[
  {
    "path": ".claude/settings.local.json",
    "content": "{\n  \"permissions\": {\n    \"allow\": [\n      \"Bash(rg:*)\",\n      \"Bash(grep:*)\"\n    ],\n    \"deny\": []\n  }\n}"
  },
  {
    "path": ".gitignore",
    "content": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n# Runtime data\npids\n*.pid\n*.seed\n*.pid.lock\n\n# Directory for instrumented libs generated by jscoverage/JSCover\nlib-cov\n\n# Coverage directory used by tools like istanbul\ncoverage\n\n# nyc test coverage\n.nyc_output\n\n# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)\n.grunt\n\n# Bower dependency directory (https://bower.io/)\nbower_components\n\n# node-waf configuration\n.lock-wscript\n\n# Compiled binary addons (https://nodejs.org/api/addons.html)\nbuild/Release\n\n# Dependency directories\nnode_modules/\njspm_packages/\n\n# TypeScript v1 declaration files\ntypings/\n\n# Optional npm cache directory\n.npm\n\n# Optional eslint cache\n.eslintcache\n\n# Optional REPL history\n.node_repl_history\n\n# Output of 'npm pack'\n*.tgz\n\n# Yarn Integrity file\n.yarn-integrity\n\n# dotenv environment variables file\n.env\n\n# parcel-bundler cache (https://parceljs.org/)\n.cache\n\n# next.js build output\n.next\n\n# nuxt.js build output\n.nuxt\n\n# vuepress build output\n.vuepress/dist\n\n# Serverless directories\n.serverless/\n\n# FuseBox cache\n.fusebox/\n\n# DynamoDB Local files\n.dynamodb/\n# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\n/node_modules\n/.pnp\n.pnp.js\n\n# testing\n/coverage\n\n# production\n**/build\n/out\n/dist\n\n# misc\n.DS_Store\n.env.local\n.env.test.local\n**/.env.development\n# .env.prod_for_dev\n\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n*.code-workspace\n.vscode\nopenapitools.json\n*.tgz\n.idea/\n.yarn/\ntestkey.txt\n\ntest_datadir\n\n#yalc\n.yalc\nyalc.lock\n\n.windsurfrules"
  },
  {
    "path": ".prettierignore",
    "content": "# Ignore artifacts:\n.idea/**\n.vscode/**\n/node_modules\n**/dist\n**/build\n**/node_modules\n"
  },
  {
    "path": ".prettierrc.json",
    "content": "{\n  \"semi\": false,\n  \"tabWidth\": 2,\n  \"printWidth\": 100,\n  \"singleQuote\": true,\n  \"trailingComma\": \"all\",\n  \"jsxSingleQuote\": true,\n  \"bracketSpacing\": true\n}\n"
  },
  {
    "path": ".yarnclean",
    "content": "# test directories\n__tests__\ntest\ntests\npowered-test\n\n# test exceptions\n!**/viem/**/test\n!**/viem/**/test/**\n\n# asset directories\ndocs\ndoc\nwebsite\nimages\n# assets\n\n# examples\nexample\nexamples\n\n# code coverage directories\ncoverage\n.nyc_output\n\n# build scripts\nMakefile\nGulpfile.js\nGruntfile.js\n\n# configs\nappveyor.yml\ncircle.yml\ncodeship-services.yml\ncodeship-steps.yml\nwercker.yml\n.tern-project\n.gitattributes\n.editorconfig\n.*ignore\n.eslintrc\n.jshintrc\n.flowconfig\n.documentup.json\n.yarn-metadata.json\n.travis.yml\n\n# misc\n*.md\n\n!@storybook/react/dist/esm/client/docs"
  },
  {
    "path": ".yarnrc",
    "content": "sass_binary_site \"https://npm.taobao.org/mirrors/node-sass/\"\nphantomjs_cdnurl \"https://npm.taobao.org/mirrors/phantomjs/\"\nelectron_mirror \"https://npm.taobao.org/mirrors/electron/\"\nelectron_builder_binaries_mirror \"https://mirrors.huaweicloud.com/electron-builder-binaries/\"\n\n#registry \"https://registry.npm.taobao.org\"\n"
  },
  {
    "path": "LICENSE",
    "content": "Licensor:             Loopring Technology Limited\n\nLicensed Work:        Loopring-web/loopring-sdk\n                      The Licensed Work is (c) 2022 Loopring Technology Limited\n\n-----------------------------------------------------------------------------\n\nTerms\n\nThe Licensor hereby grants you the right to copy, modify, create derivative\nworks, redistribute, and make limited-production use of the Licensed Work, on condition that Loopring L2 protocol/technology is supported on your platform that this Licensed Work is being used.\n\nIf your use of the Licensed Work does not comply with the requirements\ncurrently in effect as described in this License, you must acquire a\nfull licensing agreement from the Licensor, or its affiliated entities,\nor you must refrain from using the Licensed Work.\n\nAll copies of the original and modified Licensed Work, and derivative works\nof the Licensed Work, are subject to this License. This License applies\nseparately for each version of the Licensed Work.\n\nYou must conspicuously display this License on each original or modified copy\nof the Licensed Work. If you receive the Licensed Work in original or\nmodified form from a third party, the terms and conditions set forth in this\nLicense apply to your use of that work.\n\nAny use of the Licensed Work in violation of this License will automatically\nterminate your rights under this License for the current and all other\nversions of the Licensed Work.\n\nThis License does not grant you any right in any trademark or logo of\nLicensor or its affiliates (provided that you may use a trademark or logo of\nLicensor as expressly required by this License).\n\nTO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\nAN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\nEXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\nTITLE.\n\n-----------------------------------------------------------------------------\n\n"
  },
  {
    "path": "README.md",
    "content": "<p align=\"center\">\n  <a href=\"https://github.com/Loopring/loopring-web-v2\" rel=\"noopener\" target=\"_blank\"><img width=\"150\" src=\"https://loopring.org/images/logo.svg\" alt=\"Loopring-website\"></a>\n</p>\n\n<h1 align=\"center\">Loopring Application</h1>\n<div align=\"center\">\n<h2>Ethereum’s First zkRollup Layer2</h2>\n<p>Fast, Secure, and 100x Lower Fees</p>\n\n[![license](https://img.shields.io/badge/license-MIT-blue)](https://github.com/Loopring/loopring-web-v2/master/LICENSE)\n\n[![type-badge](https://img.shields.io/npm/types/react-data-grid)](https://www.npmjs.com/package/react-data-grid)\n\n<!-- [![Materi-UI](https://img.shields.io/npm/types/react-data-grid)](https://www.npmjs.com/package/react-data-grid) -->\n\n</div>\n\n## 🚀 Quick Start\n\n```bash\n// with yarn\nyarn install\nyarn up\ncd ./packages/webapp\nnpm run dev\n\n\n```\n\n## 📚 Loopring UI component [StoryBook](https://static.loopring.io/storybook-static/)\n\n```bash\n\ncd ./packages/component-lib\nnpm run storybook\n```\n\n## 🏗 Framework Design\n\n![](https://static.loopring.io/Loopring%20framwork.png)\n\n## 👉 [What is Loopring?](https://loopring.org/#/)\n\n## 🫂 Community\n\n- [Loopring Website](https://loopring.org/)\n- [Loopring Exchange](https://loopring.io/#/layer2)\n- [Loopring Reddit](https://www.reddit.com/r/loopringorg/)\n- [Loopring Medium](https://medium.com/loopring-protocol)\n- [Loopring Twitter](https://twitter.com/loopringorg)\n- [Loopring Telegram](https://t.me/loopring_en)\n\n## 👺 For Developer\n\n- We appreciate any improvements or initiatives for Loopring Layer2 website, please view the source code\n  in `./packages/component-lib`.\n- The project contains a separate lib \"web3-provider\", which is a third-party ETH web3 wallet provider service (\n  WalletConnect & metamask),\n- You are welcome to reuse it or integrate your provider service with our website.\n- Feel free to leave suggestions or ideas.\n\n### 📒 API & Dependency\n\n- [Web3-Provider](https://www.npmjs.com/package/@loopring-web/web3-provider)\n- [Loopring-sdk](https://www.npmjs.com/package/@loopring-web/loopring-sdk)\n- [APIs](https://docs.loopring.io/)\n\n## 🙋 Protocol & Architecture\n\n- [Whitepaper](https://loopring.org/resources/en_whitepaper.pdf)\n- [Design Docs](https://github.com/LoopringSecondary/docs/wiki/Loopring3_Design)\n\n## ❓[Help](https://desk.zoho.com/portal/loopring/en/home)\n\n## 🔑 Security\n\n- [Wallet](https://security.loopring.io/)\n- [Protocol Audit](https://loopring.org/resources/loopring1.0_audit.pdf)\n\n## Release Process\n\nloopring.io, wallet.loopring.io, docs.loopring.io, earn.loopring.io, static.loopring.io, and loopring.io are now auto deployed using Vercel.\n"
  },
  {
    "path": "craco.config.cjs",
    "content": "const webpack = require('webpack')\nconst {addBeforeLoader, loaderByName, getLoader, addPlugins} = require('@craco/craco');\n\n\nconst CopyWebpackPlugin = require('copy-webpack-plugin')\n// Try the environment variable, otherwise use root\nconst ASSET_PATH = process.env.ASSET_PATH || '/'\n// const rewireLess = require('react-app-rewire-less')\n\n// const { alias } = require('react-app-rewire-alias')\n\nconst path = require('path')\n\n// const GitRevisionPlugin = require('git-revision-webpack-plugin')\n// const gitRevisionPlugin = new GitRevisionPlugin()\nconst direct = './'\nconst packagesPath = './packages'\nmodule.exports = function ({env}) {\n    const dev = env === 'development'\n    const prod = env === 'production'\n    return {\n        babel: {\n            presets: [ /* ... */],\n            plugins: [\n                [\n                    \"import\",\n                    {\n                        libraryName: 'antd',\n                        libraryDirectory: 'es',\n                        style: true,\n                    }\n                ],\n            ],\n            loaderOptions: { /* ... */},\n            loaderOptions: (babelLoaderOptions, {env, paths}) => {\n                const dev = env === 'development'\n                const prod = env === 'production'\n                // console.log(babelLoaderOptions)\n                return babelLoaderOptions;\n            },\n        },\n        webpack: {\n            alias: {\n                '@material-ui/core/Menu': '@mui/material/Menu',\n                '@material-ui/core': '@mui/material',\n                '@material-ui/core/Popover': '@mui/material/Popover',\n                process: \"process/browser\"\n            },\n            plugins: {\n                add: [\n                    new CopyWebpackPlugin({\n                        patterns: [\n                            {\n                                from: path.resolve(__dirname, packagesPath, 'common-resources', 'assets'),\n                                to: './static',\n                                toType: 'dir',\n                            },\n                        ],\n                    }),\n                    new webpack.DefinePlugin({\n                        'process.env.TIME':\n                            '\"' + new Date().toLocaleString('en-US', {timeZone: 'Asia/Shanghai'}) + '/SH\"',\n                    }),\n                    new webpack.ProvidePlugin({\n                        process: 'process/browser',\n                    }),\n                    new webpack.ProvidePlugin({\n                        Buffer: ['buffer', 'Buffer'],\n                    }),\n                ],\n            },\n            configure: (config, {env, paths}) => {\n                const dev = env === 'development'\n                const prod = env === 'production'\n                config.ignoreWarnings = [/Failed to parse source map/];\n                config.resolve.fallback = Object.assign(config.resolve.fallback ?? {}, {\n                    \"crypto\": require.resolve(\"crypto-browserify\"),\n                    \"crypto-js\": require.resolve('crypto-js'),\n                    \"crypto-js/sha256\": require.resolve('crypto-js/sha256'),\n                    \"stream\": require.resolve(\"stream-browserify\"),\n                    \"assert\": require.resolve(\"assert/\"),\n                    \"http\": require.resolve(\"stream-http\"),\n                    \"https\": require.resolve(\"https-browserify\"),\n                    \"os\": require.resolve(\"os-browserify\"),\n                    \"url\": require.resolve(\"url/\"),\n                    \"util\": require.resolve(\"util\"),\n                    \"buffer\": require.resolve(\"buffer\"),\n                    \"timers\": require.resolve(\"timers-browserify\"),\n                    'process/browser': require.resolve('process/browser'),\n                    \"fs\":false,\n                    \"path\":false\n                })\n                config.node = {global: true}\n                console.log(config.node)\n                // node: { global: true, fs: 'empty'},\n                // config.packages({\n                //   packages: [\n                //     {\n                //       name: 'crypto-js',\n                //       location: 'path-to/bower_components/crypto-js',\n                //       main: 'index'\n                //     }\n                //   ]\n                // });\n                var {isFound, match} = getLoader(config, loaderByName('babel-loader'));\n                if (isFound) {\n                    console.log(match.loader)\n                    match.loader.include = [\n                        path.resolve(__dirname, packagesPath),\n                        ...[\n                            path.resolve(\n                                __dirname,\n                                `${process.env.NODE_ENV === 'development' ? direct : direct}`,\n                                `node_modules/@web3modal`,\n                            ),\n                            path.resolve(\n                                __dirname,\n                                `${process.env.NODE_ENV === 'development' ? direct : direct}`,\n                                `node_modules/@walletconnect`,\n                            ),\n                            path.resolve(\n                                __dirname,\n                                `${process.env.NODE_ENV === 'development' ? direct : direct}`,\n                                `node_modules/@metamask`,\n                            ),\n                            path.resolve(\n                                __dirname,\n                                `${process.env.NODE_ENV === 'development' ? direct : direct}`,\n                                `node_modules/@scure`,\n                            ),\n                            path.resolve(\n                                __dirname,\n                                `${process.env.NODE_ENV === 'development' ? direct : direct}`,\n                                `node_modules/@noble`,\n                            ),\n                            path.resolve(\n                                __dirname,\n                                `${process.env.NODE_ENV === 'development' ? direct : direct}`,\n                                `node_modules/@ethereumjs`,\n                            ),\n                            path.resolve(\n                                __dirname,\n                                `${process.env.NODE_ENV === 'development' ? direct : direct}`,\n                                `node_modules/micro-ftch`,\n                            ),\n                            path.resolve(\n                                __dirname,\n                                `${process.env.NODE_ENV === 'development' ? direct : direct}`,\n                                `node_modules/react-spring`,\n                            ),\n                            path.resolve(\n                                __dirname,\n                                `${process.env.NODE_ENV === 'development' ? direct : direct}`,\n                                `node_modules/@react-spring`,\n                            ),\n                            path.resolve(\n                                __dirname,\n                                `${process.env.NODE_ENV === 'development' ? direct : direct}`,\n                                `node_modules/@loopring-web/loopring-sdk`,\n                            ),\n                        ],\n                    ]\n                }\n                config.resolve.extensions.push('.html');\n                config.resolve.extensions.push('.md');\n\n                addBeforeLoader(config, loaderByName('babel-loader'), {\n                    loader: 'html-loader',\n                    test: /\\.html$/i,\n                    exclude: [/node_modules/, /index.html/i],\n                    options: {\n                        attrs: [':data-src'],\n                        minimize: true,\n                        removeComments: false,\n                        collapseWhitespace: false,\n                    },\n                });\n                addBeforeLoader(config, loaderByName('babel-loader'), {\n                    test: /\\.md$/,\n                    use: 'raw-loader',\n                });\n\n                // }\n\n\n                return config;\n            },\n        },\n    };\n};"
  },
  {
    "path": "lerna.json",
    "content": "{\n  \"version\": \"independent\",\n  \"npmClient\": \"yarn\",\n  \"command\": {\n    \"publish\": {\n      \"ignoreChanges\": [\n        \"*.md\"\n      ]\n    }\n  },\n  \"useWorkspaces\": true,\n  \"packages\": [\n    \"packages/*\"\n  ]\n}\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"loopring-web\",\n  \"version\": \"1.3.0\",\n  \"author\": \"Loopring Dex Frontend Team\",\n  \"description\": \"dex web app new version\",\n  \"private\": true,\n  \"license\": \"SEE LICENSE IN LICENSE\",\n  \"engines\": {\n    \"node\": \"22.x\"\n  },\n  \"dependencies\": {\n    \"@coinbase/onchainkit\": \"^0.38.7\",\n    \"@emotion/react\": \"^11.4.1\",\n    \"@emotion/styled\": \"^11.3.0\",\n    \"@loopring-web/loopring-sdk\": \"3.9.23\",\n    \"@loopring-web/recharts\": \"^2.0.10\",\n    \"@loopring-web/web3-provider\": \"1.4.16\",\n    \"@mui/icons-material\": \"^5.16.6\",\n    \"@mui/lab\": \"5.0.0-alpha.45\",\n    \"@mui/material\": \"5.6.2\",\n    \"@ramp-network/ramp-instant-sdk\": \"^4.0.4\",\n    \"@react-buddy/ide-toolbox\": \"^2.3.1\",\n    \"@react-buddy/palette-mui\": \"^5.0.1\",\n    \"@react-spring/parallax\": \"^9.4.4\",\n    \"@reduxjs/toolkit\": \"^1.8.1\",\n    \"@reown/appkit\": \"1.7.2\",\n    \"@reown/appkit-adapter-ethers5\": \"1.7.2\",\n    \"@reown/appkit-adapter-wagmi\": \"^1.7.2\",\n    \"assert\": \"^2.0.0\",\n    \"bignumber.js\": \"9.1.1\",\n    \"bn.js\": \"^5.2.1\",\n    \"cids\": \"^1.1.9\",\n    \"clsx\": \"^1.1.1\",\n    \"crypto-browserify\": \"^3.12.0\",\n    \"crypto-js\": \"^4.1.1\",\n    \"d3-format\": \"2.0.0\",\n    \"d3-time-format\": \"3.0.0\",\n    \"decimal.js\": \"^10.4.3\",\n    \"dompurify\": \"^2.4.0\",\n    \"dotenv\": \"^8.2.0\",\n    \"dotenv-webpack\": \"^7.0.3\",\n    \"easy-template-string\": \"^1.0.1\",\n    \"echarts\": \"^5.2.2\",\n    \"echarts-for-react\": \"^3.0.2\",\n    \"ethers\": \"^5.5.4\",\n    \"ffjavascript\": \"^0.1.0\",\n    \"firebase\": \"^9.23.0\",\n    \"github-markdown-css\": \"^5.2.0\",\n    \"html5-qrcode\": \"2.3.4\",\n    \"i18next\": \"^23.2.3\",\n    \"immutable\": \"^4.0.0-rc.12\",\n    \"ipfs-http-client\": \"^56.0.2\",\n    \"jsqr\": \"^1.4.0\",\n    \"lottie-react\": \"^2.1.0\",\n    \"material-ui-popup-state\": \"^1.9.3\",\n    \"moment\": \"^2.29.1\",\n    \"polished\": \"^4.1.1\",\n    \"qr-code-styling\": \"^1.6.0-rc.1\",\n    \"react\": \"^18.2.0\",\n    \"react-beautiful-dnd\": \"^13.1.1\",\n    \"react-currency-input-field\": \"^3.3.1\",\n    \"react-data-grid\": \"^7.0.0-canary.49\",\n    \"react-dom\": \"^18.2.0\",\n    \"react-dropzone\": \"^12.0.4\",\n    \"react-financial-charts\": \"^2.0.1\",\n    \"react-grid-layout\": \"^1.3.0\",\n    \"react-i18next\": \"^11.8.12\",\n    \"react-markdown\": \"^8.0.7\",\n    \"react-redux\": \"^7.2.3\",\n    \"react-redux-firebase\": \"^3.11.0\",\n    \"react-resizable\": \"^3.0.5\",\n    \"react-router-dom\": \"^5.3.4\",\n    \"react-scripts\": \"5.0.1\",\n    \"react-scripts-rewired\": \"3.1.1\",\n    \"react-share\": \"^4.4.1\",\n    \"react-spring\": \"^9.7.1\",\n    \"react-swipeable-views\": \"^0.13.9\",\n    \"react-use\": \"^17.4.0\",\n    \"react-virtualized\": \"^9.22.5\",\n    \"react-virtuoso\": \"^1.8.6\",\n    \"redux-actions\": \"^2.6.5\",\n    \"redux-observable\": \"^1.2.0\",\n    \"redux-persist\": \"^6.0.0\",\n    \"redux-saga\": \"^1.2.3\",\n    \"rehype-raw\": \"^6.1.1\",\n    \"remark-gfm\": \"^3.0.0\",\n    \"rxjs\": \"^7.8.1\",\n    \"three\": \"^0.149.0\",\n    \"timers\": \"^0.1.1\",\n    \"timers-browserify\": \"^2.0.12\",\n    \"util\": \"^0.12.5\",\n    \"vconsole\": \"^3.15.1\",\n    \"viem\": \"^2.27.0\",\n    \"voca\": \"^1.4.1\",\n    \"wagmi\": \"^2.14.16\",\n    \"web-vitals\": \"^3.4.0\"\n  },\n  \"build\": {\n    \"files\": [\n      \"build/**/*\",\n      \"node_modules/**/*\"\n    ],\n    \"publish\": {\n      \"provider\": \"custom\",\n      \"repo\": \"ssh://git@github.com/loopring/dexwebappv2\",\n      \"owner\": \"loopring dev\"\n    }\n  },\n  \"scripts\": {\n    \"clean\": \"yarn autoclean --force\",\n    \"docker\": \"cd ./packages/webapp; yarn build; cd devops docker-compose build\",\n    \"boot\": \"echo y | lerna clean; sleep 1; lerna bootstrap --force-local\",\n    \"up\": \"echo y | lerna clean; yarn\",\n    \"up2\": \"yarn unlink \\\"loopring-sdk'\\\"; echo y | lerna clean; yarn\",\n    \"reset\": \"npm config delete proxy; rm -rf node_modules/ yarn.lock; echo y | lerna clean; yarn\",\n    \"reset_proxy\": \"npm config set proxy=http://127.0.0.1:1087; yarn reset\",\n    \"dev\": \"cd ./packages/webapp; yarn dev\",\n    \"dev-bridge\": \"cd packages/web-bridge; yarn dev\",\n    \"dev-guardian\": \"cd packages/web-guardian; yarn dev\",\n    \"dev_earn\": \"cd packages/web-earn; yarn dev\",\n    \"build\": \"cd ./packages/webapp; yarn build\",\n    \"build-sb\": \"cd ./packages/component-lib; npm run build\",\n    \"build-bridge\": \"cd packages/web-bridge; yarn build\",\n    \"build-guardian\": \"cd packages/web-guardian; yarn build\",\n    \"build_dev\": \"cd ./packages/webapp; yarn build_dev\",\n    \"build_earn\": \"cd packages/web-earn; yarn build\",\n    \"deploy\": \"cd ./packages/webapp; yarn deploy\",\n    \"deploy:ipfs\": \"cd ./packages/webapp; yarn deploy:ipfs\",\n    \"sass\": \"node-sass packages/web-wallet/public/*.scss packages/web-wallet/public/*.css\"\n  },\n  \"browserslist\": {\n    \"production\": [\n      \"last 2 chrome version\",\n      \"last 2 firefox version\",\n      \"last 2 safari version\"\n    ],\n    \"development\": [\n      \"last 2 chrome version\",\n      \"last 2 firefox version\",\n      \"last 2 safari version\"\n    ]\n  },\n  \"workspaces\": {\n    \"packages\": [\n      \"packages/*\"\n    ],\n    \"nohoist\": [\n      \"**/babel-loader\",\n      \"**/babel-eslint\"\n    ]\n  },\n  \"prettier\": {\n    \"semi\": false,\n    \"tabWidth\": 2,\n    \"printWidth\": 100,\n    \"singleQuote\": true,\n    \"trailingComma\": \"all\",\n    \"jsxSingleQuote\": true,\n    \"bracketSpacing\": true\n  },\n  \"devDependencies\": {\n    \"@babel/core\": \"^7.13.14\",\n    \"@babel/eslint-parser\": \"^7.13.14\",\n    \"@babel/helper-builder-react-jsx\": \"^7.10.4\",\n    \"@babel/helper-builder-react-jsx-experimental\": \"^7.12.11\",\n    \"@babel/helper-explode-assignable-expression\": \"^7.18.6\",\n    \"@babel/helper-function-name\": \"^7.24.7\",\n    \"@babel/helper-split-export-declaration\": \"^7.24.7\",\n    \"@babel/plugin-proposal-optional-chaining\": \"^7.21.0\",\n    \"@babel/plugin-proposal-private-property-in-object\": \"7.21.11\",\n    \"@babel/plugin-syntax-bigint\": \"^7.8.3\",\n    \"@babel/plugin-transform-exponentiation-operator\": \"^7.22.5\",\n    \"@babel/plugin-transform-typescript\": \"^7.22.5\",\n    \"@babel/preset-env\": \"^7.13.12\",\n    \"@babel/preset-react\": \"^7.13.13\",\n    \"@babel/preset-typescript\": \"^7.13.0\",\n    \"@craco/craco\": \"^7.1.0\",\n    \"@craco/types\": \"^7.1.0\",\n    \"@manaflair/redux-batch\": \"^1.0.0\",\n    \"@testing-library/jest-dom\": \"^5.11.4\",\n    \"@testing-library/react\": \"^11.1.0\",\n    \"@testing-library/react-hooks\": \"^5.1.0\",\n    \"@testing-library/user-event\": \"^12.1.10\",\n    \"@types/crypto-js\": \"^4.1.1\",\n    \"@types/dompurify\": \"^2.3.4\",\n    \"@types/ethereumjs-abi\": \"^0.6.3\",\n    \"@types/ethereumjs-tx\": \"^2.0.0\",\n    \"@types/jest\": \"^26.0.15\",\n    \"@types/lodash\": \"^4.14.168\",\n    \"@types/node\": \"^12.0.0\",\n    \"@types/qrcode-svg\": \"^1.1.1\",\n    \"@types/react\": \"^18.2.19\",\n    \"@types/react-beautiful-dnd\": \"^13.1.2\",\n    \"@types/react-dom\": \"^18.2.7\",\n    \"@types/react-grid-layout\": \"^1.1.2\",\n    \"@types/react-router-dom\": \"^5.1.7\",\n    \"@types/react-swipeable-views\": \"^0.13.0\",\n    \"@types/react-virtualized\": \"^9.21.11\",\n    \"@types/webpack\": \"^5.28.1\",\n    \"@typescript-eslint/eslint-plugin\": \"^5.59.9\",\n    \"@typescript-eslint/parser\": \"^4.33.0\",\n    \"JSONStream\": \"^1.3.5\",\n    \"babel-plugin-import\": \"^1.13.3\",\n    \"babel-plugin-named-exports-order\": \"^0.0.2\",\n    \"browserify-fs\": \"^1.0.0\",\n    \"buffer\": \"^6.0.3\",\n    \"copy-webpack-plugin\": \"6\",\n    \"craco\": \"^0.0.3\",\n    \"cross-env\": \"^7.0.3\",\n    \"crypto-browserify\": \"^3.12.0\",\n    \"csp-html-webpack-plugin\": \"^5.1.0\",\n    \"csv-parse\": \"^5.1.0\",\n    \"customize-cra\": \"^1.0.0\",\n    \"decimal.js\": \"^10.4.3\",\n    \"dotenv-cli\": \"^4.0.0\",\n    \"eslint\": \"^7.23.0\",\n    \"eslint-config-react-app\": \"^6.0.0\",\n    \"eslint-plugin-flowtype\": \"^5.4.0\",\n    \"eslint-plugin-import\": \"^2.22.1\",\n    \"eslint-plugin-jsx-a11y\": \"^6.4.1\",\n    \"eslint-plugin-react\": \"^7.24.0\",\n    \"eslint-plugin-react-hooks\": \"^1.7.0\",\n    \"generate-react-cli\": \"^5.2.3\",\n    \"git-revision-webpack-plugin\": \"^3.0.6\",\n    \"html-loader\": \"^0.5.5\",\n    \"html5-qrcode\": \"2.3.4\",\n    \"https-browserify\": \"^1.0.0\",\n    \"lerna\": \"^7.1.5\",\n    \"prettier\": \"2.8.8\",\n    \"process\": \"^0.11.10\",\n    \"prop-types\": \"^15.8.1\",\n    \"react-app-rewire-alias\": \"^0.2.0\",\n    \"react-app-rewired\": \"^2.2.1\",\n    \"react-router\": \"^5.2.1\",\n    \"storybook-addon-styled-component-theme\": \"^1.3.0\",\n    \"stream-browserify\": \"^3.0.0\",\n    \"truffle-privatekey-provider\": \"1.3.0\",\n    \"typescript\": \"^4.1.2\",\n    \"url\": \"^0.11.1\",\n    \"webpack\": \"5.88.2\"\n  },\n  \"resolutions\": {\n    \"bufferutil\": \"npm:-@0.0.1\"\n  }\n}\n"
  },
  {
    "path": "packages/common-resources/.babelrc",
    "content": "{\n  \"presets\": [\n    \"@babel/typescript\",\n    [\n      \"@babel/env\",\n      {\n        \"modules\": false\n      }\n    ]\n  ],\n  \"plugins\": [\n    \"@babel/plugin-proposal-class-properties\"\n  ]\n}\n"
  },
  {
    "path": "packages/common-resources/assets/coin/loopring.json",
    "content": "{\"file\":\"loopring_431f2ed4.png\",\"frames\":{\"0XBTC\":{\"x\":0,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"1INCH\":{\"x\":72,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"AAVE\":{\"x\":144,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"AC\":{\"x\":216,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"ADX\":{\"x\":288,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"ALCX\":{\"x\":360,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"ALEND\":{\"x\":432,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"ALINK\":{\"x\":504,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"AMP\":{\"x\":576,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"ANT\":{\"x\":648,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"AUC\":{\"x\":720,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":73,\"sourceH\":73},\"AUSDC\":{\"x\":793,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"BADGER\":{\"x\":865,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"BAL\":{\"x\":937,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"BAND\":{\"x\":1009,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"BAT\":{\"x\":1081,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"BCDT\":{\"x\":1153,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"BCP\":{\"x\":1225,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"BEL\":{\"x\":1297,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"BERA\":{\"x\":1369,\"y\":72,\"w\":72,\"h\":72,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":72},\"BIT\":{\"x\":1441,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"BKT\":{\"x\":1513,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"BNB\":{\"x\":1585,\"y\":72,\"w\":72,\"h\":72,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":72},\"BNT\":{\"x\":1657,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"BOME\":{\"x\":1729,\"y\":72,\"w\":72,\"h\":72,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":72},\"BOR\":{\"x\":1801,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"BTC\":{\"x\":1873,\"y\":72,\"w\":72,\"h\":72,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":72},\"BTC2XFLI\":{\"x\":1945,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":74,\"sourceH\":73},\"BTU\":{\"x\":2019,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"BUSD\":{\"x\":2091,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"BZRX\":{\"x\":2163,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"CBBTC\":{\"x\":2235,\"y\":72,\"w\":72,\"h\":72,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":72},\"CDAI\":{\"x\":2307,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"CEL\":{\"x\":2379,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"CETH\":{\"x\":2451,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"CIETH\":{\"x\":2523,\"y\":72,\"w\":72,\"h\":72,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":72},\"COMP\":{\"x\":2595,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"CRV\":{\"x\":2667,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"CUSDC\":{\"x\":2739,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"CVT\":{\"x\":2811,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"DAI\":{\"x\":2883,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"DEFIL\":{\"x\":2955,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"DEP\":{\"x\":3027,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"DOGE\":{\"x\":3099,\"y\":72,\"w\":72,\"h\":72,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":72},\"DOUGH\":{\"x\":3171,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"DPI\":{\"x\":3243,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"DPR\":{\"x\":3315,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"DXD\":{\"x\":3387,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"ENJ\":{\"x\":3459,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"ENS\":{\"x\":3531,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"ENTRP\":{\"x\":3603,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"ETH-1\":{\"x\":3675,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"ETH\":{\"x\":3747,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"ETHFI\":{\"x\":3819,\"y\":72,\"w\":72,\"h\":72,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":72},\"FARM\":{\"x\":3891,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"FIN\":{\"x\":3963,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"FLI\":{\"x\":4035,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"FLX\":{\"x\":4107,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":79,\"sourceH\":73},\"FST\":{\"x\":4186,\"y\":72,\"w\":72,\"h\":72,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":72},\"FUSE\":{\"x\":4258,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"GNO\":{\"x\":4330,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"GRG\":{\"x\":4402,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"GRID\":{\"x\":4474,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"GRT\":{\"x\":4546,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"HBTC\":{\"x\":4618,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":73,\"sourceH\":73},\"HEX\":{\"x\":4691,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"HT\":{\"x\":4763,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"ICHI\":{\"x\":4835,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"IDLE\":{\"x\":4907,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"IMX\":{\"x\":4979,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"INDEX\":{\"x\":5051,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"JRT\":{\"x\":5123,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"KAI\":{\"x\":5195,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"KEEP\":{\"x\":5267,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"KNC\":{\"x\":5339,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"KP3R\":{\"x\":5411,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"LDO\":{\"x\":5483,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"LINK\":{\"x\":5555,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"LQTY\":{\"x\":5627,\"y\":72,\"w\":72,\"h\":72,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":72},\"LRC\":{\"x\":5699,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"LRTAIKO\":{\"x\":5771,\"y\":72,\"w\":72,\"h\":72,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":72},\"MANA\":{\"x\":5843,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"MASK\":{\"x\":5915,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"MATIC\":{\"x\":5987,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"MCB\":{\"x\":6059,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"MKR\":{\"x\":6131,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"MOVD\":{\"x\":6203,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"MTA\":{\"x\":6275,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"NEC\":{\"x\":6347,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"NEST\":{\"x\":6419,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"NIOX\":{\"x\":6491,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":75,\"sourceH\":73},\"NMR\":{\"x\":6566,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"OBTC\":{\"x\":6638,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"OGN\":{\"x\":6710,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"OMG\":{\"x\":6782,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"ONG\":{\"x\":6854,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"ORDI\":{\"x\":6926,\"y\":72,\"w\":72,\"h\":72,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":72},\"OVR\":{\"x\":6998,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"PAX\":{\"x\":7070,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"PBTC\":{\"x\":7142,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"PEPE\":{\"x\":7214,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"PLTC\":{\"x\":7286,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"PNK\":{\"x\":7358,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"PNT\":{\"x\":7430,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"QCAD\":{\"x\":7502,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"RAI\":{\"x\":7574,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":73,\"sourceH\":73},\"REN\":{\"x\":7647,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"RENBTC\":{\"x\":7719,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"RENDOGE\":{\"x\":7791,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"REP\":{\"x\":7863,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"REPT\":{\"x\":7935,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"RETH\":{\"x\":8007,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"RFOX\":{\"x\":8079,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"RGT\":{\"x\":8151,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"RICE\":{\"x\":8223,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"RPL\":{\"x\":8295,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"RSPT\":{\"x\":8367,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"RSR\":{\"x\":8439,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"SAND\":{\"x\":8511,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"SENT\":{\"x\":8583,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"SMARTCREDIT\":{\"x\":8655,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"SNT\":{\"x\":8727,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"SNX\":{\"x\":8799,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"SOL\":{\"x\":8871,\"y\":72,\"w\":72,\"h\":72,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":72},\"STAKE\":{\"x\":8943,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"SUSD\":{\"x\":9015,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"SUSHI\":{\"x\":9087,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"SX\":{\"x\":9159,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"TAIKO\":{\"x\":9231,\"y\":72,\"w\":72,\"h\":72,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":72},\"TEL\":{\"x\":9303,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"TLOS\":{\"x\":9375,\"y\":72,\"w\":72,\"h\":72,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":72},\"TRB\":{\"x\":9447,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"TRUMP\":{\"x\":9519,\"y\":72,\"w\":72,\"h\":72,\"offX\":0,\"offY\":0,\"sourceW\":53,\"sourceH\":72},\"TRYB\":{\"x\":9572,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":73,\"sourceH\":73},\"TUSD\":{\"x\":9645,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":73,\"sourceH\":73},\"UBT\":{\"x\":9718,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"UMA\":{\"x\":9790,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"UNI\":{\"x\":9862,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"USDC\":{\"x\":9934,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"USDT\":{\"x\":10006,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"VBZRX\":{\"x\":10078,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"VETH\":{\"x\":10150,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"VSP\":{\"x\":10222,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"WBTC\":{\"x\":10294,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"WETH\":{\"x\":10366,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"WIF\":{\"x\":10438,\"y\":72,\"w\":72,\"h\":72,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":72},\"WNXM\":{\"x\":10510,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"WOO\":{\"x\":10582,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"WSTETH\":{\"x\":10654,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"XRP\":{\"x\":10726,\"y\":72,\"w\":72,\"h\":72,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":72},\"YFI\":{\"x\":10798,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"YFII\":{\"x\":10870,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"YPIE\":{\"x\":10942,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":72,\"sourceH\":73},\"ZRX\":{\"x\":11014,\"y\":72,\"w\":72,\"h\":73,\"offX\":0,\"offY\":0,\"sourceW\":73,\"sourceH\":73}}}"
  },
  {
    "path": "packages/common-resources/index.ts",
    "content": "export * from './static-resources'\n"
  },
  {
    "path": "packages/common-resources/mail.html",
    "content": "\n<div id='zohoSupportWebToCase' align='center'>\n\t<form name='zsWebToCase_638510000000180873' id='zsWebToCase_638510000000180873'\n\t\t\t\taction='https://desk.zoho.com/support/WebToCase' method='POST' onSubmit='return zsValidateMandatoryFields()'\n\t\t\t\tenctype='multipart/form-data'><input type='hidden' name='xnQsjsdp'\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t value='edbsne3e0671907c01d4368bf22694c4645f0'/> <input type='hidden'\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tname='xmIwtLD'\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tvalue='edbsna177e6b86568a92d2e6f08fab3b80d5960bb314f2e20acd3f10783571e08dc71'/>\n\t\t<input type='hidden' name='xJdfEaS' value=''/> <input type='hidden' name='actionType' value='Q2FzZXM='/> <input\n\t\t\t\t\t\ttype=\"hidden\" id=\"property(module)\" value=\"Cases\"/> <input type=\"hidden\" id=\"dependent_field_values_Cases\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t value=\"&#x7b;&quot;JSON_VALUES&quot;&#x3a;&#x7b;&#x7d;,&quot;JSON_SELECT_VALUES&quot;&#x3a;&#x7b;&#x7d;,&quot;JSON_MAP_DEP_LABELS&quot;&#x3a;&#x5b;&#x5d;&#x7d;\"/>\n\t\t<input type='hidden' name='returnURL' value='https&#x3a;&#x2f;&#x2f;loopring.io'/>\n\t\t<section border='0' cellspacing='0' class='zsFormClass'>\n\t\t\t<div class='inline-flex' >\n\t\t\t\t<section colspan='2'  class='zsFontClass' style=\"font-size: 20px; text-align: center; padding-bottom: 20px \">Loopring Help Center</section>\n\t\t\t</div>\n\t\t\t<br>\n\t\t\t<div class='inline-flex'>\n\t\t\t\t<label  class='zsFontClass ' width='25%' align='left'>First Name&nbsp;&nbsp; </label>\n\t\t\t\t<section align='left' width='75%'><input type='text' maxlength='120' name='First Name' value=''/></section>\n\t\t\t</div>\n\t\t\t<div class='inline-flex'>\n\t\t\t\t<label  class='zsFontClass ' width='25%' align='left'>Last Name&nbsp;&nbsp; </label>\n\t\t\t\t<section align='left' width='75%'><input type='text' maxlength='120' name='Contact Name' class='manfieldbdr'/></section>\n\t\t\t</div>\n\t\t\t<div class='inline-flex'>\n\t\t\t\t<label  class='zsFontClass ' width='25%' align='left'>Email&nbsp;&nbsp; </label>\n\t\t\t\t<section align='left' width='75%'><input type='text' maxlength='120' name='Email' value='' class='manfieldbdr'/></section>\n\t\t\t</div>\n\t\t\t<div class='inline-flex'>\n\t\t\t\t<label  class='zsFontClass ' width='25%' align='left'>What&#x27;s your ticket about&#x3f; &nbsp;&nbsp; </label>\n\t\t\t\t<section align='left' width='75%' class=\"custom-select\">\n\t\t\t\t\t<select name=\"What' s your ticket about?\" value='' onchange=\"setDependent(this,\n\t\t\t\t\tfalse)\" id='CASECF1'>\n\t\t\t\t\t<option value='Loopring zkRollup Layer2'>Loopring zkRollup Layer2</option>\n\t\t\t\t\t<option value='Smart Wallet App'>Smart Wallet App</option>\n\t\t\t\t\t<option value='Others'>Others</option>\n\t\t\t\t\t</select></section>\n\t\t\t</div>\n\t\t\t<div class='inline-flex'>\n\t\t\t\t<label  class='zsFontClass ' width='25%' align='left'>What&#x27;s your Ethereum address in question&#x3f;&nbsp;&nbsp; </label>\n\t\t\t\t<section align='left' width='75%'><input type='text' maxlength='120' name=\"What' s your Ethereum address in question?\"\n\t\t\t\t\tvalue='' />\n\t\t\t\t</section>\n\t\t\t</div>\n\t\t\t<div class='inline-flex'>\n\t\t\t\t<label  class='zsFontClass ' width='25%' align='left'>What&#x27;s your operation system&#x3f; &nbsp;&nbsp; </label>\n\t\t\t\t<section align='left' width='75%'><select name=\"What' s your operation system?\" value='' onchange=\"setDependent(this,\n\t\t\t\t\tfalse)\" id='CASECF3'>\n\t\t\t\t\t<option value='Windows'>Windows</option>\n\t\t\t\t\t<option value='macOS'>macOS</option>\n\t\t\t\t\t<option value='Linux or Unix'>Linux or Unix</option>\n\t\t\t\t\t<option value='iOS'>iOS</option>\n\t\t\t\t\t<option value='Android'>Android</option>\n\t\t\t\t\t<option value='Others'>Others</option>\n\t\t\t\t\t</select></section>\n\t\t\t</div>\n\t\t\t<div class='inline-flex'>\n\t\t\t\t<label  class='zsFontClass ' width='25%' align='left'>What&#x27;s your browser - if this applies&#x3f;&nbsp;&nbsp; </label>\n\t\t\t\t<section align='left' width='75%'><input type='text' maxlength='120' name=\"What' s your browser - if this applies?\"\n\t\t\t\t\tvalue='' />\n\t\t\t\t</section>\n\t\t\t</div>\n\t\t\t<div class='inline-flex'>\n\t\t\t\t<label  class='zsFontClass ' width='25%' align='left'>Subject&nbsp;&nbsp; </label>\n\t\t\t\t<section align='left' width='75%'><input type='text' maxlength='255' name='Subject' value='' class='manfieldbdr'/>\n\t\t\t\t</section>\n\t\t\t</div>\n\t\t\t<div class='inline-flex'>\n\t\t\t\t<label  class='zsFontClass ' width='25%' align='left'>Description &nbsp;&nbsp; </label>\n\t\t\t\t<section align='left' width='75%'  >\n\t\t\t\t\t<textarea name='Description' maxlength='3000' width='250' height='300' rows=\"8\" style=\"height: 80px\">\n\t\t\t\t\t\t\n\t\t\t\t\t</textarea>\n\t\t\t\t</section>\n\t\t\t</div>\n\t\t\t<div class='inline-flex'>\n\t\t\t\t<label  class='zsFontClass ' width='25%' align='left'>Attachment &nbsp;&nbsp; </label>\n\t\t\t\t<section align='left' width='75%'><span class=\"zsFontClass wtcuploadfile\" id=\"zsBrowseAttachment\">Attach files</span><input\n\t\t\t\t\t\t\t\tclass=\"wtcuploadinput\" type='file' name='attachment_1' id='zsattachment_1' style='display:block;'\n\t\t\t\t\t\t\t\tonclick='zsOpenFileBrowseAttachment(event)'\n\t\t\t\t\t\t\t\tonchange='zsRenderBrowseFileAttachment(this.value, this)'/><input class=\"wtcuploadinput\" type='file'\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tname='attachment_2'\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tid='zsattachment_2'\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tstyle='display:none;'\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tonclick='zsOpenFileBrowseAttachment(event)'\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tonchange='zsRenderBrowseFileAttachment(this.value, this)'/>\n\t\t\t\t\t<input class=\"wtcuploadinput\" type='file' name='attachment_3' id='zsattachment_3' style='display:none;'\n\t\t\t\t\t\t\t\t onclick='zsOpenFileBrowseAttachment(event)' onchange='zsRenderBrowseFileAttachment(this.value, this)'/>\n\t\t\t\t\t<input class=\"wtcuploadinput\" type='file' name='attachment_4' id='zsattachment_4' style='display:none;'\n\t\t\t\t\t\t\t\t onclick='zsOpenFileBrowseAttachment(event)' onchange='zsRenderBrowseFileAttachment(this.value, this)'/>\n\t\t\t\t\t<input class=\"wtcuploadinput\" type='file' name='attachment_5' id='zsattachment_5' style='display:none;'\n\t\t\t\t\t\t\t\t onclick='zsOpenFileBrowseAttachment(event)' onchange='zsRenderBrowseFileAttachment(this.value, this)'/>\n\t\t\t\t\t<div class=\"clboth\"></div>\n\t\t\t\t\t<span id='zsMaxSizeMessage' style='font-size: 12px;float: left; line-height: 20px'>Each of your file(s) can be up to 20MB in size.</span><span\n\t\t\t\t\t\t\t\t\tid='zsMaxLimitMessage'\n\t\t\t\t\t\t\t\t\tstyle='color:black;font-size: 12px;float: left;margin-left: 14px;display: none;'>You can attach as many as 5 files at a time.</span>\n\t\t\t\t\t<div id='zsFileBrowseAttachments'></div>\n\t\t\t\t</section>\n\t\t\t</div>\n\t\t\t<div class='inline-flex'>\n\t\t\t\t<label  class='zsFontClass' width='25%' align='left'>Captcha&nbsp; </label>\n\t\t\t\t<section class=\"zsCaptchablock\">\n\t\t\t\t\t<div id='zsCaptchaLoading'>Loading...<br><br></div>\n\t\t\t\t\t<div id='zsCaptcha' style='display:none; align-items: center'><img src='#' id='zsCaptchaUrl' name=\"zsCaptchaImage\"><a\n\t\t\t\t\t\t\t\t\thref=\"javascript:\"\n\t\t\t\t\t\t\t\t\tstyle='color:#00a3fe; cursor:pointer; margin-left:10px; vertical-align:middle;text-decoration: none;'\n\t\t\t\t\t\t\t\t\tclass='zsFontClass' onclick='zsRegenerateCaptcha()'>Refresh</a></div>\n\t\t\t\t</section>\n\t\t\t\t<div style=\"padding-top: 8px\"><input type='text' name='zsWebFormCaptchaWord'/><input type='hidden' name='zsCaptchaSrc' value=''/></div>\n\n\t\t\t\t<div class='inline-flex'>\n\t\t\t\t<section style='padding: 11px 5px 0px 5px;' colspan='2' align='center' width='25%'><input type='submit'\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t id=\"zsSubmitButton_638510000000180873\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t class='zsFontClass'\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t value='Submit'> &nbsp;\n\t\t\t\t\t&nbsp; <input type='button' class='zsFontClass' value='Reset' onclick=\"zsResetWebForm('638510000000180873')\">\n\t\t\t\t</section>\n\t\t\t</div>\n\t\t\t<div class='inline-flex'>\n\t\t\t\t<label width='25%' align='left'></label>\n\t\t\t\t<section style='padding: 0px 5px;' align='left' width='75%'>\n\t\t\t\t\t<div class='wb_FtCon wb_common'><span>powered by  </span><a target='_blank' rel='noopener noreferrer'\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\thref='https://zoho.com/desk'\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tclass='wb_logoCon'><img class='wb_logo'\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsrc='https://d1ydxa2xvtn0b5.cloudfront.net/app/images/portalLogo.de847024ebc0131731a3.png'/></a>\n\t\t\t\t\t</div>\n\t\t\t\t</section>\n\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</form>\n</div>"
  },
  {
    "path": "packages/common-resources/package.json",
    "content": "{\n  \"name\": \"@loopring-web/common-resources\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Common package for code sharing\",\n  \"main\": \"index.ts\",\n  \"build\": {\n    \"files\": [\n      \"build/**/*\",\n      \"node_modules/**/*\"\n    ],\n    \"publish\": {\n      \"provider\": \"custom\",\n      \"repo\": \"https://github.com/Loopring/loopring-web-v2\",\n      \"owner\": \"Loopring Dev Team\"\n    }\n  },\n  \"scripts\": {\n    \"compile\": \"tsc -p tsconfig.json\",\n    \"build\": \"tsdx build\",\n    \"prepublishOnly\": \"NODE_ENV=production tsdx build\"\n  },\n  \"devDependencies\": {\n    \"tsc\": \"^2.0.4\"\n  }\n}\n"
  },
  {
    "path": "packages/common-resources/scripts/.gitignore",
    "content": "output*\n*.zip\n*.rar\n*.tar*\n"
  },
  {
    "path": "packages/common-resources/scripts/READMD.md",
    "content": "require python 3.7+\n\npip install -r requirements.txt\n"
  },
  {
    "path": "packages/common-resources/scripts/get_imgs.py",
    "content": "#!/usr/bin/python\n# -- encoding= utf8 --\n\nimport requests\n\nimport json\n\nfrom eth_utils import to_checksum_address\n\nimport os\n\nfrom PIL import Image\n\noutput_folder = 'output'\n\noutput_folder2 = 'output_resize'\n\noutput_folder_zapper = 'output_zapper'\n\noutput_folder2_zapper = 'output_resize_zapper'\n\nSIZE = (36, 36)\n\ndef gen_imgs(tokenMap):\n    tokens = requests.get('https://api3.loopring.io/api/v3/exchange/tokens')\n    print(tokens.status_code)\n\n    tokenObjs = json.loads(tokens.text)\n\n    if not os.path.exists(output_folder):\n        os.makedirs(output_folder)\n\n    if not os.path.exists(output_folder2):\n        os.makedirs(output_folder2)\n\n    if not os.path.exists(output_folder_zapper):\n        os.makedirs(output_folder_zapper)\n\n    if not os.path.exists(output_folder2_zapper):\n        os.makedirs(output_folder2_zapper)\n\n    totalNum = len(tokenObjs)\n\n    count = 1\n        \n    for tokenInfo in tokenObjs:\n        symbol = str(tokenInfo['symbol'])\n        address = str(tokenInfo['address'])\n        if not symbol.find('LP-') >= 0:\n            fileName = '{}.png'.format(symbol)\n            address = to_checksum_address(tokenInfo['address'])\n            lower_addr = address.lower()\n            filePath = os.path.join(output_folder, fileName)\n            filePath2 = os.path.join(output_folder_zapper, fileName)\n\n            try:\n\n                if not os.path.exists(filePath):\n                    url = 'https://exchange.loopring.io/assets/images/ethereum/assets/{}/logo.png'.format(address)\n                    r = requests.get(url)\n                    if r.status_code == 200:\n                        with open(filePath, \"wb\") as code:\n                            code.write(r.content)\n                        print('handling: {}/{}. {}'.format(count, totalNum, url))\n                    else:\n                        print('handling: {}/{}. {}. errorFile: {}'.format(count, totalNum, url, fileName))\n                else:\n                    print('{}/{}. {} already existed!'.format(count, totalNum, fileName))\n            except:\n                print('handling: {}/{}. {} got error!'.format(count, totalNum, fileName))\n\n            #zapper\n\n            try:\n\n                if not os.path.exists(filePath2) and lower_addr in tokenMap:\n                    tokenInfo = tokenMap[lower_addr]\n                    url = tokenInfo['logoURI']\n                    r = requests.get(url)\n                    if r.status_code == 200:\n                        with open(filePath2, \"wb\") as code:\n                            code.write(r.content)\n                        print('handling: {}/{}. {}'.format(count, totalNum, url))\n                    else:\n                        print('handling: {}/{}. {}. errorFile: {}'.format(count, totalNum, url, fileName))\n                else:\n                    print('{}/{}. {} already existed!'.format(count, totalNum, fileName))\n            except:\n                print('handling: {}/{}. {} got error!'.format(count, totalNum, fileName))\n\n        else:\n            print('{}/{}. {} is a LP Token!'.format(count, totalNum, fileName))\n            \n        count += 1\n\n    list = os.listdir(output_folder)\n    lst = []\n    for i in range(0, len(list)):\n        path = os.path.join(output_folder, list[i])\n        path2 = os.path.join(output_folder2, list[i])\n        im = Image.open(path)\n        if im.width != im.height:\n            lst.append(path)\n        im = im.resize(SIZE)\n        im.save(path2, 'PNG')\n\n    print('w!=h list:', lst)\n\ndef fetch_zapper():\n    zapperInfo = requests.get('https://zapper.fi/api/token-list')\n    print(zapperInfo.status_code)\n    print(zapperInfo.text)\n    tokenObjs = json.loads(zapperInfo.text)\n    tokens = tokenObjs['tokens']\n    tokenMap = {}\n    for token in tokens:\n        tokenMap[token['address']] = token\n    return tokenMap\n\nif __name__ == '__main__':\n    tokenMap = fetch_zapper()\n    gen_imgs(tokenMap)\n"
  },
  {
    "path": "packages/common-resources/scripts/requirements.txt",
    "content": "requests==2.24.0\neth_utils==1.10.0\npillow==8.3.2\n"
  },
  {
    "path": "packages/common-resources/static-resources/index.ts",
    "content": "import i18n from './src/i18n'\nexport { i18n }\nexport * from './src/svg'\nexport * from './src/i18n'\nexport * from './src/error'\nexport * from './src/themes'\nexport * from './src/constant'\nexport * from './src/loopring-interface'\nexport * from './src/utils'\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/constant/account.ts",
    "content": "import { StateBase } from './sagaStatus'\nimport { ConnectProviders } from '@loopring-web/web3-provider'\nimport { TokenType } from '../loopring-interface'\n\nexport enum AccountStatus {\n  UN_CONNECT = 'UN_CONNECT',\n  // CONNECT = 'CONNECT',\n  NO_ACCOUNT = 'NO_ACCOUNT',\n  DEPOSITING = 'DEPOSITING',\n  NOT_ACTIVE = 'NOT_ACTIVE',\n  LOCKED = 'LOCKED',\n  ACTIVATED = 'ACTIVATED',\n  ERROR_NETWORK = 'ERROR_NETWORK',\n}\n\nexport enum fnType {\n  UN_CONNECT = 'UN_CONNECT',\n  NO_ACCOUNT = 'NO_ACCOUNT',\n  NOT_ACTIVE = 'NOT_ACTIVE',\n  LOCKED = 'LOCKED',\n  ACTIVATED = 'ACTIVATED',\n  DEFAULT = 'DEFAULT',\n  DEPOSITING = 'DEPOSITING',\n  CONNECT = 'CONNECT',\n  ERROR_NETWORK = 'ERROR_NETWORK',\n}\n\nexport type Account = {\n  accAddress: string\n  qrCodeUrl: string\n  readyState: keyof typeof AccountStatus | 'unknown'\n  accountId: number\n  level: string\n  apiKey: string\n  frozen: boolean | undefined\n  eddsaKey: any\n  publicKey: any\n  keySeed: string\n  nonce: number | undefined\n  keyNonce: number | undefined\n  connectName: ConnectProviders\n  wrongChain?: boolean | undefined\n  isInCounterFactualStatus?: boolean\n  isContract1XAddress?: boolean\n  isContractAddress?: boolean\n  isCFAddress?: boolean\n  isContract?: boolean\n  _chainId?: 1 | 5 | 'unknown'\n  _accountIdNotActive?: number\n  _userOnModel?: boolean | undefined\n  __timer__: NodeJS.Timer | -1\n  hasUnknownCollection: undefined | boolean\n}\nexport type AccountState = Account & StateBase\nexport type AccountFull = {\n  account: Account\n  resetAccount: () => void\n  updateAccount: (account: Partial<Account>) => void\n} & StateBase\n\nexport type AssetsRawDataItem = {\n  token: {\n    type: TokenType\n    value: string\n  }\n  amount: string\n  available: string\n  locked: string\n  smallBalance: boolean\n  tokenValueDollar: number\n  name: string\n  withdrawAmount?: string\n  depositAmount?: string\n  precision: number\n  hideDepositButton?: boolean\n}\nexport const ContactLimit = 1500\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/constant/chart.ts",
    "content": "export enum ChartType {\n  Depth = 'Depth',\n  Trend = 'Trend',\n  Kline = 'Kline',\n}\n\nexport enum ChartUnit {\n  W1 = '1W',\n  H1 = '1H',\n  D1 = '1D',\n}\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/constant/firebase.ts",
    "content": "export const firebaseIOConfig = {\n  apiKey: 'AIzaSyC484SNh-OZWco7o1xUC4UGVGVf0yZU__s',\n  authDomain: 'loopring-d0829.firebaseapp.com',\n  projectId: 'loopring-d0829',\n  storageBucket: 'loopring-d0829.appspot.com',\n  messagingSenderId: '372617031978',\n  appId: '1:372617031978:web:15a3f35c4adbd679dc6e53',\n  measurementId: 'G-5TWTDQ8J7J',\n}\n\nexport const firebaseBridgeConfig = {\n  apiKey: 'AIzaSyC484SNh-OZWco7o1xUC4UGVGVf0yZU__s',\n  authDomain: 'loopring-d0829.firebaseapp.com',\n  projectId: 'loopring-d0829',\n  storageBucket: 'loopring-d0829.appspot.com',\n  messagingSenderId: '372617031978',\n  appId: '1:372617031978:web:bcc50f63d79ef868dc6e53',\n  measurementId: 'G-P4XEJ3CY0J',\n}\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/constant/index.ts",
    "content": "export * from './walletConnector'\nexport * from './setting'\nexport * from './market'\nexport * from './chart'\nexport * from './trade'\nexport * from './router'\nexport * from './table'\nexport * from './loopring'\n\nexport * from './account'\nexport * from './sagaStatus'\nexport * from './proLayout'\nexport * from './miningOuterLinks'\nexport * from './notification'\nexport * from './vendor'\nexport * from './firebase'\nexport * from './social'\nexport { SUPPORTING_NETWORKS } from './networks'\nexport { WITHDRAW_TOKEN_FILTER_LIST, mapSpecialTokenName } from './tokenConfig'\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/constant/loopring.ts",
    "content": "export const imgConfig = {\n  file: 'loopring.png',\n  frames: {\n    '0XBTC': { x: 248, y: 282, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    '1INCH': { x: 207, y: 322, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    AAVE: { x: 166, y: 362, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    AC: { x: 125, y: 402, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    ADX: { x: 84, y: 442, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    ALCX: { x: 453, y: 82, w: 36, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    ALEND: { x: 453, y: 42, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    ALINK: { x: 412, y: 82, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    AMP: { x: 371, y: 122, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    ANT: { x: 248, y: 322, w: 36, h: 35, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    AUC: { x: 166, y: 478, w: 33, h: 32, offX: 3, offY: 2, sourceW: 37, sourceH: 36 },\n    AUSDC: { x: 330, y: 162, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    BADGER: { x: 125, y: 442, w: 37, h: 35, offX: 0, offY: 1, sourceW: 37, sourceH: 36 },\n    BAL: { x: 289, y: 202, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    BAND: { x: 100, y: 482, w: 19, h: 26, offX: 9, offY: 5, sourceW: 37, sourceH: 36 },\n    BAT: { x: 248, y: 242, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    BCDT: { x: 205, y: 442, w: 27, h: 36, offX: 5, offY: 0, sourceW: 37, sourceH: 36 },\n    BCP: { x: 207, y: 282, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    BEL: { x: 166, y: 322, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    BKT: { x: 125, y: 362, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    BNT: { x: 84, y: 402, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    BOR: { x: 43, y: 442, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    BTC2XFLI: { x: 289, y: 242, w: 36, h: 36, offX: 1, offY: 0, sourceW: 38, sourceH: 36 },\n    BTU: { x: 456, y: 2, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    BUSD: { x: 412, y: 42, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    BZRX: { x: 371, y: 82, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    CDAI: { x: 330, y: 122, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    CEL: { x: 289, y: 162, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    CETH: { x: 248, y: 202, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    COMP: { x: 207, y: 242, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    CRV: { x: 166, y: 282, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    CUSDC: { x: 125, y: 322, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    CVT: { x: 409, y: 202, w: 33, h: 30, offX: 2, offY: 3, sourceW: 37, sourceH: 36 },\n    DAI: { x: 84, y: 362, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    DEP: { x: 370, y: 240, w: 31, h: 34, offX: 3, offY: 1, sourceW: 37, sourceH: 36 },\n    DOUGH: { x: 43, y: 402, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    DPI: { x: 2, y: 442, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    DPR: { x: 415, y: 2, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    DXD: { x: 371, y: 42, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    ENJ: { x: 330, y: 82, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    ENTRP: { x: 236, y: 442, w: 21, h: 30, offX: 8, offY: 3, sourceW: 37, sourceH: 36 },\n    'ETH-1': { x: 289, y: 122, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    ETH: { x: 248, y: 162, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    FARM: { x: 166, y: 442, w: 35, h: 32, offX: 1, offY: 2, sourceW: 37, sourceH: 36 },\n    FIN: { x: 207, y: 202, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    FLI: { x: 166, y: 242, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    FLX: { x: 2, y: 2, w: 40, h: 36, offX: 0, offY: 0, sourceW: 40, sourceH: 36 },\n    FUSE: { x: 207, y: 362, w: 35, h: 36, offX: 1, offY: 0, sourceW: 37, sourceH: 36 },\n    GNO: { x: 330, y: 202, w: 36, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    GRG: { x: 84, y: 322, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    GRID: { x: 43, y: 362, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    GRT: { x: 2, y: 402, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    HBTC: { x: 205, y: 402, w: 32, h: 36, offX: 2, offY: 0, sourceW: 37, sourceH: 36 },\n    HEX: { x: 452, y: 122, w: 37, h: 32, offX: 0, offY: 2, sourceW: 37, sourceH: 36 },\n    HT: { x: 374, y: 2, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    ICHI: { x: 330, y: 42, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    IDLE: { x: 289, y: 82, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    INDEX: { x: 241, y: 402, w: 24, h: 36, offX: 7, offY: 0, sourceW: 37, sourceH: 36 },\n    JRT: { x: 248, y: 122, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    KAI: { x: 125, y: 481, w: 29, h: 29, offX: 4, offY: 3, sourceW: 37, sourceH: 36 },\n    KEEP: { x: 207, y: 162, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    KNC: { x: 203, y: 482, w: 19, h: 26, offX: 9, offY: 5, sourceW: 37, sourceH: 36 },\n    KP3R: { x: 166, y: 202, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    LINK: { x: 125, y: 242, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    LRC: { x: 412, y: 122, w: 36, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    MASK: { x: 84, y: 282, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    MCB: { x: 63, y: 482, w: 33, h: 18, offX: 2, offY: 9, sourceW: 37, sourceH: 36 },\n    MKR: { x: 43, y: 322, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    MTA: { x: 2, y: 362, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    NEC: { x: 333, y: 2, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    NEST: { x: 289, y: 42, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    NIOX: { x: 411, y: 162, w: 33, h: 36, offX: 2, offY: 0, sourceW: 38, sourceH: 36 },\n    NMR: { x: 248, y: 82, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    OBTC: { x: 207, y: 122, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    OGN: { x: 166, y: 162, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    OMG: { x: 125, y: 202, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    ONG: { x: 84, y: 242, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    OVR: { x: 43, y: 282, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    PAX: { x: 2, y: 322, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    PBTC: { x: 292, y: 2, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    PLTC: { x: 248, y: 42, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    PNK: { x: 329, y: 242, w: 37, h: 34, offX: 0, offY: 1, sourceW: 37, sourceH: 36 },\n    PNT: { x: 207, y: 82, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    QCAD: { x: 166, y: 122, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    RAI: { x: 166, y: 402, w: 35, h: 36, offX: 1, offY: 0, sourceW: 37, sourceH: 36 },\n    REN: { x: 125, y: 162, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    RENBTC: { x: 84, y: 202, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    RENDOGE: { x: 43, y: 242, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    REP: { x: 2, y: 482, w: 23, h: 28, offX: 7, offY: 4, sourceW: 37, sourceH: 36 },\n    REPT: { x: 2, y: 282, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    RFOX: { x: 251, y: 2, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    RGT: { x: 207, y: 42, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    RICE: { x: 166, y: 82, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    RPL: { x: 125, y: 122, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    RSPT: { x: 84, y: 162, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    RSR: { x: 43, y: 202, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    SMARTCREDIT: { x: 2, y: 242, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    SNT: { x: 210, y: 2, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    SNX: { x: 166, y: 42, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    STAKE: { x: 125, y: 82, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    SUSD: { x: 84, y: 122, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    SUSHI: { x: 370, y: 202, w: 35, h: 34, offX: 1, offY: 1, sourceW: 37, sourceH: 36 },\n    SX: { x: 289, y: 282, w: 35, h: 34, offX: 1, offY: 1, sourceW: 37, sourceH: 36 },\n    TEL: { x: 43, y: 162, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    TRB: { x: 2, y: 202, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    TRYB: { x: 169, y: 2, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    TUSD: { x: 125, y: 42, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    UBT: { x: 84, y: 82, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    UMA: { x: 43, y: 122, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    UNI: { x: 2, y: 162, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    USDC: { x: 371, y: 162, w: 36, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    USDT: { x: 128, y: 2, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    VBZRX: { x: 84, y: 42, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    VETH: { x: 43, y: 82, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    VSP: { x: 2, y: 122, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    WBTC: { x: 87, y: 2, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    WNXM: { x: 43, y: 42, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    WOO: { x: 29, y: 482, w: 30, h: 21, offX: 3, offY: 8, sourceW: 37, sourceH: 36 },\n    YFI: { x: 2, y: 82, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    YFII: { x: 46, y: 2, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    YPIE: { x: 2, y: 42, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n    ZRX: { x: 125, y: 282, w: 37, h: 36, offX: 0, offY: 0, sourceW: 37, sourceH: 36 },\n  },\n}\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/constant/market.ts",
    "content": "export enum FloatTag {\n  increase = 'increase',\n  decrease = 'decrease',\n  none = 'none',\n}\n\nexport type MarketType = `${string}-${string}`\nexport type AMMMarketType = `AMM-${string}-${string}`\nexport type LPTokenType = `LP-${string}-${string}`\n\nexport const PrecisionTree = {\n  1: '0.1',\n  2: '0.01',\n  3: '0.001',\n  4: '0.0001',\n  5: '0.00001',\n  6: '0.000001',\n  7: '0.0000001',\n  8: '0.00000001',\n  9: '0.000000001',\n  10: '0.0000000001',\n  11: '0.00000000001',\n  12: '0.000000000001',\n}\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/constant/miningOuterLinks.ts",
    "content": "export const getMiningLinkList = (lan: string) => {\n  if (lan === 'cn') {\n    lan = 'zh'\n  }\n  return {\n    'BCDT-ETH': `https://loopring.io/#/embed/amm_mining_14_${lan}`,\n    'USDC-USDT': `https://loopring.io/#/embed/orderbook_mining_24_${lan}`,\n    'BKT-USDT': `https://loopring.io/#/embed/orderbook_mining_24_${lan}`,\n  }\n}\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/constant/networks.ts",
    "content": "\nexport const SUPPORTING_NETWORKS = process.env.REACT_APP_CHAIN_IDS!.split(',')\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/constant/notification.ts",
    "content": "/*\nimport { AMMMarketType, MarketType } from \"./market\";\n*/\n// import { CoinKey } from \"../loopring-interface\";\n\nimport { Account } from './account'\nimport { InvestAdvice } from '../loopring-interface'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\n/**\n * export enum RuleType {\n *   AMM_MINING = \"AMM_MINING\",\n *   SWAP_VOLUME_RANKING = \"SWAP_VOLUME_RANKING\",\n *   ORDERBOOK_MINING = \"ORDERBOOK_MINING\",\n * }\n */\nexport enum NOTIFY_COLOR {\n  default = 'default',\n  primary = 'primary',\n  secondary = 'secondary',\n  tertiary = 'tertiary',\n}\n\nexport type INVEST_ITEM = {\n  name: string\n  version: string\n  type: string\n  bannerMobile: string\n  bannerLaptop: string\n  linkRule: string\n  startShow: number\n  endShow: number\n  link: string\n}\n\nexport type NOTIFICATION_ITEM = {\n  version: string //localStore for visited should be unique\n  name: string\n  title: string\n  description1: string\n  description2: string\n  type: string\n  link: `#race-event/${number}/${number}/activities.${string}.json` | string\n  linkIos: string\n  linkAndroid: string\n  startShow: number\n  endShow: number\n  color: NOTIFY_COLOR\n  banner?: string\n  bannerDark?: string\n  webRouter?: string\n  webFlag: boolean\n  versionIosMin: string\n  versionIosMax: string\n  versionAndroidMin: string\n  versionAndroidMax: string\n  linkParam: string\n}\nexport type ACTIVITY = NOTIFICATION_ITEM\nexport type CAMPAIGN_TAG = {\n  name: string\n  type?: 'activity' | 'protocol' | '' //options for Amm , activity|\n  startShow: number\n  endShow: number\n  iconSource: string\n  symbols: Array<string>\n  behavior: 'tooltips' | 'link'\n  content: string\n  webFlag: boolean\n  versionIosMin: string\n  versionIosMax: string\n  versionAndroidMin: string\n  versionAndroidMax: string\n}\n\nexport enum SCENARIO {\n  ORDERBOOK = 'ORDERBOOK',\n  MARKET = 'MARKET',\n  AMM = 'AMM',\n  FIAT = 'FIAT',\n  SWAP = 'SWAP',\n  VAULT = 'VAULT',\n}\nexport type CAMPAIGNTAGCONFIG = {\n  [key in SCENARIO]: CAMPAIGN_TAG[]\n}\nexport type RedPacketConfig = {\n  timeRangeMaxInSecondsToken: number\n  timeRangeMaxInSecondsNFT: number\n  showNFT: boolean\n  showERC20Blindbox: boolean\n}\nexport type NOTIFICATION = {\n  activities: ACTIVITY[]\n  activitiesInvest: ACTIVITY[]\n  notifications: NOTIFICATION_ITEM[]\n  invest: {\n    investAdvice: InvestAdvice[]\n    STAKE: InvestAdvice[]\n  }\n  account?: Account\n  chainId: sdk.ChainId\n  prev?: {\n    endDate: number\n    // prevMonth: string;\n  }\n  campaignTagConfig?: CAMPAIGNTAGCONFIG\n  redPacket: RedPacketConfig\n}\n\nexport type Notify = Omit<NOTIFICATION, 'prev'>\nexport type NOTIFICATIONHEADER<N> = {\n  notifyMap: Notify\n  myNotifyMap: {\n    items: N[]\n    total: number\n    unReads: number\n  }\n}\n\n// export enum SCENARIO {\n//   orderbook = \"orderbook\",\n//   market = \"market\",\n//   Amm = \"Amm\",\n//   Fiat = \"Fiat\",\n//   swap = \"swap\",\n// }\n\n// export  type  CAMPAIGNTAGCONFIG  ={\n//   [key in SCENARIO]: CAMPAIGN_TAG[];\n// }\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/constant/proLayout.ts",
    "content": "import { Layouts } from 'react-grid-layout'\n\nexport enum LayoutConfig {\n  basicLayout,\n  layout1,\n  layout2,\n}\n\nexport const MarketRowHeight = 20\n\nexport enum BreakPoint {\n  xlg = 'xlg',\n  lg = 'lg',\n  md = 'md',\n  sm = 'sm',\n  xs = 'xs',\n  xxs = 'xxs',\n}\n\nexport type ConfigLayout<P = typeof BreakPoint> = {\n  breakpoints: { [key in keyof P]: number }\n  cols: { [key in keyof P]: number }\n  layouts: {\n    [key in keyof P]: Array<{\n      i: string\n      x: number\n      y: number\n      w: number\n      h: number\n      minW: number\n      minH: number\n    }>\n  }\n}\nconst basicLayout: ConfigLayout = {\n  breakpoints: { xlg: 1920, lg: 1600, md: 1200, sm: 960, xs: 768, xxs: 320 },\n  cols: { xlg: 24, lg: 24, md: 24, sm: 12, xs: 12, xxs: 6 },\n  layouts: {\n    xlg: [\n      { i: 'toolbar', x: 0, y: 0, w: 24, h: 9, minW: 24, minH: 9 },\n      { i: 'walletInfo', x: 0, y: 10, w: 4, h: 28, minW: 4, minH: 26 },\n      { i: 'spot', x: 0, y: 14, w: 4, h: 115, minW: 4, minH: 70 },\n      { i: 'market', x: 4, y: 10, w: 4, h: 88, minW: 4, minH: 58 },\n      { i: 'chart', x: 8, y: 10, w: 12, h: 88, minW: 6, minH: 32 },\n      { i: 'market2', x: 20, y: 10, w: 4, h: 88, minW: 4, minH: 36 },\n      { i: 'orderTable', x: 4, y: 64, w: 20, h: 55, minW: 6, minH: 36 },\n    ],\n    lg: [\n      { i: 'toolbar', x: 0, y: 0, w: 24, h: 9, minW: 24, minH: 9 },\n      { i: 'walletInfo', x: 0, y: 10, w: 4, h: 28, minW: 4, minH: 26 },\n      { i: 'spot', x: 0, y: 26, w: 4, h: 89, minW: 4, minH: 70 },\n      { i: 'market', x: 4, y: 10, w: 4, h: 73, minW: 4, minH: 58 },\n      { i: 'chart', x: 8, y: 10, w: 12, h: 73, minW: 6, minH: 32 },\n      { i: 'market2', x: 20, y: 10, w: 4, h: 73, minW: 4, minH: 58 },\n      { i: 'orderTable', x: 4, y: 64, w: 20, h: 44, minW: 6, minH: 36 },\n    ],\n    md: [\n      { i: 'toolbar', x: 0, y: 0, w: 24, h: 9, minW: 24, minH: 9 },\n      { i: 'walletInfo', x: 0, y: 10, w: 5, h: 28, minW: 4, minH: 26 },\n      { i: 'spot', x: 0, y: 9, w: 5, h: 68, minW: 4, minH: 68 },\n      { i: 'market', x: 5, y: 10, w: 5, h: 58, minW: 4, minH: 58 },\n      { i: 'market2', x: 0, y: 0, w: 0, h: 0, minW: 0, minH: 0 },\n      { i: 'chart', x: 10, y: 10, w: 14, h: 58, minW: 6, minH: 32 },\n      { i: 'orderTable', x: 5, y: 64, w: 19, h: 38, minW: 6, minH: 36 },\n    ],\n    sm: [\n      { i: 'toolbar', x: 0, y: 0, w: 12, h: 9, minW: 12, minH: 9 },\n      { i: 'walletInfo', x: 0, y: 10, w: 3, h: 28, minW: 3, minH: 22 },\n      { i: 'spot', x: 0, y: 14, w: 3, h: 66, minW: 3, minH: 66 },\n      { i: 'market', x: 3, y: 10, w: 3, h: 58, minW: 3, minH: 58 },\n      { i: 'market2', x: 0, y: 0, w: 0, h: 0, minW: 0, minH: 0 },\n      { i: 'chart', x: 6, y: 10, w: 6, h: 58, minW: 6, minH: 32 },\n      { i: 'orderTable', x: 3, y: 64, w: 9, h: 36, minW: 6, minH: 36 },\n    ],\n    xs: [\n      { i: 'toolbar', w: 12, h: 17, x: 0, y: 0, minW: 6, minH: 9 },\n      { i: 'walletInfo', w: 4, h: 48, x: 0, y: 121, minW: 3, minH: 22 },\n      { i: 'spot', w: 4, h: 104, x: 0, y: 17, minW: 3, minH: 54 },\n      { i: 'market', w: 4, h: 151, x: 4, y: 17, minW: 3, minH: 58 },\n      { i: 'market2', w: 4, x: 8, y: 17, h: 151, minW: 3, minH: 58 },\n      { i: 'chart', w: 12, h: 80, x: 0, y: 239, minW: 3, minH: 32 },\n      { i: 'orderTable', w: 12, h: 71, x: 0, y: 168, minW: 5, minH: 36 },\n    ],\n    xxs: [\n      { i: 'toolbar', x: 0, y: 0, w: 6, h: 14, minW: 6, minH: 9 },\n      { i: 'walletInfo', x: 0, y: 63, w: 3, h: 51, minW: 3, minH: 22 },\n      { i: 'spot', x: 0, y: 9, w: 3, h: 103, minW: 3, minH: 54 },\n      { i: 'market', x: 3, y: 9, w: 3, h: 154, minW: 3, minH: 58 },\n      { i: 'market2', x: 0, y: 0, w: 0, h: 0, minW: 0, minH: 0 },\n      { i: 'chart', x: 3, y: 125, w: 6, h: 80, minW: 3, minH: 32 },\n      { i: 'orderTable', x: 0, y: 88, w: 6, h: 80, minW: 5, minH: 36 },\n    ],\n  },\n}\n\nconst stopLimitLayout: ConfigLayout = {\n  breakpoints: { xlg: 1920, lg: 1600, md: 1200, sm: 960, xs: 768, xxs: 320 },\n  cols: { xlg: 24, lg: 24, md: 24, sm: 12, xs: 12, xxs: 6 },\n  layouts: {\n    xlg: [\n      { w: 24, h: 9, x: 0, y: 0, i: 'toolbar', minW: 24, minH: 9 },\n      { w: 5, h: 79, x: 0, y: 9, i: 'spot', minW: 4, minH: 68 },\n      { w: 7, h: 79, x: 5, y: 9, i: 'markdown', minW: 4, minH: 20 },\n      { w: 12, h: 78, x: 12, y: 9, i: 'chart', minW: 6, minH: 32 },\n      { w: 24, h: 36, x: 0, y: 88, i: 'orderTable', minW: 6, minH: 36 },\n    ],\n    lg: [\n      { w: 24, h: 9, x: 0, y: 0, i: 'toolbar', minW: 24, minH: 9 },\n      { w: 5, h: 80, x: 0, y: 9, i: 'spot', minW: 4, minH: 68 },\n      { w: 7, h: 44, x: 5, y: 9, i: 'markdown', minW: 4, minH: 20 },\n      { w: 12, h: 44, x: 12, y: 9, i: 'chart', minW: 6, minH: 32 },\n      { w: 19, h: 36, x: 5, y: 53, i: 'orderTable', minW: 6, minH: 36 },\n    ],\n    md: [\n      { i: 'toolbar', x: 0, y: 0, w: 24, h: 9, minW: 24, minH: 9 },\n      { i: 'spot', x: 0, y: 10, w: 5, h: 81, minW: 4, minH: 68 },\n      { i: 'markdown', x: 5, y: 10, w: 7, h: 44, minW: 4, minH: 20 },\n      { i: 'chart', x: 12, y: 10, w: 12, h: 44, minW: 6, minH: 32 },\n      { i: 'orderTable', x: 5, y: 53, w: 19, h: 37, minW: 6, minH: 32 },\n    ],\n    sm: [\n      { i: 'toolbar', x: 0, y: 0, w: 12, h: 9, minW: 12, minH: 9 },\n      // { i: \"walletInfo\", x: 0, y: 10, w: 3, h: 28, minW: 3, minH: 22 },\n      { i: 'spot', x: 0, y: 10, w: 3, h: 94, minW: 3, minH: 66 },\n      { i: 'markdown', x: 3, y: 10, w: 3, h: 58, minW: 3, minH: 20 },\n      // { i: \"market2\", x: 0, y: 0, w: 0, h: 0, minW: 0, minH: 0 },\n      { i: 'chart', x: 6, y: 10, w: 6, h: 58, minW: 6, minH: 32 },\n      { i: 'orderTable', x: 3, y: 64, w: 9, h: 36, minW: 6, minH: 36 },\n    ],\n    xs: [\n      { i: 'toolbar', w: 12, h: 17, x: 0, y: 0, minW: 6, minH: 9 },\n      { i: 'spot', w: 3, h: 72, x: 0, y: 17, minW: 3, minH: 54 },\n      { i: 'markdown', w: 3, h: 72, x: 3, y: 17, minW: 3, minH: 20 },\n      { i: 'chart', w: 6, h: 72, x: 6, y: 17, minW: 3, minH: 32 },\n      { i: 'orderTable', w: 12, h: 71, x: 0, y: 89, minW: 5, minH: 36 },\n    ],\n    xxs: [\n      { i: 'toolbar', w: 6, h: 14, x: 0, y: 0, minW: 6, minH: 9 },\n      { i: 'spot', w: 3, h: 73, x: 0, y: 14, minW: 3, minH: 54 },\n      { i: 'markdown', w: 3, h: 73, x: 3, y: 14, minW: 3, minH: 58 },\n      { i: 'chart', w: 6, h: 80, x: 0, y: 167, minW: 3, minH: 32 },\n      { i: 'orderTable', w: 6, h: 80, x: 0, y: 87, minW: 5, minH: 36 },\n    ],\n  },\n}\n\nexport const layoutConfigs: Array<ConfigLayout> = [basicLayout]\nexport const stopLimitLayoutConfigs: Array<ConfigLayout> = [stopLimitLayout]\n\nexport type LayoutConfigInfo = {\n  currentBreakpoint: BreakPoint\n  mounted: boolean\n  layouts: Layouts\n  compactType: 'vertical' | 'horizontal' | null | undefined\n}\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/constant/router.ts",
    "content": "import AutorenewIcon from '@mui/icons-material/Autorenew';\nimport {\n  AssetsIcon,\n  ContactIcon,\n  ImageIcon,\n  L2MyLiquidityIcon,\n  MintIcon,\n  ProfileIcon,\n  RewardIcon,\n  SecurityIcon,\n  VipIcon,\n  AmmIcon,\n  BlockTradeIcon,\n  CreateNFTIcon,\n  DualInvestIcon,\n  ETHStakingIcon,\n  FiatIcon,\n  LRCStakingIcon,\n  LeverageETHIcon,\n  MyCollectionIcon,\n  MyNFTIcon,\n  OrderBookIcon,\n  OverviewIcon,\n  StopLimitIcon,\n  SwapIcon,\n  VaultHomeIcon,\n  VaultDashboardIcon,\n  VaultTradeIcon2,\n} from '../svg'\nimport { HeaderMenuItemInterface, HeaderMenuTabStatus, InvestAdvice } from '../loopring-interface'\nimport { AddAssetList, InvestAssetRouter, InvestMapType, SendAssetList } from './trade'\nimport { Earnlite, ExchangePro, WalletSite, LOOPRING_DOC, hideDefiEntry } from './setting'\nimport { ChainId } from '@loopring-web/loopring-sdk'\n\nexport const FEED_BACK_LINK = 'https://desk.zoho.com/portal/loopring/en/home'\nexport const headerRoot = 'Landing-page'\nexport const SoursURL = 'https://static.loopring.io/assets/'\nexport const GUARDIAN_URL = 'https://guardian.loopring.io'\nexport const LoopringIPFSSite = 'ipfs.loopring.io'\nexport const LoopringIPFSSiteProtocol = 'https'\nexport const IPFS_LOOPRING_URL = `${LoopringIPFSSiteProtocol}://${LoopringIPFSSite}`\nexport const IPFS_HEAD_URL = 'ipfs://'\nexport const IPFS_HEAD_URL_REG = /^ipfs:\\/\\/(ipfs\\/)?/i\nexport const IPFS_LOOPRING_SITE = 'https://ipfs.loopring.io/ipfs/' // sdk.LOOPRING_URLs.IPFS_META_URL; //`${IPFS_LOOPRING_URL}/ipfs/`;\nexport const BANXA_URLS = {\n  1: 'https://loopring.banxa.com',\n  11155111: 'https://loopring.banxa-sandbox.com',\n}\nexport const LOOPRING_DOCUMENT = 'https://loopring.io/#/document/'\n\nexport enum RouterPath {\n  trade = '/trade',\n  lite = '/trade/lite',\n  pro = '/trade/pro',\n  stoplimit = '/trade/stoplimit',\n  btrade = '/trade/btrade',\n  fiat = '/trade/fiat',\n  markets = '/markets',\n  mining = '/mining',\n  redPacket = '/redPacket',\n  l2assets = '/l2assets',\n  l2records = '/l2assets/history',\n  l2assetsDetail = '/l2assets/assets',\n  layer2 = '/layer2',\n  nft = '/nft',\n  invest = '/invest',\n  investBalance = '/invest/balance',\n  vault = '/portal',\n  //404? loading\n  loading = '/loading',\n}\n\nexport enum InvestType {\n  MyBalance = 0,\n  AmmPool = 1,\n  DeFi = 2,\n  Overview = 3,\n  Dual = 4,\n  Stack = 5,\n  LeverageETH = 6,\n}\nexport const InvestRouter = [\n  'balance',\n  'ammpool',\n  'defi',\n  'overview',\n  'dual',\n  'stakelrc',\n  'leverageETH',\n]\n//\n//\nexport enum Layer2RouterID {\n  security = 'security',\n  vip = 'vip',\n  contact = 'contact',\n  referralrewards = 'referralrewards',\n  forcewithdraw = 'forcewithdraw',\n  notification = 'notification',\n}\n// export enum ProfileKey {\n//   security = 'security',\n//   vip = 'vip',\n//   contact = 'contact',\n//   referralrewards = 'referralrewards',\n//   forcewithdraw = 'forcewithdraw',\n//   notification = 'notification',\n// }\n\nexport const Profile = {\n  security: [\n    {\n      icon: SecurityIcon,\n      router: { path: `${RouterPath.layer2}/${Layer2RouterID.security}` },\n      label: {\n        id: 'security',\n        i18nKey: 'labelSecurity',\n      },\n    },\n  ],\n  vip: [\n    {\n      icon: VipIcon,\n      router: { path: `${RouterPath.layer2}/${Layer2RouterID.vip}` },\n      label: {\n        id: 'vip',\n        i18nKey: 'labelVipPanel',\n      },\n    },\n  ],\n  contact: [\n    {\n      icon: ContactIcon,\n      router: { path: `${RouterPath.layer2}/${Layer2RouterID.contact}` },\n      label: {\n        id: 'contact',\n        i18nKey: 'labelContactsPanel',\n      },\n    },\n  ],\n  referralrewards: [\n    {\n      icon: RewardIcon,\n      router: { path: `${RouterPath.layer2}/${Layer2RouterID.referralrewards}` },\n      label: {\n        id: 'referralrewards',\n        i18nKey: 'labelReferralReward',\n      },\n    },\n  ],\n}\n\nexport enum ButtonComponentsMap {\n  Download = 'Download',\n  Notification = 'Notification',\n  Setting = 'Setting',\n  ProfileMenu = 'ProfileMenu',\n  WalletConnect = 'WalletConnect',\n  TestNet = 'TestNet',\n  ColorSwitch = 'ColorSwitch',\n}\n\nexport const toolBarAvailableItem: ButtonComponentsMap[] = [\n  ButtonComponentsMap.Notification,\n  ButtonComponentsMap.Setting,\n  ButtonComponentsMap.ProfileMenu,\n  ButtonComponentsMap.WalletConnect,\n  ButtonComponentsMap.TestNet,\n]\n\n// export enum GuardianToolBarComponentsMap {\n//   Notification,\n//   TestNet,\n//   WalletConnect,\n// }\n\nexport const GuardianToolBarAvailableItem: ButtonComponentsMap[] = [\n  ButtonComponentsMap.Notification,\n  ButtonComponentsMap.TestNet,\n  ButtonComponentsMap.WalletConnect,\n]\nexport let headerGuardianToolBarData: {\n  [key in ButtonComponentsMap]?: {\n    buttonComponent: ButtonComponentsMap\n    handleClick?: (props: any) => void\n    [key: string]: any\n  }\n} = {\n  [ButtonComponentsMap.Notification]: {\n    buttonComponent: ButtonComponentsMap.Notification,\n    label: 'labelNotification',\n  },\n  [ButtonComponentsMap.TestNet]: { buttonComponent: ButtonComponentsMap.TestNet },\n  [ButtonComponentsMap.WalletConnect]: {\n    buttonComponent: ButtonComponentsMap.WalletConnect,\n    label: 'labelConnectWallet',\n    accountState: undefined,\n    handleClick: undefined,\n  },\n}\nexport let headerToolBarData: {\n  [key in ButtonComponentsMap]?: {\n    buttonComponent: ButtonComponentsMap\n    handleClick?: (props: any) => void\n    [key: string]: any\n  }\n} = {\n  [ButtonComponentsMap.Notification]: {\n    buttonComponent: ButtonComponentsMap.Notification,\n    label: 'labelNotification',\n  },\n  [ButtonComponentsMap.Setting]: {\n    buttonComponent: ButtonComponentsMap.Setting,\n    label: 'labelSetting',\n  },\n  [ButtonComponentsMap.ProfileMenu]: {\n    buttonComponent: ButtonComponentsMap.ProfileMenu,\n    i18nDescription: 'labelProfile',\n    readyState: undefined,\n  },\n  [ButtonComponentsMap.WalletConnect]: {\n    buttonComponent: ButtonComponentsMap.WalletConnect,\n    label: 'labelConnectWallet',\n    accountState: undefined,\n    handleClick: undefined,\n  },\n}\n\nexport let headerToolBarDataMobile: {\n  [key in ButtonComponentsMap]?: {\n    buttonComponent: ButtonComponentsMap\n    handleClick?: (props: any) => void\n    [key: string]: any\n  }\n} = {\n  // [ButtonComponentsMap.Download]: {\n  //   buttonComponent: ButtonComponentsMap.Download,\n  //   url: WalletSite,\n  // },\n  // [ButtonComponentsMap.Notification]: {\n  //   buttonComponent: ButtonComponentsMap.Notification,\n  //   label: 'labelNotification',\n  // },\n  // [ButtonComponentsMap.Setting]: {\n  //   buttonComponent: ButtonComponentsMap.Setting,\n  //   label: 'labelSetting',\n  // },\n  [ButtonComponentsMap.ProfileMenu]: {\n    buttonComponent: ButtonComponentsMap.ProfileMenu,\n    i18nDescription: 'labelProfile',\n    readyState: undefined,\n  },\n  [ButtonComponentsMap.WalletConnect]: {\n    buttonComponent: ButtonComponentsMap.WalletConnect,\n    label: 'labelConnectWallet',\n    accountState: undefined,\n    handleClick: undefined,\n  },\n}\n\n// export const toolBarMobileAvailableItem = [\n//   ButtonComponentsMap.Download,\n//   ButtonComponentsMap.Notification,\n//   ButtonComponentsMap.Setting,\n//   ButtonComponentsMap.WalletConnect,\n// ]\n\nexport enum RouterMainKey {\n  lite = 'lite',\n  pro = 'pro',\n  stoplimit = 'stoplimit',\n  btrade = 'btrade',\n  fiat = 'fiat',\n  markets = 'markets',\n  mining = 'mining',\n  redPacket = 'redPacket',\n  l2assets = 'l2assets',\n  layer2 = 'layer2',\n  nft = 'nft',\n  invest = 'invest',\n  earn = 'earn',\n  vault = 'portal',\n}\n\nexport enum NFTSubRouter {\n  transactionNFT = 'transactionNFT',\n  mintNFTLanding = 'mintNFTLanding',\n  mintNFT = 'mintNFT',\n  mintNFTAdvance = 'mintNFTAdvance',\n  depositNFT = 'depositNFT',\n  myCollection = 'myCollection',\n  addCollection = 'addCollection',\n  editCollection = 'editCollection',\n  addLegacyCollection = 'addLegacyCollection',\n  importLegacyCollection = 'importLegacyCollection',\n  assetsNFT = 'assetsNFT',\n}\n\nexport let layer2ItemData: Array<HeaderMenuItemInterface> = [\n  {\n    label: {\n      id: 'lite',\n      i18nKey: 'labelClassic',\n      description: 'labelClassicDescription',\n      icon: SwapIcon,\n    },\n    router: { path: RouterPath.lite + '/${pair}' },\n  },\n  {\n    label: {\n      id: 'pro',\n      i18nKey: 'labelAdvanced',\n      description: 'labelAdvancedDescription',\n      icon: OrderBookIcon,\n    },\n    router: { path: RouterPath.pro + '/${pair}' },\n  },\n  {\n    label: {\n      id: 'stopLimit',\n      i18nKey: 'labelStopLimit',\n      description: 'labelStopLimitDescription',\n      icon: StopLimitIcon,\n    },\n    router: { path: RouterPath.stoplimit + '/${pair}' },\n  },\n  // {\n  //   label: {\n  //     id: 'btrade',\n  //     i18nKey: 'labelBtradeTrade',\n  //     description: 'labelBtradeTradeDescription',\n  //     icon: BlockTradeIcon,\n  //   },\n  //   router: { path: RouterPath.btrade + '/${pair}' },\n  // },\n\n  // {\n  //   label: {\n  //     id: 'fiat',\n  //     i18nKey: 'labelFiat',\n  //     description: 'labelFiatDescription',\n  //     icon: FiatIcon,\n  //   },\n  //   router: { path: RouterPath.fiat },\n  // },\n]\n\nexport enum VaultKey {\n  VAULT_HOME = 'portalHome',\n  VAULT_DASHBOARD = 'portalDashboard',\n  VAULT_TRADE = 'portalTrade',\n}\n\nexport let vaultItemData: Array<HeaderMenuItemInterface> = [\n  {\n    label: {\n      id: VaultKey.VAULT_DASHBOARD,\n      i18nKey: 'labelVaultDashboard',\n      description: 'labelVaultDashboardDes',\n      icon: VaultDashboardIcon,\n    },\n    router: { path: RouterPath.vault + `/${VaultKey.VAULT_DASHBOARD}` },\n  },\n  {\n    label: {\n      id: VaultKey.VAULT_HOME,\n      i18nKey: 'labelVaultHome',\n      description: 'labelVaultHomeDes',\n      icon: VaultHomeIcon,\n    },\n    router: { path: RouterPath.vault + `/${VaultKey.VAULT_HOME}`  },\n  },\n  {\n    label: {\n      id: VaultKey.VAULT_TRADE,\n      i18nKey: 'labelVaultTradeTabTitle',\n      description: 'labelVaultTradeTabDes', \n      icon: AutorenewIcon, \n    },\n    router: { path: RouterPath.vault + `/${VaultKey.VAULT_TRADE}` },\n  },\n]\n\nexport const orderDisableList = ['Liquidity', 'Markets', 'Trading', 'Mining']\nexport const ammDisableList = ['Liquidity']\n\nexport const headerMenuLandingData: Array<HeaderMenuItemInterface> = [\n  ...(!hideDefiEntry ? [{\n    label: {\n      id: 'loopringLite',\n      i18nKey: 'labelNavEarn',\n      description: 'labelNavEarnDes',\n    },\n    router: { path: Earnlite },\n    logo: {\n      dark: SoursURL + 'images/landing_page_nav_earn_dark.png',\n      light: SoursURL + 'images/landing_page_nav_earn_light.png',\n    }\n  }] : []),\n  {\n    label: {\n      id: 'loopringPro',\n      i18nKey: 'labelNavPro',\n      description: 'labelNavProDes',\n    },\n    router: { path: ExchangePro },\n    logo: {\n      dark: SoursURL + 'images/landing_page_nav_pro_dark.png',\n      light: SoursURL + 'images/landing_page_nav_pro_light.png',\n    }\n  },\n  ...(!hideDefiEntry ? [{\n    label: {\n      id: 'wallet',\n      i18nKey: 'labelNavWallet',\n      description: 'labelNavWalletDes',\n    },\n    router: { path: WalletSite },\n    logo: {\n      dark: SoursURL + 'images/landing_page_nav_wallet_dark.png',\n      light: SoursURL + 'images/landing_page_nav_wallet_light.png',\n    }\n  }] : []),\n  {\n    label: {\n      id: 'doc',\n      i18nKey: 'labelNavDoc',\n      description: 'labelNavDocDes',\n    },\n    router: { path: LOOPRING_DOC },\n    logo: {\n      dark: SoursURL + 'images/landing_page_nav_doc_dark.png',\n      light: SoursURL + 'images/landing_page_nav_doc_light.png',\n    }\n  },\n]\nexport const subMenuLayer2 = {\n  assetsGroup: [\n    {\n      icon: AssetsIcon,\n      router: { path: RouterPath.l2assetsDetail },\n      label: {\n        id: 'assets',\n        i18nKey: 'labelAssets',\n      },\n    },\n  ],\n  profileGroup: [\n    {\n      icon: ProfileIcon,\n      router: { path: `${RouterPath.layer2}/${Layer2RouterID.security}` },\n      label: {\n        id: 'security',\n        i18nKey: 'labelSecurity',\n      },\n    },\n    {\n      icon: VipIcon,\n      router: { path: `${RouterPath.layer2}/${Layer2RouterID.vip}` },\n      label: {\n        id: 'vip',\n        i18nKey: 'labelVipPanel',\n      },\n    },\n  ],\n}\n\nexport const subMenuInvest = [\n  // {\n  //   icon: L2MyLiquidityIcon,\n  //   router: { path: `${RouterPath.invest}/${InvestRouter[InvestType.Overview]}` },\n  //   label: {\n  //     id: 'overview',\n  //     i18nKey: 'labelInvestOverview',\n  //     description: 'labelInvestOverviewDes',\n  //     icon: OverviewIcon,\n  //   },\n  // },\n  // {\n  //   icon: L2MyLiquidityIcon,\n  //   router: { path: `${RouterPath.invest}/${InvestAssetRouter.DUAL}` },\n  //   label: {\n  //     id: 'dual',\n  //     i18nKey: 'labelInvestDual',\n  //     description: 'labelInvestDualDes',\n  //     icon: DualInvestIcon,\n  //   },\n  // },\n  {\n    icon: L2MyLiquidityIcon,\n    router: { path: `${RouterPath.invest}/${InvestAssetRouter.STAKE}` },\n    label: {\n      id: 'defi',\n      i18nKey: 'labelInvestDefi',\n      description: 'labelInvestDefiDes',\n      icon: ETHStakingIcon,\n    },\n  },\n  {\n    icon: L2MyLiquidityIcon,\n    router: { path: `${RouterPath.invest}/${InvestAssetRouter.LEVERAGEETH}` },\n    label: {\n      id: 'leverageeth',\n      i18nKey: 'labelInvestLeverageETH',\n      description: 'labelInvestLeverageETHDes',\n      icon: LeverageETHIcon,\n    },\n  },\n  {\n    icon: L2MyLiquidityIcon,\n    router: { path: `${RouterPath.invest}/${InvestAssetRouter.AMM}` },\n    label: {\n      id: 'ammpool',\n      i18nKey: 'labelInvestAmm',\n      description: 'labelInvestAmmDes',\n      icon: AmmIcon,\n    },\n  },\n  // {\n  //   icon: L2MyLiquidityIcon,\n  //   router: { path: `${RouterPath.invest}/${InvestAssetRouter.STAKELRC}` },\n  //   label: {\n  //     id: 'stackonesided',\n  //     i18nKey: 'labelInvestStakeLRC',\n  //     description: 'labelInvestStakeLRCDes',\n  //     icon: LRCStakingIcon,\n  //   },\n  // },\n]\n// export enum INVEST_TAB {\n//   pools = 'pools',\n//   lido = 'lido',\n//   staking = 'staking',\n//   dual = 'dual',\n//   leverageETH = 'leverageETH',\n// }\n\nexport const INVEST_TABS = [\n  { tab: InvestAssetRouter.DUAL, label: 'labelInvestDualTitle' },\n  { tab: InvestAssetRouter.STAKE, label: 'labelInvestDefiTitle' },\n  { tab: InvestAssetRouter.LEVERAGEETH, label: 'labelLeverageETHTitle' },\n  { tab: InvestAssetRouter.AMM, label: 'labelLiquidityPageTitle' },\n  { tab: InvestAssetRouter.STAKELRC, label: 'labelInvestLRCTitle' },\n]\n\n\nexport const DEFI_CONFIG = {\n  products: {\n    TAIKOHEKLA: [] as string[],\n    TAIKO: [] as string[],\n    ETHEREUM: ['LIDO', 'ROCKETPOOL'],\n    GOERLI: ['ROCKETPOOL'],\n    SEPOLIA: ['LIDO'],\n    ARBGOERLI: ['ROCKETPOOL'],\n    BASE: [],\n    BASESEPOLIA: [],\n  },\n  MARKETS: {\n    TAIKOHEKLA: [] as string[],\n    TAIKO: [] as string[],\n    ETHEREUM: ['RETH-ETH', 'WSTETH-ETH'],\n    GOERLI: ['RETH-ETH'],\n    SEPOLIA: ['WSTETH-ETH'],\n    ARBGOERLI: ['RETH-ETH'],\n    BASE: [],\n    BASESEPOLIA: [],\n  },\n}\nexport const LEVERAGE_ETH_CONFIG = {\n  coins: {\n    TAIKOHEKLA: [] as string[],\n    TAIKO: [] as string[],\n    ETHEREUM: ['CIETH'],\n    GOERLI: ['WSTETH'],\n    SEPOLIA: ['WSTETH'],\n    ARBGOERLI: ['WSTETH'],\n    BASE: ['WSTETH'],\n    BASESEPOLIA: ['WSTETH'],\n  },\n  types: {\n    TAIKOHEKLA: [] as string[],\n    TAIKO: [] as string[],\n    ETHEREUM: ['cian'],\n    GOERLI: ['lido'],\n    SEPOLIA: ['lido'],\n    ARBGOERLI: ['lido'],\n    BASE: [],\n    BASESEPOLIA: [],\n  },\n  products: {\n    TAIKOHEKLA: [] as string[],\n    TAIKO: [] as string[],\n    ETHEREUM: ['CIAN'],\n    GOERLI: ['LIDO'],\n    SEPOLIA: ['LIDO'],\n    ARBGOERLI: ['LIDO'],\n    BASE: ['LIDO'],\n    BASESEPOLIA: ['LIDO'],\n  },\n  MARKETS: {\n    TAIKOHEKLA: [] as string[],\n    TAIKO: [] as string[],\n    ETHEREUM: ['CIETH-ETH'],\n    GOERLI: ['WSTETH-ETH'],\n    SEPOLIA: ['WSTETH-ETH'],\n    ARBGOERLI: ['WSTETH-ETH'],\n    BASE: [],\n    BASESEPOLIA: [],\n  },\n  // ['LIDO,ROCKETPOOL', 'CIAN'] : ['ROCKETPOOL', 'LIDO']\n}\n\nexport const DUAL_CONFIG = {\n  products: {\n    TAIKOHEKLA: ['PIONEX'] as string[],\n    TAIKO: ['PIONEX'] as string[],\n    ETHEREUM: ['PIONEX'],\n    GOERLI: ['PIONEX'],\n    SEPOLIA: ['PIONEX'],\n    ARBGOERLI: ['PIONEX'],\n    BASE: ['PIONEX'],\n    BASESEPOLIA: ['PIONEX'],\n  },\n}\n\nexport const subMenuNFT = {\n  NFTGroup: [\n    {\n      icon: AssetsIcon,\n      router: { path: `${RouterPath.nft}/${NFTSubRouter.assetsNFT}` },\n      label: {\n        id: 'assetsNFT',\n        i18nKey: 'labelMyAssetsNFT',\n        description: 'labelMyAssetsNFTDes',\n        icon: MyNFTIcon,\n      },\n    },\n    // {\n    //   icon: MintIcon,\n    //   router: { path: `${RouterPath.nft}/${NFTSubRouter.mintNFTLanding}` },\n    //   label: {\n    //     id: 'mintNFT',\n    //     i18nKey: 'labelMintNFT',\n    //     description: 'labelMintNFTDes',\n    //     icon: CreateNFTIcon,\n    //   },\n    // },\n    {\n      icon: ImageIcon,\n      router: { path: `${RouterPath.nft}/${NFTSubRouter.myCollection}` },\n      label: {\n        id: 'collection',\n        i18nKey: 'labelMyCollection',\n        description: 'labelMyCollectionDes',\n        icon: MyCollectionIcon,\n      },\n    },\n  ],\n}\nexport const FOOTER_LIST_MAP = {\n  About: [\n    {\n      linkName: 'Org', // loopring.org\n      linkHref: 'https://loopring.org',\n    },\n    {\n      linkName: 'Terms', //Terms of service\n      linkHref: 'https://loopring.io/#/document/terms_en.md',\n    },\n    {\n      linkName: 'Privacy', //Privacy policy\n      linkHref: LOOPRING_DOCUMENT + 'privacy_en.md',\n    },\n    {\n      linkName: 'Risks', //Risks Disclosure\n      linkHref: LOOPRING_DOCUMENT + 'risks_en.md',\n    },\n  ],\n  Platform: [\n    {\n      linkName: 'Fees', //Fees\n      linkHref: LOOPRING_DOCUMENT + 'dex_fees_en.md',\n    },\n    {\n      linkName: 'VIP', //VIP\n      linkHref: 'https://medium.loopring.io/introducing-loopring-vip-tiers-c6f73d753bac',\n    },\n    {\n      linkName: 'Referrals', //Referrals\n      linkHref:\n        'https://medium.loopring.io/loopring-exchange-launches-referral-program-c61777f072d1',\n    },\n  ],\n}\n\nexport const MEDIA_LIST = [\n  {\n    linkName: 'Discord', //color={\"inherit\"} fontSize={\"large\"}\n    linkHref: 'https://discord.com/invite/KkYccYp',\n  },\n  {\n    linkName: 'Twitter',\n    linkHref: 'https://twitter.com/loopringorg',\n  },\n  {\n    linkName: 'Youtube',\n    linkHref: 'https://www.youtube.com/c/Loopring',\n  },\n  {\n    linkName: 'Medium',\n    linkHref: 'https://medium.com/loopring-protocol',\n  },\n]\n\nexport const headerMenuData: Array<HeaderMenuItemInterface> = [\n  {\n    label: {\n      id: 'home',\n      i18nKey: 'labelHome',\n    },\n    router: { path: `/pro` },\n    status: HeaderMenuTabStatus.default,\n  },\n  {\n    label: {\n      id: 'L2Assets',\n      i18nKey: 'labelAssets',\n    },\n    router: { path: `${RouterPath.l2assets}` },\n    status: HeaderMenuTabStatus.default,\n  },\n  {\n    label: {\n      id: 'Markets',\n      i18nKey: 'labelMarkets',\n    },\n    router: { path: `${RouterPath.markets}` },\n    status: HeaderMenuTabStatus.default,\n  },\n  {\n    label: {\n      id: 'Trade',\n      i18nKey: 'labelTrade',\n    },\n    status: HeaderMenuTabStatus.default,\n    child: layer2ItemData,\n  },\n  {\n    label: {\n      id: 'Invest',\n      i18nKey: 'labelInvest',\n    },\n    router: { path: `${RouterPath.invest}/${InvestRouter[InvestType.Overview]}` },\n    status: HeaderMenuTabStatus.default,\n    child: subMenuInvest,\n  },\n  // {\n  //   label: {\n  //     id: 'vault',\n  //     i18nKey: 'labelVault',\n  //     description: 'labelVaultDescription',\n  //   },\n  //   router: { path: `${RouterPath.vault}` },\n  //   status: HeaderMenuTabStatus.default,\n  //   child: vaultItemData,\n  // },\n  {\n    label: {\n      id: 'NFT',\n      i18nKey: 'labelNFT',\n    },\n    router: { path: `${RouterPath.nft}` },\n    status: HeaderMenuTabStatus.default,\n    child: subMenuNFT,\n  },\n]\n\nexport const ammAdvice: InvestAdvice = {\n  type: InvestMapType.AMM,\n  router: `${RouterPath.invest}/${InvestAssetRouter.AMM}`,\n  banner: SoursURL + 'images/icon-amm.svg',\n  titleI18n: 'labelInvestAmm',\n  desI18n: 'labelInvestAmmDes',\n  notification: '',\n  enable: true,\n}\nexport const defiAdvice: InvestAdvice = {\n  type: InvestMapType.STAKE,\n  router: `${RouterPath.invest}/${InvestAssetRouter.STAKE}`,\n  notification: '',\n  banner: SoursURL + 'images/icon-lido.svg',\n  titleI18n: 'labelInvestDefi',\n  desI18n: 'labelInvestDefiDes',\n  enable: true,\n}\nexport const defiWSTETHAdvice: InvestAdvice = {\n  type: InvestMapType.STAKE,\n  router: `${RouterPath.invest}/${InvestAssetRouter.STAKE}/WSTETH`,\n  notification: '',\n  banner: SoursURL + 'images/icon-lido2.svg',\n  titleI18n: 'labelInvestWSTETH',\n  desI18n: 'labelInvestWSTETHDes',\n  enable: true,\n  project: 'Lido',\n  market: 'WSTETH-ETH',\n}\nexport const defiRETHAdvice: InvestAdvice = {\n  type: InvestMapType.STAKE,\n  router: `${RouterPath.invest}/${InvestAssetRouter.STAKE}/RETH`,\n  notification: '',\n  banner: SoursURL + 'images/icon-pocket.svg',\n  titleI18n: 'labelInvestRETH',\n  desI18n: 'labelInvestRETHDes',\n  enable: true,\n  project: 'Rocket Pool',\n  market: 'RETH-ETH',\n}\n\nexport const dualAdvice: InvestAdvice = {\n  type: InvestMapType.DUAL,\n  router: `${RouterPath.invest}/${InvestAssetRouter.DUAL}`,\n  notification: '',\n  banner: SoursURL + 'images/icon-dual.svg',\n  titleI18n: 'labelInvestDual',\n  desI18n: 'labelInvestDualDes',\n  enable: true,\n}\nexport const stakeAdvice: InvestAdvice = {\n  type: InvestMapType.STAKELRC,\n  router: `${RouterPath.invest}/${InvestAssetRouter.STAKELRC}`,\n  notification: '',\n  banner: SoursURL + 'images/icon-stake-lrc.svg',\n  titleI18n: 'labelInvestStakeLRC',\n  desI18n: 'labelInvestStakeLRCDes',\n  enable: true,\n}\nexport const leverageETHAdvice: InvestAdvice = {\n  type: InvestMapType.LEVERAGEETH,\n  router: `${RouterPath.invest}/${InvestAssetRouter.LEVERAGEETH}`,\n  notification: '',\n  banner: SoursURL + 'images/icon-leverage-ETH.svg',\n  titleI18n: 'labelInvestLeverageETH',\n  desI18n: 'labelInvestLeverageETHDes',\n  enable: true,\n  project: 'Leveraged ETH Staking',\n  market: 'CIETH-ETH',\n}\nexport const DEFI_ADVICE_MAP = {\n  WSTETH: defiWSTETHAdvice,\n  RETH: defiRETHAdvice,\n  CIETH: leverageETHAdvice,\n}\n\nexport enum RecordTabIndex {\n  Transactions = 'Transactions',\n  Trades = 'Trades',\n  AmmRecords = 'AmmRecords',\n  Orders = 'Orders',\n  DefiRecords = 'DefiRecords',\n  DualRecords = 'DualRecords',\n  SideStakingRecords = 'SideStakingRecords',\n  BtradeSwapRecords = 'BtradeSwapRecords',\n  StopLimitRecords = 'StopLimitRecords',\n  leverageETHRecords = 'leverageETHRecords',\n  VaultRecords = 'VaultRecords',\n  TaikoLockRecords = 'TaikoLockRecords',\n}\n\nexport enum AssetTabIndex {\n  Tokens = 'Tokens',\n  Invests = 'Invests',\n  RedPacket = 'RedPacket',\n  Rewards = 'Rewards',\n}\n\nexport enum RedPacketRouterIndex {\n  create = 'create',\n  records = 'records',\n  markets = 'markets',\n}\nexport enum RedPacketRecordsTabIndex {\n  Received = 'Received',\n  Send = 'Send',\n  NFTReceived = 'NFTReceived',\n  NFTSend = 'NFTSend',\n  BlindBoxReceived = 'BlindBoxReceived',\n  BlindBoxSend = 'BlindBoxSend',\n  NFTsUnClaimed = 'NFTsUnClaimed',\n  BlindBoxUnClaimed = 'BlindBoxUnClaimed',\n}\n\nexport enum TabOrderIndex {\n  orderOpenTable = 'orderOpenTable',\n  orderHistoryTable = 'orderHistoryTable',\n}\n\nexport const headerMenuDataMap: { [key: string]: HeaderMenuItemInterface[] } = {\n  TAIKOHEKLA:[\n    {\n      label: {\n        id: 'home',\n        i18nKey: 'labelHome',\n      },\n      router: { path: `/pro` },\n      status: HeaderMenuTabStatus.default,\n    },\n    {\n      label: {\n        id: 'L2Assets',\n        i18nKey: 'labelAssets',\n      },\n      router: { path: `${RouterPath.l2assets}` },\n      status: HeaderMenuTabStatus.default,\n    },\n    {\n      label: {\n        id: 'Markets',\n        i18nKey: 'labelMarkets',\n      },\n      router: { path: `${RouterPath.markets}` },\n      status: HeaderMenuTabStatus.default,\n    },\n    {\n      label: {\n        id: 'Trade',\n        i18nKey: 'labelTrade',\n      },\n      status: HeaderMenuTabStatus.default,\n      child: [\n        {\n          label: {\n            id: 'lite',\n            i18nKey: 'labelClassic',\n            description: 'labelClassicDescription',\n            icon: SwapIcon,\n          },\n          router: { path: RouterPath.lite + '/${pair}' },\n        },\n        {\n          label: {\n            id: 'pro',\n            i18nKey: 'labelAdvanced',\n            description: 'labelAdvancedDescription',\n            icon: OrderBookIcon,\n          },\n          router: { path: RouterPath.pro + '/${pair}' },\n        },\n        {\n          label: {\n            id: 'stopLimit',\n            i18nKey: 'labelStopLimit',\n            description: 'labelStopLimitDescription',\n            icon: StopLimitIcon,\n          },\n          router: { path: RouterPath.stoplimit + '/${pair}' },\n        },\n        // {\n        //   label: {\n        //     id: 'btrade',\n        //     i18nKey: 'labelBtradeTrade',\n        //     description: 'labelBtradeTradeDescription',\n        //     icon: BlockTradeIcon,\n        //   },\n        //   router: { path: RouterPath.btrade + '/${pair}' },\n        // },\n      ]\n    },\n    {\n      label: {\n        id: 'vault',\n        i18nKey: 'labelVault',\n        description: 'labelVaultDescription',\n      },\n      router: { path: `${RouterPath.vault}` },\n      status: HeaderMenuTabStatus.default,\n      child: vaultItemData,\n    },\n    {\n      label: {\n        id: 'Invest',\n        i18nKey: 'labelInvest',\n      },\n      router: { path: `${RouterPath.invest}/${InvestRouter[InvestType.Overview]}` },\n      status: HeaderMenuTabStatus.default,\n      child: [\n        // {\n        //   icon: L2MyLiquidityIcon,\n        //   router: { path: `${RouterPath.invest}/${InvestRouter[InvestType.Overview]}` },\n        //   label: {\n        //     id: 'overview',\n        //     i18nKey: 'labelInvestOverview',\n        //     description: 'labelInvestOverviewDes',\n        //     icon: OverviewIcon,\n        //   },\n        // },\n        {\n          icon: L2MyLiquidityIcon,\n          router: { path: `${RouterPath.invest}/${InvestAssetRouter.DUAL}` },\n          label: {\n            id: 'dual',\n            i18nKey: 'labelInvestDual',\n            description: 'labelInvestDualDes',\n            icon: DualInvestIcon,\n          },\n        },\n        {\n          icon: L2MyLiquidityIcon,\n          router: { path: `${RouterPath.invest}/${InvestAssetRouter.AMM}` },\n          label: {\n            id: 'ammpool',\n            i18nKey: 'labelInvestAmm',\n            description: 'labelInvestAmmDes',\n            icon: AmmIcon,\n          },\n        },\n      ] as HeaderMenuItemInterface[]\n    },\n  ],\n  TAIKO:[\n    {\n      label: {\n        id: 'home',\n        i18nKey: 'labelHome',\n      },\n      router: { path: `/pro` },\n      status: HeaderMenuTabStatus.default,\n    },\n    {\n      label: {\n        id: 'L2Assets',\n        i18nKey: 'labelAssets',\n      },\n      router: { path: `${RouterPath.l2assets}` },\n      status: HeaderMenuTabStatus.default,\n    },\n    {\n      label: {\n        id: 'Markets',\n        i18nKey: 'labelMarkets',\n      },\n      router: { path: `${RouterPath.markets}` },\n      status: HeaderMenuTabStatus.default,\n    },\n    {\n      label: {\n        id: 'Trade',\n        i18nKey: 'labelTrade',\n      },\n      status: HeaderMenuTabStatus.default,\n      child: [\n        {\n          label: {\n            id: 'lite',\n            i18nKey: 'labelClassic',\n            description: 'labelClassicDescription',\n            icon: SwapIcon,\n          },\n          router: { path: RouterPath.lite + '/${pair}' },\n        },\n        {\n          label: {\n            id: 'pro',\n            i18nKey: 'labelAdvanced',\n            description: 'labelAdvancedDescription',\n            icon: OrderBookIcon,\n          },\n          router: { path: RouterPath.pro + '/${pair}' },\n        },\n        {\n          label: {\n            id: 'stopLimit',\n            i18nKey: 'labelStopLimit',\n            description: 'labelStopLimitDescription',\n            icon: StopLimitIcon,\n          },\n          router: { path: RouterPath.stoplimit + '/${pair}' },\n        },\n        // {\n        //   label: {\n        //     id: 'btrade',\n        //     i18nKey: 'labelBtradeTrade',\n        //     description: 'labelBtradeTradeDescription',\n        //     icon: BlockTradeIcon,\n        //   },\n        //   router: { path: RouterPath.btrade + '/${pair}' },\n        // },\n      ]\n    },\n    {\n      label: {\n        id: 'vault',\n        i18nKey: 'labelVault',\n        description: 'labelVaultDescription',\n      },\n      router: { path: `${RouterPath.vault}` },\n      status: HeaderMenuTabStatus.default,\n      child: vaultItemData,\n    },\n    {\n      label: {\n        id: 'Invest',\n        i18nKey: 'labelInvest',\n      },\n      router: { path: `${RouterPath.invest}/${InvestRouter[InvestType.Overview]}` },\n      status: HeaderMenuTabStatus.default,\n      child: [\n        // {\n        //   icon: L2MyLiquidityIcon,\n        //   router: { path: `${RouterPath.invest}/${InvestRouter[InvestType.Overview]}` },\n        //   label: {\n        //     id: 'overview',\n        //     i18nKey: 'labelInvestOverview',\n        //     description: 'labelInvestOverviewDes',\n        //     icon: OverviewIcon,\n        //   },\n        // },\n        {\n          icon: L2MyLiquidityIcon,\n          router: { path: `${RouterPath.invest}/${InvestAssetRouter.DUAL}` },\n          label: {\n            id: 'dual',\n            i18nKey: 'labelInvestDual',\n            description: 'labelInvestDualDes',\n            icon: DualInvestIcon,\n          },\n        },\n        {\n          icon: L2MyLiquidityIcon,\n          router: { path: `${RouterPath.invest}/${InvestAssetRouter.AMM}` },\n          label: {\n            id: 'ammpool',\n            i18nKey: 'labelInvestAmm',\n            description: 'labelInvestAmmDes',\n            icon: AmmIcon,\n          },\n        },\n      ] as HeaderMenuItemInterface[]\n    },\n  ],\n  ETHEREUM: headerMenuData,\n  GOERLI: headerMenuData,\n  SEPOLIA: headerMenuData,\n  ARBGOERLI: headerMenuData,\n  BASE: headerMenuData,\n  BASESEPOLIA: headerMenuData,\n}\n\nexport const TokenPriceBase = {\n  TAIKOHEKLA: '0x931c7ada32c20b9d565cab616fe9976154e29809', \n  TAIKO: '0x07d83526730c7438048d55a4fc0b850e2aab6f0b', \n  ETHEREUM: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',\n  GOERLI: '0xd4e71c4bb48850f5971ce40aa428b09f242d3e8a',\n  SEPOLIA: '0xa7bc5a2731803be668090125b5074555f91cbc9d',\n  ARBGOERLI: '0xd4e71c4bb48850f5971ce40aa428b09f242d3e8a',\n  BASE: '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913',\n  BASESEPOLIA: '0x5cc6b635bb68976e4ae3d0546ba0f20f66872a72',\n}\nexport const RecordMap: { [key: string]: RecordTabIndex[] } = {\n  TAIKOHEKLA: [\n    RecordTabIndex.Transactions,\n    RecordTabIndex.Trades,\n    RecordTabIndex.Orders,\n    RecordTabIndex.StopLimitRecords,\n    RecordTabIndex.AmmRecords,\n    RecordTabIndex.DefiRecords,\n    RecordTabIndex.DualRecords,\n    RecordTabIndex.SideStakingRecords,\n    RecordTabIndex.BtradeSwapRecords,\n    RecordTabIndex.leverageETHRecords,\n    RecordTabIndex.VaultRecords,\n  ],\n  TAIKO: [\n    RecordTabIndex.Transactions,\n    RecordTabIndex.Trades,\n    RecordTabIndex.Orders,\n    RecordTabIndex.StopLimitRecords,\n    RecordTabIndex.AmmRecords,\n    RecordTabIndex.DefiRecords,\n    RecordTabIndex.DualRecords,\n    RecordTabIndex.SideStakingRecords,\n    RecordTabIndex.BtradeSwapRecords,\n    RecordTabIndex.leverageETHRecords,\n    RecordTabIndex.VaultRecords,\n  ],\n  ETHEREUM: [\n    RecordTabIndex.Transactions,\n    RecordTabIndex.Trades,\n    RecordTabIndex.Orders,\n    RecordTabIndex.StopLimitRecords,\n    RecordTabIndex.AmmRecords,\n    RecordTabIndex.DefiRecords,\n    RecordTabIndex.DualRecords,\n    RecordTabIndex.SideStakingRecords,\n    RecordTabIndex.BtradeSwapRecords,\n    RecordTabIndex.leverageETHRecords,\n    RecordTabIndex.VaultRecords,\n  ],\n  GOERLI: [\n    RecordTabIndex.Transactions,\n    RecordTabIndex.Trades,\n    RecordTabIndex.Orders,\n    RecordTabIndex.StopLimitRecords,\n    RecordTabIndex.AmmRecords,\n    RecordTabIndex.DefiRecords,\n    RecordTabIndex.DualRecords,\n    RecordTabIndex.SideStakingRecords,\n    RecordTabIndex.BtradeSwapRecords,\n    RecordTabIndex.leverageETHRecords,\n    RecordTabIndex.VaultRecords,\n  ],\n  SEPOLIA: [\n    RecordTabIndex.Transactions,\n    RecordTabIndex.Trades,\n    RecordTabIndex.Orders,\n    RecordTabIndex.StopLimitRecords,\n    RecordTabIndex.AmmRecords,\n    RecordTabIndex.DefiRecords,\n    RecordTabIndex.DualRecords,\n    RecordTabIndex.SideStakingRecords,\n    RecordTabIndex.BtradeSwapRecords,\n    RecordTabIndex.leverageETHRecords,\n    RecordTabIndex.VaultRecords,\n  ],\n  ARBGOERLI: [\n    RecordTabIndex.Transactions,\n    RecordTabIndex.Trades,\n    RecordTabIndex.Orders,\n    RecordTabIndex.StopLimitRecords,\n    RecordTabIndex.AmmRecords,\n    RecordTabIndex.DefiRecords,\n    RecordTabIndex.DualRecords,\n    RecordTabIndex.SideStakingRecords,\n    RecordTabIndex.BtradeSwapRecords,\n    RecordTabIndex.leverageETHRecords,\n    RecordTabIndex.VaultRecords,\n  ],\n  BASE: [\n    RecordTabIndex.Transactions,\n    RecordTabIndex.Trades,\n    RecordTabIndex.Orders,\n    RecordTabIndex.StopLimitRecords,\n    RecordTabIndex.DefiRecords,\n    RecordTabIndex.DualRecords,\n    RecordTabIndex.SideStakingRecords,\n    RecordTabIndex.BtradeSwapRecords,\n    RecordTabIndex.leverageETHRecords,\n    RecordTabIndex.VaultRecords,\n  ],\n  BASESEPOLIA: [\n    RecordTabIndex.Transactions,\n    RecordTabIndex.Trades,\n    RecordTabIndex.Orders,\n    RecordTabIndex.StopLimitRecords,\n    RecordTabIndex.DefiRecords,\n    RecordTabIndex.DualRecords,\n    RecordTabIndex.SideStakingRecords,\n    RecordTabIndex.BtradeSwapRecords,\n    RecordTabIndex.leverageETHRecords,\n    RecordTabIndex.VaultRecords,\n  ],\n}\nexport const AddAssetListMap = {\n  TAIKOHEKLA: [\n    AddAssetList.FromMyL1.key,\n    AddAssetList.BuyWithCard.key,\n    AddAssetList.FromOtherL2.key,\n    AddAssetList.FromOtherL1.key,\n    AddAssetList.FromExchange.key,\n    AddAssetList.FromAnotherNet.key,\n    AddAssetList.FromExchange.key,\n  ],\n  TAIKO: [\n    AddAssetList.FromMyL1.key,\n    AddAssetList.BuyWithCard.key,\n    AddAssetList.FromOtherL2.key,\n    AddAssetList.FromOtherL1.key,\n    AddAssetList.FromExchange.key,\n    AddAssetList.FromAnotherNet.key,\n    AddAssetList.FromExchange.key,\n  ],\n  ETHEREUM: [\n    AddAssetList.FromMyL1.key,\n    AddAssetList.BuyWithCard.key,\n    AddAssetList.FromOtherL2.key,\n    AddAssetList.FromOtherL1.key,\n    AddAssetList.FromExchange.key,\n    AddAssetList.FromAnotherNet.key,\n  ],\n  GOERLI: [\n    AddAssetList.FromMyL1.key,\n    AddAssetList.BuyWithCard.key,\n    AddAssetList.FromOtherL2.key,\n    AddAssetList.FromOtherL1.key,\n    AddAssetList.FromExchange.key,\n    AddAssetList.FromAnotherNet.key,\n  ],\n  SEPOLIA: [\n    AddAssetList.FromMyL1.key,\n    AddAssetList.BuyWithCard.key,\n    AddAssetList.FromOtherL2.key,\n    AddAssetList.FromOtherL1.key,\n    AddAssetList.FromExchange.key,\n    AddAssetList.FromAnotherNet.key,\n  ],\n  ARBGOERLI: [\n    AddAssetList.FromMyL1.key,\n    AddAssetList.BuyWithCard.key,\n    AddAssetList.FromOtherL2.key,\n    AddAssetList.FromOtherL1.key,\n    AddAssetList.FromExchange.key,\n    AddAssetList.FromAnotherNet.key,\n  ],\n  BASE: [\n    AddAssetList.FromMyL1.key,\n    AddAssetList.BuyWithCard.key,\n    AddAssetList.FromOtherL2.key,\n    AddAssetList.FromOtherL1.key,\n    AddAssetList.FromExchange.key,\n    AddAssetList.FromAnotherNet.key,\n  ],\n  BASESEPOLIA: [\n    AddAssetList.FromMyL1.key,\n    AddAssetList.BuyWithCard.key,\n    AddAssetList.FromOtherL2.key,\n    AddAssetList.FromOtherL1.key,\n    AddAssetList.FromExchange.key,\n    AddAssetList.FromAnotherNet.key,\n  ],\n}\nexport const SendAssetListMap = {\n  TAIKOHEKLA: [\n    SendAssetList.SendAssetToMyL1.key,\n    SendAssetList.SendAssetToL2.key,\n    SendAssetList.SendAssetToOtherL1.key,\n  ],\n  TAIKO: [\n    SendAssetList.SendAssetToMyL1.key,\n    SendAssetList.SendAssetToL2.key,\n    SendAssetList.SendAssetToOtherL1.key,\n  ],\n  ETHEREUM: [\n    SendAssetList.SendAssetToMyL1.key,\n    SendAssetList.SendAssetToL2.key,\n    SendAssetList.SendAssetToOtherL1.key,\n    SendAssetList.SendAssetToTaikoAccount.key,\n    SendAssetList.SendAssetToAnotherNet.key,\n  ],\n  SEPOLIA: [\n    SendAssetList.SendAssetToMyL1.key,\n    SendAssetList.SendAssetToL2.key,\n    SendAssetList.SendAssetToOtherL1.key,\n    SendAssetList.SendAssetToTaikoAccount.key,\n    SendAssetList.SendAssetToAnotherNet.key,\n  ],\n  BASE: [\n    SendAssetList.SendAssetToMyL1.key,\n    SendAssetList.SendAssetToL2.key,\n    SendAssetList.SendAssetToOtherL1.key,\n    SendAssetList.SendAssetToTaikoAccount.key,\n    SendAssetList.SendAssetToAnotherNet.key,\n  ],\n  BASESEPOLIA: [\n    SendAssetList.SendAssetToMyL1.key,\n    SendAssetList.SendAssetToL2.key,\n    SendAssetList.SendAssetToOtherL1.key,\n    SendAssetList.SendAssetToTaikoAccount.key,\n    SendAssetList.SendAssetToAnotherNet.key,\n  ],\n}\nexport const AssetL2TabIndex = {\n  TAIKOHEKLA: [AssetTabIndex.Tokens],\n  TAIKO: [AssetTabIndex.Tokens],\n  ETHEREUM: [\n    AssetTabIndex.Tokens,\n    AssetTabIndex.Invests,\n    // AssetTabIndex.RedPacket,\n    AssetTabIndex.Rewards,\n  ],\n  GOERLI: [\n    AssetTabIndex.Tokens,\n    AssetTabIndex.Invests,\n    // AssetTabIndex.RedPacket,\n    AssetTabIndex.Rewards,\n  ],\n  SEPOLIA: [\n    AssetTabIndex.Tokens,\n    AssetTabIndex.Invests,\n    // AssetTabIndex.RedPacket,\n    AssetTabIndex.Rewards,\n  ],\n  ARBGOERLI: [\n    AssetTabIndex.Tokens,\n    AssetTabIndex.Invests,\n    // AssetTabIndex.RedPacket,\n    AssetTabIndex.Rewards,\n  ],\n  BASE: [\n    AssetTabIndex.Tokens,\n    AssetTabIndex.Invests,\n    // AssetTabIndex.RedPacket,\n    AssetTabIndex.Rewards,\n  ],\n  BASESEPOLIA: [\n    AssetTabIndex.Tokens,\n    AssetTabIndex.Invests,\n    // AssetTabIndex.RedPacket,\n    AssetTabIndex.Rewards,\n  ],\n}\nexport const RouterAllowIndex = {\n  TAIKOHEKLA: [\n    RouterMainKey.lite,\n    RouterMainKey.pro,\n    RouterMainKey.stoplimit,\n    RouterMainKey.btrade,\n    RouterMainKey.fiat,\n    RouterMainKey.markets,\n    RouterMainKey.mining,\n    RouterMainKey.redPacket,\n    RouterMainKey.l2assets,\n    RouterMainKey.layer2,\n    RouterMainKey.nft,\n    RouterMainKey.invest,\n    RouterMainKey.vault,\n  ],\n  TAIKO: [\n    RouterMainKey.lite,\n    RouterMainKey.pro,\n    RouterMainKey.stoplimit,\n    RouterMainKey.btrade,\n    RouterMainKey.fiat,\n    RouterMainKey.markets,\n    RouterMainKey.mining,\n    RouterMainKey.redPacket,\n    RouterMainKey.l2assets,\n    RouterMainKey.layer2,\n    RouterMainKey.nft,\n    RouterMainKey.invest,\n    RouterMainKey.vault,\n  ],\n  ETHEREUM: [\n    RouterMainKey.lite,\n    RouterMainKey.pro,\n    RouterMainKey.stoplimit,\n    RouterMainKey.btrade,\n    RouterMainKey.fiat,\n    RouterMainKey.markets,\n    RouterMainKey.mining,\n    RouterMainKey.redPacket,\n    RouterMainKey.l2assets,\n    RouterMainKey.layer2,\n    RouterMainKey.nft,\n    RouterMainKey.invest,\n    RouterMainKey.vault,\n  ],\n  GOERLI: [\n    RouterMainKey.lite,\n    RouterMainKey.pro,\n    RouterMainKey.stoplimit,\n    RouterMainKey.btrade,\n    RouterMainKey.fiat,\n    RouterMainKey.markets,\n    RouterMainKey.mining,\n    RouterMainKey.redPacket,\n    RouterMainKey.l2assets,\n    RouterMainKey.layer2,\n    RouterMainKey.nft,\n    RouterMainKey.invest,\n    RouterMainKey.vault,\n  ],\n  SEPOLIA: [\n    RouterMainKey.lite,\n    RouterMainKey.pro,\n    RouterMainKey.stoplimit,\n    RouterMainKey.btrade,\n    RouterMainKey.fiat,\n    RouterMainKey.markets,\n    RouterMainKey.mining,\n    RouterMainKey.redPacket,\n    RouterMainKey.l2assets,\n    RouterMainKey.layer2,\n    RouterMainKey.nft,\n    RouterMainKey.invest,\n    RouterMainKey.vault,\n  ],\n  ARBGOERLI: [\n    RouterMainKey.lite,\n    RouterMainKey.pro,\n    RouterMainKey.stoplimit,\n    RouterMainKey.btrade,\n    RouterMainKey.fiat,\n    RouterMainKey.markets,\n    RouterMainKey.mining,\n    RouterMainKey.redPacket,\n    RouterMainKey.l2assets,\n    RouterMainKey.layer2,\n    RouterMainKey.nft,\n    RouterMainKey.invest,\n  ],\n  BASE: [\n    RouterMainKey.lite,\n    RouterMainKey.pro,\n    RouterMainKey.stoplimit,\n    RouterMainKey.btrade,\n    RouterMainKey.fiat,\n    RouterMainKey.markets,\n    RouterMainKey.mining,\n    RouterMainKey.redPacket,\n    RouterMainKey.l2assets,\n    RouterMainKey.layer2,\n    RouterMainKey.nft,\n    RouterMainKey.invest,\n    RouterMainKey.vault,\n  ],\n  BASESEPOLIA: [\n    RouterMainKey.lite,\n    RouterMainKey.pro,\n    RouterMainKey.stoplimit,\n    RouterMainKey.btrade,\n    RouterMainKey.fiat,\n    RouterMainKey.markets,\n    RouterMainKey.mining,\n    RouterMainKey.redPacket,\n    RouterMainKey.l2assets,\n    RouterMainKey.layer2,\n    RouterMainKey.nft,\n    RouterMainKey.invest,\n    RouterMainKey.vault,\n  ],\n}\nexport const ProfileIndex = {\n  TAIKOHEKLA: [\n    Layer2RouterID.security,\n  ],\n  TAIKO: [\n    Layer2RouterID.security,\n  ],\n  ETHEREUM: [\n    Layer2RouterID.security,\n    Layer2RouterID.forcewithdraw,\n    Layer2RouterID.vip,\n    Layer2RouterID.contact,\n    Layer2RouterID.referralrewards,\n    Layer2RouterID.notification,\n  ],\n  GOERLI: [\n    Layer2RouterID.security,\n    Layer2RouterID.forcewithdraw,\n    Layer2RouterID.vip,\n    Layer2RouterID.contact,\n    Layer2RouterID.referralrewards,\n    Layer2RouterID.notification,\n  ],\n  SEPOLIA: [\n    Layer2RouterID.security,\n    Layer2RouterID.forcewithdraw,\n    Layer2RouterID.vip,\n    Layer2RouterID.contact,\n    Layer2RouterID.referralrewards,\n    Layer2RouterID.notification,\n  ],\n  ARBGOERLI: [\n    Layer2RouterID.security,\n    Layer2RouterID.forcewithdraw,\n    Layer2RouterID.vip,\n    Layer2RouterID.contact,\n    Layer2RouterID.referralrewards,\n  ],\n  BASE: [\n    Layer2RouterID.security,\n  ],\n  BASESEPOLIA: [\n    Layer2RouterID.security,\n  ],\n}\n\nexport const L1L2_NAME_DEFINED = {\n  TAIKOHEKLA: {\n    layer2: process.env.REACT_APP_NAME === 'loopring defi' ? 'Loopring DeFi' : 'Layer 3',\n    l1ChainName: 'Taiko Hekla',\n    loopringL2: process.env.REACT_APP_NAME === 'loopring defi' ? 'Loopring DeFi' : 'Loopring L3',\n    l2Symbol: process.env.REACT_APP_NAME === 'loopring defi' ? 'Loopring DeFi' : 'L3',\n    l1Symbol: 'Taiko Hekla',\n    ethereumL1: 'Taiko Hekla',\n    loopringLayer2: process.env.REACT_APP_NAME === 'loopring defi' ? 'Loopring DeFi' : 'Loopring Layer 3',\n    L1Token: 'ETH',\n    L2Token: 'TAIKO',\n  },\n  TAIKO: {\n    layer2: process.env.REACT_APP_NAME === 'loopring defi' ? 'Loopring DeFi' : 'Layer 3',\n    l1ChainName: 'Taiko',\n    loopringL2: process.env.REACT_APP_NAME === 'loopring defi' ? 'Loopring DeFi' : 'Loopring L3',\n    l2Symbol: process.env.REACT_APP_NAME === 'loopring defi' ? 'Loopring DeFi' : 'L3',\n    l1Symbol: 'Taiko',\n    ethereumL1: 'Taiko',\n    loopringLayer2: process.env.REACT_APP_NAME === 'loopring defi' ? 'Loopring DeFi' : 'Loopring Layer 3',\n    L1Token: 'ETH',\n    L2Token: 'TAIKO',\n  },\n  ETHEREUM: {\n    layer2: 'Layer 2',\n    l1ChainName: 'Ethereum',\n    loopringL2: 'Loopring L2',\n    l2Symbol: 'L2',\n    l1Symbol: 'L1',\n    ethereumL1: 'Ethereum L1',\n    loopringLayer2: 'Loopring Layer 2',\n    L1Token: 'ETH',\n    L2Token: 'LRC',\n  },\n  GOERLI: {\n    layer2: 'Layer 2',\n    l1ChainName: 'Ethereum',\n    loopringL2: 'Loopring L2',\n    l2Symbol: 'L2',\n    l1Symbol: 'L1',\n    ethereumL1: 'Ethereum L1',\n    loopringLayer2: 'Loopring Layer 2',\n    L1Token: 'ETH',\n    L2Token: 'LRC',\n  },\n  SEPOLIA: {\n    layer2: 'Layer 2',\n    l1ChainName: 'Ethereum',\n    loopringL2: 'Loopring L2',\n    l2Symbol: 'L2',\n    l1Symbol: 'L1',\n    ethereumL1: 'Ethereum L1',\n    loopringLayer2: 'Loopring Layer 2',\n    L1Token: 'ETH',\n    L2Token: 'LRC',\n  },\n  ARBGOERLI: {\n    layer2: 'Layer 2',\n    l1ChainName: 'Ethereum',\n    loopringL2: 'Loopring L2',\n    l2Symbol: 'L2',\n    l1Symbol: 'L1',\n    ethereumL1: 'Ethereum L1',\n    loopringLayer2: 'Loopring Layer 2',\n    L1Token: 'ETH',\n    L2Token: 'LRC',\n  },\n  BASE: {\n    layer2: process.env.REACT_APP_NAME === 'loopring defi' ? 'Loopring DeFi' : 'Layer 3',\n    l1ChainName: 'BASE',\n    loopringL2: process.env.REACT_APP_NAME === 'loopring defi' ? 'Loopring DeFi' : 'Loopring L3',\n    l2Symbol: process.env.REACT_APP_NAME === 'loopring defi' ? 'Loopring DeFi' : 'L3',\n    l1Symbol: 'L1',\n    ethereumL1: 'BASE',\n    loopringLayer2: process.env.REACT_APP_NAME === 'loopring defi' ? 'Loopring DeFi' : 'Loopring Layer 3',\n    L1Token: 'ETH',\n    L2Token: 'ETH',\n  },\n  BASESEPOLIA: {\n    layer2: process.env.REACT_APP_NAME === 'loopring defi' ? 'Loopring DeFi' : 'Layer 3',\n    l1ChainName: 'BASE',\n    loopringL2: process.env.REACT_APP_NAME === 'loopring defi' ? 'Loopring DeFi' : 'Loopring L3',\n    l2Symbol: process.env.REACT_APP_NAME === 'loopring defi' ? 'Loopring DeFi' : 'L3',\n    l1Symbol: 'L1',\n    ethereumL1: 'BASE',\n    loopringLayer2: process.env.REACT_APP_NAME === 'loopring defi' ? 'Loopring DeFi' : 'Loopring Layer 3',\n    L1Token: 'ETH',\n    L2Token: 'ETH',\n  },\n}\n\nexport const SPECIAL_ACTIVATION_NETWORKS = [\n  ChainId.TAIKO,\n  ChainId.TAIKOHEKLA, \n  ChainId.BASE,\n  ChainId.SEPOLIA,\n  ChainId.BASESEPOLIA,\n]"
  },
  {
    "path": "packages/common-resources/static-resources/src/constant/sagaStatus.ts",
    "content": "import { ErrorObject } from '../error'\n\nexport enum SagaStatus {\n  UNSET = 'UNSET',\n  PENDING = 'PENDING',\n  ERROR = 'ERROR', // success failed timeout is Done\n  DONE = 'DONE', // success failed timeout is Done\n}\n\nexport type StateBase = {\n  status:  SagaStatus\n  errorMessage?: ErrorObject | null\n}\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/constant/setting.ts",
    "content": "import { IsMobile } from '../utils'\nimport { NetworkItemInfo } from '../loopring-interface'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { mainnet, sepolia, base, baseSepolia, taiko, taikoHekla, Chain } from 'viem/chains'\n\nexport enum UpColor {\n  green = 'green',\n  red = 'red',\n}\nexport const SlippageTolerance: Array<0.1 | 0.5 | 1 | string> = [0.1, 0.5, 1]\nexport const SlippageBtradeTolerance: Array<0.1 | 0.5 | 1 | string> = [0.1, 0.5, 1]\nexport type RowConfigType = {\n  rowHeight?: number\n  rowHeaderHeight?: number\n  minHeight?: number\n}\nexport const RowConfig = {\n  rowHeight: IsMobile.any() ? 48 : 44,\n  rowHeaderHeight: IsMobile.any() ? 48 : 44,\n  minHeight: 350,\n}\nexport const RowInvestConfig = {\n  rowHeight: IsMobile.any() ? 48 : 56,\n  rowHeaderHeight: IsMobile.any() ? 48 : 56,\n  minHeight: 350,\n}\nexport const RowDualInvestConfig = {\n  rowHeight: IsMobile.any() ? 48 : 72,\n  rowHeaderHeight: IsMobile.any() ? 48 : 72,\n  minHeight: 350,\n}\nexport const DirectionTag = '\\u2192'\nexport const FeeChargeOrderDefaultMap = new Map([\n  [sdk.ChainId.MAINNET, ['ETH', 'USDT', 'LRC', 'DAI', 'USDC']],\n  [sdk.ChainId.TAIKO, ['ETH', 'USDT', 'LRC', 'USDC', 'TAIKO']],\n  [sdk.ChainId.SEPOLIA, ['ETH', 'USDT', 'LRC', 'DAI']],\n  [sdk.ChainId.TAIKOHEKLA, ['ETH', 'USDT', 'LRC', 'TAIKO']],\n  [sdk.ChainId.BASE, ['ETH', 'USDT', 'LRC', 'USDC']],\n  [sdk.ChainId.BASESEPOLIA, ['ETH', 'USDT', 'LRC', 'USDC']],\n])\nexport const HEADER_HEIGHT = 64\nexport const LandPageHeightConfig = {\n  headerHeight: 64,\n  whiteHeight: 32,\n  maxHeight: 836,\n  minHeight: 800,\n}\nexport const Lang = {\n  en_US: 'en',\n  zh_CN: 'zh',\n}\nexport const Explorer = 'https://explorer.loopring.io/'\nexport const Bridge = 'https://bridge.loopring.io/#/'\nexport const ExchangeIO = 'https://loopring.io'\nexport const Exchange = 'https://loopring.io/#/'\nexport const ExchangePro = window.location.origin + '/#/pro'\nexport const Earnlite = 'https://defi.loopring.io/#/'\nexport const WalletSite = 'https://wallet.loopring.io'\nexport const LOOPRING_DOC = 'https://docs.loopring.io'\n\nexport const YEAR_FROMATE = 'YYYY'\nexport const DAY_FORMAT = 'MM/DD'\nexport const MINUTE_FORMAT = 'HH:mm'\nexport const DAY_MINUTE_FORMAT = `${DAY_FORMAT} ${MINUTE_FORMAT}`\nexport const DAT_STRING_FORMAT = 'MMM DD [UTC]Z'\nexport const DAT_STRING_FORMAT_S = 'MMM DD'\n\nexport const SECOND_FORMAT = `${MINUTE_FORMAT}:ss`\nexport const YEAR_DAY_FORMAT = `${YEAR_FROMATE}/${DAY_FORMAT}`\nexport const YEAR_DAY_MINUTE_FORMAT = `${YEAR_DAY_FORMAT} ${MINUTE_FORMAT}`\nexport const YEAR_DAY_SECOND_FORMAT = `${YEAR_DAY_FORMAT} ${SECOND_FORMAT}`\nexport const MINT_STRING_FORMAT = `${MINUTE_FORMAT} ${DAT_STRING_FORMAT}`\nexport const UNIX_TIMESTAMP_FORMAT = 'x'\nexport const sizeNFTConfig = (size: 'large' | 'medium' | 'small') => {\n  switch (size) {\n    case 'large':\n      return {\n        wrap_xs: 12,\n        wrap_md: 4,\n        wrap_lg: 4,\n        avatar: 40,\n        contentHeight: 80,\n      }\n      break\n    case 'small':\n      return {\n        wrap_xs: 6,\n        wrap_md: 3,\n        wrap_lg: 2,\n        avatar: 28,\n        contentHeight: 60,\n      }\n      break\n    case 'medium':\n      return {\n        wrap_xs: 6,\n        wrap_md: 3,\n        wrap_lg: 3,\n        avatar: 38,\n        contentHeight: 72,\n      }\n      break\n  }\n}\nexport enum TradeBtnStatus {\n  AVAILABLE = 'AVAILABLE',\n  DISABLED = 'DISABLED',\n  LOADING = 'LOADING',\n}\nexport const { NetworkMap, ChainTests, MapChainId, ChainIdExtends } = (\n  process.env.REACT_APP_RPC_OTHERS?.split(',') ?? []\n).reduce(\n  ({ NetworkMap, ChainTests, MapChainId, ChainIdExtends }, item: string, index: number) => {\n    let [_name, isTest] = process.env[`REACT_APP_RPC_CHAINNAME_${item}`]?.split('|') ?? [\n      `unknown${item}`,\n    ]\n    const name = _name.toUpperCase()\n    ChainIdExtends[name] = Number(item)\n    MapChainId[item] = name\n    // MapChainIdMap.set(Number(item), name);\n    // myLog(\"MapChainIdMap\", item, MapChainIdMap);\n    if (isTest) {\n      ChainTests.push(Number(item))\n    }\n    NetworkMap[Number(item)] = {\n      label: _name,\n      chainId: index.toString(),\n      // RPC: process.env[`REACT_APP_RPC_URL_${item}`] ?? \"\",\n      isTest: isTest ? true : false,\n      walletType: name,\n    }\n    return { NetworkMap, ChainTests, MapChainId, ChainIdExtends }\n  },\n  {\n    MapChainId: {\n      1: 'ETHEREUM',\n      5: 'GOERLI',\n      421613: 'ARBGOERLI',\n      11155111: 'SEPOLIA',\n      167009: 'TAIKOHEKLA',\n      167000: 'TAIKO',\n      8453: 'BASE',\n      84532: 'BASESEPOLIA',\n    },\n    NetworkMap: {\n      1: {\n        label: 'Ethereum',\n        chainId: '1',\n        isTest: false,\n        walletType: 'ETHEREUM',\n      },\n      5: {\n        label: 'Görli',\n        chainId: '5',\n        isTest: true,\n        walletType: 'GOERLI',\n      },\n      11155111: {\n        label: 'Sepolia',\n        chainId: '11155111',\n        isTest: true,\n        walletType: 'SEPOLIA',\n      },\n      167009: {\n        label: 'Taiko Hekla',\n        chainId: '167009',\n        isTest: true,\n        walletType: 'Taiko Hekla',\n      },\n      167000: {\n        label: 'Taiko',\n        chainId: '167000',\n        isTest: false,\n        walletType: 'TAIKO',\n      },\n      8453: {\n        label: 'Base',\n        chainId: '8453',\n        isTest: false,\n        walletType: 'BASE',\n      },\n      84532: {\n        label: 'Base Sepolia',\n        chainId: '84532',\n        isTest: true,\n        walletType: 'BASESEPOLIA',\n      },\n    },\n    ChainTests: [11155111, 5, 167009, 84532],\n    ChainIdExtends: {\n      NONETWORK: 'unknown',\n    },\n  } as {\n    ChainTests: number[]\n    MapChainId: { [key: string]: string }\n    NetworkMap: { [key: number]: NetworkItemInfo }\n    ChainIdExtends: { [key: string]: number | string }\n  },\n)\nif (window) {\n  // @ts-ignore\n  window.__ChainIdExtends = ChainIdExtends\n  // @ts-ignore\n  window.__MapChainId = MapChainId\n}\n\nexport const HEBAO_CONTRACT_MAP = [\n  ['V3_0_0', sdk.AddressType.LOOPRING_HEBAO_CONTRACT_3_0_0],\n  ['V2_2_0', sdk.AddressType.LOOPRING_HEBAO_CONTRACT_2_2_0],\n  ['V2_1_0', sdk.AddressType.LOOPRING_HEBAO_CONTRACT_2_1_0],\n  ['V2_0_0', sdk.AddressType.LOOPRING_HEBAO_CONTRACT_2_0_0],\n  ['V1_2_0', sdk.AddressType.LOOPRING_HEBAO_CONTRACT_1_2_0],\n  ['V1_1_6', sdk.AddressType.LOOPRING_HEBAO_CONTRACT_1_1_6],\n]\n\nexport type ContactType = Pick<sdk.GetContactsResponse, 'contacts'>['contacts'][0]\n\nexport type CoinSource = {\n  x: number\n  y: number\n  w: number\n  h: number\n  offX: number\n  offY: number\n  sourceW: number\n  sourceH: number\n  simpleName?: string\n}\n\nexport enum TableFilterParams {\n  all = 'all',\n  favourite = 'favourite',\n  ranking = 'ranking',\n}\n\nexport type Contact = {\n  contactName: string\n  // name?: string\n  address?: string\n  addressType?: (typeof sdk.AddressType)[sdk.AddressTypeKeys]\n  ens?: string\n} & Partial<sdk.CreateContactRequest>\nexport enum ToastType {\n  success = 'success',\n  error = 'error',\n  warning = 'warning',\n  info = 'info',\n}\n\nexport const SEND_TO_TAIKO_NETWORK_MAP = new Map([\n  [sdk.ChainId.SEPOLIA, sdk.ChainId.TAIKOHEKLA],\n  [sdk.ChainId.MAINNET, sdk.ChainId.TAIKO],\n])\n\nexport const CHAIN_ID_TO_VIEW_CHAIN = new Map<sdk.ChainId, Chain>([\n  [sdk.ChainId.SEPOLIA, sepolia],\n  [sdk.ChainId.MAINNET, mainnet],\n  [sdk.ChainId.TAIKOHEKLA, taikoHekla],\n  [sdk.ChainId.TAIKO, taiko],\n  [sdk.ChainId.BASE, base],\n  [sdk.ChainId.BASESEPOLIA, baseSepolia],\n])\n\nexport const coinbaseSmartWalletChains = [sdk.ChainId.BASE, sdk.ChainId.BASESEPOLIA] \n\nexport const hideDefiEntry = process.env.REACT_APP_HIDE_DEFI_ENTRY === 'true'"
  },
  {
    "path": "packages/common-resources/static-resources/src/constant/social.ts",
    "content": "import * as Social from 'react-share'\nimport { DiscordSvg } from '../svg';\nimport { createElement } from 'react';\nimport { ExchangeIO } from './setting';\nimport { IPFSHTTPClient } from 'ipfs-http-client';\nimport { IPFS_LOOPRING_SITE } from './router';\nimport { myLog } from '../utils';\n\nexport enum SOCIAL_NAME_KEYS {\n  Facebook = 'Facebook',\n  WhatsApp = 'WhatsApp',\n  Twitter = 'Twitter',\n  Telegram = 'Telegram',\n  Email = 'Email',\n  Pinterest = 'Pinterest',\n  Discord = 'Discord'\n}\n\n\n// Object.values(SOCIAL_NAME_KEYS)\n\nexport const SOCIAL_COMPONENT_MAP = {\n  [ SOCIAL_NAME_KEYS.Facebook ]: {\n    SocialNetworkName: SOCIAL_NAME_KEYS.Facebook,\n    SocialComponent: Social.FacebookShareButton,\n    SocialIcon: Social.FacebookIcon,\n  },\n  [ SOCIAL_NAME_KEYS.WhatsApp ]: {\n    SocialNetworkName: SOCIAL_NAME_KEYS.WhatsApp,\n    SocialComponent: Social.WhatsappShareButton,\n    SocialIcon: Social.WhatsappIcon,\n  },\n  [ SOCIAL_NAME_KEYS.Twitter ]: {\n    SocialNetworkName: SOCIAL_NAME_KEYS.Twitter,\n    SocialComponent: Social.TwitterShareButton,\n    SocialIcon: Social.TwitterIcon,\n  },\n  [ SOCIAL_NAME_KEYS.Telegram ]: {\n    SocialNetworkName: SOCIAL_NAME_KEYS.Telegram,\n    SocialComponent: Social.TelegramShareButton,\n    SocialIcon: Social.TelegramIcon,\n  },\n  [ SOCIAL_NAME_KEYS.Email ]: {\n    SocialNetworkName: SOCIAL_NAME_KEYS.Email,\n    SocialComponent: Social.EmailShareButton,\n    SocialIcon: Social.EmailIcon,\n  },\n  [ SOCIAL_NAME_KEYS.Pinterest ]: {\n    SocialNetworkName: SOCIAL_NAME_KEYS.Pinterest,\n    SocialComponent: Social.PinterestShareButton,\n    SocialIcon: Social.PinterestIcon,\n  },\n  [ SOCIAL_NAME_KEYS.Discord ]: {\n    SocialNetworkName: SOCIAL_NAME_KEYS.Discord,\n    SocialComponent: createElement(''),\n    SocialIcon: DiscordSvg,\n  }\n}\n\nexport const SOCIAL_LIST = [\n  SOCIAL_COMPONENT_MAP[ SOCIAL_NAME_KEYS.Facebook ],\n  SOCIAL_COMPONENT_MAP[ SOCIAL_NAME_KEYS.Twitter ],\n  SOCIAL_COMPONENT_MAP[ SOCIAL_NAME_KEYS.Email ],\n]\n// export const SOCIAL_WITH_TITLE = new Set([\n//   SOCIAL_NAME_KEYS.Facebook,\n//   // SOCIAL_NAME_KEYS.Discord,\n//   SOCIAL_NAME_KEYS.Twitter,\n//   SOCIAL_NAME_KEYS.Email,\n//   // SOCIAL_NAME_KEYS.\n//   // SOCIAL_NAME_KEYS.telegram,\n//   // SOCIAL_NAME_KEYS.pinterest,\n// ])\n\n\nexport const shareOnTwitter = async (message: string, image: string, ipfs?: IPFSHTTPClient, url: string = ExchangeIO) => {\n  let ipfsUrl = ''\n  if (ipfs) {\n    const {cid} = await ipfs.add(Buffer.from(image.replace(/^data:image\\/(png|jpeg|jpg);base64,/, ''), 'base64'))\n    ipfsUrl = `${IPFS_LOOPRING_SITE}${cid}`;\n  }\n  myLog('ipfsUrl', ipfsUrl)\n  const tweetText = encodeURIComponent(`${message}\\n\\nImage: ${ipfsUrl}\\n\\nWebsite: ${url}`);\n  const twitterUrl = `https://twitter.com/intent/tweet?text=${tweetText}`;\n  window.open(twitterUrl, '_blank');\n};\n\nexport const shareOnFacebook = async (message: string, image: string, ipfs?: IPFSHTTPClient, url: string = ExchangeIO) => {\n  let ipfsUrl = ''\n  if (ipfs) {\n    const {cid} = await ipfs.add(Buffer.from(image.replace(/^data:image\\/(png|jpeg|jpg);base64,/, ''), 'base64'))\n    ipfsUrl = `${IPFS_LOOPRING_SITE}${cid}`;\n  }\n  myLog('ipfsUrl', ipfsUrl)\n  const facebookUrl = `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(\n    url\n  )}&quote=${encodeURIComponent(message)}&picture=${encodeURIComponent(\n    `${ipfsUrl}`\n  )}`;\n  window.open(facebookUrl, '_blank');\n}\n\nexport const shareViaEmail = async (message: string, image: string, ipfs?: IPFSHTTPClient, _width = '315', _height = '440') => {\n  const emailSubject = encodeURIComponent(\"Join me at Loopring and earn exclusive rewards\");\n  // let ipfsUrl = ''\n  // if (ipfs) {\n  //   const {cid} = await ipfs.add(Buffer.from(image.replace(/^data:image\\/(png|jpeg|jpg);base64,/, ''), 'base64'))\n  //   ipfsUrl = `${IPFS_LOOPRING_SITE}${cid}`;\n  // }\n  // myLog('ipfsUrl', ipfsUrl)\n  // </br> <img src=\"${ipfsUrl}\" alt=\"\" width=\"${width}\" height=\"${height}\" />\n  const emailBody = encodeURIComponent(\n    `${message}`\n  );\n  const mailtoUrl = `mailto:?subject=${emailSubject}&body=${emailBody}`;\n  window.open(mailtoUrl, '_blank');\n};\n\nexport const shareDownload = (name: string, url: Blob | string) => {\n  const link = document.createElement('a');\n  link.href = typeof url === \"string\" ? url : URL.createObjectURL(url);\n  link.download = name;\n  link.click();\n  // const facebookUrl = `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(\n  //   window.location.href\n  // )}&quote=${encodeURIComponent(message)}&picture=${encodeURIComponent(\n  //   `${image}`\n  // )}`;\n  // window.open(facebookUrl, '_blank');\n}\n\nexport const shareOnDiscord = (message: string, image: string) => {\n  const discordShareUrl = `https://discord.com/api/oauth2/authorize?client_id=YOUR_BOT_CLIENT_ID&scope=bot&permissions=0&response_type=code&redirect_uri=${encodeURIComponent(\n    window.location.href\n  )}&state=${encodeURIComponent(\n    JSON.stringify({message, image: `${image}`})\n  )}`;\n  window.open(discordShareUrl, '_blank');\n};\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/constant/table.ts",
    "content": "export enum TableType {\n  filter = 'filter',\n  page = 'page',\n}\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/constant/tokenConfig.ts",
    "content": "const SPECIAL_TOKEN_NAME_MAP = new Map(\n  [\n    ['LRTAIKO', 'lrTAIKO'],\n  ]\n);\n\n\nexport const WITHDRAW_TOKEN_FILTER_LIST = ['LRTAIKO']\n\nexport const mapSpecialTokenName = (original: string) => {\n  return SPECIAL_TOKEN_NAME_MAP.get(original) || original\n}"
  },
  {
    "path": "packages/common-resources/static-resources/src/constant/trade.ts",
    "content": "import {\n  CollectionMeta,\n  DeFiCalcData,\n  DeFiSideCalcData,\n  DeFiSideRedeemCalcData,\n  FeeInfo,\n  IBData,\n  LuckyRedPacketItem,\n} from '../loopring-interface'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { MarketType } from './market'\nimport { VendorProviders } from './vendor'\n\nexport enum DeFiChgType {\n  coinSell = 'coinSell',\n  coinBuy = 'coinBuy',\n  exchange = 'exchange',\n}\n\nexport type WithdrawType =\n  | sdk.OffchainNFTFeeReqType.NFT_WITHDRAWAL\n  | sdk.OffchainFeeReqType.OFFCHAIN_WITHDRAWAL\n  | sdk.OffchainFeeReqType.FAST_OFFCHAIN_WITHDRAWAL\n\nexport type WithdrawTypes = {\n  // @ts-ignore\n  [sdk.OffchainFeeReqType.FAST_OFFCHAIN_WITHDRAWAL]: 'Fast'\n  // @ts-ignore\n  [sdk.OffchainFeeReqType.OFFCHAIN_WITHDRAWAL]: 'Standard'\n}\n\n// export type PriceTagType = '$' | '￥'\n\nexport enum CurrencyToTag {\n  USD = 'USD',\n  CNY = 'CNY',\n  JPY = 'JPY',\n  AUD = 'AUD',\n  CAD = 'CAD',\n  HKD = 'HKD',\n  EUR = 'EUR',\n  KRW = 'KRW',\n  GBP = 'GBP',\n}\n\nexport enum PriceTag {\n  USD = '$',\n  CNY = '¥',\n  JPY = '¥',\n  AUD = 'A$',\n  CAD = 'C$',\n  HKD = 'HKD',\n  EUR = '€',\n  KRW = '₩',\n  GBP = '£',\n}\n\nexport enum TradeTypes {\n  Buy = 'Buy',\n  Sell = 'Sell',\n}\n\nexport enum TradeStatus {\n  // Filled = 'Filled',\n  // Cancelled = 'Cancelled',\n  // Succeeded = 'Succeeded',\n  Processing = 'processing',\n  Processed = 'processed',\n  Cancelling = 'cancelling',\n  Cancelled = 'cancelled',\n  Expired = 'expired',\n  Waiting = 'waiting',\n}\n\nexport type TxInfo = {\n  hash: string\n  timestamp?: number | undefined\n  status?: 'pending' | 'success' | 'failed' | undefined\n  [key: string]: any\n}\n\nexport interface AccountHashInfo {\n  depositHashes: { [key: string]: TxInfo[] }\n  vaultBorrowHashes: { [key: string]: TxInfo[] }\n  showHadUnknownCollection: { [key: string]: boolean }\n}\n\nexport interface NFTHashInfo {\n  nftDataHashes: { [key: string]: Required<TxInfo> }\n}\n\nexport enum Layer1Action {\n  GuardianLock = 'GuardianLock',\n  NFTDeploy = 'NFTDeploy',\n}\n\n// GuardianLock\nexport type Layer1ActionHistory = {\n  [key: string]: {\n    [key in keyof typeof Layer1Action]?: { [key: string]: number }\n    // NFTDeploy?: { [key: string]: number };\n  }\n}\n\nexport type ChainHashInfos = {\n  [key in sdk.ChainId extends string ? string : string]: AccountHashInfo\n}\n\nexport type NFTHashInfos = {\n  [key in sdk.ChainId extends string ? string : string]: NFTHashInfo\n}\nexport type LAYER1_ACTION_HISTORY = {\n  [key in sdk.ChainId extends string ? string : string]: Layer1ActionHistory\n} & { __timer__: -1 | NodeJS.Timeout }\n\nexport type MetaProperty = {\n  key: string\n  value: string\n}\nexport type MetaDataProperty = { [key: string]: string }\nexport type AttributesProperty = {\n  trait_type: string\n  value: string\n}\n\nexport type NFTMETA = {\n  image: string\n  name: string\n  royaltyPercentage: number // 0 - 10 for UI\n  description: string\n  collection_metadata: string\n  properties?: Array<MetaProperty>\n  animationUrl?: string\n  attributes?: AttributesProperty[]\n}\n\nexport enum Media {\n  Audio = 'Audio',\n  Image = 'Image',\n  Video = 'Video',\n  Media3D = 'Media3D',\n}\n\nexport type NFTWholeINFO<Co = CollectionMeta> = sdk.NFTTokenInfo &\n  sdk.UserNFTBalanceInfo &\n  NFTMETA & {\n    nftBalance?: number\n    nftIdView?: string\n    pendingOnSync: boolean\n    fee?: FeeInfo\n    isFailedLoadMeta?: boolean\n    etherscanBaseUrl: string\n    __mediaType__?: Media\n    // collectionMeta?: Partial<Co>;\n    preference?: {\n      favourite: boolean\n      hide: boolean\n    }\n    collectionInfo?: Co\n  }\n\nexport type MintTradeNFT<I> = {\n  balance?: number\n  fee?: FeeInfo\n  cid?: string\n  nftId?: string\n  nftBalance?: number\n  nftIdView?: string\n  royaltyPercentage?: number\n  // tokenAddress?:string;\n} & Partial<IBData<I>> &\n  Partial<Omit<sdk.NFTTokenInfo, 'creatorFeeBips' | 'nftData'>>\nexport type MintReadTradeNFT<I> = {\n  balance?: number\n  fee?: FeeInfo\n  readonly cid?: string\n  readonly nftId?: string\n  readonly nftIdView?: string\n  readonly nftBalance?: number\n  readonly royaltyPercentage?: number\n} & Partial<IBData<I>> &\n  Partial<Omit<sdk.NFTTokenInfo, 'creatorFeeBips' | 'nftData'>>\n\nexport type TradeNFT<I, Co> = MintTradeNFT<I> &\n  Partial<NFTWholeINFO<Co>> & {\n    isApproved?: boolean\n    collectionMeta?: CollectionMeta\n  }\n\nexport enum NFT_TYPE_STRING {\n  ERC721 = 'ERC721',\n  ERC1155 = 'ERC1155',\n}\n\nexport const EmptyValueTag = '--'\nexport const HiddenTag = '*****'\nexport const DEAULT_NFTID_STRING =\n  '0x0000000000000000000000000000000000000000000000000000000000000000'\nexport const MINT_LIMIT = 100000\nexport const SUBMIT_PANEL_CHECK = 1000\nexport const SUBMIT_PANEL_AUTO_CLOSE = 8000\nexport const SUBMIT_PANEL_QUICK_AUTO_CLOSE = 3000\nexport const SUBMIT_PANEL_DOUBLE_QUICK_AUTO_CLOSE = 1000\nexport const TOAST_TIME = 3000\n\nexport const PROPERTY_LIMIT = 64\nexport const PROPERTY_KET_LIMIT = 20\nexport const STAKING_INVEST_LIMIT = 5\nexport const PROPERTY_Value_LIMIT = 40\nexport const REDPACKET_ORDER_LIMIT = 10000\nexport const REDPACKET_ORDER_NFT_LIMIT = 20000\nexport const EXCLUSIVE_REDPACKET_ORDER_LIMIT_WHITELIST = 10000\nexport const EXCLUSIVE_REDPACKET_ORDER_LIMIT = 50\nexport const BLINDBOX_REDPACKET_LIMIT = 10000\n\nexport const VAULT_MARKET_REFRESH = 60000\nexport const LOOPRING_TAKE_NFT_META_KET = {\n  name: 'name',\n  image: 'image',\n  royaltyPercentage: 'royaltyPercentage',\n  description: 'description',\n  properties: 'properties',\n}\nexport type LOOPRING_NFT_METADATA = {\n  [key in keyof typeof LOOPRING_TAKE_NFT_META_KET]?: string | undefined\n}\n\nexport const NFTLimit = 12,\n  CollectionLimit = 12,\n  RedPacketLimit = 12\n\nexport const AddAssetList = {\n  FromMyL1: {\n    key: 'FromMyL1',\n    svgIcon: 'IncomingIcon',\n    enableKey: 'deposit',\n  },\n  BuyWithCard: {\n    key: 'BuyWithCard',\n    svgIcon: 'CardIcon',\n    enableKey: 'legal',\n  },\n  FromOtherL2: {\n    key: 'FromOtherL2',\n    svgIcon: 'L2l2Icon',\n    enableKey: null,\n  },\n  FromOtherL1: {\n    key: 'FromOtherL1',\n    svgIcon: 'OutputIcon',\n    enableKey: null,\n  },\n  FromExchange: {\n    key: 'FromExchange',\n    svgIcon: 'ExchangeAIcon',\n    enableKey: null,\n  },\n  FromAnotherNet: {\n    key: 'FromAnotherNet',\n    svgIcon: 'AnotherIcon',\n    enableKey: null,\n  },\n}\n\ntype SendAssetListType = Record<\n  string,\n  {\n    key: string\n    svgIcon: string\n    enableKey?: string | null\n    type: 'sameLayer' | 'crossLayer' | 'crossChain'\n    cornerTag?: 'Loopring' | '3rd party'\n    description?: string\n  }\n>\n\nexport const SendAssetList: SendAssetListType = {\n  SendAssetToMyL1: {\n    key: 'SendToMyL1',\n    svgIcon: 'IncomingIcon',\n    enableKey: 'withdraw',\n    type: 'crossLayer',\n  },\n  SendAssetToL2: {\n    key: 'SendTOL2',\n    svgIcon: 'L2l2Icon',\n    enableKey: 'transfer',\n    type: 'sameLayer',\n  },\n  SendAssetToOtherL1: {\n    key: 'SendToOtherL1',\n    svgIcon: 'L1l2Icon',\n    enableKey: 'withdraw',\n    type: 'crossLayer',\n  },\n  SendAssetToAnotherNet: {\n    key: 'SendAssetToAnotherNet',\n    svgIcon: 'AnotherIcon',\n    enableKey: 'withdraw',\n    type: 'crossChain',\n    cornerTag: '3rd party'\n  },\n  SendAssetToTaikoAccount: {\n    key: 'SendAssetToTaikoAccount',\n    svgIcon: 'AnotherIcon',\n    enableKey: 'transferToTaikoAccount',\n    type: 'crossChain',\n    cornerTag: 'Loopring',\n  },\n}\n\nexport const SendNFTAssetList: SendAssetListType = {\n  SendAssetToMyL1: {\n    key: 'SendToMyL1',\n    svgIcon: 'IncomingIcon',\n    enableKey: 'withdrawNFT',\n    type: 'crossLayer',\n  },\n  SendAssetToL2: {\n    key: 'SendTOL2',\n    svgIcon: 'L2l2Icon',\n    enableKey: 'transferNFT',\n    type: 'sameLayer',\n  },\n  SendAssetToOtherL1: {\n    key: 'SendToOtherL1',\n    svgIcon: 'L1l2Icon',\n    enableKey: 'withdrawNFT',\n    type: 'crossLayer',\n  },\n}\n\nexport enum AddressError {\n  NoError = 'NoError',\n  EmptyAddr = 'EmptyAddr',\n  InvalidAddr = 'InvalidAddr',\n  ENSResolveFailed = 'ENSResolveFailed',\n  IsNotLoopringContract = 'IsNotLoopringContract',\n  TimeOut = 'TimeOut',\n}\n\nexport enum WALLET_TYPE {\n  EOA = 'EOA',\n  Loopring = 'Loopring',\n  OtherSmart = 'OtherSmart',\n  Exchange = 'Exchange',\n}\n\nexport enum EXCHANGE_TYPE {\n  NonExchange = 'NonExchange',\n  Binance = 'Binance',\n  Huobi = 'Huobi',\n  Coinbase = 'Coinbase',\n  Others = 'Others',\n}\n\nexport type AddressItemType<T> = {\n  value: T\n  label: string\n  description: string\n  disabled?: boolean\n  maxWidth?: string | number\n}\n\nexport const defaultSlipage = 0.1\nexport const defaultBlockTradeSlipage = 0.1\n\nexport type ForexMap<C = CurrencyToTag> = { [k in keyof C]?: number }\n\nexport const enum InvestMapType {\n  Token = 'Token',\n  AMM = 'AMM',\n  STAKE = 'STAKE',\n  DUAL = 'DUAL',\n  STAKELRC = 'STAKELRC',\n  LEVERAGEETH = 'LEVERAGEETH',\n}\n\nexport const enum InvestAssetRouter {\n  AMM = 'ammpool',\n  STAKE = 'defi',\n  DUAL = 'dual',\n  STAKELRC = 'stakelrc',\n  LEVERAGEETH = 'leverageETH',\n  // BTradeInvest = \"BTradeInvest\",\n}\n\nexport const InvestOpenType = [\n  InvestMapType.AMM,\n  InvestMapType.STAKE,\n  InvestMapType.DUAL,\n  InvestMapType.STAKELRC,\n  InvestMapType.LEVERAGEETH,\n]\n\nexport const enum InvestDuration {\n  Flexible = 'Flexible',\n  Duration = 'Duration',\n  All = 'All',\n}\n\nexport type InvestItem = {\n  type: InvestMapType\n  i18nKey: `labelInvestType_${InvestMapType}` | ''\n  apr: [start: number, end: number]\n  durationType: InvestDuration\n  duration: string\n}\nexport type InvestDetail = {\n  token: sdk.TokenInfo\n  apr: [start: number, end: number]\n  durationType: InvestDuration\n  duration: string\n}\n\nexport enum CreateCollectionStep {\n  // CreateTokenAddress,\n  // Loading,\n  // CreateTokenAddressFailed,\n  ChooseMethod,\n  ChooseMintMethod,\n  ChooseCollectionEdit,\n  // AdvancePanel,\n  // CommonPanel,\n}\n\nexport type TradeDefi<C> = {\n  type: string\n  market?: MarketType // eg: ETH-LRC, Pair from loopring market\n  isStoB: boolean\n  sellVol: string\n  buyVol: string\n  sellToken: sdk.TokenInfo\n  buyToken: sdk.TokenInfo\n  deFiCalcData?: DeFiCalcData<C>\n  fee: string\n  feeRaw: string\n  depositPrice?: string\n  withdrawPrice?: string\n  maxSellVol?: string\n  maxBuyVol?: string\n  maxFeeBips?: number\n  miniSellVol?: string\n  request?: sdk.DefiOrderRequest\n  defiBalances?: { [key: string]: string }\n  lastInput?: DeFiChgType\n  withdrawFeeBips?: number\n  defaultFee: string\n}\nexport type TradeStake<C> = {\n  sellToken: sdk.TokenInfo\n  sellVol: string\n  deFiSideCalcData?: DeFiSideCalcData<C>\n  request?: {\n    accountId: number\n    hash: string\n    token: sdk.TokenVolumeV3\n  }\n}\n\nexport type RedeemStake<C> = {\n  sellToken: sdk.TokenInfo\n  sellVol?: string\n  deFiSideRedeemCalcData: DeFiSideRedeemCalcData<C>\n  request?: {\n    accountId: number\n    hash: string\n    token: sdk.TokenVolumeV3\n  }\n}\n\nexport type L2CollectionFilter = {\n  isMintable?: boolean\n  isLegacy?: boolean\n  tokenAddress?: string\n  owner?: string\n}\nexport type MyNFTFilter = {\n  favourite?: boolean\n  hidden?: boolean\n}\n\nexport enum MY_NFT_VIEW {\n  LIST_COLLECTION = 'byCollection',\n  LIST_NFT = 'byList',\n}\n\nexport const LIVE_FEE_TIMES = 60000\nexport const L1_UPDATE = 15000\n\nexport type DualCurrentPrice = {\n  quote: string\n  base: string\n  precisionForPrice: number\n  currentPrice?: number\n  quoteUnit: string\n}\nexport type DualViewBase = {\n  apy: `${string}%`\n  settleRatio: string //targetPrice\n  term: string\n  strike: string\n  isUp: boolean\n  expireTime: number\n  currentPrice: DualCurrentPrice\n  productId: string\n  sellSymbol: string\n  buySymbol: string\n  amount?: string\n  enterTime?: number\n  stepLength?: string\n  quote?: string\n  outSymbol?: string\n  outAmount?: string\n  side?: string\n  status?: string\n  statusColor?: string\n  maxDuration?: number\n  autoStatus?: string\n  autoIcon?: JSX.Element\n  autoContent?: string\n  newStrike?: string\n  deliveryPrice?: string | undefined\n  __raw__?: any\n}\n\nexport type DualViewInfo = DualViewBase & {\n  __raw__: {\n    info: sdk.DualProductAndPrice\n    index: sdk.DualIndex\n    rule: sdk.DualRulesCoinsInfo\n  }\n}\nexport type ClaimToken = sdk.UserBalanceInfo & {\n  isNft?: boolean\n  nftTokenInfo?: sdk.UserNFTBalanceInfo\n  luckyTokenHash?: string\n}\nexport type DualViewOrder = DualViewBase & {\n  __raw__: {\n    order: sdk.UserDualTxsHistory\n  }\n}\n\nexport enum TRADE_TYPE {\n  TOKEN = 'TOKEN',\n  NFT = 'NFT',\n}\n\nexport enum CLAIM_TYPE {\n  redPacket = 'redPacket',\n  lrcStaking = 'lrcStaking',\n  allToken = 'allToken',\n}\n\nexport type BanxaOrder = {\n  id: string\n  account_id: string\n  account_reference: string\n  order_type: 'CRYPTO-SELL'\n  payment_type: string | null\n  ref: number | null\n  fiat_code: string\n  fiat_amount: number\n  coin_code: string\n  coin_amount: number\n  wallet_address: string | null\n  wallet_address_tag: string | null\n  fee: number | null\n  fee_tax: number | null\n  payment_fee: number | null\n  payment_fee_tax: number | null\n  commission: number | null\n  tx_hash: string | null\n  tx_confirms: number | null\n  created_date: string\n  created_at: string\n  status: string\n  completed_at: string | null\n  merchant_fee: number | null\n  merchant_commission: number | null\n  meta_data: string | null\n  blockchain: { id: number; code: 'LRC'; description: 'Loopring ' | null }\n}\n\nexport const LuckyRedPacketList: LuckyRedPacketItem[] = [\n  {\n    labelKey: 'labelLuckyRandomToken',\n    desKey: 'labelRedPacketsSplitLuckyDetail',\n    tags: [\n      'showInNormal',\n      'enableInNFTS',\n      'enableInERC20',\n      'defaultForERC20',\n      'defaultForNFT',\n      'enableInBlindBox',\n    ],\n    value: {\n      value: 1,\n      partition: sdk.LuckyTokenAmountType.RANDOM,\n      mode: sdk.LuckyTokenClaimType.COMMON,\n    },\n  },\n  {\n    labelKey: 'labelLuckyRandomToken',\n    desKey: 'labelRedPacketsSplitLuckyDetail',\n    tags: ['defaultForBlindBox', 'enableInBlindBox', 'showInBlindBox', 'defaultForFromNFT'],\n    value: {\n      value: 4,\n      partition: sdk.LuckyTokenAmountType.RANDOM,\n      mode: sdk.LuckyTokenClaimType.BLIND_BOX,\n    },\n  },\n  {\n    labelKey: 'labelLuckyCommonToken',\n    desKey: 'labelLuckyCommonTokenDes',\n    tags: ['showInNormal', 'showInBlindBox', 'enableInNFTS', 'enableInERC20'],\n    value: {\n      value: 2,\n      partition: sdk.LuckyTokenAmountType.AVERAGE,\n      mode: sdk.LuckyTokenClaimType.COMMON,\n    },\n  },\n  {\n    labelKey: 'labelLuckyRelayToken',\n    desKey: 'labelLuckyRelayTokenDes',\n    tags: ['showInNormal', 'showInBlindBox', 'enableInERC20', 'disabledForExclusive'],\n    value: {\n      value: 0,\n      partition: sdk.LuckyTokenAmountType.RANDOM,\n      mode: sdk.LuckyTokenClaimType.RELAY,\n    },\n  },\n]\n\nexport const QRCODE_REGION_ID = 'qrcodeRegionId'\n\nexport type ACCOUNT_ADDRESS = string\nexport type TX_HASH = string\nexport type RedPacketHashItems = {\n  [key: TX_HASH]: {\n    claim: string\n    luckToken: sdk.LuckyTokenItemForReceive\n    blindboxClaimed: any\n  }\n}\nexport type RedPacketHashInfo = {\n  [key: ACCOUNT_ADDRESS]: RedPacketHashItems\n}\nexport type RedPacketHashInfos = {\n  [key in sdk.ChainId extends string ? string : string]: RedPacketHashInfo\n}\n\nexport enum OffRampStatus {\n  // waitingForPayment = \"waitingForPayment\",\n  watingForCreateOrder = 'watingForCreateOrder',\n  waitingForWithdraw = 'waitingForWithdraw',\n  expired = 'expired',\n  cancel = 'cancel',\n  done = 'done',\n  refund = 'refund',\n}\n\nexport type OffRampHashItem = {\n  orderId: string\n  chainId: sdk.ChainId\n  address: string\n  product: VendorProviders\n  status: OffRampStatus\n  wallet_address?: string | undefined\n  checkout_iframe?: string\n  account_reference?: string\n  [key: string]: any\n}\nexport type OffRampHashItemObj = {\n  pending: OffRampHashItem\n  payments: OffRampHashItem[]\n}\nexport type OffRampHashItems<T = VendorProviders> = {\n  [K in keyof T]: OffRampHashItemObj\n}\nexport type OffRampHashInfo = {\n  [key: ACCOUNT_ADDRESS]: OffRampHashItems\n}\nexport type OffRampHashInfos = {\n  [key in sdk.ChainId extends string ? string : string]: OffRampHashInfo\n}\n\nexport enum RedPacketOrderType {\n  TOKEN = 'TOKEN',\n  NFT = 'NFT',\n  BlindBox = 'BlindBox',\n  FromNFT = 'FromNFT',\n}\n\nexport type RedPacketOrderData<I> = {\n  tradeType: RedPacketOrderType\n  isNFT: boolean\n  tradeValue?: number\n  fee: FeeInfo | undefined\n  __request__: any\n  target?: {\n    redpacketHash: string\n    addressListString: string\n    popupChecked: boolean\n    maxSendCount: number\n    sentAddresses?: string[]\n  }\n  showNFT: boolean\n  type: any\n} & Partial<IBData<I>> &\n  Partial<NFTWholeINFO> &\n  Partial<sdk.LuckyTokenItemForSendV3>\n\nexport enum TabTokenTypeIndex {\n  ERC20 = 'ERC20',\n  NFT = 'NFT',\n}\n\nexport interface SnackbarMessage {\n  message: string\n  key: number | string\n  svgIcon?: string\n}\n\nexport const BTRDE_PRE = 'BTRADE-'\n\nexport enum TradeProType {\n  sell = 'sell',\n  buy = 'buy',\n}\n\nexport enum TradeBaseType {\n  price = 'price',\n  quote = 'quote',\n  base = 'base',\n  tab = 'tab',\n  slippage = 'slippage',\n  stopPrice = 'stopPrice',\n  checkMarketPrice = 'checkMarketPrice',\n}\n\nexport type AmmHistoryItem = {\n  close: number\n  timeStamp: number\n}\nexport enum LocalStorageConfigKey {\n  tokenMap = 'tokenMap',\n  ammpools = 'ammpools',\n  markets = 'markets',\n  btradeMarkets = 'btradeMarkets',\n  vaultMarkets = 'vaultMarkets',\n  vaultTokenMap = 'vaultTokenMap',\n  exchangeInfo = 'exchangeInfo',\n  disableWithdrawTokenList = 'disableWithdrawTokenList',\n}\n\nexport enum DualStep {\n  ChooseType = 'ChooseType',\n  ShowBase = 'ShowBase',\n  ShowSellBuy = 'ShowSellBuy',\n  ShowQuote = 'ShowQuote',\n  ShowList = 'ShowList',\n}\nexport enum DualViewType {\n  DualGain = 'DualGain',\n  DualDip = 'DualDip',\n  DualBegin = 'DualBegin',\n  DualBTC = 'DualBTC',\n  All = 'All',\n}\nexport const DualGain = [\n  // { step: DualStep.ChooseType, type: 'Card' },\n  { step: DualStep.ShowBase, type: 'Tab', labelKey: 'labelDualChooseTokenDUAL_BASE' },\n  {},\n  { step: DualStep.ShowQuote, type: 'Tab', labelKey: 'labelDualChooseTargetPriceDUAL_BASE' },\n]\nexport const DualDip = [\n  // { step: DualStep.ChooseType, type: 'Card' },\n  { step: DualStep.ShowBase, type: 'Tab', labelKey: 'labelDualChooseTokenDUAL_CURRENCY' },\n  {},\n  { step: DualStep.ShowQuote, type: 'Tab', labelKey: 'labelDualChooseTargetPriceDUAL_CURRENCY' },\n]\nexport const DualBegin = [\n  { step: DualStep.ShowBase, type: 'Tab', labelKey: 'labelDualBeginnerStep1Title' },\n  { step: DualStep.ChooseType, type: 'Tab', labelKey: 'labelDualBeginnerSellHigh' },\n  { step: DualStep.ShowQuote, type: 'Tab', labelKey: 'labelDualBeginnerStep3Title' },\n]\nexport const DualBTC = [\n  { step: DualStep.ShowBase, type: 'Tab', labelKey: 'labelDualChooseTokenDUAL_BASE' },\n  {},\n  { step: DualStep.ShowQuote, type: 'Tab', labelKey: 'labelDualBeginnerStep3Title' },\n]\n\nexport type VaultMarketExtends = { enabled: boolean | 'isFormLocal' } & Omit<\n  sdk.VaultMarket,\n  'enabled'\n> & {\n    vaultMarket: string\n    originalBaseSymbol: string\n    originalQuoteSymbol: string\n  }\n\nexport enum VaultLoanType {\n  Borrow = 'Borrow',\n  Repay = 'Repay',\n}\n\nexport enum AmmPanelType {\n  Join = 0,\n  Exit = 1,\n}\n\nexport enum DualInvestConfirmType {\n  USDCOnly = 'USDCOnly',\n  all = 'all',\n}\n\nexport enum VaultAction {\n  VaultJoin = 'VaultJoin',\n  VaultExit = 'VaultExit',\n  VaultLoan = 'VaultLoan',\n  VaultSwap = 'VaultSwap',\n}\n\nexport enum VaultSwapStep {\n  Edit = 'Edit',\n  Borrow = 'Borrow',\n  Swap = 'Swap',\n  Swaping = 'Swaping',\n}\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/constant/vendor.ts",
    "content": "export enum VendorProviders {\n  Ramp = 'Ramp',\n  Banxa = 'Banxa',\n}\n\n// export const vendorList: VendorItem[] = [\n//   {\n//     key: VendorProviders.Ramp,\n//     svgIcon: \"RampIcon\",\n//     // handleSelect: () => {},\n//   },\n//   {\n//     key: VendorProviders.Banxa,\n//     svgIcon: \"BanxaIcon\",\n//     flag: {\n//       startDate: Date.now() - 100, //1649688436000,\n//       endDate: 1650844800000,\n//       tag: \"🔥\",\n//       highLight: \"lableBanxaFeeFree\",\n//     },\n//     // handleSelect: () => {},\n//   },\n// ];\nexport const VendorList = {\n  Ramp: {\n    key: VendorProviders.Ramp,\n    svgIcon: 'RampIcon',\n    // handleSelect: () => {},\n  },\n  Banxa: {\n    key: VendorProviders.Banxa,\n    svgIcon: 'BanxaIcon',\n    flag: {\n      startDate: 1649635200000,\n      endDate: 1650844800000,\n      tag: '🔥',\n      highLight: 'labelBanxaFeeFree',\n    },\n    // handleSelect: () => {},\n  },\n}\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/constant/walletConnector.ts",
    "content": "import { GatewayItem } from '../loopring-interface'\nimport { SoursURL } from './router'\nimport { ConnectProviders } from '@loopring-web/web3-provider'\n\nexport enum GatewaySort {\n  MetaMask,\n  WalletConnect,\n  GameStop,\n  Coinbase,\n  WalletConnectV1,\n}\n\nconst gatewayMap = new Map<GatewaySort, GatewayItem>() // = [\ngatewayMap.set(GatewaySort.MetaMask, {\n  key: ConnectProviders.MetaMask,\n  keyi18n: ConnectProviders.MetaMask,\n  imgSrc: SoursURL + 'svg/meta-mask.svg',\n})\ngatewayMap.set(GatewaySort.WalletConnect, {\n  key: ConnectProviders.WalletConnect,\n  keyi18n: ConnectProviders.WalletConnect,\n  imgSrc: SoursURL + 'svg/wallet-connect.svg',\n})\ngatewayMap.set(GatewaySort.GameStop, {\n  key: ConnectProviders.GameStop,\n  keyi18n: ConnectProviders.GameStop,\n  imgSrc: SoursURL + 'svg/gs.svg',\n})\n\ngatewayMap.set(GatewaySort.Coinbase, {\n  key: ConnectProviders.Coinbase,\n  keyi18n: ConnectProviders.Coinbase,\n  imgSrc: SoursURL + 'svg/coinbase-wallet.svg',\n})\ngatewayMap.set(GatewaySort.WalletConnectV1, {\n  key: (ConnectProviders.WalletConnectV1 + 'V1') as ConnectProviders,\n  keyi18n: ConnectProviders.WalletConnectV1 + 'V1',\n  imgSrc: SoursURL + 'svg/wallet-connect.svg',\n})\n\nexport const gatewayList: GatewayItem[] = [...gatewayMap.keys()].reduce((prev, key) => {\n  // @ts-ignore\n  prev[key as any] = gatewayMap.get(key as any)\n  return prev\n}, [] as GatewayItem[])\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/error/errorMap.tsx",
    "content": "import { Trans } from 'react-i18next'\nimport { Link } from '@mui/material'\n\nexport const ErrorMap = {\n  ERROR_UNKNOWN: {\n    id: 'ERROR_UNKNOWN',\n    messageKey: 'errorUnknown',\n  },\n  ERROR_ON_FROM_SUBMIT: {\n    id: 'ERROR_ON_FROM_SUBMIT',\n    messageKey: 'errorOnFromSubmit',\n  },\n  ERROR_WRONG_ACCOUNT: {\n    id: 'ERROR_WRONG_ACCOUNT',\n    messageKey: 'errorWrongAccount',\n  },\n  ERROR_WRONG_TOKEN: {\n    id: 'ERROR_WRONG_TOKEN',\n    messageKey: 'errorWrongToken',\n  },\n  ERROR_WRONG_APIKEY: {\n    id: 'ERROR_WRONG_APIKEY',\n    messageKey: 'errorWrongApikey',\n  },\n  ERROR_WRONG_BALANCE: {\n    id: 'ERROR_WRONG_BALANCE',\n    messageKey: 'errorWrongBalance',\n  },\n  ERROR_WRONG_MIN: {\n    id: 'ERROR_WRONG_BALANCE',\n    messageKey: 'errorWrongBalance',\n  },\n  ERROR_MINIMUM_ORDER: {\n    id: 'ERROR_MINIMUM_ORDER',\n    messageKey: 'errorMinimumOrder',\n  },\n  ERROR_MAXIMUM_ORDER: {\n    id: 'ERROR_MAXIMUM_ORDER',\n    messageKey: 'errorMaximumOrder',\n  },\n  ERROR_ON_FROZEN: {\n    id: 'ERROR_ON_FROZEN',\n    messageKey: 'errorOnFrozen',\n  },\n  ERROR_ON_FEE: {\n    id: 'ERROR_ON_FEE',\n    messageKey: 'errorAboutFee',\n  },\n  ERROR_PROVIDER_ERROR: {\n    id: 'ERROR_PROVIDER_ERROR',\n    messageKey: 'errorProviderError',\n    options: {},\n  },\n  ERROR_ON_STORAGE_ID: {\n    id: 'ERROR_ON_STORAGE_ID',\n    messageKey: 'errorOnStorageId',\n    options: {},\n  },\n  ERROR_ON_NO_RECIPIENT: {\n    id: 'ERROR_ON_NO_RECIPIENT',\n    messageKey: 'errorOnNoRecipient',\n    options: {},\n  },\n  ERROR_INVALID_HASH: {\n    id: 'ERROR_INVALID_HASH',\n    messageKey: 'errorInvalidHash',\n    options: {},\n  },\n  ERROR_ON_CANCEL_ORDERS: {\n    id: 'ERROR_ON_CANCEL_ORDERS',\n    messageKey: 'errorOnCancelOrders',\n    options: {},\n  },\n  ERROR_ON_GAS: {\n    id: 'ERROR_ON_GAS',\n    messageKey: 'errorOnGas',\n    options: {},\n  },\n  ERROR_NO_MARKET: {\n    id: 'ERROR_NO_MARKET',\n    messageKey: 'errorNoMarket',\n    options: {},\n  },\n  ERROR_INVALID_ORDER_ID: {\n    id: 'ERROR_INVALID_ORDER_ID',\n    messageKey: 'errorInvalidOrderId',\n    options: {},\n  },\n  ERROR_ON_RATE: {\n    id: 'ERROR_ON_RATE',\n    messageKey: 'errorOnRate',\n    options: {},\n  },\n  ERROR_FOR_EXIST_ORDER: {\n    id: 'ERROR_FOR_EXIST_ORDER',\n    messageKey: 'errorForExistOrder',\n    options: {},\n  },\n  ERROR_ORDER_EXPIRED: {\n    id: 'ERROR_ORDER_EXPIRED',\n    messageKey: 'errorOrderExpired',\n    options: {},\n  },\n  LOADING_WHOLE_SITE: {\n    id: 'LOADING_WHOLE_SITE',\n    messageKey: 'errorLoading',\n  },\n  NO_SUPPORT_PAIR: {\n    id: 'NO_SUPPORT_PAIR',\n    messageKey: 'no support base/quote pair!',\n  },\n  NO_SDK: {\n    id: 'NO_SDK',\n    messageKey: 'errorBase',\n  },\n  TIME_OUT: {\n    id: 'TIME_OUT',\n    messageKey: 'errorTimeout',\n  },\n  NO_NETWORK_ERROR: {\n    id: 'NO_NETWORK_ERROR',\n    messageKey: 'errorMessageNoNetwork',\n  },\n  NO_TOKEN_MAP: {\n    id: 'NO_TOKEN_MAP',\n    messageKey: 'errorMessageTokenMapIsEmpty',\n  },\n  NO_ENOUGH_BALANCE: {\n    id: 'NO_ENOUGH_BALANCE',\n    messageKey: 'errorTokenNotEnough',\n  },\n  NO_TOKEN_KEY_LIST: {\n    id: 'NO_TOKEN_KEY_LIST',\n    messageKey: 'errorRequiredTokenKeyList',\n  },\n  GET_X_TOKEN_TICKER_ERROR: {\n    id: 'NO_TOKEN_KEY_LIST',\n    messageKey: 'errorRequiredTokenKeyList',\n    options: {},\n  },\n  BUILD_AMM_MAP_WITH_TICKER: {\n    id: 'BUILD_AMM_MAP_WITH_TICKER',\n    messageKey: 'errorBase',\n    options: {},\n  },\n  TRADE_LITE_SET_PAIR_ERROR: {\n    id: 'TRADE_LITE_SET_PAIR_ERROR',\n    messageKey: 'errorBase',\n    options: {},\n  },\n  SOCKET_ERROR: {\n    id: 'SOCKET_ERROR',\n    messageKey: 'errorBase',\n    options: {},\n  },\n  TRADE_404: {\n    id: '404',\n    messageKey: 'error404',\n    options: {},\n  },\n  NTF_ID_ENCODE_ERROR: {\n    id: 'NTF_ID_ENCODE_ERROR',\n    messageKey: 'NTF_ID_ENCODE_ERROR',\n    options: {},\n  },\n  PROVIDER_ERROR: {\n    id: 'PROVIDER_ERROR',\n    messageKey: 'errorDisableOtherWalletForCurrent',\n    options: {},\n  },\n  GENERATE_EDDSA: {\n    id: 'GENERATE_EDDSA',\n    messageKey: 'errorGenerateEddsa',\n    options: {},\n  },\n  DATA_NOT_READY: {\n    id: 'DATA_NOT_READY',\n    messageKey: 'errorDataNotReady',\n    options: {},\n  },\n  PROVIDER_NOT_INSTALL_GME: {\n    id: 'PROVIDER_NOT_INSTALL_GME',\n    messageKey: 'errorNotInstallGME',\n    options: {\n      link: (\n        <Trans i18nKey={'errorLinKWalletApp'} ns={'error'}>\n          <Link\n            target='_blank'\n            rel='noopener noreferrer'\n            href={'https://wallet.gamestop.com/wallets'}\n          >\n            app market\n          </Link>\n        </Trans>\n      ),\n    },\n  },\n  NO_IPFS_INSTANCE: {\n    id: 'NO_IPFS_INSTANCE',\n    messageKey: 'errorNoIpfsInstance',\n    options: {},\n  },\n  ADD_IPFS_ERROR: {\n    id: 'ADD_IPFS_ERROR',\n    messageKey: 'errorAddIpfsError',\n    options: {},\n  },\n  CREATE_IPFS_ERROR: {\n    id: 'CREATE_IPFS_ERROR',\n    messageKey: 'errorCreateIpfsError',\n    options: {},\n  },\n  NOT_SAME_IPFS_RESOURCE: {\n    id: 'NOT_SAME_IPFS_RESOURCE',\n    messageKey: 'errorNotSameIpfsResource',\n    options: {},\n  },\n  IPFS_CID_TO_NFTID_ERROR: {\n    id: 'IPFS_CID_TO_NFTID_ERROR',\n    messageKey: 'errorIpfsDidToNftidError',\n    options: {},\n  },\n  ERROR_MINT_OVERLAP: {\n    id: 'ERROR_MINT_OVERLAP',\n    messageKey: 'errorMintOverlap',\n    options: {},\n  },\n  ERROR_JSON_STRINGIFY: {\n    id: 'ERROR_JSON_STRINGIFY',\n    messageKey: 'errorJSONStringify',\n    options: {},\n  },\n  ERROR_COLLECTION_METADATA_NO_TILEURI: {\n    id: 'ERROR_COLLECTION_METADATA_NO_TILEURI',\n    messageKey: 'errorCollectionMetadataNoTileUri',\n    options: {},\n  },\n  ERROR_COLLECTION_NO_NAME: {\n    id: 'ERROR_COLLECTION_NO_NAME',\n    messageKey: 'errorCollectionNoName',\n    options: {},\n  },\n  ERROR_COLLECTION_SAME_NAME: {\n    id: 'ERROR_COLLECTION_SAME_NAME',\n    messageKey: 'errorCollectionSameName',\n    options: {},\n  },\n  ERROR_COLLECTION_EMPTY: {\n    id: 'ERROR_COLLECTION_EMPTY',\n    messageKey: 'errorCollectionEmpty',\n    options: {},\n  },\n  ERROR_COLLECTION_NOT_READABLE: {\n    id: 'ERROR_COLLECTION_NOT_READABLE',\n    messageKey: 'errorCollectionNotReadable',\n    options: {},\n  },\n  ERROR_COLLECTION_INFO: {\n    id: 'ERROR_COLLECTION_INFO',\n    messageKey: 'errorCollectionInfo',\n    options: {},\n  },\n  ERROR_COLLECTION_NO_SUPPORT: {\n    id: 'ERROR_COLLECTION_NO_SUPPORT',\n    messageKey: 'errorCollectionNoSupport',\n    options: {},\n  },\n  ERROR_ON_REFRESH: {\n    id: 'ERROR_ON_REFRESH',\n    messageKey: 'errorOnRefresh',\n    options: {},\n  },\n  IPFS_TIME_OUT: {\n    id: 'IPFS_TIME_OUT',\n    messageKey: 'errorIpfsTimeout',\n  },\n  ERROR_RAMP_NO_INSTANCE: {\n    id: 'ERROR_RAMP_NO_INSTANCE',\n    messageKey: 'errorRampNoInstance',\n    options: {},\n  },\n  ERROR_DUAL_EXPIRED: {\n    id: 'ERROR_DUAL_EXPIRED',\n    messageKey: 'errorDualExpired',\n    options: {},\n  },\n  ERROR_PRIVATE_KEY: {\n    id: 'ERROR_PRIVATE_KEY',\n    messageKey: 'errorPrivateKey',\n    options: {},\n  },\n  ERROR_NO_RESPONSE: {\n    id: 'ERROR_NO_RESPONSE',\n    messageKey: 'errorNoResponse',\n    options: {},\n  },\n  ERROR_REDPACKET_EMPTY: {\n    id: 'ERROR_REDPACKET_EMPTY',\n    messageKey: 'errorRedpacketEmpty',\n    options: {},\n  },\n  ERROR_REDPACKET_CLAIMED: {\n    id: 'ERROR_REDPACKET_CLAIMED',\n    messageKey: 'errorRedpacketClaimed',\n    options: {},\n  },\n  ERROR_REDPACKET_CLAIM_OUT: {\n    id: 'ERROR_REDPACKET_CLAIM_OUT',\n    messageKey: 'errorRedpacketClaimOut',\n    options: {},\n  },\n  ERROR_REDPACKET_CLAIM_TIMEOUT: {\n    id: 'ERROR_REDPACKET_CLAIM_TIMEOUT',\n    messageKey: 'errorRedpacketClaimTimeOut',\n    options: {},\n  },\n  ERROR_OFF_RAMP_EXPIRED: {\n    id: 'ERROR_OFF_RAMP_EXPIRED',\n    messageKey: 'errorOffRampExpired',\n  },\n  PROVIDER_ERROR_UNKNOWN: {\n    id: 'PROVIDER_ERROR_UNKNOWN',\n    messageKey: 'errorProviderErrorUnknown',\n  },\n  GUARDIAN_ROUTER_ERROR: {\n    id: 'GUARDIAN_ROUTER_ERROR',\n    messageKey: 'errorGuardianRouterError',\n  },\n  ERROR_SWITCH_ETHEREUM: {\n    id: 'ERROR_SWITCH_ETHEREUM',\n    messageKey: 'errorSwitchEthereum',\n  },\n  ERROR_NO_GAMESTOP_EXTENSION: {\n    id: 'ERROR_NO_GAMESTOP_EXTENSION',\n    messageKey: 'errorNoGamestopExtension',\n  },\n  ERROR_ETHEREUM_NOT_METAMASK: {\n    id: 'ERROR_ETHEREUM_NOT_METAMASK',\n    messageKey: 'errorEthereumNotMetamask',\n  },\n  ERROR_GAMESTOP_NO_CHAIN_CHANGE: {\n    id: 'ERROR_GAMESTOP_NO_CHAIN_CHANGE',\n    messageKey: 'errorGamestopNoChainChange',\n  },\n  ERROR_ADDRESS_CHECK_ERROR: {\n    id: 'ERROR_ADDRESS_CHECK_ERROR',\n    messageKey: 'errorAddressCheckError',\n  },\n  ERROR_CONTACT_EXISTED: { id: 'ERROR_CONTACT_EXISTED', messageKey: 'errorContactExisted' },\n  ERROR_CONTACT_NAME_EXISTED: {\n    id: 'ERROR_CONTACT_NAME_EXISTED',\n    messageKey: 'errorContactNameExisted',\n  },\n  ERROR_CONTACT_LIMIT_REACHED: {\n    id: 'ERROR_CONTACT_LIMIT_REACHED',\n    messageKey: 'errorContactLimit',\n  },\n  ERROR_CONTACT_NAME_OVER_LIMIT: {\n    id: 'ERROR_CONTACT_NAME_OVER_LIMIT',\n    messageKey: 'errorContactOverLimit',\n  },\n  ERROR_ORDER_FAILED: {\n    id: 'ERROR_ORDER_FAILED',\n    messageKey: 'errorOrderFailed',\n  },\n  ERROR_ADDRESS_BURN_NFT:{\n    id: 'ERROR_ADDRESS_BURN_NFT',\n    messageKey: 'errorAddressBurnNft',\n  }\n}\n\nexport enum UIERROR_CODE {\n  NO_NETWORK_ERROR = 700000,\n  UNKNOWN = 700001,\n  PROVIDER_ERROR = 700002,\n  PROVIDER_ERROR_UNKNOWN = 700003,\n  PROVIDER_NOT_INSTALL_GME = 700004,\n  DATA_NOT_READY = 700005,\n  GENERATE_EDDSA = 700006,\n  NO_IPFS_INSTANCE = 700007,\n  ADD_IPFS_ERROR = 700008,\n  CREATE_IPFS_ERROR = 700009,\n  NOT_SAME_IPFS_RESOURCE = 700010,\n  IPFS_CID_TO_NFTID_ERROR = 700011,\n  TIME_OUT = 700012,\n  ERROR_JSON_STRINGIFY = 700013,\n  ERROR_COLLECTION_METADATA_NO_TILEURI = 700014,\n  ERROR_COLLECTION_NO_NAME = 700015,\n  ERROR_COLLECTION_INFO = 700016,\n  ERROR_COLLECTION_EMPTY = 700017,\n  ERROR_COLLECTION_NO_SUPPORT = 700018,\n  ERROR_COLLECTION_NOT_READABLE = 700019,\n  IPFS_TIME_OUT = 700020,\n  ERROR_ON_FEE_UI = 700021,\n  ERROR_PRIVATE_KEY = 700022,\n  ERROR_NO_RESPONSE = 700023,\n  ERROR_REDPACKET_EMPTY = 700024,\n  ERROR_ORDER_FAILED = 700205,\n\n  ERROR_RAMP_NO_INSTANCE = 700100,\n  ERROR_OFF_RAMP_EXPIRED = 700101,\n  ERROR_ADDRESS_CHECK_ERROR = 700102,\n  ERROR_ADDRESS_BURN_NFT = 700103,\n  ERROR_WALLECTCONNECT_MANUALLY_CLOSE = 700201,\n  ERROR_GAMESTOP_NO_CHAIN_CHANGE = 700202,\n  ERROR_DUAL_EXPIRED = 115003,\n  ERROR_REDPACKET_CLAIMED = 113002,\n  ERROR_REDPACKET_CLAIM_OUT = 113006,\n  ERROR_REDPACKET_CLAIM_TIMEOUT = 113000,\n  ERROR_SWITCH_ETHEREUM = 700202,\n  ERROR_NO_GAMESTOP_EXTENSION = 700203,\n  ERROR_ETHEREUM_NOT_METAMASK = 700204,\n  ERROR_CONTACT_EXISTED = 124001,\n  ERROR_CONTACT_NAME_EXISTED = 124002,\n  ERROR_CONTACT_LIMIT_REACHED = 124003,\n  ERROR_CONTACT_NAME_OVER_LIMIT = 124004,\n\n}\n\nexport type ErrorObject = {\n  from?: string\n  timestamp?: number\n  messageKey: string\n  [key: string]: any\n}\nexport const SDK_ERROR_MAP_TO_UI = {\n  700000: ErrorMap.NO_NETWORK_ERROR,\n  700001: ErrorMap.ERROR_UNKNOWN, //UI Unknown error =>\n  700002: ErrorMap.ERROR_PROVIDER_ERROR,\n  700003: ErrorMap.PROVIDER_ERROR_UNKNOWN,\n  700004: ErrorMap.PROVIDER_NOT_INSTALL_GME,\n  700005: ErrorMap.DATA_NOT_READY,\n  700006: ErrorMap.GENERATE_EDDSA,\n  700007: ErrorMap.NO_IPFS_INSTANCE,\n  700008: ErrorMap.ADD_IPFS_ERROR,\n  700009: ErrorMap.CREATE_IPFS_ERROR,\n  700010: ErrorMap.NOT_SAME_IPFS_RESOURCE,\n  700011: ErrorMap.IPFS_CID_TO_NFTID_ERROR,\n  700012: ErrorMap.TIME_OUT,\n  700013: ErrorMap.ERROR_JSON_STRINGIFY,\n  700014: ErrorMap.ERROR_COLLECTION_METADATA_NO_TILEURI,\n  700015: ErrorMap.ERROR_COLLECTION_NO_NAME,\n  700016: ErrorMap.ERROR_COLLECTION_INFO,\n  700017: ErrorMap.ERROR_COLLECTION_EMPTY,\n  700018: ErrorMap.ERROR_COLLECTION_NO_SUPPORT,\n  700019: ErrorMap.ERROR_COLLECTION_NOT_READABLE,\n  700020: ErrorMap.IPFS_TIME_OUT,\n  700021: ErrorMap.ERROR_ON_FEE,\n  700022: ErrorMap.ERROR_PRIVATE_KEY,\n  700023: ErrorMap.ERROR_NO_RESPONSE,\n  700024: ErrorMap.ERROR_REDPACKET_EMPTY,\n  700205: ErrorMap.ERROR_ORDER_FAILED,\n  700100: ErrorMap.ERROR_RAMP_NO_INSTANCE,\n  700101: ErrorMap.ERROR_OFF_RAMP_EXPIRED,\n  700202: ErrorMap.ERROR_SWITCH_ETHEREUM,\n  700103: ErrorMap.ERROR_ADDRESS_BURN_NFT,\n  700203: ErrorMap.ERROR_NO_GAMESTOP_EXTENSION,\n  700204: ErrorMap.ERROR_ETHEREUM_NOT_METAMASK,\n  700102: ErrorMap.ERROR_ADDRESS_CHECK_ERROR,\n  100000: ErrorMap.ERROR_UNKNOWN, //Unknown error =>\n  100001: ErrorMap.ERROR_ON_FROM_SUBMIT, //Invalid argument\n  101001: ErrorMap.ERROR_WRONG_ACCOUNT, //The address was not found\n  101002: ErrorMap.ERROR_WRONG_ACCOUNT, //User not found\n  102001: ErrorMap.ERROR_ON_FROM_SUBMIT, //Exchange ID is incorrect\n  102002: ErrorMap.ERROR_WRONG_TOKEN, //Unsupported TokenId in the order\n  102003: ErrorMap.ERROR_WRONG_ACCOUNT, //Invalid account ID\n  102004: ErrorMap.ERROR_INVALID_ORDER_ID, //Invalid order ID\n  102005: ErrorMap.ERROR_NO_MARKET, //Market does not support\n  102006: ErrorMap.ERROR_ON_RATE, //Illegal rate field\n  102007: ErrorMap.ERROR_FOR_EXIST_ORDER, //Order already exists\n  102008: ErrorMap.ERROR_ORDER_EXPIRED, //Order has expired\n  102010: ErrorMap.ERROR_WRONG_APIKEY, //Order is missing signature information\n  102011: ErrorMap.ERROR_WRONG_BALANCE, //Insufficient user balance\n  102012: ErrorMap.ERROR_MINIMUM_ORDER, //The order amount is too small\n  102014: ErrorMap.ERROR_ON_FROZEN, //Failed to freeze the amount, please try again later\n  102020: ErrorMap.ERROR_MAXIMUM_ORDER, //Exceeded the maximum order amount\n  102021: ErrorMap.ERROR_ON_FROM_SUBMIT, //\tNonce is invalid\n  102022: ErrorMap.ERROR_ON_FROM_SUBMIT, //Transfer sender is invalid\n  102023: ErrorMap.ERROR_ON_FROM_SUBMIT, //Transfer receiver is invalid\n  102024: ErrorMap.ERROR_ON_FEE, //Fee token is unsupported\n  102025: ErrorMap.ERROR_ON_FEE, //Fee token is unsupported//Transfer token isnt consistent with fee token\n  102027: ErrorMap.ERROR_ON_FROM_SUBMIT, //Submit order failed\n  102028: ErrorMap.ERROR_ON_STORAGE_ID, //No Available storage id\n  102030: ErrorMap.ERROR_ON_STORAGE_ID, //Invalid storage id\n  102032: ErrorMap.ERROR_ON_NO_RECIPIENT, //Invalid recipient\n  102117: ErrorMap.ERROR_ON_CANCEL_ORDERS, //No orders to cancel\n  102118: ErrorMap.ERROR_ON_CANCEL_ORDERS, //Failed to cancel orders, please try again later\n  102119: ErrorMap.ERROR_INVALID_HASH, //Invalid hash\n  102120: ErrorMap.ERROR_ON_FROM_SUBMIT, //Order is not valid\n  102122: ErrorMap.ERROR_ON_CANCEL_ORDERS, //Order already in cancel\n  104001: ErrorMap.ERROR_WRONG_APIKEY, //Empty ApiKey\n  102040: ErrorMap.ERROR_MINT_OVERLAP, //mint record with the same nft token address and token id already exists\n  104002: ErrorMap.ERROR_WRONG_APIKEY, //Invalid ApiKey\n  104003: ErrorMap.ERROR_WRONG_ACCOUNT, //Invalid Account ID\n  104004: ErrorMap.ERROR_ON_FROM_SUBMIT, //No signature information provided\n  104005: ErrorMap.ERROR_ON_FROM_SUBMIT, //Wrong signature information\n  104208: ErrorMap.ERROR_UNKNOWN, //Unknown error in Ethereum node\n  104209: ErrorMap.ERROR_UNKNOWN, //Partial batch operation failed\n  105001: ErrorMap.ERROR_ON_GAS, //Failed to get recommended gas\n  107001: ErrorMap.ERROR_WRONG_ACCOUNT, //User ID cannot be empty\n  107002: ErrorMap.ERROR_INVALID_HASH, //Order Hash cannot be empty\n  107003: ErrorMap.ERROR_ON_FROM_SUBMIT, //Order does not exist\n  108000: ErrorMap.ERROR_NO_MARKET, //Unsupported market\n  102127: ErrorMap.ERROR_COLLECTION_SAME_NAME,\n  108001: ErrorMap.ERROR_ON_FROM_SUBMIT, //Unsupported depth level\n  113002: ErrorMap.ERROR_REDPACKET_CLAIMED, // REDPACKET_CLAIMED\n  113006: ErrorMap.ERROR_REDPACKET_CLAIM_OUT, // REDPACKET_COUNT_OUT\n  113000: ErrorMap.ERROR_REDPACKET_CLAIM_TIMEOUT, // REDPACKET_CLAIM_TIMEOUT\n  114001: ErrorMap.ERROR_ON_FEE, //Fee token not support\n  114002: ErrorMap.ERROR_ON_FEE, //Fee amount invalid, need refresh the fee. App need refresh fee less than every 15 mins\n  122001: ErrorMap.ERROR_ON_REFRESH,\n  124001: ErrorMap.ERROR_CONTACT_EXISTED,\n  124002: ErrorMap.ERROR_CONTACT_NAME_EXISTED,\n  124003: ErrorMap.ERROR_CONTACT_LIMIT_REACHED,\n  124004: ErrorMap.ERROR_CONTACT_NAME_OVER_LIMIT,\n  115003: ErrorMap.ERROR_DUAL_EXPIRED,\n}\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/error/index.ts",
    "content": "export * from './errorMap'\n\nexport type ErrorType = {\n  id: string\n  messageKey: string\n  message?: string\n  options?: any\n}\nexport type ErrorWithCodeType = {\n  id: string\n  code: number\n  message: string\n  messageKey?: string\n  options?: any\n}\n\nexport class CustomError extends Error {\n  constructor(error: ErrorType) {\n    // Pass remaining arguments (including vendor specific ones) to parent constructor\n    super(error.id)\n\n    // Maintains proper stack trace for where our error was thrown (only available on V8)\n    if (Error.captureStackTrace) {\n      Error.captureStackTrace(this, CustomError)\n    }\n\n    this.name = error.id\n    this.message = error?.message ?? error.id\n    this._date = Date.now()\n    this._messageKey = error.messageKey\n    this._options = error.options\n    // Custom debugging information\n    // this.foo = foo\n    // this.date = new Date()\n  }\n\n  private _options: any\n\n  get options(): any {\n    return this._options\n  }\n\n  private _date: number\n\n  get date(): number {\n    return this._date\n  }\n\n  private _messageKey: string\n\n  get messageKey(): string {\n    return this._messageKey\n  }\n}\n\nexport class CustomErrorWithCode extends Error {\n  constructor(error: ErrorWithCodeType) {\n    // Pass remaining arguments (including vendor specific ones) to parent constructor\n    super(error.id)\n\n    // Maintains proper stack trace for where our error was thrown (only available on V8)\n    if (Error.captureStackTrace) {\n      Error.captureStackTrace(this, CustomError)\n    }\n\n    this.name = error.id\n    this._code = error.code\n    this.message = error.message\n    this._date = Date.now()\n    this._messageKey = error.messageKey ?? error.message\n    // this._options = error.options;\n    // Custom debugging information          '\n    // this.foo = foo\n    // this.date = new Date()\n  }\n  private _code: number\n\n  get code(): number {\n    return this._code\n  }\n\n  private _options: any\n\n  get options(): any {\n    return this._options\n  }\n\n  private _date: number\n\n  get date(): number {\n    return this._date\n  }\n\n  private _messageKey: string\n\n  get messageKey(): string {\n    return this._messageKey\n  }\n}\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/i18n/en_US/common.ts",
    "content": "/* eslint-disable max-len */\nexport default {\n  labelErrorTitle: 'Error Detail: ',\n  labelNoContent: 'No Content',\n  labelError: 'Error',\n  tokenEnter: 'Enter Token',\n  tokenEnterPaymentToken: '',\n  tokenMax: 'Available: ',\n  tokenNFTMaxMINT: 'Max:',\n  tokenHave: 'Available:',\n  tokenEnterReceiveToken: '',\n  tokenSelectToken: 'Select Token',\n  tokenExchange: 'exchange',\n  tokenNotEnough: 'Insufficient {{belong}} balance',\n  tokenSearchCoin: 'Search Token Symbol',\n  swapTitle: 'Swap',\n  swapTolerance: 'Slippage Tolerance',\n  labelSwapToleranceTooltips:\n    'Your trade will revert if the price changes unfavorably by more than this percentage.',\n  swapPriceImpact: 'Price Impact',\n  labelSwapPriceImpactTooltips:\n    'The difference between market price and estimated price due to trade size',\n  swapMinReceive: 'Minimum Received',\n  swapMinReceiveS: 'Min. Received',\n  labelSwapMinReceiveTooltips:\n    'The pool price changes dynamically, the price you see when placing an order may be inconsistent with the final transaction price; also the received amount needs to deduct the fees from converted amount. The protocol can guarantee that the received token is at least this amount.',\n  swapFee: 'Trading Fee',\n  swapFeeS: 'Est. Fee',\n  labelSwapFeeTooltips:\n    'The trading fee is determined by your VIP level and the size of your trade. Small trades (below ~$100) incur a higher fee. Please review the fee before confirming.',\n  swapBtn: 'swap',\n  goBack: 'go back',\n  resetTitle: 'Reset {{layer2}} Keypair',\n  restLabelEnterToken: 'Select Reset cause token',\n  labelResetDescription:\n    'Each account on {{loopringL2}} needs an EdDSA private key (the account key) to sign off-chain (aka {{layer2}}) requests. You can reset the EdDSA keypair at any time.',\n  resetFee: 'Fee {{count}} GAS ≈ ${{price}}',\n  resetLabelBtn: 'Reset',\n  labelActiveEnterToken: 'Select payment token',\n  labelActiveAccountDescription:\n    'You need to have enough balance for {{layer2}} creation as below.',\n  labelActiveAccountFee: 'Fee {{count}} GAS ≈ ${{price}}',\n  labelActiveAccountBtn: 'Activate Account',\n  depositLabelEnterToken: 'Select Layer 1 Token',\n  labelDepositDescription:\n    'Once your deposit is confirmed on {{l1ChainName}}, \\n it will be added to your balance within 2 minutes.',\n  labelDepositAndActiveDescription:\n    'Make a deposit to activate your {{loopringL2}} account. Once your deposit is <1>confirmed on {{l1ChainName}}</1>, it will be added to your balance within <3>2 minutes</3>.',\n  depositLabelRefer: 'Referral address, Account ID or ENS. (Optional)',\n  depositLabelPlaceholder: 'address, Account ID or ENS',\n  withdrawDescription:\n    'Your withdrawal will be processed in the next batch,\\n which usually takes 30 minutes to 2 hours.\\n (There will be a large delay if the {{l1ChainName}} gas price exceeds 500 GWei.）',\n  withdrawTypeLabelFast: 'Fast ~15 seconds',\n  withdrawTypeLabelStandard: 'Standard ~25 minutes',\n  labelConnectWallet: 'Connect wallet',\n\n  labelCustomer: 'Custom',\n  labelChange24h: '{{timeUnit}} Change',\n  labelDepth: 'Depth',\n  labelTrend: 'Price',\n  label1W: 'W1',\n  label1H: 'H1',\n  label1D: 'D1',\n  labelCopyAddress: 'Copy',\n  labelDisconnect: 'Disconnect',\n  labelLockLayer2: 'Lock',\n  labelUnLockLayer2: 'Sign in First',\n  labelSwitchAccount: 'Switch',\n  labelViewEth: 'View on Etherscan',\n  labelQRCode: 'View QR Code',\n  labelShowAccountInfo: 'Show account information',\n  labelAssetTitle: '{{loopringL2}} Total Assets',\n  labelAssetMobileTitle: '{{l2Symbol}} Assets',\n  labelShowAccount: 'Show or Hide Assets',\n  labelLevel: 'VIP Level',\n  labelOrderbook: 'Order book',\n  labelSetPublicKey: 'Set EdDSA Public Key',\n  labelTitleSecurity: 'Security',\n  labelTitleResetL2Keypair: 'Reset {{loopringL2}} Keypair',\n  labelBtnReset: 'Reset',\n  labelHadChangPassword: 'You changed your keypair {{passDay}} ago.',\n  labelTitleForceWithdraw: 'Force Withdraw',\n  labelBtnForceWithdraw: 'Force Withdraw',\n  labelTitleExportAccount: 'Export Account',\n  labelDescriptionExportAccount:\n    'In order to access the {{loopringL2}} APIs, you will need to export a security key.',\n  labelBtnExportAccount: 'Export Account',\n  labelDownloadViewMore: 'View More',\n  labelTitlePreferences: 'Preferences',\n  labelTitleLayout: 'Custom Setting',\n  whichColorIsUp: '<0>{{up}} up</0> and <2>{{down}} down</2> ',\n  labelTradeFeeLevel: 'Your Trading Fee Level:',\n  labelLanguage: 'Language',\n  labelCurrency: 'Currency',\n  currencySetting: 'Currency',\n  labelColors: 'Colors',\n  labelTheme: 'Dark Theme',\n  labelthemeLight: 'Light theme',\n  labelthemeDark: 'Dark theme',\n  labelgreen: 'green',\n  labelred: 'red',\n  langZH: 'Chinese',\n  langEN: 'English',\n  labelUSDollar: 'USD',\n  labelCNYYuan: 'CNY',\n  labelMaker: 'Maker',\n  labelTaker: 'Taker',\n  labelAssetsTitle: 'Assets',\n  labelVolume: 'volume',\n  labelAmount: 'Amount',\n  labelLiquidityDeposit: 'Subscribe',\n  labelLiquidityWithdraw: 'Redeem',\n  labelAvailable: 'Available:',\n  labelTokenAmount: 'Amount',\n  labelRemoveLiquidityBtn: 'Remove Liquidity',\n  labelAddLiquidityBtn: 'Add Liquidity',\n  labelEndLiquidityBtn: 'Ended',\n  labelTradePanelHideOtherPairs: 'Hide other pairs',\n  labelLPTokens: 'LP Tokens',\n  labelMyLPToken: 'My Liquidity Token',\n  labelMyLPAToken: 'My {{symbol}}',\n  labelMyLPBToken: 'My {{symbol}}',\n  labelMyLPAmountFor: 'My Ratio',\n  labelTrade: 'Trade',\n  labelAmmList: 'AMM List',\n  labelMyPoolShare: 'My Pool Share',\n  labelFee: 'Fee',\n  labelLPTotal: 'Total ',\n  labelReward: 'Rewards',\n  labelMyReward: 'My Rewards',\n  labelDate: 'Date',\n  labelBack: 'Back',\n  labelAPR: 'APR',\n  label24Volume: '24h Volume',\n  label24VolumeSimple: '24h Vol',\n  labelTVL: 'TVL',\n  labelAmmTotalToken: 'Tokens in AMM',\n  labelNoActiveEvent: 'No event',\n  labelNew: 'New',\n  labelAccount: 'Account',\n  labelAll: 'All',\n  labelMe: 'My Liquidity',\n  labelMyTrade: 'My Trades',\n  labelRecent: 'Market Trades',\n  labelMyAmm: 'My AMM Liquidity',\n  labelMyAmmRecord: 'My AMM Records',\n  labelCurrentActivities: 'Current Activities',\n  labelPastActivities: 'Past Activities',\n  labelTotalPositionValue: 'Total Investment',\n  labelFeeRewards: 'Fee Rewards',\n  labelMiningRewards: 'Mining Rewards',\n  labelLiquidityValue: 'Liquidity Value',\n  labelCopyAddClip: 'Address Copied to Clipboard!',\n  labelPleaseInputWalletAddress: 'Please input address / ENS / Account ID',\n  labelEmptyDefault: 'No data to display',\n  labelUnlockAccount: 'Unlock Account',\n  labelLockWallet: 'Lock Wallet',\n  labelAssetsDistribution: 'Assets Distribution',\n  labelTotalAssets: 'Assets Trend',\n  labelTxnPageTitle: 'Deposit/Withdraw',\n  labelTradePageTitle: 'Trade History',\n  labelAmmPageTitle: 'AMM Records',\n  labelSwapSuccess: 'Swap successful!',\n  labelOrderProcessing: 'Order Placed!',\n  labelSwapFailed: 'Swap failed!',\n  labelJoinAmmSuccess: 'Successfully joined AMM Pool!',\n  labelJoinAmmFailed: 'Failed to join AMM Pool!',\n  labelExitAmmSuccess: 'Successfully exited the AMM Pool!',\n  labelExitAmmFailed: 'Failed to exit the AMM Pool!',\n  labelConnectBy: 'Connected with <1>{{connectBy}}</1>',\n  labelWrongNetwork: 'Wrong network',\n  labelActivatedAccountDeposit: 'Please deposit to activate your {{layer2}} account',\n  labelActivatedAccountNotSupport: 'Your wallet does not support {{loopringL2}}',\n  labelActivatedAccountNotSupportDes:\n    'Please connect with a different wallet or download the Loopring Wallet mobile app.',\n  labelNotAllowForSmartWalletTitle: 'Apologize',\n  labelProcessing: 'Processing',\n  labelProviderProcessing: 'Connect Wallet with {{name}}...',\n  labelProviderCommonProcessDescribe:\n    'Please click the ‘Approve’ button on the Wallet Extension popup window. If the wallet popup window is dismissed, please manually click <5></5> on your browser toolbar.',\n  labelWalletConnectProcessDescribe: 'Please wait for WalletConnect provider to confirm processing',\n  labelWalletConnectQRCode: 'Please scan the QR code with a WalletConnect compatible application',\n  labelSuccessConnect: 'Successfully Connected with {{providerName}}',\n  labelSuccessConnectDescribe: 'Congratulations, Connection Successful!',\n  labelCopyClipBoard: 'Copy',\n  labelCopyManually: 'Manually Selected & Copy:',\n  labelRejectOrError: 'Request was rejected or some unknown error occurred, please retry',\n  labelWalletConnectProcessDescribe2: 'Please click ‘Approve’ on your device.',\n  labelUnlockProcessing: 'Unlocking {{layer2}}...',\n  labelFailedConnect: 'Connection Failed',\n  labelRejectConnect: 'Connection request was rejected',\n  // labelTokenAccess:'Waiting to approve {{symbol}} access!',\n  labelTokenAccess: 'Waiting for approval',\n  labelFailedTokenAccess: 'Failed to approve {{symbol}} access!',\n  labelNFTTokenFailedAccess: 'Failed to approve NFT access!',\n  labelSuccessTokenAccess: 'Congratulations, you have {{symbol}} access!',\n  labelSuccessUnlockDescribe: 'Congratulations, Successfully Unlocked!',\n  labelSuccessUnlock: 'Unlock Successful!',\n\n  labelActivateAccount: 'Activate Account',\n  labelClose: 'Close',\n  labelRetry: 'Retry',\n  labelTryNext: 'Sign Again',\n  labelQuotePageFavourite: 'Favourites',\n  labelQuotePageAll: 'All',\n  labelQuotePageTradeRanking: 'Tournaments',\n  labelFailedUnlock: 'Unlock Failed',\n  labelFailedUpdateAcc: 'Update Account Failed',\n  labelUpdateAccSigWarning:\n    'Your Wallet does not support current sig function, it will try another one.',\n  labelUpdateAccUserDenied: 'Signature request was rejected!',\n  labelCreateLayer2Title: 'Create {{layer2}} Account',\n  labelCreateAccount: 'Create {{layer2}} Account',\n  labelUpdateAccount: 'Sign in Account',\n  labelTryAnother: 'Try Another Sig Method',\n  labelCancel: 'Cancel',\n  describeTitleNoAccount:\n    \"As {{l1ChainName}}'s first ever zkRollup, Loopring {{layer2}} allows you to avoid costly gas fees and network congestion with the same security as mainnet - 100x cheaper and faster.\",\n  describeTitleOpenAccounting:\n    'Your deposit has been submitted to {{l1ChainName}}.\\n Please wait...',\n  describeTitleOnErrorNetwork:\n    'Your current network is not supported by Loopring!\\n Please change network via {{connectName}}.',\n  describeTitleNotActive:\n    \"As {{l1ChainName}}'s first ever zkRollup, Loopring {{layer2}} allows you to avoid costly gas fees and network congestion with the same security as mainnet - 100x cheaper and faster.\",\n  describeTitleConnectToWallet:\n    \"As {{l1ChainName}}'s first ever zkRollup, Loopring {{layer2}} allows you to avoid costly gas fees and network congestion with the same security as mainnet - 100x cheaper and faster.\",\n  describeWhatIsGuardian: 'What is a Loopring guardian',\n  describeTitleConnectToWalletAsGuardian: 'Connect a wallet to assign it as a guardian!',\n  describeTitleLocked: 'Unlock your account to view your assets.',\n  labelLiquidityPageTitle: 'AMM Pools',\n  labelMinReceive: 'Minimum Received Amount',\n  labelFilter: 'Search',\n  labelMiningPageTitle: 'Loopring Liquidity Mining',\n  labelMiningPageViceTitle: 'Earn rewards for contributing to Loopring liquidity.',\n  labelMiningActiveDate: 'Active Date',\n  labelMiningLiquidity: 'Liquidity',\n  labelMiningActivityReward: 'Activity Reward',\n  labelMiningMyShare: 'My Share',\n  labelMiningMyReward: 'My Reward',\n  labelMiningPlaceOrderBtn: 'Place Order',\n  labelMiningViewDetails: 'View details',\n  labelMiningMaxSpread: 'Max Spread',\n  labelMiningReward: 'Reward',\n  labelCookiesAgree: 'Agree',\n  labelLimitMin: 'Minimum of {{arg}}',\n  labelAmmMinAnd: 'and',\n  labelLimitMinUnknown: 'Order too small',\n  labelLimitMax: 'Maximum of {{arg}}',\n  labelOrderSmall: 'Order too small (>= 100.5LRC)',\n  labelEnterAmount: 'Enter amount',\n  labelAgreeLoopringTxt: 'Allow Loopring to use Cookies.',\n  labelLayer2HistoryTransactions: 'Transfer',\n  labelLayer2HistoryTrades: 'Trades',\n  labelLayer2HistoryAmmRecords: 'AMM Records',\n  labelTxnDetailHeader: 'Transaction',\n  labelDTxnDetailHeader: 'Deposit Record',\n  labelWTxnDetailHeader: 'Withdraw Record',\n  labelTTxnDetailHeader: 'Transfer Record',\n  labelTxnDetailHash: '{{layer2}} Hash',\n  labelTxnDetailHashLv1: 'Eth Hash',\n  labelTxnDetailStatus: 'Status',\n  labelTxnDetailTime: 'Time',\n  labelTxnDetailFrom: 'From',\n  labelTxnDetailTo: 'To',\n  labelTxnDetailAmount: 'Amount',\n  labelTxnDetailFee: 'Fee',\n  labelTxnDetailMemo: 'Memo',\n  labelTxnDetailProcessed: 'PROCESSED',\n  labelTxnDetailProcessing: 'PROCESSING',\n  labelTxnDetailFailed: 'FAILED',\n  labelAgreeConfirm: 'Agree',\n  labelDisAgreeConfirm: 'Disagree',\n  labelImpactAgree: 'Type \"AGREE\" to confirm.',\n  labelImpactTitle: 'Swap Requires Confirmation',\n  labelPriceExtraGreat:\n    'The price you set is {{compare}} than 20% of the market price. Are you sure you want to complete this order?',\n  labelPriceCompareGreat: 'Greater',\n  labelPriceCompareLess: 'Less',\n  labelImpactExtraGreat:\n    'Your transaction amount will affect the pool price by <1>{{value}}</1>. Are you sure you want to swap?',\n  labelCalculating: 'Calculating...',\n  labelFeeCalculating: 'Calculating fee...',\n  labelAmmMyTransactions: 'My Transactions',\n  labelAmmAllTransactions: 'All Transactions',\n  labelWaitForAuth: 'Waiting for signature',\n  labelSignDenied: 'Signature request was rejected',\n  labelFirstSignDenied: \"Your wallet doesn't support this signature method\",\n  labelUpdateAccountSuccess: 'Congratulations!',\n  labelUpdateAccountSuccess2: 'You have successfully sign in your {{loopringL2}} account!',\n  labelResetAccountSuccess: 'Congratulations!',\n  labelResetAccountSuccess2: 'You have successfully reset your {{loopringL2}} account keypair!',\n  labelUpdateAccountSubmit: 'Activating Tx submitted.',\n  labelUnlockAccountSuccess: 'Unlock successful!',\n  labelUnlockAccountFailed: 'Unlock failed!',\n  labelNotSupportTitle: 'Information',\n  labelNotAllowTrade:\n    'Unfortunately we are unable to provide Order and AMM Deposit services due to your IP address as per our Terms of Use.',\n  labelKnown: 'OK',\n  labelResetAccount: 'Reset {{layer2}} Account',\n  labelExportAccount: 'Export Account',\n  labelExportAccountNoPhotos: 'No Photos',\n  labelExportAccountDescription: 'Please keep your API key secure.',\n  labelExportAccountCopy: 'Copy',\n  labelExportAccountSuccess: 'Export Account successful!',\n  labelExportAccountFailed: 'Export Account has failed!',\n  // labelCreateAccountApproveWaitForAuth: 'Waiting for <1>{{symbol}}</1> Approve...',\n  labelCreateAccountApproveDenied: 'Signature request was rejected',\n  labelAmmSwitch: 'switch',\n  labelCreateAccountDepositDenied: 'Signature request was rejected',\n  labelSlippageAlert:\n    'Your slippage tolerance is rather high which could result in less tokens received.',\n  labelOrderGroup: 'Order Records',\n  labelOrderTableOpenOrder: 'Open Order',\n  labelOrderTableOrderHistory: 'Order History',\n  labelResetLayout: 'Reset Layout',\n  labelResetMobileLayout: 'Reset',\n  labelBtnFix: 'reset',\n  labelProSell: 'Sell',\n  labelProBuy: 'Buy',\n  labelProLimit: 'Limit',\n  labelProMarket: 'Market',\n  labelProPrice: 'Price',\n  labelProBaseLabel: 'Amount',\n  labelProQuoteLabel: 'Total',\n  labelProLimitBtn: '{{tradeType}} {{symbol}}',\n  labelProMarketBtn: '{{tradeType}} {{symbol}}',\n  labelProOrderbook: 'Orderbook',\n  labelProTrades: 'Trades',\n\n  labelProToolbar24hChange: '24h Change',\n  labelProToolbar24hHigh: '24h High',\n  labelProToolbar24hLow: '24h Low',\n  labelProToolbar24hBaseVol: '24h Volume({{symbol}})',\n  labelProToolbar24hQuoteVol: '24h Volume({{symbol}})',\n  labelErrorPricePrecisionLimit: '{{symbol}} price only allows {{decimal}} decimals.',\n  labelDepthPrice: 'Price({{symbol}})',\n  labelDepthAmount: 'Accum({{symbol}})',\n  labelDepthTotal: 'Accumulation',\n\n  labelProChartTitle: 'Chart',\n  labelProTimeDefault: 'Time(1m)',\n  labelProTime1m: '1m',\n  labelProTime5m: '5m',\n  labelProTime15m: '15m',\n  labelProTime30m: '30m',\n  labelProTime1H: '1H',\n  labelProTime2H: '2H',\n  labelProTime4H: '4H',\n  labelProTime12H: '12H',\n  labelProTime1D: '1D',\n  labelProTime1W: '1W',\n  labelProTime1M: '1M',\n  labelProChartTradingView: 'Candlestick',\n  labelProChartDepth: 'Depth',\n  labelProOrderPrice: 'Order Price',\n  labelProOrderTotalAmount: 'Accumulative Amount',\n\n  labelSwapCancelled: 'Swap is cancelled.',\n  labelSuccessfully: 'Success',\n  labelWarning: 'Warning',\n  labelFailure: 'Failure',\n  labelPrompt: 'Prompt',\n\n  // labelSwapCancelled: 'Swap is cancelled.',\n  // labelWarning: 'Warning',\n  // labelFailure: 'Failure',\n  // labelPrompt: 'Prompt',\n\n  labelComingSoon: 'Coming Soon',\n  labelTradeProHideOtherPairs: 'Hide other trading pairs',\n  labelCancelAllOrders: 'Confirm cancelling all orders?',\n  labelConfirm: 'Confirm',\n  labelSettingFee: 'Token Order for Fees',\n  descriptionSettingFee:\n    'Change the token priority order to adjust which tokens will be used for fees first.',\n  labelBtnEdit: 'Edit',\n  labelSettingChargeFeeOrder: 'Token Order for Fees',\n  labelDesSettingChargeFeeOrder: '{{loopringL2}} will use this token order when processing fees.',\n  labelReset: 'Reset',\n  labelQueryFeeOK: 'Save',\n  depositLimit:\n    'Limit Orders \\n Used to set the maximum or minimum price \\n at which you are willing to buy or sell.',\n  depositMarket: 'Market Orders \\n Used to buy or sell immediately \\n at the current market price.',\n  labelTransactions: 'Transactions',\n  labelMyRewards: 'My Rewards',\n  labelClearAll: 'Clear All',\n  labelProviderAgree: 'I have read, understand, and agree to the <1> Terms of Service </1>.',\n  labelNFTName: 'Name:',\n  labelNFTDetail: 'Details',\n  labelNFTTokenStandard: 'Token Standard:',\n  labelNFTTokenMinted: 'Token Minted:',\n  labelNFTDescription: 'Description:',\n  labelNFTDate: 'Date:',\n  labelNFTDeployContract: 'Deploy Contract',\n  labelNFTSend: 'Send:',\n  labelNFTDeploy: 'Deploy:',\n  labelNFTDeploying: 'Deploying',\n  labelNFTMyNFT: 'My NFTs - Collection: {{collection}}',\n  labelNFTTokenID: 'ID:',\n  labelNFTTYPE: 'Token Standard:',\n  labelNFTRoyaltyPercentage: 'Royalty (%):',\n  labelNFTID: 'ID:',\n  labelNFTMinter: 'Minter:',\n  labelNFTMetadata: 'Metadata:',\n  labelNFTMint: 'Create NFT',\n  labelNFTCreateCollection: '+ Create Collection',\n  labelNFTTitleMyNFT: 'My NFTs',\n  labelNFTTOTAL: 'Amount:',\n  labelInformation: 'Notification',\n  labelNoticeForProvider:\n    'Loopring currently supports the following wallet connections: {{name}}. Please make sure to use one of these when attempting to connect.',\n  labelIKnow: 'OK',\n  labelYes: 'Yes',\n  labelNo: 'No',\n  labelNoticeForNoMetaNFT:\n    'Your NFT does not contain Metadata or media information. \\n Are you sure you still wish to {{ method }} this NFT?',\n  labelAgreeConfirmNotShowAgain: 'I know & not show again',\n  labelInvalidCID: 'Invalid CID. CIDv0 is start with `Qm`, CIDv1 only works for dag-pb',\n  labelInvalidAddress: 'Invalid address, ENS',\n  labelInvalidisCFAddress: 'Loopring Counterfactual wallet is disabled {{way}} {{token}}',\n  labelInvalidisContract1XAddress: 'Loopring wallet 1.x is disabled {{way}} {{token}}',\n  labelInvalidisContractAddress: '{{way}} of {{token}} to Contract wallet is not available',\n  labelInvalidisLoopringAddress:\n    'This address does not yet have an active {{loopringL2}}, {{way}} of {{token}} is disabled!',\n  labelInvalidisSameAddress: 'Cannot {{way}} to your own address.',\n  labelTradeRaceRanking: 'Trading Leaderboard',\n  labelTradeRaceYourRanking: 'Your ranking',\n  labelTradeRaceGoTrading: 'Go to trade',\n  labelTradeReadRule: 'Read Rules',\n  labelTradeRaceRewards: 'Rewards',\n  labelTradeRaceRules: 'Activity Rules',\n  labelTradeRaceStart: 'Activity ends in:',\n  labelTradeRaceReady: 'Activity starts in:',\n  labelTradeRaceEnd: 'Activity has ended',\n  labelDay: 'Days',\n  labelHours: 'Hours',\n  labelMinutes: 'Minutes',\n  labelSeconds: 'Seconds',\n  labelIsNotFeeToken: 'Please deposit {{symbols}}, or {{lastSymbol}} to activate your {{loopringL2}} account.',\n  labelIsETHDepositAlert: 'Please reserve enough ETH in your account to pay for gas!',\n  labelIsNotEnoughFeeToken:\n    'Please deposit enough token to cover the activation fee: {{fee}} {{symbol}}. Remaining token will appear in your asset after activation',\n  depositNFTAddressLabelPlaceholder: 'please input NFT contract address...',\n  mintNFTAddressLabelPlaceholder:\n    '(CIDv0 or dag-pb CIDv1) eg: QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR',\n  depositNFTIdLabelPlaceholder: 'please input NFT id...',\n  nftDepositDescription:\n    'Creates a smart contract on {{ethereumL1}}, \\n which requires a gas fee. NFTs minted \\nhere remain on {{loopringL2}} until deployed.',\n  labelNFTDescribe: 'Description:',\n  labelNFTTitle: 'Amount',\n  labelNFTDepositInputTitle: 'Amount:',\n  labelNFTTId: 'NFT Token ID:',\n  labelNFTCid: 'IPFS CIDv0 or dag-pb CIDv1:(Store Metadata Information)',\n  labelNFTType: 'Token Standard:',\n  labelNFTAccess: 'Allow Loopring to spend {{symbol}}',\n  labelDeployDenied: 'Signature request was rejected',\n  labelNFTTokenDeployWaitForAuth: 'Allow Loopring to deploy {{symbol}}?',\n  labelDeployFailed: 'Deploy of {{symbol}} has failed!',\n  labelDeploySubmit: 'Deploy of {{symbol}} has been submitted!',\n  labelMint: 'Mint',\n  labelMintDenied: 'Signature request was rejected',\n  labelNFTTokenMintWaitForAuth: 'Allow Loopring to Create {{symbol}}?',\n  labelMintFailed: 'Create of {{symbol}} has failed!',\n  labelMintSuccess: 'Create of {{symbol}} has been submitted!',\n  labelNFTMintBtn: 'Create NFT',\n  labelNFTMintNoMetaBtn: 'Wrong Metadata',\n  labelNFTMintNoMetaDetail:\n    'Your NFT metadata should identify <1>name, image, and royalty_percentage (integer from 0 to 10)</1>.',\n  nftDeployDescription: 'Deploy Collection',\n  nftDeployTitle: 'Deploy Contract',\n  nftMintTitle: 'Create NFT',\n  nftMintBtn: 'Create NFT',\n  labelMintInProgress: 'Processing...',\n  labelNFTDeployBtn: 'Deploy Contract',\n  labelNFTDeployBroker: 'Deploy Broker:',\n  labelDeployInProgress: 'Processing...',\n  labelNFTDeployTitle: 'Deploy Contract',\n  labelVendor: 'Buy with Card',\n  labelLock: 'Lock',\n  labelWalletToWallet:\n    'The connected wallet is a contract address which cannot be used (Except Recover Wallet). If you are connecting a mobile Loopring Smart Wallet, you can protect it and manage guardians within the app.',\n  labelWalletAddAsGuardian: 'Add a guardian',\n  labelWalletInputGuardianCode: 'Input 6 digital Code and Approve',\n  labelWalletScanQRCode: 'Using Loopring Wallet, scan the QR code.',\n  labelWalletInputGuardianCodeDes:\n    'Please contact the owner to obtain the approval code and enter it below.',\n  labelWalletGuardianList: 'Guardian List',\n  labelWalletRequestRecovery: 'Request for Wallet Recovery',\n  labelWalletLoopringSmartWallet:\n    'The connected wallet is a Loopring Smart Wallet. Please use your Loopring Wallet mobile app to add Guardians.',\n  labelWalletNonLoopringSmartWallet:\n    'The connected wallet is a non-Loopring smart contract wallet, which cannot be set as a Guardian. Please try again using a different wallet.',\n  labelWalletGuardianHint:\n    'Easily add other Loopring Wallets as Guardians to secure your identity and crypto assets. After entering the wallet address, the user will receive a notification of the request directly in their Loopring Wallet app. Invite your friends and family to use the Loopring Wallet.',\n  labelWalletLockTitle: 'Lock/unlock Wallet',\n  labelWalletLockDes: 'Who I Protect',\n  labelWalletValidationTitle: 'Approval Requests',\n  labelWalletValidationDes: 'Guardian Request Handling',\n  labelWalletHistoryTitle: 'View History',\n  labelAddProtector: 'add Guardian',\n  labelUnknown: 'Unknown',\n  labelApprove: 'Approve',\n  labelReject: 'Reject',\n  labelWalletApprove: 'Approve Signature',\n  labelCommonList: 'Waiting for your Approve List',\n  labelLogList: 'Log List',\n  labelWalletReject: 'Reject Signature',\n  labelLockAccountSuccess: 'Lock Account Success',\n  labelLockAccountFailed: 'Lock Account Failed',\n  labelApproveSuccess: 'Approve Signature Success',\n  labelApproveFailed: 'Approve Signature Failed',\n  labelRejectSuccess: 'Reject Signature Success',\n  labelRejectFailed: 'Reject Signature Failed',\n  labelYourBalance: 'Your {{layer2}} have: {{balance}}',\n  labelTxGuardianADD_GUARDIAN: 'ADD GUARDIAN',\n  labelTxGuardianGUARDIAN_CONFIRM_ADDITION: 'GUARDIAN CONFIRM ADDITION',\n  labelTxGuardianGUARDIAN_REJECT_ADDITION: 'GUARDIAN REJECT ADDITION',\n  labelTxGuardianGUARDIAN_APPROVE: 'GUARDIAN APPROVE',\n  labelTxGuardianAPPROVE_RECOVER: 'RECOVER WALLET', // RECOVER  16\n  labelTxGuardianAPPROVE_TRANSFER: 'OVER DAILY QUOTA TRANSFER', // APPROVE TRANSFER 18\n  labelTxGuardianAPPROVE_TOKEN_APPROVE: 'TOKEN ACCESS', // 23\n  labelTxGuardianADD_GUARDIAN_WA: 'ADD GUARDIAN', // 34\n  labelTxGuardianREMOVE_GUARDIAN_WA: 'REMOVE GUARDIAN', // 35\n  labelTxGuardianUNLOCK_WALLET_WA: 'UNLOCK WALLET', // 37\n  labelTxGuardianRESET_GUARDIANS_WA: 'RESET GUARDIANS', // 200\n  labelTxGuardianCONTACT_UPDATE_WA: 'RESET GUARDIANS', // 201\n  labelTxGuardianCALL_CONTRACT_WA: 'CALL CONTRACT',\n  labelTxGuardian_recovery: 'recovery wallet',\n  labelTxGuardian_transfer: 'over daily quota transfer',\n  labelTxGuardian_add_guardian: 'add guardian',\n  labelTxGuardian_remove_guardian: 'remove guardian',\n  labelTxGuardian_unlock_wallet: 'unlock wallet',\n  labelTxGuardian_deposit_wallet: 'deposit',\n  labelTxGuardianApprove: 'APPROVE',\n  labelTxGuardianReject: 'REJECT',\n  labelReActiveAccount: 'Re-Activate Account',\n  labelWalletSignType: 'Request for {{type}}',\n  labelSpotTrading: 'Spot Trading Volume (30d in ETH)',\n  labelTradeSpot: 'Trade Spot',\n  labelBuyToken: 'Buy {{token}}',\n  labelCurrentlyLevel: 'Currently {{value}} {{token}}',\n  labelLRCBalance: 'LRC Balance',\n  labelNoticeForForAccountFrozen:\n    'Your wallet’s L2 account is locked. While locked, you can’t perform any L2 operations. If you require further assistance, please send an email to support@loopring.io.',\n  labelAction: 'action',\n  labelGoExplore: 'View transactions on the <1>Loopring Block Explorer</1>.',\n  labelNOETH: 'Need ETH for gas',\n  labelBanxaFeeFree: 'zero fees for a limited time',\n  labellimit: 'limit',\n  labelmarket: 'Market',\n  labelswap: 'Swap',\n  labelamm: 'Amm',\n  labelActiveAccountTitle: 'Activate {{loopringL2}} Account',\n  labelDepositTitle: 'Add Assets from My {{l1Symbol}}',\n  labelDepositTitleAndActive: 'Add Asset from My {{l1Symbol}} & Activate',\n  labelDepositAndActiveBtn: 'Activate {{loopringL2}}',\n  labelDepositTitleActive: 'Activate {{loopringL2}}',\n  depositLabelBtn: 'Receive',\n  labelL2ToL1Title: 'Send to {{l1Symbol}}',\n  labelL2ToMyL1Title: 'Send to My {{l1Symbol}}',\n  labelL2ToOtherL1Title: 'Send to Another {{l1Symbol}}',\n  labelL2ToL1DeployTitle: 'Deploy & Send to {{l1Symbol}}',\n  labelL2toL1EnterToken: 'Select Token',\n  labelSendL1Btn: 'Send',\n  labelSendL1DeployBtn: 'Deploy & Send',\n  labelL2toL1BtnExceed: 'Exceed Max Fast Withdraw amount: {{arg}}!',\n  labelL2toL1BtnExceedWithFee: 'Insufficient balance (with fee)',\n  labelL2toL1Address: '{{l1ChainName}} Address',\n  labelL2toL1MyAddress: 'To my {{l1Symbol}}',\n  labelL2toL1AddressInput: 'Please input the address',\n  labelL2toL1Fee: 'Select payment token',\n  labelL2toL1Fast: 'Fast',\n  labelL2toL1Standard: 'Standard',\n  labelL2toL1LinkRecent: 'Recent withdrawal history',\n  labelL2toL2Title: 'Send to Another {{loopringL2}}',\n  labelL2toL2EnterToken: 'Select Token',\n  transferDescription:\n    'Send assets to any valid {{l1ChainName}} address instantly.\\n Please make sure the recipient address accepts \\n {{loopringL2}} payments before you proceed.',\n  labelL2toL2Btn: 'Send',\n  labelL2toL2Address: 'Recipient',\n  labelL2toL2AddressInput: 'Please input address / ENS / Account ID',\n  labelL2toL2Memo: 'Memo (Optional)',\n  labelL2toL2MemoPlaceholder: 'Please input the memo',\n  labelL2toL2FeeChoose: 'Select payment token',\n  labelL2toL2Fee: 'Network Fee',\n  labelL2toL2FeeNotEnough: 'Insufficient balance',\n  labelL2toL2FeeFastNotAllowEnough: 'Please choose Standard!',\n  labelL2toL2LinkRecent: 'Recent send history',\n  labelL2toL2ExchangeError:\n    'Sending to an Exchange Address {{l2symbol}} account is not supported. {{loopringL2}} accounts cannot be activated on Exchange wallet addresses. Instead, please send to the {{l1Symbol}} account associated with this address.',\n  labelL2toL2SmartWalletError:\n    'This wallet binds with smart contract that does not support {{loopringLayer2}}. You will need to send funds to the {{l1Symbol}} account. ',\n  labelActiveLayer2: 'Activate {{loopringL2}}',\n  labelAddAsset: 'Receive',\n  labelAddAssetBtn: 'Receive',\n  labelSendAsset: 'Send',\n  labelSendAssetBtn: 'Send',\n  labelSend: 'Send',\n  labelReceive: 'Receive',\n  labelWaitingRefer: 'Waiting for approval',\n  labelL1toL2WaitForAuth:\n    'Please confirm to receive {{value}} {{symbol}} to {{to}} {{loopringL2}}.',\n  labelL1toL2Denied: 'You rejected to receive {{value}} {{symbol}}.',\n  labelL1toL2Failed: 'Add asset request of {{value}} {{symbol}} failed!',\n  labelL1toL2Submit: 'Add asset request has been submitted. <1></1>',\n  labelL1toL2NeedApprove: 'Allow Loopring Exchange to spend {{symbol}}',\n  labelL2toL1InProgress: 'Processing...',\n  labelL2toL1Failed: 'Sent {{value}} {{symbol}} to {{l1Symbol}} has failed!',\n  labelL2toL1Success: 'Sent {{value}} {{symbol}} to {{l1Symbol}} was successful!',\n  labelL2toL2InProgress: 'Processing...',\n  labelL2toL2Failed:\n    'Sent {{value}} {{symbol}} from my {{loopringL2}} to another {{loopringL2}} failed!',\n  labelL2toL2Success: 'Sent {{value}} {{symbol}} was successful!',\n  labelUpdateAccountFailed: 'Activate {{loopringL2}} has failed!',\n  labelCreateAccountSubmit:\n    \"Activation of {{loopringL2}} with deposit of {{value}} {{symbol}} has been submitted! \\n Approximately {{count}} minutes remaining...',\",\n  labelCreateAccountFailed:\n    'Activation of {{loopringL2}} with deposit of {{value}} {{symbol}} has failed!',\n  labelL1toL2Hash: 'Recent transactions (From my {{l1Symbol}} to my {{l2Symbol}})',\n  labelL1toL2HashEmpty: 'My {{l1Symbol}} \\u2192 {{loopringL2}} transactions will show up here.',\n  labelL1toL2Record: 'Receive {{value}} {{symbol}}',\n  labelNFTSendL2Btn: 'To Another {{loopringL2}}',\n  labelNFTSendMyL1Btn: 'To My {{l1Symbol}}',\n  labelNFTSendOtherL1Btn: 'To Other {{l1Symbol}}',\n  labelNFTDeploySendMyL1: 'To My {{l1Symbol}} & Deploy Contract',\n  labelNFTDeploySendAnotherL1: 'To another {{l1Symbol}} & Deploy Contract',\n  labelGuid: 'Go to Guide',\n  labelOK: 'Ok',\n  labelL2toL2InvalidAddr: 'Invalid address or ENS',\n  labelL2toL2AddressNotLoopring:\n    '<0></0> This address does not have an activated {{loopringL2}}. Please ensure  the recipient can access {{loopringL2}} before sending.',\n  labelL2toL2AddressType: 'Address Type',\n  labelL2toL2OriginDesc:\n    'Please select the address source. Note: the following trading platforms currently do not support {{loopringL2}}  transfers (Binance, Huobi, Okex…)',\n  labelL2toL2OriginBtnExchange: 'Exchange',\n  labelL2toL2OriginBtnWallet: 'Wallet',\n  labelL2toL2Confirm: 'Confirm',\n  labelL2toL2TokenAmount: 'Token Amount',\n\n  labelActiveAccountFeeNotEnough: 'Insufficient balance <1>Add assets</1>',\n  labelNFTTransferTX: '{{l2Symbol}} \\u2192 {{l2Symbol}}',\n  labelNFTWithdrawTX: '{{l2Symbol}} \\u2192 {{l1Symbol}}',\n  labelNFTDepositTX: '{{l1Symbol}} \\u2192 {{l2Symbol}}',\n  labelNFTDeposit: 'Receive {{loopringL2}} NFT',\n  labelNFTDepositNeedApprove: 'Allow Loopring to spend {{symbol}} and deposit it?',\n  labelNFTDepositBtn: 'Receive NFT',\n  labelNFTDepositTitle: 'Receive NFT from my {{l1Symbol}}',\n  labelNFTContractAddress: 'Contract:',\n  labelNFTAmount: 'Amount:',\n  labelNFTTokenDepositWaitForAuth: 'Please confirm to send {{loopringL2}} {{symbol}}',\n  nftMintDescription:\n    'Paste in the CID that you obtained from uploading \\n the metadata.json file (point 11 above) - if successful,\\n the data from the metadata.json file you created contained\\n within the folder will populate the Name\\n and Image below.',\n  labelNFTMintInputTitle: 'Amount <1>\\uFE61</1>',\n  labelL1toL2Vendor:\n    'Use a Loopring partner to deposit funds.\\nOnce your order is confirmed by Loopring,\\n it will be added to your balance within 2 minutes.',\n  depositLabelTo: 'To address, Account ID or ENS.',\n  labelAddressNotLoopring: \"Account doesn't have an active {{loopringL2}}\",\n  labelMINTNFTTitle: 'Create NFT (ERC1155)',\n  labelIPFSUploadTitle: 'Preview Image (Dimensions: 1:1) <1>\\uFE61</1><2>\\u2139</2>',\n  labelIPFSUploadTooltips:\n    'The file uploaded here will be used as the cover image when displaying NFT item.',\n  labelIPFSUploadMediaTitle: 'Multimedia Content (image, audio, video and 3D)<1>\\u2139</1>',\n  labelIPFSUploadMediaTooltips:\n    'If no file is uploaded here, it will use the same content as “Preview Image”.',\n  labelLoadDes: 'Drag or click to upload files ({{types}}, max size:  {{size}}MB)',\n  labelUpload: 'upload',\n  labelMintNoImageBtn: 'Please upload image',\n  labelMintUserAgree: 'Please agree to the terms of service',\n  labelMintTradeValueBtn: 'Please input amount(1 - 10,000)',\n  labelMintNoRoyaltyPercentageBtn: 'Please input Royalty',\n  labelMintWrongRoyaltyBtn: 'Royalty should be (0 - 10)',\n  labelMintNoNameBtn: 'Please input name',\n  labelNFTMetaBtn: 'Upload metadata & create',\n  labelMintName: 'Name <1>\\uFE61</1>',\n  labelMintCollection: 'Choose Collection <1>{{required}}</1><2></2>',\n  labelMintCollectionTooltips: 'This is the collection where your NFT will appear.',\n  labelMintRoyaltyPercentage: 'Royalty (%) <1>\\uFE61</1><2>\\u2139</2>',\n  labelMintRoyaltyPercentageRange: 'Max Int:',\n  labelMintRoyaltyPercentageTooltips:\n    'Represents the percentage to be received from each subsequent resale (max 10%).',\n  labelMintDescription: 'Description <1>\\u2139</1>',\n  labelMintDescriptionTooltips:\n    \"The description will be included on the NFT's detail page beneath it's image.\",\n  labelMintProperty: 'Properties (Limit 64) <1>\\u2139</1>',\n  labelMintPropertyTooltips: 'Tags can be added to the NFT for easy searchability and distinction',\n  labelPropertyAdd: 'Add property',\n  labelMintNFT: 'Create NFT',\n  labelL1toL2NFT: 'Receive NFT',\n  labelMyAssetsNFT: 'My NFTs',\n  labelTransactionNFT: 'Transactions',\n  labelMintPropertyKey: 'Key',\n  labelMintPropertyValue: 'Value',\n  labelNFTProperty: 'Properties:',\n  labelConfirmMint: 'Confirm Metadata',\n  labelUseIpfsMintAgree:\n    'I confirm that the NFT minted does not infringe on copyright laws or contain illegal, explicit, sensitive, adult themed, or any other content considered NSFW. We reserve the right to hide inappropriate content if an NFT is discovered to be harmful.',\n  labelL1toL2TitleBridge: 'Add {{loopringL2}} Assets',\n  labelL1toL2TitleBridgeNoConnect:\n    'Connect your {{ethereumL1}} Wallet to transfer assets to any {{loopringL2}} account',\n  labelPayer: 'My Wallet:',\n  labelL1toL2TokenAmount: 'Token Amount',\n  labelL1toL2From: 'From',\n  labelL1toL2TO: 'To {{loopringL2}}',\n  labelAddAssetTitle: 'Add {{loopringL2}} {{symbol}} assets',\n  labelSendAssetTitle: 'Send {{loopringL2}} {{symbol}} assets',\n  labelAddAssetHowto: 'How would you like to add {{loopringL2}} assets?',\n  labelAddAssetTitleActive: 'Add assets & Activate',\n  labelFromMyL1: 'From my {{l1Symbol}} account',\n  labelFromOtherL1: 'From another {{l1Symbol}} account',\n  labelBuyWithCard: 'On-Ramp From Fiat',\n  labelFromOtherL2: 'From another {{loopringL2}} account',\n  labelFromExchange: 'From an exchange',\n  labelOpenInWalletApp: 'Open in wallet app/extension',\n  labelConnectWithDapp: 'Connect with Dapp',\n  labelOpenInWalletTitle: 'Open in wallet',\n  labelOpenInWalletDetail: `URL for adding funds has been copied. You can choose either way to continue:`,\n  labelOpenInWalletDetailLi1: `Open your wallet app and paste the URL into its internal Dapp browser`,\n  labelOpenInWalletDetailLi2: `Open your desktop Chrome browser and paste the URL in Chrome`,\n  labelActiveL2Btn: 'Activate {{loopringL2}}',\n  labelWrongNetworkGuideTitle: 'Wrong Network',\n  labelWrongNetworkGuide:\n    'Your chosen network is not currently supported on Loopring. Please choose {{l1ChainName}} main Network or test Network Goerli',\n  labelSenAssetTitle: 'Send {{symbol}} from {{loopringL2}}',\n  labelSendTOL2: 'To another {{loopringL2}} account',\n  labelSendToMyL1: 'To my {{l1Symbol}} account',\n  labelSendToOtherL1: 'To another {{l1Symbol}} account \\n(incl. exchange)',\n  labelSendAssetHowto: 'Where would you like to send your crypto to',\n  labelL1toL2: 'Add {{loopringL2}} assets From My {{l1Symbol}}',\n  labelActivatedAccountChargeFeeList:\n    'Please make sure one of the below tokens with the minimum quantity in your {{loopringL2}} account to proceed',\n  labelReceiveAddress: 'Receive Address',\n  labelAssets: '{{loopringL2}} Assets',\n  labelReceiveAddressGuide:\n    'Please use a {{loopringL2}} account when transferring to avoid loss of assets ({{symbol}}).',\n  labelL2toL2: 'Send to another {{loopringL2}}',\n  labelL2toL1: 'Send to {{l1Symbol}}',\n  labelBenefitL2:\n    \"As {{l1ChainName}}'s first ever zkRollup, {{loopringL2}} allows you to avoid costly gas fees and network congestion with the same security as mainnet - 100x cheaper and faster.\\n\\nActivating your {{loopringL2}} account requires a small payment fee. \",\n  labelNotBalancePayForActive: 'Insufficient balance in your {{loopringL2}} account',\n  labelEnoughBalancePayForActive: 'You have enough balance to pay for {{loopringL2}} creation.',\n  labelHaveInProcessingL1toL2:\n    'If you have already started the deposit, please be patient and recheck as transactions on {{l1ChainName}} can take up to 30 minutes.',\n  labelWaitingL1toL2: 'Please wait',\n  labelAddAssetGateBtn: 'Add assets',\n  labelActiveLayer2Btn: 'Activate {{loopringL2}}',\n  labelActiveLayer2PayBtn: 'Pay Activation Fee',\n  labelBalanceActiveAccountFee:\n    '{{symbol}}: <2>Fee {{fee}};</2><3>My {{loopringL2}} balance: {{count}}</3>',\n  labelToAddressShouldLoopring: 'To address is no {{loopringL2}}',\n  labelBridgeSendTo: 'Send to (address, Account ID or ENS)',\n  labelInvalidAddressClick:\n    'Invalid Wallet Address, {{way}} of {{token}} is disabled! <1>Click to input another receive address </1>',\n  labelENSShouldConnect: 'Receive address is an ENS, please connect wallet to check real address',\n  labelToken: 'Token',\n  labelMinRequirement: 'Min Requirement',\n  labelAvailability: 'Availability',\n  labelWhatProvider: 'Which provider would you like to use?',\n  labelMemo: 'Memo',\n  labelAdvanceMint: 'Advance Create NFT',\n  labelWalletTypeDes:\n    'Please confirm the address type again to ensure the assets are not mistakenly sent to the exchange address. ',\n  labelWalletTypeOptions: '{{type}} Wallet',\n  labelWalletTypeOtherSmart: 'Other Smart',\n  labelWalletTypeLoopring: 'Loopring',\n  labelWalletTypeEOA: 'EOA',\n  labelWalletTypeExchange: 'Exchange',\n  labelEOADes:\n    'There is no smart contract binds with this wallet address. (e.g. MetaMask, imtoken, Ledger, Trezor, etc....) ',\n  labelLoopringDes:\n    'This wallet is created using Loopring Wallet mobile app and binds with Loopring smart contract.',\n  labelOtherSmartDes:\n    'This wallet binds with smart contract that does not support {{loopringLayer2}}. You will need to send funds to the {{l1Symbol}} account. ',\n  labelExchangeDes:\n    'The following trading platforms currently do not support {{loopringL2}} transfers (Binance, Coinbase, etc...). You will need to send funds to the {{l1Symbol}} account. ',\n  labelExchangeTypeDes: 'Please select the address source:',\n  labelNonExchangeTypeDes:\n    'eg: Loopring Wallet, Metamask, Coinbase Wallet, imtoken, Ledger, Trezor... EOA wallet',\n  labelNonExchangeType: 'Non-Exchange Wallet',\n  labelExchangeType: 'Exchange',\n  labelExchangeBinance: 'Binance',\n  labelExchangeBinanceDes: '',\n  labelExchangeHuobi: 'Huobi',\n  labelExchangeHuobiDes: 'Transactions need to wait 24 hours',\n  labelExchangeCoinbase: 'Coinbase',\n  labelExchangeOthers: 'Other Exchanges',\n  labelExchangeOthersDes: '',\n  labelL2toL1AddressType: 'Address Type',\n  labelConfirmBtrade: 'Confirm CEX Support',\n  labelConfirmDetail:\n    '<0>Before withdrawing, please confirm with your CEX support that they accept deposits from smart contracts.</0>' +\n    '<1>{{l2Symbol}} to {{l1Symbol}} withdrawing is performed via a smart contract. The CEX depositing address may not be able to automatically acknowledge the deposit.</1>' +\n    '<2>If the deposit does not appear at the CEX address within 24 hours, please contact your CEX support and ask they manually acknowledge the transaction.</2>',\n  labelBtradeUnderstand: 'I understand and acknowledge the risk',\n  labelMintFee: 'Create Fee',\n  labelMintFeeNotEnough: 'Insufficient balance',\n  labelMintFeeChoose: 'Select payment token',\n  labelLayerSwapUnderstand: 'I understand and acknowledge the risk',\n  labelIUnderStand: 'I Understand',\n  labelLayerSwapUnderstandDes:\n    'LayerSwap is a 3rd party App service provider to help move tokens from exchange to {{loopringL2}} directly. If you have any concerns regarding their service, please check out their <1>TOS</1>.',\n  labelInvestAmmTitle: 'AMM Pools',\n  labelInvestBalanceTitle: 'My Investments',\n  labelInvestDualRefreshErrorTitle: 'Subscription Failed',\n  labelInvestDualRefreshError: 'The subscription of {{token1}}/{{token2}} Dual Investment failed.',\n  labelTransactionsLink: 'Transactions',\n  labelAMMTransactionsLink: 'View Pool Transactions',\n  labelNFTMintWrongCIDBtn: 'Wrong MetaData format',\n  labelWithdrawBtn: 'Withdraw',\n  labelFWithdrawFee: 'Fee',\n  labelFWithdrawNotEnough: 'Insufficient balance',\n  labelForceWithdrawTitle: 'Force Withdraw',\n  labelForceWithdrawWaitForAuth: 'Please confirm to force withdraw {{symbol}}',\n  labelForceWithdrawDenied: 'You rejected to force withdraw {{symbol}}.',\n  labelForceWithdrawInProgress: 'Processing...',\n  labelForceWithdrawFailed: 'Force withdraw has failed!',\n  labelForceWithdrawSubmit: 'Force withdraw has been submitted',\n  labelForceWithdrawToken: 'Token Amount',\n  labelForceWithdrawFee: 'Network Fee',\n  labelForceWithdrawEnterToken: 'Select Token',\n  labelPleaseForceWithdrawAddress: 'Please enter the address you wish to withdraw from',\n  labelForceWithdrawAddress: 'The address you wish to withdraw from',\n  labelForceWithdrawDes:\n    \"If the recipient doesn't have an active {{loopringL2}} account, you will be able to withdraw the token from {{l2Symbol}} to {{l1ChainName}} {{l1Symbol}}. This process is usually only needed when tokens were sent to a CEX address using {{loopringL2}}. Since the CEX does not have access to the {{l2Symbol}} account, you will need to perform this action to reclaim the tokens.\",\n  labelForceWithdrawConfirm:\n    'This feature allows a user to move their {{l2Symbol}} tokens to the {{l1Symbol}} address. The target address must either be a wallet or exchange address',\n  labelForceWithdrawConfirm1:\n    'This operation usually requires more than 30 minutes to take effect, as it needs to interact with {{l1ChainName}} Mainnet. Please be patient.',\n  labelNFTSendBtn: 'Send',\n  labelNFTProperties: 'Properties',\n  labelNFTDescription2: 'Description',\n  labelForceWithdrawNotAvailable:\n    '{{loopringL2}} account is activated in this address. For security reason, Loopring would not allow other user to force withdraw token from its {{l2Symbol}} to {{l1symbol}} anymore',\n  labelForceWithdrawNoToken: 'No token is detected from this address to operate',\n  labelForceWithdrawBtn: 'Force Withdraw',\n  labelInvestDefiTitle: 'ETH Staking',\n  labelInvestDefDeposit: 'Subscribe',\n  labelInvestDefWithdraw: 'Redeem',\n  labelNFTDepositLabel: 'Receive NFT',\n  labelDefiFee: 'Fee',\n  labelDefiMin: 'Minimum of {{arg}}',\n  labelDefiNoEnough: 'Insufficient balance',\n  labelDefiMaxBalance:\n    'It is not possible for the Loopring pool to fulfil your complete request at the moment. You can only redeem {{maxValue}} now.\\n' +\n    'You can choose one of the following approaches for the remaining amount:',\n  labelDefiMaxBalance1:\n    '<li>Withdraw {{symbol}} to {{l1Symbol}} and trade through 1Inch or {{type}}, etc...</li>' +\n    '<li>The Loopring pool will rebalance soon. Please come back later to redeem.</li>',\n  labelDefiNoBalance:\n    '<span>It is not possible for the Loopring pool to fulfil your complete request at the moment.</span>' +\n    '<span>You can choose one of the following approaches for the remaining amount:</span>',\n  labelDefiNoBalanceList:\n    '<li>Withdraw {{symbol}} to {{l1Symbol}} and trade through 1Inch or {{type}}, etc...</li>' +\n    '<li>The Loopring pool will rebalance soon. Please come back later to redeem.</li>',\n  labelDefiMaxBalanceJoin:\n    \"The quota is almost sold out and can't fulfil your complete order. You can only subscribe {{maxValue}} now. Loopring will setup the pool soon, please revisit for subscription later. \",\n  labelDefiNoBalanceJoin:\n    'Loopring will set up the pool soon. Please come back later to subscribe.',\n  labelInvestBtn: 'Subscribe',\n  labelRedeemBtn: 'Redeem',\n  labelVipTitle: 'VIP',\n  labelSecurity: 'Security',\n  labelFeeTitleList: 'Fee',\n  labelInvestOverviewTitle: 'Overview',\n  labelTitleOverviewToken: 'Total Investment Tokens',\n  labelInvestType_AMM: 'AMM Pools',\n  labelInvestType_STAKE: 'ETH Staking',\n  labelInvestType_DUAL: 'Dual Investment',\n  labelInvestType_STAKELRC: 'LRC Staking',\n  labelInvestAll: 'Mixed',\n  labelInvestFlexible: 'Flexible',\n  labelInvestDuration: 'Duration',\n  labelDefiOrderTable: 'ETH Staking',\n  labelTitleMyInvestAvailable: 'My Holding Tokens',\n  labelViewMore: 'View more',\n  labelInvestSuccess: 'Successfully {{type}} {{symbol}}',\n  labelInvestFailed: 'Subscribe Failed',\n  labelWSETHDefiRiskTitle: 'What is ETH Staking via Lido?',\n  labelRETHDefiRiskTitle: 'What is ETH Staking via Rocket Pool?',\n  labelWSETHDefiRisk:\n    '<p>Lido is a liquid staking solution for ETH 2.0 backed by industry-leading staking providers. Lido lets users stake their ETH - without locking assets or maintaining infrastructure.</p>' +\n    '<p>When using Lido to stake your ETH on the {{l1ChainName}} beacon chain, users will receive a token (stETH), which represents their ETH on the {{l1ChainName}} beacon chain on a 1:1 basis. It effectively acts as a bridge bringing ETH 2.0’s staking rewards to ETH 1.0.</p>' +\n    \"<p>wstETH is the wrapped version of stETH. The total amount of wstETH doesn't change after users receive the token. Instead, the token’s value increase over time to reflect ETH staking rewards earned.</p>\",\n  labelRETHDefiRisk:\n    '<p>Rocket Pool is the first truly decentralized {{l1ChainName}} staking pool. Rocket Pool’s liquid staking token allows anyone to earn staking rewards easily without running staking software or locking assets. Rocket Pool handles all of the {{l1ChainName}} validator operations with smart contracts on the Execution layer.</p>' +\n    \"<p>Acquiring and holding rETH in your wallet means that you are staking ETH. rETH's value continuously increases relative to ETH, indicating the daily stake reward received.</p>\" +\n    '<p></p>',\n  labelWSETHDefiRisk2:\n    \"<0>It is important to note that users can't redeem wstETH for ETH until phase 2 of {{l1ChainName}} 2.0. However, users are able to trade wstETH for ETH on various exchanges at market prices.</p>\" +\n    '<1>Loopring will provide a pool to allow users to trade wstETH for ETH directly on {{layer2}}. The pool will rebalance periodically when it reaches a specific threshold. If there is not enough inventory on {{layer2}}, user can always withdraw their wstETH tokens to Layer 1 and swap for ETH in Lido, Curve, or 1inch.</p>',\n  labelRETHDefiRisk2:\n    '<0>Loopring will provide a pool to allow users to trade rETH for ETH directly on {{layer2}}. The pool will rebalance periodically when it reaches a specific threshold. If there is not enough inventory on {{layer2}}, users can always withdraw their rETH tokens to Layer 1 and swap for ETH in Rocket Pool, 1Inch, etc… </0>' +\n    '<1></1>',\n  labelDefiAgree: 'I have read and understand the risk warning.',\n\n  labelDefiInvest: 'Defi Earn',\n  labelLRCStakingInvest: 'LRC staking',\n  labelLRCStakingRedeemInvest: 'LRC staking Redeem',\n\n  labelDefiClose:\n    'This service is temporarily unavailable as we set up the pool. This process may take several hours to complete. Thank you for your patience!',\n  labelCreateCollection: 'Create Collection',\n  labelCollectionCreateName: 'Contract address for your collection',\n  labelCollectionCreateERC1155: 'Collection ERC-1155',\n  labelCollectionCreateWaiting: 'Waiting for create Collection token Address',\n  labelMintSelect: 'Choose Creation Method',\n  labelMintSelectDes: 'Choose the most suitable approach for your needs.',\n  labelCollectionCreateFailed: 'Create Collection token Address Failed',\n  labelCollectionMetaTitle: 'Import Metadata from IPFS',\n  labelAdvanceCreateCollection: 'Advance Create Collection',\n  labelCreateCollectionSuccess: 'Collection create was successful',\n  labelCreateCollectionFailed: 'Collection create has failed',\n  labelCollectionAdvanceJSON: 'NFT Collection information follow this format: ',\n  labelCopyDemo: 'Click to copy the demo',\n  labelCollectionCreatBtn: 'Create Collection',\n  labelEnterMeta: 'Enter Collection Metadata',\n  labelMintGuid:\n    'Fill up content in GUI and let Loopring to generate necessary metadata and upload to IPFS for you, then use \"Mint\" to create your NFT.',\n  labelAdMintGuid:\n    'Generate all the required metadata and upload to IPFS by yourself first, then use \"Advanced Create NFT\" to create your NFT.',\n  labelFilterTradeNFTSell: 'Sell',\n  labelFilterTradeNFTSelf: 'Self Trade',\n  labelFilterTradeNFTBuy: 'Buy',\n  labelAdMintTitle: 'Advance Create NFT',\n  labelCopyNFTDemo: 'Copy NFT Demo',\n  labelSelectCollection: 'Choose or Create a Collection to Create Your Own NFT',\n  labelSelectCollectionDes: 'A NFT Collection can help you manage and group your NFTs',\n  labelChooseCollectionBtn: 'Choose a Collection to Create NFT',\n  labelNFTMint721Btn: 'ERC721 will coming soon',\n  labelADMint1: 'Prepare NFT metadata',\n  labelADMint2: 'Fill in the IPFS CID',\n  labelADMint3: 'Preview & Create NFT',\n  labelADMintSelect: 'Prepare NFT metadata with proper collection_metadata value',\n  labelHasData: 'Has generated metadata with collection_metadata field',\n  labelNoData: 'Hasn’t generated metadata with collection_metadata field',\n  labelChooseCollection: 'Choose a collection',\n  labelBanner: 'Banner (Dimensions: 3:1)',\n  labelBannerDes: 'Drag or click to upload files ({{types}}, max size:  {{size}}MB)',\n  labelAvatar: 'Avatar (Dimensions: 1:1)',\n  labelAvatarDes: 'Max size: {{size}}MB)',\n  labelTileUri: 'Tile (Dimensions: 5:7) <1>\\uFE61</1>',\n  labelTileUriDes: 'Drag or click to upload files ({{types}}, max size:  {{size}}MB)',\n  labelCollectionDescription: 'Description <1>\\u2139</1>',\n  labelCollectionDescriptionTooltips:\n    'You can describe your collection here. 0 of 1000 characters used',\n  labelCollectionName: 'Collection Name <1>\\uFE61</1>',\n  labelCollectionCreateBtn: 'Create Collection',\n  labelCollectionRequiredName: 'Please input Name',\n  labelCollectionRequiredTileUri: 'Please input tile',\n  labelCollectionIsUploading: 'Source is loading',\n  labelMintNext: 'Next',\n  labelMintCollectionInput: 'Please input contract address',\n  labelMintCid: 'Please input IPFS CID',\n  labelMintBack: 'Back',\n  labelTokenAdMintBtn: 'Enter Amount',\n  labelMintSubmitBtn: 'Create Your NFT',\n  labelMintIPFSCIDDes: 'Fill in the IPFS CID for NFT metadata',\n  labelNFTMintSimpleBtn: 'Create NFT',\n  labelCollectionEditBtn: 'Edit Collection',\n  labelCopyMetaClip: 'Metadata Copied to Clipboard',\n  labelCollectionMetaNoNameORTileUri:\n    'Your Collection metadata is not setup {{type}}, please go to collection panel edit!',\n  labelCollectionMetaMiss: 'Your NFT metadata is no not setup {{type}}.',\n  labelCollectionMetaError:\n    'Your NFT metadata is no not setup {{type}}, please check and fix it from your IPFS site',\n  labelCollectionMetaErrorType: 'correct `royalty_percentage` from 0 to 10',\n  labelNFTServerRefresh:\n    \"Click to refresh the NFT's metadata. This process usually takes around 30 minutes.\",\n  labelNFTServerRefreshSubmit: 'Refresh command submitted',\n  labelNFTCollection: 'Collection',\n  labelNFTCollectionName: 'Collection Name:',\n  labelMyCollection: 'My Collections',\n  labelCounterFactualNFT: '{{l2Symbol}} NFT:',\n  labelCopyUrlClip: 'URL Copied to Clipboard!',\n  labelCollectionMetaData: 'Collection MetaData',\n  labelViewEtherscan: 'Etherscan',\n  labelNFTMyNFTCollection: 'View by Collection',\n  labelNFTMyNFTList: 'View by item',\n  labelNoCollectionCover: 'No Cover Media',\n  labelNoNFTCover: 'No Media Resource',\n  labelNFTAmountValue: 'Amount: {{value}}',\n  labelNFTAmountSimpleValue: ' \\u2A09 {{value}}',\n  labelCollectionItemValue: 'Item: {{value}}',\n  labelCollectionItemSimpleValue: ' \\u2A09 {{value}}',\n  labelMyCollectionsDes:\n    \"Legacy NFTs created in Loopring don't contain collection information. We have added the feature to allow creators to import the collection information so that those NFTs can be categorized well. <1>Go to Import Collection for Legacy NFT</1>\",\n  labelNFTGuid:\n    'Please fill in the appropriate collection metadata field value in your NFT metadata with this string first, then upload it to IPFS to retrieve the CID to continue. <1>view more </1>',\n  labelChooseCollectionTooltips:\n    'This is the collection where your NFT will appear. \\n Note: NFT minted under collection will be bound with different contract address than previous created one. If you have incomplete work to finish and would like them created under previous contract address, you can still use the legacy creation method under <1>https://legacy-nft.loopring.io/</1>.',\n  labelMintPreview: 'Back',\n  labelMintNoCollectionBtn: 'Please Choose Collection',\n  labelInvestDualTitle: 'Dual Investment',\n  labelBuy: 'Buy',\n  labelSell: 'Sell',\n  labelRampNoBalance: 'Insufficient {{belong}} balance',\n  labelBanxaNoBalance: 'Insufficient {{belong}} balance',\n  labelBanxaFeeNoBalance: 'Insufficient {{belong}} balance & fee',\n  labelL2toRampTitle: 'Send to Ramp',\n  labelL2toBanxaTitle: 'Send to Banxa',\n\n  labelDualInvest: 'Invest {{symbol}}',\n  labelDualBase: 'Sell High for {{symbol}}',\n  labelDualQuote: 'Buy {{symbol}} Low',\n  labelDualAgree: 'I have read and understand the risk warning.',\n  labelDualRiskTitle: 'Dual Investment',\n  labelDualInvestBaseTitle: 'Invest {{symbolA}} (Sell High for {{symbolB}})',\n  labelDualInvestQuoteTitle: 'Invest {{symbolA}} (Buy {{symbolB}} Low)',\n  labelDualInvestDes: 'Invest {{symbolA}} to earn more {{symbolA}} or {{symbolB}}',\n  labelDualCurrentPriceTip:\n    'Current Price is based on {{symbol}} derived from some leading exchanges.',\n  labelDualCurrentPrice: '{{symbol}} Current Price:<1>{{price}}</1> {{baseSymbol}}',\n  labelDualCurrentPrice2: 'Current Price:\\n <1>{{price}}</1> {{baseSymbol}}',\n\n  labelDualSuccess: 'Subscription {{symbol}} Successfully',\n  labelDualProcessing: 'Waiting for completion',\n  labelDualProcessingDes:\n    'We will try to fulfill your subscription request within minutes. If your subscription cannot be fully completed within the time frame, the unfilled portion will be unlocked. You can return later to resubscribe.',\n  labelDualFailed: 'Subscribe Failed',\n  labelDualFee: 'Fee',\n  labelDualMin: 'Minimum of {{arg}}',\n  labelDualMax: 'Maximum of {{arg}}',\n  labelDualNoEnough: 'Insufficient balance',\n  labelDualSettleDate: 'Settlement Date',\n  labelDualSubDate: 'Subscription Date',\n  // labelDualCurrentPrice2: '{{symbol}} Current Price',\n  // labelDualCurrentPrice3: '{{symbol}} current Price',\n  labelDualCurrentAPR: 'APR <1>\\u2139</1>',\n  labelDualCurrentAPRDes:\n    'APR is refreshed in real time. We will use the lastest APR at the time you complete the subscription successfully.',\n  labelDualTargetPrice2: 'Target Price <1>\\u2139</1>',\n  labelDualTargetPrice3: 'Target Price',\n\n  labelDualTargetPriceDes:\n    'Target Price is a benchmark price based on USDT. On Settlement Date, the Settlement Price will be compared against this benchmark price.',\n  labelDualRiskDes:\n    'Your investment will be locked up until settlement date after investing and cannot be redeemed before settlement. \\n As we make profit ratio a top priority, the total opened position might vary with your initial investment.',\n  labelDualReturn: 'Return \\n {{symbol}}',\n  labelDualReceive: 'Settlement Calculator',\n  labelDualCalcLabel: 'If {{symbol}} {{tag}} {{target}}',\n  labelDualReturnValue: 'Return {{value}} {{symbol}}',\n  labelDualQuota: 'Total Quota',\n  labelProduct: 'Product',\n  labelDualAssetFrozen_Target: 'Invest Target',\n  labelDualAssetPrice: 'Price',\n  labelDualAssetSettlement_Date: 'SettlementDate',\n  labelDualAssetAPR: 'APR',\n  labelDualAssetAction: 'Detail',\n  labelInvestDualTutorial: 'Tutorial',\n  labelInvestDualTutorialContent:\n    'Dual Investment offers you a chance to sell cryptocurrency high or buy cryptocurrency low at your desired price on your desired date. Once subscribed, users are not able to cancel or redeem the subscription until the Settlement Date.\\n You may be better off holding your cryptocurrency, and may be required to trade your cryptocurrency at a less favorable rate of exchange than the market rate on Settlement Date. Cryptocurrency trading is subject to high market risk. Please make your trades cautiously. There may be no recourse for any losses.',\n  labelInvestDualTutorialCheck1:\n    'I understand that Dual Investment is NOT a principal-guaranteed products.',\n  labelInvestDualTutorialCheck2:\n    'I understand that subscribed assets are locked and users aren’t able to cancel or redeem before the Settlement Date.',\n  labelInvestDualTutorialCheck3:\n    'I understand that I should review the possible scenarios of settlement amount and confirmed the subscription details.',\n  labelInvestDualTutorialCheck4:\n    'Please be aware that the target price in Dual Investment portfolio is USDT. If you subscribe USDC-related product with another token, that token may be converted to USDC if the target price is reached. If you want to completely avoid the USDC depegging risk, you can select USDT-related products instead.',\n  labelInvestDualTutorialCheck5: 'I have read and understand the risk warning.',\n  labelInvestDualBeginerMode: 'Beginner Mode',\n  labelInvestDualBeginerModeDesLine1: 'What is Dual Investment?',\n  labelInvestDualBeginerModeDesLine2: 'You can use the beginner mode to quickly learn.',\n  labelDualAmount: 'Amount',\n  labelDuaInvestmentDetails: 'Dual Investment Details',\n  labelDualOrderTable: 'Dual Investments',\n\n  labelDualBeginnerPriceSmallerThan: 'if Index Price < {{value}}',\n  labelDualBeginnerPriceSmallerThanOrEqual: 'if Index Price ≤ {{value}}',\n  labelDualBeginnerPriceGreaterThan: 'if Index Price > {{value}}',\n  labelDualBeginnerPriceGreaterThanOrEqual: 'if Index Price ≥ {{value}}',\n\n  labelDualBeginnerAtSettlementDay: 'At Settlement Date',\n  labelDualBeginnerIndexPriceDes: 'Index Price is derived from some leading exchanges.',\n  labelDualBeginnerLockingDes: 'Your token for investment will be locked until Settlement Date.',\n  labelDualBeginnerAPR: 'APR: {{APR}}',\n  labelDualBeginnerStep1Title: 'Step 1: Choose a token to sell or buy',\n  labelDualBeginnerStep2Title: 'Step 2: Choose to sell or buy at desired price in the future',\n  labelDualBeginnerSellHigh: 'Sell {{token}} High',\n  labelDualBeginnerBuyLow: 'Buy {{token}} Low',\n  labelDualBeginnerReceiveStable: 'You will receive {{list}} {{last}}',\n  labelDualBeginnerInvestStable: 'You can invest {{list}} {{last}}',\n  labelDualBeginnerLast: 'or {{last}}',\n  labelDualBeginnerStep3Title: 'Step 3: Choose Target Price and Settlement Date',\n  labelDualBeginnerSellHighFor: 'Sell high for {{token}}',\n  labelDualBeginnerBuyLowWith: 'Buy low with {{token}}',\n\n  labelInvestMyAmm: 'My Investments',\n  labelInvestMyDual: 'My Investments',\n  labelInvestMyDefi: 'My Investments',\n  labelInvestMaxDual: 'Max {{value}}',\n  labelDualTitle: 'Dual Investment',\n  labelDualDesSuccess:\n    'Your token for investment is just locked but still in your account as Loopring is a DEX. \\n When the transaction expires, if the settlement price is not reached, you will get a profit and the frozen token will also be unlocked; if the settlement price is reached, your investment and interest income will be converted into the target token at the Target price.',\n  labelDualRefresh: 'Refresh',\n  labelNoticeForMarketFrozen:\n    '{{ type }} is not supported, If you believe this is indeed a bug, please contact us.',\n  labelInvestRangeDay: '{{arg}} Days',\n  labelAmmExit: 'Redeem',\n  labelAmmJoin: 'Subscribe',\n  labelDualPanelClose: 'Go to My Investments',\n  labelDualMobilePrice: '{{symbol}} price:',\n  labelEditCollectionSuccess: 'Collection edit was successful',\n  labelEditCollectionFailed: 'Collection edit has failed',\n  labelEditCollectionBtn: 'Edit',\n  labelEditRestCollectionBtn: 'Reset',\n  labelEditCollectionERC1155: 'Edit My Collection',\n  labelDualSettlementCalculator: 'Settlement Calculator',\n  labelDualSettleDateDur: 'Subscription Length (days)',\n  labelNoInvestContent:\n    'You currently have no investment assets. Start earning now with AMM, ETH Staking, or Dual Investments',\n  labelImportCollection: 'Import Collection for Legacy NFT',\n  labelCheckImportCollectionTitle: 'Import legacy NFTs under contract address to proceed',\n  labelContinue: 'Next',\n  labelImportCollection1: 'Import Collection for Legacy NFT',\n  labelImportCollection2: 'Create/Choose a collection',\n  labelImportCollection3: 'Select NFTs to move into/out of collection',\n  labelSelectContractAddress: 'Contract address',\n  labelImportChooseCollection:\n    'The created collection here can only be used to categorize the Legacy NFT minted without collection_metadata field.\\n You can freely move those NFTs into any collection you created here.',\n  labelImportCollectionundecided: 'Undecided',\n  labelImportCollectionoutside: 'Others',\n  labelImportCollectioninside: 'Current Collection',\n  labelImportCollectionall: 'All',\n  labelImportCollectionundecidedDes: 'items under this contract not classified into a collection',\n  labelImportCollectionoutsideDes:\n    'items under this contract classified into a different collection',\n  labelImportCollectioninsideDes:\n    'items under this contract classified into the current collection',\n  labelImportCollectionallDes: 'all items under this contract',\n  labelImportCollectionTitle: 'Import Collection for Legacy NFT',\n  labelAssetTokens: 'Tokens',\n  labelAssetInvests: 'My Investments',\n  labelAssetRedPacket: 'Red Packets',\n  labelORCreateCollection: 'Or <1>Create Collection</1>',\n  labelCreateLegacyCollection: 'Create Legacy Collection',\n  labelNoLegacyCollection: 'You have no Legacy Collection, please',\n  labelLegacyCollectionTitle: 'Create Legacy Collection',\n  labelMoveOut: 'Move out of {{symbol}}',\n  labelMoveIn: 'Move into {{symbol}}',\n  labelMoveInCollection: 'Collection',\n  labelSelectAll: 'Select All',\n  labelCancelAll: 'Cancel',\n  labelDoneBtn: 'Done',\n  labelDetail: 'Detail',\n  labelNFTMyCollection: 'Collection: {{collection}}',\n  labelZoom: 'Zoom Media',\n  labelRefresh: 'Refresh NFT cache',\n  labelNFTDetailTab: 'Details',\n  labelNFTPropertiesTab: 'Properties',\n  labelLinkMetaData: 'NFT metadata Resource link',\n  labelCountDown: 'Count Down',\n  labelStackingSelect: 'Choose Staking Product',\n  labelImportCollectionMove: 'Collection',\n  labelCollectionImportNFTBtn: 'Manage Legacy NFT',\n  labelNFTMoveFailed: 'NFT move failed!',\n  labelNFTMoveSuccess: 'NFT moved successful',\n  labelLuckTokenDefaultTitle: 'Good Luck!',\n  labelSync: 'in Sync',\n  labelMintInSyncTooltips:\n    'The NFT and collection information may not be synced up timely after minting due to onChain operation. Please stay tuned and refresh the page later.',\n  labelEstRateApr: 'Est.rate (APR)',\n  labelStakingApr: 'APR',\n  labelManageCollectionTitle: 'Manage Legacy NFT',\n  labelLegacy: 'legacy',\n  labelTitleMyNFTSAvailable: 'My Holding NFTs',\n  labelTitleTotalAvailable: 'Total NFTs',\n  labelEstRateAprDes:\n    'APR stands for annual percentage Rate. It is the actual annual rate of return, NOT taking into account the effect of compound interest.',\n  labelCheckImportCollectionDes:\n    'As the creator, you will be able to generate collection information for those NFT minted earlier that belong to nowhere. And once done, the other people holding your NFT will be able to view those NFT with proper collection information via loopring.io and loopring wallet.',\n  labelL2toL1NFTFailed: 'Sent {{value}} <span>{{symbol}}</span> to {{l1Symbol}} has failed!',\n  labelL2toL1NFTSuccess: 'Sent {{value}} <span>{{symbol}}</span> to {{l1Symbol}} was successful!',\n  labelL2toL2NFTFailed:\n    'Sent {{value}} <span>{{symbol}}</span> from my {{loopringL2}} to another {{loopringL2}} failed!',\n  labelL2toL2NFTSuccess: 'Sent {{value}} <span>{{symbol}}</span> was successful!',\n  labelDoAgain: '{{method}} Again',\n  labelDepositL1: 'Receive from {{l1Symbol}}',\n  labelDepositNFTL1: 'Receive NFT from {{l1Symbol}}',\n  labelL2ToL1Method: 'Send {{symbol}} to {{l1Symbol}}',\n  labelL2ToL2Method: 'Send {{symbol}} to {{l2Symbol}}',\n  labelConfirmAgainByFailed: 'You had a failed order, please confirm information again...',\n  labelConfirmAgainByFailedWithBalance:\n    'You had a failed order, please confirm information again, Balance of {{symbol}} is {{count}}',\n  labelNFTListfav: 'Favorite',\n  labelNFTListhide: 'Hidden',\n  labelNFTListall: 'Owned',\n  labelNFTHide: 'Deploy Contract',\n  labelNFTUnHide: 'Hide NFT',\n  labelNFTUnHideDes: 'The easiest way to trade',\n  labelHideMethodTooltiphide: 'Hide NFT',\n  labelHideMethodTooltipunhide: 'Show NFT',\n  labelFavouriteMethodTooltipfavourite: 'Favorite',\n  labelFavouriteMethodTooltipunfavourite: 'Unfavorite',\n  labelfavourite: 'Favorite',\n  labelunfavourite: 'Unfavorite',\n  labelFavouriteSuccess: 'Set {{favorite}} Successful',\n  labelFavouriteFailed: 'Set {{favorite}} Failed',\n  labelhide: 'Hide',\n  labelunhide: 'Show',\n  labelHideSuccess: '{{hide}} NFT Successful',\n  labelHideFailed: '{{hide}} NFT Failed',\n  labelSmallOrderAlertLine1: 'Small trades (below ~$100) incur a higher fee.',\n  labelSmallOrderAlertLine2: 'Please review the fee before confirming.',\n  labelSmallOrderAlertLine3: 'Trading Fee:',\n  labelSmallOrderAlertLine4: 'Fee ratio:',\n  labelSmallOrderAlertLine5: 'Minimum Converted:',\n  labelSwapSecondConfirmTitle: 'Confirm Swap',\n  labelSwapSettingTitle: 'Settings',\n  labelSwapSettingSecondConfirm: 'Second confirmation',\n  labelSwapSettingSecondConfirmTootip: 'skip confirm screen when toggled off',\n  labelSwapSettingToggleSuccess: 'Swap second confirmation trun {{onOrOff}}',\n  labelFeeMin: 'Min {{fee}}',\n  labelIKnow2: 'I know',\n  labelAddAssetTitleBridge: 'Add Asset From Another L1',\n  labelAddAssetTitleBridgeDesActive:\n    'If you have transferred tokens from another {{ethereumL1}} Symbol account, it may take some time for this transaction to execute on-chain. Once you receive the assets, you can manually activate the {{l2Symbol}} account.',\n  labelAddAssetTitleBridgeDes:\n    'If you have transferred tokens from another {{ethereumL1}} account, it may take some time for this transaction to execute on-chain.',\n  labelAddAssetTitleExchange: 'Add Asset From An Exchange',\n  labelAddAssetTitleExchangeDes: 'If you have transferred tokens from an Exchange, please wait. ',\n  labelAddAssetTitleExchangeDesActive:\n    'If you have transferred tokens from an Exchange, please wait. Once you receive the assets, you can manually activate the {{l2Symbol}} account.',\n  labelAddAssetTitleCard: 'Add Asset With a Card',\n  labelAddAssetTitleCardDes:\n    'If you have purchased crypto with a card, please wait for it to arrive in your account.',\n  labelAddAssetTitleCardDesActive:\n    'If you have purchased crypto with a card, please wait for it to arrive in your account. Upon arrival, {{l2Symbol}} will be activated manually.',\n  labelMinFeeForActive: 'Min {{fee}}',\n  labelReceiveAddressDes:\n    'If you have transferred tokens from another {{loopringL2}} account, please wait.',\n  labelReceiveAddressDesActive:\n    'If you have transferred tokens from other {{loopringL2}} accounts, please close this window and try to activate your {{l2Symbol}} account again.',\n  labelDepositWaiting: 'It make take some time for this transaction to execute on-chain.',\n  labelFrom: 'From',\n  labelTo: 'To',\n  labeltransfer: 'Transfer',\n  labelwithdraw: 'Withdrawal',\n  labelDeposit: 'Deposit',\n  labelFiatAmount: 'Fiat Amount',\n  labelToMyL2: 'My {{loopringL2}}',\n  labelBanxaNotReady:\n    'Please waiting a while for Banxa sdk loading, if you keep on face this problem try fresh the browser or contact us',\n  labelBanxaFailedForAPI: 'Please waiting a while, Banxa service is not available currently.',\n  labelL2toL2AddressFeePaid: 'Active account fee had paid',\n  labelL2toL2AddressFeeActiveFee: \"Pay recipient's {{l2Symbol}} activation fee: {{value}}\",\n  labelL2toL2FeeWithActive: 'Fee (including activation fee)',\n  labelRedPacketOpen: 'Open',\n  labelRedPacketTitle: 'Red Packets',\n  labelRedPacketTypeTokens: 'Choose Tokens / NFTs / Blind Box',\n  labelRedPacketChoose: 'Choose Red Packet Type',\n  labelRedPacketMain: 'Input Red Packet/Send',\n  labelLuckyTokenViewTypePublic: 'Public Red Packet',\n  labelLuckyTokenViewTypePrivate: 'Private Red Packet',\n  labelLuckyTokenViewTypeDesPublic:\n    'Your Red Packet is public, and everyone can try to claim a share of it.',\n  labelLuckyTokenViewTypeDesPrivate:\n    'Your Red Packet is shared privately with others via a custom QR code.',\n  labelLuckyBlindBox: 'Blind Box Red Packet',\n  labelLuckyBlindBoxDes:\n    'Each recipient will receive a sealed Red Packet which cannot be opened until the expiration date. While some recipients will receive an NFT, others will need to try their luck next time.',\n  labelLuckyRecievedBlindBox: 'Received Blind Box {{opendBlindBoxAmount}}/{{totalBlindBoxAmount}}',\n  labelBlindBoxExplainationNotEnded:\n    \"The outcome of the Blind Box will be revealed upon expiration. Please claim within 3 days if your Red Packet contains a gift or it will be forfeited and returned to the Sender's wallet.\",\n  labelBlindBoxExplainationEnded:\n    \"Please claim within 3 days or it will be forfeited and returned to the Sender's wallet.\",\n  labelBlindBoxExplaination2:\n    '{{opendBlindBoxAmount}} out of {{totalBlindBoxAmount}} blind boxes have been opened.',\n  labelBlindBoxExplaination3: '{{remainingGiftsAmount}} gifts available for grabbing.',\n  labelBlindBoxNotStarted: 'Red Packet is available to grab after: {{time}}',\n  labelBlindBoxStarted: 'Blind Box Reveal time after: {{time}}',\n  labelBlindBoxTokenHint: 'Unopen tokens will be returned back to sender after: {{time}}',\n  labelBlindBoxClaimStarted: 'Any unclaimed NFTs will be returned to the Sender after: {{time}}',\n  labelBlindBoxRecievedNFT: 'Received NFT {{deliverdGiftsAmount}}/{{totalGiftsAmount}}',\n  labelBlindBoxStartDate: 'Start date',\n  labelBlindBoxStartTime: 'Start Time',\n  labelBlindBoxEndDate: 'End date',\n  labelBlindBoxEndDate2: 'Blindbox reveal time',\n  labelBlindBoxEndTime: 'End Time',\n  labelBlindBoxRedPacketWithGift: 'Count of Red Packets with gift',\n  labelBlindBoxExpirationExplainationForToken:\n    'After expiration, any unopened Red Packets will be forfeited and sent back to the Sender',\n  labelBlindBoxExpirationExplainationForNFT:\n    \"If NFT Red Packet recipients do not claim their NFT within 30 days, it will be forfeited and returned to the Sender's wallet.\",\n  labelBlindBoxPrivate: 'Private Red Packet',\n  labelBlindBoxPrivateDes: 'Your Red Packet is shared privately with others via a custom QR code.',\n  labelBlindBoxClaimWarning:\n    \"If the recipients of the NFT Red Packets do not claim their received NFT within 3 days, the NFT will be forfeited and sent back to the Sender's wallet.\",\n  labelBlindBoxRecievedRedPackets: 'Received NFT Red Packets',\n  labelBlindBoxCongratulations: 'Congratulations',\n  labelBlindBoxSorry: 'Sorry',\n  labelBlindBoxNoRewards: 'You have not received a reward',\n  labelBlindBoxCongratulationsBlindBox: 'Congratulations on receiving a Blind Box',\n  labelBlindBoxSorryBlindBox: 'Sorry, you did not win a prize',\n  labelLuckyRelayToken: 'Relay Red Packet',\n  labelLuckyRelayTokenDes:\n    'If the recipient of the Red Packet also re-shares the packet, they receive half of whatever the next person receives.',\n  labelLuckyRandomToken: 'Lucky Red Packet',\n  labelLuckyRandomTokenDes: 'Each recipient will get a random amount of.',\n  labelLuckyCommonToken: 'Average Red Packet',\n  labelLuckyCommonTokenDes:\n    'Each recipient will receive a pre-set split of the total Red Packet shared.',\n  labelL1toL2NFTAmount: 'NFT Amount',\n  labelInputRedPacketBtnLabel: 'Select Token',\n  labelCreateRedPacket: 'Send Red Packet',\n  labelMyRedPacket: ' My Red Packet Record',\n  labelRedPacketMarkets: 'Red Packet Plaza',\n  labelRedPacketQRCodeImport: 'Receive Red Packet',\n  labelLuckyTokenViewType1: 'Private Red Packet',\n  labelLuckyTokenViewTypeDes1:\n    'Your Red Packet is shared privately with others via a custom QR code.',\n  labelLuckyTokenViewType0: 'Public Red Packet',\n  labelLuckyTokenViewTypeDes0:\n    'Your Red Packet is public, and everyone can try to claim a share of it.',\n  labelSplit: 'Red Packet Count',\n  labelRedPacketMemo: 'Memo',\n  labelRedPacketMemoPlaceholder: 'Best wishes',\n  labelRedPacketStart: 'Available in',\n  labelRedPacketSendWaitForAuth: 'Please confirm to send red packet {{value}} {{symbol}}.',\n  labelRedPacketSendDenied: 'You rejected to send {{value}} {{symbol}} red packet.',\n  labelRedPacketRecordTitle: 'My Red Packet Record',\n  labelRedPacketReceived: 'ERC20 Received',\n  labelRedPacketSend: 'ERC20 Send',\n  labelRedPacketNFTReceived: 'NFT Received',\n  labelRedPacketNFTSend: 'NFT Send',\n  labelImportRedPacket: 'Import QR code to receive red packet',\n  labelCreateRedPacketTitle: 'Send Red Packet',\n  labelClaimWithdrawFee: 'Fee',\n  labelClaimWithdrawNotEnough: 'Insufficient balance',\n  labelClaimWithdrawTitle: 'Claim to {{loopringL2}}',\n  labelClaimWithdrawWaitForAuth: 'Please confirm to claim {{symbol}}',\n  labelClaimWithdrawDenied: 'You rejected to claim {{symbol}}.',\n  labelClaimWithdrawInProgress: 'Processing...',\n  labelClaimWithdrawFailed: 'Claim has failed!',\n  labelClaimWithdrawSubmit: 'Claim has been submitted',\n  labelClaimWithdrawToken: 'Token Amount',\n  labelRedPacketSendSubmit: 'Send red packet has been submitted.',\n  labelRedPacketSendSuccess: 'Red packet Send Successful.',\n  labelRedPacketSendFailed: 'Send red packet of {{value}} {{symbol}} failed!',\n  labelRedPacketSendInProgress: 'Processing...',\n  labelRefreshRedPacket: 'Refresh List',\n  labelRedPacketSendCommonTitle: 'Normal Red Packet',\n  labelRedPacketSenRandomTitle: 'Lucky Red Packet',\n  labelAmountEach: 'Amount Each',\n  labelRedPacketTotalAmount: 'Total Amount',\n  labelQuantity: 'Quantity',\n  labelAssetAmount: 'Total Asset Amounts: {{value}}',\n  labelCreateRedPacketBtn: 'Prepare Red Packet',\n  labelRedPacketsExpireDes:\n    'Unclaimed tokens remaining after the expiration will be returned within 24h',\n  labelReserveFee: 'Insufficient {{symbol}} with fee',\n  labelRedPacketFee: 'Insufficient fee',\n  labelRedPacketsInsufficient: 'Insufficient {{symbol}} balance',\n  labelRedPacketsMinRange: 'Min {{value}}',\n  labelRedPacketsMaxRange: 'Max {{value}}',\n  labelRedPacketsMin: 'Minimum of {{value}} {{symbol}}',\n  labelRedPacketsMax: 'Maximum of {{value}} {{symbol}}',\n  labelRedPacketsGiftsLargerThanPackets:\n    'The number of Red Packets containing gifts cannot exceed the total number of Red Packets',\n  labelBlindBoxNumberOverMaximun: 'Number of Blind Box exceeds maximum',\n  labelRedPacketsSplitNumber: 'The maximum number of Red Packet is {{value}}',\n  labelRedPacketsSplitCommonDetail: 'Distribution per red packet: {{value}}',\n  labelRedPacketsSplitLuckyDetail: 'Token amount for each Red Packet is randomized.',\n  labelSendRedPacketTitle: 'Send Red Packet',\n  labelSendRedPacketTitlePublic: 'Send Red Packet -- Public',\n  labelSendRedPacketTitlePrivate: 'Send Red Packet -- Private',\n  labelRedPacketWaitingBlock: 'Block is not ready',\n  labelShare: 'Share',\n  labelRelayRedPacket: 'Relay Red Packet',\n  labelNormalRedPacket: 'Average Red Packet',\n  labelluckyRedPacket: 'Lucky Red Packet',\n  labelrelayRedPacket: 'Relay Red Packet',\n  labelnormalRedPacket: 'Average Red Packet',\n  labelLuckyRedPacket: 'Lucky Red Packet',\n  labelLuckyRedPacketStart: 'Starts in: {{value}}',\n  labelLuckyRedPacketTimeout: 'Red Packet has been \\n taken out',\n  labelLuckyRedPacketDetail: 'View Red Packet details >',\n  labelRedPacketOpenInProgress: 'Processing...',\n  labelRedPacketOpenFailed: 'Read red packet failed!',\n  labelRedPacketShowQR: 'Share red packet',\n  labelRedPacketReceivedRecord: 'Receive Red Packet {{value}}/{{count}}',\n  labelAmmExitMiniOrderDisabled:\n    'Transaction fees will be greater than the value of the LP, which will cost you your assets.',\n  labelAmmExitMiniOrderMini:\n    'The transaction fee will account for 15% of the LP value, are you sure you want to redeem it?',\n  labelLpAmount: 'LP Amount: {{value}}',\n  labelRedPacketMarketsBtn: 'Red Packet Plaza',\n  labelRedPacketBtn: 'Shared',\n  labelRedPacketViewType0: 'Public Plaza',\n  labelRedPacketViewType1: 'Public QR',\n  labelRedPacketViewTypeDetail0: 'public Red Packet',\n  labelRedPacketViewTypeDetail1: 'public Red Packet',\n  labelRedPacketStatusSUBMITTING: 'Submitting', // SUBMITTING = 0,\n  labelRedPacketStatusNOT_EFFECTIVE: 'Not Start', // NOT_EFFECTIVE = 1,\n  labelRedPacketStatusPENDING: 'In Processing', // PENDING = 2,\n  labelRedPacketStatusCOMPLETED: 'Completed', // COMPLETED = 3,\n  labelRedPacketStatusOVER_DUE: 'Over Due', // OVER_DUE = 4,\n  labelRedPacketStatusFAILED: 'Failed', // FAILED = 5\n  labelRedPacketStatusNotStarted: 'Hasn’t started',\n  labelRedPacketStatusStarted: 'Started',\n  labelRedPacketStatusEnded: 'Ended',\n  labelRedPacketNo: 'NO.{{value}}',\n  labelRedPacketClaimInProgress: 'Processing...',\n  labelRedPacketClaimFailed: 'Open red packet failed!',\n  labelRedPacketClaimSuccess: '',\n  labelReceived: 'Received',\n  labelGoodLuck: 'Good Luck',\n  labelRedPacketGrab: 'Share with Friends',\n  labelRedPacketEnded: 'Ended',\n  labelLuckDraw: 'Luckiest Draw',\n  labelMyLuckReward: '(My reward)',\n  labelRedPacketClaimTitle: 'Claim to {{loopringL2}}',\n  labelClaimNoBalance: 'Insufficient {{belong}} balance',\n  labelShareQRCode: 'Generate QR Code for share',\n  labelSeal: 'Seal',\n  labelOpenAfter: 'Open after {{time}}',\n  labelOpenStart: 'Start',\n  labelTotalRedPacket: 'Total Quantity: {{value}}',\n  labelMyRedPacketReward: 'My Rewards',\n  labelRedpacketScanDes:\n    'Grab this Red Packet by scanning with your Loopring Wallet or importing to loopring.io',\n  labelLuckyRedPacketStarted: 'Red Packet is Started',\n  labelNFTRedpacketBtn: 'Send Red Packet',\n  labelRedpacketDurationTitle: 'Expires after',\n  labelRedpacketDurationPlaceHold: 'Min 1 - Max 30 Days',\n  labelRedPacketDescription: 'Red Packet Description',\n  labelRedpacketHavePeopleHelp:\n    '<1>{{number}}</1> friends relayed this red packet, you extend reward: <3>{{amount}}</3>.',\n  labelRedPacketFrom: 'From',\n  labelRedPacketTo: 'To {{loopringL2}}',\n  labelRedPacketMy: 'My Red packet',\n  labelRedpacketNotActive: 'Hide received Red Packets',\n  labelRedpacketTokens: 'ERC20 Tokens',\n  labelRedpacketTokensShort: 'Tokens',\n  labelRedpacketNFTS: 'NFTs',\n  labelRedpacketBlindBox: 'Blind Box',\n  labelRedpacketHideInactionable: 'Hide inactionable records',\n  labelChooseNFT: 'Choose NFT <1>{{required}}</1>',\n  labelChooseNFTTooltips: '',\n  tokenSelectNFTToken: 'Select NFT',\n  labelRedPacketClaimERC20: 'ERC20',\n  labelRedPacketClaimNFT: 'NFT',\n  labelRedPacketMarketERC20: 'ERC20',\n  labelRedPacketMarketNFT: 'NFT',\n  labelRedPacketNotSupport:\n    'Unfortunately Mobile Dapp does not support Red Packet feature, Please download Loopring wallet or try this feature on laptop browser.',\n  labelRedPacketTimeRange: 'Start / End Time',\n  labelRedPacketTimeRangeDes: 'The Red Packet expires after the end date',\n  labelRedPacketTimeRangeBlindbox: 'Start / Reveal Time',\n  labelRedPacketTimeRangeBlindboxDes:\n    'The Reveal Time is when the Red Packet ends, and recipients can open it to see if they have received an NFT',\n  labelRedPacketStartWithTime: '{{time}} Start',\n  labelRedPacketTabReceived: 'Received',\n  labelRedPacketTabSent: 'Sent',\n  labelRedPacketTabNFTs: 'NFTs',\n  labelRedPacketTabBlindBox: 'Blind Box',\n  labelOrderOpen: 'Continue',\n  labelOrderCancel: 'Cancel',\n  labelOrderBanxaIsReadyToPay: 'The crypto selling order is ready. Please continue.',\n  labelBanxaContinuous: 'Proceed existing order',\n  labelBanxaCreate: 'Create new order',\n  labelBanxaTitleCreateAgain: '',\n  labelYouAlreadyHaveAnBanxa: 'Existing <1>order</1> detected, send token to complete order.',\n  labelHaveAnBanxaCancel: 'Create a new order from scratch.',\n  labelBanxaConfirmSubmit:\n    'Token has been sent to Banxa wallet. You can save/click below link to check the payment status anytime.',\n  labelInvestStakeLRC: 'LRC STAKING',\n  labelInvestStakeLRCDES: 'Earn LRC staking rewards',\n  labelFriendsPayActivation: 'Your friend has paid for your {{l2Symbol}} activation fee.',\n  labelLRCStakingTitle: \"What's LRC Staking\",\n  labelLRCStakingRisk:\n    '<p>LRC staking is incentivized through an allocated portion of the Loopring protocol fee; the exact percentage is determined by the Loopring DAO. The APY is updated daily based on the allocated amount from previous day’s fee. Any LRC holder can participate in LRC staking via {{l2Symbol}} to accumulate daily rewards. The assets must be staked for a minimum of 90 days to receive rewards.</p>',\n  labelLRCStakingAgree: 'I have read and understand the risk warning.',\n  labelLRCStakingRisk2:\n    '<0>The staked LRC will be locked in {{loopringL2}}, meaning it cannot be used for other purposes. You may redeem your LRC at any time; however, doing so before the minimum Locked Duration will forfeit any accumulated reward.</0>',\n  labelInvestLRCStakingTitle: 'LRC Staking',\n  labelMyInvestLRCStaking: 'My Investments',\n  labelInvestLRCStakingLockAlert:\n    'Your assets for investment will be locked until your redemption.',\n  labelLRCStakeAPRTooltips:\n    'APR stands for annual percentage rate, not taking into account the effect of compound interest. The value displayed here indicates the current value, while it keeps changing dynamically. ',\n  labelLRCStakeAPR: 'APR <1></1>',\n  labelLRCStakeEarn: 'Daily Rewards (est.) <1></1>',\n  labelLRCStakeEarnTooltips:\n    'Once funds are successfully locked for staking, rewards will begin calculating at 00:00 (UTC) the following day.',\n  labelLRCStakeSubTime: 'Subscribe Time',\n  labelLRCStakeDurationTooltips:\n    'Staking Duration refers to the minimum amount of time that staked assets must be locked in order to be entitled to claim rewards. LRC staking requires the minimum Locked Duration.',\n  labelLRCStakeDuration: 'Lock duration to claim reward<1></1>',\n  labelInvestLRCTitle: 'LRC Staking',\n  labelLRCStakeRiskDes:\n    'The staked LRC will be locked in {{loopringL2}}, meaning it cannot be used for other purposes. You may redeem your LRC at any time; however, doing so before the minimum Locked Duration will forfeit any accumulated reward.',\n  labelAgreeRedeem: 'Redeem',\n  labelStackingAgreeRedeemTitle: 'Redeem In Advance',\n  labelStackingAgreeRedeem:\n    'Redeeming staked assets before the minimum Locked Duration will forfeit the accumulated rewards. Are you sure you still want to redeem?',\n  labelLRCStakeProduct: 'Product',\n  labelLRCStakeRedeemDes:\n    'This product has meet the minimum Locked Duration. You can now redeem any portion of the subscription amount without deducting from your earnings. The remaining subscription amount will continue to generate income.',\n  labelLRCStakeRedeemAgree:\n    'I acknowledge the early redemption will forfeit the accumulated reward',\n  labelLRCStakeCurrentEarn: 'Current Total Rewards',\n  labelLRCStakeForfeitedReward: 'Forfeited Reward',\n  labelLRCStakeRemainingEarnings: 'Remaining Rewards',\n  labelDeFiSideAmount: 'Amount',\n  labelDeFiSideProduct: 'Product',\n  labelDeFiSidePoolShare: 'Pool Share',\n  labelDeFiSideAPR: 'APR',\n  labelDeFiSideCumulativeEarnings: 'Cumulative Earnings',\n  labelDeFiSidePreviousEarnings: \"Previous Day's Earnings\",\n  labelDeFiSideLockDuration: 'Lock duration to claim reward',\n  labelDeFiSideSubscribeTime: 'Subscribe Time',\n  labelDeFiSideHoldingTime: 'Holding Time',\n  labelDeFiSideInvestmentDetails: '{{symbol}} Staking Details',\n  labelSideStakingTable: 'LRC Staking',\n  labelInvestMaxDefi: 'Min {{minValue}} - Max {{maxValue}}',\n  labelDefiMax: 'Allowable maximum is {{arg}}',\n  labelDefiStakingDetail: 'Detail',\n  labelDefiStakingRedeem: 'Redeem',\n  labelDays: 'day(s)',\n  labelRemainingAmount: 'Remaining amount should be greater than {{symbol}},\\n Please redeem all.',\n  labelRemainingBtnAmount: 'Remaining amount is insufficient',\n  labelStakingCumulativeEarnings: 'Cumulative Rewards',\n  labelStakingClaimableEarnings: 'Claimable Rewards',\n  labelClaimBtn: 'Claim',\n  labelStakeNoEnough: 'Insufficient {{arg}} balance',\n  labelClaimBtnClaimed: 'Claimed',\n  labelClaimBtnExpired: 'Expired',\n  labelDefiRemindMin: 'Please redeem all Balance',\n  labelInvestType_LRCSTAKE: 'LRC Staking',\n  labelNFTs_one: '\\u2A09{{count}} NFT',\n  labelNFTs_other: '\\u2A09{{count}} NFTs',\n  labelTokenNFTMaxRedPack: 'Max: ',\n  labelNFTRedPackAskClaim:\n    'Note: After expiration, all the unclaimed NFTs will be returned back to sender. Please claim as soon as possible if you want to hold them.',\n  labelTransferDelayConfirm:\n    'Your claim request has been received. Loopring will transfer the token into your {{l2Symbol}} account soon. Please verify it.',\n  labelClaimredPacket: 'My Red Packet',\n  labelRedPacketMe: 'Me',\n  labelClaimlrcStaking: 'My LRC Staking',\n  labelExpectSettlementPrice:\n    'The expected settlement price from this order is {{symbolSell}}/{{symbolBuy}}={{stob}}, while the current market price from a trusted oracle is {{symbolSell}}/{{symbolBuy}}={{marketPrice}}. There is a {{marketRatePrice}}% variance observed. To proceed, tap here to confirm you understand and acknowledge the risk.',\n  labelStakingSuccess: '{{symbol}} Staking Successful',\n  labelStakingFailed: '{{symbol}} Staking failed',\n  labelStakingRedeemFailed: 'Redeem {{symbol}} failed',\n  labelStakingRedeemSuccess: 'Redeem {{symbol}} Successful',\n  labelStakingRedeemRemaining: 'Remaining Amount',\n  labelStakingRedeemDate: 'Redeem Time',\n\n  labelContactsAddContact: 'Add Contact',\n  labelContactsAddressTitle: 'Address',\n  labelContactsAddressDes: 'Enter wallet address or ENS',\n  labelContactsAddressInvalid: 'Invalid address or ENS',\n  labelContactsNameTitle: 'Name',\n  labelContactsNameDes: 'Enter name for the contact',\n  labelContactsAddContactBtn: 'Add',\n  labelContactsDeleteContact: 'Delete Contact',\n  labelDeleteContactInfo: 'Contact',\n  labelContactsDeleteContactBtn: 'Delete',\n  labelContactsAddSuccess: 'Add Contact Succeed',\n  labelContactsDeleteSuccess: 'Delete Contact Succeed',\n  labelContactsEditSuccess: 'Edit Contact Succeed',\n  labelContactsSendSuccess: 'Send Succeed',\n  labelContactsCopySuccess: 'Copied to Clipboard',\n  labelContactsAddFailed: 'Add Contact Failed',\n  labelContactsDeleteFailed: 'Delete Contact Failed',\n  labelContactsEditFailed: 'Edit Contact Failed',\n  labelContactsSendFailed: 'Send Failed',\n  labelContacts: 'Contacts',\n  labelContactsSend: 'Send',\n  labelContactsTransactions: 'Transactions',\n  labelContactsNetworkChoose: 'Choose {{l2Symbol}} or {{l1Symbol}} Account',\n  labelContactsNext: 'Next',\n  labelContactsContactExisted: 'Contact Already Existed',\n  labelNotExchangeEOA:\n    'Sending to an Exchange Address {{l2Symbol}} account is not supported. {{loopringL2}} accounts cannot be activated on Exchange wallet addresses. Instead, please send to the {{l1Symbol}} account associated with this address.',\n  labelNotOtherSmartWallet:\n    'This wallet binds with smart contract that does not support {{loopringL2}}. You will need to send funds to the {{l1Symbol}} account.',\n  labelContactsNoContact: 'No Contact',\n  labelContactsSelectReciepient: 'Select the Recipient',\n  labelContactsBinanceNotSupportted:\n    'Binance currently do not support {{loopringL2}} transfers. You will need to send funds to the {{l1Symbol}} account.',\n  labelContactsHuobiNotSupportted:\n    'Huobi currently do not support {{loopringL2}} transfers. You will need to send funds to the {{l1Symbol}} account. Transactions need to wait for 24 hours.',\n  labelContactsOtherExchangesNotSupportted:\n    'The trading platforms currently do not support {{loopringL2}} transfers. You will need to send funds to the {{l1Symbol}} account.',\n  labelBtradeSwapTitle: 'Block Trade',\n  labelBtradeSwapType: 'Type',\n  labelBtradeSwapFilled: 'Filled',\n  labelBtradeSwapFee: 'Fee',\n  labelBtradeSwapTime: 'Time',\n  labelBtradeSwapPrice: 'Price',\n  labelBtradeSwapSettled: 'Settled',\n  labelBtradeSwapDelivering: 'Delivering',\n  labelBtradeSwapPanelDes:\n    'The Loopring pool is currently unable to swap the full requested amount. The tokens that were successfully swapped will be transferred to your account now. The unswapped tokens will be locked until they can be swapped. \\n We’ll rebalance the pool shortly and swap the remaining portion.',\n  labelBtradeSwapDeliverDes:\n    'The Loopring pool is currently unable to swap the full requested amount. The tokens that were successfully swapped will be transferred to your account now. The unswapped tokens will be locked until they can be swapped. \\n We’ll rebalance the pool shortly and swap the remaining portion.',\n  labelGoBtradeSwap:\n    'Swapping on the DEX will result in a large Price Impact (loss of assets). We recommend using the <a>Block Trade</a> option to help minimize potential losses.',\n  labelBtradeSwap: 'Block Trade',\n  labelBtrade: 'Block Trade',\n  labelBtradeSwapFailed: 'Failed!',\n  labelBtradeSwapTitleDes: 'What is Block Trade?',\n  labelBtradeSwapContentDes:\n    '<p>Block Trade offers a secure and trustless way for users to swap tokens using CEX liquidity. The trades happen exclusively between designated entities, ensuring that the existing liquidity of the DEX remains unaffected. There is no price impact to other DEX users as a result of the transaction.</p>' +\n    '<p>This is similar to the traditional stock market’s Block Trade System. A block trade is a large, privately negotiated transaction, which can be made outside the open market through a private purchase agreement.</p>' +\n    \"<p>The Loopring pool is currently unable to swap the fully requested amount. If you choose to continue, the unswapped tokens will be locked until they can be swapped. We'll rebalance the pool shortly.</p>\" +\n    '<p>Block Trade offers two options:</p><ul>' +\n    '<li>Prioritize Speed.</li>' +\n    '<li>Prioritize Quantity.</li></ul>' +\n    '<h6>Prioritize Speed</h6>' +\n    '<p>This option prioritizes quick trade execution to ensure that trades are completed as soon as possible. It’s ideal for users who need to complete their trades quickly.</p>' +\n    '<h6>Prioritize Quantity</h6>' +\n    '<p>This option prioritizes trading as much of the asset as possible, even if it means waiting longer for the order to be fully executed. It’s ideal for users who want to maximize their trading volume and are willing to wait for the market to be favorable before completing the transaction.</p>' +\n    '<p>We’ll use the Loopring pool to swap your tokens. If your request exceeds the pool’s available balance, we’ll swap as many tokens as we can. Afterwards, we’ll rebalance the pool and then swap the remaining portion. The entire transaction should complete within 24 hours.</p>',\n  labelRefereeRewards: 'Referee Rewards',\n  labelReferralRewards: 'Referral Rewards',\n  labelRewardLRC: 'Rewards LRC',\n  labelPrice: 'Price',\n  labelBtradeSwapMiniMax: 'Min {{minValue}} - Max {{maxValue}}',\n  labelBtradeSwapMini: 'Min {{minValue}}',\n  labelBtradeConfirm: 'Please check the checkbox',\n  labelBtradeSwapBtn: 'Swap',\n  labelType: 'Type',\n  labelBtradeTrade: 'Block Trade',\n  labelBtradeTitle: 'Block Trade Details',\n  labelBtradeQuote: 'Total Quota:',\n  labelBtradeQuoteDes: 'Total Quota is the maximum allowable trading amount.',\n  labelBtradePoolDes: 'Loopring Pool:',\n  labelBtradePool: 'Loopring Pool',\n  labelBtradeToleranceTooltips:\n    'Your trade will revert if the price changes unfavorably by more than this percentage.',\n  labelBtradeFeeTooltips: 'The trading fee is fixed at {{feeRate}}.',\n  labelBtradeMinReceiveTooltips:\n    'The price in other liquidity source changes dynamically, the price you see when placing an order may be inconsistent with the final transaction price; also the received amount needs to deduct the fees from converted amount. The protocol can guarantee that the received token is at least this amount.',\n  labelBtradeInsufficient: 'Insufficient',\n  labelBtradeTime: 'Time',\n  labelStopLimit: 'Stop-Limit {{tradeType}} {{symbol1}}',\n  labelStopLimitDes:\n    '<p>If the last price {{from}} to or {{behavior}} {{stopPrice}} {{symbol2}}, and order to {{tradeType}} {{value1}} {{symbol1}} at a price of {{limitPrice}} {{symbol2}} will be placed.</p>',\n  labelStopLimitFromGoesUp: 'goes up',\n  labelStopLimitFromDropsDown: 'drops down',\n  labelStopLimitBehaviorAbove: 'above',\n  labelStopLimitBehaviorBelow: 'below',\n  labelStopLimitType: 'Stop-Limit / {{tradeType}}',\n  labelStopLimitStopPrice: 'Stop Price',\n  labelStopLimitPriceLimitPrice: 'Limit Price',\n  labelStopLimitAmount: 'Amount',\n  labelStopLimitCancel: 'Cancel',\n  labelStopLimitConfirm: 'Confirm',\n  labelBtradeSwapPending: 'Pending',\n  labelStopLimitTitle: 'Stop-Limit',\n  labelStopPrice: 'Limit / Buy Price',\n  labelStopStopPrice: 'Stop / Trigger Price',\n  labelStopLimitWhatIs: \"What's Stop-Limit?\",\n  labelStopLimitMinMax: 'Min {{minValue}} - Max {{maxValue}}',\n  labelLimitStopPriceMinMax: 'Stop Price Range {{arg}}',\n  labelLimitMainContent:\n    'A Stop-Limit order is a limit order with a limit price and a stop price. When the stop price is reached, the limit order will be placed on the order book. Once the limit price is reached, the limit order will be executed.',\n  labelLimitStopPriceLabel: 'Stop Price / Trigger Price',\n  labelLimitStopPriceContent:\n    'When the current asset price reaches the given stop price, the Stop-Limit order is executed to buy or sell the asset at the given limit price or better.',\n  labelLimitLimitPriceLabel: 'Limit Price',\n  labelLimitLimitPriceContent:\n    'The selected (or potentially better) price that the Stop-Limit order is executed at.',\n  labelLimitAmountLabel: 'Amount',\n  labelLimitAmountContent: 'The quantity of assets to buy or sell in the Stop-Limit order.',\n  labelLimitDes:\n    'You can set the stop price and limit price at the same price. However, it’s recommended that the stop price for sell orders should be slightly higher than the limit price. This price difference will allow for a safety gap in price between the time the order is triggered and when it is fulfilled. You can set the stop price slightly lower than the limit price for buy orders. This will also reduce the risk of your order not being fulfilled.\\n' +\n    'Please note that your order will be executed as a limit order after the market price reaches your limit price. If you set the stop-loss limit too high or the take-profit limit too low, your order may never be filled because the market price can’t reach the set limit price.',\n  labelLimitDemoTitle: 'How does a Stop-Limit order work?',\n  labelLimitDemoDes:\n    'The current price is 2,400 (A). You can set the stop price above the current price, such as 3,000 (B), or below the current price, such as 1,500 (C). Once the price goes up to 3,000 (B) or drops to 1,500 (C), the Stop-Limit order will be triggered, and the limit order will be automatically placed on the order book.\\n Note: <ol>' +\n    '<li>Limit price can be set above or below the stop price for both buy and sell orders. For example, stop price B can be placed along with a lower limit price B1 or a higher limit price B2.\\n</li>' +\n    '<li>A limit order is invalid before the stop price is triggered, including when the limit price is reached ahead of the stop price.</li>' +\n    '<li>When the stop price is reached, it only indicates that a limit order is activated and will be submitted to the order book rather than the limit order being filled immediately. The limit order will be executed according to its own rules.</li></ol>',\n  labelLimitFailed: 'Submitted failed',\n  labelLimitMarket: 'Market data has issue',\n  labelStopLimitOrderGroup: 'Stop-Limit Records',\n  labelStoplimit: 'Stop-Limit',\n  labelStopLimitProduct: 'Product',\n  labelStopLimitLabelType: 'Type',\n  labelStopLimitNotSupport:\n    'Sorry, there is currently insufficient liquidity in this token pair to execute Stop-Limit orders. Please try again later or consider using a market / limit order instead.',\n  labelStopLimitTriggered:\n    'Triggered: The limit order has been submitted to the order book.\\n Time: {{time}}',\n  labelStopLimitWaitingTrigger:\n    'The limit order is not placed until the stop price has been triggered.',\n  labelStopLimitCurrentlyInsufficient: 'Currently insufficient',\n  labelDUAL_CURRENCY: 'Dual Investment',\n  labelDUAL_BASE: 'Dual Investment',\n  labelBTRADE: 'Block Trade',\n  labelL2STAKING: 'LRC Staking',\n  labelSTOP_LIMIT: 'Stop-Limit',\n  labelAMMPending: 'Pending',\n  labelAMMTitle: 'AMM Investment',\n  labelAMMChartFailed: 'Failed load data',\n  labelExpectSettlementLimitPrice:\n    'The expected settlement price from this order is {{symbolBase}}/{{symbolQuote}} = {{price}}, while the current market price from a trusted oracle is {{symbolBase}}/{{symbolQuote}} = {{marketPrice}}. There is a {{marketRatePrice}}% variance observed. To proceed, tap here to confirm you understand and acknowledge the risk.',\n  labelAMMNoEnough: 'Insufficient {{arg}} balance',\n  labelAMMMax: 'Max {{arg}} ',\n  labelAMMMaxAND: '{{coinA}} and {{coinB}}',\n  labelDepositTo: 'Deposit to',\n  labelReferTitle: 'Invite friends to join in \\nLoopring and receive rewards',\n  labelReferTitleDes:\n    'As referrer: will receive a commission on fees the new referred user trades. \\n As referee:  will enjoy a discount on transfer fees.',\n  labelCopy: 'Copy',\n  labelReferralRules: 'Reward rules',\n  labelReferralMethod1: 'Method 1',\n  labelReferralMethod2: 'Method 2',\n  labelReferralMethod1Step1: 'Download the Loopring Wallet App',\n  labelReferralMethod1Step2: 'Sign up with referral code',\n  labelReferralMethod1Step3: 'Activate {{loopringL2}} Account',\n  labelReferralMethod1Step4: 'Both of us receive rewards',\n  labelReferralMethod2Step1: 'Access the website <1>https://loopring.io</1>',\n  labelReferralMethod2Step2: 'Connect Wallet',\n  labelReferralMethod2Step3: 'Activate {{loopringL2}} Account with referral code',\n  labelReferralMethod2Step4: 'Both of us receive rewards',\n  labelReferralMyReferrals: 'My Referrals',\n  labelReferralReferralsRefunds: 'Referee Refunds',\n  labelBtradeQuantity: 'Prioritize Quantity',\n  labelBtradeSpeed: 'Prioritize Speed',\n  labelBtradeSettled: 'Settled',\n  labelOrderCancelConfirm: 'Confirm to cancel this order?',\n  labelOrderCancelOrder: 'Cancel',\n\n  labelRedpacketTotalReward: 'Total {{amount}}',\n  labelRedpacketCantOpen: 'Now is not the time to open',\n  labelLocketInfo: '{{symbol}} Locked Detail',\n  labelSendAssetToAnotherNet: 'To Others Via Third Party Bridge',\n  labelFromAnotherNet: 'From another network',\n  labelAddAssetTitleAnotherNetDes:\n    'If you have transferred tokens from another network, please wait. ',\n  labelAddAssetTitleAnotherNetDesActive:\n    'If you have transferred tokens from another network, please wait. Once you receive the assets, you can manually activate the {{l2Symbol}} account.',\n  labelAnotherNetworkDes:\n    '<0>Orbiter.finance</0> is a 3rd party service provider to help move tokens between various {{l1ChainName}} {{l1Symbol}} and {{l2Symbol}} networks. If you have any concerns regarding their service, please check out their <2>TOS</2>.',\n  labelAnotherNetworkUnderstand: 'I understand and acknowledge the risk',\n  labelReferralImageDes: 'Scan code to register',\n  labelReferralImageCode: 'Code: {{code}}',\n  labelInvite: 'Invite Friends',\n  labelReferralsTotalEarning: 'Total Rewards ',\n  labelReferralsClaimEarning: 'Claimable Rewards ',\n  labelReferralsTotalReferrals: 'Total Referrals ',\n  labelReferralsTotalRefund: 'Total Refunds ',\n  labelReferralsClaimRefund: 'Claimable Refunds ',\n  labelReferralsTotalTradeNumber: 'Total Trade Number ',\n  labelReferralCode: 'Referral Code (Optional) <1>\\uFE61</1>',\n  labelReferralToolTip: 'Enter referral code to enjoy a discount on  transfer fees.',\n  labelBtradeRefresh: 'Refresh',\n  labelArgNoEnough: 'Insufficient {{arg}} balance',\n  WalletConnectV1: 'WalletConnect Legacy',\n  labelDualInvestDesInsufficient: 'Insufficient quota',\n  labelExplorer: 'Explorer',\n  labelTutorial: 'Tutorial',\n  labelRejectSwitchNetwork: 'Switch Chain was Rejected',\n  labelAssetRewards: 'Rewards',\n  labelClaimTypeREBATE_FEE: 'Maker Order Rewards',\n  labelClaimTypeRECOMMENDER_FEE: 'Referral Rewards',\n  labelClaimTypeREFERER_FEE: 'Referee Refunds',\n  labelClaimTypePROTOCOL_FEE: 'Dedicated AMM Incentive',\n  labelClaimTypeLRC_STAKING: 'LRC Staking Rewards',\n  labelClaimOtherRewards: 'Other Rewards',\n  labelAMMClaimableEarnings: 'Dedicated AMM Incentive',\n  labelLayer2HistoryOrders: 'Order Records',\n  labelLayer2HistoryStopLimitRecords: 'Stop-Limit Records',\n  labelLayer2HistoryDefiRecords: 'ETH Staking',\n  labelLayer2HistoryDualRecords: 'Dual Investment',\n  labelLayer2HistorySideStakingRecords: 'LRC Staking',\n  labelLayer2HistoryBtradeSwapRecords: 'Block Trade',\n  labelPayLoopringL2: 'Pay {{loopringL2}}',\n  labelRedPacketTimeRangeBlindboxDesERC20:\n    'The Reveal Time is when the Red Packet ends, and recipients can open it to see if they have received tokens',\n  labelBlindBoxExpirationExplainationForTokenBlindbox:\n    \"If the recipients of the Tokens Red Packets do not open their received Tokens, the Tokens will be forfeited and sent back to the Sender's wallet.\",\n  labelBlindBoxRecieved: 'Received {{deliverdGiftsAmount}}/{{totalGiftsAmount}}',\n  labelBlindBoxClaimHint: 'You can visit Assets > Red Packets to claim your rewards.',\n  labelRedPacketBlindboxReceived1: 'ERC20 Blind Box',\n  labelRedPacketBlindboxReceived2: 'Received',\n  labelRedPacketsGiftsEqualsZero: \"Number of gifts can't be zero\",\n  labelRedpacketStandard: 'Standard',\n  labelCiETHDefiRiskTitle: \"What's Cian Leveraged ETH?\",\n  labelCiETHDefiRisk:\n    '<p>CIAN protocol is a liquid staking derivatives (“LSD”) focused yield strategy platform, where users could earn either through joining algorithmic strategy vaults or through building their own DeFi strategies using CIAN’s advanced automation tools.</p>' +\n    \"<p>The stETH/ETH leveraged staking strategy enables users to safely leverage stETH’s staking rewards. This strategy focuses on staking derivatives and protection/optimization tooling. By nature, this strategy is to use the user's asset as collateral to borrow ETH from lending platforms, then stake ETH in Lido to earn ETH staking interest. By utilizing tools like Flashloan, it actually adds leverage to users' ETH investment. If only there is a positive APY diff between the borrowing rate and ETH staking rate, there will be additional earnings from this strategy vs. standard ETH staking.</p>\" +\n    '<p>It is quite important to understand that, when using such leveraged strategy, it’s highly advised to intend on holding that position for a while. By doing so, users will give enough time for the high APY to cover their entry & exit costs.</p>\\n',\n  labelDefiWithdrawFee: '',\n  labelLeverageETHTitle: 'Leveraged ETH Staking',\n  labelLayer2HistoryleverageETHRecords: 'Leveraged ETH Staking',\n  labelSwapMinConverted: 'Minimum Converted',\n  labelSwapMinConvertedTooltip:\n    'The pool price changes dynamically, the price you see when placing an order may be inconsistent with the final transaction price. The protocol can guarantee that you will receive at least this amount.',\n  labelNetworkFee: 'Network Fee',\n  labelTradingFee: 'Trading Fee',\n  labelTradingFeeEst: 'Trading Fee (est.)',\n  labelStopStopPriceDes:\n    'It\\'s actually the trigger price for the relayer to place a valid order. When the market price reaches the \"Stop Price\",  the system will automatically place a limit order at \"Limit Price\".',\n  labelStopPriceDes:\n    'After the \"Stop Price\" is triggered, the relayer will automatically place a limit order at this price. ',\n  labelStopPriceSell: 'Limit / Sell Price',\n  labelClaimallToken: 'My Rewards',\n  labelConnecting: 'Connecting',\n  labelTitleOverviewAllPrd: 'All Products',\n  labelInvestDefiDes: 'Earn ETH staking rewards',\n  labelInvestChoseProduct: 'Choose the product you want',\n  labelInvestTotalEarnings: 'Total Earnings',\n  labelInvestLoopringEarn: 'Loopring DeFi',\n  labelInvestLoopringEarnDes: 'Earn stable profits with professional asset management',\n  labelInvestLRCDes: 'Earn LRC staking rewards',\n  labelHadUnknownCollectionTitle: 'Import Collection for Legacy NFT',\n  labelHadUnknownCollectionDes:\n    'As the creator, you will be able to generate collection information for those NFT minted earlier that belong to nowhere. And once done, the other people holding your NFT will be able to view those NFT with proper collection information via loopring.io and loopring wallet. ',\n  labelGo: 'Go',\n  labelAnotherNetworkDes2:\n    'Note: Please ensure to check out the \"Change Account\" option and input the recipient\\'s address carefully. If you want to send token to network other than ethereum, the recipient address must be different than the sender address; else you will lose that asset for ever.',\n  labelAnotherNetworkDes3: '',\n  labelRiskReminder: 'Risk Reminder',\n  labelDefiRedeem: 'Redeem',\n  labelDefiSubscribe: 'Subscribe',\n  labelDefiMaxBalance1Leverage:\n    '<li>The Loopring pool will rebalance soon. Please come back later to redeem.</li>',\n  labelDefiNoBalanceLeverage:\n    '<span>Loopring will set up the pool soon. Please come back later to redeem.</span>',\n  labelDefiMaxBalanceLeverage:\n    'It is not possible for the Loopring pool to fulfil your complete request at the moment. You can choose withdraw ciETH https://vault.cian.app/vaults',\n  labelFunctionList: 'Function List:',\n  labelSuperUserTitle: 'Super User',\n  labelLeverageETHStaking: 'Leveraged ETH Staking',\n  labelLeverageETHBack: 'Leveraged ETH Staking',\n  labelInvestType_LEVERAGEETH: 'Leveraged ETH Staking',\n  labelRewardRefresh: 'Refresh',\n  labelToMyL2WidthAddress: '<0>My {{loopringL2}}</0><1>({{address}})</1>',\n  labelFeeAvailablePay: 'Available: {{available}}, Pay: {{pay}}',\n  labelMarketOrderUnfilled: 'Market Order Unfilled',\n  labelRiskAgree: 'Proceed Anyway',\n  labelRiskCancel: 'Cancel',\n  labelExpectedSettlementPrice: 'Expected Settlement Price',\n  labelCurrentMarketPrice: 'Current Market Price',\n  labelPriceVariance: 'Price Variance',\n  labelImpactExtraNewGreat:\n    'This trade will result in a loss of {{value}}% of the position’s market value. To proceed, tap ‘Proceed Anyway’ to confirm you understand and acknowledge the risk.',\n  labelPriceImpact: 'Price Impact',\n  labelPriceImpactDes1:\n    'This trade will affect the pool price by more than {{value}}%，which is too high. It may result in significant slippage and potential losses. If you acknowledge the risk and wish to proceed, type the <t>‘AGREE’</t> and tap ‘Proceed Anyway’ to confirm again.',\n  labelPriceImpactDes2:\n    'This trade will affect the pool price by more than {{value}}%，which is too high. It may result in significant slippage and potential losses. To proceed, tap ‘Proceed Anyway’ to confirm you understand and acknowledge the risk.',\n  labelCopyCodeClip: 'Referral Code Copied to Clipboard!',\n  labelDepositPending: '{{l1Symbol}} to {{l2Symbol}} Pending',\n  labelWithDrawPending: '{{l2Symbol}} to {{l1Symbol}} Pending',\n  labelContactsEditContactBtn: 'Edit Contact',\n  labelLargePriceVariance: 'Large Price Variance',\n  labelHighPriceImpacTitle: 'High Price Impact Detected',\n  labelTimeoutAddressClick:\n    '{{l1Symbol}} account checking request was rejected or some unknown error occurred, please <a>retry</a>',\n  labelSmallOrderAlertLine: 'Small trades (below ~$100) incur a higher fee.',\n  labelLimitImpactTitle: 'Limit taker Order Requires Confirmation',\n  labelRedPacketViewType2: 'Exclusive',\n  labelRedPacketPlazaPublic: 'Public Plaza',\n  labelRedPacketPlazaPublicDes:\n    'Everyone in the Loopring community can participate in claiming the red packet',\n  labelRedPacketQRPublic: 'Public QR',\n  labelRedPacketQRPublicDes:\n    'Anyone that knows the QR code can participate in claiming the red packet',\n  labelRedPacketExclusive: 'Exclusive Red Packet',\n  labelRedPacketExclusiveDes: 'Only users that have received the red packet can claim it',\n  labelRedPacketHaveExclusive: 'You have {{count}} exclusive Red Packets.',\n  labelRedPacketExclusiveViewDetails: 'View Details >',\n  labelRedPacketCongratulations: 'Congratulations!',\n  labelExclusiveRedpacket: 'Exclusive Red Packets',\n  labelRedpacketExclusiveReady: 'You have {{count}} exclusive Red Packets ready',\n  labelRedpacketSentMaxLimit: 'Sent / Max Limit',\n  labelRedpacketCreateNew: 'Create New Red Packet',\n  labelRedpacketGiftRedPacket: 'Count of Red Packet with Gift',\n  labelRedpacketRedPacketscount: 'Total Red Packets',\n  labelRedpacketRevealTime: 'Reveal Time',\n  labelRedpacketRecipients: 'Red Packet Recipients >',\n  labelRedpacketRecipientList: 'Recipient List',\n  labelExclusiveWhitelistDes:\n    \"For whitelisted users, each Red Packet can accommodate a maximum of 10,000 addresses, while standard users are allowed up to 50 addresses per Red Packet. Whitelisted addresses include Loopring, our partners, or other verified members. If you're interested in being whitelisted, please contact us at support@loopring.io.\",\n  labelRedpacketTextimport: 'Text import',\n  labelRedpacketContactImport: 'Contact import',\n  labelRedpacketNotificationDisplay: 'Notification Display',\n  labelRedpacketRedDotDes: 'Recipients are alerted via a badge next to the Red Packets category',\n  labelRedpacketBadge: 'Badge',\n  labelRedpacketPopUp: 'Pop-up Notification',\n  labelRedpacketPopUpTooltip:\n    \"Whitelisted addresses include Loopring, our partners, or other verified members. If you're interested in being whitelisted, please contact us at support@loopring.io.\",\n  labelRedpacketPopPpDes:\n    'Recipients are alerted via a prominent display that highlights the contents of the RedPacket. (Limited to whitelisted users)',\n  labelRedpacketPrepareRedPacket: 'Prepare Red Packet',\n  labelRedPacketChooseTarget: 'Select existing red packet or create a new one',\n  labelRedPacketRecipientList: 'Recipient List',\n  labelRedPacketPublicTooltip:\n    'Your Red Packet is public, and everyone can participate in claiming it.',\n  labelRedPacketPrivateTooltip:\n    '<p>Your Red Packet is private, and only the addresses you specify can claim it.</p>' +\n    '<p>To create a new Exclusive Red Packet, please follow these steps:</p>' +\n    '<li>1. Select the type of Red Packet</li>' +\n    '<li>2. Specify the amount of Red Packets to be sent and the date/time for delivery</li>' +\n    '<li>3. Designate the recipients</li>' +\n    '<li>4. Set the Notification Display</li>' +\n    '<p>For whitelisted users, each Red Packet can accommodate a maximum of 10,000 addresses, while standard users are allowed up to 50 addresses per Red Packet.</p>' +\n    \"<p>Whitelisted addresses include Loopring, our partners, or other verified members. If you're interested in being whitelisted, please contact us at support@loopring.io.</p>\",\n  labelRedpacketExclusiveEmpty: 'Your Prepared but unaddressed red packets will be displayed here!',\n  labelRedpacketExclusiveSelected: 'Selected: {{count}}',\n  labelRedpacketExclusiveManualEdit: 'Manual Edit',\n  labelRedpacketValidAddresses: 'Valid Addresses: {{count}}',\n  labelRedpacketTips: 'Tips',\n  labelRedpacketChangeImportTips:\n    'If you change the import method, the previously selected addresses will be erased, are you sure you want to erase them?',\n  labelRedpacketAddressesReview: 'Addresses Review',\n  labelRedpacketAddressesReviewPart1: 'The list contains {{count}} valid addresses,',\n  labelRedpacketAddressesReviewPart2: '{{count}} invalid addresses',\n  labelRedpacketAddressesReviewPart3:\n    '. To proceed, invalid addresses will be automatically removed from the list.',\n  labelRedpacketExclusiveListEmpty:\n    'Your Prepared but unaddressed red packets will be displayed here!',\n  labelRedpacketreceiptListEmpty: 'The addresses of the red packet you sent will be displayed here',\n  labelRedpacketBestwishes: 'Best wishes',\n  labelSendRedPacketTitleExclusive: 'Send Red Packet -- Exclusive',\n  labelSendRedPacketClear: 'Clear',\n  labelSendRedPacketMax: 'Max: {{count}}',\n  labelRedPacketMaxValueExceeded: 'Maximum value exceeded',\n  labelRedPacketTotal: 'Total {{count}}',\n  labelRedPacketExclusiveTag: 'Exclusive',\n  labelRedPacketClaiming: 'Claiming',\n  labelRedPacketReceiptsList: 'Red Packet Receipt >',\n  labelEOA: 'EOA',\n  labelLoopringWallet: 'Loopring',\n  labelOtherSmart: 'Other Smart',\n  labelBinance: 'Binance',\n  labelHuobi: 'Huobi',\n  labelOtherExchange: 'Other Exchange',\n  labelContactsEditContact: 'Edit Contact',\n  labelLeverageETHStakingDes: 'Gain higher APY aggressively',\n  labelDownloadShared: 'Download',\n  labelShareReferralCode: 'Share to',\n  labelShareMessage:\n    'Join me at Loopring and earn exclusive rewards with Loopring Referral Program! https://www.loopring.io/#/?referralcode={{code}}',\n\n  labelInvestDualAutoTitle: \"What's Auto Reinvest\",\n  labelDualAutoTitle: 'Auto Reinvest <1></1>',\n  labelDualAutoTitleDes:\n    'Auto Reinvest will automatically reinvest your investment and earned interest into a new term with the same Target Price once the previous term expires, continuing until you successfully buy or sell crypto. If there isn’t an available product within 2 hours after the previous settlement, the order will be automatically closed and your investment and earned interest will be unlocked.\\n',\n  labelInvestDualAutoCheck:\n    '<p>Auto Reinvest will automatically reinvest your investment and earned interest into a new term with the same Target Price once the previous term expires, continuing until you successfully buy or sell crypto. If there isn’t an available product within 2 hours after the previous settlement, the order will be automatically closed and your investment and earned interest will be unlocked.</p><p> Reinvest Target Price: The Target Price at which you want to buy or sell crypto.</p><p> Longest Settlement Date: The maximum duration available for selecting the settlement period. Auto Reinvest will automatically match products with settlement periods that do not exceed the Longest Settlement Date.</p>',\n  labelDualAutoDetail:\n    'Auto Reinvest will try to find a new product which based on the following rule at 16:00 on the settlement day.',\n  labelDualAutoDUAL_BASEPrice: 'Sell Price <1></1>',\n  labelDualAutoDUAL_CURRENCYPrice: 'Buy Price <1></1>',\n  labelDualAutoDUAL_BASEPriceDes: 'The target price at which you want to sell crypto.',\n  labelDualAutoDUAL_CURRENCYPriceDes: 'The target price at which you want to buy crypto.',\n  labelDualModifyParameter: 'Modify Parameter',\n  labelDayDisplay: '{{item}} Day(s)',\n  labelDualModifyConfirm: 'confirm',\n  labelDualAutoDurationDes:\n    'The maximum duration when selecting the settlement period. Auto Reinvest will automatically match products with settlement periods that do not exceed the Longest Settlement Date.',\n  labelDualModifyBtn: 'Modify',\n  labelTurnOffDualAutoInvest: 'Stop Auto Invest',\n  labelDualModifyAPR: 'APR: {{value}}',\n  labelDualModifySettlementDateDes: 'Changes will take effect after the Next Settlement Date.',\n  labelDualModifySettlementDate: 'Next Settlement Date: {{date}}',\n  labelDualEditSuccess: 'Update successful!',\n  labelDualEditFailed: 'Update Failed!',\n  labelDualEditDuration: 'Modify Longest Settlement Date <1></1>',\n  labelDualEditDurationDes:\n    'The maximum duration when selecting the settlement period. Auto Reinvest will automatically match products with settlement periods that do not exceed the Longest Settlement Date.',\n  labelDualInvestGuid: 'Invest',\n  labelCoverGain: 'Covered Gain',\n  labelCoverGainDes: 'Earn interest before taking profits',\n  labelDip: 'Buy The Dip',\n  labelDipDes: 'Earn interest while waiting for your price target',\n  labelDualMerge: 'Dual Investment',\n  labelDualMergeDes: 'Select based on Token and Settlement Date',\n  labelDualChooseTokenDUAL_BASE: 'Step 1: Choose a token to sell',\n  labelDualChooseTargetPriceDUAL_BASE: 'Step 2: Choose Target Price and Settlement Date',\n  labelDualChooseTokenDUAL_CURRENCY: 'Step 1: Choose a token to buy',\n  labelDualChooseTargetPriceDUAL_CURRENCY: 'Step 2: Choose Target Price and Settlement Date',\n  labelDualTypeDualGain: 'Covered Gain',\n  labelDualTypeDualDip: 'Buy The Dip',\n  labelDualTypeDualBegin: 'Dual Investment',\n  labelDualTypeAll: 'Dual Investment',\n  labelDualAutoCancelConfirm: 'Disable Auto Reinvest',\n  labelDualAutoCancelOrder: 'Cancel',\n  labelDualAutoCancelConfirmDes:\n    'Are you sure about disable auto reinvest? If disabled, there will be no new orders after the next settlement.',\n  labelDualModifySettlementDateDialog: 'Next Settlement Date',\n  labelDefiRate: 'Rate',\n  labelDefiLido: 'Lido',\n  labelDefiRocketPool: 'Rocket Pool',\n  labelDualIsHigh: 'is significantly higher',\n  labelDualIsLow: 'is significantly lower',\n  labelDualAutoAlert:\n    \"The current price of {{base}} is {{currentPrice}} {{quote}}, which  {{method}}  than the price you've set for Auto Reinvest. This may result in a lower APY for your next settlement. You can adjust the price for Auto Reinvest.\",\n  labelDualAutoDuration: 'Longest Settlement Date <1></1>',\n  labelInvestDualGainTitle: 'What is Covered Gain?',\n  labelInvestDualGainGuid:\n    '<p>Covered Gain is an investment strategy to sell digital assets at your Target Price and earn interest while waiting.</p>' +\n    '<p>On the Settlement Date, there can be 2 scenarios:</p>' +\n    '<ol><li>Market Price > Target Price</li>' +\n    '<li>Market Price ≤ Target Price</li></ol>' +\n    '<h5>Market Price > Target Price</h5>' +\n    '<p>Your original investment and earned interest will be sold at the target price.</p>' +\n    '<p>This order is then closed regardless of whether \"Auto Reinvest\" is enabled or not.</p>' +\n    '<h5>Market Price ≤ Target Price</h5>' +\n    '<p>Your original investment and earned interest won’t be sold.</p>' +\n    '<p>If you enable the “Auto Reinvest” feature, Loopring will automatically subscribe to a suitable dual investment product based on the agreed terms until you either successfully sell crypto at your desired price or disable the feature.</p>' +\n    '<h5>Auto Reinvest</h5>' +\n    '<p>When you enable the “Auto Reinvest” feature, Loopring will automatically reinvest your funds into a new product with the same target price when the previous product expires, continuing until you successfully sell your crypto at your Target Price. If there isn’t an available product within 2 hours after the previous settlement, the order will be automatically closed.</p>' +\n    '<p>Sell Price: the Target Price at which you want to sell your crypto.</p>' +\n    \"<p>Longest Settlement Date: your acceptable investment period. If no suitable products are available within this range, “Auto Reinvest” will not subscribe to any products for you, even if it's enabled.</p>\",\n  labelInvestDualDipTitle: 'What is Buy The Dip?',\n  labelInvestDualDipGuid:\n    '<p>Buy The Dip is an investment strategy to buy digital assets at your Target Price and earn interest while waiting.</p>' +\n    '<p>On the Settlement Date, there can be 2 scenarios: </p>' +\n    '<ol><li>Market Price > Target Price </li>' +\n    '<li>Market Price ≤ Target Price </li></ol>' +\n    '<h5>Market Price > Target Price</h5>' +\n    '<p>Your original investment and earned interest won’t be converted. Earned interest is in USDC or USDT.</p>' +\n    '<p>If you enable the “Auto Reinvest” feature, Loopring will automatically subscribe to a suitable dual investment product based on the agreed terms until you either successfully buy crypto at your desired price or disable the feature.</p>' +\n    '<h5>Market Price ≤ Target Price</h5>' +\n    '<p>Your original investment and earned interest will be converted at the Target Price.</p>' +\n    '<p>This order is then closed regardless of whether \"Auto Reinvest\" is enabled or not.</p>' +\n    '<h5>Auto Reinvest</h5>' +\n    '<p>When you enable the “Auto Reinvest” feature, Loopring will automatically reinvest your funds into a new product with the same target price when the previous product expires, continuing until you successfully buy crypto at your desired price. If there isn’t an available product within 2 hours after the previous settlement, the order will be automatically closed.</p>' +\n    '<p>Buy Price: the Target Price at which you want to buy crypto.</p>' +\n    '<p>Sell Price: the Target Price at which you want to sell crypto.</p>' +\n    \"<p>Longest Settlement Date: your acceptable investment period. If no suitable products are available within this range, “Auto Reinvest” will not subscribe to any products for you, even if it's enabled.</p>\",\n  labelAssetDualInvests: 'Dual Investment',\n  labelTxGuardian_upgrade_contract: 'upgrade contract',\n  labelTxGuardian_approve_token: 'approve token',\n  labelContactNameExisted: 'Name already exists',\n  labelContactAddressExisted: 'Address already exists',\n  labelL1toL2ThirdPartOn: 'On-ramp Crypto',\n  labelL1toL2ThirdPartOff: 'Off-ramp Crypto',\n  labelTargetRedpacketOption1: 'Option 1',\n  labelTargetRedpacketCreateTitle:\n    'The following steps are required to create a new Exclusive Red Packet',\n  labelTargetRedpacketCreateStep1: '1. Select the type of red packet to be sent.',\n  labelTargetRedpacketCreateStep2: '2. Number of red packets to be sent/transmission time',\n  labelTargetRedpacketCreateStep3: '3. Designated Red Packet Recipients',\n  labelTargetRedpacketCreateStep4: '4. Notification display for red packet recipients',\n  labelTargetRedpacketNoRedpacket: 'You do not have an existing wallet yet',\n  labelTargetRedpacketNoRedpacketDes:\n    'If your prepared but unaddressed Red Packets will be displayed here !',\n  labelTargetRedpacketOption2: 'Option 2',\n  labelEarnVaultTitle: 'Loopring DeFi Assets',\n  labelDualBTC: 'ETH - WBTC Dual Investment',\n  labelDualBTCDes: 'Select based on Token and Settlement Date',\n  labelDualTypeDualBTC: 'ETH - WBTC Dual Investment',\n  labelDualNewPriceLessThan: 'if {{base}} < {{value}} {{quote}}',\n  labelDualNewPriceLessOrEqualThan: 'if {{base}} ≤ {{value}} {{quote}}',\n  labelDualNewPriceGreaterThan: 'if {{base}} > {{value}} {{quote}}',\n  labelDualNewPriceGreaterThanOrEqual: 'if {{base}} ≥ {{value}} {{quote}}',\n  labelInputMax: 'Max',\n  labelTokenEnterDualToken: 'Amount',\n  labelTokenMaxBalance: 'Available Balance',\n  labelInvestMiniDual: 'Min {{value}}',\n  labelDualAutoSearchingDes: 'Auto reinvesting. Searching for the product...',\n  labelDualAutoInvestTip: 'Auto Reinvest Status:{{}}',\n  labelDualRetryStatusSuccess:\n    'Auto reinvested successful. A new order has been generated for you.',\n  labelDualRetryStatusError:\n    'Auto reinvest failed. Cannot find product with Buy Price of {{price}} and Longest Settlement Date of {{day}} days. ',\n  labelDualRetryStatusRetrying: 'Auto reinvesting. Searching for the product...',\n  labelDualRetryPending: 'Pending',\n  labelDualRetryTerminated: 'Terminated',\n  labelDualRetryFailed: 'Failed',\n  labelDualRetrySuccess: 'Success',\n  labelDualRetryStatusTerminated:\n    'Auto Reinvest terminated. You successfully purchased the target token.',\n  labelInvestmentStatusSettled: 'Settled',\n  labelInvestmentStatusDelivering: 'Delivering',\n  labelInvestmentStatusSubscribe: 'Earning',\n  labelDualTxsSettlement: 'Settlement',\n  labelDualAuto: 'Auto Reinvest',\n  labelDualAssetReInvestEnable: 'Enabled',\n  labelDualDeliver: 'Settlement Price',\n  labelDualAssetReInvestDisable: 'Disabled',\n  \n  labelUnlockErrorLine2Part1: 'If you are using an MPC wallet (such as the OKX keyless wallet), the signature may produce random results, which can lead to sign-in failures. In such cases, you may need to ',\n  labelUnlockErrorLine2Part2: 'reset your EDDSA key',\n  labelResetLoopringL2: 'Reset Loopring L2 keypair',\n  labelResetlockedReset1:\n    \"Please note that if you have pending Dual Investment subscriptions, the L2 keypair reset won't take immediate effect. Your wallet's L2 account will remain locked until all subscriptions have settled. While locked, you won't be able to perform any L2 operations.\",\n  labelResetlockedReset2:\n    'Additionally, any pending limit orders will be canceled since they are tied to the old L2 keypair.',\n  labelResetunlockedWithDual1:\n    \"We’ve detected that you have an active Dual Investment subscription. As a result, the L2 keypair reset won't take effect immediately. Instead, your wallet's L2 account will remain locked until all subscriptions have settled. While locked, you won't be able to perform any L2 operations.\",\n  labelResetunlockedWithDual2:\n    'Additionally, any pending limit orders will be canceled since they are tied to the old L2 keypair.',\n  labelResetunlockedWithoutDual:\n    'Resetting the L2 keypair will cancel all pending limit orders as they tied to the old L2 keypair.',\n  labelDualAutoReinvest: 'Auto Reinvest',\n  labelInvestDualTutorialContent2:\n    '<h6>Auto Reinvest</h6>' +\n    '<p>When you enable the “Auto Reinvest” feature, Loopring will automatically reinvest your funds into a new product with the same target price when the previous product expires, continuing until you successfully buy crypto at your desired price. If there isn’t an available product within 2 hours after the previous settlement, the order will be automatically closed.</p>' +\n    '<p>Buy Price: the Target Price at which you want to buy crypto.</p>' +\n    '<p>Sell Price: the Target Price at which you want to sell crypto.</p>' +\n    \"<p>Longest Settlement Date: your acceptable investment period. If no suitable products are available within this range, “Auto Reinvest” will not subscribe to any products for you, even if it's enabled.</p>\",\n  labelNoticeTitle: 'Notifications',\n  labelNotificationTime: '{{time}}',\n  labelNotificationClear: 'Clear all',\n  labelNotificationReadAll: 'Mark all as read',\n  labelNotificationLabel: 'Notification',\n  labelActiveL1successfulNote: 'Active {{ethereumL1}} successful',\n  labelActiveL2successfulNote: 'Active {{loopringL2}} successful',\n  labelActivatingL1AccountNote: 'Activating {{ethereumL1}} successful',\n  labelL1ReceiveNote: 'Receive token in {{ethereumL1}}',\n  labelL1SendNote: ' Send token from {{ethereumL1}}',\n  labelL2ReceiveNote: 'Receive token in {{loopringL2}}',\n  labelL2SendNote: 'Send token from {{loopringL2}} successful',\n  labelL2DepositNote: 'Receive token in {{loopringL2}}',\n  labelL2WithdrawNote: 'Send token in {{loopringL2}}',\n  labelTotalUnRead: '{{total}} unread(s)',\n  labelReadAll: 'View all',\n  labelDualDefaultAutoTitle: 'Default Enable Auto Reinvest',\n  labelDualLongestSettlementDuration: 'Modify Longest Settlement Date',\n  labelDualLongestSettlementFixed: 'Fixed',\n  labelDualLongestSettlementAutomatic: 'Automatic',\n  labelDualSettingConfirm: 'Confirm',\n  labelLuckyTokenNormal: 'Normal',\n  labelRedPacketSendAverageTitle: 'Average Red Packet',\n  labelBlindBoxHint:\n    'Each recipient will receive a sealed Red Packet which cannot be opened until the expiration date. While some recipients will receive an NFT, others will need to try their luck next time.',\n  labelNormalRedPacketTitle: 'Normal Red Packet',\n  labelL2DualNote: 'Dual Investment Notification',\n  labelQuickInvest: 'Quick Invest',\n  labelReceiveToken: 'Receive',\n  labelETHStakingEnterPaymentToken: 'Amount',\n  labelDefiDuration: 'Duration',\n  labelFlexible: 'Flexible',\n  labelEstAPR: 'Est.APR',\n  labelTradingFeeTooltips:\n    \"The trading fee is determined by the size of your trade. Usually, it's 0.1% of your total converted amount; or the necessary fee that covers the transaction cost for small transactions.\",\n  labelHideRead: 'Hide Read(s)',\n  labelL2NFTBurnTitle: 'Burn NFT',\n  labelL2NFTBurnBtn: 'Burn NFT',\n  labelENSAlert:\n    \"ENS & Address Mismatch. Before proceeding with the transfer, we recommend updating the contact's information for accuracy.\",\n  labelSendToContact: 'Send to',\n  labelContactENSAlert:\n    \"ENS & Address Mismatch. Before proceeding with the transfer, we recommend updating the contact's information for accuracy.\",\n  labelUpdateContactsNext: 'Go to Update Contact',\n  labelENSAddressMismatch: 'ENS & Address Mismatch',\n\n  labelVault: 'Portal',\n  labelVaultHome: 'Home',\n  labelVaultDashboard: 'Dashboard',\n  labelVaultRefresh: 'Refresh',\n  labelVaultAddBtn: 'Margin Call',\n  labelVaultJoinBtn: 'Supply Collateral',\n  labelVaultCheckInProcessing: 'Checking Portal status',\n  labelVaultRecord: 'Records',\n  labelEnterToken: 'Select Token',\n  labelVaultExitBtn: 'Settle',\n  labelVaultLoanBtn: 'Loan',\n  labelVaultTutorial: 'Tutorial',\n  labelVaultTotalToken: 'Portal Token',\n  labelVaultJoinMini: 'Minimum of {{arg}}',\n  labelVaultJoinMax: 'Maximum of {{arg}}',\n  labelVaultJoinNotEnough: 'Insufficient {{arg}} balance',\n  labelVaultJoinMarginTitle: 'Add Collateral',\n  labelVaultJoinTitle: 'Supply Collateral',\n  labelVaultTradeBtn: 'Portal Trade',\n  labelVaultRedeemBtn: 'Settle',\n  labelVaultExitDes:\n    'Upon closing your position, all open orders will be canceled, and any outstanding debts will be automatically repaid. If the available balance of the Portal_Token is insufficient to cover the debt, Loopring will sell a portion of your assets at the market price to repay the debt. The remaining Portal_Token will be converted to the token you have staked at the current market price and returned to your {{loopringL2}} Account.',\n  labelVaultConfirm: 'Confirm',\n  labelVaultCancel: 'Cancel',\n  labelVaultExitTitle: 'Settle',\n  labelVaultSwapBtn: 'Swap',\n  labelVaultSwap: 'Portal Trade',\n  labelVaultType: 'Type',\n  labelVaultTypeOpenPosition: 'Supply Collateral',\n  labelVaultStatus: 'Status',\n  labelVaultJoinStatus: '{{status}} {{percentage}}',\n  labelVaultTradeStatus: '{{status}} {{percentage}}',\n  labelVaultCollateral: 'Collateral',\n  labelVaultReceive: 'Receive',\n  labelVaultTime: 'Time',\n  labelVaultExitType: 'Type',\n  labelVaultExitTypeClose: 'Settle',\n  labelVaultExitStatusLabel: 'Status',\n  labelVaultExitStatus: '{{status}}',\n  labelVaultExitStatusSuccess: 'Success',\n  labelVaultExitTotalBalance: 'Total Balance',\n  labelVaultExitTotalDebt: 'Total Debt',\n  labelVaultExitTotalEquity: 'Total Equity',\n  labelVaultExitProfit: 'Profit',\n  labelVaultExitProfitPercentage: 'Profit Percentage',\n  labelVaultExitTime: 'Time',\n  labelVaultExitStatusPending: 'Pending',\n  labelVaultExitCloseAmount: 'Redeem Token',\n  labelVaultExitPendingDes:\n    'The request is being processed and is expected to take 1-2 minutes. Please be patient.',\n  labelVaultBorrow: 'Borrow',\n  labelVaultRepay: 'Repay',\n  labelVaultTotalQuoteDes:\n    'Total Quota is the maximum amount available  for you to be used as collateral.',\n  labelVaultTokenQuoteDes:\n    'When provide the token as collateral, you will receive an equivalent amount of Portal Token.',\n  labelTitleVaultDes:\n    'Loopring Portal can be treated as an isolated margin account allowing users to borrow/lend tokens with collateral. Other than leveraged trading, it also allows users to trade hot tokens that are not available in Loopring DEX with CEX liquidity.',\n  labelTitleVault: 'Portal',\n  labelVaultHomeTitle: 'Dashboard',\n  labelVaultDashboardTitle: 'Dashboard',\n  labelVaultTotalBalance: 'Total Balance',\n  labelVaultOpenDate: 'Open Date:',\n  labelVaultMarginLevel: 'Margin Level',\n  labelVaultTotalCollateral: 'Total Collateral',\n  labelVaultTotalDebt: 'Total Debt',\n  labelVaultTotalEquity: 'Total Equity',\n  labelVaultProfit: 'Profit',\n  labelVaultCloseBtn: 'Close',\n  labelGoVaultDashBoard: 'Go to Dashboard',\n  labelVaultBrowserToken: 'Amount',\n  labelVaultQuotaTooltips: 'PortalQuoteDes',\n  labelVaultQuota: 'Total Quota',\n  labelVaultBorrowMini: 'Minimum of {{arg}}',\n  labelVaultBorrowNotEnough: 'Exceeded Maximum Borrowable Amount',\n  labelVaultBorrowMax: 'Maximum of {{arg}}',\n  labelVaultBorrowBtn: 'Borrow',\n  labelVaultBorrowStatusLabel: 'Status',\n  labelVaultBorrowTypeLabel: 'Type',\n  labelVaultBorrowAmountLabel: 'Amount',\n  labelVaultBorrowStatus: '{{status}}',\n  labelVaultBorrowTitle: 'Borrow',\n  labelPending: 'Pending',\n  labelVaultRepayMini: 'Minimum of {{arg}}',\n  labelVaultRepayNotEnough: 'Insufficient balance',\n  labelVaultRepayMax: 'Maximum of {{arg}}',\n  labelVaultRepayBtn: 'Repay',\n  labelRepayQuota: 'Borrowed',\n  labelVaultWhatis: 'What is Loopring Portal?',\n  labelVaultDesSimple:\n    '<p>Portal: Using a third-party funds to trade assets. Traders can access additional capital, amplifying trading results.</p>',\n  labelVaultRiskDes:\n    '<p>Loopring Portal acts as an isolated margin account, enabling users to borrow and lend tokens with collateral. Besides supporting leveraged trading, it also facilitates the trading of tokens not available on Loopring DEX by tapping into CEX liquidity depth. </p>' +\n    \"<p>It's important to note that all assets in Portal are hedged on CEX, incurring an associated cost known as the Asset Holding Fee, charged on an hourly basis. We strongly recommend closing your position if it's no longer needed for trading to reduce costs.</p>\" +\n    '<p>In order to initiate the forced clearing of assets in the event of liquidation, Loopring will require your approval to handle the collateral asset. Additionally, after closing a position, there may be some remaining Portal tokens in your account that Loopring will need to clear before allowing you to open a new position.</p><ul>' +\n    '<li>There is an Asset Holding Fee for assets in Portal.</li>' +\n    '<li>I will grant Loopring authority to deal with my collateral in case of forced liquidation.</li>' +\n    '<li> I will grant Loopring the authority to clear all previously remaining Lv tokens for all new position openings in Portal.</li></ul>',\n  labelVaultRepayTitle: 'Repay',\n  labelVaultRepayStatus: '{{status}}',\n  labelVaultRepayStatusLabel: 'Status',\n  labelVaultRepayTypeLabel: 'Type',\n  labelVaultRepayType: 'Repay',\n  labelVaultRepayTotalBalance: 'Amount',\n  labelVaultVAULT_STATUS_RECEIVED: 'Received',\n  labelVaultVAULT_STATUS_PROCESSING: 'Processing',\n  labelVaultVAULT_STATUS_SUCCEED: 'Success',\n  labelVaultVAULT_STATUS_FAILED: 'Failed',\n  labelVaultVAULT_STATUS_PENDING: 'Pending',\n  labelVaultAccountWait: 'Portal account in loading...',\n  labelVaultInRedeemWaiting: 'Portal account is in process of settle...',\n  labelVaultJoinSymbolNotSame: 'Only {{symbol}} allow Margin Call',\n  labelVaultRepaySuccess: 'Success',\n  labelVaultJoinSuccess: 'Success',\n  labelVaultRedeemSuccess: 'Success',\n  labelVaultBorrowSuccess: 'Success',\n  labelVaultTradeSuccess: 'Success',\n  labelVaultRepayInProgress: 'Processing...',\n  labelVaultRedeemInProgress: 'Processing...',\n  labelVaultBorrowInProgress: 'Processing...',\n  labelVaultTradeInProgress: 'Processing...',\n  labelVaultJoinInProgress: 'Processing...',\n  labelVaultRepayFailed: 'Failed',\n  labelVaultRedeemFailed: 'Failed',\n  labelVaultBorrowFailed: 'Failed',\n  labelVaultJoinFailed: 'Failed',\n  labelVaultTradeFailed: 'Failed',\n  labelLayer2HistoryVaultRecords: 'Portal',\n  labelVaultTitleRisk: 'What is Loopring Portal?',\n  labelProTime1h: '1h',\n  labelProTime1d: '1d',\n  labelProTime1w: '1w',\n  labelStats: 'Stats',\n  label24PriceChange: '24h Price Change',\n  label7dPriceChange: '7d Price Change',\n  labelVaultREDEEMPendingBtn: 'Settle in Processing',\n  labelVaultlnredeemWaiting: 'Settle in Processing',\n  labelJoinTitle: 'Supply Collateral',\n  labelRedeemTitle: 'Settle',\n  labelRedeemDesMessage:\n    'Please be aware that there may be a brief waiting period due to automatic liquidation. We appreciate your patience and assure you that we are working to process your request as quickly as possible. Thank you for your understanding.',\n  labelJoinDesMessage:\n    'Please open a position first.',\n  labelFailed: 'Failed',\n  labelVAULT_COLLATERAL: 'Portal Collateral',\n  labelTokenVaultDes:\n    '{{symbol}} in Portal is a token backed 1:1 with {{symbol}}, bringing greater liquidity to Loopring DEX.',\n  labelTokenWebsite: 'Website',\n  labelTokenContractAddress: 'Contract Address',\n  labelTokenSupply: 'Total Supply',\n  labelMarketCap: 'Market Cap',\n  labelTokenInfo: 'Token Info',\n  labelTokenIntroduce: 'Introduction',\n  labelVaultRedeemDetail: 'Details',\n  labelCloseOutDetail: 'Settle',\n  labelVaultTradeTitle: 'Portal Trade',\n  labelVaultPrice: 'Price',\n  labelVaultSell: 'Sell',\n  labelVaultBuy: 'Buy',\n  labelVaultFee: 'Trade Fee',\n  labelVaultJoin: 'Supply Collateral',\n  labelVaultMarginCall: 'Add Collateral',\n  labelVaultMaxBrowserLabel: 'Max borrowable: ',\n  labelVaultBorrowed: 'Borrowed',\n  labelVaultRepayBalance: 'Total Balance',\n  labelVaultPendingDes:\n    'The request is being processed and is expected to take 1-2 minutes. Please be patient.',\n  labelVaultTotalDebtTooltips:\n    'Total Debt is comprised of two parts: loans and the cost incurred from utilizing the capital. The cost is determined by multiplying the Total Balance by the Funding Rate, which will accumulate on an hourly basis.',\n  labelVaultMarginLevelTooltips:\n    'Margin Level provides an indication of how close your account is to experiencing a margin call or being liquidated. To avoid liquidation, you can either supply more collateral or repay borrowed positions.',\n  labelVaultActiveLoanAlert:\n    'You currently have an active loan order in progress. This may affect the available tokens for trading. Please proceed with caution.',\n  labelVaultSwapBorrowTip: 'Max is sum of Holding and Borrowable tokens. When the swap amount exceeds the available balance, it will automatically borrow tokens. This Amount is the borrowed quantity.',\n  labelVaultSwapBorrow: 'Max:',\n  labelVaultSwapHoldTip:\n    'When the swap amount exceeds the available balance, it will automatically borrow tokens. This Amount is the borrowed quantity.',\n  labelVaultSwapHold: 'Holding:',\n  labelTobeBorrowedtips:\n    'When the swap amount exceeds the available balance, it will automatically borrow tokens. This Amount is the borrowed quantity.',\n  labelTobeBorrowed: 'To be Borrowed',\n  labelStep1Borrow: 'STEP1: Borrow',\n  labelStep2Swap: 'STEP2: Swap',\n  labelVaultSwapCancel:\n    'You are currently borrowing tokens. \\nAre you sure you want to exit the current transaction?',\n  labelAgree: 'I know',\n  labelTradeVaultMiniBorrow:\n    'The minimum borrowing amount is {{arg}}, so the amount you trade should be greater than {{arg1}}',\n  labelVaultTradeSimpleBtn: 'Trade',\n  labelBorrowing: 'Borrowing {{value}} {{symbol}}',\n  labelBorrowed: 'Borrowed {{symbol}}',\n  labelBorrowSwap: 'Borrow & Swap',\n  labelVaultTradeInsufficient: 'Insufficient quota',\n  labelVaultActiveLoanError:\n    'Due to high borrowing demand, there are currently insufficient loanable assets for {{symbol}}. You can continue trading with the tokens you hold or choose to Cancel.',\n  \n  labelL2NFTBurnTip:\n    'The NFT will be permanently sent to a burn address and unrecoverable. Please proceed with caution.',\n  labelL2NFTBurSuccess: 'Burned {{value}} {{symbol}} successfully!',\n  labelOpenPositionDetail: 'Supply Collateral Detail',\n  labelMarginCallDetail: 'Add Collateral',\n  labelBorrowDetail: 'Borrow',\n  labelRepayDetail: 'Repay',\n  labelTradeDetail: 'Trade',\n  labelVaultPlacedAmount: 'Placed Amount',\n  labelVaultExecutedAmount: 'Executed Amount',\n  labelVaultExecutedRate: 'Executed Rate',\n  labelVaultConvertedAmount: 'Converted Amount',\n  labelVaultTxFee: 'Fee',\n  labelBtradeExecutedAmount: 'Executed Amount',\n  labelBtradeExecutedAmountTip: 'The quantity successfully processed on the CEX side.',\n  labelBtradePlacedAmount: 'Placed Amount',\n  labelBtradePlacedAmountTip: `The quantity you invested in 'Block Trade' that you intend to execute.`,\n  labelBtradeExecutedRate: 'Executed Rate',\n  labelBtradeConvertedAmount: 'Converted Amount',\n  labelBtradeConvertedAmountTip: 'The quantity successfully converted from the CEX side',\n  labelBtradeSettledAmount: 'Settled Amount',\n  labelBtradeSettledAmountTip: `The quantity deposited into your Loopring L2 account. If you opt for 'Prioritize Quantity' mode and the Loopring L2 pool exhausts its quota, you may not receive the entire amount instantly. The remaining tokens will be 'swapped' at the executed price once the pool is replenished.`,\n  labelVaultExitTypeForcedLiquidation: 'Forced Liquidation',\n\n  labelVaultExecutedAmountTip: 'The quantity successfully processed on the CEX side.',\n  labelVaultPlacedAmountTip: `The quantity you invested in 'Portal Trade' that you intend to execute.`,\n  labelVaultConvertedAmountTip: 'The quantity successfully converted from the CEX side.',\n  labelVaultSettledAmountTip: `The quantity deposited into your Loopring L2 account. If you opt for 'Prioritize Quantity' mode and the Loopring L2 pool exhausts its quota, you may not receive the entire amount instantly. The remaining tokens will be 'swapped' at the executed price once the pool is replenished.`,\n  labelVaultActiveLoanError2:\n    'Borrowed {{value}} {{symbol}} failed.',\n  labelVaultActiveLoanSuccessful:\n    'Borrowed {{value}} {{symbol}} successful.',\n  labelVaultAmount: 'Amount',\n  labelVaultOpenPositionDes: 'Please open a position first.' ,\n  labelHourlyInterestRate: 'Hourly Interest Rate',\n  labelHourlyInterestRateTips: 'Interest Rate will change every hour based on current market conditions. Interest will accrue as soon as tokens are borrowed and it will continue to accrue every hour.',\n\n  labelVaultMarginLevelTooltips2:\n    'Margin Level = (Balance + Collateral) / Total Debt',\n  labelVaultMarginLevelTooltips3:\n    'Default Margin Level is 999.00',\n  labelVaultMarginLevelTooltips4:\n    'Low Risk: Margin Level ≥ 1.5',\n  labelVaultMarginLevelTooltips5:\n    'At Low Risk, your collateral is relatively sufficient. You should mainly focus on whether the market fluctuates violently and causes liquidation.',\n  labelVaultMarginLevelTooltips6:\n    'Middle Risk: 1.15 ≤ Margin Level < 1.5',\n  labelVaultMarginLevelTooltips7:\n    'At Middle Risk, it is recommended that you always pay attention to changes in market conditions and add collateral or repay borrowed tokens to reduce the risk of liquidation.',\n  labelVaultMarginLevelTooltips8:\n    'High Risk: {{liqMarginLevel}} ≤ Margin Level < 1.15',\n  labelVaultMarginLevelTooltips9:\n    'At High Risk, it is strongly recommended that you add collateral or repay borrowed tokens immediately to reduce the risk of liquidation.',\n  labelVaultMarginLevelTooltips10:\n    'Liquidation: Margin Level < {{liqMarginLevel}}',\n  labelVaultMarginLevelTooltips11:\n    'When Margin Level is lower than {{liqMarginLevel}}, the position will be liquidated.',\n  labelVaultCollateralManagement: 'Collateral Management',\n  labelGuardianCodeNetworkError: 'Network not match',\n  labelGuardianCodeAccountError: 'guardian not match current account',\n  labelGuardianCodeFormatError: 'wrong data format',\n  labelGuardianCodeOwner: 'Owner',\n  labelGuardianCodeRequestedWallet: 'Requested wallet',\n  labelGuardianCodeRequestType: 'Request Type',\n  labelGuardianCodeNetwork: 'Network',\n  labelGuardianCodeRequester: 'Requester',\n  labelGuardianCodeAuthorizationResult: 'Authorization Result',\n  labelGuardianCodeApproved: 'Approved',\n  labelGuardianCodeReject: 'Reject',\n  labelGuardianCodeApprove: 'Approve',\n  labelGuardianCodeShare: 'Share',\n  labelGuardianCodeNext: 'Next',\n  labelGuardianCodeEnterApprovalCode: 'Enter Approval Code',\n  labelGuardianCodeEnterApprovalCodeHint: 'Please enter the Approval Code',\n  labelGuardianCodeConfirmationDes: `Kindly approve the operation request from the wallet you are safeguarding. The approval\n  process is fee-free. For added security, we request you enter the authorization code\n  generated by the requester. If you haven't received this code, kindly synchronize with the\n  requester for the necessary information.`,\n  labelGuardianCodeSharingDes: `Please send the QR code to the requester`,\n  labelGuardianCodeSharingApprovalRequest: 'Approval Request',\n  labelGuardianNotWhoIProtect: 'Request not from who I protect',\n  labelEarnAssetDefiPortfolio: 'DeFi Portfolio',\n  labelEarnDepositDes: `There are no assets in your Loopring DeFi account yet. Please deposit a supported token to start exploring the DeFi world.`,\n  labelEarnAssetTokens: 'All Tokens',\n  labelBlockTradeTutorial: 'Block Trade Tutorial',\n  labelAccountCreatedHint: 'Your Loopring DeFi account has been created. Please sign to complete the process.',\n  labelFrozen: 'Frozen',\n  labelBTradeTutorial: `\n  Block Trade offers a secure and trustless way for users to swap tokens using CEX\n  liquidity. The trades happen exclusively between designated entities, ensuring that the\n  existing liquidity of the DEX remains unaffected. There is no price impact to other DEX\n  users as a result of the transaction.\n  `,\n  labelLearnMore: 'Learn More >',\n  labelLearnMore2: 'Learn More',\n  labelInvestDualDes: 'Buy the dip or sell the covered gain while earning a high yield',\n  labelPortalDes: 'Loopring Portal can be treated as an isolated margin account allowing users to borrow/lend tokens with collateral. ',\n  labelBtradeDes: 'Offers a secure and trustless way for users to swap tokens using CEX liquidity.',\n  labelAPY: 'APY',\n  labelAction2: 'Action',\n  labelTotalBalance: 'Total Balance',\n  labelBalance: 'Balance',\n  depositLabelEnterTokenEarn: 'Select Token',\n  labelLaunch: 'Launch',\n  labelSmartWalletDepositError1: 'Currently, only EOA wallets are supported.',\n  labelSmartWalletDepositError2: 'Loopring Smart Wallet support is coming soon ',\n  labelSmartWalletDepositError3: 'stay tuned for updates!',\n  labelDustCollectorDetail: 'Dust Collector',\n  labelVaultRedeem: 'Redeem Collateral',\n  labelVaultRedeemNotEnough: 'Exceeded the maximum {{arg}} redemption value',\n  labelVaultJoinRedeem: 'Redeem Collateral',\n  labelVaultCollateralDetails: 'Collateral Details',\n  labelVaultMaximumCredit: 'Maximum Credit',\n  labelVaultMaximumCreditDes: 'Maximum Credit means the maximum amount of money you can borrow from Portal based on your collateral.',\n  labelVaultMaximumCreditFormula: 'Maximum Credit = Sum ( Token_MarketPrice * Token_Amount * Token_PriceFactor ) * Maximum_Leverage',\n  labelVaultPriceFactor: 'The Price Factor of each collateral',\n  labelVaultMaximumLeverage: 'Maximum Leverage',\n  labelVaultLeverage: 'Leverage',\n  labelVaultAvailableBorrow: 'Borrowing Limit',\n  labelVaultLeverageRisk1: '· Selecting higher leverage will increase your liquidation risk.',\n  labelVaultLeverageRisk2: '· Borrowing Limit is based on the upper limit corresponding to the leverage you choose. The total value of all your borrowed tokens will not exceed the Borrowing Limit.',\n  labelVaultLeverageRisk3: '· Maximum Credit is the maximum amount you can borrow based on your collateral.',\n  labelVaultDebt: 'Debt Details',\n  labelVaultDebtDetails: 'Details',\n  labelVaultTotalBorrowed: 'Total Borrowed',\n  labelVaultTotalFundingFee: 'Total Funding Fee',\n  labelVaultValueEst: 'Value (est.)',\n  labelVaultDustCollectorDes: `The accumulated dust will be converted into corresponding USDT. If you do not have any USDT to be repaid, the converted amount will be deposited into your portal's USDT. `,\n  labelVaultConvert: 'Convert',\n  labelVaultMarginLevelAlert: 'Your margin level has reached a critical point. Please review your positions and considering adding additional collateral. Failure to address the margin call may result in forced liquidation.',\n  labelVaultDetail: 'Detail',\n  labelVaultDefaultLeverage: 'Default Leverage',\n  labelVaultHoldingCollateral: 'Holding Collateral',\n  labelVaultRedeemAlert: 'Collateral valued at more than twice your total debt can be withdrawn from your Portal account.',\n  labelTotalValue: 'Total Value',\n  labelVaultRepayment: 'Payment',\n  labelDetails: 'Details',\n  labelVaultErrorOccurred: 'An error has occurred. Please try again later.',\n  labelVaultDetails: 'Details',\n  labelVaultNoDust: 'No Dust to Collect',\n  labelVaultJoinAdd: 'Add Collateral',\n  labelVaultChangeLeverageFailed: 'Change Leverage Failed',\n  labelVaultChangeLeverageFailedTooSmall: `Leverage is smaller than permitted. Insufficient Available Borrow amount.`,\n  labelVaultDustCollectorUnavailableTitle: 'Feature Unavailable',\n  labelVaultDustCollectorUnavailableDes: 'This feature is temporarily unavailable. Please try again later.',\n  labelVaultMaximumCreditDesLong: 'Maximum Credit means the maximum amount of money you can borrow from Portal based on your collateral. It is calculated by taking the total value of your collateral, adjusted for price factor and the maximum leverage.',\n  labelVaultMarginLevelDes: 'Margin Level provides an indication of how close your account is to experiencing a margin call or being liquidated. To avoid liquidation, you can either supply more collateral or repay borrowed positions.',\n  labelLayer2HistoryTaikoLockRecords: 'Taiko Farming',\n  labelL2TaikoFarming: 'Taiko Farming',\n  labelTaikoFarmingNotChecked: 'Please check the above box',\n  labelTaikoFarmingUnlock: \"Unlock the Value of Your Locked TAIKO !\",\n  labelTaikoFarmingMintInfo: \"Mint lrTAIKO and use it in Loopring DeFi at zero cost!\",\n  labelTaikoFarming: \"Taiko Farming\",\n  labelTaikoFarmingDescription: \"Earn Trailblazers points 60x faster by locking TAIKO and participating in Taiko Farming. Please note that TAIKO can only be unlocked after the end of Trailblazers Campaign Season 2.\",\n  labelLock2: \"LOCK\",\n  labelEnterPaymentToken: \"Enter payment token\",\n  labelMax: \"Max\",\n  labelSelectToken: \"Select token\",\n  labelAcknowledgeAndProceed: \"I acknowledge and would like to proceed.\",\n  labelUnlockAfterSeason2: \"You can unlock your TAIKO tokens only after the end of Trailblazers Season 2.\",\n  labelCurrentLockedPosition: \"My Current Locked Position\",\n  labelTotalPoints: \"Total Points\",\n  labelDailyEarningPoints: \"Daily Earning Points\",\n  labelTaikoFarmingBannerTitle: \"Taiko Farming\",\n  labelTaikoFarmingBannerDes: \"Earn Trailblazers points 60x faster by locking TAIKO and participating in Taiko Farming. Please note that TAIKO can only be unlocked after the end of Trailblazers Campaign Season 2.\",\n  labelTaikoFarmingQuestion: \"Worried about missing trading or earning opportunities when locking your valuable TAIKO?\",\n  labelTaikoFarmingExplanation: \"Loopring lets you mint lrTAIKO at a 1:1 ratio, allowing you to freely use it across all trading and earning options within Loopring DeFi. Plus, you'll continue farming Trailblazers points.\",\n  labelTaikoFarmingComingSoon: \"The lrTAIKO mint feature is coming soon!\",\n  labelTaikoFarmingPortalIntegration: \"The first DeFi integration will be with Portal, allowing you to use lrTAIKO as collateral for leveraged trading on select hot tokens. You'll be able to go LONG or SHORT on your favorite tokens based on market conditions.\",\n  labelTaikoFarmingStayTuned: \"Stay tuned for the upcoming release—more exciting use cases are on the way!\",\n  labelTaikoFarmingExploreUseCase: \"Take a tour to explore all the current Loopring DeFi use cases \",\n  labelTaikoFarmingHereLink: \"<here>\",\n  labelTaikoFarmingDepositAnytime: \". You can deposit assets into Loopring DeFi anytime and start enjoying the experience!\",\n  labelTotalPointsDes: 'Please note that Trailblazers points are awarded directly by the Taiko team. The Loopring dashboard provides a reference for the points you may receive from Taiko, but if there are any discrepancies, the official results from Taiko will be the final and trusted source.',\n  labelInvestType_TAIKOFarming: 'Taiko Farming',\n  labelTaikoFarmingTrailblazerBooster: 'Trailblazers Booster',\n  labelTaikoFarmingPointsToBeTrackedRetroactively: 'Points to be tracked retroactively',\n  labelTaikoFarmingPointsToBeTrackedRetroactivelyDes: 'Loopring is actively working with the Taiko team to integrate Trailblazers points collected through Taiko Farming. You are guaranteed to receive 60x Trailblazers points by participating in this campaign. However, it may take a few days for the points to be retroactively tracked in the Taiko Trailblazers Leaderboard.',\n  labelTaikoFarmingLockSuccess: 'TAIKO Locked Successfully',\n  labelTaikoFarmingUnlockValue: 'Unlock The Value Of Your Locked TAIKO To Keep Trading Or Earning',\n  labelTotalPortfolio: 'Total Portfolio',\n  labelLoopringDeFiIs: 'Loopring DeFi is expanding to various EVM-compatible networks using its trustless, time-tested ZK-Rollup protocol. The first deployment will be on Taiko. Join us for an exciting journey ahead!',\n  labelLoopringDeFiIs21: 'Loopring DeFi is expanding to various EVM-compatible networks using its trustless, time-tested ZK-Rollup protocol. The first',\n  labelLoopringDeFiIs22: 'deployment will be on Taiko. Join us for an exciting journey ahead!',\n  labelLoopringDeFiAssets: 'Loopring DeFi Assets',\n  labelSendAssetToTaikoAccount: 'To Taiko',\n  labelL1toL2WaitForAuthTaikoEarn: 'Your {{symbol}} is being deposited into the {{loopringL2}} Protocol and may take a few moments to complete.',\n  labelTaikoFarmingMintSuccess: 'Success',\n  labelTime: 'Time',\n  labelTaikoFarmingMintInfoDes: 'You can freely use lrTAIKO across all trading and earning options within Loopring DeFi.',\n  labelTaikoFarmingMintVisitPortal: 'Visit Portal to use lrTAIKO as collateral to earn >',\n  labelLockTAIKO: 'Lock TAIKO',\n  labelTaikoLockEarn: 'Earn Trailblazers points with up to a 60x multiplier by locking your TAIKO.',\n  labelTaikoLockEnjoyComplete: 'Enjoy complete control over your locking duration by choosing any period that suits you. Trailblazers points will be awarded linearly based on the length of your lock. Plus, your locked TAIKO remains usable within Loopring’s DeFi ecosystem! Use it as collateral to continue trading and earning, maximizing your capital efficiency even while it’s locked.',\n  labelTaikoFarmingMintRiskReminder: 'Risk Reminder: You can use minted lrTAIKO as collateral across other Loopring DeFi utilities. However, if you incur any losses during your investment, those losses will be deducted from your locked TAIKO upon unlocking.',\n  labelCompleteSignIn: 'Complete Sign in',\n  labelSignIn: 'Sign in',\n  labelComplete: 'Complete',\n  labelStartMintlrTAIKO: 'Start Mint lrTAIKO',\n  labelCompleteSignInDes: 'You need to activate Loopring DeFi account first before minting. Please sign in to proceed.',\n  labelLocked: 'Locked',\n  labelTAIKO_FARMING: 'Taiko Farming',\n\n  labelDefiCloseCian:\n    'The ciETH subscription has been deprecated. We recommend redeeming your ciETH for ETH as soon as possible. You can also explore other ETH staking portfolios for alternative options.',\n  labelUnlockErrorSupport1: 'The inability to unlock your wallet is most likely due to network conditions or browser-related issues. This can often be resolved by refreshing the page.',\n  labelUnlockErrorSupport2: 'If the problem persists after multiple attempts, please contact us directly at support@loopring.io and provide your wallet information. Our engineers will assist you in resolving the issue as soon as possible. Thank you for your understanding.',\n  labelVaultMarketTitle: 'Market',\n\n  labelUnlockErrorLine1Part1:\n    'The inability to unlock your wallet is most likely due to network conditions or browser-related issues. In many cases, simply refreshing the page can resolve the issue. If the problem persists after multiple attempts, try manually ',\n  labelUnlockErrorLine1Part2:\n    'resetting your Loopring EDDSA keypair ',\n  labelUnlockErrorLine1Part3:\n    'to resolve the issue',\n  labelVaultCloseShort: 'Close Short',\n  labelVaultTradeTabTitle: 'Trade',\n  labelVaultTradeTabDes: 'An isolated margin account',\n}\n\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/i18n/en_US/error.ts",
    "content": "export default {\n  labelConnectUsSimple: 'Please <1>contact us</1>.',\n  labelConnectUs:\n    'If you believe this is indeed a bug, please <1>&nbsp; contact us</1>. We would appreciate your feedback.',\n  errorBase: 'Oops! Something went wrong.',\n  errorTimeout: 'Oops! Something went wrong at network.',\n  errorLoading: 'Loading! Please wait...',\n  error404: \"404! Page can't be reached.\",\n  errorMaintain: 'System update! Please wait...',\n  errorMessageNoNetwork: 'Oops! Something went wrong at service.',\n  errorUnknown: 'Unknown Error',\n  errorOnFromSubmit: 'Submit request Info has Error!',\n  errorWrongAccount: 'Error on account Info!',\n  errorWrongToken: 'Error on Token Info!',\n  errorWrongApikey: 'Error on signature or no API key.',\n  errorWrongBalance: 'Insufficient balance',\n  errorMinimumOrder: 'Trade amount is minimum',\n  errorMaximumOrder: 'Trade amount is maximum',\n  errorOnFrozen: 'Some of your assets are frozen, please try again later.',\n  errorAboutFee: 'Fee token is not enough or incorrect.',\n  errorProviderError: 'Global ethereum is not {{name}}, please disable your other Wallet Plugin.',\n  errorOnStorageId: 'Error on wrong StorageId',\n  errorOnNoRecipient: 'Error on no Receiver',\n  errorNoMarket: 'Market is not supported.',\n  errorOnGas: 'Error on Gas Info',\n  errorOnCancelOrders: 'Error on cancel order',\n  errorInvalidHash: 'Invalid Hash',\n  errorInvalidOrderId: 'Invalid OrderId',\n  errorOnRate: 'Error on submit rate value',\n  errorForExistOrder: 'Order does not exist',\n  errorOrderExpired: 'Order has expired',\n  errorDisableOtherWalletForCurrent:\n    'Global ethereum is not {{name}}, please disable other Wallet Plugin.',\n  errorGenerateEddsa: 'Generate EdDSA key has failed.',\n  errorNotInstallGME:\n    'Please install the Gamestop Wallet browser extension. Then create, deposit, and activate the wallet before connecting to Loopring.io.',\n  errorLinKWalletApp: '<0>app market</0>',\n  errorIpfsDidToNftidError: 'IPFS Gateway Error',\n  errorMintOverlap: 'You have already minted this NFT. Please check your Wallet',\n  errorJSONStringify: 'Wrong JSON format',\n  errorCollectionMetadataNoTileUri: 'Tile uri is required',\n  errorCollectionNoName: 'Name is required',\n  errorCollectionSameName: 'Collection called {{name}} is existe',\n  errorCollectionInfo:\n    \"We've detected this collection is not yours or the Contract Address don't match\",\n  errorCollectionNoSupport: 'Only {{l2symbol}} collection is allow to mint',\n  errorCollectionNotReadable: 'Read Collection Info Failed',\n  errorIpfsTimeout: 'IPFS Gateway timeout, please try again',\n  errorRampNoInstance: 'Ramp Widget had out-off service, please re-order it.',\n  errorDualExpired: 'The order has expired.',\n  errorPrivateKey: 'Signature Wrong private key',\n  errorNoResponse: 'No response!',\n  errorMinError: 'Minimum of {{value}}',\n  errorMaxError: 'Max of {{value}}',\n  errorLengthLimit: 'Length is limit',\n  errorRedpacketEmpty: 'Red Packet is Empty',\n  errorRedpacketClaimed: 'You already opened Red Packet',\n  errorRedpacketClaimOut: 'You opened the Red Packet Too Later',\n  errorRedpacketClaimTimeOut: 'You opened the Red Packet Too Later',\n  errorOffRampExpired: 'The order has expired. please create a neworder ',\n  errorNFTRedPacketMaxError: 'Total Amount cannot exceeds {{value}} NTFs',\n  errorBetaEnv:\n    'Oops! This site is not released yet and could contain bugs. Please use it with caution!.',\n  errorProviderErrorUnknown: 'Unknown Error',\n  errorNoGamestopExtension: 'User not installed GameStop extension',\n  errorSwitchEthereum: 'wallet switch Ethereum Chain is not allowed',\n  errorEthereumNotMetamask: 'Global ethereum is not MetaMask',\n  errorGamestopNoChainChange: 'Gamestop extension no switch Ethereum Chain method',\n  errorHadUnknownCollectionDes:\n    'As the creator, you will be able to generate collection information for those NFT minted earlier that belong to nowhere. And once done, the other people holding your NFT will be able to view those NFT with proper collection information via loopring.io and loopring wallet. <1>Go</1>',\n  errorGuardianRouterError: 'Oops! Guardian site moved to <a>guardian.loopring.io</a>.',\n  errorAddressCheckError: 'Oops! Something went wrong on address checking processing ',\n  errorContactExisted: 'Contact address already exists',\n  errorContactNameExisted: 'Name already exists',\n  errorContactLimit: 'Unable to Add Contact,You have reached the maximum limit of 1500 contacts',\n  errorContactOverLimit:\n    'Unable to Add Contact,You have reached the maximum limit of 1500 contacts',\n  labelContactsAddSuccess: 'Add Contact Succeed',\n  labelContactsDeleteSuccess: 'Delete Contact Succeed',\n  labelContactsEditSuccess: 'Edit Contact Succeed',\n  labelContactsSendSuccess: 'Send Succeed',\n  labelContactsCopySuccess: 'Copied to Clipboard',\n  labelContactsAddFailed: 'Add Contact Failed',\n  labelContactsDeleteFailed: 'Delete Contact Failed',\n  labelContactsEditFailed: 'Edit Contact Failed',\n  labelContactsSendFailed: 'Send Failed',\n  errorOrderFailed: 'Order status Failed',\n  errorAddressBurnNft:\"Oops! Something went wrong on checking burn avaiable\"\n}\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/i18n/en_US/index.ts",
    "content": "import common from './common'\nimport layout from './layout'\nimport tables from './tables'\nimport error from './error'\nimport landPage from './landPage'\nimport webEarn from './webEarn'\nexport default {\n  common,\n  layout,\n  tables,\n  error,\n  landPage,\n  webEarn\n}\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/i18n/en_US/landPage.ts",
    "content": "export default {\n  labelH1Title: 'Ethereum’s First zkRollup Layer 2',\n  labelH1TitleDetail: 'Fast, Secure, and 100x Lower Fees',\n  labelH1TitleWallet: 'Loopring Wallet',\n  labelH2TitleWallet: 'FREEDOM AT YOUR FINGERTIPS',\n  labelProtocol: 'loopring offers',\n  labelStartTrade: 'start trading',\n  labelTitleDEX: 'Loopring Dex',\n  labelTradeVolume: 'Volume',\n  labelTradeUser: 'Users',\n  labelTradeTVL: 'TVL', //Total Value Locked\n  labelTradeNofTrades: 'Trades',\n  labelZeroKpt: 'Powered by Zero-knowledge Proof',\n  labelLoopringWallet: 'LOOPRING WALLET',\n  labelBtnLearnMore: 'LEARN MORE',\n  labelSafety: 'Ultimate Security',\n  labelLowCost: 'Low Transaction Fees',\n  labelFastTransfer: 'High Throughput',\n  labelSuperpowers: 'Ready for Developers',\n  describeSafety: 'Assets on Loopring L2 are equally secure as they are on the Ethereum mainnet.',\n  describeLowCost:\n    'Transaction fees are reduced to 1/30 - 1/100 of the fees on the Ethereum mainnet.',\n  describeFastTransfer:\n    'Loopring L2 can settle ~2000 transactions per second with near instant finality.',\n  describeSuperpowers:\n    \"Build scalable payment apps, non-custodial exchanges, and NFT marketplaces on Ethereum with Loopring's time-tested zkRollup technology.   Get started with quick-start guides, protocol documentation, a Javascript SDK, and a fully open source codebase.\",\n  labelBtnStart: 'LAUNCH LOOPRING L2 APP',\n  labelBtnDeveloper: 'Developer Documentation',\n  labelFirstWallet: 'BETTER THAN BEING SMART',\n  labelFirstWalletDetail:\n    'Smart wallets enable limitless extensibility over EOA wallets, but Loopring Wallet takes one step further with native zkRollup layer 2 integration.   Now you can transact directly on Loopring L2, faster and cheaper.',\n  labelWalletSecureH1: 'SECURE, at its core',\n  labelWalletSecureH2: 'With social-recovery and guardians',\n  labelWalletSecureDetail:\n    'Completely self-custodial, only you control your assets. You can choose people, institutions, and hardware that you trust to be the guardians of your wallet.  You can also set quota for daily transfers, and lock it down if ever needed.',\n  labelWalletIdentityH1: 'OWN YOUR IDENTITY',\n  labelWalletIdentityH2: 'Your wallet is your continuous Web3 identity.',\n  labelWalletIdentityDetail:\n    'The Loopring Wallet decouples identity and security. You can choose your wallet name and address, and maintain this identity forever with renewable transaction signing keys.',\n  labelWalletUsageH1: 'EASY TO USE',\n  labelWalletUsageH2: 'with zkRollup scaling solution',\n  labelWalletUsageDetail:\n    \"The Loopring Wallet integrates Loopring's Layer 2 zkRollup technology to greatly increase speeds and lower fees, while inheriting the same security guarantees as the Ethereum mainnet.\",\n  labelWalletFutureH1: 'FORWARD LOOKING',\n  labelWalletFutureH2: 'Easily upgradable to adapt future scenarios',\n  labelWalletFutureDetail:\n    'Based on smart contracts, the Loopring Wallet adopts a pluggable, modular design which can be continuously upgraded under your authorization to use future standards and new technologies.',\n  labelWalletUnleashed: 'ETHEREUM UNLEASHED',\n  labelWalletUnleashedDetail: 'Your mobile gateway to Ethereum DeFi, collectibles, and more.',\n  labelLaunchApp: 'View Dapps',\n  labelLaunchMobileApp: 'Exchange',\n  labelUpgradeHide:\n    'Loopring System Service Upgrade: Loopring will perform a temporary system upgrade starting at 2021/12/20 2:00pm (UTC+8), which will take approximately 2 hours.',\n  labelUpgradeShow:\n    'Loopring System Service Upgrade: Loopring will perform a temporary system upgrade starting at 2021/12/20 2:00pm (UTC+8), which will take approximately 2 hours.   During this period, the following relayer services will be suspended: deposits, withdrawals, trading and wallet creation. Deposits that are not completed before the start of the upgrade   will be processed after the completion of the upgrade.   We apologize for any inconvenience this may cause, and thank you for your patience! Please note: The 2 hours is our best estimation and may vary. As usual, we will maintain regular communication on the progress of the upgrade on our Twitter and Discord.',\n  labelGoGuardian: 'Manage Security',\n  labelHaveWallet: 'Already have a wallet?',\n  labelMainDes:\n    'Unleash the Power of DeFi and Advanced Trading on \\n Top of an App-Specific ZK-Rollup',\n  labelEthereum: 'Ethereum ',\n  labelGoDapps: 'Go Dapps',\n  labelNavPro: 'Loopring pro',\n  labelNavEarn: 'Loopring DeFi',\n  labelNavWallet: 'Wallet',\n  labelNavLanuch: 'View Dapps',\n  labelLoopringSmartWallet: 'Loopring Smart Wallet',\n  labelLoopringSmartWalletDes:\n    \"Ethereum's most secure wallet, fully integrated with advanced trading functionality and innovative Earn products, unlocking the true potential of Layer 2.\",\n  labelEthereumUnleashed: \"<0>Ethereum's First zkRollup </0><1>Layer 2</1>\",\n  labelGatewayToEthereum:\n    'Your gateway to Ethereum, DeFi, NFTs, and Financial Freedom.\\n Fast, Low-cost, & Secure',\n  labelTitleLite: 'Loopring DeFi',\n  labelLoopringProtocol: 'Loopring Protocol',\n  labelLoopringProtocolDes:\n    \"The world's first ZK-rollup implementation designed to scale Ethereum,\\n fully optimized for trading.\",\n  labelUltimateSecurity: 'Ultimate Security',\n  labelUltimateSecurityDes:\n    'Assets on Loopring L2 are equally secure as they are on the Ethereum mainnet.',\n  labelLowTransactionFees: 'Low Transaction Fees',\n  labelLowTransactionFeesDes:\n    'Loopring performs most operations, including trade and transfer settlement, off the Ethereum blockchain. This dramatically reduces gas consumption and overall transaction cost to small fractions of comparable on-chain cost.',\n  labelHighThroughput: 'High Throughput',\n  labelHighThroughputDes:\n    'Loopring L2 can settle ~2000 transactions per second with near instant finality.',\n  labelReadyForDevelopers: 'Ready for Developers',\n  labelReadyForDevelopersDes:\n    \"Build scalable payment apps, non-custodial exchanges, and NFT marketplaces on Ethereum with Loopring's battle-tested zkRollup technology. Get started with quick-start guides, protocol documentation, a Javascript SDK, and a fully open source codebase.\",\n  labelFeatureDes8: 'Loopring Layer2',\n  labelFeatureDes8_2: 'Crypto exchange on the go',\n  labelGo: 'Go',\n  labelTitleLiteDes: 'Revolutionizing Decentralized Finance with Cutting-Edge\\nEarning and Trading Solutions.',\n  labelInvestStakeLRCDes:\n    'Lock your LRC for a minimum duration to earn interest and redeem at any time.',\n  labelInvestDualDes: 'Buy the dip or sell the covered gain while earning a high yield.',\n  labelInvestLeverageETHDes:\n    \"Boost your earnings with CIAN protocol's leveraged ETH staking strategy.\",\n  labelInvestDefiDes: 'Earn steady income while holding! Stake ETH to accumulate daily rewards.',\n  labelInvestAmmDes:\n    'Participate in farming pools, earn additional protocol fee incentives for HOT pools.',\n  labelProductsTitleDes: 'A wide variety of trading tools to choose from',\n  labelProductsTitle: 'Trading Products',\n  labelSpotDes: 'Full access to all trading tools',\n  labelSpot: 'Spot',\n  labelSwapDes: 'Intuitive trading interface',\n  labelSwap: 'Swap',\n  labelBlockTradeDes: 'Trade via CEX liquidity',\n  labelBlockTrade: 'Block Trade',\n  labelFiatDes: 'On & Off Ramp Solutions',\n  labelFiat: 'Fiat',\n  labelNFTCollections: 'Manage and Display Your NFT Collections',\n  labelNFTCollectionsDes:\n    'Collaborate on a strategic plan to integrate \\n NFTs into your ecosystem',\n  labelRedPackets: 'Red Packets',\n  labelRedPacketsDes:\n    'Explore the various use cases of our revolutionary Red Packets! Send token or NFT gifts directly or gamify the experience with blind boxes.',\n  labelEndProductTitle: 'Earn Products',\n  labelEndProductTitleDes: 'Choose from a variety of financial products',\n  labelSupportedNetworkDes: 'Supported networks: Ethereum & Taiko',\n  labelLaunch: 'Launch',\n  labelLeadingOnChainStructuredProduct: 'Leading On-Chain Structured Product',\n  labelLeadingOnChainStructuredProductDes: 'Buy the dip or sell at a higher price—all while earning high yields.',\n  labelTradeWithCEXLiquidity: 'Trade with CEX Liquidity',\n  labelTradeWithCEXLiquidityDes: 'Effortlessly trade tokens with near-zero slippage, leveraging a unified liquidity pool that combines both CEX and DEX liquidity to generate the best execution price.',\n  labelUnlockThePowerOfLeveragedTrading: 'Unlock the Power of Leveraged Trading',\n  labelUnlockThePowerOfLeveragedTradingDes: 'Seamlessly borrow tokens against your collateral, paving the way for leveraged trading opportunities. By bridging decentralized and centralized exchanges, Loopring Portal broadens your trading horizon, granting access to tokens beyond the Ethereum network.',\n  labelEthereumOnly: 'Ethereum-Only',\n  labelLoopringLayer2: 'Loopring Layer 2',\n  labelLoopringLayer2Des: 'Unleash the Power of DeFi and Advanced \\n Trading on Top of an App-Specific ZK-Rollup',\n  labelTrade: 'Trade',\n  labelTradeDes: 'A wide variety of trading methods to choose from',\n  labelEarn: 'Earn',\n  labelEarnDes: 'Choose from a variety of financial products',\n  labelNFT: 'NFTs',\n  labelNFTDes: 'Manage and display your NFT collections',\n  labelRedPackets2: 'Red Packets',\n  labelRedPacketsDes2:\n    'Explore the possibilities with our revolutionary Red Packets',  \n  labelLoopringSmartWalletDes2: 'Trade on the go — anytime, anywhere',\n  labelExplore: 'Explore',\n  labelLoopringProtocolDes2: 'The world\\'s first ZKRollup implementation designed to scale Ethereum fully optimized for trading',\n  labelProvenAppSpecificZKRollup: 'Proven App-Specific ZK-Rollup',\n  labelProvenAppSpecificZKRollupDes: `Leverage the world's first ZK-Rollup implementation to unlock the full potential of DeFi and advanced trading`,\n  labelAuditedAndSecure: 'Bulletproof Security',\n  labelAuditedAndSecureDes: 'Assets on the Loopring Protocol are just as secure as they are on the underlying networks where the protocol is deployed',\n  labelBringingCEXToDeFi: 'Bringing CeFi to DeFi',\n  labelBringingCEXToDeFiDes: 'Seamlessly bring CeFi use cases into the DeFi world in a truly trustless manner',\n  labelReadyForDevelopersDes2: `Build scalable payment apps, non-custodial exchanges, and NFT marketplaces on Ethereum with Loopring's battle-tested ZK-rollup technology. Get started with quick-start guides, protocol documentation, a Javascript SDK, and a fully open source codebase.`,\n}\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/i18n/en_US/layout.ts",
    "content": "export default {\n  labelMarkets: 'Markets',\n  labelTrade: 'Trade',\n  labelLiquidity: 'Pools',\n  labelMining: 'Farm',\n  labelLayer2: 'L2 Wallet',\n  labelWallet: 'Wallet',\n  labelBridge: 'L2 Bridge',\n  labelBridgeDes: 'Ethereum Layer 1 to zkRollup Layer 2 Bridge',\n  labelGuardian: 'Guardian',\n  labelGuardianDes: 'Loopring Wallet smart contracts Guardian Security Specs',\n  labelZkRollupLayer2: 'zkRollup Layer 2',\n  labelSmartWallet: 'Smart Wallet',\n  loopringDomain: 'Loopring L2 - APP ',\n  labelClassic: 'Swap',\n  labelClassicDescription: 'Intuitive trading interface',\n  labelAdvanced: 'Order Book',\n  labelFiat: 'Fiat',\n  labelFiatDescription: 'On-ramp/Off-ramp crypto', /// Sell\n  labelAdvancedDescription: 'Full access to all trading tools',\n  labelDownloadApp: 'Download Loopring Wallet Mobile Application',\n  labelDownloadAppTitle: 'Download Loopring Wallet',\n  labelDownloadBtn: 'Go to Loopring Website',\n  labelNotification: 'Notification Information',\n  themeSetting: 'Theme setting',\n  languageSetting: 'Language setting',\n  labelConnectWallet: 'Connect Wallet',\n  notificationApprove: 'Approving',\n  notificationPending: 'Pending',\n  labelMyTrades: 'My Trades',\n  labelRecentTrades: 'Recent Trades',\n  // layer2 submenu\n  labelAssets: '{{l2Symbol}} Assets',\n  labelTransactions: 'Deposit/Withdraw',\n  labelTrades: 'Trade History',\n  labelHistory: 'Transactions',\n  labelOrder: 'Orders',\n  labelReward: 'Rewards',\n  labelRedPacket: 'RedPacket',\n  labelAmmRecords: 'AMM records',\n  labelAmmRecordsDes: '(Add & Remove)',\n  rewards: 'Rewards',\n  labelOrders: 'Orders',\n  selectLanguage: 'select language',\n  labelPools: 'Pools',\n  labelAmmMining: 'AMM Mining',\n  labelMyLiquidity: 'My Liquidity',\n  labelOrderBookMining: 'Orderbook Mining ',\n  labelMakerRebates: 'Maker Rebates',\n  labelSetting: 'Setting',\n  labelSecurity: 'Security',\n  labelVipPanel: 'VIP',\n  labelContactsPanel: 'Contacts',\n  titleLoopring: 'Loopring',\n  labelLoopringDescribe: 'zkRollup Exchange and Payment Protocol',\n  labelWrongNetwork: 'Wrong network',\n  labelYoutube: 'Youtube',\n  labelWeibo: 'Weibo',\n  // Footer\n  labelFooterAbout: 'About',\n  labelkeyOrg: 'Loopring.org',\n  labelkeyTerms: 'Terms of Service',\n  labelkeyPrivacy: 'Privacy Policy',\n  labelkeyNews: 'Blog',\n  labelkeyRisks: 'Risk Disclosure',\n  labelFooterPlatform: 'Platform',\n  labelkeyFees: 'Fees',\n  labelkeyVIP: 'VIP Program',\n  labelkeyReferrals: 'Referrals',\n  labelkeyTokenListing: 'List a Token',\n  labelkeyCreatorGrants: 'Creator Grants',\n  labelkeyL2Explorer: 'Layer 2 Explorer',\n  labelkeySubgraph: 'Subgraph',\n  labelkeyBugBounty: 'Bug Bounty',\n  labelFooterSupport: 'Support',\n  labelkeyFeedback: '❤️ Submit a Request',\n  labelkeyGuardian: 'Wallet Guardian',\n  labelkeyLoopringTutorial: 'Loopring Tutorial',\n  labelkeyCommunityDocs: 'Community Docs',\n  labelkeySupportCenter: 'Support Center',\n  labelFooterDevelopers: 'Developers',\n  labelkeySmartContract: 'Smart Contracts',\n  labelkeyLoopringApp: 'Loopring App',\n  labelkeyLoopringSmartWallet: 'Loopring Smart Wallet',\n  labelkeyAPIs: 'APIs',\n  labelkeyReportIssue: 'Report Issue',\n  labelMyNFT: 'My NFTs',\n  labelLaunchApp: 'View Dapps',\n  labelLaunchMobileApp: 'Exchange',\n  labelLandingHeaderLayer2: 'zkRollup Layer 2',\n  labelLandingHeaderWallet: 'Smart Wallet',\n  labelCopyRight: '© 2017 Loopring Technology Limited. All rights reserved.',\n  labelWalletProtect: 'Guardian',\n  labelWalletValidation: 'Approval Requests',\n  labelWalletHistory: 'History',\n  labelNFT: 'L2 NFT',\n  labelMyAssetsNFT: 'My NFTs',\n  labelMyAssetsNFTDes: 'Receive/Send NFTs',\n  labelInvest: 'Earn',\n  labelMintNFT: 'Create NFT',\n  labelMintNFTDes: 'Create your own NFTs',\n  labelTransactionNFT: 'NFT Transactions',\n  labelTransactionNFTDes: 'NFT Transactions History',\n  labelForceWithdraw: 'Force Withdraw',\n  labelInvestBalance: 'My Investments',\n  labelInvestBalanceDes: 'The deposition you hold',\n  labelInvestAmm: 'AMM Pools',\n  labelInvestOverview: 'Overview',\n  labelInvestOverviewDes: 'Select DeFi Investment',\n  labelInvestAmmDes: 'Add liquidity and earn fees',\n  labelInvestDefi: 'ETH Staking',\n  labelInvestDefiDes: 'Earn ETH staking rewards',\n  labelInvestWSTETH: 'Via Lido',\n  labelInvestWSTETHDes: 'Stake ETH get WSTETH',\n  labelInvestRETH: 'Via Rocket Pool',\n  labelInvestRETHDes: 'Stake ETH get RETH',\n  labelInvestDual: 'Dual Investment',\n  labelInvestDualDes: 'Buy the Dips, Sell the Rallies',\n  labelDepositNFT: 'Receive NFT',\n  labelMyCollection: 'My Collections',\n  labelMyCollectionDes: 'Create, curate, and \\n manage my NFT collections',\n  labelInvestStakeLRC: 'LRC Staking',\n  labelInvestStakeLRCDes: 'Earn LRC staking rewards',\n  labelBtradeTrade: 'Block Trade',\n  labelBtradeTradeDescription: 'Trade via CEX liquidity',\n  labelStopLimit: 'Stop-Limit',\n  labelStopLimitDescription: 'Control trading, like a pro',\n  labelCopyRightBeta:\n    'This site is not released yet and could contain bugs. Please use it with caution!',\n  labelReferralReward: 'Referrals Reward',\n  // labelDepositNFTDes:\"Receive NFT\"\n  labelInvestLeverageETH: 'Leveraged ETH Staking',\n  labelInvestLeverageETHDes: 'Gain higher APY aggressively',\n  labelDualInvest: 'Dual Investment',\n  labelVault: 'Portal',\n  labelNavPro: 'Loopring Layer 2',\n  labelNavEarn: 'Loopring DeFi',\n  labelNavWallet: 'Wallet',\n\n  labelDashBoard: 'Dashboard',\n  labelRecord: 'Records',\n  labelHome: 'Loopring Layer 2',\n  labelVaultHome: 'Market',\n  labelVaultHomeDes: 'Browse tradable tokens',\n  labelVaultDashboard: 'Dashboard',\n  labelVaultDashboardDes: 'Manage assets and positions',\n  labelUnlockFirst: 'Unlock First',\n  labelVault2: 'Assets',\n  labelTaikoFarming: 'Taiko Farming',\n  labelNavDoc: 'Developers',\n\n  labelNavWalletDes: `Trade on the go — anytime, anywhere`,\n  labelNavEarnDes: 'Revolutionizing Decentralized Finance with Cutting-Edge Earning and Trading Solutions',\n  labelNavProDes: 'Unleash the Power of DeFi and Advanced Trading \\n on Top of an App-Specific ZK-Rollup',\n  labelNavDocDes: 'Our API,SDK, and step-by-step references to building, minting, and trading on Loopring',\n\n  labelAssetsDes: 'Revolutionizing Decentralized Finance with Cutting-Edge Earning and Trading Solutions',\n  labelDualInvestDes: 'Bring structured finance from CeFi to DeFi in a trustless manner. Place orders at your preferred price and earn high yields!',\n  labelVaultDes: 'Trade popular tokens beyond the Ethereum chain, with leverage!',\n  labelBtradeTradeDes: 'Swap tokens securely and trustlessly, tapping into CEX liquidity.',\n  labelTaikoFarmingDes: 'Farm Trailblazers points at 60X while unlocking the value of your locked TAIKO to keep trading or earning.',\n  labelVaultTradeTabTitle: 'Trade',\n  labelVaultTradeTabDes: 'Long or Short with leverage',\n}\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/i18n/en_US/tables.ts",
    "content": "export default {\n  labelStatus: 'Status',\n  labelAMM: 'AMM',\n  labelSend: 'Send',\n  labelSendL2: 'Send L2',\n  labelSendL1: 'Send L1',\n  labelL2toL1Action: 'Withdraw',\n  labelReceive: 'Receive',\n  labelTransfer: 'Transfer',\n  labelWithdraw: 'Withdraw',\n  labelWithdrawAction: 'Withdraw',\n  labelDeposit: 'Deposit',\n  labelTrade: 'Trade',\n  labelToken: 'Token',\n  labelAmount: 'Amount',\n  labelAvailable: 'Available',\n  labelLocked: 'Frozen',\n  labelAssetsTableValue: 'Value',\n  labelActions: 'Actions',\n  labelAllToken: 'All Tokens',\n  labelHideSmallBalances: 'Hide Small Balances',\n  labelHideInvestToken: 'Hide Invest Tokens',\n  labelOrderFilterAllTypes: 'All Types',\n  labelOrderFilterBuy: 'Buy',\n  labelOrderFilterSell: 'Sell',\n  labelFilterReset: 'Reset',\n  labelFilterSearch: 'Search',\n  labelOrderSide: 'Orders',\n  labelOrderAmount: 'Amount',\n  labelOrderAverage: 'Average',\n  labelOrderPrice: 'Price',\n  labelOrderFilledAmount: 'Filled Amount',\n  labelOrderFilledPrice: 'Filled Price',\n  labelOrderFilterAllPairs: 'All Pairs',\n  labelOrderFee: 'Fee',\n  labelOrderRole: 'Role',\n  labelOrderTime: 'Time',\n  labelOrderStatus: 'Status',\n  labelOrderTradingPrice: 'Trading Price',\n  labelOrderTotal: 'Total',\n  labelQuotaPair: 'Pair',\n  labelQuotaLastPrice: 'Latest Price',\n  labelQuota24hChange: '24h Change',\n  labelQuota24hChangeLit: '24h Chg ',\n  labelQuota24hHigh: '24h High',\n  labelQuota24hLow: '24h Low',\n  labelQuota24hAmount: '24h Amount',\n  labelQuoteAction: 'Action',\n  labelTradeFilterAllTypes: 'All Types',\n  labelTradeFilterBuy: 'Buy',\n  labelTradeFilterSell: 'Sell',\n  labelTradeSide: 'Trades',\n  labelTradeAmount: 'Amount',\n  labelTradePrice: 'Price',\n  labelTradeFee: 'Fee',\n  labelTradeTime: 'Time',\n  labelTradeRole: 'Role',\n  labelTradeRoleMaker: 'Maker',\n  labelTradeRoleTaker: 'Taker',\n  labelTradeConterparty: 'Counterparty',\n  labelTradeCounterpartyOrderbook: 'Orderbook',\n  labelTradeCounterpartyPool: 'Pool',\n  labelTxFilterAllTypes: 'All Types',\n  labelTxFilterReceive: 'Receive',\n  labelTxFilterSendL1: 'Send L1',\n  labelTxFilterSendL2: 'Send L2',\n  labelTxFilterDeposit: 'Deposit',\n  labelTxFilterWithdraw: 'Withdrawal',\n  labelTxFilterTransfer: 'Transfer',\n  labelTxFilterAllTokens: 'All Tokens',\n  labelTxSide: 'Transactions',\n  labelTxToken: 'Token',\n  labelTxFrom: 'Description',\n  labelTxTo: 'To',\n  labelTxAmount: 'Amount',\n  labelTxFee: 'Fee',\n  labelTxMemo: 'Memo',\n  labelTxTime: 'Time',\n  labelTxTxnHash: 'Txn Hash',\n  labelTxStatus: 'Status',\n  labelTransactions: 'Transactions',\n  labelVolume: 'volume',\n  labelTradePair: 'Trade Pair',\n  labelPool: 'Pool',\n  labelLiquidity: 'Liquidity',\n  labelMyLiquidity: 'My Liquidity',\n  label24TradeVolume: '24h Volume',\n  label24Reward: '24h Reward',\n  labelAPR: 'APR',\n  labelTradePool: 'Subscribe',\n  labelAction: 'Action',\n  labelFilter: 'Filter',\n  labelFilterAllPairs: 'All pairs',\n  valueAddTOAMM: `Add <1></1> and <3></3>`,\n  valueSwapForAMM: `Swap <1></1> for <3></3>`,\n  valueRemoveTOAMM: `Remove <1></1> and <3></3>`,\n  labelAmmTotalValue: 'Total Value',\n  labelAmmTokenAmount: 'Token Amount',\n  labelAmmTime: 'Time',\n  labelFeeEarned: 'Fees Earned',\n  labelBuy: 'Buy',\n  labelSell: 'Sell',\n  labelAmmSide: 'Subscribe/Redeem',\n  labelAmmAmount: 'Amount',\n  labelAmmLpTokenAmount: 'LP Token Amount',\n  labelAmmFee: 'Fee',\n  labelAmmRecordTime: 'Time',\n  labelAmmExit: 'Redeem',\n  labelAmmJoin: 'Subscribe',\n  labelAmmFilterTypes: 'All Types',\n  labelAmmFilterJoin: 'Subscribe',\n  labelAmmFilterExit: 'Redeem',\n  labelPoolTableAddLiquidity: 'Subscribe',\n  labelPoolTableRemoveLiquidity: 'Redeem',\n  labelEmptyDefault: 'No data to display',\n  labelAmmTableType: 'Type',\n  labelOrderDetailTaker: 'Taker',\n  labelOrderDetailMaker: 'Maker',\n  labelOrderDetailTradingVolume: 'Trading Volume',\n  labelOrderDetailOrderId: 'Order Id',\n  labelOrderCancelAll: 'Cancel All',\n  labelOrderCancelOrder: 'Cancel',\n  labelOrderProcessing: 'Processing',\n  labelOrderProcessed: 'Processed',\n  labelOrderCancelling: 'Cancelling',\n  labelOrderCancelled: 'Cancelled',\n  labelOrderExpired: 'Expired',\n  labelOrderWaiting: 'Waiting',\n  // labelOrderAmm: 'AMM',\n  labelOrderLimitOrder: 'Limit',\n  labelOrderStopLimitOrder: 'Stop-Limit',\n  labelOrderMarketOrder: 'Market',\n  // labelOrderMaker: 'Maker',\n  labelOrderTaker: 'Taker',\n  labelOrderChannelsMixed: 'Merged',\n  // labelOrderChannelsAMM: 'AMM',\n  labelOrderChannelsSwap: 'Swap',\n  labelOrderChannelsOrderBook: 'Orderbook',\n  labelOrderTypes: 'Types',\n  labelOrderChannels: 'Channels',\n  labelOrderCompletion: 'Completion',\n  labelRewardTableAmount: 'Amount',\n  labelRewardTableTime: 'Time',\n  labelOrderCancelConfirm: 'Confirm to cancel this order?',\n  labelOrderConfirm: 'Confirm',\n  labelOrderCancel: 'Cancel',\n  labelTradeProPrice: 'Price ({{symbol}})',\n  labelTradeProAmount: 'Amount ({{symbol}})',\n  labelVipTableLevel: 'Level',\n  labelVipTable30dTradeVolume: '30d Volume',\n  labelVipTableRule: 'and / or',\n  labelVipTableBalance: 'LRC Balance',\n  labelVipTableMaker: 'Maker',\n  labelVipTableTaker: 'Taker',\n  labelTradeRaceRank: 'Rank',\n  labelTradeRaceAddress: 'Address',\n  labelTradeRaceTradeVolume: 'Trade Volume',\n  labelTradeRaceAward: 'Award',\n  labelTradeRaceProject: 'Project',\n  labelTradeRacePair: 'Pair',\n  labelTradeRaceToken: 'Token',\n  labelTradeRaceReward: 'Reward',\n  labelMaker: 'Maker',\n  labelTaker: 'Taker',\n  labelNFTTypeDEPOSIT: 'Deposit',\n  labelNFTTypeTRANSFER: 'Transfer',\n  labelNFTTypeWITHDRAWAL: 'Withdraw',\n  labelNFTTypeWITHDRAW: 'Withdraw',\n  labelNFTTypeWITHDRAW_LUCKY_TOKEN: 'Claim Red Packet',\n  labelNFTTypeSEND_BACK_LUCKY_TOKEN: 'Back From Red Packet',\n  labelNFTTypeSEND_LUCKY_TOKEN: 'Send Red Packet',\n  labelMint: 'Mint',\n  labelNFTTypeMINT: 'Mint',\n  labelTxNFTFilterALL: 'All Types',\n  labelTxNFTFilterDEPOSIT: 'Deposit',\n  labelTxNFTFilterWITHDRAW: 'Withdraw',\n  labelTxNFTFilterWITHDRAWAL: 'Withdraw',\n  labelTxNFTFilterRECEIVE: 'Receive',\n  labelTxNFTFilterSEND: 'Send',\n  labelTxNFTFilterFORCEWITHDRAW: 'Force Withdraw',\n  labelTxNFTFilterTRANSFER: 'Transfer',\n  labelTxFilterALL: 'All Types',\n  labelTxFilterRECEIVE: 'Receive',\n  labelTxFilterSEND: 'Send',\n  labelTxFilterFORCEWITHDRAW: 'Force Withdraw',\n  labelTxFilterDEPOSIT: 'Deposit',\n  labelTxFilterWITHDRAW: 'Withdraw',\n  labelTxFilterWITHDRAWAL: 'Withdraw',\n  labelTxFilterTRANSFER: 'Transfer',\n  labelTypeDEPOSIT: 'Receive',\n  labelTypeWITHDRAW: 'Send',\n  labelTypeSEND: 'Send',\n  labelTypeReceive: 'Receive',\n  labelTypeONCHAIN_WITHDRAWAL: 'Send',\n  labelTypeOFFCHAIN_WITHDRAWAL: 'Send',\n  labelTypeTRANSFER: 'Send',\n  labelTypeWITHDRAW_LUCKY_TOKEN: 'Claim Red Packet',\n  labelTypeSEND_BACK_LUCKY_TOKEN: 'Back From Red Packet',\n  labelTypeSEND_LUCKY_TOKEN: 'Send Red Packet',\n  labelTypeDUAL_INVESTMENT: 'Dual Investment Settled',\n  labelTypeL2_STAKING: 'Claim Earnings',\n  labelTxNFTFilterMINT: 'Mint',\n  labelShowFilter: 'Show Filter',\n  labelTypeDELEGATED_FORCE_WITHDRAW: 'Force Withdraw',\n  labelForceWithdrawTotalDes: 'All {{symbol}}',\n  labelForceWithdrawDes: '{{address}} (Address that the token is withdrawn from L2 to L1)',\n  labelDefiInvest: 'Subscribe',\n  labelDefiRedeem: 'Redeem',\n  labelSelect: 'Select',\n  labelDuration: 'Duration',\n\n  labelInvestAll: 'Both',\n  labelDefiExit: 'Redeem',\n  labelDefiJoin: 'Subscribe',\n  labelDefiType: 'Subscribe/Redeem',\n  labelDefiFee: 'Fee',\n  labelDefiTime: 'Time',\n  labelDefiAmount: 'Amount',\n  labelFilterTradeNFTAll: 'All',\n  labelFilterTradeNFTSell: 'Sell',\n  labelFilterTradeNFTSelf: 'Self Trade',\n  labelFilterTradeNFTBuy: 'Buy',\n  labelTradeNFTSide: 'Trade',\n  labelFrom: 'from',\n  labelTo: 'to',\n  labelUPrice: 'unit price: ',\n  labelTradeNFTUnitPrice: 'Unit Price',\n  labelDualApy: 'APR',\n  labelDualTerm: 'Term',\n  labelDualPrice: 'Target Price',\n  labelDualTPrice: 'Target',\n  labelDualSettlement: 'Settlement Date',\n  labelDualAction: 'Action',\n  labelInvestmentStatusSettled: 'Settled',\n  labelInvestmentStatusDelivering: 'Delivering',\n  labelInvestmentStatusSubscribe: 'Earning',\n  labelDualAssetProduct: 'Product',\n  labelDualAssetFrozen: 'Invest',\n  labelDualAssetPrice: 'Target Price',\n  labelDualAssetSettlement_Date: 'Settlement Date',\n  labelDualAssetAPR: 'APR',\n  labelDualAssetAction: 'Actions',\n  labelDualAssetDetail: 'Details',\n  labelDualAssetRefresh: 'Refresh',\n  labelDualTxsSide: 'Type',\n  labelDualTxsProduct: 'Product',\n  labelDualTxAPR: 'APR',\n  labelDualTxsTargetPrice: 'Target Price',\n  labelDualTxsSettlement_Date: 'Settlement Date',\n  labelDualTxsSettlementPrice: 'Settlement Price',\n  labelDualTxsSettlement: 'Settlement',\n  labelDualTxsTime: 'Time',\n  labelDualAssetReturn: 'Return',\n  labelAprPool: 'Amm Pool APR:',\n  labelAprFee: 'Protocol APR:',\n  labelAprEvent: 'Activity APR:',\n  label24Rewards: '24h Rewards',\n  labelRewardFee: 'AMM Rewards:',\n  labelRewardReward: 'Other Rewards:',\n  labelRewardExtra: 'Campaign Rewards:',\n\n  labelRecordToken: 'Token',\n  labelRecordAmount: 'Amount',\n  labelRecordType: 'Type',\n  labelRecordStatus: 'Status',\n  labelRecordNumber: 'Number',\n  labelRecordTime: 'Time',\n  labelReceiveTime: 'Receive Time',\n  labelValue: 'Value',\n  labelClaim: 'Claim',\n  labelAddress: 'Address',\n  labelType: 'Type',\n  labelDefiStakingProduct: 'Product',\n  labelDefiStakingFrozen: 'Frozen',\n  labelDefiStakingEarn: 'Cumulative Earnings',\n  labelDefiStakingPreviousEarn: \"Previous Day's Earnings\",\n  labelDefiStakingDuration: 'Holding Time',\n  labelDefiStakingARR: 'APR',\n  labelDefiStakingAction: 'Action',\n  labelDefiStakingTxType: 'Type',\n  labelDefiStakingTxAmount: 'Amount',\n  labelDefiStakingTxProduct: 'Product',\n  labelDefiStakingTxLockedDuration: 'Locked Duration',\n  labelDefiStakingTxHashId: 'HashID',\n  labelDefiStakingTxSubscribeTime: 'Time',\n  labelDefiStakingTxRewardsDate: 'Rewards Date',\n  labelDefiStakingTxTxID: 'TxID',\n  labelDefiStakingTxTime: 'Time',\n  labelDefiStakingDetail: 'Detail',\n  labelDefiStakingRedeem: 'Redeem',\n  labelDays: 'day(s)',\n  labelStakeTransactionTypesubscribe: 'subscribe',\n  labelStakeTransactionTyperedeem: 'redeem',\n  labelStakeTransactionTypeclaim: 'claim',\n  labelDefiStakingAndPreviousEarn: \"Cumulative & Previous Day's Earnings\",\n  labelDefiStakingTxRewardsMobileDate: 'Date',\n\n  labelBlindBoxOpend: 'Opend',\n  labelBlindBoxEndTime: 'End Time',\n  labelBlindBoxCalim: 'Claim',\n  labelBlindBoxExpired: 'Expired',\n  labelBlindBoxClaimed: 'Claimed',\n  labelBlindBoxStartTime: 'Reveal Time: {{time}}',\n  labelBlindBoxExpiredTime: 'Expiration Time: {{time}}',\n  labelRedPacketOpen: 'Open',\n  labelRedPacketSenderAddress: 'Sender Address',\n  // labelRecordAction: \"Action\",\n  labelBtradeSwapType: 'Type',\n  labelBtradeSwapFee: 'Trading Fee',\n  labelBtradeSwapTime: 'Time',\n  labelBtradeSwapPrice: 'Price',\n  labelBtradeSwapSettled: 'Settled',\n  labelBtradeSwapDelivering: 'Delivering',\n  labelBtradeSettled: 'Settled',\n  labelBtradeDelivering: 'Delivering',\n  labelBtradeDeliveringDes:\n    'The Loopring pool is currently unable to swap the full requested amount. The tokens that were successfully swapped will be transferred to your account now. The unswapped tokens will be locked until they can be swapped. \\n We’ll rebalance the pool shortly and swap the remaining portion.',\n  labelBtradeFailed: 'Failed',\n  labelBtradeCancelled: 'Cancelled',\n  labelBtradePending: 'Pending',\n  labelBtradeSwapFailed: 'Filled',\n  labelStopLimitStopPrice: 'Trigger Condition',\n  labelDUAL_CURRENCY: 'Dual',\n  labelDUAL_BASE: 'Dual',\n  labelBTRADE: 'Block Trade',\n  labelL2STAKING: 'LRC Staking',\n  labelSTOP_LIMIT: 'Stop-Limit',\n  labelStopLimitTriggered:\n    'Triggered: The limit order has been submitted to the order book.\\n Time: {{time}}',\n  labelStopLimitWaitingTrigger:\n    'The limit order is not placed until the stop price has been triggered.',\n  labelRevealTime: 'Reveal Time',\n  labelRevealTimeTooltip:\n    'The Reveal time is when the Red Packet ends， and recipients can open it to see if they have received',\n  labelExpiredTime: 'Expired Time',\n  labelExpiredTimeTooltip: 'After expiration, all unclaimed NFTs will be returned to the Sender.',\n  labelRedpacketFromBlindbox: 'From Blind Box',\n  labelRedpacketCantOpen: 'It is not yet time to open, reveal time: {{time}}',\n  labelReferralsTableReferee: 'Referee',\n  labelReferralsTableAmount: 'Rewards',\n  labelReferralsTableTime: 'Time',\n  labelRefundTableAmount: 'Refunds',\n  labelRefundTableTime: 'Time',\n  labelTxNetworkFee: 'Network Fee',\n  labelTxTradingFee: 'Trading Fee',\n  labelTypeUNIFIED_CLAIM: 'Claim Rewards',\n  labelRedPacketClaiming: 'Claiming',\n  labelLoadingMore: 'Loading More...',\n  labelDualAutoReinvest: 'Auto Reinvest',\n  labelDualAssetModify: 'Modify',\n  labelDualAssetReInvestDisable: 'Disabled',\n  labelDualAssetReInvestEnable: 'Enabled',\n  labelDualAuto: 'ReInvest',\n  labelDualFailed: 'Failed',\n  labelDualPending: 'pending',\n  labelDualAutoInvestTip: 'Auto Reinvest Status:{{}}',\n  labelDualRetryStatusSuccess:\n    'Auto reinvested successful. A new order has been generated for you.',\n  labelDualRetryStatusError:\n    'Auto reinvest failed. Cannot find product with Buy Price of {{price}} and Longest Settlement Date of {{day}} days. ',\n  labelDualRetryStatusRetrying: 'Auto reinvesting. Searching for the product...',\n  labelDualAssetReInvestYes: 'ReInvest On',\n  labelDualAssetReInvestNo: 'ReInvest Off',\n  labelDualRetryPending: 'Pending',\n  labelDualRetryTerminated: 'Terminated',\n  labelDualRetryFailed: 'Failed',\n  labelDualRetrySuccess: 'Successful',\n  labelDualRetryStatusTerminated:\n    'Auto Reinvest terminated. You successfully purchased the target token.',\n  labelTypeCHANGE_PWD: 'Reset Loopring L2 Keypair',\n  labelAveragePositionCost: 'Average Position Cost <1></1>',\n  labelAveragePositionCostDes: 'The average holding cost of the last 10 purchases.',\n  labelDefiApr: 'Est.APR <1></1>',\n  labelDefiAprDes:\n    'APR stands for annual percentage rate, not taking into account the effect of compound interest. The value displayed here indicates the current value, while it keeps changing dynamically. ',\n  labelVaultAssetsTableValue: 'Value',\n  labelVaultborrow: 'Borrow',\n  labelVaultopen: 'Supply Collateral',\n  labelVaultcloseout: 'Settle',\n  labelVaultmargin: 'Add Collateral',\n  labelVaultrepay: 'Repay',\n  labelVaulttrade: 'Trade',\n  labelVaultSellShort: 'Sell/Short',\n  labelVaultBuyLong: 'Buy/Long',\n  labelVaultborrowDes: 'Borrow des',\n  labelVaultopenDes: 'Supply Collateral des',\n  labelVaultcloseoutDes: 'Settle des',\n  labelVaultmarginDes: 'Margin Call des',\n  labelVaultrepayDes: 'Repay des',\n  labelVaulttradeDes: 'Trade des',\n  labelVaultTxType: 'Type',\n  labelVaultTxFilled: 'Filled Amount',\n  labelVaultTxStatus: 'Status',\n  labelVaultTxTime: 'Time',\n  labelVaultVAULT_STATUS_EARNING: 'Success',\n  labelVaultVAULT_STATUS_RECEIVED: 'Received',\n  labelVaultVAULT_STATUS_PROCESSING: 'Pending',\n  labelVaultVAULT_STATUS_SUCCEED: 'Success',\n  labelVaultVAULT_STATUS_FAILED: 'Failed',\n  labelVaultVAULT_STATUS_PENDING: 'Pending',\n  labelDetail: 'Detail',\n  labelVaultcloseoutForced: 'Forced Liquidation',\n  labelInvest: 'Invest',\n  labelVaultconvert: 'Dust Collector',\n  labelVaultredeem: 'Redeem Collateral',\n  labelVaultJoinRedeem: 'Redeem Collateral',\n  labelFailed: 'Failed',\n  labelTotalValue: 'Total Value',\n  labelVaultConvert: 'Converted',\n  labelVaultRepayment: 'Payment',\n  labelVaultTime: 'Time',\n  labelVaultDetails: 'Details',\n  labelVaultErrorOccurred: 'An error has occurred. Please try again later.',\n  labelVaultDustCollector: 'Dust Collector',\n  labelDetails: 'Details',\n  labelLock: 'Lock',\n  labelLockTime: 'Time',\n  labelTotalLocked: 'Total/Locked',\n  labelLocked2: 'Locked',\n  labelTAIKO_FARMING: 'Taiko Farming',\n  labelVaultcloseShort: 'Close Short'\n}\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/i18n/en_US/webEarn.ts",
    "content": "/* eslint-disable max-len */\nexport default {\n  labelFAQ1Question: 'What is Loopring protocol ?',\n  labelFAQ1Answer:\n    \"As the world's first ZKRollup implementation to scale up Ethereum, Loopring Protocol has run since 2017. There have been more than 210K users and $5.88B trading volume occurred on this protocol. As an app-specific ZKRollup protocol, it has been successfully deployed not only as a Layer 2 on top of Ethereum but also as a Layer 3 on top of other EVM-compatible networks such as Arbitrum.\",\n  labelFAQ2Question: 'What is Dual Investment ?',\n  labelFAQ2AnswerLine1:\n    'Dual Investment is a non-principal protected structured product. Upon purchasing, you can select the underlying asset, investment currency, investment amount, and delivery date. Your return will be denominated in the investment currency or alternate currency, depending on the below conditions.',\n  labelFAQ2AnswerLine2:\n    'There are two types of Dual Investment products: “Buy Low” and “Sell High”.',\n  labelFAQ2AnswerLine3:\n    'Buy Low products gives you a chance to buy your desired crypto (such as LRC) at a lower price in the future with stablecoins (USDC).',\n  labelFAQ2AnswerLine4:\n    'Target Reached: On the Settlement Date, if the Market Price is at or below the Target Price, the target currency (LRC) will be bought;',\n  labelFAQ2AnswerLine5:\n    'Target Not Reached: On the Settlement Date, if the Market Price is above the Target Price, then you will keep your stablecoins; In both scenarios, you will first earn interest in stablecoins. Once the Target Price is reached, your subscription amount and interest income will be used to buy LRC.',\n  labelFAQ2AnswerLine6:\n    'Sell High products gives you a chance to sell your existing crypto (such as LRC) at a higher price in the future (for USDC).',\n  labelFAQ2AnswerLine7:\n    'Target Reached: On the Settlement Date, the Market Price is at or above the Target Price, your LRC will be sold for USDC.',\n  labelFAQ2AnswerLine8:\n    'Target Not Reached: On the Settlement Date, the Market Price is below the Target Price, then you will keep your LRC. In both scenarios, you will first earn interest in your existing currency (LRC). Once the Target Price is reached, your subscription amount and interest income will be sold for USDC.',\n  labelFAQ2AnswerLine9:\n    'Your token for investment is just locked but still in your account as Loopring is a DEX.',\n  labelFAQ2AnswerLine10:\n    '  Each purchased product has a settlement date. We will take an average of the market price in the last 30 minutes before 16:00 (UTC+8) on the delivery date as the settlement price.',\n  labelFAQ2AnswerLine11:\n    'Please make sure that you fully understand the product and the risks before investing.',\n  labelFAQ3Question: 'What is the Dual Investment Sell covered gain ?',\n  labelFAQ3AnswerLine1:\n    'Covered Gain is an investment strategy to sell digital assets at your Target Price and earn interest while waiting.',\n  labelFAQ3AnswerLine2: 'On the Settlement Date, there can be 2 scenarios:',\n  labelFAQ3AnswerLine3: 'Market Price > Target Price',\n  labelFAQ3AnswerLine4: 'Market Price ≤ Target Price',\n  labelFAQ3AnswerLine5: 'Market Price > Target Price',\n  labelFAQ3AnswerLine6:\n    'Your original investment and earned interest will be sold at the target price.',\n  labelFAQ3AnswerLine7:\n    'This order is then closed regardless of whether \"Auto Reinvest\" is enabled or not.',\n  labelFAQ3AnswerLine8: 'Market Price ≤ Target Price',\n  labelFAQ3AnswerLine9: 'Your original investment and earned interest won’t be sold.',\n  labelFAQ3AnswerLine10:\n    'If you enable the “Auto Reinvest” feature, Loopring will automatically subscribe to a suitable dual investment product based on the agreed terms until you either successfully sell crypto at your desired price or disable the feature.',\n  labelFAQ3AnswerLine11: 'Auto Reinvest',\n  labelFAQ3AnswerLine12:\n    'When you enable the “Auto Reinvest” feature, Loopring will automatically reinvest your funds into a new product with the same target price when the previous product expires, continuing until you successfully sell your crypto at your Target Price. If there isn’t an available product within 2 hours after the previous settlement, the order will be automatically closed.',\n  labelFAQ3AnswerLine13: 'Sell Price: the Target Price at which you want to sell your crypto.',\n  labelFAQ3AnswerLine14:\n    \"Longest Settlement Date: your acceptable investment period. If no suitable products are available within this range, “Auto Reinvest” will not subscribe to any products for you, even if it's enabled.\",\n  labelFAQ4Question: 'What is the Dual Investment Buy the dip ?',\n  labelFAQ4AnswerLine1:\n    'Buy The Dip is an investment strategy to buy digital assets at your Target Price and earn interest while waiting.\\n',\n  labelFAQ4AnswerLine2: 'On the Settlement Date, there can be 2 scenarios:',\n  labelFAQ4AnswerLine3: 'Market Price > Target Price',\n  labelFAQ4AnswerLine4: 'Market Price ≤ Target Price',\n  labelFAQ4AnswerLine5: 'Market Price > Target Price',\n  labelFAQ4AnswerLine6:\n    'Your original investment and earned interest won’t be converted. Earned interest is in USDC or USDT.',\n  labelFAQ4AnswerLine7:\n    'If you enable the “Auto Reinvest” feature, Loopring will automatically subscribe to a suitable dual investment product based on the agreed terms until you either successfully buy crypto at your desired price or disable the feature.',\n  labelFAQ4AnswerLine8: 'Market Price ≤ Target Price',\n  labelFAQ4AnswerLine9:\n    'Your original investment and earned interest will be converted at the Target Price.',\n  labelFAQ4AnswerLine10:\n    'This order is then closed regardless of whether \"Auto Reinvest\" is enabled or not.',\n  labelFAQ4AnswerLine11: 'Auto Reinvest',\n  labelFAQ4AnswerLine12:\n    'When you enable the “Auto Reinvest” feature, Loopring will automatically reinvest your funds into a new product with the same target price when the previous product expires, continuing until you successfully buy crypto at your desired price. If there isn’t an available product within 2 hours after the previous settlement, the order will be automatically closed.',\n  labelFAQ4AnswerLine13: 'Buy Price: the Target Price at which you want to buy crypto.',\n  labelFAQ4AnswerLine14:\n    \"Longest Settlement Date: your acceptable investment period. If no suitable products are available within this range, “Auto Reinvest” will not subscribe to any products for you, even if it's enabled.\",\n  labelDualEarnTitle: 'DUAL INVESTMENT',\n  labelDualEarnSubTitle: 'The most innovative structural products brought to the DeFi world',\n  labelDualEarnTag1: 'Buy Low or Sell High',\n  labelDualEarnTag2: 'No Trading Fees',\n  labelDualEarnTag3: 'High Rewards',\n  labelSellHigh: 'Sell Hign',\n  labelBuyLow: 'Buy Low',\n  labelInvestSymbol: 'Invest {{symbol}}',\n  labelInvestSymbolSellHigh: 'Sell {{symbol}} High',\n  labelInvestSymbolBuyLow: 'Buy {{symbol}} Low',\n  labelApy: 'APY',\n  labelCurrentPrice: 'Current Price',\n  labelViewDetails: 'View Details',\n  labelLoopringEarn: 'Loopring DeFi',\n  labelLoopringEarnDes:\n    'Loopring DeFi is built on top of Loopring Protocol to take full advantage of its ZKRollup technology and full-stack DEX capability to provide the most innovative DeFi products to users.',\n  labelLoopringProtocol: 'Loopring Protocol',\n  labelLoopringProtocolDes:\n    \"The world's first ZKRollup implementation designed to scale Ethereum, fully optimized for trading.\",\n  labelUltimateSecurity: 'Ultimate Security',\n  labelUltimateSecurityDes:\n    'Assets on Loopring are equally secure as they are on the Ethereum mainnet.',\n  labelLowTransactionFees: 'Low Transaction Fees',\n  labelLowTransactionFeesDes:\n    'Loopring performs most operations, including trade and transfer settlement, off the Ethereum blockchain. This dramatically reduces gas consumption and overall transaction cost to small fractions of comparable on-chain cost.',\n  labelHighThroughput: 'High Throughput',\n  labelHighThroughputDes:\n    'Loopring can settle ~2000 transactions per second with near instant finality.',\n  labelFAQs: 'FAQs',\n  labelBtradeSwapTitle: 'Block Trade',\n  labelViewMore: 'View more',\n  labelVault: 'Portal',\n  labelInvestDualDes1: 'Experience the Leading On-Chain Structured Product',\n  labelInvestDualDes2: 'Buy the dip or sell at a higher price - all while earning high yields.',\n  labelPortalDes1: 'Unlock the Power of Leveraged Trading',\n  labelPortalDes2: 'Seamlessly borrow tokens against your collateral, paving the way for leveraged trading opportunities. By bridging decentralized and centralized exchanges, Loopring Portal broadens your trading horizon, granting access to tokens beyond the Ethereum network.',\n  labelBtradeDes1: 'Trade with CEX Liquidity',\n  labelBtradeDes2: 'Effortlessly trade tokens with near-zero impact, leveraging multiple liquidity sources across crypto to guarantee the best rates every time.',\n  labelInvestDualTitle: 'Dual Investment',\n  labelLoopringDeFi: 'Loopring DeFi',\n  labelIntroDes1: 'Revolutionizing Decentralized Finance with Cutting-',\n  labelIntroDes2: 'Edge Earning and Trading Solutions',\n  labelIntroDes3: 'Delivering CeFi-like user experiences in a fully trustless environment',\n  labelLearnMore2: 'Learn More',\n  labelReadyForDevelopers: 'Ready for Developers',\n  labelReadyForDevelopersDes:\n    \"Build scalable payment apps, non-custodial exchanges, and NFT marketplaces on Ethereum with Loopring's battle-tested zkRollup technology. Get started with quick-start guides, protocol documentation, a Javascript SDK, and a fully open source codebase.\",\n  labelLaunch: 'Launch',\n  labelInvestTaikoFarmingTitle: 'Taiko Farming',\n  labelInvestTaikoFarmingDes1: 'Earn up to 60x Trailblazers Points by Locking Your TAIKO!',\n  labelInvestTaikoFarmingDes2: 'Farm Trailblazers points at up to 60x while keeping the flexibility to trade or earn with your locked TAIKO.',\n}\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/i18n/index.ts",
    "content": "import i18n from 'i18next'\nimport { initReactI18next } from 'react-i18next'\nimport enUS from './en_US'\n// import zhCN from './zh_CN'\n// import { localStore } from '../storage';\n// the translations\n// (tip move them in a JSON file and import them)\nexport enum LanguageType {\n  en_US = 'en_US',\n  zh_CN = 'zh_CN',\n}\n\nexport enum languageMap {\n  en_US = 'en',\n}\n\nexport type LanguageKeys = keyof typeof LanguageType\n\nexport const resources = {\n  en_US: { ...enUS },\n  // zh_CN: {...zhCN},\n}\n\n// const initLng = JSON.parse(localStorage.getItem('persist:settings') as string)?.language === `\"${LanguageType.zh_CN}\"` ? LanguageType.zh_CN : LanguageType.en_US\n\nconst initLng = LanguageType.en_US\n\ni18n.use(initReactI18next).init({\n  resources,\n  ns: ['common', 'layout', 'tables', 'landPage', 'error', 'webEarn'],\n  defaultNS: 'common',\n  lng: initLng,\n  load: 'currentOnly',\n  fallbackLng: LanguageType.en_US,\n  // supportedLngs: [LanguageType.en_US, LanguageType.zh_CN],\n  keySeparator: '.', // we do not use keys in form messages.welcome\n  interpolation: {\n    escapeValue: true, // react already safes from xss\n    formatSeparator: `, `,\n    // format: function (value, _format, lng) {\n    //\n    //   if (\n    //     Object().toString.call(value) === \"[object Array]\" &&\n    //     lng === LanguageType.en_US\n    //   ) {\n    //     return value.join(\", \");\n    //   }\n    //   return value;\n    //   // if (format === 'uppercase') return value.toUpperCase();\n    //   // return value;\n    // },\n  },\n  react: {\n    bindI18n: 'languageChanged',\n    // bindI18nStore: '',\n    transEmptyNodeValue: '',\n    transSupportBasicHtmlNodes: true,\n    transKeepBasicHtmlNodesFor: ['br', 'strong', 'i'],\n    useSuspense: true,\n  },\n})\nexport default i18n\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/i18n/zh_CN/common.ts",
    "content": "/* eslint-disable max-len */\nexport default {\n  labelErrorTitle: 'Error Detail:',\n  labelNoContent: 'No Content',\n  labelError: '错误',\n  tokenEnter: '输入币种',\n  tokenEnterPaymentToken: '',\n  tokenMax: '可用: ',\n  tokenNFTMaxMINT: 'Max:',\n  tokenHave: '可用:',\n  tokenEnterReceiveToken: '',\n  tokenSelectToken: '选择币种',\n  tokenExchange: '转换',\n  tokenNotEnough: '{{belong}}余额不足无法交易',\n  tokenSearchCoin: '搜索交易币种',\n  swapTitle: '兑换',\n  swapTolerance: '滑点范围',\n  labelSwapToleranceTooltips:\n    'Your trade will revert if the price changes unfavorably by more than this percentage.',\n  swapPriceImpact: '价格影响',\n  labelSwapPriceImpactTooltips:\n    'The difference between market price and estimated price due to trade size',\n  swapMinReceive: '最少买入',\n  swapMinReceiveS: 'Min. Received',\n  labelSwapMinReceiveTooltips:\n    'Because the pool price changes dynamically, the price you see when placing an order may be inconsistent with the final transaction price, but the protocol can guarantee that you will receive at least this amount.',\n  swapFee: '费用',\n  swapFeeS: 'Est. Fee',\n  labelSwapFeeTooltips:\n    'The trading fee is determined by your VIP level and the size of your trade. Small trades (below ~$100) incur a higher fee. Please review the fee before confirming.',\n  swapBtn: '兑换',\n  goBack: '返回',\n  resetTitle: '重置{{layer2}}账号密钥',\n  resetLabelEnterToken: '请选择消耗代币',\n  resetDescription:\n    '创建一个新的{{loopringL2}}身份验证签名密钥（无需备份），该操作将会<1>取消您的所有待定指令</1>。',\n  resetFee: '{{count}} GAS ≈ ${{price}} 费用',\n  resetLabelBtn: '重置',\n  labelActiveEnterToken: 'Select payment token',\n  labelActiveAccountDescription:\n    'You need to have enough balance for {{layer2}} creation as below.',\n  labelActiveAccountFee: 'Fee {{count}} GAS ≈ ${{price}}',\n  labelActiveAccountBtn: 'Reset',\n  depositLabelEnterToken: '选择充值代币',\n  depositDescription: '您的充值将会在以太坊<1>确认</1>后<3>两分钟</3>内到账。',\n  depositAndActiveDescription:\n    '完成一次充值来激活您的路印{{loopringL2}}账号。您的充值将会在以太坊<1>确认</1>后<3>两分钟</3>内到账。',\n  depositLabelRefer: '请输入推荐您的ENS，地址，或者账号ID。(选填)',\n  depositLabelPlaceholder: '以太坊地址， 账号ID或ENS',\n  withdrawDescription:\n    '提现操作会被提交到以太坊的下一个区块，一般会在<1>30分钟到2小时</1>内到账。（如果以太坊的GAS价格<5>超过500GWei</5>的话，可能会存在<3>长时间的延迟</3>）',\n  withdrawTypeLabelFast: '快速提现（最快15秒到账）',\n  withdrawTypeLabelStandard: '普通提现（约25分钟）',\n  labelConnectWallet: '连接钱包',\n\n  labelCustomer: '自定义',\n  labelChange24h: '{{timeUnit}} 涨幅',\n  labelDepth: '深度',\n  labelTrend: '价格',\n  label1W: '1周',\n  label1H: '1小时',\n  label1D: '1日',\n  labelCopyAddress: '复制地址',\n  labelDisconnect: '断开',\n  labelLockLayer2: '锁定',\n  labelUnLockLayer2: '解锁',\n  labelSwitchAccount: '切换钱包',\n  labelViewEth: '跳转至Etherscan',\n  labelQRCode: '查看二维码',\n  labelShowAccountInfo: '查看,设置账号信息',\n  labelAssetTitle: '总资产({{loopringL2}})',\n  labelAssetMobileTitle: '{{l2Symbol}} Total Assets',\n  labelShowAccount: '显示或隐藏总资产',\n  labelLevel: 'VIP等级',\n  labelOrderbook: '订单本',\n  labelSetPublicKey: '设置 EdDSA 公钥',\n  labelTitleSecurity: '安全设置',\n  labelTitleResetL2Keypair: '重置{{loopringL2}}账号密钥',\n  labelBtnReset: '重置',\n  labelHadChangPassword: '您在{{passDay}}修改了密码',\n  labelTitleForceWithdraw: '强制提现',\n  labelBtnForceWithdraw: '强制提现',\n  labelTitleExportAccount: '导出账号',\n  descriptionExportAccount: '你可以导出你的{{loopringL2}}API密钥，在脚本中使用。',\n  labelBtnExportAccount: '导出账号',\n  labelDownloadViewMore: '查看更多',\n  labelTitlePreferences: '偏好设置',\n  labelTitleLayout: '个性化设置',\n  whichColorIsUp: '<0>{{up}} 上涨</0> -- <2>{{down}} 下跌</2>',\n  labelTradeFeeLevel: '您的交易等级评定:',\n  labelLanguage: '显示语言',\n  labelCurrency: '结算货币',\n  currencySetting: '货币设置',\n  labelColors: '选择颜色',\n  labelTheme: '暗黑模式',\n  labelthemeLight: '明亮模式',\n  labelthemeDark: '暗黑模式',\n  labelgreen: '绿色',\n  labelred: '红色',\n  langZH: '中文',\n  langEN: '英语',\n  labelUSDollar: '美金结算',\n  labelCNYYuan: '人民币结算',\n  labelMaker: '挂单',\n  labelTaker: '吃单',\n  labelAssetsTitle: '资产清单',\n  labelVolume: '总量',\n  labelAmount: '成交量',\n  labelLiquidityDeposit: '入金',\n  labelLiquidityWithdraw: '出金',\n  labelAvailable: '可用:',\n  labelTokenAmount: '数量',\n  labelRemoveLiquidityBtn: '立刻出金',\n  labelAddLiquidityBtn: '立刻入金',\n  labelEndLiquidityBtn: '活动已结束',\n  labelTradePanelHideOtherPairs: '隐藏其他交易对',\n  labelLPTokens: '权益代币',\n  labelMyLPToken: '我的权益代币',\n  labelMyLPAToken: '我的 {{symbol}}',\n  labelMyLPBToken: '我的 {{symbol}}',\n  labelMyLPAmountFor: '我的持有比',\n  labelTrade: '兑换',\n  labelAmmList: 'AMM 列表',\n  labelMyPoolShare: '我的份额',\n  labelFee: '费用',\n  labelLPTotal: '总资金池',\n  labelReward: '奖励池',\n  labelMyReward: '我的奖励',\n  labelDate: '日期',\n  labelBack: '返回',\n  labelAPR: 'APR',\n  label24Volume: '24h 交易量',\n  label24VolumeSimple: '24h Vol',\n  labelTVL: '总锁仓量',\n  labelAmmTotalToken: '池子中的代币',\n  labelNoActiveEvent: '暂时没有活动',\n  labelNew: '新的',\n  labelAccount: '账户信息',\n  labelAll: '所有',\n  labelMe: '我的',\n  labelMyTrade: '我的交易',\n  labelRecent: '市场交易',\n  labelMyAmm: '我的AMM流动性',\n  labelMyAmmRecord: '我的AMM记录',\n  labelCurrentActivities: '当前活动',\n  labelPastActivities: '往期活动',\n  labelTotalPositionValue: '我的流动性总价值',\n  labelFeeRewards: '做市返佣',\n  labelMiningRewards: '活动奖励',\n  labelLiquidityValue: '流动性价值',\n  labelCopyAddClip: '复制地址到剪切板！',\n  labelPleaseInputWalletAddress: '请输入地址',\n  labelEmptyDefault: '内容空空的～',\n  labelUnlockAccount: '解锁账号',\n  labelLockWallet: 'Lock Wallet',\n  labelAssetsDistribution: '资产分布',\n  labelTotalAssets: '总资产',\n  labelTxnPageTitle: '充值提现',\n  labelTradePageTitle: '交易记录',\n  labelAmmPageTitle: 'AMM 出入金记录',\n  labelSwapSuccess: '兑换成功！',\n  labelOrderProcessing: '已下单！',\n  labelSwapFailed: '兑换失败！',\n  labelJoinAmmSuccess: '加入流动性池成功！',\n  labelJoinAmmFailed: '加入流动性池失败！',\n  labelExitAmmSuccess: '退出流动性池成功！',\n  labelExitAmmFailed: '退出流动性池失败！',\n  labelConnectBy: '当前连接 <1>{{connectBy}}</1>',\n  labelWrongNetwork: '未识别网络',\n  labelActivatedAccountDeposit: '首次开通{{layer2}}钱包需充值并激活',\n  labelActivatedAccountNotSupport: 'Your wallet does not support {{loopringL2}}.',\n  labelActivatedAccountNotSupportDes:\n    '  The wallet you have connected does not support Loopring Layer 2. Please use a different wallet to connect or download the Loopring Wallet app.',\n  labelNotAllowForSmartWalletTitle: 'Apologize',\n  labelProcessing: '请稍等片刻',\n  labelProviderProcessing: '{{name}}正在连接路印钱包',\n  labelProviderCommonProcessDescribe:\n    '请在{{name}}的弹出窗口内点击确定按钮。 如果{{name}}插件没有主动弹出窗口, 请在浏览器工具栏中点击 <1></1> 图标。',\n  labelWalletConnectProcessDescribe: '正在等待WalletConnect确认相关信息，请耐心等待片刻。',\n  labelWalletConnectQRCode: '请用移动端路印钱包（或支持WalletConnect的应用）扫描二维码',\n  labelSuccessConnect: '使用{{providerName}}连接成功',\n  labelSuccessConnectDescribe: '恭喜，连接成功',\n  labelCopyClipBoard: '复制到剪切板',\n  labelCopyManually: 'Manually Selected & Copy:',\n  labelRejectOrError: '用户拒绝或错误发生, 请<1>点击重试</1>。',\n  labelWalletConnectProcessDescribe2: '请在你的移动应用上点击确认按钮。',\n  labelUnlockProcessing: '正在解锁{{layer2}}账号...',\n  labelFailedConnect: '连接失败',\n  // labelTokenAccess: '等待钱包确认{{symbol}}授权！',\n  labelTokenAccess: '等待钱包确认授权！',\n  labelFailedTokenAccess: '{{symbol}}授权失败！',\n  labelSuccessTokenAccess: '恭喜, 你可以交易 {{symbol}} 了！',\n  labelSuccessUnlockDescribe: '恭喜，解锁成功！',\n  labelSuccessUnlock: '解锁成功',\n\n  labelActivateAccount: '激活账户',\n  labelClose: '关闭',\n  labelRetry: '重试',\n  labelTryNext: '尝试另一种签名',\n  labelQuotePageFavourite: '自选',\n  labelQuotePageAll: '全部',\n  labelQuotePageTradeRanking: '交易竞赛',\n  labelFailedUnlock: '解锁失败',\n  labelFailedUpdateAcc: '更新账号失败',\n  labelUpdateAccSigWarning: '你的钱包不支持当前签名方法，准备尝试另一种签名方式。',\n  labelUpdateAccUserDenied: '签名被拒绝',\n  labelCreateLayer2Title: '创建{{layer2}}账号',\n  labelCreateAccount: '创建{{layer2}}账号',\n  labelUpdateAccount: '激活{{layer2}}账号',\n  labelTryAnother: '尝试另一种签名方式',\n  labelCancel: '取消',\n  describeTitleNoAccount: '该账户还未开通{{layer2}}，点击充值开通钱包。',\n  describeTitleOpenAccounting: '您的充值已提交以太坊，\\n等待以太坊确认。。。',\n  describeTitleOnErrorNetwork: '路印暂不支持您当前登入的网络，\\n请在{{connectName}}切换网络',\n  describeTitleNotActive: '充值钱包, 激活账户, \\n开始二层之旅.',\n  describeTitleConnectToWallet: '点击按钮，连接路印钱包，\\n开始二层之旅.',\n  describeWhatIsGuardian: 'what is Loopring guardian!',\n  describeTitleConnectToWalletAsGuardian: '点击按钮，连接路印钱包，作为守护人',\n  describeTitleLocked: '已连接您的钱包，\\n点击解锁后查看账户信息',\n  labelLiquidityPageTitle: 'AMM 资金池',\n  labelMinReceive: '最少接收量',\n  labelFilter: '搜索',\n  labelMiningPageTitle: '路印流动性挖矿',\n  labelMiningPageViceTitle: '提供流动性以赚取奖励',\n  labelMiningActiveDate: '奖励时间',\n  labelMiningLiquidity: '流动性',\n  labelMiningActivityReward: '活动奖励',\n  labelMiningMyShare: '我的份额',\n  labelMiningPlaceOrderBtn: '立刻下单',\n  labelMiningViewDetails: '查看活动详情',\n  labelMiningMaxSpread: '最大 spread',\n  labelMiningMyReward: '我的奖励',\n  labelMiningReward: '活动奖励',\n  labelCookiesAgree: '同意',\n  labelLimitMin: '最小下单量{{arg}}',\n  labelAmmMinAnd: 'and',\n  labelLimitMax: '{{arg}} 最大下单量{{arg}}',\n  labelOrderSmall: 'Order too small (>= 100.5LRC)',\n  labelEnterAmount: '请填写兑换数',\n  labelAgreeLoopringTxt: '允许路印使用Cookies。',\n  labelLayer2HistoryTransactions: '充值提现',\n  labelLayer2HistoryTrades: '成交明细',\n  labelLayer2HistoryAmmRecords: '出入金记录',\n  labelTxnDetailHeader: '充值提现',\n  labelDTxnDetailHeader: '充值记录',\n  labelWTxnDetailHeader: '提现记录',\n  labelTTxnDetailHeader: '转账记录',\n  labelTxnDetailHash: '{{layer2}}哈希值',\n  labelTxnDetailHashLv1: '以太坊哈希值',\n  labelTxnDetailStatus: '状态',\n  labelTxnDetailTime: '时间',\n  labelTxnDetailFrom: '付款方',\n  labelTxnDetailTo: '收款方',\n  labelTxnDetailAmount: '数量',\n  labelTxnDetailFee: '费用',\n  labelTxnDetailMemo: '备注',\n  labelTxnDetailProcessed: '已完成',\n  labelTxnDetailProcessing: '处理中',\n  labelTxnDetailFailed: '失败',\n  labelAgreeConfirm: '确认',\n  labelDisAgreeConfirm: '取消',\n  labelImpactAgree: '请输入大写\"AGREE\"再次确认。',\n  labelImpactTitle: '兑换二次确认',\n  labelPriceExtraGreat: '您设置的价格已经{{compare}}市价的20%，您确定执行此操作吗？',\n  labelPriceCompareGreat: '大于',\n  labelPriceCompareLess: '小于',\n  labelImpactExtraGreat: '您的交易金额将影响池子价格<1> {{value}}</1>，您确定执行此操作吗？',\n  labelCalculating: '计算中...',\n  labelFeeCalculating: '费用计算中...',\n  labelAmmMyTransactions: '我的交易',\n  labelAmmAllTransactions: '所有交易',\n  labelWaitForAuth: '等待钱包签名',\n  labelSignDenied: '签名已被用户拒绝',\n  labelFirstSignDenied: '您的钱包不支持当前签名方法',\n  labelUpdateAccountSuccess: '恭喜你!',\n  labelUpdateAccountSuccess2: '您已经成功激活路印二层账号!',\n  labelResetAccountSuccess: '恭喜你!',\n  labelResetAccountSuccess2: '您已经成功重置路印二层账号密钥!',\n  labelUpdateAccountSubmit: '开户申请以提交',\n  labelUnlockAccountSuccess: '解锁成功!',\n  labelUnlockAccountFailed: '解锁失败!',\n  labelNotSupportTitle: '告知',\n  labelNotAllowTrade:\n    '抱歉！尊敬的用户，根据我们的使用条款，我们无法为您的IP地址提供交易下单和AMM入金功能。',\n  labelKnown: '知道了',\n  labelResetAccount: '重置{{layer2}}账号密钥',\n  labelExportAccount: '导出账号',\n  labelExportAccountNoPhotos: '请勿拍照',\n  labelExportAccountDescription:\n    '请对以下信息严格保密，不要明文存储到任何联网的电脑中；否则，您在交易所的资产可能会因为低价下单而受损失。',\n  labelExportAccountCopy: '复制',\n  labelExportAccountSuccess: '导出账号成功!',\n  labelExportAccountFailed: '导出账号失败!',\n  // labelCreateAccountApproveWaitForAuth: 'Waiting for <1>{{symbol}}</1> Approve...',\n  labelCreateAccountApproveDenied: 'Signature request rejected!',\n  labelAmmSwitch: '切换',\n  labelCreateAccountDepositDenied: '您以拒绝充值 {{value}} {{symbol}}, 账户未激活',\n  labelSlippageAlert: '滑点过大将会影响您出金后收到的token数量',\n  labelOrderGroup: 'Order Records',\n  labelOrderTableOpenOrder: '当前委托',\n  labelOrderTableOrderHistory: '历史委托',\n  labelResetLayout: '重置布局',\n  labelResetMobileLayout: 'Reset',\n  labelBtnFix: '重置',\n  labelProSell: '卖',\n  labelProBuy: '买',\n  labelProLimit: '限价',\n  labelProMarket: '市价',\n  labelProPrice: '价格',\n  labelProBaseLabel: '数量',\n  labelProQuoteLabel: '成交额',\n  labelProLimitBtn: '{{tradeType}} {{symbol}}',\n  labelProMarketBtn: '{{tradeType}} {{symbol}}',\n  labelProOrderbook: '订单',\n  labelProTrades: '交易',\n\n  labelProToolbar24hChange: '24h 涨跌',\n  labelProToolbar24hHigh: '24h 最高价',\n  labelProToolbar24hLow: '24h 最低价',\n  labelProToolbar24hBaseVol: '24h 成交量（{{symbol}}）',\n  labelProToolbar24hQuoteVol: '24h 成交量（{{symbol}}）',\n  labelErrorPricePrecisionLimit: '限价 {{symbol}}，最多可保留小数点后 {{decimal} 位',\n  labelDepthPrice: '价格({{symbol}})',\n  labelDepthAmount: '数量({{symbol}})',\n  labelDepthTotal: '累积',\n\n  labelProChartTitle: '图表',\n  labelProTimeDefault: '分时(1分钟)',\n  labelProTime1m: '1分钟',\n  labelProTime5m: '5分钟',\n  labelProTime15m: '15分钟',\n  labelProTime30m: '30分钟',\n  labelProTime1H: '1小时',\n  labelProTime2H: '2小时',\n  labelProTime4H: '4小时',\n  labelProTime12H: '12小时',\n  labelProTime1D: '1天',\n  labelProTime1W: '1周',\n  labelProTime1M: '1月',\n  labelProChartTradingView: '蜡烛图',\n  labelProChartDepth: '深度图',\n  labelProOrderPrice: '委托价',\n  labelProOrderTotalAmount: '累积',\n\n  labelSwapCancelled: '交易被取消',\n  labelSuccessfully: '成功',\n  labelWarning: '警告',\n  labelFailure: '失败',\n  labelPrompt: '提示',\n\n  // labelSwapCancelled: '交易被取消',\n  // labelSuccessfully: '成功',\n  // labelWarning: '警告',\n  // labelFailure: '失败',\n  // labelPrompt: '提示',\n\n  labelComingSoon: '敬请期待',\n  labelTradeProHideOtherPairs: '隐藏其他交易对',\n  labelCancelAllOrders: '确认撤销全部订单？',\n  labelConfirm: '确定',\n  labelSettingFee: 'Token Order for Fees',\n  descriptionSettingFee:\n    'Change the token priority order to adjust which tokens will be used for fees first.',\n  labelBtnEdit: 'Edit',\n  labelSettingChargeFeeOrder: 'Token Order for Fees',\n  labelDesSettingChargeFeeOrder: '{{loopringL2}} will use this token order when processing fees.',\n  labelReset: 'Reset',\n  labelQueryFeeOK: 'Save',\n  depositLimit:\n    'Limit Orders \\n Used to set the maximum or minimum price \\n at which you are willing to buy or sell.',\n  depositMarket: 'Market Orders \\n Used to buy or sell immediately \\n at the current market price.',\n  labelTransactions: 'Transactions',\n  labelMyRewards: 'My Rewards',\n  labelClearAll: 'Clear All',\n  labelProviderAgree: 'I have read, understand, and agree to the <1> Terms of Service </1>.',\n  labelNFTName: 'Name:',\n  labelNFTDetail: 'Details',\n  labelNFTTokenStandard: 'Token Standard:',\n  labelNFTTokenMinted: 'Token Minted:',\n  labelNFTDescription: 'Description:',\n  labelNFTDate: 'Date:',\n  labelNFTDeployContract: 'Deploy Contract',\n  labelNFTSend: 'Send:',\n  labelNFTDeploy: 'Deploy:',\n  labelNFTDeploying: 'Deploying',\n  labelNFTMyNFT: 'My NFTs - Collection: {{collection}}',\n  labelNFTTokenID: 'ID:',\n  labelNFTTYPE: 'Token Standard:',\n  labelNFTRoyaltyPercentage: 'Royalty (%):',\n  labelNFTID: 'ID:',\n  labelNFTMinter: 'Minter:',\n  labelNFTMetadata: 'Metadata:',\n  labelNFTMint: 'Create NFT',\n  labelNFTCreateCollection: '+ Create Collection',\n  labelNFTTitleMyNFT: 'My NFTs',\n  labelNFTTOTAL: 'Amount:',\n  labelInformation: 'Notification',\n  labelNoticeForProvider:\n    'Loopring currently supports the following wallet connections: {{name}}. Please make sure to use one of these when attempting to connect.',\n  labelIKnow: 'OK',\n  labelYes: 'Yes',\n  labelNo: 'No',\n  labelNoticeForNoMetaNFT:\n    'Your NFT does not contain Metadata or media information. \\n Are you sure you still wish to {{ method }} this NFT?',\n  labelAgreeConfirmNotShowAgain: 'I know & not show again',\n  labelInvalidCID: 'Invalid CID. CIDv0 is start with `Qm`, CIDv1 only works for dag-pb',\n  labelInvalidAddress: 'Invalid address, ENS',\n  labelInvalidisCFAddress: 'Loopring Counterfactual wallet is disabled {{way}} {{token}}',\n  labelInvalidisContract1XAddress: 'Loopring wallet 1.x is disabled {{way}} {{token}}',\n  labelInvalidisContractAddress: '{{way}} of {{token}} to Contract wallet is not available',\n  labelInvalidisLoopringAddress:\n    'This address does not yet have an active {{loopringL2}}, {{way}} of {{token}} is disabled!',\n  labelInvalidisSameAddress: 'Cannot {{way}} to your own address.',\n  labelTradeRaceRanking: 'Trading Leaderboard',\n  labelTradeRaceYourRanking: 'Your ranking',\n  labelTradeRaceGoTrading: 'Go to trade',\n  labelTradeReadRule: 'Read Rules',\n  labelTradeRaceRewards: 'Rewards',\n  labelTradeRaceRules: 'Activity Rules',\n  labelTradeRaceStart: 'Activity ends in:',\n  labelTradeRaceReady: 'Activity starts in:',\n  labelTradeRaceEnd: 'Activity has ended',\n  labelDay: 'Days',\n  labelHours: 'Hours',\n  labelMinutes: 'Minutes',\n  labelSeconds: 'Seconds',\n  labelIsNotFeeToken: 'Please deposit {{symbols}}, or {{lastSymbol}} to activate your {{loopringL2}} account.',\n  labelIsETHDepositAlert: 'Please reserve enough ETH in your account to pay for gas!',\n  labelIsNotEnoughFeeToken:\n    'Please deposit enough token to cover the activation fee: {{fee}} {{symbol}}. Remaining token will appear in your asset after activation',\n  depositNFTAddressLabelPlaceholder: 'please input NFT contract address...',\n  mintNFTAddressLabelPlaceholder:\n    '(CIDv0 or dag-pb CIDv1) eg: QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR',\n  depositNFTIdLabelPlaceholder: 'please input NFT id...',\n  nftDepositDescription:\n    'Creates a smart contract on {{ethereumL1}}, \\n which requires a gas fee. NFTs minted \\nhere remain on {{loopringL2}} until deployed.',\n  labelNFTDescribe: 'Description:',\n  labelNFTTitle: 'Amount',\n  labelNFTDepositInputTitle: 'Amount:',\n  labelNFTTId: 'NFT Token ID:',\n  labelNFTCid: 'IPFS CIDv0 or dag-pb CIDv1:(Store Metadata Information)',\n  labelNFTType: 'Token Standard:',\n  labelNFTAccess: 'Allow Loopring to spend {{symbol}}',\n  labelDeployDenied: 'Signature request was rejected',\n  labelNFTTokenDeployWaitForAuth: 'Allow Loopring to deploy {{symbol}}?',\n  labelDeployFailed: 'Deploy of {{symbol}} has failed!',\n  labelDeploySubmit: 'Deploy of {{symbol}} has been submitted!',\n  labelMint: 'Mint',\n  labelMintDenied: 'Signature request was rejected',\n  labelNFTTokenMintWaitForAuth: 'Allow Loopring to Create {{symbol}}?',\n  labelMintFailed: 'Create of {{symbol}} has failed!',\n  labelMintSuccess: 'Create of {{symbol}} has been submitted!',\n  labelNFTMintBtn: 'Create NFT',\n  labelNFTMintNoMetaBtn: 'Wrong Metadata',\n  labelNFTMintNoMetaDetail:\n    'Your NFT metadata should identify <1>name, image, and royalty_percentage (integer from 0 to 10)</1>.',\n  nftDeployDescription: 'Deploy Collection',\n  nftDeployTitle: 'Deploy Contract',\n  nftMintTitle: 'Create NFT',\n  nftMintBtn: 'Create NFT',\n  labelMintInProgress: 'Processing...',\n  labelNFTDeployBtn: 'Deploy Contract',\n  labelNFTDeployBroker: 'Deploy Broker:',\n  labelDeployInProgress: 'Processing...',\n  labelNFTDeployTitle: 'Deploy Contract',\n  labelVendor: 'Buy with Card',\n  labelLock: 'Lock',\n  labelWalletToWallet:\n    'The connected wallet is a contract address which cannot be used (Except Recover Wallet). If you are connecting a mobile Loopring Smart Wallet, you can protect it and manage guardians within the app.',\n  labelWalletAddAsGuardian: 'Add a guardian',\n  labelWalletInputGuardianCode: 'Input 6 digital Code and Approve',\n  labelWalletScanQRCode: 'Using Loopring Wallet, scan the QR code.',\n  labelWalletInputGuardianCodeDes:\n    'Please contact the owner to obtain the approval code and enter it below.',\n  labelWalletGuardianList: 'Guardian List',\n  labelWalletRequestRecovery: 'Request for Wallet Recovery',\n  labelWalletLoopringSmartWallet:\n    'The connected wallet is a Loopring Smart Wallet. Please use your Loopring Wallet mobile app to add Guardians.',\n  labelWalletNonLoopringSmartWallet:\n    'The connected wallet is a non-Loopring smart contract wallet, which cannot be set as a Guardian. Please try again using a different wallet.',\n  labelWalletGuardianHint:\n    'Easily add other Loopring Wallets as Guardians to secure your identity and crypto assets. After entering the wallet address, the user will receive a notification of the request directly in their Loopring Wallet app. Invite your friends and family to use the Loopring Wallet.',\n  labelWalletLockTitle: 'Lock/unlock Wallet',\n  labelWalletLockDes: 'Who I Protect',\n  labelWalletValidationTitle: 'Approval Requests',\n  labelWalletValidationDes: 'Guardian Request Handling',\n  labelWalletHistoryTitle: 'View History',\n  labelAddProtector: 'add Guardian',\n  labelUnknown: 'Unknown',\n  labelApprove: 'Approve',\n  labelReject: 'Reject',\n  labelWalletApprove: 'Approve Signature',\n  labelCommonList: 'Waiting for your Approve List',\n  labelLogList: 'Log List',\n  labelWalletReject: 'Reject Signature',\n  labelLockAccountSuccess: 'Lock Account Success',\n  labelLockAccountFailed: 'Lock Account Failed',\n  labelApproveSuccess: 'Approve Signature Success',\n  labelApproveFailed: 'Approve Signature Failed',\n  labelRejectSuccess: 'Reject Signature Success',\n  labelRejectFailed: 'Reject Signature Failed',\n  labelYourBalance: 'Your {{layer2}} have: {{balance}}',\n  labelTxGuardianADD_GUARDIAN: 'ADD GUARDIAN',\n  labelTxGuardianGUARDIAN_CONFIRM_ADDITION: 'GUARDIAN CONFIRM ADDITION',\n  labelTxGuardianGUARDIAN_REJECT_ADDITION: 'GUARDIAN REJECT ADDITION',\n  labelTxGuardianGUARDIAN_APPROVE: 'GUARDIAN APPROVE',\n  labelTxGuardianAPPROVE_RECOVER: 'RECOVER WALLET', // RECOVER  16\n  labelTxGuardianAPPROVE_TRANSFER: 'OVER DAILY QUOTA TRANSFER', // APPROVE TRANSFER 18\n  labelTxGuardianAPPROVE_TOKEN_APPROVE: 'TOKEN ACCESS', // 23\n  labelTxGuardianADD_GUARDIAN_WA: 'ADD GUARDIAN', // 34\n  labelTxGuardianREMOVE_GUARDIAN_WA: 'REMOVE GUARDIAN', // 35\n  labelTxGuardianUNLOCK_WALLET_WA: 'UNLOCK WALLET', // 37\n  labelTxGuardianRESET_GUARDIANS_WA: 'RESET GUARDIANS', // 200\n  labelTxGuardianCONTACT_UPDATE_WA: 'RESET GUARDIANS', // 201\n  labelTxGuardianCALL_CONTRACT_WA: 'CALL CONTRACT',\n  labelTxGuardian_recovery: 'recovery wallet',\n  labelTxGuardian_transfer: 'over daily quota transfer',\n  labelTxGuardian_add_guardian: 'add guardian',\n  labelTxGuardian_remove_guardian: 'remove guardian',\n  labelTxGuardian_unlock_wallet: 'unlock wallet',\n  labelTxGuardian_deposit_wallet: 'deposit',\n  labelTxGuardianApprove: 'APPROVE',\n  labelTxGuardianReject: 'REJECT',\n  labelReActiveAccount: 'Re-Activate Account',\n  labelWalletSignType: 'Request for {{type}}',\n  labelSpotTrading: 'Spot Trading Volume (30d in ETH)',\n  labelTradeSpot: 'Trade Spot',\n  labelBuyToken: 'Buy {{token}}',\n  labelCurrentlyLevel: 'Currently {{value}} {{token}}',\n  labelLRCBalance: 'LRC Balance',\n  labelNoticeForForAccountFrozen:\n    'Your wallet’s L2 account is locked. While locked, you can’t perform any L2 operations. If you require further assistance, please send an email to support@loopring.io.',\n  labelAction: 'action',\n  labelGoExplore: 'View transactions on the <1>Loopring Block Explorer</1>.',\n  labelNOETH: 'Need ETH for gas',\n  labelBanxaFeeFree: 'zero fees for a limited time',\n  labellimit: 'limit',\n  labelmarket: 'Market',\n  labelswap: 'Swap',\n  labelamm: 'Amm',\n  labelActiveAccountTitle: 'Activate {{loopringL2}} Account',\n  labelDepositTitle: 'Add Assets from My {{l1Symbol}}',\n  labelDepositTitleAndActive: 'Add Asset from My {{l1Symbol}} & Activate',\n  labelDepositAndActiveBtn: 'Activate {{loopringL2}}',\n  labelDepositTitleActive: 'Activate {{loopringL2}}',\n  depositLabelBtn: 'Receive',\n  labelL2ToL1Title: 'Send to {{l1Symbol}}',\n  labelL2ToMyL1Title: 'Send to My {{l1Symbol}}',\n  labelL2ToOtherL1Title: 'Send to Another {{l1Symbol}}',\n  labelL2ToL1DeployTitle: 'Deploy & Send to {{l1Symbol}}',\n  labelL2toL1EnterToken: 'Select Token',\n  labelSendL1Btn: 'Send',\n  labelSendL1DeployBtn: 'Deploy & Send',\n  labelL2toL1BtnExceed: 'Exceed Max Fast Withdraw amount: {{arg}}!',\n  labelL2toL1BtnExceedWithFee: 'Insufficient balance (with fee)',\n  labelL2toL1Address: '{{l1ChainName}} Address',\n  labelL2toL1MyAddress: 'To my {{l1Symbol}}',\n  labelL2toL1AddressInput: 'Please input the address',\n  labelL2toL1Fee: 'Select payment token',\n  labelL2toL1Fast: 'Fast',\n  labelL2toL1Standard: 'Standard',\n  labelL2toL1LinkRecent: 'Recent withdrawal history',\n  labelL2toL2Title: 'Send to Another {{loopringL2}}',\n  labelL2toL2EnterToken: 'Select Token',\n  transferDescription:\n    'Send assets to any valid {{l1ChainName}} address instantly.\\n Please make sure the recipient address accepts \\n {{loopringL2}} payments before you proceed.',\n  labelL2toL2Btn: 'Send',\n  labelL2toL2Address: 'Recipient',\n  labelL2toL2AddressInput: 'Please input address / ENS / Account ID',\n  labelL2toL2Memo: 'Memo (Optional)',\n  labelL2toL2MemoPlaceholder: 'Please input the memo',\n  labelL2toL2FeeChoose: 'Select payment token',\n  labelL2toL2Fee: 'Network Fee',\n  labelL2toL2FeeNotEnough: 'Insufficient balance',\n  labelL2toL2FeeFastNotAllowEnough: 'Please choose Standard!',\n  labelL2toL2LinkRecent: 'Recent send history',\n  labelL2toL2ExchangeError:\n    'Sending to an Exchange Address {{l2symbol}} account is not supported. {{loopringL2}} accounts cannot be activated on Exchange wallet addresses. Instead, please send to the {{l1Symbol}} account associated with this address.',\n  labelL2toL2SmartWalletError:\n    'This wallet binds with smart contract that does not support {{loopringLayer2}}. You will need to send funds to the {{l1Symbol}} account. ',\n  labelActiveLayer2: 'Activate {{loopringL2}}',\n  labelAddAsset: 'Receive',\n  labelAddAssetBtn: 'Receive',\n  labelSendAsset: 'Send',\n  labelSendAssetBtn: 'Send',\n  labelSend: 'Send',\n  labelReceive: 'Receive',\n  labelWaitingRefer: 'Waiting for approval',\n  labelL1toL2WaitForAuth:\n    'Please confirm to receive {{value}} {{symbol}} to {{to}} {{loopringL2}}.',\n  labelL1toL2Denied: 'You rejected to receive {{value}} {{symbol}}.',\n  labelL1toL2Failed: 'Add asset request of {{value}} {{symbol}} failed!',\n  labelL1toL2Submit: 'Add asset request has been submitted. <1></1>',\n  labelL1toL2NeedApprove: 'Allow Loopring Exchange to spend {{symbol}}',\n  labelL2toL1InProgress: 'Processing...',\n  labelL2toL1Failed: 'Sent {{value}} {{symbol}} to {{l1Symbol}} has failed!',\n  labelL2toL1Success: 'Sent {{value}} {{symbol}} to {{l1Symbol}} was successful!',\n  labelL2toL2InProgress: 'Processing...',\n  labelL2toL2Failed:\n    'Sent {{value}} {{symbol}} from my {{loopringL2}} to another {{loopringL2}} failed!',\n  labelL2toL2Success: 'Sent {{value}} {{symbol}} was successful!',\n  labelUpdateAccountFailed: 'Activate {{loopringL2}} has failed!',\n  labelCreateAccountSubmit:\n    \"Activation of {{loopringL2}} with deposit of {{value}} {{symbol}} has been submitted! \\n Approximately {{count}} minutes remaining...',\",\n  labelCreateAccountFailed:\n    'Activation of {{loopringL2}} with deposit of {{value}} {{symbol}} has failed!',\n  labelL1toL2Hash: 'Recent transactions (From my {{l1Symbol}} to my {{l2Symbol}})',\n  labelL1toL2HashEmpty: 'My {{l1Symbol}} \\u2192 {{loopringL2}} transactions will show up here.',\n  labelL1toL2Record: 'Receive {{value}} {{symbol}}',\n  labelNFTSendL2Btn: 'To Another {{loopringL2}}',\n  labelNFTSendMyL1Btn: 'To My {{l1Symbol}}',\n  labelNFTSendOtherL1Btn: 'To Other {{l1Symbol}}',\n  labelNFTDeploySendMyL1: 'To My {{l1Symbol}} & Deploy Contract',\n  labelNFTDeploySendAnotherL1: 'To another {{l1Symbol}} & Deploy Contract',\n  labelGuid: 'Go to Guide',\n  labelOK: 'Ok',\n  labelL2toL2InvalidAddr: 'Invalid address or ENS',\n  labelL2toL2AddressNotLoopring:\n    '<0></0> This address does not have an activated {{loopringL2}}. Please ensure  the recipient can access {{loopringL2}} before sending.',\n  labelL2toL2AddressType: 'Address Type',\n  labelL2toL2OriginDesc:\n    'Please select the address source. Note: the following trading platforms currently do not support {{loopringL2}}  transfers (Binance, Huobi, Okex…)',\n  labelL2toL2OriginBtnExchange: 'Exchange',\n  labelL2toL2OriginBtnWallet: 'Wallet',\n  labelL2toL2Confirm: 'Confirm',\n  labelL2toL2TokenAmount: 'Token Amount',\n\n  labelActiveAccountFeeNotEnough: 'Insufficient balance <1>Add assets</1>',\n  labelNFTTransferTX: '{{l2Symbol}} \\u2192 {{l2Symbol}}',\n  labelNFTWithdrawTX: '{{l2Symbol}} \\u2192 {{l1Symbol}}',\n  labelNFTDepositTX: '{{l1Symbol}} \\u2192 {{l2Symbol}}',\n  labelNFTDeposit: 'Receive {{loopringL2}} NFT',\n  labelNFTDepositNeedApprove: 'Allow Loopring to spend {{symbol}} and deposit it?',\n  labelNFTDepositBtn: 'Receive NFT',\n  labelNFTDepositTitle: 'Receive NFT from my {{l1Symbol}}',\n  labelNFTContractAddress: 'Contract:',\n  labelNFTAmount: 'Amount:',\n  labelNFTTokenDepositWaitForAuth: 'Please confirm to send {{loopringL2}} {{symbol}}',\n  nftMintDescription:\n    'Paste in the CID that you obtained from uploading \\n the metadata.json file (point 11 above) - if successful,\\n the data from the metadata.json file you created contained\\n within the folder will populate the Name\\n and Image below.',\n  labelNFTMintInputTitle: 'Amount <1>\\uFE61</1>',\n  labelL1toL2Vendor:\n    'Use a Loopring partner to deposit funds.\\nOnce your order is confirmed by Loopring,\\n it will be added to your balance within 2 minutes.',\n  depositLabelTo: 'To address, Account ID or ENS.',\n  labelAddressNotLoopring: \"Account doesn't have an active {{loopringL2}}\",\n  labelMINTNFTTitle: 'Create NFT (ERC1155)',\n  labelIPFSUploadTitle: 'Preview Image (Dimensions: 1:1) <1>\\uFE61</1><2>\\u2139</2>',\n  labelIPFSUploadTooltips:\n    'The file uploaded here will be used as the cover image when displaying NFT item.',\n  labelIPFSUploadMediaTitle: 'Multimedia Content (image, audio, video and 3D)<1>\\u2139</1>',\n  labelIPFSUploadMediaTooltips:\n    'If no file is uploaded here, it will use the same content as “Preview Image”.',\n  labelLoadDes: 'Drag or click to upload files ({{types}}, max size:  {{size}}MB)',\n  labelUpload: 'upload',\n  labelMintNoImageBtn: 'Please upload image',\n  labelMintUserAgree: 'Please agree to the terms of service',\n  labelMintTradeValueBtn: 'Please input amount(1 - 10,000)',\n  labelMintNoRoyaltyPercentageBtn: 'Please input Royalty',\n  labelMintWrongRoyaltyBtn: 'Royalty should be (0 - 10)',\n  labelMintNoNameBtn: 'Please input name',\n  labelNFTMetaBtn: 'Upload metadata & create',\n  labelMintName: 'Name <1>\\uFE61</1>',\n  labelMintCollection: 'Choose Collection <1>{{required}}</1><2></2>',\n  labelMintCollectionTooltips: 'This is the collection where your NFT will appear.',\n  labelMintRoyaltyPercentage: 'Royalty (%) <1>\\uFE61</1><2>\\u2139</2>',\n  labelMintRoyaltyPercentageRange: 'Max Int:',\n  labelMintRoyaltyPercentageTooltips:\n    'Represents the percentage to be received from each subsequent resale (max 10%).',\n  labelMintDescription: 'Description <1>\\u2139</1>',\n  labelMintDescriptionTooltips:\n    \"The description will be included on the NFT's detail page beneath it's image.\",\n  labelMintProperty: 'Properties (Limit 64) <1>\\u2139</1>',\n  labelMintPropertyTooltips: 'Tags can be added to the NFT for easy searchability and distinction',\n  labelPropertyAdd: 'Add property',\n  labelMintNFT: 'Create NFT',\n  labelL1toL2NFT: 'Receive NFT',\n  labelMyAssetsNFT: 'My NFTs',\n  labelTransactionNFT: 'Transactions',\n  labelMintPropertyKey: 'Key',\n  labelMintPropertyValue: 'Value',\n  labelNFTProperty: 'Properties:',\n  labelConfirmMint: 'Confirm Metadata',\n  labelUseIpfsMintAgree:\n    'I confirm that the NFT minted does not infringe on copyright laws or contain illegal, explicit, sensitive, adult themed, or any other content considered NSFW. We reserve the right to hide inappropriate content if an NFT is discovered to be harmful.',\n  labelL1toL2TitleBridge: 'Add {{loopringL2}} Assets',\n  labelL1toL2TitleBridgeNoConnect:\n    'Connect your {{ethereumL1}} Wallet to transfer assets to any {{loopringL2}} account',\n  labelPayer: 'My Wallet:',\n  labelL1toL2TokenAmount: 'Token Amount',\n  labelL1toL2From: 'From',\n  labelL1toL2TO: 'To {{loopringL2}}',\n  labelAddAssetTitle: 'Add {{loopringL2}} {{symbol}} assets',\n  labelSendAssetTitle: 'Send {{loopringL2}} {{symbol}} assets',\n  labelAddAssetHowto: 'How would you like to add {{loopringL2}} assets?',\n  labelAddAssetTitleActive: 'Add assets & Activate',\n  labelFromMyL1: 'From my {{l1Symbol}} account',\n  labelFromOtherL1: 'From another {{l1Symbol}} account',\n  labelBuyWithCard: 'On-Ramp From Fiat',\n  labelFromOtherL2: 'From another {{loopringL2}} account',\n  labelFromExchange: 'From an exchange',\n  labelOpenInWalletApp: 'Open in wallet app/extension',\n  labelConnectWithDapp: 'Connect with Dapp',\n  labelOpenInWalletTitle: 'Open in wallet',\n  labelOpenInWalletDetail: `URL for adding funds has been copied. You can choose either way to continue:`,\n  labelOpenInWalletDetailLi1: `Open your wallet app and paste the URL into its internal Dapp browser`,\n  labelOpenInWalletDetailLi2: `Open your desktop Chrome browser and paste the URL in Chrome`,\n  labelActiveL2Btn: 'Activate {{loopringL2}}',\n  labelWrongNetworkGuideTitle: 'Wrong Network',\n  labelWrongNetworkGuide:\n    'Your chosen network is not currently supported on Loopring. Please choose {{l1ChainName}} main Network or test Network Goerli',\n  labelSenAssetTitle: 'Send {{symbol}} from {{loopringL2}}',\n  labelSendTOL2: 'To another {{loopringL2}} account',\n  labelSendToMyL1: 'To my {{l1Symbol}} account',\n  labelSendToOtherL1: 'To another {{l1Symbol}} account \\n(incl. exchange)',\n  labelSendAssetHowto: 'Where would you like to send your crypto to',\n  labelL1toL2: 'Add {{loopringL2}} assets From My {{l1Symbol}}',\n  labelActivatedAccountChargeFeeList:\n    'Please make sure one of the below tokens with the minimum quantity in your {{loopringL2}} account to proceed',\n  labelReceiveAddress: 'Receive Address',\n  labelAssets: '{{loopringL2}} Assets',\n  labelReceiveAddressGuide:\n    'Please use a {{loopringL2}} account when transferring to avoid loss of assets ({{symbol}}).',\n  labelL2toL2: 'Send to another {{loopringL2}}',\n  labelL2toL1: 'Send to {{l1Symbol}}',\n  labelBenefitL2:\n    \"As {{l1ChainName}}'s first ever zkRollup, {{loopringL2}} allows you to avoid costly gas fees and network congestion with the same security as mainnet - 100x cheaper and faster.\\n\\nActivating your {{loopringL2}} account requires a small payment fee. \",\n  labelNotBalancePayForActive: 'Insufficient balance in your {{loopringL2}} account',\n  labelEnoughBalancePayForActive: 'You have enough balance to pay for {{loopringL2}} creation.',\n  labelHaveInProcessingL1toL2:\n    'If you have already started the deposit, please be patient and recheck as transactions on {{l1ChainName}} can take up to 30 minutes.',\n  labelWaitingL1toL2: 'Please wait',\n  labelAddAssetGateBtn: 'Add assets',\n  labelActiveLayer2Btn: 'Activate {{loopringL2}}',\n  labelActiveLayer2PayBtn: 'Pay Activation Fee',\n  labelBalanceActiveAccountFee:\n    '{{symbol}}: <2>Fee {{fee}};</2><3>My {{loopringL2}} balance: {{count}}</3>',\n  labelToAddressShouldLoopring: 'To address is no {{loopringL2}}',\n  labelBridgeSendTo: 'Send to (address, Account ID or ENS)',\n  labelInvalidAddressClick:\n    'Invalid Wallet Address, {{way}} of {{token}} is disabled! <1>Click to input another receive address </1>',\n  labelENSShouldConnect: 'Receive address is an ENS, please connect wallet to check real address',\n  labelToken: 'Token',\n  labelMinRequirement: 'Min Requirement',\n  labelAvailability: 'Availability',\n  labelWhatProvider: 'Which provider would you like to use?',\n  labelMemo: 'Memo',\n  labelAdvanceMint: 'Advance Create NFT',\n  labelWalletTypeDes:\n    'Please confirm the address type again to ensure the assets are not mistakenly sent to the exchange address. ',\n  labelWalletTypeOptions: '{{type}} Wallet',\n  labelWalletTypeOtherSmart: 'Other Smart',\n  labelWalletTypeLoopring: 'Loopring',\n  labelWalletTypeEOA: 'EOA',\n  labelWalletTypeExchange: 'Exchange',\n  labelEOADes:\n    'There is no smart contract binds with this wallet address. (e.g. MetaMask, imtoken, Ledger, Trezor, etc....) ',\n  labelLoopringDes:\n    'This wallet is created using Loopring Wallet mobile app and binds with Loopring smart contract.',\n  labelOtherSmartDes:\n    'This wallet binds with smart contract that does not support {{loopringLayer2}}. You will need to send funds to the {{l1Symbol}} account. ',\n  labelExchangeDes:\n    'The following trading platforms currently do not support {{loopringL2}} transfers (Binance, Coinbase, etc...). You will need to send funds to the {{l1Symbol}} account. ',\n  labelExchangeTypeDes: 'Please select the address source:',\n  labelNonExchangeTypeDes:\n    'eg: Loopring Wallet, Metamask, Coinbase Wallet, imtoken, Ledger, Trezor... EOA wallet',\n  labelNonExchangeType: 'Non-Exchange Wallet',\n  labelExchangeType: 'Exchange',\n  labelExchangeBinance: 'Binance',\n  labelExchangeBinanceDes: '',\n  labelExchangeHuobi: 'Huobi',\n  labelExchangeHuobiDes: 'Transactions need to wait 24 hours',\n  labelExchangeCoinbase: 'Coinbase',\n  labelExchangeOthers: 'Other Exchanges',\n  labelExchangeOthersDes: '',\n  labelL2toL1AddressType: 'Address Type',\n  labelConfirmBtrade: 'Confirm CEX Support',\n  labelConfirmDetail:\n    '<0>Before withdrawing, please confirm with your CEX support that they accept deposits from smart contracts.</0>' +\n    '<1>{{l2Symbol}} to {{l1Symbol}} withdrawing is performed via a smart contract. The CEX depositing address may not be able to automatically acknowledge the deposit.</1>' +\n    '<2>If the deposit does not appear at the CEX address within 24 hours, please contact your CEX support and ask they manually acknowledge the transaction.</2>',\n  labelBtradeUnderstand: 'I understand and acknowledge the risk',\n  labelMintFee: 'Create Fee',\n  labelMintFeeNotEnough: 'Insufficient balance',\n  labelMintFeeChoose: 'Select payment token',\n  labelLayerSwapUnderstand: 'I understand and acknowledge the risk',\n  labelIUnderStand: 'I Understand',\n  labelLayerSwapUnderstandDes:\n    'LayerSwap is a 3rd party App service provider to help move tokens from exchange to {{loopringL2}} directly. If you have any concerns regarding their service, please check out their <1>TOS</1>.',\n  labelInvestAmmTitle: 'AMM Pools',\n  labelInvestBalanceTitle: 'My Investments',\n  labelInvestDualRefreshErrorTitle: 'Subscription Failed',\n  labelInvestDualRefreshError: 'The subscription of {{token1}}/{{token2}} Dual Investment failed.',\n  labelTransactionsLink: 'Transactions',\n  labelAMMTransactionsLink: 'View Pool Transactions',\n  labelNFTMintWrongCIDBtn: 'Wrong MetaData format',\n  labelWithdrawBtn: 'Withdraw',\n  labelFWithdrawFee: 'Fee',\n  labelFWithdrawNotEnough: 'Insufficient balance',\n  labelForceWithdrawTitle: 'Force Withdraw',\n  labelForceWithdrawWaitForAuth: 'Please confirm to force withdraw {{symbol}}',\n  labelForceWithdrawDenied: 'You rejected to force withdraw {{symbol}}.',\n  labelForceWithdrawInProgress: 'Processing...',\n  labelForceWithdrawFailed: 'Force withdraw has failed!',\n  labelForceWithdrawSubmit: 'Force withdraw has been submitted',\n  labelForceWithdrawToken: 'Token Amount',\n  labelForceWithdrawFee: 'Network Fee',\n  labelForceWithdrawEnterToken: 'Select Token',\n  labelPleaseForceWithdrawAddress: 'Please enter the address you wish to withdraw from',\n  labelForceWithdrawAddress: 'The address you wish to withdraw from',\n  labelForceWithdrawDes:\n    \"If the recipient doesn't have an active {{loopringL2}} account, you will be able to withdraw the token from {{l2Symbol}} to {{l1ChainName}} {{l1Symbol}}. This process is usually only needed when tokens were sent to a CEX address using {{loopringL2}}. Since the CEX does not have access to the {{l2Symbol}} account, you will need to perform this action to reclaim the tokens.\",\n  labelForceWithdrawConfirm:\n    'This feature allows a user to move their {{l2Symbol}} tokens to the {{l1Symbol}} address. The target address must either be a wallet or exchange address',\n  labelForceWithdrawConfirm1:\n    'This operation usually requires more than 30 minutes to take effect, as it needs to interact with {{l1ChainName}} Mainnet. Please be patient.',\n  labelNFTSendBtn: 'Send',\n  labelNFTProperties: 'Properties',\n  labelNFTDescription2: 'Description',\n  labelForceWithdrawNotAvailable:\n    '{{loopringL2}} account is activated in this address. For security reason, Loopring would not allow other user to force withdraw token from its {{l2Symbol}} to {{l1symbol}} anymore',\n  labelForceWithdrawNoToken: 'No token is detected from this address to operate',\n  labelForceWithdrawBtn: 'Force Withdraw',\n  labelInvestDefiTitle: 'ETH Staking',\n  labelInvestDefDeposit: 'Subscribe',\n  labelInvestDefWithdraw: 'Redeem',\n  labelNFTDepositLabel: 'Receive NFT',\n  labelDefiFee: 'Fee',\n  labelDefiMin: 'Minimum of {{arg}}',\n  labelDefiNoEnough: 'Insufficient balance',\n  labelDefiMaxBalance:\n    'It is not possible for the Loopring pool to fulfil your complete request at the moment. You can only redeem {{maxValue}} now.\\n' +\n    'You can choose one of the following approaches for the remaining amount:',\n  labelDefiMaxBalance1:\n    '<li>Withdraw {{symbol}} to {{l1Symbol}} and trade through 1Inch or {{type}}, etc...</li>' +\n    '<li>The Loopring pool will rebalance soon. Please come back later to redeem.</li>',\n  labelDefiNoBalance:\n    '<span>It is not possible for the Loopring pool to fulfil your complete request at the moment.</span>' +\n    '<span>You can choose one of the following approaches for the remaining amount:</span>',\n  labelDefiNoBalanceList:\n    '<li>Withdraw {{symbol}} to {{l1Symbol}} and trade through 1Inch or {{type}}, etc...</li>' +\n    '<li>The Loopring pool will rebalance soon. Please come back later to redeem.</li>',\n  labelDefiMaxBalanceJoin:\n    \"The quota is almost sold out and can't fulfil your complete order. You can only subscribe {{maxValue}} now. Loopring will setup the pool soon, please revisit for subscription later. \",\n  labelDefiNoBalanceJoin:\n    'Loopring will set up the pool soon. Please come back later to subscribe.',\n  labelInvestBtn: 'Subscribe',\n  labelRedeemBtn: 'Redeem',\n  labelVipTitle: 'VIP',\n  labelSecurity: 'Security',\n  labelFeeTitleList: 'Fee',\n  labelInvestOverviewTitle: 'Overview',\n  labelTitleOverviewToken: 'Total Investment Tokens',\n  labelInvestType_AMM: 'AMM Pools',\n  labelInvestType_STAKE: 'ETH Staking',\n  labelInvestType_DUAL: 'Dual Investment',\n  labelInvestType_STAKELRC: 'LRC Staking',\n  labelInvestAll: 'Mixed',\n  labelInvestFlexible: 'Flexible',\n  labelInvestDuration: 'Duration',\n  labelDefiOrderTable: 'ETH Staking',\n  labelTitleMyInvestAvailable: 'My Holding Tokens',\n  labelViewMore: 'View more',\n  labelInvestSuccess: 'Successfully {{type}} {{symbol}}',\n  labelInvestFailed: 'Subscribe Failed',\n  labelWSETHDefiRiskTitle: 'What is ETH Staking via Lido?',\n  labelRETHDefiRiskTitle: 'What is ETH Staking via Rocket Pool?',\n  labelWSETHDefiRisk:\n    '<p>Lido is a liquid staking solution for ETH 2.0 backed by industry-leading staking providers. Lido lets users stake their ETH - without locking assets or maintaining infrastructure.</p>' +\n    '<p>When using Lido to stake your ETH on the {{l1ChainName}} beacon chain, users will receive a token (stETH), which represents their ETH on the {{l1ChainName}} beacon chain on a 1:1 basis. It effectively acts as a bridge bringing ETH 2.0’s staking rewards to ETH 1.0.</p>' +\n    \"<p>wstETH is the wrapped version of stETH. The total amount of wstETH doesn't change after users receive the token. Instead, the token’s value increase over time to reflect ETH staking rewards earned.</p>\",\n  labelRETHDefiRisk:\n    '<p>Rocket Pool is the first truly decentralized {{l1ChainName}} staking pool. Rocket Pool’s liquid staking token allows anyone to earn staking rewards easily without running staking software or locking assets. Rocket Pool handles all of the {{l1ChainName}} validator operations with smart contracts on the Execution layer.</p>' +\n    \"<p>Acquiring and holding rETH in your wallet means that you are staking ETH. rETH's value continuously increases relative to ETH, indicating the daily stake reward received.</p>\" +\n    '<p></p>',\n  labelWSETHDefiRisk2:\n    \"<0>It is important to note that users can't redeem wstETH for ETH until phase 2 of {{l1ChainName}} 2.0. However, users are able to trade wstETH for ETH on various exchanges at market prices.</p>\" +\n    '<1>Loopring will provide a pool to allow users to trade wstETH for ETH directly on {{layer2}}. The pool will rebalance periodically when it reaches a specific threshold. If there is not enough inventory on {{layer2}}, user can always withdraw their wstETH tokens to Layer 1 and swap for ETH in Lido, Curve, or 1inch.</p>',\n  labelRETHDefiRisk2:\n    '<0>Loopring will provide a pool to allow users to trade rETH for ETH directly on {{layer2}}. The pool will rebalance periodically when it reaches a specific threshold. If there is not enough inventory on {{layer2}}, users can always withdraw their rETH tokens to Layer 1 and swap for ETH in Rocket Pool, 1Inch, etc… </0>' +\n    '<1></1>',\n  labelDefiAgree: 'I have read and understand the risk warning.',\n\n  labelDefiInvest: 'Defi Earn',\n  labelLRCStakingInvest: 'LRC staking',\n  labelLRCStakingRedeemInvest: 'LRC staking Redeem',\n\n  labelDefiClose:\n    'This service is temporarily unavailable as we set up the pool. This process may take several hours to complete. Thank you for your patience!',\n  labelCreateCollection: 'Create Collection',\n  labelCollectionCreateName: 'Contract address for your collection',\n  labelCollectionCreateERC1155: 'Collection ERC-1155',\n  labelCollectionCreateWaiting: 'Waiting for create Collection token Address',\n  labelMintSelect: 'Choose Creation Method',\n  labelMintSelectDes: 'Choose the most suitable approach for your needs.',\n  labelCollectionCreateFailed: 'Create Collection token Address Failed',\n  labelCollectionMetaTitle: 'Import Metadata from IPFS',\n  labelAdvanceCreateCollection: 'Advance Create Collection',\n  labelCreateCollectionSuccess: 'Collection create was successful',\n  labelCreateCollectionFailed: 'Collection create has failed',\n  labelCollectionAdvanceJSON: 'NFT Collection information follow this format: ',\n  labelCopyDemo: 'Click to copy the demo',\n  labelCollectionCreatBtn: 'Create Collection',\n  labelEnterMeta: 'Enter Collection Metadata',\n  labelMintGuid:\n    'Fill up content in GUI and let Loopring to generate necessary metadata and upload to IPFS for you, then use \"Mint\" to create your NFT.',\n  labelAdMintGuid:\n    'Generate all the required metadata and upload to IPFS by yourself first, then use \"Advanced Create NFT\" to create your NFT.',\n  labelFilterTradeNFTSell: 'Sell',\n  labelFilterTradeNFTSelf: 'Self Trade',\n  labelFilterTradeNFTBuy: 'Buy',\n  labelAdMintTitle: 'Advance Create NFT',\n  labelCopyNFTDemo: 'Copy NFT Demo',\n  labelSelectCollection: 'Choose or Create a Collection to Create Your Own NFT',\n  labelSelectCollectionDes: 'A NFT Collection can help you manage and group your NFTs',\n  labelChooseCollectionBtn: 'Choose a Collection to Create NFT',\n  labelNFTMint721Btn: 'ERC721 will coming soon',\n  labelADMint1: 'Prepare NFT metadata',\n  labelADMint2: 'Fill in the IPFS CID',\n  labelADMint3: 'Preview & Create NFT',\n  labelADMintSelect: 'Prepare NFT metadata with proper collection_metadata value',\n  labelHasData: 'Has generated metadata with collection_metadata field',\n  labelNoData: 'Hasn’t generated metadata with collection_metadata field',\n  labelChooseCollection: 'Choose a collection',\n  labelBanner: 'Banner (Dimensions: 3:1)',\n  labelBannerDes: 'Drag or click to upload files ({{types}}, max size:  {{size}}MB)',\n  labelAvatar: 'Avatar (Dimensions: 1:1)',\n  labelAvatarDes: 'Max size: {{size}}MB)',\n  labelTileUri: 'Tile (Dimensions: 5:7) <1>\\uFE61</1>',\n  labelTileUriDes: 'Drag or click to upload files ({{types}}, max size:  {{size}}MB)',\n  labelCollectionDescription: 'Description <1>\\u2139</1>',\n  labelCollectionDescriptionTooltips:\n    'You can describe your collection here. 0 of 1000 characters used',\n  labelCollectionName: 'Collection Name <1>\\uFE61</1>',\n  labelCollectionCreateBtn: 'Create Collection',\n  labelCollectionRequiredName: 'Please input Name',\n  labelCollectionRequiredTileUri: 'Please input tile',\n  labelCollectionIsUploading: 'Source is loading',\n  labelMintNext: 'Next',\n  labelMintCollectionInput: 'Please input contract address',\n  labelMintCid: 'Please input IPFS CID',\n  labelMintBack: 'Back',\n  labelTokenAdMintBtn: 'Enter Amount',\n  labelMintSubmitBtn: 'Create Your NFT',\n  labelMintIPFSCIDDes: 'Fill in the IPFS CID for NFT metadata',\n  labelNFTMintSimpleBtn: 'Create NFT',\n  labelCollectionEditBtn: 'Edit Collection',\n  labelCopyMetaClip: 'Metadata Copied to Clipboard',\n  labelCollectionMetaNoNameORTileUri:\n    'Your Collection metadata is not setup {{type}}, please go to collection panel edit!',\n  labelCollectionMetaMiss: 'Your NFT metadata is no not setup {{type}}.',\n  labelCollectionMetaError:\n    'Your NFT metadata is no not setup {{type}}, please check and fix it from your IPFS site',\n  labelCollectionMetaErrorType: 'correct `royalty_percentage` from 0 to 10',\n  labelNFTServerRefresh:\n    \"Click to refresh the NFT's metadata. This process usually takes around 30 minutes.\",\n  labelNFTServerRefreshSubmit: 'Refresh command submitted',\n  labelNFTCollection: 'Collection',\n  labelNFTCollectionName: 'Collection Name:',\n  labelMyCollection: 'My Collections',\n  labelCounterFactualNFT: '{{l2Symbol}} NFT:',\n  labelCopyUrlClip: 'URL Copied to Clipboard!',\n  labelCollectionMetaData: 'Collection MetaData',\n  labelViewEtherscan: 'Etherscan',\n  labelNFTMyNFTCollection: 'View by Collection',\n  labelNFTMyNFTList: 'View by item',\n  labelNoCollectionCover: 'No Cover Media',\n  labelNoNFTCover: 'No Media Resource',\n  labelNFTAmountValue: 'Amount: {{value}}',\n  labelNFTAmountSimpleValue: ' \\u2A09 {{value}}',\n  labelCollectionItemValue: 'Item: {{value}}',\n  labelCollectionItemSimpleValue: ' \\u2A09 {{value}}',\n  labelMyCollectionsDes:\n    \"Legacy NFTs created in Loopring don't contain collection information. We have added the feature to allow creators to import the collection information so that those NFTs can be categorized well. <1>Go to Import Collection for Legacy NFT</1>\",\n  labelNFTGuid:\n    'Please fill in the appropriate collection metadata field value in your NFT metadata with this string first, then upload it to IPFS to retrieve the CID to continue. <1>view more </1>',\n  labelChooseCollectionTooltips:\n    'This is the collection where your NFT will appear. \\n Note: NFT minted under collection will be bound with different contract address than previous created one. If you have incomplete work to finish and would like them created under previous contract address, you can still use the legacy creation method under <1>https://legacy-nft.loopring.io/</1>.',\n  labelMintPreview: 'Back',\n  labelMintNoCollectionBtn: 'Please Choose Collection',\n  labelInvestDualTitle: 'Dual Investment',\n  labelBuy: 'Buy',\n  labelSell: 'Sell',\n  labelRampNoBalance: 'Insufficient {{belong}} balance',\n  labelBanxaNoBalance: 'Insufficient {{belong}} balance',\n  labelBanxaFeeNoBalance: 'Insufficient {{belong}} balance & fee',\n  labelL2toRampTitle: 'Send to Ramp',\n  labelL2toBanxaTitle: 'Send to Banxa',\n\n  labelDualInvest: 'Invest {{symbol}}',\n  labelDualBase: 'Sell High for {{symbol}}',\n  labelDualQuote: 'Buy {{symbol}} Low',\n  labelDualAgree: 'I have read and understand the risk warning.',\n  labelDualRiskTitle: 'Dual Investment',\n  labelDualInvestBaseTitle: 'Invest {{symbolA}} (Sell High for {{symbolB}})',\n  labelDualInvestQuoteTitle: 'Invest {{symbolA}} (Buy {{symbolB}} Low)',\n  labelDualInvestDes: 'Invest {{symbolA}} to earn more {{symbolA}} or {{symbolB}}',\n  labelDualCurrentPriceTip:\n    'Current Price is based on {{symbol}} derived from some leading exchanges.',\n  labelDualCurrentPrice: '{{symbol}} Current Price:<1>{{price}}</1> {{baseSymbol}}',\n  labelDualCurrentPrice2: 'Current Price:\\n <1>{{price}}</1> {{baseSymbol}}',\n\n  labelDualSuccess: 'Subscription {{symbol}} Successfully',\n  labelDualProcessing: 'Waiting for completion',\n  labelDualProcessingDes:\n    'We will try to fulfill your subscription request within minutes. If your subscription cannot be fully completed within the time frame, the unfilled portion will be unlocked. You can return later to resubscribe.',\n  labelDualFailed: 'Subscribe Failed',\n  labelDualFee: 'Fee',\n  labelDualMin: 'Minimum of {{arg}}',\n  labelDualMax: 'Maximum of {{arg}}',\n  labelDualNoEnough: 'Insufficient balance',\n  labelDualSettleDate: 'Settlement Date',\n  labelDualSubDate: 'Subscription Date',\n  // labelDualCurrentPrice2: '{{symbol}} Current Price',\n  // labelDualCurrentPrice3: '{{symbol}} current Price',\n  labelDualCurrentAPR: 'APR <1>\\u2139</1>',\n  labelDualCurrentAPRDes:\n    'APR is refreshed in real time. We will use the lastest APR at the time you complete the subscription successfully.',\n  labelDualTargetPrice2: 'Target Price <1>\\u2139</1>',\n  labelDualTargetPrice3: 'Target Price',\n\n  labelDualTargetPriceDes:\n    'Target Price is a benchmark price based on USDT. On Settlement Date, the Settlement Price will be compared against this benchmark price.',\n  labelDualRiskDes:\n    'Your investment will be locked up until settlement date after investing and cannot be redeemed before settlement. \\n As we make profit ratio a top priority, the total opened position might vary with your initial investment.',\n  labelDualReturn: 'Return \\n {{symbol}}',\n  labelDualReceive: 'Settlement Calculator',\n  labelDualCalcLabel: 'If {{symbol}} {{tag}} {{target}}',\n  labelDualReturnValue: 'Return {{value}} {{symbol}}',\n  labelDualQuota: 'Total Quota',\n  labelProduct: 'Product',\n  labelDualAssetFrozen_Target: 'Invest Target',\n  labelDualAssetPrice: 'Price',\n  labelDualAssetSettlement_Date: 'SettlementDate',\n  labelDualAssetAPR: 'APR',\n  labelDualAssetAction: 'Detail',\n  labelInvestDualTutorial: 'Tutorial',\n  labelInvestDualTutorialContent:\n    'Dual Investment offers you a chance to sell cryptocurrency high or buy cryptocurrency low at your desired price on your desired date. Once subscribed, users are not able to cancel or redeem the subscription until the Settlement Date.\\n You may be better off holding your cryptocurrency, and may be required to trade your cryptocurrency at a less favorable rate of exchange than the market rate on Settlement Date. Cryptocurrency trading is subject to high market risk. Please make your trades cautiously. There may be no recourse for any losses.',\n  labelInvestDualTutorialCheck1:\n    'I understand that Dual Investment is NOT a principal-guaranteed products.',\n  labelInvestDualTutorialCheck2:\n    'I understand that subscribed assets are locked and users aren’t able to cancel or redeem before the Settlement Date.',\n  labelInvestDualTutorialCheck3:\n    'I understand that I should review the possible scenarios of settlement amount and confirmed the subscription details.',\n  labelInvestDualTutorialCheck4:\n    'Please be aware that the target price in Dual Investment portfolio is USDT. If you subscribe USDC-related product with another token, that token may be converted to USDC if the target price is reached. If you want to completely avoid the USDC depegging risk, you can select USDT-related products instead.',\n  labelInvestDualTutorialCheck5: 'I have read and understand the risk warning.',\n  labelInvestDualBeginerMode: 'Beginner Mode',\n  labelInvestDualBeginerModeDesLine1: 'What is Dual Investment?',\n  labelInvestDualBeginerModeDesLine2: 'You can use the beginner mode to quickly learn.',\n  labelDualAmount: 'Amount',\n  labelDuaInvestmentDetails: 'Dual Investment Details',\n  labelDualOrderTable: 'Dual Investments',\n\n  labelDualBeginnerPriceSmallerThan: 'if Index Price < {{value}}',\n  labelDualBeginnerPriceSmallerThanOrEqual: 'if Index Price ≤ {{value}}',\n  labelDualBeginnerPriceGreaterThan: 'if Index Price > {{value}}',\n  labelDualBeginnerPriceGreaterThanOrEqual: 'if Index Price ≥ {{value}}',\n\n  labelDualBeginnerAtSettlementDay: 'At Settlement Date',\n  labelDualBeginnerIndexPriceDes: 'Index Price is derived from some leading exchanges.',\n  labelDualBeginnerLockingDes: 'Your token for investment will be locked until Settlement Date.',\n  labelDualBeginnerAPR: 'APR: {{APR}}',\n  labelDualBeginnerStep1Title: 'Step 1: Choose a token to sell or buy',\n  labelDualBeginnerStep2Title: 'Step 2: Choose to sell or buy at desired price in the future',\n  labelDualBeginnerSellHigh: 'Sell {{token}} High',\n  labelDualBeginnerBuyLow: 'Buy {{token}} Low',\n  labelDualBeginnerReceiveStable: 'You will receive {{list}} {{last}}',\n  labelDualBeginnerInvestStable: 'You can invest {{list}} {{last}}',\n  labelDualBeginnerLast: 'or {{last}}',\n  labelDualBeginnerStep3Title: 'Step 3: Choose Target Price and Settlement Date',\n  labelDualBeginnerSellHighFor: 'Sell high for {{token}}',\n  labelDualBeginnerBuyLowWith: 'Buy low with {{token}}',\n\n  labelInvestMyAmm: 'My Investments',\n  labelInvestMyDual: 'My Investments',\n  labelInvestMyDefi: 'My Investments',\n  labelInvestMaxDual: 'Max {{value}}',\n  labelDualTitle: 'Dual Investment',\n  labelDualDesSuccess:\n    'Your token for investment is just locked but still in your account as Loopring is a DEX. \\n When the transaction expires, if the settlement price is not reached, you will get a profit and the frozen token will also be unlocked; if the settlement price is reached, your investment and interest income will be converted into the target token at the Target price.',\n  labelDualRefresh: 'Refresh',\n  labelNoticeForMarketFrozen:\n    '{{ type }} is not supported, If you believe this is indeed a bug, please contact us.',\n  labelInvestRangeDay: '{{arg}} Days',\n  labelAmmExit: 'Redeem',\n  labelAmmJoin: 'Subscribe',\n  labelDualPanelClose: 'Go to My Investments',\n  labelDualMobilePrice: '{{symbol}} price:',\n  labelEditCollectionSuccess: 'Collection edit was successful',\n  labelEditCollectionFailed: 'Collection edit has failed',\n  labelEditCollectionBtn: 'Edit',\n  labelEditRestCollectionBtn: 'Reset',\n  labelEditCollectionERC1155: 'Edit My Collection',\n  labelDualSettlementCalculator: 'Settlement Calculator',\n  labelDualSettleDateDur: 'Subscription Length (days)',\n  labelNoInvestContent:\n    'You currently have no investment assets. Start earning now with AMM, ETH Staking, or Dual Investments',\n  labelImportCollection: 'Import Collection for Legacy NFT',\n  labelCheckImportCollectionTitle: 'Import legacy NFTs under contract address to proceed',\n  labelContinue: 'Next',\n  labelImportCollection1: 'Import Collection for Legacy NFT',\n  labelImportCollection2: 'Create/Choose a collection',\n  labelImportCollection3: 'Select NFTs to move into/out of collection',\n  labelSelectContractAddress: 'Contract address',\n  labelImportChooseCollection:\n    'The created collection here can only be used to categorize the Legacy NFT minted without collection_metadata field.\\n You can freely move those NFTs into any collection you created here.',\n  labelImportCollectionundecided: 'Undecided',\n  labelImportCollectionoutside: 'Others',\n  labelImportCollectioninside: 'Current Collection',\n  labelImportCollectionall: 'All',\n  labelImportCollectionundecidedDes: 'items under this contract not classified into a collection',\n  labelImportCollectionoutsideDes:\n    'items under this contract classified into a different collection',\n  labelImportCollectioninsideDes:\n    'items under this contract classified into the current collection',\n  labelImportCollectionallDes: 'all items under this contract',\n  labelImportCollectionTitle: 'Import Collection for Legacy NFT',\n  labelAssetTokens: 'Tokens',\n  labelAssetInvests: 'My Investments',\n  labelAssetRedPacket: 'Red Packets',\n  labelORCreateCollection: 'Or <1>Create Collection</1>',\n  labelCreateLegacyCollection: 'Create Legacy Collection',\n  labelNoLegacyCollection: 'You have no Legacy Collection, please',\n  labelLegacyCollectionTitle: 'Create Legacy Collection',\n  labelMoveOut: 'Move out of {{symbol}}',\n  labelMoveIn: 'Move into {{symbol}}',\n  labelMoveInCollection: 'Collection',\n  labelSelectAll: 'Select All',\n  labelCancelAll: 'Cancel',\n  labelDoneBtn: 'Done',\n  labelDetail: 'Detail',\n  labelNFTMyCollection: 'Collection: {{collection}}',\n  labelZoom: 'Zoom Media',\n  labelRefresh: 'Refresh NFT cache',\n  labelNFTDetailTab: 'Details',\n  labelNFTPropertiesTab: 'Properties',\n  labelLinkMetaData: 'NFT metadata Resource link',\n  labelCountDown: 'Count Down',\n  labelStackingSelect: 'Choose Staking Product',\n  labelImportCollectionMove: 'Collection',\n  labelCollectionImportNFTBtn: 'Manage Legacy NFT',\n  labelNFTMoveFailed: 'NFT move failed!',\n  labelNFTMoveSuccess: 'NFT moved successful',\n  labelLuckTokenDefaultTitle: 'Good Luck!',\n  labelSync: 'in Sync',\n  labelMintInSyncTooltips:\n    'The NFT and collection information may not be synced up timely after minting due to onChain operation. Please stay tuned and refresh the page later.',\n  labelEstRateApr: 'Est.rate (APR)',\n  labelStakingApr: 'APR',\n  labelManageCollectionTitle: 'Manage Legacy NFT',\n  labelLegacy: 'legacy',\n  labelTitleMyNFTSAvailable: 'My Holding NFTs',\n  labelTitleTotalAvailable: 'Total NFTs',\n  labelEstRateAprDes:\n    'APR stands for annual percentage Rate. It is the actual annual rate of return, NOT taking into account the effect of compound interest.',\n  labelCheckImportCollectionDes:\n    'As the creator, you will be able to generate collection information for those NFT minted earlier that belong to nowhere. And once done, the other people holding your NFT will be able to view those NFT with proper collection information via loopring.io and loopring wallet.',\n  labelL2toL1NFTFailed: 'Sent {{value}} <span>{{symbol}}</span> to {{l1Symbol}} has failed!',\n  labelL2toL1NFTSuccess: 'Sent {{value}} <span>{{symbol}}</span> to {{l1Symbol}} was successful!',\n  labelL2toL2NFTFailed:\n    'Sent {{value}} <span>{{symbol}}</span> from my {{loopringL2}} to another {{loopringL2}} failed!',\n  labelL2toL2NFTSuccess: 'Sent {{value}} <span>{{symbol}}</span> was successful!',\n  labelDoAgain: '{{method}} Again',\n  labelDepositL1: 'Receive from {{l1Symbol}}',\n  labelDepositNFTL1: 'Receive NFT from {{l1Symbol}}',\n  labelL2ToL1Method: 'Send {{symbol}} to {{l1Symbol}}',\n  labelL2ToL2Method: 'Send {{symbol}} to {{l2Symbol}}',\n  labelConfirmAgainByFailed: 'You had a failed order, please confirm information again...',\n  labelConfirmAgainByFailedWithBalance:\n    'You had a failed order, please confirm information again, Balance of {{symbol}} is {{count}}',\n  labelNFTListfav: 'Favorite',\n  labelNFTListhide: 'Hidden',\n  labelNFTListall: 'Owned',\n  labelNFTHide: 'Deploy Contract',\n  labelNFTUnHide: 'Hide NFT',\n  labelNFTUnHideDes: 'The easiest way to trade',\n  labelHideMethodTooltiphide: 'Hide NFT',\n  labelHideMethodTooltipunhide: 'Show NFT',\n  labelFavouriteMethodTooltipfavourite: 'Favorite',\n  labelFavouriteMethodTooltipunfavourite: 'Unfavorite',\n  labelfavourite: 'Favorite',\n  labelunfavourite: 'Unfavorite',\n  labelFavouriteSuccess: 'Set {{favorite}} Successful',\n  labelFavouriteFailed: 'Set {{favorite}} Failed',\n  labelhide: 'Hide',\n  labelunhide: 'Show',\n  labelHideSuccess: '{{hide}} NFT Successful',\n  labelHideFailed: '{{hide}} NFT Failed',\n  labelSmallOrderAlertLine1: 'Small trades (below ~$100) incur a higher fee.',\n  labelSmallOrderAlertLine2: 'Please review the fee before confirming.',\n  labelSmallOrderAlertLine3: 'Trading Fee:',\n  labelSmallOrderAlertLine4: 'Fee ratio:',\n  labelSmallOrderAlertLine5: 'Minimum Converted:',\n  labelSwapSecondConfirmTitle: 'Confirm Swap',\n  labelSwapSettingTitle: 'Settings',\n  labelSwapSettingSecondConfirm: 'Second confirmation',\n  labelSwapSettingSecondConfirmTootip: 'skip confirm screen when toggled off',\n  labelSwapSettingToggleSuccess: 'Swap second confirmation trun {{onOrOff}}',\n  labelFeeMin: 'Min {{fee}}',\n  labelIKnow2: 'I know',\n  labelAddAssetTitleBridge: 'Add Asset From Another L1',\n  labelAddAssetTitleBridgeDesActive:\n    'If you have transferred tokens from another {{ethereumL1}} Symbol account, it may take some time for this transaction to execute on-chain. Once you receive the assets, you can manually activate the {{l2Symbol}} account.',\n  labelAddAssetTitleBridgeDes:\n    'If you have transferred tokens from another {{ethereumL1}} account, it may take some time for this transaction to execute on-chain.',\n  labelAddAssetTitleExchange: 'Add Asset From An Exchange',\n  labelAddAssetTitleExchangeDes: 'If you have transferred tokens from an Exchange, please wait. ',\n  labelAddAssetTitleExchangeDesActive:\n    'If you have transferred tokens from an Exchange, please wait. Once you receive the assets, you can manually activate the {{l2Symbol}} account.',\n  labelAddAssetTitleCard: 'Add Asset With a Card',\n  labelAddAssetTitleCardDes:\n    'If you have purchased crypto with a card, please wait for it to arrive in your account.',\n  labelAddAssetTitleCardDesActive:\n    'If you have purchased crypto with a card, please wait for it to arrive in your account. Upon arrival, {{l2Symbol}} will be activated manually.',\n  labelMinFeeForActive: 'Min {{fee}}',\n  labelReceiveAddressDes:\n    'If you have transferred tokens from another {{loopringL2}} account, please wait.',\n  labelReceiveAddressDesActive:\n    'If you have transferred tokens from other {{loopringL2}} accounts, please close this window and try to activate your {{l2Symbol}} account again.',\n  labelDepositWaiting: 'It make take some time for this transaction to execute on-chain.',\n  labelFrom: 'From',\n  labelTo: 'To',\n  labeltransfer: 'Transfer',\n  labelwithdraw: 'Withdrawal',\n  labelDeposit: 'Deposit',\n  labelFiatAmount: 'Fiat Amount',\n  labelToMyL2: 'My {{loopringL2}}',\n  labelBanxaNotReady:\n    'Please waiting a while for Banxa sdk loading, if you keep on face this problem try fresh the browser or contact us',\n  labelBanxaFailedForAPI: 'Please waiting a while, Banxa service is not available currently.',\n  labelL2toL2AddressFeePaid: 'Active account fee had paid',\n  labelL2toL2AddressFeeActiveFee: \"Pay recipient's {{l2Symbol}} activation fee: {{value}}\",\n  labelL2toL2FeeWithActive: 'Fee (including activation fee)',\n  labelRedPacketOpen: 'Open',\n  labelRedPacketTitle: 'Red Packets',\n  labelRedPacketTypeTokens: 'Choose Tokens / NFTs / Blind Box',\n  labelRedPacketChoose: 'Choose Red Packet Type',\n  labelRedPacketMain: 'Input Red Packet/Send',\n  labelLuckyTokenViewTypePublic: 'Public Red Packet',\n  labelLuckyTokenViewTypePrivate: 'Private Red Packet',\n  labelLuckyTokenViewTypeDesPublic:\n    'Your Red Packet is public, and everyone can try to claim a share of it.',\n  labelLuckyTokenViewTypeDesPrivate:\n    'Your Red Packet is shared privately with others via a custom QR code.',\n  labelLuckyBlindBox: 'Blind Box Red Packet',\n  labelLuckyBlindBoxDes:\n    'Each recipient will receive a sealed Red Packet which cannot be opened until the expiration date. While some recipients will receive an NFT, others will need to try their luck next time.',\n  labelLuckyRecievedBlindBox: 'Received Blind Box {{opendBlindBoxAmount}}/{{totalBlindBoxAmount}}',\n  labelBlindBoxExplainationNotEnded:\n    \"The outcome of the Blind Box will be revealed upon expiration. Please claim within 3 days if your Red Packet contains a gift or it will be forfeited and returned to the Sender's wallet.\",\n  labelBlindBoxExplainationEnded:\n    \"Please claim within 3 days or it will be forfeited and returned to the Sender's wallet.\",\n  labelBlindBoxExplaination2:\n    '{{opendBlindBoxAmount}} out of {{totalBlindBoxAmount}} blind boxes have been opened.',\n  labelBlindBoxExplaination3: '{{remainingGiftsAmount}} gifts available for grabbing.',\n  labelBlindBoxNotStarted: 'Red Packet is available to grab after: {{time}}',\n  labelBlindBoxStarted: 'Blind Box Reveal time after: {{time}}',\n  labelBlindBoxTokenHint: 'Unopen tokens will be returned back to sender after: {{time}}',\n  labelBlindBoxClaimStarted: 'Any unclaimed NFTs will be returned to the Sender after: {{time}}',\n  labelBlindBoxRecievedNFT: 'Received NFT {{deliverdGiftsAmount}}/{{totalGiftsAmount}}',\n  labelBlindBoxStartDate: 'Start date',\n  labelBlindBoxStartTime: 'Start Time',\n  labelBlindBoxEndDate: 'End date',\n  labelBlindBoxEndDate2: 'Blindbox reveal time',\n  labelBlindBoxEndTime: 'End Time',\n  labelBlindBoxRedPacketWithGift: 'Count of Red Packets with gift',\n  labelBlindBoxExpirationExplainationForToken:\n    'After expiration, any unopened Red Packets will be forfeited and sent back to the Sender',\n  labelBlindBoxExpirationExplainationForNFT:\n    \"If NFT Red Packet recipients do not claim their NFT within 30 days, it will be forfeited and returned to the Sender's wallet.\",\n  labelBlindBoxPrivate: 'Private Red Packet',\n  labelBlindBoxPrivateDes: 'Your Red Packet is shared privately with others via a custom QR code.',\n  labelBlindBoxClaimWarning:\n    \"If the recipients of the NFT Red Packets do not claim their received NFT within 3 days, the NFT will be forfeited and sent back to the Sender's wallet.\",\n  labelBlindBoxRecievedRedPackets: 'Received NFT Red Packets',\n  labelBlindBoxCongratulations: 'Congratulations',\n  labelBlindBoxSorry: 'Sorry',\n  labelBlindBoxNoRewards: 'You have not received a reward',\n  labelBlindBoxCongratulationsBlindBox: 'Congratulations on receiving a Blind Box',\n  labelBlindBoxSorryBlindBox: 'Sorry, you did not win a prize',\n  labelLuckyRelayToken: 'Relay Red Packet',\n  labelLuckyRelayTokenDes:\n    'If the recipient of the Red Packet also re-shares the packet, they receive half of whatever the next person receives.',\n  labelLuckyRandomToken: 'Lucky Red Packet',\n  labelLuckyRandomTokenDes: 'Each recipient will get a random amount of.',\n  labelLuckyCommonToken: 'Average Red Packet',\n  labelLuckyCommonTokenDes:\n    'Each recipient will receive a pre-set split of the total Red Packet shared.',\n  labelL1toL2NFTAmount: 'NFT Amount',\n  labelInputRedPacketBtnLabel: 'Select Token',\n  labelCreateRedPacket: 'Send Red Packet',\n  labelMyRedPacket: ' My Red Packet Record',\n  labelRedPacketMarkets: 'Red Packet Plaza',\n  labelRedPacketQRCodeImport: 'Receive Red Packet',\n  labelLuckyTokenViewType1: 'Private Red Packet',\n  labelLuckyTokenViewTypeDes1:\n    'Your Red Packet is shared privately with others via a custom QR code.',\n  labelLuckyTokenViewType0: 'Public Red Packet',\n  labelLuckyTokenViewTypeDes0:\n    'Your Red Packet is public, and everyone can try to claim a share of it.',\n  labelSplit: 'Red Packet Count',\n  labelRedPacketMemo: 'Memo',\n  labelRedPacketMemoPlaceholder: 'Best wishes',\n  labelRedPacketStart: 'Available in',\n  labelRedPacketSendWaitForAuth: 'Please confirm to send red packet {{value}} {{symbol}}.',\n  labelRedPacketSendDenied: 'You rejected to send {{value}} {{symbol}} red packet.',\n  labelRedPacketRecordTitle: 'My Red Packet Record',\n  labelRedPacketReceived: 'ERC20 Received',\n  labelRedPacketSend: 'ERC20 Send',\n  labelRedPacketNFTReceived: 'NFT Received',\n  labelRedPacketNFTSend: 'NFT Send',\n  labelImportRedPacket: 'Import QR code to receive red packet',\n  labelCreateRedPacketTitle: 'Send Red Packet',\n  labelClaimWithdrawFee: 'Fee',\n  labelClaimWithdrawNotEnough: 'Insufficient balance',\n  labelClaimWithdrawTitle: 'Claim to {{loopringL2}}',\n  labelClaimWithdrawWaitForAuth: 'Please confirm to claim {{symbol}}',\n  labelClaimWithdrawDenied: 'You rejected to claim {{symbol}}.',\n  labelClaimWithdrawInProgress: 'Processing...',\n  labelClaimWithdrawFailed: 'Claim has failed!',\n  labelClaimWithdrawSubmit: 'Claim has been submitted',\n  labelClaimWithdrawToken: 'Token Amount',\n  labelRedPacketSendSubmit: 'Send red packet has been submitted.',\n  labelRedPacketSendSuccess: 'Red packet Send Successful.',\n  labelRedPacketSendFailed: 'Send red packet of {{value}} {{symbol}} failed!',\n  labelRedPacketSendInProgress: 'Processing...',\n  labelRefreshRedPacket: 'Refresh List',\n  labelRedPacketSendCommonTitle: 'Normal Red Packet',\n  labelRedPacketSenRandomTitle: 'Lucky Red Packet',\n  labelAmountEach: 'Amount Each',\n  labelRedPacketTotalAmount: 'Total Amount',\n  labelQuantity: 'Quantity',\n  labelAssetAmount: 'Total Asset Amounts: {{value}}',\n  labelCreateRedPacketBtn: 'Prepare Red Packet',\n  labelRedPacketsExpireDes:\n    'Unclaimed tokens remaining after the expiration will be returned within 24h',\n  labelReserveFee: 'Insufficient {{symbol}} with fee',\n  labelRedPacketFee: 'Insufficient fee',\n  labelRedPacketsInsufficient: 'Insufficient {{symbol}} balance',\n  labelRedPacketsMinRange: 'Min {{value}}',\n  labelRedPacketsMaxRange: 'Max {{value}}',\n  labelRedPacketsMin: 'Minimum of {{value}} {{symbol}}',\n  labelRedPacketsMax: 'Maximum of {{value}} {{symbol}}',\n  labelRedPacketsGiftsLargerThanPackets:\n    'The number of Red Packets containing gifts cannot exceed the total number of Red Packets',\n  labelBlindBoxNumberOverMaximun: 'Number of Blind Box exceeds maximum',\n  labelRedPacketsSplitNumber: 'The maximum number of Red Packet is {{value}}',\n  labelRedPacketsSplitCommonDetail: 'Distribution per red packet: {{value}}',\n  labelRedPacketsSplitLuckyDetail: 'Token amount for each Red Packet is randomized.',\n  labelSendRedPacketTitle: 'Send Red Packet',\n  labelSendRedPacketTitlePublic: 'Send Red Packet -- Public',\n  labelSendRedPacketTitlePrivate: 'Send Red Packet -- Private',\n  labelRedPacketWaitingBlock: 'Block is not ready',\n  labelShare: 'Share',\n  labelRelayRedPacket: 'Relay Red Packet',\n  labelNormalRedPacket: 'Average Red Packet',\n  labelluckyRedPacket: 'Lucky Red Packet',\n  labelrelayRedPacket: 'Relay Red Packet',\n  labelnormalRedPacket: 'Average Red Packet',\n  labelLuckyRedPacket: 'Lucky Red Packet',\n  labelLuckyRedPacketStart: 'Starts in: {{value}}',\n  labelLuckyRedPacketTimeout: 'Red Packet has been \\n taken out',\n  labelLuckyRedPacketDetail: 'View Red Packet details >',\n  labelRedPacketOpenInProgress: 'Processing...',\n  labelRedPacketOpenFailed: 'Read red packet failed!',\n  labelRedPacketShowQR: 'Share red packet',\n  labelRedPacketReceivedRecord: 'Receive Red Packet {{value}}/{{count}}',\n  labelAmmExitMiniOrderDisabled:\n    'Transaction fees will be greater than the value of the LP, which will cost you your assets.',\n  labelAmmExitMiniOrderMini:\n    'The transaction fee will account for 15% of the LP value, are you sure you want to redeem it?',\n  labelLpAmount: 'LP Amount: {{value}}',\n  labelRedPacketMarketsBtn: 'Red Packet Plaza',\n  labelRedPacketBtn: 'Shared',\n  labelRedPacketViewType0: 'Public Plaza',\n  labelRedPacketViewType1: 'Public QR',\n  labelRedPacketViewTypeDetail0: 'public Red Packet',\n  labelRedPacketViewTypeDetail1: 'public Red Packet',\n  labelRedPacketStatusSUBMITTING: 'Submitting', // SUBMITTING = 0,\n  labelRedPacketStatusNOT_EFFECTIVE: 'Not Start', // NOT_EFFECTIVE = 1,\n  labelRedPacketStatusPENDING: 'In Processing', // PENDING = 2,\n  labelRedPacketStatusCOMPLETED: 'Completed', // COMPLETED = 3,\n  labelRedPacketStatusOVER_DUE: 'Over Due', // OVER_DUE = 4,\n  labelRedPacketStatusFAILED: 'Failed', // FAILED = 5\n  labelRedPacketStatusNotStarted: 'Hasn’t started',\n  labelRedPacketStatusStarted: 'Started',\n  labelRedPacketStatusEnded: 'Ended',\n  labelRedPacketNo: 'NO.{{value}}',\n  labelRedPacketClaimInProgress: 'Processing...',\n  labelRedPacketClaimFailed: 'Open red packet failed!',\n  labelRedPacketClaimSuccess: '',\n  labelReceived: 'Received',\n  labelGoodLuck: 'Good Luck',\n  labelRedPacketGrab: 'Share with Friends',\n  labelRedPacketEnded: 'Ended',\n  labelLuckDraw: 'Luckiest Draw',\n  labelMyLuckReward: '(My reward)',\n  labelRedPacketClaimTitle: 'Claim to {{loopringL2}}',\n  labelClaimNoBalance: 'Insufficient {{belong}} balance',\n  labelShareQRCode: 'Generate QR Code for share',\n  labelSeal: 'Seal',\n  labelOpenAfter: 'Open after {{time}}',\n  labelOpenStart: 'Start',\n  labelTotalRedPacket: 'Total Quantity: {{value}}',\n  labelMyRedPacketReward: 'My Rewards',\n  labelRedpacketScanDes:\n    'Grab this Red Packet by scanning with your Loopring Wallet or importing to loopring.io',\n  labelLuckyRedPacketStarted: 'Red Packet is Started',\n  labelNFTRedpacketBtn: 'Send Red Packet',\n  labelRedpacketDurationTitle: 'Expires after',\n  labelRedpacketDurationPlaceHold: 'Min 1 - Max 30 Days',\n  labelRedPacketDescription: 'Red Packet Description',\n  labelRedpacketHavePeopleHelp:\n    '<1>{{number}}</1> friends relayed this red packet, you extend reward: <3>{{amount}}</3>.',\n  labelRedPacketFrom: 'From',\n  labelRedPacketTo: 'To {{loopringL2}}',\n  labelRedPacketMy: 'My Red packet',\n  labelRedpacketNotActive: 'Hide received Red Packets',\n  labelRedpacketTokens: 'ERC20 Tokens',\n  labelRedpacketTokensShort: 'Tokens',\n  labelRedpacketNFTS: 'NFTs',\n  labelRedpacketBlindBox: 'Blind Box',\n  labelRedpacketHideInactionable: 'Hide inactionable records',\n  labelChooseNFT: 'Choose NFT <1>{{required}}</1>',\n  labelChooseNFTTooltips: '',\n  tokenSelectNFTToken: 'Select NFT',\n  labelRedPacketClaimERC20: 'ERC20',\n  labelRedPacketClaimNFT: 'NFT',\n  labelRedPacketMarketERC20: 'ERC20',\n  labelRedPacketMarketNFT: 'NFT',\n  labelRedPacketNotSupport:\n    'Unfortunately Mobile Dapp does not support Red Packet feature, Please download Loopring wallet or try this feature on laptop browser.',\n  labelRedPacketTimeRange: 'Start / End Time',\n  labelRedPacketTimeRangeDes: 'The Red Packet expires after the end date',\n  labelRedPacketTimeRangeBlindbox: 'Start / Reveal Time',\n  labelRedPacketTimeRangeBlindboxDes:\n    'The Reveal Time is when the Red Packet ends, and recipients can open it to see if they have received an NFT',\n  labelRedPacketStartWithTime: '{{time}} Start',\n  labelRedPacketTabReceived: 'Received',\n  labelRedPacketTabSent: 'Sent',\n  labelRedPacketTabNFTs: 'NFTs',\n  labelRedPacketTabBlindBox: 'Blind Box',\n  labelOrderOpen: 'Continue',\n  labelOrderCancel: 'Cancel',\n  labelOrderBanxaIsReadyToPay: 'The crypto selling order is ready. Please continue.',\n  labelBanxaContinuous: 'Proceed existing order',\n  labelBanxaCreate: 'Create new order',\n  labelBanxaTitleCreateAgain: '',\n  labelYouAlreadyHaveAnBanxa: 'Existing <1>order</1> detected, send token to complete order.',\n  labelHaveAnBanxaCancel: 'Create a new order from scratch.',\n  labelBanxaConfirmSubmit:\n    'Token has been sent to Banxa wallet. You can save/click below link to check the payment status anytime.',\n  labelInvestStakeLRC: 'LRC STAKING',\n  labelInvestStakeLRCDES: 'Earn LRC staking rewards',\n  labelFriendsPayActivation: 'Your friend has paid for your {{l2Symbol}} activation fee.',\n  labelLRCStakingTitle: \"What's LRC Staking\",\n  labelLRCStakingRisk:\n    '<p>LRC staking is incentivized through an allocated portion of the Loopring protocol fee; the exact percentage is determined by the Loopring DAO. The APY is updated daily based on the allocated amount from previous day’s fee. Any LRC holder can participate in LRC staking via {{l2Symbol}} to accumulate daily rewards. The assets must be staked for a minimum of 90 days to receive rewards.</p>',\n  labelLRCStakingAgree: 'I have read and understand the risk warning.',\n  labelLRCStakingRisk2:\n    '<0>The staked LRC will be locked in {{loopringL2}}, meaning it cannot be used for other purposes. You may redeem your LRC at any time; however, doing so before the minimum Locked Duration will forfeit any accumulated reward.</0>',\n  labelInvestLRCStakingTitle: 'LRC Staking',\n  labelMyInvestLRCStaking: 'My Investments',\n  labelInvestLRCStakingLockAlert:\n    'Your assets for investment will be locked until your redemption.',\n  labelLRCStakeAPRTooltips:\n    'Apr stands for annual percentage rate, not taking into account the effect of compound interest. The value displayed here indicates the current value, while it keeps changing dynamically. ',\n  labelLRCStakeAPR: 'APR <1></1>',\n  labelLRCStakeEarn: 'Daily Rewards (est.) <1></1>',\n  labelLRCStakeEarnTooltips:\n    'Once funds are successfully locked for staking, rewards will begin calculating at 00:00 (UTC) the following day.',\n  labelLRCStakeSubTime: 'Subscribe Time',\n  labelLRCStakeDurationTooltips:\n    'Staking Duration refers to the minimum amount of time that staked assets must be locked in order to be entitled to claim rewards. LRC staking requires the minimum Locked Duration.',\n  labelLRCStakeDuration: 'Lock duration to claim reward<1></1>',\n  labelInvestLRCTitle: 'LRC Staking',\n  labelLRCStakeRiskDes:\n    'The staked LRC will be locked in {{loopringL2}}, meaning it cannot be used for other purposes. You may redeem your LRC at any time; however, doing so before the minimum Locked Duration will forfeit any accumulated reward.',\n  labelAgreeRedeem: 'Redeem',\n  labelStackingAgreeRedeemTitle: 'Redeem In Advance',\n  labelStackingAgreeRedeem:\n    'Redeeming staked assets before the minimum Locked Duration will forfeit the accumulated rewards. Are you sure you still want to redeem?',\n  labelLRCStakeProduct: 'Product',\n  labelLRCStakeRedeemDes:\n    'This product has meet the minimum Locked Duration. You can now redeem any portion of the subscription amount without deducting from your earnings. The remaining subscription amount will continue to generate income.',\n  labelLRCStakeRedeemAgree:\n    'I acknowledge the early redemption will forfeit the accumulated reward',\n  labelLRCStakeCurrentEarn: 'Current Total Rewards',\n  labelLRCStakeForfeitedReward: 'Forfeited Reward',\n  labelLRCStakeRemainingEarnings: 'Remaining Rewards',\n  labelDeFiSideAmount: 'Amount',\n  labelDeFiSideProduct: 'Product',\n  labelDeFiSidePoolShare: 'Pool Share',\n  labelDeFiSideAPR: 'APR',\n  labelDeFiSideCumulativeEarnings: 'Cumulative Earnings',\n  labelDeFiSidePreviousEarnings: \"Previous Day's Earnings\",\n  labelDeFiSideLockDuration: 'Lock duration to claim reward',\n  labelDeFiSideSubscribeTime: 'Subscribe Time',\n  labelDeFiSideHoldingTime: 'Holding Time',\n  labelDeFiSideInvestmentDetails: '{{symbol}} Staking Details',\n  labelSideStakingTable: 'LRC Staking',\n  labelInvestMaxDefi: 'Min {{minValue}} - Max {{maxValue}}',\n  labelDefiMax: 'Allowable maximum is {{arg}}',\n  labelDefiStakingDetail: 'Detail',\n  labelDefiStakingRedeem: 'Redeem',\n  labelDays: 'day(s)',\n  labelRemainingAmount: 'Remaining amount should be greater than {{symbol}},\\n Please redeem all.',\n  labelRemainingBtnAmount: 'Remaining amount is insufficient',\n  labelStakingCumulativeEarnings: 'Cumulative Rewards',\n  labelStakingClaimableEarnings: 'Claimable Rewards',\n  labelClaimBtn: 'Claim',\n  labelStakeNoEnough: 'Insufficient {{arg}} balance',\n  labelClaimBtnClaimed: 'Claimed',\n  labelClaimBtnExpired: 'Expired',\n  labelDefiRemindMin: 'Please redeem all Balance',\n  labelInvestType_LRCSTAKE: 'LRC Staking',\n  labelNFTs_one: '\\u2A09{{count}} NFT',\n  labelNFTs_other: '\\u2A09{{count}} NFTs',\n  labelTokenNFTMaxRedPack: 'Max: ',\n  labelNFTRedPackAskClaim:\n    'Note: After expiration, all the unclaimed NFTs will be returned back to sender. Please claim as soon as possible if you want to hold them.',\n  labelTransferDelayConfirm:\n    'Your claim request has been received. Loopring will transfer the token into your {{l2Symbol}} account soon. Please verify it.',\n  labelClaimredPacket: 'My Red Packet',\n  labelRedPacketMe: 'Me',\n  labelClaimlrcStaking: 'My LRC Staking',\n  labelExpectSettlementPrice:\n    'The expected settlement price from this order is {{symbolSell}}/{{symbolBuy}}={{stob}}, while the current market price from a trusted oracle is {{symbolSell}}/{{symbolBuy}}={{marketPrice}}. There is a {{marketRatePrice}}% variance observed. To proceed, tap here to confirm you understand and acknowledge the risk.',\n  labelStakingSuccess: '{{symbol}} Staking Successful',\n  labelStakingFailed: '{{symbol}} Staking failed',\n  labelStakingRedeemFailed: 'Redeem {{symbol}} failed',\n  labelStakingRedeemSuccess: 'Redeem {{symbol}} Successful',\n  labelStakingRedeemRemaining: 'Remaining Amount',\n  labelStakingRedeemDate: 'Redeem Time',\n\n  labelContactsAddContact: 'Add Contact',\n  labelContactsAddressTitle: 'Address',\n  labelContactsAddressDes: 'Enter wallet address or ENS',\n  labelContactsAddressInvalid: 'Invalid address or ENS',\n  labelContactsNameTitle: 'Name',\n  labelContactsNameDes: 'Enter name for the contact',\n  labelContactsAddContactBtn: 'Add',\n  labelContactsDeleteContact: 'Delete Contact',\n  labelDeleteContactInfo: 'Contact',\n  labelContactsDeleteContactBtn: 'Delete',\n  labelContactsAddSuccess: 'Add Contact Succeed',\n  labelContactsDeleteSuccess: 'Delete Contact Succeed',\n  labelContactsEditSuccess: 'Edit Contact Succeed',\n  labelContactsSendSuccess: 'Send Succeed',\n  labelContactsCopySuccess: 'Copied to Clipboard',\n  labelContactsAddFailed: 'Add Contact Failed',\n  labelContactsDeleteFailed: 'Delete Contact Failed',\n  labelContactsEditFailed: 'Edit Contact Failed',\n  labelContactsSendFailed: 'Send Failed',\n  labelContacts: 'Contacts',\n  labelContactsSend: 'Send',\n  labelContactsTransactions: 'Transactions',\n  labelContactsNetworkChoose: 'Choose {{l2Symbol}} or {{l1Symbol}} Account',\n  labelContactsNext: 'Next',\n  labelContactsContactExisted: 'Contact Already Existed',\n  labelNotExchangeEOA:\n    'Sending to an Exchange Address {{l2Symbol}} account is not supported. {{loopringL2}} accounts cannot be activated on Exchange wallet addresses. Instead, please send to the {{l1Symbol}} account associated with this address.',\n  labelNotOtherSmartWallet:\n    'This wallet binds with smart contract that does not support {{loopringL2}}. You will need to send funds to the {{l1Symbol}} account.',\n  labelContactsNoContact: 'No Contact',\n  labelContactsSelectReciepient: 'Select the Recipient',\n  labelContactsBinanceNotSupportted:\n    'Binance currently do not support {{loopringL2}} transfers. You will need to send funds to the {{l1Symbol}} account.',\n  labelContactsHuobiNotSupportted:\n    'Huobi currently do not support {{loopringL2}} transfers. You will need to send funds to the {{l1Symbol}} account. Transactions need to wait for 24 hours.',\n  labelContactsOtherExchangesNotSupportted:\n    'The trading platforms currently do not support {{loopringL2}} transfers. You will need to send funds to the {{l1Symbol}} account.',\n  labelBtradeSwapTitle: 'Block Trade',\n  labelBtradeSwapType: 'Type',\n  labelBtradeSwapFilled: 'Filled',\n  labelBtradeSwapFee: 'Fee',\n  labelBtradeSwapTime: 'Time',\n  labelBtradeSwapPrice: 'Price',\n  labelBtradeSwapSettled: 'Settled',\n  labelBtradeSwapDelivering: 'Delivering',\n  labelBtradeSwapPanelDes:\n    'The Loopring pool is currently unable to swap the full requested amount. The tokens that were successfully swapped will be transferred to your account now. The unswapped tokens will be locked until they can be swapped. \\n We’ll rebalance the pool shortly and swap the remaining portion.',\n  labelBtradeSwapDeliverDes:\n    'The Loopring pool is currently unable to swap the full requested amount. The tokens that were successfully swapped will be transferred to your account now. The unswapped tokens will be locked until they can be swapped. \\n We’ll rebalance the pool shortly and swap the remaining portion.',\n  labelGoBtradeSwap:\n    'Swapping on the DEX will result in a large Price Impact (loss of assets). We recommend using the <a>Block Trade</a> option to help minimize potential losses.',\n  labelBtradeSwap: 'Block Trade',\n  labelBtrade: 'Block Trade',\n  labelBtradeSwapFailed: 'Failed!',\n  labelBtradeSwapTitleDes: 'What is Block Trade?',\n  labelBtradeSwapContentDes:\n    '<p>Block Trade offers a secure and trustless way for users to swap tokens using CEX liquidity. The trades happen exclusively between designated entities, ensuring that the existing liquidity of the DEX remains unaffected. There is no price impact to other DEX users as a result of the transaction.</p>' +\n    '<p>This is similar to the traditional stock market’s Block Trade System. A block trade is a large, privately negotiated transaction, which can be made outside the open market through a private purchase agreement.</p>' +\n    \"<p>The Loopring pool is currently unable to swap the fully requested amount. If you choose to continue, the unswapped tokens will be locked until they can be swapped. We'll rebalance the pool shortly.</p>\" +\n    '<p>Block Trade offers two options:</p><ul>' +\n    '<li>Prioritize Speed.</li>' +\n    '<li>Prioritize Quantity.</li></ul>' +\n    '<h6>Prioritize Speed</h6>' +\n    '<p>This option prioritizes quick trade execution to ensure that trades are completed as soon as possible. It’s ideal for users who need to complete their trades quickly.</p>' +\n    '<h6>Prioritize Quantity</h6>' +\n    '<p>This option prioritizes trading as much of the asset as possible, even if it means waiting longer for the order to be fully executed. It’s ideal for users who want to maximize their trading volume and are willing to wait for the market to be favorable before completing the transaction.</p>' +\n    '<p>We’ll use the Loopring pool to swap your tokens. If your request exceeds the pool’s available balance, we’ll swap as many tokens as we can. Afterwards, we’ll rebalance the pool and then swap the remaining portion. The entire transaction should complete within 24 hours.</p>',\n  labelRefereeRewards: 'Referee Rewards',\n  labelReferralRewards: 'Referral Rewards',\n  labelRewardLRC: 'Rewards LRC',\n  labelPrice: 'Price',\n  labelBtradeSwapMiniMax: 'Min {{minValue}} - Max {{maxValue}}',\n  labelBtradeSwapMini: 'Min {{minValue}}',\n  labelBtradeConfirm: 'Please check the checkbox',\n  labelBtradeSwapBtn: 'Swap',\n  labelType: 'Type',\n  labelBtradeTrade: 'Block Trade',\n  labelBtradeTitle: 'Block Trade Details',\n  labelBtradeQuote: 'Total Quota:',\n  labelBtradeQuoteDes: 'Total Quota is the maximum allowable trading amount.',\n  labelBtradePoolDes: 'Loopring Pool:',\n  labelBtradePool: 'Loopring Pool',\n  labelBtradeToleranceTooltips:\n    'Your trade will revert if the price changes unfavorably by more than this percentage.',\n  labelBtradeFeeTooltips: 'The trading fee is fixed at {{feeRate}}.',\n  labelBtradeMinReceiveTooltips:\n    'The price in other liquidity source changes dynamically, the price you see when placing an order may be inconsistent with the final transaction price; also the received amount needs to deduct the fees from converted amount. The protocol can guarantee that the received token is at least this amount.',\n  labelBtradeInsufficient: 'Insufficient',\n  labelBtradeTime: 'Time',\n  labelStopLimit: 'Stop-Limit {{tradeType}} {{symbol1}}',\n  labelStopLimitDes:\n    '<p>If the last price {{from}} to or {{behavior}} {{stopPrice}} {{symbol2}}, and order to {{tradeType}} {{value1}} {{symbol1}} at a price of {{limitPrice}} {{symbol2}} will be placed.</p>',\n  labelStopLimitFromGoesUp: 'goes up',\n  labelStopLimitFromDropsDown: 'drops down',\n  labelStopLimitBehaviorAbove: 'above',\n  labelStopLimitBehaviorBelow: 'below',\n  labelStopLimitType: 'Stop-Limit / {{tradeType}}',\n  labelStopLimitStopPrice: 'Stop Price',\n  labelStopLimitPriceLimitPrice: 'Limit Price',\n  labelStopLimitAmount: 'Amount',\n  labelStopLimitCancel: 'Cancel',\n  labelStopLimitConfirm: 'Confirm',\n  labelBtradeSwapPending: 'Pending',\n  labelStopLimitTitle: 'Stop-Limit',\n  labelStopPrice: 'Limit / Buy Price',\n  labelStopStopPrice: 'Stop / Trigger Price',\n  labelStopLimitWhatIs: \"What's Stop-Limit?\",\n  labelStopLimitMinMax: 'Min {{minValue}} - Max {{maxValue}}',\n  labelLimitStopPriceMinMax: 'Stop Price Range {{arg}}',\n  labelLimitMainContent:\n    'A Stop-Limit order is a limit order with a limit price and a stop price. When the stop price is reached, the limit order will be placed on the order book. Once the limit price is reached, the limit order will be executed.',\n  labelLimitStopPriceLabel: 'Stop Price / Trigger Price',\n  labelLimitStopPriceContent:\n    'When the current asset price reaches the given stop price, the Stop-Limit order is executed to buy or sell the asset at the given limit price or better.',\n  labelLimitLimitPriceLabel: 'Limit Price',\n  labelLimitLimitPriceContent:\n    'The selected (or potentially better) price that the Stop-Limit order is executed at.',\n  labelLimitAmountLabel: 'Amount',\n  labelLimitAmountContent: 'The quantity of assets to buy or sell in the Stop-Limit order.',\n  labelLimitDes:\n    'You can set the stop price and limit price at the same price. However, it’s recommended that the stop price for sell orders should be slightly higher than the limit price. This price difference will allow for a safety gap in price between the time the order is triggered and when it is fulfilled. You can set the stop price slightly lower than the limit price for buy orders. This will also reduce the risk of your order not being fulfilled.\\n' +\n    'Please note that your order will be executed as a limit order after the market price reaches your limit price. If you set the stop-loss limit too high or the take-profit limit too low, your order may never be filled because the market price can’t reach the set limit price.',\n  labelLimitDemoTitle: 'How does a Stop-Limit order work?',\n  labelLimitDemoDes:\n    'The current price is 2,400 (A). You can set the stop price above the current price, such as 3,000 (B), or below the current price, such as 1,500 (C). Once the price goes up to 3,000 (B) or drops to 1,500 (C), the Stop-Limit order will be triggered, and the limit order will be automatically placed on the order book.\\n Note: <ol>' +\n    '<li>Limit price can be set above or below the stop price for both buy and sell orders. For example, stop price B can be placed along with a lower limit price B1 or a higher limit price B2.\\n</li>' +\n    '<li>A limit order is invalid before the stop price is triggered, including when the limit price is reached ahead of the stop price.</li>' +\n    '<li>When the stop price is reached, it only indicates that a limit order is activated and will be submitted to the order book rather than the limit order being filled immediately. The limit order will be executed according to its own rules.</li></ol>',\n  labelLimitFailed: 'Submitted failed',\n  labelLimitMarket: 'Market data has issue',\n  labelStopLimitOrderGroup: 'Stop-Limit Records',\n  labelStoplimit: 'Stop-Limit',\n  labelStopLimitProduct: 'Product',\n  labelStopLimitLabelType: 'Type',\n  labelStopLimitNotSupport:\n    'Sorry, there is currently insufficient liquidity in this token pair to execute Stop-Limit orders. Please try again later or consider using a market / limit order instead.',\n  labelStopLimitTriggered:\n    'Triggered: The limit order has been submitted to the order book.\\n Time: {{time}}',\n  labelStopLimitWaitingTrigger:\n    'The limit order is not placed until the stop price has been triggered.',\n  labelStopLimitCurrentlyInsufficient: 'Currently insufficient',\n  labelDUAL_CURRENCY: 'Dual Investment',\n  labelDUAL_BASE: 'Dual Investment',\n  labelBTRADE: 'Block Trade',\n  labelL2STAKING: 'LRC Staking',\n  labelSTOP_LIMIT: 'Stop-Limit',\n  labelAMMPending: 'Pending',\n  labelAMMTitle: 'AMM Investment',\n  labelAMMChartFailed: 'Failed load data',\n  labelExpectSettlementLimitPrice:\n    'The expected settlement price from this order is {{symbolBase}}/{{symbolQuote}} = {{price}}, while the current market price from a trusted oracle is {{symbolBase}}/{{symbolQuote}} = {{marketPrice}}. There is a {{marketRatePrice}}% variance observed. To proceed, tap here to confirm you understand and acknowledge the risk.',\n  labelAMMNoEnough: 'Insufficient {{arg}} balance',\n  labelAMMMax: 'Max {{arg}} ',\n  labelAMMMaxAND: '{{coinA}} and {{coinB}}',\n  labelDepositTo: 'Deposit to',\n  labelReferTitle: 'Invite friends to join in \\nLoopring and receive rewards',\n  labelReferTitleDes:\n    'As referrer: will receive a commission on fees the new referred user trades. \\n As referee:  will enjoy a discount on transfer fees.',\n  labelCopy: 'Copy',\n  labelReferralRules: 'Reward rules',\n  labelReferralMethod1: 'Method 1',\n  labelReferralMethod2: 'Method 2',\n  labelReferralMethod1Step1: 'Download the Loopring Wallet App',\n  labelReferralMethod1Step2: 'Sign up with referral code',\n  labelReferralMethod1Step3: 'Activate {{loopringL2}} Account',\n  labelReferralMethod1Step4: 'Both of us receive rewards',\n  labelReferralMethod2Step1: 'Access the website <1>https://loopring.io</1>',\n  labelReferralMethod2Step2: 'Connect Wallet',\n  labelReferralMethod2Step3: 'Activate {{loopringL2}} Account with referral code',\n  labelReferralMethod2Step4: 'Both of us receive rewards',\n  labelReferralMyReferrals: 'My Referrals',\n  labelReferralReferralsRefunds: 'Referee Refunds',\n  labelBtradeQuantity: 'Prioritize Quantity',\n  labelBtradeSpeed: 'Prioritize Speed',\n  labelBtradeSettled: 'Settled',\n  labelOrderCancelConfirm: 'Confirm to cancel this order?',\n  labelOrderCancelOrder: 'Cancel',\n\n  labelRedpacketTotalReward: 'Total {{amount}}',\n  labelRedpacketCantOpen: 'Now is not the time to open',\n  labelLocketInfo: '{{symbol}} Locked Detail',\n  labelSendAssetToAnotherNet: 'To Others Via Third Party Bridge',\n  labelFromAnotherNet: 'From another network',\n  labelAddAssetTitleAnotherNetDes:\n    'If you have transferred tokens from another network, please wait. ',\n  labelAddAssetTitleAnotherNetDesActive:\n    'If you have transferred tokens from another network, please wait. Once you receive the assets, you can manually activate the {{l2Symbol}} account.',\n  labelAnotherNetworkDes:\n    '<0>Orbiter.finance</0> is a 3rd party service provider to help move tokens between various {{l1ChainName}} {{l1Symbol}} and {{l2Symbol}} networks. If you have any concerns regarding their service, please check out their <2>TOS</2>.',\n  labelAnotherNetworkUnderstand: 'I understand and acknowledge the risk',\n  labelReferralImageDes: 'Scan code to register',\n  labelReferralImageCode: 'Code: {{code}}',\n  labelInvite: 'Invite Friends',\n  labelReferralsTotalEarning: 'Total Rewards ',\n  labelReferralsClaimEarning: 'Claimable Rewards ',\n  labelReferralsTotalReferrals: 'Total Referrals ',\n  labelReferralsTotalRefund: 'Total Refunds ',\n  labelReferralsClaimRefund: 'Claimable Refunds ',\n  labelReferralsTotalTradeNumber: 'Total Trade Number ',\n  labelReferralCode: 'Referral Code (Optional) <1>\\uFE61</1>',\n  labelReferralToolTip: 'Enter referral code to enjoy a discount on  transfer fees.',\n  labelBtradeRefresh: 'Refresh',\n  labelArgNoEnough: 'Insufficient {{arg}} balance',\n  WalletConnectV1: 'WalletConnect Legacy',\n  labelDualInvestDesInsufficient: 'Insufficient quota',\n  labelExplorer: 'Explorer',\n  labelTutorial: 'Tutorial',\n  labelRejectSwitchNetwork: 'Switch Chain was Rejected',\n  labelAssetRewards: 'Rewards',\n  labelClaimTypeREBATE_FEE: 'Maker Order Rewards',\n  labelClaimTypeRECOMMENDER_FEE: 'Referral Rewards',\n  labelClaimTypeREFERER_FEE: 'Referee Refunds',\n  labelClaimTypePROTOCOL_FEE: 'Dedicated AMM Incentive',\n  labelClaimTypeLRC_STAKING: 'LRC Staking Rewards',\n  labelClaimOtherRewards: 'Other Rewards',\n  labelAMMClaimableEarnings: 'Dedicated AMM Incentive',\n  labelLayer2HistoryOrders: 'Order Records',\n  labelLayer2HistoryStopLimitRecords: 'Stop-Limit Records',\n  labelLayer2HistoryDefiRecords: 'ETH Staking',\n  labelLayer2HistoryDualRecords: 'Dual Investment',\n  labelLayer2HistorySideStakingRecords: 'LRC Staking',\n  labelLayer2HistoryBtradeSwapRecords: 'Block Trade',\n  labelPayLoopringL2: 'Pay {{loopringL2}}',\n  labelRedPacketTimeRangeBlindboxDesERC20:\n    'The Reveal Time is when the Red Packet ends, and recipients can open it to see if they have received tokens',\n  labelBlindBoxExpirationExplainationForTokenBlindbox:\n    \"If the recipients of the Tokens Red Packets do not open their received Tokens, the Tokens will be forfeited and sent back to the Sender's wallet.\",\n  labelBlindBoxRecieved: 'Received {{deliverdGiftsAmount}}/{{totalGiftsAmount}}',\n  labelBlindBoxClaimHint: 'You can visit Assets > Red Packets to claim your rewards.',\n  labelRedPacketBlindboxReceived1: 'ERC20 Blind Box',\n  labelRedPacketBlindboxReceived2: 'Received',\n  labelRedPacketsGiftsEqualsZero: \"Number of gifts can't be zero\",\n  labelRedpacketStandard: 'Standard',\n  labelCiETHDefiRiskTitle: \"What's Cian Leveraged ETH?\",\n  labelCiETHDefiRisk:\n    '<p>CIAN protocol is a liquid staking derivatives (“LSD”) focused yield strategy platform, where users could earn either through joining algorithmic strategy vaults or through building their own DeFi strategies using CIAN’s advanced automation tools.</p>' +\n    \"<p>The stETH/ETH leveraged staking strategy enables users to safely leverage stETH’s staking rewards. This strategy focuses on staking derivatives and protection/optimization tooling. By nature, this strategy is to use the user's asset as collateral to borrow ETH from lending platforms, then stake ETH in Lido to earn ETH staking interest. By utilizing tools like Flashloan, it actually adds leverage to users' ETH investment. If only there is a positive APY diff between the borrowing rate and ETH staking rate, there will be additional earnings from this strategy vs. standard ETH staking.</p>\" +\n    '<p>It is quite important to understand that, when using such leveraged strategy, it’s highly advised to intend on holding that position for a while. By doing so, users will give enough time for the high APY to cover their entry & exit costs.</p>\\n',\n  labelDefiWithdrawFee: '',\n  labelLeverageETHTitle: 'Leveraged ETH Staking',\n  labelLayer2HistoryleverageETHRecords: 'Leveraged ETH Staking',\n  labelSwapMinConverted: 'Minimum Converted',\n  labelSwapMinConvertedTooltip:\n    'The pool price changes dynamically, the price you see when placing an order may be inconsistent with the final transaction price. The protocol can guarantee that you will receive at least this amount.',\n  labelNetworkFee: 'Network Fee',\n  labelTradingFee: 'Trading Fee',\n  labelTradingFeeEst: 'Trading Fee (est.)',\n  labelStopStopPriceDes:\n    'It\\'s actually the trigger price for the relayer to place a valid order. When the market price reaches the \"Stop Price\",  the system will automatically place a limit order at \"Limit Price\".',\n  labelStopPriceDes:\n    'After the \"Stop Price\" is triggered, the relayer will automatically place a limit order at this price. ',\n  labelStopPriceSell: 'Limit / Sell Price',\n  labelClaimallToken: 'My Rewards',\n  labelConnecting: 'Connecting',\n  labelTitleOverviewAllPrd: 'All Products',\n  labelInvestDefiDes: 'Earn ETH staking rewards',\n  labelInvestChoseProduct: 'Choose the product you want',\n  labelInvestTotalEarnings: 'Total Earnings',\n  labelInvestLoopringEarn: 'Loopring DeFi',\n  labelInvestLoopringEarnDes: 'Earn stable profits with professional asset management',\n  labelInvestLRCDes: 'Earn LRC staking rewards',\n  labelHadUnknownCollectionTitle: 'Import Collection for Legacy NFT',\n  labelHadUnknownCollectionDes:\n    'As the creator, you will be able to generate collection information for those NFT minted earlier that belong to nowhere. And once done, the other people holding your NFT will be able to view those NFT with proper collection information via loopring.io and loopring wallet. ',\n  labelGo: 'Go',\n  labelAnotherNetworkDes2:\n    'Note: Please ensure to check out the \"Change Account\" option and input the recipient\\'s address carefully. If you want to send token to network other than ethereum, the recipient address must be different than the sender address; else you will lose that asset for ever.',\n  labelAnotherNetworkDes3: '',\n  labelRiskReminder: 'Risk Reminder',\n  labelDefiRedeem: 'Redeem',\n  labelDefiSubscribe: 'Subscribe',\n  labelDefiMaxBalance1Leverage:\n    '<li>The Loopring pool will rebalance soon. Please come back later to redeem.</li>',\n  labelDefiNoBalanceLeverage:\n    '<span>Loopring will set up the pool soon. Please come back later to redeem.</span>',\n  labelDefiMaxBalanceLeverage:\n    'It is not possible for the Loopring pool to fulfil your complete request at the moment. You can choose withdraw ciETH https://vault.cian.app/vaults',\n  labelFunctionList: 'Function List:',\n  labelSuperUserTitle: 'Super User',\n  labelLeverageETHStaking: 'Leveraged ETH Staking',\n  labelLeverageETHBack: 'Leveraged ETH Staking',\n  labelInvestType_LEVERAGEETH: 'Leveraged ETH Staking',\n  labelRewardRefresh: 'Refresh',\n  labelToMyL2WidthAddress: '<0>My {{loopringL2}}</0><1>({{address}})</1>',\n  labelFeeAvailablePay: 'Available: {{available}}, Pay: {{pay}}',\n  labelMarketOrderUnfilled: 'Market Order Unfilled',\n  labelRiskAgree: 'Proceed Anyway',\n  labelRiskCancel: 'Cancel',\n  labelExpectedSettlementPrice: 'Expected Settlement Price',\n  labelCurrentMarketPrice: 'Current Market Price',\n  labelPriceVariance: 'Price Variance',\n  labelImpactExtraNewGreat:\n    'This trade will result in a loss of {{value}}% of the position’s market value. To proceed, tap ‘Proceed Anyway’ to confirm you understand and acknowledge the risk.',\n  labelPriceImpact: 'Price Impact',\n  labelPriceImpactDes1:\n    'This trade will affect the pool price by more than {{value}}%，which is too high. It may result in significant slippage and potential losses. If you acknowledge the risk and wish to proceed, type the <t>‘AGREE’</t> and tap ‘Proceed Anyway’ to confirm again.',\n  labelPriceImpactDes2:\n    'This trade will affect the pool price by more than {{value}}%，which is too high. It may result in significant slippage and potential losses. To proceed, tap ‘Proceed Anyway’ to confirm you understand and acknowledge the risk.',\n  labelCopyCodeClip: 'Referral Code Copied to Clipboard!',\n  labelDepositPending: '{{l1Symbol}} to {{l2Symbol}} Pending',\n  labelWithDrawPending: '{{l2Symbol}} to {{l1Symbol}} Pending',\n  labelContactsEditContactBtn: 'Edit Contact',\n  labelLargePriceVariance: 'Large Price Variance',\n  labelHighPriceImpacTitle: 'High Price Impact Detected',\n  labelTimeoutAddressClick:\n    '{{l1Symbol}} account checking request was rejected or some unknown error occurred, please <a>retry</a>',\n  labelSmallOrderAlertLine: 'Small trades (below ~$100) incur a higher fee.',\n  labelLimitImpactTitle: 'Limit taker Order Requires Confirmation',\n  labelRedPacketViewType2: 'Exclusive',\n  labelRedPacketPlazaPublic: 'Public Plaza',\n  labelRedPacketPlazaPublicDes:\n    'Everyone in the Loopring community can participate in claiming the red packet',\n  labelRedPacketQRPublic: 'Public QR',\n  labelRedPacketQRPublicDes:\n    'Anyone that knows the QR code can participate in claiming the red packet',\n  labelRedPacketExclusive: 'Exclusive Red Packet',\n  labelRedPacketExclusiveDes: 'Only users that have received the red packet can claim it',\n  labelRedPacketHaveExclusive: 'You have {{count}} exclusive Red Packets.',\n  labelRedPacketExclusiveViewDetails: 'View Details >',\n  labelRedPacketCongratulations: 'Congratulations!',\n  labelExclusiveRedpacket: 'Exclusive Red Packets',\n  labelRedpacketExclusiveReady: 'You have {{count}} exclusive Red Packets ready',\n  labelRedpacketSentMaxLimit: 'Sent / Max Limit',\n  labelRedpacketCreateNew: 'Create New Red Packet',\n  labelRedpacketGiftRedPacket: 'Count of Red Packet with Gift',\n  labelRedpacketRedPacketscount: 'Total Red Packets',\n  labelRedpacketRevealTime: 'Reveal Time',\n  labelRedpacketRecipients: 'Red Packet Recipients >',\n  labelRedpacketRecipientList: 'Recipient List',\n  labelExclusiveWhitelistDes:\n    \"For whitelisted users, each Red Packet can accommodate a maximum of 10,000 addresses, while standard users are allowed up to 50 addresses per Red Packet. Whitelisted addresses include Loopring, our partners, or other verified members. If you're interested in being whitelisted, please contact us at support@loopring.io.\",\n  labelRedpacketTextimport: 'Text import',\n  labelRedpacketContactImport: 'Contact import',\n  labelRedpacketNotificationDisplay: 'Notification Display',\n  labelRedpacketRedDotDes: 'Recipients are alerted via a badge next to the Red Packets category',\n  labelRedpacketBadge: 'Badge',\n  labelRedpacketPopUp: 'Pop-up Notification',\n  labelRedpacketPopUpTooltip:\n    \"Whitelisted addresses include Loopring, our partners, or other verified members. If you're interested in being whitelisted, please contact us at support@loopring.io.\",\n  labelRedpacketPopPpDes:\n    'Recipients are alerted via a prominent display that highlights the contents of the RedPacket. (Limited to whitelisted users)',\n  labelRedpacketPrepareRedPacket: 'Prepare Red Packet',\n  labelRedPacketChooseTarget: 'Select existing red packet or create a new one',\n  labelRedPacketRecipientList: 'Recipient List',\n  labelRedPacketPublicTooltip:\n    'Your Red Packet is public, and everyone can participate in claiming it.',\n  labelRedPacketPrivateTooltip:\n    '<p>Your Red Packet is private, and only the addresses you specify can claim it.</p>' +\n    '<p>To create a new Exclusive Red Packet, please follow these steps:</p>' +\n    '<li>1. Select the type of Red Packet</li>' +\n    '<li>2. Specify the amount of Red Packets to be sent and the date/time for delivery</li>' +\n    '<li>3. Designate the recipients</li>' +\n    '<li>4. Set the Notification Display</li>' +\n    '<p>For whitelisted users, each Red Packet can accommodate a maximum of 10,000 addresses, while standard users are allowed up to 50 addresses per Red Packet.</p>' +\n    \"<p>Whitelisted addresses include Loopring, our partners, or other verified members. If you're interested in being whitelisted, please contact us at support@loopring.io.</p>\",\n  labelRedpacketExclusiveEmpty: 'Your Prepared but unaddressed red packets will be displayed here!',\n  labelRedpacketExclusiveSelected: 'Selected: {{count}}',\n  labelRedpacketExclusiveManualEdit: 'Manual Edit',\n  labelRedpacketValidAddresses: 'Valid Addresses: {{count}}',\n  labelRedpacketTips: 'Tips',\n  labelRedpacketChangeImportTips:\n    'If you change the import method, the previously selected addresses will be erased, are you sure you want to erase them?',\n  labelRedpacketAddressesReview: 'Addresses Review',\n  labelRedpacketAddressesReviewPart1: 'The list contains {{count}} valid addresses,',\n  labelRedpacketAddressesReviewPart2: '{{count}} invalid addresses',\n  labelRedpacketAddressesReviewPart3:\n    '. To proceed, invalid addresses will be automatically removed from the list.',\n  labelRedpacketExclusiveListEmpty:\n    'Your Prepared but unaddressed red packets will be displayed here!',\n  labelRedpacketreceiptListEmpty: 'The addresses of the red packet you sent will be displayed here',\n  labelRedpacketBestwishes: 'Best wishes',\n  labelSendRedPacketTitleExclusive: 'Send Red Packet -- Exclusive',\n  labelSendRedPacketClear: 'Clear',\n  labelSendRedPacketMax: 'Max: {{count}}',\n  labelRedPacketMaxValueExceeded: 'Maximum value exceeded',\n  labelRedPacketTotal: 'Total {{count}}',\n  labelRedPacketExclusiveTag: 'Exclusive',\n  labelRedPacketClaiming: 'Claiming',\n  labelRedPacketReceiptsList: 'Red Packet Receipt >',\n  labelEOA: 'EOA',\n  labelLoopringWallet: 'Loopring',\n  labelOtherSmart: 'Other Smart',\n  labelBinance: 'Binance',\n  labelHuobi: 'Huobi',\n  labelOtherExchange: 'Other Exchange',\n  labelContactsEditContact: 'Edit Contact',\n  labelLeverageETHStakingDes: 'Gain higher APY aggressively',\n  labelDownloadShared: 'Download',\n  labelShareReferralCode: 'Share to',\n  labelShareMessage:\n    'Join me at Loopring and earn exclusive rewards with Loopring Referral Program! https://www.loopring.io/#/?referralcode={{code}}',\n\n  labelInvestDualAutoTitle: \"What's Auto Reinvest\",\n  labelDualAutoTitle: 'Auto Reinvest <1></1>',\n  labelDualAutoTitleDes:\n    'Auto Reinvest will automatically reinvest your investment and earned interest into a new term with the same Target Price once the previous term expires, continuing until you successfully buy or sell crypto. If there isn’t an available product within 2 hours after the previous settlement, the order will be automatically closed and your investment and earned interest will be unlocked.\\n',\n  labelInvestDualAutoCheck:\n    '<p>Auto Reinvest will automatically reinvest your investment and earned interest into a new term with the same Target Price once the previous term expires, continuing until you successfully buy or sell crypto. If there isn’t an available product within 2 hours after the previous settlement, the order will be automatically closed and your investment and earned interest will be unlocked.</p><p> Reinvest Target Price: The Target Price at which you want to buy or sell crypto.</p><p> Longest Settlement Date: The maximum duration available for selecting the settlement period. Auto Reinvest will automatically match products with settlement periods that do not exceed the Longest Settlement Date.</p>',\n  labelDualAutoDetail:\n    'Auto Reinvest will try to find a new product which based on the following rule at 16:00 on the settlement day.',\n  labelDualAutoDUAL_BASEPrice: 'Sell Price <1></1>',\n  labelDualAutoDUAL_CURRENCYPrice: 'Buy Price <1></1>',\n  labelDualAutoDUAL_BASEPriceDes: 'The target price at which you want to sell crypto.',\n  labelDualAutoDUAL_CURRENCYPriceDes: 'The target price at which you want to buy crypto.',\n  labelDualModifyParameter: 'Modify Parameter',\n  labelDayDisplay: '{{item}} Day(s)',\n  labelDualModifyConfirm: 'confirm',\n  labelDualAutoDurationDes:\n    'The maximum duration when selecting the settlement period. Auto Reinvest will automatically match products with settlement periods that do not exceed the Longest Settlement Date.',\n  labelDualModifyBtn: 'Modify',\n  labelTurnOffDualAutoInvest: 'Stop Auto Invest',\n  labelDualModifyAPR: 'APR: {{value}}',\n  labelDualModifySettlementDateDes: 'Changes will take effect after the Next Settlement Date.',\n  labelDualModifySettlementDate: 'Next Settlement Date: {{date}}',\n  labelDualEditSuccess: 'Update successful!',\n  labelDualEditFailed: 'Update Failed!',\n  labelDualEditDuration: 'Modify Longest Settlement Date <1></1>',\n  labelDualEditDurationDes:\n    'The maximum duration when selecting the settlement period. Auto Reinvest will automatically match products with settlement periods that do not exceed the Longest Settlement Date.',\n  labelDualInvestGuid: 'Invest',\n  labelCoverGain: 'Covered Gain',\n  labelCoverGainDes: 'Earn interest before taking profits',\n  labelDip: 'Buy The Dip',\n  labelDipDes: 'Earn interest while waiting for your price target',\n  labelDualMerge: 'Dual Investment',\n  labelDualMergeDes: 'Select based on Token and Settlement Date',\n  labelDualChooseTokenDUAL_BASE: 'Step 1: Choose a token to sell',\n  labelDualChooseTargetPriceDUAL_BASE: 'Step 2: Choose Target Price and Settlement Date',\n  labelDualChooseTokenDUAL_CURRENCY: 'Step 1: Choose a token to buy',\n  labelDualChooseTargetPriceDUAL_CURRENCY: 'Step 2: Choose Target Price and Settlement Date',\n  labelDualTypeDualGain: 'Covered Gain',\n  labelDualTypeDualDip: 'Buy The Dip',\n  labelDualTypeDualBegin: 'Dual Investment',\n  labelDualTypeAll: 'Dual Investment',\n  labelDualAutoCancelConfirm: 'Disable Auto Reinvest',\n  labelDualAutoCancelOrder: 'Cancel',\n  labelDualAutoCancelConfirmDes:\n    'Are you sure about disable auto reinvest? If disabled, there will be no new orders after the next settlement.',\n  labelDualModifySettlementDateDialog: 'Next Settlement Date',\n  labelDefiRate: 'Rate',\n  labelDefiLido: 'Lido',\n  labelDefiRocketPool: 'Rocket Pool',\n  labelDualIsHigh: 'is significantly higher',\n  labelDualIsLow: 'is significantly lower',\n  labelDualAutoAlert:\n    \"The current price of {{base}} is {{currentPrice}} {{quote}}, which  {{method}}  than the price you've set for Auto Reinvest. This may result in a lower APY for your next settlement. You can adjust the price for Auto Reinvest.\",\n  labelDualAutoDuration: 'Longest Settlement Date <1></1>',\n  labelInvestDualGainTitle: 'What is Covered Gain?',\n  labelInvestDualGainGuid:\n    '<p>Covered Gain is an investment strategy to sell digital assets at your Target Price and earn interest while waiting.</p>' +\n    '<p>On the Settlement Date, there can be 2 scenarios:</p>' +\n    '<ol><li>Market Price > Target Price</li>' +\n    '<li>Market Price ≤ Target Price</li></ol>' +\n    '<h5>Market Price > Target Price</h5>' +\n    '<p>Your original investment and earned interest will be sold at the target price.</p>' +\n    '<p>This order is then closed regardless of whether \"Auto Reinvest\" is enabled or not.</p>' +\n    '<h5>Market Price ≤ Target Price</h5>' +\n    '<p>Your original investment and earned interest won’t be sold.</p>' +\n    '<p>If you enable the “Auto Reinvest” feature, Loopring will automatically subscribe to a suitable dual investment product based on the agreed terms until you either successfully sell crypto at your desired price or disable the feature.</p>' +\n    '<h5>Auto Reinvest</h5>' +\n    '<p>When you enable the “Auto Reinvest” feature, Loopring will automatically reinvest your funds into a new product with the same target price when the previous product expires, continuing until you successfully sell your crypto at your Target Price. If there isn’t an available product within 2 hours after the previous settlement, the order will be automatically closed.</p>' +\n    '<p>Sell Price: the Target Price at which you want to sell your crypto.</p>' +\n    \"<p>Longest Settlement Date: your acceptable investment period. If no suitable products are available within this range, “Auto Reinvest” will not subscribe to any products for you, even if it's enabled.</p>\",\n  labelInvestDualDipTitle: 'What is Buy The Dip?',\n  labelInvestDualDipGuid:\n    '<p>Buy The Dip is an investment strategy to buy digital assets at your Target Price and earn interest while waiting.</p>' +\n    '<p>On the Settlement Date, there can be 2 scenarios: </p>' +\n    '<ol><li>Market Price > Target Price </li>' +\n    '<li>Market Price ≤ Target Price </li></ol>' +\n    '<h5>Market Price > Target Price</h5>' +\n    '<p>Your original investment and earned interest won’t be converted. Earned interest is in USDC or USDT.</p>' +\n    '<p>If you enable the “Auto Reinvest” feature, Loopring will automatically subscribe to a suitable dual investment product based on the agreed terms until you either successfully buy crypto at your desired price or disable the feature.</p>' +\n    '<h5>Market Price ≤ Target Price</h5>' +\n    '<p>Your original investment and earned interest will be converted at the Target Price.</p>' +\n    '<p>This order is then closed regardless of whether \"Auto Reinvest\" is enabled or not.</p>' +\n    '<h5>Auto Reinvest</h5>' +\n    '<p>When you enable the “Auto Reinvest” feature, Loopring will automatically reinvest your funds into a new product with the same target price when the previous product expires, continuing until you successfully buy crypto at your desired price. If there isn’t an available product within 2 hours after the previous settlement, the order will be automatically closed.</p>' +\n    '<p>Buy Price: the Target Price at which you want to buy crypto.</p>' +\n    '<p>Sell Price: the Target Price at which you want to sell crypto.</p>' +\n    \"<p>Longest Settlement Date: your acceptable investment period. If no suitable products are available within this range, “Auto Reinvest” will not subscribe to any products for you, even if it's enabled.</p>\",\n  labelAssetDualInvests: 'Dual Investment',\n  labelTxGuardian_upgrade_contract: 'upgrade contract',\n  labelTxGuardian_approve_token: 'approve token',\n  labelContactNameExisted: 'Name already exists',\n  labelContactAddressExisted: 'Address already exists',\n  labelL1toL2ThirdPartOn: 'On-ramp Crypto',\n  labelL1toL2ThirdPartOff: 'Off-ramp Crypto',\n  labelTargetRedpacketOption1: 'Option 1',\n  labelTargetRedpacketCreateTitle:\n    'The following steps are required to create a new Exclusive Red Packet',\n  labelTargetRedpacketCreateStep1: '1. Select the type of red packet to be sent.',\n  labelTargetRedpacketCreateStep2: '2. Number of red packets to be sent/transmission time',\n  labelTargetRedpacketCreateStep3: '3. Designated Red Packet Recipients',\n  labelTargetRedpacketCreateStep4: '4. Notification display for red packet recipients',\n  labelTargetRedpacketNoRedpacket: 'You do not have an existing wallet yet',\n  labelTargetRedpacketNoRedpacketDes:\n    'If your prepared but unaddressed Red Packets will be displayed here !',\n  labelTargetRedpacketOption2: 'Option 2',\n  labelEarnVaultTitle: 'Loopring DeFi Assets',\n  labelDualBTC: 'ETH - WBTC Dual Investment',\n  labelDualBTCDes: 'Select based on Token and Settlement Date',\n  labelDualTypeDualBTC: 'ETH - WBTC Dual Investment',\n  labelDualNewPriceLessThan: 'if {{base}} < {{value}} {{quote}}',\n  labelDualNewPriceLessOrEqualThan: 'if {{base}} ≤ {{value}} {{quote}}',\n  labelDualNewPriceGreaterThan: 'if {{base}} > {{value}} {{quote}}',\n  labelDualNewPriceGreaterThanOrEqual: 'if {{base}} ≥ {{value}} {{quote}}',\n  labelInputMax: 'Max',\n  labelTokenEnterDualToken: 'Amount',\n  labelTokenMaxBalance: 'Available Balance',\n  labelInvestMiniDual: 'Min {{value}}',\n  labelDualAutoSearchingDes: 'Auto reinvesting. Searching for the product...',\n  labelDualAutoInvestTip: 'Auto Reinvest Status:{{}}',\n  labelDualRetryStatusSuccess:\n    'Auto reinvested successful. A new order has been generated for you.',\n  labelDualRetryStatusError:\n    'Auto reinvest failed. Cannot find product with Buy Price of {{price}} and Longest Settlement Date of {{day}} days. ',\n  labelDualRetryStatusRetrying: 'Auto reinvesting. Searching for the product...',\n  labelDualRetryPending: 'Pending',\n  labelDualRetryTerminated: 'Terminated',\n  labelDualRetryFailed: 'Failed',\n  labelDualRetrySuccess: 'Successful',\n  labelDualRetryStatusTerminated:\n    'Auto Reinvest terminated. You successfully purchased the target token.',\n  labelInvestmentStatusSettled: 'Settled',\n  labelInvestmentStatusDelivering: 'Delivering',\n  labelInvestmentStatusSubscribe: 'Earning',\n  labelDualTxsSettlement: 'Settlement',\n  labelDualAuto: 'Auto Reinvest',\n  labelDualAssetReInvestEnable: 'Enabled',\n  labelDualDeliver: 'Settlement Price',\n  labelDualAssetReInvestDisable: 'Disabled',\n  labelUnlockErrorLine1:\n    'The failure to unlock your wallet most likely is due to network condition or browser issue, which may be recovered via refreshing the page or reopening it',\n  labelUnlockErrorLine2Part1: 'As a last resort, you can ',\n  labelUnlockErrorLine2Part2: 'Reset Loopring L2 keypair',\n  labelUnlockErrorLine2Part3:\n    '. This can be especially helpful if all other retry attempts fail, particularly when using hardware wallets.',\n  labelResetLoopringL2: 'Reset Loopring L2 keypair',\n  labelResetlockedReset1:\n    \"Please note that if you have pending Dual Investment subscriptions, the L2 keypair reset won't take immediate effect. Your wallet's L2 account will remain locked until all subscriptions have settled. While locked, you won't be able to perform any L2 operations.\",\n  labelResetlockedReset2:\n    'Additionally, any pending limit orders will be canceled since they are tied to the old L2 keypair.',\n  labelResetunlockedWithDual1:\n    \"We’ve detected that you have an active Dual Investment subscription. As a result, the L2 keypair reset won't take effect immediately. Instead, your wallet's L2 account will remain locked until all subscriptions have settled. While locked, you won't be able to perform any L2 operations.\",\n  labelResetunlockedWithDual2:\n    'Additionally, any pending limit orders will be canceled since they are tied to the old L2 keypair.',\n  labelResetunlockedWithoutDual:\n    'Resetting the L2 keypair will cancel all pending limit orders as they tied to the old L2 keypair.',\n  labelDualAutoReinvest: 'Auto Reinvest',\n  labelInvestDualTutorialContent2:\n    '<h6>Auto Reinvest</h6>' +\n    '<p>When you enable the “Auto Reinvest” feature, Loopring will automatically reinvest your funds into a new product with the same target price when the previous product expires, continuing until you successfully buy crypto at your desired price. If there isn’t an available product within 2 hours after the previous settlement, the order will be automatically closed.</p>' +\n    '<p>Buy Price: the Target Price at which you want to buy crypto.</p>' +\n    '<p>Sell Price: the Target Price at which you want to sell crypto.</p>' +\n    \"<p>Longest Settlement Date: your acceptable investment period. If no suitable products are available within this range, “Auto Reinvest” will not subscribe to any products for you, even if it's enabled.</p>\",\n  labelNoticeTitle: 'Notifications',\n  labelNotificationTime: '{{time}}',\n  labelNotificationClear: 'Clear all',\n  labelNotificationReadAll: 'Mark all as read',\n  labelNotificationLabel: 'Notification',\n  labelActiveL1successfulNote: 'Active {{ethereumL1}} successful',\n  labelActiveL2successfulNote: 'Active {{loopringL2}} successful',\n  labelActivatingL1AccountNote: 'Activating {{ethereumL1}} successful',\n  labelL1ReceiveNote: 'Receive token in {{ethereumL1}}',\n  labelL1SendNote: ' Send token from {{ethereumL1}}',\n  labelL2ReceiveNote: 'Receive token in {{loopringL2}}',\n  labelL2SendNote: 'Send token from {{loopringL2}} successful',\n  labelL2DepositNote: 'Receive token in {{loopringL2}}',\n  labelL2WithdrawNote: 'Send token in {{loopringL2}}',\n  labelTotalUnRead: '{{total}} unread(s)',\n  labelReadAll: 'View all',\n  labelLuckyTokenNormal: 'Normal',\n  labelRedPacketSendAverageTitle: 'Average Red Packet',\n  labelBlindBoxHint:\n    'Each recipient will receive a sealed Red Packet which cannot be opened until the expiration date. While some recipients will receive an NFT, others will need to try their luck next time.',\n  labelNormalRedPacketTitle: 'Normal Red Packet',\n  labelDualDefaultAutoTitle: 'Default Enable Auto Reinvest',\n  labelDualLongestSettlementDuration: 'Modify Longest Settlement Date',\n  labelDualLongestSettlementFixed: 'Fixed',\n  labelDualLongestSettlementAutomatic: 'Automatic',\n  labelDualSettingConfirm: 'Confirm',\n  labelReceiveToken: 'Receive',\n  labelETHStakingEnterPaymentToken: 'Amount',\n  labelDefiDuration: 'Duration',\n  labelFlexible: 'Flexible',\n  labelEstAPR: 'Est.APR',\n  labelTradingFeeTooltips:\n    \"The trading fee is determined by the size of your trade. Usually, it's 0.1% of your total converted amount; or the necessary fee that covers the transaction cost for small transactions.\",\n  labelENSAlert:\n    \"ENS & Address Mismatch. Before proceeding with the transfer, we recommend updating the contact's information for accuracy.\",\n  labelSendToContact: 'Send to',\n  labelContactENSAlert:\n    \"ENS & Address Mismatch. Before proceeding with the transfer, we recommend updating the contact's information for accuracy.\",\n  labelL2DualNote: 'Dual Investment Notification',\n  labelQuickInvest: 'Quick Invest',\n  labelUpdateContactsNext: 'Go to Update Contact',\n  labelENSAddressMismatch: 'ENS & Address Mismatch',\n  labelVault: 'Portal',\n  labelVaultHome: 'Home',\n  labelVaultDashboard: 'Dashboard',\n  labelVaultRefresh: 'Refresh',\n  labelVaultAddBtn: 'Add Collateral',\n  labelVaultJoinBtn: 'Supply Collateral',\n  labelVaultCheckInProcessing: 'Checking Portal status',\n  labelVaultRecord: 'Records',\n  labelEnterToken: 'Select Token',\n  labelVaultExitBtn: 'Settle',\n  labelVaultLoanBtn: 'Loan',\n  labelVaultTutorial: 'Tutorial',\n  labelVaultTotalToken: 'Portal Token',\n  labelVaultJoinMini: 'Minimum of {{arg}}',\n  labelVaultJoinMax: 'Maximum of {{arg}}',\n  labelVaultJoinNotEnough: 'Insufficient {{arg}} balance',\n  labelVaultJoinMarginTitle: 'Add Collateral',\n  labelVaultJoinTitle: 'Supply Collateral',\n  labelVaultTradeBtn: 'Portal Trade',\n  labelVaultRedeemBtn: 'Settle',\n  labelVaultExitDes:\n    'Upon closing your position, all open orders will be canceled, and any outstanding debts will be automatically repaid. If the available balance of the Portal_Token is insufficient to cover the debt, Loopring will sell a portion of your assets at the market price to repay the debt. The remaining Portal_Token will be converted to the token you have staked at the current market price and returned to your {{loopringL2}} Account.',\n  labelVaultConfirm: 'Confirm',\n  labelVaultCancel: 'Cancel',\n  labelVaultExitTitle: 'Settle',\n  labelVaultSwapBtn: 'Swap',\n  labelVaultSwap: 'Portal Trade',\n  labelVaultType: 'Type',\n  labelVaultTypeOpenPosition: 'Supply Collateral',\n  labelVaultStatus: 'Status',\n  labelVaultJoinStatus: '{{status}} {{percentage}}',\n  labelVaultTradeStatus: '{{status}} {{percentage}}',\n  labelVaultCollateral: 'Collateral',\n  labelVaultReceive: 'Receive',\n  labelVaultTime: 'Time',\n  labelVaultExitType: 'Type',\n  labelVaultExitTypeClose: 'Settle',\n  labelVaultExitStatusLabel: 'Status',\n  labelVaultExitStatus: '{{status}}',\n  labelVaultExitStatusSuccess: 'Success',\n  labelVaultExitTotalBalance: 'Total Balance',\n  labelVaultExitTotalDebt: 'Total Debt',\n  labelVaultExitTotalEquity: 'Total Equity',\n  labelVaultExitProfit: 'Profit',\n  labelVaultExitProfitPercentage: 'Profit Percentage',\n  labelVaultExitTime: 'Time',\n  labelVaultExitStatusPending: 'Pending',\n  labelVaultExitCloseAmount: 'Redeem Token',\n  labelVaultExitPendingDes:\n    'The request is being processed and is expected to take 1-2 minutes. Please be patient.',\n  labelVaultBorrow: 'Borrow',\n  labelVaultRepay: 'Repay',\n  labelVaultTotalQuoteDes:\n    'Total Quota is the maximum amount available  for you to be used as collateral.',\n  labelVaultTokenQuoteDes:\n    'When provide the token as collateral, you will receive an equivalent amount of Portal Token.',\n  labelTitleVaultDes:\n    'Loopring Portal can be treated as an isolated margin account allowing users to borrow/lend tokens with collateral. Other than leveraged trading, it also allows users to trade hot tokens that are not available in Loopring DEX with CEX liquidity.',\n  labelTitleVault: 'Portal',\n  labelVaultHomeTitle: 'Home',\n  labelVaultDashboardTitle: 'Dashboard',\n  labelVaultTotalBalance: 'Total Balance',\n  labelVaultOpenDate: 'Open Date:',\n  labelVaultMarginLevel: 'Margin Level',\n  labelVaultTotalCollateral: 'Total Collateral',\n  labelVaultTotalDebt: 'Total Debt',\n  labelVaultTotalEquity: 'Total Equity',\n  labelVaultProfit: 'Profit',\n  labelVaultCloseBtn: 'Close',\n  labelGoVaultDashBoard: 'Go to Dashboard',\n  labelVaultBrowserToken: 'Amount',\n  labelVaultQuotaTooltips: 'PortalQuoteDes',\n  labelVaultQuota: 'Total Quota',\n  labelVaultBorrowMini: 'Minimum of {{arg}}',\n  labelVaultBorrowNotEnough: 'Exceeded Maximum Borrowable Amount',\n  labelVaultBorrowMax: 'Maximum of {{arg}}',\n  labelVaultBorrowBtn: 'Borrow',\n  labelVaultBorrowStatusLabel: 'Status',\n  labelVaultBorrowTypeLabel: 'Type',\n  labelVaultBorrowAmountLabel: 'Amount',\n  labelVaultBorrowStatus: '{{status}}',\n  labelVaultBorrowTitle: 'Borrow',\n  labelPending: 'Pending',\n  labelVaultRepayMini: 'Minimum of {{arg}}',\n  labelVaultRepayNotEnough: 'Insufficient balance',\n  labelVaultRepayMax: 'Maximum of {{arg}}',\n  labelVaultRepayBtn: 'Repay',\n  labelRepayQuota: 'Borrowed',\n  labelVaultWhatis: 'What is Loopring Portal?',\n  labelVaultDesSimple:\n    '<p>Vault: Using a third-party funds to trade assets. Traders can access additional capital, amplifying trading results.</p>',\n  labelVaultRiskDes:\n    '<p>Loopring Portal acts as an isolated margin account, enabling users to borrow and lend tokens with collateral. Besides supporting leveraged trading, it also facilitates the trading of tokens not available on Loopring DEX by tapping into CEX liquidity depth. </p>' +\n    \"<p>It's important to note that all assets in Portal are hedged on CEX, incurring an associated cost known as the Asset Holding Fee, charged on an hourly basis. We strongly recommend closing your position if it's no longer needed for trading to reduce costs.</p>\" +\n    '<p>In order to initiate the forced clearing of assets in the event of liquidation, Loopring will require your approval to handle the collateral asset. Additionally, after closing a position, there may be some remaining Portal tokens in your account that Loopring will need to clear before allowing you to open a new position.</p><ul>' +\n    '<li>There is an Asset Holding Fee for assets in Portal.</li>' +\n    '<li>I will grant Loopring authority to deal with my collateral in case of forced liquidation.</li>' +\n    '<li> I will grant Loopring the authority to clear all previously remaining Lv tokens for all new position openings in Portal.</li></ul>',\n  labelVaultRepayTitle: 'Repay',\n  labelVaultRepayStatus: '{{status}}',\n  labelVaultRepayStatusLabel: 'Status',\n  labelVaultRepayTypeLabel: 'Type',\n  labelVaultRepayType: 'Repay',\n  labelVaultRepayTotalBalance: 'Amount',\n  labelVaultVAULT_STATUS_RECEIVED: 'Received',\n  labelVaultVAULT_STATUS_PROCESSING: 'Processing',\n  labelVaultVAULT_STATUS_SUCCEED: 'Success',\n  labelVaultVAULT_STATUS_FAILED: 'Failed',\n  labelVaultVAULT_STATUS_PENDING: 'Pending',\n  labelVaultAccountWait: 'Portal account in loading...',\n  labelVaultInRedeemWaiting: 'Portal account is in process of settle...',\n  labelVaultJoinSymbolNotSame: 'Only {{symbol}} allow Margin Call',\n  labelVaultRepaySuccess: 'Success',\n  labelVaultJoinSuccess: 'Success',\n  labelVaultRedeemSuccess: 'Success',\n  labelVaultBorrowSuccess: 'Success',\n  labelVaultTradeSuccess: 'Success',\n  labelVaultRepayInProgress: 'Processing...',\n  labelVaultRedeemInProgress: 'Processing...',\n  labelVaultBorrowInProgress: 'Processing...',\n  labelVaultTradeInProgress: 'Processing...',\n  labelVaultJoinInProgress: 'Processing...',\n  labelVaultRepayFailed: 'Failed',\n  labelVaultRedeemFailed: 'Failed',\n  labelVaultBorrowFailed: 'Failed',\n  labelVaultJoinFailed: 'Failed',\n  labelVaultTradeFailed: 'Failed',\n  labelLayer2HistoryVaultRecords: 'Portal',\n  labelVaultTitleRisk: 'What is Loopring Portal?',\n  labelProTime1h: '1h',\n  labelProTime1d: '1d',\n  labelProTime1w: '1w',\n  labelStats: 'Stats',\n  label24PriceChange: '24h Price Change',\n  label7dPriceChange: '7d Price Change',\n  labelVaultREDEEMPendingBtn: 'Settle in Processing',\n  labelVaultlnredeemWaiting: 'Settle in Processing',\n  labelJoinTitle: 'Supply Collateral',\n  labelRedeemTitle: 'Settle',\n  labelRedeemDesMessage:\n    'Please be aware that there may be a brief waiting period due to automatic liquidation. We appreciate your patience and assure you that we are working to process your request as quickly as possible. Thank you for your understanding.',\n  labelJoinDesMessage:\n    'Please open a position first.',\n  labelFailed: 'Failed',\n  labelVAULT_COLLATERAL: 'Portal Collateral',\n  labelTokenVaultDes:\n    '{{symbol}} in Portal is a token backed 1:1 with {{symbol}}, bringing greater liquidity to Loopring DEX.',\n  labelTokenWebsite: 'Website',\n  labelTokenContractAddress: 'Contract Address',\n  labelTokenSupply: 'Total Supply',\n  labelMarketCap: 'Market Cap',\n  labelTokenInfo: 'Token Info',\n  labelTokenIntroduce: 'Introduction',\n  labelVaultRedeemDetail: 'Details',\n  labelCloseOutDetail: 'Settle',\n  labelVaultTradeTitle: 'Portal Trade',\n  labelVaultPrice: 'Price',\n  labelVaultSell: 'Sell',\n  labelVaultBuy: 'Buy',\n  labelVaultFee: 'Trade Fee',\n  labelVaultJoin: 'Supply Collateral',\n  labelVaultMarginCall: 'Add Collateral',\n  labelVaultMaxBrowserLabel: 'Max borrowable: ',\n  labelVaultBorrowed: 'Borrowed',\n  labelVaultRepayBalance: 'Total Balance',\n  labelVaultPendingDes:\n    'The request is being processed and is expected to take 1-2 minutes. Please be patient.',\n  labelVaultTotalDebtTooltips:\n    'Total Debt is comprised of two parts: loans and the cost incurred from utilizing the capital. The cost is determined by multiplying the Total Balance by the Funding Rate, which will accumulate on an hourly basis.',\n  labelVaultMarginLevelTooltips:\n    'Margin Level provides an indication of how close your account is to experiencing a margin call or being liquidated. To avoid liquidation, you can either supply more collateral or repay borrowed positions.',\n  labelOpenPositionDetail: 'Supply Collateral Detail',\n  labelMarginCallDetail: 'Margin Call',\n  labelBorrowDetail: 'Borrow',\n  labelRepayDetail: 'Repay',\n  labelTradeDetail: 'Trade',\n  labelVaultPlacedAmount: 'Placed Amount',\n  labelVaultExecutedAmount: 'Executed Amount',\n  labelVaultExecutedRate: 'Executed Rate',\n  labelVaultConvertedAmount: 'Converted Amount',\n  labelVaultTxFee: 'Fee',\n    labelBtradeExecutedAmount: 'Executed Amount',\n    labelBtradeExecutedAmountTip: 'The quantity successfully processed on the CEX side.',\n    labelBtradePlacedAmount: 'Placed Amount',\n    labelBtradePlacedAmountTip: `The quantity you invested in 'Block Trade' that you intend to execute.`,\n    labelBtradeExecutedRate: 'Executed Rate',\n    labelBtradeConvertedAmount: 'Converted Amount',\n    labelBtradeConvertedAmountTip: 'The quantity successfully converted from the CEX side',\n    labelBtradeSettledAmount: 'Settled Amount',\n    labelBtradeSettledAmountTip: `The quantity deposited into your Loopring L2 account. If you opt for 'Prioritize Quantity' mode and the Loopring L2 pool exhausts its quota, you may not receive the entire amount instantly. The remaining tokens will be 'swapped' at the executed price once the pool is replenished.`,\n  labelVaultExitTypeForcedLiquidation: 'Forced Liquidation',\n\n  labelVaultExecutedAmountTip: 'The quantity successfully processed on the CEX side.',\n  labelVaultPlacedAmountTip: `The quantity you invested in 'Portal Trade' that you intend to execute.`,\n  labelVaultConvertedAmountTip: 'The quantity successfully converted from the CEX side.',\n  labelVaultSettledAmountTip: `The quantity deposited into your Loopring L2 account. If you opt for 'Prioritize Quantity' mode and the Loopring L2 pool exhausts its quota, you may not receive the entire amount instantly. The remaining tokens will be 'swapped' at the executed price once the pool is replenished.`,\n  labelVaultAmount: 'Amount',\n  labelVaultOpenPositionDes: 'Please open a position first.' ,\n  labelVaultCollateralManagement: 'Collateral Management',\n  labelGuardianCodeNetworkError: 'Network not match',\n  labelGuardianCodeAccountError: 'guardian not match current account',\n  labelGuardianCodeFormatError: 'wrong data format',\n  labelGuardianCodeOwner: 'Owner',\n  labelGuardianCodeRequestedWallet: 'Requested wallet',\n  labelGuardianCodeRequestType: 'Request Type',\n  labelGuardianCodeNetwork: 'Network',\n  labelGuardianCodeRequester: 'Requester',\n  labelGuardianCodeAuthorizationResult: 'Authorization Result',\n  labelGuardianCodeApproved: 'Approved',\n  labelGuardianCodeReject: 'Reject',\n  labelGuardianCodeApprove: 'Approve',\n  labelGuardianCodeShare: 'Share',\n  labelGuardianCodeNext: 'Next',\n  labelGuardianCodeEnterApprovalCode: 'Enter Approval Code',\n  labelGuardianCodeEnterApprovalCodeHint: 'Please enter the Approval Code',\n  labelGuardianCodeConfirmationDes: `Kindly approve the operation request from the wallet you are safeguarding. The approval\n  process is fee-free. For added security, we request you enter the authorization code\n  generated by the requester. If you haven't received this code, kindly synchronize with the\n  requester for the necessary information.`,\n  labelGuardianCodeSharingDes: `Please send the QR code to the requester`,\n  labelGuardianCodeSharingApprovalRequest: 'Approval Request',\n  labelGuardianNotWhoIProtect: 'Request not from who I protect',\n  labelEarnAssetDefiPortfolio: 'DeFi Portfolio',\n  labelEarnDepositDes: `There are no assets in your Loopring DeFi account yet. Please deposit a supported token to start exploring the DeFi world.`,\n  labelEarnAssetTokens: 'All Tokens',\n  labelBlockTradeTutorial: 'Block Trade Tutorial',\n  labelAccountCreatedHint: 'Your Loopring DeFi account has been created. Please sign to complete the process.',\n  labelFrozen: 'Frozen',\n  labelBTradeTutorial: `\n  Block Trade offers a secure and trustless way for users to swap tokens using CEX\n  liquidity. The trades happen exclusively between designated entities, ensuring that the\n  existing liquidity of the DEX remains unaffected. There is no price impact to other DEX\n  users as a result of the transaction.\n  `,\n  labelLearnMore: 'Learn More >',\n  labelLearnMore2: 'Learn More',\n  labelInvestDualDes: 'Buy the dip or sell the covered gain while earning a high yield',\n  labelPortalDes: 'Loopring Portal can be treated as an isolated margin account allowing users to borrow/lend tokens with collateral. ',\n  labelBtradeDes: 'Offers a secure and trustless way for users to swap tokens using CEX liquidity.',\n  labelAPY: 'APY',\n  labelAction2: 'Action',\n  labelTotalBalance: 'Total Balance',\n  labelBalance: 'Balance',\n  depositLabelEnterTokenEarn: '选择充值代币',\n  labelLaunch: 'Launch',\n  labelSmartWalletDepositError1: 'Currently, only EOA wallets are supported.',\n  labelSmartWalletDepositError2: 'Loopring Smart Wallet support is coming soon ',\n  labelSmartWalletDepositError3: 'stay tuned for updates!',\n  labelDustCollectorDetail: 'Dust Collector',\n  labelVaultRedeem: 'Redeem Collateral',\n  labelVaultRedeemNotEnough: 'Exceeded the maximum {{arg}} redemption value',\n  labelVaultJoinRedeem: 'Redeem Collateral',\n  labelVaultCollateralDetails: 'Collateral Details',\n  labelVaultMaximumCredit: 'Maximum Credit',\n  labelVaultMaximumCreditDes: 'Maximum Credit means the maximum amount of money you can borrow from Portal based on your collateral. It is calculated by taking the total value of your collateral, adjusted for price factor and the maximum leverage.',\n  labelVaultMaximumCreditFormula: 'Maximum Credit = Sum ( Token_MarketPrice * Token_Amount * Token_PriceFactor ) * Maximum_Leverage',\n  labelVaultPriceFactor: 'The Price Factor of each collateral',\n  labelVaultMaximumLeverage: 'Maximum Leverage',\n  labelVaultLeverage: 'Leverage',\n  labelVaultAvailableBorrow: 'Borrowing Limit',\n  labelVaultLeverageRisk1: '· Selecting higher leverage will increase your liquidation risk.',\n  labelVaultLeverageRisk2: '· Borrowing Limit is based on the upper limit corresponding to the leverage you choose. The total value of all your borrowed tokens will not exceed the Borrowing Limit.',\n  labelVaultLeverageRisk3: '· Maximum Credit is the maximum amount you can borrow based on your collateral.',\n  labelVaultDebt: 'Debt',\n  labelVaultDebtDetails: 'Details',\n  labelVaultTotalBorrowed: 'Total Borrowed',\n  labelVaultTotalFundingFee: 'Total Funding Fee',\n  labelVaultValueEst: 'Value (est.)',\n  labelVaultDustCollectorDes: `The accumulated dust will be converted into corresponding USDT. If you do not have any USDT to be repaid, the converted amount will be deposited into your portal's USDT. `,\n  labelVaultConvert: 'Convert',\n  labelVaultMarginLevelAlert: 'Your margin level has reached a critical point. Please review your positions and considering adding additional collateral. Failure to address the margin call may result in forced liquidation.',\n  labelVaultDetail: 'Detail',\n  labelVaultDefaultLeverage: 'Default Leverage',\n  labelVaultHoldingCollateral: 'Holding Collateral',\n  labelVaultRedeemAlert: 'Collateral valued at more than twice your total debt can be withdrawn from your Portal account.',\n  labelTotalValue: 'Total Value',\n  labelVaultRepayment: 'Payment',\n  labelDetails: 'Details',\n  labelVaultErrorOccurred: 'An error has occurred. Please try again later.',\n  labelVaultDetails: 'Details',\n  labelVaultNoDust: 'No Dust to Collect',\n  labelVaultJoinAdd: 'Add Collateral',\n  labelVaultChangeLeverageFailed: 'Change Leverage Failed',\n  labelVaultChangeLeverageFailedTooSmall: `Leverage is smaller than permitted. Insufficient Available Borrow amount.`,\n  labelVaultMaximumCreditDesLong: 'Maximum Credit means the maximum amount of money you can borrow from Portal based on your collateral. It is calculated by taking the total value of your collateral, adjusted for price factor and the maximum leverage.',\n  labelVaultMarginLevelDes: 'Margin Level provides an indication of how close your account is to experiencing a margin call or being liquidated. To avoid liquidation, you can either supply more collateral or repay borrowed positions.',\n  labelLayer2HistoryTaikoLockRecords: 'Taiko Farming',\n  labelTaikoFarmingUnlock: \"Unlock the Value of Your Locked TAIKO !\",\n  labelTaikoFarmingMintInfo: \"Mint lrTAIKO and use it in Loopring DeFi at zero cost!\",\n  labelTaikoFarming: \"Taiko Farming\",\n  labelTaikoFarmingDescription: \"Earn Trailblazers points 60x faster by locking TAIKO and participating in Taiko Farming. Please note that TAIKO can only be unlocked after the end of Trailblazers Campaign Season 2.\",\n  labelLock2: \"LOCK\",\n  labelEnterPaymentToken: \"Enter payment token\",\n  labelMax: \"Max\",\n  labelSelectToken: \"Select token\",\n  labelAcknowledgeAndProceed: \"I acknowledge and would like to proceed.\",\n  labelUnlockAfterSeason2: \"You can unlock your TAIKO tokens only after the end of Trailblazers Season 2.\",\n  labelCurrentLockedPosition: \"My Current Locked Position\",\n  labelTotalPoints: \"Total Points\",\n  labelDailyEarningPoints: \"Daily Earning Points\",\n  labelTaikoFarmingBannerTitle: \"Taiko Farming\",\n  labelTaikoFarmingBannerDes: \"Earn Trailblazers points 60x faster by locking TAIKO and participating in Taiko Farming. Please note that TAIKO can only be unlocked after the end of Trailblazers Campaign Season 2.\",\n  labelTaikoFarmingQuestion: \"Worried about missing trading or earning opportunities when locking your valuable TAIKO?\",\n  labelTaikoFarmingExplanation: \"Loopring lets you mint lrTAIKO at a 1:1 ratio, allowing you to freely use it across all trading and earning options within Loopring DeFi. Plus, you'll continue farming Trailblazers points.\",\n  labelTaikoFarmingComingSoon: \"The lrTAIKO mint feature is coming soon!\",\n  labelTaikoFarmingPortalIntegration: \"The first DeFi integration will be with Portal, allowing you to use lrTAIKO as collateral for leveraged trading on select hot tokens. You'll be able to go LONG or SHORT on your favorite tokens based on market conditions.\",\n  labelTaikoFarmingStayTuned: \"Stay tuned for the upcoming release—more exciting use cases are on the way!\",\n  labelTaikoFarmingExploreUseCase: \"Take a tour to explore all the current Loopring DeFi use cases \",\n  labelTaikoFarmingHereLink: \"<here>\",\n  labelTaikoFarmingDepositAnytime: \". You can deposit assets into Loopring DeFi anytime and start enjoying the experience!\",\n  labelTotalPointsDes: 'Please note that Trailblazers points are awarded directly by the Taiko team. The Loopring dashboard provides a reference for the points you may receive from Taiko, but if there are any discrepancies, the official results from Taiko will be the final and trusted source.',\n  labelTAIKO_FARMING: 'Taiko Farming',\n  labelDefiCloseCian:\n    'The ciETH subscription has been deprecated. We recommend redeeming your ciETH for ETH as soon as possible. You can also explore other ETH staking portfolios for alternative options.',\n  labelVaultMarketTitle: 'Market',\n}\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/i18n/zh_CN/error.ts",
    "content": "export default {\n  labelConnectUsSimple: 'Please <1>contact us</1>.',\n  labelConnectUs: '这有可能时候一个错误, 如需帮助请<1>联系我们</1>~',\n  errorBase: '奥哦! 遇到了一些问题',\n  errorTimeout: 'Oops! Something went wrong at network.',\n  errorLoading: '不要着急, 不要着急马上就好',\n  error404: '四〇四! 这是页面不存在呢.',\n  errorMaintain: '系统维护中...',\n  errorMessageNoNetwork: 'Oops! Something went wrong at service.',\n  errorUnknown: 'Unknown Error',\n  errorOnFromSubmit: 'Submit request Info has Error!',\n  errorWrongAccount: 'Error on account Info!',\n  errorWrongToken: 'Error on Token Info!',\n  errorWrongApikey: 'Error on signature or no API key.',\n  errorWrongBalance: 'Insufficient balance',\n  errorMinimumOrder: 'Trade amount is minimum',\n  errorMaximumOrder: 'Trade amount is maximum',\n  errorOnFrozen: 'Some of your assets are frozen, please try again later.',\n  errorAboutFee: 'Fee token is not enough or incorrect.',\n  errorProviderError: 'Global ethereum is not {{name}}, please disable your other Wallet Plugin.',\n  errorOnStorageId: 'Error on wrong StorageId',\n  errorOnNoRecipient: 'Error on no Receiver',\n  errorNoMarket: 'Market is not supported.',\n  errorOnGas: 'Error on Gas Info',\n  errorOnCancelOrders: 'Error on cancel order',\n  errorInvalidHash: 'Invalid Hash',\n  errorInvalidOrderId: 'Invalid OrderId',\n  errorOnRate: 'Error on submit rate value',\n  errorForExistOrder: 'Order does not exist',\n  errorOrderExpired: 'Order has expired',\n  errorDisableOtherWalletForCurrent:\n    'Global ethereum is not {{name}}, please disable other Wallet Plugin.',\n  errorGenerateEddsa: 'Generate EdDSA key has failed.',\n  errorNotInstallGME:\n    'Please install the Gamestop Wallet browser extension. Then create, deposit, and activate the wallet before connecting to Loopring.io.',\n  errorLinKWalletApp: '<0>app market</0>',\n  errorIpfsDidToNftidError: 'IPFS Gateway Error',\n  errorMintOverlap: 'You have already minted this NFT. Please check your Wallet',\n  errorJSONStringify: 'Wrong JSON format',\n  errorCollectionMetadataNoTileUri: 'Tile uri is required',\n  errorCollectionNoName: 'Name is required',\n  errorCollectionSameName: 'Collection called {{name}} is existe',\n  errorCollectionInfo:\n    \"We've detected this collection is not yours or the Contract Address don't match\",\n  errorCollectionNoSupport: 'Only {{l2symbol}} collection is allow to mint',\n  errorCollectionNotReadable: 'Read Collection Info Failed',\n  errorIpfsTimeout: 'IPFS Gateway timeout, please try again',\n  errorRampNoInstance: 'Ramp Widget had out-off service, please re-order it.',\n  errorDualExpired: 'The order has expired.',\n  errorPrivateKey: 'Signature Wrong private key',\n  errorNoResponse: 'No response!',\n  errorMinError: 'Minimum of {{value}}',\n  errorMaxError: 'Max of {{value}}',\n  errorLengthLimit: 'Length is limit',\n  errorRedpacketEmpty: 'Red Packet is Empty',\n  errorRedpacketClaimed: 'You already opened Red Packet',\n  errorRedpacketClaimOut: 'You opened the Red Packet Too Later',\n  errorRedpacketClaimTimeOut: 'You opened the Red Packet Too Later',\n  errorOffRampExpired: 'The order has expired. please create a neworder ',\n  errorNFTRedPacketMaxError: 'Total Amount cannot exceeds {{value}} NTFs',\n  errorBetaEnv:\n    'Oops! This site is not released yet and could contain bugs. Please use it with caution!.',\n  errorProviderErrorUnknown: 'Unknown Error',\n  errorNoGamestopExtension: 'User not installed GameStop extension',\n  errorSwitchEthereum: 'wallet switch Ethereum Chain is not allowed',\n  errorEthereumNotMetamask: 'Global ethereum is not MetaMask',\n  errorGamestopNoChainChange: 'Gamestop extension no switch Ethereum Chain method',\n  errorHadUnknownCollectionDes:\n    'As the creator, you will be able to generate collection information for those NFT minted earlier that belong to nowhere. And once done, the other people holding your NFT will be able to view those NFT with proper collection information via loopring.io and loopring wallet. <1>Go</1>',\n  errorGuardianRouterError: 'Oops! Guardian site moved to <a>guardian.loopring.io</a>.',\n  errorAddressCheckError: 'Oops! Something went wrong on address checking processing ',\n  errorContactExisted: 'Contact address already exists',\n  errorContactNameExisted: 'Name already exists',\n  errorContactLimit: 'Unable to Add Contact,You have reached the maximum limit of 1500 contacts',\n  errorContactOverLimit:\n    'Unable to Add Contact,You have reached the maximum limit of 1500 contacts',\n  labelContactsAddSuccess: 'Add Contact Succeed',\n  labelContactsDeleteSuccess: 'Delete Contact Succeed',\n  labelContactsEditSuccess: 'Edit Contact Succeed',\n  labelContactsSendSuccess: 'Send Succeed',\n  labelContactsCopySuccess: 'Copied to Clipboard',\n  labelContactsAddFailed: 'Add Contact Failed',\n  labelContactsDeleteFailed: 'Delete Contact Failed',\n  labelContactsEditFailed: 'Edit Contact Failed',\n  labelContactsSendFailed: 'Send Failed',\n  errorOrderFailed: 'Order status Failed',\n}\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/i18n/zh_CN/index.ts",
    "content": "import common from './common'\nimport layout from './layout'\nimport tables from './tables'\nimport error from './error'\nimport landPage from './landPage'\nimport webEarn from './webEarn'\nexport default {\n  common,\n  layout,\n  tables,\n  error,\n  landPage,\n  webEarn\n}\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/i18n/zh_CN/landPage.ts",
    "content": "export default {\n  labelH1Title: '路印二层,\\n 第一个去中心化 \\n交易平台 ',\n  labelH1TitleDetail: 'Fast, Secure, and 100x Lower Fees',\n  labelH1TitleWallet: 'Loopring Wallet',\n  labelH2TitleWallet: 'FREEDOM AT YOUR FINGERTIPS',\n  labelProtocol: 'loopring offers',\n  labelStartTrade: 'start trading',\n  labelTitleDEX: 'Loopring Dex',\n  labelTradeVolume: '交易 \\n 量',\n  labelTradeUser: '注册 \\n 用户',\n  labelTradeTVL: '流动性',\n  labelTradeNofTrades: '成交 \\n 量',\n  labelZeroKpt: '零知识证明技术',\n  labelLoopringWallet: 'LOOPRING WALLET',\n  labelBtnLearnMore: 'LEARN MORE',\n  labelSafety: 'Ultimate Security',\n  labelLowCost: 'Low Transaction Fees',\n  labelFastTransfer: 'High Throughput',\n  labelSuperpowers: 'Ready for Developers',\n  describeSafety: 'Assets on Loopring L2 are equally secure as they are on the Ethereum mainnet.',\n  describeLowCost:\n    'Transaction fees are reduced to 1/30 - 1/100 of the fees on the Ethereum mainnet.',\n  describeFastTransfer:\n    'Loopring L2 can settle ~2000 transactions per second with near instant finality.',\n  describeSuperpowers:\n    \"Build scalable payment apps, non-custodial exchanges, and NFT marketplaces on Ethereum with Loopring's time-tested zkRollup technology.   Get started with quick-start guides, protocol documentation, a Javascript SDK, and a fully open source codebase.\",\n  labelBtnStart: 'LAUNCH LOOPRING L2 APP',\n  labelBtnDeveloper: 'Developer Documentation',\n  labelFirstWallet: 'BETTER THAN BEING SMART',\n  labelFirstWalletDetail:\n    'Smart wallets enable limitless extensibility over EOA wallets, but Loopring Wallet takes one step further with native zkRollup layer 2 integration.   Now you can transact directly on Loopring L2, faster and cheaper.',\n  labelWalletSecureH1: 'SECURE, at its core',\n  labelWalletSecureH2: 'With social-recovery and guardians',\n  labelWalletSecureDetail:\n    'Completely self-custodial, only you control your assets. You can choose people, institutions, and hardware that you trust to be the guardians of your wallet.  You can also set quota for daily transfers, and lock it down if ever needed.',\n  labelWalletIdentityH1: 'OWN YOUR IDENTITY',\n  labelWalletIdentityH2: 'Your wallet is your continuous Web3 identity.',\n  labelWalletIdentityDetail:\n    'The Loopring Wallet decouples identity and security. You can choose your wallet name and address, and maintain this identity forever with renewable transaction signing keys.',\n  labelWalletUsageH1: 'EASY TO USE',\n  labelWalletUsageH2: 'with zkRollup scaling solution',\n  labelWalletUsageDetail:\n    \"The Loopring Wallet integrates Loopring's Layer 2 zkRollup technology to greatly increase speeds and lower fees, while inheriting the same security guarantees as the Ethereum mainnet.\",\n  labelWalletFutureH1: 'FORWARD LOOKING',\n  labelWalletFutureH2: 'Easily upgradable to adapt future scenarios',\n  labelWalletFutureDetail:\n    'Based on smart contracts, the Loopring Wallet adopts a pluggable, modular design which can be continuously upgraded under your authorization to use future standards and new technologies.',\n  labelWalletUnleashed: 'ETHEREUM UNLEASHED',\n  labelWalletUnleashedDetail: 'Your mobile gateway to Ethereum DeFi, collectibles, and more.',\n  labelLaunchApp: 'View Dapps',\n  labelLaunchMobileApp: 'Exchange',\n  labelUpgradeHide:\n    'Loopring System Service Upgrade: Loopring will perform a temporary system upgrade starting at 2021/12/20 2:00pm (UTC+8), which will take approximately 2 hours.',\n  labelUpgradeShow:\n    'Loopring System Service Upgrade: Loopring will perform a temporary system upgrade starting at 2021/12/20 2:00pm (UTC+8), which will take approximately 2 hours.   During this period, the following relayer services will be suspended: deposits, withdrawals, trading and wallet creation. Deposits that are not completed before the start of the upgrade   will be processed after the completion of the upgrade.   We apologize for any inconvenience this may cause, and thank you for your patience! Please note: The 2 hours is our best estimation and may vary. As usual, we will maintain regular communication on the progress of the upgrade on our Twitter and Discord.',\n  labelGoGuardian: 'Manage Security',\n  labelHaveWallet: 'Already have a wallet?',\n  labelMainDes:\n    'Unleash the Power of DeFi and Advanced Trading on \\n Top of an App-Specific ZK-Rollup',\n  labelEthereum: 'Ethereum ',\n  labelGoDapps: 'Go Dapps',\n  labelNavPro: 'Loopring pro',\n  labelNavEarn: 'Loopring DeFi',\n  labelNavWallet: 'Wallet',\n  labelNavLanuch: 'View Dapps',\n  labelLoopringSmartWallet: 'Loopring Smart Wallet',\n  labelLoopringSmartWalletDes:\n    \"Ethereum's most secure wallet, fully integrated with advanced trading functionality and innovative Earn products, unlocking the true potential of Layer 2.\",\n  labelEthereumUnleashed: \"<0>Ethereum's First zkRollup </0><1>Layer 2</1>\",\n  labelGatewayToEthereum:\n    'Your gateway to Ethereum, DeFi, NFTs, and Financial Freedom.\\n Fast, Low-cost, & Secure',\n  labelTitleLite: 'Loopring DeFi',\n  labelLoopringProtocol: 'Loopring Protocol',\n  labelLoopringProtocolDes:\n    \"The world's first ZKRollup implementation designed to scale Ethereum, fully optimized for trading.\",\n  labelUltimateSecurity: 'Ultimate Security',\n  labelUltimateSecurityDes:\n    'Assets on Loopring L2 are equally secure as they are on the Ethereum mainnet.',\n  labelLowTransactionFees: 'Low Transaction Fees',\n  labelLowTransactionFeesDes:\n    'Loopring performs most operations, including trade and transfer settlement, off the Ethereum blockchain. This dramatically reduces gas consumption and overall transaction cost to small fractions of comparable on-chain cost.',\n  labelHighThroughput: 'High Throughput',\n  labelHighThroughputDes:\n    'Loopring L2 can settle ~2000 transactions per second with near instant finality.',\n  labelReadyForDevelopers: 'Ready for Developers',\n  labelReadyForDevelopersDes:\n    \"Build scalable payment apps, non-custodial exchanges, and NFT marketplaces on Ethereum with Loopring's battle-tested zkRollup technology. Get started with quick-start guides, protocol documentation, a Javascript SDK, and a fully open source codebase.\",\n  labelFeatureDes8: 'Loopring Layer2',\n  labelFeatureDes8_2: 'Crypto exchange on the go',\n  labelGo: 'Go',\n  labelTitleLiteDes: 'Revolutionizing Decentralized Finance with Cutting-Edge Earning and Trading Solutions.',\n  labelInvestStakeLRCDes:\n    'Lock your LRC for a minimum duration to earn interest and redeem at any time.',\n  labelInvestDualDes: 'Buy the dip or sell the covered gain while earning a high yield.',\n  labelInvestLeverageETHDes:\n    \"Boost your earnings with CIAN protocol's leveraged ETH staking strategy.\",\n  labelInvestDefiDes: 'Earn steady income while holding! Stake ETH to accumulate daily rewards.',\n  labelInvestAmmDes:\n    'Participate in farming pools, earn additional protocol fee incentives for HOT pools.',\n  labelProductsTitleDes: 'A wide variety of trading tools to choose from',\n  labelProductsTitle: 'Trading Products',\n  labelSpotDes: 'Full access to all trading tools',\n  labelSpot: 'Spot',\n  labelSwapDes: 'Intuitive trading interface',\n  labelSwap: 'Swap',\n  labelBlockTradeDes: 'Trade via CEX liquidity',\n  labelBlockTrade: 'Block Trade',\n  labelFiatDes: 'On & Off Ramp Solutions',\n  labelFiat: 'Fiat',\n  labelNFTCollections: 'Manage and Display Your NFT Collections',\n  labelNFTCollectionsDes:\n    'Collaborate on a strategic plan to integrate \\n NFTs into your ecosystem',\n  labelRedPackets: 'Red Packets',\n  labelRedPacketsDes:\n    'Explore the various use cases of our revolutionary Red Packets! Send token or NFT gifts directly or gamify the experience with blind boxes.',\n  labelEndProductTitle: 'Earn Products',\n  labelEndProductTitleDes: 'Choose from a variety of financial products',\n  labelSupportedNetworkDes: 'Supported networks: Ethereum & Taiko',\n  labelLaunch: 'Launch',\n  labelLeadingOnChainStructuredProduct: 'Leading On-Chain Structured Product',\n  labelLeadingOnChainStructuredProductDes: 'Buy the dip or sell at a higher price—all while earning high yields.',\n  labelTradeWithCEXLiquidity: 'Trade with CEX Liquidity',\n  labelTradeWithCEXLiquidityDes: 'Effortlessly trade tokens with near-zero slippage, leveraging a unified liquidity pool that combines both CEX and DEX liquidity to generate the best execution price.',\n  labelUnlockThePowerOfLeveragedTrading: 'Unlock the Power of Leveraged Trading',\n  labelUnlockThePowerOfLeveragedTradingDes: 'Seamlessly borrow tokens against your collateral, paving the way for leveraged trading opportunities. By bridging decentralized and centralized exchanges, Loopring Portal broadens your trading horizon, granting access to tokens beyond the Ethereum network.',\n  labelEthereumOnly: 'Ethereum-Only',\n  labelLoopringLayer2: 'Loopring Layer 2',\n  labelLoopringLayer2Des: 'Unleash the Power of DeFi and Advanced \\n Trading on Top of an App-Specific ZK-Rollup',\n  labelTrade: 'Trade',\n  labelTradeDes: 'A wide variety of trading methods to choose from',\n  labelEarn: 'Earn',\n  labelEarnDes: 'Choose from a variety of financial products',\n  labelNFT: 'NFTs',\n  labelNFTDes: 'Manage and display your NFT collections',\n  labelRedPackets2: 'Red Packets',\n  labelRedPacketsDes2:\n    'Explore the possibilities with our revolutionary Red Packets',  \n  labelLoopringSmartWalletDes2: 'Trade on the go - anytime, anywhere',\n  labelExplore: 'Explore',\n  labelLoopringProtocolDes2: 'The world\\'s first ZKRollup implementation designed to scale Ethereum fully optimized for trading',\n  labelProvenAppSpecificZKRollup: 'Proven App-Specific ZK-Rollup',\n  labelProvenAppSpecificZKRollupDes: `Leverage the world's first ZK-Rollup implementation to unlock the full potential of DeFi and advanced trading`,\n  labelAuditedAndSecure: 'Bulletproof Security',\n  labelAuditedAndSecureDes: 'Assets on the Loopring Protocol are just as secure as they are on the underlying networks where the protocol is deployed',\n  labelBringingCEXToDeFi: 'Bringing CeFi to DeFi',\n  labelBringingCEXToDeFiDes: 'Seamlessly bring CeFi use cases into the DeFi world in a truly trustless manner',\n  labelReadyForDevelopersDes2: `Build scalable payment apps, non-custodial exchanges, and NFT marketplaces on Ethereum with Loopring's battle-tested ZK-rollup technology. Get started with quick-start guides, protocol documentation, a Javascript SDK, and a fully open source codebase.`,\n}\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/i18n/zh_CN/layout.ts",
    "content": "export default {\n  labelMarkets: '市场',\n  labelTrade: '交易',\n  labelLiquidity: '流动性矿池',\n  labelMining: '挖矿',\n  labelLayer2: '二层账号',\n  labelWallet: '钱包',\n  labelZkRollupLayer2: 'zkRollup Layer 2',\n  labelSmartWallet: 'Smart Wallet',\n  loopringDomain: '路印二层应用',\n  labelClassic: '简洁版',\n  labelClassicDescription: '快捷交易平台',\n  labelAdvanced: '专业版',\n  labelAdvancedDescription: '提供更丰富的交易模式',\n  labelDownloadApp: '下载手机客户端',\n  labelDownloadAppTitle: '下载钱包',\n  labelDownloadBtn: '转去路印官网',\n  labelNotification: '消息提醒',\n  themeSetting: '主题模版',\n  languageSetting: '语言设置',\n  labelConnectWallet: '连接钱包',\n  notificationApprove: '验证中',\n  notificationPending: '进行中',\n  labelMyTrades: '交易历史',\n  labelRecentTrades: '最近交易',\n  // layer2 submenu\n  labelAssets: '资产信息',\n  labelTransactions: '充值提现',\n  labelTrades: '交易记录',\n  labelHistory: '交易历史',\n  labelOrder: '订单记录',\n  labelReward: '',\n  labelRedPacket: '红包',\n  labelAmmRecords: 'AMM记录',\n  labelAmmRecordsDes: '(出金和入金)',\n  rewards: '推荐奖励',\n  labelOrders: '订单记录',\n  selectLanguage: '语言设置',\n  labelPools: '流动性挖矿池',\n  labelAmmMining: '交易大赛',\n  labelMyLiquidity: '我的流动性',\n  labelOrderBookMining: '订单本挖矿排名',\n  labelMakerRebates: '做市收益',\n  labelSetting: '高级设置',\n  labelSecurity: '安全设置',\n  labelVipPanel: 'VIP',\n  labelContactsPanel: '联系人',\n  titleLoopring: '路印协议',\n  labelLoopringDescribe: '零知卷叠交易与支付协议',\n  labelWrongNetwork: '未识别网络',\n  labelYoutube: '油管',\n  labelWeibo: '微博',\n  labelFooterLoopring: 'Loopring',\n  // Footer\n  labelFooterAbout: 'About',\n  labelkeyOrg: 'Loopring.org',\n  labelkeyTerms: 'Terms of Service',\n  labelkeyPrivacy: 'Privacy Policy',\n  labelkeyNews: 'Blog',\n  labelkeyRisks: 'Risk Disclosure',\n  labelFooterPlatform: 'Platform',\n  labelkeyFees: 'Fees',\n  labelkeyVIP: 'VIP Program',\n  labelkeyReferrals: 'Referrals',\n  labelkeyTokenListing: 'List a Token',\n  labelkeyCreatorGrants: 'Creator Grants',\n  labelkeyL2Explorer: 'Layer 2 Explorer',\n  labelkeySubgraph: 'Subgraph',\n  labelkeyBugBounty: 'Bug Bounty',\n  labelFooterSupport: 'Support',\n  labelkeyFeedback: '❤️ Submit a Request',\n  labelkeyGuardian: 'Wallet Guardian',\n  labelkeyLoopringTutorial: 'Loopring Tutorial',\n  labelkeyCommunityDocs: 'Community Docs',\n  labelkeySupportCenter: 'Support Center',\n  labelFooterDevelopers: 'Developers',\n  labelkeySmartContract: 'Smart Contracts',\n  labelkeyLoopringApp: 'Loopring App',\n  labelkeyLoopringSmartWallet: 'Loopring Smart Wallet',\n  labelkeyAPIs: 'APIs',\n  labelkeyReportIssue: 'Report Issue',\n  labelMyNFT: 'My NFTs',\n  labelLaunchApp: 'View Dapps',\n  labelLaunchMobileApp: 'Exchange',\n  labelLandingHeaderLayer2: 'zkRollup Layer 2',\n  labelLandingHeaderWallet: 'Smart Wallet',\n  labelCopyRight: '© 2017 Loopring Technology Limited. All rights reserved.',\n  labelWalletProtect: 'Guardian',\n  labelWalletValidation: 'Approval Requests',\n  labelWalletHistory: 'History',\n  labelNFT: 'L2 NFT',\n  labelMyAssetsNFT: 'My NFTs',\n  labelMyAssetsNFTDes: 'Receive/Send NFTs',\n  labelInvest: 'Earn',\n  labelMintNFT: 'Create NFT',\n  labelMintNFTDes: 'Create your own NFTs',\n  labelTransactionNFT: 'NFT Transactions',\n  labelTransactionNFTDes: 'NFT Transactions History',\n  labelForceWithdraw: 'Force Withdraw',\n  labelInvestBalance: 'My Investments',\n  labelInvestBalanceDes: 'The deposition you hold',\n  labelInvestAmm: 'AMM Pools',\n  labelInvestOverview: 'Overview',\n  labelInvestOverviewDes: 'Select DeFi Investment',\n  labelInvestAmmDes: 'Add liquidity and earn fees',\n  labelInvestDefi: 'ETH Staking',\n  labelInvestDefiDes: 'Earn ETH staking rewards',\n  labelInvestWSTETH: 'Via Lido',\n  labelInvestWSTETHDes: 'Stake ETH get WSTETH',\n  labelInvestRETH: 'Via Rocket Pool',\n  labelInvestRETHDes: 'Stake ETH get RETH',\n  labelInvestDual: 'Dual Investment',\n  labelInvestDualDes: 'Buy the Dips, Sell the Rallies',\n  labelDepositNFT: 'Receive NFT',\n  labelMyCollection: 'My Collections',\n  labelMyCollectionDes: 'Create, curate, and \\n manage my NFT collections',\n  labelInvestStakeLRC: 'LRC Staking',\n  labelInvestStakeLRCDes: 'Earn LRC staking rewards',\n  labelBtradeTrade: 'Block Trade',\n  labelBtradeTradeDescription: 'Trade via CEX liquidity',\n  labelStopLimit: 'Stop-Limit',\n  labelStopLimitDescription: 'Control trading, like a pro',\n  labelCopyRightBeta:\n    'This site is not released yet and could contain bugs. Please use it with caution!',\n  labelReferralReward: 'Referrals Reward',\n  // labelDepositNFTDes:\"Receive NFT\"\n  labelInvestLeverageETH: 'Leveraged ETH Staking',\n  labelInvestLeverageETHDes: 'Gain higher APY aggressively',\n  labelDualInvest: 'Dual Investment',\n  labelVault: 'Portal',\n  labelNavPro: 'Loopring Layer 2',\n  labelNavEarn: 'Loopring DeFi',\n  labelNavWallet: 'Wallet',\n\n  labelDashBoard: 'Dashboard',\n  labelRecord: 'Records',\n  labelHome: 'Loopring Layer 2',\n  labelVaultDes: '',\n  labelVaultHome: 'Home',\n  labelVaultHomeDes: 'Browse tradable tokens',\n  labelVaultDashboard: 'Dashboard',\n  labelVaultDashboardDes: 'Manage assets and positions',\n  labelVault2: 'Portfolio',\n  labelUnlockFirst: 'Unlock First',\n  labelVault2: 'Assets',\n  labelTaikoFarming: 'Taiko Farming',\n}\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/i18n/zh_CN/tables.ts",
    "content": "export default {\n  labelStatus: '状态',\n  labelAMM: 'AMM',\n  labelSend: 'Send',\n  labelSendL2: 'Send L2',\n  labelSendL1: 'Send L1',\n  labelL2toL1Action: 'Withdraw',\n  labelReceive: 'Receive',\n  labelTransfer: 'Transfer',\n  labelWithdraw: 'Withdraw',\n  labelWithdrawAction: 'Withdraw',\n  labelDeposit: 'Deposit',\n  labelTrade: '交易',\n  labelToken: '币种',\n  labelAmount: '总量',\n  labelAvailable: '可用额度',\n  labelLocked: '冻结',\n  labelAssetsTableValue: '金额',\n  labelActions: '操作',\n  labelAllToken: '所有币种',\n  labelHideSmallBalances: '隐藏小额资产',\n  labelHideInvestToken: '隐藏流动性凭证',\n  labelOrderFilterAllTypes: '所有类型',\n  labelOrderFilterBuy: '买入',\n  labelOrderFilterSell: '卖出',\n  labelFilterReset: '重置',\n  labelFilterSearch: '搜索',\n  labelOrderSide: '卖/买',\n  labelOrderAmount: '订单总量',\n  labelOrderAverage: '均值',\n  labelOrderPrice: '挂单价格',\n  labelOrderFilledAmount: '成交部分',\n  labelOrderFilledPrice: '成交价格',\n  labelOrderFilterAllPairs: '所有交易对',\n  labelOrderFee: '手续费',\n  labelOrderRole: '订单类型',\n  labelOrderTime: '挂单时间',\n  labelOrderStatus: '状态',\n  labelOrderTradingPrice: '交易价格',\n  labelOrderTotal: '全部数量',\n  labelQuotaPair: '交易对',\n  labelQuotaLastPrice: '最新价',\n  labelQuota24hChange: '24h 涨跌',\n  labelQuota24hChangeLit: '24h Chg',\n  labelQuota24hHigh: '24h 最高',\n  labelQuota24hLow: '24h 最低',\n  labelQuoteAction: '操作',\n  labelQuota24hAmount: '24h 交易量',\n  labelTradeFilterAllTypes: '所有类型',\n  labelTradeFilterBuy: '买入',\n  labelTradeFilterSell: '卖出',\n  labelTradeSide: '兑换',\n  labelTradeAmount: '交易总额',\n  labelTradePrice: '价格',\n  labelTradeFee: '费用',\n  labelTradeTime: '交易时间',\n  labelTradeRole: '交易类型',\n  labelTradeRoleMaker: '挂单',\n  labelTradeRoleTaker: '吃单',\n  labelTradeConterparty: '交易对手方',\n  labelTradeCounterpartyOrderbook: '订单本',\n  labelTradeCounterpartyPool: '流动性矿池',\n  labelTxFilterAllTypes: '所有类型',\n  labelTxFilterReceive: 'Receive',\n  labelTxFilterSendL1: 'Send L1',\n  labelTxFilterSendL2: 'Send L2',\n  labelTxFilterDeposit: 'Deposit',\n  labelTxFilterWithdraw: 'Withdrawal',\n  labelTxFilterTransfer: 'Transfer',\n  labelTxFilterAllTokens: 'All Tokens',\n  labelTxSide: '交易类型',\n  labelTxToken: '币种',\n  labelTxFrom: '起始',\n  labelTxTo: '完结',\n  labelTxAmount: '总额',\n  labelTxFee: '费用',\n  labelTxMemo: '备注',\n  labelTxTime: '时间',\n  labelTxTxnHash: '交易哈希',\n  labelTxStatus: '状态',\n  labelTransactions: 'Transactions',\n  labelVolume: '交易量',\n  labelTradePair: '交易对',\n  labelPool: '资金池',\n  labelLiquidity: '流动性',\n  labelMyLiquidity: '我的流动性',\n  label24TradeVolume: '24h 交易量',\n  label24Reward: '24h 奖励',\n  labelAPR: 'APR',\n  labelTradePool: '入金',\n  labelAction: '操作',\n  labelFilter: '搜索',\n  labelFilterAllPairs: '所有交易对',\n  valueAddTOAMM: `添加 <1></1> 和 <3></3>`,\n  valueSwapForAMM: `<1></1> 和 <3></3> 兑换`,\n  valueRemoveTOAMM: `移出 <1></1> 和 <3></3>`,\n  labelAmmTotalValue: '价值总和',\n  labelAmmTokenAmount: '代币数量',\n  labelAmmTime: '时间',\n  labelFeeEarned: '赚取费用',\n  labelBuy: '买',\n  labelSell: '卖',\n  labelAmmSide: '入金/出金',\n  labelAmmAmount: '交易总额',\n  labelAmmLpTokenAmount: '流动性资产变化',\n  labelAmmFee: '费用',\n  labelAmmRecordTime: '交易时间',\n  labelAmmExit: '出金',\n  labelAmmJoin: '入金',\n  labelAmmFilterTypes: '所有类型',\n  labelAmmFilterJoin: '入金',\n  labelAmmFilterExit: '出金',\n  labelPoolTableAddLiquidity: '入金',\n  labelPoolTableRemoveLiquidity: '出金',\n  labelEmptyDefault: '记录是空的',\n  labelAmmTableType: '交易类型',\n  labelOrderDetailTaker: '吃单',\n  labelOrderDetailMaker: '挂单',\n  labelOrderDetailTradingVolume: '交易量',\n  labelOrderDetailOrderId: '订单号',\n  labelOrderCancelAll: '撤销所有订单',\n  labelOrderCancelOrder: '撤销订单',\n  labelOrderProcessing: '挂单中',\n  labelOrderProcessed: '完全成交',\n  labelOrderCancelling: '取消中',\n  labelOrderCancelled: '已取消',\n  labelOrderExpired: '已过期',\n  labelOrderWaiting: '等待队列中',\n  // labelOrderAmm: 'AMM',\n  labelOrderLimitOrder: '限价单',\n  labelOrderMarketOrder: '市价单',\n  // labelOrderMaker: '挂单',\n  labelOrderTaker: '吃单',\n  labelOrderChannelsMixed: '混合订单',\n  // labelOrderChannelsAMM: 'AMM 订单',\n  labelOrderChannelsSwap: '闪兑',\n  labelOrderChannelsOrderBook: '订单本',\n  labelOrderTypes: '订单类型',\n  labelOrderChannels: '订单渠道',\n  labelOrderCompletion: '成交比例',\n  labelRewardTableAmount: '奖励数量',\n  labelRewardTableTime: '时间',\n  labelOrderCancelConfirm: '确认撤销该订单？',\n  labelOrderConfirm: '确定',\n  labelOrderCancel: '取消',\n  labelTradeProPrice: '价格({{symbol}})',\n  labelTradeProAmount: '总量',\n  labelVipTableLevel: 'Level',\n  labelVipTable30dTradeVolume: '30d Volume',\n  labelVipTableRule: 'and / or',\n  labelVipTableBalance: 'LRC Balance',\n  labelVipTableMaker: 'Maker',\n  labelVipTableTaker: 'Taker',\n  labelTradeRaceRank: 'Rank',\n  labelTradeRaceAddress: 'Address',\n  labelTradeRaceTradeVolume: 'Trade Volume',\n  labelTradeRaceAward: 'Award',\n  labelTradeRaceProject: 'Project',\n  labelTradeRacePair: 'Pair',\n  labelTradeRaceToken: 'Token',\n  labelTradeRaceReward: 'Reward',\n  labelMaker: 'Maker',\n  labelTaker: 'Taker',\n  labelNFTTypeDEPOSIT: 'Deposit',\n  labelNFTTypeTRANSFER: 'Transfer',\n  labelNFTTypeWITHDRAWAL: 'Withdraw',\n  labelNFTTypeWITHDRAW: 'Withdraw',\n  labelNFTTypeWITHDRAW_LUCKY_TOKEN: 'Claim Red Packet',\n  labelNFTTypeSEND_BACK_LUCKY_TOKEN: 'Back From Red Packet',\n  labelNFTTypeSEND_LUCKY_TOKEN: 'Send Red Packet',\n  labelMint: 'Mint',\n  labelNFTTypeMINT: 'Mint',\n  labelTxNFTFilterALL: 'All Types',\n  labelTxNFTFilterDEPOSIT: 'Deposit',\n  labelTxNFTFilterWITHDRAW: 'Withdraw',\n  labelTxNFTFilterWITHDRAWAL: 'Withdraw',\n  labelTxNFTFilterRECEIVE: 'Receive',\n  labelTxNFTFilterSEND: 'Send',\n  labelTxNFTFilterFORCEWITHDRAW: 'Force Withdraw',\n  labelTxNFTFilterTRANSFER: 'Transfer',\n  labelTxFilterALL: 'All Types',\n  labelTxFilterRECEIVE: 'Receive',\n  labelTxFilterSEND: 'Send',\n  labelTxFilterFORCEWITHDRAW: 'Force Withdraw',\n  labelTxFilterDEPOSIT: 'Deposit',\n  labelTxFilterWITHDRAW: 'Withdraw',\n  labelTxFilterWITHDRAWAL: 'Withdraw',\n  labelTxFilterTRANSFER: 'Transfer',\n  labelTypeDEPOSIT: 'Receive',\n  labelTypeWITHDRAW: 'Send',\n  labelTypeSEND: 'Send',\n  labelTypeReceive: 'Receive',\n  labelTypeONCHAIN_WITHDRAWAL: 'Send',\n  labelTypeOFFCHAIN_WITHDRAWAL: 'Send',\n  labelTypeTRANSFER: 'Send',\n  labelTypeWITHDRAW_LUCKY_TOKEN: 'Claim Red Packet',\n  labelTypeSEND_BACK_LUCKY_TOKEN: 'Back From Red Packet',\n  labelTypeSEND_LUCKY_TOKEN: 'Send Red Packet',\n  labelTypeDUAL_INVESTMENT: 'Dual Investment Settled',\n  labelTypeL2_STAKING: 'Claim Earnings',\n  labelTxNFTFilterMINT: 'Mint',\n  labelShowFilter: 'Show Filter',\n  labelTypeDELEGATED_FORCE_WITHDRAW: 'Force Withdraw',\n  labelForceWithdrawTotalDes: 'All {{symbol}}',\n  labelForceWithdrawDes: '{{address}} (Address that the token is withdrawn from L2 to L1)',\n  labelDefiInvest: 'Subscribe',\n  labelDefiRedeem: 'Redeem',\n  labelSelect: 'Select',\n  labelDuration: 'Duration',\n\n  labelInvestAll: 'Both',\n  labelDefiExit: 'Redeem',\n  labelDefiJoin: 'Subscribe',\n  labelDefiType: 'Subscribe/Redeem',\n  labelDefiFee: 'Fee',\n  labelDefiTime: 'Time',\n  labelDefiAmount: 'Amount',\n  labelFilterTradeNFTAll: 'All',\n  labelFilterTradeNFTSell: 'Sell',\n  labelFilterTradeNFTSelf: 'Self Trade',\n  labelFilterTradeNFTBuy: 'Buy',\n  labelTradeNFTSide: 'Trade',\n  labelFrom: 'from',\n  labelTo: 'to',\n  labelUPrice: 'unit price: ',\n  labelTradeNFTUnitPrice: 'Unit Price',\n  labelDualApy: 'APR',\n  labelDualTerm: 'Term',\n  labelDualPrice: 'Target Price',\n  labelDualTPrice: 'Target',\n  labelDualSettlement: 'Settlement Date',\n  labelDualAction: 'Action',\n  labelInvestmentStatusSettled: 'Settled',\n  labelInvestmentStatusDelivering: 'Delivering',\n  labelInvestmentStatusSubscribe: 'Earning',\n  labelDualAssetProduct: 'Product',\n  labelDualAssetFrozen: 'Invest',\n  labelDualAssetPrice: 'Target Price',\n  labelDualAssetSettlement_Date: 'Settlement Date',\n  labelDualAssetAPR: 'APR',\n  labelDualAssetAction: 'Actions',\n  labelDualAssetDetail: 'Details',\n  labelDualAssetRefresh: 'Refresh',\n  labelDualTxsSide: 'Type',\n  labelDualTxsProduct: 'Product',\n  labelDualTxAPR: 'APR',\n  labelDualTxsTargetPrice: 'Target Price',\n  labelDualTxsSettlement_Date: 'Settlement Date',\n  labelDualTxsSettlementPrice: 'Settlement Price',\n  labelDualTxsSettlement: 'Settlement',\n  labelDualTxsTime: 'Time',\n  labelDualAssetReturn: 'Return',\n  labelAprPool: 'Amm Pool APR:',\n  labelAprFee: 'Protocol APR:',\n  labelAprEvent: 'Activity APR:',\n  label24Rewards: '24h Rewards',\n  labelRewardFee: 'AMM Rewards:',\n  labelRewardReward: 'Other Rewards:',\n  labelRewardExtra: 'Campaign Rewards:',\n\n  labelRecordToken: 'Token',\n  labelRecordAmount: 'Amount',\n  labelRecordType: 'Type',\n  labelRecordStatus: 'Status',\n  labelRecordNumber: 'Number',\n  labelRecordTime: 'Time',\n  labelReceiveTime: 'Receive Time',\n  labelValue: 'Value',\n  labelClaim: 'Claim',\n  labelAddress: 'Address',\n  labelType: 'Type',\n  labelDefiStakingProduct: 'Product',\n  labelDefiStakingFrozen: 'Frozen',\n  labelDefiStakingEarn: 'Cumulative Earnings',\n  labelDefiStakingPreviousEarn: \"Previous Day's Earnings\",\n  labelDefiStakingDuration: 'Holding Time',\n  labelDefiStakingARR: 'APR',\n  labelDefiStakingAction: 'Action',\n  labelDefiStakingTxType: 'Type',\n  labelDefiStakingTxAmount: 'Amount',\n  labelDefiStakingTxProduct: 'Product',\n  labelDefiStakingTxLockedDuration: 'Locked Duration',\n  labelDefiStakingTxHashId: 'HashID',\n  labelDefiStakingTxSubscribeTime: 'Time',\n  labelDefiStakingTxRewardsDate: 'Rewards Date',\n  labelDefiStakingTxTxID: 'TxID',\n  labelDefiStakingTxTime: 'Time',\n  labelDefiStakingDetail: 'Detail',\n  labelDefiStakingRedeem: 'Redeem',\n  labelDays: 'day(s)',\n  labelStakeTransactionTypesubscribe: 'subscribe',\n  labelStakeTransactionTyperedeem: 'redeem',\n  labelStakeTransactionTypeclaim: 'claim',\n  labelDefiStakingAndPreviousEarn: \"Cumulative & Previous Day's Earnings\",\n  labelDefiStakingTxRewardsMobileDate: 'Date',\n\n  labelBlindBoxOpend: 'Opend',\n  labelBlindBoxEndTime: 'End Time',\n  labelBlindBoxCalim: 'Claim',\n  labelBlindBoxExpired: 'Expired',\n  labelBlindBoxClaimed: 'Claimed',\n  labelBlindBoxStartTime: 'Reveal Time: {{time}}',\n  labelBlindBoxExpiredTime: 'Expiration Time: {{time}}',\n  labelRedPacketOpen: 'Open',\n  labelRedPacketSenderAddress: 'Sender Address',\n  // labelRecordAction: \"Action\",\n  labelBtradeSwapType: 'Type',\n  labelBtradeSwapFee: 'Trading Fee',\n  labelBtradeSwapTime: 'Time',\n  labelBtradeSwapPrice: 'Price',\n  labelBtradeSwapSettled: 'Settled',\n  labelBtradeSwapDelivering: 'Delivering',\n  labelBtradeSettled: 'Settled',\n  labelBtradeDelivering: 'Delivering',\n  labelBtradeDeliveringDes:\n    'The Loopring pool is currently unable to swap the full requested amount. The tokens that were successfully swapped will be transferred to your account now. The unswapped tokens will be locked until they can be swapped. \\n We’ll rebalance the pool shortly and swap the remaining portion.',\n  labelBtradeFailed: 'Failed',\n  labelBtradeCancelled: 'Cancelled',\n  labelBtradePending: 'Pending',\n  labelBtradeSwapFailed: 'Filled',\n  labelStopLimitStopPrice: 'Trigger Condition',\n  labelDUAL_CURRENCY: 'Dual',\n  labelDUAL_BASE: 'Dual',\n  labelBTRADE: 'Block Trade',\n  labelL2STAKING: 'LRC Staking',\n  labelSTOP_LIMIT: 'Stop-Limit',\n  labelStopLimitTriggered:\n    'Triggered: The limit order has been submitted to the order book.\\n Time: {{time}}',\n  labelStopLimitWaitingTrigger:\n    'The limit order is not placed until the stop price has been triggered.',\n  labelRevealTime: 'Reveal Time',\n  labelRevealTimeTooltip:\n    'The Reveal time is when the Red Packet ends， and recipients can open it to see if they have received',\n  labelExpiredTime: 'Expired Time',\n  labelExpiredTimeTooltip: 'After expiration, all unclaimed NFTs will be returned to the Sender.',\n  labelRedpacketFromBlindbox: 'From Blind Box',\n  labelRedpacketCantOpen: 'It is not yet time to open, reveal time: {{time}}',\n  labelReferralsTableReferee: 'Referee',\n  labelReferralsTableAmount: 'Rewards',\n  labelReferralsTableTime: 'Time',\n  labelRefundTableAmount: 'Refunds',\n  labelRefundTableTime: 'Time',\n  labelTxNetworkFee: 'Network Fee',\n  labelTxTradingFee: 'Trading Fee',\n  labelTypeUNIFIED_CLAIM: 'Claim Rewards',\n  labelRedPacketClaiming: 'Claiming',\n  labelLoadingMore: 'Loading More...',\n  labelDualAutoReinvest: 'Auto Reinvest',\n  labelDualAssetModify: 'Modify',\n  labelDualAssetReInvestDisable: 'Disabled',\n  labelDualAssetReInvestEnable: 'Enabled',\n  labelDualAuto: 'ReInvest',\n  labelDualFailed: 'Failed',\n  labelDualPending: 'pending',\n  labelDualAutoInvestTip: 'Auto Reinvest Status:{{}}',\n  labelDualRetryStatusSuccess:\n    'Auto reinvested successful. A new order has been generated for you.',\n  labelDualRetryStatusError:\n    'Auto reinvest failed. Cannot find product with Buy Price of {{price}} and Longest Settlement Date of {{day}} days. ',\n  labelDualRetryStatusRetrying: 'Auto reinvesting. Searching for the product...',\n  labelDualAssetReInvestYes: 'ReInvest On',\n  labelDualAssetReInvestNo: 'ReInvest Off',\n  labelDualRetryPending: 'Pending',\n  labelDualRetryTerminated: 'Terminated',\n  labelDualRetryFailed: 'Failed',\n  labelDualRetrySuccess: 'Successful',\n  labelDualRetryStatusTerminated:\n    'Auto Reinvest terminated. You successfully purchased the target token.',\n  labelTypeCHANGE_PWD: 'Reset Loopring L2 Keypair',\n  labelAveragePositionCost: 'Average Position Cost <1></1>',\n  labelAveragePositionCostDes: 'The average holding cost of the last 10 purchases.',\n  labelDefiApr: 'Est.APR <1></1>',\n  labelDefiAprDes:\n    'Apr stands for annual percentage rate, not taking into account the effect of compound interest. The value displayed here indicates the current value, while it keeps changing dynamically. ',\n  labelVaultAssetsTableValue: 'Value',\n  labelVaultborrow: 'Borrow',\n  labelVaultopen: 'Supply Collateral',\n  labelVaultcloseout: 'Settle',\n  labelVaultmargin: 'Margin Call',\n  labelVaultrepay: 'Repay',\n  labelVaulttrade: 'Trade',\n  labelVaultborrowDes: 'Borrow des',\n  labelVaultopenDes: 'Supply Collateral des',\n  labelVaultcloseoutDes: 'Settle des',\n  labelVaultmarginDes: 'Margin Call des',\n  labelVaultrepayDes: 'Repay des',\n  labelVaulttradeDes: 'Trade des',\n  labelVaultTxType: 'Type',\n  labelVaultTxFilled: 'Filled Amount',\n  labelVaultTxStatus: 'Status',\n  labelVaultTxTime: 'Time',\n  labelVaultVAULT_STATUS_EARNING: 'Succeed',\n  labelVaultVAULT_STATUS_RECEIVED: 'Received',\n  labelVaultVAULT_STATUS_PROCESSING: 'Delivering',\n  labelVaultVAULT_STATUS_SUCCEED: 'Success',\n  labelVaultVAULT_STATUS_FAILED: 'Failed',\n  labelVaultVAULT_STATUS_PENDING: 'Pending',\n  labelDetail: 'Detail',\n  labelVaultcloseoutForced: 'Forced Liquidation',\n  labelInvest: 'Invest',\n  labelVaultconvert: 'Dust Collector',\n  labelVaultredeem: 'Redeem Collateral',\n  labelVaultJoinRedeem: 'Redeem Collateral',\n  labelFailed: 'Failed',\n  labelTotalValue: 'Total Value',\n  labelVaultConvert: 'Converted',\n  labelVaultRepayment: 'Payment',\n  labelVaultTime: 'Time',\n  labelVaultDetails: 'Details',\n  labelVaultErrorOccurred: 'An error has occurred. Please try again later.',\n  labelVaultDustCollector: 'Dust Collector',\n  labelDetails: 'Details',\n  labelTAIKO_FARMING: 'Taiko Farming',\n}\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/i18n/zh_CN/webEarn.ts",
    "content": "/* eslint-disable max-len */\nexport default {\n  labelFAQ1Question: 'What is Loopring protocol ?',\n  labelFAQ1Answer:\n    \"As the world's first ZKRollup implementation to scale up Ethereum, Loopring Protocol has run since 2017. There have been more than 210K users and $5.88B trading volume occurred on this protocol. As an app-specific ZKRollup protocol, it has been successfully deployed not only as a Layer 2 on top of Ethereum but also as a Layer 3 on top of other EVM-compatible networks such as Arbitrum.\",\n  labelFAQ2Question: 'What is Dual Investment ?',\n  labelFAQ2AnswerLine1:\n    'Dual Investment is a non-principal protected structured product. Upon purchasing, you can select the underlying asset, investment currency, investment amount, and delivery date. Your return will be denominated in the investment currency or alternate currency, depending on the below conditions.',\n  labelFAQ2AnswerLine2:\n    'There are two types of Dual Investment products: “Buy Low” and “Sell High”.',\n  labelFAQ2AnswerLine3:\n    'Buy Low products gives you a chance to buy your desired crypto (such as LRC) at a lower price in the future with stablecoins (USDC).',\n  labelFAQ2AnswerLine4:\n    'Target Reached: On the Settlement Date, if the Market Price is at or below the Target Price, the target currency (LRC) will be bought;',\n  labelFAQ2AnswerLine5:\n    'Target Not Reached: On the Settlement Date, if the Market Price is above the Target Price, then you will keep your stablecoins; In both scenarios, you will first earn interest in stablecoins. Once the Target Price is reached, your subscription amount and interest income will be used to buy LRC.',\n  labelFAQ2AnswerLine6:\n    'Sell High products gives you a chance to sell your existing crypto (such as LRC) at a higher price in the future (for USDC).',\n  labelFAQ2AnswerLine7:\n    'Target Reached: On the Settlement Date, the Market Price is at or above the Target Price, your LRC will be sold for USDC.',\n  labelFAQ2AnswerLine8:\n    'Target Not Reached: On the Settlement Date, the Market Price is below the Target Price, then you will keep your LRC. In both scenarios, you will first earn interest in your existing currency (LRC). Once the Target Price is reached, your subscription amount and interest income will be sold for USDC.',\n  labelFAQ2AnswerLine9:\n    'Your token for investment is just locked but still in your account as Loopring is a DEX.',\n  labelFAQ2AnswerLine10:\n    '  Each purchased product has a settlement date. We will take an average of the market price in the last 30 minutes before 16:00 (UTC+8) on the delivery date as the settlement price.',\n  labelFAQ2AnswerLine11:\n    'Please make sure that you fully understand the product and the risks before investing.',\n  labelFAQ3Question: 'What is the Dual Investment Sell covered gain ?',\n  labelFAQ3AnswerLine1:\n    'Covered Gain is an investment strategy to sell digital assets at your Target Price and earn interest while waiting.',\n  labelFAQ3AnswerLine2: 'On the Settlement Date, there can be 2 scenarios:',\n  labelFAQ3AnswerLine3: 'Market Price > Target Price',\n  labelFAQ3AnswerLine4: 'Market Price ≤ Target Price',\n  labelFAQ3AnswerLine5: 'Market Price > Target Price',\n  labelFAQ3AnswerLine6:\n    'Your original investment and earned interest will be sold at the target price.',\n  labelFAQ3AnswerLine7:\n    'This order is then closed regardless of whether \"Auto Reinvest\" is enabled or not.',\n  labelFAQ3AnswerLine8: 'Market Price ≤ Target Price',\n  labelFAQ3AnswerLine9: 'Your original investment and earned interest won’t be sold.',\n  labelFAQ3AnswerLine10:\n    'If you enable the “Auto Reinvest” feature, Loopring will automatically subscribe to a suitable dual investment product based on the agreed terms until you either successfully sell crypto at your desired price or disable the feature.',\n  labelFAQ3AnswerLine11: 'Auto Reinvest',\n  labelFAQ3AnswerLine12:\n    'When you enable the “Auto Reinvest” feature, Loopring will automatically reinvest your funds into a new product with the same target price when the previous product expires, continuing until you successfully sell your crypto at your Target Price. If there isn’t an available product within 2 hours after the previous settlement, the order will be automatically closed.',\n  labelFAQ3AnswerLine13: 'Sell Price: the Target Price at which you want to sell your crypto.',\n  labelFAQ3AnswerLine14:\n    \"Longest Settlement Date: your acceptable investment period. If no suitable products are available within this range, “Auto Reinvest” will not subscribe to any products for you, even if it's enabled.\",\n  labelFAQ4Question: 'What is the Dual Investment Buy the dip ?',\n  labelFAQ4AnswerLine1:\n    'Buy The Dip is an investment strategy to buy digital assets at your Target Price and earn interest while waiting.\\n',\n  labelFAQ4AnswerLine2: 'On the Settlement Date, there can be 2 scenarios:',\n  labelFAQ4AnswerLine3: 'Market Price > Target Price',\n  labelFAQ4AnswerLine4: 'Market Price ≤ Target Price',\n  labelFAQ4AnswerLine5: 'Market Price > Target Price',\n  labelFAQ4AnswerLine6:\n    'Your original investment and earned interest won’t be converted. Earned interest is in USDC or USDT.',\n  labelFAQ4AnswerLine7:\n    'If you enable the “Auto Reinvest” feature, Loopring will automatically subscribe to a suitable dual investment product based on the agreed terms until you either successfully buy crypto at your desired price or disable the feature.',\n  labelFAQ4AnswerLine8: 'Market Price ≤ Target Price',\n  labelFAQ4AnswerLine9:\n    'Your original investment and earned interest will be converted at the Target Price.',\n  labelFAQ4AnswerLine10:\n    'This order is then closed regardless of whether \"Auto Reinvest\" is enabled or not.',\n  labelFAQ4AnswerLine11: 'Auto Reinvest',\n  labelFAQ4AnswerLine12:\n    'When you enable the “Auto Reinvest” feature, Loopring will automatically reinvest your funds into a new product with the same target price when the previous product expires, continuing until you successfully buy crypto at your desired price. If there isn’t an available product within 2 hours after the previous settlement, the order will be automatically closed.',\n  labelFAQ4AnswerLine13: 'Buy Price: the Target Price at which you want to buy crypto.',\n  labelFAQ4AnswerLine14:\n    \"Longest Settlement Date: your acceptable investment period. If no suitable products are available within this range, “Auto Reinvest” will not subscribe to any products for you, even if it's enabled.\",\n  labelDualEarnTitle: 'DUAL INVESTMENT',\n  labelDualEarnSubTitle: 'The most innovative structural products brought to the DeFi world',\n  labelDualEarnTag1: 'Buy Low or Sell High',\n  labelDualEarnTag2: 'No Trading Fees',\n  labelDualEarnTag3: 'High Rewards',\n  labelSellHigh: 'Sell Hign',\n  labelBuyLow: 'Buy Low',\n  labelInvestSymbol: 'Invest {{symbol}}',\n  labelInvestSymbolSellHigh: 'Sell {{symbol}} High',\n  labelInvestSymbolBuyLow: 'Buy {{symbol}} Low',\n  labelApy: 'APY',\n  labelCurrentPrice: 'Current Price',\n  labelViewDetails: 'View Details',\n  labelLoopringEarn: 'Loopring DeFi',\n  labelLoopringEarnDes:\n    'Loopring DeFi is built on top of Loopring Protocol to take full advantage of its ZKRollup technology and full-stack DEX capability to provide the most innovative DeFi products to users.',\n  labelLoopringProtocol: 'Loopring Protocol',\n  labelLoopringProtocolDes:\n    \"The world's first ZKRollup implementation designed to scale Ethereum, fully optimized for trading.\",\n  labelUltimateSecurity: 'Ultimate Security',\n  labelUltimateSecurityDes:\n    'Assets on Loopring are equally secure as they are on the Ethereum mainnet.',\n  labelLowTransactionFees: 'Low Transaction Fees',\n  labelLowTransactionFeesDes:\n    'Loopring performs most operations, including trade and transfer settlement, off the Ethereum blockchain. This dramatically reduces gas consumption and overall transaction cost to small fractions of comparable on-chain cost.',\n  labelHighThroughput: 'High Throughput',\n  labelHighThroughputDes:\n    'Loopring can settle ~2000 transactions per second with near instant finality.',\n  labelFAQs: 'FAQs',\n  labelBtradeSwapTitle: 'Block Trade',\n  labelViewMore: 'View more',\n  labelVault: 'Portal',\n  labelInvestDualDes1: 'Experience the Leading On-Chain Structured Product',\n  labelInvestDualDes2: 'Buy the dip or sell at a higher price - all while earning high yields.',\n  labelPortalDes1: 'Unlock the Power of Leveraged Trading',\n  labelPortalDes2: 'Seamlessly borrow tokens against your collateral, paving the way for leveraged trading opportunities. By bridging decentralized and centralized exchanges, Loopring Portal broadens your trading horizon, granting access to tokens beyond the Ethereum network.',\n  labelBtradeDes1: 'Trade with CEX Liquidity',\n  labelBtradeDes2: 'Effortlessly trade tokens with near-zero impact, leveraging multiple liquidity sources across crypto to guarantee the best rates every time.',\n  labelInvestDualTitle: 'Dual Investment',\n  labelLoopringDeFi: 'Loopring DeFi',\n  labelIntroDes1: 'Revolutionizing Decentralized Finance with Cutting-',\n  labelIntroDes2: 'Edge Earning and Trading Solutions',\n  labelIntroDes3: 'Delivering CeFi-like user experiences in a fully trustless environment',\n  labelLearnMore2: 'Learn More',\n  labelReadyForDevelopers: 'Ready for Developers',\n  labelReadyForDevelopersDes:\n    \"Build scalable payment apps, non-custodial exchanges, and NFT marketplaces on Ethereum with Loopring's battle-tested zkRollup technology. Get started with quick-start guides, protocol documentation, a Javascript SDK, and a fully open source codebase.\",\n  labelLaunch: 'Launch',\n}\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/loopring-interface/CoinInterface.ts",
    "content": "import { Account, FloatTag, ForexMap, TradeStatus, TradeTypes, VaultSwapStep } from '../constant'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nimport React from 'react'\n\nexport type CoinKey<R> = keyof R\nexport type PairKey<P> = keyof P\n\nexport interface IBData<R> {\n  belong: CoinKey<R>\n  balance: number\n  tradeValue: number | undefined\n}\n\nexport interface IBDataMax<R> extends IBData<R> {\n  max?: string\n}\n\nexport interface CoinInfo<R> {\n  icon?: string\n  name: string\n  simpleName: CoinKey<R>\n  description?: string\n  company: string\n  belongAlice?: string\n  [key: string]: any\n}\n\nexport interface WalletCoin<R> {\n  belong: CoinKey<R>\n  count: number\n\n  [key: string]: any\n}\n\nexport type CoinMap<R, I = CoinInfo<R>> = {\n  //[k in keyof R]: I;\n  [K in CoinKey<R>]?: I\n  // [k in k extends typeof R]: I;\n}\n\nexport interface FeeInfo {\n  belong: string\n  fee: number | string\n  feeRaw?: string | number\n  token?: string\n  hasToken?: boolean\n  count?: string\n  discount?: number\n  __raw__: {\n    fastWithDraw: string\n    tokenId: number\n    feeRaw: string\n  }\n}\n\nexport enum TokenType {\n  single = 'single',\n  lp = 'lp',\n  defi = 'defi',\n  dual = 'dual',\n  nft = 'nft',\n  vault = 'vault',\n}\n\nexport type PairMap<\n  R extends {\n    [key: string]: any\n  },\n  P = {\n    coinA: CoinInfo<R>\n    coinB: CoinInfo<R>\n  },\n> = {\n  [K in PairKey<R>]?: P\n}\nexport type WalletMap<R, I extends WalletCoin<R> = WalletCoin<R>> = {\n  [K in CoinKey<R>]?: I\n}\n\nexport type TradeCalcData<T> = {\n  coinSell: keyof T //name\n  coinBuy: keyof T\n  buyPrecision: number\n  sellPrecision: number\n  // tokenA: sdk.TokenInfo,\n  // tokenB: sdk.TokenInfo,\n  StoB: string | undefined\n  BtoS: string | undefined\n  // marketPrecision: number,\n  coinInfoMap?: CoinMap<T, CoinInfo<T>>\n  sellCoinInfoMap?: CoinMap<T, CoinInfo<T>>\n  buyCoinInfoMap?: CoinMap<T, CoinInfo<T>>\n  walletMap?: WalletMap<T, WalletCoin<T>>\n  slippage: number | string\n  // slippageTolerance: Array<number | string>,\n  minimumReceived: string | undefined\n  fee: string\n  isReverse: boolean\n  feeTakerRate?: number\n  tradeCost?: string\n  lastStepAt?: 'sell' | 'buy'\n  totalQuota: string\n  minimumConverted: string | undefined\n} & (\n  | {\n      isBtrade: undefined | boolean\n    }\n  | {\n      isVault: undefined | boolean\n    }\n)\n\nexport type SwapTradeCalcData<T> = TradeCalcData<T> & {\n  isNotMatchMarketPrice?: boolean\n  marketPrice?: string\n  marketRatePrice?: string\n  isChecked?: boolean\n  slippage: number | string\n  priceImpact: string\n  priceImpactColor: string\n  feeTakerRate?: number\n  tradeCost?: string\n  isShowBtradeAllow?: boolean\n  minimumConverted: string | undefined\n  sellMaxAmtStr?: string\n  sellMinAmtStr?: string\n} & (\n    | {\n        isBtrade: undefined | boolean\n      }\n    | {\n        isVault: undefined | boolean\n      }\n  )\n\nexport enum BtradeType {\n  Quantity = 'Quantity',\n  Speed = 'Speed',\n}\n\nexport type BtradeTradeCalcData<T> = TradeCalcData<T> & {\n  isBtrade: true\n  maxFeeBips: number\n  lockedNotification: true\n  volumeSell: string | undefined\n  volumeBuy: string | undefined\n  sellMinAmtStr: string | undefined\n  sellMaxL2AmtStr: string | undefined\n  sellMaxAmtStr: string | undefined\n  l1Pool: string\n  l2Pool: string\n  slippage: number | string\n  btradeType: BtradeType\n  // totalPool: string;\n}\n\nexport type VaultTradeCalcData<T> = Omit<BtradeTradeCalcData<T>, 'btradeType' | 'isBtrade'> & {\n  isVault: true\n  belongBuyAlice: string\n  belongSellAlice: string\n  supportBorrowData: VaultBorrowData\n  showHasBorrow: boolean\n  isRequiredBorrow: boolean\n  borrowVol: string\n  borrowStr: string\n  step: VaultSwapStep\n}\n\nexport type TradeCalcProData<T> = {\n  coinBase: keyof T //name\n  coinQuote: keyof T\n  StoB: string\n  BtoS: string\n  coinInfoMap?: CoinMap<T, CoinInfo<T>>\n  walletMap?: WalletMap<T, WalletCoin<T>>\n  slippage: number | string\n  priceImpact: string\n  priceImpactColor: string\n  minimumReceived: string\n  fee: string\n  feeTakerRate?: number\n  tradeCost?: string\n  lastStepAt?: 'base' | 'quote'\n  stopRange?: [string | undefined, string | undefined]\n  isNotMatchMarketPrice?: boolean\n  marketPrice?: string\n  marketRatePrice?: string\n  isChecked?: boolean\n  minimumConverted?: string\n}\n\n/**\n *   @description coinA and coinB balance is different\n *      when is deposit the balance is from wallet balance\n *      when is withdraw the balance is from ammDeposit balance\n *\n */\nexport type AmmJoinData<C extends IBData<I>, I = any> = {\n  coinA: C\n  coinB: C\n  coinLP: C\n  slippage: number | string\n  __cache__?: {\n    [key: string]: any\n  }\n}\n\nexport type AmmExitData<C extends IBData<I>, I = any> = {\n  coinA: C\n  coinB: C\n  coinLP: C\n  slippage: number | string\n  __cache__?: {\n    [key: string]: any\n  }\n}\nexport type DeFiCalcData<T> = {\n  coinSell: T\n  coinBuy: T\n  AtoB: string\n  BtoA: string\n  fee: string\n}\nexport type DeFiSideCalcData<T, R = sdk.STACKING_PRODUCT> = {\n  coinSell: T\n  stakeViewInfo: R & {\n    dalyEarn?: string\n    maxSellAmount?: string\n    minSellAmount?: string\n    maxSellVol?: string\n    minSellVol?: string\n  }\n}\ntype RedeemInfo = sdk.StakeInfoOrigin &\n  Omit<sdk.STACKING_PRODUCT, 'status'> & {\n    status_product: number\n\n    maxSellAmount?: string\n    minSellAmount?: string\n    maxSellVol?: string\n    minSellVol?: string\n    minAmount: string\n    maxAmount: string\n  }\nexport type DeFiSideRedeemCalcData<T, _R = RedeemInfo> = {\n  coinSell: T\n  stakeViewInfo: _R\n}\nexport type DualTrade<R> = IBData<R> & {\n  isRenew: boolean\n  renewTargetPrice?: string\n  renewDuration?: number\n}\n\n// { isRenew?: true; target; maxRecurseProductDuration: number }\nexport type DualCalcData<R, B = DualTrade<any>> = sdk.CalDualResult & {\n  sellToken?: sdk.TokenInfo\n  buyToken?: sdk.TokenInfo\n  coinSell: B\n  dualViewInfo: R\n  balance: {\n    [key: string]: sdk.DualBalance\n  }\n  request?: sdk.DualOrderRequest\n}\n\nexport type AmmInData<T> = {\n  myCoinA: IBData<T>\n  myCoinB: IBData<T>\n  lpCoinA: IBData<T>\n  lpCoinB: IBData<T>\n  lpCoin: IBData<T>\n  AtoB: number\n  BtoA: number\n  coinInfoMap: CoinMap<T, CoinInfo<T>>\n  // walletMap: WalletMap<T, WalletCoin<T>>,\n  // AmmWalletMap: WalletMap<T, WalletCoin<T>>,\n  slippage: number | string\n  // slippageTolerance: Array<number | string>,\n  fee: string\n  fees: any\n  percentage: string\n}\n\nexport type AmmDetailBase<T> = {\n  // name?: string,\n  market: string\n  coinA: CoinKey<T>\n  coinB: CoinKey<T>\n  coinAInfo: CoinInfo<T>\n  coinBInfo: CoinInfo<T>\n  address: string\n  amountU?: string\n  totalLPToken?: number\n  totalA?: number\n  totalB?: number\n  totalAStr?: string\n  totalBStr?: string\n  totalAU?: number\n  totalBU?: number\n  rewardToken?: CoinKey<T>\n  rewardA?: number\n  rewardB?: number\n  rewardAU?: number\n  rewardBU?: number\n  rewardToken2?: CoinKey<T>\n  feeA?: number\n  feeB?: number\n  feeU?: number\n  isNew?: boolean\n  isActivity?: boolean\n  APR?: number\n  APRs?: {\n    self: number\n    event: number\n    fee: number\n  }\n}\n\nexport type AmmDetail<T> = AmmDetailBase<T> & {\n  exitDisable: boolean\n  joinDisable: boolean\n  swapDisable: boolean\n  showDisable: boolean\n  isRiskyMarket: boolean\n  stob: string\n  btos: string\n  tradeFloat: Partial<TradeFloat>\n  __rawConfig__: sdk.AmmPoolInfoV3\n  __ammPoolState__: sdk.AmmPoolStat\n} & sdk.AmmPoolInfoV3\n\nexport type AmmCardProps<T> = AmmDetail<T> & {\n  activity: AmmActivity<T>\n  tradeFloat: TradeFloat\n  handleClick: () => void\n  account: Account\n  forexMap: ForexMap<sdk.Currency>\n  popoverIdx: number\n  precisionA?: number\n  precisionB?: number\n  coinAPriceU: number\n  coinBPriceUr: number\n  getLiquidityMining: (market: string, size?: number) => Promise<void>\n  // getMiningLinkList: (market: string) => { [key: string]: string };\n  setShowRewardDetail: React.Dispatch<React.SetStateAction<boolean>>\n  setChosenCardInfo: React.Dispatch<React.SetStateAction<any>>\n  ammInfo: any\n}\n\nexport type AmmActivity<I> = {\n  market: string\n  status: sdk.AmmPoolActivityStatus\n  ruleType: string\n  totalRewards: number\n  myRewards: number\n  rewardToken: CoinInfo<I>\n  duration: {\n    from: Date\n    to: Date\n  }\n  isPass?: boolean\n  rewardTokenU?: number\n  maxSpread?: number\n}\nexport type Amount<T> = {\n  sell: {\n    belong: T\n    tradeValue: number\n  }\n  buy: {\n    belong: T\n    tradeValue: number\n  }\n}\n\nexport type TradeBasic<T> = {\n  side: keyof typeof TradeTypes\n  amount: Amount<T>\n  time: number // timestamp\n  fee: number\n\n  // actionsStatus: object;\n}\nexport type Trade<T> = TradeBasic<T> & {\n  priceValue: number\n  priceToken: T\n}\n\nexport type AmmTrade<T> = TradeBasic<T> & {\n  priceValue: number\n  priceToken: T\n}\n\nexport type AmmRecord<T> = TradeBasic<T> & {\n  amountLP: Amount<T>\n}\n\nexport type OrderTrade<T> = TradeBasic<T> & {\n  average: number\n  filledAmount: Amount<T>\n  filledPrice: number\n  status: keyof typeof TradeStatus\n}\n\nexport type AmmDetailExtend<ACD, T> = {\n  ammCalcData: ACD\n} & AmmDetail<T>\n\nexport type AmmDetailExtendProps<ACD, T> = AmmDetailExtend<ACD, T> & {\n  tradeFloat: TradeFloat\n  activity?: AmmActivity<any>\n}\nexport type MyAmmLP<T> = {\n  smallBalance?: boolean\n  balanceA: number | undefined\n  balanceB: number | undefined\n  balanceAStr: string | undefined\n  balanceBStr: string | undefined\n  balanceU: number | undefined\n  feeA: number | undefined\n  feeB: number | undefined\n  feeU: number | undefined\n  reward?: number | undefined\n  rewardToken: CoinInfo<T> | undefined\n  reward2?: number | undefined\n  rewardToken2?: CoinInfo<T> | undefined\n  rewardU?: number | undefined\n  totalLpAmount?: number | undefined\n  feeA24: number | undefined\n  feeB24: number | undefined\n  feeU24: number | undefined\n  reward24: number | undefined\n  reward224: number | undefined\n  rewardU24: number | undefined\n  extraU24: number | undefined\n  extraRewards24: {\n    tokenSymbol: string\n    amount: number\n  }[]\n}\n\nexport type TradeFloat = {\n  // value: number,\n  change?: any\n  timeUnit: '24h' | 'all'\n  floatTag: keyof typeof FloatTag\n  reward?: number\n  rewardToken?: string\n  volume?: number\n  volumeView?: string\n  close?: number\n  high?: number\n  low?: number\n  priceU: number\n  changeU?: number\n  closeU?: number\n}\n\nexport enum EXPLORE_TYPE {\n  TRANSFER = 'transfer',\n  DEPOSIT = 'deposit',\n  WITHDRAW = 'withdraw',\n  OFFCHAIN_WITHDRAWAL = 'withdraw',\n  NFTMINT = 'nftMint',\n  NFTWITHDRAW = 'nftWithdraw',\n  NFTTRANSFER = 'nftTransfer',\n  NFTSEND_BACK_LUCKY_TOKEN = 'nftTransfer',\n  NFTSEND_LUCKY_TOKEN = 'nftTransfer',\n  NFTWITHDRAW_LUCKY_TOKEN = 'nftWithdraw',\n}\n\n/**\n * CollectionMeta\n * @property name string useToCreate Collection\n * @property name string\n * @property tileUri string option\n * @property owner? string option\n * @property nftFactory? string option\n * @property baseUri? string option\n * @property collectionTitle? string option\n * @property description? string option\n * @property avatar? string option\n * @property banner? string option\n * @property thumbnail? string option\n * @property cid? string option\n *\n */\nexport type CollectionMeta = sdk.CollectionMeta & {\n  extends: {\n    [key: string]: any\n  }\n}\nexport type CollectionMetaJSON = {\n  contract: string\n  thumbnail_uri: string\n  banner_uri: string\n  avatar_uri: string\n  tile_uri: string\n  name: string\n  description: string\n  [key: string]: any\n}\n\nexport enum CollectionMetaKey {\n  name = 'name',\n  tileUri = 'tileUri',\n  owner = 'owner',\n  nftFactory = 'nftFactory',\n  baseUri = 'baseUri',\n  collectionTitle = 'collectionTitle',\n  description = 'description',\n  avatar = 'avatar',\n  banner = 'banner',\n  thumbnail = 'thumbnail',\n  cid = 'cid',\n}\n\nexport type MakeMeta<Co = CollectionMeta> = (props: { collection: Co; domain: string }) => {\n  metaDemo: any\n}\n\nexport type GET_IPFS_STRING = (url: string | undefined, basicURl: string) => string\n\nexport type RedPacketSend = {\n  type: sdk.LuckyTokenType\n  signerFlag: sdk.LuckyTokenSignerFlag\n  luckyToken: sdk.LuckyTokenInfo\n  numbers: number\n  templateID: number\n  memo: string\n  validSince: number\n} // sdk.LuckyTokenItemForSend;\n\nexport type LuckyRedPacketItem = {\n  labelKey: string\n  desKey: string\n  tags?: string[],\n  value: {\n    value: number\n    partition: sdk.LuckyTokenAmountType\n    mode: sdk.LuckyTokenClaimType\n  }\n}\n\nexport type TickerNew<R = sdk.DatacenterTokenInfoSimple> = R & {\n  timeUnit: '24h'\n  erc20Symbol: string\n  type: TokenType\n  volume: string\n  priceU: string\n  change: string\n  __rawTicker__: R & any\n  rawData: R & any\n}\nexport type TickerNewMap<R> = {\n  [key in keyof R]: TickerNew\n}\n\nexport type Ticker = TradeFloat & {\n  open: number\n  high: number\n  low: number\n  close: number\n  change: number\n  volume: number | string\n  base: string\n  quote: string\n  __rawTicker__: sdk.TickerData\n}\nexport type NetworkItemInfo = {\n  label: string\n  chainId: string\n  RPC?: string\n  link?: string\n  isTest?: boolean | undefined\n  walletType: string\n}\n\nexport const url_path = 'https://static.loopring.io/events'\nexport const url_test_path = 'https://static.loopring.io/events/testEvents'\n\nexport type VaultLoanData<T> = {\n  coinInfoMap: CoinMap<T, CoinInfo<T>>\n  tradeData: T\n} & T\nexport type VaultBorrowData<\n  T = IBData<any> & {\n    erc20Symbol: string\n  },\n> = {\n  borrowedAmt: string\n  borrowedStr: string\n  maxBorrowAmount: string\n  maxBorrowStr: string\n  minBorrowAmount: string\n  minBorrowStr: string\n  maxBorrowVol: string\n  minBorrowVol: string\n  maxQuote: string\n  borrowVol: string\n  borrowAmt: string\n  totalQuote: string\n  borrowAmtStr: string\n  request: sdk.VaultBorrowRequest\n} & VaultLoanData<T>\n\nexport type VaultRepayData<T> = {\n  maxRepayAmount: string\n  maxRepayStr: string\n  minRepayAmount: string\n  minRepayStr: string\n  maxRepayVol: string\n  minRepayVol: string\n  maxQuote: string\n  repayVol: string\n  repayAmt: string\n  repayAmtStr: string\n  request: sdk.VaultRepayRequestV3WithPatch['request']\n} & VaultLoanData<T>\n\nexport type VaultJoinData<I = any, T = IBData<I>> = {\n  walletMap: WalletMap<I>\n  coinMap: CoinMap<I> & { vaultToken: string; vaultId: number }\n  vaultLayer2Map: WalletMap<I>\n  vaultSymbol?: string\n  request?: sdk.VaultJoinRequest\n  maxShowVal: string\n  minShowVal: string\n  maxAmount: string\n  minAmount: string\n  amount: string\n  isMerge: boolean\n  vaultTokenInfo: sdk.TokenInfo\n  tradeData: T\n  // isShouldClean:boolean\n  __request__: sdk.VaultJoinRequest\n} & Partial<IBData<I>> &\n  Partial<sdk.VaultJoinRequest>\n\nexport type VaultExitData<I = any, T = IBData<I>> = {\n  __request__: any\n  tradeData: T\n} & Partial<IBData<I>> &\n  Partial<sdk.VaultExitRequest>\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/loopring-interface/FooterInterface.ts",
    "content": "export type FooterInterface = {\n  linkName: string\n  linkHref: string\n}\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/loopring-interface/HeaderInterface.ts",
    "content": "export enum HeaderMenuTabStatus {\n  hidden = 'hidden',\n  disabled = 'disabled',\n  default = 'default',\n}\n\nexport interface HeaderMenuItemInterface {\n  label: {\n    icon?: any\n    id: string\n    style?: any\n    description?: string\n    i18nKey: string\n  }\n  handleListKeyDown?: (props?: any) => void\n  child?: Array<HeaderMenuItemInterface> | { [key: string]: Array<HeaderMenuItemInterface> }\n  router?: { path: string; [key: string]: any; pathName?: string }\n  status?: keyof typeof HeaderMenuTabStatus\n  extender?: JSX.Element | undefined\n  logo?: {\n    dark: string\n    light: string\n  }\n}\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/loopring-interface/Investment.ts",
    "content": "import { InvestMapType } from '../constant'\n\nexport type InvestAdvice = {\n  type: InvestMapType\n  banner: string\n  titleI18n: string\n  desI18n: string\n  router: string\n  notification: string\n  enable: boolean\n  project?: string\n  market?: string\n}\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/loopring-interface/VendorInterface.ts",
    "content": "import { VendorProviders } from '../constant/vendor'\nimport { TradeBtnStatus } from '../constant'\n\nexport interface VendorItem {\n  key: VendorProviders\n  svgIcon: string\n  flag?: {\n    startDate: number\n    endDate: number\n    tag?: string\n    highLight?: string\n  }\n  btnStatus?: TradeBtnStatus\n  handleSelect?: (event?: React.MouseEvent) => void\n}\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/loopring-interface/WallectInterface.ts",
    "content": "import { ConnectProviders } from '@loopring-web/web3-provider'\n\nexport enum WalletStatus {\n  disabled = 'disabled',\n  loading = 'loading',\n  unlock = 'unlock',\n  connect = 'connect',\n  noAccount = 'noAccount',\n  accountPending = 'accountPending',\n  noNetwork = 'noNetwork',\n  default = 'default',\n}\n\nexport interface GatewayItem {\n  key: keyof typeof ConnectProviders\n  keyi18n: string\n  imgSrc: string\n  handleSelect?: (event?: React.MouseEvent) => void\n}\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/loopring-interface/index.ts",
    "content": "export * from './CoinInterface'\nexport * from './HeaderInterface'\nexport * from './WallectInterface'\nexport * from './VendorInterface'\nexport * from './FooterInterface'\nexport * from './Investment'\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/svg/Icon.tsx",
    "content": "import { SvgIcon, SvgIconProps } from '@mui/material'\n\ntype DepthColor = {\n  bo?: string\n  l?: string\n  a?: string\n  b?: string\n}\n\nexport const DepthHIcon = ({\n  bo = '#49527D',\n  l = '#49527D',\n  a = '#FF5677',\n  b = '#00BBA8',\n  ...props\n}: SvgIconProps & DepthColor) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M20 3H4C3.44772 3 3 3.44772 3 4V20C3 20.5523 3.44772 21 4 21H20C20.5523 21 21 20.5523 21 20V4C21 3.44772 20.5523 3 20 3ZM4 2C2.89543 2 2 2.89543 2 4V20C2 21.1046 2.89543 22 4 22H20C21.1046 22 22 21.1046 22 20V4C22 2.89543 21.1046 2 20 2H4Z'\n        fill={bo}\n      />\n      <rect x='10.0001' y='4.66675' width='9.33333' height='2.66667' fill={l} />\n      <rect x='10.0001' y='8.66675' width='9.33333' height='2.66667' fill={l} />\n      <rect x='10.0001' y='12.6665' width='9.33333' height='2.66667' fill={l} />\n      <rect x='10.0001' y='16.6667' width='9.33333' height='2.66667' fill={l} />\n      <rect x='4.66663' y='4.66675' width='4' height='6.66667' fill={a} />\n      <rect x='4.66663' y='12.6665' width='4' height='6.66667' fill={b} />\n    </SvgIcon>\n  )\n}\n\nexport const DepthFIcon = ({\n  bo = '#49527D',\n  l = '#49527D',\n  a = '#FF5677',\n  b = '#00BBA8',\n  ...props\n}: SvgIconProps & DepthColor) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M20 3H4C3.44772 3 3 3.44772 3 4V20C3 20.5523 3.44772 21 4 21H20C20.5523 21 21 20.5523 21 20V4C21 3.44772 20.5523 3 20 3ZM4 2C2.89543 2 2 2.89543 2 4V20C2 21.1046 2.89543 22 4 22H20C21.1046 22 22 21.1046 22 20V4C22 2.89543 21.1046 2 20 2H4Z'\n        fill={bo}\n      />\n      <rect x='10.0001' y='4.66675' width='9.33333' height='2.66667' fill={l} />\n      <rect x='10.0001' y='8.66675' width='9.33333' height='2.66667' fill={l} />\n      <rect x='10.0001' y='12.6665' width='9.33333' height='2.66667' fill={l} />\n      <rect x='10.0001' y='16.6667' width='9.33333' height='2.66667' fill={l} />\n      <rect x='4.66663' y='4.66675' width='4' height='14.6667' fill={a} />\n    </SvgIcon>\n  )\n}\n\nexport const UpIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path d='M13 7.83L16.59 11.41L18 10L12 4L6 10L7.41 11.41L11 7.83L11 20L13 20L13 7.83Z' />\n    </SvgIcon>\n  )\n}\n\nexport const DragIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path d='M15 1.5H24V4.5H15V1.5Z' />\n      <path d='M15 10.5H24V13.5H15V10.5Z' />\n      <path d='M24 19.5H15V22.5H24V19.5Z' />\n    </SvgIcon>\n  )\n}\nexport const DragListIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path d='M21 18L3 18L3 16L21 16L21 18ZM21 13L3 13L3 11L21 11L21 13ZM21 8L3 8L3 6L21 6L21 8Z' />\n    </SvgIcon>\n  )\n}\n\nexport const ResizeIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path d='M24 24V9L9 24H24Z' />\n    </SvgIcon>\n  )\n}\nexport const AssetsIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path d='M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C21.9939 17.5203 17.5203 21.9939 12 22ZM11 4.062C7.72604 4.47603 5.04227 6.85789 4.24231 10.0595C3.44234 13.2611 4.69036 16.6254 7.38479 18.5307C10.0792 20.436 13.6671 20.4913 16.419 18.67L16.319 18.741L16.413 18.676L16.472 18.635L16.536 18.59L16.552 18.579L16.561 18.572L11.433 13.442C11.1544 13.1585 10.9988 12.7765 11 12.379L11 4.062ZM13.829 13L18.056 17.227L18.063 17.219L18.068 17.213L18.058 17.224C19.0896 16.0335 19.744 14.5633 19.938 13L13.829 13ZM13 4.062L13 11L19.938 11C19.4815 7.37411 16.6259 4.51851 13 4.062Z' />\n    </SvgIcon>\n  )\n}\nexport const L2MyLiquidityIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path d='M5.5 8.49962L7 8.49962L7 10.4996L5.5 10.4996C4.67157 10.4996 4 11.1712 4 11.9996C4 12.8281 4.67157 13.4996 5.5 13.4996L12 13.4996L12 15.4996L5.5 15.4996C3.567 15.4996 2 13.9326 2 11.9996C2 10.0666 3.567 8.49962 5.5 8.49962Z' />\n      <path d='M17 15.4996L18.5 15.4996C20.433 15.4996 22 13.9326 22 11.9996C22 10.0666 20.433 8.49962 18.5 8.49962L12 8.49962L12 10.4996L18.5 10.4996C19.3284 10.4996 20 11.1712 20 11.9996C20 12.8281 19.3284 13.4996 18.5 13.4996L17 13.4996L17 15.4996Z' />\n      <path d='M8.5 18.4995L8.5 16.9995L10.5 16.9995L10.5 18.4995C10.5 19.3279 11.1716 19.9995 12 19.9995C12.8284 19.9995 13.5 19.3279 13.5 18.4995L13.5 11.9995L15.5 11.9995L15.5 18.4995C15.5 20.4325 13.933 21.9995 12 21.9995C10.067 21.9995 8.5 20.4325 8.5 18.4995Z' />\n      <path d='M15.5 6.99951L15.5 5.49951C15.5 3.56651 13.933 1.99951 12 1.99951C10.067 1.99951 8.5 3.56652 8.5 5.49951L8.5 11.9995L10.5 11.9995L10.5 5.49951C10.5 4.67109 11.1716 3.99951 12 3.99951C12.8284 3.99951 13.5 4.67109 13.5 5.49951L13.5 6.99951L15.5 6.99951Z' />\n    </SvgIcon>\n  )\n}\nexport const L2HistoryIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M4.99902 22H18.999C20.1036 22 20.999 21.1046 20.999 20V6C20.999 4.89543 20.1036 4 18.999 4H16.999V2H14.999V4H8.99902V2H6.99902V4H4.99902C3.89445 4 2.99902 4.89543 2.99902 6V20C2.99902 21.1046 3.89445 22 4.99902 22ZM4.99902 20V10H18.999V20H4.99902ZM4.99902 8V6H18.999V8H4.99902ZM8.8521 14.0837L8.8521 14.0837L10.2663 12.6695L11.6805 14.0837L12.529 14.9322L13.6604 13.8008L12.2681 12.4085L16.7374 12.1382L16.4671 16.6075L15.0746 15.215L13.9432 16.3464L12.529 17.7606L11.1148 16.3464L10.2663 15.4979L8.00356 17.7607L6.58936 16.3464L8.8521 14.0837Z'\n      />\n    </SvgIcon>\n  )\n}\nexport const RewardIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M11.0817 1.86863C11.4288 1.06267 12.5715 1.06267 12.9186 1.86863L14.4691 5.46905C14.6139 5.80523 14.9308 6.03545 15.2952 6.06925L19.1985 6.43127C20.0723 6.51231 20.4254 7.59912 19.7662 8.17828L16.8211 10.7655C16.5461 11.0071 16.4251 11.3796 16.5056 11.7366L17.3675 15.5608C17.381 15.6208 17.389 15.6799 17.392 15.7378C17.4128 15.7365 17.4337 15.7359 17.4548 15.7359H20.7034C21.842 15.7359 22.5654 16.9546 22.0202 17.9542L21.4008 19.0899L21.9798 19.7269C22.8558 20.6904 22.1721 22.2359 20.8699 22.2359H18.23C18.0571 22.5348 17.7339 22.7359 17.3638 22.7359H6.63652C6.26637 22.7359 5.9432 22.5348 5.7703 22.2359H3.13039C1.82818 22.2359 1.14452 20.6904 2.02048 19.7269L2.59957 19.0899L1.98009 17.9542C1.43488 16.9546 2.15834 15.7359 3.29693 15.7359H6.54557C6.56664 15.7359 6.58756 15.7365 6.60831 15.7378C6.61129 15.6799 6.61933 15.6208 6.63286 15.5608L7.49475 11.7366C7.57523 11.3796 7.45419 11.0071 7.17921 10.7655L4.23414 8.17828C3.57487 7.59912 3.928 6.51231 4.80177 6.43127L8.7051 6.06925C9.06956 6.03545 9.38643 5.80523 9.53121 5.46905L11.0817 1.86863ZM11.3681 6.2601L12.0002 4.79243L12.6322 6.2601C13.0665 7.26863 14.0171 7.95929 15.1105 8.0607L16.7017 8.20828L15.5011 9.26293C14.6762 9.98764 14.3131 11.1052 14.5545 12.1764L14.9059 13.7352L13.5318 12.9194C12.5877 12.3587 11.4126 12.3587 10.4685 12.9194L9.09447 13.7352L9.44581 12.1764C9.68724 11.1052 9.32414 9.98764 8.49918 9.26293L7.29865 8.20828L8.88981 8.0607C9.98318 7.95929 10.9338 7.26863 11.3681 6.2601ZM7.90909 16.7359H16.0912C16.0205 16.7129 15.9502 16.6814 15.8814 16.6405L12.5107 14.6391C12.196 14.4522 11.8043 14.4522 11.4896 14.6391L8.11895 16.6405C8.05008 16.6814 7.97981 16.7129 7.90909 16.7359ZM7.63651 20.7359V18.7359H16.3638V20.7359H7.63651ZM18.4548 17.7359V20.2359H19.7397L19.6815 20.1719C19.2516 19.699 19.1685 19.0057 19.4745 18.4446L19.8611 17.7359H18.4548ZM5.54557 20.2359V17.7359H4.13921L4.52578 18.4446C4.83181 19.0057 4.74874 19.699 4.31885 20.1719L4.26067 20.2359H5.54557Z'\n      />\n    </SvgIcon>\n  )\n}\n// export const RedPacketIcon = (props: SvgIconProps) => {\n//   return (\n//     <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n//       <path\n//         fillRule='evenodd'\n//         clipRule='evenodd'\n//         d='M4 3C4 2.44772 4.44772 2 5 2H19C19.5523 2 20 2.44772 20 3V21C20 21.5523 19.5523 22 19 22H5C4.44772 22 4 21.5523 4 21V3ZM7.56283 4L8.94744 7H15.0524L16.437 4H7.56283ZM18 5.38612L16.6538 8.30287C16.4577 8.72785 16.0323 9 15.5643 9H8.43557C7.96751 9 7.54217 8.72785 7.34602 8.30287L6 5.38649V20H18V5.38612Z'\n//       />\n//       <path d='M12.8217 9.75H11.4901V10.6955C10.9551 10.7761 10.5044 10.9603 10.1533 11.2613C9.7473 11.6094 9.54106 12.0617 9.54106 12.5994C9.54106 12.9958 9.6589 13.3519 9.89651 13.6572C10.1312 13.9588 10.4727 14.1982 10.902 14.3847C11.1593 14.4977 11.5108 14.6176 11.9514 14.7449L11.9528 14.7453C12.3796 14.8659 12.6499 14.9945 12.7956 15.1168L12.7973 15.1183C12.928 15.2259 12.987 15.352 12.987 15.5142C12.987 15.6889 12.9216 15.8196 12.7762 15.9275L12.7746 15.9287C12.6314 16.0367 12.3944 16.1096 12.026 16.1096C11.6628 16.1096 11.4174 16.0225 11.2555 15.8817C11.1024 15.7456 11.013 15.547 11.013 15.2492V14.9992H9.25V15.2492C9.25 15.8656 9.45685 16.3815 9.88206 16.7711L9.88292 16.7719C10.2611 17.1151 10.7693 17.3207 11.3862 17.407V18.25H12.7126V17.4043C13.2822 17.3282 13.7567 17.1494 14.118 16.8515C14.5375 16.5086 14.75 16.0529 14.75 15.5058C14.75 15.2225 14.6974 14.9628 14.5835 14.734C14.4734 14.513 14.3174 14.3206 14.1196 14.1571C13.925 13.9935 13.691 13.8531 13.4215 13.7336C13.1544 13.6152 12.7946 13.4897 12.3467 13.3566C11.9119 13.2274 11.6344 13.0997 11.485 12.984C11.3634 12.8849 11.3041 12.7615 11.3041 12.591C11.3041 12.3832 11.3715 12.2525 11.4884 12.1614C11.6169 12.0613 11.8154 11.9955 12.1143 11.9955C12.3961 11.9955 12.5902 12.0792 12.7281 12.2246L12.7309 12.2274C12.8719 12.3715 12.9558 12.5802 12.9558 12.8854V13.1354H14.7136V12.8854C14.7136 12.2823 14.5312 11.7708 14.1504 11.3749C13.8153 11.024 13.366 10.807 12.8217 10.7095V9.75Z' />\n//     </SvgIcon>\n//   )\n// }\n\nexport const SecurityIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path d='M20.784 4.86011L20.7837 4.8527C20.7692 4.50346 20.561 4.19153 20.244 4.04411C20.064 3.96011 15.744 2.01611 11.652 2.01611C7.56003 2.01611 3.24003 3.96011 3.04803 4.04411C2.73109 4.19153 2.52289 4.50346 2.50834 4.8527L2.50803 4.86011C2.50803 5.02811 2.36403 9.00011 3.12003 12.6601L4.72803 11.1121C4.35603 8.42411 4.34403 6.70811 4.35603 5.50811C5.59203 5.01611 8.74803 3.86411 11.652 3.86411C14.556 3.86411 17.712 5.01611 18.948 5.50811C18.96 6.88811 18.888 10.4641 18.12 13.3201C17.052 17.1121 12.852 19.2121 11.652 19.7521C10.644 19.3081 7.57203 17.7841 5.95203 15.0961L8.58003 12.2401L11.172 14.4001L15.36 9.81611L15.432 11.3761L17.112 11.2921L16.884 6.67211L12.432 6.88811L12.516 8.56811L14.052 8.49611L11.004 11.8441L8.42403 9.68411L3.72003 14.7841L4.00803 15.3601C6.12003 19.6201 11.124 21.5281 11.34 21.6121C11.5491 21.6895 11.779 21.6895 11.988 21.6121C12.252 21.5161 18.408 19.1521 19.908 13.8121C20.94 9.93611 20.796 5.06411 20.784 4.86011Z' />\n    </SvgIcon>\n  )\n}\nexport const VipIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path d='M12 21L11.949 21C11.8 20.9888 11.6583 20.9311 11.544 20.835C11.5126 20.8084 11.4839 20.7789 11.458 20.747L2.16797 9.673C2.09553 9.59022 2.04438 9.49102 2.01897 9.384C2.01897 9.371 2.01297 9.358 2.00997 9.345C1.98164 9.17748 2.01733 9.00543 2.10997 8.863L2.12897 8.835L5.75897 3.7C5.77197 3.68 5.78497 3.662 5.79997 3.646C5.90615 3.51982 6.05348 3.43518 6.21597 3.407C6.24378 3.40276 6.27184 3.40042 6.29997 3.4L11.95 3L12 3L12.049 3L17.7 3.4C17.7312 3.40177 17.7623 3.40578 17.793 3.412C17.9713 3.44519 18.1297 3.54629 18.235 3.694L21.872 8.838C21.8795 8.84797 21.8865 8.85831 21.893 8.869C21.9762 8.99649 22.0139 9.14838 22 9.3C21.9957 9.33886 21.9884 9.37732 21.978 9.415C21.9506 9.51087 21.9021 9.59938 21.836 9.674L12.543 20.746C12.5275 20.7654 12.5108 20.7838 12.493 20.801C12.4346 20.8577 12.3669 20.9041 12.293 20.938C12.2323 20.9654 12.1679 20.9839 12.102 20.993C12.0682 20.9977 12.0341 21 12 21ZM7.94597 9.911L12 18.663L16.054 9.911L7.94597 9.911ZM17.586 9.911L14.824 15.874L19.824 9.911L17.586 9.911ZM4.17297 9.911L9.17297 15.874L6.41397 9.911L4.17297 9.911ZM18.168 5.994L17.908 8.545L19.97 8.545L18.168 5.994ZM12 4.869L8.87197 8.545L15.128 8.545L12 4.869ZM5.83197 5.994L4.02997 8.545L6.09197 8.545L5.83197 5.994ZM13.477 4.471L16.551 8.084L16.9 4.711L13.477 4.471ZM10.521 4.471L7.09997 4.711L7.44497 8.084L10.521 4.471Z' />\n    </SvgIcon>\n  )\n}\n\nexport const L2OrderIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path d='M18 2L6 2C4.89543 2 4 2.89543 4 4L4 20C4 21.1046 4.89543 22 6 22L13 22C13.0109 21.9995 13.0217 21.9975 13.032 21.994C13.0418 21.991 13.0518 21.989 13.062 21.988C13.1502 21.9823 13.2373 21.9652 13.321 21.937L13.349 21.928C13.3717 21.9203 13.3937 21.911 13.415 21.9C13.5239 21.8516 13.6232 21.7838 13.708 21.7L19.708 15.7C19.7918 15.6152 19.8596 15.5159 19.908 15.407C19.918 15.385 19.925 15.362 19.933 15.339L19.942 15.313C19.9699 15.2296 19.9864 15.1428 19.991 15.055C19.9926 15.0458 19.9949 15.0368 19.998 15.028C19.9998 15.0188 20.0004 15.0094 20.0001 15L20.0001 4C20.0001 2.89543 19.1046 2 18 2ZM6 20L6 4L18 4L18 14L13 14C12.4477 14 12 14.4477 12 15L12 20L6 20ZM14 18.586L14 16L16.586 16L14 18.586Z' />\n      <path d='M9.8 14.987L8 14.987L8 13.187L12.2 8.997L14 10.797L9.8 14.987ZM14.625 10.169L12.825 8.369L14.2 7L16 8.8L14.63 10.17L14.625 10.169Z' />\n    </SvgIcon>\n  )\n}\n\nexport const CheckBoxIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path d='M4 3H20C20.2652 3 20.5196 3.10536 20.7071 3.29289C20.8946 3.48043 21 3.73478 21 4V20C21 20.2652 20.8946 20.5196 20.7071 20.7071C20.5196 20.8946 20.2652 21 20 21H4C3.73478 21 3.48043 20.8946 3.29289 20.7071C3.10536 20.5196 3 20.2652 3 20V4C3 3.73478 3.10536 3.48043 3.29289 3.29289C3.48043 3.10536 3.73478 3 4 3ZM5 5V19H19V5H5Z' />\n    </SvgIcon>\n  )\n}\n\nexport const CheckedIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M20 3H4C3.73478 3 3.48043 3.10536 3.29289 3.29289C3.10536 3.48043 3 3.73478 3 4V20C3 20.2652 3.10536 20.5196 3.29289 20.7071C3.48043 20.8946 3.73478 21 4 21H20C20.2652 21 20.5196 20.8946 20.7071 20.7071C20.8946 20.5196 21 20.2652 21 20V4C21 3.73478 20.8946 3.48043 20.7071 3.29289C20.5196 3.10536 20.2652 3 20 3ZM6.76001 11.7569L11.003 15.9999L18.074 8.92889L16.659 7.51489L11.003 13.1719L8.17401 10.3429L6.76001 11.7569Z'\n        color='#446EFF'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const ViewIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path d='M12 18.9999C10.3599 19.0203 8.7367 18.6663 7.254 17.9649C6.10469 17.4041 5.07265 16.6296 4.213 15.6829C3.30243 14.704 2.58547 13.5615 2.1 12.3159L2 11.9999L2.105 11.6839C2.59082 10.4393 3.30624 9.29713 4.214 8.31686C5.07334 7.37017 6.10504 6.59572 7.254 6.03486C8.73671 5.33345 10.3599 4.97947 12 4.99986C13.6401 4.9795 15.2633 5.33348 16.746 6.03486C17.8953 6.59559 18.9274 7.37005 19.787 8.31686C20.6993 9.29441 21.4165 10.4372 21.9 11.6839L22 11.9999L21.895 12.3159C20.3262 16.3996 16.3742 19.0692 12 18.9999ZM12 6.99986C8.59587 6.89319 5.47142 8.87495 4.117 11.9999C5.4712 15.125 8.59579 17.1068 12 16.9999C15.4041 17.1062 18.5284 15.1246 19.883 11.9999C18.5304 8.87344 15.4047 6.89094 12 6.99986ZM12 14.9999C10.5573 15.0094 9.30937 13.9972 9.02097 12.5836C8.73256 11.17 9.48427 9.74988 10.8154 9.19352C12.1465 8.63716 13.6852 9.09999 14.4885 10.2984C15.2919 11.4967 15.1354 13.0959 14.115 14.1159C13.5563 14.6811 12.7948 14.9994 12 14.9999Z' />\n    </SvgIcon>\n  )\n}\nexport const HideIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path d='M19.97 21.385L16.614 18.029C15.1661 18.6882 13.5908 19.0204 12 19.002C10.3599 19.0223 8.73671 18.6684 7.254 17.967C6.10468 17.4062 5.07264 16.6317 4.213 15.685C3.30049 14.7068 2.5833 13.5633 2.1 12.316L2 12.002L2.105 11.686C2.82781 9.84224 4.04426 8.23312 5.621 7.03495L3 4.41395L4.413 3.00195L21.382 19.971L19.972 21.385L19.97 21.385ZM7.036 8.45095C5.75792 9.34687 4.74865 10.5747 4.117 12.002C5.47142 15.1269 8.59587 17.1086 12 17.002C13.0498 17.0106 14.0936 16.8415 15.087 16.502L13.287 14.702C12.8863 14.8984 12.4462 15.0009 12 15.002C10.3475 14.9916 9.01037 13.6545 9 12.002C9.00048 11.5547 9.10309 11.1135 9.3 10.712L7.036 8.45095ZM19.852 15.612L18.46 14.221C19.0456 13.5589 19.5256 12.8104 19.883 12.002C18.5304 8.87553 15.4047 6.89303 12 7.00195C11.753 7.00195 11.505 7.01095 11.265 7.02795L9.5 5.26095C10.3216 5.08519 11.1598 4.99835 12 5.00195C13.6401 4.9816 15.2633 5.33557 16.746 6.03695C17.8953 6.59769 18.9274 7.37215 19.787 8.31895C20.6991 9.29592 21.4163 10.438 21.9 11.684L22 12.002L21.895 12.318C21.4268 13.536 20.7342 14.6554 19.853 15.618L19.852 15.612Z' />\n    </SvgIcon>\n  )\n}\nexport const DropDownIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path d='M12.0002 15.7131L18.0102 9.70309L16.5972 8.28809L12.0002 12.8881L7.40423 8.28809L5.99023 9.70209L12.0002 15.7131Z' />\n    </SvgIcon>\n  )\n}\nexport const BackIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path d='M15.535 3.51465L7.04993 11.9996L15.535 20.4846L16.95 19.0706L9.87794 11.9996L16.95 4.92865L15.535 3.51465Z' />\n    </SvgIcon>\n  )\n}\n\nexport const MoreIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path d='M12.5918 20C11.4872 20 10.5918 19.1046 10.5918 18C10.5918 16.8954 11.4872 16 12.5918 16C13.6964 16 14.5918 16.8954 14.5918 18C14.5918 19.1046 13.6964 20 12.5918 20ZM12.5918 14C11.4872 14 10.5918 13.1046 10.5918 12C10.5918 10.8954 11.4872 10 12.5918 10C13.6964 10 14.5918 10.8954 14.5918 12C14.5918 12.5304 14.3811 13.0391 14.006 13.4142C13.6309 13.7893 13.1222 14 12.5918 14ZM12.5918 8C11.4872 8 10.5918 7.10457 10.5918 6C10.5918 4.89543 11.4872 4 12.5918 4C13.6964 4 14.5918 4.89543 14.5918 6C14.5918 6.53043 14.3811 7.03914 14.006 7.41421C13.6309 7.78929 13.1222 8 12.5918 8Z' />\n    </SvgIcon>\n  )\n}\nexport const StarHollowIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M21.2654 10.5904L21.2653 10.5904C20.9788 9.48264 20.9788 9.48262 20.5967 8.47558L14.8658 8.37488L13.051 2.73535H10.9497L9.03937 8.37488L3.40396 8.47558C3.11741 9.58335 3.11741 9.58335 2.73535 10.5904L7.32009 14.2158L5.60082 19.956L7.32009 21.2652L12.0004 17.8412L16.6806 21.2652C17.1104 20.9127 17.3253 20.7617 17.5402 20.6106C17.7552 20.4596 17.9701 20.3085 18.3999 19.956L16.6806 14.2158L21.2654 10.5904ZM17.4782 19.6669L15.9142 14.4453C15.8202 14.1313 15.9272 13.7916 16.1844 13.5883L20.3598 10.2866C20.2956 10.0432 20.2491 9.87691 20.1965 9.71259C20.153 9.57658 20.1053 9.44191 20.0399 9.26592L14.8518 9.17475C14.5096 9.16874 14.2091 8.94573 14.1043 8.61994L12.4681 3.53535H11.5233L9.79708 8.63154C9.68875 8.95136 9.39128 9.16872 9.05367 9.17475L4.02486 9.26461C3.90802 9.70292 3.83877 9.92257 3.68996 10.3254L7.81631 13.5883C8.07346 13.7916 8.18052 14.1313 8.08646 14.4453L6.52608 19.6551L7.32967 20.267L11.528 17.1956C11.8093 16.9898 12.1914 16.9898 12.4727 17.1956L16.6613 20.2599C16.8274 20.1339 16.9549 20.0442 17.0802 19.9561L17.0844 19.9532C17.2032 19.8697 17.3202 19.7874 17.4782 19.6669Z'\n      />\n    </SvgIcon>\n  )\n}\nexport const StarSolidIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path d='M21.2654 10.5904C20.9788 9.48264 20.9788 9.48264 20.5967 8.47558L14.8658 8.37488L13.051 2.73535H10.9497L9.03937 8.37488L3.40396 8.47558C3.11741 9.58335 3.11741 9.58335 2.73535 10.5904L7.32009 14.2158L5.60082 19.956L7.32009 21.2652L12.0004 17.8412L16.6806 21.2652C17.5402 20.5603 17.5402 20.661 18.3999 19.956L16.6806 14.2158L21.2654 10.5904Z' />\n    </SvgIcon>\n  )\n}\nexport const FavHollowIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path d='M12.001 4.52898C14.35 2.41998 17.98 2.48998 20.243 4.75698C22.505 7.02498 22.583 10.637 20.479 12.993L11.999 21.485L3.52101 12.993C1.41701 10.637 1.49601 7.01898 3.75701 4.75698C6.02201 2.49298 9.64501 2.41698 12.001 4.52898V4.52898ZM18.827 6.16998C17.327 4.66798 14.907 4.60698 13.337 6.01698L12.002 7.21498L10.666 6.01798C9.09101 4.60598 6.67601 4.66798 5.17201 6.17198C3.68201 7.66198 3.60701 10.047 4.98001 11.623L12 18.654L19.02 11.624C20.394 10.047 20.319 7.66498 18.827 6.16998V6.16998Z' />\n    </SvgIcon>\n  )\n}\n\nexport const FavSolidIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path d='M20.243 4.75698C17.98 2.48998 14.35 2.41998 12.001 4.52898C9.64501 2.41698 6.02201 2.49298 3.75701 4.75698C1.49601 7.01898 1.41701 10.637 3.52101 12.993L11.999 21.485L20.479 12.993C22.583 10.637 22.505 7.02498 20.243 4.75698Z' />\n    </SvgIcon>\n  )\n}\n\nexport const DownloadIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M20 21H4C3.44772 21 3 20.5523 3 20V4C3 3.44772 3.44772 3 4 3H20C20.5523 3 21 3.44772 21 4V20C21 20.5523 20.5523 21 20 21ZM7.33321 18.6668H16.6665V17.3335H7.33321V18.6668ZM7.99988 12.0002L11.9999 16.0002L15.9998 12.0002L15.0599 11.0602L12.6665 13.4468V5.3335H11.3332V13.4468L8.93987 11.0602L7.99988 12.0002Z'\n      />\n    </SvgIcon>\n  )\n}\nexport const NotificationIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path d='M12 22C10.896 21.9946 10.0009 21.1039 9.99 20L13.99 20C13.9921 20.2674 13.9411 20.5325 13.84 20.78C13.5777 21.382 13.0418 21.8211 12.4 21.96L12.395 21.96L12.38 21.96L12.362 21.96L12.353 21.96C12.2368 21.9842 12.1186 21.9976 12 22ZM20 19L4 19L4 17L6 16L6 10.5C5.94732 9.08912 6.26594 7.68913 6.924 6.44C7.57904 5.28151 8.6987 4.45888 10 4.18L10 2L14 2L14 4.18C16.579 4.794 18 7.038 18 10.5L18 16L20 17L20 19Z' />\n    </SvgIcon>\n  )\n}\nexport const SettingIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path d='M13.8199 22L10.1799 22C9.71003 22 9.30347 21.673 9.20292 21.214L8.79592 19.33C8.25297 19.0921 7.73814 18.7946 7.26092 18.443L5.42392 19.028C4.97592 19.1709 4.4889 18.9823 4.25392 18.575L2.42992 15.424C2.19751 15.0165 2.27758 14.5025 2.62292 14.185L4.04792 12.885C3.98312 12.2961 3.98312 11.7019 4.04792 11.113L2.62292 9.816C2.27707 9.49837 2.19697 8.98372 2.42992 8.576L4.24992 5.423C4.4849 5.0157 4.97192 4.82714 5.41992 4.97L7.25692 5.555C7.50098 5.37416 7.75505 5.20722 8.01792 5.055C8.27026 4.91269 8.52995 4.78385 8.79592 4.669L9.20392 2.787C9.30399 2.32797 9.71011 2.00049 10.1799 2L13.8199 2C14.2897 2.00049 14.6958 2.32797 14.7959 2.787L15.2079 4.67C15.4887 4.79352 15.7622 4.93308 16.0269 5.088C16.2742 5.23078 16.5132 5.38736 16.7429 5.557L18.5809 4.972C19.0286 4.82967 19.515 5.01816 19.7499 5.425L21.5699 8.578C21.8023 8.98548 21.7223 9.49951 21.3769 9.817L19.9519 11.117C20.0167 11.7059 20.0167 12.3001 19.9519 12.889L21.3769 14.189C21.7223 14.5065 21.8023 15.0205 21.5699 15.428L19.7499 18.581C19.515 18.9878 19.0286 19.1763 18.5809 19.034L16.7429 18.449C16.5103 18.6203 16.2687 18.7789 16.0189 18.924C15.7567 19.0759 15.4863 19.2131 15.2089 19.335L14.7959 21.214C14.6954 21.6726 14.2894 21.9996 13.8199 22ZM11.9959 8C9.78678 8 7.99592 9.79086 7.99592 12C7.99592 14.2091 9.78678 16 11.9959 16C14.2051 16 15.9959 14.2091 15.9959 12C15.9959 9.79086 14.2051 8 11.9959 8Z' />\n    </SvgIcon>\n  )\n}\nexport const LinkIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M21.8843 2.20898H15.3848V4.34676H18.1311L11.6167 10.8611L13.1298 12.3726L19.7458 5.75653V8.70785H21.8843V2.20898ZM15.4848 4.24676V2.30908H21.7843V2.30898H15.4848V4.24676H15.4848ZM18.3724 4.24686L11.7582 10.8611L11.7583 10.8612L18.3726 4.24686H18.3724ZM19.8458 5.51531V8.60785H19.8459V5.51521L19.8458 5.51531ZM19.8538 10.9314H17.7161V19.6535H4.34798V6.28548H13.0702V4.14697H2.20947V21.7913H19.8538V10.9314ZM4.24807 19.7535H17.8161V11.0314H19.7538V11.0315H17.8161V19.7536H4.24807V19.7535ZM2.30957 21.6913H2.30947V4.24697H12.9702V4.24707H2.30957V21.6913Z'\n      />\n    </SvgIcon>\n  )\n}\nexport const CopyIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M2.17451 2.17529L18.3089 2.17529L18.3089 5.41878L18.3091 5.41878L18.3091 2.175L2.17451 2.175L2.17451 2.17529ZM5.4181 18.3096L5.4183 18.3096L5.4183 16.2377L4.24641 16.2377L4.24641 4.24719L4.24621 4.24719L4.24621 16.238L5.4181 16.238L5.4181 18.3096ZM16.1872 5.46878L16.1872 4.2969L4.29641 4.2969L4.29641 16.1877L5.4683 16.1877L5.4683 18.3596L2.12451 18.3596L2.12451 2.125L18.3591 2.125L18.3591 5.46878L16.1872 5.46878ZM21.876 6.14268L6.14372 6.14268L6.14372 21.875L21.876 21.875L21.876 6.14268ZM19.7428 19.7417L19.7428 8.27595L8.27698 8.27595L8.27698 19.7417L19.7428 19.7417ZM21.826 21.825L21.826 6.19268L6.19372 6.19269L6.19372 6.19298L21.8258 6.19298L21.8258 21.825L21.826 21.825ZM8.22698 8.22624L8.22679 8.22624L8.22679 19.792L19.7926 19.792L19.7926 19.7917L8.22698 19.7917L8.22698 8.22624Z'\n      />\n    </SvgIcon>\n  )\n}\nexport const ReverseIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M18 19C18.5523 19 19 18.5523 19 18L19 13L17 13L17 17L7 17L7 14L3 18L7 22L7 19L18 19ZM6 5C5.44772 5 5 5.44772 5 6L5 11L7 11L7 7L17 7L17 10L21 6L17 2L17 5L6 5Z'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const HelpIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M7.25 1.25C5.59314 1.25 4.25 2.59315 4.25 4.25V19.25C4.25 20.9069 5.59314 22.25 7.25 22.25H19.4444C19.8587 22.25 20.1944 21.9142 20.1944 21.5C20.1944 21.0858 19.8587 20.75 19.4444 20.75H7.25C6.42157 20.75 5.75 20.0784 5.75 19.25V18.2155H17.75C19.4069 18.2155 20.75 16.8724 20.75 15.2155V4.25C20.75 2.59315 19.4069 1.25 17.75 1.25H7.25ZM17.75 16.7155H5.75V4.25C5.75 3.42157 6.42157 2.75 7.25 2.75H17.75C18.5784 2.75 19.25 3.42157 19.25 4.25V15.2155C19.25 16.0439 18.5784 16.7155 17.75 16.7155ZM11.4868 7.15582C12.121 6.61471 13.1924 6.61471 13.8266 7.15582C14.3908 7.63676 14.3911 8.35967 13.8269 8.84061L13.8246 8.84258C13.7216 8.93113 13.6016 9.00764 13.4698 9.06972C12.8261 9.37375 11.9075 10.0481 11.9075 11.1389V11.7099C11.9075 12.1241 12.2433 12.4599 12.6575 12.4599C13.0717 12.4599 13.4075 12.1241 13.4075 11.7099V11.1389C13.4075 11.0563 13.4407 10.9481 13.5639 10.8108C13.6906 10.6696 13.8834 10.5333 14.1101 10.4262C14.3527 10.3119 14.5874 10.1646 14.8011 9.98115C16.0666 8.90129 16.0661 7.09402 14.8 6.0145C13.6049 4.99508 11.7082 4.99514 10.5132 6.01471C10.1981 6.28356 10.1606 6.75695 10.4295 7.07206C10.6983 7.38717 11.1717 7.42467 11.4868 7.15582ZM12.6567 13.2439C12.2425 13.2439 11.9067 13.5797 11.9067 13.9939V14C11.9067 14.4142 12.2425 14.75 12.6567 14.75H12.663C13.0772 14.75 13.413 14.4142 13.413 14V13.9939C13.413 13.5797 13.0772 13.2439 12.663 13.2439H12.6567Z'\n      />\n    </SvgIcon>\n  )\n}\nexport const CalendarIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path d='M19 22L5 22C3.89543 22 3 21.1046 3 20L3 6C3 4.89543 3.89543 4 5 4L7 4L7 2L9 2L9 4L15 4L15 2L17 2L17 4L19 4C20.1046 4 21 4.89543 21 6L21 20C21 21.1046 20.1046 22 19 22ZM5 10L5 20L19 20L19 10L5 10ZM5 6L5 8L19 8L19 6L5 6ZM17 18L15 18L15 16L17 16L17 18ZM13 18L11 18L11 16L13 16L13 18ZM9 18L7 18L7 16L9 16L9 18ZM17 14L15 14L15 12L17 12L17 14ZM13 14L11 14L11 12L13 12L13 14ZM9 14L7 14L7 12L9 12L9 14Z' />\n    </SvgIcon>\n  )\n}\nexport const LinkedIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path d='M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C21.9939 17.5203 17.5203 21.9939 12 22ZM4 12.172C4.04732 16.5732 7.64111 20.1095 12.0425 20.086C16.444 20.0622 19.9995 16.4875 19.9995 12.086C19.9995 7.68451 16.444 4.10977 12.0425 4.086C7.64111 4.06246 4.04732 7.59876 4 12L4 12.172ZM13 17L11 17L11 13L7 13L7 11L11 11L11 7L13 7L13 11L17 11L17 13L13 13L13 17Z' />\n    </SvgIcon>\n  )\n}\nexport const ExchangeIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path d='M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C21.9939 17.5203 17.5203 21.9939 12 22ZM12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20C16.4183 20 20 16.4183 20 12C19.995 7.58378 16.4162 4.00496 12 4ZM12 17L7 12L8.41 10.59L11 13.17L11 7L13 7L13 13.17L15.59 10.59L17 12L12 17Z' />\n    </SvgIcon>\n  )\n}\nexport const CloseIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path d='M17.59 5L12 10.59L6.41 5L5 6.41L10.59 12L5 17.59L6.41 19L12 13.41L17.59 19L19 17.59L13.41 12L19 6.41L17.59 5Z' />\n    </SvgIcon>\n  )\n}\nexport const SearchIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M15.3201 17.7344C14.0741 18.5354 12.5913 19 11 19C6.58172 19 3 15.4183 3 11C3 6.58172 6.58172 3 11 3C15.4183 3 19 6.58172 19 11C19 13.1038 18.1879 15.018 16.8601 16.4461L20.6567 20.2426L19.2425 21.6569L15.3201 17.7344ZM17 11C17 14.3137 14.3137 17 11 17C7.68629 17 5 14.3137 5 11C5 7.68629 7.68629 5 11 5C14.3137 5 17 7.68629 17 11Z'\n      />\n    </SvgIcon>\n  )\n}\nexport const MenuIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path d='M21 18L3 18L3 16L21 16L21 18ZM21 13L3 13L3 11L21 11L21 13ZM21 8L3 8L3 6L21 6L21 8Z' />\n    </SvgIcon>\n  )\n}\nexport const QRIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='10' height='10' viewBox='0 0 24 24' fill='none'>\n      <path d='M4 17.3333H6.66667V20H4V17.3333Z' />\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M10.6667 21.3328L7.99951 24H0V13.3333H10.6667V21.3328ZM2.66667 21.3333L2.66667 16H8V21.3333H2.66667Z'\n      />\n      <path d='M20 4L17.3333 4V6.66667H20V4Z' />\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M21.3328 10.6667L24 7.99951V0H13.3333V10.6667H21.3328ZM21.3333 8V2.66667L16 2.66667V8H21.3333Z'\n      />\n      <path d='M17.3333 14.6662V13.3333H13.3333V16H15.9995L17.3333 14.6662Z' />\n      <path d='M6.66667 4H4V6.66667H6.66667V4Z' />\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M0 0V10.6667H10.6667V0H0ZM2.66667 8V2.66667H8V8H2.66667Z'\n      />\n    </SvgIcon>\n  )\n}\nexport const DoneIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M22.875 12C22.875 18.0061 18.0061 22.875 12 22.875C5.9939 22.875 1.125 18.0061 1.125 12C1.125 5.9939 5.9939 1.125 12 1.125C18.0061 1.125 22.875 5.9939 22.875 12ZM24 12C24 18.6274 18.6274 24 12 24C5.37258 24 0 18.6274 0 12C0 5.37258 5.37258 0 12 0C18.6274 0 24 5.37258 24 12ZM10.2099 15.7774L16.9716 9.01572L16.1784 8.22259L10.2099 14.1855L7.82101 11.8023L7.02788 12.5954L10.2099 15.7774Z'\n      />\n    </SvgIcon>\n  )\n}\nexport const RefuseIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M22.875 12C22.875 18.0061 18.0061 22.875 12 22.875C9.25164 22.875 6.7414 21.8555 4.82685 20.174L20.174 4.82686C21.8555 6.74142 22.875 9.25165 22.875 12ZM4.02078 19.3891L19.3891 4.02079C17.4493 2.22358 14.8529 1.125 12 1.125C5.9939 1.125 1.125 5.9939 1.125 12C1.125 14.8529 2.22358 17.4493 4.02078 19.3891ZM24 12C24 18.6274 18.6274 24 12 24C5.37258 24 0 18.6274 0 12C0 5.37258 5.37258 0 12 0C18.6274 0 24 5.37258 24 12Z'\n      />\n    </SvgIcon>\n  )\n}\nexport const SubmitIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M22.875 12C22.875 18.0061 18.0061 22.875 12 22.875C5.9939 22.875 1.125 18.0061 1.125 12C1.125 5.9939 5.9939 1.125 12 1.125C18.0061 1.125 22.875 5.9939 22.875 12ZM24 12C24 18.6274 18.6274 24 12 24C5.37258 24 0 18.6274 0 12C0 5.37258 5.37258 0 12 0C18.6274 0 24 5.37258 24 12ZM12.5754 7.09267C12.3543 6.88211 12.0056 6.88636 11.7897 7.10225L7.85218 11.0398L8.64768 11.8352L11.6249 8.858V16.6875H12.7499V8.8125L15.737 11.6573L16.5129 10.8427L12.5754 7.09267Z'\n      />\n    </SvgIcon>\n  )\n}\nexport const FailedIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M12.9775 11.807L16.1423 14.9718L15.3468 15.7673L12.182 12.6025L9.01725 15.7673L8.22176 14.9718L11.3865 11.807L8.22176 8.64225L9.01725 7.84676L12.182 11.0115L15.3468 7.84676L16.1423 8.64225L12.9775 11.807ZM12 22.875C18.0061 22.875 22.875 18.0061 22.875 12C22.875 5.9939 18.0061 1.125 12 1.125C5.9939 1.125 1.125 5.9939 1.125 12C1.125 18.0061 5.9939 22.875 12 22.875ZM12 24C18.6274 24 24 18.6274 24 12C24 5.37258 18.6274 0 12 0C5.37258 0 0 5.37258 0 12C0 18.6274 5.37258 24 12 24Z'\n      />\n    </SvgIcon>\n  )\n}\nexport const GoodIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path d='M10 20C4.47967 19.994 0.00606248 15.5204 6.79866e-08 10L6.66269e-08 9.80002C0.109932 4.30455 4.63459 -0.0720257 10.1307 0.000898149C15.6268 0.073822 20.0337 4.5689 19.9978 10.0654C19.9619 15.5618 15.4966 19.9989 10 20ZM5.41 9.59002L4 11L8 15L16 7.00002L14.59 5.58002L8 12.17L5.41 9.59002Z' />\n    </SvgIcon>\n  )\n}\nexport const AlertIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path d='M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C21.9939 17.5203 17.5203 21.9939 12 22ZM11 15V17H13V15H11ZM11 7V13H13V7H11Z' />\n    </SvgIcon>\n  )\n}\n\nexport const ErrorIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path d='M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C21.9939 17.5203 17.5203 21.9939 12 22ZM11 15V17H13V15H11ZM11 7V13H13V7H11Z' />\n    </SvgIcon>\n  )\n}\n\nexport const InfoIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path d='M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C21.9939 17.5203 17.5203 21.9939 12 22ZM9.99 10.99L9.99 13L10.99 13L10.99 17L14.01 17L14.01 15L13 15L13.01 10.991L9.99 10.99ZM10.99 7L10.99 9.019L13.01 9.019L13.01 7L10.99 7Z' />\n    </SvgIcon>\n  )\n}\n\nexport const UnConnectIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24' fill='none'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M3.71573 12L6.65622 9.05951L8.12068 10.524L5.1802 13.4645C3.70136 14.9433 3.70136 17.341 5.18019 18.8198C6.65903 20.2986 9.0567 20.2986 10.5355 18.8198L13.476 15.8793L14.9405 17.3438L12 20.2843C9.71236 22.5719 6.00337 22.5719 3.71573 20.2843C1.42809 17.9966 1.42809 14.2876 3.71573 12ZM18.8198 10.5355L16.405 12.9504L17.8694 14.4149L20.2843 12C22.5719 9.71236 22.5719 6.00337 20.2843 3.71573C17.9966 1.42809 14.2876 1.42809 12 3.71573L9.58515 6.13058L11.0496 7.59505L13.4645 5.18019C14.9433 3.70136 17.341 3.70136 18.8198 5.1802C20.2986 6.65903 20.2986 9.0567 18.8198 10.5355ZM3.03226 3.26608C2.837 3.46134 2.837 3.77792 3.03226 3.97318L19.9187 20.8596C20.1139 21.0548 20.4305 21.0548 20.6258 20.8596L21.3831 20.1022C21.5784 19.907 21.5784 19.5904 21.3831 19.3951L4.49673 2.50872C4.30147 2.31345 3.98489 2.31345 3.78962 2.50872L3.03226 3.26608Z'\n      />\n    </SvgIcon>\n  )\n}\nexport const LockIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24' aria-hidden='true' data-testid='LockIcon'>\n      <path d='M6.6658 10.25L6.66712 7.6C6.66712 6.11479 7.25712 4.69041 8.30732 3.64021C9.35753 2.58999 10.7819 2 12.2671 2C13.7038 2 15.0856 2.55221 16.1266 3.54241C17.1677 4.53258 17.7883 5.885 17.8603 7.32253L17.8671 7.6V10.25H19.6C20.5988 10.25 21.4307 11.0096 21.5259 12.0022L21.5343 12.1829V20.4329C21.5343 21.4309 20.7727 22.2636 19.782 22.3574L19.6 22.3657H4.93434C4.45351 22.3661 3.98984 22.1874 3.63381 21.8643C3.27776 21.5413 3.05488 21.0971 3.00836 20.6136L3 20.4329V12.1829C3 11.1848 3.76156 10.3521 4.75225 10.2583L4.93425 10.25H6.6658ZM19.7 12.1829H4.83425V20.4329H19.7V12.1829ZM12.2671 13.9157C12.7727 13.9157 13.1995 14.287 13.2743 14.7896L13.2843 14.9329L13.2843 17.6835C13.2827 17.9392 13.185 18.1848 13.0106 18.3715C12.8361 18.5584 12.5978 18.6728 12.3428 18.6918C12.088 18.7108 11.8352 18.6332 11.6349 18.4743C11.4347 18.3154 11.3017 18.087 11.2613 17.8271L11.25 17.6829V14.9329C11.25 14.3717 11.7059 13.9157 12.2671 13.9157ZM12.2671 3.83288C11.3095 3.83311 10.3879 4.19803 9.68969 4.85345C8.9915 5.50887 8.56913 6.40559 8.50845 7.36129L8.50006 7.59645L8.5 10.35L8.6 10.45H15.9329L16.0329 10.35V7.6C16.0329 6.60117 15.6362 5.64319 14.93 4.93674C14.2239 4.23031 13.266 3.83325 12.2671 3.83288Z' />\n    </SvgIcon>\n  )\n}\nexport const UnlockedIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24' aria-hidden='true' fill=\"none\" data-testid='LockIcon'>\n      <path d=\"M19.0001 10.9999H4.99999C3.89542 10.9999 3 11.8953 3 12.9999V20C3 21.1044 3.89542 21.9999 4.99999 21.9999H19.0001C20.1045 21.9999 21 21.1044 21 20V12.9999C21 11.8953 20.1045 10.9999 19.0001 10.9999Z\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill='none'/>\n      <path d=\"M7.00003 11.0002V7.00016C6.99879 5.7602 7.45831 4.56402 8.2894 3.64382C9.12049 2.72362 10.2639 2.14506 11.4975 2.02044C12.7312 1.89583 13.9672 2.23406 14.9655 2.96946C15.9639 3.70488 16.6533 4.785 16.9 6.00015\"  stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill='none'/>\n    </SvgIcon>\n  )\n}\nexport const ProToLiteIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M4.83922 13.6991H3V5H6.43182C8.40719 5 9.54898 6.21907 9.54898 7.94786C9.54898 9.68493 8.38511 10.8792 6.38491 10.8792H4.83922V13.6991ZM4.83922 6.50429V9.40523H6.08773C7.14119 9.40523 7.65459 8.80995 7.65459 7.94786C7.65459 7.08117 7.14119 6.50429 6.07945 6.50429H4.83922ZM12.2897 13.6993H10.4809V7.1752H12.2345V8.31331H12.3026C12.5409 7.50642 13.1398 7.08136 13.8703 7.08136C14.0525 7.08136 14.2779 7.10711 14.4389 7.14576V8.75125C14.2697 8.69605 13.9256 8.65374 13.6744 8.65374C12.8767 8.65374 12.2897 9.20577 12.2897 10.0081V13.6993ZM17.789 13.8261C19.768 13.8261 21 12.4718 21 10.4623C21 8.44098 19.768 7.09035 17.789 7.09035C15.8099 7.09035 14.578 8.44098 14.578 10.4623C14.578 12.4718 15.8099 13.8261 17.789 13.8261ZM17.7973 12.4248C16.8846 12.4248 16.4172 11.5885 16.4172 10.4495C16.4172 9.31136 16.8846 8.47043 17.7973 8.47043C18.6934 8.47043 19.1608 9.31136 19.1608 10.4495C19.1608 11.5885 18.6934 12.4248 17.7973 12.4248ZM5.00364 16.4594C4.49577 16.4594 4.08358 16.8716 4.08358 17.3794C4.08358 17.8873 4.49577 18.2995 5.00364 18.2995H17.8844C18.3923 18.2995 18.8045 17.8873 18.8045 17.3794C18.8045 16.8716 18.3923 16.4594 17.8844 16.4594H5.00364Z'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const CheckIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path d='M22 5.67972L8.4 20L2 13.261L3.59523 11.5813L8.4 16.6286L20.4048 4L22 5.67972Z' />\n    </SvgIcon>\n  )\n}\n\nexport const LoadingIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon\n      {...props}\n      width={props.width ? props.width : '48'}\n      height={props.height ? props.height : '48'}\n      viewBox='0 0 48 48'\n      fill='none'\n    >\n      <path d='M43.935,25.145c0-10.318-8.364-18.683-18.683-18.683c-10.318,0-18.683,8.365-18.683,18.683h4.068c0-8.071,6.543-14.615,14.615-14.615c8.072,0,14.615,6.543,14.615,14.615H43.935z'>\n        <animateTransform\n          attributeType='xml'\n          attributeName='transform'\n          type='rotate'\n          from='0 25 25'\n          to='360 25 25'\n          dur='0.6s'\n          repeatCount='indefinite'\n        />\n      </path>\n    </SvgIcon>\n  )\n}\nexport const LoadingIcon2 = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 25 25' fill='none'>\n      <path\n        d='M12.0132 2.02637V6.02637'\n        stroke='#446EFF'\n        stroke-width='2'\n        stroke-linecap='round'\n        stroke-linejoin='round'\n      />\n      <path\n        d='M12.0132 18.0264V22.0264'\n        stroke='#446EFF'\n        stroke-width='2'\n        stroke-linecap='round'\n        stroke-linejoin='round'\n      />\n      <path\n        d='M4.94312 4.9563L7.77312 7.7863'\n        stroke='#446EFF'\n        stroke-width='2'\n        stroke-linecap='round'\n        stroke-linejoin='round'\n      />\n      <path\n        d='M16.2534 16.2664L19.0834 19.0964'\n        stroke='#446EFF'\n        stroke-width='2'\n        stroke-linecap='round'\n        stroke-linejoin='round'\n      />\n      <path\n        d='M2.01318 12.0264H6.01318'\n        stroke='#446EFF'\n        stroke-width='2'\n        stroke-linecap='round'\n        stroke-linejoin='round'\n      />\n      <path\n        d='M18.0132 12.0264H22.0132'\n        stroke='#446EFF'\n        stroke-width='2'\n        stroke-linecap='round'\n        stroke-linejoin='round'\n      />\n      <path\n        d='M4.94312 19.0964L7.77312 16.2664'\n        stroke='#446EFF'\n        stroke-width='2'\n        stroke-linecap='round'\n        stroke-linejoin='round'\n      />\n      <path\n        d='M16.2534 7.7863L19.0834 4.9563'\n        stroke='#446EFF'\n        stroke-width='2'\n        stroke-linecap='round'\n        stroke-linejoin='round'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const ActiveIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path d='M18.775 8.17266L17.7828 7.18603L18.775 6.19941C18.9066 6.06765 18.9805 5.88894 18.9805 5.7026C18.9805 5.51626 18.9066 5.33755 18.775 5.20579C18.6435 5.07402 18.465 5 18.2789 5C18.0928 5 17.9144 5.07402 17.7828 5.20579L10.4179 12.581C9.69537 12.1036 8.82166 11.9119 7.96602 12.0428C7.11039 12.1737 6.33375 12.6181 5.7866 13.2897C5.23944 13.9613 4.96073 14.8124 5.00447 15.6781C5.0482 16.5438 5.41127 17.3624 6.02332 17.9753C6.63536 18.5882 7.45282 18.9517 8.31728 18.9955C9.18174 19.0393 10.0317 18.7602 10.7024 18.2123C11.3731 17.6644 11.8168 16.8867 11.9475 16.0299C12.0783 15.173 11.8868 14.2981 11.4101 13.5746L14.8201 10.1529L15.8053 11.1465C15.8706 11.2114 15.948 11.2627 16.0332 11.2975C16.1183 11.3323 16.2095 11.35 16.3014 11.3494C16.3934 11.35 16.4846 11.3323 16.5697 11.2975C16.6548 11.2627 16.7323 11.2114 16.7976 11.1465C16.863 11.0815 16.915 11.0041 16.9505 10.9188C16.986 10.8335 17.0042 10.7421 17.0042 10.6497C17.0042 10.5573 16.986 10.4659 16.9505 10.3806C16.915 10.2953 16.863 10.218 16.7976 10.1529L15.8053 9.20127L16.7976 8.20764L17.7828 9.20127C17.8481 9.26612 17.9255 9.31743 18.0107 9.35225C18.0958 9.38707 18.187 9.40472 18.2789 9.40419C18.3709 9.40472 18.462 9.38707 18.5472 9.35225C18.6323 9.31743 18.7098 9.26612 18.775 9.20127C18.846 9.13574 18.9026 9.05622 18.9413 8.9677C18.98 8.87918 19 8.7836 19 8.68696C19 8.59033 18.98 8.49474 18.9413 8.40622C18.9026 8.31771 18.846 8.23818 18.775 8.17266V8.17266ZM8.49626 17.5981C8.08166 17.5981 7.67636 17.475 7.33163 17.2443C6.9869 17.0136 6.71821 16.6858 6.55955 16.3022C6.40089 15.9186 6.35937 15.4965 6.44026 15.0893C6.52114 14.6821 6.7208 14.3081 7.01397 14.0145C7.30714 13.7209 7.68066 13.521 8.0873 13.44C8.49394 13.359 8.91543 13.4006 9.29848 13.5595C9.68152 13.7183 10.0089 13.9874 10.2393 14.3326C10.4696 14.6778 10.5925 15.0837 10.5925 15.4989C10.5925 16.0556 10.3717 16.5896 9.97856 16.9832C9.58543 17.3769 9.05223 17.5981 8.49626 17.5981Z' />\n    </SvgIcon>\n  )\n}\n\nexport const RefreshIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24' aria-hidden='true'>\n      <path d='M12 6v3l4-4-4-4v3c-4.42 0-8 3.58-8 8 0 1.57.46 3.03 1.24 4.26L6.7 14.8c-.45-.83-.7-1.79-.7-2.8 0-3.31 2.69-6 6-6zm6.76 1.74L17.3 9.2c.44.84.7 1.79.7 2.8 0 3.31-2.69 6-6 6v-3l-4 4 4 4v-3c4.42 0 8-3.58 8-8 0-1.57-.46-3.03-1.24-4.26z' />\n    </SvgIcon>\n  )\n}\n\nexport const CompleteIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path d='M12 2C6.4863 2 2 6.4863 2 12C2 17.5144 6.48558 22 12 22C17.5144 22 22 17.5144 22 12C22 6.4863 17.5144 2 12 2ZM16.8257 10.3506L11.0809 16.1577C11.0795 16.1591 11.0766 16.1599 11.0752 16.162C11.073 16.1634 11.073 16.1663 11.0709 16.1677C11.025 16.2122 10.9683 16.2395 10.9152 16.2696C10.8886 16.2847 10.8671 16.3076 10.8391 16.3184C10.753 16.3528 10.6619 16.3708 10.5708 16.3708C10.479 16.3708 10.3864 16.3528 10.2996 16.317C10.2709 16.3048 10.248 16.2804 10.2207 16.2653C10.1676 16.2352 10.1124 16.2086 10.0664 16.1634C10.065 16.162 10.0643 16.1591 10.0628 16.1577C10.0614 16.1555 10.0585 16.1555 10.0571 16.1534L7.23174 13.2498C6.95552 12.9657 6.96197 12.5116 7.24609 12.2353C7.5302 11.9598 7.98364 11.9648 8.26058 12.2497L10.5758 14.6288L15.8061 9.34108C16.0845 9.05912 16.5394 9.05625 16.8206 9.33534C17.1012 9.61444 17.104 10.0686 16.8257 10.3506Z' />\n    </SvgIcon>\n  )\n}\n\nexport const WaitingIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path d='M10.9951 6.99628H13.0051V12.0076L16.3516 15.3541L14.9303 16.7753L10.9922 12.8372L10.9951 12.8343V6.99628Z' />\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M2.00024 12.0001C2.00024 17.5231 6.47724 22.0001 12.0002 22.0001C17.5232 22.0001 22.0002 17.5231 22.0002 12.0001C22.0002 6.47706 17.5232 2.00006 12.0002 2.00006C6.47724 2.00006 2.00024 6.47706 2.00024 12.0001ZM17.6571 17.6569C16.1568 19.1572 14.122 20.0001 12.0002 20.0001C9.87851 20.0001 7.84368 19.1572 6.34339 17.6569C4.8431 16.1566 4.00024 14.1218 4.00024 12.0001C4.00024 9.87833 4.8431 7.8435 6.34339 6.34321C7.84368 4.84292 9.87851 4.00006 12.0002 4.00006C14.122 4.00006 16.1568 4.84292 17.6571 6.34321C19.1574 7.8435 20.0002 9.87833 20.0002 12.0001C20.0002 14.1218 19.1574 16.1566 17.6571 17.6569Z'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const WarningIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path d='M12 22C6.477 22 2 17.523 2 12C2 6.477 6.477 2 12 2C17.523 2 22 6.477 22 12C22 17.523 17.523 22 12 22ZM12 20C14.1217 20 16.1566 19.1571 17.6569 17.6569C19.1571 16.1566 20 14.1217 20 12C20 9.87827 19.1571 7.84344 17.6569 6.34315C16.1566 4.84285 14.1217 4 12 4C9.87827 4 7.84344 4.84285 6.34315 6.34315C4.84285 7.84344 4 9.87827 4 12C4 14.1217 4.84285 16.1566 6.34315 17.6569C7.84344 19.1571 9.87827 20 12 20ZM11 15H13V17H11V15ZM11 7H13V13H11V7Z' />\n    </SvgIcon>\n  )\n}\n\nexport const EmptyIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path d='M13.7154 4.8073C13.5636 4.8073 13.4262 4.7031 13.3903 4.54883L13.1251 3.40997C13.0832 3.23021 13.195 3.05064 13.3746 3.00878C13.5544 2.96693 13.734 3.07869 13.7759 3.25837L14.0411 4.39733C14.083 4.5771 13.9713 4.75666 13.7915 4.79852C13.7666 4.80431 13.741 4.80726 13.7154 4.8073ZM17.4343 7.74442C17.4123 7.74442 17.3901 7.74232 17.3677 7.73775L16.2215 7.50628C16.0406 7.46978 15.9236 7.29353 15.9601 7.11263C15.9967 6.93173 16.1729 6.81477 16.3538 6.85127L17.5001 7.08273C17.6809 7.11923 17.798 7.29555 17.7615 7.47639C17.7293 7.63501 17.5901 7.74442 17.4343 7.74442ZM15.6071 5.44742C15.5109 5.44742 15.4154 5.40613 15.3493 5.32617C15.2319 5.18388 15.2519 4.97323 15.3941 4.85575L16.377 4.04368C16.5193 3.9261 16.7299 3.94618 16.8475 4.08845C16.965 4.23067 16.9449 4.44127 16.8027 4.55888L15.8198 5.37092C15.76 5.42043 15.6848 5.44749 15.6071 5.44742ZM18.8346 20.207H10.9544L16.478 18.2049C16.8202 18.0809 17.0936 17.831 17.248 17.5013C17.4022 17.1716 17.4188 16.8016 17.2948 16.4593L16.9367 15.4715C16.8928 15.3501 16.7586 15.2873 16.6372 15.3314C16.5157 15.3754 16.453 15.5095 16.497 15.6309L16.855 16.6187C16.9364 16.8435 16.9256 17.0865 16.8243 17.3031C16.723 17.5196 16.5433 17.6837 16.3186 17.7651L10.1025 20.0183C9.87759 20.0997 9.63462 20.0888 9.41811 19.9875C9.2016 19.8861 9.03748 19.7066 8.95605 19.4818L5.52144 10.0059C5.3533 9.54203 5.59392 9.0277 6.05791 8.85956L12.274 6.60636C12.4988 6.52492 12.7418 6.5359 12.9584 6.63721C13.1749 6.73852 13.339 6.91813 13.4204 7.14254L14.8233 11.0268C14.8672 11.1484 15.0012 11.2112 15.1228 11.1674C15.2442 11.1235 15.3071 10.9895 15.2632 10.868L13.8601 6.98342C13.7361 6.64124 13.4863 6.36783 13.1566 6.21348C12.8269 6.05921 12.4568 6.04261 12.1146 6.1666L5.89845 8.41973C5.19198 8.67583 4.82561 9.45888 5.08163 10.1653L8.51626 19.6411C8.68333 20.102 9.07459 20.4179 9.52261 20.511C9.54931 20.5284 9.58051 20.5376 9.61239 20.5376H9.72953C9.75259 20.5387 9.77562 20.5396 9.79883 20.5396C9.82196 20.5396 9.8451 20.5389 9.86831 20.5376H18.8347C18.926 20.5376 19 20.4636 19 20.3723C19 20.281 18.926 20.207 18.8346 20.207ZM17.212 10.2003L16.8487 10.003C16.7036 9.92445 16.4959 10.0268 16.3846 10.2319L13.361 15.8048C13.3475 15.8296 13.3406 15.857 13.3415 15.8821L13.3612 16.4987C13.3518 16.4993 13.3424 16.5012 13.3332 16.5047L12.394 16.8548C12.369 16.864 12.3488 16.8828 12.3378 16.907C12.3267 16.9312 12.3257 16.9588 12.335 16.9837C12.3443 17.0086 12.3631 17.0288 12.3873 17.0398C12.4115 17.0509 12.439 17.0519 12.4639 17.0426L13.368 16.7057L13.3682 16.7129C13.3704 16.7809 13.4263 16.8112 13.4844 16.7759L14.1955 16.3454C14.217 16.3324 14.2362 16.3118 14.2497 16.2869L17.2732 10.714C17.3845 10.509 17.3571 10.2789 17.212 10.2003ZM10.4528 17.5784L9.76355 17.8352C9.75121 17.8398 9.7399 17.8468 9.73026 17.8558C9.72063 17.8647 9.71285 17.8755 9.70738 17.8875C9.70191 17.8995 9.69885 17.9124 9.69838 17.9255C9.69791 17.9387 9.70004 17.9518 9.70464 17.9641C9.71392 17.9891 9.73272 18.0093 9.7569 18.0203C9.78107 18.0314 9.80864 18.0324 9.83355 18.0231L10.5228 17.7662C10.5352 17.7616 10.5465 17.7546 10.5561 17.7456C10.5658 17.7367 10.5735 17.7259 10.579 17.7139C10.5845 17.702 10.5875 17.689 10.588 17.6759C10.5885 17.6627 10.5864 17.6496 10.5818 17.6373C10.5772 17.6249 10.5702 17.6136 10.5613 17.604C10.5523 17.5943 10.5415 17.5865 10.5295 17.5811C10.5175 17.5756 10.5046 17.5725 10.4914 17.5721C10.4783 17.5716 10.4652 17.5737 10.4528 17.5784ZM11.893 17.0415L10.9538 17.3916C10.9414 17.3962 10.9301 17.4031 10.9205 17.4121C10.9108 17.4211 10.9031 17.4318 10.8976 17.4438C10.8921 17.4558 10.8891 17.4687 10.8886 17.4819C10.8881 17.495 10.8902 17.5081 10.8948 17.5205C10.9041 17.5454 10.9229 17.5656 10.9471 17.5766C10.9713 17.5877 10.9988 17.5887 11.0238 17.5794L11.963 17.2293C11.9753 17.2247 11.9866 17.2178 11.9963 17.2088C12.0059 17.1998 12.0137 17.1891 12.0192 17.1771C12.0247 17.1651 12.0277 17.1522 12.0282 17.139C12.0287 17.1258 12.0265 17.1127 12.0219 17.1004C12.0173 17.088 12.0103 17.0767 12.0014 17.0671C11.9924 17.0574 11.9816 17.0497 11.9697 17.0442C11.9577 17.0387 11.9448 17.0357 11.9316 17.0352C11.9184 17.0347 11.9053 17.0368 11.893 17.0415ZM9.1285 15.4922C9.10804 15.4922 9.08807 15.4859 9.07126 15.4743C9.05445 15.4626 9.04162 15.4461 9.03447 15.4269C9.02521 15.402 9.02621 15.3744 9.03725 15.3503C9.0483 15.3261 9.06848 15.3073 9.09337 15.298L9.68278 15.0783C9.7076 15.0694 9.73492 15.0707 9.75882 15.0818C9.78273 15.0929 9.80129 15.113 9.8105 15.1377C9.8197 15.1624 9.81881 15.1897 9.80801 15.2137C9.79721 15.2378 9.77737 15.2566 9.75279 15.2661L9.1634 15.4858C9.15224 15.49 9.14042 15.4922 9.1285 15.4922ZM10.2187 15.0858C10.1781 15.0858 10.1399 15.0608 10.1248 15.0204C10.1202 15.0081 10.1181 14.995 10.1186 14.9818C10.119 14.9686 10.1221 14.9557 10.1276 14.9437C10.133 14.9318 10.1408 14.921 10.1504 14.912C10.1601 14.9031 10.1714 14.8961 10.1837 14.8915L11.123 14.5414C11.1353 14.5368 11.1484 14.5346 11.1616 14.5351C11.1747 14.5356 11.1876 14.5387 11.1996 14.5441C11.2116 14.5496 11.2224 14.5574 11.2313 14.567C11.2403 14.5766 11.2473 14.5879 11.2519 14.6003C11.2565 14.6126 11.2586 14.6257 11.2581 14.6389C11.2577 14.652 11.2546 14.665 11.2492 14.677C11.2437 14.6889 11.2359 14.6997 11.2263 14.7087C11.2166 14.7177 11.2053 14.7246 11.193 14.7292L10.2537 15.0793C10.2425 15.0836 10.2307 15.0857 10.2187 15.0858ZM11.6589 14.549C11.6384 14.549 11.6185 14.5427 11.6017 14.531C11.5849 14.5194 11.5721 14.5029 11.565 14.4837C11.5604 14.4714 11.5582 14.4583 11.5587 14.4451C11.5592 14.432 11.5622 14.419 11.5677 14.407C11.5732 14.3951 11.5809 14.3843 11.5906 14.3753C11.6002 14.3664 11.6115 14.3594 11.6239 14.3548L12.5631 14.0046C12.5754 14 12.5886 13.9979 12.6017 13.9983C12.6149 13.9988 12.6278 14.0019 12.6398 14.0073C12.6517 14.0128 12.6625 14.0206 12.6715 14.0302C12.6804 14.0399 12.6874 14.0512 12.692 14.0635C12.6966 14.0758 12.6988 14.089 12.6983 14.1021C12.6978 14.1153 12.6948 14.1282 12.6893 14.1402C12.6838 14.1522 12.676 14.1629 12.6664 14.1719C12.6568 14.1809 12.6455 14.1878 12.6331 14.1924L11.6939 14.5425C11.6827 14.5468 11.6708 14.5489 11.6589 14.549ZM13.099 14.0121C13.0755 14.0121 13.0528 14.0038 13.0347 13.9887C13.0167 13.9737 13.0045 13.9527 13.0003 13.9296C12.9962 13.9065 13.0003 13.8826 13.0119 13.8622C13.0236 13.8418 13.042 13.8261 13.064 13.8179L14.0033 13.4678C14.0156 13.4632 14.0287 13.4611 14.0419 13.4615C14.055 13.462 14.068 13.4651 14.0799 13.4705C14.0919 13.476 14.1027 13.4838 14.1117 13.4934C14.1206 13.503 14.1276 13.5144 14.1322 13.5267C14.1368 13.539 14.1389 13.5521 14.1385 13.5653C14.138 13.5784 14.1349 13.5914 14.1295 13.6034C14.124 13.6153 14.1162 13.6261 14.1066 13.6351C14.0969 13.644 14.0856 13.651 14.0733 13.6556L13.1341 14.0057C13.1229 14.0099 13.111 14.0121 13.099 14.0121Z' />\n    </SvgIcon>\n  )\n}\n\nexport const CircleIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <circle cx='12' cy='12' r='3' />\n    </SvgIcon>\n  )\n}\n\nexport const GrowIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path d='M4 11L12 1L20 11L15 11C15 16.523 10.523 21 5 21C4.727 21 4.457 20.99 4.19 20.968C7.05 19.46 9 16.458 9 13L9 11L4 11Z' />\n    </SvgIcon>\n  )\n}\n\nexport const NoPhotosIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path d='M19.5861 21.0001H3.00007C2.73485 21.0001 2.4805 20.8947 2.29296 20.7072C2.10542 20.5196 2.00007 20.2653 2.00007 20.0001V6.00007C2.00007 5.73485 2.10542 5.4805 2.29296 5.29296C2.4805 5.10542 2.73485 5.00007 3.00007 5.00007H3.58607L1.39307 2.80807L2.80807 1.39307L22.6071 21.1931L21.1921 22.6071L19.5861 21.0001ZM5.58607 7.00007H4.00007V19.0001H17.5861L15.4061 16.8201C14.3486 17.657 13.0205 18.0762 11.6742 17.9981C10.3279 17.92 9.05726 17.35 8.10368 16.3965C7.1501 15.4429 6.5801 14.1722 6.502 12.8259C6.4239 11.4796 6.84315 10.1515 7.68007 9.09407L5.58607 7.00007V7.00007ZM9.11007 10.5251C8.64905 11.1988 8.43805 12.0125 8.51359 12.8254C8.58912 13.6383 8.94644 14.3992 9.5237 14.9764C10.101 15.5537 10.8619 15.911 11.6747 15.9865C12.4876 16.0621 13.3013 15.8511 13.9751 15.3901L9.11007 10.5251ZM22.0001 17.7851L20.0001 15.7851V7.00007H16.1721L14.1721 5.00007H9.82807L9.52107 5.30707L8.10707 3.89307L9.00007 3.00007H15.0001L17.0001 5.00007H21.0001C21.2653 5.00007 21.5196 5.10542 21.7072 5.29296C21.8947 5.4805 22.0001 5.73485 22.0001 6.00007V17.7861V17.7851ZM11.2631 7.05007C12.1024 6.93646 12.9567 7.01825 13.7592 7.28905C14.5618 7.55986 15.2909 8.01236 15.8898 8.61128C16.4888 9.21021 16.9413 9.93937 17.2121 10.7419C17.4829 11.5445 17.5647 12.3987 17.4511 13.2381L15.1131 10.9001C14.7783 10.2513 14.2499 9.72282 13.6011 9.38807L11.2631 7.05007V7.05007Z' />\n    </SvgIcon>\n  )\n}\n//\n// export const SellBuyBg = (props: SvgIconProps) => {\n//     return <SvgIcon {...props} width=\"18\" height=\"28\" viewBox=\"0 0 18 28\" fill=\"none\" >\n//         <path d=\"M0 0H12.4213C15.1599 0 17.0886 2.68993 16.2098 5.28363L9.43321 25.2836C8.88302 26.9074 7.35922 28 5.64476 28H0V0Z\" />\n//     </SvgIcon>\n// }\n\nexport const KLineFeaturesIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path d='M16.6122 7.62583L18.0264 9.04004L13.0766 13.9898L10.9233 11.8365L7.38778 15.372L5.97357 13.9578L10.9233 9.00805L13.0766 11.1614L16.6122 7.62583Z' />\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M21 3H3C2.73478 3 2.48043 3.10536 2.29289 3.29289C2.10536 3.48043 2 3.73478 2 4V20C2 20.2652 2.10536 20.5196 2.29289 20.7071C2.48043 20.8946 2.73478 21 3 21H21C21.2652 21 21.5196 20.8946 21.7071 20.7071C21.8946 20.5196 22 20.2652 22 20V4C22 3.73478 21.8946 3.48043 21.7071 3.29289C21.5196 3.10536 21.2652 3 21 3ZM4 19V5H20V19H4Z'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const LoopringDarkFooterIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='145' height='33' viewBox='0 0 145 33' fill='none'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M69.2692 32.321C69.8884 32.321 70.3802 32.1127 70.739 31.7019C71.0746 31.3084 71.2482 30.8049 71.2482 30.18C71.2482 29.5492 71.0746 29.04 70.739 28.6465C70.3802 28.2299 69.8884 28.0273 69.275 28.0273C68.6501 28.0273 68.164 28.2357 67.8052 28.6523C67.4638 29.0458 67.296 29.555 67.296 30.18C67.296 30.7991 67.4638 31.3084 67.8052 31.7019C68.164 32.1127 68.65 32.321 69.2692 32.321ZM51.5461 32.2399V30.4635H52.796C53.0564 30.4635 53.2531 30.5097 53.392 30.6139C53.5425 30.7181 53.6293 30.8974 53.6524 31.1405L53.7045 31.6902C53.7218 31.9217 53.7797 32.1011 53.8723 32.2399H54.3873C54.2658 32.0895 54.1906 31.887 54.1674 31.6324L54.1038 30.9958C54.0575 30.5792 53.8376 30.3304 53.4441 30.2436V30.232C53.6813 30.1741 53.8665 30.0584 54.0054 29.8732C54.1327 29.6938 54.1963 29.4913 54.1963 29.2598C54.1963 28.8779 54.069 28.5886 53.826 28.3918C53.5888 28.2009 53.2647 28.1083 52.8538 28.1083H51.0716V32.2399H51.5461ZM47.95 32.2403V30.3191H50.12V29.9082H47.95V28.5194H50.2415V28.1086H47.4755V32.2403H47.95ZM51.5461 30.0521H52.796C53.0969 30.0521 53.3342 29.9769 53.4962 29.838C53.6408 29.7049 53.7161 29.5198 53.7161 29.2767C53.7161 29.0221 53.6408 28.8312 53.502 28.7096C53.3515 28.5823 53.1143 28.5187 52.796 28.5187H51.5461V30.0521ZM58.267 32.2399V31.8291H55.7151V30.313H58.0297V29.9021H55.7151V28.5191H58.1686V28.1083H55.2406V32.2399H58.267ZM62.2102 31.8291V32.2399H59.1838V28.1083H62.1118V28.5191H59.6583V29.9021H61.9729V30.313H59.6583V31.8291H62.2102ZM64.5621 32.2399C65.2102 32.2399 65.7078 32.049 66.055 31.6729C66.3849 31.3141 66.5527 30.8106 66.5527 30.1741C66.5527 29.526 66.3964 29.0226 66.0897 28.6754C65.7541 28.2935 65.2623 28.1083 64.6084 28.1083H63.127V32.2399H64.5621ZM63.6016 31.8286H64.4812C65.0193 31.8286 65.4244 31.684 65.6964 31.4004C65.951 31.1227 66.0841 30.7118 66.0841 30.1737C66.0841 29.6181 65.9626 29.2073 65.7253 28.9411C65.4707 28.6576 65.0772 28.5187 64.5333 28.5187H63.6016V31.8286ZM68.1524 31.4127C68.4186 31.7368 68.7947 31.8988 69.2692 31.8988C69.7437 31.8988 70.1199 31.7368 70.386 31.4243C70.6407 31.1118 70.7738 30.701 70.7738 30.1802C70.7738 29.6536 70.6407 29.237 70.386 28.9245C70.1199 28.6062 69.7495 28.45 69.275 28.45C68.8005 28.45 68.4244 28.612 68.1524 28.9418C67.8978 29.2543 67.7705 29.6652 67.7705 30.1802C67.7705 30.6894 67.8978 31.1003 68.1524 31.4127ZM72.6395 32.2399V28.9531H72.6569L74.0862 32.2399H74.5144L75.9437 28.9531H75.9611V32.2399H76.4356V28.1083H75.8453L74.3119 31.6324H74.2945L72.7553 28.1083H72.165V32.2399H72.6395ZM80.2426 31.0826L79.8028 32.2399H79.2936L80.9197 28.1083H81.4694L83.0954 32.2399H82.5804L82.1406 31.0826H80.2426ZM81.9901 30.6833H80.393L81.1858 28.6175H81.2089L81.9901 30.6833ZM85.3779 28.5191V32.2399H84.9092V28.5191H83.451V28.1083H86.8362V28.5191H85.3779ZM91.5284 32.2399V30.5618L93.1776 28.1083H92.6047L91.2912 30.122L89.9776 28.1083H89.4047L91.0539 30.5618V32.2399H91.5284ZM97.1498 31.7019C96.7911 32.1127 96.2992 32.321 95.68 32.321C95.0609 32.321 94.5748 32.1127 94.216 31.7019C93.8746 31.3084 93.7068 30.7991 93.7068 30.18C93.7068 29.555 93.8746 29.0458 94.216 28.6523C94.5748 28.2357 95.0609 28.0273 95.6858 28.0273C96.2992 28.0273 96.7911 28.2299 97.1498 28.6465C97.4855 29.04 97.6591 29.5492 97.6591 30.18C97.6591 30.8049 97.4855 31.3084 97.1498 31.7019ZM95.6801 31.8988C95.2056 31.8988 94.8294 31.7368 94.5632 31.4127C94.3086 31.1003 94.1813 30.6894 94.1813 30.1802C94.1813 29.6652 94.3086 29.2543 94.5632 28.9418C94.8352 28.612 95.2113 28.45 95.6858 28.45C96.1603 28.45 96.5307 28.6062 96.7969 28.9245C97.0515 29.237 97.1846 29.6536 97.1846 30.1802C97.1846 30.701 97.0515 31.1118 96.7969 31.4243C96.5307 31.7368 96.1546 31.8988 95.6801 31.8988ZM101.464 31.887C101.18 32.1763 100.769 32.321 100.225 32.321C99.6812 32.321 99.2704 32.1763 98.9926 31.8927C98.7149 31.6034 98.576 31.1926 98.576 30.6544V28.1083H99.0505V30.6602C99.0505 31.0653 99.1373 31.372 99.3224 31.5803C99.5134 31.7944 99.8143 31.9043 100.225 31.9043C100.63 31.9043 100.931 31.7944 101.128 31.5803C101.307 31.372 101.4 31.0653 101.4 30.6602V28.1083H101.874V30.6544C101.874 31.1926 101.735 31.6034 101.464 31.887ZM103.439 32.2399V30.4635H104.689C104.95 30.4635 105.146 30.5097 105.285 30.6139C105.436 30.7181 105.522 30.8974 105.546 31.1405L105.598 31.6902C105.615 31.9217 105.673 32.1011 105.765 32.2399H106.281C106.159 32.0895 106.084 31.887 106.061 31.6324L105.997 30.9958C105.951 30.5792 105.731 30.3304 105.337 30.2436V30.232C105.575 30.1741 105.76 30.0584 105.899 29.8732C106.026 29.6938 106.09 29.4913 106.09 29.2598C106.09 28.8779 105.962 28.5886 105.719 28.3918C105.482 28.2009 105.158 28.1083 104.747 28.1083H102.965V32.2399H103.439ZM103.439 30.0521H104.689C104.99 30.0521 105.227 29.9769 105.389 29.838C105.534 29.7049 105.609 29.5198 105.609 29.2767C105.609 29.0221 105.534 28.8312 105.395 28.7096C105.245 28.5823 105.007 28.5187 104.689 28.5187H103.439V30.0521ZM109.792 32.2399V30.3188H111.962V29.9079H109.792V28.5191H112.084V28.1083H109.318V32.2399H109.792ZM113.417 28.1083V32.2399H112.949V28.1083H113.417ZM115.017 32.2399V28.8432H115.034L117.384 32.2399H117.87V28.1083H117.395V31.4703H117.378L115.04 28.1083H114.543V32.2399H115.017ZM121.773 32.1821C121.472 32.2747 121.154 32.321 120.812 32.321C120.158 32.321 119.649 32.1127 119.29 31.6961C118.955 31.3084 118.787 30.8049 118.787 30.1915C118.787 29.5782 118.949 29.0747 119.284 28.6754C119.637 28.2414 120.118 28.0273 120.725 28.0273C121.24 28.0273 121.651 28.1489 121.958 28.4035C122.247 28.6407 122.427 28.9821 122.502 29.4335H122.027C121.964 29.121 121.825 28.8838 121.611 28.716C121.385 28.5366 121.09 28.4498 120.725 28.4498C120.274 28.4498 119.921 28.606 119.655 28.9243C119.389 29.2368 119.261 29.6592 119.261 30.1915C119.261 30.7123 119.389 31.1232 119.643 31.4241C119.915 31.7424 120.32 31.9044 120.858 31.9044C121.084 31.9044 121.298 31.8697 121.507 31.8118C121.709 31.7539 121.883 31.6729 122.027 31.5803V30.5272H120.731V30.1163H122.496V31.806C122.299 31.968 122.056 32.0896 121.773 32.1821ZM126.572 32.2399V31.8291H124.02V30.313H126.335V29.9021H124.02V28.5191H126.474V28.1083H123.546V32.2399H126.572ZM127.964 30.4635V32.2399H127.489V28.1083H129.271C129.682 28.1083 130.006 28.2009 130.244 28.3918C130.487 28.5886 130.614 28.8779 130.614 29.2598C130.614 29.4913 130.55 29.6938 130.423 29.8732C130.284 30.0584 130.099 30.1741 129.862 30.232V30.2436C130.255 30.3304 130.475 30.5792 130.521 30.9958L130.585 31.6324C130.608 31.887 130.683 32.0895 130.805 32.2399H130.29C130.197 32.1011 130.139 31.9217 130.122 31.6902L130.07 31.1405C130.047 30.8974 129.96 30.7181 129.81 30.6139C129.671 30.5097 129.474 30.4635 129.214 30.4635H127.964ZM129.214 30.0521H127.964V28.5187H129.214C129.532 28.5187 129.769 28.5823 129.92 28.7096C130.058 28.8312 130.134 29.0221 130.134 29.2767C130.134 29.5198 130.058 29.7049 129.914 29.838C129.752 29.9769 129.514 30.0521 129.214 30.0521ZM133.267 28.5191V32.2399H132.798V28.5191H131.34V28.1083H134.725V28.5191H133.267ZM136.001 32.2399V28.1083H135.532V32.2399H136.001ZM137.6 30.5503V32.2399H137.126V28.1083H138.816C139.765 28.1083 140.239 28.5134 140.239 29.3235C140.239 30.1394 139.759 30.5503 138.81 30.5503H137.6ZM138.787 30.1389H137.6V28.5187H138.787C139.116 28.5187 139.36 28.5823 139.522 28.7212C139.684 28.8427 139.765 29.0453 139.765 29.323C139.765 29.6008 139.684 29.8033 139.527 29.9364C139.365 30.0695 139.122 30.1389 138.787 30.1389ZM143.719 32.0143C143.43 32.2169 143.042 32.321 142.55 32.321C142.064 32.321 141.682 32.2169 141.405 32.0085C141.081 31.7597 140.901 31.3836 140.867 30.8744H141.335C141.376 31.2331 141.503 31.4993 141.711 31.6671C141.902 31.8176 142.18 31.8986 142.55 31.8986C142.886 31.8986 143.164 31.8349 143.372 31.7076C143.581 31.5803 143.685 31.4067 143.685 31.1868C143.685 30.9264 143.546 30.7239 143.274 30.5792C143.158 30.5098 142.863 30.4114 142.4 30.2783C141.902 30.1279 141.584 30.0122 141.451 29.9427C141.133 29.7575 140.977 29.4914 140.977 29.1442C140.977 28.7854 141.127 28.5018 141.434 28.3051C141.706 28.1199 142.059 28.0273 142.487 28.0273C142.95 28.0273 143.32 28.1315 143.586 28.3456C143.864 28.5655 144.02 28.8953 144.061 29.3293H143.592C143.54 29.0284 143.424 28.8085 143.245 28.6639C143.06 28.5134 142.799 28.444 142.464 28.444C142.157 28.444 141.92 28.4903 141.746 28.5944C141.549 28.7102 141.451 28.8838 141.451 29.121C141.451 29.3293 141.567 29.4971 141.804 29.6245C141.908 29.6823 142.163 29.7691 142.562 29.8849C143.106 30.0469 143.465 30.18 143.638 30.2841C143.98 30.4924 144.153 30.7818 144.153 31.1579C144.153 31.5167 144.009 31.806 143.719 32.0143Z'\n        fill='#FCFDFD'\n      />\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M23.787 15.9745H41.115V16.0782L14.0595 32.5761L27.4705 21.8369L23.787 15.9745ZM13.6963 0.0732422V32.8096L0 21.8629L13.6963 0.0732422Z'\n        fill='#FCFDFD'\n      />\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M84.1605 6.28613V7.82151H82.6251V6.28613H84.1605ZM52.4832 16.9976V15.4622H47.2673V6.28663H45.6438V16.9976H52.4832ZM56.6412 17.0857C57.2436 17.0759 57.7309 16.9657 58.1031 16.7551C58.3039 16.6669 58.468 16.5616 58.5953 16.4392C58.7373 16.3315 58.8573 16.2213 58.9553 16.1086C59.2589 15.8001 59.4744 15.4352 59.6018 15.014C59.7242 14.5928 59.7854 13.9806 59.7854 13.1774C59.7854 12.3742 59.7242 11.7571 59.6018 11.3262C59.4744 10.905 59.2589 10.5499 58.9553 10.2609C58.7545 10.0063 58.4704 9.77854 58.1031 9.57774C57.7309 9.38674 57.2436 9.28634 56.6412 9.27654C56.0584 9.28634 55.5809 9.38674 55.2087 9.57774C54.8316 9.77854 54.5377 10.0063 54.3271 10.2609C54.0431 10.5499 53.8325 10.905 53.6953 11.3262C53.5631 11.7571 53.497 12.3742 53.497 13.1774C53.497 13.9806 53.5631 14.5928 53.6953 15.014C53.8325 15.4352 54.0431 15.8001 54.3271 16.1086C54.5377 16.3486 54.8316 16.5641 55.2087 16.7551C55.5809 16.9657 56.0584 17.0759 56.6412 17.0857ZM55.9212 15.3885C56.1416 15.4963 56.3816 15.5501 56.6411 15.5501C56.9203 15.5501 57.1652 15.4963 57.3758 15.3885C57.5962 15.2759 57.7627 15.1461 57.8753 14.9991C58.0272 14.8081 58.1276 14.5878 58.1765 14.338C58.2255 14.0931 58.25 13.7111 58.25 13.192C58.25 12.6483 58.2255 12.2516 58.1765 12.0019C58.1276 11.7619 58.0272 11.5513 57.8753 11.3701C57.7627 11.1987 57.5962 11.064 57.3758 10.966C57.1652 10.8632 56.9203 10.8118 56.6411 10.8118C56.3816 10.8118 56.1416 10.8632 55.9212 10.966C55.7106 11.064 55.5392 11.1987 55.407 11.3701C55.2747 11.5513 55.1792 11.7619 55.1205 12.0019C55.0617 12.2516 55.0323 12.6434 55.0323 13.1773C55.0323 13.7062 55.0617 14.0931 55.1205 14.338C55.1792 14.5878 55.2747 14.8081 55.407 14.9991C55.5392 15.1461 55.7106 15.2759 55.9212 15.3885ZM64.1638 17.0857C64.7662 17.0759 65.2535 16.9657 65.6257 16.7551C65.8265 16.6669 65.9906 16.5616 66.1179 16.4392C66.26 16.3315 66.38 16.2213 66.4779 16.1086C66.7816 15.8001 66.997 15.4352 67.1244 15.014C67.2468 14.5928 67.308 13.9806 67.308 13.1774C67.308 12.3742 67.2468 11.7571 67.1244 11.3262C66.997 10.905 66.7816 10.5499 66.4779 10.2609C66.2771 10.0063 65.993 9.77854 65.6257 9.57774C65.2535 9.38674 64.7662 9.28634 64.1638 9.27654C63.581 9.28634 63.1035 9.38674 62.7313 9.57774C62.3542 9.77854 62.0603 10.0063 61.8497 10.2609C61.5657 10.5499 61.3551 10.905 61.2179 11.3262C61.0857 11.7571 61.0196 12.3742 61.0196 13.1774C61.0196 13.9806 61.0857 14.5928 61.2179 15.014C61.3551 15.4352 61.5657 15.8001 61.8497 16.1086C62.0603 16.3486 62.3542 16.5641 62.7313 16.7551C63.1035 16.9657 63.581 17.0759 64.1638 17.0857ZM63.4438 15.3885C63.6642 15.4963 63.9042 15.5501 64.1638 15.5501C64.4429 15.5501 64.6878 15.4963 64.8984 15.3885C65.1188 15.2759 65.2853 15.1461 65.3979 14.9991C65.5498 14.8081 65.6502 14.5878 65.6991 14.338C65.7481 14.0931 65.7726 13.7111 65.7726 13.192C65.7726 12.6483 65.7481 12.2516 65.6991 12.0019C65.6502 11.7619 65.5498 11.5513 65.3979 11.3701C65.2853 11.1987 65.1188 11.064 64.8984 10.966C64.6878 10.8632 64.4429 10.8118 64.1638 10.8118C63.9042 10.8118 63.6642 10.8632 63.4438 10.966C63.2332 11.064 63.0618 11.1987 62.9296 11.3701C62.7974 11.5513 62.7019 11.7619 62.6431 12.0019C62.5843 12.2516 62.5549 12.6434 62.5549 13.1773C62.5549 13.7062 62.5843 14.0931 62.6431 14.338C62.7019 14.5878 62.7974 14.8081 62.9296 14.9991C63.0618 15.1461 63.2332 15.2759 63.4438 15.3885ZM70.4522 20.083V16.1821C70.7314 16.4563 71.0375 16.6718 71.3705 16.8286C71.6791 17 72.0292 17.0857 72.421 17.0857C72.8961 17.0759 73.3026 16.9804 73.6405 16.7992C73.9833 16.6229 74.2601 16.3878 74.4707 16.0939C74.6813 15.8441 74.8257 15.5234 74.9041 15.1316C74.9775 14.7397 75.0143 14.0933 75.0143 13.1921C75.0143 12.2665 74.9775 11.6102 74.9041 11.2233C74.8257 10.8315 74.6813 10.5156 74.4707 10.2756C74.0397 9.63406 73.3565 9.30103 72.421 9.27654C71.6178 9.30103 70.9616 9.59733 70.4522 10.1654V9.37205H68.9168V20.083H70.4522ZM71.1428 15.3297C71.3436 15.4767 71.6155 15.5501 71.9583 15.5501C72.3207 15.5501 72.6072 15.4816 72.8178 15.3444C73.0284 15.2024 73.1778 15.0212 73.2659 14.8008C73.3639 14.5706 73.43 14.3159 73.4643 14.0368C73.4741 13.7625 73.479 13.4809 73.479 13.192C73.479 12.8883 73.4741 12.592 73.4643 12.3031C73.43 12.0141 73.3639 11.7594 73.2659 11.539C73.1778 11.3089 73.0284 11.1276 72.8178 10.9954C72.6072 10.873 72.3207 10.8118 71.9583 10.8118C71.6155 10.8118 71.3436 10.8828 71.1428 11.0248C70.9322 11.1668 70.778 11.3529 70.68 11.5831C70.587 11.8133 70.5257 12.0631 70.4964 12.3324C70.467 12.6165 70.4523 12.903 70.4523 13.192C70.4523 13.4613 70.467 13.7307 70.4964 14.0001C70.5257 14.2841 70.587 14.5412 70.68 14.7714C70.778 15.0016 70.9322 15.1877 71.1428 15.3297ZM78.2613 16.9975V12.4061C78.2711 11.8478 78.4328 11.4437 78.7462 11.1939C79.0254 10.9393 79.3608 10.8119 79.7526 10.8119C80.1004 10.8119 80.4358 10.9393 80.7591 11.1939L81.8757 9.86425C81.4202 9.48224 80.8864 9.28634 80.2742 9.27654C79.4563 9.27654 78.7952 9.57774 78.2907 10.1801H78.2613V9.37205H76.726V16.9975H78.2613ZM84.1605 16.9971V9.37161H82.6251V16.9971H84.1605ZM87.7234 12.4575V16.9975H86.1881V9.37205H87.7234V10.1801H87.7528C88.2573 9.57774 88.9184 9.27654 89.7363 9.27654C90.3681 9.27654 90.946 9.49938 91.4701 9.94506C91.9892 10.3956 92.261 11.0568 92.2855 11.9286V16.9975H90.7501V12.4575C90.7501 11.9237 90.6081 11.5172 90.324 11.238C90.0449 10.954 89.6849 10.8119 89.2441 10.8119C88.8033 10.8119 88.4409 10.954 88.1569 11.238C87.8679 11.5172 87.7234 11.9237 87.7234 12.4575ZM96.7814 20.1711C97.6826 20.1711 98.4564 19.8944 99.1029 19.341C99.7444 18.8023 100.075 17.9599 100.095 16.8139V9.37205H98.5592V10.1801C98.0058 9.57774 97.3495 9.27654 96.5904 9.27654C96.0958 9.28634 95.6844 9.38184 95.3562 9.56305C95.0134 9.75405 94.7514 9.96954 94.5702 10.2095C94.3694 10.4544 94.2249 10.7556 94.1368 11.1131C94.0437 11.4755 93.9972 12.1685 93.9972 13.1921C93.9972 14.1961 94.0437 14.8769 94.1368 15.2344C94.2249 15.5968 94.3694 15.9029 94.5702 16.1527C94.7514 16.3731 95.0134 16.5788 95.3562 16.7698C95.6844 16.9706 96.0958 17.0759 96.5904 17.0857C97.3985 17.0661 98.0548 16.7698 98.5592 16.1968V16.9828C98.5494 17.502 98.3878 17.9085 98.0744 18.2023C97.756 18.4913 97.3349 18.6357 96.8108 18.6357C96.5317 18.6259 96.2623 18.55 96.0027 18.408C95.748 18.2807 95.5228 18.1264 95.3269 17.9452L94.1368 18.8929C94.8665 19.7254 95.748 20.1515 96.7814 20.1711ZM96.3039 15.3444C96.5047 15.4816 96.7544 15.5501 97.0532 15.5501C97.3519 15.5501 97.6017 15.4816 97.8025 15.3444C98.0033 15.2318 98.1551 15.1069 98.258 14.9698C98.3853 14.8179 98.471 14.6269 98.5151 14.3968C98.5445 14.1764 98.5592 13.7748 98.5592 13.192C98.5592 12.5994 98.5445 12.188 98.5151 11.9578C98.471 11.7276 98.3853 11.5415 98.258 11.3995C98.1551 11.2623 98.0033 11.1276 97.8025 10.9954C97.6017 10.8828 97.3519 10.8215 97.0532 10.8118C96.7544 10.8215 96.5047 10.8828 96.3039 10.9954C96.0933 11.1276 95.9366 11.2623 95.8337 11.3995C95.7064 11.5415 95.6256 11.7276 95.5913 11.9578C95.5521 12.188 95.5325 12.5994 95.5325 13.192C95.5325 13.7748 95.5521 14.1764 95.5913 14.3968C95.6256 14.6269 95.7064 14.8179 95.8337 14.9698C95.9366 15.1069 96.0933 15.2318 96.3039 15.3444ZM108.888 16.9971L110.938 9.27608H110.967L113.009 16.9971H114.368L117.043 6.28613H115.331L113.641 13.8969H113.612L111.54 6.28613H110.365L108.286 13.8969H108.256L106.574 6.28613H104.862L107.536 16.9971H108.888ZM121.516 16.8945C121.223 17.0218 120.816 17.0855 120.297 17.0855C119.445 17.0757 118.789 16.8504 118.328 16.4096C117.843 15.9786 117.601 15.4276 117.601 14.7567C117.601 14.1151 117.811 13.5837 118.233 13.1625C118.654 12.7316 119.271 12.5112 120.084 12.5014H122.207V11.7006C122.217 11.0297 121.695 10.704 120.642 10.7236C120.26 10.7236 119.959 10.7627 119.739 10.8411C119.508 10.9342 119.327 11.0909 119.195 11.3113L117.99 10.393C118.573 9.62896 119.433 9.25675 120.569 9.27634C121.529 9.26654 122.295 9.44775 122.868 9.81996C123.441 10.202 123.733 10.8582 123.742 11.7888V16.9973H122.207V16.3214H122.178C122.036 16.581 121.815 16.772 121.516 16.8945ZM120.488 15.6452C119.979 15.6452 119.614 15.5448 119.393 15.344C119.163 15.1628 119.048 14.9424 119.048 14.6828C119.038 14.0902 119.479 13.7841 120.37 13.7645H122.207V14.3155C122.207 14.8885 122.087 15.2558 121.847 15.4174C121.583 15.5791 121.13 15.655 120.488 15.6452ZM128.363 15.5498V16.9971H127.68C127.122 16.9971 126.661 16.8575 126.299 16.5783C125.917 16.2943 125.726 15.8167 125.726 15.1458V6.28613H127.261V15.0282C127.261 15.376 127.452 15.5498 127.834 15.5498H128.363ZM132.242 16.9971V15.5498H131.713C131.331 15.5498 131.14 15.376 131.14 15.0282V6.28613H129.605V15.1458C129.605 15.8167 129.796 16.2943 130.178 16.5783C130.54 16.8575 131.001 16.9971 131.559 16.9971H132.242ZM139.243 15.8515C138.464 16.6841 137.549 17.0955 136.496 17.0857C136.094 17.0857 135.702 17.0269 135.32 16.9094C135.129 16.8457 134.943 16.76 134.762 16.6522C134.571 16.5592 134.392 16.4441 134.226 16.307C133.902 16.0229 133.64 15.6262 133.439 15.1169C133.219 14.6271 133.109 13.9904 133.109 13.2068C133.109 12.4526 133.204 11.8257 133.395 11.3262C133.586 10.8168 133.831 10.4152 134.13 10.1214C134.434 9.82262 134.774 9.60713 135.151 9.47489C135.523 9.34266 135.891 9.27654 136.253 9.27654C137.125 9.28634 137.862 9.57284 138.464 10.1361C139.077 10.7091 139.388 11.4976 139.397 12.5016V13.7651H134.644C134.644 14.3773 134.821 14.8426 135.173 15.1609C135.501 15.4842 135.932 15.6458 136.466 15.6458C137.088 15.6458 137.644 15.3985 138.134 14.9038L139.243 15.8515ZM134.644 12.5011C134.674 11.9085 134.833 11.4604 135.122 11.1567C135.416 10.8678 135.793 10.7233 136.253 10.7233C136.714 10.7233 137.091 10.8678 137.385 11.1567C137.683 11.4604 137.842 11.9085 137.862 12.5011H134.644ZM143.746 15.5501V16.9973H142.946C142.407 16.9973 141.966 16.8308 141.623 16.4978C141.271 16.1795 141.094 15.7191 141.094 15.1167V10.5399H140.33V9.37188H141.094V7.05044H142.63V9.37188H143.746V10.5399H142.63V14.9845C142.62 15.3714 142.801 15.5599 143.173 15.5501H143.746Z'\n        fill='#FCFDFD'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const LoopringLightFooterIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='145' height='33' viewBox='0 0 145 33' fill='none'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M69.329 32.2478C69.9481 32.2478 70.44 32.0395 70.7988 31.6286C71.1344 31.2351 71.308 30.7317 71.308 30.1067C71.308 29.476 71.1344 28.9668 70.7988 28.5733C70.44 28.1566 69.9481 27.9541 69.3348 27.9541C68.7098 27.9541 68.2237 28.1624 67.865 28.5791C67.5235 28.9725 67.3557 29.4818 67.3557 30.1067C67.3557 30.7259 67.5235 31.2351 67.865 31.6286C68.2237 32.0395 68.7098 32.2478 69.329 32.2478ZM51.6058 32.1667V30.3902H52.8557C53.1161 30.3902 53.3129 30.4365 53.4518 30.5407C53.6022 30.6448 53.689 30.8242 53.7122 31.0672L53.7642 31.617C53.7816 31.8484 53.8395 32.0278 53.932 32.1667H54.4471C54.3255 32.0163 54.2503 31.8137 54.2272 31.5591L54.1635 30.9226C54.1172 30.5059 53.8973 30.2571 53.5038 30.1703V30.1587C53.7411 30.1009 53.9263 29.9851 54.0651 29.8C54.1924 29.6206 54.2561 29.4181 54.2561 29.1866C54.2561 28.8047 54.1288 28.5153 53.8858 28.3186C53.6485 28.1276 53.3245 28.0351 52.9136 28.0351H51.1313V32.1667H51.6058ZM48.0097 32.167V30.2458H50.1797V29.835H48.0097V28.4462H50.3012V28.0354H47.5352V32.167H48.0097ZM51.6058 29.9789H52.8557C53.1567 29.9789 53.3939 29.9037 53.5559 29.7648C53.7006 29.6317 53.7758 29.4465 53.7758 29.2035C53.7758 28.9489 53.7006 28.7579 53.5617 28.6364C53.4113 28.5091 53.174 28.4454 52.8557 28.4454H51.6058V29.9789ZM58.3267 32.1667V31.7559H55.7748V30.2398H58.0895V29.8289H55.7748V28.4459H58.2284V28.0351H55.3003V32.1667H58.3267ZM62.2699 31.7559V32.1667H59.2435V28.0351H62.1716V28.4459H59.718V29.8289H62.0327V30.2398H59.718V31.7559H62.2699ZM64.6218 32.1667C65.2699 32.1667 65.7676 31.9757 66.1148 31.5996C66.4446 31.2408 66.6124 30.7374 66.6124 30.1009C66.6124 29.4528 66.4562 28.9493 66.1495 28.6021C65.8139 28.2202 65.322 28.0351 64.6681 28.0351H63.1867V32.1667H64.6218ZM63.6614 31.7554H64.5409C65.0791 31.7554 65.4842 31.6107 65.7561 31.3272C66.0107 31.0494 66.1438 30.6386 66.1438 30.1004C66.1438 29.5449 66.0223 29.1341 65.7851 28.8679C65.5305 28.5843 65.137 28.4454 64.593 28.4454H63.6614V31.7554ZM68.2122 31.3395C68.4783 31.6635 68.8545 31.8256 69.329 31.8256C69.8035 31.8256 70.1796 31.6635 70.4458 31.3511C70.7004 31.0386 70.8335 30.6277 70.8335 30.1069C70.8335 29.5804 70.7004 29.1637 70.4458 28.8512C70.1796 28.533 69.8093 28.3767 69.3348 28.3767C68.8603 28.3767 68.4841 28.5388 68.2122 28.8686C67.9576 29.1811 67.8302 29.5919 67.8302 30.1069C67.8302 30.6162 67.9576 31.027 68.2122 31.3395ZM72.6993 32.1667V28.8799H72.7167L74.146 32.1667H74.5742L76.0035 28.8799H76.0208V32.1667H76.4953V28.0351H75.9051L74.3716 31.5591H74.3543L72.815 28.0351H72.2248V32.1667H72.6993ZM80.3024 31.0094L79.8626 32.1667H79.3534L80.9794 28.0351H81.5291L83.1552 32.1667H82.6402L82.2004 31.0094H80.3024ZM82.0499 30.6101H80.4528L81.2455 28.5443H81.2687L82.0499 30.6101ZM85.4377 28.4459V32.1667H84.969V28.4459H83.5107V28.0351H86.8959V28.4459H85.4377ZM91.5882 32.1667V30.4886L93.2374 28.0351H92.6645L91.3509 30.0488L90.0374 28.0351H89.4645L91.1137 30.4886V32.1667H91.5882ZM97.2096 31.6286C96.8508 32.0395 96.359 32.2478 95.7398 32.2478C95.1206 32.2478 94.6345 32.0395 94.2758 31.6286C93.9344 31.2351 93.7665 30.7259 93.7665 30.1067C93.7665 29.4818 93.9344 28.9725 94.2758 28.5791C94.6345 28.1624 95.1206 27.9541 95.7456 27.9541C96.359 27.9541 96.8508 28.1566 97.2096 28.5733C97.5452 28.9668 97.7188 29.476 97.7188 30.1067C97.7188 30.7317 97.5452 31.2351 97.2096 31.6286ZM95.7398 31.8256C95.2653 31.8256 94.8892 31.6635 94.623 31.3395C94.3684 31.027 94.2411 30.6162 94.2411 30.1069C94.2411 29.5919 94.3684 29.1811 94.623 28.8686C94.895 28.5388 95.2711 28.3767 95.7456 28.3767C96.2201 28.3767 96.5904 28.533 96.8566 28.8512C97.1112 29.1637 97.2443 29.5804 97.2443 30.1069C97.2443 30.6277 97.1112 31.0386 96.8566 31.3511C96.5904 31.6635 96.2143 31.8256 95.7398 31.8256ZM101.523 31.8137C101.24 32.1031 100.829 32.2477 100.285 32.2477C99.741 32.2477 99.3301 32.1031 99.0524 31.8195C98.7746 31.5302 98.6357 31.1193 98.6357 30.5812V28.0351H99.1102V30.587C99.1102 30.992 99.197 31.2987 99.3822 31.507C99.5732 31.7211 99.8741 31.8311 100.285 31.8311C100.69 31.8311 100.991 31.7211 101.188 31.507C101.367 31.2987 101.46 30.992 101.46 30.587V28.0351H101.934V30.5812C101.934 31.1193 101.795 31.5302 101.523 31.8137ZM103.499 32.1667V30.3902H104.749C105.009 30.3902 105.206 30.4365 105.345 30.5407C105.495 30.6448 105.582 30.8242 105.605 31.0672L105.657 31.617C105.675 31.8484 105.733 32.0278 105.825 32.1667H106.34C106.219 32.0163 106.144 31.8137 106.12 31.5591L106.057 30.9226C106.01 30.5059 105.791 30.2571 105.397 30.1703V30.1587C105.634 30.1009 105.819 29.9851 105.958 29.8C106.086 29.6206 106.149 29.4181 106.149 29.1866C106.149 28.8047 106.022 28.5153 105.779 28.3186C105.542 28.1276 105.218 28.0351 104.807 28.0351H103.025V32.1667H103.499ZM103.499 29.9789H104.749C105.05 29.9789 105.287 29.9037 105.449 29.7648C105.594 29.6317 105.669 29.4465 105.669 29.2035C105.669 28.9489 105.594 28.7579 105.455 28.6364C105.304 28.5091 105.067 28.4454 104.749 28.4454H103.499V29.9789ZM109.852 32.1667V30.2455H112.022V29.8347H109.852V28.4459H112.144V28.0351H109.378V32.1667H109.852ZM113.477 28.0351V32.1667H113.008V28.0351H113.477ZM115.077 32.1667V28.77H115.094L117.444 32.1667H117.93V28.0351H117.455V31.3971H117.438L115.1 28.0351H114.602V32.1667H115.077ZM121.832 32.1089C121.532 32.2015 121.213 32.2478 120.872 32.2478C120.218 32.2478 119.709 32.0395 119.35 31.6228C119.014 31.2351 118.847 30.7317 118.847 30.1183C118.847 29.5049 119.009 29.0015 119.344 28.6022C119.697 28.1682 120.177 27.9541 120.785 27.9541C121.3 27.9541 121.711 28.0756 122.018 28.3302C122.307 28.5675 122.486 28.9089 122.562 29.3603H122.087C122.023 29.0478 121.885 28.8105 121.67 28.6427C121.445 28.4633 121.15 28.3765 120.785 28.3765C120.334 28.3765 119.981 28.5328 119.715 28.851C119.448 29.1635 119.321 29.5859 119.321 30.1183C119.321 30.6391 119.448 31.0499 119.703 31.3509C119.975 31.6691 120.38 31.8311 120.918 31.8311C121.144 31.8311 121.358 31.7964 121.566 31.7386C121.769 31.6807 121.942 31.5997 122.087 31.5071V30.4539H120.791V30.0431H122.556V31.7328C122.359 31.8948 122.116 32.0163 121.832 32.1089ZM126.632 32.1667V31.7559H124.08V30.2398H126.395V29.8289H124.08V28.4459H126.534V28.0351H123.606V32.1667H126.632ZM128.023 30.3902V32.1667H127.549V28.0351H129.331C129.742 28.0351 130.066 28.1276 130.303 28.3186C130.546 28.5153 130.674 28.8047 130.674 29.1866C130.674 29.4181 130.61 29.6206 130.483 29.8C130.344 29.9851 130.159 30.1009 129.921 30.1587V30.1703C130.315 30.2571 130.535 30.5059 130.581 30.9226L130.645 31.5591C130.668 31.8137 130.743 32.0163 130.865 32.1667H130.35C130.257 32.0278 130.199 31.8484 130.182 31.617L130.13 31.0672C130.107 30.8242 130.02 30.6448 129.869 30.5407C129.73 30.4365 129.534 30.3902 129.273 30.3902H128.023ZM129.273 29.9789H128.023V28.4454H129.273C129.592 28.4454 129.829 28.5091 129.979 28.6364C130.118 28.7579 130.193 28.9489 130.193 29.2035C130.193 29.4465 130.118 29.6317 129.974 29.7648C129.811 29.9037 129.574 29.9789 129.273 29.9789ZM133.327 28.4459V32.1667H132.858V28.4459H131.4V28.0351H134.785V28.4459H133.327ZM136.06 32.1667V28.0351H135.592V32.1667H136.06ZM137.66 30.477V32.1667H137.186V28.0351H138.875C139.824 28.0351 140.299 28.4401 140.299 29.2502C140.299 30.0662 139.819 30.477 138.87 30.477H137.66ZM138.846 30.0657H137.66V28.4454H138.846C139.176 28.4454 139.419 28.5091 139.581 28.648C139.743 28.7695 139.824 28.972 139.824 29.2498C139.824 29.5275 139.743 29.7301 139.587 29.8632C139.425 29.9963 139.182 30.0657 138.846 30.0657ZM143.779 31.9411C143.49 32.1436 143.102 32.2478 142.61 32.2478C142.124 32.2478 141.742 32.1436 141.464 31.9353C141.14 31.6865 140.961 31.3103 140.926 30.8011H141.395C141.436 31.1599 141.563 31.4261 141.771 31.5939C141.962 31.7443 142.24 31.8254 142.61 31.8254C142.946 31.8254 143.224 31.7617 143.432 31.6344C143.64 31.5071 143.744 31.3335 143.744 31.1136C143.744 30.8532 143.606 30.6507 143.334 30.506C143.218 30.4366 142.923 30.3382 142.46 30.2051C141.962 30.0546 141.644 29.9389 141.511 29.8695C141.193 29.6843 141.036 29.4181 141.036 29.0709C141.036 28.7122 141.187 28.4286 141.493 28.2319C141.765 28.0467 142.118 27.9541 142.547 27.9541C143.01 27.9541 143.38 28.0583 143.646 28.2724C143.924 28.4923 144.08 28.8221 144.121 29.2561H143.652C143.6 28.9552 143.484 28.7353 143.305 28.5906C143.119 28.4402 142.859 28.3707 142.523 28.3707C142.217 28.3707 141.98 28.417 141.806 28.5212C141.609 28.6369 141.511 28.8105 141.511 29.0478C141.511 29.2561 141.627 29.4239 141.864 29.5512C141.968 29.6091 142.223 29.6959 142.622 29.8116C143.166 29.9736 143.525 30.1067 143.698 30.2109C144.04 30.4192 144.213 30.7085 144.213 31.0847C144.213 31.4434 144.068 31.7328 143.779 31.9411Z'\n        fill='#3B5AF4'\n      />\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M23.8468 15.9012H41.1747V16.005L14.1193 32.5029L27.5303 21.7637L23.8468 15.9012ZM13.7561 0V32.7363L0.0597534 21.7896L13.7561 0Z'\n        fill='#3B5AF4'\n      />\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M84.2203 6.21289V7.74827H82.6849V6.21289H84.2203ZM52.543 16.9243V15.3889H47.3271V6.21339H45.7036V16.9243H52.543ZM56.701 17.0124C57.3034 17.0026 57.7907 16.8924 58.1629 16.6818C58.3637 16.5937 58.5277 16.4884 58.6551 16.366C58.7971 16.2582 58.9171 16.148 59.015 16.0354C59.3187 15.7268 59.5342 15.362 59.6615 14.9408C59.784 14.5196 59.8452 13.9074 59.8452 13.1042C59.8452 12.301 59.784 11.6839 59.6615 11.2529C59.5342 10.8317 59.3187 10.4767 59.015 10.1877C58.8142 9.93303 58.5302 9.7053 58.1629 9.5045C57.7907 9.3135 57.3034 9.2131 56.701 9.2033C56.1181 9.2131 55.6406 9.3135 55.2684 9.5045C54.8913 9.7053 54.5975 9.93303 54.3869 10.1877C54.1028 10.4767 53.8922 10.8317 53.7551 11.2529C53.6228 11.6839 53.5567 12.301 53.5567 13.1042C53.5567 13.9074 53.6228 14.5196 53.7551 14.9408C53.8922 15.362 54.1028 15.7268 54.3869 16.0354C54.5975 16.2753 54.8913 16.4908 55.2684 16.6818C55.6406 16.8924 56.1181 17.0026 56.701 17.0124ZM55.981 15.3153C56.2014 15.423 56.4413 15.4769 56.7009 15.4769C56.9801 15.4769 57.2249 15.423 57.4355 15.3153C57.6559 15.2026 57.8224 15.0728 57.9351 14.9259C58.0869 14.7349 58.1873 14.5145 58.2363 14.2647C58.2853 14.0199 58.3097 13.6379 58.3097 13.1187C58.3097 12.5751 58.2853 12.1784 58.2363 11.9286C58.1873 11.6886 58.0869 11.478 57.9351 11.2968C57.8224 11.1254 57.6559 10.9907 57.4355 10.8928C57.2249 10.7899 56.9801 10.7385 56.7009 10.7385C56.4413 10.7385 56.2014 10.7899 55.981 10.8928C55.7704 10.9907 55.599 11.1254 55.4667 11.2968C55.3345 11.478 55.239 11.6886 55.1802 11.9286C55.1214 12.1784 55.0921 12.5702 55.0921 13.104C55.0921 13.633 55.1214 14.0199 55.1802 14.2647C55.239 14.5145 55.3345 14.7349 55.4667 14.9259C55.599 15.0728 55.7704 15.2026 55.981 15.3153ZM64.2236 17.0124C64.826 17.0026 65.3133 16.8924 65.6855 16.6818C65.8863 16.5937 66.0504 16.4884 66.1777 16.366C66.3197 16.2582 66.4397 16.148 66.5377 16.0354C66.8413 15.7268 67.0568 15.362 67.1841 14.9408C67.3066 14.5196 67.3678 13.9074 67.3678 13.1042C67.3678 12.301 67.3066 11.6839 67.1841 11.2529C67.0568 10.8317 66.8413 10.4767 66.5377 10.1877C66.3369 9.93303 66.0528 9.7053 65.6855 9.5045C65.3133 9.3135 64.826 9.2131 64.2236 9.2033C63.6408 9.2131 63.1633 9.3135 62.791 9.5045C62.4139 9.7053 62.1201 9.93303 61.9095 10.1877C61.6254 10.4767 61.4148 10.8317 61.2777 11.2529C61.1455 11.6839 61.0793 12.301 61.0793 13.1042C61.0793 13.9074 61.1455 14.5196 61.2777 14.9408C61.4148 15.362 61.6254 15.7268 61.9095 16.0354C62.1201 16.2753 62.4139 16.4908 62.791 16.6818C63.1633 16.8924 63.6408 17.0026 64.2236 17.0124ZM63.5036 15.3153C63.724 15.423 63.9639 15.4769 64.2235 15.4769C64.5027 15.4769 64.7476 15.423 64.9582 15.3153C65.1785 15.2026 65.3451 15.0728 65.4577 14.9259C65.6095 14.7349 65.7099 14.5145 65.7589 14.2647C65.8079 14.0199 65.8324 13.6379 65.8324 13.1187C65.8324 12.5751 65.8079 12.1784 65.7589 11.9286C65.7099 11.6886 65.6095 11.478 65.4577 11.2968C65.3451 11.1254 65.1785 10.9907 64.9582 10.8928C64.7476 10.7899 64.5027 10.7385 64.2235 10.7385C63.9639 10.7385 63.724 10.7899 63.5036 10.8928C63.293 10.9907 63.1216 11.1254 62.9893 11.2968C62.8571 11.478 62.7616 11.6886 62.7028 11.9286C62.6441 12.1784 62.6147 12.5702 62.6147 13.104C62.6147 13.633 62.6441 14.0199 62.7028 14.2647C62.7616 14.5145 62.8571 14.7349 62.9893 14.9259C63.1216 15.0728 63.293 15.2026 63.5036 15.3153ZM70.512 20.0097V16.1088C70.7911 16.3831 71.0972 16.5986 71.4303 16.7553C71.7388 16.9267 72.089 17.0124 72.4808 17.0124C72.9558 17.0026 73.3623 16.9071 73.7003 16.7259C74.0431 16.5496 74.3198 16.3145 74.5304 16.0207C74.741 15.7709 74.8855 15.4501 74.9638 15.0583C75.0373 14.6665 75.074 14.02 75.074 13.1189C75.074 12.1932 75.0373 11.537 74.9638 11.1501C74.8855 10.7583 74.741 10.4424 74.5304 10.2024C74.0994 9.56082 73.4162 9.22779 72.4808 9.2033C71.6776 9.22779 71.0213 9.52409 70.512 10.0922V9.2988H68.9766V20.0097H70.512ZM71.2026 15.2565C71.4034 15.4034 71.6752 15.4769 72.018 15.4769C72.3805 15.4769 72.667 15.4083 72.8775 15.2712C73.0881 15.1292 73.2375 14.9479 73.3257 14.7276C73.4236 14.4974 73.4897 14.2427 73.524 13.9635C73.5338 13.6893 73.5387 13.4077 73.5387 13.1187C73.5387 12.8151 73.5338 12.5188 73.524 12.2298C73.4897 11.9409 73.4236 11.6862 73.3257 11.4658C73.2375 11.2356 73.0881 11.0544 72.8775 10.9222C72.667 10.7997 72.3805 10.7385 72.018 10.7385C71.6752 10.7385 71.4034 10.8095 71.2026 10.9516C70.992 11.0936 70.8377 11.2797 70.7398 11.5099C70.6467 11.7401 70.5855 11.9898 70.5561 12.2592C70.5267 12.5433 70.512 12.8298 70.512 13.1187C70.512 13.3881 70.5267 13.6574 70.5561 13.9268C70.5855 14.2109 70.6467 14.468 70.7398 14.6982C70.8377 14.9284 70.992 15.1145 71.2026 15.2565ZM78.3211 16.9243V12.3328C78.3309 11.7745 78.4925 11.3705 78.8059 11.1207C79.0851 10.866 79.4206 10.7387 79.8124 10.7387C80.1601 10.7387 80.4956 10.866 80.8188 11.1207L81.9355 9.79101C81.48 9.409 80.9462 9.2131 80.334 9.2033C79.5161 9.2033 78.8549 9.5045 78.3505 10.1069H78.3211V9.2988H76.7857V16.9243H78.3211ZM84.2203 16.9238V9.29837H82.6849V16.9238H84.2203ZM87.7832 12.3843V16.9243H86.2478V9.2988H87.7832V10.1069H87.8126C88.317 9.5045 88.9782 9.2033 89.7961 9.2033C90.4279 9.2033 91.0058 9.42614 91.5298 9.87181C92.049 10.3224 92.3208 10.9836 92.3453 11.8553V16.9243H90.8099V12.3843C90.8099 11.8504 90.6678 11.4439 90.3838 11.1648C90.1046 10.8807 89.7447 10.7387 89.3039 10.7387C88.8631 10.7387 88.5007 10.8807 88.2166 11.1648C87.9277 11.4439 87.7832 11.8504 87.7832 12.3843ZM96.8412 20.0979C97.7423 20.0979 98.5161 19.8212 99.1626 19.2677C99.8042 18.729 100.135 17.8866 100.154 16.7406V9.2988H98.619V10.1069C98.0656 9.5045 97.4093 9.2033 96.6502 9.2033C96.1555 9.2131 95.7441 9.3086 95.416 9.48981C95.0732 9.68081 94.8112 9.8963 94.6299 10.1363C94.4291 10.3812 94.2847 10.6824 94.1965 11.0399C94.1035 11.4023 94.0569 12.0953 94.0569 13.1189C94.0569 14.1229 94.1035 14.8036 94.1965 15.1612C94.2847 15.5236 94.4291 15.8297 94.6299 16.0794C94.8112 16.2998 95.0732 16.5055 95.416 16.6965C95.7441 16.8973 96.1555 17.0026 96.6502 17.0124C97.4583 16.9928 98.1145 16.6965 98.619 16.1235V16.9096C98.6092 17.4287 98.4476 17.8352 98.1341 18.1291C97.8158 18.418 97.3946 18.5625 96.8706 18.5625C96.5914 18.5527 96.322 18.4768 96.0625 18.3348C95.8078 18.2074 95.5825 18.0532 95.3866 17.8719L94.1965 18.8196C94.9262 19.6522 95.8078 20.0783 96.8412 20.0979ZM96.3636 15.2712C96.5644 15.4083 96.8142 15.4769 97.1129 15.4769C97.4117 15.4769 97.6615 15.4083 97.8623 15.2712C98.0631 15.1585 98.2149 15.0337 98.3177 14.8965C98.4451 14.7447 98.5308 14.5537 98.5749 14.3235C98.6042 14.1031 98.6189 13.7015 98.6189 13.1187C98.6189 12.5261 98.6042 12.1147 98.5749 11.8845C98.5308 11.6544 98.4451 11.4682 98.3177 11.3262C98.2149 11.1891 98.0631 11.0544 97.8623 10.9222C97.6615 10.8095 97.4117 10.7483 97.1129 10.7385C96.8142 10.7483 96.5644 10.8095 96.3636 10.9222C96.153 11.0544 95.9963 11.1891 95.8935 11.3262C95.7661 11.4682 95.6853 11.6544 95.651 11.8845C95.6118 12.1147 95.5923 12.5261 95.5923 13.1187C95.5923 13.7015 95.6118 14.1031 95.651 14.3235C95.6853 14.5537 95.7661 14.7447 95.8935 14.8965C95.9963 15.0337 96.153 15.1585 96.3636 15.2712ZM108.948 16.9238L110.998 9.20284H111.027L113.069 16.9238H114.428L117.102 6.21289H115.391L113.701 13.8237H113.672L111.6 6.21289H110.424L108.345 13.8237H108.316L106.634 6.21289H104.922L107.596 16.9238H108.948ZM121.576 16.8212C121.282 16.9486 120.876 17.0122 120.357 17.0122C119.505 17.0024 118.848 16.7771 118.388 16.3364C117.903 15.9054 117.661 15.3544 117.661 14.6834C117.661 14.0419 117.871 13.5105 118.292 13.0893C118.714 12.6583 119.331 12.4379 120.144 12.4281H122.267V11.6274C122.277 10.9564 121.755 10.6307 120.702 10.6503C120.32 10.6503 120.019 10.6895 119.798 10.7679C119.568 10.8609 119.387 11.0176 119.255 11.238L118.05 10.3197C118.633 9.55572 119.492 9.1835 120.629 9.20309C121.588 9.1933 122.355 9.37451 122.928 9.74672C123.501 10.1287 123.792 10.785 123.802 11.7155V16.9241H122.267V16.2482H122.237C122.095 16.5078 121.875 16.6988 121.576 16.8212ZM120.548 15.5719C120.038 15.5719 119.674 15.4715 119.453 15.2707C119.223 15.0895 119.108 14.8691 119.108 14.6096C119.098 14.017 119.539 13.7109 120.43 13.6913H122.267V14.2422C122.267 14.8153 122.147 15.1826 121.907 15.3442C121.642 15.5058 121.189 15.5817 120.548 15.5719ZM128.423 15.4766V16.9238H127.74C127.181 16.9238 126.721 16.7842 126.359 16.5051C125.977 16.221 125.786 15.7435 125.786 15.0725V6.21289H127.321V14.955C127.321 15.3027 127.512 15.4766 127.894 15.4766H128.423ZM132.302 16.9238V15.4766H131.773C131.391 15.4766 131.2 15.3027 131.2 14.955V6.21289H129.665V15.0725C129.665 15.7435 129.856 16.221 130.238 16.5051C130.6 16.7842 131.06 16.9238 131.619 16.9238H132.302ZM139.303 15.7782C138.524 16.6108 137.608 17.0222 136.555 17.0124C136.154 17.0124 135.762 16.9537 135.38 16.8361C135.189 16.7724 135.003 16.6867 134.822 16.579C134.631 16.4859 134.452 16.3709 134.285 16.2337C133.962 15.9497 133.7 15.553 133.499 15.0436C133.279 14.5539 133.169 13.9172 133.169 13.1336C133.169 12.3794 133.264 11.7525 133.455 11.2529C133.646 10.7436 133.891 10.342 134.19 10.0481C134.493 9.74938 134.834 9.53389 135.211 9.40165C135.583 9.26942 135.95 9.2033 136.313 9.2033C137.185 9.2131 137.922 9.4996 138.524 10.0628C139.136 10.6358 139.447 11.4243 139.457 12.4283V13.6919H134.704C134.704 14.3041 134.88 14.7694 135.233 15.0877C135.561 15.4109 135.992 15.5726 136.526 15.5726C137.148 15.5726 137.704 15.3252 138.194 14.8306L139.303 15.7782ZM134.704 12.4278C134.733 11.8352 134.893 11.3871 135.182 11.0835C135.475 10.7945 135.853 10.65 136.313 10.65C136.773 10.65 137.15 10.7945 137.444 11.0835C137.743 11.3871 137.902 11.8352 137.922 12.4278H134.704ZM143.806 15.4769V16.9241H143.005C142.467 16.9241 142.026 16.7576 141.683 16.4246C141.331 16.1062 141.154 15.6458 141.154 15.0435V10.4667H140.39V9.29864H141.154V6.9772H142.69V9.29864H143.806V10.4667H142.69V14.9112C142.68 15.2981 142.861 15.4867 143.233 15.4769H143.806Z'\n        fill='#3B5AF4'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const YoutubeIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} htmlColor={''} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M22.5417 12C22.5417 17.822 17.822 22.5417 12 22.5417C6.178 22.5417 1.45833 17.822 1.45833 12C1.45833 6.178 6.178 1.45833 12 1.45833C17.822 1.45833 22.5417 6.178 22.5417 12ZM23 12C23 18.0751 18.0751 23 12 23C5.92487 23 1 18.0751 1 12C1 5.92487 5.92487 1 12 1C18.0751 1 23 5.92487 23 12ZM18.1111 12C18.1111 12 18.1111 9.72667 17.8318 8.63767C17.6784 8.03756 17.225 7.56456 16.6475 7.402C15.6031 7.11111 12 7.11111 12 7.11111C12 7.11111 8.39872 7.11111 7.3525 7.402C6.77744 7.56211 6.32339 8.03572 6.16817 8.63767C5.88889 9.72667 5.88889 12 5.88889 12C5.88889 12 5.88889 14.2733 6.16817 15.3623C6.32156 15.9624 6.775 16.4354 7.3525 16.598C8.39872 16.8889 12 16.8889 12 16.8889C12 16.8889 15.6031 16.8889 16.6475 16.598C17.2226 16.4379 17.6766 15.9643 17.8318 15.3623C18.1111 14.2733 18.1111 12 18.1111 12ZM14.4444 12L10.7778 14.1389V9.86111L14.4444 12Z'\n      />\n    </SvgIcon>\n  )\n}\nexport const TwitterIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} htmlColor={''} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M22.5417 12C22.5417 17.822 17.822 22.5417 12 22.5417C6.178 22.5417 1.45833 17.822 1.45833 12C1.45833 6.178 6.178 1.45833 12 1.45833C17.822 1.45833 22.5417 6.178 22.5417 12ZM23 12C23 18.0751 18.0751 23 12 23C5.92487 23 1 18.0751 1 12C1 5.92487 5.92487 1 12 1C18.0751 1 23 5.92487 23 12ZM16.7095 9.93043C16.7145 10.0394 16.7165 10.1494 16.7165 10.2604C16.7165 13.6354 14.2725 17.5254 9.80347 17.5244C8.43047 17.5244 7.15347 17.0944 6.07747 16.3564C6.26747 16.3804 6.46147 16.3934 6.65747 16.3934C7.79547 16.3964 8.84347 15.9844 9.67547 15.2944C8.61247 15.2694 7.71447 14.5164 7.40547 13.4854C7.55347 13.5174 7.70547 13.5344 7.86247 13.5354C8.08347 13.5364 8.29847 13.5064 8.50247 13.4484C7.39047 13.2024 6.55247 12.1484 6.55247 10.8904V10.8574C6.88047 11.0554 7.25447 11.1764 7.65347 11.1944C7.00147 10.7224 6.57247 9.92243 6.57247 9.02243C6.57247 8.54643 6.69247 8.10243 6.90147 7.72243C8.09947 9.30843 9.89047 10.3604 11.9115 10.4904C11.8695 10.3014 11.8485 10.1054 11.8485 9.90343C11.8485 8.48243 12.9365 7.34843 14.2785 7.37043C14.9775 7.38243 15.6095 7.70343 16.0525 8.20743C16.6055 8.10143 17.1255 7.89743 17.5955 7.61243C17.4135 8.20543 17.0285 8.69943 16.5265 9.00843C17.0185 8.95343 17.4865 8.82243 17.9225 8.62643C17.5965 9.13343 17.1845 9.57643 16.7095 9.93043Z'\n      />\n    </SvgIcon>\n  )\n}\nexport const MediumIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} htmlColor={''} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M22.5417 12C22.5417 17.822 17.822 22.5417 12 22.5417C6.178 22.5417 1.45833 17.822 1.45833 12C1.45833 6.178 6.178 1.45833 12 1.45833C17.822 1.45833 22.5417 6.178 22.5417 12ZM23 12C23 18.0751 18.0751 23 12 23C5.92487 23 1 18.0751 1 12C1 5.92487 5.92487 1 12 1C18.0751 1 23 5.92487 23 12ZM17.7337 16.4862L16.8583 15.6117H16.8593C16.7676 15.5658 16.7217 15.4274 16.7217 15.3358V8.33883C16.7217 8.24717 16.7676 8.10875 16.8593 8.01708L17.7337 7.00417V6.95833H14.6033L12.2548 12.8965L9.5855 6.95833H6.36342V7.00417L7.193 8.15642C7.37633 8.33975 7.42217 8.61658 7.42217 8.84667V13.9085C7.468 14.1853 7.42217 14.508 7.28467 14.783L6.04167 16.4862V16.532H9.35633V16.4862L8.11333 14.8298C7.97583 14.5529 7.92908 14.277 7.97583 13.9543V9.35267C7.99111 9.38322 8.00639 9.40359 8.02167 9.42396C8.05222 9.4647 8.08278 9.50544 8.11333 9.62767L11.2438 16.6246H11.2896L14.3274 9.03C14.2807 9.30592 14.2807 9.62767 14.2807 9.85867V15.2899C14.2807 15.4283 14.2348 15.52 14.1432 15.6117L13.2228 16.4862V16.532H17.7337V16.4862Z'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const DiscordIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} htmlColor={''} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M22.5417 12C22.5417 17.822 17.822 22.5417 12 22.5417C6.178 22.5417 1.45833 17.822 1.45833 12C1.45833 6.178 6.178 1.45833 12 1.45833C17.822 1.45833 22.5417 6.178 22.5417 12ZM23 12C23 18.0751 18.0751 23 12 23C5.92487 23 1 18.0751 1 12C1 5.92487 5.92487 1 12 1C18.0751 1 23 5.92487 23 12ZM10.7503 15.4042C10.6021 15.3766 10.4546 15.3449 10.3081 15.3092V15.3083L9.3882 16.3442C7.31174 16.2766 6.5124 14.8862 6.5124 14.8862C6.5124 11.7976 7.86626 9.29449 7.86626 9.29449C9.21828 8.25854 10.5064 8.28686 10.5064 8.28686L10.9101 8.76647C11.6111 8.66738 12.3223 8.66431 13.0241 8.75733C13.0583 8.75866 13.0924 8.76171 13.1264 8.76647L13.4945 8.28686C13.4945 8.28686 14.7817 8.25854 16.1346 9.29357C16.1346 9.29357 17.4876 11.7976 17.4876 14.8862C17.4876 14.8862 16.6983 16.2775 14.6218 16.3442L13.7805 15.2507C13.5238 15.3192 13.3246 15.3677 13.1839 15.3951C12.3806 15.5525 11.5547 15.5556 10.7503 15.4042ZM14.7972 12.9523C14.7972 12.4498 14.3633 12.0387 13.8143 12.0387C13.2652 12.0387 12.8231 12.4498 12.8322 12.9523C12.8322 13.4547 13.2661 13.8658 13.8143 13.8658C14.3542 13.8658 14.7972 13.4547 14.7972 12.9523ZM11.281 12.9523C11.281 12.4498 10.8471 12.0387 10.299 12.0387C9.74996 12.0387 9.31603 12.4498 9.31603 12.9523C9.31603 13.4547 9.74996 13.8658 10.299 13.8658C10.838 13.8658 11.281 13.4547 11.281 12.9523Z'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const LoopringIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='89' height='27' viewBox='0 0 89 27' fill='none'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M33.2461 13.1402H19.2495L22.2249 17.7118L11.3922 26.0863L33.2461 13.2211V13.1402ZM11.0988 26.2683V0.740234L0.0356445 17.732L11.0988 26.2683ZM35.2363 26.1875V13.1807H37.4154V24.4074H40.3908V26.1875H35.2363ZM88.6455 15.6486V17.7928H86.5293V15.6283C86.5921 14.6372 84.5387 14.5967 84.6854 15.6283V23.659C84.6854 24.1647 84.9578 24.4277 85.5654 24.4277C86.1311 24.4277 86.5293 24.1647 86.5293 23.659V21.4541H85.6073V19.674H88.6455V23.6792C88.6455 25.257 87.556 26.2887 85.5654 26.2887C83.5749 26.2887 82.4853 25.2368 82.4853 23.6792V15.6486C82.4853 14.091 83.5749 13.0391 85.5654 13.0391C87.556 13.0391 88.6455 14.0708 88.6455 15.6486ZM79.1119 20.2809C79.07 19.0874 79.049 17.9951 79.049 16.9836H79.0281V13.1605H81.0186V26.1875H78.7138L76.6604 18.9256C76.7023 20.1393 76.7233 21.2923 76.7233 22.3441V26.1875H74.7327V13.1605H77.1004L79.1119 20.2809ZM73.1403 26.1673H70.9612V13.1403H73.1403V26.1673ZM66.582 19.411C67.1058 19.411 67.3782 19.1481 67.3782 18.6424V15.7093C67.3782 15.2036 67.1058 14.9406 66.582 14.9406H65.5972V19.411H66.582ZM69.5573 15.7093V18.6424C69.5573 19.6335 69.1383 20.4022 68.3421 20.827L69.8297 26.1875H67.6506L66.2677 21.2114H65.5972V26.1875H63.4181V13.1605H66.582C68.5306 13.1605 69.5573 14.1315 69.5573 15.7093ZM59.3532 19.411C59.8771 19.411 60.1494 19.1481 60.1494 18.6424H60.1704V15.7093C60.1704 15.2036 59.898 14.9406 59.3742 14.9406H58.3894V19.411H59.3532ZM56.2103 13.1605H59.3742C61.3228 13.1605 62.3285 14.1112 62.3495 15.7295V18.6626C62.3495 20.2404 61.3228 21.2114 59.3742 21.2114H58.3894V26.1875H56.2103V13.1605ZM50.7834 23.6792C50.6577 24.6906 52.7111 24.6906 52.5854 23.6792V15.6486C52.6902 14.6372 50.6577 14.6372 50.7834 15.6486V23.6792ZM48.6043 15.6486C48.6043 14.0708 49.6939 13.0391 51.6844 13.0391C53.654 13.0391 54.7645 14.0708 54.7645 15.6486V23.6792C54.7645 25.257 53.675 26.2887 51.6844 26.2887C49.6939 26.2887 48.6043 25.2368 48.6043 23.6792V15.6486ZM43.3242 23.6792C43.1985 24.6906 45.2519 24.6906 45.1261 23.6792V15.6486C45.2309 14.6372 43.1985 14.6372 43.3242 15.6486V23.6792ZM41.1451 15.6486C41.1451 14.0708 42.2346 13.0391 44.2252 13.0391C46.2157 13.0391 47.3053 14.0708 47.3053 15.6486V23.6792C47.3053 25.257 46.2157 26.2887 44.2252 26.2887C42.2346 26.2887 41.1451 25.2368 41.1451 23.6792V15.6486Z'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const LightIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path d='M12 18C10.4087 18 8.88258 17.3679 7.75736 16.2426C6.63214 15.1174 6 13.5913 6 12C6 10.4087 6.63214 8.88258 7.75736 7.75736C8.88258 6.63214 10.4087 6 12 6C13.5913 6 15.1174 6.63214 16.2426 7.75736C17.3679 8.88258 18 10.4087 18 12C18 13.5913 17.3679 15.1174 16.2426 16.2426C15.1174 17.3679 13.5913 18 12 18ZM12 16C13.0609 16 14.0783 15.5786 14.8284 14.8284C15.5786 14.0783 16 13.0609 16 12C16 10.9391 15.5786 9.92172 14.8284 9.17157C14.0783 8.42143 13.0609 8 12 8C10.9391 8 9.92172 8.42143 9.17157 9.17157C8.42143 9.92172 8 10.9391 8 12C8 13.0609 8.42143 14.0783 9.17157 14.8284C9.92172 15.5786 10.9391 16 12 16V16ZM11 1H13V4H11V1ZM11 20H13V23H11V20ZM3.515 4.929L4.929 3.515L7.05 5.636L5.636 7.05L3.515 4.93V4.929ZM16.95 18.364L18.364 16.95L20.485 19.071L19.071 20.485L16.95 18.364ZM19.071 3.514L20.485 4.929L18.364 7.05L16.95 5.636L19.071 3.515V3.514ZM5.636 16.95L7.05 18.364L4.929 20.485L3.515 19.071L5.636 16.95V16.95ZM23 11V13H20V11H23ZM4 11V13H1V11H4Z' />\n    </SvgIcon>\n  )\n}\n\nexport const DarkIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path d='M11.38 2.01953C10.6431 2.70615 10.0521 3.53416 9.64219 4.45415C9.23227 5.37414 9.01185 6.36728 8.99408 7.37431C8.97632 8.38133 9.16156 9.38163 9.53877 10.3155C9.91598 11.2494 10.4774 12.0977 11.1896 12.8099C11.9018 13.5221 12.7501 14.0835 13.684 14.4608C14.6179 14.838 15.6182 15.0232 16.6252 15.0054C17.6323 14.9877 18.6254 14.7673 19.5454 14.3573C20.4654 13.9474 21.2934 13.3564 21.98 12.6195C21.662 17.8545 17.316 22.0005 12.001 22.0005C6.477 22.0005 2 17.5235 2 12.0005C2 6.68553 6.146 2.33953 11.38 2.01953Z' />\n    </SvgIcon>\n  )\n}\n\nexport const ExitIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path d='M20.1489 6.1501V3.0001C20.1489 2.6951 20.0277 2.40259 19.812 2.18692C19.5964 1.97126 19.3039 1.8501 18.9989 1.8501H4.99888C4.69388 1.8501 4.40137 1.97126 4.1857 2.18692C3.97004 2.40259 3.84888 2.6951 3.84888 3.0001V21.0001C3.84888 21.3051 3.97004 21.5976 4.1857 21.8133C4.40137 22.0289 4.69388 22.1501 4.99888 22.1501H18.9989C19.3039 22.1501 19.5964 22.0289 19.812 21.8133C20.0277 21.5976 20.1489 21.3051 20.1489 21.0001V17.8501H17.8489V19.8501H6.14888V4.1501H17.8489V6.1501H20.1489Z' />\n      <path d='M17.9989 13.0001V16.0001L22.9989 12.0001L17.9989 8.0001V11.0001H10.9989V13.0001H17.9989Z' />\n    </SvgIcon>\n  )\n}\nexport const RampIcon = ({\n  fontColor = '#fff',\n  ...props\n}: SvgIconProps & { fontColor?: string }) => (\n  <SvgIcon {...props} width='138' height='32' viewBox='0 0 138 32' fill='none'>\n    <g clipPath='url(#clip0_684_463)'>\n      <path\n        d='M34.4433 18.8309L28.3845 24.912C27.8712 25.4272 27.8717 26.2647 28.3855 26.7792L33.0155 31.4158C33.8046 32.1947 35.0946 32.1947 35.8837 31.4158L50.0747 17.4093C50.8638 16.6305 50.8638 15.3571 50.0747 14.5783L35.8837 0.584122C35.0946 -0.194707 33.8046 -0.194707 33.0155 0.584122L28.3855 5.22078C27.8717 5.73535 27.8712 6.57281 28.3845 7.08795L34.4433 13.1691C36.0215 14.7267 36.0215 17.2733 34.4433 18.8309Z'\n        fill='#0A6E5C'\n      />\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M22.282 24.912L16.2232 18.8309C14.645 17.2733 14.645 14.7267 16.2232 13.1691L22.282 7.08795C22.7953 6.57281 22.7948 5.73535 22.281 5.22078L17.651 0.584122C16.8619 -0.194707 15.5719 -0.194707 14.7828 0.584122L0.591812 14.5783C-0.197271 15.3571 -0.197271 16.6305 0.591812 17.4093L14.7828 31.4158C15.5719 32.1947 16.8619 32.1947 17.651 31.4158L22.281 26.7792C22.7948 26.2647 22.7953 25.4272 22.282 24.912ZM17.8128 14.843C17.1737 15.482 17.1737 16.518 17.8128 17.157L24.1765 23.5207C24.8155 24.1598 25.8515 24.1598 26.4905 23.5207L32.8542 17.157C33.4932 16.518 33.4932 15.482 32.8542 14.843L26.4905 8.47926C25.8515 7.84025 24.8155 7.84025 24.1765 8.47926L17.8128 14.843Z'\n        fill='#21BF73'\n      />\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M73.2829 25.6003H77.8051L75.4481 19.5165C74.9365 18.1585 74.1051 17.3601 72.954 17.1215C74.233 16.7178 75.2105 16.0479 75.8866 15.112C76.5809 14.176 76.928 13.0565 76.928 11.7535C76.928 9.89988 76.3433 8.47757 75.174 7.48654C74.0046 6.49551 72.2871 6 70.0215 6H61.3335V25.6003H65.5542V17.6996H68.3223C68.9435 17.6996 69.4551 17.8006 69.857 18.0025C70.2773 18.2043 70.5879 18.5622 70.7889 19.0761L73.2829 25.6003ZM72.077 13.8181C71.5106 14.2219 70.6153 14.4237 69.3911 14.4237H65.4993V9.30343H69.3911C70.6153 9.30343 71.5106 9.51448 72.077 9.93659C72.6434 10.3403 72.9266 10.9827 72.9266 11.8636C72.9266 12.7445 72.6434 13.396 72.077 13.8181ZM94.3864 25.6003V11.6434H90.3028V13.6254C89.8826 12.9097 89.2888 12.3407 88.5214 11.9186C87.754 11.4965 86.8861 11.2855 85.9177 11.2855C84.7301 11.2855 83.6703 11.5975 82.7385 12.2215C81.8067 12.8271 81.0758 13.6896 80.546 14.8091C80.0344 15.9286 79.7786 17.2041 79.7786 18.6356C79.7786 20.0671 80.0344 21.3334 80.546 22.4346C81.0758 23.5173 81.7975 24.3524 82.7111 24.9397C83.6429 25.5269 84.7118 25.8206 85.9177 25.8206C86.8861 25.8206 87.754 25.6187 88.5214 25.2149C89.2888 24.8112 89.8826 24.2514 90.3028 23.5357V25.6003H94.3864ZM89.4806 21.6087C88.9325 22.3061 88.1468 22.6548 87.1236 22.6548C86.0822 22.6548 85.2782 22.3153 84.7118 21.6362C84.1637 20.9388 83.8896 19.9386 83.8896 18.6356C83.8896 17.3326 84.1728 16.314 84.7392 15.5799C85.3056 14.8458 86.1004 14.4788 87.1236 14.4788C88.1468 14.4788 88.9325 14.8367 89.4806 15.5524C90.0287 16.2498 90.3028 17.2592 90.3028 18.5806C90.3028 19.9019 90.0287 20.9113 89.4806 21.6087ZM114.719 11.2855C116.309 11.2855 117.487 11.7718 118.255 12.7445C119.04 13.6988 119.433 15.167 119.433 17.1491V25.6003H115.295V17.2867C115.295 16.314 115.139 15.6166 114.829 15.1945C114.518 14.7541 114.007 14.5339 113.294 14.5339C112.454 14.5339 111.805 14.8275 111.348 15.4148C110.891 16.002 110.663 16.8279 110.663 17.8923V25.6003H106.524V17.2867C106.524 16.3324 106.36 15.635 106.031 15.1945C105.721 14.7541 105.218 14.5339 104.524 14.5339C103.683 14.5339 103.026 14.8275 102.55 15.4148C102.094 16.002 101.865 16.8279 101.865 17.8923V25.6003H97.7269V15.635C97.7269 14.1485 97.6538 12.8179 97.5076 11.6434H101.399L101.646 13.7355C102.066 12.9464 102.651 12.3407 103.4 11.9186C104.167 11.4965 105.045 11.2855 106.031 11.2855C108.096 11.2855 109.466 12.148 110.142 13.8732C110.599 13.084 111.229 12.46 112.033 12.0012C112.855 11.5241 113.751 11.2855 114.719 11.2855ZM134.374 12.2215C133.442 11.5975 132.382 11.2855 131.194 11.2855C130.153 11.2855 129.221 11.5241 128.399 12.0012C127.595 12.4784 127.01 13.1299 126.645 13.9558L126.371 11.6434H122.479C122.625 12.8179 122.698 14.1485 122.698 15.635V32H126.837V23.5357C127.239 24.2514 127.823 24.8112 128.591 25.2149C129.358 25.6187 130.226 25.8206 131.194 25.8206C132.4 25.8206 133.469 25.5269 134.401 24.9397C135.333 24.3524 136.055 23.5173 136.566 22.4346C137.078 21.3334 137.333 20.0671 137.333 18.6356C137.333 17.2041 137.069 15.9286 136.539 14.8091C136.027 13.6896 135.305 12.8271 134.374 12.2215ZM132.373 21.6362C131.825 22.3153 131.039 22.6548 130.016 22.6548C128.993 22.6548 128.198 22.3061 127.631 21.6087C127.083 20.9113 126.809 19.9019 126.809 18.5806C126.809 17.2592 127.083 16.2498 127.631 15.5524C128.198 14.8367 128.993 14.4788 130.016 14.4788C131.021 14.4788 131.797 14.8458 132.345 15.5799C132.912 16.314 133.195 17.3326 133.195 18.6356C133.195 19.9386 132.921 20.9388 132.373 21.6362Z'\n        fill={fontColor}\n      />\n    </g>\n  </SvgIcon>\n)\nexport const BanxaIcon = ({\n  fontColor = '#fff',\n  ...props\n}: SvgIconProps & { fontColor?: string }) => (\n  <SvgIcon {...props} width='153' height='32' viewBox='0 0 153 32' fill='none'>\n    <path\n      d='M138.04 10.2625L146.148 24.3045H129.937L138.04 10.2625ZM135.346 5.55588L123.847 25.4756C123.429 26.2005 123.429 27.0928 123.847 27.8178C124.266 28.5427 125.041 28.9888 125.877 28.9888H150.202C151.039 28.9888 151.814 28.5427 152.232 27.8178C152.651 27.0928 152.651 26.2005 152.232 25.4756L140.728 5.55588C140.176 4.5967 139.144 4 138.04 4C136.93 4 135.904 4.5967 135.346 5.55588Z'\n      fill='url(#paint0_linear_697_479)'\n    />\n    <path\n      fillRule='evenodd'\n      clipRule='evenodd'\n      d='M22.1241 26.4069C23.5573 25.0016 24.2711 23.3007 24.2711 21.3043C24.2711 18.9621 23.3509 17.0772 21.5051 15.644C22.5144 14.3391 23.0219 12.8724 23.0219 11.244C23.0219 9.2476 22.3025 7.54115 20.8582 6.12469C19.4138 4.70823 17.6795 4 15.6608 4H1.1281C0.46448 4 0.129883 4.3346 0.129883 4.99821V27.5166C0.129883 28.1802 0.46448 28.5148 1.1281 28.5148H16.9099C18.9566 28.5148 20.6965 27.8122 22.1241 26.4069ZM17.3003 9.21972C17.7855 9.76622 18.0253 10.4354 18.0253 11.2273C18.0253 11.9969 17.7855 12.6605 17.3003 13.2182C16.8207 13.7758 16.2463 14.0547 15.5771 14.0547H5.97418C5.33287 14.0547 5.00943 13.7368 5.00943 13.0899V9.37028C5.00943 8.7234 5.33287 8.39995 5.97418 8.39995H15.5771C16.2463 8.39995 16.8207 8.67321 17.3003 9.21972ZM18.555 19.2911C19.0402 19.8432 19.28 20.518 19.28 21.3043C19.28 22.0683 19.0402 22.7263 18.5606 23.284C18.081 23.8361 17.5066 24.1149 16.8374 24.1149H5.97418C5.33287 24.1149 5.00943 23.7803 5.00943 23.1167V19.4584C5.00943 18.7948 5.33287 18.4602 5.97418 18.4602H16.8319C17.5011 18.4602 18.0755 18.739 18.555 19.2911ZM55.0873 28.9888H30.762C29.9255 28.9888 29.1504 28.5427 28.7321 27.8178C28.3139 27.0928 28.3139 26.2005 28.7321 25.4756L40.2311 5.55588C40.7832 4.5967 41.8149 4 42.9246 4C44.0344 4 45.0605 4.5967 45.6182 5.55588L57.1172 25.4756C57.5354 26.2005 57.5354 27.0928 57.1172 27.8178C56.6933 28.5371 55.9238 28.9888 55.0873 28.9888ZM34.8162 24.3045H51.0275L42.9246 10.2625L34.8162 24.3045ZM85.9317 28.5148C86.573 28.5148 86.8965 28.1802 86.8965 27.5166H86.8909V4.99821C86.8909 4.3346 86.573 4 85.9317 4H82.9761C82.3404 4 82.0169 4.3346 82.0169 4.99821V20.8581L67.8189 4.36806C67.5958 4.12269 67.3393 4 67.0437 4H63.3854C62.7441 4 62.4263 4.3346 62.4263 4.99821V27.5166C62.4263 28.1802 62.7441 28.5148 63.3854 28.5148H66.3411C66.9824 28.5148 67.3058 28.1858 67.3058 27.5166V11.311L81.8943 28.197C82.0671 28.4089 82.3014 28.5148 82.5969 28.5148H85.9317ZM118.544 27.5557C118.544 27.3103 118.466 27.0984 118.321 26.9255L108.93 15.6886L117.128 5.63952C117.273 5.43877 117.345 5.2157 117.345 4.97033C117.345 4.32902 117.027 4.00558 116.386 4.00558H112.321C112.003 4.00558 111.741 4.12826 111.545 4.37363L105.779 11.7292L100.013 4.40709C99.8122 4.13384 99.5445 4 99.1988 4H95.1334C94.4921 4 94.1742 4.32344 94.1742 4.96475C94.1742 5.2157 94.2467 5.43319 94.3917 5.63395L102.601 15.6942L93.2541 26.892C93.0812 27.0872 92.9976 27.3103 92.9976 27.5557C92.9976 28.197 93.3322 28.5148 93.9958 28.5148H98.2842C98.6021 28.5148 98.8753 28.381 99.0984 28.1077L105.79 19.7149L112.521 28.1802C112.716 28.4033 112.979 28.5148 113.296 28.5148H117.585C118.226 28.5148 118.544 28.197 118.544 27.5557Z'\n      fill={fontColor}\n    />\n    <defs>\n      <linearGradient\n        id='paint0_linear_697_479'\n        x1='123.533'\n        y1='16.4933'\n        x2='152.543'\n        y2='16.4933'\n        gradientUnits='userSpaceOnUse'\n      >\n        <stop stopColor='#0172D0' />\n        <stop offset='0.0644' stopColor='#0181CD' />\n        <stop offset='0.2231' stopColor='#019FC8' />\n        <stop offset='0.3899' stopColor='#00B7C3' />\n        <stop offset='0.5666' stopColor='#00C8C0' />\n        <stop offset='0.7597' stopColor='#00D2BF' />\n        <stop offset='1' stopColor='#00D5BE' />\n      </linearGradient>\n    </defs>\n  </SvgIcon>\n)\n\nexport const FirstPlaceIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path\n        d='M22.2998 11.264L19.9805 22.013H5.21793L2.89777 11.264L8.38532 14.7132L12.3627 7.38745L16.7096 14.7132L22.2998 11.264Z'\n        fill='#FFDE5D'\n      />\n      <path\n        d='M10.1735 6.16853C10.1735 6.70727 10.3864 7.22394 10.7654 7.60489C11.1445 7.98584 11.6585 8.19985 12.1945 8.19985C12.7305 8.19985 13.2446 7.98584 13.6236 7.60489C14.0026 7.22394 14.2156 6.70727 14.2156 6.16853C14.2156 5.62979 14.0026 5.11311 13.6236 4.73217C13.2446 4.35122 12.7305 4.13721 12.1945 4.13721C11.6585 4.13721 11.1445 4.35122 10.7654 4.73217C10.3864 5.11311 10.1735 5.62979 10.1735 6.16853Z'\n        fill='#FFCD52'\n      />\n      <path\n        d='M11.7904 4.13721C13.1299 4.13721 14.2156 5.04561 14.2156 6.16853C14.2156 7.28982 13.1299 8.19985 11.7904 8.19985V4.13721ZM22.2998 11.45L19.9958 22.0128H5.323L22.2998 11.45Z'\n        fill='#FFDE5D'\n      />\n      <path d='M2.89771 11.45L5.20171 22.0128H19.8745L2.89771 11.45Z' fill='#FFCD52' />\n      <path\n        d='M1.59796 11.0408C1.76739 11.2114 1.98339 11.3277 2.21861 11.3748C2.45383 11.422 2.69768 11.3979 2.91929 11.3057C3.1409 11.2135 3.33029 11.0572 3.46348 10.8567C3.59668 10.6563 3.66769 10.4206 3.66751 10.1795C3.66751 10.0194 3.63614 9.86095 3.5752 9.71307C3.51426 9.5652 3.42494 9.43085 3.31234 9.31767C3.19974 9.20449 3.06606 9.11472 2.91893 9.05347C2.77181 8.99222 2.61413 8.96069 2.45488 8.96069C2.29564 8.96069 2.13795 8.99222 1.99083 9.05347C1.8437 9.11472 1.71002 9.20449 1.59742 9.31767C1.48482 9.43085 1.39549 9.5652 1.33455 9.71307C1.27361 9.86095 1.24225 10.0194 1.24225 10.1795C1.24253 10.5026 1.37048 10.8124 1.59796 11.0408Z'\n        fill='#FFCD52'\n      />\n      <path\n        d='M2.89764 9.01245C3.11187 9.01245 3.31801 9.14083 3.46919 9.36996C3.62117 9.59828 3.70605 9.90867 3.70605 10.2312C3.70605 10.5546 3.62117 10.865 3.46919 11.0933C3.31801 11.3217 3.11187 11.4508 2.89764 11.45V9.01245Z'\n        fill='#FFDE5D'\n      />\n      <path\n        d='M20.6829 10.2312C20.6829 10.3913 20.7143 10.5498 20.7752 10.6977C20.8361 10.8455 20.9255 10.9799 21.0381 11.0931C21.1507 11.2062 21.2843 11.296 21.4315 11.3573C21.5786 11.4185 21.7363 11.45 21.8955 11.45C22.0548 11.45 22.2125 11.4185 22.3596 11.3573C22.5067 11.296 22.6404 11.2062 22.753 11.0931C22.8656 10.9799 22.9549 10.8455 23.0158 10.6977C23.0768 10.5498 23.1082 10.3913 23.1082 10.2312C23.1082 9.908 22.9804 9.598 22.753 9.36943C22.5256 9.14086 22.2171 9.01245 21.8955 9.01245C21.5739 9.01245 21.2655 9.14086 21.0381 9.36943C20.8107 9.598 20.6829 9.908 20.6829 10.2312Z'\n        fill='#FFCD52'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const SecondPlaceIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' fill='none'>\n      <path\n        d='M18.4027 8.69486H7.55664V2.80911C7.55664 2.63699 7.69914 2.49609 7.87446 2.49609H18.0849C18.2602 2.49609 18.4027 2.63699 18.4027 2.80831V8.69406V8.69486Z'\n        fill='#FFF7D7'\n      />\n      <path\n        d='M7.55664 2.49683H10.1529V8.17843H7.55664V2.49683ZM11.6811 2.49683H14.2782V8.17843H11.6811V2.49683ZM15.8064 2.49683H18.4027V8.17843H15.8064V2.49683Z'\n        fill='#F94F46'\n      />\n      <path\n        d='M4.64624 14.1627C4.64624 18.7635 8.37624 22.496 12.9796 22.496C17.5829 22.496 21.3129 18.766 21.3129 14.1627C21.3129 9.55935 17.5829 5.82935 12.9796 5.82935C8.37624 5.82935 4.64624 9.56185 4.64624 14.1627Z'\n        fill='#F5B319'\n      />\n      <path\n        d='M7.14624 14.1279C7.14624 15.6842 7.76082 17.1768 8.85478 18.2773C9.94875 19.3778 11.4325 19.996 12.9796 19.996C14.5267 19.996 16.0104 19.3778 17.1044 18.2773C18.1983 17.1768 18.8129 15.6842 18.8129 14.1279C18.7947 12.5837 18.1721 11.109 17.0802 10.0235C15.9883 8.93807 14.5151 8.32935 12.98 8.32935C11.4449 8.32935 9.97165 8.93807 8.87975 10.0235C7.78784 11.109 7.16528 12.5837 7.14706 14.1279H7.14624Z'\n        fill='#FEE701'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const ThirdPlaceIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' fill='none'>\n      <path\n        d='M18.2069 8.94486H7.36084V3.05911C7.36084 2.88699 7.50334 2.74609 7.67866 2.74609H17.8891C18.0644 2.74609 18.2069 2.88699 18.2069 3.05831V8.94406V8.94486Z'\n        fill='#FEE701'\n      />\n      <path\n        d='M7.36084 2.74683H9.95707V8.42843H7.36084V2.74683ZM11.4853 2.74683H14.0824V8.42843H11.4853V2.74683ZM15.6106 2.74683H18.2069V8.42843H15.6106V2.74683Z'\n        fill='#F5B319'\n      />\n      <path\n        d='M4.45044 14.4127C4.45044 19.0135 8.18044 22.746 12.7838 22.746C17.3871 22.746 21.1171 19.016 21.1171 14.4127C21.1171 9.80935 17.3871 6.07935 12.7838 6.07935C8.18044 6.07935 4.45044 9.81185 4.45044 14.4127Z'\n        fill='#E9A70F'\n      />\n      <path\n        d='M6.95044 14.3779C6.95044 15.9342 7.56502 17.4268 8.65898 18.5273C9.75295 19.6278 11.2367 20.246 12.7838 20.246C14.3309 20.246 15.8146 19.6278 16.9086 18.5273C18.0025 17.4268 18.6171 15.9342 18.6171 14.3779C18.5989 12.8337 17.9763 11.359 16.8844 10.2735C15.7925 9.18807 14.3193 8.57935 12.7842 8.57935C11.2491 8.57935 9.77585 9.18807 8.68395 10.2735C7.59204 11.359 6.96948 12.8337 6.95126 14.3779H6.95044Z'\n        fill='#EBCE01'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const TrophyIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' fill='none'>\n      <rect x='4.00244' y='3.30493' width='17.1703' height='17.7154' fill='url(#pattern0)' />\n      <defs>\n        <pattern id='pattern0' patternContentUnits='objectBoundingBox' width='1' height='1'>\n          <use xlinkHref='#image0_12879_40065' transform='scale(0.00793651 0.00769231)' />\n        </pattern>\n        <image\n          id='image0_12879_40065'\n          width='126'\n          height='130'\n          xlinkHref='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAH4AAACCCAYAAACAc3zqAAAgAElEQVR4nO19C5QdR3XgvVX9PvPRjCTr/8d/C39RzMcxXoPtOASSEAIkhCR817FJIPyyCYcEFsJmAxvCcVibkLAhDjFmgXiNY3A4YHDsrGLWNsZgC1tYlvXDsjySRjOaeZ/uqtpzb1V1V3e/NxrNvJFGcu7R05t+3V3dVbfurfsvNMbATEFNPLlEHPzb34dDX3qLVntXI6JGbYQRqIU2gpul5jF4gD/23zr//PR1jNCAmtug1goXiSO+cod+deorpj9pAIO5axGR3iNri4/LbWTt0msKMKgBTeTat50tPhvLzQQNuv+0u1BjOoaxXHwgWfprN9XWvPPPxdDp+0r3ThNmjHhz6J5NZuT3/gGTrRsxppeTpWs6DVKxf9wfh3w/2HSbH2MefD4ftNWpXVN4fqdrpkJ++FBwSPbtEPLDc6b4vsa1Y5FOyEdD39K9twZjkJ9D86DTd/pMrWmmg9HCHRpqLZ1Q1I6oKlDirK361L/67cqKK75X6tA0YGaIn9i2zOz+5X9F8eTZ0LAvrB1ihJugwg9mkeKhQPXpQNoBSw8dUWeID++f4p2LCAqOtda2vdzlaN+D3zVDaHqeXpSxE0yEwnPKY0h9iRxCscs1ZaqnMRTB+Bh63/QkEt+w7yMBiKFosX6HOfeOF0dDZ+0tNX4EODLL7ARj//RGjJ482zQUACbE9BnRwnVEhB3CAL/+G91ABINdehVUduaDbd8ed/9oP0IFqqRvP+hCdOiu0iUqRyHSD79XeF9xAqS/S0D+ICBWgNDE1yKvVbYPwQd9n/xvRCx+MgltkS4Eo5q4GdOBQNBowCgDENMkeWq9efqWt5f6NA2IZnITTP7b5VppO5ApVWWnU4r3Y9Lpu7Re6gD5xrJuWitRlEkjN+C2HTHlJd2pDrDIjopILbxnB4q3v9vJZ9l4DMjs3mRtFCa2KVJ82C5Rt1B8P7qlgrgeTyo3LkDIp+VgfPNlpfefBnQggWmAGVvIL2QMo6s4+7siodvv9q7gb3TUQE3r0pX5Nk3wZ8Z6S1ymKFwdEeH+wi7P78DmvQiKJdmzSxudgAmJOKiXjd17CivDGP8QYVm/1JMDHVo5IswI8aZyxmN+4I6qgeJYiw6DX7p4qmsKd3hWjVi6u4jo3EQIhasSTN3DsF3T6XaGqdsoQTBx0Mk76Agg5BL07KR62k9K908DZoR4HP61myCutvza5+dzR1Za6lRhdDqyh06/BWeDCdP1mR2RGJwucPNu9xqjup6b8vmFroYTpNPKFV7L8kr4HJbmTf43WmUVglj++r8vNTYNmBmrX3jlZhh+18dNBJplHz9DZaZSdR4QnT+nQqFKB9dkIn9Ku/QMJ8GhyvTaHCWjTAeNJPhOoGkZoIFMbxMFVpxfuxFk+nPYh/R81wkmMm0k0Hq4hQ5ii1fxvHykvWjPAqK0gqbXkqSV7JNT3vFJufKVd5cePQ2YlQEHnrnhGr3/Ex8Ret8KOjQ6Yck27WA4s4ztsZUKQkMHOL03FMCU1VeFAO3apKHzgg9TgEJHABg8wB4bjcwaWf1BL4AKpl6ra0P67FRdAzu5NK+vXhr3enWoUorQAOFJL0dDqV7PnRNW3y+t+2XiKHGCgr0g/QmXjiTr3vfRyqnv/XSp0WnC7BBPKHrs3X+J+7/6njg2TP6p6mQs0gRI+xupSKhBgwRGP9JfEmKjrRrjKIkNIiStCqt3C5R5AUrSecKjzgYV0VEJgkF7rARAZCyl+WtocjEBOaOLN4yhsAYTuhcO7QdI2jT17PvQJGKKtailyUPnqH9oewIixziVMywayLgzOsZif6PnSI1l7ce9l6d+4FERIGkSR4YNmbWKhvbat/x1fdNnrysh4yhgZupcAIlYeKCmKqBiiwSjIRtUUQNFlEJrMlGFsZSrXQdjRk7EyPF6uEUSqSuW4pVSFrFOqlWx5sEk9VtY5ZcH0yNYyghI1ZQKGUGsj4NlCMoPuGfRwrJd0ovpWUJraLcMYKzAOM5l0pVIu/sEt+EsVMwxtNHZ5CTLCtk2aGIIA9pzKB0InIYmpl1SvATBzyHuIhAkd58mlQIBCcQ00ZIqoIj5PIolMzbVepg14rGy4qdGELIUD4pBb76kfsWA0rEo1scTRx800JYNKmeoEeAHWjnza97oYicEiRGCER15I1C6xGYsX9BkYNxYDuBXZWbhJJOgs4NrZG6jpQZpEBJHmKpSAVRJ2kemYOHMs2BlBISMEyEvu9bYY0QCCBXuh+VcVmaheYTpko+Fd3d9kX41MyCFsSKQQW6biYF4DGGsvvSZEiKOEmaN+Ki+chfPfkms1K6hqYEGAjs2MWKmIquj0s9KJBAZyRzAyi7KOjdEklKOIdMnmoxFs0XLUgt/B0ITD7JX6dx/glm8XyMtG1WMKcNTDdk6aJeECmpoSwVVo5niPJLs+p63MxiT5JYhazmwsomGxD4/4OPCmMA3ZbjPqDNOR1SObhmgiatUApIGBb0tA13/JFT6V+4uIeJYIx6E1FiJmD2CEYHxxLi10Q42Id2wLdoOoMBMoOMVET3SLOfwgpMX6qwFy4DlwIF5JlSTGBHIE8V+Z3o9MIFbgS5y0j9xKmbWvI6TTKKYPSunMwu3VkPJ/2N4fffmlVAosxNB5AQy93asUfi3l8baMYRX3yAzOtkJK/yfVgBlOQat+VhU4hIejhJmj3iUsR9cZpP80tKt84ZFObYvQ95Bwt20ZAEAXdSi1GrmzcKiZEljgnStpMTpJWBmy06Ac8KdcQi34O4U1lrGNwvDQqdHIIuMAWV68E1wP0k+8GwcMPcdOphymmcgsMr0v0DAKw2Gcv2nSVttl3WEo4OeUDxTprSap9COEtCte7R+KzdSpKLRRCjqsUTGzlDiHTjolgoGkoaJOtBL/iIYRDtQBq3ELKQXuhzVsfCHYBz3sGqcF86ks4Nb9Y25i7ufGY1Rlq4jZFYdgudkjDO0gqXQljL5fYQEJA4SZctd3lqYoU4E53gqotUVZOjyRZH6ioSIjj/Fi6h/ItGKX0obdDPXs2qTOllIQBLCUj6v8UKn7NgLLuBZG7NdbZHtWGI2EdCOmVsT2ZYj3J38z42OkwssYyG0OycK2QYI78otrLQmR25glYaI+gESIlRWsia5w6mXKbgJnKqgXm8TkFIrTRoj7MT3yqoM6VjrvNzgbDMsIrJ8Y8dHCrDqI8s6CmKSoWStcdwp3oCMjayCwAZ3jcYyISOIJsrWoE0CEqXV6HiAKkCacMQeKO2MJnZo7CSQkBgN0ortzEZ9EArwHLCCn4kUr5kCM2pmGQOtNM5CJtmynb3Aq02C0EqerkqULhE8CdCA0pqNYvSGbRKiWAgTzJDS+42TurUKqD7TPFL/O/+vQGov07hlwTEbDJYHYNtWNikUCY524bSrDy9zLauayiqAHJgoIeIoYdaI17jwIMg6oGmCJONGJCAi7hlpqJBRxFGYZaz0dwIVUwElaU2NWJiSjjMwizRtqEjBBEHSrQRrMIkcySkTAUoDqKQTxKyebN2VNKBV2460wlLkjDbSDTLTH6lrRqUym6la+UFGGhRNKKxAxcSQ+KXACKg40YK4TQQISYQQaWv6VczFgGUBP718MAapiumyZgIad3aBPFgOE2EEipcZy955gomI1WAV1UBGg+OlW48SOlru4kN7BszeH21Knn7gEjGxb1nFtPqMUQKFETqQVinGzsh2DRc/8CaQk+A9qFZdJnu5YPZkWTuLd9b2jdoJUn4NTw3vmUQslBMQrX4svV5P6x8hU2QWOaZ0Dm6QVi9nw4e9w1OYcpYzdGoUyCgntLEtfPIgiMYIY8haGDU/39vZPQJJTpDKFOz93p9gbP+cICq0ZdtFJKMz87JsAIEt3wQaAep0bISxSx/CQojhFTdJLZXCKBFscjSpvxYhSmIplOpbvrey6uLNuOKC+yvDq0scooT4yS23XS223PqGWuunb0Idk6nM+UyMtUg5FU1EInUiqOc9C1BNLOKFU72cBE2sWxnjpG5LoSJ9uHdMkAGl4hBuzbmsx9NUce9HgiIPjmPhxku5YKV0dAPkPXeejWZzyk1WWmKktd9njNlOOtN4FrBx0AsNOQNNCGyOdsfG+xhYe9ApQnPgtZEwtpAmprCGIJ6Q6Ytm7lcTLCGOJECZfpCjZ7uHJ3acjfdPEDFFTuev8t/t+uq/M+e85ku1c37pWx0RrycOiOZDN13b9+Qdr0MVX560J0GR5Y0DBWOrIyM4Y4pln8b75J/fBOxLwCSYCUGOzNh2nhsc1xEZDk7oIfOdVXlXJuajWMIgx3RwOqiEhvVfYSdT+mpeAMwojd7HTDwL0DoYOJp03suWPqs8EUqex1zfII2iydrAXKBlzjttMq3eO5XsuCkwyTDovSsdt3FhZRoKRib6rpL0D1G1Djqq3NVY/6pb+17wm38jBpawEJSu8YcfvuWtQ099/YakeRhU0gJUbUAWlJztnGaz8PomspRu2NRqUjt0XvIV/Hz00nYQHFGwu7BlKqVIN3CKEBEMiEV03n1adHgZxxGKwEgPzKyeK/glgaO3+bmJs+Eb1i7RdygMGNGm5OoPGbkoBVdm53L+eR9b42wZKhgD8OZmF4RqfKQvyTQc8KvYgpmzEbCfJHHeQuKKbTBJBG3VBhn1XTGw81+umIiq7YGXvONzfmpAc/u/burbetuvx41x0O0mmGSSpUjQsVVLQLj2kNdGHghvuxYShKg4LoBZDwuGlswdERhmgms4+BCcPo55BOapSKQU2TGGw1nw/PtYRGJu7WQNwL8/Jo7qtHsfO9CC2DD7H4xDnjvnfPk0afzfmAbhGpb4Wd534bIYnMfctfmpQ/YHfpbQ6WTx725E5sYTWLf4oH4IhwsWmq1xhy2gug1AllT6Vg3Q7UmIm+NQ/cntr20+ee9F1E5ELD5+9NY31qF9RTtpglYtlqTtIAkb80jfUcV6sJyUbmPAtFWbTCOd90LaIEOTBmBmQQ+pDZ/UMR6YCLz4lji1jaVj0qnZm2cnm0F03qvMbm3ZhsgbVtBeC06l82sr+rh4zznQBXWgpRDB7lwnfaPVFtjKFOrquagcnTqPMPX154Te/NLjAjPzQSP5uHyEyHEl9l9ac7Kx7l8JPj6ADIwCsFJjwdSwpzCGtjZQ0Vb/EaoNSsQQYQIJxSywb8MAtgSIqHZ1/OhXt+jlz384Uod2ra/tf+w9pjEBJk5AEJVTo6SGyApE1SooEhRknV1iioXxajYDhbPUmQkye3A4tPJWUGGDHFK/mTdueCQSRVmfE0TO9g1+LRMVOxDa3SP8oHpkOD0/Rz2+/cCHz0uS9Qha4iIBtcLLF4uhaKNyeOA9VSvj7P4qRUwaZ+DjxY0zB0N23msMxtkXwj6Di+sP8O5Cz62IqXUSdgRQedavcxNEYx2gtgBQS+bGvFyRaqitpqGTCOqmDUm7bZ1N9A7kaRQKdGscxP6t79HjO2+IDu+6/9Ih1YI2GVp0i33LKiK3YBVMfRAmN775s9XTL/ucBJEIU2mDkG1Om9FGmki0Na2F4zd+xbS/dqFpt6xK5cecpctAQPPmKXZBOjemmxjGJztQwAH77duW4ryc5ZcFEw6QzKJlILuu6PIUzqTKErQkHd5SC5rEGXoE2w+som2RzqHuPBd1KR4/s8dDyhl9H6hf6EOvCXlpOJpiH0YpYwfcKiPstALnMjYSnBnYmbHpbEUALHrZD2HT+35F2tltc3X4HYzkb90cnHjiruvqj/3vtypzEHRihWujWmCSGtRrbRjb9cNNkRp5fKPUmt2A2ngBS0BUl3B4zeUPDF7yrmuhC6C3difPe0AocyGrEP5F0kBMFyrMHpQgDEnbCSAc+XvuwMkCtISIitUIgri1gFbcJLCUbxDdeLlMk+Aar+dngqWXlp3E7nVuH2vHsoDOtAinyubDnzIOgAUk2mAUu7zJ3DmRTm7+Nphrg/mCP+/8B953mWYbUHN9pz5UWXrWk/mJmH0TPgZWbHrb+OG9Zyx46hsvTQiv3kNq2mCUgvYzj14glGrXEj8IoF2Eh2R1QPct3dYZ5XnA6vLHrR86G2ytlEt08MYN4xIkMh0mt+YFKVOh7zz/IJ3/20lKaLxVrCQ15QXDYoy8i4zJLlapBlI0anZKvbIev7yK6T2Bwi0j7kSujVwYeKrNBM/IJdSFzzRQqS9/snSiA2DfsicNRSPxmmtYJbciF5nR45qoLTx1a5TKIEGUrECoTO49q9xkGRAHR9n2HJzJscecJ05DSaztoILle6zL1xXvKeM8u7SYsUMIFn0AOJAzmOSvLxtU00flYukDdc1k1jw/CdyJqV80RXj40sUxoutIih+aVthVdWLP2VaDETbkDa2LiOwV0aINT4j+VRc8qDHrDAcy0kVk4Tq0+7z44PZVpVZLIJRlVeHodelrmHY8XZhGVnRqvMhNqgJnIUMOdVAOgVn1QdCrPwiIi51L2MoO6ViUda6s1S7vn5f8O1/TMWcgTZ8qnQkad15OJBlramiN7ljWGt1xvtGhIcq2QSvpwKrzHxQwtGpXQwx+U0pvmbNrTzvRUI1HpJwcWzblUxhkqxQ+PFWWzBSDOmswJlgm8s8hjYNlhkWvB+x7PojqRjCLfsWKCsqmhKWZ+F0R1x26I7sXoK3DQURHRDw096+rxfv7EhM4iIQEwnFD9N+Jg6t2ieqyM/fK4bU7hJSWPQvJli420mECzZFHri41XARZaZO5Nsf2SMItjoO3Wc/JAGXh1uDW15yzA21MIPS9AGDhz4HW46BhEnDRVYADPwNGN20rwuryM4FOJuOegXA1CETfoSOOxL4fX1Yl+VnZuWJclBJGEqKFa3YQzplM1fDaHaSjJ3xWuehXzdGiOPrki0otF8BgbVwnuiTolFhXKkHPFeTDu1IdXFPwYhs0Lga9/E2gdZvVQNJ/2cmy9DcBxCIA07ZCmdepj3KCFim+ey7d0QPr8An5hKuNI77HgW0vAudXpPgIGZHhrcoTOhlcuwP8wiiXn/8g2d6lrFBGJAiI2RgASQNgfOdF8dj+aqn1ALQY2C9EH2hZyDMrFjTwMJeUUVxrwU44zt8/5fUgqytteLVJOGsGdQugugpw8eu572k2UJoNMf2JWpL8u3R/pn3CShWU6ZvSF6/H90scf/IiSGJrCOMCCy5ARURQWXn+g5D2avG67S1ddSFONq6dokA0IX981wZoHZhSwEMcHAGsp7HxKaTrfHcJubcgUpt8+m6kFRNl918MMPhSANW2yxBnwxA3UABJC+CUnwe96FIb02g9NFma1DQn6tyu8SR49oOsLni2dCIA1dp3KhzccwYlnqTakIhAiho0FYIcWpNRfGVg+R4YXPHlKIpS6xHFcJMZsaYbYA7/dGPpCSFEw/tADGZZrOSjzwUYFt1oczVAgUnUC8qasmuWAC75DeesoZh3xZI8B2+QTVy42MWV14GproA0YaqjOtYdQhUuTIPqCbBcNwRGLp4yph4PPXNGVTSYcFOXO5lzZQRmcPmXzdCqXZCy+uHVE3po9S7EyCLPSJuWRLlvRkN7349+ofSEAER92STK/kBtMiVjRfZm06egGYGb5ZkPG1hyx+pS663CzNNmrXdO8qX1vbYWcPVbrVHHp0cjHhUC0/zLzjaYWfSLDGt9IPqXTinVt559+OeEtraK1NdPQntUAVy4/snK8EqWEVJSTBad/hilOfu0YDsYiimkOrbzotITisDyQWb46OYynZEeH96eObHdD8UgiSAggiKIBn8WYMGLiQfaa3Wnj4upT5qAC68CWHwlGJokxs6csnFHFLQImPvlrBPn7ACV8V3no3PspMkdyHljoBaemhZRSFuqrzzvIU2eASFtbBezCgRIFCQHn7owGd25vPyY8MWEJRF0AYp+fewEs6B46zoNfftZdI9dt+l0y068/hcCLnlDltzgAjKm/NAEWPVOgIWXWeGIJ0zsQqy080FkJu6MozmTsw6XuB6ye+I8cuqqJ+1DO5epA09dYJIYfHCY9eVT8KaE6vLnP+SvzQzSAyv2NGT/t+rR5FWq3QQFFRBaQUxqWmtfv24eWAuwrmuynsbqpEBckM5M41wmRaudDyA8WuSn+r/MJVWScMbhYDZoHpLKGohqG8AMbALoO9tFsycuOqfUagdIgJYt2PAnoMceAnPobhCTWwCaT7O3jQM3KPC6y+sb76Z28Qi9ZPca6+2pLAyisX81tp9dHJMbNszUkRJacuBOMbD86Yr7LUU8KfV6aO0OcWAUFFYgIhctFyxoQV32Q3tk60thxYUPlJ7mARfsNwYX2EgawUjwAU6ZOdXr8TMYDe9B43vJy6S5rJgRg4DV9QD1s0ANnANRtARADLsQLie0pQGQ2fpvff0B60RbZc4G3Gi2Y8jhiwHoo8fBNHaAOfx9gPEtoCcfB0gO2SAQdBYS4dl+wSnUQ7uFifoOl34MoPXsj182AAm0gypZFHsgKxFEC9dtry49M62Hl3NBxUMbttVHH+WBSlCCxJhSAiBSMaiRx14GAJ8qPS19qf5RIZypCCDzu3eqLTdDVk+x5lJLMLVVgAOng66fDaZ+GkA0BKxOGic4miZn71r/dOxy1RPHcRwV6kIeHt9qDTd0mWQXcsvJOhXAvo0Ag+cBLGsBxiNgDm8BGHsI9MQWwPhpDvCwBqOyx7EXYCOLTtkxVVNi/9ZLgGPtYhv7b6y3lZw77cFVe0JjTA7x0cpzH4Ldd3JCgdRNLj4giW0Qizv0xAvjsWerlaEuUiUu3W40Xph2G3tsqKGgA0Lw4t8C7D8NtOmz9mdGLFFWwwoxStnUq8QEzhZrPrZlTmxz4d8eOHff2Kgfm5+VRYVqaINI3ESRiwEXXQ56+HIQegLU4YdB7PorgPbYTKsKTWcAAPuWdFXlkvGRKh7afhHEyHEAMbRdJBI6w80F94fX515TLlq/va0iXhMoeE9y3xGSWEH18O7lMIU+j9Vl2zDKwp2mhJlI9VQ9wtQA6qcy0gUVIFBNV+nS1YajxAXKL8+nrGTn/aLrr8HsY3P6bH6dcb/b1cWdA5VdS54c3QKBLQ5Jk4PPByP6QYskq1MLR6cGHhGEAVFZ0bW0mR7feb4Z335qHLdsCRmosgWSbDNNyj4aXpvjFjkMiQVrdqih9V+IomoaQUNpUdo0oUJxXD/d/NulJ/p7o2VPpNRVjLAtBkPMhBNQcEPyLOiR2xjpxM5YngjVMSomQNTPx1YVZSucDq/r/GGdntKWiGWDvZaEW4pXw6BNjsNTiY0a1q6c6p6bAJu7UqEPXVw8Hqk441F1HwGqS3aWTjhI9tz3+j4Tc64isA9CsYYVkf4+uPomuWBNd8RHC5a19JIztyBb8CJbTIj0QQrfiVsgdnznd/XYTxeWnsogla0ska3xufAkDzPW422tGxi7B/SBewGlC47k7B5X8ZmQYZPYMgEOjqC+dfqASn9H156f0Jj7jkDv+wYAfUQnd8YRON9RASVM1jva6fXYT4fFju+8TVPMI09Um56maSWXESSLztwiFyxrTflmct2ldxF7pwhbH5Ejic3Gbai1nqk2tv3L+0tP5paiNnnn0nXThVmV7NczttzZEiEcQ37wNoDJbWmSoY1EtcEUigNGjdO9LYWy3wFU/sN5ear8d5cP17Qx2Yd9AuM/ArPnH0vWyVy/e2WeZjFFqNLvJM3/5OvvrTf2LE5U23ocOXuoAjKqsLwWbbj0ruI9ZcQvOeeR9sD6mytRNc3d0hSkp9tg2k0QP7n9g6395agcY2SLByNNS+1isp0pxXsTMCUe6AbE+74IoEbsOeXCsDWyNO4FNP/h0g1U2Sr8ECv3x+HfXT5Ze041jPdBsvtGVuv8shgGY+Zi6nsAHE2DlZJLNjmwYxk8efsfeWr3sRRKSqhUatBYsPYmueSsLcX7SoivDK9omOddeSdUq9ZNC+iKoytIWpNQS/aB+sFnvqInDuRsCWTAgbbm9GXb8hzY49EFgkYRiGQvqH232chRn6XD5cstq2atkoW9IGsnLXvegb1P48Ml1Cl8WseQ7Po8RM3dIKIqeHNAMX9vpsJdiViIoyVUIq2e0+MJB+0ffPpLfc2RahLHoMnzyFk1EUjyu1QqEK278hvR0IrShCkhnkCeccXXJ2pLb8VqzWZd+jVNadATk9C/73uXNJ/4Px/Jt9Q3qkw1y2LRWRpUT4S71Owa22pVlHDR+AHog3e7cp+JE8gS/luyo4KcTIk7pwPbvD7qDxdGcraJ5OmvAoxt5lp4CSQcvMGeOVFwCXtbxizZPWtkWAER5X3x7cdu/6P+vd97Wdw8zPUJkFNakIMuKtU+aNVX3iJOe+m3Sw12Q3xt4fpRPOvVt8hKHShEl4QYjgCh9Bya7a3DUPnxzR9s/vir78oaWrBfULUGF8euuai+dgmSvTBq+DWz4pIeXOz96HdBjz9sLWciCSZWkk9UQy8IZsLg0XwoX5+cWPrgfQDP3s7Ppn5VeHx8oGoHKf4IgZudoCgX2RzFPjCQ+eKbj37l2ujxz39MNcctpdPaDjEktK4TV6QMqDNeeWtl0fMOdHhEZ8QT1M64+p8nh8/+62p9wFZ5RFu9AlUMut0A0RoDfPjT17ceuYWFPVMdeobDlcHpnL7xTn2eDQUY7cKFHZWRHf7ANwBae90GQJrVOisNxU7l0gWHkT7qD+oITPMpMHv+Acg8YnPwnN8h0F7mxB/PEdJkmh7m0OrmD29+r/zBpz8D7cOQxK3UMUSVRBFqUB1YAJMLz/l03+k/98+ltrImO4McWNaSP3PN9XFl6JuV6iAjn122rMcqUK1JkO0JkA/f8D+amz9+s2kbwOqQTY0yUzhEZuuPR2frdzn6FCeO8X5IRr/jdHdfkcKlEjsJ37qYu3x4Wepyzn2Im5i9t7O5VriyJCnyobyu99ofLypDoGMdNf7vn32h8sPPfFK2x0G3JtzSpixXphIu1YVyXmkAABWNSURBVBq05eCd8qK33igG8ypcbhhL6lYBJn7wj6/tf/hvf1/Fk5fqZBIMsRWXYixI5avUIOofhEbfaVBb9xgI8UyZzMP6dN1YfRDEMeVxEYwtMqBNDcTqawHFYDoxpuIs3QopBC+ULS802eJDkGz9EAg97goT+iVEuvInWbvZ4JYemv3dYVUI3y1rQ9g9asSp0Bh7IfRPbgPVOAwqjq0hyaWkmagOMqqDqPbf0zj/dz7Vf8Ebbis1HMARix8NXPibX52ceGZl/1NfuzRuOJc7qU+CYvJim+J8OIFa8hiI9gRAX5bM6vvn69PZm+cm0taQbZpUznSCmVymaScwJtS5g8oVDNkx2yP1JJADxNr/JWQVclVaQGG2MXdhVqwIBUVWJyehf+wxiJstMDrmsSceTAmmJqoBUFGk/gV3T677hVuPhHSYbtWr+oVvuaGRNPv69nz74/HkITDQYuSxN8zYlzATGkwLQdYLZUZN/rjnSGfKJjt7zW3fVax8aQIOpPP38U+qMDHCDRPSmpm2ajWnzWuXcu3KsAXFGjsarI6qKy5NUojcVmkcTNFEUM0G+wg0V/SWVvYirSuqQZW47qqX39n/s++bVg37aSFeDCzW1U3X/GVD1ht9O+94rWqOX0aWPN55SbVcUcAYTEMCDNNgVcBXhsOO0l3vIROsbOi0dQf7MqAFlcpNFts5/3eR9zrxlNVT56Gj6h8qylWy9gmbvtBBCDNd5w3mNSFONI41aNXkJNQIyXYQWetctQam1n93Y93P31678O3XlxrrAtOucycHlyZ9l77v0xMPDo/Wt34prlaaVyTtBtdu55pspEOPKTArKf88dmVKTWm5nytWT4UQuQQoFXbgjQds+TPFhcsKCEnr2GBWkL5Eqco3zEYf0tGp5KESE7ZuTiijBomSU67xR4C0uEJBNuaavA07EbVEW4ePvG/9NUhwwbeSM19/U9+mt908det5OOoChwOb3v6FxsIzt+CPPvueemP3G5OmcN6ghi3pJ6wfWxvTWWWYk0waV/SAq2lluevatFxB5eK67cuUZWVPy9uceawmti6udrtrpHWITLrPXDnwcmYQmnzzb0KVRuo2oFVUoRb1AVRrkNTX3aTPf/v1fae+9KGjfeCMKlv2nXbZg8kpG35v8sf/tLm689uvqprxV6gm7Y5jQLcPcHmcXAGsKQSsXgHVtWc7tdYuysYVU4RuHMYEXx2qRfuAziBUjNQlXt2123jBcZX0FrQZw8X9Y2cFFA2V1EHrfmbrslaHNg7eqddeeUd0zq9+sbZw3ehMmp9xSdNo4brR6CXvubG14fJvxtu+8avip5svr5nDrwA1CSAn0qyWtBhCOjrdEDE7ML6sPCaueKEIkF52ahUnYola00OVlT7xcYS+iKPN08nlDPZcj+ftW/oBqoshxgW3x8su/ndzxqu+0rfywmkVregGs96MyEMysm1JsvNfr66KL70JKz+5CosF3j10Q/os9Hi2o0crAJe8hsuvZYKar47pEeKercmTNWrZPVnEogH3qPIESV+PPF87bgBo77RlxlLItgyHkg5efNcj6/ElNi+oItjP3K+GrvkUrL30rtqSM2a9Hw30pF69b2jJaSPRktNuhpG+hjn4x1dB02q6ItSmYK4o3ic9JbaYsbElTxFjGylMEj4Zntr7ABpPgW7uAKMmrN5PknL/GYAD5wLW1wBQaDVxjTR4kpapyIlYUSqwZkjtjPSZgN3MQaSVNfgZtQrg2jffUFv7llt6OWI9Q7wHUz3nYYwHt4AY30j13zWXGgtCrHuCdISS3JtmZStIy2yyn/4ZSA4/Baa1A0RygB0ZVK7NbmDQAGjvBdPcA/rgZoDKCjALNoIcPAdE/2on8NuwK+MmrMAoZe92/7okpfhZ6/FBSVKui0vev2ToQDR4yT2li2cJPUc8Dl24LameuSWKH9hIzhShO+TJzxqK3iuRlSWn5Ir2AVCNHYCtnQDtEQ6btkG/5MuvWnWOlgQKXiDTc6VmvVvxLtD7dwOM3gNJtBrE0LmAg2cC1E6xxReJmcSKK1J7ww0G8f690uNZM6GAgooG0XfeQ7DovO2li2YJPUc8QdR/5Z3Q+P5rYbJDKklPWH1oR7cGGK0OAIzea6Xg1m6Q5J/muHLpKnS6ypnEfSoRQEKUOgkQSeub561PKrY5CmFqPwFq3xOgDy4EUd8AhvIKm7tZhmDBUdtUapNu9V2m+BkJd2iRzoGk5HZe/Iqvla7pAcwJ4s3gS75rxvofQ5w8G7TukT8+94TckS2BmoBpbGEyIx85y+JRti+NzXOrWC8jx2Q0bdlUak06o4nzp4tIgkoEb5Vr1BiY8Ydt1XopuHw6bz0mfOXLLJ16Nmye7xXgKn3bQE5lBsdx0ZV3lC7uAcxJ+D8Onb8dqpfcjRXsqWsyeELpkKmNqNLVdrO2BFt719adc7V3wYZcCzWR1bIPbO2WamOQ0m5jxm5fqqRNGxu47c2y7cVkqfzLTP3xljhkdk81ARy68g6x6Pyes3mYK8QT4MJfvdlt61g40UWPOSooziYb5cK7XlHVUt5WNBjEQn08ygSGuJGfPmmyZ1bvz9buE2nx5lyF7pTCCzkEM9Xjjd1iFN1+NUZVAZa/8X+VrusRzB3i+zfdZ/Csr0Ml7L2edX78dMCkwRiF0ucu3t7EY/ky6uDtBLrETErHBZg2VU91ocvpS336JHbUz78fF7zku6VrewRzV4Kqfkpiht/wdzat2RtOgsDcbgaZ2UCnbNX0cWj3siH9nOrxzwFMucYH5F+6Dn2aV2YhNKuu+wvsP2XOqi3MZe0xEMNX3w7ivNugolydXE+J4PZd6zGgI5tCASQvfbPBNRlnXT6D3tXdm64/ouN1xnkzKwBJ/eJ/i0551a2la3oIc4p4pvrFb/ufgJXtuaKBQswNxXsoyhHahj5TaRTTPpildvFX796lkx7fCUoU76ts8N53CNG6P/go9J+SdLi1ZzC3iKfBXfKqu0z04nug4hewToURuozQDKHkDeQa9glA+4Ctp59uS+ov6M0wlFKpujCSkoNIObWygiAX/MJtsPwXv1W6qccw54hnWPb+jxhc8Ijx5UVzewp1EKhmBMWy5/k6NJR2BXqSs0l9hEtWpas3y06JkrtAyRGDbntSsXREbfhQ59zEHsMxQTzp9bjgmuuxgjv87lQAkO0d15M1trz9l427lyzQQWvUlj4Qzl2c7u7UO4YzXT2+tMbT61Qk4Ko/+LBcfNGs3K3ThWND8cDFAz+nxcWboR4kIBQrYfYAwoEHP7laB215FB8lg4HTqMc5fl31+NIskKm1Dqqkvl35ddzw7htLDc4RHDvEE6z68B8YXPVvkKaSTzHoAVXo6ZYUxWB3RrQTCykwRB+G0u7/6U09sikc6R1LC75b17mY6Gnb8PRP/E7pnjmEY4p4MXD2Hlj8x38I0P+YNZdOMehpnn157/apwISJG4T09v4pru4hmLJ3Lgclix+wL0HD4IQ+9VNvxeFz9pTumUM4thRPnT3lqs1q+LpPiprc7jMvOlG0SXn1FINZbNttOsSUTunTybNZadJjAKW1O9ehvOzB9SArkTZrPvgBsezne+5vPxIcc8QTyFXv+Jzqf/MN0FffykWJ0vCqwNLWreR5N2D1zAl45IhJ9rs2jl0Xp6T4QJbgyqH1Kujl7/lYtGF6CRC9huOCeAK55gOf1LXXfcHUpSvKQ15tmSHfLclTDmYIfgcoKlHW3Ef7r1nBDnHKFaWXUNwkIQfZFl2AVQFq8Tv/XJz2sQ8fmzcrw3FDPIFY95GPmcqv/x30RdvsrtPGYpx1fbfVd6cCiR3AhslTIeJnAaFpvXDahRtMwYF7CeEkLU9Yp03UAJLF13xKnvmJDxybt+oMxxXxBGLDn37U9L/5MxjJbTYyk4oVCVeyxAl2U62dDIZdmpDs4/LjqVNImM7FCuYIQj3exuOFHSU7fE3rJe//aHTm9e89Zi/VBXoWXj1b0Hs/91u4/5MfBoxPg9jFxEGQ84ZFU2/qbOeoWNN61qZuGcE1qiQEYdZTUGJe1w4Ocj78gg2+1IZI93wP9fdsByjKo6839JqPvVtu+L2/OYbD2hXmDeIJzMjtV+HIx/8UxL4XUUJuWukaQnUojLClPWAPg1EH7A5Tvh2/jyxMB2m5k8GBzI6DcOdO45VG4Ri/XXoQlUM2C7lhu17759eJFb/yzdLNxwnmFeKBS3M+uhb3/+WHMLn37ZyNnbisWyECarJbbSOVGtOuHhCVSXfRK2lZ9A615roiHjHvKi5QvMEgY0bbfeftJgCUUiUy06+2G6pz9RgKqBj8xVtx3Z++G4c37ip19jjCvEM8gZncL/DQF6+B0c+9E+DwRkjSemJcgAgokIIQTo4XXzNW2cBHy+ZdASa/335PWb3dsszGRNrN/n1cPWfiUFRvlcqTDY/Dqg980Cz97c+IgSVz6mKdCcxLxHswhx442xz629/HibuvRgnPg1bLIl2MA8S2ChUoTDcxYKRjgeILjpiuiC/lzhUonp25oSPIRe2GW5cQ/hVCsvCXbxGr3/VxseiSh0udmicwrxGfwsjXrjYHb3wftjdfxVRO+zSg9+q55EXt04+0TXkypiO774p4mB7F51U2W5mC5U4yv9YuvF8v+y8fjla+5s5SH+YZnBiIJ5jcV4OJb7wGDtx0rW7/v0vRJIJ3mHB7whaLG9ja837tTlKBa6aID6V1zr+QCBxIaiJtai+4D5f85+v1oqu/JvqXd600NZ/gxEF8CCNfuxpGP38tTN53GcixxbRhkkkkS9R2TbfcgIoscjXncHv0WVG8sLtpUr6AXjgK/S++x5zy5hvnk7Q+XTgxEe9h7KEzzcQ9L4fR296gWz/cJCuNAbuNmNtdwgRCIfg/j4B4isblCeTu9XMmqoBp1ydg4NyHzPCrb8Hh//RtHH7B1tI7nSBwYiM+ADN237k4ueUCffjel4vWQy80zd3rsdpcwBbA2E0E8NG9WTYMS+m0Y4UP/SYBrUJLSASmXZ3A6podSf/5D8rhl99p6uf8SCx68SOlh5+AcNIgvgh69HsbIdmzXiSji2Hv7a81k//+arvXjN+9InbBGhVfM9R60AZecjus/OUvG7Fg1FTW7jhZEF2EOUmanA8gFr6IarTbOu17x4Zx++ZXQ1PZvfDIU2K1/TQOn1VCCgt7/hV3woq33hwktpyc41P65WQErSrgas7a/WbChAqVFjoi65zW7dpzYUhOWorPgbOyGZ+yLTLVTwehXba+8slM5xk8RyjeRnfYLURsSTIG4yN9tDME6ZLUf7LCc4LiNWpB9XjCBFnjVDkb8+k8fvPOoj538JxAvEWu4LJo6W8m8/h6sMUT/oPiTxowSgugIsAJOr09iN4GSDfgFYkCnfDGHic9PDcQb1BTjf0khrT0mt0FUlg/O1KBFA0yoYLk4tjFah1HeE4gnpZ3bJMFD9l7p1LcWmEu4oKIyGXRlDLiuTAoz401nsrXt2kfHeDCSFyLlmYD1bXRCLRTPtfJixCE6kmRnnkPzw09ngT6toEkJkZuQHGwBqTrPcfSUUxHi/36zwkV96RCvGmMRNDcfjpHXHGMHC3mZI7bs97UDEhpw6ZkYa8aX5jQVKkE6tNrYfS+cwGiBIyKAGViaN/K2mlbsW/+hVDNFE4aJ40e374Yf3LNl+HwvVekUTnGbkRgXa8qH5yBQQWusFI2bymGLq4jkP0HX3oXnvnZX4fBU0dKDz8B4aRha2LsrldCfPcVlI1D1jjDGxTZv23cXbDTtTG5jQJ9XJ7V6zUnZ1B0L99LhZDpfPzdK2D0rleWHnyCwsmznqkDS/jbhV+LHCObjv3duOidjP2n38ZFa+pDXfbOP/HgJEJ8lNjuGLvrcwCcPevy17stbWm9nC7X2LIp8qSR+E8e4Y6nsHO9YmT3oPOpTJyI6a7rtOMUZpuk+b3gi9fYuL3yhDhR4eRBvBS06S0bYmhppq3ItNuOhKx1ygQeubRYcRCLByb3W9E9K+iYnnGSwAmHeDO2c6FpHF4AanLAuC3AmLL3711tJgZBNxREKKBtNH+TR9bo/LoNAe2me711qI8XToyEmMnI06uNuP9s1EYgSl5PTKXWkrWFB3B4TW5v9/kOJ4Q6p/ZvWxLv+O4r4t2bL0sObT8TGiOX0QbHvMdduucbQjuxCQ605x1VsOZoWVbrMEBqoX5+h/3iSgUSwW5VKqRNz6K/qc1EI4ioH6BvyT3R8PO2Vldfck+04eV3ylPmv8o3rxGvDu1a0H70K2+OH//Kb8nmvosJGW1ythA6aZ+YDggC517VHbYcmy3QsxRrDNrVrndePdRQcaVOktrS+2vn/Nrf1za+7gvzmQvMW8THT9598cS9H/1ENLHz8iRRltUyBDXq2OQqsmIEbhdm2pCXKFMJKFUZ6zZZZg6aY/C1q5Yp0UAUSUgG19wzcOl/fX/l1Mvvn7NBmgXMS8Q3fnDLq5ub//t/k8nkxnasSgETnWAqhIoOQRdzCfQeNbL9R4Nb6pf84Z/0XfjGOa1EPROYd4hv/eirr5z49gduQN1ar3Tk1tMjv2OY2+b/DmpmdPzNw5F+K1WpPAL46yWH+FV21K76s9/tP+91X5/6rmML8wrx8Y7NFxy6/bovYvPQxiS2dWdpFxlJu0yVrj46EKVNRKYP07k3VAUlB3awYgmC9smpDm0ZevVf/0Zl/fxJm543ljsqhjD+nb/4UF/j0EbaK10YSUERIBLSwa1kTr5z+pguxyzPKSidR97qPH88VTvF66bzfN7LWNt3YGmfc/hobzuAauvQRuob9bHU8eME8+ZFGo9/65dg7/dfM9YmvVvwPvA0eKSacdAE7Vqp7Qe6HPtCCKXrjfXD+2OtnVvWOWHCdqyDJ3+t6HBdp2OK6yMTD+1ozXGdJmHj8WTLgHj6+69pbv32q0odP04wLww45vAB0fje318bKQNR2+3a6DZ2D0seHQ2E1xu/IWD+qR1+6/y76bTNePEuY9+ZEnWlNrzpBBmOaD88dvWChsn7Pv+O+ulX3YGDi4+7zX9eID7e+8hF5pnHr24qZdkohUadcO4QBFuF3Pr9fYQP6/taQTtGkM88fnX76Yc31c542XFX8eYF4ttPfe/SqklgMjGuWGGBvtJadzj1cRGC86Zofy+2OcXvtnza9J5vNyjQ6XneU9uVQasKhNaO77/4PxDvoLH7kYsiCm02qssWpEfaDO5IjNhtVdLhtzJ0+h2PcG92rMoPcuclJDGC2v3DTaXmjwPMDyfN6N5VijbkUbZGXCfUn+jAAqPQoA/tWzEfujIvEK+bh4dEG/ah0RGisMXGjRaa/jbkCTsZQp6Ry+xCY3TxcX8VAPj/B86TaCOi8qUAAAAASUVORK5CYII='\n        />\n      </defs>\n    </SvgIcon>\n  )\n}\nexport const AmmRankIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path\n        d='M9.45879 10.2699L7.05319 12.6754C5.0453 14.6833 4.4245 17.5836 5.28779 19.5818C7.22779 20.707 10.3124 20.1638 12.4076 18.0686L14.7453 15.7309C14.9781 15.4981 14.9975 15.1198 14.7938 14.8579L13.5328 13.2574C13.5231 13.238 13.494 13.238 13.4746 13.2477C12.6307 13.9849 11.7383 14.6736 10.8168 15.3041L10.487 15.5272C10.1475 15.76 9.71099 15.7212 9.41999 15.4302C9.12899 15.1392 9.09019 14.6833 9.32299 14.3438L9.54609 14.0237C10.1766 13.1022 10.8653 12.2099 11.6025 11.366C11.6219 11.3466 11.6122 11.3272 11.5928 11.3078L9.99229 10.0468L10.0311 10.0759C9.82739 10.0468 9.61399 10.1147 9.45879 10.2699Z'\n        fill='url(#paint0_linear_12879_40038)'\n      />\n      <path\n        d='M5.26825 19.5723C5.27795 19.5723 5.27795 19.582 5.28765 19.582C4.42435 17.5838 5.04515 14.6932 7.05305 12.6756L9.45864 10.27C9.61384 10.1148 9.81754 10.0566 10.0212 10.076L9.98244 10.0469C9.72054 9.83354 9.34224 9.85294 9.10944 10.0954L6.77175 12.4331C4.67655 14.538 4.13336 17.6323 5.26825 19.5723Z'\n        fill='#5BACF3'\n      />\n      <path\n        d='M19.1874 8.36347C19.208 8.38413 19.2493 8.39446 19.2803 8.38413C19.3836 8.34282 19.4972 8.31183 19.6005 8.27051L20.2306 8.03295C20.2615 8.02262 20.2719 7.98131 20.2512 7.95032C19.2287 6.78318 18.1235 5.678 16.9563 4.65546C16.9254 4.6348 16.8944 4.64513 16.8737 4.67611L16.6362 5.30617C16.5948 5.40945 16.5535 5.51274 16.5225 5.62636C16.5122 5.65734 16.5225 5.68833 16.5432 5.71932C17.4625 6.54562 18.3507 7.43389 19.1874 8.36347Z'\n        fill='#EA9C60'\n      />\n      <path\n        d='M9.91208 14.1695C10.0563 13.9848 10.1894 13.8002 10.3336 13.6155C10.6109 13.2564 10.8993 12.8974 11.2321 12.5486C11.9753 11.6765 11.7781 11.8454 12.6323 11.0555L14.5698 8.77809C14.6031 8.73705 14.6474 8.69602 14.6918 8.65499L14.6918 8.65498C14.7362 8.61394 14.7806 8.5729 14.8138 8.52161L14.8249 8.50109L14.8804 8.43953C14.9469 8.35746 15.0024 8.26513 15.0579 8.1728C15.1133 8.08046 15.1577 7.97787 15.2021 7.88554C15.2464 7.78295 15.2797 7.69062 15.3019 7.58803L15.3019 7.588C15.3241 7.48542 15.3463 7.38284 15.3574 7.28025C15.3685 7.14688 15.3907 7.01351 15.4128 6.8904C15.4239 6.84937 15.4239 6.79807 15.435 6.75704C15.4461 6.67496 15.4572 6.59289 15.4794 6.51082C15.4905 6.44928 15.5016 6.398 15.5127 6.34672L15.5127 6.34667C15.5238 6.27485 15.5349 6.20304 15.557 6.13123C15.5681 6.06967 15.5903 6.01838 15.6014 5.95682C15.6236 5.88501 15.6347 5.82345 15.6569 5.75164C15.6791 5.70034 15.6902 5.63879 15.7123 5.57723C15.7234 5.50542 15.7456 5.44387 15.7678 5.38231C15.7789 5.32076 15.8011 5.2592 15.8233 5.19764L15.8898 5.01298L15.9564 4.82831C15.9786 4.76676 16.0008 4.71547 16.0229 4.65391C16.0426 4.59939 16.0709 4.54487 16.0926 4.49035C16.0952 4.47993 16.0979 4.46947 16.1006 4.45898V4.46924C16.0981 4.47628 16.0954 4.48331 16.0926 4.49035C15.5035 6.80469 15.7107 7.53967 15.3574 8.19331C14.9691 8.91146 15.8565 9.41743 15.4794 9.76624L9.80595 14.9692C9.70082 14.9551 9.57486 14.7754 9.91208 14.1695Z'\n        fill='#C68C57'\n      />\n      <path\n        d='M15.1086 9.8083L9.79345 14.9644C9.97506 15.1291 10.2576 15.1485 10.4694 15.0031L10.8024 14.7803C12.2553 13.8306 12.5812 13.7507 13.8323 12.5491L15.9057 10.4866C15.9864 10.4091 16.0671 10.3413 16.1579 10.2734L16.2387 10.2153C16.5817 9.98272 16.9651 9.84706 17.3687 9.79861C18.4382 9.68232 19.4774 9.41099 20.4662 8.9943C20.5671 8.95553 20.6276 8.85863 20.6377 8.75203C20.6377 8.6842 20.6074 8.62606 20.5671 8.5776C20.4964 8.50008 20.3855 8.47101 20.2947 8.50977L19.9012 8.65513C19.0738 8.96522 18.2061 9.17841 17.3182 9.27532C16.9853 9.31408 16.6624 9.4013 16.3597 9.53696C16.1478 9.63387 15.9057 9.5951 15.7342 9.44006L15.4517 9.16872C15.2902 9.01368 15.2499 8.77141 15.3508 8.56791C15.492 8.2772 15.5929 7.9671 15.6232 7.64732C15.7241 6.79455 15.9461 5.96117 16.2689 5.16655L16.4203 4.78862C16.4606 4.69172 16.4304 4.58512 16.3496 4.52698C16.2992 4.48822 16.2286 4.45915 16.168 4.45915C16.057 4.45915 15.9561 4.52698 15.9158 4.62389C15.8653 4.73048 15.825 4.82739 15.7846 4.93398C15.2398 7.14341 15.4315 7.84113 15.1086 8.46132C14.7454 9.12996 15.4517 9.46913 15.1086 9.8083Z'\n        fill='#EA9C60'\n      />\n      <defs>\n        <linearGradient\n          id='paint0_linear_12879_40038'\n          x1='9.92147'\n          y1='20.1555'\n          x2='9.92147'\n          y2='10.0468'\n          gradientUnits='userSpaceOnUse'\n        >\n          <stop stopColor='#8DC9FA' />\n          <stop offset='1' stopColor='#6CB7F9' />\n        </linearGradient>\n      </defs>\n    </SvgIcon>\n  )\n}\n\nexport const SpeakerIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' fill='none'>\n      <path d='M13.491 6.07691L10.094 8.39357H6.49103V11.7269H10.094L13.491 14.0436V6.07691ZM9.38003 13.3936H5.49103C5.22581 13.3936 4.97146 13.3058 4.78392 13.1495C4.59638 12.9932 4.49103 12.7813 4.49103 12.5602V7.56024C4.49103 7.33923 4.59638 7.12726 4.78392 6.97098C4.97146 6.8147 5.22581 6.72691 5.49103 6.72691H9.38003L14.674 3.11691C14.7473 3.06686 14.8361 3.03519 14.9301 3.02557C15.0241 3.01595 15.1195 3.02878 15.2051 3.06257C15.2907 3.09636 15.363 3.14972 15.4136 3.21643C15.4642 3.28315 15.4911 3.36047 15.491 3.43941V16.6811C15.4911 16.76 15.4642 16.8373 15.4136 16.904C15.363 16.9708 15.2907 17.0241 15.2051 17.0579C15.1195 17.0917 15.0241 17.1045 14.9301 17.0949C14.8361 17.0853 14.7473 17.0536 14.674 17.0036L9.38103 13.3936H9.38003ZM19.354 13.8861L17.932 12.7011C18.4175 12.39 18.8106 11.99 19.0809 11.5321C19.3513 11.0742 19.4916 10.5706 19.491 10.0602C19.491 8.86857 18.741 7.82274 17.611 7.23357L19.05 6.03441C19.8075 6.49873 20.4231 7.10511 20.8472 7.8045C21.2713 8.50389 21.4918 9.27664 21.491 10.0602C21.491 11.5952 20.661 12.9686 19.354 13.8861Z' />\n    </SvgIcon>\n  )\n}\n\nexport const GoTopIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' fill='none'>\n      <path d='M4 11L12 1L20 11L15 11C15 16.523 15 20.968 15 20.968L9 20.968C9 20.968 9 14.458 9 11L4 11Z' />\n    </SvgIcon>\n  )\n}\nexport const NFTIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' fill='none'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M12.5692 1.46513L12.1911 1.23901L11.8094 1.45925L2.88622 6.609L2.51111 6.82548V7.25858V17.5136V17.9458L2.88507 18.1625L11.5419 23.1791L11.9132 23.3943L12.2869 23.1832L21.1657 18.1666L21.5468 17.9513V17.5136V7.25858V6.83319L21.1817 6.61488L12.5692 1.46513ZM4.01111 17.0814V7.69168L12.1776 2.97866L20.0468 7.68398V17.0759L11.9227 21.6661L4.01111 17.0814ZM11.7188 16.4006H10.4709V7.84255H15.4901V8.98719H11.7188V11.6975H15.1726V12.8184H11.7188V16.4006ZM6.47512 16.4006H5.73779V11.2047H6.421L8.93062 14.9855H8.98135V11.2047H9.71867V16.4006H9.03546L6.52923 12.627H6.47512V16.4006ZM16.4317 15.4786H17.1893V10.9776H18.7215V10.2826H14.8962V10.9776H16.4317V15.4786Z'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const RecordIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' fill='none'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M8.72283 3.63043C8.97048 2.11492 10.3769 1 12 1C13.6231 1 15.0295 2.11492 15.2772 3.63043H18.3947C19.7935 3.63043 21 4.6899 21 6.08152V20.5489C21 21.9405 19.7935 23 18.3947 23H5.60526C4.20649 23 3 21.9405 3 20.5489V6.08152C3 4.6899 4.20649 3.63043 5.60526 3.63043H8.72283ZM6.07895 6.55978V19.0707C6.07895 19.6229 6.52666 20.0707 7.07895 20.0707H16.9211C17.4733 20.0707 17.9211 19.6229 17.9211 19.0707V6.55978H16.7368V7.56114C16.7368 8.13486 16.2453 8.53261 15.7303 8.53261H8.26974C7.75468 8.53261 7.26316 8.13486 7.26316 7.56114V6.55978H6.07895ZM12 5C12.5523 5 13 4.55228 13 4C13 3.44772 12.5523 3 12 3C11.4477 3 11 3.44772 11 4C11 4.55228 11.4477 5 12 5Z'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const WaitApproveIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' fill='none'>\n      <path d='M6.99885 3.15166C6.95095 3.10359 6.89403 3.06545 6.83135 3.03942C6.76868 3.0134 6.70148 3 6.63362 3C6.56575 3 6.49856 3.0134 6.43588 3.03942C6.37321 3.06545 6.31628 3.10359 6.26838 3.15166L3.53213 5.87201L2.55674 4.92154C2.50883 4.87347 2.45191 4.83533 2.38924 4.80931C2.32656 4.78328 2.25937 4.76988 2.1915 4.76988C2.12364 4.76988 2.05644 4.78328 1.99377 4.80931C1.93109 4.83533 1.87417 4.87347 1.82627 4.92154L1.15166 5.59701C1.10359 5.64491 1.06545 5.70184 1.03942 5.76451C1.0134 5.82719 1 5.89438 1 5.96225C1 6.03011 1.0134 6.0973 1.03942 6.15998C1.06545 6.22266 1.10359 6.27958 1.15166 6.32748L3.19654 8.3642C3.29861 8.46123 3.43406 8.51533 3.57488 8.51533C3.71571 8.51533 3.85115 8.46123 3.95322 8.3642L4.62311 7.69303L7.72545 4.59111C7.82211 4.49437 7.87673 4.36342 7.87746 4.22667C7.87818 4.08992 7.82495 3.9584 7.72932 3.86064L6.99885 3.15166ZM6.99885 9.99186C6.95095 9.94379 6.89403 9.90565 6.83135 9.87962C6.76868 9.8536 6.70148 9.8402 6.63362 9.8402C6.56575 9.8402 6.49856 9.8536 6.43588 9.87962C6.37321 9.90565 6.31628 9.94379 6.26838 9.99186L3.53213 12.7298L2.55674 11.7802C2.50883 11.7321 2.45191 11.694 2.38924 11.668C2.32656 11.642 2.25937 11.6286 2.1915 11.6286C2.12364 11.6286 2.05644 11.642 1.99377 11.668C1.93109 11.694 1.87417 11.7321 1.82627 11.7802L1.15166 12.4544C1.10359 12.5023 1.06545 12.5592 1.03942 12.6219C1.0134 12.6846 1 12.7518 1 12.8196C1 12.8875 1.0134 12.9547 1.03942 13.0174C1.06545 13.08 1.10359 13.137 1.15166 13.1849L3.19139 15.2259C3.29338 15.3229 3.42876 15.377 3.56951 15.377C3.71027 15.377 3.84564 15.3229 3.94764 15.2259L4.62225 14.5517L7.72459 11.4485C7.82088 11.3524 7.87532 11.2222 7.87604 11.0862C7.87677 10.9502 7.82372 10.8194 7.72846 10.7223L6.99885 9.99186ZM3.74998 17.4388C2.61174 17.4388 1.66213 18.3626 1.66213 19.5013C1.66213 20.64 2.6126 21.5638 3.74998 21.5638C4.88736 21.5638 5.81248 20.638 5.81248 19.5013C5.81248 18.3646 4.88822 17.4388 3.74998 17.4388ZM22.3125 18.1263H9.93749C9.75515 18.1263 9.58028 18.1987 9.45135 18.3276C9.32242 18.4566 9.24999 18.6314 9.24999 18.8138V20.1888C9.24999 20.3711 9.32242 20.546 9.45135 20.6749C9.58028 20.8038 9.75515 20.8763 9.93749 20.8763H22.3125C22.4948 20.8763 22.6697 20.8038 22.7986 20.6749C22.9276 20.546 23 20.3711 23 20.1888V18.8138C23 18.6314 22.9276 18.4566 22.7986 18.3276C22.6697 18.1987 22.4948 18.1263 22.3125 18.1263ZM22.3125 4.37627H9.93749C9.75515 4.37627 9.58028 4.4487 9.45135 4.57763C9.32242 4.70656 9.24999 4.88143 9.24999 5.06377V6.43877C9.24999 6.62111 9.32242 6.79597 9.45135 6.92491C9.58028 7.05384 9.75515 7.12627 9.93749 7.12627H22.3125C22.4948 7.12627 22.6697 7.05384 22.7986 6.92491C22.9276 6.79597 23 6.62111 23 6.43877V5.06377C23 4.88143 22.9276 4.70656 22.7986 4.57763C22.6697 4.4487 22.4948 4.37627 22.3125 4.37627ZM22.3125 11.2513H9.93749C9.75515 11.2513 9.58028 11.3237 9.45135 11.4526C9.32242 11.5816 9.24999 11.7564 9.24999 11.9388V13.3138C9.24999 13.4961 9.32242 13.671 9.45135 13.7999C9.58028 13.9288 9.75515 14.0013 9.93749 14.0013H22.3125C22.4948 14.0013 22.6697 13.9288 22.7986 13.7999C22.9276 13.671 23 13.4961 23 13.3138V11.9388C23 11.7564 22.9276 11.5816 22.7986 11.4526C22.6697 11.3237 22.4948 11.2513 22.3125 11.2513Z' />\n    </SvgIcon>\n  )\n}\n\nexport const LoopringLogoIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon width='24' height='24' {...props} viewBox='0 0 24 24' fill='none'>\n      <path d='M23.4736 11.8583H14.1426L16.1262 15.0013L8.90438 20.7588L23.4736 11.914V11.8583ZM8.70878 20.8839V3.33333L1.33334 15.0152L8.70878 20.8839Z' />\n    </SvgIcon>\n  )\n}\n\nexport const TransferIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon width='24' height='24' {...props} viewBox='0 0 24 24' fill='none'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M12 2C6.47828 2 2 6.47828 2 12C2 17.5217 6.47828 22 12 22C17.5217 22 22 17.5217 22 12C22 6.47828 17.5217 2 12 2ZM17.7134 10.9066L14.7808 14.012C14.7403 14.0563 14.6909 14.0916 14.6358 14.1157C14.5808 14.1397 14.5214 14.152 14.4613 14.1518C14.4045 14.1527 14.3481 14.1408 14.2966 14.1168C14.2154 14.082 14.1462 14.0242 14.0974 13.9506C14.0486 13.877 14.0224 13.7908 14.022 13.7024L14.0469 12.5342L9.60359 12.5841C9.49432 12.5824 9.38942 12.5408 9.30855 12.4673C9.22768 12.3938 9.17638 12.2933 9.16425 12.1847L9.10934 11.3959L7.23415 13.3829L9.26111 15.2901L9.24114 14.641C9.23905 14.5264 9.28163 14.4154 9.35989 14.3315C9.43816 14.2477 9.54596 14.1975 9.66051 14.1917L12.1468 14.1118H12.1568C12.2696 14.1129 12.378 14.1556 12.4613 14.2317C12.5038 14.2712 12.5377 14.3191 12.5609 14.3724C12.5841 14.4256 12.5961 14.4831 12.5961 14.5412C12.5975 14.5993 12.5872 14.6571 12.5657 14.7112C12.5443 14.7652 12.5122 14.8144 12.4713 14.8557C12.3913 14.9388 12.282 14.9872 12.1667 14.9905L10.1248 15.0554L10.1598 16.3135C10.162 16.3992 10.139 16.4836 10.0938 16.5564C10.0485 16.6291 9.98295 16.687 9.90514 16.7229C9.84689 16.7485 9.78406 16.7621 9.72042 16.7629C9.61235 16.7622 9.50801 16.7233 9.42586 16.653L6.31053 13.7224C6.22611 13.6429 6.17597 13.5337 6.17074 13.4179C6.1689 13.3601 6.17854 13.3026 6.19911 13.2486C6.21968 13.1946 6.25076 13.1452 6.29056 13.1033L9.14628 10.0779C9.18685 10.0336 9.23624 9.99829 9.29126 9.97421C9.34629 9.95014 9.40574 9.93784 9.4658 9.93809C9.51667 9.93908 9.56713 9.94749 9.61558 9.96306C9.69618 9.99173 9.7666 10.0435 9.81807 10.1118C9.86955 10.1801 9.89983 10.2621 9.90514 10.3475L10.005 11.7054L14.4883 11.6555C14.5459 11.6556 14.6029 11.6671 14.6561 11.6894C14.7092 11.7116 14.7574 11.7443 14.7978 11.7853C14.8794 11.8679 14.9259 11.9788 14.9276 12.0949V12.1048L14.9176 12.5891L16.7698 10.6271L14.7928 8.76985L14.8427 9.42886C14.8478 9.48918 14.8397 9.54989 14.8191 9.60678C14.7984 9.66368 14.7656 9.7154 14.7229 9.75836C14.682 9.80226 14.6326 9.83732 14.5776 9.86136C14.5227 9.88541 14.4634 9.89793 14.4034 9.89815L11.997 9.89316C11.8816 9.89284 11.7708 9.84815 11.6875 9.76835C11.6455 9.72753 11.6124 9.67858 11.5901 9.62449C11.5678 9.5704 11.5567 9.51232 11.5577 9.45382C11.5595 9.33669 11.6051 9.22448 11.6855 9.13929C11.7664 9.05898 11.876 9.01409 11.99 9.01448H11.995L13.9271 9.01947L13.8323 7.71643C13.8256 7.62796 13.8453 7.53951 13.8888 7.46221C13.9323 7.38492 13.9978 7.32224 14.0769 7.28208C14.1358 7.25256 14.2007 7.23718 14.2666 7.23714C14.3794 7.2382 14.4879 7.28087 14.5711 7.35696L17.6815 10.2826C17.7508 10.3481 17.7979 10.4336 17.8163 10.5272C17.8161 10.5342 17.8178 10.5411 17.8213 10.5472C17.8332 10.6114 17.8296 10.6774 17.8108 10.74C17.7921 10.8025 17.7587 10.8596 17.7134 10.9066Z'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const DepositIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon width='24' height='24' {...props} viewBox='0 0 24 24' fill='none'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M23.8301 16.2914L20.1699 12.9121C20.0391 12.8137 19.8431 12.8137 19.7125 12.9121L16.0524 16.2914C15.8563 16.4882 15.987 16.7836 16.2812 16.7836H17.3923C17.5883 16.7836 17.7191 16.9149 17.7191 17.1117L17.2617 21.6719C17.2291 21.836 17.3925 22 17.5885 22H22.3269C22.5229 22 22.6537 21.8687 22.6537 21.6719L22.1963 17.1117C22.1637 16.9476 22.3271 16.7836 22.5231 16.7836H23.6014C23.8628 16.7836 24.0263 16.4555 23.8301 16.2914ZM10.9544 21.9671C12.8826 21.9671 14.6799 21.4093 16.1832 20.4908C16.3466 20.3924 16.4446 20.2283 16.4446 20.0643L16.6406 17.9645C16.6406 17.8661 16.5752 17.7677 16.4446 17.7677H16.2812C15.7255 17.7677 15.2681 17.4396 15.0721 16.9474C14.8761 16.4553 15.0067 15.9304 15.3989 15.5695L19.059 12.1904C19.2879 11.9607 19.6147 11.8623 19.9413 11.8623C20.0814 11.8623 20.1973 11.8864 20.3304 11.914C20.3527 11.9186 20.3754 11.9233 20.3988 11.928C20.4517 11.9457 20.5047 11.9826 20.5629 12.0232C20.6123 12.0576 20.6655 12.0947 20.7256 12.1248C20.791 12.1904 20.889 12.1248 20.889 12.0264V11.9937C20.889 6.2521 16.0851 1.65925 10.3008 2.01988C5.33375 2.34799 1.34674 6.35056 1.01982 11.3702C0.660388 17.1446 5.23538 21.9671 10.9544 21.9671ZM9.71758 10.1692V14.8827H11.1783C11.4148 14.8827 11.6443 14.8443 11.8669 14.7675C12.0895 14.6907 12.2877 14.565 12.4616 14.3904C12.6355 14.2089 12.7746 13.9749 12.879 13.6886C12.9833 13.4023 13.0355 13.0532 13.0355 12.6412C13.0355 12.2641 12.9972 11.9254 12.9207 11.6251C12.8512 11.3179 12.7329 11.056 12.566 10.8395C12.399 10.6231 12.1764 10.459 11.8982 10.3472C11.6269 10.2285 11.2896 10.1692 10.8861 10.1692H9.71758ZM8.07949 16.2654V8.78652H11.2931C11.773 8.78652 12.2182 8.86334 12.6286 9.01696C13.0459 9.17059 13.4041 9.40103 13.7032 9.70829C14.0093 10.0155 14.2458 10.3996 14.4127 10.8605C14.5866 11.3214 14.6736 11.8626 14.6736 12.484C14.6736 13.0287 14.604 13.5315 14.4649 13.9924C14.3258 14.4533 14.1136 14.8513 13.8284 15.1865C13.5502 15.5217 13.1989 15.787 12.7746 15.9825C12.3573 16.1711 11.8634 16.2654 11.2931 16.2654H8.07949Z'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const WithdrawIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon width='24' height='24' {...props} viewBox='0 0 24 24' fill='none'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M0.486618 5.70861L4.14675 9.0879C4.27756 9.1863 4.47358 9.1863 4.60419 9.0879L8.26433 5.70861C8.46034 5.51182 8.32973 5.21644 8.03551 5.21644H6.92442C6.7284 5.21644 6.59759 5.08512 6.59759 4.88834L7.05503 0.328109C7.08764 0.164052 6.92422 0 6.7282 0H1.98977C1.79375 0 1.66294 0.131322 1.66294 0.328109L2.12039 4.88834C2.15299 5.05239 1.98958 5.21644 1.79356 5.21644H0.715267C0.453843 5.21644 0.290404 5.54455 0.486618 5.70861ZM13.3623 0.0328913C11.4341 0.0328913 9.63675 0.590738 8.1335 1.50921C7.97009 1.6076 7.87208 1.77165 7.87208 1.93571L7.67606 4.03551C7.67606 4.13391 7.74146 4.2323 7.87208 4.2323H8.03549C8.59117 4.2323 9.04861 4.56041 9.24462 5.05256C9.44064 5.54472 9.31002 6.06963 8.91779 6.43046L5.25766 9.80955C5.02884 10.0393 4.70198 10.1377 4.37536 10.1377C4.23533 10.1377 4.1194 10.1136 3.98626 10.086L3.98488 10.0857C3.96308 10.0812 3.94082 10.0766 3.91792 10.072C3.86495 10.0543 3.81198 10.0174 3.75381 9.97684C3.70438 9.94237 3.65119 9.9053 3.59109 9.87521C3.52569 9.80955 3.42768 9.87521 3.42768 9.97361V10.0063C3.42768 15.7479 8.23154 20.3407 14.0159 19.9801C18.9829 19.652 22.9699 15.6494 23.2969 10.6298C23.6563 4.85535 19.0813 0.0328913 13.3623 0.0328913ZM18.3956 7.39205L16.4877 14.5148H14.9376L13.7352 9.66653H13.7154L12.5329 14.5148H10.9529L9.07486 7.39205H10.6349L11.7578 12.2403H11.7777L13.0098 7.39205H14.4706L15.6828 12.3001H15.7027L16.8653 7.39205H18.3956Z'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const MintIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon width='24' height='24' {...props} viewBox='0 0 24 24' fill='none'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12ZM8.11325 8.27287L11.829 6.2229L15.5776 8.27287H14.9658H14.3736H13.6691L11.7599 14.4136L9.85069 8.27287H9.14622H8.55405H8.11325ZM7.85469 8.41552L6.1985 9.32923V15.257L7.85469 16.1959V8.41552ZM8.63218 16.6367L11.8322 18.4509L15.1496 16.6367H14.1388V14.2585L14.2912 10.3741L12.2806 16.6367H11.2392L9.22865 10.3741L9.38104 14.2585V16.6367H8.63218ZM15.6702 16.352L17.5092 15.3463V9.32923L15.6702 8.32356V16.352ZM11.823 5.01941L18.5622 8.70491V12.3378V15.9706L11.823 19.6561L5.13644 15.8653V8.70491L11.823 5.01941Z'\n      />\n    </SvgIcon>\n  )\n}\nexport const AddIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon width='24' height='24' {...props} viewBox='0 0 24 24' fill='none'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M21.1304 2H2V21.1304H21.1304V2ZM3.91304 19.2174V3.91304H19.2174V19.2174H3.91304ZM15.3913 12.4026V10.5906H12.6157V7.73913H10.5224V10.5906H7.73913V12.4026H10.5224V15.3913H12.6157V12.4026H15.3913Z'\n      />\n    </SvgIcon>\n  )\n}\nexport const DeleteIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon width='24' height='24' {...props} viewBox='0 0 24 24' fill='none'>\n      <path d='M17 6H22V8H20V21C20 21.5523 19.5523 22 19 22H5C4.44772 22 4 21.5523 4 21V8H2V6H7V3C7 2.44772 7.44772 2 8 2H16C16.5523 2 17 2.44772 17 3V6ZM18 8H6V20H18V8ZM13.4142 13.9997L15.182 15.7675L13.7678 17.1817L12 15.4139L10.2322 17.1817L8.81802 15.7675L10.5858 13.9997L8.81802 12.232L10.2322 10.8178L12 12.5855L13.7678 10.8178L15.182 12.232L13.4142 13.9997ZM9 4V6H15V4H9Z' />\n    </SvgIcon>\n  )\n}\n\nexport const ImageIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon width='24' height='24' {...props} viewBox='0 0 24 24' fill='none'>\n      <path d='M4.1108 21.8L4.0888 21.822L4.0657 21.8H2.0912C1.80169 21.7997 1.52415 21.6845 1.31954 21.4797C1.11493 21.2749 1 20.9972 1 20.7077V3.0923C1.00201 2.80342 1.11759 2.52692 1.32176 2.32254C1.52594 2.11816 1.80232 2.0023 2.0912 2H21.9088C22.5116 2 23 2.4895 23 3.0923V20.7077C22.998 20.9966 22.8824 21.2731 22.6782 21.4775C22.4741 21.6818 22.1977 21.7977 21.9088 21.8H4.1108ZM20.8 15.2V4.2H3.2V19.6L14.2 8.6L20.8 15.2ZM20.8 18.3108L14.2 11.7108L6.3108 19.6H20.8V18.3108ZM7.6 10.8C7.01652 10.8 6.45694 10.5682 6.04436 10.1556C5.63178 9.74305 5.4 9.18348 5.4 8.6C5.4 8.01652 5.63178 7.45694 6.04436 7.04436C6.45694 6.63178 7.01652 6.4 7.6 6.4C8.18348 6.4 8.74305 6.63178 9.15563 7.04436C9.56821 7.45694 9.8 8.01652 9.8 8.6C9.8 9.18348 9.56821 9.74305 9.15563 10.1556C8.74305 10.5682 8.18348 10.8 7.6 10.8Z' />\n    </SvgIcon>\n  )\n}\n\nexport const Info2Icon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon width='24' height='24' {...props} viewBox='0 0 24 24' fill='none'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M11 0.549988C5.22867 0.549988 0.550049 5.22861 0.550049 11C0.550049 16.7711 5.22876 21.4497 10.9999 21.45C16.7683 21.4436 21.4437 16.7685 21.4501 11.0001C21.4498 5.22894 16.7712 0.549988 11 0.549988ZM2.45005 11C2.45005 6.27795 6.27801 2.44999 11 2.44999C15.7213 2.44999 19.5489 6.27678 19.55 10.9978C19.5448 15.7185 15.7192 19.5447 10.9985 19.55C6.27746 19.5488 2.45005 15.7212 2.45005 11ZM12.06 5.94998H9.94V8.06898H12.06V5.94998ZM12.0601 9.941L8.94 9.93997V12.05H9.94V16.05H13.06V13.95H12.0501L12.0601 9.941Z'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const IncomingIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon width='24' height='24' {...props} viewBox='0 0 24 24' fill='none'>\n      <path d='M15.0527 11.1289L18.9653 7.19748V10.9013H20.9653V3.03775H18.9653V6.95734L15.0299 3.00302L13.6123 4.41383L15.2565 6.06594H7.9574V17.1894H9.9574V8.06594H15.2793L13.6351 9.71805L15.0527 11.1289Z' />\n      <path d='M6 20.8906H4V18.8906H6V20.8906Z' />\n      <path d='M10 20.8906H8V18.8906H10V20.8906Z' />\n      <path d='M12 20.8906H14V18.8906H12V20.8906Z' />\n    </SvgIcon>\n  )\n}\nexport const OutputIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon width='24' height='24' {...props} viewBox='0 0 24 24' fill='none'>\n      <path d='M15.0527 12.8711L18.9653 16.8025V13.0987H20.9653V20.9622H18.9653V17.0427L15.0299 20.997L13.6123 19.5862L15.2565 17.9341H7.9574V6.81059H9.9574V15.9341H15.2793L13.6351 14.2819L15.0527 12.8711Z' />\n      <path d='M6 3.10938H4V5.10938H6V3.10938Z' />\n      <path d='M10 3.10938H8V5.10938H10V3.10938Z' />\n      <path d='M12 3.10938H14V5.10938H12V3.10938Z' />\n    </SvgIcon>\n  )\n}\n\nexport const CardIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon width='24' height='24' {...props} viewBox='0 0 24 24' fill='none'>\n      <path d='M3 3H21C21.2652 3 21.5196 3.10536 21.7071 3.29289C21.8946 3.48043 22 3.73478 22 4V20C22 20.2652 21.8946 20.5196 21.7071 20.7071C21.5196 20.8946 21.2652 21 21 21H3C2.73478 21 2.48043 20.8946 2.29289 20.7071C2.10536 20.5196 2 20.2652 2 20V4C2 3.73478 2.10536 3.48043 2.29289 3.29289C2.48043 3.10536 2.73478 3 3 3ZM20 11H4V19H20V11ZM20 9V5H4V9H20ZM14 15H18V17H14V15Z' />\n    </SvgIcon>\n  )\n}\nexport const L2l2Icon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon width='24' height='24' {...props} viewBox='0 0 24 24' fill='none'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M6.25971 1.66588L7.67731 3.0767L5.36513 5.4H22V7.4H5.3919L7.7047 9.72393L6.2871 11.1347L1.56165 6.38655L6.25971 1.66588ZM17.3599 12.8653L15.9423 14.2761L18.2551 16.6H1.89404V18.6H18.2271L15.9149 20.9233L17.3325 22.3341L22.058 17.5859L17.3599 12.8653Z'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const L1l2Icon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon width='24' height='24' {...props} viewBox='0 0 24 24' fill='none'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M1.66589 17.7403L3.07671 16.3227L5.40001 18.6349L5.40001 2H7.40001L7.40001 18.6081L9.72394 16.2953L11.1348 17.7129L6.38656 22.4384L1.66589 17.7403ZM12.8653 6.64008L14.2761 8.05768L16.6 5.74488V22.106H18.6V5.7729L20.9233 8.08507L22.3341 6.66747L17.5859 1.94202L12.8653 6.64008Z'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const ExchangeAIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon width='24' height='24' {...props} viewBox='0 0 24 24' fill='none'>\n      <path d='M19.375 15.103C20.0239 13.5613 20.1733 11.855 19.8021 10.224C19.431 8.59305 18.558 7.11939 17.306 6.01025C16.0539 4.90111 14.4857 4.21227 12.8219 4.04056C11.158 3.86886 9.48222 4.22293 8.03004 5.053L7.03804 3.316C8.55567 2.44862 10.2742 1.99437 12.0222 1.99858C13.7703 2.00279 15.4866 2.46531 17 3.34C21.49 5.932 23.21 11.482 21.117 16.11L22.459 16.884L18.294 19.098L18.129 14.384L19.375 15.103V15.103ZM4.62504 8.897C3.97618 10.4387 3.82682 12.145 4.19796 13.776C4.56909 15.407 5.44205 16.8806 6.69411 17.9897C7.94617 19.0989 9.51436 19.7877 11.1782 19.9594C12.842 20.1311 14.5179 19.7771 15.97 18.947L16.962 20.684C15.4444 21.5514 13.7258 22.0056 11.9778 22.0014C10.2298 21.9972 8.51347 21.5347 7.00004 20.66C2.51004 18.068 0.790039 12.518 2.88304 7.89L1.54004 7.117L5.70504 4.903L5.87004 9.617L4.62404 8.898L4.62504 8.897ZM13.415 14.828L10.584 12L7.75604 14.828L6.34204 13.414L10.585 9.172L13.414 12L16.243 9.172L17.657 10.586L13.414 14.828H13.415Z' />\n    </SvgIcon>\n  )\n}\n\nexport const AudioIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon width='24' height='24' {...props} viewBox='0 0 24 24' fill='none'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M23 15.3329L22.9723 16.3568C22.7227 18.608 20.8143 20.3584 18.4969 20.3584C16.0098 20.3584 13.9937 18.3423 13.9937 15.8553C13.9937 13.3683 16.0098 11.3522 18.4969 11.3522H20.618V4.48492C20.618 3.80153 20.0024 3.2829 19.3289 3.39889L10.9212 4.84688C10.3925 4.93793 10.0062 5.39645 10.0062 5.93291L10 17C10 17 10.0238 17.6102 10 18C9.98601 18.229 9.94319 18.5847 9.94319 18.5847C9.58392 20.7125 7.73295 22.3329 5.50312 22.3329C3.01612 22.3329 1 20.3168 1 17.8298C1 15.3428 3.01611 13.3267 5.50312 13.3267H7.62425L7.62425 5.93291C7.62425 4.2369 8.84554 2.7873 10.5169 2.49945L18.9246 1.05146C21.0538 0.684766 23 2.32439 23 4.48492V15.3329ZM5.50312 15.7087H7.62425L7.62425 17.8311C7.62354 19.002 6.67415 19.951 5.50312 19.951C4.33165 19.951 3.38199 19.0013 3.38199 17.8298C3.38199 16.6584 4.33165 15.7087 5.50312 15.7087ZM16.3757 15.8553C16.3757 14.6838 17.3254 13.7341 18.4969 13.7341H20.618V15.8553C20.618 17.0267 19.6683 17.9764 18.4969 17.9764C17.3254 17.9764 16.3757 17.0267 16.3757 15.8553Z'\n      />\n    </SvgIcon>\n  )\n}\nexport const VideoIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon width='24' height='24' {...props} viewBox='0 0 24 24' fill='none'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M16.4889 3H3.7245C2.2198 3 1 4.2198 1 5.7245V18.3212C1 19.8259 2.2198 21.0457 3.7245 21.0457H16.4889C17.9936 21.0457 19.2134 19.8259 19.2134 18.3212V17.109C20.5126 18.6269 23 17.7085 23 15.7095V8.33612C23 6.3372 20.5126 5.41874 19.2134 6.93661V5.7245C19.2134 4.2198 17.9936 3 16.4889 3ZM19.2462 14.0469C19.2269 14.0243 19.2155 13.9962 19.2134 13.9667V10.0788C19.2155 10.0494 19.2269 10.0213 19.2462 9.99878L20.7428 8.24626C20.8264 8.14848 20.9864 8.20753 20.9864 8.33612V15.7095C20.9864 15.8381 20.8264 15.8972 20.7428 15.7994L19.2462 14.0469ZM17.1998 5.7245V10.0498C17.1996 10.0628 17.1995 10.0757 17.1995 10.0886L17.1995 13.957C17.1995 13.9698 17.1996 13.9826 17.1998 13.9954V18.3212C17.1998 18.7138 16.8815 19.0321 16.4889 19.0321H3.7245C3.33186 19.0321 3.01356 18.7138 3.01356 18.3212V5.7245C3.01356 5.33186 3.33186 5.01356 3.7245 5.01356H16.4889C16.8815 5.01356 17.1998 5.33186 17.1998 5.7245ZM13.1004 6.14916C12.5444 6.14916 12.0936 6.59991 12.0936 7.15594C12.0936 7.71197 12.5444 8.16272 13.1004 8.16272H14.5319C15.0879 8.16272 15.5386 7.71197 15.5386 7.15594C15.5386 6.59991 15.0879 6.14916 14.5319 6.14916H13.1004Z'\n      />\n    </SvgIcon>\n  )\n}\nexport const ThreeDIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon width='24' height='24' {...props} viewBox='0 0 24 24' fill='none'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M13.236 3.95096L13.9168 3.26693L11.78 1.14041C11.702 1.06275 11.5759 1.06275 11.4979 1.14041L9.34781 3.28015L10.0286 3.96418L11.1499 2.8482L10.5647 6.82908L5.24135 10.0539L11.6451 13.3472L18.1402 10.0539L12.6776 6.82908L12.115 2.83528L13.236 3.95096ZM4.60099 17.0498V10.6028L11.2791 14.3535V22.1294L5.24135 18.8972L1.90885 19.8148L3.31673 20.5364L2.87655 21.3952L0 19.9208L1.45209 17.0539L2.313 17.49L1.59835 18.9009L4.60099 17.0498ZM12.1939 14.3535V22.1294L18.1402 18.7044L22.1074 19.819L20.6999 20.5404L21.1401 21.3992L24 19.9334L22.5394 17.0498L21.6785 17.4859L22.3934 18.8972L18.8721 17.0498V10.6028L12.1939 14.3535Z'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const PlayIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon width='24' height='24' {...props} viewBox='0 0 24 24' fill='none'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M12 23C18.0751 23 23 18.0751 23 12C23 5.92487 18.0751 1 12 1C5.92487 1 1 5.92487 1 12C1 18.0751 5.92487 23 12 23ZM20.5641 12C20.5641 16.7298 16.7298 20.5641 12 20.5641C7.27019 20.5641 3.43592 16.7298 3.43592 12C3.43592 7.27019 7.27019 3.43592 12 3.43592C16.7298 3.43592 20.5641 7.27019 20.5641 12ZM15 12L10.5 14.5V9.5L15 12ZM17.004 13.0063C17.7877 12.5324 17.7877 11.3957 17.004 10.9218L10.4185 6.93966C9.60675 6.44883 8.57029 7.03331 8.57029 7.9819V15.9462C8.57029 16.8948 9.60675 17.4792 10.4185 16.9884L17.004 13.0063Z'\n      />\n    </SvgIcon>\n  )\n}\nexport const ProfileIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon width='24' height='24' {...props} viewBox='0 0 24 24' fill='none'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M12 1C5.93636 1 1 5.93636 1 12C1 18.0636 5.93636 23 12 23C18.0636 23 23 18.0636 23 12C23 5.93636 18.0636 1 12 1ZM12 14.0569C9.10375 14.0569 6.75012 16.3752 6.69307 19.2577C8.16832 20.3477 10.0344 20.9904 12 20.9904C13.9656 20.9904 15.8317 20.3477 17.3069 19.2577C17.2499 16.3752 14.8962 14.0569 12 14.0569ZM9.8484 9.89574C9.8484 8.6997 10.804 7.74414 12 7.74414C13.196 7.74414 14.1516 8.6997 14.1516 9.89574C14.1516 11.0918 13.196 12.0473 12 12.0473C10.804 12.0473 9.8484 11.0918 9.8484 9.89574ZM20.9904 12C20.9904 14.1062 20.2772 15.9886 19.0562 17.5253C18.4937 15.3861 17.0005 13.6268 15.0069 12.7164C15.6993 11.9678 16.1086 10.999 16.1086 9.89574C16.1086 7.61976 14.2234 5.73458 11.9474 5.73458C9.67141 5.73458 7.78623 7.61976 7.78623 9.89574C7.78623 10.999 8.19544 11.9678 8.8879 12.7164C6.89709 13.6255 5.40532 15.3812 4.84096 17.5162C3.65778 15.9781 2.90435 14.0983 2.90435 12C2.90435 7.0689 6.96369 3.00957 11.8948 3.00957C16.8291 3.00957 20.9904 7.07207 20.9904 12Z'\n      />\n    </SvgIcon>\n  )\n}\nexport const OrderListIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon width='24' height='24' {...props} viewBox='0 0 24 24'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        fill={props.fill}\n        d='M3 2.96429C3 1.87978 3.87978 1 4.96429 1H10.0714C12.7804 1 15.3785 2.07614 17.294 3.99169C19.2096 5.90724 20.2857 8.50529 20.2857 11.2143V21.0357C20.2857 22.1202 19.4059 23 18.3214 23H4.96429C3.87978 23 3 22.1202 3 21.0357V2.96429ZM18.7143 11.6071C18.7143 10.8778 18.4246 10.1783 17.9088 9.6626C17.3931 9.14688 16.6936 8.85714 15.9643 8.85714H14.3929C13.8719 8.85714 13.3723 8.65019 13.0039 8.28182C12.6355 7.91344 12.4286 7.41382 12.4286 6.89286V5.32143C12.4286 4.59208 12.1388 3.89261 11.6231 3.37688C11.1074 2.86116 10.4079 2.57143 9.67857 2.57143H4.96429C4.74765 2.57143 4.57143 2.74765 4.57143 2.96429V21.0357C4.57143 21.2523 4.74765 21.4286 4.96429 21.4286H18.3214C18.5381 21.4286 18.7143 21.2523 18.7143 21.0357V11.6071ZM13.484 3.27369C13.8197 3.8975 14 4.60017 14 5.32143V6.89286C14 6.99705 14.0414 7.09697 14.1151 7.17065C14.1887 7.24432 14.2887 7.28571 14.3929 7.28571H15.9643C16.6855 7.28571 17.3882 7.46603 18.012 7.80168C17.5831 6.80365 16.9659 5.88587 16.1829 5.10286C15.3998 4.31985 14.4821 3.7026 13.484 3.27369ZM6.92857 15.1429C6.92857 14.7089 7.28035 14.3571 7.71429 14.3571H15.5714C16.0054 14.3571 16.3571 14.7089 16.3571 15.1429C16.3571 15.5768 16.0054 15.9286 15.5714 15.9286H7.71429C7.28035 15.9286 6.92857 15.5768 6.92857 15.1429ZM6.92857 18.2857C6.92857 17.8518 7.28035 17.5 7.71429 17.5H11.6429C12.0768 17.5 12.4286 17.8518 12.4286 18.2857C12.4286 18.7197 12.0768 19.0714 11.6429 19.0714H7.71429C7.28035 19.0714 6.92857 18.7197 6.92857 18.2857Z'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const RefreshIPFSIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24' aria-hidden='true'>\n      <path d='M12 6v3l4-4-4-4v3c-4.42 0-8 3.58-8 8 0 1.57.46 3.03 1.24 4.26L6.7 14.8c-.45-.83-.7-1.79-.7-2.8 0-3.31 2.69-6 6-6zm6.76 1.74L17.3 9.2c.44.84.7 1.79.7 2.8 0 3.31-2.69 6-6 6v-3l-4 4 4 4v-3c4.42 0 8-3.58 8-8 0-1.57-.46-3.03-1.24-4.26z' />\n    </SvgIcon>\n  )\n}\n\nexport const ViewMoreIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24' aria-hidden='true'>\n      <path d='M5 10C3.9 10 3 10.9 3 12C3 13.1 3.9 14 5 14C6.1 14 7 13.1 7 12C7 10.9 6.1 10 5 10ZM19 10C17.9 10 17 10.9 17 12C17 13.1 17.9 14 19 14C20.1 14 21 13.1 21 12C21 10.9 20.1 10 19 10ZM12 10C10.9 10 10 10.9 10 12C10 13.1 10.9 14 12 14C13.1 14 14 13.1 14 12C14 10.9 13.1 10 12 10Z' />\n    </SvgIcon>\n  )\n}\n\nexport const ZoomIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24' aria-hidden='true'>\n      <path d='M21.9976 2H15.4981V4.13778H18.2444L13.33 9.05216L14.83 10.5767L19.8591 5.54755V8.49887H21.9976V2ZM2.00232 22H8.50182V19.8622H5.75552L10.6699 14.9478L9.16994 13.4233L4.14082 18.4524V15.5011H2.00232V22Z' />\n    </SvgIcon>\n  )\n}\n\nexport const SyncIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24' aria-hidden='true'>\n      <path d='M8.39787 9.85037L6.57746 8.32045L12.2324 7.99122L11.9031 13.6074L10.3732 11.8257L5.57042 16.493C2.3169 15.2341 1 13.2394 1 10.1214C1.34859 6.96477 3.65316 5.18309 6.19014 4.64088C6.19014 4.64088 7.95244 1 11.9031 1C16.1056 1 17.713 4.64088 17.713 4.64088C17.713 4.64088 22.8837 5.37675 22.9806 10.5475C22.7869 16.338 17.2676 16.6285 17.2676 16.6285H11.5546L7.15844 21.1989L8.7271 22.6708L3.24648 23L3.65316 17.4806L5.1831 19.1849L9.8116 14.537H16.1831H17.5968C18.1584 14.537 20.9278 13.5686 20.9471 10.5475C20.9664 7.54339 18.1708 6.79883 17.8537 6.71438L17.8485 6.71301C17.558 6.63554 16.2605 6.67432 16.2605 6.67432C16.2605 6.67432 16.125 5.45422 14.8662 4.19542C13.6074 2.93662 11.9031 3.05281 11.9031 3.05281C11.9031 3.05281 10.3732 3.03815 9.01759 4.19542C7.79256 5.2412 7.54577 6.63559 7.54577 6.63559C2.45247 6.30637 2.06514 12.213 4.54401 13.6461L8.39787 9.85037Z' />\n    </SvgIcon>\n  )\n}\nexport const LegacyIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24' aria-hidden='true'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M4.3033 5.36154L2.89389 5.18537L1.04404 9.85404L2.1011 10.7569V12.6068L1.08809 13.5978L2.95996 18.1123H4.34735L5.64665 19.3675L5.6026 20.8871L10.1832 22.6929L11.1301 21.6578H12.98L13.9269 22.6929L18.5075 20.7549L18.4635 19.3675L19.7628 18.0683L21.1942 18.1563L23.044 13.5978L22.031 12.6288V10.779L23.044 9.87606L21.1281 5.3175H19.7628L18.4414 4.0182L18.4855 2.63081L13.9269 0.692874L12.98 1.77195H11.1522L10.1391 0.692874L5.62462 2.63081V4.0182L4.3033 5.36154ZM7.03403 4.59518L4.81966 6.84647L3.51051 10.1072V13.1997L4.91696 16.7029L7.0735 18.7863L10.5093 20.2484H13.6008L17.0354 18.8024L19.2153 16.6225L20.6216 13.231V10.1472L19.1859 6.72691L17.0132 4.59039L13.6183 3.18136H10.5421L7.03403 4.59518ZM12.0771 5.58176C8.73886 5.58176 6.02102 8.31625 6.02102 11.7039C6.02102 15.0915 8.73886 17.826 12.0771 17.826C15.4153 17.826 18.1331 15.0915 18.1331 11.7039C18.1331 8.31625 15.4153 5.58176 12.0771 5.58176ZM11.6146 6.41736H12.6276V10.7882C12.9436 10.971 13.1562 11.3126 13.1562 11.7039C13.1562 12.2877 12.6829 12.7609 12.0991 12.7609C12.0342 12.7609 11.9707 12.7551 11.9091 12.7439L11.9142 12.7489L9.74446 14.9393L9.02476 14.2264L11.1224 12.1088C11.0706 11.9841 11.042 11.8473 11.042 11.7039C11.042 11.2947 11.2745 10.9398 11.6146 10.7641V6.41736Z'\n      />\n    </SvgIcon>\n  )\n}\nexport const SwapSettingIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24' aria-hidden='true'>\n      <path d='M6.17 15.7001C6.3766 15.1146 6.75974 14.6075 7.2666 14.2489C7.77346 13.8902 8.37909 13.6976 9 13.6976C9.62091 13.6976 10.2265 13.8902 10.7334 14.2489C11.2403 14.6075 11.6234 15.1146 11.83 15.7001H22V17.7001H11.83C11.6234 18.2856 11.2403 18.7926 10.7334 19.1513C10.2265 19.51 9.62091 19.7026 9 19.7026C8.37909 19.7026 7.77346 19.51 7.2666 19.1513C6.75974 18.7926 6.3766 18.2856 6.17 17.7001H2V15.7001H6.17ZM12.17 6.30009C12.3766 5.71456 12.7597 5.20753 13.2666 4.84888C13.7735 4.49024 14.3791 4.29764 15 4.29764C15.6209 4.29764 16.2265 4.49024 16.7334 4.84888C17.2403 5.20753 17.6234 5.71456 17.83 6.30009H22V8.30009H17.83C17.6234 8.88562 17.2403 9.39266 16.7334 9.7513C16.2265 10.1099 15.6209 10.3025 15 10.3025C14.3791 10.3025 13.7735 10.1099 13.2666 9.7513C12.7597 9.39266 12.3766 8.88562 12.17 8.30009H2V6.30009H12.17ZM15 8.30009C15.2652 8.30009 15.5196 8.19473 15.7072 8.0072C15.8946 7.81966 16 7.56531 16 7.30009C16 7.03487 15.8946 6.78052 15.7072 6.59299C15.5196 6.40545 15.2652 6.30009 15 6.30009C14.7348 6.30009 14.4804 6.40545 14.2928 6.59299C14.1054 6.78052 14 7.03487 14 7.30009C14 7.56531 14.1054 7.81966 14.2928 8.0072C14.4804 8.19473 14.7348 8.30009 15 8.30009ZM9 17.7001C9.26522 17.7001 9.51957 17.5948 9.70711 17.4072C9.89464 17.2196 10 16.9652 10 16.7C10 16.4348 9.89464 16.1806 9.70711 15.993C9.51957 15.8054 9.26522 15.7001 9 15.7001C8.73478 15.7001 8.48043 15.8054 8.2929 15.993C8.10536 16.1806 8 16.4348 8 16.7C8 16.9652 8.10536 17.2196 8.2929 17.4072C8.48043 17.5948 8.73478 17.7001 9 17.7001Z' />\n    </SvgIcon>\n  )\n}\n\nexport const WarningIcon2 = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24' aria-hidden='true'>\n      <path d='M12.905 2.52247L22.86 19.7655C22.9517 19.9244 23 20.1046 23 20.288C23 20.4715 22.9517 20.6517 22.86 20.8106C22.7683 20.9694 22.6364 21.1013 22.4775 21.193C22.3186 21.2848 22.1384 21.3331 21.955 21.3331H2.04501C1.86157 21.3331 1.68136 21.2848 1.5225 21.193C1.36364 21.1013 1.23172 20.9694 1.14 20.8106C1.04828 20.6517 0.999999 20.4715 1 20.288C1 20.1046 1.04829 19.9244 1.14001 19.7655L11.095 2.52247C11.1867 2.36362 11.3187 2.23171 11.4775 2.13999C11.6364 2.04828 11.8166 2 12 2C12.1834 2 12.3636 2.04828 12.5225 2.13999C12.6814 2.23171 12.8133 2.36362 12.905 2.52247ZM10.955 16.1079V18.198H13.045V16.1079H10.955ZM10.955 8.79266V14.0179H13.045V8.79266H10.955Z' />\n    </SvgIcon>\n  )\n}\n\nexport const RoundAddIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24' aria-hidden='true'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M12 4C16.4153 4 20 7.5847 20 12C20 16.4153 16.4153 20 12 20C7.5847 20 4 16.4153 4 12C4 7.5847 7.5847 4 12 4ZM12 4.69565C16.0313 4.69565 19.3043 7.9687 19.3043 12C19.3043 16.0313 16.0313 19.3043 12 19.3043C7.9687 19.3043 4.69565 16.0313 4.69565 12C4.69565 7.9687 7.9687 4.69565 12 4.69565ZM12.3478 11.6522H16.5217V12.3478H12.3478V16.5217H11.6522V12.3478H7.47826V11.6522H11.6522V7.47826H12.3478V11.6522Z'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const ApprovalIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24' aria-hidden='true'>\n      <path d='M8.4 16H15.6C15.84 16 16 15.84 16 15.6C16 15.36 15.84 15.2 15.6 15.2H8.4C8.16 15.2 8 15.36 8 15.6C8 15.84 8.16 16 8.4 16Z' />\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M8.4 12.8H10.4C10.52 12.8 10.6 12.76 10.68 12.68L16.68 6.68C16.84 6.52 16.84 6.28 16.68 6.12L14.68 4.12C14.52 3.96 14.28 3.96 14.12 4.12L8.64 9.6H4.4C4.16 9.6 4 9.76 4 10V19.6C4 19.84 4.16 20 4.4 20H19.6C19.84 20 20 19.84 20 19.6V10C20 9.76 19.84 9.6 19.6 9.6H16.4C16.16 9.6 16 9.76 16 10C16 10.24 16.16 10.4 16.4 10.4H19.2V19.2H4.8V10.4L8 10.4V12.4C8 12.64 8.16 12.8 8.4 12.8ZM9.01037 10.3496L8.8 10.56V12H10.24L15.84 6.4L14.4 4.96L9.14963 10.2104C9.11704 10.2696 9.06963 10.317 9.01037 10.3496Z'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const LockGuardianIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24' aria-hidden='true'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M16.2544 9.17095H18.4317C18.6333 9.17095 18.795 9.33267 18.795 9.53423V19.6988C18.795 19.8981 18.6333 20.0621 18.4317 20.0621H5.36327C5.16406 20.0621 5 19.9004 5 19.6988V9.53423C5 9.33501 5.16172 9.17095 5.36327 9.17095H7.54057V7.35693C7.54057 6.19212 7.9929 5.09761 8.81554 4.27497C9.63818 3.45233 10.7327 3 11.8975 3C13.0623 3 14.1568 3.45233 14.9795 4.27497C15.8021 5.09761 16.2544 6.19212 16.2544 7.35693V9.17095ZM9.33115 4.79058C8.64679 5.47494 8.26946 6.38664 8.26946 7.35693V9.17095H15.5255V7.35693C15.5255 6.38664 15.1482 5.47494 14.4638 4.79058C13.7795 4.10623 12.8678 3.72889 11.8975 3.72889C10.9272 3.72889 10.0155 4.10623 9.33115 4.79058ZM5.72889 19.3356H18.0685V9.8975H5.72889V19.3356ZM12.624 14.6974C12.8443 14.4982 12.9873 14.2122 12.9873 13.8912C12.9873 13.2888 12.4998 12.8013 11.8975 12.8013C11.2952 12.8013 10.8077 13.2888 10.8077 13.8912C10.8077 14.2122 10.9506 14.4982 11.1709 14.6974V15.7052C11.1709 16.106 11.4967 16.4317 11.8975 16.4317C12.2983 16.4317 12.624 16.106 12.624 15.7052V14.6974Z'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const ViewHistoryIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24' aria-hidden='true'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M17.4844 19.2351V19.7859C17.4844 19.8562 17.4281 19.9125 17.3578 19.9125H4.54221C4.4719 19.9125 4.41565 19.8562 4.41565 19.7859V3.97733C4.41565 3.90702 4.4719 3.85077 4.54221 3.85077H17.3555C17.4258 3.85077 17.4821 3.90702 17.4821 3.97733V9.25546C17.4821 9.42889 17.5992 9.57889 17.768 9.62108L17.7715 9.62225L17.775 9.62343C18.0117 9.68436 18.2414 9.50389 18.2414 9.2578V3.97733C18.2414 3.48749 17.843 3.08905 17.3531 3.08905H4.54221C4.05237 3.08905 3.65393 3.48749 3.65393 3.97733V19.7836C3.65393 20.2734 4.05237 20.6719 4.54221 20.6719H17.3555C17.8453 20.6719 18.2438 20.2734 18.2438 19.7836V19.2328C18.2438 18.989 18.0141 18.8086 17.7774 18.8672L17.7739 18.8683L17.7703 18.8695C17.6016 18.9117 17.4844 19.0617 17.4844 19.2351ZM13.6031 14.8617C13.6031 16.6078 15.0235 18.0258 16.7672 18.0258C17.3246 18.0258 17.8489 17.8809 18.3044 17.6268L19.8375 19.1578C19.9102 19.2305 20.0063 19.268 20.1024 19.268C20.1985 19.268 20.2946 19.2305 20.3672 19.1578C20.5149 19.0125 20.5149 18.7734 20.3672 18.6281L18.9178 17.1807C19.5407 16.6027 19.9313 15.7773 19.9313 14.8617C19.9313 13.1156 18.5133 11.6977 16.7672 11.6977C15.0211 11.6977 13.6031 13.1156 13.6031 14.8617ZM14.3531 14.8641C14.3531 13.5328 15.436 12.45 16.7672 12.45C18.0985 12.45 19.1813 13.5328 19.1813 14.8641C19.1813 16.1953 18.0985 17.2781 16.7672 17.2781C15.436 17.2781 14.3531 16.1953 14.3531 14.8641ZM6.41248 16.4039H10.2351C10.4437 16.4039 10.6125 16.2352 10.6125 16.0289C10.6125 15.8227 10.4437 15.6539 10.2375 15.6539H6.41248C6.20623 15.6539 6.03748 15.8227 6.03748 16.0289C6.03748 16.2352 6.20623 16.4039 6.41248 16.4039ZM6.41248 12.157H11.9695C12.1781 12.157 12.3469 11.9883 12.3469 11.782C12.3469 11.5758 12.1781 11.407 11.9719 11.407H6.41248C6.20623 11.407 6.03748 11.5758 6.03748 11.782C6.03748 11.9883 6.20623 12.157 6.41248 12.157ZM6.41248 7.91016H14.6203C14.8265 7.91016 14.9953 7.74141 14.9953 7.53516C14.9953 7.32891 14.8265 7.16016 14.6203 7.16016H6.41248C6.20623 7.16016 6.03748 7.32891 6.03748 7.53516C6.03748 7.74141 6.20623 7.91016 6.41248 7.91016Z'\n      />\n    </SvgIcon>\n  )\n}\nexport const ScanQRIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24' aria-hidden='true'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M5.5 19.5V15.5H3.5V19.5V21.5H5.5H9.5V19.5H5.5ZM5.5 4.5H9.5V2.5H5.5H3.5V4.5V8.5H5.5V4.5ZM18.5 4.5V8.5H20.5V4.5V2.5H18.5H14.5V4.5H18.5ZM18.5 19.5H14.5V21.5H18.5H20.5V19.5V15.5H18.5V19.5ZM1.5 13H22.5V11H1.5V13Z'\n      />\n    </SvgIcon>\n  )\n}\nexport const ClockIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 16 16' aria-hidden='true'>\n      <path d='M7.99992 14.6673C4.31792 14.6673 1.33325 11.6827 1.33325 8.00065C1.33325 4.31865 4.31792 1.33398 7.99992 1.33398C11.6819 1.33398 14.6666 4.31865 14.6666 8.00065C14.6666 11.6827 11.6819 14.6673 7.99992 14.6673ZM7.99992 13.334C9.41441 13.334 10.771 12.7721 11.7712 11.7719C12.7713 10.7717 13.3333 9.41514 13.3333 8.00065C13.3333 6.58616 12.7713 5.22961 11.7712 4.22941C10.771 3.22922 9.41441 2.66732 7.99992 2.66732C6.58543 2.66732 5.22888 3.22922 4.22868 4.22941C3.22849 5.22961 2.66659 6.58616 2.66659 8.00065C2.66659 9.41514 3.22849 10.7717 4.22868 11.7719C5.22888 12.7721 6.58543 13.334 7.99992 13.334ZM8.66658 8.00065H11.3333V9.33398H7.33325V4.66732H8.66658V8.00065Z' />\n    </SvgIcon>\n  )\n}\nexport const CloseRedPacketIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M12 21.3238C17.1494 21.3238 21.3238 17.1494 21.3238 12C21.3238 6.8506 17.1494 2.67619 12 2.67619C6.8506 2.67619 2.67619 6.8506 2.67619 12C2.67619 17.1494 6.8506 21.3238 12 21.3238ZM12 23C18.0751 23 23 18.0751 23 12C23 5.92487 18.0751 1 12 1C5.92487 1 1 5.92487 1 12C1 18.0751 5.92487 23 12 23ZM12 10.437L9.56298 8L8 9.56298L10.437 12L8 14.437L9.56298 16L12 13.563L14.437 16L16 14.437L13.563 12L16 9.56298L14.437 8L12 10.437Z'\n      />\n    </SvgIcon>\n  )\n}\nexport const UploadedIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} width='24' height='24' viewBox='0 0 24 24' fill='none'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M3.24796 14.0789H11.1137C11.1137 14.0789 11.8838 10.3385 15.4042 9.51343C18.9245 8.68835 21.6198 11.8787 21.6198 11.8787C21.6198 11.8787 22.6649 10.1735 21.2897 8.02829C19.9146 5.88308 18.1544 6.48813 18.1544 6.48813C18.1544 6.48813 19.3069 2.59595 14.9091 0.54755C10.5113 -1.50085 7.92342 2.85778 7.92342 2.85778C7.92342 2.85778 5.94323 1.70266 4.29307 3.13281C2.6429 4.56295 3.24796 6.48813 3.24796 6.48813C3.24796 6.48813 0.112658 6.81817 0.00264725 10.1735C-0.107364 13.5288 3.24796 14.0789 3.24796 14.0789ZM21.8922 15.1815C21.8922 17.9156 19.6758 20.132 16.9417 20.132C14.2076 20.132 11.9912 17.9156 11.9912 15.1815C11.9912 12.4474 14.2076 10.231 16.9417 10.231C19.6758 10.231 21.8922 12.4474 21.8922 15.1815ZM15.902 18.0364L15.9006 18.0382L13.5314 16.1293L14.0911 15.4346L15.7716 16.7886L19.1864 12.5412L19.8816 13.1002L15.9087 18.0418L15.902 18.0364Z'\n      />\n    </SvgIcon>\n  )\n}\nexport const ContactIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24' aria-hidden='true'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M5 2H21C21.2652 2 21.5196 2.10536 21.7071 2.29289C21.8946 2.48043 22 2.73478 22 3V21C22 21.2652 21.8946 21.5196 21.7071 21.7071C21.5196 21.8946 21.2652 22 21 22H5C4.73478 22 4.48043 21.8946 4.29289 21.7071C4.10536 21.5196 4 21.2652 4 21V17H2V15H4V13H2V11H4V9H2V7H4V3C4 2.73478 4.10536 2.48043 4.29289 2.29289C4.48043 2.10536 4.73478 2 5 2ZM6 4V20H20V4H6ZM16 17C16 15.797 15.708 13 13 13C10.292 13 10 15.797 10 17H8C8 14.533 8.865 12.711 10.346 11.755C9.826 11.145 9.5 10.363 9.5 9.5C9.5 7.57 11.07 6 13 6C14.93 6 16.5 7.57 16.5 9.5C16.5 10.363 16.174 11.145 15.654 11.755C17.135 12.711 18 14.533 18 17H16ZM13 8C12.173 8 11.5 8.673 11.5 9.5C11.5 10.327 12.173 11 13 11C13.827 11 14.5 10.327 14.5 9.5C14.5 8.673 13.827 8 13 8Z'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const EditIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24' aria-hidden='true'>\n      <path d='M6.414 16.0001L16.556 5.85803L15.142 4.44403L4.99999 14.586V16.0001H6.414ZM7.24301 18H3V13.757L14.435 2.32202C14.6225 2.13455 14.8768 2.02924 15.142 2.02924C15.4071 2.02924 15.6615 2.13455 15.849 2.32202L18.678 5.15102C18.8655 5.33855 18.9708 5.59286 18.9708 5.85803C18.9708 6.12319 18.8655 6.3775 18.678 6.56503L7.24301 18ZM3 20H21V22.0001H3V20Z' />\n    </SvgIcon>\n  )\n}\n\nexport const ConvertToIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24' aria-hidden='true'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M12.1956 18L13.1556 18.96C13.283 19.0872 13.4556 19.1586 13.6356 19.1586C13.8156 19.1586 13.9883 19.0872 14.1156 18.96L21.0756 12L14.1156 5.03997C13.9883 4.91276 13.8156 4.84131 13.6356 4.84131C13.4556 4.84131 13.283 4.91276 13.1556 5.03997L12.1956 5.99997C12.0684 6.12733 11.997 6.29997 11.997 6.47998C11.997 6.65998 12.0684 6.83262 12.1956 6.95997L15.8748 10.6392H2.91966C2.7392 10.6392 2.56614 10.7109 2.43854 10.8385C2.31094 10.9661 2.23926 11.1392 2.23926 11.3196V12.6804C2.23926 12.8609 2.31094 13.0339 2.43854 13.1615C2.56614 13.2891 2.7392 13.3608 2.91966 13.3608H15.8748L12.1956 17.04C12.1325 17.103 12.0824 17.1778 12.0482 17.2601C12.0141 17.3425 11.9965 17.4308 11.9965 17.52C11.9965 17.6091 12.0141 17.6974 12.0482 17.7798C12.0824 17.8622 12.1325 17.937 12.1956 18Z'\n      />\n    </SvgIcon>\n  )\n}\nexport const LinkSharedIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24' aria-hidden='true'>\n      <path d='M17.1261 14.563L15.8445 13.2815L17.1261 12C18.5416 10.5845 18.5416 8.28948 17.1261 6.87396C15.7106 5.45845 13.4155 5.45845 12 6.87396L10.7185 8.15547L9.43699 6.87396L10.7185 5.59246C12.8417 3.46918 16.2843 3.46918 18.4076 5.59246C20.5308 7.71573 20.5308 11.1583 18.4076 13.2815L17.1261 14.563ZM14.563 17.1261L13.2815 18.4076C11.1583 20.5308 7.71573 20.5308 5.59245 18.4076C3.46918 16.2842 3.46918 12.8417 5.59245 10.7185L6.87397 9.43699L8.15547 10.7185L6.87397 12C5.45845 13.4155 5.45845 15.7105 6.87397 17.1261C8.28949 18.5416 10.5845 18.5416 12 17.1261L13.2815 15.8446L14.563 17.1261ZM14.563 8.15547L15.8445 9.43699L9.43699 15.8446L8.15547 14.563L14.563 8.15547Z' />\n    </SvgIcon>\n  )\n}\n\nexport const AnotherIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24' aria-hidden='true'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M4.30705 12L8.33205 5H16.3609L20.3859 12L16.3609 19H8.33205L4.30705 12ZM7.175 3H17.518L22.693 12L17.518 21H7.175L2 12L7.175 3ZM15.4913 13.6515C15.74 13.4333 16.0618 13.303 16.4129 13.303C17.2057 13.303 17.8464 13.9667 17.8464 14.7879C17.8464 15.6091 17.2057 16.2727 16.4129 16.2727C15.6201 16.2727 14.9794 15.6091 14.9794 14.7879C14.9794 14.6848 14.9882 14.5818 15.0086 14.4848L10.2488 11.6121C10.0119 11.8818 9.70176 12.0848 9.3507 12.1909L9.60229 14.5333C10.164 14.6394 10.5911 15.1455 10.5911 15.7576C10.5911 16.4424 10.0528 17 9.39165 17C8.73048 17 8.19218 16.4424 8.19218 15.7576C8.19218 15.3455 8.38527 14.9818 8.68367 14.7545L8.41453 12.2333C7.51931 12.0455 6.84644 11.2242 6.84644 10.2424C6.84644 9.12121 7.7241 8.21212 8.80655 8.21212C9.53793 8.21212 10.1728 8.62727 10.5092 9.23939L14.1076 8.10909C14.1719 7.48485 14.681 7 15.3012 7C15.9624 7 16.5007 7.55758 16.5007 8.24242C16.5007 8.92727 15.9624 9.48485 15.3012 9.48485C14.9296 9.48485 14.5991 9.31212 14.3796 9.03939L10.7637 10.1727C10.7666 10.197 10.7666 10.2182 10.7666 10.2424C10.7666 10.4242 10.7432 10.597 10.7023 10.7636L15.4913 13.6515Z'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const RiskIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24' aria-hidden='true'>\n      <path d='M3.783 2.826L12 1L20.217 2.826C20.4391 2.87536 20.6377 2.99897 20.78 3.1764C20.9224 3.35384 21 3.57452 21 3.802V13.789C20.9999 14.7767 20.756 15.7492 20.2899 16.62C19.8238 17.4908 19.1499 18.2331 18.328 18.781L12 23L5.672 18.781C4.85027 18.2332 4.17646 17.4911 3.71035 16.6205C3.24424 15.7498 3.00024 14.7776 3 13.79V3.802C3.00004 3.57452 3.07764 3.35384 3.21999 3.1764C3.36234 2.99897 3.56094 2.87536 3.783 2.826V2.826ZM5 4.604V13.789C5.00001 14.4475 5.16257 15.0957 5.47326 15.6763C5.78395 16.2568 6.23315 16.7517 6.781 17.117L12 20.597L17.219 17.117C17.7667 16.7518 18.2158 16.2571 18.5265 15.6767C18.8372 15.0964 18.9998 14.4483 19 13.79V4.604L12 3.05L5 4.604ZM13 10H16L11 17V12H8L13 5V10Z' />\n    </SvgIcon>\n  )\n}\n\nexport const RiskAlertIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24' aria-hidden='true'>\n      <ellipse cx='12' cy='12.0357' rx='4' ry='4' fill='#636471' />\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M12.5 9.53571H11.5V13.0357H12.5V9.53571ZM12.5 14.0357H11.5V15.0357H12.5V14.0357Z'\n        fill='#FF5677'\n      />\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M1.39286 3.39286L22.6071 3.39286V19.6684H15.6436C15.4048 19.6684 15.179 19.777 15.0299 19.9635L12.2245 23.4729L9.41908 19.9635C9.26998 19.777 9.04415 19.6684 8.80536 19.6684H1.39286V3.39286ZM23 3.39286C23 3.17589 22.8241 3 22.6071 3H1.39286C1.17589 3 1 3.17589 1 3.39286V19.6684C1 19.8853 1.17589 20.0612 1.39286 20.0612H8.80536C8.92476 20.0612 9.03767 20.1155 9.11222 20.2088L11.9176 23.7182C12.0749 23.9149 12.3741 23.9149 12.5313 23.7182L15.3368 20.2088C15.4113 20.1155 15.5242 20.0612 15.6436 20.0612H22.6071C22.8241 20.0612 23 19.8853 23 19.6684V3.39286ZM17.1071 12.0357C17.1071 14.8563 14.8206 17.1429 12 17.1429C9.1794 17.1429 6.89286 14.8563 6.89286 12.0357C6.89286 9.21512 9.1794 6.92857 12 6.92857C14.8206 6.92857 17.1071 9.21512 17.1071 12.0357ZM17.5 12.0357C17.5 15.0733 15.0376 17.5357 12 17.5357C8.96243 17.5357 6.5 15.0733 6.5 12.0357C6.5 8.99815 8.96243 6.53571 12 6.53571C15.0376 6.53571 17.5 8.99815 17.5 12.0357Z'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const RoundCheckIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24' aria-hidden='true'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M2 12C2 17.523 6.477 22 12 22C17.523 22 22 17.523 22 12C22 6.477 17.523 2 12 2C6.477 2 2 6.477 2 12Z'\n        fill={props.fill}\n      />\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M11.2936 15.5353C10.903 15.9259 10.2698 15.9259 9.87921 15.5353L7.05042 12.7065C6.65995 12.316 6.65995 11.683 7.05042 11.2925C7.44088 10.902 8.07395 10.902 8.46442 11.2925L10.5864 13.4145L15.5354 8.46463C15.9259 8.07411 16.559 8.07408 16.9495 8.46457C17.3399 8.85501 17.3399 9.48804 16.9495 9.87851L11.2936 15.5353Z'\n        fill='white'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const RoundCircleIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24' aria-hidden='true'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M12.101 20.5C16.8655 20.5 20.702 16.6802 20.702 12C20.702 7.31976 16.8655 3.5 12.101 3.5C7.33655 3.5 3.5 7.31976 3.5 12C3.5 16.6802 7.33655 20.5 12.101 20.5ZM12.101 22C17.6796 22 22.202 17.5228 22.202 12C22.202 6.47715 17.6796 2 12.101 2C6.52238 2 2 6.47715 2 12C2 17.5228 6.52238 22 12.101 22Z'\n      />\n    </SvgIcon>\n  )\n}\nexport const DiscordSvg = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 36 36'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M18 36C27.9411 36 36 27.9411 36 18C36 8.05887 27.9411 0 18 0C8.05887 0 0 8.05887 0 18C0 27.9411 8.05887 36 18 36ZM21.6605 8C23.5419 8.32586 25.3414 8.89815 27.0245 9.68559C29.9672 14.0802 31.4294 19.0366 30.8895 24.7533C28.638 26.4368 26.4539 27.4582 24.3067 28.1265C23.775 27.3976 23.3046 26.6206 22.8977 25.806C23.6727 25.5115 24.4171 25.1481 25.1206 24.7241C24.9365 24.5862 24.7545 24.4421 24.5766 24.2938C20.3496 26.2948 15.7014 26.2948 11.4233 24.2938C11.2474 24.4421 11.0654 24.5862 10.8793 24.7241C11.5807 25.146 12.3231 25.5094 13.0981 25.8039C12.6912 26.6206 12.2188 27.3955 11.6891 28.1245C9.54394 27.4561 7.36194 26.4347 5.11041 24.7533C4.65029 19.822 5.57053 14.8196 8.96521 9.68976C10.6482 8.90025 12.4499 8.32586 14.3333 8C14.5664 8.41774 14.8425 8.97962 15.0286 9.42659C16.9918 9.12582 18.9734 9.12582 20.9734 9.42659C21.1595 8.97962 21.4294 8.41774 21.6605 8ZM11.3435 19.0617C11.3435 20.5217 12.3967 21.7206 13.6809 21.7206C14.9877 21.7206 16.0204 20.5217 16.0184 19.0617C16.0409 17.5996 14.9877 16.4007 13.6809 16.4007C12.3742 16.4007 11.3435 17.6017 11.3435 19.0617ZM19.9815 19.0617C19.9815 20.5217 21.0347 21.7206 22.319 21.7206C23.6257 21.7206 24.6564 20.5217 24.6564 19.0617C24.6789 17.5996 23.6257 16.4007 22.319 16.4007C21.0122 16.4007 19.9815 17.6017 19.9815 19.0617Z'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const BorderTickIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24'>\n      <path\n        fill={props.fill}\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M0 0H17C17.3395 0 17.6734 0.0241719 18 0.0708887V0H19H20H22.5H23.5H24V0.5V1.5V2.5V4V6L23.9305 6.00973C23.9763 6.33324 24 6.66385 24 7V24L11.6923 12L0 0ZM22 2.10102V2H21.899C21.933 2.03333 21.9667 2.067 22 2.10102ZM14.6666 10.1145L20.7946 3.98584L21.7379 4.92851L14.6666 11.9998L10.424 7.75717L11.3666 6.81451L14.6666 10.1145Z'\n      />\n      <path\n        d='M14.6665 10.1145L20.7945 3.98584L21.7378 4.92851L14.6665 11.9998L10.4238 7.75717L11.3665 6.81451L14.6665 10.1145Z'\n        fill='white'\n      />\n    </SvgIcon>\n  )\n}\nexport const MarginLevelIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24'>\n      <path d='M20.7923 20.6L19.2209 19.0287C20.2514 17.5563 20.8028 15.8021 20.8 14.005C20.8 11.6532 19.8848 9.44218 18.2221 7.77953C17.4071 6.95954 16.4375 6.30941 15.3694 5.86682C14.3014 5.42423 13.1561 5.19796 12 5.20114C10.8437 5.19806 9.69831 5.42436 8.63009 5.86695C7.56186 6.30953 6.59204 6.9596 5.77675 7.77953C4.95712 8.59542 4.30738 9.5657 3.8651 10.6343C3.42281 11.7028 3.19675 12.8485 3.2 14.005C3.2 15.8288 3.7566 17.564 4.77795 19.0292L3.2077 20.6C1.77237 18.7012 0.997104 16.3852 1.00001 14.005C1.00001 11.0652 2.14401 8.30148 4.22135 6.22303C5.24032 5.19804 6.45252 4.3854 7.78774 3.83216C9.12297 3.27893 10.5547 2.99609 12 3.00004C13.4453 2.99609 14.877 3.27893 16.2122 3.83216C17.5475 4.3854 18.7596 5.19804 19.7786 6.22303C20.8033 7.24286 21.6155 8.45571 22.1685 9.79146C22.7214 11.1272 23.004 12.5593 23 14.005C23 16.4178 22.2179 18.7058 20.7923 20.6ZM5.4 12.9C5.69174 12.9 5.97152 13.0159 6.17781 13.2222C6.3841 13.4285 6.5 13.7083 6.5 14C6.5 14.2918 6.3841 14.5715 6.17781 14.7778C5.97152 14.9841 5.69174 15.1 5.4 15.1C5.10826 15.1 4.82847 14.9841 4.62218 14.7778C4.41589 14.5715 4.3 14.2918 4.3 14C4.3 13.7083 4.41589 13.4285 4.62218 13.2222C4.82847 13.0159 5.10826 12.9 5.4 12.9ZM6.555 8.55558C6.65643 8.45048 6.77778 8.36664 6.91196 8.30894C7.04615 8.25125 7.19048 8.22085 7.33653 8.21953C7.48259 8.21821 7.62745 8.24599 7.76265 8.30125C7.89786 8.35651 8.0207 8.43815 8.12402 8.54139C8.22734 8.64464 8.30906 8.76742 8.36442 8.90259C8.41977 9.03775 8.44766 9.18259 8.44644 9.32865C8.44522 9.47471 8.41493 9.61906 8.35733 9.75328C8.29972 9.88751 8.21597 10.0089 8.11094 10.1104C7.90355 10.3109 7.62573 10.4218 7.33731 10.4194C7.04889 10.417 6.77296 10.3014 6.56894 10.0976C6.36492 9.8937 6.24913 9.61784 6.24653 9.32943C6.24392 9.04101 6.35469 8.76311 6.555 8.55558ZM10.9 7.40003C10.8967 7.25354 10.9227 7.10787 10.9764 6.97157C11.0302 6.83526 11.1106 6.71107 11.213 6.60629C11.3155 6.5015 11.4378 6.41823 11.5728 6.36137C11.7079 6.30451 11.8529 6.2752 11.9994 6.27516C12.146 6.27513 12.291 6.30436 12.4261 6.36116C12.5611 6.41795 12.6835 6.50116 12.786 6.60589C12.8884 6.71063 12.969 6.83478 13.0228 6.97106C13.0766 7.10733 13.1027 7.25299 13.0994 7.39948C13.0931 7.68689 12.9745 7.96039 12.769 8.16143C12.5635 8.36248 12.2875 8.47509 12 8.47516C11.7125 8.47523 11.4364 8.36276 11.2308 8.16182C11.0252 7.96088 10.9065 7.68743 10.9 7.40003ZM15.025 11.5107C15.025 11.5107 13.8843 16.7858 13.4289 17.575C13.2085 17.9509 12.8484 18.2243 12.4272 18.3357C12.006 18.4471 11.5578 18.3873 11.1804 18.1695C10.8031 17.9516 10.5273 17.5933 10.4131 17.1728C10.2989 16.7524 10.3557 16.3038 10.5711 15.925C11.0265 15.1358 15.025 11.5107 15.025 11.5107ZM17.4444 8.55558C17.5465 8.65771 17.6276 8.77895 17.6828 8.91239C17.7381 9.04583 17.7666 9.18884 17.7666 9.33328C17.7666 9.47771 17.7381 9.62073 17.6828 9.75416C17.6276 9.8876 17.5465 10.0088 17.4444 10.111C17.3423 10.2131 17.221 10.2941 17.0876 10.3494C16.9542 10.4047 16.8112 10.4331 16.6667 10.4331C16.5223 10.4331 16.3793 10.4047 16.2458 10.3494C16.1124 10.2941 15.9912 10.2131 15.889 10.111C15.784 10.0095 15.7002 9.88812 15.6425 9.75392C15.5849 9.61972 15.5545 9.47537 15.5533 9.32932C15.552 9.18326 15.5798 9.03841 15.6351 8.90323C15.6904 8.76804 15.7721 8.64522 15.8754 8.54194C15.9787 8.43866 16.1015 8.35698 16.2367 8.30167C16.3719 8.24637 16.5167 8.21853 16.6628 8.2198C16.8088 8.22107 16.9532 8.25142 17.0874 8.30907C17.2216 8.36672 17.3429 8.45052 17.4444 8.55558ZM18.6 12.9C18.8917 12.9 19.1715 13.0159 19.3778 13.2222C19.5841 13.4285 19.7 13.7083 19.7 14C19.7 14.2918 19.5841 14.5715 19.3778 14.7778C19.1715 14.9841 18.8917 15.1 18.6 15.1C18.3082 15.1 18.0284 14.9841 17.8222 14.7778C17.6159 14.5715 17.5 14.2918 17.5 14C17.5 13.7083 17.6159 13.4285 17.8222 13.2222C18.0284 13.0159 18.3082 12.9 18.6 12.9Z' />\n    </SvgIcon>\n  )\n}\nexport const LoadIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M12.5 2C12.8701 2 13.1702 2.30006 13.1702 2.6702V3.51652C15.254 3.54389 17.3342 3.70287 19.3983 3.9926C20.4305 4.13874 21.453 4.31664 22.4643 4.524C22.8269 4.59836 23.0606 4.95257 22.9862 5.31517C22.9119 5.67777 22.5576 5.91144 22.195 5.83709C21.5323 5.7012 20.8652 5.57839 20.1936 5.46926L22.5976 15.3108C22.5976 15.3108 22.5976 15.3107 22.5976 15.3108C22.7867 16.0847 22.4459 17.0003 21.5799 17.3123C20.8504 17.5741 20.0802 17.7078 19.3052 17.7068C18.5301 17.7078 17.7607 17.5744 17.0312 17.3126C16.1651 17.0006 15.8239 16.0851 16.0114 15.312L16.0117 15.3108L18.4771 5.22261C16.7162 5.00304 14.9446 4.881 13.1702 4.85705V19.4082C14.4937 19.4767 15.7649 19.7469 16.953 20.1892C17.2999 20.3183 17.4764 20.7042 17.3473 21.0511C17.2182 21.398 16.8323 21.5745 16.4854 21.4454C15.2454 20.9838 13.903 20.7313 12.5 20.7313C11.097 20.7313 9.75455 20.9838 8.5146 21.4454C8.16771 21.5745 7.78182 21.398 7.6527 21.0511C7.52358 20.7042 7.70012 20.3183 8.04701 20.1892C9.2351 19.7469 10.5063 19.4767 11.8298 19.4082V4.85726C10.0349 4.88188 8.26407 5.00528 6.52306 5.22248L8.98728 15.3108C8.9873 15.3108 8.98727 15.3107 8.98728 15.3108C9.17644 16.0847 8.83558 17.0003 7.96959 17.3123C7.24007 17.5741 6.46992 17.7078 5.69485 17.7068C4.91977 17.7078 4.1504 17.5744 3.42087 17.3126C2.55484 17.0006 2.21364 16.0851 2.4011 15.312L4.8065 5.46924C4.13492 5.57837 3.46775 5.70119 2.80496 5.83709C2.44236 5.91144 2.08814 5.67777 2.01379 5.31517C1.93944 4.95257 2.17311 4.59836 2.53571 4.524C3.54698 4.31664 4.56872 4.13885 5.60089 3.99271C7.63938 3.70612 9.71915 3.54491 11.8298 3.51673V2.6702C11.8298 2.30006 12.1299 2 12.5 2ZM5.69482 7.48058L3.70376 15.6279C3.70372 15.628 3.7038 15.6277 3.70376 15.6279C3.6476 15.8604 3.76641 16.0121 3.87411 16.0511C4.45795 16.2606 5.07367 16.3673 5.69395 16.3664H5.69575C6.31619 16.3673 6.93208 16.2605 7.51606 16.0509C7.62391 16.0121 7.74199 15.8613 7.68523 15.6291L5.69482 7.48058ZM5.69485 17.7068C5.69455 17.7068 5.69425 17.7068 5.69395 17.7068L5.69485 17.0366L5.69575 17.7068C5.69545 17.7068 5.69515 17.7068 5.69485 17.7068ZM19.3051 7.48059L17.3141 15.6279C17.314 15.6281 17.3141 15.6276 17.3141 15.6279C17.258 15.8604 17.3769 16.0123 17.4846 16.0512C18.0684 16.2606 18.684 16.3673 19.3042 16.3664H19.3061C19.9265 16.3673 20.5424 16.2605 21.1263 16.051C21.2342 16.0121 21.3523 15.8613 21.2955 15.6291L19.3051 7.48059ZM19.3052 17.7068C19.3048 17.7068 19.3045 17.7068 19.3042 17.7068L19.3051 17.0366L19.3061 17.7068C19.3058 17.7068 19.3055 17.7068 19.3052 17.7068Z'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const MarginIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M14.3616 2.95748C16.5733 1.8333 19.0196 1.24821 21.5005 1.25C21.9143 1.2503 22.2497 1.58564 22.25 1.99941C22.252 4.48058 21.6669 6.92702 20.5428 9.1389C19.4914 11.2075 17.9963 13.0161 16.1666 14.4367C16.3003 15.275 16.2749 16.1327 16.0901 16.9643C15.8692 17.9586 15.4261 18.89 14.794 19.6886C14.162 20.4873 13.3574 21.1326 12.4406 21.5762C11.5237 22.0198 10.5184 22.2501 9.49989 22.25C9.08572 22.2499 8.75 21.9142 8.75 21.5V17.3681C8.74087 17.3615 8.73187 17.3547 8.72301 17.3477C7.7707 16.5925 6.90847 15.7303 6.15334 14.778C6.14605 14.7688 6.139 14.7595 6.13218 14.75H2C1.58584 14.75 1.25008 14.4143 1.25 14.0001C1.24981 12.9815 1.48017 11.976 1.92382 11.0591C2.36746 10.1421 3.01288 9.3375 3.81171 8.70545C4.61053 8.0734 5.54205 7.63035 6.53645 7.40949C7.36823 7.22474 8.22596 7.19947 9.0644 7.33336C10.4849 5.50378 12.2933 4.00882 14.3616 2.95748ZM8.08161 8.74955C7.6728 8.74319 7.26335 8.78459 6.86168 8.8738C6.08826 9.04558 5.36375 9.39018 4.74244 9.88178C4.12113 10.3734 3.61914 10.9992 3.27408 11.7124C3.03861 12.1991 2.88039 12.7178 2.80369 13.25H6.19943C6.58831 11.6595 7.22407 10.1411 8.08161 8.74955ZM7.54306 14.1099C8.10122 14.7805 8.71942 15.3988 9.38996 15.957C11.3796 15.5471 13.2572 14.7142 14.8972 13.5146L14.8984 13.5138C16.7127 12.1922 18.1886 10.4602 19.2056 8.45927C20.1061 6.68748 20.6242 4.74931 20.7298 2.77028C18.7509 2.87603 16.8129 3.39416 15.0413 4.29466C13.0405 5.31164 11.3087 6.78746 9.98722 8.60159L9.98635 8.60278C8.7869 10.2426 7.95315 12.1208 7.54306 14.1099ZM10.25 17.3007V20.6963C10.7821 20.6196 11.3007 20.4614 11.7873 20.226C12.5004 19.8809 13.1262 19.379 13.6178 18.7578C14.1094 18.1366 14.454 17.4122 14.6258 16.6389C14.7151 16.2374 14.7565 15.8281 14.7502 15.4195C13.3586 16.2769 11.8405 16.912 10.25 17.3007ZM14.75 8C14.5511 8 14.3603 8.07902 14.2197 8.21967C14.079 8.36033 14 8.55109 14 8.75C14 8.94892 14.079 9.13968 14.2197 9.28033C14.3603 9.42099 14.5511 9.5 14.75 9.5C14.9489 9.5 15.1397 9.42099 15.2803 9.28033C15.421 9.13968 15.5 8.94892 15.5 8.75C15.5 8.55109 15.421 8.36033 15.2803 8.21967C15.1397 8.07902 14.9489 8 14.75 8ZM13.159 7.15901C13.581 6.73706 14.1533 6.5 14.75 6.5C15.3467 6.5 15.919 6.73706 16.341 7.15901C16.7629 7.58097 17 8.15327 17 8.75C17 9.34674 16.7629 9.91904 16.341 10.341C15.919 10.763 15.3467 11 14.75 11C14.1533 11 13.581 10.763 13.159 10.341C12.7371 9.91904 12.5 9.34674 12.5 8.75C12.5 8.15327 12.7371 7.58097 13.159 7.15901ZM5.16284 15.9425C5.41001 16.2749 5.34092 16.7447 5.00854 16.9918C4.46053 17.3994 4.03445 17.949 3.77644 18.5813C3.59187 19.0337 3.49835 19.516 3.49905 20.0009C3.98398 20.0015 4.46633 19.9079 4.91869 19.7232C5.55101 19.465 6.10064 19.0388 6.50805 18.4906C6.75514 18.1582 7.22494 18.089 7.55739 18.3361C7.88984 18.5831 7.95904 19.0529 7.71195 19.3854C7.14127 20.1532 6.37138 20.7503 5.48566 21.1119C4.59995 21.4735 3.63217 21.5859 2.68717 21.4368C2.36589 21.3862 2.11389 21.1342 2.06317 20.8129C1.91401 19.868 2.02621 18.9003 2.38761 18.0146C2.74901 17.1289 3.34584 16.359 4.11346 15.7882C4.44585 15.541 4.91567 15.6101 5.16284 15.9425Z'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const VaultTradeIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24'>\n      <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M18.9017 13.2828C18.9664 13.6789 19 14.0855 19 14.5C19 18.6421 15.6421 22 11.5 22C7.35786 22 4 18.6421 4 14.5C4 10.3579 7.35786 7 11.5 7C14.4137 7 16.9394 8.66155 18.1811 11.0888C18.697 10.3567 18.9999 9.46371 18.9999 8.5C18.9999 6.01472 16.9852 4 14.4999 4C12.5001 4 10.805 5.30448 10.2191 7.10894C9.44279 7.24252 8.70732 7.49543 8.03222 7.84808C8.35923 4.56434 11.1301 2 14.4999 2C18.0898 2 20.9999 4.91015 20.9999 8.5C20.9999 10.3918 20.1917 12.0949 18.9017 13.2828ZM17 14.5C17 17.5376 14.5376 20 11.5 20C8.46243 20 6 17.5376 6 14.5C6 11.4624 8.46243 9 11.5 9C14.5376 9 17 11.4624 17 14.5Z\" fill=\"#EBEEF5\"/>\n    </SvgIcon>\n  )\n}\n\nexport const CloseOutIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M5.99361 3.06844C9.65223 2.64377 13.3477 2.64377 17.0063 3.06844ZM17.0065 3.06846C17.7101 3.15044 18.25 3.76263 18.25 4.50846V20.3937L15.5285 19.3051C15.3497 19.2336 15.1503 19.2336 14.9715 19.3051L11.5 20.6937L8.02854 19.3051C7.84973 19.2336 7.65027 19.2336 7.47146 19.3051L4.75 20.3937V4.50846C4.75 3.76231 5.28919 3.15041 5.99348 3.06846M5.82052 1.57846C9.59417 1.14043 13.4058 1.14043 17.1795 1.57846L17.1797 1.57849C18.676 1.7526 19.75 3.03837 19.75 4.50846V21.5015C19.75 21.7503 19.6266 21.983 19.4205 22.1225C19.2144 22.262 18.9525 22.2902 18.7215 22.1978L15.25 20.8092L11.7785 22.1978C11.5997 22.2693 11.4003 22.2693 11.2215 22.1978L7.75 20.8092L4.27854 22.1978C4.04747 22.2902 3.78561 22.262 3.57953 22.1225C3.37345 21.983 3.25 21.7503 3.25 21.5015V4.50846C3.25 3.03866 4.32274 1.75259 5.82039 1.57848L5.82052 1.57846ZM15.0303 7.47113C15.3232 7.76403 15.3232 8.2389 15.0303 8.53179L9.03033 14.5318C8.73744 14.8247 8.26256 14.8247 7.96967 14.5318C7.67678 14.2389 7.67678 13.764 7.96967 13.4711L13.9697 7.47113C14.2626 7.17824 14.7374 7.17824 15.0303 7.47113Z'\n      />\n    </SvgIcon>\n  )\n}\nexport const SwapExchangeIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24'>\n      <path d='M14.1222 18.5882C14.1222 19.2704 14.6327 19.8235 15.2624 19.8235C15.8922 19.8235 16.4027 19.2704 16.4027 18.5882V9.34616L17.8536 11.0132C18.2856 11.5096 19.0073 11.5326 19.4655 11.0646C19.9237 10.5966 19.9449 9.81475 19.5129 9.31837L16.0921 5.38791C15.7715 5.01957 15.2759 4.90041 14.8416 5.08725C14.4073 5.27408 14.1222 5.72909 14.1222 6.23533V18.5882Z' />\n      <path d='M10.7014 6.23533C10.7014 5.5531 10.1908 5.00005 9.56109 5.00005C8.93133 5.00005 8.42082 5.5531 8.42082 6.23533V15.4774L6.96992 13.8103C6.5379 13.3139 5.81624 13.2909 5.35803 13.759C4.89983 14.227 4.87861 15.0088 5.31063 15.5052L8.73144 19.4356C9.05202 19.804 9.5476 19.9231 9.98192 19.7363C10.4162 19.5494 10.7014 19.0944 10.7014 18.5882V6.23533Z' />\n    </SvgIcon>\n  )\n}\n\nexport const BiArrow = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24'>\n      <path\n        d='M12.0001 19.1643L18.2072 12.9572L16.793 11.543L12.0001 16.3359L7.20718 11.543L5.79297 12.9572L12.0001 19.1643ZM12.0001 13.5144L18.2072 7.30728L16.793 5.89307L12.0001 10.686L7.20718 5.89307L5.79297 7.30728L12.0001 13.5144Z'\n        fill='#5D667A'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const MessageIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24'>\n      <path d='M3.5 16.565H10.3995L12.1415 18.5975L13.8835 16.565H20.7825V4.5H3.5V16.565V16.565ZM2 17.565V3.5C2 3.36739 2.05268 3.24021 2.14645 3.14645C2.24021 3.05268 2.36739 3 2.5 3H21.7825C21.9151 3 22.0423 3.05268 22.1361 3.14645C22.2298 3.24021 22.2825 3.36739 22.2825 3.5V17.565C22.2825 17.6976 22.2298 17.8248 22.1361 17.9186C22.0423 18.0123 21.9151 18.065 21.7825 18.065H14.573L12.521 20.46C12.4741 20.5148 12.4158 20.5588 12.3503 20.589C12.2847 20.6191 12.2134 20.6347 12.1413 20.6347C12.0691 20.6347 11.9978 20.6191 11.9322 20.589C11.8667 20.5588 11.8084 20.5148 11.7615 20.46L9.7095 18.065H2.5C2.36739 18.065 2.24021 18.0123 2.14645 17.9186C2.05268 17.8248 2 17.6976 2 17.565V17.565ZM7.4455 11.58C7.16789 11.58 6.90164 11.4697 6.70534 11.2734C6.50903 11.0771 6.39875 10.8109 6.39875 10.5332C6.39875 10.2556 6.50903 9.98939 6.70534 9.79309C6.90164 9.59678 7.16789 9.4865 7.4455 9.4865C7.72312 9.4865 7.98936 9.59678 8.18566 9.79309C8.38197 9.98939 8.49225 10.2556 8.49225 10.5332C8.49225 10.8109 8.38197 11.0771 8.18566 11.2734C7.98936 11.4697 7.72312 11.58 7.4455 11.58ZM12.1415 11.58C11.8639 11.58 11.5976 11.4697 11.4013 11.2734C11.205 11.0771 11.0948 10.8109 11.0948 10.5332C11.0948 10.2556 11.205 9.98939 11.4013 9.79309C11.5976 9.59678 11.8639 9.4865 12.1415 9.4865C12.4191 9.4865 12.6854 9.59678 12.8817 9.79309C13.078 9.98939 13.1882 10.2556 13.1882 10.5332C13.1882 10.8109 13.078 11.0771 12.8817 11.2734C12.6854 11.4697 12.4191 11.58 12.1415 11.58ZM16.8365 11.58C16.5589 11.58 16.2926 11.4697 16.0963 11.2734C15.9 11.0771 15.7897 10.8109 15.7897 10.5332C15.7897 10.2556 15.9 9.98939 16.0963 9.79309C16.2926 9.59678 16.5589 9.4865 16.8365 9.4865C17.1141 9.4865 17.3804 9.59678 17.5767 9.79309C17.773 9.98939 17.8832 10.2556 17.8832 10.5332C17.8832 10.8109 17.773 11.0771 17.5767 11.2734C17.3804 11.4697 17.1141 11.58 16.8365 11.58Z' />\n    </SvgIcon>\n  )\n}\n\nexport const ReadIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24'>\n      <path d='M8 20V15H10V20H19V13H5V20H8ZM4 11H20V8H14V4H10V8H4V11ZM3 21V13H2V7C2 6.44772 2.44772 6 3 6H8V3C8 2.44772 8.44772 2 9 2H15C15.5523 2 16 2.44772 16 3V6H21C21.5523 6 22 6.44772 22 7V13H21V21C21 21.5523 20.5523 22 20 22H4C3.44772 22 3 21.5523 3 21Z' />\n    </SvgIcon>\n  )\n}\nexport const FiatLandIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M11.7803 1.08477C11.6488 1.18819 11.635 1.39438 11.75 1.53636C11.809 1.60923 11.8684 1.63201 11.9997 1.63201C12.2073 1.63201 12.3268 1.51256 12.3268 1.30515C12.3268 1.14378 12.1727 1 11.9997 1C11.9383 1 11.8396 1.03815 11.7803 1.08477ZM11.4774 2.6417C11.1263 2.69204 10.4969 2.92321 10.1505 3.12895C9.78251 3.3476 9.30197 3.80418 9.05575 4.16923C8.63656 4.79077 8.44198 5.42425 8.44198 6.16769C8.44198 6.71468 8.52046 7.11907 8.71434 7.57098C9.06046 8.37777 9.57845 8.938 10.3691 9.36072C10.6732 9.52327 11.0381 9.63626 11.5805 9.73583L11.6726 9.75272V11.3468C11.6726 12.2235 11.6579 12.9408 11.64 12.9408C11.6222 12.9408 11.5381 12.8497 11.4532 12.7384C10.9285 12.0504 10.0212 11.4825 9.15762 11.3015C8.84376 11.2358 8.60556 11.2243 7.53922 11.2239L6.28891 11.2233L6.19396 11.3244C6.10415 11.42 6.10031 11.4469 6.12243 11.8253C6.20557 13.2481 7.21429 14.6912 8.48726 15.2085C8.63104 15.2669 8.78103 15.3329 8.82058 15.3551C9.0504 15.4843 9.42829 15.5281 10.5275 15.553L11.6521 15.5785L11.6635 16.1203L11.6749 16.6621L11.1115 16.6624C10.4632 16.6626 10.2965 16.6979 10.091 16.8784C9.82544 17.1116 9.83236 17.0402 9.83236 19.5408V21.8088L9.94011 21.8935C10.1216 22.0363 10.3299 21.9917 10.4391 21.7867C10.4735 21.7221 10.4866 21.1056 10.4866 19.556C10.4866 17.945 10.4988 17.4024 10.5357 17.3655C10.6061 17.2952 13.3933 17.2952 13.4637 17.3655C13.5008 17.4026 13.5128 18.0171 13.5128 19.8804V22.3463H11.122H8.73135L8.71957 20.9662C8.70628 19.4075 8.70431 19.3968 8.38768 19.146L8.22039 19.0135H6.53566H4.85098L4.69383 19.1401C4.60738 19.2097 4.49558 19.3385 4.44532 19.4263C4.3558 19.5828 4.354 19.6134 4.35331 20.9662L4.35265 22.3463H3.40896H2.46526L2.34095 22.4706C2.23651 22.5751 2.2208 22.616 2.24268 22.7262C2.25699 22.7984 2.30975 22.8892 2.35992 22.9281C2.44576 22.9946 3.04873 22.9988 12.6252 22.9997L22.7993 23.0006L22.8996 22.9002C22.9629 22.8369 23 22.7531 23 22.6734C23 22.5938 22.9629 22.51 22.8996 22.4467L22.7993 22.3463H21.2236H19.648L19.6371 18.6113L19.6263 14.8762L19.5061 14.7029C19.2749 14.3692 19.2925 14.3721 17.4797 14.3721C16.2303 14.3721 15.8531 14.3842 15.7497 14.4274C15.5749 14.5004 15.3679 14.741 15.3145 14.9333C15.2861 15.0357 15.2715 16.311 15.2714 18.7182L15.2712 22.3487L14.7293 22.3373L14.1875 22.3259L14.167 19.7496C14.1519 17.839 14.1338 17.151 14.097 17.0869C14.0133 16.9408 13.7683 16.7506 13.6059 16.7055C13.5209 16.6819 13.1982 16.6625 12.8886 16.6624L12.3258 16.6621L12.3365 15.2411L12.3473 13.82L13.4514 13.7976C14.6582 13.773 14.7531 13.7583 15.4089 13.4939C16.7777 12.9421 17.7908 11.5354 17.8769 10.0669C17.8991 9.68844 17.8953 9.66157 17.8054 9.56596L17.7105 9.46491L16.4602 9.46545C15.3969 9.46589 15.1547 9.47747 14.8418 9.54269C13.9777 9.72279 13.0714 10.2914 12.5421 10.9854C12.4594 11.0938 12.3772 11.1824 12.3594 11.1824C12.3415 11.1824 12.3268 10.8608 12.3268 10.4676C12.3268 9.75853 12.3276 9.7526 12.4189 9.73583C12.9613 9.63626 13.3262 9.52327 13.6303 9.36072C14.4194 8.93886 14.9391 8.37576 15.287 7.56587C15.5046 7.05937 15.571 6.66172 15.5488 5.9979C15.5333 5.53748 15.5182 5.43819 15.4492 5.34581C15.3449 5.20608 15.1958 5.16678 15.0317 5.23581C14.8565 5.30946 14.8133 5.44077 14.8682 5.73275C14.9297 6.05981 14.8862 6.64225 14.7713 7.03176C14.4168 8.23325 13.2577 9.09687 11.9997 9.09687C10.7226 9.09687 9.56504 8.22208 9.21225 6.9903C9.04406 6.40295 9.09321 5.58348 9.32994 5.02799C9.6615 4.25 10.5124 3.53976 11.333 3.35594C12.2994 3.1395 13.2689 3.41078 14.0112 4.10531C14.3168 4.39124 14.3832 4.43504 14.5107 4.43504C14.7072 4.43504 14.8213 4.31857 14.8213 4.11816C14.8213 3.97985 14.7883 3.93274 14.484 3.63725C13.6717 2.84854 12.5727 2.48467 11.4774 2.6417ZM11.849 3.78103C11.7205 3.8328 11.6726 3.94845 11.6726 4.20673V4.43365L11.4783 4.53294C11.0958 4.72841 10.8956 5.0358 10.8956 5.4276C10.8956 5.85812 11.2044 6.25659 11.6652 6.42057C12.1559 6.59514 12.294 6.66102 12.3689 6.75622C12.475 6.89117 12.4708 7.02289 12.3562 7.1562C12.1744 7.36746 11.6865 7.31936 11.5927 7.08092C11.5733 7.03139 11.5357 6.93264 11.5092 6.86148C11.4239 6.63211 11.0935 6.58329 10.956 6.77974C10.7548 7.06697 11.0646 7.6899 11.4893 7.85208L11.6726 7.92209V8.18074C11.6726 8.49194 11.7604 8.60615 11.9997 8.60615C12.239 8.60615 12.3268 8.49194 12.3268 8.18074V7.92209L12.5101 7.85208C12.7285 7.76866 13.0029 7.47533 13.0622 7.26171C13.1149 7.07212 13.1147 6.82709 13.0617 6.63636C13 6.41427 12.6905 6.09085 12.4586 6.00608C11.9483 5.81952 11.6662 5.68703 11.6107 5.60782C11.5178 5.47516 11.5376 5.3407 11.6694 5.20886C11.7693 5.109 11.8222 5.08933 11.991 5.08933C12.2425 5.08933 12.3897 5.19439 12.4495 5.41648C12.4946 5.58389 12.6555 5.74362 12.7791 5.74362C12.8193 5.74362 12.9088 5.69598 12.978 5.63775C13.0793 5.55249 13.1038 5.50051 13.1038 5.37064C13.1038 5.03678 12.8814 4.71708 12.5211 4.53294L12.3268 4.43365V4.18714C12.3268 3.9799 12.3109 3.92461 12.2265 3.84024C12.1231 3.73683 12.0048 3.71826 11.849 3.78103ZM17.3673 6.3488C17.1633 6.37951 17.0765 6.73111 17.234 6.88864C17.2881 6.94266 17.3703 6.97042 17.4764 6.97042C17.6829 6.97042 17.8261 6.81261 17.7888 6.62614C17.7457 6.41076 17.5987 6.314 17.3673 6.3488ZM8.89892 10.0912C8.70677 10.2957 8.85799 10.6508 9.13725 10.6508C9.29428 10.6508 9.46432 10.4807 9.46432 10.3237C9.46432 10.0457 9.08732 9.89065 8.89892 10.0912ZM17.1932 10.2149C17.1932 10.4121 17.0299 10.9382 16.8722 11.2491C16.5146 11.9539 16.018 12.4542 15.3453 12.7872C14.7664 13.0737 14.5207 13.1169 13.3594 13.1362L12.3677 13.1528V13.0338C12.3677 12.8536 12.5052 12.382 12.6502 12.0648C13.0525 11.1847 13.9076 10.474 14.8622 10.2263C15.2198 10.1336 15.3279 10.1253 16.2219 10.1224L17.1932 10.1192V10.2149ZM9.19851 11.9972C9.87358 12.183 10.6236 12.7089 11.0341 13.2842C11.3328 13.7027 11.6288 14.4623 11.631 14.8158L11.6317 14.9119L10.5991 14.8924C9.40126 14.8699 9.14956 14.8221 8.57096 14.508C7.93348 14.1618 7.4374 13.6484 7.12248 13.0088C6.96721 12.6935 6.80625 12.1646 6.80625 11.9697V11.8704L7.83881 11.8888C8.74042 11.9048 8.91287 11.9186 9.19851 11.9972ZM17.3287 12.7367C17.1503 12.8086 17.0914 13.1039 17.2238 13.2633C17.4165 13.4954 17.782 13.3511 17.782 13.0431C17.782 12.926 17.7551 12.8663 17.6693 12.7924C17.5504 12.6901 17.4749 12.6778 17.3287 12.7367ZM18.9434 15.0755C18.9808 15.1129 18.9925 15.9816 18.9925 18.7359V22.3473L17.4692 22.3366L15.9459 22.3259L15.9355 18.7317C15.9278 16.1102 15.9375 15.1225 15.9711 15.082C16.0345 15.0057 18.8674 14.9995 18.9434 15.0755ZM6.27779 16.768C6.12726 16.8947 6.1127 17.051 6.23673 17.2087C6.41098 17.4302 6.80625 17.3087 6.80625 17.0335C6.80625 16.8584 6.76908 16.7889 6.63973 16.722C6.47931 16.639 6.42251 16.6462 6.27779 16.768ZM8.01027 19.7122C8.06716 19.7691 8.07378 19.9331 8.0643 21.0515L8.0535 22.3259L6.53022 22.3366L5.00695 22.3473V21.0464C5.00695 20.0891 5.01991 19.7325 5.05602 19.6964C5.09229 19.6601 5.47522 19.6473 6.52528 19.6473C7.76716 19.6473 7.95355 19.6555 8.01027 19.7122ZM1.10462 22.4418C0.966934 22.5795 0.964969 22.7654 1.09979 22.9002C1.23462 23.035 1.42048 23.0331 1.55817 22.8954C1.64539 22.8082 1.65934 22.7648 1.63946 22.6426C1.60929 22.4566 1.54341 22.3907 1.35738 22.3605C1.23515 22.3407 1.19185 22.3546 1.10462 22.4418Z'\n      />\n    </SvgIcon>\n  )\n}\nexport const SwapLandIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M10.1728 1.71164C10.4883 1.41836 10.904 1.18622 11.3039 1.08002C11.7414 0.963805 12.3982 0.975418 12.8142 1.10676C13.4591 1.31037 14.1107 1.87971 14.3754 2.47093L14.4258 2.58338H16.2153H18.0049L18.1214 2.48536C18.4524 2.2068 18.9094 2.08904 19.3466 2.16959C20.0164 2.29301 20.4943 2.82935 20.5377 3.50644C20.5685 3.98611 20.4383 4.36166 20.1413 4.64979C20.0493 4.73901 19.974 4.82607 19.974 4.84329C19.974 4.8605 20.0499 5.06292 20.1427 5.2931C20.2355 5.52328 20.3627 5.84044 20.4255 5.99788C20.6261 6.50151 20.9588 7.33514 21.1231 7.74602C21.2928 8.17052 21.517 8.73471 21.7284 9.26926C21.7995 9.44918 21.9119 9.7252 21.9781 9.88264C22.0443 10.0401 22.1441 10.2885 22.1998 10.4347C22.485 11.1837 22.4882 11.1889 22.6771 11.2152C22.8837 11.2441 23 11.368 23 11.5593C23 11.633 22.9535 11.8722 22.8967 12.0907C22.5561 13.4019 21.4143 14.5221 20.0754 14.8586C19.7697 14.9354 19.6019 14.9505 19.0743 14.9486C18.5282 14.9466 18.3864 14.9318 18.0492 14.8415C16.7884 14.5042 15.7564 13.5328 15.3377 12.2895C15.2613 12.0628 15.1859 11.783 15.17 11.6677C15.143 11.4714 15.149 11.4504 15.2645 11.3349C15.3546 11.2448 15.4262 11.2116 15.5306 11.2116C15.6639 11.2116 15.6784 11.1985 15.7447 11.0174C15.7839 10.9106 15.8694 10.6943 15.9348 10.5369C16.0001 10.3795 16.1733 9.94704 16.3196 9.57595C16.466 9.20485 16.7061 8.6068 16.8533 8.24695C17.0005 7.8871 17.1543 7.50067 17.1951 7.38821C17.2359 7.27576 17.3642 6.95374 17.4802 6.6726C17.5962 6.39147 17.7705 5.95903 17.8676 5.71163C17.9647 5.46424 18.0823 5.16621 18.1289 5.0493L18.2136 4.83683L18.1069 4.75284C18.0029 4.67105 17.9537 4.66888 16.2092 4.66888C14.469 4.66888 14.4174 4.67113 14.3928 4.74866C14.3789 4.79254 14.2774 4.96646 14.1673 5.1351L13.9672 5.44175L13.9548 6.72498L13.9424 8.00822L13.8197 8.20422C13.7086 8.38173 13.5373 8.51242 13.3392 8.57086C13.2741 8.59008 13.2677 8.66736 13.2677 9.43356C13.2677 10.4653 13.2374 10.5574 12.8979 10.5574C12.8294 10.5574 12.7453 10.5199 12.6968 10.4678C12.6181 10.3835 12.6134 10.3275 12.6134 9.48643V8.59453H12H11.3866V13.6038V18.6131H12H12.6134V14.9506C12.6134 12.6398 12.6281 11.2604 12.6534 11.2132C12.7085 11.1103 12.9193 11.042 13.0402 11.088C13.0443 11.0896 13.0484 11.091 13.0524 11.0925C13.0593 11.0949 13.066 11.0972 13.0725 11.0994C13.0938 11.1066 13.1128 11.1131 13.1298 11.1231C13.2682 11.2046 13.2681 11.5212 13.2677 14.4241V14.4242V14.4243V14.4243C13.2677 14.5946 13.2677 14.7738 13.2677 14.9624V18.6131L15.4247 18.6134C16.8038 18.6135 17.6375 18.6291 17.7362 18.6565C17.9142 18.7059 18.152 18.9004 18.2381 19.067C18.2824 19.1525 18.2974 19.3415 18.2974 19.8118V20.4421L18.4857 20.468C18.7427 20.5032 19.0329 20.67 19.1561 20.8532C19.2558 21.0016 19.2584 21.0236 19.2584 21.7478V22.4903L19.1333 22.6474C19.0645 22.7339 18.9272 22.846 18.8282 22.8966L18.6481 22.9886H11.9993H5.35064L5.14835 22.8868C5.02784 22.8262 4.90476 22.7229 4.84387 22.6312C4.74429 22.4814 4.74164 22.4582 4.74164 21.7414C4.74164 21.024 4.74425 21.0014 4.84387 20.8532C4.96123 20.6787 5.23762 20.5152 5.48301 20.4752L5.6519 20.4478L5.6696 19.8269C5.68927 19.1378 5.71704 19.0438 5.96521 18.8259C6.04446 18.7563 6.17879 18.6801 6.26377 18.6565C6.36252 18.6291 7.19623 18.6135 8.57528 18.6134L10.7323 18.6131V13.6028V8.59249L10.6199 8.55254C10.4012 8.47484 10.3016 8.39568 10.1803 8.20303L10.0576 8.00822L10.0452 6.69742C10.0384 5.97649 10.0178 5.37697 9.99931 5.36511C9.9504 5.33371 9.63545 4.83777 9.6065 4.74658C9.58278 4.67175 9.51494 4.66892 7.77514 4.67023C6.05346 4.67154 5.96394 4.6753 5.87406 4.75026L5.77969 4.82889L5.88641 5.08627C5.94509 5.2278 6.04561 5.48162 6.10981 5.6503C6.21118 5.91663 6.59242 6.86398 6.71865 7.16331C6.74237 7.21953 6.8657 7.53236 6.99275 7.85848C7.1198 8.18459 7.26706 8.55262 7.31997 8.67632C7.37293 8.80002 7.53551 9.20485 7.68129 9.57595C7.82712 9.94704 7.99988 10.3795 8.06523 10.5369C8.13062 10.6943 8.21612 10.9105 8.25526 11.0174C8.32163 11.1985 8.33614 11.2116 8.46937 11.2116C8.57393 11.2116 8.64549 11.2449 8.73623 11.3356C8.85052 11.4499 8.85801 11.4747 8.83237 11.6525C8.77994 12.0161 8.52441 12.6979 8.29803 13.0784C7.79849 13.9181 6.91121 14.5845 5.95082 14.8415C5.61358 14.9318 5.47185 14.9466 4.92565 14.9486C4.16256 14.9514 3.76362 14.8677 3.20294 14.587C2.74168 14.3561 2.51538 14.2007 2.19131 13.8924C1.85007 13.5678 1.6259 13.2731 1.39629 12.8473C1.20683 12.496 1 11.8237 1 11.5593C1 11.3675 1.11622 11.2441 1.32403 11.2152L1.49754 11.1912L1.74068 10.5778C1.87444 10.2404 2.0122 9.90366 2.04692 9.82936C2.0816 9.75506 2.14351 9.59864 2.18444 9.48177C2.22542 9.3649 2.29927 9.17725 2.34854 9.0648C2.39782 8.95234 2.49911 8.70392 2.57361 8.51275C2.64812 8.32158 2.78638 7.97195 2.88084 7.7358C2.97534 7.49965 3.13146 7.10401 3.22781 6.85662C3.32415 6.60922 3.4321 6.3424 3.46768 6.26368C3.53961 6.10449 3.73041 5.6265 3.90817 5.16037L4.02479 4.85445L3.84344 4.66966C3.74366 4.56804 3.61052 4.37446 3.54758 4.23952C3.44883 4.02794 3.43309 3.9435 3.43309 3.62613C3.43309 3.31306 3.44932 3.22343 3.54186 3.02604C3.94305 2.17025 4.96319 1.88065 5.72922 2.40509L5.98962 2.58338H7.78573C9.51449 2.58338 9.58278 2.58048 9.6065 2.50569C9.6606 2.33521 9.97265 1.89766 10.1728 1.71164ZM13.1012 20.4533H17.6454L17.6227 19.3287L6.35688 19.3354V20.4472L6.949 20.4605C7.52926 20.4735 7.54333 20.4759 7.65099 20.5837C7.80025 20.7331 7.79968 20.9235 7.64952 21.0527C7.53916 21.1476 7.52946 21.1484 6.50589 21.1484C5.75752 21.1484 5.46011 21.1619 5.42454 21.1975C5.3567 21.2653 5.3567 22.2174 5.42454 22.2852C5.4959 22.3566 18.5041 22.3566 18.5755 22.2852C18.627 22.2337 18.6473 21.3372 18.5997 21.2131C18.5773 21.1546 18.0904 21.1484 13.5055 21.1484H8.43608L8.31656 21.0289C8.18599 20.8983 8.17307 20.8369 8.2436 20.6821C8.24796 20.6725 8.2518 20.6633 8.25549 20.6546C8.26304 20.6366 8.26991 20.6202 8.27915 20.6052C8.37344 20.4529 8.71397 20.4529 12.53 20.4532H12.5301H12.5301C12.7124 20.4533 12.9027 20.4533 13.1012 20.4533ZM5.1919 5.1187L7.58336 11.181L2.22677 11.1915L4.64946 5.1187H5.1919ZM8.08322 11.9068C8.06523 13.0019 6.41822 14.29 4.92565 14.29C3.31041 14.29 1.74068 13.0019 1.73606 11.9262L8.08322 11.9068ZM21.7729 11.1924L19.3815 5.13011H18.8391L16.4164 11.2029L21.7729 11.1924ZM19.1152 14.3014C20.6078 14.3014 22.2548 13.0133 22.2728 11.9182L15.9257 11.9376C15.9303 13.0133 17.5 14.3014 19.1152 14.3014ZM11.3639 6.18108C11.2052 6.1408 11.0051 6.07848 10.9193 6.04262C10.8335 6.00675 10.7471 5.97743 10.7274 5.97743C10.6874 5.97743 10.677 7.73228 10.7163 7.83468C10.7369 7.88845 10.8199 7.89937 11.2078 7.89937H11.6745L11.6635 7.07686L11.6524 6.25431L11.3639 6.18108ZM13.2837 7.83468C13.2974 7.7991 13.3086 7.36666 13.3086 6.87371L13.3086 6.82883L13.3086 6.76015V6.75802V6.75593C13.3089 6.2034 13.309 6.02329 13.2432 5.99468C13.2114 5.98084 13.1641 6.00244 13.0941 6.03447L13.094 6.0345L13.0939 6.03456C13.0841 6.03903 13.0739 6.0437 13.0632 6.0485C12.9845 6.08396 12.7913 6.14407 12.6338 6.1821L12.3476 6.25125L12.3365 7.07531L12.3255 7.89937H12.7922C13.1801 7.89937 13.2631 7.88845 13.2837 7.83468ZM9.40017 3.24597V3.94114H6.41503L6.41242 3.24859L9.40017 3.24597ZM17.6318 3.94114H14.6753V3.59355V3.24597H17.6318V3.94114ZM5.72714 3.60892C5.72714 4.05609 5.36464 4.41859 4.91747 4.41859C4.47031 4.41859 4.10781 4.05609 4.10781 3.60892C4.10781 3.16176 4.47031 2.79926 4.91747 2.79926C5.36464 2.79926 5.72714 3.16176 5.72714 3.60892ZM19.1071 4.41859C19.5542 4.41859 19.9167 4.05609 19.9167 3.60892C19.9167 3.16176 19.5542 2.79926 19.1071 2.79926C18.6599 2.79926 18.2974 3.16176 18.2974 3.60892C18.2974 4.05609 18.6599 4.41859 19.1071 4.41859ZM12 4.59851C12.542 4.59851 12.9814 4.15912 12.9814 3.6171C12.9814 3.07508 12.542 2.63569 12 2.63569C11.458 2.63569 11.0186 3.07508 11.0186 3.6171C11.0186 4.15912 11.458 4.59851 12 4.59851ZM12 5.57993C13.084 5.57993 13.9628 4.70114 13.9628 3.6171C13.9628 2.53306 13.084 1.65428 12 1.65428C10.916 1.65428 10.0372 2.53306 10.0372 3.6171C10.0372 4.70114 10.916 5.57993 12 5.57993ZM12 3.98513C12.2033 3.98513 12.368 3.82036 12.368 3.6171C12.368 3.41384 12.2033 3.24907 12 3.24907C11.7967 3.24907 11.632 3.41384 11.632 3.6171C11.632 3.82036 11.7967 3.98513 12 3.98513Z'\n      />\n    </SvgIcon>\n  )\n}\nexport const SpotIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M18.7614 2.73747C18.9209 2.38156 19.2233 2.12358 19.6006 2.02158C19.7783 1.97357 20.2256 2.01004 20.4137 2.08784C20.6101 2.16911 20.9011 2.44042 21.0028 2.63714C21.1763 2.97265 21.1793 3.47161 21.0097 3.8C20.7249 4.35158 20.0492 4.61216 19.4722 4.39288L19.2705 4.31625L18.965 4.5635C18.4246 5.00088 16.5244 6.55315 16.3111 6.73149C16.1975 6.82649 16.0472 6.94463 15.9771 6.99406C15.8573 7.07862 15.8487 7.10208 15.8316 7.39051C15.8093 7.76646 15.7077 8.00887 15.4691 8.2549C15.1151 8.62 14.5627 8.71679 14.0859 8.49727C13.6466 8.29502 13.3829 7.91789 13.3449 7.43738C13.3337 7.29583 13.3189 7.1748 13.312 7.16842C13.2765 7.13553 10.4037 5.76608 10.3702 5.76608C10.3603 5.76608 10.2817 5.83661 10.1955 5.92283C9.99761 6.12069 9.65442 6.29017 9.39441 6.31834C9.21664 6.33761 8.92744 6.28557 8.72552 6.19797C8.68088 6.17862 4.9861 10.3204 4.9861 10.3204C4.9861 10.3394 5.00415 10.3661 5.02623 10.3798C5.04826 10.3934 5.10534 10.533 5.15302 10.69C5.30157 11.1791 5.17867 11.6385 4.81089 11.9692C4.52039 12.2304 4.37831 12.2838 3.96979 12.2852C3.55542 12.2866 3.40184 12.2289 3.12134 11.9665C2.75384 11.6228 2.63831 11.1781 2.78823 10.6846C2.85966 10.4494 2.91486 10.354 3.0678 10.2016C3.4003 9.87022 3.80312 9.74184 4.23147 9.83079L4.46226 9.87868C4.46226 9.87868 8.15679 5.73372 8.15655 5.70912C8.1563 5.68457 8.12886 5.57464 8.09557 5.46488C7.95849 5.01303 8.05195 4.58671 8.36253 4.24685C8.60547 3.98107 8.82743 3.86484 9.15802 3.83025C9.67743 3.77598 10.1621 4.04575 10.3868 4.51427C10.4543 4.65496 10.5217 4.84928 10.5366 4.94608C10.5609 5.10405 10.581 5.12954 10.7324 5.19544C10.8251 5.23581 11.1754 5.40094 11.5108 5.56245C11.8462 5.72392 12.3493 5.96523 12.6288 6.09861C12.9082 6.23203 13.2438 6.39672 13.3744 6.46453L13.6119 6.58786L13.7403 6.46591C13.8109 6.39883 13.951 6.30106 14.0516 6.24862C14.4186 6.05727 15.1743 6.15227 15.4169 6.42025C15.4554 6.46294 15.5015 6.49782 15.5191 6.49782C15.5367 6.49782 15.6756 6.39172 15.8278 6.26208C15.98 6.13239 16.1526 5.99064 16.2114 5.94702C16.2702 5.9034 16.6518 5.5933 17.0596 5.25792C17.4674 4.92254 17.8607 4.6024 17.9336 4.5465C18.0065 4.49061 18.199 4.33511 18.3613 4.20096C18.5236 4.0668 18.6913 3.92899 18.7338 3.89468C18.808 3.8348 18.8084 3.82598 18.7415 3.67109C18.6378 3.43104 18.6471 2.99252 18.7614 2.73747ZM17.6145 7.65641C17.7433 7.476 17.8494 7.39091 18.0227 7.32912C18.2174 7.25969 21.5007 7.24517 21.7438 7.31266C21.9387 7.36681 22.1242 7.52433 22.2245 7.72089C22.2952 7.85939 22.304 7.96273 22.304 8.64785V9.4189L22.1969 9.50313C22.0604 9.6105 21.8972 9.6105 21.7607 9.50313L21.6536 9.4189V8.7544C21.6536 8.38893 21.6425 8.06099 21.6289 8.02562C21.607 7.96838 21.4167 7.96131 19.902 7.96131H18.1997L18.1776 8.05277C18.1655 8.1031 18.1606 11.0529 18.1667 14.608L18.1778 21.0717H19.9055H21.6333L21.6436 15.7796L21.6539 10.4874L21.7609 10.4033C21.8197 10.357 21.9178 10.3191 21.9788 10.3191C22.0399 10.3191 22.1379 10.357 22.1968 10.4033L22.3038 10.4874L22.314 15.7796L22.3244 21.0717C22.3244 21.0717 22.2486 21.0717 22.6736 21.0717C23.0986 21.0717 23.1189 21.7425 22.6736 21.7425H1.20173C0.943021 21.7425 0.922685 21.109 1.20173 21.109H1.533V15.7812C1.533 15.377 1.86061 15.0494 2.26474 15.0494H5.59824C5.91893 15.0494 6.36829 15.36 6.36829 15.7812V18.348L6.38861 21.0717H6.87644L6.89677 15.36L6.89912 9.64266C6.89912 9.23852 7.22673 8.91091 7.63086 8.91091H10.9644C11.3685 8.91091 11.6961 9.23852 11.6961 9.64266V21.092H11.9368H12.1799L12.1761 12.0411C12.1761 11.5964 12.6233 11.3094 12.997 11.3094H16.3305C16.7346 11.3094 17.0622 11.637 17.0622 12.0411V21.0717H17.2428H17.4867L17.507 14.425L17.5274 7.77837L17.6145 7.65641ZM2.26474 15.7812V21.1025L3.42753 21.092L5.59824 21.0726V15.7812H2.26474ZM19.9282 3.79684C20.2313 3.79684 20.477 3.55113 20.477 3.24803C20.477 2.94493 20.2313 2.69922 19.9282 2.69922C19.6251 2.69922 19.3794 2.94493 19.3794 3.24803C19.3794 3.55113 19.6251 3.79684 19.9282 3.79684ZM9.27728 5.6262C9.58038 5.6262 9.82609 5.38049 9.82609 5.07739C9.82609 4.77429 9.58038 4.52858 9.27728 4.52858C8.97419 4.52858 8.72848 4.77429 8.72848 5.07739C8.72848 5.38049 8.97419 5.6262 9.27728 5.6262ZM4.54128 11.1346C4.54128 11.4377 4.29557 11.6834 3.99247 11.6834C3.68937 11.6834 3.44366 11.4377 3.44366 11.1346C3.44366 10.8315 3.68937 10.5858 3.99247 10.5858C4.29557 10.5858 4.54128 10.8315 4.54128 11.1346ZM12.997 12.0493H16.3305V21.0741H12.997V12.0493ZM15.1922 7.43523C15.1922 7.73833 14.9465 7.98404 14.6434 7.98404C14.3403 7.98404 14.0946 7.73833 14.0946 7.43523C14.0946 7.13213 14.3403 6.88642 14.6434 6.88642C14.9465 6.88642 15.1922 7.13213 15.1922 7.43523ZM7.59021 9.85405H10.9237V21.0741H7.59021V9.85405Z'\n      />\n    </SvgIcon>\n  )\n}\nexport const BlockTradeLandIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M1.46857 2.53191C1.75021 2.24817 1.93058 2.14129 2.26849 2.0581C2.55153 1.98842 21.3255 1.97749 21.652 2.04681C22.0029 2.12137 22.2203 2.24478 22.5038 2.53052C22.9432 2.97334 22.9673 3.06496 22.9852 4.35813L23 5.42653L22.9012 5.54139C22.777 5.6858 22.58 5.69676 22.4496 5.56656C22.3631 5.48014 22.3591 5.43905 22.3394 4.44468C22.319 3.41801 22.3183 3.41151 22.2103 3.22835C22.075 2.99904 21.9647 2.89621 21.7092 2.76134L21.5088 2.65548H11.9868H2.46482L2.26436 2.76122C1.99675 2.90235 1.8589 3.03918 1.73626 3.28523L1.63425 3.48995V9.45609V15.4223H11.0458H20.4574L20.447 9.99025L20.4366 4.55823H11.9868H3.53699L3.51653 9.69358C3.51541 9.97352 3.51439 10.2386 3.51342 10.4896C3.49746 14.6109 3.49619 14.939 3.35405 15.02C3.34177 15.027 3.32844 15.0322 3.31396 15.0378L3.3139 15.0378C3.3037 15.0417 3.29291 15.0459 3.28153 15.0511C3.13299 15.1188 3.06998 15.1048 2.94051 14.9753L2.8209 14.8557L2.82115 9.70697C2.82131 6.07666 2.83469 4.51023 2.86653 4.39549C2.92447 4.18688 3.16565 3.94571 3.37425 3.88776C3.60516 3.82369 20.3684 3.82369 20.5994 3.88776C20.808 3.94571 21.0491 4.18688 21.1071 4.39549C21.139 4.51043 21.1523 6.15326 21.1525 9.99025L21.1527 15.4223H21.746H22.3394V10.8566V6.29099L22.459 6.17138C22.6053 6.02502 22.7422 6.01904 22.8864 6.15268L22.9953 6.25359L22.9845 11.4415L22.9736 16.6294L22.8787 16.8644C22.7003 17.3062 22.3168 17.6784 21.8466 17.866C21.6777 17.9334 21.4095 17.9397 18.2168 17.9503L14.7693 17.9619L14.7697 18.0526C14.7702 18.1653 14.9534 19.335 15.0163 19.6267L15.0625 19.8415H15.4492C15.9991 19.8415 16.2327 19.9543 16.4134 20.3069C16.4834 20.4433 16.4928 20.5298 16.4811 20.9273C16.468 21.3716 16.4627 21.3951 16.3423 21.5463C16.2735 21.6327 16.1361 21.7448 16.037 21.7954L15.8568 21.8875H11.9868H8.11683L7.93662 21.7954C7.83752 21.7448 7.70011 21.6326 7.63128 21.5461C7.5064 21.3892 7.50615 21.3878 7.50615 20.8645C7.50615 20.3412 7.5064 20.3399 7.63128 20.1829C7.83821 19.9229 8.04854 19.8415 8.51395 19.8415H8.91107L8.95735 19.6267C9.02016 19.335 9.20336 18.1653 9.20389 18.0526L9.2043 17.9619L5.75686 17.9503C2.5641 17.9397 2.29595 17.9334 2.12704 17.866C1.65683 17.6784 1.2733 17.3062 1.09489 16.8644L1 16.6294V9.98002V3.33065L1.10029 3.06627C1.17759 2.86249 1.26201 2.74002 1.46857 2.53191ZM9.04217 5.41434C9.09369 5.30791 9.17574 5.21739 9.257 5.17729C9.36139 5.12586 9.5346 5.11231 10.0983 5.11158C10.8959 5.11051 11.0234 5.14198 11.1678 5.37555C11.2486 5.50636 11.2503 5.5722 11.2503 8.66725C11.2503 8.83042 11.2503 8.98553 11.2503 9.13301C11.2508 11.6394 11.2508 11.94 11.1011 12.0782C11.0807 12.097 11.0575 12.1128 11.0311 12.1308C11.0197 12.1386 11.0077 12.1467 10.9951 12.1557L10.8615 12.251L7.75167 12.2626L7.48412 12.2636C4.7731 12.2738 4.44653 12.275 4.28665 12.1124C4.26476 12.0901 4.24599 12.0648 4.22466 12.036L4.22061 12.0305L4.21709 12.0258L4.21212 12.0191L4.20917 12.0151L4.10986 11.8828L4.09816 10.419C4.08518 8.79578 4.08956 8.76361 4.35018 8.57772C4.46672 8.49461 4.53386 8.48528 5.10215 8.47337L5.72617 8.46024V7.3819V6.30355L5.83677 6.17212C6.01751 5.95729 6.13908 5.92902 6.88083 5.9291C7.43315 5.92914 7.57154 5.94138 7.69029 6.00071C7.89443 6.10268 8.01764 6.36387 8.01764 6.6947V6.952H8.48821H8.95878V6.2693C8.95878 5.66603 8.96848 5.56656 9.04217 5.41434ZM15.7364 5.1714C15.3387 5.25434 15.0755 5.34743 14.7693 5.51353C13.4672 6.21991 12.7404 7.58363 12.8903 9.03888C12.9924 10.0302 13.4247 10.8266 14.2099 11.4701C14.8435 11.9892 15.8984 12.3238 16.6711 12.2507C17.815 12.1426 18.7824 11.5821 19.3878 10.6771C19.8458 9.99242 20.0247 9.36112 19.9971 8.52739C19.9811 8.04585 19.9653 7.95493 19.8304 7.56816C19.4258 6.40831 18.5537 5.56443 17.4291 5.2446C16.985 5.11833 16.1617 5.08273 15.7364 5.1714ZM5.88898 13.252C5.81369 13.1112 5.84275 12.928 5.9572 12.8219C6.06526 12.7218 6.06711 12.7216 6.96176 12.7216C8.04277 12.7216 8.1404 12.7509 8.1404 13.0755C8.1404 13.3759 8.00189 13.4172 6.99466 13.4172C6.16101 13.4172 5.96149 13.3874 5.88898 13.252ZM8.95563 12.8412C8.81585 12.981 8.80321 13.1189 8.91692 13.2635C9.13359 13.539 9.59082 13.3195 9.50583 12.9808C9.47821 12.8707 9.27398 12.722 9.15 12.7218C9.10887 12.7217 9.02143 12.7754 8.95563 12.8412ZM13.1971 13.2976C13.0455 13.1549 13.0536 12.9654 13.2175 12.8275L13.3434 12.7216H14.2783H15.2132L15.339 12.8275C15.5836 13.0334 15.4676 13.3464 15.1277 13.3973C15.0313 13.4118 14.5812 13.4176 14.1275 13.4102C13.3195 13.3971 13.3005 13.3947 13.1971 13.2976ZM16.1341 12.7813C16.0022 12.8741 15.9544 13.049 16.019 13.2027C16.1076 13.4135 16.2065 13.4238 17.9953 13.4096L19.6051 13.3968L19.6833 13.3002C19.7834 13.1764 19.7834 12.9624 19.6833 12.8387L19.6051 12.7421L17.9135 12.7308C16.458 12.721 16.2097 12.7281 16.1341 12.7813ZM4.68088 14.5853C4.49638 14.4008 4.57867 14.0561 4.81616 14.0187C4.87779 14.009 6.205 14.0032 7.76554 14.0058L10.6028 14.0106L10.681 14.1072C10.7925 14.2449 10.7825 14.4616 10.6588 14.5853L10.5584 14.6857H7.66983H4.7813L4.68088 14.5853ZM13.3781 14.019C13.0869 14.0736 12.9955 14.3929 13.2175 14.5798L13.3434 14.6857H15.5531H17.7627L17.8871 14.5613C17.9917 14.4567 18.0073 14.416 17.9853 14.3057C17.9708 14.2336 17.9221 14.1376 17.8771 14.0925C17.7973 14.0127 17.7381 14.0104 15.6377 14.0052C14.4512 14.0023 13.4343 14.0085 13.3781 14.019ZM18.493 14.325C18.493 14.2168 18.6393 14.0407 18.7495 14.0163C18.7997 14.0052 19.0145 14.0016 19.2269 14.0083C19.5695 14.019 19.6213 14.0307 19.6872 14.1121C19.7951 14.2454 19.7831 14.4632 19.661 14.5853C19.5687 14.6776 19.5299 14.6857 19.1802 14.6852C18.971 14.6849 18.7577 14.6733 18.7061 14.6595C18.6064 14.6328 18.493 14.4548 18.493 14.325ZM10.5956 8.67061V11.5759H10.1045H9.61349V8.67061V5.76534H10.1045H10.5956V8.67061ZM7.36293 9.10026V11.5759H6.8719H6.38087V9.10026V6.62465H6.8719H7.36293V9.10026ZM8.95956 11.5759L8.94896 9.60152L8.93832 7.62717L8.50654 7.61563C8.26909 7.60928 8.06196 7.61698 8.0462 7.63269C8.03049 7.6484 8.01764 8.54204 8.01764 9.61858V11.5759H8.48862H8.95956ZM5.72617 10.3688V11.5759H5.23514H4.74411V10.3688V9.16164H5.23514H5.72617V10.3688ZM13.6031 8.66983C13.6031 7.17757 14.7123 5.94809 16.1401 5.78333V8.83351H16.1479L16.1401 8.84949L18.9065 10.1939C18.402 11.0227 17.4983 11.5751 16.4675 11.5751C14.8855 11.5751 13.6031 10.2744 13.6031 8.66983ZM16.7948 8.43974L19.1819 9.59985C19.2791 9.30786 19.3318 8.99509 19.3318 8.66983C19.3318 7.17757 18.2226 5.94809 16.7948 5.78333V8.43974ZM22.3862 16.1179C22.3862 16.6294 22.1438 16.989 21.8044 17.1581L21.5927 17.2636L12.0359 17.2632L2.47902 17.2628L2.27197 17.1664C1.93705 17.0105 1.6811 16.5672 1.6811 16.1179H12.0337H22.3862ZM14.1003 17.9593L14.4177 19.8415H12.2901C10.1995 19.8415 10.1605 19.843 10.0546 19.9264C9.97141 19.9918 9.94678 20.0472 9.94678 20.1689C9.94678 20.2906 9.97141 20.346 10.0546 20.4114C10.1613 20.4954 10.1915 20.4963 12.9789 20.4963C15.7215 20.4963 15.7965 20.4983 15.8377 20.5754C15.896 20.6844 15.8912 21.1235 15.831 21.1837C15.7598 21.2549 8.30755 21.2549 8.23635 21.1837C8.17616 21.1235 8.1713 20.6844 8.22961 20.5754C8.26827 20.5032 8.65782 20.4966 8.82064 20.4963C9.16931 20.4955 9.33299 20.5159 9.43746 20.4287C9.53325 20.3487 9.60685 20.1063 9.69482 19.5695C9.70398 19.5136 9.96032 17.9593 9.96032 17.9593H12.0303H14.1003Z'\n      />\n    </SvgIcon>\n  )\n}\nexport const GoIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24'>\n      <path d='M16.0037 9.41421L7.39712 18.0208L5.98291 16.6066L14.5895 8H7.00373V6H18.0037V17H16.0037V9.41421Z' />\n    </SvgIcon>\n  )\n}\nexport const BlindBoxIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M10.3391 3.91403C9.79639 3.0061 8.09699 1.29612 5.65396 1.67798C4.4416 1.86749 3.85889 2.47582 3.60147 3.14219C3.37375 3.73171 3.39391 4.38598 3.49923 4.875H10.3125V4.3125C10.3125 4.17001 10.3302 4.03164 10.3634 3.89947L10.3391 3.91403ZM2.25 5.25H10.3125V8.625H3H2.625H2.25C1.62868 8.625 1.125 8.12132 1.125 7.5V6.375C1.125 5.75368 1.62868 5.25 2.25 5.25ZM10.6875 5.25V8.625H13.3125V5.25H10.6875ZM13.3125 9H13.6875H21V18.6782H3V9H10.3125H10.6875H13.3125ZM2.625 19.0532V18.6782V9H2.25C1.42157 9 0.75 8.32843 0.75 7.5V6.375C0.75 5.54657 1.42157 4.875 2.25 4.875H3.11661C3.01421 4.3416 3.00386 3.64857 3.25167 3.00707C3.55988 2.20919 4.25841 1.51657 5.59605 1.30748C8.06524 0.921529 9.81641 2.49645 10.519 3.50297C10.8056 2.97977 11.3614 2.625 12 2.625C12.6386 2.625 13.1944 2.97977 13.481 3.50297C14.1836 2.49645 15.9348 0.921529 18.4039 1.30748C19.7416 1.51657 20.4401 2.20919 20.7483 3.00707C20.9961 3.64857 20.9858 4.3416 20.8834 4.875H21.75C22.5784 4.875 23.25 5.54657 23.25 6.375V7.5C23.25 8.32843 22.5784 9 21.75 9H21.375V18.6782V19.0532V20.25C21.375 21.4926 20.3676 22.5 19.125 22.5H4.875C3.63236 22.5 2.625 21.4926 2.625 20.25V19.0532ZM21 19.0532V20.25C21 21.2855 20.1605 22.125 19.125 22.125H4.875C3.83947 22.125 3 21.2855 3 20.25V19.0532H21ZM21 8.625H13.6875V5.25H21.75C22.3713 5.25 22.875 5.75368 22.875 6.375V7.5C22.875 8.12132 22.3713 8.625 21.75 8.625H21.375H21ZM20.5008 4.875H13.6875V4.3125C13.6875 4.17001 13.6698 4.03164 13.6366 3.89947L13.6609 3.91403C14.2036 3.0061 15.903 1.29612 18.346 1.67798C19.5584 1.86749 20.1411 2.47582 20.3985 3.14219C20.6262 3.73171 20.6061 4.38598 20.5008 4.875ZM10.6875 4.3125V4.875H13.3125V4.3125C13.3125 3.58763 12.7249 3 12 3C11.2751 3 10.6875 3.58763 10.6875 4.3125ZM14.135 6.27413L14.4585 6.27356C14.4724 6.27354 14.4838 6.28485 14.4838 6.29883L14.4841 6.4357C14.4841 6.44968 14.4728 6.46104 14.4588 6.46106L14.1354 6.46162C14.1214 6.46165 14.11 6.45034 14.11 6.43636L14.1098 6.29948C14.1097 6.2855 14.1211 6.27415 14.135 6.27413ZM1.93614 6.27401L2.28301 6.27461C2.29052 6.27463 2.2966 6.28072 2.29658 6.28823L2.2963 6.44948C2.29629 6.45699 2.29019 6.46306 2.28269 6.46305L1.93581 6.46245C1.9283 6.46243 1.92223 6.45634 1.92224 6.44883L1.92252 6.28758C1.92254 6.28007 1.92863 6.274 1.93614 6.27401ZM2.87629 6.27431H3.21754C3.2266 6.27431 3.23394 6.28166 3.23394 6.29072V6.44634C3.23394 6.4554 3.2266 6.46275 3.21754 6.46275H2.87629C2.86723 6.46275 2.85988 6.4554 2.85988 6.44634V6.29072C2.85988 6.28166 2.86723 6.27431 2.87629 6.27431ZM4.15473 6.27461L3.81442 6.27401C3.8051 6.274 3.79753 6.28154 3.79752 6.29086L3.79725 6.44555C3.79723 6.45487 3.80477 6.46244 3.81409 6.46245L4.1544 6.46305C4.16372 6.46306 4.17129 6.45552 4.17131 6.4462L4.17158 6.29151C4.1716 6.28219 4.16405 6.27462 4.15473 6.27461ZM4.75223 6.27431H5.0916C5.10118 6.27431 5.10894 6.28208 5.10894 6.29166V6.4454C5.10894 6.45498 5.10118 6.46275 5.0916 6.46275H4.75223C4.74265 6.46275 4.73488 6.45498 4.73488 6.4454V6.29166C4.73488 6.28208 4.74265 6.27431 4.75223 6.27431ZM6.02973 6.27461L5.68942 6.27401C5.6801 6.274 5.67253 6.28154 5.67252 6.29086L5.67225 6.44555C5.67223 6.45487 5.67977 6.46244 5.68909 6.46245L6.0294 6.46305C6.03872 6.46306 6.04629 6.45552 6.04631 6.4462L6.04658 6.29151C6.0466 6.28219 6.03905 6.27462 6.02973 6.27461ZM6.62723 6.27431H6.9666C6.97618 6.27431 6.98394 6.28208 6.98394 6.29166V6.4454C6.98394 6.45498 6.97618 6.46275 6.9666 6.46275H6.62723C6.61765 6.46275 6.60988 6.45498 6.60988 6.4454V6.29166C6.60988 6.28208 6.61765 6.27431 6.62723 6.27431ZM7.90426 6.27461L7.56489 6.27401C7.55531 6.274 7.54753 6.28175 7.54752 6.29133L7.54725 6.44508C7.54723 6.45466 7.55498 6.46244 7.56456 6.46245L7.90394 6.46304C7.91352 6.46306 7.92129 6.45531 7.92131 6.44573L7.92158 6.29198C7.9216 6.2824 7.91384 6.27462 7.90426 6.27461ZM8.50098 6.27401L8.84317 6.27461C8.85197 6.27463 8.8591 6.28177 8.85908 6.29057L8.85881 6.44714C8.85879 6.45594 8.85164 6.46306 8.84284 6.46305L8.50066 6.46245C8.49185 6.46243 8.48473 6.45529 8.48475 6.44648L8.48502 6.28992C8.48503 6.28112 8.49218 6.274 8.50098 6.27401ZM9.78285 6.27431H9.43598C9.42847 6.27431 9.42238 6.2804 9.42238 6.28791V6.44916C9.42238 6.45666 9.42847 6.46275 9.43598 6.46275H9.78285C9.79036 6.46275 9.79644 6.45666 9.79644 6.44916V6.28791C9.79644 6.2804 9.79036 6.27431 9.78285 6.27431ZM15.4043 6.27461L15.0649 6.27401C15.0553 6.274 15.0475 6.28175 15.0475 6.29133L15.0472 6.44508C15.0472 6.45466 15.055 6.46244 15.0646 6.46245L15.4039 6.46304C15.4135 6.46306 15.4213 6.45531 15.4213 6.44573L15.4216 6.29198C15.4216 6.2824 15.4138 6.27462 15.4043 6.27461ZM16.0027 6.27431H16.3411C16.351 6.27431 16.3589 6.28229 16.3589 6.29212V6.44494C16.3589 6.45477 16.351 6.46275 16.3411 6.46275H16.0027C15.9929 6.46275 15.9849 6.45477 15.9849 6.44494V6.29212C15.9849 6.28229 15.9929 6.27431 16.0027 6.27431ZM17.2816 6.27508L16.9375 6.27448C16.9293 6.27447 16.9225 6.28117 16.9225 6.28945L16.9222 6.44789C16.9222 6.45618 16.9289 6.4629 16.9372 6.46292L17.2813 6.46352C17.2896 6.46353 17.2963 6.45683 17.2963 6.44854L17.2966 6.29011C17.2966 6.28182 17.2899 6.27509 17.2816 6.27508ZM17.9672 6.27478H18.3141C18.3216 6.27478 18.3277 6.28087 18.3277 6.28837V6.44962C18.3277 6.45713 18.3216 6.46322 18.3141 6.46322H17.9672C17.9597 6.46322 17.9536 6.45713 17.9536 6.44962V6.28837C17.9536 6.28087 17.9597 6.27478 17.9672 6.27478ZM19.2511 6.27431H18.9052C18.8974 6.27431 18.8911 6.28061 18.8911 6.28837V6.44869C18.8911 6.45645 18.8974 6.46275 18.9052 6.46275H19.2511C19.2589 6.46275 19.2652 6.45645 19.2652 6.44869V6.28837C19.2652 6.28061 19.2589 6.27431 19.2511 6.27431ZM19.8432 6.27431H20.1882C20.1962 6.27431 20.2027 6.28082 20.2027 6.28884V6.44822C20.2027 6.45624 20.1962 6.46275 20.1882 6.46275H19.8432C19.8351 6.46275 19.8286 6.45624 19.8286 6.44822V6.28884C19.8286 6.28082 19.8351 6.27431 19.8432 6.27431ZM21.1266 6.27478H20.7797C20.7722 6.27478 20.7661 6.28087 20.7661 6.28837V6.44962C20.7661 6.45713 20.7722 6.46322 20.7797 6.46322H21.1266C21.1341 6.46322 21.1402 6.45713 21.1402 6.44962V6.28837C21.1402 6.28087 21.1341 6.27478 21.1266 6.27478ZM21.7182 6.27431H22.0632C22.0712 6.27431 22.0777 6.28082 22.0777 6.28884V6.44822C22.0777 6.45624 22.0712 6.46275 22.0632 6.46275H21.7182C21.7101 6.46275 21.7036 6.45624 21.7036 6.44822V6.28884C21.7036 6.28082 21.7101 6.27431 21.7182 6.27431ZM3.81505 20.3789H4.15349C4.16333 20.3789 4.1713 20.3869 4.1713 20.3967V20.5486C4.1713 20.5584 4.16333 20.5664 4.15349 20.5664H3.81505C3.80522 20.5664 3.79724 20.5584 3.79724 20.5486V20.3967C3.79724 20.3869 3.80522 20.3789 3.81505 20.3789ZM4.75294 20.3789H5.09044C5.1008 20.3789 5.10919 20.3873 5.10919 20.3977V20.5477C5.10919 20.558 5.1008 20.5664 5.09044 20.5664H4.75294C4.74259 20.5664 4.73419 20.558 4.73419 20.5477V20.3977C4.73419 20.3873 4.74259 20.3789 4.75294 20.3789ZM6.02849 20.3789H5.69005C5.68022 20.3789 5.67224 20.3869 5.67224 20.3967V20.5486C5.67224 20.5584 5.68022 20.5664 5.69005 20.5664H6.02849C6.03833 20.5664 6.0463 20.5584 6.0463 20.5486V20.3967C6.0463 20.3869 6.03833 20.3789 6.02849 20.3789ZM6.62802 20.3789H6.96552C6.97562 20.3789 6.9838 20.3871 6.9838 20.3972V20.5481C6.9838 20.5582 6.97562 20.5664 6.96552 20.5664H6.62802C6.61793 20.5664 6.60974 20.5582 6.60974 20.5481V20.3972C6.60974 20.3871 6.61793 20.3789 6.62802 20.3789ZM7.90294 20.3789H7.56544C7.55509 20.3789 7.54669 20.3873 7.54669 20.3977V20.5477C7.54669 20.558 7.55509 20.5664 7.56544 20.5664H7.90294C7.9133 20.5664 7.92169 20.558 7.92169 20.5477V20.3977C7.92169 20.3873 7.9133 20.3789 7.90294 20.3789ZM8.50302 20.3789H8.84052C8.85062 20.3789 8.8588 20.3871 8.8588 20.3972V20.5481C8.8588 20.5582 8.85062 20.5664 8.84052 20.5664H8.50302C8.49293 20.5664 8.48474 20.5582 8.48474 20.5481V20.3972C8.48474 20.3871 8.49293 20.3789 8.50302 20.3789ZM9.77849 20.3789H9.44005C9.43022 20.3789 9.42224 20.3869 9.42224 20.3967V20.5486C9.42224 20.5584 9.43022 20.5664 9.44005 20.5664H9.77849C9.78833 20.5664 9.7963 20.5584 9.7963 20.5486V20.3967C9.7963 20.3869 9.78833 20.3789 9.77849 20.3789ZM14.1275 20.3789H14.4659C14.476 20.3789 14.4842 20.3871 14.4842 20.3972V20.5481C14.4842 20.5582 14.476 20.5664 14.4659 20.5664H14.1275C14.1174 20.5664 14.1092 20.5582 14.1092 20.5481V20.3972C14.1092 20.3871 14.1174 20.3789 14.1275 20.3789ZM15.4035 20.3789H15.0651C15.0552 20.3789 15.0472 20.3869 15.0472 20.3967V20.5486C15.0472 20.5584 15.0552 20.5664 15.0651 20.5664H15.4035C15.4133 20.5664 15.4213 20.5584 15.4213 20.5486V20.3967C15.4213 20.3869 15.4133 20.3789 15.4035 20.3789ZM16.0029 20.3789H16.3404C16.3508 20.3789 16.3592 20.3873 16.3592 20.3977V20.5477C16.3592 20.558 16.3508 20.5664 16.3404 20.5664H16.0029C15.9926 20.5664 15.9842 20.558 15.9842 20.5477V20.3977C15.9842 20.3873 15.9926 20.3789 16.0029 20.3789ZM17.278 20.3789H16.9405C16.9304 20.3789 16.9222 20.3871 16.9222 20.3972V20.5481C16.9222 20.5582 16.9304 20.5664 16.9405 20.5664H17.278C17.2881 20.5664 17.2963 20.5582 17.2963 20.5481V20.3972C17.2963 20.3871 17.2881 20.3789 17.278 20.3789ZM17.9712 20.3789H18.3097C18.3198 20.3789 18.3279 20.3871 18.3279 20.3972V20.5481C18.3279 20.5582 18.3198 20.5664 18.3097 20.5664H17.9712C17.9611 20.5664 17.9529 20.5582 17.9529 20.5481V20.3972C17.9529 20.3871 17.9611 20.3789 17.9712 20.3789ZM19.2472 20.3789H18.9087C18.8986 20.3789 18.8904 20.3871 18.8904 20.3972V20.5481C18.8904 20.5582 18.8986 20.5664 18.9087 20.5664H19.2472C19.2573 20.5664 19.2654 20.5582 19.2654 20.5481V20.3972C19.2654 20.3871 19.2573 20.3789 19.2472 20.3789ZM19.8458 20.3789H20.1851C20.195 20.3789 20.2029 20.3869 20.2029 20.3967V20.5486C20.2029 20.5584 20.195 20.5664 20.1851 20.5664H19.8458C19.8359 20.5664 19.8279 20.5584 19.8279 20.5486V20.3967C19.8279 20.3869 19.8359 20.3789 19.8458 20.3789Z'\n      />\n      <path\n        d='M12.08 15.1207C11.855 13.8682 13.6175 13.5382 13.6175 12.6832C13.6175 12.1657 13.25 11.7907 12.485 11.7907C11.9675 11.7907 11.495 12.0157 11.06 12.4657L10.6625 12.0982C11.1575 11.5732 11.7425 11.2207 12.5525 11.2207C13.61 11.2207 14.2925 11.7682 14.2925 12.6307C14.2925 13.7632 12.5 13.9957 12.695 15.1207H12.08ZM12.4025 16.9657C12.1325 16.9657 11.9225 16.7782 11.9225 16.4782C11.9225 16.1782 12.14 15.9757 12.4025 15.9757C12.665 15.9757 12.8825 16.1782 12.8825 16.4782C12.8825 16.7782 12.665 16.9657 12.4025 16.9657Z'\n        fill='#446EFF'\n      />\n    </SvgIcon>\n  )\n}\nexport const NormalRedpacketIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M7.35166 1.77115H7.15381C5.91117 1.77115 4.90381 2.77851 4.90381 4.02115V11.2108L3.38145 17.5115C3.32189 17.758 3.30541 18.0049 3.32717 18.2441C3.44145 18.1578 3.56393 18.0818 3.69323 18.0175C3.69501 17.8795 3.71216 17.7395 3.74596 17.5996L4.90381 12.8075V16.2624C5.01682 16.1417 5.14253 16.0331 5.27881 15.9386V4.02115C5.27881 2.98561 6.11827 2.14615 7.15381 2.14615H17.9711C19.0066 2.14615 19.8461 2.98561 19.8461 4.02115V19.6038C19.8461 20.6394 19.0066 21.4788 17.9711 21.4788H7.15381C6.98169 21.4788 6.81499 21.4557 6.65666 21.4122C6.58077 21.5238 6.49544 21.6285 6.40181 21.7251C6.63696 21.8085 6.89009 21.8538 7.15381 21.8538H11.7731L15.4133 22.7334C16.3323 22.9554 17.2558 22.5787 17.7735 21.8538H17.9711C19.2137 21.8538 20.2211 20.8465 20.2211 19.6038V12.4151L21.7437 6.11357C22.0313 4.92328 21.3143 3.72533 20.1375 3.41141C19.8717 2.46503 19.0024 1.77115 17.9711 1.77115H13.3515L9.71182 0.89173C8.7929 0.669703 7.86942 1.04638 7.35166 1.77115ZM8.09836 19.641L8.10256 19.641C8.1118 19.641 8.1193 19.6329 8.11979 19.6229C8.11269 19.629 8.10554 19.635 8.09836 19.641ZM8.78635 17.038C11.3359 17.038 13.8856 17.0381 16.4353 17.0383C16.6372 17.0383 16.7755 17.025 16.8501 16.9983C17.0555 16.9253 17.2386 16.7139 17.2515 16.4759C17.2596 16.3299 17.2679 16.1157 17.2199 15.9742C17.148 15.7618 16.9953 15.625 16.7617 15.5637C16.7534 15.5615 16.7492 15.5562 16.749 15.5477C16.7486 15.5305 16.7485 15.5129 16.7485 15.4952V15.4952C16.7483 15.434 16.7481 15.3714 16.7344 15.3166C16.6613 15.0274 16.4706 14.8636 16.1624 14.8252C16.1542 14.8242 16.1484 14.8198 16.1452 14.8121C16.03 14.5473 16.0258 14.2809 16.1326 14.0128C16.136 14.0043 16.1422 14.0001 16.1513 14.0001C16.1918 13.9999 16.2347 14.0008 16.2785 14.0017C16.4266 14.0047 16.5857 14.0079 16.7013 13.9726C17.3084 13.7882 17.1767 12.903 16.5381 12.8876C16.4876 12.8864 16.4379 12.8865 16.389 12.8881L16.3842 12.887L16.3804 12.8839L16.3783 12.8794L16.3784 12.8744C16.8561 11.1371 16.8321 9.24111 16.174 7.5543C15.5528 5.96198 14.3278 4.72485 12.5546 4.5758C12.4905 4.57039 12.4208 4.57078 12.3513 4.57116C12.3236 4.57132 12.2959 4.57147 12.2686 4.57125C12.2599 4.57125 12.254 4.56713 12.251 4.55888C12.2418 4.5347 12.2336 4.50843 12.2254 4.48206C12.2091 4.42992 12.1927 4.37735 12.1684 4.33959C11.9488 3.9993 11.435 4.3694 11.2579 4.55989C11.2545 4.56355 11.2505 4.56648 11.246 4.56848C11.2414 4.57048 11.2365 4.57151 11.2316 4.57151C10.8855 4.571 10.5407 4.571 10.1973 4.57151C10.0781 4.57168 9.99362 4.57673 9.94394 4.58667C9.4796 4.67963 9.3975 5.12325 9.59632 5.4936C9.74436 5.76931 9.89964 6.04029 10.0622 6.30657C10.0644 6.3102 10.0653 6.31449 10.0648 6.31872C10.0642 6.32295 10.0622 6.32686 10.0592 6.32981C9.50621 6.84483 8.95211 7.35902 8.39683 7.87236C8.22353 8.03287 8.1154 8.14823 8.07246 8.21846C7.812 8.6444 8.07599 9.38763 8.42083 9.70039C8.89098 10.1273 9.58899 10.0561 10.0463 9.64607C10.0534 9.63945 10.0621 9.63475 10.0715 9.63243L11.5797 9.25753C11.5929 9.25433 11.5946 9.25736 11.5848 9.26662C11.529 9.31932 11.473 9.37203 11.4168 9.42484L11.4165 9.42513L11.4162 9.42543C10.3995 10.3819 9.34892 11.3702 9.24718 12.8732C9.24651 12.8831 9.2412 12.888 9.23127 12.8878C9.19034 12.8871 9.11413 12.8865 9.00264 12.8858C8.4509 12.8828 8.21317 13.6043 8.69014 13.9092C8.83148 13.9996 8.96615 13.9998 9.11905 14C9.14952 14.0001 9.18072 14.0001 9.21283 14.0009C9.22142 14.0011 9.22731 14.0051 9.23051 14.013C9.33763 14.2835 9.33249 14.552 9.2151 14.8187C9.21123 14.8274 9.20449 14.8315 9.19489 14.8308C8.82858 14.803 8.50749 15.0779 8.51279 15.4391C8.51346 15.4846 8.51355 15.5205 8.51304 15.547C8.51271 15.5561 8.50816 15.5618 8.4994 15.5642C8.25688 15.6275 8.10143 15.7733 8.03305 16.0017C8.032 16.0052 8.03098 16.0087 8.03 16.0123C8.09249 16.0607 8.15245 16.1123 8.20964 16.1667C8.2098 16.1131 8.22044 16.0599 8.24098 16.0104C8.26167 15.9604 8.29201 15.915 8.33024 15.8768C8.36848 15.8385 8.41388 15.8082 8.46384 15.7875C8.5138 15.7668 8.56734 15.7562 8.62142 15.7562H16.6399C16.694 15.7562 16.7475 15.7668 16.7975 15.7875C16.8474 15.8082 16.8928 15.8385 16.9311 15.8768C16.9693 15.915 16.9996 15.9604 17.0203 16.0104C17.041 16.0603 17.0517 16.1139 17.0517 16.1679V16.4241C17.0517 16.4782 17.041 16.5317 17.0203 16.5817C16.9996 16.6317 16.9693 16.6771 16.9311 16.7153C16.8928 16.7535 16.8474 16.7839 16.7975 16.8046C16.7475 16.8252 16.694 16.8359 16.6399 16.8359H8.69957C8.73155 16.9016 8.76054 16.969 8.78635 17.038ZM7.83922 1.77115H11.7548L9.62375 1.25624C8.95635 1.09498 8.28605 1.31271 7.83922 1.77115ZM20.213 3.82858C20.2184 3.89206 20.2211 3.95628 20.2211 4.02115V10.8184L21.3792 6.0255C21.6044 5.09311 21.09 4.15508 20.213 3.82858ZM17.286 21.8538H13.3698L15.5014 22.3689C16.1688 22.5301 16.8392 22.3124 17.286 21.8538ZM6.28251 3.13465L6.5567 3.13254C6.5663 3.13247 6.57413 3.14098 6.5742 3.15156L6.57504 3.28345C6.5751 3.29403 6.56738 3.30266 6.55778 3.30273L6.28359 3.30484C6.274 3.30491 6.26616 3.2964 6.26609 3.28583L6.26526 3.15393C6.26519 3.14336 6.27292 3.13473 6.28251 3.13465ZM7.05486 3.13465L7.32905 3.13254C7.33865 3.13247 7.34648 3.14098 7.34655 3.15156L7.34738 3.28345C7.34745 3.29403 7.33972 3.30266 7.33013 3.30273L7.05594 3.30484C7.04634 3.30491 7.03851 3.2964 7.03844 3.28583L7.0376 3.15393C7.03754 3.14336 7.04526 3.13473 7.05486 3.13465ZM8.10148 3.13254L7.82729 3.13465C7.81769 3.13473 7.80997 3.14336 7.81004 3.15393L7.81087 3.28583C7.81094 3.2964 7.81877 3.30491 7.82837 3.30484L8.10256 3.30273C8.11215 3.30266 8.11988 3.29403 8.11981 3.28345L8.11898 3.15156C8.11891 3.14098 8.11108 3.13247 8.10148 3.13254ZM8.59964 3.13465L8.87383 3.13254C8.88342 3.13247 8.89126 3.14098 8.89132 3.15156L8.89216 3.28345C8.89223 3.29403 8.8845 3.30266 8.8749 3.30273L8.60072 3.30484C8.59112 3.30491 8.58329 3.2964 8.58322 3.28583L8.58238 3.15393C8.58232 3.14336 8.59004 3.13473 8.59964 3.13465ZM9.64154 3.13258L9.37662 3.13462C9.36446 3.13471 9.35468 3.14564 9.35476 3.15904L9.35553 3.28072C9.35562 3.29412 9.36554 3.3049 9.3777 3.30481L9.64262 3.30277C9.65477 3.30267 9.66456 3.29174 9.66448 3.27835L9.6637 3.15666C9.66362 3.14327 9.6537 3.13249 9.64154 3.13258ZM10.1491 3.13462L10.414 3.13258C10.4262 3.13249 10.4361 3.14327 10.4362 3.15666L10.4369 3.27835C10.437 3.29174 10.4272 3.30267 10.4151 3.30277L10.1502 3.30481C10.138 3.3049 10.1281 3.29412 10.128 3.28072L10.1272 3.15904C10.1271 3.14564 10.1369 3.13471 10.1491 3.13462ZM11.191 3.13254L10.9168 3.13465C10.9072 3.13473 10.8995 3.14336 10.8995 3.15393L10.9004 3.28583C10.9005 3.2964 10.9083 3.30491 10.9179 3.30484L11.1921 3.30273C11.2017 3.30266 11.2094 3.29403 11.2093 3.28345L11.2085 3.15156C11.2084 3.14098 11.2006 3.13247 11.191 3.13254ZM11.6892 3.13465L11.9633 3.13254C11.9729 3.13247 11.9808 3.14098 11.9808 3.15156L11.9817 3.28345C11.9817 3.29403 11.974 3.30266 11.9644 3.30273L11.6902 3.30484C11.6806 3.30491 11.6728 3.2964 11.6727 3.28583L11.6719 3.15393C11.6718 3.14336 11.6796 3.13473 11.6892 3.13465ZM13.8096 3.13391L13.5578 3.13439C13.5405 3.13443 13.5265 3.14988 13.5266 3.16892L13.5267 3.26933C13.5268 3.28837 13.5408 3.30377 13.5581 3.30373L13.8099 3.30325C13.8271 3.30322 13.8411 3.28776 13.8411 3.26873L13.8409 3.16831C13.8409 3.14928 13.8269 3.13388 13.8096 3.13391ZM14.3302 3.13439L14.5819 3.13391C14.5992 3.13388 14.6132 3.14928 14.6133 3.16831L14.6134 3.26873C14.6135 3.28776 14.5995 3.30322 14.5822 3.30325L14.3304 3.30373C14.3131 3.30377 14.2991 3.28837 14.2991 3.26933L14.2989 3.16892C14.2989 3.14988 14.3129 3.13443 14.3302 3.13439ZM15.3551 3.13412H15.1026C15.0853 3.13412 15.0713 3.14955 15.0713 3.16859V3.269C15.0713 3.28803 15.0853 3.30346 15.1026 3.30346H15.3551C15.3724 3.30346 15.3864 3.28803 15.3864 3.269V3.16859C15.3864 3.14955 15.3724 3.13412 15.3551 3.13412ZM15.8748 3.13439L16.1266 3.13391C16.1439 3.13388 16.1579 3.14928 16.158 3.16831L16.1581 3.26873C16.1582 3.28776 16.1442 3.30322 16.1269 3.30325L15.8751 3.30373C15.8578 3.30377 15.8438 3.28837 15.8438 3.26933L15.8436 3.16892C15.8436 3.14988 15.8576 3.13443 15.8748 3.13439ZM16.8999 3.13412H16.6474C16.6301 3.13412 16.6161 3.14955 16.6161 3.16859V3.269C16.6161 3.28803 16.6301 3.30346 16.6474 3.30346H16.8999C16.9172 3.30346 16.9312 3.28803 16.9312 3.269V3.16859C16.9312 3.14955 16.9172 3.13412 16.8999 3.13412ZM17.3689 3.13268L17.6277 3.13467C17.6432 3.13479 17.6558 3.14879 17.6556 3.16594L17.655 3.27316C17.6549 3.29032 17.6422 3.30412 17.6266 3.304L17.3678 3.30201C17.3523 3.30189 17.3397 3.28789 17.3398 3.27074L17.3405 3.16352C17.3406 3.14637 17.3533 3.13256 17.3689 3.13268ZM18.4006 3.1334L18.1403 3.1339C18.1247 3.13393 18.1121 3.14786 18.1121 3.16502L18.1123 3.27309C18.1123 3.29024 18.125 3.30412 18.1405 3.30409L18.4008 3.30359C18.4164 3.30356 18.429 3.28963 18.429 3.27248L18.4288 3.16441C18.4288 3.14725 18.4161 3.13337 18.4006 3.1334ZM18.912 3.13294L19.1738 3.13445C19.1883 3.13454 19.2 3.14756 19.2 3.16354L19.1994 3.27586C19.1994 3.29184 19.1875 3.30473 19.173 3.30464L18.9112 3.30313C18.8967 3.30305 18.885 3.29003 18.8851 3.27405L18.8856 3.16172C18.8857 3.14575 18.8975 3.13286 18.912 3.13294ZM12.8848 7.43152C13.3961 8.26924 12.8785 8.91724 12.0567 9.13803C12.0217 9.14747 11.9916 9.16372 11.9665 9.18679C11.6239 9.50157 11.2867 9.82182 10.9547 10.1475C10.2074 10.8804 9.51118 11.7813 9.45131 12.8739C9.4508 12.8827 9.45501 12.8871 9.46394 12.8871H14.9842C14.9869 12.8871 14.9895 12.8862 14.9918 12.8847C14.994 12.8832 14.9956 12.881 14.9965 12.8785C15.3965 11.7287 15.4581 10.4537 15.2249 9.26334C14.9695 7.95876 14.3041 6.77014 13.1993 6.00644C13.1393 5.96498 13.0782 5.92748 13.0178 5.89037L13.0178 5.89036C12.8704 5.79974 12.7267 5.71145 12.6107 5.57344C12.3414 5.2526 12.138 4.88258 12.0004 4.46338C11.9884 4.427 11.9638 4.40831 11.9266 4.4073C11.7076 4.40149 11.4499 4.62784 11.3263 4.79028C11.149 5.02338 11.0822 5.27474 11.126 5.54438C11.1318 5.57975 11.1303 5.61487 11.1053 5.63786C10.6703 6.03837 10.2368 6.44044 9.80332 6.84252C9.32818 7.28321 8.85302 7.72392 8.37587 8.16263C8.21502 8.3105 8.14631 8.48793 8.16972 8.69492C8.20862 9.03698 8.36576 9.43538 8.65527 9.63142C9.06731 9.91032 9.60188 9.78906 9.9452 9.46898C9.95878 9.45622 9.97549 9.44718 9.9937 9.4427C10.6416 9.28759 11.2923 9.12675 11.9458 8.96018C12.2474 8.88338 12.6049 8.71665 12.7772 8.44962C12.9727 8.14672 12.8762 7.83042 12.7196 7.5399C12.7134 7.52843 12.7096 7.51581 12.7085 7.50282C12.7074 7.48982 12.709 7.47673 12.7131 7.46436C12.7173 7.45198 12.7239 7.44057 12.7326 7.43084C12.7413 7.42111 12.7519 7.41326 12.7638 7.40778L12.7807 7.39994C12.799 7.39153 12.8197 7.3901 12.8388 7.39592C12.858 7.40175 12.8744 7.41442 12.8848 7.43152ZM11.0828 4.78801C11.0889 4.77841 11.0863 4.77361 11.075 4.77361L10.1145 4.7721C9.79463 4.77159 9.60895 4.98809 9.73779 5.29681C9.84108 5.54381 9.98063 5.77696 10.1187 6.00758L10.1187 6.00765C10.1515 6.06241 10.1842 6.11703 10.2163 6.17166L10.2187 6.17422L10.2221 6.17548L10.2256 6.17519L10.2287 6.17343L10.9105 5.54362C10.913 5.54128 10.9149 5.53839 10.9161 5.53519C10.9173 5.53199 10.9177 5.52856 10.9173 5.52518C10.8845 5.2579 10.9397 5.01218 11.0828 4.78801ZM15.9788 7.60988C15.3952 6.12316 14.2581 4.93504 12.59 4.78321C12.499 4.77496 12.4221 4.77159 12.3591 4.77311C12.3495 4.77344 12.3467 4.77799 12.3508 4.78675C12.4609 5.02506 12.6015 5.24384 12.7726 5.44308C12.8531 5.53672 12.9185 5.59786 12.9687 5.62649C15.3358 6.97452 15.9765 10.023 15.3255 12.4831C15.2909 12.6135 15.2539 12.7438 15.2143 12.8742C15.2118 12.8829 15.2151 12.8873 15.2242 12.8873L16.1551 12.8871C16.1574 12.8871 16.1595 12.8863 16.1613 12.885L16.1626 12.8838L16.1634 12.8828C16.1641 12.8818 16.1647 12.8807 16.165 12.8795C16.6528 11.172 16.6338 9.27951 15.9788 7.60988ZM16.8918 13.4398C16.8918 13.3467 16.8548 13.2575 16.789 13.1917C16.7232 13.1259 16.6339 13.0889 16.5409 13.0889H8.98874C8.89568 13.0889 8.80643 13.1259 8.74062 13.1917C8.67481 13.2575 8.63784 13.3467 8.63784 13.4398V13.4469C8.63784 13.5399 8.67481 13.6292 8.74062 13.695C8.80643 13.7608 8.89568 13.7978 8.98874 13.7978H16.5409C16.6339 13.7978 16.7232 13.7608 16.789 13.695C16.8548 13.6292 16.8918 13.5399 16.8918 13.4469V13.4398ZM9.4359 14.8068C9.43085 14.8209 9.43581 14.828 9.4508 14.828H15.9239L15.9275 14.8271L15.9303 14.8247L15.9316 14.8213L15.9313 14.8176C15.8349 14.5512 15.83 14.2833 15.9166 14.0138C15.9196 14.0045 15.9163 13.9999 15.9065 13.9999H9.45712C9.44701 13.9999 9.44356 14.0047 9.44676 14.0143C9.53148 14.2797 9.52785 14.5439 9.4359 14.8068ZM8.73131 15.5541H16.529C16.5351 15.5541 16.5409 15.5516 16.5452 15.5473C16.5496 15.543 16.552 15.5372 16.552 15.5311V15.4631C16.552 15.3479 16.5048 15.2373 16.4208 15.1559C16.3368 15.0744 16.2229 15.0286 16.1041 15.0286H9.15624C9.03744 15.0286 8.92352 15.0744 8.83952 15.1559C8.75552 15.2373 8.70833 15.3479 8.70833 15.4631V15.5311C8.70833 15.5372 8.71075 15.543 8.71506 15.5473C8.71937 15.5516 8.72522 15.5541 8.73131 15.5541ZM8.87383 19.4708L8.59964 19.4729C8.59005 19.473 8.58232 19.4817 8.58239 19.4922L8.58322 19.6241C8.58329 19.6347 8.59112 19.6432 8.60072 19.6431L8.87491 19.641C8.88451 19.641 8.89223 19.6323 8.89216 19.6217L8.89133 19.4899C8.89126 19.4793 8.88343 19.4708 8.87383 19.4708ZM9.37663 19.4729L9.64154 19.4709C9.6537 19.4708 9.66362 19.4816 9.66371 19.495L9.66448 19.6166C9.66456 19.63 9.65478 19.641 9.64262 19.6411L9.3777 19.6431C9.36555 19.6432 9.35562 19.6324 9.35554 19.619L9.35477 19.4973C9.35468 19.4839 9.36447 19.473 9.37663 19.4729ZM10.4139 19.4709L10.149 19.4729C10.1369 19.473 10.1271 19.4839 10.1272 19.4973L10.1279 19.619C10.128 19.6324 10.1379 19.6432 10.1501 19.6431L10.415 19.6411C10.4272 19.641 10.437 19.63 10.4369 19.6166L10.4361 19.495C10.436 19.4816 10.4261 19.4708 10.4139 19.4709ZM10.9167 19.4729L11.1909 19.4708C11.2005 19.4708 11.2083 19.4793 11.2084 19.4899L11.2092 19.6217C11.2093 19.6323 11.2016 19.641 11.192 19.641L10.9178 19.6431C10.9082 19.6432 10.9004 19.6347 10.9003 19.6241L10.8995 19.4922C10.8994 19.4817 10.9071 19.473 10.9167 19.4729ZM11.9633 19.4708L11.6891 19.4729C11.6795 19.473 11.6718 19.4817 11.6718 19.4922L11.6727 19.6241C11.6727 19.6347 11.6806 19.6432 11.6902 19.6431L11.9643 19.641C11.9739 19.641 11.9817 19.6323 11.9816 19.6217L11.9808 19.4899C11.9807 19.4793 11.9729 19.4708 11.9633 19.4708ZM13.5577 19.4727L13.8095 19.4722C13.8268 19.4722 13.8408 19.4876 13.8409 19.5066L13.841 19.607C13.841 19.6261 13.8271 19.6415 13.8098 19.6415L13.558 19.642C13.5407 19.6421 13.5267 19.6267 13.5267 19.6076L13.5265 19.5072C13.5265 19.4882 13.5405 19.4727 13.5577 19.4727ZM14.5819 19.4722L14.3301 19.4727C14.3128 19.4727 14.2988 19.4882 14.2988 19.5072L14.299 19.6076C14.299 19.6267 14.3131 19.6421 14.3303 19.642L14.5821 19.6415C14.5994 19.6415 14.6134 19.6261 14.6134 19.607L14.6132 19.5066C14.6132 19.4876 14.5991 19.4722 14.5819 19.4722ZM15.1025 19.4724H15.3551C15.3723 19.4724 15.3864 19.4878 15.3864 19.5069V19.6073C15.3864 19.6263 15.3723 19.6418 15.3551 19.6418H15.1025C15.0852 19.6418 15.0712 19.6263 15.0712 19.6073V19.5069C15.0712 19.4878 15.0852 19.4724 15.1025 19.4724ZM16.1266 19.4722L15.8748 19.4727C15.8575 19.4727 15.8435 19.4882 15.8435 19.5072L15.8437 19.6076C15.8437 19.6267 15.8578 19.6421 15.875 19.642L16.1268 19.6415C16.1441 19.6415 16.1581 19.6261 16.1581 19.607L16.1579 19.5066C16.1579 19.4876 16.1438 19.4722 16.1266 19.4722ZM16.6473 19.4724H16.8998C16.9171 19.4724 16.9311 19.4878 16.9311 19.5069V19.6073C16.9311 19.6263 16.9171 19.6418 16.8998 19.6418H16.6473C16.63 19.6418 16.616 19.6263 16.616 19.6073V19.5069C16.616 19.4878 16.63 19.4724 16.6473 19.4724ZM17.6276 19.473L17.3688 19.471C17.3533 19.4709 17.3406 19.4847 17.3405 19.5018L17.3398 19.609C17.3397 19.6262 17.3522 19.6402 17.3678 19.6403L17.6265 19.6423C17.6421 19.6424 17.6548 19.6286 17.6549 19.6115L17.6556 19.5042C17.6557 19.4871 17.6431 19.4731 17.6276 19.473ZM18.1402 19.4722L18.4005 19.4717C18.416 19.4717 18.4287 19.4855 18.4287 19.5027L18.4289 19.6108C18.4289 19.6279 18.4163 19.6419 18.4007 19.6419L18.1405 19.6424C18.1249 19.6424 18.1122 19.6285 18.1122 19.6114L18.112 19.5033C18.112 19.4862 18.1246 19.4722 18.1402 19.4722ZM19.1738 19.4728L18.9119 19.4712C18.8974 19.4712 18.8856 19.484 18.8855 19.5L18.885 19.6123C18.8849 19.6283 18.8966 19.6413 18.9111 19.6414L19.173 19.6429C19.1875 19.643 19.1993 19.6301 19.1994 19.6142L19.1999 19.5018C19.2 19.4859 19.1883 19.4728 19.1738 19.4728Z'\n      />\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M7.20365 19.9499C7.20679 20.0009 7.20838 20.0524 7.20838 20.1042C7.20838 20.1567 7.20675 20.2088 7.20354 20.2604C8.28319 19.9924 9.08338 19.0168 9.08338 17.8542C9.08338 16.485 7.97342 15.375 6.60421 15.375C5.28748 15.375 4.21051 16.4015 4.12988 17.698C3.05021 17.966 2.25 18.9416 2.25 20.1042C2.25 21.4734 3.35996 22.5834 4.72917 22.5834C6.09838 22.5834 7.20834 21.4734 7.20834 20.1042C7.20834 18.735 6.09838 17.625 4.72917 17.625C4.62971 17.625 4.53161 17.6309 4.43521 17.6423C4.54176 16.5382 5.47218 15.675 6.60421 15.675C7.80773 15.675 8.78338 16.6507 8.78338 17.8542C8.78338 18.8498 8.11569 19.6895 7.20365 19.9499ZM7.07976 19.3139C7.69459 19.1137 8.13894 18.5359 8.13894 17.8543C8.13894 17.0067 7.45182 16.3196 6.60422 16.3196C5.82585 16.3196 5.18283 16.899 5.08297 17.6501C5.18329 17.6644 5.28168 17.6848 5.37776 17.7107C5.44889 17.0964 5.97087 16.6196 6.60422 16.6196C7.28613 16.6196 7.83894 17.1724 7.83894 17.8543C7.83894 18.4101 7.47168 18.8802 6.9666 19.035C7.00974 19.1251 7.04759 19.2182 7.07976 19.3139ZM4.72917 17.925C3.52565 17.925 2.55 18.9007 2.55 20.1042C2.55 21.3077 3.52565 22.2834 4.72917 22.2834C5.93269 22.2834 6.90834 21.3077 6.90834 20.1042C6.90834 18.9007 5.93269 17.925 4.72917 17.925ZM3.49446 20.1042C3.49446 19.4223 4.04726 18.8695 4.72918 18.8695C5.41109 18.8695 5.9639 19.4223 5.9639 20.1042C5.9639 20.7861 5.41109 21.3389 4.72918 21.3389C4.04726 21.3389 3.49446 20.7861 3.49446 20.1042ZM4.72918 18.5695C3.88158 18.5695 3.19446 19.2566 3.19446 20.1042C3.19446 20.9518 3.88158 21.6389 4.72918 21.6389C5.57678 21.6389 6.2639 20.9518 6.2639 20.1042C6.2639 19.2566 5.57678 18.5695 4.72918 18.5695Z'\n        fill='#446EFF'\n      />\n    </SvgIcon>\n  )\n}\nexport const BurnIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24'>\n      <path d=\"M3 1.86134C3 1.38563 3.38563 1 3.86134 1H20.2268C20.7025 1 21.0881 1.38563 21.0881 1.86134V14.5658C20.7144 13.8132 20.0984 13.1431 19.3654 12.5305V2.72268H4.72268V17.3654H13.7279C13.4761 17.9364 13.3361 18.5679 13.3361 19.2318C13.3361 20.5245 13.8659 21.6935 14.7202 22.5334H3.86134C3.38563 22.5334 3 22.1478 3 21.6721V1.86134Z\" />\n      <path d=\"M17.9657 23C15.8845 23 14.1974 21.3128 14.1974 19.2316C14.1974 18.1495 14.6535 17.1739 15.3841 16.4866C15.4551 16.4197 15.5371 16.3472 15.6266 16.268C16.3863 15.596 17.688 14.4446 17.4633 12.1974C20.478 14.2072 21.9853 16.217 18.9706 19.2316C19.4731 19.2316 20.2268 19.2316 21.4829 17.9904C21.6184 18.3791 21.7341 18.7968 21.7341 19.2316C21.7341 21.3128 20.0469 23 17.9657 23Z\" />\n      <path d=\"M7.73736 7.02936C8.45091 7.02936 9.02936 6.45091 9.02936 5.73736C9.02936 5.0238 8.45091 4.44535 7.73736 4.44535C7.0238 4.44535 6.44535 5.0238 6.44535 5.73736C6.44535 6.45091 7.0238 7.02936 7.73736 7.02936Z\" />\n    </SvgIcon>\n  )\n}\n\nexport const RedPacketIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24'>\n      <path fillRule=\"evenodd\" clipRule=\"evenodd\" d=\"M12.3652 8.98852C12.2048 8.92441 12.0299 8.88913 11.847 8.88913C11.6556 8.88913 11.4731 8.92772 11.3067 8.99754C11.1401 9.06722 10.9868 9.16915 10.8566 9.29938C10.5939 9.56204 10.4464 9.9183 10.4464 10.2898C10.4464 10.6612 10.5939 11.0175 10.8566 11.2802C10.9914 11.415 11.1509 11.5195 11.3244 11.5892C11.4719 11.6488 11.6317 11.6839 11.7989 11.6896C11.8149 11.6901 11.8309 11.6904 11.847 11.6904C11.866 11.6904 11.8849 11.69 11.9038 11.6892C12.059 11.683 12.2077 11.6514 12.3461 11.5985C12.5287 11.5288 12.6965 11.4211 12.8374 11.2802C13.1001 11.0175 13.2476 10.6612 13.2476 10.2898C13.2476 9.9183 13.1001 9.56204 12.8374 9.29938C12.7014 9.16342 12.5404 9.0583 12.3652 8.98852ZM14.6865 9.1512C14.2339 8.02655 13.1315 7.23049 11.847 7.23049C10.5624 7.23049 9.46005 8.02655 9.00742 9.1512C6.15177 8.05001 3.84659 5.37186 3.05803 2.17211C3.24416 1.49667 3.86247 1 4.59734 1H19.0966C19.8315 1 20.4498 1.49667 20.6359 2.17211C19.8474 5.37214 17.542 8.05007 14.6865 9.1512ZM16.0682 10.3552C17.3348 9.73688 18.4797 8.86194 19.4721 7.7548C19.923 7.25098 20.3314 6.71069 20.6931 6.13947V21.4031C20.6931 22.2849 19.978 23 19.0962 23H4.5969C3.71506 23 3 22.2849 3 21.4031V6.13947C3.36075 6.70848 3.7685 7.2503 4.22094 7.7548C5.21336 8.86148 6.35874 9.73642 7.62484 10.3552C8.02387 10.5501 8.42924 10.7165 8.83992 10.8543C9.1056 12.2724 10.353 13.349 11.847 13.349C13.341 13.349 14.5885 12.2722 14.8541 10.854C15.2644 10.7163 15.6695 10.5499 16.0682 10.3552Z\" />\n    </SvgIcon>\n  )\n}\n\nexport const BrushIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon  className='custom-size'  {...props} viewBox='0 0 24 24'>\n      <path d=\"M15.9385 4.77359C15.2252 6.23389 16.0575 5.5599 15.2252 6.90788C14.8684 7.58187 14.1551 7.58187 13.6795 7.91887C13.5606 7.91887 13.3228 8.0312 13.3228 8.0312C13.2039 8.14353 13.085 8.48053 13.085 8.48053L17.2464 10.8395C17.2464 10.8395 17.4843 10.6148 17.4843 10.5025C17.4843 10.3902 17.6031 10.1655 17.6031 10.0532C17.6031 9.37917 17.2464 8.92985 17.6031 8.14353C18.4354 6.79555 18.1976 7.91887 19.2677 6.57089C20.4566 4.88591 16.8897 2.86395 15.9385 4.77359ZM18.1976 12.0751L11.4205 8.3682C10.7071 7.91887 9.75589 8.14353 9.3992 8.81752L18.911 13.9848C19.2677 13.3108 18.911 12.5245 18.1976 12.0751ZM9.75589 12.2998L7.85353 16.2314L9.87478 17.3547L12.4905 13.8724L10.5882 17.804L12.6094 18.9273L15.3441 15.4451L13.4417 19.3767L15.5819 20.5L18.3164 14.8834L8.80472 9.71617L5 14.6587L7.14015 15.782L9.75589 12.2998Z\" />\n    </SvgIcon>\n  )\n}\n\nexport const ConnectivityIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon className='custom-size'  {...props} viewBox='0 0 24 24'>\n      <path d=\"M16.0665 13.303C15.7154 13.303 15.3936 13.4333 15.1449 13.6515L10.3559 10.7636C10.3968 10.597 10.4202 10.4242 10.4202 10.2424C10.4202 10.2182 10.4202 10.197 10.4173 10.1727L14.0332 9.03939C14.2527 9.31212 14.5832 9.48485 14.9548 9.48485C15.616 9.48485 16.1543 8.92727 16.1543 8.24242C16.1543 7.55758 15.616 7 14.9548 7C14.3346 7 13.8255 7.48485 13.7612 8.10909L10.1628 9.23939C9.82633 8.62727 9.19149 8.21212 8.46011 8.21212C7.37766 8.21212 6.5 9.12121 6.5 10.2424C6.5 11.2242 7.17287 12.0455 8.06809 12.2333L8.33723 14.7545C8.03883 14.9818 7.84574 15.3455 7.84574 15.7576C7.84574 16.4424 8.38404 17 9.04521 17C9.70638 17 10.2447 16.4424 10.2447 15.7576C10.2447 15.1455 9.81755 14.6394 9.25585 14.5333L9.00426 12.1909C9.35532 12.0848 9.66543 11.8818 9.90239 11.6121L14.6622 14.4848C14.6418 14.5818 14.633 14.6848 14.633 14.7879C14.633 15.6091 15.2737 16.2727 16.0665 16.2727C16.8593 16.2727 17.5 15.6091 17.5 14.7879C17.5 13.9667 16.8593 13.303 16.0665 13.303Z\" fill=\"#EBEEF5\"/>\n      <path d=\"M6.82853 3H17.1715L22.3465 12L17.1715 21H6.82853L1.65353 12L6.82853 3Z\" stroke=\"#EBEEF5\" stroke-width=\"2\"/>\n    </SvgIcon>\n  )\n}\n\nexport const AlertIcon2 = (props: SvgIconProps) => {\n\n  return (\n    <SvgIcon  {...props} viewBox='0 0 24 24'>\n      <path d=\"M4.51954 20V14C4.51954 9.58172 8.10126 6 12.5195 6C16.9378 6 20.5195 9.58172 20.5195 14V20H21.5195V22H3.51954V20H4.51954ZM6.51954 20H18.5195V14C18.5195 10.6863 15.8332 8 12.5195 8C9.20583 8 6.51954 10.6863 6.51954 14V20ZM11.5195 2H13.5195V5H11.5195V2ZM20.2977 4.80761L21.7119 6.22183L19.5906 8.34315L18.1764 6.92893L20.2977 4.80761ZM3.32715 6.22183L4.74136 4.80761L6.86268 6.92893L5.44847 8.34315L3.32715 6.22183ZM7.51954 14C7.51954 11.2386 9.75811 9 12.5195 9V11C10.8627 11 9.51954 12.3431 9.51954 14H7.51954Z\" fill={props.color}/>\n    </SvgIcon>\n  )\n}\n\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/svg/dropdownLogo.tsx",
    "content": "import { SvgIcon, SvgIconProps } from '@mui/material'\n\nexport const OverviewIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M10.7192 14.1656V10.178C10.8006 8.73345 11.4306 6.61046 13.0425 4.97629C14.5201 3.47828 16.8921 2.32025 20.6334 2.55528C20.2154 3.92425 19.4506 5.6386 18.3029 7.06562C16.917 8.78877 15.0351 10.0274 12.5548 9.86567L12.4572 11.3625C15.5782 11.566 17.8904 9.97194 19.4718 8.0057C21.043 6.05205 21.9537 3.66687 22.3192 2.05312L22.5041 1.23716L21.6728 1.14227C17.0319 0.612481 13.9304 1.94001 11.9746 3.92294C10.0489 5.87528 9.3125 8.38298 9.22024 10.1176L9.21918 10.1375V10.1574V12.3753C8.66447 11.9056 8.00751 11.4276 7.27742 11.0133C5.82373 10.1883 4.00391 9.57343 2.09049 9.87312L1.45654 9.97241V10.6141C1.45654 12.5882 2.74071 16.6854 7.76999 17.4937L8.00801 16.0127C4.48488 15.4464 3.27338 12.9377 3.01374 11.2968C4.23859 11.2792 5.45165 11.7019 6.53707 12.3179C7.69508 12.975 8.6463 13.8183 9.21918 14.4478V21.1782H2.20654V22.6782H9.96918H17.7318V21.1782H10.7192V14.1656ZM17.1959 15.6623C17.1959 16.1088 16.8339 16.4708 16.3874 16.4708C15.9408 16.4708 15.5789 16.1088 15.5789 15.6623C15.5789 15.2158 15.9408 14.8538 16.3874 14.8538C16.8339 14.8538 17.1959 15.2158 17.1959 15.6623ZM18.6959 15.6623C18.6959 16.9373 17.6623 17.9708 16.3874 17.9708C15.1124 17.9708 14.0789 16.9373 14.0789 15.6623C14.0789 14.3874 15.1124 13.3538 16.3874 13.3538C17.6623 13.3538 18.6959 14.3874 18.6959 15.6623Z'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const DualInvestIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M24.0039 9C24.0039 12.6949 21.7773 15.8698 18.5926 17.256C17.41 21.1563 13.7865 23.9953 9.5 23.9953C4.25329 23.9953 0 19.742 0 14.4953C0 10.2036 2.84588 6.57656 6.75345 5.39839C8.14262 2.22062 11.3139 0 15.0039 0C19.9744 0 24.0039 4.02944 24.0039 9ZM22.5039 9C22.5039 11.6901 21.0876 14.0494 18.96 15.3729C18.9865 15.0839 19 14.7912 19 14.4953C19 9.24861 14.7467 4.99532 9.5 4.99532C9.20913 4.99532 8.9213 5.00839 8.63709 5.03398C9.96179 2.91189 12.3179 1.5 15.0039 1.5C19.146 1.5 22.5039 4.85786 22.5039 9ZM9.5 22.4953C13.9183 22.4953 17.5 18.9136 17.5 14.4953C17.5 10.077 13.9183 6.49532 9.5 6.49532C5.08172 6.49532 1.5 10.077 1.5 14.4953C1.5 18.9136 5.08172 22.4953 9.5 22.4953ZM9.5 13.0915L10.9038 14.4953L9.5 15.8991L8.09619 14.4953L9.5 13.0915ZM9.5 10.9702L10.5607 12.0308L11.9645 13.4347L13.0251 14.4953L11.9645 15.556L10.5607 16.9598L9.5 18.0204L8.43934 16.9598L7.03553 15.556L5.97487 14.4953L7.03553 13.4347L8.43934 12.0308L9.5 10.9702Z'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const ETHStakingIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M12 22.5C17.799 22.5 22.5 17.799 22.5 12C22.5 6.20101 17.799 1.5 12 1.5C6.20101 1.5 1.5 6.20101 1.5 12C1.5 17.799 6.20101 22.5 12 22.5ZM12 24C18.6274 24 24 18.6274 24 12C24 5.37258 18.6274 0 12 0C5.37258 0 0 5.37258 0 12C0 18.6274 5.37258 24 12 24ZM12.3751 3.92177L18.1588 12.3749L12.3751 20.8281L6.59131 12.3749L12.3751 3.92177ZM9.66707 14.2139L12.3751 18.1718L15.0831 14.2138L12.375 15.8804L9.66707 14.2139ZM8.74421 11.8847L12.3751 6.57812L16.0059 11.8847L12.375 14.1191L8.74421 11.8847Z'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const LeverageETHIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M1.83712 11.7851L21.8902 6.41192L22.1629 7.42964L2.10982 12.8028L1.83712 11.7851ZM0 10.7245L1.44889 10.3362L21.502 4.96303L22.9508 4.5748L23.3391 6.02369L23.6118 7.04141L24 8.4903L22.5511 8.87853L14.571 11.0168C16.3534 11.5378 17.6554 13.1844 17.6554 15.1351C17.6554 17.5045 15.7346 19.4252 13.3653 19.4252C10.9959 19.4252 9.0752 17.5045 9.0752 15.1351C9.0752 13.9853 9.52754 12.9411 10.264 12.1709L2.49804 14.2517L1.04916 14.64L0.660927 13.1911L0.388229 12.1733L0 10.7245ZM16.1554 15.1351C16.1554 16.676 14.9062 17.9252 13.3653 17.9252C11.8244 17.9252 10.5752 16.676 10.5752 15.1351C10.5752 13.5942 11.8244 12.345 13.3653 12.345C14.9062 12.345 16.1554 13.5942 16.1554 15.1351Z'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const AmmIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M22.4934 12.375C22.296 18.0003 17.6735 22.5 12 22.5C6.20101 22.5 1.5 17.799 1.5 12C1.5 6.45319 5.80104 1.91094 11.25 1.52637V8.32501C9.53831 8.67247 8.25 10.1858 8.25 12C8.25 14.0711 9.92893 15.75 12 15.75C13.9445 15.75 15.5433 14.27 15.7315 12.375L22.4934 12.375ZM22.4404 10.875H15.5783C15.1736 9.58631 14.0919 8.5974 12.75 8.32501V1.52637C17.8256 1.88458 21.9052 5.85025 22.4404 10.875ZM24 12C24 18.6274 18.6274 24 12 24C5.37258 24 0 18.6274 0 12C0 5.37258 5.37258 0 12 0C18.6274 0 24 5.37258 24 12ZM14.25 12C14.25 13.2426 13.2426 14.25 12 14.25C10.7574 14.25 9.75 13.2426 9.75 12C9.75 10.7574 10.7574 9.75 12 9.75C13.2426 9.75 14.25 10.7574 14.25 12Z'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const LRCStakingIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M22.5 12C22.5 17.799 17.799 22.5 12 22.5C6.20101 22.5 1.5 17.799 1.5 12C1.5 6.20101 6.20101 1.5 12 1.5C17.799 1.5 22.5 6.20101 22.5 12ZM24 12C24 18.6274 18.6274 24 12 24C5.37258 24 0 18.6274 0 12C0 5.37258 5.37258 0 12 0C18.6274 0 24 5.37258 24 12ZM5 14.3164L10.3861 5V19L5 14.3164ZM21 11.6957L10.3861 19L15.4554 14.2826L14.1881 11.6957H21ZM8.88614 10.5915V15.7079L6.91775 13.9962L8.88614 10.5915Z'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const SwapIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M12 22.5C17.799 22.5 22.5 17.799 22.5 12C22.5 6.20101 17.799 1.5 12 1.5C6.20101 1.5 1.5 6.20101 1.5 12C1.5 17.799 6.20101 22.5 12 22.5ZM12 24C18.6274 24 24 18.6274 24 12C24 5.37258 18.6274 0 12 0C5.37258 0 0 5.37258 0 12C0 18.6274 5.37258 24 12 24ZM5.43997 8.29678L5.98826 7.78504L8.48826 5.45171L9 4.97409L9.51174 5.45171L12.0117 7.78504L12.56 8.29678L11.5366 9.39336L10.9883 8.88162L9.75 7.72591L9.75 13V13.75H8.25V13L8.25 7.72591L7.01174 8.88162L6.46345 9.39336L5.43997 8.29678ZM18.0117 16.215L18.56 15.7032L17.5366 14.6066L16.9883 15.1184L15.75 16.2741V11V10.25H14.25V11V16.2741L13.0117 15.1184L12.4634 14.6066L11.44 15.7032L11.9883 16.215L14.4883 18.5483L15 19.0259L15.5117 18.5483L18.0117 16.215Z'\n      />\n    </SvgIcon>\n  )\n}\nexport const OrderBookIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M7.25 3.5V6H8.75V3.5H15.25V6H16.75V3.5H19.5V21.5H4.5V3.5H7.25ZM7.25 2H4.5H3V3.5V21.5V23H4.5H19.5H21V21.5V3.5V2H19.5H16.75V0H15.25V2H8.75V0H7.25V2ZM7 9.75H17V8.25H7V9.75ZM7 13.75H17V12.25H7V13.75Z'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const StopLimitIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M0.0688477 1.81459H1.56885V5.78024C3.58068 2.32358 7.3257 0 11.6134 0C17.7073 0 22.705 4.69342 23.1888 10.6626H21.683C21.2037 5.52299 16.8784 1.5 11.6134 1.5C7.60545 1.5 4.142 3.83139 2.50523 7.212H6.96626V8.712L0.0688477 8.71201V1.81459ZM18.6373 10.6626V12.0837C18.9904 12.1156 19.3182 12.172 19.6209 12.253C20.1205 12.3822 20.5421 12.5762 20.8856 12.8348C21.2353 13.0934 21.5007 13.4101 21.6818 13.7851C21.8692 14.16 21.9629 14.5932 21.9629 15.0845H20.2392C20.2392 14.7957 20.1892 14.5307 20.0893 14.2893C19.9894 14.048 19.8395 13.839 19.6396 13.6623C19.4398 13.4812 19.1962 13.3433 18.9089 13.2485C18.6217 13.1494 18.2907 13.0998 17.916 13.0998C17.3914 13.0998 16.9573 13.1623 16.6138 13.2873C16.2766 13.4123 16.0268 13.589 15.8644 13.8174C15.702 14.0415 15.6208 14.3023 15.6208 14.5996C15.6208 14.8755 15.702 15.1168 15.8644 15.3237C16.0268 15.5306 16.3016 15.718 16.6888 15.8861C17.0822 16.0499 17.6224 16.2115 18.3094 16.371C19.115 16.5477 19.7989 16.7567 20.361 16.998C20.923 17.2351 21.3508 17.5281 21.6444 17.8772C21.9379 18.222 22.0846 18.6509 22.0846 19.1637C22.0846 19.7197 21.9035 20.1894 21.5413 20.573C21.1791 20.9523 20.6701 21.241 20.0144 21.4393C19.5544 21.5783 19.0392 21.6686 18.4687 21.7101V22.9456H17.0729V21.7127C16.7584 21.6888 16.4461 21.6473 16.1361 21.588C15.6177 21.4889 15.1493 21.3272 14.7309 21.1031C14.3125 20.8747 13.9784 20.5752 13.7285 20.2045C13.4787 19.8296 13.3538 19.3706 13.3538 18.8276H15.0962C15.0962 19.1939 15.1712 19.4977 15.3211 19.7391C15.4772 19.9761 15.6833 20.1657 15.9393 20.308C16.1954 20.4459 16.4764 20.545 16.7825 20.6053C17.0947 20.6614 17.4039 20.6894 17.7099 20.6894C18.2719 20.6894 18.7466 20.629 19.1338 20.5084C19.5272 20.3834 19.827 20.2067 20.0331 19.9783C20.2392 19.7498 20.3422 19.4826 20.3422 19.1766C20.3422 18.9181 20.2579 18.6853 20.0893 18.4785C19.9207 18.2716 19.6428 18.082 19.2556 17.9096C18.8684 17.7372 18.35 17.5777 17.7005 17.4312C16.9136 17.2631 16.2329 17.0584 15.6583 16.817C15.09 16.5757 14.6497 16.2762 14.3375 15.9184C14.0314 15.5607 13.8784 15.1276 13.8784 14.619C13.8784 14.0889 14.0439 13.6321 14.3749 13.2485C14.7059 12.8649 15.1743 12.5697 15.7801 12.3629C16.2105 12.2159 16.6945 12.1211 17.2321 12.0786V10.6626H18.6373ZM1.50006 11.5194C1.50006 17.0598 5.95472 21.6541 11.478 21.7266V23.2267C5.12627 23.1542 0 17.8883 0 11.5194H1.50006Z'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const BlockTradeIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M12 22.5C14.3797 22.5 16.5744 21.7084 18.3353 20.3741C18.2479 20.3707 18.1604 20.3617 18.073 20.3461C17.6872 20.2771 17.3276 20.0973 16.9746 19.9207C16.9174 19.8921 16.86 19.8635 16.8031 19.8355C16.5676 19.7197 16.3052 19.6402 16.0474 19.7138C15.905 19.7542 15.7743 19.805 15.6552 19.866C15.3926 20.0004 15.1513 20.1137 14.9313 20.2059C14.3547 20.448 13.7716 20.4266 13.1819 20.1418C12.8788 19.9954 12.6181 19.8732 12.4001 19.7752C12.1879 19.6799 11.9844 19.6594 11.7897 19.7138C11.6332 19.7575 11.4716 19.8226 11.3049 19.909C10.7256 20.2101 10.1573 20.4716 9.49959 20.3367C9.26856 20.2893 9.03669 20.2066 8.804 20.0887C8.54468 19.9574 8.31057 19.8481 8.1017 19.7609C7.8914 19.6731 7.68559 19.6613 7.48426 19.7256C7.26565 19.7953 7.05266 19.9011 6.83954 20.007C6.71445 20.0691 6.58932 20.1313 6.46298 20.1862C6.20214 20.2993 5.93509 20.3613 5.66182 20.372C7.4232 21.7075 9.61905 22.5 12 22.5ZM19.2258 19.1325C19.5003 19.0128 19.7576 18.9032 19.9977 18.8038C21.5582 16.9712 22.5 14.5956 22.5 12C22.5 6.20101 17.799 1.5 12 1.5C6.20101 1.5 1.5 6.20101 1.5 12C1.5 14.5925 2.43958 16.9656 3.99679 18.7973C4.15418 18.8601 4.31045 18.9283 4.46479 18.9957C4.61073 19.0594 4.75495 19.1224 4.89675 19.1793C5.12272 19.2698 5.38617 19.3392 5.62699 19.334C5.81795 19.3295 6.02801 19.2452 6.20023 19.1588C6.42962 19.0442 6.65087 18.9388 6.86399 18.8429C7.46092 18.574 8.05961 18.5806 8.66008 18.8627C8.8864 18.969 9.10895 19.0751 9.32773 19.181C9.64105 19.333 9.92466 19.393 10.2578 19.248C10.4938 19.1451 10.7455 19.0262 11.0131 18.8914C11.1765 18.8094 11.3671 18.7429 11.5849 18.692C12.285 18.5289 12.8605 18.8183 13.4574 19.1185L13.5211 19.1505C13.7329 19.2567 13.9928 19.3614 14.2301 19.3267C14.3822 19.3043 14.5551 19.2443 14.7489 19.1467L14.8145 19.1136C15.2517 18.8929 15.6872 18.673 16.1779 18.6466C16.5496 18.6268 16.935 18.7381 17.2653 18.8998C17.5103 19.0198 17.7427 19.1303 17.9627 19.2313C18.1777 19.3303 18.4053 19.3571 18.6455 19.3118C18.8438 19.2743 19.0372 19.2146 19.2258 19.1325ZM12 24C18.6274 24 24 18.6274 24 12C24 5.37258 18.6274 0 12 0C5.37258 0 0 5.37258 0 12C0 18.6274 5.37258 24 12 24ZM10.4701 15.7711C10.4701 15.0659 10.1011 14.4194 9.46533 14.1013C9.29272 14.015 9.10215 13.9653 8.91286 13.9159C6.82109 13.4127 5.32268 12.0581 4.54241 10.2362C4.41281 9.93357 4.3064 9.61998 4.22319 9.29543C4.18319 9.13945 4.14856 8.98095 4.11928 8.81991C4.06034 8.49574 4.0231 8.16123 4.00757 7.81656C4.00373 7.73126 4.00122 7.64534 4.00004 7.55879C3.99988 7.5466 4.00022 7.53478 4.00102 7.52336C4.02629 7.16349 4.51302 7.18306 4.51701 7.51719C4.51701 7.51719 4.5245 7.52983 4.54121 7.55176C4.61143 7.64381 4.84752 7.90403 5.4154 8.14088C5.4773 8.1667 5.54314 8.19224 5.61314 8.21725C5.96979 8.3447 6.43437 8.45849 7.03528 8.52583C7.03528 8.52583 8.19537 8.72419 9.22618 8.91566C9.41581 8.95088 9.96381 9.05268 10.5595 9.31377L10.5646 9.316C10.7193 9.38402 10.8772 9.46279 11.0327 9.55394C11.1956 9.64932 11.3559 9.75825 11.5074 9.88259C11.5074 9.88259 11.5556 9.9242 11.614 9.97722C11.667 10.0254 11.7283 10.083 11.7696 10.1273C11.7841 10.143 11.7961 10.157 11.8044 10.1683C11.8044 10.1683 11.8215 10.2124 11.8407 10.213C11.8599 10.2124 11.8768 10.1686 11.8768 10.1686C11.8852 10.157 11.8977 10.1425 11.9128 10.1264C11.9547 10.0814 12.0169 10.0231 12.0701 9.97481C12.1272 9.92294 12.1739 9.88259 12.1739 9.88259C12.3245 9.75904 12.4837 9.65071 12.6454 9.55577C12.802 9.46383 12.961 9.38444 13.1167 9.31596L13.1218 9.31373C13.7174 9.05266 14.2653 8.95088 14.4549 8.91566C15.4856 8.72419 16.6456 8.52583 16.6456 8.52583C17.2463 8.4585 17.7108 8.34473 18.0674 8.21731C18.1374 8.19229 18.2033 8.16675 18.2652 8.14093C18.8331 7.90407 19.0695 7.64346 19.1397 7.5514C19.1564 7.52947 19.1636 7.51719 19.1636 7.51719C19.1676 7.18306 19.6543 7.16349 19.6795 7.52336C19.6803 7.53478 19.6807 7.54659 19.6805 7.55879C19.6793 7.64532 19.6768 7.73132 19.673 7.81659C19.6575 8.16129 19.6202 8.49573 19.5613 8.81992C19.532 8.98097 19.4974 9.13949 19.4574 9.29549C19.3742 9.62002 19.2678 9.93359 19.1382 10.2362C18.358 12.0581 16.8598 13.4127 14.7682 13.9159C14.5789 13.9653 14.3884 14.015 14.2158 14.1013C13.5801 14.4194 13.2111 15.0659 13.2111 15.7711C13.2111 15.9305 13.2749 16.2612 13.3651 16.6488C13.5176 17.3045 13.7456 18.123 13.8677 18.55C13.8054 18.5244 13.7339 18.4901 13.6525 18.4509C13.3169 18.2897 12.8122 18.0472 12.0896 18.0029C12.0095 17.9979 11.9269 17.9955 11.8414 17.9958C11.7548 17.9979 11.671 18.0024 11.5899 18.0091C10.8562 18.0697 10.3466 18.3059 10.0113 18.4613C9.93698 18.4958 9.87121 18.5263 9.81346 18.55C9.93461 18.1264 10.16 17.3174 10.3125 16.6643C10.4046 16.2701 10.4701 15.9327 10.4701 15.7711ZM9.27958 12.3913C7.82852 12.0422 6.77771 11.1766 6.15411 9.97873C6.36102 10.0179 6.58054 10.0516 6.81341 10.0787L6.96552 10.1049C7.0893 10.1263 7.26519 10.1569 7.47309 10.1934C7.88957 10.2665 8.43163 10.3629 8.93981 10.4573C9.06543 10.4807 9.32957 10.5301 9.64379 10.6385C9.96023 10.7476 10.2642 10.8955 10.4971 11.0821L10.5077 11.0914C10.526 11.1076 10.5499 11.1289 10.5738 11.1509L10.5777 11.1544C10.6179 11.2068 10.6682 11.2658 10.7293 11.3256C10.8385 11.4327 11.2026 11.7624 11.7931 11.7804L11.8407 11.7818L11.8883 11.7804C12.4764 11.7625 12.8399 11.4354 12.951 11.3266C13.0125 11.2665 13.0631 11.2072 13.1036 11.1545L13.1077 11.1507C13.1317 11.1287 13.1556 11.1074 13.1739 11.0912L13.1844 11.0819C13.4172 10.8954 13.7211 10.7475 14.0374 10.6385C14.3516 10.5301 14.6157 10.4807 14.7413 10.4573C15.2494 10.3629 15.7914 10.2665 16.2079 10.1934C16.4158 10.1569 16.5916 10.1263 16.7154 10.1049L16.8675 10.0787C17.1002 10.0516 17.3197 10.0179 17.5265 9.97876C16.903 11.1766 15.8523 12.0423 14.4014 12.3913L14.3868 12.3948L14.3722 12.3986L14.3416 12.4066C14.1702 12.451 13.8378 12.5372 13.514 12.699C12.6914 13.1107 12.1204 13.8069 11.8406 14.6059C11.5607 13.8069 10.9891 13.1104 10.1664 12.6987C9.84265 12.5369 9.51087 12.451 9.33946 12.4066L9.30881 12.3986L9.29423 12.3948L9.27958 12.3913ZM10.6258 11.2C10.6378 11.212 10.6358 11.2108 10.6247 11.199L10.6258 11.2Z'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const FiatIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M21.5 5.5H2.5V8H21.5V5.5ZM1 8V10V18.5V20H2.5H21.5H23V18.5V10V8V5.5V4H21.5H2.5H1V5.5V8ZM21.5 18.5V10H2.5V18.5H21.5ZM5 14.75H12V13.25H5V14.75ZM5 17.25H9V15.75H5V17.25Z'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const MyNFTIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M6.73245 20.0118L11.9763 23.0394L21.9527 17.2795V5.75985L11.9763 0L2 5.75985V17.2795L6.61669 19.945L6.69218 20.0429L6.73245 20.0118ZM3.5 6.62587L11.9763 1.73205L20.4527 6.62587V15.0423L14.997 11.7445L6.61221 18.2103L3.5 16.4135V6.62587ZM8.01688 19.0213L15.0998 13.5594L20.1298 16.5999L11.9763 21.3073L8.01688 19.0213ZM11.1017 9.55246C11.1017 10.7029 10.1692 11.6355 9.01874 11.6355C7.86832 11.6355 6.93573 10.7029 6.93573 9.55246C6.93573 8.40205 7.86832 7.46945 9.01874 7.46945C10.1692 7.46945 11.1017 8.40205 11.1017 9.55246Z'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const CreateNFTIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M1 0H16.4803L17.9362 1.4559H17.944L21.1 4.6201L22.6 6.11965V24H1V0ZM21.1 7.22989H15.5018V1.5H2.5V22.5H21.1V7.22989ZM11.0271 12.847H7.0188V11.347H11.0271V7.33867H12.5271V11.347H16.5355V12.847H12.5271V16.8553H11.0271V12.847Z'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const MyCollectionIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M11.5225 1.74919L3.91586 6.27555L11.7933 11.0394L19.3999 6.51305L11.5225 1.74919ZM11.5287 0L1.00001 6.26515L11.787 12.7886L22.3158 6.52344L11.5287 0ZM2.43738 10.3865L1 11.2418L11.787 17.7653L22.3158 11.5001L20.8784 10.6309L11.787 16.0407L2.43738 10.3865ZM1 16.4851L2.43738 15.6298L11.787 21.2839L20.8784 15.8741L22.3158 16.7434L11.787 23.0085L1 16.4851Z'\n      />\n    </SvgIcon>\n  )\n}\nexport const VaultHomeIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M11.5225 1.74919L3.91586 6.27555L11.7933 11.0394L19.3999 6.51305L11.5225 1.74919ZM11.5287 0L1.00001 6.26515L11.787 12.7886L22.3158 6.52344L11.5287 0ZM2.43738 10.3865L1 11.2418L11.787 17.7653L22.3158 11.5001L20.8784 10.6309L11.787 16.0407L2.43738 10.3865ZM1 16.4851L2.43738 15.6298L11.787 21.2839L20.8784 15.8741L22.3158 16.7434L11.787 23.0085L1 16.4851Z'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const VaultDashboardIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M22.5 12C22.5 17.799 17.799 22.5 12 22.5C6.20101 22.5 1.5 17.799 1.5 12C1.5 6.20101 6.20101 1.5 12 1.5C17.799 1.5 22.5 6.20101 22.5 12ZM24 12C24 18.6274 18.6274 24 12 24C5.37258 24 0 18.6274 0 12C0 5.37258 5.37258 0 12 0C18.6274 0 24 5.37258 24 12ZM6 7H8.72727L11.0455 11.7368L9.68182 14.7368L6 7ZM10.6364 16.6316L11.7273 19H12.2727L18 7H15.2727L10.6364 16.6316Z'\n      />\n    </SvgIcon>\n  )\n}\n\n\nexport const VaultTradeIcon2 = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24'>\n      <path d=\"M16.166 2.83398L19.4993 6.16732L16.166 9.50065\" stroke=\"black\" stroke-width=\"1.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n      <path d=\"M4.5 11.166V9.49935C4.5 8.61529 4.85119 7.76745 5.47631 7.14233C6.10143 6.5172 6.94928 6.16602 7.83333 6.16602H19.5\" stroke=\"black\" stroke-width=\"1.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n      <path d=\"M7.83333 21.1667L4.5 17.8333L7.83333 14.5\" stroke=\"black\" stroke-width=\"1.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n      <path d=\"M19.5 12.834V14.5007C19.5 15.3847 19.1488 16.2326 18.5237 16.8577C17.8986 17.4828 17.0507 17.834 16.1667 17.834H4.5\" stroke=\"black\" stroke-width=\"1.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n    </SvgIcon>\n  )\n}\n\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/svg/earnLogo.tsx",
    "content": "import { styled } from '@mui/material'\nimport { SvgIcon, SvgIconProps } from '@mui/material'\n\nconst LargeSvgIcon = styled(SvgIcon)`\n  && {\n    width: 240px;\n    height: 240px;\n  }\n`\n\nexport const Overview = (props: SvgIconProps) => {\n  return (\n    <LargeSvgIcon {...props} viewBox='0 0 240 240' aria-hidden='true'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M99.4783 118.69C124.023 112.08 138.562 86.8249 131.953 62.2803C125.343 37.7357 100.088 23.1964 75.5429 29.806C50.9983 36.4156 36.4591 61.671 43.0686 86.2157C46.4764 98.8703 54.8405 108.865 65.5083 114.673C68.0682 113.934 70.7585 113.857 73.2661 114.184C77.8151 114.779 81.9558 116.732 83.8403 118.734C84.1267 119.039 84.5688 119.546 85.1406 120.225C89.8505 120.466 94.678 119.983 99.4783 118.69ZM86.4295 121.773C90.8579 121.872 95.3746 121.348 99.8683 120.138C105.015 118.752 109.735 116.573 113.933 113.766C113.835 113.978 113.747 114.197 113.67 114.421L109.912 125.402L92.1323 128.82C89.9055 126.039 87.93 123.594 86.4295 121.773ZM111.609 125.076L131.591 121.234C133.999 120.771 136.468 121.65 138.042 123.53L202.078 200.04L218.584 98.6971C218.943 96.494 217.025 94.5932 214.825 94.9717L119.166 111.433C117.275 111.758 115.711 113.091 115.09 114.907L111.609 125.076ZM203.35 201.56L203.565 201.817C204.431 202.852 203.85 204.436 202.52 204.665L100.343 222.252C98.8824 222.503 97.388 222.058 96.3026 221.049L17.3752 147.647C15.7267 146.114 16.518 143.357 18.7288 142.932L59.1504 135.161L59.0778 135.078C59.0652 135.064 59.0532 135.049 59.0417 135.034C57.8361 133.43 56.4236 130.679 56.0787 127.58C55.7301 124.449 56.4761 120.952 59.6135 118C60.8469 116.839 62.2101 115.971 63.6428 115.345C53.1772 109.267 45.0158 99.2151 41.6202 86.6057C34.7953 61.2611 49.8083 35.1826 75.1529 28.3576C100.497 21.5326 126.576 36.5457 133.401 61.8903C138.265 79.9518 132.038 98.3862 118.885 109.959C118.894 109.958 118.903 109.956 118.912 109.955L214.571 93.4934C217.786 92.9402 220.589 95.7182 220.064 98.9382L203.356 201.525C203.354 201.536 203.352 201.548 203.35 201.56ZM19.012 144.405L60.298 136.468L64.3653 141.099L62.0181 141.551L62.2069 142.533L65.1303 141.971L83.2147 162.564C83.3946 162.769 83.6715 162.86 83.938 162.802L112.667 156.539C112.919 156.484 113.125 156.303 113.212 156.06C113.3 155.818 113.256 155.547 113.097 155.344C109.124 150.27 103.164 142.692 97.6318 135.722L98.2246 135.608L98.0358 134.626L96.9304 134.839L96.3047 134.051C95.2381 132.71 94.1941 131.399 93.1912 130.144L131.875 122.707C133.747 122.347 135.668 123.031 136.892 124.493L202.415 202.78C202.539 202.928 202.456 203.154 202.266 203.187L100.089 220.773C99.0892 220.945 98.0668 220.641 97.3241 219.95L18.3967 146.548C17.6474 145.851 18.0071 144.599 19.012 144.405ZM123.069 64.6715C128.357 84.3107 116.724 104.519 97.0844 109.807C77.4452 115.096 57.2372 103.462 51.9486 83.8232C46.66 64.184 58.2935 43.976 77.9327 38.6874C97.5719 33.3988 117.78 45.0322 123.069 64.6715ZM124.517 64.2814C130.021 84.7206 117.914 105.752 97.4744 111.256C77.0353 116.76 56.0042 104.652 50.5002 84.2132C44.9962 63.7741 57.1035 42.743 77.5426 37.2389C97.9818 31.7349 119.013 43.8423 124.517 64.2814ZM86.528 66.607L81.7361 48.812L73.8802 77.2182L73.886 77.2144L73.8797 77.2197L90.2489 80.4276L87.1246 68.8255L90.249 80.4261L102.793 69.433L102.795 69.4331L102.794 69.4321L81.7366 48.8131L86.528 66.607ZM91.0387 83.3608L74.4349 79.2813L94.7885 97.2861L103.349 71.4958L91.0387 83.3608ZM73.0717 115.672C68.7649 115.109 64.0945 115.842 60.6416 119.092C57.9039 121.669 57.2639 124.67 57.5694 127.414C57.8771 130.178 59.1474 132.669 60.2241 134.11L84.0502 161.242L111.179 155.328C106.891 149.857 100.686 141.973 95.1306 134.985C89.2318 127.565 84.1026 121.202 82.748 119.762C81.1767 118.093 77.4061 116.238 73.0717 115.672ZM67.9452 125.602C66.3279 127.348 66.6549 130.645 69.1697 132.974C71.6845 135.303 74.9967 135.377 76.6141 133.631C78.2314 131.885 77.9043 128.588 75.3896 126.259C72.8748 123.93 69.5625 123.856 67.9452 125.602ZM68.1504 134.074C65.2697 131.406 64.464 127.153 66.8448 124.582C69.2255 122.012 73.5282 122.49 76.4089 125.159C79.2896 127.827 80.0953 132.08 77.7145 134.651C75.3337 137.221 71.0311 136.743 68.1504 134.074ZM128.051 128.856C128.625 128.745 129.203 128.714 129.771 128.757L129.695 129.754C129.215 129.718 128.726 129.744 128.239 129.838L126.238 130.222L126.05 129.24L128.051 128.856ZM132.99 129.903C133.458 130.229 133.887 130.618 134.262 131.067L135.532 132.584L134.765 133.226L133.495 131.709C133.177 131.329 132.815 130.999 132.419 130.724L132.99 129.903ZM118.046 130.779L122.048 130.01L122.236 130.992L118.234 131.761L118.046 130.779ZM110.042 132.318L114.044 131.548L114.232 132.53L110.23 133.3L110.042 132.318ZM102.038 133.857L106.04 133.087L106.229 134.069L102.227 134.839L102.038 133.857ZM138.072 135.619L140.613 138.654L139.846 139.296L137.306 136.261L138.072 135.619ZM143.153 141.689L145.693 144.724L144.926 145.366L142.386 142.331L143.153 141.689ZM54.0142 143.089L58.0161 142.32L58.2049 143.302L54.203 144.071L54.0142 143.089ZM46.0102 144.628L50.0122 143.859L50.201 144.841L46.199 145.61L46.0102 144.628ZM38.0063 146.167L42.0083 145.398L42.1971 146.38L38.1951 147.149L38.0063 146.167ZM32.0034 147.321L34.0043 146.936L34.1931 147.918L32.1922 148.303C31.8958 148.36 31.6515 148.491 31.4613 148.665L30.7852 147.929C31.1101 147.63 31.5225 147.414 32.0034 147.321ZM148.233 147.759L150.773 150.794L150.006 151.436L147.466 148.401L148.233 147.759ZM30.7729 151.607C30.4143 151.273 30.1797 150.871 30.0625 150.446L31.0265 150.18C31.0951 150.429 31.2329 150.669 31.4539 150.875L32.9829 152.297L32.3019 153.029L30.7729 151.607ZM153.313 153.829L155.854 156.864L155.087 157.506L152.547 154.471L153.313 153.829ZM38.4182 158.717L35.3601 155.873L36.0411 155.141L39.0992 157.985L38.4182 158.717ZM158.394 159.899L160.934 162.934L160.167 163.576L157.627 160.541L158.394 159.899ZM44.5345 164.405L41.4764 161.561L42.1574 160.829L45.2155 163.673L44.5345 164.405ZM163.474 165.969L166.014 169.004L165.247 169.646L162.707 166.611L163.474 165.969ZM50.6508 170.093L47.5926 167.249L48.2736 166.517L51.3318 169.361L50.6508 170.093ZM168.554 172.039L171.095 175.074L170.328 175.716L167.788 172.681L168.554 172.039ZM56.7671 175.781L53.7089 172.937L54.3899 172.205L57.4481 175.049L56.7671 175.781ZM62.8834 181.469L59.8252 178.625L60.5062 177.893L63.5644 180.737L62.8834 181.469ZM173.635 178.109L176.175 181.144L175.408 181.786L172.868 178.751L173.635 178.109ZM68.9996 187.158L65.9415 184.314L66.6225 183.581L69.6806 186.425L68.9996 187.158ZM178.715 184.179L181.255 187.214L180.488 187.856L177.948 184.821L178.715 184.179ZM75.1159 192.846L72.0578 190.002L72.7388 189.269L75.7969 192.113L75.1159 192.846ZM183.795 190.249L186.336 193.284L185.569 193.926L183.029 190.891L183.795 190.249ZM81.2322 198.534L78.1741 195.69L78.8551 194.958L81.9132 197.802L81.2322 198.534ZM188.876 196.319L190.146 197.836C190.888 198.723 190.39 200.081 189.25 200.277L187.264 200.619L187.095 199.634L189.08 199.292C189.46 199.227 189.626 198.774 189.379 198.478L188.109 196.961L188.876 196.319ZM183.293 201.303L179.322 201.986L179.152 201.001L183.123 200.317L183.293 201.303ZM87.3485 204.222L84.2904 201.378L84.9714 200.646L88.0295 203.49L87.3485 204.222ZM175.35 202.67L171.379 203.353L171.209 202.368L175.181 201.684L175.35 202.67ZM167.408 204.037L163.436 204.721L163.267 203.735L167.238 203.052L167.408 204.037ZM159.465 205.404L155.493 206.088L155.324 205.102L159.295 204.419L159.465 205.404ZM151.522 206.771L147.551 207.455L147.381 206.469L151.352 205.786L151.522 206.771ZM93.4648 209.91L90.4066 207.066L91.0876 206.334L94.1458 209.178L93.4648 209.91ZM143.579 208.138L139.608 208.822L139.438 207.836L143.41 207.153L143.579 208.138ZM135.637 209.505L131.665 210.189L131.496 209.204L135.467 208.52L135.637 209.505ZM127.694 210.873L123.722 211.556L123.553 210.571L127.524 209.887L127.694 210.873ZM119.751 212.24L115.78 212.923L115.61 211.938L119.581 211.254L119.751 212.24ZM98.052 214.176L96.5229 212.754L97.2039 212.022L98.733 213.444C99.5328 214.188 100.634 214.515 101.71 214.33L103.696 213.988L103.866 214.974L101.88 215.316C100.496 215.554 99.0802 215.132 98.052 214.176ZM111.808 213.607L107.837 214.29L107.667 213.305L111.639 212.621L111.808 213.607Z'\n        fill={props.color}\n      />\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M204.507 111.333C204.783 109.506 203.214 107.932 201.387 108.202L127.945 119.039C125.655 119.377 123.721 120.858 122.783 122.927L124.742 122.551C125.558 121.472 126.777 120.728 128.164 120.523L201.605 109.686C202.436 109.563 203.149 110.278 203.024 111.109L191.51 187.414L192.795 188.949L204.507 111.333ZM181.081 74.8317C181.081 80.8954 176.165 85.8111 170.101 85.8111C164.038 85.8111 159.122 80.8954 159.122 74.8317C159.122 68.7679 164.038 63.8523 170.101 63.8523C176.165 63.8523 181.081 68.7679 181.081 74.8317ZM182.581 74.8317C182.581 81.7239 176.994 87.3111 170.101 87.3111C163.209 87.3111 157.622 81.7239 157.622 74.8317C157.622 67.9395 163.209 62.3523 170.101 62.3523C176.994 62.3523 182.581 67.9395 182.581 74.8317ZM38.4591 199.626C38.4591 203.72 35.1398 207.04 31.0452 207.04C26.9506 207.04 23.6313 203.72 23.6313 199.626C23.6313 195.531 26.9506 192.212 31.0452 192.212C35.1398 192.212 38.4591 195.531 38.4591 199.626ZM39.9591 199.626C39.9591 204.549 35.9682 208.54 31.0452 208.54C26.1222 208.54 22.1313 204.549 22.1313 199.626C22.1313 194.703 26.1222 190.712 31.0452 190.712C35.9682 190.712 39.9591 194.703 39.9591 199.626Z'\n        fill='#446EFF'\n      />\n    </LargeSvgIcon>\n  )\n}\n\nexport const AmmLogo = (props: SvgIconProps) => {\n  return (\n    <LargeSvgIcon {...props} viewBox='0 0 240 240' aria-hidden='true'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M190.476 37.0633C191.166 36.4438 192.211 36.4778 192.866 37.1215L222.98 66.7584C223.673 67.4401 223.678 68.5558 222.99 69.2431L209.253 82.9801C209.197 83.0367 209.134 83.0924 209.061 83.1458C207.954 83.9591 206.063 84.8981 203.856 85.1642C201.626 85.4329 199.061 85.0137 196.698 83.0805C195.293 81.9314 193.257 79.9895 190.976 77.7023L152.706 115.972L165.508 128.774C166.183 129.45 166.192 130.542 165.529 131.228L153.908 143.249C153.207 143.236 152.506 143.243 151.804 143.268L164.45 130.186C164.545 130.088 164.544 129.932 164.447 129.835L151.645 117.033L145.963 122.716C143.543 125.135 139.621 125.135 137.201 122.716C134.782 120.296 134.782 116.374 137.201 113.954L142.884 108.272L129.85 95.2374C129.751 95.1389 129.605 95.1438 129.515 95.2359C128.005 96.7896 123.776 101.149 114.211 111.022C108.288 117.137 106.087 125.092 105.786 132.675C105.674 135.511 105.829 138.286 106.15 140.876C105.617 140.605 105.083 140.345 104.55 140.098C104.297 137.711 104.186 135.189 104.288 132.616C104.597 124.802 106.871 116.443 113.134 109.978C122.698 100.105 126.929 95.7451 128.44 94.1904C129.12 93.4904 130.228 93.4943 130.91 94.1768L143.944 107.211L182.389 68.7662C180.184 66.4084 178.178 64.2244 176.707 62.6026C176.6 62.485 176.51 62.3547 176.437 62.2035C175.82 60.9183 175.168 58.8254 175.133 56.5242C175.098 54.2132 175.686 51.6418 177.615 49.4983C180.99 45.749 187.21 39.9951 190.476 37.0633ZM113.556 144.851C112.929 144.592 112.302 144.303 111.677 143.984C110.918 141.471 110.603 138.402 110.516 135.51C110.414 132.089 110.631 128.831 110.864 126.865C110.913 126.453 111.286 126.159 111.698 126.208C112.109 126.257 112.403 126.63 112.354 127.041C112.129 128.941 111.916 132.125 112.016 135.465C112.116 138.824 112.53 142.256 113.513 144.701C113.533 144.751 113.547 144.801 113.556 144.851ZM191.813 38.1907C191.717 38.096 191.572 38.0958 191.478 38.1796C188.209 41.1137 182.045 46.8191 178.73 50.5017C177.12 52.2906 176.602 54.457 176.633 56.5013C176.664 58.5557 177.252 60.436 177.79 61.5541C177.796 61.5669 177.802 61.5777 177.818 61.5949C182.709 66.988 193.328 78.3852 197.648 81.9195C199.645 83.5533 201.783 83.9031 203.676 83.6749C205.591 83.4441 207.243 82.6202 208.173 81.9369C208.175 81.9352 208.179 81.9328 208.183 81.9285C208.186 81.9261 208.189 81.9231 208.193 81.9194L221.93 68.1825C222.028 68.0843 222.027 67.9249 221.928 67.8275L191.813 38.1907ZM189.976 48.0632C190.663 47.4435 191.708 47.4749 192.363 48.1164L211.643 67.0114C212.326 67.6809 212.345 68.7748 211.685 69.4677L206.269 75.1581C206.204 75.2268 206.128 75.2959 206.039 75.3603C204.57 76.4167 200.882 77.9127 197.656 75.2837C194.745 72.9122 187.75 65.4308 184.555 61.924C184.448 61.8066 184.355 61.6731 184.281 61.5173C183.867 60.6394 183.439 59.2413 183.423 57.7065C183.407 56.1615 183.81 54.4307 185.118 52.9834C187.2 50.6798 188.374 49.5067 189.976 48.0632ZM191.313 49.1876C191.218 49.0944 191.072 49.0944 190.98 49.1774C189.424 50.5793 188.287 51.7144 186.231 53.9891C185.24 55.0854 184.91 56.4142 184.923 57.691C184.936 58.9777 185.301 60.1634 185.638 60.8769C185.642 60.8859 185.648 60.8965 185.664 60.9139C188.889 64.4547 195.799 71.8363 198.603 74.1208C201.049 76.1138 203.921 75.0354 205.163 74.1426L205.164 74.1413C205.164 74.1413 205.168 74.1386 205.171 74.136C205.174 74.1332 205.178 74.1293 205.183 74.124L210.599 68.4336C210.693 68.3346 210.69 68.1783 210.593 68.0827L191.313 49.1876ZM138.262 115.015L183.028 70.2486L189.668 76.8886L144.902 121.655C143.068 123.488 140.095 123.488 138.262 121.655C136.428 119.821 136.428 116.848 138.262 115.015ZM206.5 121.5C208.709 121.5 210.5 119.709 210.5 117.5C210.5 115.291 208.709 113.5 206.5 113.5C204.291 113.5 202.5 115.291 202.5 117.5C202.5 119.709 204.291 121.5 206.5 121.5ZM206.5 123C209.538 123 212 120.538 212 117.5C212 114.462 209.538 112 206.5 112C203.462 112 201 114.462 201 117.5C201 120.538 203.462 123 206.5 123ZM187.5 143.5C193.023 143.5 197.5 139.023 197.5 133.5C197.5 127.977 193.023 123.5 187.5 123.5C181.977 123.5 177.5 127.977 177.5 133.5C177.5 139.023 181.977 143.5 187.5 143.5ZM187.5 145C193.851 145 199 139.851 199 133.5C199 127.149 193.851 122 187.5 122C181.149 122 176 127.149 176 133.5C176 139.851 181.149 145 187.5 145ZM97.75 152.25H74.25V162.25H52.25V176.25H30.25V184.25H8.25V213.75H30.25H31.75H52.25H53.75H74.25H75.75H96.25H97.75H118.25H119.75H140.25H141.75H162.25H163.75H184.25H185.75H206.25H207.75H229.75V180.25H207.75V176.25H185.75V170.25H162.25V177.25H141.75V166.25H119.75V156.25H97.75V152.25ZM207.75 181.75V212.25H228.25V181.75H207.75ZM206.25 180.25V177.75H185.75V200.5H186.679V202H185.75V212.25H206.25V202H201.607V200.5H206.25V180.25ZM184.25 176.25V200.5H181.702V202H184.25V212.25H163.75V202H166.774V200.5H163.75V177.25V171.75H184.25V176.25ZM162.25 212.25V202H161.798V200.5H162.25V178.75H141.75V212.25H162.25ZM140.25 177.25V212.25H119.75V167.75H140.25V177.25ZM118.25 166.25V157.75H97.75V212.25H118.25V166.25ZM96.25 153.75V156.25V200.5H92.1309V202H96.25V212.25H75.75V202H77.2024V200.5H75.75V162.25V153.75H96.25ZM72.2262 200.5H74.25V163.75H53.75V176.25V200.5H57.2976V202H53.75V212.25H74.25V202H72.2262V200.5ZM52.25 177.75V212.25H31.75V184.25V177.75H52.25ZM30.25 212.25V185.75H9.75V212.25H30.25ZM17.4881 202H15V200.5H17.4881V202ZM27.4405 202H22.4643V200.5H27.4405V202ZM37.3929 202H32.4167V200.5H37.3929V202ZM47.3452 202H42.369V200.5H47.3452V202ZM67.25 202H62.2738V200.5H67.25V202ZM87.1547 202H82.1786V200.5H87.1547V202ZM107.06 202H102.083V200.5H107.06V202ZM117.012 202H112.036V200.5H117.012V202ZM126.964 202H121.988V200.5H126.964V202ZM136.917 202H131.94V200.5H136.917V202ZM146.869 202H141.893V200.5H146.869V202ZM156.821 202H151.845V200.5H156.821V202ZM176.726 202H171.75V200.5H176.726V202ZM196.631 202H191.655V200.5H196.631V202ZM216.536 202H211.56V200.5H216.536V202ZM224 202H221.512V200.5H224V202ZM79.8101 79.73L79.8103 79.7116C80.0334 64.1965 67.2743 51.5719 51.8595 51.4991C36.1841 51.4264 23.5137 64.032 23.5 79.5143C23.4863 95.1883 36.0906 107.854 51.708 107.809C67.3629 107.759 79.965 95.0418 79.8102 79.7484L79.8101 79.73ZM51.7127 109.309C35.2564 109.357 21.9856 96.0096 22 79.513C22.0144 63.1935 35.3669 49.9226 51.8665 49.9991C68.0922 50.0757 81.5456 63.361 81.3102 79.7332C81.4735 95.8756 68.1835 109.257 51.7127 109.309Z'\n        fill={props.color}\n      />\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M27.5552 76C29.0808 65.5479 37.5569 57.2494 48.3099 55.7316V57.2472C38.3689 58.7403 30.5764 66.3951 29.0728 76H27.5552ZM27.5814 83C29.1753 93.4892 37.6122 101.755 48.3099 103.243V101.728C38.432 100.264 30.6698 92.6489 29.1003 83H27.5814ZM74.5649 83C73.1097 92.5307 65.2917 100.231 55.3099 101.722V103.237C66.0993 101.722 74.6071 93.3804 76.0818 83H74.5649ZM76.0866 76C74.6116 65.4997 65.9981 57.2067 55.3099 55.7206V57.2356C65.1983 58.6988 73.1142 66.3563 74.5699 76H76.0866ZM52.9999 71.8284V94H50.9999V71.8284L45.6359 77.1924L44.2217 75.7782L51.9999 68L59.778 75.7782L58.3638 77.1924L52.9999 71.8284ZM59.8732 149.833C67.2953 143.153 75.2728 139.107 83.5261 138.042C91.7719 136.978 100.363 138.88 109.039 144.22C118.393 149.976 127.991 148.596 137.266 146.875C137.856 146.765 138.444 146.654 139.03 146.544L139.035 146.543C147.757 144.901 156.139 143.323 164.221 146.915C173.352 150.974 186.456 153.725 196.548 154.986C207.186 156.316 218.046 156.287 228.914 156.259H228.914C230.495 156.254 232.076 156.25 233.657 156.25C234.071 156.25 234.407 155.914 234.407 155.5C234.407 155.086 234.071 154.75 233.657 154.75C232.07 154.75 230.485 154.754 228.903 154.758H228.903C218.026 154.787 207.27 154.815 196.734 153.498C186.704 152.244 173.766 149.516 164.83 145.544C156.303 141.754 147.47 143.423 138.851 145.051C138.231 145.168 137.611 145.285 136.993 145.4C127.705 147.124 118.642 148.368 109.825 142.942C100.895 137.447 91.9633 135.44 83.3342 136.554C74.7126 137.666 66.4629 141.884 58.8698 148.718C52.1357 154.779 43.3844 156.91 34.0357 157.501C29.3649 157.796 24.5696 157.706 19.8285 157.54C18.6371 157.499 17.4479 157.452 16.265 157.406H16.2648C12.7534 157.269 9.29704 157.134 6 157.134C5.58579 157.134 5.25 157.47 5.25 157.884C5.25 158.298 5.58579 158.634 6 158.634C9.26515 158.634 12.6792 158.767 16.1824 158.904C17.3708 158.951 18.5695 158.997 19.7762 159.04C24.5269 159.206 29.3828 159.298 34.1303 158.998C43.6182 158.398 52.772 156.224 59.8732 149.833Z'\n        fill='#446EFF'\n      />\n    </LargeSvgIcon>\n  )\n}\n\nexport const SatkingLogo = (props: SvgIconProps) => {\n  return (\n    <LargeSvgIcon {...props} viewBox='0 0 240 240' aria-hidden='true'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M144.75 30C144.75 29.5858 144.414 29.25 144 29.25C143.586 29.25 143.25 29.5858 143.25 30V45C143.25 45.4142 143.586 45.75 144 45.75C144.414 45.75 144.75 45.4142 144.75 45V30ZM132.75 33.5C132.75 33.0858 132.414 32.75 132 32.75C131.586 32.75 131.25 33.0858 131.25 33.5V45C131.25 45.4142 131.586 45.75 132 45.75C132.414 45.75 132.75 45.4142 132.75 45V33.5ZM112.25 39C112.25 38.5858 111.914 38.25 111.5 38.25C111.086 38.25 110.75 38.5858 110.75 39V56.5C110.75 56.9142 111.086 57.25 111.5 57.25C111.914 57.25 112.25 56.9142 112.25 56.5V39ZM100.25 41.5C100.25 41.0858 99.9142 40.75 99.5 40.75C99.0858 40.75 98.75 41.0858 98.75 41.5V56.5C98.75 56.9142 99.0858 57.25 99.5 57.25C99.9142 57.25 100.25 56.9142 100.25 56.5V41.5ZM194.25 75.5C194.25 75.0858 194.586 74.75 195 74.75H206C206.335 74.75 206.629 74.972 206.721 75.294L209.721 85.794C209.835 86.1922 209.604 86.6073 209.206 86.7211C208.808 86.8349 208.393 86.6043 208.279 86.206L205.69 77.1446L183.212 106.647C182.62 107.424 181.507 107.566 180.739 106.963L168.27 97.1662C168.167 97.0851 168.019 97.0977 167.93 97.1952L149.865 117.175C149.953 117.603 150 118.046 150 118.5C150 121.202 148.351 123.519 146.004 124.5C148.351 125.481 150 127.798 150 130.5C150 133.202 148.351 135.519 146.004 136.5C148.351 137.481 150 139.798 150 142.5C150 144.392 149.191 146.096 147.901 147.283C153.367 154.571 158.75 162.792 158.75 176C158.75 189.508 152.869 197.985 145.487 203.056C138.145 208.099 129.362 209.75 123.5 209.75C117.689 209.75 108.406 208.743 100.551 204.018C92.6388 199.258 86.25 190.764 86.25 176C86.25 175.435 86.2579 174.88 86.2733 174.334L73.6811 161.742C73.5831 161.644 73.4239 161.644 73.3265 161.743L33.5336 202.027C33.2425 202.322 32.7676 202.325 32.4729 202.034C32.1782 201.742 32.1753 201.268 32.4664 200.973L72.2593 160.689C72.9415 159.998 74.0554 159.995 74.7418 160.681L86.3678 172.307C87.0237 162.276 90.3331 155.616 94.1268 150.061C94.6289 150.105 95.1372 149.93 95.5071 149.564C106.999 138.208 108.939 127.704 108.349 123.042C108.33 122.895 108.39 122.783 108.465 122.729L108.748 122.525C108.749 122.683 108.75 122.842 108.75 123C108.75 133.209 104.107 139.279 99.282 145.587L99.2812 145.588L99.2793 145.59L99.279 145.591C98.8858 146.105 98.4913 146.62 98.0981 147.14C92.8923 154.019 87.75 161.735 87.75 176C87.75 190.236 93.8612 198.242 101.324 202.732C108.844 207.257 117.811 208.25 123.5 208.25C129.138 208.25 137.605 206.651 144.638 201.819C151.631 197.015 157.25 188.992 157.25 176C157.25 163.275 152.099 155.379 146.688 148.166C145.746 148.697 144.658 149 143.5 149H131.5C127.91 149 125 146.09 125 142.5C125 139.798 126.649 137.481 128.996 136.5C126.649 135.519 125 133.202 125 130.5C125 127.798 126.649 125.481 128.996 124.5C126.649 123.519 125 121.202 125 118.5C125 118.223 125.017 117.95 125.051 117.682C125.09 117.701 125.129 117.721 125.168 117.74C125.604 117.955 126.05 118.159 126.502 118.347C126.501 118.398 126.5 118.449 126.5 118.5C126.5 121.261 128.739 123.5 131.5 123.5H143.5C146.261 123.5 148.5 121.261 148.5 118.5C148.5 115.739 146.261 113.5 143.5 113.5H137.791C137.827 112.966 137.809 112.424 137.745 111.881C137.73 111.754 137.712 111.627 137.692 111.5H143.5C146.261 111.5 148.5 109.261 148.5 106.5C148.5 103.739 146.261 101.5 143.5 101.5H132.394C131.945 100.966 131.498 100.468 131.068 100.014C131.211 100.005 131.355 100 131.5 100H139.182C141.881 92.6555 145.288 86.2486 147.843 82.1758C147.963 81.983 147.815 81.75 147.619 81.75H97.4432C97.3414 81.75 97.2559 81.802 97.2033 81.9003C97.1497 82.0004 97.151 82.1121 97.2109 82.2067C99.2583 85.4389 101.88 90.512 104.106 96.8325L102.892 97.9077C100.667 91.4413 98.0024 86.2594 95.9438 83.0094C95.2052 81.8434 96.0146 80.25 97.4432 80.25H147.619C149.026 80.25 149.844 81.8084 149.113 82.9729C146.643 86.9113 143.396 93.016 140.781 100H143.5C147.09 100 150 102.91 150 106.5C150 109.202 148.351 111.519 146.004 112.5C147.433 113.097 148.603 114.19 149.3 115.563L166.818 96.1891C167.435 95.507 168.474 95.4186 169.197 95.9868L181.665 105.783C181.775 105.869 181.934 105.849 182.019 105.738L204.486 76.25H195C194.586 76.25 194.25 75.9142 194.25 75.5ZM131.5 125.5H143.5C146.261 125.5 148.5 127.739 148.5 130.5C148.5 133.261 146.261 135.5 143.5 135.5H131.5C128.739 135.5 126.5 133.261 126.5 130.5C126.5 127.739 128.739 125.5 131.5 125.5ZM131.5 137.5H143.5C146.261 137.5 148.5 139.739 148.5 142.5C148.5 145.261 146.261 147.5 143.5 147.5H131.5C128.739 147.5 126.5 145.261 126.5 142.5C126.5 139.739 128.739 137.5 131.5 137.5ZM109.32 94.375C109.237 94.3509 109.148 94.3708 109.084 94.4278L92.2811 109.31C91.9611 109.594 91.5483 109.75 91.1208 109.75H32C31.5858 109.75 31.25 109.414 31.25 109C31.25 108.586 31.5858 108.25 32 108.25H91.1208C91.1819 108.25 91.2409 108.228 91.2866 108.187L108.089 93.3049C108.54 92.9059 109.163 92.7664 109.741 92.9354L129.477 98.7119C129.744 98.7901 129.993 98.9318 130.198 99.1312C130.88 99.7943 131.64 100.604 132.409 101.517C134.762 104.312 137.311 108.211 137.745 111.881C137.953 113.645 137.677 115.395 136.617 116.927C135.289 118.845 133.358 119.537 131.307 119.494C129.293 119.453 127.131 118.708 125.168 117.74C123.267 116.802 121.496 115.626 120.142 114.574C120.036 114.492 119.901 114.496 119.812 114.56L108.465 122.729C108.39 122.783 108.33 122.895 108.349 123.042C108.939 127.704 106.999 138.208 95.5071 149.564C95.004 150.061 94.2446 150.207 93.5932 149.927L87.3932 147.27C87.3621 147.257 87.3286 147.25 87.2947 147.25H32C31.5858 147.25 31.25 146.914 31.25 146.5C31.25 146.086 31.5858 145.75 32 145.75H87.2947C87.5317 145.75 87.7663 145.798 87.9841 145.892L94.1841 148.549C94.2734 148.587 94.3826 148.567 94.4527 148.497C105.69 137.392 107.38 127.33 106.861 123.23C106.78 122.594 107.023 121.919 107.589 121.512L118.936 113.342C119.585 112.875 120.45 112.915 121.062 113.39C122.352 114.391 124.037 115.51 125.832 116.395C127.706 117.32 129.639 117.959 131.338 117.995C133.001 118.029 134.402 117.491 135.383 116.073C136.189 114.909 136.431 113.547 136.255 112.057C135.876 108.846 133.576 105.232 131.261 102.483C130.524 101.608 129.797 100.834 129.152 100.206C129.128 100.183 129.095 100.163 129.056 100.151L109.32 94.375Z'\n        fill={props.color}\n      />\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M120.459 158L105 182.594L120.459 194.949V158ZM120.816 194.687L151.353 176.066V175.949H131.795L135.953 182.566L120.816 194.687ZM133.656 185.687L147.984 176.949H133.604L137.274 182.789L133.656 185.687ZM119.459 192.869V161.47L106.322 182.37L119.459 192.869ZM112.595 79.25C112.253 79.6085 111.886 79.9427 111.496 80.25H113.714C115.751 78.0995 117 75.1956 117 72C117 65.3726 111.627 60 105 60C98.3726 60 93 65.3726 93 72C93 75.3213 94.3493 78.3275 96.5297 80.5003C96.6822 80.4079 96.8517 80.3377 97.0354 80.2955C97.1646 80.2658 97.3008 80.25 97.4432 80.25H98.5041C98.129 79.9542 97.7745 79.6334 97.4432 79.2901C97.4304 79.2768 97.4177 79.2635 97.405 79.2502C95.6052 77.3655 94.5 74.8118 94.5 72C94.5 66.201 99.201 61.5 105 61.5C110.799 61.5 115.5 66.201 115.5 72C115.5 74.8117 114.395 77.3652 112.595 79.25ZM138 70.5C143.799 70.5 148.5 65.799 148.5 60C148.5 54.201 143.799 49.5 138 49.5C132.201 49.5 127.5 54.201 127.5 60C127.5 65.799 132.201 70.5 138 70.5ZM138 72C144.627 72 150 66.6274 150 60C150 53.3726 144.627 48 138 48C131.373 48 126 53.3726 126 60C126 66.6274 131.373 72 138 72Z'\n        fill='#446EFF'\n      />\n    </LargeSvgIcon>\n  )\n}\n\nexport const DualInvestmentLogo = (props: SvgIconProps) => {\n  return (\n    <LargeSvgIcon {...props} viewBox='0 0 240 240' aria-hidden='true'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M93.8103 66.7116L93.8101 66.73L93.8102 66.7484C93.965 82.0418 81.3629 94.7593 65.708 94.8093C50.0906 94.8545 37.4863 82.1883 37.5 66.5143C37.5137 51.032 50.1841 38.4264 65.8595 38.4991C81.2743 38.5719 94.0334 51.1965 93.8103 66.7116ZM36 66.513C35.9856 83.0096 49.2564 96.3571 65.7127 96.3093C82.1835 96.2566 95.4735 82.8756 95.3102 66.7332C95.5456 50.361 82.0922 37.0757 65.8665 36.9991C49.3669 36.9226 36.0144 50.1935 36 66.513ZM41.3101 66.3687C41.3209 54.371 50.4246 44.4093 62.3101 42.7316V44.2472C51.2308 45.9113 42.8201 55.229 42.8101 66.3701C42.8 77.6909 51.2222 87.0847 62.3101 88.7281V90.2435C50.4046 88.5871 41.2992 78.5363 41.3101 66.3687ZM88.8076 66.5624C88.922 77.6301 80.4679 87.0552 69.3101 88.7216V90.237C81.273 88.5573 90.4309 78.4852 90.3075 66.5469C90.4857 54.4108 81.1766 44.3705 69.3101 42.7206V44.2356C80.3768 45.8731 88.9729 55.2692 88.8077 66.5249L88.8074 66.5436L88.8076 66.5624ZM203.5 66.73L203.5 66.7116C203.723 51.1965 190.964 38.5719 175.549 38.4991C159.874 38.4264 147.204 51.032 147.19 66.5143C147.176 82.1883 159.781 94.8545 175.398 94.8093C191.053 94.7593 203.655 82.0418 203.5 66.7484L203.5 66.73ZM175.403 96.3093C158.946 96.3571 145.676 83.0096 145.69 66.513C145.704 50.1935 159.057 36.9226 175.556 36.9991C191.782 37.0757 205.236 50.361 205 66.7332C205.163 82.8756 191.873 96.2566 175.403 96.3093ZM151 66.3687C151.011 54.371 160.115 44.4093 172 42.7316V44.2472C160.921 45.9113 152.51 55.229 152.5 66.3701C152.49 77.6909 160.912 87.0847 172 88.7281V90.2435C160.095 88.5871 150.989 78.5363 151 66.3687ZM198.498 66.5624C198.612 77.6301 190.158 87.0552 179 88.7216V90.237C190.963 88.5573 200.121 78.4852 199.997 66.5469C199.998 66.4995 199.999 66.4521 199.999 66.4048C200.103 54.3325 190.82 44.3641 179 42.7206V44.2356C180.383 44.4403 181.728 44.7662 183.022 45.2018C192.079 48.2512 198.642 56.6761 198.498 66.5249L198.497 66.5436L198.498 66.5624ZM40.9312 106.707H90.3103C90.5864 106.707 90.8103 106.931 90.8103 107.207V118.034C90.8103 118.31 90.5864 118.534 90.3103 118.534H40.9312C40.655 118.534 40.4312 118.31 40.4312 118.034V107.207C40.4312 106.931 40.655 106.707 40.9312 106.707ZM38.9312 107.207C38.9312 106.102 39.8266 105.207 40.9312 105.207H90.3103C91.4149 105.207 92.3103 106.102 92.3103 107.207V118.034C92.3103 119.139 91.4149 120.034 90.3103 120.034H40.9312C39.8266 120.034 38.9312 119.139 38.9312 118.034V107.207ZM39.6812 187.276C39.6812 186.585 40.2408 186.026 40.9312 186.026H86.3516L86.3714 186.026C86.3825 186.026 86.3936 186.026 86.4047 186.026H107.138C107.552 186.026 107.888 185.69 107.888 185.276C107.888 184.861 107.552 184.526 107.138 184.526H87.5517L108.373 139.481C111.682 142.156 115.895 143.758 120.482 143.758C125.468 143.758 130.012 141.865 133.435 138.758L154.888 184.526H133.827C133.413 184.526 133.077 184.861 133.077 185.276C133.077 185.69 133.413 186.026 133.827 186.026H156.042C156.06 186.026 156.077 186.026 156.095 186.026H203C203.69 186.026 204.25 186.585 204.25 187.276V201.069C204.25 201.759 203.69 202.319 203 202.319H40.9312C40.2408 202.319 39.6812 201.759 39.6812 201.069V187.276ZM156.545 184.526H203C204.518 184.526 205.75 185.757 205.75 187.276V201.069C205.75 202.588 204.518 203.819 203 203.819H40.9312C39.4124 203.819 38.1812 202.588 38.1812 201.069V187.276C38.1812 185.757 39.4124 184.526 40.9312 184.526H85.8992L107.197 138.449C105.466 136.802 104.041 134.837 103.016 132.647H66.6211C65.6546 132.647 64.8711 131.863 64.8711 130.897V120.035H66.3711V130.897C66.3711 131.035 66.483 131.147 66.6211 131.147H102.39C101.624 129.07 101.207 126.825 101.207 124.482C101.207 113.837 109.837 105.207 120.482 105.207C131.128 105.207 139.758 113.837 139.758 124.482C139.758 126.825 139.34 129.07 138.575 131.147H174.345C174.483 131.147 174.595 131.035 174.595 130.897V120.035H176.095V130.897C176.095 131.863 175.311 132.647 174.345 132.647H137.949C137.086 134.489 135.94 136.173 134.568 137.642L156.545 184.526ZM200.033 106.707H150.654C150.378 106.707 150.154 106.931 150.154 107.207V118.034C150.154 118.31 150.378 118.534 150.654 118.534H200.033C200.31 118.534 200.533 118.31 200.533 118.034V107.207C200.533 106.931 200.31 106.707 200.033 106.707ZM150.654 105.207C149.55 105.207 148.654 106.102 148.654 107.207V118.034C148.654 119.139 149.55 120.034 150.654 120.034H200.033C201.138 120.034 202.033 119.139 202.033 118.034V107.207C202.033 106.102 201.138 105.207 200.033 105.207H150.654ZM138.258 124.482C138.258 134.3 130.3 142.258 120.482 142.258C110.665 142.258 102.707 134.3 102.707 124.482C102.707 114.665 110.665 106.707 120.482 106.707C130.3 106.707 138.258 114.665 138.258 124.482ZM130.773 125.837L129.286 125.643C129.335 125.264 129.361 124.876 129.361 124.482C129.361 124.087 129.335 123.699 129.286 123.32L130.773 123.126C130.831 123.57 130.861 124.022 130.861 124.482C130.861 124.941 130.831 125.394 130.773 125.837ZM130.074 120.509L128.688 121.083C128.389 120.362 127.997 119.688 127.527 119.077L128.717 118.163C129.266 118.877 129.724 119.665 130.074 120.509ZM126.801 116.247L125.887 117.436C125.275 116.966 124.601 116.574 123.88 116.275L124.455 114.89C125.299 115.24 126.086 115.698 126.801 116.247ZM121.837 114.19L121.643 115.677C121.264 115.628 120.876 115.602 120.482 115.602C120.087 115.602 119.7 115.628 119.32 115.677L119.126 114.19C119.57 114.132 120.022 114.102 120.482 114.102C120.941 114.102 121.394 114.132 121.837 114.19ZM116.509 114.89L117.083 116.275C116.362 116.574 115.689 116.966 115.077 117.436L114.163 116.247C114.877 115.698 115.665 115.24 116.509 114.89ZM112.247 118.163L113.436 119.077C112.966 119.688 112.575 120.362 112.276 121.083L110.89 120.509C111.24 119.665 111.698 118.877 112.247 118.163ZM110.19 123.126C110.132 123.57 110.103 124.022 110.103 124.482C110.103 124.941 110.132 125.394 110.19 125.837L111.678 125.643C111.628 125.264 111.603 124.876 111.603 124.482C111.603 124.087 111.628 123.699 111.678 123.32L110.19 123.126ZM110.89 128.455L112.276 127.88C112.575 128.601 112.966 129.275 113.436 129.886L112.247 130.8C111.698 130.086 111.24 129.298 110.89 128.455ZM114.163 132.716L115.077 131.527C115.689 131.997 116.362 132.389 117.083 132.688L116.509 134.073C115.665 133.723 114.877 133.265 114.163 132.716ZM119.126 134.773L119.32 133.286C119.7 133.335 120.087 133.361 120.482 133.361C120.876 133.361 121.264 133.335 121.643 133.286L121.837 134.773C121.394 134.831 120.941 134.861 120.482 134.861C120.022 134.861 119.57 134.831 119.126 134.773ZM124.455 134.073L123.88 132.688C124.601 132.389 125.275 131.997 125.887 131.527L126.801 132.716C126.086 133.265 125.299 133.723 124.455 134.073ZM128.717 130.8L127.527 129.886C127.997 129.275 128.389 128.601 128.688 127.88L130.074 128.455C129.724 129.298 129.266 130.086 128.717 130.8Z'\n        fill={props.color}\n      />\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M177.766 50.6094V51.6094V54.1784C178.094 54.2567 178.414 54.3533 178.723 54.4688C179.727 54.8394 180.599 55.3907 181.323 56.127C182.049 56.8659 182.59 57.7647 182.957 58.8018C183.337 59.8382 183.516 60.9983 183.516 62.2656V63.2656H182.516H178.766H177.766V62.2656C177.766 61.6752 177.696 61.1811 177.574 60.7717L177.57 60.7604L177.567 60.7491C177.451 60.3258 177.287 60.0063 177.094 59.7653L177.086 59.7546L177.086 59.7546C176.887 59.499 176.655 59.3134 176.384 59.1845L176.375 59.1803C176.124 59.0582 175.814 58.9844 175.422 58.9844C174.803 58.9844 174.383 59.1026 174.1 59.2687L174.093 59.2728L174.086 59.2768C173.781 59.4491 173.575 59.6714 173.437 59.9549C173.289 60.2821 173.203 60.6811 173.203 61.1719C173.203 61.6357 173.292 61.9953 173.437 62.2789C173.566 62.5308 173.814 62.8163 174.261 63.1127C174.741 63.4135 175.436 63.7423 176.374 64.0917C177.761 64.5869 178.983 65.1486 180.029 65.7824C181.136 66.4357 182.019 67.2663 182.645 68.283C183.311 69.3362 183.609 70.6117 183.609 72.0469C183.609 73.5479 183.259 74.8896 182.506 76.0202C181.777 77.1319 180.755 77.965 179.48 78.5249L179.476 78.5267C178.849 78.7988 178.179 78.9991 177.469 79.1314V81.3125V82.3125H176.469H174.078H173.078V81.3125V79.1318C172.785 79.0777 172.492 79.0125 172.2 78.9363L172.187 78.9328L172.187 78.9327C171.16 78.6493 170.221 78.1865 169.379 77.5459C168.499 76.8765 167.813 75.9995 167.315 74.9424L167.313 74.9385C166.797 73.8343 166.563 72.5352 166.563 71.0781V70.0781H167.563H171.344H172.344V71.0781C172.344 71.8089 172.443 72.349 172.599 72.7349C172.768 73.1536 172.977 73.4344 173.203 73.6224C173.475 73.8489 173.769 74.0066 174.093 74.1026C174.474 74.2125 174.849 74.2656 175.219 74.2656C175.892 74.2656 176.387 74.1531 176.744 73.9788C177.124 73.7879 177.373 73.5457 177.536 73.2579L177.539 73.2519C177.724 72.9297 177.828 72.5475 177.828 72.0781C177.828 71.6141 177.733 71.2618 177.58 70.9874L177.573 70.9754L177.567 70.9633C177.425 70.6913 177.164 70.3968 176.715 70.1001L176.704 70.0929L176.704 70.0928C176.249 69.784 175.598 69.4694 174.718 69.1631L174.715 69.1622C173.335 68.6768 172.108 68.1257 171.043 67.5044L171.032 67.4982L171.033 67.4981C169.927 66.8348 169.037 66.0018 168.392 64.9913L168.384 64.9795L168.384 64.9795C167.722 63.9094 167.422 62.6267 167.422 61.1875C167.422 59.75 167.751 58.4512 168.448 57.3311L168.452 57.3243C169.151 56.221 170.119 55.3748 171.329 54.7878C171.961 54.4813 172.639 54.2592 173.359 54.1167V51.6094V50.6094H174.359H176.766H177.766ZM174.359 53.9721V54.977C174.014 55.0131 173.681 55.0669 173.359 55.1385C172.789 55.2656 172.258 55.4486 171.766 55.6875C170.714 56.1979 169.891 56.9219 169.297 57.8594C168.714 58.7969 168.422 59.9062 168.422 61.1875C168.422 62.4896 168.693 63.5781 169.234 64.4531C169.787 65.3177 170.557 66.0469 171.547 66.6406C172.547 67.224 173.714 67.75 175.047 68.2188C175.974 68.5417 176.714 68.8906 177.266 69.2656C177.818 69.6302 178.214 70.0417 178.453 70.5C178.703 70.9479 178.828 71.474 178.828 72.0781C178.828 72.7031 178.688 73.2604 178.406 73.75C178.136 74.2292 177.729 74.6042 177.188 74.875C176.656 75.1354 176 75.2656 175.219 75.2656C174.75 75.2656 174.281 75.1979 173.813 75.0625C173.354 74.9271 172.938 74.7031 172.563 74.3906C172.188 74.0781 171.891 73.651 171.672 73.1094C171.453 72.5677 171.344 71.8906 171.344 71.0781H170.344H168.563H167.563C167.563 71.4251 167.577 71.7585 167.606 72.0781C167.689 73.0059 167.893 73.8184 168.219 74.5156C168.656 75.4427 169.245 76.1875 169.984 76.75C170.724 77.3125 171.547 77.7188 172.453 77.9688C172.661 78.0231 172.87 78.0713 173.078 78.1134C173.411 78.1804 173.744 78.2318 174.078 78.2674V79.2726V80.3125V81.3125H175.078H175.469H176.469V80.3125V79.2707V78.2658C176.814 78.2301 177.147 78.1789 177.469 78.1124C178.043 77.9937 178.579 77.826 179.078 77.6094C180.193 77.1198 181.057 76.4062 181.672 75.4688C182.297 74.5312 182.609 73.3906 182.609 72.0469C182.609 70.7448 182.339 69.6667 181.797 68.8125C181.266 67.9479 180.505 67.224 179.516 66.6406C178.537 66.0469 177.375 65.5104 176.031 65.0312C175.052 64.6667 174.281 64.3073 173.719 63.9531C173.167 63.5885 172.776 63.1823 172.547 62.7344C172.318 62.2865 172.203 61.7656 172.203 61.1719C172.203 60.5573 172.313 60.0104 172.531 59.5312C172.761 59.0521 173.115 58.6771 173.594 58.4062C174.073 58.125 174.682 57.9844 175.422 57.9844C175.943 57.9844 176.406 58.0833 176.813 58.2812C177.229 58.4792 177.583 58.7656 177.875 59.1406C178.167 59.5052 178.386 59.9531 178.531 60.4844C178.688 61.0052 178.766 61.599 178.766 62.2656H179.766H181.516H182.516C182.516 61.9207 182.501 61.5873 182.473 61.2656C182.404 60.4896 182.251 59.7813 182.016 59.1406C181.693 58.224 181.224 57.4531 180.609 56.8281C179.995 56.2031 179.25 55.7292 178.375 55.4062C178.178 55.3325 177.975 55.2672 177.766 55.2103C177.446 55.1231 177.112 55.0557 176.766 55.0081V53.9996V52.6094V51.6094H175.766H175.359H174.359V52.6094V53.9721ZM63.8581 78.8737V55.2121V53.333L62.8581 54.9239L52.6367 71.1852L62.8581 79.3546L63.8581 80.1539V79.7052V79.6402V79.5388V78.9507V78.8904V78.8737ZM64.8581 79.3707L64.1173 79.9639L64.8581 79.5122L70.8249 75.8737L84.7833 67.3622L86.2838 66.4472V66.3622H86.232H85.2838H84.5025H73.2681H72.0871L72.7154 67.3622L75.105 71.1653L70.2497 75.0532L64.8581 79.3707ZM76.3801 71.3151L82.8625 67.3622H73.8964L75.9517 70.6333L76.3801 71.3151ZM62.8581 78.0745V56.803L53.9585 70.9615L62.8581 78.0745ZM118.999 185.275C118.999 186.913 117.672 188.24 116.034 188.24C114.396 188.24 113.068 186.913 113.068 185.275C113.068 183.637 114.396 182.309 116.034 182.309C117.672 182.309 118.999 183.637 118.999 185.275ZM127.897 185.275C127.897 186.913 126.569 188.24 124.931 188.24C123.294 188.24 121.966 186.913 121.966 185.275C121.966 183.637 123.294 182.309 124.931 182.309C126.569 182.309 127.897 183.637 127.897 185.275Z'\n        fill='#446EFF'\n      />\n    </LargeSvgIcon>\n  )\n}\n\nexport const DualUpIcon = (props) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24' aria-hidden='true'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M20.5205 12.7039C20.5205 17.8377 16.3588 21.9994 11.225 21.9994C9.90327 21.9994 8.64594 21.7235 7.50748 21.2262L7.50745 21.3797C8.64826 21.8692 9.905 22.1403 11.225 22.1403C16.4366 22.1403 20.6614 17.9155 20.6614 12.7039C20.6614 7.49237 16.4366 3.26758 11.225 3.26758C6.01349 3.26758 1.7887 7.49237 1.7887 12.7039C1.7887 13.534 1.89586 14.339 2.09712 15.1059L2.21517 14.9996C2.02866 14.2653 1.92954 13.4962 1.92954 12.7039C1.92954 7.57016 6.09128 3.40842 11.225 3.40842C16.3588 3.40842 20.5205 7.57016 20.5205 12.7039ZM2.93811 16.9194C3.08519 17.2079 3.24689 17.4878 3.42225 17.758L3.31627 17.8534C3.14038 17.5838 2.9779 17.3046 2.82977 17.0169L2.93811 16.9194ZM11.225 20.3093C8.10438 20.3093 5.4227 18.4298 4.25025 15.741C4.25127 15.7408 4.25232 15.7407 4.25337 15.7407C4.25699 15.7407 4.26046 15.742 4.26312 15.7444L4.50902 15.9659C5.71967 18.4538 8.27212 20.1685 11.225 20.1685C15.3476 20.1685 18.6896 16.8265 18.6896 12.7039C18.6896 8.58135 15.3476 5.23935 11.225 5.23935C7.10247 5.23935 3.76047 8.58135 3.76047 12.7039C3.76047 12.9951 3.77714 13.2823 3.80957 13.5647L3.68166 13.6798C3.64073 13.3603 3.61963 13.0346 3.61963 12.7039C3.61963 8.50357 7.02469 5.09851 11.225 5.09851C15.4254 5.09851 18.8305 8.50357 18.8305 12.7039C18.8305 16.9043 15.4254 20.3093 11.225 20.3093ZM10.7101 15.8376V16.5815H11.2382V15.842C12.2769 15.7584 13.1396 15.1642 13.1396 14.1079V14.0991C13.1396 13.1793 12.5058 12.7127 11.3747 12.4398L11.2382 12.409V10.3888C11.8324 10.4637 12.2549 10.829 12.3122 11.4187V11.4276L13.078 11.4232V11.4187C13.0428 10.4505 12.2549 9.79028 11.2382 9.69785V8.95403H10.7101V9.69785C9.66699 9.79468 8.92317 10.4373 8.92317 11.3791V11.3879C8.92317 12.2506 9.51294 12.7391 10.6089 13.0032L10.7101 13.0296V15.1466C9.94427 15.063 9.60537 14.6273 9.52615 14.0815V14.0727L8.76032 14.0771V14.0815C8.79553 15.1026 9.66259 15.7408 10.7101 15.8376ZM10.7101 12.2814C9.95307 12.0965 9.68899 11.762 9.68899 11.3351V11.3263C9.68899 10.9038 10.0411 10.4813 10.7101 10.3888V12.2814ZM11.2382 13.1573L11.2647 13.1617C12.1361 13.3729 12.3738 13.681 12.3738 14.1607V14.1695C12.3738 14.6757 12.0569 15.0894 11.2382 15.1554V13.1573Z'\n        fill={props.fill}\n      />\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M19.6361 2.1865C18.6721 3.05377 17.7083 3.92121 16.7447 4.78883C16.6922 4.83622 16.6675 4.86339 16.6533 4.88775C16.6428 4.90566 16.6346 4.92807 16.6335 4.97023C16.5907 4.94027 16.5477 4.91066 16.5044 4.88139C16.5252 4.80575 16.5735 4.75357 16.6503 4.68425C17.614 3.81659 18.5779 2.94911 19.5419 2.0818C19.5939 2.03501 19.6565 2.00774 19.7299 2H19.7685C19.8405 2.01005 19.9004 2.03657 19.9481 2.07954C20.9332 2.96603 21.9183 3.85258 22.9032 4.73919C22.984 4.81197 22.9994 4.90746 22.9994 5.02357C22.9998 5.58691 22.9989 6.15031 22.9966 6.71377C22.9961 6.8516 22.9394 6.94686 22.8264 6.99954C22.6731 7.07129 22.5608 7.00145 22.4372 6.89019C21.5424 6.0855 20.6486 5.28115 19.7557 4.47716C19.7531 4.47474 19.7496 4.4734 19.746 4.4734C19.7424 4.4734 19.7389 4.47474 19.7361 4.47716L17.9502 6.08444C17.9173 6.05094 17.884 6.01768 17.8506 5.98467L19.6419 4.37248L19.6425 4.37192C19.6709 4.34671 19.7076 4.33257 19.746 4.33256C19.7842 4.33257 19.8214 4.34668 19.8501 4.37263C20.7429 5.17657 21.6366 5.98084 22.5314 6.78547C22.5911 6.83928 22.6329 6.86833 22.668 6.88086C22.6947 6.89038 22.7226 6.89261 22.7668 6.87197L22.7669 6.8719C22.8011 6.85595 22.8206 6.83692 22.8327 6.81652C22.8454 6.79524 22.8556 6.76309 22.8558 6.7133C22.8581 6.15007 22.859 5.5868 22.8585 5.02369C22.8585 4.91616 22.8428 4.87438 22.8089 4.84381C21.824 3.95723 20.839 3.0707 19.8539 2.18424C19.8312 2.16384 19.801 2.14822 19.7578 2.14084H19.7381C19.6958 2.14643 19.6633 2.16196 19.6361 2.1865ZM19.7408 8.31749L19.6327 8.4149C19.6106 8.3717 19.5882 8.3287 19.5655 8.28589L19.6466 8.21285L19.6469 8.21252C19.6742 8.18814 19.7095 8.17467 19.746 8.17467C19.7826 8.17467 19.8179 8.18814 19.8451 8.21252L19.8455 8.21284C20.7658 9.04178 21.682 9.86661 22.5941 10.6873C22.6514 10.7389 22.7138 10.7404 22.7637 10.716C22.816 10.6904 22.8582 10.6339 22.8585 10.5562C22.8595 10.3115 22.8595 9.74618 22.8585 8.85972C22.8585 8.78438 22.8479 8.75215 22.8357 8.73014C22.8206 8.70301 22.7946 8.67505 22.7309 8.6176L19.9201 6.08822C19.8514 6.02646 19.8107 6.00171 19.7935 5.99517C19.7624 5.98348 19.7375 5.98263 19.7154 5.98764C19.6922 5.99291 19.6629 6.00682 19.6277 6.03846L18.6679 6.90243C18.639 6.86534 18.6098 6.82848 18.5803 6.79184L19.5335 5.93375C19.6312 5.84594 19.7344 5.82249 19.8432 5.86339C19.8863 5.87968 19.9433 5.91971 20.0143 5.98348L22.8252 8.51298C22.9495 8.6251 22.9992 8.68229 22.9994 8.85958C23.0003 9.74595 23.0003 10.3117 22.9994 10.5567C22.9983 10.8219 22.7036 10.9752 22.4999 10.7921C21.5878 9.9713 20.6716 9.14645 19.7512 8.31749C19.7498 8.31622 19.7479 8.31551 19.746 8.31551C19.7441 8.31551 19.7422 8.31622 19.7408 8.31749ZM1.25248 16.0561C2.2161 15.1885 3.17989 14.3211 4.14385 13.4538C4.17112 13.4292 4.2036 13.4137 4.24591 13.4081H4.26559C4.3088 13.4155 4.33901 13.4311 4.36166 13.4515C5.34679 14.338 6.3318 15.2245 7.3167 16.1111C7.35062 16.1417 7.36633 16.1834 7.36633 16.291C7.36679 16.8541 7.36587 17.4174 7.36356 17.9806C7.36339 18.0304 7.35317 18.0625 7.3405 18.0838C7.32835 18.1042 7.30889 18.1232 7.2747 18.1392L7.27454 18.1393C7.23042 18.1599 7.20245 18.1577 7.17581 18.1482C7.14073 18.1356 7.09893 18.1066 7.03916 18.0528C6.14443 17.2481 5.25068 16.4439 4.35791 15.6399C4.32919 15.614 4.29198 15.5999 4.25374 15.5998C4.21542 15.5999 4.17866 15.614 4.15031 15.6392L4.1497 15.6398C3.24152 16.4572 2.33248 17.2753 1.42257 18.094C1.354 18.1556 1.29365 18.1651 1.2326 18.137C1.18766 18.1163 1.171 18.0935 1.16059 18.0666C1.14677 18.031 1.14119 17.9799 1.1411 17.8967C1.14075 17.3472 1.14075 16.7976 1.1411 16.2481C1.1411 16.199 1.14978 16.1744 1.16105 16.155C1.17525 16.1307 1.19995 16.1035 1.25248 16.0561ZM4.04965 13.3491C3.08564 14.2164 2.1218 15.0839 1.15814 15.9515C1.0519 16.0474 1.00026 16.1105 1.00026 16.2481C0.999913 16.7976 0.999913 17.3472 1.00026 17.8968C1.00043 18.0656 1.01967 18.194 1.17373 18.2649C1.29851 18.3225 1.41774 18.2876 1.5167 18.1987C2.42664 17.3801 3.33571 16.562 4.24392 15.7444C4.24664 15.742 4.25014 15.7407 4.25376 15.7407C4.25738 15.7407 4.26085 15.742 4.26351 15.7444C5.15635 16.5484 6.05018 17.3528 6.94498 18.1575C7.06855 18.2687 7.18085 18.3386 7.33422 18.2668C7.44721 18.2141 7.50394 18.1189 7.5044 17.9811C7.50671 17.4176 7.50763 16.8542 7.50717 16.2909C7.50717 16.1747 7.49175 16.0793 7.41099 16.0065C6.42607 15.1199 5.44103 14.2333 4.45587 13.3468C4.40815 13.3039 4.34831 13.2773 4.27633 13.2673H4.23769C4.16432 13.275 4.10164 13.3023 4.04965 13.3491ZM1.14093 21.7184C1.14081 21.1718 1.14098 20.625 1.14145 20.0781C1.14145 20.027 1.16197 19.9823 1.20788 19.9409L4.13552 17.3058C4.17071 17.2741 4.19999 17.2602 4.22318 17.2549C4.24526 17.2499 4.27014 17.2508 4.30133 17.2625C4.31852 17.269 4.35921 17.2937 4.42791 17.3555L7.23872 19.8849C7.30237 19.9423 7.3284 19.9703 7.34345 19.9974C7.35565 20.0194 7.36626 20.0517 7.36633 20.127C7.36725 21.0135 7.36725 21.5788 7.36633 21.8234C7.36603 21.9012 7.32377 21.9577 7.2715 21.9833C7.22161 22.0077 7.1592 22.0062 7.10191 21.9546C6.1898 21.1339 5.27358 20.3091 4.35326 19.4801L4.35289 19.4798C4.32564 19.4554 4.29036 19.442 4.2538 19.442C4.21725 19.442 4.18197 19.4554 4.15471 19.4798L4.15434 19.4801C3.23553 20.3078 2.31615 21.1353 1.39619 21.9626C1.32185 22.0294 1.18615 21.9947 1.1529 21.8925L1.15279 21.8922C1.14816 21.8781 1.14093 21.827 1.14093 21.7184ZM4.35102 17.1307C4.24219 17.0898 4.13896 17.1132 4.04133 17.201L1.1136 19.8362C1.04272 19.9002 1.00061 19.9811 1.00061 20.078C1.00014 20.6249 0.999971 21.1718 1.00009 21.7185C1.00009 21.8252 1.00638 21.8978 1.01898 21.9361C1.08188 22.1294 1.33576 22.2063 1.49034 22.0673C2.41034 21.24 3.32976 20.4125 4.2486 19.5848C4.25003 19.5835 4.25188 19.5828 4.2538 19.5828C4.25572 19.5828 4.25757 19.5835 4.259 19.5848C5.17934 20.4137 6.09558 21.2386 7.00772 22.0593C7.21135 22.2425 7.50613 22.0891 7.50717 21.824C7.50809 21.5789 7.50809 21.0132 7.50717 20.1269C7.507 19.9496 7.45726 19.8924 7.333 19.7803L4.52207 17.2508C4.45113 17.187 4.39412 17.147 4.35102 17.1307Z'\n        fill='#446EFF'\n      />\n    </SvgIcon>\n  )\n}\nexport const DualDownIcon = (props) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24' aria-hidden='true'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M12.775 2.00057C7.64119 2.00057 3.47945 6.16231 3.47945 11.2961C3.47945 16.4298 7.64119 20.5916 12.775 20.5916C17.9087 20.5916 22.0705 16.4298 22.0705 11.2961C22.0705 10.5038 21.9713 9.73466 21.7848 9.00041L21.9029 8.89414C22.1041 9.66103 22.2113 10.466 22.2113 11.2961C22.2113 16.5076 17.9865 20.7324 12.775 20.7324C7.56341 20.7324 3.33861 16.5076 3.33861 11.2961C3.33861 6.08453 7.56341 1.85973 12.775 1.85973C14.095 1.85973 15.3517 2.13078 16.4926 2.62026L16.4925 2.77376C15.3541 2.27645 14.0967 2.00057 12.775 2.00057ZM20.5777 6.24204C20.7531 6.51221 20.9148 6.79207 21.0619 7.08063L21.1702 6.98313C21.0221 6.69539 20.8596 6.41624 20.6837 6.14664L20.5777 6.24204ZM19.7497 8.25898C18.5773 5.57018 15.8956 3.69066 12.775 3.69066C8.5746 3.69066 5.16955 7.09572 5.16955 11.2961C5.16955 15.4964 8.5746 18.9015 12.775 18.9015C16.9753 18.9015 20.3804 15.4964 20.3804 11.2961C20.3804 10.9654 20.3593 10.6397 20.3183 10.3202L20.1904 10.4353C20.2229 10.7177 20.2395 11.0049 20.2395 11.2961C20.2395 15.4186 16.8975 18.7606 12.775 18.7606C8.65239 18.7606 5.31039 15.4186 5.31039 11.2961C5.31039 7.17351 8.65239 3.8315 12.775 3.8315C15.7279 3.8315 18.2803 5.54615 19.491 8.03414L19.7369 8.25556C19.7395 8.25797 19.743 8.25931 19.7466 8.25931C19.7477 8.25931 19.7487 8.2592 19.7497 8.25898ZM12.8102 14.3022V15.046H13.3383V14.3066C14.377 14.2229 15.2397 13.6288 15.2397 12.5724V12.5636C15.2397 11.6438 14.6059 11.1772 13.4748 10.9044L13.3383 10.8736V8.85336C13.9325 8.92819 14.355 9.29349 14.4122 9.88326V9.89207L15.1781 9.88767V9.88326C15.1428 8.91498 14.355 8.25479 13.3383 8.16236V7.41855H12.8102V8.16236C11.7671 8.25919 11.0232 8.90178 11.0232 9.84365V9.85246C11.0232 10.7151 11.613 11.2036 12.7089 11.4677L12.8102 11.4941L12.8102 13.6111C12.0443 13.5275 11.7054 13.0918 11.6262 12.546V12.5372L10.8604 12.5416V12.546C10.8956 13.5671 11.7627 14.2053 12.8102 14.3022ZM13.3383 11.6218L13.3647 11.6262C14.2362 11.8374 14.4739 12.1455 14.4739 12.6253V12.6341C14.4739 13.1402 14.157 13.5539 13.3383 13.62L13.3383 11.6218ZM12.8102 10.7459C12.0531 10.5611 11.7891 10.2266 11.7891 9.79964V9.79084C11.7891 9.36831 12.1412 8.94579 12.8102 8.85336V10.7459Z'\n        fill={props.fill}\n      />\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M4.36401 21.8135C5.32797 20.9462 6.29177 20.0788 7.25539 19.2112C7.30792 19.1638 7.33261 19.1366 7.34681 19.1122C7.35725 19.0943 7.36546 19.0719 7.36662 19.0298C7.40938 19.0597 7.4524 19.0893 7.49568 19.1186C7.47485 19.1942 7.42657 19.2464 7.34973 19.3157C6.38606 20.1834 5.42222 21.0509 4.45821 21.9182C4.40622 21.965 4.34354 21.9923 4.27018 22H4.23153C4.15955 21.9899 4.09971 21.9634 4.05199 21.9205C3.06684 21.034 2.0818 20.1474 1.09687 19.2608C1.01611 19.188 1.00069 19.0925 1.00069 18.9764C1.00023 18.4131 1.00115 17.8497 1.00346 17.2862C1.00393 17.1484 1.06065 17.0531 1.17364 17.0005C1.32702 16.9287 1.43931 16.9986 1.56288 17.1098C2.45768 17.9145 3.35151 18.7188 4.24436 19.5228C4.24702 19.5253 4.25049 19.5266 4.2541 19.5266C4.25772 19.5266 4.26122 19.5253 4.26394 19.5228C4.85886 18.9873 5.45416 18.4516 6.04983 17.9156C6.0828 17.9491 6.11603 17.9823 6.14951 18.0153C5.55202 18.553 4.9549 19.0904 4.35816 19.6275L4.35755 19.6281C4.3292 19.6533 4.29245 19.6674 4.25412 19.6674C4.21588 19.6674 4.17867 19.6533 4.14995 19.6274C3.25719 18.8234 2.36343 18.0192 1.4687 17.2145C1.40894 17.1607 1.36713 17.1317 1.33205 17.1191C1.30541 17.1096 1.27745 17.1074 1.23332 17.128L1.23316 17.1281C1.19897 17.144 1.17951 17.1631 1.16736 17.1835C1.15469 17.2048 1.14447 17.2369 1.1443 17.2867C1.14199 17.8499 1.14107 18.4132 1.14153 18.9763C1.14153 19.0838 1.15724 19.1256 1.19116 19.1562C2.17606 20.0428 3.16107 20.9293 4.1462 21.8158C4.16885 21.8362 4.19907 21.8518 4.24228 21.8592H4.26195C4.30426 21.8536 4.33675 21.838 4.36401 21.8135ZM4.25926 15.6825L4.3674 15.5851C4.38948 15.6283 4.41188 15.6713 4.43461 15.7141L4.35352 15.7872L4.35315 15.7875C4.3259 15.8119 4.29061 15.8253 4.25406 15.8253C4.2175 15.8253 4.18222 15.8119 4.15497 15.7875L4.1546 15.7872C3.23429 14.9582 2.31807 14.1334 1.40595 13.3127C1.34866 13.2611 1.28625 13.2596 1.23636 13.284C1.18409 13.3096 1.14184 13.3661 1.14153 13.4438C1.14061 13.6885 1.14061 14.2538 1.14153 15.1403C1.14161 15.2156 1.15221 15.2479 1.16442 15.2699C1.17946 15.297 1.20549 15.325 1.26914 15.3824L4.07995 17.9118C4.14865 17.9735 4.18934 17.9983 4.20653 18.0048C4.23772 18.0165 4.2626 18.0174 4.28468 18.0124C4.30787 18.0071 4.33716 17.9932 4.37234 17.9615L5.33214 17.0976C5.36109 17.1347 5.39031 17.1715 5.4198 17.2082L4.46653 18.0663C4.3689 18.1541 4.26567 18.1775 4.15684 18.1366C4.11375 18.1203 4.05673 18.0803 3.98579 18.0165L1.17486 15.487C1.0506 15.3749 1.00087 15.3177 1.00069 15.1404C0.999767 14.254 0.999767 13.6883 1.00069 13.4433C1.00173 13.1781 1.29652 13.0248 1.50014 13.2079C2.41228 14.0287 3.32852 14.8536 4.24886 15.6825C4.25029 15.6838 4.25214 15.6845 4.25406 15.6845C4.25598 15.6845 4.25783 15.6838 4.25926 15.6825ZM22.7475 7.94389C21.7839 8.81151 20.8201 9.67895 19.8561 10.5462C19.8289 10.5708 19.7964 10.5863 19.7541 10.5919H19.7344C19.6912 10.5845 19.661 10.5689 19.6383 10.5485C18.6532 9.66201 17.6682 8.77549 16.6833 7.88891C16.6494 7.85834 16.6337 7.81655 16.6337 7.70903C16.6332 7.14592 16.6341 6.58264 16.6364 6.01942C16.6366 5.96963 16.6468 5.93747 16.6595 5.91619C16.6716 5.8958 16.6911 5.87676 16.7253 5.86082L16.7255 5.86074C16.7696 5.8401 16.7975 5.84233 16.8242 5.85185C16.8593 5.86439 16.9011 5.89344 16.9608 5.94725C17.8556 6.75187 18.7493 7.55615 19.6421 8.36008C19.6708 8.38604 19.708 8.40015 19.7463 8.40016C19.7846 8.40015 19.8213 8.38601 19.8497 8.36079L19.8503 8.36024C20.7585 7.54275 21.6675 6.72469 22.5774 5.90605C22.646 5.84445 22.7064 5.83488 22.7674 5.86303C22.8123 5.88371 22.829 5.90654 22.8394 5.93337C22.8532 5.96895 22.8588 6.02012 22.8589 6.10331C22.8592 6.65283 22.8592 7.20243 22.8589 7.75195C22.8589 7.80102 22.8502 7.82562 22.8389 7.84497C22.8248 7.86933 22.8001 7.8965 22.7475 7.94389ZM19.9503 10.6509C20.9144 9.78361 21.8782 8.91612 22.8419 8.04847C22.9481 7.95263 22.9997 7.88955 22.9997 7.75195C23.0001 7.20236 23.0001 6.65276 22.9997 6.10317C22.9996 5.93438 22.9803 5.80596 22.8263 5.73508C22.7015 5.67754 22.5823 5.71238 22.4833 5.80128C21.5734 6.61995 20.6643 7.43805 19.7561 8.25556C19.7534 8.25798 19.7499 8.25931 19.7462 8.25931C19.7426 8.25931 19.7392 8.25798 19.7365 8.25556C18.8436 7.45156 17.9498 6.64722 17.055 5.84253C16.9315 5.73127 16.8192 5.66143 16.6658 5.73317C16.5528 5.78586 16.4961 5.88111 16.4956 6.01895C16.4933 6.5824 16.4924 7.1458 16.4928 7.70914C16.4928 7.82526 16.5083 7.92074 16.589 7.99353C17.5739 8.88014 18.559 9.76668 19.5441 10.6532C19.5918 10.6962 19.6517 10.7227 19.7237 10.7327H19.7623C19.8357 10.725 19.8984 10.6977 19.9503 10.6509ZM22.8591 2.28158C22.8592 2.82823 22.859 3.375 22.8586 3.92189C22.8586 3.97298 22.838 4.01769 22.7921 4.05913C21.8161 4.93751 20.8402 5.81588 19.8645 6.69425C19.8293 6.7259 19.8 6.7398 19.7768 6.74507C19.7547 6.75009 19.7299 6.74924 19.6987 6.73755C19.6815 6.73101 19.6408 6.70625 19.5721 6.64449L16.7613 4.11511C16.6976 4.05767 16.6716 4.02971 16.6566 4.00257C16.6444 3.98057 16.6337 3.94833 16.6337 3.87299C16.6327 2.98654 16.6327 2.42121 16.6337 2.17656C16.634 2.09879 16.6762 2.0423 16.7285 2.01672C16.7784 1.9923 16.8408 1.99384 16.8981 2.04537C17.8102 2.86611 18.7264 3.69094 19.6467 4.51987L19.6471 4.5202C19.6744 4.54458 19.7096 4.55805 19.7462 4.55805C19.7828 4.55805 19.818 4.54458 19.8453 4.5202L19.8457 4.51987C20.7645 3.69221 21.6838 2.86474 22.6038 2.03743C22.6782 1.97059 22.8138 2.00533 22.8471 2.10748L22.8472 2.10782C22.8518 2.12192 22.8591 2.17297 22.8591 2.28158ZM19.649 6.86933C19.7578 6.91023 19.861 6.88677 19.9587 6.79897C20.9345 5.92057 21.9104 5.04216 22.8864 4.16376C22.9573 4.09981 22.9994 4.01888 22.9994 3.92201C22.9999 3.37507 23 2.82825 22.9999 2.28155C22.9999 2.17479 22.9936 2.10224 22.981 2.06388C22.9181 1.87065 22.6642 1.79372 22.5097 1.9327C21.5897 2.76004 20.6702 3.58754 19.7514 4.41522C19.75 4.4165 19.7481 4.41721 19.7462 4.41721C19.7443 4.41721 19.7424 4.4165 19.741 4.41522C18.8207 3.58627 17.9044 2.76142 16.9923 1.94067C16.7887 1.75749 16.4939 1.91086 16.4928 2.17601C16.4919 2.42105 16.4919 2.98676 16.4928 3.87314C16.493 4.05042 16.5427 4.10761 16.667 4.21974L19.4779 6.74923C19.5489 6.81301 19.6059 6.85304 19.649 6.86933Z'\n        fill='#446EFF'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const DualConvertIcon = (props) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24' aria-hidden='true'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M11.8132 18.6612C13.0139 18.6612 14.1433 18.3562 15.1282 17.8196C14.8118 17.5224 14.5369 17.1816 14.3129 16.8068C13.559 17.1781 12.7105 17.3868 11.8132 17.3868C8.685 17.3868 6.14907 14.8508 6.14907 11.7226C6.14907 8.59437 8.685 6.05844 11.8132 6.05844C14.2979 6.05844 16.4088 7.65821 17.1723 9.88391C17.5416 9.79003 17.9285 9.74014 18.327 9.74014C18.3732 9.74014 18.4192 9.74081 18.4651 9.74214C17.6127 6.87499 14.9572 4.784 11.8132 4.784C7.98115 4.784 4.87464 7.89052 4.87464 11.7226C4.87464 15.5547 7.98115 18.6612 11.8132 18.6612ZM18.6147 9.74885C17.7601 6.799 15.0385 4.6424 11.8132 4.6424C7.90295 4.6424 4.73303 7.81231 4.73303 11.7226C4.73303 15.6329 7.90295 18.8028 11.8132 18.8028C13.0559 18.8028 14.2238 18.4827 15.239 17.9203C16.0624 18.6459 17.1433 19.086 18.327 19.086C20.9078 19.086 23 16.9939 23 14.4131C23 11.9289 21.0615 9.89744 18.6147 9.74885ZM17.0352 9.92098C16.2883 7.75556 14.2324 6.20004 11.8132 6.20004C8.76321 6.20004 6.29068 8.67257 6.29068 11.7226C6.29068 14.7726 8.76321 17.2452 11.8132 17.2452C12.6847 17.2452 13.509 17.0433 14.2419 16.6838C13.8674 16.0116 13.6541 15.2372 13.6541 14.4131C13.6541 13.766 13.7856 13.1497 14.0234 12.5893L11.3572 14.2151L13.4957 12.5026L12.9083 11.5678H14.6199C15.2207 10.7862 16.063 10.2001 17.0352 9.92098ZM11.3068 14.2523V9.03212L9.12276 12.5068L11.3068 14.2523ZM22.8584 14.4131C22.8584 16.9157 20.8296 18.9444 18.327 18.9444C15.8244 18.9444 13.7957 16.9157 13.7957 14.4131C13.7957 11.9105 15.8244 9.88174 18.327 9.88174C20.8296 9.88174 22.8584 11.9105 22.8584 14.4131ZM18.327 17.9532C20.2822 17.9532 21.8671 16.3682 21.8671 14.4131C21.8671 12.4579 20.2822 10.873 18.327 10.873C16.3719 10.873 14.7869 12.4579 14.7869 14.4131C14.7869 16.3682 16.3719 17.9532 18.327 17.9532ZM18.327 18.0948C20.3604 18.0948 22.0087 16.4464 22.0087 14.4131C22.0087 12.3797 20.3604 10.7314 18.327 10.7314C16.2937 10.7314 14.6453 12.3797 14.6453 14.4131C14.6453 16.4464 16.2937 18.0948 18.327 18.0948ZM18.2098 15.9176V16.2915H18.4753V15.9198C18.9974 15.8778 19.4311 15.5791 19.4311 15.0481V15.0437C19.4311 14.5812 19.1125 14.3467 18.5439 14.2095L18.4753 14.194V13.1785C18.774 13.2161 18.9864 13.3997 19.0151 13.6962V13.7006L19.4001 13.6984V13.6962C19.3824 13.2094 18.9864 12.8776 18.4753 12.8311V12.4572H18.2098V12.8311C17.6854 12.8798 17.3115 13.2028 17.3115 13.6763V13.6807C17.3115 14.1144 17.6079 14.36 18.1589 14.4927L18.2098 14.506V15.5702C17.8248 15.5282 17.6544 15.3092 17.6146 15.0348V15.0304L17.2296 15.0326V15.0348C17.2473 15.5481 17.6832 15.8689 18.2098 15.9176ZM18.2098 14.1299C17.8292 14.0369 17.6964 13.8688 17.6964 13.6542V13.6497C17.6964 13.4373 17.8734 13.2249 18.2098 13.1785V14.1299ZM18.4753 14.5702L18.4885 14.5724C18.9266 14.6786 19.0461 14.8335 19.0461 15.0746V15.0791C19.0461 15.3335 18.8868 15.5415 18.4753 15.5747V14.5702Z'\n        fill={props.fill}\n      />\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M18.8769 7.19154C18.9006 7.21528 18.9567 7.24053 19.0799 7.2226C19.2 7.20512 19.3564 7.14967 19.5404 7.05393C19.9069 6.86326 20.3538 6.52819 20.7901 6.09187C21.2264 5.65555 21.5615 5.2086 21.7522 4.84215C21.8479 4.65816 21.9034 4.5018 21.9208 4.3817C21.9388 4.25842 21.9135 4.20239 21.8898 4.17865C21.8661 4.15492 21.81 4.12966 21.6867 4.14759C21.5666 4.16507 21.4103 4.22052 21.2263 4.31626C20.8598 4.50693 20.4129 4.842 19.9766 5.27832C19.5402 5.71464 19.2052 6.16159 19.0145 6.52804C18.9188 6.71204 18.8633 6.8684 18.8458 6.98849C18.8279 7.11177 18.8532 7.1678 18.8769 7.19154ZM19.0184 7.37C19.4323 7.35926 20.1801 6.90212 20.8902 6.192C21.6039 5.47837 22.062 4.72662 22.0684 4.31403C22.2859 4.54121 22.4413 4.80015 22.3876 5.07872C22.3215 5.4214 22.0923 5.95219 21.406 6.63857C20.7859 7.2586 20.2759 7.52246 19.9153 7.63007C19.5995 7.72429 19.2888 7.59296 19.0184 7.37ZM18.7438 7.25011C18.5417 6.92708 19.0289 6.02574 19.8764 5.17819C20.724 4.33064 21.6253 3.84346 21.9484 4.04552L21.9746 4.01926L22.1331 4.17771C22.3739 4.41855 22.5976 4.73723 22.5266 5.10552C22.4539 5.48274 22.207 6.0378 21.5061 6.7387C20.8727 7.37209 20.343 7.65023 19.9558 7.76576C19.5001 7.90172 19.0774 7.64272 18.7656 7.33095L18.7143 7.2796L18.7438 7.25011ZM6.82789 19.1242C6.76348 19.1886 6.64257 19.2265 6.4368 19.1966C6.23421 19.1671 5.97774 19.075 5.68261 18.9214C5.09388 18.6151 4.38054 18.0796 3.68638 17.3854C2.99223 16.6913 2.45671 15.9779 2.15039 15.3892C1.99683 15.0941 1.90474 14.8376 1.87527 14.635C1.84533 14.4292 1.88321 14.3083 1.94762 14.2439C2.01203 14.1795 2.13294 14.1416 2.33871 14.1716C2.5413 14.201 2.79777 14.2931 3.0929 14.4467C3.68163 14.753 4.39497 15.2885 5.08913 15.9827C5.78328 16.6768 6.3188 17.3902 6.62512 17.9789C6.77868 18.274 6.87077 18.5305 6.90024 18.7331C6.93018 18.9389 6.8923 19.0598 6.82789 19.1242ZM3.58625 17.4856C4.75718 18.6565 5.99303 19.3924 6.62714 19.3464L6.54455 19.429C6.24299 19.7306 5.877 19.9453 5.48154 19.8829C4.90686 19.7922 3.95499 19.4341 2.74168 18.2208C1.44484 16.9239 1.17069 15.9716 1.14265 15.4493C1.12626 15.144 1.30622 14.874 1.54075 14.6394L1.72466 14.4555C1.68776 15.0928 2.42197 16.3213 3.58625 17.4856ZM5.18926 15.8826C3.84911 14.5424 2.42391 13.7721 1.91317 14.0916L1.90073 14.0792L1.44062 14.5393C1.1986 14.7813 0.981508 15.0892 1.00125 15.4569C1.03164 16.0229 1.32707 17.0064 2.64155 18.3209C3.87166 19.551 4.84965 19.9265 5.45946 20.0228C5.92232 20.0958 6.33179 19.842 6.64468 19.5292L6.99769 19.1762L6.98018 19.1586C7.29973 18.6479 6.5294 17.2227 5.18926 15.8826ZM6.2749 18.5711C6.26345 18.5826 6.21225 18.6104 6.06049 18.5715C5.91936 18.5353 5.73367 18.451 5.51417 18.3194C5.0771 18.0573 4.53366 17.6242 3.99061 17.0811C3.44757 16.5381 3.01448 15.9947 2.75236 15.5576C2.62073 15.3381 2.53647 15.1524 2.50026 15.0113C2.46132 14.8595 2.48917 14.8083 2.50062 14.7969C2.51207 14.7854 2.56327 14.7576 2.71503 14.7965C2.85616 14.8327 3.04185 14.917 3.26135 15.0486C3.69842 15.3107 4.24186 15.7438 4.78491 16.2868C5.32795 16.8299 5.76104 17.3733 6.02316 17.8104C6.15479 18.0299 6.23905 18.2156 6.27526 18.3567C6.3142 18.5085 6.28635 18.5597 6.2749 18.5711ZM6.37503 18.6713C6.10039 18.9459 4.98802 18.2788 3.89048 17.1813C2.79295 16.0837 2.12585 14.9714 2.40049 14.6967C2.67513 14.4221 3.7875 15.0892 4.88504 16.1867C5.98257 17.2843 6.64967 18.3966 6.37503 18.6713ZM19.2295 6.83884C19.2282 6.82727 19.2281 6.80235 19.24 6.7559C19.2611 6.6736 19.3116 6.56109 19.3936 6.42422C19.5567 6.1524 19.8276 5.81203 20.1689 5.47069C20.5103 5.12935 20.8507 4.8584 21.1225 4.6954C21.2593 4.61332 21.3719 4.56285 21.4542 4.54173C21.5006 4.52981 21.5255 4.52991 21.5371 4.53127C21.5385 4.54285 21.5386 4.56776 21.5266 4.61421C21.5055 4.69651 21.4551 4.80903 21.373 4.9459C21.21 5.21771 20.939 5.55809 20.5977 5.89943C20.2563 6.24076 19.916 6.51171 19.6441 6.67472C19.5073 6.7568 19.3948 6.80726 19.3125 6.82838C19.266 6.8403 19.2411 6.8402 19.2295 6.83884ZM20.6978 5.99955C20.0037 6.69369 19.3002 7.11558 19.1265 6.94189C18.9528 6.7682 19.3747 6.06469 20.0688 5.37056C20.7629 4.67643 21.4665 4.25453 21.6401 4.42822C21.8138 4.60191 21.3919 5.30542 20.6978 5.99955Z'\n        fill='#446EFF'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const DualBTCIcon = (props) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24' aria-hidden='true'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M11.7892 18.6288C12.9872 18.6288 14.1141 18.3245 15.0969 17.7891C14.7812 17.4925 14.5068 17.1525 14.2833 16.7785C13.5311 17.149 12.6844 17.3572 11.7892 17.3572C8.66785 17.3572 6.13752 14.8269 6.13752 11.7056C6.13752 8.58423 8.66785 6.0539 11.7892 6.0539C14.2683 6.0539 16.3746 7.65015 17.1364 9.87092C17.5049 9.77726 17.8909 9.72748 18.2886 9.72748C18.3346 9.72748 18.3806 9.72814 18.4263 9.72947C17.5759 6.86865 14.9262 4.78228 11.7892 4.78228C7.96555 4.78228 4.8659 7.88194 4.8659 11.7056C4.8659 15.5292 7.96555 18.6288 11.7892 18.6288ZM18.5756 9.73617C17.7229 6.79283 15.0073 4.64099 11.7892 4.64099C7.88752 4.64099 4.72461 7.8039 4.72461 11.7056C4.72461 15.6072 7.88752 18.7701 11.7892 18.7701C13.0291 18.7701 14.1944 18.4507 15.2074 17.8896C16.0289 18.6135 17.1075 19.0527 18.2886 19.0527C20.8637 19.0527 22.9512 16.9652 22.9512 14.3901C22.9512 11.9114 21.017 9.88443 18.5756 9.73617ZM16.9997 9.90792C16.2544 7.74728 14.203 6.19519 11.7892 6.19519C8.74588 6.19519 6.27881 8.66227 6.27881 11.7056C6.27881 14.7488 8.74588 17.2159 11.7892 17.2159C12.6587 17.2159 13.4812 17.0145 14.2125 16.6558C13.8388 15.985 13.626 15.2124 13.626 14.3901C13.626 13.7445 13.7572 13.1295 13.9944 12.5704C14.2316 12.0112 14.5896 11.5511 14.5896 11.5511C15.1891 10.7712 16.0296 10.1864 16.9997 9.90792ZM22.8099 14.3901C22.8099 16.8871 20.7856 18.9114 18.2886 18.9114C15.7915 18.9114 13.7672 16.8871 13.7672 14.3901C13.7672 11.893 15.7915 9.86877 18.2886 9.86877C20.7856 9.86877 22.8099 11.893 22.8099 14.3901ZM18.2886 17.9224C20.2394 17.9224 21.8209 16.3409 21.8209 14.3901C21.8209 12.4393 20.2394 10.8578 18.2886 10.8578C16.3377 10.8578 14.7563 12.4393 14.7563 14.3901C14.7563 16.3409 16.3377 17.9224 18.2886 17.9224ZM18.2886 18.0637C20.3174 18.0637 21.9621 16.4189 21.9621 14.3901C21.9621 12.3612 20.3174 10.7165 18.2886 10.7165C16.2597 10.7165 14.615 12.3612 14.615 14.3901C14.615 16.4189 16.2597 18.0637 18.2886 18.0637ZM19.6294 13.7093C19.6582 14.0003 19.5535 14.2066 19.3152 14.3281C19.5023 14.3729 19.6422 14.4552 19.735 14.5752C19.8277 14.6951 19.8637 14.8662 19.8429 15.0885C19.8317 15.202 19.8057 15.3019 19.7649 15.3883C19.7242 15.4746 19.6726 15.5458 19.6102 15.6017C19.5479 15.6577 19.4703 15.7045 19.3776 15.7421C19.2848 15.7796 19.1877 15.8072 19.0861 15.8248C18.9846 15.8424 18.8683 15.8544 18.7371 15.8608V16.4724H18.3678V15.8704C18.2399 15.8704 18.1423 15.8696 18.0751 15.868V16.4724H17.7058V15.8608C17.677 15.8608 17.6339 15.8604 17.5763 15.8596C17.5187 15.8588 17.4747 15.8583 17.4444 15.8583H16.9646L17.039 15.4194H17.3053C17.3852 15.4194 17.4316 15.3786 17.4444 15.2971V13.6421C17.4236 13.5334 17.3524 13.479 17.2309 13.479H16.9646V13.0857L17.4731 13.0881C17.5755 13.0881 17.653 13.0873 17.7058 13.0857V12.4812H18.0752V13.0737C18.2063 13.0705 18.3039 13.0689 18.3678 13.0689V12.4812H18.7372V13.0857C18.8635 13.0969 18.9754 13.1148 19.073 13.1396C19.1705 13.1644 19.2609 13.2004 19.344 13.2475C19.4272 13.2947 19.4931 13.3571 19.5419 13.4346C19.5907 13.5122 19.6198 13.6037 19.6294 13.7093ZM19.1137 15.0165C19.1137 14.9589 19.1017 14.9077 19.0778 14.863C19.0538 14.8182 19.0242 14.7814 18.989 14.7526C18.9538 14.7238 18.9079 14.6994 18.8511 14.6795C18.7944 14.6595 18.742 14.6447 18.694 14.6351C18.646 14.6255 18.5869 14.6183 18.5165 14.6135C18.4462 14.6087 18.391 14.6063 18.351 14.6063C18.311 14.6063 18.2595 14.6071 18.1963 14.6087C18.1332 14.6103 18.0952 14.6111 18.0824 14.6111V15.4218C18.0952 15.4218 18.1248 15.4222 18.1711 15.423C18.2175 15.4238 18.2559 15.4242 18.2863 15.4242C18.3166 15.4242 18.359 15.423 18.4134 15.4207C18.4677 15.4183 18.5145 15.4151 18.5537 15.4111C18.5929 15.4071 18.6384 15.4003 18.6904 15.3907C18.7424 15.3811 18.7868 15.3699 18.8235 15.3571C18.8603 15.3443 18.8983 15.3275 18.9375 15.3067C18.9766 15.2859 19.0082 15.2619 19.0322 15.2348C19.0562 15.2076 19.0758 15.1756 19.0909 15.1388C19.1061 15.102 19.1137 15.0613 19.1137 15.0165ZM18.9434 13.8748C18.9434 13.822 18.9335 13.7752 18.9135 13.7344C18.8935 13.6937 18.8691 13.6601 18.8403 13.6337C18.8115 13.6073 18.7731 13.5849 18.7252 13.5665C18.6772 13.5481 18.6332 13.535 18.5933 13.5269C18.5533 13.519 18.5041 13.5125 18.4458 13.5078C18.3874 13.503 18.341 13.501 18.3066 13.5018C18.2723 13.5026 18.2291 13.5033 18.1771 13.5042C18.1252 13.505 18.0936 13.5054 18.0824 13.5054V14.2417C18.0904 14.2417 18.118 14.2421 18.1651 14.2429C18.2123 14.2437 18.2495 14.2437 18.2767 14.2429C18.3039 14.2421 18.3438 14.2405 18.3966 14.2381C18.4493 14.2357 18.4933 14.2313 18.5285 14.2249C18.5637 14.2185 18.6049 14.2097 18.652 14.1985C18.6992 14.1873 18.738 14.1726 18.7684 14.1542C18.7987 14.1358 18.8283 14.1142 18.8571 14.0894C18.8859 14.0646 18.9075 14.0338 18.9218 13.9971C18.9362 13.9603 18.9434 13.9195 18.9434 13.8748ZM9.43337 11.8271L11.7757 7.85548L14.118 11.8271L11.7757 12.9776L9.43337 11.8271ZM11.7757 13.453L9.43337 12.1612L11.7757 15.7092L13.8623 12.5486L14.118 12.1612L13.8058 12.3334L12.9469 12.8071L11.7757 13.453Z'\n        fill={props.fill}\n      />\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M18.8374 7.18449C18.8611 7.20817 18.917 7.23337 19.04 7.21548C19.1598 7.19804 19.3159 7.14271 19.4994 7.04719C19.8651 6.85694 20.311 6.52261 20.7464 6.08725C21.1818 5.65189 21.5161 5.20593 21.7063 4.84029C21.8019 4.6567 21.8572 4.50069 21.8746 4.38085C21.8925 4.25785 21.8673 4.20194 21.8436 4.17826C21.82 4.15457 21.7641 4.12937 21.641 4.14727C21.5212 4.1647 21.3652 4.22004 21.1816 4.31556C20.816 4.50581 20.37 4.84014 19.9346 5.2755C19.4993 5.71085 19.165 6.15681 18.9747 6.52245C18.8792 6.70604 18.8239 6.86206 18.8064 6.98189C18.7885 7.1049 18.8137 7.1608 18.8374 7.18449ZM18.9786 7.36255C19.3915 7.35184 20.1378 6.89571 20.8463 6.18716C21.5584 5.47511 22.0155 4.72501 22.0218 4.31334C22.2389 4.54001 22.3939 4.79838 22.3403 5.07634C22.2744 5.41826 22.0457 5.94788 21.3609 6.63274C20.7422 7.2514 20.2333 7.51468 19.8735 7.62205C19.5584 7.71607 19.2484 7.58503 18.9786 7.36255ZM18.7046 7.24293C18.503 6.92061 18.9891 6.02127 19.8347 5.17559C20.6804 4.32991 21.5798 3.8438 21.9021 4.04542L21.9283 4.01922L22.0864 4.17732C22.3267 4.41763 22.5499 4.7356 22.4791 5.10308C22.4065 5.47946 22.1601 6.0333 21.4608 6.73265C20.8288 7.36464 20.3002 7.64216 19.9139 7.75744C19.4593 7.8931 19.0375 7.63468 18.7264 7.32359L18.6751 7.27236L18.7046 7.24293ZM6.81501 19.0908C6.75075 19.1551 6.63011 19.1929 6.42479 19.163C6.22265 19.1336 5.96674 19.0417 5.67226 18.8885C5.08483 18.5828 4.37307 18.0485 3.68045 17.3559C2.98783 16.6632 2.45349 15.9515 2.14785 15.3641C1.99462 15.0696 1.90274 14.8137 1.87333 14.6115C1.84346 14.4062 1.88126 14.2856 1.94553 14.2213C2.0098 14.157 2.13044 14.1192 2.33575 14.1491C2.53789 14.1785 2.7938 14.2704 3.08828 14.4236C3.67571 14.7293 4.38747 15.2636 5.08009 15.9562C5.77271 16.6488 6.30705 17.3606 6.6127 17.948C6.76592 18.2425 6.8578 18.4984 6.88721 18.7006C6.91708 18.9059 6.87928 19.0265 6.81501 19.0908ZM3.58054 17.4558C4.74888 18.6241 5.982 19.3584 6.61471 19.3125L6.5323 19.3949C6.23141 19.6958 5.86622 19.9101 5.47164 19.8478C4.89823 19.7573 3.94846 19.4 2.73784 18.1893C1.44385 16.8954 1.17032 15.9451 1.14234 15.424C1.12598 15.1194 1.30555 14.8499 1.53956 14.6159L1.72306 14.4324C1.68624 15.0683 2.41882 16.2941 3.58054 17.4558ZM5.18 15.8563C3.84282 14.5191 2.42077 13.7505 1.91115 14.0693L1.89874 14.0569L1.43965 14.516C1.19816 14.7575 0.981549 15.0647 1.00125 15.4316C1.03157 15.9963 1.32635 16.9777 2.63793 18.2893C3.86532 19.5166 4.84114 19.8913 5.44961 19.9874C5.91145 20.0603 6.32002 19.8071 6.63221 19.4949L6.98444 19.1426L6.96697 19.1252C7.28581 18.6155 6.51719 17.1935 5.18 15.8563ZM6.26325 18.5389C6.25182 18.5504 6.20073 18.5782 6.04931 18.5393C5.90849 18.5032 5.72321 18.4191 5.5042 18.2878C5.06809 18.0262 4.52585 17.5941 3.98401 17.0522C3.44216 16.5104 3.01003 15.9682 2.74849 15.532C2.61715 15.313 2.53308 15.1278 2.49695 14.9869C2.45809 14.8355 2.48588 14.7844 2.49731 14.773C2.50873 14.7616 2.55982 14.7338 2.71124 14.7726C2.85206 14.8088 3.03734 14.8928 3.25635 15.0242C3.69246 15.2857 4.2347 15.7179 4.77655 16.2597C5.31839 16.8015 5.75053 17.3438 6.01206 17.7799C6.1434 17.9989 6.22747 18.1842 6.26361 18.325C6.30246 18.4764 6.27467 18.5275 6.26325 18.5389ZM6.36315 18.6389C6.08912 18.9129 4.97921 18.2473 3.8841 17.1522C2.78899 16.057 2.12337 14.9471 2.3974 14.6731C2.67143 14.3991 3.78134 15.0647 4.87645 16.1598C5.97157 17.2549 6.63719 18.3648 6.36315 18.6389ZM19.1893 6.83257C19.1879 6.82102 19.1878 6.79616 19.1997 6.74981C19.2208 6.66769 19.2711 6.55543 19.353 6.41886C19.5157 6.14765 19.786 5.80802 20.1266 5.46744C20.4672 5.12685 20.8068 4.85651 21.078 4.69386C21.2146 4.61196 21.3268 4.56161 21.409 4.54054C21.4553 4.52864 21.4802 4.52874 21.4917 4.5301C21.4931 4.54165 21.4932 4.5665 21.4813 4.61286C21.4602 4.69497 21.4099 4.80724 21.328 4.94381C21.1653 5.21502 20.895 5.55464 20.5544 5.89523C20.2138 6.23581 19.8742 6.50616 19.603 6.66881C19.4664 6.75071 19.3541 6.80106 19.272 6.82213C19.2257 6.83402 19.2008 6.83392 19.1893 6.83257ZM20.6543 5.99514C19.9617 6.68773 19.2597 7.1087 19.0864 6.93539C18.9131 6.76208 19.3341 6.06013 20.0267 5.36753C20.7193 4.67493 21.4212 4.25397 21.5945 4.42728C21.7679 4.60059 21.3469 5.30254 20.6543 5.99514Z'\n        fill='#446EFF'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const DualChartDD = (props) => {\n  return (\n    <svg {...props} viewBox='0 0 311 122' aria-hidden='true'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M1.49519 1H0V0H1.49519V1ZM7.47596 1H4.48558V0H7.47596V1ZM13.4567 1H10.4663V0H13.4567V1ZM19.4375 1H16.4471V0H19.4375V1ZM25.4183 1H22.4279V0H25.4183V1ZM31.399 1H28.4087V0H31.399V1ZM37.3798 1H34.3894V0H37.3798V1ZM43.3606 1H40.3702V0H43.3606V1ZM49.3413 1H46.351V0H49.3413V1ZM55.3221 1H52.3317V0H55.3221V1ZM61.3029 1H58.3125V0H61.3029V1ZM67.2836 1H64.2933V0H67.2836V1ZM73.2644 1H70.274V0H73.2644V1ZM79.2452 1H76.2548V0H79.2452V1ZM85.226 1H82.2356V0H85.226V1ZM91.2067 1H88.2164V0H91.2067V1ZM97.1875 1H94.1971V0H97.1875V1ZM103.168 1H100.178V0H103.168V1ZM109.149 1H106.159V0H109.149V1ZM115.13 1H112.139V0H115.13V1ZM121.111 1H118.12V0H121.111V1ZM127.091 1H124.101V0H127.091V1ZM133.072 1H130.082V0H133.072V1ZM139.053 1H136.063V0H139.053V1ZM145.034 1H142.043V0H145.034V1ZM151.014 1H148.024V0H151.014V1ZM156.995 1H154.005V0H156.995V1ZM162.976 1H159.986V0H162.976V1ZM168.957 1H165.966V0H168.957V1ZM174.938 1H171.947V0H174.938V1ZM180.918 1H177.928V0H180.918V1ZM186.899 1H183.909V0H186.899V1ZM192.88 1H189.89V0H192.88V1ZM198.861 1H195.87V0H198.861V1ZM204.841 1H201.851V0H204.841V1ZM210.822 1H207.832V0H210.822V1ZM216.803 1H213.813V0H216.803V1ZM222.784 1H219.793V0H222.784V1ZM228.765 1H225.774V0H228.765V1ZM234.745 1H231.755V0H234.745V1ZM240.726 1H237.736V0H240.726V1ZM246.707 1H243.716V0H246.707V1ZM252.688 1H249.697V0H252.688V1ZM258.668 1H255.678V0H258.668V1ZM264.649 1H261.659V0H264.649V1ZM270.63 1H267.64V0H270.63V1ZM276.611 1H273.62V0H276.611V1ZM282.591 1H279.601V0H282.591V1ZM288.572 1H285.582V0H288.572V1ZM294.553 1H291.563V0H294.553V1ZM300.534 1H297.543V0H300.534V1ZM306.515 1H303.524V0H306.515V1ZM311 1H309.505V0H311V1ZM1.49519 122H0V121H1.49519V122ZM7.47596 122H4.48558V121H7.47596V122ZM13.4567 122H10.4663V121H13.4567V122ZM19.4375 122H16.4471V121H19.4375V122ZM25.4183 122H22.4279V121H25.4183V122ZM31.399 122H28.4087V121H31.399V122ZM37.3798 122H34.3894V121H37.3798V122ZM43.3606 122H40.3702V121H43.3606V122ZM49.3413 122H46.351V121H49.3413V122ZM55.3221 122H52.3317V121H55.3221V122ZM61.3029 122H58.3125V121H61.3029V122ZM67.2836 122H64.2933V121H67.2836V122ZM73.2644 122H70.274V121H73.2644V122ZM79.2452 122H76.2548V121H79.2452V122ZM85.226 122H82.2356V121H85.226V122ZM91.2067 122H88.2164V121H91.2067V122ZM97.1875 122H94.1971V121H97.1875V122ZM103.168 122H100.178V121H103.168V122ZM109.149 122H106.159V121H109.149V122ZM115.13 122H112.139V121H115.13V122ZM121.111 122H118.12V121H121.111V122ZM127.091 122H124.101V121H127.091V122ZM133.072 122H130.082V121H133.072V122ZM139.053 122H136.063V121H139.053V122ZM145.034 122H142.043V121H145.034V122ZM151.014 122H148.024V121H151.014V122ZM156.995 122H154.005V121H156.995V122ZM162.976 122H159.986V121H162.976V122ZM168.957 122H165.966V121H168.957V122ZM174.938 122H171.947V121H174.938V122ZM180.918 122H177.928V121H180.918V122ZM186.899 122H183.909V121H186.899V122ZM192.88 122H189.89V121H192.88V122ZM198.861 122H195.87V121H198.861V122ZM204.841 122H201.851V121H204.841V122ZM210.822 122H207.832V121H210.822V122ZM216.803 122H213.813V121H216.803V122ZM222.784 122H219.793V121H222.784V122ZM228.765 122H225.774V121H228.765V122ZM234.745 122H231.755V121H234.745V122ZM240.726 122H237.736V121H240.726V122ZM246.707 122H243.716V121H246.707V122ZM252.688 122H249.697V121H252.688V122ZM258.668 122H255.678V121H258.668V122ZM264.649 122H261.659V121H264.649V122ZM270.63 122H267.64V121H270.63V122ZM276.611 122H273.62V121H276.611V122ZM282.591 122H279.601V121H282.591V122ZM288.572 122H285.582V121H288.572V122ZM294.553 122H291.563V121H294.553V122ZM300.534 122H297.543V121H300.534V122ZM306.515 122H303.524V121H306.515V122ZM311 122H309.505V121H311V122ZM0 62H1.47222V61H0V62ZM4.41667 62H7.36111V61H4.41667V62ZM10.3056 62H13.25V61H10.3056V62ZM16.1944 62H19.1389V61H16.1944V62ZM22.0833 62H25.0278V61H22.0833V62ZM27.9722 62H30.9167V61H27.9722V62ZM33.8611 62H36.8056V61H33.8611V62ZM39.75 62H42.6944V61H39.75V62ZM45.6389 62H48.5833V61H45.6389V62ZM51.5278 62H54.4722V61H51.5278V62ZM57.4167 62H60.3611V61H57.4167V62ZM63.3055 62H66.25V61H63.3055V62ZM69.1944 62H72.1389V61H69.1944V62ZM75.0833 62H78.0278V61H75.0833V62ZM80.9722 62H83.9166V61H80.9722V62ZM86.8611 62H89.8055V61H86.8611V62ZM92.75 62H95.6944V61H92.75V62ZM98.6389 62H101.583V61H98.6389V62ZM104.528 62H107.472V61H104.528V62ZM110.417 62H113.361V61H110.417V62ZM116.306 62H119.25V61H116.306V62ZM122.194 62H125.139V61H122.194V62ZM128.083 62H131.028V61H128.083V62ZM133.972 62H136.917V61H133.972V62ZM139.861 62H142.805V61H139.861V62ZM145.75 62H148.694V61H145.75V62ZM151.639 62H154.583V61H151.639V62ZM157.528 62H159V61H157.528V62Z'\n        fill='#DFE3EC'\n      />\n      <path d='M159 1H311V61H159V1Z' fill='#00BBA8' fillOpacity='0.1' />\n      <path fillRule='evenodd' clipRule='evenodd' d='M157.5 1H159V61H157.5V1Z' fill='#00BBA8' />\n      <path d='M159 61H311V121H159V61Z' fill='#FBA95C' fillOpacity='0.1' />\n      <path fillRule='evenodd' clipRule='evenodd' d='M157.5 61H159V121H157.5V61Z' fill='#FBA95C' />\n      <circle cx='5' cy='72' r='4.25' stroke='#FBA95C' stroke-width='1.5' />\n      <circle cx='159' cy='89' r='4.25' fill='white' stroke='#FBA95C' stroke-width='1.5' />\n      <path\n        d='M8.5 70C12.5 68.5 23.8 48.8016 37 62.0016C53.5 78.5016 77 82.5013 100 52.5013C123 22.5013 147.5 47.5 157 85'\n        stroke='#FBA95C'\n        stroke-width='1.5'\n      />\n    </svg>\n  )\n}\nexport const DualChartDH = (props) => {\n  return (\n    <svg {...props} viewBox='0 0 311 122' aria-hidden='true'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M1.49519 1H0V0H1.49519V1ZM7.47596 1H4.48558V0H7.47596V1ZM13.4567 1H10.4663V0H13.4567V1ZM19.4375 1H16.4471V0H19.4375V1ZM25.4183 1H22.4279V0H25.4183V1ZM31.399 1H28.4087V0H31.399V1ZM37.3798 1H34.3894V0H37.3798V1ZM43.3606 1H40.3702V0H43.3606V1ZM49.3413 1H46.351V0H49.3413V1ZM55.3221 1H52.3317V0H55.3221V1ZM61.3029 1H58.3125V0H61.3029V1ZM67.2836 1H64.2933V0H67.2836V1ZM73.2644 1H70.274V0H73.2644V1ZM79.2452 1H76.2548V0H79.2452V1ZM85.226 1H82.2356V0H85.226V1ZM91.2067 1H88.2164V0H91.2067V1ZM97.1875 1H94.1971V0H97.1875V1ZM103.168 1H100.178V0H103.168V1ZM109.149 1H106.159V0H109.149V1ZM115.13 1H112.139V0H115.13V1ZM121.111 1H118.12V0H121.111V1ZM127.091 1H124.101V0H127.091V1ZM133.072 1H130.082V0H133.072V1ZM139.053 1H136.063V0H139.053V1ZM145.034 1H142.043V0H145.034V1ZM151.014 1H148.024V0H151.014V1ZM156.995 1H154.005V0H156.995V1ZM162.976 1H159.986V0H162.976V1ZM168.957 1H165.966V0H168.957V1ZM174.938 1H171.947V0H174.938V1ZM180.918 1H177.928V0H180.918V1ZM186.899 1H183.909V0H186.899V1ZM192.88 1H189.89V0H192.88V1ZM198.861 1H195.87V0H198.861V1ZM204.841 1H201.851V0H204.841V1ZM210.822 1H207.832V0H210.822V1ZM216.803 1H213.813V0H216.803V1ZM222.784 1H219.793V0H222.784V1ZM228.765 1H225.774V0H228.765V1ZM234.745 1H231.755V0H234.745V1ZM240.726 1H237.736V0H240.726V1ZM246.707 1H243.716V0H246.707V1ZM252.688 1H249.697V0H252.688V1ZM258.668 1H255.678V0H258.668V1ZM264.649 1H261.659V0H264.649V1ZM270.63 1H267.64V0H270.63V1ZM276.611 1H273.62V0H276.611V1ZM282.591 1H279.601V0H282.591V1ZM288.572 1H285.582V0H288.572V1ZM294.553 1H291.563V0H294.553V1ZM300.534 1H297.543V0H300.534V1ZM306.515 1H303.524V0H306.515V1ZM311 1H309.505V0H311V1ZM1.49519 122H0V121H1.49519V122ZM7.47596 122H4.48558V121H7.47596V122ZM13.4567 122H10.4663V121H13.4567V122ZM19.4375 122H16.4471V121H19.4375V122ZM25.4183 122H22.4279V121H25.4183V122ZM31.399 122H28.4087V121H31.399V122ZM37.3798 122H34.3894V121H37.3798V122ZM43.3606 122H40.3702V121H43.3606V122ZM49.3413 122H46.351V121H49.3413V122ZM55.3221 122H52.3317V121H55.3221V122ZM61.3029 122H58.3125V121H61.3029V122ZM67.2836 122H64.2933V121H67.2836V122ZM73.2644 122H70.274V121H73.2644V122ZM79.2452 122H76.2548V121H79.2452V122ZM85.226 122H82.2356V121H85.226V122ZM91.2067 122H88.2164V121H91.2067V122ZM97.1875 122H94.1971V121H97.1875V122ZM103.168 122H100.178V121H103.168V122ZM109.149 122H106.159V121H109.149V122ZM115.13 122H112.139V121H115.13V122ZM121.111 122H118.12V121H121.111V122ZM127.091 122H124.101V121H127.091V122ZM133.072 122H130.082V121H133.072V122ZM139.053 122H136.063V121H139.053V122ZM145.034 122H142.043V121H145.034V122ZM151.014 122H148.024V121H151.014V122ZM156.995 122H154.005V121H156.995V122ZM162.976 122H159.986V121H162.976V122ZM168.957 122H165.966V121H168.957V122ZM174.938 122H171.947V121H174.938V122ZM180.918 122H177.928V121H180.918V122ZM186.899 122H183.909V121H186.899V122ZM192.88 122H189.89V121H192.88V122ZM198.861 122H195.87V121H198.861V122ZM204.841 122H201.851V121H204.841V122ZM210.822 122H207.832V121H210.822V122ZM216.803 122H213.813V121H216.803V122ZM222.784 122H219.793V121H222.784V122ZM228.765 122H225.774V121H228.765V122ZM234.745 122H231.755V121H234.745V122ZM240.726 122H237.736V121H240.726V122ZM246.707 122H243.716V121H246.707V122ZM252.688 122H249.697V121H252.688V122ZM258.668 122H255.678V121H258.668V122ZM264.649 122H261.659V121H264.649V122ZM270.63 122H267.64V121H270.63V122ZM276.611 122H273.62V121H276.611V122ZM282.591 122H279.601V121H282.591V122ZM288.572 122H285.582V121H288.572V122ZM294.553 122H291.563V121H294.553V122ZM300.534 122H297.543V121H300.534V122ZM306.515 122H303.524V121H306.515V122ZM311 122H309.505V121H311V122ZM0 62H1.47222V61H0V62ZM4.41667 62H7.36111V61H4.41667V62ZM10.3056 62H13.25V61H10.3056V62ZM16.1944 62H19.1389V61H16.1944V62ZM22.0833 62H25.0278V61H22.0833V62ZM27.9722 62H30.9167V61H27.9722V62ZM33.8611 62H36.8056V61H33.8611V62ZM39.75 62H42.6944V61H39.75V62ZM45.6389 62H48.5833V61H45.6389V62ZM51.5278 62H54.4722V61H51.5278V62ZM57.4167 62H60.3611V61H57.4167V62ZM63.3055 62H66.25V61H63.3055V62ZM69.1944 62H72.1389V61H69.1944V62ZM75.0833 62H78.0278V61H75.0833V62ZM80.9722 62H83.9166V61H80.9722V62ZM86.8611 62H89.8055V61H86.8611V62ZM92.75 62H95.6944V61H92.75V62ZM98.6389 62H101.583V61H98.6389V62ZM104.528 62H107.472V61H104.528V62ZM110.417 62H113.361V61H110.417V62ZM116.306 62H119.25V61H116.306V62ZM122.194 62H125.139V61H122.194V62ZM128.083 62H131.028V61H128.083V62ZM133.972 62H136.917V61H133.972V62ZM139.861 62H142.805V61H139.861V62ZM145.75 62H148.694V61H145.75V62ZM151.639 62H154.583V61H151.639V62ZM157.528 62H159V61H157.528V62Z'\n        fill='#DFE3EC'\n      />\n      <path d='M159 1H311V61H159V1Z' fill='#00BBA8' fillOpacity='0.1' />\n      <path fillRule='evenodd' clipRule='evenodd' d='M157.5 1H159V61H157.5V1Z' fill='#00BBA8' />\n      <path d='M159 61H311V121H159V61Z' fill='#FBA95C' fillOpacity='0.1' />\n      <path fillRule='evenodd' clipRule='evenodd' d='M157.5 61H159V121H157.5V61Z' fill='#FBA95C' />\n      <circle cx='5' cy='75' r='4.25' fill='white' stroke='#00BBA8' stroke-width='1.5' />\n      <circle cx='158' cy='31' r='4.25' fill='white' stroke='#00BBA8' stroke-width='1.5' />\n      <path\n        d='M9 75.5001C13 77.0001 23.8 73.2252 37 60.0252C53.5 43.5252 77 39.5255 100 69.5255C123 99.5255 148 73.0274 157.5 35.5274'\n        stroke='#00BBA8'\n        stroke-width='1.5'\n      />\n    </svg>\n  )\n}\n\nexport const DualChartHD = (props) => {\n  return (\n    <svg {...props} viewBox='0 0 311 122' aria-hidden='true'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M1.49519 1H0V0H1.49519V1ZM7.47596 1H4.48558V0H7.47596V1ZM13.4567 1H10.4663V0H13.4567V1ZM19.4375 1H16.4471V0H19.4375V1ZM25.4183 1H22.4279V0H25.4183V1ZM31.399 1H28.4087V0H31.399V1ZM37.3798 1H34.3894V0H37.3798V1ZM43.3606 1H40.3702V0H43.3606V1ZM49.3413 1H46.351V0H49.3413V1ZM55.3221 1H52.3317V0H55.3221V1ZM61.3029 1H58.3125V0H61.3029V1ZM67.2836 1H64.2933V0H67.2836V1ZM73.2644 1H70.274V0H73.2644V1ZM79.2452 1H76.2548V0H79.2452V1ZM85.226 1H82.2356V0H85.226V1ZM91.2067 1H88.2164V0H91.2067V1ZM97.1875 1H94.1971V0H97.1875V1ZM103.168 1H100.178V0H103.168V1ZM109.149 1H106.159V0H109.149V1ZM115.13 1H112.139V0H115.13V1ZM121.111 1H118.12V0H121.111V1ZM127.091 1H124.101V0H127.091V1ZM133.072 1H130.082V0H133.072V1ZM139.053 1H136.063V0H139.053V1ZM145.034 1H142.043V0H145.034V1ZM151.014 1H148.024V0H151.014V1ZM156.995 1H154.005V0H156.995V1ZM162.976 1H159.986V0H162.976V1ZM168.957 1H165.966V0H168.957V1ZM174.938 1H171.947V0H174.938V1ZM180.918 1H177.928V0H180.918V1ZM186.899 1H183.909V0H186.899V1ZM192.88 1H189.89V0H192.88V1ZM198.861 1H195.87V0H198.861V1ZM204.841 1H201.851V0H204.841V1ZM210.822 1H207.832V0H210.822V1ZM216.803 1H213.813V0H216.803V1ZM222.784 1H219.793V0H222.784V1ZM228.765 1H225.774V0H228.765V1ZM234.745 1H231.755V0H234.745V1ZM240.726 1H237.736V0H240.726V1ZM246.707 1H243.716V0H246.707V1ZM252.688 1H249.697V0H252.688V1ZM258.668 1H255.678V0H258.668V1ZM264.649 1H261.659V0H264.649V1ZM270.63 1H267.64V0H270.63V1ZM276.611 1H273.62V0H276.611V1ZM282.591 1H279.601V0H282.591V1ZM288.572 1H285.582V0H288.572V1ZM294.553 1H291.563V0H294.553V1ZM300.534 1H297.543V0H300.534V1ZM306.515 1H303.524V0H306.515V1ZM311 1H309.505V0H311V1ZM1.49519 122H0V121H1.49519V122ZM7.47596 122H4.48558V121H7.47596V122ZM13.4567 122H10.4663V121H13.4567V122ZM19.4375 122H16.4471V121H19.4375V122ZM25.4183 122H22.4279V121H25.4183V122ZM31.399 122H28.4087V121H31.399V122ZM37.3798 122H34.3894V121H37.3798V122ZM43.3606 122H40.3702V121H43.3606V122ZM49.3413 122H46.351V121H49.3413V122ZM55.3221 122H52.3317V121H55.3221V122ZM61.3029 122H58.3125V121H61.3029V122ZM67.2836 122H64.2933V121H67.2836V122ZM73.2644 122H70.274V121H73.2644V122ZM79.2452 122H76.2548V121H79.2452V122ZM85.226 122H82.2356V121H85.226V122ZM91.2067 122H88.2164V121H91.2067V122ZM97.1875 122H94.1971V121H97.1875V122ZM103.168 122H100.178V121H103.168V122ZM109.149 122H106.159V121H109.149V122ZM115.13 122H112.139V121H115.13V122ZM121.111 122H118.12V121H121.111V122ZM127.091 122H124.101V121H127.091V122ZM133.072 122H130.082V121H133.072V122ZM139.053 122H136.063V121H139.053V122ZM145.034 122H142.043V121H145.034V122ZM151.014 122H148.024V121H151.014V122ZM156.995 122H154.005V121H156.995V122ZM162.976 122H159.986V121H162.976V122ZM168.957 122H165.966V121H168.957V122ZM174.938 122H171.947V121H174.938V122ZM180.918 122H177.928V121H180.918V122ZM186.899 122H183.909V121H186.899V122ZM192.88 122H189.89V121H192.88V122ZM198.861 122H195.87V121H198.861V122ZM204.841 122H201.851V121H204.841V122ZM210.822 122H207.832V121H210.822V122ZM216.803 122H213.813V121H216.803V122ZM222.784 122H219.793V121H222.784V122ZM228.765 122H225.774V121H228.765V122ZM234.745 122H231.755V121H234.745V122ZM240.726 122H237.736V121H240.726V122ZM246.707 122H243.716V121H246.707V122ZM252.688 122H249.697V121H252.688V122ZM258.668 122H255.678V121H258.668V122ZM264.649 122H261.659V121H264.649V122ZM270.63 122H267.64V121H270.63V122ZM276.611 122H273.62V121H276.611V122ZM282.591 122H279.601V121H282.591V122ZM288.572 122H285.582V121H288.572V122ZM294.553 122H291.563V121H294.553V122ZM300.534 122H297.543V121H300.534V122ZM306.515 122H303.524V121H306.515V122ZM311 122H309.505V121H311V122ZM0 62H1.47222V61H0V62ZM4.41667 62H7.36111V61H4.41667V62ZM10.3056 62H13.25V61H10.3056V62ZM16.1944 62H19.1389V61H16.1944V62ZM22.0833 62H25.0278V61H22.0833V62ZM27.9722 62H30.9167V61H27.9722V62ZM33.8611 62H36.8056V61H33.8611V62ZM39.75 62H42.6944V61H39.75V62ZM45.6389 62H48.5833V61H45.6389V62ZM51.5278 62H54.4722V61H51.5278V62ZM57.4167 62H60.3611V61H57.4167V62ZM63.3055 62H66.25V61H63.3055V62ZM69.1944 62H72.1389V61H69.1944V62ZM75.0833 62H78.0278V61H75.0833V62ZM80.9722 62H83.9166V61H80.9722V62ZM86.8611 62H89.8055V61H86.8611V62ZM92.75 62H95.6944V61H92.75V62ZM98.6389 62H101.583V61H98.6389V62ZM104.528 62H107.472V61H104.528V62ZM110.417 62H113.361V61H110.417V62ZM116.306 62H119.25V61H116.306V62ZM122.194 62H125.139V61H122.194V62ZM128.083 62H131.028V61H128.083V62ZM133.972 62H136.917V61H133.972V62ZM139.861 62H142.805V61H139.861V62ZM145.75 62H148.694V61H145.75V62ZM151.639 62H154.583V61H151.639V62ZM157.528 62H159V61H157.528V62Z'\n        fill='#DFE3EC'\n      />\n      <path d='M159 1H311V61H159V1Z' fill='#00BBA8' fillOpacity='0.1' />\n      <path fillRule='evenodd' clipRule='evenodd' d='M157.5 1H159V61H157.5V1Z' fill='#00BBA8' />\n      <path d='M159 61H311V121H159V61Z' fill='#FBA95C' fillOpacity='0.1' />\n      <path fillRule='evenodd' clipRule='evenodd' d='M157.5 61H159V121H157.5V61Z' fill='#FBA95C' />\n      <circle cx='5' cy='51' r='4.25' fill='white' stroke='#FBA95C' stroke-width='1.5' />\n      <circle cx='159' cy='89' r='4.25' fill='white' stroke='#FBA95C' stroke-width='1.5' />\n      <path\n        d='M8.5 50.0016C12.5 48.5016 23.8 48.8016 37 62.0016C53.5 78.5016 77 82.5013 100 52.5013C123 22.5013 147.5 47.5 157 85'\n        stroke='#FBA95C'\n        stroke-width='1.5'\n      />\n    </svg>\n  )\n}\n\nexport const DualChartHH = (props) => {\n  return (\n    <svg {...props} viewBox='0 0 311 122' aria-hidden='true'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M1.49519 1H0V0H1.49519V1ZM7.47596 1H4.48558V0H7.47596V1ZM13.4567 1H10.4663V0H13.4567V1ZM19.4375 1H16.4471V0H19.4375V1ZM25.4183 1H22.4279V0H25.4183V1ZM31.399 1H28.4087V0H31.399V1ZM37.3798 1H34.3894V0H37.3798V1ZM43.3606 1H40.3702V0H43.3606V1ZM49.3413 1H46.351V0H49.3413V1ZM55.3221 1H52.3317V0H55.3221V1ZM61.3029 1H58.3125V0H61.3029V1ZM67.2836 1H64.2933V0H67.2836V1ZM73.2644 1H70.274V0H73.2644V1ZM79.2452 1H76.2548V0H79.2452V1ZM85.226 1H82.2356V0H85.226V1ZM91.2067 1H88.2164V0H91.2067V1ZM97.1875 1H94.1971V0H97.1875V1ZM103.168 1H100.178V0H103.168V1ZM109.149 1H106.159V0H109.149V1ZM115.13 1H112.139V0H115.13V1ZM121.111 1H118.12V0H121.111V1ZM127.091 1H124.101V0H127.091V1ZM133.072 1H130.082V0H133.072V1ZM139.053 1H136.063V0H139.053V1ZM145.034 1H142.043V0H145.034V1ZM151.014 1H148.024V0H151.014V1ZM156.995 1H154.005V0H156.995V1ZM162.976 1H159.986V0H162.976V1ZM168.957 1H165.966V0H168.957V1ZM174.938 1H171.947V0H174.938V1ZM180.918 1H177.928V0H180.918V1ZM186.899 1H183.909V0H186.899V1ZM192.88 1H189.89V0H192.88V1ZM198.861 1H195.87V0H198.861V1ZM204.841 1H201.851V0H204.841V1ZM210.822 1H207.832V0H210.822V1ZM216.803 1H213.813V0H216.803V1ZM222.784 1H219.793V0H222.784V1ZM228.765 1H225.774V0H228.765V1ZM234.745 1H231.755V0H234.745V1ZM240.726 1H237.736V0H240.726V1ZM246.707 1H243.716V0H246.707V1ZM252.688 1H249.697V0H252.688V1ZM258.668 1H255.678V0H258.668V1ZM264.649 1H261.659V0H264.649V1ZM270.63 1H267.64V0H270.63V1ZM276.611 1H273.62V0H276.611V1ZM282.591 1H279.601V0H282.591V1ZM288.572 1H285.582V0H288.572V1ZM294.553 1H291.563V0H294.553V1ZM300.534 1H297.543V0H300.534V1ZM306.515 1H303.524V0H306.515V1ZM311 1H309.505V0H311V1ZM1.49519 122H0V121H1.49519V122ZM7.47596 122H4.48558V121H7.47596V122ZM13.4567 122H10.4663V121H13.4567V122ZM19.4375 122H16.4471V121H19.4375V122ZM25.4183 122H22.4279V121H25.4183V122ZM31.399 122H28.4087V121H31.399V122ZM37.3798 122H34.3894V121H37.3798V122ZM43.3606 122H40.3702V121H43.3606V122ZM49.3413 122H46.351V121H49.3413V122ZM55.3221 122H52.3317V121H55.3221V122ZM61.3029 122H58.3125V121H61.3029V122ZM67.2836 122H64.2933V121H67.2836V122ZM73.2644 122H70.274V121H73.2644V122ZM79.2452 122H76.2548V121H79.2452V122ZM85.226 122H82.2356V121H85.226V122ZM91.2067 122H88.2164V121H91.2067V122ZM97.1875 122H94.1971V121H97.1875V122ZM103.168 122H100.178V121H103.168V122ZM109.149 122H106.159V121H109.149V122ZM115.13 122H112.139V121H115.13V122ZM121.111 122H118.12V121H121.111V122ZM127.091 122H124.101V121H127.091V122ZM133.072 122H130.082V121H133.072V122ZM139.053 122H136.063V121H139.053V122ZM145.034 122H142.043V121H145.034V122ZM151.014 122H148.024V121H151.014V122ZM156.995 122H154.005V121H156.995V122ZM162.976 122H159.986V121H162.976V122ZM168.957 122H165.966V121H168.957V122ZM174.938 122H171.947V121H174.938V122ZM180.918 122H177.928V121H180.918V122ZM186.899 122H183.909V121H186.899V122ZM192.88 122H189.89V121H192.88V122ZM198.861 122H195.87V121H198.861V122ZM204.841 122H201.851V121H204.841V122ZM210.822 122H207.832V121H210.822V122ZM216.803 122H213.813V121H216.803V122ZM222.784 122H219.793V121H222.784V122ZM228.765 122H225.774V121H228.765V122ZM234.745 122H231.755V121H234.745V122ZM240.726 122H237.736V121H240.726V122ZM246.707 122H243.716V121H246.707V122ZM252.688 122H249.697V121H252.688V122ZM258.668 122H255.678V121H258.668V122ZM264.649 122H261.659V121H264.649V122ZM270.63 122H267.64V121H270.63V122ZM276.611 122H273.62V121H276.611V122ZM282.591 122H279.601V121H282.591V122ZM288.572 122H285.582V121H288.572V122ZM294.553 122H291.563V121H294.553V122ZM300.534 122H297.543V121H300.534V122ZM306.515 122H303.524V121H306.515V122ZM311 122H309.505V121H311V122ZM0 62H1.47222V61H0V62ZM4.41667 62H7.36111V61H4.41667V62ZM10.3056 62H13.25V61H10.3056V62ZM16.1944 62H19.1389V61H16.1944V62ZM22.0833 62H25.0278V61H22.0833V62ZM27.9722 62H30.9167V61H27.9722V62ZM33.8611 62H36.8056V61H33.8611V62ZM39.75 62H42.6944V61H39.75V62ZM45.6389 62H48.5833V61H45.6389V62ZM51.5278 62H54.4722V61H51.5278V62ZM57.4167 62H60.3611V61H57.4167V62ZM63.3055 62H66.25V61H63.3055V62ZM69.1944 62H72.1389V61H69.1944V62ZM75.0833 62H78.0278V61H75.0833V62ZM80.9722 62H83.9166V61H80.9722V62ZM86.8611 62H89.8055V61H86.8611V62ZM92.75 62H95.6944V61H92.75V62ZM98.6389 62H101.583V61H98.6389V62ZM104.528 62H107.472V61H104.528V62ZM110.417 62H113.361V61H110.417V62ZM116.306 62H119.25V61H116.306V62ZM122.194 62H125.139V61H122.194V62ZM128.083 62H131.028V61H128.083V62ZM133.972 62H136.917V61H133.972V62ZM139.861 62H142.805V61H139.861V62ZM145.75 62H148.694V61H145.75V62ZM151.639 62H154.583V61H151.639V62ZM157.528 62H159V61H157.528V62Z'\n        fill='#DFE3EC'\n      />\n      <path d='M159 1H311V61H159V1Z' fill='#00BBA8' fillOpacity='0.1' />\n      <path fillRule='evenodd' clipRule='evenodd' d='M157.5 1H159V61H157.5V1Z' fill='#00BBA8' />\n      <path d='M159 61H311V121H159V61Z' fill='#FBA95C' fillOpacity='0.1' />\n      <path fillRule='evenodd' clipRule='evenodd' d='M157.5 61H159V121H157.5V61Z' fill='#FBA95C' />\n      <circle cx='5' cy='52' r='4.25' fill='white' stroke='#00BBA8' stroke-width='1.5' />\n      <circle cx='158' cy='31' r='4.25' fill='white' stroke='#00BBA8' stroke-width='1.5' />\n      <path\n        d='M9 53.5001C13 55.0001 23.8 73.2252 37 60.0252C53.5 43.5252 77 39.5255 100 69.5255C123 99.5255 148 73.0274 157.5 35.5274'\n        stroke='#00BBA8'\n        stroke-width='1.5'\n      />\n    </svg>\n  )\n}\n\nexport const VaultIcon = (props) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24' aria-hidden='true'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M3.49602 4.25127L3.03301 3L2.57 4.25127L1.31873 4.71428L2.57 5.1773L3.03301 6.42857L3.49602 5.1773L4.74729 4.71428L3.49602 4.25127ZM17.4507 19.8146C16.391 20.2741 15.2219 20.5288 13.9933 20.5288C12.6549 20.5288 11.387 20.2265 10.2543 19.6865L10.1636 19.7873C11.322 20.3458 12.6211 20.6588 13.9933 20.6588C15.2592 20.6588 16.4628 20.3925 17.5512 19.9127C17.5171 19.8806 17.4836 19.8479 17.4507 19.8146ZM16.8078 18.9474C16.0666 19.2407 15.2686 19.4216 14.4348 19.4691V19.3387C15.247 19.2917 16.0246 19.1159 16.7475 18.8313C16.7669 18.8704 16.7871 18.9091 16.8078 18.9474ZM22.4134 14.0245C22.5957 13.3233 22.6927 12.5877 22.6927 11.8294C22.6927 7.02492 18.7979 3.1301 13.9933 3.1301C9.18884 3.1301 5.29402 7.02492 5.29402 11.8294C5.29402 12.8633 5.47436 13.855 5.8053 14.7748C5.75741 14.7323 5.71115 14.7081 5.64061 14.6987C5.33165 13.7991 5.16392 12.8339 5.16392 11.8294C5.16392 6.95307 9.11699 3 13.9933 3C18.8697 3 22.8228 6.95307 22.8228 11.8294C22.8228 12.6176 22.7195 13.3817 22.5257 14.1089C22.4888 14.0801 22.4514 14.0519 22.4134 14.0245ZM7.95619 18.2724C8.17017 18.473 8.39415 18.663 8.6273 18.8417L8.7146 18.7447C8.48124 18.5663 8.25717 18.3763 8.04325 18.1757L7.95619 18.2724ZM10.9896 18.8695C11.6971 19.1718 12.4595 19.3705 13.2576 19.4467V19.316C12.493 19.2417 11.7619 19.053 11.0816 18.7672L10.9896 18.8695ZM9.50515 17.8664L9.41774 17.9635C7.69752 16.6782 6.53603 14.6863 6.36348 12.418H6.49396C6.66656 14.6478 7.81142 16.6051 9.50515 17.8664ZM21.4577 13.5217C21.4167 13.5071 21.3754 13.4932 21.3338 13.4799C21.4111 13.1344 21.4647 12.7798 21.4927 12.418H21.6232C21.5946 12.7942 21.5388 13.1627 21.4577 13.5217ZM6.36348 11.2408C6.64553 7.5331 9.56982 4.56397 13.2576 4.21216V4.34287C9.64173 4.69389 6.77539 7.60499 6.49396 11.2408H6.36348ZM14.4348 4.18977V4.32008C18.1884 4.53733 21.2037 7.50689 21.4927 11.2408H21.6232C21.3337 7.435 18.2603 4.40738 14.4348 4.18977ZM13.2104 15.6555V7.1204L9.57862 12.8015L13.2104 15.6555ZM20.4682 11.2662H15.8735L16.8502 12.7947L13.2941 15.5946L20.4682 11.2933V11.2662Z'\n        fill={props.secondary}\n      />\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M23.8699 17.1271C23.8699 19.1683 22.2151 20.8231 20.1739 20.8231C18.1326 20.8231 16.4779 19.1683 16.4779 17.1271C16.4779 15.0858 18.1326 13.4311 20.1739 13.4311C22.2151 13.4311 23.8699 15.0858 23.8699 17.1271ZM23.9999 17.1271C23.9999 19.2402 22.287 20.9532 20.1739 20.9532C18.0608 20.9532 16.3478 19.2402 16.3478 17.1271C16.3478 15.014 18.0608 13.301 20.1739 13.301C22.287 13.301 23.9999 15.014 23.9999 17.1271ZM19.155 15.5905H18.0037L19.4695 18.2599L20.0439 17.1647L19.155 15.5905ZM19.4668 17.9848L18.2236 15.7206H19.079L19.8958 17.167L19.4668 17.9848ZM22.6384 15.5905H21.4867L19.7453 18.7258L20.1816 19.5467H20.4598L22.6384 15.5905ZM19.8934 18.7272L21.5633 15.7206H22.4183L20.3829 19.4166H20.2598L19.8934 18.7272Z'\n        fill={props.fill}\n      />\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M11.8592 17.528C11.8992 17.5723 11.9238 17.6279 11.9331 17.6948V17.7307C11.9259 17.7988 11.9006 17.857 11.8571 17.9053C11.0516 18.8006 10.246 19.6958 9.44012 20.5908C9.35111 20.6895 9.29252 20.7374 9.16472 20.7374C8.65429 20.7378 8.14385 20.7378 7.63342 20.7374C7.47665 20.7373 7.35738 20.7194 7.29155 20.5763C7.23812 20.4604 7.27047 20.3497 7.35304 20.2578C8.11338 19.4127 8.87319 18.5684 9.63245 17.7249C9.6347 17.7223 9.63594 17.7191 9.63594 17.7157C9.63594 17.7124 9.6347 17.7092 9.63245 17.7067C8.88574 16.8775 8.1387 16.0473 7.39134 15.2163C7.28801 15.1015 7.22315 14.9972 7.28978 14.8548C7.33871 14.7498 7.42718 14.6971 7.55519 14.6967C8.07851 14.6946 8.60176 14.6937 9.12497 14.6941C9.23281 14.6941 9.32149 14.7085 9.38909 14.7835C10.2125 15.6982 11.0359 16.6131 11.8592 17.528ZM9.34077 14.827C10.1642 15.7417 10.9876 16.6566 11.8109 17.5715C11.8402 17.6041 11.8599 17.6458 11.8681 17.6995V17.7271C11.8618 17.7809 11.8419 17.825 11.8088 17.8618C11.0033 18.7571 10.1976 19.6522 9.39182 20.5472C9.34756 20.5963 9.31646 20.6261 9.28422 20.6449C9.2543 20.6623 9.21951 20.6724 9.16472 20.6724C8.65432 20.6727 8.14388 20.6727 7.63348 20.6724M9.34077 14.827C9.29267 14.7736 9.22884 14.7592 9.12497 14.7592C8.60187 14.7587 8.07867 14.7596 7.55546 14.7617C7.50029 14.7619 7.45818 14.7733 7.42612 14.7924C7.39446 14.8113 7.3684 14.8401 7.34874 14.8822C7.32245 14.9384 7.32323 14.9824 7.33808 15.024C7.35433 15.0695 7.38886 15.1163 7.43968 15.1727C8.18701 16.0038 8.93404 16.8339 9.68073 17.6631C9.69384 17.6776 9.70099 17.6964 9.70099 17.7157C9.70099 17.7351 9.69383 17.7538 9.68105 17.7681C8.9218 18.6116 8.16175 19.4562 7.40142 20.3013C7.33147 20.3791 7.31076 20.4626 7.35062 20.5491C7.37672 20.6058 7.41055 20.6338 7.45192 20.6498C7.49733 20.6675 7.55565 20.6723 7.63348 20.6724'\n        fill={props.primary}\n      />\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M5.6076 20.6721C5.09965 20.6725 4.59182 20.6727 4.08409 20.6726C3.98408 20.6726 3.92663 20.6663 3.90221 20.6583L3.90205 20.6582C3.76466 20.6135 3.71268 20.4323 3.80845 20.3258C4.57682 19.4713 5.34536 18.6174 6.11406 17.7641L6.11421 17.7639C6.12607 17.7507 6.13262 17.7335 6.13262 17.7157C6.13262 17.6979 6.12607 17.6808 6.11421 17.6675L6.11406 17.6674C5.34417 16.8126 4.5781 15.9616 3.81583 15.1145C3.74927 15.0405 3.74508 14.9535 3.77905 14.8841C3.81355 14.8136 3.88849 14.7596 3.98631 14.7592C4.21371 14.7583 4.73894 14.7583 5.5622 14.7592C5.63839 14.7593 5.68064 14.77 5.71437 14.7887C5.75047 14.8087 5.78315 14.841 5.83588 14.8995L8.18507 17.51C8.18508 17.5101 8.18506 17.51 8.18507 17.51C8.24336 17.5749 8.27349 17.6203 8.28411 17.6483C8.29907 17.6882 8.3015 17.7244 8.2937 17.7587C8.2858 17.7935 8.26639 17.8305 8.23127 17.8695C7.41546 18.7758 6.59965 19.6822 5.78383 20.5887C5.73484 20.643 5.67641 20.6721 5.6076 20.6721ZM5.83218 20.6322C6.648 19.7257 7.46382 18.8193 8.27964 17.913C8.36118 17.8224 8.38297 17.7265 8.34498 17.6254C8.32985 17.5854 8.29267 17.5324 8.23344 17.4666L5.88417 14.8559C5.78003 14.7405 5.72692 14.6943 5.56227 14.6941C4.73904 14.6933 4.21364 14.6933 3.98605 14.6941C3.73979 14.6951 3.59735 14.9689 3.76748 15.158C4.52975 16.0052 5.29583 16.8561 6.06573 17.7109C6.06691 17.7122 6.06757 17.7139 6.06757 17.7157C6.06757 17.7175 6.06691 17.7192 6.06573 17.7205C5.29701 18.5739 4.52846 19.4278 3.76007 20.2823C3.63099 20.4258 3.70245 20.6616 3.88192 20.7201C3.91754 20.7318 3.98493 20.7376 4.08407 20.7376C4.59183 20.7377 5.09969 20.7376 5.60765 20.7371C5.69763 20.7371 5.77279 20.698 5.83218 20.6322Z'\n        fill={props.primary}\n        fillOpacity='0.6'\n      />\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M1.91534 20.6721C1.40739 20.6725 0.899556 20.6727 0.391825 20.6726C0.291824 20.6726 0.234367 20.6663 0.209945 20.6583L0.209791 20.6582C0.0723945 20.6135 0.0204213 20.4323 0.116184 20.3258C0.884562 19.4713 1.6531 18.6174 2.4218 17.7641L2.42195 17.7639C2.43381 17.7507 2.44036 17.7335 2.44036 17.7157C2.44036 17.6979 2.43381 17.6808 2.42195 17.6675L2.4218 17.6674C1.65191 16.8126 0.885838 15.9616 0.123571 15.1145C0.0570128 15.0405 0.0528226 14.9535 0.0867853 14.8841C0.121287 14.8136 0.196231 14.7596 0.294046 14.7592C0.52145 14.7583 1.04668 14.7583 1.86994 14.7592C1.94613 14.7593 1.98838 14.77 2.02211 14.7887C2.05821 14.8087 2.09089 14.841 2.14362 14.8995L4.49281 17.51C4.49282 17.5101 4.4928 17.51 4.49281 17.51C4.5511 17.5749 4.58123 17.6203 4.59185 17.6483C4.60681 17.6882 4.60924 17.7244 4.60144 17.7587C4.59353 17.7935 4.57413 17.8305 4.53901 17.8695C3.7232 18.7758 2.90739 19.6822 2.09157 20.5887C2.04258 20.643 1.98415 20.6721 1.91534 20.6721ZM2.13992 20.6322C2.95574 19.7257 3.77156 18.8193 4.58737 17.913C4.66892 17.8224 4.69071 17.7265 4.65272 17.6254C4.63759 17.5854 4.60041 17.5324 4.54118 17.4666L2.19191 14.8559C2.08777 14.7405 2.03466 14.6943 1.87 14.6941C1.04678 14.6933 0.521379 14.6933 0.293791 14.6941C0.0475332 14.6951 -0.0949103 14.9689 0.0752171 15.158C0.837491 16.0052 1.60357 16.8561 2.37347 17.7109C2.37465 17.7122 2.37531 17.7139 2.37531 17.7157C2.37531 17.7175 2.37465 17.7192 2.37347 17.7205C1.60475 18.5739 0.836203 19.4278 0.0678132 20.2823C-0.0612711 20.4258 0.0101921 20.6616 0.189655 20.7201C0.225279 20.7318 0.292665 20.7376 0.391812 20.7376C0.899565 20.7377 1.40743 20.7376 1.91539 20.7371C2.00537 20.7371 2.08053 20.698 2.13992 20.6322Z'\n        fill={props.primary}\n        fillOpacity='0.3'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const ToRightTopArrow = (props: SvgIconProps) => {\n  return (\n    <SvgIcon {...props} viewBox='0 0 24 24' aria-hidden='true'>\n      <path d=\"M16.0037 9.41421L7.39712 18.0208L5.98291 16.6066L14.5895 8H7.00373V6H18.0037V17H16.0037V9.41421Z\" />\n    </SvgIcon>\n  )\n}\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/svg/index.ts",
    "content": "export * from './Icon'\nexport * from './dropdownLogo'\nexport * from './earnLogo'\nexport * from './redPacketSvg'\nexport * from './shareReferral'\nexport * from './network'\nexport * from './redPacketScope'\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/svg/network.tsx",
    "content": "import { SvgIcon, SvgIconProps } from '@mui/material'\n\nexport const ChainGOERLIIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon width='36' height='36' {...props} viewBox='0 0 36 36' fill='none'>\n      <path\n        fillRule='evenodd'\n        clipRule='evenodd'\n        d='M11.1515 19.9674V16.8714L18.357 16.8573V24.2014L18.2059 24.3486C17.2218 25.3074 16.1928 26.0418 15.1171 26.5409L15.1141 26.5423C14.0357 27.034 12.9208 27.2823 11.7734 27.2823C10.2552 27.2823 8.88449 26.9013 7.67647 26.131C6.46528 25.3587 5.51716 24.2376 4.82448 22.7923L4.82386 22.791C4.1347 21.3352 3.80005 19.6075 3.80005 17.6265C3.80005 15.6203 4.1386 13.8481 4.83246 12.3234C5.52024 10.8119 6.4374 9.66267 7.60112 8.91611C8.758 8.16579 10.1151 7.8 11.6515 7.8C12.7864 7.8 13.8038 8.01085 14.6895 8.44927C15.5682 8.88415 16.2944 9.50342 16.8624 10.3022C17.437 11.1102 17.847 12.1874 18.1153 13.5034L18.2036 13.9366L15.5202 14.8373L15.3951 14.3024C15.1655 13.3204 14.8876 12.6431 14.5865 12.2256L14.5842 12.2224C14.2778 11.7907 13.873 11.4499 13.3592 11.2002C12.8501 10.9527 12.268 10.8238 11.6027 10.8238C10.6228 10.8238 9.80499 11.0619 9.12683 11.5187C8.46297 11.9637 7.89796 12.6775 7.45386 13.7029C7.02437 14.7133 6.79945 15.971 6.79945 17.4924C6.79945 19.824 7.28894 21.4797 8.182 22.5474C9.08318 23.6167 10.2415 24.1488 11.7003 24.1488C12.3824 24.1488 13.0917 23.9859 13.8323 23.6458L13.8333 23.6453C14.5153 23.3354 15.0518 22.9813 15.4551 22.5912V19.9674H11.1515ZM21.6803 14.6507C22.9142 13.409 24.4756 12.7936 26.3255 12.7936C28.1488 12.7936 29.6986 13.4107 30.9399 14.6492C32.2041 15.9107 32.8 17.7001 32.8 19.9364C32.8 22.3362 32.2219 24.2206 30.9723 25.4891C29.747 26.7329 28.1843 27.3478 26.3255 27.3478C24.4934 27.3478 22.9384 26.7313 21.6965 25.4922L21.6937 25.4894C20.4383 24.2169 19.851 22.3814 19.851 20.0707C19.851 17.7539 20.4324 15.9176 21.6788 14.6523L21.6803 14.6507ZM23.8086 23.7337C24.5032 24.5058 25.3572 24.8881 26.3832 24.8881C27.3361 24.8881 28.1517 24.5056 28.8395 23.7228C29.5267 22.9435 29.888 21.7539 29.888 20.1183C29.888 18.4738 29.5266 17.2899 28.841 16.5277C28.1461 15.7473 27.2916 15.3606 26.2661 15.3606C25.3028 15.3606 24.4825 15.7436 23.7951 16.5259C23.1178 17.2968 22.7613 18.4819 22.7613 20.1183C22.7613 21.7707 23.1226 22.9631 23.8086 23.7337ZM22.5262 9.37007C22.5262 8.50295 23.2291 7.8 24.0962 7.8C24.9633 7.8 25.6663 8.50295 25.6663 9.37007C25.6663 10.2372 24.9633 10.9401 24.0962 10.9401C23.2291 10.9401 22.5262 10.2372 22.5262 9.37007ZM26.9848 9.37007C26.9848 8.50295 27.6877 7.8 28.5548 7.8C29.4219 7.8 30.1249 8.50295 30.1249 9.37007C30.1249 10.2372 29.4219 10.9401 28.5548 10.9401C27.6877 10.9401 26.9848 10.2372 26.9848 9.37007Z'\n        fill='#FBA95C'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const ChainTAIKOIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon width='36' height='36' {...props} viewBox='0 0 36 36' fill='none'>\n      <path\n        d='M31.4116 25.2445L26.6137 18.7257C26.0924 18.0174 25.3206 17.593 24.4987 17.4995C24.3116 17.4778 24.1445 17.3692 24.0509 17.2055C23.9557 17.0417 23.9457 16.843 24.0209 16.6692C24.35 15.9108 24.37 15.0304 24.0159 14.2251L20.7699 6.81095C20.2888 5.71001 19.2012 5 18 5C16.7989 5 15.7112 5.71168 15.2302 6.81095L11.9841 14.2251C11.6316 15.0304 11.65 15.9108 11.9791 16.6692C12.0543 16.843 12.0426 17.0417 11.949 17.2055C11.8538 17.3692 11.6884 17.4778 11.5013 17.4995C10.6794 17.593 9.90756 18.0174 9.38634 18.7257L4.58834 25.2445C3.87666 26.2117 3.80482 27.5081 4.40457 28.5489C5.00599 29.5881 6.16539 30.1745 7.3582 30.0425L15.4022 29.147C16.2759 29.0501 17.0294 28.5941 17.5205 27.9292C17.6325 27.7771 17.8113 27.6869 18 27.6869C18.1888 27.6869 18.3659 27.7771 18.4795 27.9292C18.9706 28.5941 19.7241 29.0501 20.5979 29.147L28.6418 30.0425C29.8347 30.1761 30.994 29.5897 31.5955 28.5489C32.1951 27.5081 32.1234 26.2117 31.4116 25.2445ZM14.0824 15.1557L17.3334 7.73313C17.4504 7.4675 17.7127 7.29542 18.0016 7.29542C18.2907 7.29542 18.5529 7.4675 18.67 7.73313L21.921 15.1557C22.0229 15.3895 22.0011 15.6602 21.8608 15.874C21.7205 16.0878 21.4833 16.2165 21.226 16.2165H14.7757C14.5201 16.2165 14.2812 16.0878 14.1409 15.874C14.0006 15.6602 13.9788 15.3895 14.0807 15.1557H14.0824ZM15.7513 26.4556C15.6361 26.6845 15.4122 26.8382 15.1583 26.8666L7.10595 27.7621C6.8186 27.7938 6.53794 27.6535 6.3926 27.4029C6.24725 27.1523 6.26563 26.8399 6.4377 26.606L11.2407 20.0806C11.3927 19.8751 11.6366 19.7582 11.8922 19.7732C12.1479 19.7866 12.3784 19.9286 12.507 20.1507L12.5121 20.1591L15.728 25.729L15.733 25.7373C15.8616 25.9595 15.8683 26.2302 15.753 26.4573L15.7513 26.4556ZM18.6616 23.9364C18.5246 24.1719 18.274 24.319 18 24.319C17.7277 24.319 17.4755 24.1737 17.3385 23.938L14.8676 19.6596C14.7306 19.4241 14.7306 19.1317 14.8676 18.8962C15.0046 18.6605 15.2552 18.5136 15.5292 18.5136H20.4692C20.7415 18.5136 20.9937 18.6572 21.1307 18.8945C21.2677 19.1317 21.2677 19.4224 21.1307 19.6579L18.6616 23.9364ZM29.6091 27.4029C29.4638 27.6535 29.1847 27.7955 28.8958 27.7637L20.8434 26.8683C20.5895 26.8399 20.3656 26.6862 20.2504 26.4573C20.1351 26.2285 20.1417 25.9578 20.2704 25.7373L20.2754 25.729L23.4913 20.1591L23.4963 20.1507C23.6249 19.9286 23.8555 19.7866 24.1111 19.7732C24.3667 19.7599 24.6106 19.8751 24.7627 20.0806L29.5657 26.606C29.7377 26.8399 29.7544 27.1523 29.6107 27.4029H29.6091Z'\n        fill='#E81899'\n      />\n    </SvgIcon>\n  )\n}\n\nexport const ChainETHEREUMIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon width='36' height='36' {...props} viewBox='0 0 36 36' fill='none'>\n      <path d='M18 3V15.4588L9 18.2603L18 3Z' fill='#8C95B5' />\n      <path d='M18 3V15.4588L27 18.2603L18 3Z' fill='#666B91' />\n      <path d='M18 33.1761V24.5069L9 19.5437L18 33.1761Z' fill='#8D96B6' />\n      <path d='M18 33.1761V24.5069L27 19.5437L18 33.1761Z' fill='#666B91' />\n      <path d='M9 18.2601L18 14.0778V22.6807L9 18.2601Z' fill='#4A4E79' />\n      <path d='M27 18.2601L18 14.0778V22.6807L27 18.2601Z' fill='#4A4E79' />\n    </SvgIcon>\n  )\n}\n\nexport const BaseIcon = (props: SvgIconProps) => {\n  return (\n    <SvgIcon width='146' height='146' {...props} viewBox='0 0 146 146' fill='none'>\n      <circle cx=\"73\" cy=\"73\" r=\"73\" fill=\"#0052FF\"/>\n      <path d=\"M73.323 123.729C101.617 123.729 124.553 100.832 124.553 72.5875C124.553 44.343 101.617 21.4463 73.323 21.4463C46.4795 21.4463 24.4581 42.0558 22.271 68.2887H89.9859V76.8864H22.271C24.4581 103.119 46.4795 123.729 73.323 123.729Z\" fill=\"white\"/>\n    </SvgIcon>\n  )\n}\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/svg/redPacketScope.tsx",
    "content": "import { SVGProps } from \"react\"\n\nexport const ScopePublic = (props: SVGProps<SVGSVGElement>) => {\n  const {\n    color = \"#A4ABC1\", \n    ...rest\n  } = props;\n  return (\n    <svg width=\"64\" height=\"64\" viewBox=\"0 0 24 24\" fill={color} xmlns=\"http://www.w3.org/2000/svg\">\n      <path fill={color} fillRule=\"evenodd\" clipRule=\"evenodd\" d=\"M7.09536 1C5.93455 1 4.99359 1.941 4.99359 3.10178V8.17042H4.98897L4.98874 10.6997C4.98874 10.706 4.98752 10.7123 4.98507 10.7182C4.98267 10.724 4.97911 10.7293 4.97464 10.7338C4.97013 10.7383 4.96482 10.7418 4.95897 10.7443C4.95313 10.7467 4.94686 10.7479 4.94052 10.7479C4.30297 10.7467 3.66018 10.7468 3.01213 10.7484C2.7303 10.749 2.51583 10.7696 2.3687 10.81C1.74916 10.9801 1.24282 11.4821 1.07277 12.094C1.02436 12.2676 1.00016 12.5583 1.00016 12.9662C0.999841 15.6365 1 18.3067 1.00064 20.9769C1.00064 21.2084 1.01274 21.384 1.03694 21.5037C1.17451 22.194 1.71046 22.7524 2.37061 22.9291C2.5464 22.9763 2.82902 22.9998 3.21849 22.9998C9.37415 23.0002 15.5298 23 21.6854 22.9994C22.036 22.9994 22.2932 22.9764 22.4569 22.9306C23.2909 22.6975 23.8168 21.9413 23.8173 21.0772C23.8194 16.7752 23.8208 12.4729 23.8214 8.17042H23.8202V6.20298L23.8224 6.20194L23.8306 6.19812L23.8328 6.19705L23.8337 6.19659C23.8337 6.19659 23.8339 6.19655 23.8202 6.16795V3.10177C23.8202 1.941 22.8792 1 21.7184 1H7.09536ZM23.0809 6.08955C23.2269 6.03602 23.3461 5.98922 23.438 5.95163V3.10177C23.438 2.15205 22.6681 1.38214 21.7184 1.38214H7.09536C6.14561 1.38214 5.37573 2.15205 5.37573 3.10178V5.9243C5.47363 5.9654 5.61492 6.02214 5.7988 6.08955C6.19328 6.23415 6.78376 6.42786 7.5628 6.62187C8.74732 6.91689 10.3679 7.2127 12.3982 7.33755C12.4802 6.29992 13.3482 5.48345 14.4069 5.48345C15.5198 5.48345 16.4219 6.38562 16.4219 7.4985C16.4219 7.44566 16.4199 7.3933 16.4159 7.34152C18.4769 7.21905 20.1197 6.92006 21.3169 6.62187C22.096 6.42786 22.6865 6.23415 23.0809 6.08955ZM16.4094 7.72469C16.297 8.73111 15.4433 9.51356 14.4069 9.51356C13.3691 9.51356 12.5146 8.72907 12.4039 7.72076C10.3355 7.59545 8.68205 7.29444 7.47047 6.9927C6.67749 6.79521 6.0739 6.59738 5.66726 6.44834C5.55503 6.40721 5.45779 6.36978 5.37573 6.3371V8.17042H5.38262L5.38284 10.7002C5.38284 10.7064 5.38407 10.7126 5.38647 10.7183C5.38888 10.7241 5.3924 10.7294 5.39687 10.7337C5.4013 10.7382 5.40658 10.7416 5.41235 10.744C5.41815 10.7463 5.42435 10.7475 5.43061 10.7474C8.94153 10.7471 12.4638 10.7473 15.9973 10.7479C16.2708 10.7482 16.4827 10.7694 16.6331 10.8114C17.2507 10.9858 17.7522 11.4845 17.9213 12.0974C17.9691 12.2716 17.9931 12.5599 17.9935 12.9624C17.9941 15.6097 17.9938 18.257 17.9925 20.9043C17.9925 21.6384 17.844 22.0755 17.3185 22.5852C17.2962 22.6069 17.3007 22.6177 17.3319 22.6177C18.7888 22.618 20.2551 22.6177 21.7308 22.6168C22.0114 22.6164 22.2152 22.5996 22.3423 22.5661C23.0167 22.3879 23.439 21.7708 23.439 21.0767C23.4397 17.4729 23.4398 13.8688 23.4394 10.2642H23.438V6.3631C23.3712 6.38917 23.296 6.41773 23.2125 6.44834C22.8058 6.59738 22.2023 6.79521 21.4093 6.9927C20.1848 7.29769 18.5088 7.60187 16.4094 7.72469ZM6.46776 2.56795L6.80691 2.56558C6.8188 2.5655 6.82847 2.57506 6.82854 2.58693L6.82957 2.73501C6.82969 2.74688 6.8201 2.75657 6.80825 2.75665L6.4691 2.75902C6.45722 2.7591 6.44755 2.74955 6.44747 2.73767L6.44644 2.5896C6.44633 2.57772 6.45588 2.56804 6.46776 2.56795ZM7.42311 2.56795L7.76226 2.56558C7.77415 2.5655 7.78382 2.57506 7.78389 2.58693L7.78493 2.73501C7.78504 2.74688 7.77545 2.75657 7.7636 2.75665L7.42445 2.75902C7.41257 2.7591 7.4029 2.74955 7.40282 2.73767L7.40179 2.5896C7.40168 2.57772 7.41123 2.56804 7.42311 2.56795ZM8.71762 2.56558L8.37847 2.56795C8.36658 2.56804 8.35703 2.57772 8.35714 2.5896L8.35818 2.73767C8.35825 2.74955 8.36792 2.7591 8.37981 2.75902L8.71895 2.75665C8.7308 2.75657 8.74039 2.74688 8.74028 2.73501L8.73925 2.58693C8.73917 2.57506 8.7295 2.5655 8.71762 2.56558ZM9.33382 2.56795L9.67297 2.56558C9.68485 2.5655 9.69452 2.57506 9.6946 2.58693L9.69563 2.73501C9.69575 2.74688 9.68615 2.75657 9.67431 2.75665L9.33516 2.75902C9.32327 2.7591 9.3136 2.74955 9.31353 2.73767L9.3125 2.5896C9.31238 2.57772 9.32194 2.56804 9.33382 2.56795ZM10.6226 2.56563L10.2949 2.56791C10.2799 2.56802 10.2678 2.58029 10.2679 2.59533L10.2688 2.73194C10.2689 2.74698 10.2812 2.75908 10.2962 2.75898L10.6239 2.75669C10.6389 2.75659 10.6511 2.74431 10.6509 2.72927L10.65 2.59266C10.6499 2.57763 10.6376 2.56552 10.6226 2.56563ZM11.2503 2.56791L11.5779 2.56563C11.593 2.56552 11.6053 2.57763 11.6053 2.59266L11.6063 2.72927C11.6064 2.74431 11.5943 2.75659 11.5793 2.75669L11.2516 2.75898C11.2366 2.75908 11.2243 2.74698 11.2242 2.73194L11.2232 2.59533C11.2231 2.58029 11.2352 2.56802 11.2503 2.56791ZM12.539 2.56558L12.1999 2.56795C12.188 2.56804 12.1784 2.57772 12.1786 2.5896L12.1796 2.73767C12.1797 2.74955 12.1893 2.7591 12.2012 2.75902L12.5404 2.75665C12.5522 2.75657 12.5618 2.74688 12.5617 2.73501L12.5607 2.58693C12.5606 2.57506 12.5509 2.5655 12.539 2.56558ZM13.1552 2.56795L13.4944 2.56558C13.5063 2.5655 13.5159 2.57506 13.516 2.58693L13.517 2.73501C13.5172 2.74688 13.5076 2.75657 13.4957 2.75665L13.1566 2.75902C13.1447 2.7591 13.135 2.74955 13.1349 2.73767L13.1339 2.5896C13.1338 2.57772 13.1433 2.56804 13.1552 2.56795ZM15.7779 2.56697L15.4664 2.56752C15.4451 2.56755 15.4277 2.58491 15.4278 2.60627L15.428 2.71901C15.428 2.74038 15.4454 2.75767 15.4668 2.75763L15.7782 2.75709C15.7996 2.75705 15.8169 2.7397 15.8168 2.71833L15.8166 2.6056C15.8166 2.58423 15.7992 2.56694 15.7779 2.56697ZM16.4218 2.56752L16.7332 2.56697C16.7546 2.56694 16.7719 2.58423 16.772 2.6056L16.7722 2.71833C16.7722 2.7397 16.7549 2.75705 16.7336 2.75709L16.4221 2.75763C16.4007 2.75767 16.3834 2.74038 16.3834 2.71901L16.3831 2.60627C16.3831 2.58491 16.4004 2.56755 16.4218 2.56752ZM17.6897 2.56724H17.3773C17.3559 2.56724 17.3386 2.58457 17.3386 2.60593V2.71867C17.3386 2.74004 17.3559 2.75736 17.3773 2.75736H17.6897C17.7111 2.75736 17.7284 2.74004 17.7284 2.71867V2.60593C17.7284 2.58457 17.7111 2.56724 17.6897 2.56724ZM18.3325 2.56752L18.6439 2.56697C18.6653 2.56694 18.6826 2.58423 18.6827 2.6056L18.6829 2.71833C18.6829 2.7397 18.6656 2.75705 18.6443 2.75709L18.3328 2.75763C18.3115 2.75767 18.2941 2.74038 18.294 2.71901L18.2938 2.60627C18.2938 2.58491 18.3111 2.56755 18.3325 2.56752ZM19.6004 2.56724H19.288C19.2666 2.56724 19.2493 2.58457 19.2493 2.60593V2.71867C19.2493 2.74004 19.2666 2.75736 19.288 2.75736H19.6004C19.6217 2.75736 19.6391 2.74004 19.6391 2.71867V2.60593C19.6391 2.58457 19.6217 2.56724 19.6004 2.56724ZM20.1805 2.56565L20.5005 2.56788C20.5198 2.56802 20.5353 2.58374 20.5351 2.603L20.5343 2.72337C20.5342 2.74263 20.5184 2.75813 20.4992 2.758L20.1792 2.75576C20.1599 2.75563 20.1444 2.73991 20.1445 2.72065L20.1454 2.60028C20.1455 2.58102 20.1612 2.56552 20.1805 2.56565ZM21.4565 2.56649L21.1345 2.56705C21.1153 2.56708 21.0997 2.58272 21.0997 2.60198L21.0999 2.72331C21.1 2.74256 21.1156 2.75815 21.1349 2.75812L21.4568 2.75756C21.4761 2.75752 21.4917 2.74188 21.4916 2.72262L21.4914 2.6013C21.4914 2.58204 21.4757 2.56645 21.4565 2.56649ZM22.0891 2.56592L22.413 2.56762C22.4309 2.56771 22.4454 2.58233 22.4453 2.60027L22.4446 2.72637C22.4445 2.74431 22.4299 2.75878 22.412 2.75868L22.0881 2.75699C22.0702 2.7569 22.0557 2.74227 22.0558 2.72434L22.0564 2.59823C22.0565 2.58029 22.0711 2.56582 22.0891 2.56592ZM13.4432 18.2474H9.4068C9.30285 18.2474 9.21859 18.3317 9.21859 18.4356V18.4404C9.21859 18.5444 9.30285 18.6286 9.4068 18.6286H13.4432C13.5471 18.6286 13.6314 18.5444 13.6314 18.4404V18.4356C13.6314 18.3317 13.5471 18.2474 13.4432 18.2474ZM1.71452 18.8077L1.9992 18.8097C2.02822 18.8099 2.05158 18.8336 2.05138 18.8626L2.05078 18.9486C2.05058 18.9776 2.02689 19.001 1.99787 19.0007L1.71318 18.9988C1.68416 18.9986 1.6608 18.9749 1.661 18.9459L1.6616 18.8599C1.66181 18.8309 1.6855 18.8075 1.71452 18.8077ZM2.97469 18.8071L2.65465 18.8093C2.6375 18.8094 2.6237 18.8235 2.62382 18.8406L2.62472 18.9696C2.62484 18.9867 2.63884 19.0005 2.65598 19.0004L2.97602 18.9982C2.99317 18.9981 3.00697 18.984 3.00685 18.9669L3.00595 18.838C3.00583 18.8208 2.99183 18.807 2.97469 18.8071ZM3.62457 18.8067L3.91785 18.8098C3.94238 18.81 3.96206 18.8301 3.9618 18.8547L3.96073 18.9569C3.96048 18.9814 3.94038 19.0011 3.91585 19.0008L3.62257 18.9978C3.59804 18.9975 3.57836 18.9774 3.57861 18.9529L3.57969 18.8506C3.57994 18.8261 3.60004 18.8064 3.62457 18.8067ZM4.87223 18.8082H4.57989C4.55509 18.8082 4.53499 18.8283 4.53499 18.8531V18.9544C4.53499 18.9792 4.55509 18.9993 4.57989 18.9993H4.87223C4.89703 18.9993 4.91713 18.9792 4.91713 18.9544V18.8531C4.91713 18.8283 4.89703 18.8082 4.87223 18.8082ZM5.5337 18.8065L5.82982 18.809C5.85359 18.8093 5.87266 18.8287 5.87247 18.8524L5.87155 18.9575C5.87132 18.9812 5.85191 19.0003 5.82818 19.0001L5.53202 18.9975C5.50829 18.9973 5.48922 18.9779 5.48941 18.9542L5.49033 18.8491C5.49052 18.8253 5.50993 18.8062 5.5337 18.8065ZM6.79262 18.8069L6.48117 18.8096C6.46191 18.8098 6.44644 18.8255 6.44663 18.8448L6.4477 18.9661C6.44785 18.9853 6.46359 19.0008 6.48285 19.0006L6.7943 18.9979C6.81356 18.9978 6.82904 18.982 6.82884 18.9628L6.82777 18.8414C6.82762 18.8222 6.81188 18.8067 6.79262 18.8069ZM7.42971 18.8082H7.75452C7.77035 18.8082 7.78319 18.8211 7.78319 18.8369V18.9706C7.78319 18.9865 7.77035 18.9993 7.75452 18.9993H7.42971C7.41388 18.9993 7.40104 18.9865 7.40104 18.9706V18.8369C7.40104 18.8211 7.41388 18.8082 7.42971 18.8082ZM16.07 18.8081L15.7442 18.8093C15.7281 18.8093 15.7151 18.8224 15.7152 18.8385L15.7157 18.9704C15.7157 18.9865 15.7288 18.9994 15.7449 18.9994L16.0707 18.9983C16.0868 18.9982 16.0998 18.9851 16.0997 18.969L16.0993 18.8372C16.0992 18.8211 16.0861 18.8081 16.07 18.8081ZM16.6942 18.8091L17.0266 18.8073C17.0414 18.8073 17.0535 18.8192 17.0535 18.834L17.0543 18.9715C17.0544 18.9863 17.0424 18.9983 17.0277 18.9984L16.6952 19.0002C16.6804 19.0003 16.6684 18.9883 16.6683 18.9735L16.6676 18.836C16.6675 18.8212 16.6794 18.8092 16.6942 18.8091ZM13.4441 19.4058H10.2523C10.1491 19.4058 10.0655 19.4894 10.0655 19.5926V19.5973C10.0655 19.7005 10.1491 19.7841 10.2523 19.7841H13.4441C13.5472 19.7841 13.6309 19.7005 13.6309 19.5973V19.5926C13.6309 19.4894 13.5472 19.4058 13.4441 19.4058ZM18.5765 20.3643L18.9127 20.3666C18.9259 20.3667 18.9365 20.3775 18.9364 20.3907L18.9355 20.5301C18.9354 20.5433 18.9246 20.554 18.9114 20.5539L18.5751 20.5515C18.5619 20.5514 18.5513 20.5407 18.5514 20.5275L18.5524 20.388C18.5525 20.3748 18.5632 20.3642 18.5765 20.3643ZM19.8677 20.3665L19.5305 20.3653C19.5176 20.3653 19.5071 20.3757 19.507 20.3886L19.5065 20.53C19.5065 20.543 19.5169 20.5535 19.5299 20.5535L19.8671 20.5547C19.88 20.5548 19.8905 20.5443 19.8906 20.5314L19.891 20.39C19.8911 20.3771 19.8807 20.3666 19.8677 20.3665ZM20.4859 20.3653L20.8231 20.3665C20.836 20.3666 20.8465 20.3771 20.8464 20.39L20.8459 20.5314C20.8459 20.5443 20.8354 20.5548 20.8224 20.5547L20.4852 20.5535C20.4723 20.5535 20.4618 20.543 20.4619 20.53L20.4624 20.3886C20.4624 20.3757 20.4729 20.3653 20.4859 20.3653ZM21.7784 20.3665L21.4412 20.3653C21.4283 20.3653 21.4178 20.3757 21.4177 20.3886L21.4172 20.53C21.4172 20.543 21.4276 20.5535 21.4406 20.5535L21.7778 20.5547C21.7907 20.5548 21.8012 20.5443 21.8013 20.5314L21.8018 20.39C21.8018 20.3771 21.7914 20.3666 21.7784 20.3665ZM22.3969 20.3656L22.7332 20.3662C22.7464 20.3662 22.7571 20.3769 22.7571 20.3901L22.7568 20.5306C22.7568 20.5438 22.7461 20.5545 22.7329 20.5544L22.3966 20.5538C22.3834 20.5538 22.3727 20.5431 22.3727 20.5299L22.373 20.3895C22.373 20.3763 22.3837 20.3656 22.3969 20.3656ZM11.6547 11.1287C11.6573 11.1277 11.66 11.1271 11.6628 11.1272C13.123 11.1317 14.5642 11.1317 15.9868 11.1272C16.741 11.1248 17.3353 11.4558 17.5488 12.2024C17.5914 12.3518 17.6126 12.5626 17.6123 12.8349C17.6114 15.1879 17.611 17.5411 17.6113 19.8945C17.6113 19.9107 17.6032 19.9188 17.587 19.9188H15.2473C15.2317 19.9188 15.2239 19.9109 15.2239 19.895C15.222 19.3548 15.2217 18.8156 15.223 18.277C15.2249 17.5118 14.922 17.1354 14.1305 17.1359C12.4558 17.1365 10.7812 17.1365 9.10681 17.1359C8.35208 17.1354 8.03441 17.5051 8.03395 18.2412C8.0336 18.7931 8.0336 19.344 8.03395 19.894C8.03395 19.9006 8.03131 19.9069 8.02665 19.9115C8.02202 19.9162 8.01568 19.9188 8.00911 19.9188H1.40714C1.40055 19.9188 1.39423 19.9162 1.38958 19.9115C1.38492 19.9069 1.3823 19.9006 1.3823 19.894V13.0121C1.3823 12.6048 1.40205 12.3309 1.44153 12.1905C1.57146 11.7257 1.95217 11.3374 2.41742 11.1917C2.54735 11.1512 2.73715 11.1309 2.98681 11.1306C4.41602 11.1293 5.8567 11.129 7.30883 11.1296C7.32049 11.1296 7.33165 11.1342 7.3399 11.1424C7.34816 11.1507 7.35278 11.1619 7.35278 11.1735C7.35404 11.6012 7.35404 12.0357 7.35278 12.4771C7.35133 13.1263 7.66996 13.529 8.3468 13.5294L10.61 13.5304C11.3242 13.5309 11.6433 13.1464 11.6409 12.4542C11.6396 12.0182 11.6398 11.5831 11.6414 11.1487C11.6414 11.1458 11.6419 11.143 11.643 11.1403L11.6446 11.1371L11.6477 11.1333C11.6497 11.1313 11.6521 11.1298 11.6547 11.1287ZM7.74971 11.1286H11.2444C11.2488 11.1286 11.2531 11.1304 11.2562 11.1335C11.2594 11.1367 11.2611 11.1409 11.2611 11.1453V12.5922C11.2611 12.7404 11.2032 12.8826 11.1001 12.9874C10.997 13.0922 10.8571 13.1511 10.7113 13.1511H8.2828C8.21061 13.1511 8.13911 13.1366 8.07239 13.1086C8.00571 13.0805 7.9451 13.0393 7.89404 12.9874C7.84299 12.9355 7.80248 12.8739 7.77486 12.8061C7.74723 12.7383 7.73301 12.6656 7.73301 12.5922V11.1453C7.73301 11.1409 7.73477 11.1367 7.7379 11.1335C7.74104 11.1304 7.74528 11.1286 7.74971 11.1286ZM14.6846 17.6742C14.7843 17.7739 14.8403 17.9092 14.8403 18.0502V20.0554C14.8403 20.1964 14.7843 20.3317 14.6846 20.4314C14.5849 20.5311 14.4497 20.5871 14.3087 20.5871H8.94822C8.80721 20.5871 8.67197 20.5311 8.57227 20.4314C8.47257 20.3317 8.41655 20.1964 8.41655 20.0554V18.0502C8.41655 17.9092 8.47257 17.7739 8.57227 17.6742C8.67197 17.5745 8.80721 17.5185 8.94822 17.5185H14.3087C14.4497 17.5185 14.5849 17.5745 14.6846 17.6742ZM2.8631 22.6153C2.07159 22.6148 1.46876 22.0297 1.38564 21.2525C1.37195 21.1222 1.37306 20.8142 1.38899 20.3282C1.38924 20.3209 1.39236 20.3139 1.39771 20.3089C1.40306 20.3038 1.41021 20.3009 1.41765 20.3009H8.05351C8.05603 20.3009 8.05852 20.3017 8.06058 20.3032C8.06264 20.3046 8.06417 20.3067 8.06498 20.3091C8.27374 20.8541 8.62722 20.9692 9.19229 20.9692L13.9624 20.9702C14.5666 20.9702 14.9693 20.9081 15.1804 20.3225C15.1859 20.3081 15.1962 20.3009 15.2115 20.3009H17.5865C17.5931 20.3009 17.5994 20.3035 17.6041 20.3081C17.6087 20.3127 17.6113 20.3189 17.6113 20.3253C17.6115 20.4087 17.6131 20.4971 17.6148 20.5873C17.6206 20.8949 17.6268 21.2259 17.5736 21.467C17.4594 21.9843 17.0563 22.4118 16.5456 22.5585C16.4097 22.5976 16.1927 22.6172 15.8946 22.6172C11.5509 22.6179 7.20707 22.6172 2.8631 22.6153ZM12.774 7.4985C12.774 6.59667 13.505 5.86559 14.4069 5.86559C15.3087 5.86559 16.0398 6.59667 16.0398 7.4985C16.0398 8.40034 15.3087 9.13142 14.4069 9.13142C13.505 9.13142 12.774 8.40034 12.774 7.4985Z\" />\n    </svg>\n  )\n}\n\nexport const ScopeQR = (props: SVGProps<SVGSVGElement>) => {\n  const {\n    color = \"#A4ABC1\", \n    ...rest\n  } = props;\n  return (\n    <svg width='64' height='64' viewBox='0 0 24 24' fill={color} xmlns='http://www.w3.org/2000/svg'>\n      <g clipPath='url(#clip0_1_2)'>\n        <mask\n          id='mask0_1_2'\n          style={{maskType: 'luminance'}}\n          maskUnits='userSpaceOnUse'\n          x='0'\n          y='0'\n          width='8'\n          height='8'\n        >\n          <path\n            fillRule='evenodd'\n            clipRule='evenodd'\n            d='M7.55036 1.125C7.55036 0.710786 7.21459 0.375 6.80036 0.375H1.125C0.710786 0.375 0.375 0.710786 0.375 1.125V2.68798L0.375004 6.85455C0.375004 7.26877 0.71079 7.60455 1.125 7.60455H1.93799C2.3522 7.60455 2.68799 7.26877 2.68799 6.85455V3.43798C2.68799 3.02377 3.02377 2.68798 3.43799 2.68798H6.80036C7.21459 2.68798 7.55036 2.3522 7.55036 1.93798V1.125Z'\n            fill={color}\n          />\n        </mask>\n        <g mask='url(#mask0_1_2)'>\n          <path\n            d='M1.125 0.75H6.80036V0H1.125V0.75ZM0.75 2.68798V1.125H0L5.63265e-06 2.68798L0.75 2.68798ZM0.750004 6.85455L0.75 2.68798L5.63265e-06 2.68798L5.43146e-06 6.85455H0.750004ZM1.93799 7.22955H1.125V7.97955H1.93799V7.22955ZM2.31299 3.43798V6.85455H3.06299V3.43798H2.31299ZM6.80036 2.31298H3.43799V3.06298H6.80036V2.31298ZM7.17536 1.125V1.93798H7.92536V1.125H7.17536ZM6.80036 3.06298C7.4217 3.06298 7.92536 2.5593 7.92536 1.93798H7.17536C7.17536 2.14509 7.00748 2.31298 6.80036 2.31298V3.06298ZM3.06299 3.43798C3.06299 3.23088 3.23088 3.06298 3.43799 3.06298V2.31298C2.81667 2.31298 2.31299 2.81666 2.31299 3.43798H3.06299ZM1.93799 7.97955C2.55931 7.97955 3.06299 7.47589 3.06299 6.85455H2.31299C2.31299 7.06166 2.14509 7.22955 1.93799 7.22955V7.97955ZM5.43146e-06 6.85455C5.40911e-06 7.47589 0.503685 7.97955 1.125 7.97955V7.22955C0.917899 7.22955 0.750004 7.06166 0.750004 6.85455H5.43146e-06ZM0.375004 3.06298C0.148129 3.06298 5.6103e-06 2.87475 5.63265e-06 2.68798L0.75 2.68798C0.75 2.50121 0.601879 2.31298 0.375004 2.31298V3.06298ZM5.63265e-06 2.68798C5.63265e-06 2.89509 0.167895 3.06298 0.375004 3.06298V2.31298C0.582109 2.31298 0.75 2.48087 0.75 2.68798L5.63265e-06 2.68798ZM6.80036 0.75C7.00748 0.75 7.17536 0.917895 7.17536 1.125H7.92536C7.92536 0.503677 7.4217 0 6.80036 0V0.75ZM1.125 0C0.503681 0 0 0.503681 0 1.125H0.75C0.75 0.917895 0.917895 0.75 1.125 0.75V0Z'\n            fill={color}\n          />\n        </g>\n        <mask\n          id='mask1_1_2'\n          style={{maskType: 'luminance'}}\n          maskUnits='userSpaceOnUse'\n          x='0'\n          y='16'\n          width='8'\n          height='8'\n        >\n          <path\n            fillRule='evenodd'\n            clipRule='evenodd'\n            d='M7.55036 22.875C7.55036 23.2892 7.21459 23.625 6.80036 23.625H1.125C0.710788 23.625 0.375002 23.2892 0.375002 22.875V21.312C0.374998 21.312 0.375002 21.312 0.375002 21.312L0.375005 17.1455C0.375005 16.7312 0.710792 16.3955 1.12501 16.3955H1.93799C2.3522 16.3955 2.68799 16.7312 2.68799 17.1455V20.562C2.68799 20.9762 3.02378 21.312 3.43799 21.312H6.80036C7.21459 21.312 7.55036 21.6478 7.55036 22.062V22.875Z'\n            fill={color}\n          />\n        </mask>\n        <g mask='url(#mask1_1_2)'>\n          <path\n            d='M1.125 23.25H6.80036V24H1.125V23.25ZM0.75 21.312V22.875H0L5.63265e-06 21.312L0.75 21.312ZM0.750004 17.1455L0.75 21.312L5.63265e-06 21.312L5.43146e-06 17.1455H0.750004ZM1.93799 16.7705H1.125V16.0205H1.93799V16.7705ZM2.31299 20.562V17.1455H3.06299V20.562H2.31299ZM6.80036 21.687H3.43799V20.937H6.80036V21.687ZM7.17536 22.875V22.062H7.92536V22.875H7.17536ZM6.80036 20.937C7.4217 20.937 7.92536 21.4407 7.92536 22.062H7.17536C7.17536 21.8549 7.00748 21.687 6.80036 21.687V20.937ZM3.06299 20.562C3.06299 20.7691 3.23088 20.937 3.43799 20.937V21.687C2.81667 21.687 2.31299 21.1833 2.31299 20.562H3.06299ZM1.93799 16.0205C2.55931 16.0205 3.06299 16.5241 3.06299 17.1455H2.31299C2.31299 16.9383 2.14509 16.7705 1.93799 16.7705V16.0205ZM5.43146e-06 17.1455C5.40911e-06 16.5241 0.503685 16.0205 1.125 16.0205V16.7705C0.917899 16.7705 0.750004 16.9383 0.750004 17.1455H5.43146e-06ZM0.375004 20.937C0.148129 20.937 5.6103e-06 21.1253 5.63265e-06 21.312L0.75 21.312C0.75 21.4988 0.601879 21.687 0.375004 21.687V20.937ZM5.63265e-06 21.312C5.63265e-06 21.1049 0.167895 20.937 0.375004 20.937V21.687C0.582109 21.687 0.75 21.5191 0.75 21.312L5.63265e-06 21.312ZM6.80036 23.25C7.00748 23.25 7.17536 23.0821 7.17536 22.875H7.92536C7.92536 23.4963 7.4217 24 6.80036 24V23.25ZM1.125 24C0.503681 24 0 23.4963 0 22.875H0.75C0.75 23.0821 0.917895 23.25 1.125 23.25V24Z'\n            fill={color}\n          />\n        </g>\n        <mask\n          id='mask2_1_2'\n          style={{maskType: 'luminance'}}\n          maskUnits='userSpaceOnUse'\n          x='16'\n          y='0'\n          width='8'\n          height='8'\n        >\n          <path\n            fillRule='evenodd'\n            clipRule='evenodd'\n            d='M16.4496 1.125C16.4496 0.710786 16.7854 0.375 17.1996 0.375H22.875C23.2892 0.375 23.625 0.710786 23.625 1.125V2.68798V6.85455C23.625 7.26877 23.2892 7.60455 22.875 7.60455H22.062C21.6478 7.60455 21.312 7.26877 21.312 6.85455V3.43798C21.312 3.02377 20.9762 2.68798 20.562 2.68798H17.1996C16.7854 2.68798 16.4496 2.3522 16.4496 1.93798V1.125Z'\n            fill={color}\n          />\n        </mask>\n        <g mask='url(#mask2_1_2)'>\n          <path\n            d='M22.875 0.75H17.1996V0H22.875V0.75ZM23.25 2.68798V1.125H24V2.68798L23.25 2.68798ZM23.25 6.85455V2.68798L24 2.68798V6.85455H23.25ZM22.062 7.22955H22.875V7.97955H22.062V7.22955ZM21.687 3.43798V6.85455H20.937V3.43798H21.687ZM17.1996 2.31298H20.562V3.06298H17.1996V2.31298ZM16.8246 1.125V1.93798H16.0746V1.125H16.8246ZM17.1996 3.06298C16.5783 3.06298 16.0746 2.5593 16.0746 1.93798H16.8246C16.8246 2.14509 16.9925 2.31298 17.1996 2.31298V3.06298ZM20.937 3.43798C20.937 3.23088 20.7691 3.06298 20.562 3.06298V2.31298C21.1833 2.31298 21.687 2.81666 21.687 3.43798H20.937ZM22.062 7.97955C21.4407 7.97955 20.937 7.47589 20.937 6.85455H21.687C21.687 7.06166 21.8549 7.22955 22.062 7.22955V7.97955ZM24 6.85455C24 7.47589 23.4963 7.97955 22.875 7.97955V7.22955C23.0821 7.22955 23.25 7.06166 23.25 6.85455H24ZM23.625 3.06298C23.8519 3.06298 24 2.87475 24 2.68798L23.25 2.68798C23.25 2.50121 23.3981 2.31298 23.625 2.31298V3.06298ZM24 2.68798C24 2.89509 23.8321 3.06298 23.625 3.06298V2.31298C23.4179 2.31298 23.25 2.48087 23.25 2.68798L24 2.68798ZM17.1996 0.75C16.9925 0.75 16.8246 0.917895 16.8246 1.125H16.0746C16.0746 0.503677 16.5783 0 17.1996 0V0.75ZM22.875 0C23.4963 0 24 0.503681 24 1.125H23.25C23.25 0.917895 23.0821 0.75 22.875 0.75V0Z'\n            fill={color}\n          />\n        </g>\n        <mask\n          id='mask3_1_2'\n          style={{maskType: 'luminance'}}\n          maskUnits='userSpaceOnUse'\n          x='16'\n          y='16'\n          width='8'\n          height='8'\n        >\n          <path\n            fillRule='evenodd'\n            clipRule='evenodd'\n            d='M16.4496 22.875C16.4496 23.2892 16.7854 23.625 17.1996 23.625H22.875C23.2892 23.625 23.625 23.2892 23.625 22.875V21.312V17.1455C23.625 16.7312 23.2892 16.3955 22.875 16.3955H22.062C21.6478 16.3955 21.312 16.7312 21.312 17.1455V20.562C21.312 20.9762 20.9762 21.312 20.562 21.312H17.1996C16.7854 21.312 16.4496 21.6478 16.4496 22.062V22.875Z'\n            fill={color}\n          />\n        </mask>\n        <g mask='url(#mask3_1_2)'>\n          <path\n            d='M22.875 23.25H17.1996V24H22.875V23.25ZM23.25 21.312V22.875H24V21.312L23.25 21.312ZM23.25 17.1455V21.312L24 21.312V17.1455H23.25ZM22.062 16.7705H22.875V16.0205H22.062V16.7705ZM21.687 20.562V17.1455H20.937V20.562H21.687ZM17.1996 21.687H20.562V20.937H17.1996V21.687ZM16.8246 22.875V22.062H16.0746V22.875H16.8246ZM17.1996 20.937C16.5783 20.937 16.0746 21.4407 16.0746 22.062H16.8246C16.8246 21.8549 16.9925 21.687 17.1996 21.687V20.937ZM20.937 20.562C20.937 20.7691 20.7691 20.937 20.562 20.937V21.687C21.1833 21.687 21.687 21.1833 21.687 20.562H20.937ZM22.062 16.0205C21.4407 16.0205 20.937 16.5241 20.937 17.1455H21.687C21.687 16.9383 21.8549 16.7705 22.062 16.7705V16.0205ZM24 17.1455C24 16.5241 23.4963 16.0205 22.875 16.0205V16.7705C23.0821 16.7705 23.25 16.9383 23.25 17.1455H24ZM23.625 20.937C23.8519 20.937 24 21.1253 24 21.312L23.25 21.312C23.25 21.4988 23.3981 21.687 23.625 21.687V20.937ZM24 21.312C24 21.1049 23.8321 20.937 23.625 20.937V21.687C23.4179 21.687 23.25 21.5191 23.25 21.312L24 21.312ZM17.1996 23.25C16.9925 23.25 16.8246 23.0821 16.8246 22.875H16.0746C16.0746 23.4963 16.5783 24 17.1996 24V23.25ZM22.875 24C23.4963 24 24 23.4963 24 22.875H23.25C23.25 23.0821 23.0821 23.25 22.875 23.25V24Z'\n            fill={color}\n          />\n        </g>\n        <path\n          fillRule='evenodd'\n          clipRule='evenodd'\n          d='M7.31441 4.33047C6.95349 4.33047 6.63017 4.49149 6.41238 4.74561L6.60938 4.74424C6.621 4.74416 6.63053 4.75354 6.6306 4.7652L6.63161 4.91051C6.63169 4.92214 6.62231 4.93166 6.61069 4.93174L6.28016 4.93405C6.1826 5.10647 6.12691 5.30572 6.12691 5.51797V7.47495L6.15338 7.48748C6.43033 7.61783 6.84576 7.79284 7.39435 7.96826C8.12856 8.20304 9.1015 8.43864 10.3006 8.56882C10.4263 7.63978 11.2225 6.92361 12.186 6.92361C13.1535 6.92361 13.9523 7.6458 14.0729 8.58052C15.3232 8.45317 16.3337 8.21028 17.0905 7.96826C17.5847 7.81021 17.9709 7.6525 18.2451 7.52748V5.51797C18.2451 5.30505 18.189 5.10522 18.0909 4.93242L17.9199 4.93271C17.8989 4.93275 17.8819 4.91576 17.8818 4.8948L17.8816 4.78418C17.8816 4.76321 17.8986 4.74619 17.9196 4.74615L17.96 4.74608C17.7422 4.49169 17.4187 4.33047 17.0576 4.33047H7.31441ZM14.0842 8.95629C14.0174 9.94641 13.193 10.7288 12.186 10.7288C11.1749 10.7288 10.348 9.94021 10.287 8.94453C9.04903 8.81211 8.04232 8.5692 7.28013 8.32545C6.79573 8.17054 6.41022 8.01536 6.12691 7.88804V18.647C6.12691 19.3028 6.65857 19.8345 7.31441 19.8345H17.0576C17.5947 19.8345 18.0485 19.4779 18.1952 18.9886C18.1895 18.9997 18.1778 19.0073 18.1645 19.0072L17.8504 19.005C17.8315 19.0049 17.8163 18.9895 17.8164 18.9706L17.8173 18.8525C17.8174 18.8336 17.8328 18.8183 17.8517 18.8185L18.1658 18.8207C18.1847 18.8208 18.1999 18.8362 18.1998 18.8551L18.1989 18.9732L18.1988 18.9764C18.2289 18.8718 18.2451 18.7613 18.2451 18.647V7.93782C17.9751 8.05476 17.6276 8.19021 17.2047 8.32545C16.4193 8.57661 15.3743 8.82687 14.0842 8.95629ZM5.12691 5.51797C5.12691 4.30985 6.10629 3.33047 7.31441 3.33047H17.0576C18.2657 3.33047 19.2451 4.30985 19.2451 5.51797V18.647C19.2451 19.8551 18.2657 20.8345 17.0576 20.8345H7.31441C6.10629 20.8345 5.12691 19.8551 5.12691 18.647V5.51797ZM7.21406 4.74656L7.54688 4.74424C7.5585 4.74416 7.56803 4.75354 7.5681 4.7652L7.56911 4.91051C7.56919 4.92214 7.55981 4.93166 7.54819 4.93174L7.21537 4.93406C7.20371 4.93414 7.19423 4.92476 7.19411 4.91314L7.1931 4.76783C7.19303 4.75616 7.2024 4.74664 7.21406 4.74656ZM8.48438 4.74424L8.15156 4.74656C8.1399 4.74664 8.13053 4.75616 8.1306 4.76783L8.13161 4.91314C8.13172 4.92476 8.14121 4.93414 8.15287 4.93406L8.48569 4.93174C8.49731 4.93166 8.50669 4.92214 8.50661 4.91051L8.5056 4.7652C8.50553 4.75354 8.496 4.74416 8.48438 4.74424ZM9.08906 4.74656L9.42188 4.74424C9.4335 4.74416 9.44303 4.75354 9.4431 4.7652L9.44411 4.91051C9.44419 4.92214 9.43481 4.93166 9.42319 4.93174L9.09037 4.93406C9.07871 4.93414 9.06922 4.92476 9.06911 4.91314L9.0681 4.76783C9.06803 4.75616 9.0774 4.74664 9.08906 4.74656ZM10.3538 4.74428L10.0322 4.74653C10.0174 4.74664 10.0056 4.75868 10.0056 4.77345L10.0066 4.90751C10.0067 4.92225 10.0187 4.93414 10.0335 4.93403L10.3551 4.93178C10.3698 4.93166 10.3817 4.91963 10.3816 4.90489L10.3806 4.77083C10.3805 4.75605 10.3685 4.7442 10.3538 4.74428ZM15.1071 4.74615L15.4127 4.74563C15.4337 4.74559 15.4507 4.76254 15.4507 4.7835L15.4509 4.89413C15.451 4.91509 15.434 4.93215 15.413 4.93219L15.1074 4.93271C15.0864 4.93275 15.0694 4.91576 15.0694 4.8948L15.0691 4.78418C15.0691 4.76321 15.0861 4.74619 15.1071 4.74615ZM14.4758 4.74563L14.1702 4.74615C14.1492 4.74619 14.1323 4.76321 14.1323 4.78418L14.1325 4.8948C14.1325 4.91576 14.1495 4.93275 14.1705 4.93271L14.4761 4.93219C14.4971 4.93215 14.5141 4.91509 14.514 4.89413L14.5139 4.7835C14.5138 4.76254 14.4968 4.74559 14.4758 4.74563ZM16.0446 4.74615L16.3502 4.74563C16.3712 4.74559 16.3882 4.76254 16.3882 4.7835L16.3884 4.89413C16.3884 4.91509 16.3715 4.93215 16.3505 4.93219L16.0449 4.93271C16.0239 4.93275 16.0069 4.91576 16.0068 4.8948L16.0066 4.78418C16.0066 4.76321 16.0236 4.74619 16.0446 4.74615ZM17.2888 4.74589H16.9822C16.9613 4.74589 16.9443 4.76288 16.9443 4.78384V4.89446C16.9443 4.91543 16.9613 4.93245 16.9822 4.93245H17.2888C17.3097 4.93245 17.3268 4.91543 17.3268 4.89446V4.78384C17.3268 4.76288 17.3097 4.74589 17.2888 4.74589ZM6.60304 18.8184L6.27026 18.8207C6.2586 18.8208 6.24923 18.8303 6.2493 18.842L6.25031 18.9873C6.25039 18.9989 6.25991 19.0083 6.27154 19.0082L6.60435 19.0059C6.61601 19.0058 6.62539 18.9963 6.62531 18.9847L6.6243 18.8394C6.62423 18.8277 6.6147 18.8183 6.60304 18.8184ZM7.54054 18.8184L7.20776 18.8207C7.1961 18.8208 7.18673 18.8303 7.1868 18.842L7.18781 18.9873C7.18789 18.9989 7.19741 19.0083 7.20904 19.0082L7.54185 19.0059C7.55351 19.0058 7.56289 18.9963 7.56281 18.9847L7.5618 18.8394C7.56173 18.8277 7.5522 18.8183 7.54054 18.8184ZM8.15089 18.8207L8.47241 18.8184C8.48719 18.8183 8.49922 18.8302 8.49934 18.845L8.50027 18.9791C8.50035 18.9938 8.4885 19.0058 8.47372 19.0059L8.15216 19.0082C8.13742 19.0083 8.12539 18.9964 8.12528 18.9816L8.12434 18.8476C8.12422 18.8328 8.13611 18.8208 8.15089 18.8207ZM9.40991 18.8184L9.08839 18.8207C9.07361 18.8208 9.06172 18.8328 9.06184 18.8476L9.06277 18.9816C9.06289 18.9964 9.07492 19.0083 9.08966 19.0082L9.41122 19.0059C9.426 19.0058 9.43785 18.9938 9.43777 18.9791L9.43684 18.845C9.43672 18.8302 9.42469 18.8183 9.40991 18.8184ZM10.0203 18.8207L10.353 18.8184C10.3647 18.8183 10.3742 18.8277 10.3743 18.8394L10.3753 18.9847C10.3754 18.9963 10.366 19.0058 10.3543 19.0059L10.0215 19.0082C10.0099 19.0083 10.0004 18.9989 10.0003 18.9873L9.9993 18.842C9.99922 18.8303 10.0086 18.8208 10.0203 18.8207ZM11.2905 18.8184L10.9578 18.8207C10.9461 18.8208 10.9367 18.8303 10.9368 18.842L10.9378 18.9873C10.9379 18.9989 10.9474 19.0083 10.959 19.0082L11.2918 19.0059C11.3035 19.0058 11.3129 18.9963 11.3128 18.9847L11.3118 18.8394C11.3117 18.8277 11.3022 18.8183 11.2905 18.8184ZM13.2258 18.8203L13.5314 18.8197C13.5523 18.8197 13.5694 18.8367 13.5694 18.8577L13.5696 18.9683C13.5696 18.9893 13.5526 19.0063 13.5317 19.0063L13.2261 19.0069C13.2051 19.0069 13.1881 18.9899 13.188 18.969L13.1878 18.8583C13.1878 18.8374 13.2048 18.8203 13.2258 18.8203ZM14.4689 18.8197L14.1633 18.8203C14.1423 18.8203 14.1253 18.8374 14.1253 18.8583L14.1255 18.969C14.1256 18.9899 14.1426 19.0069 14.1636 19.0069L14.4692 19.0063C14.4901 19.0063 14.5071 18.9893 14.5071 18.9683L14.5069 18.8577C14.5069 18.8367 14.4898 18.8197 14.4689 18.8197ZM15.1009 18.82H15.4075C15.4284 18.82 15.4454 18.837 15.4454 18.858V18.9686C15.4454 18.9896 15.4284 19.0066 15.4075 19.0066H15.1009C15.0799 19.0066 15.0629 18.9896 15.0629 18.9686V18.858C15.0629 18.837 15.0799 18.82 15.1009 18.82ZM16.3438 18.8197L16.0382 18.8203C16.0173 18.8203 16.0003 18.8374 16.0003 18.8583L16.0005 18.969C16.0006 18.9899 16.0176 19.0069 16.0386 19.0069L16.3442 19.0063C16.3651 19.0063 16.3821 18.9893 16.3821 18.9683L16.3819 18.8577C16.3819 18.8367 16.3648 18.8197 16.3438 18.8197ZM16.9759 18.82H17.2825C17.3034 18.82 17.3204 18.837 17.3204 18.858V18.9686C17.3204 18.9896 17.3034 19.0066 17.2825 19.0066H16.9759C16.9549 19.0066 16.9379 18.9896 16.9379 18.9686V18.858C16.9379 18.837 16.9549 18.82 16.9759 18.82ZM11.2833 8.82623C11.2833 8.32772 11.6875 7.92361 12.186 7.92361C12.6845 7.92361 13.0886 8.32772 13.0886 8.82623C13.0886 9.32473 12.6845 9.72884 12.186 9.72884C11.6875 9.72884 11.2833 9.32473 11.2833 8.82623Z'\n          fill={color}\n        />\n      </g>\n      <defs>\n        <clipPath id='clip0_1_2'>\n          <rect width='24' height='24' fill='white' />\n        </clipPath>\n      </defs>\n    </svg>\n  )\n}\nexport const ScopeTarget = (props: SVGProps<SVGSVGElement>) => {\n  const {\n    color = \"#A4ABC1\", \n    ...rest\n  } = props;\n  return (\n    <svg width='64' height='64' viewBox='0 0 24 24' fill={color} xmlns='http://www.w3.org/2000/svg'>\n      <g clip-path='url(#clip0_1_66)'>\n        <mask\n          id='mask0_1_66'\n          style={{maskType: 'luminance'}}\n          maskUnits='userSpaceOnUse'\n          x='0'\n          y='0'\n          width='24'\n          height='24'\n        >\n          <path d='M24 0H0V24H24V0Z' fill={color} />\n        </mask>\n        <g mask='url(#mask0_1_66)'>\n          <path\n            fillRule='evenodd'\n            clipRule='evenodd'\n            d='M17.6967 2.25469C18.3539 2.46516 18.9295 2.64141 19.6209 2.41688C19.6403 2.41062 19.6502 2.41766 19.6505 2.43797L19.6528 3.35859C19.6528 3.36294 19.6511 3.36712 19.648 3.3702C19.6449 3.37327 19.6408 3.375 19.6364 3.375H15.9108C15.9034 3.37502 15.8964 3.37225 15.8911 3.36728C15.8857 3.3623 15.8826 3.3555 15.8822 3.34828C15.6727 -0.989999 8.38406 -0.996562 8.15625 3.34453C8.1558 3.35291 8.15212 3.36078 8.14601 3.36653C8.1399 3.37229 8.13184 3.37548 8.12344 3.37547L4.4175 3.375C4.40156 3.375 4.39361 3.36703 4.39361 3.35109V2.44828C4.39357 2.44347 4.3947 2.43872 4.39687 2.43443C4.39909 2.43014 4.40227 2.42642 4.40621 2.42358C4.41011 2.42075 4.41469 2.41888 4.41952 2.41812C4.42432 2.41736 4.42927 2.41774 4.43392 2.41922C5.07236 2.62969 5.66017 2.48625 6.27705 2.26922C6.48296 2.19641 6.63079 2.11688 6.72049 2.03063C7.19625 1.57219 6.85125 0.887814 6.21375 0.882657C5.61281 0.878281 5.01157 0.877501 4.41 0.880314C4.4034 0.880336 4.39695 0.878056 4.39185 0.873867C4.38671 0.869679 4.38319 0.86384 4.38188 0.857345C4.19156 -0.146249 2.78532 -0.15328 2.64048 0.852188C2.63946 0.859707 2.63567 0.866604 2.62981 0.871602C2.62395 0.876601 2.61642 0.879361 2.6086 0.879376C2.0061 0.876875 1.39939 0.878907 0.788449 0.88547C-0.0609268 0.894376 -0.123739 1.93125 0.598136 2.21672C0.895635 2.33422 1.25126 2.42969 1.66501 2.50313C1.99548 2.5619 2.19776 2.51646 2.55696 2.43579L2.55696 2.43579L2.55696 2.43578L2.59735 2.42672C2.61579 2.42234 2.62501 2.42969 2.62501 2.44875V3.35063C2.62501 3.36875 2.61595 3.37766 2.59782 3.37734C2.11189 3.37391 1.62564 3.37375 1.13907 3.37688C0.277979 3.38156 -0.217489 4.41424 0.335636 5.08736C0.533917 5.3283 0.81798 5.45111 1.12126 5.51344C3.34001 5.9703 5.55641 6.42656 7.77049 6.88219C7.77352 6.88283 7.7763 6.88444 7.77832 6.8868C7.78035 6.88916 7.78155 6.89213 7.7817 6.89524C7.78185 6.89835 7.78099 6.90143 7.77922 6.90398C7.77742 6.90653 7.77487 6.90844 7.77187 6.90938C5.98969 7.5225 4.21031 8.13938 2.43376 8.76C1.44517 9.10549 1.52532 10.1967 1.65142 11.0156C1.85017 12.3035 2.05126 13.5906 2.2547 14.8772C2.38407 15.6923 2.71314 16.4438 3.65064 16.53C3.65863 16.5308 3.66604 16.5346 3.67141 16.5406C3.67678 16.5465 3.67974 16.5543 3.6797 16.5623C3.67939 18.3167 3.67954 20.0747 3.68017 21.8363C3.68017 22.1744 3.70251 22.4255 3.7472 22.5895C3.95392 23.3498 4.67017 23.9414 5.47267 23.9414C9.75641 23.9417 14.0403 23.9416 18.3244 23.9409C18.6056 23.9409 18.8158 23.9242 18.9549 23.8908C19.5937 23.738 20.1159 23.2317 20.287 22.6045C20.3327 22.437 20.3555 22.1699 20.3555 21.803C20.3552 20.0523 20.3552 18.3055 20.3555 16.5623C20.3554 16.5544 20.3584 16.5468 20.3637 16.5409C20.369 16.5351 20.3763 16.5315 20.3841 16.5309C21.1509 16.4606 21.6169 15.9051 21.7369 15.173C21.8719 14.3498 22.0886 12.9612 22.387 11.0072C22.4939 10.3055 22.5961 9.42611 21.9412 8.94375C21.8247 8.85814 21.585 8.7522 21.2222 8.62594C19.5669 8.05001 17.9125 7.47626 16.2591 6.90469C16.2567 6.90405 16.2546 6.90259 16.2531 6.90056C16.2517 6.8985 16.251 6.89606 16.2511 6.89355C16.2513 6.89108 16.2523 6.88871 16.254 6.88691C16.2557 6.88508 16.258 6.88391 16.2605 6.88361C18.3748 6.45143 20.4902 6.01766 22.6064 5.58236C22.8305 5.53639 22.9992 5.4975 23.1127 5.46563C24.383 5.11125 24.1041 3.37125 22.8277 3.37453C22.3636 3.37578 21.8989 3.37578 21.4336 3.37453C21.418 3.37422 21.4102 3.36625 21.4102 3.35063V2.44875C21.4102 2.42969 21.4194 2.42234 21.4378 2.42672C21.8672 2.52703 22.1208 2.56828 22.4995 2.48438C22.8164 2.41437 23.1099 2.33406 23.3799 2.24344C24.0942 2.00297 24.1692 0.967501 23.3259 0.892032C22.8905 0.853356 22.4285 0.862585 21.975 0.871644C21.7909 0.875321 21.6083 0.87897 21.4294 0.879376C21.4138 0.879376 21.4044 0.871565 21.4012 0.855939C21.2095 -0.108749 19.9889 -0.170155 19.6706 0.762189C19.6663 0.775235 19.6641 0.788847 19.6641 0.802501V0.852657C19.6641 0.871407 19.6547 0.880782 19.6359 0.880782C18.7687 0.876406 18.158 0.876875 17.8036 0.882188C16.8905 0.896251 16.9008 2.00016 17.6967 2.25469ZM3.99236 3.37594L3.01454 3.37406C3.00994 3.37406 3.00553 3.37224 3.00228 3.36898C2.99902 3.36573 2.9972 3.36132 2.9972 3.35672L3.00095 0.986251C3.0012 0.849252 3.05443 0.717965 3.14893 0.621267C3.24343 0.52457 3.37146 0.470382 3.50485 0.470626H3.51142C3.57747 0.470746 3.64285 0.484227 3.70383 0.510297C3.76481 0.536371 3.8202 0.574524 3.86681 0.62258C3.91342 0.670632 3.95036 0.727647 3.97552 0.79037C4.00069 0.853089 4.01359 0.920289 4.01344 0.988126L4.00969 3.35859C4.00969 3.3632 4.00789 3.36761 4.00462 3.37086C4.00136 3.37411 3.99694 3.37594 3.99236 3.37594ZM9.69142 8.13326C9.19312 8.13326 8.72719 7.76108 8.57812 7.28576C8.54096 7.16704 8.52187 6.96203 8.52094 6.6708C8.51531 5.00861 8.5158 3.95299 8.52236 3.50391C8.58 -0.57328 15.5222 -0.53203 15.5161 3.53859C15.5145 4.55205 15.5149 5.5653 15.517 6.57844C15.5177 6.90563 15.4953 7.14281 15.45 7.29C15.2634 7.89563 14.7642 8.13424 14.1581 8.13375C12.6691 8.13251 11.1802 8.13233 9.69142 8.13326ZM20.9864 3.38016L20.0742 3.37828C20.059 3.37828 20.0445 3.37226 20.0338 3.36153C20.0231 3.35081 20.017 3.33626 20.017 3.32109L20.0208 1.02703C20.0211 0.878611 20.0748 0.736366 20.17 0.631583C20.2653 0.526797 20.3944 0.468057 20.5289 0.468282H20.5411C20.6077 0.468391 20.6736 0.482982 20.7351 0.511216C20.7966 0.539454 20.8525 0.580778 20.8995 0.63284C20.9465 0.684901 20.9838 0.746671 21.0091 0.814632C21.0345 0.88259 21.0475 0.9554 21.0474 1.02891L21.0436 3.32297C21.0436 3.33814 21.0376 3.35268 21.0268 3.36341C21.0161 3.37413 21.0016 3.38016 20.9864 3.38016ZM2.05407 2.15016C1.76251 2.18859 1.2797 2.04938 0.955792 1.94297L0.896089 1.92348C0.697415 1.85915 0.55841 1.81413 0.492199 1.62703C0.422824 1.42969 0.565324 1.25719 0.764542 1.25625C1.37954 1.25313 1.99001 1.25266 2.59595 1.25484C2.61626 1.25484 2.62642 1.265 2.62642 1.28531L2.62454 2.00438C2.62454 2.01938 2.6172 2.02891 2.60251 2.03297C2.39563 2.09016 2.21282 2.12922 2.05407 2.15016ZM5.42625 2.11359C5.07094 2.19 4.75549 2.13422 4.42031 2.02734C4.41337 2.02518 4.4073 2.0209 4.40291 2.0151C4.39856 2.0093 4.39612 2.00226 4.39594 1.995L4.39125 1.28672C4.39121 1.28243 4.392 1.27818 4.39357 1.2742C4.39519 1.27022 4.39755 1.2666 4.40055 1.26354C4.40359 1.26049 4.40715 1.25807 4.41112 1.25641C4.41506 1.25476 4.4193 1.25391 4.42361 1.25391C5.00329 1.2536 5.58735 1.25375 6.1758 1.25438C6.4383 1.25438 6.6825 1.41656 6.50812 1.70344C6.38326 1.9087 5.76219 2.04166 5.46344 2.10562L5.42625 2.11359ZM18.5968 2.11104C18.2354 2.04419 17.2838 1.86819 17.5167 1.39172C17.5592 1.30484 17.6472 1.26078 17.7806 1.25953C18.3934 1.25453 19.0053 1.25266 19.6162 1.25391C19.6258 1.25391 19.635 1.25771 19.6418 1.26448C19.6485 1.27125 19.6524 1.28043 19.6524 1.29V1.99078C19.6524 2.00797 19.6441 2.01922 19.6275 2.02453C19.3074 2.12438 18.9999 2.18813 18.6605 2.12297C18.6422 2.11944 18.6208 2.11548 18.5968 2.11104ZM23.2031 1.25859C23.6719 1.26469 23.6756 1.73203 23.2927 1.86891C22.8942 2.01141 22.373 2.18906 21.9516 2.14219C21.7766 2.12281 21.6045 2.08484 21.4355 2.02828C21.4186 2.02297 21.4102 2.01141 21.4102 1.99359V1.27969C21.4102 1.26469 21.4178 1.25703 21.4331 1.25672C22.0247 1.25016 22.6147 1.25078 23.2031 1.25859ZM8.12111 6.56906L1.95235 5.30861C1.57923 5.23234 1.28501 5.16874 1.0697 5.11781C0.403605 4.95986 0.221729 4.1025 0.884542 3.81518C0.984543 3.77205 1.1422 3.7503 1.35751 3.75H8.12017C8.12662 3.75 8.13285 3.75255 8.13739 3.75713C8.14196 3.7617 8.14455 3.76793 8.14455 3.77438V6.55031C8.14455 6.55316 8.14391 6.55594 8.14267 6.55849C8.14144 6.56108 8.1396 6.56333 8.13739 6.56509C8.13514 6.56689 8.13251 6.56816 8.1297 6.56888C8.12689 6.56955 8.12396 6.56963 8.12111 6.56906ZM23.5669 4.38188C23.6522 4.96174 23.0016 5.1117 22.5961 5.19563C20.3692 5.65781 18.1431 6.11689 15.9178 6.57281C15.9145 6.57353 15.9112 6.57345 15.9079 6.57266C15.9046 6.57184 15.9016 6.5703 15.899 6.56813C15.8964 6.56599 15.8943 6.56325 15.8928 6.56018C15.8914 6.5571 15.8907 6.55373 15.8906 6.55031V3.77438C15.8906 3.76793 15.8932 3.7617 15.8978 3.75713C15.9024 3.75255 15.9085 3.75 15.915 3.75H22.5834C22.8719 3.75 23.0706 3.77438 23.1797 3.82313C23.3975 3.92063 23.5266 4.10689 23.5669 4.38188ZM14.6259 8.47826C15.2706 8.3142 15.6895 7.88595 15.8827 7.19344C15.8834 7.19078 15.8847 7.1883 15.8864 7.18616C15.8882 7.18399 15.8903 7.18223 15.8927 7.18095C15.8939 7.18031 15.8952 7.17981 15.8965 7.17944C15.8978 7.17907 15.8991 7.17883 15.9005 7.17874C15.9032 7.17855 15.9059 7.17893 15.9084 7.17986C17.755 7.8186 19.6047 8.4597 21.4575 9.10313C22.2567 9.38108 22.1137 10.3205 22.0064 11.0152C21.8155 12.253 21.623 13.4903 21.4289 14.7272C21.3305 15.3534 21.1627 16.0936 20.3742 16.1494C20.3617 16.1503 20.3555 16.1445 20.3555 16.132C20.3552 14.2998 20.3552 12.4675 20.3555 10.635C20.3555 10.4681 20.3236 10.4096 20.1675 10.3603C18.2328 9.75158 16.298 9.14265 14.363 8.53361C14.3586 8.53208 14.3548 8.529 14.3524 8.52495C14.35 8.52094 14.349 8.51618 14.3498 8.5116C14.3505 8.50703 14.3529 8.50286 14.3564 8.49994C14.3599 8.49701 14.3644 8.49548 14.3691 8.49563C14.4562 8.49799 14.5406 8.49986 14.6259 8.47826ZM3.91994 10.3472C3.80389 10.3834 3.67926 10.4222 3.6797 10.5708C3.68032 12.4208 3.68017 14.2719 3.67923 16.1241C3.67923 16.1394 3.67157 16.1466 3.65626 16.1456C2.89079 16.0992 2.70798 15.3389 2.61095 14.7248C2.41657 13.4936 2.22454 12.2621 2.03485 11.0302L2.02854 10.9892C1.9425 10.432 1.82596 9.67718 2.26923 9.29201C2.36954 9.20483 2.58673 9.10328 2.92079 8.98733C4.65517 8.38421 6.39296 7.7817 8.13424 7.17986C8.13739 7.1787 8.14076 7.17821 8.14414 7.17848C8.14747 7.1787 8.15074 7.17968 8.1537 7.18125C8.15666 7.18286 8.15929 7.18504 8.16131 7.1877C8.16337 7.19036 8.16484 7.19344 8.16562 7.19674C8.3619 7.98424 8.86594 8.42359 9.67781 8.51483C9.69502 8.5167 9.69626 8.52218 9.68156 8.53125C9.64056 8.55612 9.58606 8.56919 9.54122 8.57995C9.52352 8.5842 9.50733 8.58808 9.49406 8.59219C7.6425 9.17344 5.79142 9.75626 3.9408 10.3406L3.91994 10.3472ZM19.9537 12.5259C19.5731 12.038 19.0467 11.8364 18.4308 11.8364C14.2311 11.8358 10.0311 11.8356 5.8308 11.8359C5.44579 11.8359 5.17031 11.8594 5.00437 11.9063C4.64501 12.0078 4.33984 12.2106 4.08892 12.5147C4.08641 12.5178 4.083 12.5201 4.07917 12.5212C4.07531 12.5223 4.07122 12.5221 4.06747 12.5208C4.06369 12.5195 4.06046 12.517 4.05817 12.5137C4.05589 12.5104 4.05465 12.5065 4.05469 12.5025V10.7344C4.05469 10.7238 4.05802 10.7134 4.06425 10.7048C4.07047 10.6962 4.07929 10.6898 4.08937 10.6866C6.34095 9.97718 8.59252 9.26828 10.8441 8.55986C10.9453 8.52799 11.0492 8.51171 11.1558 8.51111C11.7283 8.50736 12.3013 8.50609 12.8747 8.50736C12.9791 8.50736 13.0813 8.52311 13.1812 8.55469C15.4294 9.26156 17.6903 9.97313 19.9641 10.6894C19.9747 10.6925 19.98 10.6997 19.98 10.7109L19.9814 12.5161C19.9815 12.5193 19.9805 12.5225 19.9787 12.5252C19.9768 12.5279 19.9742 12.5299 19.9711 12.531C19.9681 12.5321 19.9647 12.5322 19.9616 12.5313C19.9585 12.5304 19.9558 12.5285 19.9537 12.5259ZM13.253 14.1951L10.778 14.1905C10.6482 14.1902 10.5237 14.1384 10.432 14.0465C10.3404 13.9546 10.2889 13.83 10.2891 13.7001L10.2919 12.2503C10.2919 12.2379 10.2931 12.2261 10.2952 12.2173C10.2973 12.2085 10.3002 12.2035 10.3031 12.2034L13.7353 12.2091C13.7368 12.209 13.7383 12.2102 13.7397 12.2126C13.741 12.2149 13.7422 12.2183 13.7433 12.2227C13.7443 12.227 13.7452 12.2322 13.7457 12.2379C13.7463 12.2436 13.7466 12.2498 13.7466 12.2559L13.7437 13.7058C13.7437 13.7702 13.731 13.8339 13.7062 13.8933C13.6815 13.9527 13.6454 14.0067 13.5998 14.0522C13.5542 14.0976 13.5001 14.1336 13.4406 14.1582C13.3811 14.1827 13.3173 14.1953 13.253 14.1951ZM17.7197 19.2426C17.7211 18.5278 17.3869 18.1912 16.672 18.1898C15.7273 18.1877 14.7825 18.1866 13.8375 18.1866C13.5322 18.1866 13.3177 18.2106 13.1939 18.2588C12.7941 18.4144 12.6455 18.7622 12.645 19.1826C12.6444 19.7539 12.6444 20.3241 12.645 20.8931C12.645 20.8997 12.6424 20.906 12.6377 20.9107C12.6331 20.9154 12.6268 20.9179 12.6202 20.9179H4.07861C4.06327 20.9179 4.05562 20.9102 4.05562 20.8945C4.05409 18.4989 4.05375 16.1045 4.05469 13.7114C4.05469 13.042 4.43719 12.4711 5.08267 12.2742C5.22202 12.2317 5.4219 12.2105 5.68219 12.2105C7.08439 12.2108 8.48659 12.2109 9.88875 12.2109C9.90469 12.2109 9.91282 12.2191 9.91312 12.2353C9.91534 12.6663 9.91534 13.0958 9.91312 13.5239C9.91125 13.9716 10.0472 14.3419 10.4789 14.5059C10.6055 14.5541 10.8277 14.5781 11.1455 14.5781H12.8409C13.1928 14.5784 13.4333 14.5538 13.5624 14.5041C13.9702 14.347 14.1234 13.9926 14.122 13.5661C14.1205 13.1186 14.1203 12.6719 14.1216 12.2259C14.1216 12.2237 14.122 12.2215 14.1229 12.2195C14.1233 12.2185 14.1238 12.2176 14.1243 12.2167C14.125 12.2157 14.1257 12.2148 14.1265 12.214C14.1275 12.213 14.1286 12.2122 14.1298 12.2114L14.132 12.2103C14.134 12.2095 14.1362 12.2091 14.1384 12.2091C15.5553 12.2125 16.9558 12.2123 18.3399 12.2086C19.0992 12.2063 19.7002 12.4992 19.9205 13.2656C19.9614 13.4088 19.9817 13.6064 19.9814 13.8586C19.9798 16.2045 19.9797 18.5494 19.9809 20.8931C19.9809 20.8997 19.9783 20.906 19.9737 20.9107C19.969 20.9154 19.9627 20.9179 19.9561 20.9179H17.7431C17.7368 20.9179 17.7307 20.9154 17.7262 20.911C17.7217 20.9065 17.7192 20.9004 17.7192 20.8941C17.718 20.3466 17.7181 19.7961 17.7197 19.2426ZM17.1935 18.7133C17.29 18.8098 17.3442 18.9407 17.3442 19.0772V21.0591C17.3442 21.1266 17.3309 21.1936 17.305 21.256C17.2792 21.3185 17.2413 21.3752 17.1935 21.423C17.1457 21.4708 17.0889 21.5087 17.0265 21.5346C16.9641 21.5604 16.8971 21.5737 16.8295 21.5737H13.5342C13.4666 21.5737 13.3997 21.5604 13.3373 21.5346C13.2748 21.5087 13.2181 21.4708 13.1703 21.423C13.1225 21.3752 13.0846 21.3185 13.0587 21.256C13.0329 21.1936 13.0195 21.1266 13.0195 21.0591V19.0772C13.0195 18.9407 13.0738 18.8098 13.1703 18.7133C13.2668 18.6167 13.3977 18.5625 13.5342 18.5625H16.8295C16.966 18.5625 17.097 18.6167 17.1935 18.7133ZM12.6816 21.3173C12.8695 21.8213 13.2183 21.9454 13.7358 21.9473C14.6721 21.9498 15.6081 21.9505 16.5441 21.9492C17.1094 21.9483 17.4872 21.8639 17.6817 21.3117C17.6861 21.2992 17.695 21.2929 17.7084 21.2929H19.9566C19.9629 21.2929 19.969 21.2955 19.9735 21.3C19.978 21.3045 19.9805 21.3105 19.9805 21.3169C19.9805 21.4014 19.9822 21.4909 19.9839 21.5825C19.9896 21.8824 19.9956 22.2036 19.9439 22.4381C19.8324 22.9458 19.4367 23.3644 18.9356 23.5088C18.8031 23.5472 18.5975 23.5664 18.3187 23.5664C14.1181 23.5661 9.91766 23.5664 5.71736 23.5673C5.46202 23.5673 5.26204 23.5467 5.11736 23.5055C4.59266 23.3555 4.25734 23.0167 4.11142 22.4892C4.03804 22.2252 4.04499 21.8908 4.05155 21.5757V21.5757V21.5757V21.5757V21.5757V21.5756V21.5756V21.5756V21.5756V21.5755V21.5755C4.05332 21.4901 4.05507 21.4061 4.05517 21.3253C4.05517 21.3167 4.05851 21.3085 4.06451 21.3024C4.07047 21.2964 4.07857 21.2929 4.08705 21.2929H12.6464C12.6636 21.2929 12.6753 21.3011 12.6816 21.3173ZM13.2983 4.90399C13.6379 4.5645 13.8286 4.10404 13.8286 3.62391C13.8286 3.14378 13.6379 2.68332 13.2983 2.34382C12.9588 2.00432 12.4984 1.81359 12.0183 1.81359C11.5381 1.81359 11.0777 2.00432 10.7382 2.34382C10.3987 2.68332 10.208 3.14378 10.208 3.62391C10.208 4.10404 10.3987 4.5645 10.7382 4.90399C11.0777 5.24348 11.5381 5.43424 12.0183 5.43424C12.4984 5.43424 12.9588 5.24348 13.2983 4.90399ZM13.0342 2.60846C13.3036 2.8779 13.455 3.24333 13.455 3.62438C13.455 4.00541 13.3036 4.37085 13.0342 4.64029C12.7647 4.90973 12.3993 5.06108 12.0183 5.06108C11.6372 5.06108 11.2718 4.90973 11.0023 4.64029C10.7329 4.37085 10.5815 4.00541 10.5815 3.62438C10.5815 3.24333 10.7329 2.8779 11.0023 2.60846C11.2718 2.33903 11.6372 2.18766 12.0183 2.18766C12.3993 2.18766 12.7647 2.33903 13.0342 2.60846ZM9.34687 6.51562H9.02813C9.0126 6.51562 9 6.52823 9 6.54375V6.675C9 6.69052 9.0126 6.70312 9.02813 6.70312H9.34687C9.3624 6.70312 9.375 6.69052 9.375 6.675V6.54375C9.375 6.52823 9.3624 6.51562 9.34687 6.51562ZM9.98066 6.51532L10.2703 6.51686C10.2939 6.51697 10.3129 6.53617 10.3128 6.55972L10.3122 6.66191C10.3121 6.68546 10.2929 6.70447 10.2694 6.70436L9.97969 6.70282C9.95614 6.70271 9.93713 6.68351 9.93724 6.65996L9.93776 6.55777C9.93791 6.53422 9.95711 6.51521 9.98066 6.51532ZM11.2036 6.51731L10.9233 6.51581C10.8972 6.5157 10.8759 6.53678 10.8757 6.56291L10.8752 6.65572C10.8751 6.6819 10.8962 6.7032 10.9223 6.70331L11.2026 6.70481C11.2288 6.70492 11.2501 6.68385 11.2502 6.65771L11.2507 6.5649C11.2509 6.53872 11.2298 6.51742 11.2036 6.51731ZM11.8531 6.51634L12.1466 6.51585C12.1688 6.51581 12.1869 6.53381 12.1869 6.55609L12.1871 6.66296C12.1872 6.6852 12.1692 6.70331 12.1469 6.70335L11.8534 6.70384C11.8312 6.70387 11.8131 6.68587 11.8131 6.6636L11.8129 6.55672C11.8128 6.53449 11.8309 6.51637 11.8531 6.51634ZM13.0804 6.51656H12.7955C12.7706 6.51656 12.7505 6.5367 12.7505 6.56156V6.65906C12.7505 6.68393 12.7706 6.70406 12.7955 6.70406H13.0804C13.1053 6.70406 13.1255 6.68393 13.1255 6.65906V6.56156C13.1255 6.5367 13.1053 6.51656 13.0804 6.51656ZM13.7299 6.51694L14.0214 6.519C14.0437 6.51915 14.0616 6.5373 14.0615 6.55958L14.0607 6.66645C14.0606 6.68873 14.0424 6.70665 14.0201 6.7065L13.7286 6.70444C13.7063 6.70429 13.6884 6.68614 13.6886 6.66386L13.6893 6.55699C13.6895 6.53471 13.7076 6.51679 13.7299 6.51694ZM14.967 6.51503L14.6576 6.51716C14.6395 6.51731 14.6249 6.53209 14.625 6.5502L14.6259 6.67208C14.626 6.69023 14.6408 6.70481 14.6589 6.70466L14.9683 6.70253C14.9864 6.70238 15.001 6.6876 15.0009 6.66949L15 6.54761C14.9999 6.52946 14.9851 6.51488 14.967 6.51503ZM13.9669 19.2544H15.9506C16.0518 19.2544 16.1339 19.3364 16.1339 19.4377V19.4442C16.1339 19.5454 16.0518 19.6275 15.9506 19.6275H13.9669C13.8656 19.6275 13.7836 19.5454 13.7836 19.4442V19.4377C13.7836 19.3364 13.8656 19.2544 13.9669 19.2544ZM18.4641 19.8281H18.1453C18.1298 19.8281 18.1172 19.8407 18.1172 19.8562V19.9875C18.1172 20.003 18.1298 20.0156 18.1453 20.0156H18.4641C18.4796 20.0156 18.4922 20.003 18.4922 19.9875V19.8562C18.4922 19.8407 18.4796 19.8281 18.4641 19.8281ZM19.0828 19.8281H19.4016C19.4171 19.8281 19.4297 19.8407 19.4297 19.8562V19.9875C19.4297 20.003 19.4171 20.0156 19.4016 20.0156H19.0828C19.0673 20.0156 19.0547 20.003 19.0547 19.9875V19.8562C19.0547 19.8407 19.0673 19.8281 19.0828 19.8281ZM4.68146 19.8626L4.36928 19.8593C4.35248 19.8591 4.33868 19.8726 4.33849 19.8895L4.33718 20.0179C4.33699 20.0347 4.35049 20.0485 4.36729 20.0487L4.67948 20.0519C4.69631 20.0521 4.71008 20.0386 4.71026 20.0218L4.71161 19.8934C4.7118 19.8765 4.6983 19.8627 4.68146 19.8626ZM5.31675 19.8589L5.61675 19.861C5.64008 19.8612 5.65883 19.8802 5.65864 19.9035L5.65793 20.0095C5.65774 20.0328 5.63873 20.0515 5.61544 20.0514L5.31544 20.0493C5.29215 20.0491 5.2734 20.0301 5.27355 20.0068L5.2743 19.9008C5.27445 19.8775 5.29346 19.8588 5.31675 19.8589ZM6.56486 19.8622L6.24986 19.8606C6.23227 19.8605 6.21791 19.8747 6.21784 19.8923L6.21716 20.017C6.21709 20.0346 6.23126 20.0489 6.24889 20.049L6.56389 20.0506C6.58148 20.0508 6.59584 20.0366 6.59591 20.019L6.59655 19.8943C6.59666 19.8767 6.58245 19.8623 6.56486 19.8622ZM7.19002 19.8595L7.50502 19.8623C7.52107 19.8625 7.53397 19.8756 7.53382 19.8916L7.5327 20.0229C7.53255 20.0389 7.51942 20.0518 7.50337 20.0517L7.18837 20.0489C7.17232 20.0488 7.15942 20.0357 7.15957 20.0196L7.16074 19.8884C7.16085 19.8723 7.17397 19.8594 7.19002 19.8595ZM8.44346 19.8623L8.12752 19.8595C8.11147 19.8594 8.09835 19.8723 8.09824 19.8884L8.09707 20.0196C8.09692 20.0356 8.10982 20.0488 8.12587 20.0489L8.44181 20.0517C8.45786 20.0518 8.47099 20.0389 8.47114 20.0229L8.47226 19.8916C8.47241 19.8756 8.45951 19.8625 8.44346 19.8623ZM9.06502 19.8595L9.38096 19.8623C9.39701 19.8625 9.40991 19.8756 9.40976 19.8916L9.40864 20.0229C9.40849 20.0389 9.39536 20.0518 9.37931 20.0517L9.06337 20.0489C9.04732 20.0488 9.03442 20.0356 9.03457 20.0196L9.03574 19.8884C9.03585 19.8723 9.04897 19.8594 9.06502 19.8595ZM10.3226 19.8634L10.001 19.8594C9.98651 19.8593 9.97462 19.8709 9.97444 19.8854L9.97279 20.0222C9.9726 20.0367 9.98419 20.0486 9.9987 20.0488L10.3202 20.0527C10.3347 20.0529 10.3466 20.0413 10.3468 20.0268L10.3485 19.89C10.3486 19.8754 10.3371 19.8636 10.3226 19.8634ZM10.9385 19.8594L11.2601 19.8634C11.2746 19.8636 11.2861 19.8754 11.286 19.89L11.2843 20.0268C11.2841 20.0413 11.2722 20.0529 11.2577 20.0527L10.9362 20.0488C10.9217 20.0486 10.9101 20.0367 10.9103 20.0222L10.9119 19.8854C10.9121 19.8709 10.924 19.8593 10.9385 19.8594ZM12.1946 19.8636L11.8786 19.862C11.8623 19.8619 11.849 19.875 11.8489 19.8913L11.8482 20.0198C11.8482 20.0361 11.8613 20.0494 11.8776 20.0495L12.1936 20.0511C12.2099 20.0512 12.2232 20.0381 12.2232 20.0218L12.2239 19.8933C12.224 19.877 12.2109 19.8637 12.1946 19.8636ZM14.7951 20.3798H15.9529C16.0532 20.3798 16.1344 20.461 16.1344 20.5612V20.5716C16.1344 20.6718 16.0532 20.753 15.9529 20.753H14.7951C14.695 20.753 14.6138 20.6718 14.6138 20.5716V20.5612C14.6138 20.461 14.695 20.3798 14.7951 20.3798Z'\n            fill={color}\n          />\n        </g>\n      </g>\n      <defs>\n        <clipPath id='clip0_1_66'>\n          <rect width='24' height='24' fill={color} />\n        </clipPath>\n      </defs>\n    </svg>\n  )\n}\n\n\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/svg/redPacketSvg.tsx",
    "content": "import { SoursURL } from '../constant'\nimport { sanitize } from 'dompurify'\nimport React from 'react'\n\nexport const RedPacketColorConfig: {\n  default: ColorConfig\n  official: ColorConfig\n} = {\n  default: {\n    colorTop: '#FD7659',\n    startColor: '#FC7A5A',\n    endColor: '#FF6151',\n    bgColor: '#ffffff',\n    fontColor: '#FFF7B1',\n    btnColor: '#FD7659',\n    qrColor: '#FD7659',\n  },\n  official: {\n    colorTop: '#FFD595',\n    startColor: '#FFD596',\n    endColor: '#FDBD6A',\n    bgColor: '#ffffff',\n    fontColor: '#A25402',\n    btnColor: '#FD7659',\n    qrColor: '#A25402',\n  },\n}\nexport const RedPacketCssColorConfig: {\n  default: ColorCssConfig\n  official: ColorCssConfig\n  blindbox: ColorCssConfig\n} = {\n  default: {\n    colorTop: '#FD7659',\n    startColor: '#FC7A5A',\n    endColor: '#FF6151',\n    startBgColor: '#FC7A5A',\n    endBgColor: '#930D00',\n    startCard: '#FEF4DE',\n    endCard: '#FED897',\n    line: '#D4B164',\n    highLightColor: '#A25402',\n    highLightDisableColor: '#A25402',\n    primaryColor: '#FFF7B1',\n    secondaryColor: '#D09145',\n    disableColor: '#7C3400',\n  },\n  official: {\n    colorTop: '#FFD595',\n    startColor: '#FFD596',\n    endColor: '#FDBD6A',\n    startBgColor: '#FFD595',\n    endBgColor: '#934F00',\n    startCard: '#FEF4DE',\n    endCard: '#FED897',\n    line: '#D4B164',\n    highLightColor: '#A25402',\n    highLightDisableColor: '#A25402',\n    primaryColor: '#A25402',\n    secondaryColor: '#D09145',\n    disableColor: '#7C3400',\n  },\n  blindbox: {\n    // background: linear-gradient(95.9deg, #A35388 0.7%, #FF6151 99.3%);\n\n    colorTop: \"url('#gradient1')\",\n    startColor: '#A35388',\n    endColor: '#FF6151',\n    startBgColor: '#FC7A5A',\n    endBgColor: '#930D00',\n    startCard: '#FEF4DE',\n    endCard: '#FED897',\n    line: '#D4B164',\n    highLightColor: '#A25402',\n    highLightDisableColor: '#A25402',\n    primaryColor: '#FFF7B1',\n    secondaryColor: '#D09145',\n    disableColor: '#7C3400',\n  },\n}\nexport const RedPacketWrapSVG = ({\n  colorTop,\n  startColor,\n  endColor,\n  type,\n}: {\n  type: 'default' | 'official' | 'blindbox'\n  colorTop: '#FD7659' | '#FFD595'\n  startColor: '#FC7A5A' | '#FFD596'\n  endColor: '#FF6151' | '#FDBD6A'\n}) => {\n  return (\n    <svg width={274} height={414} viewBox='0 0 274 414' aria-hidden='true'>\n      <path\n        d='M7 13C7 7.47714 11.4772 3 17 3H257C262.523 3 267 7.47715 267 13V393C267 398.523 262.523 403 257 403H17C11.4772 403 7 398.523 7 393V13Z'\n        fill={`url(#paint_linear_${type})`}\n      />\n      <g filter={`url(#filterWrap${type}1)`}>\n        <path\n          d='M17 3C11.4771 3 7 7.47716 7 13V108.095C7 112.092 9.3688 115.728 13.1024 117.154C43.3399 128.709 87.6387 136 137 136C186.361 136 230.66 128.709 260.898 117.154C264.631 115.728 267 112.092 267 108.095V13C267 7.47716 262.523 3 257 3H17Z'\n          fill={colorTop}\n        />\n      </g>\n      {type === 'blindbox' && (\n        <image\n          style={{ transform: 'translate(37px, 150px)' }}\n          opacity={'0.2'}\n          href={SoursURL + 'images/redpackBlind3.webp'}\n          height='200'\n          width='200'\n        />\n      )}\n      <defs>\n        <filter\n          id={`filterWrap${type}1`}\n          x='0'\n          y='0'\n          width='274'\n          height='147'\n          filterUnits='userSpaceOnUse'\n          colorInterpolationFilters='sRGB'\n        >\n          <feFlood floodOpacity='0' result='BackgroundImageFix' />\n          <feColorMatrix\n            in='SourceAlpha'\n            type='matrix'\n            values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0'\n            result='hardAlpha'\n          />\n          <feOffset dy='4' />\n          <feGaussianBlur stdDeviation='3.5' />\n          <feComposite in2='hardAlpha' operator='out' />\n          <feColorMatrix type='matrix' values='0 0 0 0 0.745276 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0' />\n          <feBlend mode='normal' in2='BackgroundImageFix' result='effect1_dropShadow_8955_1158' />\n          <feBlend\n            mode='normal'\n            in='SourceGraphic'\n            in2='effect1_dropShadow_8955_1158'\n            result='shape'\n          />\n        </filter>\n        <linearGradient gradientTransform='rotate(95.9deg)' id={`paint_linear_${type}`}>\n          <stop offset='0.7%' stop-color={startColor} />\n          <stop offset='99.3%' stop-color={endColor} />\n        </linearGradient>\n        <linearGradient gradientTransform='rotate(95.9deg)' id='gradient1'>\n          <stop offset='0.7%' stop-color='#A35388' />\n          <stop offset='99.3%' stop-color='#FF6151' />\n        </linearGradient>\n      </defs>\n    </svg>\n  )\n}\n\nexport const RedPacketOpenWrapSVG = ({\n  // colorTop,\n  startColor,\n  endColor,\n  startBgColor,\n  endBgColor,\n  startCard,\n  endCard,\n  line,\n  type,\n}: {\n  type: 'default' | 'official' | 'blindbox'\n  colorTop: '#FD7659' | '#FFD595'\n  startColor: '#FC7A5A' | '#FFD596'\n  endColor: '#FF6151' | '#FDBD6A'\n  startBgColor: '#FC7A5A' | '#FFD595'\n  endBgColor: '#930D00' | '#934F00'\n  startCard: '#FEF4DE'\n  endCard: '#FED897'\n  line: '#D4B164'\n} & Partial<React.SVGProps<SVGSVGElement>>) => {\n  return (\n    <svg width={274} height={414} viewBox='0 0 274 414' aria-hidden='true'>\n      <g transform={'translate(7 7)'}>\n        <path\n          d='M0 39C0 33.4772 4.47715 29 10 29H250C255.523 29 260 33.4772 260 39V393C260 398.523 255.523 403 250 403H10C4.47716 403 0 398.523 0 393V39Z'\n          fill={`url(#paint${type}0)`}\n        />\n        <path\n          fillRule='evenodd'\n          clipRule='evenodd'\n          d='M130 14C137.732 14 144 7.73199 144 0H236C240.418 0 244 3.58172 244 8V180C244 184.418 240.418 188 236 188H24C19.5817 188 16 184.418 16 180V8C16 3.58172 19.5817 0 24 0H116C116 7.73199 122.268 14 130 14Z'\n          fill={`url(#paint${type}1)`}\n        />\n        <path\n          fillRule='evenodd'\n          clipRule='evenodd'\n          d='M111.976 13.6182C111.609 13.0951 111.264 12.5552 110.943 12H108.945V13H110.375C110.624 13.406 110.885 13.8036 111.157 14.1924L111.976 13.6182ZM34.5551 13.3475L35.1114 14.1784C34.3476 14.6898 33.6898 15.3476 33.1784 16.1114L32.3475 15.5551C32.9315 14.6827 33.6827 13.9315 34.5551 13.3475ZM31 166.053H32V168C32 168.469 32.0459 168.926 32.1333 169.367L31.1523 169.561C31.0524 169.056 31 168.534 31 168V166.053ZM32.3475 172.445L33.1784 171.889C33.6898 172.652 34.3476 173.31 35.1114 173.822L34.5551 174.653C33.6827 174.068 32.9315 173.317 32.3475 172.445ZM219.906 176V175H221.894C222.362 175 222.819 174.954 223.261 174.867L223.455 175.848C222.95 175.948 222.428 176 221.894 176H219.906ZM226.339 174.653L225.782 173.822C226.546 173.31 227.204 172.652 227.715 171.889L228.546 172.445C227.962 173.317 227.211 174.068 226.339 174.653ZM229.894 21.9474H228.894V20C228.894 19.5312 228.848 19.0742 228.76 18.6328L229.741 18.4387C229.841 18.9437 229.894 19.4657 229.894 20V21.9474ZM228.546 15.5551L227.715 16.1114C227.204 15.3476 226.546 14.6898 225.782 14.1784L226.339 13.3475C227.211 13.9315 227.962 14.6827 228.546 15.5551ZM151.08 12V13H149.625C149.376 13.406 149.115 13.8036 148.843 14.1924L148.024 13.6182C148.391 13.0951 148.736 12.5552 149.057 12H151.08ZM145.557 16.5555L146.264 17.2625C145.319 18.2078 144.292 19.0712 143.195 19.8411L142.62 19.0225C143.67 18.2859 144.653 17.4599 145.557 16.5555ZM139.3 20.9433L139.723 21.8494C138.52 22.4114 137.26 22.8724 135.955 23.2215L135.696 22.2554C136.945 21.9217 138.15 21.4808 139.3 20.9433ZM131.919 22.9175L132.005 23.9138C131.344 23.9709 130.675 24 130 24C129.325 24 128.656 23.9709 127.995 23.9138L128.081 22.9175C128.714 22.9721 129.354 23 130 23C130.646 23 131.286 22.9721 131.919 22.9175ZM124.304 22.2554L124.045 23.2215C122.74 22.8724 121.48 22.4114 120.277 21.8494L120.7 20.9433C121.85 21.4808 123.055 21.9217 124.304 22.2554ZM117.38 19.0225L116.805 19.8411C115.708 19.0712 114.681 18.2078 113.736 17.2625L114.443 16.5555C115.347 17.4599 116.33 18.2859 117.38 19.0225ZM155.127 12V13H159.173V12H155.127ZM163.22 12V13H167.266V12H163.22ZM171.312 12V13H175.359V12H171.312ZM179.405 12V13H183.452V12H179.405ZM187.498 12V13H191.545V12H187.498ZM195.591 12V13H199.638V12H195.591ZM203.684 12V13H207.731V12H203.684ZM211.777 12V13H215.824V12H211.777ZM219.87 12V13H221.894C222.362 13 222.819 13.0459 223.261 13.1333L223.455 12.1523C222.95 12.0524 222.428 12 221.894 12H219.87ZM229.894 25.8421H228.894V29.7368H229.894V25.8421ZM229.894 33.6316H228.894V37.5263H229.894V33.6316ZM229.894 41.421H228.894V45.3158H229.894V41.421ZM229.894 49.2105H228.894V53.1053H229.894V49.2105ZM229.894 57H228.894V60.8947H229.894V57ZM229.894 64.7895H228.894V68.6842H229.894V64.7895ZM229.894 72.5789H228.894V76.4737H229.894V72.5789ZM229.894 80.3684H228.894V84.2632H229.894V80.3684ZM229.894 88.1579H228.894V92.0526H229.894V88.1579ZM229.894 95.9474H228.894V99.8421H229.894V95.9474ZM229.894 103.737H228.894V107.632H229.894V103.737ZM229.894 111.526H228.894V115.421H229.894V111.526ZM229.894 119.316H228.894V123.211H229.894V119.316ZM229.894 127.105H228.894V131H229.894V127.105ZM229.894 134.895H228.894V138.789H229.894V134.895ZM229.894 142.684H228.894V146.579H229.894V142.684ZM229.894 150.474H228.894V154.368H229.894V150.474ZM229.894 158.263H228.894V162.158H229.894V158.263ZM229.894 166.053H228.894V168C228.894 168.469 228.848 168.926 228.76 169.367L229.741 169.561C229.841 169.056 229.894 168.534 229.894 168V166.053ZM215.93 176V175H211.954V176H215.93ZM207.978 176V175H204.002V176H207.978ZM200.026 176V175H196.05V176H200.026ZM192.074 176V175H188.098V176H192.074ZM184.122 176V175H180.146V176H184.122ZM176.17 176V175H172.194V176H176.17ZM168.218 176V175H164.242V176H168.218ZM160.266 176V175H156.29V176H160.266ZM152.314 176V175H148.339V176H152.314ZM144.363 176V175H140.387V176H144.363ZM136.411 176V175H132.435V176H136.411ZM128.459 176V175H124.483V176H128.459ZM120.507 176V175H116.531V176H120.507ZM112.555 176V175H108.579V176H112.555ZM104.603 176V175H100.627V176H104.603ZM96.6513 176V175H92.6753V176H96.6513ZM88.6994 176V175H84.7234V176H88.6994ZM80.7475 176V175H76.7715V176H80.7475ZM72.7956 176V175H68.8196V176H72.7956ZM64.8437 176V175H60.8677V176H64.8437ZM56.8918 176V175H52.9158V176H56.8918ZM48.9399 176V175H44.9639V176H48.9399ZM40.988 176V175H39C38.5312 175 38.0742 174.954 37.6328 174.867L37.4387 175.848C37.9437 175.948 38.4657 176 39 176H40.988ZM31 162.158H32V158.263H31V162.158ZM31 154.368H32V150.474H31V154.368ZM31 146.579H32V142.684H31V146.579ZM31 138.789H32V134.895H31V138.789ZM31 131H32V127.105H31V131ZM31 123.211H32V119.316H31V123.211ZM31 115.421H32V111.526H31V115.421ZM31 107.632H32V103.737H31V107.632ZM31 99.8421H32V95.9474H31V99.8421ZM31 92.0526H32V88.1579H31V92.0526ZM31 84.2632H32V80.3684H31V84.2632ZM31 76.4737H32V72.579H31V76.4737ZM31 68.6842H32V64.7895H31V68.6842ZM31 60.8947H32V57H31V60.8947ZM31 53.1053H32V49.2105H31V53.1053ZM31 45.3158H32V41.4211H31V45.3158ZM31 37.5263H32V33.6316H31V37.5263ZM31 29.7368H32V25.8421H31V29.7368ZM31 21.9474H32V20C32 19.5312 32.0459 19.0742 32.1333 18.6328L31.1523 18.4387C31.0524 18.9437 31 19.4657 31 20V21.9474ZM37.4387 12.1523L37.6328 13.1333C38.0742 13.0459 38.5312 13 39 13H40.9984V12H39C38.4657 12 37.9437 12.0524 37.4387 12.1523ZM44.9953 12V13H48.9921V12H44.9953ZM52.989 12V13H56.9858V12H52.989ZM60.9826 12V13H64.9795V12H60.9826ZM68.9763 12V13H72.9732V12H68.9763ZM76.97 12V13H80.9669V12H76.97ZM84.9637 12V13H88.9606V12H84.9637ZM92.9574 12V13H96.9543V12H92.9574ZM100.951 12V13H104.948V12H100.951Z'\n          fill={line}\n        />\n        <g filter={`url(#filterOpenWrap${type}0)`}>\n          <path\n            d='M0 108.095V393C0 398.523 4.47716 403 10 403H250C255.523 403 260 398.523 260 393V108.095C260 112.092 257.631 115.728 253.898 117.154C223.66 128.709 179.361 136 130 136C80.6387 136 36.3399 128.709 6.10237 117.154C2.3688 115.728 0 112.092 0 108.095Z'\n            fill={`url(#paint${type}2)`}\n          />\n        </g>\n        {type === 'blindbox' && (\n          <image\n            style={{ transform: 'translate(30px, 150px)' }}\n            opacity={'0.2'}\n            href={SoursURL + 'images/redpackBlind3.webp'}\n            height='200'\n            width='200'\n          />\n        )}\n      </g>\n\n      <defs>\n        <filter\n          id={`filterOpenWrap${type}0`}\n          x='0'\n          y='108.095'\n          width='260'\n          height='294.905'\n          filterUnits='userSpaceOnUse'\n          colorInterpolationFilters='sRGB'\n        >\n          <feFlood floodOpacity='0' result='BackgroundImageFix' />\n          <feBlend mode='normal' in='SourceGraphic' in2='BackgroundImageFix' result='shape' />\n          <feColorMatrix\n            in='SourceAlpha'\n            type='matrix'\n            values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0'\n            result='hardAlpha'\n          />\n          <feOffset dy='3' />\n          <feComposite in2='hardAlpha' operator='arithmetic' k2='-1' k3='1' />\n          <feColorMatrix type='matrix' values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.25 0' />\n          <feBlend mode='normal' in2='shape' result='effect1_innerShadow_8955_1198' />\n        </filter>\n        <linearGradient gradientTransform='rotate(95.9deg)' id={`paint${type}0`}>\n          <stop offset='0.7%' stop-color={startBgColor} />\n          <stop offset='99.3%' stop-color={endBgColor} />\n        </linearGradient>\n        <linearGradient gradientTransform='rotate(95.9deg)' id={`paint${type}1`}>\n          <stop offset='0.7%' stop-color={startCard} />\n          <stop offset='99.3%' stop-color={endCard} />\n        </linearGradient>\n        <linearGradient gradientTransform='rotate(95.9deg)' id={`paint${type}2`}>\n          <stop offset='0.7%' stop-color={startColor} />\n          <stop offset='99.3%' stop-color={endColor} />\n        </linearGradient>\n        {/* <linearGradient gradientTransform=\"rotate(95.9deg)\" id=\"gradient1\">\n          <stop offset=\"0.7%\" stop-color=\"#A35388\" />\n          <stop offset=\"99.3%\" stop-color=\"#FF6151\" />\n        </linearGradient> */}\n\n        {/* <linearGradient\n          id={`paint${type}0`}\n          x1=\"130\"\n          y1=\"29\"\n          x2=\"130\"\n          y2=\"164.5\"\n          gradientUnits=\"userSpaceOnUse\"\n        >\n          <stop stopColor={startBgColor} />\n          <stop offset=\"1\" stopColor={endBgColor} />\n        </linearGradient>\n        <linearGradient\n          id={`paint${type}1`}\n          x1=\"130\"\n          y1=\"0\"\n          x2=\"130\"\n          y2=\"318\"\n          gradientUnits=\"userSpaceOnUse\"\n        >\n          <stop stopColor={startCard} />\n          <stop offset=\"1\" stopColor={endCard} />\n        </linearGradient>\n        <linearGradient\n          id={`paint${type}2`}\n          x1=\"130\"\n          y1=\"2.99983\"\n          x2=\"328.271\"\n          y2=\"176.757\"\n          gradientUnits=\"userSpaceOnUse\"\n        >\n          <stop stopColor={startColor} />\n          <stop offset=\"1\" stopColor={endColor} />\n        </linearGradient> */}\n      </defs>\n    </svg>\n  )\n}\nexport type RedPacketQRPropsExtends = {\n  textAddress: string\n  textContent: string\n  amountStr: string\n  textSendBy: string //text send by\n  textType: string\n  textShared: string\n  textNo: string\n  textDes: string\n  imageEleUrl?: string\n  onClickShareButton?: (e: React.MouseEvent<SVGGElement, MouseEvent>) => void\n}\nexport type ColorConfig = {\n  colorTop: string\n  startColor: string\n  endColor: string\n  bgColor: string\n  fontColor: string\n  btnColor: string\n  qrColor: string\n}\nexport type ColorCssConfig = {\n  colorTop: string\n  startColor: string\n  endColor: '#FF6151' | '#FDBD6A'\n  startBgColor: '#FC7A5A' | '#FFD595'\n  endBgColor: '#930D00' | '#934F00'\n  startCard: '#FEF4DE'\n  endCard: '#FED897'\n  line: '#D4B164'\n  highLightColor: '#A25402'\n  highLightDisableColor: '#A25402'\n  primaryColor: '#FFF7B1' | '#A25402'\n  secondaryColor: '#D09145'\n  disableColor: '#7C3400'\n}\nexport const RedPacketQRCodeSvg = React.memo(\n  React.forwardRef(\n    (\n      {\n        startColor,\n        endColor,\n        colorTop,\n        bgColor,\n        fontColor,\n        btnColor,\n        type,\n        qrcodeRef,\n        textAddress,\n        textContent,\n        amountStr,\n        qrCodeG,\n        textSendBy,\n        textType,\n        textShared,\n        textNo,\n        textDes,\n        imageEleUrl,\n        onClickShareButton,\n      }: ColorConfig & {\n        type: 'default' | 'official'\n        qrcodeRef: React.Ref<SVGGElement>\n        // qrCodeG;\n      } & RedPacketQRPropsExtends & {\n          qrcodeRef: React.Ref<SVGGElement>\n          qrCodeG: string\n        },\n      ref: React.ForwardedRef<any>,\n    ) => {\n      const [[textContent1, textContent2], setTextContent] = React.useState([\n        textContent,\n        // \"textContentdaskdjhkas jhdkjashdkjhaskjdhsakjhdkashd\",\n        '',\n      ])\n      // const imageRef = React.useRef<any>();\n\n      const [imageBase64, setImageBase64] = React.useState<string>(imageEleUrl ?? '')\n      React.useEffect(() => {\n        if (imageEleUrl) {\n          fetch(imageEleUrl)\n            .then((result) => result.blob())\n            .then((result) => {\n              const reader = new FileReader()\n              reader.onloadend = () => {\n                // @ts-ignore\n                setImageBase64((state) => reader?.result ?? state)\n              }\n\n              reader.onerror = () => {\n                console.log('reader error')\n              }\n              reader.readAsDataURL(result)\n\n              // myLog(\"blob\", result.stream());\n              // if (result) {\n              //   setImageBase64(result.toString());\n              // }\n            })\n        }\n      }, [imageEleUrl])\n\n      React.useEffect(() => {\n        const [str1, str2] = textContent?.split('\\n')\n        if (textContent && str2) {\n          setTextContent([str1, str2])\n        } else if (textContent && textContent.length > 12) {\n          const value = textContent.substring(0, 12)\n          let _textContent2 = textContent.substring(12, textContent.length)\n          const textArray = value.split(' ')\n          _textContent2 = (textArray.length > 2 ? textArray.pop() : '') + _textContent2\n          const _textContent1 = textArray.join(' ')\n          setTextContent([_textContent1, _textContent2])\n        }\n      }, [textContent])\n\n      const station = imageEleUrl ? [36, 68, 86, 188] : [56, 88, 106, 186]\n      return (\n        <>\n          <svg\n            ref={ref}\n            width='334'\n            height='603'\n            viewBox='0 0 334 603'\n            fill='none'\n            xmlns='http://www.w3.org/2000/svg'\n          >\n            <path\n              d='M7 13C7 7.47714 11.4772 3 17 3H317C322.523 3 327 7.47715 327 13V593C327 598.523 322.523 603 317 603H17C11.4772 603 7 598.523 7 593V13Z'\n              fill={`url(#paintQRCode${type}0)`}\n            />\n            <path\n              onClick={onClickShareButton}\n              d='M108 537C108 527.059 116.059 519 126 519H208C217.941 519 226 527.059 226 537V537C226 546.941 217.941 555 208 555H126C116.059 555 108 546.941 108 537V537Z'\n              fill={bgColor}\n            />\n            {!!textSendBy && (\n              <path\n                opacity='0.16'\n                d='M31 428C31 423.582 34.5817 420 39 420H295C299.418 420 303 423.582 303 428V477C303 481.418 299.418 485 295 485H39C34.5817 485 31 481.418 31 477V428Z'\n                fill='white'\n              />\n            )}\n            <g filter={`url(#filterQRCode${type}0)`}>\n              <path\n                d='M19.3077 3C12.5103 3 7 8.52071 7 15.3308V134.131C7 138.126 9.36023 141.753 13.0801 143.208C50.3215 157.777 105.464 167 167 167C228.536 167 283.679 157.777 320.92 143.208C324.64 141.753 327 138.126 327 134.131V15.3308C327 8.52071 321.49 3 314.692 3H19.3077Z'\n                fill={colorTop}\n              />\n            </g>\n            <path\n              opacity='0.16'\n              d='M225 3H319C323.418 3 327 6.58172 327 11V30H233C228.582 30 225 26.4183 225 22V3Z'\n              fill='white'\n            />\n            <defs>\n              <filter\n                id={`filterQRCode${type}0`}\n                x='0'\n                y='0'\n                width='334'\n                height='178'\n                filterUnits='userSpaceOnUse'\n                colorInterpolationFilters='sRGB'\n              >\n                <feFlood floodOpacity='0' result='BackgroundImageFix' />\n                <feColorMatrix\n                  in='SourceAlpha'\n                  type='matrix'\n                  values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0'\n                  result='hardAlpha'\n                />\n                <feOffset dy='4' />\n                <feGaussianBlur stdDeviation='3.5' />\n                <feComposite in2='hardAlpha' operator='out' />\n                <feColorMatrix\n                  type='matrix'\n                  values={\n                    type == 'official'\n                      ? '0 0 0 0 0.745276 0 0 0 0 0.402449 0 0 0 0 0 0 0 0 0.25 0'\n                      : '0 0 0 0 0.745276 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0'\n                  }\n                  // values=\"0 0 0 0 0.745276 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0\"\n                />\n                <feBlend\n                  mode='normal'\n                  in2='BackgroundImageFix'\n                  result='effect1_dropShadow_8960_1241'\n                />\n                <feBlend\n                  mode='normal'\n                  in='SourceGraphic'\n                  in2='effect1_dropShadow_8960_1241'\n                  result='shape'\n                />\n              </filter>\n              <linearGradient\n                id={`paintQRCode${type}0`}\n                x1='167'\n                y1='2.99995'\n                x2='451.393'\n                y2='207.498'\n                gradientUnits='userSpaceOnUse'\n              >\n                <stop stopColor={startColor} />\n                <stop offset='1' stopColor={endColor} />\n              </linearGradient>\n            </defs>\n            <g\n              ref={qrcodeRef}\n              transform={'translate(67 210)'}\n              width='160'\n              height='160'\n              dangerouslySetInnerHTML={{ __html: qrCodeG ?? '' }}\n            >\n              {/*<rect className={\"qrcode\"} width=\"160\" height=\"160\" fill=\"#D9D9D9\" />*/}\n              {/*{qrCodeG}*/}\n            </g>\n            {imageEleUrl && (\n              <image transform={'translate(128 90)'} href={imageBase64} height='80' width='80' />\n            )}\n\n            <g transform={`translate(167 ${station[0]})`}>\n              {/*<rect x=\"15.5\" y=\"45.5\" width=\"280\" height=\"21\" />*/}\n              <text\n                className={'textAddress'}\n                strokeWidth='0'\n                fill={fontColor}\n                x='1'\n                y='1'\n                style={{\n                  dominantBaseline: 'central',\n                  textAnchor: 'middle',\n                  fontSize: '14px',\n                }}\n              >\n                {textAddress}\n              </text>\n            </g>\n            <g transform={`translate(167 ${station[1]})`}>\n              <text\n                className={'textContent1'}\n                strokeWidth='0'\n                fill={fontColor}\n                x='1'\n                y='1'\n                style={{\n                  dominantBaseline: 'central',\n                  textAnchor: 'middle',\n                  fontSize: '14px',\n                }}\n                dangerouslySetInnerHTML={{ __html: sanitize(textContent1) }}\n              />\n            </g>\n            <g transform={`translate(167 ${station[2]})`}>\n              <text\n                className={'textContent2'}\n                strokeWidth='0'\n                fill={fontColor}\n                x='1'\n                y='1'\n                style={{\n                  dominantBaseline: 'central',\n                  textAnchor: 'middle',\n                  fontSize: '14px',\n                }}\n                dangerouslySetInnerHTML={{\n                  __html:\n                    textContent2 &&\n                    sanitize(\n                      textContent2.length > 12 ? textContent2.slice(0, 12) + '...' : textContent2,\n                    ),\n                }}\n              />\n            </g>\n            <g transform={`translate(167 ${station[3]})`}>\n              <text\n                id={'amountStr'}\n                strokeWidth='0'\n                fill={fontColor}\n                x='1'\n                y='1'\n                style={{\n                  dominantBaseline: 'central',\n                  textAnchor: 'middle',\n                  fontSize: '28px',\n                }}\n              >\n                {amountStr}\n              </text>\n            </g>\n            <g transform={'translate(276 14)'}>\n              <text\n                className={'textType'}\n                strokeWidth='0'\n                fill={fontColor}\n                x='1'\n                y='1'\n                style={{\n                  dominantBaseline: 'central',\n                  textAnchor: 'middle',\n                  fontSize: '10px',\n                }}\n              >\n                {textType}\n              </text>\n            </g>\n            <g transform={'translate(167 434)'}>\n              <text\n                id={'textSendBy'}\n                strokeWidth='0'\n                fill={fontColor}\n                x='1'\n                y='1'\n                style={{\n                  dominantBaseline: 'central',\n                  textAnchor: 'middle',\n                  fontSize: '12px',\n                }}\n              >\n                {textDes\n                  .split(' ')\n                  .slice(0, Math.ceil(textDes.split(' ').length / 2))\n                  .join(' ')}\n              </text>\n            </g>\n            <g transform={'translate(167 452)'}>\n              <text\n                id={'textSendBy'}\n                strokeWidth='0'\n                fill={fontColor}\n                x='1'\n                y='1'\n                style={{\n                  dominantBaseline: 'central',\n                  textAnchor: 'middle',\n                  fontSize: '12px',\n                }}\n              >\n                {textDes\n                  .split(' ')\n                  .slice(Math.ceil(textDes.split(' ').length / 2))\n                  .join(' ')}\n              </text>\n            </g>\n            <g transform={'translate(167 470)'}>\n              <text\n                id={'textSendBy'}\n                strokeWidth='0'\n                fill={fontColor}\n                x='1'\n                y='1'\n                style={{\n                  dominantBaseline: 'central',\n                  textAnchor: 'middle',\n                  fontSize: '12px',\n                }}\n                dangerouslySetInnerHTML={{ __html: textSendBy }}\n              />\n            </g>\n            <g onClick={onClickShareButton} transform={'translate(167 535)'}>\n              <text\n                className={'textShared'}\n                strokeWidth='0'\n                fill={btnColor}\n                x='1'\n                y='1'\n                style={{\n                  dominantBaseline: 'central',\n                  textAnchor: 'middle',\n                  fontSize: '16px',\n                }}\n              >\n                {textShared}\n              </text>\n            </g>\n            <g transform={'translate(167 568)'}>\n              <text\n                className={'textNo'}\n                strokeWidth='0'\n                fill={fontColor}\n                x='1'\n                y='1'\n                style={{\n                  dominantBaseline: 'central',\n                  textAnchor: 'middle',\n                  fontSize: '12px',\n                }}\n              >\n                {textNo}\n              </text>\n            </g>\n          </svg>\n        </>\n      )\n    },\n  ),\n)\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/svg/shareReferral.tsx",
    "content": "import { WithTranslation, withTranslation } from 'react-i18next'\nimport React from 'react'\n\nexport type ShareReferralSvgProps = {\n  src: string\n  code: string\n  label?: string\n  height?: number\n  width?: number\n  bottom?: number\n  left?: number\n  fontColor?: string\n  name?: string\n}\nexport const ShareReferralSvg = withTranslation('common', { withRef: true })(\n  React.memo(\n    React.forwardRef(\n      (\n        {\n          t,\n          code,\n          label = t('labelReferralImageDes'),\n          height = 880,\n          width = 630,\n          src,\n          bottom = 30,\n          left = 48,\n          name,\n          fontColor = '#000000',\n        }: ShareReferralSvgProps & WithTranslation,\n        ref: React.ForwardedRef<any>,\n      ) => {\n        const lebelY = height - bottom - 100 + 10\n        const lebelX = left\n        const lebelCodeY = lebelY + 60\n        const lebelCodeX = left\n        const labelCode = t('labelReferralImageCode', { code })\n\n        return (\n          <>\n            <svg\n              ref={ref}\n              name={name}\n              width={width}\n              height={height}\n              viewBox={`0 0 ${width} ${height}`}\n              aria-hidden='true'\n            >\n              <image width={width} height={height} href={src} />\n              <g transform={`translate(${lebelX} ${lebelY})`}>\n                <text\n                  strokeWidth='0'\n                  fill={fontColor}\n                  x='1'\n                  y='1'\n                  style={{\n                    dominantBaseline: 'central',\n                    textAnchor: 'start',\n                    fontSize: '28px',\n                  }}\n                >\n                  {label}\n                </text>\n              </g>\n              <g transform={`translate(${lebelCodeX} ${lebelCodeY})`}>\n                <text\n                  strokeWidth='0'\n                  fill={fontColor}\n                  x='1'\n                  y='1'\n                  style={{\n                    dominantBaseline: 'central',\n                    textAnchor: 'start',\n                    fontSize: '44px',\n                  }}\n                >\n                  {labelCode}\n                </text>\n              </g>\n            </svg>\n          </>\n        )\n      },\n    ),\n  ),\n)\n// export const ShareReferralSvg = _ShareReferralSvg)\n// ) as (\n//   props: ShareReferralSvgProps & WithTranslation & RefAttributes<any>\n// ) => JSX.Element;\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/themes/css/color-lib.ts",
    "content": "export const hexToRGB = (hex: string, alpha?: string | number) => {\n  var r = parseInt(hex.slice(1, 3), 16),\n    g = parseInt(hex.slice(3, 5), 16),\n    b = parseInt(hex.slice(5, 7), 16)\n\n  if (alpha !== undefined) {\n    return 'rgba(' + r + ', ' + g + ', ' + b + ', ' + alpha.toString() + ')'\n  } else {\n    return 'rgb(' + r + ', ' + g + ', ' + b + ')'\n  }\n}\n\nexport const GrayBlack = {\n  gray100: '#EBEEF5',\n  gray200: '#A2A9B8',\n  gray300: '#6C717A',\n  gray400: '#5E6470',\n  gray500: '#4A505C',\n  gray600: '#393E47',\n  gray700: '#31353D',\n  gray800: '#25282E',\n  gray900: '#25282E',\n  gray1000: '#31353D',\n  gray1100: '#292C33',\n}\n\nexport const SystemColor = {\n  blue: '#446EFF',\n  green: '#00BBA8',\n  orange: '#FBA95C',\n  red: '#FF5677',\n  white: '#FFFFFF',\n  black: '#000000',\n  optional: '#F0B90B'\n}\n\nexport const GrayLight = {\n  gray100: '#1A2947',\n  gray200: '#5D667A',\n  gray300: '#AFB7C7',\n  gray400: '#BCC1CC',\n  gray500: '#E1E6F0',\n  gray600: '#EBEFF7',\n  gray700: '#F5F7FC',\n  gray800: '#FFFFFF',\n  gray900: '#F5F7FC',\n  gray1000: '#FFFFFF',\n  gray1100: '#FFFFFF',\n}\n\nexport const ColorDarkDefault = Object.freeze({\n  primary: SystemColor.blue,\n  primaryHover: `${hexToRGB(GrayBlack.gray200, '0.2')}`,\n  primaryPressed: '#2D49B2',\n  secondary: SystemColor.blue,\n  secondaryHover: '#46A6FF',\n  secondaryPressed: '#1064B2',\n  disable: '#343754',\n  success: SystemColor.green,\n  warning: SystemColor.orange,\n  error: SystemColor.red,\n  textPrimary: GrayBlack.gray100,\n  textSecondary: GrayBlack.gray200,\n  textThird: GrayBlack.gray300,\n  textButton: SystemColor.white,\n  textButtonSelect: GrayBlack.gray100,\n  textButtonDisabled: GrayBlack.gray400,\n  textDisable: `${hexToRGB(GrayBlack.gray100, '0.45')}`,\n  border: GrayBlack.gray500,\n  borderHover: SystemColor.blue,\n  borderDark: GrayBlack.gray400,\n  placeholder: GrayBlack.gray400,\n  borderSelect: SystemColor.blue,\n  borderDisable: GrayBlack.gray300,\n  borderDisable2: GrayBlack.gray200,\n  tag: '#6787FF',\n  popBg: GrayBlack.gray1100, //ColorBlack.dark800,\n  box: GrayBlack.gray800, //\"#2D2F4B\",\n  boxSecondary: GrayBlack.gray700,\n  boxThird: GrayBlack.gray1000,\n  boxHover: `${hexToRGB(GrayBlack.gray100, '0.05')}`,\n  boxLinear: GrayBlack.gray1100,\n  globalBg: GrayBlack.gray900, // \"#1F2034\",\n  globalBgOpacity: `${hexToRGB('#1F2034', '0.5')}`,\n  fieldOpacity: GrayBlack.gray700,\n  divide: GrayBlack.gray500,\n  boxEnhance: `${hexToRGB(GrayBlack.gray100, '0.1')}`,\n  mask: `${hexToRGB('#000000', '0.4')}`,\n  tableHeaderBg: '#393f64',\n  star: SystemColor.optional,\n  logo: GrayBlack.gray100,\n  /********************CSS special button *******************/\n  buttonPot: GrayBlack.gray100,\n  buttonIcon: GrayBlack.gray200,\n  buttonInactive: GrayBlack.gray700,\n  buttonDisabled: GrayBlack.gray600,\n  buttonOutlined: GrayBlack.gray500,\n\n  /********************CSS shadow *******************/\n  shadow: ` 0px 4px 4px ${hexToRGB(GrayBlack.gray600, '.25')}`,\n  shadowHeader: `0px 4px 8px  ${hexToRGB(GrayBlack.gray600, '.15')}`,\n  shadow2: `0px -4px 8px ${hexToRGB(GrayBlack.gray600, '.15')}`,\n  shadowHover: `0px 10px 20px  ${hexToRGB(GrayBlack.gray600, '.45')}`,\n  shadow3: `0px 10px 20px ${hexToRGB(GrayBlack.gray600, '.15')}`,\n\n  /********************Case for provider*******************/\n  white: SystemColor.white,\n  black: SystemColor.black,\n  dark: GrayBlack.gray700,\n  opacity: `${hexToRGB(GrayBlack.gray700, '0')}`,\n  providerBtn: `${hexToRGB(GrayBlack.gray100, '0.1')}`,\n  providerBtnHover: `${hexToRGB(GrayBlack.gray100, '0.03')}`,\n  providerApprove: `${hexToRGB(GrayBlack.gray100, '0.03')}`,\n  boxNFTLabel: `${hexToRGB(GrayBlack.gray700, '0.48')}`,\n  boxNFTBtn: `${hexToRGB(GrayBlack.gray700, '0.28')}`,\n\n  redPacket1: `linear-gradient(96.56deg, #FFD596 1.14%, #FFD390 46.4%, #FDBD6A 98.91%)`,\n  redPacket0: `linear-gradient(95.9deg, #FC7A5A 0.7%, #FF6151 99.3%);`,\n  redPacket1Disabled: `${hexToRGB(GrayBlack.gray400, '0.5')}`,\n  redPacketText1: '#A25402',\n  redPacketText0: '#FFF7B1',\n  redPacketBorder: `1px dashed ${hexToRGB(GrayBlack.gray100, '0.2')}`,\n})\n\nexport const ColorLightDefault = Object.freeze({\n  ...ColorDarkDefault,\n  primary: SystemColor.blue,\n  primaryHover: `${hexToRGB(GrayLight.gray100, '0.2')}`,\n  primaryPressed: '#293EAA',\n  secondary: SystemColor.blue,\n  secondaryHover: '#46A6FF',\n  secondaryPressed: '#1064B2',\n  disable: '#F4F5F9',\n  success: SystemColor.green,\n  warning: SystemColor.orange,\n  error: SystemColor.red,\n  textPrimary: GrayLight.gray100,\n  textSecondary: GrayLight.gray200,\n  textThird: GrayLight.gray300,\n  textButton: SystemColor.white,\n  textButtonSelect: SystemColor.blue,\n  textButtonDisabled: GrayLight.gray400,\n  textDisable: `${hexToRGB(GrayLight.gray100, '0.25')}`,\n  border: GrayLight.gray500,\n  borderHover: SystemColor.blue,\n  borderDark: GrayLight.gray400,\n  placeholder: GrayLight.gray400,\n  borderSelect: SystemColor.blue,\n  borderDisable: GrayLight.gray300,\n  borderDisable2: GrayLight.gray200,\n  tag: '#6787FF',\n  box: GrayLight.gray800,\n  boxHover: GrayLight.gray700,\n  popBg: GrayLight.gray1100,\n\n  boxLinear: GrayLight.gray1100,\n  globalBg: GrayLight.gray900,\n  globalBgOpacity: `${hexToRGB(GrayLight.gray500, '0.5')}`,\n  fieldOpacity: GrayLight.gray700,\n  divide: GrayLight.gray500,\n  boxEnhance: GrayLight.gray400,\n  boxSecondary: GrayLight.gray700,\n  boxThird: GrayLight.gray1000,\n  mask: `${hexToRGB('#000000', '0.4')}`,\n  tableHeaderBg: GrayLight.gray600,\n  star: SystemColor.optional,\n  logo: SystemColor.blue,\n  /********************CSS special buttonr*******************/\n  buttonPot: GrayBlack.gray100,\n  buttonIcon: '#15162B',\n  buttonInactive: GrayLight.gray700,\n  buttonDisabled: GrayLight.gray600,\n  buttonOutlined: GrayLight.gray500,\n  // box-shadow: 0px 4px 20px 0px #1D20231A;\n\n  /********************CSS shadow *******************/\n  shadow: `0px 4px 20px 0px #1D20231A`,\n  shadowHeader: `0px 4px 8px ${hexToRGB('#5766EC', '0.1')}`,\n  shadow2: `0px -4px 8px ${hexToRGB('#5766EC', '0.1')}`,\n  shadowHover: `0px 0px 4px  ${hexToRGB('#5781EC', '0.25')}`,\n  shadow3: `0px 10px 20px  ${hexToRGB('#5781EC', '0.1')}`,\n\n  /********************Case for provider*******************/\n  white: SystemColor.white,\n  black: SystemColor.black,\n  dark: GrayBlack.gray700,\n  opacity: `${hexToRGB(GrayBlack.gray100, '0')}`,\n  providerBtn: `${hexToRGB(SystemColor.blue, '0.1')}`,\n  providerBtnHover: `${hexToRGB(SystemColor.blue, '0.15')}`,\n  providerApprove: `#F6F7FB`,\n  boxNFTLabel: `${hexToRGB(GrayBlack.gray100, '0.58')}`,\n  boxNFTBtn: `${hexToRGB(GrayBlack.gray700, '0.28')}`,\n\n  redPacket1: `linear-gradient(96.56deg, #FFD596 1.14%, #FFD390 46.4%, #FDBD6A 98.91%)`,\n  redPacket0: `linear-gradient(95.9deg, #FC7A5A 0.7%, #FF6151 99.3%);`,\n  redPacket1Disabled: `${hexToRGB(GrayLight.gray500, '0.5')}`,\n  redPacketText1: '#A25402',\n  redPacketText0: '#FFF7B1',\n  redPacketBorder: `1px dashed ${hexToRGB(GrayBlack.gray100, '0.2')}`,\n})\n\nexport type ColorBaseInterface = typeof ColorDarkDefault\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/themes/css/global.tsx",
    "content": "import { css } from '@emotion/react'\nimport reset from './reset'\n// @ts-ignore\nimport InterMedium from '../fonts/english/Inter-Medium.ttf'\n\nimport {\n  ColorDarkDefault,\n  ColorLightDefault,\n  GrayBlack,\n  GrayLight,\n  hexToRGB,\n  SystemColor,\n} from './color-lib'\nimport { ThemeType } from '../interface'\n\nexport const fontDefault = {\n  h1: '3.8rem',\n  h2: '3.0rem',\n  h3: '2.4rem',\n  h4: '2.0rem',\n  h5: '1.6rem',\n  h6: '1.4rem',\n  body1: '1.4rem',\n  body2: '1.2rem',\n}\nexport enum SvgSize {\n  svgSizeSmall = 12,\n  svgSize = 14,\n  svgSizeMedium = 16,\n  svgSizeCover = 32,\n  svgSizeLarge = 24,\n  svgSizeHuge2 = 40,\n  svgSizeHuge = 48,\n}\n\nexport const refreshTime = 15\nexport const colorBase = ({ theme }: any) => css`\n  html {\n    --gray100: ${theme.mode == ThemeType.dark ? GrayBlack.gray100 : GrayLight.gray100};\n    --gray200: ${theme.mode == ThemeType.dark ? GrayBlack.gray200 : GrayLight.gray200};\n    --gray300: ${theme.mode == ThemeType.dark ? GrayBlack.gray300 : GrayLight.gray300};\n    --gray400: ${theme.mode == ThemeType.dark ? GrayBlack.gray400 : GrayLight.gray400};\n    --gray500: ${theme.mode == ThemeType.dark ? GrayBlack.gray500 : GrayLight.gray500};\n    --gray600: ${theme.mode == ThemeType.dark ? GrayBlack.gray600 : GrayLight.gray600};\n    --gray700: ${theme.mode == ThemeType.dark ? GrayBlack.gray700 : GrayLight.gray700};\n    --gray800: ${theme.mode == ThemeType.dark ? GrayBlack.gray800 : GrayLight.gray800};\n    --gray900: ${theme.mode == ThemeType.dark ? GrayBlack.gray900 : GrayLight.gray900};\n\n    --color-primary: ${theme.colorBase.primary};\n    --color-primary-hover: ${theme.colorBase.primaryHover};\n    --color-primary-pressed: ${theme.colorBase.primaryPressed};\n    --color-secondary: ${theme.colorBase.secondary};\n    --color-secondary-hover: ${theme.colorBase.secondaryHover};\n    --color-secondary-pressed: ${theme.colorBase.secondaryPressed};\n    --color-disable: ${theme.colorBase.disable};\n    --color-success: ${theme.colorBase.success};\n    --color-warning: ${theme.colorBase.warning};\n    --color-error: ${theme.colorBase.error};\n    --color-text-primary: ${theme.colorBase.textPrimary};\n    --color-text-secondary: ${theme.colorBase.textSecondary};\n    --color-text-third: ${theme.colorBase.textThird};\n    --color-text-button: ${theme.colorBase.textButton};\n    --color-text-button-select: ${theme.colorBase.textButtonSelect};\n    --color-text-button-disabled: ${theme.colorBase.textButtonDisabled};\n    --color-text-disable: ${theme.colorBase.textDisable};\n    --color-border: ${theme.colorBase.border};\n    --color-border-hover: ${theme.colorBase.borderHover};\n    --color-border-dark: ${theme.colorBase.borderDark};\n    --color-placeholder: ${theme.colorBase.placeholder};\n    --color-border-select: ${theme.colorBase.borderSelect};\n    --color-border-disable: ${theme.colorBase.borderDisable};\n    --color-border-disable2: ${theme.colorBase.borderDisable2};\n    --color-tag: ${theme.colorBase.tag};\n    --color-box: ${theme.colorBase.box};\n    --color-box-nft-label: ${theme.colorBase.boxNFTLabel};\n    --color-box-nft-btn: ${theme.colorBase.boxNFTBtn};\n    --color-box: ${theme.colorBase.box};\n    --color-box-hover: ${theme.colorBase.boxHover};\n    --color-pop-bg: ${theme.colorBase.popBg};\n\n    --color-box-linear: ${theme.colorBase.boxLinear};\n    --color-global-bg: ${theme.colorBase.globalBg};\n    --color-global-bg-opacity: ${theme.colorBase.globalBgOpacity};\n    --field-opacity: ${theme.colorBase.fieldOpacity};\n    --color-divide: ${theme.colorBase.divide};\n    --color-box-secondary: ${theme.colorBase.boxSecondary};\n    --color-box-third: ${theme.colorBase.boxThird};\n    --color-mask: ${theme.colorBase.mask};\n    --color-box-enhance: ${theme.colorBase.boxEnhance};\n    --color-table-header-bg: ${theme.colorBase.tableHeaderBg};\n    --color-star: ${theme.colorBase.star};\n    --color-logo: ${theme.colorBase.logo};\n\n    /********************Case for shadow*******************/\n    --color-button-pot: ${theme.colorBase.buttonPot};\n    --color-button-icon: ${theme.colorBase.buttonIcon};\n    --color-button-inactive: ${theme.colorBase.buttonInactive};\n    --color-button-disabled: ${theme.colorBase.buttonDisabled};\n    --color-button-outlined: ${theme.colorBase.buttonOutlined};\n\n    /********************CSS shadow *******************/\n    --shadow: ${theme.colorBase.shadow};\n    --shadow-header: ${theme.colorBase.shadowHeader};\n    --shadow2: ${theme.colorBase.shadow2};\n    --shadow-hover: ${theme.colorBase.shadowHover};\n    --shadow3: ${theme.colorBase.shadow3};\n\n    /********************Case for special*******************/\n    --provider-btn: ${theme.colorBase.providerBtn};\n    --provider-hover: ${theme.colorBase.providerBtnHover};\n    --provider-agree: ${theme.colorBase.providerApprove};\n    --vip-bg: ${hexToRGB(theme.colorBase.warning, '0.2')};\n    --vip-text: ${theme.colorBase.warning};\n    --network-bg: ${hexToRGB(theme.colorBase.warning, '0.2')};\n    --network-text: ${theme.colorBase.warning};\n    --auto-refresh-color: ${theme.colorBase.primary};\n    --opacity: ${theme.colorBase.opacity};\n    --color-white: white;\n    --color-black: ${theme.colorBase.black};\n    --color-settlet: ${theme.colorBase.opacity};\n\n    --color-redPacket0: ${theme.colorBase.redPacket0};\n    --color-redPacket1: ${theme.colorBase.redPacket1};\n    --color-redPacket1Disabled: ${theme.colorBase.redPacket1Disabled};\n    --color-redPacket-text0: ${theme.colorBase.redPacketText0};\n    --color-redPacket-text1: ${theme.colorBase.redPacketText1};\n    --color-redPacket-Border: ${theme.colorBase.redPacketBorder};\n  }\n`\nexport const scrollbarDefault = ({ theme }: any) => css`\n  html {\n    scrollbar-face-color: ${theme.colorBase.box};\n    scrollbar-base-color: ${theme.colorBase.box};\n    scrollbar-3dlight-color: ${theme.colorBase.box};\n    scrollbar-highlight-color: ${theme.colorBase.box};\n    scrollbar-track-color: ${theme.colorBase.box};\n    scrollbar-arrow-color: ${theme.colorBase.box};\n    scrollbar-shadow-color: ${theme.colorBase.box};\n    scrollbar-dark-shadow-color: ${theme.colorBase.box};\n  }\n\n  .MuiPaper-elevation2 {\n    box-shadow: var(--shadow);\n  }\n\n  .MuiPaper-elevation4 {\n    box-shadow: var(--shadow-header);\n  }\n  ::-webkit-scrollbar-track {\n    background-color: ${theme.colorBase.box};\n    border-radius: 3px;\n  }\n\n  ::-webkit-scrollbar-track-piece {\n    background-color: ${theme.colorBase.box};\n    border-radius: 3px;\n  }\n\n  ::-webkit-scrollbar-thumb {\n    height: 50px;\n    background-color: ${theme.colorBase.blur};\n    border-radius: 3px;\n  }\n\n  ::-webkit-scrollbar-corner {\n    background-color: ${theme.colorBase.box};\n  }\n\n  ::-webkit-resizer {\n    background-color: ${theme.colorBase.box};\n  }\n`\nexport const globalCss = ({ theme }: any) => css`\n  ${colorBase({ theme })}\n  ${scrollbarDefault({ theme })};\n\n  ${reset}\n  #root {\n    display: flex;\n    flex-direction: column;\n    justify-content: space-between;\n  }\n\n  html,\n  body {\n    position: relative;\n    color: var(--color-text-primary);\n    background: var(--color-global-bg);\n    height: 100vh;\n    box-sizing: border-box;\n    -moz-box-sizing: border-box; /* Firefox */\n    -webkit-box-sizing: border-box; /* Safari */\n    font-family: Roboto, Helvetica, Arial, '华文细黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体',\n      Heiti, '黑体', sans-serif;\n    font-size: 62.5%; /* 62.5% of 16px = 10px */\n  }\n\n  body {\n    display: flex;\n    width: 100%;\n    position: relative;\n    z-index: 1;\n    flex-direction: column;\n\n    &:before {\n      content: '';\n      position: fixed;\n      z-index: -1;\n      top: 0;\n      left: 0;\n      right: 0;\n      bottom: 0;\n    }\n  }\n\n  h1 {\n    font-size: ${fontDefault.h1};\n  }\n\n  h2 {\n    font-size: ${fontDefault.h2};\n  }\n\n  h3 {\n    font-size: ${fontDefault.h3};\n  }\n\n  h4 {\n    font-size: ${fontDefault.h4};\n  }\n\n  h5 {\n    font-size: ${fontDefault.h5};\n  }\n\n  h6 {\n    font-size: ${fontDefault.h6};\n  }\n\n  html {\n    overflow-y: auto;\n    --auto-refresh-duration: ${refreshTime - 1}s;\n    --durationInternal: calc(var(--auto-refresh-duration) * 2);\n    --delay: calc(var(--auto-refresh-duration) / 2);\n    --header-row-height: 44px;\n    --header-height: 64px;\n    --header-submenu-item-height: 52px;\n    --header-submenu-item-width: 250px;\n    --desktop-max-width: 1200px;\n    --desktop-min-width: 1024px;\n    --btn-Input-small-height: 32px;\n    --btn-medium-height: 40px;\n    --btn-min-width: 100px;\n    --coin-min-width: 80px;\n    --datePicker-width: 320px;\n    --datePicker-height: 232px;\n    --list-coin-item: 44px;\n    --withdraw-coin-size: 16px;\n    --header-menu-icon-size: 20px;\n    --header-menu-icon-large: 28px;\n    --list-menu-coin-size: 24px;\n    --slippage-pop-width: 308px;\n    --chart-title-coin-size: 28px;\n    --btn-icon-size-small: 20px;\n    --btn-icon-size-medium: 24px;\n    --btn-icon-size-large: 28px;\n    --btn-icon-size: 36px;\n    --svg-size: ${SvgSize.svgSize}px;\n    --svg-size-small: ${SvgSize.svgSizeSmall}px;\n    --svg-size-medium: ${SvgSize.svgSizeMedium}px;\n    --svg-size-cover: ${SvgSize.svgSizeCover}px;\n    --svg-size-large: ${SvgSize.svgSizeLarge}px;\n    --svg-size-huge2: ${SvgSize.svgSizeHuge2}px;\n    --svg-size-huge: ${SvgSize.svgSizeHuge}px;\n    --swap-box-height: 580px; /** js used also **/\n    --panel-setting-height: 680px;\n    --panel-setting-width: 800px;\n    --modal-width: 480px;\n    --modal-height: 400px;\n    --swap-box-width: 338px;\n    --mobile-full-panel-width: 352px;\n    --toolbar-row-height: 56px; /** js used also  40 + 56 = 96  CoinList.tsx **/\n    --toolbar-row-height-minus: -56px;\n    --toolbar-row-padding: 40px; /** js used also  40 + 56 = 96  CoinList.tsx **/\n    --toolbar-row-padding-minus: -40px;\n    --sub-menuItem-width: 200px;\n    --sub-menuItem-height: 52px;\n    --lage-modal-width: 580px;\n    --lage-modal-height: 620px;\n    --gateway-icon-size: 56px;\n    --account-button-fixed-width: 88px;\n    --account-button-fixed-height: 72px;\n    --empty-size: 130px;\n    --account-modal-box-width: 284px;\n    --walletconnect-width: 150px;\n    --row-height: 44px;\n    --row-header-height: 44px;\n    --chart-height: 396px;\n    --nft-height: 396px;\n    --nft-card: 320px;\n    --nft-large-avatar: 160px;\n    --nft-small-avatar: 80px;\n    --redPacket-avatar: 72px;\n    --notification-activited-heigth: 80px;\n    --modal-min-width: 340px;\n    --carousel-dot-size: 14px;\n    --earning-banner-width: 320px;\n    --provider-btn-height: 56px;\n    --input-height-large: 48px;\n    --input-height-huge: 56px;\n    --dual-type-width: 320px;\n    --min-height: 350px;\n    --input-height-swap: 86px;\n    @media only screen and (max-width: 768px) {\n      --modal-width: var(--modal-min-width);\n      --lage-modal-width: 460px;\n      --walletconnect-width: 126px;\n      --dual-type-width: 240px;\n    }\n    --color-EOA-Text: #fba95c;\n    --color-Loopring-Text: #4169ff;\n    --color-OtherSmart-Text: #979797;\n    --color-Binance-Text: #a25402;\n    --color-Huobi-Text: #199e5e;\n    --color-OtherExchange-Text: #a0635a;\n    --color-EOA-Bg: #fffedc;\n    --color-Loopring-Bg: #c9dbef;\n    --color-OtherSmart-Bg: #d9d9d9;\n    --color-Binance-Bg: #fde3c8;\n    --color-Huobi-Bg: #b1f4dd;\n    --color-OtherExchange-Bg: #c1a6a2;\n  }\n\n  select {\n    appearance: none;\n    -moz-appearance: none;\n    -webkit-appearance: none;\n\n    &::-ms-expand {\n      display: none;\n    }\n  }\n\n  .rdg.rdg {\n    --background-color: inherit;\n  }\n`\nexport { ColorDarkDefault, ColorLightDefault, SystemColor }\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/themes/css/reset.tsx",
    "content": "import { css } from '@emotion/react'\n\nexport default css`\n  html,\n  body,\n  div,\n  span,\n  applet,\n  object,\n  iframe,\n  h1,\n  h2,\n  h3,\n  h4,\n  h5,\n  h6,\n  p,\n  blockquote,\n  pre,\n  a,\n  abbr,\n  acronym,\n  address,\n  big,\n  cite,\n  code,\n  del,\n  dfn,\n  em,\n  img,\n  ins,\n  kbd,\n  q,\n  s,\n  samp,\n  small,\n  strike,\n  strong,\n  sub,\n  sup,\n  tt,\n  var,\n  b,\n  u,\n  i,\n  center,\n  dl,\n  dt,\n  dd,\n  ol,\n  ul,\n  li,\n  fieldset,\n  form,\n  label,\n  legend,\n  table,\n  caption,\n  tbody,\n  tfoot,\n  thead,\n  tr,\n  th,\n  td,\n  article,\n  aside,\n  canvas,\n  details,\n  embed,\n  figure,\n  figcaption,\n  footer,\n  header,\n  hgroup,\n  menu,\n  nav,\n  output,\n  ruby,\n  section,\n  summary,\n  time,\n  mark,\n  audio,\n  video {\n    margin: 0;\n    padding: 0;\n    border: 0;\n    font-size: 100%;\n    font: inherit;\n    vertical-align: baseline;\n    box-sizing: border-box;\n  }\n\n  address,\n  caption,\n  cite,\n  code,\n  dfn,\n  em,\n  strong,\n  th,\n  var,\n  b {\n    font-weight: normal;\n    font-style: normal;\n  }\n\n  abbr,\n  acronym {\n    border: 0;\n  }\n\n  article,\n  aside,\n  details,\n  figcaption,\n  figure,\n  footer,\n  header,\n  hgroup,\n  menu,\n  nav,\n  section {\n    display: block;\n  }\n  *,\n  *::after,\n  *::before {\n    margin: 0;\n    padding: 0;\n    box-sizing: inherit;\n  }\n  *:focus-visible {\n    outline: rgba(0, 0, 0, 0);\n  }\n\n  html {\n    text-size-adjust: 100%;\n    box-sizing: border-box;\n    scroll-behavior: smooth;\n  }\n  body {\n    line-height: 1;\n  }\n  ol,\n  ul {\n    list-style: none;\n  }\n  blockquote,\n  q {\n    quotes: none;\n  }\n\n  blockquote {\n    &:before,\n    &:after {\n      content: '';\n      content: none;\n    }\n  }\n  q {\n    &:before,\n    &:after {\n      content: '';\n      content: none;\n    }\n  }\n\n  table {\n    border-collapse: collapse;\n    border-spacing: 0;\n  }\n  caption,\n  th {\n    text-align: left;\n  }\n  textarea {\n    resize: none;\n  }\n  a {\n    text-decoration: none;\n    cursor: pointer;\n  }\n  button {\n    padding: 0;\n    border: none;\n    background: none;\n  }\n  html {\n    overscroll-behavior-x: none;\n    overscroll-behavior-y: none;\n    text-underline-offset: 3px;\n  }\n\n  iframe {\n    display: none;\n  }\n\n  #iubenda-pp,\n  #iframeBanxaTarget {\n    iframe {\n      display: initial;\n    }\n  }\n\n  #iframeBanxaTarget {\n    z-index: 9999;\n\n    #iframeBanxaClose {\n      transform: scale(2);\n      position: absolute;\n      top: 20px;\n      right: 20px;\n      cursor: pointer;\n      padding: 4px;\n      border-bottom-left-radius: 80%;\n      background: rgba(255, 255, 255, 0.6);\n    }\n    position: absolute;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n    display: none;\n    align-items: center;\n    justify-content: center;\n    background-color: rgba(166, 174, 185, 0.7);\n  }\n  #walletconnect-qrcode-modal {\n    font-size: 16px;\n    .walletconnect-modal__mobile__toggle {\n      a {\n        color: rgb(76, 130, 251);\n      }\n    }\n  }\n  #iframeBanxaTarget {\n    z-index: 9999;\n    #iframeBanxaClose {\n      transform: scale(2);\n      position: absolute;\n      top: 20px;\n      right: 20px;\n      cursor: pointer;\n      padding: 4px;\n      border-bottom-left-radius: 80%;\n      background: rgba(255, 255, 255, 0.6);\n    }\n    position: absolute;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n    display: none;\n    align-items: center;\n    justify-content: center;\n    background-color: rgba(166, 174, 185, 0.7);\n  }\n`\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/themes/fonts/english/LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty change (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/themes/globalSetup.ts",
    "content": "export const globalSetup = Object.freeze({\n  wait: 100,\n  throttleWait: 3000,\n})\n\nexport const FORMAT_STRING_LEN = 10\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/themes/index.ts",
    "content": "import styled from '@emotion/styled'\nimport { Avatar, Grid } from '@mui/material'\nimport { AvatarCoinProps, ThemeType } from './interface'\nimport { hr } from './overrides/overrides-mui'\nimport { css } from '@emotion/react'\n//@ts-ignore\nimport cssStyle from 'github-markdown-css/github-markdown.css'\nimport loopringJSON from '../../../assets/coin/loopring.json'\nexport * from './overrides/muTheme'\nexport * from './css/global'\n// export * from \"./css/color-lib\"\nexport * from './interface'\nexport * from './globalSetup'\nexport { hexToRGB } from './css/color-lib'\nexport { hr }\n//https://static.loopring.io/assets/images/coin/loopring.png\nexport const AvatarCoinStyled = styled(Avatar)<AvatarCoinProps>`\n  &.MuiAvatar-root {\n    height: 72px;\n    width: 72px;\n    background-image: url('./static/coin/${loopringJSON.file}');\n    ${({\n      imgx,\n      imgy,\n      imgheight = 72,\n      imgwidth = 73,\n    }: // size = 24,\n    AvatarCoinProps) => {\n      return `\n             background-position-x: -${imgx}px ;\n             background-position-y: -${imgy}px ;\n             height: ${imgheight}px ;\n             width: ${imgwidth}px ;\n             transform-origin: center;\n        `\n    }}\n    background-size: auto;\n  }\n` as (props: AvatarCoinProps) => JSX.Element\n\nconst style = css`\n  ${cssStyle}\n`\nexport const MarkdownStyle = styled(Grid)`\n  ${({ theme }) => ` \n      .markdown-body{\n        border-radius: ${theme.unit / 2}px;\n        max-width:1200px;\n          --color-fg-default: ${theme.colorBase.textPrimary};\n          --color-fg-muted: ${theme.colorBase.textThird};\n          --color-fg-subtle: ${theme.colorBase.textSecondary};\n          --color-canvas-default: ${theme.colorBase.box};\n          --color-border-default: ${theme.colorBase.border};\n          --color-border-muted: ${theme.colorBase.divide};\n          --color-canvas-subtle:${theme.colorBase.fieldOpacity};\n\n         ${\n           theme.mode === ThemeType.dark\n             ? `\n          --color-prettylights-syntax-comment: #8b949e;\n          --color-prettylights-syntax-constant: #79c0ff;\n          --color-prettylights-syntax-entity: #d2a8ff;\n          --color-prettylights-syntax-storage-modifier-import: #c9d1d9;\n          --color-prettylights-syntax-entity-tag: #7ee787;\n          --color-prettylights-syntax-keyword: #ff7b72;\n          --color-prettylights-syntax-string: #a5d6ff;\n          --color-prettylights-syntax-variable: #ffa657;\n          --color-prettylights-syntax-brackethighlighter-unmatched: #f85149;\n          --color-prettylights-syntax-invalid-illegal-text: #f0f6fc;\n          --color-prettylights-syntax-invalid-illegal-bg: #8e1519;\n          --color-prettylights-syntax-carriage-return-text: #f0f6fc;\n          --color-prettylights-syntax-carriage-return-bg: #b62324;\n          --color-prettylights-syntax-string-regexp: #7ee787;\n          --color-prettylights-syntax-markup-list: #f2cc60;\n          --color-prettylights-syntax-markup-heading: #1f6feb;\n          --color-prettylights-syntax-markup-italic: #c9d1d9;\n          --color-prettylights-syntax-markup-bold: #c9d1d9;\n          --color-prettylights-syntax-markup-deleted-text: #ffdcd7;\n          --color-prettylights-syntax-markup-deleted-bg: #67060c;\n          --color-prettylights-syntax-markup-inserted-text: #aff5b4;\n          --color-prettylights-syntax-markup-inserted-bg: #033a16;\n          --color-prettylights-syntax-markup-changed-text: #ffdfb6;\n          --color-prettylights-syntax-markup-changed-bg: #5a1e02;\n          --color-prettylights-syntax-markup-ignored-text: #c9d1d9;\n          --color-prettylights-syntax-markup-ignored-bg: #1158c7;\n          --color-prettylights-syntax-meta-diff-range: #d2a8ff;\n          --color-prettylights-syntax-brackethighlighter-angle: #8b949e;\n          --color-prettylights-syntax-sublimelinter-gutter-mark: #484f58;\n          --color-prettylights-syntax-constant-other-reference-link: #a5d6ff;   \n          --color-accent-fg: #58a6ff;\n          --color-accent-emphasis: #1f6feb;\n          --color-danger-fg: #f85149;\n          }`\n             : `\n          --color-prettylights-syntax-comment: #6e7781;\n          --color-prettylights-syntax-constant: #0550ae;\n          --color-prettylights-syntax-entity: #8250df;\n          --color-prettylights-syntax-storage-modifier-import: #24292f;\n          --color-prettylights-syntax-entity-tag: #116329;\n          --color-prettylights-syntax-keyword: #cf222e;\n          --color-prettylights-syntax-string: #0a3069;\n          --color-prettylights-syntax-variable: #953800;\n          --color-prettylights-syntax-brackethighlighter-unmatched: #82071e;\n          --color-prettylights-syntax-invalid-illegal-text: #f6f8fa;\n          --color-prettylights-syntax-invalid-illegal-bg: #82071e;\n          --color-prettylights-syntax-carriage-return-text: #f6f8fa;\n          --color-prettylights-syntax-carriage-return-bg: #cf222e;\n          --color-prettylights-syntax-string-regexp: #116329;\n          --color-prettylights-syntax-markup-list: #3b2300;\n          --color-prettylights-syntax-markup-heading: #0550ae;\n          --color-prettylights-syntax-markup-italic: #24292f;\n          --color-prettylights-syntax-markup-bold: #24292f;\n          --color-prettylights-syntax-markup-deleted-text: #82071e;\n          --color-prettylights-syntax-markup-deleted-bg: #FFEBE9;\n          --color-prettylights-syntax-markup-inserted-text: #116329;\n          --color-prettylights-syntax-markup-inserted-bg: #dafbe1;\n          --color-prettylights-syntax-markup-changed-text: #953800;\n          --color-prettylights-syntax-markup-changed-bg: #ffd8b5;\n          --color-prettylights-syntax-markup-ignored-text: #eaeef2;\n          --color-prettylights-syntax-markup-ignored-bg: #0550ae;\n          --color-prettylights-syntax-meta-diff-range: #8250df;\n          --color-prettylights-syntax-brackethighlighter-angle: #57606a;\n          --color-prettylights-syntax-sublimelinter-gutter-mark: #8c959f;\n          --color-prettylights-syntax-constant-other-reference-link: #0a3069;\n          --color-accent-fg: #0969da;\n          --color-accent-emphasis: #0969da;\n          --color-danger-fg: #cf222e;\n        `\n         }\n      }\n  `};\n\n  ul {\n    list-style: inherit;\n  }\n\n  ol {\n    list-style: decimal;\n  }\n\n  ${style}\n  .markdown-body.no-bg {\n    background-color: initial;\n    box-shadow: initial;\n    padding: 0;\n  }\n` as typeof Grid\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/themes/interface.ts",
    "content": "import { AvatarProps, Theme } from '@mui/material'\nimport { ColorBaseInterface } from './css/color-lib'\n\nexport enum ThemeType {\n  dark = 'dark',\n  light = 'light',\n}\n\ndeclare module '@mui/material' {\n  interface TextFieldPropsSizeOverrides {\n    large: true\n  }\n\n  interface InputBasePropsSizeOverrides {\n    large: true\n  }\n\n  // interface InputBasePropsSizeOverrides {\n  //   large: true\n  // }\n}\nexport type ThemeKeys = keyof typeof ThemeType\nexport type LoopringTheme = Theme & {\n  colorBase: ColorBaseInterface\n  fontDefault: {\n    h1: string\n    h2: string\n    h3: string\n    h4: string\n    h5: string\n    h6: string\n    body1: string\n    body2: string\n  }\n  unit: number\n  mode: ThemeKeys\n  border: {\n    defaultBorder: string\n    defaultRadius: string\n    defaultFrame: (props: {\n      d_W?: number\n      d_R?: number\n      c_key?: 'primary' | 'selected' | 'blur' | 'focus' | string\n    }) => string\n    borderConfig: (props: {\n      d_W?: number\n      c_key?: 'primary' | 'selected' | 'blur' | 'focus' | string\n    }) => string\n  }\n}\nexport type AvatarCoinProps = AvatarProps & {\n  imgx: number\n  imgy: number\n  imgh?: number\n  imgw?: number\n  imgheight: number\n  imgwidth: number\n  size?: number\n}\n\ndeclare module '@emotion/react' {\n  export interface Theme extends LoopringTheme {}\n}\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/themes/overrides/muTheme.ts",
    "content": "import { createTheme } from '@mui/material'\nimport { ColorDarkDefault, ColorLightDefault } from '../css/color-lib'\nimport { borderFunc, unit } from './utils'\nimport {\n  MuiAlert,\n  MuiBreadcrumbs,\n  MuiButton,\n  MuiButtonBase,\n  MuiCard,\n  MuiCardActions,\n  MuiCardContent,\n  MuiCheckbox,\n  MuiDialog,\n  MuiDialogTitle,\n  MuiDivider,\n  MuiFormLabel,\n  MuiIconButton,\n  MuiInputBase,\n  MuiInputLabel,\n  MuiLinearProgress,\n  MuiLink,\n  MuiList,\n  MuiListItem,\n  MuiListItemAvatar,\n  MuiMenu,\n  MuiMenuItem,\n  MuiModal,\n  MuiPaginationItem,\n  MuiPaper,\n  MuiPopover,\n  MuiRadio,\n  MuiSnackbar,\n  MuiSvgIcon,\n  MuiSwitch,\n  MuiTab,\n  MuiTabs,\n  MuiTextField,\n  MuiToggleButton,\n  MuiToolbar,\n  MuiTooltip,\n  MuiBadge,\n  radius,\n} from './overrides-mui'\nimport { MuPickDate } from './overrides-date-pick'\nimport { fontDefault } from '../css/global'\nimport { LoopringTheme, ThemeKeys } from '../interface'\n\nexport { unit }\nexport const getTheme = (themeMode: ThemeKeys, _isMobile = false): LoopringTheme => {\n  const colorBase: typeof ColorDarkDefault = (\n    themeMode === 'dark' ? ColorDarkDefault : ColorLightDefault\n  ) as typeof ColorDarkDefault\n  const theme = createTheme({\n    spacing: unit,\n    palette: {\n      mode: themeMode,\n      primary: {\n        light: colorBase.primary,\n        main: colorBase.primary,\n        dark: colorBase.primary,\n        contrastText: themeMode === 'dark' ? '#fff' : '#000',\n      },\n      secondary: {\n        light: colorBase.secondary,\n        main: colorBase.secondary,\n        dark: colorBase.secondary,\n        contrastText: themeMode === 'dark' ? '#fff' : '#000',\n        // light:\n      },\n      contrastThreshold: 3,\n      tonalOffset: 0.2,\n      background: {\n        paper: colorBase.box,\n        default: colorBase.globalBg,\n      },\n      text: {\n        primary: colorBase.textPrimary,\n        secondary: colorBase.textSecondary,\n        disabled: colorBase.textDisable,\n        //hint: colorBase.textHint,\n      },\n      // divider: \"rgba(0, 0, 0, 0.12)\",\n      common: { black: '#000', white: '#fff' },\n      action: {\n        hoverOpacity: 0.05,\n        hover: colorBase.secondaryHover,\n        selected: colorBase.secondaryPressed,\n        // disabledBackground: \"rgba(0, 0, 0, 0.12)\",\n        disabled: colorBase.textDisable,\n        active: colorBase.secondaryPressed,\n      },\n      warning: {\n        main: colorBase.warning,\n      },\n      success: {\n        main: colorBase.success,\n      },\n      error: {\n        main: colorBase.error,\n        dark: colorBase.error,\n        contrastText: themeMode === 'dark' ? '#fff' : '#000',\n      },\n    },\n    typography: {\n      // fontFamily: `DINCondensed, Helvetica, Arial, \"华文细黑\", \"Microsoft YaHei\", \"微软雅黑\", SimSun, \"宋体\", Heiti, \"黑体\", sans-serif`,\n      fontFamily: 'Roboto',\n      fontSize: 14,\n      h1: {\n        fontSize: fontDefault.h1,\n        lineHeight: '4.6rem',\n        fontWeight: 500,\n      },\n      h2: {\n        fontSize: fontDefault.h2,\n        lineHeight: '3.8rem',\n        fontWeight: 500,\n      },\n      h3: {\n        fontSize: fontDefault.h3,\n        lineHeight: '3.2rem',\n        fontWeight: 500,\n      },\n      h4: {\n        fontSize: fontDefault.h4,\n        lineHeight: '2.8rem',\n        fontWeight: 400,\n      },\n      h5: {\n        fontSize: fontDefault.h5,\n        lineHeight: '2.4rem',\n        fontWeight: 400,\n        margin: 0,\n      },\n      h6: {\n        fontSize: fontDefault.h6,\n        margin: 0,\n      },\n      subtitle1: {\n        fontSize: 16,\n        lineHeight: '2.4rem',\n        fontWeight: 500,\n      },\n      button: {\n        fontSize: 20,\n        color: colorBase.textButton,\n        fontWeight: 400,\n      },\n      body1: {\n        fontSize: fontDefault.body1,\n        color: colorBase.textPrimary,\n        fontWeight: 400,\n      },\n      body2: {\n        fontSize: 12,\n        color: colorBase.textSecondary,\n      },\n    },\n    zIndex: {\n      tooltip: 2002,\n    },\n    components: {\n      MuiCard: MuiCard({ colorBase }),\n      MuiCardContent: MuiCardContent(),\n      MuiCardActions: MuiCardActions(),\n      MuiCheckbox: MuiCheckbox({ colorBase }),\n      MuiLink: MuiLink({ colorBase }),\n      MuiModal: MuiModal({ colorBase }),\n      // MuiBackdrop:MuiBackdrop({colorBase}),\n      MuiPopover: MuiPopover(),\n      MuiToolbar: MuiToolbar(),\n      MuiSvgIcon: MuiSvgIcon(),\n      MuiTabs: MuiTabs(),\n      MuiTab: MuiTab({ colorBase }),\n      MuiButtonBase: MuiButtonBase,\n      MuiRadio: MuiRadio(),\n      MuiBadge: MuiBadge,\n      MuiButton: MuiButton({ colorBase, themeMode }),\n      MuiToggleButton: MuiToggleButton({ colorBase }),\n      // MuiToggleButtonGroup: MuiToggleButtonGroup({colorBase}),\n      MuiSwitch: MuiSwitch(),\n      MuiIconButton: MuiIconButton({ colorBase }),\n      MuiPaginationItem: MuiPaginationItem({ colorBase }),\n      MuiTextField: MuiTextField({ colorBase }),\n      MuiBreadcrumbs: MuiBreadcrumbs(),\n      MuiFormLabel: MuiFormLabel({ colorBase }),\n      MuiInputBase: MuiInputBase({ colorBase, themeMode }),\n      MuiMenu: MuiMenu({ colorBase }),\n      MuiMenuItem: MuiMenuItem({ colorBase, themeMode }),\n      MuiList: MuiList(),\n      MuiListItem: MuiListItem({ colorBase }),\n      MuiListItemAvatar: MuiListItemAvatar(),\n      MuiInputLabel: MuiInputLabel({ colorBase }),\n      // MuiPopover: MuiPopover({colorBase, themeMode}),\n      MuiPaper: MuiPaper({ colorBase, themeMode }),\n      MuiDivider: MuiDivider({ colorBase }),\n      MuiAlert: MuiAlert({ colorBase }),\n      MuiSnackbar: MuiSnackbar(),\n      MuiDialogTitle: MuiDialogTitle({ colorBase }),\n      MuiDialog: MuiDialog({ colorBase }),\n      MuiLinearProgress: MuiLinearProgress({ colorBase }),\n      MuiTooltip: MuiTooltip({ colorBase }),\n      ...MuPickDate({ colorBase, themeMode }),\n    },\n    shape: { borderRadius: radius },\n  })\n  return {\n    ...theme,\n    ...{\n      unit,\n      mode: themeMode,\n      border: borderFunc(themeMode),\n      fontDefault,\n      colorBase: themeMode === 'dark' ? ColorDarkDefault : ColorLightDefault,\n    },\n  } as LoopringTheme\n}\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/themes/overrides/overrides-date-pick.ts",
    "content": "import { borderFunc } from './utils'\nimport { ColorDarkDefault } from '../css/color-lib'\nimport { radius } from './overrides-mui'\nimport { fontDefault } from '../css/global'\nimport { ThemeKeys } from '../interface'\n\nexport const MuPickDate = ({\n  colorBase,\n  themeMode,\n}: {\n  colorBase: typeof ColorDarkDefault\n  themeMode: ThemeKeys\n}) => {\n  return {\n    MuiPickersBasePicker: {\n      styleOverrides: {\n        root: {\n          width: `var(--datePicker-width)`,\n          background: colorBase.popBg,\n          boxShadow: colorBase.shadow,\n          borderRadius: radius * 2 + 'px',\n          // border: borderFunc(themeMode).borderConfig({c_key: 'blur'}),\n          border: borderFunc(themeMode).defaultFrame({ c_key: colorBase.divide }), //`1px solid `,\n          '& svg': {\n            fontSize: '2rem',\n            // color: colorBase.textSecondary\n          },\n          '& .MuiPickersCalendar-weekDayLabel': {\n            fontSize: '1rem',\n          },\n          '& .MuiPickersArrowSwitcher-root .MuiIconButton-edgeEnd': {\n            position: 'relative',\n            padding: 3,\n          },\n        },\n      },\n    },\n    MuiPicker: {\n      styleOverrides: {\n        root: {\n          width: `var(--datePicker-width)`,\n          background: colorBase.popBg,\n          boxShadow: colorBase.shadow,\n          borderRadius: radius * 2 + 'px',\n          border: borderFunc(themeMode).borderConfig({ c_key: 'blur' }),\n          '& svg': {\n            fontSize: '2rem',\n            // color: colorBase.textSecondary\n          },\n          '& .MuiPickersCalendar-weekDayLabel': {\n            fontSize: '1rem',\n          },\n          '& .MuiPickersArrowSwitcher-root .MuiIconButton-edgeEnd': {\n            position: 'relative',\n            padding: 3,\n          },\n        },\n      },\n    },\n    MuiDateRangePickerViewDesktop: {\n      styleOverrides: {\n        root: {\n          '& svg': {\n            fontSize: '2rem',\n            color: colorBase.textSecondary,\n          },\n          background: colorBase.popBg,\n          boxShadow: colorBase.shadow,\n          borderRadius: radius * 2 + 'px',\n          // border: borderFunc(themeMode).borderConfig({c_key: 'blur'}),\n          border: borderFunc(themeMode).defaultFrame({ c_key: colorBase.divide }), //`1px solid ${colorBase.divide}`,\n          fontSize: 1.6,\n          '& .MuiDateRangePickerViewDesktop-rangeCalendarContainer:not(:last-child)': {\n            borderColor: colorBase.divide,\n          },\n          '& .MuiPickersArrowSwitcher-root': {\n            border: borderFunc(themeMode).borderConfig({ c_key: 'rgba(0,0,0,0)' }),\n            borderBottomColor: colorBase.divide,\n            boxSizing: 'border-box',\n            height: 52,\n            minHeight: 52,\n            maxHeight: 52,\n            margin: 0,\n            marginBottom: 0,\n            '& .MuiIconButton-root': {\n              color: colorBase.textSecondary,\n            },\n            '& .MuiTypography-subtitle1,& .MuiTypography-subtitle2': {\n              fontSize: '1.4rem',\n            },\n          },\n          '& .MuiPickersCalendar-weekDayLabel': {\n            fontSize: '1rem',\n          },\n          '& .MuiDateRangePickerDay-rangeIntervalPreview,& .MuiDateRangePickerDay-rangeIntervalDayPreview':\n            {\n              borderWidth: 0,\n            },\n          '& .MuiDateRangePickerDay-day': {\n            transform: 'none',\n          },\n          '& .MuiDateRangePickerViewDesktop-calendar': {\n            width: `var(--datePicker-width)`,\n            minHeight: `var(--datePicker-height)`,\n            marginBottom: '.8rem',\n          },\n          '& .MuiDateRangePickerDay-dayOutsideRangeInterval:hover': {\n            borderColor: 'transparent',\n          },\n        },\n      },\n    },\n    MuiPickersDesktopDateRangeCalendar: {\n      styleOverrides: {\n        root: {\n          '& svg': {\n            fontSize: '2rem',\n            // color: colorBase.textSecondary\n          },\n          background: colorBase.popBg,\n          boxShadow: colorBase.shadow,\n          borderRadius: radius * 2 + 'px',\n          border: borderFunc(themeMode).borderConfig({ c_key: 'blur' }),\n          fontSize: 1.6,\n          '& .MuiTypography-subtitle1': {\n            fontSize: fontDefault.h4,\n          },\n          '& .MuiPickersDesktopDateRangeCalendar-rangeCalendarContainer:not(:last-child)': {\n            borderColor: colorBase.divide,\n          },\n          '& .MuiPickersArrowSwitcher-root': {\n            border: borderFunc(themeMode).borderConfig({ c_key: 'rgba(0,0,0,0)' }),\n            borderBottomColor: colorBase.divide,\n            boxSizing: 'border-box',\n            height: 52,\n            minHeight: 52,\n            maxHeight: 52,\n            margin: 0,\n            marginBottom: 0,\n            '& .MuiIconButton-root': {\n              color: colorBase.textSecondary,\n            },\n            '& .MuiTypography-subtitle1,& .MuiTypography-subtitle2': {\n              fontSize: '1.4rem',\n            },\n          },\n          '& .MuiPickersCalendar-weekDayLabel': {\n            fontSize: '1rem',\n          },\n          '& .MuiPickersDateRangeDay-rangeIntervalPreview,& .MuiPickersDateRangeDay-rangeIntervalDayPreview':\n            {\n              borderWidth: 0,\n            },\n          '& .MuiPickersDateRangeDay-day': {\n            transform: 'none',\n          },\n          '& .MuiPickersDesktopDateRangeCalendar-calendar': {\n            width: `var(--datePicker-width)`,\n            minHeight: `var(--datePicker-height)`,\n            marginBottom: '.8rem',\n          },\n          '& .MuiPickersDateRangeDay-dayOutsideRangeInterval:hover': {\n            borderColor: 'transparent',\n          },\n        },\n      },\n    },\n    MuiPickersDateRangeDay: {\n      styleOverrides: {\n        root: {\n          '&.MuiPickersDateRangeDay-rangeIntervalDayHighlight:last-child, &.MuiPickersDateRangeDay-rangeIntervalDayHighlightEnd':\n            {\n              borderTopRightRadius: radius * 2 + 'px',\n              borderBottomRightRadius: radius * 2 + 'px',\n            },\n          '&.MuiPickersDateRangeDay-rangeIntervalDayHighlight:first-of-type, &.MuiPickersDateRangeDay-rangeIntervalDayHighlightStart':\n            {\n              borderTopLeftRadius: radius * 2 + 'px',\n              borderBottomLeftRadius: radius * 2 + 'px',\n            },\n          '& .MuiPickersDay-root:focus.Mui-selected': {\n            backgroundColor: colorBase.primaryPressed,\n          },\n          '& .MuiPickersDay-root:focus.Mui-selected,& .MuiPickersDay-root.Mui-selected,& .MuiPickersDay-root':\n            {\n              '&:hover': {\n                borderColor: 'transparent',\n              },\n            },\n        },\n      },\n    },\n    MuiDateRangePickerDay: {\n      styleOverrides: {\n        root: {\n          '&.MuiDateRangePickerDay-rangeIntervalDayHighlight:last-child, &.MuiDateRangePickerDay-rangeIntervalDayHighlightEnd':\n            {\n              borderTopRightRadius: radius * 2 + 'px',\n              borderBottomRightRadius: radius * 2 + 'px',\n            },\n          '&.MuiDateRangePickerDay-rangeIntervalDayHighlight:first-of-type, &.MuiDateRangePickerDay-rangeIntervalDayHighlightStart':\n            {\n              borderTopLeftRadius: radius * 2 + 'px',\n              borderBottomLeftRadius: radius * 2 + 'px',\n            },\n          '& .MuiPickersDay-root:focus.Mui-selected': {\n            backgroundColor: colorBase.primaryPressed,\n          },\n        },\n      },\n    },\n    MuiPickersToolbarButton: {\n      styleOverrides: {\n        root: {\n          fontSize: 1.6,\n        },\n      },\n    },\n    MuiPickersToolbar: {\n      root: {},\n    },\n    MuiPickersDay: {\n      styleOverrides: {\n        root: {\n          '&&': {\n            fontSize: '1.4rem',\n            borderRadius: radius * 2 + 'px',\n            border: borderFunc(themeMode).borderConfig({ c_key: 'rgba(0,0,0,0)' }),\n            backgroundColor: colorBase.opacity,\n          },\n\n          '&.Mui-selected,&:focus.Mui-selected ': {\n            backgroundColor: colorBase.primary,\n            // color: colorBase.textThird,\n          },\n          '&.Mui-disabled': {\n            //backgroundColor: colorBase.primary,\n            color: colorBase.textDisable,\n          },\n          '&.MuiPickersDay-today': {\n            '&:not(.Mui-selected)': {\n              backgroundColor: 'transparent',\n              color: colorBase.primary,\n              borderColor: 'transparent',\n            },\n\n            // borderColor: colorBase.primary,\n            '&.Mui-selected': {\n              //backgroundColor: colorBase.primary,\n              color: colorBase.textPrimary,\n              backgroundColor: colorBase.primary,\n            },\n          },\n\n          '&:hover.Mui-selected, &:hover': {\n            backgroundColor: colorBase.tag,\n          },\n        },\n      },\n    },\n    MuiPickersCalendar: {\n      styleOverrides: {\n        root: {\n          minHeight: `var(--datePicker-height)`,\n          marginBottom: '.8rem',\n        },\n      },\n    },\n    MuiPickersCalendarHeader: {\n      styleOverrides: {\n        root: {\n          '&&': {\n            border: borderFunc(themeMode).borderConfig({ c_key: 'rgba(0,0,0,0)' }),\n            borderBottomColor: colorBase.divide,\n            boxSizing: 'border-box',\n            height: 52,\n            minHeight: 52,\n            maxHeight: 52,\n            margin: 0,\n            marginBottom: 0,\n            // margin:0,\n          },\n          '& .MuiButtonBase': {\n            color: colorBase.textSecondary,\n          },\n          '& .MuiTypography-subtitle1': {\n            fontSize: fontDefault.h4,\n          },\n        },\n      },\n    },\n    MuiPickersYear: {\n      styleOverrides: {\n        root: {\n          '&&': {\n            fontSize: '1.4rem',\n          },\n          '&& .MuiPickersYear-yearButton': {\n            color: colorBase.textSecondary,\n            fontSize: '1.4rem',\n            '&.Mui-selected': {\n              backgroundColor: colorBase.primary,\n              // color: colorBase.textThird,\n              borderRadius: radius * 2 + 'px',\n            },\n          },\n        },\n      },\n    },\n    MuiPickersModalDialog: {\n      dialogAction: {},\n    },\n  }\n}\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/themes/overrides/overrides-mui.ts",
    "content": "import { borderFunc, pxToRem, unit } from './utils'\nimport { ComponentsOverrides, TooltipProps } from '@mui/material'\nimport { fontDefault } from '../css/global'\n\nexport const radius = 4\nexport const checkBoxSize = 18\nexport const hr = ({ colorBase }: any) => {\n  return {\n    borderRadius: `${radius}px`,\n    content: '\"\"',\n    margin: `0 ${2 * unit}px`,\n    // margin: `0 ${unit}px`,\n    display: 'block',\n    height: `2px`,\n    backgroundColor: colorBase.primary,\n    position: 'absolute',\n    left: 0,\n    right: 0,\n    bottom: 0,\n  }\n}\n\nexport const MuiCheckbox = ({\n  colorBase,\n}: any): { styleOverrides: ComponentsOverrides['MuiCheckbox'] } => {\n  return {\n    styleOverrides: {\n      root: {\n        '&.MuiCheckbox-colorDefault': {\n          color: colorBase.textSecondary,\n        },\n        '&:hover': {\n          backgroundColor: 'inherit',\n          color: colorBase.textButtonSelect,\n        },\n        '&.Mui-checked': {\n          color: colorBase.textButtonSelect,\n          '&:hover': {\n            color: colorBase.textButtonSelect,\n          },\n        },\n        ' .MuiSvgIcon-fontSizeMedium ': {\n          // fontSize: fontDefault.h5\n          height: fontDefault.h5,\n          width: fontDefault.h5,\n        },\n      },\n    },\n  }\n}\nexport const MuiCard = ({ colorBase }: any) => {\n  return {\n    styleOverrides: {\n      root: {\n        backgroundColor: colorBase.box,\n        padding: pxToRem(24),\n      },\n    },\n  }\n}\n\nexport const MuiCardContent = () => {\n  return {\n    styleOverrides: {\n      root: {\n        padding: pxToRem(8),\n      },\n    },\n  }\n}\n\nexport const MuiCardActions = () => {\n  return {\n    styleOverrides: {\n      root: {\n        padding: 0,\n      },\n    },\n  }\n}\n\nexport const MuiLink = ({ colorBase }: any) => {\n  return {\n    styleOverrides: {\n      root: {\n        color: colorBase.secondary,\n        textDecoration: 'none',\n        '&:hover': {\n          color: colorBase.secondaryHover,\n        },\n        '&.Mui-selected': {\n          color: colorBase.secondaryPressed,\n        },\n      },\n    },\n  }\n}\n\nexport const MuiTextField = ({\n  colorBase,\n}: any): {\n  styleOverrides: ComponentsOverrides['MuiTextField']\n} => {\n  return {\n    styleOverrides: {\n      root: {\n        '.MuiFormHelperText-root': {\n          marginLeft: 0,\n          marginRight: 0,\n          textAlign: 'right',\n          whiteSpace: 'pre-line',\n        },\n        ' .MuiFormLabel-root': {\n          color: colorBase.textThird,\n          '&.Mui-focused': {\n            color: colorBase.textSecondary,\n          },\n        },\n      },\n    },\n  }\n}\n\n// export const MuiFormLabel = ({colorBase}: any): { styleOverrides: ComponentsOverrides['MuiFormLabel'] } => {\n//     return {\n//         styleOverrides: {\n//             root: {\n//\n//                 // '.MuiFormLabel-root':{\n//                 //\n//                 // }\n//             }\n//         }\n//     }\n// }\n\nexport const MuiModal = ({ colorBase }: any) => {\n  return {\n    styleOverrides: {\n      root: {\n        color: colorBase.textPrimary,\n        ' .MuiBackdrop-root': {\n          zIndex: -1,\n          backgroundColor: colorBase.mask,\n        },\n      },\n    },\n    defaultProps: {\n      disableAutoFocus: true,\n      disableEnforceFocus: true,\n      disableScrollLock: true,\n    },\n  }\n}\n\nexport const MuiToolbar = () => {\n  return {\n    styleOverrides: {\n      root: { height: 'var(--header-height)' },\n    },\n  }\n}\n\n// @ts-ignore\nexport const MuiSwitch = (): {\n  styleOverrides: ComponentsOverrides['MuiSwitch']\n} => {\n  return { styleOverrides: {} }\n}\n\nexport const MuiBadge = (): {\n  styleOverrides: ComponentsOverrides['MuiBadge']\n} => {\n  return {\n    styleOverrides: {\n      fontSize: '1rem',\n    },\n  }\n}\nexport const MuiButton = ({\n  colorBase,\n}: any): { styleOverrides: ComponentsOverrides['MuiButton'] } => {\n  return {\n    styleOverrides: {\n      root: {\n        textTransform: 'capitalize',\n        '&:not($sizeLarge):not($sizeSmall) $label': {\n          fontSize: '1.4rem',\n\n          // font: 'normal normal 700 0.875rem/1.6875rem Open Sans',\n          // color: 'green'\n        },\n        fontFamily: 'Roboto',\n        fontSize: pxToRem(14),\n        borderRadius: pxToRem(4),\n        fontWeight: 'normal',\n        paddingLeft: pxToRem(12),\n        paddingRight: pxToRem(12),\n        // '&.MuiButton-contained':{\n        //\n        // }\n      },\n      text: {\n        color: colorBase.secondary,\n        fontSize: '1.6rem',\n        '&:hover': {\n          'svg, &': {\n            color: colorBase.secondaryHover,\n          },\n          backgroundColor: 'inherit',\n        },\n        '&:active': {\n          color: colorBase.secondaryPressed,\n        },\n        '&:disabled': {\n          color: colorBase.disable,\n        },\n        '& .MuiButton-endIcon,& .MuiButton-startIcon': {\n          color: 'inherit',\n        },\n        '&.MuiButton-sizeSmall': {\n          fontSize: '1.4rem',\n        },\n      },\n      contained: {\n        color: colorBase.textButton,\n        height: pxToRem(40),\n        fontSize: pxToRem(14),\n        boxShadow: 'initial',\n        '&:hover': {\n          boxShadow: 'initial',\n          '&:before': {\n            background: colorBase.primaryHover,\n            content: \"''\",\n            position: 'absolute',\n            top: 0,\n            left: 0,\n            right: 0,\n            bottom: 0,\n            borderRadius: pxToRem(8),\n          },\n        },\n        borderRadius: pxToRem(8),\n        '&.Mui-disabled': {\n          backgroundColor: colorBase.defaultDisable,\n          color: colorBase.textDisable,\n        },\n      },\n      sizeLarge: {\n        height: pxToRem(48),\n        fontSize: '2.0rem',\n        fontWeight: 'normal',\n        //     '& .MuiButton-label': {\n        //\n        // }\n      },\n      sizeSmall: {\n        height: pxToRem(32),\n        fontSize: '1.6rem',\n        //     '& $label': {\n        //\n        // },\n      },\n      outlinedSizeSmall: {\n        height: pxToRem(24),\n        fontSize: '1.2rem',\n      },\n      outlined: {\n        height: pxToRem(32),\n        // boxShadow: '0px 4px 62px rgba(0, 0, 0, 0.25)',\n        fontSize: '1.4rem',\n        fontWeight: 'normal',\n        color: colorBase.textSecondary,\n        borderColor: colorBase.border,\n        backgroundColor: colorBase.box,\n        '&:hover': {\n          color: colorBase.textPrimary,\n          borderColor: colorBase.textPrimary,\n          backgroundColor: colorBase.box,\n        },\n        '&.MuiContained-sizeMedium': {\n          height: pxToRem(40),\n          fontSize: pxToRem(14),\n        },\n        '&.Mui-disabled': {\n          // backgroundColor: colorBase.defaultDisable,\n          color: colorBase.textDisable,\n          border: `1px dashed ${colorBase.textDisable}`,\n          // borderColor:\n          // backgroundImage: `url(\"data:image/svg+xml,%3csvg width='100%25' height='100%25' xmlns='http://www.w3.org/2000/svg'%3e%3crect width='100%25' height='100%25' fill='none' rx='4' ry='4' stroke='%23FFFFFF33' stroke-width='1' stroke-dasharray='4%25%2c 8%25' stroke-dashoffset='5' stroke-linecap='square'/%3e%3c/svg%3e\")`\n        },\n      },\n    },\n  }\n}\n\n// @ts-ignore\nexport const MuiPopover = (): {\n  styleOverrides: ComponentsOverrides['MuiPopover']\n} => {\n  return {\n    styleOverrides: {},\n  }\n}\n// export const MuiBackdrop = ({colorBase}: any) => {\n//     return {\n//         styleOverrides: {\n//             root: {\n//                 zIndex: -1,\n//\n//             }\n//         }\n//     }\n// }\n\nexport const MuiPaper = ({\n  colorBase,\n}: any): { styleOverrides: ComponentsOverrides['MuiPaper'] } => {\n  return {\n    styleOverrides: {\n      root: {\n        borderRadius: pxToRem(8),\n        backgroundImage: 'none',\n        backgroundColor: colorBase.popBg,\n        border: `.5px solid ${colorBase.border}`,\n        '&.MuiPopover-paper': {\n          backgroundImage: 'none',\n          boxShadow: colorBase.shadowHover,\n        },\n      },\n    },\n  }\n}\nexport const MuiSvgIcon = () => {\n  return {\n    styleOverrides: {\n      root: {\n        // margin: '-4px',\n        '&.MuiSvgIcon-fontSizeSmall': {\n          height: 'var(--svg-size)',\n          width: 'var(--svg-size)',\n        },\n        '&.MuiSvgIcon-fontSizeLarge': {\n          height: 'var(--svg-size-large)',\n          width: 'var(--svg-size-large)',\n          // margin: '-6px',\n        },\n        '&.MuiSvgIcon-fontSizeMedium': {\n          height: 'var(--svg-size-medium)',\n          width: 'var(--svg-size-medium)',\n          // margin: '-6px',\n        },\n        '&.tag': {\n          width: 'auto',\n          height: 'auto',\n        },\n        '&.custom-size': {\n          width: '1em',\n          height: '1em',\n        },\n        \n      },\n\n      \n    },\n    \n  }\n}\n//@ts-ignore\nexport const MuiRadio = () => {\n  return {\n    styleOverrides: {\n      root: {\n        ' svg': {\n          height: 'var(--svg-size)',\n          width: 'var(--svg-size)',\n        },\n      },\n    },\n  }\n}\n\nexport const MuiInputLabel = ({\n  colorBase,\n}: any): { styleOverrides: ComponentsOverrides['MuiInputLabel'] } => {\n  return {\n    styleOverrides: {\n      root: {\n        fontSize: fontDefault.body1,\n        height: 20,\n        color: colorBase.textThird,\n        transform: 'none',\n        top: 0,\n        left: 0,\n        right: 0,\n        '&.Mui-focused': {\n          color: colorBase.textSecondary,\n        },\n        '&.Mui-disabled ': {\n          color: colorBase.textSecondary,\n        },\n      },\n    },\n  }\n}\nexport const MuiInputBase = ({\n  colorBase,\n  themeMode,\n}: any): { styleOverrides: ComponentsOverrides['MuiInputBase'] } => {\n  return {\n    styleOverrides: {\n      root: {\n        'label + &': {\n          marginTop: 24,\n        },\n        position: 'relative',\n        fontSize: '1.4rem',\n        backgroundColor: colorBase.box,\n        border: borderFunc(themeMode).borderConfig({ c_key: colorBase.border }), //`1px solid ${colorBase.border}`,\n        borderRadius: 4,\n        boxSizing: 'border-box',\n        height: pxToRem(32),\n        '&.MuiInputBase-sizeSmall': {\n          height: pxToRem(32),\n        },\n        '&:not(.MuiFormControl-fullWidth)': {\n          // width: 'var(--btn-min-width)',\n          minWidth: 'var(--btn-min-width)',\n          // maxWidth: 'var(--btn-max-width)',\n        },\n        '& .MuiListItemText-multiline': {\n          display: 'flex',\n          flexDirection: 'row',\n          alignItems: 'center',\n          flexWrap: 'noWrap',\n          justifyContent: 'space-between',\n          margin: 0,\n          height: 'inherit',\n        },\n        '& fieldset': {\n          display: 'none',\n        },\n        ' .MuiInputAdornment-root, .MuiSelect-iconOutlined': {\n          color: colorBase.textThird,\n        },\n        '.search .MuiInputAdornment-root': {\n          pointerEvents: 'none',\n        },\n        paddingRight: 0,\n        '&:hover': {\n          border: borderFunc(themeMode).borderConfig({\n            c_key: colorBase.borderHover,\n          }), //`1px solid ${colorBase.border}`,\n        },\n        '&:disabled': {\n          backgroundColor: colorBase.defaultDisable,\n          borderColor: colorBase.defaultDisable,\n          color: colorBase.textBtnDisabled,\n        },\n        '.MuiSelect-iconOpen': {\n          transform: 'rotate(180deg)',\n        },\n        ' .MuiSelect-select': {\n          padding: 0,\n          border: 'transparent',\n          backgroundColor: 'transparent',\n          color: 'var(--color-text-primary)',\n          '&:focus': {\n            background: 'transparent',\n          },\n\n          ' svg': {\n            right: '.4rem',\n            top: '50%',\n            transform: 'translateY(-50%)',\n            position: 'absolute',\n            transition: 'fill 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms',\n            // color: 'var(--color-text-secondary)'\n          },\n          '&.MuiInputBase-root': {\n            minWidth: 'auto',\n            width: 'auto',\n          },\n        },\n\n        '&.MuiOutlinedInput-root': {\n          padding: '.3rem .3rem .3rem .8rem',\n          minWidth: 'auto',\n        },\n        '.text-address &.MuiOutlinedInput-root': {\n          paddingRight: '2em',\n        },\n        ' .MuiOutlinedInput-input': {\n          padding: 0,\n          height: 'calc(3.2rem - .6rem)',\n        },\n        ' .MuiSelect-outlined': {\n          height: 'calc(3.2rem - .6rem)',\n          lineHeight: 'calc(3.2rem - .6rem)',\n          minWidth: 'auto',\n        },\n        ' .MuiSelect-icon': {\n          color: colorBase.textThird,\n        },\n      },\n    },\n  }\n}\n\nexport const MuiIconButton = ({\n  colorBase,\n}: any): { styleOverrides: ComponentsOverrides['MuiIconButton'] } => {\n  return {\n    styleOverrides: {\n      root: {\n        color: 'inherit',\n        height: 'var(--btn-icon-size-medium)',\n        width: 'var(--btn-icon-size-medium)',\n        ' svg': {\n          height: 'var(--svg-size-medium)',\n          width: 'var(--svg-size-medium)',\n        },\n        '&.MuiIconButton-sizeLarge': {\n          height: 'var(--btn-icon-size)',\n          width: 'var(--btn-icon-size)',\n          ' svg': {\n            height: 'var(--svg-size-large)',\n            width: 'var(--svg-size-large)',\n          },\n        },\n        '&.MuiIconButton-sizeMedium': {\n          height: 'var(--btn-icon-size-medium)',\n          width: 'var(--btn-icon-size-medium)',\n          ' svg': {\n            height: 'var(--svg-size-medium)',\n            width: 'var(--svg-size-medium)',\n          },\n        },\n        '&.MuiIconButton-sizeSmall': {\n          height: 'var(--btn-icon-size-small)',\n          width: 'var(--btn-icon-size-small)',\n          ' svg': {\n            height: 'var(--svg-size)',\n            width: 'var(--svg-size)',\n          },\n        },\n        '&.MuiIconButton-colorInherit': {\n          color: colorBase.textSecondary,\n          '&:hover': {\n            color: colorBase.textPrimary,\n          },\n        },\n      },\n      // label: {\n      //     width: 'auto'\n      // }\n    },\n  }\n}\n\nexport const MuiToggleButton = ({\n  colorBase,\n}: any): { styleOverrides: ComponentsOverrides['MuiToggleButton'] } => {\n  return {\n    styleOverrides: {\n      root: {\n        '&.MuiToggleButton-sizeMedium': {\n          fontSize: '1.4rem',\n          minWidth: pxToRem(51),\n        },\n        height: pxToRem(28),\n        // boxShadow: '0px 4px 62px rgba(0, 0, 0, 0.25)',\n        borderRadius: '4px !important',\n        marginRight: pxToRem(2),\n        fontSize: '1.4rem',\n        color: colorBase.textSecondary,\n        border: 'none',\n        textTransform: 'none',\n        // borderColor: colorBase.border,\n        '&&:not(:first-of-type), &&:not(:last-child)': {\n          // borderColor: colorBase.border,\n        },\n        backgroundColor: 'inherit',\n        '&:hover': {\n          backgroundColor: 'inherit',\n          // color: colorBase.textButton,\n          color: colorBase.textPrimary,\n          // borderColor: colorBase.textPrimary,\n          border: 'none',\n          '&:not(:last-child), &:not(:first-of-type)': {\n            // borderColor: colorBase.textPrimary,\n          },\n          '&.Mui-selected,&.Mui-selected': {\n            // borderColor: colorBase.primary,\n          },\n        },\n        '&.Mui-disabled': {\n          // backgroundColor: colorBase.defaultDisable,\n          color: colorBase.textDisable,\n          border: 'none',\n          // border: '1px dashed',\n          // borderColor: colorBase.border\n          // backgroundImage: `url(\"data:image/svg+xml,%3csvg width='100%25' height='100%25' xmlns='http://www.w3.org/2000/svg'%3e%3crect width='100%25' height='100%25' fill='none' rx='4' ry='4' stroke='%23FFFFFF33' stroke-width='1' stroke-dasharray='4%25%2c 8%25' stroke-dashoffset='5' stroke-linecap='square'/%3e%3c/svg%3e\")`\n        },\n        '&&.Mui-selected, &&.Mui-selected + &.Mui-selected': {\n          color: colorBase.textButton,\n          backgroundColor: colorBase.primary,\n          // border: 'none'\n          // border: borderFunc(themeMode).borderConfig({c_key: rgba(colorBase.primary, 0.5)})\n        },\n      },\n    },\n  }\n}\nexport const MuiButtonBase = {\n  defaultProps: {\n    disableRipple: true,\n  },\n}\nexport const MuiPaginationItem = ({ colorBase }: any) => {\n  return {\n    styleOverrides: {\n      root: {\n        fontSize: '1.4rem',\n        color: colorBase.textSecondary,\n        borderRadius: '4px',\n      },\n      icon: {\n        fontSize: '2rem',\n      },\n      textPrimary: {\n        '&:hover': {\n          backgroundColor: colorBase.boxHover,\n          color: colorBase.textButtonSelect,\n        },\n        '&.Mui-selected': {\n          backgroundColor: 'transparent',\n          color: colorBase.textButtonSelect,\n          '&:hover': {\n            backgroundColor: colorBase.boxHover,\n            color: colorBase.textButtonSelect,\n          },\n        },\n      },\n      selected: {},\n    },\n  }\n}\nexport const MuiFormLabel = ({\n  colorBase,\n}: any): { styleOverrides: ComponentsOverrides['MuiFormLabel'] } => {\n  return {\n    styleOverrides: {\n      root: {\n        color: colorBase.textSecondary,\n        lineHeight: 1,\n        boxSizing: 'border-box',\n        '&.MuiInputLabel-shrink': {\n          transform: 'none',\n        },\n        '&.Mui-focused': {\n          color: colorBase.textSecondary,\n        },\n      },\n    },\n  }\n}\nexport const MuiBreadcrumbs = (): {\n  styleOverrides: ComponentsOverrides['MuiBreadcrumbs']\n} => {\n  return {\n    styleOverrides: {\n      root: {\n        ' .MuiLink-root': {\n          textDecoration: 'none',\n        },\n      },\n    },\n  }\n}\nexport const MuiList = () => {\n  return {\n    styleOverrides: {\n      root: {\n        '&.MuiList-padding': {\n          padding: '0.8rem 0',\n        },\n      },\n    },\n  }\n}\nexport const MuiListItem = ({ colorBase }: any) => {\n  return {\n    styleOverrides: {\n      root: {\n        height: pxToRem(32),\n        paddingLeft: pxToRem(20),\n        paddingRight: pxToRem(20),\n        color: colorBase.textSecondary,\n        '&:hover': {\n          color: colorBase.textButtonSelect,\n          background: colorBase.boxHover,\n        },\n        '&.Mui-selected, &.Mui-focusVisible': {\n          backgroundColor: 'transparent',\n          color: colorBase.textButtonSelect,\n          // \" .MuiTypography-body1\":{\n          //     color: colorBase.textButtonSelect,\n          // },\n          '&:hover': {\n            color: colorBase.textButtonSelect,\n            // \" .MuiTypography-body1\":{\n            //     color: colorBase.textButtonSelect,\n            // },\n          },\n        },\n        ' .MuiListItemAvatar-root': {\n          color: colorBase.buttonIcon, // \"var(--color-button-icon)\"\n        },\n      },\n    },\n  }\n}\nexport const MuiMenu = ({ colorBase }: any) => {\n  return {\n    styleOverrides: {\n      root: {\n        ' .MuiBackdrop-root': {\n          opacity: '0 !important',\n        },\n      },\n      list: {\n        backgroundColor: colorBase.popBg,\n      },\n    },\n  }\n}\nexport const MuiMenuItem = ({ colorBase, themeMode }: any) => {\n  return {\n    styleOverrides: {\n      root: {\n        height: pxToRem(32),\n        borderLeft: borderFunc(themeMode).borderConfig({\n          c_key: 'var(--opacity)',\n        }), ////`1px solid transparent`,\n        // borderLeftColor: 'transparent',\n        paddingLeft: pxToRem(12),\n        paddingRight: pxToRem(12),\n        color: colorBase.textSecondary,\n        '&.Mui-selected, &.Mui-selected.Mui-focusVisible': {\n          background: colorBase.boxHover,\n          color: colorBase.textButtonSelect,\n          // \" .MuiTypography-body1\":{\n          //     color: colorBase.textButtonSelect,\n          // },\n        },\n\n        // backgroundColor: `${colorBase.borderHover} !important`,\n        '&:hover, &.Mui-selected:hover': {\n          // background:'inherit',\n          // color: colorBase.textPrimary,\n          // borderColor: colorBase.primaryLight,\n          background: colorBase.boxHover,\n        },\n        '& .MuiListItemText-multiline': {\n          display: 'flex',\n          flexDirection: 'row',\n          alignItems: 'space-between',\n          flexWrap: 'noWrap',\n          justifyContent: 'space-between',\n          '&.Mui-selected, &.Mui-selected.Mui-focusVisible': {\n            '&:after': {\n              display: 'none',\n            },\n          },\n        },\n        // '&.Mui-selected, &.Mui-selected.Mui-focusVisible': {\n        //     // backgroundColor: 'transparent',\n        //     background: 'none',\n        //     color: colorBase.textPrimary,\n        //     // '&:after': {\n        //     //     fontSize: '1.6rem',\n        //     //     height: '1em',\n        //     //     width: '1em',\n        //     //     right: '1em',\n        //     //     position: 'absolute',\n        //     //     display: 'block',\n        //     //     content: `url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 13' fill='` + encodeURIComponent(colorBase.primaryLight) + `'><path fillRule='evenodd' clipRule='evenodd' d='M17.7071 0.292893C18.0976 0.683417 18.0976 1.31658 17.7071 1.70711L6.70711 12.7071C6.31658 13.0976 5.68342 13.0976 5.29289 12.7071L0.292893 7.70711C-0.0976311 7.31658 -0.0976311 6.68342 0.292893 6.29289C0.683417 5.90237 1.31658 5.90237 1.70711 6.29289L6 10.5858L11.1464 5.43934L16.2929 0.292893C16.6834 -0.0976311 17.3166 -0.0976311 17.7071 0.292893Z' /></svg>\\\")`\n        //     // }\n        // },\n      },\n    },\n  }\n}\nexport const MuiTab = ({ colorBase }: any): { styleOverrides: ComponentsOverrides['MuiTab'] } => {\n  return {\n    styleOverrides: {\n      root: {\n        fontWeight: 'normal',\n        padding: `${unit * 2}px`,\n        maxWidth: 'initial',\n        minWidth: 'auto !important',\n        fontSize: fontDefault.h5,\n        color: colorBase.textSecondary,\n        '&:hover': {\n          backgroundColor: 'transparent',\n        },\n        '&.MuiTab-root': {\n          textTransform: 'capitalize',\n        },\n        '&.Mui-selected': {\n          color: colorBase.textPrimary,\n          '&:after': hr({ colorBase }),\n        },\n        '&:focus-visible::after, &:active::after, &.Mui-selected:after': hr({\n          colorBase,\n        }),\n        '&MuiTab-fullWidth.:focus-visible::after, &.MuiTab-fullWidth:active::after, &.MuiTab-fullWidth.Mui-selected:after':\n          {\n            margin: 0,\n          },\n        '> div, > button': {\n          height: 'calc(100% - 2px)',\n          textTransform: 'capitalize',\n        },\n        '.MuiTabs-indicator': {\n          display: 'none',\n        },\n        '.MuiTabs-small &.MuiTab-root': {\n          fontSize: fontDefault.body1,\n          padding: `${unit}px`,\n          minHeight: `36px`,\n        },\n      },\n    },\n  }\n}\nexport const MuiTabs = () => {\n  return {\n    styleOverrides: {\n      root: {\n        '& .MuiTabs-indicator': {\n          display: 'none',\n          background: 'red',\n        },\n        '& .MuiTabs-small': {\n          minHeight: '28px',\n          height: '28px',\n          fontSize: '',\n        },\n      },\n    },\n  }\n}\nexport const MuiListItemAvatar = () => {\n  return {\n    styleOverrides: {\n      root: {\n        minWidth: 'auto',\n        marginRight: `${unit}px`,\n        '.MuiAvatar-root': {\n          height: `var(--list-menu-coin-size)`,\n          width: `var(--list-menu-coin-size)`,\n          svg: {\n            height: `var(--header-menu-icon-size)`,\n            width: `var(--header-menu-icon-size)`,\n          },\n        },\n      },\n    },\n  }\n}\nexport const MuiDivider = ({ colorBase }: any) => {\n  return {\n    styleOverrides: {\n      root: {\n        borderColor: `${colorBase.divide}`,\n        // margin: `${unit / 4 * 5}px 0`,\n      },\n    },\n  }\n}\n\nexport const MuiAlert = ({ colorBase }: any) => {\n  return {\n    styleOverrides: {\n      root: {\n        // backgroundColor: colorBase.borderDark,\n        // backgroundColor: 'var(--color-pop-bg)',\n        backgroundColor: colorBase.popBg,\n        height: `auto`,\n        '.MuiAlertTitle-root': {\n          color: colorBase.textPrimary,\n          fontSize: pxToRem(16),\n        },\n      },\n    },\n  }\n}\n\nexport const MuiDialogTitle = ({ colorBase }: any) => {\n  return {\n    styleOverrides: {\n      root: {\n        '&.MuiDialogTitle-root': {\n          color: colorBase.textPrimary,\n          fontSize: pxToRem(16),\n          padding: `${2 * unit}px`,\n        },\n      },\n    },\n  }\n}\nexport const MuiDialog = ({ colorBase }: any) => {\n  return {\n    styleOverrides: {\n      root: {\n        ' .MuiPaper-root': {\n          background: colorBase.box,\n          borderRadius: pxToRem(4),\n        },\n        ' .MuiDialogContent-root': {\n          padding: `0 ${2 * unit}px ${2 * unit}px ${2 * unit}px`,\n        },\n        ' .MuiDialogActions-root': {\n          padding: `0 ${2 * unit}px ${2 * unit}px ${2 * unit}px`,\n        },\n      },\n    },\n    defaultProps: {\n      disableAutoFocus: true,\n      disableEnforceFocus: true,\n      disableScrollLock: true,\n    },\n  }\n}\n\nexport const MuiSnackbar = () => {\n  return {\n    styleOverrides: {\n      root: {\n        '@media (min-width: 600px)': {\n          top: `${unit * 10}px`,\n          right: `${unit * 2}px`,\n        },\n        top: `${unit * 10}px`,\n        right: `${unit * 2}px`,\n        width: 'auto',\n        minHeight: `${unit * 10}px`,\n        justifyContent: 'flex-end',\n        alignItems: 'flex-start',\n        pointerEvents: 'none' as any,\n      },\n    },\n  }\n}\n\nexport const MuiLinearProgress = ({ colorBase }: any) => {\n  return {\n    styleOverrides: {\n      root: {\n        height: '0.8rem',\n      },\n      barColorPrimary: {\n        backgroundColor: colorBase.star,\n        borderRadius: '28px',\n      },\n      determinate: {\n        backgroundColor: colorBase.borderHover,\n        borderRadius: '28px',\n      },\n    },\n  }\n}\n\nexport const MuiTooltip = ({\n  colorBase,\n}: any): {\n  styleOverrides: ComponentsOverrides['MuiTooltip']\n  defaultProps?: Partial<TooltipProps>\n} => {\n  return {\n    defaultProps: {\n      arrow: true,\n    },\n    styleOverrides: {\n      tooltip: {\n        fontSize: fontDefault.body1,\n        fontWeight: 400,\n        color: colorBase.textSecondary,\n        background: colorBase.popBg,\n        boxShadow: colorBase.shadowHover,\n        lineHeight: '1.5em',\n        border: `0.5px solid ${colorBase.border}`,\n        padding: `${unit * 2}px`,\n        borderRadius: `${unit}px`,\n      },\n      arrow: {\n        color: colorBase.popBg,\n        '&:before': {\n          border: `0.5px solid ${colorBase.border}`,\n        },\n      },\n      // root: {\n      //   fontSize: fontDefault.body1,\n      //   color: colorBase.textSecondary,\n      // },\n    },\n  }\n}\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/themes/overrides/utils.ts",
    "content": "import { ColorDarkDefault, ColorLightDefault } from '../css/color-lib'\nimport { fontDefault } from '../css/global'\nimport { ThemeKeys } from '../interface'\nimport { IsMobile } from '../../utils'\n\nconst isMobile = IsMobile.any()\nexport const unit = isMobile ? 4 : 8\nexport const pxToRem = (px: any, oneRemPx = 10) => `${px / oneRemPx}rem`\nexport const borderFunc = (themeMode: ThemeKeys) => {\n  const colorBase = themeMode === 'dark' ? ColorDarkDefault : ColorLightDefault\n  const borderColor = {\n    default: colorBase.border,\n    primary: colorBase.secondary,\n    selected: colorBase.secondaryPressed,\n    focus: colorBase.borderHover,\n  }\n  return {\n    defaultBorder: `1px solid ${borderColor.default}`,\n    defaultRadius: `${unit / 2}px`,\n    FontDefault: fontDefault,\n    defaultFrame: ({\n      d_W = 1,\n      d_R = 1,\n      c_key = 'primary',\n    }: {\n      d_W?: number\n      d_R?: number\n      c_key?: 'primary' | 'selected' | 'focus' | string\n    }) => {\n      let color\n      switch (c_key) {\n        case 'primary':\n        case 'selected':\n        case 'focus':\n          color = borderColor[c_key]\n          break\n        default:\n          color = c_key\n      }\n      return `\n        border: ${d_W}px solid ${color};\n        border-radius: ${d_R * unit}px;\n       `\n    },\n    borderConfig: ({\n      d_W = 1,\n      c_key = 'primary',\n    }: {\n      d_W?: number\n      c_key?: 'primary' | 'selected' | 'focus' | string\n    }) => {\n      let color\n      switch (c_key) {\n        case 'primary':\n        case 'selected':\n        case 'focus':\n          color = borderColor[c_key]\n          break\n        default:\n          color = c_key\n      }\n      return `${d_W}px solid ${color}`\n    },\n  }\n}\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/utils/format_tools.ts",
    "content": "import * as sdk from '@loopring-web/loopring-sdk'\nimport BigNumber from 'bignumber.js'\nimport { getValuePrecisionThousand } from './util'\nimport { myError } from './log_tools'\nimport { getAddress } from '@ethersproject/address'\n\nexport function isAddress(value: any): string | false {\n  try {\n    return getAddress(value)\n  } catch {\n    return false\n  }\n}\nexport function getShowStr(\n  rawVal: string | number | undefined,\n  fixed: number = 2,\n  precision: number = 4,\n) {\n  if (rawVal === '0' || rawVal === 0) return '0'\n  let newVal: any = undefined\n  if (rawVal) {\n    newVal = typeof rawVal === 'number' ? rawVal : parseFloat(rawVal)\n    if (newVal > 10) {\n      newVal = newVal.toFixed(fixed)\n    } else {\n      newVal = sdk.toBig(newVal).toPrecision(precision)\n    }\n  }\n  return newVal\n}\n\nexport type DepthData = {\n  amtSlice: sdk.ABInfo[]\n  amtTotalSlice: string[]\n  priceSlice: number[]\n  baseDecimal: number\n  quoteDecimal: number\n  count: number\n  maxVal: BigNumber\n  precisionForPrice: number\n  basePrecision: number\n}\nexport type DepthViewData = {\n  price: number\n  amt: string\n  amtForShow: string\n  amtTotal: string\n  amtTotalForShow: string\n  percentage: number\n}\nfunction genABViewDataAccumulated({\n  // precisionForPrice,\n  amtSlice,\n  amtTotalSlice,\n  priceSlice,\n  baseDecimal,\n  count,\n  maxVal,\n  basePrecision,\n}: DepthData): DepthViewData[] {\n  if (amtTotalSlice.length < count) {\n    const lastV = amtTotalSlice[amtTotalSlice.length - 1]\n    amtSlice = amtSlice.concat(new Array(count - amtSlice.length).fill(lastV))\n    amtTotalSlice = amtTotalSlice.concat(new Array(count - amtTotalSlice.length).fill(lastV))\n    priceSlice = priceSlice.concat(new Array(count - priceSlice.length).fill(0))\n  }\n\n  amtSlice = amtSlice.reverse()\n  amtTotalSlice = amtTotalSlice.reverse()\n  priceSlice = priceSlice.reverse()\n\n  return amtTotalSlice.reduce((prv, value: string, ind: number) => {\n    if (amtSlice[ind] && amtSlice[ind].amt) {\n      const amt = amtSlice[ind].amt\n      // @ts-ignore\n      const amtForShow = getValuePrecisionThousand(\n        sdk.toBig(amt).div('1e' + baseDecimal),\n        undefined,\n        undefined,\n        basePrecision,\n        true,\n        { isAbbreviate: true },\n      )\n      const amtTotalForShow = getValuePrecisionThousand(\n        sdk.toBig(value).div('1e' + baseDecimal),\n        undefined,\n        undefined,\n        basePrecision,\n        true,\n        { isAbbreviate: true },\n      )\n      const percentage = maxVal.gt(sdk.toBig(0)) ? sdk.toBig(value).div(maxVal).toNumber() : 0\n      prv.push({\n        price: priceSlice[ind],\n        amt,\n        amtForShow,\n        amtTotal: amtTotalSlice[ind],\n        amtTotalForShow,\n        percentage,\n      })\n    }\n    return prv\n\n    // myLog('value:', value, ' maxVal:', maxVal.toString(), percentage)\n  }, [] as DepthViewData[])\n}\n\nexport function depth2ViewDataAccumulated({\n  depth,\n  countAsk,\n  countBid,\n  baseDecimal,\n  quoteDecimal,\n  precisionForPrice,\n  basePrecision,\n}: {\n  depth: sdk.DepthData\n  baseDecimal: number\n  quoteDecimal: number\n  countAsk?: number\n  countBid?: number\n  maxWidth?: number\n  basePrecision: number\n  precisionForPrice: number\n}): { asks: DepthViewData[]; bids: DepthViewData[] } {\n  if (countAsk === undefined || countBid === undefined) {\n    countAsk = 8\n    countBid = 8\n  }\n\n  let askSlice = depth.asks.slice(0, countAsk)\n  let askTotalSlice = depth.asks_amtTotals.slice(0, countAsk)\n  let askPriceSlice = depth.asks_prices.slice(0, countAsk)\n\n  let bidSlice = countBid > 0 ? depth.bids.slice(-countBid) : []\n  let bidTotalSlice = countBid > 0 ? depth.bids_amtTotals.slice(-countBid) : []\n  let bidPriceSlice = countBid > 0 ? depth.bids_prices.slice(-countBid) : []\n\n  let maxVal = sdk.toBig(0)\n\n  if (askTotalSlice.length && bidTotalSlice.length) {\n    maxVal = BigNumber.max(\n      sdk.toBig(askTotalSlice[askTotalSlice.length - 1]),\n      sdk.toBig(bidTotalSlice[0]),\n    )\n  } else if (askTotalSlice.length) {\n    maxVal = sdk.toBig(askTotalSlice[askTotalSlice.length - 1])\n  } else if (bidTotalSlice.length) {\n    maxVal = sdk.toBig(bidTotalSlice[0])\n  } else {\n    myError('no ab input!')\n    // throw new Error('no ab input!')\n  }\n\n  const asks = genABViewDataAccumulated({\n    basePrecision,\n    precisionForPrice,\n    amtSlice: askSlice,\n    amtTotalSlice: askTotalSlice,\n    priceSlice: askPriceSlice,\n    baseDecimal,\n    quoteDecimal,\n    count: countAsk,\n    maxVal,\n  })\n\n  const bids = genABViewDataAccumulated({\n    basePrecision,\n    precisionForPrice,\n    amtSlice: bidSlice,\n    amtTotalSlice: bidTotalSlice,\n    priceSlice: bidPriceSlice,\n    baseDecimal,\n    quoteDecimal,\n    count: countBid,\n    maxVal,\n  })\n\n  return {\n    asks,\n    bids,\n  }\n}\n\nexport type DepthDataNew = {\n  amtSlice: sdk.ABInfo[]\n  abInfoSlice: sdk.ABInfo[]\n  amtTotalSlice: string[]\n  priceSlice: number[]\n  baseDecimal: number\n  quoteDecimal: number\n  count: number\n  maxVal: BigNumber\n  precisionForPrice: number\n  basePrecision: number\n}\n\nfunction genABViewData({\n  // precisionForPrice,\n  amtSlice,\n  abInfoSlice,\n  amtTotalSlice,\n  priceSlice,\n  baseDecimal,\n  count,\n  maxVal,\n  basePrecision,\n}: DepthDataNew): DepthViewData[] {\n  if (abInfoSlice.length < count) {\n    const lastV = abInfoSlice[abInfoSlice.length - 1] ?? {}\n    amtSlice = amtSlice.concat(new Array(count - amtSlice.length).fill(lastV.amt))\n    amtTotalSlice = amtTotalSlice.concat(\n      new Array(count - amtTotalSlice.length).fill(lastV.amtTotal),\n    )\n    abInfoSlice = abInfoSlice.concat(new Array(count - abInfoSlice.length).fill(lastV))\n    priceSlice = priceSlice.concat(new Array(count - priceSlice.length).fill(0))\n  }\n\n  amtSlice = amtSlice.reverse()\n  amtTotalSlice = amtTotalSlice.reverse()\n  abInfoSlice = abInfoSlice.reverse()\n  priceSlice = priceSlice.reverse()\n\n  return abInfoSlice.reduce((prv, value: sdk.ABInfo, ind: number) => {\n    if (amtSlice[ind] && amtSlice[ind].amt) {\n      const amt = amtSlice[ind].amt\n      const amtForShow = getValuePrecisionThousand(\n        sdk.toBig(amt).div('1e' + baseDecimal),\n        undefined,\n        undefined,\n        basePrecision,\n        true,\n        { isAbbreviate: true },\n      )\n      const amtTotalForShow = getValuePrecisionThousand(\n        sdk.toBig(amtTotalSlice[ind]).div('1e' + baseDecimal),\n        undefined,\n        undefined,\n        basePrecision,\n        true,\n        { isAbbreviate: true },\n      )\n      const percentage = maxVal.gt(sdk.toBig(0)) ? sdk.toBig(value.amt).div(maxVal).toNumber() : 0\n      prv.push({\n        price: priceSlice[ind],\n        amt,\n        amtForShow,\n        amtTotal: amtTotalSlice[ind],\n        amtTotalForShow,\n        percentage,\n      })\n    }\n    return prv\n  }, [] as DepthViewData[])\n}\n\nfunction getMaxAmt(askInfoSlice: sdk.ABInfo[], bidInfoSlice: sdk.ABInfo[]) {\n  let maxVal = sdk.toBig(0)\n\n  const totalLst = askInfoSlice.concat(bidInfoSlice)\n\n  totalLst.forEach((item: sdk.ABInfo) => {\n    const newAmt = sdk.toBig(item.amt)\n    if (newAmt.gte(maxVal)) {\n      maxVal = newAmt\n    }\n  })\n\n  return maxVal\n}\n\nexport function depth2ViewData({\n  depth,\n  countAsk,\n  countBid,\n  baseDecimal,\n  quoteDecimal,\n  precisionForPrice,\n  basePrecision,\n}: {\n  depth: sdk.DepthData\n  baseDecimal: number\n  quoteDecimal: number\n  countAsk?: number\n  countBid?: number\n  maxWidth?: number\n  basePrecision: number\n  precisionForPrice: number\n}): { asks: DepthViewData[]; bids: DepthViewData[] } {\n  if (countAsk === undefined || countBid === undefined) {\n    countAsk = 8\n    countBid = 8\n  }\n\n  let askSlice = depth.asks.slice(0, countAsk)\n  let askInfoSlice = depth.asks.slice(0, countAsk)\n  let askTotalSlice = depth.asks_amtTotals.slice(0, countAsk)\n  let askPriceSlice = depth.asks_prices.slice(0, countAsk)\n\n  let bidSlice = countBid > 0 ? depth.bids.slice(-countBid) : []\n  let bidInfoSlice = countBid > 0 ? depth.bids.slice(-countBid) : []\n  let bidTotalSlice = countBid > 0 ? depth.bids_amtTotals.slice(-countBid) : []\n  let bidPriceSlice = countBid > 0 ? depth.bids_prices.slice(-countBid) : []\n\n  const maxVal = getMaxAmt(askInfoSlice, bidInfoSlice)\n\n  const asks =\n    countAsk > 0\n      ? genABViewData({\n          basePrecision,\n          precisionForPrice,\n          amtSlice: askSlice,\n          amtTotalSlice: askTotalSlice,\n          abInfoSlice: askInfoSlice,\n          priceSlice: askPriceSlice,\n          baseDecimal,\n          quoteDecimal,\n          count: countAsk,\n          maxVal,\n        })\n      : []\n\n  const bids =\n    countBid > 0\n      ? genABViewData({\n          basePrecision,\n          precisionForPrice,\n          amtSlice: bidSlice,\n          amtTotalSlice: bidTotalSlice,\n          abInfoSlice: bidInfoSlice,\n          priceSlice: bidPriceSlice,\n          baseDecimal,\n          quoteDecimal,\n          count: countBid,\n          maxVal,\n        })\n      : []\n\n  return {\n    asks,\n    bids,\n  }\n}\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/utils/index.ts",
    "content": "export * from './types'\nexport * from './util'\nexport * from './log_tools'\nexport * from './format_tools'\nexport * from './obj_tools'\nexport * from './makeDom'\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/utils/log_tools.ts",
    "content": "let _myLog\n// @ts-ignore\nif (process.env.NODE_ENV !== 'production' || window?.___OhTrustDebugger___) {\n  _myLog = console.log\n} else {\n  // @ts-ignore\n  _myLog = function (message?: any, ...optionalParams: any[]) {}\n}\nlet _myError\n// @ts-ignore\nif (process.env.NODE_ENV !== 'production' || window?.___OhTrustDebugger___) {\n  _myError = console.error\n} else {\n  // @ts-ignore\n  _myError = function (message?: any, ...optionalParams: any[]) {}\n}\nexport const setMyLog = (___OhTrustDebugger___: boolean) => {\n  if (___OhTrustDebugger___) {\n    _myLog = console.log\n  }\n}\nexport const myLog = _myLog\nexport const myError = _myError\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/utils/makeDom.ts",
    "content": "export const htmlDecode = (input: string) => {\n  const doc = new DOMParser().parseFromString(input, 'text/html')?.documentElement?.textContent\n  return doc ?? ''\n}\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/utils/obj_tools.ts",
    "content": "import { myLog } from './log_tools'\n\nexport async function copyToClipBoard(text: string) {\n  if (document.execCommand) {\n    var textarea = document.createElement('textarea')\n    document.body.appendChild(textarea)\n    textarea.value = text\n    textarea.select()\n    document.execCommand('copy')\n    document.body.removeChild(textarea)\n  }\n\n  if (navigator.clipboard) {\n    await navigator.clipboard.writeText(text)\n  }\n\n  if ((window as any).clipboardData) {\n    ;(window as any).clipboardData.setData('Text', text)\n\n    myLog('clipboardData:', text)\n    return true\n  }\n  return false\n}\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/utils/types.tsx",
    "content": "type Values<T extends {}> = T[keyof T]\n\ntype Tuplize<T extends {}[]> = Pick<T, Exclude<keyof T, Extract<keyof {}[], string> | number>>\n\ntype _OneOf<T extends {}> = Values<{\n  [K in keyof T]: T[K] & {\n    [M in Values<{ [L in keyof Omit<T, K>]: keyof T[L] }>]?: undefined\n  }\n}>\n\nexport type OneOf<T extends {}[]> = _OneOf<Tuplize<T>>\n\nexport type Complete<T> = {\n  [P in keyof Required<T>]: Pick<T, P> extends Required<Pick<T, P>> ? T[P] : T[P] | undefined\n}\n\nexport type Required<T> = {\n  [P in keyof T]-?: T[P]\n}\n\nexport type RequireOne<T, K extends keyof T> = {\n  [X in Exclude<keyof T, K>]?: T[X]\n} & {\n  [P in K]-?: T[P]\n}\n\n// type Partial<T> = {\n//     [P in keyof T]?: T[P]\n// }\n"
  },
  {
    "path": "packages/common-resources/static-resources/src/utils/util.ts",
    "content": "import { toBig } from '@loopring-web/loopring-sdk'\nimport BigNumber from 'bignumber.js'\n\nexport const DOT = '.'\n\nexport function abbreviateNumber(value: number, precision?: number) {\n  let newValue = value,\n    result: string\n  const suffixes = ['', 'K', 'M', 'B', 'T', 'Qa', 'Qi']\n  let suffixNum = 0\n  while (newValue >= 1000) {\n    newValue /= 1000\n    suffixNum++\n  }\n\n  if (precision) {\n    result = newValue.toFixed(precision)\n  } else {\n    result = newValue.toPrecision(3)\n  }\n\n  result += suffixes[suffixNum]\n  return result\n}\n\nexport const getAbbreviateNumber = (value: number | string) => {\n  let newValue: any = value\n  value = parseInt(toBig(value).toString())\n  const formattedValue = toBig(value).toNumber()\n  if (formattedValue >= 1000) {\n    let suffixes = ['', 'K', 'M', 'B', 'T']\n    let suffixNum = Math.floor(('' + formattedValue).length / 3)\n    let shortValue: string | number = 0\n    for (let precision = 3; precision >= 1; precision--) {\n      shortValue = parseFloat(\n        (suffixNum !== 0\n          ? formattedValue / 1000 ** suffixNum //(Math.pow(1000, suffixNum))\n          : formattedValue\n        ).toPrecision(precision),\n      )\n      const dotLessShortValue = (shortValue + '').replace(/[^a-zA-Z 0-9]+/g, '')\n      if (dotLessShortValue.length <= 3) {\n        break\n      }\n    }\n    if (shortValue && toBig(shortValue).toNumber() % 1 !== 0) {\n      shortValue = toBig(shortValue).toNumber()\n    }\n    newValue = shortValue + suffixes[suffixNum]\n  }\n  return newValue\n}\n\nexport const getFormattedHash = (hash?: string) => {\n  if (!hash) return hash\n  const firstSix = hash.slice(0, 6)\n  const lastFour = hash.slice(hash.length - 4)\n  return `${firstSix}****${lastFour}`\n}\n\nexport function getShortAddr(address: string, isMobile?: boolean): string | '' {\n  if (!address || address.trim() === '') {\n    return ''\n  }\n  return (isMobile ? '0x' : address.substr(0, 6)) + '...' + address.substr(address.length - 4)\n}\n\nconst getFloatFloor = (value: number | string | undefined, precision: number) => {\n  if (\n    (!value || !Number.isFinite(Number(value)) || Number(value) === 0) &&\n    !BigNumber.isBigNumber(value)\n  ) {\n    return '0.00'\n  }\n  const result = Math.floor(Number(value) * 10 ** precision) // Math.pow(10, precision));\n  return result / 10 ** precision //Math.pow(10, precision);\n}\n\nconst getFloatCeil = (value: number | string | undefined, precision: number) => {\n  if (\n    (!value || !Number.isFinite(Number(value)) || Number(value) === 0) &&\n    !BigNumber.isBigNumber(value)\n  ) {\n    return '0.00'\n  }\n  let result = Math.ceil(Number(value) * 10 ** precision) //  Math.pow(10, precision)\n  return result / 10 ** precision //Math.pow(10, precision);\n}\n\nconst addZeroAfterDot = (value: string) => {\n  let [_init, _dot] = value.split(DOT)\n  if (_dot) {\n    _dot = _dot.replace(/0+?$/, '')\n    if (_dot) {\n      value = _init + DOT + _dot\n    } else {\n      value = _init\n    }\n    return value\n  }\n  return value\n}\n\n/**\n * @param value\n * @param minDigit  default = 6\n * @param precision  default = 2\n * @param fixed default = undefined\n * @param notRemoveEndZero default will remove after dot end 0\n * @param option { floor?: boolean, isFait?: boolean, isTrade?: boolean }\n */\nexport const getValuePrecisionThousand = (\n  value: number | string | BigNumber | undefined | BigNumber,\n  minDigit = 6,\n  precision = 2,\n  fixed?: number,\n  notRemoveEndZero?: boolean,\n  option?: {\n    floor?: boolean\n    isFait?: boolean\n    isTrade?: boolean\n    isExponential?: boolean\n    isPrice?: boolean\n    abbreviate?: 3 | 6 | 9 | 12 | 15 | 18\n    isAbbreviate?: boolean\n  },\n) => {\n  const floor = option?.floor\n  const isFait = option?.isFait\n  const isTrade = option?.isTrade\n  const isExponential = option?.isExponential\n  const isPrice = option?.isPrice\n  const isAbbreviate = option?.isAbbreviate\n  const abbreviate = option?.abbreviate ?? 6\n  if (\n    (!value || !Number.isFinite(Number(value)) || Number(value) === 0) &&\n    !BigNumber.isBigNumber(value)\n  ) {\n    return '0.00'\n  }\n  let result: any = value\n\n  if (!BigNumber.isBigNumber(result)) {\n    result = toBig(value)\n  }\n\n  // integer part exceed 6 digits abbreaviate, otherwise toLocaleString\n  if (isAbbreviate === true) {\n    let [_init, _dot] = result.toString().split(DOT)\n    const integerPartLength = _init.length\n    if (integerPartLength > abbreviate) {\n      // return getAbbreviateNumber(result)\n      return abbreviateNumber(result.toString())\n    }\n  }\n\n  // remove exponential\n  if (isExponential === true) {\n    result = toBig(toBig(value).toFixed(20))\n  }\n\n  if (isPrice === true) {\n    return toBig(toBig(result).toFixed(fixed || 6))\n      .toNumber()\n      .toLocaleString('en-US', { minimumFractionDigits: fixed || 6 })\n  }\n\n  // fait price\n  if (isFait === true) {\n    if (toBig(result).isGreaterThanOrEqualTo(1)) {\n      if (floor === true) {\n        result = getFloatFloor(result, 2)\n      }\n      if (floor === false) {\n        result = getFloatCeil(result, 2)\n      }\n      // fixed 2 decimals\n      return toBig(result.toFixed(2))\n        .toNumber()\n        .toLocaleString('en-US', { minimumFractionDigits: 2 })\n    } else {\n      if (floor === true) {\n        result = toBig(result).sd(minDigit ?? 6, BigNumber.ROUND_DOWN) //getFloatFloor(result, precision ?? 6)\n      }\n      if (floor === false) {\n        result = toBig(result).sd(minDigit ?? 6, BigNumber.ROUND_CEIL)\n        // result = getFloatCeil(result, precision ?? 6)\n      }\n      return toBig(result)\n        .toNumber()\n        .toLocaleString('en-US', { minimumFractionDigits: notRemoveEndZero ? 6 : undefined })\n    }\n  }\n  if (isTrade === true) {\n    let [_init, _dot] = result.toString().split('.')\n    if (_dot && _dot.length > 3) {\n      return result.toNumber().toLocaleString('en-US', { minimumFractionDigits: _dot.length })\n    } else {\n      return result.toNumber().toLocaleString('en-US')\n    }\n  }\n  if (result.isGreaterThan(1)) {\n    let formattedValue: any = null\n    if (floor === true) {\n      formattedValue = getFloatFloor(result, fixed || minDigit)\n    }\n    if (floor === false) {\n      formattedValue = getFloatCeil(result, fixed || minDigit)\n    }\n    if (floor === undefined) {\n      formattedValue = result.toFixed(fixed || minDigit)\n    }\n    // remain string-number zero\n    result = toBig(formattedValue)\n      .toNumber()\n      .toLocaleString('en-US', { minimumFractionDigits: fixed || minDigit })\n  } else if (result.isLessThanOrEqualTo(1)) {\n    if (floor === false) {\n      result = getFloatCeil(result, fixed || precision).toString()\n    } else {\n      result = fixed\n        ? result.toFixed(fixed)\n        : precision\n        ? toBig(result).toPrecision(precision)\n        : toBig(result).toFixed(0)\n    }\n  }\n\n  if (result && !notRemoveEndZero) {\n    result = addZeroAfterDot(result)\n  }\n  if (BigNumber.isBigNumber(result) ) {\n    result = result.toString()\n  }\n\n  return result\n}\n\nexport const IsMobile = {\n  Android: function () {\n    return navigator.userAgent.match(/Android/i)\n  },\n  BlackBerry: function () {\n    return navigator.userAgent.match(/BlackBerry/i)\n  },\n  iOS: function () {\n    return navigator.userAgent.match(/iPhone|iPad|iPod/i)\n  },\n  Opera: function () {\n    return navigator.userAgent.match(/Opera Mini/i)\n  },\n  Windows: function () {\n    return navigator.userAgent.match(/IEMobile/i) || navigator.userAgent.match(/WPDesktop/i)\n  },\n  Ethereum: function () {\n    // @ts-ignore\n    return window?.ethereum && window?.ethereum.isImToken\n  },\n\n  any: function () {\n    return (\n      IsMobile.Android() ||\n      IsMobile.BlackBerry() ||\n      IsMobile.iOS() ||\n      IsMobile.Opera() ||\n      IsMobile.Windows() ||\n      IsMobile.Ethereum()\n    )\n  },\n}\n\nexport const IsWhichWebView = {\n  any: function () {\n    // @ts-ignore\n    if (window?.ethereum.isImToken) {\n      return 'isImToken'\n    }\n    // @ts-ignore\n    if (window?.ethereum.isMetaMask) {\n      return 'isMetaMask'\n    }\n  },\n}\n\nexport function type(value: any) {\n  var matches = Object.prototype.toString.call(value).match(/^\\[object (\\w+?)\\]$/) || []\n\n  return (matches[1] || 'undefined').toLowerCase()\n}\n"
  },
  {
    "path": "packages/common-resources/static-resources/types.d.ts",
    "content": "/// <reference types=\"@google/model-viewer\" />\n\ndeclare global {\n  interface Window {\n    __ChainIdExtends: any\n    __MapChainId: any\n  }\n}\n"
  },
  {
    "path": "packages/common-resources/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.build.json\",\n  \"compilerOptions\": {\n    \"jsx\": \"react-jsx\",\n    \"noUnusedLocals\": true,\n    \"resolveJsonModule\": true,\n    \"noUnusedParameters\": true,  \n    \"baseUrl\": \"./static-resources/src\",\n    \"rootDir\": \"./static-resources\"\n  },\n  \"include\": [\n    \"./static-resources/src\",\n    \"./static-resources/src/**/*.json\",\n    \"./static-resources/src/*\"\n  ],\n  \"exclude\": [\n    \"node_modules\",\n    \"build\",\n    \"dist\",\n    \"example\",\n    \"rollup.config.js\"\n  ]\n}\n"
  },
  {
    "path": "packages/common-resources/tsconfig.tsbuildinfo",
    "content": "{\"program\":{\"fileNames\":[\"../../node_modules/typescript/lib/lib.es5.d.ts\",\"../../node_modules/typescript/lib/lib.es2015.d.ts\",\"../../node_modules/typescript/lib/lib.es2016.d.ts\",\"../../node_modules/typescript/lib/lib.es2017.d.ts\",\"../../node_modules/typescript/lib/lib.es2018.d.ts\",\"../../node_modules/typescript/lib/lib.es2019.d.ts\",\"../../node_modules/typescript/lib/lib.es2020.d.ts\",\"../../node_modules/typescript/lib/lib.es2021.d.ts\",\"../../node_modules/typescript/lib/lib.es2022.d.ts\",\"../../node_modules/typescript/lib/lib.esnext.d.ts\",\"../../node_modules/typescript/lib/lib.dom.d.ts\",\"../../node_modules/typescript/lib/lib.dom.iterable.d.ts\",\"../../node_modules/typescript/lib/lib.es2015.core.d.ts\",\"../../node_modules/typescript/lib/lib.es2015.collection.d.ts\",\"../../node_modules/typescript/lib/lib.es2015.generator.d.ts\",\"../../node_modules/typescript/lib/lib.es2015.iterable.d.ts\",\"../../node_modules/typescript/lib/lib.es2015.promise.d.ts\",\"../../node_modules/typescript/lib/lib.es2015.proxy.d.ts\",\"../../node_modules/typescript/lib/lib.es2015.reflect.d.ts\",\"../../node_modules/typescript/lib/lib.es2015.symbol.d.ts\",\"../../node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts\",\"../../node_modules/typescript/lib/lib.es2016.array.include.d.ts\",\"../../node_modules/typescript/lib/lib.es2017.object.d.ts\",\"../../node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts\",\"../../node_modules/typescript/lib/lib.es2017.string.d.ts\",\"../../node_modules/typescript/lib/lib.es2017.intl.d.ts\",\"../../node_modules/typescript/lib/lib.es2017.typedarrays.d.ts\",\"../../node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts\",\"../../node_modules/typescript/lib/lib.es2018.asynciterable.d.ts\",\"../../node_modules/typescript/lib/lib.es2018.intl.d.ts\",\"../../node_modules/typescript/lib/lib.es2018.promise.d.ts\",\"../../node_modules/typescript/lib/lib.es2018.regexp.d.ts\",\"../../node_modules/typescript/lib/lib.es2019.array.d.ts\",\"../../node_modules/typescript/lib/lib.es2019.object.d.ts\",\"../../node_modules/typescript/lib/lib.es2019.string.d.ts\",\"../../node_modules/typescript/lib/lib.es2019.symbol.d.ts\",\"../../node_modules/typescript/lib/lib.es2020.bigint.d.ts\",\"../../node_modules/typescript/lib/lib.es2020.promise.d.ts\",\"../../node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts\",\"../../node_modules/typescript/lib/lib.es2020.string.d.ts\",\"../../node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts\",\"../../node_modules/typescript/lib/lib.es2020.intl.d.ts\",\"../../node_modules/typescript/lib/lib.es2021.promise.d.ts\",\"../../node_modules/typescript/lib/lib.es2021.string.d.ts\",\"../../node_modules/typescript/lib/lib.es2021.weakref.d.ts\",\"../../node_modules/typescript/lib/lib.es2021.intl.d.ts\",\"../../node_modules/typescript/lib/lib.es2022.array.d.ts\",\"../../node_modules/typescript/lib/lib.es2022.error.d.ts\",\"../../node_modules/typescript/lib/lib.es2022.object.d.ts\",\"../../node_modules/typescript/lib/lib.es2022.string.d.ts\",\"../../node_modules/typescript/lib/lib.esnext.intl.d.ts\",\"../../node_modules/@types/react/global.d.ts\",\"../../node_modules/csstype/index.d.ts\",\"../../node_modules/@types/prop-types/index.d.ts\",\"../../node_modules/@types/scheduler/tracing.d.ts\",\"../../node_modules/@types/react/index.d.ts\",\"../../node_modules/@types/react/jsx-runtime.d.ts\",\"../../node_modules/i18next/index.d.ts\",\"../../node_modules/react-i18next/ts4.1/index.d.ts\",\"../../node_modules/@loopring-web/loopring-sdk/dist/utils/network_tools.d.ts\",\"../../node_modules/@loopring-web/loopring-sdk/dist/utils/symbol_tools.d.ts\",\"../../node_modules/@types/node/assert.d.ts\",\"../../node_modules/@types/node/globals.d.ts\",\"../../node_modules/@types/node/async_hooks.d.ts\",\"../../node_modules/@types/node/buffer.d.ts\",\"../../node_modules/@types/node/child_process.d.ts\",\"../../node_modules/@types/node/cluster.d.ts\",\"../../node_modules/@types/node/console.d.ts\",\"../../node_modules/@types/node/constants.d.ts\",\"../../node_modules/@types/node/crypto.d.ts\",\"../../node_modules/@types/node/dgram.d.ts\",\"../../node_modules/@types/node/dns.d.ts\",\"../../node_modules/@types/node/domain.d.ts\",\"../../node_modules/@types/node/events.d.ts\",\"../../node_modules/@types/node/fs.d.ts\",\"../../node_modules/@types/node/http.d.ts\",\"../../node_modules/@types/node/http2.d.ts\",\"../../node_modules/@types/node/https.d.ts\",\"../../node_modules/@types/node/inspector.d.ts\",\"../../node_modules/@types/node/module.d.ts\",\"../../node_modules/@types/node/net.d.ts\",\"../../node_modules/@types/node/os.d.ts\",\"../../node_modules/@types/node/path.d.ts\",\"../../node_modules/@types/node/perf_hooks.d.ts\",\"../../node_modules/@types/node/process.d.ts\",\"../../node_modules/@types/node/punycode.d.ts\",\"../../node_modules/@types/node/querystring.d.ts\",\"../../node_modules/@types/node/readline.d.ts\",\"../../node_modules/@types/node/repl.d.ts\",\"../../node_modules/@types/node/stream.d.ts\",\"../../node_modules/@types/node/string_decoder.d.ts\",\"../../node_modules/@types/node/timers.d.ts\",\"../../node_modules/@types/node/tls.d.ts\",\"../../node_modules/@types/node/trace_events.d.ts\",\"../../node_modules/@types/node/tty.d.ts\",\"../../node_modules/querystring/decode.d.ts\",\"../../node_modules/querystring/encode.d.ts\",\"../../node_modules/querystring/index.d.ts\",\"../../node_modules/@types/node/url.d.ts\",\"../../node_modules/@types/node/util.d.ts\",\"../../node_modules/@types/node/v8.d.ts\",\"../../node_modules/@types/node/vm.d.ts\",\"../../node_modules/@types/node/wasi.d.ts\",\"../../node_modules/@types/node/worker_threads.d.ts\",\"../../node_modules/@types/node/zlib.d.ts\",\"../../node_modules/@types/node/globals.global.d.ts\",\"../../node_modules/@types/node/index.d.ts\",\"../../node_modules/@types/bn.js/index.d.ts\",\"../../node_modules/bignumber.js/bignumber.d.ts\",\"../../node_modules/@loopring-web/loopring-sdk/dist/defs/web3_defs.d.ts\",\"../../node_modules/web3-bzz/types/index.d.ts\",\"../../node_modules/web3-core-helpers/types/index.d.ts\",\"../../node_modules/web3-core-method/types/index.d.ts\",\"../../node_modules/web3-core/types/index.d.ts\",\"../../node_modules/web3-core-subscriptions/types/index.d.ts\",\"../../node_modules/web3-utils/types/index.d.ts\",\"../../node_modules/web3-eth-abi/types/index.d.ts\",\"../../node_modules/web3-eth-accounts/types/index.d.ts\",\"../../node_modules/web3-eth-contract/types/index.d.ts\",\"../../node_modules/web3-eth-ens/types/index.d.ts\",\"../../node_modules/web3-eth-iban/types/index.d.ts\",\"../../node_modules/web3-eth-personal/types/index.d.ts\",\"../../node_modules/web3-net/types/index.d.ts\",\"../../node_modules/web3-eth/types/index.d.ts\",\"../../node_modules/web3-shh/types/index.d.ts\",\"../../node_modules/web3/types/index.d.ts\",\"../../node_modules/@loopring-web/loopring-sdk/dist/defs/loopring_enums.d.ts\",\"../../node_modules/@loopring-web/loopring-sdk/dist/defs/error_codes.d.ts\",\"../../node_modules/@loopring-web/loopring-sdk/dist/defs/loopring_constants.d.ts\",\"../../node_modules/axios/index.d.ts\",\"../../node_modules/@loopring-web/loopring-sdk/dist/api/request.d.ts\",\"../../node_modules/@loopring-web/loopring-sdk/dist/api/base_api.d.ts\",\"../../node_modules/@loopring-web/loopring-sdk/dist/api/ws_api.d.ts\",\"../../node_modules/@loopring-web/loopring-sdk/dist/api/exchange_api.d.ts\",\"../../node_modules/@loopring-web/loopring-sdk/dist/api/ammpool_api.d.ts\",\"../../node_modules/@loopring-web/loopring-sdk/dist/api/sign/sign_tools.d.ts\",\"../../node_modules/@loopring-web/loopring-sdk/dist/api/user_api.d.ts\",\"../../node_modules/@loopring-web/loopring-sdk/dist/api/wallet_api.d.ts\",\"../../node_modules/@loopring-web/loopring-sdk/dist/api/whitelisted_user_api.d.ts\",\"../../node_modules/@loopring-web/loopring-sdk/dist/api/contract_api.d.ts\",\"../../node_modules/@loopring-web/loopring-sdk/dist/defs/nft_defs.d.ts\",\"../../node_modules/@loopring-web/loopring-sdk/dist/api/nft_api.d.ts\",\"../../node_modules/@loopring-web/loopring-sdk/dist/api/global_api.d.ts\",\"../../node_modules/@loopring-web/loopring-sdk/dist/api/delegate_api.d.ts\",\"../../node_modules/@loopring-web/loopring-sdk/dist/api/defi_api.d.ts\",\"../../node_modules/@loopring-web/loopring-sdk/dist/api/lucktoken_api.d.ts\",\"../../node_modules/@loopring-web/loopring-sdk/dist/api/contacts_api.d.ts\",\"../../node_modules/@loopring-web/loopring-sdk/dist/api/index.d.ts\",\"../../node_modules/@loopring-web/loopring-sdk/dist/defs/loopring_defs.d.ts\",\"../../node_modules/@loopring-web/loopring-sdk/dist/defs/account_defs.d.ts\",\"../../node_modules/@loopring-web/loopring-sdk/dist/defs/ws_defs.d.ts\",\"../../node_modules/@loopring-web/loopring-sdk/dist/defs/url_defs.d.ts\",\"../../node_modules/@loopring-web/loopring-sdk/dist/defs/index.d.ts\",\"../../node_modules/@loopring-web/loopring-sdk/dist/utils/formatter.d.ts\",\"../../node_modules/@loopring-web/loopring-sdk/dist/utils/swap_calc_utils.d.ts\",\"../../node_modules/@loopring-web/loopring-sdk/dist/utils/index.d.ts\",\"../../node_modules/@loopring-web/loopring-sdk/dist/index.d.ts\",\"../../node_modules/@mui/types/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/system/createtheme/createbreakpoints.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/system/createtheme/shape.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/system/createtheme/createspacing.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/system/createtheme/createtheme.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/system/createtheme/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/system/stylefunctionsx/standardcssproperties.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/system/stylefunctionsx/aliasescssproperties.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/system/stylefunctionsx/overwritecssproperties.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/system/stylefunctionsx/stylefunctionsx.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/system/stylefunctionsx/extendsxprop.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/system/stylefunctionsx/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/system/box/box.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/system/box/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/private-theming/defaulttheme/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/private-theming/themeprovider/themeprovider.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/private-theming/themeprovider/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/private-theming/usetheme/usetheme.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/private-theming/usetheme/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/private-theming/index.d.ts\",\"../../node_modules/@emotion/utils/types/index.d.ts\",\"../../node_modules/@emotion/cache/types/index.d.ts\",\"../../node_modules/@emotion/serialize/types/index.d.ts\",\"../../node_modules/@emotion/react/types/jsx-namespace.d.ts\",\"../../node_modules/@emotion/react/types/helper.d.ts\",\"../../node_modules/@emotion/react/types/theming.d.ts\",\"../../node_modules/@emotion/react/types/index.d.ts\",\"../../node_modules/@emotion/styled/types/base.d.ts\",\"../../node_modules/@emotion/styled/types/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/styled-engine/styledengineprovider/styledengineprovider.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/styled-engine/styledengineprovider/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/styled-engine/globalstyles/globalstyles.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/styled-engine/globalstyles/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/styled-engine/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/system/style.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/system/spacing.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/system/sx/sx.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/system/sx/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/system/createbox.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/system/createstyled.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/system/styled.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/system/usethemeprops/usethemeprops.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/system/usethemeprops/getthemeprops.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/system/usethemeprops/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/system/usetheme.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/system/usethemewithoutdefault.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/system/colormanipulator.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/system/themeprovider/themeprovider.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/system/themeprovider/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/system/cssvars/getinitcolorschemescript.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/system/cssvars/usecurrentcolorscheme.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/system/cssvars/createcssvarsprovider.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/system/cssvars/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/system/cssvars/creategetcssvar.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/system/index.d.ts\",\"../../node_modules/@mui/material/styles/createmixins.d.ts\",\"../../node_modules/@mui/material/styles/createpalette.d.ts\",\"../../node_modules/@mui/material/styles/createtypography.d.ts\",\"../../node_modules/@mui/material/styles/shadows.d.ts\",\"../../node_modules/@mui/material/styles/createtransitions.d.ts\",\"../../node_modules/@mui/material/styles/zindex.d.ts\",\"../../node_modules/@mui/material/overridablecomponent.d.ts\",\"../../node_modules/@mui/material/paper/paperclasses.d.ts\",\"../../node_modules/@mui/material/paper/paper.d.ts\",\"../../node_modules/@mui/material/paper/index.d.ts\",\"../../node_modules/@mui/material/alert/alertclasses.d.ts\",\"../../node_modules/@mui/material/alert/alert.d.ts\",\"../../node_modules/@mui/material/alert/index.d.ts\",\"../../node_modules/@mui/material/alerttitle/alerttitleclasses.d.ts\",\"../../node_modules/@mui/material/alerttitle/alerttitle.d.ts\",\"../../node_modules/@mui/material/alerttitle/index.d.ts\",\"../../node_modules/@mui/material/appbar/appbarclasses.d.ts\",\"../../node_modules/@mui/material/appbar/appbar.d.ts\",\"../../node_modules/@mui/material/appbar/index.d.ts\",\"../../node_modules/@mui/material/chip/chipclasses.d.ts\",\"../../node_modules/@mui/material/chip/chip.d.ts\",\"../../node_modules/@mui/material/chip/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@popperjs/core/lib/enums.d.ts\",\"../../node_modules/@mui/material/node_modules/@popperjs/core/lib/modifiers/popperoffsets.d.ts\",\"../../node_modules/@mui/material/node_modules/@popperjs/core/lib/modifiers/flip.d.ts\",\"../../node_modules/@mui/material/node_modules/@popperjs/core/lib/modifiers/hide.d.ts\",\"../../node_modules/@mui/material/node_modules/@popperjs/core/lib/modifiers/offset.d.ts\",\"../../node_modules/@mui/material/node_modules/@popperjs/core/lib/modifiers/eventlisteners.d.ts\",\"../../node_modules/@mui/material/node_modules/@popperjs/core/lib/modifiers/computestyles.d.ts\",\"../../node_modules/@mui/material/node_modules/@popperjs/core/lib/modifiers/arrow.d.ts\",\"../../node_modules/@mui/material/node_modules/@popperjs/core/lib/modifiers/preventoverflow.d.ts\",\"../../node_modules/@mui/material/node_modules/@popperjs/core/lib/modifiers/applystyles.d.ts\",\"../../node_modules/@mui/material/node_modules/@popperjs/core/lib/types.d.ts\",\"../../node_modules/@mui/material/node_modules/@popperjs/core/lib/modifiers/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@popperjs/core/lib/utils/detectoverflow.d.ts\",\"../../node_modules/@mui/material/node_modules/@popperjs/core/lib/createpopper.d.ts\",\"../../node_modules/@mui/material/node_modules/@popperjs/core/lib/popper-lite.d.ts\",\"../../node_modules/@mui/material/node_modules/@popperjs/core/lib/popper.d.ts\",\"../../node_modules/@mui/material/node_modules/@popperjs/core/lib/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@popperjs/core/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/portal/portal.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/portal/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/popperunstyled/popperunstyled.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/popperunstyled/index.d.ts\",\"../../node_modules/@mui/material/popper/popper.d.ts\",\"../../node_modules/@mui/material/popper/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/utils/appendownerstate.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/utils/arearraysequal.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/utils/types.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/utils/extracteventhandlers.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/utils/ishostcomponent.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/utils/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/autocompleteunstyled/useautocomplete.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/autocompleteunstyled/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/badgeunstyled/badgeunstyledprops.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/badgeunstyled/badgeunstyled.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/badgeunstyled/usebadge.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/badgeunstyled/badgeunstyledclasses.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/badgeunstyled/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/buttonunstyled/usebutton.types.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/buttonunstyled/buttonunstyled.types.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/buttonunstyled/buttonunstyled.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/buttonunstyled/buttonunstyledclasses.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/buttonunstyled/usebutton.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/buttonunstyled/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/clickawaylistener/clickawaylistener.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/clickawaylistener/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/composeclasses/composeclasses.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/composeclasses/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/generateutilityclass/generateutilityclass.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/generateutilityclass/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/generateutilityclasses/generateutilityclasses.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/generateutilityclasses/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/formcontrolunstyled/formcontrolunstyled.types.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/formcontrolunstyled/formcontrolunstyled.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/formcontrolunstyled/formcontrolunstyledcontext.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/formcontrolunstyled/formcontrolunstyledclasses.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/formcontrolunstyled/useformcontrolunstyledcontext.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/formcontrolunstyled/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/inputunstyled/inputunstyledprops.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/inputunstyled/inputunstyled.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/inputunstyled/useinput.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/inputunstyled/inputunstyledclasses.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/inputunstyled/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/listboxunstyled/uselistbox.types.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/listboxunstyled/uselistbox.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/listboxunstyled/defaultlistboxreducer.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/listboxunstyled/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/menuunstyled/usemenu.types.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/menuunstyled/menuunstyled.types.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/menuunstyled/menuunstyled.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/menuunstyled/menuunstyledcontext.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/menuunstyled/menuunstyledclasses.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/menuunstyled/usemenu.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/menuunstyled/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/menuitemunstyled/menuitemunstyled.types.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/menuitemunstyled/menuitemunstyled.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/menuitemunstyled/menuitemunstyledclasses.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/menuitemunstyled/usemenuitem.types.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/menuitemunstyled/usemenuitem.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/menuitemunstyled/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/modalunstyled/modalunstyledclasses.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/modalunstyled/modalunstyled.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/modalunstyled/modalmanager.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/modalunstyled/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/selectunstyled/useselect.types.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/selectunstyled/selectunstyled.types.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/selectunstyled/selectunstyled.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/selectunstyled/selectunstyledcontext.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/selectunstyled/selectunstyledclasses.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/selectunstyled/useselect.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/selectunstyled/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/multiselectunstyled/multiselectunstyled.types.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/multiselectunstyled/multiselectunstyled.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/multiselectunstyled/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/nossr/nossr.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/nossr/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/optiongroupunstyled/optiongroupunstyledprops.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/optiongroupunstyled/optiongroupunstyled.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/optiongroupunstyled/optiongroupunstyledclasses.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/optiongroupunstyled/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/optionunstyled/optionunstyledprops.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/optionunstyled/optionunstyled.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/optionunstyled/optionunstyledclasses.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/optionunstyled/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/sliderunstyled/sliderunstyledclasses.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/sliderunstyled/slidervaluelabelunstyled.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/sliderunstyled/sliderunstyledprops.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/sliderunstyled/sliderunstyled.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/sliderunstyled/useslider.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/sliderunstyled/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/switchunstyled/useswitch.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/switchunstyled/switchunstyled.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/switchunstyled/switchunstyledclasses.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/switchunstyled/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/tabpanelunstyled/tabpanelunstyledprops.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/tabpanelunstyled/tabpanelunstyled.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/tabpanelunstyled/tabpanelunstyledclasses.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/tabpanelunstyled/usetabpanel.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/tabpanelunstyled/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/tabslistunstyled/tabslistunstyledprops.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/tabslistunstyled/tabslistunstyled.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/tabslistunstyled/tabslistunstyledclasses.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/tabslistunstyled/usetabslist.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/tabslistunstyled/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/tabsunstyled/tabsunstyledprops.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/tabsunstyled/tabsunstyled.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/tabsunstyled/tabscontext.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/tabsunstyled/tabsunstyledclasses.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/tabsunstyled/usetabs.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/tabsunstyled/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/tabunstyled/tabunstyledprops.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/tabunstyled/tabunstyled.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/tabunstyled/tabunstyledclasses.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/tabunstyled/usetab.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/tabunstyled/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/textareaautosize/textareaautosize.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/textareaautosize/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/trapfocus/trapfocus.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/trapfocus/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/index.d.ts\",\"../../node_modules/@mui/material/autocomplete/autocompleteclasses.d.ts\",\"../../node_modules/@mui/material/autocomplete/autocomplete.d.ts\",\"../../node_modules/@mui/material/autocomplete/index.d.ts\",\"../../node_modules/@mui/material/avatar/avatarclasses.d.ts\",\"../../node_modules/@mui/material/avatar/avatar.d.ts\",\"../../node_modules/@mui/material/avatar/index.d.ts\",\"../../node_modules/@mui/material/avatargroup/avatargroupclasses.d.ts\",\"../../node_modules/@mui/material/avatargroup/avatargroup.d.ts\",\"../../node_modules/@mui/material/avatargroup/index.d.ts\",\"../../node_modules/@types/react-transition-group/transition.d.ts\",\"../../node_modules/@mui/material/transitions/transition.d.ts\",\"../../node_modules/@mui/material/fade/fade.d.ts\",\"../../node_modules/@mui/material/fade/index.d.ts\",\"../../node_modules/@mui/material/backdrop/backdropclasses.d.ts\",\"../../node_modules/@mui/material/backdrop/backdrop.d.ts\",\"../../node_modules/@mui/material/backdrop/index.d.ts\",\"../../node_modules/@mui/material/badge/badgeclasses.d.ts\",\"../../node_modules/@mui/material/badge/badge.d.ts\",\"../../node_modules/@mui/material/badge/index.d.ts\",\"../../node_modules/@mui/material/buttonbase/touchrippleclasses.d.ts\",\"../../node_modules/@mui/material/buttonbase/touchripple.d.ts\",\"../../node_modules/@mui/material/buttonbase/buttonbaseclasses.d.ts\",\"../../node_modules/@mui/material/buttonbase/buttonbase.d.ts\",\"../../node_modules/@mui/material/buttonbase/index.d.ts\",\"../../node_modules/@mui/material/bottomnavigationaction/bottomnavigationactionclasses.d.ts\",\"../../node_modules/@mui/material/bottomnavigationaction/bottomnavigationaction.d.ts\",\"../../node_modules/@mui/material/bottomnavigationaction/index.d.ts\",\"../../node_modules/@mui/material/bottomnavigation/bottomnavigationclasses.d.ts\",\"../../node_modules/@mui/material/bottomnavigation/bottomnavigation.d.ts\",\"../../node_modules/@mui/material/bottomnavigation/index.d.ts\",\"../../node_modules/@mui/material/breadcrumbs/breadcrumbsclasses.d.ts\",\"../../node_modules/@mui/material/breadcrumbs/breadcrumbs.d.ts\",\"../../node_modules/@mui/material/breadcrumbs/index.d.ts\",\"../../node_modules/@mui/material/buttongroup/buttongroupclasses.d.ts\",\"../../node_modules/@mui/material/buttongroup/buttongroup.d.ts\",\"../../node_modules/@mui/material/buttongroup/index.d.ts\",\"../../node_modules/@mui/material/button/buttonclasses.d.ts\",\"../../node_modules/@mui/material/button/button.d.ts\",\"../../node_modules/@mui/material/button/index.d.ts\",\"../../node_modules/@mui/material/cardactionarea/cardactionareaclasses.d.ts\",\"../../node_modules/@mui/material/cardactionarea/cardactionarea.d.ts\",\"../../node_modules/@mui/material/cardactionarea/index.d.ts\",\"../../node_modules/@mui/material/cardactions/cardactionsclasses.d.ts\",\"../../node_modules/@mui/material/cardactions/cardactions.d.ts\",\"../../node_modules/@mui/material/cardactions/index.d.ts\",\"../../node_modules/@mui/material/cardcontent/cardcontentclasses.d.ts\",\"../../node_modules/@mui/material/cardcontent/cardcontent.d.ts\",\"../../node_modules/@mui/material/cardcontent/index.d.ts\",\"../../node_modules/@mui/material/typography/typographyclasses.d.ts\",\"../../node_modules/@mui/material/typography/typography.d.ts\",\"../../node_modules/@mui/material/typography/index.d.ts\",\"../../node_modules/@mui/material/cardheader/cardheaderclasses.d.ts\",\"../../node_modules/@mui/material/cardheader/cardheader.d.ts\",\"../../node_modules/@mui/material/cardheader/index.d.ts\",\"../../node_modules/@mui/material/cardmedia/cardmediaclasses.d.ts\",\"../../node_modules/@mui/material/cardmedia/cardmedia.d.ts\",\"../../node_modules/@mui/material/cardmedia/index.d.ts\",\"../../node_modules/@mui/material/card/cardclasses.d.ts\",\"../../node_modules/@mui/material/card/card.d.ts\",\"../../node_modules/@mui/material/card/index.d.ts\",\"../../node_modules/@mui/material/internal/switchbaseclasses.d.ts\",\"../../node_modules/@mui/material/internal/switchbase.d.ts\",\"../../node_modules/@mui/material/checkbox/checkboxclasses.d.ts\",\"../../node_modules/@mui/material/checkbox/checkbox.d.ts\",\"../../node_modules/@mui/material/checkbox/index.d.ts\",\"../../node_modules/@mui/material/circularprogress/circularprogressclasses.d.ts\",\"../../node_modules/@mui/material/circularprogress/circularprogress.d.ts\",\"../../node_modules/@mui/material/circularprogress/index.d.ts\",\"../../node_modules/@mui/material/collapse/collapseclasses.d.ts\",\"../../node_modules/@mui/material/collapse/collapse.d.ts\",\"../../node_modules/@mui/material/collapse/index.d.ts\",\"../../node_modules/@mui/material/container/containerclasses.d.ts\",\"../../node_modules/@mui/material/container/container.d.ts\",\"../../node_modules/@mui/material/container/index.d.ts\",\"../../node_modules/@mui/material/cssbaseline/cssbaseline.d.ts\",\"../../node_modules/@mui/material/cssbaseline/index.d.ts\",\"../../node_modules/@mui/material/dialogactions/dialogactionsclasses.d.ts\",\"../../node_modules/@mui/material/dialogactions/dialogactions.d.ts\",\"../../node_modules/@mui/material/dialogactions/index.d.ts\",\"../../node_modules/@mui/material/dialogcontent/dialogcontentclasses.d.ts\",\"../../node_modules/@mui/material/dialogcontent/dialogcontent.d.ts\",\"../../node_modules/@mui/material/dialogcontent/index.d.ts\",\"../../node_modules/@mui/material/dialogcontenttext/dialogcontenttextclasses.d.ts\",\"../../node_modules/@mui/material/dialogcontenttext/dialogcontenttext.d.ts\",\"../../node_modules/@mui/material/dialogcontenttext/index.d.ts\",\"../../node_modules/@mui/material/modal/modal.d.ts\",\"../../node_modules/@mui/material/modal/index.d.ts\",\"../../node_modules/@mui/material/dialog/dialogclasses.d.ts\",\"../../node_modules/@mui/material/dialog/dialog.d.ts\",\"../../node_modules/@mui/material/dialog/index.d.ts\",\"../../node_modules/@mui/material/dialogtitle/dialogtitleclasses.d.ts\",\"../../node_modules/@mui/material/dialogtitle/dialogtitle.d.ts\",\"../../node_modules/@mui/material/dialogtitle/index.d.ts\",\"../../node_modules/@mui/material/divider/dividerclasses.d.ts\",\"../../node_modules/@mui/material/divider/divider.d.ts\",\"../../node_modules/@mui/material/divider/index.d.ts\",\"../../node_modules/@mui/material/slide/slide.d.ts\",\"../../node_modules/@mui/material/slide/index.d.ts\",\"../../node_modules/@mui/material/drawer/drawerclasses.d.ts\",\"../../node_modules/@mui/material/drawer/drawer.d.ts\",\"../../node_modules/@mui/material/drawer/index.d.ts\",\"../../node_modules/@mui/material/accordionactions/accordionactionsclasses.d.ts\",\"../../node_modules/@mui/material/accordionactions/accordionactions.d.ts\",\"../../node_modules/@mui/material/accordionactions/index.d.ts\",\"../../node_modules/@mui/material/accordiondetails/accordiondetailsclasses.d.ts\",\"../../node_modules/@mui/material/accordiondetails/accordiondetails.d.ts\",\"../../node_modules/@mui/material/accordiondetails/index.d.ts\",\"../../node_modules/@mui/material/accordion/accordionclasses.d.ts\",\"../../node_modules/@mui/material/accordion/accordion.d.ts\",\"../../node_modules/@mui/material/accordion/index.d.ts\",\"../../node_modules/@mui/material/accordionsummary/accordionsummaryclasses.d.ts\",\"../../node_modules/@mui/material/accordionsummary/accordionsummary.d.ts\",\"../../node_modules/@mui/material/accordionsummary/index.d.ts\",\"../../node_modules/@mui/material/fab/fabclasses.d.ts\",\"../../node_modules/@mui/material/fab/fab.d.ts\",\"../../node_modules/@mui/material/fab/index.d.ts\",\"../../node_modules/@mui/material/inputbase/inputbaseclasses.d.ts\",\"../../node_modules/@mui/material/inputbase/inputbase.d.ts\",\"../../node_modules/@mui/material/inputbase/index.d.ts\",\"../../node_modules/@mui/material/filledinput/filledinputclasses.d.ts\",\"../../node_modules/@mui/material/filledinput/filledinput.d.ts\",\"../../node_modules/@mui/material/filledinput/index.d.ts\",\"../../node_modules/@mui/material/formcontrollabel/formcontrollabelclasses.d.ts\",\"../../node_modules/@mui/material/formcontrollabel/formcontrollabel.d.ts\",\"../../node_modules/@mui/material/formcontrollabel/index.d.ts\",\"../../node_modules/@mui/material/formcontrol/formcontrolclasses.d.ts\",\"../../node_modules/@mui/material/formcontrol/formcontrol.d.ts\",\"../../node_modules/@mui/material/formcontrol/useformcontrol.d.ts\",\"../../node_modules/@mui/material/formcontrol/index.d.ts\",\"../../node_modules/@mui/material/formgroup/formgroupclasses.d.ts\",\"../../node_modules/@mui/material/formgroup/formgroup.d.ts\",\"../../node_modules/@mui/material/formgroup/index.d.ts\",\"../../node_modules/@mui/material/formhelpertext/formhelpertextclasses.d.ts\",\"../../node_modules/@mui/material/formhelpertext/formhelpertext.d.ts\",\"../../node_modules/@mui/material/formhelpertext/index.d.ts\",\"../../node_modules/@mui/material/formlabel/formlabelclasses.d.ts\",\"../../node_modules/@mui/material/formlabel/formlabel.d.ts\",\"../../node_modules/@mui/material/formlabel/index.d.ts\",\"../../node_modules/@mui/material/grid/gridclasses.d.ts\",\"../../node_modules/@mui/material/grid/grid.d.ts\",\"../../node_modules/@mui/material/grid/index.d.ts\",\"../../node_modules/@mui/material/iconbutton/iconbuttonclasses.d.ts\",\"../../node_modules/@mui/material/iconbutton/iconbutton.d.ts\",\"../../node_modules/@mui/material/iconbutton/index.d.ts\",\"../../node_modules/@mui/material/icon/iconclasses.d.ts\",\"../../node_modules/@mui/material/icon/icon.d.ts\",\"../../node_modules/@mui/material/icon/index.d.ts\",\"../../node_modules/@mui/material/imagelist/imagelistclasses.d.ts\",\"../../node_modules/@mui/material/imagelist/imagelist.d.ts\",\"../../node_modules/@mui/material/imagelist/index.d.ts\",\"../../node_modules/@mui/material/imagelistitembar/imagelistitembarclasses.d.ts\",\"../../node_modules/@mui/material/imagelistitembar/imagelistitembar.d.ts\",\"../../node_modules/@mui/material/imagelistitembar/index.d.ts\",\"../../node_modules/@mui/material/imagelistitem/imagelistitemclasses.d.ts\",\"../../node_modules/@mui/material/imagelistitem/imagelistitem.d.ts\",\"../../node_modules/@mui/material/imagelistitem/index.d.ts\",\"../../node_modules/@mui/material/inputadornment/inputadornmentclasses.d.ts\",\"../../node_modules/@mui/material/inputadornment/inputadornment.d.ts\",\"../../node_modules/@mui/material/inputadornment/index.d.ts\",\"../../node_modules/@mui/material/inputlabel/inputlabelclasses.d.ts\",\"../../node_modules/@mui/material/inputlabel/inputlabel.d.ts\",\"../../node_modules/@mui/material/inputlabel/index.d.ts\",\"../../node_modules/@mui/material/input/inputclasses.d.ts\",\"../../node_modules/@mui/material/input/input.d.ts\",\"../../node_modules/@mui/material/input/index.d.ts\",\"../../node_modules/@mui/material/linearprogress/linearprogressclasses.d.ts\",\"../../node_modules/@mui/material/linearprogress/linearprogress.d.ts\",\"../../node_modules/@mui/material/linearprogress/index.d.ts\",\"../../node_modules/@mui/material/link/linkclasses.d.ts\",\"../../node_modules/@mui/material/link/link.d.ts\",\"../../node_modules/@mui/material/link/index.d.ts\",\"../../node_modules/@mui/material/listitemavatar/listitemavatarclasses.d.ts\",\"../../node_modules/@mui/material/listitemavatar/listitemavatar.d.ts\",\"../../node_modules/@mui/material/listitemavatar/index.d.ts\",\"../../node_modules/@mui/material/listitemicon/listitemiconclasses.d.ts\",\"../../node_modules/@mui/material/listitemicon/listitemicon.d.ts\",\"../../node_modules/@mui/material/listitemicon/index.d.ts\",\"../../node_modules/@mui/material/listitem/listitemclasses.d.ts\",\"../../node_modules/@mui/material/listitem/listitem.d.ts\",\"../../node_modules/@mui/material/listitem/index.d.ts\",\"../../node_modules/@mui/material/listitembutton/listitembuttonclasses.d.ts\",\"../../node_modules/@mui/material/listitembutton/listitembutton.d.ts\",\"../../node_modules/@mui/material/listitembutton/index.d.ts\",\"../../node_modules/@mui/material/listitemsecondaryaction/listitemsecondaryactionclasses.d.ts\",\"../../node_modules/@mui/material/listitemsecondaryaction/listitemsecondaryaction.d.ts\",\"../../node_modules/@mui/material/listitemsecondaryaction/index.d.ts\",\"../../node_modules/@mui/material/listitemtext/listitemtextclasses.d.ts\",\"../../node_modules/@mui/material/listitemtext/listitemtext.d.ts\",\"../../node_modules/@mui/material/listitemtext/index.d.ts\",\"../../node_modules/@mui/material/list/listclasses.d.ts\",\"../../node_modules/@mui/material/list/list.d.ts\",\"../../node_modules/@mui/material/list/index.d.ts\",\"../../node_modules/@mui/material/listsubheader/listsubheaderclasses.d.ts\",\"../../node_modules/@mui/material/listsubheader/listsubheader.d.ts\",\"../../node_modules/@mui/material/listsubheader/index.d.ts\",\"../../node_modules/@mui/material/menuitem/menuitemclasses.d.ts\",\"../../node_modules/@mui/material/menuitem/menuitem.d.ts\",\"../../node_modules/@mui/material/menuitem/index.d.ts\",\"../../node_modules/@mui/material/menulist/menulist.d.ts\",\"../../node_modules/@mui/material/menulist/index.d.ts\",\"../../node_modules/@mui/material/popover/popoverclasses.d.ts\",\"../../node_modules/@mui/material/popover/popover.d.ts\",\"../../node_modules/@mui/material/popover/index.d.ts\",\"../../node_modules/@mui/material/menu/menuclasses.d.ts\",\"../../node_modules/@mui/material/menu/menu.d.ts\",\"../../node_modules/@mui/material/menu/index.d.ts\",\"../../node_modules/@mui/material/mobilestepper/mobilestepperclasses.d.ts\",\"../../node_modules/@mui/material/mobilestepper/mobilestepper.d.ts\",\"../../node_modules/@mui/material/mobilestepper/index.d.ts\",\"../../node_modules/@mui/material/nativeselect/nativeselectinput.d.ts\",\"../../node_modules/@mui/material/nativeselect/nativeselectclasses.d.ts\",\"../../node_modules/@mui/material/nativeselect/nativeselect.d.ts\",\"../../node_modules/@mui/material/nativeselect/index.d.ts\",\"../../node_modules/@mui/material/usemediaquery/usemediaquery.d.ts\",\"../../node_modules/@mui/material/usemediaquery/index.d.ts\",\"../../node_modules/@mui/material/outlinedinput/outlinedinputclasses.d.ts\",\"../../node_modules/@mui/material/outlinedinput/outlinedinput.d.ts\",\"../../node_modules/@mui/material/outlinedinput/index.d.ts\",\"../../node_modules/@mui/material/usepagination/usepagination.d.ts\",\"../../node_modules/@mui/material/pagination/paginationclasses.d.ts\",\"../../node_modules/@mui/material/pagination/pagination.d.ts\",\"../../node_modules/@mui/material/pagination/index.d.ts\",\"../../node_modules/@mui/material/paginationitem/paginationitemclasses.d.ts\",\"../../node_modules/@mui/material/paginationitem/paginationitem.d.ts\",\"../../node_modules/@mui/material/paginationitem/index.d.ts\",\"../../node_modules/@mui/material/radiogroup/radiogroup.d.ts\",\"../../node_modules/@mui/material/radiogroup/radiogroupcontext.d.ts\",\"../../node_modules/@mui/material/radiogroup/useradiogroup.d.ts\",\"../../node_modules/@mui/material/radiogroup/index.d.ts\",\"../../node_modules/@mui/material/radio/radioclasses.d.ts\",\"../../node_modules/@mui/material/radio/radio.d.ts\",\"../../node_modules/@mui/material/radio/index.d.ts\",\"../../node_modules/@mui/material/rating/ratingclasses.d.ts\",\"../../node_modules/@mui/material/rating/rating.d.ts\",\"../../node_modules/@mui/material/rating/index.d.ts\",\"../../node_modules/@mui/material/scopedcssbaseline/scopedcssbaselineclasses.d.ts\",\"../../node_modules/@mui/material/scopedcssbaseline/scopedcssbaseline.d.ts\",\"../../node_modules/@mui/material/scopedcssbaseline/index.d.ts\",\"../../node_modules/@mui/material/select/selectinput.d.ts\",\"../../node_modules/@mui/material/select/selectclasses.d.ts\",\"../../node_modules/@mui/material/select/select.d.ts\",\"../../node_modules/@mui/material/select/index.d.ts\",\"../../node_modules/@mui/material/skeleton/skeletonclasses.d.ts\",\"../../node_modules/@mui/material/skeleton/skeleton.d.ts\",\"../../node_modules/@mui/material/skeleton/index.d.ts\",\"../../node_modules/@mui/material/slider/slider.d.ts\",\"../../node_modules/@mui/material/slider/index.d.ts\",\"../../node_modules/@mui/material/snackbarcontent/snackbarcontentclasses.d.ts\",\"../../node_modules/@mui/material/snackbarcontent/snackbarcontent.d.ts\",\"../../node_modules/@mui/material/snackbarcontent/index.d.ts\",\"../../node_modules/@mui/material/snackbar/snackbarclasses.d.ts\",\"../../node_modules/@mui/material/snackbar/snackbar.d.ts\",\"../../node_modules/@mui/material/snackbar/index.d.ts\",\"../../node_modules/@mui/material/transitions/index.d.ts\",\"../../node_modules/@mui/material/speeddial/speeddialclasses.d.ts\",\"../../node_modules/@mui/material/speeddial/speeddial.d.ts\",\"../../node_modules/@mui/material/speeddial/index.d.ts\",\"../../node_modules/@mui/material/tooltip/tooltipclasses.d.ts\",\"../../node_modules/@mui/material/tooltip/tooltip.d.ts\",\"../../node_modules/@mui/material/tooltip/index.d.ts\",\"../../node_modules/@mui/material/speeddialaction/speeddialactionclasses.d.ts\",\"../../node_modules/@mui/material/speeddialaction/speeddialaction.d.ts\",\"../../node_modules/@mui/material/speeddialaction/index.d.ts\",\"../../node_modules/@mui/material/speeddialicon/speeddialiconclasses.d.ts\",\"../../node_modules/@mui/material/speeddialicon/speeddialicon.d.ts\",\"../../node_modules/@mui/material/speeddialicon/index.d.ts\",\"../../node_modules/@mui/material/stack/stack.d.ts\",\"../../node_modules/@mui/material/stack/index.d.ts\",\"../../node_modules/@mui/material/stepbutton/stepbuttonclasses.d.ts\",\"../../node_modules/@mui/material/stepbutton/stepbutton.d.ts\",\"../../node_modules/@mui/material/stepbutton/index.d.ts\",\"../../node_modules/@mui/material/stepconnector/stepconnectorclasses.d.ts\",\"../../node_modules/@mui/material/stepconnector/stepconnector.d.ts\",\"../../node_modules/@mui/material/stepconnector/index.d.ts\",\"../../node_modules/@mui/material/stepcontent/stepcontentclasses.d.ts\",\"../../node_modules/@mui/material/stepcontent/stepcontent.d.ts\",\"../../node_modules/@mui/material/stepcontent/index.d.ts\",\"../../node_modules/@mui/material/stepicon/stepiconclasses.d.ts\",\"../../node_modules/@mui/material/stepicon/stepicon.d.ts\",\"../../node_modules/@mui/material/stepicon/index.d.ts\",\"../../node_modules/@mui/material/steplabel/steplabelclasses.d.ts\",\"../../node_modules/@mui/material/steplabel/steplabel.d.ts\",\"../../node_modules/@mui/material/steplabel/index.d.ts\",\"../../node_modules/@mui/material/stepper/stepperclasses.d.ts\",\"../../node_modules/@mui/material/stepper/stepper.d.ts\",\"../../node_modules/@mui/material/stepper/index.d.ts\",\"../../node_modules/@mui/material/step/stepclasses.d.ts\",\"../../node_modules/@mui/material/step/step.d.ts\",\"../../node_modules/@mui/material/step/stepcontext.d.ts\",\"../../node_modules/@mui/material/step/index.d.ts\",\"../../node_modules/@mui/material/svgicon/svgiconclasses.d.ts\",\"../../node_modules/@mui/material/svgicon/svgicon.d.ts\",\"../../node_modules/@mui/material/svgicon/index.d.ts\",\"../../node_modules/@mui/material/swipeabledrawer/swipeabledrawer.d.ts\",\"../../node_modules/@mui/material/swipeabledrawer/index.d.ts\",\"../../node_modules/@mui/material/switch/switchclasses.d.ts\",\"../../node_modules/@mui/material/switch/switch.d.ts\",\"../../node_modules/@mui/material/switch/index.d.ts\",\"../../node_modules/@mui/material/tablebody/tablebodyclasses.d.ts\",\"../../node_modules/@mui/material/tablebody/tablebody.d.ts\",\"../../node_modules/@mui/material/tablebody/index.d.ts\",\"../../node_modules/@mui/material/tablecell/tablecellclasses.d.ts\",\"../../node_modules/@mui/material/tablecell/tablecell.d.ts\",\"../../node_modules/@mui/material/tablecell/index.d.ts\",\"../../node_modules/@mui/material/tablecontainer/tablecontainerclasses.d.ts\",\"../../node_modules/@mui/material/tablecontainer/tablecontainer.d.ts\",\"../../node_modules/@mui/material/tablecontainer/index.d.ts\",\"../../node_modules/@mui/material/tablehead/tableheadclasses.d.ts\",\"../../node_modules/@mui/material/tablehead/tablehead.d.ts\",\"../../node_modules/@mui/material/tablehead/index.d.ts\",\"../../node_modules/@mui/material/tablepagination/tablepaginationactions.d.ts\",\"../../node_modules/@mui/material/tablepagination/tablepaginationclasses.d.ts\",\"../../node_modules/@mui/material/tablepagination/tablepagination.d.ts\",\"../../node_modules/@mui/material/tablepagination/index.d.ts\",\"../../node_modules/@mui/material/table/tableclasses.d.ts\",\"../../node_modules/@mui/material/table/table.d.ts\",\"../../node_modules/@mui/material/table/index.d.ts\",\"../../node_modules/@mui/material/tablerow/tablerowclasses.d.ts\",\"../../node_modules/@mui/material/tablerow/tablerow.d.ts\",\"../../node_modules/@mui/material/tablerow/index.d.ts\",\"../../node_modules/@mui/material/tablesortlabel/tablesortlabelclasses.d.ts\",\"../../node_modules/@mui/material/tablesortlabel/tablesortlabel.d.ts\",\"../../node_modules/@mui/material/tablesortlabel/index.d.ts\",\"../../node_modules/@mui/material/tablefooter/tablefooterclasses.d.ts\",\"../../node_modules/@mui/material/tablefooter/tablefooter.d.ts\",\"../../node_modules/@mui/material/tablefooter/index.d.ts\",\"../../node_modules/@mui/material/tab/tabclasses.d.ts\",\"../../node_modules/@mui/material/tab/tab.d.ts\",\"../../node_modules/@mui/material/tab/index.d.ts\",\"../../node_modules/@mui/material/tabscrollbutton/tabscrollbuttonclasses.d.ts\",\"../../node_modules/@mui/material/tabscrollbutton/tabscrollbutton.d.ts\",\"../../node_modules/@mui/material/tabscrollbutton/index.d.ts\",\"../../node_modules/@mui/material/tabs/tabsclasses.d.ts\",\"../../node_modules/@mui/material/tabs/tabs.d.ts\",\"../../node_modules/@mui/material/tabs/index.d.ts\",\"../../node_modules/@mui/material/textfield/textfieldclasses.d.ts\",\"../../node_modules/@mui/material/textfield/textfield.d.ts\",\"../../node_modules/@mui/material/textfield/index.d.ts\",\"../../node_modules/@mui/material/togglebutton/togglebuttonclasses.d.ts\",\"../../node_modules/@mui/material/togglebutton/togglebutton.d.ts\",\"../../node_modules/@mui/material/togglebutton/index.d.ts\",\"../../node_modules/@mui/material/togglebuttongroup/togglebuttongroupclasses.d.ts\",\"../../node_modules/@mui/material/togglebuttongroup/togglebuttongroup.d.ts\",\"../../node_modules/@mui/material/togglebuttongroup/index.d.ts\",\"../../node_modules/@mui/material/toolbar/toolbarclasses.d.ts\",\"../../node_modules/@mui/material/toolbar/toolbar.d.ts\",\"../../node_modules/@mui/material/toolbar/index.d.ts\",\"../../node_modules/@mui/material/styles/props.d.ts\",\"../../node_modules/@mui/material/styles/overrides.d.ts\",\"../../node_modules/@mui/material/styles/variants.d.ts\",\"../../node_modules/@mui/material/styles/components.d.ts\",\"../../node_modules/@mui/material/styles/createtheme.d.ts\",\"../../node_modules/@mui/material/styles/adaptv4theme.d.ts\",\"../../node_modules/@mui/material/styles/createstyles.d.ts\",\"../../node_modules/@mui/material/styles/responsivefontsizes.d.ts\",\"../../node_modules/@mui/material/styles/usetheme.d.ts\",\"../../node_modules/@mui/material/styles/usethemeprops.d.ts\",\"../../node_modules/@mui/material/styles/styled.d.ts\",\"../../node_modules/@mui/material/styles/themeprovider.d.ts\",\"../../node_modules/@mui/material/styles/cssutils.d.ts\",\"../../node_modules/@mui/material/styles/makestyles.d.ts\",\"../../node_modules/@mui/material/styles/withstyles.d.ts\",\"../../node_modules/@mui/material/styles/withtheme.d.ts\",\"../../node_modules/@mui/material/styles/experimental_extendtheme.d.ts\",\"../../node_modules/@mui/material/styles/cssvarsprovider.d.ts\",\"../../node_modules/@mui/material/styles/index.d.ts\",\"../../node_modules/@mui/material/colors/amber.d.ts\",\"../../node_modules/@mui/material/colors/blue.d.ts\",\"../../node_modules/@mui/material/colors/bluegrey.d.ts\",\"../../node_modules/@mui/material/colors/brown.d.ts\",\"../../node_modules/@mui/material/colors/common.d.ts\",\"../../node_modules/@mui/material/colors/cyan.d.ts\",\"../../node_modules/@mui/material/colors/deeporange.d.ts\",\"../../node_modules/@mui/material/colors/deeppurple.d.ts\",\"../../node_modules/@mui/material/colors/green.d.ts\",\"../../node_modules/@mui/material/colors/grey.d.ts\",\"../../node_modules/@mui/material/colors/indigo.d.ts\",\"../../node_modules/@mui/material/colors/lightblue.d.ts\",\"../../node_modules/@mui/material/colors/lightgreen.d.ts\",\"../../node_modules/@mui/material/colors/lime.d.ts\",\"../../node_modules/@mui/material/colors/orange.d.ts\",\"../../node_modules/@mui/material/colors/pink.d.ts\",\"../../node_modules/@mui/material/colors/purple.d.ts\",\"../../node_modules/@mui/material/colors/red.d.ts\",\"../../node_modules/@mui/material/colors/teal.d.ts\",\"../../node_modules/@mui/material/colors/yellow.d.ts\",\"../../node_modules/@mui/material/colors/index.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/utils/chainproptypes.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/utils/deepmerge.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/utils/elementacceptingref.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/utils/elementtypeacceptingref.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/utils/exactprop.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/utils/formatmuierrormessage.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/utils/getdisplayname.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/utils/htmlelementtype.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/utils/ponyfillglobal.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/utils/reftype.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/utils/capitalize.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/utils/createchainedfunction.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/utils/debounce.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/utils/deprecatedproptype.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/utils/ismuielement.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/utils/ownerdocument.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/utils/ownerwindow.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/utils/requirepropfactory.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/utils/setref.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/utils/useenhancedeffect.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/utils/useid.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/utils/unsupportedprop.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/utils/usecontrolled.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/utils/useeventcallback.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/utils/useforkref.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/utils/useisfocusvisible.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/utils/getscrollbarsize.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/utils/scrollleft.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/utils/usepreviousprops.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/utils/visuallyhidden.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/utils/integerproptype.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/utils/resolveprops.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/utils/index.d.ts\",\"../../node_modules/@mui/material/utils/capitalize.d.ts\",\"../../node_modules/@mui/material/utils/createchainedfunction.d.ts\",\"../../node_modules/@mui/material/utils/createsvgicon.d.ts\",\"../../node_modules/@mui/material/utils/debounce.d.ts\",\"../../node_modules/@mui/material/utils/deprecatedproptype.d.ts\",\"../../node_modules/@mui/material/utils/ismuielement.d.ts\",\"../../node_modules/@mui/material/utils/ownerdocument.d.ts\",\"../../node_modules/@mui/material/utils/ownerwindow.d.ts\",\"../../node_modules/@mui/material/utils/requirepropfactory.d.ts\",\"../../node_modules/@mui/material/utils/setref.d.ts\",\"../../node_modules/@mui/material/utils/useenhancedeffect.d.ts\",\"../../node_modules/@mui/material/utils/useid.d.ts\",\"../../node_modules/@mui/material/utils/unsupportedprop.d.ts\",\"../../node_modules/@mui/material/utils/usecontrolled.d.ts\",\"../../node_modules/@mui/material/utils/useeventcallback.d.ts\",\"../../node_modules/@mui/material/utils/useforkref.d.ts\",\"../../node_modules/@mui/material/utils/useisfocusvisible.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/classname/classnamegenerator.d.ts\",\"../../node_modules/@mui/material/node_modules/@mui/base/classname/index.d.ts\",\"../../node_modules/@mui/material/utils/index.d.ts\",\"../../node_modules/@mui/material/box/box.d.ts\",\"../../node_modules/@mui/material/box/index.d.ts\",\"../../node_modules/@mui/material/clickawaylistener/index.d.ts\",\"../../node_modules/@mui/material/darkscrollbar/index.d.ts\",\"../../node_modules/@mui/material/grow/grow.d.ts\",\"../../node_modules/@mui/material/grow/index.d.ts\",\"../../node_modules/@mui/material/hidden/hidden.d.ts\",\"../../node_modules/@mui/material/hidden/index.d.ts\",\"../../node_modules/@mui/material/nossr/index.d.ts\",\"../../node_modules/@mui/material/portal/index.d.ts\",\"../../node_modules/@mui/material/textareaautosize/index.d.ts\",\"../../node_modules/@mui/material/usescrolltrigger/usescrolltrigger.d.ts\",\"../../node_modules/@mui/material/usescrolltrigger/index.d.ts\",\"../../node_modules/@mui/material/zoom/zoom.d.ts\",\"../../node_modules/@mui/material/zoom/index.d.ts\",\"../../node_modules/@mui/material/useautocomplete/useautocomplete.d.ts\",\"../../node_modules/@mui/material/useautocomplete/index.d.ts\",\"../../node_modules/@mui/material/globalstyles/globalstyles.d.ts\",\"../../node_modules/@mui/material/globalstyles/index.d.ts\",\"../../node_modules/@mui/material/index.d.ts\",\"./static-resources/src/error/errormap.tsx\",\"./static-resources/src/error/index.ts\",\"./static-resources/src/constant/sagastatus.ts\",\"../../node_modules/@loopring-web/web3-provider/dist/command.d.ts\",\"../../node_modules/eventemitter3/index.d.ts\",\"../../node_modules/@walletconnect/http-connection/dist/cjs/index.d.ts\",\"../../node_modules/@walletconnect/types/index.d.ts\",\"../../node_modules/@walletconnect/web3-provider/dist/cjs/index.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/dist/assets/wallet-logo.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/dist/relay/relaymessage.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/dist/types.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/dist/relay/web3method.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/dist/relay/web3request.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/dist/relay/web3requestmessage.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/dist/relay/web3response.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/dist/relay/web3responsemessage.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/subscription.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/types.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/subscriber.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/operator.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/observable/iif.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/observable/throwerror.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/observable.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/subject.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/observable/connectableobservable.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/operators/groupby.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/symbol/observable.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/behaviorsubject.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/replaysubject.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/asyncsubject.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/scheduler.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/scheduler/action.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/scheduler/asyncscheduler.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/scheduler/asyncaction.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/scheduler/asapscheduler.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/scheduler/asap.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/scheduler/async.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/scheduler/queuescheduler.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/scheduler/queue.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/scheduler/animationframescheduler.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/scheduler/animationframe.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/scheduler/virtualtimescheduler.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/notification.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/util/pipe.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/util/noop.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/util/identity.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/util/isobservable.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/util/argumentoutofrangeerror.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/util/emptyerror.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/util/objectunsubscribederror.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/util/unsubscriptionerror.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/util/timeouterror.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/observable/bindcallback.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/observable/bindnodecallback.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/innersubscriber.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/outersubscriber.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/observable/combinelatest.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/observable/concat.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/observable/defer.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/observable/empty.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/observable/forkjoin.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/observable/from.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/observable/fromevent.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/observable/fromeventpattern.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/observable/generate.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/observable/interval.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/observable/merge.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/observable/never.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/observable/of.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/observable/onerrorresumenext.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/observable/pairs.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/observable/partition.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/observable/race.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/observable/range.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/observable/timer.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/observable/using.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/observable/zip.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/scheduled/scheduled.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/internal/config.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/node_modules/rxjs/index.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/dist/connection/rxwebsocket.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/dist/connection/servermessage.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/dist/connection/diagnosticlogger.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/dist/connection/eventlistener.d.ts\",\"../../node_modules/@metamask/safe-event-emitter/index.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/dist/lib/scopedlocalstorage.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/dist/provider/jsonrpc.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/dist/relay/ethereumtransactionparams.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/dist/relay/session.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/dist/relay/walletsdkrelayabstract.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/dist/relay/walletsdkrelayeventmanager.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/dist/provider/web3provider.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/dist/provider/coinbasewalletprovider.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/dist/provider/walletui.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/dist/coinbasewalletsdk.d.ts\",\"../../node_modules/@coinbase/wallet-sdk/dist/index.d.ts\",\"../../node_modules/@ethersproject/bytes/lib/index.d.ts\",\"../../node_modules/@ethersproject/bignumber/lib/bignumber.d.ts\",\"../../node_modules/@ethersproject/bignumber/lib/fixednumber.d.ts\",\"../../node_modules/@ethersproject/bignumber/lib/index.d.ts\",\"../../node_modules/@ethersproject/networks/lib/types.d.ts\",\"../../node_modules/@ethersproject/networks/lib/index.d.ts\",\"../../node_modules/@ethersproject/properties/lib/index.d.ts\",\"../../node_modules/@ethersproject/transactions/lib/index.d.ts\",\"../../node_modules/@ethersproject/web/lib/index.d.ts\",\"../../node_modules/@ethersproject/abstract-provider/lib/index.d.ts\",\"../../node_modules/@ethersproject/providers/lib/formatter.d.ts\",\"../../node_modules/@ethersproject/providers/lib/base-provider.d.ts\",\"../../node_modules/@ethersproject/abstract-signer/lib/index.d.ts\",\"../../node_modules/@ethersproject/providers/lib/json-rpc-provider.d.ts\",\"../../node_modules/@ethersproject/providers/lib/websocket-provider.d.ts\",\"../../node_modules/@ethersproject/providers/lib/url-json-rpc-provider.d.ts\",\"../../node_modules/@ethersproject/providers/lib/alchemy-provider.d.ts\",\"../../node_modules/@ethersproject/providers/lib/ankr-provider.d.ts\",\"../../node_modules/@ethersproject/providers/lib/cloudflare-provider.d.ts\",\"../../node_modules/@ethersproject/providers/lib/etherscan-provider.d.ts\",\"../../node_modules/@ethersproject/providers/lib/fallback-provider.d.ts\",\"../../node_modules/@ethersproject/providers/lib/ipc-provider.d.ts\",\"../../node_modules/@ethersproject/providers/lib/infura-provider.d.ts\",\"../../node_modules/@ethersproject/providers/lib/json-rpc-batch-provider.d.ts\",\"../../node_modules/@ethersproject/providers/lib/nodesmith-provider.d.ts\",\"../../node_modules/@ethersproject/providers/lib/pocket-provider.d.ts\",\"../../node_modules/@ethersproject/providers/lib/web3-provider.d.ts\",\"../../node_modules/@ethersproject/providers/lib/index.d.ts\",\"../../node_modules/@loopring-web/web3-provider/dist/providers.d.ts\",\"../../node_modules/@loopring-web/web3-provider/dist/walletservices.d.ts\",\"../../node_modules/@loopring-web/web3-provider/dist/index.d.ts\",\"./static-resources/src/svg/icon.tsx\",\"../../node_modules/@types/trusted-types/lib/index.d.ts\",\"../../node_modules/@types/trusted-types/index.d.ts\",\"../../node_modules/@types/dompurify/index.d.ts\",\"./static-resources/src/svg/redpacketsvg.tsx\",\"./static-resources/src/svg/index.ts\",\"./static-resources/src/constant/market.ts\",\"./static-resources/src/constant/vendor.ts\",\"./static-resources/src/constant/trade.ts\",\"./static-resources/src/constant/router.ts\",\"./static-resources/src/constant/walletconnector.ts\",\"./static-resources/src/utils/types.tsx\",\"./static-resources/src/utils/util.ts\",\"./static-resources/src/utils/log_tools.ts\",\"./static-resources/src/utils/format_tools.ts\",\"./static-resources/src/utils/obj_tools.ts\",\"./static-resources/src/utils/makedom.ts\",\"./static-resources/src/utils/index.ts\",\"./static-resources/src/constant/setting.ts\",\"./static-resources/src/constant/chart.ts\",\"./static-resources/src/constant/table.ts\",\"./static-resources/src/constant/loopring.ts\",\"./static-resources/src/constant/prolayout.ts\",\"./static-resources/src/constant/miningouterlinks.ts\",\"./static-resources/src/constant/notification.ts\",\"./static-resources/src/constant/firebase.ts\",\"./static-resources/src/constant/index.ts\",\"./static-resources/src/loopring-interface/coininterface.ts\",\"./static-resources/src/loopring-interface/headerinterface.ts\",\"./static-resources/src/loopring-interface/wallectinterface.ts\",\"./static-resources/src/loopring-interface/vendorinterface.ts\",\"./static-resources/src/loopring-interface/footerinterface.ts\",\"./static-resources/src/loopring-interface/investment.ts\",\"./static-resources/src/loopring-interface/index.ts\",\"./static-resources/src/constant/account.ts\",\"./static-resources/src/i18n/en_us/common.ts\",\"./static-resources/src/i18n/en_us/layout.ts\",\"./static-resources/src/i18n/en_us/tables.ts\",\"./static-resources/src/i18n/en_us/error.ts\",\"./static-resources/src/i18n/en_us/landpage.ts\",\"./static-resources/src/i18n/en_us/index.ts\",\"./static-resources/src/i18n/index.ts\",\"./static-resources/src/i18n/zh_cn/common.ts\",\"./static-resources/src/i18n/zh_cn/error.ts\",\"./static-resources/src/i18n/zh_cn/layout.ts\",\"./static-resources/src/i18n/zh_cn/tables.ts\",\"./static-resources/src/i18n/zh_cn/landpage.ts\",\"./static-resources/src/i18n/zh_cn/index.ts\",\"./static-resources/src/themes/globalsetup.ts\",\"./static-resources/src/themes/css/color-lib.ts\",\"./static-resources/src/themes/interface.ts\",\"./static-resources/src/themes/css/reset.tsx\",\"./static-resources/src/themes/css/global.tsx\",\"./static-resources/src/themes/overrides/utils.ts\",\"./static-resources/src/themes/overrides/overrides-mui.ts\",\"./static-resources/src/themes/overrides/overrides-date-pick.ts\",\"./static-resources/src/themes/overrides/mutheme.ts\",\"./static-resources/src/themes/index.ts\",\"../../node_modules/@types/aria-query/index.d.ts\",\"../../node_modules/@babel/types/lib/index.d.ts\",\"../../node_modules/@types/babel__generator/index.d.ts\",\"../../node_modules/@babel/parser/typings/babel-parser.d.ts\",\"../../node_modules/@types/babel__template/index.d.ts\",\"../../node_modules/@types/babel__traverse/index.d.ts\",\"../../node_modules/@types/babel__core/index.d.ts\",\"../../node_modules/keyv/src/index.d.ts\",\"../../node_modules/@types/http-cache-semantics/index.d.ts\",\"../../node_modules/@types/responselike/index.d.ts\",\"../../node_modules/@types/cacheable-request/index.d.ts\",\"../../node_modules/@types/connect/index.d.ts\",\"../../node_modules/@types/d3-format/index.d.ts\",\"../../node_modules/@types/d3-path/index.d.ts\",\"../../node_modules/@types/d3-time/index.d.ts\",\"../../node_modules/@types/d3-scale/index.d.ts\",\"../../node_modules/@types/d3-shape/index.d.ts\",\"../../node_modules/@types/d3-time-format/index.d.ts\",\"../../node_modules/@types/ms/index.d.ts\",\"../../node_modules/@types/debug/index.d.ts\",\"../../node_modules/@types/eslint/helpers.d.ts\",\"../../node_modules/@types/eslint/lib/rules/index.d.ts\",\"../../node_modules/@types/json-schema/index.d.ts\",\"../../node_modules/@types/estree/index.d.ts\",\"../../node_modules/@types/eslint/index.d.ts\",\"../../node_modules/@types/eslint-scope/node_modules/@types/eslint/helpers.d.ts\",\"../../node_modules/@types/eslint-scope/node_modules/@types/eslint/index.d.ts\",\"../../node_modules/@types/eslint-scope/index.d.ts\",\"../../node_modules/@types/eslint-visitor-keys/index.d.ts\",\"../../node_modules/@types/ethereumjs-abi/index.d.ts\",\"../../node_modules/@types/minimatch/index.d.ts\",\"../../node_modules/@types/glob/index.d.ts\",\"../../node_modules/@types/graceful-fs/index.d.ts\",\"../../node_modules/@types/unist/index.d.ts\",\"../../node_modules/@types/hast/index.d.ts\",\"../../node_modules/@types/history/domutils.d.ts\",\"../../node_modules/@types/history/createbrowserhistory.d.ts\",\"../../node_modules/@types/history/createhashhistory.d.ts\",\"../../node_modules/@types/history/creatememoryhistory.d.ts\",\"../../node_modules/@types/history/locationutils.d.ts\",\"../../node_modules/@types/history/pathutils.d.ts\",\"../../node_modules/@types/history/index.d.ts\",\"../../node_modules/@types/hoist-non-react-statics/index.d.ts\",\"../../node_modules/@types/html-minifier-terser/index.d.ts\",\"../../node_modules/@types/is-function/index.d.ts\",\"../../node_modules/@types/istanbul-lib-coverage/index.d.ts\",\"../../node_modules/@types/istanbul-lib-report/index.d.ts\",\"../../node_modules/@types/istanbul-reports/index.d.ts\",\"../../node_modules/jest-diff/build/cleanupsemantic.d.ts\",\"../../node_modules/jest-diff/build/types.d.ts\",\"../../node_modules/jest-diff/build/difflines.d.ts\",\"../../node_modules/jest-diff/build/printdiffs.d.ts\",\"../../node_modules/jest-diff/build/index.d.ts\",\"../../node_modules/pretty-format/build/types.d.ts\",\"../../node_modules/pretty-format/build/index.d.ts\",\"../../node_modules/@types/jest/index.d.ts\",\"../../node_modules/@types/jest-specific-snapshot/index.d.ts\",\"../../node_modules/@types/js-cookie/index.d.ts\",\"../../node_modules/@types/jsbn/index.d.ts\",\"../../node_modules/@types/json5/index.d.ts\",\"../../node_modules/@types/keyv/index.d.ts\",\"../../node_modules/@types/lodash/common/common.d.ts\",\"../../node_modules/@types/lodash/common/array.d.ts\",\"../../node_modules/@types/lodash/common/collection.d.ts\",\"../../node_modules/@types/lodash/common/date.d.ts\",\"../../node_modules/@types/lodash/common/function.d.ts\",\"../../node_modules/@types/lodash/common/lang.d.ts\",\"../../node_modules/@types/lodash/common/math.d.ts\",\"../../node_modules/@types/lodash/common/number.d.ts\",\"../../node_modules/@types/lodash/common/object.d.ts\",\"../../node_modules/@types/lodash/common/seq.d.ts\",\"../../node_modules/@types/lodash/common/string.d.ts\",\"../../node_modules/@types/lodash/common/util.d.ts\",\"../../node_modules/@types/lodash/index.d.ts\",\"../../node_modules/@types/long/index.d.ts\",\"../../node_modules/@types/mdast/index.d.ts\",\"../../node_modules/@types/mdurl/encode.d.ts\",\"../../node_modules/@types/mdurl/decode.d.ts\",\"../../node_modules/@types/mdurl/parse.d.ts\",\"../../node_modules/@types/mdurl/format.d.ts\",\"../../node_modules/@types/mdurl/index.d.ts\",\"../../node_modules/@types/minimist/index.d.ts\",\"../../node_modules/@types/ms.macro/index.d.ts\",\"../../node_modules/form-data/index.d.ts\",\"../../node_modules/@types/node-fetch/externals.d.ts\",\"../../node_modules/@types/node-fetch/index.d.ts\",\"../../node_modules/@types/normalize-package-data/index.d.ts\",\"../../node_modules/@types/npmlog/index.d.ts\",\"../../node_modules/@types/parse-json/index.d.ts\",\"../../node_modules/@types/parse5/lib/tree-adapters/default.d.ts\",\"../../node_modules/@types/parse5/index.d.ts\",\"../../node_modules/@types/pbkdf2/index.d.ts\",\"../../node_modules/@types/prettier/index.d.ts\",\"../../node_modules/@types/pretty-hrtime/index.d.ts\",\"../../node_modules/@types/q/index.d.ts\",\"../../node_modules/@types/qrcode-svg/index.d.ts\",\"../../node_modules/@types/qrcode.react/index.d.ts\",\"../../node_modules/@types/qs/index.d.ts\",\"../../node_modules/@types/react-beautiful-dnd/index.d.ts\",\"../../node_modules/@types/react-dom/index.d.ts\",\"../../node_modules/@types/react-grid-layout/index.d.ts\",\"../../node_modules/@types/react-is/index.d.ts\",\"../../node_modules/redux/index.d.ts\",\"../../node_modules/@types/react-redux/index.d.ts\",\"../../node_modules/@types/react-router/index.d.ts\",\"../../node_modules/@types/react-router-dom/index.d.ts\",\"../../node_modules/@types/react-swipeable-views/index.d.ts\",\"../../node_modules/@types/react-test-renderer/index.d.ts\",\"../../node_modules/@types/react-transition-group/csstransition.d.ts\",\"../../node_modules/@types/react-transition-group/transitiongroup.d.ts\",\"../../node_modules/@types/react-transition-group/switchtransition.d.ts\",\"../../node_modules/@types/react-transition-group/config.d.ts\",\"../../node_modules/@types/react-transition-group/index.d.ts\",\"../../node_modules/@types/react-virtualized/dist/es/cellmeasurer.d.ts\",\"../../node_modules/@types/react-virtualized/dist/es/list.d.ts\",\"../../node_modules/@types/react-virtualized/dist/es/table.d.ts\",\"../../node_modules/@types/react-virtualized/dist/es/grid.d.ts\",\"../../node_modules/@types/react-virtualized/dist/es/arrowkeystepper.d.ts\",\"../../node_modules/@types/react-virtualized/dist/es/autosizer.d.ts\",\"../../node_modules/@types/react-virtualized/dist/es/collection.d.ts\",\"../../node_modules/@types/react-virtualized/dist/es/columnsizer.d.ts\",\"../../node_modules/@types/react-virtualized/dist/es/infiniteloader.d.ts\",\"../../node_modules/@types/react-virtualized/dist/es/masonry.d.ts\",\"../../node_modules/@types/react-virtualized/dist/es/multigrid.d.ts\",\"../../node_modules/@types/react-virtualized/dist/es/scrollsync.d.ts\",\"../../node_modules/@types/react-virtualized/dist/es/windowscroller.d.ts\",\"../../node_modules/@types/react-virtualized/index.d.ts\",\"../../node_modules/@types/react-virtualized-auto-sizer/index.d.ts\",\"../../node_modules/@types/redux-logger/index.d.ts\",\"../../node_modules/@types/resize-observer-browser/index.d.ts\",\"../../node_modules/@types/resolve/index.d.ts\",\"../../node_modules/@types/scheduler/index.d.ts\",\"../../node_modules/@types/secp256k1/index.d.ts\",\"../../node_modules/@types/source-list-map/index.d.ts\",\"../../node_modules/@types/stack-utils/index.d.ts\",\"../../node_modules/@types/styled-components/index.d.ts\",\"../../node_modules/@types/styled-react-modal/index.d.ts\",\"../../node_modules/@types/tapable/index.d.ts\",\"../../node_modules/@types/testing-library__jest-dom/matchers.d.ts\",\"../../node_modules/@types/testing-library__jest-dom/index.d.ts\",\"../../node_modules/source-map/source-map.d.ts\",\"../../node_modules/@types/uglify-js/index.d.ts\",\"../../node_modules/@types/voca/index.d.ts\",\"../../node_modules/@types/webpack/node_modules/anymatch/index.d.ts\",\"../../node_modules/@types/webpack-sources/node_modules/source-map/source-map.d.ts\",\"../../node_modules/@types/webpack-sources/lib/source.d.ts\",\"../../node_modules/@types/webpack-sources/lib/compatsource.d.ts\",\"../../node_modules/@types/webpack-sources/lib/concatsource.d.ts\",\"../../node_modules/@types/webpack-sources/lib/originalsource.d.ts\",\"../../node_modules/@types/webpack-sources/lib/prefixsource.d.ts\",\"../../node_modules/@types/webpack-sources/lib/rawsource.d.ts\",\"../../node_modules/@types/webpack-sources/lib/replacesource.d.ts\",\"../../node_modules/@types/webpack-sources/lib/sizeonlysource.d.ts\",\"../../node_modules/@types/webpack-sources/lib/sourcemapsource.d.ts\",\"../../node_modules/@types/webpack-sources/lib/index.d.ts\",\"../../node_modules/@types/webpack-sources/lib/cachedsource.d.ts\",\"../../node_modules/@types/webpack-sources/index.d.ts\",\"../../node_modules/@types/webpack/index.d.ts\",\"../../node_modules/@types/webpack-env/index.d.ts\",\"../../node_modules/@types/ws/index.d.ts\",\"../../node_modules/@types/yargs-parser/index.d.ts\",\"../../node_modules/@types/yargs/index.d.ts\"],\"fileInfos\":[{\"version\":\"3ac1b83264055b28c0165688fda6dfcc39001e9e7828f649299101c23ad0a0c3\",\"affectsGlobalScope\":true},\"dc47c4fa66b9b9890cf076304de2a9c5201e94b740cffdf09f87296d877d71f6\",\"7a387c58583dfca701b6c85e0adaf43fb17d590fb16d5b2dc0a2fbd89f35c467\",\"8a12173c586e95f4433e0c6dc446bc88346be73ffe9ca6eec7aa63c8f3dca7f9\",\"5f4e733ced4e129482ae2186aae29fde948ab7182844c3a5a51dd346182c7b06\",\"e6b724280c694a9f588847f754198fb96c43d805f065c3a5b28bbc9594541c84\",\"e21c071ca3e1b4a815d5f04a7475adcaeea5d64367e840dd0154096d705c3940\",\"746d62152361558ea6d6115cf0da4dd10ede041d14882ede3568bce5dc4b4f1f\",\"2f93dda35dafec68ec217c9ce67f0f4fbbbb030c055ac312641565ad60dd7e26\",\"aea179452def8a6152f98f63b191b84e7cbd69b0e248c91e61fb2e52328abe8c\",{\"version\":\"72704b10d97777e15f1a581b73f88273037ef752d2e50b72287bd0a90af64fe6\",\"affectsGlobalScope\":true},{\"version\":\"dbb73d4d99be496175cb432c74c2615f78c76f4272f1d83cba11ee0ed6dbddf0\",\"affectsGlobalScope\":true},{\"version\":\"d8996609230d17e90484a2dd58f22668f9a05a3bfe00bfb1d6271171e54a31fb\",\"affectsGlobalScope\":true},{\"version\":\"43fb1d932e4966a39a41b464a12a81899d9ae5f2c829063f5571b6b87e6d2f9c\",\"affectsGlobalScope\":true},{\"version\":\"cdccba9a388c2ee3fd6ad4018c640a471a6c060e96f1232062223063b0a5ac6a\",\"affectsGlobalScope\":true},{\"version\":\"c5c05907c02476e4bde6b7e76a79ffcd948aedd14b6a8f56e4674221b0417398\",\"affectsGlobalScope\":true},{\"version\":\"0d5f52b3174bee6edb81260ebcd792692c32c81fd55499d69531496f3f2b25e7\",\"affectsGlobalScope\":true},{\"version\":\"810627a82ac06fb5166da5ada4159c4ec11978dfbb0805fe804c86406dab8357\",\"affectsGlobalScope\":true},{\"version\":\"62d80405c46c3f4c527ee657ae9d43fda65a0bf582292429aea1e69144a522a6\",\"affectsGlobalScope\":true},{\"version\":\"3013574108c36fd3aaca79764002b3717da09725a36a6fc02eac386593110f93\",\"affectsGlobalScope\":true},{\"version\":\"75ec0bdd727d887f1b79ed6619412ea72ba3c81d92d0787ccb64bab18d261f14\",\"affectsGlobalScope\":true},{\"version\":\"3be5a1453daa63e031d266bf342f3943603873d890ab8b9ada95e22389389006\",\"affectsGlobalScope\":true},{\"version\":\"17bb1fc99591b00515502d264fa55dc8370c45c5298f4a5c2083557dccba5a2a\",\"affectsGlobalScope\":true},{\"version\":\"7ce9f0bde3307ca1f944119f6365f2d776d281a393b576a18a2f2893a2d75c98\",\"affectsGlobalScope\":true},{\"version\":\"6a6b173e739a6a99629a8594bfb294cc7329bfb7b227f12e1f7c11bc163b8577\",\"affectsGlobalScope\":true},{\"version\":\"12a310447c5d23c7d0d5ca2af606e3bd08afda69100166730ab92c62999ebb9d\",\"affectsGlobalScope\":true},{\"version\":\"b0124885ef82641903d232172577f2ceb5d3e60aed4da1153bab4221e1f6dd4e\",\"affectsGlobalScope\":true},{\"version\":\"0eb85d6c590b0d577919a79e0084fa1744c1beba6fd0d4e951432fa1ede5510a\",\"affectsGlobalScope\":true},{\"version\":\"da233fc1c8a377ba9e0bed690a73c290d843c2c3d23a7bd7ec5cd3d7d73ba1e0\",\"affectsGlobalScope\":true},{\"version\":\"d154ea5bb7f7f9001ed9153e876b2d5b8f5c2bb9ec02b3ae0d239ec769f1f2ae\",\"affectsGlobalScope\":true},{\"version\":\"bb2d3fb05a1d2ffbca947cc7cbc95d23e1d053d6595391bd325deb265a18d36c\",\"affectsGlobalScope\":true},{\"version\":\"c80df75850fea5caa2afe43b9949338ce4e2de086f91713e9af1a06f973872b8\",\"affectsGlobalScope\":true},{\"version\":\"9d57b2b5d15838ed094aa9ff1299eecef40b190722eb619bac4616657a05f951\",\"affectsGlobalScope\":true},{\"version\":\"6c51b5dd26a2c31dbf37f00cfc32b2aa6a92e19c995aefb5b97a3a64f1ac99de\",\"affectsGlobalScope\":true},{\"version\":\"6e7997ef61de3132e4d4b2250e75343f487903ddf5370e7ce33cf1b9db9a63ed\",\"affectsGlobalScope\":true},{\"version\":\"2ad234885a4240522efccd77de6c7d99eecf9b4de0914adb9a35c0c22433f993\",\"affectsGlobalScope\":true},{\"version\":\"1b3fe904465430e030c93239a348f05e1be80640d91f2f004c3512c2c2c89f34\",\"affectsGlobalScope\":true},{\"version\":\"3787b83e297de7c315d55d4a7c546ae28e5f6c0a361b7a1dcec1f1f50a54ef11\",\"affectsGlobalScope\":true},{\"version\":\"e7e8e1d368290e9295ef18ca23f405cf40d5456fa9f20db6373a61ca45f75f40\",\"affectsGlobalScope\":true},{\"version\":\"faf0221ae0465363c842ce6aa8a0cbda5d9296940a8e26c86e04cc4081eea21e\",\"affectsGlobalScope\":true},{\"version\":\"06393d13ea207a1bfe08ec8d7be562549c5e2da8983f2ee074e00002629d1871\",\"affectsGlobalScope\":true},{\"version\":\"5075b36ab861c8c0c45377cb8c96270d7c65f0eeaf105d53fac6850da61f1027\",\"affectsGlobalScope\":true},{\"version\":\"6c55633c733c8378db65ac3da7a767c3cf2cf3057f0565a9124a16a3a2019e87\",\"affectsGlobalScope\":true},{\"version\":\"fb4416144c1bf0323ccbc9afb0ab289c07312214e8820ad17d709498c865a3fe\",\"affectsGlobalScope\":true},{\"version\":\"5b0ca94ec819d68d33da516306c15297acec88efeb0ae9e2b39f71dbd9685ef7\",\"affectsGlobalScope\":true},{\"version\":\"e8c9f4e445a489991ca1a4232667de3ac36b07ba75ea335971fbeacf2d26fe67\",\"affectsGlobalScope\":true},{\"version\":\"34478567f8a80171f88f2f30808beb7da15eac0538ae91282dd33dce928d98ed\",\"affectsGlobalScope\":true},{\"version\":\"6ea9ab679ea030cf46c16a711a316078e9e02619ebaf07a7fcd16964aba88f2d\",\"affectsGlobalScope\":true},{\"version\":\"aedb8de1abb2ff1095c153854a6df7deae4a5709c37297f9d6e9948b6806fa66\",\"affectsGlobalScope\":true},{\"version\":\"11ffe3c281f375fff9ffdde8bbec7669b4dd671905509079f866f2354a788064\",\"affectsGlobalScope\":true},{\"version\":\"10bbdc1981b8d9310ee75bfac28ee0477bb2353e8529da8cff7cb26c409cb5e8\",\"affectsGlobalScope\":true},{\"version\":\"bbdf156fea2fabed31a569445835aeedcc33643d404fcbaa54541f06c109df3f\",\"affectsGlobalScope\":true},\"ea0aa24a32c073b8639aa1f3130ba0add0f0f2f76b314d9ba988a5cb91d7e3c4\",\"f7b46d22a307739c145e5fddf537818038fdfffd580d79ed717f4d4d37249380\",\"f5a8b384f182b3851cec3596ccc96cb7464f8d3469f48c74bf2befb782a19de5\",{\"version\":\"ce4e9cdf1ec90f3d435a4df18342b187805924f6046e872e76d3c1659ad545ff\",\"affectsGlobalScope\":true},\"af7fd2870746deed40e130fc0a3966de74e8f52a97ec114d0fbb35876ab05ca9\",\"d0476ddaacf1b8b9b18aa7cdb54eb8bc7edb69165a455803e2065fc28a321960\",\"2be6f8fda5c8ca751609548426d25da1785178c75e2af1cb675afd207d9da85f\",\"dd051e4d359b018fca5a4f5520be1d6bc9701b3dce8274badfd378aed11fb7ec\",\"60693bef7f2b4d077f08a1a837b7d6ad99a0ad66115bac4b4141466927069f99\",\"0ce65cf5b36034006f2b315f379179f07bd5a6027f6538c7aed4ac5be6742fc7\",{\"version\":\"cb8b955fbbb257a05b2d5a2f93212c7edf033b61b9420fa700d10d39d9bd4533\",\"affectsGlobalScope\":true},\"0721418a90edc5fca466672f266ab6de12cb50a9db29998fc58765481a3c82ef\",\"97b39f33e966bcf9762bccdaca76c94825199f3fef153ebea9bdfd3fcd2413b6\",\"78650a1b5800e82b6914260e9ca0fe9ea744e4333c3bec51b08f91525718d7fa\",\"c41eff6b8e1f91104ae974ccd2bc37c723a462b30ca1df942b2c5b0158ef1df3\",\"2e341737e0711c12040e83047487240b1693a6774253b8142d1a0500a805b7a1\",\"e08e97c2865750e880fea09b150a702ccfa84163382daa0221f5597185a554bf\",\"7ec6b45fc1f5f012ac226b44d0eeaf5a0e90947431ad7c6d1f244ba080b2870d\",\"4a1a19573176829708dc03efea508e7c364f6fa30098a5100bd9d93fc9cd38ee\",\"8296198bc72e7ef2221b0e140738ce56004e8d1323cd08b0ac1a15295fe911b5\",\"baeda1fadac9fd31920480b85340ab9c4266a25ad08403dee8e15fd0751101fb\",\"12c4e8e811f4310b0dcaa3d1f843a35dc985f78941886cad4950453ad6753959\",\"6bdede4dc73ad9816d0beeca7413ab29523f99a98441cc9fa6c614fd97fac49d\",\"8698062058cbdc84171bd576315a5eecab2bf46d7d034144653ae78864889683\",\"b3e4f2772da66bac2144ca8cd63f70d211d2f970c93fcb789d03e8a046d47c93\",\"a3586135924c800f21f739a1da43acace1acfdba124deb0871cbd6d04d7dfd1b\",\"f74c1fae7233cd08c72bb2dc09cb0673c53fb4c3c7903ccf0094404e3f2ba6d4\",\"4ec74fe565d13fd219884cfacf903c89477cc54148887e51c5bead4dae7dc4fd\",\"f50f52f8fc2a5f8dfa594ff59a6273876b1734fe612e9f331ca9078fede3b304\",\"a46d8aa9e561fb135d253e1657a0cd0f6c18377676305eb0ca28e418358b229c\",\"5a168a15e7a423011b10da472ee3b6d92b27227c192cdaf1e09b30f58806856d\",\"ad107fa472d28e615af522b31653e75caad12b834b257c1a83f6c4acff2de9bf\",{\"version\":\"07cfc938dfbb5a7b5ba3c363366db93d5728b0fcad1aa08a12052a1b3b72817a\",\"affectsGlobalScope\":true},\"7f77304372efe3c9967e5f9ea2061f1b4bf41dc3cda3c83cdd676f2e5af6b7e6\",\"67cf04da598e6407427a17d828e9e02d8f5ae5a8466dc73d1585073b8dc29160\",\"fa960168e0650a987d5738376a22a1969b5dff2112b9653f9f1efddf8ba7d5bb\",\"140b05c89cbd5fc75c4e9c1780d85dfb4ea73a2b11dd345f8f944afd002ad74f\",\"ece46d0e5702e9c269aa71b42d02c934c10d4d24545b1d8594a8115f23a9011f\",\"5b0df2143d96172bf207ed187627e8c58b15a1a8f97bdbc2ede942b36b39fc98\",\"75409a3abea76ea586c6fb7f2e9f1a7dc007140e2d4ee26ab127735c4f9154e4\",\"8e721f0a95eb26a30228d571659d2db062213bfe066a97fff7967a0c8e1d56e4\",\"7df562288f949945cf69c21cd912100c2afedeeb7cdb219085f7f4b46cb7dde4\",\"9d16690485ff1eb4f6fc57aebe237728fd8e03130c460919da3a35f4d9bd97f5\",\"ad7e61eca7f2f8bf47e72695f9f6663b75e41d87ef49abdb17c0cb843862f8aa\",\"ecba2e44af95b0599c269a92628cec22e752868bce37396740deb51a5c547a26\",\"46a9fb41a8f3bc7539eeebc15a6e04b9e55d7537a081615ad3614220d34c3e0f\",{\"version\":\"fd240b48ab1e78082c96c1faca62df02c0b8befa1fd98d031fab4f75c90feee6\",\"affectsGlobalScope\":true},\"3d87bdaed72f86b91f99401e6e04729afbb5916064778cf324b3d9b51c3a6d91\",\"8ca837d16a31d6d01b13328ca9e6a39e424b4bf294d3b73349dccacea51be730\",\"a9d40247ec6c68a47effbb1d8acd8df288bcee7b6bf29c17cf4161e5ef609a0c\",\"caf38c850b924a0af08a893d06f68fcae3d5a41780b50cc6df9481beeca8e9a3\",\"7152c46a63e7f9ac7db6cd8d4dbf85d90f051a0db60e650573fae576580cbf9a\",\"496370c58ed054e51a68517846c28a695bf84df2873556cca7fe51e297b32420\",{\"version\":\"2708349d5a11a5c2e5f3a0765259ebe7ee00cdcc8161cb9990cb4910328442a1\",\"affectsGlobalScope\":true},\"263da3252e029b3b62580b7a0c5e7bab07325a31c8af436ff60143cfda73b629\",\"cdac7e46e615e1fdcca7c3a2aab2fbd19085443048733cf239a090f7a17efa27\",\"1d7d9e42cb2cc36dfc7ce35755ce67d5ff0f4a2ef72d3019f4c461bfd22123da\",\"55c8e16380925dc895e3206510688b1decd3505bc6ff5b76e834f7f9531e22bb\",\"864d3573f14f138134b33f9589fb2bfb68a63cb63801a23d17a247f5f3bfa375\",\"1acfc1c5a9f95332a2c17a1e665661a049c818e1c7b0bb7cc2dacfdbf08f79af\",\"3170c0416dd2064d848fe1f06a2e1e53ed55030e93cb91ca451ad56b06354ff8\",\"3310413f72492d930655e27a99cb740367c5041852c8c84992a75454dde746b5\",\"5666d8fa634bec348d8e96cc49a620bb48f9420af778cd3acd1610e9ab03e236\",\"6aa5fdfff96c112d37fdee50d1bb82bdfc9247420fc76128e81b28fbd29c28a2\",\"f17d0f19ad9242b09b68a6d30402a841a7d4194d063855da5ca0567df0fb310e\",\"9e47cea2039dc59f4d9a33cc1da282a487a71c724efb2e888046417777d85313\",\"98c6b260f35311b89c326595d985c1553eb5d7a5b76d6e4a782cd3b088f362c4\",\"e082f4e967527c06203e5a3d9624f71a5b5102a38f66710325d51777cf4d5377\",\"1e13aa4f2ff194e7b753650d271c814a93419bf3dd6085ab6dcce0990e43bc68\",\"068b7d8771cc226375d8fc8a79fa03d0b2398f915a463b72faac8216c68d0d31\",\"2f208677a8d0b0ec9ae1fd09e8276dd455e6eef200c680078e40dc106cb21f0e\",\"e6df230289fad09ce77339f88a696b64d8b7f224c97113db9b707f4bea66f151\",\"1a86456517579a769ea206f9039a7d11e80c065bbd02b4ac8aafe2cf6ad008ca\",\"089e611f488f1de8aeb1c32c396d376b5c6e04f7b41684d334fe30139ae1dc02\",\"b574cbf23ab912f26339bc1f2a355bb26b8fcfd19e3f4264c7bc08fec99dc6fc\",\"1afca0be2d8f2e7046b636dc4ab1cff021f9394b45f91ce818976f8ae1a2c10f\",\"f3c83c293295b4629a0caccb448f9faf593a6d58396b17c369ed9934feaa9485\",\"3154a026075044aa102298fe9e6a7a14aaa26a06270680c7478a1765af8ffb09\",\"d6e832a6024676e553c569724e059e6438d6666fe1d8495ffc4dfa3696cbcbb3\",\"49de1678763fd9668f70a787c216a8b9fd902ef43dc11823c4581055bba17dda\",\"706f8c94c2f32d9a0f9d8f5948c2a50ca91808061812e9496137227d9fa655d4\",\"5ea44ed1739c4c4bbf8acd92242187cd8de9a6e8607381e66f3e54f26d8c32bc\",\"f079849b1695b3152412a4ae2525da5544158e7c03b47a314f6c4f513e50f0af\",\"8903ca0ff1d3c84b773b2b4b7cf8ab792902c85e0cfe546d578fef5b04f92ae4\",\"e73808fd2b1facc0c486b9225e47f1e65ce3f3fd75bc703dcb09a79c4c422fab\",\"0af5b5acb2a594b5fb23991ba3dc575f4c692cc7473e60fe76ce91c001edad48\",\"4089f519cfea3124c47dd8a2fbc26023fc013b6e860b7b1b29dd647b57af4d40\",\"89c9e52ccc437bf15581a8ee90db80065d3e5cb684a17193f87ad2ddf72ff435\",\"9615c1139380c409d7e014da5bad95f9a7b202bad43cd974dbbe604d367b1682\",\"0fec981c94bf74c599d4ff6b37781eedd4fc9ff0615f461cf9eab5622ea92625\",\"6079f704271f14a5d0a1805c97ca16de28286b8e4eee353607d1e8cddec0669e\",\"eaf998c111f92602e21fc71433f5f48f852e1585f54755b709c7b37b4da6ae17\",\"8d64573a06f0a6baf19add71cd8f0099d26ce7858daaad2c3a834f333dbf495c\",\"d6e0999c4c3fe1674238fc91a51d6cda6344bd8b01638a01db939838f8dec44e\",\"ded66243642cc55406173ba5bccf1162b106eb8671cf5eba95d39705505f7130\",\"0cb822a91a00ab0205385706b5e2d8df56f4b318276a2676cfb30b7d4fa713bf\",\"7f8d78620739775a268c820e9f9606c90552fc1bec08a9b43aec6964908af68d\",\"4bdc041df40c2e45cad929816632497173247e3a73f09e94186c2f1c3a6a6fee\",\"7ed54901a39f26fb71a656d203164bfb77288c416e8d82d33fd7970102b91c28\",\"815260e4afd5b26e8767e95dd2d08720d2021beaa58c357b1f0a769af6225352\",{\"version\":\"5169b051efebd75efb356781092c08985d8e6de131e960e45bd852fc6ca25bbd\",\"affectsGlobalScope\":true},\"cdc14771f2aa98ccefb2d089a7274bfa4b01dc2efd324950e2b50b7bc9b82fe7\",\"417892d55c03ed0d682fbae492a11a0157c837d42db8c535ff6b55ade07edf14\",\"f6d14869dbf8d88d3c91d987178ebc928f5de36db7ee2132c6bd98a451a06437\",\"132c108b095b43892c7e800bc499d2c1dcb46cd2cbe988a08284de0d9ccac9ac\",\"ad919527ce080334f1ee9a7430122a9dfc94ed01da38a3aeb28650a55d54c78a\",\"49b4ba730e0a7cacc42298d011e949c2147f7ebdebcf422e4fd8cdcf5133f62e\",\"e359f4c81ca411741f9986c25ce76481f0731f4d11906496e48e826dcd9ccbe8\",\"9d42a116928e196c8a93807d1c76f9bf24d5ba8a89a7a0cedcdba90446e1efcb\",\"a0b6d7e00a21158c7299d2d17152fc48dec67434a7c9864edece97cd2cd7e185\",\"3bd6ffa4f64fbbc031c1503c3ce63fa6e2134deb673c8571130a3675d91fcb17\",\"8ea05ab5a1250aa9d98070151c3981a85f5fd05185454f6c871ca2a988feb725\",\"0e1f5fa05f1097f2cc3a1581afc7270af08d31be123f3a8e92a5b4080858861e\",\"655638506266d44bc4815f7fda912d712114e200aa11ce4dee055d357dba96c5\",\"a9ecd22f5649301e9be4bacf88e13a9daf20011b63a18f6b7d506e1c8bf41f6a\",\"03fd06fcc894c94effaef2fc57d92c9e2871c6a5adb2db7136859a6ceff3f91a\",\"1121a97eee889dd43800e5486eff4b161397885b880c9e59569b5cc87520ecbf\",\"96251a479e0c56d3130cb7a15a682c86d86423422feb49059882ec574f0c6969\",\"7f6ee041490e9470a22c0cd293205083293c12e654364556bacadb5cbebed30c\",\"47dada41ced5a0e23c415fb8599b1b8c848fdd1df1b2f02b2e756558be9b3153\",\"b0a59b88d6d32ed5734ac9413f8a9e34773d4b7b0eddaeccdecee24ab8a4457d\",\"492dae861616e49ded6e82df7110868489b8f80cebb5f56bbe05bbf829f8a6fc\",\"dd4e64e454be95294aceb5286575faa08af11ebacc2c524310be108c1abd2a84\",\"3711c896e72680d79cfc4df36cae172b7dbb72e11936e5e9545f5351e6ed0962\",\"fdb706b594619f05e73b97213d760f59ed1514b302f58b4b46d86fe77757c031\",\"531cd80e4dba2620d86844a50e7d21b89436e56a14e66d6774e99b3759ac69ad\",\"03d59e612afdc3039a83b12d45b026306b291cfc8e2fc72859f7902b8a857caf\",\"93b24ca76698e62732d72800da132367639a4426363c821338bbbd7cf6b64443\",\"ecfa9ce3a5a37d15b813065e8a7cdf677a0f493018e47ce59815443dfbb9c910\",\"83e56d3337e1a6dbafdbe5a2502a84c330b1a328ed2860d689b2ded82b1f5c95\",\"e630f8a3c49d5db0a8af774799abdb8f19675b940a6cfa25eca35e5280709f28\",\"909bac92983e542dd29efcf9eedf4ab5a330767c70c505a52326f7f5ee4b288d\",\"a10d9cbca387b94d7d31330e44b9af8035331a8c5a9388ff7bea6ac6c547d5ea\",\"137a44f0f62468569f6cb54ec0ee289b9694bf6acf872c749f20a80bf9e5b991\",\"cc051639247f18781cd39ae70ae4606902fb5e7ea104c1b2a4927af5cfd05693\",\"40a5bb1733bb8fb3ffa425b92db062334f9b998ba8ad4390cc8008cc2ce701ed\",\"0cc48e862938eccfe92ba6c7daaf5fa144bbc60ed8d547c33dadeff1ab788cd5\",\"9e7c4846057815d55e1eaf27214286ec0768a1b463a4669e1ce37849b6cc1016\",\"0c60536372b6903323d2c1c95e9b7d1343e667dffb730007226499245481b240\",\"7119474d0a340253e9e1ef219ec97f8478203fa668714e58a5ee818f28631ed1\",\"c6d45af373d0c9312216472066d811aa099cfa1ed1976c153f0d06a4c2623efd\",\"b35a027bb203fdb38fe945b2d8d9fefaf7cb0dd0d5def1c83b900dceec353ada\",\"21d57b691fd32ee6e25d8e3636a0dc536eef3a6d2b17c2b94bad2fc7d4984c77\",\"150abc6422a16506cb374e767f4c26b148fd6b32a4f5314c21cee19089523eaf\",\"e625115cc4849c93391c298e23a6843b61052b984e43ec3579866b33da92fe7d\",\"54b0087a8523d0a289460fb3ac4b9ed55633977f2eb7e7f4bba5ff2c1ba972e0\",\"2d855457c0bafe580ac84cc88a12d41ef2daa53b3620fa7b668b0bc746dbd01f\",\"1f5aa8db4794fcddae21b728f556979e9205b70c2060ae32f30cb3d7ba90fa1e\",\"794d96375f04d39dc8513db4479a0023d3b8074b9738e38f7c0ac62d9696431d\",\"656b3a9ee8a2eb73218ccddedbaf412751787b303bf5b0e293f2c60443aeeb08\",\"e78dd7346725ac2d936a296d601e01f55eefabd010bee84cd03e20f55bd61a8c\",\"c67d068b46b9b7eadd921df08d61aa59bb6238b202ddaa32a22e9217c8ba7a47\",\"86fe8e0f91d25f8b32efa2765956adb5a66d375b2336d563ea6cba79f5914e49\",\"492dae861616e49ded6e82df7110868489b8f80cebb5f56bbe05bbf829f8a6fc\",\"d196a729c0ae94c27ca16d922f39fa633424a7d8fda45755fc567ecf2c7726c9\",\"e672c26404625fb9664bc08a5167bba8fddbcbbf3cc03ec01d6701fabe2696f3\",\"076472e9ee039c77985996c0a2cde3dcc96db4b0665a2a04d029bd916c1906ce\",\"7a887e5116279a22ec2040cfd1928ee54fc045c757f32f780529ea8d8cffe7e2\",\"1e47992f91186f9784bf4995764f00bd15372d7ba9fe6c732bd415baff87ab2c\",\"3c8ae1287018757532451e59daf1b969f6a9a9328ffca61edb180f1691c665fc\",\"164b2bc6d40e0e23fab13be163bf55221ffefc45049eac6bdd42bbfa2ba42b70\",\"b71b7186fe4c29e0f548ba350b4da320d83bc2ad35fa943d4a0cc6f88fa15a03\",\"7926f45e28be799136e12839665fe5a04054936c87202e4bb3215138246015ca\",\"4165eca67f3344524716c2818892d0330f3cfee91eb3f53eb9918c3de6351715\",\"6cc7b9937aaf140567dffcbb8cc7e5be37f159d2d970a6cd6029804bde96498a\",\"92d50ec4ddb64d487c7875f1228e210d3caacc906e1965ec3c4dd32e4030d1ef\",\"d8bb5f19f7a470a9d4d16be98766e87b2841ba18ad7fe3ea154326f5a01b339f\",\"3de03e5772d3171dee3537b5a26a6e687b1f29c57fdeb00bff8ea4cea5e2cf6b\",\"29db4a461345a5e1434379f551fb29e4a49fc8235f31e7dd7a6d703e10bc5db7\",\"486709c57cfd544d043356d4323a8ec01fac74c17339788cc7892c6f5ad96137\",\"1e434bdb7961baca128646c8fef458dead8fb5fb07e045b893b16288e36051e6\",\"60f0ea704b15210f097886213221e35d6dac30b246d5daa90e6772a35fd67a7a\",\"f369dea98bf5569c323f39110018bc30696595504922861cae1522918c9e0701\",\"2716ae07247d93af5e7b9ac2bc96e803f9c294c786763bf4067a975775eef32f\",\"64784db50ecb6a5ef3e593a3b5d50e36057366002731117d7f62a586d089cf3d\",\"91dc72de609fc31f6b5d86741abfa61efb70a56c843e160182a5bc1a786d964d\",\"ba2ef6a6d7a14889c74af720a62b9954acf4cca59108bafbf3dacfee5745a432\",\"18bc2b87197aa9e669883f1f84b8e32b7911a8aa2aeaea32c3a441a36dd84518\",\"4fd346095bed1cfb30362b6209da2dbd5534a27f49ffcea8e9df14de750fe8e0\",\"e3c9d8274d395f82be6723ff3bb054937fe4f7303240f18c29620861f8c3c12a\",\"a7a82c9d00d823f77d4a36825c13f49914cea5120ba301b06ab2026f10c4e9a4\",\"3541ec2884b8ca7517ce60c453fd73c8b44ac57e6e6c511337fd24ba9ede8561\",\"70a29119482d358ab4f28d28ee2dcd05d6cbf8e678068855d016e10a9256ec12\",\"869ac759ae8f304536d609082732cb025a08dcc38237fe619caf3fcdd41dde6f\",\"0ea900fe6565f9133e06bce92e3e9a4b5a69234e83d40b7df2e1752b8d2b5002\",\"e5408f95ca9ac5997c0fea772d68b1bf390e16c2a8cad62858553409f2b12412\",\"3c1332a48695617fc5c8a1aead8f09758c2e73018bd139882283fb5a5b8536a6\",\"9260b03453970e98ce9b1ad851275acd9c7d213c26c7d86bae096e8e9db4e62b\",\"083838d2f5fea0c28f02ce67087101f43bd6e8697c51fd48029261653095080c\",\"969132719f0f5822e669f6da7bd58ea0eb47f7899c1db854f8f06379f753b365\",\"94ca5d43ff6f9dc8b1812b0770b761392e6eac1948d99d2da443dc63c32b2ec1\",\"2cbc88cf54c50e74ee5642c12217e6fd5415e1b35232d5666d53418bae210b3b\",\"ccb226557417c606f8b1bba85d178f4bcea3f8ae67b0e86292709a634a1d389d\",\"5ea98f44cc9de1fe05d037afe4813f3dcd3a8c5de43bdd7db24624a364fad8e6\",\"3a1e3199054ae95161fc6a8418ee28cd774f1a258d1b0ee14aa71c48a1f8448c\",\"0b3fc2d2d41ad187962c43cb38117d0aee0d3d515c8a6750aaea467da76b42aa\",\"ed219f328224100dad91505388453a8c24a97367d1bc13dcec82c72ab13012b7\",\"6847b17c96eb44634daa112849db0c9ade344fe23e6ced190b7eeb862beca9f4\",\"d479a5128f27f63b58d57a61e062bd68fa43b684271449a73a4d3e3666a599a7\",\"6f308b141358ac799edc3e83e887441852205dc1348310d30b62c69438b93ca0\",\"116d0e80d8014e9a290850567e06c1a27e50b87cbf899b4c22d44a1fb9dc5d37\",\"c29b40a4cf970e5265985793c53e2f320691de66e45c68295231558769b9acbc\",\"6dedb11e905cde893a2370e482f52c9b20e7fab5497173c08bb69a083c077056\",\"a12a0a356d8f4e764f33915dac4203e1bab7bbcbcff8897fa0bb5805c0d1da8c\",\"40c3e3db2f1b415c6e8e0e60f4c7079f00eb59a870eec48d71640a89d171a896\",\"2db51435a699cffa904e668db713296300103eb68eb4c7b57d9175673290c28f\",\"c82774c75fd8f0a8453e3441a3a2df817f5db8fc2a7e0d5b4025c447715cbe23\",\"3d196011008cb35d3d6bc62f6e8178f4bfaed6e03bc2a64bedb5fc7147ae958c\",\"3ec2a1975fbdc61c009566ab7142e5dd92945b407443eb73008a6e0f422c0a61\",\"00e49e2d9e77c247cd6856f1708e4badbef3922c420843feef3a55e5d9f13ffe\",\"f12456857ca9139b39c29141c0ae6403cec08649520890b5281c181e40db8244\",\"f0facf58f98febf89a1724213686c54f8881a73dc059acef5fa5a6e770243274\",\"709d1dbfe1c9c5c689dd91dc9709737e876fe83372f2608c2c966a1349b5fb18\",\"df53e721f2c859b8dbf999ad123dd7b426db3a01ca7e18796024e0be8dd7eee1\",\"957a814d65729a44e20dd014e34dd899f5d3f9bf5490c15641ea4fe33ac8bffb\",\"2c947d51aec4c376f6777aba55cf20eb662a71726d6fa5238f149faff8c46b99\",\"736193947ff3690ab548ea0630b861238ad30b118a68c927f5a45afcecf76ec7\",\"56591e2e884fafb673887bd4ea4522f34e247cfba483b0d5732c1c4448e2d97b\",\"12e7fd4b664e48bad66ef64e25f4321b9997ba07ce7dcdde735723a2cb92add3\",\"4319b3a2e847c8ae162c2f43ca16eecc9e2fe012903d03170eb26fb62535f488\",\"8d1b1b3a5e21f45c50b9e4d81648617350f50713da05ec5c53c42be53de67823\",\"cabfa66e2059b7131d24631cedf2c148ef5da81670d7bf043739a4594b0b21da\",\"2ad698fc4a0281c8b8960710163c186e271942b75eeb824b4f52d1f9c18b2b22\",\"45d28611d4d9a75ecebbb01858b6e358da4aa43e643914bca1f87fe1d1cc6c80\",\"3a028db0ff8a34cba2e1c210578069ecd008337ceaee69bbbc86c12473d89414\",\"ccccea50f620b1e56b08156724a1a94e567d45508d31d39254c23dd36a94f7cf\",\"ea495540dbd5923a56dfdecd8640a2ae184a6e46e0b7bac86cecd3427a7cbc61\",\"cbad9dba1273b88b6ea2607fab6b75c720c8848acb245de96eb5d01c60588c97\",\"6da586222c97b893743b885bb6277102a2a6e5b0f4e8577e3ad18bf43e1227e5\",\"91c4645551e8280a1d5b914f4fd98cb4ee1596a9cc6f891fc648be34702c3871\",\"c48e28d82c22f46175446a0a9bfab97d8b4d0448d30d6512356fa726d8613003\",\"4e001356d313995ba5d22c5877adca17bdf286079fae6c0601f3ec46e86bb7b3\",\"e9aa694406c00009f8bb4a8a29235f219b5cb81c34184bb3ee957764918aaacf\",\"7ceded6b3ee49a6569f7a5df3b18a67694e6624d31d83ce8cb4a4f487a7bd1bd\",\"d5344b38ca0ce6978b1ad2e6ab96ca9370573001dc12b52f3faf2f117b15258c\",\"f953f02c90bdc74889f383d14d3da77ad53d7a3356b144b5e9b13aff44d6762a\",\"070aec45444ff31c6c78e433f76bb20a2f0521a0ecb99e37a96e47b7a39e4c59\",\"8e64669869b6e1b5cae2b7e2080c6a0309161e465692357fe19f8ba32bae782d\",\"e44165a63ebf8f093c3f2174caa6a7e5acf1170afa71585afd747092bf0393f5\",\"203ca4bb190e0c2f992efc00bb40a0a7e18ffa1815332b6362c0b2a4eaa9d50e\",\"0ac3acc6c90dcdf9d3a0d930584f6956d39dda76dc150f9867dae347c01fb1f6\",\"9a1951b0694be21f193c8ee78f598eb94a43ad93457d81ad3a91430cfabb7340\",\"c8fcde56a1d77e75bc717fa955bf3599ef56276b3ce1a8d0d59f336960ac8a1b\",\"70f694f85323a0f7aebd36116dcb9aef2d734e61600049a04b63ff703fec507d\",\"7caeaf3da59c1edfccd64ce89321bed55ac4305e08d75d7f9303c239154757b1\",\"597b2da170ee7f119fa3c5fb3ae12bb1e53b9f680f63cffaace97e8a8bfeb96f\",\"d5ff63e4a2e3d6acc7d6745a127bbe3fe83582d5ecd6c38b132c95e0972a146f\",\"a0039d5e07a8547253df379605f359df34d2c15bdb18e05c68bd104840811076\",\"88161201850a32202212dedb6883405313ebf7e88f1d8c15e5014b39ee9a0078\",\"8e11aea6c1a377aa188ba244cdb09ed2ee0484e0c51bd8fecb84157d95b2276d\",\"ebbf6d898eba4ee0c5f56643d9030fb685b06b3d2a9af30c3cab3ccb26bf4455\",\"dbdc1a1aa099ccd56afa36b000df3af56a365a2e098cf42acb3ccb5faa3bf00f\",\"17bcf414ae62927a0208af02a1b7744a4e83cf060d32ad4755ce64738d61b69f\",\"8227d03878d91b818065aec2a4cbba98759a3efba65a2b19138e49d716e5a5a7\",\"7bb82b75b067252c50421e2e6df14409461daa8021b0bf8445de19bbdd3edf96\",\"de22662b7c70dff9ef5a9c84bb392d67b044a160fe4cd7a12678eb2ab2e99cb0\",\"bec4e539bb1da6e4466e65ed565e2a95442ce67ab16eb416f1b12472cc7ac479\",\"eab40a2564d526742a478eed31b5f38719f27be17b68c7e6df96e06df1a1d0ab\",\"651e0baa0dfbe3d32026f14d2e143e68c328d4a54da7e134f1eacafd121b8447\",\"d4de6aa7918b76f00323c238bd2b60c505969546e92edc311f12c1147b223a93\",\"b56fafd88184cde2ba20bd2a1fa26a0a61440df3705dd29ef241aa148f8b6952\",\"8767dab6669e60b6263e95561c8d8f9b685fb132ef39e1439615e39bdc6f22e6\",\"b0d581c82eeeb1ad076442b263de5c78485a8911f6e3dad5b382ab4d81c9251b\",\"2541869881525e60fcda6c1cb5fd2ffd463cafa784b3a065a399a148d49796bc\",\"ee3ec95a69cf06584c2c6e6d9178b2e9099eef7672270d8ae7d67f7f952814cb\",\"bd7cdc04f8b60d831b7292d8abbd95f2ce2b64ad558bffcce61edf1f5a74aa54\",\"3d85076a0c33d6f933ccd3872845bc4add2c4aaa986899a7219ac365a1a47673\",\"c37a891d346dbe6a116084c8fd72d3b9618048f3db641924ec62ed8004b579fc\",\"62fb099143a678b45cbc38f1d9d82fd6a7159064afbc5ecf5421b10c02a3b671\",\"1556e31b98321494a6199e496cd62cf3939644a8069b72946e5355ff9973e68c\",\"6642dd46b3c5f98fb8e712eaa2d8860cdc7008c47adce3de3fb151673f8b5df8\",\"b5e25bcf725731e226b0dffa478559aa3a1d9ed7565e7182019c82df6d089ad8\",\"6eb449d224a5765991ed3f00da4a8e365f7f4744011678eb4468752f49c8ff55\",\"e8b5997569d17831a58e5998b1aaef9ecd16f955036ee939503b02fff0023acb\",\"069067d4b266b4ed33873c3150278d975eb35ccce76713af351b5a58e6239523\",\"efdf0d918e3a873bac075c295d556b1b3c255614a7b8bb18d9371bf2fe58bc20\",\"e750c528779acfa867a986226f44d1a48ad9655f7ad16776164ae0b244a246b4\",\"761fb1b26c4881796eeb34be3c221b4f95ed45cb785dce432fe768a73057771f\",\"7af68f16d603beae2c1facfbdff0630d931484316214dc5a916d7b0cd9a9458b\",\"23a587e27e52bf7690467a04d758f56d352c19cd10390d9283873c4db2066600\",\"e80705540f0784c8b1bd920235c53da00de702f53b285640f9ed0add0d352141\",\"75e45e1eb92b81dd90df2b04f0edf98027d2509850d7ab1afbbb54a9812ad3a2\",\"8f95a1ca16757c8eec472a99efcea19fcf2612825cb8fda75c1b38609bad730c\",\"98f99c3ac0ba2faaa9a315645408eb2080ca1de91c73c0333c8c2b71ab1b9e10\",\"742cc88fbfd1bafe5daf719e770895abd1d3bd7f3069e798831662bee8f34325\",\"bfe1f72d72a2aef5aee49721a7889f964725395837ad80d00ef000945f89c93f\",\"100c2f9b11a935eda58275950bc355cff48626ea207ad6ed77eca3e2106f881e\",\"f577fca4c11b0e8ac24dcb85297d9a93d022809f7ef41ae56e7f3354ac3836de\",\"bc27d1ac93da39bc492aa8a5d8763a40371ce0b684284c2012d68d38b5c2d7a5\",\"333abcbd774b67a3d8cfc74010b6dc4dcc81566234845390c164002ebf654957\",\"196634c2c59c0e622c585e27fef52f38f53b0d580717880a48038719b5bea316\",\"d3457744a704a869417ae2ea3fa370bb7702b5cea469dc66ac6d2f13bda86bef\",\"cbcfc1d0d791ad79e3ce63af9a28a4a97d66aae07c98067f79eb43d4ac1f21d9\",\"09ea63c4bbf3921b83df91a5e44b7525db030186cecea14828e663479c9ec721\",\"3191c985ef62014fcf6bf2d9ecb4d388314be814c02a1f2e61e51258b0492b8e\",\"91543bb08a8b3820b0b24ada224157d9e5296412584792a7e2b4665d36cbf6bb\",\"4b64ab1c145bd2e749cf86f375efad1a176fb87c0a81c6a075a3444484c672ff\",\"c6418057a57e24f0e7fa4a88ae63bd12ed7fbec9d0b3fe9183dfbd18717b7a07\",\"1a19f13c461053526e49ad5f862dc2b7a654952a538993c5758b751e681afb64\",\"61697bf787400fc5a52ca0245be444f5f9bfe4caf9555f5c707af72ee90b997f\",\"febc8d55f3c59aac614b16d7e20d3f4db021533af1639fea45c724ed51d6e1f6\",\"57fe0993a42c115793fad9a53511262f93164c6365790838a9eb1b1c30d90ba9\",\"da8f5f86aa98df54025cadf424f156ea22a7b10fe44dc13877757ade96231fb0\",\"53199d721ed05ce1587ef264709d707f0b9de9164c218d01171231f20153a4ff\",\"a92ea4c9b6338da2101ef4a6d48f1883ba6001882205cfb80e042315c5b526e9\",\"b2422a9563aa6f6801467c55f5afae0649efd34462b96b7d0ce2b66d17a6756a\",\"6de2a81407e9c69353987762afdef3c9ba65c1a8e676f5756413977e63feb57c\",\"84ac3711b2e2dcd512289adaf17cd9cce9e5094c3c2aa26e170a00ba2b868461\",\"9d03902e555324be467f26dd785fc2b5d7608e73c891941f8edb9902564a58f4\",\"20ed7a6271fb28e9aa03650ae159c78f19aea8f5bd40ff7b8f001307078a7a76\",\"7c43c2d9536ac21c2c1ff9157e54c436668acc5d427246149232cce7ba4d4f09\",\"3a8b64fe252b2fdf73c23366022fd1e3de9122ac7ae53359a200b695211476b1\",\"fca44252263c04a11024a21dd7846cdd8015fdca04c8e134670bfdfc2159aae0\",\"54333fc8dea208903a12eb3a2eb90c96a85d1b2b48ab0eadf73f85ddb288bf3a\",\"31b85cdf2eae65dfdad0c9e8a37a97d5e33a9f54aae3d5888b07b19a43055cd3\",\"5f351b90bccca19a363993e23b955389c662e993eb39838f93bbac69211d0154\",\"707b2628af532dab1b2cb276810aa5f7464eaf6874fae5d7a325243a7eb72c20\",\"954d8ae14048dd443054894b3a04fccfd668d00df26ceb898c8157f3dcdc4b9c\",\"f8f26916224f695f8f09da6dc727ea28e9b1dfbbdc0e2430c8c87e9c026f0586\",\"448adb291d55fce06d09c99fadcfeeb7c4e68bd21cd0ca185a920c47e23ff697\",\"0d81ce8f3f8f21533d4954c0b5c47a30b67d3e2f4cceb6bec171f4c9b10480b9\",\"aea7ef3fbc166c93a05b45051da09e5f696a02db9f807fd5fcf2a3eef114320e\",\"5ac619782c83b8ee4ea4b958e2d26e5df67bb6166ea39fd55e7f3586eae4dcbd\",\"e648cc0ba42b6f18788088a10757b89e33ab9d308df3a5cce8b8e7ff15e2b22f\",\"8e00ca1bdf7a90e43b84a473401e6d29855dc34f2186bd2737c4176d877d179e\",\"c1b3ceff69c9f834bce028e07c45152a8f3c92ebddad5011427b0d6e11587874\",\"b96bec9e77061e5853b4fa63d6ea8cf4250773702676e300420b7735c34f9901\",\"5e91b06300a55effee484ade3afef7959c5b7d88c5c099e75ccdbe4fdd152cfb\",\"61c07905bea1e63d21ff444167bcf9f0e390def2594627a1fbbe2a9677e4641b\",\"7705bb666bdd4085a9787d5c2ac6b23020b3246115eafcb4f453bd9c1448edba\",\"30688eab034d1aa3bbe4d8f2c7f462ddaec9f30f1a38a306a4728a9a06a58b11\",\"2217ae539f7c59065b654206f44d4f681d38a5039ba6bcf4be8d8d40afe5f537\",\"f4d43aa1331941b39fa38a255a16eb8855cc2926ce02a73cc06dde067c473900\",\"9921f71db289a60c25a161d036c2885085cd3f06672d9913b37342333993cf3e\",\"a11be745973acc0346b8bfd052e2693172c6b2f63d61fe43d27edc605baf9616\",\"9c951ac943d835e83b7774841625b44c2a5a6f0cc8b804f30b24c5a25a44f8ca\",\"f75ce377d83090f4180590fe78c9431b3d9bdf494373f0418c58e62937e890c9\",\"bd66d12958f4fe9cbd391d9abc812bfe6793cb5229d3c87545a74881dc3ec818\",\"f5e2e8a5acc9b5038db5956d10071f725422f41834524a9752ba7537a19b257e\",\"2ea50238f239ef3217965ea0a5ac6ffa2acb94bd03a912e7edae4cdb90496b16\",\"e82f01d51ac6d7fe5a4aa92d42abe67249c17c3b4bb8aa71abe6c2fdae1e54c7\",\"afa60ee9164efe27fd39fd758994eb8537459ed6bd9c9f0cbba3fa75a14608e6\",\"7d417f30f3db71a32c4f7513e80681b7ac9181aef5b8d33625cc96a533cd38c5\",\"d35dbdada2eef1ea36d48afa970f108f0c346516a9229660a8b48cec9b74995d\",\"0fa6899ee1f2be4f6d8641a444fbf598af4129acf30bce77f27466b3d0a86cf6\",\"c0c8c2902a682290fce1fb42d94f4f9db3ee09bd1797289e5b636b2b2f1317c4\",\"e5c046694911bbb40b9a2e7ef94e9f9ef681df18dc26ad7d5558e9406d2e4cf7\",\"fa7d28cc714e9d5256d2d5d2d7895a85e5db44987b41cc39f047598dbd3e3fe0\",\"64a6b0d7cc063f53f242f630935ba001b5d6906328466c5ebf6c7daebefb5bbf\",\"6264dbd99bf7baf85a6d215eace6fb1307f3d3df6464dcbef84f50744516608d\",\"057dc3da750916d3983709948a7b5a6ef9788378d38a60bb7458b30f79101800\",\"2fd7cced404fed3ec31b730d7cb8dc8a2aeecee576d73a719ab3be8d5f5d41ce\",\"349abba9835b8eef131b9e084130e20ecfc2a4a5480340659f0235a034896908\",\"9ac5c75774da8cdc4d6e0a7ab1a775a00e8f8b13d26c1eecd13230f3882668fd\",\"1070ecda3d1cdfc866df5e21173047a27f0578103362ffa24081b9d26a1de794\",\"650f197ae461ab7dda0b980277b8439951493e0f654dba3f81cd5fb75e65f884\",\"31ba7047f9570c93a5fd3d9264cac8e15ddc83d28f79bdb52fa55bf864c409b9\",\"2ee74e25034063383c1c0d03fc49e6451405241b0596d074750aabd4325e07ce\",\"1a1657d991b048a8ced17278f8fc500374a7094530b6f648e8b96b8ce7d1b66c\",\"183e0a4b07d3e6b6715344771e5a4e73e516246dcea97384e5349c42691742c8\",\"3ff0ab8ac69e2f98f671cc151c890b4d9d4d3a716785416c6c68bf4f3b163d15\",\"435547ade7df6de0a3cfbb2c4b925b9d36f84568f3728bb5c05b6de41f228c08\",\"0fe4061cfe1eab8c542bbc0b2cd2c203630c5de51941d8b8114c4428505d6135\",\"103c4a718e8e0dd8cdc45f7b565a29f84f5c66d8236c040582785b9db2484355\",\"ad91a831d9b7e2434d7f038137999f4675206f8f595f0e68b4443a089b357cca\",\"ddec19525a3a6d2d5128692249af3ff927989304aa6850a420cea5d655b80ebc\",\"0f1f2bd19722285e46efa6eecfac73477bd6e9b7e2ce4c94063fdcf457e5f48f\",\"5bd3e4d7623ab6130114cfe8393fdee2d902bc78ca840443ae8e205b8961e0cf\",\"f65b67af065b6e88888ce795af1e0d201276d21a8d8d38dbbd0eb5432ac0cab0\",\"601d6bd5c983fec28baf7ce27ff7fef77b696d5a7df19ba42f58961ed037186b\",\"1283c26efd1597984ab5c6e9c3be1fe9546c5d61648a73c7251b5d81c0b9e153\",\"b68e17021361507cbb11a8c5b1d7291c28e5f97a3a7c24520026b57b37b88629\",\"e94ff61f3c37cebe7bd248cf511778d06ec6714e44f4f6b2cbd6b27f7ed53b95\",\"66a542affaebb09a0909678a413e63f7a9fb875297853e6be5461e40d7eb9909\",\"2609c35f3d947adebe6e486d6d8b5e7b2864a80bb99898478b6fde940ab71e44\",\"33c104f72b69cd455efed2aaf9e993bbe871823743538560692131b620b9b540\",\"a66349a9c6b3f195c510e6621a6aecd4826a0a98d3d5a8b20a7d748eb8263ccc\",\"892b371df653d6787b8449e611c0206f561c3bea8fb3e41eac0a6570f43bfed2\",\"924c680fe647c2cfe4ad3944c84c9b36726dff2aa38f87340f56cc2a92eefb06\",\"788dacfb72816440b160221ba68f6b048b5c7f4b8a9190e8fe6b35f1c9e99f61\",\"6c31318d3e0c181c9b859eeb8730701e7942d521fc9110873c6a8210ed9e2464\",\"bdba09420c48524e7cdb180ca9a63f7cca6781f09826056ad2c023de8a4540b6\",\"5d9aa25744b6d7ecd29738a79523e2aaf9205ce94481f6fa26fbac63b12c8f1a\",\"2586e841e38c5b310cc5728a2d56c56b47f4fde386410df801c01507594a05c9\",\"4c17c33c33b043e950a9cbd7da1640fd12b9bdcb484eb76e4bf346a11c35e18a\",\"df24accdcf6a15915053cb96127f69f7d29fb7286951d58d4b8ca9361f8bffd2\",\"e30ea0601f5904235d46202c56913cdaa08140875b16d75093f8238ea0895caf\",\"b37f4f501b287c3e8cd36e244c6a25e1c663b4758f82047a4e4b09b349ff3979\",\"679c5345cf9eff4a5b7f14bd5b89e4bf13d75ade530b8ff8fcb25114b6747ec1\",\"6554423eee77326ce78a2c25213005dfa3f8a0703bad5f99182e404623000987\",\"2cb13bcb9a9ee0055324c4f92b365fe3871965780d70f4f5f423833a0c46672b\",\"2a412555ff316ca06ef90dd936584f7e3cfde321d9aab67c7dece93470d3ca4a\",\"531f7aab9b06755e06d996aee169cbd2cd206eb4a1016065200b9a8b544f08f0\",\"cfa161efbf2be5c56a49a25c92ecdf29bbd085e027a4f9c4d6dea112c01b013f\",\"ac0a84a5b1487392bbd89deaaf75e37ff97badb5cebc5b125816cce6c994dc49\",\"2d5f1bb582c3e3aa1c94755a93372f915c396cc68a3a87767b5648d8999a565a\",\"b972bef785abdf30030b19f64b568f7952b8166dc01ca4ddc2ac6919a5649a6a\",\"2ff73f906d4dfc23e04846d7e853863aa68fd14606a369d14d0ac23fde145071\",\"c9bf6475289573665a13651f96f3a4d935e63f755f1c66b567e20142af4739dc\",\"d4083eab88a986f2fcff672be3477a79849f25be3eca5a0fde6d745dac3fdea9\",\"b9d7f8b9ca4ceaaa58bebc717080cd9f504d68096195130271050786c680639b\",\"e65b61493d31153b25aad756d014579d88ea4d82ff4672ba53b523c545918a79\",\"cb41a8d1704595b290fb4bda78ff88dd45dcdb7a039003eedf7c4d50d0196866\",\"f285f3733702fb5ef2c430ca75ceee91c8c221a63f10efe55401b36c03ad8464\",\"d0e47a2e505bc9c18e2e9cfe7c656d8a343972516e35d05a905d4e9037c6bdb7\",\"81807c39ffddf0f980ff2c71b5fce8a5f57b6d85ee8f9860a0c00270f4b4b3ca\",\"931695b9c1db126cc04ebc9e53e30bcf5503cf6e846be941d431e51d677a024f\",\"d2d541552277aaeb140b43c1c158a840ed5fc004743311830a7802e8038daab3\",\"2f67d6611fb61f4aa056dc54938196ace86fdda2d27585f7dcee3205b86ba219\",\"6d86ebe5bfeafa959f1b1eec44c5412a065b9305d42dee581b5282e666a5ffab\",\"3717cf65a204081e3323d5592b6671cc5b1314a2d2cc96df407adff995f716f3\",\"774a0460e08fcfea8f89e6e030974df7f872ef1831c98c4beb129242a577df1d\",\"341ee4fd594942fb3b4cdec6897d0e0758e90c8e66b16edf296513f8115ab588\",\"95578ac9452eb3f422aaf44830dea4704b9f2144f05e88c0000d4c271a9d6589\",\"237e57570cc3793a9966c53c9b5d83f940f87ab197727cfb4b9ef854325aadb8\",\"31a12c4f4852605acf229c9c3dcc5d873fb17c93532fdfd8ad542765a172982f\",\"4128d4e6d5485d7b327fb5381d599014cdf529acb6a693dcb25a74b7c22867e1\",\"51850971a27368bcac5e76b687c81d9dd33c32ad93776efb1fea6010aeb664b3\",\"59bc67c98670c8c2e527f4bc135f3addc61073a9c86fd7db12655a117edd4223\",\"27ea3657821a5a4ec97f8904db29683d528445795af136a8c82c2b00df434d5a\",\"0ae415dfb5d523f2f40994716d8eed4399a63ca0a99c53adf341bfda84ecffcc\",\"3afa1cde2398e3081bd31d85277ac529e66cb78cba646acb29015133711039d5\",\"669cb574eb8b1b78a7bfbf772cd672a4495458fce3e3871c493ed63662e1913a\",\"dc66fb9d538514e75bf3750edb6648961775139c5917217cde4b071666e27e8f\",\"790cfcddd6b7cebbd6d1bc6e70cbdb92acf1b4ab436e5e5dad3437c81a51c2e8\",\"2bda98b9e0c6042bef86ba9098c5e150a7a1a4c56e2c4267fec821d99c06e345\",\"78fca22391d0029ceab9c7e424fea085ba38d0cdefacdd413d04bdb80974cae7\",\"c4285f0b817f5480a4ffe86a977980018dfa65b8918a33af4d8a28150be77869\",\"1de18fad1bc6b35862f27b59df19b8c18bc44679178b96ac0541ac275c1b9ffc\",\"d78fe5788e28252b6a1c9d0c09e8ba556064afe2ebac88b0d3ac494d723d6363\",\"bc5ce122aa88a6a2b5a60c538abdd43d2081f1bd7a05c06ee69ba07deab62133\",\"5e683802155ae9f4987b4cfb34064d14b4f7b5d7d35fc3769bfe2f5fff69daa8\",\"8a305d77d5904e620970e9ffa8f9180c06ca5998eafa24973048b65b0507e025\",\"61296e04fa2cb74b694d71d82fcd25416bbbc7c4decebf3e10d521c7fe27a976\",\"0b60e40f6a5f3b55a250d3269e09584d26ead289f387504de4198bfd8f0bea7d\",\"15aa83eb24e7e5de1979c6c269f48f078019b6909b49d178f5a599da38e5e8c6\",\"f11f9a1d67876a869d99f3145cc63cd1db5ef0034cdbef3930366d4bedbb4d60\",\"01846a047f18ea3c7bc9dc4053839960085d632d48b65bfcdeda3305e29d185e\",\"4ef18ed259b50434626c5c014f51c846649961aab112fe46974d34a8c1555d71\",\"92307dd94cfb0ac601d622976f10278624679021d9b4c6f85a45cabf99ff11d0\",\"c8db51a33c2c8da0f49596a501a82a11fcaf484e1c8564a3245e2dd9383a2426\",\"0b52548eff60d7b381e8cd32b4a13add2b624b58ee09ee92816ff74d66194e72\",\"69da9257d179f2dc2e1bacfe8852eb4301fff47b438930c1d275b949382fd912\",\"cdc3c58b626a97722f44154266a41578707308aefd4bcbbfb07649beadccbf49\",\"f56091a30aa030840992cd83fc810ac341c7911e9976a2d51bc3ac5ed8474c26\",\"16d160f0397cdb35f79a6d6eb3e2b6c059a0557fa0f67ac7c08b48eddaece743\",\"74fc1b18fce4ba9830abca70a4ab6eb42b064541f566f4460d7445ce08048e6a\",\"712a0b2b69621dda100e3beaa0724648c0c617b9bc70e974e2ddf77242b9dc65\",\"5fb9748f22a366aae8f1c94020c5b4687be9f63f5707475c262f535cc2c04714\",\"e56156d303b97504d313d87019b1fc9b794bb9fe65be0ba5d92b78d9d976946b\",\"2d107a101a7cbf697f722758f62d5ed250227d00f902b77c6c3d4efedf39178f\",\"a565ea5ff31a879c0d7d889591ed3ff47af47d5f882d0cd6c464c00911c80a7b\",\"cefbd3c11ff2a8d66c078d323f8f3394a4ecb324d05910e40b2fe15e324c7b9b\",\"d48133c28b8962eee96e27c4fb4732d631d6e49f608691c760ad719f9ccf0a42\",\"e23d352259fb0baf62376748faceefe9fdab1d03e48a9cce74c7b0562aaee25c\",\"dba61a7e471bf5151825b2db98cbbf08a697c8e30e3d3323c7d56066df0e7375\",\"d3495b28f188ca07af6ed2805c0af96cd3f971077ae3ee2322ad7a5bae556abd\",\"270068e563d8f2b2d72b30e4eba99c1acad69eeba293db0d45717201c8d9fe27\",\"b7e4785625d92f0b12ce9302e34f4dae9ad98149e6a37fba6b9789105a56c217\",\"03f71ab7ec76c26bf79e35e8b6cb1461192aee2c53dd934be05bd030a11df208\",\"44de21a271e7c10adad6275bb5936a4d69baa0bdf2e9dd5a46a97b31c3c15319\",\"ad58a5c0408f9297576a7e5e8c63189a0a93bb2b33bdef332edcef900ce04d48\",\"ebee18397576d0f8ab69feb9fb0cc7b43ad2f5b73490b1764507bfb5d92f765f\",\"9ee0c771688eb96dea9ac24adcb8ba5b2d048329e00da4b97c7c7e28bae863b5\",\"8c5e22bb09bb7e396fecbd16438342715a8f2f8d747a0b8264c82753fa610f60\",\"8e8686a68120655842b28c1cd6168ca934a7cb8031db9d2a760184fa6cea28ce\",\"864dec0508df24ea1564c279cf063a65ea9355191b9d753b79fb98b18a864661\",\"f964c8f47956ebd6790b5f85c753c3a02ed97f80428d458da112701efa531e86\",\"b8aff80b84648fe9d0f5e7cf0454e79861c953484dbab32e467012e4912caefc\",\"97c199f54a25929c46d500123ca918b6ca2bd3f7f391b834415a584e14519895\",\"1fdcb5089fe9fcc3a9870d120db60cc99aaa60c861a7751ab04e808cc8b41fd8\",\"edeacf69127fdf1dd68af8d3cae3826e0ce9d191943dd50d0f8090412296df02\",\"a86cbefaa20e0313956af4ad368cc8405c5b403e72b46ce626e232c0e387cfb1\",\"353e434635d5413f8cc0cc02dc014d2e80518dec03beb42eeb48edcefa3d19d9\",\"07e3033c5b7e4d1ff7a7c4a97f7d4a0d763d65e68b2f946086e2dd8b77627fd6\",\"1a5bfd7c176e6619f7c1435a5ee2a9c522666746c10e03d8266811d9f603484d\",\"0d6749f9522cdabea764e7e4ef90f36d15cce8d4d6a130d82de493a500495ca5\",\"adb2d3fa91ce25b3f0805cdf515ba577ee52e9b7ed906f0904c0cb8a94718a20\",\"0ddf692a51d6051318cf95b1b6385fc5865d40da66ab416b76c3e5a7993bc3e6\",\"541dce26752db36391695715fd07e23ab8365fe8f0bfa22fb1988040647f7220\",\"eff553e8f5d9a743ecd52dccd4e5fc9dc1ae0e3dda832721d6bdaff804ea40ea\",\"070372ddfc211ed2eb16aed6ef928a5d0de9da581356d944aafca691cfd3775c\",\"93c3f399a49a8f0ca7f59b77b20f15e2ea646d76dcc1aa67b016620b77dad7df\",\"e8c5583f4bbe3882c1ac602512d712778c8e79743726e649eee3f7fd3935671a\",\"73c4b3a6aa56bc60488233c6ac61971421b1aac371961304e7abe89df157b8ed\",\"8320ac9d1af2097dd0f146f5a61cec3188e1fc87c8b06150d56440a37a21aaff\",\"b2784440af239186fea1e9e8d79fe8c68a393774d5ef7e1064f7aac1b20ffe6f\",\"9831c9be2464a6dc0a47e32f15f4c423e169236ff2d76258cd0b4044bbfefcec\",\"32bf1f74a876afd0ffc272e5b3608fecb1da2da3bf29abdf0b63fb79a79503f8\",\"90acce1b73d50154590d12b572a3e2151c6cabfe08ef3b907fe5921454fefa02\",\"50bc3bec14002f6c484f88abbc40521da9397f5aff8f129aacb0f737ddf67ea5\",\"e06a8867a9a2ec503f9b8614734bb82e58824a4a2eee94cda1f522767993a973\",\"dde10b7ce7fe0f6b95044ecc3525d751f2c7afba86fd61d4d3f9f860a520987b\",\"030f27adaaee1cfacca3bfa4a177214de5ec43637e2e314c273adf7ee6151458\",\"750eb28a121bfda70e7c697d50f2df3363e9d9b2b74c81088bec2d3bc8d3ad68\",\"6472b5d726886eb4450f7ea4d781d722229df8e191d85f7a6f0d703b07c67bff\",\"7246e9b6d9fc705a0990e7a0b6f92e8692d9190d3f5aedcccbd597d5ff0df7c7\",\"d2b04e90889d746abf99b4c59486793f9fea741b705cfd4edab3d509c126477a\",\"3405f252f40153c837e2e7584b6fdf135dc22c7b0a94061309e608b213e9181c\",\"17ec62b7242d227e11336113296b088225da6ebd6cfd2f9f07bfcc9900b9cd42\",\"dff8f02234faac11ec1098f7813a2f08b95b37d472a8eddb9864c2947ee28446\",\"9a6464da21e25bc18de4b285b893c0eaca46a690b2830617a8ef06f96eef4aa3\",\"125ef4d1e5c1a420a80daa8f1b9871d9068ee684d304b38e4351a71ac04b8cc3\",\"502b5d9948de17a1358e68b9ac80dad58590476184f314b2e440d381aa969745\",\"085dbb45b93a4cddcfda33f5ceeaad53d4ae19ba7503e01d0bfd6f98208b832e\",\"bed2ed24c753afb04dcec65f7568f971d84362fb51fcac820e8ee1855ea76bc6\",\"1f222372836b1ed57997de12464e9e11dc91ead0c077c09520b48f81da40b9f4\",\"ba5229b45bf792e65a16d37f3cb86da8bfb1055336f50c5056c3f3da192975b5\",\"7c4dbd82e16b34a81804383b9c28da2cbfad04ed7882ab654056b58a8ec94ec5\",\"8d5e423573fa5dff24971d868f62bdea17b9b4d953b255b0067d312f02895ebb\",\"f939621054f14847addfa2e3017eaf4c62c28614992907200a497167e45333d9\",\"7505f387079b2b2d22beb29a517bb8e1ae68279ec7c576d122d24b0e3f27727f\",\"a8f7305348698c11d9a0fc1839d4cbb094cbf31cef96ee76bd883b0e2de243f4\",\"c29d38dfeaef89564f930868cb75f9f321108b70b0b1c784e168319550ec0285\",\"a646ab41f1cf62899a9edcdf7653108fa437d788767fa8d2b5f0ced7524ea21a\",\"401edf8f46652f4dd13a4358b011c8b887f43f80ea0c5f6f082048a622368262\",\"2dc0752ae058cc4f62c929b0b24866f65bccb221c2b1d8e9857ee9622b7f7b82\",\"3fb078c92a847d104bc0b710521baa0f5112531b436717bb16f37cf7e6882388\",\"d62a65c939304424b6d6b08ab97fb488dad098062c5ae90a64ce6e3f6b9a2af2\",\"cc41b83df5c3a4772e40d094c735b8e795eb73eaba597ddd07efb59a661b7f93\",\"fb607236d72aba12bf6df811ae50b7ac780a1ec06239525c5aeaf5be5ceaf3b0\",\"3ba14ea840bc8d17e5a2de5f0d1fea1b927db415c737bfeb2a4f46e7abe61111\",\"890b4f429929d54134e0e265d13ccd8828e361cf1c37c046bf0764a0bb22af19\",\"09db36cf75bc53cd67d8fc8722ad858df44503d3167b5d49825cd4b8be6f4076\",\"69254494e4c555ed797cd9ddab57a1b4393ad312a1eb6ce4dd164342f6cc785f\",\"5db512ef773765ace42dadcb265ac20a31cd6d8d44fca6795d75b3b4983d483c\",\"cc62668f61863e8c4cfb5aa7edf1c675af6c770167861148223f74d6cf4a52d3\",\"bf2881a9a7f7c609c2451abb06f759df2df99fd68613333d9815a03d06dac3e1\",\"1f826086c3b28aacf9de890d19004b2a308e0e64815d86a7f8c23ff37b3a814b\",\"a11253e1d20bc720789d85374a8f3bb2fb2db3d8dc50475017f1768f9adf9484\",\"c651b2993749b0e1d39dc5e2dbbdd662def0410ebf7ba683a27e1d26ea23809b\",\"921a77e8330dc53decbbb4dee54b81654e7567a1711984d6fe3bd7e8997af8b6\",\"56577c24f2d8711ec54f1f25a9c305aa6e778ce192b30c7c917ad2912af0a850\",\"aa7443532c7c4fa930709fe30e0bf642e4040867b0c180278d60cd04f2832d20\",\"2f463fd8b55fede3ea03465e7f8e6827ed6b735e6bfbfafd9176be6c80b1099c\",\"d3afb6e0fbb2ff982a1aa1f8192754d1fc26f5b80c9e1b79fd29f60a4c8ee4b9\",\"75f45b4569f64e7f8bb60b80aac8a4fb58c1268f6416d28dda85024753d9cb05\",\"1aaaa6952692db7d7ed9ebcb1aa98199632d378d02e28cfb0728d977559119e7\",\"ab63739e2f5354d2829ece988d74f377ffcfd9072580c43878ae56c20a15e12d\",\"39ef22cb2067a2b384a86e391705ea84f7481eeae0fa35d7be2545e896af3bcf\",\"b78d106f6d66731bf40b6cfc8d42c9c88d2f64b8b539cb8f65b97d2dee5d1a1a\",\"c3fb4424ec154c8efffbaed24c29f8295d603567570da0f6d16fbed0ff49079e\",\"f408fb593ad8b84ce2ac6040641475658060fc4c0efb24cc05804a1e45ebea88\",\"8af6a2bc2bc301fd69996eb8118a84476f294da0b1c6d3f811686cf1fc83c23c\",\"7be452a374be117cd1c563a9312a8fc45b46595ecd71411886fab30717b0644e\",\"ebc138e51212ed0f884ac5310237298c50b48d45b7902597f85604ad6851cff6\",\"7fe903d93d7eadfa7b0c41249c02bd805af04faff7c85916999420546dcfa3bb\",\"af357489e64b057dc99b7f42852aa61972d1db4836a8c284c88db68ca8d9abb7\",\"4cdbc6e2f9ea733c647c4f134b3707a66d7579455e2901dafb79f93d9127fac0\",\"d5148561c435367869a0e6ead443cdc3ebcb36cea7f35fedaf6e2bcf9865e436\",\"fb95417798d0671407f8316a4f8ac1d9ae045cf4a65c19c62201fa96b49d0e7c\",\"e5145766e9eecb5337255479b76c62ebe8adb7d46e8e23ecfe956b2795774ada\",\"89b20c074a5abe9208d39e7153ab01726c44a9fce77e9b46bb86f3cf4882ad0f\",\"5cb64c0e2918564a101a6445ef48121d2b7c4d4e565565c043db6266ec2a8d72\",\"21a511987dd4319b5ea9a3723c07c5b8598b5a3e0fc22c720baf74759bcac3e8\",\"3eea6cbdf32fce708775ac2c4d8dd9faf964a0408ceaa4f86f3ad2380b8bdd39\",\"4c814feac4977d0a7f3ab04c474079b022d653a9b58b11ad1e021f2abf6c681c\",\"b0c64de8a3414c763ade5430cb9cacb7de7026f5e0abc69d93b3ba9a7423af4e\",\"311cccecab649ce5438dfc8d891bb192fd9669fd0a58d9b8b09538978247610c\",\"c77a4380d0ad31b3191a8f46dd27ed85605a735590431bd39a98ead41c248eea\",\"8075f3d5502f29821e22b7df9c09c1c1f79651b43fadb00a51de0782adaffd59\",\"3d61ff8c2f62dc2ce2bccbaa8b25d0804b0af705db707162f790d32656ac0b7b\",\"72e4a806db5cfec09a48c5a87a242e6ac4d433a79413eb8cf0bfa9527f9dadc5\",\"64c249438441de30089b1cb2f59b8b6b1e735be5bbc5ef2c1c0aef6affdacec5\",\"abeeac5d26cea85669a4f950d633b48cbe945d151c5766b5570eadf50de95541\",\"e448f86b862b39e330b447215e46a0e16d92e0000144b7c6d7a4960ff7eeaf80\",\"e508b6ec6635ffac325b6347109743dffc0908279d5262907e8918819652d60b\",\"ac9492e075da7f2a119911a4bd90231f1802f05752c39c2af7ab3bc0ed54bd5c\",\"ffc7197b1581632257868a283f2c04159b5686ce518500dd58cde12ad64498db\",\"4f80b6bcb59a68c5b1cd388a588e20063a835471b37e6f66a5f479d557dc21df\",\"171792728ee2bad492204152640940a15304a58749b57459d49840afc9c4abf7\",\"945505221444935396d0f0fe2ec923900ad3e95b26456b32b3b7c60ecee71a07\",\"424b449c04ba8e623bed30672a773ca379146f015d5b669b220bc67d2b1e107f\",\"6a50c27254f43a06c80822a0645c0e8ec85bdf9c111540c6762a784a588c0201\",\"81cbbaf1089bc937bcced90dd4f018dd0c11bc66a234e06b4dbaf8932e86f512\",\"777b0681c7c1fc6c88a646f26b8c0f9cca1a6a12ee596afe86bc7a86db0ab110\",\"572a1f4ffc78bde699d6d6e3192d3ca8588ecc93d8f74a0d5988379383c19c48\",\"5edaecf61850e689c92168580fe06fe310b77280c3577e85fa937f4ba1986671\",\"9f7c544eb1e3e53559971fc5147852c4b7b08ec17ce5933316f0e64ad23bfca1\",\"8d824c8231d69baa4e7cf359412d9c42311ecef21106b461180e07f56008ad47\",\"dffabe54aff3652fe5bb1577c95c05326efc4fd3f768fc4270bec3c8434931b5\",\"ad5b3942fafe6c3b6cecda21965d3a4e7816f839f0e267e094c97cb6273c11e8\",\"0708f9a1cf32e7e142124420c19f3c1c0bc92be4158edcd269553e4e9164174c\",\"f40cf16f9b6d2274dd6ad83e0679d51de268548c2f4b3f64a7b85b025edaa705\",\"a8000efd37b9ce8f0827c6e7e662f264aa578685233961d3eed41e0f34ae59ae\",\"dc74f8b52593fe37c2a1ce212467b1e5c026683011cd6ee619961b3aa30af52b\",\"01a54c0f358c3c2f704c1cfb7a9d17d1c1181e3402cf75b827967a4880b06d72\",\"cad320f4e32a3f55ab3b2dafae2df2669b02c31d922d1ad7a59d1f29d2e9f3e4\",\"32bff26d5c7b3a3a93bdb23e42c2b75de24b988b9bc12daad8bb9b27c64d9911\",\"92745c589913abc8fe8f4bc45ac2abde83b3395ae2880570513ade6ff7e0d6d6\",\"98438cac06c378648053c66b400ca908d1c681309ad29256528ea0245f6993b7\",\"75a50890f1ba583165adcd02e72a62f68e733ed94e6919cb43f090fc9d049b6d\",\"68f33658a8c87c4f4e0bdf7d964173b95181f105d27156df04b45696c4ebb0b7\",\"4d641dde3104d6e9beb0ea8bba72ff4cfb420c2b63b132b42c8586d4ca2bbc22\",\"bf96e3cd8ac82645c19c2ff81770a133c75d54b0ee98086bed5e6acdfbd54f6c\",\"afb81ce8bb3e6de91fe2553d774f6a167cc1e5926a7be46ea8d5088e2c03e553\",\"2e2b8a0d9b0520bbe93416eb49e23f5d71cfec834d59d0138bcc3631db9fba70\",\"97181768db0a446bcea80e6449e884f6d68d85e324e4ea923b2c3c284ab7b80a\",\"c6ef0974736bda6224e3d6e2e8fc0062c41bf2d213433a9b4c625e0730852c20\",\"41a7ee8a48ace43456aac2e36df1b31900d21c0c4c1e1efb8a494f5561860726\",\"7ca5cbc45d37cd33c255d0911a1cf346f94a8c55f95714fa1db723e69367d3dc\",\"e536e6ab99bbc55c57f677ac8f845dbc88fc887dfd48addd1ffdca2a25f55fc8\",\"8eeafa5bd9bb629553d3279e21f56957ca9a1ee50f942dfad966b86346644a25\",\"2bc76065771be133978a14314bf9e0a562a28377b113852fd89e76406135dba9\",\"6236548a81d719390c5d221398aed6e21c2d0f49e76b9eacee2ed3c4a92821e8\",\"85f9a6b1c483960e7883fdf3d5d31d046858a0bbd518fb3b4fda1bae57e8fd57\",\"89c36d5078de736e3bb4b695ca9e2d412ba4242e13eda0a7d64ac5d2387b922d\",\"38efd2cadd1c34164c9b638cd4510d5cc4259bde4add371e5dbd2817ffc74b6a\",\"91d540092ab34ccef7b0e2d582ca2fd5fd21ec157e7fc9c6914438af5125b051\",\"79cd9ee099d926504d2c5281df43e3b013ed1cdb413808ce78c6c8e41a95ef07\",\"e4eceee438d823c529f596806842c342cd8620088d41ceb6b756064c664f3a08\",\"d0cd4d19b9355d54cf276bb76e2f17b18fdee83cbe25cb9df5fa2c38c97fbe88\",\"01e0566609a3d553235099361c083d6ff47767bb3ea8d6ab1cfeba8e26d06354\",\"9df4da519d58916b856971122d79e200f2a3be01fd2a0b4e2a556cc618007824\",\"4db911d5484d25802dab82385ef58f16e4c079db6bf96c844a65b8d3ceafc1f6\",\"f98905b0043d1c0ad988a9cc5ab583acec308482d2c31d31da84c0616f2f0d64\",\"4892d7383c60a6ceff1d527e84cac274c2a8e1a04ce4263b536b74c20f92f3fc\",\"cd77e5aa7e8355cfb68ed697b5cad13c98612bb068c63be0b7f103960a5b1f13\",\"291025a5b950003bb695197781fc77b2a1fd0eed93e9176ec6e1e6a21e195615\",\"19689d91927c6ee23bcf5cdd48f3c72f035518a5acf684098ad5b8b468a8902f\",\"53dfe63d246f0393ba95252485acf8591f2b0a97056e8ac844840e4b2ba027ed\",\"1761017a42df74ef2b3ef3764ca764d1b843ea377b5042c7828d3c81af498a94\",\"cd0dc8d94e8438957ff7774a7d492153eb8a4b410e0720bec3f8c45cb489581d\",\"27f8053a45c7954e6e515d8dc611dac0a2ad3cd541eb1a2230ffcae1236585de\",\"4c7e372a8042e2e70fd52aa2668d6e5b892d45cb8519e1d02e69417bf5494a56\",\"fdf174102948861a8c8af43d57e5dc6b7da2448b3470273d845775a6a0e9243e\",\"c9ff568e82c126c392a79f118b23cfa857188a9f96147d21cf83a28c5f7cd27f\",\"a3b36911d8bf20bd2f3e43e3b2aff8cceda729f7fca3557e469d5ef3f23f37ce\",\"a3ced15b4b32f451c16cf3cc965c9943bec0d0886c163ffdbbd6a9446004ad8e\",\"f65801b9f6ed4e95a87f2d86d5a1cb115d0cac8b63b1045d279275e39ccc8099\",\"f8d698c6794fc3c5116d9af4b75b674942947a58fb689bb9e93b30fcbd12912c\",\"d2b48ae1700a7dd8b1972cae53817ac1c4ad8c41d1d063848704ae5c880757c4\",\"8112ed22d19a5b06f52344e786ac82a34ff4f2cc0b76c6ef3e3e44d6bbc97608\",\"859e4844681f1c837d160cb1159e157a7c8e11a189c1265d0372b83c458b042d\",\"774f43648cb10a2b999b38750e948c662b79deb59996a4bb6b08e026e888895a\",\"bb98f61d5b0abfb7f8979a1334216da7c08a8e559aeb7c6347425a6848bee63a\",\"5418441ec6b92f07033180eed038b750bb80f1b4aef2dd9b5b6d99c6fc017c27\",\"3272ee1bd9d15f9c5b7ee04e78ad993cde0e9fe840cdb6745adae4309f1d6259\",\"6ee0192244f3dbccb01c01cdfc5e85fa034a4b8e39ca4f0e4796cb0651670705\",\"1491401cb59dfb870559cacad62ecf8758a4e48b67d761c746193d850348f052\",\"d43d918a425a086113ee6cc901185771c0052b9a8568fb240a1f6801e7d66cbf\",\"45abc27bd0627bcaf392056fbe2ca4356005fcb6ee811e54b3f85b28f94424e0\",\"c2446e2a19cae904bb71e0d8fa59f6c7525670e56dbfa3ac270663e3238d9530\",\"d6a50ecc2edc5c8d11b26681726b74249399eef9978f853545c099a2edd3b434\",\"935520c5fb3e88ecf473dc43e9f03b6c93b7b068c25929a89eee13db9c370413\",\"7d3f30d8f862a6d6ba8da4e34733e0ea57f8baa075f6f3c03969d4b91256a63b\",\"5380c75f0cbab7c65c3cbac98e1a1800bc09620e9650a27490e91ec2b8030f19\",\"ed455f5e991d93946073ebce07c518bb205b3159f2684b072bb79a7e9ab663c8\",\"0e055675b6b5a94b87dec7e15a632cafb639b3d43995a79ae9360928f5851156\",\"d3f03803d9165bd3cb740c0b304657adebb48bc2b92436b0e9ec4a1e6a14823d\",\"bb117ead947078490ebf5103088c06e89e9562df0c9c7956cad518ad01e95006\",\"67ae8379904c44490fab225a7caa7ae05a8e9a035e2dfd9e9d6a9154a684536c\",\"013600ce63487c1696ea3b4cf60f401cdc24e74d1b0ac836a0193aeec632e2fe\",\"fd9f34e9871cb72fbb2d79b20dfca65bb4d16f71891a8d621d6abad786a25daa\",\"019fa0d21ca411e6b08b439306a4b911e2c61e9f715b0e7e82f86b819ba8c329\",\"9c2faa7239c5785950d9852f56ddf2c66adc00f2279faca943ac6b283ae84fec\",\"6f9a80185e7aa24ce85b79ee9b70c3207c08fab73d23f3cfa09bec38efff9a87\",\"6a9f8f7afea733b1736be30c8b440d25a48b2d82dbdc48404f3f0ce1aa82038e\",\"ca9be90bb0409c07e622a4e03b968974c5736cccad75533c60fb14dcbec7c73b\",\"776ee8795d43b5763d3654c7b5c0758027fd1df812607a7d02bb30e5238dfdfe\",\"9b9e1ccb86c3ad50b74dc49830d275737f4ce166a50b124019fc319b2717cf63\",\"ec94d5d3a4f131ad79abfade176f9fb7472e6a8f202015bb4f7f29b0f0bf0e32\",\"fedf5fe5b4bf8ce15c159340e569317d15c8a198f8710a0d29821c32592e1a71\",\"b66197c2fddf3fdeaa76ed1b6ba7ca29dce2261a9b195dcc3318c9c6524a44a0\",\"80bb561bd66489e524790d47a287833179baacd89ae2b60532c7f92023f48cc2\",\"4a6e633741382a94045e8050c51a92b5aede9aea65d5cbb48005907ecd6701ba\",\"c942521fb4829d3a6d14630db343b8cb46b813709df918c65f2b643d11ed017b\",\"cadde74af3321fe5dfb348dc1d72e19c6a11475d990a2809aa8a8a0c968ff968\",\"bc1a6e48943bb9b281a229f3bd506e698bd82bbc6b110de14fc1cdb82844ca61\",\"f4e5eb0d5e2e30df899d343e7923d656f71265d32b6bf7f469d7207cb8e3f704\",\"af4220aa50c809f7fab954561da809da8a218c2d27dda489a64fb2d4ddf030a0\",\"d62bdde544698cd0023e13982cf5b588d80913fd2ecfb8ea2468b9c557df9ce2\",\"27182fce23c374fdf04959c90ee3153177608c2b1cd7468c60296a93d4b9911e\",\"261c41c9919bebafccdef0c501c7eaf7034258b3c027a22b1166cd096834556f\",\"7ac116a9a8c012220f82014b63dd744115d09a6fa83021f909c87ddac2e39cb2\",\"ae71cfc0629ed8403682a122f7a1bcf6d87a8e9033c2f1033acaa00c857b056f\",\"6231cded9a3b79d8a9c355048efed866c8eaeb4f2cd395951752cdab6318da10\",\"c6d860360ececa1e5e01a4b39fac1e9db8924627c30726932db4f7109f0a551f\",\"947c89d7df64c322d26c487b53867889d340824e2845c0d87d5504bce6532542\",\"dc538f7162e974fbf18b8616a20a9c6d084e5847a35f165d94d69255c20983a9\",\"e3b9222330621eac375f6bc4b52ea78c8469b4c94ae2a8b09fb1d1c3113307d3\",\"4485370e15e4376b92686fd39336d9027b26b371248e25e1cb2d0244e94a1fa1\",\"99e8e188456e5dc71e60d7790267772ad0f22e854fef5d40d8ecb48981fc3296\",\"b88c260399542fb51f72a67584d6390c0e1b68c361b3b927e817a57f93121148\",\"0179850287dfbfd1fc429e9897fdabf1e1094e80592dd6d5630a67e4cd42fd09\",\"4224a4dfccee19347a5743b7d69343b2a16c865c8734a605d28af4023eed2d17\",\"d1028283a35e89fde13ddb206acd55624f9eec7874df694fd185d62bbdd3a72c\",\"05034631dc7665c544420c87919787415718eb904c7e377a2deed50f174726c5\",\"cd2b5bd606dbef4a5a0d0ed510e2d53dac00f0ef92db994e1f72ce4525d918d3\",\"ba2151c63fe743790a29e9e8de924e65d5bcb4f51cff999b825afbaf135d592d\",\"2e51f8457814a3e4aa3b73ca27c14d36928a348f85c003bc3b1b8d8797cf0fc9\",\"c4cdadeb3aecf4031106c52c2fb782ba5cdcd7dbefd0a3aba2fd9850f8cdd478\",\"5f4a10115c06510164e18ac8a5b5db1f615f096a40d5c69726bb32309af93252\",\"58e3f7eeaadad8a3f69dff6a59566e9eaa15b11facd397e2b9e199fdb2a84533\",\"537b5657a19792461eefee12e406dbccb7b3fbbf4117e7a443e81e925f6e1b43\",\"c3be2a86d6ab205269fdb5f1da4ab6e7d825f8e119ecc235fc587cec2af2c8f1\",\"a35dd28e140a6ded634995e25fc6c1d1f85eb59ebb18c3afaf5c66de43972fbf\",\"be4bc9c39dd458aa3a993a48dbbfb09be898bf30f3276660b012401ebcc54cbf\",\"25b92cc86a4aa9b088a1abb16c60547951859d4ae12fc909e23d675e6046b4a6\",\"dbe50a407dca6d6143ac10dc3f4a09816ca2604788851d086e621d990eac1662\",\"8b226b564befbf10933d0e3c0f179c522aa024f1472022d9fe35a0addd6e17d1\",\"43d7bf6b658159db2ec49152852d3b25113b50ead0a0088564a83bbc30b5a61d\",\"4ab69812962d1cf86bccfd350af2e07ce74267e90071888f823e1402212bc100\",\"efe27b07f8f5f9dc29e2c64bae34e21c3f755895adb0aa9813733860d5fa41af\",\"c6ca120560597056bb69d12cf8b3f2e05aa15ad6cd2deda6f7b25ebad41b15ea\",\"0bd118496029e7bde27d232865e91eb1e8bd5f1aafdbd8365c2f8862c2122326\",\"8a9fac3501784d42eed037c9b3702a64e51ab0cf862c19a82851b712703e32ff\",\"e00aed0f8e5f35807d735a1fc5424e3a15fcf4052eab5cc59887006db55d5ee7\",\"3fd188ce8702e15ef258dbe0ce9531a311a8fad945343a1876c7bfd8b75c54e5\",\"c3b262ba6bf1d028b0999b6f2810930fea722787bcfb016997a28c06c82daabd\",\"e862acf7cde7ae3002960593801a2300f2b2f6ffdf70c8814b9ac9c0fa7998ab\",\"7edc3292c8307f372d884c40d32fca914a782ecb704c1ce3461db1f5402c99f4\",\"9c7021a58d44f73b69bf07728c24bc6b7968e9399ea91009e8065ccd72e13c76\",\"1ddf94976ed035a37b6e3445226d3974155a93af053574124e07a2c810e8f355\",\"7d19228684b37a3f0f926ae802498c4dc9a8e175e8f25305c74ab74e48644214\",\"b727fbf25d1eae6af35c84820f0190635114c2aa58bf41632bd75d35b1fb2974\",\"d496b86b371307426bf3ee7832c05c4c8f02c46af10e59bd77d57f711217d653\",\"213ffff1c4eab65acb3905dac82a82ffd8c3159176cb8683a0029510bf74f01f\",\"af560c1ff8c707db02ceaf6b3cef02a112c3d75aacadefdd16fd34d1b2229285\",\"e36bcb121675af7fc068f828968865ef82657106746d191225017bd714cadb7f\",\"4dbf0716499198a5eebbbf51522b2ff4506fab854e247dcccc781aafff70e277\",\"506f2dd82ae2d9db53d80e21068cb73c483627bb0ebcb8755e93921a2c37b9cb\",\"8955c4a967185303e49b5456a90f24f763caba0c40b0d3234efcff6e533cea97\",\"b92e949044dab0dcc4427b28c537a69cf12f6de0afd814bdccbb77c60c6e0c92\",\"302629b070c984735f674addff60fe67000150c2b1eee7f4e0b6bb774b5f2894\",\"1f5973936b80ca510f224b60f2ba970d166be8d8d6fb3ea203d6ad17b10eb920\",\"51972559bff9ee985ee8e675aa09e3a3be8b4ca883642d762b906f4cfebaf2aa\",\"ad9384c0977fcbb01f08a27c5814a2eaf997558e15eb95f5e1445acbe9504c6f\",\"4bd666bc780a7280a544e6897ad4878dead08d648b0734e460fb1f198b241072\",\"28caba7d9bc8ce812dcf2dc0d27e2b13fa12e75b2b83d3598be16ef3d10c5981\",\"6756086988b5faafb5b0f605f761cd13d4878dc0aca5700e62a79bc3ea6673c2\",\"d59622d42ea535480ca6946688a6eca33f69df94378c2b163cc88c3dc846e5e5\",\"3dbb1d73ed0a48d08c3efadef251705a0001668a09b7059f6f46f53d78b9dde4\",\"fb59d7942787b6757b5487815d18eea35197a15790bf237cc9c13e7f95042e5d\",\"a5e50584b9224014d84a17bfad354011db20c4afda7744d51e67ad65426bed6a\",\"b2f527d9297256ef42ec14997a44d4a8a437ffdb510886038562642577ca4c14\",\"d0660043f9daac0c1424b4799f8c7af49bdcfc7755018a512e5d51719c96ff48\",\"48e41db5807769d4b85c78739b8b718649fd78d256eed87e803239d88ec273d3\",\"837c4255eb9d91a850ba844e615145fa84b01ac3e781cc7dbe6867ddab33e694\",\"76106e67bb64a356c5ebda8161f202c6b64522c760a77d2602f7a2679ec6503a\",\"accd08571235cef22f637299d5cbf3b0b97ad6012d0d543df843be956a1d9fd9\",\"27fff93cb53ae9a40c88586558463d9a9565c4951643d80597ce4e2f3e1fbb74\",\"073b157e1b9f89ee0b8067b0b2202a63667d7f3a2d66f2432cc04742796a0c67\",\"9d459e023609e74bbc8da58e71d21fafd293bad7130da8fe9c12b2200750ca36\",\"3544b93ce1c4afc26e27889bc1683efb5fa96ccf470c8bb5432fac6111422aa2\",\"6d7180a99a3385df5c383a82d4ceaabeecc227fa83eb9c7c8e7edbcde284ab4c\",\"52d872949bec72fdbd43c683f2de8e6c99812e520d4242140cbb1def52077b52\",\"cfbd3062c931b1e325f9b3d6fc1ebd25246951a0b90267d35af580dc8048490a\",\"0ebcddd81acec871f2a6bb726f6611d367d5c4f6c2ad6ed46a5edaee52e1ecf3\",\"6d6d1b9c3cc0148d3aa40f3f87f6f616a38ad8c1b68b8151b866186a6c85798d\",\"6d754d32de2cfc04c15c77fbe0eda31a2e2e4886b2e4c5e6fec5e24a07d40bb9\",\"13431dd53835377d79adc5e6fb65642cae90612804d18161c6538a348b817c55\",\"4d6b3f10cab65e78389a1618ca68a5258a6b6d2eafc0f454190e011cc0a90d1d\",\"edbf50304ae52ed829961d62d446dd1e3f4fbda1f0e1db1c8934e05b3b73d3be\",\"7880a5552a9c6fe2fed8a970430085ae9b753d5778033e6a704fa6e0aa164589\",\"9c32dc593fd45d6da83ac6e7265247f13da9a4c0beb58f254fd78f97bd883dd5\",\"27e25e7fb2df5c76ce24a2cb6fdacdd031fabe665b4203ba1e8a82efd7ccad85\",\"233fbf69bc142b400afb9aa69f6289593936bc53dcfb464206dd4e65a4194f91\",\"4dca5a6b9792762913ae2a230b782b351405c243244c35ff0a938347144787d2\",\"fdeb952e3b3c6ac4afe4ed89b8fc547789cbb23c5f362bda24e9118d10271010\",\"c222bb29c98dfb69cdbfa98f24965defdda9c09b3ad754a76dfaee9869279191\",\"5b8125c2f2941ed289aa6b661c86302eb4afa6e22f697e82c8a14e058ed61b67\",\"7f6ee041490e9470a22c0cd293205083293c12e654364556bacadb5cbebed30c\",\"9fab50375eafcd42df96516b3cc42aefc6a4aa3f268e7d5cbbd05875287bd7da\",\"b8a6419ec42bf4d8eed52f187e161b7dee898c96faf691713fe1a4ae0d89234b\",\"1a0fc724d26754b15d02f70589e49e1510b5f031c16c0f36d033491b10e04e7f\",\"20d7df13f5c0f787c1c7c1c66c13e38f65a6ce33f317971868784f6687ea1311\",\"f523e2c118075521f4b6683c5fb2a0b3aa63f588df75ce094db5f4af7cd610da\",\"bd42e75f00e559514fd8c0f8b1efdff737ebfd9dfc4d420b7942ac8921530b6e\",\"4943549f64f3800b8517fbeadc03cd9ea254b9325d3989b6d0b8bdadcf41123e\",\"d3b6559df7ac0bdc2efc652a70ada0524a585390f3892e0533ec1f7a1ac8499d\",\"8f6157e68f24e1b405e1f0376baa6762216888df0fa8292ea7c29cac1705de10\",\"a273bb46ef5465ad1fe1b7bb5b1fddcc119fe788c4e73e226834a186fa052798\",\"a1af0abffba61d11fe81b8338e62f2b7f4e5ef73828a162bb380d9cacc54e111\",\"6c8e9cb096ddabfa76e8e9ef77977a44f39cf77f1c8309ab1398b822fa3f7c05\",\"94ba095ba3e0fc474c0106211ad66c7f6c19aad4d62af9427e38069d9c0ed3ca\",\"ae39fe36423fa67d1a7e1ad8c4b21e837fa15cc8d71b9ce5bbc8647b167bd635\",\"706bfe9d17e578e4d5f546c9b66ae83fc08a86b2e2c640597dbe3b5666a272e0\",\"f8f4cbcdd78975372b40f887fe6dfae1ed68b73e416319bbce7c953edca909c2\",\"9e7c4846057815d55e1eaf27214286ec0768a1b463a4669e1ce37849b6cc1016\",\"d1674a00918199355611c680feb06f169d1454e83ab35c467e5a9263cbc9f263\",\"b38058aec186ffd334c83b6657461d9c9b7c8d84c8abf404d8569520b1771a45\",\"760b1c23d10297af55bbe15ac83c32c5ebcf768d32b530ab66b85249f059a5db\",\"b7f88a8f6233d326148043be8f6124678941cbb3f21152229b4877d2ddb9de6f\",\"764dd6c53fa86e251de57b31a6a41eed7ebb8ce726704e6cfd44b67ca1275e07\",\"b80c780c52524beb13488942543972c8b0e54400e8b59cee0169f38d0fabb968\",\"d1c9f45a2401b2372f6d523471d7775e501401411c1ddec8aceb09e93f242c6b\",\"ec23ea828cdd31b5f3e5adfff57a611c80b2896e01a049ce6e2ff2a762868b5a\",\"a7d13f7c794ed9c8ffd5d3b78e720c3330355eed5b11a104d433146dc8e7b10c\",\"307b73411d5d5aefad6bcf036d154b5d6303ffb598e69952240926758e086254\",\"777b0513cea387c17734fadfb877fb05ea9f9584a7d18e013f76cbbb436d24c5\",\"10cf3bbb1f3fa03e8fabf03ad247ed9631d0c7591a1c2bf12e156c0f6ec850d3\",\"1a731460b5a81522bca63f1c4e3319e9d6518e0c2e1755233d7214974ec00cfa\",\"8e68a60d94268392d286d7869b14ffe93648db4f689026a904cac98bfcd2f55c\",\"a2f4fac4d986243ff1f4fac562c4c93bef390b4d1adad0dbdc21b13e50fb4fcc\",\"2e9b5de48cb2c347378bc6c04df6248e406f6bc363e546ab12ffd5f5377ad766\",\"5ea8401fb134a69d4aa33ea67ff7332e3bb7c846264031d14c87b19c5a0b93b3\",\"6cb35d83d21a7e72bd00398c93302749bcd38349d0cc5e76ff3a90c6d1498a4d\",{\"version\":\"369dd7668d0e6c91550bce0c325f37ce6402e5dd40ecfca66fbb5283e23e559d\",\"affectsGlobalScope\":true},\"2632057d8b983ee33295566088c080384d7d69a492bc60b008d6a6dfd3508d6b\",\"4bf71cf2a94492fc71e97800bdf2bcb0a9a0fa5fce921c8fe42c67060780cbfa\",\"0996ff06f64cb05b6dac158a6ada2e16f8c2ccd20f9ff6f3c3e871f1ba5fb6d9\",\"5c492d01a19fea5ebfff9d27e786bc533e5078909521ca17ae41236f16f9686a\",\"a6ee930b81c65ec79aca49025b797817dde6f2d2e9b0e0106f0844e18e2cc819\",\"84fce15473e993e6b656db9dd3c9196b80f545647458e6621675e840fd700d29\",\"7d5336ee766aa72dffb1cc2a515f61d18a4fb61b7a2757cbccfb7b286b783dfb\",\"63e96248ab63f6e7a86e31aa3e654ed6de1c3f99e3b668e04800df05874e8b77\",\"80da0f61195385d22b666408f6cccbc261c066d401611a286f07dfddf7764017\",\"06a20cc7d937074863861ea1159ac783ff97b13952b4b5d1811c7d8ab5c94776\",\"ab6de4af0e293eae73b67dad251af097d7bcc0b8b62de84e3674e831514cb056\",\"18cbd79079af97af66c9c07c61b481fce14a4e7282eca078c474b40c970ba1d0\",\"e7b45405689d87e745a217b648d3646fb47a6aaba9c8d775204de90c7ea9ff35\",\"669b754ec246dd7471e19b655b73bda6c2ca5bb7ccb1a4dff44a9ae45b6a716a\",\"bcfaca4a8ff50f57fd36df91fba5d34056883f213baff7192cbfc4d3805d2084\",\"76a564b360b267502219a89514953058494713ee0923a63b2024e542c18b40e5\",\"8f62cbd3afbd6a07bb8c934294b6bfbe437021b89e53a4da7de2648ecfc7af25\",\"a20629551ed7923f35f7556c4c15d0c8b2ebe7afaa68ceaab079a1707ba64be2\",\"d6de66600c97cd499526ddecea6e12166ab1c0e8d9bf36fb2339fd39c8b3372a\",\"8e7a5b8f867b99cc8763c0b024068fb58e09f7da2c4810c12833e1ca6eb11c4f\",\"a8932876de2e3138a5a27f9426b225a4d27f0ba0a1e2764ba20930b4c3faf4b9\",\"df877050b04c29b9f8409aa10278d586825f511f0841d1ec41b6554f8362092b\",\"027d600e00c5f5e1816c207854285d736f2f5fa28276e2829db746d5d6811ba1\",\"5443113a16ef378446e08d6500bb48b35de582426459abdb5c9704f5c7d327d9\",\"0fb581ecb53304a3c95bb930160b4fa610537470cce850371cbaad5a458ca0d9\",\"7da4e290c009d7967343a7f8c3f145a3d2c157c62483362183ba9f637a536489\",\"eb21ddc3a8136a12e69176531197def71dc28ffaf357b74d4bf83407bd845991\",\"914560d0c4c6aa947cfe7489fe970c94ba25383c414bbe0168b44fd20dbf0df4\",\"4fb3405055b54566dea2135845c3a776339e7e170d692401d97fd41ad9a20e5d\",\"8d607832a6ef0eac30657173441367dd76c96bf7800d77193428b922e060c3af\",\"20ff7207f0bb5cdde5fee8e83315ade7e5b8100cfa2087d20d39069a3d7d06f4\",\"7ca4c534eab7cff43d81327e369a23464bc37ef38ce5337ceff24a42c6c84eb2\",\"5252dec18a34078398be4e321dee884dc7f47930e5225262543a799b591b36d2\",\"23caed4dff98bd28157d2b798b43f1dfefe727f18641648c01ce4e0e929a1630\",\"f67e013d5374826596d7c23dbae1cdb14375a27cd72e16c5fb46a4b445059329\",\"ea3401b70e2302683bbf4c18b69ef2292b60f4d8f8e6d920413b81fb7bde0f65\",\"71afe26642c0fb86b9f8b1af4af5deb5181b43b6542a3ff2314871b53d04c749\",\"0d7f01634e6234d84cf0106508efdb8ae00e5ed126eff9606d37b031ac1de654\",\"f8d209086bad78af6bd7fef063c1ed449c815e6f8d36058115f222d9f788b848\",\"3ad003278d569d1953779e2f838f7798f02e793f6a1eceac8e0065f1a202669b\",\"fb2c5eceffcd918dbb86332afa0199f5e7b6cf6ee42809e930a827b28ef25afe\",\"f664aaff6a981eeca68f1ff2d9fd21b6664f47bf45f3ae19874df5a6683a8d8a\",\"ce066f85d73e09e9adbd0049bcf6471c7eefbfc2ec4b5692b5bcef1e36babd2a\",\"09d302513cacfbcc54b67088739bd8ac1c3c57917f83f510b2d1adcb99fd7d2a\",\"3faa54e978b92a6f726440c13fe3ab35993dc74d697c7709681dc1764a25219f\",\"2bd0489e968925eb0c4c0fb12ef090be5165c86bd088e1e803102c38d4a717d8\",\"88924207132b9ba339c1adb1ed3ea07e47b3149ff8a2e21a3ea1f91cee68589d\",\"b8800b93d8ab532f8915be73f8195b9d4ef06376d8a82e8cdc17c400553172d6\",\"d7d469703b78beba76d511957f8c8b534c3bbb02bea7ab4705c65ef573532fb8\",\"74c8c3057669c03264263d911d0f82e876cef50b05be21c54fef23c900de0420\",\"b303eda2ff2d582a9c3c5ecb708fb57355cdc25e8c8197a9f66d4d1bf09fda19\",\"4e5dc89fa22ff43da3dee1db97d5add0591ebaff9e4adef6c8b6f0b41f0f60f0\",\"ec4e82cb42a902fe83dc13153c7a260bee95684541f8d7ef26cb0629a2f4ca31\",\"5f36e24cd92b0ff3e2a243685a8a780c9413941c36739f04b428cc4e15de629d\",\"40a26494e6ab10a91851791169582ab77fed4fbd799518968177e7eefe08c7a9\",\"208e125b45bc561765a74f6f1019d88e44e94678769824cf93726e1bac457961\",\"b3985971de086ef3aa698ef19009a53527b72e65851b782dc188ac341a1e1390\",\"c81d421aabb6113cd98b9d4f11e9a03273b363b841f294b457f37c15d513151d\",\"30063e3a184ff31254bbafa782c78a2d6636943dfe59e1a34f451827fd7a68dc\",\"c05d4cae0bceed02c9d013360d3e65658297acb1b7a90252fe366f2bf4f9ccc9\",\"6f14b92848889abba03a474e0750f7350cc91fc190c107408ca48679a03975ae\",\"a588d0765b1d18bf00a498b75a83e095aef75a9300b6c1e91cbf39e408f2fe2f\",\"fe843ca244961850c8ef10e9c132c8905f40b5db8865f8096bf3281b089c181d\",\"011c1e6d5520e98859ac63a30546139f677d6bcdbcce29d2b684a471fab4d511\",\"449ac014c5b8093559db84b53f35728681b2694e31b64b440bc37fdbc7d8439b\",\"ac0ee07a92140d64a014bc3cc97272bd8e3629f8a5a383507ed90bc0e2b705f3\",\"fcc8beef29f39f09b1d9c9f99c42f9fed605ab1c28d2a630185f732b9ba53763\",\"21cfd01ca3bbace027f4e1407926a77668c878ba422daa6259b3667ec74bc081\",\"f7fbd57ffdb07dd247895edfa15c272af7d9ed275638e656d8488e96e86827b6\",\"6eaa2a284a5038d0f955a8df77510ce0d0d4a75c2c36b50ce3f03d3ca4f1abbd\",\"5c6907d6d785564c2f7825acb2e043ab36775fe3c1aa9f3345d757ba6035c560\",\"add28373f3633ed263db511d7974d9de7a3cbb4297601489c650ee0ea591aa7c\",\"d36b86989075dac65b2d6e513109f47a49d55dff5c5d19ffb1ea1696b4fc646a\",\"ff10369fff135948e1fa3d8511f7859ecdbfaad342e770d70121ccbde3cc5340\",\"4dc0f07ce5ed43ab1f9761e0567df52f3b7a5368c5c328ab5e66ba37fe56759c\",\"548d270bdee09e2438e97cdc0b5ba55e7b188d4250e5d080c5009cbb7bbfb8ab\",\"331875925874156fe9138ffa6819608675d6d4e6a0680cb597da030b3f943c7b\",{\"version\":\"691f5ee739e59e7214e8ee82d6d460412d15ee4e05fb719150f5cf4df46d7577\",\"affectsGlobalScope\":true},\"1fcb8b15db812281d69a3090d488903f9e93033004aef9d8889ca3ad0753a96f\",\"bdf5a95eb0a2dd1d39805bdf51b46ba012bb9b92b2ddaae16219595bba7678a5\",\"9f794a0e8550a03baff865a3961cc22afbd85bc4ba9672bdda036971928f85f4\",\"66a697d1e4cdbf25cdce4644a8085a8563041fa8c7731d4d9f5e8f22e66ba72c\",\"4f1ae3f24125216cf07c5211a3f00d2bb4782d7cc76c0681603f8249f9232ff0\",\"d3fb92a5640f83f7844d60b35317a0f95c27e3658a749d76d218c461ad091668\",\"8bc2cad630da1033c1fd8d7df2bffb18af0da6113bd086a8bbec04a2471a1e00\",\"d1f8bfcd91b284657ef8187c55ace7db91a3c43e642c3f14e54364154932f7e4\",\"4cbd412a47e9734c74d1e5d895652019a6c4204435fbb843ea30be1be617b2fd\",\"f97816e5e50a4c54ce155816ebff932709f77a69589249bf5134e44a279e9715\",\"277afd6ab6ec72889e2988e0ddd7d138c1f512e68a1fa4e90eedfd71e2097a51\",\"c0908f85f2b645d375127a3b53a17a65f782e17962d5c1eb68f08b1188acbf15\",\"c993f7ed1b8e1023c1f2ee5b262dbc3b70b27475674e40a53a58591f9972dacc\",\"3fadac5d409cc2f27b1d2f4e7568600f02840205f301c9ae7a3068b46476438b\",\"daef728543afe5b7408e01f0ddeac58e6a290e3cfc6965a8e981f8beae2ab29c\",\"3633f87c97d359cb55fa7bf0668fb2be8a23342951af6ec2d06e6d0cf7409371\",\"cc3a5427d44fc77ff25e80b3edee4650a51f83de761faf5e633994ecf1ab1b44\",\"b350eda75c6e47299b36002b31d5b220c405c21c365e708989829db013fadbb4\",\"f421882756b6714834ae4687ab1aeadf344a1cc45437d2edffbac020ff3801c1\",\"dfb1d4f5b00473a54a4f025ca7606173036bdf111f9806d957d5099e2cd55c62\",\"e5cef5de3e5ad3436d414d20743231e284733b9cf4375dc79eff4fcca4282f99\",\"e624419ba84e33e661e89a28083119ca41f6953dba09a4f82b660684087afe6d\",\"942be430bd0feaced2e3e598273b17e50ea565ec9dac840b580b0b99e1a3cd5c\",\"73350006cec5a0c6b71d53b0b0ddbfb82be96752a9c4e3c904c59e633bc9485e\",\"a7df5c2e9594966c7e0d4a763b13ed5727506d892669df5f7bc9826f539c1d35\",\"2286a5599f5746d6ae48dceef0322b020e6d0b0b0b64683492ac6cda6809c6d0\",\"00a6db28fc4df6ddf10adbe630d9df620ec13af19039c1869653e60dafa739d2\",\"649324d5abb5464aabe35d86cd0eef16562df811f0971481cee664afa5acbc88\",\"7698c256203945e61639d30614dbce3d3d0bf4610b4e576f546d131b8da5f2fd\",\"075e48ac85ba80a50bdee0b926271f1b06715e9baf17716899faf2f7445b95c5\",\"c7ad660832be3a529d67ef9cc459821d04938728fd01fa4951148183c80b06cd\",\"af929fed708b236eded273ad7b344b4411ea85bad120b045d491c065a58aaf11\",\"2fcd2d22b1f30555e785105597cd8f57ed50300e213c4f1bbca6ae149f782c38\",{\"version\":\"bb4248c7f953233ac52332088fac897d62b82be07244e551d87c5049600b6cf7\",\"affectsGlobalScope\":true},\"969afc7787b06c00f480e0c5a82ae92ccb94c3dfd4e1bcc45d740158207cb662\",\"2140fac55503bd2142c95bdeefb459a305833dbc747481e3f031e54393951578\",\"5286545abb6d557eddd26ad4bef22e915ac6495c8173532f259191061674e3aa\",\"833ca9bc196b4ee332010c96e9afcced2c680d15aa15d559fd50e77c73965a78\",\"4fe642bdec9d07f619933c9b4eac66df3ea30b0ee49e9f98586493f98a7ad886\",\"21e198f821e5170e98e65aa26a3bea3641ec340ff43e22102224281d6f30ac98\",\"065c2146947458566ae1eaf2a8dbb94780d71791126ed33e816eb1b6577afe49\",\"fd7599bb27dc7fafaa85cb770619aa794934be09515cfa6a23227a523f1c87af\",\"5b7e5d7274c975b0e3759eacbd4f8620c6d72fcf76dc809d125ba77bec681182\",\"1234b860468564ed0616f53ad4f25d15fd54347b1f6792e515e2ee8829fc9b60\",\"d2ef32b6b38964189331baf5f31aa2db808efb977b16f9f341154a85bf5fd402\",\"c266b536202c877e0ec2a9473d4f82c89586ffc8ed5096bee19a1ff0cddfb639\",\"3484b62cad338eff2313b469bfc6e5853950f549055672450112b086b285613d\",\"9ae112e46f100e07b3b16db152322714d2afd1e16cb6fd848c2164c4b97cf532\",\"9ed3d56eafb7ee9d875da6769b6f73621ce6661cfce283de7bc115e62ae03abf\",\"a362bb8bddc4095ce47b0babf7178ef68bc7aebad0af7626ca5ce1d590494bf4\",\"ba0037eb3d55903ccf7fa3004c2990d6b831da2a0f44e57ea6325bbf3992269b\",\"7bc75399ab3a05535989a336743dd9fbc41b32e1b69905881eab3a1d8fc3f788\",\"3576f553b3104bb09e93a2857077cf37d2634def579e90c76ea3a5a456e177fd\",\"3983674571a3ad496d3d693d5a79d545bbfe8a9598c0da278b151ab1e4e18fbd\",\"19e6b101e0c358787690959f1d4b6f795c0108ee8367eb20e6127a6465c669a1\",\"a58cd8883de63179e8761f4b783e2965e45ff70651d7e20e39b4794724ada314\",\"a82a31423116bad5be7eca7b4738930d9e293eda7509bce6e9265d1b90321f81\",\"f04791198d22830c4898959cc8d32ee2da096df6ff9fcceac868a97e6c375ceb\",\"bb12d0a77526f90f6624ffc85d4749ceabc77d4d2fd6ebd700464527f840f696\",\"e3a6cb11daad5360db3d3747c0bad9b9f2392e179305b927508e5e1a40043e11\",\"5b0526046e67ed5d225ef7c8b5d1fbfd20182906afdc924c7aaac4caf0533a64\",\"6f89168ad01e605745fcd22cb3f158fced83ca048794597f56c094f748be5c4e\",\"e4f093af5ed0eaed770235baaefd7438661f14f57eaf170f4b47e197d58c76db\",\"b8c0e05f44976d6b0f550fa524c0ab327015b5723ec7d192e0cb16fa0de5acd7\",\"21afb72063e9106fb27ae08d982445130f34504a8f2b790f57dfd7f58faa35d5\",\"d23caa4f64e4877ffafd0d58e1e4b807805b91a2b58a67e44e933972b75d86d5\",\"f924d32d12e1b44e4851bc9ca5a7f63e8a2f2cfe932d7b4a77c02fa9d42993e7\",\"2806ec7ceb39ff7791018df324bf8114c8666dea6f17a7fb0a4e5f45a06b6fc2\",\"f58761cc2cbf31f0953b38e13cf6171e1c7130ce84782a8afbe9fbdf412b6cea\",\"7aaa724482e6f15d8f70cb2833dbc55794d7c29d2650fe2afa9de5c390bd9f57\",\"63b5a892c2b2b092e374d33f4c1c51b4bfc9df8104fec0b7b006ce26aa68c989\",\"8e548bc3d16d78659b357da30d0a45b3b697bcd4dbc24595c52dcb897b71a486\",\"1c6c1e15f05a8e3639172a7c649644e00adfcc215a9c9536bf2c5299237b6638\",\"356901e3b86a6e115eafb7a725cd073a0024bc0eb0cf741e85695352517887ca\",\"db9cb7459bc8ecfd91bfd08598d60d62cf5cf78dcf7d3f8a209204e578b830e8\",\"ab7202dc81b82f1e8b4008bd87c0465e1ebbc70bb7ebb33182d528999d9a0470\",\"c60fe1946466c6d68d773a6faaf22bc2f9e107452b8b569254517977d24d5ae9\",\"e6bb26643971a72d3c829f28d4f0d4e5d15d3cd57a0909d9647f107145812615\",\"8e548bc3d16d78659b357da30d0a45b3b697bcd4dbc24595c52dcb897b71a486\",\"064eab1a7b24cd8b1247320848f6ab7cfddede24b80973ad7cffd2f73134b20c\",\"5034adb393d7863f1867c193b5705de1d7219ca97874037d661a30bb405b2049\",\"1f159da169f65d987860bd30d79f502d05613293c4625036974c9d6b35e2a671\",\"42ad4ce262b0400a475c89027fa746f95eeebc13185612ca3c8bcba346f07d6f\",\"8b55ff6e48ec9c8a17c15ca8dc8f5d4dca6e0fa609ca41fa9a11dd796d16b050\",\"b7d829281b4cefb06f2d47b1223821e849a01e8d21c81b08da244d91f0d17fca\",\"fbfb7a3de011ac08cdde24dc1c49d05aa372f1e861bb985aea0ca3dcee952ff8\",\"e2f401fd1afeab210aa64e0a0e996ade90a20395a18d0ab5cd4a6089e651785c\",\"6bda70a402621b19ab7d0e568dae193944e2dd2f866857d0a47d5ebfe1be27eb\",\"936efb9566b2f375e713befa3a69c237be13d3ead2738d8736357df8dd04a851\",\"5024433f8da3a7968f6d12cffd32f2cefae4442a9ad1c965fa2d23342338b700\",\"2ff9995137f3e5d68971388ec58af0c79721626323884513f9f5e2e996ac1fdd\",\"cc957354aa3c94c9961ebf46282cfde1e81d107fc5785a61f62c67f1dd3ac2eb\",\"1a7cc144992d79b062c22ac0309c6624dbb0d49bbddff7ea3b9daa0c17bcac0a\",\"93de1c6dab503f053efe8d304cb522bb3a89feab8c98f307a674a4fae04773e9\",\"3b043cf9a81854a72963fdb57d1884fc4da1cf5be69b5e0a4c5b751e58cb6d88\",\"5426e62886b7be7806312d31a00e8f7dccd6fe63ba9bbefe99ee2eab29cc48a3\",\"a7d9d2a35530516e191ade6dc804d7de42d45ff6620c0319cfb4469dbdbd8044\",\"cab425b5559edac18327eb2c3c0f47e7e9f71b667290b7689faafd28aac69eae\",\"3cfb0cb51cc2c2e1b313d7c4df04dbf7e5bda0a133c6b309bf6af77cf614b971\",\"f992cd6cc0bcbaa4e6c810468c90f2d8595f8c6c3cf050c806397d3de8585562\",\"6d829824ead8999f87b6df21200df3c6150391b894b4e80662caa462bd48d073\",\"becb604e8f5399436f67baa1c4923fea0413533e9000d98d97c9da729eeb4e81\",\"e39b1f1a88ac45ddde24e46eb57fa4a3681bc0bfa898305d6152e4fcb5a82974\",\"a04bbf3e3e34cf8ad52dc42197ea42474f8d4d6f9d3df8af0c271400f0c2dd42\",\"8224fcf3a00e38208a7a8705bd3f9fd486bd0efe4d9e56c520b1b3a6f43acc04\",{\"version\":\"924dfa21135e4aeb4498c4facc93545b30bb844618929d342f9ab552947e34db\",\"affectsGlobalScope\":true},\"68bb1cebc4ec3f0a3083d4ed22837fab5d38ea761810a4b831e492fabd0bce2f\",\"6a9c5127096b35264eb7cd21b2417bfc1d42cceca9ba4ce2bb0c3410b7816042\",\"78828b06c0d3b586954015e9ebde5480b009e166c71244763bda328ec0920f41\",{\"version\":\"64d4b35c5456adf258d2cf56c341e203a073253f229ef3208fc0d5020253b241\",\"affectsGlobalScope\":true},\"0133ebdd17a823ae56861948870cde4dac18dd8818ab641039c85bbb720429e0\",\"f3e604694b624fa3f83f6684185452992088f5efb2cf136b62474aa106d6f1b6\",\"a1c79f857f5c7754e14c93949dad8cfefcd7df2ecc0dc9dd79a30fd493e28449\",\"874d84ca5699231d5af2868fef01fc63f948bd83be928881479db48508f92ca0\",{\"version\":\"64d4b35c5456adf258d2cf56c341e203a073253f229ef3208fc0d5020253b241\",\"affectsGlobalScope\":true},\"3adc8ac088388fd10b0e9cd3fa08abbebed9172577807394a241466ccb98f411\",\"e050a0afcdbb269720a900c85076d18e0c1ab73e580202a2bf6964978181222a\",\"725d9be2fd48440256f4deb00649adffdbc5ecd282b09e89d4e200663792c34c\",\"4130f45b114de4cf06a465c0540c4fe31270876afff1cd59111314b6c4077c69\",\"8841e2aa774b89bd23302dede20663306dc1b9902431ac64b24be8b8d0e3f649\",\"fd326577c62145816fe1acc306c734c2396487f76719d3785d4e825b34540b33\",\"3ebae8c00411116a66fca65b08228ea0cf0b72724701f9b854442100aab55aba\",\"cddf5c26907c0b8378bc05543161c11637b830da9fadf59e02a11e675d11e180\",\"3d2cd8f3047fff04a71e7037a6a4cb9f4accb28dbd8c0d83164d414811025af0\",{\"version\":\"271cde49dfd9b398ccc91bb3aaa43854cf76f4d14e10fed91cbac649aa6cbc63\",\"affectsGlobalScope\":true},\"2bcecd31f1b4281710c666843fc55133a0ee25b143e59f35f49c62e168123f4b\",\"a6273756fa05f794b64fe1aff45f4371d444f51ed0257f9364a8b25f3501915d\",\"9c4e644fe9bf08d93c93bd892705842189fe345163f8896849d5964d21b56b78\",\"25d91fb9ed77a828cc6c7a863236fb712dafcd52f816eec481bd0c1f589f4404\",\"4cd14cea22eed1bfb0dc76183e56989f897ac5b14c0e2a819e5162eafdcfe243\",\"8d32432f68ca4ce93ad717823976f2db2add94c70c19602bf87ee67fe51df48b\",\"bfe1b52cf71aea9bf8815810cc5d9490fa9617313e3d3c2ee3809a28b80d0bb4\",\"70b34c8420d6226ed565d55f47fe04912d0ca0ad128825c5a06e018a3498db32\",\"de1d6e224048139baf7494237a9231be6bab9e990fb239c7825bfd38b06d8c90\",\"8b06ac3faeacb8484d84ddb44571d8f410697f98d7bfa86c0fda60373a9f5215\",\"7eb06594824ada538b1d8b48c3925a83e7db792f47a081a62cf3e5c4e23cf0ee\",\"f5638f7c2f12a9a1a57b5c41b3c1ea7db3876c003bab68e6a57afd6bcc169af0\",\"d8aab31ba8e618cc3eea10b0945de81cb93b7e8150a013a482332263b9305322\",\"69da61a7b5093dac77fa3bec8be95dcf9a74c95a0e9161edb98bb24e30e439d2\",\"561eca7a381b96d6ccac6e4061e6d2ae53f5bc44203f3fd9f5b26864c32ae6e9\",\"62ea38627e3ebab429f7616812a9394d327c2bc271003dfba985de9b4137369f\",\"b4439890c168d646357928431100daac5cbdee1d345a34e6bf6eca9f3abe22bc\",\"5d72971a459517c44c1379dab9ed248e87a61ba0a1e0f25c9d67e1e640cd9a09\",\"02d734976af36f4273d930bea88b3e62adf6b078cf120c1c63d49aa8d8427c5c\",{\"version\":\"516a426e3960379f310107635b8f3a7e8c307c6c665080b128039d9299ec4087\",\"affectsGlobalScope\":true},{\"version\":\"597e57d1aed6e56c5711328daa1a5f835d9aa1a23093f133d98acabeedff06fe\",\"affectsGlobalScope\":true},\"b3338366fe1f2c5f978e2ec200f57d35c5bd2c4c90c2191f1e638cfa5621c1f6\",\"83c5b66b5a31c9c21c57a2e7070e84a0dcaf66bcf01b54f5c36c8acfd369deef\",\"96d14f21b7652903852eef49379d04dbda28c16ed36468f8c9fa08f7c14c9538\",\"fec943fdb3275eb6e006b35e04a8e2e99e9adf3f4b969ddf15315ac7575a93e4\",\"675e702f2032766a91eeadee64f51014c64688525da99dccd8178f0c599f13a8\",\"fe4a2042d087990ebfc7dc0142d5aaf5a152e4baea86b45f283f103ec1e871ea\",\"d70c026dd2eeaa974f430ea229230a1897fdb897dc74659deebe2afd4feeb08f\",\"187119ff4f9553676a884e296089e131e8cc01691c546273b1d0089c3533ce42\",\"febf0b2de54781102b00f61653b21377390a048fbf5262718c91860d11ff34a6\",\"ca59fe42b81228a317812e95a2e72ccc8c7f1911b5f0c2a032adf41a0161ec5d\",\"9364c7566b0be2f7b70ff5285eb34686f83ccb01bda529b82d23b2a844653bfb\",\"00baffbe8a2f2e4875367479489b5d43b5fc1429ecb4a4cc98cfc3009095f52a\",\"ae9930989ed57478eb03b9b80ad3efa7a3eacdfeff0f78ecf7894c4963a64f93\",\"3c92b6dfd43cc1c2485d9eba5ff0b74a19bb8725b692773ef1d66dac48cda4bd\",\"3e59f00ab03c33717b3130066d4debb272da90eeded4935ff0604c2bc25a5cae\",\"df996e25faa505f85aeb294d15ebe61b399cf1d1e49959cdfaf2cc0815c203f9\",{\"version\":\"0714e2046df66c0e93c3330d30dbc0565b3e8cd3ee302cf99e4ede6220e5fec8\",\"affectsGlobalScope\":true},\"e8465811693dfe4e96ef2b3dffda539d6edfe896961b7af37b44db2c0e48532b\",\"2a2e2c6463bcf3c59f31bc9ab4b6ef963bbf7dffb049cd017e2c1834e3adca63\",\"f313731860257325f13351575f381fef333d4dfe30daf5a2e72f894208feea08\",\"951b37f7d86f6012f09e6b35f1de57c69d75f16908cb0adaa56b93675ea0b853\",\"3816fc03ffd9cbd1a7a3362a264756a4a1d547caabea50ca68303046be40e376\",\"0c417b4ec46b88fb62a43ec00204700b560d01eb5677c7faa8ecd34610f096a8\",\"13d29cdeb64e8496424edf42749bbb47de5e42d201cf958911a4638cbcffbd3f\",\"209e814e8e71aec74f69686a9506dd7610b97ab59dcee9446266446f72a76d05\",\"7366d0aa1eaa9efadb11633ac3a19a099b27d13a8ff0803f45b13ea1ea129cca\",\"736097ddbb2903bef918bb3b5811ef1c9c5656f2a73bd39b22a91b9cc2525e50\",\"208bb742e0f201470da121bc73847c74b62cff4172f38ae5949ae77d6c9c6b71\",\"3663d1b50f356656a314e5df169bb51cb9d5fd75905fa703f75db6bb32030568\",\"6fa0008bf91a4cc9c8963bace4bba0bd6865cbfa29c3e3ccc461155660fb113a\",\"df38da6685578ac3d0e4ce2d20f3d59462ee53959b8263d2532ec9cec48ae098\",\"2b8264b2fefd7367e0f20e2c04eed5d3038831fe00f5efbc110ff0131aab899b\",\"fc37aca06f6b8b296c42412a2e75ab53d30cd1fa8a340a3bb328a723fd678377\",\"5f2c582b9ef260cb9559a64221b38606378c1fabe17694592cdfe5975a6d7efa\",\"a73a445c1e0a6d0f8b48e8eb22dc9d647896783a7f8991cbbc31c0d94bf1f5a2\",\"6209c901f30cc321f4b86800d11fad3d67e73a3308f19946b1bc642af0280298\",\"c0a3ea3aee13c4946a6aefce3a6ab9292a40a29f6622cde0fda0b1067a1a1f5f\",\"62b931417104c7cb35d0725e1869f51d52d7b18462fd58f32f846a314a42ba10\",\"84063cb4682d54b1b83b6cf88430e33e647d57afe29237c4c414196b7ae33ea8\",\"d650d5f6a4c75431fcfeeac768c65f10efe245d5e3f867017da40ed003fca114\",\"ba601641fac98c229ccd4a303f747de376d761babb33229bb7153bed9356c9cc\",\"163be962fa11ca0e3bc9afd1188701e16f5db0d84f904be3a5327c04bf14c1dc\",\"45a63e17814c570ea59407f231ef9c561510bd6edb36f17479b09b44619496c6\",\"39daf0586ebf95e65217d55923ac49ada1939510bed54c6364504d2e0b0ccfc9\",\"06c2fc0bf929858d3ee5fb8c14f0a39b48d91bb8161b6480d833f787df761672\",{\"version\":\"8f19251323456195ec9236df857bac3b8f97b73b540ef06ead2ceccc3884954f\",\"affectsGlobalScope\":true},\"fc5feab7b3f0a96eaddb118cb7c200b9a06e4db387f8eecea6ef463c57496476\",\"6c362c5d50652957065cf52f282a2bf0a456ed3713738d0ee1a9089dbb5b5fe7\",\"8017277c3843df85296d8730f9edf097d68d7d5f9bc9d8124fcacf17ecfd487e\",\"47d7d2886a64d471f1f8a5d895c442068e6d5d868e176ef7d3de347f8127cb9e\",\"60aaac5fb1858fbd4c4eb40e01706eb227eed9eca5c665564bd146971280dbd3\",\"e03334588c63840b7054accd0b90f29c5890db6a6555ac0869a78a23297f1396\",\"c3052485f32a96bfde75a2976c1238995522584ba464f04ff16a8a40af5e50d1\",\"c220410b8e956fa157ce4e5e6ac871f0f433aa120c334d906ff1f5e2c7369e95\",\"960a68ced7820108787135bdae5265d2cc4b511b7dcfd5b8f213432a8483daf1\",\"ed3b711f533ddb3a5451f4c4bb0df3a0b95e9d0433b3b7834644dd1718d06d31\",\"c8178ab5f29f3493dfb6bed728f81a644ecfce0f6206b09408096ee4f10eebc8\",\"8133fbe7d8377a2033c06e889272800bafc776d36d7c10dde05a7f99b90be6d6\",\"064679ecac24a086709d83d1aa9953e04a7f31d456c7a44910e9e218a10fc9c2\",\"8ac3261b8b7017c6b1fa92420ab01356f0f4994237ceb9f813a3cb797f436c8b\",\"6a8d0553dbfd16e9c9ea42373edb4145d06083b60e2e8cd469ab3165baceae5a\",\"0777eaff71bb5a4c44c170b80023cb343a8feb42101259ceef6b449d25d845f4\",\"c87ffbd89d0625350fbe78f727da51a00efa6b777532415fbccaf214309de091\",\"f15541d66c08700872c9ea3f1ee827a0c08ee0c71111df82546b3128d2ca4020\",\"0d6b3824d757ce8bd598edeba960f132eb70db238f7951284c01dedc70c84f3c\",\"319f03b90f7cda79f85ae161866b16e3faa759b5624db0756340399059c6369a\",\"df513d30d09a5fd30306e177d196d3fb1944e23dc8420d2f523da9ffebe58dec\",\"f12702d78d48adcbd27598ec64e9feffa7baf5990b44d40b71d5c381361bc575\",\"f5cba585efc396a54dbacb8ff689799e6b3b3a3ed0e051fb69894b6669524801\",\"ecafe5a693cb23c3f17618522471e7426f9b8c1a2eda59a72e9bc0aa0a0ed45f\",\"23255560340f60336ff79daf50b3b6432ec0f32f7dd19638d3a2406826a15d49\",\"8adb0cee1edd485ae5675aa5100d73c1c17201446ee33a1d2bd364b766d6469c\",{\"version\":\"b40add723ee9828e126ff18a0a2fb5124958ff911e1836bfe461916e434bd051\",\"affectsGlobalScope\":true},\"8a19491eba2108d5c333c249699f40aff05ad312c04a17504573b27d91f0aede\",\"74b0245c42990ed8a849df955db3f4362c81b13f799ebc981b7bec2d5b414a57\",\"3dce33e7eb25594863b8e615f14a45ab98190d85953436750644212d8a18c066\",\"67fc055eb86a0632e2e072838f889ffe1754083cb13c8c80a06a7d895d877aae\",\"b0d10e46cfe3f6c476b69af02eaa38e4ccc7430221ce3109ae84bb9fb8282298\",{\"version\":\"20278d7dc78142b77cb5ebaadd6a20eae3eff7bec44fc70930520c2f4dba5e25\",\"affectsGlobalScope\":true},\"d73c25c0db01c24b2826af004d6147a766e1c61181f1b6a49f5e762cb69e68d1\",\"3833c70307dc3d2b46cb6f2a8b6a90e4d7e7367a21ab18c481d7de0909a43e67\",\"bd0f4458d57115491a1dd9fe522fa1d6ffe45a85b12bbd463967f90b50e43c29\",{\"version\":\"06279f0df6f368af41fe267319e90b5af9d89ad489d1662164b94ce30a797c79\",\"affectsGlobalScope\":true},\"2887592574fcdfd087647c539dcb0fbe5af2521270dad4a37f9d17c16190d579\",\"9d74c7330800b325bb19cc8c1a153a612c080a60094e1ab6cfb6e39cf1b88c36\",\"6d6e06d8269ca289d16f53844f23c254c3944a524bc67382d9b4691ec8c486b9\",\"4fb0b7d532aa6fb850b6cd2f1ee4f00802d877b5c66a51903bc1fb0624126349\",\"b90c59ac4682368a01c83881b814738eb151de8a58f52eb7edadea2bcffb11b9\",\"8560a87b2e9f8e2c3808c8f6172c9b7eb6c9b08cb9f937db71c285ecf292c81d\",\"ffe3931ff864f28d80ae2f33bd11123ad3d7bad9896b910a1e61504cc093e1f5\",\"083c1bd82f8dc3a1ed6fc9e8eaddf141f7c05df418eca386598821e045253af9\",\"274ebe605bd7f71ce161f9f5328febc7d547a2929f803f04b44ec4a7d8729517\",\"6ca0207e70d985a24396583f55836b10dc181063ab6069733561bfde404d1bad\",\"5908142efeaab38ffdf43927ee0af681ae77e0d7672b956dfb8b6c705dbfe106\",\"f772b188b943549b5c5eb803133314b8aa7689eced80eed0b70e2f30ca07ab9c\",\"0026b816ef05cfbf290e8585820eef0f13250438669107dfc44482bac007b14f\",\"05d64cc1118031b29786632a9a0f6d7cf1dcacb303f27023a466cf3cdc860538\",\"e0fff9119e1a5d2fdd46345734126cd6cb99c2d98a9debf0257047fe3937cc3f\",\"d84398556ba4595ee6be554671da142cfe964cbdebb2f0c517a10f76f2b016c0\",\"e275297155ec3251200abbb334c7f5641fecc68b2a9573e40eed50dff7584762\",\"b2f006ee835f315d01c43c0f5d9e9ad78a5870b380899877b32a33078d065dbd\",{\"version\":\"3a1e422f919c70fca66e94dc641ad8d9732b3d2533ac047b8a9aaca9eea3aa10\",\"affectsGlobalScope\":true},\"bc81aff061c53a7140270555f4b22da4ecfe8601e8027cf5aa175fbdc7927c31\",\"70e9a18da08294f75bf23e46c7d69e67634c0765d355887b9b41f0d959e1426e\",\"d9f5e2cb6bce0d05a252e991b33e051f6385299b0dd18d842fc863b59173a18e\"],\"options\":{\"allowSyntheticDefaultImports\":true,\"composite\":true,\"esModuleInterop\":true,\"jsx\":4,\"module\":99,\"noFallthroughCasesInSwitch\":true,\"noImplicitAny\":true,\"noUnusedLocals\":true,\"noUnusedParameters\":true,\"rootDir\":\"./static-resources\",\"skipLibCheck\":true,\"sourceMap\":true,\"strict\":true,\"suppressImplicitAnyIndexErrors\":true,\"target\":2},\"fileIdsList\":[[1020],[842,916,917,926,927],[847,849,914,915],[913],[844],[926,928],[844,916,918,919,920,923,924,925],[844,846,848,913,922],[844,920],[107,108,844],[913,919],[107,844,846,848,920,921,922],[848],[844,845],[843,846],[843,848],[850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,869,870,872,874,875,876,877,878,879,880,881,882,883,884,885,886,887,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912],[850,852,857],[852,889],[851,856],[850,851,852,853,854,855],[851,852,853,856,889],[850,852,856,857],[856],[856,896],[850,851,852,856],[851,852,853,856],[851,852],[850,851,852,856,857],[852,888],[850,851,852,857],[850,851,865],[850,851,864],[873],[866,867],[868],[866],[850,851,865,866],[850,851,864,865,867],[871],[850,851,866,867],[850,851,852,853,856],[850,851],[851],[850,856],[178],[56],[56,179,180,181,182,183],[56,180,184,1011],[56,182,184,1011],[53,178],[184,185,1011],[930,933,935,936,937,938],[930,933,936,939],[930],[930,931],[931,932],[934],[935,938,940,944,945],[935,938,945],[107,933,935,936,937,939,940],[935,945],[935,939,941],[933,937,939],[935,939,940,941,943,944,945,946,947,948,949,950,951,952,953,954,955,956],[935,943],[107,943],[930,935,936,937,938,939,941,942],[935,938,940,943],[935,941,943],[930,933],[132,153],[126,130,131,153],[110,126,149],[132,149,153],[132],[109,132,153],[127,132,149],[132,133,134,135,136,137,138,139,140,142,143,144,145,146,147],[132,141,149,153],[130,149],[108,110,126,149,153],[130,132,136,149,153],[107,126,132,149,153],[132,149],[149],[110,127,128,129,149,150,151,152],[110,126,127,128,129,148,150],[110,126,148],[127],[148,153,156],[107,108,109,153],[60,61,154,155],[109,153],[126],[837,958,959],[114,126,841,929,957],[126,837],[74,107],[56,212,222,384,481,833],[481,482],[56,212,475,833],[475,476],[56,212,478,833],[478,479],[56,212,219,397,484,833],[484,485],[56,158,212,222,223,833],[223,224],[56,212,226,833],[226,227],[56,158,212,219,222,229,833],[229,230],[56,158,212,222,234,258,373,374,833],[374,375],[56,158,212,219,377,739],[377,378],[56,158,212,379,380,833],[380,381],[56,212,219,384,386,387,739],[387,388],[56,158,212,219,271,390,739],[390,391],[56,212,219,401,833],[401,402],[56,212,219,397,398,833],[398,399],[212,219,739],[814],[56,212,219,404,739],[404,405],[56,158,212,219,397,410,739],[410,411],[56,212,219,394,395,739],[393,395,396],[56,393,833],[56,158,212,219,407,833],[407,408],[56,158,212,219,222,431,833],[431,432],[56,212,219,397,413,833],[413,414],[56,212,416,833],[416,417],[56,212,219,419,833],[419,420],[56,212,219,424,425,833],[425,426],[56,212,219,428,833],[428,429],[56,158,212,435,436,833],[436,437],[56,158,212,219,232,833],[232,233],[56,158,212,439,833],[439,440],[279],[56,212,384,442,833],[442,443],[740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759],[56,212,219,445,739],[445,446],[56,739],[448],[56,212,222,384,460,461,833],[461,462],[56,212,450,833],[450,451],[56,212,453,833],[453,454],[56,212,219,424,456,739],[456,457],[56,212,464,833],[464,465],[56,158,212,219,467,833],[467,468],[56,212,222,384,460,471,472,833],[472,473],[158,212,219,397,487,833],[487,488],[56,384],[385],[212,492,493,833],[493,494],[56,158,212,219,499,739],[499,500,501],[500],[56,212,424,496,833],[496,497],[56,212,503,833],[503,504],[56,212,219,506,739],[506,507],[56,158,212,219,509,739],[509,510],[212,739],[831],[56,212,219,512,739],[512,513],[818],[56,212],[820],[56,158,212,219,518,739],[518,519],[56,158,212,219,397,515,833],[515,516],[56,158,212,219,521,833],[521,522],[56,212,219,527,833],[527,528],[56,212,524,833],[524,525],[56,158,222,225,228,231,234,258,281,283,285,376,379,382,386,389,392,397,400,403,406,409,412,415,418,421,424,427,430,433,438,441,444,447,449,452,455,458,460,463,466,469,471,474,477,480,483,486,489,492,495,498,502,505,508,511,514,517,520,523,526,529,532,535,538,541,544,547,550,553,556,559,562,565,568,571,573,576,579,582,586,588,591,595,598,602,605,608,611,615,618,620,623,626,630,633,636,639,641,644,647,650,653,656,659,663,666,668,671,674,677,680,683,687,690,693,696,699,702,705,708,711,714,717,720,739,760,813,815,816,817,819,821,822,823,824,826,828,830,832,1011],[536,537],[212,492,536,833],[530,531],[56,212,219,530,833],[490,491],[56,158,212,490,739,833],[533,534],[56,212,511,533,739,833],[56,397,434,833],[539,540],[56,158,212,539,833],[542,543],[56,158,212,219,424,542,739],[563,564],[56,212,219,563,833],[551,552],[56,212,219,397,551,739],[545,546],[212,545,833],[554,555],[56,212,219,397,554,739],[548,549],[56,212,548,833],[557,558],[56,212,557,833],[560,561],[56,212,424,560,833],[566,567],[56,212,219,566,833],[577,578],[56,212,384,573,576,577,739,833],[569,570],[212,219,397,569,739],[572],[56,219,565],[580,581],[56,212,222,541,580,833],[317,459],[56,158,212,317,389,739],[584,585],[56,212,538,583,584,833],[56,212,833],[265],[158,267],[56,158],[267,268,269,270],[56,267],[56,273],[56,158,272],[272,273,274,275,276],[56,261,272],[811],[278],[280],[158,286],[56,286],[286,287,288,289,290],[282],[284],[254,256,264,266,271,277,279,281,283,285,291,296,300,307,313,317,324,327,329,333,337,343,347,352,357,363,368,370,372],[292,293,294,295],[158,292],[56,158,291],[56,286,292],[297],[297,298,299],[261,297],[308,309,310,311,312],[56,308],[56,307,311],[301,302,303,304,305,306],[56,302],[56,256,301],[56,301],[56,264,300,301],[56,300],[314,315,316],[56,158,254,314],[325,326],[56,325],[56,158,256,324],[328],[330,331,332],[56,330],[334,335,336],[56,334],[255],[56,252,254],[253],[318,319,320,321,322,323],[56,319],[56,158,256,318],[56,300,318],[318],[56,261,277,300],[338,339,340,341,342],[158,340],[56,158,338,339],[53,56,340],[344,345,346],[56,344],[348,349,350,351],[158,348],[353,354,355,356],[158,353],[358,359,360,361,362],[158,358],[364,365,366,367],[158,364],[56,158,277],[369],[371],[261],[259,260,261,262,263],[172,174,176],[173],[172],[175],[56,184,1011],[189],[53,184,186,188,190,1011],[187],[56,158,163,169],[170],[169,171],[56,163,169,191],[158],[159,160,161],[162],[56,207,208],[209],[159,160,161,163,169,171,177,191,192,193,195,196,197,198,201,202,203,204,206,210,211],[171],[171,191],[197],[164],[167],[164,165,166,167,168],[53],[53,164,165,166],[194],[169,191],[205],[177],[163],[199,200],[54],[761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792],[251],[245,247],[235,245,246,248,249,250],[245],[235,245],[236,237,238,239,240,241,242,243,244],[236,240,241,244,245,248],[236,237,238,239,240,241,242,243,244,245,246,248,249],[235,236,237,238,239,240,241,242,243,244],[329],[589,590],[56,212,492,589,833],[56,158,739],[593,594],[56,158,212,592,593,739,833],[596,597],[56,158,212,219,592,596,739],[220,221],[56,158,212,219,220,739],[574,575],[56,212,222,384,460,574,739,833],[256,257],[56,212,256,739],[254],[603,604],[56,158,212,435,603,833],[599,601],[56,505],[600],[606,607],[56,158,212,606,833],[609,610],[56,219,609],[613,614],[56,212,538,579,591,612,613,833],[56,212,579,833],[616,617],[56,158,212,219,616,833],[470],[619],[56,158,212,219,343,739],[624,625],[56,212,279,384,623,624,739,833],[621,622],[56,212,222,621,739,833],[628,629],[56,212,489,627,628,739,833],[634,635],[56,212,489,633,634,739,833],[637,638],[56,212,637,739,833],[640],[56,212,219,725],[660,661,662],[56,212,660,833],[642,643],[56,212,219,397,642,739],[645,646],[56,212,645,739,833],[648,649],[56,212,384,648,739,833],[651,652],[56,212,651,739,833],[654,655],[56,212,653,654,739,833],[657,658],[56,212,222,657,739,833],[212,213,214,215,216,217,218,721,722,723,725],[721,722,723],[53,212],[833],[212,213,214,215,216,217,218,724],[53,56,214],[215],[212,214,737],[158,212,213,214,215,216,217,218,724],[212,214,215,217,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738],[212,222,225,228,231,234,376,379,382,389,392,394,397,400,403,406,409,412,415,418,421,424,427,430,433,438,441,444,447,452,455,458,460,463,466,469,474,477,480,483,486,489,492,495,498,502,505,508,511,514,517,520,523,526,529,532,535,538,541,544,547,550,553,556,559,562,565,568,571,576,579,582,586,591,595,598,605,608,611,615,618,620,623,626,630,633,636,639,644,647,650,653,656,659,663,666,671,674,677,680,683,687,690,693,696,699,702,708,711,714,717,720,721,1011],[222,225,228,231,234,258,376,379,382,389,392,394,397,400,403,406,409,412,415,418,421,424,427,430,433,438,441,444,447,449,452,455,458,460,463,466,469,474,477,480,483,486,489,492,495,498,502,505,508,511,514,517,520,523,526,529,532,535,538,541,544,547,550,553,556,559,562,565,568,571,573,576,579,582,586,588,591,595,598,602,605,608,611,615,618,620,623,626,630,633,636,639,641,644,647,650,653,656,659,663,666,668,671,674,677,680,683,687,690,693,696,699,702,708,711,714,717,720,1011],[212,215,725],[212,725],[212],[725],[724,725],[212,721,725],[664,665],[56,158,212,219,664,739],[667],[56,474],[669,670],[56,158,212,435,669,833],[700,701],[56,212,219,397,700,833],[688,689],[56,158,212,219,688,833],[672,673],[56,212,219,672,833],[675,676],[56,212,675,833],[678,679],[56,212,219,678,833],[697,698],[56,212,219,697,833],[681,682],[56,212,219,681,833],[685,686],[56,212,219,517,615,677,684,685,739],[56,516],[691,692],[56,212,219,691,833],[694,695],[56,212,219,397,694,833],[706,707],[56,212,219,397,705,706,739],[703,704],[56,212,703,833],[370],[709,710],[56,158,212,492,495,502,508,535,538,591,615,709,739,833],[712,713],[56,158,212,219,397,712,833],[715,716],[56,158,212,715,739,833],[718,719],[56,158,212,219,718,833],[631,632],[56,212,258,384,631,833],[384],[56,383],[422,423],[56,158,212,215,219,422,739],[829],[266],[587],[825],[793],[666],[794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,812],[827],[1020,1021,1022,1023,1024],[1020,1022],[107],[74,76,99,107,1026,1027,1028],[76,107],[1033],[1032],[1037],[963],[1042,1045],[1041,1042,1044],[1039,1040,1041,1042],[1043],[74,75,107,1049],[75,107],[1052],[1054,1060],[1055,1056,1057,1058,1059],[1060],[1064],[1065],[1074],[1071,1073],[1080,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092],[1080,1081,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092],[1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092],[1080,1081,1082,1084,1085,1086,1087,1088,1089,1090,1091,1092],[1080,1081,1082,1083,1085,1086,1087,1088,1089,1090,1091,1092],[1080,1081,1082,1083,1084,1086,1087,1088,1089,1090,1091,1092],[1080,1081,1082,1083,1084,1085,1087,1088,1089,1090,1091,1092],[1080,1081,1082,1083,1084,1085,1086,1088,1089,1090,1091,1092],[1080,1081,1082,1083,1084,1085,1086,1087,1089,1090,1091,1092],[1080,1081,1082,1083,1084,1085,1086,1087,1088,1090,1091,1092],[1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1091,1092],[1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1092],[1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091],[1099],[1095,1096,1097,1098],[76,99,107,1102,1103],[74,81,90],[66,74,81],[90],[72,74,81],[74],[74,90,99],[81,90,99],[74,75,76,81,90,93,99],[76,90,93,99],[62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,99,100,101,102,103,104,105,106],[72,74,90],[64],[95],[88,100,102],[81,90],[81],[87,99],[74,75,90,102],[1108],[1109],[56,1061,1121],[56,1060,1123],[56,1060],[383,1127,1128,1129,1130],[54,56,1135],[54,56],[56,1145],[56,1132,1133,1134,1145],[56,1132,1135,1145],[56,1132,1135],[1132,1133,1134,1135,1136,1137,1138,1139,1140,1141,1142,1143,1144],[52,53,54,55],[1121],[76,90,107],[53,56,1061],[56,1154],[1074,1157],[962],[1159],[107,1164,1165,1166,1167,1168,1169,1170,1171,1172,1173,1174],[1163,1164,1173],[1164,1173],[1152,1163,1164,1173],[1163,1164,1165,1166,1167,1168,1169,1170,1171,1172,1174],[1164],[70,1163,1173],[70,107,1156,1159,1160,1162,1175],[74,76,78,81,90,93,99,105,107],[1179],[838],[839,840],[1067,1068],[1067,1068,1069,1070],[1072],[96,97],[56,58,59],[76,78,81],[112],[81,108,109,112,113],[116],[114],[108,114,116,118],[112,114,119,124],[81,114],[81,108,109,114,115,116,117,118,119,120,121,122,123],[81,114,123],[108],[81,111,114,116,122,123,124,125],[57,836,960,994],[57],[57,836,967,968,969,970,971,979,980,981,982,983,984,985,986,995],[57,157,994,995],[57,966,969,994],[57,835],[57,978],[57,59,157,967,968,994],[57,960,970,994],[57,58,59,157,833],[57,834],[57,996,997,998,999,1000],[57,58,59,1001],[57,1003,1004,1005,1006,1007],[56,57,157,987],[57,988,989,990,991,992,993],[57,987],[57,968,987],[57,960],[57,833],[57,961,965],[56,57,964],[57,184,1010,1011,1012],[57,184,1011],[57,184,186,833,1009,1010,1011,1013,1015,1017],[57,184,711,833,1010],[57,833,1010,1011,1013,1014,1015,1016],[57,1010,1011,1013,1014,1015],[57,833,1013,1014],[57,978,1010,1011,1013],[57,109,157,973,974],[57,972,973,974,975,976,977],[57,974],[57,109,157]],\"referencedMap\":[[1022,1],[928,2],[916,3],[914,4],[915,5],[929,6],[926,7],[927,8],[925,9],[921,10],[922,11],[923,12],[924,13],[846,14],[847,15],[848,14],[849,16],[913,17],[863,18],[861,18],[888,19],[876,20],[856,21],[886,20],[887,20],[890,22],[891,20],[858,23],[892,20],[893,20],[894,20],[895,20],[896,24],[897,25],[898,20],[854,20],[899,20],[900,20],[901,24],[902,20],[903,20],[904,26],[905,20],[906,22],[907,20],[855,20],[908,20],[909,20],[910,27],[853,28],[859,29],[889,30],[862,31],[911,4],[864,32],[865,33],[874,34],[873,35],[869,36],[868,35],[870,37],[867,38],[866,39],[872,40],[871,37],[875,41],[857,42],[852,43],[850,44],[851,45],[880,24],[877,44],[179,46],[182,47],[184,48],[181,49],[183,50],[180,51],[185,49],[186,52],[939,53],[942,54],[931,55],[932,56],[933,57],[935,58],[946,59],[947,60],[941,61],[948,62],[949,63],[950,63],[940,64],[957,65],[952,59],[951,66],[953,67],[943,68],[954,62],[955,60],[945,69],[956,66],[944,70],[937,71],[135,72],[132,73],[147,72],[140,74],[145,75],[144,76],[134,77],[143,78],[148,79],[146,75],[142,80],[131,81],[136,82],[137,83],[138,84],[139,85],[133,76],[150,86],[153,87],[149,88],[141,89],[151,90],[157,91],[154,92],[156,93],[155,94],[837,95],[960,96],[958,97],[959,98],[918,99],[482,100],[483,101],[476,102],[477,103],[479,104],[480,105],[485,106],[486,107],[224,108],[225,109],[227,110],[228,111],[230,112],[231,113],[375,114],[376,115],[378,116],[379,117],[381,118],[382,119],[388,120],[389,121],[391,122],[392,123],[402,124],[403,125],[399,126],[400,127],[814,128],[815,129],[405,130],[406,131],[411,132],[412,133],[396,134],[397,135],[394,136],[408,137],[409,138],[432,139],[433,140],[414,141],[415,142],[417,143],[418,144],[420,145],[421,146],[426,147],[427,148],[429,149],[430,150],[437,151],[438,152],[233,153],[234,154],[440,155],[441,156],[816,157],[443,158],[444,159],[760,160],[446,161],[447,162],[448,163],[449,164],[462,165],[463,166],[451,167],[452,168],[454,169],[455,170],[457,171],[458,172],[465,173],[466,174],[468,175],[469,176],[473,177],[474,178],[488,179],[489,180],[385,181],[386,182],[494,183],[495,184],[500,185],[502,186],[501,187],[497,188],[498,189],[504,190],[505,191],[507,192],[508,193],[510,194],[511,195],[831,196],[832,197],[513,198],[514,199],[818,181],[819,200],[820,201],[821,202],[519,203],[520,204],[516,205],[517,206],[522,207],[523,208],[528,209],[529,210],[525,211],[526,212],[833,213],[538,214],[537,215],[532,216],[531,217],[492,218],[491,219],[535,220],[534,221],[435,222],[541,223],[540,224],[544,225],[543,226],[565,227],[564,228],[553,229],[552,230],[547,231],[546,232],[556,233],[555,234],[550,235],[549,236],[559,237],[558,238],[562,239],[561,240],[568,241],[567,242],[579,243],[578,244],[571,245],[570,246],[573,247],[572,248],[582,249],[581,250],[460,251],[459,252],[586,253],[585,254],[583,255],[266,256],[265,47],[268,257],[267,258],[271,259],[269,260],[274,261],[273,262],[277,263],[276,264],[272,47],[812,265],[278,47],[279,266],[281,267],[287,268],[286,258],[288,269],[291,270],[290,269],[283,271],[285,272],[373,273],[296,274],[293,275],[292,276],[294,277],[299,278],[300,279],[298,280],[297,47],[313,281],[309,282],[308,47],[312,283],[311,47],[307,284],[303,285],[302,286],[304,287],[306,288],[301,289],[317,290],[315,291],[327,292],[326,293],[325,294],[329,295],[328,47],[333,296],[331,297],[330,47],[337,298],[335,299],[334,289],[256,300],[255,301],[254,302],[253,47],[324,303],[320,304],[319,305],[321,306],[323,307],[318,308],[343,309],[341,310],[340,311],[339,47],[342,312],[347,313],[345,314],[344,47],[352,315],[349,316],[348,258],[357,317],[354,318],[353,258],[356,47],[363,319],[360,47],[359,320],[358,258],[362,47],[368,321],[365,322],[364,323],[367,47],[370,324],[369,47],[372,325],[371,47],[259,47],[262,326],[264,327],[263,47],[261,47],[177,328],[174,329],[173,330],[176,331],[175,330],[189,332],[190,333],[191,334],[188,335],[187,47],[170,336],[171,337],[196,338],[197,339],[159,340],[162,341],[163,342],[209,343],[207,47],[210,344],[212,345],[193,346],[192,347],[198,348],[165,349],[168,350],[169,351],[166,352],[164,352],[167,353],[195,354],[194,355],[206,356],[205,357],[202,358],[201,359],[761,360],[763,360],[764,360],[765,360],[767,47],[793,361],[770,360],[778,47],[779,47],[780,47],[785,47],[786,47],[790,47],[252,362],[248,363],[251,364],[244,365],[242,366],[241,366],[240,365],[237,366],[238,365],[246,367],[239,366],[236,365],[243,366],[249,368],[250,369],[245,370],[247,366],[822,371],[591,372],[590,373],[219,374],[595,375],[594,376],[598,377],[597,378],[222,379],[221,380],[576,381],[575,382],[258,383],[257,384],[823,385],[605,386],[604,387],[602,388],[599,389],[600,47],[601,390],[608,391],[607,392],[611,393],[610,394],[615,395],[614,396],[612,397],[618,398],[617,399],[471,400],[470,181],[620,401],[619,402],[626,403],[625,404],[623,405],[622,406],[630,407],[629,408],[636,409],[635,410],[639,411],[638,412],[641,413],[640,414],[663,415],[661,416],[662,47],[644,417],[643,418],[647,419],[646,420],[650,421],[649,422],[653,423],[652,424],[656,425],[655,426],[659,427],[658,428],[726,429],[724,430],[213,431],[214,432],[725,433],[215,434],[733,435],[738,436],[737,437],[739,438],[722,439],[721,440],[728,441],[731,442],[732,443],[729,444],[730,445],[723,446],[666,447],[665,448],[668,449],[667,450],[671,451],[670,452],[702,453],[701,454],[690,455],[689,456],[674,457],[673,458],[677,459],[676,460],[680,461],[679,462],[699,463],[698,464],[683,465],[682,466],[687,467],[686,468],[684,469],[693,470],[692,471],[696,472],[695,473],[708,474],[707,475],[705,476],[704,477],[824,478],[711,479],[710,480],[714,481],[713,482],[717,483],[716,484],[720,485],[719,486],[633,487],[632,488],[627,489],[384,490],[424,491],[423,492],[830,493],[829,494],[588,495],[592,47],[826,496],[794,497],[795,497],[796,498],[797,497],[798,497],[813,499],[799,497],[800,497],[801,497],[802,497],[803,497],[806,497],[807,497],[804,497],[808,497],[809,497],[805,497],[810,497],[828,500],[827,181],[158,47],[1025,501],[1021,1],[1023,502],[1024,1],[108,503],[1029,504],[1030,505],[1034,506],[1035,507],[1038,508],[964,509],[1046,510],[1045,511],[1043,512],[1040,513],[1048,503],[1050,514],[1051,515],[1053,516],[1055,517],[1056,517],[1057,517],[1060,518],[1058,519],[1059,519],[1061,47],[1065,520],[1066,521],[1075,522],[1074,523],[1079,99],[1081,524],[1082,525],[1080,526],[1083,527],[1084,528],[1085,529],[1086,530],[1087,531],[1088,532],[1089,533],[1090,534],[1091,535],[1092,536],[1094,516],[1098,537],[1099,538],[1097,537],[1104,539],[66,540],[67,541],[70,542],[71,543],[73,544],[74,544],[75,545],[76,546],[77,547],[78,548],[107,549],[79,544],[81,550],[84,551],[85,552],[88,544],[89,553],[90,544],[93,554],[95,555],[99,556],[101,542],[104,557],[105,542],[1106,544],[1109,558],[1108,559],[1110,503],[1115,47],[1117,47],[1118,47],[1119,47],[1120,47],[1122,560],[1124,561],[1123,562],[1125,47],[1126,47],[1127,490],[1131,563],[1129,47],[383,47],[1128,490],[1146,47],[1136,564],[1137,565],[1132,47],[1138,566],[1139,47],[1135,567],[1140,566],[1133,568],[1141,568],[1142,569],[1143,47],[1134,568],[1144,47],[1145,570],[56,571],[57,47],[1147,572],[1149,503],[1028,573],[1151,503],[1154,574],[1155,575],[1158,576],[963,577],[1160,578],[1175,579],[1174,580],[1165,581],[1166,582],[1173,583],[1167,582],[1168,581],[1169,581],[1170,581],[1171,584],[1164,585],[1172,580],[1176,586],[1178,587],[1180,588],[839,589],[841,590],[1102,573],[1069,591],[1071,592],[1070,591],[1026,544],[1073,593],[98,594],[59,595],[112,596],[113,597],[114,598],[117,599],[118,600],[119,601],[120,602],[122,603],[124,604],[123,600],[125,605],[116,606],[126,607],[995,608],[980,609],[986,609],[987,610],[982,609],[967,609],[984,609],[985,611],[983,609],[970,612],[836,613],[979,614],[981,609],[969,615],[968,609],[971,616],[834,617],[835,618],[996,609],[999,609],[1001,619],[1000,609],[997,609],[998,609],[1002,620],[1003,609],[1004,609],[1008,621],[1007,609],[1005,609],[1006,609],[988,622],[992,609],[989,609],[994,623],[993,624],[991,625],[990,626],[961,627],[966,628],[965,629],[1010,609],[1013,630],[1012,631],[1009,609],[1018,632],[1011,633],[1017,634],[1016,635],[1015,636],[1014,637],[975,638],[978,639],[974,609],[977,609],[976,640],[972,609],[973,641]],\"exportedModulesMap\":[[1022,1],[928,2],[916,3],[914,4],[915,5],[929,6],[926,7],[927,8],[925,9],[921,10],[922,11],[923,12],[924,13],[846,14],[847,15],[848,14],[849,16],[913,17],[863,18],[861,18],[888,19],[876,20],[856,21],[886,20],[887,20],[890,22],[891,20],[858,23],[892,20],[893,20],[894,20],[895,20],[896,24],[897,25],[898,20],[854,20],[899,20],[900,20],[901,24],[902,20],[903,20],[904,26],[905,20],[906,22],[907,20],[855,20],[908,20],[909,20],[910,27],[853,28],[859,29],[889,30],[862,31],[911,4],[864,32],[865,33],[874,34],[873,35],[869,36],[868,35],[870,37],[867,38],[866,39],[872,40],[871,37],[875,41],[857,42],[852,43],[850,44],[851,45],[880,24],[877,44],[179,46],[182,47],[184,48],[181,49],[183,50],[180,51],[185,49],[186,52],[939,53],[942,54],[931,55],[932,56],[933,57],[935,58],[946,59],[947,60],[941,61],[948,62],[949,63],[950,63],[940,64],[957,65],[952,59],[951,66],[953,67],[943,68],[954,62],[955,60],[945,69],[956,66],[944,70],[937,71],[135,72],[132,73],[147,72],[140,74],[145,75],[144,76],[134,77],[143,78],[148,79],[146,75],[142,80],[131,81],[136,82],[137,83],[138,84],[139,85],[133,76],[150,86],[153,87],[149,88],[141,89],[151,90],[157,91],[154,92],[156,93],[155,94],[837,95],[960,96],[958,97],[959,98],[918,99],[482,100],[483,101],[476,102],[477,103],[479,104],[480,105],[485,106],[486,107],[224,108],[225,109],[227,110],[228,111],[230,112],[231,113],[375,114],[376,115],[378,116],[379,117],[381,118],[382,119],[388,120],[389,121],[391,122],[392,123],[402,124],[403,125],[399,126],[400,127],[814,128],[815,129],[405,130],[406,131],[411,132],[412,133],[396,134],[397,135],[394,136],[408,137],[409,138],[432,139],[433,140],[414,141],[415,142],[417,143],[418,144],[420,145],[421,146],[426,147],[427,148],[429,149],[430,150],[437,151],[438,152],[233,153],[234,154],[440,155],[441,156],[816,157],[443,158],[444,159],[760,160],[446,161],[447,162],[448,163],[449,164],[462,165],[463,166],[451,167],[452,168],[454,169],[455,170],[457,171],[458,172],[465,173],[466,174],[468,175],[469,176],[473,177],[474,178],[488,179],[489,180],[385,181],[386,182],[494,183],[495,184],[500,185],[502,186],[501,187],[497,188],[498,189],[504,190],[505,191],[507,192],[508,193],[510,194],[511,195],[831,196],[832,197],[513,198],[514,199],[818,181],[819,200],[820,201],[821,202],[519,203],[520,204],[516,205],[517,206],[522,207],[523,208],[528,209],[529,210],[525,211],[526,212],[833,213],[538,214],[537,215],[532,216],[531,217],[492,218],[491,219],[535,220],[534,221],[435,222],[541,223],[540,224],[544,225],[543,226],[565,227],[564,228],[553,229],[552,230],[547,231],[546,232],[556,233],[555,234],[550,235],[549,236],[559,237],[558,238],[562,239],[561,240],[568,241],[567,242],[579,243],[578,244],[571,245],[570,246],[573,247],[572,248],[582,249],[581,250],[460,251],[459,252],[586,253],[585,254],[583,255],[266,256],[265,47],[268,257],[267,258],[271,259],[269,260],[274,261],[273,262],[277,263],[276,264],[272,47],[812,265],[278,47],[279,266],[281,267],[287,268],[286,258],[288,269],[291,270],[290,269],[283,271],[285,272],[373,273],[296,274],[293,275],[292,276],[294,277],[299,278],[300,279],[298,280],[297,47],[313,281],[309,282],[308,47],[312,283],[311,47],[307,284],[303,285],[302,286],[304,287],[306,288],[301,289],[317,290],[315,291],[327,292],[326,293],[325,294],[329,295],[328,47],[333,296],[331,297],[330,47],[337,298],[335,299],[334,289],[256,300],[255,301],[254,302],[253,47],[324,303],[320,304],[319,305],[321,306],[323,307],[318,308],[343,309],[341,310],[340,311],[339,47],[342,312],[347,313],[345,314],[344,47],[352,315],[349,316],[348,258],[357,317],[354,318],[353,258],[356,47],[363,319],[360,47],[359,320],[358,258],[362,47],[368,321],[365,322],[364,323],[367,47],[370,324],[369,47],[372,325],[371,47],[259,47],[262,326],[264,327],[263,47],[261,47],[177,328],[174,329],[173,330],[176,331],[175,330],[189,332],[190,333],[191,334],[188,335],[187,47],[170,336],[171,337],[196,338],[197,339],[159,340],[162,341],[163,342],[209,343],[207,47],[210,344],[212,345],[193,346],[192,347],[198,348],[165,349],[168,350],[169,351],[166,352],[164,352],[167,353],[195,354],[194,355],[206,356],[205,357],[202,358],[201,359],[761,360],[763,360],[764,360],[765,360],[767,47],[793,361],[770,360],[778,47],[779,47],[780,47],[785,47],[786,47],[790,47],[252,362],[248,363],[251,364],[244,365],[242,366],[241,366],[240,365],[237,366],[238,365],[246,367],[239,366],[236,365],[243,366],[249,368],[250,369],[245,370],[247,366],[822,371],[591,372],[590,373],[219,374],[595,375],[594,376],[598,377],[597,378],[222,379],[221,380],[576,381],[575,382],[258,383],[257,384],[823,385],[605,386],[604,387],[602,388],[599,389],[600,47],[601,390],[608,391],[607,392],[611,393],[610,394],[615,395],[614,396],[612,397],[618,398],[617,399],[471,400],[470,181],[620,401],[619,402],[626,403],[625,404],[623,405],[622,406],[630,407],[629,408],[636,409],[635,410],[639,411],[638,412],[641,413],[640,414],[663,415],[661,416],[662,47],[644,417],[643,418],[647,419],[646,420],[650,421],[649,422],[653,423],[652,424],[656,425],[655,426],[659,427],[658,428],[726,429],[724,430],[213,431],[214,432],[725,433],[215,434],[733,435],[738,436],[737,437],[739,438],[722,439],[721,440],[728,441],[731,442],[732,443],[729,444],[730,445],[723,446],[666,447],[665,448],[668,449],[667,450],[671,451],[670,452],[702,453],[701,454],[690,455],[689,456],[674,457],[673,458],[677,459],[676,460],[680,461],[679,462],[699,463],[698,464],[683,465],[682,466],[687,467],[686,468],[684,469],[693,470],[692,471],[696,472],[695,473],[708,474],[707,475],[705,476],[704,477],[824,478],[711,479],[710,480],[714,481],[713,482],[717,483],[716,484],[720,485],[719,486],[633,487],[632,488],[627,489],[384,490],[424,491],[423,492],[830,493],[829,494],[588,495],[592,47],[826,496],[794,497],[795,497],[796,498],[797,497],[798,497],[813,499],[799,497],[800,497],[801,497],[802,497],[803,497],[806,497],[807,497],[804,497],[808,497],[809,497],[805,497],[810,497],[828,500],[827,181],[158,47],[1025,501],[1021,1],[1023,502],[1024,1],[108,503],[1029,504],[1030,505],[1034,506],[1035,507],[1038,508],[964,509],[1046,510],[1045,511],[1043,512],[1040,513],[1048,503],[1050,514],[1051,515],[1053,516],[1055,517],[1056,517],[1057,517],[1060,518],[1058,519],[1059,519],[1061,47],[1065,520],[1066,521],[1075,522],[1074,523],[1079,99],[1081,524],[1082,525],[1080,526],[1083,527],[1084,528],[1085,529],[1086,530],[1087,531],[1088,532],[1089,533],[1090,534],[1091,535],[1092,536],[1094,516],[1098,537],[1099,538],[1097,537],[1104,539],[66,540],[67,541],[70,542],[71,543],[73,544],[74,544],[75,545],[76,546],[77,547],[78,548],[107,549],[79,544],[81,550],[84,551],[85,552],[88,544],[89,553],[90,544],[93,554],[95,555],[99,556],[101,542],[104,557],[105,542],[1106,544],[1109,558],[1108,559],[1110,503],[1115,47],[1117,47],[1118,47],[1119,47],[1120,47],[1122,560],[1124,561],[1123,562],[1125,47],[1126,47],[1127,490],[1131,563],[1129,47],[383,47],[1128,490],[1146,47],[1136,564],[1137,565],[1132,47],[1138,566],[1139,47],[1135,567],[1140,566],[1133,568],[1141,568],[1142,569],[1143,47],[1134,568],[1144,47],[1145,570],[56,571],[57,47],[1147,572],[1149,503],[1028,573],[1151,503],[1154,574],[1155,575],[1158,576],[963,577],[1160,578],[1175,579],[1174,580],[1165,581],[1166,582],[1173,583],[1167,582],[1168,581],[1169,581],[1170,581],[1171,584],[1164,585],[1172,580],[1176,586],[1178,587],[1180,588],[839,589],[841,590],[1102,573],[1069,591],[1071,592],[1070,591],[1026,544],[1073,593],[98,594],[59,595],[112,596],[113,597],[114,598],[117,599],[118,600],[119,601],[120,602],[122,603],[124,604],[123,600],[125,605],[116,606],[126,607],[995,608],[980,609],[986,609],[987,610],[982,609],[967,609],[984,609],[985,611],[983,609],[970,612],[836,613],[979,614],[981,609],[969,615],[968,609],[971,616],[834,617],[835,618],[996,609],[999,609],[1001,619],[1000,609],[997,609],[998,609],[1002,620],[1003,609],[1004,609],[1008,621],[1007,609],[1005,609],[1006,609],[988,622],[992,609],[989,609],[994,623],[993,624],[991,625],[990,626],[961,627],[966,628],[965,629],[1010,609],[1013,630],[1012,631],[1009,609],[1018,632],[1011,633],[1017,634],[1016,635],[1015,636],[1014,637],[975,638],[978,639],[974,609],[977,609],[976,640],[972,609],[973,641]],\"semanticDiagnosticsPerFile\":[1022,1020,842,928,916,917,914,915,929,919,926,920,927,925,921,843,922,923,924,845,846,847,848,849,844,913,863,861,912,888,876,856,886,887,890,891,858,892,893,894,895,896,897,898,854,899,900,901,902,903,904,905,906,907,855,908,909,910,853,859,889,862,911,864,865,874,873,869,868,870,867,866,872,871,875,857,852,850,860,851,881,882,879,880,878,883,877,885,884,179,182,184,181,183,180,185,186,178,939,942,931,932,933,930,935,934,936,946,947,941,948,949,950,940,957,952,951,953,943,954,955,945,956,944,937,938,135,132,147,140,145,144,134,143,148,146,142,131,136,137,138,139,133,150,128,153,129,149,127,141,152,110,151,157,154,156,60,155,61,837,960,958,959,918,482,481,483,476,475,477,479,478,480,485,484,486,224,223,225,227,226,228,230,229,231,375,374,376,378,377,379,381,380,382,388,387,389,391,390,392,402,401,403,399,398,400,814,815,405,404,406,411,410,412,396,395,397,394,393,408,407,409,432,431,433,414,413,415,417,416,418,420,419,421,426,425,427,429,428,430,437,436,438,233,232,234,440,439,441,816,443,442,444,740,741,742,743,744,745,746,747,748,749,760,750,751,752,753,754,755,756,757,758,759,446,445,447,448,449,817,462,461,463,451,450,452,454,453,455,457,456,458,465,464,466,468,467,469,473,472,474,488,487,489,385,386,494,493,495,500,499,502,501,497,496,498,504,503,505,507,506,508,510,509,511,831,832,513,512,514,818,819,820,821,519,518,520,516,515,517,522,521,523,528,527,529,525,524,526,833,538,537,536,532,531,530,492,491,490,535,534,533,435,434,541,540,539,544,543,542,565,564,563,553,552,551,547,546,545,556,555,554,550,549,548,559,558,557,562,561,560,568,567,566,579,578,577,571,570,569,573,572,582,581,580,460,459,586,585,584,583,266,265,268,270,267,271,269,274,273,275,277,276,272,811,812,278,279,280,281,287,286,289,288,291,290,282,283,284,285,373,296,293,295,292,294,299,300,298,297,313,309,308,310,312,311,307,303,302,305,304,306,301,317,316,315,314,327,326,325,329,328,333,331,332,330,337,335,336,334,256,255,254,253,324,320,319,322,321,323,318,343,341,338,340,339,342,347,345,346,344,352,349,350,348,351,357,354,355,353,356,363,360,359,361,358,362,368,365,366,364,367,370,369,372,371,259,260,262,264,263,261,172,177,174,173,176,175,189,190,191,188,187,170,171,204,196,197,159,161,162,163,160,209,211,207,210,208,212,193,192,198,165,168,169,166,164,167,195,194,206,205,202,200,201,199,203,771,761,772,773,762,774,763,764,765,766,767,787,768,793,791,775,776,777,769,770,778,792,788,779,782,783,780,784,785,781,786,789,790,252,248,235,251,244,242,241,240,237,238,246,239,236,243,249,250,245,247,822,591,590,589,219,595,594,593,598,597,596,222,221,220,576,575,574,258,257,823,605,604,603,602,599,600,601,608,607,606,611,610,609,615,614,613,612,618,617,616,471,470,620,619,626,625,624,623,622,621,630,629,628,636,635,634,639,638,637,641,640,663,661,660,662,644,643,642,647,646,645,650,649,648,653,652,651,656,655,654,659,658,657,726,724,213,214,727,725,217,215,733,738,737,739,734,722,721,728,216,731,732,729,730,723,735,736,218,666,665,664,668,667,671,670,669,702,701,700,690,689,688,674,673,672,677,676,675,680,679,678,699,698,697,683,682,681,687,686,684,685,693,692,691,696,695,694,708,707,706,705,704,703,824,711,710,709,714,713,712,717,716,715,720,719,718,633,632,631,627,384,424,423,422,830,829,588,587,592,826,825,794,795,796,797,798,813,799,800,801,802,803,806,807,804,808,809,805,810,828,827,158,1019,1025,1021,1023,1024,108,1029,1030,1031,1032,1034,1035,1036,1033,1038,964,1046,1044,1045,1047,1039,1043,1040,1042,1048,1050,1051,1053,1055,1056,1057,1054,1060,1058,1059,1061,1062,1027,1063,1064,1065,1066,1075,1074,1076,1077,1041,1078,1079,1081,1082,1080,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1096,1095,1098,1099,1097,1049,1100,1101,1037,1103,1104,62,64,65,66,67,68,69,70,71,72,73,74,75,63,106,76,77,78,107,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,99,100,101,102,103,104,105,1105,1106,1107,1109,1108,1110,1111,1112,54,1113,1114,1115,1116,1117,1118,1119,1120,1122,1124,1123,1125,1126,1130,1127,1131,1129,383,1128,1146,1136,1137,1132,1138,1139,1135,1140,1133,1141,1142,1143,1134,1144,1145,52,56,57,1147,1148,1149,1028,1150,55,1151,1152,1153,1154,1155,1156,1158,1157,963,962,1160,1052,1161,1177,1175,1174,1165,1166,1173,1167,1168,1169,1170,1171,1164,1172,1163,1176,1162,1178,1179,1180,839,840,841,130,109,53,838,1102,58,1067,1069,1071,1070,1068,1026,1073,1072,96,97,98,59,1121,1159,11,12,14,13,2,15,16,17,18,19,20,21,22,3,4,26,23,24,25,27,28,29,5,30,31,32,33,6,34,35,36,37,7,42,38,39,40,41,8,46,43,44,45,47,9,48,49,50,1,10,51,111,112,113,115,114,117,118,119,120,121,122,124,123,125,116,126,995,980,986,987,982,967,984,985,983,970,836,979,981,969,968,971,834,835,996,999,1001,1000,997,998,1002,1003,1004,1008,1007,1005,1006,988,992,989,994,993,991,990,961,966,965,1010,1013,1012,1009,[1018,[{\"file\":\"./static-resources/src/themes/index.ts\",\"start\":878,\"length\":4,\"messageText\":\"'size' is declared but its value is never read.\",\"category\":1,\"code\":6133,\"reportsUnnecessary\":true}]],1011,1017,1016,1015,1014,975,978,974,977,976,972,973],\"affectedFilesPendingEmit\":[[1022,1],[1020,1],[842,1],[928,1],[916,1],[917,1],[914,1],[915,1],[929,1],[919,1],[926,1],[920,1],[927,1],[925,1],[921,1],[843,1],[922,1],[923,1],[924,1],[845,1],[846,1],[847,1],[848,1],[849,1],[844,1],[913,1],[863,1],[861,1],[912,1],[888,1],[876,1],[856,1],[886,1],[887,1],[890,1],[891,1],[858,1],[892,1],[893,1],[894,1],[895,1],[896,1],[897,1],[898,1],[854,1],[899,1],[900,1],[901,1],[902,1],[903,1],[904,1],[905,1],[906,1],[907,1],[855,1],[908,1],[909,1],[910,1],[853,1],[859,1],[889,1],[862,1],[911,1],[864,1],[865,1],[874,1],[873,1],[869,1],[868,1],[870,1],[867,1],[866,1],[872,1],[871,1],[875,1],[857,1],[852,1],[850,1],[860,1],[851,1],[881,1],[882,1],[879,1],[880,1],[878,1],[883,1],[877,1],[885,1],[884,1],[179,1],[182,1],[184,1],[181,1],[183,1],[180,1],[185,1],[186,1],[178,1],[939,1],[942,1],[931,1],[932,1],[933,1],[930,1],[935,1],[934,1],[936,1],[946,1],[947,1],[941,1],[948,1],[949,1],[950,1],[940,1],[957,1],[952,1],[951,1],[953,1],[943,1],[954,1],[955,1],[945,1],[956,1],[944,1],[937,1],[938,1],[135,1],[132,1],[147,1],[140,1],[145,1],[144,1],[134,1],[143,1],[148,1],[146,1],[142,1],[131,1],[136,1],[137,1],[138,1],[139,1],[133,1],[150,1],[128,1],[153,1],[129,1],[149,1],[127,1],[141,1],[152,1],[110,1],[151,1],[157,1],[154,1],[156,1],[60,1],[155,1],[61,1],[837,1],[960,1],[958,1],[959,1],[918,1],[482,1],[481,1],[483,1],[476,1],[475,1],[477,1],[479,1],[478,1],[480,1],[485,1],[484,1],[486,1],[224,1],[223,1],[225,1],[227,1],[226,1],[228,1],[230,1],[229,1],[231,1],[375,1],[374,1],[376,1],[378,1],[377,1],[379,1],[381,1],[380,1],[382,1],[388,1],[387,1],[389,1],[391,1],[390,1],[392,1],[402,1],[401,1],[403,1],[399,1],[398,1],[400,1],[814,1],[815,1],[405,1],[404,1],[406,1],[411,1],[410,1],[412,1],[396,1],[395,1],[397,1],[394,1],[393,1],[408,1],[407,1],[409,1],[432,1],[431,1],[433,1],[414,1],[413,1],[415,1],[417,1],[416,1],[418,1],[420,1],[419,1],[421,1],[426,1],[425,1],[427,1],[429,1],[428,1],[430,1],[437,1],[436,1],[438,1],[233,1],[232,1],[234,1],[440,1],[439,1],[441,1],[816,1],[443,1],[442,1],[444,1],[740,1],[741,1],[742,1],[743,1],[744,1],[745,1],[746,1],[747,1],[748,1],[749,1],[760,1],[750,1],[751,1],[752,1],[753,1],[754,1],[755,1],[756,1],[757,1],[758,1],[759,1],[446,1],[445,1],[447,1],[448,1],[449,1],[817,1],[462,1],[461,1],[463,1],[451,1],[450,1],[452,1],[454,1],[453,1],[455,1],[457,1],[456,1],[458,1],[465,1],[464,1],[466,1],[468,1],[467,1],[469,1],[473,1],[472,1],[474,1],[488,1],[487,1],[489,1],[385,1],[386,1],[494,1],[493,1],[495,1],[500,1],[499,1],[502,1],[501,1],[497,1],[496,1],[498,1],[504,1],[503,1],[505,1],[507,1],[506,1],[508,1],[510,1],[509,1],[511,1],[831,1],[832,1],[513,1],[512,1],[514,1],[818,1],[819,1],[820,1],[821,1],[519,1],[518,1],[520,1],[516,1],[515,1],[517,1],[522,1],[521,1],[523,1],[528,1],[527,1],[529,1],[525,1],[524,1],[526,1],[833,1],[538,1],[537,1],[536,1],[532,1],[531,1],[530,1],[492,1],[491,1],[490,1],[535,1],[534,1],[533,1],[435,1],[434,1],[541,1],[540,1],[539,1],[544,1],[543,1],[542,1],[565,1],[564,1],[563,1],[553,1],[552,1],[551,1],[547,1],[546,1],[545,1],[556,1],[555,1],[554,1],[550,1],[549,1],[548,1],[559,1],[558,1],[557,1],[562,1],[561,1],[560,1],[568,1],[567,1],[566,1],[579,1],[578,1],[577,1],[571,1],[570,1],[569,1],[573,1],[572,1],[582,1],[581,1],[580,1],[460,1],[459,1],[586,1],[585,1],[584,1],[583,1],[266,1],[265,1],[268,1],[270,1],[267,1],[271,1],[269,1],[274,1],[273,1],[275,1],[277,1],[276,1],[272,1],[811,1],[812,1],[278,1],[279,1],[280,1],[281,1],[287,1],[286,1],[289,1],[288,1],[291,1],[290,1],[282,1],[283,1],[284,1],[285,1],[373,1],[296,1],[293,1],[295,1],[292,1],[294,1],[299,1],[300,1],[298,1],[297,1],[313,1],[309,1],[308,1],[310,1],[312,1],[311,1],[307,1],[303,1],[302,1],[305,1],[304,1],[306,1],[301,1],[317,1],[316,1],[315,1],[314,1],[327,1],[326,1],[325,1],[329,1],[328,1],[333,1],[331,1],[332,1],[330,1],[337,1],[335,1],[336,1],[334,1],[256,1],[255,1],[254,1],[253,1],[324,1],[320,1],[319,1],[322,1],[321,1],[323,1],[318,1],[343,1],[341,1],[338,1],[340,1],[339,1],[342,1],[347,1],[345,1],[346,1],[344,1],[352,1],[349,1],[350,1],[348,1],[351,1],[357,1],[354,1],[355,1],[353,1],[356,1],[363,1],[360,1],[359,1],[361,1],[358,1],[362,1],[368,1],[365,1],[366,1],[364,1],[367,1],[370,1],[369,1],[372,1],[371,1],[259,1],[260,1],[262,1],[264,1],[263,1],[261,1],[172,1],[177,1],[174,1],[173,1],[176,1],[175,1],[189,1],[190,1],[191,1],[188,1],[187,1],[170,1],[171,1],[204,1],[196,1],[197,1],[159,1],[161,1],[162,1],[163,1],[160,1],[209,1],[211,1],[207,1],[210,1],[208,1],[212,1],[193,1],[192,1],[198,1],[165,1],[168,1],[169,1],[166,1],[164,1],[167,1],[195,1],[194,1],[206,1],[205,1],[202,1],[200,1],[201,1],[199,1],[203,1],[771,1],[761,1],[772,1],[773,1],[762,1],[774,1],[763,1],[764,1],[765,1],[766,1],[767,1],[787,1],[768,1],[793,1],[791,1],[775,1],[776,1],[777,1],[769,1],[770,1],[778,1],[792,1],[788,1],[779,1],[782,1],[783,1],[780,1],[784,1],[785,1],[781,1],[786,1],[789,1],[790,1],[252,1],[248,1],[235,1],[251,1],[244,1],[242,1],[241,1],[240,1],[237,1],[238,1],[246,1],[239,1],[236,1],[243,1],[249,1],[250,1],[245,1],[247,1],[822,1],[591,1],[590,1],[589,1],[219,1],[595,1],[594,1],[593,1],[598,1],[597,1],[596,1],[222,1],[221,1],[220,1],[576,1],[575,1],[574,1],[258,1],[257,1],[823,1],[605,1],[604,1],[603,1],[602,1],[599,1],[600,1],[601,1],[608,1],[607,1],[606,1],[611,1],[610,1],[609,1],[615,1],[614,1],[613,1],[612,1],[618,1],[617,1],[616,1],[471,1],[470,1],[620,1],[619,1],[626,1],[625,1],[624,1],[623,1],[622,1],[621,1],[630,1],[629,1],[628,1],[636,1],[635,1],[634,1],[639,1],[638,1],[637,1],[641,1],[640,1],[663,1],[661,1],[660,1],[662,1],[644,1],[643,1],[642,1],[647,1],[646,1],[645,1],[650,1],[649,1],[648,1],[653,1],[652,1],[651,1],[656,1],[655,1],[654,1],[659,1],[658,1],[657,1],[726,1],[724,1],[213,1],[214,1],[727,1],[725,1],[217,1],[215,1],[733,1],[738,1],[737,1],[739,1],[734,1],[722,1],[721,1],[728,1],[216,1],[731,1],[732,1],[729,1],[730,1],[723,1],[735,1],[736,1],[218,1],[666,1],[665,1],[664,1],[668,1],[667,1],[671,1],[670,1],[669,1],[702,1],[701,1],[700,1],[690,1],[689,1],[688,1],[674,1],[673,1],[672,1],[677,1],[676,1],[675,1],[680,1],[679,1],[678,1],[699,1],[698,1],[697,1],[683,1],[682,1],[681,1],[687,1],[686,1],[684,1],[685,1],[693,1],[692,1],[691,1],[696,1],[695,1],[694,1],[708,1],[707,1],[706,1],[705,1],[704,1],[703,1],[824,1],[711,1],[710,1],[709,1],[714,1],[713,1],[712,1],[717,1],[716,1],[715,1],[720,1],[719,1],[718,1],[633,1],[632,1],[631,1],[627,1],[384,1],[424,1],[423,1],[422,1],[830,1],[829,1],[588,1],[587,1],[592,1],[826,1],[825,1],[794,1],[795,1],[796,1],[797,1],[798,1],[813,1],[799,1],[800,1],[801,1],[802,1],[803,1],[806,1],[807,1],[804,1],[808,1],[809,1],[805,1],[810,1],[828,1],[827,1],[158,1],[1019,1],[1025,1],[1021,1],[1023,1],[1024,1],[108,1],[1029,1],[1030,1],[1031,1],[1032,1],[1034,1],[1035,1],[1036,1],[1033,1],[1038,1],[964,1],[1046,1],[1044,1],[1045,1],[1047,1],[1039,1],[1043,1],[1040,1],[1042,1],[1048,1],[1050,1],[1051,1],[1053,1],[1055,1],[1056,1],[1057,1],[1054,1],[1060,1],[1058,1],[1059,1],[1061,1],[1062,1],[1027,1],[1063,1],[1064,1],[1065,1],[1066,1],[1075,1],[1074,1],[1076,1],[1077,1],[1041,1],[1078,1],[1079,1],[1081,1],[1082,1],[1080,1],[1083,1],[1084,1],[1085,1],[1086,1],[1087,1],[1088,1],[1089,1],[1090,1],[1091,1],[1092,1],[1093,1],[1094,1],[1096,1],[1095,1],[1098,1],[1099,1],[1097,1],[1049,1],[1100,1],[1101,1],[1037,1],[1103,1],[1104,1],[62,1],[64,1],[65,1],[66,1],[67,1],[68,1],[69,1],[70,1],[71,1],[72,1],[73,1],[74,1],[75,1],[63,1],[106,1],[76,1],[77,1],[78,1],[107,1],[79,1],[80,1],[81,1],[82,1],[83,1],[84,1],[85,1],[86,1],[87,1],[88,1],[89,1],[90,1],[91,1],[92,1],[93,1],[94,1],[95,1],[99,1],[100,1],[101,1],[102,1],[103,1],[104,1],[105,1],[1105,1],[1106,1],[1107,1],[1109,1],[1108,1],[1110,1],[1111,1],[1112,1],[54,1],[1113,1],[1114,1],[1115,1],[1116,1],[1117,1],[1118,1],[1119,1],[1120,1],[1122,1],[1124,1],[1123,1],[1125,1],[1126,1],[1130,1],[1127,1],[1131,1],[1129,1],[383,1],[1128,1],[1146,1],[1136,1],[1137,1],[1132,1],[1138,1],[1139,1],[1135,1],[1140,1],[1133,1],[1141,1],[1142,1],[1143,1],[1134,1],[1144,1],[1145,1],[52,1],[56,1],[57,1],[1147,1],[1148,1],[1149,1],[1028,1],[1150,1],[55,1],[1151,1],[1152,1],[1153,1],[1154,1],[1155,1],[1156,1],[1158,1],[1157,1],[963,1],[962,1],[1160,1],[1052,1],[1161,1],[1177,1],[1175,1],[1174,1],[1165,1],[1166,1],[1173,1],[1167,1],[1168,1],[1169,1],[1170,1],[1171,1],[1164,1],[1172,1],[1163,1],[1176,1],[1162,1],[1178,1],[1179,1],[1180,1],[839,1],[840,1],[841,1],[130,1],[109,1],[53,1],[838,1],[1102,1],[58,1],[1067,1],[1069,1],[1071,1],[1070,1],[1068,1],[1026,1],[1073,1],[1072,1],[96,1],[97,1],[98,1],[59,1],[1121,1],[1159,1],[2,1],[3,1],[4,1],[5,1],[6,1],[7,1],[8,1],[9,1],[10,1],[111,1],[112,1],[113,1],[115,1],[114,1],[117,1],[118,1],[119,1],[120,1],[121,1],[122,1],[124,1],[123,1],[125,1],[116,1],[126,1],[995,1],[980,1],[986,1],[987,1],[982,1],[967,1],[984,1],[985,1],[983,1],[970,1],[836,1],[979,1],[981,1],[969,1],[968,1],[971,1],[834,1],[835,1],[996,1],[999,1],[1001,1],[1000,1],[997,1],[998,1],[1002,1],[1003,1],[1004,1],[1008,1],[1007,1],[1005,1],[1006,1],[988,1],[992,1],[989,1],[994,1],[993,1],[991,1],[990,1],[961,1],[966,1],[965,1],[1010,1],[1013,1],[1012,1],[1009,1],[1018,1],[1011,1],[1017,1],[1016,1],[1015,1],[1014,1],[975,1],[978,1],[974,1],[977,1],[976,1],[972,1],[973,1]]},\"version\":\"4.6.3\"}"
  },
  {
    "path": "packages/component-lib/.babelrc",
    "content": "{\n  \"presets\": [\n    \"@babel/typescript\",\n    \"@babel/preset-env\",\n    \"@babel/preset-react\",\n    \"@emotion/babel-preset-css-prop\",\n    [\n      \"@babel/env\",\n      {\n        \"modules\": false\n      }\n    ]\n  ],\n  \"plugins\": [\n    \"@babel/plugin-proposal-class-properties\"\n  ]\n}\n"
  },
  {
    "path": "packages/component-lib/.eslintignore",
    "content": "*.css\n*.scss\n*.svg"
  },
  {
    "path": "packages/component-lib/.eslintrc.json",
    "content": "{\n  \"plugins\": [\n    \"react-hooks\"\n  ],\n  \"extends\": [\n    \"react-app\"\n  ],\n  \"overrides\": [\n    {\n      \"files\": [\n        \"**/*.tsx\",\n        \"**/*.ts\"\n      ],\n      \"rules\": {\n        \"import/no-anonymous-default-export\": \"off\",\n        \"@typescript-eslint/no-unused-vars\": \"off\",\n        \"react-hooks/rules-of-hooks\": \"error\",\n        // 检查 Hook 的规则\n        \"react-hooks/exhaustive-deps\": \"warn\"\n        // 检查 effect 的依赖\n      }\n    }\n  ]\n}\n"
  },
  {
    "path": "packages/component-lib/.gitignore",
    "content": "\n# See https://help.github.com/ignore-files/ for more about ignoring files.\n\n# dependencies\nnode_modules\n\n# builds\nbuild\ndist\n.rpt2_cache\n\n# misc\n.DS_Store\n.env\n.env.local\n.env.development.local\n.env.test.local\n.env.production.local\n.idea/**\n.vscode/**\n./component-lib/**\n./lib/**\n\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\nsrc/assets\nstorybook-static\n\n\n"
  },
  {
    "path": "packages/component-lib/.storybook/main.ts",
    "content": "import type { StorybookConfig } from '@storybook/react-webpack5'\nimport CopyWebpackPlugin from 'copy-webpack-plugin'\nimport path, { join, dirname } from 'path'\nimport MiniCssExtractPlugin from 'mini-css-extract-plugin'\nconst nodePath = '../../'\nconst toPath = (filePath) => path.join(process.cwd(), nodePath + filePath)\nconst disableEsLint = (e) => {\n  return (\n    e.module.rules\n      .filter((e) => e.use && e.use.some((e) => e.options && void 0 !== e.options.useEslintrc))\n      .forEach((s) => {\n        e.module.rules = e.module.rules.filter((e) => e !== s)\n      }),\n    e\n  )\n}\nfunction findBabelRules(config): any {\n  let result_rule = {}\n  config.module.rules.filter((rule) => {\n    // console.log(rule);\n    if (rule.oneOf) {\n      result_rule = rule.oneOf.find((rule) => {\n        return rule.test && rule.test.toString() === /\\.(js|mjs|jsx|ts|tsx)$/.toString()\n      })\n    }\n  })\n  return result_rule as any\n}\n\n/**\n * This function is used to resolve the absolute path of a package.\n * It is needed in projects that use Yarn PnP or are set up within a monorepo.\n */\nfunction getAbsolutePath(value: string): any {\n  return dirname(require.resolve(join(value, 'package.json')))\n}\nconst config: StorybookConfig = {\n  stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],\n  addons: [\n    getAbsolutePath('@storybook/addon-links'),\n    getAbsolutePath('@storybook/addon-essentials'),\n    getAbsolutePath('@storybook/preset-create-react-app'),\n    getAbsolutePath('@storybook/addon-onboarding'),\n    getAbsolutePath('@storybook/addon-interactions'),\n  ],\n  framework: {\n    name: '@storybook/react-webpack5',\n    options: {},\n  },\n  docs: {\n    autodocs: 'tag',\n  },\n  webpackFinal: async (config, { configType }) => {\n    config = disableEsLint(config)\n\n    // @ts-ignore\n    const isProd = configType.toLowerCase() === 'production'\n    const rule = findBabelRules(config)\n    const modules = [\n      // @ts-ignore\n      ...config?.resolve?.modules,\n      path.resolve(__dirname, '..', 'src'),\n      'node_modules/@loopring-web/common-resources',\n    ]\n    rule.include = [\n      ...rule.include,\n      path.resolve(__dirname, '..', '..', 'common-resources', 'static-resources'),\n    ]\n    rule.options.presets = [\n      [\n        '@babel/preset-env',\n        {\n          useBuiltIns: 'usage',\n          corejs: 3,\n          loose: true,\n          bugfixes: true,\n          modules: false,\n        },\n      ],\n      [\n        '@babel/preset-react',\n        {\n          useBuiltIns: true,\n        },\n      ],\n      ...rule.options.presets,\n    ]\n    console.log('rule.plugins:', rule.options.plugins)\n    // @ts-ignore\n    config.module.rules.push({\n      test: /\\.s(a|c)ss$/,\n      use: [\n        {\n          loader: MiniCssExtractPlugin.loader,\n          options: {\n            emit: false,\n            esModule: false,\n            hmr: false,\n          },\n        },\n        'css-loader',\n      ],\n    })\n    config.plugins = [\n      // @ts-ignore\n      ...config?.plugins,\n      // new MiniCssExtractPlugin({\n      //   filename: isProd ? '[name].[contenthash].css' : '[name].css',\n      //   chunkFilename: isProd ? '[id].[contenthash].css' : '[id].css',\n      //   ignoreOrder: true,\n      // }),\n      new webpack.ProvidePlugin({\n        Buffer: ['buffer', 'Buffer'],\n      }),\n      new CopyWebpackPlugin({\n        patterns: [\n          {\n            from: path.resolve(__dirname, '..', '..', 'common-resources', 'assets'),\n            to: './static',\n            toType: 'dir',\n          },\n        ],\n      }),\n    ]\n    return {\n      ...config,\n      // framework: getAbsolutePath('@storybook/react-webpack5'),\n      plugins: [...config.plugins],\n      resolve: {\n        ...config.resolve,\n        modules,\n        extensions: [...config?.resolve?.extensions, '.ts', '.js'],\n        fallback: {\n          ...config?.resolve?.fallback,\n          crypto: require.resolve('crypto-browserify'),\n          'crypto-js': require.resolve('crypto-js'),\n          'crypto-js/sha256': require.resolve('crypto-js/sha256'),\n          stream: require.resolve('stream-browserify'),\n          assert: require.resolve('assert'),\n          http: require.resolve('stream-http'),\n          https: require.resolve('https-browserify'),\n          os: require.resolve('os-browserify'),\n          url: require.resolve('url'),\n          util: require.resolve('util'),\n          buffer: require.resolve('buffer'),\n          timers: require.resolve('timers-browserify'),\n          'process/browser': require.resolve('process/browser'),\n        },\n        alias: {\n          // @ts-ignore\n          ...config.resolve.alias,\n          '@emotion/core': toPath('node_modules/@emotion/react'),\n          'emotion-theming': toPath('node_modules/@emotion/react'),\n          '@emotion/styled': toPath('node_modules/@emotion/styled'),\n          '@material-ui/core/Menu': '@mui/material/Menu',\n          '@material-ui/core': '@mui/material',\n          '@material-ui/core/Popover': '@mui/material/Popover',\n        },\n      },\n    }\n  },\n}\nexport default config\nexport const framework = '@storybook/react'\n\n// import CopyWebpackPlugin from 'copy-webpack-plugin'\n// import path from 'path'\n// const direct = '../../'\n// import { addBeforeLoader, getLoader, loaderByName } from '@craco/craco'\n// const toPath = (filePath) => path.join(process.cwd(), direct + filePath)\n// const disableEsLint = (e) => {\n//   return (\n//     e.module.rules\n//       .filter((e) => e.use && e.use.some((e) => e.options && void 0 !== e.options.useEslintrc))\n//       .forEach((s) => {\n//         e.module.rules = e.module.rules.filter((e) => e !== s)\n//       }),\n//       e\n//   )\n// }\n// const config = {\n//   stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],\n//   addons: [\n//     '@storybook/addon-links',\n//     // '@storybook/addon-essentials',\n//     '@storybook/preset-create-react-app',\n//     '@storybook/addon-onboarding',\n//     '@storybook/addon-interactions',\n//   ],\n//   framework: {\n//     name: '@storybook/react-webpack5', //getAbsolutePath('@storybook/react-webpack5'),\n//     options: {},\n//   },\n//   docs: {\n//     autodocs: 'tag',\n//   },\n//   webpackFinal: async (config, { configType }) => {\n//     config = disableEsLint(config)\n//     var { isFound, match } = getLoader(config, loaderByName('babel-loader'))\n//     if (isFound && match?.loader?.include) {\n//       match.loader.include = [\n//         //@ts-ignore\n//         ...match.loader.include,\n//         // toPath('packages/component-lib'),\n//         toPath('node_modules/@loopring-web/common-resources/static-resources'),\n//         toPath('node_modules/@loopring-web/loopring-sdk'),\n//       ]\n//       console.log('match?.loader', match?.loader)\n//     }\n//     // const rule = findBabelRules(config)\n//     // rule.include = [\n//     //   ...rule.include,\n//     //   path.resolve(__dirname, '..', '..', 'common-resources', 'static-resources'),\n//     // ]\n//     // var { isFound, match } = getLoader(config, loaderByName('babel-loader'))\n//     // if (isFound && match?.loader) {\n//     //   console.log(match.loader)\n//     //   match.loader.include = [\n//     //     path.resolve(__dirname, packagesPath),\n//     //     ...[\n//     //       path.resolve(\n//     //         __dirname,\n//     //         `${process.env.NODE_ENV === 'development' ? direct : direct}`,\n//     //         `node_modules/@web3modal`,\n//     //       ),\n//     //       path.resolve(\n//     //         __dirname,\n//     //         `${process.env.NODE_ENV === 'development' ? direct : direct}`,\n//     //         `node_modules/@walletconnect`,\n//     //       ),\n//     //       path.resolve(\n//     //         __dirname,\n//     //         `${process.env.NODE_ENV === 'development' ? direct : direct}`,\n//     //         `node_modules/@metamask`,\n//     //       ),\n//     //       path.resolve(\n//     //         __dirname,\n//     //         `${process.env.NODE_ENV === 'development' ? direct : direct}`,\n//     //         `node_modules/@scure`,\n//     //       ),\n//     //       path.resolve(\n//     //         __dirname,\n//     //         `${process.env.NODE_ENV === 'development' ? direct : direct}`,\n//     //         `node_modules/@noble`,\n//     //       ),\n//     //       path.resolve(\n//     //         __dirname,\n//     //         `${process.env.NODE_ENV === 'development' ? direct : direct}`,\n//     //         `node_modules/@ethereumjs`,\n//     //       ),\n//     //       path.resolve(\n//     //         __dirname,\n//     //         `${process.env.NODE_ENV === 'development' ? direct : direct}`,\n//     //         `node_modules/micro-ftch`,\n//     //       ),\n//     //       path.resolve(\n//     //         __dirname,\n//     //         `${process.env.NODE_ENV === 'development' ? direct : direct}`,\n//     //         `node_modules/react-spring`,\n//     //       ),\n//     //       path.resolve(\n//     //         __dirname,\n//     //         `${process.env.NODE_ENV === 'development' ? direct : direct}`,\n//     //         `node_modules/@react-spring`,\n//     //       ),\n//     //       path.resolve(\n//     //         __dirname,\n//     //         `${process.env.NODE_ENV === 'development' ? direct : direct}`,\n//     //         `node_modules/@loopring-web/loopring-sdk`,\n//     //       ),\n//     //     ],\n//     //   ]\n//     // }\n//     addBeforeLoader(config, loaderByName('babel-loader'), {\n//       loader: 'html-loader',\n//       test: /\\.html$/i,\n//       exclude: [/node_modules/, /index.html/i],\n//       options: {\n//         attrs: [':data-src'],\n//         minimize: true,\n//         removeComments: false,\n//         collapseWhitespace: false,\n//       },\n//     })\n//     // addBeforeLoader(config, loaderByName('babel-loader'), {\n//     //   test: /\\.md$/,\n//     //   use: 'raw-loader',\n//     // })\n//     config.resolve.extensions.push('.html')\n//     config.resolve.extensions.push('.md')\n//     return {\n//       ...config,\n//       // alias: {\n//       //   '@material-ui/core/Menu': '@mui/material/Menu',\n//       //   '@material-ui/core': '@mui/material',\n//       //   '@material-ui/core/Popover': '@mui/material/Popover',\n//       //   process: 'process/browser',\n//       // },\n//       plugins: [\n//         ...config.plugins,\n//         new CopyWebpackPlugin({\n//           patterns: [\n//             {\n//               from: toPath('packages/common-resources/assets'),\n//               to: './static',\n//               toType: 'dir',\n//             },\n//           ],\n//         }),\n//       ],\n//       resolve: {\n//         ...config.resolve,\n//         fallback: Object.assign(config.resolve.fallback ?? {}, {\n//           crypto: require.resolve('crypto-browserify'),\n//           'crypto-js': require.resolve('crypto-js'),\n//           'crypto-js/sha256': require.resolve('crypto-js/sha256'),\n//           stream: require.resolve('stream-browserify'),\n//           assert: require.resolve('assert/'),\n//           http: require.resolve('stream-http'),\n//           https: require.resolve('https-browserify'),\n//           os: require.resolve('os-browserify'),\n//           url: require.resolve('url/'),\n//           util: require.resolve('util'),\n//           buffer: require.resolve('buffer'),\n//           timers: require.resolve('timers-browserify'),\n//           'process/browser': require.resolve('process/browser'),\n//           // \"fs\": require.resolve('browserify-fs'),\n//         }),\n//         alias: {\n//           // @ts-ignore\n//           ...config.resolve.alias,\n//           '@emotion/core': toPath('node_modules/@emotion/react'),\n//           'emotion-theming': toPath('node_modules/@emotion/react'),\n//           '@emotion/styled': toPath('node_modules/@emotion/styled'),\n//           '@material-ui/core/Menu': '@mui/material/Menu',\n//           '@material-ui/core': '@mui/material',\n//           '@material-ui/core/Popover': '@mui/material/Popover',\n//         },\n//       },\n//     }\n//   },\n// }\n// export default config\n// export const framework = '@storybook/react'\n"
  },
  {
    "path": "packages/component-lib/.storybook/preview.tsx",
    "content": "import type { Preview } from '@storybook/react'\nimport { getTheme, globalCss, i18n } from '@loopring-web/common-resources'\nimport StoryRouter from 'storybook-react-router/dist/react'\nimport { ThemeProvider } from '@emotion/react'\nimport { Provider } from 'react-redux'\nimport { LocalizationProvider } from '@mui/lab'\nimport { I18nextProvider } from 'react-i18next'\nimport DateAdapter from '@mui/lab/AdapterMoment'\nimport createStorybookListener from 'storybook-addon-redux-listener'\nimport { GlobalStyles, ThemeProvider as MuThemeProvider } from '@mui/material'\nimport { applyMiddleware, combineReducers, compose, createStore } from 'redux'\nimport {\n  modalsSlice,\n  provider,\n  ProviderComposer,\n  setLanguage,\n  setTheme,\n  settingsSlice,\n} from '../src'\n\nexport const parameters = {\n  actions: { argTypesRegex: '^on[A-Z].*' },\n  // controls: {\n  //   matchers: {\n  //     color: /(background|color)$/i,\n  //     date: /Date$/,\n  //   },\n  // },\n  backgrounds: {\n    default: 'dark',\n    values: [\n      { name: 'dark', value: '#14172C' },\n      { name: 'light', value: '#ffffff' },\n    ],\n  },\n}\nexport const globalTypes = {\n  locale: {\n    name: 'Locale',\n    description: 'Internationalization locale',\n    defaultValue: 'zh_CN',\n    toolbar: {\n      icon: 'globe',\n      items: [\n        { value: 'en_US', right: 'en_US', title: 'English' },\n        { value: 'zh_CN', right: 'zh_CN', title: '中文' },\n      ],\n    },\n  },\n}\n\nconst preview: Preview = {\n  parameters: {\n    actions: { argTypesRegex: '^on[A-Z].*' },\n    controls: {\n      matchers: {\n        color: /(background|color)$/i,\n        date: /Date$/i,\n      },\n    },\n  },\n}\n\nconst middlewares: any[] = [\n  // window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__(),\n  //...getDefaultMiddleware({ thunk: true })      Button.stories.tsx\n]\nconst reducers = combineReducers({\n  settings: settingsSlice.reducer,\n  modals: modalsSlice.reducer,\n})\nif (process.env.NODE_ENV === 'storybook') {\n  const reduxListener = createStorybookListener()\n  middlewares.push(reduxListener)\n}\n// @ts-ignore\nconst composeEnhancers = (global ?? window)?.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose\n\nconst enhancer = composeEnhancers(\n  applyMiddleware(...middlewares),\n  // other stores enhancers if any\n)\n\nconst createStoreWithMiddleware = (reducers) => {\n  return createStore(reducers, enhancer)\n}\nconst configureStore = () => createStoreWithMiddleware(reducers)\nconst store = configureStore()\nexport const decorators = [\n  (Story, context) => {\n    const { backgrounds, locale } = context.globals\n    const themeMode = backgrounds && backgrounds.value === '#ffffff' ? 'light' : 'dark'\n    store.dispatch(setLanguage(locale))\n    store.dispatch(setTheme(themeMode))\n    // @ts-ignore\n    const theme = getTheme(store.getState().settings.themeMode)\n    StoryRouter()\n    return (\n      <ProviderComposer\n        providers={\n          [\n            // @ts-ignore\n            provider(LocalizationProvider, { dateAdapter: DateAdapter }),\n            // @ts-ignore\n            provider(I18nextProvider, { i18n: i18n }),\n            // @ts-ignore\n            provider(MuThemeProvider, { theme: theme }),\n            // @ts-ignore\n            provider(ThemeProvider, { theme: theme }),\n            // @ts-ignore\n            provider(Provider, { store }),\n          ] as any\n        }\n      >\n        <style type='text/css'>\n          {`.sb-show-main.sb-main-padded{\n            padding:0.01em;  \n          }\n        `}\n        </style>\n        <GlobalStyles styles={globalCss({ theme })}></GlobalStyles>\n        <Story {...{ context }}> </Story>\n      </ProviderComposer>\n    )\n  },\n]\n"
  },
  {
    "path": "packages/component-lib/.travis.yml",
    "content": "language: node_js\nnode_js:\n  - 8\nenv:\n  - SKIP_PREFLIGHT_CHECK=true\n"
  },
  {
    "path": "packages/component-lib/README.md",
    "content": "# component-lib\n\n> Loopring UI component lib\n\n[![NPM](https://img.shields.io/npm/v/component-lib.svg)](https://www.npmjs.com/package/component-lib) [![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)\n\n## Install\n\n```bash\nnpm install --save component-lib\n```\n\n## Usage\n\n```tsx\nimport * as React from 'react'\n\n<\nProviderComposer\nproviders = {\n    [\n        provider(LocalizationProvider, {dateAdapter: MomentUtils}),\n    provider(I18nextProvider, {i18n}),\n    provider(ThemeProvider),\n]\n}>\n<\nStory\n{...\n    context\n}\n/>\n</ProviderComposer>\n</Global><Global styles={\n    `${globalCss}`\n}\n>\n<\nProviderComposer\nproviders = {\n    [\n        provider(LocalizationProvider, {dateAdapter: MomentUtils}),\n    provider(I18nextProvider, {i18n}),\n    provider(ThemeProvider),\n]\n}>\n<\nStory\n{...\n    context\n}\n/>\n</ProviderComposer>\n</Global>\n\n\"@loopring-web/static-resource\": \"file:../static-resource/src\",\n\n```\n\n## License\n\nMIT © [Loopring dev Team](https://github.com/Loopring dev Team)\n\n---\n\nThis hook is created using [create-react-hook](https://github.com/hermanya/create-react-hook).\n"
  },
  {
    "path": "packages/component-lib/craco.config.cjs",
    "content": "module.exports = require(\"../../craco.config.cjs\")"
  },
  {
    "path": "packages/component-lib/package.json",
    "content": "{\n  \"name\": \"@loopring-web/component-lib\",\n  \"version\": \"1.0.0\",\n  \"main\": \"src/index.ts\",\n  \"private\": true,\n  \"resolutions\": {\n    \"**/@emotion/styled\": \"^11.1.5\"\n  },\n  \"dependencies\": {\n    \"@loopring-web/common-resources\": \"1.0.0\",\n    \"@storybook/cli\": \"^7.6.4\",\n    \"cross-env\": \"^7.0.3\",\n    \"react\": \"^18.2.0\",\n    \"react-dom\": \"^18.2.0\",\n    \"react-scripts\": \"5.0.1\"\n  },\n  \"scripts\": {\n    \"rollup:build\": \"rollup --config --no-stdin\",\n    \"release:version\": \"lerna version --exact --no-changelog --no-push --no-git-tag-version\",\n    \"release:build\": \"lerna run --parallel --scope \\\"@loopring-web/*\\\" build\",\n    \"test\": \"react-scripts-rewired test\",\n    \"eject\": \"react-scripts eject\",\n    \"build-storybook\": \"storybook build\",\n    \"build\": \"NODE_ENV=production storybook build -c .storybook_back --quiet \",\n    \"storybook\": \"storybook dev -p 6006\"\n  },\n  \"eslintConfig\": {\n    \"extends\": [\n      \"react-app\"\n    ],\n    \"overrides\": [\n      {\n        \"files\": [\n          \"**/*.stories.*\"\n        ],\n        \"rules\": {\n          \"import/no-anonymous-default-export\": \"off\"\n        }\n      },\n      {\n        \"files\": [\n          \"**/*.stories.*\"\n        ],\n        \"rules\": {\n          \"import/no-anonymous-default-export\": \"off\"\n        }\n      }\n    ]\n  },\n  \"browserslist\": {\n    \"production\": [\n      \">0.2%\",\n      \"not dead\",\n      \"not op_mini all\"\n    ],\n    \"development\": [\n      \"last 1 chrome version\",\n      \"last 1 firefox version\",\n      \"last 1 safari version\"\n    ]\n  },\n  \"devDependencies\": {\n    \"@emotion/react\": \"^11.1.5\",\n    \"@emotion/server\": \"^11.0.0\",\n    \"@rollup/plugin-commonjs\": \"^18.0.0\",\n    \"@rollup/plugin-node-resolve\": \"^11.2.1\",\n    \"@rollup/plugin-typescript\": \"^8.2.1\",\n    \"@rollup/plugin-url\": \"^6.0.0\",\n    \"@storybook/addon-actions\": \"^7.6.4\",\n    \"@storybook/addon-essentials\": \"^7.6.4\",\n    \"@storybook/addon-interactions\": \"^7.6.4\",\n    \"@storybook/addon-links\": \"^7.6.4\",\n    \"@storybook/addon-onboarding\": \"^1.0.10\",\n    \"@storybook/blocks\": \"^7.6.4\",\n    \"@storybook/builder-webpack5\": \"^7.6.4\",\n    \"@storybook/cli\": \"^7.6.4\",\n    \"@storybook/manager-webpack5\": \"^6.5.16\",\n    \"@storybook/node-logger\": \"^7.6.4\",\n    \"@storybook/preset-create-react-app\": \"^7.6.4\",\n    \"@storybook/react\": \"^7.6.4\",\n    \"@storybook/react-webpack5\": \"^7.6.4\",\n    \"@storybook/test\": \"^7.6.4\",\n    \"@storybook/testing-library\": \"^0.2.2\",\n    \"@testing-library/jest-dom\": \"^5.11.4\",\n    \"@testing-library/react\": \"^11.1.0\",\n    \"@testing-library/user-event\": \"^12.1.10\",\n    \"@types/d3-format\": \"^2.0.0\",\n    \"@types/d3-time-format\": \"^3.0.0\",\n    \"@typescript-eslint/eslint-plugin\": \"^4.21.0\",\n    \"arr-flatten\": \"^1.1.0\",\n    \"babel-plugin-named-asset-import\": \"0.3.8\",\n    \"babel-plugin-react-require\": \"^3.1.3\",\n    \"eslint-plugin-storybook\": \"^0.6.15\",\n    \"prop-types\": \"^15.8.1\",\n    \"repeat-element\": \"^1.1.3\",\n    \"rollup\": \"2.30\",\n    \"rollup-plugin-font\": \"^1.1.1\",\n    \"rollup-plugin-json\": \"^4.0.0\",\n    \"rollup-plugin-peer-deps-external\": \"^2.2.4\",\n    \"rollup-plugin-svg\": \"^2.0.0\",\n    \"rollup-plugin-typescript2\": \"^0.30.0\",\n    \"snapdragon-node\": \"^3.0.0\",\n    \"storybook\": \"^7.6.4\",\n    \"storybook-addon-redux-listener\": \"^0.1.7\",\n    \"storybook-react-router\": \"^1.0.8\",\n    \"mini-css-extract-plugin\": \"^2.7.6\"\n  }\n}\n"
  },
  {
    "path": "packages/component-lib/rollup.config.js",
    "content": "import ts from 'rollup-plugin-typescript2'\nimport typescript from 'typescript'\nimport commonjs from '@rollup/plugin-commonjs'\nimport resolve from '@rollup/plugin-node-resolve'\nimport external from 'rollup-plugin-peer-deps-external'\nimport svg from 'rollup-plugin-svg'\nimport url from '@rollup/plugin-url'\nimport json from 'rollup-plugin-json'\n// importfont  from \"rollup-plugin-font\";\n\n// import pkg from './package.json'\n\nexport default {\n  input: './src/DualListPanel.tsx',\n  output: [\n    {\n      file: './dist/bundle.cjs', //pkg.main,\n      format: 'cjs',\n      preferConst: true,\n      interop: false,\n      //exports: 'named',\n      sourcemap: true,\n    },\n    {\n      file: './dist/bundle.js', //pkg.module,\n      format: 'es',\n      preferConst: true,\n      //exports: 'named',\n      sourcemap: true,\n    },\n  ],\n  plugins: [\n    external(),\n    url({ exclude: ['**/*.svg'] }),\n    url({\n      include: ['**/*.ttf', '**/*.eot', '**/*.woff', '**/*.woff2'],\n      limit: Infinity,\n    }),\n    resolve(),\n    ts({ typescript }),\n    svg(),\n    commonjs({ extensions: ['.js', '.ts'] }),\n    json({\n      // 默认情况下将解析所有JSON文件,\n      // 但您可以专门包含/排除文件\n      // exclude: [ 'node_modules/foo/**', 'node_modules/bar/**' ],\n      // exclude: [ 'node_modules/foo/**', 'node_modules/bar/**' ],\n\n      // 对于 tree-shaking, 属性将声明为\n      // 变量, 使用 `var` 或者 `const`\n      preferConst: true, // 默认是 false\n\n      // 为生成的默认导出指定缩进 —\n      // 默认为 '\\t'\n      indent: '  ',\n\n      // 忽略缩进并生成最小的代码\n      compact: true, // 默认是 false\n\n      // 为JSON对象的每个属性生成一个命名导出\n      namedExports: true, // 默认是 true\n    }),\n    //font()\n  ],\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/Icon.stories.tsx",
    "content": "import { Meta, Story } from '@storybook/react'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport styled from '@emotion/styled'\nimport { Grid, Typography } from '@mui/material'\nimport {\n  ActiveIcon,\n  AddIcon,\n  AlertIcon,\n  AmmRankIcon,\n  ApprovalIcon,\n  AssetsIcon,\n  AudioIcon,\n  BackIcon,\n  BanxaIcon,\n  CalendarIcon,\n  CardIcon,\n  CheckBoxIcon,\n  CheckedIcon,\n  CheckIcon,\n  CircleIcon,\n  ClockIcon,\n  CloseIcon,\n  CloseRedPacketIcon,\n  CompleteIcon,\n  ContactIcon,\n  ConvertToIcon,\n  CopyIcon,\n  DarkIcon,\n  DeleteIcon,\n  DepositIcon,\n  DepthFIcon,\n  DepthHIcon,\n  DiscordIcon,\n  DoneIcon,\n  DownloadIcon,\n  DragIcon,\n  DragListIcon,\n  DropDownIcon,\n  EditIcon,\n  EmptyIcon,\n  ErrorIcon,\n  ExchangeAIcon,\n  ExchangeIcon,\n  ExitIcon,\n  FailedIcon,\n  FavHollowIcon,\n  FavSolidIcon,\n  FirstPlaceIcon,\n  GoodIcon,\n  GoTopIcon,\n  GrowIcon,\n  HelpIcon,\n  HideIcon,\n  ImageIcon,\n  IncomingIcon,\n  Info2Icon,\n  InfoIcon,\n  KLineFeaturesIcon,\n  L1l2Icon,\n  L2HistoryIcon,\n  L2l2Icon,\n  L2MyLiquidityIcon,\n  L2OrderIcon,\n  LegacyIcon,\n  LightIcon,\n  LinkedIcon,\n  LinkIcon,\n  LoadingIcon,\n  LockGuardianIcon,\n  LockIcon,\n  LoopringDarkFooterIcon,\n  LoopringIcon,\n  LoopringLightFooterIcon,\n  LoopringLogoIcon,\n  MediumIcon,\n  MenuIcon,\n  MintIcon,\n  MoreIcon,\n  NFTIcon,\n  NoPhotosIcon,\n  NotificationIcon,\n  OrderListIcon,\n  OutputIcon,\n  PlayIcon,\n  ProfileIcon,\n  ProToLiteIcon,\n  QRIcon,\n  RampIcon,\n  RecordIcon,\n  RedPacketIcon,\n  RefreshIcon,\n  RefreshIPFSIcon,\n  RefuseIcon,\n  ResizeIcon,\n  ReverseIcon,\n  RewardIcon,\n  RoundAddIcon,\n  ScanQRIcon,\n  SearchIcon,\n  SecondPlaceIcon,\n  SecurityIcon,\n  SettingIcon,\n  SpeakerIcon,\n  StarHollowIcon,\n  StarSolidIcon,\n  SubmitIcon,\n  SwapSettingIcon,\n  SyncIcon,\n  ThirdPlaceIcon,\n  TransferIcon,\n  TrophyIcon,\n  TwitterIcon,\n  UnConnectIcon,\n  UpIcon,\n  UploadedIcon,\n  VideoIcon,\n  ViewHistoryIcon,\n  ViewIcon,\n  ViewMoreIcon,\n  VipIcon,\n  WaitApproveIcon,\n  WaitingIcon,\n  WarningIcon,\n  WarningIcon2,\n  WithdrawIcon,\n  YoutubeIcon,\n  ZoomIcon,\n  RiskAlertIcon,\n  RiskIcon,\n  AnotherIcon,\n  LinkSharedIcon,\n  ReadIcon,\n  MessageIcon,\n  GoIcon,\n  ThreeDIcon,\n  RoundCheckIcon,\n  RoundCircleIcon,\n  DiscordSvg,\n  BorderTickIcon,\n  MarginLevelIcon,\n  LoadIcon,\n  MarginIcon,\n  VaultTradeIcon,\n  CloseOutIcon,\n  SwapExchangeIcon,\n  Overview,\n  AmmLogo,\n  SatkingLogo,\n  DualInvestmentLogo,\n  DualUpIcon,\n  DualDownIcon,\n  DualConvertIcon,\n  DualBTCIcon,\n  DualChartDD,\n  DualChartDH,\n  DualChartHD,\n  DualChartHH,\n  VaultIcon,\n} from '@loopring-web/common-resources'\n\nconst Styled = styled.div`\n  background: var(--color-global-bg);\n\n  svg {\n    height: 24px !important;\n    width: 24px !important;\n  }\n`\n\n// @ts-ignore\nconst listIcon = [\n  <DepthHIcon />,\n  <DepthFIcon />,\n  <UpIcon />,\n  <DragIcon />,\n  <DragListIcon />,\n  <ResizeIcon />,\n  <AssetsIcon />,\n  <L2MyLiquidityIcon />,\n  <L2HistoryIcon />,\n  <RewardIcon />,\n  <RedPacketIcon />,\n  <SecurityIcon />,\n  <VipIcon />,\n  <L2OrderIcon />,\n  <CheckBoxIcon />,\n  <CheckedIcon />,\n  <ViewIcon />,\n  <HideIcon />,\n  <DropDownIcon />,\n  <BackIcon />,\n  <MoreIcon />,\n  <StarHollowIcon />,\n  <StarSolidIcon />,\n  <FavHollowIcon />,\n  <FavSolidIcon />,\n  <DownloadIcon />,\n  <NotificationIcon />,\n  <SettingIcon />,\n  <LinkIcon />,\n  <CopyIcon />,\n  <ReverseIcon />,\n  <HelpIcon />,\n  <CalendarIcon />,\n  <LinkedIcon />,\n  <ExchangeIcon />,\n  <CloseIcon />,\n  <SearchIcon />,\n  <MenuIcon />,\n  <QRIcon />,\n  <DoneIcon />,\n  <RefuseIcon />,\n  <SubmitIcon />,\n  <FailedIcon />,\n  <GoodIcon />,\n  <AlertIcon />,\n  <ErrorIcon />,\n  <InfoIcon />,\n  <UnConnectIcon />,\n  <LockIcon />,\n  <ProToLiteIcon />,\n  <CheckIcon />,\n  <LoadingIcon />,\n  <ActiveIcon />,\n  <RefreshIcon />,\n  <CompleteIcon />,\n  <WaitingIcon />,\n  <WarningIcon />,\n  <EmptyIcon />,\n  <CircleIcon />,\n  <GrowIcon />,\n  <NoPhotosIcon />,\n  <KLineFeaturesIcon />,\n  <LoopringDarkFooterIcon />,\n  <LoopringLightFooterIcon />,\n  <YoutubeIcon />,\n  <TwitterIcon />,\n  <MediumIcon />,\n  <DiscordIcon />,\n  <LoopringIcon />,\n  <LightIcon />,\n  <DarkIcon />,\n  <ExitIcon />,\n  <RampIcon />,\n  <BanxaIcon />,\n  <FirstPlaceIcon />,\n  <SecondPlaceIcon />,\n  <ThirdPlaceIcon />,\n  <TrophyIcon />,\n  <AmmRankIcon />,\n  <SpeakerIcon />,\n  <GoTopIcon />,\n  <NFTIcon />,\n  <RecordIcon />,\n  <WaitApproveIcon />,\n  <LoopringLogoIcon />,\n  <TransferIcon />,\n  <DepositIcon />,\n  <WithdrawIcon />,\n  <MintIcon />,\n  <AddIcon />,\n  <DeleteIcon />,\n  <ImageIcon />,\n  <Info2Icon />,\n  <IncomingIcon />,\n  <OutputIcon />,\n  <CardIcon />,\n  <L2l2Icon />,\n  <L1l2Icon />,\n  <ExchangeAIcon />,\n  <AudioIcon />,\n  <VideoIcon />,\n  <ThreeDIcon />,\n  <PlayIcon />,\n  <ProfileIcon />,\n  <OrderListIcon />,\n  <RefreshIPFSIcon />,\n  <ViewMoreIcon />,\n  <ZoomIcon />,\n  <LegacyIcon />,\n  <SyncIcon />,\n  <FavHollowIcon />,\n  <FavSolidIcon />,\n  <SwapSettingIcon />,\n  <WarningIcon2 />,\n  <RoundAddIcon />,\n  <ApprovalIcon />,\n  <LockGuardianIcon />,\n  <ViewHistoryIcon />,\n  <ScanQRIcon />,\n  <CloseRedPacketIcon />,\n  <ClockIcon />,\n  <CloseRedPacketIcon />,\n  <UploadedIcon />,\n  <ContactIcon />,\n  <UploadedIcon />,\n  <EditIcon />,\n  <ConvertToIcon />,\n  <AnotherIcon />,\n  <RiskIcon />,\n  <RiskAlertIcon />,\n  <RoundCheckIcon />,\n  <RoundCircleIcon />,\n  <DiscordSvg />,\n  <BorderTickIcon />,\n  <MarginLevelIcon />,\n  <LoadIcon />,\n  <MarginIcon />,\n  <VaultTradeIcon />,\n  <CloseOutIcon />,\n  <SwapExchangeIcon />,\n  <Overview />,\n  <AmmLogo />,\n  <SatkingLogo />,\n  <DualInvestmentLogo />,\n  <DualUpIcon />,\n  <DualDownIcon />,\n  <DualConvertIcon />,\n  <DualBTCIcon />,\n  <DualChartDD />,\n  <DualChartDH />,\n  <DualChartHD />,\n  <DualChartHH />,\n  <VaultIcon />,\n  <LinkSharedIcon />,\n  <ReadIcon />,\n  <MessageIcon />,\n  <GoIcon />,\n]\n\nexport const IconList: Story<any> = withTranslation()(({}: WithTranslation & any) => {\n  const view = listIcon.map((item, index) => {\n    return (\n      <Grid\n        key={index}\n        item\n        padding={2}\n        display={'flex'}\n        flexDirection={'column'}\n        alignItems={'center'}\n      >\n        {item}\n        <Typography padding={1} variant={'body2'}>\n          {item.type.name}\n        </Typography>\n      </Grid>\n    )\n  })\n\n  return (\n    <>\n      <Styled>\n        {/*<MemoryRouter initialEntries={['/']}>*/}\n        <Grid container>{view}</Grid>\n      </Styled>\n      {/*</MemoryRouter>*/}\n    </>\n  )\n}) as Story<any>\n\n//export const Button = Template.bind({});\n// @ts-ignore\nexport default {\n  title: 'Resource/IconsList',\n  component: IconList,\n  argTypes: {},\n} as Meta\n// LButton.args = {}\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/btns/BtnPercentage.tsx",
    "content": "/* Rectangle 340 */\nimport styled from '@emotion/styled'\nimport { BtnPercentageProps } from './Interface'\nimport { Box, Slider } from '@mui/material'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport React from 'react'\nimport { Mark } from '@mui/base/SliderUnstyled/SliderUnstyledProps'\nimport { myLog } from '@loopring-web/common-resources'\n\nconst StyledSlider = styled(Slider)`\n  && {\n    border: 0;\n\n    & .MuiSlider-mark {\n      width: 24px;\n      height: 24px;\n      line-height: initial;\n      box-sizing: border-box;\n      display: flex;\n      justify-content: center;\n      align-items: center;\n      cursor: pointer;\n      background: var(--opacity);\n      border: 0;\n      transform: translate(-50%, -50%);\n      z-index: 25;\n\n      :after {\n        content: '';\n        width: 8px;\n        height: 8px;\n        background: var(--color-box);\n        ${({ theme }) =>\n          theme.border.defaultFrame({\n            d_W: 1,\n            d_R: 2,\n            c_key: 'var(--color-secondary)',\n          })};\n      }\n    }\n\n    & .MuiSlider-markLabel {\n      line-height: initial;\n    }\n\n    & .MuiSlider-rail {\n      width: 100%;\n      height: 4px;\n      border-radius: 4px;\n      background-color: var(--color-divide);\n      z-index: 10;\n      transform: translateY(-50%);\n    }\n\n    & .MuiSlider-track {\n      width: 100%;\n      height: 4px;\n      border-radius: 4px;\n      background-color: var(--color-secondary);\n      z-index: 15;\n      transform: translateY(-50%);\n    }\n\n    & .MuiSlider-thumb {\n      z-index: 30;\n      transform: translate(-50%, -50%);\n      width: 18px;\n      height: 18px;\n      color: var(--color-button-pot);\n      margin-top: 0;\n      margin-left: 0;\n      ${({ theme }) =>\n        theme.border.defaultFrame({\n          d_W: 2,\n          d_R: 12,\n          c_key: 'var(--color-secondary)',\n        })};\n      box-shadow: initial;\n\n      input {\n        cursor: pointer;\n      }\n\n      .MuiSlider-valueLabel {\n        background: var(--opacity);\n        padding: 0;\n        top: -4px;\n      }\n    }\n  }\n` as typeof Slider\n\nexport const BtnPercentage = withTranslation('common')(\n  ({\n    selected = -1,\n    handleChanged,\n    anchors,\n    valueLabelDisplay = 'off',\n    valuetext,\n    step = 1,\n    t,\n    tReady,\n    ...rest\n  }: BtnPercentageProps & WithTranslation) => {\n    const [value, setValue] = React.useState<number>(selected)\n\n    React.useEffect(() => {\n      myLog('selected', selected)\n      if (selected >= 0 && selected <= 100) {\n        setValue(Math.floor(selected))\n      } else {\n        setValue(0)\n      }\n    }, [selected])\n    const _anchors: Mark[] =\n      anchors && anchors.length\n        ? anchors\n        : [\n            {\n              value: 0,\n              label: '0',\n            },\n            {\n              value: 25,\n              label: '',\n            },\n            {\n              value: 50,\n              label: '',\n            },\n            {\n              value: 75,\n              label: '',\n            },\n            {\n              value: 100,\n              label: t('labelMax:') + '100%',\n            },\n          ]\n    const _handleChanged = (_event: Event, value: number | number[], _activeThumb: number) => {\n      setValue(value as number)\n      handleChanged(value)\n    }\n    const _valuetext = (value: number): string | number => {\n      if (valuetext) {\n        return valuetext(value)\n      } else {\n        return value\n      }\n    }\n    // function valuetext(value: number) {\n    //     return `${value}°C`;\n    // }\n    return (\n      <Box width={'100%'} display={'flex'}>\n        <StyledSlider\n          {...rest}\n          aria-label='Always visible'\n          value={value}\n          getAriaValueText={_valuetext as any}\n          valueLabelDisplay={valueLabelDisplay}\n          onChange={(_event, value, _activeThumb) => {\n            _handleChanged(_event, value, _activeThumb)\n          }}\n          step={step}\n          marks={_anchors}\n        />\n      </Box>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/btns/Button.stories.tsx",
    "content": "import React from 'react'\nimport { Meta, Story } from '@storybook/react'\n\nimport { Box, Breadcrumbs, Grid, Link, Pagination, Switch, Typography } from '@mui/material'\nimport { ButtonProps, TGItemData, TGItemJSXInterface } from './Interface'\nimport {\n  BtnPercentage,\n  Button,\n  LinkActionStyle,\n  ModalCloseButton,\n  ToggleButtonGroup,\n} from './index'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport styled from '@emotion/styled'\n\nconst Styled = styled.div`\n  background: var(--color-global-bg);\n`\nconst toggleData: TGItemData[] = [\n  { value: '15M', key: '15m' },\n  { value: '1H', key: '1h' },\n  { value: '4HHH', key: '4HHH', disabled: true },\n  { value: '1D', key: '1d' },\n]\nconst ToggleButtonDefault = withTranslation()(({ ...rest }: any) => {\n  const [value, setValue] = React.useState('4H')\n  const [values, setValues] = React.useState(['4H', '1H'])\n  const [cValue, setCValues] = React.useState('4H')\n  const tgItemJSXs: TGItemJSXInterface[] = toggleData.map(({ value, label, key, disabled }) => {\n    return {\n      value,\n      tlabel: rest.t(label),\n      disabled,\n      JSX: <>C {rest.t(key)}</>,\n    }\n  })\n  const handleChange = (_e: React.MouseEvent, value: any) => {\n    setCValues(value)\n  }\n  return (\n    <Grid container direction={'column'} spacing={2}>\n      <Grid item>\n        {' '}\n        <ToggleButtonGroup\n          exclusive\n          size={'large'}\n          {...{ ...rest, data: toggleData, value, setValue }}\n        />\n      </Grid>\n      <Grid item>\n        {' '}\n        <ToggleButtonGroup\n          size={'medium'}\n          {...{ ...rest, fata: toggleData, value: values, setValue: setValues }}\n        />\n      </Grid>\n      <Grid item>\n        {' '}\n        <ToggleButtonGroup\n          size={'small'}\n          exclusive\n          {...{\n            ...rest,\n            data: toggleData,\n            value,\n            setValue,\n            size: 'small',\n          }}\n        />\n      </Grid>\n      <Grid item>\n        {' '}\n        <ToggleButtonGroup\n          size={'small'}\n          exclusive\n          {...{\n            ...rest,\n            tgItemJSXs,\n            value: cValue,\n            handleChange,\n            size: 'small',\n          }}\n        />\n      </Grid>\n    </Grid>\n  )\n})\nconst PaginationControlled = () => {\n  const [page, setPage] = React.useState(1)\n  const handleChange = (_event: React.ChangeEvent<unknown>, value: number) => {\n    setPage(value)\n  }\n\n  return (\n    <>\n      <Typography>Page: {page}</Typography>\n      <Pagination color={'primary'} count={10} page={page} onChange={handleChange} />\n    </>\n  )\n}\n\nexport const LButton: Story<ButtonProps> = withTranslation()(\n  ({ t, ...rest }: WithTranslation & any) => {\n    const [switched, setSwitched] = React.useState(false)\n    /*********Toggle Button**********/\n    const [selected, setSelected] = React.useState(-1)\n    /*********Toggle **********/\n\n    return (\n      <>\n        <Styled>\n          <h4>Button</h4>\n          <Box>\n            <Grid\n              container\n              spacing={2}\n              alignContent={'center'}\n              justifyContent={'flex-start'}\n              flexWrap={'nowrap'}\n            >\n              <Grid item xs={6} margin={2}>\n                <Button variant={'contained'} size={'large'} color={'primary'} fullWidth={true}>\n                  {t(`Large contained FullWidth 58`)}\n                </Button>\n              </Grid>\n            </Grid>\n            <Grid container spacing={2} alignContent={'center'} justifyContent={'space-between'}>\n              <Grid item>\n                <Grid container direction={'column'} spacing={2}>\n                  <Grid item>\n                    {' '}\n                    <Button variant={'contained'} size={'large'} color={'primary'}>\n                      Large contained 58{' '}\n                    </Button>\n                  </Grid>\n                  <Grid item>\n                    {' '}\n                    <Button\n                      variant={'contained'}\n                      size={'large'}\n                      color={'primary'}\n                      disabled={true}\n                      loading={'true'}\n                    >\n                      Large contained 58{' '}\n                    </Button>\n                  </Grid>\n                </Grid>\n              </Grid>\n              <Grid item>\n                <Grid container direction={'column'} spacing={2}>\n                  <Grid item>\n                    <Button variant={'contained'} size={'medium'} color={'primary'}>\n                      default contained 44\n                    </Button>\n                  </Grid>\n                  <Grid item>\n                    <Button variant={'contained'} size={'medium'} color={'primary'} disabled={true}>\n                      default contained 44\n                    </Button>\n                  </Grid>\n                </Grid>\n              </Grid>\n              <Grid item>\n                <Grid container direction={'column'} spacing={2}>\n                  <Grid item>\n                    {' '}\n                    <Button variant={'contained'} size={'small'} color={'primary'}>\n                      small contained 32\n                    </Button>\n                  </Grid>\n                  <Grid item>\n                    {' '}\n                    <Button variant={'outlined'} size={'medium'} color={'primary'}>\n                      outline default 32\n                    </Button>\n                  </Grid>\n                  <Grid item>\n                    {' '}\n                    <Button variant={'outlined'} size={'medium'} color={'secondary'}>\n                      outline primary 32\n                    </Button>\n                  </Grid>\n                  <Grid item>\n                    {' '}\n                    <Button variant={'outlined'} size={'medium'} disabled={true}>\n                      outline default 32\n                    </Button>\n                  </Grid>\n                </Grid>\n              </Grid>\n              <Grid item>\n                <Button variant={'outlined'} size={'small'} color={'primary'}>\n                  outline small 28\n                </Button>\n              </Grid>\n              <Grid item>\n                <Typography color={'textPrimary'} variant={'body1'}>\n                  <LinkActionStyle color={'textPrimary'}>xxxxxxxxxxx</LinkActionStyle>\n                </Typography>\n              </Grid>\n              <Grid item>\n                <ModalCloseButton {...{ t, ...rest }} />\n              </Grid>\n              <Grid item>\n                <Button variant={'text'} size={'medium'} color={'primary'}>\n                  Text Btn\n                </Button>\n                <Button variant={'text'} size={'medium'} color={'primary'} disabled>\n                  Text Btn\n                </Button>\n              </Grid>\n              <Grid item>\n                <Link underline={'none'}>Test Link</Link>\n              </Grid>\n            </Grid>\n          </Box>\n\n          <h4>Tab Button</h4>\n          <Grid container spacing={2} alignContent={'center'} justifyContent={'space-around'}>\n            <Grid item margin={2}>\n              <Grid container direction={'column'} spacing={2}>\n                <Grid item>\n                  <Switch\n                    checked={switched}\n                    color='default'\n                    onChange={(e) => setSwitched(e.target.checked)}\n                  />\n                </Grid>\n                <Grid item>\n                  <Switch\n                    checked={!switched}\n                    color='default'\n                    onChange={(e) => setSwitched(!e.target.checked)}\n                  />\n                </Grid>\n                <Grid item>\n                  <Switch\n                    checked={switched}\n                    disabled\n                    color='default'\n                    onChange={(e) => setSwitched(e.target.checked)}\n                  />\n                </Grid>\n              </Grid>\n            </Grid>\n            <Grid item xs={6}>\n              <h4>Pagination</h4>\n              <Grid item marginY={1}>\n                <PaginationControlled />\n              </Grid>\n              <h4>Percentage selector</h4>\n              <Grid item marginY={1}>\n                <BtnPercentage\n                  selected={selected}\n                  handleChanged={(value: any) => {\n                    console.log(value)\n                    setSelected(value)\n                  }}\n                />\n              </Grid>\n            </Grid>\n\n            <Grid item>\n              <ToggleButtonDefault />\n            </Grid>\n            <Grid item>\n              <Breadcrumbs aria-label='breadcrumb'>\n                <Link color='textSecondary' href='/'>\n                  Material-UI\n                </Link>\n                <Link color='textSecondary' href='/'>\n                  Core\n                </Link>\n                <Typography color='textPrimary'>Breadcrumb</Typography>\n              </Breadcrumbs>\n            </Grid>\n          </Grid>\n          <h4>Font</h4>\n          <Grid\n            container\n            spacing={2}\n            alignContent={'left'}\n            justifyContent={'flex-start'}\n            direction={'column'}\n          >\n            <Grid item>\n              <Typography variant={'h1'}>Font size h1 48</Typography>\n            </Grid>\n            <Grid item>\n              <Typography variant={'h2'}>Font size h2 36</Typography>\n            </Grid>\n            <Grid item>\n              <Typography variant={'h3'}>Font size h3 24</Typography>\n            </Grid>\n            <Grid item>\n              <Typography variant={'h4'}>Font size h4 20</Typography>\n            </Grid>\n            <Grid item>\n              <Typography variant={'h5'}>Font size h5 16</Typography>\n            </Grid>\n            <Grid item>\n              <Typography variant={'h6'}>Font size h6 12</Typography>\n            </Grid>\n            <Grid item>\n              <Typography variant={'subtitle1'}>Font size subtitle1</Typography>\n            </Grid>\n            <Grid item>\n              <Typography variant={'body1'}>Font size body1</Typography>\n            </Grid>\n            <Grid item>\n              <Typography variant={'body2'}>Font size body2</Typography>\n            </Grid>\n          </Grid>\n          {/*<Grid container spacing={2} alignContent={'center'} justifyContent={'space-around'}>*/}\n          {/*    /!*<Grid item> <Button variant={'outlined'} size={'large'} color={'primary'}>Large primary outlined</Button>*!/*/}\n          {/*    /!*</Grid>*!/*/}\n          {/*    <Grid item xs={4}> <Button variant={'outlined'} size={'medium'} color={'primary'}>default primary outlined</Button>*/}\n          {/*    </Grid>*/}\n          {/*    <Grid item> <Button variant={'outlined'} size={'small'} color={'primary'}>small primary outlined</Button>*/}\n          {/*    </Grid>*/}\n          {/*</Grid>*/}\n          {/*<Grid container spacing={2} alignContent={'center'} justifyContent={'space-around'}>*/}\n          {/*    /!*<Grid item> <Button variant={'outlined'} size={'large'} color={'secondary'}>Large secondary*!/*/}\n          {/*    /!*    outlined</Button> </Grid>*!/*/}\n          {/*    <Grid item> <Button variant={'outlined'} size={'medium'} color={'secondary'}>default secondary*/}\n          {/*        outlined</Button></Grid>*/}\n          {/*    <Grid item> <Button variant={'outlined'} size={'small'} color={'secondary'}>small secondary*/}\n          {/*        outlined</Button> </Grid>*/}\n          {/*</Grid>*/}\n        </Styled>\n        {/*</MemoryRouter>*/}\n      </>\n    )\n  },\n) as Story<ButtonProps>\n\n//export const Button = Template.bind({});\n\nexport default {\n  title: 'basic-lib/Buttons',\n  component: LButton,\n  argTypes: {},\n} as Meta\n// LButton.args = {}\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/btns/Button.tsx",
    "content": "import {\n  Box,\n  Button as MuButton,\n  IconButton,\n  Link,\n  ToggleButton,\n  ToggleButtonGroup as MuToggleButtonGroup,\n  useScrollTrigger,\n  Zoom,\n  Tabs as MuTabs,\n} from '@mui/material'\nimport { ButtonProps, TGItemJSXInterface, ToggleButtonGroupProps } from './Interface'\nimport { TFunction, withTranslation, WithTranslation } from 'react-i18next'\nimport styled from '@emotion/styled'\nimport { BackIcon, CloseIcon, QRIcon, SoursURL } from '@loopring-web/common-resources'\nimport React from 'react'\nimport { SxProps } from '@mui/system'\nimport { Theme } from '@mui/material/styles'\n\nconst loadingSvg = SoursURL + 'svg/loading.svg'\n\nexport const Button = styled(MuButton)<ButtonProps>`\n  && {\n    line-height: 1em;\n\n    &:hover {\n      cursor: pointer;\n    }\n    &.MuiButton-outlined {\n      background-color: transparent;\n      :hover {\n        border-color: var(--color-primary);\n      }\n    }\n\n    &.MuiButton-root.Mui-disabled {\n      color: var(--color-text-button-disabled);\n      background-color: var(--color-button-disabled);\n      ${({ loading, theme, loadingbg }) => {\n        return loading === 'true'\n          ? `\n           color:transparent;\n           background-color:${theme.colorBase.primary};\n           background-color:${loadingbg};\n           &::after{\n            display: block;\n            content: url(${loadingSvg});\n            height: 40px;\n            width: 40px;\n            position: absolute;\n            transform:scale(.55);\n            display:flex;\n            flex-direction:row;\n            align-items: center;\n            justify-content: center;\n            color:#fff  \n           }\n       `\n          : ''\n      }}\n    }\n\n    &.disabledViewOnly {\n      pointer-events: inherit;\n    }\n  }\n\n  //&.disabled{\n  //\n  //}\n` as (props: ButtonProps) => JSX.Element\n\nexport function ScrollTop({\n  // anchorTopRef,\n  ...props\n}: {\n  children: React.ReactElement\n  // anchorTopRef?: React.Ref<any>;\n}) {\n  const { children } = props\n\n  const trigger = useScrollTrigger({\n    target: window ? window : undefined,\n    disableHysteresis: true,\n    threshold: 100,\n  })\n\n  const scrollToTop = React.useCallback((event: React.MouseEvent<HTMLDivElement>) => {\n    const anchor =\n      (event.currentTarget as HTMLDivElement).parentElement || //.ownerDocument || document\n      document.querySelector('#back-to-top-anchor')\n    if (anchor) {\n      window.scrollTo(0, anchor?.offsetTop)\n    }\n  }, [])\n\n  return (\n    <Zoom in={trigger}>\n      <Box\n        position={'fixed'}\n        role='presentation'\n        bottom={24}\n        right={24}\n        zIndex={9999}\n        display={'flex'}\n        flexDirection={'column'}\n        alignItems={'center'}\n        onClick={scrollToTop}\n        title={'go top'}\n      >\n        {children}\n      </Box>\n    </Zoom>\n  )\n}\n\nexport const MuToggleButtonGroupStyle = styled(MuToggleButtonGroup)`\n  ${({ theme, size }) =>\n    size !== 'small'\n      ? `\n      background: var(--color-box);\n      padding: ${theme.unit / 2}px;\n      padding-right: ${theme.unit / 4}px;\n      box-shadow: var(--shadow3);\n  `\n      : ``};\n\n  .MuiToggleButton-sizeSmall {\n    background: var(--color-box);\n    height: 2.4rem;\n    font-size: 1.2rem;\n    margin-right: ${({ theme }) => theme.unit}px;\n    border: ${({ theme }) => theme.border.borderConfig({ c_key: 'var(--color-border)' })};\n    color: var(--color-text-secondary);\n\n    &:not(:first-of-type),\n    &:not(:last-child) {\n      border-color: var(--color-border);\n    }\n\n    &:hover {\n      //backgroundColor: var(--color-box);\n      // color: var(--color-primary);\n      color: var(--color-text-button-select);\n      border: ${({ theme }) => theme.border.borderConfig({ c_key: 'var(--color-border-hover)' })};\n      background: var(--color-box);\n      // &:not(:last-child), &:not(:first-of-type) {\n      border: ${({ theme }) => theme.border.borderConfig({ c_key: 'var(--color-primary)' })};\n      // }\n\n      &.Mui-selected,\n      &.Mui-selected {\n        //background: var(--opacity);\n        background: var(--color-box);\n        // color: var(--color-primary);\n        color: var(--color-text-button-select);\n        border: ${({ theme }) => theme.border.borderConfig({ c_key: 'var(--color-primary)' })};\n        /* border: ${({ theme }) =>\n          theme.border.borderConfig({ c_key: 'var(--color-border-hover)' })}; */\n      }\n    }\n\n    &.Mui-disabled {\n      //background ;\n      background: var(--opacity);\n      color: var(--color-disable);\n      border: 1px dashed var(--color-border);\n    }\n\n    &.Mui-selected,\n    &.Mui-selected + &.Mui-selected {\n      // color: var(--color-primary);\n      color: var(--color-text-button-select) !important;\n      background: var(--color-box) !important;\n      //background:  var(--color-disable);\n      border: ${({ theme }) => theme.border.borderConfig({ c_key: 'var(--color-primary)' })};\n      /* border: ${({ theme }) =>\n        theme.border.borderConfig({ c_key: 'var(--color-border-hover)' })}; */\n    }\n  }\n` as typeof MuToggleButtonGroup\n\nexport const ToggleButtonGroup = withTranslation('common')(\n  ({\n    t,\n    value,\n    // handleChange,\n    size = 'medium',\n    tgItemJSXs,\n    data,\n    exclusive,\n    onChange,\n  }: { t: TFunction } & ToggleButtonGroupProps) => {\n    const _handleChange = React.useCallback(\n      (_e: React.MouseEvent<HTMLElement, MouseEvent>, value: any) => {\n        // setValue(value)\n        if (onChange) {\n          onChange(_e, value)\n        }\n      },\n      [onChange],\n    )\n    if (data) {\n      tgItemJSXs = data.map(({ value, key, disabled }) => {\n        return { value, JSX: t(key), tlabel: t(key), disabled }\n      })\n    }\n    return (\n      <MuToggleButtonGroupStyle\n        size={size}\n        value={value}\n        exclusive={exclusive}\n        onChange={_handleChange}\n      >\n        {tgItemJSXs?.map(({ value, JSX, tlabel, disabled, key, notWrap }: TGItemJSXInterface) =>\n          notWrap ? (\n            <Box key={key ? key : value}>{JSX}</Box>\n          ) : (\n            <ToggleButton\n              key={key ? key : value}\n              value={value}\n              aria-label={tlabel}\n              disabled={disabled}\n            >\n              {JSX}\n            </ToggleButton>\n          ),\n        )}\n      </MuToggleButtonGroupStyle>\n    )\n  },\n)\n\nexport const ModalCloseButton = ({\n  onClose,\n  className = '',\n  closeIcon = <CloseIcon />,\n  t,\n}: {\n  className?: string\n  closeIcon?: JSX.Element\n  onClose?: {\n    bivarianceHack(event: {}, reason: 'backdropClick' | 'escapeKeyDown'): void\n  }['bivarianceHack']\n} & { t: TFunction }) => {\n  return (\n    <Box\n      className={`close-button ${className}`}\n      alignSelf={'flex-end'}\n      position={'absolute'}\n      zIndex={99}\n      marginTop={'-27px'}\n      marginRight={1}\n    >\n      <IconButton\n        size={'large'}\n        aria-label={t('labelClose')}\n        color={'inherit'}\n        onClick={(event) => {\n          // myLog(\"IconButton escapeKeyDown\");\n          onClose && onClose(event, 'escapeKeyDown')\n        }}\n      >\n        {closeIcon}\n      </IconButton>\n    </Box>\n  )\n}\n\nexport const ModalCloseButtonPosition = ({\n  onClose,\n  className = '',\n  closeIcon = <CloseIcon />,\n  t,\n  right,\n  top,\n}: {\n  className?: string\n  closeIcon?: JSX.Element\n  onClose?: {\n    bivarianceHack(event: {}, reason: 'backdropClick' | 'escapeKeyDown'): void\n  }['bivarianceHack']\n  right?: number\n  top?: number\n} & { t: TFunction }) => {\n  return (\n    <Box\n      className={`close-button ${className}`}\n      alignSelf={'flex-end'}\n      position={'absolute'}\n      zIndex={99}\n      right={right}\n      top={top}\n    >\n      <IconButton\n        size={'large'}\n        aria-label={t('labelClose')}\n        color={'inherit'}\n        onClick={(event) => {\n          onClose && onClose(event, 'escapeKeyDown')\n        }}\n      >\n        {closeIcon}\n      </IconButton>\n    </Box>\n  )\n}\n\nexport const ModalBackButton = ({\n  onBack,\n  t,\n  marginTop = '-24px',\n  marginLeft = 1.5,\n  sx,\n}: {\n  onBack?: () => void\n  marginTop?: number | string\n  marginLeft?: number | string\n  sx?: SxProps<Theme>\n} & Partial<WithTranslation>) => {\n  return (\n    <Box alignSelf={'flex-start'} marginTop={marginTop} marginLeft={marginLeft} sx={sx}>\n      <IconButton\n        className={'back-btn'}\n        size={'large'}\n        color={'inherit'}\n        aria-label={t && t('labelBack')}\n        onClick={() => {\n          onBack && onBack()\n        }}\n      >\n        <BackIcon />\n      </IconButton>\n    </Box>\n  )\n}\nconst QRStyle = styled(Box)`\n  .MuiButtonBase-root {\n    position: relative;\n    //z-index: 10;\n  }\n\n  &:after {\n    pointer-events: none;\n    content: '';\n    position: absolute;\n    display: block;\n    height: 48px;\n    width: 48px;\n    top: -2px;\n    left: -2px;\n    //z-index: -1;\n    background-image: ${({ theme }) => {\n      if (theme.mode === 'dark') {\n        return `url('${SoursURL}images/qr_code_dark.png')`\n      } else {\n        return `url('${SoursURL}images/qr_code_light.png')`\n      }\n    }};\n  }\n` as typeof Box\nexport const QRButtonStyle = ({\n  onQRClick,\n  t,\n}: {\n  onQRClick?: () => void\n} & WithTranslation) => {\n  return (\n    <QRStyle\n      alignSelf={'flex-start'}\n      marginTop={(-1 / 2) * 7}\n      marginLeft={1.5}\n      position={'absolute'}\n    >\n      <IconButton\n        size={'large'}\n        aria-label={t('labelBack')}\n        onClick={() => {\n          onQRClick && onQRClick()\n        }}\n      >\n        <QRIcon htmlColor={'var(--color-text-third)'} />\n      </IconButton>\n    </QRStyle>\n  )\n}\nexport const LinkActionStyle = styled(Link)`\n  text-decoration: underline dotted;\n  color: inherit;\n` as typeof Link\n\nexport const Tabs = styled(MuTabs)`\n  &.btnTab {\n    .MuiTab-root {\n      color: var(--color-text-primary);\n      margin-right: ${({ theme }) => theme.unit}px;\n      padding: ${({ theme }) => theme.unit}px ${({ theme }) => theme.unit * 1.5}px;\n      min-height: auto;\n      line-height: 24px;\n      &.Mui-selected {\n        color: var(--color-text-button);\n        border-radius: ${({ theme }) => theme.unit * 0.5}px;\n        background: var(--color-primary);\n        &:focus-visible::after,\n        &:after {\n          display: none;\n        }\n      }\n    }\n  }\n\n  &.btnOutLineTab {\n    min-height: 28px;\n    height: 28px;\n    .MuiTabs-fixed {\n      .MuiTab-root {\n        margin: 0 ${({ theme }) => theme.unit}px;\n        &:first-child {\n          margin-left: 0;\n        }\n        &:last-child {\n          margin-right: 0;\n        }\n      }\n    }\n    .MuiTab-root {\n      min-height: 28px;\n      height: 28px;\n      padding: 0;\n      color: var(--color-text-secondary);\n      border: var(--color-text-secondary) 1px solid;\n      border-radius: ${({ theme }) => theme.unit * 0.5}px;\n      margin: 0;\n      &.Mui-selected {\n        color: var(--color-primary);\n        border: var(--color-primary) 1px solid;\n        &:focus-visible::after,\n        &:after {\n          display: none;\n        }\n      }\n    }\n  }\n`\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/btns/Interface.ts",
    "content": "import {\n  ButtonProps as MuButtonPros,\n  SliderProps,\n  ToggleButtonGroupProps as MuToggleButtonGroupProps,\n} from '@mui/material'\nimport { XOR } from '../../../types/lib'\nimport { Mark } from '@mui/base/SliderUnstyled/SliderUnstyledProps'\n\nexport type ButtonProps = MuButtonPros & {\n  // bg:'',\n  // color:'',\n  // hBg:'',\n  // hColor:'',\n  loading?: 'true' | 'false'\n  loadingbg?: string\n}\n\nexport type BtnInfo = {\n  label: string\n  params: {\n    [key: string]: string\n  }\n}\n\nexport type BtnInfoProps = {\n  btnInfo?: BtnInfo\n}\n\nexport interface BtnPercentageProps extends SliderProps {\n  anchors?: Mark[] //0 --100    default 0,20,40,60,80,100\n  selected: number\n  valueLabelDisplay?: 'on' | 'auto' | 'off'\n  valuetext?: (value: any) => string\n  handleChanged: (item: any) => void\n  step?: number\n}\n\nexport interface BtnPercentageDraggableProps extends BtnPercentageProps {\n  maxValue: string | number\n}\n\nexport interface TGItemJSXInterface {\n  value: any\n  key?: string\n  notWrap?: boolean\n  JSX: React.ReactElement\n  tlabel?: string // after 18n\n  disabled?: boolean\n}\n\nexport interface TGItemData {\n  value: string | number\n  key: string\n  label?: string\n  disabled?: boolean\n}\n\nexport type ToggleButtonGroupProps = MuToggleButtonGroupProps & {\n  value: Array<string | number> | string | number\n} & XOR<{ tgItemJSXs: TGItemJSXInterface[] }, { data: TGItemData[] }> // & { handleChange: (event: MouseEvent|InputEvent, newValue: string) => void }\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/btns/index.ts",
    "content": "export * from './Button'\nexport * from './Interface'\nexport * from './BtnPercentage'\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/checkbox/index.tsx",
    "content": "import { useTheme } from '@emotion/react'\nimport { CheckIcon } from '@loopring-web/common-resources'\nimport CheckCircleRoundedIcon from '@mui/icons-material/RadioButtonChecked'\nimport RadioButtonUncheckedIcon from '@mui/icons-material/RadioButtonUnchecked'\nimport { Box, BoxProps, SvgIconProps } from '@mui/material'\n\ntype CustomCheckBoxProps = {\n  CheckedIcon?: React.ComponentType<SvgIconProps>\n  UncheckIcon?: React.ComponentType<SvgIconProps>\n  checked: boolean\n  onCheck: () => void\n}\n\nexport const CustomCheckBox = (props: CustomCheckBoxProps & BoxProps) => {\n  const theme = useTheme()\n  const {\n    CheckedIcon = CheckCircleRoundedIcon,\n    UncheckIcon = RadioButtonUncheckedIcon,\n    checked,\n    onCheck,\n    ...rest\n  } = props\n  return (\n    <Box component={'div'} onClick={onCheck} {...rest}>\n      {checked ? (\n        <CheckedIcon\n          sx={{\n            color: theme.colorBase.primary,\n            fontSize: '24px',\n            cursor: 'pointer',\n          }}\n          className='custom-size'\n        />\n      ) : (\n        <UncheckIcon\n          sx={{\n            fontSize: '24px',\n            cursor: 'pointer',\n          }}\n          className='custom-size'\n        />\n      )}\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/color.stories.tsx",
    "content": "import { Meta, Story } from '@storybook/react'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport { Box, Grid, Typography } from '@mui/material'\nimport { ColorDarkDefault, ColorLightDefault } from '@loopring-web/common-resources'\nimport styled from '@emotion/styled'\nimport React from 'react'\n\nconst Styled = styled.div`\n  background: var(--color-global-bg);\n\n  svg {\n    height: 24px;\n    width: 24px;\n  }\n`\n\nexport const ColorList: Story<any> = withTranslation()(({}: WithTranslation & any) => {\n  const dark = Object.keys(ColorDarkDefault).map((key, indx) => {\n    if (key !== 'background' && key !== 'border') {\n      return (\n        <Grid\n          item\n          width={120}\n          key={indx}\n          padding={2}\n          display={'flex'}\n          flexDirection={'column'}\n          alignItems={'center'}\n        >\n          <Box\n            width={60}\n            height={60}\n            style={{\n              background: ColorDarkDefault[key],\n              border: '1px solid #fff',\n            }}\n          ></Box>\n          <Typography padding={1} variant={'body2'} color={'rgb(104 107 208)'}>\n            {key}\n          </Typography>\n        </Grid>\n      )\n    } else {\n      return <React.Fragment key={indx}></React.Fragment>\n    }\n  })\n  const light = Object.keys(ColorLightDefault).map((key, indx) => {\n    if (key !== 'background' && key !== 'border') {\n      return (\n        <Grid\n          item\n          width={120}\n          key={indx}\n          padding={2}\n          display={'flex'}\n          flexDirection={'column'}\n          alignItems={'center'}\n        >\n          <Box\n            width={60}\n            height={60}\n            style={{\n              background: ColorDarkDefault[key],\n              border: '1px solid #fff',\n            }}\n          ></Box>\n          <Typography padding={1} variant={'body2'} color={'rgb(104 107 208)'}>\n            {key}\n          </Typography>\n        </Grid>\n      )\n    } else {\n      return <React.Fragment key={indx}></React.Fragment>\n    }\n  })\n\n  return (\n    <>\n      <Styled>\n        {/*<MemoryRouter initialEntries={['/']}>*/}\n        <Styled>\n          {/*<MemoryRouter initialEntries={['/']}>*/}\n          <Grid container style={{ background: '#000' }}>\n            {dark}\n          </Grid>\n          <Grid container style={{ background: '#cccccc' }}>\n            {light}\n          </Grid>\n        </Styled>\n      </Styled>\n      {/*</MemoryRouter>*/}\n    </>\n  )\n}) as Story<any>\n\n//export const Button = Template.bind({});\n\nexport default {\n  title: 'Resource/ColorsList',\n  component: ColorList,\n  argTypes: {},\n} as Meta\n// LButton.args = {}\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/display/SpaceBetweenBox.tsx",
    "content": "import { Box, BoxProps } from '@mui/material'\n\nexport type SpaceBetweenProps = {\n  leftNode: React.ReactNode,\n  rightNode: React.ReactNode\n}\n\nexport default (props: BoxProps & SpaceBetweenProps) => {\n  const { leftNode, rightNode, ...rest } = props\n  \n  return <Box display={'flex'} justifyContent={'space-between'} {...rest}>\n    <Box>{leftNode}</Box>\n    <Box>{rightNode}</Box>\n  </Box>\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/display/index.ts",
    "content": "import SpaceBetweenBox from \"./SpaceBetweenBox\";\n\nexport { SpaceBetweenBox }\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/empty/Empty.tsx",
    "content": "import { withTranslation, WithTranslation } from 'react-i18next'\nimport styled from '@emotion/styled'\nimport { EmptyIcon } from '@loopring-web/common-resources'\nimport { Box, BoxProps, Typography } from '@mui/material'\n\nexport type EmptyProps = {\n  height?: number | string\n  emptyPic?: string | JSX.Element //PATH or element\n  message: () => JSX.Element\n}\nconst EmptyIconStyle = styled(EmptyIcon)`\n  && {\n    height: var(--empty-size);\n    width: var(--empty-size);\n  }\n\n  opacity: 0.3;\n  font-size: ${({ theme }) => theme.fontDefault.h1};\n  color: var(--color-text-disable);\n` as typeof EmptyIcon\nconst WrapStyled = styled(Box)<{ height: number | undefined | string }>`\n  display: flex;\n  flex-direction: column;\n  flex-flow: column wrap;\n  flex-wrap: nowrap;\n  justify-content: center;\n  align-items: center;\n  height: ${(props) =>\n    props.height\n      ? typeof props.height == 'number'\n        ? props.height + 'px'\n        : props.height\n      : `${350 - 35}px`};\n` as typeof Box\nexport const EmptyDefault = withTranslation(['layout', 'common'])(\n  ({\n    t,\n    i18n,\n    tReady,\n    emptyPic = <EmptyIconStyle fontSize={'large'} />,\n    height,\n    message,\n    ...rest\n  }: EmptyProps & BoxProps & WithTranslation) => {\n    const renderPic =\n      !emptyPic || typeof emptyPic === 'string' ? (\n        <img src={emptyPic as string} alt={t('Empty')} />\n      ) : (\n        emptyPic\n      )\n    return (\n      <WrapStyled height={height} {...rest}>\n        {renderPic}\n        <Typography component={'span'} color={'textSecondary'} fontSize={'h6'} marginTop={1}>\n          {message()}\n        </Typography>\n      </WrapStyled>\n    )\n  },\n) as (props: EmptyProps & BoxProps) => JSX.Element\n\nexport const ComingSoonPanel = withTranslation(['common', 'layout'])(({ t }: WithTranslation) => {\n  return (\n    <Box\n      flex={1}\n      alignItems={'center'}\n      justifyContent={'center'}\n      textAlign={'center'}\n      marginBottom={2}\n      display={'flex'}\n    >\n      <Typography component={'h6'} variant={'h1'} padding={3}>\n        {t('labelComingSoon')}\n      </Typography>\n    </Box>\n  )\n})\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/empty/index.ts",
    "content": "import { EmptyDefault } from './Empty'\n\nexport { EmptyDefault }\nexport * from './Empty'\n\n// export default EmptyWallet;\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/form/Form.stories.tsx",
    "content": "import React from 'react'\nimport { Meta, Story } from '@storybook/react'\nimport styled from '@emotion/styled'\nimport {\n  Box,\n  Checkbox,\n  FormControl,\n  FormControlLabel as MuiFormControlLabel,\n  Grid,\n  Link,\n  ListItemText,\n  SelectChangeEvent,\n  Typography,\n} from '@mui/material'\nimport { InputCoinProps, MenuItem, OutlineSelect, OutlineSelectItem } from '../../basic-lib'\nimport { Trans, withTranslation } from 'react-i18next'\nimport {\n  DatePicker,\n  DateRangePicker,\n  InputButton,\n  InputButtonProps,\n  InputSearch,\n  InputSelect,\n  InputSelectProps,\n  TextField,\n} from './input'\nimport {\n  CheckBoxIcon,\n  CheckedIcon,\n  CloseIcon,\n  CoinInfo,\n  CoinKey,\n  DropDownIcon,\n  i18n,\n  IBData,\n  LanguageType,\n} from '@loopring-web/common-resources'\nimport { DateRange } from '@mui/lab'\nimport { EmptyDefault } from '../empty'\nimport { coinMap, CoinType, inputProps, walletMap } from '../../../static'\nimport { CoinMenu } from '../lists'\nimport { InputCoin } from './input'\nimport { IconClearStyled } from '../../tradePanel'\n\nconst Style = styled.div`\n  background: var(--color-global-bg);\n`\nexport default {\n  title: 'basic-lib/Form',\n  component: TextField,\n  argTypes: {},\n} as Meta\n\nconst InputButtonWrap = () => {\n  let information = { value: \"hello, it's callback inject\" }\n\n  setTimeout(() => {\n    information.value = 'I have update'\n  }, 100)\n\n  const ref = React.createRef<HTMLInputElement>()\n  const handleError = ({ belong, balance, tradeValue }: IBData<CoinType>) => {\n    if (typeof tradeValue !== 'undefined' && balance < tradeValue) {\n      return { error: true, message: `Not enough ${belong} perform a deposit` }\n    }\n    return { error: false }\n  }\n  const [data, setData] = React.useState<IBData<CoinType>>({\n    belong: 'ETH',\n    balance: 23244,\n    tradeValue: 0,\n  })\n  const handleCountChange = React.useCallback((ibData: IBData<CoinType>) => {\n    setData(ibData)\n  }, [])\n\n  const handleOnClick = React.useCallback(\n    (_event) => {\n      console.log(information)\n    },\n    [information],\n  )\n\n  let _inputProps: InputButtonProps<IBData<CoinType>, CoinType, CoinInfo<CoinType>> = {\n    isShowCoinIcon: true,\n    isShowCoinInfo: true,\n    handleOnClick,\n    ...inputProps,\n  }\n\n  return (\n    <>\n      <Grid item xs={4}>\n        <InputButton<IBData<CoinType>, CoinType, CoinInfo<CoinType>> {..._inputProps} />\n      </Grid>\n\n      <Grid item xs={4}>\n        <InputButton<IBData<CoinType>, CoinType, CoinInfo<CoinType>>\n          {...{\n            ..._inputProps,\n            ...{\n              maxAllow: true,\n              inputData: data,\n              handleError,\n              handleCountChange,\n              ref,\n            },\n          }}\n        />\n      </Grid>\n      <Grid item xs={4}>\n        <InputButton<IBData<CoinType>, CoinType, CoinInfo<CoinType>>\n          {...{ ..._inputProps, ...{ inputData: data } }}\n        />\n      </Grid>\n    </>\n  )\n}\nexport const BtnLanguage = ({ handleChange }: any) => {\n  const _handleChange = React.useCallback(\n    (event: SelectChangeEvent<any>) => {\n      if (handleChange) {\n        handleChange(event.target.value)\n      }\n    },\n    [handleChange],\n  )\n  return (\n    <OutlineSelect\n      IconComponent={DropDownIcon}\n      labelId='language-selected'\n      id='language-selected'\n      value={i18n.language}\n      onChange={_handleChange}\n    >\n      <OutlineSelectItem value={LanguageType.en_US}>EN</OutlineSelectItem>\n      <OutlineSelectItem value={LanguageType.zh_CN}>中文</OutlineSelectItem>\n    </OutlineSelect>\n  )\n}\nconst InputIconWrap = () => {\n  const ref = React.createRef<HTMLInputElement>()\n  const handleError = ({ belong, balance, tradeValue }: IBData<CoinType>) => {\n    if (typeof tradeValue !== 'undefined' && balance < tradeValue) {\n      return { error: true, message: `Not enough ${belong} perform a deposit` }\n    }\n    return { error: false }\n  }\n  const [data, setData] = React.useState<IBData<CoinType>>({\n    belong: 'ETH',\n    balance: 23244,\n    tradeValue: 0,\n  })\n  const handleCountChange = React.useCallback((ibData: IBData<CoinType>) => {\n    setData(ibData)\n  }, [])\n\n  let _inputProps: InputCoinProps<IBData<CoinType>, CoinType, CoinInfo<CoinType>> = {\n    handleCountChange,\n    ...inputProps,\n    isShowCoinIcon: true,\n    isShowCoinInfo: true,\n  } as any\n\n  return (\n    <>\n      <Grid item xs={4}>\n        <InputCoin<IBData<CoinType>, CoinType, CoinInfo<CoinType>>\n          {...{\n            ..._inputProps,\n            ...{\n              maxAllow: true,\n              inputData: data,\n              handleError,\n              ref,\n            },\n          }}\n        />\n      </Grid>\n      <Grid item xs={4}>\n        <InputCoin<IBData<CoinType>, CoinType, CoinInfo<CoinType>>\n          {...{\n            ..._inputProps,\n            ...{\n              order: 'right',\n              maxAllow: true,\n              inputData: data,\n              handleError,\n              ref,\n            },\n          }}\n        />\n      </Grid>\n    </>\n  )\n}\n\nconst SimpleSelect = ({ t }: any) => {\n  const datas = [\n    { label: 'Text1', value: '1' },\n    { label: 'Text2', value: '2' },\n    { label: 'Text3', value: '3' },\n    { label: 'Text4', value: '4' },\n    { label: 'Text5', value: '5' },\n    { label: 'Text6', value: '6' },\n    { label: 'Text7', value: '7' },\n    { label: 'Text8', value: '8' },\n    { label: 'Text4TextTextTextTextText', value: '9' },\n    { label: 'Text3', value: '10' },\n    { label: 'Text4TextTextTextTextText', value: '11' },\n    { label: 'Text4TextTextTextTextText', value: '12' },\n  ]\n  const [value, setValue] = React.useState('1')\n  return (\n    <>\n      <FormControl>\n        <TextField\n          id='outlined-select-currency'\n          select\n          label='type'\n          value={value}\n          onChange={(event: React.ChangeEvent<{ value: unknown }>) => {\n            setValue(event.target.value as string)\n          }}\n          inputProps={{ IconComponent: DropDownIcon }}\n        >\n          {datas.map(({ label, value }) => (\n            <MenuItem key={value} value={value}>\n              {t(label)}\n            </MenuItem>\n          ))}\n        </TextField>\n      </FormControl>\n    </>\n  )\n}\nconst InputSelectWrap = (rest: any) => {\n  const ref = React.useRef<any>(null)\n  const selected: CoinKey<CoinType> = 'TEST3'\n  const backElement = React.useMemo(\n    () => (\n      <>\n        <Typography component={'span'} fontSize={'body1'} color={'textPrimary'}>\n          <Link\n            color={'inherit'}\n            style={{ color: 'var(--color-text-primary)', textAlign: 'right' }}\n            onClick={() => {}}\n          >\n            Cancel\n          </Link>\n        </Typography>\n      </>\n    ),\n    [],\n  )\n  const inputSelectProps: InputSelectProps<CoinType> = {\n    placeholder: 'Search Coin',\n    focusOnInput: true,\n    allowScroll: true,\n    selected: '',\n    panelRender: () => <></>,\n    backElement,\n    handleContentChange: (value) => {\n      console.log('FilterString', value)\n      //setFilterString(value);\n    },\n  }\n  const handleListItemClick = (value: any) => {\n    console.log('handleListItemClick', value)\n  }\n  const filterBy = (coinInfo: CoinInfo<CoinType>, filterString: string) => {\n    return filterString && filterString.length\n      ? RegExp(filterString, 'i').test(coinInfo.simpleName)\n      : true\n  }\n  const PanelRender = ({ selected, value }: any) => {\n    return (\n      <CoinMenu<CoinType, CoinInfo<CoinType>>\n        {...{\n          coinMap,\n          height: '410px',\n          filterBy,\n          filterString: value,\n          walletMap,\n          selected,\n          ...rest,\n        }}\n        ref={ref}\n      />\n    )\n\n    {\n      /*<CoinMenu<CoinType, CoinInfo<CoinType>>  style={{ width: '100px', height:'100px' }}*/\n    }\n    {\n      /*    width={330} height={100} {...{coinMap, walletMap, ...rest}}></CoinMenu>*/\n    }\n    // </Box>\n  }\n\n  const PanelEmptyRender = () => {\n    return (\n      <Box alignSelf={'center'}>\n        <EmptyDefault\n          message={() => {\n            return <Trans i18nKey='labelEmptyDefault'>Content is Empty</Trans>\n          }}\n        />\n      </Box>\n    )\n  }\n\n  return (\n    <>\n      <Grid item xs={6} md={4}>\n        <Box height={500} width={338}>\n          <InputSelect\n            {...{\n              ...inputSelectProps,\n              panelRender: PanelRender,\n              handleListItemClick,\n              ...rest,\n            }}\n          />\n        </Box>\n      </Grid>\n      <Grid item xs={6} md={4}>\n        <Box height={500} width={338}>\n          <InputSelect\n            {...{\n              ...inputSelectProps,\n              panelRender: PanelRender,\n              selected,\n              handleListItemClick,\n              ...rest,\n            }}\n          />\n        </Box>\n      </Grid>\n      <Grid item xs={6} md={4}>\n        <Box height={500} width={338}>\n          <InputSelect\n            {...{\n              ...inputSelectProps,\n              panelRender: PanelEmptyRender,\n              ...rest,\n            }}\n          />\n        </Box>\n      </Grid>\n    </>\n  )\n}\nconst MyDatePicker = (props: any) => {\n  const [value, setValue] = React.useState<Date | undefined>(new Date())\n  const [svalue, setSValue] = React.useState<DateRange<Date | string>>([new Date(), new Date()])\n  return (\n    <>\n      <Grid item xs={4}>\n        <DatePicker\n          {...props}\n          label='Basic example'\n          value={value}\n          onChange={(newValue: any) => setValue(newValue)}\n        />\n      </Grid>\n      <Grid item xs={4}>\n        <DateRangePicker\n          {...props}\n          value={svalue}\n          onChange={(newValue: any) => setSValue(newValue)}\n          startText='Start'\n          endText='End'\n        />\n      </Grid>\n    </>\n  )\n}\n// const SearchWrap = () => {\n//     const inputProps: OutlinedInputProps = {\n//         placeholder: 'Search Coin',\n//         value: '',\n//         onChange: (value: any) => {\n//             console.log('FilterString', value);\n//             //setFilterString(value);\n//         },\n//     }\n//     return <OutlinedInput\n//         // ref={inputEle}\n//         {...inputProps}\n//         key={'search'}\n//         // placeholder={'search'}\n//         className={'search'}\n//         aria-label={'search'}\n//         startAdornment={<InputAdornment position=\"start\">\n//             <SearchIcon/>\n//         </InputAdornment>}\n//     />\n// }\nconst Template: Story<any> = withTranslation()((props: any) => {\n  const [value, setValue] = React.useState('')\n  const [searchValue, setSearchValue] = React.useState('')\n\n  const handleSearchChange = React.useCallback((value) => {\n    setSearchValue(value)\n  }, [])\n  const handleClear = React.useCallback(() => {\n    // @ts-ignore\n    // addressInput?.current?.value = \"\";\n    setSearchValue('')\n  }, [])\n  // const handleClear = React.useCallback(() => {\n  //     // @ts-ignore\n  //     // addressInput?.current?.value = \"\";\n  //     setAddress('')\n  // }, [])\n\n  return (\n    <Style>\n      <h4>Select token ground btn and input value</h4>\n      <Grid\n        container\n        spacing={2}\n        alignItems={'center'}\n        justifyContent={'flex-start'}\n        marginBottom={2}\n      >\n        <Grid item xs={3}>\n          <SimpleSelect {...props} />\n        </Grid>\n        <Grid item xs={3}>\n          <TextField\n            id='transferFeeType'\n            select\n            label={'label'}\n            value={value}\n            onChange={(event: React.ChangeEvent<any>) => {\n              setValue(event.target?.value)\n            }}\n            inputProps={{ IconComponent: DropDownIcon }}\n            fullWidth={true}\n          >\n            {[\n              { belong: 'eth', fee: '0.1' },\n              { belong: 'lrc', fee: '1000' },\n            ].map(({ belong, fee }) => {\n              return (\n                <MenuItem key={belong} value={fee} withnocheckicon={'true'}>\n                  <ListItemText\n                    primary={\n                      <Typography\n                        sx={{ display: 'inline' }}\n                        component='span'\n                        variant='body1'\n                        color='text.primary'\n                      >\n                        {belong}\n                      </Typography>\n                    }\n                    secondary={\n                      <Typography\n                        sx={{ display: 'inline' }}\n                        component='span'\n                        variant='body1'\n                        color='text.primaryLight'\n                      >\n                        {fee}\n                      </Typography>\n                    }\n                  />\n                </MenuItem>\n              )\n            })}\n          </TextField>\n        </Grid>\n        <Grid item xs={3}>\n          <BtnLanguage {...props} handleChange={(value: any) => console.log(value)} />\n        </Grid>\n        <Grid item xs={3}>\n          <MuiFormControlLabel\n            control={\n              <Checkbox\n                defaultChecked\n                checkedIcon={<CheckedIcon />}\n                icon={<CheckBoxIcon />}\n                color='default'\n              />\n            }\n            label='Label'\n          />\n        </Grid>\n\n        <Grid item xs={3} marginTop={2} alignSelf={'stretch'} position={'relative'}>\n          <InputSearch value={searchValue} fullWidth onChange={handleSearchChange} />\n          {searchValue !== '' ? (\n            <IconClearStyled\n              size={'small'}\n              style={{ top: '22px' }}\n              aria-label='Clear'\n              onClick={handleClear}\n            >\n              <CloseIcon />\n            </IconClearStyled>\n          ) : (\n            ''\n          )}\n        </Grid>\n        <Grid item xs={3} marginTop={2} alignSelf={'stretch'} position={'relative'}>\n          <TextField\n            value={searchValue}\n            // error={addressError && addressError.error ? true : false}\n            label={'input'}\n            placeholder={'input'}\n            onChange={() => {\n              handleSearchChange(searchValue)\n            }}\n            // disabled={chargeFeeTokenList.length ? false : true}\n            SelectProps={{ IconComponent: DropDownIcon }}\n            // required={true}\n            // inputRef={addressInput}\n            // helperText={<Typography\n            //     variant={'body2'}\n            //     component={'span'}>{addressError && addressError.error ? addressError.message : ''}</Typography>}\n            fullWidth={true}\n          />\n          {searchValue !== '' ? (\n            <IconClearStyled\n              size={'small'}\n              style={{ top: '46px' }}\n              aria-label='Clear'\n              onClick={handleClear}\n            >\n              <CloseIcon />\n            </IconClearStyled>\n          ) : (\n            ''\n          )}\n        </Grid>\n        <MyDatePicker {...props} />\n      </Grid>\n      <h4>Select token ground btn and input value</h4>\n      <Grid\n        container\n        spacing={2}\n        alignItems={'center'}\n        justifyContent={'flex-start'}\n        marginBottom={2}\n      >\n        <InputButtonWrap />\n        <InputIconWrap />\n      </Grid>\n\n      <h4>Select token menu with search</h4>\n      <Grid\n        container\n        spacing={2}\n        alignContent={'center'}\n        justifyContent={'flex-start'}\n        flexWrap={'wrap'}\n        marginBottom={2}\n      >\n        <InputSelectWrap {...props} />\n      </Grid>\n    </Style>\n  )\n}) as Story<any>\n\n// @ts-ignore\nexport const FormItem = Template.bind({})\nFormItem.args = {}\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/form/hooks/index.ts",
    "content": "export * from './useFocusRef'\nexport * from './usePanelRef'\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/form/hooks/useFocusRef.ts",
    "content": "import React from 'react'\n\nexport function useFocusRef<T extends HTMLInputElement>({\n  value,\n  shouldFocusOn,\n  callback,\n}: {\n  value?: any\n  shouldFocusOn?: boolean | undefined\n  // ref: React.RefObject<T>,\n  callback?: (prorps: { current: any }) => void\n}) {\n  const ref = React.useRef<T>(null)\n  React.useEffect(() => {\n    if (shouldFocusOn) {\n      ref?.current?.focus()\n    }\n    callback && callback({ current: ref.current })\n  }, [value, shouldFocusOn])\n  return ref\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/form/hooks/usePanelRef.ts",
    "content": "import React from 'react'\n\nexport function usePanelRef<T extends HTMLInputElement>({\n  callback,\n}: {\n  callback?: (prorps: { current: any }) => void\n}) {\n  const ref = React.useRef<T>(null)\n  React.useEffect(() => {\n    if (ref.current) {\n      callback && callback({ current: ref.current })\n    }\n  }, [])\n  return ref\n}\n\n// {\n//     const ref = React.useRef<T>(null);\n//     React.useEffect(() => {\n//\n//         callback && callback({current: ref.current});\n//         return ref\n//     }, [height, width, callback]);\n//     return ref;\n// }\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/form/index.ts",
    "content": "export * from './input'\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/form/input/CollectionInput.tsx",
    "content": "import { Avatar, Box, BoxProps, Divider, Link, Modal, Tooltip, Typography } from '@mui/material'\nimport {\n  CollectionMeta,\n  CopyIcon,\n  copyToClipBoard,\n  getShortAddr,\n  ImageIcon,\n  Info2Icon,\n  LoadingIcon,\n  MakeMeta,\n  myLog,\n  TOAST_TIME,\n  RouterPath,\n  NFTSubRouter,\n  htmlDecode,\n} from '@loopring-web/common-resources'\nimport {\n  Button,\n  CollectionCardList,\n  CollectionListProps,\n  DropdownIconStyled,\n  MenuItem,\n  SwitchPanelStyled,\n  // TextField,\n  Toast,\n  ToastType,\n} from '../../../index'\nimport React from 'react'\nimport { Trans, useTranslation } from 'react-i18next'\nimport styled from '@emotion/styled'\nimport { useHistory } from 'react-router-dom'\nimport { TextField } from '../../../basic-lib'\n\nconst SizeCss = {\n  small: `\n\t  height: 2.4rem;\n\t  lineHeight: 2.4rem;\n\t`,\n  large: `\n\t  height: 4.8rem;\n\t  lineHeight: 4.8rem;\n\t`,\n  medium: `\n\t height: 3.2rem;\n\t lineHeight: 3.2rem;\n\t`,\n}\nconst BoxStyle = styled(Box)<BoxProps & { size: 'small' | 'large' | 'medium' }>`\n  padding: 0.3rem 0.3rem 0.3rem 0.8rem;\n  ${({ theme }) => theme.border.defaultFrame({ c_key: 'var(--color-border)', d_R: 0.5 })};\n\n  &:hover,\n  &:active {\n    color: var(--color-text-primary);\n    ${({ theme }) =>\n      theme.border.defaultFrame({\n        c_key: 'var(--color-border-hover)',\n        d_R: 0.5,\n      })};\n  }\n\n  .selected {\n    color: var(--color-text-button-select);\n    background: var(--color-box);\n    ${({ theme }) =>\n      theme.border.defaultFrame({\n        c_key: 'var(--color-border-select)',\n        d_R: 0.5,\n      })};\n  }\n\n  ${({ size }) => SizeCss[size]}\n` as (props: BoxProps & { size: 'small' | 'large' | 'medium' }) => JSX.Element\n\nexport type CollectionInputProps<Co> = {\n  collection?: Co\n  collectionListProps: CollectionListProps<Co>\n  onSelected: (item: Co) => void\n  domain: string\n  makeMeta: MakeMeta\n}\n\nexport const CollectionInput = <Co extends CollectionMeta>({\n  collection,\n  collectionListProps,\n  fullWidth = false,\n  width = 'content-fit',\n  showCopy = false,\n  onSelected,\n  domain,\n  size = 'large',\n  // makeMeta,\n  isRequired = false,\n}: CollectionInputProps<Co> & {\n  showCopy?: boolean\n  fullWidth?: boolean\n  width?: any\n  size?: 'small' | 'large' | 'medium'\n  domain: string\n  makeMeta: MakeMeta\n  isRequired?: boolean\n}) => {\n  const [_modalState, setModalState] = React.useState(false)\n  // const [selectCollectionMeta, setSelectCollectionMeta] = React.useState(collection);\n  const { t } = useTranslation('common')\n  const [dropdownStatus, setDropdownStatus] = React.useState<'up' | 'down'>('down')\n  const { onPageChange, collectionList, isLoading: isLoadingCollectionList } = collectionListProps\n  const noCollectionAndSelected = collectionList.length === 0 && collection === undefined\n  myLog('collectionList', collectionListProps.collectionList)\n  const history = useHistory()\n  const pushRoute = React.useCallback((route: string) => {\n    history.push(route)\n  }, [])\n  return (\n    <Box display={'flex'} flexDirection={'column'} width={fullWidth ? '100%' : width}>\n      <Box width={'100%'}>\n        <Tooltip\n          title={\n            <Trans i18nKey='labelChooseCollectionTooltips'>\n              This is the collection where your NFT will appear.NFT minted under collection will be\n              bound with different contract address than previous created one. If you have\n              incomplete work to finish and would like them created under previous contract address,\n              you can still use the legacy created method under\n              <Link\n                style={{\n                  cursor: 'pointer',\n                  color: 'var(--color-primary)',\n                  textOverflow: 'ellipsis',\n                  overflow: 'hidden',\n                }}\n                target='_blank'\n                rel='noopener noreferrer'\n                href={'https://legacy-nft.loopring.io'}\n              >\n                legacy-nft.loopring.io\n              </Link>\n            </Trans>\n          }\n          placement={'top-start'}\n        >\n          <Typography\n            variant={'body1'}\n            color={'textSecondary'}\n            className={'main-label'}\n            paddingBottom={1 / 2}\n            display={'inline-flex'}\n            height={24}\n            lineHeight={24}\n            alignItems={'center'}\n          >\n            <Trans\n              i18nKey={'labelMintCollection'}\n              tOptions={{ required: isRequired ? '\\uFE61' : '' }}\n            >\n              Choose Collection\n              <Typography component={'span'} variant={'inherit'} color={'error'}>\n                {'\\uFE61'}\n              </Typography>\n              <Info2Icon fontSize={'small'} color={'inherit'} sx={{ marginX: 1 / 2 }} />\n            </Trans>\n          </Typography>\n        </Tooltip>\n      </Box>\n      {dropdownStatus === 'up' && noCollectionAndSelected ? (\n        <TextField\n          select\n          size={size}\n          SelectProps={{\n            open: true,\n            IconComponent: () => (\n              <DropdownIconStyled\n                sx={{ color: 'white!important' }}\n                status={dropdownStatus}\n                fontSize={size}\n              />\n            ),\n          }}\n          sx={{ width: '100%', maxWidth: 'none!important' }}\n          onClick={(_e: any) => {\n            _e.stopPropagation()\n            setDropdownStatus((prev) => (prev === 'up' ? 'down' : 'up'))\n          }}\n        >\n          <MenuItem\n            onClick={() => {\n              pushRoute(`${RouterPath.nft}/${NFTSubRouter.addCollection}`)\n            }}\n          >\n            {t('labelNFTCreateCollection')}\n          </MenuItem>\n        </TextField>\n      ) : (\n        <BoxStyle\n          width={'100%'}\n          display={'flex'}\n          alignItems={'center'}\n          fontSize={'1.6rem'}\n          size={size}\n          className={collection ? 'selected' : ''}\n          justifyContent={'space-between'}\n          onClick={(_e: any) => {\n            if (isLoadingCollectionList) return\n            if (noCollectionAndSelected) {\n              _e.stopPropagation()\n              setDropdownStatus((prev) => (prev === 'up' ? 'down' : 'up'))\n            } else {\n              setModalState(true)\n              onPageChange(1, { isMintable: true })\n            }\n          }}\n          style={{ cursor: 'pointer', whiteSpace: 'nowrap' }}\n          position={'relative'}\n        >\n          <Box flex={1} display={'flex'} flexDirection={'row'}>\n            {collection ? (\n              <>\n                {(\n                  collection?.cached?.tileUri ??\n                  collectionListProps.getIPFSString(\n                    collection?.tileUri ?? '',\n                    collectionListProps.baseURL,\n                  )\n                ).startsWith('http') ? (\n                  <Avatar\n                    sx={{\n                      bgcolor: 'var(--color-border-disable2)',\n                      marginRight: 1,\n                      width: size === 'large' ? 'var(--svg-size-huge2)' : 'var(--svg-size-large)',\n                      height: size === 'large' ? 'var(--svg-size-huge2)' : 'var(--svg-size-large)',\n                    }}\n                    variant={'rounded'}\n                    src={\n                      collection?.cached?.tileUri ??\n                      collectionListProps.getIPFSString(\n                        collection?.tileUri ?? '',\n                        collectionListProps.baseURL,\n                      )\n                    }\n                  />\n                ) : (\n                  <Avatar\n                    sx={{\n                      bgcolor: 'var(--color-border-disable2)',\n                      marginRight: 1,\n                      width: size === 'large' ? 'var(--svg-size-huge2)' : 'var(--svg-size-medium)',\n                      height: size === 'large' ? 'var(--svg-size-huge2)' : 'var(--svg-size-medium)',\n                    }}\n                    variant={'rounded'}\n                  >\n                    <ImageIcon />\n                  </Avatar>\n                )}\n\n                <Box\n                  flex={1}\n                  display={'flex'}\n                  flexDirection={size === 'large' ? 'column' : 'row'}\n                  alignItems={size === 'large' ? 'stretch' : 'center'}\n                >\n                  <Typography\n                    component={'span'}\n                    variant={'body1'}\n                    color={'textPrimary'}\n                    textOverflow={'ellipsis'}\n                    overflow={'hidden'}\n                    display={'inline-flex'}\n                    whiteSpace={'pre'}\n                    sx={\n                      size !== 'large'\n                        ? {\n                            maxWidth: '160px',\n                            wordBreak: 'break-all',\n                          }\n                        : {}\n                    }\n                  >\n                    {htmlDecode(collection.name)}\n                  </Typography>\n                  <Typography\n                    component={'span'}\n                    marginLeft={size === 'large' ? 0 : 1}\n                    variant={'body2'}\n                    color={'var(--color-text-third)'}\n                  >\n                    {size === 'large'\n                      ? collection.contractAddress\n                      : ' ' + getShortAddr(collection.contractAddress ?? '', true)}\n                  </Typography>\n                </Box>\n              </>\n            ) : (\n              <></>\n            )}\n          </Box>\n          {isLoadingCollectionList ? (\n            <LoadingIcon />\n          ) : (\n            <DropdownIconStyled status={dropdownStatus} fontSize={size} />\n          )}\n        </BoxStyle>\n      )}\n\n      {collection && showCopy && (\n        <Typography display={'inline-flex'} alignItems={'center'} marginY={1}>\n          collection_metadata:\n          <Link\n            color={'primary'}\n            display={'inline-flex'}\n            alignItems={'center'}\n            sx={{\n              marginLeft: 0,\n              paddingLeft: 1,\n              justifyContent: 'flex-start',\n            }}\n            onClick={(e) => {\n              e.stopPropagation()\n              if (collection) {\n                // @ts-ignore\n                copyToClipBoard(`${domain}/${(collection as any).collectionAddress}`)\n                collectionListProps.setCopyToastOpen({\n                  isShow: true,\n                  type: 'url',\n                })\n              }\n            }}\n          >\n            {domain}/{getShortAddr((collection as any).collectionAddress)}\n            <CopyIcon color={'inherit'} />\n          </Link>\n        </Typography>\n      )}\n      <Modal\n        open={_modalState}\n        onClose={() => {\n          // setDropdownStatus((prev) => (prev === \"up\" ? \"down\" : \"up\"));\n          setModalState(false)\n        }}\n      >\n        <SwitchPanelStyled\n          display={'flex'}\n          overflow={'auto'}\n          alignItems={'stretch'}\n          height={'80%'}\n          width={'90%'}\n          paddingX={4}\n          className={'collectionSelect'}\n        >\n          <Box\n            display={'flex'}\n            alignItems={'center'}\n            justifyContent={'space-between'}\n            marginBottom={2}\n          >\n            <Typography variant={'h5'}>{t('labelChooseCollection')}</Typography>\n            <Button\n              variant={'contained'}\n              onClick={() => {\n                pushRoute(`${RouterPath.nft}/${NFTSubRouter.addCollection}`)\n              }}\n            >\n              {t('labelNFTCreateCollection')}\n            </Button>\n          </Box>\n          <Divider style={{ marginTop: '-1px' }} />\n          <CollectionCardList\n            {...{ ...(collectionListProps as any) }}\n            isSelectOnly={true}\n            size={collectionListProps?.size ?? size}\n            filter={{ isMintable: true }}\n            selectCollection={collection}\n            onSelectItem={(item) => {\n              onSelected(item as Co)\n              // setSelectCollectionMeta(item as any);\n              setDropdownStatus((prev) => (prev === 'up' ? 'down' : 'up'))\n              setModalState(false)\n            }}\n          />\n          <Toast\n            alertText={\n              collectionListProps.copyToastOpen?.type === 'json'\n                ? t('labelCopyMetaClip')\n                : t('labelCopyAddClip')\n            }\n            open={collectionListProps.copyToastOpen?.isShow}\n            autoHideDuration={TOAST_TIME}\n            onClose={() => {\n              collectionListProps.setCopyToastOpen({ isShow: false, type: '' })\n            }}\n            severity={ToastType.success}\n          />\n        </SwitchPanelStyled>\n      </Modal>\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/form/input/DatePicker.tsx",
    "content": "import { Box, experimentalStyled, IconButton, InputAdornment, TextFieldProps } from '@mui/material'\nimport styled from '@emotion/styled'\nimport {\n  DatePicker as MuDatePicker,\n  DatePickerProps as MuDatePickerProps,\n  DateRangePicker as MuDateRangePicker,\n  DateRangePickerProps as MuDateRangePickerProps,\n  DateTimePicker as MuDateTimePicker,\n  DateTimePickerProps as MuDateTimePickerProps,\n} from '@mui/lab'\n\nimport { TFunction } from 'i18next'\nimport {\n  CalendarIcon,\n  YEAR_DAY_FORMAT,\n  YEAR_DAY_MINUTE_FORMAT,\n} from '@loopring-web/common-resources'\nimport { TextField } from './style'\n\nexport const DateTextField = styled(TextField)`\n  && .date-range-adornment {\n    .MuiIconButton-edgeEnd {\n      height: var(--btn-icon-size);\n      width: var(--btn-icon-size);\n    }\n  }\n`\n\n// const DateRangeDelimiterStyled = styled(DateRangeDelimiter)`\n//     margin: 0 ${({theme}) => theme.unit}px !important;\n// `\n\nexport type DateRangePickerProps = {} & Omit<MuDateRangePickerProps<Date>, 'renderInput'>\n\nexport const DateRangePicker = experimentalStyled(\n  ({ ...props }: DateRangePickerProps & { t: TFunction }) => {\n    return (\n      <MuDateRangePicker\n        {...props}\n        disableFuture={props.disableFuture ? props.disableFuture : true}\n        calendars={props.calendars ? props.calendars : 2}\n        mask={props.mask ? props.mask : '__-__-__'}\n        inputFormat={props.inputFormat ? props.inputFormat : 'YY-MM-DD'}\n        // endIcon={<CalendarIcon/>}\n        OpenPickerButtonProps={props.OpenPickerButtonProps}\n        renderInput={(startProps: any, endProps: any) => {\n          startProps.InputProps = {\n            ...startProps.InputProps,\n            endAdornment: (\n              <InputAdornment\n                variant={'standard'}\n                position='end'\n                className={'date-range-adornment'}\n              >\n                <IconButton size={'large'} edge={'end'}>\n                  <CalendarIcon />\n                </IconButton>\n              </InputAdornment>\n            ),\n          }\n          endProps.InputProps = {\n            ...endProps.InputProps,\n            endAdornment: (\n              <InputAdornment\n                variant={'standard'}\n                position='end'\n                className={'date-range-adornment'}\n              >\n                <IconButton size={'large'} edge={'end'}>\n                  <CalendarIcon />\n                </IconButton>\n              </InputAdornment>\n            ),\n          }\n          return (\n            <>\n              <DateTextField\n                ref={startProps.inputRef}\n                {...{ ...startProps, helperText: null, label: undefined }}\n                placeholder={'YY-MM-DD'}\n              />\n              <Box sx={{ mx: 2 }}> - </Box>\n              {/*<DateRangeDelimiterStyled>-</DateRangeDelimiterStyled>*/}\n              <DateTextField\n                ref={endProps.inputRef}\n                {...{ ...endProps, helperText: null, label: undefined }}\n                placeholder={'YY-MM-DD'}\n              />\n            </>\n          )\n        }}\n      />\n    )\n  },\n)<DateRangePickerProps>`\n\n` as React.ComponentType<DateRangePickerProps & { t?: TFunction }>\n\nexport type DatePickerProps = Omit<MuDatePickerProps, 'renderInput'> & {\n  textFiledProps?: TextFieldProps\n}\nexport const DatePicker = styled(\n  ({ t, inputFormat, value, ...props }: DatePickerProps & { t?: TFunction }) => (\n    <MuDatePicker\n      {...props}\n      disableFuture={props.disableFuture ? props.disableFuture : true}\n      mask={props.mask ? props.mask : '__-__-__'}\n      inputFormat={inputFormat ? inputFormat : YEAR_DAY_FORMAT}\n      openTo={props.openTo ? props.openTo : 'day'}\n      views={props.views ? props.views : ['year', 'day']}\n      value={value}\n      components={{ OpenPickerIcon: CalendarIcon }}\n      OpenPickerButtonProps={\n        props.OpenPickerButtonProps\n          ? props.OpenPickerButtonProps\n          : {\n              size: 'large',\n            }\n      }\n      desktopModeMediaQuery={'@media (min-width: 720px)'}\n      renderInput={(_props) => {\n        return (\n          <DateTextField\n            ref={_props.inputRef}\n            {...{ ..._props, ...props?.textFiledProps, helperText: null }}\n          />\n        )\n      }}\n    />\n  ),\n)<DatePickerProps>`` as React.ComponentType<DatePickerProps & { t?: TFunction }>\n\nexport type DateTimePickerProps = Omit<MuDateTimePickerProps, 'renderInput'>\n\nexport const DateTimePicker = ({\n  t,\n  inputFormat,\n  value,\n  fullWidth = false,\n  textFiledProps,\n  ...props\n}: DateTimePickerProps & {\n  t?: TFunction\n  fullWidth?: boolean\n  textFiledProps?: Partial<TextFieldProps>\n}) => (\n  <MuDateTimePicker\n    {...props}\n    disableFuture={props.disableFuture ? props.disableFuture : false}\n    mask={props.mask ? props.mask : '__-__-__'}\n    inputFormat={inputFormat ? inputFormat : YEAR_DAY_MINUTE_FORMAT}\n    openTo={props.openTo ? props.openTo : 'day'}\n    views={props.views ? props.views : ['day', 'hours', 'minutes']}\n    value={value}\n    components={{\n      OpenPickerIcon: CalendarIcon,\n    }}\n    OpenPickerButtonProps={\n      props.OpenPickerButtonProps\n        ? props.OpenPickerButtonProps\n        : {\n            size: 'large',\n          }\n    }\n    desktopModeMediaQuery={'@media (min-width: 720px)'}\n    renderInput={(_props) => {\n      return (\n        <DateTextField\n          ref={_props.inputRef}\n          fullWidth={fullWidth}\n          {...{ ...textFiledProps, ..._props, helperText: null }}\n        />\n      )\n    }}\n  />\n)\n// (({ theme }) => ({\n//     position: 'relative',\n//     '& .MuiIconButton-edgeEnd': {\n//         position: 'absolute',\n//         left: 0,\n//         right: 0,\n//         padding: 0,\n//         height: '100%',\n//         display: 'flex',\n//         justifyContent: 'center',\n//         color: theme.palette.primary.light\n//     }\n// }))\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/form/input/Default.tsx",
    "content": "import styled from '@emotion/styled'\nimport React from 'react'\nimport { Avatar, Box, FormControlLabel as MuFormControlLabel } from '@mui/material'\nimport {\n  AvatarCoinProps,\n  AvatarCoinStyled,\n  LPTokenType,\n  MarketType,\n  SoursURL,\n  TokenType,\n} from '@loopring-web/common-resources'\nimport { useSettings } from '../../../../stores'\nimport { VaultTag } from '../../tags'\n\nexport const FormControlLabel = styled(MuFormControlLabel)`\n  && {\n    padding-right: ${({ theme }) => theme.unit * 2}px;\n    background-color: inherit;\n    border-radius: ${({ theme }) => theme.unit / 2}px;\n    color: var(--color-text-secondary);\n  }\n`\n\nexport const AvatarCoin = (props: AvatarCoinProps) => {\n  const size = props.size ?? 36\n  return (\n    <Box\n      display={'inline-flex'}\n      alignItems={'center'}\n      justifyContent={'center'}\n      height={36}\n      width={36}\n      sx={{ transform: `scale(${size / (36 * 2)})` }}\n    >\n      <AvatarCoinStyled {...props} />\n    </Box>\n  )\n}\n\nexport const CoinIcon = <R extends MarketType | string | LPTokenType>({\n  symbol,\n  lpSize = 24,\n  size: _size,\n  type,\n  tokenImageKey,\n}: {\n  symbol: R\n  lpSize?: number\n  size?: number | 'middle' | 'small' | 'large'\n  type?: TokenType\n  tokenImageKey?: R\n}) => {\n  const { coinJson } = useSettings()\n  const size = React.useMemo(() => {\n    if (!_size) {\n      return 24\n    } else if (typeof _size === 'string') {\n      switch (_size) {\n        case 'middle':\n          return 24\n          break\n        case 'small':\n          return 20\n          break\n        case 'large':\n          return 36\n          break\n      }\n    } else {\n      return _size\n    }\n  }, [_size])\n\n  if (symbol && symbol.match(/LP-(\\w+)-(\\w+)/i) && coinJson) {\n    // @ts-ignore\n    const [, coinA, coinB] = symbol.match(/LP-(\\w+)-(\\w+)/i)\n    const coinAIcon: any = coinJson[coinA]\n    const coinBIcon: any = coinJson[coinB]\n\n    return (\n      <Box display={'flex'} alignItems={'center'} marginRight={-1 / 2}>\n        <Box\n          className={'logo-icon'}\n          display={'flex'}\n          height={'var(--list-menu-coin-size)'}\n          position={'relative'}\n          zIndex={20}\n          width={'var(--list-menu-coin-size)'}\n          alignItems={'center'}\n          justifyContent={'center'}\n        >\n          {coinAIcon ? (\n            <AvatarCoin\n              imgx={coinAIcon.x}\n              imgy={coinAIcon.y}\n              imgheight={coinAIcon.h}\n              imgwidth={coinAIcon.w}\n              size={lpSize}\n              variant='circular'\n              alt={symbol}\n              src={\n                'data:image/svg+xml;utf8,' +\n                '<svg width=\"36\" height=\"36\" viewBox=\"0 0 36 36\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M0 0H36V36H0V0Z\"/></svg>'\n              }\n            />\n          ) : (\n            <Avatar\n              variant='circular'\n              alt={symbol}\n              style={{\n                height: 'var(--list-menu-coin-size)',\n                width: 'var(--list-menu-coin-size)',\n              }}\n              src={SoursURL + 'images/icon-default.png'}\n            />\n          )}\n        </Box>\n        <Box\n          className={'logo-icon'}\n          display={'flex'}\n          height={'var(--list-menu-coin-size)'}\n          position={'relative'}\n          zIndex={18}\n          left={-8}\n          width={'var(--list-menu-coin-size)'}\n          alignItems={'center'}\n          justifyContent={'center'}\n        >\n          {coinBIcon ? (\n            <AvatarCoin\n              imgx={coinBIcon.x}\n              imgy={coinBIcon.y}\n              imgheight={coinBIcon.h}\n              imgwidth={coinBIcon.w}\n              size={lpSize}\n              variant='circular'\n              alt={symbol}\n              src={\n                'data:image/svg+xml;utf8,' +\n                '<svg width=\"36\" height=\"36\" viewBox=\"0 0 36 36\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M0 0H36V36H0V0Z\"/></svg>'\n              }\n            />\n          ) : (\n            <Avatar\n              variant='circular'\n              alt={symbol}\n              style={{\n                height: 'var(--list-menu-coin-size)',\n                width: 'var(--list-menu-coin-size)',\n              }}\n              src={SoursURL + 'images/icon-default.png'}\n            />\n          )}\n        </Box>\n      </Box>\n    )\n  } else {\n    if (type && type == TokenType.vault) {\n      const coinIcon: any = coinJson[tokenImageKey ?? symbol]\n      return (\n        <Box display={'flex'} alignItems={'flex-end'} marginRight={-1 / 2}>\n          <Box\n            className={'logo-icon'}\n            display={'flex'}\n            height={'var(--list-menu-coin-size)'}\n            position={'relative'}\n            zIndex={20}\n            width={'var(--list-menu-coin-size)'}\n            alignItems={'center '}\n            justifyContent={'center'}\n          >\n            {coinIcon ? (\n              <AvatarCoin\n                imgx={coinIcon.x}\n                imgy={coinIcon.y}\n                imgheight={coinIcon.h}\n                imgwidth={coinIcon.w}\n                size={size}\n                variant='circular'\n                alt={symbol}\n                src={\n                  'data:image/svg+xml;utf8,' +\n                  '<svg width=\"36\" height=\"36\" viewBox=\"0 0 36 36\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M0 0H36V36H0V0Z\"/></svg>'\n                }\n              />\n            ) : (\n              <Avatar\n                variant='circular'\n                alt={symbol}\n                style={{\n                  height: 'var(--list-menu-coin-size)',\n                  width: 'var(--list-menu-coin-size)',\n                }}\n                src={SoursURL + 'images/icon-default.png'}\n              />\n            )}\n          </Box>\n          <Box\n            className={`logo-icon ${type}`}\n            display={'flex'}\n            height={'var(--svg-size-small)'}\n            position={'relative'}\n            zIndex={24}\n            left={-10}\n            width={'var(--svg-size-small)'}\n            alignItems={'flex-center'}\n            justifyContent={'center'}\n          >\n            <VaultTag\n              sx={{\n                height: 36,\n                width: 36,\n                transformOrigin: 'bottom',\n                transform: `scale(${size / (36 * 4)})`,\n              }}\n            />\n          </Box>\n        </Box>\n      )\n    } else {\n      const coinIcon: any = coinJson[symbol]\n\n      return (\n        <>\n          {coinIcon ? (\n            <AvatarCoin\n              imgx={coinIcon.x}\n              imgy={coinIcon.y}\n              imgheight={coinIcon.h}\n              imgwidth={coinIcon.w}\n              size={size}\n              variant='circular'\n              alt={symbol}\n              src={\n                'data:image/svg+xml;utf8,' +\n                '<svg width=\"36\" height=\"36\" viewBox=\"0 0 36 36\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M0 0H36V36H0V0Z\"/></svg>'\n              }\n            />\n          ) : (\n            <Avatar\n              variant='circular'\n              alt={symbol}\n              style={{\n                height: 'var(--list-menu-coin-size)',\n                width: 'var(--list-menu-coin-size)',\n              }}\n              // src={sellData?.icon}\n              src={SoursURL + 'images/icon-default.png'}\n            />\n          )}\n        </>\n      )\n    }\n    // {[TokenType.vault].includes(type) && (\n    //     <Box\n    //         className={`logo-icon ${type}`}\n    //         display={'flex'}\n    //         height={'var(--btn-icon-size-small)'}\n    //         position={'relative'}\n    //         zIndex={24}\n    //         left={-12}\n    //         width={'var(--btn-icon-size-small)'}\n    //         alignItems={'center'}\n    //         justifyContent={'center'}\n    //     >\n    //       <VaultTag\n    //           sx={{\n    //             height: 36,\n    //             width: 36,\n    //             transformOrigin: 'bottom',\n    //             transform: `scale(${size / (36 * 2)})`,\n    //           }}\n    //       />\n    //     </Box>\n    // )}\n  }\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/form/input/InputButton.tsx",
    "content": "import { FormHelperText, Grid, Typography } from '@mui/material'\nimport {\n  CoinInfo,\n  DropDownIcon,\n  EmptyValueTag,\n  FORMAT_STRING_LEN,\n  getValuePrecisionThousand,\n  IBData,\n  mapSpecialTokenName,\n  SoursURL,\n} from '@loopring-web/common-resources'\nimport { InputButtonProps, InputSize } from './Interface'\nimport React from 'react'\nimport { useFocusRef } from '../hooks'\nimport { IInput, ISBtn, IWrap } from './style'\nimport { CoinIcon } from './Default'\nimport { sanitize } from 'dompurify'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nfunction _InputButton<T extends Partial<IBData<C>>, C, I extends CoinInfo<C>>(\n  {\n    label = 'Enter token',\n    handleError,\n    subLabel,\n    // wait = globalSetup.wait,\n    // coinMap,\n    disableInputValue,\n    maxAllow,\n    disabled,\n    decimalsLimit = 8,\n    allowDecimals = true,\n    isShowCoinIcon = false,\n    CoinIconElement,\n    emptyText = 'tokenSelectToken',\n    placeholderText = '0.00',\n    inputData,\n    handleCountChange,\n    handleOnClick,\n    focusOnInput,\n    name,\n    size = InputSize.middle,\n    isHideError = false,\n    fullwidth = false,\n    loading = false,\n    disableBelong = false,\n    className,\n    tokenType,\n    tokenImageKey = undefined,\n    belongAlice = undefined,\n    subEle,\n  }: // isAllowBalanceClick\n  InputButtonProps<T, C, I>,\n  ref: React.ForwardedRef<any>,\n) {\n  const { balance, belong, tradeValue } = (inputData ? inputData : {}) as IBData<C>\n  const [sValue, setsValue] = React.useState<number | undefined | string>(\n    tradeValue ? tradeValue : undefined,\n  )\n  const [error, setError] = React.useState<{\n    error: boolean\n    message?: string | JSX.Element\n  }>({\n    error: false,\n    message: '',\n  })\n  React.useEffect(() => {\n    if (tradeValue === undefined && error.error) {\n      setError({ error: false })\n    } else if (balance && tradeValue) {\n      _handleError(tradeValue)\n    }\n  }, [tradeValue, balance])\n  const _handleError = React.useCallback(\n    (value: any) => {\n      if (handleError) {\n        let _error = handleError(\n          {\n            balance: Number(balance),\n            belong,\n            ...{ tradeValue: value },\n            maxAllow,\n          } as T & { maxAllow?: boolean },\n          ref,\n        )\n        setError(_error ? _error : { error: false })\n      }\n    },\n    [handleError, balance, belong, maxAllow, ref],\n  )\n\n  const inputCallback = React.useCallback(\n    ({ current }: any) => {\n      if (inputData && inputData.tradeValue !== Number(current?.value)) {\n        setsValue(inputData.tradeValue)\n        _handleError(inputData.tradeValue)\n      }\n    },\n    [inputData, _handleError],\n  )\n  const inputEle = useFocusRef({\n    callback: inputCallback,\n    shouldFocusOn: focusOnInput,\n    value: tradeValue,\n  })\n  // const debounceCount = debounce(({...props}: any) => {\n  //     if (handleCountChange) {\n  //         handleCountChange({...props}, ref)\n  //     }\n  // }, wait)\n  const _handleContChange = React.useCallback(\n    (value: any, _name: any) => {\n      _handleError(value)\n      setsValue(value)\n      if (handleCountChange) {\n        handleCountChange({ ...inputData, ...{ tradeValue: value } } as any, _name, ref)\n      }\n      //debounceCount({...inputData, ...{tradeValue: value}})\n    },\n    [_handleError, setsValue, inputData, handleCountChange, ref],\n  )\n\n  // const _handleContChange =\n  // const _handleOnClick = React.useCallback((event: React.MouseEvent) => {\n  //     if (handleOnClick) handleOnClick(event,ref)\n  // }, [])\n  const _handleMaxAllowClick = React.useCallback(\n    (_event: React.MouseEvent) => {\n      if (maxAllow && !disabled) {\n        _handleContChange(balance, name)\n        //setsValue(balance);\n      }\n    },\n    [_handleContChange, balance, name, maxAllow],\n  )\n  //@ts-ignore\n  // const {coinJson} = useSettings();\n  // const coinIcon: any = coinJson[ belong ];\n  //\"x\": 248,\n  // \"y\": 322,\n  // \"w\": 36,\n  // \"h\": 35,\n  // \"offX\": 0,\n  // \"offY\": 0,\n  // \"sourceW\": 37,\n  // \"sourceH\": 36\n  // const coinInfo: any = coinMap[ belong ] ? coinMap[ belong ] : {};\n  // const hasLoaded = useImage(coinInfo.icon ? coinInfo.icon : '').hasLoaded;\n\n  // formatValue(sValue)\n\n  return (\n    <IWrap className={className} component={'div'} ref={ref} size={size} fullWidth={fullwidth}>\n      <Grid\n        container\n        component={'div'}\n        className={'label-wrap'}\n        justifyContent={'space-between'}\n        paddingBottom={1 / 2}\n      >\n        <Grid item xs={3}>\n          <Typography\n            fontSize={'inherit'}\n            className={'main-label'}\n            color={'var(--color-text-third)'}\n          >\n            {label}\n          </Typography>\n        </Grid>\n        <Grid item xs={9} className={'sub-label'}>\n          {subEle ? (\n            subEle\n          ) : subLabel && belong ? (\n            <Typography\n              fontSize={'inherit'}\n              className={\n                maxAllow && balance > 0\n                  ? `max-allow ${disabled ? 'disabled' : ''}`\n                  : `no-balance ${disabled ? 'disabled' : ''}`\n              }\n              onClick={_handleMaxAllowClick}\n            >\n              <span>{subLabel}</span>\n              <span>\n                {balance ? getValuePrecisionThousand(balance, 8, 8, 8, false) : EmptyValueTag}\n              </span>\n            </Typography>\n          ) : null}\n        </Grid>\n      </Grid>\n      <Grid\n        container\n        className={`btnInput-wrap\n                  ${(belong && belong.length) >= FORMAT_STRING_LEN ? 'text-small' : ''}\n                  ${error.error ? 'error' : ''}\n                  `}\n        wrap={'nowrap'}\n        alignItems={'stretch'}\n        alignContent={'stretch'}\n      >\n        <Grid item className={'btn-wrap'}>\n          <ISBtn\n            variant={'text'}\n            onClick={(event) => handleOnClick(event, name ?? 'inputBtnDefault', ref)}\n            endIcon={\n              disabled || disableBelong ? (\n                <></>\n              ) : (\n                <DropDownIcon color={'inherit'} fontSize={'large'} style={{ marginLeft: '-4px' }} />\n              )\n            }\n            disabled={disabled || disableBelong}\n            sx={{textTransform: 'none'}}\n          >\n            {belong ? (\n              <Grid container align-items={'center'} display={'flex'}>\n                {isShowCoinIcon && (\n                  <Grid\n                    item\n                    display={'flex'}\n                    className={'logo-icon'}\n                    width={'var(--list-menu-coin-size)'}\n                    height={'var(--list-menu-coin-size)'}\n                    alignItems={'center'}\n                    justifyContent={'center'}\n                  >\n                    <CoinIcon\n                      tokenImageKey={tokenImageKey ?? undefined}\n                      symbol={belong}\n                      type={tokenType ?? undefined}\n                    />\n                  </Grid>\n                )}\n                {!isShowCoinIcon && CoinIconElement && (\n                  <Grid\n                    item\n                    display={'flex'}\n                    className={'logo-icon'}\n                    width={'var(--list-menu-coin-size)'}\n                    height={'var(--list-menu-coin-size)'}\n                    alignItems={'center'}\n                    justifyContent={'center'}\n                  >\n                    {CoinIconElement}\n                  </Grid>\n                )}\n                <Grid item paddingLeft={1}>\n                  <Typography\n                    fontSize={'inherit'}\n                    color={'inherit'}\n                    dangerouslySetInnerHTML={{ __html: sanitize(mapSpecialTokenName(belongAlice ?? belong))  }}\n                  />\n                </Grid>\n              </Grid>\n            ) : (\n              <span className={'placeholder'}>{emptyText}</span>\n            )}\n          </ISBtn>\n        </Grid>\n        <Grid item className={'input-wrap input-wrap-right'} sx={{ position: 'relative' }}>\n          {loading && (\n            <img\n              style={{\n                position: 'absolute',\n                transform: 'translate(50%, -50%)',\n                top: '50%',\n                right: '24px',\n              }}\n              className='loading-gif'\n              alt={'loading'}\n              width='24'\n              src={`${SoursURL}images/loading-line.gif`}\n            />\n          )}\n\n          <IInput\n            className={loading ? 'loading' : ''}\n            ref={inputEle}\n            autoComplete='off'\n            onValueChange={_handleContChange}\n            value={typeof sValue === 'undefined' ? '' : sValue}\n            allowNegativeValue={false}\n            decimalSeparator='.'\n            groupSeparator={sdk.SEP}\n            name={name}\n            disabled={!(!disabled || belong) || disableInputValue || loading}\n            placeholder={placeholderText}\n            aria-placeholder={placeholderText}\n            aria-label={belong}\n            decimalsLimit={decimalsLimit}\n            allowDecimals={allowDecimals}\n          />\n          <label />\n        </Grid>\n      </Grid>\n      {isHideError ? (\n        <></>\n      ) : (\n        <Grid\n          container\n          className={'message-wrap'}\n          wrap={'nowrap'}\n          alignItems={'stretch'}\n          alignContent={'stretch'}\n          justifyContent={'flex-end'}\n        >\n          <Grid item>\n            <FormHelperText>{error.message}</FormHelperText>\n          </Grid>\n        </Grid>\n      )}\n    </IWrap>\n  )\n}\n\nexport const InputButton = React.memo(React.forwardRef(_InputButton)) as <\n  T,\n  C,\n  I extends CoinInfo<C>,\n>(\n  props: InputButtonProps<T, C, I> & React.RefAttributes<any>,\n) => JSX.Element\n//as React.ComponentType<InputButtonProps<coinType,CoinInfo> & RefAttributes<HTMLDivElement>>;\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/form/input/InputCode.tsx",
    "content": "import React from 'react'\nimport styled from '@emotion/styled'\nimport { Box } from '@mui/material'\n\nconst InputCodeStyle = styled(Box)`\n  .code-input {\n    display: flex;\n    flex-direction: column;\n    align-items: start;\n  }\n\n  //.code-label {\n  //  margin-bottom: 16px;\n  //}\n  //.code-inputs {\n  //  display: flex;\n  //  justify-content: start;\n  //  align-items: center;\n  //}\n  .code-inputs input {\n    border: none;\n    color: var(--color-text-third);\n    background-color: var(--field-opacity);\n    -webkit-box-shadow: none;\n    -moz-box-shadow: none;\n    box-shadow: none;\n    text-align: center;\n    height: 60px;\n    width: 40px;\n    border-radius: 4px;\n    margin: 0 4px;\n    border: 1px solid var(--color-border);\n    font-size: 38px;\n  }\n\n  .code-inputs input:focus {\n    outline: none;\n  }\n\n  .code-inputs input:first-of-type {\n    margin-left: 24px;\n  }\n\n  .code-inputs input:nth-of-type(3n) {\n    margin-right: 24px;\n  }\n` as typeof Box\n\nconst InputCode = ({\n  length,\n  loading,\n  onComplete,\n}: {\n  length: number\n  loading: boolean\n  onComplete: (code: string) => void\n}) => {\n  const [code, setCode] = React.useState([...Array(length)].map(() => ''))\n  const inputs = React.useRef([])\n  // Typescript\n  // useRef<(HTMLInputElement | null)[]>([])\n\n  const processInput = (e: React.ChangeEvent<HTMLInputElement>, slot: number) => {\n    const num = e.target.value\n    if (/[^0-9]/.test(num)) return\n    const newCode = [...code]\n    newCode[slot] = num\n    setCode(newCode)\n    if (slot !== length - 1) {\n      // @ts-ignore\n      inputs.current[slot + 1].focus()\n    }\n    if (newCode.every((num) => num !== '')) {\n      onComplete(newCode.join(''))\n    }\n  }\n\n  const onKeyUp = (e: React.KeyboardEvent<HTMLInputElement>, slot: number) => {\n    if (e.keyCode === 8 && !code[slot] && slot !== 0) {\n      const newCode = [...code]\n      newCode[slot - 1] = ''\n      setCode(newCode)\n      // @ts-ignore\n      inputs.current[slot - 1].focus()\n    }\n  }\n\n  return (\n    <InputCodeStyle\n      className='code-input'\n      display={'flex'}\n      flexDirection={'column'}\n      alignItems={'start'}\n    >\n      {/*<label className=\"code-label\">{label}</label>*/}\n      <Box className='code-inputs' display={'flex'} justifyContent={'start'} alignItems={'center'}>\n        {code.map((num, idx) => {\n          return (\n            <input\n              key={idx}\n              type='text'\n              inputMode='numeric'\n              maxLength={1}\n              value={num}\n              autoFocus={!code[0].length && idx === 0}\n              readOnly={loading}\n              onChange={(e) => processInput(e, idx)}\n              onKeyUp={(e) => onKeyUp(e, idx)}\n              // @ts-ignore\n              ref={(ref) => ref && inputs.current.push(ref)}\n            />\n          )\n        })}\n      </Box>\n    </InputCodeStyle>\n  )\n}\n\nexport { InputCode }\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/form/input/InputCoin.tsx",
    "content": "import { FormHelperText, Grid, Typography } from '@mui/material'\nimport {\n  CoinInfo,\n  FORMAT_STRING_LEN,\n  getValuePrecisionThousand,\n  IBData,\n  myLog,\n} from '@loopring-web/common-resources'\nimport { InputCoinProps, InputSize } from './Interface'\nimport React from 'react'\nimport { useFocusRef } from '../hooks'\nimport { CoinWrap, IInput, IWrap } from './style'\nimport { CoinIcon } from './Default'\nimport { useSettings } from '../../../../stores'\nimport { sanitize } from 'dompurify'\n\nfunction _InputCoin<T extends IBData<C>, C, I extends CoinInfo<C>>(\n  {\n    order = 'left',\n    label = 'Amount',\n    handleError,\n    subLabel,\n    className,\n    // wait = globalSetup.wait,\n    // coinMap,\n    // isBalanceLimit = true,\n    maxAllow,\n    disabled,\n    placeholderText = '0.00',\n    inputData,\n    handleCountChange,\n    focusOnInput,\n    name,\n    allowDecimals = true,\n    noBalance = '0.00',\n    decimalsLimit = 8,\n    size = InputSize.middle,\n    isHideError = false,\n    isShowCoinInfo = true,\n    isShowCoinIcon = true,\n    coinLabelStyle = undefined,\n    coinPrecision = 6,\n    CoinIconElement,\n    tokenType,\n    tokenImageKey,\n    belongAlice = undefined,\n  }: InputCoinProps<T, C, I>,\n  ref: React.ForwardedRef<any>,\n) {\n  const { balance, belong, tradeValue } = (inputData ? inputData : {}) as IBData<C>\n  // myLog(\"InputCoin\", balance, belong, tradeValue);\n  const { isMobile } = useSettings()\n  const [sValue, setsValue] = React.useState<number | undefined>(\n    tradeValue ? tradeValue : undefined,\n  )\n  React.useEffect(() => {\n    if (tradeValue === undefined && error.error) {\n      setError({ error: false })\n    } else if (balance !== undefined && tradeValue) {\n      _handleError(tradeValue)\n    }\n  }, [tradeValue, balance])\n  const [error, setError] = React.useState<{\n    error: boolean\n    message?: string | JSX.Element\n  }>({\n    error: false,\n    message: '',\n  })\n  const _handleError = React.useCallback(\n    (value: any) => {\n      if (handleError) {\n        let _error = handleError(\n          {\n            balance: Number(balance),\n            belong,\n            ...{ tradeValue: value },\n            maxAllow,\n          } as T & { maxAllow?: boolean },\n          ref,\n        )\n        setError(_error ? _error : { error: false })\n      }\n    },\n    [handleError, balance, belong, maxAllow, ref],\n  )\n  const inputCallback = React.useCallback(\n    ({ current }: any) => {\n      if (inputData && inputData.tradeValue !== Number(current?.value)) {\n        setsValue(inputData.tradeValue)\n        _handleError(inputData.tradeValue)\n        // debounceCount({...inputData, ...{tradeValue: inputData.tradeValue}})\n        // _handleContChange(current?.value, name)\n      }\n    },\n    [inputData, _handleError],\n  )\n  const inputEle = useFocusRef({\n    callback: inputCallback,\n    shouldFocusOn: focusOnInput,\n    value: tradeValue,\n  })\n\n  myLog('inputCoin ref inputEle', inputEle)\n  // const debounceCount = debounce(({...props}: any) => {\n  //     if (handleCountChange) {\n  //         handleCountChange({...props}, ref)\n  //     }\n  // }, wait)\n  const _handleContChange = React.useCallback(\n    (value: any, _name: any) => {\n      _handleError(value)\n      setsValue(value)\n      if (handleCountChange) {\n        handleCountChange({ ...inputData, ...{ tradeValue: value } } as any, _name, ref)\n      }\n      //debounceCount({...inputData, ...{tradeValue: value}})\n    },\n    [_handleError, setsValue, inputData, handleCountChange, ref],\n  )\n\n  // const _handleContChange =\n  // const _handleOnClick = React.useCallback((event: React.MouseEvent) => {\n  //     if (handleOnClick) handleOnClick(event,ref)\n  // }, [])\n  const _handleMaxAllowClick = React.useCallback(\n    (_event: React.MouseEvent) => {\n      if (maxAllow && !disabled) {\n        _handleContChange(balance, name)\n        //setsValue(balance);\n      }\n    },\n    [_handleContChange, balance, name, maxAllow, disabled],\n  )\n\n  // const coinInfo: any = coinMap[ belong ] ? coinMap[ belong ] : {};\n  // const hasLoaded = useImage(coinInfo.icon ? coinInfo.icon : '').hasLoaded;\n  // formatValue(sValue)\n  const formattedBalance = getValuePrecisionThousand(\n    balance,\n    undefined,\n    undefined,\n    coinPrecision,\n    false,\n    { floor: true },\n  )\n  return (\n    <>\n      <IWrap className={className} isMobile={isMobile} size={size} component={'div'} ref={ref}>\n        <Grid\n          container\n          component={'div'}\n          className={'label-wrap'}\n          justifyContent={'space-between'}\n          paddingBottom={1 / 2}\n        >\n          <Grid item xs={3}>\n            <Typography\n              fontSize={'inherit'}\n              color={'var(--color-text-third)'}\n              className={'main-label'}\n              component={'span'}\n            >\n              {label}\n            </Typography>\n          </Grid>\n          <Grid item xs={9} className={'sub-label'}>\n            {subLabel && belong ? (\n              <Typography\n                component={'span'}\n                fontSize={'inherit'}\n                color={'inherit'}\n                className={maxAllow && balance > 0 ? 'max-allow' : 'no-balance'}\n                onClick={_handleMaxAllowClick}\n              >\n                <span>{subLabel}</span>\n                <span>{balance ? formattedBalance : noBalance}</span>\n              </Typography>\n            ) : null}\n          </Grid>\n        </Grid>\n\n        <Grid\n          container\n          className={`coinInput-wrap\n         ${(belong && belong.length) >= FORMAT_STRING_LEN ? 'text-small' : ''} \n         ${error.error ? 'error' : ''}`}\n          wrap={'nowrap'}\n          alignItems={'stretch'}\n          alignContent={'stretch'}\n        >\n          {isShowCoinInfo && (\n            <CoinWrap\n              order={order === 'left' ? 2 : 1}\n              display={'flex'}\n              alignItems={'center'}\n              style={coinLabelStyle}\n              className={`icon-wrap icon-wrap-${order}`}\n            >\n              <Grid container align-items={'center'} display={'flex'}>\n                {isShowCoinIcon && (\n                  <Grid\n                    item\n                    display={'flex'}\n                    order={order === 'left' ? 2 : 1}\n                    paddingLeft={order === 'left' ? 1 : 0}\n                    className={'logo-icon'}\n                    width={'var(--list-menu-coin-size)'}\n                    height={'var(--list-menu-coin-size)'}\n                    alignItems={'center'}\n                    justifyContent={'center'}\n                  >\n                    <CoinIcon\n                      tokenImageKey={tokenImageKey ?? undefined}\n                      symbol={belong}\n                      type={tokenType ?? undefined}\n                    />\n                  </Grid>\n                )}\n                {!isShowCoinIcon && CoinIconElement && (\n                  <Grid\n                    item\n                    display={'flex'}\n                    order={order === 'left' ? 2 : 1}\n                    paddingLeft={order === 'left' ? 1 : 0}\n                    className={'logo-icon'}\n                    width={'var(--list-menu-coin-size)'}\n                    height={'var(--list-menu-coin-size)'}\n                    alignItems={'center'}\n                    justifyContent={'center'}\n                  >\n                    {CoinIconElement}\n                  </Grid>\n                )}\n                <Grid item order={order === 'left' ? 1 : 2} paddingLeft={order === 'left' ? 0 : 1}>\n                  <Typography\n                    fontSize={'inherit'}\n                    color={'inherit'}\n                    dangerouslySetInnerHTML={{ __html: sanitize(belongAlice ?? belong) }}\n                  />\n                </Grid>\n              </Grid>\n            </CoinWrap>\n          )}\n\n          <Grid\n            order={order === 'left' ? 1 : 2}\n            flex={1}\n            item\n            className={`input-wrap input-wrap-${order}`}\n          >\n            <IInput\n              ref={inputEle}\n              autoComplete='off'\n              onValueChange={_handleContChange}\n              value={typeof sValue === 'undefined' ? '' : isNaN(sValue) ? '' : sValue}\n              allowNegativeValue={false}\n              decimalSeparator='.'\n              groupSeparator=','\n              name={name}\n              decimalsLimit={decimalsLimit}\n              allowDecimals={allowDecimals}\n              disabled={disabled || !belong}\n              placeholder={placeholderText}\n              aria-placeholder={placeholderText}\n              aria-label={typeof label === 'string' ? label : ''}\n            />\n            <label />\n          </Grid>\n        </Grid>\n\n        {isHideError ? (\n          <></>\n        ) : (\n          <Grid\n            container\n            className={'message-wrap'}\n            wrap={'nowrap'}\n            alignItems={'stretch'}\n            alignContent={'stretch'}\n            justifyContent={'flex-end'}\n          >\n            <Grid item>\n              <FormHelperText sx={{ whiteSpace: 'pre-line', wordBreak: 'break-all' }}>\n                {error.message}\n              </FormHelperText>\n            </Grid>\n          </Grid>\n        )}\n      </IWrap>\n    </>\n  )\n}\n\nexport const InputCoin = React.memo(React.forwardRef(_InputCoin)) as <\n  T extends IBData<C>,\n  C,\n  I extends CoinInfo<C>,\n>(\n  props: InputCoinProps<T, C, I> & React.RefAttributes<any>,\n) => JSX.Element\n//as React.ComponentType<InputButtonProps<coinType,CoinInfo> & RefAttributes<HTMLDivElement>>;\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/form/input/InputMaxButton.tsx",
    "content": "import { Divider, FormHelperText, Grid, Link, Typography } from '@mui/material'\nimport {\n  CoinInfo,\n  DropDownIcon,\n  FORMAT_STRING_LEN,\n  getValuePrecisionThousand,\n  IBData,\n  SoursURL,\n} from '@loopring-web/common-resources'\nimport { InputButtonProps, InputSize } from './Interface'\nimport React from 'react'\nimport { useFocusRef } from '../hooks'\nimport { IInput, ISBtn, IWrap } from './style'\nimport { sanitize } from 'dompurify'\nimport { useTranslation } from 'react-i18next'\nimport { CoinIcon } from './Default'\n\nfunction _InputMaxButton<T extends Partial<IBData<C>>, C, I extends CoinInfo<C>>(\n  {\n    label = 'Enter token',\n    handleError,\n    subLabel,\n    order = 'left',\n    // wait = globalSetup.wait,\n    // coinMap,\n    disableInputValue,\n    maxAllow,\n    disabled,\n    decimalsLimit = 8,\n    allowDecimals = true,\n    isShowCoinIcon = false,\n    CoinIconElement,\n    emptyText = 'tokenSelectToken',\n    placeholderText = '0.00',\n    inputData,\n    handleCountChange,\n    handleOnClick,\n    focusOnInput,\n    name,\n    noBalance = '0.00',\n    size = InputSize.middle,\n    isHideError = false,\n    fullwidth = false,\n    loading = false,\n    className,\n    coinPrecision = 6,\n    tokenType,\n    tokenImageKey,\n    belongAlice = undefined,\n  }: // tokenType = TokenType.single,\n  // isAllowBalanceClick\n  InputButtonProps<T, C, I>,\n  ref: React.ForwardedRef<any>,\n) {\n  const { t } = useTranslation('common')\n\n  const { balance, belong, tradeValue, max } = (inputData ? inputData : {}) as IBData<C>\n  const [sValue, setsValue] = React.useState<number | undefined | string>(\n    tradeValue ? tradeValue : undefined,\n  )\n  const [error, setError] = React.useState<{\n    error: boolean\n    message?: string | JSX.Element\n  }>({\n    error: false,\n    message: '',\n  })\n  React.useEffect(() => {\n    if (tradeValue === undefined && error.error) {\n      setError({ error: false })\n    } else if (balance && tradeValue) {\n      _handleError(tradeValue)\n    }\n  }, [tradeValue, balance])\n  const _handleError = React.useCallback(\n    (value: any) => {\n      if (handleError) {\n        let _error = handleError(\n          {\n            balance: Number(balance),\n            belong,\n            ...{ tradeValue: value },\n            maxAllow,\n          } as T & {\n            maxAllow?: boolean\n          },\n          ref,\n        )\n        setError(_error ? _error : { error: false })\n      }\n    },\n    [handleError, balance, belong, maxAllow, ref],\n  )\n\n  const inputCallback = React.useCallback(\n    ({ current }: any) => {\n      if (inputData && inputData.tradeValue !== Number(current?.value)) {\n        setsValue(inputData.tradeValue)\n        _handleError(inputData.tradeValue)\n      }\n    },\n    [inputData, _handleError],\n  )\n  const inputEle = useFocusRef({\n    callback: inputCallback,\n    shouldFocusOn: focusOnInput,\n    value: tradeValue,\n  })\n\n  const _handleContChange = React.useCallback(\n    (value: any, _name: any) => {\n      _handleError(value)\n      setsValue(value)\n      if (handleCountChange) {\n        handleCountChange({ ...inputData, ...{ tradeValue: value } } as any, _name, ref)\n      }\n      //debounceCount({...inputData, ...{tradeValue: value}})\n    },\n    [_handleError, setsValue, inputData, handleCountChange, ref],\n  )\n\n  // const _handleContChange =\n  // const _handleOnClick = React.useCallback((event: React.MouseEvent) => {\n  //     if (handleOnClick) handleOnClick(event,ref)\n  // }, [])\n  const _handleMaxAllowClick = React.useCallback(\n    (_event: React.MouseEvent) => {\n      if (maxAllow && !disabled) {\n        _handleContChange(max ?? balance, name)\n        //setsValue(balance);\n      }\n    },\n    [_handleContChange, balance, name, maxAllow],\n  )\n  const formattedBalance = getValuePrecisionThousand(\n    balance,\n    undefined,\n    undefined,\n    coinPrecision,\n    false,\n    { floor: true },\n  )\n\n  return (\n    <IWrap className={className} component={'div'} ref={ref} size={size} fullWidth={fullwidth}>\n      <Grid\n        container\n        component={'div'}\n        className={'label-wrap'}\n        justifyContent={'space-between'}\n        paddingBottom={1 / 2}\n      >\n        <Grid item xs={3}>\n          <Typography\n            fontSize={'inherit'}\n            className={'main-label'}\n            color={'var(--color-text-third)'}\n          >\n            {label}\n          </Typography>\n        </Grid>\n      </Grid>\n      <Grid\n        container\n        columns={24}\n        className={`btnInput-wrap\n                  ${(belong && belong.length) >= FORMAT_STRING_LEN ? 'text-small' : ''}\n                  ${error.error ? 'error' : ''}\n                  `}\n        wrap={'nowrap'}\n        alignItems={'stretch'}\n        alignContent={'stretch'}\n        marginBottom={size == 'small' ? 1 : 2}\n      >\n        <Grid\n          item\n          xs={10}\n          order={order === 'left' ? 0 : 1}\n          className={`input-wrap input-wrap-${order}`}\n          sx={{ position: 'relative' }}\n        >\n          {loading && (\n            <img\n              style={{\n                position: 'absolute',\n                transform: 'translate(50%, -50%)',\n                top: '50%',\n                right: '24px',\n              }}\n              className='loading-gif'\n              alt={'loading'}\n              width='24'\n              src={`${SoursURL}images/loading-line.gif`}\n            />\n          )}\n\n          <IInput\n            className={loading ? 'loading' : ''}\n            ref={inputEle}\n            autoComplete='off'\n            onValueChange={_handleContChange}\n            value={typeof sValue === 'undefined' ? '' : sValue}\n            allowNegativeValue={false}\n            decimalSeparator='.'\n            groupSeparator=','\n            name={name}\n            disabled={!(!disabled || belong) || disableInputValue || loading}\n            placeholder={placeholderText}\n            aria-placeholder={placeholderText}\n            aria-label={belong}\n            decimalsLimit={decimalsLimit}\n            allowDecimals={allowDecimals}\n          />\n          <label />\n        </Grid>\n        <Grid\n          item\n          className={`btn-wrap btn-wrap-${order} bnt-input-max`}\n          xs={10}\n          order={order === 'left' ? 1 : 0}\n          display={'flex'}\n          direction={'row'}\n          alignItems={'center'}\n          justifyContent={'space-around'}\n          wrap={'nowrap'}\n          paddingY={1}\n          paddingX={1}\n        >\n          <ISBtn\n            variant={'text'}\n            onClick={(event) => handleOnClick(event, name ?? 'inputBtnDefault', ref)}\n            endIcon={\n              <DropDownIcon color={'inherit'} fontSize={'large'} style={{ marginLeft: '-4px' }} />\n            }\n            disabled={disabled}\n            sx={{\n              justifyContent: 'left'\n            }}\n          >\n            {belong ? (\n              <Grid container width={'auto'} align-items={'center'} display={'flex'} wrap={'nowrap'}>\n                {isShowCoinIcon && (\n                  <Grid\n                    item\n                    display={'flex'}\n                    // order={order === 'left' ? 2 : 1}\n                    paddingLeft={order === 'left' ? 0 : 0}\n                    className={'logo-icon'}\n                    width={'var(--list-menu-coin-size)'}\n                    height={'var(--list-menu-coin-size)'}\n                    alignItems={'center'}\n                    justifyContent={order === 'left' ? 'flex-start' : 'center'}\n                  >\n                    <CoinIcon\n                      tokenImageKey={tokenImageKey ?? undefined}\n                      symbol={belong}\n                      type={tokenType ?? undefined}\n                    />\n                  </Grid>\n                )}\n                {!isShowCoinIcon && CoinIconElement && (\n                  <Grid\n                    item\n                    display={'flex'}\n                    className={'logo-icon'}\n                    width={'var(--list-menu-coin-size)'}\n                    height={'var(--list-menu-coin-size)'}\n                    alignItems={'center'}\n                    justifyContent={'center'}\n                  >\n                    {CoinIconElement}\n                  </Grid>\n                )}\n                <Grid item paddingLeft={1}>\n                  <Typography\n                    fontSize={'inherit'}\n                    color={'inherit'}\n                    dangerouslySetInnerHTML={{ __html: sanitize(belongAlice ?? belong) }}\n                  />\n                </Grid>\n              </Grid>\n            ) : (\n              <span className={'placeholder'}>{emptyText}</span>\n            )}\n          </ISBtn>\n        </Grid>\n        <Grid\n          item\n          order={2}\n          xs={4}\n          display={'flex'}\n          direction={'row'}\n          alignItems={'center'}\n          justifyContent={'space-around'}\n          paddingY={1}\n          paddingX={1}\n        >\n          <Divider orientation={'vertical'} />\n          <Link\n            component={'span'}\n            fontSize={'inherit'}\n            className={maxAllow && balance > 0 ? 'max-allow' : 'no-balance'}\n            onClick={_handleMaxAllowClick}\n            marginLeft={1 / 2}\n          >\n            {t('labelInputMax')}\n          </Link>\n        </Grid>\n      </Grid>\n\n      {subLabel && (\n        <Grid container paddingBottom={1}>\n          <Grid item xs={12}>\n            <Typography\n              component={'span'}\n              fontSize={size === 'small' ? 'body1' : 'body1'}\n              color={'inherit'}\n            >\n              <Typography component={'span'} variant={'inherit'} color={'textSecondary'}>\n                {subLabel}\n                {/*{t('labelTokenMaxBalance')}*/}\n              </Typography>\n              <Typography\n                component={'span'}\n                variant={'inherit'}\n                color={'textPrimary'}\n                marginLeft={1 / 2}\n              >\n                {balance ? formattedBalance : noBalance}\n              </Typography>\n            </Typography>\n          </Grid>\n        </Grid>\n      )}\n      {isHideError ? (\n        <></>\n      ) : (\n        <Grid\n          container\n          className={'message-wrap'}\n          wrap={'nowrap'}\n          alignItems={'stretch'}\n          alignContent={'stretch'}\n          justifyContent={'flex-end'}\n        >\n          <Grid item>\n            <FormHelperText>{error.message}</FormHelperText>\n          </Grid>\n        </Grid>\n      )}\n    </IWrap>\n  )\n}\n\nexport const InputMaxButton = React.memo(React.forwardRef(_InputMaxButton)) as <\n  T,\n  C,\n  I extends CoinInfo<C>,\n>(\n  props: InputButtonProps<T, C, I> & React.RefAttributes<any>,\n) => JSX.Element\n//as React.ComponentType<InputButtonProps<coinType,CoinInfo> & RefAttributes<HTMLDivElement>>;\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/form/input/InputMaxCoin.tsx",
    "content": "import { Divider, FormHelperText, Grid, Link, Typography } from '@mui/material'\nimport {\n  CoinInfo,\n  FORMAT_STRING_LEN,\n  getValuePrecisionThousand,\n  IBData,\n  IBDataMax,\n} from '@loopring-web/common-resources'\nimport { InputCoinProps, InputSize } from './Interface'\nimport React from 'react'\nimport { useFocusRef } from '../hooks'\nimport { CoinWrap, IInput, IWrap } from './style'\nimport { useSettings } from '../../../../stores'\nimport { useTranslation } from 'react-i18next'\nimport { CoinIcon } from './Default'\n\nfunction _InputMaxCoin<T extends IBDataMax<C>, C, I extends CoinInfo<C>>(\n  {\n    order = 'left',\n    label = 'Amount',\n    handleError,\n    subLabel,\n    className,\n    maxAllow,\n    disabled,\n    placeholderText = '0.00',\n    inputData,\n    handleCountChange,\n    focusOnInput,\n    name,\n    allowDecimals = true,\n    noBalance = '0.00',\n    decimalsLimit = 8,\n    size = InputSize.middle,\n    isHideError = false,\n    isShowCoinIcon = true,\n    coinLabelStyle = undefined,\n    coinPrecision = 6,\n    CoinIconElement,\n    tokenType,\n    tokenImageKey,\n  }: // coinIcon,\n  InputCoinProps<T, C, I>,\n  ref: React.ForwardedRef<any>,\n) {\n  const { t } = useTranslation('common')\n  const { balance, belong, tradeValue, max } = (inputData ? inputData : {}) as IBData<C>\n  // myLog(\"InputCoin\", balance, belong, tradeValue);\n  const { isMobile } = useSettings()\n\n  const [sValue, setsValue] = React.useState<number | undefined>(\n    tradeValue ? tradeValue : undefined,\n  )\n  React.useEffect(() => {\n    if (tradeValue === undefined && error.error) {\n      setError({ error: false })\n    } else if (balance !== undefined && tradeValue) {\n      _handleError(tradeValue)\n    }\n  }, [tradeValue, balance])\n  const [error, setError] = React.useState<{\n    error: boolean\n    message?: string | JSX.Element\n  }>({\n    error: false,\n    message: '',\n  })\n  const _handleError = React.useCallback(\n    (value: any) => {\n      if (handleError) {\n        let _error = handleError(\n          {\n            balance: Number(balance),\n            belong,\n            ...{ tradeValue: value },\n            maxAllow,\n          } as T & { maxAllow?: boolean },\n          ref,\n        )\n        setError(_error ? _error : { error: false })\n      }\n    },\n    [handleError, balance, belong, maxAllow, ref],\n  )\n  const inputCallback = React.useCallback(\n    ({ current }: any) => {\n      if (inputData && inputData.tradeValue !== Number(current?.value)) {\n        setsValue(inputData.tradeValue)\n        _handleError(inputData.tradeValue)\n        // debounceCount({...inputData, ...{tradeValue: inputData.tradeValue}})\n        // _handleContChange(current?.value, name)\n      }\n    },\n    [inputData, _handleError],\n  )\n  const inputEle = useFocusRef({\n    callback: inputCallback,\n    shouldFocusOn: focusOnInput,\n    value: tradeValue,\n  })\n\n  // const debounceCount = debounce(({...props}: any) => {\n  //     if (handleCountChange) {\n  //         handleCountChange({...props}, ref)\n  //     }\n  // }, wait)\n  const _handleContChange = React.useCallback(\n    (value: any, _name: any) => {\n      _handleError(value)\n      setsValue(value)\n      if (handleCountChange) {\n        handleCountChange({ ...inputData, ...{ tradeValue: value } } as any, _name, ref)\n      }\n      //debounceCount({...inputData, ...{tradeValue: value}})\n    },\n    [_handleError, setsValue, inputData, handleCountChange, ref],\n  )\n\n  // const _handleContChange =\n  // const _handleOnClick = React.useCallback((event: React.MouseEvent) => {\n  //     if (handleOnClick) handleOnClick(event,ref)\n  // }, [])\n  const _handleMaxAllowClick = React.useCallback(\n    (_event: React.MouseEvent) => {\n      if (maxAllow && !disabled) {\n        _handleContChange(max ?? balance, name)\n        //setsValue(balance);\n      }\n    },\n    [_handleContChange, balance, name, maxAllow, disabled],\n  )\n\n  // const coinInfo: any = coinMap[ belong ] ? coinMap[ belong ] : {};\n  // const hasLoaded = useImage(coinInfo.icon ? coinInfo.icon : '').hasLoaded;\n  // formatValue(sValue)\n  const formattedBalance = getValuePrecisionThousand(\n    balance,\n    undefined,\n    undefined,\n    coinPrecision,\n    false,\n    { floor: true },\n  )\n  return (\n    <>\n      <IWrap className={className} isMobile={isMobile} size={size} component={'div'} ref={ref}>\n        <Grid\n          container\n          component={'div'}\n          className={'label-wrap'}\n          justifyContent={'space-between'}\n          paddingBottom={1 / 2}\n        >\n          <Grid item xs={3}>\n            <Typography\n              fontSize={'inherit'}\n              color={'var(--color-text-secondary)'}\n              className={'main-label'}\n              component={'span'}\n            >\n              {label}\n            </Typography>\n          </Grid>\n        </Grid>\n\n        <Grid\n          container\n          className={`coinInput-wrap\n         ${(belong && belong.length) >= FORMAT_STRING_LEN ? 'text-small' : ''} \n         ${error.error ? 'error' : ''}`}\n          wrap={'nowrap'}\n          alignItems={'stretch'}\n          alignContent={'stretch'}\n          marginBottom={size == 'small' ? 1 : 2}\n        >\n          <Grid\n            order={order === 'left' ? 1 : 2}\n            flex={1}\n            item\n            className={`input-wrap input-wrap-${order}`}\n          >\n            <IInput\n              ref={inputEle}\n              autoComplete='off'\n              onValueChange={_handleContChange}\n              value={typeof sValue === 'undefined' ? '' : isNaN(sValue) ? '' : sValue}\n              allowNegativeValue={false}\n              decimalSeparator='.'\n              groupSeparator=','\n              name={name}\n              decimalsLimit={decimalsLimit}\n              allowDecimals={allowDecimals}\n              disabled={disabled || !belong}\n              placeholder={placeholderText}\n              aria-placeholder={placeholderText}\n              aria-label={typeof label === 'string' ? label : ''}\n            />\n          </Grid>\n          <Grid\n            order={order === 'left' ? 2 : 1}\n            xs={4}\n            item\n            display={'flex'}\n            direction={'row'}\n            alignItems={'center'}\n            justifyContent={'space-around'}\n            className={`input-wrap input-wrap-${order}`}\n            paddingY={1}\n            paddingX={1}\n          >\n            <CoinWrap\n              order={order === 'left' ? 1 : 3}\n              display={'flex'}\n              alignItems={'center'}\n              style={coinLabelStyle}\n              justifyContent={order === 'left' ? 'flex-end' : 'flex-start'}\n              className={`icon-wrap icon-wrap-${order} icon-input-max`}\n            >\n              {isShowCoinIcon && (\n                <Grid\n                  item\n                  display={'flex'}\n                  // order={order === 'left' ? 2 : 1}\n                  paddingLeft={order === 'left' ? 0 : 0}\n                  className={'logo-icon'}\n                  width={'var(--list-menu-coin-size)'}\n                  height={'var(--list-menu-coin-size)'}\n                  alignItems={'center'}\n                  justifyContent={order === 'left' ? 'flex-start' : 'center'}\n                >\n                  <CoinIcon\n                    tokenImageKey={tokenImageKey ?? undefined}\n                    symbol={belong}\n                    type={tokenType ?? undefined}\n                  />\n                </Grid>\n              )}\n              {!isShowCoinIcon && CoinIconElement && (\n                <Grid\n                  item\n                  display={'flex'}\n                  // order={order === 'left' ? 2 : 1}\n                  paddingLeft={order === 'left' ? 0 : 0}\n                  className={'logo-icon'}\n                  width={'var(--list-menu-coin-size)'}\n                  height={'var(--list-menu-coin-size)'}\n                  alignItems={'center'}\n                  justifyContent={'center'}\n                >\n                  {CoinIconElement}\n                </Grid>\n              )}\n              <Grid item order={order === 'left' ? 1 : 2} paddingLeft={order === 'left' ? 0 : 1}>\n                <Typography fontSize={'inherit'} color={'inherit'}>\n                  {belong}\n                </Typography>\n              </Grid>\n            </CoinWrap>\n            <Divider sx={{ order: 2, marginX: 1 / 2 }} orientation={'vertical'} />\n            <Link\n              order={order === 'left' ? 3 : 1}\n              component={'span'}\n              fontSize={'inherit'}\n              className={maxAllow && balance > 0 ? 'max-allow' : 'no-balance'}\n              onClick={_handleMaxAllowClick}\n            >\n              {t('labelInputMax')}\n            </Link>\n          </Grid>\n        </Grid>\n        {subLabel && (\n          <Grid container paddingBottom={1}>\n            <Grid item xs={12}>\n              <Typography component={'span'} fontSize={'body1'} color={'inherit'}>\n                <Typography component={'span'} variant={'inherit'} color={'textSecondary'}>\n                  {subLabel}\n                  {/*{t('labelTokenMaxBalance')}*/}\n                </Typography>\n                <Typography\n                  component={'span'}\n                  variant={'inherit'}\n                  color={'textPrimary'}\n                  marginLeft={1 / 2}\n                >\n                  {balance ? formattedBalance : noBalance}\n                </Typography>\n              </Typography>\n            </Grid>\n          </Grid>\n        )}\n        {/*<Grid item xs={9} className={'sub-label'}>*/}\n        {/*  */}\n        {/*</Grid>*/}\n        {isHideError ? (\n          <></>\n        ) : (\n          <Grid\n            container\n            className={'message-wrap'}\n            wrap={'nowrap'}\n            alignItems={'stretch'}\n            alignContent={'stretch'}\n            justifyContent={'flex-end'}\n          >\n            <Grid item>\n              <FormHelperText sx={{ whiteSpace: 'pre-line', wordBreak: 'break-all' }}>\n                {error.message}\n              </FormHelperText>\n            </Grid>\n          </Grid>\n        )}\n      </IWrap>\n    </>\n  )\n}\n\nexport const InputMaxCoin = React.memo(React.forwardRef(_InputMaxCoin)) as <\n  T extends IBData<C>,\n  C,\n  I extends CoinInfo<C>,\n>(\n  props: InputCoinProps<T, C, I> & React.RefAttributes<any>,\n) => JSX.Element\n//as React.ComponentType<InputButtonProps<coinType,CoinInfo> & RefAttributes<HTMLDivElement>>;\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/form/input/InputSearch.tsx",
    "content": "import { InputAdornment, OutlinedInput, OutlinedInputProps } from '@mui/material'\nimport { CloseIcon, SearchIcon } from '@loopring-web/common-resources'\nimport React from 'react'\nimport styled from '@emotion/styled'\n\nconst CloseIconStyled = styled(CloseIcon)`\n  position: absolute;\n  top: 55%;\n  transform: translateY(-50%);\n  right: ${({ theme }) => theme.unit}px;\n  cursor: pointer;\n`\n\nexport type InputSearchProps = {\n  value?: string\n  onChange?: (value: string) => void;\n} & OutlinedInputProps\n\nexport const InputSearch = React.forwardRef(\n  ({ value, onChange, ...rest }: InputSearchProps, _ref: React.ForwardedRef<any>) => {\n    return (\n      <OutlinedInput\n        {...{ ...rest }}\n        className={'search'}\n        aria-label={'search'}\n        placeholder={'Search'}\n        value={value}\n        onChange={(event: any) => {\n          if (onChange) {\n            onChange(event.target.value)\n          }\n        }}\n        startAdornment={\n          <InputAdornment position='start'>\n            <SearchIcon color={'inherit'} />\n          </InputAdornment>\n        }\n        endAdornment={\n          <CloseIconStyled\n            htmlColor={'var(--color-text-third)'}\n            style={{ visibility: value ? 'visible' : 'hidden' }}\n            onClick={() => {\n              if (onChange) {\n                onChange('' as any)\n              }\n            }}\n          />\n        }\n        sx={{\n          backgroundColor: 'transparent'\n        }}\n      />\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/form/input/InputSelect.tsx",
    "content": "import { Box } from '@mui/material'\nimport { CoinInfo, CoinKey, globalSetup } from '@loopring-web/common-resources'\nimport React from 'react'\nimport { InputSelectProps } from './Interface'\nimport { useFocusRef, usePanelRef } from '../hooks'\nimport { WithTranslation } from 'react-i18next'\nimport { InputSearch } from './InputSearch'\nimport * as _ from 'lodash'\n\nfunction _InputSelect<C, I extends string = CoinKey<C>>(\n  {\n    t,\n    handleContentChange,\n    wait = globalSetup.wait,\n    panelRender,\n    inputProps,\n    placeholder,\n    focusOnInput,\n    backElement,\n    selected,\n  }: InputSelectProps<C, I> & WithTranslation,\n  _ref: React.ForwardedRef<C>,\n) {\n  const [_value, setValue] = React.useState<{\n    selected: string | undefined\n    focusOnInput: boolean\n  }>({\n    selected: '',\n    focusOnInput: focusOnInput ? focusOnInput : false,\n  })\n  const debounceContentChange = React.useCallback(\n    _.debounce(({ value }: any) => {\n      if (handleContentChange) {\n        handleContentChange(value)\n      }\n    }, wait),\n    [],\n  )\n  const _handleContentChange = (value: any) => {\n    setValue({ ..._value, selected: value })\n    debounceContentChange({ value })\n  }\n\n  const inputEle = useFocusRef({\n    shouldFocusOn: _value.focusOnInput,\n    value: _value.selected,\n  })\n  // let height = '100%';\n  // let width = '100%';\n  const panelRef = usePanelRef({\n    // callback:({current})=>{\n    //  height = current.offsetHeight;\n    //   width = current.offsetWidth;\n    // }\n  })\n\n  React.useEffect(() => {\n    setValue({\n      selected: '',\n      focusOnInput: false,\n    })\n  }, [selected])\n  return (\n    <>\n      <Box\n        display={'flex'}\n        alignItems={'center'}\n        justifyContent={'space-between'}\n        paddingBottom={2}\n        paddingLeft={5 / 2}\n        paddingRight={5 / 2}\n      >\n        <InputSearch\n          key={'search'}\n          fullWidth\n          ref={inputEle}\n          {...inputProps}\n          aria-label={t(placeholder)}\n          placeholder={t(selected ? selected : placeholder)}\n          value={_value?.selected}\n          className={'search-wrap'}\n          onChange={_handleContentChange}\n        />\n        {backElement ? <Box marginLeft={2}>{backElement}</Box> : <></>}\n      </Box>\n      <Box flex={1} ref={panelRef}>\n        {panelRender({ selected, value: _value.selected })}\n      </Box>\n    </>\n  )\n}\n\nexport const InputSelect = React.memo(React.forwardRef(_InputSelect)) as <C, I = CoinInfo<C>>(\n  props: InputSelectProps<C, I> & WithTranslation & React.RefAttributes<HTMLDivElement>,\n) => JSX.Element\n//as React.ComponentType<InputButtonProps<coinType,CoinInfo> & RefAttributes<HTMLDivElement>>;\n// export const InputSelectSearch=withTranslation()(()=><></>)\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/form/input/Interface.ts",
    "content": "import { CoinInfo, CoinKey, CoinMap, CoinSource, TokenType } from '@loopring-web/common-resources'\nimport React from 'react'\nimport { InputProps } from '@mui/material'\nimport { XOR } from '../../../../types/lib'\nexport type defaultProps<T, R, I> = {\n  label: string | JSX.Element\n\n  coinMap: CoinMap<R, I extends CoinInfo<R> ? CoinInfo<R> : CoinInfo<R>>\n  placeholderText?: string\n  allowDecimals?: boolean\n  size?: InputSize\n  order?: 'left' | 'right'\n  tokenType?: TokenType | undefined\n  placeholder: string\n  handleError?: (\n    ibData: T & { maxAllow?: boolean },\n    ref: React.ForwardedRef<any>,\n  ) => { error: boolean; message?: string | JSX.Element }\n  maxValue?: string | number | undefined\n  focusOnInput?: boolean\n  coinPrecision?: number\n  className?: string\n  name?: string\n  minimum?: number | string\n  maxAllow?: boolean\n  decimalsLimit?: number\n  disabled?: boolean\n  logoColor?: string\n  wait?: number\n  isHideError?: boolean\n  tokenImageKey?: string\n  belongAlice?: string\n  coinIcon?: [CoinSource, CoinSource?]\n  noBalance?: string\n} & XOR<\n  { isShowCoinInfo?: true } & XOR<\n    { isShowCoinIcon: true },\n    { isShowCoinIcon: false; CoinIconElement?: JSX.Element }\n  >,\n  { isShowCoinInfo: false }\n> &\n  XOR<{ subLabel?: string }, { subEle: JSX.Element }>\n\nexport type InputButtonProps<T, R, I> = defaultProps<T, R, I> & {\n  inputData?: T | undefined\n  emptyText: string\n  isAllowBalanceClick?: boolean\n  disableInputValue?: boolean\n  disableBelong?: boolean\n  disabled?: boolean\n  logoColor?: string\n  wait?: number\n  maxValue?: string | number | undefined\n  minimum?: string | number | undefined\n  isHideError?: boolean\n  handleCountChange?: (ibData: T, name: string, ref: React.ForwardedRef<any>) => void\n  handleOnClick: (event: React.MouseEvent, name: string, ref: React.ForwardedRef<any>) => void\n  coinPrecision?: number\n  handleError?: (\n    tradeData: T & { maxAllow?: boolean },\n    ref: React.ForwardedRef<any>,\n  ) => { error: boolean; message?: string | JSX.Element }\n  focusOnInput?: boolean\n  name?: string\n  className?: string\n  fullwidth?: boolean\n  loading?: boolean\n  belongAlice?: string\n}\n\nexport enum InputSize {\n  middle = 'middle',\n  small = 'small',\n}\n\nexport type InputCoinProps<T, R, I> = defaultProps<T, R, I> & {\n  inputData?: T | undefined\n  handleCountChange?: (ibData: T, name: string, ref: React.ForwardedRef<any>) => void\n  coinLabelStyle?: React.CSSProperties\n}\nexport type InputSelectProps<T, I = CoinKey<T>> = {\n  placeholder?: string\n  focusOnInput?: boolean\n  // coinMap: CoinMap<R,I extends CoinInfo?CoinInfo:CoinInfo>,\n  // walletMap: WalletMap<R,I extends CoinInfo?WalletCoin:WalletCoin> | {},\n  panelRender: (props: any) => JSX.Element\n  height?: number //outSide height, default is defined in global.ts file\n  inputProps?: InputProps\n  backElement?: JSX.Element\n  allowScroll?: boolean\n  selected?: string | undefined\n  // handleClose?: (event: React.MouseEvent) => void,\n  handleContentChange?: (value: string | undefined | I) => void\n  // onRefresh?: (event: React.MouseEvent) => void,\n  useInputRef?: <T extends HTMLInputElement, I>(\n    props: useFocusRefProps<I>,\n    deps: any[],\n  ) => React.RefObject<T>\n  hasCancel?: boolean\n}\nexport type useFocusRefProps<I> = {\n  selected?: I | null | undefined\n  isFocus?: boolean\n  callback?: (props?: any) => void\n}\n\n// export type {IBData, CoinMap, CoinInfo, coinType}\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/form/input/TextareaWithCount.tsx",
    "content": "import { TextareaAutosizeStyled } from './style'\nimport React from 'react'\nimport { TextareaAutosizeProps } from '@mui/base/TextareaAutosize/TextareaAutosize'\nimport { Box, Typography } from '@mui/material'\nimport { useTranslation } from 'react-i18next'\n\nexport const TextareaWithCount = ({\n  // totalCount,\n  value,\n  handleError,\n  ...rest\n}: TextareaAutosizeProps & {\n  label?: string\n  // totalCount: number;\n  handleError?: (\n    value: string,\n    count: number,\n  ) =>\n    | {\n        error: boolean\n        message?: string | JSX.Element\n      }\n    | undefined\n}) => {\n  const [countObj, setCountObj] = React.useState({\n    number: 0,\n    count: rest.maxLength ?? 25,\n  })\n  const { t } = useTranslation(['error', 'common'])\n  const [error, setError] = React.useState<{\n    error: boolean\n    message?: string | JSX.Element\n  }>({\n    error: false,\n    message: '',\n  })\n  React.useEffect(() => {\n    if (value === undefined && error.error) {\n      setError({ error: false })\n    }\n  }, [value])\n  const _handleError = React.useCallback(\n    (value: any) => {\n      if (handleError) {\n        const error = handleError(value, countObj.count)\n        if (error) {\n          setError(error)\n        } else {\n          setError({ error: false })\n        }\n      } else {\n        if (value.length > countObj.count) {\n          setError({\n            error: true,\n            message: t('errorLengthLimit', {}),\n          })\n        } else {\n          setError({ error: false })\n        }\n      }\n    },\n    [countObj],\n  )\n\n  return (\n    <Box display={'flex'} flexDirection={'column'} justifyContent={'stretch'}>\n      <TextareaAutosizeStyled\n        {...{ ...rest }}\n        className={`${rest.className}  ${error.error ? 'error' : ''}`}\n        value={value}\n        aria-label={rest.label}\n        maxRows={rest.maxRows ?? 5}\n        minRows={rest.minRows ?? 5}\n        disabled={rest.disabled}\n        style={{\n          overflowX: 'hidden',\n          resize: 'vertical',\n          ...rest.style,\n        }}\n        maxLength={rest.maxLength}\n        onChange={(event, ..._rest) => {\n          setCountObj((state) => ({\n            number: event.target.value?.length ?? 0,\n            count: state.count,\n          }))\n          _handleError(event.target.value)\n          rest.onChange && rest.onChange(event, ..._rest)\n        }}\n        draggable={true}\n      />\n      <Typography\n        color={error.error ? 'var(--color-error)' : 'var(--color-text-third)'}\n        alignSelf={'flex-end'}\n        alignItems={'flex-end'}\n        display={'inline-flex'}\n        // marginTop={1 / 2}\n      >\n        {`${countObj.number}/${countObj.count}`}\n        {/*{this.state.count}*/}\n        {/*{countLimit > 0 && `/${countLimit}`}*/}\n      </Typography>\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/form/input/index.ts",
    "content": "export * from './InputSelect'\nexport * from './InputButton'\nexport * from './DatePicker'\nexport * from './Interface'\nexport * from './Default'\nexport * from './InputCoin'\nexport * from './InputSearch'\nexport * from './InputCode'\nexport * from './CollectionInput'\nexport * from './TextareaWithCount'\nexport * from './InputMaxButton'\nexport * from './InputMaxCoin'\nexport {\n  TextField,\n  TextareaAutosizeStyled,\n  InputSearchWrapperStyled,\n  RadioGroupStyle,\n  OutlinedInput,\n} from './style'\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/form/input/style.ts",
    "content": "import styled from '@emotion/styled'\nimport {\n  Box,\n  BoxProps,\n  Button,\n  ButtonProps,\n  RadioGroup,\n  TextareaAutosize,\n  TextField as MuiTextField,\n  OutlinedInput as MuiOutlinedInput,\n  TextFieldProps,\n  OutlinedInputProps,\n} from '@mui/material'\nimport CurrencyInput from 'react-currency-input-field'\n\nimport { InputSize } from './Interface'\nimport { css } from '@emotion/react'\n\nexport const inputHeightLarge = () => css`\n  height: var(--input-height-large);\n  font-size: 1.5rem;\n\n  .MuiInputAdornment-root {\n    svg {\n      height: var(--btn-icon-size-large);\n      width: var(--btn-icon-size-large);\n    }\n  }\n`\nexport const OutlinedInput = styled(MuiOutlinedInput)<OutlinedInputProps>`\n  ${({ size }) => size?.toLowerCase() === 'large' && inputHeightLarge}\n`\n\nexport const TextField = styled(MuiTextField)<TextFieldProps>`\n  && .MuiOutlinedInput-root {\n    ${({ size }) => size?.toLowerCase() === 'large' && inputHeightLarge}\n    background-color: transparent;\n  }\n  background-color: transparent;\n\n  input::placeholder {\n    color: var(--color-placeholder);\n    opacity: 1;\n  }\n\n  .MuiInputAdornment-root {\n    padding: 0 ${({ theme }) => theme.unit}px;\n  }\n\n  label + & {\n    //margin-top: 24px;\n    margin-top: 0;\n  }\n\n  && {\n    .MuiSelect-nativeInput + svg {\n      position: absolute;\n      right: ${({ size }) => (size === 'large' ? 1 : 0.4)}rem;\n      top: ${({ theme, size }) => (size === 'large' ? 2 * theme.unit : theme.unit)}px;\n      color: var(--color-text-secondary);\n    }\n\n    &:not(.MuiFormControl-fullWidth) {\n      max-width: 260px;\n    }\n\n    text-overflow: fade();\n  }\n\n  &:focus {\n    ${({ theme }) => theme.border.defaultFrame({ c_key: 'focus', d_R: 0.5 })};\n    outline: transparent;\n  }\n`\n// export MuiTextField = styled(MuTextField)<>``;\nexport const IWrap = styled(Box)<\n  BoxProps & {\n    size: 'middle' | 'small'\n    isMobile?: boolean\n    fullWidth?: boolean\n  }\n>`\n  ${({ theme }) => theme.border.defaultFrame({ c_key: 'var(--opacity)' })};\n  ${({ fullWidth }) => fullWidth && `width:100%`};\n\n  .label-wrap {\n    white-space: nowrap;\n    text-overflow: ellipsis;\n    text-transform: capitalize;\n    color: var(--color-text-secondary);\n  }\n\n  .message-wrap {\n    .MuiFormHelperText-root {\n      color: var(--color-error);\n      text-align: right;\n      font-size: ${({ theme }) => theme.fontDefault.h6};\n    }\n  }\n\n  .sub-label {\n    text-align: right;\n    cursor: pointer;\n\n    .max-allow {\n      text-decoration: underline dotted;\n      color: var(--color-secoundary);\n\n      &:hover {\n        color: var(--color-primary);\n      }\n    }\n\n    .no-balance {\n      text-decoration: none;\n    }\n\n    .disabled {\n      color: var(--color-text-disable);\n    }\n  }\n\n  .coinInput-wrap,\n  .btnInput-wrap {\n    position: relative;\n    box-sizing: border-box;\n    border-radius: ${({ theme }) => theme.unit}px;\n    margin-top: ${({ theme }) => `${theme.unit / 2}px`};\n    height: var(--input-height-large);\n\n    ::before {\n      content: '';\n      display: block;\n      width: 100%;\n      height: 100%;\n      position: absolute;\n      top: 0;\n      left: 0;\n      box-sizing: border-box;\n      pointer-events: none;\n      z-index: 1;\n    }\n\n    &.error {\n      border: 1px solid var(--color-error) !important;\n      border-radius: ${({ theme }) => theme.unit / 2}px;\n    }\n  }\n\n  .input-wrap {\n    //min-width: 128px;\n    // width: 100%;\n    flex: 1;\n    height: 100%;\n  }\n\n  .icon-wrap,\n  .btn-wrap {\n    max-width: var(--btn-max-width);\n    min-width: var(--coin-min-width);\n\n    .MuiButton-label {\n      justify-content: flex-start;\n    }\n    &.icon-wrap-left,\n    &.btn-wrap-left {\n      justify-content: flex-end;\n    }\n  }\n\n  ${({ size, theme, isMobile }) => {\n    if (size === InputSize.small) {\n      return `\n          .input-wrap,.icon-wrap{\n            font-size: ${isMobile ? theme.fontDefault.body2 : theme.fontDefault.body1};\n          }\n          .label-wrap, .main-label{\n            font-size: ${theme.fontDefault.body2};\n          }\n          .coinInput-wrap, .btnInput-wrap {\n            font-size: ${isMobile ? theme.fontDefault.body2 : theme.fontDefault.body1};\n            height: var(--btn-Input-small-height);\n            &.text-small{\n              font-size: ${theme.fontDefault.body2};\n            }\n            input[type=text]{\n              font-size: ${theme.fontDefault.body1};\n               &:focus {\n                outline: 0;\n              }\n            }\n          }\n         \n      `\n    } else {\n      return `\n          .input-wrap,.icon-wrap{\n             font-size: ${theme.fontDefault.h5};\n          }\n          .label-wrap{\n            font-size: ${theme.fontDefault.body1};\n          }\n          .coinInput-wrap, .btnInput-wrap{\n              font-size: ${theme.fontDefault.h4};\n              height: var(--input-height-large);\n              &.text-small{\n                font-size: ${theme.fontDefault.body1};\n              }\n              input[type=text]{\n                font-size: ${theme.fontDefault.h4};\n              }\n          }\n         \n      `\n    }\n  }};\n  &.swapWrap {\n    &.buyInput {\n      padding-top: ${({ theme }) => 2 * theme.unit}px;\n    }\n    :has(.btnInput-wrap.error) {\n      border-color: var(--color-error);\n    }\n    .btnInput-wrap {\n      &.error {\n        border: initial !important;\n        //border-bottom: 1px solid var(--color-error) !important;\n      }\n      input:focus + label::before {\n        box-shadow: initial;\n        ${({ theme }) => `${theme.border.defaultFrame({ c_key: 'var(--opacity)', d_R: 0.5 })};`}\n      }\n    }\n    //.input-wrap {\n    //  position: initial;\n    //}\n    flex: 1;\n    &:focus-within {\n      box-shadow: initial;\n\n      ${({ theme }) =>\n        `${theme.border.defaultFrame({ c_key: 'var(--color-border-hover)', d_R: 0.5 })};`}\n    }\n\n    min-height: var(--input-height-swap);\n    background: var(--field-opacity);\n    display: flex;\n    flex-direction: column;\n    position: relative;\n\n    .label-wrap {\n      //margin-left: 40%;\n      //width: 60%;\n\n      .MuiGrid-item {\n        flex-basis: inherit;\n        width: inherit;\n        max-width: inherit;\n      }\n      p {\n        padding-right: 1rem;\n      }\n      padding-top: 0.8rem;\n      height: var(--input-height-swap-label);\n    }\n    .btnInput-wrap {\n      position: initial;\n    }\n    .btn-wrap {\n      position: absolute;\n      top: 0rem;\n    }\n    //.input-wrap-right{\n    //\n    //}\n  }\n` as (\n  props: BoxProps & {\n    size: 'middle' | 'small'\n    isMobile?: boolean\n    fullWidth?: boolean\n  },\n) => JSX.Element\nexport const CoinWrap = styled(Box)<BoxProps & { logoColor?: any }>`\n  & {\n    border-top-right-radius: 0;\n    border-bottom-right-radius: 0;\n    border-right: 1px solid transparent;\n    white-space: nowrap;\n    text-overflow: ellipsis;\n    font-size: ${({ theme }) => theme.fontDefault.h5};\n    color: var(--color-text-primary);\n\n    .placeholder {\n      color: var(--color-text-secondary);\n    }\n  }\n\n  &.icon-wrap-right > div {\n    justify-content: flex-start;\n    padding-left: ${({ theme }) => (theme.unit / 2) * 3}px;\n    align-items: center;\n  }\n\n  &.icon-wrap-left > div {\n    justify-content: flex-end;\n    padding-right: ${({ theme }) => theme.unit}px;\n    align-items: center;\n  }\n` as (props: BoxProps & { logoColor?: any }) => JSX.Element\nexport const ISBtn = styled(Button)<ButtonProps & { logoColor?: any }>`\n  && {\n    width: 100%;\n    height: 100%;\n    border-top-right-radius: 0;\n    border-bottom-right-radius: 0;\n    border-right: 1px solid transparent;\n    white-space: nowrap;\n    text-overflow: ellipsis;\n    font-size: ${({ theme }) => theme.fontDefault.h5};\n    color: var(--color-text-primary);\n\n    .MuiButton-endIcon {\n      color: var(--color-text-third);\n    }\n\n    .placeholder {\n      color: var(--color-text-secondary);\n    }\n  }\n\n  &:hover,\n  &:active {\n    color: var(--color-text-primary);\n    background: var(--color-box-hover);\n  }\n  &.swapWrap {\n    //.input-wrap-right {\n    //  input[type='text'] {\n    //    text-align: left;\n    //  }\n    //}\n    & {\n      :active {\n        //color: var(--color-text-primary);\n        background: var(--opacity);\n      }\n    }\n  }\n` as (props: ButtonProps & { logoColor?: any }) => JSX.Element\n\nexport const IInput = styled(CurrencyInput)`\n  text-align: right;\n  color: var(--color-text-primary);\n\n  ::placeholder {\n    color: var(--color-placeholder);\n  }\n\n  :disabled {\n    color: var(--color-text-disable);\n  }\n\n  .loading:disabled {\n    color: var(--color-text-primary);\n  }\n\n  width: 100%;\n  height: 100%;\n  border: 0;\n  margin: 0;\n\n\n  display: block;\n  padding: .8rem 1rem;\n  min-width: 0;\n  background: none;\n  box-sizing: border-box;\n  animation-name: mui-auto-fill-cancel;\n  letter-spacing: inherit;\n  animation-duration: 10ms;\n  -webkit-tap-highlight-color: transparent;\n\n  + label {\n    height: 0;\n    width: 0;\n  }\n\n  :focus {\n    outline: 0;\n\n    & + label::before {\n      content: '';\n      position: absolute;\n      top: 0;\n      left: 0;\n      right: 0;\n      bottom: 0;\n      ${({ theme }) =>\n        `${theme.border.defaultFrame({\n          c_key: 'var(--color-border-hover)',\n          d_R: 0.5,\n        })};`};\n    }\n  }\n\n  .error &:focus {\n    & + label::before {\n      ${({ theme }) => `${theme.border.defaultFrame({ c_key: 'var(--opacity)', d_R: 0.5 })};`}\n    }\n  }\n\n  .input-wrap-right & {\n    text-align: right;\n    border-top-left-radius: 0;\n    border-bottom-left-radius: 0;\n\n\n    :focus {\n\n    }\n  }\n\n  .input-wrap-left & {\n    text-align: left;\n    border-top-right-radius: 0;\n    border-bottom-right-radius: 0;\n\n\n    :focus {\n\n    }\n  }\n}` as typeof CurrencyInput\n\nexport const TextareaAutosizeStyled = styled(TextareaAutosize)`\n  label + & {\n    margin-top: ${({ theme }) => theme.unit}px;\n  }\n\n  background: (var(--opacity));\n  font-family: inherit;\n  color: inherit;\n  padding: ${({ theme }) => theme.unit}px;\n  width: 100%;\n  ${({ theme }) =>\n    theme.border.defaultFrame({\n      c_key: theme.colorBase.border,\n      d_R: 0.5,\n    })};\n\n  &:focus {\n    ${({ theme }) => theme.border.defaultFrame({ c_key: 'focus', d_R: 0.5 })};\n    outline: transparent;\n  }\n\n  &:disabled {\n    line-height: 1.5em;\n    border: 0;\n    background: (var(--opacity));\n    color: var(--color-text-third);\n    ${({ theme }) =>\n      theme.border.defaultFrame({\n        c_key: theme.colorBase.opacity,\n        d_R: 0.5,\n      })};\n  }\n\n  &.error {\n    ${({ theme }) => theme.border.defaultFrame({ c_key: 'var(--color-error)', d_R: 0.5 })};\n  }\n` as typeof TextareaAutosize\n\nexport const InputSearchWrapperStyled = styled(Box)`\n  padding: ${({ theme }) => theme.unit * 2}px;\n  padding-bottom: 0;\n` as typeof Box\n\nexport const RadioGroupStyle = styled(RadioGroup)`\n  margin: 0;\n\n  .MuiFormControlLabel-root {\n    margin-right: 0;\n    display: inline-flex;\n    align-items: center;\n    justify-content: flex-end;\n    flex-direction: row;\n  }\n\n  .MuiFormControlLabel-label {\n    line-height: var(--svg-size-cover);\n  }\n` as typeof RadioGroup\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/index.tsx",
    "content": "export * from './btns'\nexport * from './form'\nexport * from './lists'\nexport * from './panel'\nexport * from './tables'\nexport * from './popover'\nexport * from './resource'\nexport * from './table-pagination'\nexport * from './tags'\nexport * from './media'\nexport { SpaceBetweenBox } from './display'\nexport { Loading } from './loading'\nexport { CustomCheckBox } from './checkbox'\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/lists/CoinList.tsx",
    "content": "import { Box, ListItem, ListItemIcon, ListItemText, Typography } from '@mui/material'\nimport { Trans, WithTranslation } from 'react-i18next'\nimport React from 'react'\nimport styled from '@emotion/styled'\nimport { CoinItemProps, CoinMenuProps } from './Interface'\nimport { CoinInfo, CoinKey, mapSpecialTokenName, TokenType, WalletCoin } from '@loopring-web/common-resources'\nimport { Virtuoso } from 'react-virtuoso'\nimport { CoinIcon } from '../form'\nimport { EmptyDefault } from '../empty'\n\nfunction _CoinMenu<C, I extends CoinInfo<C>>(\n  {\n    coinMap = {},\n    walletMap = {},\n    nonZero,\n    sorted,\n    filterBy = (ele, filterString) => {\n      return filterString && filterString.length\n        ? RegExp(filterString).test(ele.simpleName as string)\n        : true\n    },\n    filterString,\n    handleSelect,\n    allowScroll = true,\n    selected = null,\n    listProps = {},\n    height = '100px',\n    tokenType,\n    className,\n    filterWithBorrowed,\n    ...rest\n  }: CoinMenuProps<C, I> & WithTranslation,\n  _ref: React.Ref<HTMLUListElement>,\n) {\n  const [select, setSelect] = React.useState<CoinKey<C> | null>(selected as CoinKey<C>)\n  const [list, setList] = React.useState<any[]>([])\n  const virtuoso = React.useRef(null)\n  let rowIndex = 0\n  React.useEffect(() => {\n    if (select !== selected) {\n      setSelect(selected)\n    }\n  }, [select, selected])\n\n  if (nonZero === undefined) {\n    nonZero = false\n  }\n  if (sorted === undefined) {\n    sorted = true\n  }\n  const update = React.useCallback(() => {\n    if (coinMap) {\n      setList(\n        Object.keys(coinMap)\n          .reduce((list: Array<{ walletCoin: WalletCoin<C>; key: string }>, key) => {\n            const filter = filterBy(coinMap[key], filterString)\n            if (filter) {\n              const walletCoin: WalletCoin<C> = walletMap[key]\n                ? walletMap[key]\n                : { belong: key, count: 0 }\n              if ((nonZero && walletMap[key] && (filterWithBorrowed ? walletMap[key].borrowed > 0 : walletMap[key].count > 0) ) || !nonZero) {\n                list.push({ walletCoin, key: key })\n                if (select === key) {\n                  rowIndex = list.length - 1\n                }\n              }\n            }\n            return list\n          }, [])\n          .sort(function (a, b) {\n            if (sorted) {\n              if (a.walletCoin.count && b.walletCoin.count) {\n                return b.walletCoin.count - a.walletCoin.count\n              } else if (a.walletCoin.count && !b.walletCoin.count) {\n                return -1\n              } else if (!a.walletCoin.count && b.walletCoin.count) {\n                return 1\n              }\n              return a.walletCoin.belong.localeCompare(b.walletCoin.belong)\n            }\n            return 1\n          }),\n      )\n    }\n  }, [coinMap, filterString, sorted, walletMap, nonZero])\n  const coinMapJSONString = JSON.stringify(coinMap) \n  React.useEffect(() => {\n    update()\n  }, [coinMapJSONString, filterString, sorted])\n\n  const handleListItemClick = React.useCallback(\n    (_event: React.MouseEvent, select: CoinKey<C>) => {\n      setSelect(select)\n      handleSelect && handleSelect(_event, select)\n    },\n    [handleSelect],\n  )\n  return (\n    <>\n      {list.length ? (\n        <Virtuoso<{ walletCoin: WalletCoin<C>; key: string }>\n          data={list}\n          className={`coin-menu ${className}`}\n          style={{ minHeight: '210px', flex: 1 }}\n          ref={virtuoso}\n          initialTopMostItemIndex={rowIndex}\n          itemContent={(index, item) => {\n            let { walletCoin, key } = item //list[ index ];\n            return (\n              <CoinItem<C>\n                tokenType={tokenType}\n                key={index}\n                {...{\n                  coinInfo: coinMap[key] ?? ({} as CoinInfo<C>),\n                  walletCoin,\n                  select: select,\n                  handleListItemClick,\n                  itemKey: key as CoinKey<C>,\n                  ...rest,\n                }}\n              />\n            )\n          }}\n        />\n      ) : (\n        <Box flex={1} height={'100%'} width={'100%'}>\n          <EmptyDefault\n            height={'calc(100% - 35px)'}\n            message={() => {\n              return <Trans i18nKey='labelNoContent'>Content is Empty</Trans>\n            }}\n          />\n        </Box>\n      )}\n    </>\n  )\n}\n\nexport const CoinMenu = React.memo(React.forwardRef(_CoinMenu)) as unknown as <C, I = CoinInfo<C>>(\n  props: CoinMenuProps<C, I> & WithTranslation & React.RefAttributes<HTMLDivElement>,\n) => JSX.Element\n\nconst StyledCoinItem = styled(ListItem)`\n  && {\n    width: 100%;\n    display: flex;\n    justify-content: stretch;\n    justify-items: center;\n    height: var(--list-coin-item);\n    box-sizing: border-box;\n    padding-left: ${({ theme }) => (theme.unit / 2) * 5}px;\n    padding-right: ${({ theme }) => (theme.unit / 2) * 5}px;\n    align-items: center;\n  }\n\n  &.Mui-selected,\n  &.Mui-focusVisible {\n    background: var(--color-box-hover);\n\n    &:hover {\n      background: var(--color-box-hover);\n    }\n  }\n\n  .MuiListItemIcon-root {\n    height: var(--btn-icon-size);\n    width: var(--btn-icon-size);\n    min-width: var(--btn-icon-size);\n    margin-right: ${({ theme }) => theme.unit}px;\n    display: flex;\n    justify-content: center;\n    justify-items: center;\n    align-items: center;\n    .MuiAvatar-root {\n      transform-origin: center;\n    }\n  }\n\n  .MuiListItemText-multiline {\n    display: flex;\n    flex-direction: row;\n    justify-content: space-between;\n  }\n`\n\nexport const CoinItem = React.memo(\n  React.forwardRef(\n    <C extends any>(\n      {\n        // t,\n        coinInfo,\n        walletCoin,\n        select,\n        itemKey,\n        handleListItemClick,\n        tokenType,\n        contentEle,\n      }: CoinItemProps<C> & WithTranslation,\n      ref: React.ForwardedRef<any>,\n    ) => {\n      const { simpleName, erc20Symbol, belongAlice } = coinInfo\n\n      return (\n        <StyledCoinItem\n          button={false}\n          ref={ref}\n          key={itemKey as string}\n          selected={select === simpleName}\n          onClick={(event: React.MouseEvent) => handleListItemClick(event, itemKey)}\n        >\n          <ListItemIcon>\n            <CoinIcon\n              type={tokenType}\n              tokenImageKey={tokenType == TokenType.vault ? erc20Symbol ?? simpleName : undefined}\n              symbol={simpleName}\n              size={24}\n              lpSize={24}\n            />\n          </ListItemIcon>\n          <ListItemText\n            primary={mapSpecialTokenName(belongAlice ?? simpleName)}\n            secondary={\n              <>\n                {contentEle ? (\n                  contentEle({ ele: { ...walletCoin } })\n                ) : (\n                  <Typography\n                    sx={{ display: 'block' }}\n                    component='span'\n                    color='textSecondary'\n                    variant={'h5'}\n                  >\n                    {walletCoin.count}\n                  </Typography>\n                )}\n              </>\n            }\n          />\n        </StyledCoinItem>\n      )\n    },\n  ),\n) as unknown as <C>(\n  props: CoinItemProps<C> & WithTranslation & React.RefAttributes<any>,\n) => JSX.Element\n\n//  <C>(props: CoinItemProps<C> & RefAttributes<HTMLElement>) => JSX.Element;\n//as React.ComponentType<InputButtonProps<coinType,CoinInfo> & RefAttributes<HTMLDivElement>>;\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/lists/CollectionItem.tsx",
    "content": "import {\n  CardStyleItem,\n  CollectionItemProps,\n  CollectionListProps,\n  CollectionMedia,\n  EmptyDefault,\n  IconButtonStyle,\n} from '../../../index'\nimport {\n  Avatar,\n  Box,\n  Grid,\n  Link,\n  MenuItem,\n  Pagination,\n  Popover,\n  Radio,\n  Typography,\n} from '@mui/material'\nimport {\n  CollectionLimit,\n  CollectionMeta,\n  CopyIcon,\n  copyToClipBoard,\n  getShortAddr,\n  ImageIcon,\n  NFT_TYPE_STRING,\n  NFTLimit,\n  sizeNFTConfig,\n  SoursURL,\n  ViewMoreIcon,\n} from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport React from 'react'\nimport { useTranslation } from 'react-i18next'\nimport styled from '@emotion/styled'\nimport { bindMenu, bindTrigger, usePopupState } from 'material-ui-popup-state/hooks'\nimport { sanitize } from 'dompurify'\n\nconst BoxStyle = styled(Box)`\n  .MuiRadio-root {\n    position: absolute;\n    right: ${({ theme }) => theme.unit}px;\n    top: ${({ theme }) => theme.unit}px;\n    transform: scale(1.5);\n  }\n\n  .btn-group {\n    width: auto;\n  }\n\n  .collection:hover {\n    .btn-group {\n      display: flex;\n      width: initial;\n    }\n  }\n` as typeof Box\nconst BoxLabel = styled(Box)`\n  background: var(--color-box-third);\n  color: var(--color-text-button);\n  border-radius: ${({ theme }) => theme.unit}px;\n` as typeof Box\nconst BoxBtnGroup = styled(Box)`\n  position: absolute;\n  right: ${({ theme }) => 2 * theme.unit}px;\n  top: ${({ theme }) => 2 * theme.unit}px;\n  width: 100%;\n  //flex-direction: row-reverse;\n  &.mobile {\n  }\n` as typeof Box\n\nconst ActionMemo = React.memo(\n  <Co extends CollectionMeta>({\n    setShowDeploy,\n    setShowEdit,\n    setShowManageLegacy,\n    item,\n    account,\n    setShowMintNFT,\n  }: CollectionItemProps<Co>) => {\n    const { t } = useTranslation('common')\n\n    const popupState = usePopupState({\n      variant: 'popover',\n      popupId: 'collection-action',\n    })\n    const bindContent = bindMenu(popupState)\n    const bindAction = bindTrigger(popupState)\n\n    return (\n      <Grid item marginTop={1}>\n        <IconButtonStyle size={'large'} edge={'end'} {...{ ...bindAction }}>\n          <ViewMoreIcon />\n        </IconButtonStyle>\n        <Popover\n          {...bindContent}\n          anchorReference='anchorEl'\n          anchorOrigin={{\n            vertical: 'bottom',\n            horizontal: 'right',\n          }}\n          transformOrigin={{\n            vertical: 'top',\n            horizontal: 'right',\n          }}\n        >\n          <Box borderRadius={'inherit'} minWidth={110}>\n            {!!(\n              item.extra?.properties?.isCounterFactualNFT &&\n              item.extra?.properties?.isEditable &&\n              item.owner?.toLowerCase() === account?.accAddress?.toLowerCase() &&\n              item?.nftType !== NFT_TYPE_STRING.ERC721\n            ) && (\n              <MenuItem\n                onClick={() => {\n                  if (setShowEdit) {\n                    setShowEdit(item)\n                    popupState.close()\n                  }\n                }}\n              >\n                {t('labelCollectionEditBtn')}\n              </MenuItem>\n            )}\n            {!!(\n              item.extra?.properties?.isCounterFactualNFT &&\n              item.extra?.properties?.isEditable &&\n              item.extra?.properties?.isLegacy &&\n              item.owner?.toLowerCase() === account?.accAddress?.toLowerCase() &&\n              item?.nftType !== NFT_TYPE_STRING.ERC721\n            ) && (\n              <MenuItem\n                onClick={() => {\n                  if (setShowManageLegacy) {\n                    setShowManageLegacy(item)\n                    popupState.close()\n                  }\n                }}\n              >\n                {t('labelCollectionImportNFTBtn')}\n              </MenuItem>\n            )}\n            {item.extra?.properties?.isCounterFactualNFT &&\n            item.baseUri !== '' &&\n            item.deployStatus === sdk.DEPLOYMENT_STATUS.NOT_DEPLOYED &&\n            item.owner?.toLowerCase() === account?.accAddress?.toLowerCase() ? (\n              <MenuItem\n                onClick={(_e) => {\n                  setShowDeploy && setShowDeploy(item)\n                  popupState.close()\n                }}\n              >\n                {t('labelNFTDeployContract')}\n              </MenuItem>\n            ) : (\n              <></>\n              //   <MenuItem\n              //   onClick={(e) => {\n              //   e.stopPropagation();\n              //   window.open(\n              //   `${etherscanBaseUrl}address/${item?.contractAddress}`\n              //   );\n              //   window.opener = null;\n              // }}\n              //   >\n              // {t(\"labelViewEtherscan\")}\n              //   <LinkIcon\n              //   color={\"inherit\"}\n              //   fontSize={\"small\"}\n              //   style={{\n              //   verticalAlign: \"middle\",\n              //   marginLeft: 2,\n              // }}\n              //   />\n              //   </MenuItem>\n            )}\n            {/* {!!(\n              item.extra?.properties?.isCounterFactualNFT &&\n              item.extra?.properties?.isMintable &&\n              item.owner?.toLowerCase() === account?.accAddress?.toLowerCase() &&\n              item?.nftType !== NFT_TYPE_STRING.ERC721\n            ) && (\n              <MenuItem\n                onClick={() => {\n                  if (setShowMintNFT) {\n                    setShowMintNFT(item)\n                    popupState.close()\n                  }\n                }}\n              >\n                {t('labelNFTMintSimpleBtn')}\n              </MenuItem>\n            )} */}\n          </Box>\n        </Popover>\n      </Grid>\n    )\n  },\n)\n\nexport const CollectionItem = React.memo(\n  React.forwardRef(\n    <Co extends CollectionMeta>(props: CollectionItemProps<Co>, _ref: React.Ref<any>) => {\n      const {\n        item,\n        index,\n        setCopyToastOpen,\n        noEdit,\n        isSelectOnly = false,\n        selectCollection,\n        onItemClick,\n        getIPFSString,\n        baseURL,\n        size,\n      } = props\n      const { t } = useTranslation('common')\n      const sizeConfig = sizeNFTConfig(size ?? 'large')\n\n      return (\n        <CardStyleItem\n          ref={_ref}\n          className={'collection'}\n          size={size as any}\n          contentheight={sizeConfig.contentHeight}\n        >\n          <Box\n            position={'absolute'}\n            width={'100%'}\n            height={'100%'}\n            display={'flex'}\n            flexDirection={'column'}\n            justifyContent={'space-between'}\n          >\n            <CollectionMedia\n              item={item}\n              index={index}\n              getIPFSString={getIPFSString}\n              baseURL={baseURL}\n              // onNFTReload={onNFTReload}\n              onRenderError={() => undefined}\n              onClick={(e) => {\n                e.stopPropagation()\n                if (onItemClick) {\n                  onItemClick(item)\n                }\n              }}\n            />\n            {isSelectOnly && (\n              <Radio\n                size={'medium'}\n                checked={\n                  selectCollection?.contractAddress?.toLowerCase() ===\n                    item?.contractAddress?.toLowerCase() && selectCollection?.id === item.id\n                }\n                value={item.contractAddress}\n                name='radio-collection'\n                inputProps={{ 'aria-label': 'selectCollection' }}\n              />\n            )}\n            {!isSelectOnly && !noEdit && (\n              <BoxBtnGroup className={'btn-group'}>\n                <ActionMemo {...{ ...(props as any) }} />\n              </BoxBtnGroup>\n            )}\n            <BoxLabel\n              className={'boxLabel'}\n              display={'flex'}\n              height={sizeConfig.contentHeight}\n              flexDirection={'row'}\n              justifyContent={'space-between'}\n              alignItems={'center'}\n              position={'absolute'}\n              bottom={0}\n              left={0}\n              right={0}\n            >\n              {(item?.cached?.avatar ?? getIPFSString(item?.avatar ?? '', baseURL)).startsWith(\n                'http',\n              ) ? (\n                <Avatar\n                  sx={{\n                    bgcolor: 'var(--color-border-disable2)',\n                    width: sizeConfig.avatar,\n                    height: sizeConfig.avatar,\n                    ...(size === 'small' ? { display: 'none' } : {}),\n                  }}\n                  variant={'circular'}\n                  src={item?.cached?.avatar ?? getIPFSString(item?.avatar ?? '', baseURL)}\n                />\n              ) : (\n                <Avatar\n                  sx={{\n                    bgcolor: 'var(--color-border-disable2)',\n                    width: sizeConfig.avatar,\n                    height: sizeConfig.avatar,\n                    ...(size === 'small' ? { display: 'none' } : {}),\n                  }}\n                  variant={'circular'}\n                >\n                  <ImageIcon />\n                </Avatar>\n              )}\n\n              <Typography\n                className={'content'}\n                component={'span'}\n                marginLeft={size === 'small' ? 0 : 1}\n                color={'var(--color-text-button)'}\n                whiteSpace={'pre'}\n                overflow={'hidden'}\n                display={'flex'}\n                flexDirection={'column'}\n                textOverflow={'ellipsis'}\n                variant={'h5'}\n                alignItems={'flex-start'}\n                justifyContent={'space-evenly'}\n                alignSelf={'stretch'}\n              >\n                <Typography\n                  color={'textPrimary'}\n                  overflow={'hidden'}\n                  textOverflow={'ellipsis'}\n                  variant={size == 'small' ? 'body2' : 'body1'}\n                  component={'span'}\n                  paddingRight={size === 'small' ? 1 / 2 : 1}\n                  width={'100%'}\n                  dangerouslySetInnerHTML={{\n                    __html:\n                      sanitize(\n                        item?.name\n                          ? item.name\n                          : t('labelUnknown') +\n                              '-' +\n                              getShortAddr(item?.contractAddress ?? '', true),\n                      ) ?? '',\n                  }}\n                />\n                <Link\n                  variant={'body2'}\n                  display={'inline-flex'}\n                  style={{ color: 'var(--color-text-primary)' }}\n                  alignItems={'center'}\n                  paddingTop={1}\n                  onClick={(e) => {\n                    e.stopPropagation()\n                    copyToClipBoard(item?.contractAddress ?? '')\n                    setCopyToastOpen({ isShow: true, type: 'address' })\n                  }}\n                >\n                  {getShortAddr(item?.contractAddress ?? '')}\n                  <CopyIcon color={'inherit'} />\n                </Link>\n              </Typography>\n              <Typography\n                component={'span'}\n                whiteSpace={'pre'}\n                overflow={'hidden'}\n                display={'flex'}\n                paddingLeft={1}\n                flexDirection={'column'}\n                alignItems={'center'}\n                textOverflow={'ellipsis'}\n                justifyContent={'space-evenly'}\n              >\n                {item?.extends?.count && (\n                  <Typography\n                    color={'textPrimary'}\n                    component={'span'}\n                    whiteSpace={'pre'}\n                    overflow={'hidden'}\n                    textOverflow={'ellipsis'}\n                    width={'fit-content'}\n                    minWidth={'36px'}\n                  >\n                    {t(\n                      size == 'small'\n                        ? 'labelCollectionItemSimpleValue'\n                        : 'labelCollectionItemValue',\n                      {\n                        value:\n                          item?.extends?.count?.toString()?.length > 2\n                            ? '99+'\n                            : item?.extends?.count,\n                      },\n                    )}\n                  </Typography>\n                )}\n                <Typography\n                  component={'span'}\n                  color={'textPrimary'}\n                  title={item?.nftType}\n                  sx={size === 'small' ? { display: 'none' } : {}}\n                >\n                  {item?.nftType}\n                </Typography>\n              </Typography>\n            </BoxLabel>\n          </Box>\n        </CardStyleItem>\n      )\n    },\n  ),\n)\n\nexport const CollectionCardList = <Co extends CollectionMeta>({\n  collectionList,\n  page,\n  total,\n  onPageChange,\n  setCopyToastOpen,\n  setShowDeploy,\n  setShowManageLegacy,\n  setShowEdit,\n  setShowMintNFT,\n  setShowTradeIsFrozen,\n  toggle,\n  account,\n  onSelectItem,\n  onItemClick,\n  isSelectOnly = false,\n  selectCollection,\n  etherscanBaseUrl,\n  isLoading,\n  noEdit = false,\n  filter,\n  size = 'large',\n  ...rest\n}: CollectionListProps<Co> &\n  Partial<CollectionItemProps<Co>> & { onSelectItem?: (item: Co) => void }) => {\n  const { t } = useTranslation('common')\n  const sizeConfig = sizeNFTConfig(size)\n\n  return (\n    <BoxStyle\n      flex={1}\n      display={'flex'}\n      flexDirection={'column'}\n      justifyContent={'stretch'}\n      marginTop={2}\n      width={'100%'}\n    >\n      {isLoading ? (\n        <Box\n          flex={1}\n          display={'flex'}\n          alignItems={'center'}\n          justifyContent={'center'}\n          height={'90%'}\n        >\n          <img\n            className='loading-gif'\n            alt={'loading'}\n            width='36'\n            src={`${SoursURL}images/loading-line.gif`}\n          />\n        </Box>\n      ) : !collectionList?.length ? (\n        <Box flex={1} display={'flex'} alignItems={'center'} justifyContent={'center'}>\n          <EmptyDefault\n            style={{ flex: 1 }}\n            height={'100%'}\n            message={() => (\n              <Box flex={1} display={'flex'} alignItems={'center'} justifyContent={'center'}>\n                {t('labelNoContent')}\n              </Box>\n            )}\n          />\n        </Box>\n      ) : (\n        <>\n          <Grid container spacing={2} paddingBottom={3}>\n            {collectionList.map((item, index) => {\n              return (\n                <Grid\n                  xs={sizeConfig.wrap_xs}\n                  md={sizeConfig.wrap_md}\n                  lg={sizeConfig.wrap_lg}\n                  key={index.toString() + (item?.name ?? '')}\n                  item\n                  flex={'1 1 120%'}\n                  onClick={(e) => {\n                    e.stopPropagation()\n                    if (onSelectItem) {\n                      onSelectItem(item)\n                    }\n                  }}\n                >\n                  <CollectionItem\n                    {...{ ...rest }}\n                    size={size}\n                    onItemClick={onItemClick as any}\n                    etherscanBaseUrl={etherscanBaseUrl}\n                    selectCollection={selectCollection}\n                    isSelectOnly={isSelectOnly}\n                    noEdit={noEdit}\n                    setShowTradeIsFrozen={setShowTradeIsFrozen as any}\n                    account={account}\n                    toggle={toggle}\n                    setShowDeploy={setShowDeploy as any}\n                    setShowEdit={setShowEdit as any}\n                    setShowManageLegacy={setShowManageLegacy as any}\n                    setShowMintNFT={setShowMintNFT as any}\n                    setCopyToastOpen={setCopyToastOpen as any}\n                    item={item as any}\n                    index={index}\n                  />\n                </Grid>\n              )\n            })}\n          </Grid>\n          {total > CollectionLimit && (\n            <Box\n              display={'flex'}\n              alignItems={'center'}\n              justifyContent={'right'}\n              marginRight={3}\n              marginBottom={2}\n            >\n              <Pagination\n                color={'primary'}\n                count={parseInt(String(total / NFTLimit)) + (total % NFTLimit > 0 ? 1 : 0)}\n                page={page}\n                onChange={(_event, value) => {\n                  onPageChange(Number(value), filter ? { ...filter } : undefined)\n                }}\n              />\n            </Box>\n          )}\n        </>\n      )}\n    </BoxStyle>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/lists/FileListItem.tsx",
    "content": "import { Box, IconButton, ListItem, ListItemText, Typography } from '@mui/material'\nimport { CloseIcon, CompleteIcon, FailedIcon, LoadingIcon } from '@loopring-web/common-resources'\nimport React, { ForwardedRef } from 'react'\nimport { IpfsFile } from '../panel'\n\nexport const FileListItem = React.memo(\n  React.forwardRef(\n    (\n      {\n        file,\n        // index,\n        onDelete,\n        isProcessing,\n        error,\n      }: IpfsFile & {\n        onDelete: () => void\n        index: number\n      },\n      ref: ForwardedRef<any>,\n    ) => {\n      return (\n        <ListItem\n          ref={ref}\n          sx={{\n            display: 'flex',\n            justifyContent: 'space-between',\n          }}\n        >\n          <ListItemText\n            primary={\n              <Typography sx={{ display: 'block' }} component='span' variant='body1'>\n                {file.name}\n              </Typography>\n            }\n            secondary={\n              <Typography sx={{ display: 'inline' }} component='span' variant='body2'>\n                size: {file.size}\n              </Typography>\n            }\n          />\n          <Box\n            className={'status'}\n            display={'flex'}\n            justifyContent={'flex-end'}\n            alignItems={'center'}\n          >\n            <Typography color={'primay'}>\n              {isProcessing ? (\n                <LoadingIcon color={'inherit'} />\n              ) : error ? (\n                <FailedIcon color={'error'} />\n              ) : (\n                <CompleteIcon color={'success'} />\n              )}\n            </Typography>\n            <IconButton edge={'end'} onClick={onDelete}>\n              <CloseIcon color={'error'} />\n            </IconButton>\n          </Box>\n        </ListItem>\n      )\n    },\n  ),\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/lists/HeadMenuItem.tsx",
    "content": "import {\n  Box,\n  BoxProps,\n  Container,\n  ListItemAvatar,\n  MenuItem,\n  MenuProps,\n  Typography,\n} from '@mui/material'\nimport { WithTranslation } from 'react-i18next'\nimport { bindHover, bindMenu, bindTrigger, usePopupState } from 'material-ui-popup-state/hooks'\nimport { BasicHeaderItem, HeadMenuType, MenuItemLink, MenuItemProps } from './Interface'\nimport styled from '@emotion/styled'\nimport clsx from 'clsx'\nimport {\n  ammDisableList,\n  DropDownIcon,\n  L1L2_NAME_DEFINED,\n  MapChainId,\n  orderDisableList,\n} from '@loopring-web/common-resources'\nimport Menu from 'material-ui-popup-state/HoverMenu'\nimport React, { ForwardedRef, RefAttributes } from 'react'\nimport { useHistory, useRouteMatch } from 'react-router-dom'\nimport { useSettings } from '../../../stores'\n\nexport const HeaderMenu = styled(Container)`\n  display: flex;\n  justify-content: space-between;\n  align-items: stretch;\n  position: relative;\n` as typeof Container\nconst StyledHeadMenuItem = styled(MenuItem)<MenuItemProps<any>>`\n  &:not(.layer-0) {\n    display: flex;\n    min-height: var(--header-submenu-item-height);\n    height: fit-content;\n    width: var(--header-submenu-item-weight);\n    align-items: flex-start;\n  }\n\n\n  &.layer-0 {\n    display: flex;\n    flex-direction: column;\n    justify-content: center;\n    text-transform: capitalize;\n      // font-size: ${({ theme }) => theme.fontDefault.h5};\n    box-shadow: inherit;\n    height: var(--header-height);\n    //color: var(--color-text-secondary);\n    background: inherit;\n    position: relative;\n    &.Mui-disabled{\n      color: var(--color-text-disable)\n    }\n    &.Mui-selected, &.Mui-selected:hover {\n      background: inherit;\n      color: var(--color-text-button-select);\n      //color: var(--color-primary);\n    }\n    &:hover {\n      background: inherit;\n      color: var(--color-primary);\n    }\n\n    &.Mui-selected.Mui-focusVisible {\n      background: inherit;\n    }\n\n    .MuiButtonBase-root {\n      opacity: 1;\n      color: inherit;\n\n      &:hover {\n        // color: var(--primary);\n      }\n    }\n\n\n    .MuiTab-root {\n      &:hover {\n        //color: var(--primary);\n      }\n    }\n\n\n    //.MuiButtonBase-root {\n    //  opacity: 1;\n    //  color: inherit;\n    //}\n  }\n  \n  //svg {\n  //  width: var(--header-menu-icon-size);\n  //  height: var(--header-menu-icon-size);\n  //}\n\n  &&.layer-next {\n    display: flex;\n  }\n\n  .mobile & {\n    align-items: flex-start;\n  }\n\n}\n` as typeof MenuItem\nconst StyledLayer2Item = styled(Box)<BoxProps<any>>`\n  padding: 0;\n  margin: 0;\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n\n  &:hover {\n    //border-left-color: transparent;\n    background: var(--opacity);\n    h5 {\n      color: var(--color-primary);\n    }\n    svg {\n      fill: var(--color-primary);\n    }\n  }\n` as typeof MenuItem\n\nconst StyledHeaderMenuSub = styled(Menu)<MenuProps>`\n  && {\n    color: var(--color-text-third);\n\n    ul {\n      box-shadow: inset 0.5px var(--color-border);\n      background: var(--color-box-pop);\n      padding: 0;\n      //.layer-sub {\n      //  height: var(--header-menu-list-height)\n      //}\n    }\n  }\n` as typeof Menu\nconst StyledTabBtn = styled(MenuItem)<MenuItemProps<any>>`\n  &.Mui-selected, &.Mui-selected.Mui-focusVisible {\n    background: inherit;\n  }\n  &.Mui-disabled{\n    color: var(--color-text-disable)\n  }\n\n\n  && {\n    text-transform: capitalize;\n    display: flex;\n    height: 100%;\n    padding-right: 0;\n\n    svg {\n      transition: fill 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;\n    }\n\n    &:hover {\n      background-color: inherit;\n      color: var(--color-primary);\n      svg {\n        transform: rotate(180deg);\n      }\n    }\n` as typeof MenuItem\n\nconst checkEnable = ({ allowTrade, id }: { id: string; allowTrade?: any }): boolean => {\n  if (allowTrade?.order?.enable === false && orderDisableList.includes(id)) {\n    return true\n  } else if (allowTrade?.joinAmm?.enable === false && ammDisableList.includes(id)) {\n    return true\n  } else {\n    return false\n  }\n}\n\nexport const HeadMenuItem = React.memo(\n  React.forwardRef(\n    <I extends BasicHeaderItem>(\n      {\n        className,\n        layer,\n        selected,\n        allowTrade,\n        handleListKeyDown,\n        children,\n        status,\n        router,\n        label,\n      }: MenuItemLink<I>,\n      ref: ForwardedRef<any>,\n    ) => {\n      const history = useHistory()\n      const match = useRouteMatch('/trade/:item/:pair')\n      //@ts-ignore\n      const pair = match?.params?.pair ?? 'LRC-ETH'\n\n      return (\n        <StyledHeadMenuItem\n          selected={selected}\n          disabled={checkEnable({ allowTrade, id: label.id }) || status === 'disabled'}\n          className={clsx([`layer-${layer}`, className])}\n          ref={ref}\n          title={router?.description ?? undefined}\n          onClick={\n            handleListKeyDown\n              ? handleListKeyDown\n              : () => {\n                  router?.path?.startsWith('http')\n                    ? window.open(router?.path, '_blank')\n                    : history.push(router?.path.replace('${pair}', pair) ?? '')\n                }\n          }\n        >\n          {children}\n        </StyledHeadMenuItem>\n      )\n    },\n  ),\n) as <I extends BasicHeaderItem>(props: MenuItemLink<I>) => JSX.Element\n\nexport let Layer2Item: <I extends BasicHeaderItem>(\n  props: MenuItemProps<I> & WithTranslation,\n) => JSX.Element\nLayer2Item = React.memo(\n  <I extends BasicHeaderItem>({ t, label }: MenuItemProps<I> & WithTranslation) => {\n    const { defaultNetwork } = useSettings()\n    const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n    return (\n      <StyledLayer2Item className={'layer-sub'} key={label.id}>\n        <Box paddingLeft={1} paddingRight={2} display={'flex'} alignItems={'center'}>\n          {label.icon && <label.icon fontSize={'large'} color={'inherit'} />}\n        </Box>\n        <Box>\n          <Typography lineHeight={'22px'} component={'h5'} variant={'body1'} color={'text.primary'}>\n            {t(label.i18nKey, {\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n              l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n              ns: ['layout', 'landPage', 'common'],\n            })}\n          </Typography>\n          <Typography\n            lineHeight={'20px'}\n            component={'p'}\n            whiteSpace={'pre-line'}\n            variant={'body2'}\n            color={'inherit'}\n          >\n            {label?.description ? t(label.description) : ''}\n          </Typography>\n        </Box>\n      </StyledLayer2Item>\n    )\n  },\n) as <I extends BasicHeaderItem>(props: MenuItemProps<I> & WithTranslation) => JSX.Element\n\nexport const HeaderMenuSub = React.memo(\n  React.forwardRef(\n    <I extends BasicHeaderItem>(\n      {\n        t,\n        label,\n        className,\n        selected,\n        allowTrade,\n        status,\n        renderList,\n        layer = 0,\n        anchorOrigin = { vertical: 'bottom', horizontal: 'left' },\n      }: HeadMenuType<I> & WithTranslation,\n      ref: ForwardedRef<any>,\n    ) => {\n      const { defaultNetwork } = useSettings()\n      const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n      const popupState = usePopupState({\n        variant: 'popover',\n        popupId: `tradeHeaderSubMenu${label.id}`,\n      })\n      return (\n        <>\n          {checkEnable({ allowTrade, id: label.id }) || status === 'disabled' ? (\n            <StyledTabBtn disabled={true} selected={selected} className={className}>\n              <Typography component={'span'} variant={'body1'} paddingRight={1} color={'inherit'}>\n                {t(label.i18nKey, {\n                  loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                  l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                  ns: ['layout', 'landPage', 'common'],\n                })}\n              </Typography>\n            </StyledTabBtn>\n          ) : (\n            <>\n              <StyledTabBtn\n                {...bindHover(popupState)}\n                selected={selected}\n                className={className}\n                ref={ref}\n              >\n                <Typography component={'span'} variant={'body1'} paddingRight={1} color={'inherit'}>\n                  {t(label.i18nKey, {\n                    loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                    l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                    ns: ['layout', 'landPage', 'common'],\n                  })}\n                </Typography>\n                <ListItemAvatar\n                  color={'inherit'}\n                  style={{ display: 'inline-flex', alignItems: 'center' }}\n                >\n                  <DropDownIcon\n                    style={{\n                      transform: anchorOrigin.vertical === 'right' ? 'rotate(-90deg)' : '',\n                    }}\n                    fontSize={'medium'}\n                  />\n                </ListItemAvatar>\n              </StyledTabBtn>\n              <StyledHeaderMenuSub\n                key={`menu-${layer}-${label.id}`}\n                {...bindMenu(popupState)}\n                // getContentAnchorEl={null}\n                anchorOrigin={anchorOrigin}\n                transformOrigin={{ vertical: 'top', horizontal: 'left' }}\n                className={`MuiPaper-elevation2 menu-${layer}-${label.id}`}\n              >\n                {renderList &&\n                  renderList({\n                    handleListKeyDown: popupState.close,\n                  })}\n              </StyledHeaderMenuSub>\n            </>\n          )}\n        </>\n      )\n    },\n  ),\n) as <I extends BasicHeaderItem>(\n  props: HeadMenuType<I> & WithTranslation & RefAttributes<any>,\n) => JSX.Element\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/lists/HeadToolbar.tsx",
    "content": "import styled from '@emotion/styled'\nimport { MenuItem, MenuItemProps } from '@mui/material'\n//${({ theme }) => theme.unit * 2}\nexport const TabItemPlus = styled<any>(MenuItem)`\n  && {\n    &.Mui-focusVisible {\n      background-color: transparent;\n    }\n\n    margin: 0;\n    padding: 0 ${({ theme }) => 0.5 * theme.unit}px;\n\n    &:hover {\n      background-color: transparent;\n      border-left-color: transparent;\n    }\n\n    .MuiIconButton-root {\n      &.MuiIconButton-sizeMedium {\n        svg {\n          width: var(--header-menu-icon-size);\n          height: var(--header-menu-icon-size);\n          color: var(--color-text-secondary);\n        }\n      }\n      &.MuiIconButton-sizeLarge {\n        svg {\n          width: var(--header-menu-icon-large);\n          height: var(--header-menu-icon-large);\n          color: var(--color-text-secondary);\n        }\n      }\n\n      :hover {\n        svg {\n          color: var(--color-text-primary);\n        }\n\n        color: var(--color-text-primary);\n      }\n    }\n  }\n` as (props: MenuItemProps) => JSX.Element\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/lists/Interface.ts",
    "content": "import React from 'react'\nimport { LinkProps, ListItemProps, MenuItemProps as muMenuItemProps } from '@mui/material'\nimport {\n  Account,\n  CoinInfo,\n  CoinKey,\n  CoinMap,\n  GET_IPFS_STRING,\n  L2CollectionFilter,\n  MakeMeta,\n  TokenType,\n  WalletCoin,\n  WalletMap,\n} from '@loopring-web/common-resources'\nimport { ListProps } from 'react-virtualized'\nimport { List } from 'immutable'\n\nexport type MuiMenuItemProps = muMenuItemProps & {\n  withnocheckicon?: 'true' | 'false' | undefined\n}\n\nexport type BasicListItem = {\n  label: {\n    id: string\n    [key: string]: any\n  }\n  router?: { path: string; [key: string]: any }\n}\n\nexport type NotificationItem = {\n  handleClick?: (event: React.MouseEvent) => void\n  startIcon: {\n    className: string\n    iconItem: JSX.Element\n  }\n} & BasicListItem\n\nexport type BasicHeaderItem = {\n  status?: 'disabled' | 'hidden' | 'default'\n} & BasicListItem\n\nexport type HeadMenuType<I extends BasicHeaderItem> = {\n  children?: JSX.Element\n  className?: string\n  allowTrade?: object\n  renderList?: (props: { handleListKeyDown: ({ ...rest }) => any }) => any\n  onOpen?: boolean\n  selected?: boolean\n  setOnOpen?: () => {}\n  toggle?: boolean\n  style?: any\n  layer?: number\n  anchorOrigin?: { vertical: string; horizontal: string }\n} & I\nexport type MenuItemLink<I extends BasicHeaderItem> = HeadMenuType<I> & {\n  className?: string\n  allowTrade: any\n  handleListKeyDown?: () => any\n  layer: number\n} & LinkProps\n\nexport type MenuItemProps<I extends BasicHeaderItem> = HeadMenuType<I> & {\n  className?: string\n  handleListKeyDown?: () => any\n  layer: number\n} & muMenuItemProps\nexport type SubMenuListProps<I> = {\n  selected: string\n  subMenu: { [key: string]: List<I> }\n}\n\nexport interface CoinItemProps<C> extends ListItemProps {\n  tokenType?: TokenType\n  itemKey: CoinKey<C>\n  coinInfo: CoinInfo<C>\n  walletCoin: WalletCoin<C>\n  select: CoinKey<C> | null\n  handleListItemClick: (event: React.MouseEvent, selected: CoinKey<C>) => void\n  contentEle?: (props: any) => JSX.Element\n}\n\nexport type CoinMenuProps<R, I> = {\n  tokenType?: TokenType\n  listProps?: ListProps | any\n  selected: CoinKey<R> | null\n  nonZero: boolean\n  sorted: boolean\n  filterString: string\n  height?: string\n  allowScroll?: boolean //boolean\n  filterBy: (coinInfo: CoinInfo<R>, filterString: string) => boolean\n  coinMap: CoinMap<R, I extends CoinInfo<R> ? CoinInfo<R> : CoinInfo<R>>\n  walletMap: WalletMap<R, I extends CoinInfo<R> ? WalletCoin<R> : WalletCoin<R>> | {}\n  handleSelect?: (event: React.MouseEvent, selected: CoinKey<R>) => void\n  className?: string\n  filterWithBorrowed?: boolean\n}\n\nexport type CollectionListProps<Co> = {\n  onPageChange: (page: number, filter?: L2CollectionFilter | undefined) => void\n  collectionList: Co[]\n  size?: 'large' | 'medium' | 'small'\n  total: number\n  domain: string\n  makeMeta: MakeMeta\n  page: number\n  copyToastOpen: { isShow: boolean; type: string }\n  setCopyToastOpen: (props: { isShow: boolean; type: string }) => void\n  isLoading: boolean\n  etherscanBaseUrl: string\n  baseURL: string\n  getIPFSString: GET_IPFS_STRING\n  filter?: Partial<L2CollectionFilter>\n}\nexport type CollectionItemProps<Co> = {\n  item: Co\n  index: number\n  size?: 'large' | 'medium' | 'small'\n  setCopyToastOpen: (prosp: { isShow: boolean; type: string }) => void\n  setShowDeploy?: (item: Co) => void\n  setShowEdit?: (item: Co) => void\n  setShowManageLegacy?: (item: Co) => void\n  setShowTradeIsFrozen?: (item: Co, type: string) => void\n  setShowMintNFT?: (item: Co) => void\n  onItemClick?: (item: Co) => void\n  account?: Account\n  toggle: any\n  isSelectOnly?: boolean\n  noEdit?: boolean\n  selectCollection?: Co\n  domain: string\n  makeMeta: MakeMeta\n  baseURL: string\n  getIPFSString: GET_IPFS_STRING\n  etherscanBaseUrl: string\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/lists/List.stories.tsx",
    "content": "import { Meta, Story } from '@storybook/react'\nimport styled from '@emotion/styled'\nimport { MemoryRouter } from 'react-router-dom'\nimport { HeaderMenu, HeaderMenuSub, HeadMenuItem, Layer2Item } from './HeadMenuItem'\n\nimport { withTranslation } from 'react-i18next'\nimport {\n  Box,\n  Divider,\n  GlobalStyles,\n  Grid,\n  IconButton,\n  List as MuiList,\n  ListItemAvatar,\n  ListItemText,\n  MenuItem,\n  Tab,\n  Tabs,\n  Typography,\n} from '@mui/material'\nimport { coinMap, CoinType, layer2ItemData, walletMap } from '../../../static'\nimport { CoinMenu } from './CoinList'\nimport {\n  ACTIVITY,\n  AssetsIcon,\n  CoinInfo,\n  DownloadIcon,\n  globalCss,\n  NOTIFICATION_ITEM,\n} from '@loopring-web/common-resources'\nimport React from 'react'\nimport { SubMenuItem } from './SubMenuList'\nimport { TabItemPlus } from './HeadToolbar'\nimport { ListItemActivity, NotificationListItem } from './Notification'\nimport { useTheme } from '@emotion/react'\n\nconst BtnDownload = ({ t }: any) => (\n  <IconButton aria-label={t('downloadApp')}>\n    <DownloadIcon />\n  </IconButton>\n)\n\nconst Style = styled.div`\n  background: var(--color-global-bg);\n`\nconst SubMenu = withTranslation('layout')((rest: any) => {\n  return (\n    <>\n      <MuiList>\n        <SubMenuItem button selected={true} {...rest}>\n          <ListItemAvatar>\n            <AssetsIcon />\n          </ListItemAvatar>\n          <ListItemText\n            primary={\n              <Typography\n                sx={{ display: 'block' }}\n                component='span'\n                variant='body1'\n                color='text.button'\n              >\n                Assets\n              </Typography>\n            }\n          />\n        </SubMenuItem>\n        <SubMenuItem button {...rest}>\n          <ListItemAvatar>\n            <AssetsIcon />\n          </ListItemAvatar>\n          <ListItemText\n            primary={\n              <Typography\n                sx={{ display: 'block' }}\n                component='span'\n                variant='body1'\n                color='text.button'\n              >\n                Assets\n              </Typography>\n            }\n          />\n        </SubMenuItem>\n        <SubMenuItem button selected={true} alignItems={'flex-start'} {...rest}>\n          <ListItemAvatar>\n            <AssetsIcon />\n          </ListItemAvatar>\n          <ListItemText\n            primary={\n              <Typography\n                sx={{ display: 'block' }}\n                component='span'\n                variant='body1'\n                color='text.button'\n              >\n                AMM Records\n              </Typography>\n            }\n            secondary={\n              <Typography\n                sx={{ display: 'inline' }}\n                component='span'\n                variant='body2'\n                color='text.button'\n              >\n                (Joins & Exits )\n              </Typography>\n            }\n          />\n        </SubMenuItem>\n        <Divider />\n        <SubMenuItem button alignItems={'flex-start'} {...rest}>\n          <ListItemAvatar>\n            <AssetsIcon />\n          </ListItemAvatar>\n          <ListItemText\n            primary={\n              <Typography\n                sx={{ display: 'block' }}\n                component='span'\n                variant='body1'\n                color='text.button'\n              >\n                AMM Records\n              </Typography>\n            }\n            secondary={\n              <Typography\n                sx={{ display: 'inline' }}\n                component='span'\n                variant='body2'\n                color='text.button'\n              >\n                (Joins & Exits )\n              </Typography>\n            }\n          />\n        </SubMenuItem>\n      </MuiList>\n    </>\n  )\n})\n\nconst LoopringHeader = (wrap: any) => {\n  const layer2ItemDemo = layer2ItemData.map(({ label, router, child }) => (\n    <Layer2Item {...{ ...wrap, label, router, child }} key={label.id} />\n  ))\n  return (\n    <>\n      <Grid item>\n        <Box display='flex' alignContent='center' justifyContent={'flex-start'}>\n          <HeaderMenu className={'wrap'} maxWidth='lg'>\n            <HeadMenuItem\n              selected={true}\n              value={'markets'}\n              layer={0}\n              key={'markets-0'}\n              label={{ id: 'markets', i18nKey: 'markets', icon: '' }}\n              {...wrap}\n            >\n              <Typography component='div' key={'markets'}>\n                {wrap.t('markets')}\n              </Typography>\n            </HeadMenuItem>\n            <HeadMenuItem\n              value={'layer2'}\n              layer={0}\n              key={'layer-0'}\n              label={{ id: 'layer 2', i18nKey: 'layer', icon: '' }}\n              {...wrap}\n            >\n              <Typography component='div' key={'layer 2'}>\n                {wrap.t('layer 2')}\n              </Typography>\n            </HeadMenuItem>\n            <HeaderMenuSub\n              selected={true}\n              className={'layer-0'}\n              renderList={() => layer2ItemDemo}\n              layer={0}\n              key={'trade-0'}\n              label={{ id: 'trade', i18nKey: 'trade', icon: '' }}\n              {...wrap}\n            />\n            <Box\n              component={'ul'}\n              display='flex'\n              alignItems='center'\n              justifyContent={'flex-end'}\n              color={'textSecondary'}\n            >\n              <TabItemPlus key={'1'}>\n                <BtnDownload {...wrap} />\n              </TabItemPlus>\n            </Box>\n          </HeaderMenu>\n        </Box>\n      </Grid>\n      <Grid item>\n        <ul>{layer2ItemDemo}</ul>\n      </Grid>\n    </>\n  )\n}\nconst CoinMapMenu = (rest: any) => {\n  return (\n    <CoinMenu<CoinType, CoinInfo<CoinType>>\n      {...{\n        coinMap,\n        walletMap,\n        handleListItemClick: (_event: any) => {\n          // console.log('handleListItemClick', key)\n        },\n        ...rest,\n      }}\n    />\n  )\n}\nconst TabPanelBtn = () => {\n  const [value, setValue] = React.useState('one')\n\n  const handleChange = (_event: any, newValue: any) => {\n    setValue(newValue)\n  }\n  return (\n    <Tabs value={value} onChange={handleChange} aria-label='disabled tabs example'>\n      <Tab label='Active' value='one' />\n      <Tab label='Active' value='three' />\n    </Tabs>\n  )\n}\nconst Template: Story<any> = withTranslation()(({ t }: any) => {\n  const theme = useTheme()\n  const activity: ACTIVITY = {\n    type: '',\n    link: `2021/12/2021-12-23`,\n    title: '🎄 Loopring Holiday Trading Giveaway',\n    description1: 'Loopring Holiday Trading Giveaway,$600,000 in Prizes!\\n',\n    description2: 'Period: 2021-12-23 12AM to 2021-12-31 12AM (UAT)',\n    startDate: 1639526400000,\n    endDate: 1612915200000,\n    pairs: ['LRC-ETH'],\n    // config: [string, number, number, number, number];\n    // giftIcon?: string;\n  }\n  const notify: NOTIFICATION_ITEM = {\n    name: '',\n    type: '',\n    version: '',\n    title: '路印中继系统升级',\n    description1: 'Loopring Relayer System Upgrade Notice',\n    description2: 'Period: 2021-12-23 12AM to 2021-12-31 12AM (UAT)',\n    link: `2021/12/2021-12-23`,\n    startShow: 1639526400000,\n    endShow: 1612915200000,\n  }\n\n  return (\n    <Style>\n      <MemoryRouter initialEntries={['/']}>\n        <GlobalStyles styles={globalCss({ theme })} />\n        <h4>Tabs List </h4>\n        <Grid container spacing={2} alignContent={'center'} justifyContent={'flex-start'}>\n          <LoopringHeader t={t} />\n          <Grid item sm={2}>\n            <TabPanelBtn />\n          </Grid>\n        </Grid>\n        <h4>MenuList list for select</h4>\n        <Grid container spacing={2} alignContent={'center'} justifyContent={'flex-start'}>\n          <Grid item xs={3}>\n            <Grid item style={{ backgroundColor: 'var(--color-pop-bg)' }}>\n              <MenuItem value={1}>\n                <ListItemText>{t('test key')}</ListItemText>\n              </MenuItem>\n              <MenuItem value={1} selected={true}>\n                <ListItemText>{t('test key')}</ListItemText>\n              </MenuItem>\n            </Grid>\n          </Grid>\n          <Grid item xs={3}>\n            <Box width={375} style={{ backgroundColor: 'var(--color-pop-bg)' }}>\n              <ListItemActivity {...{ ...activity }} />\n              <ListItemActivity {...{ ...activity }} type={''} />\n              <ListItemActivity {...{ ...activity }} type={''} />\n              <ListItemActivity {...{ ...activity }} type={''} />\n              <NotificationListItem key={1} {...{ ...notify }} />\n              <NotificationListItem key={1} {...{ ...notify }} />\n            </Box>\n          </Grid>\n        </Grid>\n        <Box>\n          <Grid container spacing={2} alignContent={'center'} justifyContent={'space-around'}>\n            <Grid item xs={6}>\n              <h4>Left tab</h4>\n              <Box width={200} style={{ backgroundColor: 'var(--color-pop-bg)' }}>\n                <SubMenu />\n              </Box>\n            </Grid>\n            <Grid item xs={6} alignContent={'center'} justifyContent={'space-around'}>\n              <h4>CoinMap Menu</h4>\n              <Box height={200} display={'flex'} style={{ backgroundColor: 'var(--color-pop-bg)' }}>\n                <Box flex={1} minWidth={330} height={'100%'}>\n                  {<CoinMapMenu t={t} height={200} />}\n                </Box>\n              </Box>\n            </Grid>\n          </Grid>\n        </Box>\n      </MemoryRouter>\n    </Style>\n  )\n}) as Story<any>\n\n// @ts-ignore\nexport const ListItem = Template.bind({})\nListItem.args = {}\nexport default {\n  title: 'basic-lib/ListItem',\n  component: ListItem,\n  argTypes: {},\n} as Meta\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/lists/NFTList.tsx",
    "content": "import {\n  Box,\n  Checkbox,\n  Grid,\n  MenuItem,\n  Pagination,\n  Popover,\n  Radio,\n  Typography,\n} from '@mui/material'\nimport {\n  Account,\n  CollectionMeta,\n  EmptyValueTag,\n  GET_IPFS_STRING,\n  getShortAddr,\n  NFTLimit,\n  NFTWholeINFO,\n  sizeNFTConfig,\n  SoursURL,\n  ViewMoreIcon,\n} from '@loopring-web/common-resources'\nimport { AccountStep, CardStyleItem, EmptyDefault, NFTMedia } from '../../index'\nimport { useTranslation, WithTranslation, withTranslation } from 'react-i18next'\nimport { sanitize } from 'dompurify'\nimport { IconButtonStyle } from '../../../'\nimport { ToggleState, useSettings } from '../../../stores'\nimport { XOR } from '../../../types/lib'\nimport React from 'react'\nimport { bindMenu, bindTrigger, usePopupState } from 'material-ui-popup-state/hooks'\nimport styled from '@emotion/styled'\nimport { DEPLOYMENT_STATUS } from '@loopring-web/loopring-sdk'\n\nconst BoxBtnGroup = styled(Box)`\n  position: absolute;\n  right: ${({ theme }) => 2 * theme.unit}px;\n  top: ${({ theme }) => 2 * theme.unit}px;\n  z-index: 99;\n  //flex-direction: row-reverse;\n  &.mobile {\n  }\n` as typeof Box\n\nexport type NFTItemBasicProps = {\n  toggle?: ToggleState\n  setNFTMetaNotReady: (props: any) => void\n  setShowNFTDeploy: (props: any) => void\n  setShowNFTDetail: (props: any) => void\n  setShowNFTTransfer: (props: any) => void\n  setShowNFTWithdraw: (props: any) => void\n  setShowTradeIsFrozen: (props: any) => void\n  setShowRedPacket: (props: any) => void\n  setShowAccount: (props: any) => void\n}\n\nconst ActionMemo = React.memo(\n  <NFT extends NFTWholeINFO>({\n    account,\n    toggle,\n    setShowNFTDeploy,\n    // setShowNFTDetail,\n    setShowNFTTransfer,\n    setShowNFTWithdraw,\n    setShowAccount,\n    setShowTradeIsFrozen,\n    setNFTMetaNotReady,\n    setShowRedPacket,\n    item,\n  }: NFTItemBasicProps & { item: NFT; account?: Account }) => {\n    const { t } = useTranslation('common')\n\n    const popupState = usePopupState({\n      variant: 'popover',\n      popupId: 'collection-action',\n    })\n    const bindContent = bindMenu(popupState)\n    const bindAction = bindTrigger(popupState)\n    const [isKnowNFTNoMeta, setIsKnowNFTNoMeta] = React.useState<boolean>(\n      !!(item?.name !== '' && item.image && item.image !== ''),\n    )\n    React.useEffect(() => {\n      setIsKnowNFTNoMeta((_state) => {\n        return !!(item.name !== '' && item.image && item.image !== '')\n      })\n    }, [item.name, item.image])\n\n    return (\n      <Grid item marginTop={1}>\n        <IconButtonStyle size={'large'} edge={'end'} {...{ ...bindAction }}>\n          <ViewMoreIcon />\n        </IconButtonStyle>\n        <Popover\n          {...bindContent}\n          anchorReference='anchorEl'\n          anchorOrigin={{\n            vertical: 'bottom',\n            horizontal: 'right',\n          }}\n          transformOrigin={{\n            vertical: 'top',\n            horizontal: 'right',\n          }}\n        >\n          <Box borderRadius={'inherit'} minWidth={110}>\n            {!!(\n              item.isCounterFactualNFT &&\n              item.deploymentStatus === DEPLOYMENT_STATUS.NOT_DEPLOYED &&\n              item.minter?.toLowerCase() === account?.accAddress.toLowerCase()\n            ) && (\n              <MenuItem\n                onClick={() =>\n                  toggle?.deployNFT?.enable\n                    ? setShowNFTDeploy({\n                        ...item,\n                      })\n                    : setShowTradeIsFrozen({\n                        isShow: true,\n                        type: t('nftDeployDescription'),\n                      })\n                }\n              >\n                {t('labelNFTDeployContract')}\n              </MenuItem>\n            )}\n            <MenuItem\n              onClick={() => {\n                setShowNFTTransfer({ ...item })\n                setShowNFTWithdraw({ ...item })\n                isKnowNFTNoMeta\n                  ? setShowAccount({\n                      isShow: true,\n                      step: AccountStep.SendNFTGateway,\n                      info: { ...item },\n                    })\n                  : setNFTMetaNotReady({\n                      isShow: false,\n                      info: { method: 'Send' },\n                    })\n              }}\n            >\n              {t('labelNFTSendBtn')}\n            </MenuItem>\n            <MenuItem\n              onClick={() => {\n                isKnowNFTNoMeta\n                  ? setShowRedPacket({ ...item })\n                  : setNFTMetaNotReady({\n                      isShow: false,\n                      info: { method: 'Send' },\n                    })\n              }}\n            >\n              {t('labelNFTRedpacketBtn')}\n            </MenuItem>\n          </Box>\n        </Popover>\n      </Grid>\n    )\n  },\n)\n\nexport const NFTList = withTranslation('common')(\n  <NFT extends NFTWholeINFO, Co = CollectionMeta>({\n    baseURL,\n    nftList,\n    getIPFSString,\n    size = 'large',\n    total,\n    page,\n    isLoading,\n    onClick,\n    selected = undefined,\n    isSelectOnly = false,\n    isMultipleSelect = false,\n    onPageChange,\n    setNFTMetaNotReady,\n    isEdit,\n    t,\n    ...props\n  }: {\n    getIPFSString: GET_IPFS_STRING\n    baseURL: string\n    isManage?: boolean\n    nftList: Partial<NFT>[]\n    etherscanBaseUrl?: string\n    size?: 'large' | 'medium' | 'small'\n    onClick?: (item: Partial<NFT>) => Promise<void>\n    onNFTReload?: (item: Partial<NFT>, index: number) => Promise<void>\n    total: number\n    page: number\n    isLoading: boolean\n    selected?: Partial<NFT>[]\n    onPageChange?: (page: number) => void\n    setNFTMetaNotReady: (props: any) => void\n    account?: Account\n    toggle?: any\n    collectionMeta?: Co\n    // onSelected: (item: Partial<NFT>) => void;\n  } & ((NFTItemBasicProps & { isEdit: true }) | { isEdit?: false }) &\n    XOR<\n      { isSelectOnly: true; isMultipleSelect: true; selected: Partial<NFT>[] },\n      | { isSelectOnly: true; isMultipleSelect?: false; selected: NFT }\n      | {\n          isSelectOnly?: false\n          isMultipleSelect?: false\n        }\n    > &\n    WithTranslation) => {\n    const sizeConfig = sizeNFTConfig(size)\n    const { isMobile } = useSettings()\n    return (\n      <Box\n        flex={1}\n        // className={\"MuiPaper-elevation2\"}\n        marginTop={2}\n        marginBottom={2}\n        className={'nft-list-wrap'}\n        paddingX={isMobile ? 0 : 2}\n        display={'flex'}\n        flexDirection={'column'}\n      >\n        {isLoading ? (\n          <Box\n            flex={1}\n            display={'flex'}\n            alignItems={'center'}\n            justifyContent={'center'}\n            height={'90%'}\n          >\n            <img\n              className='loading-gif'\n              alt={'loading'}\n              width='36'\n              src={`${SoursURL}images/loading-line.gif`}\n            />\n          </Box>\n        ) : nftList && nftList.length ? (\n          <>\n            <Grid container spacing={2}>\n              {nftList.map((item, index) => (\n                <Grid\n                  xs={sizeConfig.wrap_xs}\n                  md={sizeConfig.wrap_md}\n                  lg={sizeConfig.wrap_lg}\n                  key={(item?.nftId ?? '') + index.toString()}\n                  item\n                  flex={'1 1 120%'}\n                >\n                  <CardStyleItem\n                    size={size}\n                    contentheight={sizeConfig.contentHeight}\n                    className={'nft-item'}\n                    style={{\n                      backgroundColor: 'var(--color-box-secondary)',\n                      border: 'none'\n                    }}\n                  >\n                    {isEdit && (\n                      <BoxBtnGroup className={'btn-group'}>\n                        <ActionMemo\n                          {...{ ...(props as any) }}\n                          item={item as any}\n                          setNFTMetaNotReady={setNFTMetaNotReady}\n                        />\n                      </BoxBtnGroup>\n                    )}\n                    <Box\n                      position={'absolute'}\n                      width={'100%'}\n                      height={'100%'}\n                      display={'flex'}\n                      flexDirection={'column'}\n                      justifyContent={'space-between'}\n                      onClick={(e) => {\n                        e.isPropagationStopped()\n                        onClick && onClick(item)\n                      }}\n                    >\n                      <NFTMedia\n                        item={item}\n                        index={index}\n                        shouldPlay={false}\n                        onNFTError={() => undefined}\n                        isOrigin={false}\n                        getIPFSString={getIPFSString}\n                        baseURL={baseURL}\n                      />\n\n                      {isSelectOnly &&\n                        (isMultipleSelect ? (\n                          <Checkbox\n                            size={'medium'}\n                            checked={\n                              !!selected?.find((_item) => {\n                                return item.nftData === _item.nftData\n                              })\n                            }\n                            // color={\"default\"}\n                            value={item.nftData}\n                            name='radio-nft'\n                            inputProps={{ 'aria-label': 'selectNFT' }}\n                          />\n                        ) : (\n                          <Radio\n                            size={'medium'}\n                            // @ts-ignore\n                            checked={selected?.nftData === item.nftData}\n                            value={item.nftData}\n                            name='radio-nft'\n                            inputProps={{ 'aria-label': 'selectNFT' }}\n                          />\n                        ))}\n                      <Box\n                        padding={2}\n                        className={'boxLabel'}\n                        height={sizeConfig.contentHeight}\n                        display={'flex'}\n                        flexDirection={'row'}\n                        alignItems={'center'}\n                        justifyContent={'space-between'}\n                      >\n                        <Box display={'flex'} flexDirection={'column'} width={'60%'}>\n                          <Typography\n                            color={'text.primary'}\n                            component={'h6'}\n                            whiteSpace={'pre'}\n                            overflow={'hidden'}\n                            textOverflow={'ellipsis'}\n                            dangerouslySetInnerHTML={{\n                              __html: sanitize(item?.name ?? EmptyValueTag) ?? '',\n                            }}\n                          />\n                          <Typography\n                            color={'textSecondary'}\n                            component={'p'}\n                            paddingTop={1}\n                            variant={size == 'small' ? 'body2' : 'body1'}\n                            minWidth={164}\n                            textOverflow={'ellipsis'}\n                            title={item?.nftId?.toString()}\n                          >\n                            {t('labelNFTTokenID')} #{' ' + getShortAddr(item?.nftId ?? '')}\n                          </Typography>\n                        </Box>\n\n                        <Box display={'flex'} flexDirection={'column'} alignItems={'flex-end'}>\n                          <Typography\n                            color={'textSecondary'}\n                            component={'span'}\n                            whiteSpace={'pre'}\n                            overflow={'hidden'}\n                            textOverflow={'ellipsis'}\n                          >\n                            {t(\n                              size == 'small' ? 'labelNFTAmountSimpleValue' : 'labelNFTAmountValue',\n                              { value: item.total },\n                            )}\n                          </Typography>\n                          <Typography\n                            color={'--color-text-primary'}\n                            component={'p'}\n                            paddingTop={1}\n                            whiteSpace={'pre-line'}\n                            minWidth={1}\n                            textOverflow={'ellipsis'}\n                            title={item?.nftId?.toString()}\n                          />\n                        </Box>\n                      </Box>\n                    </Box>\n                  </CardStyleItem>\n                </Grid>\n              ))}\n            </Grid>\n            {total > NFTLimit && onPageChange && (\n              <Box\n                display={'flex'}\n                alignItems={'center'}\n                justifyContent={'right'}\n                marginRight={3}\n                marginTop={1}\n                marginBottom={2}\n              >\n                <Pagination\n                  color={'primary'}\n                  count={parseInt(String(total / NFTLimit)) + (total % NFTLimit > 0 ? 1 : 0)}\n                  page={page}\n                  onChange={(_event, value) => {\n                    onPageChange(Number(value))\n                  }}\n                />\n              </Box>\n            )}\n          </>\n        ) : (\n          <Box flex={1} alignItems={'center'}>\n            <EmptyDefault\n              message={() => (\n                <Box flex={1} display={'flex'} alignItems={'center'} justifyContent={'center'}>\n                  No NFT\n                </Box>\n              )}\n            />\n          </Box>\n        )}\n      </Box>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/lists/Notification.tsx",
    "content": "import { Box, ListItem, ListItemAvatar, ListItemProps, ListItemText } from '@mui/material'\nimport styled from '@emotion/styled'\nimport {\n  Account,\n  ACTIVITY,\n  hexToRGB,\n  languageMap,\n  NOTIFICATION_ITEM,\n  NOTIFY_COLOR,\n  ThemeType,\n} from '@loopring-web/common-resources'\nimport { css, Theme } from '@emotion/react'\nimport { useHistory } from 'react-router-dom'\nimport { useSettings } from '../../../stores'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nconst cssBackground = ({\n  theme,\n  color,\n  banner,\n  bannerDark,\n  lng,\n}: { theme: Theme; lng: string } & Partial<NOTIFICATION_ITEM>) => {\n  let svg: string, _color: string\n  const fillColor = theme.colorBase.textDisable\n  const _banner: string | undefined =\n    theme.mode === ThemeType.dark && bannerDark?.length ? bannerDark : banner\n  const opacity = 0.2\n  if (banner) {\n    return css`\n      text-indent: -99999em;\n\n      &,\n      &:hover {\n        background: url('${_banner?.replace('{lng}', lng)}');\n        background-size: cover;\n      }\n\n      &:hover {\n        filter: blur(0.6px);\n        box-shadow: var(--shadow-hover);\n      }\n    `\n  }\n  switch (color) {\n    case NOTIFY_COLOR.primary:\n      _color = theme.colorBase.warning\n      svg =\n        encodeURI(`<svg width=\"88\" height=\"88\" viewBox=\"0 0 88 88\" fill=\"${fillColor}\" xmlns=\"http://www.w3.org/2000/svg\">\n<g opacity=\"${opacity}\">\n<path d=\"M15.4 28.6005L22 28.6005L22 37.4005L15.4 37.4005C11.7549 37.4005 8.8 40.3554 8.8 44.0005C8.8 47.6456 11.7549 50.6005 15.4 50.6005L44 50.6005L44 59.4005L15.4 59.4005C6.89482 59.4005 -7.13936e-07 52.5057 -5.98288e-07 44.0005C-4.8264e-07 35.4953 6.89482 28.6005 15.4 28.6005Z\" />\n<path d=\"M66 59.4005L72.6 59.4005C81.1052 59.4005 88 52.5057 88 44.0005C88 35.4953 81.1052 28.6005 72.6 28.6005L44 28.6005L44 37.4005L72.6 37.4005C76.2451 37.4005 79.2 40.3554 79.2 44.0005C79.2 47.6456 76.2451 50.6005 72.6 50.6005L66 50.6005L66 59.4005Z\" />\n<path d=\"M28.6 72.6L28.6 66L37.4 66L37.4 72.6C37.4 76.2451 40.3549 79.2 44 79.2C47.6451 79.2 50.6 76.2451 50.6 72.6L50.6 44L59.4 44L59.4 72.6C59.4 81.1052 52.5052 88 44 88C35.4948 88 28.6 81.1052 28.6 72.6Z\" />\n<path d=\"M59.4 22L59.4 15.4C59.4 6.89481 52.5052 3.42155e-07 44 5.98281e-07C35.4948 8.54407e-07 28.6 6.89482 28.6 15.4L28.6 44L37.4 44L37.4 15.4C37.4 11.7549 40.3549 8.8 44 8.8C47.6451 8.8 50.6 11.7549 50.6 15.4L50.6 22L59.4 22Z\" />\n</g>\n</svg>`)\n      break\n    case NOTIFY_COLOR.secondary:\n      _color = theme.colorBase.success\n      svg =\n        encodeURI(`<svg width=\"80\" height=\"88\" viewBox=\"0 0 80 88\" fill=\"${fillColor}\" xmlns=\"http://www.w3.org/2000/svg\">\n<path opacity=\"${opacity}\" d=\"M17.6 88L4.78625e-07 70.4L17.6 52.8L17.6 66L61.6 66L61.6 48.4L70.4 48.4L70.4 70.4C70.4 72.8301 68.43 74.8 66 74.8L17.6 74.8L17.6 88ZM17.6 39.6L8.8 39.6L8.8 17.6C8.8 15.1699 10.7699 13.2 13.2 13.2L61.6 13.2L61.6 -4.18797e-07L79.2 17.6L61.6 35.2L61.6 22L17.6 22L17.6 39.6Z\" />\n</svg>`)\n      break\n    case NOTIFY_COLOR.tertiary:\n      _color = theme.colorBase.error\n      svg =\n        encodeURI(`<svg width=\"87\" height=\"88\" viewBox=\"0 0 87 88\" fill=\"${fillColor}\" xmlns=\"http://www.w3.org/2000/svg\">\n<path opacity=\"${opacity}\"  fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M9.66409 88H77.3127C82.6501 88 86.9767 84.0602 86.9767 79.2V17.6C86.9767 12.7399 82.6501 8.8 77.3127 8.8H67.6486V0H57.9845V8.8H28.9923V0H19.3282V8.8H9.66409C4.32676 8.8 0 12.7399 0 17.6V79.2C0 84.0602 4.32676 88 9.66409 88ZM9.66409 79.2V35.2H77.3127V79.2H9.66409ZM9.66409 26.4V17.6H77.3127V26.4H9.66409ZM28.2823 53.1683L28.2823 53.1683L35.1158 46.9458L41.9493 53.1683L46.0493 56.9017L51.5163 51.9236L44.7886 45.7975L66.3845 44.6081L65.0784 64.2731L58.3498 58.1461L52.8828 63.1242L46.0493 69.3467L39.2158 63.1241L35.1158 59.3908L24.1822 69.3471L17.3487 63.1242L28.2823 53.1683Z\"/>\n</svg>`)\n      break\n    case NOTIFY_COLOR.default:\n      _color = theme.colorBase.primary\n      svg =\n        encodeURI(`<svg width=\"102\" height=\"88\" viewBox=\"0 0 102 88\" fill=\"${fillColor}\" xmlns=\"http://www.w3.org/2000/svg\">\n<path opacity=\"${opacity}\" d=\"M64.8421 2.86449e-05C68.0948 -0.000358379 71.2902 0.85563 74.1072 2.48192C76.9241 4.10822 79.2632 6.4475 80.8893 9.26454C82.5154 12.0816 83.3712 15.2771 83.3706 18.5298C83.37 21.7825 82.513 24.9777 80.8859 27.7941L101.895 27.7895V37.0526H92.6315V83.3684C92.6315 84.5968 92.1436 85.7749 91.275 86.6434C90.4064 87.512 89.2283 88 88 88H13.8947C12.6664 88 11.4883 87.512 10.6197 86.6434C9.75112 85.7749 9.26315 84.5968 9.26315 83.3684V37.0526H0V27.7895L21.0088 27.7941C18.7109 23.8151 17.9737 19.1241 18.9403 14.632C19.9069 10.1399 22.5083 6.16728 26.2394 3.48553C29.9706 0.803779 34.5651 -0.395741 39.131 0.119888C43.6969 0.635517 47.9083 2.8295 50.9473 6.27582C52.6823 4.2999 54.8196 2.71772 57.216 1.63534C59.6125 0.552957 62.2126 -0.00460494 64.8421 2.86449e-05ZM46.3158 37.0526H18.5263V78.7368H46.3158V37.0526ZM83.3684 37.0526H55.5789V78.7368H83.3684V37.0526ZM37.0526 9.26318C34.6489 9.25243 32.3351 10.1765 30.6001 11.8401C28.8651 13.5037 27.8447 15.7766 27.7545 18.1787C27.6643 20.5807 28.5114 22.9238 30.1168 24.7128C31.7222 26.5019 33.9601 27.5968 36.3579 27.7663L37.0526 27.7895H46.3158V18.5263C46.3159 16.3127 45.5232 14.1723 44.0815 12.4926C42.6397 10.8129 40.644 9.70507 38.456 9.36971L37.7427 9.28634L37.0526 9.26318ZM64.8421 9.26318C62.5051 9.26244 60.2542 10.1451 58.5406 11.7341C56.827 13.3232 55.7774 15.5012 55.6021 17.8316L55.5789 18.5263V27.7895H64.8421C67.1791 27.7902 69.43 26.9076 71.1436 25.3186C72.8572 23.7295 73.9068 21.5515 74.0821 19.2211L74.1052 18.5263C74.1052 16.0696 73.1293 13.7135 71.3921 11.9763C69.6549 10.2391 67.2988 9.26318 64.8421 9.26318Z\" />\n</svg>\n`)\n      break\n    default:\n      _color = theme.colorBase.box\n      svg = ''\n  }\n  return css`\n    &,\n    &:hover {\n      background-color: ${hexToRGB(_color, 0.25)};\n      background-image: url('data:image/svg+xml, ${svg}');\n      background-repeat: no-repeat;\n      background-position-x: 100%;\n    }\n    &:hover {\n      background-color: ${hexToRGB(_color, 0.45)};\n    }\n  `\n}\n\nconst NotificationListItemStyled = styled(ListItem)<\n  ListItemProps & Partial<ACTIVITY> & { lng: string; bannerDark: string }\n>`\n  cursor: pointer;\n  height: var(--notification-activited-heigth);\n  width: calc(var(--notification-activited-heigth) * 343 / 80);\n  overflow: hidden;\n  padding: ${({ theme }) => theme.unit}px ${({ theme }) => theme.unit}px;\n  background-color: var(--opacity);\n\n  &:not(:last-child) {\n    border-bottom: 1px solid var(--color-divide);\n    // margin-bottom: ${({ theme }) => theme.unit}px;\n  }\n\n  .MuiListItemText-root {\n    margin-top: 0;\n  }\n\n  .description {\n    text-overflow: ellipsis;\n    word-break: break-all;\n    white-space: nowrap;\n    width: 100%;\n  }\n\n  .MuiListItemAvatar-root {\n    width: 1em;\n    height: 100%;\n  }\n\n  ${(props) => cssBackground(props)}\n` as (props: ListItemProps & Partial<ACTIVITY> & { lng: string }) => JSX.Element\n\nexport const NotificationListItem = (\n  props: Partial<NOTIFICATION_ITEM> & {\n    closePop?: () => void\n    account?: Account\n    chainId: sdk.ChainId\n  },\n) => {\n  const history = useHistory()\n  const { language } = useSettings()\n  const lng = languageMap[language]\n  const {\n    title,\n    description1,\n    description2,\n    account,\n    banner,\n    bannerDark,\n    webRouter,\n    link,\n    linkParam,\n    chainId,\n    closePop,\n  } = props\n  return (\n    <NotificationListItemStyled\n      {...{ lng, banner, bannerDark }}\n      alignItems='flex-start'\n      onClick={() => {\n        const hasParamTag = /\\?/.test(link ?? '')\n        let params = ''\n        if (linkParam) {\n          params = linkParam.split('&').reduce((pre, ele) => {\n            const [key, value] = ele.split('=')\n            const [_, valueKey] = value.match(/\\{(.*)\\}/) ?? []\n            let _value: any = ''\n            switch (valueKey) {\n              case 'chainId':\n                _value = chainId\n                break\n              case 'l2address':\n                _value = account?.accAddress\n                break\n            }\n            return `${pre}&${key}=${_value}`\n          }, '')\n        }\n        if (webRouter) {\n          const [_, target, router] = webRouter.match(/\\[(.*)\\](.*)/i) ?? []\n          if (router && target === 'self') {\n            history.push(router)\n          } else {\n            window.open(\n              router\n                ? `https://loopring.io/#/${router}`\n                : `${link}${hasParamTag ? '' : '?'}` + `${params}`,\n              '_blank',\n            )\n            window.opener = null\n          }\n        } else if (link) {\n          window.open(`${link}${hasParamTag ? '' : '?'}` + `${params}`, '_blank')\n          window.opener = null\n        }\n        closePop && closePop()\n      }}\n      className={`notification`}\n    >\n      <ListItemAvatar />\n      <Box\n        className={'notification-content'}\n        component={'section'}\n        display={'flex'}\n        alignItems={'flex-start'}\n        flexDirection={'column'}\n        overflow={'hidden'}\n      >\n        <ListItemText\n          className={'title'}\n          primary={<span dangerouslySetInnerHTML={{ __html: title ?? '' }} />}\n          primaryTypographyProps={{\n            component: 'h4',\n            color: 'textPrimary',\n            title,\n          }}\n        />\n        <ListItemText\n          className='description description1'\n          primary={<span dangerouslySetInnerHTML={{ __html: description1 ?? '' }} />}\n          primaryTypographyProps={{\n            component: 'p',\n            variant: 'body1',\n            textOverflow: 'ellipsis',\n            title: description1,\n            color: 'textPrimary',\n            overflow: 'hidden',\n          }}\n        />\n        <ListItemText\n          className='description description2'\n          primary={<span dangerouslySetInnerHTML={{ __html: description2 ?? '' }} />}\n          primaryTypographyProps={{\n            component: 'p',\n            variant: 'body2',\n            textOverflow: 'ellipsis',\n            title: description2,\n            color: 'textSecondary',\n            overflow: 'hidden',\n          }}\n        />\n      </Box>\n    </NotificationListItemStyled>\n  )\n}\n\nconst ListItemActivityStyle = styled(NotificationListItemStyled)<\n  ListItemProps & Partial<ACTIVITY> & { lng: string }\n>`\n  &:not(:last-child) {\n    border-bottom: 0;\n    margin-bottom: ${({ theme }) => theme.unit}px;\n  }\n\n  padding: ${({ theme }) => theme.unit}px;\n  ${(props) => cssBackground(props)}\n  border-radius: ${({ theme }) => theme.unit}px;\n` as (props: ListItemProps & Partial<ACTIVITY> & { lng: string }) => JSX.Element\nexport const ListItemActivity = (props: ACTIVITY & { account?: Account; chainId: sdk.ChainId }) => {\n  const {\n    type,\n    title,\n    description1,\n    description2,\n    startShow,\n    link,\n    account,\n    banner,\n    color,\n    webRouter,\n    linkParam,\n    chainId,\n  } = props\n  const { language } = useSettings()\n  const lng = languageMap[language]\n  const history = useHistory()\n  if (Date.now() > startShow) {\n    return (\n      <ListItemActivityStyle\n        {...{ banner, color, lng }}\n        className={type}\n        // onClick={() =>\n        //   history.replace(``)\n        // }\n        onClick={() => {\n          const hasParamTag = /\\?/.test(link)\n          let params = ''\n          if (linkParam) {\n            params = linkParam.split('&').reduce((pre, ele) => {\n              const [key, value] = ele.split('=')\n              const [_, valueKey] = value.match(/\\{(.*)\\}/) ?? []\n              let _value: any = ''\n              switch (valueKey) {\n                case 'chainId':\n                  _value = chainId\n                  break\n                case 'l2address':\n                  _value = account?.accAddress\n                  break\n              }\n              return `${pre}&${key}=${_value}`\n            }, '')\n          }\n          if (webRouter) {\n            const [_, target, router] = webRouter.match(/\\[(.*)\\](.*)/i) ?? []\n            if (router && target === 'self') {\n              history.push(router)\n            } else {\n              window.open(\n                router\n                  ? `https://loopring.io/#/${router}`\n                  : `${link}${hasParamTag ? '' : '?'}` + `${params}`,\n                '_blank',\n              )\n              window.opener = null\n            }\n          } else if (link) {\n            window.open(`${link}${hasParamTag ? '' : '?'}` + `${params}`, '_blank')\n            window.opener = null\n          }\n        }}\n        type={props.type}\n      >\n        <ListItemAvatar />\n        <Box\n          className={'activity-content'}\n          component={'section'}\n          display={'flex'}\n          alignItems={'flex-start'}\n          flexDirection={'column'}\n          overflow={'hidden'}\n        >\n          <ListItemText\n            primary={title}\n            primaryTypographyProps={{\n              component: 'h6',\n              variant: 'subtitle1',\n              title: title,\n              color: 'textPrimary',\n              textOverflow: 'ellipsis',\n              overflow: 'hidden',\n            }}\n          />\n          <ListItemText\n            className='description description1'\n            primary={description1}\n            primaryTypographyProps={{\n              component: 'p',\n              title: description1,\n              variant: 'body1',\n              color: 'textPrimary',\n              textOverflow: 'ellipsis',\n              overflow: 'hidden',\n            }}\n          />\n          <ListItemText\n            className='description description2'\n            primary={description2}\n            primaryTypographyProps={{\n              component: 'p',\n              title: description2,\n              variant: 'body2',\n              color: 'textSecondary',\n              textOverflow: 'ellipsis',\n              overflow: 'hidden',\n            }}\n          />\n        </Box>\n      </ListItemActivityStyle>\n    )\n  } else {\n    return <></>\n  }\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/lists/SubMenuList.tsx",
    "content": "import styled from '@emotion/styled'\nimport {\n  Box,\n  Divider,\n  ListItem,\n  ListItemAvatar,\n  ListItemProps,\n  ListItemText,\n  Typography,\n} from '@mui/material'\nimport { withTranslation, WithTranslation } from 'react-i18next'\nimport { SubMenuListProps } from './Interface'\n\nimport { Link as RouterLink } from 'react-router-dom'\nimport { L1L2_NAME_DEFINED, MapChainId } from '@loopring-web/common-resources'\nimport { useSettings } from '../../../stores'\nimport React from 'react'\n\nexport const SubMenuItem = styled<any>(ListItem)`\n  border-left: 2px solid transparent;\n  border-right: 0px solid transparent;\n  padding: 0 0 0 ${({ theme }) => theme.unit * 3}px;\n  width: var(--sub-menuItem-width);\n  min-width: var(--sub-menuItem-width);\n  height: var(--sub-menuItem-height);\n  color: var(--color-text-secondary);\n  text-transform: capitalize;\n\n  .MuiListItemAvatar-root {\n    margin-left: ${({ theme }) => theme.unit * 0.75}px;\n    color: var(--color-text-third);\n\n    svg {\n      width: var(--header-menu-icon-size);\n      height: var(--header-menu-icon-size);\n    }\n  }\n\n  //&:hover,\n  //&.Mui-selected,\n  //&.Mui-selected.Mui-focusVisible,\n  //&.Mui-selected:hover {\n  //}\n\n  &:hover,\n  &.Mui-selected,\n  &.Mui-selected:hover,\n  &.Mui-selected.Mui-focusVisible,\n  &.Mui-selected.Mui-focusVisible:hover {\n    background-color: var(--color-box-hover);\n    border-color: var(--color-primary);\n    color: var(--color-button-select);\n\n    &&,\n    .MuiListItemAvatar-root {\n      color: var(--color-button-select);\n    }\n  }\n\n  //&.Mui-selected, &.Mui-selected.Mui-focusVisible {\n  //  background-color: var(--color-primary);\n  //  color: var(--color-text-button);\n  //  &:hover{\n  //    background-color: var(--color-primary);\n  //    color: var(--color-text-button);\n  //  }\n  //  //border-color:var(--primary);\n  //\n  //}\n` as (props: ListItemProps<any>) => JSX.Element\nexport const SubMenuList = withTranslation(['layout', 'common'], {\n  withRef: true,\n})(<I extends any>({ t, selected, subMenu }: SubMenuListProps<I> & WithTranslation<'layout'>) => {\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const filteredSubMenus = Object.keys(subMenu).filter(key => subMenu[key])\n  return (\n    <>\n      {filteredSubMenus.map((list: any, index) => {\n        const subList = subMenu[list]?.map((item: any) => {\n          return (\n            <SubMenuItem\n              button\n              selected={new RegExp(item.label.id, 'ig').test(selected)}\n              alignItems={item.label.description ? 'flex-start' : 'center'}\n              key={item.label.id}\n              {...{\n                component: RouterLink,\n                to: item.router ? item.router.path : '',\n                style: { textDecoration: 'none' },\n                // ...props\n              }}\n            >\n              <ListItemAvatar>\n                <item.icon />\n              </ListItemAvatar>\n              {item.label.description ? (\n                <ListItemText\n                  primary={\n                    <Typography sx={{ display: 'block' }} component='span' variant='body1'>\n                      {t(item.label.i18nKey, {\n                        loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                        l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                      })}\n                    </Typography>\n                  }\n                  secondary={\n                    <Typography sx={{ display: 'inline' }} component='span' variant='body2'>\n                      {t(item.label.description)}\n                    </Typography>\n                  }\n                />\n              ) : (\n                <ListItemText\n                  primary={\n                    <Typography\n                      sx={{ display: 'block' }}\n                      color={'text.button'}\n                      component='span'\n                      variant='body1'\n                    >\n                      {t(item.label.i18nKey, {\n                        loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                        l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                      })}\n                    </Typography>\n                  }\n                />\n              )}\n            </SubMenuItem>\n          )\n        })\n        return (\n          <>\n            {subList ? (\n              <div key={`group-${list}`}>\n                {subList}\n                {index + 1 !== filteredSubMenus.length ? (\n                  <Box marginX={3}>\n                    <Divider />\n                  </Box>\n                ) : (\n                  ''\n                )}\n              </div>\n            ) : (\n              <React.Fragment key={`group-any`}></React.Fragment>\n            )}\n          </>\n        )\n      })}\n    </>\n  )\n})\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/lists/index.tsx",
    "content": "import {\n  Card,\n  CardProps,\n  IconButton,\n  MenuItem as MuiMenuItem,\n  Select,\n  SelectProps,\n} from '@mui/material'\nimport styled from '@emotion/styled'\nimport { MuiMenuItemProps } from './Interface'\nimport React from 'react'\nimport { BorderTickIcon, SystemColor } from '@loopring-web/common-resources'\nimport { useTheme } from '@emotion/react'\n\nexport const MenuItem = styled(MuiMenuItem)<MuiMenuItemProps>`\n  ${({ withnocheckicon }) => {\n    return withnocheckicon === 'true'\n      ? `        \n        &.Mui-selected, &.Mui-selected.Mui-focusVisible {\n            color: var(--color-text-primary);\n            &:after{\n             display:none;\n            }\n        }\n     `\n      : ''\n  }}\n` as React.ComponentType<MuiMenuItemProps>\n\nexport const OutlineSelect = styled(Select)`\n  //padding: 0;\n  min-width: var(--btn-min-width);\n  //background-color: transparent;\n  color: var(--color-text-secondary);\n  .MuiInput-input {\n    padding: 0.3rem 0.3rem 0.3rem 0.8rem;\n  }\n  border: transparent;\n  .MuiSelect-select,\n  &.Mui-selected.Mui-focusVisible {\n    border: transparent;\n    &:focus {\n      background-color: transparent;\n    }\n\n    &:before {\n      content: '';\n      display: none;\n      pointer-events: none;\n    }\n  }\n\n  &:hover {\n    color: var(--color-text-primary);\n    border: transparent;\n  }\n\n  input {\n    padding-right: 0;\n  }\n\n  &:hover:not(.Mui-disabled):before,\n  &:after,\n  &:before {\n    margin: 0 auto;\n    width: 60%;\n    border: 0;\n    pointer-events: none;\n  }\n` as React.ComponentType<SelectProps>\n\nexport const OutlineSelectItem = styled(MenuItem)<any>`\n  &.MuiSelect-root {\n    padding: ${({ theme }) => `0 ${theme.unit * 1} $0 ${theme.unit * 1} `};\n    padding-right: ${({ theme }) => `${theme.unit * 2}`};\n    &:hover {\n      color: var(--color-text-primary);\n      border-left-color: transparent;\n    }\n  }\n\n  &.Mui-selected,\n  &.Mui-selected.Mui-focusVisible {\n    padding: ${({ theme }) => `${theme.unit * 1} ${theme.unit * 1} 0 ${theme.unit * 1} `};\n    padding-right: ${({ theme }) => `${theme.unit * 2}`};\n\n    &:after {\n      content: '';\n    }\n  }\n` as typeof MenuItem\nexport const IconButtonStyle = styled(IconButton)`\n  background-color: var(--color-box-nft-btn);\n  margin: 0 ${({ theme }) => theme.unit / 2}px;\n  ${({ theme }) => theme.border.defaultFrame({ c_key: 'transparent' })};\n}`\n\nexport const CardStyleItem = styled(Card)<\n  CardProps & {\n    contentheight?: number\n    size?: 'large' | 'medium' | 'small' | undefined\n  }\n>`\n  background: var(--color-global-bg);\n  width: 100%;\n  cursor: pointer;\n  height: auto;\n  display: flex;\n  cursor: pointer;\n  padding: 0 0 calc(100% + ${({ contentheight }) => `${contentheight ? contentheight : 80}px`});\n  position: relative;\n\n  .boxLabel {\n    overflow: hidden;\n  }\n\n  &.collection {\n    padding: 0 0 calc(140%);\n\n    .boxLabel {\n      ${({ size, theme }) =>\n        size === 'small'\n          ? `\n            padding: ${1 * theme.unit}px;\n            margin:0;\n          `\n          : `\n              .content{\n                width:60%;\n              }\n              padding: ${2 * theme.unit}px;\n              margin: ${2 * theme.unit}px;`}\n    }\n  }\n\n  &.nft-item {\n    .MuiRadio-root,\n    .MuiCheckbox-root {\n      &:hover {\n        background-color: rgba(65, 105, 255, 0.05);\n        color: var(--color-text-secondary);\n      }\n\n      &.Mui-checked {\n        box-shadow: inset 0px 0px 60px var(--color-global-bg-opacity);\n      }\n\n      position: absolute;\n      right: ${({ theme }) => theme.unit}px;\n      top: ${({ theme }) => theme.unit}px;\n      transform: scale(1.5);\n    }\n    background-color: var(--color-box-secondary);\n  }\n\n  &.btnCard {\n    background: var(--color-box);\n    .MuiCardContent-root {\n      padding: ${({ theme }) => theme.unit}px;\n    }\n    .MuiCardContent-root {\n      display: flex;\n      flex-direction: row;\n      align-items: center;\n      justify-content: center;\n    }\n\n    &.column .MuiCardContent-root {\n      flex-direction: column;\n    }\n\n    height: auto;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    padding: 0px;\n    box-shadow: none;\n    transition: none;\n    ${({ theme }) =>\n      theme.border.defaultFrame({\n        c_key: 'var(--color-border)',\n        d_R: 0.5,\n      })};\n\n    .Mui-selected &,\n    &.selected,\n    &:hover {\n      ${({ theme }) =>\n        theme.border.defaultFrame({\n          c_key: 'var(--color-border-select)',\n          d_R: 0.5,\n        })};\n      &:after {\n        display: none;\n      }\n    }\n  }\n\n  img {\n    object-fit: contain;\n  }\n  &.dualPrice {\n    padding: ${({ theme }) => theme.unit}px;\n    height: 54px;\n  }\n\n  &.MuiPaper-root.dualInvestCard {\n    padding: 0;\n    background: var(--color-box);\n    &.selected,\n    &:hover {\n      padding: inherit;\n    }\n    .MuiCardContent-root {\n      box-sizing: border-box;\n      padding: ${({ theme }) => 2 * theme.unit}px ${({ theme }) => 3 * theme.unit}px;\n      &:last-child {\n        padding: ${({ theme }) => 2 * theme.unit}px ${({ theme }) => 3 * theme.unit}px;\n      }\n    }\n  }\n` as (\n  props: CardProps & {\n    contentheight?: number\n    size?: 'large' | 'medium' | 'small' | undefined\n  },\n) => JSX.Element\n\nexport const TickCardStyleItem = (\n  props: CardProps & {\n    contentheight?: number\n    size?: 'large' | 'medium' | 'small' | undefined\n    selected?: boolean\n    width?: string\n  },\n) => {\n  const { children, selected, width, ...rest } = props\n  const theme = useTheme()\n  return (\n    <CardStyleItem\n      style={{\n        borderRadius: theme.unit,\n        background: 'transparent',\n        width,\n        justifyContent: 'left',\n        padding: '0',\n      }}\n      {...rest}\n    >\n      {selected && (\n        <BorderTickIcon\n          fontSize={'large'}\n          fill={SystemColor.blue}\n          sx={{\n            position: 'absolute',\n            top: '0px',\n            right: '0px',\n          }}\n        />\n      )}\n      {children}\n    </CardStyleItem>\n  )\n}\n\nexport * from './FileListItem'\nexport * from './HeadMenuItem'\nexport * from './Interface'\nexport * from './CoinList'\nexport * from './HeadToolbar'\nexport * from './SubMenuList'\nexport * from './Notification'\nexport * from './CollectionItem'\nexport * from './NFTList'\n// export * from './SimpleSelectItem'\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/loading/index.tsx",
    "content": "import { SoursURL } from '@loopring-web/common-resources'\nimport { Box, BoxProps } from '@mui/material'\n\nexport type LoadingProps = {\n  size?: number\n  withContainer?: boolean\n}\n\nexport const Loading = (props: BoxProps & LoadingProps) => {\n  const { size = 40, withContainer, ...rest } = props\n  const loading = (\n    <Box\n      component={'img'}\n      src={`${SoursURL}/images/loading-line.gif`}\n      width={size}\n      height={size}\n      {...rest}\n    />\n  )\n  return withContainer ? (\n    <Box\n      height={'100%'}\n      width={'100%'}\n      display={'flex'}\n      justifyContent={'center'}\n      alignItems={'center'}\n    >\n      {loading}\n    </Box>\n  ) : (\n    loading\n  )\n}"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/media/Interface.ts",
    "content": "import { NFTWholeINFO } from '@loopring-web/common-resources'\nimport { ReactEventHandler } from 'react'\n\nexport type NftImageProps = {\n  onError: ReactEventHandler<any>\n} & Partial<HTMLImageElement> &\n  Partial<NFTWholeINFO>\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/media/index.ts",
    "content": "export * from './nftImage'\nexport * from './Interface'\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/media/nftImage.tsx",
    "content": "import { NftImageProps } from './Interface'\nimport { css, Theme } from '@emotion/react'\nimport styled from '@emotion/styled'\nimport { Box } from '@mui/material'\nimport { SoursURL } from '@loopring-web/loopring-sdk'\n\nexport const NftImage = (props: NftImageProps & any) => {\n  return (\n    <img\n      // contentEditable={true}\n      referrerPolicy={'unsafe-url'}\n      // loading={\"lazy\"}\n      // crossOrigin={\"anonymous\"}\n      style={{ objectFit: 'contain' }}\n      onError={props.onError}\n      alt={props.name ?? 'NFT'}\n      width={props.width ?? '100%'}\n      height={props.height ?? '100%'}\n      src={props.src?.replace(/(javascript:)|(data:)/gi, '')}\n    />\n  )\n}\n\nexport const NftImageStyle = (props: { src: string | undefined; style?: React.CSSProperties }) => {\n  return (\n    <img\n      referrerPolicy={'unsafe-url'}\n      style={{ objectFit: 'contain', ...props.style }}\n      alt={'NFT'}\n      src={props.src?.replace(/(javascript:)|(data:)/gi, '')}\n    />\n  )\n}\n\nexport const cssBackground = (_props: { theme: Theme }) => {\n  // const fillColor = theme.colorBase.textDisable.replace(\"#\", \"%23\");\n  // const _svg =\n  //   encodeURI(`<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"${fillColor}\" xmlns=\"http://www.w3.org/2000/svg\">\n  //   <g opacity=\"0.09\">\n  //     <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M3.59635 7.47796L12.0594 2.80892L20.5971 7.47796V16.522L12.0642 21.1885L3.59635 16.3878V7.47796ZM12.0504 1L22.1799 6.53957V12V17.4604L12.0504 23L2 17.3022V6.53957L12.0504 1ZM10.3283 15.3263C10.3283 15.5885 10.1157 15.8011 9.85346 15.8011H9.08297C8.897 15.8011 8.72815 15.6925 8.65097 15.5233L6.27116 10.3061C6.26803 10.2992 6.26117 10.2948 6.25362 10.2948C6.24273 10.2948 6.234 10.3038 6.23434 10.3147C6.23951 10.4782 6.24469 10.645 6.24986 10.8148C6.25525 10.9848 6.26063 11.1581 6.26602 11.3349C6.27678 11.5048 6.28486 11.6782 6.29024 11.8549C6.29563 12.0248 6.30101 12.1982 6.3064 12.3749V15.3263C6.3064 15.5885 6.09381 15.8011 5.83158 15.8011H5.69095C5.42871 15.8011 5.21613 15.5885 5.21613 15.3263V8.99534C5.21613 8.7331 5.42871 8.52052 5.69095 8.52052H6.45413C6.6397 8.52052 6.80827 8.62863 6.88567 8.79729L9.25836 13.9674C9.26072 13.9726 9.26586 13.9759 9.27152 13.9759C9.2797 13.9759 9.28625 13.9691 9.28599 13.9609C9.28076 13.7961 9.27554 13.6346 9.27031 13.4762C9.26493 13.3063 9.25954 13.1397 9.25416 12.9766C9.25416 12.8066 9.25147 12.6401 9.24608 12.4769L9.22993 11.9671V8.99534C9.22993 8.7331 9.44252 8.52052 9.70475 8.52052H9.85346C10.1157 8.52052 10.3283 8.7331 10.3283 8.99534V15.3263ZM12.2987 15.3263C12.2987 15.5885 12.0861 15.8011 11.8238 15.8011H11.5701C11.3079 15.8011 11.0953 15.5885 11.0953 15.3263V8.99534C11.0953 8.7331 11.3079 8.52052 11.5701 8.52052H13.9236C14.1858 8.52052 14.3984 8.7331 14.3984 8.99534V9.31011C14.3984 9.57235 14.1858 9.78493 13.9236 9.78493H12.7735C12.5112 9.78493 12.2987 9.99752 12.2987 10.2598V11.1863C12.2987 11.4486 12.5112 11.6612 12.7735 11.6612H13.7782C14.0405 11.6612 14.2531 11.8737 14.2531 12.136V12.4508C14.2531 12.713 14.0405 12.9256 13.7782 12.9256H12.7735C12.5112 12.9256 12.2987 13.1382 12.2987 13.4004V15.3263ZM17.4192 15.8011C17.6814 15.8011 17.894 15.5885 17.894 15.3263V10.2801C17.894 10.0179 18.1066 9.80532 18.3688 9.80532H18.9859C19.2481 9.80532 19.4607 9.59274 19.4607 9.3305V8.99534C19.4607 8.7331 19.2481 8.52052 18.9859 8.52052H15.5826C15.3203 8.52052 15.1077 8.7331 15.1077 8.99534V9.3305C15.1077 9.59274 15.3203 9.80532 15.5826 9.80532H16.1997C16.4619 9.80532 16.6745 10.0179 16.6745 10.2801V12.8032V15.3263C16.6745 15.5885 16.8871 15.8011 17.1493 15.8011H17.4192Z\"/>\n  //   </g>\n  //   </svg>`);\n\n  // background-image: url(\"data:image/svg+xml, ${svg}\");\n\n  return css`\n    flex: 1;\n    background-color: var(--color-box);\n    background-repeat: no-repeat;\n    background-clip: content-box;\n    background-size: contain;\n    background-position: 50% 50%;\n    align-self: stretch;\n  `\n}\n\nexport const BoxNFT = styled(Box)`\n  background: no-repeat 50% 50%;\n  background-color: var(--opacity);\n  background-image: url(${SoursURL + 'svg/loopring.svg'});\n\n  &.redPacketNFT {\n    //height: var(--nft-large-avatar);\n    width: var(--nft-large-avatar);\n    padding-top: var(--nft-large-avatar);\n  }\n\n  img {\n    object-fit: contain;\n    overflow: hidden;\n    border-radius: ${({ theme }) => theme.unit}px;\n  }\n` as typeof Box\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/panel/IPFSSourceUpload.tsx",
    "content": "import {\n  Box,\n  ButtonProps,\n  FormControl,\n  FormHelperText,\n  IconButton,\n  Link,\n  Typography,\n  TypographyProps,\n} from '@mui/material'\nimport { DropzoneOptions, useDropzone } from 'react-dropzone'\nimport styled from '@emotion/styled'\nimport {\n  AudioIcon,\n  CloseIcon,\n  ErrorIcon,\n  GET_IPFS_STRING,\n  hexToRGB,\n  ImageIcon,\n  Media,\n  myLog,\n  PlayIcon,\n  SoursURL,\n  ThreeDIcon,\n  VideoIcon,\n} from '@loopring-web/common-resources'\nimport { useTranslation } from 'react-i18next'\nimport React from 'react'\nimport { useTheme } from '@emotion/react'\nimport { NftImage } from '../media'\n\nexport const TYPES = ['image/jpeg', 'image/jpg', 'image/gif', 'image/png']\nexport const MediaTYPES = [\n  'image/jpeg',\n  'image/jpg',\n  'image/gif',\n  'image/webp',\n  'image/png',\n  'audio/mp3',\n  'audio/mpeg',\n  'video/mp4',\n  'video/mpeg4',\n  'model',\n  'model/glb',\n  '',\n]\nexport const getMediaType = (type: string): Media | undefined => {\n  if (/audio/gi.test(type ?? '')) {\n    return Media.Audio\n  }\n  if (/video/gi.test(type ?? '')) {\n    return Media.Video\n  }\n  if (/(model)/gi.test(type ?? '')) {\n    return Media.Media3D\n  }\n  if (/image/gi.test(type ?? '')) {\n    return Media.Image\n  }\n  return\n}\n\nconst BoxStyle = styled(Box)`\n  ${({ theme }) =>\n    theme.border.defaultFrame({\n      c_key: theme.colorBase.divide,\n      d_W: 0,\n      d_R: 1,\n    })};\n  background: ${({ theme }) => theme.colorBase.globalBg};\n  width: 100%;\n  height: 100%;\n  border-style: dashed;\n  .MuiFormHelperText-sizeMedium {\n    font-size: ${({ theme }) => theme.fontDefault.body2};\n    color: var(--color-error);\n  }\n  opacity: 0.8;\n  &.focused,\n  &:hover {\n    opacity: 0.95;\n  }\n` as typeof Box\nconst LinkStyle = styled(Link)`\n  ${({ theme }) =>\n    theme.border.defaultFrame({\n      c_key: theme.colorBase.divide,\n      d_W: 0,\n      d_R: 1,\n    })};\n\n  .media-content {\n    height: 100%;\n    width: 100%;\n  }\n` as typeof Link\n\nexport type IpfsFile = {\n  file: File\n  isProcessing: boolean\n  error:\n    | {\n        [key: string]: any\n      }\n    | undefined\n  uniqueId: string\n  isUpdateIPFS: boolean\n  cid?: string\n  localSrc?: string\n  fullSrc?: string\n}\nexport const IPFS_INIT: Partial<IpfsFile> = {\n  file: undefined,\n  isProcessing: false,\n  error: undefined,\n  isUpdateIPFS: false,\n}\nexport const MediaSVGToggle = ({\n  url,\n  play,\n  getIPFSString,\n  baseURL,\n  mediaTyp,\n  setPlay,\n  isShow,\n  shouldPlay = false,\n}: {\n  url: string\n  play: boolean\n  getIPFSString: GET_IPFS_STRING\n  baseURL: string\n  mediaTyp: Media | undefined\n  setPlay: (props: boolean) => void\n  isShow: boolean\n  shouldPlay: boolean\n}) => {\n  const theme = useTheme()\n  const vidRef = React.useRef<HTMLVideoElement>(null)\n  const aidRef = React.useRef<HTMLAudioElement>(null)\n  const d3Ref = React.useRef<HTMLAudioElement>(null)\n  const typeSvg = React.useMemo(() => {\n    myLog('item.__mediaType__', mediaTyp)\n    switch (mediaTyp) {\n      case Media.Audio:\n        return (\n          <>\n            <Box\n              position={'absolute'}\n              right={theme.unit}\n              bottom={theme.unit}\n              borderRadius={'50%'}\n              sx={{ background: 'var(--color-box)' }}\n              padding={3 / 2}\n              display={'inline-flex'}\n              alignItems={'center'}\n              justifyContent={'center'}\n              zIndex={100}\n            >\n              <AudioIcon fontSize={'large'} htmlColor={'var(--text-third)'} />\n            </Box>\n            {url && shouldPlay && (\n              <Box\n                position={'absolute'}\n                left={'50%'}\n                bottom={theme.unit}\n                display={'flex'}\n                alignItems={'flex-end'}\n                justifyContent={'center'}\n                sx={{ transform: 'translateX(-50%)' }}\n                zIndex={100}\n                className={'media-content'}\n              >\n                <audio\n                  src={getIPFSString(url, baseURL)}\n                  ref={aidRef}\n                  controls\n                  loop\n                  className='w-full rounded-none h-12'\n                  controlsList='nodownload'\n                />\n              </Box>\n            )}\n          </>\n        )\n      case Media.Video:\n        return (\n          <>\n            <Box\n              position={'absolute'}\n              right={theme.unit}\n              bottom={theme.unit}\n              borderRadius={'50%'}\n              sx={{ background: 'var(--color-box)' }}\n              padding={3 / 2}\n              display={'inline-flex'}\n              alignItems={'center'}\n              justifyContent={'center'}\n              zIndex={100}\n            >\n              <VideoIcon fontSize={'large'} htmlColor={'var(--text-third)'} />\n            </Box>\n\n            {url && shouldPlay && (\n              <Box\n                position={'absolute'}\n                left={'50%'}\n                top={'50%'}\n                zIndex={100}\n                width={'100%'}\n                sx={{\n                  transform: 'translate(-50% , -50%)',\n                  cursor: 'pointer',\n                }}\n                onClick={(e) => {\n                  e.stopPropagation()\n                  setPlay(true)\n                }}\n                className={'media-content'}\n              >\n                <Box display={'flex'} alignItems={'center'} justifyContent={'center'} flex={1}>\n                  {play ? (\n                    <video\n                      ref={vidRef}\n                      src={getIPFSString(url, baseURL)}\n                      autoPlay\n                      muted\n                      controls\n                      loop\n                      controlsList='nodownload'\n                      style={{ width: '100%' }}\n                    />\n                  ) : (\n                    <PlayIconStyle\n                      sx={{\n                        minHeight: 72,\n                        minWidth: 72,\n                      }}\n                      // width={60}\n                      // height={60}\n                      // htmlColor={\"var(--color-text-disable)\"}\n                    />\n                  )}\n                </Box>\n              </Box>\n            )}\n          </>\n        )\n      case Media.Media3D:\n        return (\n          <>\n            <Box\n              position={'absolute'}\n              right={theme.unit}\n              bottom={theme.unit}\n              borderRadius={'50%'}\n              sx={{ background: 'var(--color-box)' }}\n              padding={3 / 2}\n              display={'inline-flex'}\n              alignItems={'center'}\n              justifyContent={'center'}\n              zIndex={100}\n            >\n              <ThreeDIcon fontSize={'large'} htmlColor={'var(--text-third)'} />\n            </Box>\n\n            {url && shouldPlay && (\n              <Box\n                position={'absolute'}\n                left={'50%'}\n                top={'50%'}\n                zIndex={100}\n                height={'100%'}\n                width={'100%'}\n                sx={{\n                  transform: 'translate(-50% , -50%)',\n                  cursor: 'pointer',\n                  background: 'var(--color-global-bg)',\n                }}\n                className={'media-content'}\n              >\n                <model-viewer\n                  style={{ height: '100%', width: '100%' }}\n                  src={getIPFSString(url, baseURL)}\n                  ref={d3Ref}\n                  autoPlay\n                  auto-rotate\n                  camera-controls\n                  controls\n                  loop\n                  ar-modes='webxr scene-viewer quick-look'\n                  loading='eager'\n                  touch-action='pan-y'\n                  shadow-intensity='1'\n                />\n              </Box>\n            )}\n          </>\n        )\n      case Media.Image:\n        return (\n          <>\n            {url && shouldPlay && (\n              <Box\n                position={'absolute'}\n                left={'50%'}\n                top={'50%'}\n                width={'100%'}\n                height={'100%'}\n                zIndex={100}\n                sx={{\n                  transform: 'translate(-50% , -50%)',\n                  cursor: 'pointer',\n                }}\n                onClick={(e) => {\n                  e.stopPropagation()\n                  // setPlay(true);\n                }}\n                className={'media-content'}\n              >\n                <NftImage\n                  alt={'image'}\n                  onError={(e: any) => {\n                    e?.target?.style?.setItem('opacity', '0.3')\n                    e?.target?.setItem('alt', 'image loaded failed')\n                  }}\n                  src={getIPFSString(url, baseURL)}\n                />\n              </Box>\n            )}\n          </>\n        )\n      default:\n        return <></>\n    }\n  }, [mediaTyp, url, play, theme.unit])\n  React.useEffect(() => {\n    if (isShow === false) {\n      if (vidRef.current) {\n        vidRef.current.pause()\n      }\n      if (aidRef.current) {\n        aidRef.current.pause()\n      }\n      if (d3Ref.current) {\n        d3Ref.current.pause()\n      }\n    }\n    return () => {\n      if (vidRef.current) {\n        vidRef.current.pause()\n      }\n      if (aidRef.current) {\n        aidRef.current.pause()\n      }\n      if (d3Ref.current) {\n        d3Ref.current.pause()\n      }\n    }\n  }, [isShow])\n  return <>{typeSvg}</>\n}\n\nexport const IPFSSourceUpload = ({\n  value,\n  onChange,\n  width,\n  height,\n  fullSize = false,\n  title = 'labelLoadDes',\n  buttonText = 'labelUpload',\n  typographyProps,\n  buttonProps,\n  disabled,\n  maxSize = 10485760,\n  onDelete,\n  types = TYPES,\n  getIPFSString,\n  messageTypes,\n  baseURL,\n  ...options\n}: Omit<DropzoneOptions, 'onDrop' | 'onDropAccepted'> & {\n  // sx?: SxProps<Theme>;\n  fullSize?: boolean\n  width?: number | string\n  messageTypes?: string[]\n  height?: number | string\n  typographyProps?: TypographyProps\n  buttonProps?: Omit<ButtonProps, 'onClick'>\n  title?: string\n  buttonText?: string\n  value: IpfsFile | undefined\n  types?: string[]\n  onDelete: () => void\n  onChange: (files: IpfsFile) => void\n  getIPFSString: GET_IPFS_STRING\n  baseURL: string\n}) => {\n  const { t } = useTranslation()\n  const onDropAccepted = React.useCallback(\n    (file: File[]) => {\n      onChange({\n        file: file[0],\n        isProcessing: true,\n        error: undefined,\n        localSrc: URL.createObjectURL(file[0]),\n        isUpdateIPFS: false,\n        uniqueId: Date.now().toString() + file[0].lastModified,\n      })\n    },\n    [onChange],\n  )\n  const { fileRejections, getRootProps, getInputProps, open, isFocused } = useDropzone({\n    ...options,\n    disabled,\n    maxSize,\n    accept: types?.length ? types : undefined,\n    onDropAccepted,\n    noClick: true,\n    noKeyboard: true,\n  })\n\n  const isFileTooLarge =\n    maxSize !== undefined && fileRejections.length > 0 && fileRejections[0].file.size > maxSize\n  const close = React.useMemo(\n    () => (\n      <IconButton\n        size={'medium'}\n        aria-label={t('labelClose')}\n        sx={{\n          position: 'absolute',\n          right: 8,\n          top: 8,\n          background: 'var(--color-global-bg)',\n          zIndex: 101,\n        }}\n        color={'inherit'}\n        onClick={onDelete}\n      >\n        <CloseIcon />\n      </IconButton>\n    ),\n    [onDelete, t],\n  )\n  return (\n    <Box display={'flex'} flexDirection={'column'}>\n      <Box\n        // display={\"flex\"}\n        overflow={'hidden'}\n        position={'relative'}\n        style={{\n          paddingBottom: height ?? '100%',\n          width: width ?? '100%',\n        }}\n      >\n        <ImageIcon\n          // fontSize={\"large\"}\n          style={{\n            position: 'absolute',\n            opacity: 1,\n            height: 48,\n            width: 48,\n            top: '50%',\n            left: '50%',\n            transform: 'translateY(-50%) translateX(-50%)',\n            zIndex: 60,\n          }}\n        />\n\n        <Box\n          style={{\n            position: 'absolute',\n            top: 0,\n            right: 0,\n            left: 0,\n            bottom: 0,\n            height: '100%',\n            width: '100%',\n            zIndex: 99,\n          }}\n        >\n          {value ? (\n            value.isProcessing ? (\n              <Box\n                flex={1}\n                display={'flex'}\n                alignItems={'center'}\n                height={'100%'}\n                justifyContent={'center'}\n              >\n                <img\n                  className='loading-gif'\n                  width='36'\n                  alt={'loading'}\n                  src={`${SoursURL}images/loading-line.gif`}\n                />\n                {close}\n              </Box>\n            ) : value.error ? (\n              <Box\n                flex={1}\n                display={'flex'}\n                alignItems={'center'}\n                height={'100%'}\n                justifyContent={'center'}\n              >\n                <ErrorIcon style={{ height: 60, width: 60 }} color={'error'} />\n                <Typography variant={'body1'} component={'span'}>\n                  {t(value.error.message)}\n                </Typography>\n                {close}\n              </Box>\n            ) : (\n              <>\n                <LinkStyle\n                  alignSelf={'stretch'}\n                  flex={1}\n                  display={'flex'}\n                  style={{ background: 'var(--color-box-secondary)' }}\n                  height={'100%'}\n                  target='_blank'\n                  rel='noopener noreferrer'\n                  href={value.fullSrc}\n                >\n                  {value && value.fullSrc ? (\n                    <MediaSVGToggle\n                      url={value.fullSrc ?? ''}\n                      play={true}\n                      shouldPlay={true}\n                      setPlay={() => {}}\n                      mediaTyp={getMediaType(value.file?.type)}\n                      getIPFSString={getIPFSString}\n                      baseURL={baseURL} //\n                      isShow={true}\n                    />\n                  ) : (\n                    <></>\n                  )}\n                </LinkStyle>\n\n                <Typography\n                  component={'span'}\n                  display={'flex'}\n                  justifyContent={'flex-start'}\n                  alignItems={'center'}\n                  flexDirection={'column'}\n                  sx={{\n                    pointerEvents: 'none',\n                    opacity: 1,\n                    position: 'absolute',\n                    right: '0',\n                    top: '0',\n                    color: 'var(--color-button-text)',\n                    zIndex: 100,\n                    height: '100%',\n                    width: '100%',\n                  }}\n                >\n                  <Typography color={'inherit'} component={'span'} marginTop={1}>\n                    Successfully Uploaded\n                  </Typography>\n                </Typography>\n                {close}\n              </>\n            )\n          ) : (\n            <BoxStyle\n              {...getRootProps()}\n              paddingTop={1}\n              display={'flex'}\n              className={isFocused ? 'focused' : ''}\n            >\n              <FormControl\n                sx={{\n                  display: 'flex',\n                  flexDirection: 'column',\n                  justifyContent: 'center',\n                  alignItems: 'center',\n                  cursor: 'pointer',\n                  width: '100%',\n                  height: '100%',\n                }}\n                onClick={open}\n                error={isFileTooLarge}\n              >\n                <input {...getInputProps()} />\n                <Typography\n                  variant={'h6'}\n                  textAlign='center'\n                  paddingX={2}\n                  paddingBottom={1}\n                  {...typographyProps}\n                >\n                  {t(title, {\n                    types: (messageTypes ?? types)\n                      ?.reduce((prev, ele) => {\n                        const split = ele?.split('/')\n                        if (split.length === 2) {\n                          return [...prev, split[1]]\n                        }\n                        return prev\n                      }, [] as string[])\n                      ?.join(', '),\n                    size: (maxSize / 1000000).toFixed(0),\n                  })}\n                </Typography>\n                <FormHelperText>{fileRejections[0]?.errors[0]?.message}</FormHelperText>\n              </FormControl>\n            </BoxStyle>\n          )}\n        </Box>\n      </Box>\n    </Box>\n  )\n}\n//${({ theme }) =>\n//  // padding: ${({ theme }) => 2 * theme.unit}px;\n//background: ${({ theme }) => hexToRGB(theme.colorBase.textPrimary, \".6\")};\n\nconst PlayIconStyle = styled(PlayIcon)`\n  color: ${({ theme }) => hexToRGB(theme.colorBase.box, '.9')};\n  border-radius: 100%;\n  box-shadow: inset 0px 0px 60px ${({ theme }) => hexToRGB(theme.colorBase.textPrimary, '.7')};\n  padding: ${({ theme }) => 1 * theme.unit}px;\n`\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/panel/Interface.ts",
    "content": "export type PanelContent<T extends string> = {\n  key: T\n  element: JSX.Element\n  toolBarItem: JSX.Element | undefined\n}\nexport type SwitchPanelProps<T extends string> = {\n  // swipedBy: T,\n  index: number\n  // defaultIndex: number,\n  panelList: Array<PanelContent<T>>\n  size?: string\n  className?: string\n  // onChangeIndex?: (index: number,data:any) => void,\n  // onTransitionEnd?: () => void,\n  _height?: number | string\n  _width?: number | string\n  scrollDisabled?: boolean\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/panel/Panel.stories.tsx",
    "content": "import React from 'react'\nimport styled from '@emotion/styled'\nimport { Meta, Story } from '@storybook/react'\nimport { withTranslation } from 'react-i18next'\nimport { SwitchPanel } from './SwitchPanel'\nimport { MemoryRouter } from 'react-router-dom'\nimport {\n  Box,\n  Button,\n  Grid,\n  IconButton,\n  ListItemAvatar,\n  ListItemText,\n  Typography,\n} from '@mui/material'\n\nimport { AssetsIcon, DropDownIcon } from '@loopring-web/common-resources'\nimport { SubMenuItem } from '../lists'\nimport { SubMenu, SwitchPanelProps } from '.'\n\nconst Style = styled.div`\n  background: var(--color-global-bg);\n\n  height: 100%;\n  flex: 1;\n`\n\nconst FistWrap = ({ onChangeIndex }: any) => {\n  // const _tradeValue = tradeValue as {buy:IBData<CoinType>|null,sell:IBData<CoinType>|null} ;\n  // let information = {value: \"hello, it's callback inject\"};\n  // setTimeout(() => {\n  //     information.value = 'I have update';\n  // }, 100);\n\n  const handleOnClick = React.useCallback(\n    (_event) => {\n      onChangeIndex(1, { data: 'any' })\n    },\n    [onChangeIndex],\n  )\n\n  return (\n    <Box\n      flex={1}\n      display={'flex'}\n      justifyContent={'center'}\n      alignItems={'center'}\n      height={'100%'}\n      width={'100%'}\n    >\n      <Button variant={'outlined'} size={'small'} color={'primary'} onClick={handleOnClick}>\n        go to next panel\n      </Button>\n    </Box>\n  )\n}\n\nconst SecondWrap = () => {\n  return <Box flex={1} height={'100%'} width={'100%'} style={{ background: 'cadetblue' }} />\n}\n\nconst WrapSwitchPanel = (rest: any) => {\n  const [index, setIndex] = React.useState<any>(0)\n  const onChangeIndex = React.useCallback((index: 0 | 1, value: any) => {\n    setIndex(index)\n    console.log(value)\n  }, [])\n  const onTransitionEnd = () => {\n    console.log('onTransitionEnd')\n  }\n  const props: SwitchPanelProps<'coinMap' | 'trade'> = {\n    index: index, // show default show\n    panelList: [\n      {\n        key: 'trade',\n        element: <FistWrap key={'first'} {...{ ...rest, onChangeIndex, onTransitionEnd }} />,\n        toolBarItem: (\n          <Grid container justifyContent={'flex-end'}>\n            {/*<Grid item >*/}\n            <IconButton\n              edge='end'\n              className={'switch'}\n              color='inherit'\n              aria-label='to Professional'\n            >\n              toolbar\n            </IconButton>\n            {/*</Grid>*/}\n            {/*<Grid item >*/}\n            {/*<IconButton edge=\"end\"*/}\n            {/*            className={'clock-loading'}*/}\n            {/*            color=\"inherit\"*/}\n            {/*            aria-label=\"3' price update\">*/}\n            {/*    <img src={loadingSvg} alt={'loading'}/>*/}\n            {/*</IconButton>*/}\n            {/*</Grid>*/}\n          </Grid>\n        ),\n      },\n      {\n        key: 'coinMap',\n        element: <SecondWrap key={'second'} {...{ ...rest, onChangeIndex }} />,\n        toolBarItem: (\n          <Grid container justifyContent={'flex-start'}>\n            <IconButton\n              edge='start'\n              sx={{ transform: 'rotate(90deg)', transformOrigin: '50%' }}\n              className={'switch'}\n              color='inherit'\n              onClick={() => onChangeIndex(0, { data: 0 })}\n              aria-label='to Professional'\n            >\n              <DropDownIcon />\n            </IconButton>\n          </Grid>\n        ),\n      },\n    ],\n  }\n  return <SwitchPanel {...{ ...rest, ...props }} />\n}\nconst Template: Story<any> = withTranslation()((props: any) => {\n  return (\n    <Style>\n      <MemoryRouter initialEntries={['/']}>\n        <Box>\n          <h4>Swith Panel</h4>\n          <Grid container spacing={2} alignContent={'center'} justifyContent={'space-around'}>\n            <Grid item sm={6}>\n              <WrapSwitchPanel {...props}> </WrapSwitchPanel>\n            </Grid>\n            <Grid>\n              <SubMenu>\n                <SubMenuItem button selected={true}>\n                  <ListItemAvatar>\n                    <AssetsIcon />\n                  </ListItemAvatar>\n                  <ListItemText\n                    primary={\n                      <Typography\n                        sx={{ display: 'block' }}\n                        component='span'\n                        variant='body1'\n                        color='text.primary'\n                      >\n                        Assets\n                      </Typography>\n                    }\n                  />\n                </SubMenuItem>\n                <SubMenuItem button>\n                  <ListItemAvatar>\n                    <AssetsIcon />\n                  </ListItemAvatar>\n                  <ListItemText\n                    primary={\n                      <Typography\n                        sx={{ display: 'block' }}\n                        component='span'\n                        variant='body1'\n                        color='text.primary'\n                      >\n                        Assets\n                      </Typography>\n                    }\n                  />\n                </SubMenuItem>\n              </SubMenu>\n            </Grid>\n          </Grid>\n        </Box>\n      </MemoryRouter>\n    </Style>\n  )\n}) as Story<any>\n\nexport default {\n  title: 'basic-lib/Panel',\n  component: SwitchPanel,\n  argTypes: {},\n} as Meta\nexport const PanelStory = Template.bind({})\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/panel/QRCodeUpload.tsx",
    "content": "import { Box } from '@mui/material'\nimport styled from '@emotion/styled'\nimport { QRCODE_REGION_ID } from '@loopring-web/common-resources'\nimport React from 'react'\n\nconst BoxStyle = styled(Box)`\n  ${({ theme }) =>\n    theme.border.defaultFrame({\n      c_key: theme.colorBase.divide,\n      d_W: 0,\n      d_R: 1,\n    })};\n  background: ${({ theme }) => theme.colorBase.globalBg};\n  width: 100%;\n  height: 100%;\n  border-style: dashed;\n  &#qrcodeRegionId {\n    border: 0 !important;\n  }\n  font-size: ${({ theme }) => theme.fontDefault.body1};\n  .html5-qrcode-element{\n    margin: ${({ theme }) => theme.unit}px auto;\n  }\n  #qrcodeRegionId__scan_region{\n    img{\n      //opacity: 0 !important;\n      width: 0;\n      height: 0;\n      \n    }\n    position: relative;\n    &:after{\n      background: var(--color-logo);\n      display: block;\n      mask: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzNzEuNjQzIDM3MS42NDMiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDM3MS42NDMgMzcxLjY0MyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHBhdGggZD0iTTEwNS4wODQgMzguMjcxaDE2My43Njh2MjBIMTA1LjA4NHoiLz48cGF0aCBkPSJNMzExLjU5NiAxOTAuMTg5Yy03LjQ0MS05LjM0Ny0xOC40MDMtMTYuMjA2LTMyLjc0My0yMC41MjJWMzBjMC0xNi41NDItMTMuNDU4LTMwLTMwLTMwSDEyNS4wODRjLTE2LjU0MiAwLTMwIDEzLjQ1OC0zMCAzMHYxMjAuMTQzaC04LjI5NmMtMTYuNTQyIDAtMzAgMTMuNDU4LTMwIDMwdjEuMzMzYTI5LjgwNCAyOS44MDQgMCAwIDAgNC42MDMgMTUuOTM5Yy03LjM0IDUuNDc0LTEyLjEwMyAxNC4yMjEtMTIuMTAzIDI0LjA2MXYxLjMzM2MwIDkuODQgNC43NjMgMTguNTg3IDEyLjEwMyAyNC4wNjJhMjkuODEgMjkuODEgMCAwIDAtNC42MDMgMTUuOTM4djEuMzMzYzAgMTYuNTQyIDEzLjQ1OCAzMCAzMCAzMGg4LjMyNGMuNDI3IDExLjYzMSA3LjUwMyAyMS41ODcgMTcuNTM0IDI2LjE3Ny45MzEgMTAuNTAzIDQuMDg0IDMwLjE4NyAxNC43NjggNDUuNTM3YTkuOTg4IDkuOTg4IDAgMCAwIDguMjE2IDQuMjg4IDkuOTU4IDkuOTU4IDAgMCAwIDUuNzA0LTEuNzkzYzQuNTMzLTMuMTU1IDUuNjUtOS4zODggMi40OTUtMTMuOTIxLTYuNzk4LTkuNzY3LTkuNjAyLTIyLjYwOC0xMC43Ni0zMS40aDgyLjY4NWMuMjcyLjQxNC41NDUuODE4LjgxNSAxLjIxIDMuMTQyIDQuNTQxIDkuMzcyIDUuNjc5IDEzLjkxMyAyLjUzNCA0LjU0Mi0zLjE0MiA1LjY3Ny05LjM3MSAyLjUzNS0xMy45MTMtMTEuOTE5LTE3LjIyOS04Ljc4Ny0zNS44ODQgOS41ODEtNTcuMDEyIDMuMDY3LTIuNjUyIDEyLjMwNy0xMS43MzIgMTEuMjE3LTI0LjAzMy0uODI4LTkuMzQzLTcuMTA5LTE3LjE5NC0xOC42NjktMjMuMzM3YTkuODU3IDkuODU3IDAgMCAwLTEuMDYxLS40ODZjLS40NjYtLjE4Mi0xMS40MDMtNC41NzktOS43NDEtMTUuNzA2IDEuMDA3LTYuNzM3IDE0Ljc2OC04LjI3MyAyMy43NjYtNy42NjYgMjMuMTU2IDEuNTY5IDM5LjY5OCA3LjgwMyA0Ny44MzYgMTguMDI2IDUuNzUyIDcuMjI1IDcuNjA3IDE2LjYyMyA1LjY3MyAyOC43MzMtLjQxMyAyLjU4NS0uODI0IDUuMjQxLTEuMjQ1IDcuOTU5LTUuNzU2IDM3LjE5NC0xMi45MTkgODMuNDgzLTQ5Ljg3IDExNC42NjEtNC4yMjEgMy41NjEtNC43NTYgOS44Ny0xLjE5NCAxNC4wOTJhOS45OCA5Ljk4IDAgMCAwIDcuNjQ4IDMuNTUxIDkuOTU1IDkuOTU1IDAgMCAwIDYuNDQ0LTIuMzU4YzQyLjY3Mi0zNi4wMDUgNTAuODAyLTg4LjUzMyA1Ni43MzctMTI2Ljg4OC40MTUtMi42ODQuODIxLTUuMzA5IDEuMjI5LTcuODYzIDIuODM0LTE3LjcyMS0uNDU1LTMyLjY0MS05Ljc3Mi00NC4zNDV6bS0yMzIuMzA4IDQyLjYyYy01LjUxNCAwLTEwLTQuNDg2LTEwLTEwdi0xLjMzM2MwLTUuNTE0IDQuNDg2LTEwIDEwLTEwaDE1djIxLjMzM2gtMTV6bS0yLjUtNTIuNjY2YzAtNS41MTQgNC40ODYtMTAgMTAtMTBoNy41djIxLjMzM2gtNy41Yy01LjUxNCAwLTEwLTQuNDg2LTEwLTEwdi0xLjMzM3ptMTcuNSA5My45OTloLTcuNWMtNS41MTQgMC0xMC00LjQ4Ni0xMC0xMHYtMS4zMzNjMC01LjUxNCA0LjQ4Ni0xMCAxMC0xMGg3LjV2MjEuMzMzem0zMC43OTYgMjguODg3Yy01LjUxNCAwLTEwLTQuNDg2LTEwLTEwdi04LjI3MWg5MS40NTdjLS44NTEgNi42NjgtLjQzNyAxMi43ODcuNzMxIDE4LjI3MWgtODIuMTg4em03OS40ODItMTEzLjY5OGMtMy4xMjQgMjAuOTA2IDEyLjQyNyAzMy4xODQgMjEuNjI1IDM3LjA0IDUuNDQxIDIuOTY4IDcuNTUxIDUuNjQ3IDcuNzAxIDcuMTg4LjIxIDIuMTUtMi41NTMgNS42ODQtNC40NzcgNy4yNTEtLjQ4Mi4zNzgtLjkyOS44LTEuMzM1IDEuMjYxLTYuOTg3IDcuOTM2LTExLjk4MiAxNS41Mi0xNS40MzIgMjIuNjg4aC05Ny41NjRWMzBjMC01LjUxNCA0LjQ4Ni0xMCAxMC0xMGgxMjMuNzY5YzUuNTE0IDAgMTAgNC40ODYgMTAgMTB2MTM1LjU3OWMtMy4wMzItLjM4MS02LjE1LS42OTQtOS4zODktLjkxNC0yNS4xNTktMS42OTQtNDIuMzcgNy43NDgtNDQuODk4IDI0LjY2NnoiLz48cGF0aCBkPSJNMTc5LjEyOSA4My4xNjdoLTI0LjA2YTUgNSAwIDAgMC01IDV2MjQuMDYxYTUgNSAwIDAgMCA1IDVoMjQuMDZhNSA1IDAgMCAwIDUtNVY4OC4xNjdhNSA1IDAgMCAwLTUtNXpNMTcyLjYyOSAxNDIuODZoLTEyLjU2VjEzMC44YTUgNSAwIDEgMC0xMCAwdjE3LjA2MWE1IDUgMCAwIDAgNSA1aDE3LjU2YTUgNSAwIDEgMCAwLTEwLjAwMXpNMjE2LjU2OCA4My4xNjdoLTI0LjA2YTUgNSAwIDAgMC01IDV2MjQuMDYxYTUgNSAwIDAgMCA1IDVoMjQuMDZhNSA1IDAgMCAwIDUtNVY4OC4xNjdhNSA1IDAgMCAwLTUtNXptLTUgMjQuMDYxaC0xNC4wNlY5My4xNjdoMTQuMDZ2MTQuMDYxek0yMTEuNjY5IDEyNS45MzZIMTk3LjQxYTUgNSAwIDAgMC01IDV2MTQuMjU3YTUgNSAwIDAgMCA1IDVoMTQuMjU5YTUgNSAwIDAgMCA1LTV2LTE0LjI1N2E1IDUgMCAwIDAtNS01eiIvPjwvc3ZnPg==\") space;\n      content: '.';\n      position: absolute;\n      top: 50%;\n      left: 50%;\n      margin-top: -32px;\n      margin-left: -32px;\n      opacity: .1;\n      //right: 0;\n      //bottom: 0;\n      height: 64px;\n      width: 64px;\n    }\n  }\n  #qrcodeRegionId__header_message{\n    color: ${({ theme }) => theme.colorBase.error} !important;\n    border: 0 !important;;\n  }\n\n  //button#html5-qrcode-button-camera-permission{\n  //  display: none;\n  //}\n  button.html5-qrcode-element {\n    position: relative;\n    color: var(--color-text-button);\n    height: 36px;\n    padding: 0 ${({ theme }) => theme.unit}px;\n    background-color: ${({ theme }) => theme.colorBase.primary};\n    ${({ theme }) =>\n      theme.border.defaultFrame({\n        c_key: theme.colorBase.divide,\n        d_W: 0,\n        d_R: 1 / 2,\n      })};\n    //box-shadow: \"initial\";\n    &:hover {\n      //boxShadow: \"initial\",\n     &:before {\n      background: ${({ theme }) => theme.colorBase.primaryHover};\n      content: '';\n      position: absolute;\n      top: 0;\n      left: 0;\n      right: 0;\n      bottom: 0;\n     },\n    }\n    &[disabled] {\n      backgroundColor:  ${({ theme }) => theme.colorBase.disable};\n      color:  ${({ theme }) => theme.colorBase.textDisable}\n    }\n  }\n\n  .MuiFormHelperText-sizeMedium {\n    font-size: ${({ theme }) => theme.fontDefault.body2};\n    color: var(--color-error);\n  }\n  opacity: 0.8;\n  &.focused,\n  &:hover {\n    opacity: 0.95;\n  }\n` as typeof Box\n// const LinkStyle = styled(Link)`\n//   ${({ theme }) =>\n//     theme.border.defaultFrame({\n//       c_key: theme.colorBase.divide,\n//       d_W: 0,\n//       d_R: 1,\n//     })};\n// ` as typeof Link;\n\nexport const QRCodeUpload = React.forwardRef(({}: any, _ref: React.ForwardedRef<any>) => {\n  return <BoxStyle ref={_ref} display={'flex'} flexDirection={'column'} id={QRCODE_REGION_ID} />\n})\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/panel/SubMenu.tsx",
    "content": "import styled from '@emotion/styled'\nimport { List, ListProps } from '@mui/material'\n\nexport const SubMenu = styled(List)<ListProps>`\n  width: 100%;\n  flex: 1;\n  padding: ${({ theme }) => (theme.unit / 2) * 5}px 0;\n  background-color: var(--color-box);\n  border-radius: ${({ theme }) => theme.unit}px;\n  &.color-light {\n    background-color: initial;\n  }\n` as typeof List\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/panel/SwitchPanel.tsx",
    "content": "import { WithTranslation } from 'react-i18next'\nimport SwipeableViews, { SwipeableViewsProps } from 'react-swipeable-views'\n\nimport React, { RefAttributes } from 'react'\nimport { useTheme } from '@emotion/react'\nimport styled from '@emotion/styled'\nimport { Box, Toolbar } from '@mui/material'\nimport { boxLiner, toolBarPanel } from '../../styled'\nimport { useSettings } from '../../../stores'\nimport { PanelContent, SwitchPanelProps } from './Interface'\n\nexport const SwipeableViewsStyled = styled(SwipeableViews)<\n  SwipeableViewsProps & {\n    _height?: number | string\n    _width?: number | string\n    ismobile?: 'true' | 'false'\n    scroolDisabled?: boolean\n  }\n>`\n  overflow: ${({ scroolDisabled }) => (scroolDisabled ? 'hidden' : 'auto')};\n  position: relative;\n  flex: 1;\n  ${({ _height, _width, ismobile }) => ` \n    height: ${\n      typeof _height === 'string'\n        ? _height\n        : typeof _height === 'number'\n        ? _height + 'px'\n        : `var(--swap-box-height)`\n    };     \n    ${\n      ismobile === 'true'\n        ? ``\n        : `   \n      width: ${\n        typeof _width === 'string'\n          ? _width\n          : typeof _width === 'number'\n          ? _width + 'px'\n          : `var(--swap-box-width)`\n      };`\n    }  \n         \n  `}\n  .createRedPacket & {\n    width: 100%;\n\n    ${({ ismobile }) => `${ismobile === 'true' ? 'width:380px;' : ''}`}\n    .container {\n      & > div {\n        width: 100%;\n        flex: 1;\n        display: flex;\n        justify-content: center;\n\n        .redPacket {\n          justify-content: center;\n        }\n\n        .menu-panel {\n          max-width: 760px;\n          padding: 0 ${({ theme, ismobile }) => (ismobile === 'true' ? 2 : 10) * theme.unit}px;\n          padding-top: ${({ theme }) => 2 * theme.unit}px;\n        }\n      }\n    }\n  }\n\n  ${({ theme }) => toolBarPanel({ theme })}\n  border-radius: ${({ theme }) => theme.unit}px;\n\n  .react-swipeable-view-container {\n    height: auto;\n\n    & > div {\n      .container {\n        flex: 1;\n\n        .coinInput-wrap,\n        .btnInput-wrap,\n        .MuiOutlinedInput-root {\n          background: var(--field-opacity);\n          border-color: var(--opacity);\n          :hover {\n            border-color: var(--color-border-hover);\n          }\n        }\n      }\n      display: flex;\n      flex-direction: column;\n      flex-wrap: wrap;\n      align-content: stretch;\n      align-items: stretch;\n    }\n  }\n  &.noToolBar {\n    .react-swipeable-view-container > div {\n      & > .MuiGrid-container {\n        padding-top: 0;\n        //margin-top: ;\n        margin-bottom: calc(var(--toolbar-row-padding) / 2);\n        padding: 0 calc(var(--toolbar-row-padding) / 2);\n      }\n      //margin-top: calc(var(--toolbar-row-padding) * -1);\n    }\n  }\n  &.hasLinerBg {\n    .react-swipeable-view-container > div {\n      ${({ theme }) => boxLiner({ theme })}\n    }\n  }\n  .MuiToolbar-root {\n    align-items: flex-end;\n    display: flex;\n    justify-content: space-between;\n    padding: 0 ${({ theme }) => (theme.unit * 5) / 2}px;\n  }\n  &.vaultSwap {\n    height: auto;\n    width: var(--swap-box-width);\n    .react-swipeable-view-container > div {\n      border: none;\n    }\n    .cover {\n      position: absolute;\n      top: 0;\n      left: 0;\n      right: 0;\n      bottom: 0;\n    }\n  }\n  &.vaultBorrow {\n    .menu-panel {\n      .MuiListItemText-root {\n        .MuiListItemText-secondary {\n          visibility: hidden;\n        }\n      }\n    }\n  }\n` as (\n  props: SwipeableViewsProps & {\n    _height?: number | string\n    _width?: number | string\n    ismobile?: boolean | undefined | string\n    scroolDisabled?: boolean\n  },\n) => JSX.Element\n\nfunction _SwitchPanel<T extends string>(\n  {\n    index,\n    className,\n    panelList,\n    // _height,\n    // _width,\n    size,\n    scrollDisabled,\n    ...rest\n  }: SwitchPanelProps<T> & WithTranslation,\n  _ref: React.ForwardedRef<any>,\n) {\n  //   {/*{...{ _height, _width }}*/}\n  const { isMobile } = useSettings()\n  const theme = useTheme()\n  const hasToolBar = panelList.find((item) => item.toolBarItem !== undefined)\n  const ref = React.useRef<any>(null)\n  React.useEffect(() => {\n    ref.current && ref.current.rootNode.scrollTo(0, 0)\n  }, [index])\n  return (\n    <SwipeableViewsStyled\n      className={\n        hasToolBar ? `${className ? className : ''}` : `noToolBar ${className ? className : ''}`\n      }\n      ref={ref}\n      axis={theme.direction === 'rtl' ? 'x-reverse' : 'x'}\n      index={index}\n      _height={rest._height}\n      _width={rest._width}\n      ismobile={isMobile ? 'true' : 'false'}\n      scroolDisabled={scrollDisabled}\n    >\n      {panelList.map((panel: PanelContent<T>, _index) => {\n        return (\n          <Box\n            display={'flex'}\n            className={'container'}\n            flexDirection={'column'}\n            key={panel.key}\n            justifyContent={'space-between'}\n            flexWrap={'nowrap'}\n            paddingTop={hasToolBar && 'var(--toolbar-row-padding)'}\n            paddingBottom={3}\n          >\n            {panel.toolBarItem ? (\n              <Toolbar className={size} variant={'dense'}>\n                {panel.toolBarItem}\n              </Toolbar>\n            ) : (\n              <></>\n            )}\n            <Box flex={1}>{panel.element}</Box>\n          </Box>\n        )\n      })}\n    </SwipeableViewsStyled>\n  )\n}\n\nexport const SwitchPanel = React.memo(React.forwardRef(_SwitchPanel)) as <T extends string>(\n  props: SwitchPanelProps<T> & WithTranslation & RefAttributes<any>,\n) => JSX.Element\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/panel/index.tsx",
    "content": "import styled from '@emotion/styled'\nimport { Box, Card, Typography, BoxProps, Container, IconButton } from '@mui/material'\nimport { FirstPlaceIcon, SecondPlaceIcon, ThirdPlaceIcon } from '@loopring-web/common-resources'\nimport React from 'react'\n\nexport * from './SwitchPanel'\nexport * from './SubMenu'\nexport * from './Interface'\nexport * from './IPFSSourceUpload'\n\nexport const CardNFTStyled = styled(Card)`\n  display: flex;\n  padding: 0;\n  flex-direction: column;\n  justify-content: space-between;\n  position: relative;\n  width: var(--nft-card);\n`\nexport const LoadingStyled = styled(IconButton)`\n  position: absolute;\n  z-index: 21;\n  top: 40%;\n  left: 50%;\n  transform: translate(-50%, -50%);\n`\n\nexport const ImageUploadWrapper = styled(Box)`\n  position: relative;\n  width: 100%;\n  background: var(--color-box-third);\n  border-radius: ${({ theme }) => theme.unit}px;\n\n  .MuiFormControlLabel-root {\n    align-items: flex-start;\n\n    .MuiFormControlLabel-label {\n      color: var(--color-text-secondary);\n    }\n  }\n` as typeof Box\n\nexport const PlaceComponent = ({ rank }: { rank: number }) => {\n  return (\n    <Typography component={'span'} display={'inline-flex'} position={'relative'}>\n      <>\n        {rank.toString() === '1' ? (\n          <FirstPlaceIcon sx={{ position: 'absolute', top: -6 }} fontSize={'large'} />\n        ) : rank.toString() === '2' ? (\n          <SecondPlaceIcon sx={{ position: 'absolute', top: -4, left: -1 }} fontSize={'large'} />\n        ) : rank.toString() === '3' ? (\n          <ThirdPlaceIcon sx={{ position: 'absolute', top: -4, left: -1 }} fontSize={'large'} />\n        ) : (\n          ''\n        )}\n        <Typography\n          display={'inline-flex'}\n          component={'span'}\n          zIndex={99}\n          width={24}\n          justifyContent={'center'}\n          alignItems={'center'}\n          color={Number(rank) <= 3 ? '#B07D00' : 'inherit'}\n        >\n          {rank}\n        </Typography>\n      </>\n    </Typography>\n  )\n}\n\nexport const MaxWidthContainer = ({\n  containerProps = {},\n  ...props\n}: {\n  children: React.ReactNode\n  background?: string\n  containerProps?: BoxProps\n} & BoxProps) => {\n  const { children, background, sx, ...otherProps } = props\n  const { sx: containerPropsSX, ..._containerProps } = containerProps\n  return (\n    <Box\n      display={'flex'}\n      justifyContent={'center'}\n      sx={{ background, ...(containerPropsSX ?? {}) }}\n      {..._containerProps}\n    >\n      <Container\n        sx={{\n          display: 'flex',\n          flex: 1,\n          flexDirection: 'column',\n        }}\n        // justifyContent={'stretch'}\n        maxWidth={'lg'}\n        className={'inner-box'}\n      >\n        <Box\n          flex={1}\n          display={'flex'}\n          flexDirection={'column'}\n          width={'100%'}\n          sx={{\n            ...sx,\n          }}\n          {...otherProps}\n        >\n          {children}\n        </Box>\n      </Container>\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/popover/Interface.ts",
    "content": "import { PopoverOrigin } from '@mui/material'\nimport { OneOf } from '@loopring-web/common-resources'\n\nimport * as React from 'react'\nimport { PopupState as InjectedProps } from 'material-ui-popup-state/core'\n\nexport enum PopoverType {\n  hover = 'hover',\n  click = 'click',\n}\n\ntype HorizonLeft = {\n  left: number\n}\n\ntype HorizonRight = {\n  right: number\n}\n\n// export type PopoverProps = MuiPopoverProps & {\n//     arrowHorizon?: OneOf<[HorizonLeft, HorizonRight]>;\n// }\nexport type PopoverWrapProps = {\n  type: keyof typeof PopoverType\n  // children: React.ReactNode;\n  className: string\n  popupId: string\n  children?: JSX.Element | undefined | React.ReactElement\n  popoverContent: React.ReactNode\n  // popoverStyle?: React.CSSProperties;\n  anchorOrigin?: PopoverOrigin\n  transformOrigin?: PopoverOrigin\n  // popoverTop?: number;\n  handleStateChange?: (state: boolean) => void\n  // variant: Variant\n  parentPopupState?: InjectedProps | null | undefined\n  disableAutoFocus?: boolean | null\n  arrowHorizon?: OneOf<[HorizonLeft, HorizonRight]>\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/popover/Popover.tsx",
    "content": "import React from 'react'\nimport styled from '@emotion/styled'\nimport { Popover as MuiPopover, PopoverOrigin, PopoverProps } from '@mui/material'\nimport { PopoverWrapProps } from './Interface'\nimport {\n  bindHover,\n  bindMenu,\n  bindPopover,\n  bindTrigger,\n  usePopupState,\n} from 'material-ui-popup-state/hooks'\nimport HoverMenu from 'material-ui-popup-state/HoverMenu'\nimport HoverPopover from 'material-ui-popup-state/HoverPopover'\n\nconst DEFAULT_ANCHOR_ORIGIN: PopoverOrigin = {\n  vertical: 'bottom',\n  horizontal: 'left',\n}\n\nconst DEFAULT_TRANSFORM_ORIGIN: PopoverOrigin = {\n  vertical: 'top',\n  horizontal: 'left',\n}\n// const POPOVER_TOP = 8;\n\nexport const Popover: React.FC<PopoverWrapProps> = ({\n  type,\n  popupId,\n  className,\n  children,\n  popoverContent,\n  anchorOrigin = DEFAULT_ANCHOR_ORIGIN,\n  transformOrigin = DEFAULT_TRANSFORM_ORIGIN,\n  handleStateChange,\n}) => {\n  const popupState = usePopupState({ variant: 'popover', popupId })\n  const { isOpen } = popupState\n\n  React.useEffect(() => {\n    if (handleStateChange) {\n      handleStateChange(isOpen)\n    }\n  }, [handleStateChange, isOpen])\n\n  const isHover = type === 'hover'\n  const bindAction = isHover ? bindHover(popupState) : bindTrigger(popupState)\n  const bindContent = isHover ? bindMenu(popupState) : bindPopover(popupState)\n  const CustomPopover = isHover ? HoverMenu : MuiPopover\n\n  const PopoverStyled = styled(CustomPopover)<PopoverProps>`\n    &.MuiModal-root {\n      z-index: 200;\n\n      &.arrow-center,\n      &.arrow-right,\n      &.arrow-left,\n      &.arrow-left,\n      &.arrow-top-center {\n        .MuiPopover-paper {\n          background: var(--color-pop-bg);\n          margin-top: ${({ theme }) => theme.unit * 1.5}px;\n          margin-left: ${({ theme }) => theme.unit}px;\n          overflow: visible;\n          box-shadow: var(--shadow);\n          border-radius: ${({ theme }) => theme.unit * 0.5}px;\n          &:before {\n            position: absolute;\n            top: ${({ theme }) => theme.unit * -2}px;\n            content: '';\n            display: block;\n            width: 0;\n            height: 0;\n            border: ${({ theme }) => theme.unit}px solid transparent;\n            border-bottom: ${({ theme }) => theme.unit}px solid var(--color-pop-bg);\n          }\n        }\n      }\n\n      &.arrow-center .MuiPopover-paper {\n        &:before {\n          left: 50%;\n          transform: translateX(-50%);\n        }\n      }\n\n      &.arrow-right .MuiPopover-paper {\n        &:before {\n          right: ${({ theme }) => theme.unit}px;\n        }\n      }\n\n      &.arrow-left .MuiPopover-paper {\n        &:before {\n          left: ${({ theme }) => theme.unit}px;\n        }\n      }\n      &.arrow-top-center .MuiPopover-paper {\n        &:before {\n          left: 50%;\n          transform: translateX(-50%) rotate(-180deg);\n          bottom: ${({ theme }) => theme.unit * -2}px;\n          top: initial;\n        }\n      }\n      &.arrow-none {\n        &:before {\n          display: none;\n        }\n        &:after {\n          display: none;\n        }\n      }\n    }\n  ` as (props: PopoverProps) => JSX.Element\n\n  const getRenderChild = React.useCallback(\n    (popoverChildren: React.ReactNode) => {\n      if (React.isValidElement(popoverChildren)) {\n        return React.Children.map(popoverChildren, (child) =>\n          React.cloneElement(child, {\n            ...bindAction,\n          }),\n        )\n      }\n      throw new Error('Invalid popover element!')\n    },\n    [bindAction],\n  )\n\n  return (\n    <>\n      {getRenderChild(children)}\n      <PopoverStyled\n        {...bindContent}\n        anchorReference='anchorEl'\n        anchorOrigin={anchorOrigin}\n        transformOrigin={transformOrigin}\n        className={className}\n      >\n        {popoverContent}\n      </PopoverStyled>\n    </>\n  )\n}\n\nexport const PopoverPure = styled(HoverPopover)<PopoverProps>`\n  &.MuiModal-root {\n    .MuiBackdrop-root {\n      background-color: inherit;\n    }\n    &.arrow-center,\n    &.arrow-right,\n    &.arrow-left,\n    &.arrow-left,\n    &.arrow-top-right,\n    &.arrow-top-center {\n      .MuiPopover-paper {\n        background: var(--color-pop-bg);\n        overflow: visible;\n        box-shadow: var(--shadow);\n        border-radius: ${({ theme }) => theme.unit * 0.5}px;\n        margin-top: ${({ theme }) => theme.unit}px;\n        &:before {\n          position: absolute;\n          top: ${({ theme }) => theme.unit * -2}px;\n          content: '';\n          display: block;\n          width: 0;\n          height: 0;\n          border: ${({ theme }) => theme.unit}px solid transparent;\n          border-bottom: ${({ theme }) => theme.unit}px solid var(--color-pop-bg);\n        }\n        &:after {\n          content: '';\n          position: absolute;\n          top: ${({ theme }) => -theme.unit}px;\n          width: 100%;\n          height: ${({ theme }) => theme.unit}px;\n          background-color: transparent;\n        }\n      }\n    }\n\n    &.arrow-center .MuiPopover-paper {\n      &:before {\n        left: 50%;\n        transform: translateX(-50%);\n      }\n    }\n\n    &.no-arrow .MuiPopover-paper {\n      &:before {\n        display: none !important;\n      }\n      &:after {\n        display: none !important;\n      }\n    }\n\n    &.arrow-right .MuiPopover-paper {\n      &:before {\n        right: ${({ theme }) => theme.unit}px;\n      }\n    }\n\n    &.arrow-left .MuiPopover-paper {\n      &:before {\n        left: ${({ theme }) => theme.unit}px;\n      }\n    }\n    &.arrow-top-center .MuiPopover-paper {\n      margin-top: ${({ theme }) => theme.unit * -0.5}px;\n      &:before {\n        left: 50%;\n        transform: translateX(-50%) rotate(-180deg);\n        bottom: ${({ theme }) => theme.unit * -2}px;\n        top: initial;\n      }\n      &:after {\n        content: '';\n        position: absolute;\n        top: 100%;\n        width: 100%;\n        height: ${({ theme }) => theme.unit}px;\n        background-color: transparent;\n      }\n    }\n    &.arrow-top-right .MuiPopover-paper {\n      margin-top: ${({ theme }) => theme.unit * -0.5}px;\n      &:before {\n        right: ${({ theme }) => theme.unit}px;\n        transform: translateX(-50%) rotate(-180deg);\n        bottom: ${({ theme }) => theme.unit * -2}px;\n        top: initial;\n      }\n      &:after {\n        content: '';\n        position: absolute;\n        top: 100%;\n        width: 100%;\n        height: ${({ theme }) => theme.unit}px;\n        background-color: transparent;\n      }\n    }\n  }\n` as (props: PopoverProps) => JSX.Element\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/popover/index.ts",
    "content": "export * from './Popover'\n\nexport * from './Interface'\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/popover/popover.stories.tsx",
    "content": "import styled from '@emotion/styled'\nimport { Meta, Story } from '@storybook/react'\nimport { Box, Button, Grid } from '@mui/material'\nimport { withTranslation } from 'react-i18next'\nimport { MemoryRouter } from 'react-router-dom'\nimport { Popover, PopoverPure, PopoverType } from './index'\nimport { bindPopper, bindTrigger, usePopupState } from 'material-ui-popup-state/hooks'\nimport { bindHover } from 'material-ui-popup-state/es'\n\nconst Style = styled.div`\n  flex: 1;\n  height: 100%;\n  flex: 1;\n`\n\nconst Template: Story<any> = withTranslation()((args: any) => {\n  const leftState = usePopupState({\n    variant: 'popover',\n    popupId: `popupId: 'left'`,\n  })\n  const rightState = usePopupState({\n    variant: 'popover',\n    popupId: `popupId: 'right'`,\n  })\n  const centerState = usePopupState({\n    variant: 'popover',\n    popupId: `popupId: 'center'`,\n  })\n  const topState = usePopupState({\n    variant: 'popover',\n    popupId: `popupId: 'top'`,\n  })\n\n  return (\n    <>\n      <Style>\n        <MemoryRouter initialEntries={['/']}>\n          <Popover {...args} />\n          <Grid container>\n            <Grid item xs={3}>\n              <Button {...bindHover(rightState)}> Hover Open Right </Button>\n              <PopoverPure\n                className={'arrow-right'}\n                {...bindPopper(rightState)}\n                anchorOrigin={{\n                  vertical: 'bottom',\n                  horizontal: 'right',\n                }}\n                transformOrigin={{\n                  vertical: 'top',\n                  horizontal: 'right',\n                }}\n              >\n                <Box height={100} width={120}>\n                  Content:XXXXXXX\n                </Box>\n              </PopoverPure>\n            </Grid>\n            <Grid item xs={3}>\n              <Button {...bindHover(leftState)}> click open </Button>\n              <PopoverPure\n                className={'arrow-left'}\n                {...bindPopper(leftState)}\n                anchorOrigin={{\n                  vertical: 'bottom',\n                  horizontal: 'left',\n                }}\n                transformOrigin={{\n                  vertical: 'top',\n                  horizontal: 'left',\n                }}\n              >\n                <Box height={100} width={120}>\n                  Content:XXXXXXX\n                </Box>\n              </PopoverPure>\n            </Grid>\n            <Grid item xs={3}>\n              <Button {...bindTrigger(centerState)}> click open </Button>\n              <PopoverPure\n                className={'arrow-center'}\n                {...bindPopper(centerState)}\n                anchorOrigin={{\n                  vertical: 'bottom',\n                  horizontal: 'center',\n                }}\n                transformOrigin={{\n                  vertical: 'top',\n                  horizontal: 'center',\n                }}\n              >\n                <Box height={100} width={200}>\n                  Content:XXXXXXX\n                </Box>\n              </PopoverPure>\n            </Grid>\n            <Grid item xs={3} marginTop={8}>\n              <Button {...bindTrigger(topState)}> click open </Button>\n              <PopoverPure\n                className={'arrow-top-center'}\n                {...bindPopper(topState)}\n                anchorOrigin={{\n                  vertical: 'top',\n                  horizontal: 'center',\n                }}\n                transformOrigin={{\n                  vertical: 'top',\n                  horizontal: 'center',\n                }}\n              >\n                <Box height={100} width={200}>\n                  Content:XXXXXXX\n                </Box>\n              </PopoverPure>\n            </Grid>\n          </Grid>\n        </MemoryRouter>\n      </Style>\n    </>\n  )\n}) as Story<any>\n\nconst children = (\n  <Button style={{ margin: 12 }} variant='outlined'>\n    btnContent\n  </Button>\n)\n\nconst popoverContent =\n  'Because the pool price changes dynamically, the price you see when placing an order may be inconsistent with the final transaction price.'\n\n// @ts-ignore\nexport const PopoverStory = Template.bind({})\nPopoverStory.args = {\n  type: PopoverType.click,\n  popupId: 'testPopup',\n  children,\n  popoverContent,\n  popoverStyle: {\n    width: '180px',\n    lineHeight: '16px',\n    fontSize: '12px',\n    margin: '12px',\n  },\n}\n\nexport default {\n  title: 'basic-lib/Popover',\n  component: Popover,\n  argTypes: {},\n} as Meta\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/resource/hook/useImage.ts",
    "content": "import React from 'react'\n\nexport const useImage = (src: string) => {\n  const [hasLoaded, setHasLoaded] = React.useState(false)\n  const [hasError, setHasError] = React.useState(false)\n  const [hasStartedInitialFetch, setHasStartedInitialFetch] = React.useState(false)\n\n  React.useEffect(() => {\n    if (src.trim() !== '') {\n      setHasStartedInitialFetch(true)\n      setHasLoaded(false)\n      setHasError(false)\n\n      // Here's where the magic happens.\n      const image = new Image()\n      image.src = src\n      const handleError = () => {\n        setHasError(true)\n      }\n\n      const handleLoad = () => {\n        setHasLoaded(true)\n        setHasError(false)\n      }\n\n      image.addEventListener('error', handleError)\n      image.addEventListener('load', handleLoad)\n\n      return () => {\n        image.removeEventListener('error', handleError)\n        image.removeEventListener('load', handleLoad)\n      }\n    } else {\n      setHasError(false)\n      setHasLoaded(true)\n      setHasStartedInitialFetch(false)\n    }\n  }, [src])\n\n  return { hasLoaded, hasError, hasStartedInitialFetch }\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/resource/index.tsx",
    "content": "export * from './hook/useImage'\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/table-pagination/TablePagination.tsx",
    "content": "import React from 'react'\nimport { Box, Pagination } from '@mui/material'\nimport styled from '@emotion/styled'\nimport { RowConfig } from '@loopring-web/common-resources'\n\n// const StyledPaginationWrapper = styled(Box)`\n//     height: 44px;\n//     position: relative;\n// `\n\nconst StyledPagination = styled(Pagination)`\n  display: flex;\n  justify-content: center;\n  align-items: center;\n`\n\nexport type PaginationProps = {\n  page: number\n  pageSize: number\n  total: number\n  height?: number\n  alignItems?: string\n  justifyContent?: string\n  onPageChange: (page: number) => void\n  size?: 'small' | 'medium' | 'large' | undefined\n}\n\nexport const TablePagination = ({\n  onPageChange,\n  page,\n  height = RowConfig.rowHeight,\n  justifyContent = 'center',\n  alignItems = 'center',\n  pageSize,\n  total,\n  size,\n}: PaginationProps) => {\n  const getCount = React.useCallback(() => {\n    if (!total) return 0\n    return Math.ceil(total / pageSize)\n    // total % pageSize > 0\n    //       ? parseInt(String(total / pageSize)) + 1\n    //       : parseInt(String(total / pageSize))\n  }, [pageSize, total])\n\n  const handleChange = React.useCallback(\n    (_e: any, value: number) => {\n      onPageChange(value)\n    },\n    [onPageChange],\n  )\n\n  return (\n    <Box display={'flex'} alignItems={alignItems} height={height} justifyContent={justifyContent}>\n      <StyledPagination\n        color={'primary'}\n        count={getCount()}\n        page={page}\n        onChange={handleChange}\n        size={size}\n      />\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/table-pagination/index.ts",
    "content": "export * from './TablePagination'\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/tables/Interface.ts",
    "content": "import { WithT } from 'i18next'\nimport {\n  CalculatedColumn,\n  Column as RdgColumns,\n  DataGridProps as RdgDataGridProps,\n  SortDirection,\n} from 'react-data-grid'\n// import { XOR } from '../../../types/lib';\n\nexport type DataGridProps<R, SR> = Omit<RdgDataGridProps<R, SR>, 'rows' | 'columns'> &\n  TableProps<R, unknown>\nexport type Column<R, SR> = RdgColumns<R, SR> & {\n  [key: string]: any\n}\n\nexport type TableProps<R, SR> = {\n  rawData: any\n  columnMode: Column<R, unknown>[]\n  generateRows: (rawData: any, ...rest: any[]) => Array<R>\n  generateColumns: (\n    props: {\n      columnsRaw: Column<R, unknown>[]\n      [key: string]: any\n    } & WithT,\n  ) => Array<RdgColumns<R>>\n  // rows: any;\n  columns?: readonly Column<R, unknown>[]\n  setRows?: () => any\n  rowClassFn?: (row: R, ...rest: TableProps<R, SR>[]) => string\n  frozeSort?: boolean\n  rowHeight?: number // px\n  actionColumns?: Array<string>\n  sortInitDirection?: 'DESC' | 'ASC' | undefined\n  sortDefaultKey?: string\n  sortMethod?: (rows: R[], sortColumn: string, sortDirection: 'DESC' | 'ASC' | undefined) => R[]\n  handleSort?: (columnKey: string, direction: SortDirection) => boolean\n  EmptyRowsRenderer?: React.ReactNode\n  onRowClick?: (rowIdx: number, row: R, column: CalculatedColumn<R, SR>) => void\n}\n//& XOR<{ rows: R[] }, {generateRows: (rawData: any, ...rest: any[]) => Array<R>}>;\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/tables/Table.tsx",
    "content": "import type { Column as RdgColumn } from 'react-data-grid'\nimport DataGrid, { SortColumn } from 'react-data-grid'\nimport styled from '@emotion/styled'\nimport { Trans, WithTranslation } from 'react-i18next'\n\nimport { WithT } from 'i18next'\nimport React, { ForwardedRef } from 'react'\nimport { Column, DataGridProps, SortableHeaderCell, SortableHeaderCellProps, TableProps } from './'\nimport { EmptyDefault } from '../empty'\nimport { RowConfig, SoursURL } from '@loopring-web/common-resources'\nimport { Box } from '@mui/material'\nimport { css } from '@emotion/react'\nimport { LoadingStyled } from '../panel'\n\ninterface TableWrapperStyledProps {\n  showloading: 'true' | 'false'\n}\n\nconst TableWrapperStyled = styled(Box)<TableWrapperStyledProps>`\n  display: flex;\n  position: relative;\n  flex: 1;\n` as any\nconst hr = ({ theme }: any) => css`\n  border-radius: ${theme.unit / 2}px;\n  content: '';\n  display: block;\n  height: 1px;\n  //margin-bottom: -2px;\n  background: var(--color-divide);\n  position: absolute;\n  left: 0;\n  right: 0;\n  bottom: 0;\n`\n\nconst hrShort = ({ theme }: any) => css`\n  border-radius: ${theme.unit / 2}px;\n  content: '';\n  display: block;\n  height: 1px;\n  width: calc(100% - ${theme.unit * 6}px);\n  background: var(--color-divide);\n  position: absolute;\n  left: ${theme.unit * 3}px;\n  right: 0;\n  bottom: 0;\n`\n\nexport const DataGridStyled = styled(DataGrid)`\n  width: 100%;\n  height: 100%;\n\n  .table-divide &.rdg .rdg-header-row {\n    &:after {\n      ${hr}\n    }\n  }\n  .table-divide-short &.rdg .rdg-header-row {\n    &:after {\n      ${hrShort}\n    }\n  }\n\n  &.rdg {\n    &.scrollable .rdg-header-row {\n      background: transparent;\n      /* background: var(--color-box); */\n    }\n\n    min-height: var(--min-height);\n    color: var(--color-text-primary);\n    //color: inherit;\n    box-sizing: border-box;\n    border: rgba(0, 0, 0, 0) 0 solid;\n    //background-color: inherit;\n    .rdg-header-row {\n      color: var(--color-text-third);\n      width: 100%;\n      background-color: inherit;\n      font-weight: normal;\n      @media only screen and (max-width: 768px) {\n        .rdg-cell {\n          font-size: 12px;\n        }\n      }\n    }\n\n    .rdg-header-sort-name {\n      flex-grow: initial;\n    }\n\n    .rdg-cell-selected {\n      box-shadow: inherit;\n    }\n\n    .rdg-row {\n      box-sizing: border-box;\n      background: inherit;\n      width: 100%;\n      transition: background 0.4s ease-out;\n\n      &:hover {\n        background: var(--color-box-hover);\n\n        .rdg-cell:first-of-type {\n          // border-left: ${({ theme }) => theme.border.borderConfig({ d_W: 2, c_key: 'selected' })}\n        }\n      }\n    }\n\n    .rdg-cell {\n      color: inherit;\n      border-left: rgba(0, 0, 0, 0) 2px solid;\n      border-right: rgba(0, 0, 0, 0) 2px solid;\n      border-bottom: rgba(0, 0, 0, 0) 2px solid;\n      box-sizing: border-box;\n      height: 100%;\n      // padding: 0 ${({ theme }) => theme.unit}px;\n\n      & > span,\n      div {\n        user-select: text;\n      }\n\n      &.textAlignRight {\n        text-align: right;\n\n        .rdg-header-sort-cell {\n          justify-content: right;\n        }\n      }\n\n      &.textAlignLeft {\n        text-align: left;\n\n        .rdg-header-sort-cell {\n          justify-content: left;\n        }\n      }\n\n      &.textAlignCenter {\n        text-align: center;\n\n        .rdg-header-sort-cell {\n          justify-content: center;\n        }\n      }\n    }\n\n    .rdg-header-sort-cell {\n      .rdg-header-sort-name + span {\n        display: none;\n      }\n\n      .rdg-header-sort-name {\n        .sort-icon svg {\n          display: inline-block;\n          transform-origin: center;\n        }\n\n        .DESC svg {\n          transform: rotate(0deg) translateX(-3px) scale(1.2);\n        }\n\n        .ASC svg {\n          transform: rotate(180deg) translateX(-3px) scale(1.2);\n        }\n\n        .NONE svg {\n          transform: rotate(90deg) translateX(-3px) scale(1.2);\n        }\n      }\n    }\n\n    .rdg-cell[aria-selected='true'] {\n      box-shadow: none;\n    }\n\n    .rdg-cell.action {\n      text-overflow: initial;\n    }\n\n    .rdg-cell.success {\n      color: var(--color-success);\n    }\n\n    .rdg-cell.error {\n      color: var(--color-error);\n    }\n  }\n` as typeof DataGrid\n\nexport const generateColumns = <Row, SR>({\n  columnsRaw,\n  t,\n}: {\n  columnsRaw: Column<Row, SR>[]\n  [key: string]: any\n} & WithT): RdgColumn<Row, SR>[] => {\n  const columns: Column<Row, SR>[] = columnsRaw.reduce(\n    (prev: RdgColumn<Row, SR>[], column: Column<Row, SR>) => {\n      const { name, isHidden } = column\n      if (typeof name === 'string' && !isHidden) {\n        //@ts-ignore\n        column.name = t(name)\n        prev.push(column)\n      }\n      return prev\n    },\n    [],\n  )\n  return columns as Column<Row, SR>[]\n}\nexport const generateRows = <Row, SR>(rawData: [][], rest: TableProps<Row, SR>): Row[] => {\n  const { columnMode } = rest\n  return rawData.map(\n    (row) =>\n      row.reduce(\n        (prev: { [key: string]: any }, cell, index) => {\n          if (columnMode[index]) {\n            prev[columnMode[index].key] = cell\n          }\n          return prev\n        },\n        { _rawData: row },\n      ) as Row,\n  )\n}\n\nexport type ExtraTableProps = {\n  showloading?: boolean\n}\n\nexport const Table = React.forwardRef(\n  <R, SR>(\n    props: DataGridProps<R, SR> & WithTranslation & ExtraTableProps,\n    ref: ForwardedRef<any>,\n  ) => {\n    const {\n      EmptyRowsRenderer,\n      generateRows,\n      generateColumns,\n      sortInitDirection,\n      sortDefaultKey,\n      sortMethod,\n      rawData,\n      style,\n      frozeSort,\n      rowRenderer,\n      rowClassFn,\n      rowKeyGetter,\n      columnMode,\n      onScroll,\n      onRowClick,\n      rowHeight,\n      showloading,\n      t,\n      ...rest\n    } = props\n\n    const columns = generateColumns({ columnsRaw: columnMode, t })\n    const [rows, setRows] = React.useState(generateRows(rawData, props))\n\n    React.useEffect(() => {\n      setRows(generateRows(rawData, props))\n    }, [rawData])\n    /*** sort handle start ***/\n    const [sortColumns, setSortColumns] = React.useState<readonly Readonly<SortColumn>[]>([\n      {\n        columnKey: sortDefaultKey as any,\n        direction: sortInitDirection ? sortInitDirection : ('ASC' as any),\n      },\n    ])\n\n    const sortedRows: readonly R[] = React.useMemo(() => {\n      if (sortColumns.length === 0) return rows\n      const { columnKey, direction } = sortColumns[0]\n      let sortedRows: R[] = [...rows]\n      sortedRows = sortMethod ? sortMethod(sortedRows, columnKey, direction) : rows\n      return direction === 'DESC' ? sortedRows.reverse() : sortedRows\n    }, [rows, sortColumns, sortMethod])\n    const onSortColumnsChange = React.useCallback((sortColumns: SortColumn[]) => {\n      setSortColumns(sortColumns.slice(-1))\n    }, [])\n\n    const loopringColumns = React.useMemo(() => {\n      return columns.map((c) => {\n        if (c.headerRenderer) {\n          return { ...c } as Column<R, unknown>\n        } else {\n          return {\n            ...c,\n            headerRenderer: (props: SortableHeaderCellProps<R>) => (\n              <SortableHeaderCell {...props} />\n            ),\n          } as Column<R, unknown>\n        }\n      }) as Column<R, unknown>[]\n    }, [columns])\n    const RenderEmptyMsg = styled.span`\n      display: flex;\n\n      .link {\n        margin: 0 5px;\n      }\n    `\n    /*** sort handle end ***/\n    return (\n      <TableWrapperStyled showloading={!!showloading ? 'true' : 'false'}>\n        <DataGridStyled\n          {...rest}\n          ref={ref}\n          onScroll={onScroll}\n          columns={loopringColumns as any}\n          style={style}\n          rows={sortDefaultKey && sortedRows ? sortedRows : rows}\n          rowKeyGetter={rowKeyGetter}\n          rowClass={(row) => (rowClassFn ? rowClassFn(row, props) : '')}\n          rowHeight={rowHeight ? rowHeight : RowConfig.rowHeight}\n          onRowsChange={setRows}\n          onSortColumnsChange={onSortColumnsChange}\n          rowRenderer={rowRenderer as any}\n          sortColumns={sortColumns}\n          onRowClick={onRowClick}\n          emptyRowsRenderer={\n            !showloading\n              ? () =>\n                  EmptyRowsRenderer ? (\n                    EmptyRowsRenderer\n                  ) : (\n                    <EmptyDefault\n                      height={`calc(100% - var(--header-row-height))`}\n                      message={() => {\n                        return (\n                          <RenderEmptyMsg>\n                            <Trans i18nKey='labelEmptyDefault'>Content is Empty</Trans>\n                          </RenderEmptyMsg>\n                        )\n                      }}\n                    />\n                  )\n              : null\n          }\n        />\n        {showloading && (\n          <LoadingStyled color={'inherit'}>\n            <img\n              className='loading-gif'\n              alt={'loading'}\n              width='36'\n              src={`${SoursURL}images/loading-line.gif`}\n            />\n          </LoadingStyled>\n        )}\n      </TableWrapperStyled>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/tables/components/Formatters/CellActionsFormatter.tsx",
    "content": "// // import { useState } from 'react';\n// // import type { ReactNode } from 'react';\n// // import clsx from 'clsx';\n// // import { usePopper } from 'react-popper';\n// // import { createPortal } from 'react-dom';\n// import styled from \"@emotion/styled\";;\n// //\n// // const CellActionClassname = styled.div`\n// //   float: right;\n// // `;\n// //\n// // const CellActionLastClassname = styled.div`\n// //   margin-right: -8px;\n// // `;\n//\n// // const CellActionButtonClassname = styled.div`\n// //   width: 35px;\n// //   height: 100%;\n// //   text-align: center;\n// //   position: relative;\n// //   display: table;\n// //   color: #4a9de2;\n// //\n// //   > span {\n// //     display: table-cell;\n// //     vertical-align: middle;\n// //   }\n// // `;\n//\n// const CellActionMenuClassname = styled.div`\n//   position: absolute;\n//   top: 100%;\n//   z-index: 1000;\n//   float: left;\n//   min-width: 160px;\n//   padding: 5px 0;\n//   text-align: left;\n//   list-style: none;\n//   background-\n//   background-clip: padding-box;\n//   border: 1px solid #ccc;\n//   box-shadow: 0 0 3px 0 #ccc;\n//\n//   > span {\n//     display: block;\n//     padding: 3px 10px;\n//     clear: both;\n//     font-weight: 400;\n//     line-height: 1.42857143;\n//     color: #333;\n//     white-space: nowrap;\n//     cursor: pointer;\n//\n//     &:hover {\n//       color: #262626;\n//       text-decoration: none;\n//       background-color: #f5f5f5;\n//     }\n//   }\n// `;\n//\n// // interface Action {\n// //   text: ReactNode;\n// //   callback: () => void;\n// // }\n//\n// // interface CellActionButton {\n// //   icon: ReactNode;\n// //   actions?: Action[];\n// //   callback?: () => void;\n// // }\n//\n// // interface CellActionProps extends CellActionButton {\n// //   isFirst: boolean;\n// // }\n// //\n// // function CellAction({ icon, actions, callback, isFirst }: CellActionProps) {\n// //   const [isOpen, setIsOpen] = useState(false);\n// //   const [reference, setReference] = useState<HTMLDivElement | undefined>(undefined);\n// //   const [popper, setPopper] = useState<HTMLDivElement | undefined>(undefined);\n// //   const { styles } = usePopper(reference, popper, {\n// //     placement: 'bottom-start',\n// //     modifiers: [{ name: 'offset', options: { offset: [0, -8] } }]\n// //   });\n// //\n// //   const cellActionClasses = clsx(CellActionMenuClassname, {\n// //     [CellActionLastClassname]: isFirst\n// //   });\n// //\n// //   function onActionIconClick() {\n// //     if (typeof callback === 'function') {\n// //       callback();\n// //     }\n// //\n// //     if (actions && actions.length > 0) {\n// //       setIsOpen(isOpen => !isOpen);\n// //     }\n// //   }\n// //\n// //   return (\n// //     <div className={cellActionClasses} onMouseLeave={() => setIsOpen(false)}>\n// //       <CellActionClassname ref={setReference} onClick={onActionIconClick}>\n// //         {icon}\n// //       </CellActionClassname>\n// //       {isOpen && actions && actions.length && createPortal(\n// //         <CellActionMenuClassname ref={setPopper} style={styles.popper}>\n// //           {actions.map((action, index) => <span key={index} onClick={action.callback}>{action.text}</span>)}\n// //         </CellActionMenuClassname>,\n// //         document.body\n// //       )}\n// //     </div>\n// //   );\n// // }\n// //\n// // interface CellActionsFormatterProps {\n// //   actions: CellActionButton[];\n// // }\n// //\n// // export function CellActionsFormatter({ actions }: CellActionsFormatterProps) {\n// //   const actionButtons = actions.map((action, index) => {\n// //     return <CellAction key={index} isFirst={index === 0} {...action} />;\n// //   });\n// //\n// //   return <>{actionButtons}</>;\n// // }\nexport default {}\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/tables/components/Formatters/CellDepthFormatter.tsx",
    "content": "import clsx from 'clsx'\nimport styled from '@emotion/styled'\nimport { withTranslation, WithTranslation } from 'react-i18next'\nimport { CellRendererProps } from 'react-data-grid'\n\nconst StyleDepth = styled.div`\n  position: absolute;\n  right: 0;\n  height: 100%;\n  z-index: -1;\n  opacity: 0.06;\n\n  .rgb-depth-cell {\n    width: 100%;\n    background: var(--color-success);\n\n    &.rgb-depth-red {\n      background: var(--color-error);\n    }\n  }\n`\n\ninterface IDepthRendererProps<R, SR> extends CellRendererProps<R, SR> {\n  depthKey: string\n}\n\nexport const CellDepthFormatter = <R, SR>({\n  t,\n  row,\n  column,\n  className,\n  depthKey,\n  ...props\n}: WithTranslation & IDepthRendererProps<R, SR>) => {\n  className = clsx(className, { 'rgb-depth-cell': true })\n  const style = { width: `${Number((row as any)[depthKey]) * 100}%` }\n  return (\n    <StyleDepth {...props}>\n      <div className={className} style={style}></div>\n    </StyleDepth>\n  )\n}\nexport default withTranslation()(CellDepthFormatter)\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/tables/components/Formatters/CellExpanderFormatter.tsx",
    "content": "import styled from '@emotion/styled'\nimport { useFocusRef } from '../../hook'\n\nconst CellExpandClassname = styled.div`\n  float: right;\n  display: table;\n  height: 100%;\n\n  > span {\n    display: table-cell;\n    vertical-align: middle;\n    cursor: pointer;\n  }\n`\n\ninterface CellExpanderFormatterProps {\n  isCellSelected: boolean\n  expanded: boolean\n  onCellExpand: () => void\n}\n\nexport function CellExpanderFormatter({\n  isCellSelected,\n  expanded,\n  onCellExpand,\n}: CellExpanderFormatterProps) {\n  const iconRef = useFocusRef<HTMLSpanElement>(isCellSelected)\n\n  function handleClick(e: React.MouseEvent<HTMLSpanElement>) {\n    e.stopPropagation()\n    onCellExpand()\n  }\n\n  function handleKeyDown(e: React.KeyboardEvent<HTMLSpanElement>) {\n    if (e.key === ' ' || e.key === 'Enter') {\n      e.preventDefault()\n      onCellExpand()\n    }\n  }\n\n  return (\n    <CellExpandClassname>\n      <span onClick={handleClick} onKeyDown={handleKeyDown}>\n        <span ref={iconRef} tabIndex={-1}>\n          {expanded ? '\\u25BC' : '\\u25B6'}\n        </span>\n      </span>\n    </CellExpandClassname>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/tables/components/Formatters/ChildRowDeleteButton.tsx",
    "content": "import styled from '@emotion/styled'\nimport { useFocusRef } from '../../hook'\n\nconst ChildRowActionCrossClassname = styled.div`\n  &::before,\n  &::after {\n    content: '';\n    position: absolute;\n    background: grey;\n  }\n\n  &::before {\n    left: 21px;\n    width: 1px;\n    height: 100%;\n  }\n\n  &::after {\n    top: 50%;\n    left: 20px;\n    height: 1px;\n    width: 15px;\n  }\n\n  &:hover {\n    background: red;\n  }\n`\n\nconst ChildRowButtonClassname = styled.div`\n  cursor: pointer;\n  position: absolute;\n  left: 21px;\n  transform: translateX(-50%);\n  filter: grayscale(1);\n`\n\ninterface ChildRowDeleteButtonProps {\n  isCellSelected: boolean\n  isDeleteSubRowEnabled: boolean\n  onDeleteSubRow: () => void\n}\n\nexport function ChildRowDeleteButton({\n  isCellSelected,\n  onDeleteSubRow,\n  isDeleteSubRowEnabled,\n}: ChildRowDeleteButtonProps) {\n  const iconRef = useFocusRef<HTMLSpanElement>(isCellSelected)\n\n  function handleKeyDown(e: React.KeyboardEvent<HTMLSpanElement>) {\n    if (e.key === 'Enter') {\n      e.preventDefault()\n      onDeleteSubRow()\n    }\n  }\n\n  return (\n    <>\n      <ChildRowActionCrossClassname />\n      {isDeleteSubRowEnabled && (\n        <ChildRowButtonClassname onClick={onDeleteSubRow}>\n          <span ref={iconRef} tabIndex={-1} onKeyDown={handleKeyDown}>\n            ❌\n          </span>\n        </ChildRowButtonClassname>\n      )}\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/tables/components/Formatters/ImageFormatter.tsx",
    "content": "import styled from '@emotion/styled'\n\nconst WrapperClassname = styled.div`\n  display: flex;\n  justify-content: space-around;\n`\n\nconst ImageCellClassname = styled.div`\n  background: #efefef;\n  background-size: 100%;\n  display: inline-block;\n  height: 28px;\n  width: 28px;\n  vertical-align: middle;\n  background-position: center;\n`\n\ninterface Props {\n  /** image url, used as background-image */\n  value: string\n}\n\nexport function ImageFormatter({ value }: Props) {\n  return (\n    <WrapperClassname>\n      <ImageCellClassname style={{ backgroundImage: `url(${value})` }} />\n    </WrapperClassname>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/tables/components/Formatters/index.ts",
    "content": "// export * from './CellActionsFormatter';\nexport * from './ImageFormatter'\nexport * from './CellExpanderFormatter'\nexport * from './ChildRowDeleteButton'\nexport * from './CellDepthFormatter'\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/tables/components/HeaderRenderers/SortableHeaderCell.tsx",
    "content": "import { HeaderRendererProps } from 'react-data-grid'\nimport styled from '@emotion/styled'\nimport { Box, BoxProps } from '@mui/material'\nimport { css } from '@emotion/react'\nimport React from 'react'\n\nexport const headerSortCell = css`\n  cursor: pointer;\n  display: flex;\n`\nexport const headerSortName = css`\n  flex-grow: 1;\n  overflow: hidden;\n  text-overflow: ellipsis;\n`\nconst StyledArrowSort = styled(Box)<BoxProps & { sortdirection: 'ASC' | 'DESC' | undefined }>`\n  margin-left: ${({ theme }) => `${theme.unit / 2}px`};\n  .up {\n    width: 0;\n    height: 0;\n    border: ${({ theme }) => `${theme.unit / 2}px`} solid transparent;\n    border-bottom-color: ${({\n      // theme,\n      sortdirection,\n    }) => (sortdirection === 'DESC' ? `var(--color-text-primary)` : `var(--color-text-third)`)};\n  }\n\n  .down {\n    width: 0;\n    height: 0;\n    border: ${({ theme }) => `${theme.unit / 2}px`} solid transparent;\n    border-top-color: ${({\n      // theme,\n      sortdirection,\n    }) => (sortdirection === 'ASC' ? `var(--color-text-primary)` : `var(--color-text-third)`)};\n    margin-top: ${({ theme }) => `${theme.unit / 4}px`};\n  }\n` as (props: BoxProps & { sortdirection: 'ASC' | 'DESC' | undefined }) => JSX.Element\n\n// @ts-ignore\nexport const ArrowSort = ({\n  sortDirection,\n  // children,\n  ...rest\n}: BoxProps & { sortDirection: 'ASC' | 'DESC' | undefined }) => {\n  return (\n    <StyledArrowSort {...{ ...rest }} sortdirection={sortDirection}>\n      <div className='up' />\n      <div className='down' />\n    </StyledArrowSort>\n  )\n}\n\n// type SharedHeaderCellProps<R, SR> = Pick<\n//     HeaderRendererProps<R, SR>,\n//     'sortDirection' | 'onSort' | 'priority'\n//     >;\nexport interface SortableHeaderCellProps<R, SR = unknown> extends HeaderRendererProps<R, SR> {\n  children?: React.ReactNode\n}\n\nexport function SortableHeaderCell<R, SR>({\n  column,\n  sortDirection,\n  priority,\n  onSort,\n  children,\n}: SortableHeaderCellProps<R, SR>) {\n  // let sortText = '';\n  // if (sortDirection === 'ASC') {\n  //     sortText = '\\u25B2';\n  // } else if (sortDirection === 'DESC') {\n  //     sortText = '\\u25BC';\n  // }\n  if (column.sortable) {\n    // const showUp = sortDirection === 'ASC'\n    // const showDown =  sortDirection === 'DESC'\n\n    return (\n      <Box\n        component={'span'}\n        display={'flex'}\n        alignItems={'center'}\n        className={`rdg-header-sort-cell ${headerSortCell}`}\n        onClick={(e: React.MouseEvent) => onSort(e.ctrlKey)}\n      >\n        <span className={`rdg-header-sort-name ${headerSortName}`}>\n          {children ? children : column.name}\n        </span>\n        <ArrowSort {...{ sortDirection }} />\n        {priority}\n      </Box>\n    )\n  } else {\n    return <>{children ? children : column.name}</>\n  }\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/tables/components/HeaderRenderers/index.ts",
    "content": "export * from './SortableHeaderCell'\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/tables/components/RowRenders/RowDepthFormatter.tsx",
    "content": "import clsx from 'clsx'\nimport styled from '@emotion/styled'\nimport { CalculatedColumn, Cell, RowRendererProps } from 'react-data-grid'\nimport React from 'react'\n// import type { Column } from 'react-data-grid';\n\nconst RowDepthStyled = styled.div`\n  contain: strict;\n  contain: size layout style paint;\n  display: grid;\n  grid-template-rows: var(--row-height);\n  grid-template-columns: var(--template-columns);\n  position: absolute;\n  left: 0;\n  width: var(--row-width);\n  height: var(--row-height);\n  line-height: var(--row-height);\n  background-color: var(--background-color);\n\n  .row-background-value {\n    opacity: .06;\n    height: var(--row-height);\n    width: var(--row-width);\n    position: absolute;\n    top: 0;\n    left: 0;\n    z-index: 1;\n\n    .rgb-depth-row {\n      float: right;\n      height: var(--row-height);\n      background: var(--color-success);\n\n      &.rgb-depth-red {\n        background: var(--color-error);\n      }\n    }\n  }\n}\n`\n\nexport interface IDepthRendererProps<R, SR> extends RowRendererProps<R, SR> {\n  depthKey: string\n  rowBeforeRender: (prors: {\n    depthKey: string\n    row: R\n    column: readonly CalculatedColumn<R, SR>[]\n    className: any\n    [key: string]: any\n  }) => JSX.Element\n}\n\nfunction _DepthRow<R, SR = unknown>(\n  {\n    cellRenderer: CellRenderer = Cell,\n    className,\n    rowIdx,\n    isRowSelected,\n    copiedCellIdx,\n    draggedOverCellIdx,\n    row,\n    viewportColumns,\n    selectedCellProps,\n    onRowClick,\n    rowClass,\n    setDraggedOverRowIdx,\n    onMouseEnter,\n    top,\n    onRowChange,\n    selectCell,\n    selectRow,\n    rowBeforeRender,\n    depthKey,\n    'aria-rowindex': ariaRowIndex,\n    'aria-selected': ariaSelected,\n    ...props\n  }: IDepthRendererProps<R, SR> & { selectRow: any },\n  ref: React.Ref<HTMLDivElement>,\n) {\n  function handleDragEnter(event: React.MouseEvent<HTMLDivElement>) {\n    setDraggedOverRowIdx?.(rowIdx)\n    onMouseEnter?.(event)\n  }\n\n  className = clsx(\n    `rdg-row`,\n    `rdg-row-${rowIdx % 2 === 0 ? 'even' : 'odd'}`,\n    {\n      'rdg-cell-selected': isRowSelected,\n      'rdg-group-row-selected': selectedCellProps?.idx === -1,\n    },\n    rowClass?.(row),\n    className,\n  )\n  return (\n    <RowDepthStyled\n      role='row'\n      aria-rowindex={ariaRowIndex}\n      aria-selected={ariaSelected}\n      ref={ref}\n      className={className}\n      onMouseEnter={handleDragEnter}\n      style={{ top }}\n      {...props}\n    >\n      <div className={'row-background-value'}>\n        {rowBeforeRender({\n          row,\n          depthKey,\n          column: viewportColumns,\n          className,\n          ...props,\n        })}\n      </div>\n      {viewportColumns.map((column) => {\n        const isCellSelected = selectedCellProps?.idx === column.idx\n\n        return (\n          CellRenderer && (\n            <CellRenderer\n              {...props}\n              colSpan={undefined}\n              key={column.key}\n              rowIdx={rowIdx}\n              column={column}\n              row={row}\n              isCopied={copiedCellIdx === column.idx}\n              isDraggedOver={draggedOverCellIdx === column.idx}\n              isCellSelected={isCellSelected}\n              // isRowSelected={isRowSelected}\n              dragHandleProps={\n                isCellSelected ? (selectedCellProps as any).dragHandleProps : undefined\n              }\n              onFocus={isCellSelected ? (selectedCellProps as any).onFocus : undefined}\n              onKeyDown={isCellSelected ? selectedCellProps!.onKeyDown : undefined}\n              onRowClick={onRowClick}\n              onRowChange={onRowChange}\n              selectCell={selectCell}\n              // selectRow={selectRow}\n            />\n          )\n        )\n      })}\n    </RowDepthStyled>\n  )\n}\n\nexport const DepthRow = React.memo(React.forwardRef(_DepthRow)) as unknown as <R, SR = unknown>(\n  props: IDepthRendererProps<R, SR> & React.RefAttributes<HTMLDivElement>,\n) => JSX.Element\n\nexport const RowBefore = <R, SR>({\n  row,\n  // isRowSelected,\n  className,\n  column,\n  depthKey,\n  width,\n  // onRowReorder,\n  ...props\n}: { column: any; width: string } & IDepthRendererProps<R, SR>) => {\n  return <div className={`rgb-depth-row ${className}`} style={{ width: width }} {...props}></div>\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/tables/components/RowRenders/index.ts",
    "content": "export * from './RowDepthFormatter'\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/tables/hook/index.ts",
    "content": "export * from './useClickOutside'\nexport * from './useCombinedRefs'\nexport * from './useFocusRef'\nexport * from './useLatestFunc'\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/tables/hook/useClickOutside.ts",
    "content": "import { useEffect, useRef } from 'react'\n\n/**\n * Detecting outside click on a react component is surprisingly hard.\n * A general approach is to have a global click handler on the document\n * which checks if the click target is inside the editor container or\n * not using editorContainer.contains(e.target). This approach works well\n * until portals are used for editors. Portals render children into a DOM\n * node that exists outside the DOM hierarchy of the parent component so\n * editorContainer.contains(e.target) does not work. Here are some examples\n * of the DOM structure with different types of editors\n *\n *\n * SimpleEditor for example Texbox (No Portals)\n *   <div data-grid>..</div>\n *   <div portal-created-by-the-grid-for-editors>\n *      <div editor-container>\n *        <div simple-editor>..</div>\n *      </div>\n *   </div>\n *\n * ComplexEditor for example Modals (using Portals)\n *   <div data-grid>..</div>\n *   <div portal-created-by-the-grid-for-editors>\n *      <div editor-container>\n *        // Nothing here\n *      </div>\n *   </div>\n *   <div portal-created-by-the-editor>\n *     <div complex-editor>..</div>\n *   </div>\n *\n *\n * One approach to detect outside click is to use synthetic event bubbling through\n * portals. An event fired from inside a portal will propagate to ancestors\n * in the containing React tree, even if those elements are not ancestors\n * in the DOM tree. This means a click handler can be attached on the window\n * and on the editor container. The editor container can set a flag to notify\n * that the click was inside the editor and the window click handler can use\n * this flag to call onClickOutside. This approach however has a few caveats\n * - Click handler on the window is set using window.addEventListener\n * - Click handler on the editor container is set using onClick prop\n *\n * This means if a child component inside the editor calls e.stopPropagation\n * then the click handler on the editor container will not be called whereas\n * the document click handler will be called.\n * https://github.com/facebook/react/issues/12518\n *\n * To solve this issue onClickCapture event is used.\n */\n\nexport function useClickOutside(onClick: () => void) {\n  const frameRequestRef = useRef<number | undefined>()\n\n  function cancelAnimationFrameRequest() {\n    if (typeof frameRequestRef.current === 'number') {\n      cancelAnimationFrame(frameRequestRef.current)\n      frameRequestRef.current = undefined\n    }\n  }\n\n  // We need to prevent the `useEffect` from cleaning up between re-renders,\n  // as `handleDocumentClick` might otherwise miss valid click events.\n  // To that end we instead access the latest `onClick` prop via a ref.\n  const onClickRef = useRef((): void => {\n    throw new Error('Cannot call an event handler while rendering.')\n  })\n\n  useEffect(() => {\n    onClickRef.current = onClick\n  })\n\n  useEffect(() => {\n    function onOutsideClick() {\n      frameRequestRef.current = undefined\n      onClickRef.current()\n    }\n\n    function onWindowCaptureClick() {\n      cancelAnimationFrameRequest()\n      frameRequestRef.current = requestAnimationFrame(onOutsideClick)\n    }\n\n    window.addEventListener('click', onWindowCaptureClick, { capture: true })\n\n    return () => {\n      window.removeEventListener('click', onWindowCaptureClick, {\n        capture: true,\n      })\n      cancelAnimationFrameRequest()\n    }\n  }, [])\n\n  return cancelAnimationFrameRequest\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/tables/hook/useCombinedRefs.ts",
    "content": "import { useCallback } from 'react'\n\nexport function useCombinedRefs<T>(...refs: readonly React.Ref<T>[]) {\n  return useCallback(\n    (handle: T | null) => {\n      for (const ref of refs) {\n        if (typeof ref === 'function') {\n          ref(handle)\n        } else if (ref !== null) {\n          // @ts-ignore\n          ref.current = handle as any\n        }\n      }\n    },\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n    refs,\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/tables/hook/useFocusRef.ts",
    "content": "import { useLayoutEffect, useRef } from 'react'\n\nexport function useFocusRef<T extends HTMLOrSVGElement>(isCellSelected: boolean | undefined) {\n  const ref = useRef<T>(null)\n  useLayoutEffect(() => {\n    if (!isCellSelected) return\n    ref.current?.focus({ preventScroll: true })\n  }, [isCellSelected])\n\n  return ref\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/tables/hook/useLatestFunc.ts",
    "content": "import { useCallback, useEffect, useRef } from 'react'\n\n// https://reactjs.org/docs/hooks-faq.html#what-can-i-do-if-my-effect-dependencies-change-too-often\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function useLatestFunc<T extends (...args: any[]) => any>(fn: T) {\n  const ref = useRef(fn)\n\n  useEffect(() => {\n    ref.current = fn\n  })\n\n  return useCallback((...args: Parameters<T>) => {\n    ref.current(...args)\n  }, [])\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/tables/index.ts",
    "content": "export * from './Table'\nexport * from '../empty'\nexport * from './components/RowRenders'\nexport * from './components/HeaderRenderers'\nexport * from './components/Formatters'\nexport * from './Interface'\nexport * from './hook'\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/tables/table.stories.tsx",
    "content": "import { Meta, Story } from '@storybook/react'\nimport { CellDepthFormatter } from './components/Formatters'\nimport { Column, DataGridProps, generateColumns, generateRows, Table } from './index'\n\nimport styled from '@emotion/styled'\nimport { RowRendererProps } from 'react-data-grid'\n\nimport { DepthRow, RowBefore } from './components/RowRenders'\nimport { useTranslation } from 'react-i18next'\n\nconst Style = styled.div`\n  background: var(--color-global-bg);\n`\n\ninterface Row {\n  price: string\n  size: string\n  volume: string\n  number: string\n  sortColumn: string\n  filterColumn: string\n  cellExpend: {\n    value: string\n    children: []\n    isExpanded: boolean\n  }\n  children?: Row[]\n  isExpanded?: boolean\n  format?: any\n}\n\nconst rawData: Array<Array<any>> = [\n  ['1.2', 'big', '0.12', '123', 'abc', 'start_a'],\n  ['1.3', 'big', '0.99', '1293', 'abc', 'start_a'],\n  ['1.5', 'small', '0.42', '23', 'abc', 'start_a'],\n  ['1.2', 'big', '0.32', '123', 'abc', 'end_a'],\n  ['1.6', 'big', '0.52', '123', 'abc', 'start_a'],\n  ['1.3', 'middle', '0.852', '5', 'abc', 'before_a'],\n  ['1.2', 'big', '0.12', '123', 'abc', 'start_a'],\n]\nconst columnModeDefault: Column<Row, unknown>[] = [\n  { key: 'price', name: 'price' },\n  { key: 'size', name: 'size' },\n  { key: 'volume', name: 'volume' },\n  { key: 'number', name: 'size' },\n  { key: 'string', name: 'volume' },\n  { key: 'filter', name: 'number' },\n]\n\n/**\n * Table StoryBook\n */\nexport default {\n  component: Table,\n  title: 'basic-lib/Table',\n  argTypes: {},\n} as Meta\n\nconst Template: Story<DataGridProps<Row, unknown>> = (args: DataGridProps<Row, unknown> & any) => {\n  let rest = useTranslation()\n  return (\n    <Style>\n      <Table {...{ ...args, ...rest }} />\n    </Style>\n  )\n}\nexport const Default = Template.bind({})\nexport const Empty = Template.bind({})\nexport const FormatCell = Template.bind({})\nexport const FormatRow = Template.bind({})\nexport const SortColumn = Template.bind({})\nexport const ExpendRowDemo = Template.bind({})\nDefault.args = {\n  rawData: rawData,\n  columnMode: columnModeDefault,\n  generateRows: generateRows,\n  generateColumns: generateColumns,\n}\nEmpty.args = {\n  ...Default.args,\n  rawData: [],\n  columnMode: columnModeDefault,\n}\nconst columnModeCellDepth: Column<Row, unknown>[] = [\n  {\n    key: 'price',\n    name: 'price',\n    cellClass: (row: Row) => (Number(row.volume) > 0.4 ? 'success' : 'error'),\n  },\n  {\n    key: 'size',\n    name: 'size',\n    formatter: ({ row, column, ...props }: any) => {\n      return (\n        <>\n          <CellDepthFormatter\n            {...props}\n            row={row}\n            column={column}\n            className={row.price > 0.4 ? 'rgb-depth-success' : 'rgb-depth-error'}\n            depthKey={'price'}\n          />\n          <div className='rdg-cell-value'>\n            <div>{row[column.key]}</div>\n          </div>\n        </>\n      )\n    },\n  },\n  { key: 'volume', name: 'volume', sortable: true },\n]\nFormatCell.args = {\n  ...Default.args,\n  ...{\n    columnMode: columnModeCellDepth,\n  },\n}\nFormatRow.args = {\n  ...Default.args,\n  ...{\n    columnMode: columnModeDefault,\n    rowRenderer: (p: RowRendererProps<Row, any>) => {\n      const { row } = p\n      return (\n        <DepthRow\n          depthKey={'volume'}\n          rowBeforeRender={(p: any) => {\n            const width = `${Number(row.volume) * 100}%`\n            return (\n              <RowBefore\n                {...p}\n                width={width}\n                className={Number(row.volume) > 0.4 ? 'rgb-depth-red' : ''}\n              />\n            )\n          }}\n          {...p}\n        />\n      )\n    },\n  },\n}\n\nconst columnModeSort: Column<Row, unknown>[] = [\n  {\n    key: 'price',\n    name: 'price',\n    cellClass: (row: Row) => (Number(row.price) > 100 ? 'upper' : 'row'),\n  },\n  { key: 'size', name: 'size', sortable: true },\n  { key: 'volume', name: 'volume', sortable: true },\n  { key: 'sortColumn', name: 'value', sortable: true },\n]\nSortColumn.args = {\n  ...Default.args,\n  columnMode: columnModeSort,\n  sortDefaultKey: 'sortColumn',\n  frozeSort: false,\n  sortMethod: (sortedRows: Row[], sortColumn) => {\n    switch (sortColumn) {\n      case 'size':\n        sortedRows = sortedRows.sort((a, b) => a[sortColumn].localeCompare(b[sortColumn]))\n        break\n      case 'sortColumn':\n      case 'volume':\n        sortedRows = sortedRows.sort(\n          (a: Row, b: Row) => Number(a[sortColumn]) - Number(b[sortColumn]),\n        )\n        break\n      default:\n    }\n    return sortedRows\n  },\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/tags/Tags.stories.tsx",
    "content": "import { Meta, Story } from '@storybook/react'\n\nimport { Box, Grid } from '@mui/material'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport styled from '@emotion/styled'\nimport { NewTagIcon } from './index'\nimport { ButtonProps } from '../btns'\n\nconst Styled = styled.div`\n  background: var(--color-global-bg);\n`\n\nexport const Tags: Story<ButtonProps> = withTranslation()(({}: WithTranslation & any) => {\n  return (\n    <>\n      <Styled>\n        <h4>Tags</h4>\n        <Box>\n          <Grid\n            container\n            spacing={2}\n            alignContent={'center'}\n            justifyContent={'flex-start'}\n            flexWrap={'nowrap'}\n          >\n            <Grid item xs={6} margin={2}>\n              <NewTagIcon />\n            </Grid>\n          </Grid>\n        </Box>\n      </Styled>\n    </>\n  )\n}) as Story<ButtonProps>\n\n//export const Button = Template.bind({});\n\nexport default {\n  title: 'resource/tags',\n  component: Tags,\n  argTypes: {},\n} as Meta\n// LButton.args = {}\n"
  },
  {
    "path": "packages/component-lib/src/components/basic-lib/tags/index.tsx",
    "content": "import { SvgIcon, Chip, SvgIconProps } from '@mui/material'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { useTranslation } from 'react-i18next'\nimport styled from '@emotion/styled'\nimport { fontDefault, myLog } from '@loopring-web/common-resources'\n\nexport const NewTagIcon = () => (\n  <SvgIcon\n    className={'tag'}\n    width='25'\n    height='12'\n    viewBox='0 0 25 12'\n    fill='none'\n    xmlns='http://www.w3.org/2000/svg'\n  >\n    <path\n      d='M0 6C0 2.68629 2.68629 0 6 0H19C22.3137 0 25 2.68629 25 6C25 9.31371 22.3137 12 19 12H6C2.68629 12 0 9.31371 0 6Z'\n      fill='#F46253'\n    />\n    <path\n      fillRule='evenodd'\n      clipRule='evenodd'\n      d='M9.53831 2.54004H8.38131V6.88422L5.38532 2.54004H4.46631V9.16004H5.62331V4.80767L8.6192 9.16004H9.53831V2.54004Z'\n      fill='white'\n    />\n    <path\n      fillRule='evenodd'\n      clipRule='evenodd'\n      d='M12.8229 8.21904C12.4264 8.21904 12.1019 8.11638 11.84 7.91884C11.6327 7.75888 11.4848 7.54497 11.3988 7.27004H15.1027L15.1231 7.13377C15.1423 7.00642 15.1519 6.88147 15.1519 6.75904C15.1519 6.0677 14.9287 5.47103 14.4811 4.97824C14.0349 4.4743 13.4535 4.22304 12.7509 4.22304C12.0169 4.22304 11.4068 4.46199 10.9353 4.94644C10.4657 5.42883 10.2329 6.03401 10.2329 6.75004C10.2329 7.4723 10.4689 8.08088 10.945 8.56342L10.9465 8.56493C11.4305 9.04239 12.0548 9.27704 12.8049 9.27704C13.7352 9.27704 14.4487 8.9153 14.9193 8.18686L15.0113 8.04453L14.0637 7.50672L13.9827 7.63808C13.7468 8.0208 13.3715 8.21904 12.8229 8.21904ZM14.7849 8.10009C14.7849 8.10007 14.7849 8.10011 14.7849 8.10009ZM11.393 6.26604C11.4701 5.99196 11.61 5.773 11.8104 5.60308L11.8119 5.60178C12.0545 5.39082 12.3634 5.28104 12.7509 5.28104C13.0751 5.28104 13.3539 5.37992 13.5943 5.57763C13.7894 5.73807 13.9285 5.96388 14.0047 6.26604H11.393ZM14.1999 6.42604C14.1914 6.371 14.1812 6.31767 14.1692 6.26604C14.1014 5.9724 13.9785 5.73383 13.8005 5.55032C14.0098 5.76611 14.1429 6.05791 14.1999 6.42604L11.1941 6.4262C11.1941 6.42625 11.1941 6.42614 11.1941 6.4262L14.1999 6.42604Z'\n      fill='white'\n    />\n    <path\n      fillRule='evenodd'\n      clipRule='evenodd'\n      d='M22.0533 4.34004H20.8969L20.0218 7.37085L19.0832 4.34004H18.0914L17.1526 7.3632L16.2775 4.34004H15.1211L16.6153 9.16004H17.6514L18.5872 6.20072L19.523 9.16004H20.5591L22.0533 4.34004Z'\n      fill='white'\n    />\n  </SvgIcon>\n)\n\nexport const ChipStyle = styled(Chip)`\n  font-size: ${fontDefault.body2};\n  border-radius: ${({ theme }) => `${theme.unit}`}px;\n  height: ${({ theme }) => `${(theme.unit * 5) / 2}`}px;\n`\nexport const AddressTypeTag = ({ addressType }: { addressType }) => {\n  const { t } = useTranslation('common')\n  myLog('addressType', addressType, sdk.AddressType)\n  switch (addressType) {\n    case sdk.AddressType.EOA:\n      return (\n        <ChipStyle\n          label={t('labelEOA')}\n          size='small'\n          sx={{ backgroundColor: 'var(--color-EOA-Bg)', color: 'var(--color-EOA-Text)' }}\n        />\n      )\n    case sdk.AddressType.LOOPRING_HEBAO_CF:\n    case sdk.AddressType.LOOPRING_HEBAO_CONTRACT_1_1_6:\n    case sdk.AddressType.LOOPRING_HEBAO_CONTRACT_1_2_0:\n    case sdk.AddressType.LOOPRING_HEBAO_CONTRACT_2_0_0:\n    case sdk.AddressType.LOOPRING_HEBAO_CONTRACT_2_1_0:\n    case sdk.AddressType.LOOPRING_HEBAO_CONTRACT_2_2_0:\n    case sdk.AddressType.LOOPRING_HEBAO_CONTRACT_3_0_0:\n      return (\n        <ChipStyle\n          label={t('labelLoopringWallet')}\n          size='small'\n          sx={{ backgroundColor: 'var(--color-Loopring-Bg)', color: 'var(--color-Loopring-Text)' }}\n        />\n      )\n    case sdk.AddressType.CONTRACT:\n      return (\n        <ChipStyle\n          label={t('labelOtherSmart')}\n          size='small'\n          sx={{\n            backgroundColor: 'var(--color-OtherSmart-Bg)',\n            color: 'var(--color-OtherSmart-Text)',\n          }}\n        />\n      )\n    case sdk.AddressType.EXCHANGE_BINANCE:\n      return (\n        <ChipStyle\n          label={t('labelBinance')}\n          size='small'\n          sx={{ backgroundColor: 'var(--color-Binance-Bg)', color: 'var(--color-Binance-Text)' }}\n        />\n      )\n    case sdk.AddressType.EXCHANGE_HUOBI:\n      return (\n        <ChipStyle\n          label={t('labelHuobi')}\n          size='small'\n          sx={{ backgroundColor: 'var(--color-Huobi-Bg)', color: 'var(--color-Huobi-Text)' }}\n        />\n      )\n    case sdk.AddressType.EXCHANGE_OTHER:\n      return (\n        <ChipStyle\n          label={t('labelOtherExchange')}\n          size='small'\n          sx={{\n            backgroundColor: 'var(--color-OtherExchange-Bg)',\n            color: 'var(--color-OtherExchange-Text)',\n          }}\n        />\n      )\n    case sdk.AddressType.UNKNOWN_ADDRESS:\n    default:\n      return <></>\n  }\n}\n\nexport const VaultTag = (props: SvgIconProps) => {\n  return (\n    <svg viewBox='0 0 48 48' {...props}>\n      <path\n        d='M48 24C48 37.2548 37.2548 48 24 48C10.7452 48 0 37.2548 0 24C0 10.7452 10.7452 0 24 0C37.2548 0 48 10.7452 48 24Z'\n        fill='url(#vaultTagLinear)'\n      />\n      <path d='M17.4545 14.0859H12L19.3636 29.5596L22.0909 23.5596L17.4545 14.0859Z' fill='white' />\n      <path\n        d='M23.4545 38.0859L21.2727 33.3491L30.5455 14.0859H36L24.5455 38.0859H23.4545Z'\n        fill='white'\n      />\n      <defs>\n        <linearGradient\n          id='vaultTagLinear'\n          x1='24'\n          y1='0'\n          x2='24'\n          y2='48'\n          gradientUnits='userSpaceOnUse'\n        >\n          <stop stopColor='#68E19B' />\n          <stop offset='1' stopColor='#4EADEB' />\n        </linearGradient>\n      </defs>\n    </svg>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/block/AmmCard.tsx",
    "content": "import { Box, Card, CardActions, CardContent, Divider, Typography } from '@mui/material'\nimport { Button, CoinIcons } from '../'\nimport React from 'react'\nimport moment from 'moment'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport { useHistory } from 'react-router-dom'\nimport {\n  AmmCardProps,\n  CurrencyToTag,\n  DAY_FORMAT,\n  EmptyValueTag,\n  getValuePrecisionThousand,\n  myLog,\n  PriceTag,\n  TokenType,\n  YEAR_DAY_FORMAT,\n} from '@loopring-web/common-resources'\nimport { bindPopper, usePopupState } from 'material-ui-popup-state/hooks'\nimport { PopoverPure } from '../basic-lib'\nimport { bindHover } from 'material-ui-popup-state/es'\nimport { useSettings } from '../../stores'\nimport styled from '@emotion/styled'\n\nexport interface Reward {\n  startAt: number\n  timeInterval: string\n  accountId: number\n  tokenId: number\n  market: string\n  score: number\n  amount: string\n}\n\nconst CardStyled = styled(Card)`\n  min-height: ${({ theme }) => theme.unit * 61.5}px;\n  display: flex;\n  flex-direction: column;\n  justify-content: space-between;\n  position: relative;\n`\n\nconst LabelStyled = styled(Box)`\n  position: absolute;\n  top: 0;\n  left: 0;\n  border-radius: ${({ theme }) => theme.unit}px 0;\n  padding: ${({ theme }) => theme.unit / 2}px ${({ theme }) => theme.unit}px;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  color: var(--color-box);\n  font-size: 1.4rem;\n  background: ${({ type }: any) =>\n    type === 'ORDERBOOK_MINING' ? 'var(--color-warning)' : 'var(--color-tag)'};\n` as any\n\nconst CardActionBoxStyled = styled(Box)`\n  position: relative;\n`\n\nconst DetailWrapperStyled = styled(Box)`\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  margin-bottom: ${({ theme }) => theme.unit}px;\n`\n\nconst ViewDetailStyled = styled(Typography)`\n  &:hover {\n    color: var(--color-text-primary);\n  }\n` as any\n\nexport const AmmCard = withTranslation('common', { withRef: true })(\n  React.memo(\n    React.forwardRef(\n      <T extends { [key: string]: any }>(\n        {\n          t,\n          coinAInfo,\n          coinBInfo,\n          amountU,\n          account,\n          APR,\n          coinA,\n          coinB,\n          activity: {\n            duration,\n            myRewards,\n            rewardToken,\n            isPass,\n            ruleType,\n            totalRewards,\n            rewardTokenU,\n            maxSpread,\n          },\n          handleClick,\n          popoverIdx,\n          totalA,\n          totalB,\n          precisionA,\n          precisionB,\n          getLiquidityMining, //: (market: string, size?: number) => Promise<void>\n          setShowRewardDetail,\n          setChosenCardInfo,\n          ammInfo,\n          forexMap,\n          rewardB,\n          rewardAU,\n          rewardBU,\n        }: // ...rest\n        AmmCardProps<T> & WithTranslation,\n        ref: React.ForwardedRef<any>,\n      ) => {\n        const isOrderbook = ruleType === 'ORDERBOOK_MINING'\n        const isAmm = ruleType === 'AMM_MINING'\n\n        const { coinJson, currency } = useSettings()\n\n        const pathname = `${coinAInfo?.simpleName}-${coinBInfo?.simpleName}`\n        const pair = `${coinAInfo?.simpleName} / ${coinBInfo?.simpleName}`\n\n        const myBalanceA = ammInfo?.balanceA\n        const myBalanceB = ammInfo?.balanceB\n        const myTotalAmmValueDollar = ammInfo?.totalAmmValueDollar\n        const totalAmmReward =\n          PriceTag[CurrencyToTag[currency]] +\n          getValuePrecisionThousand(\n            (rewardAU ?? 0) * (forexMap[currency] ?? 0) +\n              (rewardBU ?? 0) * (forexMap[currency] ?? 0),\n            undefined,\n            undefined,\n            2,\n            true,\n            { isFait: true },\n          )\n\n        myLog({\n          totalAmmReward,\n        })\n        const orderbookReward =\n          CurrencyToTag[currency] +\n          getValuePrecisionThousand(\n            (totalRewards || 0) * ((rewardTokenU || 0) * (forexMap[currency] ?? 0)),\n            undefined,\n            undefined,\n            2,\n            true,\n            { isFait: true },\n          )\n\n        const isComing = moment(duration.from).unix() * 1000 > moment.now()\n\n        const popLiquidityState = usePopupState({\n          variant: 'popover',\n          popupId: `popup-totalLiquidty-${popoverIdx}`,\n        })\n        const popTotalRewardState = usePopupState({\n          variant: 'popover',\n          popupId: `popup-totalReward-${popoverIdx}`,\n        })\n        const popMyAmmValueState = usePopupState({\n          variant: 'popover',\n          popupId: `popup-myAmmValue-${popoverIdx}`,\n        })\n\n        const history = useHistory()\n\n        const handleViewDetail = React.useCallback(() => {\n          const date = new Date(duration.from)\n          const year = date.getFullYear()\n          const month = ('0' + (date.getMonth() + 1).toString()).slice(-2)\n          const current_event_date = `${year}-${month}`\n          history.push(\n            `/race-event/${current_event_date}?selected=${pathname}&type=${''}&l2account=${\n              account?.accAddress\n            }`,\n          )\n        }, [history, pathname])\n\n        const handleMyRewardClick = React.useCallback(() => {\n          getLiquidityMining(pathname, 120)\n          setShowRewardDetail(true)\n          setChosenCardInfo(rewardToken?.simpleName)\n        }, [\n          getLiquidityMining,\n          pathname,\n          rewardToken?.simpleName,\n          setChosenCardInfo,\n          setShowRewardDetail,\n        ])\n\n        return (\n          <CardStyled ref={ref}>\n            <LabelStyled type={ruleType}>{isOrderbook ? 'Orderbook' : 'AMM Pools'}</LabelStyled>\n            <CardContent style={{ paddingBottom: 0 }}>\n              <Box\n                display={'flex'}\n                flexDirection={'row'}\n                justifyContent={'space-between'}\n                alignItems={'center'}\n              >\n                <Typography\n                  variant={'h3'}\n                  component={'span'}\n                  color={'textPrimary'}\n                  fontFamily={'Roboto'}\n                >\n                  {pair}\n                </Typography>\n                <Box\n                  display={'flex'}\n                  flexDirection={'row'}\n                  justifyContent={'flex-start'}\n                  alignItems={'center'}\n                  marginRight={-1}\n                >\n                  <Box\n                    className={'logo-icon'}\n                    display={'flex'}\n                    height={'var(--chart-title-coin-size)'}\n                    position={'relative'}\n                    zIndex={20}\n                    width={'var(--chart-title-coin-size)'}\n                    alignItems={'center'}\n                    justifyContent={'center'}\n                  >\n                    <CoinIcons type={TokenType.single} tokenIcon={[coinJson[coinA]]} />\n                    <Typography\n                      component={'span'}\n                      color={'var(--color-text-primary)'}\n                      variant={'body2'}\n                      marginLeft={1 / 2}\n                      height={20}\n                      lineHeight={'20px'}\n                    >\n                      {coinA}\n                    </Typography>\n                  </Box>\n\n                  <Box\n                    className={'logo-icon'}\n                    display={'flex'}\n                    height={'var(--chart-title-coin-size)'}\n                    position={'relative'}\n                    zIndex={18}\n                    left={-8}\n                    width={'var(--chart-title-coin-size)'}\n                    alignItems={'center'}\n                    justifyContent={'center'}\n                  >\n                    <CoinIcons type={TokenType.single} tokenIcon={[coinJson[coinA]]} />\n                    <Typography\n                      variant={'body2'}\n                      color={'var(--color-text-primary)'}\n                      component={'span'}\n                      marginRight={5}\n                      marginLeft={1 / 2}\n                      alignSelf={'right'}\n                      height={20}\n                      lineHeight={'20px'}\n                    >\n                      {coinB}\n                    </Typography>\n                  </Box>\n                </Box>\n              </Box>\n              <Typography\n                display={'flex'}\n                flexDirection={'column'}\n                component={'span'}\n                justifyContent={'center'}\n                alignItems={'center'}\n                marginTop={7}\n              >\n                {isOrderbook ? (\n                  <Typography component={'span'} variant={'h2'} fontFamily={'Roboto'}>\n                    {totalRewards\n                      ? getValuePrecisionThousand(totalRewards) + ' ' + rewardToken?.simpleName\n                      : EmptyValueTag}\n                  </Typography>\n                ) : (\n                  <Typography component={'span'} variant={'h1'} fontFamily={'Roboto'}>\n                    {getValuePrecisionThousand(APR, 2, 2, 2, true) + '%' || EmptyValueTag}\n                  </Typography>\n                )}\n                <Typography\n                  component={'span'}\n                  color={'textPrimary'}\n                  variant={'h6'}\n                  marginTop={1}\n                  style={{ textTransform: 'uppercase' }}\n                >\n                  {isOrderbook ? t('labelMiningReward') : t('labelAPR')}\n                </Typography>\n              </Typography>\n\n              <Box marginTop={3} marginBottom={2}>\n                <Divider />\n              </Box>\n\n              <DetailWrapperStyled>\n                <Typography component={'span'} color={'textSecondary'} variant={'h6'}>\n                  {t('labelMiningActiveDate')}\n                </Typography>\n                <Typography\n                  component={'span'}\n                  color={'textPrimary'}\n                  variant={'h6'}\n                  fontWeight={400}\n                >\n                  {' ' + moment(duration.from).format(YEAR_DAY_FORMAT) + ' - '}\n                  {moment(duration.to).format(DAY_FORMAT)}\n                </Typography>\n              </DetailWrapperStyled>\n\n              {isAmm && (\n                <DetailWrapperStyled>\n                  <Typography component={'span'} color={'textSecondary'} variant={'h6'}>\n                    {t('labelMiningLiquidity')}\n                  </Typography>\n                  <Typography\n                    component={'span'}\n                    color={'textPrimary'}\n                    variant={'h6'}\n                    fontWeight={400}\n                  >\n                    <Typography\n                      {...bindHover(popLiquidityState)}\n                      style={{\n                        cursor: 'pointer',\n                        borderBottom: '1px dashed var(--color-text-primary)',\n                      }}\n                    >\n                      {t('labelLiquidity') + ' ' + amountU === undefined\n                        ? EmptyValueTag\n                        : PriceTag[CurrencyToTag[currency]] + amountU}\n                    </Typography>\n                    <PopoverPure\n                      className={'arrow-top-center'}\n                      {...bindPopper(popLiquidityState)}\n                      anchorOrigin={{\n                        vertical: 'top',\n                        horizontal: 'center',\n                      }}\n                      transformOrigin={{\n                        vertical: 'bottom',\n                        horizontal: 'center',\n                      }}\n                    >\n                      <Box padding={1.5} paddingLeft={1}>\n                        <Typography\n                          component={'span'}\n                          display={'flex'}\n                          flexDirection={'row'}\n                          justifyContent={'space-between'}\n                          alignItems={'center'}\n                          style={{ textTransform: 'capitalize' }}\n                          color={'textPrimary'}\n                        >\n                          <Box\n                            component={'span'}\n                            className={'logo-icon'}\n                            display={'flex'}\n                            height={'var(--list-menu-coin-size)'}\n                            width={'var(--list-menu-coin-size)'}\n                            alignItems={'center'}\n                            justifyContent={'flex-start'}\n                          >\n                            <CoinIcons type={TokenType.single} tokenIcon={[coinJson[coinA]]} />\n                            <Typography\n                              component={'span'}\n                              color={'var(--color-text-primary)'}\n                              variant={'body2'}\n                              marginLeft={1 / 2}\n                              height={20}\n                              lineHeight={'20px'}\n                            >\n                              {coinA}\n                            </Typography>\n                          </Box>\n\n                          <Typography\n                            component={'span'}\n                            color={'var(--color-text-primary)'}\n                            variant={'body2'}\n                            height={20}\n                            marginLeft={10}\n                            lineHeight={'20px'}\n                          >\n                            {getValuePrecisionThousand(\n                              totalA,\n                              undefined,\n                              undefined,\n                              precisionA,\n                              false,\n                              { floor: true },\n                            )}\n                          </Typography>\n                        </Typography>\n                        <Typography\n                          component={'span'}\n                          display={'flex'}\n                          flexDirection={'row'}\n                          justifyContent={'space-between'}\n                          alignItems={'center'}\n                          marginTop={1 / 2}\n                          style={{ textTransform: 'capitalize' }}\n                        >\n                          <Box\n                            component={'span'}\n                            className={'logo-icon'}\n                            display={'flex'}\n                            height={'var(--list-menu-coin-size)'}\n                            width={'var(--list-menu-coin-size)'}\n                            alignItems={'center'}\n                            justifyContent={'flex-start'}\n                          >\n                            <CoinIcons type={TokenType.single} tokenIcon={[coinJson[coinB]]} />\n                            <Typography\n                              variant={'body2'}\n                              color={'var(--color-text-primary)'}\n                              component={'span'}\n                              marginRight={5}\n                              marginLeft={1 / 2}\n                              alignSelf={'right'}\n                              height={20}\n                              lineHeight={'20px'}\n                            >\n                              {coinB}\n                            </Typography>\n                          </Box>\n\n                          <Typography\n                            variant={'body2'}\n                            color={'var(--color-text-primary)'}\n                            component={'span'}\n                            height={20}\n                            marginLeft={10}\n                            lineHeight={'20px'}\n                          >\n                            {getValuePrecisionThousand(\n                              totalB,\n                              undefined,\n                              undefined,\n                              precisionB,\n                              false,\n                              { floor: true },\n                            )}\n                          </Typography>\n                        </Typography>\n                      </Box>\n                    </PopoverPure>\n                  </Typography>\n                </DetailWrapperStyled>\n              )}\n\n              {isOrderbook && (\n                <DetailWrapperStyled>\n                  <Typography component={'span'} color={'textSecondary'} variant={'h6'}>\n                    {t('labelMiningMaxSpread')}\n                  </Typography>\n                  <Typography\n                    component={'span'}\n                    color={'textPrimary'}\n                    variant={'h6'}\n                    fontWeight={400}\n                  >\n                    {getValuePrecisionThousand(maxSpread, undefined, undefined, 2, true)}\n                    &nbsp;\n                    {'%'}\n                  </Typography>\n                </DetailWrapperStyled>\n              )}\n\n              {!isOrderbook && (\n                <DetailWrapperStyled>\n                  <Typography component={'span'} color={'textSecondary'} variant={'h6'}>\n                    {t('labelMiningActivityReward')}\n                  </Typography>\n                  {isPass ? (\n                    <Typography\n                      component={'span'}\n                      color={'textPrimary'}\n                      variant={'h6'}\n                      fontWeight={400}\n                    >\n                      {getValuePrecisionThousand(totalRewards)}\n                      &nbsp;\n                      {rewardToken?.simpleName}\n                    </Typography>\n                  ) : (\n                    <Typography\n                      {...bindHover(popTotalRewardState)}\n                      component={'span'}\n                      color={'textPrimary'}\n                      variant={'h6'}\n                      fontWeight={400}\n                      style={{\n                        borderBottom: totalRewards\n                          ? '1px dashed var(--color-text-primary)'\n                          : 'none',\n                      }}\n                    >\n                      {getValuePrecisionThousand(totalRewards)}\n                      &nbsp;\n                      {rewardToken?.simpleName}\n                    </Typography>\n                  )}\n                  <PopoverPure\n                    className={'arrow-top-center'}\n                    {...bindPopper(popTotalRewardState)}\n                    anchorOrigin={{\n                      vertical: 'top',\n                      horizontal: 'center',\n                    }}\n                    transformOrigin={{\n                      vertical: 'bottom',\n                      horizontal: 'center',\n                    }}\n                  >\n                    <Box padding={1}>\n                      <Typography\n                        component={'span'}\n                        display={'flex'}\n                        flexDirection={'row'}\n                        justifyContent={'space-between'}\n                        alignItems={'center'}\n                        style={{ textTransform: 'capitalize' }}\n                        color={'textPrimary'}\n                      >\n                        <Typography\n                          component={'span'}\n                          color={'var(--color-text-primary)'}\n                          variant={'body2'}\n                          height={20}\n                          lineHeight={'20px'}\n                        >\n                          {isOrderbook ? orderbookReward : isAmm ? totalAmmReward : orderbookReward}\n                        </Typography>\n                      </Typography>\n                      {coinB && (\n                        <Typography\n                          component={'span'}\n                          display={'flex'}\n                          flexDirection={'row'}\n                          justifyContent={'space-between'}\n                          alignItems={'center'}\n                          marginTop={1 / 2}\n                          style={{ textTransform: 'capitalize' }}\n                        >\n                          <Box\n                            component={'span'}\n                            className={'logo-icon'}\n                            display={'flex'}\n                            height={'var(--list-menu-coin-size)'}\n                            width={'var(--list-menu-coin-size)'}\n                            alignItems={'center'}\n                            justifyContent={'flex-start'}\n                          >\n                            <CoinIcons type={TokenType.single} tokenIcon={[coinJson[coinB]]} />\n\n                            <Typography\n                              variant={'body2'}\n                              color={'var(--color-text-primary)'}\n                              component={'span'}\n                              marginRight={5}\n                              marginLeft={1 / 2}\n                              alignSelf={'right'}\n                              height={20}\n                              lineHeight={'20px'}\n                            >\n                              {coinB}\n                            </Typography>\n                          </Box>\n\n                          <Typography\n                            variant={'body2'}\n                            color={'var(--color-text-primary)'}\n                            component={'span'}\n                            height={20}\n                            marginLeft={10}\n                            lineHeight={'20px'}\n                          >\n                            {getValuePrecisionThousand(\n                              rewardB,\n                              undefined,\n                              undefined,\n                              precisionB,\n                              false,\n                              { floor: true },\n                            )}\n                            &nbsp;\n                            {coinBInfo?.simpleName}\n                          </Typography>\n                        </Typography>\n                      )}\n                    </Box>\n                  </PopoverPure>\n                </DetailWrapperStyled>\n              )}\n\n              {isAmm && (\n                <DetailWrapperStyled>\n                  <Typography component={'span'} color={'textSecondary'} variant={'h6'}>\n                    {t('labelMiningMyShare')}\n                  </Typography>\n                  {myTotalAmmValueDollar ? (\n                    <Typography\n                      {...bindHover(popMyAmmValueState)}\n                      component={'span'}\n                      color={'textPrimary'}\n                      variant={'h6'}\n                      fontWeight={400}\n                      style={{\n                        borderBottom: myTotalAmmValueDollar\n                          ? '1px dashed var(--color-text-primary)'\n                          : 'none',\n                      }}\n                    >\n                      {CurrencyToTag[currency] +\n                        getValuePrecisionThousand(\n                          myTotalAmmValueDollar * (forexMap[currency] ?? 0),\n                          undefined,\n                          undefined,\n                          2,\n                          true,\n                          { isFait: true },\n                        )}\n                    </Typography>\n                  ) : (\n                    <Typography>{EmptyValueTag}</Typography>\n                  )}\n\n                  <PopoverPure\n                    className={'arrow-top-center'}\n                    {...bindPopper(popMyAmmValueState)}\n                    anchorOrigin={{\n                      vertical: 'top',\n                      horizontal: 'center',\n                    }}\n                    transformOrigin={{\n                      vertical: 'bottom',\n                      horizontal: 'center',\n                    }}\n                  >\n                    <Box padding={1.5} paddingLeft={1}>\n                      <Typography\n                        component={'span'}\n                        display={'flex'}\n                        flexDirection={'row'}\n                        justifyContent={'space-between'}\n                        alignItems={'center'}\n                        style={{ textTransform: 'capitalize' }}\n                        color={'textPrimary'}\n                      >\n                        <Box\n                          component={'span'}\n                          className={'logo-icon'}\n                          display={'flex'}\n                          height={'var(--list-menu-coin-size)'}\n                          width={'var(--list-menu-coin-size)'}\n                          alignItems={'center'}\n                          justifyContent={'flex-start'}\n                        >\n                          <CoinIcons type={TokenType.single} tokenIcon={[coinJson[coinA]]} />\n                          <Typography\n                            component={'span'}\n                            color={'var(--color-text-primary)'}\n                            variant={'body2'}\n                            marginLeft={1 / 2}\n                            height={20}\n                            lineHeight={'20px'}\n                          >\n                            {coinA}\n                          </Typography>\n                        </Box>\n\n                        <Typography\n                          component={'span'}\n                          color={'var(--color-text-primary)'}\n                          variant={'body2'}\n                          height={20}\n                          marginLeft={10}\n                          lineHeight={'20px'}\n                        >\n                          {getValuePrecisionThousand(myBalanceA, precisionA, 2, undefined, false, {\n                            floor: true,\n                          })}\n                        </Typography>\n                      </Typography>\n                      <Typography\n                        component={'span'}\n                        display={'flex'}\n                        flexDirection={'row'}\n                        justifyContent={'space-between'}\n                        alignItems={'center'}\n                        marginTop={1 / 2}\n                        style={{ textTransform: 'capitalize' }}\n                      >\n                        <Box\n                          component={'span'}\n                          className={'logo-icon'}\n                          display={'flex'}\n                          height={'var(--list-menu-coin-size)'}\n                          width={'var(--list-menu-coin-size)'}\n                          alignItems={'center'}\n                          justifyContent={'flex-start'}\n                        >\n                          <CoinIcons type={TokenType.single} tokenIcon={[coinJson[coinB]]} />\n                          <Typography\n                            variant={'body2'}\n                            color={'var(--color-text-primary)'}\n                            component={'span'}\n                            marginRight={5}\n                            marginLeft={1 / 2}\n                            alignSelf={'right'}\n                            height={20}\n                            lineHeight={'20px'}\n                          >\n                            {coinB}\n                          </Typography>\n                        </Box>\n\n                        <Typography\n                          variant={'body2'}\n                          color={'var(--color-text-primary)'}\n                          component={'span'}\n                          height={20}\n                          marginLeft={10}\n                          lineHeight={'20px'}\n                        >\n                          {getValuePrecisionThousand(myBalanceB, precisionB, 2, undefined, false, {\n                            floor: true,\n                          })}\n                        </Typography>\n                      </Typography>\n                    </Box>\n                  </PopoverPure>\n                </DetailWrapperStyled>\n              )}\n\n              <DetailWrapperStyled>\n                <Typography component={'span'} color={'textSecondary'} variant={'h6'}>\n                  {t('labelMiningMyReward')}\n                </Typography>\n                <Typography\n                  onClick={myRewards ? handleMyRewardClick : undefined}\n                  component={'span'}\n                  color={'textPrimary'}\n                  variant={'h6'}\n                  fontWeight={400}\n                >\n                  {myRewards === 0\n                    ? EmptyValueTag\n                    : getValuePrecisionThousand(myRewards, undefined, undefined, undefined, true, {\n                        isFait: true,\n                        floor: true,\n                      }) + rewardToken?.simpleName}\n                </Typography>\n              </DetailWrapperStyled>\n            </CardContent>\n            <CardActions>\n              <CardActionBoxStyled\n                width={'100%'}\n                display={'flex'}\n                flexDirection={'column'}\n                justifyContent={'center'}\n                alignItems={'center'}\n              >\n                <Button\n                  fullWidth\n                  variant={'contained'}\n                  size={'large'}\n                  disabled={!!isPass || isComing}\n                  color={'primary'}\n                  onClick={handleClick}\n                >\n                  {isAmm\n                    ? t(\n                        isPass\n                          ? 'labelEndLiquidityBtn'\n                          : isComing\n                          ? 'labelComingSoon'\n                          : 'labelAddLiquidityBtn',\n                      )\n                    : t(isPass ? 'labelEndLiquidityBtn' : 'labelMiningPlaceOrderBtn')}\n                </Button>\n                <ViewDetailStyled\n                  onClick={() => handleViewDetail()}\n                  component={'a'}\n                  variant={'body1'}\n                  color={'var(--color-text-secondary)'}\n                  marginTop={1}\n                >\n                  {t('labelMiningViewDetails')}\n                  &nbsp;\n                  {'>'}\n                </ViewDetailStyled>\n              </CardActionBoxStyled>\n            </CardActions>\n          </CardStyled>\n        )\n      },\n    ),\n  ),\n) as <T>(props: AmmCardProps<T> & React.RefAttributes<any>) => JSX.Element\n"
  },
  {
    "path": "packages/component-lib/src/components/block/AmmPairDetail.tsx",
    "content": "import { Box, Typography } from '@mui/material'\nimport React from 'react'\n\nimport {\n  EmptyValueTag,\n  getValuePrecisionThousand,\n  myLog,\n  TokenType,\n} from '@loopring-web/common-resources'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport styled from '@emotion/styled'\nimport { CoinIcons } from '../tableList'\nimport { useSettings } from '../../stores'\n\nexport const AmmPairDetail = ({\n  coinA,\n  coinB,\n  balanceA,\n  balanceB,\n}: {\n  coinA: string\n  coinB: string\n  balanceA: string | undefined\n  balanceB: string | undefined\n}) => {\n  const { coinJson } = useSettings()\n  return (\n    <Box padding={1.5} paddingLeft={1}>\n      <Typography\n        component={'span'}\n        display={'flex'}\n        flexDirection={'row'}\n        justifyContent={'space-between'}\n        alignItems={'center'}\n        style={{ textTransform: 'capitalize' }}\n        color={'textPrimary'}\n        paddingBottom={1}\n      >\n        <Box\n          component={'span'}\n          className={'logo-icon'}\n          display={'flex'}\n          height={'var(--list-menu-coin-size)'}\n          width={'var(--list-menu-coin-size)'}\n          alignItems={'center'}\n          justifyContent={'flex-start'}\n        >\n          <CoinIcons type={TokenType.single} tokenIcon={[coinJson[coinA]]} />\n          <Typography\n            component={'span'}\n            color={'var(--color-text-primary)'}\n            variant={'body1'}\n            marginLeft={1 / 2}\n            height={20}\n            lineHeight={'20px'}\n          >\n            {coinA}\n          </Typography>\n        </Box>\n\n        <Typography\n          component={'span'}\n          color={'var(--color-text-primary)'}\n          variant={'body1'}\n          height={20}\n          marginLeft={10}\n          lineHeight={'20px'}\n        >\n          {balanceA ? balanceA : EmptyValueTag}\n        </Typography>\n      </Typography>\n      <Typography\n        component={'span'}\n        display={'flex'}\n        flexDirection={'row'}\n        justifyContent={'space-between'}\n        alignItems={'center'}\n        marginTop={1 / 2}\n        style={{ textTransform: 'capitalize' }}\n      >\n        <Box\n          component={'span'}\n          className={'logo-icon'}\n          display={'flex'}\n          height={'var(--list-menu-coin-size)'}\n          width={'var(--list-menu-coin-size)'}\n          alignItems={'center'}\n          justifyContent={'flex-start'}\n        >\n          <CoinIcons type={TokenType.single} tokenIcon={[coinJson[coinB]]} />\n          <Typography\n            variant={'body1'}\n            color={'var(--color-text-primary)'}\n            component={'span'}\n            marginRight={5}\n            marginLeft={1 / 2}\n            alignSelf={'right'}\n            height={20}\n            lineHeight={'20px'}\n          >\n            {coinB}\n          </Typography>\n        </Box>\n\n        <Typography\n          variant={'body1'}\n          color={'var(--color-text-primary)'}\n          component={'span'}\n          height={20}\n          marginLeft={10}\n          lineHeight={'20px'}\n        >\n          {balanceB ? balanceB : EmptyValueTag}\n        </Typography>\n      </Typography>\n    </Box>\n  )\n}\n\nexport const AmmAPRDetail = withTranslation('tables')(\n  ({\n    self = 0,\n    event = 0,\n    fee = 0,\n    t,\n  }: {\n    self?: number\n    event?: number\n    fee?: number\n  } & WithTranslation) => {\n    return (\n      <Box padding={1.5} paddingLeft={1}>\n        <Typography\n          component={'span'}\n          display={'flex'}\n          flexDirection={'row'}\n          justifyContent={'space-between'}\n          alignItems={'center'}\n          style={{ textTransform: 'capitalize' }}\n          color={'textPrimary'}\n        >\n          <Typography\n            component={'span'}\n            color={'var(--color-text-primary)'}\n            variant={'body1'}\n            marginLeft={1 / 2}\n            height={20}\n            lineHeight={'20px'}\n          >\n            {t('labelAprPool')}\n          </Typography>\n\n          <Typography\n            component={'span'}\n            color={'var(--color-text-primary)'}\n            variant={'body1'}\n            height={20}\n            marginLeft={10}\n            lineHeight={'20px'}\n          >\n            {self === 0 || typeof self === 'undefined'\n              ? EmptyValueTag\n              : getValuePrecisionThousand(self, 2, 2, 2, true) + '%'}\n          </Typography>\n        </Typography>\n        <Typography\n          component={'span'}\n          display={'flex'}\n          flexDirection={'row'}\n          justifyContent={'space-between'}\n          alignItems={'center'}\n          style={{ textTransform: 'capitalize' }}\n          color={'textPrimary'}\n        >\n          <Typography\n            component={'span'}\n            color={'var(--color-text-primary)'}\n            variant={'body1'}\n            marginLeft={1 / 2}\n            height={20}\n            lineHeight={'20px'}\n          >\n            {t('labelAprFee')}\n          </Typography>\n          <Typography\n            component={'span'}\n            color={'var(--color-text-primary)'}\n            variant={'body1'}\n            height={20}\n            marginLeft={10}\n            lineHeight={'20px'}\n          >\n            {fee === 0 || typeof fee === 'undefined'\n              ? EmptyValueTag\n              : getValuePrecisionThousand(fee, 2, 2, 2, true) + '%'}\n          </Typography>\n        </Typography>\n        <Typography\n          component={'span'}\n          display={'flex'}\n          flexDirection={'row'}\n          justifyContent={'space-between'}\n          alignItems={'center'}\n          style={{ textTransform: 'capitalize' }}\n          color={'textPrimary'}\n        >\n          <Typography\n            component={'span'}\n            color={'var(--color-text-primary)'}\n            variant={'body1'}\n            marginLeft={1 / 2}\n            height={20}\n            lineHeight={'20px'}\n          >\n            {t('labelAprEvent')}\n          </Typography>\n\n          <Typography\n            component={'span'}\n            color={'var(--color-text-primary)'}\n            variant={'body1'}\n            height={20}\n            marginLeft={10}\n            lineHeight={'20px'}\n          >\n            {event === 0 || typeof event === 'undefined'\n              ? EmptyValueTag\n              : getValuePrecisionThousand(event, 2, 2, 2, true) + '%'}\n          </Typography>\n        </Typography>\n      </Box>\n    )\n  },\n) as (props: { self?: number; event?: number; fee?: number }) => JSX.Element\n\nconst TypographyStyle = styled(Typography)`\n  .rewardItem:not(:last-child) {\n    &:after {\n      display: inline-flex;\n      content: '+';\n      padding: 0 ${({ theme }) => theme.unit + 'px'};\n    }\n  }\n` as typeof Typography\ntype AmmPairDetailProps = {\n  feeA: number | undefined\n  feeB: number | undefined\n  rewards: Array<{ tokenSymbol: string; amount: number | undefined }>\n  extraRewards: Array<{ tokenSymbol: string; amount: number | undefined }>\n  tokenMap: { [key: string]: any }\n  coinA: string\n  coinB: string\n}\nexport const AmmRewardsDetail = withTranslation('tables')(\n  ({\n    feeA,\n    feeB,\n    rewards,\n    extraRewards,\n    tokenMap,\n    coinA,\n    coinB,\n    t,\n  }: AmmPairDetailProps & WithTranslation) => {\n    // labelRewardFee\n    // labelRewardReward\n    // labelRewardExtra\n    myLog('coinB', coinB)\n    return (\n      <Box padding={1.5} paddingLeft={1}>\n        <Typography\n          component={'span'}\n          display={'flex'}\n          flexDirection={'row'}\n          justifyContent={'space-between'}\n          alignItems={'center'}\n          style={{ textTransform: 'capitalize' }}\n          color={'textPrimary'}\n        >\n          <Typography\n            component={'span'}\n            color={'var(--color-text-primary)'}\n            variant={'body1'}\n            marginLeft={1 / 2}\n            height={20}\n            lineHeight={'20px'}\n          >\n            {t('labelRewardFee')}\n          </Typography>\n\n          <TypographyStyle\n            component={'span'}\n            color={'var(--color-text-primary)'}\n            variant={'body1'}\n            height={20}\n            marginLeft={10}\n            lineHeight={'20px'}\n          >\n            <Typography component={'span'} className={'rewardItem'}>\n              {(feeA\n                ? getValuePrecisionThousand(\n                    feeA,\n                    tokenMap[coinA].precision,\n                    tokenMap[coinA].precision,\n                    tokenMap[coinA].precision,\n                    true,\n                  )\n                : EmptyValueTag) + ` ${coinA}`}\n            </Typography>\n            <Typography component={'span'} className={'rewardItem'}>\n              {(feeB\n                ? getValuePrecisionThousand(\n                    feeB,\n                    tokenMap[coinB].precision,\n                    tokenMap[coinB].precision,\n                    tokenMap[coinB].precision,\n                    true,\n                  )\n                : EmptyValueTag) + ` ${coinB}`}\n            </Typography>\n          </TypographyStyle>\n        </Typography>\n        <Typography\n          component={'span'}\n          display={'flex'}\n          flexDirection={'row'}\n          justifyContent={'space-between'}\n          alignItems={'center'}\n          style={{ textTransform: 'capitalize' }}\n          color={'textPrimary'}\n        >\n          <Typography\n            component={'span'}\n            color={'var(--color-text-primary)'}\n            variant={'body1'}\n            marginLeft={1 / 2}\n            height={20}\n            lineHeight={'20px'}\n          >\n            {t('labelRewardReward')}\n          </Typography>\n          <TypographyStyle\n            component={'span'}\n            color={'var(--color-text-primary)'}\n            variant={'body1'}\n            height={20}\n            marginLeft={10}\n            lineHeight={'20px'}\n          >\n            {rewards.length ? (\n              <>\n                {rewards.map((item: any, index: number) => {\n                  return (\n                    <React.Fragment key={item.id + index}>\n                      {item?.amount ? (\n                        <Typography component={'span'} className={'rewardItem'}>\n                          {getValuePrecisionThousand(\n                            item.amount,\n                            tokenMap[item.symbol].precision,\n                            tokenMap[item.symbol].precision,\n                            tokenMap[item.symbol].precision,\n                            true,\n                          )` ${coinA}`}{' '}\n                        </Typography>\n                      ) : (\n                        <></>\n                      )}\n                    </React.Fragment>\n                  )\n                })}\n              </>\n            ) : (\n              EmptyValueTag\n            )}\n          </TypographyStyle>\n        </Typography>\n        <Typography\n          component={'span'}\n          display={'flex'}\n          flexDirection={'row'}\n          justifyContent={'space-between'}\n          alignItems={'center'}\n          style={{ textTransform: 'capitalize' }}\n          color={'textPrimary'}\n        >\n          <Typography\n            component={'span'}\n            color={'var(--color-text-primary)'}\n            variant={'body1'}\n            marginLeft={1 / 2}\n            height={20}\n            lineHeight={'20px'}\n          >\n            {t('labelRewardExtra')}\n          </Typography>\n\n          <TypographyStyle\n            component={'span'}\n            color={'var(--color-text-primary)'}\n            variant={'body1'}\n            height={20}\n            marginLeft={10}\n            lineHeight={'20px'}\n          >\n            {extraRewards?.length ? (\n              <>\n                {extraRewards?.map((item: any, index: number) => {\n                  return (\n                    <React.Fragment key={item.id + index}>\n                      {item?.amount ? (\n                        <Typography component={'span'} className={'rewardItem'}>\n                          {getValuePrecisionThousand(\n                            item.amount,\n                            tokenMap[item.symbol].precision,\n                            tokenMap[item.symbol].precision,\n                            tokenMap[item.symbol].precision,\n                            true,\n                          )` ${coinA}`}{' '}\n                        </Typography>\n                      ) : (\n                        <></>\n                      )}\n                    </React.Fragment>\n                  )\n                })}\n              </>\n            ) : (\n              EmptyValueTag\n            )}\n          </TypographyStyle>\n        </Typography>\n      </Box>\n    )\n  },\n) as (props: AmmPairDetailProps) => JSX.Element\n"
  },
  {
    "path": "packages/component-lib/src/components/block/AssetTitle.tsx",
    "content": "import { Box, Grid, IconButton, Typography } from '@mui/material'\nimport {\n  getValuePrecisionThousand,\n  HeaderMenuItemInterface,\n  HiddenTag,\n  HideIcon,\n  L1L2_NAME_DEFINED,\n  MapChainId,\n  RouterPath,\n  subMenuLayer2,\n  TradeBtnStatus,\n  ViewIcon,\n} from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { useTranslation, withTranslation, WithTranslation } from 'react-i18next'\nimport { AssetTitleMobileProps, AssetTitleProps } from './Interface'\nimport styled from '@emotion/styled'\nimport { DropdownIconStyled } from '../tradePanel'\nimport { AnimationArrow, Button, ButtonListRightStyled } from './../'\nimport { useHistory, useRouteMatch } from 'react-router-dom'\nimport { useSettings } from '../../stores'\n\nconst BoxStyled = styled(Box)`\n  color: var(--color-text-secondary);\n\n  .MuiButtonBase-root {\n    color: var(--color-text-secondary);\n  }\n` as typeof Box\n\nexport const AssetTitle = withTranslation('common')(\n  ({\n    t,\n    assetInfo,\n    accountId,\n    onShowSend,\n    onShowReceive,\n    hideL2Assets,\n    setHideL2Assets,\n    assetBtnStatus,\n    isWebEarn,\n    forexMap,\n    onClickBridge,\n    showBridgeBtn = false,\n  }: AssetTitleProps & WithTranslation) => {\n    const history = useHistory()\n    const { defaultNetwork, currency } = useSettings()\n    const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n    return (\n      <Grid container spacing={2} justifyContent={'space-between'} alignItems={'flex-start'}>\n        <Grid item xs={7} display={'flex'} flexDirection={'column'}>\n          <BoxStyled\n            component={'span'}\n            display={'flex'}\n            alignItems={'center'}\n            justifyContent={'flex-start'}\n            marginBottom={'16px'}\n          >\n            <Typography\n              component={'span'}\n              variant={'body1'}\n              paddingRight={3}\n              color={'textSecondary'}\n            >\n              {isWebEarn ? (\n                t('labelEarnVaultTitle')\n              ) : (\n                <>\n                  {t('labelAssetTitle', {\n                    loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                  })}\n                  {` (UID: ${accountId})`}\n                </>\n              )}\n\n              <IconButton\n                size={'small'}\n                // color={'secondary'}\n                onClick={() => setHideL2Assets(!hideL2Assets)}\n                aria-label={t('labelShowAccountInfo')}\n              >\n                {!hideL2Assets ? <ViewIcon /> : <HideIcon />}\n              </IconButton>\n            </Typography>\n          </BoxStyled>\n\n          <Typography\n            component={'span'}\n            display={'flex'}\n            alignItems={'center'}\n            justifyContent={'flex-start'}\n            marginTop={1}\n          >\n            <Typography component={'span'} variant={'h1'}>\n              {!hideL2Assets && assetInfo.priceTag}\n            </Typography>\n            {!hideL2Assets ? (\n              <Typography component={'span'} variant={'h1'}>\n                {assetInfo.totalAsset\n                  ? getValuePrecisionThousand(\n                      sdk.toBig(assetInfo.totalAsset).times(forexMap[currency] ?? 0),\n                      2,\n                      2,\n                      2,\n                      true,\n                      { floor: true },\n                    )\n                  : '0.00'}\n              </Typography>\n            ) : (\n              <Typography component={'span'} variant={'h1'}>\n                {HiddenTag}\n              </Typography>\n            )}\n          </Typography>\n        </Grid>\n        <ButtonListRightStyled\n          item\n          xs={5}\n          display={'flex'}\n          flexDirection={'row'}\n          justifyContent={'flex-end'}\n        >\n          {isWebEarn ? (\n            <>\n              <Button\n                variant={'contained'}\n                size={'small'}\n                color={'primary'}\n                disabled={assetBtnStatus === TradeBtnStatus.LOADING}\n                onClick={() => onShowReceive()}\n              >\n                {t('labelDeposit')}\n              </Button>\n              <Button\n                variant={'outlined'}\n                size={'medium'}\n                color={'secondary'}\n                disabled={assetBtnStatus === TradeBtnStatus.LOADING}\n                onClick={() => onShowSend()}\n              >\n                {t('labelWithdrawBtn')}\n              </Button>\n              {showBridgeBtn && (\n                <Button\n                  variant={'outlined'}\n                  size={'medium'}\n                  color={'secondary'}\n                  onClick={onClickBridge}\n                >\n                  {t('Bridge')}\n                </Button>\n              )}\n            </>\n          ) : (\n            <>\n              <Button\n                variant={'contained'}\n                size={'small'}\n                color={'primary'}\n                disabled={assetBtnStatus === TradeBtnStatus.LOADING}\n                onClick={() => onShowSend()}\n              >\n                {t('labelSendAssetBtn')}\n              </Button>\n              <Button\n                variant={'outlined'}\n                size={'medium'}\n                color={'secondary'}\n                disabled={assetBtnStatus === TradeBtnStatus.LOADING}\n                onClick={() => onShowReceive()}\n              >\n                {t('labelAddAssetBtn')}\n              </Button>\n            </>\n          )}\n          <Button\n            variant={'outlined'}\n            size={'medium'}\n            color={'secondary'}\n            onClick={() => history.push(`${RouterPath.l2records}`)}\n          >\n            {t('labelTransactions')}\n          </Button>\n        </ButtonListRightStyled>\n      </Grid>\n    )\n  },\n)\n\nexport const AssetTitleMobile = ({\n  assetInfo,\n  accountId,\n  onShowSend,\n  onShowReceive,\n  hideL2Assets,\n  setHideL2Assets,\n}: AssetTitleMobileProps) => {\n  const { hideL2Action, setHideL2Action, defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const { t } = useTranslation(['common', 'layout'])\n  let match: any = useRouteMatch('/l2assets/:item')\n  const history = useHistory()\n  const label = Reflect.ownKeys(subMenuLayer2)\n    .reduce((pre, item) => [...pre, ...subMenuLayer2[item]], [] as HeaderMenuItemInterface[])\n    .find((item) => RegExp(item?.router?.path ?? '').test(match?.url ?? ''))?.label?.i18nKey\n  return (\n    <Box display={'flex'} flexDirection={'column'} marginBottom={2}>\n      <Box\n        display={'flex'}\n        flexDirection={'column'}\n        justifyContent={'space-between'}\n        position={'relative'}\n        alignItems={'flex-end'}\n      >\n        <Typography component={'h3'} variant={'h4'} position={'absolute'} left={2} top={2}>\n          {t(label ?? 'labelAssets', {\n            ns: 'layout',\n            loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n            l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n          })}\n        </Typography>\n        <Typography\n          component={'span'}\n          variant={'body1'}\n          display={'inline-flex'}\n          alignItems={'center'}\n          marginBottom={1}\n        >\n          {t('labelAssetMobileTitle', {\n            loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n            l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n            l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n            ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n          })}\n          {` (UID: ${accountId})`}\n          <IconButton\n            size={'small'}\n            // color={'secondary'}\n            onClick={() => setHideL2Assets(!hideL2Assets)}\n            aria-label={t('labelShowAccountInfo')}\n          >\n            {!hideL2Assets ? <ViewIcon fontSize={'large'} /> : <HideIcon fontSize={'large'} />}\n          </IconButton>\n        </Typography>\n        <Typography\n          component={'span'}\n          display={'flex'}\n          alignItems={'center'}\n          justifyContent={'flex-start'}\n          marginTop={1}\n        >\n          <Typography component={'span'} paddingRight={1} variant={'h3'}>\n            {assetInfo.priceTag}\n          </Typography>\n          {!hideL2Assets ? (\n            <Typography component={'span'} variant={'h3'}>\n              {assetInfo.totalAsset\n                ? getValuePrecisionThousand(assetInfo.totalAsset, 2, 2, 2, true, { floor: true })\n                : '0.00'}\n            </Typography>\n          ) : (\n            <Typography component={'span'} variant={'h3'}>\n              &#10033;&#10033;&#10033;&#10033;.&#10033;&#10033;\n            </Typography>\n          )}\n        </Typography>\n      </Box>\n      <Box\n        component={'span'}\n        display={'flex'}\n        alignItems={'center'}\n        style={{ cursor: 'pointer' }}\n        justifyContent={'center'}\n        onClick={() => setHideL2Action(!hideL2Action)}\n        marginBottom={1}\n      >\n        {!hideL2Action ? (\n          <DropdownIconStyled status={hideL2Action ? 'down' : 'up'} fontSize={'medium'} />\n        ) : (\n          <AnimationArrow className={'arrowCta'} />\n        )}\n      </Box>\n      {!hideL2Action && (\n        <Grid container spacing={2}>\n          <Grid item xs={4}>\n            <Button\n              fullWidth\n              variant={'contained'}\n              size={'small'}\n              color={'primary'}\n              onClick={() => onShowSend()}\n            >\n              {t('labelSendAssetBtn')}\n            </Button>\n          </Grid>\n          <Grid item xs={4}>\n            <Button\n              fullWidth\n              variant={'contained'}\n              size={'small'}\n              color={'primary'}\n              onClick={() => onShowReceive()}\n            >\n              {t('labelAddAssetBtn')}\n            </Button>\n          </Grid>\n          <Grid item xs={4}>\n            <Button\n              fullWidth\n              variant={'outlined'}\n              size={'medium'}\n              color={'secondary'}\n              onClick={() => history.push(`${RouterPath.l2records}`)}\n            >\n              {t('labelTransactions')}\n            </Button>\n          </Grid>\n          {/*<Grid item xs={4}>*/}\n          {/*  <Button*/}\n          {/*    fullWidth*/}\n          {/*    variant={\"outlined\"}*/}\n          {/*    size={\"medium\"}*/}\n          {/*    color={\"primary\"}*/}\n          {/*    onClick={() => onShowTransfer()}*/}\n          {/*  >*/}\n          {/*    {t(\"labelL2toL2\")}*/}\n          {/*  </Button>*/}\n          {/*</Grid>*/}\n          {/*<Grid item xs={4}>*/}\n          {/*  <Button*/}\n          {/*    fullWidth*/}\n          {/*    variant={\"outlined\"}*/}\n          {/*    size={\"medium\"}*/}\n          {/*    color={\"primary\"}*/}\n          {/*    onClick={() => onShowWithdraw()}*/}\n          {/*  >*/}\n          {/*    {t(\"labelL2toL1\")}*/}\n          {/*  </Button>*/}\n          {/*</Grid>*/}\n        </Grid>\n      )}\n    </Box>\n  )\n}\n\nexport const AssetTitleMobileEarn = ({\n  assetInfo,\n  onShowSend,\n  onShowReceive,\n  hideL2Assets,\n  setHideL2Assets,\n  onClickBridge,\n  showBridgeBtn,\n}: AssetTitleMobileProps) => {\n  const { t } = useTranslation(['common', 'layout'])\n  const history = useHistory()\n  return (\n    <Box display={'flex'} flexDirection={'column'} marginBottom={8}>\n      <Box\n        display={'flex'}\n        flexDirection={'column'}\n        justifyContent={'space-between'}\n        position={'relative'}\n      >\n        <Typography\n          component={'span'}\n          variant={'body1'}\n          display={'inline-flex'}\n          alignItems={'center'}\n          marginBottom={1}\n          color={'var(--color-text-secondary)'}\n        >\n          {t('labelTotalPortfolio')}\n          <IconButton\n            size={'small'}\n            onClick={() => setHideL2Assets(!hideL2Assets)}\n            aria-label={t('labelShowAccountInfo')}\n          >\n            {!hideL2Assets ? <ViewIcon fontSize={'large'} /> : <HideIcon fontSize={'large'} />}\n          </IconButton>\n        </Typography>\n        <Typography\n          component={'span'}\n          display={'flex'}\n          alignItems={'center'}\n          justifyContent={'flex-start'}\n          marginTop={1}\n        >\n          <Typography component={'span'} paddingRight={1} variant={'h4'}>\n            {assetInfo.priceTag}\n          </Typography>\n          {!hideL2Assets ? (\n            <Typography component={'span'} variant={'h4'}>\n              {assetInfo.totalAsset\n                ? getValuePrecisionThousand(assetInfo.totalAsset, 2, 2, 2, true, { floor: true })\n                : '0.00'}\n            </Typography>\n          ) : (\n            <Typography component={'span'} variant={'h4'}>\n              &#10033;&#10033;&#10033;&#10033;.&#10033;&#10033;\n            </Typography>\n          )}\n        </Typography>\n      </Box>\n\n      <Box mt={4}>\n        <Button\n          variant={'contained'}\n          size={'small'}\n          color={'primary'}\n          onClick={() => onShowReceive()}\n          sx={{ mr: 2 }}\n        >\n          {t('labelDeposit')}\n        </Button>\n\n        <Button\n          variant={'outlined'}\n          size={'medium'}\n          color={'primary'}\n          onClick={() => onShowSend()}\n          sx={{ mr: 2 }}\n        >\n          {t('labelWithdrawBtn')}\n        </Button>\n\n        {showBridgeBtn && (\n          <Button\n            variant={'outlined'}\n            size={'medium'}\n            color={'secondary'}\n            onClick={onClickBridge}\n          >\n            {t('Bridge')}\n          </Button>\n        )}\n\n        <Button\n          variant={'outlined'}\n          size={'medium'}\n          color={'secondary'}\n          onClick={() => history.push(`${RouterPath.l2records}`)}\n        >\n          {t('labelTransactions')}\n        </Button>\n        {/*<Grid item xs={4}>*/}\n        {/*  <Button*/}\n        {/*    fullWidth*/}\n        {/*    variant={\"outlined\"}*/}\n        {/*    size={\"medium\"}*/}\n        {/*    color={\"primary\"}*/}\n        {/*    onClick={() => onShowTransfer()}*/}\n        {/*  >*/}\n        {/*    {t(\"labelL2toL2\")}*/}\n        {/*  </Button>*/}\n        {/*</Grid>*/}\n        {/*<Grid item xs={4}>*/}\n        {/*  <Button*/}\n        {/*    fullWidth*/}\n        {/*    variant={\"outlined\"}*/}\n        {/*    size={\"medium\"}*/}\n        {/*    color={\"primary\"}*/}\n        {/*    onClick={() => onShowWithdraw()}*/}\n        {/*  >*/}\n        {/*    {t(\"labelL2toL1\")}*/}\n        {/*  </Button>*/}\n        {/*</Grid>*/}\n      </Box>\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/block/Block.stories.tsx",
    "content": "import styled from '@emotion/styled'\nimport { Meta, Story } from '@storybook/react'\nimport { MemoryRouter } from 'react-router-dom'\nimport { Grid } from '@mui/material'\nimport {\n  AmmCardProps,\n  CoinInfo,\n  FloatTag,\n  PriceTag,\n  TradeBtnStatus,\n} from '@loopring-web/common-resources'\nimport { coinMap, CoinType, FOREXMAP } from '../../static'\nimport { withTranslation } from 'react-i18next'\nimport {\n  AssetTitle,\n  AssetTitleProps,\n  RedPacketBgOpened,\n  RedPacketClock,\n  RedPacketDetail,\n  RedPacketOpen,\n  RedPacketQRCode,\n  RedPacketTimeout,\n  TradeTitle,\n  VipPanel,\n} from './'\nimport { SettingPanel } from './SettingPanel'\nimport { MarketBlock } from './MarketBlock'\n// import { PoolDetailTitle } from './PoolDetailTitle';\nimport { AmmCard } from './AmmCard'\nimport React from 'react'\n\nconst Style = styled.div`\n  background: var(--color-global-bg);\n  height: 100%;\n  flex: 1;\n`\n\nconst vipData = [\n  {\n    level: 'VIP 0',\n    tradeVolume: '< 10,000 LRC',\n    rule: '1,000.00',\n    balance: '1,000.00',\n    maker: '1,000.00',\n    taker: '1,000.00',\n  },\n]\nconst TradeTitleWrap = withTranslation('common')((rest) => {\n  // let tradeData: any = {sell: {belong: undefined}, buy: {belong: undefined}};\n  let props: any = {\n    // swapTradeData: tradeData,\n    coinAInfo: coinMap.LRC,\n    coinBInfo: coinMap.ETH,\n  }\n  return (\n    <>\n      <Grid item>\n        <TradeTitle\n          {...{\n            ...rest,\n            ...props,\n          }}\n        />\n      </Grid>\n      <Grid item>\n        <TradeTitle\n          {...{\n            ...rest,\n            ...props,\n            tradeFloat: {\n              priceU: +123,\n              timeUnit: '24h',\n              change: 100,\n              close: 121,\n            },\n          }}\n        />\n      </Grid>\n      <Grid item>\n        <TradeTitle\n          {...{\n            ...rest,\n            ...props,\n            tradeFloat: {\n              priceU: -123,\n              timeUnit: '24h',\n              change: 100,\n              close: 121,\n            },\n          }}\n        />\n      </Grid>\n    </>\n  )\n})\n\nconst AmmCardWrap = () => {\n  const ref = React.createRef()\n  const ammInfo: AmmCardProps<CoinType> = {\n    handleClick(): void {},\n    // ammCalcData,\n    forexMap: FOREXMAP,\n    coinAInfo: coinMap.ETH as CoinInfo<CoinType>,\n    coinBInfo: coinMap.LRC as CoinInfo<CoinType>,\n    // @ts-ignore\n    activity: {\n      totalRewards: 241232132,\n      myRewards: 1232.123,\n      rewardToken: coinMap.ETH as CoinInfo<CoinType>,\n      duration: {\n        from: new Date('2021-1-1'),\n        to: new Date(),\n      },\n    },\n    APR: 56,\n    tradeFloat: {\n      priceU: 123,\n      change: '0%',\n      timeUnit: '24h',\n      volume: Number('112312312'),\n      floatTag: FloatTag.none,\n    },\n    totalLPToken: 12132131,\n    totalA: 0.002,\n    totalB: 12344,\n    totalAU: 0.002,\n    totalBU: 12344,\n    rewardToken: 'LRC',\n    rewardA: 13,\n    feeA: 121,\n    feeB: 1232,\n    isNew: true,\n    isActivity: false,\n  }\n\n  return <AmmCard ref={ref} {...{ ...ammInfo }} />\n}\n\nconst MarketWrap = withTranslation('common')((rest) => {\n  let props: any = {\n    ...rest,\n    forexMap: FOREXMAP,\n    coinAInfo: coinMap.ETH,\n    coinBInfo: coinMap.LRC,\n    tradeFloat: {\n      priceU: +123,\n      change: '+15%',\n      timeUnit: '24h',\n      volume: '112312312 USBD',\n      floatTag: FloatTag.increase,\n    },\n  }\n  const RowStyled = styled(Grid)`\n    & .MuiGrid-root:not(:last-of-type) > div {\n      margin-right: ${({ theme }) => theme.unit * 3}px;\n    }\n  ` as typeof Grid\n  return (\n    <>\n      <RowStyled container>\n        <Grid item xs={3}>\n          <MarketBlock {...{ ...props }} />\n        </Grid>\n        <Grid item xs={3}>\n          <MarketBlock\n            {...{\n              ...props,\n              tradeFloat: {\n                priceU: 123,\n                change: '0%',\n                timeUnit: '24h',\n                volume: '112312312 USBD',\n                floatTag: FloatTag.none,\n              },\n            }}\n          />\n        </Grid>\n        <Grid item xs={3}>\n          <MarketBlock\n            {...{\n              ...props,\n              tradeFloat: {\n                priceU: 123,\n                change: '-15%',\n                timeUnit: '24h',\n                volume: '112312312 USBD',\n                floatTag: FloatTag.decrease,\n              },\n            }}\n          />\n        </Grid>\n        <Grid item xs={3}>\n          <MarketBlock {...{ ...props }} />\n        </Grid>\n      </RowStyled>\n    </>\n  )\n})\n\nconst SettingPanelWrap = (_rest: any) => {\n  return <SettingPanel />\n}\n\nconst AssetTitleWrap = (rest: any) => {\n  // const dispatch = useDispatch();\n  const assetTitleProps: AssetTitleProps = {\n    onShowReceive: () => {},\n    onShowSend: () => {},\n    accountId: 0,\n    setHideL2Assets: () => undefined,\n    hideL2Assets: false,\n    assetBtnStatus: TradeBtnStatus.AVAILABLE,\n    assetInfo: {\n      totalAsset: 123456.789,\n      priceTag: PriceTag.Dollar,\n    },\n  }\n  return (\n    <>\n      <Grid item xs={12}>\n        <AssetTitle\n          {...{\n            ...rest,\n            ...assetTitleProps,\n          }}\n        />\n      </Grid>\n    </>\n  )\n}\nconst Template: Story<any> = withTranslation('common')((...rest) => {\n  const url = `https://loopring.io/wallet?redpacket&id=${'sfgffddd'}&referrer=${'0x234234'}`\n\n  // @ts-ignore\n  // @ts-ignore\n  return (\n    <Style>\n      <MemoryRouter initialEntries={['/']}>\n        <h4>MarketWrap row</h4>\n        <MarketWrap />\n\n        <h4>Trade Title</h4>\n        <Grid\n          container\n          spacing={2}\n          alignContent={'center'}\n          justifyContent={'flex-start'}\n          marginBottom={2}\n        >\n          <TradeTitleWrap />\n        </Grid>\n        {/*<h4>Amm Detail Title</h4>*/}\n        {/*<Grid container spacing={2} alignContent={'center'} justifyContent={'flex-start'} marginBottom={2}>*/}\n        {/*    <PoolDetailTitleWrap/>*/}\n        {/*</Grid>*/}\n        <h4>Amm Card</h4>\n        <Grid\n          container\n          spacing={2}\n          alignContent={'center'}\n          justifyContent={'flex-start'}\n          marginBottom={2}\n        >\n          <Grid item md={3} xs={4} lg={4}>\n            <AmmCardWrap />\n          </Grid>\n          <Grid item md={3} xs={4} lg={4}>\n            <AmmCardWrap />\n          </Grid>\n          <Grid item md={3} xs={4} lg={4}>\n            <AmmCardWrap />\n          </Grid>\n        </Grid>\n        <h4>Asset Title</h4>\n        <Grid\n          container\n          spacing={2}\n          alignContent={'center'}\n          justifyContent={'flex-start'}\n          marginBottom={2}\n        >\n          <AssetTitleWrap />\n        </Grid>\n\n        <h4>Setting Panel</h4>\n        <Grid\n          container\n          spacing={2}\n          alignContent={'stretch'}\n          justifyContent={'stretch'}\n          marginBottom={2}\n        >\n          <Grid item width={460}>\n            <SettingPanelWrap />\n          </Grid>\n        </Grid>\n        <h4>Red Pock</h4>\n        <Grid container spacing={2} alignContent={'stretch'} justifyContent={'stretch'} marginY={2}>\n          <Grid item>\n            <RedPacketOpen\n              amountStr={'1,000 LRC'}\n              sender={'0x01....0101'}\n              memo={'back test back test back test back test  back test back test'}\n              viewDetail={() => undefined}\n              onOpen={() => undefined}\n            />\n          </Grid>\n          <Grid item>\n            <RedPacketClock\n              type={'official'}\n              validSince={0}\n              sender={'..'}\n              amountStr={'..'}\n              memo={'..'}\n              showRedPacket={function (): void {\n                throw new Error('Function not implemented.')\n              }}\n            />\n          </Grid>\n          <Grid item>\n            <RedPacketBgOpened type={'default'} />\n          </Grid>\n          <Grid item>\n            <RedPacketBgOpened type={'official'} />\n          </Grid>\n          <Grid item>\n            <RedPacketQRCode\n              type={'default'}\n              textAddress={'0x01....0101'}\n              textContent={'back test back test back test back test'}\n              amountStr={'1,000 LRC'}\n              textSendBy={'Luck Red Packet'}\n              textType={'Luck Red Packet'}\n              textShared={'shared'}\n              textNo={'1231414'}\n              url={url}\n              // qrCodeG={qrCodeG}\n              textDes={''}\n            />\n          </Grid>\n          <Grid item>\n            <RedPacketQRCode\n              url={url}\n              type={'official'}\n              textAddress={'0x01....0101'}\n              textContent={'back test back test back test back test'}\n              amountStr={'1,000 LRC'}\n              textSendBy={''}\n              textType={'Relay Red Packet'}\n              textShared={'shared'}\n              textNo={'1231414'}\n              textDes={''}\n            />\n          </Grid>\n          <Grid item>\n            <RedPacketTimeout\n              sender={'0x01....0101'}\n              memo={'back test back test back test back test  back test back test'}\n              viewDetail={() => undefined}\n            />\n          </Grid>\n          <Grid item>\n            <RedPacketDetail\n              amountStr={'1,000 LRC'}\n              sender={'0x01....0101'}\n              memo={'back test back test back test back test  back test back test'}\n              amountClaimStr={''}\n              myAmountStr={''}\n              claimList={[]}\n              showReceiptListBtn={true}\n              detail={\n                {\n                  champion: {\n                    accountId: 10001,\n                    address: '0x',\n                    ens: '.loopring',\n                    amount: '1',\n                  },\n                  claimAmount: 1,\n                  claims: [\n                    //   {id:1,\n                    // hash: string\n                    // claimer: {\n                    //   accountId: number\n                    //   address: string\n                    //   ens: string\n                    // }\n                    // referrer: {\n                    //   accountId: number\n                    //   address: number\n                    //   ens: string\n                    // }\n                    // helper: {\n                    //   accountId: number\n                    //   address: number\n                    //   ens: number\n                    // }\n                    // amount: number\n                    // createdAt: number\n                    // claimId: number}\n                  ],\n                  tokenId: 1,\n                  hash: '',\n                  helpers: [\n                    //     {\n                    //   accountId: number\n                    //   address: number\n                    //   ens: number\n                    //   amount: number\n                    // }\n                  ],\n                  claimStatus: 'WAITING_CLAIM',\n                  luckyToken: {\n                    hash: '',\n                    sender: {\n                      accountId: 10001,\n                      address: '0x',\n                      ens: '.loopring',\n                    },\n                    champion: {\n                      accountId: 10001,\n                      address: '0x',\n                      ens: '.loopring',\n                      amount: '1',\n                    },\n                    tokenId: 0,\n                    tokenAmount: {\n                      totalCount: 1,\n                      remainCount: 1,\n                      totalAmount: 1,\n                      remainAmount: 1,\n                      claimedBoxCount: 1,\n                      giftCount: 1,\n                    },\n                    type: {\n                      partition: 0,\n                      scope: 0,\n                      mode: 0,\n                    },\n                    status: 'SUBMITTING',\n                    info: {\n                      memo: 'xxx',\n                      signer: 'xxx',\n                      signerUrl: 'xxx',\n                      logoUrl: 'xxx',\n                    },\n                    isNft: false,\n                    validSince: 1,\n                    validUntil: 1,\n                    templateNo: 1,\n                    createdAt: 1,\n                    isOfficial: false,\n                    nftExpireTime: 1,\n                  },\n                } as any\n              }\n              isShouldSharedRely={false}\n              totalCount={0}\n              remainCount={0}\n              onShared={function (): void {\n                throw new Error('Function not implemented.')\n              }}\n              page={0}\n              handlePageChange={function (_page: number, _limit?: number): void {\n                throw new Error('Function not implemented.')\n              }}\n              bottomButton={'ended'}\n              claimButton={'claimed'}\n              ended={true}\n              redPacketType={'lucky'}\n              showRelayText={true}\n              showShareBtn={true}\n              totalNumber={10}\n            />\n          </Grid>\n\n          {/*<Grid item xs={4}>*/}\n          {/*  <RedPacketCard*/}\n          {/*    luckyTokenItem={REDPACKETMOCK}*/}\n          {/*    idIndex={TOKEN_INFO.idIndex}*/}\n          {/*    tokenMap={TOKEN_INFO.tokenMap}*/}\n          {/*  />*/}\n          {/*</Grid>*/}\n        </Grid>\n\n        <h4>Vip Panel</h4>\n        <Grid container spacing={2}>\n          <Grid item>\n            <VipPanel {...{ ...rest }} currentLevel={1} rawData={vipData} />\n          </Grid>\n        </Grid>\n      </MemoryRouter>\n    </Style>\n  )\n}) as Story<any>\n\nexport default {\n  title: 'components/Block',\n  component: TradeTitleWrap,\n  argTypes: {},\n} as Meta\n//@ts-ignore\nexport const BlockStory = Template.bind({})\n// SwitchPanel.args = {}\n"
  },
  {
    "path": "packages/component-lib/src/components/block/CollectionDetailView.tsx",
    "content": "import {\n  Account,\n  CollectionMeta,\n  CopyIcon,\n  copyToClipBoard,\n  GET_IPFS_STRING,\n  getShortAddr,\n  ImageIcon,\n} from '@loopring-web/common-resources'\nimport styled from '@emotion/styled'\nimport { Avatar, Box, BoxProps, Link, Typography } from '@mui/material'\nimport { useTheme } from '@emotion/react'\nimport { Button, useSettings } from '../../index'\nimport { useTranslation } from 'react-i18next'\nimport { sanitize } from 'dompurify'\n\nconst StyledPaper = styled(Box)`\n  background: var(--color-box);\n  border-radius: ${({ theme }) => theme.unit}px;\n`\n//--color-box\nconst HeaderBannerStyle = styled(Box)<BoxProps & { url: string }>`\n  background-image: url(${({ url }) => url});\n  background-position: center;\n  background-repeat: no-repeat;\n  background-size: cover;\n  border-radius: ${({ theme }) => theme.unit}px;\n  height: 100%;\n  width: 100%;\n` as (props: BoxProps & { url: string }) => JSX.Element\n\nexport const CollectionDetailView = <Co extends CollectionMeta>({\n  collectionDate,\n  getIPFSString,\n  baseURL,\n  account,\n  setCopyToastOpen,\n  setShowEdit,\n  setShowManageLegacy,\n  count,\n}: {\n  collectionDate: Co\n  getIPFSString: GET_IPFS_STRING\n  baseURL: string\n  account: Account\n  setShowManageLegacy?: (item: Co) => void\n  setShowEdit?: (item: Co) => void\n  count: number\n  setCopyToastOpen: (props: { isShow: boolean; type: string }) => void\n}) => {\n  const theme = useTheme()\n  const { isMobile } = useSettings()\n  const { t } = useTranslation()\n  const lageSize = isMobile\n    ? {\n        icon: 36,\n        move: 20,\n        width: 'var(--nft-small-avatar)',\n      }\n    : {\n        icon: 48,\n        move: 40,\n        width: 'var(--nft-large-avatar)',\n      }\n  return (\n    <StyledPaper display={'flex'} marginX={2} flexDirection={'column'}>\n      <Box\n        width={'100%'}\n        paddingTop={'calc(100% / 3)'}\n        position={'relative'}\n        display={'flex'}\n        alignItems={'center'}\n        justifyContent={'center'}\n        borderRadius={1}\n        sx={{ background: 'var(--field-opacity)' }}\n      >\n        <Box\n          display={'flex'}\n          position={'absolute'}\n          alignItems={'center'}\n          top={0}\n          left={0}\n          right={0}\n          bottom={0}\n          justifyContent={'center'}\n        >\n          {(\n            collectionDate?.cached?.banner ?? getIPFSString(collectionDate?.banner ?? '', baseURL)\n          ).startsWith('http') ? (\n            <HeaderBannerStyle\n              url={\n                collectionDate?.cached?.banner ??\n                getIPFSString(collectionDate?.banner ?? '', baseURL)\n              }\n            />\n          ) : (\n            <ImageIcon\n              style={{\n                height: lageSize.icon,\n                width: lageSize.icon,\n              }}\n            />\n          )}\n        </Box>\n      </Box>\n\n      <Box paddingLeft={5} paddingRight={3} position={'relative'} display={'flex'}>\n        <Box\n          position={'relative'}\n          top={-lageSize.move}\n          // left={lageSize.move}\n          display={'flex'}\n          alignItems={'center'}\n          justifyContent={'center'}\n          height={lageSize.width}\n          width={lageSize.width}\n          borderRadius={theme.unit}\n          sx={{ background: 'var(--color-pop-bg)' }}\n        >\n          {(\n            collectionDate?.cached?.avatar ?? getIPFSString(collectionDate?.avatar ?? '', baseURL)\n          ).startsWith('http') ? (\n            <Avatar\n              sx={{\n                bgcolor: 'var(--color-border-disable2)',\n                borderRadius: `${theme.unit}px`,\n                height: '100%',\n                width: '100%',\n              }}\n              variant={'rounded'}\n              src={\n                collectionDate?.cached?.avatar ??\n                getIPFSString(collectionDate?.avatar ?? '', baseURL)\n              }\n            />\n          ) : (\n            <ImageIcon fontSize={'large'} />\n          )}\n        </Box>\n        <Box\n          flex={1}\n          paddingY={3}\n          paddingLeft={3}\n          position={'relative'}\n          display={'flex'}\n          justifyContent={'space-between'}\n        >\n          <Box>\n            <Typography\n              variant={'body1'}\n              component={'span'}\n              whiteSpace={'pre'}\n              overflow={'hidden'}\n              display={'flex'}\n              textOverflow={'ellipsis'}\n              dangerouslySetInnerHTML={{\n                __html:\n                  sanitize(\n                    collectionDate?.name\n                      ? collectionDate.name\n                      : t('labelUnknown') +\n                          '-' +\n                          getShortAddr(collectionDate?.contractAddress ?? '', true),\n                  ) ?? '',\n              }}\n            />\n            <Link\n              color={'textPrimary'}\n              paddingTop={1}\n              variant={'body1'}\n              component={'span'}\n              whiteSpace={'pre'}\n              overflow={'hidden'}\n              display={'flex'}\n              alignItems={'center'}\n              textOverflow={'ellipsis'}\n              onClick={(e) => {\n                e.stopPropagation()\n                copyToClipBoard(collectionDate?.contractAddress ?? '')\n                setCopyToastOpen({ isShow: true, type: 'address' })\n              }}\n            >\n              {getShortAddr(collectionDate?.contractAddress ?? '')}\n              <CopyIcon color={'inherit'} sx={{ marginLeft: 1 }} />\n            </Link>\n            <Typography\n              color={'textPrimary'}\n              paddingTop={1}\n              variant={'body1'}\n              component={'span'}\n              whiteSpace={'pre'}\n              overflow={'hidden'}\n              display={'flex'}\n              textOverflow={'ellipsis'}\n            >\n              {t('labelCollectionItemValue', {\n                value: count, //collectionDate?.extends.count,\n              })}\n            </Typography>\n          </Box>\n          <Box display={'flex'} flexDirection={'column'} alignItems={'flex-end'}>\n            <Typography\n              color={'textPrimary'}\n              variant={'body1'}\n              component={'span'}\n              whiteSpace={'pre'}\n              overflow={'hidden'}\n              display={'flex'}\n              textOverflow={'ellipsis'}\n              title={collectionDate?.nftType}\n            >\n              {collectionDate?.nftType}\n            </Typography>\n            {account.accAddress === collectionDate.owner ? (\n              <>\n                {setShowEdit && collectionDate.extra?.properties?.isEditable && (\n                  <Button\n                    fullWidth\n                    variant={'outlined'}\n                    size={'medium'}\n                    color={'primary'}\n                    onClick={() => {\n                      setShowEdit(collectionDate)\n                    }}\n                    sx={{ marginTop: 1 }}\n                  >\n                    {t(`labelCollectionEditBtn`)}\n                  </Button>\n                )}\n                {setShowManageLegacy &&\n                  collectionDate.extra?.properties?.isLegacy &&\n                  collectionDate.extra?.properties?.isEditable && (\n                    <Button\n                      fullWidth\n                      variant={'outlined'}\n                      size={'medium'}\n                      color={'primary'}\n                      onClick={() => {\n                        setShowManageLegacy(collectionDate)\n                      }}\n                      sx={{ marginTop: 1 }}\n                    >\n                      {t(`labelCollectionImportNFTBtn`)}\n                    </Button>\n                  )}\n              </>\n            ) : (\n              <></>\n            )}\n          </Box>\n        </Box>\n      </Box>\n    </StyledPaper>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/block/CollectionMedia.tsx",
    "content": "import {\n  CollectionMeta,\n  GET_IPFS_STRING,\n  ImageIcon,\n  LegacyIcon,\n  SoursURL,\n} from '@loopring-web/common-resources'\nimport { Theme, useTheme } from '@emotion/react'\nimport React from 'react'\nimport { Box, BoxProps, Typography } from '@mui/material'\nimport { cssBackground, EmptyDefault, MediaLabelStyled, NftImage, useImage } from '../../index'\nimport styled from '@emotion/styled'\nimport { useTranslation } from 'react-i18next'\n\nconst BoxStyle = styled(Box)<BoxProps & { theme: Theme }>`\n  ${(props) => cssBackground(props)};\n  width: 100%;\n  //height: 100vw;\n  position: relative;\n  overflow: hidden;\n` as (prosp: BoxProps & { theme: Theme }) => JSX.Element\n\nexport const CollectionMedia = React.memo(\n  React.forwardRef(\n    (\n      {\n        item,\n        onRenderError,\n        index,\n        baseURL,\n        getIPFSString,\n        onClick,\n      }: {\n        item: Partial<CollectionMeta>\n        index?: number\n        onRenderError: (popItem: Partial<CollectionMeta>, index?: number) => void\n        baseURL: string\n        getIPFSString: GET_IPFS_STRING\n        onClick?: (e: any) => void\n        // isOrigin?: boolean;\n        // shouldPlay?: boolean;\n      },\n      ref: React.ForwardedRef<any>,\n    ) => {\n      const theme = useTheme()\n      const { t } = useTranslation()\n      const { hasLoaded, hasError } = useImage(\n        item?.cached?.tileUri ?? getIPFSString(item.tileUri, baseURL) ?? '',\n      )\n\n      React.useEffect(() => {\n        if (hasError) {\n          onRenderError(item, index)\n        }\n      }, [hasError, item, index])\n\n      return (\n        <BoxStyle\n          ref={ref}\n          theme={theme}\n          flex={1}\n          display={'flex'}\n          alignItems={'center'}\n          justifyContent={'center'}\n          onClick={onClick}\n          className={'media'}\n        >\n          {!hasLoaded ? (\n            <Box\n              flex={1}\n              height={'100%'}\n              display={'flex'}\n              alignItems={'center'}\n              justifyContent={'center'}\n            >\n              <img className='loading-gif' width='36' src={`${SoursURL}images/loading-line.gif`} />\n            </Box>\n          ) : (\n            <Box\n              alignSelf={'stretch'}\n              position={'relative'}\n              flex={1}\n              display={'flex'}\n              // style={{\n              //   background:\n              //     !!item.tileUri && !hasError ? \"var(--field-opacity)\" : \"\",\n              // }}\n            >\n              {!!item.tileUri && !hasError ? (\n                <NftImage\n                  alt={'tile'}\n                  {...item}\n                  onError={() => onRenderError(item, index)}\n                  src={item?.cached?.tileUri ?? getIPFSString(item.tileUri, baseURL)}\n                />\n              ) : (\n                <EmptyDefault\n                  style={{ flex: 1 }}\n                  height={'100%'}\n                  emptyPic={\n                    <ImageIcon\n                      htmlColor={'var(--color-text-third)'}\n                      style={{ width: 80, height: 80 }}\n                    />\n                  }\n                  message={() => (\n                    <></>\n                    // <Box\n                    //   flex={1}\n                    //   display={\"flex\"}\n                    //   alignItems={\"center\"}\n                    //   justifyContent={\"center\"}\n                    // >\n                    //   {t(\"labelNoCollectionCover\")}\n                    // </Box>\n                  )}\n                />\n              )}\n            </Box>\n          )}\n          {item.extra?.properties?.isLegacy ? (\n            <MediaLabelStyled\n              position={'absolute'}\n              left={0}\n              top={0}\n              display={'flex'}\n              alignItems={'center'}\n              justifyContent={'center'}\n              colorbg={'var(--color-warning)'}\n            >\n              <LegacyIcon color={'inherit'} htmlColor={'var(--color-text-button)'} />\n              <Typography color={'var(--color-text-button)'} component={'span'} paddingLeft={1}>\n                {t('labelLegacy')}\n              </Typography>\n            </MediaLabelStyled>\n          ) : (\n            ''\n          )}\n        </BoxStyle>\n      )\n    },\n  ),\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/block/DepthRaw.tsx",
    "content": "import { Box, Grid, Typography } from '@mui/material'\nimport { MarketInfo } from '@loopring-web/loopring-sdk'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport { DepthViewData, MarketRowHeight } from '@loopring-web/common-resources'\nimport styled from '@emotion/styled'\nimport { useSettings } from '../../stores'\n\nexport type Row = DepthViewData & {\n  type: DepthType\n  onClick: (event: MouseEvent, chooseDepth: DepthViewData, type: DepthType) => void\n}\nexport const GridStyle = styled(Grid)`\n  margin: 0;\n\n  &:hover {\n    background: var(--color-box-hover);\n    transition: background 0.4s ease-out;\n  }\n\n  & > .MuiGrid-item {\n    padding-top: 0;\n    padding-left: 0;\n  }\n` as typeof Grid\n\nexport enum DepthType {\n  ask = 'ask',\n  bid = 'bid',\n}\n\nexport const Depth = ({ onClick, depthLevel, ...rest }: Row & { depthLevel?: number }) => {\n  // const theme = useTheme();\n  const { isMobile } = useSettings()\n  const { price, amtForShow, amtTotalForShow, percentage, type } = rest\n  const digitNum = depthLevel || 0\n  let formattedPrice = price as any\n  let [_init, _dot] = String(price || '').split('.')\n  if (_dot) {\n    const dotLen = _dot.length\n    if (dotLen < digitNum) {\n      for (let i = dotLen; i < digitNum; i++) {\n        _dot += '0'\n      }\n      formattedPrice = _init + '.' + _dot\n    }\n  } else {\n    let fakeDot = '.'\n    for (let i = 0; i < digitNum; i++) {\n      fakeDot += '0'\n    }\n    formattedPrice += fakeDot\n  }\n\n  const color = type === DepthType.ask ? 'var(--color-error)' : 'var(--color-success)'\n  return (\n    <GridStyle\n      container\n      spacing={1}\n      position={'relative'}\n      wrap={'nowrap'}\n      style={{ cursor: 'pointer' }}\n      onClick={(e) => onClick(e as any, { ...rest }, type)}\n    >\n      <Box\n        style={{ opacity: 0.1, backgroundColor: color }}\n        display={'block'}\n        position={'absolute'}\n        right={0}\n        width={percentage * 100 + '%'}\n        height={`${MarketRowHeight}px`}\n        zIndex={42}\n      />\n      <Grid item xs={6} lg={4} alignSelf={'flex-start'} zIndex={55}>\n        <Typography lineHeight={`${MarketRowHeight}px`} color={color} variant={'body2'}>\n          {formattedPrice}\n        </Typography>\n      </Grid>\n      <Grid item xs={6} lg={4} alignSelf={'flex-end'} textAlign={'right'} zIndex={55}>\n        <Typography lineHeight={`${MarketRowHeight}px`} color={'text.secondary'} variant={'body2'}>\n          {amtForShow}\n        </Typography>\n      </Grid>\n      {!isMobile && (\n        <Grid item xs={6} lg={4} alignSelf={'flex-end'} textAlign={'right'} zIndex={55}>\n          <Typography\n            lineHeight={`${MarketRowHeight}px`}\n            color={'text.secondary'}\n            variant={'body2'}\n          >\n            {amtTotalForShow}\n          </Typography>\n        </Grid>\n      )}\n    </GridStyle>\n  )\n}\n\nexport const DepthTitle = withTranslation('common')(\n  ({\n    marketInfo,\n    t,\n  }: {\n    marketInfo: MarketInfo\n  } & WithTranslation) => {\n    // @ts-ignore\n    const [, baseSymbol, quoteSymbol] = marketInfo?.market?.match(/(\\w+)-(\\w+)/i)\n    const { isMobile } = useSettings()\n\n    return marketInfo?.market ? (\n      <GridStyle container spacing={1} position={'relative'} wrap={'nowrap'}>\n        <Grid item xs={6} lg={4} alignSelf={'flex-start'}>\n          <Typography\n            lineHeight={`${MarketRowHeight}px`}\n            color={'var(--color-text-third)'}\n            textOverflow={'ellipsis'}\n            title={t('labelDepthPrice', { symbol: quoteSymbol })}\n            variant={'body2'}\n            component={'p'}\n          >\n            {t('labelDepthPrice', { symbol: quoteSymbol })}\n          </Typography>\n        </Grid>\n        <Grid item xs={6} lg={4} alignSelf={'flex-end'}>\n          <Typography\n            lineHeight={`${MarketRowHeight}px`}\n            title={t('labelDepthAmount', { symbol: baseSymbol })}\n            color={'var(--color-text-third)'}\n            textOverflow={'ellipsis'}\n            overflow={'hidden'}\n            variant={'body2'}\n            textAlign={'right'}\n            component={'p'}\n          >\n            {t('labelDepthAmount', { symbol: baseSymbol })}\n          </Typography>\n        </Grid>\n        {!isMobile && (\n          <Grid item xs={6} lg={4} alignSelf={'flex-end'}>\n            <Typography\n              lineHeight={`${MarketRowHeight}px`}\n              color={'var(--color-text-third)'}\n              variant={'body2'}\n              textAlign={'right'}\n              title={t('labelDepthTotal')}\n              component={'p'}\n            >\n              {t('labelDepthTotal')}\n            </Typography>\n          </Grid>\n        )}\n      </GridStyle>\n    ) : (\n      <></>\n    )\n  },\n)\nexport const DepthBlock = withTranslation('common')(\n  ({\n    depths,\n    onClick,\n    // tokenBaseInfo,\n    type,\n    depthLevel,\n  }: {\n    onClick: (event: MouseEvent, chooseDepth: DepthViewData, type: DepthType) => void\n    type: DepthType\n    // quotePrecision:number,\n    depths: DepthViewData[]\n    marketInfo: MarketInfo\n    depthLevel?: number\n  } & WithTranslation) => {\n    return (\n      <>\n        {depths.map((depth, index) => {\n          // const amt_p = ;\n          //\n          // const amtTotal_p = getValuePrecisionThousand(toBig(depth.amtTotal).div('1e' + tokenBaseInfo.decimals),\n          //     undefined, undefined, marketInfo.precisionForPrice, true);\n\n          return (\n            <Depth\n              onClick={onClick}\n              key={index}\n              {...{\n                ...depth,\n                type,\n                depthLevel,\n              }}\n            />\n          )\n        })}\n      </>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/block/DownloadPanel.tsx",
    "content": "import { useTheme } from '@emotion/react'\nimport { SoursURL } from '@loopring-web/common-resources'\nimport { Box, Link } from '@mui/material'\nimport { WithTranslation, withTranslation } from 'react-i18next'\n\nexport const DownloadPanel = withTranslation(['common', 'layout'])(\n  ({ t, viewMoreUrl }: WithTranslation & { viewMoreUrl: string }) => {\n    const theme = useTheme()\n    return (\n      <Box\n        display={'flex'}\n        flexDirection={'column'}\n        alignItems={'center'}\n        paddingX={2}\n        paddingTop={2}\n      >\n        <Link\n          marginBottom={1}\n          target='_blank'\n          rel='noopener noreferrer'\n          href='https://play.google.com/store/apps/details?id=loopring.defi.wallet'\n        >\n          <img height={56} src={`${SoursURL}images/google-play.png`} alt={'GooglePlay'} />\n        </Link>\n        <Link\n          marginBottom={1}\n          target='_blank'\n          rel='noopener noreferrer'\n          href='https://download.loopring.io/LoopringWallet.apk'\n        >\n          <img height={56} src={`${SoursURL}images/android-apk.png`} alt={'Android'} />\n        </Link>\n        <Link\n          marginBottom={1}\n          target='_blank'\n          rel='noopener noreferrer'\n          href='https://apps.apple.com/us/app/loopring-smart-wallet/id1550921126'\n        >\n          <img height={56} src={`${SoursURL}images/apple-app-store.png`} alt={'AppStore'} />\n        </Link>\n        <Link\n          marginBottom={1}\n          target='_blank'\n          rel='noopener noreferrer'\n          href={viewMoreUrl}\n          style={{ cursor: 'pointer' }}\n          variant={'body1'}\n          color={theme.colorBase.primary}\n        >\n          {t('labelDownloadViewMore')}\n        </Link>\n      </Box>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/block/ETHStakingDetail.tsx",
    "content": "import { Box, Divider, Typography } from '@mui/material'\nimport {\n  ChartType,\n  DEFI_ADVICE_MAP,\n  myLog,\n  SoursURL,\n  YEAR_DAY_MINUTE_FORMAT,\n  UpColor,\n} from '@loopring-web/common-resources'\nimport moment from 'moment'\nimport TrendAprChart from '../charts/scaleAreaChart/APRChart'\nimport { useSettings } from '../../stores'\nimport React, { useEffect } from 'react'\n\nexport const ETHStakingDetail = ({ symbol, trends, defiInfo: _defiInfo }: any) => {\n  myLog('trends', trends)\n  const [, baseSymbol] = symbol.match(/(\\w+)-(\\w+)/i)\n  const { upColor } = useSettings()\n  const colorRight =\n    upColor === UpColor.green\n      ? ['var(--color-success)', 'var(--color-error)']\n      : ['var(--color-error)', 'var(--color-success)']\n  const [defiInfo, setDefiInfo] = React.useState(undefined as undefined | {\n    apy: string,\n    timestamp:  number\n  })\n  useEffect(() => {\n    setDefiInfo({\n      apy: _defiInfo?.apy,\n      timestamp: Date.now()\n    })\n  }, [_defiInfo])\n  \n  return symbol ? (\n    <>\n      <Box\n        marginTop={-4}\n        component={'header'}\n        display={'flex'}\n        flexDirection={'row'}\n        justifyContent={'space-between'}\n        width={'var(--modal-width)'}\n      >\n        <Typography\n          component={'header'}\n          height={'var(--toolbar-row-height)'}\n          display={'flex'}\n          paddingX={3}\n          flexDirection={'row'}\n          alignItems={'center'}\n        >\n          <Typography component={'span'} flexDirection={'column'} display={'flex'}>\n            {DEFI_ADVICE_MAP[baseSymbol]?.project}\n            {/*{t('labelEstAPR')}*/}\n          </Typography>\n        </Typography>\n      </Box>\n      <Divider />\n      {defiInfo && (\n        <Box paddingX={3} marginTop={2}>\n          <Typography\n            variant={'h2'}\n            color={defiInfo?.apy?.toString().charAt(0) == '-' ? colorRight[1] : colorRight[0]}\n          >\n            {(defiInfo?.apy?.toString().charAt(0) == '-' ? '' : '+') + defiInfo?.apy + '%' + ' APR'}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-third)'}>\n            {moment(defiInfo.timestamp).format(YEAR_DAY_MINUTE_FORMAT)}\n          </Typography>\n        </Box>\n      )}\n      <Box marginX={1} flex={1} display={'flex'}>\n        <Box\n          width={'100%'}\n          display={'flex'}\n          alignItems={'center'}\n          justifyContent={'center'}\n          // height={\"60%\"}\n          height={'calc(var(--swap-box-height) - 262px)'}\n          sx={{\n            minHeihgt: '300px',\n          }}\n          marginBottom={2}\n          // minHeight={420}\n        >\n          {!trends?.length ? (\n            <img\n              className='loading-gif'\n              alt={'loading'}\n              width='36'\n              src={`${SoursURL}images/loading-line.gif`}\n            />\n          ) : (\n            <TrendAprChart type={ChartType.Trend} data={trends} showXAxis handleMove={(props) => {\n              setDefiInfo({\n                apy: props.apy,\n                timestamp: props.createdAt \n              })\n            }}/>\n          )}\n        </Box>\n      </Box>\n    </>\n  ) : (\n    <></>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/block/ErrorBlock.tsx",
    "content": "import { RESULT_INFO } from '@loopring-web/loopring-sdk'\nimport { TOptions } from 'i18next'\nimport { useTranslation } from 'react-i18next'\nimport { useSettings } from '../../stores'\nimport { L1L2_NAME_DEFINED, MapChainId, SDK_ERROR_MAP_TO_UI } from '@loopring-web/common-resources'\n\nexport const TransErrorHelp = ({\n  error,\n  options = {},\n}: {\n  error: RESULT_INFO\n  options?: TOptions<any> | string\n}) => {\n  const { t } = useTranslation(['error'])\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const errorItem = SDK_ERROR_MAP_TO_UI[error?.code ?? 700001]\n  const _options = { ...errorItem?.options, ...options }\n  if (errorItem) {\n    return (\n      <>\n        {t(errorItem.messageKey, {\n          ..._options,\n          layer2: L1L2_NAME_DEFINED[network].layer2,\n          l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n          loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n          l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n          l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n          ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n        })}\n      </>\n    )\n  } else {\n    return <>{error.message}</>\n  }\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/block/Interface.ts",
    "content": "import {\n  CoinInfo,\n  ForexMap,\n  GET_IPFS_STRING,\n  NFTWholeINFO,\n  PriceTag,\n  RedPacketQRPropsExtends,\n  TradeBtnStatus,\n  TradeFloat,\n} from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { RawDataRedPacketDetailItem } from '../tableList'\n\nexport type MarketBlockProps<C> = {\n  coinAInfo: CoinInfo<C>\n  coinBInfo: CoinInfo<C>\n  tradeFloat: TradeFloat\n  forexMap: ForexMap<sdk.Currency>\n  chartData?: {\n    close: number\n    timeStamp: number\n  }[]\n}\n\nexport type AssetTitleProps = {\n  assetInfo: {\n    isShow?: boolean\n    totalAsset: number\n    priceTag: (typeof PriceTag)[keyof typeof PriceTag]\n    [key: string]: any\n  }\n  accountId: number\n  onShowReceive: (token?: string) => void\n  onShowSend: (token?: string) => void\n  onClickBridge?: () => void\n  showBridgeBtn?: boolean\n  hideL2Assets: boolean\n  setHideL2Assets: (value: boolean) => void\n  assetBtnStatus: TradeBtnStatus\n  forexMap: ForexMap\n  isWebEarn?: boolean\n}\n\nexport type AssetTitleMobileProps = AssetTitleProps & {\n  // onShowNFTDeposit: () => void;\n  // onShowNFTMINT: () => void;\n  btnShowNFTDepositStatus?: keyof typeof TradeBtnStatus\n  btnShowNFTMINTStatus?: keyof typeof TradeBtnStatus\n}\n\nexport type NFTMedaProps = {\n  item: Partial<NFTWholeINFO>\n  index?: number\n  onNFTError: (popItem: Partial<NFTWholeINFO>, index?: number) => void\n  isOrigin?: boolean\n  shouldPlay?: boolean\n  getIPFSString: GET_IPFS_STRING\n  baseURL: string\n}\nexport type RedPacketDefaultBg = RedPacketDefault & {\n  content: JSX.Element\n  className?: string\n}\nexport type RedPacketDefault = {\n  type?: 'default' | 'official' | 'blindbox'\n  size?: 'middle' | 'large'\n  ImageEle?: JSX.Element | undefined\n}\nexport type RedPacketTimeoutProps = RedPacketDefault & {\n  sender: string\n  memo?: string\n  viewDetail?: () => void\n}\nexport type RedPacketQRCodeProps = {\n  url: string\n  imageEleUrl?: string\n} & RedPacketQRPropsExtends\nexport type RedPacketOpenProps = {\n  sender: string\n  amountStr: string\n  memo: string\n  viewDetail?: () => void\n  onOpen: () => void\n}\nexport type RedPacketUnreadyProps = {\n  sender: string\n  amountStr: string\n  memo: string\n  validSince: number\n  // viewDetail: () => void;\n  onClickOpen: () => void\n}\nexport type RedPacketOpenedProps = {\n  sender: string\n  amountStr: string\n  myAmountStr: string | undefined\n  memo: string\n  viewDetail: () => void\n}\nexport const RedPacketDetailLimit = 5\nexport const RedPacketNFTDetailLimit = 5\nexport const RedPacketBlindBoxLimit = 8\nexport type RedPacketDetailProps = {\n  redPacketType: 'normal' | 'lucky' | 'relay'\n  sender: string\n  amountStr: string\n  amountClaimStr: string\n  memo: string\n  myAmountStr: string\n  claimList: RawDataRedPacketDetailItem[]\n  detail: sdk.LuckTokenClaimDetail\n  isShouldSharedRely: boolean\n  totalCount: number\n  remainCount: number\n  onShared: () => void\n  page: number\n  relyAmount?: string\n  relyNumber?: string\n  handlePageChange: (page: number, limit?: number) => void\n  ImageEle?: JSX.Element | undefined\n  showRelayText: boolean\n  showShareBtn: boolean\n  tokenSymbol?: string\n  ended: boolean\n  bottomButton: 'ended' | 'share' | 'hidden'\n  claimButton: 'claim' | 'claimed' | 'expired' | 'hidden' | 'claiming'\n  onClickClaim?: () => void\n  totalNumber: number\n  showReceiptListBtn: boolean\n}\nexport type RedPacketBlindBoxDetailTypes =\n  | 'Not Started'\n  | 'Blind Box Started'\n  | 'Lottery Started'\n  | 'Lottery Started and Win Lottery'\n  | 'Lottery Started and Not Win Lottery'\n  | 'BlindBox Claime Detail'\nexport type RedPacketBlindBoxDetailProps = {\n  sender: string\n  memo: string\n  NFTURL?: string\n  // Not Started: Phase 1, can't get blind boxs, only red packet sender can view this detail\n  // Blind Box Started: Phase 2, can get blind boxs, everyone can view this detail\n  // Lottery Started: Phase 3, users can participate in lottery if they have blind boxs, everyone can view this detail\n  // Lottery Started And Open: Phase 3, Same as 'Lottery Started' but one more Popup to show if win NFTs\n  // BlindBox Claime Detail: Phase 2 or Phase 3, shows detail of blindboxs distribution.\n  type: RedPacketBlindBoxDetailTypes\n  blindBoxStartTime?: number\n  lotteryStartTime?: number\n  lotteryEndTime?: number\n  opendBlindBoxAmount: number\n  totalBlindBoxAmount: number\n  deliverdGiftsAmount: number\n  totalGiftsAmount: number\n  imageEle?: JSX.Element | undefined\n  onShared?: () => void\n  onClickViewDetail?: () => void\n  NFTClaimList?: {\n    who: string\n    isMe: boolean\n    when: number\n    amount: number\n    showLuckiest?: boolean\n    showMultiplier: boolean\n  }[]\n  BlindBoxClaimList?: {\n    who: string\n    isMe: boolean\n    when: number\n    amount: number\n  }[]\n  showOpenLottery?: boolean\n  wonPrizeInfo?:\n    | {\n        name: string\n        url: string\n        isNFT: true\n      }\n    | {\n        amountStr: string\n        tokenName: string\n        isNFT: false\n      }\n  onClickClaim?: () => void\n  onCloseOpenModal?: () => void\n  onClickClaimDetailBack?: () => void\n  description: string\n  shareButton: 'hidden' | 'share'\n  claimButton: 'claimed' | 'claim' | 'claiming' | 'expired' | 'hidden' | 'ended'\n  didClaimABlindBox: boolean\n  wonInfo:\n    | {\n        participated: boolean\n        won: boolean\n        amount: number\n        isNFT: true\n      }\n    | {\n        participated: boolean\n        won: boolean\n        amount: string\n        total: string\n        symbol: string\n        isNFT: false\n      }\n  page: number\n  totalCount: number\n  remainCount: number\n  handlePageChange: (page: number, limit?: number) => void\n  totalClaimedNFTsCount: number\n  totalBlindboxCount: number\n  pageForBlindbox: number\n  handlePageChange_BlindBox: (page: number, limit?: number) => void\n  // didClaimABlindBox: boolean;\n  onClickClaimPopViewDetail: () => void\n  expired: boolean\n  isTokenBlindbox: boolean\n  remainGiftsAmount: string\n  showReceiptListBtn: boolean\n  targets?: string[]\n}\nexport type RedPacketClockProps = RedPacketDefault & {\n  validSince: number\n  sender: string\n  amountStr: string\n  memo: string\n  showRedPacket: () => void\n  // viewDetail: () => void;\n  // onOpen: () => void;\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/block/LoadingBlock.tsx",
    "content": "import { SoursURL } from '@loopring-web/common-resources'\nimport styled from '@emotion/styled'\nimport { Box } from '@mui/material'\n\nconst StyleBlock = styled(Box)`\n  background: var(--color-global-bg);\n\n  svg path,\n  svg rect {\n    fill: var(--color-primary);\n  }\n` as typeof Box\n\nexport const LoadingBlock = () => {\n  return (\n    <StyleBlock\n      flex={1}\n      className={'loading-block'}\n      display={'flex'}\n      alignItems={'center'}\n      justifyContent={'center'}\n      flexDirection={'column'}\n      height={'100%'}\n      width={'100%'}\n    >\n      <div className='loader loader--style3' title='2'>\n        <img\n          className='loading-gif'\n          alt={'loading'}\n          width='36'\n          src={`${SoursURL}images/loading-line.gif`}\n        />\n      </div>\n    </StyleBlock>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/block/MarketBlock.tsx",
    "content": "import { WithTranslation } from 'react-i18next'\nimport {\n  CoinKey,\n  CurrencyToTag,\n  EmptyValueTag,\n  getValuePrecisionThousand,\n  PriceTag,\n} from '@loopring-web/common-resources'\nimport { Box, BoxProps, Grid, Typography } from '@mui/material'\nimport styled from '@emotion/styled'\nimport { floatTag, MarketBlockProps, useSettings } from './../../index'\nimport { ChartType, ScaleAreaChart } from '../charts'\n\ntype StyledProps = {\n  custom: any\n}\nconst MarketBlockStyled = styled(Box)<StyledProps>`\n  min-height: ${({ theme }) => theme.unit * 14.625}px;\n  & {\n    background: var(--color-box);\n    border-radius: ${({ theme }) => theme.unit}px;\n    border: 1px solid var(--color-box);\n    cursor: pointer;\n  }\n  ${({ theme, custom }) => floatTag({ theme, custom })};\n\n  .left-block {\n    min-width: 76px;\n  }\n\n  .float-group span {\n    display: flex;\n    align-items: flex-end;\n  }\n\n  &:hover {\n    box-shadow: var(--shadow-hover);\n  }\n` as (props: StyledProps & BoxProps) => JSX.Element\n\nexport const MarketBlock = <C extends CoinKey<I>, I>({\n  coinAInfo,\n  t,\n  coinBInfo,\n  tradeFloat,\n  chartData = [],\n  handleBlockClick,\n  forexMap,\n}: WithTranslation & MarketBlockProps<C> & { handleBlockClick: () => void }) => {\n  const { upColor, currency } = useSettings()\n  const { volume, coinApriceU, marketPrecision, coinBPrecision } = tradeFloat as any\n  const baseFaitPrice = getValuePrecisionThousand(\n    coinApriceU * (forexMap[currency] ?? 0),\n    undefined,\n    undefined,\n    undefined,\n    true,\n    {\n      isFait: true,\n    },\n  )\n\n  return (\n    <MarketBlockStyled\n      onClick={handleBlockClick}\n      className={'MuiPaper-elevation2'}\n      custom={{ chg: upColor }}\n      padding={0.5 * 5}\n      display={'flex'}\n      justifyContent={'stretch'}\n    >\n      {coinAInfo && coinBInfo ? (\n        <Grid container justifyContent={'space-around'} position={'relative'}>\n          <Grid\n            item\n            xs={12}\n            display={'flex'}\n            flexDirection={'row'}\n            justifyContent={'flex-start'}\n            alignItems={'center'}\n            height={24}\n          >\n            <Typography variant={'h4'} component={'h3'}>\n              <Typography variant={'h5'} component={'span'} title={'sell'} color={'textPrimary'}>\n                {coinAInfo?.simpleName}\n              </Typography>\n              <Typography variant={'h5'} component={'i'}>\n                {` / `}\n              </Typography>\n              <Typography variant={'h5'} component={'span'} title={'buy'} color={'textPrimary'}>\n                {coinBInfo.simpleName}\n              </Typography>\n            </Typography>\n          </Grid>\n          <Grid\n            item\n            xs={12}\n            display={'flex'}\n            flexDirection={'row'}\n            justifyContent={'flex-start'}\n            alignItems={'stretch'}\n            className={'float-group'}\n            marginTop={1}\n          >\n            <Box\n              display={'flex'}\n              flexDirection={'column'}\n              alignItems={'flex-start'}\n              justifyContent={'flex-end'}\n              className={'left-block'}\n            >\n              {tradeFloat.close ? (\n                <Box\n                  height={24}\n                  display={'flex'}\n                  alignItems={'center'}\n                  className={`float-tag float-${tradeFloat.floatTag}`}\n                >\n                  <Typography variant={'h4'}>\n                    {getValuePrecisionThousand(\n                      tradeFloat?.close,\n                      undefined,\n                      undefined,\n                      marketPrecision,\n                      true,\n                      { isPrice: true },\n                    )}\n                  </Typography>\n                  <Typography color={'var(--color-text-secondary)'} marginX={1 / 4}>\n                    &#8776;\n                  </Typography>\n                  <Typography variant={'body2'} color={'var(--color-text-secondary)'}>\n                    {PriceTag[CurrencyToTag[currency]]} {baseFaitPrice}\n                  </Typography>\n                </Box>\n              ) : (\n                ''\n              )}\n              <Box display={'flex'} alignItems={'center'}>\n                <Typography\n                  variant={'body2'}\n                  component={'span'}\n                  marginTop={1 / 2}\n                  marginRight={1}\n                  className={`float-tag float-${tradeFloat.floatTag}`}\n                >\n                  {tradeFloat.change\n                    ? `${tradeFloat.change > 0 ? '+' : ''}${getValuePrecisionThousand(\n                        tradeFloat.change,\n                        2,\n                        2,\n                        2,\n                        true,\n                      )}%`\n                    : EmptyValueTag + '%'}\n                </Typography>\n                <Typography\n                  variant={'body2'}\n                  color={'var(--color-text-secondary)'}\n                  component={'div'}\n                  textOverflow={'ellipsis'}\n                  overflow={'hidden'}\n                  whiteSpace={'nowrap'}\n                  marginTop={1 / 2}\n                >\n                  {t('labelAmount') + ' '} :\n                  {getValuePrecisionThousand(\n                    volume,\n                    coinBPrecision,\n                    coinBPrecision,\n                    undefined,\n                    true,\n                  )}\n                  &nbsp;{coinBInfo.simpleName}\n                </Typography>\n              </Box>\n            </Box>\n          </Grid>\n          <Grid item position={'absolute'} top={0} right={0} width={90} height={36}>\n            <ScaleAreaChart\n              isHeadTailCompare\n              showTooltip={true}\n              showArea={true}\n              showXAxis={true}\n              type={ChartType.Trend}\n              data={chartData}\n            />\n          </Grid>\n        </Grid>\n      ) : (\n        <></>\n      )}\n    </MarketBlockStyled>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/block/NotificationPanel.tsx",
    "content": "import { Trans, useTranslation } from 'react-i18next'\nimport {\n  ACTIVITY,\n  Layer2RouterID,\n  NOTIFICATION_ITEM,\n  NOTIFICATIONHEADER,\n  RouterPath,\n  SoursURL,\n} from '@loopring-web/common-resources'\nimport { Box, Divider, Grid, Link, Typography } from '@mui/material'\nimport { EmptyDefault, ListItemActivity, NotificationListItem } from '../basic-lib'\nimport styled from '@emotion/styled'\nimport { NotificationItem } from '@loopring-web/core'\nimport { useHistory } from 'react-router-dom'\n\nconst BoxStyle = styled(Box)`\n  background: var(--color-pop-bg);\n  box-shadow: var(--shadow);\n  .MuiInputBase-root {\n    background: var(--opacity);\n    text-align: right;\n  }\n` as typeof Box\nexport const NotificationPanel = ({\n  notification: { myNotifyMap, notifyMap, chainId, account },\n  onClickExclusiveredPacket,\n  showExclusiveRedpacket,\n  exclusiveRedpacketCount,\n  closePop,\n}: {\n  notification: NOTIFICATIONHEADER<any> & { chainId: number; account }\n  onClickExclusiveredPacket: () => void\n  showExclusiveRedpacket: boolean\n  exclusiveRedpacketCount: number\n  closePop?: () => void\n}) => {\n  const { t } = useTranslation()\n  const history = useHistory()\n  const notifications = notifyMap?.notifications?.reduce((prev, item) => {\n    if (item.endShow >= Date.now() && item.startShow <= Date.now() && item.webFlag) {\n      prev.push(item)\n    }\n    return prev\n  }, [] as NOTIFICATION_ITEM[])\n  let activities = notifyMap?.activities?.reduce((prev, item) => {\n    if (item.endShow >= Date.now() && item.startShow <= Date.now() && item.webFlag) {\n      prev.push(item)\n    }\n    return prev\n  }, [] as ACTIVITY[])\n\n  activities = notifyMap?.activitiesInvest?.reduce((prev, item) => {\n    if (item.endShow >= Date.now() && item.startShow <= Date.now() && item.webFlag) {\n      prev.push(item)\n    }\n    return prev\n  }, activities)\n\n  const hasActivities = activities && activities?.length\n  const hasNotifications = notifications && notifications?.length\n\n  return (\n    <BoxStyle\n      display={'flex'}\n      flexDirection={'column'}\n      maxHeight={600}\n      sx={{ overflowY: 'scroll' }}\n      alignItems={'center'}\n\n      // paddingBottom={1}\n    >\n      {myNotifyMap?.total !== undefined && (\n        <>\n          <Typography\n            alignSelf={'stretch'}\n            sx={{ background: 'var(--field-opacity)' }}\n            borderRadius={1 / 2}\n            padding={1}\n            display={'inline-flex'}\n            alignItems={'center'}\n            justifyContent={'space-between'}\n            minWidth={300}\n          >\n            <Typography component={'span'}>\n              {t('labelTotalUnRead', { total: myNotifyMap?.total ?? 0 })}\n            </Typography>\n            <Link\n              onClick={() => {\n                history.push(`${RouterPath.layer2}/${Layer2RouterID.notification}`)\n                closePop && closePop()\n              }}\n              color={'primary'}\n            >\n              {t('labelReadAll')}\n            </Link>\n          </Typography>\n          {myNotifyMap?.total ? (\n            <Box paddingX={1} display={'flex'} width={330} alignItems={'center'}>\n              <Grid container spacing={1 / 2} margin={0}>\n                {myNotifyMap?.items?.reduce((prev, ele, index) => {\n                  if (index < 3) {\n                    prev.push(\n                      <Grid item key={ele?.id} xs={12}>\n                        <NotificationItem\n                          {...ele}\n                          size={'small'}\n                          className={'headerItem'}\n                          index={index}\n                          noAction={true}\n                          onReadClick={() => {\n                            history.push(`${RouterPath.layer2}/${Layer2RouterID.notification}`)\n                            closePop && closePop()\n                          }}\n                        />\n                        <Divider sx={{ marginY: 1 }} />\n                      </Grid>,\n                    )\n                  }\n                  return prev\n                }, [])}\n              </Grid>\n            </Box>\n          ) : (\n            <Divider\n              sx={{ paddingY: showExclusiveRedpacket || hasActivities || hasNotifications ? 1 : 0 }}\n            />\n          )}\n        </>\n      )}\n\n      {!!(showExclusiveRedpacket || hasActivities || hasNotifications) && (\n        <>\n          <Box\n            component={'section'}\n            display={'flex'}\n            flexDirection={'column'}\n            marginX={1}\n            marginBottom={1}\n          >\n            {showExclusiveRedpacket && (\n              <Box\n                onClick={() => {\n                  onClickExclusiveredPacket()\n                  closePop && closePop()\n                }}\n                sx={{\n                  backgroundImage: `url(${SoursURL + 'images/target_pop_bg.png'})`,\n                  backgroundSize: 'contain',\n                  width: '343px',\n                  height: '77px',\n                  borderRadius: 2,\n                  paddingLeft: 3.5,\n                  paddingTop: 2.5,\n                  cursor: 'pointer',\n                  marginTop: 1,\n                  marginBottom: !!hasActivities ? 1 : 0,\n                }}\n              >\n                <Typography color={'black'}>Congratulations!</Typography>\n                <Typography variant={'body2'} color={'black'}>\n                  You've received {exclusiveRedpacketCount} exclusive Red Packet!\n                </Typography>\n              </Box>\n            )}\n            {!!hasActivities &&\n              activities.map((activity, index) => (\n                <ListItemActivity\n                  key={activity.type + index}\n                  {...activity}\n                  chainId={chainId}\n                  account={account}\n                />\n              ))}\n          </Box>\n          {!!hasNotifications && (\n            <>\n              {!!hasActivities && <Divider />}\n              <Box component={'section'} display={'flex'} flexDirection={'column'}>\n                {notifications?.map((notify, index) => (\n                  <NotificationListItem\n                    key={notify.name.toString() + index}\n                    {...notify}\n                    chainId={chainId}\n                    account={account}\n                  />\n                ))}\n              </Box>\n            </>\n          )}\n        </>\n      )}\n      {!(\n        myNotifyMap?.items?.length ||\n        showExclusiveRedpacket ||\n        hasActivities ||\n        hasNotifications\n      ) && (\n        <Box margin={2}>\n          <EmptyDefault\n            height={`calc(100% - var(--header-row-height))`}\n            message={() => <Trans i18nKey='labelEmptyDefault'>Content is Empty</Trans>}\n          />\n        </Box>\n      )}\n    </BoxStyle>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/block/RedPacket.tsx",
    "content": "import styled from '@emotion/styled'\nimport { Box, BoxProps, Button, Divider, IconButton, Link, Modal, Typography } from '@mui/material'\nimport React from 'react'\nimport { Trans, useTranslation } from 'react-i18next'\nimport {\n  Account,\n  BackIcon,\n  EmptyValueTag,\n  FirstPlaceIcon,\n  GET_IPFS_STRING,\n  getShortAddr,\n  NFTWholeINFO,\n  RedPacketColorConfig,\n  RedPacketCssColorConfig,\n  RedPacketOpenWrapSVG,\n  RedPacketQRCodeSvg,\n  RedPacketWrapSVG,\n  SoursURL,\n  YEAR_DAY_MINUTE_FORMAT,\n  DAY_MINUTE_FORMAT,\n  hexToRGB,\n} from '@loopring-web/common-resources'\nimport QRCodeStyling from 'qr-code-styling'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { RedPacketViewStep } from '../modal'\nimport { ModalStatePlayLoad } from '../../stores'\nimport moment from 'moment'\nimport {\n  RedPacketBlindBoxDetailProps,\n  RedPacketBlindBoxLimit,\n  RedPacketClockProps,\n  RedPacketDefault,\n  RedPacketDefaultBg,\n  RedPacketDetailLimit,\n  RedPacketDetailProps,\n  RedPacketNFTDetailLimit,\n  RedPacketOpenedProps,\n  RedPacketOpenProps,\n  RedPacketQRCodeProps,\n  RedPacketTimeoutProps,\n  RedPacketUnreadyProps,\n} from './Interface'\nimport { BoxNFT, CoinIcon, ModalCloseButtonPosition, TablePagination } from '../basic-lib'\nimport { NFTMedia } from './nftMedia'\nimport { sanitize } from 'dompurify'\nimport { useTheme } from '@emotion/react'\nimport { ReceiptListModal } from '../tradePanel/components/CreateRedPacketWrap'\n\nexport const RedPacketBg = styled(Box)<BoxProps & { imageSrc?: string; type: string }>`\n  display: flex;\n  align-items: center;\n  position: relative;\n  justify-content: center;\n\n  .content {\n    color: ${({ type }) => RedPacketCssColorConfig[type]?.primaryColor};\n\n    .betweenEle {\n      left: 50%;\n      top: 128px;\n      position: absolute;\n\n      .open {\n        background: #fff7b1;\n        color: ${({ type }) => RedPacketCssColorConfig[type]?.highLightColor}; //#7c3400;\n        &.disable {\n          color: ${({ type }) => RedPacketCssColorConfig[type]?.highLightDisableColor}; //#7c3400;\n        }\n\n        cursor: pointer;\n        display: inline-flex;\n        z-index: 100;\n        align-items: center;\n        justify-content: center;\n        width: 64px;\n        height: 64px;\n        content: 'Open';\n        font-size: 20px;\n        font-weight: 500;\n        border-radius: 100%;\n        transform: translate(-50%, -50%);\n      }\n\n      .open.openUnready {\n        background: url('${SoursURL}/images/redpacketLock.webp') center no-repeat;\n        color: ${({ type }) => RedPacketCssColorConfig[type]?.colorTop}; //#7c3400;\n        width: 76px;\n        height: 76px;\n        background-size: contain;\n        border-radius: initial;\n      }\n\n      .clock {\n        display: flex;\n        z-index: 100;\n        align-items: center;\n        justify-content: center;\n        position: absolute;\n        font-size: 28px;\n        font-weight: 900;\n        transform: translate(-50%, -50%);\n        left: 50%;\n        top: -50%;\n        .hours,\n        .minutes,\n        .seconds {\n          justify-content: center;\n          height: 52px;\n          width: 52px;\n          background: #fff7b1;\n          color: #7c3400;\n          display: inline-flex;\n          align-items: center;\n          border-radius: ${({ theme }) => theme.unit + 'px'};\n          h4 {\n            text-indent: -9999em;\n            height: 0;\n            width: 0;\n          }\n        }\n\n        .hours,\n        .minutes {\n          position: relative;\n\n          &:after {\n            display: block;\n            content: ':';\n            position: absolute;\n            font-size: 20px;\n            right: -12px;\n            line-height: 52px;\n            top: 0;\n          }\n        }\n      }\n    }\n\n    .secondary {\n      color: ${({ type }) => RedPacketCssColorConfig[type]?.secondaryColor};\n    }\n\n    .viewDetail {\n      color: ${({ type }) => RedPacketCssColorConfig[type]?.primaryColor};\n\n      &:hover {\n        text-decoration: underline;\n        //color: ${({ type }) => RedPacketCssColorConfig[type]?.secondaryColor};\n      }\n    }\n\n    .top {\n      height: 140px;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      color: ${({ type }) => RedPacketCssColorConfig[type]?.primaryColor};\n    }\n\n    .middle {\n      height: 218px;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n    }\n\n    .footer {\n      display: flex;\n      align-items: center;\n      justify-content: center;\n    }\n  }\n  &.RedPacketClock {\n    .top {\n      height: 40px;\n      margin-top: 50px;\n    }\n    .middle {\n      margin-top: 40px;\n      height: 128px;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n    }\n\n    .betweenEle {\n      top: 328px;\n    }\n  }\n\n  &.redPacketOpened {\n    .top {\n      color: ${({ type }) => RedPacketCssColorConfig[type]?.highLightColor};\n    }\n  }\n\n  &.redPacketOpened,\n  &.redPacketOpen {\n    .redPacketNFT {\n      margin-top: 48px;\n      padding-top: 0;\n      width: var(--nft-large-avatar);\n      height: var(--nft-large-avatar);\n    }\n\n    .RedPacketReceived .redPacketNFT {\n      margin-top: 20px;\n    }\n  }\n\n  //&.redPacketOpened {\n  //  .content {\n  //\n  //  }\n  //}\n` as (props: BoxProps & { imageSrc?: string; type: string }) => JSX.Element\n\nexport const BoxClaim = styled(Box)`\n  &.self {\n    //background-color: var(--field-opacity);\n  }\n` as typeof Box\n\nexport const RedPacketSize = {\n  middle: {\n    height: 414,\n    width: 260,\n  },\n  large: {\n    height: 600,\n    width: 320,\n  },\n}\n\nconst qrCode = new QRCodeStyling({\n  type: 'svg',\n  width: 200,\n  height: 200,\n  image: `${SoursURL + 'svg/loopring.svg'}`,\n  dotsOptions: {\n    gradient: {\n      type: 'linear',\n      rotation: 45,\n      colorStops: [\n        {\n          offset: 0,\n          color: '#4169FF', // hardcode for export png\n        },\n        {\n          offset: 1,\n          color: '#000',\n        },\n      ],\n    },\n    type: 'dots',\n  },\n  backgroundOptions: {\n    color: '#ffffff', //colorConfig.bgColor\n  },\n  imageOptions: {\n    crossOrigin: 'anonymous',\n    margin: 4,\n  },\n  cornersSquareOptions: {\n    type: 'extra-rounded',\n  },\n  cornersDotOptions: {\n    type: 'square',\n  },\n})\n\nexport const RedPacketQRCode = ({\n  type = 'default',\n  imageEleUrl,\n  url,\n  ...rest\n}: RedPacketDefault & RedPacketQRCodeProps) => {\n  const qrcodeRef = React.createRef<SVGGElement>()\n  const ref = React.useRef()\n  \n  const [qrCodeG, setQrCodeG] = React.useState<string | undefined>(undefined)\n\n  const updateSvg = React.useCallback(async () => {\n    qrCode.update({\n      data: url,\n    })\n    const svgEle = await qrCode._getElement('svg')\n    setQrCodeG(svgEle?.innerHTML)\n  }, [url])\n  React.useEffect(() => {\n    updateSvg()\n  }, [url])\n  const onClick = (e: React.MouseEvent<SVGGElement, MouseEvent>) => {\n    try {\n      // @ts-ignore-start\n      const svg: SVGElement = ref.current as SVGElement\n      const w = parseInt(svg.getAttribute('width') ?? '334')\n      const h = parseInt(svg.getAttribute('height') ?? '603')\n      if (svg && svg.outerHTML) {\n        const canvas = document.createElement('canvas')\n        const base64doc = btoa(unescape(encodeURIComponent(svg.outerHTML)))\n        const img_to_download = document.createElement('img')\n        img_to_download.src = 'data:image/svg+xml;base64,' + base64doc\n        img_to_download.onload = function () {\n          canvas.setAttribute('width', w.toString())\n          canvas.setAttribute('height', h.toString())\n          // @ts-ignore\n          const context: CanvasRenderingContext2D = canvas.getContext('2d')\n          context.drawImage(img_to_download, 0, 0, w, h)\n          const dataURL = canvas.toDataURL('image/png')\n          // @ts-ignore\n          if (window.navigator.msSaveBlob) {\n            // @ts-ignore\n            window.navigator.msSaveBlob(\n              // @ts-ignore\n              canvas.msToBlob(),\n              'Loopring_Red_Packet.png',\n            )\n            e.preventDefault()\n          } else {\n            const a = document.createElement('a')\n            const my_evt = new MouseEvent('click')\n            a.download = 'Loopring_Red_Packet.png'\n            a.href = dataURL\n            a.dispatchEvent(my_evt)\n          }\n          //canvas.parentNode.removeChild(canvas);\n        }\n      }\n      // @ts-ignore-end\n    } catch (error) {}\n  }\n  return (\n    <>\n      {qrCodeG && (\n        <Box>\n          <RedPacketQRCodeSvg\n            ref={ref}\n            {...{ ...RedPacketColorConfig[type], ...rest }}\n            qrcodeRef={qrcodeRef}\n            imageEleUrl={imageEleUrl}\n            qrCodeG={qrCodeG}\n            type={type}\n            onClickShareButton={onClick}\n          />\n        </Box>\n      )}\n    </>\n  )\n}\n\nexport const RedPacketBgDefault = ({\n  type = 'default',\n  size = 'middle',\n  className,\n  content,\n}: RedPacketDefaultBg & any) => {\n  const scale = RedPacketSize[size].width / 260\n\n  return (\n    <RedPacketBg\n      type={type}\n      sx={{\n        transform: `scale(${scale})`,\n      }}\n      className={className ?? 'redPacketOpen'}\n    >\n      <Box\n        className={'bg'}\n        position={'absolute'}\n        top={0}\n        left={0}\n        right={0}\n        bottom={0}\n        zIndex={100}\n        display={'flex'}\n        justifyContent={'center'}\n        marginTop={1}\n      >\n        <RedPacketWrapSVG\n          {...{ ...RedPacketCssColorConfig[type] }}\n          height={'100%'}\n          width={'100%'}\n          type={type}\n          // height={RedPacketSize[size].height}\n          // width={RedPacketSize[size].width}\n        />\n      </Box>\n      <Box\n        className={`content content${size}`}\n        position={'relative'}\n        zIndex={200}\n        height={RedPacketSize['middle'].height}\n        width={RedPacketSize['middle'].width}\n      >\n        {content}\n      </Box>\n    </RedPacketBg>\n  )\n}\n\nexport const RedPacketBgOpened = ({\n  type = 'default',\n  size = 'middle',\n  content,\n}: RedPacketDefaultBg & any) => {\n  const scale = RedPacketSize[size].width / 260\n\n  return (\n    <RedPacketBg\n      type={type}\n      sx={{\n        transform: `scale(${scale})`,\n      }}\n      className={'redPacketOpened'}\n    >\n      <Box\n        position={'absolute'}\n        top={0}\n        left={0}\n        right={0}\n        bottom={0}\n        zIndex={100}\n        display={'flex'}\n        justifyContent={'center'}\n      >\n        <RedPacketOpenWrapSVG\n          {...{ ...RedPacketCssColorConfig[type] }}\n          height={'100%'}\n          width={'100%'}\n          type={type}\n        />\n      </Box>\n      <Box\n        className={`content content${size}`}\n        position={'relative'}\n        zIndex={200}\n        height={RedPacketSize['middle'].height}\n      >\n        {content}\n      </Box>\n    </RedPacketBg>\n  )\n}\n\nexport const RedPacketOpen = ({\n  type = 'default',\n  size,\n  sender,\n  amountStr,\n  memo,\n  viewDetail,\n  onOpen,\n  ImageEle,\n}: RedPacketDefault & RedPacketOpenProps) => {\n  const { t } = useTranslation()\n  const content = React.useMemo(() => {\n    return (\n      <Box display={'flex'} flex={1} onClick={onOpen} flexDirection={'column'}>\n        <Box display={'flex'} className={'betweenEle'} position={'absolute'}>\n          <Box display={'flex'} position={'absolute'} className={'open'}>\n            {t('labelRedPacketOpen')}\n          </Box>\n        </Box>\n        <Box display={'flex'} className={'top'} flexDirection={'column'}>\n          <Typography color={'inherit'}>{sender}</Typography>\n        </Box>\n        <Box display={'flex'} className={'middle'} flexDirection={'column'}>\n          {ImageEle}\n          <Typography\n            color={'inherit'}\n            variant={'h4'}\n            whiteSpace={'pre-line'}\n            textAlign={'center'}\n            paddingX={2}\n            paddingTop={1}\n          >\n            {amountStr}\n          </Typography>\n          <Typography\n            color={'inherit'}\n            variant={'body1'}\n            whiteSpace={'pre-line'}\n            textAlign={'center'}\n            overflow={'hidden'}\n            textOverflow={'ellipsis'}\n            paddingX={4}\n            sx={{\n              wordBreak: 'break-all',\n              display: '-webkit-box',\n              '-webkit-line-clamp': '2',\n              lineClamp: '2',\n              '-webkit-box-orient': 'vertical',\n            }}\n            dangerouslySetInnerHTML={{ __html: sanitize(memo ?? '') }}\n          />\n        </Box>\n        <Box display={'flex'} className={'footer'}>\n          {viewDetail && (\n            <Link\n              className={'viewDetail'}\n              whiteSpace={'pre-line'}\n              color={'inherit'}\n              variant={'body1'}\n              onClick={(e) => {\n                e.stopPropagation()\n                viewDetail()\n              }}\n            >\n              {t('labelLuckyRedPacketDetail')}\n            </Link>\n          )}\n        </Box>\n      </Box>\n    )\n  }, [size, sender, amountStr, memo, viewDetail, onOpen])\n\n  return <RedPacketBgDefault type={type} size={size} content={content} />\n}\n\nexport const RedPacketClock = ({\n  type = 'default',\n  size,\n  validSince,\n  sender,\n  memo,\n  showRedPacket,\n  ImageEle,\n}: RedPacketDefault & RedPacketClockProps) => {\n  const { t } = useTranslation('common')\n  const anchorRef = React.useRef()\n  const nodeTimer = React.useRef<NodeJS.Timeout | -1>(-1)\n  const [countDown, setCountDown] = React.useState<{\n    days: undefined | string\n    hours: undefined | string\n    seconds: undefined | string\n    minutes: undefined | string\n  }>()\n  const calculateTimeLeft = React.useCallback((validSince: number) => {\n    if (nodeTimer.current !== -1) {\n      clearTimeout(nodeTimer.current as NodeJS.Timeout)\n    }\n    let difference = +new Date(validSince).getTime() - Date.now()\n    if (difference > 0) {\n      setCountDown({\n        days: Math.floor(difference / (1000 * 60 * 60 * 24)).toString(),\n        hours: ('0' + Math.floor((difference / (1000 * 60 * 60)) % 24).toString()).slice(-2),\n        minutes: ('0' + Math.floor((difference / 1000 / 60) % 60).toString()).slice(-2),\n        seconds: ('0' + Math.floor((difference / 1000) % 60).toString()).slice(-2),\n      })\n      nodeTimer.current = setTimeout(() => calculateTimeLeft(validSince), 1000)\n    } else {\n      showRedPacket()\n    }\n  }, [])\n  React.useEffect(() => {\n    calculateTimeLeft(validSince)\n    return () => {\n      if (nodeTimer.current !== -1) {\n        clearTimeout(nodeTimer.current as NodeJS.Timeout)\n      }\n    }\n  }, [validSince])\n\n  const content = React.useMemo(() => {\n    return (\n      <>\n        <Box display={'flex'} className={'betweenEle'} position={'absolute'}>\n          <Box display={'flex'} flexDirection={'column'} position={'absolute'} className={'clock'}>\n            <Typography\n              display={'none'}\n              component={'span'}\n              variant={'body1'}\n              // marginBottom={1}\n            >\n              {t('labelCountDown')}\n            </Typography>\n            <Box display={'flex'} flexDirection={'row'} flex={1} ref={anchorRef}>\n              <Box\n                className={'hours'}\n                display={'flex'}\n                flexDirection={'column'}\n                alignItems={'center'}\n                marginRight={2}\n              >\n                <Typography variant={'h2'} component={'span'} color={'inherit'}>\n                  {Number(countDown?.hours) >= 0 ? countDown?.hours : EmptyValueTag}\n                </Typography>\n                <Typography\n                  variant={'h4'}\n                  color={'var(--color-text-secondary)'}\n                  display={'none'}\n                  style={{ textTransform: 'uppercase' }}\n                >\n                  {t('labelHours')}\n                </Typography>\n              </Box>\n              <Box\n                className={'minutes'}\n                display={'flex'}\n                flexDirection={'column'}\n                alignItems={'center'}\n                marginRight={2}\n              >\n                <Typography variant={'h2'} component={'span'} color={'inherit'}>\n                  {Number(countDown?.minutes) >= 0 ? countDown?.minutes : EmptyValueTag}\n                </Typography>\n                <Typography\n                  variant={'h4'}\n                  color={'var(--color-text-secondary)'}\n                  display={'none'}\n                  style={{ textTransform: 'uppercase' }}\n                >\n                  {t('labelMinutes')}\n                </Typography>\n              </Box>\n              <Box\n                className={'seconds'}\n                display={'flex'}\n                flexDirection={'column'}\n                alignItems={'center'}\n              >\n                <Typography variant={'h2'} component={'span'} color={'inherit'}>\n                  {Number(countDown?.seconds) >= 0 ? countDown?.seconds : EmptyValueTag}\n                </Typography>\n                <Typography\n                  variant={'h4'}\n                  color={'var(--color-text-secondary)'}\n                  display={'none'}\n                  style={{ textTransform: 'uppercase' }}\n                >\n                  {t('labelSeconds')}\n                </Typography>\n              </Box>\n            </Box>\n          </Box>\n        </Box>\n\n        <Box display={'flex'} className={'top'} flexDirection={'column'}>\n          <Typography color={'inherit'}>{sender}</Typography>\n        </Box>\n        <Typography\n          color={'inherit'}\n          variant={'body1'}\n          whiteSpace={'pre-line'}\n          textAlign={'center'}\n          overflow={'hidden'}\n          textOverflow={'ellipsis'}\n          paddingX={4}\n          sx={{\n            wordBreak: 'break-all',\n            display: '-webkit-box',\n            '-webkit-line-clamp': '2',\n            lineClamp: '2',\n            '-webkit-box-orient': 'vertical',\n          }}\n          dangerouslySetInnerHTML={{ __html: sanitize(memo ?? '') }}\n        />\n        <Box display={'flex'} className={'middle'} flexDirection={'column'}>\n          {ImageEle}\n        </Box>\n      </>\n    )\n  }, [countDown])\n  return (\n    <RedPacketBgDefault className={'RedPacketClock'} type={type} size={size} content={content} />\n  )\n}\n\nexport const RedPacketUnready = ({\n  type = 'default',\n  size,\n  sender,\n  validSince,\n  amountStr,\n  memo,\n  ImageEle,\n  onClickOpen,\n}: // ImageEle,\nRedPacketDefault & RedPacketUnreadyProps) => {\n  const { t } = useTranslation()\n  const content = React.useMemo(() => {\n    return (\n      <Box display={'flex'} flex={1} flexDirection={'column'}>\n        <Box onClick={onClickOpen} display={'flex'} className={'betweenEle'} position={'absolute'}>\n          <Box display={'flex'} position={'absolute'} className={'open'}>\n            {t('labelRedPacketOpen')}\n          </Box>\n        </Box>\n        <Box display={'flex'} className={'top'} flexDirection={'column'}>\n          <Typography color={'inherit'}>{sender}</Typography>\n        </Box>\n        <Box display={'flex'} className={'middle'} flexDirection={'column'} position={'relative'}>\n          <Typography color={'inherit'} position={'absolute'} marginTop={3} top={0}>\n            {`${moment(validSince).format(DAY_MINUTE_FORMAT)} ${t('labelOpenStart')}`}\n          </Typography>\n          {ImageEle}\n          <Typography\n            color={'inherit'}\n            variant={'h4'}\n            whiteSpace={'pre-line'}\n            textAlign={'center'}\n            paddingX={2}\n            paddingTop={1}\n          >\n            {amountStr}\n          </Typography>\n          <Typography\n            color={'inherit'}\n            variant={'body1'}\n            whiteSpace={'pre-line'}\n            textAlign={'center'}\n            overflow={'hidden'}\n            textOverflow={'ellipsis'}\n            paddingX={4}\n            sx={{\n              wordBreak: 'break-all',\n              display: '-webkit-box',\n              '-webkit-line-clamp': '2',\n              lineClamp: '2',\n              '-webkit-box-orient': 'vertical',\n            }}\n            dangerouslySetInnerHTML={{ __html: sanitize(memo ?? '') }}\n          />\n        </Box>\n      </Box>\n    )\n  }, [size, sender, amountStr, memo])\n\n  return <RedPacketBgDefault type={type} size={size} content={content} />\n}\n\nexport const RedPacketOpened = ({\n  type = 'default',\n  size,\n  sender,\n  memo,\n  myAmountStr,\n  amountStr,\n  viewDetail,\n  ImageEle,\n}: RedPacketDefault & RedPacketOpenedProps) => {\n  const { t } = useTranslation('common')\n  const content = React.useMemo(() => {\n    return (\n      <Box display={'flex'} flex={1} flexDirection={'column'}>\n        <Box display={'flex'} className={'top'} flexDirection={'column'}>\n          <Typography\n            variant={'h5'}\n            color={RedPacketCssColorConfig[type].highLightColor}\n            marginTop={type === 'blindbox' ? 2 : 0}\n          >\n            {type === 'blindbox'\n              ? t('labelRedPacketBlindboxReceived1')\n              : t('labelRedPacketReceived')}\n          </Typography>\n          {type === 'blindbox' && (\n            <Typography variant={'h5'} color={RedPacketCssColorConfig[type].highLightColor}>\n              {t('labelRedPacketBlindboxReceived2')}\n            </Typography>\n          )}\n          {type !== 'blindbox' && (\n            <>\n              <Typography\n                variant={'h4'}\n                color={RedPacketCssColorConfig[type].highLightColor}\n                marginTop={1}\n              >\n                {myAmountStr ? myAmountStr : EmptyValueTag}\n              </Typography>\n              <Typography variant={'body2'} color={RedPacketCssColorConfig[type].highLightColor}>\n                {t('labelTotalRedPacket', { value: amountStr })}\n              </Typography>\n            </>\n          )}\n        </Box>\n        <Box display={'flex'} className={'middle RedPacketReceived'} flexDirection={'column'}>\n          {ImageEle}\n          <Typography color={'inherit'}>{sender}</Typography>\n          <Typography\n            variant={'body2'}\n            color={'inherit'}\n            whiteSpace={'pre-line'}\n            textAlign={'center'}\n            marginTop={1 / 2}\n            overflow={'hidden'}\n            textOverflow={'ellipsis'}\n            paddingX={4}\n            sx={{\n              wordBreak: 'break-all',\n              display: '-webkit-box',\n              '-webkit-line-clamp': '2',\n              lineClamp: '2',\n              '-webkit-box-orient': 'vertical',\n            }}\n            dangerouslySetInnerHTML={{ __html: sanitize(memo ?? '') }}\n            width={300}\n          />\n        </Box>\n        <Box display={'flex'} className={'footer'}>\n          <Link\n            className={'viewDetail'}\n            whiteSpace={'pre-line'}\n            color={'inherit'}\n            variant={'body1'}\n            onClick={(e) => {\n              e.stopPropagation()\n              viewDetail()\n            }}\n          >\n            {t('labelLuckyRedPacketDetail')}\n          </Link>\n        </Box>\n      </Box>\n    )\n  }, [type])\n  return <RedPacketBgOpened type={type} content={content} size={size} />\n}\n\nexport const RedPacketDetailStyled = styled(Box)`\n  border-radius: ${({ theme }) => theme.unit}px;\n  background-color: var(--color-box);\n` as typeof Box\n\nexport const RedPacketTimeout = ({\n  type = 'default',\n  size,\n  sender,\n  memo,\n  viewDetail,\n}: RedPacketTimeoutProps) => {\n  const { t } = useTranslation('common')\n  const content = React.useMemo(() => {\n    return (\n      <Box\n        className={`content content${size}`}\n        position={'relative'}\n        zIndex={200}\n        display={'flex'}\n        flexDirection={'column'}\n        justifyContent={'stretch'}\n        // alignItems={\"s\"}\n        height={RedPacketSize['middle'].height}\n      >\n        <Box display={'flex'} className={'top'} flexDirection={'column'}>\n          <Typography\n            color={'inherit'}\n            variant={'h4'}\n            className={'timeoutTitle'}\n            whiteSpace={'pre-line'}\n            paddingTop={2}\n            textAlign={'center'}\n          >\n            {t('labelLuckyRedPacketTimeout')}\n          </Typography>\n          <Typography paddingTop={1 / 2} className={'secondary'}>\n            {sender}\n          </Typography>\n        </Box>\n        <Box display={'flex'} className={'middle'}>\n          <Typography\n            color={'inherit'}\n            variant={'body1'}\n            whiteSpace={'pre-line'}\n            textAlign={'center'}\n            overflow={'hidden'}\n            textOverflow={'ellipsis'}\n            paddingX={4}\n            sx={{\n              wordBreak: 'break-all',\n              display: '-webkit-box',\n              '-webkit-line-clamp': '2',\n              lineClamp: '2',\n              '-webkit-box-orient': 'vertical',\n            }}\n            dangerouslySetInnerHTML={{ __html: sanitize(memo ?? '') }}\n          />\n        </Box>\n        <Box display={'flex'} className={'footer'}>\n          {viewDetail && (\n            <Link\n              className={'viewDetail'}\n              whiteSpace={'pre-line'}\n              color={'inherit'}\n              variant={'body1'}\n              onClick={(e) => {\n                e.stopPropagation()\n                viewDetail()\n              }}\n            >\n              {t('labelLuckyRedPacketDetail')}\n            </Link>\n          )}\n        </Box>\n      </Box>\n    )\n  }, [])\n  return <RedPacketBgOpened type={type} content={content} size={size} />\n}\n\nconst BoxStyle = styled(Box)`\n  background: var(--color-box);\n  border-radius: ${({ theme }) => theme.unit}px;\n\n  .redPacketNFT {\n    margin-top: ${({ theme }) => 2 * theme.unit}px;\n    padding-top: var(--nft-large-avatar);\n  }\n\n  .top {\n    border-radius: ${({ theme }) => theme.unit}px;\n    border-bottom-right-radius: 100%;\n    border-bottom-left-radius: 100%;\n  }\n`\n\nexport const RedPacketDetail = ({\n  redPacketType,\n  sender,\n  amountStr,\n  // _amountClaimStr,\n  memo,\n  // page = 1,\n  claimList,\n  // detail,\n  // detail,\n  handlePageChange,\n  myAmountStr,\n  totalCount,\n  remainCount,\n  onShared,\n  relyNumber,\n  relyAmount,\n  ImageEle,\n  showRelayText,\n  tokenSymbol,\n  detail,\n  bottomButton,\n  page,\n  onClickClaim,\n  claimButton,\n  totalNumber,\n  showReceiptListBtn,\n}: RedPacketDetailProps) => {\n  const { t } = useTranslation('common')\n  const showLucky = detail.luckyToken?.tokenAmount?.remainCount == 0\n  const limit = detail.luckyToken.isNft ? RedPacketNFTDetailLimit : RedPacketDetailLimit\n  const pageNation = totalNumber - limit > 0 && (\n    <TablePagination\n      size={'small'}\n      page={page}\n      pageSize={limit}\n      total={totalNumber}\n      onPageChange={(_page) => {\n        handlePageChange(_page)\n      }}\n    />\n  )\n  const theme = useTheme()\n  const isTarget = detail.luckyToken.type.scope === sdk.LuckyTokenViewType.TARGET\n  const [showExclusiveReceipt, setShowExclusiveReceipt] = React.useState(false)\n\n  return (\n    <BoxStyle\n      flex={1}\n      width={RedPacketSize.large.width}\n      height={RedPacketSize.large.height}\n      display={'flex'}\n      paddingBottom={1}\n      flexDirection={'column'}\n      overflow={'scroll'}\n    >\n      <Box\n        className={'top'}\n        width={'100%'}\n        sx={{\n          background: RedPacketColorConfig.default.startColor,\n          height: '88px',\n        }}\n        display={'flex'}\n        alignItems={'center'}\n        justifyContent={'center'}\n      >\n        <Typography variant={'body1'} color={RedPacketColorConfig.default.fontColor}>\n          {t(`label${redPacketType}RedPacket`)}\n        </Typography>\n      </Box>\n      <Box display={'flex'} flexDirection={'column'} alignItems={'center'} marginY={2}>\n        <Typography marginLeft={isTarget ? 8.5 : 0} variant={'body1'}>\n          {sender}\n          {isTarget && (\n            <Typography\n              marginLeft={0.5}\n              borderRadius={1}\n              paddingX={0.5}\n              bgcolor={hexToRGB(theme.colorBase.warning, 0.5)}\n              color={'var(--color-warning)'}\n              component={'span'}\n            >\n              {t('labelRedPacketExclusiveTag')}\n            </Typography>\n          )}\n        </Typography>\n        <Typography\n          variant={'body2'}\n          color={'var(--color-text-third)'}\n          whiteSpace={'pre-line'}\n          textAlign={'center'}\n          marginTop={1 / 2}\n          overflow={'hidden'}\n          textOverflow={'ellipsis'}\n          paddingX={4}\n          sx={{\n            wordBreak: 'break-all',\n            display: '-webkit-box',\n            '-webkit-line-clamp': '2',\n            lineClamp: '2',\n            '-webkit-box-orient': 'vertical',\n          }}\n        >\n          {memo ?? ''}{' '}\n        </Typography>\n        {ImageEle}\n        <Typography variant={'h3'} color={RedPacketColorConfig.default.colorTop} marginTop={1}>\n          {myAmountStr ? myAmountStr : EmptyValueTag}\n        </Typography>\n        <Typography variant={'body2'} color={RedPacketColorConfig.default.colorTop}>\n          {t('labelTotalRedPacket', { value: amountStr })}\n        </Typography>\n      </Box>\n      {/*<Divider orientation={\"horizontal\"} sx={{ borderWidth: 3 }} />*/}\n      <Box flex={1} display={'flex'} justifyContent={'stretch'} flexDirection={'column'}>\n        <Typography\n          variant={'body1'}\n          color={'var(--color-text-third)'}\n          marginY={1}\n          paddingX={1}\n          paddingY={1}\n          sx={{ background: 'var(--color-divide)' }}\n        >\n          {t('labelRedPacketReceivedRecord', {\n            value: totalCount - remainCount,\n            count: totalCount,\n          })}\n        </Typography>\n        {/*<Divider*/}\n        {/*  orientation={\"horizontal\"}*/}\n        {/*  sx={{ borderWidth: 1, paddingX: 1 }}*/}\n        {/*/>*/}\n        <Box flex={1}>\n          {claimList &&\n            claimList.map((item, index) => {\n              return (\n                <BoxClaim\n                  className={item.isSelf ? 'self claim' : 'claim'}\n                  display={'flex'}\n                  justifyContent={'stretch'}\n                  flexDirection={'column'}\n                  paddingTop={1 / 2}\n                  paddingX={1}\n                >\n                  <Typography\n                    component={'span'}\n                    display={'inline-flex'}\n                    flexDirection={'row'}\n                    justifyContent={'space-between'}\n                    alignItems={'center'}\n                    paddingX={1}\n                  >\n                    <Typography\n                      variant={'body1'}\n                      component={'span'}\n                      color={item.isSelf ? 'success' : 'textPrimary'}\n                    >\n                      {item.accountStr}\n                      {item.isSelf ? ` (${t('labelRedPacketMe')})` : ''}\n                    </Typography>\n                    <Typography variant={'body1'} component={'span'} color={'textPrimary'}>\n                      {item.amountStr}\n                    </Typography>\n                  </Typography>\n                  <Typography\n                    component={'span'}\n                    display={'inline-flex'}\n                    flexDirection={'row'}\n                    justifyContent={'space-between'}\n                    alignItems={'center'}\n                    paddingX={1}\n                  >\n                    <Typography\n                      variant={'body2'}\n                      component={'span'}\n                      color={'var(--color-text-third)'}\n                    >\n                      {moment(new Date(item.createdAt), 'YYYYMMDDHHMM').fromNow()}\n                    </Typography>\n                    <Typography display={'inline'}>\n                      {item.helper && (\n                        <Typography\n                          component={'span'}\n                          color={'var(--color-primary)'}\n                          display={'inline-flex'}\n                          alignItems={'center'}\n                          variant={'body2'}\n                        >\n                          {item.helper} Help\n                        </Typography>\n                      )}\n                      {showLucky &&\n                        (redPacketType === 'lucky' || redPacketType === 'relay') &&\n                        item.isMax && (\n                          <Typography\n                            component={'span'}\n                            color={'var(--color-warning)'}\n                            display={'inline-flex'}\n                            alignItems={'center'}\n                            variant={'body2'}\n                            marginLeft={1}\n                          >\n                            <FirstPlaceIcon fontSize={'medium'} sx={{ paddingRight: 1 / 2 }} />\n                            {t('labelLuckDraw')}\n                          </Typography>\n                        )}\n                    </Typography>\n                  </Typography>\n\n                  {index + 1 !== claimList.length && (\n                    <Divider\n                      orientation={'horizontal'}\n                      sx={{\n                        borderWidth: 1 / 2,\n                        paddingX: 1,\n                        marginTop: 1 / 2,\n                      }}\n                    />\n                  )}\n                </BoxClaim>\n              )\n            })}\n        </Box>\n        {pageNation}\n      </Box>\n      {showReceiptListBtn && (\n        <Button\n          variant={'text'}\n          sx={{ fontSize: '13px' }}\n          onClick={() => {\n            setShowExclusiveReceipt(true)\n          }}\n        >\n          {t('labelRedPacketReceiptsList')}\n        </Button>\n      )}\n      <ReceiptListModal\n        open={showExclusiveReceipt}\n        t={t}\n        onClose={() => setShowExclusiveReceipt(false)}\n        targets={(detail as any).targets}\n      />\n      {/* {showShareBtn && ( */}\n      <Box paddingX={1} display={'flex'} flexDirection={'column'}>\n        {claimButton === 'claim' ? (\n          <Button variant={'contained'} fullWidth onClick={onClickClaim}>\n            {t('labelClaimBtn')}\n          </Button>\n        ) : claimButton === 'expired' && bottomButton === 'hidden' ? (\n          <Button variant={'contained'} fullWidth disabled>\n            {t('labelClaimBtnExpired')}\n          </Button>\n        ) : claimButton === 'claimed' && bottomButton === 'hidden' ? (\n          <Button variant={'contained'} fullWidth disabled>\n            {t('labelClaimBtnClaimed')}\n          </Button>\n        ) : claimButton === 'claiming' && bottomButton === 'hidden' ? (\n          <Button variant={'contained'} fullWidth disabled>\n            {t('labelRedPacketClaiming')}\n          </Button>\n        ) : (\n          <></>\n        )}\n        {bottomButton === 'share' ? (\n          claimButton === 'claim' ? (\n            <Button variant={'text'} size={'small'} onClick={onShared}>\n              {t('labelRedPacketGrab')}\n            </Button>\n          ) : (\n            <Button\n              variant={'contained'}\n              color={'error'}\n              sx={{\n                backgroundColor: RedPacketColorConfig.default.colorTop as any,\n                '&:hover': {\n                  backgroundColor: RedPacketColorConfig.default.colorTop as any,\n                },\n              }}\n              fullWidth={true}\n              onClick={onShared}\n            >\n              {t('labelRedPacketGrab')}\n            </Button>\n          )\n        ) : (\n          bottomButton === 'ended' && (\n            <Button\n              variant={'contained'}\n              color={'error'}\n              sx={{\n                backgroundColor: RedPacketColorConfig.default.colorTop as any,\n                '&:hover': {\n                  backgroundColor: RedPacketColorConfig.default.colorTop as any,\n                },\n              }}\n              fullWidth={true}\n              disabled\n            >\n              {t('labelRedPacketEnded')}\n            </Button>\n          )\n        )}\n\n        {showRelayText && (\n          <Typography\n            color={'textSecondary'}\n            variant={'body2'}\n            textAlign={'center'}\n            paddingTop={1}\n            component={'span'}\n          >\n            <Trans\n              i18nKey={'labelRedpacketHavePeopleHelp'}\n              tOptions={{\n                number: relyNumber ? relyNumber : EmptyValueTag,\n                amount:\n                  relyAmount && !sdk.toBig(relyAmount).isZero()\n                    ? relyAmount + (tokenSymbol ? ` ${tokenSymbol}` : '')\n                    : EmptyValueTag,\n              }}\n            >\n              have\n              <Typography\n                variant={'inherit'}\n                component={'span'}\n                color={RedPacketColorConfig.default.startColor}\n              >\n                {relyNumber ?? EmptyValueTag}\n              </Typography>\n              friends help you pick up Redpacket, you extends reward:\n              <Typography\n                variant={'inherit'}\n                component={'span'}\n                color={RedPacketColorConfig.default.fontColor}\n              >\n                {relyAmount ?? EmptyValueTag}\n              </Typography>\n            </Trans>\n          </Typography>\n        )}\n      </Box>\n      {/* )} */}\n    </BoxStyle>\n  )\n}\n\nexport const RedPacketPrepare = ({\n  chainId,\n  account,\n  tokenInfo,\n  setShowRedPacket,\n  claim,\n  _type = 'default',\n  amountStr,\n  myAmountStr,\n  onOpen,\n  getIPFSString,\n  baseURL,\n  claimed,\n  ...props\n}: {\n  chainId: sdk.ChainId\n  account: Account\n  amountStr: string\n  tokenInfo: sdk.TokenInfo\n  claim: string | undefined\n  myAmountStr: string | undefined\n  setShowRedPacket: (\n    state: ModalStatePlayLoad & {\n      step?: number\n      info?: { [key: string]: any }\n    },\n  ) => void\n  baseURL: string\n  getIPFSString: GET_IPFS_STRING\n  onOpen: () => void\n  _type?: 'official' | 'default' | 'blindbox'\n  claimed: boolean\n} & sdk.LuckyTokenItemForReceive) => {\n  // const { t } = useTranslation(\"common\");\n  const ref = React.createRef()\n  const _info = props as sdk.LuckyTokenItemForReceive\n  // const props.isNft;\n  const ImageEle = React.useMemo(() => {\n    return props.isNft ? (\n      <BoxNFT flex={1} position={'relative'} className={'redPacketNFT'}>\n        <Box\n          position={'absolute'}\n          top={0}\n          right={0}\n          bottom={0}\n          left={0}\n          display={'flex'}\n          alignItems={'center'}\n          justifyContent={'center'}\n        >\n          <NFTMedia\n            ref={ref}\n            item={props.nftTokenInfo as Partial<NFTWholeINFO>}\n            shouldPlay={true}\n            onNFTError={() => undefined}\n            isOrigin={true}\n            getIPFSString={getIPFSString}\n            baseURL={baseURL}\n          />\n        </Box>\n      </BoxNFT>\n    ) : (\n      <></>\n    )\n  }, [props])\n\n  // following code is for triggering rerender\n  const getDifferenceStatus = () => {\n    const difference = new Date(_info.validSince).getTime() - Date.now()\n    return difference > 180000 ? 0 : difference > 0 ? 1 : 2\n  }\n  const [differenceStatus, setDifferenceStatus] = React.useState(getDifferenceStatus())\n  React.useEffect(() => {\n    setInterval(() => {\n      setDifferenceStatus(getDifferenceStatus)\n    }, 1000)\n  }, [])\n  const viewItem = React.useMemo(() => {\n    let difference = new Date(_info.validSince).getTime() - Date.now()\n    if (claimed) {\n      return (\n        <RedPacketOpened\n          {...{\n            ...props,\n          }}\n          ImageEle={ImageEle}\n          amountStr={amountStr}\n          myAmountStr={myAmountStr}\n          viewDetail={() => {\n            if (_info.type.mode === sdk.LuckyTokenClaimType.BLIND_BOX) {\n              setShowRedPacket({\n                isShow: true,\n                step: RedPacketViewStep.BlindBoxDetail,\n                info: {\n                  ..._info,\n                },\n              })\n            } else {\n              setShowRedPacket({\n                isShow: true,\n                step: RedPacketViewStep.DetailPanel,\n                info: {\n                  ..._info,\n                },\n              })\n            }\n          }}\n          sender={props?.sender?.ens ? props?.sender?.ens : getShortAddr(props?.sender?.address)}\n          memo={props?.info?.memo}\n          type={_type}\n        />\n      )\n    } else if (difference > 180000) {\n      return (\n        <RedPacketUnready\n          sender={props?.sender?.ens ? props?.sender?.ens : getShortAddr(props?.sender?.address)}\n          {...props?.info}\n          ImageEle={ImageEle}\n          amountStr={amountStr}\n          validSince={_info.validSince}\n          type={_type}\n          onClickOpen={() => {\n            // if (_info.type.mode === sdk.LuckyTokenClaimType.BLIND_BOX) {\n            setShowRedPacket({\n              isShow: true,\n              step: RedPacketViewStep.RedPacketClock,\n              info: {\n                ..._info,\n              },\n            })\n          }}\n        />\n      )\n    } else if (difference > 0) {\n      return (\n        <RedPacketClock\n          {...props?.info}\n          ImageEle={ImageEle}\n          sender={props?.sender?.ens ? props?.sender?.ens : getShortAddr(props?.sender?.address)}\n          showRedPacket={() => {\n            // do nothing\n            // setShowRedPacket({\n            //   isShow: true,\n            //   step: RedPacketViewStep.OpenPanel,\n            //   info: _info,\n            // });\n          }}\n          amountStr={amountStr}\n          validSince={_info.validSince}\n          type={_type}\n        />\n      )\n    } else if (\n      // difference + 86400000 < 0 ||\n      _info.status == sdk.LuckyTokenItemStatus.COMPLETED ||\n      _info.status == sdk.LuckyTokenItemStatus.OVER_DUE ||\n      _info.tokenAmount.remainCount === 0\n    ) {\n      return (\n        <RedPacketTimeout\n          {...props?.info}\n          ImageEle={ImageEle}\n          sender={props?.sender?.ens ? props?.sender?.ens : getShortAddr(props?.sender?.address)}\n          type={_type ?? 'default'}\n          viewDetail={() => {\n            if (_info.type.mode === sdk.LuckyTokenClaimType.BLIND_BOX) {\n              setShowRedPacket({\n                isShow: true,\n                step: RedPacketViewStep.BlindBoxDetail,\n                info: {\n                  ..._info,\n                },\n              })\n            } else {\n              setShowRedPacket({\n                isShow: true,\n                step: RedPacketViewStep.DetailPanel,\n                info: {\n                  ..._info,\n                },\n              })\n            }\n          }}\n        />\n      )\n    } else {\n      return (\n        <RedPacketOpen\n          {...{\n            ...props,\n          }}\n          ImageEle={ImageEle ?? undefined}\n          type={_type}\n          amountStr={amountStr}\n          sender={props?.sender?.ens ? props?.sender?.ens : getShortAddr(props?.sender?.address)}\n          memo={props?.info?.memo}\n          onOpen={() => {\n            setShowRedPacket({\n              isShow: false,\n              step: RedPacketViewStep.Loading,\n              info: _info,\n            })\n            onOpen()\n          }}\n          viewDetail={\n            _info.sender.accountId === account.accountId\n              ? () => {\n                  if (_info.type.mode === sdk.LuckyTokenClaimType.BLIND_BOX) {\n                    setShowRedPacket({\n                      isShow: true,\n                      step: RedPacketViewStep.BlindBoxDetail,\n                      info: {\n                        ..._info,\n                      },\n                    })\n                  } else {\n                    setShowRedPacket({\n                      isShow: true,\n                      step: RedPacketViewStep.DetailPanel,\n                      info: {\n                        ..._info,\n                      },\n                    })\n                  }\n                }\n              : undefined\n          }\n        />\n      )\n    }\n  }, [amountStr, claim, myAmountStr, onOpen, _info, differenceStatus])\n  return <Box>{viewItem}</Box>\n}\n\nconst BlindBoxDetailBoxStyle = styled(Box)`\n  background: var(--color-box);\n  border-radius: ${({ theme }) => theme.unit}px;\n\n  .redPacketNFT {\n    margin-top: ${({ theme }) => 2 * theme.unit}px;\n    padding-top: var(--nft-large-avatar);\n  }\n\n  .top {\n    border-radius: ${({ theme }) => theme.unit}px;\n    border-bottom-right-radius: 100%;\n    border-bottom-left-radius: 100%;\n  }\n\n  .viewDetail {\n    color: ${RedPacketCssColorConfig.default?.primaryColor};\n\n    &:hover {\n      text-decoration: underline;\n    }\n  }\n`\n\nexport const RedPacketBlindBoxDetail = ({\n  sender,\n  memo,\n  type,\n  NFTURL,\n  blindBoxStartTime,\n  lotteryStartTime,\n  lotteryEndTime,\n  opendBlindBoxAmount,\n  totalBlindBoxAmount,\n  deliverdGiftsAmount,\n  totalGiftsAmount,\n  onShared,\n  onClickViewDetail,\n  NFTClaimList,\n  BlindBoxClaimList,\n  showOpenLottery,\n  wonPrizeInfo,\n  onClickClaim,\n  onCloseOpenModal,\n  onClickClaimDetailBack,\n  description,\n  shareButton,\n  claimButton,\n  didClaimABlindBox,\n  wonInfo,\n  page,\n  handlePageChange,\n  totalClaimedNFTsCount,\n  handlePageChange_BlindBox,\n  pageForBlindbox,\n  totalBlindboxCount,\n  onClickClaimPopViewDetail,\n  expired,\n  isTokenBlindbox,\n  remainGiftsAmount,\n  showReceiptListBtn,\n  targets,\n}: RedPacketBlindBoxDetailProps) => {\n  const { t } = useTranslation('common')\n  const theme = useTheme()\n  const emptyImg =\n    theme.mode === 'dark'\n      ? SoursURL + 'images/redpackBlind1.webp'\n      : SoursURL + 'images/redpackBlind2.webp'\n  const [showExclusiveReceipt, setShowExclusiveReceipt] = React.useState(false)\n\n  const pageNation = totalClaimedNFTsCount - RedPacketNFTDetailLimit > 0 && (\n    <Box width={'100%'}>\n      <TablePagination\n        page={page}\n        pageSize={RedPacketNFTDetailLimit}\n        total={totalClaimedNFTsCount}\n        onPageChange={(_page) => {\n          handlePageChange(_page)\n        }}\n        size={'small'}\n      />\n    </Box>\n  )\n  const pageNationBlindBox = totalBlindboxCount - RedPacketBlindBoxLimit > 0 && (\n    <TablePagination\n      page={pageForBlindbox}\n      pageSize={RedPacketBlindBoxLimit}\n      total={totalBlindboxCount}\n      onPageChange={(_page) => {\n        handlePageChange_BlindBox(_page)\n      }}\n      size={'small'}\n    />\n  )\n\n  const LooteryModal = (\n    <Modal open={showOpenLottery === true} onClose={onCloseOpenModal}>\n      <>\n        <Box height={'100%'} display={'flex'} justifyContent={'center'} alignItems={'center'}>\n          <Box\n            padding={5}\n            bgcolor={'var(--color-box)'}\n            width={'var(--modal-width)'}\n            borderRadius={1}\n            display={'flex'}\n            alignItems={'center'}\n            flexDirection={'column'}\n            position={'relative'}\n          >\n            {/* <Box></Box> */}\n            <ModalCloseButtonPosition right={2} top={2} t={t} onClose={onCloseOpenModal!} />\n            <Typography marginBottom={3} variant={'h3'}>\n              {wonPrizeInfo ? t('labelBlindBoxCongratulations') : t('labelBlindBoxSorry')}\n            </Typography>\n            {wonPrizeInfo ? (\n              wonPrizeInfo.isNFT ? (\n                <>\n                  <Typography variant={'h5'}>{wonPrizeInfo.name} </Typography>\n                  <img width={'40%'} alt={''} src={wonPrizeInfo.url} />\n                </>\n              ) : (\n                <>\n                  <Box marginTop={3} />\n                  <CoinIcon symbol={wonPrizeInfo.tokenName} size={48} />\n                  {/* <img width={6} alt={\"\"} src={wonPrizeInfo.tokenURL} /> */}\n                  <Typography marginTop={2} marginBottom={3} variant={'h2'}>\n                    {wonPrizeInfo.amountStr}\n                  </Typography>\n                  <Typography width={`${25 * theme.unit}px`} textAlign={'center'} variant={'body2'}>\n                    {t('labelBlindBoxClaimHint')}\n                  </Typography>\n                </>\n              )\n            ) : (\n              <>\n                <Typography variant={'h5'}>{t('labelBlindBoxNoRewards') + ' '}</Typography>\n                <img src={emptyImg} alt={''} />\n              </>\n            )}\n            <Link\n              marginBottom={3}\n              onClick={onClickClaimPopViewDetail}\n              variant={'body1'}\n              color={theme.colorBase.textSecondary}\n              marginTop={5}\n            >\n              <u>{t('labelLuckyRedPacketDetail')}</u>\n            </Link>\n            {/* <Button variant={\"contained\"} fullWidth onClick={onClickClaim}>\n          {t(\"labelClaimBtn\")}\n        </Button> */}\n            {wonPrizeInfo && wonPrizeInfo.isNFT && (\n              <Button variant={'contained'} fullWidth onClick={onClickClaim}>\n                {t('labelClaimBtn')}\n              </Button>\n            )}\n          </Box>\n        </Box>\n      </>\n    </Modal>\n  )\n\n  if (\n    type === 'Lottery Started and Not Win Lottery' ||\n    type === 'Lottery Started and Win Lottery'\n  ) {\n    return LooteryModal\n  }\n\n  return (\n    <BlindBoxDetailBoxStyle\n      flex={1}\n      width={RedPacketSize.large.width}\n      height={RedPacketSize.large.height}\n      display={'flex'}\n      paddingBottom={1}\n      flexDirection={'column'}\n      overflow={'scroll'}\n    >\n      {LooteryModal}\n\n      <Box\n        className={'top'}\n        width={'100%'}\n        sx={{\n          background: RedPacketColorConfig.default.startColor,\n          height: '88px',\n        }}\n        display={'flex'}\n        alignItems={'center'}\n        justifyContent={'space-between'}\n      >\n        <Box flex={'1 1 0'}>\n          {type === 'BlindBox Claime Detail' && (\n            <IconButton onClick={onClickClaimDetailBack!} sx={{ marginLeft: 3 }}>\n              <BackIcon htmlColor={RedPacketColorConfig.default.fontColor} />\n            </IconButton>\n          )}\n        </Box>\n        <Typography\n          flex={'3 1 0'}\n          variant={'body1'}\n          color={RedPacketColorConfig.default.fontColor}\n          textAlign={'center'}\n        >\n          {isTokenBlindbox ? t('labelToken') : t('labelRedPacketMarketNFT')}/\n          {t('labelLuckyBlindBox')}\n        </Typography>\n        <Box flex={'1 1 0'} />\n      </Box>\n\n      {type === 'BlindBox Claime Detail' ? (\n        <Box\n          flex={1}\n          display={'flex'}\n          justifyContent={'stretch'}\n          flexDirection={'column'}\n          width={'100%'}\n          paddingX={1}\n          marginTop={3}\n        >\n          <Typography variant={'body1'} color={'var(--color-text-third)'} marginY={1} paddingX={1}>\n            {t('labelLuckyRecievedBlindBox', {\n              opendBlindBoxAmount,\n              totalBlindBoxAmount,\n            })}\n            {/* Received Blind Box {opendBlindBoxAmount}/{totalBlindBoxAmount} */}\n          </Typography>\n\n          <Box flex={1} overflow={'scroll'}>\n            {BlindBoxClaimList &&\n              BlindBoxClaimList.map((info) => {\n                return (\n                  <BoxClaim\n                    className={'claim'}\n                    display={'flex'}\n                    justifyContent={'stretch'}\n                    flexDirection={'column'}\n                    paddingY={1}\n                    paddingX={1}\n                  >\n                    <Typography\n                      component={'span'}\n                      display={'inline-flex'}\n                      flexDirection={'row'}\n                      justifyContent={'space-between'}\n                      alignItems={'center'}\n                    >\n                      <Typography variant={'body1'} component={'span'} color={'textPrimary'}>\n                        {info.who}\n                        {info.isMe ? ` (${t('labelRedPacketMe')})` : ''}\n                      </Typography>\n                      <Typography variant={'body1'} component={'span'} color={'textPrimary'}>\n                        x 1\n                      </Typography>\n                    </Typography>\n                    <Typography\n                      component={'span'}\n                      display={'inline-flex'}\n                      flexDirection={'row'}\n                      justifyContent={'space-between'}\n                      alignItems={'center'}\n                    >\n                      <Typography\n                        variant={'body2'}\n                        component={'span'}\n                        color={'var(--color-text-third)'}\n                      >\n                        {moment(info.when).fromNow()}\n                      </Typography>\n                    </Typography>\n                  </BoxClaim>\n                )\n              })}\n            {pageNationBlindBox}\n          </Box>\n        </Box>\n      ) : (\n        <Box\n          paddingBottom={2}\n          display={'flex'}\n          flexDirection={'column'}\n          paddingX={1}\n          justifyContent={'space-between'}\n          height={'100%'}\n        >\n          <Box display={'flex'} flexDirection={'column'} alignItems={'center'} marginY={2}>\n            <Typography variant={'body1'}>{sender}</Typography>\n            <Typography\n              variant={'body2'}\n              color={'var(--color-text-third)'}\n              whiteSpace={'pre-line'}\n              textAlign={'center'}\n              marginTop={1 / 2}\n              overflow={'hidden'}\n              textOverflow={'ellipsis'}\n              paddingX={4}\n              sx={{\n                wordBreak: 'break-all',\n                display: '-webkit-box',\n                '-webkit-line-clamp': '2',\n                lineClamp: '2',\n                '-webkit-box-orient': 'vertical',\n              }}\n              dangerouslySetInnerHTML={{ __html: sanitize(memo ?? '') }}\n            />\n            {!isTokenBlindbox && (\n              <Box marginY={1} width={'60%'}>\n                {NFTURL ? (\n                  <img style={{ width: '100%' }} alt={''} src={NFTURL} />\n                ) : (\n                  <img\n                    alt={''}\n                    style={{ width: '100%' }}\n                    src={SoursURL + 'images/redpackBlind3.webp'}\n                  />\n                )}\n              </Box>\n            )}\n            {isTokenBlindbox && (type === 'Blind Box Started' || type === 'Not Started') && (\n              <Box marginY={1} width={'60%'}>\n                <img\n                  alt={''}\n                  style={{ width: '100%' }}\n                  src={SoursURL + 'images/redpackBlind3.webp'}\n                />\n              </Box>\n            )}\n            {type === 'Blind Box Started' && didClaimABlindBox && (\n              <Typography>{t('labelBlindBoxCongratulationsBlindBox')}</Typography>\n            )}\n            {type === 'Lottery Started' &&\n              (wonInfo.isNFT ? (\n                wonInfo.participated ? (\n                  wonInfo.won ? (\n                    <Typography>{`${wonInfo.amount} NFTs`}</Typography>\n                  ) : (\n                    <Typography color={'var(--color-error)'}>\n                      {t('labelBlindBoxSorryBlindBox')}\n                    </Typography>\n                  )\n                ) : (\n                  <Typography color={'var(--color-error)'}>{EmptyValueTag}</Typography>\n                )\n              ) : (\n                <>\n                  <Typography\n                    marginTop={3}\n                    variant={'h2'}\n                    color={RedPacketColorConfig.default.colorTop}\n                  >\n                    {wonInfo.participated ? (\n                      wonInfo.won ? (\n                        `${wonInfo.amount} ${wonInfo.symbol}`\n                      ) : (\n                        <Typography color={'var(--color-error)'}>\n                          {t('labelBlindBoxSorryBlindBox')}\n                        </Typography>\n                      )\n                    ) : (\n                      <Typography>{EmptyValueTag}</Typography>\n                    )}\n                  </Typography>\n                  <Typography variant={'h4'} color={RedPacketColorConfig.default.colorTop}>\n                    {t('labelRedpacketTotalReward', {\n                      amount: `${wonInfo.total} ${wonInfo.symbol}`,\n                    })}{' '}\n                  </Typography>\n                </>\n              ))}\n            <Typography\n              variant={'body2'}\n              color={theme.colorBase.textSecondary}\n              marginTop={1}\n              textAlign={'center'}\n            >\n              {description}\n            </Typography>\n            {type !== 'Lottery Started' && (\n              <>\n                <Typography\n                  variant={'body2'}\n                  color={theme.colorBase.textSecondary}\n                  // color={RedPacketColorConfig.default.fontColor}\n                  marginTop={1}\n                  textAlign={'center'}\n                >\n                  {t('labelBlindBoxExplaination2', {\n                    opendBlindBoxAmount,\n                    totalBlindBoxAmount,\n                    // deliverdGiftsAmount,\n                    // totalGiftsAmount,\n                    remainingGiftsAmount: totalGiftsAmount - deliverdGiftsAmount,\n                  })}\n                  {/* {opendBlindBoxAmount} out of {totalBlindBoxAmount} blind boxes have been opened; {deliverdGiftsAmount} out of {totalGiftsAmount} gifts delivered. */}\n                </Typography>\n                <Typography\n                  variant={'body2'}\n                  color={theme.colorBase.textSecondary}\n                  // color={RedPacketColorConfig.default.fontColor}\n                  marginTop={1}\n                  textAlign={'center'}\n                >\n                  {t('labelBlindBoxExplaination3', {\n                    remainingGiftsAmount: remainGiftsAmount,\n                  })}\n                </Typography>\n              </>\n            )}\n\n            <Box>\n              {type === 'Not Started' && (\n                <Typography\n                  variant={'body2'}\n                  color={theme.colorBase.warning}\n                  marginTop={1}\n                  textAlign={'center'}\n                >\n                  {t('labelBlindBoxNotStarted', {\n                    time: moment(blindBoxStartTime).format(YEAR_DAY_MINUTE_FORMAT),\n                    interpolation: {\n                      escapeValue: false,\n                    },\n                  })}\n                </Typography>\n              )}\n              {(type === 'Not Started' || type === 'Blind Box Started') && (\n                <Typography\n                  variant={'body2'}\n                  color={\n                    type === 'Blind Box Started'\n                      ? theme.colorBase.warning\n                      : theme.colorBase.textSecondary\n                  }\n                  marginTop={1}\n                  textAlign={'center'}\n                >\n                  {t('labelBlindBoxStarted', {\n                    time: moment(lotteryStartTime).format(YEAR_DAY_MINUTE_FORMAT),\n                    interpolation: {\n                      escapeValue: false,\n                    },\n                  })}\n                </Typography>\n              )}\n              {(type === 'Not Started' || type === 'Blind Box Started') && isTokenBlindbox && (\n                <Typography\n                  variant={'body2'}\n                  color={theme.colorBase.textSecondary}\n                  marginTop={1}\n                  textAlign={'center'}\n                >\n                  {t('labelBlindBoxTokenHint', {\n                    time: moment(lotteryEndTime).format(YEAR_DAY_MINUTE_FORMAT),\n                    interpolation: {\n                      escapeValue: false,\n                    },\n                  })}\n                </Typography>\n              )}\n              {!isTokenBlindbox && (\n                <Typography\n                  variant={'body2'}\n                  color={\n                    type !== 'Blind Box Started' && type !== 'Not Started'\n                      ? expired\n                        ? theme.colorBase.textDisable\n                        : theme.colorBase.warning\n                      : theme.colorBase.textSecondary\n                  }\n                  marginTop={1}\n                  textAlign={'center'}\n                >\n                  {t('labelBlindBoxClaimStarted', {\n                    time: moment(lotteryEndTime).format(YEAR_DAY_MINUTE_FORMAT),\n                    interpolation: {\n                      escapeValue: false,\n                    },\n                  })}\n                </Typography>\n              )}\n            </Box>\n            {/* <Typography\n              variant={\"body2\"}\n              color={theme.colorBase.warning}\n              marginTop={1}\n              textAlign={\"center\"}\n            >\n              {type === \"Not Started\"\n                ? t(\"labelBlindBoxNotStarted\", {\n                    time: moment(blindBoxStartTime).format(\n                      YEAR_DAY_MINUTE_FORMAT\n                    ),\n                    interpolation: {\n                      escapeValue: false,\n                    }\n                  })\n                : type === \"Blind Box Started\"\n                ? t(\"labelBlindBoxStarted\", {\n                    time: moment(lotteryStartTime).format(\n                      YEAR_DAY_MINUTE_FORMAT\n                    ),\n                    interpolation: {\n                      escapeValue: false,\n                    }\n                  })\n                : t(\"labelBlindBoxClaimStarted\", {\n                    time: moment(lotteryEndTime).format(YEAR_DAY_MINUTE_FORMAT),\n                    interpolation: {\n                      escapeValue: false,\n                    }\n                  })}\n            </Typography> */}\n            {(type === 'Blind Box Started' || type === 'Lottery Started') && (\n              <Link\n                className={'viewDetail'}\n                whiteSpace={'pre-line'}\n                color={'inherit'}\n                variant={'body1'}\n                onClick={(e) => {\n                  e.stopPropagation()\n                  onClickViewDetail!()\n                }}\n              >\n                {t('labelLuckyRedPacketDetail')}\n              </Link>\n            )}\n            {type === 'Lottery Started' && (\n              <>\n                <Divider\n                  orientation={'horizontal'}\n                  sx={{\n                    borderWidth: 3,\n                    width: '120%',\n                    marginY: 1,\n                    marginX: -2,\n                  }}\n                />\n                <Box\n                  flex={1}\n                  display={'flex'}\n                  justifyContent={'stretch'}\n                  flexDirection={'column'}\n                  width={'100%'}\n                >\n                  <Typography\n                    variant={'body1'}\n                    color={'var(--color-text-third)'}\n                    marginY={1}\n                    paddingX={1}\n                  >\n                    {isTokenBlindbox\n                      ? t('labelBlindBoxRecieved', {\n                          deliverdGiftsAmount,\n                          totalGiftsAmount,\n                        })\n                      : t('labelBlindBoxRecievedNFT', {\n                          deliverdGiftsAmount,\n                          totalGiftsAmount,\n                        })}\n                  </Typography>\n\n                  <Box flex={1} overflow={'scroll'}>\n                    {NFTClaimList &&\n                      NFTClaimList.map((info) => {\n                        return (\n                          <BoxClaim\n                            className={'claim'}\n                            display={'flex'}\n                            justifyContent={'stretch'}\n                            flexDirection={'column'}\n                            paddingY={1}\n                            paddingX={1}\n                          >\n                            <Typography\n                              component={'span'}\n                              display={'inline-flex'}\n                              flexDirection={'row'}\n                              justifyContent={'space-between'}\n                              alignItems={'center'}\n                            >\n                              <Typography\n                                component={'span'}\n                                display={'inline-flex'}\n                                flexDirection={'row'}\n                                justifyContent={'space-between'}\n                                alignItems={'center'}\n                              >\n                                <Typography\n                                  variant={'body1'}\n                                  component={'span'}\n                                  color={'textPrimary'}\n                                >\n                                  {info.who}\n                                  {info.isMe ? ` (${t('labelRedPacketMe')})` : ''}\n                                </Typography>\n                              </Typography>\n                              <Typography\n                                component={'span'}\n                                display={'inline-flex'}\n                                flexDirection={'row'}\n                                justifyContent={'space-between'}\n                                alignItems={'center'}\n                              >\n                                <Typography\n                                  variant={'body2'}\n                                  component={'span'}\n                                  color={'textPrimary'}\n                                >\n                                  {info.showMultiplier && 'x'} {info.amount}\n                                </Typography>\n                              </Typography>\n                            </Typography>\n                            <Typography\n                              component={'span'}\n                              display={'inline-flex'}\n                              flexDirection={'row'}\n                              justifyContent={'space-between'}\n                              alignItems={'center'}\n                            >\n                              <Typography\n                                variant={'body2'}\n                                component={'span'}\n                                color={'var(--color-text-third)'}\n                              >\n                                {moment(info.when).fromNow()}\n                              </Typography>\n                              <Typography display={'inline'}>\n                                {info.showLuckiest && (\n                                  <Typography\n                                    component={'span'}\n                                    color={'var(--color-warning)'}\n                                    display={'inline-flex'}\n                                    alignItems={'center'}\n                                    variant={'body2'}\n                                    marginLeft={1}\n                                  >\n                                    <FirstPlaceIcon\n                                      fontSize={'medium'}\n                                      sx={{ paddingRight: 1 / 2 }}\n                                    />\n                                    {t('labelLuckDraw')}\n                                  </Typography>\n                                )}\n                              </Typography>\n                            </Typography>\n                          </BoxClaim>\n                        )\n                      })}\n                  </Box>\n                  {pageNation}\n                </Box>\n              </>\n            )}\n          </Box>\n          <ReceiptListModal\n            open={showExclusiveReceipt}\n            t={t}\n            onClose={() => setShowExclusiveReceipt(false)}\n            targets={targets ?? []}\n          />\n\n          {/* {(type === \"Not Started\" || type === \"Blind Box Started\") && ( */}\n          <Box>\n            <Box display={'flex'} justifyContent={'center'}>\n              {showReceiptListBtn && (\n                <Button\n                  variant={'text'}\n                  sx={{ fontSize: '13px' }}\n                  onClick={() => {\n                    setShowExclusiveReceipt(true)\n                  }}\n                >\n                  {t('labelRedPacketReceiptsList')}\n                </Button>\n              )}\n            </Box>\n\n            {shareButton === 'share' && (\n              <Button\n                variant={'contained'}\n                color={'error'}\n                sx={{\n                  backgroundColor: RedPacketColorConfig.default.colorTop as any,\n                  '&:hover': {\n                    backgroundColor: RedPacketColorConfig.default.colorTop as any,\n                  },\n                }}\n                fullWidth={true}\n                onClick={onShared}\n              >\n                {t('labelRedPacketGrab')}\n              </Button>\n            )}\n            {claimButton === 'claim' ? (\n              <Button variant={'contained'} fullWidth onClick={onClickClaim}>\n                {t('labelClaimBtn')}\n              </Button>\n            ) : claimButton === 'claimed' ? (\n              <Button disabled variant={'contained'} fullWidth>\n                {t('labelClaimBtnClaimed')}\n              </Button>\n            ) : claimButton === 'expired' ? (\n              <Button disabled variant={'contained'} fullWidth>\n                {t('Expired')}\n              </Button>\n            ) : claimButton === 'ended' ? (\n              <Button disabled variant={'contained'} fullWidth>\n                {t('labelRedPacketStatusEnded')}\n              </Button>\n            ) : undefined}\n          </Box>\n          {/* )} */}\n        </Box>\n      )}\n    </BlindBoxDetailBoxStyle>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/block/Referral.tsx",
    "content": "import React from 'react'\nimport { ShareReferralSvg, ShareReferralSvgProps } from '@loopring-web/common-resources'\n\nexport const ReferralImage = React.forwardRef(\n  (\n    { src, width, height, ...props }: ShareReferralSvgProps,\n    ref: React.ForwardedRef<SVGSVGElement>,\n  ) => {\n    // let name: any = ;\n    // name = name[name.length - 1];\n    const [base64, setBase64] = React.useState('')\n    const convertImageToBase64 = (imgUrl: string, callback: (dataUrl: string) => void) => {\n      const image = new Image()\n      image.crossOrigin = 'anonymous'\n      image.onload = () => {\n        const canvas = document.createElement('canvas')\n        const ctx = canvas.getContext('2d')\n        canvas.height = image.naturalHeight\n        canvas.width = image.naturalWidth\n        // @ts-ignore\n        ctx.drawImage(image, 0, 0)\n        const dataUrl = canvas.toDataURL()\n        callback && callback(dataUrl)\n      }\n      image.src = imgUrl\n    }\n    convertImageToBase64(src, (dataUrl) => {\n      setBase64(dataUrl)\n    })\n\n    return (\n      <>\n        {base64 && (\n          <ShareReferralSvg\n            ref={ref}\n            src={base64}\n            name={(src ?? '/').split('/')?.pop()}\n            width={width}\n            height={height}\n            {...{ ...props }}\n          />\n        )}\n      </>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/block/SettingPanel.tsx",
    "content": "import styled from '@emotion/styled'\nimport {\n  Box,\n  Divider,\n  FormControlLabel,\n  Grid,\n  Radio,\n  SelectChangeEvent,\n  Switch,\n  Typography,\n} from '@mui/material'\nimport React from 'react'\nimport {\n  CurrencyToTag,\n  DropDownIcon,\n  GrowIcon,\n  i18n,\n  LanguageType,\n  PriceTag,\n  ThemeType,\n  UpColor,\n} from '@loopring-web/common-resources'\nimport { OutlineSelect, OutlineSelectItem, RadioGroupStyle } from '../basic-lib'\nimport { Trans, WithTranslation, withTranslation } from 'react-i18next'\nimport { useSettings } from '../../stores'\n\nconst StyledSwitch = styled(Switch)`\n  margin: 0;\n`\n\nconst BoxStyle = styled(Box)`\n  .MuiInputBase-root {\n    background: var(--opacity);\n    text-align: right;\n  }\n` as typeof Box\n\nexport const BtnCurrency = ({ t, currency, label, handleChange }: any) => {\n  const _handleChange = React.useCallback(\n    (event: SelectChangeEvent<any>) => {\n      // setState(event.target.value)\n      if (handleChange) {\n        handleChange(event.target.value)\n      }\n    },\n    [handleChange],\n  )\n  return (\n    <OutlineSelect\n      aria-label={t(label)}\n      IconComponent={DropDownIcon}\n      labelId='language-selected'\n      id='language-selected'\n      value={currency?.toUpperCase()}\n      autoWidth\n      onChange={_handleChange}\n    >\n      {Object.keys(CurrencyToTag).map((item) => {\n        return (\n          <OutlineSelectItem value={CurrencyToTag[item]} key={item}>\n            {item} - {PriceTag[CurrencyToTag[item]]}\n          </OutlineSelectItem>\n        )\n      })}\n      {/*<OutlineSelectItem value={Currency.cny}>¥ {t('labelCNYYuan')}</OutlineSelectItem>*/}\n    </OutlineSelect>\n  )\n}\n\nconst StyledDivider = styled(Divider)`\n  margin: 0;\n`\n\nexport const BtnLanguage = ({ t, label, handleChange }: any) => {\n  const _handleChange = React.useCallback(\n    (event: SelectChangeEvent<any>) => {\n      if (handleChange) {\n        handleChange(event.target.value)\n      }\n    },\n    [handleChange],\n  )\n  return (\n    <OutlineSelect\n      aria-label={t(label)}\n      IconComponent={DropDownIcon}\n      labelId='language-selected'\n      id='language-selected'\n      value={i18n.language}\n      onChange={_handleChange}\n    >\n      <OutlineSelectItem value={LanguageType.en_US}>English</OutlineSelectItem>\n      {/*<OutlineSelectItem value={LanguageType.zh_CN}>简体中文</OutlineSelectItem>*/}\n    </OutlineSelect>\n  )\n}\n\nexport const SettingPanel = withTranslation(['common', 'layout'], {\n  withRef: true,\n})(({ t, ...rest }: WithTranslation) => {\n  // const theme = useTheme();\n  const { setUpColor, setCurrency, setLanguage, currency, upColor, setTheme, themeMode, isMobile } =\n    useSettings()\n\n  const handleOnLanguageChange = React.useCallback(\n    (value: any) => {\n      setLanguage(value)\n    },\n    [setLanguage],\n  )\n  const handleOnCurrencyChange = React.useCallback(\n    (value: any) => {\n      setCurrency(value)\n    },\n    [setCurrency],\n  )\n  const handleColorChange = React.useCallback(\n    (_e: any, value: any) => {\n      setUpColor(value)\n    },\n    [setUpColor],\n  )\n  //const [mode, setMode] = React.useState(themeMode)\n  const handleThemeClick = React.useCallback(\n    (e: any) => {\n      if (e.target.checked) {\n        setTheme(ThemeType.dark)\n      } else {\n        setTheme(ThemeType.light)\n      }\n    },\n    [themeMode],\n  )\n  const updown = React.useCallback(\n    ({ key }: any) => {\n      return (\n        <>\n          <Typography component={'span'} variant={'body2'} color={'textPrimary'}>\n            <Trans\n              i18nKey='whichColorIsUp'\n              tOptions={{\n                up: key === UpColor.green ? t('labelgreen') : t('labelred'),\n                down: key === UpColor.green ? t('labelred') : t('labelgreen'),\n              }}\n            >\n              <Typography\n                component={'span'}\n                variant={'body2'}\n                color={'textPrimary'}\n                style={{\n                  textTransform: 'capitalize',\n                  // color: key === UpColor.green ? theme.colorBase.success : theme.colorBase.error\n                }}\n              >\n                color up\n              </Typography>\n              and\n              <Typography\n                component={'span'}\n                variant={'body2'}\n                color={'textPrimary'}\n                style={{\n                  textTransform: 'capitalize',\n                  // color: key === UpColor.green ? theme.colorBase.error : theme.colorBase.success\n                }}\n              >\n                color down\n              </Typography>\n            </Trans>\n          </Typography>\n          <Typography\n            component={'span'}\n            style={{ verticalAlign: '-webkit-baseline-middle' }}\n            color={key === UpColor.green ? 'var(--color-success)' : 'var(--color-error)'}\n          >\n            <GrowIcon fontSize={'medium'} color={'inherit'} />\n          </Typography>\n        </>\n      )\n    },\n    [UpColor],\n  )\n  const styles = isMobile ? { flex: 1 } : { width: 'var(--swap-box-width)' }\n  return (\n    <BoxStyle component={'section'} display={'flex'} flexDirection={'column'} style={styles}>\n      {/*<Typography variant={'h6'} component={'h4'} paddingX={2}>{t('labelTitleLayout')}</Typography>*/}\n      <Grid\n        container\n        display={'flex'}\n        flexDirection={'row'}\n        justifyContent={'stretch'}\n        alignItems={'center'}\n        paddingX={2}\n        marginY={2}\n      >\n        <Grid item xs={4} display={'flex'} flexDirection={'column'}>\n          <Typography variant={'body1'} component={'p'} color={'textSecondary'}>\n            {t('labelLanguage')}\n          </Typography>\n        </Grid>\n        <Grid\n          item\n          xs={8}\n          display={'flex'}\n          flexDirection={'column'}\n          justifyContent={'space-evenly'}\n          alignItems={'flex-end'}\n          alignSelf={'stretch'}\n        >\n          <Grid item>\n            <BtnLanguage\n              {...{\n                t,\n                ...rest,\n                handleChange: handleOnLanguageChange,\n              }}\n            />\n          </Grid>\n        </Grid>\n      </Grid>\n      <StyledDivider />\n\n      <Grid\n        container\n        display={'flex'}\n        flexDirection={'row'}\n        justifyContent={'stretch'}\n        alignItems={'center'}\n        paddingX={2}\n        marginY={2}\n      >\n        <Grid item xs={4} display={'flex'} flexDirection={'column'}>\n          <Typography variant={'body1'} component={'p'} color={'textSecondary'}>\n            {t('labelCurrency')}\n          </Typography>\n        </Grid>\n        <Grid\n          item\n          xs={8}\n          display={'flex'}\n          flexDirection={'column'}\n          justifyContent={'space-evenly'}\n          alignItems={'flex-end'}\n          alignSelf={'stretch'}\n        >\n          <Grid item>\n            <BtnCurrency\n              {...{\n                t,\n                ...rest,\n                currency,\n                label: 'currencySetting',\n                handleChange: handleOnCurrencyChange,\n              }}\n            />\n          </Grid>\n        </Grid>\n      </Grid>\n      <StyledDivider />\n      <Grid\n        container\n        display={'flex'}\n        flexDirection={'row'}\n        justifyContent={'stretch'}\n        alignItems={'center'}\n        paddingX={2}\n        marginY={1}\n      >\n        <Grid item xs={4} display={'flex'} flexDirection={'column'}>\n          <Typography variant={'body1'} component={'p'} color={'textSecondary'}>\n            {t('labelColors')}\n          </Typography>\n        </Grid>\n        <Grid\n          item\n          xs={8}\n          display={'flex'}\n          flexDirection={'column'}\n          justifyContent={'center'}\n          alignItems={'flex-end'}\n          alignSelf={'stretch'}\n        >\n          <RadioGroupStyle\n            row={false}\n            aria-label='withdraw'\n            name='withdraw'\n            value={upColor}\n            onChange={handleColorChange}\n          >\n            {Object.keys(UpColor).map((key) => {\n              return (\n                <React.Fragment key={key}>\n                  <FormControlLabel value={key} control={<Radio />} label={updown({ key })} />\n                </React.Fragment>\n              )\n            })}\n          </RadioGroupStyle>\n        </Grid>\n      </Grid>\n      <StyledDivider />\n      <Grid\n        container\n        display={'flex'}\n        flexDirection={'row'}\n        justifyContent={'stretch'}\n        alignItems={'center'}\n        paddingX={2}\n        marginY={2}\n      >\n        <Grid item xs={4} display={'flex'} flexDirection={'column'}>\n          <Typography variant={'body1'} component={'p'} color={'textSecondary'}>\n            {t('labelTheme')}\n          </Typography>\n        </Grid>\n        <Grid\n          item\n          xs={8}\n          display={'flex'}\n          flexDirection={'column'}\n          justifyContent={'center'}\n          alignItems={'flex-end'}\n          alignSelf={'stretch'}\n        >\n          <StyledSwitch\n            checked={themeMode === ThemeType.dark}\n            aria-label={t('change theme')}\n            onClick={handleThemeClick}\n          />\n        </Grid>\n      </Grid>\n    </BoxStyle>\n  )\n})\n"
  },
  {
    "path": "packages/component-lib/src/components/block/ShareSocialPanel.tsx",
    "content": "export const ShareSocialPanel = () => {\n  return <></>\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/block/TagIconList.tsx",
    "content": "import { Avatar, Tooltip, Typography } from '@mui/material'\nimport React from 'react'\nimport { CAMPAIGNTAGCONFIG, SCENARIO } from '@loopring-web/common-resources'\nimport { useTheme } from '@emotion/react'\n\nexport const TagIconList = React.memo(\n  ({\n    campaignTagConfig,\n    symbol,\n    scenario,\n    size,\n  }: {\n    campaignTagConfig: CAMPAIGNTAGCONFIG\n    symbol: string\n    size?: string\n    scenario: SCENARIO\n  }) => {\n    const theme = useTheme()\n    return (\n      <Typography component={'span'} display={'inline-flex'} className={'tagIconList'}>\n        {campaignTagConfig[scenario]?.map((item, index) => {\n          return (\n            <React.Fragment key={item?.name + index}>\n              {item.symbols?.includes(symbol) &&\n              item.webFlag &&\n              item.endShow >= Date.now() &&\n              item.startShow <= Date.now() ? (\n                item?.behavior === 'tooltips' ? (\n                  <Tooltip title={item.content ?? scenario}>\n                    <Avatar\n                      alt={item.name}\n                      style={{\n                        width: 'auto',\n                        // width: size ? size : \"var(--svg-size-medium)\",\n                        height: size ? size : 'var(--svg-size-medium)',\n                        marginRight: theme.unit / 2,\n                      }}\n                      variant={'square'}\n                      src={item.iconSource}\n                    />\n                  </Tooltip>\n                ) : (\n                  <Avatar\n                    onClick={() => {\n                      if (item?.behavior === 'link') {\n                        window.open(item.content, '_blank')\n                        window.opener = null\n                      }\n                    }}\n                    alt={item.name}\n                    variant={'square'}\n                    style={{\n                      width: 'auto',\n                      // width: size ? size : \"var(--svg-size-medium)\",\n                      height: size ? size : 'var(--svg-size-medium)',\n                      marginRight: theme.unit / 2,\n                    }}\n                    src={item.iconSource}\n                  />\n                )\n              ) : (\n                <></>\n              )}\n            </React.Fragment>\n          )\n        })}\n      </Typography>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/block/TradeRace.tsx",
    "content": "import React from 'react'\nimport { Column, Table } from '../basic-lib'\nimport { useTranslation } from 'react-i18next'\nimport styled from '@emotion/styled'\nimport { Box, Typography } from '@mui/material'\nimport { EmptyValueTag, getValuePrecisionThousand, RowConfig } from '@loopring-web/common-resources'\n\nexport interface TradeRaceRow {\n  project: string\n  pair: string\n  reward: {\n    count: number\n    token: string\n  }\n}\n\nconst rowHeight = RowConfig.rowHeight\nconst TableStyle = styled(Table)`\n  &.rdg {\n    box-sizing: border-box;\n    border-top: 1px solid var(--color-divide);\n    text-align: center;\n    min-height: initial;\n    height: ${(props: any) => {\n      if (props.currentheight) {\n        return props.currentheight + 2 + 'px'\n      } else {\n        return '100%'\n      }\n    }};\n    .rdg-header-row {\n      // background:var(--color-table-header-bg);\n    }\n\n    .rdg-row,\n    .rdg-header-row {\n      border-right: 1px solid var(--color-divide);\n    }\n\n    .rdg-cell {\n      box-sizing: border-box;\n      border-left-width: 1px;\n      border-bottom-width: 1px;\n      border-left-color: var(--color-divide);\n      border-bottom-color: var(--color-divide);\n    }\n\n    .rdg-align-left {\n      text-align: left;\n    }\n\n    .rdg-align-right {\n      text-align: right;\n    }\n  }\n`\n\nexport const TradeRacePanel = ({ rawData, ...rest }: { rawData: TradeRaceRow[] }) => {\n  const { t } = useTranslation(['tables'])\n\n  const getColumnMode = React.useCallback(\n    (): Column<any, unknown>[] => [\n      {\n        key: 'project',\n        name: t('labelTradeRaceProject'),\n        formatter: ({ row }) => {\n          const value = row['project']\n\n          return <Box className='rdg-cell-value'>{value}</Box>\n        },\n      },\n      {\n        key: 'pair',\n        name: /\\-/gi.test(rawData[0].pair) ? t('labelTradeRacePair') : t('labelTradeRaceToken'),\n      },\n      {\n        key: 'reward',\n        // cellClass: \"\",\n        // headerCellClass: \"\",\n        name: t('labelTradeRaceReward'),\n        formatter: ({ row }) => {\n          return (\n            <>\n              {row.reward.token ? (\n                <>\n                  <Typography variant={'body1'} component={'span'}>\n                    {row.reward.count !== '' && getValuePrecisionThousand(row.reward.count)}\n                  </Typography>\n                  <Typography variant={'body1'} component={'span'} marginLeft={1}>\n                    {row.reward.token}\n                  </Typography>\n                </>\n              ) : (\n                <Typography variant={'body1'} component={'span'} marginLeft={1}>\n                  {EmptyValueTag}\n                </Typography>\n              )}\n            </>\n          )\n        },\n      },\n    ],\n    [],\n  )\n\n  const defaultArgs = {\n    columnMode: getColumnMode(),\n    currentheight: (rawData.length + 1) * rowHeight,\n    generateRows: (rawData: any) => rawData,\n    generateColumns: ({ columnsRaw }: any) => columnsRaw as Column<any, unknown>[],\n  }\n\n  return <TableStyle {...{ ...defaultArgs, t, ...rest, rawData }} />\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/block/TradeTitle.tsx",
    "content": "import { WithTranslation } from 'react-i18next'\nimport {\n  Account,\n  CAMPAIGNTAGCONFIG,\n  CoinInfo,\n  CurrencyToTag,\n  EmptyValueTag,\n  FloatTag,\n  ForexMap,\n  getValuePrecisionThousand,\n  PriceTag,\n  SCENARIO,\n  SoursURL,\n  Ticker,\n  UpColor,\n} from '@loopring-web/common-resources'\nimport { Avatar, Box, Grid, Typography } from '@mui/material'\nimport styled from '@emotion/styled'\nimport { AvatarCoin, baseTitleCss, TagIconList, useSettings } from '../../index'\nimport { NewTagIcon } from '../basic-lib'\nimport { Currency } from '@loopring-web/loopring-sdk'\n\nexport type StyledProps = {\n  custom: { chg: UpColor }\n}\nconst TradeTitleStyled = styled(Box)<StyledProps>`\n  ${({ theme, custom }) => baseTitleCss({ theme, custom })}\n` as (props: StyledProps) => JSX.Element\n\nexport const TradeTitle = <I extends object>({\n  baseShow,\n  quoteShow,\n  coinAInfo,\n  coinBInfo,\n  // t,\n  ticker,\n  isNew,\n  forexMap,\n  campaignTagConfig,\n}: WithTranslation & {\n  account: Account\n  baseShow: string\n  quoteShow: string\n  coinAInfo: CoinInfo<I>\n  coinBInfo: CoinInfo<I>\n  ticker: Ticker\n  isNew: boolean\n  forexMap: ForexMap<Currency>\n  campaignTagConfig: CAMPAIGNTAGCONFIG\n}) => {\n  const { coinJson } = useSettings()\n  const sellCoinIcon: any = coinJson[coinAInfo?.simpleName]\n  const buyCoinIcon: any = coinJson[coinBInfo?.simpleName]\n\n  const tradeFloatType =\n    ticker?.changeU === 0 || !ticker?.changeU\n      ? FloatTag.none\n      : ticker.changeU < 0\n      ? FloatTag.decrease\n      : FloatTag.increase\n  const { currency, upColor } = useSettings()\n  const close: any = ticker.close\n\n  const value =\n    '\\u2248 ' +\n    PriceTag[CurrencyToTag[currency]] +\n    getValuePrecisionThousand(\n      ticker?.closeU ? ticker?.closeU * (forexMap[currency] ?? 0) : 0,\n      undefined,\n      undefined,\n      undefined,\n      true,\n      { isFait: true },\n    )\n\n  const pair = `${coinAInfo?.simpleName}-${coinBInfo?.simpleName}`\n  const change = ticker?.change ? ticker?.change.toFixed(2) + '%' : '0.00%'\n  return (\n    // @ts-ignore\n    <TradeTitleStyled custom={{ chg: upColor }}>\n      {coinBInfo && coinAInfo ? (\n        <Grid container height={72}>\n          <Grid item xs={12} height={28}>\n            <Box\n              display={'flex'}\n              flexDirection={'row'}\n              justifyContent={'flex-start'}\n              alignItems={'center'}\n            >\n              <Box\n                className={'logo-icon'}\n                display={'flex'}\n                height={'var(--chart-title-coin-size)'}\n                position={'relative'}\n                zIndex={20}\n                width={'var(--chart-title-coin-size)'}\n                alignItems={'center'}\n                justifyContent={'center'}\n              >\n                {sellCoinIcon ? (\n                  <AvatarCoin\n                    imgx={sellCoinIcon.x}\n                    imgy={sellCoinIcon.y}\n                    imgheight={sellCoinIcon.h}\n                    imgwidth={sellCoinIcon.w}\n                    size={28}\n                    variant='circular'\n                    alt={coinAInfo?.simpleName as string}\n                    // src={sellData?.icon}\n                    src={\n                      'data:image/svg+xml;utf8,' +\n                      '<svg width=\"36\" height=\"36\" viewBox=\"0 0 36 36\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M0 0H36V36H0V0Z\"/></svg>'\n                    }\n                  />\n                ) : (\n                  <Avatar\n                    variant='circular'\n                    alt={coinAInfo?.simpleName as string}\n                    style={{\n                      height: 'var(--chart-title-coin-size)',\n                      width: 'var(--chart-title-coin-size)',\n                    }}\n                    // src={sellData?.icon}\n                    src={SoursURL + 'images/icon-default.png'}\n                  />\n                )}\n              </Box>\n\n              <Box\n                className={'logo-icon'}\n                display={'flex'}\n                height={'var(--chart-title-coin-size)'}\n                position={'relative'}\n                zIndex={18}\n                left={-8}\n                width={'var(--chart-title-coin-size)'}\n                alignItems={'center'}\n                justifyContent={'center'}\n              >\n                {buyCoinIcon ? (\n                  <AvatarCoin\n                    imgx={buyCoinIcon.x}\n                    imgy={buyCoinIcon.y}\n                    imgheight={buyCoinIcon.h}\n                    imgwidth={buyCoinIcon.w}\n                    size={28}\n                    variant='circular'\n                    alt={coinBInfo?.simpleName as string}\n                    // src={sellData?.icon}\n                    src={\n                      'data:image/svg+xml;utf8,' +\n                      '<svg width=\"36\" height=\"36\" viewBox=\"0 0 36 36\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M0 0H36V36H0V0Z\"/></svg>'\n                    }\n                  />\n                ) : (\n                  <Avatar\n                    variant='circular'\n                    alt={coinBInfo?.simpleName as string}\n                    style={{\n                      height: 'var(--chart-title-coin-size)',\n                      width: 'var(--chart-title-coin-size)',\n                    }}\n                    // src={sellData?.icon}\n                    src={SoursURL + 'images/icon-default.png'}\n                  />\n                )}\n              </Box>\n              <Typography variant={'h4'} component={'h3'} paddingRight={1}>\n                <Typography component={'span'} title={'sell'} className={'next-coin'}>\n                  {baseShow}\n                </Typography>\n                <Typography component={'i'}>/</Typography>\n                <Typography component={'span'} title={'buy'}>\n                  {quoteShow}\n                </Typography>\n              </Typography>\n              {campaignTagConfig && (\n                <TagIconList\n                  scenario={SCENARIO.MARKET}\n                  campaignTagConfig={campaignTagConfig}\n                  symbol={pair}\n                />\n              )}\n              {isNew ? <NewTagIcon /> : undefined}\n            </Box>\n          </Grid>\n          <Grid\n            item\n            xs={12}\n            height={36}\n            display={'flex'}\n            flexDirection={'row'}\n            justifyContent={'flex-start'}\n            alignItems={'center'}\n            className={'float-group'}\n            marginTop={1}\n          >\n            <Typography variant={'h1'}>\n              {close === 'NaN' ? EmptyValueTag : close} {quoteShow}\n            </Typography>\n            <Box\n              display={'flex'}\n              flexDirection={'column'}\n              alignItems={'flex-start'}\n              justifyContent={'center'}\n              className={'float-chart'}\n            >\n              <Typography\n                variant={'h5'}\n                component={'span'}\n                display={'flex'}\n                alignItems={'flex-end'}\n              >\n                <Typography variant={'h5'} component={'span'}>\n                  {value}\n                </Typography>\n                <Typography\n                  variant={'h5'}\n                  component={'span'}\n                  className={`float-tag float-${tradeFloatType}`}\n                >\n                  （{tradeFloatType === FloatTag.increase ? '+' : ''}\n                  {change}）\n                </Typography>\n              </Typography>\n            </Box>\n          </Grid>\n        </Grid>\n      ) : (\n        <></>\n      )}\n    </TradeTitleStyled>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/block/Vip.tsx",
    "content": "import React from 'react'\nimport { Column, Table } from '../basic-lib'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport { Box, Typography } from '@mui/material'\nimport { CheckIcon } from '@loopring-web/common-resources'\nimport styled from '@emotion/styled'\n\ninterface Row {\n  level: string\n  tradeVolume: string\n  rule: string\n  balance: string\n  maker: string\n  taker: string\n}\n\nconst TableStyle = styled(Table)`\n  &.rdg {\n    border-top: 1px solid var(--color-divide);\n    text-align: center;\n    min-height: 300px;\n    overflow: auto;\n    --template-columns: auto !important;\n    .rdg-header-row {\n      // background:var(--color-table-header-bg);\n    }\n    .rdg-row,\n    .rdg-header-row {\n      border-right: 1px solid var(--color-divide);\n    }\n    .rdg-cell {\n      border-left-width: 1px;\n      border-bottom-width: 1px;\n      border-left-color: var(--color-divide);\n      border-bottom-color: var(--color-divide);\n    }\n  }\n` as typeof Table\n\nexport const VipPanel = withTranslation(['tables'])(\n  ({\n    t,\n    rawData,\n    currentLevel,\n    ...rest\n  }: WithTranslation & { rawData: Row[]; currentLevel: number }) => {\n    const getColumnModeTransaction = React.useCallback(\n      ({ t }: WithTranslation): Column<any, unknown>[] => [\n        {\n          key: 'level',\n          name: t('labelVipTableLevel'),\n          frozen: true,\n          formatter: ({ row }) => {\n            const [_, level] = row.level.split(' ')\n            return (\n              <Box display={'flex'} justifyContent={'center'} alignItems={'center'}>\n                {String(currentLevel) === String(level) && (\n                  <Box>\n                    <CheckIcon style={{ marginBottom: -3 }} htmlColor={'var(--color-logo)'} />\n                  </Box>\n                )}\n                <Box>\n                  <Typography marginLeft={1} variant={'body1'} component={'span'}>\n                    {row.level}\n                  </Typography>\n                </Box>\n              </Box>\n            )\n          },\n\n          // headerRenderer: (props: SortableHeaderCellProps<Row>) => <SortableHeaderCell {...props}\n          //                                                                              children={<Typography\n          //                                                                                  variant={'body1'}\n          //                                                                                  paddingLeft={2}\n          //                                                                                  component={'span'}>{t('labelLevel')}</Typography>}/>,\n          // formatter: ({row}) => <Typography variant={'body1'}\n          //                                   component={'span'}>{row.level}</Typography>\n        },\n        { key: 'tradeVolume', name: t('labelVipTable30dTradeVolume') },\n        { key: 'rule', name: t('labelVipTableRule') },\n        { key: 'balance', name: t('labelVipTableBalance') },\n        { key: 'maker', name: t('labelVipTableMaker') },\n        { key: 'taker', name: t('labelVipTableTaker') },\n      ],\n      [currentLevel],\n    )\n\n    const defaultArgs: any = {\n      columnMode: getColumnModeTransaction({ t, ...rest }),\n      generateRows: (rawData: any) => rawData,\n      generateColumns: ({ columnsRaw }: any) => columnsRaw as Column<any, unknown>[],\n    }\n\n    return <TableStyle<Row, unknown> {...{ ...defaultArgs, t, ...rest, rawData }} />\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/block/index.ts",
    "content": "export * from './TradeTitle'\nexport * from './Interface'\n// export * from '../modal/AccountInfo/AccountInfo'\nexport * from './AssetTitle'\nexport * from './MarketBlock'\nexport * from './AmmCard'\nexport * from './Vip'\n// export * from './styled'\n// export * as  from './Styled'\nexport * from './Interface'\nexport * from './DepthRaw'\nexport * from './TradeRace'\nexport * from './nftMedia'\nexport * from './AmmPairDetail'\nexport * from './CollectionMedia'\nexport * from './LoadingBlock'\nexport * from './TagIconList'\nexport * from './RedPacket'\nexport * from './CollectionDetailView'\nexport * from './Referral'\nexport * from './ErrorBlock'\nexport * from './ShareSocialPanel'\nexport * from './ETHStakingDetail'\n"
  },
  {
    "path": "packages/component-lib/src/components/block/nftMedia.tsx",
    "content": "import {\n  GET_IPFS_STRING,\n  ImageIcon,\n  NFTWholeINFO,\n  RefreshIcon,\n  SoursURL,\n  SyncIcon,\n  RouterPath,\n  NFTSubRouter,\n} from '@loopring-web/common-resources'\nimport { useTheme } from '@emotion/react'\nimport React from 'react'\nimport { Box, BoxProps, Modal, Tooltip, Typography } from '@mui/material'\nimport {\n  cssBackground,\n  EmptyDefault,\n  MediaLabelStyled,\n  MediaSVGToggle,\n  ModalCloseButton,\n  NftImage,\n  NFTMedaProps,\n  useImage,\n  useOpenModals,\n  useSettings,\n  SwitchPanelStyled,\n  Button,\n} from '../../index'\nimport { NFT_IMAGE_SIZES } from '@loopring-web/loopring-sdk'\nimport styled from '@emotion/styled'\nimport { useTranslation, WithTranslation, withTranslation } from 'react-i18next'\nimport { useHistory } from 'react-router-dom'\n// import \"@google/model-viewer\";\n//background-color: var(--color-box-secondary);\nconst BoxStyle = styled(Box)<BoxProps>`\n  ${(props) => cssBackground(props)};\n  width: 100%;\n  position: relative;\n  overflow: hidden;\n  background-color: var(--opacity);\n  .redPacketNFT & {\n    background-image: none;\n    background-color: initial;\n  }\n`\n\nexport const NFTMedia = React.memo(\n  React.forwardRef(\n    (\n      {\n        item,\n        shouldPlay = true,\n        onNFTError,\n        index,\n        isOrigin = false,\n        getIPFSString,\n        baseURL,\n      }: NFTMedaProps,\n      ref: React.ForwardedRef<any>,\n    ) => {\n      const theme = useTheme()\n      const { t } = useTranslation()\n      const {\n        modals: {\n          isShowNFTDetail: { isShow },\n        },\n      } = useOpenModals()\n      const [play, setPlay] = React.useState(false)\n      const [previewSrc, setPreviewSrc] = React.useState(\n        (isOrigin\n          ? item?.metadata?.imageSize[NFT_IMAGE_SIZES.original]\n          : item?.metadata?.imageSize[NFT_IMAGE_SIZES.small]) ??\n          getIPFSString(item?.image, baseURL),\n        // item?.image?.startsWith(IPFS_HEAD_URL) ?\n        // baseURL + `/api/v3/delegator/ipfs?path=${item?.image?.replace(IPFS_HEAD_URL_REG, '')}`: item?.image\n        // item?.image?.replace(IPFS_HEAD_URL, IPFS_LOOPRING_SITE)\n      )\n      const { hasLoaded: previewSrcHasLoaded, hasError: previewSrcHasError } = useImage(\n        previewSrc ?? '',\n      )\n      const fullSrc = isOrigin\n        ? getIPFSString(item?.image, baseURL)\n        : item?.metadata?.imageSize[NFT_IMAGE_SIZES.original] ?? getIPFSString(item?.image, baseURL)\n      const { hasLoaded: fullSrcHasLoaded } = useImage(fullSrc ?? '')\n\n      return (\n        <BoxStyle\n          ref={ref}\n          theme={theme}\n          flex={1}\n          display={'flex'}\n          alignItems={'center'}\n          justifyContent={'center'}\n        >\n          {!previewSrcHasLoaded ? (\n            <Box\n              flex={1}\n              height={'100%'}\n              display={'flex'}\n              alignItems={'center'}\n              justifyContent={'center'}\n            >\n              <img className='loading-gif' width='36' src={`${SoursURL}images/loading-line.gif`} />\n            </Box>\n          ) : (\n            <>\n              {item && previewSrcHasError ? (\n                <Box\n                  flex={1}\n                  display={'flex'}\n                  alignItems={'center'}\n                  justifyContent={'center'}\n                  onClick={async (event) => {\n                    event.stopPropagation()\n                    setPreviewSrc(\n                      item?.metadata?.imageSize['160-160'] ?? getIPFSString(item?.image, baseURL),\n                    )\n                  }}\n                >\n                  <RefreshIcon style={{ height: 36, width: 36 }} />\n                </Box>\n              ) : (\n                <>\n                  {item.__mediaType__ && item.animationUrl && (\n                    <MediaSVGToggle\n                      url={item.animationUrl}\n                      play={play}\n                      shouldPlay={shouldPlay}\n                      setPlay={setPlay}\n                      mediaTyp={item.__mediaType__}\n                      getIPFSString={getIPFSString}\n                      baseURL={baseURL}\n                      isShow={isShow}\n                    />\n                  )}\n                  <Box\n                    alignSelf={'stretch'}\n                    position={'relative'}\n                    flex={1}\n                    margin={'1'}\n                    display={'flex'}\n                  >\n                    {play && shouldPlay ? (\n                      <></>\n                    ) : !!fullSrc && fullSrcHasLoaded ? (\n                      <NftImage\n                        alt={item?.image}\n                        {...item}\n                        onError={() => undefined}\n                        src={fullSrc}\n                      />\n                    ) : !!previewSrc ? (\n                      <NftImage\n                        alt={item?.image}\n                        {...item}\n                        onError={() => onNFTError(item, index)}\n                        src={previewSrc}\n                      />\n                    ) : (\n                      <EmptyDefault\n                        style={{ flex: 1 }}\n                        height={'100%'}\n                        emptyPic={\n                          <ImageIcon\n                            htmlColor={'var(--color-text-third)'}\n                            style={{ width: 80, height: 80 }}\n                          />\n                        }\n                        message={() => (\n                          <></>\n                          // <Box\n                          //   flex={1}\n                          //   display={\"flex\"}\n                          //   alignItems={\"center\"}\n                          //   justifyContent={\"center\"}\n                          // >\n                          //   {t(\"labelNoCollectionCover\")}\n                          // </Box>\n                        )}\n                      />\n                    )}\n                  </Box>\n                </>\n              )}\n            </>\n          )}\n\n          {item?.pendingOnSync ? (\n            <Tooltip title={t('labelMintInSyncTooltips').toString()} placement={'top'}>\n              <MediaLabelStyled\n                position={'absolute'}\n                left={0}\n                top={0}\n                display={'flex'}\n                justifyContent={'center'}\n                alignItems={'center'}\n              >\n                <SyncIcon color={'inherit'} />\n                <Typography color={'inherit'} component={'span'} paddingLeft={1}>\n                  {t('labelSync')}\n                </Typography>\n              </MediaLabelStyled>\n            </Tooltip>\n          ) : (\n            ''\n          )}\n        </BoxStyle>\n      )\n    },\n  ),\n)\nconst ModalFullStyled = styled(Box)`\n  & > div {\n    background: var(--color-global-bg-opacity);\n    position: absolute;\n    top: 56px;\n    left: 0;\n    right: 0;\n    bottom: 0;\n  }\n\n  .close-button {\n    margin-top: 0;\n  }\n` as typeof Box\n\nexport const ZoomMedia = withTranslation('common')(\n  ({\n    t,\n    open,\n    onClose,\n    getIPFSString,\n    baseURL,\n    nftItem,\n    className = '',\n    ...rest\n  }: WithTranslation & {\n    open: boolean\n    nftItem: Partial<NFTWholeINFO>\n    onClose: (event: any) => void\n    className?: string\n    getIPFSString: GET_IPFS_STRING\n    baseURL: string\n  }) => {\n    const ref = React.useRef()\n    // const { language } = useSettings();\n    return (\n      <Modal\n        open={open}\n        onClose={onClose}\n        aria-labelledby='modal-modal-title'\n        aria-describedby='modal-modal-description'\n      >\n        <ModalFullStyled\n          display={'flex'}\n          alignItems={'center'}\n          justifyContent={'center'}\n          className={className ?? ''}\n        >\n          <Box\n            className={'content'}\n            paddingTop={3}\n            paddingBottom={3}\n            display={'flex'}\n            flexDirection={'column'}\n          >\n            <ModalCloseButton className='full-btn-close' onClose={onClose} {...{ ...rest, t }} />\n            <Box\n              position={'absolute'}\n              top={0}\n              right={0}\n              bottom={0}\n              left={0}\n              display={'flex'}\n              alignItems={'center'}\n              justifyContent={'center'}\n              zIndex={88}\n            >\n              <NFTMedia\n                ref={ref}\n                item={nftItem as Partial<NFTWholeINFO>}\n                shouldPlay={true}\n                onNFTError={() => 'undefined'}\n                isOrigin={true}\n                getIPFSString={getIPFSString}\n                baseURL={baseURL}\n              />\n            </Box>\n          </Box>\n        </ModalFullStyled>\n      </Modal>\n    )\n  },\n)\n\nexport const CollectionHadUnknown = withTranslation('common')(\n  ({\n    t,\n    open,\n    onClose,\n    ...rest\n  }: WithTranslation & {\n    open: boolean\n    onClose: () => void\n  }) => {\n    const { mode } = useTheme()\n    const { isMobile } = useSettings()\n    const history = useHistory()\n    return (\n      <Modal\n        open={open}\n        onClose={onClose}\n        aria-labelledby='modal-modal-title'\n        aria-describedby='modal-modal-description'\n      >\n        <SwitchPanelStyled\n          display={'flex'}\n          alignItems={'center'}\n          justifyContent={'center'}\n          width={isMobile ? '90%' : 'var(--lage-modal-width)'}\n          sx={{ background: 'var(--color-pop-bg)' }}\n          // className={className ?? ''}\n        >\n          <ModalCloseButton className='full-btn-close' onClose={onClose} {...{ ...rest, t }} />\n          <Box\n            alignItems={'flex-start'}\n            justifyContent={'stretch'}\n            zIndex={88}\n            paddingX={3}\n            flexDirection={'column'}\n          >\n            <Typography component={'h4'} variant={isMobile ? 'h5' : 'h4'} textAlign={'center'}>\n              {t('labelHadUnknownCollectionTitle')}\n            </Typography>\n            <Typography\n              component={'p'}\n              variant={'body1'}\n              color={'textSecondary'}\n              textAlign={'left'}\n              marginY={2}\n            >\n              {t('labelHadUnknownCollectionDes')}\n            </Typography>\n            <Box display={'flex'} alignItems={'center'} justifyContent={'center'}>\n              <img\n                alt={'collection demo'}\n                width='80%'\n                // style={{\n                //   minHeight: '60px',\n                // }}\n                src={`${SoursURL}images/collection_unknown_${mode}.webp`}\n              />\n            </Box>\n            <Box display={'flex'} marginY={4} marginX={2} justifyContent={'center'}>\n              <Button\n                fullWidth\n                variant={'contained'}\n                size={'large'}\n                color={'primary'}\n                onClick={() => {\n                  history.replace(`${RouterPath.nft}/${NFTSubRouter.importLegacyCollection}`)\n                  onClose()\n                }}\n              >\n                {t('labelGo')}\n              </Button>\n            </Box>\n          </Box>\n        </SwitchPanelStyled>\n      </Modal>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/bottomRule/index.tsx",
    "content": "import { Box, Typography } from '@mui/material'\nimport { Button, ModalCloseButton } from '@loopring-web/component-lib'\nimport styled from '@emotion/styled'\nimport React from 'react'\nimport { useTranslation } from 'react-i18next'\n\nconst StyledBox = styled(Box)`\n  bottom: 0;\n  left: 0;\n  right: 0;\n  z-index: 100;\n  background: var(--color-pop-bg);\n  border-top: 1px solid var(--color-border);\n  //text-align: center;\n  .close-button {\n    right: ${({ theme }) => (theme.unit * 5) / 2}px;\n    top: 50%;\n    transform: translateY(-50%);\n    margin-top: 0;\n  }\n  .full-btn-close {\n  }\n` as typeof Box\n\nexport interface PopperProps {\n  isShow: boolean\n  title?: string\n  content: string\n  btnTxt: string\n  clickToConfirm?: () => void\n}\n\nexport const BottomRule = ({ isShow, title, content, btnTxt, clickToConfirm }: PopperProps) => {\n  const [_isShow, setIsShow] = React.useState(isShow)\n  const trans = useTranslation()\n  return _isShow ? (\n    <StyledBox\n      height={60}\n      width={'100%'}\n      flex={1}\n      display={'flex'}\n      alignItems={'center'}\n      justifyContent={'center'}\n      flexDirection={'row'}\n      position={'fixed'}\n    >\n      {title ? <Typography className={'title'}>{title}</Typography> : <></>}\n      <Typography className={'content'} color={'textSecondary'} variant={'body1'} paddingX={3}>\n        {content}\n      </Typography>\n      <Button\n        variant={'contained'}\n        size={'small'}\n        onClick={() => {\n          if (clickToConfirm) {\n            clickToConfirm()\n            setIsShow(false)\n          }\n        }}\n      >\n          {btnTxt}\n      </Button>\n      <ModalCloseButton onClose={() => setIsShow(false)} {...{ ...trans, tReady: true }} />\n    </StyledBox>\n  ) : (\n    <></>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/carousel/Carousel.tsx",
    "content": "import styled from '@emotion/styled'\nimport { Box, BoxProps } from '@mui/material'\nimport { CarouselItem } from './Interface'\nimport { myLog, SoursURL } from '@loopring-web/common-resources'\nimport React from 'react'\n\nconst StyleBox = styled(Box)<BoxProps & { imageList: CarouselItem[], preStr: string }>`\n  &.carousel {\n    //margin-left: 15%;\n    //margin-right: 15%;\n\n    ul.slides {\n      display: block;\n      position: relative;\n      margin: 0;\n      padding: 0;\n      overflow: hidden;\n      list-style: none;\n\n      input {\n        display: none;\n      }\n\n      ${({ imageList }) => `\n         height: calc(${imageList[0]?.height ?? 880 / 2}px + 60px);\n         width: calc(${imageList[0]?.width ?? 630 / 2}px);\n      `}\n    }\n  }\n\n  .slides * {\n    user-select: none;\n    -webkit-touch-callout: none;\n  }\n\n  .slide-container {\n    display: none;\n    position: absolute;\n  }\n\n  .slide-image {\n    display: block;\n    position: absolute;\n    top: 0;\n    opacity: 0;\n    transition: all 0.7s ease-in-out;\n  }\n\n  .carousel-controls {\n    position: absolute;\n    top: 0; //50%;\n    left: 0;\n    right: 0;\n    z-index: 999;\n    font-size: ${({ theme }) => theme.fontDefault.body1};\n    color: var(--color-text-primary);\n    height: 100%;\n    //transform: translateY(-50%);\n    label {\n      display: none;\n      position: absolute;\n      padding: 0 ${({ theme }) => 2 * theme.unit}px;\n      opacity: 0;\n      transition: opacity 0.2s;\n      cursor: pointer;\n      font-size: var(--svg-size-huge);\n      height: 100%;\n      align-items: center;\n      justify-content: center;\n\n      &:nth-child(1) {\n        justify-content: left;\n      }\n\n      &:nth-child(2) {\n        justify-content: right;\n      }\n\n      &:hover {\n        opacity: 1;\n      }\n    }\n\n    .prev-slide {\n      width: 30%;\n      text-align: left;\n      left: 0;\n    }\n\n    .next-slide {\n        width: 30%;\n        text-align: right;\n        right: 0;\n      }\n    }\n\n    .slide-image:hover + .carousel-controls label {\n      opacity: 0.5;\n    }\n\n    .carousel-dots {\n      position: absolute;\n      left: 0;\n      right: 0;\n      bottom: ${({ theme }) => 2 * theme.unit}px;\n      z-index: 999;\n      text-align: center;\n    }\n\n  .carousel-dots .carousel-dot {\n    display: inline-block;\n    width: var(--carousel-dot-size);\n    height: var(--carousel-dot-size);\n    border-radius: 50%;\n    background-color: #fff;\n    opacity: 0.5;\n    margin: 10px;\n  }\n\n  input:checked + .slide-container {\n    display: block;\n  }\n\n  input:checked + .slide-container .slide-image {\n    opacity: 1;\n    transform: scale(1);\n    transition: opacity 1s ease-in-out;\n  }\n\n  input:checked + .slide-container .carousel-controls label {\n    //display: block;\n    display: inline-flex;\n  }\n\n  ${({imageList, preStr}) => {\n    let label: string = imageList.reduce((prev, _, index) => {\n      prev += `input#${preStr}${index + 1}:checked ~ .carousel-dots label#${preStr}dot-${index + 1},`\n      return prev\n    }, '' as string)\n    label += `{ opacity: 1;}`\n    return label\n  }}\n  input:checked + .slide-container .nav label {\n    display: block;\n  }\n}\n` as (props: BoxProps & { imageList: CarouselItem[], preStr: string }) => JSX.Element\n\nexport const Carousel = ({\n                           loading,\n                           imageList,\n                           preStr = 'img-',\n                           selected,\n                           handleSelected\n                         }: {\n  loading: boolean\n  imageList: CarouselItem[]\n  selected: number\n  preStr?: string,\n  handleSelected: (id: number) => void\n}) => {\n  myLog('imageList', imageList)\n  return (\n    <Box>\n      {loading ? (\n        <Box\n          flex={1}\n          height={'100%'}\n          display={'flex'}\n          alignItems={'center'}\n          justifyContent={'center'}\n        >\n          <img className='loading-gif' width='36' src={`${SoursURL}images/loading-line.gif`} />\n        </Box>\n      ) : (\n        <StyleBox preStr={preStr} className='carousel' imageList={imageList}>\n          <Box component={'ul'} className='slides'>\n            {imageList.map((item, index) => {\n              return (\n                <React.Fragment key={index}>\n                  <input type='radio'\n                         name='radio-buttons'\n                         id={`${preStr}${index + 1}`} checked={selected == index}/>\n                  <Box\n                    component={'li'}\n                    className='slide-container'\n                    sx={{\n                      height: item?.size[ 1 ],\n                      width: item?.size[ 0 ],\n                    }}\n                  >\n                    <Box className='slide-image'>\n                      <img\n                        src={item.imageUrl}\n                        alt={'image'}\n                        style={{\n                          height: item?.size[1],\n                          width: item?.size[0],\n                        }}\n                      />\n                    </Box>\n                    <Box className='carousel-controls'>\n                      <label\n                        onClick={\n                          () => {\n                            handleSelected(selected === 0 ? imageList.length - 1 : selected - 1)\n                          }\n                        }\n                        className='prev-slide'\n                      >\n                        <span>&lsaquo;</span>\n                      </label>\n\n                      <label\n                        onClick={\n                          () => {\n                            handleSelected(selected === imageList.length - 1 ? 0 : selected + 1)\n                          }\n                        }\n                        className='next-slide'\n                      >\n                        <span>&rsaquo;</span>\n                      </label>\n                    </Box>\n                  </Box>\n                </React.Fragment>\n              )\n            })}\n\n            <Box className='carousel-dots'>\n              {imageList.map((_, index) => {\n                return (\n                  <label\n                    key={index}\n                    onClick={\n                      () => {\n                        handleSelected(index)\n                      }\n                    }\n                    className='carousel-dot'\n                    id={`${preStr}dot-${index + 1}`}\n                  />\n                )\n              })}\n            </Box>\n          </Box>\n        </StyleBox>\n      )}\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/carousel/Interface.ts",
    "content": "export type SocialButtonProps = {\n  url: string\n  /** Social Network Enum */\n  socialEnum: string\n  /** Message to be shared */\n  message?: string\n  /** Button size in pixels */\n  size?: number\n\n  imageUrl?: string\n  /** Function that sends share event to analytics */\n  sendShareEvent: () => void\n}\nexport type CarouselItem = { imageUrl: string; size: [number, number], height?: number, width?: number }\n\nexport type ShareProps = {\n  /** Social Networks configuration */\n  social: SocialButtonProps\n  size: number\n  /** share URL title */\n  title: string\n  /** Indcates if the component should render the Content Loader */\n  loading: boolean\n\n  imageUrl: string\n  /** Function that sends share event to analytics */\n  sendShareEvent: () => {}\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/carousel/index.tsx",
    "content": "export * from './Interface'\nexport * from './Carousel'\n"
  },
  {
    "path": "packages/component-lib/src/components/charts/constant.ts",
    "content": "export enum ChartType {\n  Kline = 'Kline',\n  Depth = 'Depth',\n  Trend = 'Trend',\n}\n\nexport enum timeUnit {\n  W1 = '1W',\n  H1 = '1H',\n  D1 = '1D',\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/charts/doughnutChart/DoughnutChart.stories.tsx",
    "content": "// also exported from '@storybook/react' if you can deal with breaking changes in 6.1\nimport { Meta, Story } from '@storybook/react'\nimport { DoughnutChart } from './DoughnutChart'\nimport { withTranslation } from 'react-i18next'\nimport styled from '@emotion/styled'\n\nconst Styled = styled.div`\n  flex: 1;\n\n  width: 500px;\n  height: 300px;\n`\n\n// @ts-ignore\nconst data = [\n  {\n    name: 'LP Token',\n    value: 12898.0,\n  },\n  {\n    name: 'LRC',\n    value: 12898.5,\n  },\n  {\n    name: 'ETH',\n    value: 36547.0,\n  },\n  {\n    name: 'DOT',\n    value: 23898.09,\n  },\n  {\n    name: 'BTC',\n    value: 3489,\n  },\n  {\n    name: 'CRV',\n    value: 180.09,\n  },\n]\n\nexport const Doughnut = withTranslation()(() => {\n  return (\n    <>\n      <Styled>\n        <DoughnutChart data={data} />\n      </Styled>\n    </>\n  )\n}) as Story\n\nexport default {\n  title: 'Charts/Doughnut',\n  component: Doughnut,\n  argTypes: {},\n} as Meta\n"
  },
  {
    "path": "packages/component-lib/src/components/charts/doughnutChart/DoughnutChart.tsx",
    "content": "import React from 'react'\nimport styled from '@emotion/styled'\n\nimport { Cell, Legend, Pie, PieChart, ResponsiveContainer, Sector } from '@loopring-web/recharts'\n\nconst colors = ['#00BBA8', '#ED9526', '#1C60FF', '#FFCA28', '#63992D', '#FF5677']\n\nconst StyledLegendItem = styled.div`\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  width: 170px;\n  // margin-bottom: ${({ theme }) => theme.unit}px;\n  color: ${({ theme }) => `${theme.colorBase.textPrimary}`};\n  font-size: 1.4rem;\n  padding: ${({ theme }) => theme.unit / 1.5}px;\n  border-radius: ${({ theme }) => theme.unit / 2}px;\n\n  & > span:first-of-type {\n    display: flex;\n    align-items: center;\n\n    & > div:first-of-type {\n      margin-right: ${({ theme }) => theme.unit / 2}px;\n    }\n  }\n`\n\nconst UlStyled = styled.ul`\n  margin-top: ${({ theme }) => theme.unit}px;\n  margin-right: ${({ theme }) => theme.unit * 2}px;\n` as any\n\nconst LiWrapperStyled = styled.li`\n  background-color: ${({ theme, active }: any) => {\n    return active ? theme.colorBase.fieldOpacity : 'inherit'\n  }};\n` as any\n\nconst renderActiveShape = ({\n  cx,\n  cy,\n  innerRadius,\n  outerRadius,\n  startAngle,\n  endAngle,\n  fill,\n}: any) => (\n  <g>\n    <Sector\n      cx={cx}\n      cy={cy}\n      innerRadius={innerRadius}\n      outerRadius={outerRadius + 5}\n      startAngle={startAngle}\n      endAngle={endAngle}\n      fill={fill}\n      // cornerRadius={2}\n    />\n  </g>\n)\n\nexport interface DoughnutChartProps {\n  data?: {\n    name: string\n    value: number\n  }[]\n}\n\nexport const DoughnutChart = ({ data }: DoughnutChartProps) => {\n  const [activeIndex, setActiveIndex] = React.useState(undefined)\n\n  const onPieEnter = React.useCallback((_: any, index: any) => {\n    setActiveIndex(index)\n  }, [])\n\n  const onPieLeave = React.useCallback(() => {\n    setActiveIndex(undefined)\n  }, [])\n\n  const getRenderLegend = React.useCallback(\n    ({ payload }: any) => (\n      <UlStyled>\n        {payload.map((entry: any, index: number) => {\n          const {\n            color,\n            value,\n            payload: { value: amount },\n          } = entry\n          const StyledColoredRect = styled.div`\n            width: 1.2rem;\n            height: 1.2rem;\n            background-color: ${color};\n          `\n          return (\n            <LiWrapperStyled active={index === activeIndex} key={`item-${index}`}>\n              <StyledLegendItem>\n                <span>\n                  <StyledColoredRect />\n                  {value}\n                </span>\n                <span>{(amount * 100).toFixed(2)}%</span>\n              </StyledLegendItem>\n            </LiWrapperStyled>\n          )\n        })}\n      </UlStyled>\n    ),\n    [activeIndex],\n  )\n\n  const getFormattedData = React.useCallback(() => {\n    if (!data || !data.length) return []\n    if (data.length < 7) return data\n    data.sort((a, b) => b.value - a.value)\n    const others = data.slice(5, data.length).reduce((a, b) => ({\n      name: 'Others',\n      value: a.value + b.value,\n    }))\n    const result = data.slice(0, 5).concat([others])\n    return result\n  }, [data])\n  const formattedData = getFormattedData()\n  const paddingAngle =\n    formattedData.filter((item) => {\n      return item.value\n    }).length > 1\n      ? 5\n      : 0\n  return (\n    <ResponsiveContainer debounce={1}>\n      <PieChart>\n        <Pie\n          dataKey={'value'}\n          activeIndex={activeIndex}\n          activeShape={renderActiveShape}\n          data={formattedData}\n          cx={'40%'}\n          // cy={200}\n          innerRadius={54}\n          outerRadius={70}\n          fill='#8884d8'\n          stroke='none'\n          radius={5}\n          paddingAngle={paddingAngle}\n          minAngle={2}\n          animationEasing={'ease-in-out'}\n          animationDuration={1000}\n          onMouseEnter={onPieEnter}\n          onMouseLeave={onPieLeave}\n        >\n          {formattedData.map((entry, index) => (\n            <Cell key={entry.name} fill={colors[index]} />\n          ))}\n        </Pie>\n        <Legend layout='vertical' align='right' verticalAlign='middle' content={getRenderLegend} />\n      </PieChart>\n    </ResponsiveContainer>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/charts/doughnutChart/index.ts",
    "content": "export * from './DoughnutChart'\n"
  },
  {
    "path": "packages/component-lib/src/components/charts/index.tsx",
    "content": "export * from './scaleAreaChart'\nexport * from './doughnutChart'\nexport * from './constant'\n"
  },
  {
    "path": "packages/component-lib/src/components/charts/scaleAreaChart/APRChart/index.tsx",
    "content": "import React from 'react'\nimport {\n  Area,\n  ComposedChart,\n  Line,\n  ResponsiveContainer,\n  Tooltip,\n  XAxis,\n  YAxis,\n} from '@loopring-web/recharts'\nimport moment from 'moment'\nimport { getAprRenderData } from '../data'\nimport { Box, Typography } from '@mui/material'\nimport styled from '@emotion/styled'\nimport { DAT_STRING_FORMAT, DAT_STRING_FORMAT_S, UpColor } from '@loopring-web/common-resources'\nimport { ChartType } from '../../constant'\nimport { IndicatorProps } from '../KlineChart'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { useTheme } from '@emotion/react'\nimport { useSettings } from '../../../../stores'\n// import { getValuePrecisionThousand, myLog } from '@loopring-web/common-resources';\n\nconst DEFAULT_YAXIS_DOMAIN = 0.01\n\nconst TooltipStyled = styled(Box)`\n  background: var(--color-pop-bg);\n  border: 1px solid var(--color-border);\n  border-radius: ${({ theme }) => theme.unit * 0.25}px;\n  padding: ${({ theme }) => theme.unit * 2}px ${({ theme }) => theme.unit * 2}px;\n\n  > div:last-of-type {\n    color: var(--color-text-secondary);\n  }\n`\n\nconst TrendAprChart = ({\n  type,\n  data,\n  yAxisDomainPercent = DEFAULT_YAXIS_DOMAIN,\n  handleMove,\n  showTooltip = true,\n  showArea = true,\n  showXAxis = false,\n}: // isHeadTailCompare = false,\n// isDailyTrend = false,\n// handleMoveOut = undefined,\n{\n  type: ChartType\n  data: { apy: string; createdAt: number }[]\n  indicator?: IndicatorProps\n  interval?: sdk.TradingInterval\n  handleMove?: (props: any) => void\n  yAxisDomainPercent?: number\n  riseColor?: 'green' | 'red'\n  showTooltip?: boolean\n  showArea?: boolean\n  showXAxis?: boolean\n}) => {\n  const theme = useTheme()\n  const { upColor } = useSettings()\n  const colorRight =\n    upColor === UpColor.green\n      ? ['var(--color-success)', 'var(--color-error)']\n      : ['var(--color-error)', 'var(--color-success)']\n  const renderData = getAprRenderData(type, data)\n  const trendColor = theme.colorBase.primary\n  // current chart xAxis index\n  const [currentIndex, setCurrentIndex] = React.useState(-1)\n\n  const hasData = data && Array.isArray(data) && !!data.length\n\n  const handleMousemove = React.useCallback(\n    (props: any) => {\n      if (!hasData) return\n      const { activeTooltipIndex } = props\n      // avoid duplicated event\n      const isUpdate = activeTooltipIndex !== currentIndex\n      if (Number.isFinite(activeTooltipIndex) && isUpdate) {\n        setCurrentIndex(activeTooltipIndex)\n        if (handleMove) {\n          handleMove(renderData[activeTooltipIndex])\n        }\n      }\n    },\n    [renderData, handleMove, currentIndex, hasData],\n  )\n\n  const renderTooltipContent = React.useCallback(\n    (props: any) => {\n      if (!hasData) return\n      if (!props.payload || !props.payload.length || !props.payload[0].payload.createdAt)\n        return <span></span>\n      const { createdAt, apy } = props.payload[0].payload\n      // const index = data.findIndex((o: any) => o.createdAt === createdAt)\n      return (\n        <TooltipStyled>\n          <Typography display={'inline-flex'} variant={'body1'}>\n            <Typography component={'span'} variant={'inherit'} color={'textSecondary'}>\n              APR:\n            </Typography>\n            <Typography\n              component={'span'}\n              variant={'inherit'}\n              color={apy?.toString().charAt(0) == '-' ? colorRight[1] : colorRight[0]}\n            >\n              {(apy?.toString().charAt(0) == '-' ? '' : '+') + apy + '%'}\n            </Typography>\n          </Typography>\n          <Typography component={'div'} variant={'body2'} color={'var(--color-text-third)'}>\n            {moment(createdAt).format(DAT_STRING_FORMAT)}\n          </Typography>\n        </TooltipStyled>\n      )\n    },\n    [hasData, data],\n  )\n\n  const customTick = ({ x, y, payload }: any) => {\n    if (!renderData || !renderData.length) {\n      return <span></span>\n    }\n    return (\n      <g transform={`translate(${x}, ${y})`}>\n        <text x={0} y={0} dy={16} fontSize={12} textAnchor='end' fill={theme.colorBase.textThird}>\n          {moment(payload.value).format(DAT_STRING_FORMAT_S)}\n        </text>\n      </g>\n    )\n  }\n\n  return (\n    <ResponsiveContainer debounce={100} width={'99%'}>\n      <ComposedChart\n        margin={{ left: 5, right: 16, top: 36 }}\n        data={renderData}\n        onMouseMove={showTooltip && handleMousemove}\n        // onMouseLeave={showTooltip && handleMouseLeave}\n      >\n        <defs>\n          <linearGradient id='colorUv' x1='0' y1='0' x2='0' y2='1'>\n            <stop offset='5%' stopColor={trendColor} stopOpacity={0.4} />\n            <stop offset='90%' stopColor={trendColor} stopOpacity={0.1} />\n          </linearGradient>\n        </defs>\n        <XAxis\n          reversed={true}\n          hide={!showXAxis}\n          dataKey={'createdAt'}\n          interval={30}\n          axisLine={true}\n          tickLine={true}\n          tick={customTick}\n          stroke={theme.colorBase.textThird}\n        />\n        <YAxis\n          dataKey='apy'\n          orientation={'right'}\n          hide={false}\n          axisLine={false}\n          tickLine={true}\n          width={1}\n          tickCount={6}\n          label={{\n            value: 'APR %',\n            fontSize: 14,\n            textAnchor: 'end',\n            fill: theme.colorBase.textThird,\n            position: 'insideTopRight',\n            transform: 'translate(0, -36)',\n          }}\n          tick={{\n            fill: theme.colorBase.textThird,\n            fontSize: 12,\n            textAnchor: 'start',\n            width: 34,\n            transform: 'translate(-36, 0)',\n          }}\n          tickFormatter={(value, index) => (index == 0 ? '' : value)}\n          domain={[\n            Math.min.apply(\n              null,\n              Object.values(renderData ?? {}).map((item) => Number(item.apy)),\n            ) - 1,\n            Math.max.apply(\n              null,\n              Object.values(renderData ?? {}).map((item) => Number(item.apy)),\n            ),\n          ]}\n          /* tickFormatter={convertValue} */\n          stroke={theme.colorBase.textThird}\n        />\n        {hasData && showTooltip && (\n          <Tooltip\n            cursor={{ stroke: '#808080', strokeDasharray: '5 5' }}\n            //  cursor={<CustomCursor/>}\n            position={{ y: 50 }}\n            content={(props) => renderTooltipContent(props)}\n          />\n        )}\n        <Line\n          type='monotone'\n          strokeLinecap='round'\n          strokeWidth={2}\n          dataKey='apy'\n          stroke={trendColor}\n          dot={false}\n          legendType='none'\n          isAnimationActive={false}\n        />\n\n        {showArea && (\n          <Area\n            type='monotone'\n            dataKey='apy'\n            stroke='false'\n            strokeWidth={2}\n            fillOpacity={1}\n            fill='url(#colorUv)'\n            isAnimationActive={false}\n          />\n        )}\n      </ComposedChart>\n    </ResponsiveContainer>\n  )\n}\n\nexport default TrendAprChart\n"
  },
  {
    "path": "packages/component-lib/src/components/charts/scaleAreaChart/DepthChart/ScaleAreaChart.stories.tsx",
    "content": "// also exported from '@storybook/react' if you can deal with breaking changes in 6.1\nimport { Meta, Story } from '@storybook/react'\nimport { ScaleAreaChart } from '../ScaleAreaChart'\nimport { ChartType } from '../../index'\nimport { withTranslation } from 'react-i18next'\nimport styled from '@emotion/styled'\n\nconst Styled = styled.div`\n  flex: 1;\n\n  width: 1000px;\n  height: 500px;\n`\n\n// @ts-ignore\nconst testDepthData = {\n  bidsPrices: [1.5, 1.55, 1.56, 1.57, 1.58, 1.59, 1.6, 1.61, 1.62, 1.63],\n  bidsAmtTotals: [310, 290, 280, 280, 180, 170, 160, 160, 150, 70],\n  asksPrices: [1.5, 1.52, 1.53, 1.54, 1.55, 1.56, 1.57, 1.58, 1.59, 1.6],\n  asksAmtTotals: [60, 80, 80, 100, 120, 130, 140, 140, 150, 200],\n}\n\nexport const Depth = withTranslation()(() => {\n  return (\n    <>\n      <Styled>\n        <ScaleAreaChart\n          type={ChartType.Depth}\n          data={testDepthData}\n          yAxisDomainPercent={0.2}\n          handleMove={(props) => {\n            console.log(props)\n          }}\n          // riseColor=\"red\"\n        />\n      </Styled>\n    </>\n  )\n}) as Story\n\nexport default {\n  title: 'Charts/Depth',\n  component: Depth,\n  argTypes: {},\n} as Meta\n"
  },
  {
    "path": "packages/component-lib/src/components/charts/scaleAreaChart/DepthChart/index.tsx",
    "content": "import React, { useCallback, useState } from 'react'\nimport { getDepthData } from '../data'\nimport { Box, Typography } from '@mui/material'\nimport {\n  Area,\n  ComposedChart,\n  Line,\n  ResponsiveContainer,\n  Tooltip,\n  XAxis,\n  YAxis,\n} from '@loopring-web/recharts'\nimport { getValuePrecisionThousand } from '@loopring-web/common-resources'\nimport styled from '@emotion/styled'\nimport { withTranslation, WithTranslation } from 'react-i18next'\n\nconst ASKS_COLOR = '#FF5677'\nconst BIDS_COLOR = '#00BBA8'\nconst YAXIS_DOMAIN = 0.1\n\nconst TooltipStyled = styled(Box)`\n  background: var(--color-pop-bg);\n  border: 1px solid var(--color-border);\n  border-radius: ${({ theme }) => theme.unit * 0.25}px;\n  padding: ${({ theme }) => theme.unit * 2}px ${({ theme }) => theme.unit * 2}px;\n\n  > div:last-of-type {\n    color: var(--color-text-secondary);\n  }\n`\n\nexport interface DepthData {\n  // timeStamp: number\n  bidsPrices: any[]\n  bidsAmtTotals: any[]\n  asksPrices: any[]\n  asksAmtTotals: any[]\n}\n\nexport interface DepthProps {\n  data?: DepthData\n  handleMove?: (props: { type: 'asks' | 'bids'; price: number; amount: number }) => void\n  yAxisDomainPercent?: number\n  colorBase: any\n  marketPrecision?: number\n}\n\nconst DepthChart = withTranslation('common')(\n  ({\n    data,\n    handleMove,\n    yAxisDomainPercent = YAXIS_DOMAIN,\n    marketPrecision = 2,\n    t,\n  }: DepthProps & WithTranslation) => {\n    const [currentIndex, setCurrentIndex] = useState(-1)\n\n    const asksColor = ASKS_COLOR\n    const bidsColor = BIDS_COLOR\n\n    const hasData = data\n\n    const renderTooltipContent = useCallback(\n      (props: any) => {\n        // no data\n        if (!hasData) return ''\n        if (props.payload && !!props.payload.length && props.payload[0].payload) {\n          const { payload } = props.payload[0]\n          const { price } = payload\n          if (payload.bids || payload.asks) {\n            return (\n              <TooltipStyled>\n                <Typography>\n                  {t('labelProOrderPrice')}: {formatAxisTicker(price, true)}\n                </Typography>\n                <Typography>\n                  {t('labelProOrderTotalAmount')}:{' '}\n                  {getValuePrecisionThousand(\n                    payload.bids || payload.asks,\n                    undefined,\n                    undefined,\n                    marketPrecision,\n                    false,\n                  )}\n                </Typography>\n              </TooltipStyled>\n            )\n          }\n          // if (payload.asks) {\n          //     return (\n          //         <TooltipStyled>\n          //             <Typography>price: {price}</Typography>\n          //             <Typography>amount: {payload.asks}</Typography>\n          //         </TooltipStyled>\n          //     )\n          // }\n        }\n        return <span></span>\n      },\n      [hasData, t],\n    )\n\n    const handleMousemove = useCallback(\n      (props: any) => {\n        // no data\n        if (!hasData) return\n        const { activeTooltipIndex } = props\n        // avoid duplicated event\n        const isUpdate = activeTooltipIndex !== currentIndex\n        if (Number.isFinite(activeTooltipIndex) && isUpdate) {\n          setCurrentIndex(activeTooltipIndex)\n          // const {payload, name} = props.activePayload[ 0 ]\n          const payload = props.activePayload ? props.activePayload[0].payload : undefined\n          const name = props.activePayload ? props.activePayload[0].name : undefined\n          if (handleMove && props.activePayload) {\n            handleMove({\n              price: payload.price,\n              type: name,\n              amount: payload.bids || payload.asks,\n            })\n          }\n        }\n      },\n      [handleMove, currentIndex, hasData],\n    )\n\n    const formattedData = getDepthData(data)\n\n    const formatAxisTicker = React.useCallback(\n      (value: any, addZeros: boolean) => {\n        // myLog(getValuePrecisionThousand(value, undefined, undefined, marketPrecision, false))\n        return getValuePrecisionThousand(value, undefined, undefined, marketPrecision, addZeros)\n      },\n      [marketPrecision],\n    )\n\n    return (\n      <ResponsiveContainer width={'99%'}>\n        <ComposedChart data={formattedData} onMouseMove={handleMousemove}>\n          <defs>\n            <linearGradient id='colorAsks' x1='0' y1='0' x2='0' y2='1'>\n              <stop offset='5%' stopColor={asksColor} stopOpacity={1} />\n              <stop offset='98%' stopColor={asksColor} stopOpacity={0} />\n            </linearGradient>\n            <linearGradient id='colorBids' x1='0' y1='0' x2='0' y2='1'>\n              <stop offset='5%' stopColor={bidsColor} stopOpacity={1} />\n              <stop offset='98%' stopColor={bidsColor} stopOpacity={0} />\n            </linearGradient>\n          </defs>\n          <XAxis\n            dataKey='price'\n            // hide={true}\n            type='category'\n            tickFormatter={(value) => formatAxisTicker(value, true)}\n            allowDuplicatedCategory\n          />\n          <YAxis\n            // hide={true}\n            orientation={'right'}\n            tickFormatter={(value) => formatAxisTicker(value, false)}\n            domain={[\n              (dataMin: number) => dataMin * (1 - yAxisDomainPercent),\n              (dataMax: number) => dataMax * (1 + yAxisDomainPercent),\n            ]}\n          />\n          {hasData && (\n            <Tooltip\n              cursor={{ stroke: '#808080', strokeDasharray: '5 5' }}\n              //  cursor={<CustomCursor/>}\n              position={{ y: 50 }}\n              content={(props) => renderTooltipContent(props)}\n            />\n          )}\n          <Line\n            type='step'\n            dataKey='asks'\n            stroke={asksColor}\n            dot={false}\n            animationDuration={500}\n            isAnimationActive={false}\n          />\n          <Line\n            type='step'\n            dataKey='bids'\n            stroke={bidsColor}\n            dot={false}\n            animationDuration={500}\n            isAnimationActive={false}\n          />\n          <Area\n            type='step'\n            dataKey='asks'\n            stroke='false'\n            fill='url(#colorAsks)'\n            animationDuration={500}\n            isAnimationActive={false}\n          />\n          <Area\n            type='step'\n            dataKey='bids'\n            stroke='false'\n            fill='url(#colorBids)'\n            animationDuration={500}\n            isAnimationActive={false}\n          />\n        </ComposedChart>\n      </ResponsiveContainer>\n    )\n  },\n)\n\nexport default DepthChart\n"
  },
  {
    "path": "packages/component-lib/src/components/charts/scaleAreaChart/KlineChart/KlineChart.stories.tsx",
    "content": "// also exported from '@storybook/react' if you can deal with breaking changes in 6.1\nimport { Meta, Story } from '@storybook/react'\nimport { ScaleAreaChart } from '../ScaleAreaChart'\nimport { ChartType } from '../../index'\nimport { withTranslation } from 'react-i18next'\nimport styled from '@emotion/styled'\nimport { testKlineData } from './data'\nimport { MainIndicator, SubIndicator } from '.'\nimport { TradingInterval } from '@loopring-web/loopring-sdk'\n\nconst Styled = styled.div`\n  flex: 1;\n\n  width: 100%;\n  height: 100%;\n`\n\nconst formatDateData = testKlineData.map((d) => ({\n  ...d,\n  date: new Date(d.date),\n}))\n\nexport const Kline = withTranslation()(() => {\n  return (\n    <>\n      <Styled>\n        <ScaleAreaChart\n          type={ChartType.Kline}\n          data={formatDateData}\n          interval={TradingInterval.d1}\n          indicator={{\n            mainIndicators: [\n              { indicator: MainIndicator.MA, params: { period: 5 } },\n              { indicator: MainIndicator.MA, params: { period: 10 } },\n              { indicator: MainIndicator.BOLL },\n            ],\n            subIndicator: [\n              { indicator: SubIndicator.VOLUME },\n              { indicator: SubIndicator.MACD },\n              {\n                indicator: SubIndicator.SAR,\n                params: {\n                  accelerationFactor: 0.02,\n                  maxAccelerationFactor: 0.2,\n                },\n              },\n              { indicator: SubIndicator.RSI },\n            ],\n          }}\n        />\n      </Styled>\n    </>\n  )\n}) as Story\n\nexport default {\n  title: 'Charts/KineDay',\n  component: Kline,\n  argTypes: {},\n} as Meta\n"
  },
  {
    "path": "packages/component-lib/src/components/charts/scaleAreaChart/KlineChart/KlineChart.tsx",
    "content": "import { format } from 'd3-format'\nimport { timeFormat } from 'd3-time-format'\nimport React from 'react'\nimport {\n  BarSeries,\n  bollingerBand,\n  BollingerBandTooltip,\n  BollingerSeries,\n  CandlestickSeries,\n  Chart,\n  ChartCanvas,\n  CrossHairCursor,\n  CurrentCoordinate,\n  discontinuousTimeScaleProviderBuilder,\n  EdgeIndicator,\n  ema,\n  Label,\n  lastVisibleItemBasedZoomAnchor,\n  LineSeries,\n  MACDSeries,\n  MACDTooltip,\n  MouseCoordinateX,\n  MouseCoordinateY,\n  MovingAverageTooltip,\n  OHLCTooltip,\n  rsi,\n  RSISeries,\n  RSITooltip,\n  sar,\n  SARSeries,\n  SingleValueTooltip,\n  sma,\n  withDeviceRatio,\n  withSize,\n  XAxis,\n  YAxis,\n} from 'react-financial-charts'\nimport { macd } from '@react-financial-charts/indicators'\n\nexport interface IOHLCData {\n  date: Date\n  open: number\n  high: number\n  low: number\n  close: number\n  volume: number\n  txs: number\n}\n\nexport enum MainIndicator {\n  MA = 'MA',\n  EMA = 'EMA',\n  BOLL = 'BOLL',\n}\n\nexport enum SubIndicator {\n  VOLUME = 'VOLUME',\n  MACD = 'MACD',\n  RSI = 'RSI',\n  SAR = 'SAR',\n}\n\nexport interface IndicatorProps {\n  mainIndicators?: { indicator: MainIndicator; params?: any }[]\n  subIndicator?: { indicator: SubIndicator; params?: any }[]\n}\n\nexport interface StockChartProps {\n  readonly data: IOHLCData[]\n  readonly height: number\n  readonly dateTimeFormat: string\n  readonly width: number\n  readonly ratio: number\n}\n\nexport function fibonacci(n: number) {\n  let n1 = 1,\n    n2 = 1\n  for (let i = 2; i < n; i++) {\n    ;[n1, n2] = [n2, n1 + n2]\n  }\n  return [n1, n2]\n}\n\nexport type StockChartExtraProps = {\n  upColor: 'green' | 'red'\n  colorBase: any\n  marketPrecision?: number\n}\n\nclass StockChart extends React.Component<StockChartProps & IndicatorProps & StockChartExtraProps> {\n  // private readonly marginRight = (this.props.marketPrecision || 2) * 10;\n  // private readonly margin = { left: 0, right: this.marginRight, top: 0, bottom: 24 };\n  // private readonly pricesDisplayFormat = format(`.${this.props.marketPrecision || 2}f`);\n  private readonly xScaleProvider = discontinuousTimeScaleProviderBuilder().inputDateAccessor(\n    (d: IOHLCData) => d.date,\n  )\n\n  private readonly macdAppearance = {\n    fillStyle: {\n      divergence: '#4682B4',\n    },\n    strokeStyle: {\n      macd: '#0093FF',\n      signal: '#D84315',\n      zero: 'rgba(0, 0, 0, 0.3)',\n    },\n  }\n\n  public render() {\n    const {\n      data: initialData,\n      dateTimeFormat,\n      height,\n      ratio,\n      width,\n      mainIndicators,\n      subIndicator,\n      upColor,\n      colorBase,\n      marketPrecision,\n    } = this.props\n\n    const pricesDisplayFormat = format(`.${this.props.marketPrecision || 2}f`)\n\n    const isUpGreen = upColor === 'green'\n\n    const getPricePrecisioned = (price: number, precision = 2) => {\n      let formattedPrice = price as any\n      let [_init, _dot] = String(price || '').split('.')\n      if (_dot) {\n        const dotLen = _dot.length\n        if (dotLen < precision) {\n          for (let i = dotLen; i < precision; i++) {\n            _dot = _dot + '0'\n          }\n          formattedPrice = _init + '.' + _dot\n        }\n      }\n      return String(formattedPrice)\n    }\n\n    const getPriceWithPrecisionLenth = (price: number, precision = 2) => {\n      const formattedPrice = getPricePrecisioned(price, precision)\n      return formattedPrice.length\n    }\n\n    const marginRight =\n      getPriceWithPrecisionLenth(initialData[initialData.length - 1]?.close || 6, marketPrecision) *\n      8.5\n    const margin = { left: 0, right: marginRight, top: 0, bottom: 24 }\n\n    let mainIndicatorLst: any[] = []\n    let subIndicatorLst: any[] = []\n\n    let id = 1\n\n    let maToolTipOptions: any[] = []\n    let bollToolTipOption: any = undefined\n\n    if (mainIndicators && mainIndicators?.length > 0) {\n      mainIndicators.forEach((item: { indicator: MainIndicator; params?: any }) => {\n        switch (item.indicator) {\n          case MainIndicator.MA:\n            const periodMA = item.params.period\n            const indMA = sma()\n              .id(id++)\n              .options({ windowSize: periodMA })\n              .merge((d: any, c: any) => {\n                d = {\n                  ...d,\n                  [`sma${periodMA}`]: c,\n                }\n                return d\n              })\n              .accessor((d: any = {}) => d && d[`sma${periodMA}`])\n            mainIndicatorLst.push({ func: indMA, type: item.indicator })\n            maToolTipOptions.push({\n              yAccessor: indMA.accessor(),\n              type: 'MA',\n              stroke: indMA.stroke(),\n              windowSize: indMA.options().windowSize,\n            })\n            break\n          case MainIndicator.EMA:\n            const periodEMA = item.params.period\n            const indEMA = ema()\n              .id(id++)\n              .options({ windowSize: periodEMA })\n              .merge((d: any, c: any) => {\n                d && (d[`ema${periodEMA}`] = c)\n              })\n              .accessor((d: any = {}) => d && d[`ema${periodEMA}`])\n            mainIndicatorLst.push({ func: indEMA, type: item.indicator })\n            maToolTipOptions.push({\n              yAccessor: indEMA.accessor(),\n              type: 'EMA',\n              stroke: indEMA.stroke(),\n              windowSize: indEMA.options().windowSize,\n            })\n            break\n          case MainIndicator.BOLL:\n            const indBOLL = bollingerBand()\n              .id(id++)\n              .merge((d: any, c: any) => {\n                d && (d.bb = c)\n              })\n              .accessor((d: any = {}) => d && d.bb)\n            mainIndicatorLst.push({ func: indBOLL, type: item.indicator })\n            bollToolTipOption = indBOLL.options()\n            break\n          default:\n            break\n        }\n      })\n    }\n\n    if (subIndicator && subIndicator.length > 0) {\n      subIndicator.forEach((item: { indicator: SubIndicator; params?: any }) => {\n        switch (item.indicator) {\n          case SubIndicator.MACD:\n            const macdCalculator = macd()\n              .id(id++)\n              .options({\n                fast: 12,\n                signal: 9,\n                slow: 26,\n              })\n              .merge((d: any, c: any) => {\n                d.macd = c\n              })\n              .accessor((d: any = {}) => d && d.macd)\n            subIndicatorLst.push({\n              func: macdCalculator,\n              type: item.indicator,\n            })\n            break\n          case SubIndicator.RSI:\n            const rsiCalculator = rsi()\n              .options({ windowSize: 14 })\n              .merge((d: any, c: any) => {\n                d.rsi = c\n              })\n              .accessor((d: any = {}) => d && d.rsi)\n            subIndicatorLst.push({\n              func: rsiCalculator,\n              type: item.indicator,\n            })\n            break\n          case SubIndicator.SAR:\n            const sarCalculator = sar()\n              .id(id++)\n              .options({\n                accelerationFactor: item?.params.accelerationFactor,\n                maxAccelerationFactor: item?.params.maxAccelerationFactor,\n              })\n              .merge((d: any, c: any) => {\n                d.sar = c\n              })\n              .accessor((d: any = {}) => d && d.sar)\n            subIndicatorLst.push({\n              func: sarCalculator,\n              type: item.indicator,\n              params: item?.params,\n            })\n            break\n          case SubIndicator.VOLUME:\n            subIndicatorLst.push({ func: undefined, type: item.indicator })\n            break\n          default:\n            break\n        }\n      })\n    }\n\n    let calculatedData = initialData\n\n    mainIndicatorLst.forEach((item: any) => {\n      if (item.func) {\n        calculatedData = item.func(calculatedData)\n      }\n    })\n\n    subIndicatorLst.forEach((item: any) => {\n      if (item.func) {\n        calculatedData = item.func(calculatedData)\n      }\n    })\n\n    const { xScaleProvider } = this\n\n    const { data, xScale, xAccessor, displayXAccessor } = xScaleProvider(calculatedData)\n\n    const max = xAccessor(data[data.length - 1])\n    const min = xAccessor(data[Math.max(0, data.length - 100)])\n\n    const xExtents = [min, max + 5]\n\n    const gridHeight = height - margin.top - margin.bottom\n\n    const [h1, hall] = fibonacci(3 + subIndicatorLst.length)\n\n    const chartHeight = Math.floor((gridHeight * h1) / hall)\n\n    const subHeight = subIndicatorLst.length\n      ? Math.floor((gridHeight - chartHeight) / subIndicatorLst.length)\n      : 0\n\n    const timeDisplayFormat = timeFormat(dateTimeFormat)\n\n    const bbStroke = {\n      top: '#FF01FF',\n      middle: '#CC0165',\n      bottom: '#01CCCB',\n    }\n\n    let chartId = 1\n\n    const getTrendValueColor = (data?: any) => {\n      if (data && data.close && data.open) {\n        return data.close > data.open\n          ? isUpGreen\n            ? colorBase.success\n            : colorBase.error\n          : isUpGreen\n          ? colorBase.error\n          : colorBase.success\n      }\n      return colorBase.textPrimary\n    }\n\n    return (\n      <ChartCanvas\n        height={height}\n        ratio={ratio}\n        width={width}\n        margin={margin}\n        data={data}\n        displayXAccessor={displayXAccessor}\n        seriesName='Data'\n        xScale={xScale}\n        xAccessor={xAccessor}\n        xExtents={xExtents}\n        zoomAnchor={lastVisibleItemBasedZoomAnchor}\n      >\n        <Chart\n          id={chartId++}\n          height={chartHeight}\n          yExtents={this.candleChartExtents}\n          padding={{ top: 20, bottom: 10 }}\n        >\n          <XAxis\n            showGridLines\n            gridLinesStrokeStyle={colorBase.providerBtn}\n            showTicks={false}\n            showTickLabel={false}\n            tickLabelFill={colorBase.providerBtn}\n            strokeStyle={colorBase.textDisable}\n          />\n          <YAxis\n            showGridLines\n            gridLinesStrokeStyle={colorBase.providerBtn}\n            tickFormat={pricesDisplayFormat}\n            tickLabelFill={colorBase.textDisable}\n            strokeStyle={colorBase.textDisable}\n          />\n          <CandlestickSeries\n            fill={(data) => getTrendValueColor(data)}\n            wickStroke={(data) => getTrendValueColor(data)}\n          />\n\n          {mainIndicatorLst &&\n            mainIndicatorLst.map((item: any, index: number) => {\n              return (\n                <React.Fragment key={`${item}-${index}`}>\n                  <LineSeries yAccessor={item.func.accessor()} strokeStyle={item.func.stroke()} />\n                  <CurrentCoordinate\n                    yAccessor={item.func.accessor()}\n                    fillStyle={item.func.stroke()}\n                  />\n                </React.Fragment>\n              )\n            })}\n\n          <MouseCoordinateY rectWidth={margin.right} displayFormat={pricesDisplayFormat} />\n          <EdgeIndicator\n            itemType='last'\n            rectWidth={margin.right}\n            fill={(data) => getTrendValueColor(data)}\n            lineStroke={(data) => getTrendValueColor(data)}\n            displayFormat={pricesDisplayFormat}\n            yAccessor={this.yEdgeIndicator}\n          />\n          <OHLCTooltip\n            origin={[8, 16]}\n            ohlcFormat={(n: any) => getPricePrecisioned(n, marketPrecision)}\n            changeFormat={(_: any) => ''}\n            textFill={(data: any) => getTrendValueColor(data)}\n          />\n          {maToolTipOptions && (\n            <MovingAverageTooltip\n              origin={[8, 24]}\n              textFill={colorBase.textPrimary}\n              options={maToolTipOptions}\n              // displayFormat={(n: number | {\n              //     valueOf(): number;\n              // }) => getPricePrecisioned(n | n.valueOf(), marketPrecision)}\n            />\n          )}\n          {bollToolTipOption && (\n            <>\n              <BollingerSeries strokeStyle={bbStroke} />\n              <BollingerBandTooltip\n                origin={[8, 64]}\n                yAccessor={(d) => d && d.bb}\n                options={bollToolTipOption}\n                textFill={colorBase.textPrimary}\n              />\n            </>\n          )}\n          <Label\n            text={'Loopring'}\n            fontFamily={'Roboto'}\n            // fontSize: number;\n            fontWeight={'400'}\n            fillStyle={colorBase.providerBtnHover}\n            x={(width - margin.left - margin.right) / 2}\n            y={((height - margin.top - margin.bottom) * 2) / 5}\n          />\n        </Chart>\n        {subIndicatorLst &&\n          subIndicatorLst.length > 0 &&\n          subIndicatorLst.map((item: any, ind: number) => {\n            switch (item.type) {\n              case SubIndicator.MACD:\n                return (\n                  /* @ts-ignore */\n                  <Chart\n                    key={SubIndicator.MACD}\n                    id={chartId++}\n                    height={subHeight}\n                    origin={(_w, _h) => [0, _h - (subIndicatorLst.length - ind) * subHeight]}\n                    yExtents={item.func.accessor()}\n                  >\n                    <XAxis\n                      showGridLines\n                      gridLinesStrokeStyle={colorBase.providerBtn}\n                      axisAt='bottom'\n                      orient='bottom'\n                      tickLabelFill={colorBase.textDisable}\n                      strokeStyle={colorBase.textDisable}\n                    />\n                    <YAxis\n                      showGridLines\n                      gridLinesStrokeStyle={colorBase.providerBtn}\n                      axisAt='right'\n                      orient='right'\n                      ticks={2}\n                      tickFormat={format('2s')}\n                      tickLabelFill={colorBase.textDisable}\n                      strokeStyle={colorBase.textDisable}\n                    />\n                    <MouseCoordinateX displayFormat={timeDisplayFormat} />\n                    <MouseCoordinateY\n                      rectWidth={margin.right}\n                      displayFormat={pricesDisplayFormat}\n                    />\n                    <MACDSeries yAccessor={item.func.accessor()} {...this.macdAppearance} />\n                    <MACDTooltip\n                      origin={[8, 16]}\n                      appearance={this.macdAppearance}\n                      options={item.func.options()}\n                      yAccessor={item.func.accessor()}\n                    />\n                  </Chart>\n                )\n              case SubIndicator.VOLUME:\n                return (\n                  /* @ts-ignore */\n                  <Chart\n                    key={SubIndicator.VOLUME}\n                    id={chartId++}\n                    height={subHeight}\n                    origin={(_: number, h: number) => [\n                      0,\n                      h - (subIndicatorLst.length - ind) * subHeight,\n                    ]}\n                    yExtents={this.barChartExtents}\n                  >\n                    <XAxis\n                      showGridLines\n                      gridLinesStrokeStyle={colorBase.providerBtn}\n                      axisAt='bottom'\n                      orient='bottom'\n                      tickLabelFill={colorBase.textDisable}\n                      strokeStyle={colorBase.textDisable}\n                    />\n                    <YAxis\n                      showGridLines\n                      gridLinesStrokeStyle={colorBase.providerBtn}\n                      axisAt='right'\n                      orient='right'\n                      ticks={2}\n                      tickFormat={format('.2s')}\n                      tickLabelFill={colorBase.textDisable}\n                      strokeStyle={colorBase.textDisable}\n                    />\n                    <MouseCoordinateX displayFormat={timeDisplayFormat} />\n                    <MouseCoordinateY\n                      rectWidth={margin.right}\n                      displayFormat={pricesDisplayFormat}\n                    />\n                    <BarSeries fillStyle={this.volumeColor} yAccessor={this.volumeSeries} />\n                    <SingleValueTooltip\n                      yAccessor={this.volumeSeries}\n                      yLabel={`VOL`}\n                      origin={[8, 16]}\n                      valueFill={colorBase.textPrimary}\n                    />\n                  </Chart>\n                )\n              case SubIndicator.RSI:\n                return (\n                  /* @ts-ignore */\n                  <Chart\n                    key={SubIndicator.RSI}\n                    id={chartId++}\n                    height={subHeight}\n                    origin={(_: number, h: number) => [\n                      0,\n                      h - (subIndicatorLst.length - ind) * subHeight,\n                    ]}\n                    yExtents={[0, 100]}\n                  >\n                    <XAxis\n                      showGridLines\n                      gridLinesStrokeStyle={colorBase.providerBtn}\n                      axisAt='bottom'\n                      orient='bottom'\n                      tickLabelFill={colorBase.textDisable}\n                      strokeStyle={colorBase.textDisable}\n                    />\n                    <YAxis\n                      showGridLines\n                      gridLinesStrokeStyle={colorBase.providerBtn}\n                      axisAt='right'\n                      orient='right'\n                      ticks={2}\n                      tickFormat={format('.2s')}\n                      tickLabelFill={colorBase.textDisable}\n                      strokeStyle={colorBase.textDisable}\n                    />\n                    <MouseCoordinateX displayFormat={timeDisplayFormat} />\n                    <MouseCoordinateY\n                      rectWidth={margin.right}\n                      displayFormat={pricesDisplayFormat}\n                    />\n                    <RSISeries yAccessor={item.func.accessor()} />\n                    <RSITooltip\n                      origin={[8, 16]}\n                      yAccessor={item.func.accessor()}\n                      options={item.func.options()}\n                      textFill={colorBase.textPrimary}\n                    />\n                  </Chart>\n                )\n              case SubIndicator.SAR:\n                return (\n                  /* @ts-ignore */\n                  <Chart\n                    key={SubIndicator.SAR}\n                    id={chartId++}\n                    height={subHeight}\n                    origin={(_: number, h: number) => [\n                      0,\n                      h - (subIndicatorLst.length - ind) * subHeight,\n                    ]}\n                    yExtents={item.func.accessor()}\n                  >\n                    <XAxis\n                      showGridLines\n                      gridLinesStrokeStyle={colorBase.providerBtn}\n                      axisAt='bottom'\n                      orient='bottom'\n                      tickLabelFill={colorBase.textDisable}\n                      strokeStyle={colorBase.textDisable}\n                    />\n                    <YAxis\n                      showGridLines\n                      gridLinesStrokeStyle={colorBase.providerBtn}\n                      axisAt='right'\n                      orient='right'\n                      ticks={2}\n                      tickFormat={format('.2s')}\n                      tickLabelFill={colorBase.textDisable}\n                      strokeStyle={colorBase.textDisable}\n                    />\n                    <MouseCoordinateX displayFormat={timeDisplayFormat} />\n                    <MouseCoordinateY\n                      rectWidth={margin.right}\n                      displayFormat={pricesDisplayFormat}\n                    />\n                    <SARSeries yAccessor={item.func.accessor()} />\n                    <SingleValueTooltip\n                      yLabel={`SAR (${item.params.accelerationFactor}, ${item.params.maxAccelerationFactor})`}\n                      yAccessor={item.func.accessor()}\n                      origin={[8, 16]}\n                      valueFill={colorBase.textPrimary}\n                    />\n                  </Chart>\n                )\n              default:\n                break\n            }\n            return <></>\n          })}\n        <CrossHairCursor strokeStyle={colorBase.textPrimary} />\n      </ChartCanvas>\n    )\n  }\n\n  // @ts-ignore\n  private readonly barChartExtents = (data: IOHLCData) => {\n    return data.volume\n  }\n\n  private readonly candleChartExtents = (data: any) => {\n    // data max > bolling band ? data max : bolling band\n    // data min < booling band ? data min : bolling band\n    return [\n      data.bb ? (data.high >= data.bb.top ? data.high : data.bb.top * 1.05) : data.high,\n      data.bb ? (data.low <= data.bb.bottom ? data.low : data.bb.bottom * 0.95) : data.low,\n    ]\n  }\n\n  private readonly yEdgeIndicator = (data: IOHLCData) => {\n    return data.close\n  }\n\n  private readonly volumeColor = (data: IOHLCData) => {\n    return data.close > data.open\n      ? this.props.upColor === 'green'\n        ? 'rgba(38, 166, 154, 0.3)'\n        : 'rgba(239, 83, 80, 0.3)'\n      : this.props.upColor === 'green'\n      ? 'rgba(239, 83, 80, 0.3)'\n      : 'rgba(38, 166, 154, 0.3)'\n  }\n\n  private readonly volumeSeries = (data: IOHLCData) => {\n    return data.volume\n  }\n}\n\nexport const WrapperedKlineChart = withSize({ style: { minHeight: 200 } })(\n  withDeviceRatio()(StockChart),\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/charts/scaleAreaChart/KlineChart/KlineChart_min.stories.tsx",
    "content": "// also exported from '@storybook/react' if you can deal with breaking changes in 6.1\nimport { Meta, Story } from '@storybook/react'\nimport { ScaleAreaChart } from '../ScaleAreaChart'\nimport { ChartType } from '../../index'\nimport { withTranslation } from 'react-i18next'\nimport styled from '@emotion/styled'\nimport { testKlineData } from './data_min'\nimport { MainIndicator, SubIndicator } from '.'\nimport { TradingInterval } from '@loopring-web/loopring-sdk'\n\nconst Styled = styled.div`\n  flex: 1;\n\n  width: 100%;\n  height: 100%;\n`\n\nconst formatDateData = testKlineData.map((d) => ({\n  ...d,\n  date: new Date(d.date),\n}))\n\nexport const Kline = withTranslation()(() => {\n  return (\n    <>\n      <Styled>\n        <ScaleAreaChart\n          type={ChartType.Kline}\n          data={formatDateData}\n          interval={TradingInterval.min1}\n          indicator={{\n            mainIndicators: [\n              { indicator: MainIndicator.MA, params: { period: 5 } },\n              { indicator: MainIndicator.MA, params: { period: 10 } },\n              { indicator: MainIndicator.BOLL },\n            ],\n            subIndicator: [\n              { indicator: SubIndicator.VOLUME },\n              { indicator: SubIndicator.MACD },\n              {\n                indicator: SubIndicator.SAR,\n                params: {\n                  accelerationFactor: 0.02,\n                  maxAccelerationFactor: 0.2,\n                },\n              },\n              { indicator: SubIndicator.RSI },\n            ],\n          }}\n        />\n      </Styled>\n    </>\n  )\n}) as Story\n\nexport default {\n  title: 'Charts/KineMin',\n  component: Kline,\n  argTypes: {},\n} as Meta\n"
  },
  {
    "path": "packages/component-lib/src/components/charts/scaleAreaChart/KlineChart/data.ts",
    "content": "export const testKlineData = [\n  {\n    date: '2010-01-04',\n    open: 25.436282332605284,\n    high: 25.835021381744056,\n    low: 25.411360259406774,\n    close: 25.710416,\n    volume: 38409100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-01-05',\n    open: 25.627344939513726,\n    high: 25.83502196495549,\n    low: 25.452895407434543,\n    close: 25.718722,\n    volume: 49749600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-01-06',\n    open: 25.65226505944465,\n    high: 25.81840750861228,\n    low: 25.353210976925574,\n    close: 25.560888,\n    volume: 58182400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-01-07',\n    open: 25.444587793771767,\n    high: 25.502739021094353,\n    low: 25.079077898061875,\n    close: 25.295062,\n    volume: 50559700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-01-08',\n    open: 25.153841756996414,\n    high: 25.6522649488092,\n    low: 25.120612602739726,\n    close: 25.46951,\n    volume: 51197400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-01-11',\n    open: 25.511044730573705,\n    high: 25.55258096597291,\n    low: 25.02092861663475,\n    close: 25.145534,\n    volume: 68754700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-01-12',\n    open: 25.045848646491518,\n    high: 25.253525666777517,\n    low: 24.84647870701696,\n    close: 24.979392,\n    volume: 65912100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-01-13',\n    open: 25.13722727051071,\n    high: 25.353211377924218,\n    low: 24.929550244151567,\n    close: 25.211991,\n    volume: 51863500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-01-14',\n    open: 25.178761733851413,\n    high: 25.83502196495549,\n    low: 25.137227159471163,\n    close: 25.718722,\n    volume: 63228100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-01-15',\n    open: 25.818406945612217,\n    high: 25.95132023748152,\n    low: 25.51104412745638,\n    close: 25.635652,\n    volume: 79913200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-01-19',\n    open: 25.544274163987136,\n    high: 25.95132113440514,\n    low: 25.486124596784563,\n    close: 25.835022,\n    volume: 46575700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-01-20',\n    open: 25.59411494568944,\n    high: 25.702108656795026,\n    low: 25.17876090842236,\n    close: 25.41136,\n    volume: 54849500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-01-21',\n    open: 25.427975689088637,\n    high: 25.51935191837554,\n    low: 24.92124291902699,\n    close: 24.92955,\n    volume: 73086700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-01-22',\n    open: 24.921242227943445,\n    high: 25.087384673504477,\n    low: 23.9576208617963,\n    close: 24.057305,\n    volume: 102004600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-01-25',\n    open: 24.289904353342425,\n    high: 24.63880174829468,\n    low: 24.17360522169168,\n    close: 24.356361,\n    volume: 63373000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-01-26',\n    open: 24.256677400199628,\n    high: 24.796636835593223,\n    low: 24.165298678305085,\n    close: 24.505889,\n    volume: 66639900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-01-27',\n    open: 24.381282411526794,\n    high: 24.771715213346813,\n    low: 24.107148742163798,\n    close: 24.647109,\n    volume: 63949500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-01-28',\n    open: 24.788329503429356,\n    high: 24.813251576935805,\n    low: 23.999155984106725,\n    close: 24.223448,\n    volume: 117513700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-01-29',\n    open: 24.838171916252662,\n    high: 24.854786078069555,\n    low: 22.977385792760824,\n    close: 23.409354,\n    volume: 193888500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-02-01',\n    open: 23.583802007377084,\n    high: 23.658566566701865,\n    low: 23.193370033086943,\n    close: 23.600417,\n    volume: 85931100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-02-02',\n    open: 23.567188934614894,\n    high: 23.675180153730853,\n    low: 23.376124415817756,\n    close: 23.641951,\n    volume: 54413700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-02-03',\n    open: 23.47581083464236,\n    high: 23.916086957012187,\n    low: 23.359512531703963,\n    close: 23.783172,\n    volume: 61397900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-02-04',\n    open: 23.575494533516057,\n    high: 23.67518033405172,\n    low: 23.101990926835022,\n    close: 23.126913,\n    volume: 77850000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-02-05',\n    open: 23.259826837972874,\n    high: 23.492425937060705,\n    low: 22.90262235438972,\n    close: 23.276441,\n    volume: 80960100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-02-08',\n    open: 23.268134182833126,\n    high: 23.326283750587436,\n    low: 22.902622614091726,\n    close: 23.027228,\n    volume: 52820600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-02-09',\n    open: 23.234904845121957,\n    high: 23.542267674401998,\n    low: 23.052149892895393,\n    close: 23.268134,\n    volume: 59195800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-02-10',\n    open: 23.284748153680564,\n    high: 23.459196018578062,\n    low: 23.12691278885316,\n    close: 23.251519,\n    volume: 48591300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-02-11',\n    open: 23.201676634364272,\n    high: 23.59210943129056,\n    low: 23.01061460700204,\n    close: 23.359512,\n    volume: 65993700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-02-12',\n    open: 23.101991198292986,\n    high: 23.309668221207414,\n    low: 22.9109291679198,\n    close: 23.201677,\n    volume: 81117200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-02-16',\n    open: 23.47709177175651,\n    high: 23.677395688560953,\n    low: 23.38528740952381,\n    close: 23.660703,\n    volume: 51935600,\n    split: '',\n    dividend: '$0.130',\n  },\n  {\n    date: '2010-02-17',\n    open: 23.810930273207585,\n    high: 23.911080561385095,\n    low: 23.669049515949805,\n    close: 23.861005,\n    volume: 45882900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-02-18',\n    open: 23.861005604453073,\n    high: 24.228227231839046,\n    low: 23.794238187581573,\n    close: 24.17815,\n    volume: 42856500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-02-19',\n    open: 24.0279246886073,\n    high: 24.13642090510949,\n    low: 23.944465418534303,\n    close: 24.011232,\n    volume: 44451800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-02-22',\n    open: 24.06965319596241,\n    high: 24.15311329961183,\n    low: 23.91108058475461,\n    close: 23.977848,\n    volume: 36707100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-02-23',\n    open: 23.93611844264031,\n    high: 24.061307346629015,\n    low: 23.443708753618075,\n    close: 23.644011,\n    volume: 52266200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-02-24',\n    open: 23.80258363823205,\n    high: 24.027924500255413,\n    low: 23.685739826453087,\n    close: 23.894388,\n    volume: 43165900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-02-25',\n    open: 23.593936399999997,\n    high: 23.911081636363633,\n    low: 23.385288218181813,\n    close: 23.869352,\n    volume: 48735300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-02-26',\n    open: 23.911081145797,\n    high: 24.077999687826996,\n    low: 23.794238166376,\n    close: 23.927773,\n    volume: 40370600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-03-01',\n    open: 24.01123281771192,\n    high: 24.24491794728184,\n    low: 23.810931397308096,\n    close: 24.219881,\n    volume: 43805400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-03-02',\n    open: 24.26995529971733,\n    high: 24.45356485597533,\n    low: 23.568897443742003,\n    close: 23.752507,\n    volume: 93123900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-03-03',\n    open: 23.794237468876933,\n    high: 23.87769757203811,\n    low: 23.660702639167347,\n    close: 23.752507,\n    volume: 48442100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-03-04',\n    open: 23.7525072419881,\n    high: 23.911080688476446,\n    low: 23.593935464685135,\n    close: 23.894388,\n    volume: 42890600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-03-05',\n    open: 23.919426488282614,\n    high: 23.93611834207765,\n    low: 23.719124242742218,\n    close: 23.861005,\n    volume: 56001800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-03-08',\n    open: 23.80258363823205,\n    high: 24.144766642848992,\n    low: 23.785891784348298,\n    close: 23.894388,\n    volume: 39414500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-03-09',\n    open: 23.835966751378393,\n    high: 24.294994406988312,\n    low: 23.827620824352493,\n    close: 24.036269,\n    volume: 50271600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-03-10',\n    open: 24.086346470987106,\n    high: 24.29499464871055,\n    low: 24.036269239148055,\n    close: 24.17815,\n    volume: 44891400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-03-11',\n    open: 24.11138228226816,\n    high: 24.361761761597496,\n    low: 24.077999408841674,\n    close: 24.353415,\n    volume: 35349700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-03-12',\n    open: 24.470258636146227,\n    high: 24.520333364928977,\n    low: 24.23657350832009,\n    close: 24.428529,\n    volume: 31700200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-03-15',\n    open: 24.35341496847337,\n    high: 24.511988415951947,\n    low: 24.21153420957548,\n    close: 24.445221,\n    volume: 37512000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-03-16',\n    open: 24.55371679966916,\n    high: 24.61213828763574,\n    low: 24.370107243509732,\n    close: 24.511988,\n    volume: 36723500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-03-17',\n    open: 24.620484783006575,\n    high: 24.929284918267495,\n    low: 24.5370255125557,\n    close: 24.728981,\n    volume: 50385700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-03-18',\n    open: 24.728980184354267,\n    high: 24.804093525282557,\n    low: 24.620483970939414,\n    close: 24.71229,\n    volume: 43845200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-03-19',\n    open: 24.837478759040216,\n    high: 24.954321737073336,\n    low: 24.495295751943225,\n    close: 24.695598,\n    volume: 81332100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-03-22',\n    open: 24.62048472972973,\n    high: 24.787404104862972,\n    low: 24.52867869783973,\n    close: 24.703944,\n    volume: 37718200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-03-23',\n    open: 24.695597951994575,\n    high: 24.95432168856498,\n    low: 24.545371266244018,\n    close: 24.937629,\n    volume: 42026600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-03-24',\n    open: 24.804093653097034,\n    high: 24.912591536256325,\n    low: 24.70394336593592,\n    close: 24.745673,\n    volume: 33987700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-03-25',\n    open: 24.89590031356214,\n    high: 25.51349891336221,\n    low: 24.870861697896466,\n    close: 25.046127,\n    volume: 73168700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-03-26',\n    open: 25.112893854012135,\n    high: 25.204699883817227,\n    low: 24.695597512137557,\n    close: 24.754019,\n    volume: 55595500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-03-29',\n    open: 24.795748289435686,\n    high: 24.88755432105441,\n    low: 24.662213457397836,\n    close: 24.695598,\n    volume: 33336000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-03-30',\n    open: 24.72898118589772,\n    high: 24.920939178563152,\n    low: 24.620484968088682,\n    close: 24.845825,\n    volume: 34954800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-03-31',\n    open: 24.737326775604377,\n    high: 24.804094191556327,\n    low: 24.345069041479377,\n    close: 24.445221,\n    volume: 63760000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-04-01',\n    open: 24.495295612139916,\n    high: 24.65386905887253,\n    low: 23.886043779037138,\n    close: 24.336723,\n    volume: 74768100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-04-05',\n    open: 24.311685184197852,\n    high: 24.56206383566792,\n    low: 24.228227581090845,\n    close: 24.428529,\n    volume: 34331200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-04-06',\n    open: 24.32837724079127,\n    high: 24.68725210231924,\n    low: 24.18649648158254,\n    close: 24.470258,\n    volume: 47366800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-04-07',\n    open: 24.336723385349234,\n    high: 24.670559634231825,\n    low: 24.32003069658276,\n    close: 24.495296,\n    volume: 58318800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-04-08',\n    open: 24.470258371657753,\n    high: 25.021089562834224,\n    low: 24.453565682786962,\n    close: 24.971014,\n    volume: 63713800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-04-09',\n    open: 24.996052675396935,\n    high: 25.379964490112062,\n    low: 24.954322205009888,\n    close: 25.321543,\n    volume: 54752500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-04-12',\n    open: 25.24642851253298,\n    high: 25.44673075527704,\n    low: 25.21304397081629,\n    close: 25.30485,\n    volume: 37068800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-04-13',\n    open: 25.16296936082202,\n    high: 25.455076799504866,\n    low: 25.146276672590325,\n    close: 25.413348,\n    volume: 41374600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-04-14',\n    open: 25.697110053606323,\n    high: 25.872373685918234,\n    low: 25.58861216807268,\n    close: 25.722147,\n    volume: 68941200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-04-15',\n    open: 25.722146531190592,\n    high: 25.830644414746768,\n    low: 25.630340501321108,\n    close: 25.763877,\n    volume: 52745400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-04-16',\n    open: 25.697109958166223,\n    high: 25.855681735898273,\n    low: 25.53853651124878,\n    close: 25.596958,\n    volume: 88703100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-04-19',\n    open: 25.680417138517488,\n    high: 26.081021630766053,\n    low: 25.672071211595643,\n    close: 25.905758,\n    volume: 64970300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-04-20',\n    open: 26.055983352397597,\n    high: 26.23959541623828,\n    low: 25.980870009129525,\n    close: 26.172828,\n    volume: 52199500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-04-21',\n    open: 26.147789,\n    high: 26.289669757421002,\n    low: 26.064329730928822,\n    close: 26.147789,\n    volume: 55343100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-04-22',\n    open: 25.90575822439064,\n    high: 26.314708647103302,\n    low: 25.788914411880036,\n    close: 26.197864,\n    volume: 84847600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-04-23',\n    open: 25.972525500371916,\n    high: 26.356437305440483,\n    low: 25.580266099168803,\n    close: 25.838989,\n    volume: 126766600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-04-26',\n    open: 25.87237297099412,\n    high: 26.106059755002228,\n    low: 25.75553083087908,\n    close: 25.964179,\n    volume: 63649300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-04-27',\n    open: 25.83064510525721,\n    high: 26.08102208265802,\n    low: 25.663725729335493,\n    close: 25.747185,\n    volume: 68730900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-04-28',\n    open: 25.805605926884507,\n    high: 25.872373341960532,\n    low: 25.55522895494209,\n    close: 25.79726,\n    volume: 64557900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-04-29',\n    open: 25.813952510322583,\n    high: 26.23124886516129,\n    low: 25.596958405806454,\n    close: 25.872374,\n    volume: 52665200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-04-30',\n    open: 25.93079529827127,\n    high: 25.93914122530644,\n    low: 25.471769311336956,\n    close: 25.488462,\n    volume: 63214800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-05-03',\n    open: 25.59695755583417,\n    high: 25.922447867207428,\n    low: 25.521844214457413,\n    close: 25.755531,\n    volume: 43989500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-05-04',\n    open: 25.471768984791538,\n    high: 25.49680593098337,\n    low: 24.829132611322027,\n    close: 25.146277,\n    volume: 82085600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-05-05',\n    open: 24.845824584254604,\n    high: 25.11289424723618,\n    low: 24.77905800310191,\n    close: 24.912592,\n    volume: 66833800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-05-06',\n    open: 24.695597537612148,\n    high: 24.937628581556385,\n    low: 23.29348182746722,\n    close: 24.186496,\n    volume: 128613000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-05-07',\n    open: 24.144766572660995,\n    high: 24.16145926108892,\n    low: 22.801072338924936,\n    close: 23.543859,\n    volume: 173718100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-05-10',\n    open: 24.21153365302234,\n    high: 24.60379221272315,\n    low: 23.96115501436531,\n    close: 24.153113,\n    volume: 86653300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-05-11',\n    open: 23.936118296957,\n    high: 24.745673204490068,\n    low: 23.844313101257377,\n    close: 24.103036,\n    volume: 63789400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-05-12',\n    open: 24.186496522197807,\n    high: 24.6872521437754,\n    low: 24.13642096004005,\n    close: 24.57041,\n    volume: 47146800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-05-13',\n    open: 24.420181853625174,\n    high: 24.81244041381669,\n    low: 24.35341443912449,\n    close: 24.40349,\n    volume: 45188800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-05-14',\n    open: 24.370107865356623,\n    high: 24.37845212323654,\n    low: 23.90273428051272,\n    close: 24.144767,\n    volume: 63334000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-05-17',\n    open: 24.30333968243861,\n    high: 24.395144042669525,\n    low: 23.744162586694905,\n    close: 24.153113,\n    volume: 46053300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-05-18',\n    open: 24.203414670176816,\n    high: 24.31240045454545,\n    low: 23.80938527272727,\n    close: 23.977057,\n    volume: 52690600,\n    split: '',\n    dividend: '$0.130',\n  },\n  {\n    date: '2010-05-19',\n    open: 23.90998841926346,\n    high: 24.052510226460626,\n    low: 23.29798745025666,\n    close: 23.675248,\n    volume: 61746700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-05-20',\n    open: 23.180615815912365,\n    high: 23.33990395352623,\n    low: 22.669217896668577,\n    close: 22.727903,\n    volume: 87991100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-05-21',\n    open: 22.325489846440167,\n    high: 22.72790367218875,\n    low: 22.166203380832563,\n    close: 22.501546,\n    volume: 117596300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-05-24',\n    open: 22.509930022839743,\n    high: 22.518314447799085,\n    low: 22.015298413399314,\n    close: 22.023682,\n    volume: 73711700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-05-25',\n    open: 21.503899367088607,\n    high: 22.073983248945147,\n    low: 21.277541693286924,\n    close: 21.85601,\n    volume: 98373600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-05-26',\n    open: 21.990147560975608,\n    high: 22.30872468881847,\n    low: 20.59008776619952,\n    close: 20.96735,\n    volume: 176684100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-05-27',\n    open: 21.570968163461536,\n    high: 22.09913495374327,\n    low: 21.570968163461536,\n    close: 21.797325,\n    volume: 136433600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-05-28',\n    open: 21.663187183844464,\n    high: 21.89792844060389,\n    low: 21.512282629158243,\n    close: 21.629652,\n    volume: 67496900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-06-01',\n    open: 21.40329755729635,\n    high: 22.057215639324475,\n    low: 21.394913132287105,\n    close: 21.705105,\n    volume: 76152400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-06-02',\n    open: 21.84762554061438,\n    high: 22.19973701132793,\n    low: 21.570968024979894,\n    close: 22.182969,\n    volume: 65718800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-06-03',\n    open: 22.258421143829665,\n    high: 22.57699826667914,\n    low: 22.14105177211274,\n    close: 22.518314,\n    volume: 67837000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-06-04',\n    open: 21.881160338070558,\n    high: 22.275188895882554,\n    low: 21.478749032280763,\n    close: 21.62127,\n    volume: 89832200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-06-07',\n    open: 21.646420244111496,\n    high: 21.654803830573194,\n    low: 21.160172229332847,\n    close: 21.202091,\n    volume: 80456200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-06-08',\n    open: 21.16855536963141,\n    high: 21.176938955916413,\n    low: 20.665540192531253,\n    close: 21.051186,\n    volume: 87355000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-06-09',\n    open: 21.14340352939433,\n    high: 21.394911953412183,\n    low: 20.749375816886815,\n    close: 20.782911,\n    volume: 87794000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-06-10',\n    open: 21.067951784841362,\n    high: 21.084719796,\n    low: 20.77452793755864,\n    close: 20.958966,\n    volume: 78930900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-06-11',\n    open: 20.992501474368005,\n    high: 21.56258368073722,\n    low: 20.76614380007794,\n    close: 21.512283,\n    volume: 68057700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-06-14',\n    open: 21.679954944240983,\n    high: 21.763789130268826,\n    low: 21.352993402817845,\n    close: 21.378145,\n    volume: 50972400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-06-15',\n    open: 21.587735317908205,\n    high: 22.342258105718585,\n    low: 21.579351731376974,\n    close: 22.283573,\n    volume: 81641500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-06-16',\n    open: 22.191351955334383,\n    high: 22.283572242401213,\n    low: 21.990146723784193,\n    close: 22.065599,\n    volume: 48698000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-06-17',\n    open: 22.266804463620687,\n    high: 22.359024751648665,\n    low: 21.830859650991975,\n    close: 22.107518,\n    volume: 47995500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-06-18',\n    open: 22.10751789594119,\n    high: 22.241655276647037,\n    low: 21.939845331700255,\n    close: 22.166203,\n    volume: 52075600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-06-21',\n    open: 22.45124465372495,\n    high: 22.54346242509174,\n    low: 21.70510380614602,\n    close: 21.755407,\n    volume: 54625300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-06-22',\n    open: 21.93146288242142,\n    high: 22.17458773591397,\n    low: 21.59611941327125,\n    close: 21.604503,\n    volume: 55985400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-06-23',\n    open: 21.612887249772587,\n    high: 21.612887249772587,\n    low: 21.143404720053248,\n    close: 21.218857,\n    volume: 61466200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-06-24',\n    open: 21.34461013604136,\n    high: 21.562583382441364,\n    low: 20.9002808952,\n    close: 20.958966,\n    volume: 85243400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-06-25',\n    open: 21.00088281019891,\n    high: 21.051186004637266,\n    low: 20.380497424972063,\n    close: 20.564938,\n    volume: 156256700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-06-28',\n    open: 20.548170568826432,\n    high: 20.63200727241897,\n    low: 20.22121153277291,\n    close: 20.380498,\n    volume: 73784800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-06-29',\n    open: 20.229593082687863,\n    high: 20.288279864024833,\n    low: 19.37446894923243,\n    close: 19.542139,\n    volume: 119882100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-06-30',\n    open: 19.53375617598292,\n    high: 19.852333308996087,\n    low: 19.240332318150063,\n    close: 19.290633,\n    volume: 81050500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-07-01',\n    open: 19.3577008955095,\n    high: 19.55052338169257,\n    low: 19.055891786701206,\n    close: 19.416386,\n    volume: 92239400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-07-02',\n    open: 19.58405911768827,\n    high: 19.684661318435754,\n    low: 19.32416625661341,\n    close: 19.508606,\n    volume: 62485100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-07-06',\n    open: 19.86910080057527,\n    high: 20.196059835012594,\n    low: 19.768496924433247,\n    close: 19.969703,\n    volume: 73592000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-07-07',\n    open: 19.969702693403402,\n    high: 20.388882011065103,\n    low: 19.793648218344124,\n    close: 20.372114,\n    volume: 79965300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-07-08',\n    open: 20.623622138467844,\n    high: 20.640390149296763,\n    low: 20.0954553672948,\n    close: 20.464334,\n    volume: 50758100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-07-09',\n    open: 20.39726652039555,\n    high: 20.464335214256288,\n    low: 20.2463619592089,\n    close: 20.346965,\n    volume: 53806100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-07-12',\n    open: 20.48110154450262,\n    high: 20.86674567996597,\n    low: 20.472717958115187,\n    close: 20.816445,\n    volume: 49854200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-07-13',\n    open: 21.076335586485612,\n    high: 21.210472970255505,\n    low: 20.875130349189423,\n    close: 21.067952,\n    volume: 61928700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-07-14',\n    open: 21.37814467853205,\n    high: 21.470364964523547,\n    low: 21.059569243249793,\n    close: 21.327844,\n    volume: 72808100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-07-15',\n    open: 21.378145413563306,\n    high: 21.453597691493528,\n    low: 20.94219891885535,\n    close: 21.386529,\n    volume: 56934700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-07-16',\n    open: 21.386529202351518,\n    high: 21.495514988701046,\n    low: 20.858362413483988,\n    close: 20.866746,\n    volume: 65064800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-07-19',\n    open: 20.92543033405517,\n    high: 21.210472265089656,\n    low: 20.883513241379312,\n    close: 21.151788,\n    volume: 38181800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-07-20',\n    open: 20.841596485140425,\n    high: 21.361378,\n    low: 20.707459103664757,\n    close: 21.361378,\n    volume: 45530700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-07-21',\n    open: 21.461981311226864,\n    high: 21.50389924347535,\n    low: 20.942198951345585,\n    close: 21.05957,\n    volume: 73297300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-07-22',\n    open: 21.386528652089787,\n    high: 21.788940794504644,\n    low: 21.352993468529917,\n    close: 21.663187,\n    volume: 73016400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-07-23',\n    open: 21.663187597953797,\n    high: 21.814092155524683,\n    low: 21.16855599258256,\n    close: 21.638036,\n    volume: 108520100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-07-26',\n    open: 21.67995576019774,\n    high: 21.96499770425904,\n    low: 21.62965256394019,\n    close: 21.881161,\n    volume: 67249900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-07-27',\n    open: 21.914693988858485,\n    high: 21.998530691131496,\n    low: 21.763789433812615,\n    close: 21.931462,\n    volume: 60672100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-07-28',\n    open: 21.85600919591487,\n    high: 21.956613068546975,\n    low: 21.654803127367895,\n    close: 21.755407,\n    volume: 69704800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-07-29',\n    open: 21.90631018637011,\n    high: 22.141051441373364,\n    low: 21.4619809503657,\n    close: 21.822476,\n    volume: 69446200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-07-30',\n    open: 21.587735319168356,\n    high: 21.663187597953797,\n    low: 21.252391857899724,\n    close: 21.638036,\n    volume: 83534800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-08-02',\n    open: 21.788941062286362,\n    high: 22.11590009365807,\n    low: 21.58773498860615,\n    close: 22.073983,\n    volume: 55044600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-08-03',\n    open: 21.96499718392439,\n    high: 22.09075014143731,\n    low: 21.772173020204054,\n    close: 21.931462,\n    volume: 56877700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-08-04',\n    open: 21.923077615623782,\n    high: 21.998529890400306,\n    low: 21.327843841856467,\n    close: 21.570967,\n    volume: 78531900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-08-05',\n    open: 21.36976119591008,\n    high: 21.445213471611606,\n    low: 21.135019944257824,\n    close: 21.269159,\n    volume: 64922100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-08-06',\n    open: 21.10987113306736,\n    high: 21.428446586629494,\n    low: 20.97573374699545,\n    close: 21.420063,\n    volume: 55982100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-08-09',\n    open: 21.42006180630899,\n    high: 21.570967195588945,\n    low: 21.269158932104883,\n    close: 21.470365,\n    volume: 57096500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-08-10',\n    open: 21.235624245313122,\n    high: 21.24400783167132,\n    low: 20.85836202083562,\n    close: 21.017651,\n    volume: 87257700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-08-11',\n    open: 20.69069061099394,\n    high: 20.875129506229705,\n    low: 20.590086738870365,\n    close: 20.841596,\n    volume: 76746900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-08-12',\n    open: 20.472717895467543,\n    high: 20.690691140873827,\n    low: 20.422417215655496,\n    close: 20.531403,\n    volume: 70240500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-08-13',\n    open: 20.414033067622952,\n    high: 20.682307834836067,\n    low: 20.32181361639344,\n    close: 20.455951,\n    volume: 45263500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-08-16',\n    open: 20.42241762693008,\n    high: 20.63200729019539,\n    low: 20.3721144310291,\n    close: 20.539787,\n    volume: 40909700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-08-17',\n    open: 20.826348,\n    high: 21.03705569772188,\n    low: 20.73363745583316,\n    close: 20.826348,\n    volume: 52912600,\n    split: '',\n    dividend: '$0.130',\n  },\n  {\n    date: '2010-08-18',\n    open: 20.80106369057212,\n    high: 21.028628844442387,\n    low: 20.573499379532635,\n    close: 20.91906,\n    volume: 46818900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-08-19',\n    open: 20.750494539619087,\n    high: 20.8516333898677,\n    low: 20.404932235936283,\n    close: 20.598785,\n    volume: 54064600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-08-20',\n    open: 20.489214616929882,\n    high: 20.56507022699133,\n    low: 20.39650492042051,\n    close: 20.421789,\n    volume: 49560100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-08-23',\n    open: 20.598784923605727,\n    high: 20.767349392451344,\n    low: 20.430217926267794,\n    close: 20.463932,\n    volume: 51643000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-08-24',\n    open: 20.303793696597598,\n    high: 20.52292970162522,\n    low: 20.2279389256265,\n    close: 20.261653,\n    volume: 66522500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-08-25',\n    open: 20.227938921161822,\n    high: 20.41336085177502,\n    low: 20.118371761502985,\n    close: 20.312222,\n    volume: 47404800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-08-26',\n    open: 20.303793308564234,\n    high: 20.388077228641016,\n    low: 20.05094491965697,\n    close: 20.076229,\n    volume: 49105300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-08-27',\n    open: 20.126798617261137,\n    high: 20.244795771834518,\n    low: 19.814952064772253,\n    close: 20.168941,\n    volume: 60939400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-08-30',\n    open: 20.00880292169217,\n    high: 20.07622938478128,\n    low: 19.890806611286237,\n    close: 19.924519,\n    volume: 45453100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-08-31',\n    open: 19.890806846647074,\n    high: 20.00037485046335,\n    low: 19.654814223042784,\n    close: 19.781238,\n    volume: 66074600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-09-01',\n    open: 19.949803926778245,\n    high: 20.185797380487656,\n    low: 19.840236771701047,\n    close: 20.143655,\n    volume: 65235900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-09-02',\n    open: 20.126797469333063,\n    high: 20.185797307500906,\n    low: 19.983516241817657,\n    close: 20.177369,\n    volume: 48837100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-09-03',\n    open: 20.430217619175888,\n    high: 20.607212921578718,\n    low: 20.396505231611968,\n    close: 20.47236,\n    volume: 64189100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-09-07',\n    open: 20.312222154099423,\n    high: 20.48078747022381,\n    low: 20.16051261103976,\n    close: 20.194225,\n    volume: 51928700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-09-08',\n    open: 20.286937311742584,\n    high: 20.39650615833435,\n    low: 20.00880314834935,\n    close: 20.168941,\n    volume: 65512400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-09-09',\n    open: 20.388077383022363,\n    high: 20.40493231293765,\n    low: 20.219510384423156,\n    close: 20.236367,\n    volume: 46028900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-09-10',\n    open: 20.211082000838577,\n    high: 20.253224382453418,\n    low: 20.050944996289896,\n    close: 20.101514,\n    volume: 58284300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-09-13',\n    open: 20.396505016605975,\n    high: 21.31519053517684,\n    low: 20.303792791167155,\n    close: 21.163481,\n    volume: 114680400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-09-14',\n    open: 21.104483307693638,\n    high: 21.365760003365565,\n    low: 20.97805700662757,\n    close: 21.096055,\n    volume: 87160400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-09-15',\n    open: 21.15505254159823,\n    high: 21.25619139219342,\n    low: 21.003343001459278,\n    close: 21.17191,\n    volume: 56201900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-09-16',\n    open: 21.121338842917336,\n    high: 21.382618074571813,\n    low: 21.112910534982078,\n    close: 21.348904,\n    volume: 44548300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-09-17',\n    open: 21.407902387307782,\n    high: 21.51747123448307,\n    low: 21.13819653045981,\n    close: 21.256192,\n    volume: 70341600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-09-20',\n    open: 21.306763224270032,\n    high: 21.509041771136452,\n    low: 21.16348198990118,\n    close: 21.433187,\n    volume: 49838700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-09-21',\n    open: 21.424758309343936,\n    high: 21.424758309343936,\n    low: 21.138195845725644,\n    close: 21.197194,\n    volume: 52675700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-09-22',\n    open: 20.9780569288857,\n    high: 21.045483390184913,\n    low: 20.531358308439973,\n    close: 20.742066,\n    volume: 94299400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-09-23',\n    open: 20.657782462546052,\n    high: 20.725208925092097,\n    low: 20.531358688102987,\n    close: 20.590356,\n    volume: 46201800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-09-24',\n    open: 20.767349008365777,\n    high: 20.902201929477442,\n    low: 20.716780005779658,\n    close: 20.885347,\n    volume: 51948800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-09-27',\n    open: 20.944344692680957,\n    high: 21.062341000808733,\n    low: 20.72520869187222,\n    close: 20.843205,\n    volume: 43603300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-09-28',\n    open: 20.902202852469042,\n    high: 20.98648677471637,\n    low: 20.522929837925446,\n    close: 20.801064,\n    volume: 56041200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-09-29',\n    open: 20.75892115798555,\n    high: 20.78420692408163,\n    low: 20.565070922448978,\n    close: 20.649354,\n    volume: 44318900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-09-30',\n    open: 20.742066537400003,\n    high: 20.9274884679461,\n    low: 20.53135884038081,\n    close: 20.640926,\n    volume: 61262700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-10-01',\n    open: 20.876918853852292,\n    high: 20.91906039372684,\n    low: 20.48078753620072,\n    close: 20.548214,\n    volume: 62672300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-10-04',\n    open: 20.194224696274194,\n    high: 20.21951046256796,\n    low: 20.042516841157838,\n    close: 20.152084,\n    volume: 98143400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-10-05',\n    open: 20.278508224931002,\n    high: 20.607213922912933,\n    low: 20.1520844476386,\n    close: 20.52293,\n    volume: 78152900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-10-06',\n    open: 20.49764461399918,\n    high: 20.6830682288316,\n    low: 20.33750592262153,\n    close: 20.590356,\n    volume: 50489700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-10-07',\n    open: 20.750494770654107,\n    high: 20.860061929879254,\n    low: 20.463932303738595,\n    close: 20.67464,\n    volume: 50096100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-10-08',\n    open: 20.750494381292306,\n    high: 20.77577846153846,\n    low: 20.539786688984616,\n    close: 20.708352,\n    volume: 41327800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-10-11',\n    open: 20.851633617730783,\n    high: 20.851633617730783,\n    low: 20.649354229361528,\n    close: 20.725209,\n    volume: 27587800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-10-12',\n    open: 20.77577846153846,\n    high: 21.01177107692308,\n    low: 20.590355692307693,\n    close: 20.927488,\n    volume: 50141500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-10-13',\n    open: 21.087626149960535,\n    high: 21.525898999105447,\n    low: 20.97805730555122,\n    close: 21.357332,\n    volume: 75336500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-10-14',\n    open: 21.315190688252873,\n    high: 21.35733138327388,\n    low: 21.070768925881886,\n    close: 21.26462,\n    volume: 51949100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-10-15',\n    open: 21.374189459346496,\n    high: 21.53432562215252,\n    low: 21.26462061493263,\n    close: 21.525899,\n    volume: 68954800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-10-18',\n    open: 21.56803892718823,\n    high: 21.871458840506975,\n    low: 21.450043464829204,\n    close: 21.76189,\n    volume: 48330500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-10-19',\n    open: 21.298334235458164,\n    high: 21.382618157970235,\n    low: 21.02862922330888,\n    close: 21.155053,\n    volume: 66150900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-10-20',\n    open: 21.289906302248372,\n    high: 21.407902615879202,\n    low: 21.155053372384568,\n    close: 21.332047,\n    volume: 56283600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-10-21',\n    open: 21.407901384736427,\n    high: 21.525898534412196,\n    low: 21.112909774793152,\n    close: 21.424758,\n    volume: 50032400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-10-22',\n    open: 21.509041150080424,\n    high: 21.52589860823257,\n    low: 21.298333458563178,\n    close: 21.391044,\n    volume: 25837900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-10-25',\n    open: 21.27304869579005,\n    high: 21.365760080755855,\n    low: 21.2140505417209,\n    close: 21.230908,\n    volume: 50912400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-10-26',\n    open: 21.171909840514168,\n    high: 21.888314311223283,\n    low: 21.12133830852058,\n    close: 21.829317,\n    volume: 69304200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-10-27',\n    open: 21.736606682623712,\n    high: 22.00631253251645,\n    low: 21.593325449868193,\n    close: 21.955741,\n    volume: 64805500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-10-28',\n    open: 22.090593161712853,\n    high: 22.233874389517986,\n    low: 21.846173086523095,\n    close: 22.149593,\n    volume: 80730300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-10-29',\n    open: 22.88285577615298,\n    high: 22.924998158166364,\n    low: 22.318159151106112,\n    close: 22.478297,\n    volume: 114193200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-11-01',\n    open: 22.65529016068348,\n    high: 22.941852621293407,\n    low: 22.50358230837505,\n    close: 22.71429,\n    volume: 61912100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-11-02',\n    open: 22.8069998452671,\n    high: 23.11041976598831,\n    low: 22.77328745722116,\n    close: 23.085134,\n    volume: 54402100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-11-03',\n    open: 23.144131536594614,\n    high: 23.16941730190835,\n    low: 22.722716161878203,\n    close: 22.781716,\n    volume: 110255300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-11-04',\n    open: 23.101992158142675,\n    high: 23.118848774091703,\n    low: 22.76485983916212,\n    close: 22.874427,\n    volume: 93599300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-11-05',\n    open: 22.899712856238363,\n    high: 22.91657031508406,\n    low: 22.360301986592436,\n    close: 22.630007,\n    volume: 110953700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-11-08',\n    open: 22.486725838370972,\n    high: 24.33252614094812,\n    low: 22.40244275801726,\n    close: 22.596293,\n    volume: 71670800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-11-09',\n    open: 22.596292007028495,\n    high: 22.849142922639963,\n    low: 22.512008930378517,\n    close: 22.71429,\n    volume: 58538600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-11-10',\n    open: 22.764859311623635,\n    high: 22.823857466078042,\n    low: 22.596292313208824,\n    close: 22.705862,\n    volume: 52277300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-11-11',\n    open: 22.486725,\n    high: 22.52043738805379,\n    low: 22.149593533985197,\n    close: 22.486725,\n    volume: 62073100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-11-12',\n    open: 22.309730316286068,\n    high: 22.35187269889608,\n    low: 21.997883764750668,\n    close: 22.141165,\n    volume: 64962200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-11-15',\n    open: 22.191734157185717,\n    high: 22.33501538797651,\n    low: 22.0568812340885,\n    close: 22.082167,\n    volume: 51794600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-11-16',\n    open: 22.082167877926842,\n    high: 22.082167877926842,\n    low: 21.75144333016053,\n    close: 21.887124,\n    volume: 65339200,\n    split: '',\n    dividend: '$0.160',\n  },\n  {\n    date: '2010-11-17',\n    open: 21.96344512319124,\n    high: 21.971925217833398,\n    low: 21.666640962706218,\n    close: 21.683602,\n    volume: 58299700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-11-18',\n    open: 21.80232291940538,\n    high: 22.116087275541794,\n    low: 21.71752366728193,\n    close: 21.912565,\n    volume: 59514000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-11-19',\n    open: 21.878643345114547,\n    high: 21.904084477069503,\n    low: 21.70904230015406,\n    close: 21.785364,\n    volume: 52423200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-11-22',\n    open: 21.751442244461717,\n    high: 21.827763094442282,\n    low: 21.57336110918317,\n    close: 21.819283,\n    volume: 53350500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-11-23',\n    open: 21.68360241824831,\n    high: 21.7090427026655,\n    low: 21.27655786757333,\n    close: 21.301999,\n    volume: 69742500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-11-24',\n    open: 21.36983939078288,\n    high: 21.590320155919546,\n    low: 21.33591816413409,\n    close: 21.514001,\n    volume: 56825900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-11-26',\n    open: 21.378317773376672,\n    high: 21.547920514455445,\n    low: 21.34439824277228,\n    close: 21.412239,\n    volume: 21356500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-11-29',\n    open: 21.361359558849408,\n    high: 21.55640089041489,\n    low: 21.14087624697259,\n    close: 21.463119,\n    volume: 56603600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-11-30',\n    open: 21.24263616505467,\n    high: 21.598800138926403,\n    low: 21.200236539984164,\n    close: 21.420719,\n    volume: 75282100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-12-01',\n    open: 21.68360170915508,\n    high: 22.260248137087245,\n    low: 21.675120766617212,\n    close: 22.082167,\n    volume: 74123500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-12-02',\n    open: 22.251768687681988,\n    high: 22.8792957009779,\n    low: 22.21784915659439,\n    close: 22.802974,\n    volume: 91759200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-12-03',\n    open: 22.73513316235322,\n    high: 22.94713553096906,\n    low: 22.709694574138265,\n    close: 22.913216,\n    volume: 52622000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-12-06',\n    open: 22.836894851713858,\n    high: 22.879295324888226,\n    low: 22.692733242921015,\n    close: 22.760574,\n    volume: 36264200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-12-07',\n    open: 22.964096138291918,\n    high: 23.006495763211362,\n    low: 22.769053962818983,\n    close: 22.786015,\n    volume: 57860500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-12-08',\n    open: 22.752093224752112,\n    high: 23.0997770943812,\n    low: 22.726652093599082,\n    close: 23.091297,\n    volume: 41666800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-12-09',\n    open: 23.133698738703696,\n    high: 23.184578457902514,\n    low: 22.904735338257023,\n    close: 22.964096,\n    volume: 47148300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-12-10',\n    open: 23.05737842701459,\n    high: 23.23545956839795,\n    low: 22.989537669150657,\n    close: 23.184579,\n    volume: 37625800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-12-13',\n    open: 23.1252181893578,\n    high: 23.27786074158745,\n    low: 23.04041724256881,\n    close: 23.108258,\n    volume: 47943900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-12-14',\n    open: 23.159137372876202,\n    high: 23.532262381163566,\n    low: 23.116737748126805,\n    close: 23.422022,\n    volume: 64070500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-12-15',\n    open: 23.345701814616298,\n    high: 23.73578532710951,\n    low: 23.345701814616298,\n    close: 23.617064,\n    volume: 69634200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-12-16',\n    open: 23.540742822436588,\n    high: 23.735785,\n    low: 23.455941875669883,\n    close: 23.735785,\n    volume: 57680200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-12-17',\n    open: 23.676424189247314,\n    high: 23.82058579784946,\n    low: 23.53226258064516,\n    close: 23.659464,\n    volume: 87456500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-12-20',\n    open: 23.701866024272167,\n    high: 23.73578555576359,\n    low: 23.47290261463152,\n    close: 23.583143,\n    volume: 52811000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-12-21',\n    open: 23.61706292304952,\n    high: 23.86298481283844,\n    low: 23.54074207338796,\n    close: 23.803625,\n    volume: 38153000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-12-22',\n    open: 23.75274445254543,\n    high: 24.083468134676547,\n    low: 23.72730416930457,\n    close: 23.905387,\n    volume: 42252300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-12-23',\n    open: 23.71882387668399,\n    high: 24.015628037301347,\n    low: 23.710343782038052,\n    close: 23.998667,\n    volume: 24902500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-12-27',\n    open: 23.84602632004364,\n    high: 23.913867075298363,\n    low: 23.6425023582606,\n    close: 23.803625,\n    volume: 21652800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-12-28',\n    open: 23.718823773554266,\n    high: 23.88842651374509,\n    low: 23.710343678945197,\n    close: 23.752745,\n    volume: 23042200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-12-29',\n    open: 23.693385411948853,\n    high: 23.846027116369363,\n    low: 23.642503147789746,\n    close: 23.718824,\n    volume: 19502500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-12-30',\n    open: 23.676424663554755,\n    high: 23.744265421903048,\n    low: 23.557704184454717,\n    close: 23.617064,\n    volume: 20786100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2010-12-31',\n    open: 23.574662111503258,\n    high: 23.676424094589752,\n    low: 23.43050050347746,\n    close: 23.667944,\n    volume: 24752000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-01-03',\n    open: 23.78666481496408,\n    high: 23.89690689421015,\n    low: 23.676424431736955,\n    close: 23.727305,\n    volume: 53443800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-01-04',\n    open: 23.69338542757515,\n    high: 23.88842675756497,\n    low: 23.61706372730509,\n    close: 23.820586,\n    volume: 54405600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-01-05',\n    open: 23.659464053571426,\n    high: 23.752745094642858,\n    low: 23.549222823214283,\n    close: 23.744265,\n    volume: 58998700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-01-06',\n    open: 23.778186459390458,\n    high: 24.465073284177656,\n    low: 23.625544754324533,\n    close: 24.439633,\n    volume: 88026300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-01-07',\n    open: 24.2869905310115,\n    high: 24.371792326573424,\n    low: 23.95626768356643,\n    close: 24.253071,\n    volume: 73762000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-01-10',\n    open: 23.964748227666487,\n    high: 24.083469556465964,\n    low: 23.778186987562506,\n    close: 23.930827,\n    volume: 57573600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-01-11',\n    open: 23.913867852140847,\n    high: 23.95626747754296,\n    low: 23.786664735887168,\n    close: 23.837547,\n    volume: 50298900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-01-12',\n    open: 23.84602761669694,\n    high: 24.244591227481305,\n    low: 23.803626294347684,\n    close: 24.21067,\n    volume: 52631100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-01-13',\n    open: 24.024107473781218,\n    high: 24.074987192253488,\n    low: 23.75274445254543,\n    close: 23.905387,\n    volume: 67077600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-01-14',\n    open: 23.81210576579879,\n    high: 24.06650775716752,\n    low: 23.667944156817818,\n    close: 23.998667,\n    volume: 62688400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-01-18',\n    open: 23.879946272156317,\n    high: 24.37179175645499,\n    low: 23.86298523503311,\n    close: 24.303951,\n    volume: 53322700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-01-19',\n    open: 24.13434890521671,\n    high: 24.32091183845844,\n    low: 23.973227952343795,\n    close: 24.142829,\n    volume: 50005900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-01-20',\n    open: 24.168270423280422,\n    high: 24.210670049697743,\n    low: 23.85450606451256,\n    close: 24.041069,\n    volume: 58613600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-01-21',\n    open: 24.083469607423268,\n    high: 24.10890989221984,\n    low: 23.761226,\n    close: 23.761226,\n    volume: 58080300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-01-24',\n    open: 23.76122543767531,\n    high: 24.219149705167077,\n    low: 23.735785153480798,\n    close: 24.066508,\n    volume: 52047800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-01-25',\n    open: 23.862985371217736,\n    high: 24.12587,\n    low: 23.846026878026116,\n    close: 24.12587,\n    volume: 42436600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-01-26',\n    open: 24.17674959879258,\n    high: 24.583794137811182,\n    low: 24.16826950422969,\n    close: 24.405713,\n    volume: 74628800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-01-27',\n    open: 24.380272016616836,\n    high: 24.98235788623513,\n    low: 24.159789556640472,\n    close: 24.482034,\n    volume: 146938600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-01-28',\n    open: 24.507473899099097,\n    high: 24.532914183423422,\n    low: 23.277861004766233,\n    close: 23.532263,\n    volume: 141249400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-01-31',\n    open: 23.54922237793004,\n    high: 23.659463606202667,\n    low: 23.252419071042194,\n    close: 23.515302,\n    volume: 65029000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-02-01',\n    open: 23.5746623531338,\n    high: 23.795144814727227,\n    low: 23.413542250296,\n    close: 23.735785,\n    volume: 62810700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-02-02',\n    open: 23.68490405744796,\n    high: 23.837546607223995,\n    low: 23.642502736725568,\n    close: 23.693385,\n    volume: 45824000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-02-03',\n    open: 23.71882317260539,\n    high: 23.71882317260539,\n    low: 23.354180809673093,\n    close: 23.447461,\n    volume: 60340100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-02-04',\n    open: 23.489863185063847,\n    high: 23.608583662945627,\n    low: 23.32874053763054,\n    close: 23.549223,\n    volume: 40412200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-02-07',\n    open: 23.574662514591115,\n    high: 24.032588478277003,\n    low: 23.566184115875316,\n    close: 23.913868,\n    volume: 68980900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-02-08',\n    open: 23.829065451588917,\n    high: 24.0325877187911,\n    low: 23.786664131245683,\n    close: 23.981708,\n    volume: 34904200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-02-09',\n    open: 23.90538777919956,\n    high: 23.964747594020295,\n    low: 23.6679442798693,\n    close: 23.718824,\n    volume: 52905100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-02-10',\n    open: 23.684904065454546,\n    high: 23.693385008009457,\n    low: 23.14217886255491,\n    close: 23.32026,\n    volume: 76672400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-02-11',\n    open: 23.540742828623856,\n    high: 23.583142454008883,\n    low: 22.955616295779816,\n    close: 23.108258,\n    volume: 83939700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-02-14',\n    open: 23.07433596322817,\n    high: 23.12521737752479,\n    low: 22.85385520533592,\n    close: 23.091297,\n    volume: 56766200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-02-15',\n    open: 23.065708444479725,\n    high: 23.31308389328946,\n    low: 22.988936488738926,\n    close: 22.997465,\n    volume: 44116500,\n    split: '',\n    dividend: '$0.160',\n  },\n  {\n    date: '2011-02-16',\n    open: 23.07423779982798,\n    high: 23.091299088082902,\n    low: 22.69037886010363,\n    close: 23.048648,\n    volume: 70817900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-02-17',\n    open: 23.00599577968669,\n    high: 23.347206186252375,\n    low: 22.95481532763011,\n    close: 23.210721,\n    volume: 57207300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-02-18',\n    open: 23.14247952327094,\n    high: 23.210721264152006,\n    low: 23.023057329750827,\n    close: 23.082768,\n    volume: 68667800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-02-22',\n    open: 22.84392298314584,\n    high: 23.116889086122605,\n    low: 22.622136478375328,\n    close: 22.681848,\n    volume: 60889000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-02-23',\n    open: 22.630667548772017,\n    high: 22.91216472214547,\n    low: 22.545364522000753,\n    close: 22.681848,\n    volume: 60234100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-02-24',\n    open: 22.724498320680166,\n    high: 23.08276745179709,\n    low: 22.605076129996267,\n    close: 22.835392,\n    volume: 64494200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-02-25',\n    open: 22.954815688316973,\n    high: 22.988937411927097,\n    low: 22.605076764786318,\n    close: 22.647727,\n    volume: 53006300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-02-28',\n    open: 22.767151245045824,\n    high: 22.91216494181031,\n    low: 22.61360647780286,\n    close: 22.673318,\n    volume: 51379900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-03-01',\n    open: 22.69037857033639,\n    high: 22.843923338495753,\n    low: 22.30651878249235,\n    close: 22.315049,\n    volume: 60055000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-03-02',\n    open: 22.272398505245672,\n    high: 22.49418415785303,\n    low: 22.21268698338984,\n    close: 22.246807,\n    volume: 48658200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-03-03',\n    open: 22.400350450368304,\n    high: 22.519773491611698,\n    low: 22.332108712514934,\n    close: 22.34917,\n    volume: 68271500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-03-04',\n    open: 22.366229163693866,\n    high: 22.383290451510963,\n    low: 22.007960032991328,\n    close: 22.135915,\n    volume: 70437200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-03-07',\n    open: 22.289457924562168,\n    high: 22.408881824995404,\n    low: 21.794705299571785,\n    close: 21.939719,\n    volume: 64980400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-03-08',\n    open: 21.9823699579313,\n    high: 22.195625390196838,\n    low: 21.880007350443844,\n    close: 22.101793,\n    volume: 50549800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-03-09',\n    open: 22.016490260786338,\n    high: 22.161504809637112,\n    low: 21.88853785278246,\n    close: 22.084732,\n    volume: 39789100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-03-10',\n    open: 21.854417415005194,\n    high: 21.93118766409752,\n    low: 21.624100696576154,\n    close: 21.675282,\n    volume: 66549500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-03-11',\n    open: 21.67528312266355,\n    high: 22.05061270054517,\n    low: 21.63263288728968,\n    close: 21.905599,\n    volume: 49905800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-03-14',\n    open: 21.743523801731264,\n    high: 21.97383966781473,\n    low: 21.62410076005836,\n    close: 21.914129,\n    volume: 54473400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-03-15',\n    open: 21.393785115154987,\n    high: 21.726462738804326,\n    low: 21.325543376350666,\n    close: 21.658221,\n    volume: 76067300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-03-16',\n    open: 21.513207645840353,\n    high: 21.564390656797872,\n    low: 21.05257675463587,\n    close: 21.14641,\n    volume: 100725400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-03-17',\n    open: 21.376723374713386,\n    high: 21.51320684943157,\n    low: 21.112287495468628,\n    close: 21.137879,\n    volume: 62497000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-03-18',\n    open: 21.37672465974942,\n    high: 21.47908812496323,\n    low: 21.154939,\n    close: 21.154939,\n    volume: 85486700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-03-21',\n    open: 21.479087737070667,\n    high: 21.820296438215554,\n    low: 21.4534970844848,\n    close: 21.607041,\n    volume: 46878100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-03-22',\n    open: 21.581449,\n    high: 21.717932477331363,\n    low: 21.521738331689264,\n    close: 21.581449,\n    volume: 30895600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-03-23',\n    open: 21.521738408702493,\n    high: 21.845887521546146,\n    low: 21.479087321883817,\n    close: 21.786176,\n    volume: 43969000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-03-24',\n    open: 21.83735728157138,\n    high: 22.06767401217222,\n    low: 21.75205510469024,\n    close: 22.016491,\n    volume: 38696700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-03-25',\n    open: 22.118853888413195,\n    high: 22.13591517636623,\n    low: 21.82882649458132,\n    close: 21.854418,\n    volume: 57029800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-03-28',\n    open: 21.888537430932704,\n    high: 21.93971788133483,\n    low: 21.649690495266352,\n    close: 21.675282,\n    volume: 48973200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-03-29',\n    open: 21.615570739898004,\n    high: 21.769114652020402,\n    low: 21.581449017515734,\n    close: 21.743524,\n    volume: 40763500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-03-30',\n    open: 21.8373559298182,\n    high: 21.939717682717507,\n    low: 21.752053758217347,\n    close: 21.845887,\n    volume: 41999300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-03-31',\n    open: 21.837356417383084,\n    high: 21.905598156187406,\n    low: 21.615570766269038,\n    close: 21.658221,\n    volume: 63233700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-04-01',\n    open: 21.7776459401489,\n    high: 21.7776459401489,\n    low: 21.58997945074592,\n    close: 21.734994,\n    volume: 63114200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-04-04',\n    open: 21.709404530493526,\n    high: 21.888538246126743,\n    low: 21.675282807251772,\n    close: 21.794705,\n    volume: 35433700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-04-05',\n    open: 22.025021016096936,\n    high: 22.332108838164903,\n    low: 21.95677927785961,\n    close: 21.990901,\n    volume: 73651100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-04-06',\n    open: 22.16150430745698,\n    high: 22.44300062231289,\n    low: 22.059142553977747,\n    close: 22.306518,\n    volume: 65581400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-04-07',\n    open: 22.340639782768328,\n    high: 22.400350450368304,\n    low: 22.15297329762812,\n    close: 22.34917,\n    volume: 46134700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-04-08',\n    open: 22.323579174913693,\n    high: 22.417412420340504,\n    low: 22.144443754573185,\n    close: 22.238277,\n    volume: 39887600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-04-11',\n    open: 22.340639411913163,\n    high: 22.39181986143187,\n    low: 22.007959239357042,\n    close: 22.161504,\n    volume: 34286300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-04-12',\n    open: 22.033551986878,\n    high: 22.050612422020766,\n    low: 21.794705041857565,\n    close: 21.871477,\n    volume: 36920400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-04-13',\n    open: 21.880008288334302,\n    high: 22.067673929794022,\n    low: 21.8032354764061,\n    close: 21.862947,\n    volume: 38144700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-04-14',\n    open: 21.683813,\n    high: 21.700874288112235,\n    low: 21.402315821007083,\n    close: 21.683813,\n    volume: 55239900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-04-15',\n    open: 21.71793224914883,\n    high: 21.803234421584694,\n    low: 21.479087019350143,\n    close: 21.641162,\n    volume: 65080400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-04-18',\n    open: 21.410845434609254,\n    high: 21.564390199114236,\n    low: 21.086696324011765,\n    close: 21.393785,\n    volume: 58045100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-04-19',\n    open: 21.32554274353877,\n    high: 21.470556434194833,\n    low: 21.214650774294075,\n    close: 21.453496,\n    volume: 38892400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-04-20',\n    open: 21.786176070413042,\n    high: 22.178565217391302,\n    low: 21.76058456521739,\n    close: 21.97384,\n    volume: 61608600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-04-21',\n    open: 21.99943172488695,\n    high: 22.084732193608346,\n    low: 21.632632373397925,\n    close: 21.769115,\n    volume: 46892300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-04-25',\n    open: 21.803234208156145,\n    high: 21.854417217160083,\n    low: 21.615570283655984,\n    close: 21.845887,\n    volume: 33525100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-04-26',\n    open: 21.956779367820566,\n    high: 22.553895432865392,\n    low: 21.89706784661826,\n    close: 22.34064,\n    volume: 69200000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-04-27',\n    open: 22.434471259733062,\n    high: 22.511243217533366,\n    low: 22.289457561665827,\n    close: 22.502713,\n    volume: 52689000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-04-28',\n    open: 22.570954563337498,\n    high: 22.920695185507494,\n    low: 22.519774111560245,\n    close: 22.78421,\n    volume: 80200000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-04-29',\n    open: 22.64772685531157,\n    high: 22.724498813644903,\n    low: 21.63263266783657,\n    close: 22.110324,\n    volume: 319317900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-05-02',\n    open: 22.12738494187599,\n    high: 22.17856539360873,\n    low: 21.734994085736556,\n    close: 21.888538,\n    volume: 89825600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-05-03',\n    open: 21.83735728157138,\n    high: 22.050612723774226,\n    low: 21.743524887002124,\n    close: 22.016491,\n    volume: 71892900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-05-04',\n    open: 22.050612285134775,\n    high: 22.39182098587187,\n    low: 21.99943183304596,\n    close: 22.229746,\n    volume: 73292300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-05-05',\n    open: 22.22121494103738,\n    high: 22.246806445645348,\n    low: 21.905597757828705,\n    close: 21.999431,\n    volume: 55600000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-05-06',\n    open: 22.23827649291548,\n    high: 22.366228899346662,\n    low: 21.965309539415944,\n    close: 22.067673,\n    volume: 55993000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-05-09',\n    open: 22.00796049424886,\n    high: 22.144443975472242,\n    low: 21.89706851877662,\n    close: 22.033552,\n    volume: 38696400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-05-10',\n    open: 21.649690843121622,\n    high: 22.050611912738606,\n    low: 21.538798870276587,\n    close: 21.897068,\n    volume: 120798700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-05-11',\n    open: 21.88000744952652,\n    high: 21.888537666855772,\n    low: 21.504677034017785,\n    close: 21.632632,\n    volume: 78600000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-05-12',\n    open: 21.624100651658768,\n    high: 21.658220667515405,\n    low: 21.410845221169037,\n    close: 21.59851,\n    volume: 77400000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-05-13',\n    open: 21.564390434947843,\n    high: 21.59851045151776,\n    low: 21.28289326081669,\n    close: 21.351135,\n    volume: 66812300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-05-16',\n    open: 21.29142162316874,\n    high: 21.385254866910866,\n    low: 20.899032478632478,\n    close: 20.958744,\n    volume: 91350900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-05-17',\n    open: 20.950158433931485,\n    high: 21.207743207715826,\n    low: 20.838538737357258,\n    close: 21.053192,\n    volume: 82882100,\n    split: '',\n    dividend: '$0.160',\n  },\n  {\n    date: '2011-05-18',\n    open: 21.061777918889348,\n    high: 21.24208579173407,\n    low: 20.821365418332707,\n    close: 21.199156,\n    volume: 53931100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-05-19',\n    open: 21.336533551235178,\n    high: 21.36229108322727,\n    low: 21.036018994175524,\n    close: 21.224913,\n    volume: 37783600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-05-20',\n    open: 21.224913137303677,\n    high: 21.35370680838844,\n    low: 20.984503207326785,\n    close: 21.027433,\n    volume: 45451500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-05-23',\n    open: 20.78702066269437,\n    high: 20.82136604261481,\n    low: 20.632472034037107,\n    close: 20.752677,\n    volume: 52692500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-05-24',\n    open: 20.778435508716523,\n    high: 20.855710678902856,\n    low: 20.64105742838526,\n    close: 20.735504,\n    volume: 47691800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-05-25',\n    open: 20.75267588165871,\n    high: 20.87288084114387,\n    low: 20.744089751794554,\n    close: 20.769849,\n    volume: 34904200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-05-26',\n    open: 20.907226836238344,\n    high: 21.49108454284487,\n    low: 20.88146844588569,\n    close: 21.181983,\n    volume: 78016600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-05-27',\n    open: 21.190568959612275,\n    high: 21.37946382067851,\n    low: 21.16481056946688,\n    close: 21.259258,\n    volume: 50251000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-05-31',\n    open: 21.430980489647656,\n    high: 21.516841793126268,\n    low: 21.207742817829345,\n    close: 21.473912,\n    volume: 60196300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-06-01',\n    open: 21.456739289398282,\n    high: 21.551186721244374,\n    low: 20.92440007760606,\n    close: 20.975916,\n    volume: 74033500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-06-02',\n    open: 21.02743337974539,\n    high: 21.16481146634234,\n    low: 20.761263336963804,\n    close: 20.795607,\n    volume: 51487800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-06-03',\n    open: 20.649641962382393,\n    high: 20.726917133022294,\n    low: 20.4693340895023,\n    close: 20.529437,\n    volume: 60697700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-06-06',\n    open: 20.512264577038774,\n    high: 20.821366128696376,\n    low: 20.40923187130362,\n    close: 20.615299,\n    volume: 54778700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-06-07',\n    open: 20.683988249957945,\n    high: 20.75267729354436,\n    low: 20.52085177144022,\n    close: 20.658229,\n    volume: 41112600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-06-08',\n    open: 20.520850621518353,\n    high: 20.623884181124303,\n    low: 20.4865069602627,\n    close: 20.555196,\n    volume: 42205000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-06-09',\n    open: 20.61529850940311,\n    high: 20.64105775849018,\n    low: 20.452162036400754,\n    close: 20.572367,\n    volume: 42878700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-06-10',\n    open: 20.623884896831925,\n    high: 20.623884896831925,\n    low: 20.3405434566958,\n    close: 20.357714,\n    volume: 49327200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-06-13',\n    open: 20.42640474353799,\n    high: 20.769849953877205,\n    low: 20.349129571211666,\n    close: 20.641058,\n    volume: 47572500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-06-14',\n    open: 20.864296043298474,\n    high: 20.993089716709196,\n    low: 20.769850325989154,\n    close: 20.795607,\n    volume: 42894500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-06-15',\n    open: 20.606712384161753,\n    high: 20.61529851432182,\n    low: 20.32337008887953,\n    close: 20.383473,\n    volume: 49410200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-06-16',\n    open: 20.39205875,\n    high: 20.692573300000003,\n    low: 20.30619745,\n    close: 20.606712,\n    volume: 57184100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-06-17',\n    open: 20.795606620364715,\n    high: 20.86429566240923,\n    low: 20.589540352844185,\n    close: 20.829952,\n    volume: 83320400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-06-20',\n    open: 20.7526769494351,\n    high: 21.173397334425715,\n    low: 20.744090819129166,\n    close: 21.01026,\n    volume: 54338400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-06-21',\n    open: 21.05319087883683,\n    high: 21.345120159097657,\n    low: 20.950157318255247,\n    close: 21.259258,\n    volume: 49708700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-06-22',\n    open: 21.12187935091278,\n    high: 21.302187218466127,\n    low: 21.113293221095336,\n    close: 21.16481,\n    volume: 44287300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-06-23',\n    open: 20.984503242068257,\n    high: 21.16481111915595,\n    low: 20.77843611555315,\n    close: 21.147638,\n    volume: 59470400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-06-24',\n    open: 21.04460559689735,\n    high: 21.070364846693863,\n    low: 20.769850282886676,\n    close: 20.864296,\n    volume: 101387200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-06-27',\n    open: 20.80419351054788,\n    high: 21.860286668359695,\n    low: 20.80419351054788,\n    close: 21.637049,\n    volume: 92044200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-06-28',\n    open: 21.722908491112154,\n    high: 22.255249420746104,\n    low: 21.60270352723657,\n    close: 22.152215,\n    volume: 81032100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-06-29',\n    open: 22.074939453059894,\n    high: 22.074939453059894,\n    low: 21.774426619174058,\n    close: 21.997666,\n    volume: 66051000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-06-30',\n    open: 22.10069862,\n    high: 22.323938,\n    low: 22.03200958,\n    close: 22.323938,\n    volume: 52535400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-07-01',\n    open: 22.263835827440435,\n    high: 22.469902954265955,\n    low: 22.186560654880864,\n    close: 22.341111,\n    volume: 52906200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-07-05',\n    open: 22.40979905071844,\n    high: 22.452729700240887,\n    low: 22.23807645262864,\n    close: 22.349697,\n    volume: 37805300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-07-06',\n    open: 22.298179451679417,\n    high: 22.641626379691644,\n    low: 22.28959332140976,\n    close: 22.607281,\n    volume: 48744200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-07-07',\n    open: 22.744659349645126,\n    high: 23.079517575454954,\n    low: 22.633040513450545,\n    close: 22.985071,\n    volume: 51946500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-07-08',\n    open: 22.787589918048365,\n    high: 23.165378780089153,\n    low: 22.761830669390786,\n    close: 23.113862,\n    volume: 58320700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-07-11',\n    open: 22.856279586974974,\n    high: 23.010828214268276,\n    low: 22.74465903509797,\n    close: 22.864864,\n    volume: 43999800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-07-12',\n    open: 22.79617441281973,\n    high: 23.002243251143437,\n    low: 22.61586654047225,\n    close: 22.78759,\n    volume: 47319300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-07-13',\n    open: 22.8391064678598,\n    high: 23.148206298285476,\n    low: 22.761831295600125,\n    close: 22.864864,\n    volume: 40861800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-07-14',\n    open: 22.85627967146829,\n    high: 23.191137893885074,\n    low: 22.633040284115083,\n    close: 22.727486,\n    volume: 46382300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-07-15',\n    open: 22.727485252757948,\n    high: 23.12244809139477,\n    low: 22.727485252757948,\n    close: 22.993657,\n    volume: 49132400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-07-18',\n    open: 22.864863661883415,\n    high: 23.09669003384731,\n    low: 22.547177705904474,\n    close: 22.83052,\n    volume: 44501900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-07-19',\n    open: 23.0194137895564,\n    high: 23.732062583214756,\n    low: 22.993657116650176,\n    close: 23.646203,\n    volume: 86730600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-07-20',\n    open: 23.42296458599529,\n    high: 23.483066640172456,\n    low: 23.165379815424235,\n    close: 23.234068,\n    volume: 49795400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-07-21',\n    open: 23.21689707706321,\n    high: 23.44872087681133,\n    low: 22.88203713837638,\n    close: 23.268413,\n    volume: 81737400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-07-22',\n    open: 23.062346283881972,\n    high: 23.65478754295661,\n    low: 22.907795083625313,\n    close: 23.637617,\n    volume: 76380600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-07-25',\n    open: 23.405790546040848,\n    high: 24.118439341096384,\n    low: 23.34568849422748,\n    close: 23.963889,\n    volume: 108482400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-07-26',\n    open: 23.886613620370373,\n    high: 24.169955909900285,\n    low: 23.85226995904035,\n    close: 24.109853,\n    volume: 74636500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-07-27',\n    open: 23.9381303056753,\n    high: 24.032578597145992,\n    low: 23.354275165235784,\n    close: 23.465894,\n    volume: 71488700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-07-28',\n    open: 23.43155011949142,\n    high: 24.101267414908637,\n    low: 23.362859360826384,\n    close: 23.800752,\n    volume: 83761400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-07-29',\n    open: 23.62902955912409,\n    high: 23.792165169124235,\n    low: 23.4057901810219,\n    close: 23.525996,\n    volume: 104394800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-08-01',\n    open: 23.620444124312435,\n    high: 23.77499532615977,\n    low: 22.9678982306564,\n    close: 23.414377,\n    volume: 61838400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-08-02',\n    open: 23.165379201693252,\n    high: 23.56892817834911,\n    low: 22.97648433792852,\n    close: 23.010828,\n    volume: 63883100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-08-03',\n    open: 23.036586829866266,\n    high: 23.18255104011887,\n    low: 22.73607227934621,\n    close: 23.113862,\n    volume: 64581200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-08-04',\n    open: 22.779003668211963,\n    high: 23.070932087181568,\n    low: 22.26383501141731,\n    close: 22.272422,\n    volume: 92949500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-08-05',\n    open: 22.298178913193848,\n    high: 22.40979946261682,\n    low: 21.66280614719626,\n    close: 22.049182,\n    volume: 112071700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-08-08',\n    open: 21.48249701470588,\n    high: 21.98049254901961,\n    low: 20.941569972269363,\n    close: 21.018846,\n    volume: 134257200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-08-09',\n    open: 21.216326815741947,\n    high: 21.99766637933233,\n    low: 20.63247168073968,\n    close: 21.963321,\n    volume: 126268900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-08-10',\n    open: 21.42239576677852,\n    high: 21.54260073129749,\n    low: 20.692573839149844,\n    close: 20.778436,\n    volume: 127819900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-08-11',\n    open: 21.03601818038832,\n    high: 21.791596750295408,\n    low: 20.95015688169286,\n    close: 21.628462,\n    volume: 90690100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-08-12',\n    open: 21.576944532223624,\n    high: 21.757254126693223,\n    low: 21.164811137450194,\n    close: 21.551187,\n    volume: 64787100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-08-15',\n    open: 21.671392486083885,\n    high: 21.963320911015284,\n    low: 21.594117314778515,\n    close: 21.903218,\n    volume: 56529400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-08-16',\n    open: 21.790892941095933,\n    high: 22.110585744378696,\n    low: 21.644007455494354,\n    close: 21.903218,\n    volume: 54251500,\n    split: '',\n    dividend: '$0.160',\n  },\n  {\n    date: '2011-08-17',\n    open: 21.816815,\n    high: 22.20563038878475,\n    low: 21.540324671287127,\n    close: 21.816815,\n    volume: 50923700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-08-18',\n    open: 21.229272773408997,\n    high: 21.678569551682205,\n    low: 20.762696213849857,\n    close: 21.315676,\n    volume: 105714200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-08-19',\n    open: 21.0910274777974,\n    high: 21.272475116525992,\n    low: 20.65901134756804,\n    close: 20.779975,\n    volume: 77397900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-08-22',\n    open: 21.09966718348624,\n    high: 21.160149439949958,\n    low: 20.555327739344996,\n    close: 20.719493,\n    volume: 54721000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-08-23',\n    open: 20.76269645758792,\n    high: 21.384798832313866,\n    low: 20.76269645758792,\n    close: 21.358877,\n    volume: 59670600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-08-24',\n    open: 21.298394937751006,\n    high: 21.540323967469885,\n    low: 21.099667520481933,\n    close: 21.514403,\n    volume: 45329700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-08-25',\n    open: 21.66992946031746,\n    high: 21.73905204232804,\n    low: 21.16879074074074,\n    close: 21.229273,\n    volume: 48192000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-08-26',\n    open: 21.177431114851483,\n    high: 21.89457790495049,\n    low: 21.09966820990099,\n    close: 21.816815,\n    volume: 71957000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-08-29',\n    open: 22.058744858614318,\n    high: 22.34387550954311,\n    low: 21.920499694527628,\n    close: 22.326594,\n    volume: 38863200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-08-30',\n    open: 22.231549873427372,\n    high: 22.83637245062905,\n    low: 22.20562976986527,\n    close: 22.663566,\n    volume: 57341400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-08-31',\n    open: 22.715409853130037,\n    high: 23.078301688223345,\n    low: 22.689488020300754,\n    close: 22.983259,\n    volume: 59300800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-09-01',\n    open: 22.86229306814224,\n    high: 23.207907705234366,\n    low: 22.646285,\n    close: 22.646285,\n    volume: 60510800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-09-02',\n    open: 22.274753082433527,\n    high: 22.46483932034261,\n    low: 22.17106834461505,\n    close: 22.292032,\n    volume: 43894400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-09-06',\n    open: 21.77361386285625,\n    high: 22.110585580948644,\n    low: 21.69585095928902,\n    close: 22.041463,\n    volume: 54929300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-09-07',\n    open: 22.19698986057073,\n    high: 22.464839,\n    low: 22.09330512423077,\n    close: 22.464839,\n    volume: 41961000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-09-08',\n    open: 22.464838766774932,\n    high: 23.035100058546913,\n    low: 22.421638017794166,\n    close: 22.654925,\n    volume: 65811900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-09-09',\n    open: 22.464838383838384,\n    high: 22.620364188034188,\n    low: 22.032822261072262,\n    close: 22.24019,\n    volume: 64529200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-09-12',\n    open: 21.98098219972102,\n    high: 22.4043571554406,\n    low: 21.834095847203393,\n    close: 22.369795,\n    volume: 55046100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-09-13',\n    open: 22.395716264373416,\n    high: 22.629005839492898,\n    low: 22.30067185137969,\n    close: 22.499401,\n    volume: 48792300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-09-14',\n    open: 22.61172435283019,\n    high: 23.156063815213017,\n    low: 22.36979445483566,\n    close: 22.896855,\n    volume: 66739200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-09-15',\n    open: 23.095582609484996,\n    high: 23.354793154880735,\n    low: 22.732688191543872,\n    close: 23.320231,\n    volume: 67808300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-09-16',\n    open: 23.37207201310369,\n    high: 23.56215997632154,\n    low: 23.181985777950377,\n    close: 23.432556,\n    volume: 89681500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-09-19',\n    open: 23.156063772353797,\n    high: 23.596720226255172,\n    low: 22.983258183875716,\n    close: 23.510317,\n    volume: 52324900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-09-20',\n    open: 23.59671977718347,\n    high: 23.760886767976277,\n    low: 23.268388387694586,\n    close: 23.31159,\n    volume: 49211900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-09-21',\n    open: 23.372071313728437,\n    high: 23.380711636160143,\n    low: 22.43891649110435,\n    close: 22.456198,\n    volume: 72750700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-09-22',\n    open: 21.860015746503098,\n    high: 22.162427907519067,\n    low: 21.255194016567998,\n    close: 21.652648,\n    volume: 96278300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-09-23',\n    open: 21.51440369969687,\n    high: 21.730411768970935,\n    low: 21.332957785538934,\n    close: 21.652648,\n    volume: 64768100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-09-26',\n    open: 21.764972940487738,\n    high: 22.050102715011686,\n    low: 21.36751724695294,\n    close: 21.980981,\n    volume: 51057600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-09-27',\n    open: 22.171067677444487,\n    high: 22.395716063887807,\n    low: 21.989621767810984,\n    close: 22.179708,\n    volume: 55620700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-09-28',\n    open: 22.404356288115718,\n    high: 22.784531342922012,\n    low: 22.04146274237686,\n    close: 22.101945,\n    volume: 60736200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-09-29',\n    open: 22.447558236245257,\n    high: 22.611724366533423,\n    low: 21.67856952068489,\n    close: 21.989622,\n    volume: 63407300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-09-30',\n    open: 21.77361474003125,\n    high: 22.03282356499894,\n    low: 21.497122677033335,\n    close: 21.505763,\n    volume: 54060500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-10-03',\n    open: 21.358876399772182,\n    high: 21.894577259903087,\n    low: 21.18607081345003,\n    close: 21.194712,\n    volume: 64592500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-10-04',\n    open: 20.99598356374988,\n    high: 21.93777875001665,\n    low: 20.961423136543015,\n    close: 21.894578,\n    volume: 83485400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-10-05',\n    open: 21.96370068998458,\n    high: 22.603084581038416,\n    low: 21.739052295830525,\n    close: 22.369795,\n    volume: 94061300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-10-06',\n    open: 22.37843580106302,\n    high: 22.810451936218676,\n    low: 22.20563021103303,\n    close: 22.75861,\n    volume: 55111400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-10-07',\n    open: 22.758609904,\n    high: 22.905495389333336,\n    low: 22.637646250698932,\n    close: 22.680847,\n    volume: 52741600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-10-10',\n    open: 22.965977521678635,\n    high: 23.302949239792902,\n    low: 22.870933108835818,\n    close: 23.27703,\n    volume: 41815300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-10-11',\n    open: 23.20790734773596,\n    high: 23.389353258148148,\n    low: 23.086941103375146,\n    close: 23.328871,\n    volume: 38826200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-10-12',\n    open: 23.48439696232926,\n    high: 23.596720292745225,\n    low: 23.24246792813308,\n    close: 23.294309,\n    volume: 52489800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-10-13',\n    open: 23.121503448123622,\n    high: 23.501678509359714,\n    low: 23.00053979486376,\n    close: 23.484397,\n    volume: 43823500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-10-14',\n    open: 23.596720426763476,\n    high: 23.76088742207554,\n    low: 23.346151932526585,\n    close: 23.56216,\n    volume: 50947700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-10-17',\n    open: 23.423915056026313,\n    high: 23.69176418828762,\n    low: 23.19926580800593,\n    close: 23.31159,\n    volume: 39453300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-10-18',\n    open: 23.27703078043763,\n    high: 23.674484770211816,\n    low: 23.156064531649342,\n    close: 23.596721,\n    volume: 52487900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-10-19',\n    open: 23.648564476216713,\n    high: 23.734965976548875,\n    low: 23.337511989956212,\n    close: 23.441195,\n    volume: 42880000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-10-20',\n    open: 23.553519231748552,\n    high: 23.622641812032477,\n    low: 22.81045149369632,\n    close: 23.363433,\n    volume: 76300200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-10-21',\n    open: 23.45847567746686,\n    high: 23.493037831631664,\n    low: 23.156063524774815,\n    close: 23.467116,\n    volume: 76620600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-10-24',\n    open: 23.380712078199704,\n    high: 23.674483910463994,\n    low: 23.363433161074102,\n    close: 23.493038,\n    volume: 56897800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-10-25',\n    open: 23.397994584035605,\n    high: 23.52759942848189,\n    low: 23.08694209333223,\n    close: 23.164705,\n    volume: 53554600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-10-26',\n    open: 23.354793061850998,\n    high: 23.380712301819557,\n    low: 22.55124218879278,\n    close: 22.974618,\n    volume: 63029900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-10-27',\n    open: 23.44119426514206,\n    high: 23.67448383853211,\n    low: 23.02645964587156,\n    close: 23.544879,\n    volume: 74512400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-10-28',\n    open: 23.44983429534507,\n    high: 23.493037635714973,\n    low: 23.14742473727168,\n    close: 23.31159,\n    volume: 57712100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-10-31',\n    open: 23.121504061641158,\n    high: 23.328871811072915,\n    low: 23.000540405171584,\n    close: 23.009179,\n    volume: 46799000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-11-01',\n    open: 22.629005312666333,\n    high: 22.741328640246252,\n    low: 22.343874672420085,\n    close: 22.456198,\n    volume: 61182600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-11-02',\n    open: 22.551242906574394,\n    high: 22.637647000133793,\n    low: 22.205630852498267,\n    close: 22.47348,\n    volume: 53533100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-11-03',\n    open: 22.67220677752707,\n    high: 22.97461807219683,\n    low: 22.447558387200967,\n    close: 22.922777,\n    volume: 65836100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-11-04',\n    open: 22.7931703306344,\n    high: 22.81045184,\n    low: 22.464838933333333,\n    close: 22.680847,\n    volume: 36549200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-11-07',\n    open: 22.646284960082873,\n    high: 23.173345509453192,\n    low: 22.577162378399198,\n    close: 23.156064,\n    volume: 42589700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-11-08',\n    open: 23.337511162002947,\n    high: 23.5016781541648,\n    low: 23.061021704974813,\n    close: 23.467116,\n    volume: 47822500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-11-09',\n    open: 22.974617716235965,\n    high: 23.112862877371647,\n    low: 22.516679755941766,\n    close: 22.637646,\n    volume: 62950900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-11-10',\n    open: 22.870933403816505,\n    high: 22.89685523604052,\n    low: 22.5685238363107,\n    close: 22.706769,\n    volume: 32514400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-11-11',\n    open: 22.965977355629875,\n    high: 23.397993483463395,\n    low: 22.957337033073205,\n    close: 23.251108,\n    volume: 37903000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-11-14',\n    open: 23.225187010407176,\n    high: 23.328871748878925,\n    low: 23.02646044843049,\n    close: 23.121504,\n    volume: 34199200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-11-15',\n    open: 23.12150219602842,\n    high: 23.452308574353026,\n    low: 22.98221690351533,\n    close: 23.2782,\n    volume: 43874200,\n    split: '',\n    dividend: '$0.200',\n  },\n  {\n    date: '2011-11-16',\n    open: 23.043153534141197,\n    high: 23.07797594514768,\n    low: 22.668823715187536,\n    close: 22.694939,\n    volume: 53262800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-11-17',\n    open: 22.64270723990966,\n    high: 22.668824266434246,\n    low: 22.146501146713145,\n    close: 22.233555,\n    volume: 70977500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-11-18',\n    open: 22.181321806376356,\n    high: 22.198732577025,\n    low: 21.894044090673678,\n    close: 22.024624,\n    volume: 47626200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-11-21',\n    open: 21.9723922448,\n    high: 21.98109763,\n    low: 21.676409148,\n    close: 21.763463,\n    volume: 61882500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-11-22',\n    open: 21.667703111804997,\n    high: 21.728640808822437,\n    low: 21.458774735426594,\n    close: 21.580651,\n    volume: 49204500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-11-23',\n    open: 21.423954135514144,\n    high: 21.580651071218963,\n    low: 21.302077,\n    close: 21.302077,\n    volume: 49099700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-11-25',\n    open: 21.223729084347454,\n    high: 21.476186135645523,\n    low: 21.154086,\n    close: 21.154086,\n    volume: 26164600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-11-28',\n    open: 21.711231696785777,\n    high: 21.73734611147406,\n    low: 21.493597065407997,\n    close: 21.650294,\n    volume: 46766700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-11-29',\n    open: 21.606766229468597,\n    high: 21.798285575852535,\n    low: 21.545828532608695,\n    close: 21.624177,\n    volume: 40917100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-11-30',\n    open: 22.085563775933387,\n    high: 22.27708138545739,\n    low: 21.885338169336357,\n    close: 22.268376,\n    volume: 81350900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-12-01',\n    open: 22.250964048331525,\n    high: 22.311901745683674,\n    low: 21.937571917311832,\n    close: 22.007215,\n    volume: 48545400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-12-02',\n    open: 22.277081128750243,\n    high: 22.303198155359997,\n    low: 21.902749558396096,\n    close: 21.954981,\n    volume: 52293800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-12-05',\n    open: 22.442484082115055,\n    high: 22.459893111566767,\n    low: 22.198732424173837,\n    close: 22.372841,\n    volume: 56818400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-12-06',\n    open: 22.468598910833244,\n    high: 22.52083296445904,\n    low: 22.294492943414614,\n    close: 22.338019,\n    volume: 46175300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-12-07',\n    open: 22.346724698828126,\n    high: 22.42507316875,\n    low: 22.05944697578125,\n    close: 22.285787,\n    volume: 62667000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-12-08',\n    open: 22.181321080314962,\n    high: 22.390249450721342,\n    low: 22.085562715420394,\n    close: 22.111678,\n    volume: 60522200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-12-09',\n    open: 22.2161431947026,\n    high: 22.52083254949449,\n    low: 22.198732424173837,\n    close: 22.372841,\n    volume: 53788500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-12-12',\n    open: 22.120384146609172,\n    high: 22.259670312034494,\n    low: 22.015920393078712,\n    close: 22.207438,\n    volume: 38945900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-12-13',\n    open: 22.416367614518634,\n    high: 22.72105610636646,\n    low: 22.32931375970497,\n    close: 22.425073,\n    volume: 54581100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-12-14',\n    open: 22.390250138449353,\n    high: 22.51212727382106,\n    low: 22.259670229386476,\n    close: 22.277081,\n    volume: 47926400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-12-15',\n    open: 22.390250165073795,\n    high: 22.529536330147586,\n    low: 22.23355497044284,\n    close: 22.250964,\n    volume: 46213900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-12-16',\n    open: 22.346724282307694,\n    high: 22.781993551538463,\n    low: 22.31190187023069,\n    close: 22.634002,\n    volume: 101408100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-12-19',\n    open: 22.651411998769603,\n    high: 22.73846672018732,\n    low: 22.163909563307538,\n    close: 22.224849,\n    volume: 52258300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-12-20',\n    open: 22.51212744863587,\n    high: 22.721055827081994,\n    low: 22.46859878068699,\n    close: 22.660119,\n    volume: 60767600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-12-21',\n    open: 22.642707637034164,\n    high: 22.799405446237305,\n    low: 22.14650153513482,\n    close: 22.425073,\n    volume: 64132500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-12-22',\n    open: 22.47730525599788,\n    high: 22.512127668373758,\n    low: 22.181322150380556,\n    close: 22.468599,\n    volume: 35794100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-12-23',\n    open: 22.555653504969136,\n    high: 22.668824385374364,\n    low: 22.398956568230638,\n    close: 22.660119,\n    volume: 23205800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-12-27',\n    open: 22.599179177112013,\n    high: 22.75587611118663,\n    low: 22.573063891971433,\n    close: 22.668824,\n    volume: 21287200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-12-28',\n    open: 22.72976204598393,\n    high: 22.764582716886135,\n    low: 22.425072687838888,\n    close: 22.477305,\n    volume: 29822500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-12-29',\n    open: 22.590476172229558,\n    high: 22.677528285879596,\n    low: 22.51212770297514,\n    close: 22.651413,\n    volume: 22616900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2011-12-30',\n    open: 22.634002412711958,\n    high: 22.73846790977072,\n    low: 22.555653942821802,\n    close: 22.59918,\n    volume: 27395700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-01-03',\n    open: 23.112797648325852,\n    high: 23.46971845407856,\n    low: 22.973511480227234,\n    close: 23.304317,\n    volume: 64731500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-01-04',\n    open: 23.34784266788321,\n    high: 23.91369182471697,\n    low: 23.31302199827573,\n    close: 23.852755,\n    volume: 80516100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-01-05',\n    open: 23.835344565155093,\n    high: 24.14003392738439,\n    low: 23.75699783694028,\n    close: 24.096507,\n    volume: 56081400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-01-06',\n    open: 23.965926651544372,\n    high: 24.540482082545605,\n    low: 23.965926651544372,\n    close: 24.470839,\n    volume: 99455500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-01-09',\n    open: 24.418605075748413,\n    high: 24.46213287310743,\n    low: 24.131327358733273,\n    close: 24.148739,\n    volume: 59706800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-01-10',\n    open: 24.314141468749998,\n    high: 24.505659947916666,\n    low: 24.15744453125,\n    close: 24.235793,\n    volume: 60014400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-01-11',\n    open: 23.878872688271017,\n    high: 24.3576688960198,\n    low: 23.82664124523698,\n    close: 24.131328,\n    volume: 65582400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-01-12',\n    open: 24.261909860895678,\n    high: 24.392489770714285,\n    low: 24.0703905125,\n    close: 24.375079,\n    volume: 49370800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-01-13',\n    open: 24.31414166442478,\n    high: 24.592714,\n    low: 24.19226713814917,\n    close: 24.592714,\n    volume: 60196100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-01-17',\n    open: 24.723294394904457,\n    high: 24.940929028662417,\n    low: 24.523070531847132,\n    close: 24.601419,\n    volume: 72395300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-01-18',\n    open: 24.644944209872406,\n    high: 24.723293545873183,\n    low: 24.348961118126038,\n    close: 24.575302,\n    volume: 64860600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-01-19',\n    open: 24.514364670186183,\n    high: 24.758116325797573,\n    low: 24.401195533369435,\n    close: 24.479544,\n    volume: 74053500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-01-20',\n    open: 25.088920574517694,\n    high: 25.88981602658418,\n    low: 25.02798287707785,\n    close: 25.863699,\n    volume: 165902900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-01-23',\n    open: 25.724412197069963,\n    high: 26.072629343461486,\n    low: 25.550305364951228,\n    close: 25.88111,\n    volume: 76078100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-01-24',\n    open: 25.654770140708898,\n    high: 25.74182486605317,\n    low: 25.40231483231084,\n    close: 25.541601,\n    volume: 51703300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-01-25',\n    open: 25.306555975526248,\n    high: 25.81146834105102,\n    low: 25.306555975526248,\n    close: 25.733119,\n    volume: 59231700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-01-26',\n    open: 25.77664711019956,\n    high: 25.854995579013117,\n    low: 25.59383314576271,\n    close: 25.680887,\n    volume: 49102800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-01-27',\n    open: 25.637360345393123,\n    high: 25.707003427158433,\n    low: 25.393608688676018,\n    close: 25.445841,\n    volume: 44187700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-01-30',\n    open: 25.219499615800554,\n    high: 25.785351385048788,\n    low: 25.097625095656024,\n    close: 25.776646,\n    volume: 51114800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-01-31',\n    open: 25.820172135449642,\n    high: 25.854994546292197,\n    low: 25.445840577181155,\n    close: 25.707003,\n    volume: 50572400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-02-01',\n    open: 25.93334388737839,\n    high: 26.159682165917907,\n    low: 25.907226860730244,\n    close: 26.020396,\n    volume: 67409900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-02-02',\n    open: 26.029102202701093,\n    high: 26.264147607207093,\n    low: 25.86369901047315,\n    close: 26.07263,\n    volume: 52223300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-02-03',\n    open: 26.23803027694825,\n    high: 26.464371164021166,\n    low: 26.19450422123016,\n    close: 26.325085,\n    volume: 41838500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-02-06',\n    open: 26.15097783772471,\n    high: 26.307673029207386,\n    low: 26.09003840065224,\n    close: 26.290264,\n    volume: 28039700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-02-07',\n    open: 26.246737289950573,\n    high: 26.542720397034593,\n    low: 26.159682564387314,\n    close: 26.420845,\n    volume: 39242400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-02-08',\n    open: 26.34249559230268,\n    high: 26.699416385192436,\n    low: 26.307673180994424,\n    close: 26.690711,\n    volume: 49659100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-02-09',\n    open: 26.70812253103672,\n    high: 26.812586285782547,\n    low: 26.534014822229445,\n    close: 26.786471,\n    volume: 50481600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-02-10',\n    open: 26.673299522904095,\n    high: 26.812585686838524,\n    low: 26.4295504770959,\n    close: 26.551425,\n    volume: 44605300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-02-13',\n    open: 26.664594055556968,\n    high: 26.786470319162852,\n    low: 26.49048722171354,\n    close: 26.621068,\n    volume: 33319800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-02-14',\n    open: 26.577254561652893,\n    high: 26.69116872306932,\n    low: 26.15664519173554,\n    close: 26.507153,\n    volume: 59644000,\n    split: '',\n    dividend: '$0.200',\n  },\n  {\n    date: '2012-02-15',\n    open: 26.577254340008462,\n    high: 26.629829634540155,\n    low: 26.314374362271955,\n    close: 26.331898,\n    volume: 43311300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-02-16',\n    open: 26.559728122780374,\n    high: 27.646302321355822,\n    low: 26.550965427630572,\n    close: 27.418474,\n    volume: 94705100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-02-17',\n    open: 27.339609401069506,\n    high: 27.444760865280003,\n    low: 27.120542025069504,\n    close: 27.383422,\n    volume: 70036500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-02-21',\n    open: 27.32208305336886,\n    high: 27.698879815236456,\n    low: 27.295794968327133,\n    close: 27.549914,\n    volume: 50829900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-02-22',\n    open: 27.558677390500414,\n    high: 27.76021850463703,\n    low: 27.32208374288455,\n    close: 27.400948,\n    volume: 49253200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-02-23',\n    open: 27.339610180075415,\n    high: 27.68135442010346,\n    low: 27.16435539801226,\n    close: 27.488576,\n    volume: 35034700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-02-24',\n    open: 27.584964,\n    high: 27.602489390088945,\n    low: 27.37465931893265,\n    close: 27.584964,\n    volume: 35575400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-02-27',\n    open: 27.374660350877193,\n    high: 27.602490430622012,\n    low: 27.251982615629988,\n    close: 27.47105,\n    volume: 34568400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-02-28',\n    open: 27.52362515143944,\n    high: 27.97928529402933,\n    low: 27.49733619002052,\n    close: 27.92671,\n    volume: 45230600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-02-29',\n    open: 27.944233549061313,\n    high: 28.04062407057341,\n    low: 27.6988798409828,\n    close: 27.812794,\n    volume: 59323600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-03-01',\n    open: 27.979286092930135,\n    high: 28.382369200461042,\n    low: 27.90918453053006,\n    close: 28.294744,\n    volume: 77344100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-03-02',\n    open: 28.312269113659283,\n    high: 28.426182398906086,\n    low: 28.040624685746593,\n    close: 28.110728,\n    volume: 47314200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-03-05',\n    open: 28.049385723856783,\n    high: 28.084437381102745,\n    low: 27.707643238145067,\n    close: 27.86537,\n    volume: 45240000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-03-06',\n    open: 27.637542361616234,\n    high: 28.02310008564956,\n    low: 27.59372800803954,\n    close: 27.655066,\n    volume: 51932900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-03-07',\n    open: 27.7514561790201,\n    high: 27.97052356281407,\n    low: 27.62877932036501,\n    close: 27.900422,\n    volume: 34340400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-03-08',\n    open: 28.075676714799723,\n    high: 28.224640782877085,\n    low: 27.952998103904903,\n    close: 28.049386,\n    volume: 36747400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-03-09',\n    open: 28.128249894850768,\n    high: 28.18082781869334,\n    low: 27.970523133479215,\n    close: 28.031862,\n    volume: 34628400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-03-12',\n    open: 28.014335381710012,\n    high: 28.21587912171651,\n    low: 27.8828958313703,\n    close: 28.075676,\n    volume: 34073600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-03-13',\n    open: 28.25093160444785,\n    high: 28.64525026699653,\n    low: 28.172067346176394,\n    close: 28.627724,\n    volume: 48951700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-03-14',\n    open: 28.50504743285465,\n    high: 28.811743526254283,\n    low: 28.46999927985065,\n    close: 28.715353,\n    volume: 41986900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-03-15',\n    open: 28.732878457571047,\n    high: 28.864317133125795,\n    low: 28.54886273450927,\n    close: 28.785452,\n    volume: 49068300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-03-16',\n    open: 28.83803030754787,\n    high: 28.873081965108863,\n    low: 28.478759799310417,\n    close: 28.566385,\n    volume: 65626400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-03-19',\n    open: 28.513810632362368,\n    high: 28.57514949784874,\n    low: 28.172066400922102,\n    close: 28.215879,\n    volume: 44789200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-03-20',\n    open: 28.128249894850768,\n    high: 28.172066876015133,\n    low: 27.812794619568617,\n    close: 28.031862,\n    volume: 41566800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-03-21',\n    open: 28.005572599130055,\n    high: 28.172066434456912,\n    low: 27.88289574428079,\n    close: 27.96176,\n    volume: 37928600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-03-22',\n    open: 27.87413291279297,\n    high: 28.1194892578125,\n    low: 27.85660927470703,\n    close: 28.040625,\n    volume: 31749500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-03-23',\n    open: 28.12825025797339,\n    high: 28.13701558211237,\n    low: 27.795268711688575,\n    close: 28.049386,\n    volume: 35912200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-03-26',\n    open: 28.20711531151813,\n    high: 28.57515026688014,\n    low: 28.172067159105488,\n    close: 28.557624,\n    volume: 36758300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-03-27',\n    open: 28.610201790976934,\n    high: 28.65401439102967,\n    low: 28.39113440936562,\n    close: 28.496285,\n    volume: 36274900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-03-28',\n    open: 28.496284818151132,\n    high: 28.654014208174253,\n    low: 28.075676324411035,\n    close: 28.207115,\n    volume: 41344800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-03-29',\n    open: 28.093201581537283,\n    high: 28.207114866168705,\n    low: 27.874132449824298,\n    close: 28.145776,\n    volume: 37038500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-03-30',\n    open: 28.391134238040127,\n    high: 28.399895180712655,\n    low: 28.075676334153922,\n    close: 28.268453,\n    volume: 31749400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-04-02',\n    open: 28.23340513289994,\n    high: 28.443708067561108,\n    low: 27.996812359799684,\n    close: 28.294744,\n    volume: 35853600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-04-03',\n    open: 28.18082741575368,\n    high: 28.207114624760063,\n    low: 27.742692661155523,\n    close: 27.988049,\n    volume: 42752100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-04-04',\n    open: 27.742693162534227,\n    high: 27.76898212455473,\n    low: 27.208167875994775,\n    close: 27.348371,\n    volume: 49455900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-04-05',\n    open: 27.295796269035534,\n    high: 27.716404773476654,\n    low: 27.20816843845127,\n    close: 27.620016,\n    volume: 50368600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-04-09',\n    open: 27.35713346585267,\n    high: 27.514862855305466,\n    low: 27.138066086431447,\n    close: 27.251982,\n    volume: 31056400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-04-10',\n    open: 27.216931028454187,\n    high: 27.330847821161136,\n    low: 26.550966178242014,\n    close: 26.699932,\n    volume: 54131300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-04-11',\n    open: 26.66488156177924,\n    high: 26.752509390272813,\n    low: 26.489627657331134,\n    close: 26.59478,\n    volume: 43014000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-04-12',\n    open: 26.70869425177534,\n    high: 27.199406046056456,\n    low: 26.65611808198838,\n    close: 27.146829,\n    volume: 38304000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-04-13',\n    open: 27.0679645615093,\n    high: 27.30455820787271,\n    low: 26.918998743302033,\n    close: 26.997863,\n    volume: 39749200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-04-16',\n    open: 27.155592742277992,\n    high: 27.33084752459643,\n    low: 26.962813445624196,\n    close: 27.234457,\n    volume: 38124800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-04-17',\n    open: 27.400947308494043,\n    high: 27.698879815236456,\n    low: 27.33960931966618,\n    close: 27.549914,\n    volume: 34361500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-04-18',\n    open: 27.409711485444554,\n    high: 27.435997818528126,\n    low: 27.199406800463674,\n    close: 27.287032,\n    volume: 40552900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-04-19',\n    open: 27.278269466845597,\n    high: 27.760218582392774,\n    low: 27.111780009452367,\n    close: 27.173118,\n    volume: 54781200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-04-20',\n    open: 28.172066735393138,\n    high: 28.820503549424775,\n    low: 28.084437154849425,\n    close: 28.408656,\n    volume: 106045000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-04-23',\n    open: 28.312268960711236,\n    high: 28.478759292613926,\n    low: 28.066911743497375,\n    close: 28.145776,\n    volume: 61398200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-04-24',\n    open: 28.224640283818204,\n    high: 28.496284710526318,\n    low: 27.89165874342105,\n    close: 27.970523,\n    volume: 40871100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-04-25',\n    open: 27.97052266178501,\n    high: 28.321030464564274,\n    low: 27.92671006270711,\n    close: 28.215879,\n    volume: 62495500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-04-26',\n    open: 28.14577594261007,\n    high: 28.242166465519578,\n    low: 27.970522915897767,\n    close: 28.137015,\n    volume: 40308100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-04-27',\n    open: 28.1457758554378,\n    high: 28.23340455919634,\n    low: 27.935471172510972,\n    close: 28.023099,\n    volume: 41419100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-04-30',\n    open: 28.023099219237977,\n    high: 28.137015132984068,\n    low: 27.970523048094943,\n    close: 28.05815,\n    volume: 35697200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-05-01',\n    open: 28.08443765759104,\n    high: 28.33855669844153,\n    low: 27.996812456826326,\n    close: 28.049386,\n    volume: 43832300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-05-02',\n    open: 27.909184352490072,\n    high: 27.97928591444295,\n    low: 27.72516687609424,\n    close: 27.86537,\n    volume: 37385300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-05-03',\n    open: 27.93547146629975,\n    high: 27.95299773299748,\n    low: 27.698880448057935,\n    close: 27.83032,\n    volume: 31501300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-05-04',\n    open: 27.55867653960068,\n    high: 27.663828002905102,\n    low: 27.094252830213044,\n    close: 27.146829,\n    volume: 57927200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-05-07',\n    open: 26.901474350984014,\n    high: 27.041677470070475,\n    low: 26.78755844045677,\n    close: 26.85766,\n    volume: 48641400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-05-08',\n    open: 26.708694609836066,\n    high: 26.97157633856459,\n    low: 26.437051062295083,\n    close: 26.72622,\n    volume: 46328300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-05-09',\n    open: 26.454578239403478,\n    high: 27.015389867685304,\n    low: 26.375713104681406,\n    close: 26.954051,\n    volume: 50309300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-05-10',\n    open: 27.04167821849463,\n    high: 27.18188046519193,\n    low: 26.68240771589216,\n    close: 26.936525,\n    volume: 43839200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-05-11',\n    open: 26.892712205537805,\n    high: 27.63754129090366,\n    low: 26.892712205537805,\n    close: 27.304558,\n    volume: 43459300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-05-14',\n    open: 27.006626733376795,\n    high: 27.199406904952706,\n    low: 26.848897342765678,\n    close: 26.883949,\n    volume: 40528900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-05-15',\n    open: 27.02507131080001,\n    high: 27.166194403190712,\n    low: 26.592882722372813,\n    close: 26.645803,\n    volume: 61822800,\n    split: '',\n    dividend: '$0.200',\n  },\n  {\n    date: '2012-05-16',\n    open: 26.73400504373318,\n    high: 26.742826119063547,\n    low: 26.231254907023413,\n    close: 26.372378,\n    volume: 60083700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-05-17',\n    open: 26.451760104702558,\n    high: 26.645803478202875,\n    low: 26.204793806567288,\n    close: 26.213614,\n    volume: 48484000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-05-18',\n    open: 26.275357955131774,\n    high: 26.29299657852043,\n    low: 25.728505062863,\n    close: 25.816707,\n    volume: 56205300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-05-21',\n    open: 25.666762436974793,\n    high: 26.275356655128572,\n    low: 25.63148078184622,\n    close: 26.240075,\n    volume: 38787900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-05-22',\n    open: 26.18715552718064,\n    high: 26.354737440561287,\n    low: 26.01957096774193,\n    close: 26.248896,\n    volume: 39504900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-05-23',\n    open: 25.88726776065724,\n    high: 25.931368727881527,\n    low: 25.261033144053002,\n    close: 25.675584,\n    volume: 65171000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-05-24',\n    open: 25.71968373993808,\n    high: 25.843165564489095,\n    low: 25.366876006879945,\n    close: 25.640302,\n    volume: 52575000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-05-25',\n    open: 25.75496647578969,\n    high: 25.896089574933637,\n    low: 25.587381913536884,\n    close: 25.631482,\n    volume: 29507200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-05-29',\n    open: 25.91372751763317,\n    high: 26.21361409543718,\n    low: 25.772604422195986,\n    close: 26.072491,\n    volume: 37758800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-05-30',\n    open: 25.887268193592366,\n    high: 26.001930710293113,\n    low: 25.684404622987316,\n    close: 25.878448,\n    volume: 41585500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-05-31',\n    open: 25.843165361791353,\n    high: 25.949008562897962,\n    low: 25.525640168568167,\n    close: 25.746145,\n    volume: 39134000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-06-01',\n    open: 25.36687611223634,\n    high: 25.54327909747873,\n    low: 25.084630806636913,\n    close: 25.093451,\n    volume: 56634300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-06-04',\n    open: 25.24339511961636,\n    high: 25.384518218079517,\n    low: 24.97878842797858,\n    close: 25.181652,\n    volume: 47926300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-06-05',\n    open: 25.146372,\n    high: 25.358056646790597,\n    low: 25.040528794585335,\n    close: 25.146372,\n    volume: 45715400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-06-06',\n    open: 25.47271802223959,\n    high: 25.90490926907216,\n    low: 25.410976667554753,\n    close: 25.887268,\n    volume: 46860500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-06-07',\n    open: 26.143052043057644,\n    high: 26.195974966863666,\n    low: 25.728503840232637,\n    close: 25.781425,\n    volume: 37792800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-06-08',\n    open: 25.763783614776624,\n    high: 26.178333579763912,\n    low: 25.622660522702425,\n    close: 26.151873,\n    volume: 42551100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-06-11',\n    open: 26.222435054325263,\n    high: 26.292995719710763,\n    low: 25.41979745259516,\n    close: 25.490359,\n    volume: 46361900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-06-12',\n    open: 25.666762445655092,\n    high: 25.84316542924164,\n    low: 25.43743742036745,\n    close: 25.834347,\n    volume: 35337900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-06-13',\n    open: 25.77260474216896,\n    high: 25.9666507648429,\n    low: 25.62266145140537,\n    close: 25.693223,\n    volume: 32984600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-06-14',\n    open: 25.86962780640763,\n    high: 25.98428944108902,\n    low: 25.472718212731834,\n    close: 25.878448,\n    volume: 39458900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-06-15',\n    open: 26.098952677881414,\n    high: 26.53114216122585,\n    low: 26.010750742504996,\n    close: 26.478221,\n    volume: 62314400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-06-18',\n    open: 26.451759900469167,\n    high: 26.48704155594695,\n    low: 26.204793604240717,\n    close: 26.319457,\n    volume: 58679900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-06-19',\n    open: 26.628164146899994,\n    high: 27.439621921119613,\n    low: 26.504679678088806,\n    close: 27.077994,\n    volume: 75725800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-06-20',\n    open: 27.280858,\n    high: 27.38669943805826,\n    low: 27.025071511126477,\n    close: 27.280858,\n    volume: 36257100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-06-21',\n    open: 27.307317858104042,\n    high: 27.466081339151273,\n    low: 26.513500452867902,\n    close: 26.584062,\n    volume: 48456600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-06-22',\n    open: 26.72518450803979,\n    high: 27.1044536975748,\n    low: 26.487041055731368,\n    close: 27.077994,\n    volume: 45098100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-06-25',\n    open: 26.725184543987197,\n    high: 26.742825812426325,\n    low: 26.125413169752424,\n    close: 26.345918,\n    volume: 42217200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-06-26',\n    open: 26.46058061292472,\n    high: 26.698725838441042,\n    low: 26.407660333718223,\n    close: 26.478221,\n    volume: 38421300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-06-27',\n    open: 26.6281652691589,\n    high: 26.901590387802454,\n    low: 26.487042172042557,\n    close: 26.610524,\n    volume: 33781700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-06-28',\n    open: 26.442939352724846,\n    high: 26.50467982343036,\n    low: 25.949008530926115,\n    close: 26.381198,\n    volume: 45328400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-06-29',\n    open: 26.857490172637203,\n    high: 27.069174817292318,\n    low: 26.584062409252304,\n    close: 26.980972,\n    volume: 55227200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-07-02',\n    open: 27.00743392611076,\n    high: 27.00743392611076,\n    low: 26.645804221246504,\n    close: 26.954511,\n    volume: 30589100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-07-03',\n    open: 26.663444748049415,\n    high: 27.130915,\n    low: 26.610523587451237,\n    close: 27.130915,\n    volume: 20938100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-07-05',\n    open: 26.98097099280225,\n    high: 27.148555545584315,\n    low: 26.795746053624104,\n    close: 27.077994,\n    volume: 28801900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-07-06',\n    open: 26.998612112273996,\n    high: 27.077993850618423,\n    low: 26.41647936441486,\n    close: 26.628164,\n    volume: 38294800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-07-09',\n    open: 26.566423202019333,\n    high: 26.66344444666667,\n    low: 26.266536628686,\n    close: 26.46058,\n    volume: 30680800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-07-10',\n    open: 26.531141573638198,\n    high: 26.654623398411065,\n    low: 26.028390553127107,\n    close: 26.231255,\n    volume: 37534100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-07-11',\n    open: 26.20479393247877,\n    high: 26.23125539492339,\n    low: 25.67558408801195,\n    close: 25.843166,\n    volume: 39184900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-07-12',\n    open: 25.710863942049038,\n    high: 25.737324522435365,\n    low: 25.172833022879708,\n    close: 25.252213,\n    volume: 63523600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-07-13',\n    open: 25.36687668754259,\n    high: 26.001930624087464,\n    low: 25.33159503127074,\n    close: 25.922548,\n    volume: 39085000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-07-16',\n    open: 26.0019298912388,\n    high: 26.046031739830784,\n    low: 25.613842267418743,\n    close: 25.96665,\n    volume: 27900600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-07-17',\n    open: 26.143052730927376,\n    high: 26.337098752552055,\n    low: 25.754965979794132,\n    close: 26.160694,\n    volume: 33771300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-07-18',\n    open: 26.10777267297955,\n    high: 26.85749,\n    low: 25.984289082371784,\n    close: 26.85749,\n    volume: 41090400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-07-19',\n    open: 26.910409906423215,\n    high: 27.1661946315118,\n    low: 26.795746510872743,\n    close: 27.051533,\n    volume: 46663200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-07-20',\n    open: 27.342599125411716,\n    high: 27.386699209723698,\n    low: 26.504679883097516,\n    close: 26.566423,\n    volume: 64021700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-07-23',\n    open: 26.08131172502351,\n    high: 26.090131918369813,\n    low: 25.58738089763044,\n    close: 25.825527,\n    volume: 55151900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-07-24',\n    open: 25.790244738250426,\n    high: 25.896087937936983,\n    low: 25.490358171526584,\n    close: 25.710863,\n    volume: 47723300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-07-25',\n    open: 25.79024593548387,\n    high: 25.869627677419356,\n    low: 25.38451791427742,\n    close: 25.428618,\n    volume: 45579500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-07-26',\n    open: 25.781425353909466,\n    high: 26.019570576131688,\n    low: 25.657942646090536,\n    close: 25.719684,\n    volume: 45301400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-07-27',\n    open: 26.00193058064516,\n    high: 26.32827774193548,\n    low: 25.737324774193542,\n    close: 26.248896,\n    volume: 44242600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-07-30',\n    open: 26.240076011810928,\n    high: 26.301817367132838,\n    low: 25.98428951488652,\n    close: 26.143053,\n    volume: 28905000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-07-31',\n    open: 26.001930075396338,\n    high: 26.204793641048,\n    low: 25.869627174741332,\n    close: 25.993109,\n    volume: 37620900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-08-01',\n    open: 26.098952482488947,\n    high: 26.1518736433186,\n    low: 25.763784248548486,\n    close: 25.940189,\n    volume: 31721800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-08-02',\n    open: 25.763783622475895,\n    high: 26.046031570747292,\n    low: 25.552098984301338,\n    close: 25.746145,\n    volume: 39520500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-08-03',\n    open: 26.046031629918488,\n    high: 26.407659554288237,\n    low: 26.001929781512608,\n    close: 26.240075,\n    volume: 35859400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-08-06',\n    open: 26.460580084788646,\n    high: 26.557603093785538,\n    low: 26.29299552889898,\n    close: 26.41648,\n    volume: 27471800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-08-07',\n    open: 26.522321326834103,\n    high: 26.769286739920684,\n    low: 26.345918342363017,\n    close: 26.689905,\n    volume: 28002900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-08-08',\n    open: 26.645803795527627,\n    high: 26.875128827509165,\n    low: 26.557603624188822,\n    close: 26.751647,\n    volume: 26257600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-08-09',\n    open: 26.8045669901118,\n    high: 27.03389290163934,\n    low: 26.725185249128195,\n    close: 26.90159,\n    volume: 24920800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-08-10',\n    open: 26.901589546351083,\n    high: 27.007432747897038,\n    low: 26.681084714003944,\n    close: 26.831028,\n    volume: 27810300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-08-13',\n    open: 26.769287108235837,\n    high: 26.866308354121138,\n    low: 26.60170343276418,\n    close: 26.804567,\n    volume: 23049100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-08-14',\n    open: 26.902231618019798,\n    high: 26.982139239324397,\n    low: 26.644752392789655,\n    close: 26.751295,\n    volume: 34551400,\n    split: '',\n    dividend: '$0.200',\n  },\n  {\n    date: '2012-08-15',\n    open: 26.733538382116144,\n    high: 26.884474993674534,\n    low: 26.65362987636987,\n    close: 26.813446,\n    volume: 24351000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-08-16',\n    open: 26.955504772349002,\n    high: 27.470464991486097,\n    low: 26.866717639807746,\n    close: 27.328407,\n    volume: 35787200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-08-17',\n    open: 27.45270624854369,\n    high: 27.45270624854369,\n    low: 27.159711647572816,\n    close: 27.434949,\n    volume: 32589900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-08-20',\n    open: 27.36391999414444,\n    high: 27.390555866948603,\n    low: 27.150833011711125,\n    close: 27.292891,\n    volume: 23737700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-08-21',\n    open: 27.3106493893068,\n    high: 27.48822099422266,\n    low: 27.17747090758552,\n    close: 27.346163,\n    volume: 28822700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-08-22',\n    open: 27.15971223445605,\n    high: 27.31064885033894,\n    low: 27.053167853029215,\n    close: 27.11532,\n    volume: 33437400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-08-23',\n    open: 26.982139231767412,\n    high: 26.991018744216785,\n    low: 26.706902757435554,\n    close: 26.866718,\n    volume: 28355600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-08-24',\n    open: 26.857839524143962,\n    high: 27.195226372452563,\n    low: 26.7956891516914,\n    close: 27.133076,\n    volume: 22943300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-08-27',\n    open: 27.461585096396703,\n    high: 27.488220081566663,\n    low: 27.159711868696256,\n    close: 27.248499,\n    volume: 34691100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-08-28',\n    open: 27.25737814732629,\n    high: 27.346162616746216,\n    low: 27.097562018203135,\n    close: 27.195226,\n    volume: 23947900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-08-29',\n    open: 27.212984,\n    high: 27.301770244698208,\n    low: 27.026533773996217,\n    close: 27.212984,\n    volume: 23346800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-08-30',\n    open: 27.10644099901019,\n    high: 27.177469993733148,\n    low: 26.831201868733874,\n    close: 26.919989,\n    volume: 23982100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-08-31',\n    open: 27.168590266061,\n    high: 27.488219851916938,\n    low: 26.973259644259574,\n    close: 27.36392,\n    volume: 36590100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-09-04',\n    open: 27.035412522788796,\n    high: 27.221862749649976,\n    low: 26.769052899606873,\n    close: 26.982139,\n    volume: 48556700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-09-05',\n    open: 26.831202383318967,\n    high: 27.106441518873986,\n    low: 26.822323758808317,\n    close: 26.982139,\n    volume: 33650000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-09-06',\n    open: 27.0798049122807,\n    high: 27.84336751242386,\n    low: 27.04428952617263,\n    close: 27.834488,\n    volume: 48371700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-09-07',\n    open: 27.559250618419785,\n    high: 27.585885603363955,\n    low: 27.284012378222542,\n    close: 27.479343,\n    volume: 42649100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-09-10',\n    open: 27.3727997588802,\n    high: 27.43495013134603,\n    low: 27.088683770464968,\n    close: 27.275134,\n    volume: 40524000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-09-11',\n    open: 27.248498757349342,\n    high: 27.443827603318365,\n    low: 27.177469763228817,\n    close: 27.337285,\n    volume: 25191800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-09-12',\n    open: 27.470464991486097,\n    high: 27.68355109085279,\n    low: 27.28401298979815,\n    close: 27.328407,\n    volume: 32775800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-09-13',\n    open: 27.426069103538037,\n    high: 27.683550091675823,\n    low: 26.991017408176553,\n    close: 27.470464,\n    volume: 45047300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-09-14',\n    open: 27.532614398994376,\n    high: 27.74570138563606,\n    low: 27.35504102226386,\n    close: 27.710186,\n    volume: 51422800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-09-17',\n    open: 27.69243052683808,\n    high: 27.754580010079465,\n    low: 27.559251160187028,\n    close: 27.710186,\n    volume: 36488500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-09-18',\n    open: 27.612522004490064,\n    high: 27.710185985453787,\n    low: 27.550372521281304,\n    close: 27.683551,\n    volume: 34542700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-09-19',\n    open: 27.60364338562459,\n    high: 27.692430517892387,\n    low: 27.559251151284357,\n    close: 27.568128,\n    volume: 48871900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-09-20',\n    open: 27.479343774051866,\n    high: 27.949909985694436,\n    low: 27.443828388113566,\n    close: 27.923275,\n    volume: 45543000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-09-21',\n    open: 27.90551609472536,\n    high: 28.065332219528628,\n    low: 27.603642869392665,\n    close: 27.69243,\n    volume: 102348900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-09-24',\n    open: 27.523735850430935,\n    high: 27.5858862217061,\n    low: 27.204104481724773,\n    close: 27.328407,\n    volume: 46825900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-09-25',\n    open: 27.47934374832125,\n    high: 27.523735983012042,\n    low: 26.955504902192956,\n    close: 26.982139,\n    volume: 54266400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-09-26',\n    open: 26.884475756937682,\n    high: 27.168590851839575,\n    low: 26.671388769864432,\n    close: 26.78681,\n    volume: 54672000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-09-27',\n    open: 26.78680962433687,\n    high: 26.991017984084877,\n    low: 26.538207255042074,\n    close: 26.777931,\n    volume: 47129900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-09-28',\n    open: 26.795689235887092,\n    high: 26.866718233198924,\n    low: 26.40502975067204,\n    close: 26.422787,\n    volume: 54229300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-10-01',\n    open: 26.467178089078914,\n    high: 26.618115589691424,\n    low: 26.12091263004409,\n    close: 26.183063,\n    volume: 54042700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-10-02',\n    open: 26.351757248819958,\n    high: 26.538207473567095,\n    low: 26.191942009440325,\n    close: 26.334,\n    volume: 43338900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-10-03',\n    open: 26.41390724501315,\n    high: 26.62699422783006,\n    low: 26.342878250740846,\n    close: 26.511573,\n    volume: 46655900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-10-04',\n    open: 26.609236477797324,\n    high: 26.66251,\n    low: 26.254092389141114,\n    close: 26.66251,\n    volume: 43634900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-10-05',\n    open: 26.840081729313233,\n    high: 26.857838978224457,\n    low: 26.40502913098827,\n    close: 26.502694,\n    volume: 41133900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-10-08',\n    open: 26.316241484325538,\n    high: 26.56484385208718,\n    low: 26.236333865786506,\n    close: 26.440544,\n    volume: 29752000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-10-09',\n    open: 26.351757086347096,\n    high: 26.40502883247852,\n    low: 25.90782586858518,\n    close: 25.996613,\n    volume: 45121100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-10-10',\n    open: 25.881189611801243,\n    high: 26.02324671151646,\n    low: 25.703618015191616,\n    close: 25.730253,\n    volume: 47227100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-10-11',\n    open: 25.94333907817074,\n    high: 25.969975838688224,\n    low: 25.63258900625316,\n    close: 25.703618,\n    volume: 41488500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-10-12',\n    open: 25.72137386414528,\n    high: 26.032126604379226,\n    low: 25.57043725013626,\n    close: 25.925584,\n    volume: 46464700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-10-15',\n    open: 26.076521144385666,\n    high: 26.387271227352727,\n    low: 25.969976762114538,\n    close: 26.200821,\n    volume: 42440200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-10-16',\n    open: 26.147549390744764,\n    high: 26.40502860698542,\n    low: 26.032126387249917,\n    close: 26.183063,\n    volume: 47739400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-10-17',\n    open: 26.01436900061338,\n    high: 26.316242234814126,\n    low: 25.827918773234202,\n    close: 26.27185,\n    volume: 44206100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-10-18',\n    open: 26.325121366101694,\n    high: 26.396150361355936,\n    low: 25.97885501423729,\n    close: 26.191942,\n    volume: 59238500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-10-19',\n    open: 25.792403609079038,\n    high: 25.81904037077655,\n    low: 25.30408014329889,\n    close: 25.42838,\n    volume: 90470800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-10-22',\n    open: 25.508287572857142,\n    high: 25.597073815714282,\n    low: 24.709211387142854,\n    close: 24.860148,\n    volume: 83374000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-10-23',\n    open: 24.655940400211776,\n    high: 25.037722144109203,\n    low: 24.647061775652826,\n    close: 24.904541,\n    volume: 64414800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-10-24',\n    open: 25.00220623369176,\n    high: 25.037721619045232,\n    low: 24.744727014744157,\n    close: 24.771362,\n    volume: 53320400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-10-25',\n    open: 25.02884313279939,\n    high: 25.037721757221153,\n    low: 24.735848526881366,\n    close: 24.753604,\n    volume: 54084300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-10-26',\n    open: 24.735848916074012,\n    high: 25.16202200716136,\n    low: 24.718090779088648,\n    close: 25.046599,\n    volume: 57790000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-10-31',\n    open: 25.34847184870123,\n    high: 25.64146645476309,\n    low: 25.30407961443309,\n    close: 25.339595,\n    volume: 69464100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-11-01',\n    open: 25.605953523035232,\n    high: 26.245213610782525,\n    low: 25.58819627371274,\n    close: 26.2097,\n    volume: 72047900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-11-02',\n    open: 26.27184961966102,\n    high: 26.43166485898305,\n    low: 26.041005385084745,\n    close: 26.191942,\n    volume: 57131600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-11-05',\n    open: 26.298486151395515,\n    high: 26.405028755485276,\n    low: 26.041005157981946,\n    close: 26.307363,\n    volume: 38070800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-11-06',\n    open: 26.476057615001416,\n    high: 26.81344622565729,\n    low: 26.289607392899047,\n    close: 26.511573,\n    volume: 43401500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-11-07',\n    open: 26.21857898965062,\n    high: 26.48493683631362,\n    low: 25.792403238685008,\n    close: 25.81904,\n    volume: 57871800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-11-08',\n    open: 25.854556142793232,\n    high: 26.07652176139669,\n    low: 25.570438375255858,\n    close: 25.579317,\n    volume: 49841800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-11-09',\n    open: 25.641466233885748,\n    high: 25.916705364449324,\n    low: 25.579315863438296,\n    close: 25.597074,\n    volume: 43291200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-11-12',\n    open: 25.694740753728514,\n    high: 25.756890238727507,\n    low: 25.046599375305505,\n    close: 25.055478,\n    volume: 61112300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-11-13',\n    open: 24.18717592248062,\n    high: 24.43781933739989,\n    low: 23.94548319490587,\n    close: 24.249837,\n    volume: 131689200,\n    split: '',\n    dividend: '$0.230',\n  },\n  {\n    date: '2012-11-14',\n    open: 24.38411029359165,\n    high: 24.428869100448843,\n    low: 23.990239775482596,\n    close: 24.026047,\n    volume: 76086100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-11-15',\n    open: 24.061851912043586,\n    high: 24.142416151353416,\n    low: 23.83806235840518,\n    close: 23.864918,\n    volume: 50955600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-11-16',\n    open: 23.873870738687785,\n    high: 23.9007263815836,\n    low: 23.578468513574663,\n    close: 23.739597,\n    volume: 64083300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-11-19',\n    open: 23.990239179664083,\n    high: 23.990239179664083,\n    low: 23.694836969787545,\n    close: 23.927579,\n    volume: 57179300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-11-20',\n    open: 23.95443480772875,\n    high: 23.99024024262689,\n    low: 23.685886437147527,\n    close: 23.909676,\n    volume: 47070400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-11-21',\n    open: 23.909675236208155,\n    high: 24.321448913860895,\n    low: 23.87386980245381,\n    close: 24.124515,\n    volume: 66360300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-11-23',\n    open: 24.375158734470805,\n    high: 24.858544181279992,\n    low: 24.348304882584085,\n    close: 24.795884,\n    volume: 57845700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-11-26',\n    open: 24.652658524682057,\n    high: 24.688463958687986,\n    low: 24.321449084755354,\n    close: 24.518383,\n    volume: 85198700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-11-27',\n    open: 24.491530200918945,\n    high: 24.50943157529967,\n    low: 24.20507956576385,\n    close: 24.240885,\n    volume: 45018600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-11-28',\n    open: 24.178223725211122,\n    high: 24.51838295650903,\n    low: 23.963385750607248,\n    close: 24.49153,\n    volume: 53018400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-11-29',\n    open: 24.26774031565027,\n    high: 24.49152987135381,\n    low: 24.043950759946725,\n    close: 24.124515,\n    volume: 69551400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-11-30',\n    open: 24.21402924894282,\n    high: 24.285641907409662,\n    low: 23.71274153483315,\n    close: 23.829113,\n    volume: 83690200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-12-03',\n    open: 23.972338275407946,\n    high: 24.008143709421113,\n    low: 23.63217725312145,\n    close: 23.659032,\n    volume: 53173800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-12-04',\n    open: 23.72169267266998,\n    high: 23.83806234533996,\n    low: 23.578467358419896,\n    close: 23.605323,\n    volume: 49777500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-12-05',\n    open: 23.614273218077617,\n    high: 24.106611139857517,\n    low: 23.5068551256093,\n    close: 23.87387,\n    volume: 68283800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-12-06',\n    open: 23.99919076178156,\n    high: 24.151368552936777,\n    low: 23.82016090974856,\n    close: 23.927579,\n    volume: 39182300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-12-07',\n    open: 24.00814385971821,\n    high: 24.00814385971821,\n    low: 23.605323549176475,\n    close: 23.685886,\n    volume: 46162100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-12-10',\n    open: 23.775401090907053,\n    high: 24.14241595590279,\n    low: 23.73959565777299,\n    close: 24.115563,\n    volume: 47031100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-12-11',\n    open: 24.21402938119608,\n    high: 24.607899900073203,\n    low: 24.21402938119608,\n    close: 24.455723,\n    volume: 52282800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-12-12',\n    open: 24.643706779886564,\n    high: 24.72427101997467,\n    low: 24.24088468428781,\n    close: 24.38411,\n    volume: 43966300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-12-13',\n    open: 24.45572232918767,\n    high: 24.634753971421837,\n    low: 24.124514686212663,\n    close: 24.26774,\n    volume: 45080100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-12-14',\n    open: 24.26774126769613,\n    high: 24.285642642538257,\n    low: 23.90072638194399,\n    close: 23.999192,\n    volume: 42077500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-12-17',\n    open: 23.981289844235718,\n    high: 24.366206092295645,\n    low: 23.882821543911437,\n    close: 24.258788,\n    volume: 42046100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-12-18',\n    open: 24.393061842999337,\n    high: 24.73322107629394,\n    low: 24.29459354223634,\n    close: 24.67056,\n    volume: 50486900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-12-19',\n    open: 24.786932926536206,\n    high: 24.822738361506346,\n    low: 24.393062399965665,\n    close: 24.446771,\n    volume: 53519900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-12-20',\n    open: 24.491530259320086,\n    high: 24.77798,\n    low: 24.30354613439306,\n    close: 24.77798,\n    volume: 52607300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-12-21',\n    open: 24.572094,\n    high: 24.607899433592003,\n    low: 24.16927190640175,\n    close: 24.572094,\n    volume: 98776500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-12-24',\n    open: 24.348304943506502,\n    high: 24.393061960201845,\n    low: 24.169272400933938,\n    close: 24.222981,\n    volume: 20842400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-12-26',\n    open: 24.19612789939773,\n    high: 24.348304798795464,\n    low: 23.90072568291978,\n    close: 24.043951,\n    volume: 31631100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-12-27',\n    open: 24.07080392386272,\n    high: 24.249836465127466,\n    low: 23.78435418525053,\n    close: 24.133465,\n    volume: 39394000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-12-28',\n    open: 23.909675316129015,\n    high: 24.07975627419044,\n    low: 23.76645,\n    close: 23.76645,\n    volume: 28239900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2012-12-31',\n    open: 23.802257904989066,\n    high: 23.963386390242846,\n    low: 23.60532398483714,\n    close: 23.909676,\n    volume: 42749500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-01-02',\n    open: 24.393061562524927,\n    high: 24.822737509314358,\n    low: 24.30354574027713,\n    close: 24.724271,\n    volume: 52899300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-01-03',\n    open: 24.733221235483963,\n    high: 24.75112529541284,\n    low: 24.31249775853211,\n    close: 24.393062,\n    volume: 48294400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-01-04',\n    open: 24.4109648605086,\n    high: 24.47362593642483,\n    low: 23.927579417726253,\n    close: 23.936531,\n    volume: 52521100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-01-07',\n    open: 23.96338576308034,\n    high: 24.061852273000145,\n    low: 23.847014298284442,\n    close: 23.891774,\n    volume: 37110400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-01-08',\n    open: 23.945482540319492,\n    high: 23.981289764509974,\n    low: 23.68588575967743,\n    close: 23.76645,\n    volume: 44703100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-01-09',\n    open: 23.91862637380707,\n    high: 23.94548201515049,\n    low: 23.775401060819252,\n    close: 23.900725,\n    volume: 49047900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-01-10',\n    open: 23.85596695978711,\n    high: 24.151369177300424,\n    low: 23.533710890385372,\n    close: 23.685886,\n    volume: 71431300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-01-11',\n    open: 23.712741205739846,\n    high: 24.106610821841226,\n    low: 23.524758875031495,\n    close: 24.017095,\n    volume: 55512100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-01-14',\n    open: 24.07975647749187,\n    high: 24.240884959497393,\n    low: 23.954434324820912,\n    close: 24.070804,\n    volume: 48324400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-01-15',\n    open: 24.01709576137801,\n    high: 24.428869450059697,\n    low: 24.01709576137801,\n    close: 24.357255,\n    volume: 48244500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-01-16',\n    open: 24.303545508374796,\n    high: 24.375158165489715,\n    low: 24.178223358423697,\n    close: 24.205079,\n    volume: 41077400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-01-17',\n    open: 24.33935340084631,\n    high: 24.589995917318827,\n    low: 24.22298103952066,\n    close: 24.393062,\n    volume: 51685900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-01-18',\n    open: 24.258788264220183,\n    high: 24.428869224699522,\n    low: 24.205079665066496,\n    close: 24.393062,\n    volume: 52167700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-01-22',\n    open: 24.4378188396484,\n    high: 24.572094364771495,\n    low: 24.16927226519337,\n    close: 24.303546,\n    volume: 58650600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-01-23',\n    open: 24.348304134987863,\n    high: 24.742171955903984,\n    low: 24.348304134987863,\n    close: 24.715319,\n    volume: 50387700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-01-24',\n    open: 24.79588386641711,\n    high: 25.12709151636234,\n    low: 24.589995683198502,\n    close: 24.733221,\n    volume: 101739300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-01-25',\n    open: 24.688464421393988,\n    high: 25.270317281216546,\n    low: 24.518383459518382,\n    close: 24.957011,\n    volume: 81847700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-01-28',\n    open: 25.07338182228592,\n    high: 25.27031663131494,\n    low: 24.849592266571122,\n    close: 24.983866,\n    volume: 56056500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-01-29',\n    open: 24.903301936451264,\n    high: 25.18080009234623,\n    low: 24.706367126026418,\n    close: 25.073382,\n    volume: 49242600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-01-30',\n    open: 25.073382318491923,\n    high: 25.23451169695357,\n    low: 24.849592758348297,\n    close: 24.930157,\n    volume: 43580500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-01-31',\n    open: 24.87644779437691,\n    high: 25.037574483436487,\n    low: 24.527335193903998,\n    close: 24.572094,\n    volume: 50530000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-02-01',\n    open: 24.769028854278556,\n    high: 25.109188095174723,\n    low: 24.661608968787323,\n    close: 25.00177,\n    volume: 55565900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-02-04',\n    open: 24.948060027517563,\n    high: 25.082332862888745,\n    low: 24.545237940771216,\n    close: 24.563142,\n    volume: 50540000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-02-05',\n    open: 24.724270881340036,\n    high: 24.760076314909092,\n    low: 24.491529744612762,\n    close: 24.616851,\n    volume: 35410400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-02-06',\n    open: 24.50943143402977,\n    high: 24.652658541098244,\n    low: 24.39306175932699,\n    close: 24.473626,\n    volume: 41889600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-02-07',\n    open: 24.48257717989087,\n    high: 24.51838261333213,\n    low: 24.258787626144155,\n    close: 24.419917,\n    volume: 38028300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-02-08',\n    open: 24.482578244376707,\n    high: 24.80483432062524,\n    low: 24.446771019062144,\n    close: 24.661609,\n    volume: 33318500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-02-11',\n    open: 24.751124877920855,\n    high: 24.992817598247754,\n    low: 24.616851144405917,\n    close: 24.939109,\n    volume: 32247700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-02-12',\n    open: 24.957011,\n    high: 25.06443088466395,\n    low: 24.840641323193736,\n    close: 24.957011,\n    volume: 35990900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-02-13',\n    open: 25.001769282134525,\n    high: 25.1628986581658,\n    low: 24.957010475622678,\n    close: 25.091286,\n    volume: 41715600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-02-14',\n    open: 24.99281811580535,\n    high: 25.11813937452292,\n    low: 24.948061098865082,\n    close: 25.100238,\n    volume: 32663200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-02-15',\n    open: 25.100237642034344,\n    high: 25.207655734380577,\n    low: 24.957010535045267,\n    close: 25.073382,\n    volume: 49650900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-02-19',\n    open: 25.163638176348066,\n    high: 25.3531786846053,\n    low: 25.091432612276563,\n    close: 25.317075,\n    volume: 38781400,\n    split: '',\n    dividend: '$0.230',\n  },\n  {\n    date: '2013-02-20',\n    open: 25.389280275425396,\n    high: 25.452461948408757,\n    low: 25.118510315805153,\n    close: 25.154614,\n    volume: 44110200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-02-21',\n    open: 25.037278379046924,\n    high: 25.037278379046924,\n    low: 24.576967925791198,\n    close: 24.811636,\n    volume: 49078500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-02-22',\n    open: 24.983124438040345,\n    high: 25.05533,\n    low: 24.802610533141213,\n    close: 25.05533,\n    volume: 31425900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-02-25',\n    open: 25.244868914205412,\n    high: 25.317074476784676,\n    low: 24.703329,\n    close: 24.703329,\n    volume: 48011800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-02-26',\n    open: 24.712352890183347,\n    high: 24.91091908984585,\n    low: 24.676251011463247,\n    close: 24.703329,\n    volume: 49923300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-02-27',\n    open: 24.74845678203728,\n    high: 25.271947115136534,\n    low: 24.66722552345291,\n    close: 25.100458,\n    volume: 36394700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-02-28',\n    open: 25.163637562309557,\n    high: 25.2448688199078,\n    low: 25.037278730837365,\n    close: 25.091432,\n    volume: 35840200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-03-01',\n    open: 25.01922620515044,\n    high: 25.253895183044893,\n    low: 24.838713203623854,\n    close: 25.226819,\n    volume: 34849700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-03-04',\n    open: 25.136561143872118,\n    high: 25.407332,\n    low: 25.00117661837769,\n    close: 25.407332,\n    volume: 38157500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-03-05',\n    open: 25.533693729024584,\n    high: 25.759336118795307,\n    low: 25.41635878377425,\n    close: 25.587847,\n    volume: 41432200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-03-06',\n    open: 25.4614854406131,\n    high: 25.479537733713066,\n    low: 25.07338234934774,\n    close: 25.353178,\n    volume: 51448500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-03-07',\n    open: 25.371230718889013,\n    high: 25.524667540972764,\n    low: 25.28097286215256,\n    close: 25.398306,\n    volume: 29196700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-03-08',\n    open: 25.497589383928574,\n    high: 25.569794946785713,\n    low: 25.235843316001894,\n    close: 25.271947,\n    volume: 37667800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-03-11',\n    open: 25.217793867844282,\n    high: 25.24486914892418,\n    low: 24.974099189303942,\n    close: 25.154614,\n    volume: 36627500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-03-12',\n    open: 25.12753613185238,\n    high: 25.226819684368184,\n    low: 24.947021320289643,\n    close: 25.190716,\n    volume: 39255200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-03-13',\n    open: 25.15461342656665,\n    high: 25.289997952005727,\n    low: 25.046304181590255,\n    close: 25.199741,\n    volume: 29093400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-03-14',\n    open: 25.271947166735867,\n    high: 25.41635829340293,\n    low: 25.208767298819026,\n    close: 25.398306,\n    volume: 55914800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-03-15',\n    open: 25.299025304530158,\n    high: 25.41635844306853,\n    low: 25.253895924611413,\n    close: 25.308051,\n    volume: 92710300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-03-18',\n    open: 25.163637799209823,\n    high: 25.524667419295515,\n    low: 25.100457931594164,\n    close: 25.362204,\n    volume: 44809400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-03-19',\n    open: 25.38025672939709,\n    high: 25.470511879545423,\n    low: 25.299025469638394,\n    close: 25.43441,\n    volume: 51901600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-03-20',\n    open: 25.578820390536723,\n    high: 25.714205819562146,\n    low: 25.434409266242938,\n    close: 25.560769,\n    volume: 35447800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-03-21',\n    open: 25.37123,\n    high: 25.59687237902375,\n    low: 25.31707402389527,\n    close: 25.37123,\n    volume: 34233200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-03-22',\n    open: 25.44343573124209,\n    high: 25.57882025699115,\n    low: 25.36220357168142,\n    close: 25.497589,\n    volume: 28720900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-03-25',\n    open: 25.542716831805468,\n    high: 25.5878462109375,\n    low: 25.235843191180468,\n    close: 25.416358,\n    volume: 44154000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-03-26',\n    open: 25.488563562499998,\n    high: 25.578820515624997,\n    low: 25.37123042600703,\n    close: 25.416358,\n    volume: 27824300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-03-27',\n    open: 25.39830520676055,\n    high: 25.678103561078412,\n    low: 25.344151938521257,\n    close: 25.605898,\n    volume: 36047400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-03-28',\n    open: 25.560768935310417,\n    high: 25.86764257365807,\n    low: 25.506614763837305,\n    close: 25.822515,\n    volume: 55453800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-04-01',\n    open: 25.849590280597507,\n    high: 25.86764257365807,\n    low: 25.59687261886202,\n    close: 25.822515,\n    volume: 29201100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-04-02',\n    open: 25.804463298071642,\n    high: 26.039131379830952,\n    low: 25.741283429905675,\n    close: 25.994002,\n    volume: 28456500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-04-03',\n    open: 25.948874114106236,\n    high: 26.129388923556508,\n    low: 25.759335414450995,\n    close: 25.777385,\n    volume: 35062800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-04-04',\n    open: 25.623948492885,\n    high: 25.82251559802409,\n    low: 25.515641049999996,\n    close: 25.813489,\n    volume: 45263200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-04-05',\n    open: 25.47051082737781,\n    high: 25.975951561247193,\n    low: 25.371229985801953,\n    close: 25.903746,\n    volume: 50927300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-04-08',\n    open: 25.930822734872333,\n    high: 25.930822734872333,\n    low: 25.69615375325418,\n    close: 25.804463,\n    volume: 34759500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-04-09',\n    open: 25.93082193141432,\n    high: 26.91462269386617,\n    low: 25.88569345607249,\n    close: 26.725084,\n    volume: 77733800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-04-10',\n    open: 26.688980737484126,\n    high: 27.36590787827253,\n    low: 26.643852261431565,\n    close: 27.329806,\n    volume: 71116700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-04-11',\n    open: 26.264773221673355,\n    high: 26.355031076894676,\n    low: 25.930822496861698,\n    close: 26.120363,\n    volume: 130923200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-04-12',\n    open: 26.039131269915554,\n    high: 26.19256809195665,\n    low: 25.86764305704609,\n    close: 25.984978,\n    volume: 62886300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-04-15',\n    open: 25.858616317231917,\n    high: 26.15646425387019,\n    low: 25.732256586536895,\n    close: 25.89472,\n    volume: 56332900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-04-16',\n    open: 26.084260033975145,\n    high: 26.300875823729264,\n    low: 25.90374702627497,\n    close: 26.147439,\n    volume: 52797300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-04-17',\n    open: 26.03913139091225,\n    high: 26.21062050714811,\n    low: 25.813489004509197,\n    close: 26.02108,\n    volume: 52840700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-04-18',\n    open: 26.12938912662692,\n    high: 26.15646531029992,\n    low: 25.72323193041918,\n    close: 25.984978,\n    volume: 56906600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-04-19',\n    open: 26.734110472606485,\n    high: 27.29370268055089,\n    low: 26.725084777275615,\n    close: 26.869495,\n    volume: 99790700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-04-22',\n    open: 27.34785623982423,\n    high: 28.14211833992864,\n    low: 27.320780056114174,\n    close: 27.826219,\n    volume: 137904000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-04-23',\n    open: 27.70888585681791,\n    high: 27.889398862745097,\n    low: 27.420061798084056,\n    close: 27.618628,\n    volume: 59126900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-04-24',\n    open: 27.63668061226728,\n    high: 28.810020128463474,\n    low: 27.618628318639797,\n    close: 28.665609,\n    volume: 90946600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-04-25',\n    open: 28.620478207935218,\n    high: 29.64038265496611,\n    low: 28.46704319665084,\n    close: 28.828071,\n    volume: 110700200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-04-26',\n    open: 28.79196774482643,\n    high: 28.864173306568944,\n    low: 28.385812362594326,\n    close: 28.692686,\n    volume: 47799300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-04-29',\n    open: 28.701709882413287,\n    high: 29.495971963938306,\n    low: 28.674633699336596,\n    close: 29.432793,\n    volume: 59116400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-04-30',\n    open: 29.387665155600615,\n    high: 29.88407840311803,\n    low: 29.13494387899812,\n    close: 29.87505,\n    volume: 75165200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-05-01',\n    open: 29.721614699217152,\n    high: 29.85700193420385,\n    low: 29.423764948413293,\n    close: 29.532076,\n    volume: 54330900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-05-02',\n    open: 29.450845045512853,\n    high: 29.938229890277086,\n    low: 29.234226550385834,\n    close: 29.929206,\n    volume: 46059500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-05-03',\n    open: 29.99238511989339,\n    high: 30.254130280434147,\n    low: 29.85700149716653,\n    close: 30.227055,\n    volume: 46784600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-05-06',\n    open: 30.163872246416474,\n    high: 30.606133126518518,\n    low: 30.01043722962963,\n    close: 30.461722,\n    volume: 40978300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-05-07',\n    open: 30.371466543311843,\n    high: 30.497825375165615,\n    low: 30.001413035357878,\n    close: 30.064592,\n    volume: 43078300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-05-08',\n    open: 29.847973755806386,\n    high: 30.001412377954388,\n    low: 29.468896365982037,\n    close: 29.77577,\n    volume: 51595700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-05-09',\n    open: 29.649407406434722,\n    high: 29.784794641763625,\n    low: 29.414741132578083,\n    close: 29.477921,\n    volume: 46417800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-05-10',\n    open: 29.48694470685074,\n    high: 29.532075891008656,\n    low: 29.171047176844514,\n    close: 29.504997,\n    volume: 36394900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-05-13',\n    open: 29.432793598385242,\n    high: 29.847974684165145,\n    low: 29.37863762085276,\n    close: 29.811871,\n    volume: 36027600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-05-14',\n    open: 29.86640679874064,\n    high: 30.475367,\n    low: 29.811871068789266,\n    close: 30.475367,\n    volume: 56870100,\n    split: '',\n    dividend: '$0.230',\n  },\n  {\n    date: '2013-05-15',\n    open: 30.402657307873817,\n    high: 30.811662562946918,\n    low: 30.38447842803418,\n    close: 30.766214,\n    volume: 46303900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-05-16',\n    open: 30.57534591649191,\n    high: 31.03888689767471,\n    low: 30.493545048052987,\n    close: 30.975264,\n    volume: 59382900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-05-17',\n    open: 31.0207079020361,\n    high: 31.693291,\n    low: 30.99343821929613,\n    close: 31.693291,\n    volume: 60666700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-05-20',\n    open: 31.56604569919922,\n    high: 31.902336334863264,\n    low: 31.52060077305583,\n    close: 31.884162,\n    volume: 54020800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-05-21',\n    open: 31.90233663283929,\n    high: 32.056851200967074,\n    low: 31.556957917619165,\n    close: 31.675112,\n    volume: 48702400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-05-22',\n    open: 31.62058073523254,\n    high: 31.6660247527875,\n    low: 31.229754367732582,\n    close: 31.456979,\n    volume: 66047500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-05-23',\n    open: 31.111596063156888,\n    high: 31.402442678074046,\n    low: 30.81166137201901,\n    close: 31.038886,\n    volume: 51102700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-05-24',\n    open: 30.82983669285363,\n    high: 31.157041076511433,\n    low: 30.811662357627835,\n    close: 31.147953,\n    volume: 33174400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-05-28',\n    open: 31.284286055989313,\n    high: 31.975050766990286,\n    low: 31.275198888349504,\n    close: 31.829627,\n    volume: 48212100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-05-29',\n    open: 31.575137113234714,\n    high: 31.829626886765286,\n    low: 31.420622543560135,\n    close: 31.702382,\n    volume: 38412200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-05-30',\n    open: 31.67511135876915,\n    high: 32.03867258174915,\n    low: 31.638758144946394,\n    close: 31.838714,\n    volume: 51131000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-05-31',\n    open: 31.64784630098302,\n    high: 32.06593870909921,\n    low: 31.62058025442405,\n    close: 31.72056,\n    volume: 56165700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-06-03',\n    open: 31.738735161129583,\n    high: 32.384055850455155,\n    low: 31.656937928221353,\n    close: 32.347699,\n    volume: 51252600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-06-04',\n    open: 32.37496434031753,\n    high: 32.48403488930129,\n    low: 31.602401508007926,\n    close: 31.802361,\n    volume: 65529500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-06-05',\n    open: 31.447887355517754,\n    high: 31.71146883841228,\n    low: 31.293376423041305,\n    close: 31.61149,\n    volume: 46025100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-06-06',\n    open: 31.66602508426845,\n    high: 31.91142859858468,\n    low: 31.347912413561104,\n    close: 31.775092,\n    volume: 37618500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-06-07',\n    open: 32.038673432221664,\n    high: 32.520388747977805,\n    low: 31.865983619074186,\n    close: 32.420409,\n    volume: 40757300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-06-10',\n    open: 32.274985214766026,\n    high: 32.40223464547588,\n    low: 31.938693665144473,\n    close: 32.238632,\n    volume: 35994500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-06-11',\n    open: 31.85689278369618,\n    high: 31.97505050229621,\n    low: 31.520601234213544,\n    close: 31.666025,\n    volume: 39435900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-06-12',\n    open: 31.93869388710146,\n    high: 32.056851606571435,\n    low: 31.675112400774342,\n    close: 31.811449,\n    volume: 37372700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-06-13',\n    open: 31.8023615130056,\n    high: 31.829626651220433,\n    low: 31.438800281716585,\n    close: 31.556958,\n    volume: 45654900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-06-14',\n    open: 31.4024430517152,\n    high: 31.529688844898583,\n    low: 31.129774403792183,\n    close: 31.266111,\n    volume: 53192600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-06-17',\n    open: 31.529689542815746,\n    high: 31.956872766857142,\n    low: 31.4751574480414,\n    close: 31.811449,\n    volume: 49670100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-06-18',\n    open: 31.78418192376416,\n    high: 31.965958899755865,\n    low: 31.720559936722132,\n    close: 31.79327,\n    volume: 28616500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-06-19',\n    open: 31.775091545568085,\n    high: 31.893249262792715,\n    low: 31.4388,\n    close: 31.4388,\n    volume: 30816200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-06-20',\n    open: 31.138861218998258,\n    high: 31.202487750464332,\n    low: 30.329942451809558,\n    close: 30.439013,\n    volume: 54493700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-06-21',\n    open: 30.593525437330925,\n    high: 30.657148336339038,\n    low: 30.039096408504506,\n    close: 30.239055,\n    volume: 85338500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-06-24',\n    open: 29.939117313547527,\n    high: 31.08433130378792,\n    low: 29.602825759109557,\n    close: 30.64806,\n    volume: 56109000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-06-25',\n    open: 30.975264036701873,\n    high: 31.24793268958947,\n    low: 30.41174421564825,\n    close: 30.602612,\n    volume: 44073400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-06-26',\n    open: 31.011617244907466,\n    high: 31.338821627878986,\n    low: 30.8025705809164,\n    close: 31.220663,\n    volume: 48665900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-06-27',\n    open: 31.37517705647537,\n    high: 31.611489763877056,\n    low: 31.356999085990733,\n    close: 31.466066,\n    volume: 28993100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-06-28',\n    open: 31.24793223582582,\n    high: 31.62058063152216,\n    low: 31.211575385883755,\n    close: 31.393356,\n    volume: 65545500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-07-01',\n    open: 31.584223513264742,\n    high: 31.802360975469934,\n    low: 31.2024879533475,\n    close: 31.229754,\n    volume: 31055400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-07-02',\n    open: 31.2751982152386,\n    high: 31.302464262063914,\n    low: 30.56625827531742,\n    close: 30.848015,\n    volume: 37630000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-07-03',\n    open: 30.59352532393562,\n    high: 31.23884238829893,\n    low: 30.538989592905118,\n    close: 30.911638,\n    volume: 15994400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-07-05',\n    open: 30.98435108460541,\n    high: 31.12068768276888,\n    low: 30.520814649156694,\n    close: 31.093418,\n    volume: 26085900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-07-08',\n    open: 31.220662334800444,\n    high: 31.438799797331793,\n    low: 30.88437170029876,\n    close: 31.202488,\n    volume: 32396900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-07-09',\n    open: 31.429713299585227,\n    high: 31.447887634772904,\n    low: 31.0297952156893,\n    close: 31.220663,\n    volume: 25318500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-07-10',\n    open: 31.211575619262955,\n    high: 31.638758838617324,\n    low: 31.193397648605256,\n    close: 31.53878,\n    volume: 29658800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-07-11',\n    open: 31.811447935316554,\n    high: 32.51129978989352,\n    low: 31.72055990186982,\n    close: 32.438587,\n    volume: 53638300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-07-12',\n    open: 32.33861176725656,\n    high: 32.47494473002213,\n    low: 32.065939479435656,\n    close: 32.420409,\n    volume: 35501200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-07-15',\n    open: 32.411321567670534,\n    high: 32.92030565317859,\n    low: 32.3386115030948,\n    close: 32.874858,\n    volume: 34142600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-07-16',\n    open: 32.72943456213124,\n    high: 33.11117376619796,\n    low: 32.683990544092914,\n    close: 32.96575,\n    volume: 36378500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-07-17',\n    open: 33.0293722955024,\n    high: 33.07481631271216,\n    low: 32.25681036945857,\n    close: 32.484035,\n    volume: 37285100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-07-18',\n    open: 32.46585640624208,\n    high: 32.62036733857236,\n    low: 32.01140714116169,\n    close: 32.211363,\n    volume: 49547100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-07-19',\n    open: 29.44831435282892,\n    high: 29.693713321693377,\n    low: 28.194032556687898,\n    close: 28.539414,\n    volume: 248428500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-07-22',\n    open: 28.812084183630375,\n    high: 29.09384,\n    low: 28.721193422130174,\n    close: 29.09384,\n    volume: 79040700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-07-23',\n    open: 29.002951867064738,\n    high: 29.12110958394566,\n    low: 28.821171253577905,\n    close: 28.921151,\n    volume: 65810400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-07-24',\n    open: 29.121109699921952,\n    high: 29.257442661109096,\n    low: 28.98477310314071,\n    close: 29.048396,\n    volume: 52803100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-07-25',\n    open: 28.73937248007953,\n    high: 28.766638527130887,\n    low: 28.403079114465726,\n    close: 28.530324,\n    volume: 63213000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-07-26',\n    open: 28.412167625168642,\n    high: 28.739372,\n    low: 28.366721790446118,\n    close: 28.739372,\n    volume: 38633600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-07-29',\n    open: 28.603036284093303,\n    high: 28.721194003766836,\n    low: 28.539414294882235,\n    close: 28.666661,\n    volume: 28870700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-07-30',\n    open: 28.884797009997456,\n    high: 29.193820701148542,\n    low: 28.67574852438245,\n    close: 28.948419,\n    volume: 45799500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-07-31',\n    open: 29.057484899204493,\n    high: 29.13019678111404,\n    low: 28.821171282998463,\n    close: 28.939329,\n    volume: 43898400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-08-01',\n    open: 29.139288342431858,\n    high: 29.166554389958954,\n    low: 28.721194101673508,\n    close: 28.784817,\n    volume: 42557900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-08-02',\n    open: 28.80299610686015,\n    high: 28.993863894445404,\n    low: 28.69392737139942,\n    close: 28.984774,\n    volume: 29199900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-08-05',\n    open: 28.99386279514628,\n    high: 29.084752647168685,\n    low: 28.757548270989517,\n    close: 28.812084,\n    volume: 30984000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-08-06',\n    open: 28.675748134800003,\n    high: 28.784816868904375,\n    low: 28.521235382425083,\n    close: 28.703016,\n    volume: 36331500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-08-07',\n    open: 28.66666076084302,\n    high: 29.175641214778,\n    low: 28.403079276260783,\n    close: 29.139288,\n    volume: 38078600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-08-08',\n    open: 29.302890677112632,\n    high: 30.05727464570613,\n    low: 29.13019722823123,\n    close: 29.893672,\n    volume: 59034400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-08-09',\n    open: 29.784604988544196,\n    high: 29.90276361587775,\n    low: 29.511936336973907,\n    close: 29.720983,\n    volume: 26800700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-08-12',\n    open: 29.502845599858585,\n    high: 29.966385671490105,\n    low: 29.502845599858585,\n    close: 29.875494,\n    volume: 25493700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-08-13',\n    open: 29.756504055524612,\n    high: 29.793117097417905,\n    low: 29.481914021401774,\n    close: 29.500221,\n    volume: 39464100,\n    split: '',\n    dividend: '$0.230',\n  },\n  {\n    date: '2013-08-14',\n    open: 29.41784324777838,\n    high: 30.534514956385962,\n    low: 29.01511167976134,\n    close: 29.610056,\n    volume: 48519600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-08-15',\n    open: 29.289701752447254,\n    high: 29.45445632480477,\n    low: 28.22795006392104,\n    close: 29.097489,\n    volume: 33338000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-08-16',\n    open: 29.097488798871975,\n    high: 29.28054851825624,\n    low: 28.978498471021965,\n    close: 29.10664,\n    volume: 32866300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-08-19',\n    open: 29.070029093024186,\n    high: 29.262241846157245,\n    low: 28.722212968169703,\n    close: 28.731366,\n    volume: 27902500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-08-20',\n    open: 28.777132430257893,\n    high: 29.198170970962337,\n    low: 28.713061208691517,\n    close: 28.941887,\n    volume: 22979600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-08-21',\n    open: 28.932734,\n    high: 29.298852520584614,\n    low: 28.868662778363532,\n    close: 28.932734,\n    volume: 37409100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-08-22',\n    open: 29.463608364524212,\n    high: 29.738202063647417,\n    low: 29.381230163256934,\n    close: 29.646669,\n    volume: 31169900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-08-23',\n    open: 32.19121049889007,\n    high: 32.2186723397636,\n    low: 31.12030762589928,\n    close: 31.806785,\n    volume: 225493800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-08-26',\n    open: 31.486430791869648,\n    high: 31.733558985876194,\n    low: 31.147765873993066,\n    close: 31.257605,\n    volume: 72786800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-08-27',\n    open: 30.68096265790515,\n    high: 31.21183667281146,\n    low: 30.3423023112017,\n    close: 30.442982,\n    volume: 58522300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-08-28',\n    open: 30.561972261256482,\n    high: 30.754185013730403,\n    low: 30.20500493640218,\n    close: 30.223311,\n    volume: 44257400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-08-29',\n    open: 30.14093393952113,\n    high: 30.754185244034076,\n    low: 30.02194360994106,\n    close: 30.708421,\n    volume: 45284700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-08-30',\n    open: 30.543665159627025,\n    high: 30.64434942129644,\n    low: 30.28738119327059,\n    close: 30.571127,\n    volume: 42790200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-09-03',\n    open: 29.060875503791575,\n    high: 29.353772516743174,\n    low: 28.639836962976815,\n    close: 29.179864,\n    volume: 154507000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-09-04',\n    open: 28.731365772794042,\n    high: 28.804590026857372,\n    low: 28.475082714178757,\n    close: 28.55746,\n    volume: 142320600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-09-05',\n    open: 28.46592858789625,\n    high: 28.777132581009216,\n    low: 28.3286340276951,\n    close: 28.584918,\n    volume: 71644900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-09-06',\n    open: 28.658140588067646,\n    high: 28.731364839753034,\n    low: 28.49338602177551,\n    close: 28.511693,\n    volume: 75434900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-09-09',\n    open: 28.575763694930572,\n    high: 29.097488325915915,\n    low: 28.557459462365696,\n    close: 28.978498,\n    volume: 49628500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-09-10',\n    open: 29.198171358387505,\n    high: 29.655824777683318,\n    low: 29.097488924179,\n    close: 29.646669,\n    volume: 56881200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-09-11',\n    open: 29.811423633694346,\n    high: 30.140932768116514,\n    low: 29.774810592344284,\n    close: 29.967027,\n    volume: 39087500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-09-12',\n    open: 29.94871992505289,\n    high: 30.003636283339773,\n    low: 29.82972960048118,\n    close: 29.921259,\n    volume: 32860200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-09-13',\n    open: 29.99448508944854,\n    high: 30.26907604235774,\n    low: 29.756504432987544,\n    close: 30.232463,\n    volume: 40899000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-09-16',\n    open: 30.55282066813304,\n    high: 30.66265613300781,\n    low: 29.957872693532703,\n    close: 30.021943,\n    volume: 52839700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-09-17',\n    open: 30.58943073179873,\n    high: 30.63519863713739,\n    low: 30.113476734948925,\n    close: 30.140934,\n    volume: 84716500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-09-18',\n    open: 30.195852790690335,\n    high: 30.571127082707143,\n    low: 30.049404286488656,\n    close: 30.497901,\n    volume: 64099900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-09-19',\n    open: 30.644350406788057,\n    high: 30.827411042431955,\n    low: 30.497901898272943,\n    close: 30.790798,\n    volume: 42026600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-09-20',\n    open: 30.580279052751475,\n    high: 30.644350274951197,\n    low: 29.921259851965484,\n    close: 30.012792,\n    volume: 102904900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-09-23',\n    open: 29.783965454462315,\n    high: 30.177545809466576,\n    low: 29.74735241311226,\n    close: 29.967027,\n    volume: 39826100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-09-24',\n    open: 30.086014503617765,\n    high: 30.086014503617765,\n    low: 29.426998962285946,\n    close: 29.701589,\n    volume: 40685000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-09-25',\n    open: 29.738202597336667,\n    high: 30.021943841506694,\n    low: 29.655825309894205,\n    close: 29.756505,\n    volume: 28907500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-09-26',\n    open: 29.875494672124354,\n    high: 30.205004729935915,\n    low: 29.82973042874581,\n    close: 29.994485,\n    volume: 28504000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-09-27',\n    open: 30.09516967274232,\n    high: 30.89148252930568,\n    low: 30.08601481027541,\n    close: 30.452137,\n    volume: 55348000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-09-30',\n    open: 30.205004032602286,\n    high: 30.488748925181397,\n    low: 29.93041400215451,\n    close: 30.461288,\n    volume: 39839500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-10-01',\n    open: 30.525358611599724,\n    high: 30.763340179547395,\n    low: 30.479594368818617,\n    close: 30.735882,\n    volume: 36718700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-10-02',\n    open: 30.534514965687258,\n    high: 31.14776626498969,\n    low: 30.470443743159475,\n    close: 31.047082,\n    volume: 46946800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-10-03',\n    open: 31.010472063251452,\n    high: 31.12030752745696,\n    low: 30.58942986255872,\n    close: 30.992166,\n    volume: 38703800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-10-04',\n    open: 30.836562568859666,\n    high: 31.111156262980746,\n    low: 30.77249134761029,\n    close: 31.010472,\n    volume: 33008100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-10-07',\n    open: 30.75418503888874,\n    high: 30.854869304062294,\n    low: 30.388066512542387,\n    close: 30.479595,\n    volume: 35069300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-10-08',\n    open: 30.488749698626332,\n    high: 30.507056677443963,\n    low: 30.021943248401403,\n    close: 30.214156,\n    volume: 41017600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-10-09',\n    open: 30.269076,\n    high: 30.525359058416928,\n    low: 30.168391735437677,\n    close: 30.269076,\n    volume: 35878600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-10-10',\n    open: 30.48875030859403,\n    high: 31.019624330527684,\n    low: 30.442982402982725,\n    close: 30.900634,\n    volume: 42875100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-10-11',\n    open: 30.82741065961293,\n    high: 31.2484492010622,\n    low: 30.82741065961293,\n    close: 31.239298,\n    volume: 30033300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-10-14',\n    open: 31.02877917374778,\n    high: 31.577959243020054,\n    low: 30.918940047862552,\n    close: 31.532195,\n    volume: 27757900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-10-15',\n    open: 31.73355890853193,\n    high: 32.02645958262386,\n    low: 31.550501021391888,\n    close: 31.568808,\n    volume: 47097800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-10-16',\n    open: 31.66948795777384,\n    high: 31.944082570908904,\n    low: 31.632878576760376,\n    close: 31.706101,\n    volume: 35111600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-10-17',\n    open: 31.532195254203195,\n    high: 32.02645988338172,\n    low: 31.458969169689386,\n    close: 31.962385,\n    volume: 31359200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-10-18',\n    open: 31.870856471134335,\n    high: 32.026459841088545,\n    low: 31.42235974714976,\n    close: 31.998998,\n    volume: 41811700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-10-21',\n    open: 32.01730413790774,\n    high: 32.218671745902135,\n    low: 31.953232917505982,\n    close: 32.026459,\n    volume: 27433500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-10-22',\n    open: 32.05391655847794,\n    high: 32.12713898043239,\n    low: 31.59626497997311,\n    close: 31.651185,\n    volume: 40438500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-10-23',\n    open: 31.44066288448038,\n    high: 31.568808992857992,\n    low: 30.818256712536886,\n    close: 30.900634,\n    volume: 58600500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-10-24',\n    open: 30.9555534022671,\n    high: 31.21183646085752,\n    low: 30.72672760834141,\n    close: 30.864024,\n    volume: 53209700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-10-25',\n    open: 32.84107838969443,\n    high: 33.21635268636389,\n    low: 32.465804093024964,\n    close: 32.703782,\n    volume: 113494000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-10-28',\n    open: 32.59394704237655,\n    high: 32.7037825082935,\n    low: 32.282743046949676,\n    close: 32.557334,\n    volume: 38383600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-10-29',\n    open: 32.61225326524687,\n    high: 32.694630551564444,\n    low: 32.273588342254,\n    close: 32.511569,\n    volume: 31702200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-10-30',\n    open: 32.52072113757465,\n    high: 32.7587017954748,\n    low: 32.42919173468791,\n    close: 32.529876,\n    volume: 36997700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-10-31',\n    open: 32.639710790737084,\n    high: 32.66716897032237,\n    low: 32.34681377859363,\n    close: 32.410885,\n    volume: 41682300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-11-01',\n    open: 32.64886252962062,\n    high: 32.66716950848434,\n    low: 32.39257855507621,\n    close: 32.520721,\n    volume: 40264600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-11-04',\n    open: 32.57563980594435,\n    high: 32.93260804208703,\n    low: 32.53902676385731,\n    close: 32.895995,\n    volume: 28060700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-11-05',\n    open: 32.75870211832451,\n    high: 33.60077922336439,\n    low: 32.740395139202924,\n    close: 33.536708,\n    volume: 51681900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-11-06',\n    open: 34.085891851559715,\n    high: 34.98288804207112,\n    low: 33.92113636580081,\n    close: 34.946275,\n    volume: 88948800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-11-07',\n    open: 34.74490754443016,\n    high: 34.790671787793656,\n    low: 34.259797777866666,\n    close: 34.323869,\n    volume: 60437400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-11-08',\n    open: 34.47946873555222,\n    high: 34.580153,\n    low: 34.177420518724745,\n    close: 34.580153,\n    volume: 36737800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-11-11',\n    open: 34.49777540127039,\n    high: 34.58015268618659,\n    low: 34.18657140961713,\n    close: 34.406246,\n    volume: 26872500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-11-12',\n    open: 34.21403306321451,\n    high: 34.41539701266459,\n    low: 34.04927849428395,\n    close: 34.195727,\n    volume: 31651600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-11-13',\n    open: 33.84791125838574,\n    high: 34.927969,\n    low: 33.774688835323325,\n    close: 34.927969,\n    volume: 44957600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-11-14',\n    open: 34.66253060731649,\n    high: 34.900511265382086,\n    low: 34.52523696054253,\n    close: 34.799827,\n    volume: 46183700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-11-15',\n    open: 34.73575626414038,\n    high: 34.79982657082453,\n    low: 34.52523653475349,\n    close: 34.635072,\n    volume: 50601300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-11-18',\n    open: 34.18657173023845,\n    high: 34.3970951215447,\n    low: 33.93028867203525,\n    close: 34.049279,\n    volume: 53277500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-11-19',\n    open: 33.98471823663619,\n    high: 34.335173096887694,\n    low: 33.81871417653843,\n    close: 33.883275,\n    volume: 44275000,\n    split: '',\n    dividend: '$0.280',\n  },\n  {\n    date: '2013-11-20',\n    open: 34.049275147458836,\n    high: 34.501176930357225,\n    low: 33.99394322785737,\n    close: 34.196838,\n    volume: 32229900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-11-21',\n    open: 34.37206233625335,\n    high: 34.611845052522824,\n    low: 34.362838044128665,\n    close: 34.491956,\n    volume: 23064700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-11-22',\n    open: 34.6118452869647,\n    high: 34.75018292467394,\n    low: 34.427399099746395,\n    close: 34.648736,\n    volume: 27982000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-11-25',\n    open: 34.980744911550076,\n    high: 34.999190729609026,\n    low: 34.648736786895235,\n    close: 34.713293,\n    volume: 30646800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-11-26',\n    open: 34.64873669792432,\n    high: 34.72251812548108,\n    low: 34.445841,\n    close: 34.445841,\n    volume: 34465300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-11-27',\n    open: 34.648737500198806,\n    high: 34.823962169551024,\n    low: 34.574959759912915,\n    close: 34.676403,\n    volume: 26002100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-11-29',\n    open: 34.87929819094418,\n    high: 35.31275416738633,\n    low: 34.87929819094418,\n    close: 35.165195,\n    volume: 22090400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-12-02',\n    open: 35.12830395427038,\n    high: 35.76465193537152,\n    low: 35.100637532891426,\n    close: 35.460313,\n    volume: 42950400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-12-03',\n    open: 35.17441554044337,\n    high: 35.49720398525695,\n    low: 35.11908361950703,\n    close: 35.331199,\n    volume: 52109800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-12-04',\n    open: 35.23897230705602,\n    high: 35.949101713638974,\n    low: 35.15597027641908,\n    close: 35.912211,\n    volume: 51983600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-12-05',\n    open: 35.82920822656305,\n    high: 35.85687833698163,\n    low: 34.28906127263158,\n    close: 35.045302,\n    volume: 116305000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-12-06',\n    open: 35.4326429205614,\n    high: 35.55253566528033,\n    low: 35.03608135058761,\n    close: 35.377311,\n    volume: 36457300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-12-09',\n    open: 35.56176012559687,\n    high: 35.847654166818884,\n    low: 35.386531770509855,\n    close: 35.700095,\n    volume: 30286000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-12-10',\n    open: 35.607871383596894,\n    high: 35.87532328832786,\n    low: 35.0637460487078,\n    close: 35.146749,\n    volume: 37828600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-12-11',\n    open: 35.1006371498269,\n    high: 35.321974051911695,\n    low: 34.48273130448396,\n    close: 34.685627,\n    volume: 39853400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-12-12',\n    open: 34.71329296724221,\n    high: 34.71329296724221,\n    low: 34.289061286161704,\n    close: 34.325952,\n    volume: 36012800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-12-13',\n    open: 34.51039776604191,\n    high: 34.53806787613049,\n    low: 33.772602865506755,\n    close: 33.83716,\n    volume: 40066100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-12-16',\n    open: 33.87405175315944,\n    high: 34.123057850990996,\n    low: 33.698826162115374,\n    close: 34.02161,\n    volume: 31734200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-12-17',\n    open: 34.06772189265114,\n    high: 34.22450535269386,\n    low: 33.50515533298904,\n    close: 33.68038,\n    volume: 45687700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-12-18',\n    open: 33.53282122553508,\n    high: 33.75415720667724,\n    low: 32.767356211305945,\n    close: 33.735716,\n    volume: 63192100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-12-19',\n    open: 33.6711558035104,\n    high: 33.7080465177552,\n    low: 33.2745942284896,\n    close: 33.431374,\n    volume: 34160100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-12-20',\n    open: 33.38526197619209,\n    high: 34.058499743709234,\n    low: 33.37603768389757,\n    close: 33.938607,\n    volume: 62649100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-12-23',\n    open: 33.947831353097605,\n    high: 34.02160909117985,\n    low: 33.708045865249666,\n    close: 33.772603,\n    volume: 25128700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-12-24',\n    open: 33.864828959740564,\n    high: 34.279836340524575,\n    low: 33.791047533469985,\n    close: 34.196838,\n    volume: 14243000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-12-26',\n    open: 34.30750709498801,\n    high: 34.57495900621386,\n    low: 34.27983698456595,\n    close: 34.528844,\n    volume: 17612800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-12-27',\n    open: 34.65796091024557,\n    high: 34.6948479349596,\n    low: 34.2798368589205,\n    close: 34.390509,\n    volume: 14563000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-12-30',\n    open: 34.32595186496534,\n    high: 34.47351103075887,\n    low: 34.03083445562306,\n    close: 34.390509,\n    volume: 16290500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2013-12-31',\n    open: 34.4919563967483,\n    high: 34.65796045609073,\n    low: 34.32595141516111,\n    close: 34.501177,\n    volume: 17503500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-01-02',\n    open: 34.44584066358364,\n    high: 34.49195659152939,\n    low: 34.21527946875048,\n    close: 34.270616,\n    volume: 30632200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-01-03',\n    open: 34.30750690978204,\n    high: 34.32595180547427,\n    low: 33.754157272280956,\n    close: 34.040055,\n    volume: 31134800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-01-06',\n    open: 33.98471847838005,\n    high: 34.02160919202009,\n    low: 33.30226010430237,\n    close: 33.320705,\n    volume: 43603700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-01-07',\n    open: 33.50515526085872,\n    high: 33.65271442812046,\n    low: 33.39448311867803,\n    close: 33.578933,\n    volume: 35802800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-01-08',\n    open: 33.20081259512375,\n    high: 33.32992594408221,\n    low: 32.81347162600356,\n    close: 32.979472,\n    volume: 59971700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-01-09',\n    open: 33.09014351639458,\n    high: 33.11780993745595,\n    low: 32.64746694574104,\n    close: 32.767356,\n    volume: 36516300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-01-10',\n    open: 33.108589652242415,\n    high: 33.33915084867523,\n    low: 32.97025108989315,\n    close: 33.237703,\n    volume: 40548800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-01-13',\n    open: 33.191591060613035,\n    high: 33.21925655917668,\n    low: 32.12178712922368,\n    close: 32.260122,\n    volume: 45901900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-01-14',\n    open: 32.02956091222921,\n    high: 33.09014332163389,\n    low: 31.93733735732964,\n    close: 32.997917,\n    volume: 41623300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-01-15',\n    open: 33.10859016106132,\n    high: 33.929387110731525,\n    low: 33.0624742320869,\n    close: 33.901717,\n    volume: 44812600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-01-16',\n    open: 33.837161038643295,\n    high: 34.123057850990996,\n    low: 33.48670985655516,\n    close: 34.02161,\n    volume: 38018700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-01-17',\n    open: 33.966277073014155,\n    high: 33.966277073014155,\n    low: 33.339150622962656,\n    close: 33.551266,\n    volume: 46267500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-01-21',\n    open: 33.95705295421912,\n    high: 33.95705295421912,\n    low: 33.25614784047242,\n    close: 33.357592,\n    volume: 31567300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-01-22',\n    open: 33.44059393341191,\n    high: 33.49593046479265,\n    low: 32.97025093932647,\n    close: 33.136255,\n    volume: 21904300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-01-23',\n    open: 33.283814421413915,\n    high: 33.32070513520363,\n    low: 32.75813489189865,\n    close: 33.256148,\n    volume: 43954000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-01-24',\n    open: 34.538068671821875,\n    high: 34.63029130730445,\n    low: 33.68960161158832,\n    close: 33.947832,\n    volume: 76395500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-01-27',\n    open: 34.00316462683003,\n    high: 34.02160952270693,\n    low: 33.18236768255253,\n    close: 33.228479,\n    volume: 44420800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-01-28',\n    open: 33.311481357325086,\n    high: 33.56048745409928,\n    low: 32.97025170250896,\n    close: 33.449819,\n    volume: 36205500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-01-29',\n    open: 33.18236754282597,\n    high: 34.012388776036396,\n    low: 33.10858980411861,\n    close: 33.809494,\n    volume: 52745900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-01-30',\n    open: 33.92938586637431,\n    high: 34.01238789532163,\n    low: 33.41292787512404,\n    close: 33.993943,\n    volume: 35036300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-01-31',\n    open: 34.07694605570145,\n    high: 34.943854317448654,\n    low: 33.71727058609257,\n    close: 34.897743,\n    volume: 93162300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-02-03',\n    open: 34.80551924745006,\n    high: 35.03608043851365,\n    low: 33.59737676178728,\n    close: 33.643489,\n    volume: 64063100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-02-04',\n    open: 34.09539154895131,\n    high: 34.29828356266768,\n    low: 33.431374363486896,\n    close: 33.523597,\n    volume: 54697900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-02-05',\n    open: 33.4682639685876,\n    high: 33.63426802888911,\n    low: 33.01636218216616,\n    close: 33.034808,\n    volume: 55814400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-02-06',\n    open: 33.01636305232678,\n    high: 33.43137413626312,\n    low: 32.914916123913294,\n    close: 33.366817,\n    volume: 35351800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-02-07',\n    open: 33.495931324509534,\n    high: 33.7449374219109,\n    low: 33.21003359041095,\n    close: 33.717271,\n    volume: 33260500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-02-10',\n    open: 33.78182723180528,\n    high: 33.938607,\n    low: 33.46826400643671,\n    close: 33.938607,\n    volume: 26767000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-02-11',\n    open: 34.01238877763289,\n    high: 34.362839031100464,\n    low: 33.99394388183279,\n    close: 34.279837,\n    volume: 32141400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-02-12',\n    open: 34.44584085911751,\n    high: 34.67640205525946,\n    low: 34.399729542133905,\n    close: 34.556513,\n    volume: 27051800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-02-13',\n    open: 34.4273993845747,\n    high: 34.91618819434827,\n    low: 34.4273993845747,\n    close: 34.685627,\n    volume: 37635500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-02-14',\n    open: 34.48273169877416,\n    high: 34.84240716607015,\n    low: 34.427399778232214,\n    close: 34.694848,\n    volume: 31407500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-02-18',\n    open: 34.964305464131215,\n    high: 35.103677660560564,\n    low: 34.759889254670725,\n    close: 34.769179,\n    volume: 32834000,\n    split: '',\n    dividend: '$0.280',\n  },\n  {\n    date: '2014-02-19',\n    open: 34.58334928497739,\n    high: 35.075803343151335,\n    low: 34.574055823122066,\n    close: 34.852803,\n    volume: 29750400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-02-20',\n    open: 34.908554138013244,\n    high: 35.18730131216416,\n    low: 34.75059873779089,\n    close: 35.075803,\n    volume: 27526100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-02-21',\n    open: 35.2523426569376,\n    high: 35.633297470273305,\n    low: 35.17801168745419,\n    close: 35.28951,\n    volume: 38021300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-02-24',\n    open: 35.020053,\n    high: 35.28951043325843,\n    low: 34.88068080447688,\n    close: 35.020053,\n    volume: 32085100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-02-25',\n    open: 34.945722225491714,\n    high: 35.16871792541077,\n    low: 34.70413774332713,\n    close: 34.880681,\n    volume: 30736500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-02-26',\n    open: 34.91784856988074,\n    high: 35.06651422911037,\n    low: 34.5554732380274,\n    close: 34.81564,\n    volume: 41041800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-02-27',\n    open: 34.797056254119276,\n    high: 35.20588495235349,\n    low: 34.59264004668146,\n    close: 35.178012,\n    volume: 33903400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-02-28',\n    open: 35.28951114618869,\n    high: 35.73550719833876,\n    low: 35.140845485751875,\n    close: 35.596135,\n    volume: 41215000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-03-03',\n    open: 35.233758519491914,\n    high: 35.42888497995135,\n    low: 34.83422328670135,\n    close: 35.103677,\n    volume: 29717500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-03-04',\n    open: 35.49392625589818,\n    high: 35.75409022442072,\n    low: 35.37313448138506,\n    close: 35.689049,\n    volume: 26802400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-03-05',\n    open: 35.54038352032581,\n    high: 35.558966727395266,\n    low: 35.24305220721459,\n    close: 35.410302,\n    volume: 20520100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-03-06',\n    open: 35.43817460907423,\n    high: 35.531093431002645,\n    low: 35.20588452295575,\n    close: 35.447469,\n    volume: 23582200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-03-07',\n    open: 35.56825714428249,\n    high: 35.64259183034288,\n    low: 35.02005253970226,\n    close: 35.215179,\n    volume: 26591600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-03-10',\n    open: 35.29880311585637,\n    high: 35.31738260598393,\n    low: 35.04792889531582,\n    close: 35.140844,\n    volume: 19006600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-03-11',\n    open: 35.1873020163946,\n    high: 35.52180067622303,\n    low: 35.0479298202703,\n    close: 35.326677,\n    volume: 25216400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-03-12',\n    open: 35.12226070135963,\n    high: 35.70763265769532,\n    low: 35.11297095607439,\n    close: 35.558967,\n    volume: 30494100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-03-13',\n    open: 35.69833906008364,\n    high: 35.726216658276634,\n    low: 34.973594910733965,\n    close: 35.205885,\n    volume: 32169700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-03-14',\n    open: 34.982888911825015,\n    high: 35.43817469423022,\n    low: 34.852802746644706,\n    close: 35.029346,\n    volume: 27195600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-03-17',\n    open: 35.21517973256982,\n    high: 35.689049660947425,\n    low: 35.11297116314119,\n    close: 35.354551,\n    volume: 20479600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-03-18',\n    open: 35.54967321651306,\n    high: 37.07349991074797,\n    low: 35.51250958990647,\n    close: 36.748291,\n    volume: 64063900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-03-19',\n    open: 36.67396100453599,\n    high: 36.74829197636547,\n    low: 36.15363026432391,\n    close: 36.488128,\n    volume: 35597200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-03-20',\n    open: 36.46954395762241,\n    high: 37.77037031379463,\n    low: 36.46025421238704,\n    close: 37.473039,\n    volume: 59269800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-03-21',\n    open: 37.83541072995718,\n    high: 38.03982415052092,\n    low: 37.17570408789443,\n    close: 37.31508,\n    volume: 80721800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-03-24',\n    open: 37.48232834469136,\n    high: 37.76107551923472,\n    low: 37.036332307925775,\n    close: 37.630994,\n    volume: 46098400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-03-25',\n    open: 37.77966031581556,\n    high: 38.08628509357109,\n    low: 37.12924713330865,\n    close: 37.482329,\n    volume: 43193100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-03-26',\n    open: 37.61241070790624,\n    high: 37.8261166577681,\n    low: 36.79474774723977,\n    close: 36.971291,\n    volume: 41977500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-03-27',\n    open: 36.92483385921418,\n    high: 37.13853980877064,\n    low: 36.55316786399472,\n    close: 36.571752,\n    volume: 35369200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-03-28',\n    open: 36.97129206939092,\n    high: 37.76107652595322,\n    low: 36.86908349948098,\n    close: 37.445162,\n    volume: 43472700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-03-31',\n    open: 37.565953340280394,\n    high: 38.56015492509613,\n    low: 37.53808038781189,\n    close: 38.086285,\n    volume: 46886300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-04-01',\n    open: 38.23495042108983,\n    high: 38.64377911848281,\n    low: 38.16061573445754,\n    close: 38.48582,\n    volume: 32605000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-04-02',\n    open: 38.504404361500114,\n    high: 38.708820569713204,\n    low: 38.25353013532049,\n    close: 38.420779,\n    volume: 28666700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-04-03',\n    open: 38.36503269165886,\n    high: 38.36503269165886,\n    low: 37.826117817541345,\n    close: 38.104865,\n    volume: 30139600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-04-04',\n    open: 38.32786420436078,\n    high: 38.457945723409175,\n    low: 36.831915120799934,\n    close: 37.045622,\n    volume: 51409600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-04-07',\n    open: 37.12924665599663,\n    high: 37.41728729365044,\n    low: 36.92483416648231,\n    close: 36.980581,\n    volume: 37559600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-04-08',\n    open: 36.93412377574083,\n    high: 37.101372638121546,\n    low: 36.423086514293445,\n    close: 36.999165,\n    volume: 35918600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-04-09',\n    open: 37.101373472414785,\n    high: 37.677451971075534,\n    low: 37.05491638320248,\n    close: 37.603121,\n    volume: 27398700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-04-10',\n    open: 37.57524331130602,\n    high: 37.80753339686775,\n    low: 36.32087777843299,\n    close: 36.571752,\n    volume: 45960800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-04-11',\n    open: 36.237254252416584,\n    high: 36.97129187027974,\n    low: 36.237254252416584,\n    close: 36.432377,\n    volume: 34330200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-04-14',\n    open: 36.33946270379027,\n    high: 36.61820988335885,\n    low: 36.144339956840376,\n    close: 36.404503,\n    volume: 32006600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-04-15',\n    open: 36.553168255597484,\n    high: 37.12924674480191,\n    low: 36.283710824298765,\n    close: 36.934124,\n    volume: 33968700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-04-16',\n    open: 37.222164551825514,\n    high: 37.55665949035943,\n    low: 37.08278957015893,\n    close: 37.53808,\n    volume: 30615800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-04-17',\n    open: 37.175704,\n    high: 37.352247255191166,\n    low: 36.71112382181554,\n    close: 37.175704,\n    volume: 36688400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-04-21',\n    open: 37.287205322680734,\n    high: 37.30578945861581,\n    low: 36.97129080751011,\n    close: 37.110663,\n    volume: 22221200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-04-22',\n    open: 37.12924640221014,\n    high: 37.29649526406316,\n    low: 37.00845834501954,\n    close: 37.157124,\n    volume: 27056700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-04-23',\n    open: 37.15712388974225,\n    high: 37.15712388974225,\n    low: 36.67395958332912,\n    close: 36.878373,\n    volume: 24602800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-04-24',\n    open: 36.92483368860588,\n    high: 37.13853963717493,\n    low: 36.51600035242518,\n    close: 37.036332,\n    volume: 42381600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-04-25',\n    open: 37.435871866268855,\n    high: 37.79824347782511,\n    low: 36.93412434227011,\n    close: 37.08279,\n    volume: 56876800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-04-28',\n    open: 37.29649593691493,\n    high: 38.365032209684735,\n    low: 37.25003884805576,\n    close: 37.974783,\n    volume: 50610200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-04-29',\n    open: 38.188488607662535,\n    high: 38.27211396850022,\n    low: 37.528785686923904,\n    close: 37.640284,\n    volume: 29636200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-04-30',\n    open: 37.53808,\n    high: 37.63099417668346,\n    low: 37.32436940284904,\n    close: 37.53808,\n    volume: 35458700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-05-01',\n    open: 37.3894143423207,\n    high: 37.50091265516035,\n    low: 37.11995691166035,\n    close: 37.166414,\n    volume: 28787400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-05-02',\n    open: 37.45445426966055,\n    high: 37.48232815072634,\n    low: 36.850499118934216,\n    close: 36.878373,\n    volume: 43416600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-05-05',\n    open: 36.72041743241187,\n    high: 36.83191574646733,\n    low: 36.51600122402249,\n    close: 36.636793,\n    volume: 22460900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-05-06',\n    open: 36.506711885209754,\n    high: 36.56245871995728,\n    low: 36.19079735924751,\n    close: 36.293005,\n    volume: 27112400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-05-07',\n    open: 36.44167071311115,\n    high: 36.71112443346649,\n    low: 35.78196406161665,\n    close: 36.6275,\n    volume: 41744500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-05-08',\n    open: 36.553168819202035,\n    high: 37.073500482778314,\n    low: 36.20938041274714,\n    close: 36.831916,\n    volume: 32120400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-05-09',\n    open: 36.739001,\n    high: 37.02703791970056,\n    low: 36.58104188290231,\n    close: 36.739001,\n    volume: 29647600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-05-12',\n    open: 36.92483504358886,\n    high: 37.184998089442125,\n    low: 36.84121061010436,\n    close: 37.138541,\n    volume: 22782600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-05-13',\n    open: 37.35375334448997,\n    high: 37.89647009631222,\n    low: 37.28825327271856,\n    close: 37.821611,\n    volume: 27004800,\n    split: '',\n    dividend: '$0.280',\n  },\n  {\n    date: '2014-05-14',\n    open: 37.709326111534835,\n    high: 37.84968527966738,\n    low: 37.47539728369829,\n    close: 37.653186,\n    volume: 18818700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-05-15',\n    open: 37.512827380698354,\n    high: 37.8029010028902,\n    low: 36.97011062074675,\n    close: 37.054325,\n    volume: 37793200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-05-16',\n    open: 37.119824806207994,\n    high: 37.27889828175254,\n    low: 36.7455405503118,\n    close: 37.269543,\n    volume: 29867100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-05-19',\n    open: 37.06368479080966,\n    high: 37.26018407245284,\n    low: 36.92332562126582,\n    close: 37.194684,\n    volume: 24537400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-05-20',\n    open: 37.129184,\n    high: 37.37246904815565,\n    low: 36.92332569331694,\n    close: 37.129184,\n    volume: 21320900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-05-21',\n    open: 37.24146950004528,\n    high: 37.756112,\n    low: 37.185329386936374,\n    close: 37.756112,\n    volume: 22398700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-05-22',\n    open: 37.6999717205019,\n    high: 37.756111833363036,\n    low: 37.28825416663697,\n    close: 37.522183,\n    volume: 20201800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-05-23',\n    open: 37.774826831852664,\n    high: 37.774826831852664,\n    low: 37.42861309642605,\n    close: 37.540898,\n    volume: 18020000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-05-27',\n    open: 37.67189613533472,\n    high: 37.67189613533472,\n    low: 37.2508270571591,\n    close: 37.606397,\n    volume: 26160600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-05-28',\n    open: 37.55961192704963,\n    high: 37.606397692947446,\n    low: 37.26018396101894,\n    close: 37.437968,\n    volume: 25711500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-05-29',\n    open: 37.56897196067208,\n    high: 37.75611128176717,\n    low: 37.344398412493796,\n    close: 37.746756,\n    volume: 19888200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-05-30',\n    open: 37.84968536780335,\n    high: 38.33625733083638,\n    low: 37.66254136938303,\n    close: 38.308184,\n    volume: 34567600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-06-02',\n    open: 38.31754345183343,\n    high: 38.44854266147236,\n    low: 38.064899378649194,\n    close: 38.167829,\n    volume: 18504300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-06-03',\n    open: 37.99003994068052,\n    high: 38.06489903735669,\n    low: 37.662541451661916,\n    close: 37.699971,\n    volume: 18068900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-06-04',\n    open: 37.62511138100096,\n    high: 37.774825829413665,\n    low: 37.29761289652879,\n    close: 37.728041,\n    volume: 23209000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-06-05',\n    open: 37.98068444335561,\n    high: 38.59825654812562,\n    low: 37.802900405837285,\n    close: 38.560827,\n    volume: 31865200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-06-06',\n    open: 38.813471,\n    high: 38.98189975554484,\n    low: 38.58890119737083,\n    close: 38.813471,\n    volume: 24060500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-06-09',\n    open: 38.729256904846814,\n    high: 38.81347222098376,\n    low: 38.383043165495515,\n    close: 38.616972,\n    volume: 15019200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-06-10',\n    open: 38.39239790441121,\n    high: 38.51404182938356,\n    low: 38.23332817450569,\n    close: 38.467257,\n    volume: 15117700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-06-11',\n    open: 38.29882713512416,\n    high: 38.42982727680305,\n    low: 38.149112687491126,\n    close: 38.233328,\n    volume: 18040000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-06-12',\n    open: 38.18654258472754,\n    high: 38.25204265616667,\n    low: 37.69997062546544,\n    close: 37.971329,\n    volume: 29818900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-06-13',\n    open: 38.45789713899869,\n    high: 38.8976852034926,\n    low: 38.233328273091,\n    close: 38.579542,\n    volume: 26310000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-06-16',\n    open: 38.401757886076766,\n    high: 38.935115621498454,\n    low: 38.401757886076766,\n    close: 38.832186,\n    volume: 24205300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-06-17',\n    open: 38.63568695658866,\n    high: 39.21582952615163,\n    low: 37.74675645633398,\n    close: 39.000615,\n    volume: 22518600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-06-18',\n    open: 38.93511445239652,\n    high: 39.056758376748405,\n    low: 38.53275593888326,\n    close: 38.972544,\n    volume: 27097000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-06-19',\n    open: 38.89768579054135,\n    high: 39.08482885424374,\n    low: 38.67311598552912,\n    close: 38.841541,\n    volume: 19828200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-06-20',\n    open: 38.785401409563704,\n    high: 39.140974171094776,\n    low: 38.719901336387125,\n    close: 39.000615,\n    volume: 47764900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-06-23',\n    open: 39.047400146349126,\n    high: 39.30004328173169,\n    low: 39.00997059798454,\n    close: 39.290688,\n    volume: 18743900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-06-24',\n    open: 39.14097409777796,\n    high: 39.243899976859524,\n    low: 38.88833002314048,\n    close: 39.066115,\n    volume: 26509100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-06-25',\n    open: 39.01932981554708,\n    high: 39.34682830641719,\n    low: 38.794756267110216,\n    close: 39.328114,\n    volume: 20049100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-06-26',\n    open: 39.23454328105121,\n    high: 39.243899498515255,\n    low: 38.76668562208327,\n    close: 39.038044,\n    volume: 23604400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-06-27',\n    open: 38.935115135005255,\n    high: 39.571401548259686,\n    low: 38.84154079649837,\n    close: 39.533972,\n    volume: 74640000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-06-30',\n    open: 39.45911238446593,\n    high: 39.49654193223331,\n    low: 39.019329,\n    close: 39.019329,\n    volume: 30793100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-07-01',\n    open: 39.16904371835306,\n    high: 39.44040209331742,\n    low: 39.00997024460404,\n    close: 39.178399,\n    volume: 26917000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-07-02',\n    open: 39.04739952733176,\n    high: 39.206473,\n    low: 38.86025553133689,\n    close: 39.206473,\n    volume: 20208100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-07-03',\n    open: 39.21582962238827,\n    high: 39.29068872049016,\n    low: 38.888330191417,\n    close: 39.1129,\n    volume: 15969300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-07-07',\n    open: 39.066114452673766,\n    high: 39.41232818396418,\n    low: 39.02868490430918,\n    close: 39.290688,\n    volume: 21952400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-07-08',\n    open: 39.1783993785116,\n    high: 39.30004330541033,\n    low: 38.935115267575405,\n    close: 39.094185,\n    volume: 31218200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-07-09',\n    open: 39.28132962425388,\n    high: 39.29068864900142,\n    low: 38.860256789279035,\n    close: 38.991256,\n    volume: 18445900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-07-10',\n    open: 38.710541103395805,\n    high: 39.30004267930062,\n    low: 38.41111220679161,\n    close: 39.00997,\n    volume: 21854700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-07-11',\n    open: 39.01932995923635,\n    high: 39.384258,\n    low: 38.81347165217391,\n    close: 39.384258,\n    volume: 24083000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-07-14',\n    open: 39.50590209769685,\n    high: 39.72111662321214,\n    low: 39.33747333859792,\n    close: 39.431043,\n    volume: 21881100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-07-15',\n    open: 39.60883109807776,\n    high: 39.73983030627293,\n    low: 39.32811369683793,\n    close: 39.721116,\n    volume: 28748700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-07-16',\n    open: 39.77725621104405,\n    high: 41.46154658696098,\n    low: 39.74918662299516,\n    close: 41.246333,\n    volume: 63318000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-07-17',\n    open: 42.528261960378714,\n    high: 42.77154607060733,\n    low: 41.4054026477746,\n    close: 41.667402,\n    volume: 82180300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-07-18',\n    open: 41.77969019498595,\n    high: 41.95747423131515,\n    low: 41.405402201955745,\n    close: 41.817116,\n    volume: 43407500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-07-21',\n    open: 41.695475645795604,\n    high: 42.25690390276539,\n    low: 41.37733243660738,\n    close: 41.957475,\n    volume: 37604400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-07-22',\n    open: 42.10718873043994,\n    high: 42.24754789763868,\n    low: 41.72354545534038,\n    close: 41.948119,\n    volume: 43095800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-07-23',\n    open: 42.528261750920585,\n    high: 42.528261750920585,\n    low: 41.75161617263363,\n    close: 41.985545,\n    volume: 52362900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-07-24',\n    open: 42.04168924722121,\n    high: 42.10718931949598,\n    low: 41.47090290311248,\n    close: 41.545762,\n    volume: 30725300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-07-25',\n    open: 41.452187999116134,\n    high: 41.78904645213483,\n    low: 41.452187999116134,\n    close: 41.639332,\n    volume: 26737700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-07-28',\n    open: 41.50833297873711,\n    high: 41.6486874711054,\n    low: 41.105974451080854,\n    close: 41.143404,\n    volume: 29684200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-07-29',\n    open: 41.087260242361815,\n    high: 41.255689002180205,\n    low: 40.83461616691892,\n    close: 41.068545,\n    volume: 27763100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-07-30',\n    open: 41.23697362955605,\n    high: 41.26504321736952,\n    low: 40.50711662492523,\n    close: 40.778475,\n    volume: 31921400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-07-31',\n    open: 40.591331305038764,\n    high: 40.881401181291174,\n    low: 40.310617646222106,\n    close: 40.385473,\n    volume: 31537500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-08-01',\n    open: 40.432257486070554,\n    high: 40.469687034071704,\n    low: 39.86147021299608,\n    close: 40.104759,\n    volume: 31170300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-08-04',\n    open: 40.20768774797464,\n    high: 40.67554540229462,\n    low: 40.05797329859224,\n    close: 40.581972,\n    volume: 34277400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-08-05',\n    open: 40.525831588647975,\n    high: 40.66618701571514,\n    low: 40.07668916917032,\n    close: 40.310618,\n    volume: 26266400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-08-06',\n    open: 39.992474,\n    high: 40.39482783821705,\n    low: 39.49654208129252,\n    close: 39.992474,\n    volume: 24634000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-08-07',\n    open: 40.086044027758504,\n    high: 40.65683130467205,\n    low: 39.908259989635575,\n    close: 40.450973,\n    volume: 30314900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-08-08',\n    open: 40.450972523357116,\n    high: 40.535186900574374,\n    low: 40.15154362658463,\n    close: 40.422902,\n    volume: 28942700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-08-11',\n    open: 40.47904211099893,\n    high: 40.6568308256035,\n    low: 40.25447230985018,\n    close: 40.422902,\n    volume: 20351600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-08-12',\n    open: 40.27318857909767,\n    high: 40.78783107284007,\n    low: 40.235759030330875,\n    close: 40.722331,\n    volume: 21431100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-08-13',\n    open: 40.87204500217582,\n    high: 41.33990266016775,\n    low: 40.7223305516184,\n    close: 41.246333,\n    volume: 22889500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-08-14',\n    open: 41.24633395726758,\n    high: 41.56447342922439,\n    low: 41.1808301407672,\n    close: 41.424118,\n    volume: 19313200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-08-15',\n    open: 41.714190719070984,\n    high: 42.01361962062426,\n    low: 41.54576196194727,\n    close: 41.91069,\n    volume: 41611300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-08-18',\n    open: 42.05104552424819,\n    high: 42.210119,\n    low: 41.807760476884056,\n    close: 42.210119,\n    volume: 26891100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-08-19',\n    open: 42.341936598875485,\n    high: 42.690312712979804,\n    low: 42.21011919504874,\n    close: 42.680899,\n    volume: 28139500,\n    split: '',\n    dividend: '$0.280',\n  },\n  {\n    date: '2014-08-20',\n    open: 42.69031230277392,\n    high: 42.74680776194443,\n    low: 42.27602796151684,\n    close: 42.323105,\n    volume: 24770500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-08-21',\n    open: 42.219533402487095,\n    high: 42.60557284706826,\n    low: 42.21011968939704,\n    close: 42.577327,\n    volume: 22285500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-08-22',\n    open: 42.69972615454511,\n    high: 42.81271613169404,\n    low: 42.43609134856738,\n    close: 42.511418,\n    volume: 18294500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-08-25',\n    open: 42.74680847806307,\n    high: 42.78446803804937,\n    low: 42.40784607451711,\n    close: 42.530246,\n    volume: 16910000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-08-26',\n    open: 42.66206771325777,\n    high: 42.746809021391066,\n    low: 42.31368876755788,\n    close: 42.379597,\n    volume: 14873100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-08-27',\n    open: 42.276028613139886,\n    high: 42.370182691557446,\n    low: 42.14420650074992,\n    close: 42.247779,\n    volume: 21287900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-08-28',\n    open: 42.134792309830836,\n    high: 42.35135101890929,\n    low: 42.00297490673398,\n    close: 42.257196,\n    volume: 17657600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-08-29',\n    open: 42.45492273321594,\n    high: 42.784467654522274,\n    low: 42.238364964892206,\n    close: 42.775053,\n    volume: 21607600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-09-02',\n    open: 42.77505326879574,\n    high: 42.80329911565928,\n    low: 42.22894680949554,\n    close: 42.454923,\n    volume: 22976800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-09-03',\n    open: 41.92764836888632,\n    high: 42.47375482420537,\n    low: 41.92764836888632,\n    close: 42.332519,\n    volume: 33684500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-09-04',\n    open: 42.12537876979075,\n    high: 42.62440347920475,\n    low: 42.10654663606009,\n    close: 42.614986,\n    volume: 26475500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-09-05',\n    open: 42.47375524824661,\n    high: 43.245833192332825,\n    low: 42.47375524824661,\n    close: 43.227002,\n    volume: 36939400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-09-08',\n    open: 43.33057323411721,\n    high: 44.06498878805111,\n    low: 43.302328328948214,\n    close: 43.754276,\n    volume: 45736700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-09-09',\n    open: 43.75427653455687,\n    high: 44.22505634511204,\n    low: 43.707195728822484,\n    close: 44.027326,\n    volume: 40302400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-09-10',\n    open: 44.08382080785653,\n    high: 44.196807019157724,\n    low: 43.57537767842331,\n    close: 44.102652,\n    volume: 27302400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-09-11',\n    open: 44.008498382693695,\n    high: 44.253302,\n    low: 43.75427634453834,\n    close: 44.253302,\n    volume: 29216400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-09-12',\n    open: 44.16856157776099,\n    high: 44.27213313550037,\n    low: 43.87667621373991,\n    close: 43.970835,\n    volume: 38244700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-09-15',\n    open: 43.820184939821544,\n    high: 43.98024818948499,\n    low: 43.40589588911705,\n    close: 43.537718,\n    volume: 37667600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-09-16',\n    open: 43.6789498817488,\n    high: 44.11206636589993,\n    low: 43.584795802757,\n    close: 44.027326,\n    volume: 27910600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-09-17',\n    open: 43.556546613011434,\n    high: 43.96141819558568,\n    low: 43.528301707222695,\n    close: 43.801354,\n    volume: 38311900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-09-18',\n    open: 43.86726263431876,\n    high: 44.09323882592129,\n    low: 43.7448589423307,\n    close: 43.952003,\n    volume: 35556600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-09-19',\n    open: 44.07440661348723,\n    high: 44.78999098085017,\n    low: 43.87667626923767,\n    close: 44.742913,\n    volume: 202522400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-09-22',\n    open: 44.53576942742103,\n    high: 44.61109608072038,\n    low: 44.23447128826028,\n    close: 44.309797,\n    volume: 38686100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-09-23',\n    open: 44.11206646606313,\n    high: 44.23447110020466,\n    low: 43.75427663390766,\n    close: 43.839017,\n    volume: 33430300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-09-24',\n    open: 43.904925237017366,\n    high: 44.356873846535265,\n    low: 43.6318720105407,\n    close: 44.328628,\n    volume: 26582700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-09-25',\n    open: 44.140315065358166,\n    high: 44.33804164013811,\n    low: 43.339987520864625,\n    close: 43.349405,\n    volume: 33077400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-09-26',\n    open: 43.245832392372336,\n    high: 43.89550757427751,\n    low: 43.08576537738501,\n    close: 43.697781,\n    volume: 27078800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-09-29',\n    open: 43.29291052439515,\n    high: 43.83901603542298,\n    low: 43.08576552871903,\n    close: 43.726027,\n    volume: 26091000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-09-30',\n    open: 43.66011771288132,\n    high: 43.76369021044671,\n    low: 43.321155315302775,\n    close: 43.650704,\n    volume: 33033100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-10-01',\n    open: 43.56596317272491,\n    high: 43.81076772986658,\n    low: 43.170506253242074,\n    close: 43.217588,\n    volume: 38088400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-10-02',\n    open: 43.15167893913657,\n    high: 43.40589626836233,\n    low: 42.97277978801996,\n    close: 43.085766,\n    volume: 25119400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-10-03',\n    open: 43.292911441527444,\n    high: 43.59420957916071,\n    low: 42.94453532277029,\n    close: 43.396483,\n    volume: 32453200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-10-06',\n    open: 43.424728847114714,\n    high: 43.59420957916071,\n    low: 43.23641598105954,\n    close: 43.396483,\n    volume: 20604000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-10-07',\n    open: 43.1799245536818,\n    high: 43.24583278466578,\n    low: 42.765635501586196,\n    close: 42.869208,\n    volume: 25723700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-10-08',\n    open: 42.822131437839495,\n    high: 44.149729558007095,\n    low: 42.69031309128503,\n    close: 44.046158,\n    volume: 33031000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-10-09',\n    open: 43.782522640459,\n    high: 44.064989586902335,\n    low: 43.06693920730409,\n    close: 43.170507,\n    volume: 34422800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-10-10',\n    open: 42.93511665731044,\n    high: 43.42472859976969,\n    low: 41.38154611375006,\n    close: 41.456869,\n    volume: 51978100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-10-13',\n    open: 41.25914225112751,\n    high: 41.955897306466994,\n    low: 40.94842946188543,\n    close: 41.099079,\n    volume: 37100200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-10-14',\n    open: 41.30621840145436,\n    high: 41.786415676981505,\n    low: 41.014336810756944,\n    close: 41.174401,\n    volume: 38115700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-10-15',\n    open: 40.48706394060472,\n    high: 40.85427125339012,\n    low: 39.63965839361235,\n    close: 40.694208,\n    volume: 60218700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-10-16',\n    open: 40.04452866024061,\n    high: 40.56238926251145,\n    low: 39.75264706871701,\n    close: 40.242259,\n    volume: 49040400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-10-17',\n    open: 40.67537636499818,\n    high: 41.37212859792859,\n    low: 40.28933692232202,\n    close: 41.080247,\n    volume: 40683300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-10-20',\n    open: 40.543557267623285,\n    high: 41.56043975125163,\n    low: 40.30816736791321,\n    close: 41.503949,\n    volume: 34527900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-10-21',\n    open: 41.76758500556174,\n    high: 42.35135101890929,\n    low: 41.607517989645416,\n    close: 42.257196,\n    volume: 36433800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-10-22',\n    open: 42.37018302455649,\n    high: 42.43609219815024,\n    low: 41.645182115025186,\n    close: 41.786417,\n    volume: 33570900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-10-23',\n    open: 42.01238921126135,\n    high: 42.793885577277074,\n    low: 41.92764884564606,\n    close: 42.389014,\n    volume: 45451900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-10-24',\n    open: 44.0932386723402,\n    high: 44.15914784541826,\n    low: 42.53966342380959,\n    close: 43.434146,\n    volume: 61076700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-10-27',\n    open: 43.038689135112136,\n    high: 43.405896444042604,\n    low: 43.038689135112136,\n    close: 43.227002,\n    volume: 30371300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-10-28',\n    open: 43.17992450620045,\n    high: 43.78252171294809,\n    low: 43.095183200035144,\n    close: 43.773108,\n    volume: 29049800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-10-29',\n    open: 43.726027270495905,\n    high: 43.9708346517877,\n    low: 43.63187225121991,\n    close: 43.895508,\n    volume: 30276100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-10-30',\n    open: 43.6130410356795,\n    high: 43.6130410356795,\n    low: 43.0951832513612,\n    close: 43.358819,\n    volume: 30073900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-10-31',\n    open: 44.19680752070219,\n    high: 44.225056192357165,\n    low: 43.76369103804705,\n    close: 44.206225,\n    volume: 35849700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-11-03',\n    open: 44.14972921399962,\n    high: 44.68641819221819,\n    low: 43.99908061781367,\n    close: 44.667587,\n    volume: 23130400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-11-04',\n    open: 44.53576796741665,\n    high: 44.94063953542148,\n    low: 44.48869092915704,\n    close: 44.78999,\n    volume: 21530800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-11-05',\n    open: 45.00654854012552,\n    high: 45.100707326063116,\n    low: 44.498105407768634,\n    close: 45.063044,\n    volume: 22449600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-11-06',\n    open: 45.06304392671273,\n    high: 46.004603537769,\n    low: 44.99713475393879,\n    close: 45.853954,\n    volume: 33037800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-11-07',\n    open: 46.06109442419383,\n    high: 46.06109442419383,\n    low: 45.467914692175874,\n    close: 45.835122,\n    volume: 28000600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-11-10',\n    open: 45.80687751529097,\n    high: 46.27765732651576,\n    low: 45.71271872836714,\n    close: 46.032849,\n    volume: 36370100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-11-11',\n    open: 45.9951848663219,\n    high: 46.089343651593225,\n    low: 45.8068767113753,\n    close: 46.014017,\n    volume: 23445200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-11-12',\n    open: 45.72213576817165,\n    high: 46.06109440431612,\n    low: 45.684472442076114,\n    close: 45.929277,\n    volume: 22722100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-11-13',\n    open: 45.957525315122915,\n    high: 46.74843632580347,\n    low: 45.86336747139407,\n    close: 46.710773,\n    volume: 26210400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-11-14',\n    open: 46.83317653648045,\n    high: 47.12505718873253,\n    low: 46.503627850750654,\n    close: 46.682527,\n    volume: 29081700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-11-17',\n    open: 46.52246096042177,\n    high: 46.80492790568925,\n    low: 46.26823892071777,\n    close: 46.569538,\n    volume: 30318600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-11-18',\n    open: 46.55058734919756,\n    high: 46.740087936026924,\n    low: 46.14316312463557,\n    close: 46.181064,\n    volume: 23995500,\n    split: '',\n    dividend: '$0.310',\n  },\n  {\n    date: '2014-11-19',\n    open: 46.1052622591194,\n    high: 46.19053709683664,\n    low: 45.41358857541292,\n    close: 45.688364,\n    volume: 26177500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-11-20',\n    open: 45.479913316634224,\n    high: 46.143163,\n    low: 45.35673760390348,\n    close: 46.143163,\n    volume: 21510600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-11-21',\n    open: 46.44636111421426,\n    high: 46.47478511231841,\n    low: 45.07248874343477,\n    close: 45.460963,\n    volume: 42884800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-11-24',\n    open: 45.47044118056061,\n    high: 45.47991426770329,\n    low: 44.90193940971969,\n    close: 45.09144,\n    volume: 35434200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-11-25',\n    open: 45.15776471249705,\n    high: 45.451490105250706,\n    low: 44.95879103578997,\n    close: 44.977741,\n    volume: 28008000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-11-26',\n    open: 44.99669136326865,\n    high: 45.47044046274509,\n    low: 44.79771389899395,\n    close: 45.243039,\n    volume: 27163600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-11-28',\n    open: 45.43253974832357,\n    high: 45.669414298901394,\n    low: 45.11039035953774,\n    close: 45.29989,\n    volume: 21534400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-12-01',\n    open: 45.36621521994194,\n    high: 46.21896171352529,\n    low: 45.20513862932491,\n    close: 46.067362,\n    volume: 31191600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-12-02',\n    open: 46.275812264874375,\n    high: 46.474785940136684,\n    low: 45.66941436205481,\n    close: 45.915762,\n    volume: 25773500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-12-03',\n    open: 45.89681150687733,\n    high: 45.9536623459375,\n    low: 45.299889540472876,\n    close: 45.555715,\n    volume: 23534800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-12-04',\n    open: 45.84943686331261,\n    high: 46.4842625511018,\n    low: 45.66941410065135,\n    close: 46.275812,\n    volume: 30320400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-12-05',\n    open: 46.25686217541769,\n    high: 46.39898785307387,\n    low: 45.839963914452476,\n    close: 45.877861,\n    volume: 27313400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-12-08',\n    open: 45.72626114847817,\n    high: 45.81153598631308,\n    low: 44.95879045045859,\n    close: 45.195665,\n    volume: 26663100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-12-09',\n    open: 44.636641804821174,\n    high: 45.40411251559403,\n    low: 44.57979001699012,\n    close: 45.09144,\n    volume: 24330500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-12-10',\n    open: 45.08196576911306,\n    high: 45.157763729306446,\n    low: 44.24816641452738,\n    close: 44.437667,\n    volume: 30431800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-12-11',\n    open: 44.60821695237249,\n    high: 45.23356576158803,\n    low: 44.22921577906364,\n    close: 44.693488,\n    volume: 29060400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-12-12',\n    open: 44.32396441258775,\n    high: 45.22408864123347,\n    low: 44.21973866411458,\n    close: 44.485041,\n    volume: 34248400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-12-15',\n    open: 44.72191588737027,\n    high: 45.16723719787864,\n    low: 44.10604016375276,\n    close: 44.219739,\n    volume: 29247800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-12-16',\n    open: 43.49016956771564,\n    high: 43.90706688352525,\n    low: 42.76059500130689,\n    close: 42.789019,\n    volume: 47801400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-12-17',\n    open: 42.68479240799839,\n    high: 43.537542671917,\n    low: 42.54267052233924,\n    close: 43.338569,\n    volume: 34970900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-12-18',\n    open: 44.13446857639373,\n    high: 45.025115,\n    low: 43.907067110690235,\n    close: 45.025115,\n    volume: 40105600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-12-19',\n    open: 45.12934000163164,\n    high: 45.57466131104641,\n    low: 44.69348798918322,\n    close: 45.157764,\n    volume: 64551200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-12-22',\n    open: 45.27146241515292,\n    high: 45.593611798646045,\n    low: 45.20513754208081,\n    close: 45.460963,\n    volume: 26566000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-12-23',\n    open: 45.83048724857015,\n    high: 46.23791147689989,\n    low: 45.60308957426624,\n    close: 45.906289,\n    volume: 23648100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-12-24',\n    open: 46.086312106226615,\n    high: 46.086312106226615,\n    low: 45.555715949747444,\n    close: 45.612563,\n    volume: 11437800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-12-26',\n    open: 45.868388101119706,\n    high: 45.868388101119706,\n    low: 45.309364160205426,\n    close: 45.366215,\n    volume: 13197800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-12-29',\n    open: 45.195664547168086,\n    high: 45.27146250726549,\n    low: 44.778762501657695,\n    close: 44.95879,\n    volume: 14439500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-12-30',\n    open: 44.94931430218277,\n    high: 45.11986398061748,\n    low: 44.38081632156529,\n    close: 44.551366,\n    volume: 16384700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2014-12-31',\n    open: 44.27659054646737,\n    high: 44.949313315810436,\n    low: 44.011292,\n    close: 44.011292,\n    volume: 21552500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-01-02',\n    open: 44.21026607486167,\n    high: 44.930362812889165,\n    low: 44.096567238198205,\n    close: 44.305014,\n    volume: 27913900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-01-05',\n    open: 43.935490085072885,\n    high: 44.27659038067816,\n    low: 43.82179124986871,\n    close: 43.897593,\n    volume: 39673900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-01-06',\n    open: 43.94496672690823,\n    high: 44.29554010753384,\n    low: 43.14906825224879,\n    close: 43.253294,\n    volume: 36447900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-01-07',\n    open: 43.565966454250486,\n    high: 44.02076463459138,\n    low: 43.10169423957781,\n    close: 43.802841,\n    volume: 29114100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-01-08',\n    open: 44.29554150031519,\n    high: 45.243039714225674,\n    low: 44.267117501396086,\n    close: 45.09144,\n    volume: 29645200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-01-09',\n    open: 45.11039013801291,\n    high: 45.30936381202297,\n    low: 44.437667365173674,\n    close: 44.712439,\n    volume: 23944200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-01-12',\n    open: 44.93036353763728,\n    high: 45.04406616612762,\n    low: 43.92601827050325,\n    close: 44.153415,\n    volume: 23651900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-01-13',\n    open: 44.50399089542766,\n    high: 45.39463824580159,\n    low: 43.641767543232305,\n    close: 43.926017,\n    volume: 35270600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-01-14',\n    open: 43.547017,\n    high: 43.812319342609946,\n    low: 43.224867607002835,\n    close: 43.547017,\n    volume: 29675300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-01-15',\n    open: 43.79336761328537,\n    high: 43.94496732480691,\n    low: 43.025893126209326,\n    close: 43.092218,\n    volume: 32750800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-01-16',\n    open: 42.9311437398363,\n    high: 43.85021508493191,\n    low: 42.79849115134908,\n    close: 43.812318,\n    volume: 35695300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-01-20',\n    open: 43.86916616112794,\n    high: 44.20079337701391,\n    low: 43.17749341555278,\n    close: 43.954441,\n    volume: 36161900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-01-21',\n    open: 43.52806691173819,\n    high: 43.717566554138,\n    low: 43.09221868171684,\n    close: 43.509116,\n    volume: 39081100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-01-22',\n    open: 43.94496735180615,\n    high: 44.66506408697953,\n    low: 43.6607188400268,\n    close: 44.655591,\n    volume: 35898000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-01-23',\n    open: 44.87351562320824,\n    high: 44.901938674163524,\n    low: 44.34291473711392,\n    close: 44.702965,\n    volume: 26211600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-01-26',\n    open: 44.53241591288729,\n    high: 44.65559162780413,\n    low: 43.81231916759021,\n    close: 44.541889,\n    volume: 42525500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-01-27',\n    open: 40.695048424057035,\n    high: 40.931922972814654,\n    low: 39.89914994023144,\n    close: 40.420273,\n    volume: 169164000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-01-28',\n    open: 40.49607505586247,\n    high: 40.543449018472906,\n    low: 38.999026001433016,\n    close: 39.02745,\n    volume: 84507100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-01-29',\n    open: 38.78110182580822,\n    high: 39.90862375084145,\n    low: 38.64845302359685,\n    close: 39.804398,\n    volume: 63585300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-01-30',\n    open: 39.368549082524076,\n    high: 39.396976870888714,\n    low: 38.231550300223795,\n    close: 38.278929,\n    volume: 78004900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-02-02',\n    open: 38.45895218529439,\n    high: 39.19799983854833,\n    low: 38.11785283110108,\n    close: 39.112725,\n    volume: 50352500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-02-03',\n    open: 39.44435178905354,\n    high: 39.72860030714424,\n    low: 38.894800927251865,\n    close: 39.415924,\n    volume: 52082400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-02-04',\n    open: 39.73807387324748,\n    high: 39.99389838926087,\n    low: 39.18852680791885,\n    close: 39.643325,\n    volume: 41614800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-02-05',\n    open: 40.003374416912244,\n    high: 40.40132176059787,\n    low: 39.66227506947053,\n    close: 40.221299,\n    volume: 36548200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-02-06',\n    open: 40.439223516151856,\n    high: 40.54344926652674,\n    low: 39.937051360924265,\n    close: 40.183399,\n    volume: 34616600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-02-09',\n    open: 40.022325165479764,\n    high: 40.49607425722318,\n    low: 39.993897377480614,\n    close: 40.136024,\n    volume: 31381100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-02-10',\n    open: 40.49607553988251,\n    high: 40.524498591291014,\n    low: 39.96547464532745,\n    close: 40.363422,\n    volume: 29670700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-02-11',\n    open: 40.41080046364203,\n    high: 40.41080046364203,\n    low: 39.99389840965377,\n    close: 40.154975,\n    volume: 38262500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-02-12',\n    open: 40.42027376839173,\n    high: 40.827698,\n    low: 40.27814714143894,\n    close: 40.827698,\n    volume: 33268800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-02-13',\n    open: 41.10247277796257,\n    high: 41.566745,\n    low: 40.88454913991427,\n    close: 41.566745,\n    volume: 40264900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-02-17',\n    open: 41.95798711908811,\n    high: 41.98661340125684,\n    low: 41.21367706394704,\n    close: 41.585834,\n    volume: 33695700,\n    split: '',\n    dividend: '$0.310',\n  },\n  {\n    date: '2015-02-18',\n    open: 41.633545029672966,\n    high: 41.700341914506346,\n    low: 41.404525230333256,\n    close: 41.538119,\n    volume: 27111700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-02-19',\n    open: 41.20413581011494,\n    high: 41.538119282310504,\n    low: 41.08008349748292,\n    close: 41.509493,\n    volume: 27603400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-02-20',\n    open: 41.51903271716661,\n    high: 41.87210482400628,\n    low: 41.309102515821195,\n    close: 41.85302,\n    volume: 29721100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-02-23',\n    open: 41.70034150462215,\n    high: 42.167917785377426,\n    low: 41.65263039873706,\n    close: 42.129751,\n    volume: 32518800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-02-24',\n    open: 42.12975138115196,\n    high: 42.272884700102175,\n    low: 41.91027208562055,\n    close: 42.072495,\n    volume: 25271700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-02-25',\n    open: 41.93890239711908,\n    high: 42.07249521311684,\n    low: 41.79576430623774,\n    close: 41.977073,\n    volume: 29759800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-02-26',\n    open: 41.97707306901191,\n    high: 42.20608905274423,\n    low: 41.881646084532115,\n    close: 42.043869,\n    volume: 28957300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-02-27',\n    open: 42.110666406951175,\n    high: 42.177463293008046,\n    low: 41.66217207489952,\n    close: 41.843476,\n    volume: 33807700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-03-02',\n    open: 41.671712479582396,\n    high: 42.167918871922865,\n    low: 41.55720448656996,\n    close: 41.872106,\n    volume: 31924000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-03-03',\n    open: 41.56674844977606,\n    high: 41.82439453312183,\n    low: 41.118254122649134,\n    close: 41.299559,\n    volume: 31748600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-03-04',\n    open: 41.04191307614563,\n    high: 41.23276227490965,\n    low: 40.91786457992948,\n    close: 41.089628,\n    volume: 25748700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-03-05',\n    open: 41.09916839783882,\n    high: 41.26139130998113,\n    low: 40.86060809833894,\n    close: 41.137339,\n    volume: 23193500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-03-06',\n    open: 41.03237141094497,\n    high: 41.13733889670253,\n    low: 40.22126830316449,\n    close: 40.421658,\n    volume: 36248800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-03-09',\n    open: 40.259436739314786,\n    high: 41.156425408450076,\n    low: 40.259436739314786,\n    close: 40.889235,\n    volume: 32108000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-03-10',\n    open: 40.41211323218176,\n    high: 40.75564102114881,\n    low: 40.106757,\n    close: 40.106757,\n    volume: 39159700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-03-11',\n    open: 40.373946553574235,\n    high: 40.431199117697815,\n    low: 39.925452230586004,\n    close: 40.059046,\n    volume: 32215300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-03-12',\n    open: 39.438791687858355,\n    high: 39.744148879472206,\n    low: 38.99029735843429,\n    close: 39.142975,\n    volume: 59992500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-03-13',\n    open: 38.83761896444862,\n    high: 39.572384710587684,\n    low: 38.75173725386094,\n    close: 39.486503,\n    volume: 58007700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-03-16',\n    open: 39.57238429032439,\n    high: 39.73460338900699,\n    low: 39.391076550304554,\n    close: 39.658266,\n    volume: 35273500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-03-17',\n    open: 39.47695749547203,\n    high: 39.915911310259155,\n    low: 39.267027294165246,\n    close: 39.791859,\n    volume: 31673400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-03-18',\n    open: 39.53421389082354,\n    high: 40.87015351224716,\n    low: 39.43879167695304,\n    close: 40.555252,\n    volume: 44194800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-03-19',\n    open: 40.32623190078137,\n    high: 40.641133410708605,\n    low: 40.28806511484505,\n    close: 40.354862,\n    volume: 33879100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-03-20',\n    open: 40.61250681309135,\n    high: 41.01328716666774,\n    low: 40.54571088269629,\n    close: 40.917864,\n    volume: 71904500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-03-23',\n    open: 40.91786382409975,\n    high: 41.15642412534659,\n    low: 40.822437795118596,\n    close: 40.898779,\n    volume: 26246100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-03-24',\n    open: 40.822438191565816,\n    high: 41.19459131088386,\n    low: 40.7938119093794,\n    close: 40.93695,\n    volume: 25513300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-03-25',\n    open: 40.956031226009436,\n    high: 40.96557554668537,\n    low: 39.543755175613,\n    close: 39.56284,\n    volume: 43469900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-03-26',\n    open: 39.333824320749926,\n    high: 39.70597839918122,\n    low: 39.04754909000216,\n    close: 39.32428,\n    volume: 37495600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-03-27',\n    open: 39.2383982754781,\n    high: 39.53421400990447,\n    low: 38.961671182544706,\n    close: 39.095264,\n    volume: 34401400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-03-30',\n    open: 39.21931181513363,\n    high: 39.63918081017821,\n    low: 39.03800789375018,\n    close: 39.085719,\n    volume: 35049700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-03-31',\n    open: 38.91395599214343,\n    high: 39.15251629711146,\n    low: 38.68494000785656,\n    close: 38.799448,\n    volume: 34887200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-04-01',\n    open: 38.742191192151346,\n    high: 38.89486978565138,\n    low: 38.46546410415616,\n    close: 38.856703,\n    volume: 36865300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-04-02',\n    open: 38.79944729065656,\n    high: 38.875788495333076,\n    low: 38.28415608710512,\n    close: 38.446379,\n    volume: 37487500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-04-06',\n    open: 38.49409107037524,\n    high: 39.86819748205717,\n    low: 38.34141247416155,\n    close: 39.648722,\n    volume: 39223700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-04-07',\n    open: 39.705978206251274,\n    high: 39.99224961864314,\n    low: 39.41970583961818,\n    close: 39.629637,\n    volume: 28809400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-04-08',\n    open: 39.56283960263183,\n    high: 39.78231508087787,\n    low: 39.162060203012786,\n    close: 39.524669,\n    volume: 24753400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-04-09',\n    open: 39.36244952386692,\n    high: 39.7155178138398,\n    low: 39.36244952386692,\n    close: 39.581925,\n    volume: 25723900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-04-10',\n    open: 39.72506328945066,\n    high: 40.03042048251496,\n    low: 39.515129264977716,\n    close: 39.810945,\n    volume: 28022000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-04-13',\n    open: 39.50558897292629,\n    high: 40.135387232755896,\n    low: 39.49604369786818,\n    close: 39.849112,\n    volume: 30276700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-04-14',\n    open: 39.88728131767802,\n    high: 40.10675679429384,\n    low: 39.49604242458025,\n    close: 39.744148,\n    volume: 24244400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-04-15',\n    open: 39.849111390576404,\n    high: 40.51708119801066,\n    low: 39.77277400155106,\n    close: 40.326232,\n    volume: 27343600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-04-16',\n    open: 40.03042029722035,\n    high: 40.40257342030361,\n    low: 39.90636798387097,\n    close: 40.23081,\n    volume: 22509700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-04-17',\n    open: 39.76322910601137,\n    high: 39.83002980732979,\n    low: 39.27656799991754,\n    close: 39.715518,\n    volume: 42387600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-04-20',\n    open: 39.82048538103006,\n    high: 41.19459080417199,\n    low: 39.772773320904214,\n    close: 40.94649,\n    volume: 46057700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-04-21',\n    open: 41.032372796256396,\n    high: 41.17551088891184,\n    low: 40.5838784649398,\n    close: 40.688845,\n    volume: 26013800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-04-22',\n    open: 40.71746999975338,\n    high: 41.1564238134446,\n    low: 40.602962010263894,\n    close: 41.022831,\n    volume: 25064300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-04-23',\n    open: 40.92740450168865,\n    high: 41.61446008068329,\n    low: 40.84152279287461,\n    close: 41.356814,\n    volume: 46309500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-04-24',\n    open: 43.57065386945172,\n    high: 45.93717112800596,\n    low: 43.56111336578578,\n    close: 45.679526,\n    volume: 130933700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-04-27',\n    open: 45.06881199227175,\n    high: 45.927630028728586,\n    low: 45.059270534488334,\n    close: 45.832204,\n    volume: 59248200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-04-28',\n    open: 45.59364417269125,\n    high: 46.95820910637718,\n    low: 45.51730678418426,\n    close: 46.910498,\n    volume: 60730800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-04-29',\n    open: 46.49063298663763,\n    high: 47.05363530394292,\n    low: 46.28069896492664,\n    close: 46.815075,\n    volume: 47804600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-04-30',\n    open: 46.47154838169902,\n    high: 47.27311100673114,\n    low: 46.376121396947724,\n    close: 46.414292,\n    volume: 64725500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-05-01',\n    open: 46.35703961214045,\n    high: 46.64331101918161,\n    low: 46.18527619537103,\n    close: 46.433377,\n    volume: 38937300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-05-04',\n    open: 46.15664649490276,\n    high: 46.63376710115813,\n    low: 45.97534161876693,\n    close: 46.032598,\n    volume: 34039500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-05-05',\n    open: 45.631814976126684,\n    high: 45.95625698975869,\n    low: 45.14515290991987,\n    close: 45.42188,\n    volume: 50369200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-05-06',\n    open: 45.39325410832442,\n    high: 45.58410234926756,\n    low: 43.91418024101514,\n    close: 44.162282,\n    volume: 52433000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-05-07',\n    open: 44.152741320498045,\n    high: 44.93521912215805,\n    low: 44.04777478612902,\n    close: 44.563066,\n    volume: 32971700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-05-08',\n    open: 45.37416880282685,\n    high: 45.784493479371726,\n    low: 45.34554252062828,\n    close: 45.565018,\n    volume: 35364900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-05-11',\n    open: 45.37416841717887,\n    high: 45.717696205777834,\n    low: 45.202405,\n    close: 45.202405,\n    volume: 24609400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-05-12',\n    open: 44.70619938850599,\n    high: 45.4982215120685,\n    low: 44.29587566262115,\n    close: 45.18332,\n    volume: 29928300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-05-13',\n    open: 45.98488317162727,\n    high: 46.10893548375109,\n    low: 45.39325457288989,\n    close: 45.45051,\n    volume: 34184600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-05-14',\n    open: 45.83220465244585,\n    high: 46.58605616736338,\n    low: 45.83220465244585,\n    close: 46.490633,\n    volume: 32980900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-05-15',\n    open: 46.63376749573328,\n    high: 46.67193809879788,\n    low: 45.85128969485382,\n    close: 46.08985,\n    volume: 28642700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-05-18',\n    open: 45.78449367192225,\n    high: 46.01351251864495,\n    low: 45.43142537525452,\n    close: 45.813119,\n    volume: 24136500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-05-19',\n    open: 45.67865918412254,\n    high: 45.91876987705609,\n    low: 45.31368997042076,\n    close: 45.697869,\n    volume: 28574800,\n    split: '',\n    dividend: '$0.310',\n  },\n  {\n    date: '2015-05-20',\n    open: 45.51538199204218,\n    high: 46.03402204922143,\n    low: 45.400129819876845,\n    close: 45.697869,\n    volume: 25047900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-05-21',\n    open: 45.40973397037691,\n    high: 45.717074701513276,\n    low: 45.15041345766422,\n    close: 45.544195,\n    volume: 22410700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-05-22',\n    open: 45.42894222808843,\n    high: 45.47696340632275,\n    low: 44.9679306572311,\n    close: 45.044768,\n    volume: 25720600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-05-26',\n    open: 44.97753718746636,\n    high: 45.02555836589459,\n    low: 44.3628509285892,\n    close: 44.747029,\n    volume: 29581900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-05-27',\n    open: 44.96793025524196,\n    high: 45.88035088195021,\n    low: 44.77584074180799,\n    close: 45.726681,\n    volume: 27335600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-05-28',\n    open: 45.62103217869269,\n    high: 46.12046242570153,\n    low: 45.51538251215188,\n    close: 45.573011,\n    volume: 19283700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-05-29',\n    open: 45.553800416478865,\n    high: 45.688262403792955,\n    low: 44.74702849259436,\n    close: 45.006349,\n    volume: 36519600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-06-01',\n    open: 45.198437689640315,\n    high: 45.88035109549016,\n    low: 44.77584095020725,\n    close: 45.361712,\n    volume: 28837300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-06-02',\n    open: 45.07358034883122,\n    high: 45.476964401661995,\n    low: 44.77584212207396,\n    close: 45.063974,\n    volume: 21498300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-06-03',\n    open: 45.496174213566825,\n    high: 45.851540928848834,\n    low: 44.967931637051514,\n    close: 44.996743,\n    volume: 27955200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-06-04',\n    open: 44.93911839316241,\n    high: 45.294481259394274,\n    low: 44.37245715603259,\n    close: 44.526128,\n    volume: 27745500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-06-05',\n    open: 44.478106193821745,\n    high: 44.67979821759424,\n    low: 44.02669712584953,\n    close: 44.314829,\n    volume: 25438100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-06-08',\n    open: 44.46849942005143,\n    high: 44.593357940957794,\n    low: 43.863419512746646,\n    close: 43.921048,\n    volume: 22121600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-06-09',\n    open: 43.949858862034056,\n    high: 44.12273951961242,\n    low: 43.66172699391746,\n    close: 43.844214,\n    volume: 24406100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-06-10',\n    open: 43.97867591927833,\n    high: 44.97753737234372,\n    low: 43.882629720255984,\n    close: 44.766239,\n    volume: 28417400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-06-11',\n    open: 44.814259368524105,\n    high: 45.063972566280164,\n    low: 44.30522566404364,\n    close: 44.602961,\n    volume: 27347800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-06-12',\n    open: 44.391666697408944,\n    high: 44.631777394817895,\n    low: 44.08432596516828,\n    close: 44.151556,\n    volume: 23931000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-06-15',\n    open: 43.65212467746124,\n    high: 43.84421419111421,\n    low: 43.23913332761654,\n    close: 43.680937,\n    volume: 33254500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-06-16',\n    open: 43.556077629361916,\n    high: 44.4108755350739,\n    low: 43.50805645138104,\n    close: 44.017094,\n    volume: 27070300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-06-17',\n    open: 43.921048770044614,\n    high: 44.247599318520784,\n    low: 43.56568589832216,\n    close: 44.151556,\n    volume: 28704100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-06-18',\n    open: 44.39166660616912,\n    high: 44.94872150212736,\n    low: 44.34364158545767,\n    close: 44.871888,\n    volume: 32658300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-06-19',\n    open: 44.93911941094685,\n    high: 44.977538083251595,\n    low: 44.17076613415085,\n    close: 44.276411,\n    volume: 63837000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-06-22',\n    open: 44.4973151973294,\n    high: 44.871886915017726,\n    low: 44.334038006489294,\n    close: 44.401269,\n    volume: 20318100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-06-23',\n    open: 44.30522637189998,\n    high: 44.44929086791705,\n    low: 43.815398633545456,\n    close: 44.093928,\n    volume: 25896500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-06-24',\n    open: 43.86342032327354,\n    high: 44.42047906267483,\n    low: 43.748168148851015,\n    close: 43.834608,\n    volume: 34890900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-06-25',\n    open: 44.20917936818022,\n    high: 44.23799457192168,\n    low: 43.70014566483481,\n    close: 43.844214,\n    volume: 20616000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-06-26',\n    open: 43.8442155319865,\n    high: 44.449291611775166,\n    low: 43.24873811749529,\n    close: 43.469639,\n    volume: 49835300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-06-29',\n    open: 43.25834358064432,\n    high: 43.44082674759582,\n    low: 42.60524249312796,\n    close: 42.614845,\n    volume: 34081700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-06-30',\n    open: 42.94139506712707,\n    high: 42.95100141566358,\n    low: 42.20185413800095,\n    close: 42.40355,\n    volume: 35945400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-07-01',\n    open: 42.701284506794906,\n    high: 43.44082639863157,\n    low: 42.35552414985628,\n    close: 42.691682,\n    volume: 28343900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-07-02',\n    open: 42.72049450087862,\n    high: 42.9798140493327,\n    low: 42.317109497059505,\n    close: 42.643661,\n    volume: 21752000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-07-06',\n    open: 42.22106360502387,\n    high: 42.72049481055406,\n    low: 42.21146109811928,\n    close: 42.634054,\n    volume: 23034000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-07-07',\n    open: 42.58603267146801,\n    high: 42.73010100869817,\n    low: 41.606381040324635,\n    close: 42.547614,\n    volume: 36435800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-07-08',\n    open: 42.682075672374744,\n    high: 43.123882227220065,\n    low: 42.28829413728349,\n    close: 42.48999,\n    volume: 39785900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-07-09',\n    open: 42.979814841644206,\n    high: 43.43122391327298,\n    low: 42.73970414420485,\n    close: 42.758913,\n    volume: 32099800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-07-10',\n    open: 43.22952722729808,\n    high: 43.35438574804442,\n    low: 42.806934328694595,\n    close: 42.845353,\n    volume: 25465800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-07-13',\n    open: 43.200716084744926,\n    high: 43.81539850123049,\n    low: 43.17190376189419,\n    close: 43.738565,\n    volume: 28178300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-07-14',\n    open: 43.65212564703035,\n    high: 44.141949547710446,\n    low: 43.517663656796636,\n    close: 43.815399,\n    volume: 22880300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-07-15',\n    open: 43.87302649794696,\n    high: 44.07471852271803,\n    low: 43.6329158012638,\n    close: 43.94986,\n    volume: 26629600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-07-16',\n    open: 44.189970273713676,\n    high: 44.843072322883415,\n    low: 44.151555443940424,\n    close: 44.81426,\n    volume: 26271700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-07-17',\n    open: 44.708610006065406,\n    high: 44.92951184327908,\n    low: 44.4300806421793,\n    close: 44.775841,\n    volume: 29467100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-07-20',\n    open: 44.804658287239235,\n    high: 45.26566986818657,\n    low: 44.602962419052666,\n    close: 45.063974,\n    volume: 30631900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-07-21',\n    open: 44.9295126065943,\n    high: 45.45775902066893,\n    low: 44.64138073099367,\n    close: 45.409734,\n    volume: 42781900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-07-22',\n    open: 43.6425188014694,\n    high: 45.07357949882346,\n    low: 43.41201445600682,\n    close: 43.738565,\n    volume: 59152400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-07-23',\n    open: 43.479244114308315,\n    high: 44.40126917173565,\n    low: 43.31596692283668,\n    close: 44.286017,\n    volume: 33934000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-07-24',\n    open: 44.09392767727313,\n    high: 44.48770921392489,\n    low: 43.98827801187501,\n    close: 44.12274,\n    volume: 32333200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-07-27',\n    open: 44.12274121167372,\n    high: 44.18997124713968,\n    low: 43.46003664101595,\n    close: 43.556079,\n    volume: 39701400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-07-28',\n    open: 43.77698418996365,\n    high: 43.8346078759048,\n    low: 43.01823342713885,\n    close: 43.546476,\n    volume: 34328900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-07-29',\n    open: 43.60410389098489,\n    high: 44.92951203870363,\n    low: 43.469638060759735,\n    close: 44.458897,\n    volume: 40945900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-07-30',\n    open: 44.430081588285,\n    high: 45.52499021173481,\n    low: 44.113137388158336,\n    close: 45.025559,\n    volume: 39777900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-07-31',\n    open: 45.419340242898045,\n    high: 45.49617374477832,\n    low: 44.66058948264263,\n    close: 44.852679,\n    volume: 31201500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-08-03',\n    open: 45.12160231400123,\n    high: 45.14081116981818,\n    low: 44.612568595295016,\n    close: 44.958328,\n    volume: 24125900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-08-04',\n    open: 44.90070023873159,\n    high: 45.82272435270982,\n    low: 44.83346924372172,\n    close: 45.659451,\n    volume: 33403900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-08-05',\n    open: 46.08204418780814,\n    high: 46.495034579653854,\n    low: 45.65945032868785,\n    close: 45.697869,\n    volume: 26959700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-08-06',\n    open: 45.822723619838754,\n    high: 45.88035114651118,\n    low: 44.497315477884975,\n    close: 44.775841,\n    volume: 27368000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-08-07',\n    open: 44.55493914910195,\n    high: 44.92951182947966,\n    low: 44.43008062853327,\n    close: 44.891097,\n    volume: 19163000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-08-10',\n    open: 45.09278978073483,\n    high: 45.611429845819956,\n    low: 44.987140113790836,\n    close: 45.457759,\n    volume: 23079900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-08-11',\n    open: 44.96793053609136,\n    high: 45.083182708163136,\n    low: 44.08432510769873,\n    close: 44.574149,\n    volume: 29237400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-08-12',\n    open: 44.362850595062085,\n    high: 45.04476784323189,\n    low: 43.901838065366434,\n    close: 44.891097,\n    volume: 30181400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-08-13',\n    open: 45.198438077070215,\n    high: 45.236852906848235,\n    low: 44.65098665424742,\n    close: 44.881491,\n    volume: 22627200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-08-14',\n    open: 44.68940192955721,\n    high: 45.23685335783783,\n    low: 44.679798462127664,\n    close: 45.140811,\n    volume: 21473400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-08-17',\n    open: 44.95832714641065,\n    high: 45.573010520882335,\n    low: 44.727819920540995,\n    close: 45.448152,\n    volume: 21099700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-08-18',\n    open: 45.28380020647345,\n    high: 45.854198202242436,\n    low: 45.14845249628758,\n    close: 45.699514,\n    volume: 23574100,\n    split: '',\n    dividend: '$0.310',\n  },\n  {\n    date: '2015-08-19',\n    open: 45.22579202902308,\n    high: 45.51582780448523,\n    low: 44.76173942880967,\n    close: 45.061442,\n    volume: 31444000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-08-20',\n    open: 44.53938226631625,\n    high: 44.92609373681569,\n    low: 44.143004,\n    close: 44.143004,\n    volume: 36238200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-08-21',\n    open: 43.79496306619333,\n    high: 43.968983757603894,\n    low: 41.639053,\n    close: 41.639053,\n    volume: 70053100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-08-24',\n    open: 39.1061001822273,\n    high: 41.27167704330053,\n    low: 38.40035352147875,\n    close: 40.295234,\n    volume: 88753700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-08-25',\n    open: 41.155665168379905,\n    high: 41.80340719267271,\n    low: 39.04809196606059,\n    close: 39.125436,\n    volume: 70616600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-08-26',\n    open: 40.614268652827036,\n    high: 41.416694880278506,\n    low: 39.6958341083317,\n    close: 41.291013,\n    volume: 63408000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-08-27',\n    open: 41.79373698365663,\n    high: 42.48981684537233,\n    low: 41.50370411076519,\n    close: 42.441479,\n    volume: 50943200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-08-28',\n    open: 41.958091516980694,\n    high: 42.683173710242706,\n    low: 41.948420854075096,\n    close: 42.470481,\n    volume: 28246700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-08-31',\n    open: 42.11277501732773,\n    high: 42.47048126815257,\n    low: 41.66805503565703,\n    close: 42.074103,\n    volume: 34441700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-09-01',\n    open: 40.76895275583056,\n    high: 41.17500071664276,\n    low: 40.27589879913916,\n    close: 40.430583,\n    volume: 49688900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-09-02',\n    open: 40.95264275384631,\n    high: 41.93875452492308,\n    low: 40.48859015569255,\n    close: 41.919419,\n    volume: 37671500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-09-03',\n    open: 41.96775713724137,\n    high: 42.518819601379306,\n    low: 41.84207525759156,\n    close: 42.054767,\n    volume: 28285200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-09-04',\n    open: 41.387692250097274,\n    high: 41.610050787709135,\n    low: 40.7979587373006,\n    close: 41.194337,\n    volume: 37138800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-09-08',\n    open: 41.86141100773757,\n    high: 42.53815535516417,\n    low: 41.764735315482895,\n    close: 42.431809,\n    volume: 32469800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-09-09',\n    open: 42.741176955907754,\n    high: 42.9248673433505,\n    low: 41.48436880032504,\n    close: 41.639053,\n    volume: 33469500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-09-10',\n    open: 41.687391103277065,\n    high: 42.33513312697186,\n    low: 41.32968485609414,\n    close: 41.851745,\n    volume: 31366600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-09-11',\n    open: 41.70672611096066,\n    high: 42.141776386614545,\n    low: 41.51337086257059,\n    close: 42.035431,\n    volume: 27132500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-09-14',\n    open: 41.987092772837066,\n    high: 41.996759568615,\n    low: 41.43603127402462,\n    close: 41.610051,\n    volume: 23656000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-09-15',\n    open: 41.75506480425605,\n    high: 42.818520600928125,\n    low: 41.64872231827281,\n    close: 42.518819,\n    volume: 28882200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-09-16',\n    open: 42.50915277036885,\n    high: 42.90553103371824,\n    low: 42.383470890823276,\n    close: 42.828187,\n    volume: 23372200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-09-17',\n    open: 42.81852101671975,\n    high: 43.50493118644068,\n    low: 42.61549897129261,\n    close: 42.779849,\n    volume: 32768200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-09-18',\n    open: 42.05476652483901,\n    high: 42.528488816947146,\n    low: 41.89041649725994,\n    close: 42.035431,\n    volume: 63143700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-09-21',\n    open: 42.17077870788303,\n    high: 42.99254044710861,\n    low: 42.15144221626742,\n    close: 42.644501,\n    volume: 26177200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-09-22',\n    open: 41.93875438687859,\n    high: 42.58649253611699,\n    low: 41.87108004987059,\n    close: 42.441479,\n    volume: 28085900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-09-23',\n    open: 42.47048054161113,\n    high: 42.70250490739819,\n    low: 42.06443258421442,\n    close: 42.412473,\n    volume: 17145200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-09-24',\n    open: 42.00642889321669,\n    high: 42.66383674108734,\n    low: 41.8324082020041,\n    close: 42.451145,\n    volume: 27905600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-09-25',\n    open: 43.002207136144904,\n    high: 43.243901196037804,\n    low: 42.30612631010087,\n    close: 42.480147,\n    volume: 29384600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-09-28',\n    open: 42.37380514390587,\n    high: 42.62516503637873,\n    low: 41.774400966132,\n    close: 41.851745,\n    volume: 27613800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-09-29',\n    open: 41.92908466303696,\n    high: 42.12244087827902,\n    low: 41.61971626549165,\n    close: 41.996759,\n    volume: 32763600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-09-30',\n    open: 42.422142924396766,\n    high: 42.82818701687435,\n    low: 42.20945118208093,\n    close: 42.789515,\n    volume: 34958900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-10-01',\n    open: 43.26323670671965,\n    high: 43.26323670671965,\n    low: 42.29646046746335,\n    close: 43.127889,\n    volume: 28657900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-10-02',\n    open: 42.799183895325875,\n    high: 44.055993,\n    low: 42.46081027974575,\n    close: 44.055993,\n    volume: 41839000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-10-05',\n    open: 44.230013923868455,\n    high: 45.33213789421154,\n    low: 44.18167607761317,\n    close: 45.080778,\n    volume: 34369300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-10-06',\n    open: 44.79074590574503,\n    high: 45.61250379037433,\n    low: 44.68439955073348,\n    close: 45.19679,\n    volume: 27017200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-10-07',\n    open: 45.5351599112159,\n    high: 45.77685397620936,\n    low: 44.42337011257475,\n    close: 45.245128,\n    volume: 27711500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-10-08',\n    open: 45.013103138049125,\n    high: 45.941207370680566,\n    low: 44.955095596309896,\n    close: 45.873534,\n    volume: 33772700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-10-09',\n    open: 45.873533924247425,\n    high: 45.96054378654821,\n    low: 45.36113961259181,\n    close: 45.54483,\n    volume: 28600600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-10-12',\n    open: 45.41914847489362,\n    high: 45.50615833787234,\n    low: 44.95509587234043,\n    close: 45.438484,\n    volume: 19769100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-10-13',\n    open: 45.01310376679978,\n    high: 45.56416623664543,\n    low: 45.01310376679978,\n    close: 45.332138,\n    volume: 19987800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-10-14',\n    open: 45.1001146456348,\n    high: 45.5351600972958,\n    low: 44.984098593635046,\n    close: 45.129116,\n    volume: 24697800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-10-15',\n    open: 45.44815,\n    high: 45.467486491955384,\n    low: 44.984098362477056,\n    close: 45.44815,\n    volume: 27189400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-10-16',\n    open: 45.457819567999145,\n    high: 45.96054418801571,\n    low: 45.34180835080389,\n    close: 45.931538,\n    volume: 26450300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-10-19',\n    open: 45.84452778346828,\n    high: 46.2892477582346,\n    low: 45.45781921750985,\n    close: 46.037884,\n    volume: 29387600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-10-20',\n    open: 45.863864867010626,\n    high: 46.22157401722633,\n    low: 45.457819804061124,\n    close: 46.182902,\n    volume: 30574000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-10-21',\n    open: 46.32791600017805,\n    high: 46.39559420483232,\n    low: 45.54483013743665,\n    close: 45.63184,\n    volume: 25144300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-10-22',\n    open: 45.95087387833878,\n    high: 47.32369807740912,\n    low: 45.52549329805316,\n    close: 46.434262,\n    volume: 56637100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-10-23',\n    open: 50.56239654149683,\n    high: 52.27359145836186,\n    low: 50.514058696123676,\n    close: 51.113459,\n    volume: 135227100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-10-26',\n    open: 50.78475586935277,\n    high: 52.51528633806452,\n    low: 50.7557535483871,\n    close: 52.447612,\n    volume: 64633300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-10-27',\n    open: 52.196251775911406,\n    high: 52.56362385132069,\n    low: 51.799873512615115,\n    close: 51.906216,\n    volume: 50999900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-10-28',\n    open: 51.76120141657247,\n    high: 52.186582,\n    low: 51.103793566257536,\n    close: 52.186582,\n    volume: 47000800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-10-29',\n    open: 51.76120072275076,\n    high: 52.04156679840321,\n    low: 51.45183232674942,\n    close: 51.587181,\n    volume: 30202100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-10-30',\n    open: 51.548509818930654,\n    high: 52.19625184210588,\n    low: 50.87176547493663,\n    close: 50.891101,\n    volume: 46619800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-11-02',\n    open: 51.094122398937216,\n    high: 51.58718118213386,\n    low: 50.87176483030243,\n    close: 51.471169,\n    volume: 30285000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-11-03',\n    open: 51.1714670385423,\n    high: 52.58295940024276,\n    low: 51.14246568452337,\n    close: 52.350936,\n    volume: 36596900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-11-04',\n    open: 52.37993729117878,\n    high: 53.05668163381005,\n    low: 52.263925107808454,\n    close: 52.59263,\n    volume: 37087800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-11-05',\n    open: 52.67964035540543,\n    high: 52.882662403284876,\n    low: 52.20591805432295,\n    close: 52.573294,\n    volume: 31468500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-11-06',\n    open: 52.29292764176722,\n    high: 53.1533585088623,\n    low: 52.16724576181978,\n    close: 53.09535,\n    volume: 32851200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-11-09',\n    open: 52.73764377288401,\n    high: 53.047012174656544,\n    low: 51.780537213452774,\n    close: 52.360602,\n    volume: 32513100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-11-10',\n    open: 52.27359264188349,\n    high: 52.33160018455235,\n    low: 51.50017162998213,\n    close: 51.732196,\n    volume: 55283700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-11-11',\n    open: 51.91588484502847,\n    high: 52.39927296307551,\n    low: 51.68385661481342,\n    close: 51.867547,\n    volume: 36516300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-11-12',\n    open: 51.70319319804951,\n    high: 52.18658131695424,\n    low: 51.42282712230854,\n    close: 51.548509,\n    volume: 35361100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-11-13',\n    open: 51.30681553728236,\n    high: 51.51950727885043,\n    low: 50.78475539601708,\n    close: 51.084457,\n    volume: 36848200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-11-16',\n    open: 51.316486307738884,\n    high: 52.099572185539145,\n    low: 51.094123898695926,\n    close: 51.98356,\n    volume: 32165200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-11-17',\n    open: 51.74996861146696,\n    high: 52.100354941180505,\n    low: 51.43851496131506,\n    close: 51.555313,\n    volume: 31551300,\n    split: '',\n    dividend: '$0.360',\n  },\n  {\n    date: '2015-11-18',\n    open: 51.58451118234025,\n    high: 52.53833799288164,\n    low: 51.56504532906389,\n    close: 52.411808,\n    volume: 29710000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-11-19',\n    open: 52.54807155185168,\n    high: 53.20017567371478,\n    low: 52.343677177683965,\n    close: 52.499404,\n    volume: 28149200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-11-20',\n    open: 52.80112553148414,\n    high: 52.84978919001775,\n    low: 51.84729874768959,\n    close: 52.742727,\n    volume: 37147600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-11-23',\n    open: 52.80112553148414,\n    high: 53.005516011861765,\n    low: 52.31447921322161,\n    close: 52.742727,\n    volume: 28235900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-11-24',\n    open: 52.47993748051148,\n    high: 52.986050629287995,\n    low: 52.14902187432722,\n    close: 52.801126,\n    volume: 24600000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-11-25',\n    open: 52.64539903027378,\n    high: 52.78166000021717,\n    low: 52.256081,\n    close: 52.256081,\n    volume: 21005100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-11-27',\n    open: 52.363143981278085,\n    high: 52.63566884515754,\n    low: 52.35341300129191,\n    close: 52.489673,\n    volume: 9009100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-11-30',\n    open: 53.08338252484303,\n    high: 53.49216349449629,\n    low: 52.557803516386514,\n    close: 52.898454,\n    volume: 56241400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-12-01',\n    open: 52.95685298176651,\n    high: 53.7549529531881,\n    low: 52.8497898171856,\n    close: 53.745221,\n    volume: 39952800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-12-02',\n    open: 53.842549164328005,\n    high: 54.465455484332,\n    low: 53.589494049718894,\n    close: 53.735486,\n    volume: 47274900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-12-03',\n    open: 54.00801047743383,\n    high: 54.280530469731914,\n    low: 52.489672014212694,\n    close: 52.752462,\n    volume: 38627800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-12-04',\n    open: 52.674597185176324,\n    high: 54.72824564764801,\n    low: 52.65513035890567,\n    close: 54.416792,\n    volume: 43963700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-12-07',\n    open: 54.2999981469175,\n    high: 54.47519082465998,\n    low: 53.813351819855086,\n    close: 54.319464,\n    volume: 30709800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-12-08',\n    open: 53.98854435152275,\n    high: 54.6017158020844,\n    low: 53.5213648520995,\n    close: 54.299998,\n    volume: 32878000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-12-09',\n    open: 53.89121215384451,\n    high: 54.377858470687,\n    low: 53.0541795155828,\n    close: 53.511629,\n    volume: 36373200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-12-10',\n    open: 53.91067914521649,\n    high: 54.1734691351547,\n    low: 53.54082696331157,\n    close: 53.793885,\n    volume: 31620700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-12-11',\n    open: 53.248840280335884,\n    high: 53.62842344319594,\n    low: 52.56753444728194,\n    close: 52.616202,\n    volume: 39549500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-12-14',\n    open: 52.878991869671815,\n    high: 53.73548648582028,\n    low: 52.24634969761243,\n    close: 53.667356,\n    volume: 46768900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-12-15',\n    open: 54.17346864359658,\n    high: 54.4070608250806,\n    low: 53.618691835712106,\n    close: 53.725755,\n    volume: 39843000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-12-16',\n    open: 54.05667434089154,\n    high: 54.74771114381416,\n    low: 53.2975031598194,\n    close: 54.630917,\n    volume: 37503300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-12-17',\n    open: 54.8547741421477,\n    high: 55.27328997718332,\n    low: 54.046939304679704,\n    close: 54.212401,\n    volume: 41280900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-12-18',\n    open: 54.28053096913853,\n    high: 54.50438827813803,\n    low: 52.58700078863231,\n    close: 52.684332,\n    volume: 84684200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-12-21',\n    open: 53.414301659256516,\n    high: 53.87174628534071,\n    low: 52.78166046282471,\n    close: 53.365638,\n    volume: 37246300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-12-22',\n    open: 53.52136553416847,\n    high: 53.99827699289167,\n    low: 53.04445018227462,\n    close: 53.871747,\n    volume: 28322200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-12-23',\n    open: 54.21240085684692,\n    high: 54.38759353151549,\n    low: 53.95934282462925,\n    close: 54.329195,\n    volume: 27279800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-12-24',\n    open: 54.36812852379121,\n    high: 54.465455842423424,\n    low: 53.949611710063294,\n    close: 54.1832,\n    volume: 9558500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-12-28',\n    open: 53.87174549806624,\n    high: 54.455724,\n    low: 53.51162916905041,\n    close: 54.455724,\n    volume: 22458300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-12-29',\n    open: 54.78664485475409,\n    high: 55.33168582497414,\n    low: 54.56278754274954,\n    close: 55.039699,\n    volume: 27731400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-12-30',\n    open: 54.96183682373065,\n    high: 55.263555598123496,\n    low: 54.78664414703366,\n    close: 54.80611,\n    volume: 21704500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2015-12-31',\n    open: 54.54332085505183,\n    high: 54.68931280536633,\n    low: 53.93987649465479,\n    close: 53.998276,\n    volume: 26529600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-01-04',\n    open: 52.869256503453585,\n    high: 53.336436,\n    low: 51.96409336984777,\n    close: 53.336436,\n    volume: 53778000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-01-05',\n    open: 53.46296585400483,\n    high: 53.91067950464886,\n    low: 53.08338268961204,\n    close: 53.57976,\n    volume: 34079700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-01-06',\n    open: 52.869256989995506,\n    high: 52.947122348937214,\n    low: 52.207417011673456,\n    close: 52.606467,\n    volume: 39518900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-01-07',\n    open: 51.29252402840184,\n    high: 52.06142620119234,\n    low: 50.679348680826095,\n    close: 50.776676,\n    volume: 56564900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-01-08',\n    open: 50.971334785876635,\n    high: 51.857031091793075,\n    low: 50.75721332410444,\n    close: 50.932406,\n    volume: 48754000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-01-11',\n    open: 51.1075954847263,\n    high: 51.43851498818556,\n    low: 50.08563916792417,\n    close: 50.903205,\n    volume: 36943800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-01-12',\n    open: 51.35091817374286,\n    high: 51.68183767413922,\n    low: 50.66961623986361,\n    close: 51.370385,\n    volume: 36095500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-01-13',\n    open: 52.36314414605562,\n    high: 52.62593413760523,\n    low: 49.92991249552828,\n    close: 50.260832,\n    volume: 66883600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-01-14',\n    open: 50.61121719805654,\n    high: 51.99329079803358,\n    low: 50.19270136353415,\n    close: 51.691573,\n    volume: 52381900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-01-15',\n    open: 49.93964667363994,\n    high: 50.58201982043841,\n    low: 48.99555183308289,\n    close: 49.628194,\n    volume: 70739100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-01-19',\n    open: 50.10510627640217,\n    high: 50.29976480894452,\n    low: 48.72303166864411,\n    close: 49.209678,\n    volume: 43564500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-01-20',\n    open: 48.64516697489334,\n    high: 50.00777766737069,\n    low: 47.7886674905348,\n    close: 49.433535,\n    volume: 63273000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-01-21',\n    open: 49.63792416798732,\n    high: 50.2024358404046,\n    low: 48.95661835317329,\n    close: 49.131812,\n    volume: 40191200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-01-22',\n    open: 50.03697450550823,\n    high: 50.93240567880169,\n    low: 49.89097866326402,\n    close: 50.893473,\n    volume: 37555800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-01-25',\n    open: 50.55281894999718,\n    high: 51.24385964703214,\n    low: 50.27056700314901,\n    close: 50.406827,\n    volume: 34707700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-01-26',\n    open: 50.40682770999293,\n    high: 51.03946599084255,\n    low: 50.17323552558549,\n    close: 50.776676,\n    volume: 28900800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-01-27',\n    open: 50.6209492812368,\n    high: 50.805877806446176,\n    low: 49.65739149477955,\n    close: 49.852051,\n    volume: 36775200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-01-28',\n    open: 50.47495846743485,\n    high: 50.81560895283854,\n    low: 49.8812489698185,\n    close: 50.669617,\n    volume: 62513800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-01-29',\n    open: 53.26830664657832,\n    high: 53.618692,\n    low: 52.55780301325104,\n    close: 53.618692,\n    volume: 83611700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-02-01',\n    open: 53.414301697370526,\n    high: 53.61869218093022,\n    low: 53.04444951644031,\n    close: 53.24884,\n    volume: 44208500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-02-02',\n    open: 52.723260443980756,\n    high: 52.81085678171661,\n    low: 51.24385952205698,\n    close: 51.58451,\n    volume: 56313800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-02-03',\n    open: 51.827832975460126,\n    high: 51.96409297149265,\n    low: 49.8909786791816,\n    close: 50.766944,\n    volume: 57559800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-02-04',\n    open: 50.7085453187993,\n    high: 51.39958602290804,\n    low: 49.99804265478427,\n    close: 50.611218,\n    volume: 46987100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-02-05',\n    open: 50.55281893220976,\n    high: 50.611217464114844,\n    low: 48.23638438716825,\n    close: 48.820359,\n    volume: 62009000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-02-08',\n    open: 48.226649998170615,\n    high: 48.24611682452945,\n    low: 46.90297198967031,\n    close: 48.09039,\n    volume: 59290500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-02-09',\n    open: 47.71080588333617,\n    high: 48.89822486740964,\n    low: 47.370151507963264,\n    close: 47.963861,\n    volume: 46740500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-02-10',\n    open: 48.557569678237634,\n    high: 49.0442160066755,\n    low: 48.19745236848627,\n    close: 48.382377,\n    volume: 38237000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-02-11',\n    open: 47.37988541315929,\n    high: 48.771694852779326,\n    low: 47.21442371882881,\n    close: 48.36291,\n    volume: 48878600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-02-12',\n    open: 48.90795583663366,\n    high: 49.326471677623765,\n    low: 48.42130950990099,\n    close: 49.151279,\n    volume: 34243300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-02-16',\n    open: 49.89629261626713,\n    high: 50.082544,\n    low: 49.1414754512144,\n    close: 50.082544,\n    volume: 37291200,\n    split: '',\n    dividend: '$0.360',\n  },\n  {\n    date: '2016-02-17',\n    open: 50.474657822814684,\n    high: 51.72941522336572,\n    low: 50.43544561249917,\n    close: 51.386315,\n    volume: 40789000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-02-18',\n    open: 51.29809324487058,\n    high: 51.90586632528679,\n    low: 51.07262475284389,\n    close: 51.160851,\n    volume: 27176000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-02-19',\n    open: 50.94519209432939,\n    high: 51.24907716946837,\n    low: 50.513866599225224,\n    close: 50.798149,\n    volume: 33559100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-02-22',\n    open: 51.24907618480655,\n    high: 51.95487929895995,\n    low: 51.24907618480655,\n    close: 51.611783,\n    volume: 25008300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-02-23',\n    open: 51.307894674873,\n    high: 51.337302117218265,\n    low: 49.97471284915982,\n    close: 50.170769,\n    volume: 28895300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-02-24',\n    open: 49.69042994085573,\n    high: 50.48445832390074,\n    low: 49.21009433678205,\n    close: 50.34722,\n    volume: 33014500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-02-25',\n    open: 50.709924076772516,\n    high: 51.072626,\n    low: 49.61201059801626,\n    close: 51.072626,\n    volume: 26939500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-02-26',\n    open: 51.56276600752362,\n    high: 51.6411904288731,\n    low: 50.09234486774933,\n    close: 50.288402,\n    volume: 35975900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-02-29',\n    open: 50.33741501590434,\n    high: 50.631503164737985,\n    low: 49.661023252731454,\n    close: 49.876686,\n    volume: 31654000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-03-01',\n    open: 49.96491100595934,\n    high: 51.552964846977375,\n    low: 49.91589402742267,\n    close: 51.543164,\n    volume: 33024500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-03-02',\n    open: 51.37651441158613,\n    high: 51.91566784699651,\n    low: 51.131444222635615,\n    close: 51.905867,\n    volume: 29289900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-03-03',\n    open: 51.92547301410969,\n    high: 51.92547301410969,\n    low: 50.75893694518009,\n    close: 51.317696,\n    volume: 24427800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-03-04',\n    open: 51.366713822308824,\n    high: 51.415726880064085,\n    low: 50.69031715656949,\n    close: 51.004007,\n    volume: 33034200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-03-07',\n    open: 50.54327676125815,\n    high: 50.778542182144164,\n    low: 49.582602600628164,\n    close: 50.023726,\n    volume: 38407800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-03-08',\n    open: 49.79826141668875,\n    high: 51.10203678252525,\n    low: 49.60220428523883,\n    close: 50.631503,\n    volume: 33835100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-03-09',\n    open: 50.86676730416285,\n    high: 51.80783584697066,\n    low: 50.837360842127836,\n    close: 51.798035,\n    volume: 28251600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-03-10',\n    open: 51.88626105622019,\n    high: 51.89606288362055,\n    low: 50.15116409666021,\n    close: 51.023613,\n    volume: 38387800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-03-11',\n    open: 51.9548793480309,\n    high: 52.023499,\n    low: 51.347106268013924,\n    close: 52.023499,\n    volume: 32275700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-03-14',\n    open: 51.67059783110156,\n    high: 52.53324587937732,\n    low: 51.59217733093626,\n    close: 52.121526,\n    volume: 24083600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-03-15',\n    open: 51.7098101604777,\n    high: 52.533246,\n    low: 51.70000931342586,\n    close: 52.533246,\n    volume: 21104800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-03-16',\n    open: 52.39600824600321,\n    high: 53.52332819301086,\n    low: 52.34699518768181,\n    close: 53.278258,\n    volume: 31691700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-03-17',\n    open: 53.141018680531545,\n    high: 53.91544145627516,\n    low: 52.9351607025247,\n    close: 53.582146,\n    volume: 28223900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-03-18',\n    open: 53.837016543943335,\n    high: 53.88603352202565,\n    low: 52.39600678992719,\n    close: 52.435219,\n    volume: 67625500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-03-21',\n    open: 52.199949764204426,\n    high: 52.86654067199145,\n    low: 51.88625992524583,\n    close: 52.797922,\n    volume: 23925700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-03-22',\n    open: 52.552851836578135,\n    high: 53.180230534492324,\n    low: 52.40580776393971,\n    close: 53.00378,\n    volume: 23124100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-03-23',\n    open: 53.04299330744414,\n    high: 53.170430787494475,\n    low: 52.680290403765376,\n    close: 52.905754,\n    volume: 20129000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-03-24',\n    open: 52.77831609921262,\n    high: 53.25865563199951,\n    low: 52.670485215651816,\n    close: 53.141019,\n    volume: 19950000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-03-28',\n    open: 53.14101915025679,\n    high: 53.21944357181153,\n    low: 52.27837502017354,\n    close: 52.484233,\n    volume: 17025100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-03-29',\n    open: 52.60186518994452,\n    high: 53.77820307346667,\n    low: 52.39600721215803,\n    close: 53.631159,\n    volume: 23924300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-03-30',\n    open: 53.84682228877062,\n    high: 54.542820649924906,\n    low: 53.81741582645461,\n    close: 53.964455,\n    volume: 23008300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-03-31',\n    open: 53.866428369380884,\n    high: 54.493807071156986,\n    low: 53.778203101591636,\n    close: 54.140906,\n    volume: 26360500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-04-01',\n    open: 53.96445403231598,\n    high: 54.51341321008099,\n    low: 53.493920254993704,\n    close: 54.474201,\n    volume: 24399200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-04-04',\n    open: 54.336963,\n    high: 54.56242757676348,\n    low: 53.91544226952914,\n    close: 54.336963,\n    volume: 18928800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-04-05',\n    open: 54.10169391539932,\n    high: 54.209524798503594,\n    low: 53.38608896388915,\n    close: 53.484119,\n    volume: 19272300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-04-06',\n    open: 53.2880625900061,\n    high: 54.11149842061996,\n    low: 53.14101851683499,\n    close: 54.033074,\n    volume: 21188700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-04-07',\n    open: 53.78800411002415,\n    high: 53.82721632055116,\n    low: 53.160625406364765,\n    close: 53.386089,\n    volume: 19225100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-04-08',\n    open: 53.59194719000625,\n    high: 54.189919433902276,\n    low: 53.24885088455902,\n    close: 53.346877,\n    volume: 22167200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-04-11',\n    open: 53.41550051689555,\n    high: 54.062485817816466,\n    low: 53.229244231848774,\n    close: 53.239049,\n    volume: 21414200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-04-12',\n    open: 53.29786344889163,\n    high: 53.69977855678129,\n    low: 52.69989121053115,\n    close: 53.572345,\n    volume: 24944300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-04-13',\n    open: 54.0330744059189,\n    high: 54.34676424850932,\n    low: 53.80760983155704,\n    close: 54.258538,\n    volume: 20818000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-04-14',\n    open: 54.131103695759386,\n    high: 54.48400574408744,\n    low: 53.984060603792265,\n    close: 54.268343,\n    volume: 20877100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-04-15',\n    open: 54.20952479475874,\n    high: 54.8172978828419,\n    low: 54.023273411789376,\n    close: 54.552626,\n    volume: 28793800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-04-18',\n    open: 54.39578159899191,\n    high: 55.474088479704015,\n    low: 54.12130004400725,\n    close: 55.346651,\n    volume: 23150300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-04-19',\n    open: 55.51330034263754,\n    high: 55.650538668567805,\n    low: 54.58203264163916,\n    close: 55.278031,\n    volume: 29596800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-04-20',\n    open: 55.180004506634404,\n    high: 55.385862484259754,\n    low: 54.39578088536811,\n    close: 54.493807,\n    volume: 36195700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-04-21',\n    open: 54.69966461490867,\n    high: 55.12118631572582,\n    low: 54.32715695136319,\n    close: 54.680059,\n    volume: 38909100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-04-22',\n    open: 50.88637347714124,\n    high: 51.39611946458323,\n    low: 49.7688534277492,\n    close: 50.758936,\n    volume: 126834100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-04-25',\n    open: 50.75893639106952,\n    high: 51.10203661505267,\n    low: 50.61189623873604,\n    close: 51.082431,\n    volume: 33226900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-04-26',\n    open: 51.229470237911904,\n    high: 51.317695505762316,\n    low: 50.08254371641804,\n    close: 50.425641,\n    volume: 33532600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-04-27',\n    open: 50.46485258077841,\n    high: 50.48445819561166,\n    low: 49.553190510751676,\n    close: 49.9355,\n    volume: 43369300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-04-28',\n    open: 49.621810193594555,\n    high: 49.7688532852163,\n    low: 48.58271456734632,\n    close: 48.916011,\n    volume: 43134800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-04-29',\n    open: 48.37685302995094,\n    high: 49.25910766511144,\n    low: 48.37685302995094,\n    close: 48.8866,\n    volume: 48411700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-05-02',\n    open: 49.01403775905873,\n    high: 49.74924832544461,\n    low: 48.79837501263812,\n    close: 49.61201,\n    volume: 33114500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-05-03',\n    open: 49.347333203040044,\n    high: 49.41595285588495,\n    low: 48.62192348383233,\n    close: 48.798375,\n    volume: 26460200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-05-04',\n    open: 48.85719255779412,\n    high: 49.07285530297685,\n    low: 48.48468489268268,\n    close: 48.8866,\n    volume: 24257600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-05-05',\n    open: 48.88660034704406,\n    high: 49.30812107234483,\n    low: 48.74936202141293,\n    close: 48.95522,\n    volume: 25390700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-05-06',\n    open: 48.93561405800595,\n    high: 49.396347,\n    low: 48.68074301847078,\n    close: 49.396347,\n    volume: 24715600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-05-09',\n    open: 49.494376874282274,\n    high: 49.59240298841622,\n    low: 49.0140373477132,\n    close: 49.082657,\n    volume: 17951600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-05-10',\n    open: 49.33753322771168,\n    high: 50.09234550121815,\n    low: 49.2002909787549,\n    close: 50.013925,\n    volume: 22891000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-05-11',\n    open: 50.12175642164718,\n    high: 50.758936957406554,\n    low: 49.99431894210223,\n    close: 50.043332,\n    volume: 24039100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-05-12',\n    open: 50.19037590516427,\n    high: 50.78834716891777,\n    low: 49.915894351451534,\n    close: 50.49426,\n    volume: 24102800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-05-13',\n    open: 50.42564113147954,\n    high: 50.87657322028856,\n    low: 50.03353078946127,\n    close: 50.072743,\n    volume: 22592300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-05-16',\n    open: 49.79826089128932,\n    high: 50.935386556073205,\n    low: 49.74924783429489,\n    close: 50.807953,\n    volume: 20032000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-05-17',\n    open: 51.054736973466085,\n    high: 51.06460735832933,\n    low: 49.712230381404844,\n    close: 49.860298,\n    volume: 27803500,\n    split: '',\n    dividend: '$0.360',\n  },\n  {\n    date: '2016-05-18',\n    open: 49.83068573763657,\n    high: 50.48219530095184,\n    low: 49.65300005492143,\n    close: 50.156442,\n    volume: 24907500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-05-19',\n    open: 49.820815567423374,\n    high: 49.968884173435136,\n    low: 49.17917539904611,\n    close: 49.672744,\n    volume: 23842400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-05-20',\n    open: 49.83068577934978,\n    high: 50.561168293363345,\n    low: 49.751716777745656,\n    close: 49.968884,\n    volume: 23905800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-05-23',\n    open: 49.94914021539466,\n    high: 50.02811316546299,\n    low: 49.337117127265984,\n    close: 49.386473,\n    volume: 26118700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-05-24',\n    open: 50.0478568816904,\n    high: 51.04486347651855,\n    low: 49.75171670968823,\n    close: 50.926408,\n    volume: 34757900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-05-25',\n    open: 51.252161572390285,\n    high: 51.814833726285755,\n    low: 51.12383669749475,\n    close: 51.44959,\n    volume: 24040200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-05-26',\n    open: 51.26203547566073,\n    high: 51.31139233631513,\n    low: 50.69936825133777,\n    close: 51.222549,\n    volume: 24335200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-05-27',\n    open: 51.25216114804977,\n    high: 51.647018,\n    low: 51.10409254319572,\n    close: 51.647018,\n    volume: 17653700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-05-31',\n    open: 51.58778849214068,\n    high: 52.318272,\n    low: 51.41010774333102,\n    close: 52.318272,\n    volume: 37653100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-06-01',\n    open: 51.76547373549193,\n    high: 52.268915681325076,\n    low: 51.76547373549193,\n    close: 52.170199,\n    volume: 25324800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-06-02',\n    open: 51.96290096408232,\n    high: 52.0616176450061,\n    low: 51.173192195121956,\n    close: 51.80496,\n    volume: 22840800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-06-03',\n    open: 51.706246941447944,\n    high: 51.74572946759217,\n    low: 50.936276972698415,\n    close: 51.123836,\n    volume: 23081300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-06-06',\n    open: 51.32126477973645,\n    high: 51.676630221646725,\n    low: 51.22254809875291,\n    close: 51.459463,\n    volume: 18243300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-06-07',\n    open: 51.56805015884442,\n    high: 52.05174542060443,\n    low: 51.429847,\n    close: 51.429847,\n    volume: 20866800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-06-08',\n    open: 51.35087726881482,\n    high: 51.765473906685344,\n    low: 51.20280570131771,\n    close: 51.370621,\n    volume: 21149400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-06-09',\n    open: 51.33113412109907,\n    high: 51.33113412109907,\n    low: 50.82769612610883,\n    close: 50.956021,\n    volume: 20305700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-06-10',\n    open: 50.393353017330554,\n    high: 51.380490216242755,\n    low: 50.383483619615824,\n    close: 50.817823,\n    volume: 25833200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-06-13',\n    open: 48.94226512070967,\n    high: 50.067600559287186,\n    low: 48.42895278149206,\n    close: 49.495059,\n    volume: 83217800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-06-14',\n    open: 49.258147603086506,\n    high: 49.45557109192779,\n    low: 48.932390357118585,\n    close: 49.189048,\n    volume: 42577100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-06-15',\n    open: 49.139688347129045,\n    high: 49.47531499183878,\n    low: 49.050846,\n    close: 49.050846,\n    volume: 33757600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-06-16',\n    open: 48.88303461486475,\n    high: 49.82081595103511,\n    low: 48.873161268495245,\n    close: 49.741843,\n    volume: 31188600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-06-17',\n    open: 49.76158642985065,\n    high: 49.78132917392122,\n    low: 49.179175479769086,\n    close: 49.485189,\n    volume: 45710500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-06-20',\n    open: 49.98862620998684,\n    high: 50.17618523710641,\n    low: 49.38647252534533,\n    close: 49.425959,\n    volume: 35607900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-06-21',\n    open: 49.554288151706196,\n    high: 50.76846591382039,\n    low: 49.514801676788466,\n    close: 50.531552,\n    volume: 34097800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-06-22',\n    open: 50.42296934658395,\n    high: 50.798078515193495,\n    low: 50.29464052549218,\n    close: 50.334127,\n    volume: 28816800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-06-23',\n    open: 50.62039457749389,\n    high: 51.39036356698694,\n    low: 50.49206970303572,\n    close: 51.242292,\n    volume: 29028800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-06-24',\n    open: 49.169304269123806,\n    high: 50.28476731610309,\n    low: 48.88303349777108,\n    close: 49.189048,\n    volume: 133503000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-06-27',\n    open: 48.46843495531468,\n    high: 48.517795764280606,\n    low: 47.422072475883844,\n    close: 47.807055,\n    volume: 50216300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-06-28',\n    open: 48.29074967076508,\n    high: 48.833678090164646,\n    low: 48.04396537167964,\n    close: 48.804062,\n    volume: 38140700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-06-29',\n    open: 49.26801757779942,\n    high: 50.067599695732405,\n    low: 49.15943149882576,\n    close: 49.889915,\n    volume: 31304000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-06-30',\n    open: 50.06760021745182,\n    high: 50.640137824281155,\n    low: 49.8504290443787,\n    close: 50.511809,\n    volume: 28527800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-07-01',\n    open: 50.47232587122633,\n    high: 51.054736817473405,\n    low: 50.4130966522674,\n    close: 50.501939,\n    volume: 21400400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-07-05',\n    open: 50.17618629755698,\n    high: 50.62039508010516,\n    low: 50.08734394876501,\n    close: 50.511809,\n    volume: 24806400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-07-06',\n    open: 50.12682570949911,\n    high: 50.87705195099373,\n    low: 49.74184220395189,\n    close: 50.71911,\n    volume: 28167500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-07-07',\n    open: 50.758592526336855,\n    high: 50.946151554553495,\n    low: 50.41309648281245,\n    close: 50.71911,\n    volume: 19585200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-07-08',\n    open: 51.06460777848198,\n    high: 51.68650520676444,\n    low: 50.8869220938747,\n    close: 51.627275,\n    volume: 28391000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-07-11',\n    open: 51.82470265259555,\n    high: 52.15045990068624,\n    low: 51.79508952393126,\n    close: 51.913545,\n    volume: 22269200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-07-12',\n    open: 52.25904195815585,\n    high: 52.71312802789449,\n    low: 52.11097335362793,\n    close: 52.525569,\n    volume: 27317600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-07-13',\n    open: 52.871069821787515,\n    high: 53.16721098404283,\n    low: 52.49595669579356,\n    close: 52.82171,\n    volume: 25356800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-07-14',\n    open: 53.1474667455353,\n    high: 53.295539299524215,\n    low: 52.8908130483045,\n    close: 53.048755,\n    volume: 24545500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-07-15',\n    open: 53.256052297080366,\n    high: 53.30540816935925,\n    low: 52.5255688034481,\n    close: 53.009268,\n    volume: 32024400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-07-18',\n    open: 53.009268303839704,\n    high: 53.64103512084943,\n    low: 52.86119575046838,\n    close: 53.265922,\n    volume: 31433900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-07-19',\n    open: 53.01913807747007,\n    high: 53.20669710706777,\n    low: 52.24917204784328,\n    close: 52.407114,\n    volume: 53336500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-07-20',\n    open: 55.427755902909716,\n    high: 56.10887859846182,\n    low: 54.81572787585689,\n    close: 55.190841,\n    volume: 89893300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-07-21',\n    open: 55.25994068386991,\n    high: 55.50672498488755,\n    low: 55.04276852469998,\n    close: 55.082255,\n    volume: 32776700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-07-22',\n    open: 55.35865574977377,\n    high: 55.901580218708695,\n    low: 55.062511630504666,\n    close: 55.842351,\n    volume: 32157200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-07-25',\n    open: 55.74363831676879,\n    high: 56.01016634621163,\n    low: 55.536336544675024,\n    close: 56.000293,\n    volume: 25610600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-07-26',\n    open: 55.79299504415063,\n    high: 56.55309168210163,\n    low: 55.78312169778772,\n    close: 56.029906,\n    volume: 28079000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-07-27',\n    open: 55.88183759617504,\n    high: 56.06939168895095,\n    low: 55.38826899867426,\n    close: 55.467238,\n    volume: 32327500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-07-28',\n    open: 55.27968317523008,\n    high: 55.644922951929225,\n    low: 55.00328574649114,\n    close: 55.486981,\n    volume: 37550400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-07-29',\n    open: 55.53633739799094,\n    high: 56.02990600243695,\n    low: 55.32903957126082,\n    close: 55.950937,\n    volume: 30558700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-08-01',\n    open: 55.87196279518604,\n    high: 56.02003534747136,\n    low: 55.41788067642303,\n    close: 55.852224,\n    volume: 26003400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-08-02',\n    open: 56.118747091870944,\n    high: 56.16810789975667,\n    low: 55.585695972443126,\n    close: 55.852224,\n    volume: 35122000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-08-03',\n    open: 55.950936226242995,\n    high: 56.37540620733369,\n    low: 55.76338213342165,\n    close: 56.237207,\n    volume: 22075600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-08-04',\n    open: 56.069392051186426,\n    high: 56.78013182331647,\n    low: 55.94106322786996,\n    close: 56.651803,\n    volume: 26587700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-08-05',\n    open: 56.90846143007942,\n    high: 57.46125529946143,\n    low: 56.71103300337308,\n    close: 57.214471,\n    volume: 29335200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-08-08',\n    open: 57.313187,\n    high: 57.342800128956256,\n    low: 57.03678660885336,\n    close: 57.313187,\n    volume: 19473500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-08-09',\n    open: 57.42176892260238,\n    high: 57.747526172722914,\n    low: 57.27370031694673,\n    close: 57.451386,\n    volume: 16920700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-08-10',\n    open: 57.411900209582896,\n    high: 57.56984216339193,\n    low: 57.07627355773871,\n    close: 57.273701,\n    volume: 15756900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-08-11',\n    open: 57.283570954948075,\n    high: 57.698170554858805,\n    low: 57.283570954948075,\n    close: 57.550098,\n    volume: 18162300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-08-12',\n    open: 57.283570347408386,\n    high: 57.44151229835665,\n    low: 56.878844098103485,\n    close: 57.194728,\n    volume: 21655200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-08-15',\n    open: 57.26382692100828,\n    high: 57.74752612263465,\n    low: 57.2144710482116,\n    close: 57.372413,\n    volume: 19283900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-08-16',\n    open: 57.223424246308966,\n    high: 57.23335515736059,\n    low: 56.885704733560324,\n    close: 57.054563,\n    volume: 20523500,\n    split: '',\n    dividend: '$0.360',\n  },\n  {\n    date: '2016-08-17',\n    open: 57.153894204653675,\n    high: 57.29295377878816,\n    low: 56.845973383495945,\n    close: 57.17376,\n    volume: 18856400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-08-18',\n    open: 57.034696840666946,\n    high: 57.312820957276585,\n    low: 56.885705361135614,\n    close: 57.213489,\n    volume: 14214300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-08-19',\n    open: 57.04463093881692,\n    high: 57.34261786693193,\n    low: 56.816175287218506,\n    close: 57.233355,\n    volume: 17271000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-08-22',\n    open: 57.21348871615987,\n    high: 57.36248416811112,\n    low: 56.87577019465065,\n    close: 57.283019,\n    volume: 15221900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-08-23',\n    open: 57.51147987760525,\n    high: 57.789599027631695,\n    low: 57.46181141576651,\n    close: 57.501544,\n    volume: 18732400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-08-24',\n    open: 57.412147548347015,\n    high: 57.65053907904407,\n    low: 57.332686353554045,\n    close: 57.561143,\n    volume: 18151500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-08-25',\n    open: 57.49161294624187,\n    high: 57.8988617524048,\n    low: 57.39228198254942,\n    close: 57.779664,\n    volume: 18552600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-08-26',\n    open: 57.888926440949895,\n    high: 58.30611012832525,\n    low: 57.30288548030815,\n    close: 57.640604,\n    volume: 20971200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-08-29',\n    open: 57.7895991686609,\n    high: 58.20677888800843,\n    low: 57.710134,\n    close: 57.710134,\n    volume: 16417200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-08-30',\n    open: 57.590941072913125,\n    high: 57.79953093207785,\n    low: 57.22342484997355,\n    close: 57.501544,\n    volume: 16930200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-08-31',\n    open: 57.26315703553802,\n    high: 57.41214752067035,\n    low: 56.91550263733159,\n    close: 57.074429,\n    volume: 20860300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-09-01',\n    open: 56.62744794535308,\n    high: 57.43201464768189,\n    low: 56.62744794535308,\n    close: 57.203558,\n    volume: 26075400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-09-02',\n    open: 57.283019,\n    high: 57.79953067324506,\n    low: 57.03469655771381,\n    close: 57.283019,\n    volume: 18900500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-09-06',\n    open: 57.3922812724231,\n    high: 57.41214706759988,\n    low: 56.826106109884925,\n    close: 57.223424,\n    volume: 16278400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-09-07',\n    open: 57.08436393744517,\n    high: 57.451880158168585,\n    low: 57.024765558099205,\n    close: 57.273088,\n    volume: 17493400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-09-08',\n    open: 57.24329094906202,\n    high: 57.40221731367982,\n    low: 56.796309555284694,\n    close: 57.044632,\n    volume: 20146100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-09-09',\n    open: 56.4089270534023,\n    high: 57.13402759249293,\n    low: 55.832817,\n    close: 55.832817,\n    volume: 35113900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-09-12',\n    open: 55.62422772347463,\n    high: 56.82610736492421,\n    low: 55.23684570226164,\n    close: 56.667181,\n    volume: 29303000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-09-13',\n    open: 56.1208713005638,\n    high: 56.269866750773126,\n    low: 55.67388991638459,\n    close: 56.150669,\n    volume: 30130200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-09-14',\n    open: 56.011609664606084,\n    high: 56.250001198231125,\n    low: 55.65402534403785,\n    close: 55.882481,\n    volume: 24062500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-09-15',\n    open: 55.7732226182148,\n    high: 56.96516637004169,\n    low: 55.60436137059558,\n    close: 56.806241,\n    volume: 26847000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-09-16',\n    open: 57.24329010368278,\n    high: 57.24329010368278,\n    low: 56.36919411790393,\n    close: 56.865839,\n    volume: 44607000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-09-19',\n    open: 56.88570552415247,\n    high: 57.3624846170736,\n    low: 56.46852183126692,\n    close: 56.547987,\n    volume: 20937100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-09-20',\n    open: 56.965166497575204,\n    high: 56.965166497575204,\n    low: 56.369194620327505,\n    close: 56.428793,\n    volume: 17384000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-09-21',\n    open: 57.1240925580567,\n    high: 57.46181107909958,\n    low: 56.696981931073296,\n    close: 57.372415,\n    volume: 33707300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-09-22',\n    open: 57.53134098955331,\n    high: 57.61080615703909,\n    low: 57.243289938637396,\n    close: 57.432014,\n    volume: 19822200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-09-23',\n    open: 57.48167850940916,\n    high: 57.52141109385339,\n    low: 56.99496850434672,\n    close: 57.044632,\n    volume: 19955300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-09-26',\n    open: 56.69698115575422,\n    high: 56.75657556113638,\n    low: 56.44865871720668,\n    close: 56.518189,\n    volume: 21688700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-09-27',\n    open: 56.547986444210764,\n    high: 57.6704048743872,\n    low: 56.29966400242168,\n    close: 57.561143,\n    volume: 28065100,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-09-28',\n    open: 57.491612522009596,\n    high: 57.67040467949352,\n    low: 57.28301869174239,\n    close: 57.640604,\n    volume: 20536400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-09-29',\n    open: 57.422081806806105,\n    high: 57.779663139216126,\n    low: 56.826105966427775,\n    close: 57.014834,\n    volume: 25463500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-09-30',\n    open: 57.183692293357375,\n    high: 57.38235024817189,\n    low: 56.95523564532069,\n    close: 57.213489,\n    volume: 29910800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-10-03',\n    open: 57.02476608881108,\n    high: 57.16382566427994,\n    low: 56.67711566020425,\n    close: 57.034697,\n    volume: 19189500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-10-04',\n    open: 56.88570470629963,\n    high: 57.213488341390764,\n    low: 56.587718770797885,\n    close: 56.855908,\n    volume: 20085900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-10-05',\n    open: 56.905572563129674,\n    high: 57.571074730011325,\n    low: 56.87577088982177,\n    close: 57.253222,\n    volume: 16726400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-10-06',\n    open: 57.352553,\n    high: 57.471746778473495,\n    low: 56.89563672837156,\n    close: 57.352553,\n    volume: 16212600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-10-07',\n    open: 57.46181149545875,\n    high: 57.590941152784445,\n    low: 57.03469689222147,\n    close: 57.412148,\n    volume: 20089000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-10-10',\n    open: 57.52141033715696,\n    high: 57.99818843144854,\n    low: 57.48167775323542,\n    close: 57.650539,\n    volume: 18196500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-10-11',\n    open: 57.501543839575156,\n    high: 57.630672503071736,\n    low: 56.50825406875351,\n    close: 56.806241,\n    volume: 26497400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-10-12',\n    open: 56.726779,\n    high: 56.88570436778666,\n    low: 56.02154426601321,\n    close: 56.726779,\n    volume: 22177500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-10-13',\n    open: 56.319531229394144,\n    high: 56.915503107746915,\n    low: 55.94208012164723,\n    close: 56.538052,\n    volume: 25313700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-10-14',\n    open: 56.73671106023555,\n    high: 57.35255370175028,\n    low: 56.73671106023555,\n    close: 57.034697,\n    volume: 27402500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-10-17',\n    open: 56.97510256869869,\n    high: 57.07442955976107,\n    low: 56.488388591673704,\n    close: 56.836042,\n    volume: 23830000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-10-18',\n    open: 57.14395933692182,\n    high: 57.5611430258947,\n    low: 57.024765558099205,\n    close: 57.273088,\n    volume: 19149500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-10-19',\n    open: 57.08436360087473,\n    high: 57.451879819431255,\n    low: 57.01483431084222,\n    close: 57.143959,\n    volume: 22878400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-10-20',\n    open: 57.11416144104804,\n    high: 57.13402723633188,\n    low: 56.27979803912664,\n    close: 56.865839,\n    volume: 49455600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-10-21',\n    open: 59.875505657062234,\n    high: 60.04436690260924,\n    low: 59.09080972761203,\n    close: 59.259667,\n    volume: 80032200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-10-24',\n    open: 59.53778784998892,\n    high: 60.590676,\n    low: 59.527855945573776,\n    close: 60.590676,\n    volume: 54067000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-10-25',\n    open: 60.44168045917608,\n    high: 60.95819213236384,\n    low: 60.39201696401412,\n    close: 60.580745,\n    volume: 35137200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-10-26',\n    open: 60.40195215934698,\n    high: 60.789335171265456,\n    low: 60.06423363613601,\n    close: 60.22316,\n    volume: 29911600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-10-27',\n    open: 60.203294769439324,\n    high: 60.42181951509263,\n    low: 59.68678308874487,\n    close: 59.696714,\n    volume: 28479900,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-10-28',\n    open: 59.60731657325543,\n    high: 60.113896337963865,\n    low: 59.18020594916853,\n    close: 59.468257,\n    volume: 33574700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-10-31',\n    open: 59.756312531252085,\n    high: 60.01456588473448,\n    low: 59.517921,\n    close: 59.517921,\n    volume: 26434700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-11-01',\n    open: 59.567588246761126,\n    high: 59.617251741760064,\n    low: 58.85241862211402,\n    close: 59.398727,\n    volume: 24533000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-11-02',\n    open: 59.41859401009591,\n    high: 59.527855884738344,\n    low: 58.902082336678255,\n    close: 59.031211,\n    volume: 22147000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-11-03',\n    open: 59.13053872484128,\n    high: 59.239800599005484,\n    low: 58.71335901006662,\n    close: 58.812686,\n    volume: 21600400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-11-04',\n    open: 58.25644659408156,\n    high: 58.88221616498338,\n    low: 58.127316938295294,\n    close: 58.316041,\n    volume: 28697000,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-11-07',\n    open: 59.37886153960869,\n    high: 60.11389696371722,\n    low: 59.37886153960869,\n    close: 60.014566,\n    volume: 31664800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-11-08',\n    open: 60.143695195833814,\n    high: 60.37215184527226,\n    low: 59.74638226363628,\n    close: 60.064234,\n    volume: 22935400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-11-09',\n    open: 59.59738672419434,\n    high: 60.18342769364892,\n    low: 58.80275589449486,\n    close: 59.766244,\n    volume: 49632500,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-11-10',\n    open: 60.0741647823822,\n    high: 60.084099666577856,\n    low: 57.24328995507359,\n    close: 58.30611,\n    volume: 57822400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-11-11',\n    open: 57.839264071331755,\n    high: 58.72329098502266,\n    low: 57.62073833246483,\n    close: 58.623963,\n    volume: 38767800,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-11-14',\n    open: 58.62396177949005,\n    high: 58.68356115181626,\n    low: 56.89563659954639,\n    close: 57.73,\n    volume: 41328400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-11-15',\n    open: 58.330002,\n    high: 59.490002,\n    low: 58.32,\n    close: 58.869999,\n    volume: 34764300,\n    split: '',\n    dividend: '$0.390',\n  },\n  {\n    date: '2016-11-16',\n    open: 58.939999,\n    high: 59.66,\n    low: 58.810001,\n    close: 59.650002,\n    volume: 26851400,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-11-17',\n    open: 60.41,\n    high: 60.950001,\n    low: 59.970001,\n    close: 60.639999,\n    volume: 31463700,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-11-18',\n    open: 60.779999,\n    high: 61.139999,\n    low: 60.299999,\n    close: 60.349998,\n    volume: 26580600,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-11-21',\n    open: 60.5,\n    high: 60.970001,\n    low: 60.419998,\n    close: 60.860001,\n    volume: 19563200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-11-22',\n    open: 60.98,\n    high: 61.259998,\n    low: 60.810001,\n    close: 61.119999,\n    volume: 22645300,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-11-23',\n    open: 61.009998,\n    high: 61.099998,\n    low: 60.25,\n    close: 60.400002,\n    volume: 21847200,\n    split: '',\n    dividend: '',\n  },\n  {\n    date: '2016-11-25',\n    open: 60.299999,\n    high: 60.529999,\n    low: 60.130001,\n    close: 60.529999,\n    volume: 8370500,\n    split: '',\n    dividend: '',\n  },\n]\n"
  },
  {
    "path": "packages/component-lib/src/components/charts/scaleAreaChart/KlineChart/data_min.ts",
    "content": "export const testKlineData = [\n  {\n    date: 1460727000000,\n    open: 55.3,\n    high: 55.3,\n    low: 55.25,\n    close: 55.25,\n    volume: 3399547,\n  },\n  {\n    date: 1460727060000,\n    open: 55.24,\n    high: 55.39,\n    low: 55.11,\n    close: 55.37,\n    volume: 253961,\n  },\n  {\n    date: 1460727120000,\n    open: 55.37,\n    high: 55.5299,\n    low: 55.37,\n    close: 55.5299,\n    volume: 127451,\n  },\n  {\n    date: 1460727180000,\n    open: 55.52,\n    high: 55.59,\n    low: 55.52,\n    close: 55.58,\n    volume: 101263,\n  },\n  {\n    date: 1460727240000,\n    open: 55.58,\n    high: 55.59,\n    low: 55.5,\n    close: 55.51,\n    volume: 123661,\n  },\n  {\n    date: 1460727300000,\n    open: 55.505,\n    high: 55.52,\n    low: 55.495,\n    close: 55.5065,\n    volume: 149931,\n  },\n  {\n    date: 1460727360000,\n    open: 55.51,\n    high: 55.63,\n    low: 55.5,\n    close: 55.61,\n    volume: 126985,\n  },\n  {\n    date: 1460727420000,\n    open: 55.605,\n    high: 55.64,\n    low: 55.52,\n    close: 55.55,\n    volume: 86640,\n  },\n  {\n    date: 1460727480000,\n    open: 55.56,\n    high: 55.62,\n    low: 55.55,\n    close: 55.61,\n    volume: 96088,\n  },\n  {\n    date: 1460727540000,\n    open: 55.61,\n    high: 55.62,\n    low: 55.56,\n    close: 55.585,\n    volume: 62305,\n  },\n  {\n    date: 1460727600000,\n    open: 55.58,\n    high: 55.58,\n    low: 55.5,\n    close: 55.52,\n    volume: 35996,\n  },\n  {\n    date: 1460727660000,\n    open: 55.52,\n    high: 55.55,\n    low: 55.5,\n    close: 55.5,\n    volume: 39946,\n  },\n  {\n    date: 1460727720000,\n    open: 55.5,\n    high: 55.54,\n    low: 55.5,\n    close: 55.525,\n    volume: 44578,\n  },\n  {\n    date: 1460727780000,\n    open: 55.52,\n    high: 55.53,\n    low: 55.5,\n    close: 55.5238,\n    volume: 40415,\n  },\n  {\n    date: 1460727840000,\n    open: 55.52,\n    high: 55.53,\n    low: 55.51,\n    close: 55.5233,\n    volume: 17257,\n  },\n  {\n    date: 1460727900000,\n    open: 55.525,\n    high: 55.535,\n    low: 55.5,\n    close: 55.52,\n    volume: 22595,\n  },\n  {\n    date: 1460727960000,\n    open: 55.52,\n    high: 55.52,\n    low: 55.5,\n    close: 55.505,\n    volume: 16175,\n  },\n  {\n    date: 1460728020000,\n    open: 55.51,\n    high: 55.5836,\n    low: 55.5,\n    close: 55.58,\n    volume: 120230,\n  },\n  {\n    date: 1460728080000,\n    open: 55.58,\n    high: 55.63,\n    low: 55.575,\n    close: 55.62,\n    volume: 74342,\n  },\n  {\n    date: 1460728140000,\n    open: 55.6199,\n    high: 55.66,\n    low: 55.61,\n    close: 55.6437,\n    volume: 100564,\n  },\n  {\n    date: 1460728200000,\n    open: 55.65,\n    high: 55.72,\n    low: 55.64,\n    close: 55.71,\n    volume: 139687,\n  },\n  {\n    date: 1460728260000,\n    open: 55.71,\n    high: 55.72,\n    low: 55.64,\n    close: 55.7,\n    volume: 239960,\n  },\n  {\n    date: 1460728320000,\n    open: 55.71,\n    high: 55.79,\n    low: 55.705,\n    close: 55.79,\n    volume: 83387,\n  },\n  {\n    date: 1460728380000,\n    open: 55.78,\n    high: 55.785,\n    low: 55.69,\n    close: 55.76,\n    volume: 115994,\n  },\n  {\n    date: 1460728440000,\n    open: 55.76,\n    high: 55.77,\n    low: 55.71,\n    close: 55.73,\n    volume: 84542,\n  },\n  {\n    date: 1460728500000,\n    open: 55.74,\n    high: 55.7464,\n    low: 55.675,\n    close: 55.6801,\n    volume: 61252,\n  },\n  {\n    date: 1460728560000,\n    open: 55.69,\n    high: 55.72,\n    low: 55.68,\n    close: 55.699,\n    volume: 39175,\n  },\n  {\n    date: 1460728620000,\n    open: 55.7,\n    high: 55.7,\n    low: 55.685,\n    close: 55.69,\n    volume: 60239,\n  },\n  {\n    date: 1460728680000,\n    open: 55.7,\n    high: 55.75,\n    low: 55.69,\n    close: 55.745,\n    volume: 86128,\n  },\n  {\n    date: 1460728740000,\n    open: 55.7499,\n    high: 55.7501,\n    low: 55.735,\n    close: 55.7501,\n    volume: 80104,\n  },\n  {\n    date: 1460728800000,\n    open: 55.75,\n    high: 55.77,\n    low: 55.74,\n    close: 55.7699,\n    volume: 98355,\n  },\n  {\n    date: 1460728860000,\n    open: 55.769,\n    high: 55.8,\n    low: 55.73,\n    close: 55.74,\n    volume: 127501,\n  },\n  {\n    date: 1460728920000,\n    open: 55.74,\n    high: 55.8,\n    low: 55.74,\n    close: 55.78,\n    volume: 55714,\n  },\n  {\n    date: 1460728980000,\n    open: 55.79,\n    high: 55.805,\n    low: 55.74,\n    close: 55.75,\n    volume: 176021,\n  },\n  {\n    date: 1460729040000,\n    open: 55.75,\n    high: 55.77,\n    low: 55.73,\n    close: 55.76,\n    volume: 52884,\n  },\n  {\n    date: 1460729100000,\n    open: 55.76,\n    high: 55.78,\n    low: 55.725,\n    close: 55.755,\n    volume: 120460,\n  },\n  {\n    date: 1460729160000,\n    open: 55.7527,\n    high: 55.76,\n    low: 55.7335,\n    close: 55.75,\n    volume: 94916,\n  },\n  {\n    date: 1460729220000,\n    open: 55.745,\n    high: 55.76,\n    low: 55.74,\n    close: 55.75,\n    volume: 51462,\n  },\n  {\n    date: 1460729280000,\n    open: 55.75,\n    high: 55.8,\n    low: 55.74,\n    close: 55.785,\n    volume: 83604,\n  },\n  {\n    date: 1460729340000,\n    open: 55.78,\n    high: 55.81,\n    low: 55.74,\n    close: 55.805,\n    volume: 75855,\n  },\n  {\n    date: 1460729400000,\n    open: 55.805,\n    high: 55.81,\n    low: 55.775,\n    close: 55.775,\n    volume: 53635,\n  },\n  {\n    date: 1460729460000,\n    open: 55.77,\n    high: 55.795,\n    low: 55.75,\n    close: 55.77,\n    volume: 59901,\n  },\n  {\n    date: 1460729520000,\n    open: 55.775,\n    high: 55.81,\n    low: 55.77,\n    close: 55.7867,\n    volume: 74736,\n  },\n  {\n    date: 1460729580000,\n    open: 55.79,\n    high: 55.82,\n    low: 55.77,\n    close: 55.82,\n    volume: 77197,\n  },\n  {\n    date: 1460729640000,\n    open: 55.82,\n    high: 55.825,\n    low: 55.775,\n    close: 55.815,\n    volume: 46040,\n  },\n  {\n    date: 1460729700000,\n    open: 55.8145,\n    high: 55.8554,\n    low: 55.81,\n    close: 55.8554,\n    volume: 84043,\n  },\n  {\n    date: 1460729760000,\n    open: 55.8501,\n    high: 55.89,\n    low: 55.82,\n    close: 55.825,\n    volume: 86819,\n  },\n  {\n    date: 1460729820000,\n    open: 55.82,\n    high: 55.88,\n    low: 55.82,\n    close: 55.85,\n    volume: 64912,\n  },\n  {\n    date: 1460729880000,\n    open: 55.84,\n    high: 55.86,\n    low: 55.83,\n    close: 55.835,\n    volume: 68115,\n  },\n  {\n    date: 1460729940000,\n    open: 55.835,\n    high: 55.8599,\n    low: 55.83,\n    close: 55.84,\n    volume: 49842,\n  },\n  {\n    date: 1460730000000,\n    open: 55.845,\n    high: 55.85,\n    low: 55.795,\n    close: 55.84,\n    volume: 96899,\n  },\n  {\n    date: 1460730060000,\n    open: 55.835,\n    high: 55.86,\n    low: 55.8342,\n    close: 55.855,\n    volume: 33253,\n  },\n  {\n    date: 1460730120000,\n    open: 55.86,\n    high: 55.88,\n    low: 55.85,\n    close: 55.86,\n    volume: 41537,\n  },\n  {\n    date: 1460730180000,\n    open: 55.865,\n    high: 55.865,\n    low: 55.82,\n    close: 55.855,\n    volume: 44682,\n  },\n  {\n    date: 1460730240000,\n    open: 55.86,\n    high: 55.875,\n    low: 55.84,\n    close: 55.875,\n    volume: 87616,\n  },\n  {\n    date: 1460730300000,\n    open: 55.87,\n    high: 55.9,\n    low: 55.8601,\n    close: 55.8801,\n    volume: 60941,\n  },\n  {\n    date: 1460730360000,\n    open: 55.8809,\n    high: 55.895,\n    low: 55.845,\n    close: 55.85,\n    volume: 37573,\n  },\n  {\n    date: 1460730420000,\n    open: 55.85,\n    high: 55.895,\n    low: 55.831,\n    close: 55.89,\n    volume: 39727,\n  },\n  {\n    date: 1460730480000,\n    open: 55.8899,\n    high: 55.92,\n    low: 55.88,\n    close: 55.91,\n    volume: 68520,\n  },\n  {\n    date: 1460730540000,\n    open: 55.91,\n    high: 55.915,\n    low: 55.8648,\n    close: 55.88,\n    volume: 59788,\n  },\n  {\n    date: 1460730600000,\n    open: 55.88,\n    high: 55.88,\n    low: 55.82,\n    close: 55.845,\n    volume: 64368,\n  },\n  {\n    date: 1460730660000,\n    open: 55.845,\n    high: 55.865,\n    low: 55.81,\n    close: 55.84,\n    volume: 39541,\n  },\n  {\n    date: 1460730720000,\n    open: 55.835,\n    high: 55.85,\n    low: 55.82,\n    close: 55.8335,\n    volume: 17768,\n  },\n  {\n    date: 1460730780000,\n    open: 55.84,\n    high: 55.845,\n    low: 55.81,\n    close: 55.82,\n    volume: 34595,\n  },\n  {\n    date: 1460730840000,\n    open: 55.82,\n    high: 55.83,\n    low: 55.77,\n    close: 55.78,\n    volume: 131385,\n  },\n  {\n    date: 1460730900000,\n    open: 55.78,\n    high: 55.82,\n    low: 55.7716,\n    close: 55.81,\n    volume: 45594,\n  },\n  {\n    date: 1460730960000,\n    open: 55.82,\n    high: 55.8365,\n    low: 55.78,\n    close: 55.7858,\n    volume: 32488,\n  },\n  {\n    date: 1460731020000,\n    open: 55.79,\n    high: 55.83,\n    low: 55.785,\n    close: 55.81,\n    volume: 33095,\n  },\n  {\n    date: 1460731080000,\n    open: 55.812,\n    high: 55.815,\n    low: 55.79,\n    close: 55.7964,\n    volume: 24527,\n  },\n  {\n    date: 1460731140000,\n    open: 55.8,\n    high: 55.8,\n    low: 55.74,\n    close: 55.76,\n    volume: 65555,\n  },\n  {\n    date: 1460731200000,\n    open: 55.76,\n    high: 55.76,\n    low: 55.73,\n    close: 55.7461,\n    volume: 47269,\n  },\n  {\n    date: 1460731260000,\n    open: 55.7499,\n    high: 55.76,\n    low: 55.74,\n    close: 55.7599,\n    volume: 24187,\n  },\n  {\n    date: 1460731320000,\n    open: 55.76,\n    high: 55.78,\n    low: 55.7401,\n    close: 55.76,\n    volume: 109218,\n  },\n  {\n    date: 1460731380000,\n    open: 55.76,\n    high: 55.8,\n    low: 55.76,\n    close: 55.8,\n    volume: 52788,\n  },\n  {\n    date: 1460731440000,\n    open: 55.795,\n    high: 55.8,\n    low: 55.79,\n    close: 55.8,\n    volume: 51201,\n  },\n  {\n    date: 1460731500000,\n    open: 55.8,\n    high: 55.83,\n    low: 55.78,\n    close: 55.83,\n    volume: 47082,\n  },\n  {\n    date: 1460731560000,\n    open: 55.83,\n    high: 55.86,\n    low: 55.82,\n    close: 55.82,\n    volume: 59396,\n  },\n  {\n    date: 1460731620000,\n    open: 55.81,\n    high: 55.81,\n    low: 55.77,\n    close: 55.78,\n    volume: 25316,\n  },\n  {\n    date: 1460731680000,\n    open: 55.79,\n    high: 55.79,\n    low: 55.7601,\n    close: 55.77,\n    volume: 16402,\n  },\n  {\n    date: 1460731740000,\n    open: 55.77,\n    high: 55.78,\n    low: 55.76,\n    close: 55.7736,\n    volume: 20268,\n  },\n  {\n    date: 1460731800000,\n    open: 55.775,\n    high: 55.83,\n    low: 55.77,\n    close: 55.83,\n    volume: 22863,\n  },\n  {\n    date: 1460731860000,\n    open: 55.8238,\n    high: 55.84,\n    low: 55.815,\n    close: 55.84,\n    volume: 33095,\n  },\n  {\n    date: 1460731920000,\n    open: 55.8361,\n    high: 55.84,\n    low: 55.82,\n    close: 55.825,\n    volume: 11610,\n  },\n  {\n    date: 1460731980000,\n    open: 55.83,\n    high: 55.85,\n    low: 55.8199,\n    close: 55.83,\n    volume: 76533,\n  },\n  {\n    date: 1460732040000,\n    open: 55.83,\n    high: 55.83,\n    low: 55.8,\n    close: 55.805,\n    volume: 19637,\n  },\n  {\n    date: 1460732100000,\n    open: 55.804,\n    high: 55.81,\n    low: 55.79,\n    close: 55.8,\n    volume: 16785,\n  },\n  {\n    date: 1460732160000,\n    open: 55.79,\n    high: 55.81,\n    low: 55.77,\n    close: 55.78,\n    volume: 32786,\n  },\n  {\n    date: 1460732220000,\n    open: 55.79,\n    high: 55.81,\n    low: 55.79,\n    close: 55.81,\n    volume: 17408,\n  },\n  {\n    date: 1460732280000,\n    open: 55.8038,\n    high: 55.81,\n    low: 55.785,\n    close: 55.805,\n    volume: 33830,\n  },\n  {\n    date: 1460732340000,\n    open: 55.81,\n    high: 55.82,\n    low: 55.8,\n    close: 55.81,\n    volume: 22762,\n  },\n  {\n    date: 1460732400000,\n    open: 55.8,\n    high: 55.84,\n    low: 55.78,\n    close: 55.78,\n    volume: 32796,\n  },\n  {\n    date: 1460732460000,\n    open: 55.7801,\n    high: 55.79,\n    low: 55.77,\n    close: 55.79,\n    volume: 43262,\n  },\n  {\n    date: 1460732520000,\n    open: 55.79,\n    high: 55.795,\n    low: 55.78,\n    close: 55.79,\n    volume: 14810,\n  },\n  {\n    date: 1460732580000,\n    open: 55.79,\n    high: 55.805,\n    low: 55.77,\n    close: 55.77,\n    volume: 43974,\n  },\n  {\n    date: 1460732640000,\n    open: 55.77,\n    high: 55.7999,\n    low: 55.765,\n    close: 55.765,\n    volume: 44148,\n  },\n  {\n    date: 1460732700000,\n    open: 55.77,\n    high: 55.78,\n    low: 55.76,\n    close: 55.77,\n    volume: 19445,\n  },\n  {\n    date: 1460732760000,\n    open: 55.77,\n    high: 55.775,\n    low: 55.725,\n    close: 55.73,\n    volume: 81213,\n  },\n  {\n    date: 1460732820000,\n    open: 55.73,\n    high: 55.7499,\n    low: 55.72,\n    close: 55.72,\n    volume: 34281,\n  },\n  {\n    date: 1460732880000,\n    open: 55.72,\n    high: 55.72,\n    low: 55.695,\n    close: 55.71,\n    volume: 70537,\n  },\n  {\n    date: 1460732940000,\n    open: 55.705,\n    high: 55.73,\n    low: 55.7,\n    close: 55.72,\n    volume: 47674,\n  },\n  {\n    date: 1460733000000,\n    open: 55.72,\n    high: 55.74,\n    low: 55.69,\n    close: 55.71,\n    volume: 49875,\n  },\n  {\n    date: 1460733060000,\n    open: 55.71,\n    high: 55.735,\n    low: 55.695,\n    close: 55.71,\n    volume: 85974,\n  },\n  {\n    date: 1460733120000,\n    open: 55.715,\n    high: 55.75,\n    low: 55.715,\n    close: 55.72,\n    volume: 59906,\n  },\n  {\n    date: 1460733180000,\n    open: 55.725,\n    high: 55.75,\n    low: 55.69,\n    close: 55.715,\n    volume: 145854,\n  },\n  {\n    date: 1460733240000,\n    open: 55.719,\n    high: 55.725,\n    low: 55.7,\n    close: 55.72,\n    volume: 45495,\n  },\n  {\n    date: 1460733300000,\n    open: 55.72,\n    high: 55.73,\n    low: 55.7,\n    close: 55.73,\n    volume: 35534,\n  },\n  {\n    date: 1460733360000,\n    open: 55.725,\n    high: 55.75,\n    low: 55.725,\n    close: 55.75,\n    volume: 36370,\n  },\n  {\n    date: 1460733420000,\n    open: 55.745,\n    high: 55.75,\n    low: 55.71,\n    close: 55.7267,\n    volume: 35040,\n  },\n  {\n    date: 1460733480000,\n    open: 55.72,\n    high: 55.73,\n    low: 55.71,\n    close: 55.715,\n    volume: 24869,\n  },\n  {\n    date: 1460733540000,\n    open: 55.7192,\n    high: 55.74,\n    low: 55.71,\n    close: 55.74,\n    volume: 28415,\n  },\n  {\n    date: 1460733600000,\n    open: 55.74,\n    high: 55.75,\n    low: 55.7301,\n    close: 55.75,\n    volume: 35403,\n  },\n  {\n    date: 1460733660000,\n    open: 55.75,\n    high: 55.76,\n    low: 55.725,\n    close: 55.75,\n    volume: 55479,\n  },\n  {\n    date: 1460733720000,\n    open: 55.75,\n    high: 55.76,\n    low: 55.7401,\n    close: 55.755,\n    volume: 48690,\n  },\n  {\n    date: 1460733780000,\n    open: 55.75,\n    high: 55.76,\n    low: 55.74,\n    close: 55.75,\n    volume: 34400,\n  },\n  {\n    date: 1460733840000,\n    open: 55.7575,\n    high: 55.76,\n    low: 55.74,\n    close: 55.76,\n    volume: 20475,\n  },\n  {\n    date: 1460733900000,\n    open: 55.75,\n    high: 55.755,\n    low: 55.71,\n    close: 55.735,\n    volume: 56586,\n  },\n  {\n    date: 1460733960000,\n    open: 55.7363,\n    high: 55.76,\n    low: 55.73,\n    close: 55.745,\n    volume: 45510,\n  },\n  {\n    date: 1460734020000,\n    open: 55.74,\n    high: 55.77,\n    low: 55.73,\n    close: 55.7462,\n    volume: 56101,\n  },\n  {\n    date: 1460734080000,\n    open: 55.745,\n    high: 55.765,\n    low: 55.73,\n    close: 55.7601,\n    volume: 25501,\n  },\n  {\n    date: 1460734140000,\n    open: 55.7699,\n    high: 55.77,\n    low: 55.74,\n    close: 55.76,\n    volume: 19758,\n  },\n  {\n    date: 1460734200000,\n    open: 55.76,\n    high: 55.77,\n    low: 55.75,\n    close: 55.76,\n    volume: 14410,\n  },\n  {\n    date: 1460734260000,\n    open: 55.77,\n    high: 55.7799,\n    low: 55.735,\n    close: 55.74,\n    volume: 24848,\n  },\n  {\n    date: 1460734320000,\n    open: 55.74,\n    high: 55.77,\n    low: 55.735,\n    close: 55.74,\n    volume: 29375,\n  },\n  {\n    date: 1460734380000,\n    open: 55.74,\n    high: 55.75,\n    low: 55.73,\n    close: 55.73,\n    volume: 17949,\n  },\n  {\n    date: 1460734440000,\n    open: 55.7325,\n    high: 55.74,\n    low: 55.73,\n    close: 55.74,\n    volume: 8153,\n  },\n  {\n    date: 1460734500000,\n    open: 55.74,\n    high: 55.74,\n    low: 55.73,\n    close: 55.74,\n    volume: 36254,\n  },\n  {\n    date: 1460734560000,\n    open: 55.735,\n    high: 55.77,\n    low: 55.73,\n    close: 55.76,\n    volume: 76928,\n  },\n  {\n    date: 1460734620000,\n    open: 55.7528,\n    high: 55.77,\n    low: 55.75,\n    close: 55.77,\n    volume: 29448,\n  },\n  {\n    date: 1460734680000,\n    open: 55.765,\n    high: 55.78,\n    low: 55.76,\n    close: 55.78,\n    volume: 16670,\n  },\n  {\n    date: 1460734740000,\n    open: 55.78,\n    high: 55.79,\n    low: 55.77,\n    close: 55.7701,\n    volume: 26069,\n  },\n  {\n    date: 1460734800000,\n    open: 55.78,\n    high: 55.78,\n    low: 55.71,\n    close: 55.72,\n    volume: 49897,\n  },\n  {\n    date: 1460734860000,\n    open: 55.72,\n    high: 55.75,\n    low: 55.72,\n    close: 55.75,\n    volume: 30420,\n  },\n  {\n    date: 1460734920000,\n    open: 55.74,\n    high: 55.75,\n    low: 55.7,\n    close: 55.72,\n    volume: 93811,\n  },\n  {\n    date: 1460734980000,\n    open: 55.72,\n    high: 55.725,\n    low: 55.7,\n    close: 55.715,\n    volume: 15592,\n  },\n  {\n    date: 1460735040000,\n    open: 55.72,\n    high: 55.74,\n    low: 55.71,\n    close: 55.73,\n    volume: 18233,\n  },\n  {\n    date: 1460735100000,\n    open: 55.73,\n    high: 55.74,\n    low: 55.715,\n    close: 55.729,\n    volume: 30073,\n  },\n  {\n    date: 1460735160000,\n    open: 55.725,\n    high: 55.725,\n    low: 55.7,\n    close: 55.71,\n    volume: 19944,\n  },\n  {\n    date: 1460735220000,\n    open: 55.71,\n    high: 55.73,\n    low: 55.7,\n    close: 55.71,\n    volume: 16861,\n  },\n  {\n    date: 1460735280000,\n    open: 55.7016,\n    high: 55.71,\n    low: 55.7,\n    close: 55.7001,\n    volume: 6762,\n  },\n  {\n    date: 1460735340000,\n    open: 55.7,\n    high: 55.71,\n    low: 55.68,\n    close: 55.71,\n    volume: 48130,\n  },\n  {\n    date: 1460735400000,\n    open: 55.71,\n    high: 55.73,\n    low: 55.7,\n    close: 55.7,\n    volume: 22150,\n  },\n  {\n    date: 1460735460000,\n    open: 55.7,\n    high: 55.73,\n    low: 55.7,\n    close: 55.72,\n    volume: 30198,\n  },\n  {\n    date: 1460735520000,\n    open: 55.73,\n    high: 55.73,\n    low: 55.69,\n    close: 55.705,\n    volume: 53952,\n  },\n  {\n    date: 1460735580000,\n    open: 55.71,\n    high: 55.71,\n    low: 55.69,\n    close: 55.7,\n    volume: 17930,\n  },\n  {\n    date: 1460735640000,\n    open: 55.7,\n    high: 55.72,\n    low: 55.7,\n    close: 55.705,\n    volume: 25918,\n  },\n  {\n    date: 1460735700000,\n    open: 55.7,\n    high: 55.73,\n    low: 55.7,\n    close: 55.72,\n    volume: 11680,\n  },\n  {\n    date: 1460735760000,\n    open: 55.72,\n    high: 55.74,\n    low: 55.72,\n    close: 55.735,\n    volume: 28507,\n  },\n  {\n    date: 1460735820000,\n    open: 55.735,\n    high: 55.74,\n    low: 55.73,\n    close: 55.7338,\n    volume: 36401,\n  },\n  {\n    date: 1460735880000,\n    open: 55.7375,\n    high: 55.75,\n    low: 55.73,\n    close: 55.7437,\n    volume: 26757,\n  },\n  {\n    date: 1460735940000,\n    open: 55.745,\n    high: 55.765,\n    low: 55.74,\n    close: 55.74,\n    volume: 72533,\n  },\n  {\n    date: 1460736000000,\n    open: 55.74,\n    high: 55.75,\n    low: 55.73,\n    close: 55.73,\n    volume: 28112,\n  },\n  {\n    date: 1460736060000,\n    open: 55.74,\n    high: 55.74,\n    low: 55.7,\n    close: 55.72,\n    volume: 38786,\n  },\n  {\n    date: 1460736120000,\n    open: 55.7102,\n    high: 55.725,\n    low: 55.71,\n    close: 55.71,\n    volume: 18429,\n  },\n  {\n    date: 1460736180000,\n    open: 55.72,\n    high: 55.72,\n    low: 55.71,\n    close: 55.72,\n    volume: 7367,\n  },\n  {\n    date: 1460736240000,\n    open: 55.7133,\n    high: 55.75,\n    low: 55.7133,\n    close: 55.748,\n    volume: 26052,\n  },\n  {\n    date: 1460736300000,\n    open: 55.75,\n    high: 55.75,\n    low: 55.7237,\n    close: 55.74,\n    volume: 24857,\n  },\n  {\n    date: 1460736360000,\n    open: 55.73,\n    high: 55.74,\n    low: 55.71,\n    close: 55.74,\n    volume: 25377,\n  },\n  {\n    date: 1460736420000,\n    open: 55.74,\n    high: 55.75,\n    low: 55.74,\n    close: 55.75,\n    volume: 11160,\n  },\n  {\n    date: 1460736480000,\n    open: 55.75,\n    high: 55.766,\n    low: 55.75,\n    close: 55.755,\n    volume: 12313,\n  },\n  {\n    date: 1460736540000,\n    open: 55.755,\n    high: 55.767,\n    low: 55.75,\n    close: 55.76,\n    volume: 15584,\n  },\n  {\n    date: 1460736600000,\n    open: 55.76,\n    high: 55.765,\n    low: 55.75,\n    close: 55.76,\n    volume: 5764,\n  },\n  {\n    date: 1460736660000,\n    open: 55.76,\n    high: 55.78,\n    low: 55.7536,\n    close: 55.78,\n    volume: 22609,\n  },\n  {\n    date: 1460736720000,\n    open: 55.78,\n    high: 55.78,\n    low: 55.75,\n    close: 55.775,\n    volume: 15464,\n  },\n  {\n    date: 1460736780000,\n    open: 55.78,\n    high: 55.78,\n    low: 55.77,\n    close: 55.78,\n    volume: 13828,\n  },\n  {\n    date: 1460736840000,\n    open: 55.7725,\n    high: 55.79,\n    low: 55.77,\n    close: 55.7842,\n    volume: 12254,\n  },\n  {\n    date: 1460736900000,\n    open: 55.78,\n    high: 55.79,\n    low: 55.74,\n    close: 55.75,\n    volume: 76668,\n  },\n  {\n    date: 1460736960000,\n    open: 55.7463,\n    high: 55.7463,\n    low: 55.72,\n    close: 55.72,\n    volume: 21869,\n  },\n  {\n    date: 1460737020000,\n    open: 55.7201,\n    high: 55.73,\n    low: 55.71,\n    close: 55.715,\n    volume: 14693,\n  },\n  {\n    date: 1460737080000,\n    open: 55.72,\n    high: 55.74,\n    low: 55.71,\n    close: 55.74,\n    volume: 14922,\n  },\n  {\n    date: 1460737140000,\n    open: 55.7463,\n    high: 55.77,\n    low: 55.7463,\n    close: 55.755,\n    volume: 30150,\n  },\n  {\n    date: 1460737200000,\n    open: 55.76,\n    high: 55.76,\n    low: 55.75,\n    close: 55.755,\n    volume: 7917,\n  },\n  {\n    date: 1460737260000,\n    open: 55.75,\n    high: 55.78,\n    low: 55.74,\n    close: 55.77,\n    volume: 64271,\n  },\n  {\n    date: 1460737320000,\n    open: 55.775,\n    high: 55.795,\n    low: 55.77,\n    close: 55.79,\n    volume: 34924,\n  },\n  {\n    date: 1460737380000,\n    open: 55.79,\n    high: 55.81,\n    low: 55.79,\n    close: 55.805,\n    volume: 73760,\n  },\n  {\n    date: 1460737440000,\n    open: 55.8,\n    high: 55.8037,\n    low: 55.775,\n    close: 55.7801,\n    volume: 35494,\n  },\n  {\n    date: 1460737500000,\n    open: 55.785,\n    high: 55.79,\n    low: 55.773,\n    close: 55.775,\n    volume: 7364,\n  },\n  {\n    date: 1460737560000,\n    open: 55.77,\n    high: 55.77,\n    low: 55.74,\n    close: 55.765,\n    volume: 35966,\n  },\n  {\n    date: 1460737620000,\n    open: 55.77,\n    high: 55.77,\n    low: 55.75,\n    close: 55.755,\n    volume: 11259,\n  },\n  {\n    date: 1460737680000,\n    open: 55.755,\n    high: 55.76,\n    low: 55.75,\n    close: 55.755,\n    volume: 31265,\n  },\n  {\n    date: 1460737740000,\n    open: 55.755,\n    high: 55.77,\n    low: 55.75,\n    close: 55.765,\n    volume: 43110,\n  },\n  {\n    date: 1460737800000,\n    open: 55.77,\n    high: 55.77,\n    low: 55.75,\n    close: 55.76,\n    volume: 16859,\n  },\n  {\n    date: 1460737860000,\n    open: 55.76,\n    high: 55.76,\n    low: 55.75,\n    close: 55.7538,\n    volume: 3623,\n  },\n  {\n    date: 1460737920000,\n    open: 55.7563,\n    high: 55.76,\n    low: 55.745,\n    close: 55.755,\n    volume: 44887,\n  },\n  {\n    date: 1460737980000,\n    open: 55.755,\n    high: 55.77,\n    low: 55.745,\n    close: 55.765,\n    volume: 30736,\n  },\n  {\n    date: 1460738040000,\n    open: 55.76,\n    high: 55.77,\n    low: 55.75,\n    close: 55.755,\n    volume: 16859,\n  },\n  {\n    date: 1460738100000,\n    open: 55.75,\n    high: 55.77,\n    low: 55.74,\n    close: 55.77,\n    volume: 16519,\n  },\n  {\n    date: 1460738160000,\n    open: 55.77,\n    high: 55.77,\n    low: 55.695,\n    close: 55.7199,\n    volume: 87759,\n  },\n  {\n    date: 1460738220000,\n    open: 55.72,\n    high: 55.74,\n    low: 55.71,\n    close: 55.71,\n    volume: 21524,\n  },\n  {\n    date: 1460738280000,\n    open: 55.72,\n    high: 55.74,\n    low: 55.715,\n    close: 55.73,\n    volume: 19310,\n  },\n  {\n    date: 1460738340000,\n    open: 55.7201,\n    high: 55.755,\n    low: 55.72,\n    close: 55.755,\n    volume: 40372,\n  },\n  {\n    date: 1460738400000,\n    open: 55.76,\n    high: 55.76,\n    low: 55.75,\n    close: 55.75,\n    volume: 32131,\n  },\n  {\n    date: 1460738460000,\n    open: 55.75,\n    high: 55.76,\n    low: 55.7,\n    close: 55.755,\n    volume: 44963,\n  },\n  {\n    date: 1460738520000,\n    open: 55.7563,\n    high: 55.77,\n    low: 55.7534,\n    close: 55.76,\n    volume: 16116,\n  },\n  {\n    date: 1460738580000,\n    open: 55.76,\n    high: 55.77,\n    low: 55.7525,\n    close: 55.77,\n    volume: 6044,\n  },\n  {\n    date: 1460738640000,\n    open: 55.765,\n    high: 55.77,\n    low: 55.745,\n    close: 55.76,\n    volume: 61363,\n  },\n  {\n    date: 1460738700000,\n    open: 55.754,\n    high: 55.76,\n    low: 55.75,\n    close: 55.75,\n    volume: 19916,\n  },\n  {\n    date: 1460738760000,\n    open: 55.7522,\n    high: 55.7599,\n    low: 55.75,\n    close: 55.75,\n    volume: 12675,\n  },\n  {\n    date: 1460738820000,\n    open: 55.75,\n    high: 55.76,\n    low: 55.75,\n    close: 55.75,\n    volume: 2402,\n  },\n  {\n    date: 1460738880000,\n    open: 55.755,\n    high: 55.76,\n    low: 55.75,\n    close: 55.755,\n    volume: 3900,\n  },\n  {\n    date: 1460738940000,\n    open: 55.76,\n    high: 55.76,\n    low: 55.75,\n    close: 55.75,\n    volume: 5305,\n  },\n  {\n    date: 1460739000000,\n    open: 55.75,\n    high: 55.76,\n    low: 55.75,\n    close: 55.76,\n    volume: 6120,\n  },\n  {\n    date: 1460739060000,\n    open: 55.7595,\n    high: 55.76,\n    low: 55.745,\n    close: 55.75,\n    volume: 52908,\n  },\n  {\n    date: 1460739120000,\n    open: 55.7501,\n    high: 55.76,\n    low: 55.75,\n    close: 55.755,\n    volume: 7806,\n  },\n  {\n    date: 1460739180000,\n    open: 55.75,\n    high: 55.785,\n    low: 55.75,\n    close: 55.76,\n    volume: 36102,\n  },\n  {\n    date: 1460739240000,\n    open: 55.765,\n    high: 55.77,\n    low: 55.75,\n    close: 55.755,\n    volume: 11535,\n  },\n  {\n    date: 1460739300000,\n    open: 55.75,\n    high: 55.77,\n    low: 55.74,\n    close: 55.77,\n    volume: 17805,\n  },\n  {\n    date: 1460739360000,\n    open: 55.76,\n    high: 55.78,\n    low: 55.76,\n    close: 55.7636,\n    volume: 13668,\n  },\n  {\n    date: 1460739420000,\n    open: 55.765,\n    high: 55.78,\n    low: 55.76,\n    close: 55.77,\n    volume: 12392,\n  },\n  {\n    date: 1460739480000,\n    open: 55.78,\n    high: 55.78,\n    low: 55.77,\n    close: 55.77,\n    volume: 8073,\n  },\n  {\n    date: 1460739540000,\n    open: 55.7775,\n    high: 55.78,\n    low: 55.7742,\n    close: 55.775,\n    volume: 4131,\n  },\n  {\n    date: 1460739600000,\n    open: 55.78,\n    high: 55.78,\n    low: 55.75,\n    close: 55.75,\n    volume: 16266,\n  },\n  {\n    date: 1460739660000,\n    open: 55.75,\n    high: 55.76,\n    low: 55.75,\n    close: 55.75,\n    volume: 6629,\n  },\n  {\n    date: 1460739720000,\n    open: 55.7532,\n    high: 55.76,\n    low: 55.74,\n    close: 55.74,\n    volume: 67770,\n  },\n  {\n    date: 1460739780000,\n    open: 55.7399,\n    high: 55.7558,\n    low: 55.72,\n    close: 55.74,\n    volume: 20604,\n  },\n  {\n    date: 1460739840000,\n    open: 55.74,\n    high: 55.76,\n    low: 55.731,\n    close: 55.731,\n    volume: 32800,\n  },\n  {\n    date: 1460739900000,\n    open: 55.73,\n    high: 55.75,\n    low: 55.7101,\n    close: 55.7425,\n    volume: 61179,\n  },\n  {\n    date: 1460739960000,\n    open: 55.7499,\n    high: 55.75,\n    low: 55.73,\n    close: 55.735,\n    volume: 22530,\n  },\n  {\n    date: 1460740020000,\n    open: 55.74,\n    high: 55.76,\n    low: 55.735,\n    close: 55.75,\n    volume: 20928,\n  },\n  {\n    date: 1460740080000,\n    open: 55.75,\n    high: 55.76,\n    low: 55.745,\n    close: 55.75,\n    volume: 11024,\n  },\n  {\n    date: 1460740140000,\n    open: 55.75,\n    high: 55.76,\n    low: 55.75,\n    close: 55.7538,\n    volume: 17719,\n  },\n  {\n    date: 1460740200000,\n    open: 55.755,\n    high: 55.76,\n    low: 55.75,\n    close: 55.75,\n    volume: 36697,\n  },\n  {\n    date: 1460740260000,\n    open: 55.7542,\n    high: 55.759,\n    low: 55.71,\n    close: 55.71,\n    volume: 27964,\n  },\n  {\n    date: 1460740320000,\n    open: 55.714,\n    high: 55.73,\n    low: 55.71,\n    close: 55.72,\n    volume: 24343,\n  },\n  {\n    date: 1460740380000,\n    open: 55.72,\n    high: 55.73,\n    low: 55.72,\n    close: 55.72,\n    volume: 4458,\n  },\n  {\n    date: 1460740440000,\n    open: 55.72,\n    high: 55.73,\n    low: 55.72,\n    close: 55.73,\n    volume: 71217,\n  },\n  {\n    date: 1460740500000,\n    open: 55.729,\n    high: 55.73,\n    low: 55.7101,\n    close: 55.724,\n    volume: 33675,\n  },\n  {\n    date: 1460740560000,\n    open: 55.727,\n    high: 55.75,\n    low: 55.72,\n    close: 55.75,\n    volume: 23540,\n  },\n  {\n    date: 1460740620000,\n    open: 55.755,\n    high: 55.755,\n    low: 55.72,\n    close: 55.74,\n    volume: 32343,\n  },\n  {\n    date: 1460740680000,\n    open: 55.75,\n    high: 55.75,\n    low: 55.74,\n    close: 55.745,\n    volume: 7175,\n  },\n  {\n    date: 1460740740000,\n    open: 55.74,\n    high: 55.75,\n    low: 55.7,\n    close: 55.711,\n    volume: 36916,\n  },\n  {\n    date: 1460740800000,\n    open: 55.71,\n    high: 55.72,\n    low: 55.695,\n    close: 55.715,\n    volume: 33613,\n  },\n  {\n    date: 1460740860000,\n    open: 55.715,\n    high: 55.75,\n    low: 55.71,\n    close: 55.7499,\n    volume: 21823,\n  },\n  {\n    date: 1460740920000,\n    open: 55.74,\n    high: 55.745,\n    low: 55.72,\n    close: 55.72,\n    volume: 29141,\n  },\n  {\n    date: 1460740980000,\n    open: 55.725,\n    high: 55.7475,\n    low: 55.725,\n    close: 55.735,\n    volume: 29176,\n  },\n  {\n    date: 1460741040000,\n    open: 55.733,\n    high: 55.75,\n    low: 55.7327,\n    close: 55.75,\n    volume: 12172,\n  },\n  {\n    date: 1460741100000,\n    open: 55.75,\n    high: 55.75,\n    low: 55.715,\n    close: 55.715,\n    volume: 25841,\n  },\n  {\n    date: 1460741160000,\n    open: 55.714,\n    high: 55.72,\n    low: 55.71,\n    close: 55.71,\n    volume: 16999,\n  },\n  {\n    date: 1460741220000,\n    open: 55.719,\n    high: 55.72,\n    low: 55.69,\n    close: 55.71,\n    volume: 88584,\n  },\n  {\n    date: 1460741280000,\n    open: 55.71,\n    high: 55.725,\n    low: 55.7,\n    close: 55.72,\n    volume: 29875,\n  },\n  {\n    date: 1460741340000,\n    open: 55.719,\n    high: 55.72,\n    low: 55.6901,\n    close: 55.705,\n    volume: 23123,\n  },\n  {\n    date: 1460741400000,\n    open: 55.7,\n    high: 55.72,\n    low: 55.69,\n    close: 55.715,\n    volume: 41599,\n  },\n  {\n    date: 1460741460000,\n    open: 55.71,\n    high: 55.72,\n    low: 55.66,\n    close: 55.69,\n    volume: 55270,\n  },\n  {\n    date: 1460741520000,\n    open: 55.6911,\n    high: 55.701,\n    low: 55.68,\n    close: 55.695,\n    volume: 16582,\n  },\n  {\n    date: 1460741580000,\n    open: 55.69,\n    high: 55.71,\n    low: 55.67,\n    close: 55.67,\n    volume: 30681,\n  },\n  {\n    date: 1460741640000,\n    open: 55.67,\n    high: 55.705,\n    low: 55.665,\n    close: 55.68,\n    volume: 37554,\n  },\n  {\n    date: 1460741700000,\n    open: 55.671,\n    high: 55.71,\n    low: 55.671,\n    close: 55.69,\n    volume: 31356,\n  },\n  {\n    date: 1460741760000,\n    open: 55.69,\n    high: 55.71,\n    low: 55.68,\n    close: 55.68,\n    volume: 28225,\n  },\n  {\n    date: 1460741820000,\n    open: 55.685,\n    high: 55.7,\n    low: 55.65,\n    close: 55.65,\n    volume: 21736,\n  },\n  {\n    date: 1460741880000,\n    open: 55.6598,\n    high: 55.66,\n    low: 55.61,\n    close: 55.6199,\n    volume: 56264,\n  },\n  {\n    date: 1460741940000,\n    open: 55.62,\n    high: 55.62,\n    low: 55.57,\n    close: 55.579,\n    volume: 36346,\n  },\n  {\n    date: 1460742000000,\n    open: 55.58,\n    high: 55.6,\n    low: 55.5767,\n    close: 55.6,\n    volume: 27253,\n  },\n  {\n    date: 1460742060000,\n    open: 55.5934,\n    high: 55.64,\n    low: 55.59,\n    close: 55.64,\n    volume: 31052,\n  },\n  {\n    date: 1460742120000,\n    open: 55.63,\n    high: 55.63,\n    low: 55.605,\n    close: 55.6236,\n    volume: 23105,\n  },\n  {\n    date: 1460742180000,\n    open: 55.625,\n    high: 55.65,\n    low: 55.61,\n    close: 55.615,\n    volume: 24097,\n  },\n  {\n    date: 1460742240000,\n    open: 55.6161,\n    high: 55.62,\n    low: 55.6,\n    close: 55.6,\n    volume: 6892,\n  },\n  {\n    date: 1460742300000,\n    open: 55.6,\n    high: 55.605,\n    low: 55.58,\n    close: 55.6,\n    volume: 16098,\n  },\n  {\n    date: 1460742360000,\n    open: 55.5936,\n    high: 55.61,\n    low: 55.5801,\n    close: 55.61,\n    volume: 17518,\n  },\n  {\n    date: 1460742420000,\n    open: 55.605,\n    high: 55.61,\n    low: 55.58,\n    close: 55.58,\n    volume: 25518,\n  },\n  {\n    date: 1460742480000,\n    open: 55.58,\n    high: 55.59,\n    low: 55.565,\n    close: 55.585,\n    volume: 19398,\n  },\n  {\n    date: 1460742540000,\n    open: 55.58,\n    high: 55.59,\n    low: 55.545,\n    close: 55.545,\n    volume: 27720,\n  },\n  {\n    date: 1460742600000,\n    open: 55.54,\n    high: 55.57,\n    low: 55.54,\n    close: 55.57,\n    volume: 43048,\n  },\n  {\n    date: 1460742660000,\n    open: 55.57,\n    high: 55.58,\n    low: 55.5409,\n    close: 55.5438,\n    volume: 26847,\n  },\n  {\n    date: 1460742720000,\n    open: 55.5495,\n    high: 55.55,\n    low: 55.5301,\n    close: 55.5301,\n    volume: 29218,\n  },\n  {\n    date: 1460742780000,\n    open: 55.535,\n    high: 55.54,\n    low: 55.51,\n    close: 55.52,\n    volume: 11017,\n  },\n  {\n    date: 1460742840000,\n    open: 55.525,\n    high: 55.535,\n    low: 55.511,\n    close: 55.52,\n    volume: 20739,\n  },\n  {\n    date: 1460742900000,\n    open: 55.51,\n    high: 55.52,\n    low: 55.5,\n    close: 55.5099,\n    volume: 32457,\n  },\n  {\n    date: 1460742960000,\n    open: 55.51,\n    high: 55.51,\n    low: 55.5,\n    close: 55.51,\n    volume: 12391,\n  },\n  {\n    date: 1460743020000,\n    open: 55.51,\n    high: 55.5401,\n    low: 55.51,\n    close: 55.5101,\n    volume: 37242,\n  },\n  {\n    date: 1460743080000,\n    open: 55.52,\n    high: 55.52,\n    low: 55.49,\n    close: 55.4901,\n    volume: 27753,\n  },\n  {\n    date: 1460743140000,\n    open: 55.49,\n    high: 55.52,\n    low: 55.49,\n    close: 55.52,\n    volume: 20905,\n  },\n  {\n    date: 1460743200000,\n    open: 55.52,\n    high: 55.53,\n    low: 55.52,\n    close: 55.52,\n    volume: 9589,\n  },\n  {\n    date: 1460743260000,\n    open: 55.5236,\n    high: 55.56,\n    low: 55.52,\n    close: 55.54,\n    volume: 20668,\n  },\n  {\n    date: 1460743320000,\n    open: 55.54,\n    high: 55.57,\n    low: 55.54,\n    close: 55.5536,\n    volume: 17312,\n  },\n  {\n    date: 1460743380000,\n    open: 55.56,\n    high: 55.57,\n    low: 55.55,\n    close: 55.55,\n    volume: 24005,\n  },\n  {\n    date: 1460743440000,\n    open: 55.555,\n    high: 55.56,\n    low: 55.5,\n    close: 55.52,\n    volume: 57296,\n  },\n  {\n    date: 1460743500000,\n    open: 55.54,\n    high: 55.548,\n    low: 55.51,\n    close: 55.535,\n    volume: 25071,\n  },\n  {\n    date: 1460743560000,\n    open: 55.535,\n    high: 55.535,\n    low: 55.5,\n    close: 55.505,\n    volume: 16997,\n  },\n  {\n    date: 1460743620000,\n    open: 55.5,\n    high: 55.5262,\n    low: 55.5,\n    close: 55.515,\n    volume: 20828,\n  },\n  {\n    date: 1460743680000,\n    open: 55.51,\n    high: 55.52,\n    low: 55.51,\n    close: 55.5191,\n    volume: 5792,\n  },\n  {\n    date: 1460743740000,\n    open: 55.51,\n    high: 55.52,\n    low: 55.51,\n    close: 55.515,\n    volume: 9544,\n  },\n  {\n    date: 1460743800000,\n    open: 55.5101,\n    high: 55.54,\n    low: 55.51,\n    close: 55.52,\n    volume: 17847,\n  },\n  {\n    date: 1460743860000,\n    open: 55.525,\n    high: 55.53,\n    low: 55.5,\n    close: 55.51,\n    volume: 16255,\n  },\n  {\n    date: 1460743920000,\n    open: 55.5136,\n    high: 55.515,\n    low: 55.48,\n    close: 55.48,\n    volume: 33330,\n  },\n  {\n    date: 1460743980000,\n    open: 55.48,\n    high: 55.48,\n    low: 55.46,\n    close: 55.475,\n    volume: 31257,\n  },\n  {\n    date: 1460744040000,\n    open: 55.48,\n    high: 55.49,\n    low: 55.47,\n    close: 55.47,\n    volume: 16644,\n  },\n  {\n    date: 1460744100000,\n    open: 55.47,\n    high: 55.477,\n    low: 55.44,\n    close: 55.4401,\n    volume: 20320,\n  },\n  {\n    date: 1460744160000,\n    open: 55.44,\n    high: 55.469,\n    low: 55.44,\n    close: 55.46,\n    volume: 20978,\n  },\n  {\n    date: 1460744220000,\n    open: 55.461,\n    high: 55.469,\n    low: 55.45,\n    close: 55.4536,\n    volume: 265104,\n  },\n  {\n    date: 1460744280000,\n    open: 55.46,\n    high: 55.46,\n    low: 55.44,\n    close: 55.445,\n    volume: 22198,\n  },\n  {\n    date: 1460744340000,\n    open: 55.44,\n    high: 55.45,\n    low: 55.43,\n    close: 55.44,\n    volume: 58311,\n  },\n  {\n    date: 1460744400000,\n    open: 55.43,\n    high: 55.43,\n    low: 55.4,\n    close: 55.42,\n    volume: 52215,\n  },\n  {\n    date: 1460744460000,\n    open: 55.429,\n    high: 55.445,\n    low: 55.42,\n    close: 55.44,\n    volume: 42145,\n  },\n  {\n    date: 1460744520000,\n    open: 55.435,\n    high: 55.44,\n    low: 55.42,\n    close: 55.44,\n    volume: 16951,\n  },\n  {\n    date: 1460744580000,\n    open: 55.43,\n    high: 55.45,\n    low: 55.43,\n    close: 55.445,\n    volume: 48127,\n  },\n  {\n    date: 1460744640000,\n    open: 55.45,\n    high: 55.46,\n    low: 55.44,\n    close: 55.4464,\n    volume: 64815,\n  },\n  {\n    date: 1460744700000,\n    open: 55.45,\n    high: 55.46,\n    low: 55.44,\n    close: 55.445,\n    volume: 30209,\n  },\n  {\n    date: 1460744760000,\n    open: 55.45,\n    high: 55.46,\n    low: 55.44,\n    close: 55.46,\n    volume: 23950,\n  },\n  {\n    date: 1460744820000,\n    open: 55.455,\n    high: 55.48,\n    low: 55.45,\n    close: 55.46,\n    volume: 42372,\n  },\n  {\n    date: 1460744880000,\n    open: 55.46,\n    high: 55.49,\n    low: 55.45,\n    close: 55.48,\n    volume: 73712,\n  },\n  {\n    date: 1460744940000,\n    open: 55.48,\n    high: 55.49,\n    low: 55.47,\n    close: 55.485,\n    volume: 50119,\n  },\n  {\n    date: 1460745000000,\n    open: 55.49,\n    high: 55.53,\n    low: 55.49,\n    close: 55.5229,\n    volume: 28484,\n  },\n  {\n    date: 1460745060000,\n    open: 55.525,\n    high: 55.525,\n    low: 55.49,\n    close: 55.5,\n    volume: 54757,\n  },\n  {\n    date: 1460745120000,\n    open: 55.495,\n    high: 55.5,\n    low: 55.49,\n    close: 55.495,\n    volume: 40185,\n  },\n  {\n    date: 1460745180000,\n    open: 55.49,\n    high: 55.5,\n    low: 55.47,\n    close: 55.47,\n    volume: 16042,\n  },\n  {\n    date: 1460745240000,\n    open: 55.47,\n    high: 55.49,\n    low: 55.47,\n    close: 55.48,\n    volume: 34317,\n  },\n  {\n    date: 1460745300000,\n    open: 55.48,\n    high: 55.5,\n    low: 55.48,\n    close: 55.485,\n    volume: 83771,\n  },\n  {\n    date: 1460745360000,\n    open: 55.485,\n    high: 55.49,\n    low: 55.48,\n    close: 55.485,\n    volume: 39556,\n  },\n  {\n    date: 1460745420000,\n    open: 55.485,\n    high: 55.49,\n    low: 55.45,\n    close: 55.45,\n    volume: 45505,\n  },\n  {\n    date: 1460745480000,\n    open: 55.45,\n    high: 55.46,\n    low: 55.44,\n    close: 55.44,\n    volume: 12731,\n  },\n  {\n    date: 1460745540000,\n    open: 55.45,\n    high: 55.495,\n    low: 55.445,\n    close: 55.495,\n    volume: 51526,\n  },\n  {\n    date: 1460745600000,\n    open: 55.49,\n    high: 55.4925,\n    low: 55.47,\n    close: 55.48,\n    volume: 18165,\n  },\n  {\n    date: 1460745660000,\n    open: 55.49,\n    high: 55.5,\n    low: 55.48,\n    close: 55.48,\n    volume: 12064,\n  },\n  {\n    date: 1460745720000,\n    open: 55.49,\n    high: 55.5,\n    low: 55.48,\n    close: 55.49,\n    volume: 49205,\n  },\n  {\n    date: 1460745780000,\n    open: 55.483,\n    high: 55.5,\n    low: 55.48,\n    close: 55.485,\n    volume: 21141,\n  },\n  {\n    date: 1460745840000,\n    open: 55.49,\n    high: 55.505,\n    low: 55.48,\n    close: 55.48,\n    volume: 41447,\n  },\n  {\n    date: 1460745900000,\n    open: 55.48,\n    high: 55.49,\n    low: 55.47,\n    close: 55.47,\n    volume: 20533,\n  },\n  {\n    date: 1460745960000,\n    open: 55.4799,\n    high: 55.48,\n    low: 55.46,\n    close: 55.46,\n    volume: 14343,\n  },\n  {\n    date: 1460746020000,\n    open: 55.465,\n    high: 55.47,\n    low: 55.46,\n    close: 55.46,\n    volume: 35474,\n  },\n  {\n    date: 1460746080000,\n    open: 55.47,\n    high: 55.47,\n    low: 55.43,\n    close: 55.44,\n    volume: 23002,\n  },\n  {\n    date: 1460746140000,\n    open: 55.44,\n    high: 55.44,\n    low: 55.41,\n    close: 55.4299,\n    volume: 64568,\n  },\n  {\n    date: 1460746200000,\n    open: 55.4276,\n    high: 55.4276,\n    low: 55.41,\n    close: 55.417,\n    volume: 21730,\n  },\n  {\n    date: 1460746260000,\n    open: 55.41,\n    high: 55.415,\n    low: 55.39,\n    close: 55.4,\n    volume: 63270,\n  },\n  {\n    date: 1460746320000,\n    open: 55.405,\n    high: 55.41,\n    low: 55.4,\n    close: 55.404,\n    volume: 17176,\n  },\n  {\n    date: 1460746380000,\n    open: 55.405,\n    high: 55.4499,\n    low: 55.4,\n    close: 55.4475,\n    volume: 53000,\n  },\n  {\n    date: 1460746440000,\n    open: 55.445,\n    high: 55.45,\n    low: 55.425,\n    close: 55.4301,\n    volume: 25449,\n  },\n  {\n    date: 1460746500000,\n    open: 55.44,\n    high: 55.475,\n    low: 55.433,\n    close: 55.4573,\n    volume: 40570,\n  },\n  {\n    date: 1460746560000,\n    open: 55.46,\n    high: 55.46,\n    low: 55.41,\n    close: 55.42,\n    volume: 54507,\n  },\n  {\n    date: 1460746620000,\n    open: 55.42,\n    high: 55.43,\n    low: 55.41,\n    close: 55.41,\n    volume: 19502,\n  },\n  {\n    date: 1460746680000,\n    open: 55.41,\n    high: 55.42,\n    low: 55.405,\n    close: 55.41,\n    volume: 34054,\n  },\n  {\n    date: 1460746740000,\n    open: 55.4165,\n    high: 55.43,\n    low: 55.41,\n    close: 55.4236,\n    volume: 33940,\n  },\n  {\n    date: 1460746800000,\n    open: 55.425,\n    high: 55.47,\n    low: 55.42,\n    close: 55.47,\n    volume: 64408,\n  },\n  {\n    date: 1460746860000,\n    open: 55.467,\n    high: 55.48,\n    low: 55.44,\n    close: 55.45,\n    volume: 62311,\n  },\n  {\n    date: 1460746920000,\n    open: 55.45,\n    high: 55.47,\n    low: 55.45,\n    close: 55.46,\n    volume: 45133,\n  },\n  {\n    date: 1460746980000,\n    open: 55.46,\n    high: 55.48,\n    low: 55.43,\n    close: 55.48,\n    volume: 59113,\n  },\n  {\n    date: 1460747040000,\n    open: 55.47,\n    high: 55.48,\n    low: 55.45,\n    close: 55.4564,\n    volume: 53308,\n  },\n  {\n    date: 1460747100000,\n    open: 55.45,\n    high: 55.49,\n    low: 55.45,\n    close: 55.485,\n    volume: 36947,\n  },\n  {\n    date: 1460747160000,\n    open: 55.49,\n    high: 55.5,\n    low: 55.48,\n    close: 55.49,\n    volume: 53319,\n  },\n  {\n    date: 1460747220000,\n    open: 55.5,\n    high: 55.5,\n    low: 55.48,\n    close: 55.4901,\n    volume: 20541,\n  },\n  {\n    date: 1460747280000,\n    open: 55.495,\n    high: 55.5,\n    low: 55.42,\n    close: 55.4411,\n    volume: 63147,\n  },\n  {\n    date: 1460747340000,\n    open: 55.44,\n    high: 55.46,\n    low: 55.43,\n    close: 55.44,\n    volume: 26645,\n  },\n  {\n    date: 1460747400000,\n    open: 55.44,\n    high: 55.4599,\n    low: 55.44,\n    close: 55.44,\n    volume: 16121,\n  },\n  {\n    date: 1460747460000,\n    open: 55.44,\n    high: 55.45,\n    low: 55.43,\n    close: 55.43,\n    volume: 33631,\n  },\n  {\n    date: 1460747520000,\n    open: 55.43,\n    high: 55.46,\n    low: 55.42,\n    close: 55.4599,\n    volume: 27232,\n  },\n  {\n    date: 1460747580000,\n    open: 55.455,\n    high: 55.48,\n    low: 55.455,\n    close: 55.465,\n    volume: 39002,\n  },\n  {\n    date: 1460747640000,\n    open: 55.465,\n    high: 55.47,\n    low: 55.46,\n    close: 55.465,\n    volume: 12293,\n  },\n  {\n    date: 1460747700000,\n    open: 55.46,\n    high: 55.46,\n    low: 55.42,\n    close: 55.4598,\n    volume: 39589,\n  },\n  {\n    date: 1460747760000,\n    open: 55.4532,\n    high: 55.4899,\n    low: 55.4532,\n    close: 55.4801,\n    volume: 28729,\n  },\n  {\n    date: 1460747820000,\n    open: 55.4801,\n    high: 55.49,\n    low: 55.48,\n    close: 55.49,\n    volume: 6677,\n  },\n  {\n    date: 1460747880000,\n    open: 55.49,\n    high: 55.52,\n    low: 55.49,\n    close: 55.515,\n    volume: 23552,\n  },\n  {\n    date: 1460747940000,\n    open: 55.52,\n    high: 55.525,\n    low: 55.5,\n    close: 55.51,\n    volume: 27412,\n  },\n  {\n    date: 1460748000000,\n    open: 55.51,\n    high: 55.52,\n    low: 55.51,\n    close: 55.515,\n    volume: 11199,\n  },\n  {\n    date: 1460748060000,\n    open: 55.51,\n    high: 55.535,\n    low: 55.5,\n    close: 55.5064,\n    volume: 37314,\n  },\n  {\n    date: 1460748120000,\n    open: 55.51,\n    high: 55.53,\n    low: 55.51,\n    close: 55.5101,\n    volume: 22990,\n  },\n  {\n    date: 1460748180000,\n    open: 55.5173,\n    high: 55.555,\n    low: 55.51,\n    close: 55.54,\n    volume: 60492,\n  },\n  {\n    date: 1460748240000,\n    open: 55.545,\n    high: 55.56,\n    low: 55.52,\n    close: 55.55,\n    volume: 81049,\n  },\n  {\n    date: 1460748300000,\n    open: 55.54,\n    high: 55.56,\n    low: 55.53,\n    close: 55.545,\n    volume: 23395,\n  },\n  {\n    date: 1460748360000,\n    open: 55.545,\n    high: 55.55,\n    low: 55.54,\n    close: 55.545,\n    volume: 7124,\n  },\n  {\n    date: 1460748420000,\n    open: 55.54,\n    high: 55.55,\n    low: 55.54,\n    close: 55.55,\n    volume: 35507,\n  },\n  {\n    date: 1460748480000,\n    open: 55.55,\n    high: 55.56,\n    low: 55.524,\n    close: 55.55,\n    volume: 82111,\n  },\n  {\n    date: 1460748540000,\n    open: 55.54,\n    high: 55.55,\n    low: 55.54,\n    close: 55.549,\n    volume: 7804,\n  },\n  {\n    date: 1460748600000,\n    open: 55.545,\n    high: 55.555,\n    low: 55.52,\n    close: 55.535,\n    volume: 36287,\n  },\n  {\n    date: 1460748660000,\n    open: 55.54,\n    high: 55.555,\n    low: 55.53,\n    close: 55.535,\n    volume: 35133,\n  },\n  {\n    date: 1460748720000,\n    open: 55.53,\n    high: 55.56,\n    low: 55.53,\n    close: 55.55,\n    volume: 49918,\n  },\n  {\n    date: 1460748780000,\n    open: 55.55,\n    high: 55.565,\n    low: 55.54,\n    close: 55.56,\n    volume: 144382,\n  },\n  {\n    date: 1460748840000,\n    open: 55.555,\n    high: 55.56,\n    low: 55.54,\n    close: 55.5499,\n    volume: 15528,\n  },\n  {\n    date: 1460748900000,\n    open: 55.5436,\n    high: 55.56,\n    low: 55.54,\n    close: 55.5599,\n    volume: 33980,\n  },\n  {\n    date: 1460748960000,\n    open: 55.56,\n    high: 55.57,\n    low: 55.55,\n    close: 55.56,\n    volume: 80931,\n  },\n  {\n    date: 1460749020000,\n    open: 55.555,\n    high: 55.6,\n    low: 55.555,\n    close: 55.5863,\n    volume: 56142,\n  },\n  {\n    date: 1460749080000,\n    open: 55.5875,\n    high: 55.59,\n    low: 55.56,\n    close: 55.575,\n    volume: 23633,\n  },\n  {\n    date: 1460749140000,\n    open: 55.57,\n    high: 55.6375,\n    low: 55.57,\n    close: 55.625,\n    volume: 185693,\n  },\n  {\n    date: 1460749200000,\n    open: 55.63,\n    high: 55.63,\n    low: 55.6,\n    close: 55.615,\n    volume: 30476,\n  },\n  {\n    date: 1460749260000,\n    open: 55.61,\n    high: 55.61,\n    low: 55.59,\n    close: 55.595,\n    volume: 35781,\n  },\n  {\n    date: 1460749320000,\n    open: 55.59,\n    high: 55.6269,\n    low: 55.58,\n    close: 55.605,\n    volume: 71387,\n  },\n  {\n    date: 1460749380000,\n    open: 55.61,\n    high: 55.63,\n    low: 55.61,\n    close: 55.61,\n    volume: 92427,\n  },\n  {\n    date: 1460749440000,\n    open: 55.615,\n    high: 55.625,\n    low: 55.61,\n    close: 55.615,\n    volume: 131056,\n  },\n  {\n    date: 1460749500000,\n    open: 55.62,\n    high: 55.63,\n    low: 55.61,\n    close: 55.61,\n    volume: 104309,\n  },\n  {\n    date: 1460749560000,\n    open: 55.615,\n    high: 55.625,\n    low: 55.61,\n    close: 55.615,\n    volume: 85079,\n  },\n  {\n    date: 1460749620000,\n    open: 55.615,\n    high: 55.62,\n    low: 55.61,\n    close: 55.6105,\n    volume: 42629,\n  },\n  {\n    date: 1460749680000,\n    open: 55.615,\n    high: 55.62,\n    low: 55.58,\n    close: 55.5999,\n    volume: 110449,\n  },\n  {\n    date: 1460749740000,\n    open: 55.6,\n    high: 55.62,\n    low: 55.595,\n    close: 55.595,\n    volume: 111647,\n  },\n  {\n    date: 1460749800000,\n    open: 55.595,\n    high: 55.65,\n    low: 55.59,\n    close: 55.62,\n    volume: 182012,\n  },\n  {\n    date: 1460749860000,\n    open: 55.62,\n    high: 55.63,\n    low: 55.61,\n    close: 55.62,\n    volume: 145177,\n  },\n  {\n    date: 1460749920000,\n    open: 55.62,\n    high: 55.64,\n    low: 55.61,\n    close: 55.63,\n    volume: 116990,\n  },\n  {\n    date: 1460749980000,\n    open: 55.64,\n    high: 55.64,\n    low: 55.61,\n    close: 55.63,\n    volume: 82011,\n  },\n  {\n    date: 1460750040000,\n    open: 55.63,\n    high: 55.63,\n    low: 55.62,\n    close: 55.63,\n    volume: 45767,\n  },\n  {\n    date: 1460750100000,\n    open: 55.62,\n    high: 55.64,\n    low: 55.62,\n    close: 55.625,\n    volume: 141808,\n  },\n  {\n    date: 1460750160000,\n    open: 55.63,\n    high: 55.655,\n    low: 55.625,\n    close: 55.65,\n    volume: 133620,\n  },\n  {\n    date: 1460750220000,\n    open: 55.65,\n    high: 55.68,\n    low: 55.64,\n    close: 55.67,\n    volume: 206923,\n  },\n  {\n    date: 1460750280000,\n    open: 55.66,\n    high: 55.67,\n    low: 55.65,\n    close: 55.6601,\n    volume: 313716,\n  },\n  {\n    date: 1460750340000,\n    open: 55.66,\n    high: 55.665,\n    low: 55.63,\n    close: 55.65,\n    volume: 240576,\n  },\n  {\n    date: 1460750400000,\n    open: 55.645,\n    high: 55.69,\n    low: 55.64,\n    close: 55.65,\n    volume: 3778057,\n  },\n  {\n    date: 1460986200000,\n    open: 55.49,\n    high: 55.49,\n    low: 55.21,\n    close: 55.3,\n    volume: 270788,\n  },\n  {\n    date: 1460986260000,\n    open: 55.45,\n    high: 55.48,\n    low: 55.34,\n    close: 55.39,\n    volume: 58905,\n  },\n  {\n    date: 1460986320000,\n    open: 55.39,\n    high: 55.475,\n    low: 55.37,\n    close: 55.4538,\n    volume: 65194,\n  },\n  {\n    date: 1460986380000,\n    open: 55.46,\n    high: 55.46,\n    low: 55.39,\n    close: 55.43,\n    volume: 67970,\n  },\n  {\n    date: 1460986440000,\n    open: 55.42,\n    high: 55.45,\n    low: 55.41,\n    close: 55.445,\n    volume: 43356,\n  },\n  {\n    date: 1460986500000,\n    open: 55.445,\n    high: 55.46,\n    low: 55.42,\n    close: 55.445,\n    volume: 82079,\n  },\n  {\n    date: 1460986560000,\n    open: 55.4462,\n    high: 55.49,\n    low: 55.41,\n    close: 55.4701,\n    volume: 123780,\n  },\n  {\n    date: 1460986620000,\n    open: 55.4799,\n    high: 55.51,\n    low: 55.4746,\n    close: 55.485,\n    volume: 57080,\n  },\n  {\n    date: 1460986680000,\n    open: 55.48,\n    high: 55.53,\n    low: 55.48,\n    close: 55.52,\n    volume: 22014,\n  },\n  {\n    date: 1460986740000,\n    open: 55.53,\n    high: 55.55,\n    low: 55.52,\n    close: 55.54,\n    volume: 38135,\n  },\n  {\n    date: 1460986800000,\n    open: 55.55,\n    high: 55.63,\n    low: 55.54,\n    close: 55.63,\n    volume: 51032,\n  },\n  {\n    date: 1460986860000,\n    open: 55.63,\n    high: 55.675,\n    low: 55.59,\n    close: 55.675,\n    volume: 80029,\n  },\n  {\n    date: 1460986920000,\n    open: 55.67,\n    high: 55.7,\n    low: 55.62,\n    close: 55.63,\n    volume: 76629,\n  },\n  {\n    date: 1460986980000,\n    open: 55.63,\n    high: 55.63,\n    low: 55.5601,\n    close: 55.5601,\n    volume: 30191,\n  },\n  {\n    date: 1460987040000,\n    open: 55.56,\n    high: 55.58,\n    low: 55.56,\n    close: 55.57,\n    volume: 21733,\n  },\n  {\n    date: 1460987100000,\n    open: 55.57,\n    high: 55.58,\n    low: 55.56,\n    close: 55.565,\n    volume: 17624,\n  },\n  {\n    date: 1460987160000,\n    open: 55.565,\n    high: 55.57,\n    low: 55.56,\n    close: 55.5642,\n    volume: 27449,\n  },\n  {\n    date: 1460987220000,\n    open: 55.56,\n    high: 55.57,\n    low: 55.55,\n    close: 55.56,\n    volume: 31745,\n  },\n  {\n    date: 1460987280000,\n    open: 55.55,\n    high: 55.55,\n    low: 55.51,\n    close: 55.5411,\n    volume: 27868,\n  },\n  {\n    date: 1460987340000,\n    open: 55.54,\n    high: 55.59,\n    low: 55.53,\n    close: 55.57,\n    volume: 40708,\n  },\n  {\n    date: 1460987400000,\n    open: 55.579,\n    high: 55.61,\n    low: 55.57,\n    close: 55.6,\n    volume: 32551,\n  },\n  {\n    date: 1460987460000,\n    open: 55.6,\n    high: 55.6299,\n    low: 55.6,\n    close: 55.62,\n    volume: 36765,\n  },\n  {\n    date: 1460987520000,\n    open: 55.62,\n    high: 55.65,\n    low: 55.61,\n    close: 55.65,\n    volume: 23649,\n  },\n  {\n    date: 1460987580000,\n    open: 55.65,\n    high: 55.66,\n    low: 55.64,\n    close: 55.65,\n    volume: 22917,\n  },\n  {\n    date: 1460987640000,\n    open: 55.655,\n    high: 55.7,\n    low: 55.65,\n    close: 55.6858,\n    volume: 38728,\n  },\n  {\n    date: 1460987700000,\n    open: 55.685,\n    high: 55.7199,\n    low: 55.68,\n    close: 55.7058,\n    volume: 30410,\n  },\n  {\n    date: 1460987760000,\n    open: 55.7,\n    high: 55.74,\n    low: 55.69,\n    close: 55.695,\n    volume: 54503,\n  },\n  {\n    date: 1460987820000,\n    open: 55.6911,\n    high: 55.7068,\n    low: 55.685,\n    close: 55.69,\n    volume: 27636,\n  },\n  {\n    date: 1460987880000,\n    open: 55.69,\n    high: 55.72,\n    low: 55.68,\n    close: 55.72,\n    volume: 26115,\n  },\n  {\n    date: 1460987940000,\n    open: 55.72,\n    high: 55.7264,\n    low: 55.7,\n    close: 55.71,\n    volume: 19644,\n  },\n  {\n    date: 1460988000000,\n    open: 55.72,\n    high: 55.745,\n    low: 55.71,\n    close: 55.71,\n    volume: 26334,\n  },\n  {\n    date: 1460988060000,\n    open: 55.7,\n    high: 55.74,\n    low: 55.7,\n    close: 55.71,\n    volume: 25794,\n  },\n  {\n    date: 1460988120000,\n    open: 55.7,\n    high: 55.83,\n    low: 55.7,\n    close: 55.8199,\n    volume: 78858,\n  },\n  {\n    date: 1460988180000,\n    open: 55.8168,\n    high: 55.85,\n    low: 55.81,\n    close: 55.835,\n    volume: 31849,\n  },\n  {\n    date: 1460988240000,\n    open: 55.83,\n    high: 55.85,\n    low: 55.83,\n    close: 55.85,\n    volume: 32397,\n  },\n  {\n    date: 1460988300000,\n    open: 55.85,\n    high: 55.92,\n    low: 55.8436,\n    close: 55.92,\n    volume: 51100,\n  },\n  {\n    date: 1460988360000,\n    open: 55.918,\n    high: 55.95,\n    low: 55.91,\n    close: 55.95,\n    volume: 56398,\n  },\n  {\n    date: 1460988420000,\n    open: 55.945,\n    high: 55.95,\n    low: 55.92,\n    close: 55.93,\n    volume: 38569,\n  },\n  {\n    date: 1460988480000,\n    open: 55.92,\n    high: 55.93,\n    low: 55.9,\n    close: 55.93,\n    volume: 34432,\n  },\n  {\n    date: 1460988540000,\n    open: 55.93,\n    high: 55.94,\n    low: 55.8699,\n    close: 55.8868,\n    volume: 43117,\n  },\n  {\n    date: 1460988600000,\n    open: 55.88,\n    high: 55.92,\n    low: 55.88,\n    close: 55.9,\n    volume: 58729,\n  },\n  {\n    date: 1460988660000,\n    open: 55.9,\n    high: 55.92,\n    low: 55.8926,\n    close: 55.92,\n    volume: 19081,\n  },\n  {\n    date: 1460988720000,\n    open: 55.92,\n    high: 55.93,\n    low: 55.9,\n    close: 55.92,\n    volume: 21646,\n  },\n  {\n    date: 1460988780000,\n    open: 55.916,\n    high: 55.95,\n    low: 55.9,\n    close: 55.94,\n    volume: 29451,\n  },\n  {\n    date: 1460988840000,\n    open: 55.94,\n    high: 55.96,\n    low: 55.93,\n    close: 55.96,\n    volume: 62529,\n  },\n  {\n    date: 1460988900000,\n    open: 55.96,\n    high: 56,\n    low: 55.95,\n    close: 55.985,\n    volume: 59612,\n  },\n  {\n    date: 1460988960000,\n    open: 55.989,\n    high: 56,\n    low: 55.97,\n    close: 55.9868,\n    volume: 138666,\n  },\n  {\n    date: 1460989020000,\n    open: 55.985,\n    high: 55.99,\n    low: 55.965,\n    close: 55.97,\n    volume: 30481,\n  },\n  {\n    date: 1460989080000,\n    open: 55.97,\n    high: 55.97,\n    low: 55.94,\n    close: 55.95,\n    volume: 41621,\n  },\n  {\n    date: 1460989140000,\n    open: 55.95,\n    high: 55.97,\n    low: 55.94,\n    close: 55.96,\n    volume: 64080,\n  },\n  {\n    date: 1460989200000,\n    open: 55.95,\n    high: 55.9655,\n    low: 55.95,\n    close: 55.96,\n    volume: 32541,\n  },\n  {\n    date: 1460989260000,\n    open: 55.955,\n    high: 55.99,\n    low: 55.95,\n    close: 55.9835,\n    volume: 27999,\n  },\n  {\n    date: 1460989320000,\n    open: 55.985,\n    high: 55.995,\n    low: 55.9736,\n    close: 55.98,\n    volume: 84496,\n  },\n  {\n    date: 1460989380000,\n    open: 55.97,\n    high: 55.9799,\n    low: 55.97,\n    close: 55.975,\n    volume: 7630,\n  },\n  {\n    date: 1460989440000,\n    open: 55.97,\n    high: 55.99,\n    low: 55.97,\n    close: 55.99,\n    volume: 10872,\n  },\n  {\n    date: 1460989500000,\n    open: 55.99,\n    high: 56,\n    low: 55.98,\n    close: 55.99,\n    volume: 39509,\n  },\n  {\n    date: 1460989560000,\n    open: 55.9975,\n    high: 56,\n    low: 55.98,\n    close: 55.98,\n    volume: 63393,\n  },\n  {\n    date: 1460989620000,\n    open: 55.9899,\n    high: 56.04,\n    low: 55.98,\n    close: 55.995,\n    volume: 329191,\n  },\n  {\n    date: 1460989680000,\n    open: 55.99,\n    high: 56.01,\n    low: 55.99,\n    close: 56,\n    volume: 36167,\n  },\n  {\n    date: 1460989740000,\n    open: 56,\n    high: 56.01,\n    low: 55.98,\n    close: 55.99,\n    volume: 41782,\n  },\n  {\n    date: 1460989800000,\n    open: 55.98,\n    high: 56.02,\n    low: 55.98,\n    close: 56.01,\n    volume: 53693,\n  },\n  {\n    date: 1460989860000,\n    open: 56.02,\n    high: 56.045,\n    low: 56,\n    close: 56.03,\n    volume: 67778,\n  },\n  {\n    date: 1460989920000,\n    open: 56.03,\n    high: 56.04,\n    low: 56.0001,\n    close: 56.04,\n    volume: 58847,\n  },\n  {\n    date: 1460989980000,\n    open: 56.03,\n    high: 56.08,\n    low: 56.03,\n    close: 56.07,\n    volume: 40345,\n  },\n  {\n    date: 1460990040000,\n    open: 56.08,\n    high: 56.13,\n    low: 56.07,\n    close: 56.1211,\n    volume: 38577,\n  },\n  {\n    date: 1460990100000,\n    open: 56.12,\n    high: 56.16,\n    low: 56.12,\n    close: 56.15,\n    volume: 72715,\n  },\n  {\n    date: 1460990160000,\n    open: 56.16,\n    high: 56.18,\n    low: 56.12,\n    close: 56.16,\n    volume: 87282,\n  },\n  {\n    date: 1460990220000,\n    open: 56.16,\n    high: 56.165,\n    low: 56.14,\n    close: 56.14,\n    volume: 80672,\n  },\n  {\n    date: 1460990280000,\n    open: 56.14,\n    high: 56.145,\n    low: 56.11,\n    close: 56.125,\n    volume: 39832,\n  },\n  {\n    date: 1460990340000,\n    open: 56.125,\n    high: 56.14,\n    low: 56.12,\n    close: 56.12,\n    volume: 57424,\n  },\n  {\n    date: 1460990400000,\n    open: 56.127,\n    high: 56.16,\n    low: 56.125,\n    close: 56.138,\n    volume: 21267,\n  },\n  {\n    date: 1460990460000,\n    open: 56.13,\n    high: 56.16,\n    low: 56.125,\n    close: 56.155,\n    volume: 29140,\n  },\n  {\n    date: 1460990520000,\n    open: 56.15,\n    high: 56.18,\n    low: 56.15,\n    close: 56.18,\n    volume: 41178,\n  },\n  {\n    date: 1460990580000,\n    open: 56.18,\n    high: 56.2,\n    low: 56.179,\n    close: 56.185,\n    volume: 31736,\n  },\n  {\n    date: 1460990640000,\n    open: 56.18,\n    high: 56.19,\n    low: 56.16,\n    close: 56.1601,\n    volume: 19799,\n  },\n  {\n    date: 1460990700000,\n    open: 56.16,\n    high: 56.18,\n    low: 56.15,\n    close: 56.17,\n    volume: 53005,\n  },\n  {\n    date: 1460990760000,\n    open: 56.17,\n    high: 56.18,\n    low: 56.165,\n    close: 56.175,\n    volume: 18626,\n  },\n  {\n    date: 1460990820000,\n    open: 56.1799,\n    high: 56.19,\n    low: 56.17,\n    close: 56.1801,\n    volume: 44761,\n  },\n  {\n    date: 1460990880000,\n    open: 56.1866,\n    high: 56.1866,\n    low: 56.17,\n    close: 56.17,\n    volume: 34570,\n  },\n  {\n    date: 1460990940000,\n    open: 56.18,\n    high: 56.19,\n    low: 56.17,\n    close: 56.18,\n    volume: 18372,\n  },\n  {\n    date: 1460991000000,\n    open: 56.19,\n    high: 56.2,\n    low: 56.17,\n    close: 56.1701,\n    volume: 42659,\n  },\n  {\n    date: 1460991060000,\n    open: 56.17,\n    high: 56.18,\n    low: 56.145,\n    close: 56.17,\n    volume: 71086,\n  },\n  {\n    date: 1460991120000,\n    open: 56.16,\n    high: 56.2,\n    low: 56.16,\n    close: 56.18,\n    volume: 44787,\n  },\n  {\n    date: 1460991180000,\n    open: 56.18,\n    high: 56.22,\n    low: 56.18,\n    close: 56.2165,\n    volume: 34863,\n  },\n  {\n    date: 1460991240000,\n    open: 56.22,\n    high: 56.25,\n    low: 56.22,\n    close: 56.235,\n    volume: 33919,\n  },\n  {\n    date: 1460991300000,\n    open: 56.235,\n    high: 56.25,\n    low: 56.19,\n    close: 56.2172,\n    volume: 100072,\n  },\n  {\n    date: 1460991360000,\n    open: 56.215,\n    high: 56.24,\n    low: 56.21,\n    close: 56.23,\n    volume: 37995,\n  },\n  {\n    date: 1460991420000,\n    open: 56.2248,\n    high: 56.24,\n    low: 56.205,\n    close: 56.205,\n    volume: 43771,\n  },\n  {\n    date: 1460991480000,\n    open: 56.2099,\n    high: 56.21,\n    low: 56.18,\n    close: 56.18,\n    volume: 40667,\n  },\n  {\n    date: 1460991540000,\n    open: 56.1848,\n    high: 56.185,\n    low: 56.1516,\n    close: 56.175,\n    volume: 29099,\n  },\n  {\n    date: 1460991600000,\n    open: 56.18,\n    high: 56.19,\n    low: 56.17,\n    close: 56.1825,\n    volume: 28612,\n  },\n  {\n    date: 1460991660000,\n    open: 56.19,\n    high: 56.19,\n    low: 56.15,\n    close: 56.15,\n    volume: 49266,\n  },\n  {\n    date: 1460991720000,\n    open: 56.15,\n    high: 56.16,\n    low: 56.15,\n    close: 56.15,\n    volume: 30963,\n  },\n  {\n    date: 1460991780000,\n    open: 56.16,\n    high: 56.16,\n    low: 56.14,\n    close: 56.145,\n    volume: 48859,\n  },\n  {\n    date: 1460991840000,\n    open: 56.14,\n    high: 56.15,\n    low: 56.13,\n    close: 56.14,\n    volume: 29776,\n  },\n  {\n    date: 1460991900000,\n    open: 56.13,\n    high: 56.15,\n    low: 56.13,\n    close: 56.13,\n    volume: 49491,\n  },\n  {\n    date: 1460991960000,\n    open: 56.13,\n    high: 56.14,\n    low: 56.13,\n    close: 56.135,\n    volume: 42261,\n  },\n  {\n    date: 1460992020000,\n    open: 56.1334,\n    high: 56.15,\n    low: 56.13,\n    close: 56.14,\n    volume: 32474,\n  },\n  {\n    date: 1460992080000,\n    open: 56.14,\n    high: 56.15,\n    low: 56.13,\n    close: 56.13,\n    volume: 18957,\n  },\n  {\n    date: 1460992140000,\n    open: 56.13,\n    high: 56.137,\n    low: 56.1,\n    close: 56.1,\n    volume: 52321,\n  },\n  {\n    date: 1460992200000,\n    open: 56.1032,\n    high: 56.115,\n    low: 56.09,\n    close: 56.104,\n    volume: 79871,\n  },\n  {\n    date: 1460992260000,\n    open: 56.1,\n    high: 56.13,\n    low: 56.1,\n    close: 56.115,\n    volume: 48988,\n  },\n  {\n    date: 1460992320000,\n    open: 56.12,\n    high: 56.13,\n    low: 56.115,\n    close: 56.1265,\n    volume: 10396,\n  },\n  {\n    date: 1460992380000,\n    open: 56.1265,\n    high: 56.16,\n    low: 56.125,\n    close: 56.15,\n    volume: 44327,\n  },\n  {\n    date: 1460992440000,\n    open: 56.16,\n    high: 56.16,\n    low: 56.12,\n    close: 56.1235,\n    volume: 18012,\n  },\n  {\n    date: 1460992500000,\n    open: 56.12,\n    high: 56.13,\n    low: 56.11,\n    close: 56.11,\n    volume: 22657,\n  },\n  {\n    date: 1460992560000,\n    open: 56.11,\n    high: 56.13,\n    low: 56.11,\n    close: 56.13,\n    volume: 10510,\n  },\n  {\n    date: 1460992620000,\n    open: 56.12,\n    high: 56.15,\n    low: 56.12,\n    close: 56.13,\n    volume: 44488,\n  },\n  {\n    date: 1460992680000,\n    open: 56.126,\n    high: 56.126,\n    low: 56.11,\n    close: 56.11,\n    volume: 8256,\n  },\n  {\n    date: 1460992740000,\n    open: 56.11,\n    high: 56.13,\n    low: 56.0801,\n    close: 56.085,\n    volume: 43387,\n  },\n  {\n    date: 1460992800000,\n    open: 56.09,\n    high: 56.1049,\n    low: 56.07,\n    close: 56.07,\n    volume: 50264,\n  },\n  {\n    date: 1460992860000,\n    open: 56.08,\n    high: 56.09,\n    low: 56.06,\n    close: 56.0701,\n    volume: 62275,\n  },\n  {\n    date: 1460992920000,\n    open: 56.0799,\n    high: 56.11,\n    low: 56.07,\n    close: 56.1,\n    volume: 54334,\n  },\n  {\n    date: 1460992980000,\n    open: 56.09,\n    high: 56.09,\n    low: 56.06,\n    close: 56.06,\n    volume: 16296,\n  },\n  {\n    date: 1460993040000,\n    open: 56.06,\n    high: 56.07,\n    low: 56.05,\n    close: 56.06,\n    volume: 39992,\n  },\n  {\n    date: 1460993100000,\n    open: 56.055,\n    high: 56.065,\n    low: 56.01,\n    close: 56.01,\n    volume: 64545,\n  },\n  {\n    date: 1460993160000,\n    open: 56.01,\n    high: 56.02,\n    low: 56,\n    close: 56.005,\n    volume: 77415,\n  },\n  {\n    date: 1460993220000,\n    open: 56.01,\n    high: 56.01,\n    low: 56,\n    close: 56,\n    volume: 21017,\n  },\n  {\n    date: 1460993280000,\n    open: 56.01,\n    high: 56.03,\n    low: 55.98,\n    close: 56.03,\n    volume: 60651,\n  },\n  {\n    date: 1460993340000,\n    open: 56.021,\n    high: 56.04,\n    low: 56.01,\n    close: 56.01,\n    volume: 22350,\n  },\n  {\n    date: 1460993400000,\n    open: 56,\n    high: 56.06,\n    low: 56,\n    close: 56.05,\n    volume: 47573,\n  },\n  {\n    date: 1460993460000,\n    open: 56.05,\n    high: 56.11,\n    low: 56.05,\n    close: 56.0935,\n    volume: 42417,\n  },\n  {\n    date: 1460993520000,\n    open: 56.09,\n    high: 56.0999,\n    low: 56.06,\n    close: 56.0799,\n    volume: 34189,\n  },\n  {\n    date: 1460993580000,\n    open: 56.08,\n    high: 56.09,\n    low: 56.0435,\n    close: 56.05,\n    volume: 46758,\n  },\n  {\n    date: 1460993640000,\n    open: 56.05,\n    high: 56.075,\n    low: 56.05,\n    close: 56.07,\n    volume: 69316,\n  },\n  {\n    date: 1460993700000,\n    open: 56.065,\n    high: 56.0796,\n    low: 56.05,\n    close: 56.0796,\n    volume: 50199,\n  },\n  {\n    date: 1460993760000,\n    open: 56.075,\n    high: 56.08,\n    low: 56.06,\n    close: 56.064,\n    volume: 26574,\n  },\n  {\n    date: 1460993820000,\n    open: 56.07,\n    high: 56.07,\n    low: 56.03,\n    close: 56.06,\n    volume: 35785,\n  },\n  {\n    date: 1460993880000,\n    open: 56.06,\n    high: 56.1,\n    low: 56.06,\n    close: 56.1,\n    volume: 24029,\n  },\n  {\n    date: 1460993940000,\n    open: 56.1,\n    high: 56.1,\n    low: 56.05,\n    close: 56.065,\n    volume: 22024,\n  },\n  {\n    date: 1460994000000,\n    open: 56.06,\n    high: 56.07,\n    low: 56.0428,\n    close: 56.07,\n    volume: 58642,\n  },\n  {\n    date: 1460994060000,\n    open: 56.07,\n    high: 56.08,\n    low: 56.05,\n    close: 56.0672,\n    volume: 23570,\n  },\n  {\n    date: 1460994120000,\n    open: 56.07,\n    high: 56.09,\n    low: 56.06,\n    close: 56.09,\n    volume: 32126,\n  },\n  {\n    date: 1460994180000,\n    open: 56.09,\n    high: 56.1,\n    low: 56.08,\n    close: 56.095,\n    volume: 13732,\n  },\n  {\n    date: 1460994240000,\n    open: 56.0935,\n    high: 56.1,\n    low: 56.05,\n    close: 56.09,\n    volume: 47234,\n  },\n  {\n    date: 1460994300000,\n    open: 56.08,\n    high: 56.09,\n    low: 56.0532,\n    close: 56.06,\n    volume: 11518,\n  },\n  {\n    date: 1460994360000,\n    open: 56.07,\n    high: 56.1,\n    low: 56.07,\n    close: 56.09,\n    volume: 19550,\n  },\n  {\n    date: 1460994420000,\n    open: 56.085,\n    high: 56.09,\n    low: 56.08,\n    close: 56.08,\n    volume: 8737,\n  },\n  {\n    date: 1460994480000,\n    open: 56.09,\n    high: 56.0995,\n    low: 56.05,\n    close: 56.065,\n    volume: 43992,\n  },\n  {\n    date: 1460994540000,\n    open: 56.0635,\n    high: 56.075,\n    low: 56.0235,\n    close: 56.04,\n    volume: 18030,\n  },\n  {\n    date: 1460994600000,\n    open: 56.0399,\n    high: 56.04,\n    low: 56,\n    close: 56.03,\n    volume: 26820,\n  },\n  {\n    date: 1460994660000,\n    open: 56.02,\n    high: 56.03,\n    low: 56.0101,\n    close: 56.015,\n    volume: 7122,\n  },\n  {\n    date: 1460994720000,\n    open: 56.01,\n    high: 56.05,\n    low: 56.01,\n    close: 56.0436,\n    volume: 29858,\n  },\n  {\n    date: 1460994780000,\n    open: 56.0451,\n    high: 56.0451,\n    low: 56,\n    close: 56.0063,\n    volume: 30678,\n  },\n  {\n    date: 1460994840000,\n    open: 56,\n    high: 56.03,\n    low: 56,\n    close: 56.025,\n    volume: 13858,\n  },\n  {\n    date: 1460994900000,\n    open: 56.02,\n    high: 56.07,\n    low: 56.02,\n    close: 56.04,\n    volume: 33944,\n  },\n  {\n    date: 1460994960000,\n    open: 56.04,\n    high: 56.0519,\n    low: 56.03,\n    close: 56.03,\n    volume: 16239,\n  },\n  {\n    date: 1460995020000,\n    open: 56.03,\n    high: 56.05,\n    low: 56.03,\n    close: 56.0335,\n    volume: 15579,\n  },\n  {\n    date: 1460995080000,\n    open: 56.03,\n    high: 56.06,\n    low: 56.025,\n    close: 56.055,\n    volume: 24764,\n  },\n  {\n    date: 1460995140000,\n    open: 56.0501,\n    high: 56.06,\n    low: 56.025,\n    close: 56.04,\n    volume: 18828,\n  },\n  {\n    date: 1460995200000,\n    open: 56.03,\n    high: 56.05,\n    low: 56.0239,\n    close: 56.05,\n    volume: 15191,\n  },\n  {\n    date: 1460995260000,\n    open: 56.05,\n    high: 56.0899,\n    low: 56.05,\n    close: 56.0599,\n    volume: 40171,\n  },\n  {\n    date: 1460995320000,\n    open: 56.06,\n    high: 56.07,\n    low: 56.05,\n    close: 56.06,\n    volume: 12000,\n  },\n  {\n    date: 1460995380000,\n    open: 56.06,\n    high: 56.08,\n    low: 56.0501,\n    close: 56.071,\n    volume: 14830,\n  },\n  {\n    date: 1460995440000,\n    open: 56.079,\n    high: 56.08,\n    low: 56.07,\n    close: 56.08,\n    volume: 17185,\n  },\n  {\n    date: 1460995500000,\n    open: 56.08,\n    high: 56.11,\n    low: 56.08,\n    close: 56.11,\n    volume: 28850,\n  },\n  {\n    date: 1460995560000,\n    open: 56.1,\n    high: 56.13,\n    low: 56.1,\n    close: 56.13,\n    volume: 34962,\n  },\n  {\n    date: 1460995620000,\n    open: 56.1201,\n    high: 56.17,\n    low: 56.11,\n    close: 56.17,\n    volume: 149012,\n  },\n  {\n    date: 1460995680000,\n    open: 56.17,\n    high: 56.19,\n    low: 56.17,\n    close: 56.18,\n    volume: 72947,\n  },\n  {\n    date: 1460995740000,\n    open: 56.175,\n    high: 56.18,\n    low: 56.15,\n    close: 56.165,\n    volume: 16322,\n  },\n  {\n    date: 1460995800000,\n    open: 56.167,\n    high: 56.18,\n    low: 56.1545,\n    close: 56.17,\n    volume: 34863,\n  },\n  {\n    date: 1460995860000,\n    open: 56.17,\n    high: 56.18,\n    low: 56.16,\n    close: 56.18,\n    volume: 11891,\n  },\n  {\n    date: 1460995920000,\n    open: 56.18,\n    high: 56.19,\n    low: 56.16,\n    close: 56.175,\n    volume: 34462,\n  },\n  {\n    date: 1460995980000,\n    open: 56.17,\n    high: 56.19,\n    low: 56.16,\n    close: 56.185,\n    volume: 16850,\n  },\n  {\n    date: 1460996040000,\n    open: 56.1899,\n    high: 56.23,\n    low: 56.18,\n    close: 56.23,\n    volume: 88096,\n  },\n  {\n    date: 1460996100000,\n    open: 56.2201,\n    high: 56.23,\n    low: 56.2099,\n    close: 56.2099,\n    volume: 31871,\n  },\n  {\n    date: 1460996160000,\n    open: 56.2,\n    high: 56.25,\n    low: 56.2,\n    close: 56.23,\n    volume: 209826,\n  },\n  {\n    date: 1460996220000,\n    open: 56.2201,\n    high: 56.24,\n    low: 56.22,\n    close: 56.24,\n    volume: 45955,\n  },\n  {\n    date: 1460996280000,\n    open: 56.235,\n    high: 56.25,\n    low: 56.23,\n    close: 56.245,\n    volume: 208013,\n  },\n  {\n    date: 1460996340000,\n    open: 56.25,\n    high: 56.32,\n    low: 56.24,\n    close: 56.32,\n    volume: 162639,\n  },\n  {\n    date: 1460996400000,\n    open: 56.32,\n    high: 56.33,\n    low: 56.25,\n    close: 56.259,\n    volume: 62100,\n  },\n  {\n    date: 1460996460000,\n    open: 56.25,\n    high: 56.33,\n    low: 56.25,\n    close: 56.33,\n    volume: 73381,\n  },\n  {\n    date: 1460996520000,\n    open: 56.32,\n    high: 56.37,\n    low: 56.3,\n    close: 56.37,\n    volume: 129706,\n  },\n  {\n    date: 1460996580000,\n    open: 56.37,\n    high: 56.43,\n    low: 56.35,\n    close: 56.3735,\n    volume: 268181,\n  },\n  {\n    date: 1460996640000,\n    open: 56.38,\n    high: 56.38,\n    low: 56.33,\n    close: 56.36,\n    volume: 88070,\n  },\n  {\n    date: 1460996700000,\n    open: 56.355,\n    high: 56.355,\n    low: 56.3271,\n    close: 56.33,\n    volume: 19425,\n  },\n  {\n    date: 1460996760000,\n    open: 56.325,\n    high: 56.34,\n    low: 56.32,\n    close: 56.33,\n    volume: 40874,\n  },\n  {\n    date: 1460996820000,\n    open: 56.325,\n    high: 56.33,\n    low: 56.32,\n    close: 56.325,\n    volume: 12245,\n  },\n  {\n    date: 1460996880000,\n    open: 56.325,\n    high: 56.38,\n    low: 56.32,\n    close: 56.38,\n    volume: 57649,\n  },\n  {\n    date: 1460996940000,\n    open: 56.38,\n    high: 56.41,\n    low: 56.38,\n    close: 56.395,\n    volume: 60674,\n  },\n  {\n    date: 1460997000000,\n    open: 56.399,\n    high: 56.4,\n    low: 56.385,\n    close: 56.3925,\n    volume: 56405,\n  },\n  {\n    date: 1460997060000,\n    open: 56.395,\n    high: 56.46,\n    low: 56.39,\n    close: 56.46,\n    volume: 88238,\n  },\n  {\n    date: 1460997120000,\n    open: 56.451,\n    high: 56.495,\n    low: 56.45,\n    close: 56.495,\n    volume: 90524,\n  },\n  {\n    date: 1460997180000,\n    open: 56.5,\n    high: 56.59,\n    low: 56.49,\n    close: 56.545,\n    volume: 202060,\n  },\n  {\n    date: 1460997240000,\n    open: 56.555,\n    high: 56.555,\n    low: 56.46,\n    close: 56.49,\n    volume: 116820,\n  },\n  {\n    date: 1460997300000,\n    open: 56.486,\n    high: 56.51,\n    low: 56.465,\n    close: 56.5,\n    volume: 111333,\n  },\n  {\n    date: 1460997360000,\n    open: 56.5,\n    high: 56.51,\n    low: 56.44,\n    close: 56.455,\n    volume: 128108,\n  },\n  {\n    date: 1460997420000,\n    open: 56.458,\n    high: 56.49,\n    low: 56.4535,\n    close: 56.48,\n    volume: 53836,\n  },\n  {\n    date: 1460997480000,\n    open: 56.47,\n    high: 56.54,\n    low: 56.47,\n    close: 56.53,\n    volume: 134992,\n  },\n  {\n    date: 1460997540000,\n    open: 56.5235,\n    high: 56.54,\n    low: 56.48,\n    close: 56.515,\n    volume: 132885,\n  },\n  {\n    date: 1460997600000,\n    open: 56.5,\n    high: 56.51,\n    low: 56.49,\n    close: 56.5,\n    volume: 57421,\n  },\n  {\n    date: 1460997660000,\n    open: 56.5,\n    high: 56.52,\n    low: 56.48,\n    close: 56.4862,\n    volume: 24080,\n  },\n  {\n    date: 1460997720000,\n    open: 56.49,\n    high: 56.49,\n    low: 56.47,\n    close: 56.47,\n    volume: 77088,\n  },\n  {\n    date: 1460997780000,\n    open: 56.48,\n    high: 56.49,\n    low: 56.44,\n    close: 56.44,\n    volume: 20787,\n  },\n  {\n    date: 1460997840000,\n    open: 56.45,\n    high: 56.5,\n    low: 56.44,\n    close: 56.48,\n    volume: 60981,\n  },\n  {\n    date: 1460997900000,\n    open: 56.48,\n    high: 56.5,\n    low: 56.47,\n    close: 56.5,\n    volume: 56260,\n  },\n  {\n    date: 1460997960000,\n    open: 56.51,\n    high: 56.52,\n    low: 56.51,\n    close: 56.5128,\n    volume: 25027,\n  },\n  {\n    date: 1460998020000,\n    open: 56.52,\n    high: 56.52,\n    low: 56.505,\n    close: 56.51,\n    volume: 17053,\n  },\n  {\n    date: 1460998080000,\n    open: 56.51,\n    high: 56.52,\n    low: 56.5,\n    close: 56.51,\n    volume: 41443,\n  },\n  {\n    date: 1460998140000,\n    open: 56.51,\n    high: 56.52,\n    low: 56.5,\n    close: 56.51,\n    volume: 34880,\n  },\n  {\n    date: 1460998200000,\n    open: 56.5083,\n    high: 56.51,\n    low: 56.5,\n    close: 56.504,\n    volume: 41051,\n  },\n  {\n    date: 1460998260000,\n    open: 56.505,\n    high: 56.52,\n    low: 56.485,\n    close: 56.505,\n    volume: 49762,\n  },\n  {\n    date: 1460998320000,\n    open: 56.51,\n    high: 56.51,\n    low: 56.5,\n    close: 56.51,\n    volume: 8924,\n  },\n  {\n    date: 1460998380000,\n    open: 56.5,\n    high: 56.52,\n    low: 56.49,\n    close: 56.52,\n    volume: 42532,\n  },\n  {\n    date: 1460998440000,\n    open: 56.515,\n    high: 56.52,\n    low: 56.48,\n    close: 56.49,\n    volume: 163286,\n  },\n  {\n    date: 1460998500000,\n    open: 56.49,\n    high: 56.49,\n    low: 56.45,\n    close: 56.45,\n    volume: 81007,\n  },\n  {\n    date: 1460998560000,\n    open: 56.4435,\n    high: 56.45,\n    low: 56.43,\n    close: 56.43,\n    volume: 44923,\n  },\n  {\n    date: 1460998620000,\n    open: 56.43,\n    high: 56.435,\n    low: 56.41,\n    close: 56.41,\n    volume: 30075,\n  },\n  {\n    date: 1460998680000,\n    open: 56.41,\n    high: 56.425,\n    low: 56.4,\n    close: 56.4,\n    volume: 37495,\n  },\n  {\n    date: 1460998740000,\n    open: 56.4,\n    high: 56.4,\n    low: 56.34,\n    close: 56.35,\n    volume: 33157,\n  },\n  {\n    date: 1460998800000,\n    open: 56.34,\n    high: 56.38,\n    low: 56.34,\n    close: 56.35,\n    volume: 89200,\n  },\n  {\n    date: 1460998860000,\n    open: 56.35,\n    high: 56.36,\n    low: 56.325,\n    close: 56.35,\n    volume: 54924,\n  },\n  {\n    date: 1460998920000,\n    open: 56.36,\n    high: 56.37,\n    low: 56.35,\n    close: 56.357,\n    volume: 22218,\n  },\n  {\n    date: 1460998980000,\n    open: 56.36,\n    high: 56.36,\n    low: 56.325,\n    close: 56.33,\n    volume: 19658,\n  },\n  {\n    date: 1460999040000,\n    open: 56.33,\n    high: 56.35,\n    low: 56.33,\n    close: 56.3458,\n    volume: 25868,\n  },\n  {\n    date: 1460999100000,\n    open: 56.34,\n    high: 56.37,\n    low: 56.33,\n    close: 56.365,\n    volume: 58927,\n  },\n  {\n    date: 1460999160000,\n    open: 56.38,\n    high: 56.41,\n    low: 56.3735,\n    close: 56.39,\n    volume: 142714,\n  },\n  {\n    date: 1460999220000,\n    open: 56.39,\n    high: 56.395,\n    low: 56.36,\n    close: 56.36,\n    volume: 40346,\n  },\n  {\n    date: 1460999280000,\n    open: 56.36,\n    high: 56.3699,\n    low: 56.31,\n    close: 56.31,\n    volume: 40954,\n  },\n  {\n    date: 1460999340000,\n    open: 56.32,\n    high: 56.33,\n    low: 56.31,\n    close: 56.33,\n    volume: 50317,\n  },\n  {\n    date: 1460999400000,\n    open: 56.33,\n    high: 56.35,\n    low: 56.33,\n    close: 56.33,\n    volume: 22002,\n  },\n  {\n    date: 1460999460000,\n    open: 56.34,\n    high: 56.35,\n    low: 56.32,\n    close: 56.3264,\n    volume: 31272,\n  },\n  {\n    date: 1460999520000,\n    open: 56.33,\n    high: 56.33,\n    low: 56.32,\n    close: 56.32,\n    volume: 16131,\n  },\n  {\n    date: 1460999580000,\n    open: 56.328,\n    high: 56.345,\n    low: 56.3,\n    close: 56.3301,\n    volume: 53834,\n  },\n  {\n    date: 1460999640000,\n    open: 56.335,\n    high: 56.34,\n    low: 56.33,\n    close: 56.33,\n    volume: 7072,\n  },\n  {\n    date: 1460999700000,\n    open: 56.34,\n    high: 56.36,\n    low: 56.33,\n    close: 56.36,\n    volume: 17697,\n  },\n  {\n    date: 1460999760000,\n    open: 56.35,\n    high: 56.35,\n    low: 56.34,\n    close: 56.35,\n    volume: 14306,\n  },\n  {\n    date: 1460999820000,\n    open: 56.35,\n    high: 56.35,\n    low: 56.34,\n    close: 56.35,\n    volume: 13504,\n  },\n  {\n    date: 1460999880000,\n    open: 56.35,\n    high: 56.35,\n    low: 56.3,\n    close: 56.3,\n    volume: 54626,\n  },\n  {\n    date: 1460999940000,\n    open: 56.31,\n    high: 56.32,\n    low: 56.26,\n    close: 56.26,\n    volume: 56341,\n  },\n  {\n    date: 1461000000000,\n    open: 56.26,\n    high: 56.27,\n    low: 56.23,\n    close: 56.26,\n    volume: 37948,\n  },\n  {\n    date: 1461000060000,\n    open: 56.2687,\n    high: 56.29,\n    low: 56.26,\n    close: 56.27,\n    volume: 25464,\n  },\n  {\n    date: 1461000120000,\n    open: 56.27,\n    high: 56.27,\n    low: 56.24,\n    close: 56.26,\n    volume: 31896,\n  },\n  {\n    date: 1461000180000,\n    open: 56.2531,\n    high: 56.27,\n    low: 56.25,\n    close: 56.26,\n    volume: 27317,\n  },\n  {\n    date: 1461000240000,\n    open: 56.27,\n    high: 56.27,\n    low: 56.24,\n    close: 56.25,\n    volume: 60498,\n  },\n  {\n    date: 1461000300000,\n    open: 56.24,\n    high: 56.33,\n    low: 56.23,\n    close: 56.3,\n    volume: 37487,\n  },\n  {\n    date: 1461000360000,\n    open: 56.3,\n    high: 56.31,\n    low: 56.29,\n    close: 56.305,\n    volume: 18244,\n  },\n  {\n    date: 1461000420000,\n    open: 56.3033,\n    high: 56.31,\n    low: 56.28,\n    close: 56.305,\n    volume: 35100,\n  },\n  {\n    date: 1461000480000,\n    open: 56.3,\n    high: 56.3,\n    low: 56.28,\n    close: 56.2936,\n    volume: 20784,\n  },\n  {\n    date: 1461000540000,\n    open: 56.3,\n    high: 56.31,\n    low: 56.29,\n    close: 56.299,\n    volume: 38103,\n  },\n  {\n    date: 1461000600000,\n    open: 56.29,\n    high: 56.3,\n    low: 56.29,\n    close: 56.3,\n    volume: 24469,\n  },\n  {\n    date: 1461000660000,\n    open: 56.29,\n    high: 56.31,\n    low: 56.275,\n    close: 56.295,\n    volume: 34621,\n  },\n  {\n    date: 1461000720000,\n    open: 56.2959,\n    high: 56.3,\n    low: 56.27,\n    close: 56.27,\n    volume: 19882,\n  },\n  {\n    date: 1461000780000,\n    open: 56.275,\n    high: 56.28,\n    low: 56.26,\n    close: 56.27,\n    volume: 23400,\n  },\n  {\n    date: 1461000840000,\n    open: 56.28,\n    high: 56.28,\n    low: 56.26,\n    close: 56.27,\n    volume: 15174,\n  },\n  {\n    date: 1461000900000,\n    open: 56.26,\n    high: 56.3099,\n    low: 56.26,\n    close: 56.28,\n    volume: 34956,\n  },\n  {\n    date: 1461000960000,\n    open: 56.27,\n    high: 56.32,\n    low: 56.26,\n    close: 56.32,\n    volume: 49461,\n  },\n  {\n    date: 1461001020000,\n    open: 56.31,\n    high: 56.32,\n    low: 56.29,\n    close: 56.295,\n    volume: 22548,\n  },\n  {\n    date: 1461001080000,\n    open: 56.29,\n    high: 56.32,\n    low: 56.29,\n    close: 56.3,\n    volume: 60921,\n  },\n  {\n    date: 1461001140000,\n    open: 56.3,\n    high: 56.31,\n    low: 56.28,\n    close: 56.2936,\n    volume: 59330,\n  },\n  {\n    date: 1461001200000,\n    open: 56.29,\n    high: 56.3336,\n    low: 56.29,\n    close: 56.3025,\n    volume: 103631,\n  },\n  {\n    date: 1461001260000,\n    open: 56.3,\n    high: 56.3364,\n    low: 56.3,\n    close: 56.335,\n    volume: 30494,\n  },\n  {\n    date: 1461001320000,\n    open: 56.34,\n    high: 56.41,\n    low: 56.335,\n    close: 56.4,\n    volume: 47693,\n  },\n  {\n    date: 1461001380000,\n    open: 56.4099,\n    high: 56.43,\n    low: 56.4,\n    close: 56.42,\n    volume: 17853,\n  },\n  {\n    date: 1461001440000,\n    open: 56.43,\n    high: 56.44,\n    low: 56.42,\n    close: 56.43,\n    volume: 16207,\n  },\n  {\n    date: 1461001500000,\n    open: 56.43,\n    high: 56.45,\n    low: 56.42,\n    close: 56.45,\n    volume: 31400,\n  },\n  {\n    date: 1461001560000,\n    open: 56.4468,\n    high: 56.45,\n    low: 56.435,\n    close: 56.44,\n    volume: 23242,\n  },\n  {\n    date: 1461001620000,\n    open: 56.4399,\n    high: 56.48,\n    low: 56.43,\n    close: 56.47,\n    volume: 35825,\n  },\n  {\n    date: 1461001680000,\n    open: 56.46,\n    high: 56.47,\n    low: 56.43,\n    close: 56.44,\n    volume: 36558,\n  },\n  {\n    date: 1461001740000,\n    open: 56.438,\n    high: 56.44,\n    low: 56.4265,\n    close: 56.44,\n    volume: 11117,\n  },\n  {\n    date: 1461001800000,\n    open: 56.437,\n    high: 56.44,\n    low: 56.405,\n    close: 56.43,\n    volume: 19772,\n  },\n  {\n    date: 1461001860000,\n    open: 56.4265,\n    high: 56.44,\n    low: 56.41,\n    close: 56.4202,\n    volume: 20578,\n  },\n  {\n    date: 1461001920000,\n    open: 56.43,\n    high: 56.43,\n    low: 56.41,\n    close: 56.425,\n    volume: 22186,\n  },\n  {\n    date: 1461001980000,\n    open: 56.43,\n    high: 56.46,\n    low: 56.425,\n    close: 56.46,\n    volume: 12008,\n  },\n  {\n    date: 1461002040000,\n    open: 56.45,\n    high: 56.47,\n    low: 56.42,\n    close: 56.44,\n    volume: 80257,\n  },\n  {\n    date: 1461002100000,\n    open: 56.4401,\n    high: 56.46,\n    low: 56.44,\n    close: 56.46,\n    volume: 10807,\n  },\n  {\n    date: 1461002160000,\n    open: 56.46,\n    high: 56.465,\n    low: 56.45,\n    close: 56.465,\n    volume: 12739,\n  },\n  {\n    date: 1461002220000,\n    open: 56.464,\n    high: 56.47,\n    low: 56.45,\n    close: 56.45,\n    volume: 18098,\n  },\n  {\n    date: 1461002280000,\n    open: 56.457,\n    high: 56.47,\n    low: 56.4435,\n    close: 56.4435,\n    volume: 25815,\n  },\n  {\n    date: 1461002340000,\n    open: 56.45,\n    high: 56.46,\n    low: 56.435,\n    close: 56.45,\n    volume: 15555,\n  },\n  {\n    date: 1461002400000,\n    open: 56.445,\n    high: 56.48,\n    low: 56.445,\n    close: 56.47,\n    volume: 25537,\n  },\n  {\n    date: 1461002460000,\n    open: 56.47,\n    high: 56.47,\n    low: 56.45,\n    close: 56.465,\n    volume: 70969,\n  },\n  {\n    date: 1461002520000,\n    open: 56.46,\n    high: 56.465,\n    low: 56.44,\n    close: 56.4501,\n    volume: 39537,\n  },\n  {\n    date: 1461002580000,\n    open: 56.455,\n    high: 56.47,\n    low: 56.45,\n    close: 56.46,\n    volume: 38495,\n  },\n  {\n    date: 1461002640000,\n    open: 56.46,\n    high: 56.5,\n    low: 56.46,\n    close: 56.47,\n    volume: 84788,\n  },\n  {\n    date: 1461002700000,\n    open: 56.4736,\n    high: 56.5,\n    low: 56.47,\n    close: 56.495,\n    volume: 34321,\n  },\n  {\n    date: 1461002760000,\n    open: 56.495,\n    high: 56.505,\n    low: 56.47,\n    close: 56.5,\n    volume: 46669,\n  },\n  {\n    date: 1461002820000,\n    open: 56.505,\n    high: 56.51,\n    low: 56.49,\n    close: 56.495,\n    volume: 23153,\n  },\n  {\n    date: 1461002880000,\n    open: 56.4936,\n    high: 56.515,\n    low: 56.48,\n    close: 56.511,\n    volume: 38348,\n  },\n  {\n    date: 1461002940000,\n    open: 56.5111,\n    high: 56.52,\n    low: 56.47,\n    close: 56.47,\n    volume: 32150,\n  },\n  {\n    date: 1461003000000,\n    open: 56.47,\n    high: 56.495,\n    low: 56.44,\n    close: 56.44,\n    volume: 53397,\n  },\n  {\n    date: 1461003060000,\n    open: 56.4501,\n    high: 56.47,\n    low: 56.45,\n    close: 56.451,\n    volume: 16570,\n  },\n  {\n    date: 1461003120000,\n    open: 56.46,\n    high: 56.46,\n    low: 56.44,\n    close: 56.45,\n    volume: 18348,\n  },\n  {\n    date: 1461003180000,\n    open: 56.45,\n    high: 56.48,\n    low: 56.45,\n    close: 56.48,\n    volume: 34150,\n  },\n  {\n    date: 1461003240000,\n    open: 56.48,\n    high: 56.49,\n    low: 56.47,\n    close: 56.47,\n    volume: 16188,\n  },\n  {\n    date: 1461003300000,\n    open: 56.4799,\n    high: 56.5,\n    low: 56.47,\n    close: 56.49,\n    volume: 25157,\n  },\n  {\n    date: 1461003360000,\n    open: 56.49,\n    high: 56.495,\n    low: 56.47,\n    close: 56.475,\n    volume: 10535,\n  },\n  {\n    date: 1461003420000,\n    open: 56.48,\n    high: 56.48,\n    low: 56.47,\n    close: 56.475,\n    volume: 26835,\n  },\n  {\n    date: 1461003480000,\n    open: 56.47,\n    high: 56.48,\n    low: 56.45,\n    close: 56.46,\n    volume: 36938,\n  },\n  {\n    date: 1461003540000,\n    open: 56.46,\n    high: 56.49,\n    low: 56.46,\n    close: 56.4835,\n    volume: 21754,\n  },\n  {\n    date: 1461003600000,\n    open: 56.4838,\n    high: 56.485,\n    low: 56.46,\n    close: 56.47,\n    volume: 25138,\n  },\n  {\n    date: 1461003660000,\n    open: 56.48,\n    high: 56.5,\n    low: 56.48,\n    close: 56.4825,\n    volume: 47681,\n  },\n  {\n    date: 1461003720000,\n    open: 56.4872,\n    high: 56.52,\n    low: 56.48,\n    close: 56.519,\n    volume: 41000,\n  },\n  {\n    date: 1461003780000,\n    open: 56.5128,\n    high: 56.52,\n    low: 56.5001,\n    close: 56.505,\n    volume: 33881,\n  },\n  {\n    date: 1461003840000,\n    open: 56.51,\n    high: 56.51,\n    low: 56.49,\n    close: 56.49,\n    volume: 19260,\n  },\n  {\n    date: 1461003900000,\n    open: 56.5,\n    high: 56.5,\n    low: 56.46,\n    close: 56.465,\n    volume: 52861,\n  },\n  {\n    date: 1461003960000,\n    open: 56.465,\n    high: 56.51,\n    low: 56.46,\n    close: 56.495,\n    volume: 66277,\n  },\n  {\n    date: 1461004020000,\n    open: 56.495,\n    high: 56.495,\n    low: 56.45,\n    close: 56.46,\n    volume: 24003,\n  },\n  {\n    date: 1461004080000,\n    open: 56.46,\n    high: 56.48,\n    low: 56.46,\n    close: 56.465,\n    volume: 20392,\n  },\n  {\n    date: 1461004140000,\n    open: 56.46,\n    high: 56.51,\n    low: 56.45,\n    close: 56.46,\n    volume: 90395,\n  },\n  {\n    date: 1461004200000,\n    open: 56.46,\n    high: 56.48,\n    low: 56.45,\n    close: 56.45,\n    volume: 53623,\n  },\n  {\n    date: 1461004260000,\n    open: 56.456,\n    high: 56.46,\n    low: 56.44,\n    close: 56.45,\n    volume: 29772,\n  },\n  {\n    date: 1461004320000,\n    open: 56.4532,\n    high: 56.47,\n    low: 56.45,\n    close: 56.465,\n    volume: 13878,\n  },\n  {\n    date: 1461004380000,\n    open: 56.47,\n    high: 56.48,\n    low: 56.46,\n    close: 56.48,\n    volume: 20878,\n  },\n  {\n    date: 1461004440000,\n    open: 56.47,\n    high: 56.485,\n    low: 56.4601,\n    close: 56.485,\n    volume: 48836,\n  },\n  {\n    date: 1461004500000,\n    open: 56.4802,\n    high: 56.49,\n    low: 56.45,\n    close: 56.455,\n    volume: 56732,\n  },\n  {\n    date: 1461004560000,\n    open: 56.4599,\n    high: 56.479,\n    low: 56.45,\n    close: 56.479,\n    volume: 19822,\n  },\n  {\n    date: 1461004620000,\n    open: 56.48,\n    high: 56.52,\n    low: 56.475,\n    close: 56.49,\n    volume: 41255,\n  },\n  {\n    date: 1461004680000,\n    open: 56.495,\n    high: 56.52,\n    low: 56.49,\n    close: 56.515,\n    volume: 39011,\n  },\n  {\n    date: 1461004740000,\n    open: 56.515,\n    high: 56.52,\n    low: 56.48,\n    close: 56.48,\n    volume: 21925,\n  },\n  {\n    date: 1461004800000,\n    open: 56.48,\n    high: 56.5,\n    low: 56.475,\n    close: 56.5,\n    volume: 39754,\n  },\n  {\n    date: 1461004860000,\n    open: 56.49,\n    high: 56.52,\n    low: 56.49,\n    close: 56.515,\n    volume: 39101,\n  },\n  {\n    date: 1461004920000,\n    open: 56.515,\n    high: 56.525,\n    low: 56.5,\n    close: 56.5099,\n    volume: 48164,\n  },\n  {\n    date: 1461004980000,\n    open: 56.51,\n    high: 56.52,\n    low: 56.5005,\n    close: 56.505,\n    volume: 13362,\n  },\n  {\n    date: 1461005040000,\n    open: 56.503,\n    high: 56.545,\n    low: 56.5,\n    close: 56.54,\n    volume: 38363,\n  },\n  {\n    date: 1461005100000,\n    open: 56.54,\n    high: 56.54,\n    low: 56.522,\n    close: 56.522,\n    volume: 21135,\n  },\n  {\n    date: 1461005160000,\n    open: 56.52,\n    high: 56.525,\n    low: 56.5,\n    close: 56.5025,\n    volume: 52068,\n  },\n  {\n    date: 1461005220000,\n    open: 56.5058,\n    high: 56.51,\n    low: 56.5,\n    close: 56.505,\n    volume: 30907,\n  },\n  {\n    date: 1461005280000,\n    open: 56.51,\n    high: 56.535,\n    low: 56.5,\n    close: 56.535,\n    volume: 22442,\n  },\n  {\n    date: 1461005340000,\n    open: 56.54,\n    high: 56.55,\n    low: 56.5,\n    close: 56.54,\n    volume: 76404,\n  },\n  {\n    date: 1461005400000,\n    open: 56.53,\n    high: 56.54,\n    low: 56.52,\n    close: 56.52,\n    volume: 48621,\n  },\n  {\n    date: 1461005460000,\n    open: 56.523,\n    high: 56.55,\n    low: 56.505,\n    close: 56.51,\n    volume: 75071,\n  },\n  {\n    date: 1461005520000,\n    open: 56.5137,\n    high: 56.53,\n    low: 56.505,\n    close: 56.5223,\n    volume: 35859,\n  },\n  {\n    date: 1461005580000,\n    open: 56.5228,\n    high: 56.527,\n    low: 56.5,\n    close: 56.5171,\n    volume: 38262,\n  },\n  {\n    date: 1461005640000,\n    open: 56.5138,\n    high: 56.515,\n    low: 56.5,\n    close: 56.51,\n    volume: 17354,\n  },\n  {\n    date: 1461005700000,\n    open: 56.515,\n    high: 56.52,\n    low: 56.495,\n    close: 56.51,\n    volume: 42073,\n  },\n  {\n    date: 1461005760000,\n    open: 56.51,\n    high: 56.5199,\n    low: 56.5,\n    close: 56.515,\n    volume: 10928,\n  },\n  {\n    date: 1461005820000,\n    open: 56.51,\n    high: 56.52,\n    low: 56.47,\n    close: 56.49,\n    volume: 32137,\n  },\n  {\n    date: 1461005880000,\n    open: 56.48,\n    high: 56.49,\n    low: 56.455,\n    close: 56.465,\n    volume: 37079,\n  },\n  {\n    date: 1461005940000,\n    open: 56.4699,\n    high: 56.4799,\n    low: 56.44,\n    close: 56.47,\n    volume: 33930,\n  },\n  {\n    date: 1461006000000,\n    open: 56.47,\n    high: 56.5,\n    low: 56.46,\n    close: 56.5,\n    volume: 22312,\n  },\n  {\n    date: 1461006060000,\n    open: 56.5,\n    high: 56.5,\n    low: 56.48,\n    close: 56.485,\n    volume: 25986,\n  },\n  {\n    date: 1461006120000,\n    open: 56.485,\n    high: 56.49,\n    low: 56.47,\n    close: 56.47,\n    volume: 19588,\n  },\n  {\n    date: 1461006180000,\n    open: 56.47,\n    high: 56.5,\n    low: 56.4624,\n    close: 56.5,\n    volume: 35560,\n  },\n  {\n    date: 1461006240000,\n    open: 56.51,\n    high: 56.51,\n    low: 56.49,\n    close: 56.4937,\n    volume: 22917,\n  },\n  {\n    date: 1461006300000,\n    open: 56.4933,\n    high: 56.5,\n    low: 56.48,\n    close: 56.48,\n    volume: 23143,\n  },\n  {\n    date: 1461006360000,\n    open: 56.47,\n    high: 56.48,\n    low: 56.4601,\n    close: 56.47,\n    volume: 16301,\n  },\n  {\n    date: 1461006420000,\n    open: 56.48,\n    high: 56.48,\n    low: 56.47,\n    close: 56.47,\n    volume: 12068,\n  },\n  {\n    date: 1461006480000,\n    open: 56.471,\n    high: 56.471,\n    low: 56.42,\n    close: 56.455,\n    volume: 51020,\n  },\n  {\n    date: 1461006540000,\n    open: 56.4502,\n    high: 56.49,\n    low: 56.45,\n    close: 56.49,\n    volume: 18372,\n  },\n  {\n    date: 1461006600000,\n    open: 56.49,\n    high: 56.5,\n    low: 56.47,\n    close: 56.495,\n    volume: 38003,\n  },\n  {\n    date: 1461006660000,\n    open: 56.4901,\n    high: 56.5,\n    low: 56.48,\n    close: 56.496,\n    volume: 28615,\n  },\n  {\n    date: 1461006720000,\n    open: 56.4901,\n    high: 56.5,\n    low: 56.46,\n    close: 56.4601,\n    volume: 40709,\n  },\n  {\n    date: 1461006780000,\n    open: 56.4672,\n    high: 56.495,\n    low: 56.45,\n    close: 56.495,\n    volume: 22013,\n  },\n  {\n    date: 1461006840000,\n    open: 56.495,\n    high: 56.5,\n    low: 56.48,\n    close: 56.49,\n    volume: 28700,\n  },\n  {\n    date: 1461006900000,\n    open: 56.485,\n    high: 56.51,\n    low: 56.46,\n    close: 56.46,\n    volume: 45225,\n  },\n  {\n    date: 1461006960000,\n    open: 56.465,\n    high: 56.505,\n    low: 56.46,\n    close: 56.505,\n    volume: 31536,\n  },\n  {\n    date: 1461007020000,\n    open: 56.5069,\n    high: 56.52,\n    low: 56.495,\n    close: 56.515,\n    volume: 32388,\n  },\n  {\n    date: 1461007080000,\n    open: 56.515,\n    high: 56.53,\n    low: 56.5,\n    close: 56.515,\n    volume: 38239,\n  },\n  {\n    date: 1461007140000,\n    open: 56.52,\n    high: 56.535,\n    low: 56.51,\n    close: 56.52,\n    volume: 52704,\n  },\n  {\n    date: 1461007200000,\n    open: 56.5201,\n    high: 56.54,\n    low: 56.52,\n    close: 56.5301,\n    volume: 28250,\n  },\n  {\n    date: 1461007260000,\n    open: 56.54,\n    high: 56.55,\n    low: 56.52,\n    close: 56.525,\n    volume: 42075,\n  },\n  {\n    date: 1461007320000,\n    open: 56.5294,\n    high: 56.5294,\n    low: 56.4733,\n    close: 56.485,\n    volume: 42014,\n  },\n  {\n    date: 1461007380000,\n    open: 56.48,\n    high: 56.48,\n    low: 56.45,\n    close: 56.455,\n    volume: 48273,\n  },\n  {\n    date: 1461007440000,\n    open: 56.4636,\n    high: 56.48,\n    low: 56.4535,\n    close: 56.4701,\n    volume: 34600,\n  },\n  {\n    date: 1461007500000,\n    open: 56.475,\n    high: 56.475,\n    low: 56.46,\n    close: 56.463,\n    volume: 22282,\n  },\n  {\n    date: 1461007560000,\n    open: 56.46,\n    high: 56.47,\n    low: 56.45,\n    close: 56.47,\n    volume: 45293,\n  },\n  {\n    date: 1461007620000,\n    open: 56.465,\n    high: 56.49,\n    low: 56.46,\n    close: 56.472,\n    volume: 41321,\n  },\n  {\n    date: 1461007680000,\n    open: 56.47,\n    high: 56.495,\n    low: 56.47,\n    close: 56.49,\n    volume: 46436,\n  },\n  {\n    date: 1461007740000,\n    open: 56.495,\n    high: 56.5,\n    low: 56.47,\n    close: 56.48,\n    volume: 57296,\n  },\n  {\n    date: 1461007800000,\n    open: 56.48,\n    high: 56.49,\n    low: 56.47,\n    close: 56.49,\n    volume: 16845,\n  },\n  {\n    date: 1461007860000,\n    open: 56.485,\n    high: 56.4999,\n    low: 56.46,\n    close: 56.4939,\n    volume: 81601,\n  },\n  {\n    date: 1461007920000,\n    open: 56.4913,\n    high: 56.5,\n    low: 56.49,\n    close: 56.49,\n    volume: 57514,\n  },\n  {\n    date: 1461007980000,\n    open: 56.49,\n    high: 56.51,\n    low: 56.49,\n    close: 56.495,\n    volume: 89349,\n  },\n  {\n    date: 1461008040000,\n    open: 56.4905,\n    high: 56.53,\n    low: 56.485,\n    close: 56.53,\n    volume: 307808,\n  },\n  {\n    date: 1461008100000,\n    open: 56.53,\n    high: 56.54,\n    low: 56.5,\n    close: 56.5,\n    volume: 65549,\n  },\n  {\n    date: 1461008160000,\n    open: 56.5,\n    high: 56.5099,\n    low: 56.47,\n    close: 56.47,\n    volume: 56294,\n  },\n  {\n    date: 1461008220000,\n    open: 56.4701,\n    high: 56.51,\n    low: 56.47,\n    close: 56.48,\n    volume: 51122,\n  },\n  {\n    date: 1461008280000,\n    open: 56.49,\n    high: 56.49,\n    low: 56.47,\n    close: 56.475,\n    volume: 50662,\n  },\n  {\n    date: 1461008340000,\n    open: 56.4709,\n    high: 56.49,\n    low: 56.47,\n    close: 56.47,\n    volume: 60224,\n  },\n  {\n    date: 1461008400000,\n    open: 56.475,\n    high: 56.475,\n    low: 56.46,\n    close: 56.468,\n    volume: 24941,\n  },\n  {\n    date: 1461008460000,\n    open: 56.47,\n    high: 56.495,\n    low: 56.45,\n    close: 56.495,\n    volume: 79524,\n  },\n  {\n    date: 1461008520000,\n    open: 56.48,\n    high: 56.54,\n    low: 56.48,\n    close: 56.535,\n    volume: 56149,\n  },\n  {\n    date: 1461008580000,\n    open: 56.535,\n    high: 56.555,\n    low: 56.52,\n    close: 56.55,\n    volume: 109054,\n  },\n  {\n    date: 1461008640000,\n    open: 56.55,\n    high: 56.55,\n    low: 56.495,\n    close: 56.515,\n    volume: 141813,\n  },\n  {\n    date: 1461008700000,\n    open: 56.515,\n    high: 56.535,\n    low: 56.5,\n    close: 56.5,\n    volume: 142573,\n  },\n  {\n    date: 1461008760000,\n    open: 56.505,\n    high: 56.515,\n    low: 56.48,\n    close: 56.505,\n    volume: 67443,\n  },\n  {\n    date: 1461008820000,\n    open: 56.51,\n    high: 56.525,\n    low: 56.5,\n    close: 56.51,\n    volume: 77970,\n  },\n  {\n    date: 1461008880000,\n    open: 56.52,\n    high: 56.54,\n    low: 56.5,\n    close: 56.5261,\n    volume: 87080,\n  },\n  {\n    date: 1461008940000,\n    open: 56.53,\n    high: 56.53,\n    low: 56.5,\n    close: 56.5,\n    volume: 99915,\n  },\n  {\n    date: 1461009000000,\n    open: 56.5,\n    high: 56.5075,\n    low: 56.46,\n    close: 56.48,\n    volume: 70822,\n  },\n  {\n    date: 1461009060000,\n    open: 56.48,\n    high: 56.5,\n    low: 56.47,\n    close: 56.5,\n    volume: 112618,\n  },\n  {\n    date: 1461009120000,\n    open: 56.5,\n    high: 56.51,\n    low: 56.49,\n    close: 56.49,\n    volume: 68952,\n  },\n  {\n    date: 1461009180000,\n    open: 56.495,\n    high: 56.4999,\n    low: 56.47,\n    close: 56.48,\n    volume: 125145,\n  },\n  {\n    date: 1461009240000,\n    open: 56.475,\n    high: 56.5,\n    low: 56.4601,\n    close: 56.5,\n    volume: 95920,\n  },\n  {\n    date: 1461009300000,\n    open: 56.5,\n    high: 56.5,\n    low: 56.47,\n    close: 56.485,\n    volume: 155747,\n  },\n  {\n    date: 1461009360000,\n    open: 56.49,\n    high: 56.49,\n    low: 56.45,\n    close: 56.46,\n    volume: 181252,\n  },\n  {\n    date: 1461009420000,\n    open: 56.45,\n    high: 56.475,\n    low: 56.45,\n    close: 56.47,\n    volume: 163982,\n  },\n  {\n    date: 1461009480000,\n    open: 56.455,\n    high: 56.46,\n    low: 56.44,\n    close: 56.445,\n    volume: 38734,\n  },\n  {\n    date: 1461009540000,\n    open: 56.44,\n    high: 56.45,\n    low: 56.43,\n    close: 56.445,\n    volume: 121723,\n  },\n  {\n    date: 1461009600000,\n    open: 56.44,\n    high: 56.48,\n    low: 56.44,\n    close: 56.46,\n    volume: 1898870,\n  },\n  {\n    date: 1461072600000,\n    open: 56.63,\n    high: 56.77,\n    low: 56.62,\n    close: 56.65,\n    volume: 358554,\n  },\n  {\n    date: 1461072660000,\n    open: 56.665,\n    high: 56.74,\n    low: 56.64,\n    close: 56.65,\n    volume: 146116,\n  },\n  {\n    date: 1461072720000,\n    open: 56.645,\n    high: 56.66,\n    low: 56.561,\n    close: 56.59,\n    volume: 172803,\n  },\n  {\n    date: 1461072780000,\n    open: 56.59,\n    high: 56.6,\n    low: 56.51,\n    close: 56.555,\n    volume: 159441,\n  },\n  {\n    date: 1461072840000,\n    open: 56.555,\n    high: 56.58,\n    low: 56.475,\n    close: 56.4855,\n    volume: 163869,\n  },\n  {\n    date: 1461072900000,\n    open: 56.49,\n    high: 56.52,\n    low: 56.36,\n    close: 56.36,\n    volume: 140045,\n  },\n  {\n    date: 1461072960000,\n    open: 56.36,\n    high: 56.37,\n    low: 56.31,\n    close: 56.36,\n    volume: 145838,\n  },\n  {\n    date: 1461073020000,\n    open: 56.36,\n    high: 56.36,\n    low: 56.11,\n    close: 56.11,\n    volume: 374767,\n  },\n  {\n    date: 1461073080000,\n    open: 56.1,\n    high: 56.11,\n    low: 55.91,\n    close: 55.99,\n    volume: 514291,\n  },\n  {\n    date: 1461073140000,\n    open: 55.99,\n    high: 56.03,\n    low: 55.88,\n    close: 55.97,\n    volume: 283029,\n  },\n  {\n    date: 1461073200000,\n    open: 55.96,\n    high: 56.05,\n    low: 55.96,\n    close: 56.02,\n    volume: 157151,\n  },\n  {\n    date: 1461073260000,\n    open: 56.02,\n    high: 56.03,\n    low: 55.75,\n    close: 55.76,\n    volume: 405630,\n  },\n  {\n    date: 1461073320000,\n    open: 55.76,\n    high: 55.87,\n    low: 55.68,\n    close: 55.85,\n    volume: 267003,\n  },\n  {\n    date: 1461073380000,\n    open: 55.86,\n    high: 55.96,\n    low: 55.825,\n    close: 55.93,\n    volume: 205257,\n  },\n  {\n    date: 1461073440000,\n    open: 55.9325,\n    high: 56.04,\n    low: 55.925,\n    close: 56.01,\n    volume: 284401,\n  },\n  {\n    date: 1461073500000,\n    open: 56.01,\n    high: 56.1,\n    low: 56.005,\n    close: 56.04,\n    volume: 173116,\n  },\n  {\n    date: 1461073560000,\n    open: 56.04,\n    high: 56.12,\n    low: 56,\n    close: 56.11,\n    volume: 207216,\n  },\n  {\n    date: 1461073620000,\n    open: 56.11,\n    high: 56.18,\n    low: 56.09,\n    close: 56.12,\n    volume: 203198,\n  },\n  {\n    date: 1461073680000,\n    open: 56.12,\n    high: 56.221,\n    low: 56.115,\n    close: 56.14,\n    volume: 169136,\n  },\n  {\n    date: 1461073740000,\n    open: 56.1401,\n    high: 56.17,\n    low: 56.1,\n    close: 56.16,\n    volume: 72483,\n  },\n  {\n    date: 1461073800000,\n    open: 56.17,\n    high: 56.26,\n    low: 56.1402,\n    close: 56.22,\n    volume: 175357,\n  },\n  {\n    date: 1461073860000,\n    open: 56.2,\n    high: 56.25,\n    low: 56.17,\n    close: 56.23,\n    volume: 132252,\n  },\n  {\n    date: 1461073920000,\n    open: 56.24,\n    high: 56.3,\n    low: 56.14,\n    close: 56.14,\n    volume: 134531,\n  },\n  {\n    date: 1461073980000,\n    open: 56.14,\n    high: 56.145,\n    low: 56.05,\n    close: 56.09,\n    volume: 123200,\n  },\n  {\n    date: 1461074040000,\n    open: 56.09,\n    high: 56.09,\n    low: 56.03,\n    close: 56.075,\n    volume: 153741,\n  },\n  {\n    date: 1461074100000,\n    open: 56.075,\n    high: 56.09,\n    low: 56,\n    close: 56.005,\n    volume: 87306,\n  },\n  {\n    date: 1461074160000,\n    open: 56,\n    high: 56.0562,\n    low: 56,\n    close: 56.04,\n    volume: 86267,\n  },\n  {\n    date: 1461074220000,\n    open: 56.05,\n    high: 56.06,\n    low: 56.02,\n    close: 56.04,\n    volume: 58736,\n  },\n  {\n    date: 1461074280000,\n    open: 56.041,\n    high: 56.13,\n    low: 56.041,\n    close: 56.115,\n    volume: 99549,\n  },\n  {\n    date: 1461074340000,\n    open: 56.125,\n    high: 56.14,\n    low: 56.0538,\n    close: 56.0538,\n    volume: 61633,\n  },\n  {\n    date: 1461074400000,\n    open: 56.05,\n    high: 56.06,\n    low: 56,\n    close: 56.03,\n    volume: 150006,\n  },\n  {\n    date: 1461074460000,\n    open: 56.03,\n    high: 56.05,\n    low: 56,\n    close: 56.0001,\n    volume: 207159,\n  },\n  {\n    date: 1461074520000,\n    open: 56.005,\n    high: 56.16,\n    low: 56,\n    close: 56.11,\n    volume: 343365,\n  },\n  {\n    date: 1461074580000,\n    open: 56.11,\n    high: 56.17,\n    low: 56.1,\n    close: 56.14,\n    volume: 109922,\n  },\n  {\n    date: 1461074640000,\n    open: 56.14,\n    high: 56.22,\n    low: 56.13,\n    close: 56.21,\n    volume: 129595,\n  },\n  {\n    date: 1461074700000,\n    open: 56.205,\n    high: 56.21,\n    low: 56.13,\n    close: 56.2,\n    volume: 243782,\n  },\n  {\n    date: 1461074760000,\n    open: 56.2,\n    high: 56.21,\n    low: 56.14,\n    close: 56.17,\n    volume: 92802,\n  },\n  {\n    date: 1461074820000,\n    open: 56.17,\n    high: 56.21,\n    low: 56.155,\n    close: 56.205,\n    volume: 85889,\n  },\n  {\n    date: 1461074880000,\n    open: 56.21,\n    high: 56.21,\n    low: 56.145,\n    close: 56.175,\n    volume: 267195,\n  },\n  {\n    date: 1461074940000,\n    open: 56.1734,\n    high: 56.175,\n    low: 56.13,\n    close: 56.13,\n    volume: 61402,\n  },\n  {\n    date: 1461075000000,\n    open: 56.14,\n    high: 56.15,\n    low: 56.12,\n    close: 56.13,\n    volume: 54244,\n  },\n  {\n    date: 1461075060000,\n    open: 56.14,\n    high: 56.21,\n    low: 56.133,\n    close: 56.2,\n    volume: 176899,\n  },\n  {\n    date: 1461075120000,\n    open: 56.2,\n    high: 56.22,\n    low: 56.2,\n    close: 56.2,\n    volume: 55781,\n  },\n  {\n    date: 1461075180000,\n    open: 56.205,\n    high: 56.245,\n    low: 56.19,\n    close: 56.23,\n    volume: 124342,\n  },\n  {\n    date: 1461075240000,\n    open: 56.23,\n    high: 56.25,\n    low: 56.19,\n    close: 56.2201,\n    volume: 64303,\n  },\n  {\n    date: 1461075300000,\n    open: 56.225,\n    high: 56.23,\n    low: 56.19,\n    close: 56.21,\n    volume: 28602,\n  },\n  {\n    date: 1461075360000,\n    open: 56.21,\n    high: 56.25,\n    low: 56.18,\n    close: 56.185,\n    volume: 55600,\n  },\n  {\n    date: 1461075420000,\n    open: 56.18,\n    high: 56.18,\n    low: 56.09,\n    close: 56.17,\n    volume: 118672,\n  },\n  {\n    date: 1461075480000,\n    open: 56.17,\n    high: 56.2,\n    low: 56.14,\n    close: 56.19,\n    volume: 42389,\n  },\n  {\n    date: 1461075540000,\n    open: 56.195,\n    high: 56.2,\n    low: 56.15,\n    close: 56.16,\n    volume: 41702,\n  },\n  {\n    date: 1461075600000,\n    open: 56.17,\n    high: 56.19,\n    low: 56.16,\n    close: 56.1741,\n    volume: 112776,\n  },\n  {\n    date: 1461075660000,\n    open: 56.17,\n    high: 56.225,\n    low: 56.17,\n    close: 56.22,\n    volume: 48119,\n  },\n  {\n    date: 1461075720000,\n    open: 56.2299,\n    high: 56.24,\n    low: 56.18,\n    close: 56.18,\n    volume: 47054,\n  },\n  {\n    date: 1461075780000,\n    open: 56.18,\n    high: 56.1999,\n    low: 56.18,\n    close: 56.18,\n    volume: 34640,\n  },\n  {\n    date: 1461075840000,\n    open: 56.17,\n    high: 56.175,\n    low: 56.12,\n    close: 56.12,\n    volume: 21978,\n  },\n  {\n    date: 1461075900000,\n    open: 56.1299,\n    high: 56.14,\n    low: 56.07,\n    close: 56.075,\n    volume: 71185,\n  },\n  {\n    date: 1461075960000,\n    open: 56.075,\n    high: 56.1,\n    low: 56.07,\n    close: 56.08,\n    volume: 49867,\n  },\n  {\n    date: 1461076020000,\n    open: 56.075,\n    high: 56.105,\n    low: 56.06,\n    close: 56.06,\n    volume: 54527,\n  },\n  {\n    date: 1461076080000,\n    open: 56.07,\n    high: 56.09,\n    low: 56.05,\n    close: 56.0599,\n    volume: 75736,\n  },\n  {\n    date: 1461076140000,\n    open: 56.05,\n    high: 56.12,\n    low: 56.03,\n    close: 56.12,\n    volume: 114574,\n  },\n  {\n    date: 1461076200000,\n    open: 56.12,\n    high: 56.12,\n    low: 56.01,\n    close: 56.03,\n    volume: 110748,\n  },\n  {\n    date: 1461076260000,\n    open: 56.04,\n    high: 56.14,\n    low: 56.035,\n    close: 56.14,\n    volume: 67078,\n  },\n  {\n    date: 1461076320000,\n    open: 56.1466,\n    high: 56.185,\n    low: 56.12,\n    close: 56.185,\n    volume: 68131,\n  },\n  {\n    date: 1461076380000,\n    open: 56.18,\n    high: 56.21,\n    low: 56.18,\n    close: 56.21,\n    volume: 70795,\n  },\n  {\n    date: 1461076440000,\n    open: 56.22,\n    high: 56.23,\n    low: 56.21,\n    close: 56.22,\n    volume: 25175,\n  },\n  {\n    date: 1461076500000,\n    open: 56.229,\n    high: 56.255,\n    low: 56.21,\n    close: 56.246,\n    volume: 55580,\n  },\n  {\n    date: 1461076560000,\n    open: 56.25,\n    high: 56.25,\n    low: 56.15,\n    close: 56.157,\n    volume: 121382,\n  },\n  {\n    date: 1461076620000,\n    open: 56.15,\n    high: 56.16,\n    low: 56.115,\n    close: 56.14,\n    volume: 39649,\n  },\n  {\n    date: 1461076680000,\n    open: 56.14,\n    high: 56.16,\n    low: 56.12,\n    close: 56.12,\n    volume: 58194,\n  },\n  {\n    date: 1461076740000,\n    open: 56.1205,\n    high: 56.13,\n    low: 56.1,\n    close: 56.1,\n    volume: 18242,\n  },\n  {\n    date: 1461076800000,\n    open: 56.1001,\n    high: 56.15,\n    low: 56.1001,\n    close: 56.13,\n    volume: 23147,\n  },\n  {\n    date: 1461076860000,\n    open: 56.1301,\n    high: 56.14,\n    low: 56.095,\n    close: 56.1,\n    volume: 27520,\n  },\n  {\n    date: 1461076920000,\n    open: 56.1,\n    high: 56.109,\n    low: 56.05,\n    close: 56.109,\n    volume: 54049,\n  },\n  {\n    date: 1461076980000,\n    open: 56.095,\n    high: 56.13,\n    low: 56.09,\n    close: 56.125,\n    volume: 37229,\n  },\n  {\n    date: 1461077040000,\n    open: 56.12,\n    high: 56.16,\n    low: 56.11,\n    close: 56.15,\n    volume: 54511,\n  },\n  {\n    date: 1461077100000,\n    open: 56.155,\n    high: 56.17,\n    low: 56.12,\n    close: 56.17,\n    volume: 34958,\n  },\n  {\n    date: 1461077160000,\n    open: 56.17,\n    high: 56.191,\n    low: 56.16,\n    close: 56.185,\n    volume: 17652,\n  },\n  {\n    date: 1461077220000,\n    open: 56.18,\n    high: 56.2,\n    low: 56.125,\n    close: 56.15,\n    volume: 52394,\n  },\n  {\n    date: 1461077280000,\n    open: 56.15,\n    high: 56.16,\n    low: 56.11,\n    close: 56.12,\n    volume: 26583,\n  },\n  {\n    date: 1461077340000,\n    open: 56.13,\n    high: 56.13,\n    low: 56.065,\n    close: 56.07,\n    volume: 43199,\n  },\n  {\n    date: 1461077400000,\n    open: 56.0679,\n    high: 56.11,\n    low: 56.06,\n    close: 56.1,\n    volume: 26603,\n  },\n  {\n    date: 1461077460000,\n    open: 56.1,\n    high: 56.15,\n    low: 56.1,\n    close: 56.1371,\n    volume: 24000,\n  },\n  {\n    date: 1461077520000,\n    open: 56.13,\n    high: 56.1715,\n    low: 56.12,\n    close: 56.17,\n    volume: 38509,\n  },\n  {\n    date: 1461077580000,\n    open: 56.17,\n    high: 56.205,\n    low: 56.1535,\n    close: 56.205,\n    volume: 42461,\n  },\n  {\n    date: 1461077640000,\n    open: 56.2,\n    high: 56.23,\n    low: 56.195,\n    close: 56.22,\n    volume: 31682,\n  },\n  {\n    date: 1461077700000,\n    open: 56.2268,\n    high: 56.28,\n    low: 56.22,\n    close: 56.26,\n    volume: 71777,\n  },\n  {\n    date: 1461077760000,\n    open: 56.2535,\n    high: 56.2599,\n    low: 56.22,\n    close: 56.22,\n    volume: 30540,\n  },\n  {\n    date: 1461077820000,\n    open: 56.23,\n    high: 56.27,\n    low: 56.23,\n    close: 56.25,\n    volume: 23039,\n  },\n  {\n    date: 1461077880000,\n    open: 56.24,\n    high: 56.25,\n    low: 56.2101,\n    close: 56.233,\n    volume: 22110,\n  },\n  {\n    date: 1461077940000,\n    open: 56.24,\n    high: 56.28,\n    low: 56.23,\n    close: 56.2601,\n    volume: 34637,\n  },\n  {\n    date: 1461078000000,\n    open: 56.27,\n    high: 56.27,\n    low: 56.2402,\n    close: 56.245,\n    volume: 32156,\n  },\n  {\n    date: 1461078060000,\n    open: 56.25,\n    high: 56.27,\n    low: 56.25,\n    close: 56.25,\n    volume: 18145,\n  },\n  {\n    date: 1461078120000,\n    open: 56.25,\n    high: 56.27,\n    low: 56.23,\n    close: 56.235,\n    volume: 93342,\n  },\n  {\n    date: 1461078180000,\n    open: 56.24,\n    high: 56.24,\n    low: 56.2,\n    close: 56.2299,\n    volume: 27343,\n  },\n  {\n    date: 1461078240000,\n    open: 56.22,\n    high: 56.24,\n    low: 56.2,\n    close: 56.22,\n    volume: 21624,\n  },\n  {\n    date: 1461078300000,\n    open: 56.205,\n    high: 56.25,\n    low: 56.205,\n    close: 56.2464,\n    volume: 23138,\n  },\n  {\n    date: 1461078360000,\n    open: 56.25,\n    high: 56.29,\n    low: 56.25,\n    close: 56.26,\n    volume: 53692,\n  },\n  {\n    date: 1461078420000,\n    open: 56.26,\n    high: 56.305,\n    low: 56.26,\n    close: 56.2701,\n    volume: 57113,\n  },\n  {\n    date: 1461078480000,\n    open: 56.27,\n    high: 56.3,\n    low: 56.27,\n    close: 56.2865,\n    volume: 19902,\n  },\n  {\n    date: 1461078540000,\n    open: 56.29,\n    high: 56.3,\n    low: 56.28,\n    close: 56.2899,\n    volume: 79030,\n  },\n  {\n    date: 1461078600000,\n    open: 56.29,\n    high: 56.2961,\n    low: 56.28,\n    close: 56.287,\n    volume: 33426,\n  },\n  {\n    date: 1461078660000,\n    open: 56.285,\n    high: 56.29,\n    low: 56.235,\n    close: 56.235,\n    volume: 33774,\n  },\n  {\n    date: 1461078720000,\n    open: 56.235,\n    high: 56.26,\n    low: 56.22,\n    close: 56.26,\n    volume: 10607,\n  },\n  {\n    date: 1461078780000,\n    open: 56.2564,\n    high: 56.265,\n    low: 56.25,\n    close: 56.26,\n    volume: 10914,\n  },\n  {\n    date: 1461078840000,\n    open: 56.26,\n    high: 56.27,\n    low: 56.21,\n    close: 56.24,\n    volume: 50079,\n  },\n  {\n    date: 1461078900000,\n    open: 56.24,\n    high: 56.27,\n    low: 56.23,\n    close: 56.24,\n    volume: 15627,\n  },\n  {\n    date: 1461078960000,\n    open: 56.24,\n    high: 56.25,\n    low: 56.23,\n    close: 56.24,\n    volume: 11742,\n  },\n  {\n    date: 1461079020000,\n    open: 56.2311,\n    high: 56.255,\n    low: 56.22,\n    close: 56.25,\n    volume: 27751,\n  },\n  {\n    date: 1461079080000,\n    open: 56.24,\n    high: 56.245,\n    low: 56.23,\n    close: 56.2336,\n    volume: 12566,\n  },\n  {\n    date: 1461079140000,\n    open: 56.24,\n    high: 56.26,\n    low: 56.225,\n    close: 56.24,\n    volume: 22404,\n  },\n  {\n    date: 1461079200000,\n    open: 56.235,\n    high: 56.28,\n    low: 56.225,\n    close: 56.28,\n    volume: 22490,\n  },\n  {\n    date: 1461079260000,\n    open: 56.27,\n    high: 56.29,\n    low: 56.26,\n    close: 56.2899,\n    volume: 26261,\n  },\n  {\n    date: 1461079320000,\n    open: 56.2899,\n    high: 56.31,\n    low: 56.28,\n    close: 56.31,\n    volume: 38820,\n  },\n  {\n    date: 1461079380000,\n    open: 56.305,\n    high: 56.3537,\n    low: 56.3,\n    close: 56.35,\n    volume: 39854,\n  },\n  {\n    date: 1461079440000,\n    open: 56.36,\n    high: 56.39,\n    low: 56.335,\n    close: 56.335,\n    volume: 31713,\n  },\n  {\n    date: 1461079500000,\n    open: 56.33,\n    high: 56.34,\n    low: 56.31,\n    close: 56.33,\n    volume: 48664,\n  },\n  {\n    date: 1461079560000,\n    open: 56.32,\n    high: 56.325,\n    low: 56.2906,\n    close: 56.297,\n    volume: 9892,\n  },\n  {\n    date: 1461079620000,\n    open: 56.29,\n    high: 56.33,\n    low: 56.28,\n    close: 56.2999,\n    volume: 101975,\n  },\n  {\n    date: 1461079680000,\n    open: 56.2901,\n    high: 56.305,\n    low: 56.275,\n    close: 56.3,\n    volume: 22214,\n  },\n  {\n    date: 1461079740000,\n    open: 56.291,\n    high: 56.295,\n    low: 56.28,\n    close: 56.29,\n    volume: 15549,\n  },\n  {\n    date: 1461079800000,\n    open: 56.2801,\n    high: 56.31,\n    low: 56.275,\n    close: 56.31,\n    volume: 50255,\n  },\n  {\n    date: 1461079860000,\n    open: 56.305,\n    high: 56.31,\n    low: 56.27,\n    close: 56.3,\n    volume: 26142,\n  },\n  {\n    date: 1461079920000,\n    open: 56.2964,\n    high: 56.3085,\n    low: 56.29,\n    close: 56.305,\n    volume: 19403,\n  },\n  {\n    date: 1461079980000,\n    open: 56.305,\n    high: 56.315,\n    low: 56.27,\n    close: 56.27,\n    volume: 59139,\n  },\n  {\n    date: 1461080040000,\n    open: 56.26,\n    high: 56.31,\n    low: 56.23,\n    close: 56.3001,\n    volume: 61708,\n  },\n  {\n    date: 1461080100000,\n    open: 56.305,\n    high: 56.33,\n    low: 56.295,\n    close: 56.325,\n    volume: 17785,\n  },\n  {\n    date: 1461080160000,\n    open: 56.32,\n    high: 56.328,\n    low: 56.3,\n    close: 56.3027,\n    volume: 14322,\n  },\n  {\n    date: 1461080220000,\n    open: 56.31,\n    high: 56.34,\n    low: 56.3,\n    close: 56.335,\n    volume: 47046,\n  },\n  {\n    date: 1461080280000,\n    open: 56.3364,\n    high: 56.35,\n    low: 56.3139,\n    close: 56.345,\n    volume: 44909,\n  },\n  {\n    date: 1461080340000,\n    open: 56.35,\n    high: 56.35,\n    low: 56.33,\n    close: 56.335,\n    volume: 29417,\n  },\n  {\n    date: 1461080400000,\n    open: 56.335,\n    high: 56.355,\n    low: 56.33,\n    close: 56.35,\n    volume: 40091,\n  },\n  {\n    date: 1461080460000,\n    open: 56.36,\n    high: 56.36,\n    low: 56.35,\n    close: 56.355,\n    volume: 10203,\n  },\n  {\n    date: 1461080520000,\n    open: 56.36,\n    high: 56.36,\n    low: 56.335,\n    close: 56.335,\n    volume: 32103,\n  },\n  {\n    date: 1461080580000,\n    open: 56.335,\n    high: 56.34,\n    low: 56.31,\n    close: 56.31,\n    volume: 31853,\n  },\n  {\n    date: 1461080640000,\n    open: 56.305,\n    high: 56.31,\n    low: 56.275,\n    close: 56.305,\n    volume: 26606,\n  },\n  {\n    date: 1461080700000,\n    open: 56.305,\n    high: 56.33,\n    low: 56.3,\n    close: 56.32,\n    volume: 18588,\n  },\n  {\n    date: 1461080760000,\n    open: 56.32,\n    high: 56.35,\n    low: 56.3,\n    close: 56.34,\n    volume: 49616,\n  },\n  {\n    date: 1461080820000,\n    open: 56.3433,\n    high: 56.349,\n    low: 56.32,\n    close: 56.3364,\n    volume: 17850,\n  },\n  {\n    date: 1461080880000,\n    open: 56.335,\n    high: 56.335,\n    low: 56.285,\n    close: 56.3,\n    volume: 36992,\n  },\n  {\n    date: 1461080940000,\n    open: 56.3,\n    high: 56.31,\n    low: 56.2,\n    close: 56.2,\n    volume: 58249,\n  },\n  {\n    date: 1461081000000,\n    open: 56.2,\n    high: 56.26,\n    low: 56.2,\n    close: 56.2408,\n    volume: 33883,\n  },\n  {\n    date: 1461081060000,\n    open: 56.2533,\n    high: 56.255,\n    low: 56.14,\n    close: 56.14,\n    volume: 74900,\n  },\n  {\n    date: 1461081120000,\n    open: 56.14,\n    high: 56.165,\n    low: 56.13,\n    close: 56.14,\n    volume: 81992,\n  },\n  {\n    date: 1461081180000,\n    open: 56.14,\n    high: 56.17,\n    low: 56.14,\n    close: 56.17,\n    volume: 33663,\n  },\n  {\n    date: 1461081240000,\n    open: 56.16,\n    high: 56.175,\n    low: 56.13,\n    close: 56.13,\n    volume: 24963,\n  },\n  {\n    date: 1461081300000,\n    open: 56.1201,\n    high: 56.15,\n    low: 56.12,\n    close: 56.1299,\n    volume: 34191,\n  },\n  {\n    date: 1461081360000,\n    open: 56.12,\n    high: 56.12,\n    low: 56.0699,\n    close: 56.0699,\n    volume: 57038,\n  },\n  {\n    date: 1461081420000,\n    open: 56.0664,\n    high: 56.08,\n    low: 56.025,\n    close: 56.035,\n    volume: 41291,\n  },\n  {\n    date: 1461081480000,\n    open: 56.03,\n    high: 56.04,\n    low: 56.01,\n    close: 56.025,\n    volume: 100108,\n  },\n  {\n    date: 1461081540000,\n    open: 56.025,\n    high: 56.07,\n    low: 56.02,\n    close: 56.07,\n    volume: 50197,\n  },\n  {\n    date: 1461081600000,\n    open: 56.06,\n    high: 56.07,\n    low: 56,\n    close: 56.015,\n    volume: 199940,\n  },\n  {\n    date: 1461081660000,\n    open: 56.01,\n    high: 56.04,\n    low: 56,\n    close: 56.035,\n    volume: 59176,\n  },\n  {\n    date: 1461081720000,\n    open: 56.04,\n    high: 56.075,\n    low: 56.04,\n    close: 56.07,\n    volume: 93953,\n  },\n  {\n    date: 1461081780000,\n    open: 56.07,\n    high: 56.07,\n    low: 56.04,\n    close: 56.045,\n    volume: 87128,\n  },\n  {\n    date: 1461081840000,\n    open: 56.045,\n    high: 56.08,\n    low: 56.035,\n    close: 56.065,\n    volume: 96007,\n  },\n  {\n    date: 1461081900000,\n    open: 56.075,\n    high: 56.095,\n    low: 56.05,\n    close: 56.0736,\n    volume: 79244,\n  },\n  {\n    date: 1461081960000,\n    open: 56.07,\n    high: 56.1,\n    low: 56.07,\n    close: 56.09,\n    volume: 23728,\n  },\n  {\n    date: 1461082020000,\n    open: 56.09,\n    high: 56.1,\n    low: 56.06,\n    close: 56.1,\n    volume: 56190,\n  },\n  {\n    date: 1461082080000,\n    open: 56.1044,\n    high: 56.12,\n    low: 56.08,\n    close: 56.12,\n    volume: 87187,\n  },\n  {\n    date: 1461082140000,\n    open: 56.115,\n    high: 56.1308,\n    low: 56.09,\n    close: 56.125,\n    volume: 33799,\n  },\n  {\n    date: 1461082200000,\n    open: 56.13,\n    high: 56.13,\n    low: 56.08,\n    close: 56.11,\n    volume: 26781,\n  },\n  {\n    date: 1461082260000,\n    open: 56.11,\n    high: 56.11,\n    low: 56.09,\n    close: 56.1,\n    volume: 21543,\n  },\n  {\n    date: 1461082320000,\n    open: 56.1,\n    high: 56.13,\n    low: 56.085,\n    close: 56.13,\n    volume: 55392,\n  },\n  {\n    date: 1461082380000,\n    open: 56.13,\n    high: 56.18,\n    low: 56.1224,\n    close: 56.1701,\n    volume: 28360,\n  },\n  {\n    date: 1461082440000,\n    open: 56.179,\n    high: 56.18,\n    low: 56.105,\n    close: 56.105,\n    volume: 30822,\n  },\n  {\n    date: 1461082500000,\n    open: 56.105,\n    high: 56.14,\n    low: 56.1,\n    close: 56.14,\n    volume: 25318,\n  },\n  {\n    date: 1461082560000,\n    open: 56.135,\n    high: 56.15,\n    low: 56.119,\n    close: 56.119,\n    volume: 21584,\n  },\n  {\n    date: 1461082620000,\n    open: 56.12,\n    high: 56.13,\n    low: 56.11,\n    close: 56.13,\n    volume: 17256,\n  },\n  {\n    date: 1461082680000,\n    open: 56.134,\n    high: 56.14,\n    low: 56.11,\n    close: 56.11,\n    volume: 20405,\n  },\n  {\n    date: 1461082740000,\n    open: 56.11,\n    high: 56.13,\n    low: 56.095,\n    close: 56.104,\n    volume: 28908,\n  },\n  {\n    date: 1461082800000,\n    open: 56.1,\n    high: 56.11,\n    low: 56.08,\n    close: 56.09,\n    volume: 76639,\n  },\n  {\n    date: 1461082860000,\n    open: 56.095,\n    high: 56.155,\n    low: 56.09,\n    close: 56.145,\n    volume: 41486,\n  },\n  {\n    date: 1461082920000,\n    open: 56.14,\n    high: 56.179,\n    low: 56.14,\n    close: 56.175,\n    volume: 81824,\n  },\n  {\n    date: 1461082980000,\n    open: 56.17,\n    high: 56.19,\n    low: 56.14,\n    close: 56.18,\n    volume: 92337,\n  },\n  {\n    date: 1461083040000,\n    open: 56.1864,\n    high: 56.24,\n    low: 56.18,\n    close: 56.235,\n    volume: 103278,\n  },\n  {\n    date: 1461083100000,\n    open: 56.23,\n    high: 56.23,\n    low: 56.15,\n    close: 56.1511,\n    volume: 20864,\n  },\n  {\n    date: 1461083160000,\n    open: 56.155,\n    high: 56.16,\n    low: 56.125,\n    close: 56.15,\n    volume: 12976,\n  },\n  {\n    date: 1461083220000,\n    open: 56.15,\n    high: 56.16,\n    low: 56.14,\n    close: 56.15,\n    volume: 23121,\n  },\n  {\n    date: 1461083280000,\n    open: 56.15,\n    high: 56.16,\n    low: 56.13,\n    close: 56.15,\n    volume: 13754,\n  },\n  {\n    date: 1461083340000,\n    open: 56.16,\n    high: 56.19,\n    low: 56.16,\n    close: 56.185,\n    volume: 17103,\n  },\n  {\n    date: 1461083400000,\n    open: 56.1839,\n    high: 56.215,\n    low: 56.14,\n    close: 56.15,\n    volume: 30489,\n  },\n  {\n    date: 1461083460000,\n    open: 56.15,\n    high: 56.165,\n    low: 56.13,\n    close: 56.16,\n    volume: 21546,\n  },\n  {\n    date: 1461083520000,\n    open: 56.17,\n    high: 56.17,\n    low: 56.125,\n    close: 56.166,\n    volume: 47993,\n  },\n  {\n    date: 1461083580000,\n    open: 56.16,\n    high: 56.18,\n    low: 56.15,\n    close: 56.1798,\n    volume: 19968,\n  },\n  {\n    date: 1461083640000,\n    open: 56.175,\n    high: 56.18,\n    low: 56.155,\n    close: 56.155,\n    volume: 18369,\n  },\n  {\n    date: 1461083700000,\n    open: 56.15,\n    high: 56.1501,\n    low: 56.12,\n    close: 56.14,\n    volume: 18375,\n  },\n  {\n    date: 1461083760000,\n    open: 56.13,\n    high: 56.17,\n    low: 56.129,\n    close: 56.17,\n    volume: 15842,\n  },\n  {\n    date: 1461083820000,\n    open: 56.165,\n    high: 56.1662,\n    low: 56.145,\n    close: 56.16,\n    volume: 13039,\n  },\n  {\n    date: 1461083880000,\n    open: 56.155,\n    high: 56.175,\n    low: 56.141,\n    close: 56.17,\n    volume: 23775,\n  },\n  {\n    date: 1461083940000,\n    open: 56.17,\n    high: 56.175,\n    low: 56.145,\n    close: 56.15,\n    volume: 54249,\n  },\n  {\n    date: 1461084000000,\n    open: 56.15,\n    high: 56.175,\n    low: 56.14,\n    close: 56.159,\n    volume: 20254,\n  },\n  {\n    date: 1461084060000,\n    open: 56.16,\n    high: 56.16,\n    low: 56.14,\n    close: 56.14,\n    volume: 16019,\n  },\n  {\n    date: 1461084120000,\n    open: 56.15,\n    high: 56.16,\n    low: 56.125,\n    close: 56.155,\n    volume: 23063,\n  },\n  {\n    date: 1461084180000,\n    open: 56.15,\n    high: 56.16,\n    low: 56.1433,\n    close: 56.15,\n    volume: 12063,\n  },\n  {\n    date: 1461084240000,\n    open: 56.15,\n    high: 56.15,\n    low: 56.12,\n    close: 56.12,\n    volume: 26335,\n  },\n  {\n    date: 1461084300000,\n    open: 56.125,\n    high: 56.155,\n    low: 56.1202,\n    close: 56.141,\n    volume: 13889,\n  },\n  {\n    date: 1461084360000,\n    open: 56.1435,\n    high: 56.155,\n    low: 56.12,\n    close: 56.12,\n    volume: 43557,\n  },\n  {\n    date: 1461084420000,\n    open: 56.125,\n    high: 56.14,\n    low: 56.09,\n    close: 56.09,\n    volume: 42310,\n  },\n  {\n    date: 1461084480000,\n    open: 56.08,\n    high: 56.085,\n    low: 56.045,\n    close: 56.0799,\n    volume: 36521,\n  },\n  {\n    date: 1461084540000,\n    open: 56.08,\n    high: 56.085,\n    low: 56.04,\n    close: 56.069,\n    volume: 28268,\n  },\n  {\n    date: 1461084600000,\n    open: 56.0663,\n    high: 56.09,\n    low: 56.06,\n    close: 56.081,\n    volume: 28336,\n  },\n  {\n    date: 1461084660000,\n    open: 56.08,\n    high: 56.08,\n    low: 56.06,\n    close: 56.07,\n    volume: 19643,\n  },\n  {\n    date: 1461084720000,\n    open: 56.07,\n    high: 56.1,\n    low: 56.07,\n    close: 56.0937,\n    volume: 12659,\n  },\n  {\n    date: 1461084780000,\n    open: 56.09,\n    high: 56.155,\n    low: 56.09,\n    close: 56.155,\n    volume: 37393,\n  },\n  {\n    date: 1461084840000,\n    open: 56.155,\n    high: 56.27,\n    low: 56.155,\n    close: 56.27,\n    volume: 70634,\n  },\n  {\n    date: 1461084900000,\n    open: 56.26,\n    high: 56.27,\n    low: 56.23,\n    close: 56.235,\n    volume: 51220,\n  },\n  {\n    date: 1461084960000,\n    open: 56.23,\n    high: 56.24,\n    low: 56.19,\n    close: 56.1999,\n    volume: 13025,\n  },\n  {\n    date: 1461085020000,\n    open: 56.194,\n    high: 56.23,\n    low: 56.185,\n    close: 56.22,\n    volume: 40834,\n  },\n  {\n    date: 1461085080000,\n    open: 56.2234,\n    high: 56.23,\n    low: 56.22,\n    close: 56.228,\n    volume: 8116,\n  },\n  {\n    date: 1461085140000,\n    open: 56.2242,\n    high: 56.24,\n    low: 56.22,\n    close: 56.235,\n    volume: 34299,\n  },\n  {\n    date: 1461085200000,\n    open: 56.23,\n    high: 56.2495,\n    low: 56.22,\n    close: 56.2495,\n    volume: 41459,\n  },\n  {\n    date: 1461085260000,\n    open: 56.25,\n    high: 56.27,\n    low: 56.24,\n    close: 56.26,\n    volume: 24183,\n  },\n  {\n    date: 1461085320000,\n    open: 56.265,\n    high: 56.305,\n    low: 56.2601,\n    close: 56.305,\n    volume: 47201,\n  },\n  {\n    date: 1461085380000,\n    open: 56.305,\n    high: 56.3199,\n    low: 56.275,\n    close: 56.2925,\n    volume: 64281,\n  },\n  {\n    date: 1461085440000,\n    open: 56.2861,\n    high: 56.2999,\n    low: 56.2861,\n    close: 56.295,\n    volume: 35604,\n  },\n  {\n    date: 1461085500000,\n    open: 56.295,\n    high: 56.3,\n    low: 56.225,\n    close: 56.225,\n    volume: 71788,\n  },\n  {\n    date: 1461085560000,\n    open: 56.23,\n    high: 56.26,\n    low: 56.2201,\n    close: 56.26,\n    volume: 44990,\n  },\n  {\n    date: 1461085620000,\n    open: 56.26,\n    high: 56.28,\n    low: 56.25,\n    close: 56.28,\n    volume: 42736,\n  },\n  {\n    date: 1461085680000,\n    open: 56.28,\n    high: 56.3,\n    low: 56.26,\n    close: 56.26,\n    volume: 59091,\n  },\n  {\n    date: 1461085740000,\n    open: 56.2601,\n    high: 56.29,\n    low: 56.2601,\n    close: 56.275,\n    volume: 12210,\n  },\n  {\n    date: 1461085800000,\n    open: 56.27,\n    high: 56.28,\n    low: 56.22,\n    close: 56.22,\n    volume: 38440,\n  },\n  {\n    date: 1461085860000,\n    open: 56.225,\n    high: 56.24,\n    low: 56.215,\n    close: 56.2243,\n    volume: 18251,\n  },\n  {\n    date: 1461085920000,\n    open: 56.2236,\n    high: 56.245,\n    low: 56.2164,\n    close: 56.24,\n    volume: 9455,\n  },\n  {\n    date: 1461085980000,\n    open: 56.24,\n    high: 56.265,\n    low: 56.23,\n    close: 56.265,\n    volume: 16214,\n  },\n  {\n    date: 1461086040000,\n    open: 56.26,\n    high: 56.28,\n    low: 56.26,\n    close: 56.26,\n    volume: 14000,\n  },\n  {\n    date: 1461086100000,\n    open: 56.27,\n    high: 56.29,\n    low: 56.265,\n    close: 56.2772,\n    volume: 17437,\n  },\n  {\n    date: 1461086160000,\n    open: 56.2736,\n    high: 56.3,\n    low: 56.27,\n    close: 56.285,\n    volume: 41959,\n  },\n  {\n    date: 1461086220000,\n    open: 56.28,\n    high: 56.3,\n    low: 56.27,\n    close: 56.28,\n    volume: 21677,\n  },\n  {\n    date: 1461086280000,\n    open: 56.27,\n    high: 56.28,\n    low: 56.265,\n    close: 56.27,\n    volume: 16787,\n  },\n  {\n    date: 1461086340000,\n    open: 56.27,\n    high: 56.275,\n    low: 56.22,\n    close: 56.22,\n    volume: 28091,\n  },\n  {\n    date: 1461086400000,\n    open: 56.22,\n    high: 56.225,\n    low: 56.2,\n    close: 56.204,\n    volume: 16186,\n  },\n  {\n    date: 1461086460000,\n    open: 56.2014,\n    high: 56.23,\n    low: 56.2,\n    close: 56.23,\n    volume: 12703,\n  },\n  {\n    date: 1461086520000,\n    open: 56.23,\n    high: 56.235,\n    low: 56.215,\n    close: 56.23,\n    volume: 6491,\n  },\n  {\n    date: 1461086580000,\n    open: 56.24,\n    high: 56.29,\n    low: 56.22,\n    close: 56.27,\n    volume: 66115,\n  },\n  {\n    date: 1461086640000,\n    open: 56.27,\n    high: 56.3,\n    low: 56.27,\n    close: 56.295,\n    volume: 43543,\n  },\n  {\n    date: 1461086700000,\n    open: 56.2999,\n    high: 56.3,\n    low: 56.28,\n    close: 56.295,\n    volume: 13823,\n  },\n  {\n    date: 1461086760000,\n    open: 56.29,\n    high: 56.315,\n    low: 56.29,\n    close: 56.305,\n    volume: 38911,\n  },\n  {\n    date: 1461086820000,\n    open: 56.305,\n    high: 56.33,\n    low: 56.3,\n    close: 56.33,\n    volume: 19475,\n  },\n  {\n    date: 1461086880000,\n    open: 56.33,\n    high: 56.33,\n    low: 56.31,\n    close: 56.3199,\n    volume: 14462,\n  },\n  {\n    date: 1461086940000,\n    open: 56.315,\n    high: 56.32,\n    low: 56.31,\n    close: 56.31,\n    volume: 9284,\n  },\n  {\n    date: 1461087000000,\n    open: 56.311,\n    high: 56.3199,\n    low: 56.245,\n    close: 56.255,\n    volume: 43148,\n  },\n  {\n    date: 1461087060000,\n    open: 56.25,\n    high: 56.28,\n    low: 56.25,\n    close: 56.275,\n    volume: 25026,\n  },\n  {\n    date: 1461087120000,\n    open: 56.27,\n    high: 56.2745,\n    low: 56.2,\n    close: 56.215,\n    volume: 57830,\n  },\n  {\n    date: 1461087180000,\n    open: 56.215,\n    high: 56.24,\n    low: 56.2,\n    close: 56.24,\n    volume: 26066,\n  },\n  {\n    date: 1461087240000,\n    open: 56.231,\n    high: 56.265,\n    low: 56.231,\n    close: 56.265,\n    volume: 29011,\n  },\n  {\n    date: 1461087300000,\n    open: 56.265,\n    high: 56.275,\n    low: 56.23,\n    close: 56.23,\n    volume: 38810,\n  },\n  {\n    date: 1461087360000,\n    open: 56.2236,\n    high: 56.24,\n    low: 56.215,\n    close: 56.235,\n    volume: 13807,\n  },\n  {\n    date: 1461087420000,\n    open: 56.2301,\n    high: 56.24,\n    low: 56.215,\n    close: 56.22,\n    volume: 17529,\n  },\n  {\n    date: 1461087480000,\n    open: 56.224,\n    high: 56.255,\n    low: 56.22,\n    close: 56.245,\n    volume: 23219,\n  },\n  {\n    date: 1461087540000,\n    open: 56.245,\n    high: 56.25,\n    low: 56.2336,\n    close: 56.25,\n    volume: 13515,\n  },\n  {\n    date: 1461087600000,\n    open: 56.25,\n    high: 56.26,\n    low: 56.24,\n    close: 56.25,\n    volume: 17627,\n  },\n  {\n    date: 1461087660000,\n    open: 56.245,\n    high: 56.245,\n    low: 56.234,\n    close: 56.245,\n    volume: 8223,\n  },\n  {\n    date: 1461087720000,\n    open: 56.25,\n    high: 56.25,\n    low: 56.205,\n    close: 56.23,\n    volume: 30382,\n  },\n  {\n    date: 1461087780000,\n    open: 56.22,\n    high: 56.24,\n    low: 56.215,\n    close: 56.235,\n    volume: 16923,\n  },\n  {\n    date: 1461087840000,\n    open: 56.24,\n    high: 56.26,\n    low: 56.23,\n    close: 56.245,\n    volume: 60839,\n  },\n  {\n    date: 1461087900000,\n    open: 56.245,\n    high: 56.245,\n    low: 56.22,\n    close: 56.22,\n    volume: 23454,\n  },\n  {\n    date: 1461087960000,\n    open: 56.225,\n    high: 56.25,\n    low: 56.225,\n    close: 56.25,\n    volume: 11970,\n  },\n  {\n    date: 1461088020000,\n    open: 56.245,\n    high: 56.285,\n    low: 56.244,\n    close: 56.275,\n    volume: 29641,\n  },\n  {\n    date: 1461088080000,\n    open: 56.2769,\n    high: 56.29,\n    low: 56.262,\n    close: 56.29,\n    volume: 21201,\n  },\n  {\n    date: 1461088140000,\n    open: 56.29,\n    high: 56.325,\n    low: 56.28,\n    close: 56.32,\n    volume: 41334,\n  },\n  {\n    date: 1461088200000,\n    open: 56.32,\n    high: 56.347,\n    low: 56.31,\n    close: 56.345,\n    volume: 19347,\n  },\n  {\n    date: 1461088260000,\n    open: 56.3442,\n    high: 56.369,\n    low: 56.335,\n    close: 56.34,\n    volume: 72441,\n  },\n  {\n    date: 1461088320000,\n    open: 56.34,\n    high: 56.35,\n    low: 56.32,\n    close: 56.34,\n    volume: 31699,\n  },\n  {\n    date: 1461088380000,\n    open: 56.335,\n    high: 56.345,\n    low: 56.32,\n    close: 56.34,\n    volume: 19714,\n  },\n  {\n    date: 1461088440000,\n    open: 56.34,\n    high: 56.34,\n    low: 56.32,\n    close: 56.33,\n    volume: 10540,\n  },\n  {\n    date: 1461088500000,\n    open: 56.335,\n    high: 56.35,\n    low: 56.335,\n    close: 56.34,\n    volume: 12148,\n  },\n  {\n    date: 1461088560000,\n    open: 56.345,\n    high: 56.36,\n    low: 56.34,\n    close: 56.355,\n    volume: 70775,\n  },\n  {\n    date: 1461088620000,\n    open: 56.36,\n    high: 56.37,\n    low: 56.35,\n    close: 56.35,\n    volume: 21969,\n  },\n  {\n    date: 1461088680000,\n    open: 56.36,\n    high: 56.37,\n    low: 56.35,\n    close: 56.355,\n    volume: 15666,\n  },\n  {\n    date: 1461088740000,\n    open: 56.35,\n    high: 56.375,\n    low: 56.34,\n    close: 56.36,\n    volume: 14111,\n  },\n  {\n    date: 1461088800000,\n    open: 56.36,\n    high: 56.385,\n    low: 56.355,\n    close: 56.385,\n    volume: 15450,\n  },\n  {\n    date: 1461088860000,\n    open: 56.385,\n    high: 56.39,\n    low: 56.38,\n    close: 56.39,\n    volume: 7637,\n  },\n  {\n    date: 1461088920000,\n    open: 56.39,\n    high: 56.45,\n    low: 56.385,\n    close: 56.44,\n    volume: 62070,\n  },\n  {\n    date: 1461088980000,\n    open: 56.45,\n    high: 56.45,\n    low: 56.43,\n    close: 56.445,\n    volume: 24560,\n  },\n  {\n    date: 1461089040000,\n    open: 56.44,\n    high: 56.445,\n    low: 56.43,\n    close: 56.44,\n    volume: 13423,\n  },\n  {\n    date: 1461089100000,\n    open: 56.4399,\n    high: 56.4399,\n    low: 56.375,\n    close: 56.378,\n    volume: 31867,\n  },\n  {\n    date: 1461089160000,\n    open: 56.371,\n    high: 56.39,\n    low: 56.36,\n    close: 56.385,\n    volume: 18129,\n  },\n  {\n    date: 1461089220000,\n    open: 56.385,\n    high: 56.41,\n    low: 56.365,\n    close: 56.385,\n    volume: 29720,\n  },\n  {\n    date: 1461089280000,\n    open: 56.3899,\n    high: 56.4138,\n    low: 56.385,\n    close: 56.3868,\n    volume: 18994,\n  },\n  {\n    date: 1461089340000,\n    open: 56.385,\n    high: 56.3999,\n    low: 56.38,\n    close: 56.39,\n    volume: 26702,\n  },\n  {\n    date: 1461089400000,\n    open: 56.3876,\n    high: 56.43,\n    low: 56.3802,\n    close: 56.43,\n    volume: 30352,\n  },\n  {\n    date: 1461089460000,\n    open: 56.425,\n    high: 56.455,\n    low: 56.41,\n    close: 56.449,\n    volume: 97635,\n  },\n  {\n    date: 1461089520000,\n    open: 56.44,\n    high: 56.465,\n    low: 56.42,\n    close: 56.465,\n    volume: 42565,\n  },\n  {\n    date: 1461089580000,\n    open: 56.47,\n    high: 56.48,\n    low: 56.46,\n    close: 56.47,\n    volume: 22546,\n  },\n  {\n    date: 1461089640000,\n    open: 56.46,\n    high: 56.485,\n    low: 56.45,\n    close: 56.475,\n    volume: 62430,\n  },\n  {\n    date: 1461089700000,\n    open: 56.48,\n    high: 56.5,\n    low: 56.46,\n    close: 56.49,\n    volume: 37597,\n  },\n  {\n    date: 1461089760000,\n    open: 56.49,\n    high: 56.5,\n    low: 56.46,\n    close: 56.4664,\n    volume: 33442,\n  },\n  {\n    date: 1461089820000,\n    open: 56.46,\n    high: 56.475,\n    low: 56.4589,\n    close: 56.47,\n    volume: 19356,\n  },\n  {\n    date: 1461089880000,\n    open: 56.47,\n    high: 56.474,\n    low: 56.46,\n    close: 56.465,\n    volume: 15280,\n  },\n  {\n    date: 1461089940000,\n    open: 56.47,\n    high: 56.485,\n    low: 56.465,\n    close: 56.475,\n    volume: 35283,\n  },\n  {\n    date: 1461090000000,\n    open: 56.475,\n    high: 56.48,\n    low: 56.4401,\n    close: 56.46,\n    volume: 37573,\n  },\n  {\n    date: 1461090060000,\n    open: 56.455,\n    high: 56.48,\n    low: 56.45,\n    close: 56.475,\n    volume: 20199,\n  },\n  {\n    date: 1461090120000,\n    open: 56.475,\n    high: 56.4863,\n    low: 56.47,\n    close: 56.48,\n    volume: 82363,\n  },\n  {\n    date: 1461090180000,\n    open: 56.48,\n    high: 56.48,\n    low: 56.43,\n    close: 56.46,\n    volume: 35970,\n  },\n  {\n    date: 1461090240000,\n    open: 56.465,\n    high: 56.465,\n    low: 56.43,\n    close: 56.445,\n    volume: 12169,\n  },\n  {\n    date: 1461090300000,\n    open: 56.4498,\n    high: 56.4498,\n    low: 56.41,\n    close: 56.41,\n    volume: 25139,\n  },\n  {\n    date: 1461090360000,\n    open: 56.415,\n    high: 56.415,\n    low: 56.37,\n    close: 56.375,\n    volume: 26176,\n  },\n  {\n    date: 1461090420000,\n    open: 56.3789,\n    high: 56.405,\n    low: 56.37,\n    close: 56.395,\n    volume: 41487,\n  },\n  {\n    date: 1461090480000,\n    open: 56.4,\n    high: 56.415,\n    low: 56.39,\n    close: 56.405,\n    volume: 27720,\n  },\n  {\n    date: 1461090540000,\n    open: 56.407,\n    high: 56.43,\n    low: 56.38,\n    close: 56.385,\n    volume: 30626,\n  },\n  {\n    date: 1461090600000,\n    open: 56.385,\n    high: 56.39,\n    low: 56.36,\n    close: 56.365,\n    volume: 24746,\n  },\n  {\n    date: 1461090660000,\n    open: 56.365,\n    high: 56.375,\n    low: 56.36,\n    close: 56.365,\n    volume: 19517,\n  },\n  {\n    date: 1461090720000,\n    open: 56.37,\n    high: 56.375,\n    low: 56.354,\n    close: 56.354,\n    volume: 34761,\n  },\n  {\n    date: 1461090780000,\n    open: 56.36,\n    high: 56.37,\n    low: 56.335,\n    close: 56.335,\n    volume: 28470,\n  },\n  {\n    date: 1461090840000,\n    open: 56.33,\n    high: 56.34,\n    low: 56.33,\n    close: 56.3301,\n    volume: 5284,\n  },\n  {\n    date: 1461090900000,\n    open: 56.33,\n    high: 56.35,\n    low: 56.315,\n    close: 56.32,\n    volume: 43401,\n  },\n  {\n    date: 1461090960000,\n    open: 56.32,\n    high: 56.33,\n    low: 56.29,\n    close: 56.3,\n    volume: 23033,\n  },\n  {\n    date: 1461091020000,\n    open: 56.3,\n    high: 56.31,\n    low: 56.29,\n    close: 56.305,\n    volume: 14443,\n  },\n  {\n    date: 1461091080000,\n    open: 56.309,\n    high: 56.32,\n    low: 56.305,\n    close: 56.315,\n    volume: 9805,\n  },\n  {\n    date: 1461091140000,\n    open: 56.314,\n    high: 56.34,\n    low: 56.31,\n    close: 56.315,\n    volume: 23875,\n  },\n  {\n    date: 1461091200000,\n    open: 56.32,\n    high: 56.34,\n    low: 56.315,\n    close: 56.3301,\n    volume: 13627,\n  },\n  {\n    date: 1461091260000,\n    open: 56.335,\n    high: 56.34,\n    low: 56.325,\n    close: 56.3399,\n    volume: 107429,\n  },\n  {\n    date: 1461091320000,\n    open: 56.335,\n    high: 56.36,\n    low: 56.31,\n    close: 56.36,\n    volume: 42530,\n  },\n  {\n    date: 1461091380000,\n    open: 56.35,\n    high: 56.36,\n    low: 56.35,\n    close: 56.355,\n    volume: 147848,\n  },\n  {\n    date: 1461091440000,\n    open: 56.3563,\n    high: 56.395,\n    low: 56.35,\n    close: 56.38,\n    volume: 76633,\n  },\n  {\n    date: 1461091500000,\n    open: 56.375,\n    high: 56.41,\n    low: 56.37,\n    close: 56.4076,\n    volume: 53615,\n  },\n  {\n    date: 1461091560000,\n    open: 56.4093,\n    high: 56.43,\n    low: 56.4093,\n    close: 56.427,\n    volume: 26731,\n  },\n  {\n    date: 1461091620000,\n    open: 56.42,\n    high: 56.45,\n    low: 56.42,\n    close: 56.435,\n    volume: 41743,\n  },\n  {\n    date: 1461091680000,\n    open: 56.43,\n    high: 56.4399,\n    low: 56.42,\n    close: 56.43,\n    volume: 23142,\n  },\n  {\n    date: 1461091740000,\n    open: 56.43,\n    high: 56.43,\n    low: 56.42,\n    close: 56.42,\n    volume: 9974,\n  },\n  {\n    date: 1461091800000,\n    open: 56.42,\n    high: 56.465,\n    low: 56.415,\n    close: 56.45,\n    volume: 41484,\n  },\n  {\n    date: 1461091860000,\n    open: 56.45,\n    high: 56.46,\n    low: 56.44,\n    close: 56.447,\n    volume: 16999,\n  },\n  {\n    date: 1461091920000,\n    open: 56.45,\n    high: 56.46,\n    low: 56.395,\n    close: 56.41,\n    volume: 50819,\n  },\n  {\n    date: 1461091980000,\n    open: 56.4036,\n    high: 56.41,\n    low: 56.38,\n    close: 56.385,\n    volume: 33530,\n  },\n  {\n    date: 1461092040000,\n    open: 56.39,\n    high: 56.4,\n    low: 56.38,\n    close: 56.39,\n    volume: 8880,\n  },\n  {\n    date: 1461092100000,\n    open: 56.395,\n    high: 56.42,\n    low: 56.37,\n    close: 56.4069,\n    volume: 49538,\n  },\n  {\n    date: 1461092160000,\n    open: 56.4001,\n    high: 56.405,\n    low: 56.38,\n    close: 56.385,\n    volume: 15769,\n  },\n  {\n    date: 1461092220000,\n    open: 56.395,\n    high: 56.405,\n    low: 56.3842,\n    close: 56.405,\n    volume: 11003,\n  },\n  {\n    date: 1461092280000,\n    open: 56.4036,\n    high: 56.42,\n    low: 56.39,\n    close: 56.415,\n    volume: 22181,\n  },\n  {\n    date: 1461092340000,\n    open: 56.42,\n    high: 56.43,\n    low: 56.385,\n    close: 56.395,\n    volume: 66343,\n  },\n  {\n    date: 1461092400000,\n    open: 56.395,\n    high: 56.3954,\n    low: 56.335,\n    close: 56.34,\n    volume: 45550,\n  },\n  {\n    date: 1461092460000,\n    open: 56.33,\n    high: 56.33,\n    low: 56.26,\n    close: 56.26,\n    volume: 50805,\n  },\n  {\n    date: 1461092520000,\n    open: 56.255,\n    high: 56.2563,\n    low: 56.23,\n    close: 56.232,\n    volume: 47319,\n  },\n  {\n    date: 1461092580000,\n    open: 56.24,\n    high: 56.24,\n    low: 56.21,\n    close: 56.24,\n    volume: 26625,\n  },\n  {\n    date: 1461092640000,\n    open: 56.23,\n    high: 56.24,\n    low: 56.205,\n    close: 56.23,\n    volume: 22626,\n  },\n  {\n    date: 1461092700000,\n    open: 56.235,\n    high: 56.25,\n    low: 56.23,\n    close: 56.23,\n    volume: 25679,\n  },\n  {\n    date: 1461092760000,\n    open: 56.23,\n    high: 56.26,\n    low: 56.225,\n    close: 56.2599,\n    volume: 31865,\n  },\n  {\n    date: 1461092820000,\n    open: 56.26,\n    high: 56.31,\n    low: 56.251,\n    close: 56.305,\n    volume: 29486,\n  },\n  {\n    date: 1461092880000,\n    open: 56.3,\n    high: 56.335,\n    low: 56.29,\n    close: 56.29,\n    volume: 55771,\n  },\n  {\n    date: 1461092940000,\n    open: 56.2971,\n    high: 56.3,\n    low: 56.29,\n    close: 56.295,\n    volume: 10413,\n  },\n  {\n    date: 1461093000000,\n    open: 56.294,\n    high: 56.3,\n    low: 56.265,\n    close: 56.275,\n    volume: 32873,\n  },\n  {\n    date: 1461093060000,\n    open: 56.275,\n    high: 56.315,\n    low: 56.27,\n    close: 56.3,\n    volume: 28223,\n  },\n  {\n    date: 1461093120000,\n    open: 56.31,\n    high: 56.34,\n    low: 56.31,\n    close: 56.325,\n    volume: 22417,\n  },\n  {\n    date: 1461093180000,\n    open: 56.325,\n    high: 56.34,\n    low: 56.3,\n    close: 56.335,\n    volume: 32896,\n  },\n  {\n    date: 1461093240000,\n    open: 56.335,\n    high: 56.385,\n    low: 56.335,\n    close: 56.34,\n    volume: 131612,\n  },\n  {\n    date: 1461093300000,\n    open: 56.345,\n    high: 56.37,\n    low: 56.34,\n    close: 56.365,\n    volume: 48475,\n  },\n  {\n    date: 1461093360000,\n    open: 56.3628,\n    high: 56.38,\n    low: 56.3401,\n    close: 56.3401,\n    volume: 62203,\n  },\n  {\n    date: 1461093420000,\n    open: 56.348,\n    high: 56.348,\n    low: 56.31,\n    close: 56.31,\n    volume: 35354,\n  },\n  {\n    date: 1461093480000,\n    open: 56.31,\n    high: 56.34,\n    low: 56.29,\n    close: 56.325,\n    volume: 32237,\n  },\n  {\n    date: 1461093540000,\n    open: 56.325,\n    high: 56.35,\n    low: 56.32,\n    close: 56.325,\n    volume: 29937,\n  },\n  {\n    date: 1461093600000,\n    open: 56.325,\n    high: 56.35,\n    low: 56.3005,\n    close: 56.3005,\n    volume: 31461,\n  },\n  {\n    date: 1461093660000,\n    open: 56.31,\n    high: 56.32,\n    low: 56.31,\n    close: 56.32,\n    volume: 13290,\n  },\n  {\n    date: 1461093720000,\n    open: 56.315,\n    high: 56.34,\n    low: 56.3137,\n    close: 56.32,\n    volume: 27676,\n  },\n  {\n    date: 1461093780000,\n    open: 56.33,\n    high: 56.349,\n    low: 56.32,\n    close: 56.345,\n    volume: 18457,\n  },\n  {\n    date: 1461093840000,\n    open: 56.34,\n    high: 56.37,\n    low: 56.34,\n    close: 56.355,\n    volume: 57576,\n  },\n  {\n    date: 1461093900000,\n    open: 56.355,\n    high: 56.37,\n    low: 56.35,\n    close: 56.37,\n    volume: 35298,\n  },\n  {\n    date: 1461093960000,\n    open: 56.37,\n    high: 56.375,\n    low: 56.35,\n    close: 56.357,\n    volume: 60910,\n  },\n  {\n    date: 1461094020000,\n    open: 56.355,\n    high: 56.36,\n    low: 56.34,\n    close: 56.36,\n    volume: 70413,\n  },\n  {\n    date: 1461094080000,\n    open: 56.355,\n    high: 56.36,\n    low: 56.35,\n    close: 56.355,\n    volume: 53999,\n  },\n  {\n    date: 1461094140000,\n    open: 56.3501,\n    high: 56.355,\n    low: 56.3001,\n    close: 56.32,\n    volume: 53107,\n  },\n  {\n    date: 1461094200000,\n    open: 56.3105,\n    high: 56.3525,\n    low: 56.3105,\n    close: 56.35,\n    volume: 40812,\n  },\n  {\n    date: 1461094260000,\n    open: 56.355,\n    high: 56.39,\n    low: 56.34,\n    close: 56.38,\n    volume: 60023,\n  },\n  {\n    date: 1461094320000,\n    open: 56.375,\n    high: 56.395,\n    low: 56.37,\n    close: 56.3801,\n    volume: 51103,\n  },\n  {\n    date: 1461094380000,\n    open: 56.385,\n    high: 56.4,\n    low: 56.35,\n    close: 56.36,\n    volume: 57250,\n  },\n  {\n    date: 1461094440000,\n    open: 56.36,\n    high: 56.37,\n    low: 56.335,\n    close: 56.345,\n    volume: 53152,\n  },\n  {\n    date: 1461094500000,\n    open: 56.35,\n    high: 56.37,\n    low: 56.345,\n    close: 56.3501,\n    volume: 76961,\n  },\n  {\n    date: 1461094560000,\n    open: 56.3599,\n    high: 56.365,\n    low: 56.33,\n    close: 56.33,\n    volume: 50236,\n  },\n  {\n    date: 1461094620000,\n    open: 56.34,\n    high: 56.345,\n    low: 56.31,\n    close: 56.345,\n    volume: 63159,\n  },\n  {\n    date: 1461094680000,\n    open: 56.345,\n    high: 56.35,\n    low: 56.33,\n    close: 56.335,\n    volume: 19892,\n  },\n  {\n    date: 1461094740000,\n    open: 56.335,\n    high: 56.355,\n    low: 56.33,\n    close: 56.3405,\n    volume: 36559,\n  },\n  {\n    date: 1461094800000,\n    open: 56.345,\n    high: 56.37,\n    low: 56.34,\n    close: 56.35,\n    volume: 79019,\n  },\n  {\n    date: 1461094860000,\n    open: 56.3599,\n    high: 56.3599,\n    low: 56.34,\n    close: 56.345,\n    volume: 35476,\n  },\n  {\n    date: 1461094920000,\n    open: 56.34,\n    high: 56.37,\n    low: 56.34,\n    close: 56.37,\n    volume: 25167,\n  },\n  {\n    date: 1461094980000,\n    open: 56.37,\n    high: 56.37,\n    low: 56.36,\n    close: 56.36,\n    volume: 27646,\n  },\n  {\n    date: 1461095040000,\n    open: 56.37,\n    high: 56.37,\n    low: 56.35,\n    close: 56.3515,\n    volume: 100462,\n  },\n  {\n    date: 1461095100000,\n    open: 56.35,\n    high: 56.36,\n    low: 56.29,\n    close: 56.325,\n    volume: 84963,\n  },\n  {\n    date: 1461095160000,\n    open: 56.32,\n    high: 56.33,\n    low: 56.28,\n    close: 56.2801,\n    volume: 54374,\n  },\n  {\n    date: 1461095220000,\n    open: 56.28,\n    high: 56.29,\n    low: 56.25,\n    close: 56.28,\n    volume: 64594,\n  },\n  {\n    date: 1461095280000,\n    open: 56.28,\n    high: 56.29,\n    low: 56.27,\n    close: 56.28,\n    volume: 38588,\n  },\n  {\n    date: 1461095340000,\n    open: 56.28,\n    high: 56.3,\n    low: 56.2699,\n    close: 56.295,\n    volume: 43876,\n  },\n  {\n    date: 1461095400000,\n    open: 56.3,\n    high: 56.32,\n    low: 56.295,\n    close: 56.315,\n    volume: 48822,\n  },\n  {\n    date: 1461095460000,\n    open: 56.315,\n    high: 56.34,\n    low: 56.3125,\n    close: 56.335,\n    volume: 77608,\n  },\n  {\n    date: 1461095520000,\n    open: 56.335,\n    high: 56.36,\n    low: 56.33,\n    close: 56.35,\n    volume: 94774,\n  },\n  {\n    date: 1461095580000,\n    open: 56.35,\n    high: 56.355,\n    low: 56.29,\n    close: 56.3,\n    volume: 87810,\n  },\n  {\n    date: 1461095640000,\n    open: 56.295,\n    high: 56.3,\n    low: 56.28,\n    close: 56.28,\n    volume: 64209,\n  },\n  {\n    date: 1461095700000,\n    open: 56.275,\n    high: 56.295,\n    low: 56.27,\n    close: 56.285,\n    volume: 110531,\n  },\n  {\n    date: 1461095760000,\n    open: 56.288,\n    high: 56.29,\n    low: 56.26,\n    close: 56.2699,\n    volume: 92929,\n  },\n  {\n    date: 1461095820000,\n    open: 56.265,\n    high: 56.28,\n    low: 56.25,\n    close: 56.275,\n    volume: 128498,\n  },\n  {\n    date: 1461095880000,\n    open: 56.275,\n    high: 56.29,\n    low: 56.26,\n    close: 56.265,\n    volume: 164414,\n  },\n  {\n    date: 1461095940000,\n    open: 56.265,\n    high: 56.31,\n    low: 56.245,\n    close: 56.285,\n    volume: 355244,\n  },\n  {\n    date: 1461096000000,\n    open: 56.285,\n    high: 56.4,\n    low: 56.285,\n    close: 56.39,\n    volume: 2223313,\n  },\n  {\n    date: 1461159000000,\n    open: 56.29,\n    high: 56.29,\n    low: 56.28,\n    close: 56.29,\n    volume: 421554,\n  },\n  {\n    date: 1461159060000,\n    open: 56.285,\n    high: 56.5,\n    low: 56.2301,\n    close: 56.25,\n    volume: 140410,\n  },\n  {\n    date: 1461159120000,\n    open: 56.25,\n    high: 56.3,\n    low: 56.23,\n    close: 56.2775,\n    volume: 178566,\n  },\n  {\n    date: 1461159180000,\n    open: 56.275,\n    high: 56.3,\n    low: 56.205,\n    close: 56.27,\n    volume: 122158,\n  },\n  {\n    date: 1461159240000,\n    open: 56.28,\n    high: 56.37,\n    low: 56.26,\n    close: 56.3301,\n    volume: 95263,\n  },\n  {\n    date: 1461159300000,\n    open: 56.34,\n    high: 56.36,\n    low: 56.33,\n    close: 56.35,\n    volume: 81874,\n  },\n  {\n    date: 1461159360000,\n    open: 56.35,\n    high: 56.35,\n    low: 56.29,\n    close: 56.29,\n    volume: 46973,\n  },\n  {\n    date: 1461159420000,\n    open: 56.3,\n    high: 56.36,\n    low: 56.27,\n    close: 56.34,\n    volume: 126114,\n  },\n  {\n    date: 1461159480000,\n    open: 56.34,\n    high: 56.35,\n    low: 56.3,\n    close: 56.31,\n    volume: 67055,\n  },\n  {\n    date: 1461159540000,\n    open: 56.3072,\n    high: 56.39,\n    low: 56.3,\n    close: 56.39,\n    volume: 65616,\n  },\n  {\n    date: 1461159600000,\n    open: 56.385,\n    high: 56.41,\n    low: 56.3535,\n    close: 56.41,\n    volume: 62803,\n  },\n  {\n    date: 1461159660000,\n    open: 56.4005,\n    high: 56.41,\n    low: 56.39,\n    close: 56.4,\n    volume: 119220,\n  },\n  {\n    date: 1461159720000,\n    open: 56.4001,\n    high: 56.41,\n    low: 56.28,\n    close: 56.28,\n    volume: 94429,\n  },\n  {\n    date: 1461159780000,\n    open: 56.2839,\n    high: 56.31,\n    low: 56.26,\n    close: 56.26,\n    volume: 109087,\n  },\n  {\n    date: 1461159840000,\n    open: 56.25,\n    high: 56.26,\n    low: 56.24,\n    close: 56.25,\n    volume: 62663,\n  },\n  {\n    date: 1461159900000,\n    open: 56.24,\n    high: 56.25,\n    low: 56.12,\n    close: 56.13,\n    volume: 132199,\n  },\n  {\n    date: 1461159960000,\n    open: 56.12,\n    high: 56.12,\n    low: 56.08,\n    close: 56.1035,\n    volume: 62222,\n  },\n  {\n    date: 1461160020000,\n    open: 56.1,\n    high: 56.11,\n    low: 56.05,\n    close: 56.08,\n    volume: 92025,\n  },\n  {\n    date: 1461160080000,\n    open: 56.08,\n    high: 56.1,\n    low: 56.07,\n    close: 56.1,\n    volume: 98510,\n  },\n  {\n    date: 1461160140000,\n    open: 56.095,\n    high: 56.11,\n    low: 56.09,\n    close: 56.1,\n    volume: 116555,\n  },\n  {\n    date: 1461160200000,\n    open: 56.09,\n    high: 56.11,\n    low: 56.09,\n    close: 56.11,\n    volume: 91122,\n  },\n  {\n    date: 1461160260000,\n    open: 56.1012,\n    high: 56.16,\n    low: 56.1,\n    close: 56.14,\n    volume: 71180,\n  },\n  {\n    date: 1461160320000,\n    open: 56.14,\n    high: 56.18,\n    low: 56.14,\n    close: 56.18,\n    volume: 65191,\n  },\n  {\n    date: 1461160380000,\n    open: 56.18,\n    high: 56.19,\n    low: 56.16,\n    close: 56.178,\n    volume: 84458,\n  },\n  {\n    date: 1461160440000,\n    open: 56.17,\n    high: 56.235,\n    low: 56.16,\n    close: 56.23,\n    volume: 66112,\n  },\n  {\n    date: 1461160500000,\n    open: 56.23,\n    high: 56.25,\n    low: 56.225,\n    close: 56.23,\n    volume: 55639,\n  },\n  {\n    date: 1461160560000,\n    open: 56.23,\n    high: 56.33,\n    low: 56.23,\n    close: 56.32,\n    volume: 115976,\n  },\n  {\n    date: 1461160620000,\n    open: 56.32,\n    high: 56.32,\n    low: 56.27,\n    close: 56.29,\n    volume: 68862,\n  },\n  {\n    date: 1461160680000,\n    open: 56.2825,\n    high: 56.33,\n    low: 56.2825,\n    close: 56.32,\n    volume: 55183,\n  },\n  {\n    date: 1461160740000,\n    open: 56.32,\n    high: 56.33,\n    low: 56.28,\n    close: 56.285,\n    volume: 41070,\n  },\n  {\n    date: 1461160800000,\n    open: 56.28,\n    high: 56.29,\n    low: 56.25,\n    close: 56.251,\n    volume: 173142,\n  },\n  {\n    date: 1461160860000,\n    open: 56.25,\n    high: 56.26,\n    low: 56.21,\n    close: 56.2237,\n    volume: 56697,\n  },\n  {\n    date: 1461160920000,\n    open: 56.23,\n    high: 56.23,\n    low: 56.17,\n    close: 56.2,\n    volume: 35756,\n  },\n  {\n    date: 1461160980000,\n    open: 56.19,\n    high: 56.21,\n    low: 56.16,\n    close: 56.1861,\n    volume: 47839,\n  },\n  {\n    date: 1461161040000,\n    open: 56.19,\n    high: 56.2,\n    low: 56.16,\n    close: 56.16,\n    volume: 52658,\n  },\n  {\n    date: 1461161100000,\n    open: 56.16,\n    high: 56.16,\n    low: 56.12,\n    close: 56.15,\n    volume: 42556,\n  },\n  {\n    date: 1461161160000,\n    open: 56.155,\n    high: 56.16,\n    low: 56.14,\n    close: 56.16,\n    volume: 106315,\n  },\n  {\n    date: 1461161220000,\n    open: 56.1562,\n    high: 56.16,\n    low: 56.14,\n    close: 56.155,\n    volume: 49807,\n  },\n  {\n    date: 1461161280000,\n    open: 56.1598,\n    high: 56.17,\n    low: 56.12,\n    close: 56.1299,\n    volume: 75754,\n  },\n  {\n    date: 1461161340000,\n    open: 56.13,\n    high: 56.16,\n    low: 56.12,\n    close: 56.155,\n    volume: 79236,\n  },\n  {\n    date: 1461161400000,\n    open: 56.155,\n    high: 56.16,\n    low: 56.11,\n    close: 56.11,\n    volume: 45861,\n  },\n  {\n    date: 1461161460000,\n    open: 56.1101,\n    high: 56.115,\n    low: 56.08,\n    close: 56.085,\n    volume: 58198,\n  },\n  {\n    date: 1461161520000,\n    open: 56.08,\n    high: 56.16,\n    low: 56.08,\n    close: 56.15,\n    volume: 96116,\n  },\n  {\n    date: 1461161580000,\n    open: 56.1599,\n    high: 56.16,\n    low: 56.14,\n    close: 56.155,\n    volume: 68985,\n  },\n  {\n    date: 1461161640000,\n    open: 56.16,\n    high: 56.16,\n    low: 56.13,\n    close: 56.135,\n    volume: 38769,\n  },\n  {\n    date: 1461161700000,\n    open: 56.1301,\n    high: 56.16,\n    low: 56.13,\n    close: 56.16,\n    volume: 81544,\n  },\n  {\n    date: 1461161760000,\n    open: 56.17,\n    high: 56.22,\n    low: 56.16,\n    close: 56.22,\n    volume: 66753,\n  },\n  {\n    date: 1461161820000,\n    open: 56.22,\n    high: 56.23,\n    low: 56.145,\n    close: 56.145,\n    volume: 87545,\n  },\n  {\n    date: 1461161880000,\n    open: 56.145,\n    high: 56.16,\n    low: 56.14,\n    close: 56.145,\n    volume: 39668,\n  },\n  {\n    date: 1461161940000,\n    open: 56.14,\n    high: 56.15,\n    low: 56.1,\n    close: 56.105,\n    volume: 61121,\n  },\n  {\n    date: 1461162000000,\n    open: 56.105,\n    high: 56.11,\n    low: 56.1,\n    close: 56.1,\n    volume: 63840,\n  },\n  {\n    date: 1461162060000,\n    open: 56.1,\n    high: 56.11,\n    low: 56.1,\n    close: 56.105,\n    volume: 50657,\n  },\n  {\n    date: 1461162120000,\n    open: 56.105,\n    high: 56.11,\n    low: 56.1,\n    close: 56.105,\n    volume: 75139,\n  },\n  {\n    date: 1461162180000,\n    open: 56.105,\n    high: 56.11,\n    low: 56.05,\n    close: 56.09,\n    volume: 266768,\n  },\n  {\n    date: 1461162240000,\n    open: 56.0999,\n    high: 56.15,\n    low: 56.0999,\n    close: 56.14,\n    volume: 87360,\n  },\n  {\n    date: 1461162300000,\n    open: 56.14,\n    high: 56.14,\n    low: 56.07,\n    close: 56.085,\n    volume: 81986,\n  },\n  {\n    date: 1461162360000,\n    open: 56.085,\n    high: 56.09,\n    low: 56.05,\n    close: 56.07,\n    volume: 46543,\n  },\n  {\n    date: 1461162420000,\n    open: 56.07,\n    high: 56.1,\n    low: 56.06,\n    close: 56.0838,\n    volume: 38631,\n  },\n  {\n    date: 1461162480000,\n    open: 56.085,\n    high: 56.09,\n    low: 56.04,\n    close: 56.04,\n    volume: 61687,\n  },\n  {\n    date: 1461162540000,\n    open: 56.045,\n    high: 56.05,\n    low: 56,\n    close: 56.01,\n    volume: 65511,\n  },\n  {\n    date: 1461162600000,\n    open: 56.005,\n    high: 56.055,\n    low: 56,\n    close: 56.045,\n    volume: 429591,\n  },\n  {\n    date: 1461162660000,\n    open: 56.04,\n    high: 56.05,\n    low: 56.015,\n    close: 56.04,\n    volume: 64408,\n  },\n  {\n    date: 1461162720000,\n    open: 56.03,\n    high: 56.05,\n    low: 56.02,\n    close: 56.035,\n    volume: 60772,\n  },\n  {\n    date: 1461162780000,\n    open: 56.04,\n    high: 56.05,\n    low: 56.03,\n    close: 56.045,\n    volume: 47692,\n  },\n  {\n    date: 1461162840000,\n    open: 56.05,\n    high: 56.06,\n    low: 56.03,\n    close: 56.06,\n    volume: 74412,\n  },\n  {\n    date: 1461162900000,\n    open: 56.06,\n    high: 56.06,\n    low: 56.043,\n    close: 56.055,\n    volume: 36918,\n  },\n  {\n    date: 1461162960000,\n    open: 56.0528,\n    high: 56.055,\n    low: 56,\n    close: 56.005,\n    volume: 105632,\n  },\n  {\n    date: 1461163020000,\n    open: 56,\n    high: 56.02,\n    low: 56,\n    close: 56,\n    volume: 64452,\n  },\n  {\n    date: 1461163080000,\n    open: 56,\n    high: 56.01,\n    low: 55.96,\n    close: 55.965,\n    volume: 185423,\n  },\n  {\n    date: 1461163140000,\n    open: 55.96,\n    high: 55.9699,\n    low: 55.94,\n    close: 55.95,\n    volume: 89827,\n  },\n  {\n    date: 1461163200000,\n    open: 55.9542,\n    high: 56.01,\n    low: 55.95,\n    close: 56,\n    volume: 77442,\n  },\n  {\n    date: 1461163260000,\n    open: 55.9927,\n    high: 56,\n    low: 55.9634,\n    close: 55.98,\n    volume: 54640,\n  },\n  {\n    date: 1461163320000,\n    open: 55.98,\n    high: 56.0033,\n    low: 55.97,\n    close: 56,\n    volume: 40360,\n  },\n  {\n    date: 1461163380000,\n    open: 56.01,\n    high: 56.02,\n    low: 55.99,\n    close: 55.99,\n    volume: 85878,\n  },\n  {\n    date: 1461163440000,\n    open: 55.99,\n    high: 55.9999,\n    low: 55.97,\n    close: 55.97,\n    volume: 18448,\n  },\n  {\n    date: 1461163500000,\n    open: 55.97,\n    high: 55.9857,\n    low: 55.96,\n    close: 55.96,\n    volume: 47930,\n  },\n  {\n    date: 1461163560000,\n    open: 55.9662,\n    high: 55.97,\n    low: 55.945,\n    close: 55.965,\n    volume: 57718,\n  },\n  {\n    date: 1461163620000,\n    open: 55.965,\n    high: 55.97,\n    low: 55.94,\n    close: 55.945,\n    volume: 93745,\n  },\n  {\n    date: 1461163680000,\n    open: 55.945,\n    high: 55.98,\n    low: 55.935,\n    close: 55.955,\n    volume: 95327,\n  },\n  {\n    date: 1461163740000,\n    open: 55.955,\n    high: 56,\n    low: 55.95,\n    close: 55.995,\n    volume: 90455,\n  },\n  {\n    date: 1461163800000,\n    open: 55.99,\n    high: 56.03,\n    low: 55.99,\n    close: 56,\n    volume: 70029,\n  },\n  {\n    date: 1461163860000,\n    open: 56,\n    high: 56.01,\n    low: 55.98,\n    close: 55.99,\n    volume: 39683,\n  },\n  {\n    date: 1461163920000,\n    open: 55.99,\n    high: 56.02,\n    low: 55.99,\n    close: 56.005,\n    volume: 37560,\n  },\n  {\n    date: 1461163980000,\n    open: 56.005,\n    high: 56.02,\n    low: 55.97,\n    close: 55.97,\n    volume: 115310,\n  },\n  {\n    date: 1461164040000,\n    open: 55.98,\n    high: 55.99,\n    low: 55.9734,\n    close: 55.985,\n    volume: 20719,\n  },\n  {\n    date: 1461164100000,\n    open: 55.99,\n    high: 56.0063,\n    low: 55.9839,\n    close: 56,\n    volume: 42003,\n  },\n  {\n    date: 1461164160000,\n    open: 56.01,\n    high: 56.035,\n    low: 55.9942,\n    close: 56.02,\n    volume: 72522,\n  },\n  {\n    date: 1461164220000,\n    open: 56.03,\n    high: 56.065,\n    low: 56.025,\n    close: 56.055,\n    volume: 54473,\n  },\n  {\n    date: 1461164280000,\n    open: 56.0533,\n    high: 56.06,\n    low: 56.03,\n    close: 56.055,\n    volume: 49679,\n  },\n  {\n    date: 1461164340000,\n    open: 56.058,\n    high: 56.06,\n    low: 56.03,\n    close: 56.045,\n    volume: 75360,\n  },\n  {\n    date: 1461164400000,\n    open: 56.045,\n    high: 56.05,\n    low: 56.03,\n    close: 56.035,\n    volume: 27897,\n  },\n  {\n    date: 1461164460000,\n    open: 56.04,\n    high: 56.05,\n    low: 56.015,\n    close: 56.025,\n    volume: 52109,\n  },\n  {\n    date: 1461164520000,\n    open: 56.025,\n    high: 56.03,\n    low: 56,\n    close: 56,\n    volume: 94182,\n  },\n  {\n    date: 1461164580000,\n    open: 56,\n    high: 56.01,\n    low: 55.98,\n    close: 55.995,\n    volume: 44592,\n  },\n  {\n    date: 1461164640000,\n    open: 55.995,\n    high: 56.01,\n    low: 55.96,\n    close: 55.995,\n    volume: 93051,\n  },\n  {\n    date: 1461164700000,\n    open: 55.995,\n    high: 56.01,\n    low: 55.96,\n    close: 55.995,\n    volume: 78876,\n  },\n  {\n    date: 1461164760000,\n    open: 55.995,\n    high: 56.03,\n    low: 55.9901,\n    close: 56.025,\n    volume: 50082,\n  },\n  {\n    date: 1461164820000,\n    open: 56.03,\n    high: 56.0524,\n    low: 56.02,\n    close: 56.0364,\n    volume: 55908,\n  },\n  {\n    date: 1461164880000,\n    open: 56.0403,\n    high: 56.075,\n    low: 56.03,\n    close: 56.045,\n    volume: 229799,\n  },\n  {\n    date: 1461164940000,\n    open: 56.045,\n    high: 56.06,\n    low: 56.02,\n    close: 56.035,\n    volume: 156551,\n  },\n  {\n    date: 1461165000000,\n    open: 56.04,\n    high: 56.05,\n    low: 56.03,\n    close: 56.0336,\n    volume: 91537,\n  },\n  {\n    date: 1461165060000,\n    open: 56.03,\n    high: 56.06,\n    low: 56.03,\n    close: 56.05,\n    volume: 135679,\n  },\n  {\n    date: 1461165120000,\n    open: 56.06,\n    high: 56.09,\n    low: 56.055,\n    close: 56.0826,\n    volume: 54563,\n  },\n  {\n    date: 1461165180000,\n    open: 56.09,\n    high: 56.09,\n    low: 56.04,\n    close: 56.0701,\n    volume: 90324,\n  },\n  {\n    date: 1461165240000,\n    open: 56.07,\n    high: 56.08,\n    low: 56.065,\n    close: 56.075,\n    volume: 24204,\n  },\n  {\n    date: 1461165300000,\n    open: 56.08,\n    high: 56.12,\n    low: 56.075,\n    close: 56.1,\n    volume: 64675,\n  },\n  {\n    date: 1461165360000,\n    open: 56.105,\n    high: 56.17,\n    low: 56.105,\n    close: 56.1599,\n    volume: 54670,\n  },\n  {\n    date: 1461165420000,\n    open: 56.1593,\n    high: 56.17,\n    low: 56.14,\n    close: 56.145,\n    volume: 63596,\n  },\n  {\n    date: 1461165480000,\n    open: 56.15,\n    high: 56.15,\n    low: 56.14,\n    close: 56.145,\n    volume: 37675,\n  },\n  {\n    date: 1461165540000,\n    open: 56.15,\n    high: 56.15,\n    low: 56.11,\n    close: 56.12,\n    volume: 53706,\n  },\n  {\n    date: 1461165600000,\n    open: 56.12,\n    high: 56.15,\n    low: 56.11,\n    close: 56.1439,\n    volume: 49816,\n  },\n  {\n    date: 1461165660000,\n    open: 56.145,\n    high: 56.155,\n    low: 56.14,\n    close: 56.155,\n    volume: 69811,\n  },\n  {\n    date: 1461165720000,\n    open: 56.155,\n    high: 56.16,\n    low: 56.1435,\n    close: 56.1465,\n    volume: 22805,\n  },\n  {\n    date: 1461165780000,\n    open: 56.14,\n    high: 56.15,\n    low: 56.12,\n    close: 56.15,\n    volume: 78596,\n  },\n  {\n    date: 1461165840000,\n    open: 56.15,\n    high: 56.16,\n    low: 56.145,\n    close: 56.16,\n    volume: 98318,\n  },\n  {\n    date: 1461165900000,\n    open: 56.15,\n    high: 56.16,\n    low: 56.13,\n    close: 56.14,\n    volume: 43137,\n  },\n  {\n    date: 1461165960000,\n    open: 56.14,\n    high: 56.16,\n    low: 56.13,\n    close: 56.14,\n    volume: 122371,\n  },\n  {\n    date: 1461166020000,\n    open: 56.14,\n    high: 56.1511,\n    low: 56.14,\n    close: 56.145,\n    volume: 26642,\n  },\n  {\n    date: 1461166080000,\n    open: 56.15,\n    high: 56.16,\n    low: 56.145,\n    close: 56.153,\n    volume: 20068,\n  },\n  {\n    date: 1461166140000,\n    open: 56.15,\n    high: 56.161,\n    low: 56.15,\n    close: 56.155,\n    volume: 134746,\n  },\n  {\n    date: 1461166200000,\n    open: 56.155,\n    high: 56.16,\n    low: 56.14,\n    close: 56.15,\n    volume: 57780,\n  },\n  {\n    date: 1461166260000,\n    open: 56.15,\n    high: 56.1575,\n    low: 56.14,\n    close: 56.145,\n    volume: 44956,\n  },\n  {\n    date: 1461166320000,\n    open: 56.14,\n    high: 56.16,\n    low: 56.14,\n    close: 56.155,\n    volume: 31933,\n  },\n  {\n    date: 1461166380000,\n    open: 56.1535,\n    high: 56.16,\n    low: 56.14,\n    close: 56.14,\n    volume: 39005,\n  },\n  {\n    date: 1461166440000,\n    open: 56.145,\n    high: 56.16,\n    low: 56.14,\n    close: 56.15,\n    volume: 47930,\n  },\n  {\n    date: 1461166500000,\n    open: 56.15,\n    high: 56.155,\n    low: 56.14,\n    close: 56.15,\n    volume: 31955,\n  },\n  {\n    date: 1461166560000,\n    open: 56.15,\n    high: 56.16,\n    low: 56.15,\n    close: 56.15,\n    volume: 62497,\n  },\n  {\n    date: 1461166620000,\n    open: 56.155,\n    high: 56.16,\n    low: 56.15,\n    close: 56.155,\n    volume: 9523,\n  },\n  {\n    date: 1461166680000,\n    open: 56.15,\n    high: 56.155,\n    low: 56.11,\n    close: 56.115,\n    volume: 44316,\n  },\n  {\n    date: 1461166740000,\n    open: 56.12,\n    high: 56.155,\n    low: 56.115,\n    close: 56.1465,\n    volume: 42870,\n  },\n  {\n    date: 1461166800000,\n    open: 56.15,\n    high: 56.16,\n    low: 56.14,\n    close: 56.15,\n    volume: 44481,\n  },\n  {\n    date: 1461166860000,\n    open: 56.15,\n    high: 56.17,\n    low: 56.1433,\n    close: 56.165,\n    volume: 71054,\n  },\n  {\n    date: 1461166920000,\n    open: 56.165,\n    high: 56.17,\n    low: 56.16,\n    close: 56.165,\n    volume: 25535,\n  },\n  {\n    date: 1461166980000,\n    open: 56.17,\n    high: 56.17,\n    low: 56.12,\n    close: 56.125,\n    volume: 71952,\n  },\n  {\n    date: 1461167040000,\n    open: 56.125,\n    high: 56.15,\n    low: 56.105,\n    close: 56.14,\n    volume: 39215,\n  },\n  {\n    date: 1461167100000,\n    open: 56.14,\n    high: 56.15,\n    low: 56.1375,\n    close: 56.145,\n    volume: 29195,\n  },\n  {\n    date: 1461167160000,\n    open: 56.145,\n    high: 56.17,\n    low: 56.14,\n    close: 56.165,\n    volume: 79131,\n  },\n  {\n    date: 1461167220000,\n    open: 56.16,\n    high: 56.16,\n    low: 56.115,\n    close: 56.14,\n    volume: 64831,\n  },\n  {\n    date: 1461167280000,\n    open: 56.14,\n    high: 56.16,\n    low: 56.1,\n    close: 56.15,\n    volume: 82644,\n  },\n  {\n    date: 1461167340000,\n    open: 56.155,\n    high: 56.16,\n    low: 56.15,\n    close: 56.155,\n    volume: 17503,\n  },\n  {\n    date: 1461167400000,\n    open: 56.16,\n    high: 56.16,\n    low: 56.15,\n    close: 56.15,\n    volume: 11051,\n  },\n  {\n    date: 1461167460000,\n    open: 56.15,\n    high: 56.16,\n    low: 56.08,\n    close: 56.09,\n    volume: 83806,\n  },\n  {\n    date: 1461167520000,\n    open: 56.1,\n    high: 56.11,\n    low: 56.085,\n    close: 56.1,\n    volume: 28428,\n  },\n  {\n    date: 1461167580000,\n    open: 56.095,\n    high: 56.11,\n    low: 56.09,\n    close: 56.105,\n    volume: 42857,\n  },\n  {\n    date: 1461167640000,\n    open: 56.1,\n    high: 56.11,\n    low: 56.0541,\n    close: 56.06,\n    volume: 31009,\n  },\n  {\n    date: 1461167700000,\n    open: 56.065,\n    high: 56.07,\n    low: 56.06,\n    close: 56.06,\n    volume: 37903,\n  },\n  {\n    date: 1461167760000,\n    open: 56.065,\n    high: 56.1,\n    low: 56.06,\n    close: 56.09,\n    volume: 30290,\n  },\n  {\n    date: 1461167820000,\n    open: 56.09,\n    high: 56.1,\n    low: 56.085,\n    close: 56.1,\n    volume: 22418,\n  },\n  {\n    date: 1461167880000,\n    open: 56.095,\n    high: 56.1,\n    low: 56.09,\n    close: 56.09,\n    volume: 62176,\n  },\n  {\n    date: 1461167940000,\n    open: 56.09,\n    high: 56.095,\n    low: 56.07,\n    close: 56.085,\n    volume: 29759,\n  },\n  {\n    date: 1461168000000,\n    open: 56.08,\n    high: 56.1,\n    low: 56.07,\n    close: 56.1,\n    volume: 33055,\n  },\n  {\n    date: 1461168060000,\n    open: 56.0999,\n    high: 56.1,\n    low: 56.08,\n    close: 56.09,\n    volume: 28997,\n  },\n  {\n    date: 1461168120000,\n    open: 56.09,\n    high: 56.1,\n    low: 56.09,\n    close: 56.09,\n    volume: 8381,\n  },\n  {\n    date: 1461168180000,\n    open: 56.09,\n    high: 56.1,\n    low: 56.09,\n    close: 56.1,\n    volume: 31383,\n  },\n  {\n    date: 1461168240000,\n    open: 56.094,\n    high: 56.1,\n    low: 56.09,\n    close: 56.1,\n    volume: 22890,\n  },\n  {\n    date: 1461168300000,\n    open: 56.1,\n    high: 56.1,\n    low: 56.09,\n    close: 56.1,\n    volume: 15227,\n  },\n  {\n    date: 1461168360000,\n    open: 56.1,\n    high: 56.11,\n    low: 56.09,\n    close: 56.095,\n    volume: 182603,\n  },\n  {\n    date: 1461168420000,\n    open: 56.1,\n    high: 56.1,\n    low: 56.09,\n    close: 56.09,\n    volume: 11405,\n  },\n  {\n    date: 1461168480000,\n    open: 56.09,\n    high: 56.1,\n    low: 56.06,\n    close: 56.07,\n    volume: 40278,\n  },\n  {\n    date: 1461168540000,\n    open: 56.075,\n    high: 56.08,\n    low: 56.07,\n    close: 56.07,\n    volume: 8043,\n  },\n  {\n    date: 1461168600000,\n    open: 56.07,\n    high: 56.08,\n    low: 56.07,\n    close: 56.075,\n    volume: 22203,\n  },\n  {\n    date: 1461168660000,\n    open: 56.075,\n    high: 56.09,\n    low: 56.07,\n    close: 56.0835,\n    volume: 12090,\n  },\n  {\n    date: 1461168720000,\n    open: 56.09,\n    high: 56.09,\n    low: 56.05,\n    close: 56.05,\n    volume: 26845,\n  },\n  {\n    date: 1461168780000,\n    open: 56.0536,\n    high: 56.065,\n    low: 56.045,\n    close: 56.05,\n    volume: 36555,\n  },\n  {\n    date: 1461168840000,\n    open: 56.05,\n    high: 56.055,\n    low: 56.04,\n    close: 56.04,\n    volume: 20900,\n  },\n  {\n    date: 1461168900000,\n    open: 56.045,\n    high: 56.08,\n    low: 56.04,\n    close: 56.06,\n    volume: 31308,\n  },\n  {\n    date: 1461168960000,\n    open: 56.07,\n    high: 56.075,\n    low: 56.005,\n    close: 56.015,\n    volume: 58612,\n  },\n  {\n    date: 1461169020000,\n    open: 56.016,\n    high: 56.0273,\n    low: 56.01,\n    close: 56.0259,\n    volume: 17619,\n  },\n  {\n    date: 1461169080000,\n    open: 56.0258,\n    high: 56.03,\n    low: 56.02,\n    close: 56.025,\n    volume: 39198,\n  },\n  {\n    date: 1461169140000,\n    open: 56.025,\n    high: 56.03,\n    low: 56,\n    close: 56,\n    volume: 49785,\n  },\n  {\n    date: 1461169200000,\n    open: 56,\n    high: 56.02,\n    low: 56,\n    close: 56.02,\n    volume: 44178,\n  },\n  {\n    date: 1461169260000,\n    open: 56.024,\n    high: 56.04,\n    low: 56.02,\n    close: 56.02,\n    volume: 35403,\n  },\n  {\n    date: 1461169320000,\n    open: 56.03,\n    high: 56.04,\n    low: 56.02,\n    close: 56.04,\n    volume: 29585,\n  },\n  {\n    date: 1461169380000,\n    open: 56.035,\n    high: 56.04,\n    low: 56.03,\n    close: 56.03,\n    volume: 8755,\n  },\n  {\n    date: 1461169440000,\n    open: 56.03,\n    high: 56.05,\n    low: 56.03,\n    close: 56.041,\n    volume: 18849,\n  },\n  {\n    date: 1461169500000,\n    open: 56.0438,\n    high: 56.085,\n    low: 56.0438,\n    close: 56.075,\n    volume: 35509,\n  },\n  {\n    date: 1461169560000,\n    open: 56.08,\n    high: 56.09,\n    low: 56.07,\n    close: 56.08,\n    volume: 22323,\n  },\n  {\n    date: 1461169620000,\n    open: 56.075,\n    high: 56.08,\n    low: 56.07,\n    close: 56.08,\n    volume: 5723,\n  },\n  {\n    date: 1461169680000,\n    open: 56.07,\n    high: 56.1,\n    low: 56.07,\n    close: 56.08,\n    volume: 23264,\n  },\n  {\n    date: 1461169740000,\n    open: 56.085,\n    high: 56.1,\n    low: 56.08,\n    close: 56.09,\n    volume: 15307,\n  },\n  {\n    date: 1461169800000,\n    open: 56.09,\n    high: 56.12,\n    low: 56.09,\n    close: 56.09,\n    volume: 70795,\n  },\n  {\n    date: 1461169860000,\n    open: 56.09,\n    high: 56.11,\n    low: 56.09,\n    close: 56.1,\n    volume: 29875,\n  },\n  {\n    date: 1461169920000,\n    open: 56.0964,\n    high: 56.1,\n    low: 56.05,\n    close: 56.07,\n    volume: 30617,\n  },\n  {\n    date: 1461169980000,\n    open: 56.065,\n    high: 56.0799,\n    low: 56.06,\n    close: 56.065,\n    volume: 14541,\n  },\n  {\n    date: 1461170040000,\n    open: 56.065,\n    high: 56.1,\n    low: 56.065,\n    close: 56.1,\n    volume: 27068,\n  },\n  {\n    date: 1461170100000,\n    open: 56.1,\n    high: 56.1,\n    low: 56.095,\n    close: 56.095,\n    volume: 14410,\n  },\n  {\n    date: 1461170160000,\n    open: 56.1,\n    high: 56.11,\n    low: 56.1,\n    close: 56.105,\n    volume: 14683,\n  },\n  {\n    date: 1461170220000,\n    open: 56.1,\n    high: 56.11,\n    low: 56.1,\n    close: 56.1,\n    volume: 10852,\n  },\n  {\n    date: 1461170280000,\n    open: 56.105,\n    high: 56.13,\n    low: 56.1,\n    close: 56.11,\n    volume: 111444,\n  },\n  {\n    date: 1461170340000,\n    open: 56.11,\n    high: 56.1371,\n    low: 56.1002,\n    close: 56.13,\n    volume: 36611,\n  },\n  {\n    date: 1461170400000,\n    open: 56.12,\n    high: 56.15,\n    low: 56.12,\n    close: 56.1499,\n    volume: 18240,\n  },\n  {\n    date: 1461170460000,\n    open: 56.145,\n    high: 56.16,\n    low: 56.1301,\n    close: 56.16,\n    volume: 53235,\n  },\n  {\n    date: 1461170520000,\n    open: 56.15,\n    high: 56.15,\n    low: 56.13,\n    close: 56.13,\n    volume: 27589,\n  },\n  {\n    date: 1461170580000,\n    open: 56.1272,\n    high: 56.1361,\n    low: 56.12,\n    close: 56.13,\n    volume: 25563,\n  },\n  {\n    date: 1461170640000,\n    open: 56.125,\n    high: 56.13,\n    low: 56.1029,\n    close: 56.1029,\n    volume: 35203,\n  },\n  {\n    date: 1461170700000,\n    open: 56.1,\n    high: 56.1338,\n    low: 56.1,\n    close: 56.1231,\n    volume: 54983,\n  },\n  {\n    date: 1461170760000,\n    open: 56.12,\n    high: 56.13,\n    low: 56.11,\n    close: 56.125,\n    volume: 12385,\n  },\n  {\n    date: 1461170820000,\n    open: 56.125,\n    high: 56.135,\n    low: 56.11,\n    close: 56.129,\n    volume: 26956,\n  },\n  {\n    date: 1461170880000,\n    open: 56.12,\n    high: 56.12,\n    low: 56.1,\n    close: 56.105,\n    volume: 17255,\n  },\n  {\n    date: 1461170940000,\n    open: 56.1015,\n    high: 56.13,\n    low: 56.1015,\n    close: 56.11,\n    volume: 24600,\n  },\n  {\n    date: 1461171000000,\n    open: 56.116,\n    high: 56.12,\n    low: 56.1,\n    close: 56.11,\n    volume: 25454,\n  },\n  {\n    date: 1461171060000,\n    open: 56.11,\n    high: 56.11,\n    low: 56.1,\n    close: 56.105,\n    volume: 63412,\n  },\n  {\n    date: 1461171120000,\n    open: 56.1036,\n    high: 56.11,\n    low: 56.1,\n    close: 56.1,\n    volume: 43992,\n  },\n  {\n    date: 1461171180000,\n    open: 56.1,\n    high: 56.125,\n    low: 56.1,\n    close: 56.1,\n    volume: 30635,\n  },\n  {\n    date: 1461171240000,\n    open: 56.105,\n    high: 56.12,\n    low: 56.105,\n    close: 56.12,\n    volume: 30427,\n  },\n  {\n    date: 1461171300000,\n    open: 56.12,\n    high: 56.12,\n    low: 56.095,\n    close: 56.1,\n    volume: 49622,\n  },\n  {\n    date: 1461171360000,\n    open: 56.1,\n    high: 56.12,\n    low: 56.095,\n    close: 56.11,\n    volume: 49025,\n  },\n  {\n    date: 1461171420000,\n    open: 56.11,\n    high: 56.12,\n    low: 56.105,\n    close: 56.11,\n    volume: 20027,\n  },\n  {\n    date: 1461171480000,\n    open: 56.115,\n    high: 56.125,\n    low: 56.11,\n    close: 56.12,\n    volume: 26433,\n  },\n  {\n    date: 1461171540000,\n    open: 56.11,\n    high: 56.12,\n    low: 56.105,\n    close: 56.11,\n    volume: 15629,\n  },\n  {\n    date: 1461171600000,\n    open: 56.1199,\n    high: 56.1199,\n    low: 56.07,\n    close: 56.0864,\n    volume: 37378,\n  },\n  {\n    date: 1461171660000,\n    open: 56.0825,\n    high: 56.1,\n    low: 56.07,\n    close: 56.1,\n    volume: 29675,\n  },\n  {\n    date: 1461171720000,\n    open: 56.095,\n    high: 56.12,\n    low: 56.09,\n    close: 56.115,\n    volume: 27894,\n  },\n  {\n    date: 1461171780000,\n    open: 56.11,\n    high: 56.12,\n    low: 56.1,\n    close: 56.1159,\n    volume: 13513,\n  },\n  {\n    date: 1461171840000,\n    open: 56.115,\n    high: 56.12,\n    low: 56.11,\n    close: 56.11,\n    volume: 26306,\n  },\n  {\n    date: 1461171900000,\n    open: 56.116,\n    high: 56.12,\n    low: 56.09,\n    close: 56.11,\n    volume: 19388,\n  },\n  {\n    date: 1461171960000,\n    open: 56.1199,\n    high: 56.1199,\n    low: 56.09,\n    close: 56.093,\n    volume: 33772,\n  },\n  {\n    date: 1461172020000,\n    open: 56.09,\n    high: 56.095,\n    low: 56.03,\n    close: 56.04,\n    volume: 49468,\n  },\n  {\n    date: 1461172080000,\n    open: 56.0375,\n    high: 56.0375,\n    low: 56,\n    close: 56.0065,\n    volume: 76136,\n  },\n  {\n    date: 1461172140000,\n    open: 56.01,\n    high: 56.03,\n    low: 56,\n    close: 56.0101,\n    volume: 67103,\n  },\n  {\n    date: 1461172200000,\n    open: 56.01,\n    high: 56.0163,\n    low: 56,\n    close: 56.005,\n    volume: 17844,\n  },\n  {\n    date: 1461172260000,\n    open: 56.01,\n    high: 56.03,\n    low: 56,\n    close: 56.0201,\n    volume: 17276,\n  },\n  {\n    date: 1461172320000,\n    open: 56.03,\n    high: 56.03,\n    low: 56.015,\n    close: 56.02,\n    volume: 46617,\n  },\n  {\n    date: 1461172380000,\n    open: 56.03,\n    high: 56.035,\n    low: 56.0132,\n    close: 56.02,\n    volume: 24726,\n  },\n  {\n    date: 1461172440000,\n    open: 56.0236,\n    high: 56.04,\n    low: 56.02,\n    close: 56.035,\n    volume: 15601,\n  },\n  {\n    date: 1461172500000,\n    open: 56.04,\n    high: 56.04,\n    low: 56.03,\n    close: 56.035,\n    volume: 96644,\n  },\n  {\n    date: 1461172560000,\n    open: 56.035,\n    high: 56.05,\n    low: 56.0338,\n    close: 56.0338,\n    volume: 90578,\n  },\n  {\n    date: 1461172620000,\n    open: 56.035,\n    high: 56.04,\n    low: 56.025,\n    close: 56.035,\n    volume: 19841,\n  },\n  {\n    date: 1461172680000,\n    open: 56.04,\n    high: 56.07,\n    low: 56.035,\n    close: 56.06,\n    volume: 31843,\n  },\n  {\n    date: 1461172740000,\n    open: 56.05,\n    high: 56.06,\n    low: 56.05,\n    close: 56.06,\n    volume: 17203,\n  },\n  {\n    date: 1461172800000,\n    open: 56.0532,\n    high: 56.06,\n    low: 56.05,\n    close: 56.055,\n    volume: 10214,\n  },\n  {\n    date: 1461172860000,\n    open: 56.0571,\n    high: 56.06,\n    low: 56.01,\n    close: 56.0236,\n    volume: 66582,\n  },\n  {\n    date: 1461172920000,\n    open: 56.021,\n    high: 56.05,\n    low: 56.0205,\n    close: 56.05,\n    volume: 42305,\n  },\n  {\n    date: 1461172980000,\n    open: 56.05,\n    high: 56.06,\n    low: 56.045,\n    close: 56.055,\n    volume: 48512,\n  },\n  {\n    date: 1461173040000,\n    open: 56.05,\n    high: 56.06,\n    low: 56.05,\n    close: 56.06,\n    volume: 9988,\n  },\n  {\n    date: 1461173100000,\n    open: 56.0577,\n    high: 56.08,\n    low: 56.05,\n    close: 56.075,\n    volume: 33233,\n  },\n  {\n    date: 1461173160000,\n    open: 56.075,\n    high: 56.115,\n    low: 56.07,\n    close: 56.1075,\n    volume: 92450,\n  },\n  {\n    date: 1461173220000,\n    open: 56.115,\n    high: 56.115,\n    low: 56.09,\n    close: 56.1,\n    volume: 117499,\n  },\n  {\n    date: 1461173280000,\n    open: 56.1,\n    high: 56.11,\n    low: 56.06,\n    close: 56.1,\n    volume: 132283,\n  },\n  {\n    date: 1461173340000,\n    open: 56.1,\n    high: 56.11,\n    low: 56.09,\n    close: 56.1,\n    volume: 290616,\n  },\n  {\n    date: 1461173400000,\n    open: 56.1,\n    high: 56.11,\n    low: 56.06,\n    close: 56.065,\n    volume: 264616,\n  },\n  {\n    date: 1461173460000,\n    open: 56.065,\n    high: 56.09,\n    low: 56.055,\n    close: 56.065,\n    volume: 78773,\n  },\n  {\n    date: 1461173520000,\n    open: 56.065,\n    high: 56.085,\n    low: 56.06,\n    close: 56.085,\n    volume: 59672,\n  },\n  {\n    date: 1461173580000,\n    open: 56.085,\n    high: 56.095,\n    low: 56.075,\n    close: 56.08,\n    volume: 78018,\n  },\n  {\n    date: 1461173640000,\n    open: 56.085,\n    high: 56.1,\n    low: 56.07,\n    close: 56.09,\n    volume: 50521,\n  },\n  {\n    date: 1461173700000,\n    open: 56.1,\n    high: 56.12,\n    low: 56.08,\n    close: 56.0858,\n    volume: 70047,\n  },\n  {\n    date: 1461173760000,\n    open: 56.085,\n    high: 56.1,\n    low: 56.0799,\n    close: 56.085,\n    volume: 50258,\n  },\n  {\n    date: 1461173820000,\n    open: 56.09,\n    high: 56.095,\n    low: 56.07,\n    close: 56.075,\n    volume: 70013,\n  },\n  {\n    date: 1461173880000,\n    open: 56.075,\n    high: 56.08,\n    low: 56.05,\n    close: 56.05,\n    volume: 59659,\n  },\n  {\n    date: 1461173940000,\n    open: 56.05,\n    high: 56.06,\n    low: 56.05,\n    close: 56.055,\n    volume: 26365,\n  },\n  {\n    date: 1461174000000,\n    open: 56.05,\n    high: 56.075,\n    low: 56.04,\n    close: 56.045,\n    volume: 72085,\n  },\n  {\n    date: 1461174060000,\n    open: 56.05,\n    high: 56.06,\n    low: 56.035,\n    close: 56.035,\n    volume: 36744,\n  },\n  {\n    date: 1461174120000,\n    open: 56.035,\n    high: 56.04,\n    low: 56.01,\n    close: 56.01,\n    volume: 48621,\n  },\n  {\n    date: 1461174180000,\n    open: 56.01,\n    high: 56.0164,\n    low: 56,\n    close: 56.005,\n    volume: 45690,\n  },\n  {\n    date: 1461174240000,\n    open: 56.004,\n    high: 56.01,\n    low: 56,\n    close: 56.005,\n    volume: 35910,\n  },\n  {\n    date: 1461174300000,\n    open: 56.0036,\n    high: 56.01,\n    low: 55.98,\n    close: 56,\n    volume: 45039,\n  },\n  {\n    date: 1461174360000,\n    open: 56.005,\n    high: 56.01,\n    low: 55.99,\n    close: 56.005,\n    volume: 98151,\n  },\n  {\n    date: 1461174420000,\n    open: 56.005,\n    high: 56.0188,\n    low: 55.99,\n    close: 56,\n    volume: 25789,\n  },\n  {\n    date: 1461174480000,\n    open: 56,\n    high: 56.05,\n    low: 55.995,\n    close: 56.04,\n    volume: 57431,\n  },\n  {\n    date: 1461174540000,\n    open: 56.03,\n    high: 56.05,\n    low: 56.01,\n    close: 56.035,\n    volume: 61221,\n  },\n  {\n    date: 1461174600000,\n    open: 56.03,\n    high: 56.035,\n    low: 56.02,\n    close: 56.02,\n    volume: 28760,\n  },\n  {\n    date: 1461174660000,\n    open: 56.03,\n    high: 56.04,\n    low: 56.02,\n    close: 56.02,\n    volume: 24296,\n  },\n  {\n    date: 1461174720000,\n    open: 56.025,\n    high: 56.05,\n    low: 56.02,\n    close: 56.05,\n    volume: 56435,\n  },\n  {\n    date: 1461174780000,\n    open: 56.04,\n    high: 56.05,\n    low: 56.03,\n    close: 56.04,\n    volume: 39903,\n  },\n  {\n    date: 1461174840000,\n    open: 56.04,\n    high: 56.05,\n    low: 56.03,\n    close: 56.03,\n    volume: 39587,\n  },\n  {\n    date: 1461174900000,\n    open: 56.035,\n    high: 56.05,\n    low: 56.02,\n    close: 56.035,\n    volume: 42901,\n  },\n  {\n    date: 1461174960000,\n    open: 56.035,\n    high: 56.05,\n    low: 56.03,\n    close: 56.035,\n    volume: 27129,\n  },\n  {\n    date: 1461175020000,\n    open: 56.03,\n    high: 56.05,\n    low: 56.02,\n    close: 56.035,\n    volume: 21751,\n  },\n  {\n    date: 1461175080000,\n    open: 56.03,\n    high: 56.035,\n    low: 56.01,\n    close: 56.015,\n    volume: 26766,\n  },\n  {\n    date: 1461175140000,\n    open: 56.01,\n    high: 56.02,\n    low: 56,\n    close: 56.005,\n    volume: 35957,\n  },\n  {\n    date: 1461175200000,\n    open: 56.01,\n    high: 56.02,\n    low: 56,\n    close: 56.01,\n    volume: 36083,\n  },\n  {\n    date: 1461175260000,\n    open: 56.01,\n    high: 56.01,\n    low: 55.99,\n    close: 56.005,\n    volume: 71318,\n  },\n  {\n    date: 1461175320000,\n    open: 56.005,\n    high: 56.02,\n    low: 55.99,\n    close: 55.995,\n    volume: 45462,\n  },\n  {\n    date: 1461175380000,\n    open: 55.9959,\n    high: 55.9999,\n    low: 55.97,\n    close: 55.9899,\n    volume: 39425,\n  },\n  {\n    date: 1461175440000,\n    open: 55.985,\n    high: 56.01,\n    low: 55.985,\n    close: 56,\n    volume: 49157,\n  },\n  {\n    date: 1461175500000,\n    open: 56.0001,\n    high: 56.02,\n    low: 56,\n    close: 56.01,\n    volume: 32499,\n  },\n  {\n    date: 1461175560000,\n    open: 56.015,\n    high: 56.02,\n    low: 56,\n    close: 56,\n    volume: 36354,\n  },\n  {\n    date: 1461175620000,\n    open: 56.0032,\n    high: 56.01,\n    low: 55.99,\n    close: 56,\n    volume: 60421,\n  },\n  {\n    date: 1461175680000,\n    open: 56,\n    high: 56,\n    low: 55.99,\n    close: 56,\n    volume: 35496,\n  },\n  {\n    date: 1461175740000,\n    open: 55.9974,\n    high: 56,\n    low: 55.99,\n    close: 55.995,\n    volume: 23513,\n  },\n  {\n    date: 1461175800000,\n    open: 55.995,\n    high: 56.005,\n    low: 55.98,\n    close: 56,\n    volume: 75494,\n  },\n  {\n    date: 1461175860000,\n    open: 55.995,\n    high: 56.01,\n    low: 55.99,\n    close: 55.99,\n    volume: 59751,\n  },\n  {\n    date: 1461175920000,\n    open: 55.99,\n    high: 56,\n    low: 55.99,\n    close: 55.995,\n    volume: 55027,\n  },\n  {\n    date: 1461175980000,\n    open: 55.9999,\n    high: 56.005,\n    low: 55.99,\n    close: 55.995,\n    volume: 52885,\n  },\n  {\n    date: 1461176040000,\n    open: 56,\n    high: 56,\n    low: 55.99,\n    close: 55.99,\n    volume: 38682,\n  },\n  {\n    date: 1461176100000,\n    open: 56,\n    high: 56,\n    low: 55.99,\n    close: 56,\n    volume: 55795,\n  },\n  {\n    date: 1461176160000,\n    open: 56,\n    high: 56,\n    low: 55.99,\n    close: 55.9953,\n    volume: 107195,\n  },\n  {\n    date: 1461176220000,\n    open: 55.995,\n    high: 56.005,\n    low: 55.99,\n    close: 55.995,\n    volume: 96075,\n  },\n  {\n    date: 1461176280000,\n    open: 56,\n    high: 56.015,\n    low: 55.9929,\n    close: 55.995,\n    volume: 147841,\n  },\n  {\n    date: 1461176340000,\n    open: 55.9965,\n    high: 56,\n    low: 55.99,\n    close: 55.995,\n    volume: 38981,\n  },\n  {\n    date: 1461176400000,\n    open: 56,\n    high: 56.03,\n    low: 55.9901,\n    close: 56.02,\n    volume: 135413,\n  },\n  {\n    date: 1461176460000,\n    open: 56.015,\n    high: 56.03,\n    low: 56,\n    close: 56.0264,\n    volume: 20646,\n  },\n  {\n    date: 1461176520000,\n    open: 56.03,\n    high: 56.1,\n    low: 56.03,\n    close: 56.0901,\n    volume: 54048,\n  },\n  {\n    date: 1461176580000,\n    open: 56.095,\n    high: 56.105,\n    low: 56.085,\n    close: 56.1,\n    volume: 107865,\n  },\n  {\n    date: 1461176640000,\n    open: 56.095,\n    high: 56.11,\n    low: 56.06,\n    close: 56.065,\n    volume: 117314,\n  },\n  {\n    date: 1461176700000,\n    open: 56.0662,\n    high: 56.07,\n    low: 56.025,\n    close: 56.045,\n    volume: 120466,\n  },\n  {\n    date: 1461176760000,\n    open: 56.05,\n    high: 56.05,\n    low: 56.02,\n    close: 56.035,\n    volume: 69025,\n  },\n  {\n    date: 1461176820000,\n    open: 56.04,\n    high: 56.04,\n    low: 55.995,\n    close: 56.005,\n    volume: 131048,\n  },\n  {\n    date: 1461176880000,\n    open: 56.008,\n    high: 56.02,\n    low: 55.99,\n    close: 56.02,\n    volume: 53525,\n  },\n  {\n    date: 1461176940000,\n    open: 56.01,\n    high: 56.01,\n    low: 55.98,\n    close: 55.995,\n    volume: 48961,\n  },\n  {\n    date: 1461177000000,\n    open: 55.995,\n    high: 56.02,\n    low: 55.9932,\n    close: 56.02,\n    volume: 41443,\n  },\n  {\n    date: 1461177060000,\n    open: 56.02,\n    high: 56.05,\n    low: 56.01,\n    close: 56.035,\n    volume: 56776,\n  },\n  {\n    date: 1461177120000,\n    open: 56.04,\n    high: 56.05,\n    low: 56.015,\n    close: 56.025,\n    volume: 63097,\n  },\n  {\n    date: 1461177180000,\n    open: 56.0263,\n    high: 56.04,\n    low: 56.02,\n    close: 56.0268,\n    volume: 66473,\n  },\n  {\n    date: 1461177240000,\n    open: 56.03,\n    high: 56.04,\n    low: 55.98,\n    close: 56.005,\n    volume: 130889,\n  },\n  {\n    date: 1461177300000,\n    open: 56.01,\n    high: 56.01,\n    low: 55.99,\n    close: 55.995,\n    volume: 104269,\n  },\n  {\n    date: 1461177360000,\n    open: 55.995,\n    high: 56,\n    low: 55.97,\n    close: 55.975,\n    volume: 265926,\n  },\n  {\n    date: 1461177420000,\n    open: 55.98,\n    high: 56,\n    low: 55.975,\n    close: 55.995,\n    volume: 82133,\n  },\n  {\n    date: 1461177480000,\n    open: 56,\n    high: 56,\n    low: 55.98,\n    close: 55.985,\n    volume: 79856,\n  },\n  {\n    date: 1461177540000,\n    open: 55.984,\n    high: 55.99,\n    low: 55.98,\n    close: 55.985,\n    volume: 44153,\n  },\n  {\n    date: 1461177600000,\n    open: 55.985,\n    high: 56.02,\n    low: 55.98,\n    close: 56.01,\n    volume: 78484,\n  },\n  {\n    date: 1461177660000,\n    open: 56,\n    high: 56.01,\n    low: 55.99,\n    close: 56,\n    volume: 81828,\n  },\n  {\n    date: 1461177720000,\n    open: 56.0028,\n    high: 56.045,\n    low: 55.9936,\n    close: 56.025,\n    volume: 84556,\n  },\n  {\n    date: 1461177780000,\n    open: 56.025,\n    high: 56.05,\n    low: 56.02,\n    close: 56.045,\n    volume: 40240,\n  },\n  {\n    date: 1461177840000,\n    open: 56.0475,\n    high: 56.05,\n    low: 56.04,\n    close: 56.045,\n    volume: 32870,\n  },\n  {\n    date: 1461177900000,\n    open: 56.04,\n    high: 56.05,\n    low: 56.02,\n    close: 56.02,\n    volume: 35162,\n  },\n  {\n    date: 1461177960000,\n    open: 56.025,\n    high: 56.04,\n    low: 56.01,\n    close: 56.01,\n    volume: 39869,\n  },\n  {\n    date: 1461178020000,\n    open: 56.02,\n    high: 56.03,\n    low: 56.01,\n    close: 56.015,\n    volume: 51847,\n  },\n  {\n    date: 1461178080000,\n    open: 56.01,\n    high: 56.01,\n    low: 55.98,\n    close: 55.985,\n    volume: 101329,\n  },\n  {\n    date: 1461178140000,\n    open: 55.985,\n    high: 56,\n    low: 55.98,\n    close: 55.985,\n    volume: 98152,\n  },\n  {\n    date: 1461178200000,\n    open: 55.9832,\n    high: 55.99,\n    low: 55.98,\n    close: 55.985,\n    volume: 16829,\n  },\n  {\n    date: 1461178260000,\n    open: 55.989,\n    high: 56.01,\n    low: 55.98,\n    close: 56,\n    volume: 134433,\n  },\n  {\n    date: 1461178320000,\n    open: 56,\n    high: 56,\n    low: 55.98,\n    close: 55.985,\n    volume: 95983,\n  },\n  {\n    date: 1461178380000,\n    open: 55.985,\n    high: 56,\n    low: 55.98,\n    close: 55.98,\n    volume: 80116,\n  },\n  {\n    date: 1461178440000,\n    open: 55.9836,\n    high: 55.99,\n    low: 55.95,\n    close: 55.95,\n    volume: 62342,\n  },\n  {\n    date: 1461178500000,\n    open: 55.95,\n    high: 55.96,\n    low: 55.95,\n    close: 55.955,\n    volume: 46995,\n  },\n  {\n    date: 1461178560000,\n    open: 55.9505,\n    high: 55.98,\n    low: 55.95,\n    close: 55.97,\n    volume: 38268,\n  },\n  {\n    date: 1461178620000,\n    open: 55.975,\n    high: 55.985,\n    low: 55.96,\n    close: 55.965,\n    volume: 57285,\n  },\n  {\n    date: 1461178680000,\n    open: 55.96,\n    high: 55.97,\n    low: 55.87,\n    close: 55.875,\n    volume: 182554,\n  },\n  {\n    date: 1461178740000,\n    open: 55.9,\n    high: 55.93,\n    low: 55.89,\n    close: 55.9264,\n    volume: 117582,\n  },\n  {\n    date: 1461178800000,\n    open: 55.92,\n    high: 55.93,\n    low: 55.89,\n    close: 55.93,\n    volume: 115230,\n  },\n  {\n    date: 1461178860000,\n    open: 55.925,\n    high: 56,\n    low: 55.925,\n    close: 56,\n    volume: 68555,\n  },\n  {\n    date: 1461178920000,\n    open: 55.995,\n    high: 56.005,\n    low: 55.98,\n    close: 55.9864,\n    volume: 123366,\n  },\n  {\n    date: 1461178980000,\n    open: 55.98,\n    high: 56,\n    low: 55.965,\n    close: 55.99,\n    volume: 122891,\n  },\n  {\n    date: 1461179040000,\n    open: 55.985,\n    high: 56.0099,\n    low: 55.984,\n    close: 56.005,\n    volume: 58665,\n  },\n  {\n    date: 1461179100000,\n    open: 56.0001,\n    high: 56.005,\n    low: 55.98,\n    close: 56.005,\n    volume: 82941,\n  },\n  {\n    date: 1461179160000,\n    open: 56.005,\n    high: 56.01,\n    low: 55.98,\n    close: 55.9864,\n    volume: 72680,\n  },\n  {\n    date: 1461179220000,\n    open: 55.985,\n    high: 56.01,\n    low: 55.985,\n    close: 56.0066,\n    volume: 37874,\n  },\n  {\n    date: 1461179280000,\n    open: 56.005,\n    high: 56.03,\n    low: 56,\n    close: 56,\n    volume: 98964,\n  },\n  {\n    date: 1461179340000,\n    open: 56.0099,\n    high: 56.01,\n    low: 55.9805,\n    close: 55.9939,\n    volume: 63755,\n  },\n  {\n    date: 1461179400000,\n    open: 55.9901,\n    high: 56.0075,\n    low: 55.99,\n    close: 56.005,\n    volume: 44962,\n  },\n  {\n    date: 1461179460000,\n    open: 56,\n    high: 56.02,\n    low: 56,\n    close: 56.01,\n    volume: 29923,\n  },\n  {\n    date: 1461179520000,\n    open: 56.0128,\n    high: 56.015,\n    low: 55.94,\n    close: 55.975,\n    volume: 129149,\n  },\n  {\n    date: 1461179580000,\n    open: 55.98,\n    high: 55.98,\n    low: 55.94,\n    close: 55.95,\n    volume: 65913,\n  },\n  {\n    date: 1461179640000,\n    open: 55.95,\n    high: 55.96,\n    low: 55.92,\n    close: 55.94,\n    volume: 110265,\n  },\n  {\n    date: 1461179700000,\n    open: 55.95,\n    high: 55.96,\n    low: 55.935,\n    close: 55.935,\n    volume: 40519,\n  },\n  {\n    date: 1461179760000,\n    open: 55.94,\n    high: 55.945,\n    low: 55.89,\n    close: 55.9,\n    volume: 117821,\n  },\n  {\n    date: 1461179820000,\n    open: 55.905,\n    high: 55.91,\n    low: 55.84,\n    close: 55.85,\n    volume: 102122,\n  },\n  {\n    date: 1461179880000,\n    open: 55.845,\n    high: 55.87,\n    low: 55.8,\n    close: 55.8,\n    volume: 270141,\n  },\n  {\n    date: 1461179940000,\n    open: 55.81,\n    high: 55.876,\n    low: 55.805,\n    close: 55.865,\n    volume: 94374,\n  },\n  {\n    date: 1461180000000,\n    open: 55.86,\n    high: 55.86,\n    low: 55.815,\n    close: 55.83,\n    volume: 82942,\n  },\n  {\n    date: 1461180060000,\n    open: 55.83,\n    high: 55.83,\n    low: 55.8,\n    close: 55.8162,\n    volume: 83895,\n  },\n  {\n    date: 1461180120000,\n    open: 55.81,\n    high: 55.82,\n    low: 55.79,\n    close: 55.8099,\n    volume: 66906,\n  },\n  {\n    date: 1461180180000,\n    open: 55.8,\n    high: 55.815,\n    low: 55.79,\n    close: 55.81,\n    volume: 84983,\n  },\n  {\n    date: 1461180240000,\n    open: 55.815,\n    high: 55.83,\n    low: 55.8,\n    close: 55.83,\n    volume: 88494,\n  },\n  {\n    date: 1461180300000,\n    open: 55.825,\n    high: 55.85,\n    low: 55.82,\n    close: 55.83,\n    volume: 83504,\n  },\n  {\n    date: 1461180360000,\n    open: 55.84,\n    high: 55.84,\n    low: 55.82,\n    close: 55.83,\n    volume: 48743,\n  },\n  {\n    date: 1461180420000,\n    open: 55.835,\n    high: 55.86,\n    low: 55.835,\n    close: 55.845,\n    volume: 87067,\n  },\n  {\n    date: 1461180480000,\n    open: 55.845,\n    high: 55.86,\n    low: 55.83,\n    close: 55.85,\n    volume: 58691,\n  },\n  {\n    date: 1461180540000,\n    open: 55.854,\n    high: 55.87,\n    low: 55.83,\n    close: 55.835,\n    volume: 59300,\n  },\n  {\n    date: 1461180600000,\n    open: 55.84,\n    high: 55.84,\n    low: 55.78,\n    close: 55.78,\n    volume: 127204,\n  },\n  {\n    date: 1461180660000,\n    open: 55.785,\n    high: 55.82,\n    low: 55.78,\n    close: 55.795,\n    volume: 165652,\n  },\n  {\n    date: 1461180720000,\n    open: 55.8,\n    high: 55.805,\n    low: 55.78,\n    close: 55.79,\n    volume: 93393,\n  },\n  {\n    date: 1461180780000,\n    open: 55.79,\n    high: 55.9,\n    low: 55.71,\n    close: 55.725,\n    volume: 345336,\n  },\n  {\n    date: 1461180840000,\n    open: 55.73,\n    high: 55.73,\n    low: 55.67,\n    close: 55.685,\n    volume: 317205,\n  },\n  {\n    date: 1461180900000,\n    open: 55.686,\n    high: 55.7,\n    low: 55.68,\n    close: 55.6901,\n    volume: 135570,\n  },\n  {\n    date: 1461180960000,\n    open: 55.6999,\n    high: 55.7,\n    low: 55.68,\n    close: 55.68,\n    volume: 168583,\n  },\n  {\n    date: 1461181020000,\n    open: 55.68,\n    high: 55.695,\n    low: 55.63,\n    close: 55.6336,\n    volume: 246287,\n  },\n  {\n    date: 1461181080000,\n    open: 55.64,\n    high: 55.68,\n    low: 55.63,\n    close: 55.645,\n    volume: 167430,\n  },\n  {\n    date: 1461181140000,\n    open: 55.65,\n    high: 55.65,\n    low: 55.58,\n    close: 55.595,\n    volume: 281465,\n  },\n  {\n    date: 1461181200000,\n    open: 55.59,\n    high: 55.605,\n    low: 55.56,\n    close: 55.57,\n    volume: 174274,\n  },\n  {\n    date: 1461181260000,\n    open: 55.58,\n    high: 55.6,\n    low: 55.565,\n    close: 55.57,\n    volume: 145470,\n  },\n  {\n    date: 1461181320000,\n    open: 55.565,\n    high: 55.59,\n    low: 55.55,\n    close: 55.57,\n    volume: 101179,\n  },\n  {\n    date: 1461181380000,\n    open: 55.57,\n    high: 55.6,\n    low: 55.55,\n    close: 55.59,\n    volume: 117354,\n  },\n  {\n    date: 1461181440000,\n    open: 55.595,\n    high: 55.6064,\n    low: 55.54,\n    close: 55.55,\n    volume: 172688,\n  },\n  {\n    date: 1461181500000,\n    open: 55.54,\n    high: 55.54,\n    low: 55.49,\n    close: 55.49,\n    volume: 170450,\n  },\n  {\n    date: 1461181560000,\n    open: 55.495,\n    high: 55.51,\n    low: 55.49,\n    close: 55.505,\n    volume: 551623,\n  },\n  {\n    date: 1461181620000,\n    open: 55.51,\n    high: 55.54,\n    low: 55.5,\n    close: 55.535,\n    volume: 135578,\n  },\n  {\n    date: 1461181680000,\n    open: 55.535,\n    high: 55.54,\n    low: 55.5,\n    close: 55.53,\n    volume: 190103,\n  },\n  {\n    date: 1461181740000,\n    open: 55.53,\n    high: 55.59,\n    low: 55.495,\n    close: 55.5705,\n    volume: 179830,\n  },\n  {\n    date: 1461181800000,\n    open: 55.57,\n    high: 55.58,\n    low: 55.51,\n    close: 55.52,\n    volume: 111026,\n  },\n  {\n    date: 1461181860000,\n    open: 55.52,\n    high: 55.55,\n    low: 55.5,\n    close: 55.524,\n    volume: 212081,\n  },\n  {\n    date: 1461181920000,\n    open: 55.52,\n    high: 55.53,\n    low: 55.49,\n    close: 55.505,\n    volume: 358237,\n  },\n  {\n    date: 1461181980000,\n    open: 55.51,\n    high: 55.51,\n    low: 55.49,\n    close: 55.505,\n    volume: 296595,\n  },\n  {\n    date: 1461182040000,\n    open: 55.505,\n    high: 55.51,\n    low: 55.49,\n    close: 55.5,\n    volume: 185108,\n  },\n  {\n    date: 1461182100000,\n    open: 55.5,\n    high: 55.5,\n    low: 55.485,\n    close: 55.5,\n    volume: 193689,\n  },\n  {\n    date: 1461182160000,\n    open: 55.49,\n    high: 55.56,\n    low: 55.49,\n    close: 55.55,\n    volume: 617918,\n  },\n  {\n    date: 1461182220000,\n    open: 55.55,\n    high: 55.63,\n    low: 55.54,\n    close: 55.595,\n    volume: 374023,\n  },\n  {\n    date: 1461182280000,\n    open: 55.6,\n    high: 55.63,\n    low: 55.59,\n    close: 55.6199,\n    volume: 175786,\n  },\n  {\n    date: 1461182340000,\n    open: 55.62,\n    high: 55.63,\n    low: 55.6,\n    close: 55.615,\n    volume: 271159,\n  },\n  {\n    date: 1461182400000,\n    open: 55.615,\n    high: 55.63,\n    low: 55.55,\n    close: 55.59,\n    volume: 1837931,\n  },\n  {\n    date: 1461245400000,\n    open: 55.8,\n    high: 55.8,\n    low: 55.57,\n    close: 55.68,\n    volume: 394608,\n  },\n  {\n    date: 1461245460000,\n    open: 55.62,\n    high: 55.78,\n    low: 55.61,\n    close: 55.67,\n    volume: 141305,\n  },\n  {\n    date: 1461245520000,\n    open: 55.67,\n    high: 55.74,\n    low: 55.58,\n    close: 55.69,\n    volume: 217016,\n  },\n  {\n    date: 1461245580000,\n    open: 55.68,\n    high: 55.75,\n    low: 55.68,\n    close: 55.75,\n    volume: 83016,\n  },\n  {\n    date: 1461245640000,\n    open: 55.75,\n    high: 55.8,\n    low: 55.73,\n    close: 55.77,\n    volume: 64766,\n  },\n  {\n    date: 1461245700000,\n    open: 55.77,\n    high: 55.88,\n    low: 55.77,\n    close: 55.865,\n    volume: 96922,\n  },\n  {\n    date: 1461245760000,\n    open: 55.865,\n    high: 55.89,\n    low: 55.83,\n    close: 55.88,\n    volume: 149103,\n  },\n  {\n    date: 1461245820000,\n    open: 55.89,\n    high: 55.92,\n    low: 55.835,\n    close: 55.855,\n    volume: 106536,\n  },\n  {\n    date: 1461245880000,\n    open: 55.84,\n    high: 55.9,\n    low: 55.82,\n    close: 55.9,\n    volume: 139417,\n  },\n  {\n    date: 1461245940000,\n    open: 55.91,\n    high: 55.92,\n    low: 55.865,\n    close: 55.88,\n    volume: 109358,\n  },\n  {\n    date: 1461246000000,\n    open: 55.883,\n    high: 55.98,\n    low: 55.883,\n    close: 55.9298,\n    volume: 131984,\n  },\n  {\n    date: 1461246060000,\n    open: 55.925,\n    high: 55.935,\n    low: 55.87,\n    close: 55.9,\n    volume: 108244,\n  },\n  {\n    date: 1461246120000,\n    open: 55.895,\n    high: 55.97,\n    low: 55.895,\n    close: 55.93,\n    volume: 147380,\n  },\n  {\n    date: 1461246180000,\n    open: 55.9334,\n    high: 56.01,\n    low: 55.92,\n    close: 56.005,\n    volume: 138520,\n  },\n  {\n    date: 1461246240000,\n    open: 56.005,\n    high: 56.01,\n    low: 55.96,\n    close: 55.97,\n    volume: 68712,\n  },\n  {\n    date: 1461246300000,\n    open: 55.965,\n    high: 55.97,\n    low: 55.905,\n    close: 55.95,\n    volume: 68578,\n  },\n  {\n    date: 1461246360000,\n    open: 55.95,\n    high: 55.955,\n    low: 55.91,\n    close: 55.9241,\n    volume: 131194,\n  },\n  {\n    date: 1461246420000,\n    open: 55.93,\n    high: 55.93,\n    low: 55.87,\n    close: 55.89,\n    volume: 181244,\n  },\n  {\n    date: 1461246480000,\n    open: 55.89,\n    high: 55.9,\n    low: 55.795,\n    close: 55.795,\n    volume: 775871,\n  },\n  {\n    date: 1461246540000,\n    open: 55.795,\n    high: 55.8,\n    low: 55.705,\n    close: 55.72,\n    volume: 176953,\n  },\n  {\n    date: 1461246600000,\n    open: 55.72,\n    high: 55.73,\n    low: 55.64,\n    close: 55.64,\n    volume: 229244,\n  },\n  {\n    date: 1461246660000,\n    open: 55.65,\n    high: 55.65,\n    low: 55.5699,\n    close: 55.58,\n    volume: 242726,\n  },\n  {\n    date: 1461246720000,\n    open: 55.58,\n    high: 55.61,\n    low: 55.57,\n    close: 55.6,\n    volume: 84502,\n  },\n  {\n    date: 1461246780000,\n    open: 55.609,\n    high: 55.61,\n    low: 55.49,\n    close: 55.495,\n    volume: 217634,\n  },\n  {\n    date: 1461246840000,\n    open: 55.49,\n    high: 55.525,\n    low: 55.47,\n    close: 55.5063,\n    volume: 191519,\n  },\n  {\n    date: 1461246900000,\n    open: 55.505,\n    high: 55.538,\n    low: 55.5,\n    close: 55.51,\n    volume: 68235,\n  },\n  {\n    date: 1461246960000,\n    open: 55.51,\n    high: 55.52,\n    low: 55.415,\n    close: 55.445,\n    volume: 145492,\n  },\n  {\n    date: 1461247020000,\n    open: 55.445,\n    high: 55.48,\n    low: 55.42,\n    close: 55.455,\n    volume: 80729,\n  },\n  {\n    date: 1461247080000,\n    open: 55.455,\n    high: 55.54,\n    low: 55.45,\n    close: 55.535,\n    volume: 51016,\n  },\n  {\n    date: 1461247140000,\n    open: 55.535,\n    high: 55.57,\n    low: 55.53,\n    close: 55.56,\n    volume: 64206,\n  },\n  {\n    date: 1461247200000,\n    open: 55.55,\n    high: 55.55,\n    low: 55.5,\n    close: 55.51,\n    volume: 90864,\n  },\n  {\n    date: 1461247260000,\n    open: 55.505,\n    high: 55.54,\n    low: 55.5,\n    close: 55.515,\n    volume: 86736,\n  },\n  {\n    date: 1461247320000,\n    open: 55.52,\n    high: 55.615,\n    low: 55.5101,\n    close: 55.605,\n    volume: 112084,\n  },\n  {\n    date: 1461247380000,\n    open: 55.62,\n    high: 55.63,\n    low: 55.585,\n    close: 55.6,\n    volume: 39177,\n  },\n  {\n    date: 1461247440000,\n    open: 55.5962,\n    high: 55.6,\n    low: 55.57,\n    close: 55.58,\n    volume: 84970,\n  },\n  {\n    date: 1461247500000,\n    open: 55.58,\n    high: 55.59,\n    low: 55.57,\n    close: 55.575,\n    volume: 71818,\n  },\n  {\n    date: 1461247560000,\n    open: 55.575,\n    high: 55.61,\n    low: 55.5578,\n    close: 55.61,\n    volume: 155135,\n  },\n  {\n    date: 1461247620000,\n    open: 55.605,\n    high: 55.62,\n    low: 55.585,\n    close: 55.6,\n    volume: 59065,\n  },\n  {\n    date: 1461247680000,\n    open: 55.6,\n    high: 55.67,\n    low: 55.59,\n    close: 55.66,\n    volume: 135049,\n  },\n  {\n    date: 1461247740000,\n    open: 55.67,\n    high: 55.7501,\n    low: 55.66,\n    close: 55.6899,\n    volume: 131528,\n  },\n  {\n    date: 1461247800000,\n    open: 55.6862,\n    high: 55.74,\n    low: 55.685,\n    close: 55.715,\n    volume: 110709,\n  },\n  {\n    date: 1461247860000,\n    open: 55.71,\n    high: 55.725,\n    low: 55.705,\n    close: 55.715,\n    volume: 67443,\n  },\n  {\n    date: 1461247920000,\n    open: 55.715,\n    high: 55.715,\n    low: 55.595,\n    close: 55.605,\n    volume: 183903,\n  },\n  {\n    date: 1461247980000,\n    open: 55.61,\n    high: 55.64,\n    low: 55.565,\n    close: 55.635,\n    volume: 109718,\n  },\n  {\n    date: 1461248040000,\n    open: 55.6305,\n    high: 55.64,\n    low: 55.61,\n    close: 55.625,\n    volume: 43534,\n  },\n  {\n    date: 1461248100000,\n    open: 55.6235,\n    high: 55.66,\n    low: 55.62,\n    close: 55.6599,\n    volume: 82212,\n  },\n  {\n    date: 1461248160000,\n    open: 55.655,\n    high: 55.655,\n    low: 55.6,\n    close: 55.604,\n    volume: 70935,\n  },\n  {\n    date: 1461248220000,\n    open: 55.61,\n    high: 55.64,\n    low: 55.58,\n    close: 55.595,\n    volume: 73409,\n  },\n  {\n    date: 1461248280000,\n    open: 55.59,\n    high: 55.595,\n    low: 55.54,\n    close: 55.54,\n    volume: 56183,\n  },\n  {\n    date: 1461248340000,\n    open: 55.545,\n    high: 55.56,\n    low: 55.51,\n    close: 55.5538,\n    volume: 89783,\n  },\n  {\n    date: 1461248400000,\n    open: 55.555,\n    high: 55.62,\n    low: 55.545,\n    close: 55.62,\n    volume: 78668,\n  },\n  {\n    date: 1461248460000,\n    open: 55.615,\n    high: 55.64,\n    low: 55.61,\n    close: 55.62,\n    volume: 71413,\n  },\n  {\n    date: 1461248520000,\n    open: 55.615,\n    high: 55.655,\n    low: 55.61,\n    close: 55.6501,\n    volume: 144162,\n  },\n  {\n    date: 1461248580000,\n    open: 55.66,\n    high: 55.66,\n    low: 55.59,\n    close: 55.63,\n    volume: 112863,\n  },\n  {\n    date: 1461248640000,\n    open: 55.625,\n    high: 55.65,\n    low: 55.625,\n    close: 55.65,\n    volume: 33921,\n  },\n  {\n    date: 1461248700000,\n    open: 55.66,\n    high: 55.66,\n    low: 55.62,\n    close: 55.63,\n    volume: 52820,\n  },\n  {\n    date: 1461248760000,\n    open: 55.63,\n    high: 55.65,\n    low: 55.63,\n    close: 55.63,\n    volume: 69133,\n  },\n  {\n    date: 1461248820000,\n    open: 55.63,\n    high: 55.655,\n    low: 55.625,\n    close: 55.64,\n    volume: 62336,\n  },\n  {\n    date: 1461248880000,\n    open: 55.65,\n    high: 55.72,\n    low: 55.645,\n    close: 55.695,\n    volume: 55319,\n  },\n  {\n    date: 1461248940000,\n    open: 55.6988,\n    high: 55.7,\n    low: 55.675,\n    close: 55.69,\n    volume: 43721,\n  },\n  {\n    date: 1461249000000,\n    open: 55.695,\n    high: 55.7298,\n    low: 55.69,\n    close: 55.7,\n    volume: 62250,\n  },\n  {\n    date: 1461249060000,\n    open: 55.705,\n    high: 55.75,\n    low: 55.69,\n    close: 55.7,\n    volume: 65046,\n  },\n  {\n    date: 1461249120000,\n    open: 55.6972,\n    high: 55.71,\n    low: 55.69,\n    close: 55.695,\n    volume: 37223,\n  },\n  {\n    date: 1461249180000,\n    open: 55.7,\n    high: 55.715,\n    low: 55.69,\n    close: 55.71,\n    volume: 45710,\n  },\n  {\n    date: 1461249240000,\n    open: 55.715,\n    high: 55.72,\n    low: 55.69,\n    close: 55.715,\n    volume: 47566,\n  },\n  {\n    date: 1461249300000,\n    open: 55.71,\n    high: 55.71,\n    low: 55.66,\n    close: 55.71,\n    volume: 52292,\n  },\n  {\n    date: 1461249360000,\n    open: 55.71,\n    high: 55.7499,\n    low: 55.71,\n    close: 55.74,\n    volume: 45578,\n  },\n  {\n    date: 1461249420000,\n    open: 55.75,\n    high: 55.785,\n    low: 55.74,\n    close: 55.775,\n    volume: 74976,\n  },\n  {\n    date: 1461249480000,\n    open: 55.77,\n    high: 55.8,\n    low: 55.72,\n    close: 55.7378,\n    volume: 80686,\n  },\n  {\n    date: 1461249540000,\n    open: 55.74,\n    high: 55.805,\n    low: 55.73,\n    close: 55.7844,\n    volume: 150947,\n  },\n  {\n    date: 1461249600000,\n    open: 55.79,\n    high: 55.85,\n    low: 55.79,\n    close: 55.84,\n    volume: 77347,\n  },\n  {\n    date: 1461249660000,\n    open: 55.85,\n    high: 55.955,\n    low: 55.84,\n    close: 55.955,\n    volume: 97513,\n  },\n  {\n    date: 1461249720000,\n    open: 55.95,\n    high: 55.97,\n    low: 55.9,\n    close: 55.925,\n    volume: 81231,\n  },\n  {\n    date: 1461249780000,\n    open: 55.93,\n    high: 56,\n    low: 55.925,\n    close: 55.995,\n    volume: 43332,\n  },\n  {\n    date: 1461249840000,\n    open: 56,\n    high: 56.03,\n    low: 55.96,\n    close: 55.97,\n    volume: 76708,\n  },\n  {\n    date: 1461249900000,\n    open: 55.965,\n    high: 55.967,\n    low: 55.9,\n    close: 55.91,\n    volume: 80585,\n  },\n  {\n    date: 1461249960000,\n    open: 55.91,\n    high: 55.955,\n    low: 55.9,\n    close: 55.95,\n    volume: 52528,\n  },\n  {\n    date: 1461250020000,\n    open: 55.95,\n    high: 55.9765,\n    low: 55.9401,\n    close: 55.95,\n    volume: 51379,\n  },\n  {\n    date: 1461250080000,\n    open: 55.95,\n    high: 55.97,\n    low: 55.95,\n    close: 55.95,\n    volume: 42724,\n  },\n  {\n    date: 1461250140000,\n    open: 55.95,\n    high: 55.96,\n    low: 55.9499,\n    close: 55.955,\n    volume: 33843,\n  },\n  {\n    date: 1461250200000,\n    open: 55.955,\n    high: 55.97,\n    low: 55.94,\n    close: 55.955,\n    volume: 62949,\n  },\n  {\n    date: 1461250260000,\n    open: 55.96,\n    high: 55.98,\n    low: 55.95,\n    close: 55.961,\n    volume: 46611,\n  },\n  {\n    date: 1461250320000,\n    open: 55.965,\n    high: 55.9798,\n    low: 55.94,\n    close: 55.9798,\n    volume: 96018,\n  },\n  {\n    date: 1461250380000,\n    open: 55.98,\n    high: 56.005,\n    low: 55.97,\n    close: 56,\n    volume: 86256,\n  },\n  {\n    date: 1461250440000,\n    open: 56,\n    high: 56.01,\n    low: 55.97,\n    close: 55.99,\n    volume: 43681,\n  },\n  {\n    date: 1461250500000,\n    open: 55.99,\n    high: 56.009,\n    low: 55.9775,\n    close: 55.995,\n    volume: 45996,\n  },\n  {\n    date: 1461250560000,\n    open: 56,\n    high: 56.02,\n    low: 55.995,\n    close: 56.01,\n    volume: 68503,\n  },\n  {\n    date: 1461250620000,\n    open: 56.014,\n    high: 56.1,\n    low: 56.01,\n    close: 56.09,\n    volume: 80717,\n  },\n  {\n    date: 1461250680000,\n    open: 56.09,\n    high: 56.115,\n    low: 56.07,\n    close: 56.095,\n    volume: 41859,\n  },\n  {\n    date: 1461250740000,\n    open: 56.095,\n    high: 56.11,\n    low: 56.03,\n    close: 56.035,\n    volume: 77287,\n  },\n  {\n    date: 1461250800000,\n    open: 56.03,\n    high: 56.065,\n    low: 56.01,\n    close: 56.05,\n    volume: 59225,\n  },\n  {\n    date: 1461250860000,\n    open: 56.05,\n    high: 56.07,\n    low: 56.03,\n    close: 56.055,\n    volume: 73655,\n  },\n  {\n    date: 1461250920000,\n    open: 56.055,\n    high: 56.15,\n    low: 56.055,\n    close: 56.13,\n    volume: 204758,\n  },\n  {\n    date: 1461250980000,\n    open: 56.13,\n    high: 56.14,\n    low: 56.09,\n    close: 56.13,\n    volume: 168745,\n  },\n  {\n    date: 1461251040000,\n    open: 56.13,\n    high: 56.15,\n    low: 56.1,\n    close: 56.1,\n    volume: 140785,\n  },\n  {\n    date: 1461251100000,\n    open: 56.109,\n    high: 56.12,\n    low: 56.09,\n    close: 56.105,\n    volume: 76646,\n  },\n  {\n    date: 1461251160000,\n    open: 56.105,\n    high: 56.12,\n    low: 56.095,\n    close: 56.1,\n    volume: 162132,\n  },\n  {\n    date: 1461251220000,\n    open: 56.092,\n    high: 56.095,\n    low: 56.05,\n    close: 56.055,\n    volume: 49583,\n  },\n  {\n    date: 1461251280000,\n    open: 56.055,\n    high: 56.07,\n    low: 56.045,\n    close: 56.06,\n    volume: 65826,\n  },\n  {\n    date: 1461251340000,\n    open: 56.06,\n    high: 56.1,\n    low: 56.055,\n    close: 56.075,\n    volume: 57313,\n  },\n  {\n    date: 1461251400000,\n    open: 56.0701,\n    high: 56.09,\n    low: 56.055,\n    close: 56.07,\n    volume: 40083,\n  },\n  {\n    date: 1461251460000,\n    open: 56.0632,\n    high: 56.075,\n    low: 56.05,\n    close: 56.07,\n    volume: 29781,\n  },\n  {\n    date: 1461251520000,\n    open: 56.07,\n    high: 56.07,\n    low: 56.04,\n    close: 56.05,\n    volume: 48102,\n  },\n  {\n    date: 1461251580000,\n    open: 56.0525,\n    high: 56.06,\n    low: 56.045,\n    close: 56.045,\n    volume: 32933,\n  },\n  {\n    date: 1461251640000,\n    open: 56.04,\n    high: 56.04,\n    low: 56,\n    close: 56.0099,\n    volume: 101752,\n  },\n  {\n    date: 1461251700000,\n    open: 56.01,\n    high: 56.03,\n    low: 56,\n    close: 56.03,\n    volume: 40476,\n  },\n  {\n    date: 1461251760000,\n    open: 56.03,\n    high: 56.055,\n    low: 56.025,\n    close: 56.025,\n    volume: 50376,\n  },\n  {\n    date: 1461251820000,\n    open: 56.03,\n    high: 56.045,\n    low: 55.994,\n    close: 56.005,\n    volume: 94829,\n  },\n  {\n    date: 1461251880000,\n    open: 56.01,\n    high: 56.01,\n    low: 55.9701,\n    close: 55.99,\n    volume: 40753,\n  },\n  {\n    date: 1461251940000,\n    open: 55.99,\n    high: 56,\n    low: 55.97,\n    close: 55.99,\n    volume: 35290,\n  },\n  {\n    date: 1461252000000,\n    open: 55.985,\n    high: 56,\n    low: 55.98,\n    close: 56,\n    volume: 27726,\n  },\n  {\n    date: 1461252060000,\n    open: 55.995,\n    high: 56.02,\n    low: 55.99,\n    close: 56,\n    volume: 26916,\n  },\n  {\n    date: 1461252120000,\n    open: 56,\n    high: 56.04,\n    low: 55.99,\n    close: 56.03,\n    volume: 37822,\n  },\n  {\n    date: 1461252180000,\n    open: 56.035,\n    high: 56.09,\n    low: 56.03,\n    close: 56.08,\n    volume: 49490,\n  },\n  {\n    date: 1461252240000,\n    open: 56.08,\n    high: 56.1,\n    low: 56.08,\n    close: 56.085,\n    volume: 41263,\n  },\n  {\n    date: 1461252300000,\n    open: 56.0805,\n    high: 56.15,\n    low: 56.08,\n    close: 56.125,\n    volume: 83156,\n  },\n  {\n    date: 1461252360000,\n    open: 56.12,\n    high: 56.15,\n    low: 56.12,\n    close: 56.145,\n    volume: 43016,\n  },\n  {\n    date: 1461252420000,\n    open: 56.1465,\n    high: 56.19,\n    low: 56.13,\n    close: 56.19,\n    volume: 104639,\n  },\n  {\n    date: 1461252480000,\n    open: 56.185,\n    high: 56.23,\n    low: 56.15,\n    close: 56.165,\n    volume: 182747,\n  },\n  {\n    date: 1461252540000,\n    open: 56.165,\n    high: 56.1764,\n    low: 56.08,\n    close: 56.08,\n    volume: 109778,\n  },\n  {\n    date: 1461252600000,\n    open: 56.08,\n    high: 56.1099,\n    low: 56.07,\n    close: 56.1,\n    volume: 55115,\n  },\n  {\n    date: 1461252660000,\n    open: 56.105,\n    high: 56.1101,\n    low: 56.082,\n    close: 56.095,\n    volume: 17631,\n  },\n  {\n    date: 1461252720000,\n    open: 56.092,\n    high: 56.1099,\n    low: 56.06,\n    close: 56.06,\n    volume: 175284,\n  },\n  {\n    date: 1461252780000,\n    open: 56.075,\n    high: 56.075,\n    low: 55.98,\n    close: 55.98,\n    volume: 85653,\n  },\n  {\n    date: 1461252840000,\n    open: 55.98,\n    high: 55.99,\n    low: 55.97,\n    close: 55.985,\n    volume: 29236,\n  },\n  {\n    date: 1461252900000,\n    open: 55.9801,\n    high: 56,\n    low: 55.95,\n    close: 55.95,\n    volume: 56997,\n  },\n  {\n    date: 1461252960000,\n    open: 55.95,\n    high: 56,\n    low: 55.95,\n    close: 55.995,\n    volume: 100248,\n  },\n  {\n    date: 1461253020000,\n    open: 55.99,\n    high: 56.03,\n    low: 55.985,\n    close: 56.03,\n    volume: 60383,\n  },\n  {\n    date: 1461253080000,\n    open: 56.03,\n    high: 56.035,\n    low: 56.01,\n    close: 56.01,\n    volume: 26521,\n  },\n  {\n    date: 1461253140000,\n    open: 56.015,\n    high: 56.015,\n    low: 55.97,\n    close: 56.005,\n    volume: 72286,\n  },\n  {\n    date: 1461253200000,\n    open: 56.01,\n    high: 56.03,\n    low: 55.991,\n    close: 56,\n    volume: 106889,\n  },\n  {\n    date: 1461253260000,\n    open: 56.01,\n    high: 56.07,\n    low: 56,\n    close: 56.07,\n    volume: 133319,\n  },\n  {\n    date: 1461253320000,\n    open: 56.07,\n    high: 56.07,\n    low: 56.005,\n    close: 56.005,\n    volume: 38249,\n  },\n  {\n    date: 1461253380000,\n    open: 56.005,\n    high: 56.01,\n    low: 56,\n    close: 56.005,\n    volume: 27211,\n  },\n  {\n    date: 1461253440000,\n    open: 56.005,\n    high: 56.0101,\n    low: 55.975,\n    close: 56.005,\n    volume: 75044,\n  },\n  {\n    date: 1461253500000,\n    open: 56.005,\n    high: 56.055,\n    low: 56.005,\n    close: 56.055,\n    volume: 28396,\n  },\n  {\n    date: 1461253560000,\n    open: 56.055,\n    high: 56.06,\n    low: 56.0099,\n    close: 56.01,\n    volume: 54087,\n  },\n  {\n    date: 1461253620000,\n    open: 56.01,\n    high: 56.02,\n    low: 55.97,\n    close: 55.97,\n    volume: 40286,\n  },\n  {\n    date: 1461253680000,\n    open: 55.98,\n    high: 56,\n    low: 55.965,\n    close: 56,\n    volume: 46108,\n  },\n  {\n    date: 1461253740000,\n    open: 55.9901,\n    high: 56,\n    low: 55.95,\n    close: 55.95,\n    volume: 64115,\n  },\n  {\n    date: 1461253800000,\n    open: 55.95,\n    high: 55.985,\n    low: 55.92,\n    close: 55.9616,\n    volume: 89138,\n  },\n  {\n    date: 1461253860000,\n    open: 55.965,\n    high: 56.01,\n    low: 55.9646,\n    close: 56,\n    volume: 52920,\n  },\n  {\n    date: 1461253920000,\n    open: 56,\n    high: 56.02,\n    low: 55.98,\n    close: 55.99,\n    volume: 70451,\n  },\n  {\n    date: 1461253980000,\n    open: 55.985,\n    high: 56.02,\n    low: 55.98,\n    close: 56.01,\n    volume: 65213,\n  },\n  {\n    date: 1461254040000,\n    open: 56.005,\n    high: 56.0228,\n    low: 55.98,\n    close: 56.0228,\n    volume: 42019,\n  },\n  {\n    date: 1461254100000,\n    open: 56.025,\n    high: 56.04,\n    low: 56.01,\n    close: 56.02,\n    volume: 77746,\n  },\n  {\n    date: 1461254160000,\n    open: 56.01,\n    high: 56.0169,\n    low: 55.955,\n    close: 55.98,\n    volume: 48649,\n  },\n  {\n    date: 1461254220000,\n    open: 55.985,\n    high: 55.99,\n    low: 55.91,\n    close: 55.93,\n    volume: 51500,\n  },\n  {\n    date: 1461254280000,\n    open: 55.94,\n    high: 55.95,\n    low: 55.92,\n    close: 55.93,\n    volume: 125699,\n  },\n  {\n    date: 1461254340000,\n    open: 55.93,\n    high: 55.94,\n    low: 55.905,\n    close: 55.905,\n    volume: 48454,\n  },\n  {\n    date: 1461254400000,\n    open: 55.905,\n    high: 55.905,\n    low: 55.875,\n    close: 55.885,\n    volume: 29341,\n  },\n  {\n    date: 1461254460000,\n    open: 55.885,\n    high: 55.89,\n    low: 55.87,\n    close: 55.875,\n    volume: 24093,\n  },\n  {\n    date: 1461254520000,\n    open: 55.875,\n    high: 55.88,\n    low: 55.8,\n    close: 55.82,\n    volume: 48409,\n  },\n  {\n    date: 1461254580000,\n    open: 55.815,\n    high: 55.83,\n    low: 55.77,\n    close: 55.775,\n    volume: 89921,\n  },\n  {\n    date: 1461254640000,\n    open: 55.775,\n    high: 55.81,\n    low: 55.75,\n    close: 55.8,\n    volume: 107329,\n  },\n  {\n    date: 1461254700000,\n    open: 55.805,\n    high: 55.81,\n    low: 55.75,\n    close: 55.78,\n    volume: 83415,\n  },\n  {\n    date: 1461254760000,\n    open: 55.78,\n    high: 55.82,\n    low: 55.775,\n    close: 55.8125,\n    volume: 110048,\n  },\n  {\n    date: 1461254820000,\n    open: 55.815,\n    high: 55.82,\n    low: 55.79,\n    close: 55.805,\n    volume: 25390,\n  },\n  {\n    date: 1461254880000,\n    open: 55.8099,\n    high: 55.83,\n    low: 55.805,\n    close: 55.82,\n    volume: 27765,\n  },\n  {\n    date: 1461254940000,\n    open: 55.825,\n    high: 55.85,\n    low: 55.815,\n    close: 55.845,\n    volume: 32109,\n  },\n  {\n    date: 1461255000000,\n    open: 55.8483,\n    high: 55.85,\n    low: 55.83,\n    close: 55.845,\n    volume: 25247,\n  },\n  {\n    date: 1461255060000,\n    open: 55.84,\n    high: 55.845,\n    low: 55.79,\n    close: 55.795,\n    volume: 39151,\n  },\n  {\n    date: 1461255120000,\n    open: 55.79,\n    high: 55.795,\n    low: 55.7601,\n    close: 55.7601,\n    volume: 46654,\n  },\n  {\n    date: 1461255180000,\n    open: 55.76,\n    high: 55.765,\n    low: 55.74,\n    close: 55.75,\n    volume: 37652,\n  },\n  {\n    date: 1461255240000,\n    open: 55.74,\n    high: 55.74,\n    low: 55.63,\n    close: 55.6399,\n    volume: 109132,\n  },\n  {\n    date: 1461255300000,\n    open: 55.64,\n    high: 55.6571,\n    low: 55.63,\n    close: 55.645,\n    volume: 86752,\n  },\n  {\n    date: 1461255360000,\n    open: 55.645,\n    high: 55.68,\n    low: 55.64,\n    close: 55.675,\n    volume: 32382,\n  },\n  {\n    date: 1461255420000,\n    open: 55.68,\n    high: 55.7065,\n    low: 55.6701,\n    close: 55.69,\n    volume: 35223,\n  },\n  {\n    date: 1461255480000,\n    open: 55.685,\n    high: 55.705,\n    low: 55.6805,\n    close: 55.7,\n    volume: 20633,\n  },\n  {\n    date: 1461255540000,\n    open: 55.705,\n    high: 55.75,\n    low: 55.7,\n    close: 55.745,\n    volume: 37576,\n  },\n  {\n    date: 1461255600000,\n    open: 55.7455,\n    high: 55.77,\n    low: 55.74,\n    close: 55.75,\n    volume: 32691,\n  },\n  {\n    date: 1461255660000,\n    open: 55.75,\n    high: 55.755,\n    low: 55.74,\n    close: 55.7445,\n    volume: 39767,\n  },\n  {\n    date: 1461255720000,\n    open: 55.74,\n    high: 55.75,\n    low: 55.73,\n    close: 55.74,\n    volume: 149002,\n  },\n  {\n    date: 1461255780000,\n    open: 55.7399,\n    high: 55.745,\n    low: 55.71,\n    close: 55.715,\n    volume: 35026,\n  },\n  {\n    date: 1461255840000,\n    open: 55.715,\n    high: 55.73,\n    low: 55.7109,\n    close: 55.725,\n    volume: 26383,\n  },\n  {\n    date: 1461255900000,\n    open: 55.72,\n    high: 55.75,\n    low: 55.705,\n    close: 55.705,\n    volume: 35128,\n  },\n  {\n    date: 1461255960000,\n    open: 55.71,\n    high: 55.72,\n    low: 55.695,\n    close: 55.695,\n    volume: 52586,\n  },\n  {\n    date: 1461256020000,\n    open: 55.69,\n    high: 55.69,\n    low: 55.65,\n    close: 55.6625,\n    volume: 43676,\n  },\n  {\n    date: 1461256080000,\n    open: 55.665,\n    high: 55.69,\n    low: 55.665,\n    close: 55.675,\n    volume: 31197,\n  },\n  {\n    date: 1461256140000,\n    open: 55.6701,\n    high: 55.71,\n    low: 55.67,\n    close: 55.705,\n    volume: 38184,\n  },\n  {\n    date: 1461256200000,\n    open: 55.71,\n    high: 55.715,\n    low: 55.7,\n    close: 55.705,\n    volume: 25896,\n  },\n  {\n    date: 1461256260000,\n    open: 55.705,\n    high: 55.77,\n    low: 55.705,\n    close: 55.755,\n    volume: 31257,\n  },\n  {\n    date: 1461256320000,\n    open: 55.7599,\n    high: 55.79,\n    low: 55.75,\n    close: 55.79,\n    volume: 23034,\n  },\n  {\n    date: 1461256380000,\n    open: 55.79,\n    high: 55.84,\n    low: 55.7801,\n    close: 55.83,\n    volume: 29098,\n  },\n  {\n    date: 1461256440000,\n    open: 55.835,\n    high: 55.85,\n    low: 55.815,\n    close: 55.84,\n    volume: 39996,\n  },\n  {\n    date: 1461256500000,\n    open: 55.845,\n    high: 55.8822,\n    low: 55.84,\n    close: 55.88,\n    volume: 40175,\n  },\n  {\n    date: 1461256560000,\n    open: 55.88,\n    high: 55.905,\n    low: 55.87,\n    close: 55.87,\n    volume: 74395,\n  },\n  {\n    date: 1461256620000,\n    open: 55.87,\n    high: 55.87,\n    low: 55.84,\n    close: 55.8425,\n    volume: 38269,\n  },\n  {\n    date: 1461256680000,\n    open: 55.849,\n    high: 55.85,\n    low: 55.82,\n    close: 55.835,\n    volume: 28312,\n  },\n  {\n    date: 1461256740000,\n    open: 55.84,\n    high: 55.84,\n    low: 55.805,\n    close: 55.825,\n    volume: 99465,\n  },\n  {\n    date: 1461256800000,\n    open: 55.82,\n    high: 55.83,\n    low: 55.81,\n    close: 55.815,\n    volume: 43201,\n  },\n  {\n    date: 1461256860000,\n    open: 55.8101,\n    high: 55.83,\n    low: 55.81,\n    close: 55.815,\n    volume: 31374,\n  },\n  {\n    date: 1461256920000,\n    open: 55.82,\n    high: 55.87,\n    low: 55.8105,\n    close: 55.865,\n    volume: 54435,\n  },\n  {\n    date: 1461256980000,\n    open: 55.8699,\n    high: 55.87,\n    low: 55.85,\n    close: 55.86,\n    volume: 62130,\n  },\n  {\n    date: 1461257040000,\n    open: 55.855,\n    high: 55.86,\n    low: 55.81,\n    close: 55.835,\n    volume: 53192,\n  },\n  {\n    date: 1461257100000,\n    open: 55.835,\n    high: 55.865,\n    low: 55.83,\n    close: 55.855,\n    volume: 26228,\n  },\n  {\n    date: 1461257160000,\n    open: 55.86,\n    high: 55.86,\n    low: 55.82,\n    close: 55.825,\n    volume: 93669,\n  },\n  {\n    date: 1461257220000,\n    open: 55.82,\n    high: 55.84,\n    low: 55.814,\n    close: 55.83,\n    volume: 45959,\n  },\n  {\n    date: 1461257280000,\n    open: 55.835,\n    high: 55.85,\n    low: 55.82,\n    close: 55.84,\n    volume: 124813,\n  },\n  {\n    date: 1461257340000,\n    open: 55.835,\n    high: 55.84,\n    low: 55.81,\n    close: 55.815,\n    volume: 114743,\n  },\n  {\n    date: 1461257400000,\n    open: 55.8199,\n    high: 55.83,\n    low: 55.8,\n    close: 55.82,\n    volume: 232189,\n  },\n  {\n    date: 1461257460000,\n    open: 55.825,\n    high: 55.83,\n    low: 55.74,\n    close: 55.765,\n    volume: 245105,\n  },\n  {\n    date: 1461257520000,\n    open: 55.765,\n    high: 55.8,\n    low: 55.75,\n    close: 55.785,\n    volume: 78409,\n  },\n  {\n    date: 1461257580000,\n    open: 55.785,\n    high: 55.796,\n    low: 55.78,\n    close: 55.785,\n    volume: 16902,\n  },\n  {\n    date: 1461257640000,\n    open: 55.79,\n    high: 55.815,\n    low: 55.78,\n    close: 55.815,\n    volume: 26160,\n  },\n  {\n    date: 1461257700000,\n    open: 55.82,\n    high: 55.84,\n    low: 55.82,\n    close: 55.825,\n    volume: 37453,\n  },\n  {\n    date: 1461257760000,\n    open: 55.82,\n    high: 55.85,\n    low: 55.82,\n    close: 55.85,\n    volume: 44430,\n  },\n  {\n    date: 1461257820000,\n    open: 55.85,\n    high: 55.86,\n    low: 55.82,\n    close: 55.8239,\n    volume: 36728,\n  },\n  {\n    date: 1461257880000,\n    open: 55.8225,\n    high: 55.86,\n    low: 55.8225,\n    close: 55.855,\n    volume: 22171,\n  },\n  {\n    date: 1461257940000,\n    open: 55.86,\n    high: 55.9,\n    low: 55.86,\n    close: 55.89,\n    volume: 66939,\n  },\n  {\n    date: 1461258000000,\n    open: 55.89,\n    high: 55.8975,\n    low: 55.835,\n    close: 55.855,\n    volume: 56257,\n  },\n  {\n    date: 1461258060000,\n    open: 55.855,\n    high: 55.86,\n    low: 55.83,\n    close: 55.845,\n    volume: 76002,\n  },\n  {\n    date: 1461258120000,\n    open: 55.845,\n    high: 55.86,\n    low: 55.84,\n    close: 55.856,\n    volume: 75575,\n  },\n  {\n    date: 1461258180000,\n    open: 55.86,\n    high: 55.916,\n    low: 55.855,\n    close: 55.875,\n    volume: 120386,\n  },\n  {\n    date: 1461258240000,\n    open: 55.88,\n    high: 55.88,\n    low: 55.83,\n    close: 55.835,\n    volume: 79369,\n  },\n  {\n    date: 1461258300000,\n    open: 55.8371,\n    high: 55.8371,\n    low: 55.77,\n    close: 55.77,\n    volume: 92115,\n  },\n  {\n    date: 1461258360000,\n    open: 55.77,\n    high: 55.775,\n    low: 55.72,\n    close: 55.725,\n    volume: 167136,\n  },\n  {\n    date: 1461258420000,\n    open: 55.725,\n    high: 55.75,\n    low: 55.7,\n    close: 55.735,\n    volume: 55107,\n  },\n  {\n    date: 1461258480000,\n    open: 55.7399,\n    high: 55.7653,\n    low: 55.735,\n    close: 55.755,\n    volume: 30799,\n  },\n  {\n    date: 1461258540000,\n    open: 55.755,\n    high: 55.76,\n    low: 55.73,\n    close: 55.735,\n    volume: 29132,\n  },\n  {\n    date: 1461258600000,\n    open: 55.735,\n    high: 55.7499,\n    low: 55.73,\n    close: 55.7399,\n    volume: 21811,\n  },\n  {\n    date: 1461258660000,\n    open: 55.7301,\n    high: 55.76,\n    low: 55.73,\n    close: 55.755,\n    volume: 49770,\n  },\n  {\n    date: 1461258720000,\n    open: 55.76,\n    high: 55.785,\n    low: 55.72,\n    close: 55.74,\n    volume: 78120,\n  },\n  {\n    date: 1461258780000,\n    open: 55.733,\n    high: 55.775,\n    low: 55.725,\n    close: 55.775,\n    volume: 121151,\n  },\n  {\n    date: 1461258840000,\n    open: 55.77,\n    high: 55.78,\n    low: 55.75,\n    close: 55.765,\n    volume: 32873,\n  },\n  {\n    date: 1461258900000,\n    open: 55.7799,\n    high: 55.78,\n    low: 55.75,\n    close: 55.75,\n    volume: 39231,\n  },\n  {\n    date: 1461258960000,\n    open: 55.7598,\n    high: 55.7598,\n    low: 55.74,\n    close: 55.74,\n    volume: 44719,\n  },\n  {\n    date: 1461259020000,\n    open: 55.74,\n    high: 55.74,\n    low: 55.725,\n    close: 55.73,\n    volume: 42230,\n  },\n  {\n    date: 1461259080000,\n    open: 55.735,\n    high: 55.735,\n    low: 55.685,\n    close: 55.7,\n    volume: 120464,\n  },\n  {\n    date: 1461259140000,\n    open: 55.7,\n    high: 55.72,\n    low: 55.69,\n    close: 55.705,\n    volume: 79792,\n  },\n  {\n    date: 1461259200000,\n    open: 55.71,\n    high: 55.775,\n    low: 55.71,\n    close: 55.775,\n    volume: 41725,\n  },\n  {\n    date: 1461259260000,\n    open: 55.78,\n    high: 55.84,\n    low: 55.775,\n    close: 55.835,\n    volume: 74290,\n  },\n  {\n    date: 1461259320000,\n    open: 55.8399,\n    high: 55.88,\n    low: 55.83,\n    close: 55.88,\n    volume: 31914,\n  },\n  {\n    date: 1461259380000,\n    open: 55.88,\n    high: 55.89,\n    low: 55.8505,\n    close: 55.8636,\n    volume: 43445,\n  },\n  {\n    date: 1461259440000,\n    open: 55.866,\n    high: 55.87,\n    low: 55.81,\n    close: 55.81,\n    volume: 44274,\n  },\n  {\n    date: 1461259500000,\n    open: 55.8101,\n    high: 55.82,\n    low: 55.795,\n    close: 55.8198,\n    volume: 37824,\n  },\n  {\n    date: 1461259560000,\n    open: 55.82,\n    high: 55.84,\n    low: 55.8,\n    close: 55.805,\n    volume: 61072,\n  },\n  {\n    date: 1461259620000,\n    open: 55.81,\n    high: 55.82,\n    low: 55.8,\n    close: 55.815,\n    volume: 65064,\n  },\n  {\n    date: 1461259680000,\n    open: 55.82,\n    high: 55.82,\n    low: 55.745,\n    close: 55.767,\n    volume: 60566,\n  },\n  {\n    date: 1461259740000,\n    open: 55.76,\n    high: 55.76,\n    low: 55.73,\n    close: 55.745,\n    volume: 36453,\n  },\n  {\n    date: 1461259800000,\n    open: 55.75,\n    high: 55.76,\n    low: 55.72,\n    close: 55.725,\n    volume: 65190,\n  },\n  {\n    date: 1461259860000,\n    open: 55.726,\n    high: 55.795,\n    low: 55.72,\n    close: 55.75,\n    volume: 53660,\n  },\n  {\n    date: 1461259920000,\n    open: 55.75,\n    high: 55.8,\n    low: 55.75,\n    close: 55.795,\n    volume: 35941,\n  },\n  {\n    date: 1461259980000,\n    open: 55.8,\n    high: 55.81,\n    low: 55.75,\n    close: 55.75,\n    volume: 56224,\n  },\n  {\n    date: 1461260040000,\n    open: 55.76,\n    high: 55.76,\n    low: 55.725,\n    close: 55.725,\n    volume: 59347,\n  },\n  {\n    date: 1461260100000,\n    open: 55.72,\n    high: 55.75,\n    low: 55.72,\n    close: 55.735,\n    volume: 42448,\n  },\n  {\n    date: 1461260160000,\n    open: 55.73,\n    high: 55.7661,\n    low: 55.73,\n    close: 55.76,\n    volume: 52794,\n  },\n  {\n    date: 1461260220000,\n    open: 55.76,\n    high: 55.855,\n    low: 55.76,\n    close: 55.824,\n    volume: 123135,\n  },\n  {\n    date: 1461260280000,\n    open: 55.82,\n    high: 55.885,\n    low: 55.82,\n    close: 55.87,\n    volume: 74212,\n  },\n  {\n    date: 1461260340000,\n    open: 55.88,\n    high: 55.88,\n    low: 55.82,\n    close: 55.825,\n    volume: 67275,\n  },\n  {\n    date: 1461260400000,\n    open: 55.83,\n    high: 55.91,\n    low: 55.825,\n    close: 55.91,\n    volume: 38859,\n  },\n  {\n    date: 1461260460000,\n    open: 55.905,\n    high: 55.97,\n    low: 55.895,\n    close: 55.96,\n    volume: 73616,\n  },\n  {\n    date: 1461260520000,\n    open: 55.955,\n    high: 55.99,\n    low: 55.93,\n    close: 55.99,\n    volume: 61296,\n  },\n  {\n    date: 1461260580000,\n    open: 55.98,\n    high: 55.98,\n    low: 55.91,\n    close: 55.955,\n    volume: 61953,\n  },\n  {\n    date: 1461260640000,\n    open: 55.96,\n    high: 55.96,\n    low: 55.89,\n    close: 55.9,\n    volume: 55560,\n  },\n  {\n    date: 1461260700000,\n    open: 55.89,\n    high: 55.94,\n    low: 55.89,\n    close: 55.925,\n    volume: 49439,\n  },\n  {\n    date: 1461260760000,\n    open: 55.9236,\n    high: 55.94,\n    low: 55.9,\n    close: 55.905,\n    volume: 38957,\n  },\n  {\n    date: 1461260820000,\n    open: 55.91,\n    high: 55.94,\n    low: 55.9,\n    close: 55.925,\n    volume: 32540,\n  },\n  {\n    date: 1461260880000,\n    open: 55.925,\n    high: 55.925,\n    low: 55.89,\n    close: 55.89,\n    volume: 38201,\n  },\n  {\n    date: 1461260940000,\n    open: 55.89,\n    high: 55.89,\n    low: 55.86,\n    close: 55.8899,\n    volume: 60017,\n  },\n  {\n    date: 1461261000000,\n    open: 55.88,\n    high: 55.88,\n    low: 55.84,\n    close: 55.845,\n    volume: 32786,\n  },\n  {\n    date: 1461261060000,\n    open: 55.845,\n    high: 55.87,\n    low: 55.845,\n    close: 55.8661,\n    volume: 29159,\n  },\n  {\n    date: 1461261120000,\n    open: 55.87,\n    high: 55.87,\n    low: 55.85,\n    close: 55.855,\n    volume: 44093,\n  },\n  {\n    date: 1461261180000,\n    open: 55.85,\n    high: 55.85,\n    low: 55.775,\n    close: 55.8,\n    volume: 71108,\n  },\n  {\n    date: 1461261240000,\n    open: 55.805,\n    high: 55.84,\n    low: 55.8,\n    close: 55.835,\n    volume: 51226,\n  },\n  {\n    date: 1461261300000,\n    open: 55.835,\n    high: 55.85,\n    low: 55.8035,\n    close: 55.81,\n    volume: 46188,\n  },\n  {\n    date: 1461261360000,\n    open: 55.815,\n    high: 55.826,\n    low: 55.795,\n    close: 55.815,\n    volume: 32113,\n  },\n  {\n    date: 1461261420000,\n    open: 55.8153,\n    high: 55.85,\n    low: 55.81,\n    close: 55.83,\n    volume: 79265,\n  },\n  {\n    date: 1461261480000,\n    open: 55.82,\n    high: 55.85,\n    low: 55.815,\n    close: 55.825,\n    volume: 26492,\n  },\n  {\n    date: 1461261540000,\n    open: 55.825,\n    high: 55.85,\n    low: 55.82,\n    close: 55.845,\n    volume: 51482,\n  },\n  {\n    date: 1461261600000,\n    open: 55.845,\n    high: 55.85,\n    low: 55.81,\n    close: 55.83,\n    volume: 34381,\n  },\n  {\n    date: 1461261660000,\n    open: 55.8238,\n    high: 55.825,\n    low: 55.81,\n    close: 55.81,\n    volume: 12269,\n  },\n  {\n    date: 1461261720000,\n    open: 55.8199,\n    high: 55.855,\n    low: 55.81,\n    close: 55.815,\n    volume: 81803,\n  },\n  {\n    date: 1461261780000,\n    open: 55.845,\n    high: 55.845,\n    low: 55.78,\n    close: 55.8,\n    volume: 129902,\n  },\n  {\n    date: 1461261840000,\n    open: 55.795,\n    high: 55.795,\n    low: 55.77,\n    close: 55.785,\n    volume: 32236,\n  },\n  {\n    date: 1461261900000,\n    open: 55.79,\n    high: 55.79,\n    low: 55.73,\n    close: 55.745,\n    volume: 101588,\n  },\n  {\n    date: 1461261960000,\n    open: 55.745,\n    high: 55.76,\n    low: 55.72,\n    close: 55.76,\n    volume: 76989,\n  },\n  {\n    date: 1461262020000,\n    open: 55.76,\n    high: 55.81,\n    low: 55.755,\n    close: 55.805,\n    volume: 44967,\n  },\n  {\n    date: 1461262080000,\n    open: 55.81,\n    high: 55.84,\n    low: 55.8,\n    close: 55.8256,\n    volume: 73870,\n  },\n  {\n    date: 1461262140000,\n    open: 55.825,\n    high: 55.8501,\n    low: 55.81,\n    close: 55.815,\n    volume: 22216,\n  },\n  {\n    date: 1461262200000,\n    open: 55.8139,\n    high: 55.82,\n    low: 55.79,\n    close: 55.795,\n    volume: 16995,\n  },\n  {\n    date: 1461262260000,\n    open: 55.8,\n    high: 55.84,\n    low: 55.8,\n    close: 55.84,\n    volume: 50586,\n  },\n  {\n    date: 1461262320000,\n    open: 55.835,\n    high: 55.84,\n    low: 55.83,\n    close: 55.835,\n    volume: 38015,\n  },\n  {\n    date: 1461262380000,\n    open: 55.835,\n    high: 55.845,\n    low: 55.83,\n    close: 55.835,\n    volume: 40249,\n  },\n  {\n    date: 1461262440000,\n    open: 55.835,\n    high: 55.87,\n    low: 55.83,\n    close: 55.86,\n    volume: 91517,\n  },\n  {\n    date: 1461262500000,\n    open: 55.865,\n    high: 55.87,\n    low: 55.85,\n    close: 55.8599,\n    volume: 32498,\n  },\n  {\n    date: 1461262560000,\n    open: 55.855,\n    high: 55.88,\n    low: 55.85,\n    close: 55.865,\n    volume: 36734,\n  },\n  {\n    date: 1461262620000,\n    open: 55.87,\n    high: 55.87,\n    low: 55.795,\n    close: 55.796,\n    volume: 75570,\n  },\n  {\n    date: 1461262680000,\n    open: 55.8,\n    high: 55.815,\n    low: 55.77,\n    close: 55.8,\n    volume: 67602,\n  },\n  {\n    date: 1461262740000,\n    open: 55.795,\n    high: 55.7999,\n    low: 55.77,\n    close: 55.78,\n    volume: 45298,\n  },\n  {\n    date: 1461262800000,\n    open: 55.774,\n    high: 55.785,\n    low: 55.745,\n    close: 55.775,\n    volume: 84494,\n  },\n  {\n    date: 1461262860000,\n    open: 55.773,\n    high: 55.78,\n    low: 55.77,\n    close: 55.775,\n    volume: 49260,\n  },\n  {\n    date: 1461262920000,\n    open: 55.78,\n    high: 55.83,\n    low: 55.78,\n    close: 55.825,\n    volume: 46659,\n  },\n  {\n    date: 1461262980000,\n    open: 55.83,\n    high: 55.84,\n    low: 55.81,\n    close: 55.81,\n    volume: 48360,\n  },\n  {\n    date: 1461263040000,\n    open: 55.819,\n    high: 55.83,\n    low: 55.81,\n    close: 55.825,\n    volume: 22116,\n  },\n  {\n    date: 1461263100000,\n    open: 55.8231,\n    high: 55.83,\n    low: 55.79,\n    close: 55.79,\n    volume: 50731,\n  },\n  {\n    date: 1461263160000,\n    open: 55.79,\n    high: 55.81,\n    low: 55.785,\n    close: 55.79,\n    volume: 75531,\n  },\n  {\n    date: 1461263220000,\n    open: 55.8,\n    high: 55.81,\n    low: 55.75,\n    close: 55.76,\n    volume: 51468,\n  },\n  {\n    date: 1461263280000,\n    open: 55.76,\n    high: 55.795,\n    low: 55.755,\n    close: 55.785,\n    volume: 51770,\n  },\n  {\n    date: 1461263340000,\n    open: 55.78,\n    high: 55.785,\n    low: 55.73,\n    close: 55.755,\n    volume: 98904,\n  },\n  {\n    date: 1461263400000,\n    open: 55.76,\n    high: 55.77,\n    low: 55.71,\n    close: 55.735,\n    volume: 70259,\n  },\n  {\n    date: 1461263460000,\n    open: 55.74,\n    high: 55.74,\n    low: 55.71,\n    close: 55.72,\n    volume: 38437,\n  },\n  {\n    date: 1461263520000,\n    open: 55.715,\n    high: 55.72,\n    low: 55.67,\n    close: 55.695,\n    volume: 43750,\n  },\n  {\n    date: 1461263580000,\n    open: 55.695,\n    high: 55.7,\n    low: 55.68,\n    close: 55.695,\n    volume: 30344,\n  },\n  {\n    date: 1461263640000,\n    open: 55.695,\n    high: 55.7,\n    low: 55.68,\n    close: 55.6899,\n    volume: 126853,\n  },\n  {\n    date: 1461263700000,\n    open: 55.69,\n    high: 55.69,\n    low: 55.65,\n    close: 55.65,\n    volume: 42233,\n  },\n  {\n    date: 1461263760000,\n    open: 55.655,\n    high: 55.66,\n    low: 55.62,\n    close: 55.645,\n    volume: 100126,\n  },\n  {\n    date: 1461263820000,\n    open: 55.645,\n    high: 55.67,\n    low: 55.6301,\n    close: 55.6588,\n    volume: 63469,\n  },\n  {\n    date: 1461263880000,\n    open: 55.655,\n    high: 55.68,\n    low: 55.65,\n    close: 55.675,\n    volume: 73834,\n  },\n  {\n    date: 1461263940000,\n    open: 55.68,\n    high: 55.7,\n    low: 55.67,\n    close: 55.695,\n    volume: 179331,\n  },\n  {\n    date: 1461264000000,\n    open: 55.695,\n    high: 55.695,\n    low: 55.66,\n    close: 55.675,\n    volume: 52116,\n  },\n  {\n    date: 1461264060000,\n    open: 55.67,\n    high: 55.67,\n    low: 55.6483,\n    close: 55.655,\n    volume: 58433,\n  },\n  {\n    date: 1461264120000,\n    open: 55.655,\n    high: 55.66,\n    low: 55.64,\n    close: 55.655,\n    volume: 39310,\n  },\n  {\n    date: 1461264180000,\n    open: 55.66,\n    high: 55.68,\n    low: 55.65,\n    close: 55.655,\n    volume: 58586,\n  },\n  {\n    date: 1461264240000,\n    open: 55.651,\n    high: 55.6869,\n    low: 55.65,\n    close: 55.675,\n    volume: 60925,\n  },\n  {\n    date: 1461264300000,\n    open: 55.675,\n    high: 55.68,\n    low: 55.65,\n    close: 55.67,\n    volume: 81549,\n  },\n  {\n    date: 1461264360000,\n    open: 55.68,\n    high: 55.71,\n    low: 55.65,\n    close: 55.7099,\n    volume: 78868,\n  },\n  {\n    date: 1461264420000,\n    open: 55.71,\n    high: 55.74,\n    low: 55.6669,\n    close: 55.715,\n    volume: 99555,\n  },\n  {\n    date: 1461264480000,\n    open: 55.719,\n    high: 55.75,\n    low: 55.71,\n    close: 55.715,\n    volume: 91080,\n  },\n  {\n    date: 1461264540000,\n    open: 55.71,\n    high: 55.77,\n    low: 55.71,\n    close: 55.77,\n    volume: 55847,\n  },\n  {\n    date: 1461264600000,\n    open: 55.77,\n    high: 55.8199,\n    low: 55.75,\n    close: 55.8199,\n    volume: 67410,\n  },\n  {\n    date: 1461264660000,\n    open: 55.82,\n    high: 55.85,\n    low: 55.8,\n    close: 55.81,\n    volume: 74058,\n  },\n  {\n    date: 1461264720000,\n    open: 55.81,\n    high: 55.81,\n    low: 55.78,\n    close: 55.795,\n    volume: 74069,\n  },\n  {\n    date: 1461264780000,\n    open: 55.7937,\n    high: 55.82,\n    low: 55.7675,\n    close: 55.8,\n    volume: 102611,\n  },\n  {\n    date: 1461264840000,\n    open: 55.79,\n    high: 55.85,\n    low: 55.79,\n    close: 55.84,\n    volume: 36677,\n  },\n  {\n    date: 1461264900000,\n    open: 55.84,\n    high: 55.87,\n    low: 55.825,\n    close: 55.85,\n    volume: 73441,\n  },\n  {\n    date: 1461264960000,\n    open: 55.85,\n    high: 55.86,\n    low: 55.84,\n    close: 55.86,\n    volume: 25481,\n  },\n  {\n    date: 1461265020000,\n    open: 55.855,\n    high: 55.8699,\n    low: 55.84,\n    close: 55.86,\n    volume: 40103,\n  },\n  {\n    date: 1461265080000,\n    open: 55.853,\n    high: 55.88,\n    low: 55.845,\n    close: 55.88,\n    volume: 44850,\n  },\n  {\n    date: 1461265140000,\n    open: 55.87,\n    high: 55.875,\n    low: 55.85,\n    close: 55.86,\n    volume: 25913,\n  },\n  {\n    date: 1461265200000,\n    open: 55.855,\n    high: 55.87,\n    low: 55.85,\n    close: 55.85,\n    volume: 40506,\n  },\n  {\n    date: 1461265260000,\n    open: 55.85,\n    high: 55.92,\n    low: 55.85,\n    close: 55.87,\n    volume: 122344,\n  },\n  {\n    date: 1461265320000,\n    open: 55.87,\n    high: 55.91,\n    low: 55.87,\n    close: 55.895,\n    volume: 71358,\n  },\n  {\n    date: 1461265380000,\n    open: 55.895,\n    high: 55.905,\n    low: 55.89,\n    close: 55.895,\n    volume: 35998,\n  },\n  {\n    date: 1461265440000,\n    open: 55.89,\n    high: 55.895,\n    low: 55.88,\n    close: 55.8899,\n    volume: 38505,\n  },\n  {\n    date: 1461265500000,\n    open: 55.89,\n    high: 55.895,\n    low: 55.8501,\n    close: 55.86,\n    volume: 60704,\n  },\n  {\n    date: 1461265560000,\n    open: 55.86,\n    high: 55.87,\n    low: 55.85,\n    close: 55.86,\n    volume: 32762,\n  },\n  {\n    date: 1461265620000,\n    open: 55.8662,\n    high: 55.88,\n    low: 55.86,\n    close: 55.88,\n    volume: 30230,\n  },\n  {\n    date: 1461265680000,\n    open: 55.88,\n    high: 55.88,\n    low: 55.84,\n    close: 55.8499,\n    volume: 43111,\n  },\n  {\n    date: 1461265740000,\n    open: 55.84,\n    high: 55.855,\n    low: 55.84,\n    close: 55.85,\n    volume: 21125,\n  },\n  {\n    date: 1461265800000,\n    open: 55.8499,\n    high: 55.85,\n    low: 55.795,\n    close: 55.8,\n    volume: 94214,\n  },\n  {\n    date: 1461265860000,\n    open: 55.8,\n    high: 55.81,\n    low: 55.7732,\n    close: 55.805,\n    volume: 69013,\n  },\n  {\n    date: 1461265920000,\n    open: 55.81,\n    high: 55.84,\n    low: 55.81,\n    close: 55.83,\n    volume: 37506,\n  },\n  {\n    date: 1461265980000,\n    open: 55.84,\n    high: 55.865,\n    low: 55.815,\n    close: 55.86,\n    volume: 83026,\n  },\n  {\n    date: 1461266040000,\n    open: 55.855,\n    high: 55.855,\n    low: 55.825,\n    close: 55.825,\n    volume: 40372,\n  },\n  {\n    date: 1461266100000,\n    open: 55.825,\n    high: 55.83,\n    low: 55.8,\n    close: 55.825,\n    volume: 43155,\n  },\n  {\n    date: 1461266160000,\n    open: 55.825,\n    high: 55.845,\n    low: 55.825,\n    close: 55.8334,\n    volume: 74007,\n  },\n  {\n    date: 1461266220000,\n    open: 55.835,\n    high: 55.84,\n    low: 55.81,\n    close: 55.815,\n    volume: 83119,\n  },\n  {\n    date: 1461266280000,\n    open: 55.815,\n    high: 55.85,\n    low: 55.8101,\n    close: 55.84,\n    volume: 60554,\n  },\n  {\n    date: 1461266340000,\n    open: 55.84,\n    high: 55.89,\n    low: 55.835,\n    close: 55.85,\n    volume: 109592,\n  },\n  {\n    date: 1461266400000,\n    open: 55.8575,\n    high: 55.865,\n    low: 55.82,\n    close: 55.845,\n    volume: 88875,\n  },\n  {\n    date: 1461266460000,\n    open: 55.84,\n    high: 55.8598,\n    low: 55.79,\n    close: 55.8,\n    volume: 95750,\n  },\n  {\n    date: 1461266520000,\n    open: 55.8,\n    high: 55.81,\n    low: 55.795,\n    close: 55.81,\n    volume: 42252,\n  },\n  {\n    date: 1461266580000,\n    open: 55.81,\n    high: 55.82,\n    low: 55.8,\n    close: 55.81,\n    volume: 33658,\n  },\n  {\n    date: 1461266640000,\n    open: 55.805,\n    high: 55.84,\n    low: 55.8,\n    close: 55.805,\n    volume: 53860,\n  },\n  {\n    date: 1461266700000,\n    open: 55.81,\n    high: 55.82,\n    low: 55.8,\n    close: 55.8101,\n    volume: 43336,\n  },\n  {\n    date: 1461266760000,\n    open: 55.82,\n    high: 55.82,\n    low: 55.81,\n    close: 55.815,\n    volume: 13623,\n  },\n  {\n    date: 1461266820000,\n    open: 55.81,\n    high: 55.9,\n    low: 55.81,\n    close: 55.885,\n    volume: 175861,\n  },\n  {\n    date: 1461266880000,\n    open: 55.88,\n    high: 55.895,\n    low: 55.825,\n    close: 55.83,\n    volume: 84630,\n  },\n  {\n    date: 1461266940000,\n    open: 55.83,\n    high: 55.84,\n    low: 55.81,\n    close: 55.825,\n    volume: 82844,\n  },\n  {\n    date: 1461267000000,\n    open: 55.83,\n    high: 55.83,\n    low: 55.76,\n    close: 55.76,\n    volume: 88915,\n  },\n  {\n    date: 1461267060000,\n    open: 55.76,\n    high: 55.825,\n    low: 55.76,\n    close: 55.825,\n    volume: 61923,\n  },\n  {\n    date: 1461267120000,\n    open: 55.83,\n    high: 55.83,\n    low: 55.79,\n    close: 55.815,\n    volume: 62037,\n  },\n  {\n    date: 1461267180000,\n    open: 55.82,\n    high: 55.82,\n    low: 55.81,\n    close: 55.815,\n    volume: 94795,\n  },\n  {\n    date: 1461267240000,\n    open: 55.815,\n    high: 55.85,\n    low: 55.81,\n    close: 55.8301,\n    volume: 146278,\n  },\n  {\n    date: 1461267300000,\n    open: 55.835,\n    high: 55.84,\n    low: 55.78,\n    close: 55.8199,\n    volume: 102822,\n  },\n  {\n    date: 1461267360000,\n    open: 55.815,\n    high: 55.85,\n    low: 55.815,\n    close: 55.835,\n    volume: 43585,\n  },\n  {\n    date: 1461267420000,\n    open: 55.84,\n    high: 55.85,\n    low: 55.78,\n    close: 55.7807,\n    volume: 98790,\n  },\n  {\n    date: 1461267480000,\n    open: 55.789,\n    high: 55.79,\n    low: 55.71,\n    close: 55.745,\n    volume: 174401,\n  },\n  {\n    date: 1461267540000,\n    open: 55.745,\n    high: 55.75,\n    low: 55.72,\n    close: 55.72,\n    volume: 168036,\n  },\n  {\n    date: 1461267600000,\n    open: 55.72,\n    high: 55.74,\n    low: 55.72,\n    close: 55.735,\n    volume: 41797,\n  },\n  {\n    date: 1461267660000,\n    open: 55.74,\n    high: 55.76,\n    low: 55.7301,\n    close: 55.755,\n    volume: 95381,\n  },\n  {\n    date: 1461267720000,\n    open: 55.75,\n    high: 55.76,\n    low: 55.73,\n    close: 55.74,\n    volume: 110939,\n  },\n  {\n    date: 1461267780000,\n    open: 55.74,\n    high: 55.81,\n    low: 55.74,\n    close: 55.8,\n    volume: 108102,\n  },\n  {\n    date: 1461267840000,\n    open: 55.7961,\n    high: 55.81,\n    low: 55.78,\n    close: 55.79,\n    volume: 106253,\n  },\n  {\n    date: 1461267900000,\n    open: 55.79,\n    high: 55.82,\n    low: 55.78,\n    close: 55.785,\n    volume: 117510,\n  },\n  {\n    date: 1461267960000,\n    open: 55.79,\n    high: 55.83,\n    low: 55.78,\n    close: 55.81,\n    volume: 83443,\n  },\n  {\n    date: 1461268020000,\n    open: 55.807,\n    high: 55.85,\n    low: 55.805,\n    close: 55.845,\n    volume: 92398,\n  },\n  {\n    date: 1461268080000,\n    open: 55.845,\n    high: 55.905,\n    low: 55.83,\n    close: 55.88,\n    volume: 177055,\n  },\n  {\n    date: 1461268140000,\n    open: 55.88,\n    high: 55.91,\n    low: 55.87,\n    close: 55.8901,\n    volume: 129152,\n  },\n  {\n    date: 1461268200000,\n    open: 55.89,\n    high: 55.91,\n    low: 55.78,\n    close: 55.815,\n    volume: 254899,\n  },\n  {\n    date: 1461268260000,\n    open: 55.815,\n    high: 55.8185,\n    low: 55.78,\n    close: 55.785,\n    volume: 153761,\n  },\n  {\n    date: 1461268320000,\n    open: 55.78,\n    high: 55.83,\n    low: 55.78,\n    close: 55.83,\n    volume: 200688,\n  },\n  {\n    date: 1461268380000,\n    open: 55.83,\n    high: 55.85,\n    low: 55.82,\n    close: 55.8499,\n    volume: 171543,\n  },\n  {\n    date: 1461268440000,\n    open: 55.84,\n    high: 55.85,\n    low: 55.79,\n    close: 55.8,\n    volume: 298806,\n  },\n  {\n    date: 1461268500000,\n    open: 55.81,\n    high: 55.82,\n    low: 55.77,\n    close: 55.81,\n    volume: 182780,\n  },\n  {\n    date: 1461268560000,\n    open: 55.8299,\n    high: 55.8699,\n    low: 55.825,\n    close: 55.83,\n    volume: 161528,\n  },\n  {\n    date: 1461268620000,\n    open: 55.825,\n    high: 55.83,\n    low: 55.77,\n    close: 55.8,\n    volume: 157422,\n  },\n  {\n    date: 1461268680000,\n    open: 55.795,\n    high: 55.9,\n    low: 55.79,\n    close: 55.895,\n    volume: 244563,\n  },\n  {\n    date: 1461268740000,\n    open: 55.88,\n    high: 55.91,\n    low: 55.84,\n    close: 55.91,\n    volume: 195862,\n  },\n  {\n    date: 1461268800000,\n    open: 55.91,\n    high: 55.97,\n    low: 55.78,\n    close: 55.78,\n    volume: 1898247,\n  },\n  {\n    date: 1461331800000,\n    open: 51.91,\n    high: 52.39,\n    low: 51.91,\n    close: 52.0372,\n    volume: 1281425,\n  },\n  {\n    date: 1461331860000,\n    open: 52.0391,\n    high: 52.4297,\n    low: 51.6,\n    close: 51.93,\n    volume: 2576487,\n  },\n  {\n    date: 1461331920000,\n    open: 51.9499,\n    high: 52.04,\n    low: 51.88,\n    close: 52.01,\n    volume: 914745,\n  },\n  {\n    date: 1461331980000,\n    open: 52,\n    high: 52.24,\n    low: 51.97,\n    close: 52.24,\n    volume: 910543,\n  },\n  {\n    date: 1461332040000,\n    open: 52.23,\n    high: 52.36,\n    low: 52.18,\n    close: 52.185,\n    volume: 1099524,\n  },\n  {\n    date: 1461332100000,\n    open: 52.1881,\n    high: 52.2,\n    low: 51.95,\n    close: 52.04,\n    volume: 909875,\n  },\n  {\n    date: 1461332160000,\n    open: 52.05,\n    high: 52.17,\n    low: 52.02,\n    close: 52.12,\n    volume: 851342,\n  },\n  {\n    date: 1461332220000,\n    open: 52.11,\n    high: 52.165,\n    low: 52.08,\n    close: 52.13,\n    volume: 696716,\n  },\n  {\n    date: 1461332280000,\n    open: 52.12,\n    high: 52.16,\n    low: 52.05,\n    close: 52.1025,\n    volume: 1093318,\n  },\n  {\n    date: 1461332340000,\n    open: 52.105,\n    high: 52.17,\n    low: 51.98,\n    close: 51.98,\n    volume: 830334,\n  },\n  {\n    date: 1461332400000,\n    open: 51.98,\n    high: 52,\n    low: 51.83,\n    close: 51.985,\n    volume: 617500,\n  },\n  {\n    date: 1461332460000,\n    open: 51.9825,\n    high: 52.01,\n    low: 51.92,\n    close: 51.92,\n    volume: 768535,\n  },\n  {\n    date: 1461332520000,\n    open: 51.92,\n    high: 51.92,\n    low: 51.76,\n    close: 51.82,\n    volume: 1059816,\n  },\n  {\n    date: 1461332580000,\n    open: 51.82,\n    high: 51.85,\n    low: 51.74,\n    close: 51.76,\n    volume: 658340,\n  },\n  {\n    date: 1461332640000,\n    open: 51.761,\n    high: 51.84,\n    low: 51.71,\n    close: 51.7668,\n    volume: 643321,\n  },\n  {\n    date: 1461332700000,\n    open: 51.7699,\n    high: 51.92,\n    low: 51.76,\n    close: 51.92,\n    volume: 448515,\n  },\n  {\n    date: 1461332760000,\n    open: 51.915,\n    high: 51.92,\n    low: 51.79,\n    close: 51.86,\n    volume: 531793,\n  },\n  {\n    date: 1461332820000,\n    open: 51.85,\n    high: 51.88,\n    low: 51.76,\n    close: 51.82,\n    volume: 572053,\n  },\n  {\n    date: 1461332880000,\n    open: 51.82,\n    high: 51.86,\n    low: 51.75,\n    close: 51.8264,\n    volume: 548497,\n  },\n  {\n    date: 1461332940000,\n    open: 51.82,\n    high: 51.83,\n    low: 51.7,\n    close: 51.8,\n    volume: 716711,\n  },\n  {\n    date: 1461333000000,\n    open: 51.802,\n    high: 51.81,\n    low: 51.74,\n    close: 51.765,\n    volume: 646384,\n  },\n  {\n    date: 1461333060000,\n    open: 51.77,\n    high: 51.83,\n    low: 51.73,\n    close: 51.805,\n    volume: 467219,\n  },\n  {\n    date: 1461333120000,\n    open: 51.8001,\n    high: 51.88,\n    low: 51.79,\n    close: 51.84,\n    volume: 416480,\n  },\n  {\n    date: 1461333180000,\n    open: 51.844,\n    high: 51.86,\n    low: 51.72,\n    close: 51.776,\n    volume: 505924,\n  },\n  {\n    date: 1461333240000,\n    open: 51.779,\n    high: 51.81,\n    low: 51.75,\n    close: 51.754,\n    volume: 405140,\n  },\n  {\n    date: 1461333300000,\n    open: 51.76,\n    high: 51.79,\n    low: 51.7,\n    close: 51.71,\n    volume: 408571,\n  },\n  {\n    date: 1461333360000,\n    open: 51.71,\n    high: 51.8,\n    low: 51.66,\n    close: 51.79,\n    volume: 477046,\n  },\n  {\n    date: 1461333420000,\n    open: 51.79,\n    high: 51.8,\n    low: 51.73,\n    close: 51.77,\n    volume: 225295,\n  },\n  {\n    date: 1461333480000,\n    open: 51.78,\n    high: 51.78,\n    low: 51.66,\n    close: 51.665,\n    volume: 453534,\n  },\n  {\n    date: 1461333540000,\n    open: 51.665,\n    high: 51.75,\n    low: 51.665,\n    close: 51.74,\n    volume: 469351,\n  },\n  {\n    date: 1461333600000,\n    open: 51.74,\n    high: 51.8,\n    low: 51.72,\n    close: 51.725,\n    volume: 440023,\n  },\n  {\n    date: 1461333660000,\n    open: 51.725,\n    high: 51.74,\n    low: 51.65,\n    close: 51.715,\n    volume: 536180,\n  },\n  {\n    date: 1461333720000,\n    open: 51.72,\n    high: 51.75,\n    low: 51.61,\n    close: 51.664,\n    volume: 444081,\n  },\n  {\n    date: 1461333780000,\n    open: 51.67,\n    high: 51.69,\n    low: 51.47,\n    close: 51.48,\n    volume: 774994,\n  },\n  {\n    date: 1461333840000,\n    open: 51.48,\n    high: 51.56,\n    low: 51.44,\n    close: 51.4871,\n    volume: 611171,\n  },\n  {\n    date: 1461333900000,\n    open: 51.4875,\n    high: 51.49,\n    low: 51.37,\n    close: 51.39,\n    volume: 629226,\n  },\n  {\n    date: 1461333960000,\n    open: 51.385,\n    high: 51.5,\n    low: 51.38,\n    close: 51.5,\n    volume: 397870,\n  },\n  {\n    date: 1461334020000,\n    open: 51.5,\n    high: 51.53,\n    low: 51.42,\n    close: 51.43,\n    volume: 481457,\n  },\n  {\n    date: 1461334080000,\n    open: 51.44,\n    high: 51.44,\n    low: 51.22,\n    close: 51.3299,\n    volume: 733578,\n  },\n  {\n    date: 1461334140000,\n    open: 51.325,\n    high: 51.33,\n    low: 51.24,\n    close: 51.29,\n    volume: 543476,\n  },\n  {\n    date: 1461334200000,\n    open: 51.295,\n    high: 51.31,\n    low: 51.1475,\n    close: 51.195,\n    volume: 535136,\n  },\n  {\n    date: 1461334260000,\n    open: 51.19,\n    high: 51.24,\n    low: 51.05,\n    close: 51.2199,\n    volume: 894538,\n  },\n  {\n    date: 1461334320000,\n    open: 51.21,\n    high: 51.25,\n    low: 51.08,\n    close: 51.09,\n    volume: 432634,\n  },\n  {\n    date: 1461334380000,\n    open: 51.09,\n    high: 51.1,\n    low: 51,\n    close: 51.03,\n    volume: 834964,\n  },\n  {\n    date: 1461334440000,\n    open: 51.025,\n    high: 51.08,\n    low: 50.91,\n    close: 51.02,\n    volume: 1122957,\n  },\n  {\n    date: 1461334500000,\n    open: 51.025,\n    high: 51.05,\n    low: 50.95,\n    close: 50.96,\n    volume: 554285,\n  },\n  {\n    date: 1461334560000,\n    open: 50.96,\n    high: 50.97,\n    low: 50.91,\n    close: 50.935,\n    volume: 506717,\n  },\n  {\n    date: 1461334620000,\n    open: 50.93,\n    high: 51.04,\n    low: 50.84,\n    close: 51.01,\n    volume: 641365,\n  },\n  {\n    date: 1461334680000,\n    open: 51,\n    high: 51.06,\n    low: 50.91,\n    close: 50.915,\n    volume: 464943,\n  },\n  {\n    date: 1461334740000,\n    open: 50.91,\n    high: 50.92,\n    low: 50.81,\n    close: 50.855,\n    volume: 719575,\n  },\n  {\n    date: 1461334800000,\n    open: 50.85,\n    high: 50.87,\n    low: 50.77,\n    close: 50.84,\n    volume: 594998,\n  },\n  {\n    date: 1461334860000,\n    open: 50.845,\n    high: 50.9299,\n    low: 50.8,\n    close: 50.82,\n    volume: 514504,\n  },\n  {\n    date: 1461334920000,\n    open: 50.815,\n    high: 50.9,\n    low: 50.81,\n    close: 50.8695,\n    volume: 387227,\n  },\n  {\n    date: 1461334980000,\n    open: 50.87,\n    high: 51.05,\n    low: 50.86,\n    close: 51.02,\n    volume: 533873,\n  },\n  {\n    date: 1461335040000,\n    open: 51.03,\n    high: 51.03,\n    low: 50.91,\n    close: 50.93,\n    volume: 302635,\n  },\n  {\n    date: 1461335100000,\n    open: 50.9361,\n    high: 51.04,\n    low: 50.93,\n    close: 51.03,\n    volume: 331151,\n  },\n  {\n    date: 1461335160000,\n    open: 51.03,\n    high: 51.14,\n    low: 51.025,\n    close: 51.08,\n    volume: 534770,\n  },\n  {\n    date: 1461335220000,\n    open: 51.09,\n    high: 51.09,\n    low: 50.96,\n    close: 50.9664,\n    volume: 413187,\n  },\n  {\n    date: 1461335280000,\n    open: 50.96,\n    high: 51.1,\n    low: 50.96,\n    close: 51.1,\n    volume: 407016,\n  },\n  {\n    date: 1461335340000,\n    open: 51.085,\n    high: 51.24,\n    low: 51.075,\n    close: 51.23,\n    volume: 424365,\n  },\n  {\n    date: 1461335400000,\n    open: 51.225,\n    high: 51.25,\n    low: 51.135,\n    close: 51.1905,\n    volume: 516277,\n  },\n  {\n    date: 1461335460000,\n    open: 51.195,\n    high: 51.2899,\n    low: 51.19,\n    close: 51.28,\n    volume: 451323,\n  },\n  {\n    date: 1461335520000,\n    open: 51.2865,\n    high: 51.35,\n    low: 51.25,\n    close: 51.349,\n    volume: 285453,\n  },\n  {\n    date: 1461335580000,\n    open: 51.34,\n    high: 51.39,\n    low: 51.29,\n    close: 51.35,\n    volume: 420866,\n  },\n  {\n    date: 1461335640000,\n    open: 51.341,\n    high: 51.38,\n    low: 51.3,\n    close: 51.38,\n    volume: 254408,\n  },\n  {\n    date: 1461335700000,\n    open: 51.38,\n    high: 51.44,\n    low: 51.34,\n    close: 51.3865,\n    volume: 309157,\n  },\n  {\n    date: 1461335760000,\n    open: 51.39,\n    high: 51.395,\n    low: 51.3,\n    close: 51.32,\n    volume: 414776,\n  },\n  {\n    date: 1461335820000,\n    open: 51.32,\n    high: 51.33,\n    low: 51.26,\n    close: 51.31,\n    volume: 258505,\n  },\n  {\n    date: 1461335880000,\n    open: 51.31,\n    high: 51.32,\n    low: 51.17,\n    close: 51.2,\n    volume: 339059,\n  },\n  {\n    date: 1461335940000,\n    open: 51.2099,\n    high: 51.27,\n    low: 51.1789,\n    close: 51.235,\n    volume: 248748,\n  },\n  {\n    date: 1461336000000,\n    open: 51.235,\n    high: 51.26,\n    low: 51.23,\n    close: 51.2499,\n    volume: 239823,\n  },\n  {\n    date: 1461336060000,\n    open: 51.245,\n    high: 51.28,\n    low: 51.23,\n    close: 51.235,\n    volume: 310514,\n  },\n  {\n    date: 1461336120000,\n    open: 51.23,\n    high: 51.27,\n    low: 51.13,\n    close: 51.14,\n    volume: 594159,\n  },\n  {\n    date: 1461336180000,\n    open: 51.13,\n    high: 51.13,\n    low: 51.04,\n    close: 51.06,\n    volume: 544086,\n  },\n  {\n    date: 1461336240000,\n    open: 51.06,\n    high: 51.11,\n    low: 51.045,\n    close: 51.09,\n    volume: 277588,\n  },\n  {\n    date: 1461336300000,\n    open: 51.1,\n    high: 51.12,\n    low: 51.06,\n    close: 51.07,\n    volume: 208071,\n  },\n  {\n    date: 1461336360000,\n    open: 51.065,\n    high: 51.17,\n    low: 51.045,\n    close: 51.105,\n    volume: 473496,\n  },\n  {\n    date: 1461336420000,\n    open: 51.105,\n    high: 51.14,\n    low: 51.08,\n    close: 51.13,\n    volume: 268392,\n  },\n  {\n    date: 1461336480000,\n    open: 51.13,\n    high: 51.27,\n    low: 51.12,\n    close: 51.26,\n    volume: 302020,\n  },\n  {\n    date: 1461336540000,\n    open: 51.265,\n    high: 51.27,\n    low: 51.235,\n    close: 51.255,\n    volume: 291067,\n  },\n  {\n    date: 1461336600000,\n    open: 51.26,\n    high: 51.349,\n    low: 51.24,\n    close: 51.292,\n    volume: 367436,\n  },\n  {\n    date: 1461336660000,\n    open: 51.295,\n    high: 51.35,\n    low: 51.285,\n    close: 51.3399,\n    volume: 199717,\n  },\n  {\n    date: 1461336720000,\n    open: 51.34,\n    high: 51.39,\n    low: 51.32,\n    close: 51.38,\n    volume: 197105,\n  },\n  {\n    date: 1461336780000,\n    open: 51.39,\n    high: 51.44,\n    low: 51.37,\n    close: 51.425,\n    volume: 533782,\n  },\n  {\n    date: 1461336840000,\n    open: 51.43,\n    high: 51.49,\n    low: 51.37,\n    close: 51.49,\n    volume: 440948,\n  },\n  {\n    date: 1461336900000,\n    open: 51.49,\n    high: 51.589,\n    low: 51.48,\n    close: 51.589,\n    volume: 459596,\n  },\n  {\n    date: 1461336960000,\n    open: 51.58,\n    high: 51.67,\n    low: 51.565,\n    close: 51.605,\n    volume: 883440,\n  },\n  {\n    date: 1461337020000,\n    open: 51.61,\n    high: 51.61,\n    low: 51.47,\n    close: 51.491,\n    volume: 438890,\n  },\n  {\n    date: 1461337080000,\n    open: 51.4999,\n    high: 51.59,\n    low: 51.49,\n    close: 51.514,\n    volume: 348092,\n  },\n  {\n    date: 1461337140000,\n    open: 51.5399,\n    high: 51.61,\n    low: 51.5363,\n    close: 51.565,\n    volume: 219806,\n  },\n  {\n    date: 1461337200000,\n    open: 51.566,\n    high: 51.63,\n    low: 51.53,\n    close: 51.59,\n    volume: 589063,\n  },\n  {\n    date: 1461337260000,\n    open: 51.58,\n    high: 51.62,\n    low: 51.52,\n    close: 51.54,\n    volume: 451846,\n  },\n  {\n    date: 1461337320000,\n    open: 51.54,\n    high: 51.63,\n    low: 51.538,\n    close: 51.6,\n    volume: 448767,\n  },\n  {\n    date: 1461337380000,\n    open: 51.605,\n    high: 51.61,\n    low: 51.555,\n    close: 51.57,\n    volume: 285671,\n  },\n  {\n    date: 1461337440000,\n    open: 51.573,\n    high: 51.61,\n    low: 51.56,\n    close: 51.58,\n    volume: 394607,\n  },\n  {\n    date: 1461337500000,\n    open: 51.589,\n    high: 51.6,\n    low: 51.56,\n    close: 51.58,\n    volume: 280484,\n  },\n  {\n    date: 1461337560000,\n    open: 51.58,\n    high: 51.65,\n    low: 51.58,\n    close: 51.595,\n    volume: 657649,\n  },\n  {\n    date: 1461337620000,\n    open: 51.6,\n    high: 51.6,\n    low: 51.42,\n    close: 51.498,\n    volume: 454111,\n  },\n  {\n    date: 1461337680000,\n    open: 51.5,\n    high: 51.59,\n    low: 51.47,\n    close: 51.57,\n    volume: 309031,\n  },\n  {\n    date: 1461337740000,\n    open: 51.57,\n    high: 51.595,\n    low: 51.535,\n    close: 51.59,\n    volume: 185810,\n  },\n  {\n    date: 1461337800000,\n    open: 51.5866,\n    high: 51.65,\n    low: 51.55,\n    close: 51.649,\n    volume: 259047,\n  },\n  {\n    date: 1461337860000,\n    open: 51.65,\n    high: 51.65,\n    low: 51.59,\n    close: 51.61,\n    volume: 189738,\n  },\n  {\n    date: 1461337920000,\n    open: 51.61,\n    high: 51.67,\n    low: 51.59,\n    close: 51.6354,\n    volume: 441155,\n  },\n  {\n    date: 1461337980000,\n    open: 51.635,\n    high: 51.64,\n    low: 51.59,\n    close: 51.595,\n    volume: 305518,\n  },\n  {\n    date: 1461338040000,\n    open: 51.5957,\n    high: 51.69,\n    low: 51.59,\n    close: 51.685,\n    volume: 391325,\n  },\n  {\n    date: 1461338100000,\n    open: 51.68,\n    high: 51.73,\n    low: 51.655,\n    close: 51.68,\n    volume: 352988,\n  },\n  {\n    date: 1461338160000,\n    open: 51.68,\n    high: 51.74,\n    low: 51.665,\n    close: 51.73,\n    volume: 343289,\n  },\n  {\n    date: 1461338220000,\n    open: 51.73,\n    high: 51.75,\n    low: 51.7,\n    close: 51.7299,\n    volume: 314970,\n  },\n  {\n    date: 1461338280000,\n    open: 51.73,\n    high: 51.74,\n    low: 51.61,\n    close: 51.645,\n    volume: 226271,\n  },\n  {\n    date: 1461338340000,\n    open: 51.649,\n    high: 51.71,\n    low: 51.64,\n    close: 51.704,\n    volume: 164331,\n  },\n  {\n    date: 1461338400000,\n    open: 51.7,\n    high: 51.75,\n    low: 51.69,\n    close: 51.6999,\n    volume: 281598,\n  },\n  {\n    date: 1461338460000,\n    open: 51.6957,\n    high: 51.72,\n    low: 51.66,\n    close: 51.679,\n    volume: 191657,\n  },\n  {\n    date: 1461338520000,\n    open: 51.6764,\n    high: 51.73,\n    low: 51.65,\n    close: 51.71,\n    volume: 333500,\n  },\n  {\n    date: 1461338580000,\n    open: 51.71,\n    high: 51.74,\n    low: 51.705,\n    close: 51.725,\n    volume: 121691,\n  },\n  {\n    date: 1461338640000,\n    open: 51.73,\n    high: 51.78,\n    low: 51.72,\n    close: 51.765,\n    volume: 335402,\n  },\n  {\n    date: 1461338700000,\n    open: 51.77,\n    high: 51.88,\n    low: 51.765,\n    close: 51.87,\n    volume: 478933,\n  },\n  {\n    date: 1461338760000,\n    open: 51.86,\n    high: 51.95,\n    low: 51.86,\n    close: 51.9401,\n    volume: 404937,\n  },\n  {\n    date: 1461338820000,\n    open: 51.9432,\n    high: 51.98,\n    low: 51.9,\n    close: 51.97,\n    volume: 633851,\n  },\n  {\n    date: 1461338880000,\n    open: 51.97,\n    high: 52.005,\n    low: 51.96,\n    close: 51.9971,\n    volume: 541125,\n  },\n  {\n    date: 1461338940000,\n    open: 51.9901,\n    high: 52,\n    low: 51.85,\n    close: 51.8557,\n    volume: 548298,\n  },\n  {\n    date: 1461339000000,\n    open: 51.855,\n    high: 51.87,\n    low: 51.72,\n    close: 51.7568,\n    volume: 384513,\n  },\n  {\n    date: 1461339060000,\n    open: 51.76,\n    high: 51.8,\n    low: 51.7599,\n    close: 51.77,\n    volume: 341178,\n  },\n  {\n    date: 1461339120000,\n    open: 51.78,\n    high: 51.89,\n    low: 51.7701,\n    close: 51.855,\n    volume: 308936,\n  },\n  {\n    date: 1461339180000,\n    open: 51.855,\n    high: 51.87,\n    low: 51.8,\n    close: 51.85,\n    volume: 279776,\n  },\n  {\n    date: 1461339240000,\n    open: 51.85,\n    high: 51.86,\n    low: 51.8,\n    close: 51.81,\n    volume: 314400,\n  },\n  {\n    date: 1461339300000,\n    open: 51.8168,\n    high: 51.91,\n    low: 51.81,\n    close: 51.91,\n    volume: 217129,\n  },\n  {\n    date: 1461339360000,\n    open: 51.905,\n    high: 52,\n    low: 51.9,\n    close: 51.955,\n    volume: 293420,\n  },\n  {\n    date: 1461339420000,\n    open: 51.955,\n    high: 52.09,\n    low: 51.95,\n    close: 52.005,\n    volume: 407924,\n  },\n  {\n    date: 1461339480000,\n    open: 52.005,\n    high: 52.09,\n    low: 51.9899,\n    close: 52.045,\n    volume: 501549,\n  },\n  {\n    date: 1461339540000,\n    open: 52.0465,\n    high: 52.1,\n    low: 52,\n    close: 52,\n    volume: 218270,\n  },\n  {\n    date: 1461339600000,\n    open: 52,\n    high: 52.1,\n    low: 51.98,\n    close: 51.995,\n    volume: 491296,\n  },\n  {\n    date: 1461339660000,\n    open: 51.999,\n    high: 52.07,\n    low: 51.99,\n    close: 52.0601,\n    volume: 138617,\n  },\n  {\n    date: 1461339720000,\n    open: 52.06,\n    high: 52.08,\n    low: 51.99,\n    close: 52.04,\n    volume: 141544,\n  },\n  {\n    date: 1461339780000,\n    open: 52.04,\n    high: 52.06,\n    low: 52.02,\n    close: 52.02,\n    volume: 76011,\n  },\n  {\n    date: 1461339840000,\n    open: 52.02,\n    high: 52.0264,\n    low: 52,\n    close: 52.005,\n    volume: 99228,\n  },\n  {\n    date: 1461339900000,\n    open: 52.01,\n    high: 52.04,\n    low: 51.99,\n    close: 52.0359,\n    volume: 252194,\n  },\n  {\n    date: 1461339960000,\n    open: 52.03,\n    high: 52.0336,\n    low: 51.99,\n    close: 51.995,\n    volume: 228580,\n  },\n  {\n    date: 1461340020000,\n    open: 51.9901,\n    high: 52.03,\n    low: 51.98,\n    close: 52,\n    volume: 197122,\n  },\n  {\n    date: 1461340080000,\n    open: 52.01,\n    high: 52.05,\n    low: 52.005,\n    close: 52.0359,\n    volume: 204625,\n  },\n  {\n    date: 1461340140000,\n    open: 52.03,\n    high: 52.035,\n    low: 51.99,\n    close: 52.0264,\n    volume: 225259,\n  },\n  {\n    date: 1461340200000,\n    open: 52.026,\n    high: 52.07,\n    low: 51.99,\n    close: 52.05,\n    volume: 208344,\n  },\n  {\n    date: 1461340260000,\n    open: 52.05,\n    high: 52.16,\n    low: 52.04,\n    close: 52.1295,\n    volume: 307954,\n  },\n  {\n    date: 1461340320000,\n    open: 52.125,\n    high: 52.13,\n    low: 52.09,\n    close: 52.1,\n    volume: 237527,\n  },\n  {\n    date: 1461340380000,\n    open: 52.1,\n    high: 52.16,\n    low: 52.1,\n    close: 52.1572,\n    volume: 175756,\n  },\n  {\n    date: 1461340440000,\n    open: 52.16,\n    high: 52.21,\n    low: 52.16,\n    close: 52.21,\n    volume: 188784,\n  },\n  {\n    date: 1461340500000,\n    open: 52.21,\n    high: 52.225,\n    low: 52.2,\n    close: 52.21,\n    volume: 188184,\n  },\n  {\n    date: 1461340560000,\n    open: 52.205,\n    high: 52.22,\n    low: 52.18,\n    close: 52.19,\n    volume: 237482,\n  },\n  {\n    date: 1461340620000,\n    open: 52.19,\n    high: 52.22,\n    low: 52.19,\n    close: 52.2,\n    volume: 160352,\n  },\n  {\n    date: 1461340680000,\n    open: 52.205,\n    high: 52.21,\n    low: 52.07,\n    close: 52.08,\n    volume: 312004,\n  },\n  {\n    date: 1461340740000,\n    open: 52.08,\n    high: 52.12,\n    low: 52.02,\n    close: 52.0501,\n    volume: 132226,\n  },\n  {\n    date: 1461340800000,\n    open: 52.06,\n    high: 52.11,\n    low: 52.045,\n    close: 52.1,\n    volume: 175336,\n  },\n  {\n    date: 1461340860000,\n    open: 52.1,\n    high: 52.1,\n    low: 52.03,\n    close: 52.065,\n    volume: 166493,\n  },\n  {\n    date: 1461340920000,\n    open: 52.065,\n    high: 52.1,\n    low: 52.05,\n    close: 52.09,\n    volume: 189291,\n  },\n  {\n    date: 1461340980000,\n    open: 52.09,\n    high: 52.15,\n    low: 52.08,\n    close: 52.14,\n    volume: 142035,\n  },\n  {\n    date: 1461341040000,\n    open: 52.14,\n    high: 52.15,\n    low: 52.1,\n    close: 52.115,\n    volume: 101557,\n  },\n  {\n    date: 1461341100000,\n    open: 52.11,\n    high: 52.119,\n    low: 52.06,\n    close: 52.0611,\n    volume: 129446,\n  },\n  {\n    date: 1461341160000,\n    open: 52.06,\n    high: 52.07,\n    low: 52.05,\n    close: 52.055,\n    volume: 178672,\n  },\n  {\n    date: 1461341220000,\n    open: 52.055,\n    high: 52.06,\n    low: 52,\n    close: 52.005,\n    volume: 191384,\n  },\n  {\n    date: 1461341280000,\n    open: 52.005,\n    high: 52.035,\n    low: 52,\n    close: 52.02,\n    volume: 115932,\n  },\n  {\n    date: 1461341340000,\n    open: 52.0201,\n    high: 52.06,\n    low: 52.01,\n    close: 52.05,\n    volume: 273179,\n  },\n  {\n    date: 1461341400000,\n    open: 52.05,\n    high: 52.06,\n    low: 52.01,\n    close: 52.03,\n    volume: 308884,\n  },\n  {\n    date: 1461341460000,\n    open: 52.025,\n    high: 52.05,\n    low: 52.01,\n    close: 52.01,\n    volume: 160025,\n  },\n  {\n    date: 1461341520000,\n    open: 52.015,\n    high: 52.05,\n    low: 52.01,\n    close: 52.04,\n    volume: 144714,\n  },\n  {\n    date: 1461341580000,\n    open: 52.0499,\n    high: 52.06,\n    low: 52.005,\n    close: 52.02,\n    volume: 434582,\n  },\n  {\n    date: 1461341640000,\n    open: 52.01,\n    high: 52.0199,\n    low: 51.96,\n    close: 52,\n    volume: 214529,\n  },\n  {\n    date: 1461341700000,\n    open: 51.995,\n    high: 52,\n    low: 51.855,\n    close: 51.8601,\n    volume: 212980,\n  },\n  {\n    date: 1461341760000,\n    open: 51.87,\n    high: 51.87,\n    low: 51.83,\n    close: 51.8401,\n    volume: 111738,\n  },\n  {\n    date: 1461341820000,\n    open: 51.845,\n    high: 51.91,\n    low: 51.84,\n    close: 51.89,\n    volume: 156009,\n  },\n  {\n    date: 1461341880000,\n    open: 51.89,\n    high: 51.93,\n    low: 51.88,\n    close: 51.9291,\n    volume: 139087,\n  },\n  {\n    date: 1461341940000,\n    open: 51.93,\n    high: 51.95,\n    low: 51.92,\n    close: 51.93,\n    volume: 116998,\n  },\n  {\n    date: 1461342000000,\n    open: 51.93,\n    high: 51.94,\n    low: 51.92,\n    close: 51.935,\n    volume: 73439,\n  },\n  {\n    date: 1461342060000,\n    open: 51.9335,\n    high: 51.94,\n    low: 51.88,\n    close: 51.885,\n    volume: 152044,\n  },\n  {\n    date: 1461342120000,\n    open: 51.88,\n    high: 51.96,\n    low: 51.88,\n    close: 51.9091,\n    volume: 104610,\n  },\n  {\n    date: 1461342180000,\n    open: 51.905,\n    high: 51.92,\n    low: 51.9,\n    close: 51.905,\n    volume: 66838,\n  },\n  {\n    date: 1461342240000,\n    open: 51.905,\n    high: 51.95,\n    low: 51.9,\n    close: 51.9399,\n    volume: 128296,\n  },\n  {\n    date: 1461342300000,\n    open: 51.931,\n    high: 51.95,\n    low: 51.9,\n    close: 51.915,\n    volume: 118888,\n  },\n  {\n    date: 1461342360000,\n    open: 51.915,\n    high: 51.94,\n    low: 51.91,\n    close: 51.925,\n    volume: 70877,\n  },\n  {\n    date: 1461342420000,\n    open: 51.9259,\n    high: 51.94,\n    low: 51.925,\n    close: 51.935,\n    volume: 57476,\n  },\n  {\n    date: 1461342480000,\n    open: 51.93,\n    high: 51.94,\n    low: 51.9,\n    close: 51.9099,\n    volume: 101770,\n  },\n  {\n    date: 1461342540000,\n    open: 51.91,\n    high: 51.91,\n    low: 51.87,\n    close: 51.88,\n    volume: 160199,\n  },\n  {\n    date: 1461342600000,\n    open: 51.88,\n    high: 51.885,\n    low: 51.84,\n    close: 51.85,\n    volume: 180997,\n  },\n  {\n    date: 1461342660000,\n    open: 51.845,\n    high: 51.89,\n    low: 51.84,\n    close: 51.886,\n    volume: 90150,\n  },\n  {\n    date: 1461342720000,\n    open: 51.89,\n    high: 51.9,\n    low: 51.88,\n    close: 51.8989,\n    volume: 124365,\n  },\n  {\n    date: 1461342780000,\n    open: 51.9,\n    high: 51.9,\n    low: 51.89,\n    close: 51.895,\n    volume: 28919,\n  },\n  {\n    date: 1461342840000,\n    open: 51.895,\n    high: 52,\n    low: 51.89,\n    close: 51.985,\n    volume: 174595,\n  },\n  {\n    date: 1461342900000,\n    open: 51.99,\n    high: 52.05,\n    low: 51.97,\n    close: 51.98,\n    volume: 166384,\n  },\n  {\n    date: 1461342960000,\n    open: 51.975,\n    high: 52.01,\n    low: 51.975,\n    close: 51.98,\n    volume: 76318,\n  },\n  {\n    date: 1461343020000,\n    open: 51.98,\n    high: 51.9899,\n    low: 51.91,\n    close: 51.9301,\n    volume: 117443,\n  },\n  {\n    date: 1461343080000,\n    open: 51.9366,\n    high: 51.95,\n    low: 51.9,\n    close: 51.905,\n    volume: 158163,\n  },\n  {\n    date: 1461343140000,\n    open: 51.905,\n    high: 51.91,\n    low: 51.85,\n    close: 51.88,\n    volume: 206137,\n  },\n  {\n    date: 1461343200000,\n    open: 51.88,\n    high: 51.92,\n    low: 51.86,\n    close: 51.9189,\n    volume: 92427,\n  },\n  {\n    date: 1461343260000,\n    open: 51.91,\n    high: 51.92,\n    low: 51.89,\n    close: 51.8901,\n    volume: 99352,\n  },\n  {\n    date: 1461343320000,\n    open: 51.891,\n    high: 51.91,\n    low: 51.865,\n    close: 51.9,\n    volume: 53799,\n  },\n  {\n    date: 1461343380000,\n    open: 51.905,\n    high: 51.93,\n    low: 51.88,\n    close: 51.8899,\n    volume: 783042,\n  },\n  {\n    date: 1461343440000,\n    open: 51.88,\n    high: 51.9,\n    low: 51.87,\n    close: 51.8977,\n    volume: 31297,\n  },\n  {\n    date: 1461343500000,\n    open: 51.893,\n    high: 51.9,\n    low: 51.85,\n    close: 51.85,\n    volume: 141480,\n  },\n  {\n    date: 1461343560000,\n    open: 51.85,\n    high: 51.8571,\n    low: 51.67,\n    close: 51.685,\n    volume: 239668,\n  },\n  {\n    date: 1461343620000,\n    open: 51.69,\n    high: 51.69,\n    low: 51.6,\n    close: 51.645,\n    volume: 297881,\n  },\n  {\n    date: 1461343680000,\n    open: 51.64,\n    high: 51.6466,\n    low: 51.56,\n    close: 51.57,\n    volume: 110782,\n  },\n  {\n    date: 1461343740000,\n    open: 51.57,\n    high: 51.675,\n    low: 51.57,\n    close: 51.675,\n    volume: 105488,\n  },\n  {\n    date: 1461343800000,\n    open: 51.6799,\n    high: 51.69,\n    low: 51.59,\n    close: 51.6099,\n    volume: 168975,\n  },\n  {\n    date: 1461343860000,\n    open: 51.6093,\n    high: 51.64,\n    low: 51.595,\n    close: 51.635,\n    volume: 293818,\n  },\n  {\n    date: 1461343920000,\n    open: 51.64,\n    high: 51.69,\n    low: 51.63,\n    close: 51.64,\n    volume: 94861,\n  },\n  {\n    date: 1461343980000,\n    open: 51.64,\n    high: 51.685,\n    low: 51.62,\n    close: 51.685,\n    volume: 102578,\n  },\n  {\n    date: 1461344040000,\n    open: 51.69,\n    high: 51.695,\n    low: 51.65,\n    close: 51.655,\n    volume: 135461,\n  },\n  {\n    date: 1461344100000,\n    open: 51.6565,\n    high: 51.6565,\n    low: 51.62,\n    close: 51.62,\n    volume: 203734,\n  },\n  {\n    date: 1461344160000,\n    open: 51.62,\n    high: 51.64,\n    low: 51.6,\n    close: 51.63,\n    volume: 108532,\n  },\n  {\n    date: 1461344220000,\n    open: 51.6399,\n    high: 51.64,\n    low: 51.61,\n    close: 51.62,\n    volume: 127543,\n  },\n  {\n    date: 1461344280000,\n    open: 51.63,\n    high: 51.74,\n    low: 51.625,\n    close: 51.735,\n    volume: 169039,\n  },\n  {\n    date: 1461344340000,\n    open: 51.73,\n    high: 51.76,\n    low: 51.7,\n    close: 51.7554,\n    volume: 142228,\n  },\n  {\n    date: 1461344400000,\n    open: 51.755,\n    high: 51.76,\n    low: 51.7,\n    close: 51.7,\n    volume: 148574,\n  },\n  {\n    date: 1461344460000,\n    open: 51.7,\n    high: 51.78,\n    low: 51.68,\n    close: 51.755,\n    volume: 139796,\n  },\n  {\n    date: 1461344520000,\n    open: 51.75,\n    high: 51.76,\n    low: 51.7,\n    close: 51.7,\n    volume: 131424,\n  },\n  {\n    date: 1461344580000,\n    open: 51.7,\n    high: 51.72,\n    low: 51.7,\n    close: 51.715,\n    volume: 154148,\n  },\n  {\n    date: 1461344640000,\n    open: 51.715,\n    high: 51.76,\n    low: 51.715,\n    close: 51.75,\n    volume: 103533,\n  },\n  {\n    date: 1461344700000,\n    open: 51.751,\n    high: 51.76,\n    low: 51.73,\n    close: 51.735,\n    volume: 141939,\n  },\n  {\n    date: 1461344760000,\n    open: 51.74,\n    high: 51.76,\n    low: 51.72,\n    close: 51.755,\n    volume: 155449,\n  },\n  {\n    date: 1461344820000,\n    open: 51.755,\n    high: 51.79,\n    low: 51.74,\n    close: 51.7866,\n    volume: 166760,\n  },\n  {\n    date: 1461344880000,\n    open: 51.785,\n    high: 51.8,\n    low: 51.705,\n    close: 51.715,\n    volume: 89610,\n  },\n  {\n    date: 1461344940000,\n    open: 51.71,\n    high: 51.72,\n    low: 51.69,\n    close: 51.698,\n    volume: 181843,\n  },\n  {\n    date: 1461345000000,\n    open: 51.7,\n    high: 51.72,\n    low: 51.69,\n    close: 51.7,\n    volume: 65620,\n  },\n  {\n    date: 1461345060000,\n    open: 51.7,\n    high: 51.71,\n    low: 51.695,\n    close: 51.705,\n    volume: 94065,\n  },\n  {\n    date: 1461345120000,\n    open: 51.705,\n    high: 51.73,\n    low: 51.7,\n    close: 51.7266,\n    volume: 90049,\n  },\n  {\n    date: 1461345180000,\n    open: 51.72,\n    high: 51.73,\n    low: 51.71,\n    close: 51.7239,\n    volume: 66219,\n  },\n  {\n    date: 1461345240000,\n    open: 51.725,\n    high: 51.78,\n    low: 51.71,\n    close: 51.775,\n    volume: 88242,\n  },\n  {\n    date: 1461345300000,\n    open: 51.78,\n    high: 51.81,\n    low: 51.755,\n    close: 51.76,\n    volume: 155997,\n  },\n  {\n    date: 1461345360000,\n    open: 51.765,\n    high: 51.77,\n    low: 51.73,\n    close: 51.73,\n    volume: 92778,\n  },\n  {\n    date: 1461345420000,\n    open: 51.7331,\n    high: 51.7341,\n    low: 51.71,\n    close: 51.725,\n    volume: 79673,\n  },\n  {\n    date: 1461345480000,\n    open: 51.72,\n    high: 51.81,\n    low: 51.72,\n    close: 51.81,\n    volume: 128555,\n  },\n  {\n    date: 1461345540000,\n    open: 51.805,\n    high: 51.82,\n    low: 51.78,\n    close: 51.815,\n    volume: 116234,\n  },\n  {\n    date: 1461345600000,\n    open: 51.815,\n    high: 51.8797,\n    low: 51.8,\n    close: 51.8692,\n    volume: 268108,\n  },\n  {\n    date: 1461345660000,\n    open: 51.87,\n    high: 51.875,\n    low: 51.82,\n    close: 51.825,\n    volume: 150499,\n  },\n  {\n    date: 1461345720000,\n    open: 51.825,\n    high: 51.83,\n    low: 51.78,\n    close: 51.7864,\n    volume: 105153,\n  },\n  {\n    date: 1461345780000,\n    open: 51.78,\n    high: 51.7866,\n    low: 51.7364,\n    close: 51.755,\n    volume: 169239,\n  },\n  {\n    date: 1461345840000,\n    open: 51.76,\n    high: 51.76,\n    low: 51.74,\n    close: 51.75,\n    volume: 76496,\n  },\n  {\n    date: 1461345900000,\n    open: 51.7501,\n    high: 51.79,\n    low: 51.75,\n    close: 51.783,\n    volume: 103735,\n  },\n  {\n    date: 1461345960000,\n    open: 51.7867,\n    high: 51.805,\n    low: 51.78,\n    close: 51.79,\n    volume: 64451,\n  },\n  {\n    date: 1461346020000,\n    open: 51.7834,\n    high: 51.79,\n    low: 51.72,\n    close: 51.7299,\n    volume: 128775,\n  },\n  {\n    date: 1461346080000,\n    open: 51.73,\n    high: 51.75,\n    low: 51.72,\n    close: 51.75,\n    volume: 147957,\n  },\n  {\n    date: 1461346140000,\n    open: 51.75,\n    high: 51.75,\n    low: 51.7101,\n    close: 51.715,\n    volume: 100285,\n  },\n  {\n    date: 1461346200000,\n    open: 51.715,\n    high: 51.72,\n    low: 51.65,\n    close: 51.685,\n    volume: 149935,\n  },\n  {\n    date: 1461346260000,\n    open: 51.69,\n    high: 51.73,\n    low: 51.68,\n    close: 51.726,\n    volume: 89266,\n  },\n  {\n    date: 1461346320000,\n    open: 51.72,\n    high: 51.74,\n    low: 51.71,\n    close: 51.725,\n    volume: 52486,\n  },\n  {\n    date: 1461346380000,\n    open: 51.725,\n    high: 51.73,\n    low: 51.7,\n    close: 51.705,\n    volume: 50941,\n  },\n  {\n    date: 1461346440000,\n    open: 51.705,\n    high: 51.71,\n    low: 51.7,\n    close: 51.7,\n    volume: 55145,\n  },\n  {\n    date: 1461346500000,\n    open: 51.71,\n    high: 51.77,\n    low: 51.7,\n    close: 51.73,\n    volume: 153854,\n  },\n  {\n    date: 1461346560000,\n    open: 51.729,\n    high: 51.74,\n    low: 51.72,\n    close: 51.723,\n    volume: 62937,\n  },\n  {\n    date: 1461346620000,\n    open: 51.725,\n    high: 51.73,\n    low: 51.7,\n    close: 51.705,\n    volume: 87215,\n  },\n  {\n    date: 1461346680000,\n    open: 51.705,\n    high: 51.715,\n    low: 51.7,\n    close: 51.715,\n    volume: 137270,\n  },\n  {\n    date: 1461346740000,\n    open: 51.72,\n    high: 51.77,\n    low: 51.71,\n    close: 51.74,\n    volume: 185420,\n  },\n  {\n    date: 1461346800000,\n    open: 51.75,\n    high: 51.76,\n    low: 51.71,\n    close: 51.716,\n    volume: 81222,\n  },\n  {\n    date: 1461346860000,\n    open: 51.71,\n    high: 51.73,\n    low: 51.69,\n    close: 51.7,\n    volume: 182293,\n  },\n  {\n    date: 1461346920000,\n    open: 51.694,\n    high: 51.757,\n    low: 51.694,\n    close: 51.75,\n    volume: 79470,\n  },\n  {\n    date: 1461346980000,\n    open: 51.745,\n    high: 51.84,\n    low: 51.745,\n    close: 51.82,\n    volume: 152872,\n  },\n  {\n    date: 1461347040000,\n    open: 51.8105,\n    high: 51.88,\n    low: 51.81,\n    close: 51.88,\n    volume: 94510,\n  },\n  {\n    date: 1461347100000,\n    open: 51.885,\n    high: 51.9791,\n    low: 51.885,\n    close: 51.92,\n    volume: 268070,\n  },\n  {\n    date: 1461347160000,\n    open: 51.91,\n    high: 52,\n    low: 51.9,\n    close: 51.9334,\n    volume: 216559,\n  },\n  {\n    date: 1461347220000,\n    open: 51.935,\n    high: 51.94,\n    low: 51.92,\n    close: 51.93,\n    volume: 124193,\n  },\n  {\n    date: 1461347280000,\n    open: 51.925,\n    high: 52.0191,\n    low: 51.91,\n    close: 52,\n    volume: 352596,\n  },\n  {\n    date: 1461347340000,\n    open: 52.005,\n    high: 52.09,\n    low: 52,\n    close: 52.09,\n    volume: 186215,\n  },\n  {\n    date: 1461347400000,\n    open: 52.085,\n    high: 52.11,\n    low: 52.02,\n    close: 52.03,\n    volume: 184159,\n  },\n  {\n    date: 1461347460000,\n    open: 52.035,\n    high: 52.04,\n    low: 52,\n    close: 52,\n    volume: 157347,\n  },\n  {\n    date: 1461347520000,\n    open: 52.005,\n    high: 52.03,\n    low: 52,\n    close: 52.005,\n    volume: 371358,\n  },\n  {\n    date: 1461347580000,\n    open: 52.005,\n    high: 52.05,\n    low: 52,\n    close: 52.025,\n    volume: 189892,\n  },\n  {\n    date: 1461347640000,\n    open: 52.03,\n    high: 52.07,\n    low: 52.02,\n    close: 52.05,\n    volume: 116965,\n  },\n  {\n    date: 1461347700000,\n    open: 52.045,\n    high: 52.09,\n    low: 52,\n    close: 52.065,\n    volume: 144324,\n  },\n  {\n    date: 1461347760000,\n    open: 52.075,\n    high: 52.075,\n    low: 51.98,\n    close: 51.98,\n    volume: 216479,\n  },\n  {\n    date: 1461347820000,\n    open: 51.9825,\n    high: 51.9825,\n    low: 51.88,\n    close: 51.8864,\n    volume: 131951,\n  },\n  {\n    date: 1461347880000,\n    open: 51.885,\n    high: 51.89,\n    low: 51.85,\n    close: 51.86,\n    volume: 84369,\n  },\n  {\n    date: 1461347940000,\n    open: 51.86,\n    high: 51.9,\n    low: 51.85,\n    close: 51.8999,\n    volume: 67561,\n  },\n  {\n    date: 1461348000000,\n    open: 51.9,\n    high: 51.92,\n    low: 51.89,\n    close: 51.8934,\n    volume: 208483,\n  },\n  {\n    date: 1461348060000,\n    open: 51.9,\n    high: 51.92,\n    low: 51.9,\n    close: 51.92,\n    volume: 130256,\n  },\n  {\n    date: 1461348120000,\n    open: 51.92,\n    high: 51.9799,\n    low: 51.91,\n    close: 51.9768,\n    volume: 117329,\n  },\n  {\n    date: 1461348180000,\n    open: 51.974,\n    high: 52.02,\n    low: 51.97,\n    close: 52.0167,\n    volume: 89310,\n  },\n  {\n    date: 1461348240000,\n    open: 52.0101,\n    high: 52.04,\n    low: 51.99,\n    close: 52.0368,\n    volume: 93394,\n  },\n  {\n    date: 1461348300000,\n    open: 52.04,\n    high: 52.04,\n    low: 51.98,\n    close: 51.98,\n    volume: 138891,\n  },\n  {\n    date: 1461348360000,\n    open: 51.97,\n    high: 51.975,\n    low: 51.95,\n    close: 51.9595,\n    volume: 66278,\n  },\n  {\n    date: 1461348420000,\n    open: 51.95,\n    high: 51.955,\n    low: 51.86,\n    close: 51.87,\n    volume: 145279,\n  },\n  {\n    date: 1461348480000,\n    open: 51.87,\n    high: 51.88,\n    low: 51.85,\n    close: 51.8534,\n    volume: 137210,\n  },\n  {\n    date: 1461348540000,\n    open: 51.8562,\n    high: 51.87,\n    low: 51.845,\n    close: 51.86,\n    volume: 127092,\n  },\n  {\n    date: 1461348600000,\n    open: 51.856,\n    high: 51.865,\n    low: 51.79,\n    close: 51.8099,\n    volume: 151494,\n  },\n  {\n    date: 1461348660000,\n    open: 51.81,\n    high: 51.87,\n    low: 51.8,\n    close: 51.865,\n    volume: 113002,\n  },\n  {\n    date: 1461348720000,\n    open: 51.8699,\n    high: 51.87,\n    low: 51.85,\n    close: 51.865,\n    volume: 49517,\n  },\n  {\n    date: 1461348780000,\n    open: 51.865,\n    high: 51.93,\n    low: 51.865,\n    close: 51.88,\n    volume: 92541,\n  },\n  {\n    date: 1461348840000,\n    open: 51.8734,\n    high: 51.89,\n    low: 51.87,\n    close: 51.885,\n    volume: 65299,\n  },\n  {\n    date: 1461348900000,\n    open: 51.8862,\n    high: 51.92,\n    low: 51.88,\n    close: 51.9199,\n    volume: 80162,\n  },\n  {\n    date: 1461348960000,\n    open: 51.92,\n    high: 51.95,\n    low: 51.91,\n    close: 51.915,\n    volume: 90041,\n  },\n  {\n    date: 1461349020000,\n    open: 51.915,\n    high: 51.92,\n    low: 51.9,\n    close: 51.905,\n    volume: 57830,\n  },\n  {\n    date: 1461349080000,\n    open: 51.91,\n    high: 51.94,\n    low: 51.9,\n    close: 51.936,\n    volume: 142049,\n  },\n  {\n    date: 1461349140000,\n    open: 51.935,\n    high: 52.01,\n    low: 51.92,\n    close: 52.0095,\n    volume: 102152,\n  },\n  {\n    date: 1461349200000,\n    open: 52.01,\n    high: 52.03,\n    low: 52,\n    close: 52.005,\n    volume: 100990,\n  },\n  {\n    date: 1461349260000,\n    open: 52.0029,\n    high: 52.0099,\n    low: 51.94,\n    close: 52,\n    volume: 171254,\n  },\n  {\n    date: 1461349320000,\n    open: 52,\n    high: 52.01,\n    low: 51.98,\n    close: 51.9864,\n    volume: 83013,\n  },\n  {\n    date: 1461349380000,\n    open: 51.99,\n    high: 52.015,\n    low: 51.98,\n    close: 52,\n    volume: 131754,\n  },\n  {\n    date: 1461349440000,\n    open: 51.995,\n    high: 52.08,\n    low: 51.995,\n    close: 52.06,\n    volume: 142860,\n  },\n  {\n    date: 1461349500000,\n    open: 52.0666,\n    high: 52.0699,\n    low: 52.02,\n    close: 52.02,\n    volume: 93912,\n  },\n  {\n    date: 1461349560000,\n    open: 52.03,\n    high: 52.05,\n    low: 52.02,\n    close: 52.035,\n    volume: 150261,\n  },\n  {\n    date: 1461349620000,\n    open: 52.04,\n    high: 52.07,\n    low: 52.03,\n    close: 52.065,\n    volume: 87871,\n  },\n  {\n    date: 1461349680000,\n    open: 52.06,\n    high: 52.09,\n    low: 52.04,\n    close: 52.055,\n    volume: 161890,\n  },\n  {\n    date: 1461349740000,\n    open: 52.05,\n    high: 52.06,\n    low: 52,\n    close: 52,\n    volume: 158379,\n  },\n  {\n    date: 1461349800000,\n    open: 52,\n    high: 52.01,\n    low: 51.97,\n    close: 52.0075,\n    volume: 128292,\n  },\n  {\n    date: 1461349860000,\n    open: 52.01,\n    high: 52.02,\n    low: 51.99,\n    close: 52.01,\n    volume: 76306,\n  },\n  {\n    date: 1461349920000,\n    open: 52.01,\n    high: 52.03,\n    low: 52,\n    close: 52.015,\n    volume: 117064,\n  },\n  {\n    date: 1461349980000,\n    open: 52.017,\n    high: 52.04,\n    low: 52.01,\n    close: 52.035,\n    volume: 57315,\n  },\n  {\n    date: 1461350040000,\n    open: 52.03,\n    high: 52.03,\n    low: 51.975,\n    close: 51.985,\n    volume: 148255,\n  },\n  {\n    date: 1461350100000,\n    open: 51.98,\n    high: 51.99,\n    low: 51.91,\n    close: 51.92,\n    volume: 136579,\n  },\n  {\n    date: 1461350160000,\n    open: 51.9299,\n    high: 51.99,\n    low: 51.92,\n    close: 51.98,\n    volume: 73032,\n  },\n  {\n    date: 1461350220000,\n    open: 51.9899,\n    high: 52.02,\n    low: 51.98,\n    close: 52.005,\n    volume: 165938,\n  },\n  {\n    date: 1461350280000,\n    open: 52.0065,\n    high: 52.03,\n    low: 52,\n    close: 52.025,\n    volume: 250968,\n  },\n  {\n    date: 1461350340000,\n    open: 52.025,\n    high: 52.05,\n    low: 52.02,\n    close: 52.04,\n    volume: 98092,\n  },\n  {\n    date: 1461350400000,\n    open: 52.05,\n    high: 52.06,\n    low: 52.04,\n    close: 52.055,\n    volume: 320919,\n  },\n  {\n    date: 1461350460000,\n    open: 52.055,\n    high: 52.085,\n    low: 52.05,\n    close: 52.065,\n    volume: 84598,\n  },\n  {\n    date: 1461350520000,\n    open: 52.065,\n    high: 52.07,\n    low: 52.02,\n    close: 52.025,\n    volume: 75803,\n  },\n  {\n    date: 1461350580000,\n    open: 52.03,\n    high: 52.03,\n    low: 52,\n    close: 52.005,\n    volume: 200200,\n  },\n  {\n    date: 1461350640000,\n    open: 52.005,\n    high: 52.08,\n    low: 52,\n    close: 52.065,\n    volume: 126503,\n  },\n  {\n    date: 1461350700000,\n    open: 52.065,\n    high: 52.08,\n    low: 52.04,\n    close: 52.08,\n    volume: 95626,\n  },\n  {\n    date: 1461350760000,\n    open: 52.0735,\n    high: 52.0765,\n    low: 52.02,\n    close: 52.02,\n    volume: 71761,\n  },\n  {\n    date: 1461350820000,\n    open: 52.03,\n    high: 52.04,\n    low: 51.99,\n    close: 52,\n    volume: 191581,\n  },\n  {\n    date: 1461350880000,\n    open: 52.01,\n    high: 52.02,\n    low: 51.995,\n    close: 52.015,\n    volume: 61511,\n  },\n  {\n    date: 1461350940000,\n    open: 52.014,\n    high: 52.08,\n    low: 52.01,\n    close: 52.08,\n    volume: 105583,\n  },\n  {\n    date: 1461351000000,\n    open: 52.07,\n    high: 52.0762,\n    low: 52.02,\n    close: 52.03,\n    volume: 100041,\n  },\n  {\n    date: 1461351060000,\n    open: 52.03,\n    high: 52.035,\n    low: 52,\n    close: 52.015,\n    volume: 196547,\n  },\n  {\n    date: 1461351120000,\n    open: 52.01,\n    high: 52.02,\n    low: 52,\n    close: 52.02,\n    volume: 88662,\n  },\n  {\n    date: 1461351180000,\n    open: 52.015,\n    high: 52.03,\n    low: 52.01,\n    close: 52.0165,\n    volume: 67623,\n  },\n  {\n    date: 1461351240000,\n    open: 52.02,\n    high: 52.02,\n    low: 52.005,\n    close: 52.015,\n    volume: 81597,\n  },\n  {\n    date: 1461351300000,\n    open: 52.015,\n    high: 52.04,\n    low: 52.01,\n    close: 52.025,\n    volume: 165666,\n  },\n  {\n    date: 1461351360000,\n    open: 52.028,\n    high: 52.04,\n    low: 52.01,\n    close: 52.02,\n    volume: 110480,\n  },\n  {\n    date: 1461351420000,\n    open: 52.02,\n    high: 52.05,\n    low: 52.01,\n    close: 52.0389,\n    volume: 86499,\n  },\n  {\n    date: 1461351480000,\n    open: 52.03,\n    high: 52.04,\n    low: 51.99,\n    close: 52,\n    volume: 138786,\n  },\n  {\n    date: 1461351540000,\n    open: 51.9959,\n    high: 52.01,\n    low: 51.99,\n    close: 51.9915,\n    volume: 135821,\n  },\n  {\n    date: 1461351600000,\n    open: 51.995,\n    high: 52.01,\n    low: 51.98,\n    close: 52,\n    volume: 142480,\n  },\n  {\n    date: 1461351660000,\n    open: 52,\n    high: 52.005,\n    low: 51.94,\n    close: 51.945,\n    volume: 206199,\n  },\n  {\n    date: 1461351720000,\n    open: 51.945,\n    high: 51.96,\n    low: 51.88,\n    close: 51.8999,\n    volume: 181709,\n  },\n  {\n    date: 1461351780000,\n    open: 51.8999,\n    high: 51.91,\n    low: 51.85,\n    close: 51.88,\n    volume: 169963,\n  },\n  {\n    date: 1461351840000,\n    open: 51.8735,\n    high: 51.895,\n    low: 51.85,\n    close: 51.855,\n    volume: 148425,\n  },\n  {\n    date: 1461351900000,\n    open: 51.8558,\n    high: 51.86,\n    low: 51.83,\n    close: 51.84,\n    volume: 249979,\n  },\n  {\n    date: 1461351960000,\n    open: 51.8499,\n    high: 51.91,\n    low: 51.82,\n    close: 51.9038,\n    volume: 131629,\n  },\n  {\n    date: 1461352020000,\n    open: 51.91,\n    high: 51.93,\n    low: 51.88,\n    close: 51.9235,\n    volume: 122860,\n  },\n  {\n    date: 1461352080000,\n    open: 51.926,\n    high: 51.9275,\n    low: 51.91,\n    close: 51.92,\n    volume: 42366,\n  },\n  {\n    date: 1461352140000,\n    open: 51.91,\n    high: 51.93,\n    low: 51.89,\n    close: 51.9192,\n    volume: 133930,\n  },\n  {\n    date: 1461352200000,\n    open: 51.915,\n    high: 51.92,\n    low: 51.88,\n    close: 51.9199,\n    volume: 113100,\n  },\n  {\n    date: 1461352260000,\n    open: 51.93,\n    high: 52,\n    low: 51.92,\n    close: 51.97,\n    volume: 157267,\n  },\n  {\n    date: 1461352320000,\n    open: 51.97,\n    high: 51.99,\n    low: 51.94,\n    close: 51.975,\n    volume: 171714,\n  },\n  {\n    date: 1461352380000,\n    open: 51.97,\n    high: 51.98,\n    low: 51.88,\n    close: 51.88,\n    volume: 213437,\n  },\n  {\n    date: 1461352440000,\n    open: 51.88,\n    high: 51.92,\n    low: 51.88,\n    close: 51.905,\n    volume: 201202,\n  },\n  {\n    date: 1461352500000,\n    open: 51.905,\n    high: 51.9065,\n    low: 51.78,\n    close: 51.783,\n    volume: 295549,\n  },\n  {\n    date: 1461352560000,\n    open: 51.79,\n    high: 51.8,\n    low: 51.7,\n    close: 51.71,\n    volume: 281972,\n  },\n  {\n    date: 1461352620000,\n    open: 51.705,\n    high: 51.71,\n    low: 51.65,\n    close: 51.6834,\n    volume: 313058,\n  },\n  {\n    date: 1461352680000,\n    open: 51.6872,\n    high: 51.7299,\n    low: 51.64,\n    close: 51.72,\n    volume: 218059,\n  },\n  {\n    date: 1461352740000,\n    open: 51.72,\n    high: 51.7599,\n    low: 51.7,\n    close: 51.7398,\n    volume: 166679,\n  },\n  {\n    date: 1461352800000,\n    open: 51.74,\n    high: 51.7699,\n    low: 51.72,\n    close: 51.72,\n    volume: 123014,\n  },\n  {\n    date: 1461352860000,\n    open: 51.72,\n    high: 51.74,\n    low: 51.7,\n    close: 51.725,\n    volume: 131390,\n  },\n  {\n    date: 1461352920000,\n    open: 51.72,\n    high: 51.73,\n    low: 51.67,\n    close: 51.7299,\n    volume: 217898,\n  },\n  {\n    date: 1461352980000,\n    open: 51.725,\n    high: 51.75,\n    low: 51.7,\n    close: 51.7499,\n    volume: 162296,\n  },\n  {\n    date: 1461353040000,\n    open: 51.745,\n    high: 51.745,\n    low: 51.68,\n    close: 51.735,\n    volume: 246690,\n  },\n  {\n    date: 1461353100000,\n    open: 51.7399,\n    high: 51.79,\n    low: 51.72,\n    close: 51.7362,\n    volume: 261164,\n  },\n  {\n    date: 1461353160000,\n    open: 51.736,\n    high: 51.76,\n    low: 51.72,\n    close: 51.74,\n    volume: 106987,\n  },\n  {\n    date: 1461353220000,\n    open: 51.735,\n    high: 51.78,\n    low: 51.735,\n    close: 51.77,\n    volume: 156943,\n  },\n  {\n    date: 1461353280000,\n    open: 51.766,\n    high: 51.8,\n    low: 51.76,\n    close: 51.7897,\n    volume: 190798,\n  },\n  {\n    date: 1461353340000,\n    open: 51.785,\n    high: 51.82,\n    low: 51.77,\n    close: 51.81,\n    volume: 112470,\n  },\n  {\n    date: 1461353400000,\n    open: 51.82,\n    high: 51.85,\n    low: 51.81,\n    close: 51.83,\n    volume: 179079,\n  },\n  {\n    date: 1461353460000,\n    open: 51.8301,\n    high: 51.8399,\n    low: 51.75,\n    close: 51.7665,\n    volume: 253217,\n  },\n  {\n    date: 1461353520000,\n    open: 51.765,\n    high: 51.795,\n    low: 51.75,\n    close: 51.775,\n    volume: 159931,\n  },\n  {\n    date: 1461353580000,\n    open: 51.775,\n    high: 51.79,\n    low: 51.75,\n    close: 51.79,\n    volume: 152949,\n  },\n  {\n    date: 1461353640000,\n    open: 51.785,\n    high: 51.81,\n    low: 51.77,\n    close: 51.805,\n    volume: 171978,\n  },\n  {\n    date: 1461353700000,\n    open: 51.8,\n    high: 51.8087,\n    low: 51.74,\n    close: 51.74,\n    volume: 195472,\n  },\n  {\n    date: 1461353760000,\n    open: 51.7401,\n    high: 51.75,\n    low: 51.72,\n    close: 51.74,\n    volume: 132009,\n  },\n  {\n    date: 1461353820000,\n    open: 51.735,\n    high: 51.76,\n    low: 51.73,\n    close: 51.75,\n    volume: 99995,\n  },\n  {\n    date: 1461353880000,\n    open: 51.745,\n    high: 51.77,\n    low: 51.74,\n    close: 51.7599,\n    volume: 247220,\n  },\n  {\n    date: 1461353940000,\n    open: 51.75,\n    high: 51.76,\n    low: 51.7,\n    close: 51.725,\n    volume: 196597,\n  },\n  {\n    date: 1461354000000,\n    open: 51.72,\n    high: 51.735,\n    low: 51.69,\n    close: 51.695,\n    volume: 215646,\n  },\n  {\n    date: 1461354060000,\n    open: 51.69,\n    high: 51.7,\n    low: 51.65,\n    close: 51.69,\n    volume: 302547,\n  },\n  {\n    date: 1461354120000,\n    open: 51.68,\n    high: 51.69,\n    low: 51.61,\n    close: 51.635,\n    volume: 322216,\n  },\n  {\n    date: 1461354180000,\n    open: 51.64,\n    high: 51.67,\n    low: 51.61,\n    close: 51.65,\n    volume: 349391,\n  },\n  {\n    date: 1461354240000,\n    open: 51.655,\n    high: 51.66,\n    low: 51.64,\n    close: 51.645,\n    volume: 203356,\n  },\n  {\n    date: 1461354300000,\n    open: 51.649,\n    high: 51.66,\n    low: 51.63,\n    close: 51.65,\n    volume: 214053,\n  },\n  {\n    date: 1461354360000,\n    open: 51.65,\n    high: 51.7,\n    low: 51.64,\n    close: 51.685,\n    volume: 320156,\n  },\n  {\n    date: 1461354420000,\n    open: 51.685,\n    high: 51.69,\n    low: 51.68,\n    close: 51.685,\n    volume: 328772,\n  },\n  {\n    date: 1461354480000,\n    open: 51.685,\n    high: 51.69,\n    low: 51.66,\n    close: 51.665,\n    volume: 289212,\n  },\n  {\n    date: 1461354540000,\n    open: 51.667,\n    high: 51.68,\n    low: 51.64,\n    close: 51.65,\n    volume: 380628,\n  },\n  {\n    date: 1461354600000,\n    open: 51.655,\n    high: 51.76,\n    low: 51.65,\n    close: 51.745,\n    volume: 323415,\n  },\n  {\n    date: 1461354660000,\n    open: 51.755,\n    high: 51.77,\n    low: 51.71,\n    close: 51.7365,\n    volume: 620111,\n  },\n  {\n    date: 1461354720000,\n    open: 51.7365,\n    high: 51.77,\n    low: 51.73,\n    close: 51.76,\n    volume: 326603,\n  },\n  {\n    date: 1461354780000,\n    open: 51.76,\n    high: 51.83,\n    low: 51.76,\n    close: 51.815,\n    volume: 339264,\n  },\n  {\n    date: 1461354840000,\n    open: 51.815,\n    high: 51.82,\n    low: 51.77,\n    close: 51.785,\n    volume: 316305,\n  },\n  {\n    date: 1461354900000,\n    open: 51.785,\n    high: 51.79,\n    low: 51.7601,\n    close: 51.77,\n    volume: 441181,\n  },\n  {\n    date: 1461354960000,\n    open: 51.78,\n    high: 51.79,\n    low: 51.76,\n    close: 51.77,\n    volume: 545388,\n  },\n  {\n    date: 1461355020000,\n    open: 51.77,\n    high: 51.82,\n    low: 51.765,\n    close: 51.805,\n    volume: 437874,\n  },\n  {\n    date: 1461355080000,\n    open: 51.8,\n    high: 51.81,\n    low: 51.77,\n    close: 51.777,\n    volume: 450747,\n  },\n  {\n    date: 1461355140000,\n    open: 51.775,\n    high: 51.78,\n    low: 51.72,\n    close: 51.77,\n    volume: 749366,\n  },\n  {\n    date: 1461355200000,\n    open: 51.765,\n    high: 51.87,\n    low: 51.73,\n    close: 51.78,\n    volume: 6084639,\n  },\n  {\n    date: 1461591000000,\n    open: 51.78,\n    high: 51.84,\n    low: 51.77,\n    close: 51.81,\n    volume: 588218,\n  },\n  {\n    date: 1461591060000,\n    open: 51.79,\n    high: 51.86,\n    low: 51.72,\n    close: 51.74,\n    volume: 160350,\n  },\n  {\n    date: 1461591120000,\n    open: 51.745,\n    high: 51.76,\n    low: 51.64,\n    close: 51.645,\n    volume: 257999,\n  },\n  {\n    date: 1461591180000,\n    open: 51.6405,\n    high: 51.75,\n    low: 51.63,\n    close: 51.7499,\n    volume: 229991,\n  },\n  {\n    date: 1461591240000,\n    open: 51.745,\n    high: 51.8025,\n    low: 51.73,\n    close: 51.75,\n    volume: 198480,\n  },\n  {\n    date: 1461591300000,\n    open: 51.745,\n    high: 51.82,\n    low: 51.74,\n    close: 51.82,\n    volume: 186251,\n  },\n  {\n    date: 1461591360000,\n    open: 51.83,\n    high: 51.91,\n    low: 51.822,\n    close: 51.88,\n    volume: 227322,\n  },\n  {\n    date: 1461591420000,\n    open: 51.88,\n    high: 51.905,\n    low: 51.83,\n    close: 51.88,\n    volume: 157948,\n  },\n  {\n    date: 1461591480000,\n    open: 51.88,\n    high: 51.96,\n    low: 51.88,\n    close: 51.94,\n    volume: 196169,\n  },\n  {\n    date: 1461591540000,\n    open: 51.9499,\n    high: 51.99,\n    low: 51.94,\n    close: 51.9401,\n    volume: 155545,\n  },\n  {\n    date: 1461591600000,\n    open: 51.945,\n    high: 51.95,\n    low: 51.92,\n    close: 51.9205,\n    volume: 120714,\n  },\n  {\n    date: 1461591660000,\n    open: 51.925,\n    high: 51.925,\n    low: 51.78,\n    close: 51.8163,\n    volume: 263986,\n  },\n  {\n    date: 1461591720000,\n    open: 51.815,\n    high: 51.82,\n    low: 51.71,\n    close: 51.77,\n    volume: 142780,\n  },\n  {\n    date: 1461591780000,\n    open: 51.775,\n    high: 51.82,\n    low: 51.77,\n    close: 51.791,\n    volume: 131694,\n  },\n  {\n    date: 1461591840000,\n    open: 51.795,\n    high: 51.96,\n    low: 51.7909,\n    close: 51.9101,\n    volume: 168698,\n  },\n  {\n    date: 1461591900000,\n    open: 51.915,\n    high: 51.92,\n    low: 51.84,\n    close: 51.855,\n    volume: 87433,\n  },\n  {\n    date: 1461591960000,\n    open: 51.855,\n    high: 51.89,\n    low: 51.85,\n    close: 51.885,\n    volume: 57411,\n  },\n  {\n    date: 1461592020000,\n    open: 51.885,\n    high: 51.92,\n    low: 51.86,\n    close: 51.91,\n    volume: 115549,\n  },\n  {\n    date: 1461592080000,\n    open: 51.91,\n    high: 51.95,\n    low: 51.88,\n    close: 51.9131,\n    volume: 98045,\n  },\n  {\n    date: 1461592140000,\n    open: 51.91,\n    high: 51.92,\n    low: 51.8538,\n    close: 51.87,\n    volume: 74013,\n  },\n  {\n    date: 1461592200000,\n    open: 51.8662,\n    high: 51.88,\n    low: 51.83,\n    close: 51.872,\n    volume: 125514,\n  },\n  {\n    date: 1461592260000,\n    open: 51.87,\n    high: 51.88,\n    low: 51.84,\n    close: 51.8499,\n    volume: 86575,\n  },\n  {\n    date: 1461592320000,\n    open: 51.845,\n    high: 51.87,\n    low: 51.8,\n    close: 51.865,\n    volume: 88289,\n  },\n  {\n    date: 1461592380000,\n    open: 51.87,\n    high: 51.88,\n    low: 51.855,\n    close: 51.865,\n    volume: 58772,\n  },\n  {\n    date: 1461592440000,\n    open: 51.86,\n    high: 51.87,\n    low: 51.83,\n    close: 51.8501,\n    volume: 75701,\n  },\n  {\n    date: 1461592500000,\n    open: 51.85,\n    high: 51.865,\n    low: 51.83,\n    close: 51.865,\n    volume: 63213,\n  },\n  {\n    date: 1461592560000,\n    open: 51.865,\n    high: 51.89,\n    low: 51.85,\n    close: 51.875,\n    volume: 152798,\n  },\n  {\n    date: 1461592620000,\n    open: 51.87,\n    high: 51.89,\n    low: 51.855,\n    close: 51.885,\n    volume: 99840,\n  },\n  {\n    date: 1461592680000,\n    open: 51.88,\n    high: 51.945,\n    low: 51.87,\n    close: 51.945,\n    volume: 156791,\n  },\n  {\n    date: 1461592740000,\n    open: 51.95,\n    high: 52,\n    low: 51.94,\n    close: 51.97,\n    volume: 158906,\n  },\n  {\n    date: 1461592800000,\n    open: 51.972,\n    high: 52,\n    low: 51.91,\n    close: 52,\n    volume: 134219,\n  },\n  {\n    date: 1461592860000,\n    open: 52,\n    high: 52.08,\n    low: 51.99,\n    close: 52.06,\n    volume: 248854,\n  },\n  {\n    date: 1461592920000,\n    open: 52.06,\n    high: 52.075,\n    low: 52.01,\n    close: 52.02,\n    volume: 186843,\n  },\n  {\n    date: 1461592980000,\n    open: 52.02,\n    high: 52.03,\n    low: 51.97,\n    close: 52.03,\n    volume: 141652,\n  },\n  {\n    date: 1461593040000,\n    open: 52.03,\n    high: 52.1,\n    low: 52.03,\n    close: 52.04,\n    volume: 113084,\n  },\n  {\n    date: 1461593100000,\n    open: 52.045,\n    high: 52.06,\n    low: 51.97,\n    close: 51.975,\n    volume: 116502,\n  },\n  {\n    date: 1461593160000,\n    open: 51.98,\n    high: 52.01,\n    low: 51.9748,\n    close: 52,\n    volume: 143056,\n  },\n  {\n    date: 1461593220000,\n    open: 52,\n    high: 52.015,\n    low: 51.995,\n    close: 52,\n    volume: 125342,\n  },\n  {\n    date: 1461593280000,\n    open: 52,\n    high: 52.045,\n    low: 51.99,\n    close: 52.025,\n    volume: 55946,\n  },\n  {\n    date: 1461593340000,\n    open: 52.02,\n    high: 52.03,\n    low: 51.99,\n    close: 52,\n    volume: 83913,\n  },\n  {\n    date: 1461593400000,\n    open: 52,\n    high: 52,\n    low: 51.97,\n    close: 51.975,\n    volume: 60483,\n  },\n  {\n    date: 1461593460000,\n    open: 51.97,\n    high: 51.99,\n    low: 51.951,\n    close: 51.98,\n    volume: 125233,\n  },\n  {\n    date: 1461593520000,\n    open: 51.975,\n    high: 51.98,\n    low: 51.955,\n    close: 51.975,\n    volume: 89984,\n  },\n  {\n    date: 1461593580000,\n    open: 51.9762,\n    high: 51.98,\n    low: 51.94,\n    close: 51.98,\n    volume: 112733,\n  },\n  {\n    date: 1461593640000,\n    open: 51.975,\n    high: 52,\n    low: 51.97,\n    close: 51.975,\n    volume: 80854,\n  },\n  {\n    date: 1461593700000,\n    open: 51.97,\n    high: 52.01,\n    low: 51.97,\n    close: 51.985,\n    volume: 246192,\n  },\n  {\n    date: 1461593760000,\n    open: 51.98,\n    high: 52.01,\n    low: 51.98,\n    close: 52.005,\n    volume: 104896,\n  },\n  {\n    date: 1461593820000,\n    open: 52.01,\n    high: 52.04,\n    low: 52,\n    close: 52.035,\n    volume: 115504,\n  },\n  {\n    date: 1461593880000,\n    open: 52.04,\n    high: 52.05,\n    low: 52.03,\n    close: 52.035,\n    volume: 106171,\n  },\n  {\n    date: 1461593940000,\n    open: 52.035,\n    high: 52.04,\n    low: 52,\n    close: 52,\n    volume: 92269,\n  },\n  {\n    date: 1461594000000,\n    open: 52,\n    high: 52.01,\n    low: 51.9975,\n    close: 52,\n    volume: 86877,\n  },\n  {\n    date: 1461594060000,\n    open: 52,\n    high: 52.005,\n    low: 51.94,\n    close: 51.94,\n    volume: 123366,\n  },\n  {\n    date: 1461594120000,\n    open: 51.9499,\n    high: 51.9615,\n    low: 51.94,\n    close: 51.94,\n    volume: 54268,\n  },\n  {\n    date: 1461594180000,\n    open: 51.9489,\n    high: 51.97,\n    low: 51.91,\n    close: 51.915,\n    volume: 63386,\n  },\n  {\n    date: 1461594240000,\n    open: 51.918,\n    high: 51.92,\n    low: 51.88,\n    close: 51.88,\n    volume: 54103,\n  },\n  {\n    date: 1461594300000,\n    open: 51.89,\n    high: 51.89,\n    low: 51.865,\n    close: 51.865,\n    volume: 51689,\n  },\n  {\n    date: 1461594360000,\n    open: 51.865,\n    high: 51.93,\n    low: 51.86,\n    close: 51.8899,\n    volume: 87384,\n  },\n  {\n    date: 1461594420000,\n    open: 51.89,\n    high: 51.9,\n    low: 51.85,\n    close: 51.855,\n    volume: 69694,\n  },\n  {\n    date: 1461594480000,\n    open: 51.86,\n    high: 51.88,\n    low: 51.82,\n    close: 51.87,\n    volume: 163214,\n  },\n  {\n    date: 1461594540000,\n    open: 51.87,\n    high: 51.91,\n    low: 51.8601,\n    close: 51.895,\n    volume: 143582,\n  },\n  {\n    date: 1461594600000,\n    open: 51.895,\n    high: 51.92,\n    low: 51.89,\n    close: 51.905,\n    volume: 35931,\n  },\n  {\n    date: 1461594660000,\n    open: 51.9099,\n    high: 51.91,\n    low: 51.87,\n    close: 51.885,\n    volume: 114183,\n  },\n  {\n    date: 1461594720000,\n    open: 51.89,\n    high: 51.91,\n    low: 51.86,\n    close: 51.8799,\n    volume: 101912,\n  },\n  {\n    date: 1461594780000,\n    open: 51.88,\n    high: 51.88,\n    low: 51.86,\n    close: 51.865,\n    volume: 80242,\n  },\n  {\n    date: 1461594840000,\n    open: 51.87,\n    high: 51.88,\n    low: 51.86,\n    close: 51.86,\n    volume: 92566,\n  },\n  {\n    date: 1461594900000,\n    open: 51.865,\n    high: 51.94,\n    low: 51.8635,\n    close: 51.94,\n    volume: 198274,\n  },\n  {\n    date: 1461594960000,\n    open: 51.94,\n    high: 51.99,\n    low: 51.93,\n    close: 51.95,\n    volume: 193026,\n  },\n  {\n    date: 1461595020000,\n    open: 51.96,\n    high: 51.98,\n    low: 51.94,\n    close: 51.96,\n    volume: 81441,\n  },\n  {\n    date: 1461595080000,\n    open: 51.955,\n    high: 51.96,\n    low: 51.95,\n    close: 51.955,\n    volume: 49397,\n  },\n  {\n    date: 1461595140000,\n    open: 51.955,\n    high: 51.955,\n    low: 51.9,\n    close: 51.9464,\n    volume: 136371,\n  },\n  {\n    date: 1461595200000,\n    open: 51.95,\n    high: 51.95,\n    low: 51.89,\n    close: 51.92,\n    volume: 80190,\n  },\n  {\n    date: 1461595260000,\n    open: 51.93,\n    high: 51.945,\n    low: 51.91,\n    close: 51.94,\n    volume: 71739,\n  },\n  {\n    date: 1461595320000,\n    open: 51.945,\n    high: 52,\n    low: 51.93,\n    close: 51.98,\n    volume: 81048,\n  },\n  {\n    date: 1461595380000,\n    open: 51.98,\n    high: 52.01,\n    low: 51.95,\n    close: 51.955,\n    volume: 223866,\n  },\n  {\n    date: 1461595440000,\n    open: 51.955,\n    high: 51.96,\n    low: 51.89,\n    close: 51.9,\n    volume: 184175,\n  },\n  {\n    date: 1461595500000,\n    open: 51.8987,\n    high: 51.9,\n    low: 51.86,\n    close: 51.889,\n    volume: 112705,\n  },\n  {\n    date: 1461595560000,\n    open: 51.885,\n    high: 51.889,\n    low: 51.825,\n    close: 51.8276,\n    volume: 154690,\n  },\n  {\n    date: 1461595620000,\n    open: 51.83,\n    high: 51.89,\n    low: 51.83,\n    close: 51.89,\n    volume: 122451,\n  },\n  {\n    date: 1461595680000,\n    open: 51.89,\n    high: 51.97,\n    low: 51.8801,\n    close: 51.97,\n    volume: 86409,\n  },\n  {\n    date: 1461595740000,\n    open: 51.97,\n    high: 51.98,\n    low: 51.95,\n    close: 51.9675,\n    volume: 70494,\n  },\n  {\n    date: 1461595800000,\n    open: 51.965,\n    high: 51.97,\n    low: 51.92,\n    close: 51.935,\n    volume: 70270,\n  },\n  {\n    date: 1461595860000,\n    open: 51.935,\n    high: 51.95,\n    low: 51.87,\n    close: 51.87,\n    volume: 80454,\n  },\n  {\n    date: 1461595920000,\n    open: 51.8764,\n    high: 51.9,\n    low: 51.87,\n    close: 51.89,\n    volume: 116636,\n  },\n  {\n    date: 1461595980000,\n    open: 51.89,\n    high: 51.9,\n    low: 51.87,\n    close: 51.875,\n    volume: 79035,\n  },\n  {\n    date: 1461596040000,\n    open: 51.87,\n    high: 51.89,\n    low: 51.82,\n    close: 51.89,\n    volume: 127682,\n  },\n  {\n    date: 1461596100000,\n    open: 51.89,\n    high: 51.9,\n    low: 51.85,\n    close: 51.855,\n    volume: 37057,\n  },\n  {\n    date: 1461596160000,\n    open: 51.855,\n    high: 51.86,\n    low: 51.83,\n    close: 51.84,\n    volume: 67143,\n  },\n  {\n    date: 1461596220000,\n    open: 51.84,\n    high: 51.85,\n    low: 51.84,\n    close: 51.845,\n    volume: 24678,\n  },\n  {\n    date: 1461596280000,\n    open: 51.8415,\n    high: 51.85,\n    low: 51.82,\n    close: 51.8266,\n    volume: 133909,\n  },\n  {\n    date: 1461596340000,\n    open: 51.82,\n    high: 51.8469,\n    low: 51.82,\n    close: 51.84,\n    volume: 88710,\n  },\n  {\n    date: 1461596400000,\n    open: 51.84,\n    high: 51.845,\n    low: 51.81,\n    close: 51.83,\n    volume: 63574,\n  },\n  {\n    date: 1461596460000,\n    open: 51.8289,\n    high: 51.88,\n    low: 51.82,\n    close: 51.8799,\n    volume: 65122,\n  },\n  {\n    date: 1461596520000,\n    open: 51.88,\n    high: 51.9301,\n    low: 51.88,\n    close: 51.895,\n    volume: 57609,\n  },\n  {\n    date: 1461596580000,\n    open: 51.895,\n    high: 51.91,\n    low: 51.88,\n    close: 51.91,\n    volume: 47384,\n  },\n  {\n    date: 1461596640000,\n    open: 51.91,\n    high: 51.92,\n    low: 51.88,\n    close: 51.89,\n    volume: 75404,\n  },\n  {\n    date: 1461596700000,\n    open: 51.9,\n    high: 51.92,\n    low: 51.87,\n    close: 51.87,\n    volume: 78708,\n  },\n  {\n    date: 1461596760000,\n    open: 51.87,\n    high: 51.885,\n    low: 51.87,\n    close: 51.885,\n    volume: 58179,\n  },\n  {\n    date: 1461596820000,\n    open: 51.8867,\n    high: 51.89,\n    low: 51.875,\n    close: 51.88,\n    volume: 34033,\n  },\n  {\n    date: 1461596880000,\n    open: 51.885,\n    high: 51.885,\n    low: 51.82,\n    close: 51.82,\n    volume: 64833,\n  },\n  {\n    date: 1461596940000,\n    open: 51.82,\n    high: 51.8271,\n    low: 51.77,\n    close: 51.78,\n    volume: 169937,\n  },\n  {\n    date: 1461597000000,\n    open: 51.7799,\n    high: 51.81,\n    low: 51.74,\n    close: 51.75,\n    volume: 144209,\n  },\n  {\n    date: 1461597060000,\n    open: 51.74,\n    high: 51.75,\n    low: 51.7,\n    close: 51.745,\n    volume: 138045,\n  },\n  {\n    date: 1461597120000,\n    open: 51.74,\n    high: 51.83,\n    low: 51.74,\n    close: 51.83,\n    volume: 137588,\n  },\n  {\n    date: 1461597180000,\n    open: 51.83,\n    high: 51.845,\n    low: 51.82,\n    close: 51.8369,\n    volume: 35000,\n  },\n  {\n    date: 1461597240000,\n    open: 51.83,\n    high: 51.8765,\n    low: 51.83,\n    close: 51.86,\n    volume: 84606,\n  },\n  {\n    date: 1461597300000,\n    open: 51.87,\n    high: 51.88,\n    low: 51.85,\n    close: 51.875,\n    volume: 72782,\n  },\n  {\n    date: 1461597360000,\n    open: 51.87,\n    high: 51.9,\n    low: 51.8601,\n    close: 51.9,\n    volume: 41478,\n  },\n  {\n    date: 1461597420000,\n    open: 51.9,\n    high: 51.91,\n    low: 51.86,\n    close: 51.865,\n    volume: 65696,\n  },\n  {\n    date: 1461597480000,\n    open: 51.865,\n    high: 51.875,\n    low: 51.84,\n    close: 51.86,\n    volume: 54606,\n  },\n  {\n    date: 1461597540000,\n    open: 51.8663,\n    high: 51.93,\n    low: 51.86,\n    close: 51.9,\n    volume: 90485,\n  },\n  {\n    date: 1461597600000,\n    open: 51.9,\n    high: 51.905,\n    low: 51.85,\n    close: 51.86,\n    volume: 67488,\n  },\n  {\n    date: 1461597660000,\n    open: 51.855,\n    high: 51.8665,\n    low: 51.835,\n    close: 51.855,\n    volume: 99995,\n  },\n  {\n    date: 1461597720000,\n    open: 51.855,\n    high: 51.91,\n    low: 51.85,\n    close: 51.885,\n    volume: 45698,\n  },\n  {\n    date: 1461597780000,\n    open: 51.8801,\n    high: 51.91,\n    low: 51.87,\n    close: 51.9045,\n    volume: 53207,\n  },\n  {\n    date: 1461597840000,\n    open: 51.9,\n    high: 51.91,\n    low: 51.88,\n    close: 51.91,\n    volume: 29845,\n  },\n  {\n    date: 1461597900000,\n    open: 51.91,\n    high: 51.91,\n    low: 51.875,\n    close: 51.8766,\n    volume: 48574,\n  },\n  {\n    date: 1461597960000,\n    open: 51.87,\n    high: 51.9,\n    low: 51.87,\n    close: 51.885,\n    volume: 60468,\n  },\n  {\n    date: 1461598020000,\n    open: 51.885,\n    high: 51.93,\n    low: 51.88,\n    close: 51.91,\n    volume: 49900,\n  },\n  {\n    date: 1461598080000,\n    open: 51.915,\n    high: 51.94,\n    low: 51.91,\n    close: 51.93,\n    volume: 62538,\n  },\n  {\n    date: 1461598140000,\n    open: 51.93,\n    high: 51.94,\n    low: 51.9101,\n    close: 51.93,\n    volume: 32941,\n  },\n  {\n    date: 1461598200000,\n    open: 51.93,\n    high: 51.965,\n    low: 51.9244,\n    close: 51.96,\n    volume: 80266,\n  },\n  {\n    date: 1461598260000,\n    open: 51.965,\n    high: 51.97,\n    low: 51.94,\n    close: 51.94,\n    volume: 62038,\n  },\n  {\n    date: 1461598320000,\n    open: 51.94,\n    high: 51.945,\n    low: 51.91,\n    close: 51.915,\n    volume: 37106,\n  },\n  {\n    date: 1461598380000,\n    open: 51.915,\n    high: 51.94,\n    low: 51.91,\n    close: 51.9301,\n    volume: 35830,\n  },\n  {\n    date: 1461598440000,\n    open: 51.93,\n    high: 51.94,\n    low: 51.91,\n    close: 51.91,\n    volume: 26277,\n  },\n  {\n    date: 1461598500000,\n    open: 51.9137,\n    high: 51.9255,\n    low: 51.91,\n    close: 51.915,\n    volume: 31793,\n  },\n  {\n    date: 1461598560000,\n    open: 51.91,\n    high: 51.915,\n    low: 51.9,\n    close: 51.9,\n    volume: 29035,\n  },\n  {\n    date: 1461598620000,\n    open: 51.9065,\n    high: 51.92,\n    low: 51.86,\n    close: 51.865,\n    volume: 114281,\n  },\n  {\n    date: 1461598680000,\n    open: 51.87,\n    high: 51.87,\n    low: 51.84,\n    close: 51.84,\n    volume: 35480,\n  },\n  {\n    date: 1461598740000,\n    open: 51.84,\n    high: 51.86,\n    low: 51.83,\n    close: 51.845,\n    volume: 70153,\n  },\n  {\n    date: 1461598800000,\n    open: 51.845,\n    high: 51.86,\n    low: 51.84,\n    close: 51.85,\n    volume: 18227,\n  },\n  {\n    date: 1461598860000,\n    open: 51.855,\n    high: 51.9,\n    low: 51.8546,\n    close: 51.9,\n    volume: 56411,\n  },\n  {\n    date: 1461598920000,\n    open: 51.9,\n    high: 51.9,\n    low: 51.86,\n    close: 51.8662,\n    volume: 53162,\n  },\n  {\n    date: 1461598980000,\n    open: 51.8638,\n    high: 51.9,\n    low: 51.8638,\n    close: 51.8964,\n    volume: 35289,\n  },\n  {\n    date: 1461599040000,\n    open: 51.895,\n    high: 51.905,\n    low: 51.8701,\n    close: 51.9,\n    volume: 82923,\n  },\n  {\n    date: 1461599100000,\n    open: 51.9,\n    high: 51.9,\n    low: 51.83,\n    close: 51.8399,\n    volume: 120728,\n  },\n  {\n    date: 1461599160000,\n    open: 51.84,\n    high: 51.85,\n    low: 51.83,\n    close: 51.84,\n    volume: 69673,\n  },\n  {\n    date: 1461599220000,\n    open: 51.84,\n    high: 51.87,\n    low: 51.835,\n    close: 51.86,\n    volume: 45558,\n  },\n  {\n    date: 1461599280000,\n    open: 51.8564,\n    high: 51.89,\n    low: 51.85,\n    close: 51.875,\n    volume: 86329,\n  },\n  {\n    date: 1461599340000,\n    open: 51.875,\n    high: 51.88,\n    low: 51.8501,\n    close: 51.86,\n    volume: 36846,\n  },\n  {\n    date: 1461599400000,\n    open: 51.86,\n    high: 51.86,\n    low: 51.81,\n    close: 51.83,\n    volume: 77893,\n  },\n  {\n    date: 1461599460000,\n    open: 51.83,\n    high: 51.84,\n    low: 51.82,\n    close: 51.84,\n    volume: 55625,\n  },\n  {\n    date: 1461599520000,\n    open: 51.84,\n    high: 51.86,\n    low: 51.84,\n    close: 51.85,\n    volume: 18939,\n  },\n  {\n    date: 1461599580000,\n    open: 51.8558,\n    high: 51.87,\n    low: 51.84,\n    close: 51.865,\n    volume: 96700,\n  },\n  {\n    date: 1461599640000,\n    open: 51.865,\n    high: 51.885,\n    low: 51.855,\n    close: 51.8599,\n    volume: 50090,\n  },\n  {\n    date: 1461599700000,\n    open: 51.86,\n    high: 51.86,\n    low: 51.835,\n    close: 51.845,\n    volume: 41664,\n  },\n  {\n    date: 1461599760000,\n    open: 51.84,\n    high: 51.86,\n    low: 51.835,\n    close: 51.86,\n    volume: 60130,\n  },\n  {\n    date: 1461599820000,\n    open: 51.86,\n    high: 51.88,\n    low: 51.85,\n    close: 51.85,\n    volume: 41365,\n  },\n  {\n    date: 1461599880000,\n    open: 51.855,\n    high: 51.87,\n    low: 51.845,\n    close: 51.8665,\n    volume: 36150,\n  },\n  {\n    date: 1461599940000,\n    open: 51.87,\n    high: 51.885,\n    low: 51.855,\n    close: 51.855,\n    volume: 21056,\n  },\n  {\n    date: 1461600000000,\n    open: 51.85,\n    high: 51.86,\n    low: 51.84,\n    close: 51.841,\n    volume: 60663,\n  },\n  {\n    date: 1461600060000,\n    open: 51.8465,\n    high: 51.87,\n    low: 51.84,\n    close: 51.85,\n    volume: 54523,\n  },\n  {\n    date: 1461600120000,\n    open: 51.855,\n    high: 51.86,\n    low: 51.845,\n    close: 51.8599,\n    volume: 24644,\n  },\n  {\n    date: 1461600180000,\n    open: 51.85,\n    high: 51.87,\n    low: 51.85,\n    close: 51.86,\n    volume: 28913,\n  },\n  {\n    date: 1461600240000,\n    open: 51.86,\n    high: 51.87,\n    low: 51.845,\n    close: 51.8501,\n    volume: 53611,\n  },\n  {\n    date: 1461600300000,\n    open: 51.86,\n    high: 51.87,\n    low: 51.85,\n    close: 51.855,\n    volume: 29360,\n  },\n  {\n    date: 1461600360000,\n    open: 51.8501,\n    high: 51.86,\n    low: 51.845,\n    close: 51.85,\n    volume: 37580,\n  },\n  {\n    date: 1461600420000,\n    open: 51.86,\n    high: 51.87,\n    low: 51.845,\n    close: 51.86,\n    volume: 126334,\n  },\n  {\n    date: 1461600480000,\n    open: 51.86,\n    high: 51.88,\n    low: 51.86,\n    close: 51.865,\n    volume: 38440,\n  },\n  {\n    date: 1461600540000,\n    open: 51.867,\n    high: 51.87,\n    low: 51.855,\n    close: 51.865,\n    volume: 44223,\n  },\n  {\n    date: 1461600600000,\n    open: 51.8601,\n    high: 51.87,\n    low: 51.86,\n    close: 51.87,\n    volume: 10877,\n  },\n  {\n    date: 1461600660000,\n    open: 51.87,\n    high: 51.87,\n    low: 51.85,\n    close: 51.855,\n    volume: 21681,\n  },\n  {\n    date: 1461600720000,\n    open: 51.855,\n    high: 51.86,\n    low: 51.825,\n    close: 51.84,\n    volume: 57843,\n  },\n  {\n    date: 1461600780000,\n    open: 51.8335,\n    high: 51.85,\n    low: 51.83,\n    close: 51.8364,\n    volume: 43688,\n  },\n  {\n    date: 1461600840000,\n    open: 51.84,\n    high: 51.85,\n    low: 51.83,\n    close: 51.84,\n    volume: 49728,\n  },\n  {\n    date: 1461600900000,\n    open: 51.847,\n    high: 51.85,\n    low: 51.83,\n    close: 51.85,\n    volume: 38291,\n  },\n  {\n    date: 1461600960000,\n    open: 51.85,\n    high: 51.86,\n    low: 51.84,\n    close: 51.8599,\n    volume: 48331,\n  },\n  {\n    date: 1461601020000,\n    open: 51.855,\n    high: 51.86,\n    low: 51.84,\n    close: 51.85,\n    volume: 30618,\n  },\n  {\n    date: 1461601080000,\n    open: 51.855,\n    high: 51.86,\n    low: 51.84,\n    close: 51.8485,\n    volume: 14961,\n  },\n  {\n    date: 1461601140000,\n    open: 51.846,\n    high: 51.85,\n    low: 51.83,\n    close: 51.83,\n    volume: 23982,\n  },\n  {\n    date: 1461601200000,\n    open: 51.83,\n    high: 51.86,\n    low: 51.83,\n    close: 51.835,\n    volume: 58489,\n  },\n  {\n    date: 1461601260000,\n    open: 51.84,\n    high: 51.85,\n    low: 51.83,\n    close: 51.8499,\n    volume: 23762,\n  },\n  {\n    date: 1461601320000,\n    open: 51.84,\n    high: 51.86,\n    low: 51.83,\n    close: 51.85,\n    volume: 66504,\n  },\n  {\n    date: 1461601380000,\n    open: 51.855,\n    high: 51.86,\n    low: 51.83,\n    close: 51.8336,\n    volume: 51170,\n  },\n  {\n    date: 1461601440000,\n    open: 51.83,\n    high: 51.83,\n    low: 51.78,\n    close: 51.8064,\n    volume: 138471,\n  },\n  {\n    date: 1461601500000,\n    open: 51.802,\n    high: 51.81,\n    low: 51.795,\n    close: 51.8,\n    volume: 44940,\n  },\n  {\n    date: 1461601560000,\n    open: 51.8099,\n    high: 51.81,\n    low: 51.79,\n    close: 51.79,\n    volume: 31029,\n  },\n  {\n    date: 1461601620000,\n    open: 51.7999,\n    high: 51.8,\n    low: 51.78,\n    close: 51.795,\n    volume: 37291,\n  },\n  {\n    date: 1461601680000,\n    open: 51.7999,\n    high: 51.8,\n    low: 51.79,\n    close: 51.7991,\n    volume: 13993,\n  },\n  {\n    date: 1461601740000,\n    open: 51.795,\n    high: 51.81,\n    low: 51.79,\n    close: 51.8064,\n    volume: 34046,\n  },\n  {\n    date: 1461601800000,\n    open: 51.8,\n    high: 51.81,\n    low: 51.79,\n    close: 51.8062,\n    volume: 37496,\n  },\n  {\n    date: 1461601860000,\n    open: 51.8089,\n    high: 51.845,\n    low: 51.795,\n    close: 51.83,\n    volume: 59988,\n  },\n  {\n    date: 1461601920000,\n    open: 51.825,\n    high: 51.83,\n    low: 51.8201,\n    close: 51.8299,\n    volume: 12796,\n  },\n  {\n    date: 1461601980000,\n    open: 51.83,\n    high: 51.83,\n    low: 51.82,\n    close: 51.8264,\n    volume: 19402,\n  },\n  {\n    date: 1461602040000,\n    open: 51.825,\n    high: 51.84,\n    low: 51.82,\n    close: 51.82,\n    volume: 59170,\n  },\n  {\n    date: 1461602100000,\n    open: 51.8299,\n    high: 51.8565,\n    low: 51.82,\n    close: 51.85,\n    volume: 132005,\n  },\n  {\n    date: 1461602160000,\n    open: 51.85,\n    high: 51.85,\n    low: 51.831,\n    close: 51.84,\n    volume: 40366,\n  },\n  {\n    date: 1461602220000,\n    open: 51.845,\n    high: 51.85,\n    low: 51.835,\n    close: 51.85,\n    volume: 31938,\n  },\n  {\n    date: 1461602280000,\n    open: 51.84,\n    high: 51.85,\n    low: 51.83,\n    close: 51.8399,\n    volume: 25190,\n  },\n  {\n    date: 1461602340000,\n    open: 51.83,\n    high: 51.8338,\n    low: 51.8,\n    close: 51.8068,\n    volume: 60873,\n  },\n  {\n    date: 1461602400000,\n    open: 51.805,\n    high: 51.82,\n    low: 51.8,\n    close: 51.805,\n    volume: 26238,\n  },\n  {\n    date: 1461602460000,\n    open: 51.809,\n    high: 51.82,\n    low: 51.8,\n    close: 51.8162,\n    volume: 13625,\n  },\n  {\n    date: 1461602520000,\n    open: 51.82,\n    high: 51.82,\n    low: 51.81,\n    close: 51.815,\n    volume: 13126,\n  },\n  {\n    date: 1461602580000,\n    open: 51.815,\n    high: 51.82,\n    low: 51.81,\n    close: 51.81,\n    volume: 19232,\n  },\n  {\n    date: 1461602640000,\n    open: 51.815,\n    high: 51.82,\n    low: 51.8,\n    close: 51.8,\n    volume: 73933,\n  },\n  {\n    date: 1461602700000,\n    open: 51.8064,\n    high: 51.83,\n    low: 51.8,\n    close: 51.83,\n    volume: 61768,\n  },\n  {\n    date: 1461602760000,\n    open: 51.825,\n    high: 51.83,\n    low: 51.815,\n    close: 51.83,\n    volume: 15899,\n  },\n  {\n    date: 1461602820000,\n    open: 51.83,\n    high: 51.835,\n    low: 51.82,\n    close: 51.822,\n    volume: 25708,\n  },\n  {\n    date: 1461602880000,\n    open: 51.8298,\n    high: 51.84,\n    low: 51.8298,\n    close: 51.835,\n    volume: 13337,\n  },\n  {\n    date: 1461602940000,\n    open: 51.835,\n    high: 51.85,\n    low: 51.835,\n    close: 51.84,\n    volume: 24676,\n  },\n  {\n    date: 1461603000000,\n    open: 51.84,\n    high: 51.86,\n    low: 51.83,\n    close: 51.841,\n    volume: 84935,\n  },\n  {\n    date: 1461603060000,\n    open: 51.85,\n    high: 51.86,\n    low: 51.84,\n    close: 51.8587,\n    volume: 34104,\n  },\n  {\n    date: 1461603120000,\n    open: 51.85,\n    high: 51.905,\n    low: 51.85,\n    close: 51.89,\n    volume: 86207,\n  },\n  {\n    date: 1461603180000,\n    open: 51.895,\n    high: 51.94,\n    low: 51.895,\n    close: 51.935,\n    volume: 45274,\n  },\n  {\n    date: 1461603240000,\n    open: 51.935,\n    high: 52.01,\n    low: 51.935,\n    close: 51.965,\n    volume: 159621,\n  },\n  {\n    date: 1461603300000,\n    open: 51.97,\n    high: 51.97,\n    low: 51.945,\n    close: 51.955,\n    volume: 89000,\n  },\n  {\n    date: 1461603360000,\n    open: 51.9559,\n    high: 51.96,\n    low: 51.94,\n    close: 51.9572,\n    volume: 46596,\n  },\n  {\n    date: 1461603420000,\n    open: 51.9533,\n    high: 52.015,\n    low: 51.94,\n    close: 51.95,\n    volume: 183157,\n  },\n  {\n    date: 1461603480000,\n    open: 51.95,\n    high: 51.95,\n    low: 51.93,\n    close: 51.94,\n    volume: 52026,\n  },\n  {\n    date: 1461603540000,\n    open: 51.94,\n    high: 51.9436,\n    low: 51.93,\n    close: 51.935,\n    volume: 21253,\n  },\n  {\n    date: 1461603600000,\n    open: 51.94,\n    high: 51.96,\n    low: 51.94,\n    close: 51.95,\n    volume: 32147,\n  },\n  {\n    date: 1461603660000,\n    open: 51.9499,\n    high: 51.95,\n    low: 51.94,\n    close: 51.94,\n    volume: 28809,\n  },\n  {\n    date: 1461603720000,\n    open: 51.94,\n    high: 51.95,\n    low: 51.935,\n    close: 51.946,\n    volume: 36368,\n  },\n  {\n    date: 1461603780000,\n    open: 51.95,\n    high: 51.955,\n    low: 51.94,\n    close: 51.95,\n    volume: 33375,\n  },\n  {\n    date: 1461603840000,\n    open: 51.95,\n    high: 51.96,\n    low: 51.94,\n    close: 51.95,\n    volume: 82868,\n  },\n  {\n    date: 1461603900000,\n    open: 51.945,\n    high: 51.95,\n    low: 51.9268,\n    close: 51.9268,\n    volume: 33896,\n  },\n  {\n    date: 1461603960000,\n    open: 51.92,\n    high: 51.9201,\n    low: 51.91,\n    close: 51.91,\n    volume: 26951,\n  },\n  {\n    date: 1461604020000,\n    open: 51.91,\n    high: 51.92,\n    low: 51.9,\n    close: 51.9099,\n    volume: 20472,\n  },\n  {\n    date: 1461604080000,\n    open: 51.91,\n    high: 51.92,\n    low: 51.9,\n    close: 51.915,\n    volume: 30094,\n  },\n  {\n    date: 1461604140000,\n    open: 51.91,\n    high: 51.93,\n    low: 51.9062,\n    close: 51.9201,\n    volume: 34102,\n  },\n  {\n    date: 1461604200000,\n    open: 51.93,\n    high: 51.9399,\n    low: 51.905,\n    close: 51.905,\n    volume: 26875,\n  },\n  {\n    date: 1461604260000,\n    open: 51.909,\n    high: 51.91,\n    low: 51.86,\n    close: 51.87,\n    volume: 80791,\n  },\n  {\n    date: 1461604320000,\n    open: 51.875,\n    high: 51.9,\n    low: 51.87,\n    close: 51.8858,\n    volume: 72816,\n  },\n  {\n    date: 1461604380000,\n    open: 51.885,\n    high: 51.885,\n    low: 51.87,\n    close: 51.8762,\n    volume: 20519,\n  },\n  {\n    date: 1461604440000,\n    open: 51.88,\n    high: 51.89,\n    low: 51.87,\n    close: 51.8861,\n    volume: 44907,\n  },\n  {\n    date: 1461604500000,\n    open: 51.89,\n    high: 51.91,\n    low: 51.88,\n    close: 51.8999,\n    volume: 54950,\n  },\n  {\n    date: 1461604560000,\n    open: 51.89,\n    high: 51.91,\n    low: 51.89,\n    close: 51.9,\n    volume: 15987,\n  },\n  {\n    date: 1461604620000,\n    open: 51.9,\n    high: 51.9075,\n    low: 51.86,\n    close: 51.86,\n    volume: 27110,\n  },\n  {\n    date: 1461604680000,\n    open: 51.864,\n    high: 51.87,\n    low: 51.85,\n    close: 51.85,\n    volume: 28106,\n  },\n  {\n    date: 1461604740000,\n    open: 51.85,\n    high: 51.86,\n    low: 51.84,\n    close: 51.84,\n    volume: 56947,\n  },\n  {\n    date: 1461604800000,\n    open: 51.84,\n    high: 51.8575,\n    low: 51.84,\n    close: 51.8568,\n    volume: 47085,\n  },\n  {\n    date: 1461604860000,\n    open: 51.86,\n    high: 51.87,\n    low: 51.85,\n    close: 51.865,\n    volume: 47146,\n  },\n  {\n    date: 1461604920000,\n    open: 51.863,\n    high: 51.87,\n    low: 51.86,\n    close: 51.87,\n    volume: 12992,\n  },\n  {\n    date: 1461604980000,\n    open: 51.86,\n    high: 51.87,\n    low: 51.86,\n    close: 51.86,\n    volume: 11299,\n  },\n  {\n    date: 1461605040000,\n    open: 51.86,\n    high: 51.869,\n    low: 51.85,\n    close: 51.85,\n    volume: 32693,\n  },\n  {\n    date: 1461605100000,\n    open: 51.855,\n    high: 51.87,\n    low: 51.84,\n    close: 51.86,\n    volume: 159681,\n  },\n  {\n    date: 1461605160000,\n    open: 51.86,\n    high: 51.93,\n    low: 51.86,\n    close: 51.93,\n    volume: 64783,\n  },\n  {\n    date: 1461605220000,\n    open: 51.93,\n    high: 51.95,\n    low: 51.915,\n    close: 51.93,\n    volume: 34476,\n  },\n  {\n    date: 1461605280000,\n    open: 51.925,\n    high: 51.93,\n    low: 51.87,\n    close: 51.8705,\n    volume: 54068,\n  },\n  {\n    date: 1461605340000,\n    open: 51.8741,\n    high: 51.91,\n    low: 51.87,\n    close: 51.9099,\n    volume: 30025,\n  },\n  {\n    date: 1461605400000,\n    open: 51.9,\n    high: 51.91,\n    low: 51.895,\n    close: 51.91,\n    volume: 35890,\n  },\n  {\n    date: 1461605460000,\n    open: 51.904,\n    high: 51.91,\n    low: 51.9,\n    close: 51.9,\n    volume: 9840,\n  },\n  {\n    date: 1461605520000,\n    open: 51.91,\n    high: 51.91,\n    low: 51.89,\n    close: 51.9,\n    volume: 36720,\n  },\n  {\n    date: 1461605580000,\n    open: 51.9,\n    high: 51.9025,\n    low: 51.87,\n    close: 51.875,\n    volume: 60551,\n  },\n  {\n    date: 1461605640000,\n    open: 51.875,\n    high: 51.88,\n    low: 51.87,\n    close: 51.875,\n    volume: 10501,\n  },\n  {\n    date: 1461605700000,\n    open: 51.88,\n    high: 51.89,\n    low: 51.86,\n    close: 51.885,\n    volume: 37997,\n  },\n  {\n    date: 1461605760000,\n    open: 51.89,\n    high: 51.89,\n    low: 51.87,\n    close: 51.875,\n    volume: 64496,\n  },\n  {\n    date: 1461605820000,\n    open: 51.875,\n    high: 51.8799,\n    low: 51.86,\n    close: 51.865,\n    volume: 15190,\n  },\n  {\n    date: 1461605880000,\n    open: 51.865,\n    high: 51.865,\n    low: 51.84,\n    close: 51.85,\n    volume: 72900,\n  },\n  {\n    date: 1461605940000,\n    open: 51.8565,\n    high: 51.86,\n    low: 51.85,\n    close: 51.855,\n    volume: 95304,\n  },\n  {\n    date: 1461606000000,\n    open: 51.8555,\n    high: 51.88,\n    low: 51.85,\n    close: 51.87,\n    volume: 23175,\n  },\n  {\n    date: 1461606060000,\n    open: 51.87,\n    high: 51.9,\n    low: 51.87,\n    close: 51.89,\n    volume: 44359,\n  },\n  {\n    date: 1461606120000,\n    open: 51.89,\n    high: 51.89,\n    low: 51.88,\n    close: 51.89,\n    volume: 12124,\n  },\n  {\n    date: 1461606180000,\n    open: 51.886,\n    high: 51.89,\n    low: 51.88,\n    close: 51.88,\n    volume: 14525,\n  },\n  {\n    date: 1461606240000,\n    open: 51.875,\n    high: 51.875,\n    low: 51.85,\n    close: 51.85,\n    volume: 17050,\n  },\n  {\n    date: 1461606300000,\n    open: 51.855,\n    high: 51.86,\n    low: 51.845,\n    close: 51.85,\n    volume: 48772,\n  },\n  {\n    date: 1461606360000,\n    open: 51.855,\n    high: 51.86,\n    low: 51.85,\n    close: 51.85,\n    volume: 14894,\n  },\n  {\n    date: 1461606420000,\n    open: 51.855,\n    high: 51.86,\n    low: 51.85,\n    close: 51.855,\n    volume: 13428,\n  },\n  {\n    date: 1461606480000,\n    open: 51.85,\n    high: 51.86,\n    low: 51.84,\n    close: 51.8585,\n    volume: 36574,\n  },\n  {\n    date: 1461606540000,\n    open: 51.86,\n    high: 51.885,\n    low: 51.855,\n    close: 51.87,\n    volume: 48116,\n  },\n  {\n    date: 1461606600000,\n    open: 51.8799,\n    high: 51.88,\n    low: 51.865,\n    close: 51.879,\n    volume: 38682,\n  },\n  {\n    date: 1461606660000,\n    open: 51.8701,\n    high: 51.88,\n    low: 51.87,\n    close: 51.875,\n    volume: 13408,\n  },\n  {\n    date: 1461606720000,\n    open: 51.875,\n    high: 51.9099,\n    low: 51.875,\n    close: 51.895,\n    volume: 60754,\n  },\n  {\n    date: 1461606780000,\n    open: 51.8968,\n    high: 51.9,\n    low: 51.88,\n    close: 51.8801,\n    volume: 32509,\n  },\n  {\n    date: 1461606840000,\n    open: 51.88,\n    high: 51.9,\n    low: 51.8705,\n    close: 51.9,\n    volume: 42643,\n  },\n  {\n    date: 1461606900000,\n    open: 51.9,\n    high: 51.91,\n    low: 51.9,\n    close: 51.905,\n    volume: 38389,\n  },\n  {\n    date: 1461606960000,\n    open: 51.905,\n    high: 51.91,\n    low: 51.9,\n    close: 51.905,\n    volume: 80748,\n  },\n  {\n    date: 1461607020000,\n    open: 51.91,\n    high: 51.91,\n    low: 51.89,\n    close: 51.906,\n    volume: 56688,\n  },\n  {\n    date: 1461607080000,\n    open: 51.9001,\n    high: 51.91,\n    low: 51.88,\n    close: 51.885,\n    volume: 31568,\n  },\n  {\n    date: 1461607140000,\n    open: 51.885,\n    high: 51.9,\n    low: 51.88,\n    close: 51.895,\n    volume: 23395,\n  },\n  {\n    date: 1461607200000,\n    open: 51.895,\n    high: 51.9,\n    low: 51.88,\n    close: 51.88,\n    volume: 26251,\n  },\n  {\n    date: 1461607260000,\n    open: 51.89,\n    high: 51.91,\n    low: 51.8833,\n    close: 51.91,\n    volume: 40370,\n  },\n  {\n    date: 1461607320000,\n    open: 51.9099,\n    high: 51.93,\n    low: 51.9,\n    close: 51.92,\n    volume: 123270,\n  },\n  {\n    date: 1461607380000,\n    open: 51.9165,\n    high: 51.93,\n    low: 51.91,\n    close: 51.925,\n    volume: 22757,\n  },\n  {\n    date: 1461607440000,\n    open: 51.925,\n    high: 51.95,\n    low: 51.925,\n    close: 51.949,\n    volume: 89793,\n  },\n  {\n    date: 1461607500000,\n    open: 51.95,\n    high: 51.95,\n    low: 51.92,\n    close: 51.925,\n    volume: 20100,\n  },\n  {\n    date: 1461607560000,\n    open: 51.925,\n    high: 51.925,\n    low: 51.86,\n    close: 51.86,\n    volume: 87470,\n  },\n  {\n    date: 1461607620000,\n    open: 51.865,\n    high: 51.88,\n    low: 51.85,\n    close: 51.85,\n    volume: 60588,\n  },\n  {\n    date: 1461607680000,\n    open: 51.85,\n    high: 51.88,\n    low: 51.85,\n    close: 51.87,\n    volume: 70267,\n  },\n  {\n    date: 1461607740000,\n    open: 51.875,\n    high: 51.89,\n    low: 51.87,\n    close: 51.875,\n    volume: 42345,\n  },\n  {\n    date: 1461607800000,\n    open: 51.875,\n    high: 51.88,\n    low: 51.87,\n    close: 51.87,\n    volume: 27357,\n  },\n  {\n    date: 1461607860000,\n    open: 51.88,\n    high: 51.88,\n    low: 51.84,\n    close: 51.85,\n    volume: 108797,\n  },\n  {\n    date: 1461607920000,\n    open: 51.85,\n    high: 51.86,\n    low: 51.85,\n    close: 51.86,\n    volume: 21878,\n  },\n  {\n    date: 1461607980000,\n    open: 51.85,\n    high: 51.86,\n    low: 51.8,\n    close: 51.819,\n    volume: 102452,\n  },\n  {\n    date: 1461608040000,\n    open: 51.81,\n    high: 51.83,\n    low: 51.81,\n    close: 51.825,\n    volume: 55523,\n  },\n  {\n    date: 1461608100000,\n    open: 51.826,\n    high: 51.85,\n    low: 51.82,\n    close: 51.85,\n    volume: 61836,\n  },\n  {\n    date: 1461608160000,\n    open: 51.85,\n    high: 51.86,\n    low: 51.84,\n    close: 51.845,\n    volume: 32594,\n  },\n  {\n    date: 1461608220000,\n    open: 51.85,\n    high: 51.8575,\n    low: 51.84,\n    close: 51.845,\n    volume: 29647,\n  },\n  {\n    date: 1461608280000,\n    open: 51.8499,\n    high: 51.85,\n    low: 51.84,\n    close: 51.84,\n    volume: 25657,\n  },\n  {\n    date: 1461608340000,\n    open: 51.84,\n    high: 51.855,\n    low: 51.84,\n    close: 51.855,\n    volume: 47548,\n  },\n  {\n    date: 1461608400000,\n    open: 51.85,\n    high: 51.8599,\n    low: 51.84,\n    close: 51.845,\n    volume: 64259,\n  },\n  {\n    date: 1461608460000,\n    open: 51.85,\n    high: 51.86,\n    low: 51.85,\n    close: 51.85,\n    volume: 38494,\n  },\n  {\n    date: 1461608520000,\n    open: 51.85,\n    high: 51.85,\n    low: 51.83,\n    close: 51.841,\n    volume: 43206,\n  },\n  {\n    date: 1461608580000,\n    open: 51.845,\n    high: 51.85,\n    low: 51.84,\n    close: 51.845,\n    volume: 14362,\n  },\n  {\n    date: 1461608640000,\n    open: 51.845,\n    high: 51.86,\n    low: 51.84,\n    close: 51.85,\n    volume: 62432,\n  },\n  {\n    date: 1461608700000,\n    open: 51.85,\n    high: 51.89,\n    low: 51.845,\n    close: 51.88,\n    volume: 52188,\n  },\n  {\n    date: 1461608760000,\n    open: 51.89,\n    high: 51.915,\n    low: 51.87,\n    close: 51.91,\n    volume: 59112,\n  },\n  {\n    date: 1461608820000,\n    open: 51.9,\n    high: 51.92,\n    low: 51.88,\n    close: 51.915,\n    volume: 34941,\n  },\n  {\n    date: 1461608880000,\n    open: 51.915,\n    high: 51.915,\n    low: 51.89,\n    close: 51.9,\n    volume: 36768,\n  },\n  {\n    date: 1461608940000,\n    open: 51.9044,\n    high: 51.92,\n    low: 51.9,\n    close: 51.915,\n    volume: 66967,\n  },\n  {\n    date: 1461609000000,\n    open: 51.915,\n    high: 51.94,\n    low: 51.91,\n    close: 51.935,\n    volume: 36072,\n  },\n  {\n    date: 1461609060000,\n    open: 51.94,\n    high: 51.94,\n    low: 51.92,\n    close: 51.935,\n    volume: 40957,\n  },\n  {\n    date: 1461609120000,\n    open: 51.935,\n    high: 51.94,\n    low: 51.93,\n    close: 51.93,\n    volume: 9187,\n  },\n  {\n    date: 1461609180000,\n    open: 51.93,\n    high: 51.96,\n    low: 51.92,\n    close: 51.9468,\n    volume: 122256,\n  },\n  {\n    date: 1461609240000,\n    open: 51.945,\n    high: 51.9667,\n    low: 51.935,\n    close: 51.945,\n    volume: 46496,\n  },\n  {\n    date: 1461609300000,\n    open: 51.941,\n    high: 51.95,\n    low: 51.94,\n    close: 51.95,\n    volume: 27358,\n  },\n  {\n    date: 1461609360000,\n    open: 51.95,\n    high: 51.955,\n    low: 51.94,\n    close: 51.95,\n    volume: 78516,\n  },\n  {\n    date: 1461609420000,\n    open: 51.96,\n    high: 51.97,\n    low: 51.95,\n    close: 51.9571,\n    volume: 36045,\n  },\n  {\n    date: 1461609480000,\n    open: 51.955,\n    high: 51.97,\n    low: 51.941,\n    close: 51.96,\n    volume: 51523,\n  },\n  {\n    date: 1461609540000,\n    open: 51.96,\n    high: 52,\n    low: 51.96,\n    close: 52,\n    volume: 128743,\n  },\n  {\n    date: 1461609600000,\n    open: 51.9901,\n    high: 52,\n    low: 51.97,\n    close: 51.98,\n    volume: 72969,\n  },\n  {\n    date: 1461609660000,\n    open: 51.98,\n    high: 51.99,\n    low: 51.98,\n    close: 51.985,\n    volume: 14844,\n  },\n  {\n    date: 1461609720000,\n    open: 51.9899,\n    high: 51.99,\n    low: 51.98,\n    close: 51.99,\n    volume: 29410,\n  },\n  {\n    date: 1461609780000,\n    open: 51.9899,\n    high: 51.99,\n    low: 51.955,\n    close: 51.96,\n    volume: 95416,\n  },\n  {\n    date: 1461609840000,\n    open: 51.965,\n    high: 52,\n    low: 51.96,\n    close: 51.9902,\n    volume: 57364,\n  },\n  {\n    date: 1461609900000,\n    open: 51.999,\n    high: 52.01,\n    low: 51.99,\n    close: 51.99,\n    volume: 110265,\n  },\n  {\n    date: 1461609960000,\n    open: 51.995,\n    high: 52,\n    low: 51.99,\n    close: 52,\n    volume: 20683,\n  },\n  {\n    date: 1461610020000,\n    open: 52,\n    high: 52,\n    low: 51.99,\n    close: 52,\n    volume: 41021,\n  },\n  {\n    date: 1461610080000,\n    open: 51.995,\n    high: 52,\n    low: 51.99,\n    close: 51.99,\n    volume: 30276,\n  },\n  {\n    date: 1461610140000,\n    open: 52,\n    high: 52,\n    low: 51.99,\n    close: 52,\n    volume: 22421,\n  },\n  {\n    date: 1461610200000,\n    open: 52,\n    high: 52,\n    low: 51.95,\n    close: 51.96,\n    volume: 90663,\n  },\n  {\n    date: 1461610260000,\n    open: 51.955,\n    high: 51.96,\n    low: 51.94,\n    close: 51.945,\n    volume: 30190,\n  },\n  {\n    date: 1461610320000,\n    open: 51.945,\n    high: 51.95,\n    low: 51.94,\n    close: 51.9475,\n    volume: 23475,\n  },\n  {\n    date: 1461610380000,\n    open: 51.95,\n    high: 51.95,\n    low: 51.93,\n    close: 51.9365,\n    volume: 36480,\n  },\n  {\n    date: 1461610440000,\n    open: 51.94,\n    high: 51.95,\n    low: 51.935,\n    close: 51.95,\n    volume: 39243,\n  },\n  {\n    date: 1461610500000,\n    open: 51.95,\n    high: 51.98,\n    low: 51.93,\n    close: 51.975,\n    volume: 98290,\n  },\n  {\n    date: 1461610560000,\n    open: 51.98,\n    high: 51.98,\n    low: 51.95,\n    close: 51.975,\n    volume: 32713,\n  },\n  {\n    date: 1461610620000,\n    open: 51.98,\n    high: 52.005,\n    low: 51.9701,\n    close: 51.995,\n    volume: 65255,\n  },\n  {\n    date: 1461610680000,\n    open: 52,\n    high: 52.02,\n    low: 51.99,\n    close: 52,\n    volume: 98182,\n  },\n  {\n    date: 1461610740000,\n    open: 52,\n    high: 52.015,\n    low: 51.99,\n    close: 51.99,\n    volume: 38008,\n  },\n  {\n    date: 1461610800000,\n    open: 51.991,\n    high: 52.005,\n    low: 51.98,\n    close: 51.9899,\n    volume: 44925,\n  },\n  {\n    date: 1461610860000,\n    open: 51.99,\n    high: 51.99,\n    low: 51.97,\n    close: 51.9867,\n    volume: 38142,\n  },\n  {\n    date: 1461610920000,\n    open: 51.99,\n    high: 51.9998,\n    low: 51.98,\n    close: 51.9899,\n    volume: 30614,\n  },\n  {\n    date: 1461610980000,\n    open: 51.99,\n    high: 51.99,\n    low: 51.95,\n    close: 51.9568,\n    volume: 36806,\n  },\n  {\n    date: 1461611040000,\n    open: 51.9599,\n    high: 51.9599,\n    low: 51.945,\n    close: 51.95,\n    volume: 46413,\n  },\n  {\n    date: 1461611100000,\n    open: 51.95,\n    high: 51.97,\n    low: 51.9341,\n    close: 51.935,\n    volume: 124097,\n  },\n  {\n    date: 1461611160000,\n    open: 51.935,\n    high: 51.95,\n    low: 51.93,\n    close: 51.9325,\n    volume: 48434,\n  },\n  {\n    date: 1461611220000,\n    open: 51.9398,\n    high: 51.95,\n    low: 51.93,\n    close: 51.9495,\n    volume: 50811,\n  },\n  {\n    date: 1461611280000,\n    open: 51.95,\n    high: 51.97,\n    low: 51.94,\n    close: 51.9499,\n    volume: 77131,\n  },\n  {\n    date: 1461611340000,\n    open: 51.94,\n    high: 51.9499,\n    low: 51.93,\n    close: 51.9376,\n    volume: 25202,\n  },\n  {\n    date: 1461611400000,\n    open: 51.93,\n    high: 51.9399,\n    low: 51.87,\n    close: 51.89,\n    volume: 133573,\n  },\n  {\n    date: 1461611460000,\n    open: 51.88,\n    high: 51.92,\n    low: 51.87,\n    close: 51.915,\n    volume: 61359,\n  },\n  {\n    date: 1461611520000,\n    open: 51.92,\n    high: 51.93,\n    low: 51.905,\n    close: 51.915,\n    volume: 50181,\n  },\n  {\n    date: 1461611580000,\n    open: 51.9201,\n    high: 51.925,\n    low: 51.89,\n    close: 51.91,\n    volume: 43905,\n  },\n  {\n    date: 1461611640000,\n    open: 51.908,\n    high: 51.93,\n    low: 51.9,\n    close: 51.93,\n    volume: 25243,\n  },\n  {\n    date: 1461611700000,\n    open: 51.925,\n    high: 51.93,\n    low: 51.9,\n    close: 51.925,\n    volume: 41217,\n  },\n  {\n    date: 1461611760000,\n    open: 51.925,\n    high: 51.93,\n    low: 51.91,\n    close: 51.92,\n    volume: 29919,\n  },\n  {\n    date: 1461611820000,\n    open: 51.92,\n    high: 51.93,\n    low: 51.91,\n    close: 51.91,\n    volume: 21313,\n  },\n  {\n    date: 1461611880000,\n    open: 51.915,\n    high: 51.92,\n    low: 51.9,\n    close: 51.905,\n    volume: 63659,\n  },\n  {\n    date: 1461611940000,\n    open: 51.905,\n    high: 51.91,\n    low: 51.87,\n    close: 51.88,\n    volume: 41530,\n  },\n  {\n    date: 1461612000000,\n    open: 51.88,\n    high: 51.92,\n    low: 51.87,\n    close: 51.92,\n    volume: 74171,\n  },\n  {\n    date: 1461612060000,\n    open: 51.915,\n    high: 51.93,\n    low: 51.891,\n    close: 51.905,\n    volume: 51902,\n  },\n  {\n    date: 1461612120000,\n    open: 51.905,\n    high: 51.93,\n    low: 51.9,\n    close: 51.93,\n    volume: 24093,\n  },\n  {\n    date: 1461612180000,\n    open: 51.92,\n    high: 51.925,\n    low: 51.91,\n    close: 51.91,\n    volume: 35625,\n  },\n  {\n    date: 1461612240000,\n    open: 51.9134,\n    high: 51.93,\n    low: 51.905,\n    close: 51.9101,\n    volume: 37307,\n  },\n  {\n    date: 1461612300000,\n    open: 51.92,\n    high: 51.95,\n    low: 51.91,\n    close: 51.945,\n    volume: 55034,\n  },\n  {\n    date: 1461612360000,\n    open: 51.95,\n    high: 51.95,\n    low: 51.89,\n    close: 51.89,\n    volume: 165949,\n  },\n  {\n    date: 1461612420000,\n    open: 51.9,\n    high: 51.9,\n    low: 51.88,\n    close: 51.8999,\n    volume: 60860,\n  },\n  {\n    date: 1461612480000,\n    open: 51.9,\n    high: 51.91,\n    low: 51.875,\n    close: 51.885,\n    volume: 87251,\n  },\n  {\n    date: 1461612540000,\n    open: 51.885,\n    high: 51.91,\n    low: 51.885,\n    close: 51.9,\n    volume: 44293,\n  },\n  {\n    date: 1461612600000,\n    open: 51.91,\n    high: 51.91,\n    low: 51.89,\n    close: 51.905,\n    volume: 40367,\n  },\n  {\n    date: 1461612660000,\n    open: 51.905,\n    high: 51.91,\n    low: 51.8801,\n    close: 51.905,\n    volume: 64493,\n  },\n  {\n    date: 1461612720000,\n    open: 51.905,\n    high: 51.93,\n    low: 51.9,\n    close: 51.9272,\n    volume: 59799,\n  },\n  {\n    date: 1461612780000,\n    open: 51.929,\n    high: 51.95,\n    low: 51.9201,\n    close: 51.945,\n    volume: 51555,\n  },\n  {\n    date: 1461612840000,\n    open: 51.9499,\n    high: 51.96,\n    low: 51.93,\n    close: 51.955,\n    volume: 94230,\n  },\n  {\n    date: 1461612900000,\n    open: 51.9585,\n    high: 51.97,\n    low: 51.94,\n    close: 51.96,\n    volume: 88037,\n  },\n  {\n    date: 1461612960000,\n    open: 51.9598,\n    high: 52.01,\n    low: 51.95,\n    close: 52,\n    volume: 241179,\n  },\n  {\n    date: 1461613020000,\n    open: 52,\n    high: 52.01,\n    low: 51.99,\n    close: 52,\n    volume: 147541,\n  },\n  {\n    date: 1461613080000,\n    open: 51.995,\n    high: 52,\n    low: 51.95,\n    close: 51.95,\n    volume: 109697,\n  },\n  {\n    date: 1461613140000,\n    open: 51.95,\n    high: 51.96,\n    low: 51.92,\n    close: 51.92,\n    volume: 53994,\n  },\n  {\n    date: 1461613200000,\n    open: 51.93,\n    high: 51.94,\n    low: 51.915,\n    close: 51.94,\n    volume: 112228,\n  },\n  {\n    date: 1461613260000,\n    open: 51.94,\n    high: 51.97,\n    low: 51.93,\n    close: 51.965,\n    volume: 121263,\n  },\n  {\n    date: 1461613320000,\n    open: 51.965,\n    high: 52,\n    low: 51.9615,\n    close: 51.98,\n    volume: 95651,\n  },\n  {\n    date: 1461613380000,\n    open: 51.98,\n    high: 52,\n    low: 51.98,\n    close: 51.995,\n    volume: 57242,\n  },\n  {\n    date: 1461613440000,\n    open: 51.9901,\n    high: 52,\n    low: 51.98,\n    close: 51.99,\n    volume: 52551,\n  },\n  {\n    date: 1461613500000,\n    open: 51.995,\n    high: 52,\n    low: 51.98,\n    close: 51.985,\n    volume: 77291,\n  },\n  {\n    date: 1461613560000,\n    open: 51.98,\n    high: 52.01,\n    low: 51.97,\n    close: 52.005,\n    volume: 127738,\n  },\n  {\n    date: 1461613620000,\n    open: 52.01,\n    high: 52.02,\n    low: 52,\n    close: 52,\n    volume: 99896,\n  },\n  {\n    date: 1461613680000,\n    open: 52,\n    high: 52.01,\n    low: 51.99,\n    close: 52.005,\n    volume: 181608,\n  },\n  {\n    date: 1461613740000,\n    open: 52.01,\n    high: 52.03,\n    low: 52.0001,\n    close: 52.015,\n    volume: 132220,\n  },\n  {\n    date: 1461613800000,\n    open: 52.01,\n    high: 52.03,\n    low: 52.01,\n    close: 52.03,\n    volume: 80022,\n  },\n  {\n    date: 1461613860000,\n    open: 52.02,\n    high: 52.04,\n    low: 52.01,\n    close: 52.01,\n    volume: 122634,\n  },\n  {\n    date: 1461613920000,\n    open: 52.01,\n    high: 52.02,\n    low: 52,\n    close: 52.01,\n    volume: 130967,\n  },\n  {\n    date: 1461613980000,\n    open: 52.01,\n    high: 52.01,\n    low: 52,\n    close: 52,\n    volume: 97397,\n  },\n  {\n    date: 1461614040000,\n    open: 52.01,\n    high: 52.01,\n    low: 51.96,\n    close: 51.97,\n    volume: 151256,\n  },\n  {\n    date: 1461614100000,\n    open: 51.97,\n    high: 52,\n    low: 51.965,\n    close: 51.99,\n    volume: 134503,\n  },\n  {\n    date: 1461614160000,\n    open: 51.99,\n    high: 52.01,\n    low: 51.98,\n    close: 52.01,\n    volume: 125610,\n  },\n  {\n    date: 1461614220000,\n    open: 52.01,\n    high: 52.03,\n    low: 52,\n    close: 52.03,\n    volume: 165358,\n  },\n  {\n    date: 1461614280000,\n    open: 52.025,\n    high: 52.05,\n    low: 52.02,\n    close: 52.05,\n    volume: 140282,\n  },\n  {\n    date: 1461614340000,\n    open: 52.04,\n    high: 52.06,\n    low: 52.02,\n    close: 52.04,\n    volume: 255190,\n  },\n  {\n    date: 1461614400000,\n    open: 52.04,\n    high: 52.13,\n    low: 52.035,\n    close: 52.11,\n    volume: 1716650,\n  },\n  {\n    date: 1461677400000,\n    open: 52.26,\n    high: 52.29,\n    low: 52.23,\n    close: 52.25,\n    volume: 341414,\n  },\n  {\n    date: 1461677460000,\n    open: 52.24,\n    high: 52.35,\n    low: 52.215,\n    close: 52.28,\n    volume: 118991,\n  },\n  {\n    date: 1461677520000,\n    open: 52.28,\n    high: 52.28,\n    low: 52.165,\n    close: 52.21,\n    volume: 68832,\n  },\n  {\n    date: 1461677580000,\n    open: 52.21,\n    high: 52.27,\n    low: 52.19,\n    close: 52.19,\n    volume: 51440,\n  },\n  {\n    date: 1461677640000,\n    open: 52.19,\n    high: 52.23,\n    low: 52.16,\n    close: 52.16,\n    volume: 55784,\n  },\n  {\n    date: 1461677700000,\n    open: 52.16,\n    high: 52.165,\n    low: 52.0899,\n    close: 52.0899,\n    volume: 85914,\n  },\n  {\n    date: 1461677760000,\n    open: 52.0801,\n    high: 52.11,\n    low: 51.97,\n    close: 51.98,\n    volume: 134229,\n  },\n  {\n    date: 1461677820000,\n    open: 51.99,\n    high: 52.06,\n    low: 51.93,\n    close: 52.06,\n    volume: 115736,\n  },\n  {\n    date: 1461677880000,\n    open: 52.07,\n    high: 52.07,\n    low: 52.02,\n    close: 52.045,\n    volume: 85184,\n  },\n  {\n    date: 1461677940000,\n    open: 52.05,\n    high: 52.05,\n    low: 51.99,\n    close: 51.995,\n    volume: 71923,\n  },\n  {\n    date: 1461678000000,\n    open: 52,\n    high: 52,\n    low: 51.95,\n    close: 51.95,\n    volume: 74423,\n  },\n  {\n    date: 1461678060000,\n    open: 51.94,\n    high: 51.96,\n    low: 51.9,\n    close: 51.94,\n    volume: 89548,\n  },\n  {\n    date: 1461678120000,\n    open: 51.945,\n    high: 51.985,\n    low: 51.94,\n    close: 51.95,\n    volume: 75591,\n  },\n  {\n    date: 1461678180000,\n    open: 51.9499,\n    high: 51.9499,\n    low: 51.8,\n    close: 51.8,\n    volume: 180273,\n  },\n  {\n    date: 1461678240000,\n    open: 51.805,\n    high: 51.87,\n    low: 51.79,\n    close: 51.86,\n    volume: 153161,\n  },\n  {\n    date: 1461678300000,\n    open: 51.86,\n    high: 51.91,\n    low: 51.82,\n    close: 51.9,\n    volume: 170911,\n  },\n  {\n    date: 1461678360000,\n    open: 51.9,\n    high: 51.98,\n    low: 51.9,\n    close: 51.96,\n    volume: 124832,\n  },\n  {\n    date: 1461678420000,\n    open: 51.96,\n    high: 51.965,\n    low: 51.9,\n    close: 51.9161,\n    volume: 97148,\n  },\n  {\n    date: 1461678480000,\n    open: 51.92,\n    high: 51.93,\n    low: 51.85,\n    close: 51.92,\n    volume: 72061,\n  },\n  {\n    date: 1461678540000,\n    open: 51.92,\n    high: 51.96,\n    low: 51.86,\n    close: 51.87,\n    volume: 88790,\n  },\n  {\n    date: 1461678600000,\n    open: 51.87,\n    high: 51.9,\n    low: 51.84,\n    close: 51.855,\n    volume: 105365,\n  },\n  {\n    date: 1461678660000,\n    open: 51.85,\n    high: 51.86,\n    low: 51.78,\n    close: 51.785,\n    volume: 127577,\n  },\n  {\n    date: 1461678720000,\n    open: 51.79,\n    high: 51.82,\n    low: 51.7899,\n    close: 51.81,\n    volume: 70054,\n  },\n  {\n    date: 1461678780000,\n    open: 51.81,\n    high: 51.85,\n    low: 51.8,\n    close: 51.845,\n    volume: 94726,\n  },\n  {\n    date: 1461678840000,\n    open: 51.85,\n    high: 51.85,\n    low: 51.8242,\n    close: 51.83,\n    volume: 107978,\n  },\n  {\n    date: 1461678900000,\n    open: 51.83,\n    high: 51.94,\n    low: 51.825,\n    close: 51.92,\n    volume: 117804,\n  },\n  {\n    date: 1461678960000,\n    open: 51.925,\n    high: 51.95,\n    low: 51.88,\n    close: 51.95,\n    volume: 102652,\n  },\n  {\n    date: 1461679020000,\n    open: 51.945,\n    high: 51.96,\n    low: 51.88,\n    close: 51.8999,\n    volume: 133381,\n  },\n  {\n    date: 1461679080000,\n    open: 51.895,\n    high: 51.895,\n    low: 51.85,\n    close: 51.86,\n    volume: 79650,\n  },\n  {\n    date: 1461679140000,\n    open: 51.855,\n    high: 51.86,\n    low: 51.82,\n    close: 51.83,\n    volume: 114242,\n  },\n  {\n    date: 1461679200000,\n    open: 51.825,\n    high: 51.835,\n    low: 51.79,\n    close: 51.82,\n    volume: 121551,\n  },\n  {\n    date: 1461679260000,\n    open: 51.815,\n    high: 51.89,\n    low: 51.81,\n    close: 51.8731,\n    volume: 61928,\n  },\n  {\n    date: 1461679320000,\n    open: 51.8763,\n    high: 51.88,\n    low: 51.85,\n    close: 51.88,\n    volume: 39590,\n  },\n  {\n    date: 1461679380000,\n    open: 51.8799,\n    high: 51.93,\n    low: 51.875,\n    close: 51.91,\n    volume: 49591,\n  },\n  {\n    date: 1461679440000,\n    open: 51.92,\n    high: 51.94,\n    low: 51.87,\n    close: 51.885,\n    volume: 58928,\n  },\n  {\n    date: 1461679500000,\n    open: 51.8869,\n    high: 51.91,\n    low: 51.86,\n    close: 51.8764,\n    volume: 44726,\n  },\n  {\n    date: 1461679560000,\n    open: 51.875,\n    high: 51.89,\n    low: 51.8699,\n    close: 51.88,\n    volume: 80941,\n  },\n  {\n    date: 1461679620000,\n    open: 51.885,\n    high: 51.885,\n    low: 51.8475,\n    close: 51.85,\n    volume: 64140,\n  },\n  {\n    date: 1461679680000,\n    open: 51.86,\n    high: 51.86,\n    low: 51.81,\n    close: 51.8199,\n    volume: 48610,\n  },\n  {\n    date: 1461679740000,\n    open: 51.815,\n    high: 51.83,\n    low: 51.8,\n    close: 51.815,\n    volume: 92663,\n  },\n  {\n    date: 1461679800000,\n    open: 51.82,\n    high: 51.83,\n    low: 51.785,\n    close: 51.785,\n    volume: 54840,\n  },\n  {\n    date: 1461679860000,\n    open: 51.79,\n    high: 51.79,\n    low: 51.77,\n    close: 51.785,\n    volume: 116842,\n  },\n  {\n    date: 1461679920000,\n    open: 51.785,\n    high: 51.8,\n    low: 51.77,\n    close: 51.799,\n    volume: 55250,\n  },\n  {\n    date: 1461679980000,\n    open: 51.795,\n    high: 51.8,\n    low: 51.76,\n    close: 51.7799,\n    volume: 59317,\n  },\n  {\n    date: 1461680040000,\n    open: 51.77,\n    high: 51.775,\n    low: 51.73,\n    close: 51.74,\n    volume: 113546,\n  },\n  {\n    date: 1461680100000,\n    open: 51.745,\n    high: 51.76,\n    low: 51.73,\n    close: 51.74,\n    volume: 66761,\n  },\n  {\n    date: 1461680160000,\n    open: 51.74,\n    high: 51.75,\n    low: 51.73,\n    close: 51.73,\n    volume: 44689,\n  },\n  {\n    date: 1461680220000,\n    open: 51.735,\n    high: 51.79,\n    low: 51.735,\n    close: 51.7875,\n    volume: 91886,\n  },\n  {\n    date: 1461680280000,\n    open: 51.785,\n    high: 51.79,\n    low: 51.73,\n    close: 51.744,\n    volume: 77044,\n  },\n  {\n    date: 1461680340000,\n    open: 51.7463,\n    high: 51.75,\n    low: 51.72,\n    close: 51.74,\n    volume: 80114,\n  },\n  {\n    date: 1461680400000,\n    open: 51.74,\n    high: 51.749,\n    low: 51.72,\n    close: 51.72,\n    volume: 26223,\n  },\n  {\n    date: 1461680460000,\n    open: 51.72,\n    high: 51.73,\n    low: 51.7,\n    close: 51.71,\n    volume: 141478,\n  },\n  {\n    date: 1461680520000,\n    open: 51.7162,\n    high: 51.73,\n    low: 51.71,\n    close: 51.719,\n    volume: 52825,\n  },\n  {\n    date: 1461680580000,\n    open: 51.711,\n    high: 51.72,\n    low: 51.63,\n    close: 51.63,\n    volume: 128384,\n  },\n  {\n    date: 1461680640000,\n    open: 51.63,\n    high: 51.6699,\n    low: 51.62,\n    close: 51.655,\n    volume: 74214,\n  },\n  {\n    date: 1461680700000,\n    open: 51.66,\n    high: 51.68,\n    low: 51.65,\n    close: 51.66,\n    volume: 58192,\n  },\n  {\n    date: 1461680760000,\n    open: 51.67,\n    high: 51.6962,\n    low: 51.66,\n    close: 51.69,\n    volume: 76746,\n  },\n  {\n    date: 1461680820000,\n    open: 51.68,\n    high: 51.68,\n    low: 51.62,\n    close: 51.65,\n    volume: 77636,\n  },\n  {\n    date: 1461680880000,\n    open: 51.65,\n    high: 51.665,\n    low: 51.64,\n    close: 51.64,\n    volume: 77174,\n  },\n  {\n    date: 1461680940000,\n    open: 51.645,\n    high: 51.65,\n    low: 51.6105,\n    close: 51.615,\n    volume: 73646,\n  },\n  {\n    date: 1461681000000,\n    open: 51.615,\n    high: 51.62,\n    low: 51.57,\n    close: 51.59,\n    volume: 105041,\n  },\n  {\n    date: 1461681060000,\n    open: 51.58,\n    high: 51.6,\n    low: 51.56,\n    close: 51.57,\n    volume: 69467,\n  },\n  {\n    date: 1461681120000,\n    open: 51.5799,\n    high: 51.6,\n    low: 51.57,\n    close: 51.6,\n    volume: 42348,\n  },\n  {\n    date: 1461681180000,\n    open: 51.59,\n    high: 51.61,\n    low: 51.55,\n    close: 51.61,\n    volume: 170713,\n  },\n  {\n    date: 1461681240000,\n    open: 51.62,\n    high: 51.65,\n    low: 51.61,\n    close: 51.646,\n    volume: 59629,\n  },\n  {\n    date: 1461681300000,\n    open: 51.645,\n    high: 51.65,\n    low: 51.61,\n    close: 51.62,\n    volume: 90211,\n  },\n  {\n    date: 1461681360000,\n    open: 51.615,\n    high: 51.64,\n    low: 51.61,\n    close: 51.63,\n    volume: 38537,\n  },\n  {\n    date: 1461681420000,\n    open: 51.634,\n    high: 51.635,\n    low: 51.604,\n    close: 51.6265,\n    volume: 31776,\n  },\n  {\n    date: 1461681480000,\n    open: 51.63,\n    high: 51.635,\n    low: 51.6,\n    close: 51.605,\n    volume: 35661,\n  },\n  {\n    date: 1461681540000,\n    open: 51.6072,\n    high: 51.61,\n    low: 51.5755,\n    close: 51.5755,\n    volume: 49129,\n  },\n  {\n    date: 1461681600000,\n    open: 51.5762,\n    high: 51.5762,\n    low: 51.51,\n    close: 51.5138,\n    volume: 94513,\n  },\n  {\n    date: 1461681660000,\n    open: 51.52,\n    high: 51.53,\n    low: 51.505,\n    close: 51.51,\n    volume: 80093,\n  },\n  {\n    date: 1461681720000,\n    open: 51.52,\n    high: 51.58,\n    low: 51.51,\n    close: 51.58,\n    volume: 76254,\n  },\n  {\n    date: 1461681780000,\n    open: 51.58,\n    high: 51.61,\n    low: 51.57,\n    close: 51.605,\n    volume: 123141,\n  },\n  {\n    date: 1461681840000,\n    open: 51.61,\n    high: 51.63,\n    low: 51.59,\n    close: 51.6,\n    volume: 55938,\n  },\n  {\n    date: 1461681900000,\n    open: 51.595,\n    high: 51.605,\n    low: 51.58,\n    close: 51.5899,\n    volume: 33460,\n  },\n  {\n    date: 1461681960000,\n    open: 51.585,\n    high: 51.59,\n    low: 51.555,\n    close: 51.58,\n    volume: 68566,\n  },\n  {\n    date: 1461682020000,\n    open: 51.58,\n    high: 51.58,\n    low: 51.52,\n    close: 51.53,\n    volume: 42917,\n  },\n  {\n    date: 1461682080000,\n    open: 51.521,\n    high: 51.54,\n    low: 51.505,\n    close: 51.51,\n    volume: 55024,\n  },\n  {\n    date: 1461682140000,\n    open: 51.51,\n    high: 51.51,\n    low: 51.48,\n    close: 51.48,\n    volume: 250405,\n  },\n  {\n    date: 1461682200000,\n    open: 51.48,\n    high: 51.488,\n    low: 51.42,\n    close: 51.44,\n    volume: 82841,\n  },\n  {\n    date: 1461682260000,\n    open: 51.435,\n    high: 51.44,\n    low: 51.38,\n    close: 51.405,\n    volume: 115093,\n  },\n  {\n    date: 1461682320000,\n    open: 51.4099,\n    high: 51.43,\n    low: 51.4,\n    close: 51.4,\n    volume: 85716,\n  },\n  {\n    date: 1461682380000,\n    open: 51.41,\n    high: 51.41,\n    low: 51.36,\n    close: 51.365,\n    volume: 95856,\n  },\n  {\n    date: 1461682440000,\n    open: 51.365,\n    high: 51.41,\n    low: 51.36,\n    close: 51.405,\n    volume: 141377,\n  },\n  {\n    date: 1461682500000,\n    open: 51.4099,\n    high: 51.43,\n    low: 51.4,\n    close: 51.4099,\n    volume: 116039,\n  },\n  {\n    date: 1461682560000,\n    open: 51.42,\n    high: 51.46,\n    low: 51.4,\n    close: 51.46,\n    volume: 97021,\n  },\n  {\n    date: 1461682620000,\n    open: 51.455,\n    high: 51.49,\n    low: 51.4221,\n    close: 51.49,\n    volume: 54512,\n  },\n  {\n    date: 1461682680000,\n    open: 51.48,\n    high: 51.54,\n    low: 51.48,\n    close: 51.537,\n    volume: 77517,\n  },\n  {\n    date: 1461682740000,\n    open: 51.535,\n    high: 51.535,\n    low: 51.46,\n    close: 51.495,\n    volume: 67543,\n  },\n  {\n    date: 1461682800000,\n    open: 51.49,\n    high: 51.51,\n    low: 51.475,\n    close: 51.48,\n    volume: 43737,\n  },\n  {\n    date: 1461682860000,\n    open: 51.49,\n    high: 51.54,\n    low: 51.48,\n    close: 51.5301,\n    volume: 29428,\n  },\n  {\n    date: 1461682920000,\n    open: 51.5371,\n    high: 51.549,\n    low: 51.47,\n    close: 51.5,\n    volume: 63751,\n  },\n  {\n    date: 1461682980000,\n    open: 51.5,\n    high: 51.52,\n    low: 51.495,\n    close: 51.51,\n    volume: 31159,\n  },\n  {\n    date: 1461683040000,\n    open: 51.52,\n    high: 51.575,\n    low: 51.52,\n    close: 51.56,\n    volume: 58288,\n  },\n  {\n    date: 1461683100000,\n    open: 51.555,\n    high: 51.57,\n    low: 51.54,\n    close: 51.56,\n    volume: 38422,\n  },\n  {\n    date: 1461683160000,\n    open: 51.56,\n    high: 51.57,\n    low: 51.51,\n    close: 51.535,\n    volume: 102909,\n  },\n  {\n    date: 1461683220000,\n    open: 51.5336,\n    high: 51.61,\n    low: 51.5315,\n    close: 51.61,\n    volume: 63360,\n  },\n  {\n    date: 1461683280000,\n    open: 51.61,\n    high: 51.61,\n    low: 51.495,\n    close: 51.52,\n    volume: 157634,\n  },\n  {\n    date: 1461683340000,\n    open: 51.525,\n    high: 51.57,\n    low: 51.52,\n    close: 51.565,\n    volume: 26296,\n  },\n  {\n    date: 1461683400000,\n    open: 51.5601,\n    high: 51.579,\n    low: 51.54,\n    close: 51.55,\n    volume: 25682,\n  },\n  {\n    date: 1461683460000,\n    open: 51.5469,\n    high: 51.585,\n    low: 51.545,\n    close: 51.585,\n    volume: 31660,\n  },\n  {\n    date: 1461683520000,\n    open: 51.59,\n    high: 51.6,\n    low: 51.565,\n    close: 51.58,\n    volume: 36007,\n  },\n  {\n    date: 1461683580000,\n    open: 51.5861,\n    high: 51.5861,\n    low: 51.56,\n    close: 51.5665,\n    volume: 23907,\n  },\n  {\n    date: 1461683640000,\n    open: 51.5635,\n    high: 51.58,\n    low: 51.54,\n    close: 51.54,\n    volume: 47242,\n  },\n  {\n    date: 1461683700000,\n    open: 51.545,\n    high: 51.545,\n    low: 51.51,\n    close: 51.52,\n    volume: 42696,\n  },\n  {\n    date: 1461683760000,\n    open: 51.51,\n    high: 51.52,\n    low: 51.47,\n    close: 51.48,\n    volume: 104260,\n  },\n  {\n    date: 1461683820000,\n    open: 51.48,\n    high: 51.4865,\n    low: 51.45,\n    close: 51.455,\n    volume: 31009,\n  },\n  {\n    date: 1461683880000,\n    open: 51.455,\n    high: 51.46,\n    low: 51.44,\n    close: 51.44,\n    volume: 36785,\n  },\n  {\n    date: 1461683940000,\n    open: 51.449,\n    high: 51.45,\n    low: 51.44,\n    close: 51.445,\n    volume: 44972,\n  },\n  {\n    date: 1461684000000,\n    open: 51.4435,\n    high: 51.47,\n    low: 51.44,\n    close: 51.455,\n    volume: 76408,\n  },\n  {\n    date: 1461684060000,\n    open: 51.455,\n    high: 51.49,\n    low: 51.455,\n    close: 51.485,\n    volume: 104421,\n  },\n  {\n    date: 1461684120000,\n    open: 51.485,\n    high: 51.51,\n    low: 51.48,\n    close: 51.5,\n    volume: 54802,\n  },\n  {\n    date: 1461684180000,\n    open: 51.51,\n    high: 51.52,\n    low: 51.48,\n    close: 51.48,\n    volume: 55340,\n  },\n  {\n    date: 1461684240000,\n    open: 51.485,\n    high: 51.49,\n    low: 51.45,\n    close: 51.454,\n    volume: 50757,\n  },\n  {\n    date: 1461684300000,\n    open: 51.45,\n    high: 51.47,\n    low: 51.41,\n    close: 51.41,\n    volume: 262017,\n  },\n  {\n    date: 1461684360000,\n    open: 51.415,\n    high: 51.42,\n    low: 51.4,\n    close: 51.415,\n    volume: 51651,\n  },\n  {\n    date: 1461684420000,\n    open: 51.42,\n    high: 51.43,\n    low: 51.41,\n    close: 51.425,\n    volume: 143986,\n  },\n  {\n    date: 1461684480000,\n    open: 51.425,\n    high: 51.44,\n    low: 51.42,\n    close: 51.435,\n    volume: 55472,\n  },\n  {\n    date: 1461684540000,\n    open: 51.435,\n    high: 51.44,\n    low: 51.41,\n    close: 51.4165,\n    volume: 47710,\n  },\n  {\n    date: 1461684600000,\n    open: 51.41,\n    high: 51.43,\n    low: 51.4,\n    close: 51.42,\n    volume: 53583,\n  },\n  {\n    date: 1461684660000,\n    open: 51.43,\n    high: 51.445,\n    low: 51.41,\n    close: 51.42,\n    volume: 45049,\n  },\n  {\n    date: 1461684720000,\n    open: 51.415,\n    high: 51.43,\n    low: 51.41,\n    close: 51.42,\n    volume: 45048,\n  },\n  {\n    date: 1461684780000,\n    open: 51.4101,\n    high: 51.42,\n    low: 51.39,\n    close: 51.3999,\n    volume: 79320,\n  },\n  {\n    date: 1461684840000,\n    open: 51.39,\n    high: 51.3998,\n    low: 51.35,\n    close: 51.3601,\n    volume: 92361,\n  },\n  {\n    date: 1461684900000,\n    open: 51.365,\n    high: 51.3674,\n    low: 51.33,\n    close: 51.345,\n    volume: 103547,\n  },\n  {\n    date: 1461684960000,\n    open: 51.35,\n    high: 51.35,\n    low: 51.32,\n    close: 51.35,\n    volume: 102378,\n  },\n  {\n    date: 1461685020000,\n    open: 51.35,\n    high: 51.4,\n    low: 51.3467,\n    close: 51.39,\n    volume: 84090,\n  },\n  {\n    date: 1461685080000,\n    open: 51.39,\n    high: 51.41,\n    low: 51.39,\n    close: 51.41,\n    volume: 59329,\n  },\n  {\n    date: 1461685140000,\n    open: 51.4067,\n    high: 51.41,\n    low: 51.38,\n    close: 51.38,\n    volume: 37022,\n  },\n  {\n    date: 1461685200000,\n    open: 51.3899,\n    high: 51.4,\n    low: 51.38,\n    close: 51.39,\n    volume: 42234,\n  },\n  {\n    date: 1461685260000,\n    open: 51.39,\n    high: 51.44,\n    low: 51.38,\n    close: 51.44,\n    volume: 65274,\n  },\n  {\n    date: 1461685320000,\n    open: 51.44,\n    high: 51.46,\n    low: 51.42,\n    close: 51.4238,\n    volume: 54913,\n  },\n  {\n    date: 1461685380000,\n    open: 51.43,\n    high: 51.44,\n    low: 51.41,\n    close: 51.42,\n    volume: 25916,\n  },\n  {\n    date: 1461685440000,\n    open: 51.42,\n    high: 51.44,\n    low: 51.4172,\n    close: 51.435,\n    volume: 24808,\n  },\n  {\n    date: 1461685500000,\n    open: 51.435,\n    high: 51.44,\n    low: 51.4,\n    close: 51.415,\n    volume: 25958,\n  },\n  {\n    date: 1461685560000,\n    open: 51.41,\n    high: 51.41,\n    low: 51.35,\n    close: 51.36,\n    volume: 62207,\n  },\n  {\n    date: 1461685620000,\n    open: 51.37,\n    high: 51.38,\n    low: 51.3528,\n    close: 51.38,\n    volume: 41964,\n  },\n  {\n    date: 1461685680000,\n    open: 51.375,\n    high: 51.4,\n    low: 51.37,\n    close: 51.395,\n    volume: 29580,\n  },\n  {\n    date: 1461685740000,\n    open: 51.395,\n    high: 51.395,\n    low: 51.36,\n    close: 51.38,\n    volume: 56814,\n  },\n  {\n    date: 1461685800000,\n    open: 51.38,\n    high: 51.43,\n    low: 51.37,\n    close: 51.43,\n    volume: 50857,\n  },\n  {\n    date: 1461685860000,\n    open: 51.43,\n    high: 51.47,\n    low: 51.42,\n    close: 51.465,\n    volume: 48822,\n  },\n  {\n    date: 1461685920000,\n    open: 51.4633,\n    high: 51.465,\n    low: 51.43,\n    close: 51.445,\n    volume: 51183,\n  },\n  {\n    date: 1461685980000,\n    open: 51.44,\n    high: 51.4499,\n    low: 51.42,\n    close: 51.4274,\n    volume: 21516,\n  },\n  {\n    date: 1461686040000,\n    open: 51.42,\n    high: 51.44,\n    low: 51.42,\n    close: 51.44,\n    volume: 24055,\n  },\n  {\n    date: 1461686100000,\n    open: 51.44,\n    high: 51.47,\n    low: 51.435,\n    close: 51.47,\n    volume: 44433,\n  },\n  {\n    date: 1461686160000,\n    open: 51.47,\n    high: 51.49,\n    low: 51.455,\n    close: 51.46,\n    volume: 38331,\n  },\n  {\n    date: 1461686220000,\n    open: 51.455,\n    high: 51.49,\n    low: 51.45,\n    close: 51.47,\n    volume: 55572,\n  },\n  {\n    date: 1461686280000,\n    open: 51.46,\n    high: 51.47,\n    low: 51.45,\n    close: 51.45,\n    volume: 26775,\n  },\n  {\n    date: 1461686340000,\n    open: 51.455,\n    high: 51.46,\n    low: 51.44,\n    close: 51.45,\n    volume: 30079,\n  },\n  {\n    date: 1461686400000,\n    open: 51.44,\n    high: 51.45,\n    low: 51.44,\n    close: 51.445,\n    volume: 24803,\n  },\n  {\n    date: 1461686460000,\n    open: 51.445,\n    high: 51.49,\n    low: 51.44,\n    close: 51.4801,\n    volume: 58246,\n  },\n  {\n    date: 1461686520000,\n    open: 51.48,\n    high: 51.49,\n    low: 51.47,\n    close: 51.48,\n    volume: 27284,\n  },\n  {\n    date: 1461686580000,\n    open: 51.475,\n    high: 51.5,\n    low: 51.47,\n    close: 51.495,\n    volume: 34723,\n  },\n  {\n    date: 1461686640000,\n    open: 51.4912,\n    high: 51.54,\n    low: 51.4912,\n    close: 51.53,\n    volume: 53092,\n  },\n  {\n    date: 1461686700000,\n    open: 51.54,\n    high: 51.54,\n    low: 51.52,\n    close: 51.525,\n    volume: 20404,\n  },\n  {\n    date: 1461686760000,\n    open: 51.5235,\n    high: 51.53,\n    low: 51.495,\n    close: 51.502,\n    volume: 95128,\n  },\n  {\n    date: 1461686820000,\n    open: 51.5,\n    high: 51.51,\n    low: 51.5,\n    close: 51.505,\n    volume: 17875,\n  },\n  {\n    date: 1461686880000,\n    open: 51.505,\n    high: 51.51,\n    low: 51.48,\n    close: 51.49,\n    volume: 40577,\n  },\n  {\n    date: 1461686940000,\n    open: 51.4899,\n    high: 51.51,\n    low: 51.48,\n    close: 51.5,\n    volume: 27770,\n  },\n  {\n    date: 1461687000000,\n    open: 51.505,\n    high: 51.51,\n    low: 51.5,\n    close: 51.51,\n    volume: 49680,\n  },\n  {\n    date: 1461687060000,\n    open: 51.509,\n    high: 51.52,\n    low: 51.5,\n    close: 51.52,\n    volume: 43809,\n  },\n  {\n    date: 1461687120000,\n    open: 51.52,\n    high: 51.55,\n    low: 51.515,\n    close: 51.527,\n    volume: 26857,\n  },\n  {\n    date: 1461687180000,\n    open: 51.525,\n    high: 51.53,\n    low: 51.48,\n    close: 51.48,\n    volume: 42443,\n  },\n  {\n    date: 1461687240000,\n    open: 51.485,\n    high: 51.51,\n    low: 51.48,\n    close: 51.4999,\n    volume: 31967,\n  },\n  {\n    date: 1461687300000,\n    open: 51.4999,\n    high: 51.5,\n    low: 51.49,\n    close: 51.495,\n    volume: 12176,\n  },\n  {\n    date: 1461687360000,\n    open: 51.4999,\n    high: 51.5,\n    low: 51.47,\n    close: 51.47,\n    volume: 24410,\n  },\n  {\n    date: 1461687420000,\n    open: 51.48,\n    high: 51.485,\n    low: 51.45,\n    close: 51.4699,\n    volume: 40343,\n  },\n  {\n    date: 1461687480000,\n    open: 51.465,\n    high: 51.48,\n    low: 51.45,\n    close: 51.475,\n    volume: 37158,\n  },\n  {\n    date: 1461687540000,\n    open: 51.479,\n    high: 51.5,\n    low: 51.47,\n    close: 51.49,\n    volume: 50578,\n  },\n  {\n    date: 1461687600000,\n    open: 51.49,\n    high: 51.515,\n    low: 51.485,\n    close: 51.51,\n    volume: 53423,\n  },\n  {\n    date: 1461687660000,\n    open: 51.5115,\n    high: 51.5115,\n    low: 51.5,\n    close: 51.505,\n    volume: 8377,\n  },\n  {\n    date: 1461687720000,\n    open: 51.51,\n    high: 51.53,\n    low: 51.49,\n    close: 51.5,\n    volume: 61460,\n  },\n  {\n    date: 1461687780000,\n    open: 51.49,\n    high: 51.505,\n    low: 51.483,\n    close: 51.485,\n    volume: 60126,\n  },\n  {\n    date: 1461687840000,\n    open: 51.485,\n    high: 51.4864,\n    low: 51.46,\n    close: 51.48,\n    volume: 50862,\n  },\n  {\n    date: 1461687900000,\n    open: 51.4835,\n    high: 51.49,\n    low: 51.47,\n    close: 51.4899,\n    volume: 29306,\n  },\n  {\n    date: 1461687960000,\n    open: 51.485,\n    high: 51.49,\n    low: 51.46,\n    close: 51.466,\n    volume: 46179,\n  },\n  {\n    date: 1461688020000,\n    open: 51.4699,\n    high: 51.47,\n    low: 51.46,\n    close: 51.4639,\n    volume: 36140,\n  },\n  {\n    date: 1461688080000,\n    open: 51.4612,\n    high: 51.48,\n    low: 51.46,\n    close: 51.47,\n    volume: 29775,\n  },\n  {\n    date: 1461688140000,\n    open: 51.465,\n    high: 51.47,\n    low: 51.45,\n    close: 51.45,\n    volume: 16316,\n  },\n  {\n    date: 1461688200000,\n    open: 51.46,\n    high: 51.46,\n    low: 51.45,\n    close: 51.455,\n    volume: 23567,\n  },\n  {\n    date: 1461688260000,\n    open: 51.455,\n    high: 51.46,\n    low: 51.45,\n    close: 51.45,\n    volume: 15973,\n  },\n  {\n    date: 1461688320000,\n    open: 51.455,\n    high: 51.46,\n    low: 51.43,\n    close: 51.44,\n    volume: 55523,\n  },\n  {\n    date: 1461688380000,\n    open: 51.435,\n    high: 51.44,\n    low: 51.415,\n    close: 51.425,\n    volume: 35326,\n  },\n  {\n    date: 1461688440000,\n    open: 51.4267,\n    high: 51.44,\n    low: 51.41,\n    close: 51.42,\n    volume: 48857,\n  },\n  {\n    date: 1461688500000,\n    open: 51.41,\n    high: 51.42,\n    low: 51.41,\n    close: 51.42,\n    volume: 12885,\n  },\n  {\n    date: 1461688560000,\n    open: 51.415,\n    high: 51.42,\n    low: 51.4,\n    close: 51.42,\n    volume: 37845,\n  },\n  {\n    date: 1461688620000,\n    open: 51.415,\n    high: 51.42,\n    low: 51.38,\n    close: 51.385,\n    volume: 55487,\n  },\n  {\n    date: 1461688680000,\n    open: 51.385,\n    high: 51.3899,\n    low: 51.35,\n    close: 51.35,\n    volume: 31888,\n  },\n  {\n    date: 1461688740000,\n    open: 51.35,\n    high: 51.37,\n    low: 51.35,\n    close: 51.35,\n    volume: 54996,\n  },\n  {\n    date: 1461688800000,\n    open: 51.355,\n    high: 51.38,\n    low: 51.35,\n    close: 51.3755,\n    volume: 74038,\n  },\n  {\n    date: 1461688860000,\n    open: 51.3716,\n    high: 51.4,\n    low: 51.37,\n    close: 51.39,\n    volume: 53750,\n  },\n  {\n    date: 1461688920000,\n    open: 51.39,\n    high: 51.4,\n    low: 51.38,\n    close: 51.3901,\n    volume: 20274,\n  },\n  {\n    date: 1461688980000,\n    open: 51.3961,\n    high: 51.4,\n    low: 51.39,\n    close: 51.4,\n    volume: 25127,\n  },\n  {\n    date: 1461689040000,\n    open: 51.399,\n    high: 51.42,\n    low: 51.39,\n    close: 51.42,\n    volume: 30873,\n  },\n  {\n    date: 1461689100000,\n    open: 51.415,\n    high: 51.42,\n    low: 51.38,\n    close: 51.38,\n    volume: 64417,\n  },\n  {\n    date: 1461689160000,\n    open: 51.384,\n    high: 51.41,\n    low: 51.384,\n    close: 51.4,\n    volume: 18695,\n  },\n  {\n    date: 1461689220000,\n    open: 51.4088,\n    high: 51.41,\n    low: 51.38,\n    close: 51.3898,\n    volume: 103745,\n  },\n  {\n    date: 1461689280000,\n    open: 51.3844,\n    high: 51.41,\n    low: 51.3844,\n    close: 51.4,\n    volume: 55625,\n  },\n  {\n    date: 1461689340000,\n    open: 51.4,\n    high: 51.405,\n    low: 51.39,\n    close: 51.39,\n    volume: 63058,\n  },\n  {\n    date: 1461689400000,\n    open: 51.3901,\n    high: 51.4,\n    low: 51.39,\n    close: 51.395,\n    volume: 26496,\n  },\n  {\n    date: 1461689460000,\n    open: 51.4,\n    high: 51.43,\n    low: 51.38,\n    close: 51.385,\n    volume: 155744,\n  },\n  {\n    date: 1461689520000,\n    open: 51.385,\n    high: 51.409,\n    low: 51.37,\n    close: 51.405,\n    volume: 59165,\n  },\n  {\n    date: 1461689580000,\n    open: 51.405,\n    high: 51.41,\n    low: 51.4,\n    close: 51.41,\n    volume: 11822,\n  },\n  {\n    date: 1461689640000,\n    open: 51.4,\n    high: 51.4099,\n    low: 51.39,\n    close: 51.39,\n    volume: 41844,\n  },\n  {\n    date: 1461689700000,\n    open: 51.395,\n    high: 51.3999,\n    low: 51.39,\n    close: 51.39,\n    volume: 9987,\n  },\n  {\n    date: 1461689760000,\n    open: 51.39,\n    high: 51.4,\n    low: 51.36,\n    close: 51.365,\n    volume: 72272,\n  },\n  {\n    date: 1461689820000,\n    open: 51.36,\n    high: 51.37,\n    low: 51.35,\n    close: 51.365,\n    volume: 97996,\n  },\n  {\n    date: 1461689880000,\n    open: 51.365,\n    high: 51.39,\n    low: 51.35,\n    close: 51.37,\n    volume: 91379,\n  },\n  {\n    date: 1461689940000,\n    open: 51.37,\n    high: 51.38,\n    low: 51.36,\n    close: 51.365,\n    volume: 17633,\n  },\n  {\n    date: 1461690000000,\n    open: 51.365,\n    high: 51.37,\n    low: 51.31,\n    close: 51.315,\n    volume: 118326,\n  },\n  {\n    date: 1461690060000,\n    open: 51.31,\n    high: 51.34,\n    low: 51.31,\n    close: 51.33,\n    volume: 63666,\n  },\n  {\n    date: 1461690120000,\n    open: 51.325,\n    high: 51.33,\n    low: 51.31,\n    close: 51.31,\n    volume: 25720,\n  },\n  {\n    date: 1461690180000,\n    open: 51.31,\n    high: 51.32,\n    low: 51.29,\n    close: 51.3001,\n    volume: 67821,\n  },\n  {\n    date: 1461690240000,\n    open: 51.3,\n    high: 51.32,\n    low: 51.29,\n    close: 51.29,\n    volume: 101723,\n  },\n  {\n    date: 1461690300000,\n    open: 51.3,\n    high: 51.3,\n    low: 51.26,\n    close: 51.265,\n    volume: 104192,\n  },\n  {\n    date: 1461690360000,\n    open: 51.2699,\n    high: 51.28,\n    low: 51.25,\n    close: 51.2665,\n    volume: 91124,\n  },\n  {\n    date: 1461690420000,\n    open: 51.26,\n    high: 51.28,\n    low: 51.25,\n    close: 51.26,\n    volume: 43026,\n  },\n  {\n    date: 1461690480000,\n    open: 51.26,\n    high: 51.27,\n    low: 51.25,\n    close: 51.255,\n    volume: 19380,\n  },\n  {\n    date: 1461690540000,\n    open: 51.255,\n    high: 51.27,\n    low: 51.25,\n    close: 51.27,\n    volume: 42793,\n  },\n  {\n    date: 1461690600000,\n    open: 51.2701,\n    high: 51.3,\n    low: 51.26,\n    close: 51.291,\n    volume: 51508,\n  },\n  {\n    date: 1461690660000,\n    open: 51.3,\n    high: 51.3,\n    low: 51.28,\n    close: 51.28,\n    volume: 14956,\n  },\n  {\n    date: 1461690720000,\n    open: 51.28,\n    high: 51.285,\n    low: 51.25,\n    close: 51.26,\n    volume: 64228,\n  },\n  {\n    date: 1461690780000,\n    open: 51.255,\n    high: 51.265,\n    low: 51.24,\n    close: 51.24,\n    volume: 124828,\n  },\n  {\n    date: 1461690840000,\n    open: 51.245,\n    high: 51.26,\n    low: 51.24,\n    close: 51.25,\n    volume: 42980,\n  },\n  {\n    date: 1461690900000,\n    open: 51.24,\n    high: 51.25,\n    low: 51.22,\n    close: 51.23,\n    volume: 67033,\n  },\n  {\n    date: 1461690960000,\n    open: 51.22,\n    high: 51.235,\n    low: 51.22,\n    close: 51.23,\n    volume: 23187,\n  },\n  {\n    date: 1461691020000,\n    open: 51.225,\n    high: 51.25,\n    low: 51.225,\n    close: 51.2423,\n    volume: 30272,\n  },\n  {\n    date: 1461691080000,\n    open: 51.2474,\n    high: 51.275,\n    low: 51.24,\n    close: 51.275,\n    volume: 71152,\n  },\n  {\n    date: 1461691140000,\n    open: 51.27,\n    high: 51.28,\n    low: 51.25,\n    close: 51.25,\n    volume: 36039,\n  },\n  {\n    date: 1461691200000,\n    open: 51.255,\n    high: 51.26,\n    low: 51.24,\n    close: 51.245,\n    volume: 26090,\n  },\n  {\n    date: 1461691260000,\n    open: 51.2499,\n    high: 51.33,\n    low: 51.24,\n    close: 51.33,\n    volume: 169187,\n  },\n  {\n    date: 1461691320000,\n    open: 51.325,\n    high: 51.35,\n    low: 51.31,\n    close: 51.335,\n    volume: 76173,\n  },\n  {\n    date: 1461691380000,\n    open: 51.335,\n    high: 51.34,\n    low: 51.33,\n    close: 51.34,\n    volume: 8174,\n  },\n  {\n    date: 1461691440000,\n    open: 51.335,\n    high: 51.34,\n    low: 51.32,\n    close: 51.325,\n    volume: 29302,\n  },\n  {\n    date: 1461691500000,\n    open: 51.33,\n    high: 51.35,\n    low: 51.325,\n    close: 51.345,\n    volume: 33042,\n  },\n  {\n    date: 1461691560000,\n    open: 51.345,\n    high: 51.3465,\n    low: 51.31,\n    close: 51.32,\n    volume: 52948,\n  },\n  {\n    date: 1461691620000,\n    open: 51.3235,\n    high: 51.34,\n    low: 51.32,\n    close: 51.3259,\n    volume: 23122,\n  },\n  {\n    date: 1461691680000,\n    open: 51.32,\n    high: 51.33,\n    low: 51.32,\n    close: 51.325,\n    volume: 16873,\n  },\n  {\n    date: 1461691740000,\n    open: 51.33,\n    high: 51.33,\n    low: 51.32,\n    close: 51.33,\n    volume: 12906,\n  },\n  {\n    date: 1461691800000,\n    open: 51.325,\n    high: 51.35,\n    low: 51.32,\n    close: 51.35,\n    volume: 51922,\n  },\n  {\n    date: 1461691860000,\n    open: 51.34,\n    high: 51.36,\n    low: 51.34,\n    close: 51.344,\n    volume: 42999,\n  },\n  {\n    date: 1461691920000,\n    open: 51.35,\n    high: 51.365,\n    low: 51.34,\n    close: 51.355,\n    volume: 73149,\n  },\n  {\n    date: 1461691980000,\n    open: 51.35,\n    high: 51.36,\n    low: 51.35,\n    close: 51.3501,\n    volume: 19223,\n  },\n  {\n    date: 1461692040000,\n    open: 51.36,\n    high: 51.41,\n    low: 51.355,\n    close: 51.3902,\n    volume: 66688,\n  },\n  {\n    date: 1461692100000,\n    open: 51.396,\n    high: 51.4,\n    low: 51.34,\n    close: 51.345,\n    volume: 39025,\n  },\n  {\n    date: 1461692160000,\n    open: 51.34,\n    high: 51.35,\n    low: 51.33,\n    close: 51.33,\n    volume: 30643,\n  },\n  {\n    date: 1461692220000,\n    open: 51.3301,\n    high: 51.35,\n    low: 51.33,\n    close: 51.3499,\n    volume: 26575,\n  },\n  {\n    date: 1461692280000,\n    open: 51.35,\n    high: 51.35,\n    low: 51.34,\n    close: 51.35,\n    volume: 19434,\n  },\n  {\n    date: 1461692340000,\n    open: 51.35,\n    high: 51.35,\n    low: 51.34,\n    close: 51.35,\n    volume: 19485,\n  },\n  {\n    date: 1461692400000,\n    open: 51.3497,\n    high: 51.385,\n    low: 51.345,\n    close: 51.37,\n    volume: 59474,\n  },\n  {\n    date: 1461692460000,\n    open: 51.365,\n    high: 51.38,\n    low: 51.3401,\n    close: 51.3401,\n    volume: 49698,\n  },\n  {\n    date: 1461692520000,\n    open: 51.3499,\n    high: 51.36,\n    low: 51.27,\n    close: 51.275,\n    volume: 126510,\n  },\n  {\n    date: 1461692580000,\n    open: 51.2799,\n    high: 51.3,\n    low: 51.275,\n    close: 51.2899,\n    volume: 27153,\n  },\n  {\n    date: 1461692640000,\n    open: 51.28,\n    high: 51.29,\n    low: 51.255,\n    close: 51.26,\n    volume: 138312,\n  },\n  {\n    date: 1461692700000,\n    open: 51.26,\n    high: 51.3,\n    low: 51.255,\n    close: 51.26,\n    volume: 80268,\n  },\n  {\n    date: 1461692760000,\n    open: 51.265,\n    high: 51.3,\n    low: 51.265,\n    close: 51.2999,\n    volume: 33419,\n  },\n  {\n    date: 1461692820000,\n    open: 51.292,\n    high: 51.295,\n    low: 51.2801,\n    close: 51.2801,\n    volume: 17175,\n  },\n  {\n    date: 1461692880000,\n    open: 51.29,\n    high: 51.3,\n    low: 51.28,\n    close: 51.2999,\n    volume: 28855,\n  },\n  {\n    date: 1461692940000,\n    open: 51.295,\n    high: 51.295,\n    low: 51.26,\n    close: 51.275,\n    volume: 64582,\n  },\n  {\n    date: 1461693000000,\n    open: 51.2712,\n    high: 51.28,\n    low: 51.27,\n    close: 51.275,\n    volume: 18615,\n  },\n  {\n    date: 1461693060000,\n    open: 51.275,\n    high: 51.28,\n    low: 51.25,\n    close: 51.26,\n    volume: 36116,\n  },\n  {\n    date: 1461693120000,\n    open: 51.255,\n    high: 51.28,\n    low: 51.255,\n    close: 51.275,\n    volume: 26105,\n  },\n  {\n    date: 1461693180000,\n    open: 51.2701,\n    high: 51.29,\n    low: 51.2549,\n    close: 51.2899,\n    volume: 68387,\n  },\n  {\n    date: 1461693240000,\n    open: 51.29,\n    high: 51.3,\n    low: 51.265,\n    close: 51.265,\n    volume: 76742,\n  },\n  {\n    date: 1461693300000,\n    open: 51.27,\n    high: 51.29,\n    low: 51.26,\n    close: 51.275,\n    volume: 42525,\n  },\n  {\n    date: 1461693360000,\n    open: 51.279,\n    high: 51.29,\n    low: 51.26,\n    close: 51.27,\n    volume: 58889,\n  },\n  {\n    date: 1461693420000,\n    open: 51.27,\n    high: 51.28,\n    low: 51.25,\n    close: 51.25,\n    volume: 81920,\n  },\n  {\n    date: 1461693480000,\n    open: 51.26,\n    high: 51.26,\n    low: 51.25,\n    close: 51.255,\n    volume: 21222,\n  },\n  {\n    date: 1461693540000,\n    open: 51.255,\n    high: 51.265,\n    low: 51.225,\n    close: 51.235,\n    volume: 149244,\n  },\n  {\n    date: 1461693600000,\n    open: 51.2315,\n    high: 51.24,\n    low: 51.22,\n    close: 51.235,\n    volume: 69064,\n  },\n  {\n    date: 1461693660000,\n    open: 51.237,\n    high: 51.24,\n    low: 51.22,\n    close: 51.225,\n    volume: 58582,\n  },\n  {\n    date: 1461693720000,\n    open: 51.2232,\n    high: 51.245,\n    low: 51.22,\n    close: 51.225,\n    volume: 58339,\n  },\n  {\n    date: 1461693780000,\n    open: 51.23,\n    high: 51.24,\n    low: 51.22,\n    close: 51.24,\n    volume: 57332,\n  },\n  {\n    date: 1461693840000,\n    open: 51.24,\n    high: 51.24,\n    low: 51.23,\n    close: 51.23,\n    volume: 35436,\n  },\n  {\n    date: 1461693900000,\n    open: 51.23,\n    high: 51.2375,\n    low: 51.21,\n    close: 51.215,\n    volume: 38542,\n  },\n  {\n    date: 1461693960000,\n    open: 51.22,\n    high: 51.22,\n    low: 51.19,\n    close: 51.1931,\n    volume: 72699,\n  },\n  {\n    date: 1461694020000,\n    open: 51.19,\n    high: 51.2,\n    low: 51.19,\n    close: 51.19,\n    volume: 133086,\n  },\n  {\n    date: 1461694080000,\n    open: 51.195,\n    high: 51.2,\n    low: 51.13,\n    close: 51.135,\n    volume: 94408,\n  },\n  {\n    date: 1461694140000,\n    open: 51.13,\n    high: 51.14,\n    low: 51.1,\n    close: 51.128,\n    volume: 177851,\n  },\n  {\n    date: 1461694200000,\n    open: 51.13,\n    high: 51.135,\n    low: 51.1,\n    close: 51.105,\n    volume: 112702,\n  },\n  {\n    date: 1461694260000,\n    open: 51.1099,\n    high: 51.12,\n    low: 51.09,\n    close: 51.1199,\n    volume: 136583,\n  },\n  {\n    date: 1461694320000,\n    open: 51.12,\n    high: 51.14,\n    low: 51.11,\n    close: 51.135,\n    volume: 83169,\n  },\n  {\n    date: 1461694380000,\n    open: 51.14,\n    high: 51.14,\n    low: 51.12,\n    close: 51.131,\n    volume: 100262,\n  },\n  {\n    date: 1461694440000,\n    open: 51.135,\n    high: 51.145,\n    low: 51.1301,\n    close: 51.145,\n    volume: 45608,\n  },\n  {\n    date: 1461694500000,\n    open: 51.145,\n    high: 51.17,\n    low: 51.135,\n    close: 51.165,\n    volume: 84293,\n  },\n  {\n    date: 1461694560000,\n    open: 51.165,\n    high: 51.21,\n    low: 51.165,\n    close: 51.201,\n    volume: 66062,\n  },\n  {\n    date: 1461694620000,\n    open: 51.205,\n    high: 51.225,\n    low: 51.19,\n    close: 51.205,\n    volume: 93173,\n  },\n  {\n    date: 1461694680000,\n    open: 51.21,\n    high: 51.225,\n    low: 51.2001,\n    close: 51.22,\n    volume: 67432,\n  },\n  {\n    date: 1461694740000,\n    open: 51.22,\n    high: 51.27,\n    low: 51.21,\n    close: 51.22,\n    volume: 106052,\n  },\n  {\n    date: 1461694800000,\n    open: 51.22,\n    high: 51.24,\n    low: 51.21,\n    close: 51.2101,\n    volume: 174594,\n  },\n  {\n    date: 1461694860000,\n    open: 51.22,\n    high: 51.22,\n    low: 51.195,\n    close: 51.195,\n    volume: 50657,\n  },\n  {\n    date: 1461694920000,\n    open: 51.2,\n    high: 51.2,\n    low: 51.18,\n    close: 51.1801,\n    volume: 56105,\n  },\n  {\n    date: 1461694980000,\n    open: 51.19,\n    high: 51.19,\n    low: 51.1601,\n    close: 51.18,\n    volume: 41722,\n  },\n  {\n    date: 1461695040000,\n    open: 51.17,\n    high: 51.225,\n    low: 51.17,\n    close: 51.225,\n    volume: 54861,\n  },\n  {\n    date: 1461695100000,\n    open: 51.22,\n    high: 51.22,\n    low: 51.2,\n    close: 51.2165,\n    volume: 38914,\n  },\n  {\n    date: 1461695160000,\n    open: 51.215,\n    high: 51.23,\n    low: 51.21,\n    close: 51.23,\n    volume: 30223,\n  },\n  {\n    date: 1461695220000,\n    open: 51.23,\n    high: 51.27,\n    low: 51.225,\n    close: 51.27,\n    volume: 77630,\n  },\n  {\n    date: 1461695280000,\n    open: 51.27,\n    high: 51.27,\n    low: 51.24,\n    close: 51.25,\n    volume: 65995,\n  },\n  {\n    date: 1461695340000,\n    open: 51.245,\n    high: 51.245,\n    low: 51.19,\n    close: 51.195,\n    volume: 67261,\n  },\n  {\n    date: 1461695400000,\n    open: 51.195,\n    high: 51.21,\n    low: 51.15,\n    close: 51.16,\n    volume: 103488,\n  },\n  {\n    date: 1461695460000,\n    open: 51.1501,\n    high: 51.18,\n    low: 51.14,\n    close: 51.1784,\n    volume: 69263,\n  },\n  {\n    date: 1461695520000,\n    open: 51.175,\n    high: 51.19,\n    low: 51.17,\n    close: 51.175,\n    volume: 52015,\n  },\n  {\n    date: 1461695580000,\n    open: 51.18,\n    high: 51.1871,\n    low: 51.17,\n    close: 51.175,\n    volume: 24689,\n  },\n  {\n    date: 1461695640000,\n    open: 51.171,\n    high: 51.21,\n    low: 51.171,\n    close: 51.205,\n    volume: 81524,\n  },\n  {\n    date: 1461695700000,\n    open: 51.2015,\n    high: 51.21,\n    low: 51.19,\n    close: 51.205,\n    volume: 58260,\n  },\n  {\n    date: 1461695760000,\n    open: 51.2074,\n    high: 51.21,\n    low: 51.19,\n    close: 51.2,\n    volume: 73273,\n  },\n  {\n    date: 1461695820000,\n    open: 51.2,\n    high: 51.23,\n    low: 51.2,\n    close: 51.225,\n    volume: 60278,\n  },\n  {\n    date: 1461695880000,\n    open: 51.225,\n    high: 51.23,\n    low: 51.21,\n    close: 51.22,\n    volume: 57308,\n  },\n  {\n    date: 1461695940000,\n    open: 51.225,\n    high: 51.23,\n    low: 51.2101,\n    close: 51.2238,\n    volume: 40786,\n  },\n  {\n    date: 1461696000000,\n    open: 51.225,\n    high: 51.245,\n    low: 51.22,\n    close: 51.235,\n    volume: 57466,\n  },\n  {\n    date: 1461696060000,\n    open: 51.235,\n    high: 51.24,\n    low: 51.23,\n    close: 51.24,\n    volume: 22579,\n  },\n  {\n    date: 1461696120000,\n    open: 51.235,\n    high: 51.24,\n    low: 51.23,\n    close: 51.235,\n    volume: 25375,\n  },\n  {\n    date: 1461696180000,\n    open: 51.24,\n    high: 51.25,\n    low: 51.235,\n    close: 51.245,\n    volume: 49874,\n  },\n  {\n    date: 1461696240000,\n    open: 51.25,\n    high: 51.2575,\n    low: 51.23,\n    close: 51.235,\n    volume: 125767,\n  },\n  {\n    date: 1461696300000,\n    open: 51.235,\n    high: 51.24,\n    low: 51.21,\n    close: 51.215,\n    volume: 34525,\n  },\n  {\n    date: 1461696360000,\n    open: 51.215,\n    high: 51.23,\n    low: 51.21,\n    close: 51.225,\n    volume: 48440,\n  },\n  {\n    date: 1461696420000,\n    open: 51.225,\n    high: 51.25,\n    low: 51.2201,\n    close: 51.225,\n    volume: 108924,\n  },\n  {\n    date: 1461696480000,\n    open: 51.225,\n    high: 51.23,\n    low: 51.22,\n    close: 51.225,\n    volume: 19035,\n  },\n  {\n    date: 1461696540000,\n    open: 51.225,\n    high: 51.25,\n    low: 51.22,\n    close: 51.23,\n    volume: 77256,\n  },\n  {\n    date: 1461696600000,\n    open: 51.235,\n    high: 51.26,\n    low: 51.2301,\n    close: 51.2365,\n    volume: 90845,\n  },\n  {\n    date: 1461696660000,\n    open: 51.235,\n    high: 51.24,\n    low: 51.21,\n    close: 51.21,\n    volume: 61294,\n  },\n  {\n    date: 1461696720000,\n    open: 51.215,\n    high: 51.22,\n    low: 51.19,\n    close: 51.19,\n    volume: 63690,\n  },\n  {\n    date: 1461696780000,\n    open: 51.1999,\n    high: 51.205,\n    low: 51.18,\n    close: 51.2,\n    volume: 50132,\n  },\n  {\n    date: 1461696840000,\n    open: 51.2,\n    high: 51.22,\n    low: 51.2,\n    close: 51.2001,\n    volume: 46719,\n  },\n  {\n    date: 1461696900000,\n    open: 51.205,\n    high: 51.21,\n    low: 51.19,\n    close: 51.2,\n    volume: 38890,\n  },\n  {\n    date: 1461696960000,\n    open: 51.205,\n    high: 51.21,\n    low: 51.2,\n    close: 51.2065,\n    volume: 23843,\n  },\n  {\n    date: 1461697020000,\n    open: 51.205,\n    high: 51.21,\n    low: 51.19,\n    close: 51.195,\n    volume: 67367,\n  },\n  {\n    date: 1461697080000,\n    open: 51.1999,\n    high: 51.1999,\n    low: 51.15,\n    close: 51.18,\n    volume: 96229,\n  },\n  {\n    date: 1461697140000,\n    open: 51.185,\n    high: 51.2,\n    low: 51.18,\n    close: 51.2,\n    volume: 28338,\n  },\n  {\n    date: 1461697200000,\n    open: 51.195,\n    high: 51.2,\n    low: 51.18,\n    close: 51.185,\n    volume: 33740,\n  },\n  {\n    date: 1461697260000,\n    open: 51.18,\n    high: 51.22,\n    low: 51.18,\n    close: 51.195,\n    volume: 124582,\n  },\n  {\n    date: 1461697320000,\n    open: 51.197,\n    high: 51.24,\n    low: 51.197,\n    close: 51.2201,\n    volume: 81428,\n  },\n  {\n    date: 1461697380000,\n    open: 51.22,\n    high: 51.24,\n    low: 51.2,\n    close: 51.205,\n    volume: 107658,\n  },\n  {\n    date: 1461697440000,\n    open: 51.205,\n    high: 51.22,\n    low: 51.2001,\n    close: 51.215,\n    volume: 40912,\n  },\n  {\n    date: 1461697500000,\n    open: 51.215,\n    high: 51.26,\n    low: 51.215,\n    close: 51.255,\n    volume: 194425,\n  },\n  {\n    date: 1461697560000,\n    open: 51.26,\n    high: 51.26,\n    low: 51.25,\n    close: 51.255,\n    volume: 33390,\n  },\n  {\n    date: 1461697620000,\n    open: 51.255,\n    high: 51.265,\n    low: 51.2501,\n    close: 51.26,\n    volume: 53701,\n  },\n  {\n    date: 1461697680000,\n    open: 51.26,\n    high: 51.29,\n    low: 51.25,\n    close: 51.29,\n    volume: 243703,\n  },\n  {\n    date: 1461697740000,\n    open: 51.29,\n    high: 51.315,\n    low: 51.28,\n    close: 51.3,\n    volume: 62867,\n  },\n  {\n    date: 1461697800000,\n    open: 51.3,\n    high: 51.31,\n    low: 51.29,\n    close: 51.2901,\n    volume: 147220,\n  },\n  {\n    date: 1461697860000,\n    open: 51.295,\n    high: 51.3099,\n    low: 51.26,\n    close: 51.26,\n    volume: 136632,\n  },\n  {\n    date: 1461697920000,\n    open: 51.27,\n    high: 51.27,\n    low: 51.26,\n    close: 51.26,\n    volume: 31462,\n  },\n  {\n    date: 1461697980000,\n    open: 51.26,\n    high: 51.27,\n    low: 51.25,\n    close: 51.25,\n    volume: 42617,\n  },\n  {\n    date: 1461698040000,\n    open: 51.25,\n    high: 51.26,\n    low: 51.25,\n    close: 51.255,\n    volume: 25352,\n  },\n  {\n    date: 1461698100000,\n    open: 51.25,\n    high: 51.26,\n    low: 51.25,\n    close: 51.26,\n    volume: 205260,\n  },\n  {\n    date: 1461698160000,\n    open: 51.26,\n    high: 51.265,\n    low: 51.25,\n    close: 51.255,\n    volume: 94549,\n  },\n  {\n    date: 1461698220000,\n    open: 51.255,\n    high: 51.26,\n    low: 51.22,\n    close: 51.2299,\n    volume: 93539,\n  },\n  {\n    date: 1461698280000,\n    open: 51.23,\n    high: 51.26,\n    low: 51.22,\n    close: 51.235,\n    volume: 97214,\n  },\n  {\n    date: 1461698340000,\n    open: 51.23,\n    high: 51.24,\n    low: 51.21,\n    close: 51.235,\n    volume: 60386,\n  },\n  {\n    date: 1461698400000,\n    open: 51.23,\n    high: 51.245,\n    low: 51.21,\n    close: 51.215,\n    volume: 99774,\n  },\n  {\n    date: 1461698460000,\n    open: 51.215,\n    high: 51.24,\n    low: 51.2,\n    close: 51.23,\n    volume: 70136,\n  },\n  {\n    date: 1461698520000,\n    open: 51.24,\n    high: 51.27,\n    low: 51.23,\n    close: 51.25,\n    volume: 90773,\n  },\n  {\n    date: 1461698580000,\n    open: 51.25,\n    high: 51.26,\n    low: 51.21,\n    close: 51.21,\n    volume: 40651,\n  },\n  {\n    date: 1461698640000,\n    open: 51.2165,\n    high: 51.24,\n    low: 51.21,\n    close: 51.215,\n    volume: 103463,\n  },\n  {\n    date: 1461698700000,\n    open: 51.21,\n    high: 51.21,\n    low: 51.16,\n    close: 51.1965,\n    volume: 78583,\n  },\n  {\n    date: 1461698760000,\n    open: 51.19,\n    high: 51.21,\n    low: 51.18,\n    close: 51.185,\n    volume: 83558,\n  },\n  {\n    date: 1461698820000,\n    open: 51.185,\n    high: 51.19,\n    low: 51.17,\n    close: 51.18,\n    volume: 93121,\n  },\n  {\n    date: 1461698880000,\n    open: 51.18,\n    high: 51.19,\n    low: 51.16,\n    close: 51.185,\n    volume: 87356,\n  },\n  {\n    date: 1461698940000,\n    open: 51.185,\n    high: 51.2,\n    low: 51.17,\n    close: 51.1701,\n    volume: 63671,\n  },\n  {\n    date: 1461699000000,\n    open: 51.17,\n    high: 51.19,\n    low: 51.16,\n    close: 51.18,\n    volume: 112298,\n  },\n  {\n    date: 1461699060000,\n    open: 51.18,\n    high: 51.2,\n    low: 51.17,\n    close: 51.1701,\n    volume: 82741,\n  },\n  {\n    date: 1461699120000,\n    open: 51.17,\n    high: 51.2,\n    low: 51.16,\n    close: 51.2,\n    volume: 126850,\n  },\n  {\n    date: 1461699180000,\n    open: 51.194,\n    high: 51.26,\n    low: 51.18,\n    close: 51.221,\n    volume: 173750,\n  },\n  {\n    date: 1461699240000,\n    open: 51.2266,\n    high: 51.25,\n    low: 51.225,\n    close: 51.245,\n    volume: 110146,\n  },\n  {\n    date: 1461699300000,\n    open: 51.25,\n    high: 51.25,\n    low: 51.2,\n    close: 51.2066,\n    volume: 91103,\n  },\n  {\n    date: 1461699360000,\n    open: 51.2099,\n    high: 51.23,\n    low: 51.2,\n    close: 51.23,\n    volume: 72088,\n  },\n  {\n    date: 1461699420000,\n    open: 51.23,\n    high: 51.29,\n    low: 51.23,\n    close: 51.255,\n    volume: 104966,\n  },\n  {\n    date: 1461699480000,\n    open: 51.255,\n    high: 51.28,\n    low: 51.25,\n    close: 51.275,\n    volume: 46451,\n  },\n  {\n    date: 1461699540000,\n    open: 51.279,\n    high: 51.3,\n    low: 51.27,\n    close: 51.29,\n    volume: 63624,\n  },\n  {\n    date: 1461699600000,\n    open: 51.299,\n    high: 51.3,\n    low: 51.285,\n    close: 51.3,\n    volume: 235141,\n  },\n  {\n    date: 1461699660000,\n    open: 51.295,\n    high: 51.33,\n    low: 51.29,\n    close: 51.33,\n    volume: 229261,\n  },\n  {\n    date: 1461699720000,\n    open: 51.33,\n    high: 51.35,\n    low: 51.32,\n    close: 51.345,\n    volume: 114393,\n  },\n  {\n    date: 1461699780000,\n    open: 51.35,\n    high: 51.37,\n    low: 51.335,\n    close: 51.342,\n    volume: 173830,\n  },\n  {\n    date: 1461699840000,\n    open: 51.34,\n    high: 51.37,\n    low: 51.32,\n    close: 51.32,\n    volume: 114021,\n  },\n  {\n    date: 1461699900000,\n    open: 51.32,\n    high: 51.36,\n    low: 51.315,\n    close: 51.355,\n    volume: 94187,\n  },\n  {\n    date: 1461699960000,\n    open: 51.355,\n    high: 51.39,\n    low: 51.35,\n    close: 51.39,\n    volume: 253167,\n  },\n  {\n    date: 1461700020000,\n    open: 51.39,\n    high: 51.39,\n    low: 51.3325,\n    close: 51.341,\n    volume: 100681,\n  },\n  {\n    date: 1461700080000,\n    open: 51.3431,\n    high: 51.37,\n    low: 51.3431,\n    close: 51.36,\n    volume: 83335,\n  },\n  {\n    date: 1461700140000,\n    open: 51.37,\n    high: 51.37,\n    low: 51.34,\n    close: 51.355,\n    volume: 84954,\n  },\n  {\n    date: 1461700200000,\n    open: 51.355,\n    high: 51.41,\n    low: 51.3501,\n    close: 51.38,\n    volume: 149678,\n  },\n  {\n    date: 1461700260000,\n    open: 51.38,\n    high: 51.4,\n    low: 51.34,\n    close: 51.345,\n    volume: 144252,\n  },\n  {\n    date: 1461700320000,\n    open: 51.345,\n    high: 51.38,\n    low: 51.34,\n    close: 51.365,\n    volume: 147299,\n  },\n  {\n    date: 1461700380000,\n    open: 51.36,\n    high: 51.38,\n    low: 51.36,\n    close: 51.3664,\n    volume: 116945,\n  },\n  {\n    date: 1461700440000,\n    open: 51.365,\n    high: 51.38,\n    low: 51.36,\n    close: 51.37,\n    volume: 133964,\n  },\n  {\n    date: 1461700500000,\n    open: 51.365,\n    high: 51.37,\n    low: 51.36,\n    close: 51.36,\n    volume: 82837,\n  },\n  {\n    date: 1461700560000,\n    open: 51.36,\n    high: 51.37,\n    low: 51.34,\n    close: 51.355,\n    volume: 167073,\n  },\n  {\n    date: 1461700620000,\n    open: 51.355,\n    high: 51.36,\n    low: 51.35,\n    close: 51.36,\n    volume: 145386,\n  },\n  {\n    date: 1461700680000,\n    open: 51.355,\n    high: 51.38,\n    low: 51.35,\n    close: 51.37,\n    volume: 281815,\n  },\n  {\n    date: 1461700740000,\n    open: 51.365,\n    high: 51.38,\n    low: 51.36,\n    close: 51.38,\n    volume: 262208,\n  },\n  {\n    date: 1461700800000,\n    open: 51.375,\n    high: 51.44,\n    low: 51.37,\n    close: 51.44,\n    volume: 2950673,\n  },\n  {\n    date: 1461763800000,\n    open: 51.48,\n    high: 51.495,\n    low: 51.48,\n    close: 51.49,\n    volume: 546773,\n  },\n  {\n    date: 1461763860000,\n    open: 51.495,\n    high: 51.5,\n    low: 51.38,\n    close: 51.39,\n    volume: 163829,\n  },\n  {\n    date: 1461763920000,\n    open: 51.4,\n    high: 51.4,\n    low: 51.2699,\n    close: 51.28,\n    volume: 134670,\n  },\n  {\n    date: 1461763980000,\n    open: 51.28,\n    high: 51.29,\n    low: 51.245,\n    close: 51.28,\n    volume: 151479,\n  },\n  {\n    date: 1461764040000,\n    open: 51.274,\n    high: 51.34,\n    low: 51.26,\n    close: 51.34,\n    volume: 108716,\n  },\n  {\n    date: 1461764100000,\n    open: 51.33,\n    high: 51.4,\n    low: 51.33,\n    close: 51.37,\n    volume: 68384,\n  },\n  {\n    date: 1461764160000,\n    open: 51.37,\n    high: 51.37,\n    low: 51.34,\n    close: 51.353,\n    volume: 86360,\n  },\n  {\n    date: 1461764220000,\n    open: 51.36,\n    high: 51.37,\n    low: 51.32,\n    close: 51.33,\n    volume: 152664,\n  },\n  {\n    date: 1461764280000,\n    open: 51.33,\n    high: 51.3711,\n    low: 51.33,\n    close: 51.35,\n    volume: 118469,\n  },\n  {\n    date: 1461764340000,\n    open: 51.355,\n    high: 51.3799,\n    low: 51.3499,\n    close: 51.36,\n    volume: 260691,\n  },\n  {\n    date: 1461764400000,\n    open: 51.3601,\n    high: 51.365,\n    low: 51.31,\n    close: 51.33,\n    volume: 77674,\n  },\n  {\n    date: 1461764460000,\n    open: 51.34,\n    high: 51.34,\n    low: 51.28,\n    close: 51.31,\n    volume: 91033,\n  },\n  {\n    date: 1461764520000,\n    open: 51.31,\n    high: 51.365,\n    low: 51.3,\n    close: 51.35,\n    volume: 203975,\n  },\n  {\n    date: 1461764580000,\n    open: 51.35,\n    high: 51.36,\n    low: 51.24,\n    close: 51.245,\n    volume: 164021,\n  },\n  {\n    date: 1461764640000,\n    open: 51.25,\n    high: 51.27,\n    low: 51.22,\n    close: 51.27,\n    volume: 195282,\n  },\n  {\n    date: 1461764700000,\n    open: 51.2665,\n    high: 51.27,\n    low: 51.16,\n    close: 51.17,\n    volume: 103043,\n  },\n  {\n    date: 1461764760000,\n    open: 51.165,\n    high: 51.2,\n    low: 51.1601,\n    close: 51.195,\n    volume: 112338,\n  },\n  {\n    date: 1461764820000,\n    open: 51.195,\n    high: 51.2,\n    low: 51.12,\n    close: 51.13,\n    volume: 122031,\n  },\n  {\n    date: 1461764880000,\n    open: 51.13,\n    high: 51.14,\n    low: 51.12,\n    close: 51.13,\n    volume: 84016,\n  },\n  {\n    date: 1461764940000,\n    open: 51.125,\n    high: 51.15,\n    low: 51.11,\n    close: 51.115,\n    volume: 143612,\n  },\n  {\n    date: 1461765000000,\n    open: 51.115,\n    high: 51.115,\n    low: 51.07,\n    close: 51.09,\n    volume: 253743,\n  },\n  {\n    date: 1461765060000,\n    open: 51.09,\n    high: 51.16,\n    low: 51.07,\n    close: 51.1482,\n    volume: 159653,\n  },\n  {\n    date: 1461765120000,\n    open: 51.15,\n    high: 51.195,\n    low: 51.12,\n    close: 51.13,\n    volume: 108530,\n  },\n  {\n    date: 1461765180000,\n    open: 51.13,\n    high: 51.14,\n    low: 51.1,\n    close: 51.125,\n    volume: 68276,\n  },\n  {\n    date: 1461765240000,\n    open: 51.13,\n    high: 51.13,\n    low: 51.0899,\n    close: 51.09,\n    volume: 86166,\n  },\n  {\n    date: 1461765300000,\n    open: 51.0936,\n    high: 51.1,\n    low: 51.075,\n    close: 51.1,\n    volume: 47248,\n  },\n  {\n    date: 1461765360000,\n    open: 51.1,\n    high: 51.12,\n    low: 51.09,\n    close: 51.1166,\n    volume: 101507,\n  },\n  {\n    date: 1461765420000,\n    open: 51.11,\n    high: 51.11,\n    low: 51.09,\n    close: 51.11,\n    volume: 94287,\n  },\n  {\n    date: 1461765480000,\n    open: 51.105,\n    high: 51.17,\n    low: 51.105,\n    close: 51.16,\n    volume: 170212,\n  },\n  {\n    date: 1461765540000,\n    open: 51.165,\n    high: 51.165,\n    low: 51.11,\n    close: 51.12,\n    volume: 146729,\n  },\n  {\n    date: 1461765600000,\n    open: 51.12,\n    high: 51.12,\n    low: 51.09,\n    close: 51.105,\n    volume: 82802,\n  },\n  {\n    date: 1461765660000,\n    open: 51.1,\n    high: 51.135,\n    low: 51.09,\n    close: 51.115,\n    volume: 177633,\n  },\n  {\n    date: 1461765720000,\n    open: 51.11,\n    high: 51.13,\n    low: 51.11,\n    close: 51.125,\n    volume: 81520,\n  },\n  {\n    date: 1461765780000,\n    open: 51.125,\n    high: 51.14,\n    low: 51.115,\n    close: 51.135,\n    volume: 155634,\n  },\n  {\n    date: 1461765840000,\n    open: 51.135,\n    high: 51.14,\n    low: 51.13,\n    close: 51.14,\n    volume: 147597,\n  },\n  {\n    date: 1461765900000,\n    open: 51.135,\n    high: 51.14,\n    low: 51.11,\n    close: 51.135,\n    volume: 122213,\n  },\n  {\n    date: 1461765960000,\n    open: 51.13,\n    high: 51.14,\n    low: 51.12,\n    close: 51.125,\n    volume: 79935,\n  },\n  {\n    date: 1461766020000,\n    open: 51.125,\n    high: 51.13,\n    low: 51.1,\n    close: 51.1,\n    volume: 119890,\n  },\n  {\n    date: 1461766080000,\n    open: 51.1,\n    high: 51.11,\n    low: 51.08,\n    close: 51.09,\n    volume: 158341,\n  },\n  {\n    date: 1461766140000,\n    open: 51.09,\n    high: 51.11,\n    low: 51.09,\n    close: 51.1099,\n    volume: 53404,\n  },\n  {\n    date: 1461766200000,\n    open: 51.105,\n    high: 51.11,\n    low: 51.09,\n    close: 51.09,\n    volume: 93424,\n  },\n  {\n    date: 1461766260000,\n    open: 51.095,\n    high: 51.13,\n    low: 51.095,\n    close: 51.115,\n    volume: 95180,\n  },\n  {\n    date: 1461766320000,\n    open: 51.115,\n    high: 51.12,\n    low: 51.085,\n    close: 51.085,\n    volume: 40666,\n  },\n  {\n    date: 1461766380000,\n    open: 51.08,\n    high: 51.15,\n    low: 51.08,\n    close: 51.0964,\n    volume: 147959,\n  },\n  {\n    date: 1461766440000,\n    open: 51.1,\n    high: 51.1,\n    low: 51.03,\n    close: 51.043,\n    volume: 141433,\n  },\n  {\n    date: 1461766500000,\n    open: 51.05,\n    high: 51.08,\n    low: 51.04,\n    close: 51.06,\n    volume: 121861,\n  },\n  {\n    date: 1461766560000,\n    open: 51.05,\n    high: 51.06,\n    low: 51,\n    close: 51.005,\n    volume: 248215,\n  },\n  {\n    date: 1461766620000,\n    open: 51.005,\n    high: 51.01,\n    low: 50.9675,\n    close: 51,\n    volume: 330780,\n  },\n  {\n    date: 1461766680000,\n    open: 51,\n    high: 51.01,\n    low: 50.99,\n    close: 50.99,\n    volume: 124089,\n  },\n  {\n    date: 1461766740000,\n    open: 50.99,\n    high: 51,\n    low: 50.94,\n    close: 50.9735,\n    volume: 65285,\n  },\n  {\n    date: 1461766800000,\n    open: 50.975,\n    high: 50.975,\n    low: 50.92,\n    close: 50.9201,\n    volume: 92963,\n  },\n  {\n    date: 1461766860000,\n    open: 50.925,\n    high: 50.94,\n    low: 50.89,\n    close: 50.905,\n    volume: 132362,\n  },\n  {\n    date: 1461766920000,\n    open: 50.905,\n    high: 50.92,\n    low: 50.86,\n    close: 50.8601,\n    volume: 137104,\n  },\n  {\n    date: 1461766980000,\n    open: 50.87,\n    high: 50.9,\n    low: 50.865,\n    close: 50.87,\n    volume: 55850,\n  },\n  {\n    date: 1461767040000,\n    open: 50.87,\n    high: 50.945,\n    low: 50.87,\n    close: 50.9364,\n    volume: 58460,\n  },\n  {\n    date: 1461767100000,\n    open: 50.935,\n    high: 50.94,\n    low: 50.8835,\n    close: 50.9,\n    volume: 76176,\n  },\n  {\n    date: 1461767160000,\n    open: 50.895,\n    high: 50.9,\n    low: 50.86,\n    close: 50.87,\n    volume: 72037,\n  },\n  {\n    date: 1461767220000,\n    open: 50.87,\n    high: 50.875,\n    low: 50.81,\n    close: 50.83,\n    volume: 187158,\n  },\n  {\n    date: 1461767280000,\n    open: 50.84,\n    high: 50.845,\n    low: 50.77,\n    close: 50.795,\n    volume: 166608,\n  },\n  {\n    date: 1461767340000,\n    open: 50.795,\n    high: 50.805,\n    low: 50.78,\n    close: 50.795,\n    volume: 97773,\n  },\n  {\n    date: 1461767400000,\n    open: 50.795,\n    high: 50.805,\n    low: 50.72,\n    close: 50.7394,\n    volume: 360640,\n  },\n  {\n    date: 1461767460000,\n    open: 50.73,\n    high: 50.81,\n    low: 50.68,\n    close: 50.8001,\n    volume: 229563,\n  },\n  {\n    date: 1461767520000,\n    open: 50.805,\n    high: 50.89,\n    low: 50.8,\n    close: 50.865,\n    volume: 159664,\n  },\n  {\n    date: 1461767580000,\n    open: 50.865,\n    high: 50.9,\n    low: 50.86,\n    close: 50.88,\n    volume: 95535,\n  },\n  {\n    date: 1461767640000,\n    open: 50.88,\n    high: 50.935,\n    low: 50.88,\n    close: 50.915,\n    volume: 85221,\n  },\n  {\n    date: 1461767700000,\n    open: 50.915,\n    high: 50.95,\n    low: 50.895,\n    close: 50.92,\n    volume: 250412,\n  },\n  {\n    date: 1461767760000,\n    open: 50.915,\n    high: 50.96,\n    low: 50.911,\n    close: 50.92,\n    volume: 61927,\n  },\n  {\n    date: 1461767820000,\n    open: 50.925,\n    high: 50.93,\n    low: 50.88,\n    close: 50.89,\n    volume: 100097,\n  },\n  {\n    date: 1461767880000,\n    open: 50.9,\n    high: 50.9,\n    low: 50.84,\n    close: 50.85,\n    volume: 103058,\n  },\n  {\n    date: 1461767940000,\n    open: 50.85,\n    high: 50.86,\n    low: 50.78,\n    close: 50.8,\n    volume: 111618,\n  },\n  {\n    date: 1461768000000,\n    open: 50.795,\n    high: 50.81,\n    low: 50.76,\n    close: 50.8,\n    volume: 335634,\n  },\n  {\n    date: 1461768060000,\n    open: 50.81,\n    high: 50.835,\n    low: 50.75,\n    close: 50.7565,\n    volume: 121757,\n  },\n  {\n    date: 1461768120000,\n    open: 50.754,\n    high: 50.78,\n    low: 50.745,\n    close: 50.7601,\n    volume: 84462,\n  },\n  {\n    date: 1461768180000,\n    open: 50.765,\n    high: 50.78,\n    low: 50.71,\n    close: 50.71,\n    volume: 97206,\n  },\n  {\n    date: 1461768240000,\n    open: 50.71,\n    high: 50.72,\n    low: 50.7,\n    close: 50.7135,\n    volume: 65100,\n  },\n  {\n    date: 1461768300000,\n    open: 50.715,\n    high: 50.72,\n    low: 50.63,\n    close: 50.63,\n    volume: 240490,\n  },\n  {\n    date: 1461768360000,\n    open: 50.63,\n    high: 50.635,\n    low: 50.59,\n    close: 50.605,\n    volume: 227340,\n  },\n  {\n    date: 1461768420000,\n    open: 50.6,\n    high: 50.6283,\n    low: 50.57,\n    close: 50.6,\n    volume: 206653,\n  },\n  {\n    date: 1461768480000,\n    open: 50.59,\n    high: 50.6,\n    low: 50.55,\n    close: 50.595,\n    volume: 141892,\n  },\n  {\n    date: 1461768540000,\n    open: 50.595,\n    high: 50.68,\n    low: 50.59,\n    close: 50.67,\n    volume: 159688,\n  },\n  {\n    date: 1461768600000,\n    open: 50.675,\n    high: 50.7,\n    low: 50.66,\n    close: 50.6975,\n    volume: 70725,\n  },\n  {\n    date: 1461768660000,\n    open: 50.69,\n    high: 50.8,\n    low: 50.69,\n    close: 50.8,\n    volume: 149106,\n  },\n  {\n    date: 1461768720000,\n    open: 50.8,\n    high: 50.8,\n    low: 50.765,\n    close: 50.77,\n    volume: 87794,\n  },\n  {\n    date: 1461768780000,\n    open: 50.7732,\n    high: 50.79,\n    low: 50.76,\n    close: 50.77,\n    volume: 55952,\n  },\n  {\n    date: 1461768840000,\n    open: 50.78,\n    high: 50.78,\n    low: 50.77,\n    close: 50.78,\n    volume: 42947,\n  },\n  {\n    date: 1461768900000,\n    open: 50.78,\n    high: 50.8,\n    low: 50.77,\n    close: 50.795,\n    volume: 62669,\n  },\n  {\n    date: 1461768960000,\n    open: 50.795,\n    high: 50.8,\n    low: 50.75,\n    close: 50.76,\n    volume: 81524,\n  },\n  {\n    date: 1461769020000,\n    open: 50.76,\n    high: 50.8,\n    low: 50.71,\n    close: 50.8,\n    volume: 63531,\n  },\n  {\n    date: 1461769080000,\n    open: 50.7999,\n    high: 50.85,\n    low: 50.79,\n    close: 50.849,\n    volume: 81082,\n  },\n  {\n    date: 1461769140000,\n    open: 50.845,\n    high: 50.85,\n    low: 50.82,\n    close: 50.825,\n    volume: 51949,\n  },\n  {\n    date: 1461769200000,\n    open: 50.83,\n    high: 50.83,\n    low: 50.79,\n    close: 50.805,\n    volume: 77604,\n  },\n  {\n    date: 1461769260000,\n    open: 50.805,\n    high: 50.81,\n    low: 50.8,\n    close: 50.805,\n    volume: 122570,\n  },\n  {\n    date: 1461769320000,\n    open: 50.8,\n    high: 50.85,\n    low: 50.8,\n    close: 50.825,\n    volume: 190433,\n  },\n  {\n    date: 1461769380000,\n    open: 50.82,\n    high: 50.83,\n    low: 50.77,\n    close: 50.8,\n    volume: 84802,\n  },\n  {\n    date: 1461769440000,\n    open: 50.8,\n    high: 50.81,\n    low: 50.79,\n    close: 50.8,\n    volume: 46270,\n  },\n  {\n    date: 1461769500000,\n    open: 50.81,\n    high: 50.82,\n    low: 50.8,\n    close: 50.81,\n    volume: 61957,\n  },\n  {\n    date: 1461769560000,\n    open: 50.82,\n    high: 50.82,\n    low: 50.76,\n    close: 50.76,\n    volume: 67023,\n  },\n  {\n    date: 1461769620000,\n    open: 50.7699,\n    high: 50.7699,\n    low: 50.69,\n    close: 50.71,\n    volume: 65532,\n  },\n  {\n    date: 1461769680000,\n    open: 50.7099,\n    high: 50.77,\n    low: 50.703,\n    close: 50.7301,\n    volume: 84168,\n  },\n  {\n    date: 1461769740000,\n    open: 50.735,\n    high: 50.75,\n    low: 50.73,\n    close: 50.74,\n    volume: 35596,\n  },\n  {\n    date: 1461769800000,\n    open: 50.745,\n    high: 50.8,\n    low: 50.74,\n    close: 50.79,\n    volume: 44315,\n  },\n  {\n    date: 1461769860000,\n    open: 50.7862,\n    high: 50.795,\n    low: 50.75,\n    close: 50.79,\n    volume: 69130,\n  },\n  {\n    date: 1461769920000,\n    open: 50.79,\n    high: 50.79,\n    low: 50.735,\n    close: 50.74,\n    volume: 48482,\n  },\n  {\n    date: 1461769980000,\n    open: 50.74,\n    high: 50.77,\n    low: 50.73,\n    close: 50.765,\n    volume: 44033,\n  },\n  {\n    date: 1461770040000,\n    open: 50.765,\n    high: 50.82,\n    low: 50.7612,\n    close: 50.8,\n    volume: 174638,\n  },\n  {\n    date: 1461770100000,\n    open: 50.8,\n    high: 50.85,\n    low: 50.8,\n    close: 50.8443,\n    volume: 70777,\n  },\n  {\n    date: 1461770160000,\n    open: 50.84,\n    high: 50.9,\n    low: 50.83,\n    close: 50.9,\n    volume: 117921,\n  },\n  {\n    date: 1461770220000,\n    open: 50.9,\n    high: 50.95,\n    low: 50.87,\n    close: 50.94,\n    volume: 207318,\n  },\n  {\n    date: 1461770280000,\n    open: 50.9368,\n    high: 50.95,\n    low: 50.93,\n    close: 50.94,\n    volume: 113294,\n  },\n  {\n    date: 1461770340000,\n    open: 50.94,\n    high: 50.96,\n    low: 50.94,\n    close: 50.94,\n    volume: 100561,\n  },\n  {\n    date: 1461770400000,\n    open: 50.95,\n    high: 51.02,\n    low: 50.95,\n    close: 51.01,\n    volume: 86181,\n  },\n  {\n    date: 1461770460000,\n    open: 51.0101,\n    high: 51.035,\n    low: 50.99,\n    close: 51.03,\n    volume: 106090,\n  },\n  {\n    date: 1461770520000,\n    open: 51.03,\n    high: 51.03,\n    low: 50.97,\n    close: 50.975,\n    volume: 106256,\n  },\n  {\n    date: 1461770580000,\n    open: 50.975,\n    high: 50.98,\n    low: 50.94,\n    close: 50.959,\n    volume: 53640,\n  },\n  {\n    date: 1461770640000,\n    open: 50.95,\n    high: 50.97,\n    low: 50.9325,\n    close: 50.97,\n    volume: 64206,\n  },\n  {\n    date: 1461770700000,\n    open: 50.97,\n    high: 50.98,\n    low: 50.945,\n    close: 50.975,\n    volume: 50979,\n  },\n  {\n    date: 1461770760000,\n    open: 50.98,\n    high: 51.02,\n    low: 50.9762,\n    close: 51.005,\n    volume: 69892,\n  },\n  {\n    date: 1461770820000,\n    open: 51,\n    high: 51.03,\n    low: 51,\n    close: 51.015,\n    volume: 73670,\n  },\n  {\n    date: 1461770880000,\n    open: 51.0106,\n    high: 51.02,\n    low: 50.965,\n    close: 50.97,\n    volume: 66729,\n  },\n  {\n    date: 1461770940000,\n    open: 50.965,\n    high: 51,\n    low: 50.96,\n    close: 50.996,\n    volume: 19251,\n  },\n  {\n    date: 1461771000000,\n    open: 51,\n    high: 51,\n    low: 50.97,\n    close: 50.975,\n    volume: 70037,\n  },\n  {\n    date: 1461771060000,\n    open: 50.98,\n    high: 51,\n    low: 50.92,\n    close: 50.925,\n    volume: 83153,\n  },\n  {\n    date: 1461771120000,\n    open: 50.93,\n    high: 50.97,\n    low: 50.92,\n    close: 50.93,\n    volume: 112518,\n  },\n  {\n    date: 1461771180000,\n    open: 50.93,\n    high: 50.95,\n    low: 50.91,\n    close: 50.9271,\n    volume: 121520,\n  },\n  {\n    date: 1461771240000,\n    open: 50.92,\n    high: 50.95,\n    low: 50.92,\n    close: 50.935,\n    volume: 40624,\n  },\n  {\n    date: 1461771300000,\n    open: 50.9331,\n    high: 50.95,\n    low: 50.93,\n    close: 50.945,\n    volume: 79579,\n  },\n  {\n    date: 1461771360000,\n    open: 50.95,\n    high: 50.96,\n    low: 50.94,\n    close: 50.945,\n    volume: 102436,\n  },\n  {\n    date: 1461771420000,\n    open: 50.945,\n    high: 50.96,\n    low: 50.94,\n    close: 50.96,\n    volume: 75844,\n  },\n  {\n    date: 1461771480000,\n    open: 50.96,\n    high: 50.98,\n    low: 50.96,\n    close: 50.965,\n    volume: 45382,\n  },\n  {\n    date: 1461771540000,\n    open: 50.965,\n    high: 50.97,\n    low: 50.95,\n    close: 50.955,\n    volume: 46659,\n  },\n  {\n    date: 1461771600000,\n    open: 50.95,\n    high: 50.97,\n    low: 50.95,\n    close: 50.965,\n    volume: 29628,\n  },\n  {\n    date: 1461771660000,\n    open: 50.965,\n    high: 50.99,\n    low: 50.965,\n    close: 50.99,\n    volume: 77939,\n  },\n  {\n    date: 1461771720000,\n    open: 50.99,\n    high: 51.005,\n    low: 50.9875,\n    close: 50.99,\n    volume: 125279,\n  },\n  {\n    date: 1461771780000,\n    open: 50.99,\n    high: 51,\n    low: 50.96,\n    close: 50.964,\n    volume: 85029,\n  },\n  {\n    date: 1461771840000,\n    open: 50.97,\n    high: 50.975,\n    low: 50.95,\n    close: 50.95,\n    volume: 35890,\n  },\n  {\n    date: 1461771900000,\n    open: 50.95,\n    high: 50.97,\n    low: 50.94,\n    close: 50.965,\n    volume: 47369,\n  },\n  {\n    date: 1461771960000,\n    open: 50.965,\n    high: 50.99,\n    low: 50.95,\n    close: 50.98,\n    volume: 56498,\n  },\n  {\n    date: 1461772020000,\n    open: 50.99,\n    high: 50.99,\n    low: 50.92,\n    close: 50.925,\n    volume: 82509,\n  },\n  {\n    date: 1461772080000,\n    open: 50.92,\n    high: 50.927,\n    low: 50.89,\n    close: 50.9,\n    volume: 52985,\n  },\n  {\n    date: 1461772140000,\n    open: 50.895,\n    high: 50.91,\n    low: 50.89,\n    close: 50.91,\n    volume: 28256,\n  },\n  {\n    date: 1461772200000,\n    open: 50.91,\n    high: 50.93,\n    low: 50.9,\n    close: 50.92,\n    volume: 31408,\n  },\n  {\n    date: 1461772260000,\n    open: 50.925,\n    high: 50.93,\n    low: 50.92,\n    close: 50.92,\n    volume: 35231,\n  },\n  {\n    date: 1461772320000,\n    open: 50.92,\n    high: 50.97,\n    low: 50.92,\n    close: 50.965,\n    volume: 53208,\n  },\n  {\n    date: 1461772380000,\n    open: 50.97,\n    high: 50.99,\n    low: 50.97,\n    close: 50.985,\n    volume: 38707,\n  },\n  {\n    date: 1461772440000,\n    open: 50.99,\n    high: 51,\n    low: 50.98,\n    close: 50.9899,\n    volume: 70663,\n  },\n  {\n    date: 1461772500000,\n    open: 50.98,\n    high: 50.99,\n    low: 50.95,\n    close: 50.955,\n    volume: 43151,\n  },\n  {\n    date: 1461772560000,\n    open: 50.95,\n    high: 50.97,\n    low: 50.95,\n    close: 50.96,\n    volume: 41211,\n  },\n  {\n    date: 1461772620000,\n    open: 50.9699,\n    high: 50.975,\n    low: 50.95,\n    close: 50.97,\n    volume: 91224,\n  },\n  {\n    date: 1461772680000,\n    open: 50.9615,\n    high: 50.9699,\n    low: 50.95,\n    close: 50.955,\n    volume: 32623,\n  },\n  {\n    date: 1461772740000,\n    open: 50.955,\n    high: 50.97,\n    low: 50.95,\n    close: 50.97,\n    volume: 42395,\n  },\n  {\n    date: 1461772800000,\n    open: 50.97,\n    high: 50.97,\n    low: 50.96,\n    close: 50.97,\n    volume: 64555,\n  },\n  {\n    date: 1461772860000,\n    open: 50.96,\n    high: 50.97,\n    low: 50.95,\n    close: 50.96,\n    volume: 73075,\n  },\n  {\n    date: 1461772920000,\n    open: 50.9599,\n    high: 50.96,\n    low: 50.92,\n    close: 50.93,\n    volume: 67430,\n  },\n  {\n    date: 1461772980000,\n    open: 50.93,\n    high: 50.94,\n    low: 50.9,\n    close: 50.9,\n    volume: 129244,\n  },\n  {\n    date: 1461773040000,\n    open: 50.9,\n    high: 50.91,\n    low: 50.9,\n    close: 50.9,\n    volume: 14770,\n  },\n  {\n    date: 1461773100000,\n    open: 50.9,\n    high: 50.91,\n    low: 50.9,\n    close: 50.9,\n    volume: 43930,\n  },\n  {\n    date: 1461773160000,\n    open: 50.905,\n    high: 50.9099,\n    low: 50.85,\n    close: 50.85,\n    volume: 57613,\n  },\n  {\n    date: 1461773220000,\n    open: 50.85,\n    high: 50.86,\n    low: 50.83,\n    close: 50.835,\n    volume: 53671,\n  },\n  {\n    date: 1461773280000,\n    open: 50.83,\n    high: 50.84,\n    low: 50.8,\n    close: 50.8,\n    volume: 69494,\n  },\n  {\n    date: 1461773340000,\n    open: 50.8065,\n    high: 50.81,\n    low: 50.76,\n    close: 50.77,\n    volume: 110882,\n  },\n  {\n    date: 1461773400000,\n    open: 50.775,\n    high: 50.78,\n    low: 50.77,\n    close: 50.771,\n    volume: 41524,\n  },\n  {\n    date: 1461773460000,\n    open: 50.77,\n    high: 50.795,\n    low: 50.75,\n    close: 50.755,\n    volume: 84627,\n  },\n  {\n    date: 1461773520000,\n    open: 50.7599,\n    high: 50.78,\n    low: 50.75,\n    close: 50.76,\n    volume: 60314,\n  },\n  {\n    date: 1461773580000,\n    open: 50.77,\n    high: 50.775,\n    low: 50.75,\n    close: 50.765,\n    volume: 58247,\n  },\n  {\n    date: 1461773640000,\n    open: 50.7635,\n    high: 50.77,\n    low: 50.75,\n    close: 50.75,\n    volume: 74728,\n  },\n  {\n    date: 1461773700000,\n    open: 50.75,\n    high: 50.76,\n    low: 50.71,\n    close: 50.72,\n    volume: 114091,\n  },\n  {\n    date: 1461773760000,\n    open: 50.72,\n    high: 50.73,\n    low: 50.71,\n    close: 50.71,\n    volume: 34304,\n  },\n  {\n    date: 1461773820000,\n    open: 50.715,\n    high: 50.73,\n    low: 50.71,\n    close: 50.715,\n    volume: 58197,\n  },\n  {\n    date: 1461773880000,\n    open: 50.7101,\n    high: 50.72,\n    low: 50.7,\n    close: 50.715,\n    volume: 53987,\n  },\n  {\n    date: 1461773940000,\n    open: 50.715,\n    high: 50.77,\n    low: 50.7,\n    close: 50.7635,\n    volume: 72733,\n  },\n  {\n    date: 1461774000000,\n    open: 50.765,\n    high: 50.77,\n    low: 50.76,\n    close: 50.77,\n    volume: 12431,\n  },\n  {\n    date: 1461774060000,\n    open: 50.77,\n    high: 50.815,\n    low: 50.76,\n    close: 50.79,\n    volume: 134679,\n  },\n  {\n    date: 1461774120000,\n    open: 50.79,\n    high: 50.86,\n    low: 50.785,\n    close: 50.8485,\n    volume: 98992,\n  },\n  {\n    date: 1461774180000,\n    open: 50.84,\n    high: 50.91,\n    low: 50.83,\n    close: 50.89,\n    volume: 69143,\n  },\n  {\n    date: 1461774240000,\n    open: 50.89,\n    high: 50.8999,\n    low: 50.86,\n    close: 50.875,\n    volume: 33263,\n  },\n  {\n    date: 1461774300000,\n    open: 50.875,\n    high: 50.88,\n    low: 50.87,\n    close: 50.8743,\n    volume: 44584,\n  },\n  {\n    date: 1461774360000,\n    open: 50.88,\n    high: 50.88,\n    low: 50.87,\n    close: 50.8764,\n    volume: 31907,\n  },\n  {\n    date: 1461774420000,\n    open: 50.87,\n    high: 50.88,\n    low: 50.87,\n    close: 50.875,\n    volume: 20350,\n  },\n  {\n    date: 1461774480000,\n    open: 50.88,\n    high: 50.94,\n    low: 50.875,\n    close: 50.935,\n    volume: 79990,\n  },\n  {\n    date: 1461774540000,\n    open: 50.935,\n    high: 50.94,\n    low: 50.925,\n    close: 50.93,\n    volume: 49628,\n  },\n  {\n    date: 1461774600000,\n    open: 50.93,\n    high: 50.95,\n    low: 50.93,\n    close: 50.935,\n    volume: 54678,\n  },\n  {\n    date: 1461774660000,\n    open: 50.935,\n    high: 50.95,\n    low: 50.93,\n    close: 50.945,\n    volume: 64743,\n  },\n  {\n    date: 1461774720000,\n    open: 50.95,\n    high: 50.955,\n    low: 50.93,\n    close: 50.9536,\n    volume: 95624,\n  },\n  {\n    date: 1461774780000,\n    open: 50.955,\n    high: 50.96,\n    low: 50.93,\n    close: 50.935,\n    volume: 90701,\n  },\n  {\n    date: 1461774840000,\n    open: 50.93,\n    high: 50.9399,\n    low: 50.9,\n    close: 50.9,\n    volume: 52529,\n  },\n  {\n    date: 1461774900000,\n    open: 50.905,\n    high: 50.91,\n    low: 50.9,\n    close: 50.905,\n    volume: 19098,\n  },\n  {\n    date: 1461774960000,\n    open: 50.905,\n    high: 50.91,\n    low: 50.9,\n    close: 50.9,\n    volume: 27275,\n  },\n  {\n    date: 1461775020000,\n    open: 50.9,\n    high: 50.91,\n    low: 50.9,\n    close: 50.9,\n    volume: 34795,\n  },\n  {\n    date: 1461775080000,\n    open: 50.9,\n    high: 50.905,\n    low: 50.86,\n    close: 50.86,\n    volume: 73572,\n  },\n  {\n    date: 1461775140000,\n    open: 50.865,\n    high: 50.87,\n    low: 50.84,\n    close: 50.865,\n    volume: 71864,\n  },\n  {\n    date: 1461775200000,\n    open: 50.865,\n    high: 50.9,\n    low: 50.8625,\n    close: 50.87,\n    volume: 127532,\n  },\n  {\n    date: 1461775260000,\n    open: 50.875,\n    high: 50.88,\n    low: 50.86,\n    close: 50.87,\n    volume: 44333,\n  },\n  {\n    date: 1461775320000,\n    open: 50.87,\n    high: 50.88,\n    low: 50.85,\n    close: 50.865,\n    volume: 101278,\n  },\n  {\n    date: 1461775380000,\n    open: 50.86,\n    high: 50.87,\n    low: 50.83,\n    close: 50.83,\n    volume: 51251,\n  },\n  {\n    date: 1461775440000,\n    open: 50.83,\n    high: 50.84,\n    low: 50.79,\n    close: 50.8,\n    volume: 77830,\n  },\n  {\n    date: 1461775500000,\n    open: 50.795,\n    high: 50.83,\n    low: 50.79,\n    close: 50.815,\n    volume: 66549,\n  },\n  {\n    date: 1461775560000,\n    open: 50.815,\n    high: 50.84,\n    low: 50.815,\n    close: 50.8357,\n    volume: 42949,\n  },\n  {\n    date: 1461775620000,\n    open: 50.83,\n    high: 50.85,\n    low: 50.83,\n    close: 50.83,\n    volume: 32531,\n  },\n  {\n    date: 1461775680000,\n    open: 50.84,\n    high: 50.84,\n    low: 50.83,\n    close: 50.835,\n    volume: 8218,\n  },\n  {\n    date: 1461775740000,\n    open: 50.835,\n    high: 50.87,\n    low: 50.83,\n    close: 50.865,\n    volume: 42559,\n  },\n  {\n    date: 1461775800000,\n    open: 50.868,\n    high: 50.9,\n    low: 50.86,\n    close: 50.8901,\n    volume: 56942,\n  },\n  {\n    date: 1461775860000,\n    open: 50.9,\n    high: 50.91,\n    low: 50.86,\n    close: 50.865,\n    volume: 86074,\n  },\n  {\n    date: 1461775920000,\n    open: 50.865,\n    high: 50.94,\n    low: 50.865,\n    close: 50.93,\n    volume: 49193,\n  },\n  {\n    date: 1461775980000,\n    open: 50.9368,\n    high: 50.94,\n    low: 50.9,\n    close: 50.9072,\n    volume: 35140,\n  },\n  {\n    date: 1461776040000,\n    open: 50.9035,\n    high: 50.92,\n    low: 50.9,\n    close: 50.915,\n    volume: 20236,\n  },\n  {\n    date: 1461776100000,\n    open: 50.91,\n    high: 50.93,\n    low: 50.9,\n    close: 50.905,\n    volume: 27764,\n  },\n  {\n    date: 1461776160000,\n    open: 50.905,\n    high: 50.91,\n    low: 50.9,\n    close: 50.91,\n    volume: 14914,\n  },\n  {\n    date: 1461776220000,\n    open: 50.91,\n    high: 50.91,\n    low: 50.88,\n    close: 50.88,\n    volume: 18695,\n  },\n  {\n    date: 1461776280000,\n    open: 50.885,\n    high: 50.8862,\n    low: 50.87,\n    close: 50.87,\n    volume: 17452,\n  },\n  {\n    date: 1461776340000,\n    open: 50.87,\n    high: 50.88,\n    low: 50.87,\n    close: 50.875,\n    volume: 9819,\n  },\n  {\n    date: 1461776400000,\n    open: 50.88,\n    high: 50.88,\n    low: 50.87,\n    close: 50.87,\n    volume: 27100,\n  },\n  {\n    date: 1461776460000,\n    open: 50.875,\n    high: 50.88,\n    low: 50.86,\n    close: 50.865,\n    volume: 28316,\n  },\n  {\n    date: 1461776520000,\n    open: 50.8657,\n    high: 50.9,\n    low: 50.86,\n    close: 50.8775,\n    volume: 76273,\n  },\n  {\n    date: 1461776580000,\n    open: 50.875,\n    high: 50.88,\n    low: 50.855,\n    close: 50.86,\n    volume: 34953,\n  },\n  {\n    date: 1461776640000,\n    open: 50.86,\n    high: 50.88,\n    low: 50.86,\n    close: 50.88,\n    volume: 27751,\n  },\n  {\n    date: 1461776700000,\n    open: 50.87,\n    high: 50.875,\n    low: 50.83,\n    close: 50.83,\n    volume: 84008,\n  },\n  {\n    date: 1461776760000,\n    open: 50.835,\n    high: 50.84,\n    low: 50.8,\n    close: 50.805,\n    volume: 46987,\n  },\n  {\n    date: 1461776820000,\n    open: 50.8,\n    high: 50.81,\n    low: 50.75,\n    close: 50.76,\n    volume: 118821,\n  },\n  {\n    date: 1461776880000,\n    open: 50.755,\n    high: 50.76,\n    low: 50.7,\n    close: 50.705,\n    volume: 99961,\n  },\n  {\n    date: 1461776940000,\n    open: 50.705,\n    high: 50.71,\n    low: 50.675,\n    close: 50.675,\n    volume: 87407,\n  },\n  {\n    date: 1461777000000,\n    open: 50.67,\n    high: 50.68,\n    low: 50.65,\n    close: 50.655,\n    volume: 124052,\n  },\n  {\n    date: 1461777060000,\n    open: 50.655,\n    high: 50.66,\n    low: 50.63,\n    close: 50.63,\n    volume: 61899,\n  },\n  {\n    date: 1461777120000,\n    open: 50.64,\n    high: 50.66,\n    low: 50.63,\n    close: 50.635,\n    volume: 100374,\n  },\n  {\n    date: 1461777180000,\n    open: 50.6399,\n    high: 50.66,\n    low: 50.6,\n    close: 50.605,\n    volume: 141517,\n  },\n  {\n    date: 1461777240000,\n    open: 50.625,\n    high: 50.65,\n    low: 50.6,\n    close: 50.6436,\n    volume: 72905,\n  },\n  {\n    date: 1461777300000,\n    open: 50.65,\n    high: 50.72,\n    low: 50.65,\n    close: 50.6929,\n    volume: 58447,\n  },\n  {\n    date: 1461777360000,\n    open: 50.7,\n    high: 50.765,\n    low: 50.69,\n    close: 50.7474,\n    volume: 63631,\n  },\n  {\n    date: 1461777420000,\n    open: 50.7464,\n    high: 50.815,\n    low: 50.745,\n    close: 50.78,\n    volume: 62401,\n  },\n  {\n    date: 1461777480000,\n    open: 50.78,\n    high: 50.81,\n    low: 50.78,\n    close: 50.8,\n    volume: 26447,\n  },\n  {\n    date: 1461777540000,\n    open: 50.8036,\n    high: 50.81,\n    low: 50.78,\n    close: 50.785,\n    volume: 38046,\n  },\n  {\n    date: 1461777600000,\n    open: 50.79,\n    high: 50.81,\n    low: 50.78,\n    close: 50.79,\n    volume: 21311,\n  },\n  {\n    date: 1461777660000,\n    open: 50.78,\n    high: 50.79,\n    low: 50.7299,\n    close: 50.7299,\n    volume: 57337,\n  },\n  {\n    date: 1461777720000,\n    open: 50.73,\n    high: 50.77,\n    low: 50.725,\n    close: 50.75,\n    volume: 43249,\n  },\n  {\n    date: 1461777780000,\n    open: 50.755,\n    high: 50.76,\n    low: 50.75,\n    close: 50.755,\n    volume: 20207,\n  },\n  {\n    date: 1461777840000,\n    open: 50.7571,\n    high: 50.76,\n    low: 50.67,\n    close: 50.675,\n    volume: 117805,\n  },\n  {\n    date: 1461777900000,\n    open: 50.675,\n    high: 50.69,\n    low: 50.61,\n    close: 50.625,\n    volume: 114960,\n  },\n  {\n    date: 1461777960000,\n    open: 50.63,\n    high: 50.65,\n    low: 50.58,\n    close: 50.6005,\n    volume: 179335,\n  },\n  {\n    date: 1461778020000,\n    open: 50.6,\n    high: 50.625,\n    low: 50.6,\n    close: 50.62,\n    volume: 40380,\n  },\n  {\n    date: 1461778080000,\n    open: 50.62,\n    high: 50.6568,\n    low: 50.61,\n    close: 50.656,\n    volume: 74011,\n  },\n  {\n    date: 1461778140000,\n    open: 50.655,\n    high: 50.67,\n    low: 50.635,\n    close: 50.66,\n    volume: 63654,\n  },\n  {\n    date: 1461778200000,\n    open: 50.66,\n    high: 50.67,\n    low: 50.64,\n    close: 50.65,\n    volume: 41004,\n  },\n  {\n    date: 1461778260000,\n    open: 50.64,\n    high: 50.6799,\n    low: 50.64,\n    close: 50.6735,\n    volume: 37144,\n  },\n  {\n    date: 1461778320000,\n    open: 50.6742,\n    high: 50.7199,\n    low: 50.67,\n    close: 50.717,\n    volume: 53140,\n  },\n  {\n    date: 1461778380000,\n    open: 50.715,\n    high: 50.79,\n    low: 50.715,\n    close: 50.7671,\n    volume: 58191,\n  },\n  {\n    date: 1461778440000,\n    open: 50.765,\n    high: 50.77,\n    low: 50.76,\n    close: 50.77,\n    volume: 26237,\n  },\n  {\n    date: 1461778500000,\n    open: 50.77,\n    high: 50.8,\n    low: 50.76,\n    close: 50.8,\n    volume: 38410,\n  },\n  {\n    date: 1461778560000,\n    open: 50.79,\n    high: 50.82,\n    low: 50.79,\n    close: 50.79,\n    volume: 59465,\n  },\n  {\n    date: 1461778620000,\n    open: 50.79,\n    high: 50.79,\n    low: 50.76,\n    close: 50.76,\n    volume: 37252,\n  },\n  {\n    date: 1461778680000,\n    open: 50.765,\n    high: 50.77,\n    low: 50.75,\n    close: 50.75,\n    volume: 30447,\n  },\n  {\n    date: 1461778740000,\n    open: 50.75,\n    high: 50.7501,\n    low: 50.6536,\n    close: 50.6536,\n    volume: 91849,\n  },\n  {\n    date: 1461778800000,\n    open: 50.6533,\n    high: 50.68,\n    low: 50.65,\n    close: 50.678,\n    volume: 82383,\n  },\n  {\n    date: 1461778860000,\n    open: 50.675,\n    high: 50.72,\n    low: 50.675,\n    close: 50.715,\n    volume: 85996,\n  },\n  {\n    date: 1461778920000,\n    open: 50.685,\n    high: 50.72,\n    low: 50.67,\n    close: 50.67,\n    volume: 70375,\n  },\n  {\n    date: 1461778980000,\n    open: 50.67,\n    high: 50.69,\n    low: 50.66,\n    close: 50.68,\n    volume: 65430,\n  },\n  {\n    date: 1461779040000,\n    open: 50.68,\n    high: 50.73,\n    low: 50.68,\n    close: 50.705,\n    volume: 65061,\n  },\n  {\n    date: 1461779100000,\n    open: 50.7005,\n    high: 50.74,\n    low: 50.69,\n    close: 50.735,\n    volume: 73471,\n  },\n  {\n    date: 1461779160000,\n    open: 50.735,\n    high: 50.795,\n    low: 50.73,\n    close: 50.7854,\n    volume: 38338,\n  },\n  {\n    date: 1461779220000,\n    open: 50.787,\n    high: 50.79,\n    low: 50.78,\n    close: 50.7895,\n    volume: 27699,\n  },\n  {\n    date: 1461779280000,\n    open: 50.79,\n    high: 50.82,\n    low: 50.785,\n    close: 50.81,\n    volume: 49879,\n  },\n  {\n    date: 1461779340000,\n    open: 50.81,\n    high: 50.85,\n    low: 50.79,\n    close: 50.79,\n    volume: 132081,\n  },\n  {\n    date: 1461779400000,\n    open: 50.7999,\n    high: 50.8,\n    low: 50.79,\n    close: 50.795,\n    volume: 22727,\n  },\n  {\n    date: 1461779460000,\n    open: 50.795,\n    high: 50.84,\n    low: 50.795,\n    close: 50.84,\n    volume: 37461,\n  },\n  {\n    date: 1461779520000,\n    open: 50.84,\n    high: 50.84,\n    low: 50.795,\n    close: 50.795,\n    volume: 43102,\n  },\n  {\n    date: 1461779580000,\n    open: 50.8,\n    high: 50.84,\n    low: 50.79,\n    close: 50.83,\n    volume: 31247,\n  },\n  {\n    date: 1461779640000,\n    open: 50.825,\n    high: 50.8299,\n    low: 50.79,\n    close: 50.79,\n    volume: 24541,\n  },\n  {\n    date: 1461779700000,\n    open: 50.797,\n    high: 50.81,\n    low: 50.79,\n    close: 50.79,\n    volume: 52201,\n  },\n  {\n    date: 1461779760000,\n    open: 50.795,\n    high: 50.7973,\n    low: 50.69,\n    close: 50.69,\n    volume: 145926,\n  },\n  {\n    date: 1461779820000,\n    open: 50.69,\n    high: 50.7664,\n    low: 50.68,\n    close: 50.75,\n    volume: 63659,\n  },\n  {\n    date: 1461779880000,\n    open: 50.76,\n    high: 50.77,\n    low: 50.74,\n    close: 50.77,\n    volume: 34851,\n  },\n  {\n    date: 1461779940000,\n    open: 50.7685,\n    high: 50.7685,\n    low: 50.72,\n    close: 50.73,\n    volume: 47459,\n  },\n  {\n    date: 1461780000000,\n    open: 50.735,\n    high: 50.7399,\n    low: 50.69,\n    close: 50.7,\n    volume: 49672,\n  },\n  {\n    date: 1461780060000,\n    open: 50.715,\n    high: 50.72,\n    low: 50.57,\n    close: 50.62,\n    volume: 285998,\n  },\n  {\n    date: 1461780120000,\n    open: 50.62,\n    high: 50.68,\n    low: 50.56,\n    close: 50.59,\n    volume: 135379,\n  },\n  {\n    date: 1461780180000,\n    open: 50.585,\n    high: 50.71,\n    low: 50.58,\n    close: 50.675,\n    volume: 114775,\n  },\n  {\n    date: 1461780240000,\n    open: 50.67,\n    high: 50.71,\n    low: 50.61,\n    close: 50.655,\n    volume: 119150,\n  },\n  {\n    date: 1461780300000,\n    open: 50.66,\n    high: 50.67,\n    low: 50.62,\n    close: 50.624,\n    volume: 101793,\n  },\n  {\n    date: 1461780360000,\n    open: 50.625,\n    high: 50.77,\n    low: 50.624,\n    close: 50.75,\n    volume: 124699,\n  },\n  {\n    date: 1461780420000,\n    open: 50.755,\n    high: 50.88,\n    low: 50.745,\n    close: 50.85,\n    volume: 135859,\n  },\n  {\n    date: 1461780480000,\n    open: 50.845,\n    high: 50.845,\n    low: 50.755,\n    close: 50.77,\n    volume: 88519,\n  },\n  {\n    date: 1461780540000,\n    open: 50.78,\n    high: 50.86,\n    low: 50.765,\n    close: 50.8,\n    volume: 76028,\n  },\n  {\n    date: 1461780600000,\n    open: 50.81,\n    high: 50.915,\n    low: 50.79,\n    close: 50.88,\n    volume: 114079,\n  },\n  {\n    date: 1461780660000,\n    open: 50.88,\n    high: 50.93,\n    low: 50.87,\n    close: 50.93,\n    volume: 112280,\n  },\n  {\n    date: 1461780720000,\n    open: 50.94,\n    high: 50.94,\n    low: 50.875,\n    close: 50.885,\n    volume: 117062,\n  },\n  {\n    date: 1461780780000,\n    open: 50.883,\n    high: 50.8889,\n    low: 50.825,\n    close: 50.85,\n    volume: 135760,\n  },\n  {\n    date: 1461780840000,\n    open: 50.85,\n    high: 50.855,\n    low: 50.84,\n    close: 50.84,\n    volume: 130763,\n  },\n  {\n    date: 1461780900000,\n    open: 50.8441,\n    high: 50.85,\n    low: 50.795,\n    close: 50.8,\n    volume: 63984,\n  },\n  {\n    date: 1461780960000,\n    open: 50.8,\n    high: 50.85,\n    low: 50.8,\n    close: 50.84,\n    volume: 108273,\n  },\n  {\n    date: 1461781020000,\n    open: 50.84,\n    high: 50.855,\n    low: 50.83,\n    close: 50.845,\n    volume: 63145,\n  },\n  {\n    date: 1461781080000,\n    open: 50.845,\n    high: 50.85,\n    low: 50.8,\n    close: 50.805,\n    volume: 76710,\n  },\n  {\n    date: 1461781140000,\n    open: 50.8,\n    high: 50.8091,\n    low: 50.75,\n    close: 50.795,\n    volume: 100822,\n  },\n  {\n    date: 1461781200000,\n    open: 50.8,\n    high: 50.85,\n    low: 50.7928,\n    close: 50.84,\n    volume: 84854,\n  },\n  {\n    date: 1461781260000,\n    open: 50.83,\n    high: 50.857,\n    low: 50.8,\n    close: 50.857,\n    volume: 81170,\n  },\n  {\n    date: 1461781320000,\n    open: 50.85,\n    high: 50.895,\n    low: 50.835,\n    close: 50.89,\n    volume: 47241,\n  },\n  {\n    date: 1461781380000,\n    open: 50.9,\n    high: 50.915,\n    low: 50.88,\n    close: 50.8805,\n    volume: 49329,\n  },\n  {\n    date: 1461781440000,\n    open: 50.885,\n    high: 50.89,\n    low: 50.85,\n    close: 50.8535,\n    volume: 45068,\n  },\n  {\n    date: 1461781500000,\n    open: 50.855,\n    high: 50.86,\n    low: 50.79,\n    close: 50.82,\n    volume: 73672,\n  },\n  {\n    date: 1461781560000,\n    open: 50.82,\n    high: 50.82,\n    low: 50.7699,\n    close: 50.78,\n    volume: 132131,\n  },\n  {\n    date: 1461781620000,\n    open: 50.78,\n    high: 50.82,\n    low: 50.765,\n    close: 50.81,\n    volume: 124629,\n  },\n  {\n    date: 1461781680000,\n    open: 50.81,\n    high: 50.85,\n    low: 50.8,\n    close: 50.81,\n    volume: 53304,\n  },\n  {\n    date: 1461781740000,\n    open: 50.81,\n    high: 50.83,\n    low: 50.78,\n    close: 50.7996,\n    volume: 114490,\n  },\n  {\n    date: 1461781800000,\n    open: 50.8,\n    high: 50.8,\n    low: 50.76,\n    close: 50.78,\n    volume: 55205,\n  },\n  {\n    date: 1461781860000,\n    open: 50.78,\n    high: 50.785,\n    low: 50.75,\n    close: 50.76,\n    volume: 43172,\n  },\n  {\n    date: 1461781920000,\n    open: 50.755,\n    high: 50.78,\n    low: 50.7515,\n    close: 50.765,\n    volume: 78118,\n  },\n  {\n    date: 1461781980000,\n    open: 50.77,\n    high: 50.785,\n    low: 50.7,\n    close: 50.7099,\n    volume: 82209,\n  },\n  {\n    date: 1461782040000,\n    open: 50.7,\n    high: 50.7,\n    low: 50.66,\n    close: 50.665,\n    volume: 88480,\n  },\n  {\n    date: 1461782100000,\n    open: 50.6699,\n    high: 50.675,\n    low: 50.655,\n    close: 50.66,\n    volume: 129808,\n  },\n  {\n    date: 1461782160000,\n    open: 50.6699,\n    high: 50.77,\n    low: 50.6641,\n    close: 50.755,\n    volume: 97495,\n  },\n  {\n    date: 1461782220000,\n    open: 50.755,\n    high: 50.76,\n    low: 50.7201,\n    close: 50.735,\n    volume: 37889,\n  },\n  {\n    date: 1461782280000,\n    open: 50.7372,\n    high: 50.7372,\n    low: 50.66,\n    close: 50.675,\n    volume: 103436,\n  },\n  {\n    date: 1461782340000,\n    open: 50.675,\n    high: 50.69,\n    low: 50.655,\n    close: 50.675,\n    volume: 62047,\n  },\n  {\n    date: 1461782400000,\n    open: 50.68,\n    high: 50.68,\n    low: 50.66,\n    close: 50.665,\n    volume: 32867,\n  },\n  {\n    date: 1461782460000,\n    open: 50.67,\n    high: 50.67,\n    low: 50.63,\n    close: 50.635,\n    volume: 176298,\n  },\n  {\n    date: 1461782520000,\n    open: 50.633,\n    high: 50.74,\n    low: 50.633,\n    close: 50.7,\n    volume: 117781,\n  },\n  {\n    date: 1461782580000,\n    open: 50.709,\n    high: 50.72,\n    low: 50.695,\n    close: 50.715,\n    volume: 51976,\n  },\n  {\n    date: 1461782640000,\n    open: 50.71,\n    high: 50.715,\n    low: 50.6801,\n    close: 50.6801,\n    volume: 108922,\n  },\n  {\n    date: 1461782700000,\n    open: 50.69,\n    high: 50.69,\n    low: 50.62,\n    close: 50.62,\n    volume: 63032,\n  },\n  {\n    date: 1461782760000,\n    open: 50.625,\n    high: 50.69,\n    low: 50.62,\n    close: 50.69,\n    volume: 79602,\n  },\n  {\n    date: 1461782820000,\n    open: 50.685,\n    high: 50.695,\n    low: 50.645,\n    close: 50.655,\n    volume: 63334,\n  },\n  {\n    date: 1461782880000,\n    open: 50.655,\n    high: 50.67,\n    low: 50.635,\n    close: 50.64,\n    volume: 46696,\n  },\n  {\n    date: 1461782940000,\n    open: 50.635,\n    high: 50.66,\n    low: 50.63,\n    close: 50.655,\n    volume: 49225,\n  },\n  {\n    date: 1461783000000,\n    open: 50.65,\n    high: 50.7,\n    low: 50.65,\n    close: 50.685,\n    volume: 63520,\n  },\n  {\n    date: 1461783060000,\n    open: 50.685,\n    high: 50.69,\n    low: 50.65,\n    close: 50.68,\n    volume: 45141,\n  },\n  {\n    date: 1461783120000,\n    open: 50.68,\n    high: 50.71,\n    low: 50.67,\n    close: 50.705,\n    volume: 122417,\n  },\n  {\n    date: 1461783180000,\n    open: 50.7,\n    high: 50.72,\n    low: 50.7,\n    close: 50.71,\n    volume: 68193,\n  },\n  {\n    date: 1461783240000,\n    open: 50.705,\n    high: 50.72,\n    low: 50.705,\n    close: 50.715,\n    volume: 68263,\n  },\n  {\n    date: 1461783300000,\n    open: 50.71,\n    high: 50.73,\n    low: 50.71,\n    close: 50.72,\n    volume: 108212,\n  },\n  {\n    date: 1461783360000,\n    open: 50.725,\n    high: 50.76,\n    low: 50.71,\n    close: 50.7135,\n    volume: 223520,\n  },\n  {\n    date: 1461783420000,\n    open: 50.715,\n    high: 50.72,\n    low: 50.66,\n    close: 50.665,\n    volume: 50852,\n  },\n  {\n    date: 1461783480000,\n    open: 50.665,\n    high: 50.685,\n    low: 50.66,\n    close: 50.68,\n    volume: 77107,\n  },\n  {\n    date: 1461783540000,\n    open: 50.68,\n    high: 50.69,\n    low: 50.675,\n    close: 50.68,\n    volume: 50399,\n  },\n  {\n    date: 1461783600000,\n    open: 50.68,\n    high: 50.72,\n    low: 50.68,\n    close: 50.7,\n    volume: 113561,\n  },\n  {\n    date: 1461783660000,\n    open: 50.705,\n    high: 50.71,\n    low: 50.67,\n    close: 50.68,\n    volume: 79230,\n  },\n  {\n    date: 1461783720000,\n    open: 50.685,\n    high: 50.765,\n    low: 50.665,\n    close: 50.75,\n    volume: 187177,\n  },\n  {\n    date: 1461783780000,\n    open: 50.755,\n    high: 50.79,\n    low: 50.75,\n    close: 50.785,\n    volume: 97318,\n  },\n  {\n    date: 1461783840000,\n    open: 50.79,\n    high: 50.8,\n    low: 50.7736,\n    close: 50.8,\n    volume: 137905,\n  },\n  {\n    date: 1461783900000,\n    open: 50.8,\n    high: 50.805,\n    low: 50.77,\n    close: 50.79,\n    volume: 140377,\n  },\n  {\n    date: 1461783960000,\n    open: 50.79,\n    high: 50.8001,\n    low: 50.78,\n    close: 50.785,\n    volume: 65863,\n  },\n  {\n    date: 1461784020000,\n    open: 50.79,\n    high: 50.79,\n    low: 50.75,\n    close: 50.755,\n    volume: 82546,\n  },\n  {\n    date: 1461784080000,\n    open: 50.76,\n    high: 50.8,\n    low: 50.75,\n    close: 50.795,\n    volume: 84186,\n  },\n  {\n    date: 1461784140000,\n    open: 50.795,\n    high: 50.822,\n    low: 50.79,\n    close: 50.805,\n    volume: 118657,\n  },\n  {\n    date: 1461784200000,\n    open: 50.805,\n    high: 50.805,\n    low: 50.76,\n    close: 50.8,\n    volume: 70278,\n  },\n  {\n    date: 1461784260000,\n    open: 50.796,\n    high: 50.81,\n    low: 50.783,\n    close: 50.79,\n    volume: 109124,\n  },\n  {\n    date: 1461784320000,\n    open: 50.795,\n    high: 50.81,\n    low: 50.78,\n    close: 50.78,\n    volume: 68778,\n  },\n  {\n    date: 1461784380000,\n    open: 50.79,\n    high: 50.8,\n    low: 50.765,\n    close: 50.783,\n    volume: 70801,\n  },\n  {\n    date: 1461784440000,\n    open: 50.7842,\n    high: 50.85,\n    low: 50.78,\n    close: 50.84,\n    volume: 181439,\n  },\n  {\n    date: 1461784500000,\n    open: 50.84,\n    high: 50.84,\n    low: 50.8,\n    close: 50.8258,\n    volume: 63077,\n  },\n  {\n    date: 1461784560000,\n    open: 50.825,\n    high: 50.85,\n    low: 50.82,\n    close: 50.827,\n    volume: 65914,\n  },\n  {\n    date: 1461784620000,\n    open: 50.83,\n    high: 50.85,\n    low: 50.82,\n    close: 50.83,\n    volume: 47988,\n  },\n  {\n    date: 1461784680000,\n    open: 50.835,\n    high: 50.86,\n    low: 50.83,\n    close: 50.85,\n    volume: 190304,\n  },\n  {\n    date: 1461784740000,\n    open: 50.85,\n    high: 50.87,\n    low: 50.81,\n    close: 50.83,\n    volume: 202984,\n  },\n  {\n    date: 1461784800000,\n    open: 50.83,\n    high: 50.83,\n    low: 50.82,\n    close: 50.83,\n    volume: 122038,\n  },\n  {\n    date: 1461784860000,\n    open: 50.83,\n    high: 50.86,\n    low: 50.82,\n    close: 50.85,\n    volume: 199446,\n  },\n  {\n    date: 1461784920000,\n    open: 50.85,\n    high: 50.9,\n    low: 50.84,\n    close: 50.885,\n    volume: 68994,\n  },\n  {\n    date: 1461784980000,\n    open: 50.885,\n    high: 51.1,\n    low: 50.8545,\n    close: 50.8695,\n    volume: 172386,\n  },\n  {\n    date: 1461785040000,\n    open: 50.87,\n    high: 50.87,\n    low: 50.86,\n    close: 50.865,\n    volume: 49371,\n  },\n  {\n    date: 1461785100000,\n    open: 50.865,\n    high: 50.9,\n    low: 50.865,\n    close: 50.9,\n    volume: 118278,\n  },\n  {\n    date: 1461785160000,\n    open: 50.895,\n    high: 50.9,\n    low: 50.88,\n    close: 50.8865,\n    volume: 87765,\n  },\n  {\n    date: 1461785220000,\n    open: 50.88,\n    high: 50.89,\n    low: 50.87,\n    close: 50.8701,\n    volume: 46294,\n  },\n  {\n    date: 1461785280000,\n    open: 50.87,\n    high: 50.875,\n    low: 50.8435,\n    close: 50.865,\n    volume: 104587,\n  },\n  {\n    date: 1461785340000,\n    open: 50.865,\n    high: 50.87,\n    low: 50.82,\n    close: 50.825,\n    volume: 104835,\n  },\n  {\n    date: 1461785400000,\n    open: 50.825,\n    high: 50.84,\n    low: 50.78,\n    close: 50.78,\n    volume: 273401,\n  },\n  {\n    date: 1461785460000,\n    open: 50.785,\n    high: 50.82,\n    low: 50.78,\n    close: 50.805,\n    volume: 215696,\n  },\n  {\n    date: 1461785520000,\n    open: 50.8099,\n    high: 50.8158,\n    low: 50.8,\n    close: 50.815,\n    volume: 47710,\n  },\n  {\n    date: 1461785580000,\n    open: 50.815,\n    high: 50.875,\n    low: 50.8101,\n    close: 50.875,\n    volume: 70646,\n  },\n  {\n    date: 1461785640000,\n    open: 50.8799,\n    high: 50.9,\n    low: 50.86,\n    close: 50.885,\n    volume: 133569,\n  },\n  {\n    date: 1461785700000,\n    open: 50.88,\n    high: 50.9,\n    low: 50.88,\n    close: 50.8905,\n    volume: 52148,\n  },\n  {\n    date: 1461785760000,\n    open: 50.9,\n    high: 50.9,\n    low: 50.88,\n    close: 50.883,\n    volume: 60025,\n  },\n  {\n    date: 1461785820000,\n    open: 50.885,\n    high: 50.9,\n    low: 50.88,\n    close: 50.9,\n    volume: 117357,\n  },\n  {\n    date: 1461785880000,\n    open: 50.9,\n    high: 50.91,\n    low: 50.89,\n    close: 50.8965,\n    volume: 131701,\n  },\n  {\n    date: 1461785940000,\n    open: 50.9,\n    high: 50.96,\n    low: 50.8901,\n    close: 50.945,\n    volume: 223032,\n  },\n  {\n    date: 1461786000000,\n    open: 50.945,\n    high: 50.96,\n    low: 50.94,\n    close: 50.945,\n    volume: 115519,\n  },\n  {\n    date: 1461786060000,\n    open: 50.95,\n    high: 50.959,\n    low: 50.91,\n    close: 50.925,\n    volume: 162941,\n  },\n  {\n    date: 1461786120000,\n    open: 50.92,\n    high: 50.93,\n    low: 50.89,\n    close: 50.9,\n    volume: 50125,\n  },\n  {\n    date: 1461786180000,\n    open: 50.895,\n    high: 50.895,\n    low: 50.855,\n    close: 50.86,\n    volume: 201300,\n  },\n  {\n    date: 1461786240000,\n    open: 50.865,\n    high: 50.89,\n    low: 50.85,\n    close: 50.885,\n    volume: 201664,\n  },\n  {\n    date: 1461786300000,\n    open: 50.89,\n    high: 50.93,\n    low: 50.8801,\n    close: 50.91,\n    volume: 91414,\n  },\n  {\n    date: 1461786360000,\n    open: 50.91,\n    high: 50.98,\n    low: 50.905,\n    close: 50.98,\n    volume: 115513,\n  },\n  {\n    date: 1461786420000,\n    open: 50.98,\n    high: 50.98,\n    low: 50.94,\n    close: 50.949,\n    volume: 142650,\n  },\n  {\n    date: 1461786480000,\n    open: 50.945,\n    high: 50.965,\n    low: 50.91,\n    close: 50.92,\n    volume: 173689,\n  },\n  {\n    date: 1461786540000,\n    open: 50.93,\n    high: 50.95,\n    low: 50.92,\n    close: 50.948,\n    volume: 114290,\n  },\n  {\n    date: 1461786600000,\n    open: 50.945,\n    high: 50.98,\n    low: 50.94,\n    close: 50.975,\n    volume: 112347,\n  },\n  {\n    date: 1461786660000,\n    open: 50.97,\n    high: 50.975,\n    low: 50.88,\n    close: 50.88,\n    volume: 220538,\n  },\n  {\n    date: 1461786720000,\n    open: 50.88,\n    high: 50.9,\n    low: 50.88,\n    close: 50.885,\n    volume: 120061,\n  },\n  {\n    date: 1461786780000,\n    open: 50.885,\n    high: 50.89,\n    low: 50.87,\n    close: 50.88,\n    volume: 128413,\n  },\n  {\n    date: 1461786840000,\n    open: 50.885,\n    high: 50.89,\n    low: 50.88,\n    close: 50.885,\n    volume: 83951,\n  },\n  {\n    date: 1461786900000,\n    open: 50.885,\n    high: 50.91,\n    low: 50.87,\n    close: 50.9,\n    volume: 190571,\n  },\n  {\n    date: 1461786960000,\n    open: 50.91,\n    high: 50.91,\n    low: 50.9,\n    close: 50.9,\n    volume: 108528,\n  },\n  {\n    date: 1461787020000,\n    open: 50.905,\n    high: 50.93,\n    low: 50.89,\n    close: 50.9299,\n    volume: 230888,\n  },\n  {\n    date: 1461787080000,\n    open: 50.93,\n    high: 50.93,\n    low: 50.91,\n    close: 50.91,\n    volume: 156162,\n  },\n  {\n    date: 1461787140000,\n    open: 50.92,\n    high: 50.92,\n    low: 50.88,\n    close: 50.885,\n    volume: 235939,\n  },\n  {\n    date: 1461787200000,\n    open: 50.885,\n    high: 50.95,\n    low: 50.86,\n    close: 50.94,\n    volume: 3508181,\n  },\n  {\n    date: 1461850200000,\n    open: 50.62,\n    high: 50.7,\n    low: 50.62,\n    close: 50.68,\n    volume: 362874,\n  },\n  {\n    date: 1461850260000,\n    open: 50.688,\n    high: 50.77,\n    low: 50.6,\n    close: 50.615,\n    volume: 205859,\n  },\n  {\n    date: 1461850320000,\n    open: 50.6138,\n    high: 50.62,\n    low: 50.56,\n    close: 50.56,\n    volume: 103291,\n  },\n  {\n    date: 1461850380000,\n    open: 50.56,\n    high: 50.59,\n    low: 50.53,\n    close: 50.59,\n    volume: 93887,\n  },\n  {\n    date: 1461850440000,\n    open: 50.59,\n    high: 50.6,\n    low: 50.36,\n    close: 50.43,\n    volume: 209588,\n  },\n  {\n    date: 1461850500000,\n    open: 50.43,\n    high: 50.52,\n    low: 50.4265,\n    close: 50.47,\n    volume: 96416,\n  },\n  {\n    date: 1461850560000,\n    open: 50.47,\n    high: 50.6,\n    low: 50.46,\n    close: 50.57,\n    volume: 92282,\n  },\n  {\n    date: 1461850620000,\n    open: 50.57,\n    high: 50.59,\n    low: 50.52,\n    close: 50.54,\n    volume: 89046,\n  },\n  {\n    date: 1461850680000,\n    open: 50.54,\n    high: 50.56,\n    low: 50.48,\n    close: 50.56,\n    volume: 160894,\n  },\n  {\n    date: 1461850740000,\n    open: 50.55,\n    high: 50.57,\n    low: 50.475,\n    close: 50.5499,\n    volume: 157492,\n  },\n  {\n    date: 1461850800000,\n    open: 50.545,\n    high: 50.61,\n    low: 50.522,\n    close: 50.53,\n    volume: 108126,\n  },\n  {\n    date: 1461850860000,\n    open: 50.53,\n    high: 50.605,\n    low: 50.51,\n    close: 50.56,\n    volume: 203343,\n  },\n  {\n    date: 1461850920000,\n    open: 50.56,\n    high: 50.6,\n    low: 50.56,\n    close: 50.58,\n    volume: 265382,\n  },\n  {\n    date: 1461850980000,\n    open: 50.572,\n    high: 50.58,\n    low: 50.55,\n    close: 50.56,\n    volume: 126095,\n  },\n  {\n    date: 1461851040000,\n    open: 50.5601,\n    high: 50.59,\n    low: 50.55,\n    close: 50.57,\n    volume: 73798,\n  },\n  {\n    date: 1461851100000,\n    open: 50.5628,\n    high: 50.58,\n    low: 50.51,\n    close: 50.51,\n    volume: 80575,\n  },\n  {\n    date: 1461851160000,\n    open: 50.515,\n    high: 50.57,\n    low: 50.515,\n    close: 50.56,\n    volume: 95879,\n  },\n  {\n    date: 1461851220000,\n    open: 50.57,\n    high: 50.57,\n    low: 50.53,\n    close: 50.54,\n    volume: 92729,\n  },\n  {\n    date: 1461851280000,\n    open: 50.54,\n    high: 50.5499,\n    low: 50.51,\n    close: 50.525,\n    volume: 80307,\n  },\n  {\n    date: 1461851340000,\n    open: 50.53,\n    high: 50.71,\n    low: 50.53,\n    close: 50.64,\n    volume: 407422,\n  },\n  {\n    date: 1461851400000,\n    open: 50.64,\n    high: 50.695,\n    low: 50.64,\n    close: 50.65,\n    volume: 100084,\n  },\n  {\n    date: 1461851460000,\n    open: 50.65,\n    high: 50.655,\n    low: 50.595,\n    close: 50.615,\n    volume: 77637,\n  },\n  {\n    date: 1461851520000,\n    open: 50.615,\n    high: 50.63,\n    low: 50.59,\n    close: 50.6,\n    volume: 70822,\n  },\n  {\n    date: 1461851580000,\n    open: 50.6,\n    high: 50.6,\n    low: 50.52,\n    close: 50.52,\n    volume: 64133,\n  },\n  {\n    date: 1461851640000,\n    open: 50.525,\n    high: 50.59,\n    low: 50.5,\n    close: 50.545,\n    volume: 61358,\n  },\n  {\n    date: 1461851700000,\n    open: 50.55,\n    high: 50.56,\n    low: 50.54,\n    close: 50.54,\n    volume: 32417,\n  },\n  {\n    date: 1461851760000,\n    open: 50.54,\n    high: 50.55,\n    low: 50.5,\n    close: 50.51,\n    volume: 85382,\n  },\n  {\n    date: 1461851820000,\n    open: 50.505,\n    high: 50.53,\n    low: 50.48,\n    close: 50.51,\n    volume: 71173,\n  },\n  {\n    date: 1461851880000,\n    open: 50.51,\n    high: 50.565,\n    low: 50.51,\n    close: 50.54,\n    volume: 35147,\n  },\n  {\n    date: 1461851940000,\n    open: 50.545,\n    high: 50.6,\n    low: 50.545,\n    close: 50.595,\n    volume: 45630,\n  },\n  {\n    date: 1461852000000,\n    open: 50.5999,\n    high: 50.61,\n    low: 50.56,\n    close: 50.575,\n    volume: 95452,\n  },\n  {\n    date: 1461852060000,\n    open: 50.58,\n    high: 50.6,\n    low: 50.56,\n    close: 50.595,\n    volume: 65340,\n  },\n  {\n    date: 1461852120000,\n    open: 50.595,\n    high: 50.6,\n    low: 50.57,\n    close: 50.57,\n    volume: 91587,\n  },\n  {\n    date: 1461852180000,\n    open: 50.575,\n    high: 50.6,\n    low: 50.56,\n    close: 50.59,\n    volume: 84492,\n  },\n  {\n    date: 1461852240000,\n    open: 50.595,\n    high: 50.61,\n    low: 50.51,\n    close: 50.51,\n    volume: 134871,\n  },\n  {\n    date: 1461852300000,\n    open: 50.515,\n    high: 50.56,\n    low: 50.51,\n    close: 50.55,\n    volume: 40814,\n  },\n  {\n    date: 1461852360000,\n    open: 50.55,\n    high: 50.56,\n    low: 50.5301,\n    close: 50.55,\n    volume: 72676,\n  },\n  {\n    date: 1461852420000,\n    open: 50.55,\n    high: 50.56,\n    low: 50.55,\n    close: 50.56,\n    volume: 52193,\n  },\n  {\n    date: 1461852480000,\n    open: 50.555,\n    high: 50.56,\n    low: 50.5,\n    close: 50.505,\n    volume: 42888,\n  },\n  {\n    date: 1461852540000,\n    open: 50.505,\n    high: 50.52,\n    low: 50.45,\n    close: 50.45,\n    volume: 93210,\n  },\n  {\n    date: 1461852600000,\n    open: 50.4584,\n    high: 50.46,\n    low: 50.41,\n    close: 50.44,\n    volume: 79316,\n  },\n  {\n    date: 1461852660000,\n    open: 50.445,\n    high: 50.445,\n    low: 50.36,\n    close: 50.375,\n    volume: 127200,\n  },\n  {\n    date: 1461852720000,\n    open: 50.3799,\n    high: 50.42,\n    low: 50.3,\n    close: 50.31,\n    volume: 133004,\n  },\n  {\n    date: 1461852780000,\n    open: 50.31,\n    high: 50.44,\n    low: 50.3,\n    close: 50.4201,\n    volume: 89766,\n  },\n  {\n    date: 1461852840000,\n    open: 50.42,\n    high: 50.4462,\n    low: 50.3924,\n    close: 50.445,\n    volume: 67062,\n  },\n  {\n    date: 1461852900000,\n    open: 50.45,\n    high: 50.45,\n    low: 50.41,\n    close: 50.41,\n    volume: 51079,\n  },\n  {\n    date: 1461852960000,\n    open: 50.41,\n    high: 50.415,\n    low: 50.34,\n    close: 50.34,\n    volume: 100248,\n  },\n  {\n    date: 1461853020000,\n    open: 50.35,\n    high: 50.3958,\n    low: 50.33,\n    close: 50.385,\n    volume: 116520,\n  },\n  {\n    date: 1461853080000,\n    open: 50.39,\n    high: 50.405,\n    low: 50.375,\n    close: 50.389,\n    volume: 54942,\n  },\n  {\n    date: 1461853140000,\n    open: 50.39,\n    high: 50.44,\n    low: 50.38,\n    close: 50.44,\n    volume: 153856,\n  },\n  {\n    date: 1461853200000,\n    open: 50.435,\n    high: 50.44,\n    low: 50.41,\n    close: 50.425,\n    volume: 35609,\n  },\n  {\n    date: 1461853260000,\n    open: 50.42,\n    high: 50.455,\n    low: 50.42,\n    close: 50.455,\n    volume: 103076,\n  },\n  {\n    date: 1461853320000,\n    open: 50.4562,\n    high: 50.4562,\n    low: 50.4,\n    close: 50.4,\n    volume: 89085,\n  },\n  {\n    date: 1461853380000,\n    open: 50.405,\n    high: 50.42,\n    low: 50.37,\n    close: 50.37,\n    volume: 68682,\n  },\n  {\n    date: 1461853440000,\n    open: 50.37,\n    high: 50.39,\n    low: 50.355,\n    close: 50.37,\n    volume: 80103,\n  },\n  {\n    date: 1461853500000,\n    open: 50.3699,\n    high: 50.44,\n    low: 50.36,\n    close: 50.44,\n    volume: 60084,\n  },\n  {\n    date: 1461853560000,\n    open: 50.44,\n    high: 50.505,\n    low: 50.44,\n    close: 50.48,\n    volume: 92849,\n  },\n  {\n    date: 1461853620000,\n    open: 50.48,\n    high: 50.51,\n    low: 50.48,\n    close: 50.5,\n    volume: 42855,\n  },\n  {\n    date: 1461853680000,\n    open: 50.4932,\n    high: 50.5,\n    low: 50.47,\n    close: 50.47,\n    volume: 50732,\n  },\n  {\n    date: 1461853740000,\n    open: 50.475,\n    high: 50.49,\n    low: 50.44,\n    close: 50.44,\n    volume: 57545,\n  },\n  {\n    date: 1461853800000,\n    open: 50.44,\n    high: 50.46,\n    low: 50.42,\n    close: 50.455,\n    volume: 77793,\n  },\n  {\n    date: 1461853860000,\n    open: 50.455,\n    high: 50.49,\n    low: 50.45,\n    close: 50.47,\n    volume: 108891,\n  },\n  {\n    date: 1461853920000,\n    open: 50.475,\n    high: 50.49,\n    low: 50.47,\n    close: 50.475,\n    volume: 56247,\n  },\n  {\n    date: 1461853980000,\n    open: 50.475,\n    high: 50.5,\n    low: 50.47,\n    close: 50.475,\n    volume: 73148,\n  },\n  {\n    date: 1461854040000,\n    open: 50.48,\n    high: 50.48,\n    low: 50.42,\n    close: 50.43,\n    volume: 83732,\n  },\n  {\n    date: 1461854100000,\n    open: 50.42,\n    high: 50.49,\n    low: 50.42,\n    close: 50.455,\n    volume: 68619,\n  },\n  {\n    date: 1461854160000,\n    open: 50.46,\n    high: 50.49,\n    low: 50.44,\n    close: 50.48,\n    volume: 48140,\n  },\n  {\n    date: 1461854220000,\n    open: 50.485,\n    high: 50.515,\n    low: 50.46,\n    close: 50.51,\n    volume: 117848,\n  },\n  {\n    date: 1461854280000,\n    open: 50.5107,\n    high: 50.53,\n    low: 50.4901,\n    close: 50.515,\n    volume: 58625,\n  },\n  {\n    date: 1461854340000,\n    open: 50.515,\n    high: 50.515,\n    low: 50.44,\n    close: 50.44,\n    volume: 32806,\n  },\n  {\n    date: 1461854400000,\n    open: 50.445,\n    high: 50.45,\n    low: 50.42,\n    close: 50.42,\n    volume: 42684,\n  },\n  {\n    date: 1461854460000,\n    open: 50.42,\n    high: 50.46,\n    low: 50.4,\n    close: 50.4399,\n    volume: 62513,\n  },\n  {\n    date: 1461854520000,\n    open: 50.44,\n    high: 50.45,\n    low: 50.43,\n    close: 50.445,\n    volume: 40692,\n  },\n  {\n    date: 1461854580000,\n    open: 50.4499,\n    high: 50.47,\n    low: 50.42,\n    close: 50.42,\n    volume: 56498,\n  },\n  {\n    date: 1461854640000,\n    open: 50.4262,\n    high: 50.45,\n    low: 50.415,\n    close: 50.4333,\n    volume: 50217,\n  },\n  {\n    date: 1461854700000,\n    open: 50.435,\n    high: 50.45,\n    low: 50.42,\n    close: 50.445,\n    volume: 66527,\n  },\n  {\n    date: 1461854760000,\n    open: 50.45,\n    high: 50.45,\n    low: 50.42,\n    close: 50.43,\n    volume: 65141,\n  },\n  {\n    date: 1461854820000,\n    open: 50.4341,\n    high: 50.45,\n    low: 50.42,\n    close: 50.445,\n    volume: 65061,\n  },\n  {\n    date: 1461854880000,\n    open: 50.445,\n    high: 50.46,\n    low: 50.445,\n    close: 50.45,\n    volume: 115532,\n  },\n  {\n    date: 1461854940000,\n    open: 50.455,\n    high: 50.46,\n    low: 50.43,\n    close: 50.45,\n    volume: 81908,\n  },\n  {\n    date: 1461855000000,\n    open: 50.45,\n    high: 50.5,\n    low: 50.445,\n    close: 50.5,\n    volume: 95265,\n  },\n  {\n    date: 1461855060000,\n    open: 50.5,\n    high: 50.52,\n    low: 50.4967,\n    close: 50.515,\n    volume: 52823,\n  },\n  {\n    date: 1461855120000,\n    open: 50.515,\n    high: 50.56,\n    low: 50.51,\n    close: 50.5401,\n    volume: 77926,\n  },\n  {\n    date: 1461855180000,\n    open: 50.5409,\n    high: 50.55,\n    low: 50.5,\n    close: 50.51,\n    volume: 49825,\n  },\n  {\n    date: 1461855240000,\n    open: 50.5099,\n    high: 50.53,\n    low: 50.5,\n    close: 50.5099,\n    volume: 34568,\n  },\n  {\n    date: 1461855300000,\n    open: 50.505,\n    high: 50.52,\n    low: 50.5,\n    close: 50.5035,\n    volume: 33194,\n  },\n  {\n    date: 1461855360000,\n    open: 50.5,\n    high: 50.51,\n    low: 50.4801,\n    close: 50.49,\n    volume: 60726,\n  },\n  {\n    date: 1461855420000,\n    open: 50.4975,\n    high: 50.51,\n    low: 50.47,\n    close: 50.485,\n    volume: 51257,\n  },\n  {\n    date: 1461855480000,\n    open: 50.49,\n    high: 50.51,\n    low: 50.47,\n    close: 50.49,\n    volume: 117313,\n  },\n  {\n    date: 1461855540000,\n    open: 50.49,\n    high: 50.515,\n    low: 50.48,\n    close: 50.495,\n    volume: 79201,\n  },\n  {\n    date: 1461855600000,\n    open: 50.5,\n    high: 50.51,\n    low: 50.49,\n    close: 50.51,\n    volume: 32603,\n  },\n  {\n    date: 1461855660000,\n    open: 50.51,\n    high: 50.52,\n    low: 50.49,\n    close: 50.51,\n    volume: 91991,\n  },\n  {\n    date: 1461855720000,\n    open: 50.51,\n    high: 50.5299,\n    low: 50.5,\n    close: 50.515,\n    volume: 25794,\n  },\n  {\n    date: 1461855780000,\n    open: 50.515,\n    high: 50.52,\n    low: 50.5,\n    close: 50.5,\n    volume: 29739,\n  },\n  {\n    date: 1461855840000,\n    open: 50.505,\n    high: 50.53,\n    low: 50.5,\n    close: 50.525,\n    volume: 45836,\n  },\n  {\n    date: 1461855900000,\n    open: 50.54,\n    high: 50.55,\n    low: 50.53,\n    close: 50.55,\n    volume: 92272,\n  },\n  {\n    date: 1461855960000,\n    open: 50.545,\n    high: 50.57,\n    low: 50.54,\n    close: 50.5699,\n    volume: 85107,\n  },\n  {\n    date: 1461856020000,\n    open: 50.56,\n    high: 50.59,\n    low: 50.56,\n    close: 50.58,\n    volume: 53308,\n  },\n  {\n    date: 1461856080000,\n    open: 50.58,\n    high: 50.59,\n    low: 50.56,\n    close: 50.57,\n    volume: 15261,\n  },\n  {\n    date: 1461856140000,\n    open: 50.57,\n    high: 50.57,\n    low: 50.54,\n    close: 50.57,\n    volume: 35726,\n  },\n  {\n    date: 1461856200000,\n    open: 50.565,\n    high: 50.58,\n    low: 50.545,\n    close: 50.545,\n    volume: 37090,\n  },\n  {\n    date: 1461856260000,\n    open: 50.54,\n    high: 50.56,\n    low: 50.53,\n    close: 50.56,\n    volume: 40567,\n  },\n  {\n    date: 1461856320000,\n    open: 50.56,\n    high: 50.58,\n    low: 50.5428,\n    close: 50.575,\n    volume: 66059,\n  },\n  {\n    date: 1461856380000,\n    open: 50.57,\n    high: 50.59,\n    low: 50.56,\n    close: 50.5841,\n    volume: 52451,\n  },\n  {\n    date: 1461856440000,\n    open: 50.58,\n    high: 50.605,\n    low: 50.57,\n    close: 50.57,\n    volume: 78340,\n  },\n  {\n    date: 1461856500000,\n    open: 50.5699,\n    high: 50.575,\n    low: 50.56,\n    close: 50.56,\n    volume: 44554,\n  },\n  {\n    date: 1461856560000,\n    open: 50.5602,\n    high: 50.6,\n    low: 50.5602,\n    close: 50.59,\n    volume: 34301,\n  },\n  {\n    date: 1461856620000,\n    open: 50.595,\n    high: 50.5999,\n    low: 50.555,\n    close: 50.5554,\n    volume: 39912,\n  },\n  {\n    date: 1461856680000,\n    open: 50.555,\n    high: 50.6,\n    low: 50.55,\n    close: 50.59,\n    volume: 31505,\n  },\n  {\n    date: 1461856740000,\n    open: 50.6,\n    high: 50.6,\n    low: 50.565,\n    close: 50.565,\n    volume: 26028,\n  },\n  {\n    date: 1461856800000,\n    open: 50.56,\n    high: 50.59,\n    low: 50.55,\n    close: 50.59,\n    volume: 24022,\n  },\n  {\n    date: 1461856860000,\n    open: 50.6,\n    high: 50.61,\n    low: 50.58,\n    close: 50.605,\n    volume: 56942,\n  },\n  {\n    date: 1461856920000,\n    open: 50.605,\n    high: 50.62,\n    low: 50.59,\n    close: 50.62,\n    volume: 44976,\n  },\n  {\n    date: 1461856980000,\n    open: 50.6147,\n    high: 50.62,\n    low: 50.6,\n    close: 50.6199,\n    volume: 25550,\n  },\n  {\n    date: 1461857040000,\n    open: 50.6199,\n    high: 50.64,\n    low: 50.61,\n    close: 50.6301,\n    volume: 37060,\n  },\n  {\n    date: 1461857100000,\n    open: 50.64,\n    high: 50.65,\n    low: 50.63,\n    close: 50.645,\n    volume: 64888,\n  },\n  {\n    date: 1461857160000,\n    open: 50.65,\n    high: 50.65,\n    low: 50.63,\n    close: 50.65,\n    volume: 51583,\n  },\n  {\n    date: 1461857220000,\n    open: 50.65,\n    high: 50.65,\n    low: 50.63,\n    close: 50.64,\n    volume: 27508,\n  },\n  {\n    date: 1461857280000,\n    open: 50.6471,\n    high: 50.6471,\n    low: 50.62,\n    close: 50.626,\n    volume: 15765,\n  },\n  {\n    date: 1461857340000,\n    open: 50.62,\n    high: 50.63,\n    low: 50.615,\n    close: 50.6165,\n    volume: 22894,\n  },\n  {\n    date: 1461857400000,\n    open: 50.61,\n    high: 50.62,\n    low: 50.61,\n    close: 50.61,\n    volume: 18466,\n  },\n  {\n    date: 1461857460000,\n    open: 50.61,\n    high: 50.62,\n    low: 50.61,\n    close: 50.616,\n    volume: 28857,\n  },\n  {\n    date: 1461857520000,\n    open: 50.61,\n    high: 50.62,\n    low: 50.61,\n    close: 50.61,\n    volume: 15896,\n  },\n  {\n    date: 1461857580000,\n    open: 50.6172,\n    high: 50.62,\n    low: 50.59,\n    close: 50.5901,\n    volume: 27929,\n  },\n  {\n    date: 1461857640000,\n    open: 50.5935,\n    high: 50.6,\n    low: 50.55,\n    close: 50.56,\n    volume: 43870,\n  },\n  {\n    date: 1461857700000,\n    open: 50.57,\n    high: 50.62,\n    low: 50.567,\n    close: 50.611,\n    volume: 20569,\n  },\n  {\n    date: 1461857760000,\n    open: 50.62,\n    high: 50.63,\n    low: 50.6,\n    close: 50.63,\n    volume: 30079,\n  },\n  {\n    date: 1461857820000,\n    open: 50.625,\n    high: 50.66,\n    low: 50.62,\n    close: 50.6299,\n    volume: 82256,\n  },\n  {\n    date: 1461857880000,\n    open: 50.63,\n    high: 50.63,\n    low: 50.61,\n    close: 50.61,\n    volume: 29448,\n  },\n  {\n    date: 1461857940000,\n    open: 50.615,\n    high: 50.65,\n    low: 50.61,\n    close: 50.63,\n    volume: 59514,\n  },\n  {\n    date: 1461858000000,\n    open: 50.63,\n    high: 50.64,\n    low: 50.61,\n    close: 50.63,\n    volume: 43497,\n  },\n  {\n    date: 1461858060000,\n    open: 50.63,\n    high: 50.63,\n    low: 50.61,\n    close: 50.615,\n    volume: 27159,\n  },\n  {\n    date: 1461858120000,\n    open: 50.615,\n    high: 50.62,\n    low: 50.58,\n    close: 50.58,\n    volume: 66268,\n  },\n  {\n    date: 1461858180000,\n    open: 50.585,\n    high: 50.6,\n    low: 50.584,\n    close: 50.5942,\n    volume: 17913,\n  },\n  {\n    date: 1461858240000,\n    open: 50.59,\n    high: 50.6,\n    low: 50.59,\n    close: 50.59,\n    volume: 16714,\n  },\n  {\n    date: 1461858300000,\n    open: 50.59,\n    high: 50.6,\n    low: 50.59,\n    close: 50.59,\n    volume: 30127,\n  },\n  {\n    date: 1461858360000,\n    open: 50.595,\n    high: 50.61,\n    low: 50.59,\n    close: 50.59,\n    volume: 34228,\n  },\n  {\n    date: 1461858420000,\n    open: 50.5999,\n    high: 50.6,\n    low: 50.57,\n    close: 50.575,\n    volume: 28301,\n  },\n  {\n    date: 1461858480000,\n    open: 50.575,\n    high: 50.58,\n    low: 50.55,\n    close: 50.57,\n    volume: 48303,\n  },\n  {\n    date: 1461858540000,\n    open: 50.57,\n    high: 50.57,\n    low: 50.56,\n    close: 50.57,\n    volume: 12637,\n  },\n  {\n    date: 1461858600000,\n    open: 50.57,\n    high: 50.57,\n    low: 50.55,\n    close: 50.55,\n    volume: 28387,\n  },\n  {\n    date: 1461858660000,\n    open: 50.56,\n    high: 50.58,\n    low: 50.55,\n    close: 50.5799,\n    volume: 33777,\n  },\n  {\n    date: 1461858720000,\n    open: 50.575,\n    high: 50.5799,\n    low: 50.535,\n    close: 50.54,\n    volume: 53307,\n  },\n  {\n    date: 1461858780000,\n    open: 50.54,\n    high: 50.56,\n    low: 50.53,\n    close: 50.55,\n    volume: 23277,\n  },\n  {\n    date: 1461858840000,\n    open: 50.55,\n    high: 50.56,\n    low: 50.545,\n    close: 50.5564,\n    volume: 17796,\n  },\n  {\n    date: 1461858900000,\n    open: 50.55,\n    high: 50.575,\n    low: 50.54,\n    close: 50.545,\n    volume: 49953,\n  },\n  {\n    date: 1461858960000,\n    open: 50.549,\n    high: 50.565,\n    low: 50.545,\n    close: 50.5537,\n    volume: 20134,\n  },\n  {\n    date: 1461859020000,\n    open: 50.55,\n    high: 50.58,\n    low: 50.55,\n    close: 50.57,\n    volume: 18548,\n  },\n  {\n    date: 1461859080000,\n    open: 50.57,\n    high: 50.57,\n    low: 50.55,\n    close: 50.5577,\n    volume: 29869,\n  },\n  {\n    date: 1461859140000,\n    open: 50.555,\n    high: 50.56,\n    low: 50.53,\n    close: 50.545,\n    volume: 41326,\n  },\n  {\n    date: 1461859200000,\n    open: 50.55,\n    high: 50.57,\n    low: 50.54,\n    close: 50.5601,\n    volume: 33320,\n  },\n  {\n    date: 1461859260000,\n    open: 50.5601,\n    high: 50.59,\n    low: 50.56,\n    close: 50.58,\n    volume: 59892,\n  },\n  {\n    date: 1461859320000,\n    open: 50.58,\n    high: 50.6,\n    low: 50.58,\n    close: 50.59,\n    volume: 56709,\n  },\n  {\n    date: 1461859380000,\n    open: 50.59,\n    high: 50.59,\n    low: 50.58,\n    close: 50.59,\n    volume: 7465,\n  },\n  {\n    date: 1461859440000,\n    open: 50.59,\n    high: 50.62,\n    low: 50.57,\n    close: 50.58,\n    volume: 82293,\n  },\n  {\n    date: 1461859500000,\n    open: 50.585,\n    high: 50.59,\n    low: 50.54,\n    close: 50.55,\n    volume: 54187,\n  },\n  {\n    date: 1461859560000,\n    open: 50.55,\n    high: 50.58,\n    low: 50.55,\n    close: 50.5728,\n    volume: 20221,\n  },\n  {\n    date: 1461859620000,\n    open: 50.57,\n    high: 50.575,\n    low: 50.55,\n    close: 50.55,\n    volume: 17135,\n  },\n  {\n    date: 1461859680000,\n    open: 50.55,\n    high: 50.56,\n    low: 50.53,\n    close: 50.535,\n    volume: 17693,\n  },\n  {\n    date: 1461859740000,\n    open: 50.53,\n    high: 50.54,\n    low: 50.53,\n    close: 50.535,\n    volume: 16522,\n  },\n  {\n    date: 1461859800000,\n    open: 50.535,\n    high: 50.54,\n    low: 50.53,\n    close: 50.535,\n    volume: 20326,\n  },\n  {\n    date: 1461859860000,\n    open: 50.535,\n    high: 50.54,\n    low: 50.5,\n    close: 50.5,\n    volume: 71713,\n  },\n  {\n    date: 1461859920000,\n    open: 50.51,\n    high: 50.51,\n    low: 50.47,\n    close: 50.485,\n    volume: 114100,\n  },\n  {\n    date: 1461859980000,\n    open: 50.48,\n    high: 50.49,\n    low: 50.46,\n    close: 50.465,\n    volume: 56150,\n  },\n  {\n    date: 1461860040000,\n    open: 50.465,\n    high: 50.48,\n    low: 50.45,\n    close: 50.455,\n    volume: 36453,\n  },\n  {\n    date: 1461860100000,\n    open: 50.4559,\n    high: 50.46,\n    low: 50.4335,\n    close: 50.44,\n    volume: 50517,\n  },\n  {\n    date: 1461860160000,\n    open: 50.442,\n    high: 50.45,\n    low: 50.43,\n    close: 50.44,\n    volume: 46156,\n  },\n  {\n    date: 1461860220000,\n    open: 50.43,\n    high: 50.44,\n    low: 50.42,\n    close: 50.435,\n    volume: 39714,\n  },\n  {\n    date: 1461860280000,\n    open: 50.43,\n    high: 50.4399,\n    low: 50.41,\n    close: 50.42,\n    volume: 32182,\n  },\n  {\n    date: 1461860340000,\n    open: 50.42,\n    high: 50.43,\n    low: 50.37,\n    close: 50.38,\n    volume: 78612,\n  },\n  {\n    date: 1461860400000,\n    open: 50.38,\n    high: 50.3899,\n    low: 50.37,\n    close: 50.37,\n    volume: 19828,\n  },\n  {\n    date: 1461860460000,\n    open: 50.37,\n    high: 50.3799,\n    low: 50.34,\n    close: 50.355,\n    volume: 135527,\n  },\n  {\n    date: 1461860520000,\n    open: 50.35,\n    high: 50.36,\n    low: 50.33,\n    close: 50.3301,\n    volume: 56685,\n  },\n  {\n    date: 1461860580000,\n    open: 50.335,\n    high: 50.36,\n    low: 50.33,\n    close: 50.3313,\n    volume: 45756,\n  },\n  {\n    date: 1461860640000,\n    open: 50.33,\n    high: 50.34,\n    low: 50.33,\n    close: 50.33,\n    volume: 26701,\n  },\n  {\n    date: 1461860700000,\n    open: 50.3399,\n    high: 50.36,\n    low: 50.33,\n    close: 50.33,\n    volume: 63107,\n  },\n  {\n    date: 1461860760000,\n    open: 50.34,\n    high: 50.36,\n    low: 50.32,\n    close: 50.345,\n    volume: 278841,\n  },\n  {\n    date: 1461860820000,\n    open: 50.345,\n    high: 50.3598,\n    low: 50.33,\n    close: 50.34,\n    volume: 39224,\n  },\n  {\n    date: 1461860880000,\n    open: 50.34,\n    high: 50.36,\n    low: 50.34,\n    close: 50.34,\n    volume: 52822,\n  },\n  {\n    date: 1461860940000,\n    open: 50.34,\n    high: 50.35,\n    low: 50.34,\n    close: 50.34,\n    volume: 49410,\n  },\n  {\n    date: 1461861000000,\n    open: 50.34,\n    high: 50.35,\n    low: 50.33,\n    close: 50.33,\n    volume: 40939,\n  },\n  {\n    date: 1461861060000,\n    open: 50.335,\n    high: 50.3399,\n    low: 50.31,\n    close: 50.31,\n    volume: 37770,\n  },\n  {\n    date: 1461861120000,\n    open: 50.31,\n    high: 50.3101,\n    low: 50.29,\n    close: 50.295,\n    volume: 90923,\n  },\n  {\n    date: 1461861180000,\n    open: 50.3,\n    high: 50.35,\n    low: 50.295,\n    close: 50.315,\n    volume: 64570,\n  },\n  {\n    date: 1461861240000,\n    open: 50.315,\n    high: 50.35,\n    low: 50.3,\n    close: 50.301,\n    volume: 66936,\n  },\n  {\n    date: 1461861300000,\n    open: 50.3099,\n    high: 50.31,\n    low: 50.29,\n    close: 50.29,\n    volume: 59247,\n  },\n  {\n    date: 1461861360000,\n    open: 50.295,\n    high: 50.3,\n    low: 50.26,\n    close: 50.28,\n    volume: 107509,\n  },\n  {\n    date: 1461861420000,\n    open: 50.285,\n    high: 50.29,\n    low: 50.26,\n    close: 50.26,\n    volume: 85924,\n  },\n  {\n    date: 1461861480000,\n    open: 50.26,\n    high: 50.28,\n    low: 50.26,\n    close: 50.275,\n    volume: 90196,\n  },\n  {\n    date: 1461861540000,\n    open: 50.27,\n    high: 50.28,\n    low: 50.27,\n    close: 50.28,\n    volume: 28884,\n  },\n  {\n    date: 1461861600000,\n    open: 50.275,\n    high: 50.29,\n    low: 50.27,\n    close: 50.275,\n    volume: 53798,\n  },\n  {\n    date: 1461861660000,\n    open: 50.27,\n    high: 50.28,\n    low: 50.26,\n    close: 50.26,\n    volume: 50292,\n  },\n  {\n    date: 1461861720000,\n    open: 50.27,\n    high: 50.29,\n    low: 50.26,\n    close: 50.27,\n    volume: 67364,\n  },\n  {\n    date: 1461861780000,\n    open: 50.27,\n    high: 50.285,\n    low: 50.26,\n    close: 50.26,\n    volume: 65505,\n  },\n  {\n    date: 1461861840000,\n    open: 50.26,\n    high: 50.28,\n    low: 50.26,\n    close: 50.2799,\n    volume: 49376,\n  },\n  {\n    date: 1461861900000,\n    open: 50.28,\n    high: 50.29,\n    low: 50.27,\n    close: 50.29,\n    volume: 37262,\n  },\n  {\n    date: 1461861960000,\n    open: 50.29,\n    high: 50.325,\n    low: 50.285,\n    close: 50.31,\n    volume: 45522,\n  },\n  {\n    date: 1461862020000,\n    open: 50.31,\n    high: 50.32,\n    low: 50.3,\n    close: 50.316,\n    volume: 59421,\n  },\n  {\n    date: 1461862080000,\n    open: 50.3199,\n    high: 50.326,\n    low: 50.3,\n    close: 50.3199,\n    volume: 41762,\n  },\n  {\n    date: 1461862140000,\n    open: 50.31,\n    high: 50.3199,\n    low: 50.29,\n    close: 50.29,\n    volume: 32042,\n  },\n  {\n    date: 1461862200000,\n    open: 50.29,\n    high: 50.3,\n    low: 50.27,\n    close: 50.27,\n    volume: 29040,\n  },\n  {\n    date: 1461862260000,\n    open: 50.275,\n    high: 50.2799,\n    low: 50.26,\n    close: 50.27,\n    volume: 45003,\n  },\n  {\n    date: 1461862320000,\n    open: 50.265,\n    high: 50.3,\n    low: 50.26,\n    close: 50.295,\n    volume: 34479,\n  },\n  {\n    date: 1461862380000,\n    open: 50.3,\n    high: 50.31,\n    low: 50.29,\n    close: 50.295,\n    volume: 49639,\n  },\n  {\n    date: 1461862440000,\n    open: 50.3,\n    high: 50.305,\n    low: 50.29,\n    close: 50.2967,\n    volume: 54906,\n  },\n  {\n    date: 1461862500000,\n    open: 50.29,\n    high: 50.3,\n    low: 50.27,\n    close: 50.275,\n    volume: 43365,\n  },\n  {\n    date: 1461862560000,\n    open: 50.28,\n    high: 50.31,\n    low: 50.27,\n    close: 50.3,\n    volume: 41683,\n  },\n  {\n    date: 1461862620000,\n    open: 50.3,\n    high: 50.3099,\n    low: 50.28,\n    close: 50.2838,\n    volume: 51092,\n  },\n  {\n    date: 1461862680000,\n    open: 50.2899,\n    high: 50.3,\n    low: 50.28,\n    close: 50.295,\n    volume: 25174,\n  },\n  {\n    date: 1461862740000,\n    open: 50.29,\n    high: 50.299,\n    low: 50.28,\n    close: 50.285,\n    volume: 37623,\n  },\n  {\n    date: 1461862800000,\n    open: 50.285,\n    high: 50.29,\n    low: 50.28,\n    close: 50.285,\n    volume: 33407,\n  },\n  {\n    date: 1461862860000,\n    open: 50.29,\n    high: 50.3,\n    low: 50.285,\n    close: 50.29,\n    volume: 81186,\n  },\n  {\n    date: 1461862920000,\n    open: 50.291,\n    high: 50.3,\n    low: 50.28,\n    close: 50.295,\n    volume: 84673,\n  },\n  {\n    date: 1461862980000,\n    open: 50.3,\n    high: 50.3,\n    low: 50.29,\n    close: 50.295,\n    volume: 147910,\n  },\n  {\n    date: 1461863040000,\n    open: 50.295,\n    high: 50.31,\n    low: 50.29,\n    close: 50.295,\n    volume: 253371,\n  },\n  {\n    date: 1461863100000,\n    open: 50.294,\n    high: 50.31,\n    low: 50.27,\n    close: 50.28,\n    volume: 134815,\n  },\n  {\n    date: 1461863160000,\n    open: 50.28,\n    high: 50.29,\n    low: 50.26,\n    close: 50.28,\n    volume: 135762,\n  },\n  {\n    date: 1461863220000,\n    open: 50.275,\n    high: 50.285,\n    low: 50.27,\n    close: 50.275,\n    volume: 59564,\n  },\n  {\n    date: 1461863280000,\n    open: 50.28,\n    high: 50.29,\n    low: 50.275,\n    close: 50.28,\n    volume: 79163,\n  },\n  {\n    date: 1461863340000,\n    open: 50.285,\n    high: 50.29,\n    low: 50.27,\n    close: 50.275,\n    volume: 69269,\n  },\n  {\n    date: 1461863400000,\n    open: 50.274,\n    high: 50.28,\n    low: 50.265,\n    close: 50.275,\n    volume: 44095,\n  },\n  {\n    date: 1461863460000,\n    open: 50.28,\n    high: 50.28,\n    low: 50.25,\n    close: 50.2601,\n    volume: 70083,\n  },\n  {\n    date: 1461863520000,\n    open: 50.2638,\n    high: 50.28,\n    low: 50.245,\n    close: 50.2765,\n    volume: 305012,\n  },\n  {\n    date: 1461863580000,\n    open: 50.275,\n    high: 50.285,\n    low: 50.25,\n    close: 50.28,\n    volume: 68266,\n  },\n  {\n    date: 1461863640000,\n    open: 50.2899,\n    high: 50.3,\n    low: 50.28,\n    close: 50.295,\n    volume: 50281,\n  },\n  {\n    date: 1461863700000,\n    open: 50.3,\n    high: 50.31,\n    low: 50.29,\n    close: 50.31,\n    volume: 49211,\n  },\n  {\n    date: 1461863760000,\n    open: 50.31,\n    high: 50.31,\n    low: 50.25,\n    close: 50.26,\n    volume: 128015,\n  },\n  {\n    date: 1461863820000,\n    open: 50.255,\n    high: 50.27,\n    low: 50.25,\n    close: 50.265,\n    volume: 59425,\n  },\n  {\n    date: 1461863880000,\n    open: 50.26,\n    high: 50.27,\n    low: 50.26,\n    close: 50.27,\n    volume: 13744,\n  },\n  {\n    date: 1461863940000,\n    open: 50.27,\n    high: 50.28,\n    low: 50.26,\n    close: 50.27,\n    volume: 34048,\n  },\n  {\n    date: 1461864000000,\n    open: 50.275,\n    high: 50.28,\n    low: 50.27,\n    close: 50.2734,\n    volume: 24320,\n  },\n  {\n    date: 1461864060000,\n    open: 50.27,\n    high: 50.27,\n    low: 50.1,\n    close: 50.145,\n    volume: 520783,\n  },\n  {\n    date: 1461864120000,\n    open: 50.145,\n    high: 50.16,\n    low: 50.09,\n    close: 50.135,\n    volume: 137595,\n  },\n  {\n    date: 1461864180000,\n    open: 50.135,\n    high: 50.17,\n    low: 50.095,\n    close: 50.17,\n    volume: 104940,\n  },\n  {\n    date: 1461864240000,\n    open: 50.165,\n    high: 50.17,\n    low: 50.15,\n    close: 50.15,\n    volume: 34941,\n  },\n  {\n    date: 1461864300000,\n    open: 50.16,\n    high: 50.17,\n    low: 50.15,\n    close: 50.17,\n    volume: 29116,\n  },\n  {\n    date: 1461864360000,\n    open: 50.17,\n    high: 50.2,\n    low: 50.16,\n    close: 50.2,\n    volume: 33318,\n  },\n  {\n    date: 1461864420000,\n    open: 50.2,\n    high: 50.2,\n    low: 50.18,\n    close: 50.185,\n    volume: 61962,\n  },\n  {\n    date: 1461864480000,\n    open: 50.1899,\n    high: 50.2,\n    low: 50.18,\n    close: 50.185,\n    volume: 79066,\n  },\n  {\n    date: 1461864540000,\n    open: 50.185,\n    high: 50.2,\n    low: 50.18,\n    close: 50.2,\n    volume: 30402,\n  },\n  {\n    date: 1461864600000,\n    open: 50.2,\n    high: 50.21,\n    low: 50.19,\n    close: 50.2028,\n    volume: 51295,\n  },\n  {\n    date: 1461864660000,\n    open: 50.2,\n    high: 50.2099,\n    low: 50.19,\n    close: 50.195,\n    volume: 16904,\n  },\n  {\n    date: 1461864720000,\n    open: 50.191,\n    high: 50.21,\n    low: 50.19,\n    close: 50.205,\n    volume: 50301,\n  },\n  {\n    date: 1461864780000,\n    open: 50.205,\n    high: 50.24,\n    low: 50.2,\n    close: 50.24,\n    volume: 62535,\n  },\n  {\n    date: 1461864840000,\n    open: 50.25,\n    high: 50.28,\n    low: 50.23,\n    close: 50.235,\n    volume: 58179,\n  },\n  {\n    date: 1461864900000,\n    open: 50.2384,\n    high: 50.24,\n    low: 50.21,\n    close: 50.215,\n    volume: 49289,\n  },\n  {\n    date: 1461864960000,\n    open: 50.21,\n    high: 50.23,\n    low: 50.2,\n    close: 50.23,\n    volume: 35417,\n  },\n  {\n    date: 1461865020000,\n    open: 50.2228,\n    high: 50.235,\n    low: 50.2,\n    close: 50.2,\n    volume: 33952,\n  },\n  {\n    date: 1461865080000,\n    open: 50.2,\n    high: 50.21,\n    low: 50.2,\n    close: 50.2,\n    volume: 21550,\n  },\n  {\n    date: 1461865140000,\n    open: 50.2,\n    high: 50.21,\n    low: 50.19,\n    close: 50.199,\n    volume: 40176,\n  },\n  {\n    date: 1461865200000,\n    open: 50.19,\n    high: 50.2,\n    low: 50.17,\n    close: 50.185,\n    volume: 32751,\n  },\n  {\n    date: 1461865260000,\n    open: 50.19,\n    high: 50.19,\n    low: 50.13,\n    close: 50.15,\n    volume: 56109,\n  },\n  {\n    date: 1461865320000,\n    open: 50.145,\n    high: 50.15,\n    low: 50.13,\n    close: 50.15,\n    volume: 47986,\n  },\n  {\n    date: 1461865380000,\n    open: 50.145,\n    high: 50.19,\n    low: 50.145,\n    close: 50.175,\n    volume: 64069,\n  },\n  {\n    date: 1461865440000,\n    open: 50.175,\n    high: 50.19,\n    low: 50.175,\n    close: 50.18,\n    volume: 24022,\n  },\n  {\n    date: 1461865500000,\n    open: 50.18,\n    high: 50.19,\n    low: 50.18,\n    close: 50.1861,\n    volume: 18160,\n  },\n  {\n    date: 1461865560000,\n    open: 50.185,\n    high: 50.19,\n    low: 50.14,\n    close: 50.145,\n    volume: 28316,\n  },\n  {\n    date: 1461865620000,\n    open: 50.14,\n    high: 50.145,\n    low: 50.115,\n    close: 50.1301,\n    volume: 73736,\n  },\n  {\n    date: 1461865680000,\n    open: 50.14,\n    high: 50.159,\n    low: 50.135,\n    close: 50.145,\n    volume: 64202,\n  },\n  {\n    date: 1461865740000,\n    open: 50.145,\n    high: 50.16,\n    low: 50.135,\n    close: 50.155,\n    volume: 70139,\n  },\n  {\n    date: 1461865800000,\n    open: 50.16,\n    high: 50.16,\n    low: 50.13,\n    close: 50.135,\n    volume: 43965,\n  },\n  {\n    date: 1461865860000,\n    open: 50.14,\n    high: 50.195,\n    low: 50.135,\n    close: 50.19,\n    volume: 50912,\n  },\n  {\n    date: 1461865920000,\n    open: 50.1999,\n    high: 50.22,\n    low: 50.1928,\n    close: 50.22,\n    volume: 32539,\n  },\n  {\n    date: 1461865980000,\n    open: 50.215,\n    high: 50.22,\n    low: 50.189,\n    close: 50.1899,\n    volume: 48503,\n  },\n  {\n    date: 1461866040000,\n    open: 50.182,\n    high: 50.195,\n    low: 50.174,\n    close: 50.1801,\n    volume: 19968,\n  },\n  {\n    date: 1461866100000,\n    open: 50.185,\n    high: 50.19,\n    low: 50.16,\n    close: 50.18,\n    volume: 44410,\n  },\n  {\n    date: 1461866160000,\n    open: 50.185,\n    high: 50.2,\n    low: 50.18,\n    close: 50.19,\n    volume: 25592,\n  },\n  {\n    date: 1461866220000,\n    open: 50.19,\n    high: 50.19,\n    low: 50.17,\n    close: 50.17,\n    volume: 57816,\n  },\n  {\n    date: 1461866280000,\n    open: 50.1738,\n    high: 50.176,\n    low: 50.15,\n    close: 50.15,\n    volume: 42513,\n  },\n  {\n    date: 1461866340000,\n    open: 50.15,\n    high: 50.1599,\n    low: 50.13,\n    close: 50.15,\n    volume: 110757,\n  },\n  {\n    date: 1461866400000,\n    open: 50.15,\n    high: 50.18,\n    low: 50.14,\n    close: 50.15,\n    volume: 78105,\n  },\n  {\n    date: 1461866460000,\n    open: 50.155,\n    high: 50.195,\n    low: 50.155,\n    close: 50.18,\n    volume: 82572,\n  },\n  {\n    date: 1461866520000,\n    open: 50.165,\n    high: 50.2,\n    low: 50.13,\n    close: 50.195,\n    volume: 162461,\n  },\n  {\n    date: 1461866580000,\n    open: 50.195,\n    high: 50.24,\n    low: 50.19,\n    close: 50.24,\n    volume: 209572,\n  },\n  {\n    date: 1461866640000,\n    open: 50.24,\n    high: 50.24,\n    low: 50.21,\n    close: 50.23,\n    volume: 107050,\n  },\n  {\n    date: 1461866700000,\n    open: 50.23,\n    high: 50.23,\n    low: 50.16,\n    close: 50.18,\n    volume: 87345,\n  },\n  {\n    date: 1461866760000,\n    open: 50.185,\n    high: 50.22,\n    low: 50.18,\n    close: 50.195,\n    volume: 31133,\n  },\n  {\n    date: 1461866820000,\n    open: 50.2,\n    high: 50.235,\n    low: 50.195,\n    close: 50.21,\n    volume: 38358,\n  },\n  {\n    date: 1461866880000,\n    open: 50.21,\n    high: 50.235,\n    low: 50.2036,\n    close: 50.23,\n    volume: 23318,\n  },\n  {\n    date: 1461866940000,\n    open: 50.23,\n    high: 50.26,\n    low: 50.185,\n    close: 50.22,\n    volume: 129826,\n  },\n  {\n    date: 1461867000000,\n    open: 50.22,\n    high: 50.26,\n    low: 50.215,\n    close: 50.245,\n    volume: 99951,\n  },\n  {\n    date: 1461867060000,\n    open: 50.2499,\n    high: 50.25,\n    low: 50.24,\n    close: 50.24,\n    volume: 32234,\n  },\n  {\n    date: 1461867120000,\n    open: 50.24,\n    high: 50.245,\n    low: 50.19,\n    close: 50.22,\n    volume: 55861,\n  },\n  {\n    date: 1461867180000,\n    open: 50.22,\n    high: 50.245,\n    low: 50.215,\n    close: 50.2301,\n    volume: 45346,\n  },\n  {\n    date: 1461867240000,\n    open: 50.23,\n    high: 50.25,\n    low: 50.22,\n    close: 50.24,\n    volume: 34317,\n  },\n  {\n    date: 1461867300000,\n    open: 50.23,\n    high: 50.235,\n    low: 50.21,\n    close: 50.23,\n    volume: 42900,\n  },\n  {\n    date: 1461867360000,\n    open: 50.235,\n    high: 50.25,\n    low: 50.22,\n    close: 50.235,\n    volume: 56868,\n  },\n  {\n    date: 1461867420000,\n    open: 50.2401,\n    high: 50.25,\n    low: 50.22,\n    close: 50.2201,\n    volume: 22535,\n  },\n  {\n    date: 1461867480000,\n    open: 50.22,\n    high: 50.24,\n    low: 50.2,\n    close: 50.23,\n    volume: 30410,\n  },\n  {\n    date: 1461867540000,\n    open: 50.2371,\n    high: 50.24,\n    low: 50.2,\n    close: 50.215,\n    volume: 43258,\n  },\n  {\n    date: 1461867600000,\n    open: 50.2259,\n    high: 50.23,\n    low: 50.2,\n    close: 50.2,\n    volume: 33955,\n  },\n  {\n    date: 1461867660000,\n    open: 50.2033,\n    high: 50.2033,\n    low: 50.155,\n    close: 50.155,\n    volume: 46794,\n  },\n  {\n    date: 1461867720000,\n    open: 50.155,\n    high: 50.18,\n    low: 50.14,\n    close: 50.145,\n    volume: 130878,\n  },\n  {\n    date: 1461867780000,\n    open: 50.14,\n    high: 50.16,\n    low: 50.1338,\n    close: 50.14,\n    volume: 57245,\n  },\n  {\n    date: 1461867840000,\n    open: 50.14,\n    high: 50.16,\n    low: 50.12,\n    close: 50.16,\n    volume: 50818,\n  },\n  {\n    date: 1461867900000,\n    open: 50.16,\n    high: 50.2368,\n    low: 50.15,\n    close: 50.23,\n    volume: 60481,\n  },\n  {\n    date: 1461867960000,\n    open: 50.235,\n    high: 50.235,\n    low: 50.18,\n    close: 50.19,\n    volume: 41654,\n  },\n  {\n    date: 1461868020000,\n    open: 50.19,\n    high: 50.22,\n    low: 50.185,\n    close: 50.21,\n    volume: 37632,\n  },\n  {\n    date: 1461868080000,\n    open: 50.205,\n    high: 50.225,\n    low: 50.205,\n    close: 50.225,\n    volume: 29662,\n  },\n  {\n    date: 1461868140000,\n    open: 50.224,\n    high: 50.25,\n    low: 50.22,\n    close: 50.2264,\n    volume: 56307,\n  },\n  {\n    date: 1461868200000,\n    open: 50.225,\n    high: 50.235,\n    low: 50.22,\n    close: 50.235,\n    volume: 49232,\n  },\n  {\n    date: 1461868260000,\n    open: 50.231,\n    high: 50.2377,\n    low: 50.21,\n    close: 50.21,\n    volume: 32028,\n  },\n  {\n    date: 1461868320000,\n    open: 50.21,\n    high: 50.22,\n    low: 50.17,\n    close: 50.17,\n    volume: 67681,\n  },\n  {\n    date: 1461868380000,\n    open: 50.17,\n    high: 50.18,\n    low: 50.16,\n    close: 50.165,\n    volume: 36089,\n  },\n  {\n    date: 1461868440000,\n    open: 50.165,\n    high: 50.17,\n    low: 50.14,\n    close: 50.145,\n    volume: 47563,\n  },\n  {\n    date: 1461868500000,\n    open: 50.145,\n    high: 50.16,\n    low: 50.14,\n    close: 50.16,\n    volume: 32011,\n  },\n  {\n    date: 1461868560000,\n    open: 50.1562,\n    high: 50.2,\n    low: 50.155,\n    close: 50.1895,\n    volume: 43954,\n  },\n  {\n    date: 1461868620000,\n    open: 50.18,\n    high: 50.185,\n    low: 50.13,\n    close: 50.13,\n    volume: 50706,\n  },\n  {\n    date: 1461868680000,\n    open: 50.13,\n    high: 50.14,\n    low: 50.08,\n    close: 50.11,\n    volume: 159732,\n  },\n  {\n    date: 1461868740000,\n    open: 50.11,\n    high: 50.12,\n    low: 50.1,\n    close: 50.1095,\n    volume: 45707,\n  },\n  {\n    date: 1461868800000,\n    open: 50.105,\n    high: 50.12,\n    low: 50.09,\n    close: 50.095,\n    volume: 57589,\n  },\n  {\n    date: 1461868860000,\n    open: 50.09,\n    high: 50.12,\n    low: 50.09,\n    close: 50.115,\n    volume: 47807,\n  },\n  {\n    date: 1461868920000,\n    open: 50.12,\n    high: 50.14,\n    low: 50.1,\n    close: 50.1015,\n    volume: 64173,\n  },\n  {\n    date: 1461868980000,\n    open: 50.11,\n    high: 50.15,\n    low: 50.09,\n    close: 50.15,\n    volume: 59761,\n  },\n  {\n    date: 1461869040000,\n    open: 50.145,\n    high: 50.16,\n    low: 50.13,\n    close: 50.13,\n    volume: 39159,\n  },\n  {\n    date: 1461869100000,\n    open: 50.135,\n    high: 50.14,\n    low: 50.09,\n    close: 50.095,\n    volume: 38707,\n  },\n  {\n    date: 1461869160000,\n    open: 50.09,\n    high: 50.09,\n    low: 50.05,\n    close: 50.07,\n    volume: 150765,\n  },\n  {\n    date: 1461869220000,\n    open: 50.075,\n    high: 50.0899,\n    low: 50.06,\n    close: 50.0638,\n    volume: 64144,\n  },\n  {\n    date: 1461869280000,\n    open: 50.07,\n    high: 50.08,\n    low: 50.045,\n    close: 50.0562,\n    volume: 106589,\n  },\n  {\n    date: 1461869340000,\n    open: 50.05,\n    high: 50.06,\n    low: 50.02,\n    close: 50.021,\n    volume: 123258,\n  },\n  {\n    date: 1461869400000,\n    open: 50.025,\n    high: 50.04,\n    low: 50.02,\n    close: 50.025,\n    volume: 51810,\n  },\n  {\n    date: 1461869460000,\n    open: 50.035,\n    high: 50.0372,\n    low: 50.01,\n    close: 50.02,\n    volume: 83725,\n  },\n  {\n    date: 1461869520000,\n    open: 50.01,\n    high: 50.02,\n    low: 49.99,\n    close: 50,\n    volume: 486148,\n  },\n  {\n    date: 1461869580000,\n    open: 49.993,\n    high: 50,\n    low: 49.96,\n    close: 49.975,\n    volume: 89504,\n  },\n  {\n    date: 1461869640000,\n    open: 49.9762,\n    high: 50.04,\n    low: 49.95,\n    close: 50.025,\n    volume: 147532,\n  },\n  {\n    date: 1461869700000,\n    open: 50.03,\n    high: 50.0599,\n    low: 50.02,\n    close: 50.045,\n    volume: 104896,\n  },\n  {\n    date: 1461869760000,\n    open: 50.04,\n    high: 50.05,\n    low: 50,\n    close: 50.003,\n    volume: 75353,\n  },\n  {\n    date: 1461869820000,\n    open: 50,\n    high: 50.04,\n    low: 49.98,\n    close: 50.04,\n    volume: 136096,\n  },\n  {\n    date: 1461869880000,\n    open: 50.045,\n    high: 50.09,\n    low: 50.04,\n    close: 50.085,\n    volume: 59466,\n  },\n  {\n    date: 1461869940000,\n    open: 50.085,\n    high: 50.11,\n    low: 50.05,\n    close: 50.05,\n    volume: 81348,\n  },\n  {\n    date: 1461870000000,\n    open: 50.0565,\n    high: 50.1,\n    low: 50.045,\n    close: 50.07,\n    volume: 87537,\n  },\n  {\n    date: 1461870060000,\n    open: 50.075,\n    high: 50.085,\n    low: 50.04,\n    close: 50.05,\n    volume: 94216,\n  },\n  {\n    date: 1461870120000,\n    open: 50.05,\n    high: 50.06,\n    low: 50.04,\n    close: 50.05,\n    volume: 36160,\n  },\n  {\n    date: 1461870180000,\n    open: 50.05,\n    high: 50.05,\n    low: 50.02,\n    close: 50.035,\n    volume: 59491,\n  },\n  {\n    date: 1461870240000,\n    open: 50.04,\n    high: 50.06,\n    low: 50.03,\n    close: 50.05,\n    volume: 97251,\n  },\n  {\n    date: 1461870300000,\n    open: 50.05,\n    high: 50.05,\n    low: 49.98,\n    close: 50.005,\n    volume: 110332,\n  },\n  {\n    date: 1461870360000,\n    open: 50.01,\n    high: 50.02,\n    low: 49.975,\n    close: 49.9801,\n    volume: 52853,\n  },\n  {\n    date: 1461870420000,\n    open: 49.985,\n    high: 49.99,\n    low: 49.94,\n    close: 49.95,\n    volume: 93732,\n  },\n  {\n    date: 1461870480000,\n    open: 49.96,\n    high: 49.98,\n    low: 49.945,\n    close: 49.975,\n    volume: 72064,\n  },\n  {\n    date: 1461870540000,\n    open: 49.9735,\n    high: 49.98,\n    low: 49.94,\n    close: 49.955,\n    volume: 132372,\n  },\n  {\n    date: 1461870600000,\n    open: 49.955,\n    high: 49.96,\n    low: 49.9,\n    close: 49.9,\n    volume: 134507,\n  },\n  {\n    date: 1461870660000,\n    open: 49.905,\n    high: 49.91,\n    low: 49.86,\n    close: 49.885,\n    volume: 129414,\n  },\n  {\n    date: 1461870720000,\n    open: 49.88,\n    high: 49.9,\n    low: 49.85,\n    close: 49.895,\n    volume: 118341,\n  },\n  {\n    date: 1461870780000,\n    open: 49.89,\n    high: 49.9,\n    low: 49.84,\n    close: 49.844,\n    volume: 62011,\n  },\n  {\n    date: 1461870840000,\n    open: 49.85,\n    high: 49.86,\n    low: 49.8,\n    close: 49.84,\n    volume: 118913,\n  },\n  {\n    date: 1461870900000,\n    open: 49.835,\n    high: 49.86,\n    low: 49.79,\n    close: 49.8,\n    volume: 184477,\n  },\n  {\n    date: 1461870960000,\n    open: 49.8,\n    high: 49.8,\n    low: 49.74,\n    close: 49.7713,\n    volume: 329813,\n  },\n  {\n    date: 1461871020000,\n    open: 49.78,\n    high: 49.78,\n    low: 49.74,\n    close: 49.755,\n    volume: 131549,\n  },\n  {\n    date: 1461871080000,\n    open: 49.76,\n    high: 49.79,\n    low: 49.75,\n    close: 49.77,\n    volume: 77775,\n  },\n  {\n    date: 1461871140000,\n    open: 49.77,\n    high: 49.78,\n    low: 49.67,\n    close: 49.68,\n    volume: 226597,\n  },\n  {\n    date: 1461871200000,\n    open: 49.68,\n    high: 49.7275,\n    low: 49.67,\n    close: 49.71,\n    volume: 90263,\n  },\n  {\n    date: 1461871260000,\n    open: 49.7,\n    high: 49.71,\n    low: 49.68,\n    close: 49.6806,\n    volume: 323146,\n  },\n  {\n    date: 1461871320000,\n    open: 49.685,\n    high: 49.69,\n    low: 49.67,\n    close: 49.67,\n    volume: 65815,\n  },\n  {\n    date: 1461871380000,\n    open: 49.6799,\n    high: 49.68,\n    low: 49.63,\n    close: 49.68,\n    volume: 467942,\n  },\n  {\n    date: 1461871440000,\n    open: 49.68,\n    high: 49.71,\n    low: 49.65,\n    close: 49.66,\n    volume: 182616,\n  },\n  {\n    date: 1461871500000,\n    open: 49.66,\n    high: 49.67,\n    low: 49.64,\n    close: 49.645,\n    volume: 154174,\n  },\n  {\n    date: 1461871560000,\n    open: 49.65,\n    high: 49.705,\n    low: 49.56,\n    close: 49.62,\n    volume: 461561,\n  },\n  {\n    date: 1461871620000,\n    open: 49.625,\n    high: 49.69,\n    low: 49.625,\n    close: 49.67,\n    volume: 137580,\n  },\n  {\n    date: 1461871680000,\n    open: 49.6799,\n    high: 49.71,\n    low: 49.645,\n    close: 49.695,\n    volume: 248029,\n  },\n  {\n    date: 1461871740000,\n    open: 49.695,\n    high: 49.71,\n    low: 49.65,\n    close: 49.66,\n    volume: 160612,\n  },\n  {\n    date: 1461871800000,\n    open: 49.66,\n    high: 49.69,\n    low: 49.595,\n    close: 49.63,\n    volume: 254745,\n  },\n  {\n    date: 1461871860000,\n    open: 49.63,\n    high: 49.71,\n    low: 49.6299,\n    close: 49.695,\n    volume: 228788,\n  },\n  {\n    date: 1461871920000,\n    open: 49.6999,\n    high: 49.7,\n    low: 49.6337,\n    close: 49.65,\n    volume: 286179,\n  },\n  {\n    date: 1461871980000,\n    open: 49.66,\n    high: 49.67,\n    low: 49.62,\n    close: 49.645,\n    volume: 113576,\n  },\n  {\n    date: 1461872040000,\n    open: 49.64,\n    high: 49.66,\n    low: 49.595,\n    close: 49.63,\n    volume: 164349,\n  },\n  {\n    date: 1461872100000,\n    open: 49.63,\n    high: 49.68,\n    low: 49.62,\n    close: 49.68,\n    volume: 254257,\n  },\n  {\n    date: 1461872160000,\n    open: 49.6701,\n    high: 49.72,\n    low: 49.67,\n    close: 49.72,\n    volume: 221103,\n  },\n  {\n    date: 1461872220000,\n    open: 49.715,\n    high: 49.77,\n    low: 49.71,\n    close: 49.74,\n    volume: 242301,\n  },\n  {\n    date: 1461872280000,\n    open: 49.735,\n    high: 49.75,\n    low: 49.655,\n    close: 49.7,\n    volume: 432658,\n  },\n  {\n    date: 1461872340000,\n    open: 49.7,\n    high: 49.76,\n    low: 49.695,\n    close: 49.76,\n    volume: 314640,\n  },\n  {\n    date: 1461872400000,\n    open: 49.76,\n    high: 49.79,\n    low: 49.75,\n    close: 49.78,\n    volume: 301311,\n  },\n  {\n    date: 1461872460000,\n    open: 49.7739,\n    high: 49.83,\n    low: 49.7739,\n    close: 49.83,\n    volume: 239502,\n  },\n  {\n    date: 1461872520000,\n    open: 49.8228,\n    high: 49.83,\n    low: 49.75,\n    close: 49.79,\n    volume: 176981,\n  },\n  {\n    date: 1461872580000,\n    open: 49.79,\n    high: 49.825,\n    low: 49.75,\n    close: 49.8,\n    volume: 250012,\n  },\n  {\n    date: 1461872640000,\n    open: 49.8,\n    high: 49.92,\n    low: 49.77,\n    close: 49.845,\n    volume: 417051,\n  },\n  {\n    date: 1461872700000,\n    open: 49.85,\n    high: 49.86,\n    low: 49.82,\n    close: 49.83,\n    volume: 186654,\n  },\n  {\n    date: 1461872760000,\n    open: 49.835,\n    high: 49.91,\n    low: 49.825,\n    close: 49.9,\n    volume: 283596,\n  },\n  {\n    date: 1461872820000,\n    open: 49.89,\n    high: 49.94,\n    low: 49.875,\n    close: 49.92,\n    volume: 435304,\n  },\n  {\n    date: 1461872880000,\n    open: 49.92,\n    high: 49.995,\n    low: 49.91,\n    close: 49.965,\n    volume: 309432,\n  },\n  {\n    date: 1461872940000,\n    open: 49.96,\n    high: 49.97,\n    low: 49.89,\n    close: 49.945,\n    volume: 513054,\n  },\n  {\n    date: 1461873000000,\n    open: 49.945,\n    high: 49.95,\n    low: 49.89,\n    close: 49.92,\n    volume: 312862,\n  },\n  {\n    date: 1461873060000,\n    open: 49.925,\n    high: 49.93,\n    low: 49.88,\n    close: 49.89,\n    volume: 316675,\n  },\n  {\n    date: 1461873120000,\n    open: 49.89,\n    high: 49.9,\n    low: 49.86,\n    close: 49.895,\n    volume: 399632,\n  },\n  {\n    date: 1461873180000,\n    open: 49.895,\n    high: 49.91,\n    low: 49.84,\n    close: 49.86,\n    volume: 327313,\n  },\n  {\n    date: 1461873240000,\n    open: 49.865,\n    high: 49.9,\n    low: 49.85,\n    close: 49.855,\n    volume: 278717,\n  },\n  {\n    date: 1461873300000,\n    open: 49.8599,\n    high: 49.87,\n    low: 49.82,\n    close: 49.865,\n    volume: 225020,\n  },\n  {\n    date: 1461873360000,\n    open: 49.86,\n    high: 49.8681,\n    low: 49.82,\n    close: 49.835,\n    volume: 293086,\n  },\n  {\n    date: 1461873420000,\n    open: 49.835,\n    high: 49.84,\n    low: 49.79,\n    close: 49.795,\n    volume: 264958,\n  },\n  {\n    date: 1461873480000,\n    open: 49.801,\n    high: 49.81,\n    low: 49.75,\n    close: 49.775,\n    volume: 311663,\n  },\n  {\n    date: 1461873540000,\n    open: 49.785,\n    high: 49.84,\n    low: 49.775,\n    close: 49.81,\n    volume: 399231,\n  },\n  {\n    date: 1461873600000,\n    open: 49.835,\n    high: 49.97,\n    low: 49.8,\n    close: 49.93,\n    volume: 2816676,\n  },\n  {\n    date: 1461936600000,\n    open: 49.35,\n    high: 49.45,\n    low: 49.35,\n    close: 49.418,\n    volume: 1387226,\n  },\n  {\n    date: 1461936660000,\n    open: 49.4299,\n    high: 50.03,\n    low: 49.41,\n    close: 50.01,\n    volume: 526715,\n  },\n  {\n    date: 1461936720000,\n    open: 50.01,\n    high: 50.02,\n    low: 49.66,\n    close: 49.67,\n    volume: 311338,\n  },\n  {\n    date: 1461936780000,\n    open: 49.68,\n    high: 49.68,\n    low: 49.51,\n    close: 49.58,\n    volume: 196149,\n  },\n  {\n    date: 1461936840000,\n    open: 49.57,\n    high: 49.77,\n    low: 49.57,\n    close: 49.73,\n    volume: 170026,\n  },\n  {\n    date: 1461936900000,\n    open: 49.731,\n    high: 49.79,\n    low: 49.68,\n    close: 49.7811,\n    volume: 90592,\n  },\n  {\n    date: 1461936960000,\n    open: 49.79,\n    high: 49.83,\n    low: 49.76,\n    close: 49.78,\n    volume: 169369,\n  },\n  {\n    date: 1461937020000,\n    open: 49.7701,\n    high: 49.845,\n    low: 49.7701,\n    close: 49.84,\n    volume: 199125,\n  },\n  {\n    date: 1461937080000,\n    open: 49.84,\n    high: 49.89,\n    low: 49.82,\n    close: 49.87,\n    volume: 197767,\n  },\n  {\n    date: 1461937140000,\n    open: 49.87,\n    high: 49.885,\n    low: 49.83,\n    close: 49.87,\n    volume: 198041,\n  },\n  {\n    date: 1461937200000,\n    open: 49.87,\n    high: 49.91,\n    low: 49.83,\n    close: 49.9,\n    volume: 215750,\n  },\n  {\n    date: 1461937260000,\n    open: 49.91,\n    high: 50.01,\n    low: 49.9,\n    close: 50.005,\n    volume: 224804,\n  },\n  {\n    date: 1461937320000,\n    open: 50.005,\n    high: 50.02,\n    low: 49.9,\n    close: 49.93,\n    volume: 265413,\n  },\n  {\n    date: 1461937380000,\n    open: 49.93,\n    high: 50,\n    low: 49.905,\n    close: 49.96,\n    volume: 351369,\n  },\n  {\n    date: 1461937440000,\n    open: 49.96,\n    high: 50.04,\n    low: 49.96,\n    close: 50.01,\n    volume: 258349,\n  },\n  {\n    date: 1461937500000,\n    open: 50.01,\n    high: 50.1,\n    low: 50,\n    close: 50.015,\n    volume: 202308,\n  },\n  {\n    date: 1461937560000,\n    open: 50.01,\n    high: 50.06,\n    low: 49.99,\n    close: 50.05,\n    volume: 177037,\n  },\n  {\n    date: 1461937620000,\n    open: 50.055,\n    high: 50.055,\n    low: 49.97,\n    close: 49.97,\n    volume: 236185,\n  },\n  {\n    date: 1461937680000,\n    open: 49.97,\n    high: 49.975,\n    low: 49.9001,\n    close: 49.93,\n    volume: 152517,\n  },\n  {\n    date: 1461937740000,\n    open: 49.925,\n    high: 49.94,\n    low: 49.81,\n    close: 49.84,\n    volume: 163153,\n  },\n  {\n    date: 1461937800000,\n    open: 49.8599,\n    high: 49.93,\n    low: 49.85,\n    close: 49.8699,\n    volume: 100197,\n  },\n  {\n    date: 1461937860000,\n    open: 49.86,\n    high: 49.92,\n    low: 49.775,\n    close: 49.82,\n    volume: 200154,\n  },\n  {\n    date: 1461937920000,\n    open: 49.8299,\n    high: 49.8299,\n    low: 49.69,\n    close: 49.74,\n    volume: 128728,\n  },\n  {\n    date: 1461937980000,\n    open: 49.735,\n    high: 49.82,\n    low: 49.7302,\n    close: 49.763,\n    volume: 100055,\n  },\n  {\n    date: 1461938040000,\n    open: 49.76,\n    high: 49.8,\n    low: 49.7528,\n    close: 49.795,\n    volume: 95844,\n  },\n  {\n    date: 1461938100000,\n    open: 49.795,\n    high: 49.9,\n    low: 49.79,\n    close: 49.885,\n    volume: 122257,\n  },\n  {\n    date: 1461938160000,\n    open: 49.8801,\n    high: 49.92,\n    low: 49.85,\n    close: 49.865,\n    volume: 112947,\n  },\n  {\n    date: 1461938220000,\n    open: 49.865,\n    high: 49.9,\n    low: 49.81,\n    close: 49.9,\n    volume: 165915,\n  },\n  {\n    date: 1461938280000,\n    open: 49.89,\n    high: 49.97,\n    low: 49.89,\n    close: 49.895,\n    volume: 142760,\n  },\n  {\n    date: 1461938340000,\n    open: 49.9,\n    high: 49.905,\n    low: 49.825,\n    close: 49.85,\n    volume: 83922,\n  },\n  {\n    date: 1461938400000,\n    open: 49.85,\n    high: 49.8653,\n    low: 49.79,\n    close: 49.81,\n    volume: 68251,\n  },\n  {\n    date: 1461938460000,\n    open: 49.81,\n    high: 49.83,\n    low: 49.77,\n    close: 49.81,\n    volume: 160381,\n  },\n  {\n    date: 1461938520000,\n    open: 49.81,\n    high: 49.81,\n    low: 49.7,\n    close: 49.71,\n    volume: 120270,\n  },\n  {\n    date: 1461938580000,\n    open: 49.7001,\n    high: 49.82,\n    low: 49.69,\n    close: 49.79,\n    volume: 104701,\n  },\n  {\n    date: 1461938640000,\n    open: 49.785,\n    high: 49.91,\n    low: 49.77,\n    close: 49.91,\n    volume: 181987,\n  },\n  {\n    date: 1461938700000,\n    open: 49.9,\n    high: 49.94,\n    low: 49.87,\n    close: 49.91,\n    volume: 90937,\n  },\n  {\n    date: 1461938760000,\n    open: 49.91,\n    high: 49.92,\n    low: 49.84,\n    close: 49.84,\n    volume: 95593,\n  },\n  {\n    date: 1461938820000,\n    open: 49.835,\n    high: 49.89,\n    low: 49.83,\n    close: 49.88,\n    volume: 58929,\n  },\n  {\n    date: 1461938880000,\n    open: 49.88,\n    high: 49.895,\n    low: 49.785,\n    close: 49.895,\n    volume: 68370,\n  },\n  {\n    date: 1461938940000,\n    open: 49.89,\n    high: 49.92,\n    low: 49.86,\n    close: 49.86,\n    volume: 78053,\n  },\n  {\n    date: 1461939000000,\n    open: 49.865,\n    high: 49.895,\n    low: 49.86,\n    close: 49.88,\n    volume: 94555,\n  },\n  {\n    date: 1461939060000,\n    open: 49.885,\n    high: 49.97,\n    low: 49.88,\n    close: 49.9475,\n    volume: 163396,\n  },\n  {\n    date: 1461939120000,\n    open: 49.95,\n    high: 49.97,\n    low: 49.94,\n    close: 49.95,\n    volume: 102980,\n  },\n  {\n    date: 1461939180000,\n    open: 49.94,\n    high: 49.97,\n    low: 49.83,\n    close: 49.845,\n    volume: 138107,\n  },\n  {\n    date: 1461939240000,\n    open: 49.85,\n    high: 49.905,\n    low: 49.82,\n    close: 49.9,\n    volume: 114194,\n  },\n  {\n    date: 1461939300000,\n    open: 49.91,\n    high: 49.92,\n    low: 49.8,\n    close: 49.82,\n    volume: 105946,\n  },\n  {\n    date: 1461939360000,\n    open: 49.825,\n    high: 49.825,\n    low: 49.73,\n    close: 49.74,\n    volume: 121197,\n  },\n  {\n    date: 1461939420000,\n    open: 49.745,\n    high: 49.79,\n    low: 49.745,\n    close: 49.78,\n    volume: 93801,\n  },\n  {\n    date: 1461939480000,\n    open: 49.78,\n    high: 49.78,\n    low: 49.74,\n    close: 49.75,\n    volume: 116580,\n  },\n  {\n    date: 1461939540000,\n    open: 49.75,\n    high: 49.75,\n    low: 49.68,\n    close: 49.69,\n    volume: 174268,\n  },\n  {\n    date: 1461939600000,\n    open: 49.685,\n    high: 49.74,\n    low: 49.66,\n    close: 49.67,\n    volume: 124858,\n  },\n  {\n    date: 1461939660000,\n    open: 49.6725,\n    high: 49.68,\n    low: 49.64,\n    close: 49.66,\n    volume: 146532,\n  },\n  {\n    date: 1461939720000,\n    open: 49.665,\n    high: 49.67,\n    low: 49.5901,\n    close: 49.6,\n    volume: 89172,\n  },\n  {\n    date: 1461939780000,\n    open: 49.6,\n    high: 49.71,\n    low: 49.56,\n    close: 49.6956,\n    volume: 164944,\n  },\n  {\n    date: 1461939840000,\n    open: 49.7,\n    high: 49.78,\n    low: 49.67,\n    close: 49.7709,\n    volume: 118238,\n  },\n  {\n    date: 1461939900000,\n    open: 49.78,\n    high: 49.78,\n    low: 49.72,\n    close: 49.72,\n    volume: 102968,\n  },\n  {\n    date: 1461939960000,\n    open: 49.72,\n    high: 49.73,\n    low: 49.63,\n    close: 49.65,\n    volume: 68897,\n  },\n  {\n    date: 1461940020000,\n    open: 49.66,\n    high: 49.73,\n    low: 49.62,\n    close: 49.64,\n    volume: 139744,\n  },\n  {\n    date: 1461940080000,\n    open: 49.6399,\n    high: 49.655,\n    low: 49.565,\n    close: 49.63,\n    volume: 113362,\n  },\n  {\n    date: 1461940140000,\n    open: 49.63,\n    high: 49.73,\n    low: 49.63,\n    close: 49.72,\n    volume: 133401,\n  },\n  {\n    date: 1461940200000,\n    open: 49.72,\n    high: 49.74,\n    low: 49.665,\n    close: 49.71,\n    volume: 134562,\n  },\n  {\n    date: 1461940260000,\n    open: 49.72,\n    high: 49.77,\n    low: 49.7,\n    close: 49.76,\n    volume: 124672,\n  },\n  {\n    date: 1461940320000,\n    open: 49.75,\n    high: 49.75,\n    low: 49.71,\n    close: 49.725,\n    volume: 97009,\n  },\n  {\n    date: 1461940380000,\n    open: 49.705,\n    high: 49.76,\n    low: 49.69,\n    close: 49.7329,\n    volume: 110163,\n  },\n  {\n    date: 1461940440000,\n    open: 49.735,\n    high: 49.765,\n    low: 49.72,\n    close: 49.72,\n    volume: 94168,\n  },\n  {\n    date: 1461940500000,\n    open: 49.725,\n    high: 49.7756,\n    low: 49.72,\n    close: 49.7756,\n    volume: 103340,\n  },\n  {\n    date: 1461940560000,\n    open: 49.77,\n    high: 49.86,\n    low: 49.76,\n    close: 49.8399,\n    volume: 156331,\n  },\n  {\n    date: 1461940620000,\n    open: 49.835,\n    high: 49.9,\n    low: 49.83,\n    close: 49.85,\n    volume: 136792,\n  },\n  {\n    date: 1461940680000,\n    open: 49.85,\n    high: 49.97,\n    low: 49.84,\n    close: 49.94,\n    volume: 180050,\n  },\n  {\n    date: 1461940740000,\n    open: 49.94,\n    high: 49.95,\n    low: 49.92,\n    close: 49.94,\n    volume: 138543,\n  },\n  {\n    date: 1461940800000,\n    open: 49.94,\n    high: 49.95,\n    low: 49.9,\n    close: 49.95,\n    volume: 76543,\n  },\n  {\n    date: 1461940860000,\n    open: 49.95,\n    high: 49.985,\n    low: 49.91,\n    close: 49.9715,\n    volume: 263974,\n  },\n  {\n    date: 1461940920000,\n    open: 49.975,\n    high: 49.98,\n    low: 49.92,\n    close: 49.935,\n    volume: 147240,\n  },\n  {\n    date: 1461940980000,\n    open: 49.93,\n    high: 49.965,\n    low: 49.92,\n    close: 49.93,\n    volume: 124468,\n  },\n  {\n    date: 1461941040000,\n    open: 49.94,\n    high: 49.94,\n    low: 49.865,\n    close: 49.91,\n    volume: 141272,\n  },\n  {\n    date: 1461941100000,\n    open: 49.91,\n    high: 49.97,\n    low: 49.905,\n    close: 49.96,\n    volume: 128975,\n  },\n  {\n    date: 1461941160000,\n    open: 49.965,\n    high: 50.02,\n    low: 49.95,\n    close: 49.98,\n    volume: 319403,\n  },\n  {\n    date: 1461941220000,\n    open: 49.99,\n    high: 50.065,\n    low: 49.98,\n    close: 50.05,\n    volume: 264452,\n  },\n  {\n    date: 1461941280000,\n    open: 50.05,\n    high: 50.075,\n    low: 50.03,\n    close: 50.06,\n    volume: 369081,\n  },\n  {\n    date: 1461941340000,\n    open: 50.0595,\n    high: 50.1,\n    low: 50.04,\n    close: 50.0425,\n    volume: 177629,\n  },\n  {\n    date: 1461941400000,\n    open: 50.0499,\n    high: 50.09,\n    low: 50.04,\n    close: 50.06,\n    volume: 112670,\n  },\n  {\n    date: 1461941460000,\n    open: 50.07,\n    high: 50.08,\n    low: 50.025,\n    close: 50.03,\n    volume: 348865,\n  },\n  {\n    date: 1461941520000,\n    open: 50.02,\n    high: 50.03,\n    low: 49.91,\n    close: 49.91,\n    volume: 163438,\n  },\n  {\n    date: 1461941580000,\n    open: 49.913,\n    high: 49.97,\n    low: 49.9,\n    close: 49.9,\n    volume: 151751,\n  },\n  {\n    date: 1461941640000,\n    open: 49.9,\n    high: 49.93,\n    low: 49.84,\n    close: 49.85,\n    volume: 138713,\n  },\n  {\n    date: 1461941700000,\n    open: 49.84,\n    high: 49.87,\n    low: 49.81,\n    close: 49.86,\n    volume: 85222,\n  },\n  {\n    date: 1461941760000,\n    open: 49.86,\n    high: 49.92,\n    low: 49.85,\n    close: 49.89,\n    volume: 193365,\n  },\n  {\n    date: 1461941820000,\n    open: 49.9,\n    high: 49.9,\n    low: 49.855,\n    close: 49.88,\n    volume: 150885,\n  },\n  {\n    date: 1461941880000,\n    open: 49.875,\n    high: 49.91,\n    low: 49.86,\n    close: 49.9,\n    volume: 189905,\n  },\n  {\n    date: 1461941940000,\n    open: 49.895,\n    high: 49.92,\n    low: 49.88,\n    close: 49.894,\n    volume: 63803,\n  },\n  {\n    date: 1461942000000,\n    open: 49.9,\n    high: 49.95,\n    low: 49.895,\n    close: 49.93,\n    volume: 97198,\n  },\n  {\n    date: 1461942060000,\n    open: 49.92,\n    high: 49.95,\n    low: 49.91,\n    close: 49.9443,\n    volume: 82026,\n  },\n  {\n    date: 1461942120000,\n    open: 49.95,\n    high: 49.96,\n    low: 49.93,\n    close: 49.945,\n    volume: 111763,\n  },\n  {\n    date: 1461942180000,\n    open: 49.95,\n    high: 49.96,\n    low: 49.8,\n    close: 49.83,\n    volume: 124397,\n  },\n  {\n    date: 1461942240000,\n    open: 49.84,\n    high: 49.87,\n    low: 49.82,\n    close: 49.83,\n    volume: 100596,\n  },\n  {\n    date: 1461942300000,\n    open: 49.83,\n    high: 49.89,\n    low: 49.83,\n    close: 49.845,\n    volume: 50490,\n  },\n  {\n    date: 1461942360000,\n    open: 49.845,\n    high: 49.89,\n    low: 49.84,\n    close: 49.885,\n    volume: 55919,\n  },\n  {\n    date: 1461942420000,\n    open: 49.89,\n    high: 49.92,\n    low: 49.87,\n    close: 49.875,\n    volume: 68317,\n  },\n  {\n    date: 1461942480000,\n    open: 49.875,\n    high: 49.92,\n    low: 49.8701,\n    close: 49.905,\n    volume: 47920,\n  },\n  {\n    date: 1461942540000,\n    open: 49.905,\n    high: 49.91,\n    low: 49.85,\n    close: 49.865,\n    volume: 51570,\n  },\n  {\n    date: 1461942600000,\n    open: 49.8665,\n    high: 49.92,\n    low: 49.865,\n    close: 49.91,\n    volume: 74049,\n  },\n  {\n    date: 1461942660000,\n    open: 49.91,\n    high: 49.92,\n    low: 49.87,\n    close: 49.885,\n    volume: 96474,\n  },\n  {\n    date: 1461942720000,\n    open: 49.89,\n    high: 49.91,\n    low: 49.88,\n    close: 49.89,\n    volume: 126110,\n  },\n  {\n    date: 1461942780000,\n    open: 49.9,\n    high: 49.91,\n    low: 49.875,\n    close: 49.905,\n    volume: 57802,\n  },\n  {\n    date: 1461942840000,\n    open: 49.905,\n    high: 49.94,\n    low: 49.9,\n    close: 49.94,\n    volume: 91013,\n  },\n  {\n    date: 1461942900000,\n    open: 49.935,\n    high: 49.97,\n    low: 49.93,\n    close: 49.9499,\n    volume: 107649,\n  },\n  {\n    date: 1461942960000,\n    open: 49.945,\n    high: 49.95,\n    low: 49.8741,\n    close: 49.8799,\n    volume: 74571,\n  },\n  {\n    date: 1461943020000,\n    open: 49.879,\n    high: 49.94,\n    low: 49.87,\n    close: 49.885,\n    volume: 173823,\n  },\n  {\n    date: 1461943080000,\n    open: 49.88,\n    high: 49.9,\n    low: 49.84,\n    close: 49.875,\n    volume: 118725,\n  },\n  {\n    date: 1461943140000,\n    open: 49.88,\n    high: 49.92,\n    low: 49.87,\n    close: 49.92,\n    volume: 174945,\n  },\n  {\n    date: 1461943200000,\n    open: 49.915,\n    high: 49.92,\n    low: 49.84,\n    close: 49.88,\n    volume: 90880,\n  },\n  {\n    date: 1461943260000,\n    open: 49.88,\n    high: 49.93,\n    low: 49.87,\n    close: 49.92,\n    volume: 182376,\n  },\n  {\n    date: 1461943320000,\n    open: 49.915,\n    high: 49.93,\n    low: 49.89,\n    close: 49.91,\n    volume: 167685,\n  },\n  {\n    date: 1461943380000,\n    open: 49.905,\n    high: 49.91,\n    low: 49.89,\n    close: 49.9,\n    volume: 140784,\n  },\n  {\n    date: 1461943440000,\n    open: 49.89,\n    high: 49.92,\n    low: 49.89,\n    close: 49.91,\n    volume: 58280,\n  },\n  {\n    date: 1461943500000,\n    open: 49.915,\n    high: 49.92,\n    low: 49.845,\n    close: 49.855,\n    volume: 114051,\n  },\n  {\n    date: 1461943560000,\n    open: 49.87,\n    high: 49.9,\n    low: 49.86,\n    close: 49.88,\n    volume: 62409,\n  },\n  {\n    date: 1461943620000,\n    open: 49.88,\n    high: 49.91,\n    low: 49.84,\n    close: 49.845,\n    volume: 102269,\n  },\n  {\n    date: 1461943680000,\n    open: 49.85,\n    high: 49.9,\n    low: 49.85,\n    close: 49.9,\n    volume: 58846,\n  },\n  {\n    date: 1461943740000,\n    open: 49.895,\n    high: 49.9,\n    low: 49.87,\n    close: 49.88,\n    volume: 85893,\n  },\n  {\n    date: 1461943800000,\n    open: 49.86,\n    high: 49.87,\n    low: 49.8,\n    close: 49.82,\n    volume: 159479,\n  },\n  {\n    date: 1461943860000,\n    open: 49.82,\n    high: 49.82,\n    low: 49.79,\n    close: 49.8,\n    volume: 115453,\n  },\n  {\n    date: 1461943920000,\n    open: 49.81,\n    high: 49.81,\n    low: 49.76,\n    close: 49.77,\n    volume: 96813,\n  },\n  {\n    date: 1461943980000,\n    open: 49.765,\n    high: 49.8,\n    low: 49.75,\n    close: 49.76,\n    volume: 52387,\n  },\n  {\n    date: 1461944040000,\n    open: 49.75,\n    high: 49.79,\n    low: 49.75,\n    close: 49.78,\n    volume: 66012,\n  },\n  {\n    date: 1461944100000,\n    open: 49.7743,\n    high: 49.84,\n    low: 49.77,\n    close: 49.81,\n    volume: 125751,\n  },\n  {\n    date: 1461944160000,\n    open: 49.81,\n    high: 49.82,\n    low: 49.77,\n    close: 49.77,\n    volume: 82283,\n  },\n  {\n    date: 1461944220000,\n    open: 49.77,\n    high: 49.78,\n    low: 49.745,\n    close: 49.775,\n    volume: 132913,\n  },\n  {\n    date: 1461944280000,\n    open: 49.78,\n    high: 49.8176,\n    low: 49.77,\n    close: 49.78,\n    volume: 75727,\n  },\n  {\n    date: 1461944340000,\n    open: 49.785,\n    high: 49.81,\n    low: 49.775,\n    close: 49.785,\n    volume: 73941,\n  },\n  {\n    date: 1461944400000,\n    open: 49.785,\n    high: 49.81,\n    low: 49.76,\n    close: 49.8,\n    volume: 113801,\n  },\n  {\n    date: 1461944460000,\n    open: 49.791,\n    high: 49.795,\n    low: 49.745,\n    close: 49.75,\n    volume: 123932,\n  },\n  {\n    date: 1461944520000,\n    open: 49.755,\n    high: 49.805,\n    low: 49.75,\n    close: 49.795,\n    volume: 55178,\n  },\n  {\n    date: 1461944580000,\n    open: 49.7935,\n    high: 49.81,\n    low: 49.75,\n    close: 49.7601,\n    volume: 110463,\n  },\n  {\n    date: 1461944640000,\n    open: 49.769,\n    high: 49.8,\n    low: 49.75,\n    close: 49.795,\n    volume: 63646,\n  },\n  {\n    date: 1461944700000,\n    open: 49.8,\n    high: 49.805,\n    low: 49.7425,\n    close: 49.77,\n    volume: 133547,\n  },\n  {\n    date: 1461944760000,\n    open: 49.7742,\n    high: 49.83,\n    low: 49.76,\n    close: 49.79,\n    volume: 125299,\n  },\n  {\n    date: 1461944820000,\n    open: 49.795,\n    high: 49.795,\n    low: 49.74,\n    close: 49.76,\n    volume: 165034,\n  },\n  {\n    date: 1461944880000,\n    open: 49.76,\n    high: 49.81,\n    low: 49.73,\n    close: 49.8,\n    volume: 142208,\n  },\n  {\n    date: 1461944940000,\n    open: 49.81,\n    high: 49.8171,\n    low: 49.78,\n    close: 49.805,\n    volume: 68582,\n  },\n  {\n    date: 1461945000000,\n    open: 49.81,\n    high: 49.838,\n    low: 49.8,\n    close: 49.83,\n    volume: 81295,\n  },\n  {\n    date: 1461945060000,\n    open: 49.83,\n    high: 49.835,\n    low: 49.79,\n    close: 49.82,\n    volume: 95238,\n  },\n  {\n    date: 1461945120000,\n    open: 49.82,\n    high: 49.9,\n    low: 49.8,\n    close: 49.89,\n    volume: 143967,\n  },\n  {\n    date: 1461945180000,\n    open: 49.895,\n    high: 49.9,\n    low: 49.85,\n    close: 49.88,\n    volume: 274013,\n  },\n  {\n    date: 1461945240000,\n    open: 49.88,\n    high: 49.92,\n    low: 49.84,\n    close: 49.88,\n    volume: 118868,\n  },\n  {\n    date: 1461945300000,\n    open: 49.885,\n    high: 49.89,\n    low: 49.83,\n    close: 49.83,\n    volume: 95868,\n  },\n  {\n    date: 1461945360000,\n    open: 49.835,\n    high: 49.88,\n    low: 49.815,\n    close: 49.875,\n    volume: 79386,\n  },\n  {\n    date: 1461945420000,\n    open: 49.875,\n    high: 49.9,\n    low: 49.845,\n    close: 49.855,\n    volume: 140067,\n  },\n  {\n    date: 1461945480000,\n    open: 49.86,\n    high: 49.9,\n    low: 49.86,\n    close: 49.89,\n    volume: 36490,\n  },\n  {\n    date: 1461945540000,\n    open: 49.8991,\n    high: 49.9,\n    low: 49.87,\n    close: 49.9,\n    volume: 42814,\n  },\n  {\n    date: 1461945600000,\n    open: 49.9,\n    high: 49.91,\n    low: 49.87,\n    close: 49.8865,\n    volume: 59328,\n  },\n  {\n    date: 1461945660000,\n    open: 49.875,\n    high: 49.92,\n    low: 49.86,\n    close: 49.91,\n    volume: 68964,\n  },\n  {\n    date: 1461945720000,\n    open: 49.91,\n    high: 49.94,\n    low: 49.885,\n    close: 49.925,\n    volume: 99796,\n  },\n  {\n    date: 1461945780000,\n    open: 49.9285,\n    high: 49.945,\n    low: 49.91,\n    close: 49.92,\n    volume: 84886,\n  },\n  {\n    date: 1461945840000,\n    open: 49.92,\n    high: 49.93,\n    low: 49.91,\n    close: 49.921,\n    volume: 30362,\n  },\n  {\n    date: 1461945900000,\n    open: 49.9295,\n    high: 49.95,\n    low: 49.9,\n    close: 49.95,\n    volume: 36497,\n  },\n  {\n    date: 1461945960000,\n    open: 49.93,\n    high: 49.95,\n    low: 49.92,\n    close: 49.93,\n    volume: 54169,\n  },\n  {\n    date: 1461946020000,\n    open: 49.9365,\n    high: 49.99,\n    low: 49.93,\n    close: 49.98,\n    volume: 79203,\n  },\n  {\n    date: 1461946080000,\n    open: 49.98,\n    high: 50.02,\n    low: 49.97,\n    close: 50.005,\n    volume: 140715,\n  },\n  {\n    date: 1461946140000,\n    open: 50,\n    high: 50.005,\n    low: 49.96,\n    close: 49.975,\n    volume: 51806,\n  },\n  {\n    date: 1461946200000,\n    open: 49.97,\n    high: 49.98,\n    low: 49.93,\n    close: 49.97,\n    volume: 52951,\n  },\n  {\n    date: 1461946260000,\n    open: 49.96,\n    high: 49.97,\n    low: 49.945,\n    close: 49.96,\n    volume: 99087,\n  },\n  {\n    date: 1461946320000,\n    open: 49.96,\n    high: 49.97,\n    low: 49.91,\n    close: 49.94,\n    volume: 47486,\n  },\n  {\n    date: 1461946380000,\n    open: 49.94,\n    high: 49.95,\n    low: 49.91,\n    close: 49.92,\n    volume: 22154,\n  },\n  {\n    date: 1461946440000,\n    open: 49.91,\n    high: 49.94,\n    low: 49.9,\n    close: 49.935,\n    volume: 34510,\n  },\n  {\n    date: 1461946500000,\n    open: 49.93,\n    high: 49.94,\n    low: 49.84,\n    close: 49.85,\n    volume: 133807,\n  },\n  {\n    date: 1461946560000,\n    open: 49.84,\n    high: 49.935,\n    low: 49.83,\n    close: 49.93,\n    volume: 133528,\n  },\n  {\n    date: 1461946620000,\n    open: 49.92,\n    high: 49.97,\n    low: 49.92,\n    close: 49.9546,\n    volume: 77671,\n  },\n  {\n    date: 1461946680000,\n    open: 49.955,\n    high: 49.99,\n    low: 49.935,\n    close: 49.98,\n    volume: 79088,\n  },\n  {\n    date: 1461946740000,\n    open: 49.9701,\n    high: 50.005,\n    low: 49.955,\n    close: 50,\n    volume: 29000,\n  },\n  {\n    date: 1461946800000,\n    open: 50.0065,\n    high: 50.035,\n    low: 49.98,\n    close: 50.01,\n    volume: 104832,\n  },\n  {\n    date: 1461946860000,\n    open: 50.015,\n    high: 50.0499,\n    low: 50.0101,\n    close: 50.035,\n    volume: 99183,\n  },\n  {\n    date: 1461946920000,\n    open: 50.035,\n    high: 50.07,\n    low: 50.025,\n    close: 50.07,\n    volume: 54127,\n  },\n  {\n    date: 1461946980000,\n    open: 50.075,\n    high: 50.075,\n    low: 50.034,\n    close: 50.04,\n    volume: 79489,\n  },\n  {\n    date: 1461947040000,\n    open: 50.05,\n    high: 50.06,\n    low: 50.02,\n    close: 50.03,\n    volume: 38547,\n  },\n  {\n    date: 1461947100000,\n    open: 50.03,\n    high: 50.04,\n    low: 49.995,\n    close: 50,\n    volume: 92969,\n  },\n  {\n    date: 1461947160000,\n    open: 50.005,\n    high: 50.01,\n    low: 49.96,\n    close: 50,\n    volume: 89250,\n  },\n  {\n    date: 1461947220000,\n    open: 50,\n    high: 50.01,\n    low: 49.98,\n    close: 49.98,\n    volume: 31219,\n  },\n  {\n    date: 1461947280000,\n    open: 49.985,\n    high: 50.02,\n    low: 49.98,\n    close: 50.005,\n    volume: 47515,\n  },\n  {\n    date: 1461947340000,\n    open: 50.005,\n    high: 50.01,\n    low: 49.95,\n    close: 49.9501,\n    volume: 28363,\n  },\n  {\n    date: 1461947400000,\n    open: 49.95,\n    high: 49.98,\n    low: 49.93,\n    close: 49.96,\n    volume: 56381,\n  },\n  {\n    date: 1461947460000,\n    open: 49.97,\n    high: 49.97,\n    low: 49.92,\n    close: 49.93,\n    volume: 47276,\n  },\n  {\n    date: 1461947520000,\n    open: 49.93,\n    high: 49.955,\n    low: 49.9,\n    close: 49.9,\n    volume: 62762,\n  },\n  {\n    date: 1461947580000,\n    open: 49.909,\n    high: 49.95,\n    low: 49.9,\n    close: 49.9336,\n    volume: 29240,\n  },\n  {\n    date: 1461947640000,\n    open: 49.9372,\n    high: 49.96,\n    low: 49.93,\n    close: 49.948,\n    volume: 68407,\n  },\n  {\n    date: 1461947700000,\n    open: 49.945,\n    high: 49.98,\n    low: 49.935,\n    close: 49.965,\n    volume: 51583,\n  },\n  {\n    date: 1461947760000,\n    open: 49.965,\n    high: 49.975,\n    low: 49.92,\n    close: 49.92,\n    volume: 29182,\n  },\n  {\n    date: 1461947820000,\n    open: 49.93,\n    high: 49.98,\n    low: 49.92,\n    close: 49.975,\n    volume: 111894,\n  },\n  {\n    date: 1461947880000,\n    open: 49.97,\n    high: 50.005,\n    low: 49.965,\n    close: 50.005,\n    volume: 102501,\n  },\n  {\n    date: 1461947940000,\n    open: 50.0099,\n    high: 50.07,\n    low: 50.0001,\n    close: 50.005,\n    volume: 141342,\n  },\n  {\n    date: 1461948000000,\n    open: 50.015,\n    high: 50.0199,\n    low: 49.96,\n    close: 49.985,\n    volume: 54416,\n  },\n  {\n    date: 1461948060000,\n    open: 49.985,\n    high: 50.005,\n    low: 49.96,\n    close: 49.97,\n    volume: 90262,\n  },\n  {\n    date: 1461948120000,\n    open: 49.965,\n    high: 50.01,\n    low: 49.96,\n    close: 49.99,\n    volume: 73404,\n  },\n  {\n    date: 1461948180000,\n    open: 49.995,\n    high: 50.005,\n    low: 49.96,\n    close: 49.985,\n    volume: 136687,\n  },\n  {\n    date: 1461948240000,\n    open: 49.985,\n    high: 50.02,\n    low: 49.97,\n    close: 49.99,\n    volume: 108807,\n  },\n  {\n    date: 1461948300000,\n    open: 49.9963,\n    high: 50.01,\n    low: 49.98,\n    close: 49.99,\n    volume: 48222,\n  },\n  {\n    date: 1461948360000,\n    open: 49.995,\n    high: 50.03,\n    low: 49.99,\n    close: 50.025,\n    volume: 86664,\n  },\n  {\n    date: 1461948420000,\n    open: 50.026,\n    high: 50.03,\n    low: 49.98,\n    close: 49.9838,\n    volume: 65418,\n  },\n  {\n    date: 1461948480000,\n    open: 49.98,\n    high: 50.03,\n    low: 49.97,\n    close: 50.025,\n    volume: 48791,\n  },\n  {\n    date: 1461948540000,\n    open: 50.03,\n    high: 50.03,\n    low: 50.01,\n    close: 50.025,\n    volume: 21000,\n  },\n  {\n    date: 1461948600000,\n    open: 50.02,\n    high: 50.03,\n    low: 49.98,\n    close: 50.0136,\n    volume: 55789,\n  },\n  {\n    date: 1461948660000,\n    open: 50.025,\n    high: 50.035,\n    low: 49.99,\n    close: 50,\n    volume: 67724,\n  },\n  {\n    date: 1461948720000,\n    open: 50,\n    high: 50.02,\n    low: 49.99,\n    close: 49.99,\n    volume: 72739,\n  },\n  {\n    date: 1461948780000,\n    open: 49.99,\n    high: 49.995,\n    low: 49.94,\n    close: 49.985,\n    volume: 93933,\n  },\n  {\n    date: 1461948840000,\n    open: 49.99,\n    high: 50.02,\n    low: 49.98,\n    close: 50.01,\n    volume: 117548,\n  },\n  {\n    date: 1461948900000,\n    open: 50.01,\n    high: 50.03,\n    low: 50,\n    close: 50.015,\n    volume: 43516,\n  },\n  {\n    date: 1461948960000,\n    open: 50.015,\n    high: 50.02,\n    low: 49.99,\n    close: 50.005,\n    volume: 69207,\n  },\n  {\n    date: 1461949020000,\n    open: 50.0001,\n    high: 50.02,\n    low: 50,\n    close: 50,\n    volume: 83415,\n  },\n  {\n    date: 1461949080000,\n    open: 50.005,\n    high: 50.015,\n    low: 50,\n    close: 50,\n    volume: 70883,\n  },\n  {\n    date: 1461949140000,\n    open: 50.009,\n    high: 50.01,\n    low: 49.97,\n    close: 49.985,\n    volume: 172680,\n  },\n  {\n    date: 1461949200000,\n    open: 49.985,\n    high: 50,\n    low: 49.982,\n    close: 49.982,\n    volume: 25599,\n  },\n  {\n    date: 1461949260000,\n    open: 49.9865,\n    high: 49.99,\n    low: 49.92,\n    close: 49.965,\n    volume: 152720,\n  },\n  {\n    date: 1461949320000,\n    open: 49.965,\n    high: 50.02,\n    low: 49.965,\n    close: 49.985,\n    volume: 91256,\n  },\n  {\n    date: 1461949380000,\n    open: 50.015,\n    high: 50.02,\n    low: 49.985,\n    close: 50.0052,\n    volume: 30968,\n  },\n  {\n    date: 1461949440000,\n    open: 50.005,\n    high: 50.01,\n    low: 50,\n    close: 50.005,\n    volume: 19010,\n  },\n  {\n    date: 1461949500000,\n    open: 50.005,\n    high: 50.005,\n    low: 49.98,\n    close: 49.99,\n    volume: 39816,\n  },\n  {\n    date: 1461949560000,\n    open: 49.99,\n    high: 50.03,\n    low: 49.99,\n    close: 50.025,\n    volume: 41340,\n  },\n  {\n    date: 1461949620000,\n    open: 50.03,\n    high: 50.05,\n    low: 50.02,\n    close: 50.04,\n    volume: 66272,\n  },\n  {\n    date: 1461949680000,\n    open: 50.04,\n    high: 50.04,\n    low: 50.02,\n    close: 50.02,\n    volume: 23149,\n  },\n  {\n    date: 1461949740000,\n    open: 50.02,\n    high: 50.03,\n    low: 49.98,\n    close: 49.98,\n    volume: 27116,\n  },\n  {\n    date: 1461949800000,\n    open: 49.98,\n    high: 50.017,\n    low: 49.98,\n    close: 49.99,\n    volume: 81019,\n  },\n  {\n    date: 1461949860000,\n    open: 49.99,\n    high: 50.005,\n    low: 49.98,\n    close: 50,\n    volume: 101296,\n  },\n  {\n    date: 1461949920000,\n    open: 50,\n    high: 50.04,\n    low: 49.985,\n    close: 50.04,\n    volume: 68391,\n  },\n  {\n    date: 1461949980000,\n    open: 50.025,\n    high: 50.06,\n    low: 50.025,\n    close: 50.055,\n    volume: 110100,\n  },\n  {\n    date: 1461950040000,\n    open: 50.05,\n    high: 50.1,\n    low: 50.05,\n    close: 50.085,\n    volume: 85780,\n  },\n  {\n    date: 1461950100000,\n    open: 50.08,\n    high: 50.13,\n    low: 50.075,\n    close: 50.11,\n    volume: 83481,\n  },\n  {\n    date: 1461950160000,\n    open: 50.1135,\n    high: 50.12,\n    low: 50.08,\n    close: 50.12,\n    volume: 54365,\n  },\n  {\n    date: 1461950220000,\n    open: 50.13,\n    high: 50.13,\n    low: 50.095,\n    close: 50.114,\n    volume: 48590,\n  },\n  {\n    date: 1461950280000,\n    open: 50.11,\n    high: 50.12,\n    low: 50.1,\n    close: 50.115,\n    volume: 20738,\n  },\n  {\n    date: 1461950340000,\n    open: 50.115,\n    high: 50.14,\n    low: 50.11,\n    close: 50.135,\n    volume: 33748,\n  },\n  {\n    date: 1461950400000,\n    open: 50.1301,\n    high: 50.21,\n    low: 50.13,\n    close: 50.205,\n    volume: 98890,\n  },\n  {\n    date: 1461950460000,\n    open: 50.2,\n    high: 50.205,\n    low: 50.16,\n    close: 50.199,\n    volume: 87437,\n  },\n  {\n    date: 1461950520000,\n    open: 50.19,\n    high: 50.21,\n    low: 50.19,\n    close: 50.205,\n    volume: 50827,\n  },\n  {\n    date: 1461950580000,\n    open: 50.205,\n    high: 50.21,\n    low: 50.17,\n    close: 50.175,\n    volume: 92346,\n  },\n  {\n    date: 1461950640000,\n    open: 50.17,\n    high: 50.22,\n    low: 50.165,\n    close: 50.21,\n    volume: 139257,\n  },\n  {\n    date: 1461950700000,\n    open: 50.21,\n    high: 50.25,\n    low: 50.21,\n    close: 50.23,\n    volume: 80543,\n  },\n  {\n    date: 1461950760000,\n    open: 50.235,\n    high: 50.24,\n    low: 50.19,\n    close: 50.195,\n    volume: 77505,\n  },\n  {\n    date: 1461950820000,\n    open: 50.195,\n    high: 50.2,\n    low: 50.19,\n    close: 50.195,\n    volume: 16507,\n  },\n  {\n    date: 1461950880000,\n    open: 50.193,\n    high: 50.205,\n    low: 50.18,\n    close: 50.205,\n    volume: 74506,\n  },\n  {\n    date: 1461950940000,\n    open: 50.205,\n    high: 50.22,\n    low: 50.2,\n    close: 50.215,\n    volume: 84884,\n  },\n  {\n    date: 1461951000000,\n    open: 50.215,\n    high: 50.23,\n    low: 50.19,\n    close: 50.211,\n    volume: 81080,\n  },\n  {\n    date: 1461951060000,\n    open: 50.215,\n    high: 50.23,\n    low: 50.18,\n    close: 50.185,\n    volume: 75343,\n  },\n  {\n    date: 1461951120000,\n    open: 50.185,\n    high: 50.2,\n    low: 50.17,\n    close: 50.175,\n    volume: 160468,\n  },\n  {\n    date: 1461951180000,\n    open: 50.1799,\n    high: 50.2,\n    low: 50.17,\n    close: 50.195,\n    volume: 64476,\n  },\n  {\n    date: 1461951240000,\n    open: 50.2,\n    high: 50.2,\n    low: 50.18,\n    close: 50.195,\n    volume: 51404,\n  },\n  {\n    date: 1461951300000,\n    open: 50.2,\n    high: 50.2,\n    low: 50.16,\n    close: 50.1799,\n    volume: 64151,\n  },\n  {\n    date: 1461951360000,\n    open: 50.17,\n    high: 50.18,\n    low: 50.17,\n    close: 50.175,\n    volume: 26224,\n  },\n  {\n    date: 1461951420000,\n    open: 50.175,\n    high: 50.2,\n    low: 50.17,\n    close: 50.19,\n    volume: 63732,\n  },\n  {\n    date: 1461951480000,\n    open: 50.195,\n    high: 50.195,\n    low: 50.12,\n    close: 50.12,\n    volume: 94158,\n  },\n  {\n    date: 1461951540000,\n    open: 50.125,\n    high: 50.1263,\n    low: 50.09,\n    close: 50.099,\n    volume: 39181,\n  },\n  {\n    date: 1461951600000,\n    open: 50.095,\n    high: 50.13,\n    low: 50.0701,\n    close: 50.125,\n    volume: 74251,\n  },\n  {\n    date: 1461951660000,\n    open: 50.121,\n    high: 50.125,\n    low: 50.06,\n    close: 50.085,\n    volume: 39262,\n  },\n  {\n    date: 1461951720000,\n    open: 50.0861,\n    high: 50.0871,\n    low: 50.055,\n    close: 50.065,\n    volume: 52958,\n  },\n  {\n    date: 1461951780000,\n    open: 50.07,\n    high: 50.07,\n    low: 50.02,\n    close: 50.025,\n    volume: 23348,\n  },\n  {\n    date: 1461951840000,\n    open: 50.02,\n    high: 50.046,\n    low: 50.0101,\n    close: 50.0271,\n    volume: 35909,\n  },\n  {\n    date: 1461951900000,\n    open: 50.0299,\n    high: 50.05,\n    low: 50.02,\n    close: 50.035,\n    volume: 30602,\n  },\n  {\n    date: 1461951960000,\n    open: 50.035,\n    high: 50.05,\n    low: 50.025,\n    close: 50.03,\n    volume: 108355,\n  },\n  {\n    date: 1461952020000,\n    open: 50.04,\n    high: 50.06,\n    low: 50.025,\n    close: 50.036,\n    volume: 67288,\n  },\n  {\n    date: 1461952080000,\n    open: 50.0335,\n    high: 50.04,\n    low: 50.005,\n    close: 50.03,\n    volume: 90342,\n  },\n  {\n    date: 1461952140000,\n    open: 50.03,\n    high: 50.06,\n    low: 50.01,\n    close: 50.06,\n    volume: 59028,\n  },\n  {\n    date: 1461952200000,\n    open: 50.06,\n    high: 50.07,\n    low: 50.045,\n    close: 50.055,\n    volume: 32135,\n  },\n  {\n    date: 1461952260000,\n    open: 50.06,\n    high: 50.07,\n    low: 50.035,\n    close: 50.035,\n    volume: 29260,\n  },\n  {\n    date: 1461952320000,\n    open: 50.035,\n    high: 50.035,\n    low: 50,\n    close: 50.005,\n    volume: 40081,\n  },\n  {\n    date: 1461952380000,\n    open: 50.005,\n    high: 50.05,\n    low: 50.0035,\n    close: 50.035,\n    volume: 73310,\n  },\n  {\n    date: 1461952440000,\n    open: 50.035,\n    high: 50.05,\n    low: 50.03,\n    close: 50.045,\n    volume: 19755,\n  },\n  {\n    date: 1461952500000,\n    open: 50.045,\n    high: 50.06,\n    low: 50.02,\n    close: 50.02,\n    volume: 42459,\n  },\n  {\n    date: 1461952560000,\n    open: 50.02,\n    high: 50.02,\n    low: 49.96,\n    close: 49.96,\n    volume: 93467,\n  },\n  {\n    date: 1461952620000,\n    open: 49.96,\n    high: 50.01,\n    low: 49.93,\n    close: 49.995,\n    volume: 120296,\n  },\n  {\n    date: 1461952680000,\n    open: 49.995,\n    high: 50.01,\n    low: 49.99,\n    close: 49.99,\n    volume: 36976,\n  },\n  {\n    date: 1461952740000,\n    open: 49.99,\n    high: 49.995,\n    low: 49.96,\n    close: 49.975,\n    volume: 66270,\n  },\n  {\n    date: 1461952800000,\n    open: 49.98,\n    high: 50,\n    low: 49.96,\n    close: 49.985,\n    volume: 56904,\n  },\n  {\n    date: 1461952860000,\n    open: 49.98,\n    high: 50.025,\n    low: 49.97,\n    close: 50.02,\n    volume: 39113,\n  },\n  {\n    date: 1461952920000,\n    open: 50.02,\n    high: 50.025,\n    low: 50,\n    close: 50.005,\n    volume: 32349,\n  },\n  {\n    date: 1461952980000,\n    open: 50.005,\n    high: 50.02,\n    low: 49.99,\n    close: 50.02,\n    volume: 48536,\n  },\n  {\n    date: 1461953040000,\n    open: 50.015,\n    high: 50.025,\n    low: 49.98,\n    close: 50.015,\n    volume: 72174,\n  },\n  {\n    date: 1461953100000,\n    open: 50.0103,\n    high: 50.05,\n    low: 50,\n    close: 50.05,\n    volume: 83286,\n  },\n  {\n    date: 1461953160000,\n    open: 50.0438,\n    high: 50.045,\n    low: 50,\n    close: 50,\n    volume: 22414,\n  },\n  {\n    date: 1461953220000,\n    open: 50,\n    high: 50.01,\n    low: 49.97,\n    close: 49.9742,\n    volume: 83123,\n  },\n  {\n    date: 1461953280000,\n    open: 49.975,\n    high: 49.975,\n    low: 49.93,\n    close: 49.94,\n    volume: 61880,\n  },\n  {\n    date: 1461953340000,\n    open: 49.935,\n    high: 49.97,\n    low: 49.92,\n    close: 49.965,\n    volume: 82903,\n  },\n  {\n    date: 1461953400000,\n    open: 49.96,\n    high: 49.97,\n    low: 49.9,\n    close: 49.905,\n    volume: 105020,\n  },\n  {\n    date: 1461953460000,\n    open: 49.905,\n    high: 49.91,\n    low: 49.88,\n    close: 49.88,\n    volume: 33930,\n  },\n  {\n    date: 1461953520000,\n    open: 49.88,\n    high: 49.9262,\n    low: 49.87,\n    close: 49.92,\n    volume: 93477,\n  },\n  {\n    date: 1461953580000,\n    open: 49.92,\n    high: 49.9565,\n    low: 49.915,\n    close: 49.95,\n    volume: 87818,\n  },\n  {\n    date: 1461953640000,\n    open: 49.9499,\n    high: 49.9499,\n    low: 49.905,\n    close: 49.905,\n    volume: 31184,\n  },\n  {\n    date: 1461953700000,\n    open: 49.9099,\n    high: 49.94,\n    low: 49.89,\n    close: 49.94,\n    volume: 37747,\n  },\n  {\n    date: 1461953760000,\n    open: 49.94,\n    high: 49.95,\n    low: 49.89,\n    close: 49.9,\n    volume: 32447,\n  },\n  {\n    date: 1461953820000,\n    open: 49.9059,\n    high: 49.935,\n    low: 49.9,\n    close: 49.915,\n    volume: 82250,\n  },\n  {\n    date: 1461953880000,\n    open: 49.915,\n    high: 49.92,\n    low: 49.86,\n    close: 49.895,\n    volume: 78814,\n  },\n  {\n    date: 1461953940000,\n    open: 49.9,\n    high: 49.94,\n    low: 49.89,\n    close: 49.925,\n    volume: 103250,\n  },\n  {\n    date: 1461954000000,\n    open: 49.93,\n    high: 49.94,\n    low: 49.925,\n    close: 49.935,\n    volume: 10734,\n  },\n  {\n    date: 1461954060000,\n    open: 49.935,\n    high: 49.96,\n    low: 49.93,\n    close: 49.935,\n    volume: 83336,\n  },\n  {\n    date: 1461954120000,\n    open: 49.93,\n    high: 49.945,\n    low: 49.91,\n    close: 49.9108,\n    volume: 63628,\n  },\n  {\n    date: 1461954180000,\n    open: 49.92,\n    high: 49.9799,\n    low: 49.915,\n    close: 49.955,\n    volume: 46953,\n  },\n  {\n    date: 1461954240000,\n    open: 49.956,\n    high: 49.97,\n    low: 49.95,\n    close: 49.965,\n    volume: 25481,\n  },\n  {\n    date: 1461954300000,\n    open: 49.965,\n    high: 49.97,\n    low: 49.92,\n    close: 49.925,\n    volume: 48359,\n  },\n  {\n    date: 1461954360000,\n    open: 49.925,\n    high: 49.93,\n    low: 49.88,\n    close: 49.91,\n    volume: 71525,\n  },\n  {\n    date: 1461954420000,\n    open: 49.915,\n    high: 49.93,\n    low: 49.89,\n    close: 49.899,\n    volume: 21739,\n  },\n  {\n    date: 1461954480000,\n    open: 49.89,\n    high: 49.95,\n    low: 49.89,\n    close: 49.92,\n    volume: 91562,\n  },\n  {\n    date: 1461954540000,\n    open: 49.925,\n    high: 49.93,\n    low: 49.89,\n    close: 49.9,\n    volume: 39383,\n  },\n  {\n    date: 1461954600000,\n    open: 49.905,\n    high: 49.955,\n    low: 49.9,\n    close: 49.9,\n    volume: 61012,\n  },\n  {\n    date: 1461954660000,\n    open: 49.9,\n    high: 49.9,\n    low: 49.86,\n    close: 49.88,\n    volume: 41009,\n  },\n  {\n    date: 1461954720000,\n    open: 49.88,\n    high: 49.88,\n    low: 49.83,\n    close: 49.835,\n    volume: 40651,\n  },\n  {\n    date: 1461954780000,\n    open: 49.83,\n    high: 49.8723,\n    low: 49.805,\n    close: 49.845,\n    volume: 47983,\n  },\n  {\n    date: 1461954840000,\n    open: 49.85,\n    high: 49.8701,\n    low: 49.835,\n    close: 49.84,\n    volume: 33978,\n  },\n  {\n    date: 1461954900000,\n    open: 49.84,\n    high: 49.875,\n    low: 49.84,\n    close: 49.865,\n    volume: 22208,\n  },\n  {\n    date: 1461954960000,\n    open: 49.86,\n    high: 49.86,\n    low: 49.83,\n    close: 49.84,\n    volume: 37461,\n  },\n  {\n    date: 1461955020000,\n    open: 49.84,\n    high: 49.85,\n    low: 49.82,\n    close: 49.835,\n    volume: 36563,\n  },\n  {\n    date: 1461955080000,\n    open: 49.835,\n    high: 49.835,\n    low: 49.81,\n    close: 49.82,\n    volume: 36948,\n  },\n  {\n    date: 1461955140000,\n    open: 49.82,\n    high: 49.83,\n    low: 49.79,\n    close: 49.8,\n    volume: 92933,\n  },\n  {\n    date: 1461955200000,\n    open: 49.8,\n    high: 49.84,\n    low: 49.79,\n    close: 49.8,\n    volume: 61102,\n  },\n  {\n    date: 1461955260000,\n    open: 49.8,\n    high: 49.845,\n    low: 49.795,\n    close: 49.845,\n    volume: 22658,\n  },\n  {\n    date: 1461955320000,\n    open: 49.84,\n    high: 49.85,\n    low: 49.81,\n    close: 49.83,\n    volume: 119650,\n  },\n  {\n    date: 1461955380000,\n    open: 49.83,\n    high: 49.865,\n    low: 49.81,\n    close: 49.84,\n    volume: 124543,\n  },\n  {\n    date: 1461955440000,\n    open: 49.83,\n    high: 49.86,\n    low: 49.83,\n    close: 49.835,\n    volume: 64699,\n  },\n  {\n    date: 1461955500000,\n    open: 49.835,\n    high: 49.84,\n    low: 49.81,\n    close: 49.835,\n    volume: 23935,\n  },\n  {\n    date: 1461955560000,\n    open: 49.84,\n    high: 49.86,\n    low: 49.81,\n    close: 49.86,\n    volume: 39411,\n  },\n  {\n    date: 1461955620000,\n    open: 49.855,\n    high: 49.865,\n    low: 49.85,\n    close: 49.855,\n    volume: 25021,\n  },\n  {\n    date: 1461955680000,\n    open: 49.855,\n    high: 49.885,\n    low: 49.85,\n    close: 49.87,\n    volume: 109466,\n  },\n  {\n    date: 1461955740000,\n    open: 49.88,\n    high: 49.88,\n    low: 49.86,\n    close: 49.87,\n    volume: 83972,\n  },\n  {\n    date: 1461955800000,\n    open: 49.865,\n    high: 49.89,\n    low: 49.86,\n    close: 49.88,\n    volume: 160861,\n  },\n  {\n    date: 1461955860000,\n    open: 49.89,\n    high: 49.89,\n    low: 49.8,\n    close: 49.8129,\n    volume: 68152,\n  },\n  {\n    date: 1461955920000,\n    open: 49.81,\n    high: 49.87,\n    low: 49.81,\n    close: 49.845,\n    volume: 86848,\n  },\n  {\n    date: 1461955980000,\n    open: 49.85,\n    high: 49.87,\n    low: 49.8,\n    close: 49.82,\n    volume: 84361,\n  },\n  {\n    date: 1461956040000,\n    open: 49.83,\n    high: 49.85,\n    low: 49.81,\n    close: 49.845,\n    volume: 23189,\n  },\n  {\n    date: 1461956100000,\n    open: 49.85,\n    high: 49.85,\n    low: 49.82,\n    close: 49.84,\n    volume: 50739,\n  },\n  {\n    date: 1461956160000,\n    open: 49.84,\n    high: 49.86,\n    low: 49.81,\n    close: 49.83,\n    volume: 89480,\n  },\n  {\n    date: 1461956220000,\n    open: 49.835,\n    high: 49.85,\n    low: 49.78,\n    close: 49.795,\n    volume: 148716,\n  },\n  {\n    date: 1461956280000,\n    open: 49.79,\n    high: 49.825,\n    low: 49.79,\n    close: 49.8058,\n    volume: 48386,\n  },\n  {\n    date: 1461956340000,\n    open: 49.81,\n    high: 49.84,\n    low: 49.78,\n    close: 49.79,\n    volume: 71144,\n  },\n  {\n    date: 1461956400000,\n    open: 49.795,\n    high: 49.825,\n    low: 49.78,\n    close: 49.825,\n    volume: 41210,\n  },\n  {\n    date: 1461956460000,\n    open: 49.83,\n    high: 49.835,\n    low: 49.791,\n    close: 49.81,\n    volume: 136758,\n  },\n  {\n    date: 1461956520000,\n    open: 49.805,\n    high: 49.84,\n    low: 49.8,\n    close: 49.83,\n    volume: 78491,\n  },\n  {\n    date: 1461956580000,\n    open: 49.835,\n    high: 49.84,\n    low: 49.79,\n    close: 49.79,\n    volume: 64303,\n  },\n  {\n    date: 1461956640000,\n    open: 49.8,\n    high: 49.82,\n    low: 49.79,\n    close: 49.8,\n    volume: 38092,\n  },\n  {\n    date: 1461956700000,\n    open: 49.8,\n    high: 49.805,\n    low: 49.76,\n    close: 49.78,\n    volume: 118485,\n  },\n  {\n    date: 1461956760000,\n    open: 49.775,\n    high: 49.795,\n    low: 49.75,\n    close: 49.79,\n    volume: 57394,\n  },\n  {\n    date: 1461956820000,\n    open: 49.795,\n    high: 49.8299,\n    low: 49.79,\n    close: 49.82,\n    volume: 47534,\n  },\n  {\n    date: 1461956880000,\n    open: 49.82,\n    high: 49.84,\n    low: 49.815,\n    close: 49.84,\n    volume: 97126,\n  },\n  {\n    date: 1461956940000,\n    open: 49.84,\n    high: 49.85,\n    low: 49.79,\n    close: 49.79,\n    volume: 123615,\n  },\n  {\n    date: 1461957000000,\n    open: 49.795,\n    high: 49.82,\n    low: 49.78,\n    close: 49.795,\n    volume: 87855,\n  },\n  {\n    date: 1461957060000,\n    open: 49.795,\n    high: 49.8,\n    low: 49.75,\n    close: 49.775,\n    volume: 82391,\n  },\n  {\n    date: 1461957120000,\n    open: 49.775,\n    high: 49.835,\n    low: 49.76,\n    close: 49.835,\n    volume: 57712,\n  },\n  {\n    date: 1461957180000,\n    open: 49.8399,\n    high: 49.85,\n    low: 49.79,\n    close: 49.82,\n    volume: 131280,\n  },\n  {\n    date: 1461957240000,\n    open: 49.83,\n    high: 49.85,\n    low: 49.815,\n    close: 49.84,\n    volume: 101700,\n  },\n  {\n    date: 1461957300000,\n    open: 49.845,\n    high: 49.88,\n    low: 49.835,\n    close: 49.86,\n    volume: 124955,\n  },\n  {\n    date: 1461957360000,\n    open: 49.8561,\n    high: 49.86,\n    low: 49.84,\n    close: 49.845,\n    volume: 87694,\n  },\n  {\n    date: 1461957420000,\n    open: 49.8499,\n    high: 49.85,\n    low: 49.795,\n    close: 49.82,\n    volume: 70811,\n  },\n  {\n    date: 1461957480000,\n    open: 49.82,\n    high: 49.83,\n    low: 49.79,\n    close: 49.806,\n    volume: 30351,\n  },\n  {\n    date: 1461957540000,\n    open: 49.81,\n    high: 49.84,\n    low: 49.8,\n    close: 49.805,\n    volume: 48612,\n  },\n  {\n    date: 1461957600000,\n    open: 49.81,\n    high: 49.825,\n    low: 49.8,\n    close: 49.82,\n    volume: 30233,\n  },\n  {\n    date: 1461957660000,\n    open: 49.8277,\n    high: 49.83,\n    low: 49.79,\n    close: 49.82,\n    volume: 119299,\n  },\n  {\n    date: 1461957720000,\n    open: 49.82,\n    high: 49.84,\n    low: 49.8,\n    close: 49.835,\n    volume: 62440,\n  },\n  {\n    date: 1461957780000,\n    open: 49.8399,\n    high: 49.855,\n    low: 49.81,\n    close: 49.84,\n    volume: 137109,\n  },\n  {\n    date: 1461957840000,\n    open: 49.835,\n    high: 49.86,\n    low: 49.78,\n    close: 49.785,\n    volume: 176645,\n  },\n  {\n    date: 1461957900000,\n    open: 49.7839,\n    high: 49.825,\n    low: 49.77,\n    close: 49.78,\n    volume: 78262,\n  },\n  {\n    date: 1461957960000,\n    open: 49.78,\n    high: 49.8025,\n    low: 49.775,\n    close: 49.79,\n    volume: 91842,\n  },\n  {\n    date: 1461958020000,\n    open: 49.797,\n    high: 49.81,\n    low: 49.76,\n    close: 49.76,\n    volume: 78809,\n  },\n  {\n    date: 1461958080000,\n    open: 49.765,\n    high: 49.79,\n    low: 49.74,\n    close: 49.79,\n    volume: 52624,\n  },\n  {\n    date: 1461958140000,\n    open: 49.79,\n    high: 49.795,\n    low: 49.72,\n    close: 49.726,\n    volume: 55312,\n  },\n  {\n    date: 1461958200000,\n    open: 49.7237,\n    high: 49.745,\n    low: 49.71,\n    close: 49.73,\n    volume: 86506,\n  },\n  {\n    date: 1461958260000,\n    open: 49.73,\n    high: 49.78,\n    low: 49.73,\n    close: 49.78,\n    volume: 98958,\n  },\n  {\n    date: 1461958320000,\n    open: 49.79,\n    high: 49.815,\n    low: 49.78,\n    close: 49.8028,\n    volume: 71102,\n  },\n  {\n    date: 1461958380000,\n    open: 49.8,\n    high: 49.86,\n    low: 49.8,\n    close: 49.85,\n    volume: 285015,\n  },\n  {\n    date: 1461958440000,\n    open: 49.85,\n    high: 49.88,\n    low: 49.815,\n    close: 49.815,\n    volume: 152601,\n  },\n  {\n    date: 1461958500000,\n    open: 49.815,\n    high: 49.9,\n    low: 49.815,\n    close: 49.9,\n    volume: 96252,\n  },\n  {\n    date: 1461958560000,\n    open: 49.9,\n    high: 49.9,\n    low: 49.88,\n    close: 49.9,\n    volume: 133108,\n  },\n  {\n    date: 1461958620000,\n    open: 49.9,\n    high: 49.93,\n    low: 49.89,\n    close: 49.9,\n    volume: 156212,\n  },\n  {\n    date: 1461958680000,\n    open: 49.9,\n    high: 49.94,\n    low: 49.895,\n    close: 49.925,\n    volume: 118279,\n  },\n  {\n    date: 1461958740000,\n    open: 49.93,\n    high: 49.96,\n    low: 49.92,\n    close: 49.95,\n    volume: 356166,\n  },\n  {\n    date: 1461958800000,\n    open: 49.95,\n    high: 49.95,\n    low: 49.885,\n    close: 49.92,\n    volume: 142555,\n  },\n  {\n    date: 1461958860000,\n    open: 49.92,\n    high: 49.96,\n    low: 49.91,\n    close: 49.935,\n    volume: 159392,\n  },\n  {\n    date: 1461958920000,\n    open: 49.935,\n    high: 49.965,\n    low: 49.93,\n    close: 49.935,\n    volume: 77225,\n  },\n  {\n    date: 1461958980000,\n    open: 49.935,\n    high: 49.96,\n    low: 49.93,\n    close: 49.945,\n    volume: 94686,\n  },\n  {\n    date: 1461959040000,\n    open: 49.945,\n    high: 49.95,\n    low: 49.89,\n    close: 49.925,\n    volume: 109829,\n  },\n  {\n    date: 1461959100000,\n    open: 49.92,\n    high: 49.94,\n    low: 49.915,\n    close: 49.94,\n    volume: 50436,\n  },\n  {\n    date: 1461959160000,\n    open: 49.94,\n    high: 50.02,\n    low: 49.92,\n    close: 50.02,\n    volume: 254783,\n  },\n  {\n    date: 1461959220000,\n    open: 50.015,\n    high: 50.04,\n    low: 49.99,\n    close: 49.995,\n    volume: 223303,\n  },\n  {\n    date: 1461959280000,\n    open: 49.99,\n    high: 50,\n    low: 49.93,\n    close: 49.935,\n    volume: 132883,\n  },\n  {\n    date: 1461959340000,\n    open: 49.935,\n    high: 49.94,\n    low: 49.88,\n    close: 49.89,\n    volume: 136876,\n  },\n  {\n    date: 1461959400000,\n    open: 49.9,\n    high: 49.9,\n    low: 49.85,\n    close: 49.855,\n    volume: 223623,\n  },\n  {\n    date: 1461959460000,\n    open: 49.855,\n    high: 49.88,\n    low: 49.82,\n    close: 49.875,\n    volume: 210430,\n  },\n  {\n    date: 1461959520000,\n    open: 49.88,\n    high: 49.9262,\n    low: 49.87,\n    close: 49.91,\n    volume: 172327,\n  },\n  {\n    date: 1461959580000,\n    open: 49.905,\n    high: 49.91,\n    low: 49.86,\n    close: 49.86,\n    volume: 130391,\n  },\n  {\n    date: 1461959640000,\n    open: 49.86,\n    high: 49.87,\n    low: 49.82,\n    close: 49.835,\n    volume: 162371,\n  },\n  {\n    date: 1461959700000,\n    open: 49.835,\n    high: 49.89,\n    low: 49.83,\n    close: 49.89,\n    volume: 175742,\n  },\n  {\n    date: 1461959760000,\n    open: 49.895,\n    high: 49.93,\n    low: 49.85,\n    close: 49.875,\n    volume: 239317,\n  },\n  {\n    date: 1461959820000,\n    open: 49.88,\n    high: 49.88,\n    low: 49.84,\n    close: 49.865,\n    volume: 221813,\n  },\n  {\n    date: 1461959880000,\n    open: 49.87,\n    high: 49.885,\n    low: 49.835,\n    close: 49.86,\n    volume: 302425,\n  },\n  {\n    date: 1461959940000,\n    open: 49.865,\n    high: 49.87,\n    low: 49.83,\n    close: 49.855,\n    volume: 357334,\n  },\n  {\n    date: 1461960000000,\n    open: 49.855,\n    high: 49.91,\n    low: 49.83,\n    close: 49.87,\n    volume: 4207530,\n  },\n  {\n    date: 1462195800000,\n    open: 50,\n    high: 50.05,\n    low: 50,\n    close: 50.03,\n    volume: 383038,\n  },\n  {\n    date: 1462195860000,\n    open: 50.04,\n    high: 50.11,\n    low: 49.95,\n    close: 49.95,\n    volume: 151710,\n  },\n  {\n    date: 1462195920000,\n    open: 49.96,\n    high: 50.01,\n    low: 49.93,\n    close: 49.95,\n    volume: 103879,\n  },\n  {\n    date: 1462195980000,\n    open: 49.94,\n    high: 49.955,\n    low: 49.88,\n    close: 49.89,\n    volume: 55286,\n  },\n  {\n    date: 1462196040000,\n    open: 49.88,\n    high: 49.885,\n    low: 49.7799,\n    close: 49.81,\n    volume: 73269,\n  },\n  {\n    date: 1462196100000,\n    open: 49.8,\n    high: 49.905,\n    low: 49.785,\n    close: 49.87,\n    volume: 55416,\n  },\n  {\n    date: 1462196160000,\n    open: 49.865,\n    high: 49.95,\n    low: 49.865,\n    close: 49.91,\n    volume: 58493,\n  },\n  {\n    date: 1462196220000,\n    open: 49.91,\n    high: 49.97,\n    low: 49.88,\n    close: 49.945,\n    volume: 73315,\n  },\n  {\n    date: 1462196280000,\n    open: 49.94,\n    high: 50.02,\n    low: 49.9175,\n    close: 49.9999,\n    volume: 86652,\n  },\n  {\n    date: 1462196340000,\n    open: 49.9976,\n    high: 50.06,\n    low: 49.99,\n    close: 50.03,\n    volume: 255704,\n  },\n  {\n    date: 1462196400000,\n    open: 50.035,\n    high: 50.06,\n    low: 49.98,\n    close: 49.98,\n    volume: 112429,\n  },\n  {\n    date: 1462196460000,\n    open: 49.98,\n    high: 50.11,\n    low: 49.96,\n    close: 50.08,\n    volume: 193309,\n  },\n  {\n    date: 1462196520000,\n    open: 50.08,\n    high: 50.0999,\n    low: 50.04,\n    close: 50.0568,\n    volume: 53118,\n  },\n  {\n    date: 1462196580000,\n    open: 50.055,\n    high: 50.06,\n    low: 50.01,\n    close: 50.01,\n    volume: 84372,\n  },\n  {\n    date: 1462196640000,\n    open: 50.0168,\n    high: 50.025,\n    low: 49.975,\n    close: 50,\n    volume: 61643,\n  },\n  {\n    date: 1462196700000,\n    open: 49.991,\n    high: 50.0563,\n    low: 49.975,\n    close: 50.0305,\n    volume: 50654,\n  },\n  {\n    date: 1462196760000,\n    open: 50.03,\n    high: 50.0301,\n    low: 49.93,\n    close: 49.97,\n    volume: 74299,\n  },\n  {\n    date: 1462196820000,\n    open: 49.975,\n    high: 49.9763,\n    low: 49.88,\n    close: 49.93,\n    volume: 52612,\n  },\n  {\n    date: 1462196880000,\n    open: 49.93,\n    high: 49.93,\n    low: 49.84,\n    close: 49.84,\n    volume: 69513,\n  },\n  {\n    date: 1462196940000,\n    open: 49.84,\n    high: 49.89,\n    low: 49.83,\n    close: 49.89,\n    volume: 85516,\n  },\n  {\n    date: 1462197000000,\n    open: 49.88,\n    high: 49.97,\n    low: 49.871,\n    close: 49.95,\n    volume: 91160,\n  },\n  {\n    date: 1462197060000,\n    open: 49.94,\n    high: 49.945,\n    low: 49.84,\n    close: 49.86,\n    volume: 124052,\n  },\n  {\n    date: 1462197120000,\n    open: 49.85,\n    high: 49.94,\n    low: 49.83,\n    close: 49.9254,\n    volume: 89502,\n  },\n  {\n    date: 1462197180000,\n    open: 49.9295,\n    high: 49.99,\n    low: 49.92,\n    close: 49.985,\n    volume: 60248,\n  },\n  {\n    date: 1462197240000,\n    open: 49.98,\n    high: 50.02,\n    low: 49.97,\n    close: 49.99,\n    volume: 113258,\n  },\n  {\n    date: 1462197300000,\n    open: 49.98,\n    high: 50,\n    low: 49.96,\n    close: 49.98,\n    volume: 172259,\n  },\n  {\n    date: 1462197360000,\n    open: 49.98,\n    high: 50.01,\n    low: 49.97,\n    close: 49.97,\n    volume: 173436,\n  },\n  {\n    date: 1462197420000,\n    open: 49.965,\n    high: 49.985,\n    low: 49.94,\n    close: 49.945,\n    volume: 92568,\n  },\n  {\n    date: 1462197480000,\n    open: 49.95,\n    high: 50.01,\n    low: 49.95,\n    close: 49.956,\n    volume: 155964,\n  },\n  {\n    date: 1462197540000,\n    open: 49.96,\n    high: 49.97,\n    low: 49.93,\n    close: 49.96,\n    volume: 141365,\n  },\n  {\n    date: 1462197600000,\n    open: 49.95,\n    high: 49.9976,\n    low: 49.895,\n    close: 49.895,\n    volume: 88592,\n  },\n  {\n    date: 1462197660000,\n    open: 49.89,\n    high: 49.95,\n    low: 49.88,\n    close: 49.89,\n    volume: 151973,\n  },\n  {\n    date: 1462197720000,\n    open: 49.88,\n    high: 49.94,\n    low: 49.88,\n    close: 49.902,\n    volume: 108413,\n  },\n  {\n    date: 1462197780000,\n    open: 49.905,\n    high: 49.94,\n    low: 49.87,\n    close: 49.93,\n    volume: 127842,\n  },\n  {\n    date: 1462197840000,\n    open: 49.92,\n    high: 49.93,\n    low: 49.86,\n    close: 49.89,\n    volume: 89591,\n  },\n  {\n    date: 1462197900000,\n    open: 49.88,\n    high: 49.92,\n    low: 49.86,\n    close: 49.9,\n    volume: 102258,\n  },\n  {\n    date: 1462197960000,\n    open: 49.909,\n    high: 49.929,\n    low: 49.89,\n    close: 49.929,\n    volume: 51808,\n  },\n  {\n    date: 1462198020000,\n    open: 49.92,\n    high: 49.93,\n    low: 49.89,\n    close: 49.91,\n    volume: 85321,\n  },\n  {\n    date: 1462198080000,\n    open: 49.9001,\n    high: 49.95,\n    low: 49.895,\n    close: 49.94,\n    volume: 45907,\n  },\n  {\n    date: 1462198140000,\n    open: 49.935,\n    high: 49.95,\n    low: 49.915,\n    close: 49.93,\n    volume: 52314,\n  },\n  {\n    date: 1462198200000,\n    open: 49.93,\n    high: 49.9905,\n    low: 49.93,\n    close: 49.985,\n    volume: 54111,\n  },\n  {\n    date: 1462198260000,\n    open: 49.985,\n    high: 50,\n    low: 49.97,\n    close: 49.98,\n    volume: 54760,\n  },\n  {\n    date: 1462198320000,\n    open: 49.985,\n    high: 50.02,\n    low: 49.97,\n    close: 49.9971,\n    volume: 83728,\n  },\n  {\n    date: 1462198380000,\n    open: 49.995,\n    high: 50,\n    low: 49.97,\n    close: 49.9763,\n    volume: 42395,\n  },\n  {\n    date: 1462198440000,\n    open: 49.98,\n    high: 49.99,\n    low: 49.96,\n    close: 49.9865,\n    volume: 115119,\n  },\n  {\n    date: 1462198500000,\n    open: 49.98,\n    high: 50.01,\n    low: 49.965,\n    close: 50,\n    volume: 73596,\n  },\n  {\n    date: 1462198560000,\n    open: 50,\n    high: 50.04,\n    low: 49.985,\n    close: 50.02,\n    volume: 70429,\n  },\n  {\n    date: 1462198620000,\n    open: 50.0299,\n    high: 50.08,\n    low: 50.02,\n    close: 50.07,\n    volume: 330882,\n  },\n  {\n    date: 1462198680000,\n    open: 50.07,\n    high: 50.075,\n    low: 50.06,\n    close: 50.06,\n    volume: 95022,\n  },\n  {\n    date: 1462198740000,\n    open: 50.065,\n    high: 50.075,\n    low: 50.06,\n    close: 50.0657,\n    volume: 78907,\n  },\n  {\n    date: 1462198800000,\n    open: 50.065,\n    high: 50.075,\n    low: 50.03,\n    close: 50.04,\n    volume: 62861,\n  },\n  {\n    date: 1462198860000,\n    open: 50.0463,\n    high: 50.05,\n    low: 50,\n    close: 50.045,\n    volume: 99696,\n  },\n  {\n    date: 1462198920000,\n    open: 50.045,\n    high: 50.0799,\n    low: 50.04,\n    close: 50.07,\n    volume: 50227,\n  },\n  {\n    date: 1462198980000,\n    open: 50.07,\n    high: 50.08,\n    low: 50.02,\n    close: 50.02,\n    volume: 114235,\n  },\n  {\n    date: 1462199040000,\n    open: 50.03,\n    high: 50.0499,\n    low: 50.0015,\n    close: 50.04,\n    volume: 62061,\n  },\n  {\n    date: 1462199100000,\n    open: 50.04,\n    high: 50.06,\n    low: 50.0215,\n    close: 50.055,\n    volume: 47183,\n  },\n  {\n    date: 1462199160000,\n    open: 50.06,\n    high: 50.15,\n    low: 50.05,\n    close: 50.13,\n    volume: 299184,\n  },\n  {\n    date: 1462199220000,\n    open: 50.1262,\n    high: 50.18,\n    low: 50.12,\n    close: 50.16,\n    volume: 82964,\n  },\n  {\n    date: 1462199280000,\n    open: 50.1639,\n    high: 50.1698,\n    low: 50.12,\n    close: 50.12,\n    volume: 77628,\n  },\n  {\n    date: 1462199340000,\n    open: 50.1299,\n    high: 50.15,\n    low: 50.09,\n    close: 50.15,\n    volume: 84933,\n  },\n  {\n    date: 1462199400000,\n    open: 50.15,\n    high: 50.15,\n    low: 50.1,\n    close: 50.12,\n    volume: 54899,\n  },\n  {\n    date: 1462199460000,\n    open: 50.115,\n    high: 50.16,\n    low: 50.115,\n    close: 50.145,\n    volume: 83590,\n  },\n  {\n    date: 1462199520000,\n    open: 50.145,\n    high: 50.18,\n    low: 50.145,\n    close: 50.165,\n    volume: 107569,\n  },\n  {\n    date: 1462199580000,\n    open: 50.17,\n    high: 50.2,\n    low: 50.14,\n    close: 50.196,\n    volume: 99641,\n  },\n  {\n    date: 1462199640000,\n    open: 50.19,\n    high: 50.195,\n    low: 50.15,\n    close: 50.16,\n    volume: 112181,\n  },\n  {\n    date: 1462199700000,\n    open: 50.16,\n    high: 50.1667,\n    low: 50.14,\n    close: 50.16,\n    volume: 69920,\n  },\n  {\n    date: 1462199760000,\n    open: 50.16,\n    high: 50.16,\n    low: 50.11,\n    close: 50.12,\n    volume: 76237,\n  },\n  {\n    date: 1462199820000,\n    open: 50.12,\n    high: 50.1464,\n    low: 50.1199,\n    close: 50.14,\n    volume: 46259,\n  },\n  {\n    date: 1462199880000,\n    open: 50.14,\n    high: 50.15,\n    low: 50.11,\n    close: 50.11,\n    volume: 89815,\n  },\n  {\n    date: 1462199940000,\n    open: 50.1196,\n    high: 50.14,\n    low: 50.11,\n    close: 50.125,\n    volume: 59629,\n  },\n  {\n    date: 1462200000000,\n    open: 50.12,\n    high: 50.15,\n    low: 50.09,\n    close: 50.09,\n    volume: 74167,\n  },\n  {\n    date: 1462200060000,\n    open: 50.0899,\n    high: 50.09,\n    low: 50.0699,\n    close: 50.086,\n    volume: 57212,\n  },\n  {\n    date: 1462200120000,\n    open: 50.084,\n    high: 50.1,\n    low: 50.082,\n    close: 50.09,\n    volume: 54807,\n  },\n  {\n    date: 1462200180000,\n    open: 50.1,\n    high: 50.12,\n    low: 50.09,\n    close: 50.1142,\n    volume: 52031,\n  },\n  {\n    date: 1462200240000,\n    open: 50.12,\n    high: 50.129,\n    low: 50.1,\n    close: 50.1,\n    volume: 37065,\n  },\n  {\n    date: 1462200300000,\n    open: 50.1099,\n    high: 50.11,\n    low: 50.04,\n    close: 50.05,\n    volume: 80763,\n  },\n  {\n    date: 1462200360000,\n    open: 50.05,\n    high: 50.1,\n    low: 50.05,\n    close: 50.0735,\n    volume: 73852,\n  },\n  {\n    date: 1462200420000,\n    open: 50.07,\n    high: 50.11,\n    low: 50.06,\n    close: 50.09,\n    volume: 93871,\n  },\n  {\n    date: 1462200480000,\n    open: 50.09,\n    high: 50.11,\n    low: 50.07,\n    close: 50.0965,\n    volume: 138529,\n  },\n  {\n    date: 1462200540000,\n    open: 50.095,\n    high: 50.11,\n    low: 50.09,\n    close: 50.11,\n    volume: 19333,\n  },\n  {\n    date: 1462200600000,\n    open: 50.1,\n    high: 50.14,\n    low: 50.1,\n    close: 50.135,\n    volume: 56889,\n  },\n  {\n    date: 1462200660000,\n    open: 50.135,\n    high: 50.14,\n    low: 50.13,\n    close: 50.13,\n    volume: 50752,\n  },\n  {\n    date: 1462200720000,\n    open: 50.13,\n    high: 50.1399,\n    low: 50.06,\n    close: 50.06,\n    volume: 77398,\n  },\n  {\n    date: 1462200780000,\n    open: 50.06,\n    high: 50.07,\n    low: 50,\n    close: 50.01,\n    volume: 78016,\n  },\n  {\n    date: 1462200840000,\n    open: 50.005,\n    high: 50.01,\n    low: 49.98,\n    close: 49.99,\n    volume: 227024,\n  },\n  {\n    date: 1462200900000,\n    open: 49.995,\n    high: 50,\n    low: 49.94,\n    close: 49.967,\n    volume: 122010,\n  },\n  {\n    date: 1462200960000,\n    open: 49.97,\n    high: 49.98,\n    low: 49.91,\n    close: 49.91,\n    volume: 72187,\n  },\n  {\n    date: 1462201020000,\n    open: 49.91,\n    high: 49.955,\n    low: 49.91,\n    close: 49.945,\n    volume: 63928,\n  },\n  {\n    date: 1462201080000,\n    open: 49.9455,\n    high: 49.9455,\n    low: 49.91,\n    close: 49.91,\n    volume: 33585,\n  },\n  {\n    date: 1462201140000,\n    open: 49.91,\n    high: 49.95,\n    low: 49.9,\n    close: 49.925,\n    volume: 76455,\n  },\n  {\n    date: 1462201200000,\n    open: 49.925,\n    high: 49.93,\n    low: 49.9,\n    close: 49.9165,\n    volume: 67779,\n  },\n  {\n    date: 1462201260000,\n    open: 49.919,\n    high: 49.94,\n    low: 49.91,\n    close: 49.92,\n    volume: 87559,\n  },\n  {\n    date: 1462201320000,\n    open: 49.925,\n    high: 49.94,\n    low: 49.92,\n    close: 49.93,\n    volume: 72901,\n  },\n  {\n    date: 1462201380000,\n    open: 49.94,\n    high: 49.94,\n    low: 49.92,\n    close: 49.93,\n    volume: 26630,\n  },\n  {\n    date: 1462201440000,\n    open: 49.935,\n    high: 49.956,\n    low: 49.92,\n    close: 49.935,\n    volume: 40355,\n  },\n  {\n    date: 1462201500000,\n    open: 49.932,\n    high: 49.94,\n    low: 49.88,\n    close: 49.885,\n    volume: 71179,\n  },\n  {\n    date: 1462201560000,\n    open: 49.88,\n    high: 49.91,\n    low: 49.87,\n    close: 49.9,\n    volume: 118324,\n  },\n  {\n    date: 1462201620000,\n    open: 49.895,\n    high: 49.91,\n    low: 49.87,\n    close: 49.8765,\n    volume: 36907,\n  },\n  {\n    date: 1462201680000,\n    open: 49.87,\n    high: 49.875,\n    low: 49.85,\n    close: 49.8589,\n    volume: 30398,\n  },\n  {\n    date: 1462201740000,\n    open: 49.85,\n    high: 49.9,\n    low: 49.85,\n    close: 49.895,\n    volume: 43911,\n  },\n  {\n    date: 1462201800000,\n    open: 49.8998,\n    high: 49.92,\n    low: 49.88,\n    close: 49.9,\n    volume: 68404,\n  },\n  {\n    date: 1462201860000,\n    open: 49.89,\n    high: 49.98,\n    low: 49.89,\n    close: 49.965,\n    volume: 61847,\n  },\n  {\n    date: 1462201920000,\n    open: 49.96,\n    high: 49.995,\n    low: 49.93,\n    close: 49.94,\n    volume: 43387,\n  },\n  {\n    date: 1462201980000,\n    open: 49.94,\n    high: 49.97,\n    low: 49.935,\n    close: 49.95,\n    volume: 47098,\n  },\n  {\n    date: 1462202040000,\n    open: 49.96,\n    high: 49.99,\n    low: 49.93,\n    close: 49.94,\n    volume: 51119,\n  },\n  {\n    date: 1462202100000,\n    open: 49.94,\n    high: 49.95,\n    low: 49.92,\n    close: 49.93,\n    volume: 37486,\n  },\n  {\n    date: 1462202160000,\n    open: 49.93,\n    high: 49.94,\n    low: 49.9,\n    close: 49.92,\n    volume: 43050,\n  },\n  {\n    date: 1462202220000,\n    open: 49.925,\n    high: 49.93,\n    low: 49.91,\n    close: 49.9175,\n    volume: 75377,\n  },\n  {\n    date: 1462202280000,\n    open: 49.91,\n    high: 49.97,\n    low: 49.91,\n    close: 49.96,\n    volume: 30266,\n  },\n  {\n    date: 1462202340000,\n    open: 49.96,\n    high: 49.9899,\n    low: 49.954,\n    close: 49.965,\n    volume: 38202,\n  },\n  {\n    date: 1462202400000,\n    open: 49.96,\n    high: 49.9852,\n    low: 49.95,\n    close: 49.9808,\n    volume: 28933,\n  },\n  {\n    date: 1462202460000,\n    open: 49.9808,\n    high: 49.99,\n    low: 49.95,\n    close: 49.951,\n    volume: 47695,\n  },\n  {\n    date: 1462202520000,\n    open: 49.9567,\n    high: 49.96,\n    low: 49.93,\n    close: 49.945,\n    volume: 28467,\n  },\n  {\n    date: 1462202580000,\n    open: 49.945,\n    high: 49.99,\n    low: 49.92,\n    close: 49.985,\n    volume: 50848,\n  },\n  {\n    date: 1462202640000,\n    open: 49.985,\n    high: 49.99,\n    low: 49.95,\n    close: 49.95,\n    volume: 74207,\n  },\n  {\n    date: 1462202700000,\n    open: 49.96,\n    high: 49.977,\n    low: 49.92,\n    close: 49.925,\n    volume: 132677,\n  },\n  {\n    date: 1462202760000,\n    open: 49.92,\n    high: 49.927,\n    low: 49.88,\n    close: 49.89,\n    volume: 53495,\n  },\n  {\n    date: 1462202820000,\n    open: 49.89,\n    high: 49.9099,\n    low: 49.88,\n    close: 49.886,\n    volume: 80791,\n  },\n  {\n    date: 1462202880000,\n    open: 49.885,\n    high: 49.9289,\n    low: 49.87,\n    close: 49.915,\n    volume: 63205,\n  },\n  {\n    date: 1462202940000,\n    open: 49.915,\n    high: 49.94,\n    low: 49.9,\n    close: 49.94,\n    volume: 41704,\n  },\n  {\n    date: 1462203000000,\n    open: 49.93,\n    high: 49.985,\n    low: 49.93,\n    close: 49.97,\n    volume: 73299,\n  },\n  {\n    date: 1462203060000,\n    open: 49.9799,\n    high: 50,\n    low: 49.96,\n    close: 50,\n    volume: 26455,\n  },\n  {\n    date: 1462203120000,\n    open: 50,\n    high: 50.01,\n    low: 49.97,\n    close: 49.97,\n    volume: 33864,\n  },\n  {\n    date: 1462203180000,\n    open: 49.97,\n    high: 49.975,\n    low: 49.96,\n    close: 49.97,\n    volume: 43015,\n  },\n  {\n    date: 1462203240000,\n    open: 49.97,\n    high: 49.97,\n    low: 49.96,\n    close: 49.96,\n    volume: 19568,\n  },\n  {\n    date: 1462203300000,\n    open: 49.9676,\n    high: 50,\n    low: 49.96,\n    close: 49.99,\n    volume: 45334,\n  },\n  {\n    date: 1462203360000,\n    open: 49.9901,\n    high: 50,\n    low: 49.955,\n    close: 49.96,\n    volume: 48719,\n  },\n  {\n    date: 1462203420000,\n    open: 49.96,\n    high: 49.97,\n    low: 49.9516,\n    close: 49.965,\n    volume: 11222,\n  },\n  {\n    date: 1462203480000,\n    open: 49.965,\n    high: 50.02,\n    low: 49.96,\n    close: 50.0075,\n    volume: 70311,\n  },\n  {\n    date: 1462203540000,\n    open: 50.005,\n    high: 50.03,\n    low: 49.99,\n    close: 50.0261,\n    volume: 32086,\n  },\n  {\n    date: 1462203600000,\n    open: 50.03,\n    high: 50.035,\n    low: 50.02,\n    close: 50.0201,\n    volume: 22722,\n  },\n  {\n    date: 1462203660000,\n    open: 50.02,\n    high: 50.03,\n    low: 50.01,\n    close: 50.01,\n    volume: 52278,\n  },\n  {\n    date: 1462203720000,\n    open: 50.01,\n    high: 50.02,\n    low: 50,\n    close: 50.0095,\n    volume: 32807,\n  },\n  {\n    date: 1462203780000,\n    open: 50.005,\n    high: 50.015,\n    low: 50,\n    close: 50.005,\n    volume: 29600,\n  },\n  {\n    date: 1462203840000,\n    open: 50.005,\n    high: 50.04,\n    low: 49.995,\n    close: 50.028,\n    volume: 62627,\n  },\n  {\n    date: 1462203900000,\n    open: 50.02,\n    high: 50.03,\n    low: 49.96,\n    close: 49.99,\n    volume: 89772,\n  },\n  {\n    date: 1462203960000,\n    open: 49.985,\n    high: 49.9998,\n    low: 49.96,\n    close: 49.96,\n    volume: 27477,\n  },\n  {\n    date: 1462204020000,\n    open: 49.96,\n    high: 49.96,\n    low: 49.925,\n    close: 49.94,\n    volume: 32903,\n  },\n  {\n    date: 1462204080000,\n    open: 49.95,\n    high: 49.96,\n    low: 49.94,\n    close: 49.95,\n    volume: 28860,\n  },\n  {\n    date: 1462204140000,\n    open: 49.95,\n    high: 49.967,\n    low: 49.93,\n    close: 49.967,\n    volume: 21759,\n  },\n  {\n    date: 1462204200000,\n    open: 49.9635,\n    high: 49.98,\n    low: 49.95,\n    close: 49.97,\n    volume: 60051,\n  },\n  {\n    date: 1462204260000,\n    open: 49.98,\n    high: 49.98,\n    low: 49.97,\n    close: 49.975,\n    volume: 9734,\n  },\n  {\n    date: 1462204320000,\n    open: 49.9701,\n    high: 49.975,\n    low: 49.92,\n    close: 49.95,\n    volume: 51141,\n  },\n  {\n    date: 1462204380000,\n    open: 49.955,\n    high: 49.955,\n    low: 49.925,\n    close: 49.93,\n    volume: 29814,\n  },\n  {\n    date: 1462204440000,\n    open: 49.92,\n    high: 49.97,\n    low: 49.92,\n    close: 49.97,\n    volume: 75962,\n  },\n  {\n    date: 1462204500000,\n    open: 49.97,\n    high: 49.995,\n    low: 49.95,\n    close: 49.95,\n    volume: 83880,\n  },\n  {\n    date: 1462204560000,\n    open: 49.9599,\n    high: 49.9799,\n    low: 49.95,\n    close: 49.965,\n    volume: 44091,\n  },\n  {\n    date: 1462204620000,\n    open: 49.96,\n    high: 50.019,\n    low: 49.96,\n    close: 49.99,\n    volume: 76264,\n  },\n  {\n    date: 1462204680000,\n    open: 49.985,\n    high: 49.99,\n    low: 49.9425,\n    close: 49.9601,\n    volume: 33720,\n  },\n  {\n    date: 1462204740000,\n    open: 49.9689,\n    high: 49.97,\n    low: 49.93,\n    close: 49.93,\n    volume: 31629,\n  },\n  {\n    date: 1462204800000,\n    open: 49.9201,\n    high: 49.9201,\n    low: 49.905,\n    close: 49.91,\n    volume: 42481,\n  },\n  {\n    date: 1462204860000,\n    open: 49.91,\n    high: 49.91,\n    low: 49.85,\n    close: 49.8701,\n    volume: 173203,\n  },\n  {\n    date: 1462204920000,\n    open: 49.875,\n    high: 49.93,\n    low: 49.8735,\n    close: 49.929,\n    volume: 40586,\n  },\n  {\n    date: 1462204980000,\n    open: 49.93,\n    high: 49.95,\n    low: 49.9,\n    close: 49.94,\n    volume: 176314,\n  },\n  {\n    date: 1462205040000,\n    open: 49.94,\n    high: 49.965,\n    low: 49.94,\n    close: 49.95,\n    volume: 69635,\n  },\n  {\n    date: 1462205100000,\n    open: 49.945,\n    high: 49.97,\n    low: 49.94,\n    close: 49.97,\n    volume: 31492,\n  },\n  {\n    date: 1462205160000,\n    open: 49.97,\n    high: 49.999,\n    low: 49.96,\n    close: 49.99,\n    volume: 42553,\n  },\n  {\n    date: 1462205220000,\n    open: 49.99,\n    high: 50,\n    low: 49.97,\n    close: 49.99,\n    volume: 53746,\n  },\n  {\n    date: 1462205280000,\n    open: 49.9938,\n    high: 50.0099,\n    low: 49.98,\n    close: 49.9868,\n    volume: 43952,\n  },\n  {\n    date: 1462205340000,\n    open: 49.985,\n    high: 50.01,\n    low: 49.98,\n    close: 50,\n    volume: 150610,\n  },\n  {\n    date: 1462205400000,\n    open: 49.995,\n    high: 50.0299,\n    low: 49.995,\n    close: 50,\n    volume: 69635,\n  },\n  {\n    date: 1462205460000,\n    open: 50.005,\n    high: 50.03,\n    low: 50,\n    close: 50.025,\n    volume: 59470,\n  },\n  {\n    date: 1462205520000,\n    open: 50.025,\n    high: 50.045,\n    low: 50.02,\n    close: 50.045,\n    volume: 61870,\n  },\n  {\n    date: 1462205580000,\n    open: 50.0465,\n    high: 50.07,\n    low: 50.03,\n    close: 50.03,\n    volume: 242095,\n  },\n  {\n    date: 1462205640000,\n    open: 50.03,\n    high: 50.03,\n    low: 49.99,\n    close: 50,\n    volume: 24634,\n  },\n  {\n    date: 1462205700000,\n    open: 50,\n    high: 50.01,\n    low: 50,\n    close: 50.005,\n    volume: 17981,\n  },\n  {\n    date: 1462205760000,\n    open: 50.005,\n    high: 50.005,\n    low: 49.97,\n    close: 49.97,\n    volume: 60062,\n  },\n  {\n    date: 1462205820000,\n    open: 49.975,\n    high: 49.98,\n    low: 49.97,\n    close: 49.975,\n    volume: 14996,\n  },\n  {\n    date: 1462205880000,\n    open: 49.9761,\n    high: 50,\n    low: 49.97,\n    close: 50,\n    volume: 34480,\n  },\n  {\n    date: 1462205940000,\n    open: 49.995,\n    high: 50,\n    low: 49.99,\n    close: 49.99,\n    volume: 55279,\n  },\n  {\n    date: 1462206000000,\n    open: 49.995,\n    high: 49.999,\n    low: 49.98,\n    close: 49.98,\n    volume: 26135,\n  },\n  {\n    date: 1462206060000,\n    open: 49.985,\n    high: 50,\n    low: 49.98,\n    close: 49.995,\n    volume: 54542,\n  },\n  {\n    date: 1462206120000,\n    open: 49.99,\n    high: 50.016,\n    low: 49.99,\n    close: 50.01,\n    volume: 46633,\n  },\n  {\n    date: 1462206180000,\n    open: 50.0135,\n    high: 50.0135,\n    low: 49.97,\n    close: 49.975,\n    volume: 51402,\n  },\n  {\n    date: 1462206240000,\n    open: 49.975,\n    high: 49.99,\n    low: 49.955,\n    close: 49.96,\n    volume: 49359,\n  },\n  {\n    date: 1462206300000,\n    open: 49.95,\n    high: 49.98,\n    low: 49.95,\n    close: 49.97,\n    volume: 24635,\n  },\n  {\n    date: 1462206360000,\n    open: 49.97,\n    high: 49.98,\n    low: 49.96,\n    close: 49.96,\n    volume: 14157,\n  },\n  {\n    date: 1462206420000,\n    open: 49.96,\n    high: 49.96,\n    low: 49.9301,\n    close: 49.945,\n    volume: 25797,\n  },\n  {\n    date: 1462206480000,\n    open: 49.94,\n    high: 49.95,\n    low: 49.92,\n    close: 49.925,\n    volume: 25283,\n  },\n  {\n    date: 1462206540000,\n    open: 49.925,\n    high: 49.94,\n    low: 49.92,\n    close: 49.93,\n    volume: 27998,\n  },\n  {\n    date: 1462206600000,\n    open: 49.92,\n    high: 49.93,\n    low: 49.91,\n    close: 49.93,\n    volume: 30191,\n  },\n  {\n    date: 1462206660000,\n    open: 49.94,\n    high: 49.9668,\n    low: 49.94,\n    close: 49.96,\n    volume: 38762,\n  },\n  {\n    date: 1462206720000,\n    open: 49.96,\n    high: 49.966,\n    low: 49.95,\n    close: 49.95,\n    volume: 25694,\n  },\n  {\n    date: 1462206780000,\n    open: 49.95,\n    high: 49.96,\n    low: 49.94,\n    close: 49.96,\n    volume: 15568,\n  },\n  {\n    date: 1462206840000,\n    open: 49.96,\n    high: 50.015,\n    low: 49.955,\n    close: 50.01,\n    volume: 58300,\n  },\n  {\n    date: 1462206900000,\n    open: 50.01,\n    high: 50.02,\n    low: 50.01,\n    close: 50.01,\n    volume: 32662,\n  },\n  {\n    date: 1462206960000,\n    open: 50.015,\n    high: 50.04,\n    low: 50.015,\n    close: 50.02,\n    volume: 27421,\n  },\n  {\n    date: 1462207020000,\n    open: 50.02,\n    high: 50.02,\n    low: 49.97,\n    close: 49.9799,\n    volume: 29390,\n  },\n  {\n    date: 1462207080000,\n    open: 49.97,\n    high: 49.99,\n    low: 49.97,\n    close: 49.979,\n    volume: 18658,\n  },\n  {\n    date: 1462207140000,\n    open: 49.97,\n    high: 49.99,\n    low: 49.97,\n    close: 49.985,\n    volume: 14245,\n  },\n  {\n    date: 1462207200000,\n    open: 49.985,\n    high: 50,\n    low: 49.97,\n    close: 49.97,\n    volume: 38179,\n  },\n  {\n    date: 1462207260000,\n    open: 49.9701,\n    high: 50,\n    low: 49.97,\n    close: 49.97,\n    volume: 43761,\n  },\n  {\n    date: 1462207320000,\n    open: 49.9799,\n    high: 49.98,\n    low: 49.96,\n    close: 49.98,\n    volume: 102966,\n  },\n  {\n    date: 1462207380000,\n    open: 49.98,\n    high: 49.995,\n    low: 49.95,\n    close: 49.95,\n    volume: 51528,\n  },\n  {\n    date: 1462207440000,\n    open: 49.951,\n    high: 49.955,\n    low: 49.935,\n    close: 49.94,\n    volume: 27753,\n  },\n  {\n    date: 1462207500000,\n    open: 49.94,\n    high: 49.98,\n    low: 49.94,\n    close: 49.9599,\n    volume: 67542,\n  },\n  {\n    date: 1462207560000,\n    open: 49.95,\n    high: 49.96,\n    low: 49.94,\n    close: 49.96,\n    volume: 23413,\n  },\n  {\n    date: 1462207620000,\n    open: 49.96,\n    high: 50.0071,\n    low: 49.96,\n    close: 50.0071,\n    volume: 68846,\n  },\n  {\n    date: 1462207680000,\n    open: 50,\n    high: 50.02,\n    low: 50,\n    close: 50.01,\n    volume: 67002,\n  },\n  {\n    date: 1462207740000,\n    open: 50.015,\n    high: 50.015,\n    low: 49.99,\n    close: 49.995,\n    volume: 65707,\n  },\n  {\n    date: 1462207800000,\n    open: 49.99,\n    high: 50,\n    low: 49.98,\n    close: 49.99,\n    volume: 43383,\n  },\n  {\n    date: 1462207860000,\n    open: 49.995,\n    high: 50,\n    low: 49.98,\n    close: 49.99,\n    volume: 15296,\n  },\n  {\n    date: 1462207920000,\n    open: 49.985,\n    high: 49.99,\n    low: 49.98,\n    close: 49.99,\n    volume: 19015,\n  },\n  {\n    date: 1462207980000,\n    open: 49.99,\n    high: 50.02,\n    low: 49.98,\n    close: 50.015,\n    volume: 43954,\n  },\n  {\n    date: 1462208040000,\n    open: 50.015,\n    high: 50.055,\n    low: 50.01,\n    close: 50.0468,\n    volume: 66019,\n  },\n  {\n    date: 1462208100000,\n    open: 50.05,\n    high: 50.06,\n    low: 50.04,\n    close: 50.05,\n    volume: 36506,\n  },\n  {\n    date: 1462208160000,\n    open: 50.045,\n    high: 50.055,\n    low: 50.04,\n    close: 50.04,\n    volume: 176238,\n  },\n  {\n    date: 1462208220000,\n    open: 50.04,\n    high: 50.06,\n    low: 50.025,\n    close: 50.025,\n    volume: 57360,\n  },\n  {\n    date: 1462208280000,\n    open: 50.03,\n    high: 50.03,\n    low: 49.98,\n    close: 49.99,\n    volume: 34135,\n  },\n  {\n    date: 1462208340000,\n    open: 49.98,\n    high: 50,\n    low: 49.98,\n    close: 50,\n    volume: 21953,\n  },\n  {\n    date: 1462208400000,\n    open: 49.995,\n    high: 50.03,\n    low: 49.99,\n    close: 50.03,\n    volume: 58199,\n  },\n  {\n    date: 1462208460000,\n    open: 50.02,\n    high: 50.03,\n    low: 50,\n    close: 50.01,\n    volume: 39514,\n  },\n  {\n    date: 1462208520000,\n    open: 50.01,\n    high: 50.03,\n    low: 50.01,\n    close: 50.025,\n    volume: 34770,\n  },\n  {\n    date: 1462208580000,\n    open: 50.03,\n    high: 50.03,\n    low: 49.9917,\n    close: 50.01,\n    volume: 79230,\n  },\n  {\n    date: 1462208640000,\n    open: 50.02,\n    high: 50.025,\n    low: 49.99,\n    close: 50,\n    volume: 167724,\n  },\n  {\n    date: 1462208700000,\n    open: 49.99,\n    high: 50,\n    low: 49.97,\n    close: 49.98,\n    volume: 50661,\n  },\n  {\n    date: 1462208760000,\n    open: 49.975,\n    high: 50,\n    low: 49.97,\n    close: 49.9915,\n    volume: 20363,\n  },\n  {\n    date: 1462208820000,\n    open: 50,\n    high: 50.01,\n    low: 49.99,\n    close: 50.01,\n    volume: 88475,\n  },\n  {\n    date: 1462208880000,\n    open: 50.005,\n    high: 50.03,\n    low: 49.99,\n    close: 50,\n    volume: 43532,\n  },\n  {\n    date: 1462208940000,\n    open: 50.005,\n    high: 50.005,\n    low: 49.99,\n    close: 49.995,\n    volume: 23248,\n  },\n  {\n    date: 1462209000000,\n    open: 50,\n    high: 50,\n    low: 49.99,\n    close: 49.995,\n    volume: 11605,\n  },\n  {\n    date: 1462209060000,\n    open: 49.995,\n    high: 50.035,\n    low: 49.99,\n    close: 50.035,\n    volume: 128323,\n  },\n  {\n    date: 1462209120000,\n    open: 50.03,\n    high: 50.09,\n    low: 50.03,\n    close: 50.09,\n    volume: 23832,\n  },\n  {\n    date: 1462209180000,\n    open: 50.09,\n    high: 50.135,\n    low: 50.0899,\n    close: 50.135,\n    volume: 83153,\n  },\n  {\n    date: 1462209240000,\n    open: 50.14,\n    high: 50.18,\n    low: 50.14,\n    close: 50.1772,\n    volume: 59374,\n  },\n  {\n    date: 1462209300000,\n    open: 50.18,\n    high: 50.2199,\n    low: 50.17,\n    close: 50.21,\n    volume: 97604,\n  },\n  {\n    date: 1462209360000,\n    open: 50.21,\n    high: 50.24,\n    low: 50.2035,\n    close: 50.214,\n    volume: 66495,\n  },\n  {\n    date: 1462209420000,\n    open: 50.22,\n    high: 50.23,\n    low: 50.21,\n    close: 50.2264,\n    volume: 302275,\n  },\n  {\n    date: 1462209480000,\n    open: 50.229,\n    high: 50.249,\n    low: 50.22,\n    close: 50.24,\n    volume: 68214,\n  },\n  {\n    date: 1462209540000,\n    open: 50.24,\n    high: 50.31,\n    low: 50.24,\n    close: 50.3,\n    volume: 112581,\n  },\n  {\n    date: 1462209600000,\n    open: 50.305,\n    high: 50.31,\n    low: 50.2992,\n    close: 50.3061,\n    volume: 66327,\n  },\n  {\n    date: 1462209660000,\n    open: 50.3,\n    high: 50.31,\n    low: 50.3,\n    close: 50.305,\n    volume: 60533,\n  },\n  {\n    date: 1462209720000,\n    open: 50.31,\n    high: 50.34,\n    low: 50.3,\n    close: 50.335,\n    volume: 157674,\n  },\n  {\n    date: 1462209780000,\n    open: 50.3368,\n    high: 50.36,\n    low: 50.32,\n    close: 50.325,\n    volume: 107222,\n  },\n  {\n    date: 1462209840000,\n    open: 50.315,\n    high: 50.32,\n    low: 50.25,\n    close: 50.25,\n    volume: 56936,\n  },\n  {\n    date: 1462209900000,\n    open: 50.26,\n    high: 50.31,\n    low: 50.255,\n    close: 50.3,\n    volume: 95359,\n  },\n  {\n    date: 1462209960000,\n    open: 50.3061,\n    high: 50.32,\n    low: 50.27,\n    close: 50.28,\n    volume: 53993,\n  },\n  {\n    date: 1462210020000,\n    open: 50.275,\n    high: 50.28,\n    low: 50.27,\n    close: 50.275,\n    volume: 35828,\n  },\n  {\n    date: 1462210080000,\n    open: 50.275,\n    high: 50.2899,\n    low: 50.27,\n    close: 50.28,\n    volume: 24367,\n  },\n  {\n    date: 1462210140000,\n    open: 50.29,\n    high: 50.3,\n    low: 50.28,\n    close: 50.299,\n    volume: 27681,\n  },\n  {\n    date: 1462210200000,\n    open: 50.295,\n    high: 50.33,\n    low: 50.295,\n    close: 50.325,\n    volume: 50349,\n  },\n  {\n    date: 1462210260000,\n    open: 50.3204,\n    high: 50.37,\n    low: 50.32,\n    close: 50.33,\n    volume: 89757,\n  },\n  {\n    date: 1462210320000,\n    open: 50.32,\n    high: 50.3261,\n    low: 50.28,\n    close: 50.285,\n    volume: 36574,\n  },\n  {\n    date: 1462210380000,\n    open: 50.29,\n    high: 50.31,\n    low: 50.285,\n    close: 50.305,\n    volume: 21320,\n  },\n  {\n    date: 1462210440000,\n    open: 50.3061,\n    high: 50.3468,\n    low: 50.3,\n    close: 50.345,\n    volume: 31967,\n  },\n  {\n    date: 1462210500000,\n    open: 50.345,\n    high: 50.405,\n    low: 50.345,\n    close: 50.4,\n    volume: 163334,\n  },\n  {\n    date: 1462210560000,\n    open: 50.405,\n    high: 50.4099,\n    low: 50.39,\n    close: 50.4,\n    volume: 91658,\n  },\n  {\n    date: 1462210620000,\n    open: 50.4,\n    high: 50.44,\n    low: 50.4,\n    close: 50.44,\n    volume: 141099,\n  },\n  {\n    date: 1462210680000,\n    open: 50.44,\n    high: 50.47,\n    low: 50.4355,\n    close: 50.455,\n    volume: 188915,\n  },\n  {\n    date: 1462210740000,\n    open: 50.45,\n    high: 50.46,\n    low: 50.41,\n    close: 50.415,\n    volume: 74593,\n  },\n  {\n    date: 1462210800000,\n    open: 50.415,\n    high: 50.43,\n    low: 50.41,\n    close: 50.425,\n    volume: 73084,\n  },\n  {\n    date: 1462210860000,\n    open: 50.43,\n    high: 50.48,\n    low: 50.42,\n    close: 50.48,\n    volume: 88868,\n  },\n  {\n    date: 1462210920000,\n    open: 50.48,\n    high: 50.5,\n    low: 50.48,\n    close: 50.495,\n    volume: 131915,\n  },\n  {\n    date: 1462210980000,\n    open: 50.495,\n    high: 50.52,\n    low: 50.48,\n    close: 50.5195,\n    volume: 134666,\n  },\n  {\n    date: 1462211040000,\n    open: 50.5164,\n    high: 50.54,\n    low: 50.51,\n    close: 50.54,\n    volume: 97069,\n  },\n  {\n    date: 1462211100000,\n    open: 50.54,\n    high: 50.55,\n    low: 50.5299,\n    close: 50.535,\n    volume: 123365,\n  },\n  {\n    date: 1462211160000,\n    open: 50.53,\n    high: 50.53,\n    low: 50.51,\n    close: 50.515,\n    volume: 71038,\n  },\n  {\n    date: 1462211220000,\n    open: 50.52,\n    high: 50.53,\n    low: 50.43,\n    close: 50.435,\n    volume: 97679,\n  },\n  {\n    date: 1462211280000,\n    open: 50.445,\n    high: 50.5,\n    low: 50.435,\n    close: 50.48,\n    volume: 107166,\n  },\n  {\n    date: 1462211340000,\n    open: 50.489,\n    high: 50.53,\n    low: 50.489,\n    close: 50.53,\n    volume: 108572,\n  },\n  {\n    date: 1462211400000,\n    open: 50.5261,\n    high: 50.55,\n    low: 50.52,\n    close: 50.54,\n    volume: 115336,\n  },\n  {\n    date: 1462211460000,\n    open: 50.54,\n    high: 50.545,\n    low: 50.53,\n    close: 50.535,\n    volume: 53259,\n  },\n  {\n    date: 1462211520000,\n    open: 50.5336,\n    high: 50.54,\n    low: 50.49,\n    close: 50.49,\n    volume: 74549,\n  },\n  {\n    date: 1462211580000,\n    open: 50.49,\n    high: 50.4965,\n    low: 50.46,\n    close: 50.46,\n    volume: 76228,\n  },\n  {\n    date: 1462211640000,\n    open: 50.47,\n    high: 50.52,\n    low: 50.47,\n    close: 50.51,\n    volume: 71081,\n  },\n  {\n    date: 1462211700000,\n    open: 50.5136,\n    high: 50.5275,\n    low: 50.51,\n    close: 50.52,\n    volume: 34096,\n  },\n  {\n    date: 1462211760000,\n    open: 50.53,\n    high: 50.53,\n    low: 50.52,\n    close: 50.53,\n    volume: 52755,\n  },\n  {\n    date: 1462211820000,\n    open: 50.5262,\n    high: 50.54,\n    low: 50.52,\n    close: 50.53,\n    volume: 79888,\n  },\n  {\n    date: 1462211880000,\n    open: 50.53,\n    high: 50.589,\n    low: 50.53,\n    close: 50.585,\n    volume: 129080,\n  },\n  {\n    date: 1462211940000,\n    open: 50.58,\n    high: 50.59,\n    low: 50.53,\n    close: 50.535,\n    volume: 97488,\n  },\n  {\n    date: 1462212000000,\n    open: 50.53,\n    high: 50.54,\n    low: 50.51,\n    close: 50.515,\n    volume: 76128,\n  },\n  {\n    date: 1462212060000,\n    open: 50.52,\n    high: 50.53,\n    low: 50.49,\n    close: 50.495,\n    volume: 81237,\n  },\n  {\n    date: 1462212120000,\n    open: 50.495,\n    high: 50.5,\n    low: 50.49,\n    close: 50.49,\n    volume: 23706,\n  },\n  {\n    date: 1462212180000,\n    open: 50.49,\n    high: 50.5,\n    low: 50.49,\n    close: 50.49,\n    volume: 25104,\n  },\n  {\n    date: 1462212240000,\n    open: 50.495,\n    high: 50.52,\n    low: 50.49,\n    close: 50.515,\n    volume: 61722,\n  },\n  {\n    date: 1462212300000,\n    open: 50.52,\n    high: 50.56,\n    low: 50.52,\n    close: 50.555,\n    volume: 78302,\n  },\n  {\n    date: 1462212360000,\n    open: 50.56,\n    high: 50.59,\n    low: 50.56,\n    close: 50.585,\n    volume: 133662,\n  },\n  {\n    date: 1462212420000,\n    open: 50.59,\n    high: 50.6,\n    low: 50.59,\n    close: 50.595,\n    volume: 65073,\n  },\n  {\n    date: 1462212480000,\n    open: 50.59,\n    high: 50.62,\n    low: 50.59,\n    close: 50.62,\n    volume: 65571,\n  },\n  {\n    date: 1462212540000,\n    open: 50.6129,\n    high: 50.64,\n    low: 50.6129,\n    close: 50.63,\n    volume: 150715,\n  },\n  {\n    date: 1462212600000,\n    open: 50.63,\n    high: 50.64,\n    low: 50.61,\n    close: 50.61,\n    volume: 123197,\n  },\n  {\n    date: 1462212660000,\n    open: 50.61,\n    high: 50.63,\n    low: 50.605,\n    close: 50.63,\n    volume: 36624,\n  },\n  {\n    date: 1462212720000,\n    open: 50.6295,\n    high: 50.65,\n    low: 50.6295,\n    close: 50.65,\n    volume: 61779,\n  },\n  {\n    date: 1462212780000,\n    open: 50.65,\n    high: 50.67,\n    low: 50.635,\n    close: 50.637,\n    volume: 111500,\n  },\n  {\n    date: 1462212840000,\n    open: 50.63,\n    high: 50.63,\n    low: 50.59,\n    close: 50.6,\n    volume: 88467,\n  },\n  {\n    date: 1462212900000,\n    open: 50.6,\n    high: 50.629,\n    low: 50.59,\n    close: 50.6207,\n    volume: 37352,\n  },\n  {\n    date: 1462212960000,\n    open: 50.63,\n    high: 50.63,\n    low: 50.62,\n    close: 50.62,\n    volume: 67099,\n  },\n  {\n    date: 1462213020000,\n    open: 50.62,\n    high: 50.63,\n    low: 50.61,\n    close: 50.62,\n    volume: 46942,\n  },\n  {\n    date: 1462213080000,\n    open: 50.6274,\n    high: 50.64,\n    low: 50.61,\n    close: 50.61,\n    volume: 60069,\n  },\n  {\n    date: 1462213140000,\n    open: 50.615,\n    high: 50.63,\n    low: 50.59,\n    close: 50.605,\n    volume: 93512,\n  },\n  {\n    date: 1462213200000,\n    open: 50.605,\n    high: 50.61,\n    low: 50.59,\n    close: 50.595,\n    volume: 33400,\n  },\n  {\n    date: 1462213260000,\n    open: 50.6,\n    high: 50.6399,\n    low: 50.595,\n    close: 50.6399,\n    volume: 33702,\n  },\n  {\n    date: 1462213320000,\n    open: 50.63,\n    high: 50.64,\n    low: 50.61,\n    close: 50.61,\n    volume: 113649,\n  },\n  {\n    date: 1462213380000,\n    open: 50.61,\n    high: 50.6101,\n    low: 50.6,\n    close: 50.61,\n    volume: 43128,\n  },\n  {\n    date: 1462213440000,\n    open: 50.62,\n    high: 50.625,\n    low: 50.61,\n    close: 50.61,\n    volume: 23815,\n  },\n  {\n    date: 1462213500000,\n    open: 50.61,\n    high: 50.62,\n    low: 50.59,\n    close: 50.6074,\n    volume: 88530,\n  },\n  {\n    date: 1462213560000,\n    open: 50.6026,\n    high: 50.619,\n    low: 50.59,\n    close: 50.5935,\n    volume: 41174,\n  },\n  {\n    date: 1462213620000,\n    open: 50.6,\n    high: 50.61,\n    low: 50.58,\n    close: 50.59,\n    volume: 51799,\n  },\n  {\n    date: 1462213680000,\n    open: 50.595,\n    high: 50.595,\n    low: 50.55,\n    close: 50.5533,\n    volume: 47531,\n  },\n  {\n    date: 1462213740000,\n    open: 50.555,\n    high: 50.57,\n    low: 50.55,\n    close: 50.565,\n    volume: 72984,\n  },\n  {\n    date: 1462213800000,\n    open: 50.56,\n    high: 50.61,\n    low: 50.56,\n    close: 50.6,\n    volume: 81088,\n  },\n  {\n    date: 1462213860000,\n    open: 50.6,\n    high: 50.61,\n    low: 50.595,\n    close: 50.61,\n    volume: 61154,\n  },\n  {\n    date: 1462213920000,\n    open: 50.6167,\n    high: 50.63,\n    low: 50.61,\n    close: 50.616,\n    volume: 27960,\n  },\n  {\n    date: 1462213980000,\n    open: 50.6165,\n    high: 50.62,\n    low: 50.56,\n    close: 50.565,\n    volume: 88769,\n  },\n  {\n    date: 1462214040000,\n    open: 50.56,\n    high: 50.57,\n    low: 50.56,\n    close: 50.57,\n    volume: 61664,\n  },\n  {\n    date: 1462214100000,\n    open: 50.56,\n    high: 50.57,\n    low: 50.56,\n    close: 50.57,\n    volume: 33457,\n  },\n  {\n    date: 1462214160000,\n    open: 50.5657,\n    high: 50.61,\n    low: 50.5657,\n    close: 50.6067,\n    volume: 38679,\n  },\n  {\n    date: 1462214220000,\n    open: 50.605,\n    high: 50.62,\n    low: 50.605,\n    close: 50.6163,\n    volume: 28644,\n  },\n  {\n    date: 1462214280000,\n    open: 50.62,\n    high: 50.62,\n    low: 50.59,\n    close: 50.605,\n    volume: 81257,\n  },\n  {\n    date: 1462214340000,\n    open: 50.6,\n    high: 50.61,\n    low: 50.58,\n    close: 50.59,\n    volume: 45033,\n  },\n  {\n    date: 1462214400000,\n    open: 50.5899,\n    high: 50.59,\n    low: 50.57,\n    close: 50.58,\n    volume: 28136,\n  },\n  {\n    date: 1462214460000,\n    open: 50.57,\n    high: 50.58,\n    low: 50.56,\n    close: 50.565,\n    volume: 36647,\n  },\n  {\n    date: 1462214520000,\n    open: 50.5601,\n    high: 50.57,\n    low: 50.56,\n    close: 50.565,\n    volume: 21623,\n  },\n  {\n    date: 1462214580000,\n    open: 50.56,\n    high: 50.58,\n    low: 50.56,\n    close: 50.57,\n    volume: 34798,\n  },\n  {\n    date: 1462214640000,\n    open: 50.57,\n    high: 50.59,\n    low: 50.57,\n    close: 50.588,\n    volume: 54767,\n  },\n  {\n    date: 1462214700000,\n    open: 50.59,\n    high: 50.63,\n    low: 50.59,\n    close: 50.6245,\n    volume: 91508,\n  },\n  {\n    date: 1462214760000,\n    open: 50.621,\n    high: 50.63,\n    low: 50.62,\n    close: 50.62,\n    volume: 27892,\n  },\n  {\n    date: 1462214820000,\n    open: 50.62,\n    high: 50.63,\n    low: 50.62,\n    close: 50.6299,\n    volume: 44027,\n  },\n  {\n    date: 1462214880000,\n    open: 50.62,\n    high: 50.65,\n    low: 50.62,\n    close: 50.65,\n    volume: 47875,\n  },\n  {\n    date: 1462214940000,\n    open: 50.64,\n    high: 50.67,\n    low: 50.64,\n    close: 50.647,\n    volume: 169872,\n  },\n  {\n    date: 1462215000000,\n    open: 50.64,\n    high: 50.69,\n    low: 50.63,\n    close: 50.68,\n    volume: 107566,\n  },\n  {\n    date: 1462215060000,\n    open: 50.67,\n    high: 50.68,\n    low: 50.66,\n    close: 50.6769,\n    volume: 43839,\n  },\n  {\n    date: 1462215120000,\n    open: 50.68,\n    high: 50.7,\n    low: 50.67,\n    close: 50.67,\n    volume: 99761,\n  },\n  {\n    date: 1462215180000,\n    open: 50.6738,\n    high: 50.68,\n    low: 50.66,\n    close: 50.67,\n    volume: 37683,\n  },\n  {\n    date: 1462215240000,\n    open: 50.665,\n    high: 50.665,\n    low: 50.63,\n    close: 50.655,\n    volume: 153463,\n  },\n  {\n    date: 1462215300000,\n    open: 50.65,\n    high: 50.66,\n    low: 50.64,\n    close: 50.645,\n    volume: 109467,\n  },\n  {\n    date: 1462215360000,\n    open: 50.6401,\n    high: 50.65,\n    low: 50.64,\n    close: 50.65,\n    volume: 54627,\n  },\n  {\n    date: 1462215420000,\n    open: 50.65,\n    high: 50.69,\n    low: 50.64,\n    close: 50.685,\n    volume: 86575,\n  },\n  {\n    date: 1462215480000,\n    open: 50.69,\n    high: 50.745,\n    low: 50.68,\n    close: 50.73,\n    volume: 114430,\n  },\n  {\n    date: 1462215540000,\n    open: 50.72,\n    high: 50.73,\n    low: 50.71,\n    close: 50.71,\n    volume: 24848,\n  },\n  {\n    date: 1462215600000,\n    open: 50.7137,\n    high: 50.72,\n    low: 50.71,\n    close: 50.715,\n    volume: 28641,\n  },\n  {\n    date: 1462215660000,\n    open: 50.72,\n    high: 50.72,\n    low: 50.71,\n    close: 50.715,\n    volume: 80936,\n  },\n  {\n    date: 1462215720000,\n    open: 50.715,\n    high: 50.73,\n    low: 50.7,\n    close: 50.705,\n    volume: 147803,\n  },\n  {\n    date: 1462215780000,\n    open: 50.71,\n    high: 50.72,\n    low: 50.69,\n    close: 50.71,\n    volume: 77205,\n  },\n  {\n    date: 1462215840000,\n    open: 50.71,\n    high: 50.72,\n    low: 50.7,\n    close: 50.715,\n    volume: 62003,\n  },\n  {\n    date: 1462215900000,\n    open: 50.7,\n    high: 50.73,\n    low: 50.7,\n    close: 50.73,\n    volume: 63127,\n  },\n  {\n    date: 1462215960000,\n    open: 50.721,\n    high: 50.73,\n    low: 50.72,\n    close: 50.72,\n    volume: 68755,\n  },\n  {\n    date: 1462216020000,\n    open: 50.715,\n    high: 50.72,\n    low: 50.67,\n    close: 50.6729,\n    volume: 79729,\n  },\n  {\n    date: 1462216080000,\n    open: 50.675,\n    high: 50.6964,\n    low: 50.6701,\n    close: 50.685,\n    volume: 76882,\n  },\n  {\n    date: 1462216140000,\n    open: 50.685,\n    high: 50.7,\n    low: 50.68,\n    close: 50.695,\n    volume: 58335,\n  },\n  {\n    date: 1462216200000,\n    open: 50.69,\n    high: 50.71,\n    low: 50.69,\n    close: 50.71,\n    volume: 40624,\n  },\n  {\n    date: 1462216260000,\n    open: 50.705,\n    high: 50.71,\n    low: 50.69,\n    close: 50.695,\n    volume: 47258,\n  },\n  {\n    date: 1462216320000,\n    open: 50.695,\n    high: 50.7,\n    low: 50.685,\n    close: 50.6995,\n    volume: 98896,\n  },\n  {\n    date: 1462216380000,\n    open: 50.69,\n    high: 50.7,\n    low: 50.67,\n    close: 50.675,\n    volume: 94653,\n  },\n  {\n    date: 1462216440000,\n    open: 50.68,\n    high: 50.7,\n    low: 50.67,\n    close: 50.69,\n    volume: 45407,\n  },\n  {\n    date: 1462216500000,\n    open: 50.695,\n    high: 50.75,\n    low: 50.695,\n    close: 50.74,\n    volume: 108576,\n  },\n  {\n    date: 1462216560000,\n    open: 50.75,\n    high: 50.75,\n    low: 50.73,\n    close: 50.735,\n    volume: 224575,\n  },\n  {\n    date: 1462216620000,\n    open: 50.73,\n    high: 50.74,\n    low: 50.71,\n    close: 50.71,\n    volume: 74616,\n  },\n  {\n    date: 1462216680000,\n    open: 50.72,\n    high: 50.72,\n    low: 50.6902,\n    close: 50.7,\n    volume: 49485,\n  },\n  {\n    date: 1462216740000,\n    open: 50.7,\n    high: 50.71,\n    low: 50.67,\n    close: 50.67,\n    volume: 57140,\n  },\n  {\n    date: 1462216800000,\n    open: 50.67,\n    high: 50.68,\n    low: 50.66,\n    close: 50.68,\n    volume: 52434,\n  },\n  {\n    date: 1462216860000,\n    open: 50.68,\n    high: 50.68,\n    low: 50.64,\n    close: 50.645,\n    volume: 81933,\n  },\n  {\n    date: 1462216920000,\n    open: 50.645,\n    high: 50.67,\n    low: 50.64,\n    close: 50.6653,\n    volume: 49693,\n  },\n  {\n    date: 1462216980000,\n    open: 50.67,\n    high: 50.6761,\n    low: 50.66,\n    close: 50.675,\n    volume: 63647,\n  },\n  {\n    date: 1462217040000,\n    open: 50.675,\n    high: 50.6799,\n    low: 50.65,\n    close: 50.655,\n    volume: 105850,\n  },\n  {\n    date: 1462217100000,\n    open: 50.65,\n    high: 50.679,\n    low: 50.65,\n    close: 50.65,\n    volume: 92948,\n  },\n  {\n    date: 1462217160000,\n    open: 50.65,\n    high: 50.66,\n    low: 50.65,\n    close: 50.6535,\n    volume: 21237,\n  },\n  {\n    date: 1462217220000,\n    open: 50.6586,\n    high: 50.66,\n    low: 50.61,\n    close: 50.61,\n    volume: 76515,\n  },\n  {\n    date: 1462217280000,\n    open: 50.615,\n    high: 50.62,\n    low: 50.6,\n    close: 50.62,\n    volume: 106158,\n  },\n  {\n    date: 1462217340000,\n    open: 50.61,\n    high: 50.65,\n    low: 50.61,\n    close: 50.65,\n    volume: 60526,\n  },\n  {\n    date: 1462217400000,\n    open: 50.65,\n    high: 50.66,\n    low: 50.64,\n    close: 50.64,\n    volume: 61668,\n  },\n  {\n    date: 1462217460000,\n    open: 50.64,\n    high: 50.655,\n    low: 50.61,\n    close: 50.6133,\n    volume: 163654,\n  },\n  {\n    date: 1462217520000,\n    open: 50.61,\n    high: 50.61,\n    low: 50.59,\n    close: 50.59,\n    volume: 55304,\n  },\n  {\n    date: 1462217580000,\n    open: 50.59,\n    high: 50.595,\n    low: 50.56,\n    close: 50.56,\n    volume: 77721,\n  },\n  {\n    date: 1462217640000,\n    open: 50.56,\n    high: 50.56,\n    low: 50.52,\n    close: 50.55,\n    volume: 109330,\n  },\n  {\n    date: 1462217700000,\n    open: 50.55,\n    high: 50.58,\n    low: 50.54,\n    close: 50.542,\n    volume: 117971,\n  },\n  {\n    date: 1462217760000,\n    open: 50.545,\n    high: 50.62,\n    low: 50.54,\n    close: 50.62,\n    volume: 131595,\n  },\n  {\n    date: 1462217820000,\n    open: 50.62,\n    high: 50.64,\n    low: 50.61,\n    close: 50.6399,\n    volume: 136715,\n  },\n  {\n    date: 1462217880000,\n    open: 50.635,\n    high: 50.68,\n    low: 50.61,\n    close: 50.68,\n    volume: 166729,\n  },\n  {\n    date: 1462217940000,\n    open: 50.68,\n    high: 50.685,\n    low: 50.64,\n    close: 50.645,\n    volume: 115458,\n  },\n  {\n    date: 1462218000000,\n    open: 50.64,\n    high: 50.67,\n    low: 50.64,\n    close: 50.66,\n    volume: 105382,\n  },\n  {\n    date: 1462218060000,\n    open: 50.655,\n    high: 50.67,\n    low: 50.65,\n    close: 50.67,\n    volume: 61760,\n  },\n  {\n    date: 1462218120000,\n    open: 50.665,\n    high: 50.665,\n    low: 50.65,\n    close: 50.66,\n    volume: 69076,\n  },\n  {\n    date: 1462218180000,\n    open: 50.65,\n    high: 50.67,\n    low: 50.64,\n    close: 50.645,\n    volume: 129846,\n  },\n  {\n    date: 1462218240000,\n    open: 50.645,\n    high: 50.75,\n    low: 50.64,\n    close: 50.72,\n    volume: 193414,\n  },\n  {\n    date: 1462218300000,\n    open: 50.71,\n    high: 50.73,\n    low: 50.69,\n    close: 50.69,\n    volume: 57083,\n  },\n  {\n    date: 1462218360000,\n    open: 50.695,\n    high: 50.695,\n    low: 50.65,\n    close: 50.667,\n    volume: 129321,\n  },\n  {\n    date: 1462218420000,\n    open: 50.665,\n    high: 50.69,\n    low: 50.66,\n    close: 50.69,\n    volume: 94844,\n  },\n  {\n    date: 1462218480000,\n    open: 50.69,\n    high: 50.705,\n    low: 50.67,\n    close: 50.67,\n    volume: 112032,\n  },\n  {\n    date: 1462218540000,\n    open: 50.67,\n    high: 50.675,\n    low: 50.63,\n    close: 50.6533,\n    volume: 122329,\n  },\n  {\n    date: 1462218600000,\n    open: 50.656,\n    high: 50.67,\n    low: 50.64,\n    close: 50.65,\n    volume: 64886,\n  },\n  {\n    date: 1462218660000,\n    open: 50.645,\n    high: 50.66,\n    low: 50.64,\n    close: 50.65,\n    volume: 97294,\n  },\n  {\n    date: 1462218720000,\n    open: 50.6475,\n    high: 50.65,\n    low: 50.61,\n    close: 50.64,\n    volume: 127183,\n  },\n  {\n    date: 1462218780000,\n    open: 50.635,\n    high: 50.66,\n    low: 50.63,\n    close: 50.65,\n    volume: 82215,\n  },\n  {\n    date: 1462218840000,\n    open: 50.65,\n    high: 50.66,\n    low: 50.62,\n    close: 50.65,\n    volume: 134991,\n  },\n  {\n    date: 1462218900000,\n    open: 50.65,\n    high: 50.67,\n    low: 50.65,\n    close: 50.665,\n    volume: 114461,\n  },\n  {\n    date: 1462218960000,\n    open: 50.6601,\n    high: 50.67,\n    low: 50.64,\n    close: 50.64,\n    volume: 193977,\n  },\n  {\n    date: 1462219020000,\n    open: 50.64,\n    high: 50.65,\n    low: 50.61,\n    close: 50.635,\n    volume: 133969,\n  },\n  {\n    date: 1462219080000,\n    open: 50.635,\n    high: 50.66,\n    low: 50.615,\n    close: 50.65,\n    volume: 150671,\n  },\n  {\n    date: 1462219140000,\n    open: 50.65,\n    high: 50.66,\n    low: 50.64,\n    close: 50.645,\n    volume: 227904,\n  },\n  {\n    date: 1462219200000,\n    open: 50.64,\n    high: 50.65,\n    low: 50.59,\n    close: 50.61,\n    volume: 2042513,\n  },\n  {\n    date: 1462282200000,\n    open: 50.34,\n    high: 50.41,\n    low: 50.3,\n    close: 50.31,\n    volume: 278530,\n  },\n  {\n    date: 1462282260000,\n    open: 50.31,\n    high: 50.35,\n    low: 50.16,\n    close: 50.21,\n    volume: 99527,\n  },\n  {\n    date: 1462282320000,\n    open: 50.21,\n    high: 50.231,\n    low: 50.1799,\n    close: 50.18,\n    volume: 59633,\n  },\n  {\n    date: 1462282380000,\n    open: 50.19,\n    high: 50.225,\n    low: 50.145,\n    close: 50.225,\n    volume: 70851,\n  },\n  {\n    date: 1462282440000,\n    open: 50.22,\n    high: 50.25,\n    low: 50.16,\n    close: 50.16,\n    volume: 65430,\n  },\n  {\n    date: 1462282500000,\n    open: 50.16,\n    high: 50.2,\n    low: 50.1,\n    close: 50.175,\n    volume: 102411,\n  },\n  {\n    date: 1462282560000,\n    open: 50.18,\n    high: 50.24,\n    low: 50.17,\n    close: 50.23,\n    volume: 68389,\n  },\n  {\n    date: 1462282620000,\n    open: 50.23,\n    high: 50.29,\n    low: 50.19,\n    close: 50.285,\n    volume: 138112,\n  },\n  {\n    date: 1462282680000,\n    open: 50.2799,\n    high: 50.28,\n    low: 50.21,\n    close: 50.24,\n    volume: 49474,\n  },\n  {\n    date: 1462282740000,\n    open: 50.236,\n    high: 50.3,\n    low: 50.22,\n    close: 50.26,\n    volume: 95098,\n  },\n  {\n    date: 1462282800000,\n    open: 50.26,\n    high: 50.29,\n    low: 50.24,\n    close: 50.25,\n    volume: 52896,\n  },\n  {\n    date: 1462282860000,\n    open: 50.2416,\n    high: 50.25,\n    low: 50.16,\n    close: 50.215,\n    volume: 92093,\n  },\n  {\n    date: 1462282920000,\n    open: 50.215,\n    high: 50.22,\n    low: 50.2,\n    close: 50.21,\n    volume: 35945,\n  },\n  {\n    date: 1462282980000,\n    open: 50.2162,\n    high: 50.23,\n    low: 50.16,\n    close: 50.16,\n    volume: 56347,\n  },\n  {\n    date: 1462283040000,\n    open: 50.15,\n    high: 50.19,\n    low: 50.14,\n    close: 50.17,\n    volume: 58094,\n  },\n  {\n    date: 1462283100000,\n    open: 50.175,\n    high: 50.18,\n    low: 50.07,\n    close: 50.08,\n    volume: 68382,\n  },\n  {\n    date: 1462283160000,\n    open: 50.075,\n    high: 50.11,\n    low: 50.03,\n    close: 50.11,\n    volume: 132055,\n  },\n  {\n    date: 1462283220000,\n    open: 50.1,\n    high: 50.12,\n    low: 50.03,\n    close: 50.05,\n    volume: 88005,\n  },\n  {\n    date: 1462283280000,\n    open: 50.05,\n    high: 50.096,\n    low: 50.02,\n    close: 50.02,\n    volume: 88338,\n  },\n  {\n    date: 1462283340000,\n    open: 50.02,\n    high: 50.04,\n    low: 49.96,\n    close: 50.0395,\n    volume: 146919,\n  },\n  {\n    date: 1462283400000,\n    open: 50.04,\n    high: 50.04,\n    low: 49.95,\n    close: 49.97,\n    volume: 96254,\n  },\n  {\n    date: 1462283460000,\n    open: 49.97,\n    high: 50,\n    low: 49.92,\n    close: 49.95,\n    volume: 81110,\n  },\n  {\n    date: 1462283520000,\n    open: 49.94,\n    high: 49.95,\n    low: 49.9,\n    close: 49.9269,\n    volume: 74616,\n  },\n  {\n    date: 1462283580000,\n    open: 49.92,\n    high: 49.93,\n    low: 49.87,\n    close: 49.895,\n    volume: 79397,\n  },\n  {\n    date: 1462283640000,\n    open: 49.89,\n    high: 49.9699,\n    low: 49.89,\n    close: 49.955,\n    volume: 61579,\n  },\n  {\n    date: 1462283700000,\n    open: 49.95,\n    high: 49.97,\n    low: 49.91,\n    close: 49.925,\n    volume: 32367,\n  },\n  {\n    date: 1462283760000,\n    open: 49.92,\n    high: 50.005,\n    low: 49.92,\n    close: 49.97,\n    volume: 90385,\n  },\n  {\n    date: 1462283820000,\n    open: 49.97,\n    high: 50.05,\n    low: 49.95,\n    close: 50.01,\n    volume: 136819,\n  },\n  {\n    date: 1462283880000,\n    open: 50.015,\n    high: 50.06,\n    low: 50.01,\n    close: 50.035,\n    volume: 81739,\n  },\n  {\n    date: 1462283940000,\n    open: 50.03,\n    high: 50.07,\n    low: 50.02,\n    close: 50.065,\n    volume: 52931,\n  },\n  {\n    date: 1462284000000,\n    open: 50.06,\n    high: 50.06,\n    low: 50.01,\n    close: 50.04,\n    volume: 135210,\n  },\n  {\n    date: 1462284060000,\n    open: 50.03,\n    high: 50.03,\n    low: 49.931,\n    close: 49.947,\n    volume: 96228,\n  },\n  {\n    date: 1462284120000,\n    open: 49.9499,\n    high: 49.95,\n    low: 49.91,\n    close: 49.95,\n    volume: 59533,\n  },\n  {\n    date: 1462284180000,\n    open: 49.95,\n    high: 49.95,\n    low: 49.91,\n    close: 49.91,\n    volume: 58676,\n  },\n  {\n    date: 1462284240000,\n    open: 49.91,\n    high: 49.945,\n    low: 49.9,\n    close: 49.93,\n    volume: 70884,\n  },\n  {\n    date: 1462284300000,\n    open: 49.93,\n    high: 49.93,\n    low: 49.89,\n    close: 49.93,\n    volume: 69465,\n  },\n  {\n    date: 1462284360000,\n    open: 49.9265,\n    high: 49.95,\n    low: 49.91,\n    close: 49.94,\n    volume: 53616,\n  },\n  {\n    date: 1462284420000,\n    open: 49.94,\n    high: 49.9476,\n    low: 49.9,\n    close: 49.91,\n    volume: 55350,\n  },\n  {\n    date: 1462284480000,\n    open: 49.91,\n    high: 49.92,\n    low: 49.9,\n    close: 49.9089,\n    volume: 61659,\n  },\n  {\n    date: 1462284540000,\n    open: 49.905,\n    high: 49.9199,\n    low: 49.88,\n    close: 49.89,\n    volume: 78078,\n  },\n  {\n    date: 1462284600000,\n    open: 49.9,\n    high: 49.9,\n    low: 49.87,\n    close: 49.875,\n    volume: 112263,\n  },\n  {\n    date: 1462284660000,\n    open: 49.87,\n    high: 49.87,\n    low: 49.84,\n    close: 49.85,\n    volume: 100745,\n  },\n  {\n    date: 1462284720000,\n    open: 49.86,\n    high: 49.8701,\n    low: 49.835,\n    close: 49.835,\n    volume: 107790,\n  },\n  {\n    date: 1462284780000,\n    open: 49.84,\n    high: 49.845,\n    low: 49.77,\n    close: 49.78,\n    volume: 180614,\n  },\n  {\n    date: 1462284840000,\n    open: 49.7701,\n    high: 49.775,\n    low: 49.73,\n    close: 49.75,\n    volume: 104650,\n  },\n  {\n    date: 1462284900000,\n    open: 49.76,\n    high: 49.78,\n    low: 49.72,\n    close: 49.775,\n    volume: 62814,\n  },\n  {\n    date: 1462284960000,\n    open: 49.7799,\n    high: 49.84,\n    low: 49.765,\n    close: 49.8399,\n    volume: 75747,\n  },\n  {\n    date: 1462285020000,\n    open: 49.84,\n    high: 49.87,\n    low: 49.84,\n    close: 49.8599,\n    volume: 48064,\n  },\n  {\n    date: 1462285080000,\n    open: 49.855,\n    high: 49.9001,\n    low: 49.855,\n    close: 49.9,\n    volume: 53400,\n  },\n  {\n    date: 1462285140000,\n    open: 49.885,\n    high: 49.91,\n    low: 49.86,\n    close: 49.91,\n    volume: 71865,\n  },\n  {\n    date: 1462285200000,\n    open: 49.9,\n    high: 49.919,\n    low: 49.89,\n    close: 49.91,\n    volume: 61239,\n  },\n  {\n    date: 1462285260000,\n    open: 49.915,\n    high: 49.93,\n    low: 49.89,\n    close: 49.92,\n    volume: 89001,\n  },\n  {\n    date: 1462285320000,\n    open: 49.92,\n    high: 49.95,\n    low: 49.89,\n    close: 49.9,\n    volume: 52264,\n  },\n  {\n    date: 1462285380000,\n    open: 49.9,\n    high: 49.92,\n    low: 49.88,\n    close: 49.915,\n    volume: 40189,\n  },\n  {\n    date: 1462285440000,\n    open: 49.92,\n    high: 49.93,\n    low: 49.9,\n    close: 49.9099,\n    volume: 36422,\n  },\n  {\n    date: 1462285500000,\n    open: 49.9,\n    high: 49.98,\n    low: 49.89,\n    close: 49.97,\n    volume: 72764,\n  },\n  {\n    date: 1462285560000,\n    open: 49.9701,\n    high: 49.9701,\n    low: 49.93,\n    close: 49.94,\n    volume: 38641,\n  },\n  {\n    date: 1462285620000,\n    open: 49.945,\n    high: 49.95,\n    low: 49.9,\n    close: 49.91,\n    volume: 61244,\n  },\n  {\n    date: 1462285680000,\n    open: 49.92,\n    high: 49.94,\n    low: 49.89,\n    close: 49.925,\n    volume: 44391,\n  },\n  {\n    date: 1462285740000,\n    open: 49.9298,\n    high: 49.94,\n    low: 49.9,\n    close: 49.94,\n    volume: 83362,\n  },\n  {\n    date: 1462285800000,\n    open: 49.94,\n    high: 49.97,\n    low: 49.9,\n    close: 49.91,\n    volume: 149969,\n  },\n  {\n    date: 1462285860000,\n    open: 49.915,\n    high: 49.92,\n    low: 49.88,\n    close: 49.9166,\n    volume: 85478,\n  },\n  {\n    date: 1462285920000,\n    open: 49.92,\n    high: 49.92,\n    low: 49.87,\n    close: 49.9,\n    volume: 66278,\n  },\n  {\n    date: 1462285980000,\n    open: 49.9,\n    high: 49.94,\n    low: 49.89,\n    close: 49.9,\n    volume: 59043,\n  },\n  {\n    date: 1462286040000,\n    open: 49.905,\n    high: 49.95,\n    low: 49.905,\n    close: 49.95,\n    volume: 23017,\n  },\n  {\n    date: 1462286100000,\n    open: 49.95,\n    high: 49.98,\n    low: 49.95,\n    close: 49.97,\n    volume: 76925,\n  },\n  {\n    date: 1462286160000,\n    open: 49.965,\n    high: 49.98,\n    low: 49.94,\n    close: 49.945,\n    volume: 99288,\n  },\n  {\n    date: 1462286220000,\n    open: 49.94,\n    high: 49.99,\n    low: 49.935,\n    close: 49.98,\n    volume: 77677,\n  },\n  {\n    date: 1462286280000,\n    open: 49.9773,\n    high: 50.01,\n    low: 49.9773,\n    close: 49.985,\n    volume: 41177,\n  },\n  {\n    date: 1462286340000,\n    open: 49.9836,\n    high: 49.995,\n    low: 49.96,\n    close: 49.975,\n    volume: 51441,\n  },\n  {\n    date: 1462286400000,\n    open: 49.975,\n    high: 50.015,\n    low: 49.975,\n    close: 50.005,\n    volume: 100544,\n  },\n  {\n    date: 1462286460000,\n    open: 50.005,\n    high: 50.02,\n    low: 49.95,\n    close: 49.95,\n    volume: 63875,\n  },\n  {\n    date: 1462286520000,\n    open: 49.945,\n    high: 50.01,\n    low: 49.94,\n    close: 50.005,\n    volume: 53089,\n  },\n  {\n    date: 1462286580000,\n    open: 50.0099,\n    high: 50.05,\n    low: 50,\n    close: 50.045,\n    volume: 40383,\n  },\n  {\n    date: 1462286640000,\n    open: 50.0435,\n    high: 50.07,\n    low: 50.035,\n    close: 50.061,\n    volume: 55670,\n  },\n  {\n    date: 1462286700000,\n    open: 50.07,\n    high: 50.09,\n    low: 50.05,\n    close: 50.055,\n    volume: 52049,\n  },\n  {\n    date: 1462286760000,\n    open: 50.05,\n    high: 50.08,\n    low: 50.04,\n    close: 50.05,\n    volume: 93493,\n  },\n  {\n    date: 1462286820000,\n    open: 50.05,\n    high: 50.07,\n    low: 50.045,\n    close: 50.05,\n    volume: 28258,\n  },\n  {\n    date: 1462286880000,\n    open: 50.045,\n    high: 50.06,\n    low: 50.03,\n    close: 50.0434,\n    volume: 70159,\n  },\n  {\n    date: 1462286940000,\n    open: 50.04,\n    high: 50.08,\n    low: 50.04,\n    close: 50.06,\n    volume: 52791,\n  },\n  {\n    date: 1462287000000,\n    open: 50.06,\n    high: 50.065,\n    low: 50.01,\n    close: 50.025,\n    volume: 70337,\n  },\n  {\n    date: 1462287060000,\n    open: 50.02,\n    high: 50.055,\n    low: 50.02,\n    close: 50.032,\n    volume: 23476,\n  },\n  {\n    date: 1462287120000,\n    open: 50.04,\n    high: 50.05,\n    low: 50.01,\n    close: 50.037,\n    volume: 45403,\n  },\n  {\n    date: 1462287180000,\n    open: 50.0372,\n    high: 50.0372,\n    low: 49.97,\n    close: 49.97,\n    volume: 34463,\n  },\n  {\n    date: 1462287240000,\n    open: 49.976,\n    high: 49.98,\n    low: 49.94,\n    close: 49.95,\n    volume: 43513,\n  },\n  {\n    date: 1462287300000,\n    open: 49.957,\n    high: 49.9599,\n    low: 49.92,\n    close: 49.94,\n    volume: 37459,\n  },\n  {\n    date: 1462287360000,\n    open: 49.94,\n    high: 49.97,\n    low: 49.91,\n    close: 49.935,\n    volume: 109777,\n  },\n  {\n    date: 1462287420000,\n    open: 49.94,\n    high: 49.945,\n    low: 49.9,\n    close: 49.91,\n    volume: 44564,\n  },\n  {\n    date: 1462287480000,\n    open: 49.9,\n    high: 49.9,\n    low: 49.87,\n    close: 49.885,\n    volume: 58506,\n  },\n  {\n    date: 1462287540000,\n    open: 49.88,\n    high: 49.89,\n    low: 49.85,\n    close: 49.8799,\n    volume: 50068,\n  },\n  {\n    date: 1462287600000,\n    open: 49.875,\n    high: 49.94,\n    low: 49.86,\n    close: 49.93,\n    volume: 55359,\n  },\n  {\n    date: 1462287660000,\n    open: 49.93,\n    high: 49.935,\n    low: 49.89,\n    close: 49.9158,\n    volume: 43492,\n  },\n  {\n    date: 1462287720000,\n    open: 49.91,\n    high: 49.91,\n    low: 49.8333,\n    close: 49.87,\n    volume: 51928,\n  },\n  {\n    date: 1462287780000,\n    open: 49.86,\n    high: 49.8789,\n    low: 49.84,\n    close: 49.87,\n    volume: 43204,\n  },\n  {\n    date: 1462287840000,\n    open: 49.87,\n    high: 49.96,\n    low: 49.8658,\n    close: 49.95,\n    volume: 75549,\n  },\n  {\n    date: 1462287900000,\n    open: 49.955,\n    high: 49.97,\n    low: 49.95,\n    close: 49.965,\n    volume: 26805,\n  },\n  {\n    date: 1462287960000,\n    open: 49.97,\n    high: 49.99,\n    low: 49.9431,\n    close: 49.989,\n    volume: 68690,\n  },\n  {\n    date: 1462288020000,\n    open: 49.98,\n    high: 50,\n    low: 49.97,\n    close: 49.99,\n    volume: 40927,\n  },\n  {\n    date: 1462288080000,\n    open: 49.99,\n    high: 50.025,\n    low: 49.99,\n    close: 50.02,\n    volume: 34319,\n  },\n  {\n    date: 1462288140000,\n    open: 50.02,\n    high: 50.025,\n    low: 49.97,\n    close: 49.9832,\n    volume: 31452,\n  },\n  {\n    date: 1462288200000,\n    open: 49.99,\n    high: 49.99,\n    low: 49.969,\n    close: 49.97,\n    volume: 42674,\n  },\n  {\n    date: 1462288260000,\n    open: 49.97,\n    high: 49.975,\n    low: 49.915,\n    close: 49.92,\n    volume: 34514,\n  },\n  {\n    date: 1462288320000,\n    open: 49.93,\n    high: 49.93,\n    low: 49.9,\n    close: 49.915,\n    volume: 37255,\n  },\n  {\n    date: 1462288380000,\n    open: 49.92,\n    high: 49.94,\n    low: 49.91,\n    close: 49.937,\n    volume: 64019,\n  },\n  {\n    date: 1462288440000,\n    open: 49.9369,\n    high: 49.95,\n    low: 49.92,\n    close: 49.945,\n    volume: 44020,\n  },\n  {\n    date: 1462288500000,\n    open: 49.9431,\n    high: 49.96,\n    low: 49.9334,\n    close: 49.94,\n    volume: 41702,\n  },\n  {\n    date: 1462288560000,\n    open: 49.94,\n    high: 49.95,\n    low: 49.92,\n    close: 49.94,\n    volume: 65770,\n  },\n  {\n    date: 1462288620000,\n    open: 49.95,\n    high: 49.95,\n    low: 49.89,\n    close: 49.89,\n    volume: 46841,\n  },\n  {\n    date: 1462288680000,\n    open: 49.896,\n    high: 49.9166,\n    low: 49.875,\n    close: 49.88,\n    volume: 51638,\n  },\n  {\n    date: 1462288740000,\n    open: 49.875,\n    high: 49.94,\n    low: 49.87,\n    close: 49.9,\n    volume: 128127,\n  },\n  {\n    date: 1462288800000,\n    open: 49.905,\n    high: 49.905,\n    low: 49.87,\n    close: 49.875,\n    volume: 40708,\n  },\n  {\n    date: 1462288860000,\n    open: 49.87,\n    high: 49.88,\n    low: 49.86,\n    close: 49.865,\n    volume: 55574,\n  },\n  {\n    date: 1462288920000,\n    open: 49.867,\n    high: 49.88,\n    low: 49.85,\n    close: 49.85,\n    volume: 29316,\n  },\n  {\n    date: 1462288980000,\n    open: 49.855,\n    high: 49.86,\n    low: 49.84,\n    close: 49.85,\n    volume: 37856,\n  },\n  {\n    date: 1462289040000,\n    open: 49.84,\n    high: 49.86,\n    low: 49.84,\n    close: 49.86,\n    volume: 31933,\n  },\n  {\n    date: 1462289100000,\n    open: 49.86,\n    high: 49.86,\n    low: 49.8,\n    close: 49.825,\n    volume: 68046,\n  },\n  {\n    date: 1462289160000,\n    open: 49.8273,\n    high: 49.83,\n    low: 49.8,\n    close: 49.815,\n    volume: 41064,\n  },\n  {\n    date: 1462289220000,\n    open: 49.82,\n    high: 49.855,\n    low: 49.815,\n    close: 49.85,\n    volume: 39874,\n  },\n  {\n    date: 1462289280000,\n    open: 49.85,\n    high: 49.88,\n    low: 49.8429,\n    close: 49.88,\n    volume: 34030,\n  },\n  {\n    date: 1462289340000,\n    open: 49.8799,\n    high: 49.88,\n    low: 49.85,\n    close: 49.855,\n    volume: 74839,\n  },\n  {\n    date: 1462289400000,\n    open: 49.8665,\n    high: 49.87,\n    low: 49.825,\n    close: 49.825,\n    volume: 64261,\n  },\n  {\n    date: 1462289460000,\n    open: 49.83,\n    high: 49.83,\n    low: 49.74,\n    close: 49.7743,\n    volume: 152128,\n  },\n  {\n    date: 1462289520000,\n    open: 49.77,\n    high: 49.77,\n    low: 49.71,\n    close: 49.7512,\n    volume: 80282,\n  },\n  {\n    date: 1462289580000,\n    open: 49.7566,\n    high: 49.79,\n    low: 49.75,\n    close: 49.79,\n    volume: 53422,\n  },\n  {\n    date: 1462289640000,\n    open: 49.79,\n    high: 49.79,\n    low: 49.77,\n    close: 49.78,\n    volume: 14025,\n  },\n  {\n    date: 1462289700000,\n    open: 49.78,\n    high: 49.7835,\n    low: 49.76,\n    close: 49.7798,\n    volume: 23895,\n  },\n  {\n    date: 1462289760000,\n    open: 49.78,\n    high: 49.82,\n    low: 49.78,\n    close: 49.795,\n    volume: 35300,\n  },\n  {\n    date: 1462289820000,\n    open: 49.79,\n    high: 49.8,\n    low: 49.78,\n    close: 49.8,\n    volume: 17685,\n  },\n  {\n    date: 1462289880000,\n    open: 49.81,\n    high: 49.82,\n    low: 49.8,\n    close: 49.8,\n    volume: 23192,\n  },\n  {\n    date: 1462289940000,\n    open: 49.8,\n    high: 49.81,\n    low: 49.775,\n    close: 49.79,\n    volume: 38021,\n  },\n  {\n    date: 1462290000000,\n    open: 49.79,\n    high: 49.79,\n    low: 49.78,\n    close: 49.7864,\n    volume: 22970,\n  },\n  {\n    date: 1462290060000,\n    open: 49.78,\n    high: 49.786,\n    low: 49.765,\n    close: 49.7799,\n    volume: 34380,\n  },\n  {\n    date: 1462290120000,\n    open: 49.7735,\n    high: 49.78,\n    low: 49.76,\n    close: 49.77,\n    volume: 19486,\n  },\n  {\n    date: 1462290180000,\n    open: 49.7771,\n    high: 49.81,\n    low: 49.775,\n    close: 49.81,\n    volume: 29303,\n  },\n  {\n    date: 1462290240000,\n    open: 49.805,\n    high: 49.815,\n    low: 49.79,\n    close: 49.8005,\n    volume: 27015,\n  },\n  {\n    date: 1462290300000,\n    open: 49.81,\n    high: 49.84,\n    low: 49.805,\n    close: 49.83,\n    volume: 34673,\n  },\n  {\n    date: 1462290360000,\n    open: 49.84,\n    high: 49.85,\n    low: 49.82,\n    close: 49.84,\n    volume: 85920,\n  },\n  {\n    date: 1462290420000,\n    open: 49.841,\n    high: 49.86,\n    low: 49.84,\n    close: 49.855,\n    volume: 41682,\n  },\n  {\n    date: 1462290480000,\n    open: 49.855,\n    high: 49.88,\n    low: 49.85,\n    close: 49.87,\n    volume: 24011,\n  },\n  {\n    date: 1462290540000,\n    open: 49.875,\n    high: 49.91,\n    low: 49.8738,\n    close: 49.907,\n    volume: 48282,\n  },\n  {\n    date: 1462290600000,\n    open: 49.91,\n    high: 49.91,\n    low: 49.87,\n    close: 49.875,\n    volume: 57441,\n  },\n  {\n    date: 1462290660000,\n    open: 49.88,\n    high: 49.89,\n    low: 49.84,\n    close: 49.84,\n    volume: 61918,\n  },\n  {\n    date: 1462290720000,\n    open: 49.853,\n    high: 49.859,\n    low: 49.81,\n    close: 49.81,\n    volume: 42496,\n  },\n  {\n    date: 1462290780000,\n    open: 49.805,\n    high: 49.82,\n    low: 49.79,\n    close: 49.8099,\n    volume: 43496,\n  },\n  {\n    date: 1462290840000,\n    open: 49.8085,\n    high: 49.82,\n    low: 49.79,\n    close: 49.8,\n    volume: 30971,\n  },\n  {\n    date: 1462290900000,\n    open: 49.807,\n    high: 49.85,\n    low: 49.8,\n    close: 49.84,\n    volume: 33615,\n  },\n  {\n    date: 1462290960000,\n    open: 49.84,\n    high: 49.84,\n    low: 49.8,\n    close: 49.805,\n    volume: 34495,\n  },\n  {\n    date: 1462291020000,\n    open: 49.805,\n    high: 49.805,\n    low: 49.77,\n    close: 49.785,\n    volume: 38033,\n  },\n  {\n    date: 1462291080000,\n    open: 49.79,\n    high: 49.795,\n    low: 49.76,\n    close: 49.7699,\n    volume: 47883,\n  },\n  {\n    date: 1462291140000,\n    open: 49.7601,\n    high: 49.8,\n    low: 49.7601,\n    close: 49.8,\n    volume: 41063,\n  },\n  {\n    date: 1462291200000,\n    open: 49.8,\n    high: 49.8199,\n    low: 49.76,\n    close: 49.76,\n    volume: 56277,\n  },\n  {\n    date: 1462291260000,\n    open: 49.77,\n    high: 49.79,\n    low: 49.77,\n    close: 49.78,\n    volume: 18903,\n  },\n  {\n    date: 1462291320000,\n    open: 49.78,\n    high: 49.81,\n    low: 49.77,\n    close: 49.785,\n    volume: 45529,\n  },\n  {\n    date: 1462291380000,\n    open: 49.785,\n    high: 49.785,\n    low: 49.74,\n    close: 49.76,\n    volume: 72463,\n  },\n  {\n    date: 1462291440000,\n    open: 49.75,\n    high: 49.7599,\n    low: 49.72,\n    close: 49.72,\n    volume: 18067,\n  },\n  {\n    date: 1462291500000,\n    open: 49.72,\n    high: 49.725,\n    low: 49.7,\n    close: 49.71,\n    volume: 61256,\n  },\n  {\n    date: 1462291560000,\n    open: 49.7,\n    high: 49.71,\n    low: 49.69,\n    close: 49.71,\n    volume: 63727,\n  },\n  {\n    date: 1462291620000,\n    open: 49.7,\n    high: 49.705,\n    low: 49.68,\n    close: 49.69,\n    volume: 55343,\n  },\n  {\n    date: 1462291680000,\n    open: 49.6964,\n    high: 49.6999,\n    low: 49.6599,\n    close: 49.68,\n    volume: 46612,\n  },\n  {\n    date: 1462291740000,\n    open: 49.6765,\n    high: 49.71,\n    low: 49.67,\n    close: 49.69,\n    volume: 75439,\n  },\n  {\n    date: 1462291800000,\n    open: 49.7,\n    high: 49.72,\n    low: 49.685,\n    close: 49.71,\n    volume: 25062,\n  },\n  {\n    date: 1462291860000,\n    open: 49.7059,\n    high: 49.71,\n    low: 49.66,\n    close: 49.6899,\n    volume: 59439,\n  },\n  {\n    date: 1462291920000,\n    open: 49.6854,\n    high: 49.73,\n    low: 49.6854,\n    close: 49.7199,\n    volume: 44614,\n  },\n  {\n    date: 1462291980000,\n    open: 49.71,\n    high: 49.72,\n    low: 49.7,\n    close: 49.7,\n    volume: 29683,\n  },\n  {\n    date: 1462292040000,\n    open: 49.7,\n    high: 49.705,\n    low: 49.66,\n    close: 49.66,\n    volume: 75833,\n  },\n  {\n    date: 1462292100000,\n    open: 49.67,\n    high: 49.69,\n    low: 49.64,\n    close: 49.6599,\n    volume: 85386,\n  },\n  {\n    date: 1462292160000,\n    open: 49.65,\n    high: 49.6777,\n    low: 49.65,\n    close: 49.6665,\n    volume: 21273,\n  },\n  {\n    date: 1462292220000,\n    open: 49.66,\n    high: 49.69,\n    low: 49.66,\n    close: 49.69,\n    volume: 26666,\n  },\n  {\n    date: 1462292280000,\n    open: 49.68,\n    high: 49.715,\n    low: 49.68,\n    close: 49.705,\n    volume: 64542,\n  },\n  {\n    date: 1462292340000,\n    open: 49.71,\n    high: 49.71,\n    low: 49.67,\n    close: 49.68,\n    volume: 40799,\n  },\n  {\n    date: 1462292400000,\n    open: 49.68,\n    high: 49.7,\n    low: 49.67,\n    close: 49.6959,\n    volume: 21240,\n  },\n  {\n    date: 1462292460000,\n    open: 49.695,\n    high: 49.74,\n    low: 49.69,\n    close: 49.74,\n    volume: 27503,\n  },\n  {\n    date: 1462292520000,\n    open: 49.73,\n    high: 49.74,\n    low: 49.68,\n    close: 49.69,\n    volume: 53168,\n  },\n  {\n    date: 1462292580000,\n    open: 49.71,\n    high: 49.75,\n    low: 49.71,\n    close: 49.75,\n    volume: 13807,\n  },\n  {\n    date: 1462292640000,\n    open: 49.745,\n    high: 49.775,\n    low: 49.745,\n    close: 49.76,\n    volume: 26413,\n  },\n  {\n    date: 1462292700000,\n    open: 49.76,\n    high: 49.769,\n    low: 49.74,\n    close: 49.74,\n    volume: 43267,\n  },\n  {\n    date: 1462292760000,\n    open: 49.7462,\n    high: 49.78,\n    low: 49.7462,\n    close: 49.775,\n    volume: 43127,\n  },\n  {\n    date: 1462292820000,\n    open: 49.775,\n    high: 49.7899,\n    low: 49.76,\n    close: 49.78,\n    volume: 59622,\n  },\n  {\n    date: 1462292880000,\n    open: 49.78,\n    high: 49.82,\n    low: 49.77,\n    close: 49.8092,\n    volume: 56499,\n  },\n  {\n    date: 1462292940000,\n    open: 49.8,\n    high: 49.82,\n    low: 49.79,\n    close: 49.8,\n    volume: 41640,\n  },\n  {\n    date: 1462293000000,\n    open: 49.805,\n    high: 49.81,\n    low: 49.8,\n    close: 49.81,\n    volume: 57895,\n  },\n  {\n    date: 1462293060000,\n    open: 49.81,\n    high: 49.84,\n    low: 49.81,\n    close: 49.84,\n    volume: 77913,\n  },\n  {\n    date: 1462293120000,\n    open: 49.84,\n    high: 49.86,\n    low: 49.83,\n    close: 49.8573,\n    volume: 32019,\n  },\n  {\n    date: 1462293180000,\n    open: 49.855,\n    high: 49.86,\n    low: 49.83,\n    close: 49.835,\n    volume: 33465,\n  },\n  {\n    date: 1462293240000,\n    open: 49.83,\n    high: 49.84,\n    low: 49.82,\n    close: 49.84,\n    volume: 27745,\n  },\n  {\n    date: 1462293300000,\n    open: 49.83,\n    high: 49.85,\n    low: 49.83,\n    close: 49.84,\n    volume: 12028,\n  },\n  {\n    date: 1462293360000,\n    open: 49.85,\n    high: 49.86,\n    low: 49.81,\n    close: 49.83,\n    volume: 51900,\n  },\n  {\n    date: 1462293420000,\n    open: 49.82,\n    high: 49.85,\n    low: 49.82,\n    close: 49.85,\n    volume: 28390,\n  },\n  {\n    date: 1462293480000,\n    open: 49.85,\n    high: 49.87,\n    low: 49.84,\n    close: 49.86,\n    volume: 38423,\n  },\n  {\n    date: 1462293540000,\n    open: 49.86,\n    high: 49.87,\n    low: 49.84,\n    close: 49.86,\n    volume: 22093,\n  },\n  {\n    date: 1462293600000,\n    open: 49.86,\n    high: 49.87,\n    low: 49.85,\n    close: 49.859,\n    volume: 12917,\n  },\n  {\n    date: 1462293660000,\n    open: 49.85,\n    high: 49.89,\n    low: 49.85,\n    close: 49.887,\n    volume: 39148,\n  },\n  {\n    date: 1462293720000,\n    open: 49.8864,\n    high: 49.93,\n    low: 49.8864,\n    close: 49.92,\n    volume: 53503,\n  },\n  {\n    date: 1462293780000,\n    open: 49.9236,\n    high: 49.93,\n    low: 49.92,\n    close: 49.925,\n    volume: 19617,\n  },\n  {\n    date: 1462293840000,\n    open: 49.93,\n    high: 49.94,\n    low: 49.91,\n    close: 49.91,\n    volume: 42580,\n  },\n  {\n    date: 1462293900000,\n    open: 49.91,\n    high: 49.92,\n    low: 49.89,\n    close: 49.9,\n    volume: 18188,\n  },\n  {\n    date: 1462293960000,\n    open: 49.89,\n    high: 49.9,\n    low: 49.87,\n    close: 49.88,\n    volume: 160174,\n  },\n  {\n    date: 1462294020000,\n    open: 49.885,\n    high: 49.93,\n    low: 49.88,\n    close: 49.926,\n    volume: 19565,\n  },\n  {\n    date: 1462294080000,\n    open: 49.9241,\n    high: 49.935,\n    low: 49.88,\n    close: 49.89,\n    volume: 41023,\n  },\n  {\n    date: 1462294140000,\n    open: 49.885,\n    high: 49.89,\n    low: 49.87,\n    close: 49.8899,\n    volume: 29108,\n  },\n  {\n    date: 1462294200000,\n    open: 49.885,\n    high: 49.91,\n    low: 49.8826,\n    close: 49.9099,\n    volume: 14990,\n  },\n  {\n    date: 1462294260000,\n    open: 49.9099,\n    high: 49.94,\n    low: 49.9,\n    close: 49.936,\n    volume: 19732,\n  },\n  {\n    date: 1462294320000,\n    open: 49.93,\n    high: 49.96,\n    low: 49.93,\n    close: 49.959,\n    volume: 53944,\n  },\n  {\n    date: 1462294380000,\n    open: 49.95,\n    high: 49.96,\n    low: 49.9,\n    close: 49.9092,\n    volume: 45988,\n  },\n  {\n    date: 1462294440000,\n    open: 49.915,\n    high: 49.94,\n    low: 49.91,\n    close: 49.94,\n    volume: 11120,\n  },\n  {\n    date: 1462294500000,\n    open: 49.94,\n    high: 49.94,\n    low: 49.9,\n    close: 49.9,\n    volume: 46393,\n  },\n  {\n    date: 1462294560000,\n    open: 49.905,\n    high: 49.93,\n    low: 49.9027,\n    close: 49.9262,\n    volume: 11733,\n  },\n  {\n    date: 1462294620000,\n    open: 49.93,\n    high: 49.95,\n    low: 49.92,\n    close: 49.94,\n    volume: 21991,\n  },\n  {\n    date: 1462294680000,\n    open: 49.94,\n    high: 49.94,\n    low: 49.92,\n    close: 49.92,\n    volume: 24449,\n  },\n  {\n    date: 1462294740000,\n    open: 49.93,\n    high: 49.94,\n    low: 49.91,\n    close: 49.92,\n    volume: 47919,\n  },\n  {\n    date: 1462294800000,\n    open: 49.92,\n    high: 49.935,\n    low: 49.91,\n    close: 49.91,\n    volume: 44687,\n  },\n  {\n    date: 1462294860000,\n    open: 49.91,\n    high: 49.92,\n    low: 49.895,\n    close: 49.9,\n    volume: 74581,\n  },\n  {\n    date: 1462294920000,\n    open: 49.9,\n    high: 49.91,\n    low: 49.87,\n    close: 49.87,\n    volume: 30674,\n  },\n  {\n    date: 1462294980000,\n    open: 49.87,\n    high: 49.88,\n    low: 49.87,\n    close: 49.875,\n    volume: 35494,\n  },\n  {\n    date: 1462295040000,\n    open: 49.875,\n    high: 49.877,\n    low: 49.87,\n    close: 49.8767,\n    volume: 22472,\n  },\n  {\n    date: 1462295100000,\n    open: 49.88,\n    high: 49.88,\n    low: 49.85,\n    close: 49.85,\n    volume: 66105,\n  },\n  {\n    date: 1462295160000,\n    open: 49.8532,\n    high: 49.86,\n    low: 49.84,\n    close: 49.85,\n    volume: 24163,\n  },\n  {\n    date: 1462295220000,\n    open: 49.84,\n    high: 49.85,\n    low: 49.83,\n    close: 49.835,\n    volume: 43438,\n  },\n  {\n    date: 1462295280000,\n    open: 49.835,\n    high: 49.88,\n    low: 49.83,\n    close: 49.88,\n    volume: 81043,\n  },\n  {\n    date: 1462295340000,\n    open: 49.875,\n    high: 49.93,\n    low: 49.87,\n    close: 49.9299,\n    volume: 23234,\n  },\n  {\n    date: 1462295400000,\n    open: 49.9276,\n    high: 49.96,\n    low: 49.9276,\n    close: 49.955,\n    volume: 19039,\n  },\n  {\n    date: 1462295460000,\n    open: 49.96,\n    high: 49.98,\n    low: 49.94,\n    close: 49.94,\n    volume: 54100,\n  },\n  {\n    date: 1462295520000,\n    open: 49.94,\n    high: 49.945,\n    low: 49.92,\n    close: 49.9259,\n    volume: 51781,\n  },\n  {\n    date: 1462295580000,\n    open: 49.92,\n    high: 49.94,\n    low: 49.92,\n    close: 49.93,\n    volume: 25940,\n  },\n  {\n    date: 1462295640000,\n    open: 49.93,\n    high: 49.93,\n    low: 49.9,\n    close: 49.9,\n    volume: 26407,\n  },\n  {\n    date: 1462295700000,\n    open: 49.905,\n    high: 49.92,\n    low: 49.89,\n    close: 49.895,\n    volume: 38726,\n  },\n  {\n    date: 1462295760000,\n    open: 49.895,\n    high: 49.94,\n    low: 49.895,\n    close: 49.9399,\n    volume: 19677,\n  },\n  {\n    date: 1462295820000,\n    open: 49.94,\n    high: 49.97,\n    low: 49.93,\n    close: 49.96,\n    volume: 22787,\n  },\n  {\n    date: 1462295880000,\n    open: 49.95,\n    high: 49.96,\n    low: 49.92,\n    close: 49.9252,\n    volume: 24773,\n  },\n  {\n    date: 1462295940000,\n    open: 49.93,\n    high: 49.95,\n    low: 49.93,\n    close: 49.95,\n    volume: 13271,\n  },\n  {\n    date: 1462296000000,\n    open: 49.9468,\n    high: 49.97,\n    low: 49.945,\n    close: 49.9601,\n    volume: 33532,\n  },\n  {\n    date: 1462296060000,\n    open: 49.9695,\n    high: 49.97,\n    low: 49.93,\n    close: 49.945,\n    volume: 25070,\n  },\n  {\n    date: 1462296120000,\n    open: 49.945,\n    high: 49.97,\n    low: 49.94,\n    close: 49.965,\n    volume: 24071,\n  },\n  {\n    date: 1462296180000,\n    open: 49.965,\n    high: 50,\n    low: 49.965,\n    close: 49.98,\n    volume: 46170,\n  },\n  {\n    date: 1462296240000,\n    open: 49.975,\n    high: 49.98,\n    low: 49.94,\n    close: 49.94,\n    volume: 16777,\n  },\n  {\n    date: 1462296300000,\n    open: 49.945,\n    high: 49.975,\n    low: 49.92,\n    close: 49.9699,\n    volume: 58064,\n  },\n  {\n    date: 1462296360000,\n    open: 49.9659,\n    high: 49.98,\n    low: 49.95,\n    close: 49.98,\n    volume: 31590,\n  },\n  {\n    date: 1462296420000,\n    open: 49.985,\n    high: 50.03,\n    low: 49.985,\n    close: 49.99,\n    volume: 57074,\n  },\n  {\n    date: 1462296480000,\n    open: 49.9999,\n    high: 50.01,\n    low: 49.99,\n    close: 50,\n    volume: 26668,\n  },\n  {\n    date: 1462296540000,\n    open: 50.0024,\n    high: 50.01,\n    low: 49.985,\n    close: 49.985,\n    volume: 30432,\n  },\n  {\n    date: 1462296600000,\n    open: 49.9801,\n    high: 50.015,\n    low: 49.98,\n    close: 50.015,\n    volume: 66359,\n  },\n  {\n    date: 1462296660000,\n    open: 50.015,\n    high: 50.03,\n    low: 50.015,\n    close: 50.025,\n    volume: 29697,\n  },\n  {\n    date: 1462296720000,\n    open: 50.02,\n    high: 50.02,\n    low: 49.98,\n    close: 50,\n    volume: 37207,\n  },\n  {\n    date: 1462296780000,\n    open: 49.99,\n    high: 50.01,\n    low: 49.9801,\n    close: 49.99,\n    volume: 66624,\n  },\n  {\n    date: 1462296840000,\n    open: 49.98,\n    high: 49.9876,\n    low: 49.94,\n    close: 49.9564,\n    volume: 36364,\n  },\n  {\n    date: 1462296900000,\n    open: 49.96,\n    high: 50,\n    low: 49.96,\n    close: 50,\n    volume: 19614,\n  },\n  {\n    date: 1462296960000,\n    open: 49.997,\n    high: 50,\n    low: 49.97,\n    close: 49.976,\n    volume: 25224,\n  },\n  {\n    date: 1462297020000,\n    open: 49.97,\n    high: 49.975,\n    low: 49.94,\n    close: 49.95,\n    volume: 42172,\n  },\n  {\n    date: 1462297080000,\n    open: 49.94,\n    high: 49.96,\n    low: 49.94,\n    close: 49.94,\n    volume: 16309,\n  },\n  {\n    date: 1462297140000,\n    open: 49.94,\n    high: 50,\n    low: 49.93,\n    close: 49.9862,\n    volume: 104018,\n  },\n  {\n    date: 1462297200000,\n    open: 49.99,\n    high: 50.01,\n    low: 49.975,\n    close: 50,\n    volume: 45759,\n  },\n  {\n    date: 1462297260000,\n    open: 50.001,\n    high: 50.01,\n    low: 49.99,\n    close: 50,\n    volume: 70534,\n  },\n  {\n    date: 1462297320000,\n    open: 50,\n    high: 50.005,\n    low: 49.985,\n    close: 49.99,\n    volume: 38923,\n  },\n  {\n    date: 1462297380000,\n    open: 49.9992,\n    high: 50.005,\n    low: 49.99,\n    close: 49.99,\n    volume: 38990,\n  },\n  {\n    date: 1462297440000,\n    open: 49.995,\n    high: 50,\n    low: 49.98,\n    close: 49.985,\n    volume: 31969,\n  },\n  {\n    date: 1462297500000,\n    open: 49.98,\n    high: 49.985,\n    low: 49.93,\n    close: 49.94,\n    volume: 64368,\n  },\n  {\n    date: 1462297560000,\n    open: 49.945,\n    high: 49.99,\n    low: 49.945,\n    close: 49.985,\n    volume: 22600,\n  },\n  {\n    date: 1462297620000,\n    open: 49.99,\n    high: 50,\n    low: 49.98,\n    close: 49.995,\n    volume: 21101,\n  },\n  {\n    date: 1462297680000,\n    open: 50,\n    high: 50.0098,\n    low: 49.991,\n    close: 50,\n    volume: 29891,\n  },\n  {\n    date: 1462297740000,\n    open: 50,\n    high: 50,\n    low: 49.98,\n    close: 49.99,\n    volume: 26326,\n  },\n  {\n    date: 1462297800000,\n    open: 49.99,\n    high: 50.01,\n    low: 49.98,\n    close: 50,\n    volume: 72156,\n  },\n  {\n    date: 1462297860000,\n    open: 50,\n    high: 50.005,\n    low: 49.99,\n    close: 49.995,\n    volume: 24330,\n  },\n  {\n    date: 1462297920000,\n    open: 49.995,\n    high: 50.01,\n    low: 49.995,\n    close: 50.01,\n    volume: 39104,\n  },\n  {\n    date: 1462297980000,\n    open: 50.01,\n    high: 50.05,\n    low: 49.99,\n    close: 50.025,\n    volume: 85578,\n  },\n  {\n    date: 1462298040000,\n    open: 50.03,\n    high: 50.0373,\n    low: 50.01,\n    close: 50.015,\n    volume: 52867,\n  },\n  {\n    date: 1462298100000,\n    open: 50.01,\n    high: 50.0198,\n    low: 49.99,\n    close: 50,\n    volume: 73653,\n  },\n  {\n    date: 1462298160000,\n    open: 50.005,\n    high: 50.01,\n    low: 49.995,\n    close: 50,\n    volume: 165507,\n  },\n  {\n    date: 1462298220000,\n    open: 50.0032,\n    high: 50.015,\n    low: 49.995,\n    close: 50,\n    volume: 32074,\n  },\n  {\n    date: 1462298280000,\n    open: 49.99,\n    high: 50,\n    low: 49.98,\n    close: 49.98,\n    volume: 29795,\n  },\n  {\n    date: 1462298340000,\n    open: 49.98,\n    high: 49.985,\n    low: 49.97,\n    close: 49.9727,\n    volume: 27362,\n  },\n  {\n    date: 1462298400000,\n    open: 49.975,\n    high: 49.978,\n    low: 49.95,\n    close: 49.96,\n    volume: 38146,\n  },\n  {\n    date: 1462298460000,\n    open: 49.96,\n    high: 49.9871,\n    low: 49.95,\n    close: 49.9871,\n    volume: 37091,\n  },\n  {\n    date: 1462298520000,\n    open: 49.98,\n    high: 50,\n    low: 49.98,\n    close: 49.98,\n    volume: 32224,\n  },\n  {\n    date: 1462298580000,\n    open: 49.98,\n    high: 49.98,\n    low: 49.94,\n    close: 49.955,\n    volume: 39649,\n  },\n  {\n    date: 1462298640000,\n    open: 49.96,\n    high: 49.97,\n    low: 49.95,\n    close: 49.96,\n    volume: 23857,\n  },\n  {\n    date: 1462298700000,\n    open: 49.95,\n    high: 49.99,\n    low: 49.95,\n    close: 49.988,\n    volume: 57183,\n  },\n  {\n    date: 1462298760000,\n    open: 49.98,\n    high: 49.99,\n    low: 49.97,\n    close: 49.98,\n    volume: 121942,\n  },\n  {\n    date: 1462298820000,\n    open: 49.97,\n    high: 49.98,\n    low: 49.95,\n    close: 49.955,\n    volume: 70313,\n  },\n  {\n    date: 1462298880000,\n    open: 49.955,\n    high: 49.97,\n    low: 49.95,\n    close: 49.9699,\n    volume: 13668,\n  },\n  {\n    date: 1462298940000,\n    open: 49.9699,\n    high: 49.97,\n    low: 49.95,\n    close: 49.955,\n    volume: 28542,\n  },\n  {\n    date: 1462299000000,\n    open: 49.96,\n    high: 49.99,\n    low: 49.955,\n    close: 49.98,\n    volume: 45275,\n  },\n  {\n    date: 1462299060000,\n    open: 49.97,\n    high: 50.005,\n    low: 49.97,\n    close: 50.005,\n    volume: 76889,\n  },\n  {\n    date: 1462299120000,\n    open: 50.0036,\n    high: 50.005,\n    low: 49.98,\n    close: 49.98,\n    volume: 38210,\n  },\n  {\n    date: 1462299180000,\n    open: 49.98,\n    high: 49.98,\n    low: 49.88,\n    close: 49.88,\n    volume: 114169,\n  },\n  {\n    date: 1462299240000,\n    open: 49.87,\n    high: 49.8798,\n    low: 49.84,\n    close: 49.855,\n    volume: 59217,\n  },\n  {\n    date: 1462299300000,\n    open: 49.85,\n    high: 49.8699,\n    low: 49.85,\n    close: 49.86,\n    volume: 19962,\n  },\n  {\n    date: 1462299360000,\n    open: 49.869,\n    high: 49.9,\n    low: 49.8601,\n    close: 49.89,\n    volume: 14436,\n  },\n  {\n    date: 1462299420000,\n    open: 49.89,\n    high: 49.9,\n    low: 49.86,\n    close: 49.87,\n    volume: 39463,\n  },\n  {\n    date: 1462299480000,\n    open: 49.87,\n    high: 49.88,\n    low: 49.8,\n    close: 49.81,\n    volume: 77503,\n  },\n  {\n    date: 1462299540000,\n    open: 49.8,\n    high: 49.83,\n    low: 49.8,\n    close: 49.81,\n    volume: 41273,\n  },\n  {\n    date: 1462299600000,\n    open: 49.8,\n    high: 49.8064,\n    low: 49.76,\n    close: 49.77,\n    volume: 75871,\n  },\n  {\n    date: 1462299660000,\n    open: 49.7798,\n    high: 49.78,\n    low: 49.77,\n    close: 49.7764,\n    volume: 22030,\n  },\n  {\n    date: 1462299720000,\n    open: 49.771,\n    high: 49.81,\n    low: 49.75,\n    close: 49.8,\n    volume: 48068,\n  },\n  {\n    date: 1462299780000,\n    open: 49.8077,\n    high: 49.81,\n    low: 49.79,\n    close: 49.8,\n    volume: 24200,\n  },\n  {\n    date: 1462299840000,\n    open: 49.8,\n    high: 49.8136,\n    low: 49.78,\n    close: 49.79,\n    volume: 41266,\n  },\n  {\n    date: 1462299900000,\n    open: 49.8,\n    high: 49.86,\n    low: 49.8,\n    close: 49.84,\n    volume: 35107,\n  },\n  {\n    date: 1462299960000,\n    open: 49.835,\n    high: 49.845,\n    low: 49.82,\n    close: 49.845,\n    volume: 32927,\n  },\n  {\n    date: 1462300020000,\n    open: 49.845,\n    high: 49.85,\n    low: 49.82,\n    close: 49.83,\n    volume: 18915,\n  },\n  {\n    date: 1462300080000,\n    open: 49.825,\n    high: 49.84,\n    low: 49.805,\n    close: 49.84,\n    volume: 29993,\n  },\n  {\n    date: 1462300140000,\n    open: 49.83,\n    high: 49.9,\n    low: 49.83,\n    close: 49.8799,\n    volume: 54054,\n  },\n  {\n    date: 1462300200000,\n    open: 49.87,\n    high: 49.88,\n    low: 49.82,\n    close: 49.88,\n    volume: 47534,\n  },\n  {\n    date: 1462300260000,\n    open: 49.88,\n    high: 49.88,\n    low: 49.85,\n    close: 49.855,\n    volume: 15913,\n  },\n  {\n    date: 1462300320000,\n    open: 49.86,\n    high: 49.88,\n    low: 49.86,\n    close: 49.87,\n    volume: 19181,\n  },\n  {\n    date: 1462300380000,\n    open: 49.87,\n    high: 49.87,\n    low: 49.85,\n    close: 49.85,\n    volume: 14659,\n  },\n  {\n    date: 1462300440000,\n    open: 49.855,\n    high: 49.88,\n    low: 49.85,\n    close: 49.87,\n    volume: 34431,\n  },\n  {\n    date: 1462300500000,\n    open: 49.87,\n    high: 49.87,\n    low: 49.815,\n    close: 49.82,\n    volume: 81180,\n  },\n  {\n    date: 1462300560000,\n    open: 49.83,\n    high: 49.92,\n    low: 49.83,\n    close: 49.9,\n    volume: 157587,\n  },\n  {\n    date: 1462300620000,\n    open: 49.895,\n    high: 49.9199,\n    low: 49.88,\n    close: 49.895,\n    volume: 29924,\n  },\n  {\n    date: 1462300680000,\n    open: 49.89,\n    high: 49.89,\n    low: 49.88,\n    close: 49.885,\n    volume: 20014,\n  },\n  {\n    date: 1462300740000,\n    open: 49.885,\n    high: 49.8975,\n    low: 49.86,\n    close: 49.875,\n    volume: 32799,\n  },\n  {\n    date: 1462300800000,\n    open: 49.88,\n    high: 49.91,\n    low: 49.875,\n    close: 49.88,\n    volume: 21933,\n  },\n  {\n    date: 1462300860000,\n    open: 49.88,\n    high: 49.8829,\n    low: 49.8,\n    close: 49.8271,\n    volume: 62189,\n  },\n  {\n    date: 1462300920000,\n    open: 49.825,\n    high: 49.83,\n    low: 49.81,\n    close: 49.81,\n    volume: 26930,\n  },\n  {\n    date: 1462300980000,\n    open: 49.81,\n    high: 49.85,\n    low: 49.8,\n    close: 49.84,\n    volume: 31520,\n  },\n  {\n    date: 1462301040000,\n    open: 49.83,\n    high: 49.84,\n    low: 49.8,\n    close: 49.8271,\n    volume: 27790,\n  },\n  {\n    date: 1462301100000,\n    open: 49.83,\n    high: 49.85,\n    low: 49.81,\n    close: 49.85,\n    volume: 17643,\n  },\n  {\n    date: 1462301160000,\n    open: 49.84,\n    high: 49.85,\n    low: 49.811,\n    close: 49.8462,\n    volume: 43072,\n  },\n  {\n    date: 1462301220000,\n    open: 49.849,\n    high: 49.86,\n    low: 49.82,\n    close: 49.85,\n    volume: 24109,\n  },\n  {\n    date: 1462301280000,\n    open: 49.859,\n    high: 49.89,\n    low: 49.8536,\n    close: 49.8558,\n    volume: 48154,\n  },\n  {\n    date: 1462301340000,\n    open: 49.855,\n    high: 49.865,\n    low: 49.8,\n    close: 49.8099,\n    volume: 77665,\n  },\n  {\n    date: 1462301400000,\n    open: 49.8,\n    high: 49.8,\n    low: 49.73,\n    close: 49.77,\n    volume: 90029,\n  },\n  {\n    date: 1462301460000,\n    open: 49.78,\n    high: 49.79,\n    low: 49.73,\n    close: 49.73,\n    volume: 39586,\n  },\n  {\n    date: 1462301520000,\n    open: 49.73,\n    high: 49.79,\n    low: 49.73,\n    close: 49.78,\n    volume: 33808,\n  },\n  {\n    date: 1462301580000,\n    open: 49.77,\n    high: 49.7799,\n    low: 49.75,\n    close: 49.7745,\n    volume: 57691,\n  },\n  {\n    date: 1462301640000,\n    open: 49.77,\n    high: 49.775,\n    low: 49.755,\n    close: 49.755,\n    volume: 45988,\n  },\n  {\n    date: 1462301700000,\n    open: 49.75,\n    high: 49.8,\n    low: 49.72,\n    close: 49.7999,\n    volume: 62003,\n  },\n  {\n    date: 1462301760000,\n    open: 49.795,\n    high: 49.81,\n    low: 49.79,\n    close: 49.8,\n    volume: 30739,\n  },\n  {\n    date: 1462301820000,\n    open: 49.795,\n    high: 49.81,\n    low: 49.765,\n    close: 49.7822,\n    volume: 44895,\n  },\n  {\n    date: 1462301880000,\n    open: 49.78,\n    high: 49.8,\n    low: 49.77,\n    close: 49.77,\n    volume: 41719,\n  },\n  {\n    date: 1462301940000,\n    open: 49.77,\n    high: 49.835,\n    low: 49.765,\n    close: 49.83,\n    volume: 44715,\n  },\n  {\n    date: 1462302000000,\n    open: 49.83,\n    high: 49.84,\n    low: 49.81,\n    close: 49.82,\n    volume: 37787,\n  },\n  {\n    date: 1462302060000,\n    open: 49.8238,\n    high: 49.84,\n    low: 49.82,\n    close: 49.82,\n    volume: 28855,\n  },\n  {\n    date: 1462302120000,\n    open: 49.82,\n    high: 49.8282,\n    low: 49.785,\n    close: 49.79,\n    volume: 36733,\n  },\n  {\n    date: 1462302180000,\n    open: 49.79,\n    high: 49.85,\n    low: 49.79,\n    close: 49.82,\n    volume: 29830,\n  },\n  {\n    date: 1462302240000,\n    open: 49.82,\n    high: 49.83,\n    low: 49.8,\n    close: 49.8192,\n    volume: 36702,\n  },\n  {\n    date: 1462302300000,\n    open: 49.8159,\n    high: 49.82,\n    low: 49.8,\n    close: 49.815,\n    volume: 19259,\n  },\n  {\n    date: 1462302360000,\n    open: 49.815,\n    high: 49.86,\n    low: 49.815,\n    close: 49.8435,\n    volume: 48363,\n  },\n  {\n    date: 1462302420000,\n    open: 49.8412,\n    high: 49.85,\n    low: 49.81,\n    close: 49.82,\n    volume: 39882,\n  },\n  {\n    date: 1462302480000,\n    open: 49.83,\n    high: 49.845,\n    low: 49.83,\n    close: 49.83,\n    volume: 17381,\n  },\n  {\n    date: 1462302540000,\n    open: 49.8436,\n    high: 49.8464,\n    low: 49.83,\n    close: 49.84,\n    volume: 28866,\n  },\n  {\n    date: 1462302600000,\n    open: 49.845,\n    high: 49.855,\n    low: 49.83,\n    close: 49.85,\n    volume: 43089,\n  },\n  {\n    date: 1462302660000,\n    open: 49.8573,\n    high: 49.87,\n    low: 49.845,\n    close: 49.845,\n    volume: 50646,\n  },\n  {\n    date: 1462302720000,\n    open: 49.845,\n    high: 49.845,\n    low: 49.77,\n    close: 49.77,\n    volume: 90305,\n  },\n  {\n    date: 1462302780000,\n    open: 49.7787,\n    high: 49.78,\n    low: 49.73,\n    close: 49.74,\n    volume: 57729,\n  },\n  {\n    date: 1462302840000,\n    open: 49.75,\n    high: 49.76,\n    low: 49.73,\n    close: 49.7473,\n    volume: 27321,\n  },\n  {\n    date: 1462302900000,\n    open: 49.75,\n    high: 49.76,\n    low: 49.72,\n    close: 49.725,\n    volume: 47981,\n  },\n  {\n    date: 1462302960000,\n    open: 49.73,\n    high: 49.76,\n    low: 49.72,\n    close: 49.76,\n    volume: 36462,\n  },\n  {\n    date: 1462303020000,\n    open: 49.751,\n    high: 49.76,\n    low: 49.73,\n    close: 49.7536,\n    volume: 59134,\n  },\n  {\n    date: 1462303080000,\n    open: 49.755,\n    high: 49.77,\n    low: 49.74,\n    close: 49.7499,\n    volume: 52083,\n  },\n  {\n    date: 1462303140000,\n    open: 49.75,\n    high: 49.8,\n    low: 49.745,\n    close: 49.79,\n    volume: 48992,\n  },\n  {\n    date: 1462303200000,\n    open: 49.78,\n    high: 49.8,\n    low: 49.78,\n    close: 49.79,\n    volume: 24692,\n  },\n  {\n    date: 1462303260000,\n    open: 49.79,\n    high: 49.81,\n    low: 49.78,\n    close: 49.805,\n    volume: 25315,\n  },\n  {\n    date: 1462303320000,\n    open: 49.8021,\n    high: 49.83,\n    low: 49.8,\n    close: 49.815,\n    volume: 54007,\n  },\n  {\n    date: 1462303380000,\n    open: 49.81,\n    high: 49.815,\n    low: 49.76,\n    close: 49.7799,\n    volume: 78988,\n  },\n  {\n    date: 1462303440000,\n    open: 49.77,\n    high: 49.77,\n    low: 49.71,\n    close: 49.7165,\n    volume: 137651,\n  },\n  {\n    date: 1462303500000,\n    open: 49.71,\n    high: 49.75,\n    low: 49.71,\n    close: 49.74,\n    volume: 34810,\n  },\n  {\n    date: 1462303560000,\n    open: 49.74,\n    high: 49.76,\n    low: 49.73,\n    close: 49.76,\n    volume: 44455,\n  },\n  {\n    date: 1462303620000,\n    open: 49.76,\n    high: 49.8,\n    low: 49.76,\n    close: 49.79,\n    volume: 51179,\n  },\n  {\n    date: 1462303680000,\n    open: 49.78,\n    high: 49.795,\n    low: 49.77,\n    close: 49.775,\n    volume: 24708,\n  },\n  {\n    date: 1462303740000,\n    open: 49.775,\n    high: 49.82,\n    low: 49.76,\n    close: 49.805,\n    volume: 108617,\n  },\n  {\n    date: 1462303800000,\n    open: 49.81,\n    high: 49.8199,\n    low: 49.75,\n    close: 49.75,\n    volume: 65273,\n  },\n  {\n    date: 1462303860000,\n    open: 49.755,\n    high: 49.78,\n    low: 49.73,\n    close: 49.78,\n    volume: 55646,\n  },\n  {\n    date: 1462303920000,\n    open: 49.7799,\n    high: 49.795,\n    low: 49.74,\n    close: 49.745,\n    volume: 51398,\n  },\n  {\n    date: 1462303980000,\n    open: 49.745,\n    high: 49.75,\n    low: 49.69,\n    close: 49.69,\n    volume: 96182,\n  },\n  {\n    date: 1462304040000,\n    open: 49.68,\n    high: 49.6964,\n    low: 49.61,\n    close: 49.67,\n    volume: 136351,\n  },\n  {\n    date: 1462304100000,\n    open: 49.67,\n    high: 49.71,\n    low: 49.665,\n    close: 49.7,\n    volume: 76097,\n  },\n  {\n    date: 1462304160000,\n    open: 49.705,\n    high: 49.73,\n    low: 49.675,\n    close: 49.68,\n    volume: 68882,\n  },\n  {\n    date: 1462304220000,\n    open: 49.67,\n    high: 49.68,\n    low: 49.63,\n    close: 49.675,\n    volume: 105484,\n  },\n  {\n    date: 1462304280000,\n    open: 49.68,\n    high: 49.73,\n    low: 49.675,\n    close: 49.68,\n    volume: 99017,\n  },\n  {\n    date: 1462304340000,\n    open: 49.69,\n    high: 49.705,\n    low: 49.68,\n    close: 49.6959,\n    volume: 47308,\n  },\n  {\n    date: 1462304400000,\n    open: 49.69,\n    high: 49.7,\n    low: 49.66,\n    close: 49.68,\n    volume: 56501,\n  },\n  {\n    date: 1462304460000,\n    open: 49.68,\n    high: 49.69,\n    low: 49.65,\n    close: 49.66,\n    volume: 80404,\n  },\n  {\n    date: 1462304520000,\n    open: 49.65,\n    high: 49.6501,\n    low: 49.6,\n    close: 49.6199,\n    volume: 97964,\n  },\n  {\n    date: 1462304580000,\n    open: 49.62,\n    high: 49.64,\n    low: 49.6,\n    close: 49.615,\n    volume: 98001,\n  },\n  {\n    date: 1462304640000,\n    open: 49.614,\n    high: 49.66,\n    low: 49.6,\n    close: 49.64,\n    volume: 93245,\n  },\n  {\n    date: 1462304700000,\n    open: 49.64,\n    high: 49.66,\n    low: 49.605,\n    close: 49.66,\n    volume: 87834,\n  },\n  {\n    date: 1462304760000,\n    open: 49.66,\n    high: 49.72,\n    low: 49.65,\n    close: 49.69,\n    volume: 118407,\n  },\n  {\n    date: 1462304820000,\n    open: 49.68,\n    high: 49.7,\n    low: 49.67,\n    close: 49.675,\n    volume: 94495,\n  },\n  {\n    date: 1462304880000,\n    open: 49.67,\n    high: 49.72,\n    low: 49.67,\n    close: 49.72,\n    volume: 63806,\n  },\n  {\n    date: 1462304940000,\n    open: 49.7171,\n    high: 49.7695,\n    low: 49.71,\n    close: 49.765,\n    volume: 112030,\n  },\n  {\n    date: 1462305000000,\n    open: 49.76,\n    high: 49.79,\n    low: 49.74,\n    close: 49.785,\n    volume: 160269,\n  },\n  {\n    date: 1462305060000,\n    open: 49.78,\n    high: 49.81,\n    low: 49.745,\n    close: 49.78,\n    volume: 95163,\n  },\n  {\n    date: 1462305120000,\n    open: 49.78,\n    high: 49.8,\n    low: 49.7725,\n    close: 49.8,\n    volume: 97460,\n  },\n  {\n    date: 1462305180000,\n    open: 49.795,\n    high: 49.8,\n    low: 49.77,\n    close: 49.7801,\n    volume: 133705,\n  },\n  {\n    date: 1462305240000,\n    open: 49.79,\n    high: 49.79,\n    low: 49.729,\n    close: 49.76,\n    volume: 168220,\n  },\n  {\n    date: 1462305300000,\n    open: 49.755,\n    high: 49.8,\n    low: 49.75,\n    close: 49.8,\n    volume: 91063,\n  },\n  {\n    date: 1462305360000,\n    open: 49.8,\n    high: 49.8,\n    low: 49.74,\n    close: 49.74,\n    volume: 166095,\n  },\n  {\n    date: 1462305420000,\n    open: 49.74,\n    high: 49.75,\n    low: 49.73,\n    close: 49.745,\n    volume: 138299,\n  },\n  {\n    date: 1462305480000,\n    open: 49.745,\n    high: 49.77,\n    low: 49.725,\n    close: 49.7399,\n    volume: 211212,\n  },\n  {\n    date: 1462305540000,\n    open: 49.73,\n    high: 49.735,\n    low: 49.68,\n    close: 49.7,\n    volume: 330367,\n  },\n  {\n    date: 1462305600000,\n    open: 49.685,\n    high: 49.79,\n    low: 49.68,\n    close: 49.78,\n    volume: 2468533,\n  },\n  {\n    date: 1462368600000,\n    open: 49.84,\n    high: 49.9,\n    low: 49.82,\n    close: 49.85,\n    volume: 376187,\n  },\n  {\n    date: 1462368660000,\n    open: 49.89,\n    high: 49.89,\n    low: 49.68,\n    close: 49.8325,\n    volume: 175133,\n  },\n  {\n    date: 1462368720000,\n    open: 49.83,\n    high: 49.88,\n    low: 49.8,\n    close: 49.82,\n    volume: 106704,\n  },\n  {\n    date: 1462368780000,\n    open: 49.82,\n    high: 49.85,\n    low: 49.78,\n    close: 49.78,\n    volume: 68478,\n  },\n  {\n    date: 1462368840000,\n    open: 49.77,\n    high: 49.82,\n    low: 49.75,\n    close: 49.77,\n    volume: 66450,\n  },\n  {\n    date: 1462368900000,\n    open: 49.76,\n    high: 49.78,\n    low: 49.685,\n    close: 49.69,\n    volume: 52779,\n  },\n  {\n    date: 1462368960000,\n    open: 49.69,\n    high: 49.7,\n    low: 49.64,\n    close: 49.65,\n    volume: 56156,\n  },\n  {\n    date: 1462369020000,\n    open: 49.65,\n    high: 49.68,\n    low: 49.59,\n    close: 49.6,\n    volume: 69884,\n  },\n  {\n    date: 1462369080000,\n    open: 49.6,\n    high: 49.61,\n    low: 49.56,\n    close: 49.57,\n    volume: 48353,\n  },\n  {\n    date: 1462369140000,\n    open: 49.57,\n    high: 49.59,\n    low: 49.46,\n    close: 49.57,\n    volume: 219847,\n  },\n  {\n    date: 1462369200000,\n    open: 49.575,\n    high: 49.575,\n    low: 49.479,\n    close: 49.525,\n    volume: 116374,\n  },\n  {\n    date: 1462369260000,\n    open: 49.53,\n    high: 49.57,\n    low: 49.51,\n    close: 49.56,\n    volume: 47282,\n  },\n  {\n    date: 1462369320000,\n    open: 49.57,\n    high: 49.57,\n    low: 49.5311,\n    close: 49.55,\n    volume: 36764,\n  },\n  {\n    date: 1462369380000,\n    open: 49.54,\n    high: 49.575,\n    low: 49.4939,\n    close: 49.55,\n    volume: 62273,\n  },\n  {\n    date: 1462369440000,\n    open: 49.55,\n    high: 49.585,\n    low: 49.52,\n    close: 49.56,\n    volume: 130128,\n  },\n  {\n    date: 1462369500000,\n    open: 49.56,\n    high: 49.6,\n    low: 49.535,\n    close: 49.59,\n    volume: 91620,\n  },\n  {\n    date: 1462369560000,\n    open: 49.595,\n    high: 49.6063,\n    low: 49.53,\n    close: 49.55,\n    volume: 151075,\n  },\n  {\n    date: 1462369620000,\n    open: 49.55,\n    high: 49.56,\n    low: 49.51,\n    close: 49.529,\n    volume: 74028,\n  },\n  {\n    date: 1462369680000,\n    open: 49.5257,\n    high: 49.53,\n    low: 49.4699,\n    close: 49.5197,\n    volume: 158673,\n  },\n  {\n    date: 1462369740000,\n    open: 49.51,\n    high: 49.57,\n    low: 49.49,\n    close: 49.56,\n    volume: 49020,\n  },\n  {\n    date: 1462369800000,\n    open: 49.56,\n    high: 49.61,\n    low: 49.52,\n    close: 49.58,\n    volume: 77336,\n  },\n  {\n    date: 1462369860000,\n    open: 49.5829,\n    high: 49.67,\n    low: 49.56,\n    close: 49.67,\n    volume: 107758,\n  },\n  {\n    date: 1462369920000,\n    open: 49.67,\n    high: 49.67,\n    low: 49.58,\n    close: 49.6,\n    volume: 68481,\n  },\n  {\n    date: 1462369980000,\n    open: 49.59,\n    high: 49.636,\n    low: 49.586,\n    close: 49.59,\n    volume: 47743,\n  },\n  {\n    date: 1462370040000,\n    open: 49.59,\n    high: 49.6099,\n    low: 49.57,\n    close: 49.575,\n    volume: 43710,\n  },\n  {\n    date: 1462370100000,\n    open: 49.575,\n    high: 49.59,\n    low: 49.54,\n    close: 49.59,\n    volume: 43452,\n  },\n  {\n    date: 1462370160000,\n    open: 49.585,\n    high: 49.69,\n    low: 49.585,\n    close: 49.65,\n    volume: 74891,\n  },\n  {\n    date: 1462370220000,\n    open: 49.66,\n    high: 49.71,\n    low: 49.64,\n    close: 49.65,\n    volume: 59912,\n  },\n  {\n    date: 1462370280000,\n    open: 49.65,\n    high: 49.705,\n    low: 49.64,\n    close: 49.7,\n    volume: 43065,\n  },\n  {\n    date: 1462370340000,\n    open: 49.7,\n    high: 49.72,\n    low: 49.6735,\n    close: 49.695,\n    volume: 39650,\n  },\n  {\n    date: 1462370400000,\n    open: 49.695,\n    high: 49.76,\n    low: 49.6908,\n    close: 49.74,\n    volume: 96328,\n  },\n  {\n    date: 1462370460000,\n    open: 49.74,\n    high: 49.78,\n    low: 49.71,\n    close: 49.77,\n    volume: 72774,\n  },\n  {\n    date: 1462370520000,\n    open: 49.77,\n    high: 49.79,\n    low: 49.73,\n    close: 49.73,\n    volume: 50455,\n  },\n  {\n    date: 1462370580000,\n    open: 49.73,\n    high: 49.7399,\n    low: 49.66,\n    close: 49.7,\n    volume: 67443,\n  },\n  {\n    date: 1462370640000,\n    open: 49.7,\n    high: 49.715,\n    low: 49.645,\n    close: 49.67,\n    volume: 44465,\n  },\n  {\n    date: 1462370700000,\n    open: 49.67,\n    high: 49.73,\n    low: 49.66,\n    close: 49.685,\n    volume: 54855,\n  },\n  {\n    date: 1462370760000,\n    open: 49.68,\n    high: 49.69,\n    low: 49.67,\n    close: 49.69,\n    volume: 16982,\n  },\n  {\n    date: 1462370820000,\n    open: 49.68,\n    high: 49.72,\n    low: 49.62,\n    close: 49.64,\n    volume: 49058,\n  },\n  {\n    date: 1462370880000,\n    open: 49.65,\n    high: 49.67,\n    low: 49.641,\n    close: 49.6599,\n    volume: 15492,\n  },\n  {\n    date: 1462370940000,\n    open: 49.6562,\n    high: 49.72,\n    low: 49.65,\n    close: 49.72,\n    volume: 62035,\n  },\n  {\n    date: 1462371000000,\n    open: 49.71,\n    high: 49.73,\n    low: 49.695,\n    close: 49.713,\n    volume: 78439,\n  },\n  {\n    date: 1462371060000,\n    open: 49.71,\n    high: 49.79,\n    low: 49.7,\n    close: 49.7499,\n    volume: 80524,\n  },\n  {\n    date: 1462371120000,\n    open: 49.75,\n    high: 49.8,\n    low: 49.735,\n    close: 49.77,\n    volume: 105241,\n  },\n  {\n    date: 1462371180000,\n    open: 49.77,\n    high: 49.78,\n    low: 49.7,\n    close: 49.7,\n    volume: 51964,\n  },\n  {\n    date: 1462371240000,\n    open: 49.71,\n    high: 49.715,\n    low: 49.7,\n    close: 49.705,\n    volume: 41971,\n  },\n  {\n    date: 1462371300000,\n    open: 49.705,\n    high: 49.725,\n    low: 49.69,\n    close: 49.72,\n    volume: 48984,\n  },\n  {\n    date: 1462371360000,\n    open: 49.7252,\n    high: 49.75,\n    low: 49.7252,\n    close: 49.73,\n    volume: 25067,\n  },\n  {\n    date: 1462371420000,\n    open: 49.73,\n    high: 49.77,\n    low: 49.715,\n    close: 49.77,\n    volume: 45630,\n  },\n  {\n    date: 1462371480000,\n    open: 49.77,\n    high: 49.78,\n    low: 49.77,\n    close: 49.775,\n    volume: 16731,\n  },\n  {\n    date: 1462371540000,\n    open: 49.7667,\n    high: 49.78,\n    low: 49.74,\n    close: 49.76,\n    volume: 85974,\n  },\n  {\n    date: 1462371600000,\n    open: 49.77,\n    high: 49.825,\n    low: 49.76,\n    close: 49.82,\n    volume: 55016,\n  },\n  {\n    date: 1462371660000,\n    open: 49.8161,\n    high: 49.82,\n    low: 49.78,\n    close: 49.7832,\n    volume: 37245,\n  },\n  {\n    date: 1462371720000,\n    open: 49.7872,\n    high: 49.84,\n    low: 49.7872,\n    close: 49.84,\n    volume: 31629,\n  },\n  {\n    date: 1462371780000,\n    open: 49.83,\n    high: 49.845,\n    low: 49.82,\n    close: 49.83,\n    volume: 34162,\n  },\n  {\n    date: 1462371840000,\n    open: 49.82,\n    high: 49.84,\n    low: 49.8,\n    close: 49.815,\n    volume: 50505,\n  },\n  {\n    date: 1462371900000,\n    open: 49.82,\n    high: 49.85,\n    low: 49.81,\n    close: 49.84,\n    volume: 49413,\n  },\n  {\n    date: 1462371960000,\n    open: 49.845,\n    high: 49.85,\n    low: 49.79,\n    close: 49.81,\n    volume: 60942,\n  },\n  {\n    date: 1462372020000,\n    open: 49.805,\n    high: 49.84,\n    low: 49.8,\n    close: 49.801,\n    volume: 62268,\n  },\n  {\n    date: 1462372080000,\n    open: 49.81,\n    high: 49.87,\n    low: 49.81,\n    close: 49.83,\n    volume: 87992,\n  },\n  {\n    date: 1462372140000,\n    open: 49.835,\n    high: 49.87,\n    low: 49.835,\n    close: 49.87,\n    volume: 26158,\n  },\n  {\n    date: 1462372200000,\n    open: 49.8633,\n    high: 49.91,\n    low: 49.84,\n    close: 49.9,\n    volume: 141581,\n  },\n  {\n    date: 1462372260000,\n    open: 49.9,\n    high: 49.9399,\n    low: 49.89,\n    close: 49.925,\n    volume: 99747,\n  },\n  {\n    date: 1462372320000,\n    open: 49.92,\n    high: 49.94,\n    low: 49.9039,\n    close: 49.93,\n    volume: 67896,\n  },\n  {\n    date: 1462372380000,\n    open: 49.92,\n    high: 49.95,\n    low: 49.91,\n    close: 49.945,\n    volume: 79490,\n  },\n  {\n    date: 1462372440000,\n    open: 49.95,\n    high: 49.99,\n    low: 49.9402,\n    close: 49.965,\n    volume: 92052,\n  },\n  {\n    date: 1462372500000,\n    open: 49.97,\n    high: 49.995,\n    low: 49.93,\n    close: 49.93,\n    volume: 106546,\n  },\n  {\n    date: 1462372560000,\n    open: 49.932,\n    high: 49.94,\n    low: 49.87,\n    close: 49.875,\n    volume: 140096,\n  },\n  {\n    date: 1462372620000,\n    open: 49.8701,\n    high: 49.9,\n    low: 49.835,\n    close: 49.895,\n    volume: 56996,\n  },\n  {\n    date: 1462372680000,\n    open: 49.8955,\n    high: 49.935,\n    low: 49.895,\n    close: 49.93,\n    volume: 77582,\n  },\n  {\n    date: 1462372740000,\n    open: 49.939,\n    high: 49.97,\n    low: 49.925,\n    close: 49.94,\n    volume: 54748,\n  },\n  {\n    date: 1462372800000,\n    open: 49.94,\n    high: 49.98,\n    low: 49.9,\n    close: 49.95,\n    volume: 70242,\n  },\n  {\n    date: 1462372860000,\n    open: 49.955,\n    high: 49.9645,\n    low: 49.905,\n    close: 49.92,\n    volume: 38445,\n  },\n  {\n    date: 1462372920000,\n    open: 49.92,\n    high: 49.92,\n    low: 49.875,\n    close: 49.91,\n    volume: 27243,\n  },\n  {\n    date: 1462372980000,\n    open: 49.91,\n    high: 49.915,\n    low: 49.845,\n    close: 49.85,\n    volume: 38686,\n  },\n  {\n    date: 1462373040000,\n    open: 49.85,\n    high: 49.865,\n    low: 49.8,\n    close: 49.865,\n    volume: 42012,\n  },\n  {\n    date: 1462373100000,\n    open: 49.86,\n    high: 49.87,\n    low: 49.83,\n    close: 49.86,\n    volume: 31483,\n  },\n  {\n    date: 1462373160000,\n    open: 49.86,\n    high: 49.89,\n    low: 49.84,\n    close: 49.89,\n    volume: 21292,\n  },\n  {\n    date: 1462373220000,\n    open: 49.89,\n    high: 49.9,\n    low: 49.87,\n    close: 49.87,\n    volume: 129812,\n  },\n  {\n    date: 1462373280000,\n    open: 49.87,\n    high: 49.88,\n    low: 49.835,\n    close: 49.86,\n    volume: 31779,\n  },\n  {\n    date: 1462373340000,\n    open: 49.87,\n    high: 49.89,\n    low: 49.85,\n    close: 49.89,\n    volume: 70127,\n  },\n  {\n    date: 1462373400000,\n    open: 49.89,\n    high: 49.94,\n    low: 49.88,\n    close: 49.895,\n    volume: 84321,\n  },\n  {\n    date: 1462373460000,\n    open: 49.89,\n    high: 49.9099,\n    low: 49.875,\n    close: 49.875,\n    volume: 47809,\n  },\n  {\n    date: 1462373520000,\n    open: 49.875,\n    high: 49.875,\n    low: 49.835,\n    close: 49.845,\n    volume: 93063,\n  },\n  {\n    date: 1462373580000,\n    open: 49.845,\n    high: 49.85,\n    low: 49.84,\n    close: 49.84,\n    volume: 28747,\n  },\n  {\n    date: 1462373640000,\n    open: 49.8499,\n    high: 49.89,\n    low: 49.84,\n    close: 49.89,\n    volume: 54699,\n  },\n  {\n    date: 1462373700000,\n    open: 49.88,\n    high: 49.88,\n    low: 49.83,\n    close: 49.865,\n    volume: 34268,\n  },\n  {\n    date: 1462373760000,\n    open: 49.86,\n    high: 49.865,\n    low: 49.83,\n    close: 49.84,\n    volume: 27501,\n  },\n  {\n    date: 1462373820000,\n    open: 49.845,\n    high: 49.86,\n    low: 49.825,\n    close: 49.8301,\n    volume: 31820,\n  },\n  {\n    date: 1462373880000,\n    open: 49.84,\n    high: 49.9,\n    low: 49.83,\n    close: 49.86,\n    volume: 38207,\n  },\n  {\n    date: 1462373940000,\n    open: 49.86,\n    high: 49.866,\n    low: 49.83,\n    close: 49.835,\n    volume: 39658,\n  },\n  {\n    date: 1462374000000,\n    open: 49.83,\n    high: 49.855,\n    low: 49.82,\n    close: 49.835,\n    volume: 38659,\n  },\n  {\n    date: 1462374060000,\n    open: 49.835,\n    high: 49.85,\n    low: 49.825,\n    close: 49.83,\n    volume: 21314,\n  },\n  {\n    date: 1462374120000,\n    open: 49.84,\n    high: 49.8561,\n    low: 49.825,\n    close: 49.825,\n    volume: 25128,\n  },\n  {\n    date: 1462374180000,\n    open: 49.82,\n    high: 49.9,\n    low: 49.8,\n    close: 49.89,\n    volume: 39225,\n  },\n  {\n    date: 1462374240000,\n    open: 49.8801,\n    high: 49.89,\n    low: 49.86,\n    close: 49.875,\n    volume: 37939,\n  },\n  {\n    date: 1462374300000,\n    open: 49.87,\n    high: 49.8799,\n    low: 49.835,\n    close: 49.845,\n    volume: 30671,\n  },\n  {\n    date: 1462374360000,\n    open: 49.86,\n    high: 49.86,\n    low: 49.82,\n    close: 49.845,\n    volume: 30946,\n  },\n  {\n    date: 1462374420000,\n    open: 49.84,\n    high: 49.865,\n    low: 49.84,\n    close: 49.85,\n    volume: 31907,\n  },\n  {\n    date: 1462374480000,\n    open: 49.8436,\n    high: 49.85,\n    low: 49.82,\n    close: 49.845,\n    volume: 10859,\n  },\n  {\n    date: 1462374540000,\n    open: 49.84,\n    high: 49.845,\n    low: 49.81,\n    close: 49.82,\n    volume: 19324,\n  },\n  {\n    date: 1462374600000,\n    open: 49.83,\n    high: 49.88,\n    low: 49.81,\n    close: 49.822,\n    volume: 72652,\n  },\n  {\n    date: 1462374660000,\n    open: 49.83,\n    high: 49.83,\n    low: 49.805,\n    close: 49.82,\n    volume: 16901,\n  },\n  {\n    date: 1462374720000,\n    open: 49.82,\n    high: 49.83,\n    low: 49.78,\n    close: 49.78,\n    volume: 45559,\n  },\n  {\n    date: 1462374780000,\n    open: 49.78,\n    high: 49.839,\n    low: 49.78,\n    close: 49.8199,\n    volume: 32087,\n  },\n  {\n    date: 1462374840000,\n    open: 49.82,\n    high: 49.84,\n    low: 49.8001,\n    close: 49.835,\n    volume: 27221,\n  },\n  {\n    date: 1462374900000,\n    open: 49.8361,\n    high: 49.85,\n    low: 49.8,\n    close: 49.805,\n    volume: 51577,\n  },\n  {\n    date: 1462374960000,\n    open: 49.8,\n    high: 49.8199,\n    low: 49.76,\n    close: 49.76,\n    volume: 47474,\n  },\n  {\n    date: 1462375020000,\n    open: 49.76,\n    high: 49.77,\n    low: 49.695,\n    close: 49.7401,\n    volume: 79491,\n  },\n  {\n    date: 1462375080000,\n    open: 49.74,\n    high: 49.77,\n    low: 49.73,\n    close: 49.7545,\n    volume: 43073,\n  },\n  {\n    date: 1462375140000,\n    open: 49.755,\n    high: 49.77,\n    low: 49.7501,\n    close: 49.7601,\n    volume: 16634,\n  },\n  {\n    date: 1462375200000,\n    open: 49.77,\n    high: 49.77,\n    low: 49.7501,\n    close: 49.77,\n    volume: 27851,\n  },\n  {\n    date: 1462375260000,\n    open: 49.76,\n    high: 49.77,\n    low: 49.725,\n    close: 49.73,\n    volume: 31918,\n  },\n  {\n    date: 1462375320000,\n    open: 49.727,\n    high: 49.73,\n    low: 49.7,\n    close: 49.7025,\n    volume: 23044,\n  },\n  {\n    date: 1462375380000,\n    open: 49.7,\n    high: 49.77,\n    low: 49.69,\n    close: 49.76,\n    volume: 48682,\n  },\n  {\n    date: 1462375440000,\n    open: 49.77,\n    high: 49.7701,\n    low: 49.73,\n    close: 49.73,\n    volume: 31070,\n  },\n  {\n    date: 1462375500000,\n    open: 49.73,\n    high: 49.7699,\n    low: 49.73,\n    close: 49.7564,\n    volume: 33970,\n  },\n  {\n    date: 1462375560000,\n    open: 49.75,\n    high: 49.82,\n    low: 49.75,\n    close: 49.82,\n    volume: 63097,\n  },\n  {\n    date: 1462375620000,\n    open: 49.825,\n    high: 49.825,\n    low: 49.77,\n    close: 49.78,\n    volume: 54789,\n  },\n  {\n    date: 1462375680000,\n    open: 49.775,\n    high: 49.78,\n    low: 49.75,\n    close: 49.77,\n    volume: 25031,\n  },\n  {\n    date: 1462375740000,\n    open: 49.77,\n    high: 49.78,\n    low: 49.74,\n    close: 49.74,\n    volume: 35625,\n  },\n  {\n    date: 1462375800000,\n    open: 49.74,\n    high: 49.8,\n    low: 49.7301,\n    close: 49.76,\n    volume: 41253,\n  },\n  {\n    date: 1462375860000,\n    open: 49.76,\n    high: 49.78,\n    low: 49.74,\n    close: 49.74,\n    volume: 30147,\n  },\n  {\n    date: 1462375920000,\n    open: 49.74,\n    high: 49.79,\n    low: 49.71,\n    close: 49.783,\n    volume: 38031,\n  },\n  {\n    date: 1462375980000,\n    open: 49.7899,\n    high: 49.795,\n    low: 49.77,\n    close: 49.78,\n    volume: 29453,\n  },\n  {\n    date: 1462376040000,\n    open: 49.785,\n    high: 49.799,\n    low: 49.76,\n    close: 49.78,\n    volume: 33248,\n  },\n  {\n    date: 1462376100000,\n    open: 49.79,\n    high: 49.8399,\n    low: 49.79,\n    close: 49.819,\n    volume: 75790,\n  },\n  {\n    date: 1462376160000,\n    open: 49.82,\n    high: 49.845,\n    low: 49.815,\n    close: 49.82,\n    volume: 35400,\n  },\n  {\n    date: 1462376220000,\n    open: 49.82,\n    high: 49.83,\n    low: 49.7824,\n    close: 49.8099,\n    volume: 40852,\n  },\n  {\n    date: 1462376280000,\n    open: 49.8,\n    high: 49.81,\n    low: 49.7646,\n    close: 49.8,\n    volume: 39267,\n  },\n  {\n    date: 1462376340000,\n    open: 49.795,\n    high: 49.845,\n    low: 49.785,\n    close: 49.845,\n    volume: 39126,\n  },\n  {\n    date: 1462376400000,\n    open: 49.84,\n    high: 49.855,\n    low: 49.8101,\n    close: 49.8299,\n    volume: 59492,\n  },\n  {\n    date: 1462376460000,\n    open: 49.82,\n    high: 49.8365,\n    low: 49.795,\n    close: 49.8,\n    volume: 41740,\n  },\n  {\n    date: 1462376520000,\n    open: 49.81,\n    high: 49.83,\n    low: 49.805,\n    close: 49.82,\n    volume: 21155,\n  },\n  {\n    date: 1462376580000,\n    open: 49.82,\n    high: 49.82,\n    low: 49.8,\n    close: 49.82,\n    volume: 12496,\n  },\n  {\n    date: 1462376640000,\n    open: 49.815,\n    high: 49.83,\n    low: 49.795,\n    close: 49.8058,\n    volume: 40383,\n  },\n  {\n    date: 1462376700000,\n    open: 49.8,\n    high: 49.85,\n    low: 49.8,\n    close: 49.84,\n    volume: 34815,\n  },\n  {\n    date: 1462376760000,\n    open: 49.845,\n    high: 49.87,\n    low: 49.84,\n    close: 49.86,\n    volume: 59813,\n  },\n  {\n    date: 1462376820000,\n    open: 49.86,\n    high: 49.887,\n    low: 49.86,\n    close: 49.88,\n    volume: 50625,\n  },\n  {\n    date: 1462376880000,\n    open: 49.8799,\n    high: 49.89,\n    low: 49.86,\n    close: 49.89,\n    volume: 20854,\n  },\n  {\n    date: 1462376940000,\n    open: 49.9,\n    high: 49.92,\n    low: 49.89,\n    close: 49.905,\n    volume: 74487,\n  },\n  {\n    date: 1462377000000,\n    open: 49.89,\n    high: 49.94,\n    low: 49.89,\n    close: 49.94,\n    volume: 31908,\n  },\n  {\n    date: 1462377060000,\n    open: 49.94,\n    high: 49.95,\n    low: 49.91,\n    close: 49.91,\n    volume: 52406,\n  },\n  {\n    date: 1462377120000,\n    open: 49.9058,\n    high: 49.9058,\n    low: 49.86,\n    close: 49.88,\n    volume: 38290,\n  },\n  {\n    date: 1462377180000,\n    open: 49.8799,\n    high: 49.89,\n    low: 49.86,\n    close: 49.89,\n    volume: 29373,\n  },\n  {\n    date: 1462377240000,\n    open: 49.885,\n    high: 49.925,\n    low: 49.874,\n    close: 49.91,\n    volume: 50218,\n  },\n  {\n    date: 1462377300000,\n    open: 49.91,\n    high: 49.91,\n    low: 49.88,\n    close: 49.885,\n    volume: 15336,\n  },\n  {\n    date: 1462377360000,\n    open: 49.885,\n    high: 49.885,\n    low: 49.85,\n    close: 49.875,\n    volume: 26858,\n  },\n  {\n    date: 1462377420000,\n    open: 49.8799,\n    high: 49.905,\n    low: 49.86,\n    close: 49.9,\n    volume: 52981,\n  },\n  {\n    date: 1462377480000,\n    open: 49.9,\n    high: 49.905,\n    low: 49.86,\n    close: 49.885,\n    volume: 36003,\n  },\n  {\n    date: 1462377540000,\n    open: 49.885,\n    high: 49.94,\n    low: 49.88,\n    close: 49.93,\n    volume: 68117,\n  },\n  {\n    date: 1462377600000,\n    open: 49.93,\n    high: 49.96,\n    low: 49.92,\n    close: 49.94,\n    volume: 72396,\n  },\n  {\n    date: 1462377660000,\n    open: 49.9569,\n    high: 49.96,\n    low: 49.88,\n    close: 49.885,\n    volume: 45837,\n  },\n  {\n    date: 1462377720000,\n    open: 49.88,\n    high: 49.91,\n    low: 49.88,\n    close: 49.901,\n    volume: 20967,\n  },\n  {\n    date: 1462377780000,\n    open: 49.9,\n    high: 49.91,\n    low: 49.9,\n    close: 49.905,\n    volume: 30434,\n  },\n  {\n    date: 1462377840000,\n    open: 49.905,\n    high: 49.91,\n    low: 49.9,\n    close: 49.91,\n    volume: 22035,\n  },\n  {\n    date: 1462377900000,\n    open: 49.91,\n    high: 49.93,\n    low: 49.9,\n    close: 49.915,\n    volume: 37135,\n  },\n  {\n    date: 1462377960000,\n    open: 49.92,\n    high: 49.97,\n    low: 49.91,\n    close: 49.96,\n    volume: 44316,\n  },\n  {\n    date: 1462378020000,\n    open: 49.96,\n    high: 49.99,\n    low: 49.95,\n    close: 49.9899,\n    volume: 56348,\n  },\n  {\n    date: 1462378080000,\n    open: 49.98,\n    high: 50,\n    low: 49.975,\n    close: 49.98,\n    volume: 41301,\n  },\n  {\n    date: 1462378140000,\n    open: 49.985,\n    high: 49.985,\n    low: 49.96,\n    close: 49.9765,\n    volume: 30198,\n  },\n  {\n    date: 1462378200000,\n    open: 49.97,\n    high: 49.9799,\n    low: 49.96,\n    close: 49.97,\n    volume: 45795,\n  },\n  {\n    date: 1462378260000,\n    open: 49.97,\n    high: 49.99,\n    low: 49.965,\n    close: 49.99,\n    volume: 13995,\n  },\n  {\n    date: 1462378320000,\n    open: 49.9864,\n    high: 50.01,\n    low: 49.985,\n    close: 49.991,\n    volume: 116544,\n  },\n  {\n    date: 1462378380000,\n    open: 49.9994,\n    high: 50.02,\n    low: 49.98,\n    close: 50.02,\n    volume: 133498,\n  },\n  {\n    date: 1462378440000,\n    open: 50.02,\n    high: 50.03,\n    low: 50,\n    close: 50.0064,\n    volume: 50699,\n  },\n  {\n    date: 1462378500000,\n    open: 50.01,\n    high: 50.025,\n    low: 50,\n    close: 50,\n    volume: 51251,\n  },\n  {\n    date: 1462378560000,\n    open: 50,\n    high: 50.005,\n    low: 49.99,\n    close: 49.995,\n    volume: 34497,\n  },\n  {\n    date: 1462378620000,\n    open: 50,\n    high: 50.01,\n    low: 49.96,\n    close: 50.005,\n    volume: 65003,\n  },\n  {\n    date: 1462378680000,\n    open: 50.0099,\n    high: 50.01,\n    low: 49.985,\n    close: 49.985,\n    volume: 28114,\n  },\n  {\n    date: 1462378740000,\n    open: 49.99,\n    high: 50,\n    low: 49.981,\n    close: 49.99,\n    volume: 14877,\n  },\n  {\n    date: 1462378800000,\n    open: 49.9999,\n    high: 49.9999,\n    low: 49.98,\n    close: 49.985,\n    volume: 17662,\n  },\n  {\n    date: 1462378860000,\n    open: 49.98,\n    high: 50.01,\n    low: 49.98,\n    close: 50.01,\n    volume: 38861,\n  },\n  {\n    date: 1462378920000,\n    open: 50,\n    high: 50.005,\n    low: 49.99,\n    close: 49.99,\n    volume: 23654,\n  },\n  {\n    date: 1462378980000,\n    open: 49.987,\n    high: 50.03,\n    low: 49.97,\n    close: 50.01,\n    volume: 46807,\n  },\n  {\n    date: 1462379040000,\n    open: 50.015,\n    high: 50.015,\n    low: 49.985,\n    close: 50,\n    volume: 47784,\n  },\n  {\n    date: 1462379100000,\n    open: 49.9931,\n    high: 50.0299,\n    low: 49.99,\n    close: 50.025,\n    volume: 25066,\n  },\n  {\n    date: 1462379160000,\n    open: 50.02,\n    high: 50.06,\n    low: 50.0101,\n    close: 50.055,\n    volume: 78854,\n  },\n  {\n    date: 1462379220000,\n    open: 50.05,\n    high: 50.055,\n    low: 50.03,\n    close: 50.0499,\n    volume: 38477,\n  },\n  {\n    date: 1462379280000,\n    open: 50.049,\n    high: 50.06,\n    low: 50.0198,\n    close: 50.0198,\n    volume: 44342,\n  },\n  {\n    date: 1462379340000,\n    open: 50.02,\n    high: 50.02,\n    low: 50,\n    close: 50.0003,\n    volume: 41047,\n  },\n  {\n    date: 1462379400000,\n    open: 50.005,\n    high: 50.015,\n    low: 50,\n    close: 50.0063,\n    volume: 44752,\n  },\n  {\n    date: 1462379460000,\n    open: 50,\n    high: 50.01,\n    low: 49.98,\n    close: 49.99,\n    volume: 41014,\n  },\n  {\n    date: 1462379520000,\n    open: 49.995,\n    high: 50.01,\n    low: 49.99,\n    close: 50.01,\n    volume: 15808,\n  },\n  {\n    date: 1462379580000,\n    open: 50,\n    high: 50.0095,\n    low: 49.99,\n    close: 49.995,\n    volume: 44160,\n  },\n  {\n    date: 1462379640000,\n    open: 49.995,\n    high: 50.01,\n    low: 49.99,\n    close: 50.01,\n    volume: 18292,\n  },\n  {\n    date: 1462379700000,\n    open: 50,\n    high: 50.005,\n    low: 49.98,\n    close: 49.98,\n    volume: 45885,\n  },\n  {\n    date: 1462379760000,\n    open: 49.99,\n    high: 49.9986,\n    low: 49.97,\n    close: 49.9764,\n    volume: 24490,\n  },\n  {\n    date: 1462379820000,\n    open: 49.97,\n    high: 49.98,\n    low: 49.95,\n    close: 49.98,\n    volume: 31198,\n  },\n  {\n    date: 1462379880000,\n    open: 49.98,\n    high: 50,\n    low: 49.965,\n    close: 50,\n    volume: 26231,\n  },\n  {\n    date: 1462379940000,\n    open: 49.99,\n    high: 50,\n    low: 49.9701,\n    close: 49.995,\n    volume: 49426,\n  },\n  {\n    date: 1462380000000,\n    open: 49.99,\n    high: 50.02,\n    low: 49.98,\n    close: 49.99,\n    volume: 97539,\n  },\n  {\n    date: 1462380060000,\n    open: 49.995,\n    high: 50,\n    low: 49.975,\n    close: 49.987,\n    volume: 98725,\n  },\n  {\n    date: 1462380120000,\n    open: 49.98,\n    high: 50,\n    low: 49.965,\n    close: 49.97,\n    volume: 51750,\n  },\n  {\n    date: 1462380180000,\n    open: 49.97,\n    high: 49.985,\n    low: 49.97,\n    close: 49.98,\n    volume: 11485,\n  },\n  {\n    date: 1462380240000,\n    open: 49.9864,\n    high: 50,\n    low: 49.98,\n    close: 49.9911,\n    volume: 17100,\n  },\n  {\n    date: 1462380300000,\n    open: 49.9937,\n    high: 49.9999,\n    low: 49.96,\n    close: 49.975,\n    volume: 51474,\n  },\n  {\n    date: 1462380360000,\n    open: 49.975,\n    high: 49.99,\n    low: 49.97,\n    close: 49.97,\n    volume: 25962,\n  },\n  {\n    date: 1462380420000,\n    open: 49.97,\n    high: 50,\n    low: 49.97,\n    close: 49.99,\n    volume: 34279,\n  },\n  {\n    date: 1462380480000,\n    open: 49.98,\n    high: 49.989,\n    low: 49.96,\n    close: 49.96,\n    volume: 19567,\n  },\n  {\n    date: 1462380540000,\n    open: 49.97,\n    high: 49.98,\n    low: 49.96,\n    close: 49.975,\n    volume: 17001,\n  },\n  {\n    date: 1462380600000,\n    open: 49.98,\n    high: 49.98,\n    low: 49.97,\n    close: 49.97,\n    volume: 10616,\n  },\n  {\n    date: 1462380660000,\n    open: 49.975,\n    high: 49.98,\n    low: 49.952,\n    close: 49.9615,\n    volume: 52613,\n  },\n  {\n    date: 1462380720000,\n    open: 49.9664,\n    high: 49.99,\n    low: 49.95,\n    close: 49.98,\n    volume: 45711,\n  },\n  {\n    date: 1462380780000,\n    open: 49.9718,\n    high: 49.99,\n    low: 49.97,\n    close: 49.99,\n    volume: 20599,\n  },\n  {\n    date: 1462380840000,\n    open: 49.99,\n    high: 49.99,\n    low: 49.97,\n    close: 49.98,\n    volume: 7565,\n  },\n  {\n    date: 1462380900000,\n    open: 49.98,\n    high: 50,\n    low: 49.975,\n    close: 49.98,\n    volume: 30909,\n  },\n  {\n    date: 1462380960000,\n    open: 49.98,\n    high: 49.99,\n    low: 49.96,\n    close: 49.975,\n    volume: 57671,\n  },\n  {\n    date: 1462381020000,\n    open: 49.975,\n    high: 49.98,\n    low: 49.97,\n    close: 49.9799,\n    volume: 4428,\n  },\n  {\n    date: 1462381080000,\n    open: 49.975,\n    high: 49.98,\n    low: 49.97,\n    close: 49.9755,\n    volume: 7457,\n  },\n  {\n    date: 1462381140000,\n    open: 49.975,\n    high: 49.985,\n    low: 49.96,\n    close: 49.96,\n    volume: 72037,\n  },\n  {\n    date: 1462381200000,\n    open: 49.96,\n    high: 49.98,\n    low: 49.95,\n    close: 49.9725,\n    volume: 68698,\n  },\n  {\n    date: 1462381260000,\n    open: 49.975,\n    high: 49.98,\n    low: 49.96,\n    close: 49.965,\n    volume: 169344,\n  },\n  {\n    date: 1462381320000,\n    open: 49.96,\n    high: 49.99,\n    low: 49.96,\n    close: 49.985,\n    volume: 32674,\n  },\n  {\n    date: 1462381380000,\n    open: 49.985,\n    high: 50,\n    low: 49.98,\n    close: 49.99,\n    volume: 59421,\n  },\n  {\n    date: 1462381440000,\n    open: 49.995,\n    high: 50.05,\n    low: 49.99,\n    close: 50.04,\n    volume: 84280,\n  },\n  {\n    date: 1462381500000,\n    open: 50.04,\n    high: 50.04,\n    low: 49.99,\n    close: 50.01,\n    volume: 45781,\n  },\n  {\n    date: 1462381560000,\n    open: 50.0159,\n    high: 50.02,\n    low: 49.99,\n    close: 50,\n    volume: 24711,\n  },\n  {\n    date: 1462381620000,\n    open: 49.99,\n    high: 50.03,\n    low: 49.99,\n    close: 50.01,\n    volume: 35855,\n  },\n  {\n    date: 1462381680000,\n    open: 50.005,\n    high: 50.02,\n    low: 50,\n    close: 50.02,\n    volume: 13786,\n  },\n  {\n    date: 1462381740000,\n    open: 50.02,\n    high: 50.03,\n    low: 49.99,\n    close: 49.99,\n    volume: 18934,\n  },\n  {\n    date: 1462381800000,\n    open: 49.99,\n    high: 50.01,\n    low: 49.99,\n    close: 49.995,\n    volume: 65585,\n  },\n  {\n    date: 1462381860000,\n    open: 49.9999,\n    high: 49.9999,\n    low: 49.95,\n    close: 49.965,\n    volume: 99092,\n  },\n  {\n    date: 1462381920000,\n    open: 49.961,\n    high: 49.99,\n    low: 49.96,\n    close: 49.965,\n    volume: 53534,\n  },\n  {\n    date: 1462381980000,\n    open: 49.965,\n    high: 49.97,\n    low: 49.95,\n    close: 49.965,\n    volume: 27583,\n  },\n  {\n    date: 1462382040000,\n    open: 49.97,\n    high: 49.98,\n    low: 49.94,\n    close: 49.95,\n    volume: 42270,\n  },\n  {\n    date: 1462382100000,\n    open: 49.95,\n    high: 49.95,\n    low: 49.94,\n    close: 49.944,\n    volume: 16037,\n  },\n  {\n    date: 1462382160000,\n    open: 49.95,\n    high: 50,\n    low: 49.945,\n    close: 49.9999,\n    volume: 68723,\n  },\n  {\n    date: 1462382220000,\n    open: 49.995,\n    high: 50,\n    low: 49.99,\n    close: 49.995,\n    volume: 83073,\n  },\n  {\n    date: 1462382280000,\n    open: 50,\n    high: 50,\n    low: 49.97,\n    close: 49.975,\n    volume: 33768,\n  },\n  {\n    date: 1462382340000,\n    open: 49.975,\n    high: 49.98,\n    low: 49.96,\n    close: 49.965,\n    volume: 24332,\n  },\n  {\n    date: 1462382400000,\n    open: 49.965,\n    high: 49.98,\n    low: 49.95,\n    close: 49.975,\n    volume: 63435,\n  },\n  {\n    date: 1462382460000,\n    open: 49.975,\n    high: 49.98,\n    low: 49.97,\n    close: 49.975,\n    volume: 13318,\n  },\n  {\n    date: 1462382520000,\n    open: 49.97,\n    high: 49.98,\n    low: 49.955,\n    close: 49.955,\n    volume: 32390,\n  },\n  {\n    date: 1462382580000,\n    open: 49.955,\n    high: 49.9599,\n    low: 49.94,\n    close: 49.95,\n    volume: 27186,\n  },\n  {\n    date: 1462382640000,\n    open: 49.945,\n    high: 49.945,\n    low: 49.93,\n    close: 49.938,\n    volume: 50974,\n  },\n  {\n    date: 1462382700000,\n    open: 49.94,\n    high: 49.95,\n    low: 49.93,\n    close: 49.93,\n    volume: 23650,\n  },\n  {\n    date: 1462382760000,\n    open: 49.93,\n    high: 49.93,\n    low: 49.89,\n    close: 49.9,\n    volume: 57353,\n  },\n  {\n    date: 1462382820000,\n    open: 49.8992,\n    high: 49.92,\n    low: 49.89,\n    close: 49.92,\n    volume: 24947,\n  },\n  {\n    date: 1462382880000,\n    open: 49.91,\n    high: 49.92,\n    low: 49.905,\n    close: 49.9133,\n    volume: 14895,\n  },\n  {\n    date: 1462382940000,\n    open: 49.9127,\n    high: 49.95,\n    low: 49.91,\n    close: 49.93,\n    volume: 46834,\n  },\n  {\n    date: 1462383000000,\n    open: 49.93,\n    high: 49.97,\n    low: 49.93,\n    close: 49.97,\n    volume: 13175,\n  },\n  {\n    date: 1462383060000,\n    open: 49.975,\n    high: 49.98,\n    low: 49.94,\n    close: 49.96,\n    volume: 37778,\n  },\n  {\n    date: 1462383120000,\n    open: 49.96,\n    high: 49.9899,\n    low: 49.95,\n    close: 49.96,\n    volume: 51112,\n  },\n  {\n    date: 1462383180000,\n    open: 49.955,\n    high: 49.9699,\n    low: 49.935,\n    close: 49.96,\n    volume: 26313,\n  },\n  {\n    date: 1462383240000,\n    open: 49.965,\n    high: 49.9799,\n    low: 49.94,\n    close: 49.94,\n    volume: 46354,\n  },\n  {\n    date: 1462383300000,\n    open: 49.94,\n    high: 49.955,\n    low: 49.94,\n    close: 49.955,\n    volume: 19166,\n  },\n  {\n    date: 1462383360000,\n    open: 49.955,\n    high: 49.966,\n    low: 49.92,\n    close: 49.92,\n    volume: 20517,\n  },\n  {\n    date: 1462383420000,\n    open: 49.93,\n    high: 49.97,\n    low: 49.93,\n    close: 49.97,\n    volume: 26111,\n  },\n  {\n    date: 1462383480000,\n    open: 49.9636,\n    high: 49.9799,\n    low: 49.94,\n    close: 49.94,\n    volume: 39627,\n  },\n  {\n    date: 1462383540000,\n    open: 49.94,\n    high: 49.95,\n    low: 49.89,\n    close: 49.89,\n    volume: 49813,\n  },\n  {\n    date: 1462383600000,\n    open: 49.895,\n    high: 49.93,\n    low: 49.89,\n    close: 49.926,\n    volume: 29424,\n  },\n  {\n    date: 1462383660000,\n    open: 49.92,\n    high: 49.94,\n    low: 49.91,\n    close: 49.93,\n    volume: 29865,\n  },\n  {\n    date: 1462383720000,\n    open: 49.9301,\n    high: 49.99,\n    low: 49.9301,\n    close: 49.99,\n    volume: 90396,\n  },\n  {\n    date: 1462383780000,\n    open: 49.9871,\n    high: 49.99,\n    low: 49.96,\n    close: 49.966,\n    volume: 65141,\n  },\n  {\n    date: 1462383840000,\n    open: 49.97,\n    high: 49.98,\n    low: 49.95,\n    close: 49.95,\n    volume: 30315,\n  },\n  {\n    date: 1462383900000,\n    open: 49.95,\n    high: 49.96,\n    low: 49.925,\n    close: 49.94,\n    volume: 25304,\n  },\n  {\n    date: 1462383960000,\n    open: 49.9365,\n    high: 49.9365,\n    low: 49.91,\n    close: 49.91,\n    volume: 41739,\n  },\n  {\n    date: 1462384020000,\n    open: 49.91,\n    high: 49.92,\n    low: 49.885,\n    close: 49.92,\n    volume: 52725,\n  },\n  {\n    date: 1462384080000,\n    open: 49.91,\n    high: 49.93,\n    low: 49.91,\n    close: 49.921,\n    volume: 25272,\n  },\n  {\n    date: 1462384140000,\n    open: 49.92,\n    high: 49.96,\n    low: 49.915,\n    close: 49.94,\n    volume: 41575,\n  },\n  {\n    date: 1462384200000,\n    open: 49.935,\n    high: 49.96,\n    low: 49.9338,\n    close: 49.955,\n    volume: 17650,\n  },\n  {\n    date: 1462384260000,\n    open: 49.96,\n    high: 49.99,\n    low: 49.955,\n    close: 49.97,\n    volume: 75321,\n  },\n  {\n    date: 1462384320000,\n    open: 49.97,\n    high: 49.98,\n    low: 49.95,\n    close: 49.95,\n    volume: 24126,\n  },\n  {\n    date: 1462384380000,\n    open: 49.95,\n    high: 49.96,\n    low: 49.93,\n    close: 49.95,\n    volume: 26863,\n  },\n  {\n    date: 1462384440000,\n    open: 49.95,\n    high: 49.96,\n    low: 49.9239,\n    close: 49.94,\n    volume: 19566,\n  },\n  {\n    date: 1462384500000,\n    open: 49.94,\n    high: 49.95,\n    low: 49.92,\n    close: 49.94,\n    volume: 32586,\n  },\n  {\n    date: 1462384560000,\n    open: 49.94,\n    high: 49.97,\n    low: 49.94,\n    close: 49.94,\n    volume: 79768,\n  },\n  {\n    date: 1462384620000,\n    open: 49.9371,\n    high: 49.94,\n    low: 49.89,\n    close: 49.9029,\n    volume: 42153,\n  },\n  {\n    date: 1462384680000,\n    open: 49.9,\n    high: 49.91,\n    low: 49.9,\n    close: 49.9,\n    volume: 24748,\n  },\n  {\n    date: 1462384740000,\n    open: 49.9,\n    high: 49.91,\n    low: 49.89,\n    close: 49.905,\n    volume: 27604,\n  },\n  {\n    date: 1462384800000,\n    open: 49.8971,\n    high: 49.8971,\n    low: 49.87,\n    close: 49.875,\n    volume: 42664,\n  },\n  {\n    date: 1462384860000,\n    open: 49.88,\n    high: 49.88,\n    low: 49.8301,\n    close: 49.8468,\n    volume: 75523,\n  },\n  {\n    date: 1462384920000,\n    open: 49.8465,\n    high: 49.86,\n    low: 49.815,\n    close: 49.859,\n    volume: 57517,\n  },\n  {\n    date: 1462384980000,\n    open: 49.85,\n    high: 49.85,\n    low: 49.82,\n    close: 49.82,\n    volume: 30051,\n  },\n  {\n    date: 1462385040000,\n    open: 49.82,\n    high: 49.86,\n    low: 49.81,\n    close: 49.855,\n    volume: 35130,\n  },\n  {\n    date: 1462385100000,\n    open: 49.86,\n    high: 49.86,\n    low: 49.84,\n    close: 49.8401,\n    volume: 22465,\n  },\n  {\n    date: 1462385160000,\n    open: 49.84,\n    high: 49.85,\n    low: 49.81,\n    close: 49.82,\n    volume: 43594,\n  },\n  {\n    date: 1462385220000,\n    open: 49.81,\n    high: 49.83,\n    low: 49.8,\n    close: 49.815,\n    volume: 64133,\n  },\n  {\n    date: 1462385280000,\n    open: 49.8101,\n    high: 49.84,\n    low: 49.8101,\n    close: 49.825,\n    volume: 33226,\n  },\n  {\n    date: 1462385340000,\n    open: 49.825,\n    high: 49.854,\n    low: 49.82,\n    close: 49.82,\n    volume: 26359,\n  },\n  {\n    date: 1462385400000,\n    open: 49.82,\n    high: 49.865,\n    low: 49.82,\n    close: 49.86,\n    volume: 42682,\n  },\n  {\n    date: 1462385460000,\n    open: 49.8599,\n    high: 49.87,\n    low: 49.84,\n    close: 49.856,\n    volume: 30313,\n  },\n  {\n    date: 1462385520000,\n    open: 49.85,\n    high: 49.85,\n    low: 49.81,\n    close: 49.81,\n    volume: 21145,\n  },\n  {\n    date: 1462385580000,\n    open: 49.81,\n    high: 49.81,\n    low: 49.8,\n    close: 49.8,\n    volume: 18580,\n  },\n  {\n    date: 1462385640000,\n    open: 49.8099,\n    high: 49.83,\n    low: 49.805,\n    close: 49.83,\n    volume: 18883,\n  },\n  {\n    date: 1462385700000,\n    open: 49.825,\n    high: 49.85,\n    low: 49.82,\n    close: 49.85,\n    volume: 30434,\n  },\n  {\n    date: 1462385760000,\n    open: 49.845,\n    high: 49.845,\n    low: 49.82,\n    close: 49.8201,\n    volume: 18424,\n  },\n  {\n    date: 1462385820000,\n    open: 49.822,\n    high: 49.85,\n    low: 49.82,\n    close: 49.85,\n    volume: 35817,\n  },\n  {\n    date: 1462385880000,\n    open: 49.8467,\n    high: 49.89,\n    low: 49.8415,\n    close: 49.885,\n    volume: 51948,\n  },\n  {\n    date: 1462385940000,\n    open: 49.88,\n    high: 49.9,\n    low: 49.86,\n    close: 49.87,\n    volume: 28836,\n  },\n  {\n    date: 1462386000000,\n    open: 49.87,\n    high: 49.895,\n    low: 49.86,\n    close: 49.89,\n    volume: 27275,\n  },\n  {\n    date: 1462386060000,\n    open: 49.89,\n    high: 49.9,\n    low: 49.87,\n    close: 49.8701,\n    volume: 47923,\n  },\n  {\n    date: 1462386120000,\n    open: 49.87,\n    high: 49.87,\n    low: 49.85,\n    close: 49.865,\n    volume: 14163,\n  },\n  {\n    date: 1462386180000,\n    open: 49.867,\n    high: 49.92,\n    low: 49.86,\n    close: 49.885,\n    volume: 60686,\n  },\n  {\n    date: 1462386240000,\n    open: 49.885,\n    high: 49.93,\n    low: 49.885,\n    close: 49.915,\n    volume: 31185,\n  },\n  {\n    date: 1462386300000,\n    open: 49.92,\n    high: 49.92,\n    low: 49.885,\n    close: 49.91,\n    volume: 26943,\n  },\n  {\n    date: 1462386360000,\n    open: 49.915,\n    high: 49.945,\n    low: 49.9001,\n    close: 49.94,\n    volume: 53295,\n  },\n  {\n    date: 1462386420000,\n    open: 49.93,\n    high: 49.932,\n    low: 49.885,\n    close: 49.91,\n    volume: 30047,\n  },\n  {\n    date: 1462386480000,\n    open: 49.91,\n    high: 49.91,\n    low: 49.87,\n    close: 49.8899,\n    volume: 22374,\n  },\n  {\n    date: 1462386540000,\n    open: 49.885,\n    high: 49.9199,\n    low: 49.88,\n    close: 49.89,\n    volume: 27312,\n  },\n  {\n    date: 1462386600000,\n    open: 49.8864,\n    high: 49.904,\n    low: 49.88,\n    close: 49.895,\n    volume: 26483,\n  },\n  {\n    date: 1462386660000,\n    open: 49.89,\n    high: 49.91,\n    low: 49.88,\n    close: 49.9039,\n    volume: 130507,\n  },\n  {\n    date: 1462386720000,\n    open: 49.9,\n    high: 49.9167,\n    low: 49.895,\n    close: 49.9099,\n    volume: 47245,\n  },\n  {\n    date: 1462386780000,\n    open: 49.905,\n    high: 49.94,\n    low: 49.9,\n    close: 49.935,\n    volume: 39956,\n  },\n  {\n    date: 1462386840000,\n    open: 49.935,\n    high: 49.96,\n    low: 49.93,\n    close: 49.955,\n    volume: 80801,\n  },\n  {\n    date: 1462386900000,\n    open: 49.955,\n    high: 49.96,\n    low: 49.94,\n    close: 49.9564,\n    volume: 75807,\n  },\n  {\n    date: 1462386960000,\n    open: 49.95,\n    high: 49.985,\n    low: 49.95,\n    close: 49.97,\n    volume: 111128,\n  },\n  {\n    date: 1462387020000,\n    open: 49.965,\n    high: 49.97,\n    low: 49.95,\n    close: 49.955,\n    volume: 28322,\n  },\n  {\n    date: 1462387080000,\n    open: 49.95,\n    high: 49.965,\n    low: 49.915,\n    close: 49.945,\n    volume: 35045,\n  },\n  {\n    date: 1462387140000,\n    open: 49.9499,\n    high: 49.9664,\n    low: 49.9,\n    close: 49.91,\n    volume: 54581,\n  },\n  {\n    date: 1462387200000,\n    open: 49.91,\n    high: 49.92,\n    low: 49.91,\n    close: 49.92,\n    volume: 12752,\n  },\n  {\n    date: 1462387260000,\n    open: 49.93,\n    high: 49.945,\n    low: 49.88,\n    close: 49.8899,\n    volume: 28527,\n  },\n  {\n    date: 1462387320000,\n    open: 49.885,\n    high: 49.8956,\n    low: 49.84,\n    close: 49.84,\n    volume: 49331,\n  },\n  {\n    date: 1462387380000,\n    open: 49.845,\n    high: 49.865,\n    low: 49.84,\n    close: 49.865,\n    volume: 19315,\n  },\n  {\n    date: 1462387440000,\n    open: 49.8699,\n    high: 49.8699,\n    low: 49.8236,\n    close: 49.825,\n    volume: 24320,\n  },\n  {\n    date: 1462387500000,\n    open: 49.825,\n    high: 49.84,\n    low: 49.82,\n    close: 49.835,\n    volume: 18457,\n  },\n  {\n    date: 1462387560000,\n    open: 49.8367,\n    high: 49.85,\n    low: 49.83,\n    close: 49.845,\n    volume: 23988,\n  },\n  {\n    date: 1462387620000,\n    open: 49.85,\n    high: 49.859,\n    low: 49.815,\n    close: 49.82,\n    volume: 38013,\n  },\n  {\n    date: 1462387680000,\n    open: 49.83,\n    high: 49.85,\n    low: 49.8264,\n    close: 49.835,\n    volume: 11140,\n  },\n  {\n    date: 1462387740000,\n    open: 49.835,\n    high: 49.87,\n    low: 49.835,\n    close: 49.8633,\n    volume: 54496,\n  },\n  {\n    date: 1462387800000,\n    open: 49.864,\n    high: 49.88,\n    low: 49.84,\n    close: 49.85,\n    volume: 31259,\n  },\n  {\n    date: 1462387860000,\n    open: 49.8598,\n    high: 49.8598,\n    low: 49.82,\n    close: 49.847,\n    volume: 29020,\n  },\n  {\n    date: 1462387920000,\n    open: 49.84,\n    high: 49.85,\n    low: 49.835,\n    close: 49.845,\n    volume: 15076,\n  },\n  {\n    date: 1462387980000,\n    open: 49.84,\n    high: 49.87,\n    low: 49.84,\n    close: 49.84,\n    volume: 24839,\n  },\n  {\n    date: 1462388040000,\n    open: 49.8499,\n    high: 49.9025,\n    low: 49.845,\n    close: 49.8999,\n    volume: 29898,\n  },\n  {\n    date: 1462388100000,\n    open: 49.89,\n    high: 49.895,\n    low: 49.8301,\n    close: 49.84,\n    volume: 41722,\n  },\n  {\n    date: 1462388160000,\n    open: 49.84,\n    high: 49.86,\n    low: 49.821,\n    close: 49.85,\n    volume: 30696,\n  },\n  {\n    date: 1462388220000,\n    open: 49.85,\n    high: 49.8599,\n    low: 49.85,\n    close: 49.85,\n    volume: 10019,\n  },\n  {\n    date: 1462388280000,\n    open: 49.85,\n    high: 49.853,\n    low: 49.8256,\n    close: 49.8299,\n    volume: 30839,\n  },\n  {\n    date: 1462388340000,\n    open: 49.82,\n    high: 49.8399,\n    low: 49.815,\n    close: 49.8298,\n    volume: 50212,\n  },\n  {\n    date: 1462388400000,\n    open: 49.825,\n    high: 49.85,\n    low: 49.825,\n    close: 49.849,\n    volume: 8461,\n  },\n  {\n    date: 1462388460000,\n    open: 49.84,\n    high: 49.86,\n    low: 49.83,\n    close: 49.8556,\n    volume: 35788,\n  },\n  {\n    date: 1462388520000,\n    open: 49.85,\n    high: 49.88,\n    low: 49.85,\n    close: 49.87,\n    volume: 41657,\n  },\n  {\n    date: 1462388580000,\n    open: 49.87,\n    high: 49.8799,\n    low: 49.85,\n    close: 49.86,\n    volume: 10171,\n  },\n  {\n    date: 1462388640000,\n    open: 49.855,\n    high: 49.855,\n    low: 49.79,\n    close: 49.8,\n    volume: 148352,\n  },\n  {\n    date: 1462388700000,\n    open: 49.81,\n    high: 49.85,\n    low: 49.8,\n    close: 49.84,\n    volume: 26188,\n  },\n  {\n    date: 1462388760000,\n    open: 49.845,\n    high: 49.845,\n    low: 49.82,\n    close: 49.8236,\n    volume: 20620,\n  },\n  {\n    date: 1462388820000,\n    open: 49.825,\n    high: 49.83,\n    low: 49.8,\n    close: 49.82,\n    volume: 19694,\n  },\n  {\n    date: 1462388880000,\n    open: 49.82,\n    high: 49.83,\n    low: 49.805,\n    close: 49.81,\n    volume: 21364,\n  },\n  {\n    date: 1462388940000,\n    open: 49.8001,\n    high: 49.8573,\n    low: 49.8001,\n    close: 49.857,\n    volume: 24739,\n  },\n  {\n    date: 1462389000000,\n    open: 49.855,\n    high: 49.856,\n    low: 49.84,\n    close: 49.85,\n    volume: 22572,\n  },\n  {\n    date: 1462389060000,\n    open: 49.86,\n    high: 49.86,\n    low: 49.78,\n    close: 49.8201,\n    volume: 100580,\n  },\n  {\n    date: 1462389120000,\n    open: 49.83,\n    high: 49.85,\n    low: 49.83,\n    close: 49.83,\n    volume: 17283,\n  },\n  {\n    date: 1462389180000,\n    open: 49.831,\n    high: 49.86,\n    low: 49.83,\n    close: 49.86,\n    volume: 43611,\n  },\n  {\n    date: 1462389240000,\n    open: 49.855,\n    high: 49.87,\n    low: 49.85,\n    close: 49.861,\n    volume: 15054,\n  },\n  {\n    date: 1462389300000,\n    open: 49.86,\n    high: 49.9161,\n    low: 49.86,\n    close: 49.91,\n    volume: 55046,\n  },\n  {\n    date: 1462389360000,\n    open: 49.9199,\n    high: 49.92,\n    low: 49.88,\n    close: 49.885,\n    volume: 32450,\n  },\n  {\n    date: 1462389420000,\n    open: 49.8833,\n    high: 49.8999,\n    low: 49.87,\n    close: 49.87,\n    volume: 33752,\n  },\n  {\n    date: 1462389480000,\n    open: 49.88,\n    high: 49.8999,\n    low: 49.88,\n    close: 49.8801,\n    volume: 27573,\n  },\n  {\n    date: 1462389540000,\n    open: 49.887,\n    high: 49.9,\n    low: 49.88,\n    close: 49.8901,\n    volume: 32521,\n  },\n  {\n    date: 1462389600000,\n    open: 49.89,\n    high: 49.895,\n    low: 49.855,\n    close: 49.855,\n    volume: 56401,\n  },\n  {\n    date: 1462389660000,\n    open: 49.85,\n    high: 49.86,\n    low: 49.84,\n    close: 49.8599,\n    volume: 35084,\n  },\n  {\n    date: 1462389720000,\n    open: 49.86,\n    high: 49.9168,\n    low: 49.86,\n    close: 49.9168,\n    volume: 46118,\n  },\n  {\n    date: 1462389780000,\n    open: 49.92,\n    high: 49.92,\n    low: 49.89,\n    close: 49.91,\n    volume: 38173,\n  },\n  {\n    date: 1462389840000,\n    open: 49.9067,\n    high: 49.93,\n    low: 49.9,\n    close: 49.93,\n    volume: 21910,\n  },\n  {\n    date: 1462389900000,\n    open: 49.9272,\n    high: 49.9399,\n    low: 49.9,\n    close: 49.91,\n    volume: 65695,\n  },\n  {\n    date: 1462389960000,\n    open: 49.91,\n    high: 49.9199,\n    low: 49.89,\n    close: 49.9064,\n    volume: 33733,\n  },\n  {\n    date: 1462390020000,\n    open: 49.9075,\n    high: 49.92,\n    low: 49.906,\n    close: 49.915,\n    volume: 29228,\n  },\n  {\n    date: 1462390080000,\n    open: 49.9185,\n    high: 49.9185,\n    low: 49.88,\n    close: 49.885,\n    volume: 32653,\n  },\n  {\n    date: 1462390140000,\n    open: 49.8899,\n    high: 49.8899,\n    low: 49.86,\n    close: 49.86,\n    volume: 42848,\n  },\n  {\n    date: 1462390200000,\n    open: 49.86,\n    high: 49.88,\n    low: 49.86,\n    close: 49.87,\n    volume: 40494,\n  },\n  {\n    date: 1462390260000,\n    open: 49.87,\n    high: 49.895,\n    low: 49.865,\n    close: 49.865,\n    volume: 57012,\n  },\n  {\n    date: 1462390320000,\n    open: 49.8699,\n    high: 49.8799,\n    low: 49.86,\n    close: 49.86,\n    volume: 39338,\n  },\n  {\n    date: 1462390380000,\n    open: 49.8664,\n    high: 49.88,\n    low: 49.86,\n    close: 49.88,\n    volume: 52845,\n  },\n  {\n    date: 1462390440000,\n    open: 49.88,\n    high: 49.89,\n    low: 49.855,\n    close: 49.86,\n    volume: 67746,\n  },\n  {\n    date: 1462390500000,\n    open: 49.86,\n    high: 49.88,\n    low: 49.86,\n    close: 49.87,\n    volume: 42669,\n  },\n  {\n    date: 1462390560000,\n    open: 49.865,\n    high: 49.91,\n    low: 49.8601,\n    close: 49.9,\n    volume: 82016,\n  },\n  {\n    date: 1462390620000,\n    open: 49.89,\n    high: 49.89,\n    low: 49.87,\n    close: 49.87,\n    volume: 41939,\n  },\n  {\n    date: 1462390680000,\n    open: 49.87,\n    high: 49.88,\n    low: 49.85,\n    close: 49.86,\n    volume: 75763,\n  },\n  {\n    date: 1462390740000,\n    open: 49.86,\n    high: 49.875,\n    low: 49.85,\n    close: 49.87,\n    volume: 29703,\n  },\n  {\n    date: 1462390800000,\n    open: 49.87,\n    high: 49.8899,\n    low: 49.861,\n    close: 49.874,\n    volume: 62583,\n  },\n  {\n    date: 1462390860000,\n    open: 49.87,\n    high: 49.89,\n    low: 49.87,\n    close: 49.89,\n    volume: 37206,\n  },\n  {\n    date: 1462390920000,\n    open: 49.895,\n    high: 49.957,\n    low: 49.891,\n    close: 49.94,\n    volume: 162093,\n  },\n  {\n    date: 1462390980000,\n    open: 49.94,\n    high: 49.9499,\n    low: 49.9,\n    close: 49.92,\n    volume: 75116,\n  },\n  {\n    date: 1462391040000,\n    open: 49.925,\n    high: 49.93,\n    low: 49.89,\n    close: 49.895,\n    volume: 76899,\n  },\n  {\n    date: 1462391100000,\n    open: 49.89,\n    high: 49.91,\n    low: 49.89,\n    close: 49.905,\n    volume: 46129,\n  },\n  {\n    date: 1462391160000,\n    open: 49.91,\n    high: 49.94,\n    low: 49.9,\n    close: 49.9165,\n    volume: 107999,\n  },\n  {\n    date: 1462391220000,\n    open: 49.92,\n    high: 49.975,\n    low: 49.92,\n    close: 49.95,\n    volume: 114380,\n  },\n  {\n    date: 1462391280000,\n    open: 49.955,\n    high: 49.98,\n    low: 49.95,\n    close: 49.97,\n    volume: 73290,\n  },\n  {\n    date: 1462391340000,\n    open: 49.97,\n    high: 50.01,\n    low: 49.97,\n    close: 50.005,\n    volume: 86611,\n  },\n  {\n    date: 1462391400000,\n    open: 50.01,\n    high: 50.01,\n    low: 49.97,\n    close: 49.97,\n    volume: 57579,\n  },\n  {\n    date: 1462391460000,\n    open: 49.965,\n    high: 49.97,\n    low: 49.94,\n    close: 49.95,\n    volume: 74638,\n  },\n  {\n    date: 1462391520000,\n    open: 49.95,\n    high: 49.97,\n    low: 49.93,\n    close: 49.935,\n    volume: 91139,\n  },\n  {\n    date: 1462391580000,\n    open: 49.93,\n    high: 49.95,\n    low: 49.93,\n    close: 49.94,\n    volume: 51523,\n  },\n  {\n    date: 1462391640000,\n    open: 49.95,\n    high: 49.98,\n    low: 49.945,\n    close: 49.955,\n    volume: 88233,\n  },\n  {\n    date: 1462391700000,\n    open: 49.955,\n    high: 49.96,\n    low: 49.94,\n    close: 49.9401,\n    volume: 55301,\n  },\n  {\n    date: 1462391760000,\n    open: 49.94,\n    high: 49.94,\n    low: 49.9,\n    close: 49.935,\n    volume: 162451,\n  },\n  {\n    date: 1462391820000,\n    open: 49.935,\n    high: 49.94,\n    low: 49.92,\n    close: 49.94,\n    volume: 122575,\n  },\n  {\n    date: 1462391880000,\n    open: 49.9325,\n    high: 49.96,\n    low: 49.915,\n    close: 49.915,\n    volume: 169135,\n  },\n  {\n    date: 1462391940000,\n    open: 49.91,\n    high: 49.915,\n    low: 49.88,\n    close: 49.9,\n    volume: 166066,\n  },\n  {\n    date: 1462392000000,\n    open: 49.905,\n    high: 49.9068,\n    low: 49.86,\n    close: 49.87,\n    volume: 3168745,\n  },\n  {\n    date: 1462455000000,\n    open: 49.87,\n    high: 49.89,\n    low: 49.87,\n    close: 49.88,\n    volume: 393136,\n  },\n  {\n    date: 1462455060000,\n    open: 49.89,\n    high: 49.9585,\n    low: 49.74,\n    close: 49.75,\n    volume: 157040,\n  },\n  {\n    date: 1462455120000,\n    open: 49.76,\n    high: 49.875,\n    low: 49.76,\n    close: 49.85,\n    volume: 131622,\n  },\n  {\n    date: 1462455180000,\n    open: 49.85,\n    high: 49.875,\n    low: 49.79,\n    close: 49.82,\n    volume: 113400,\n  },\n  {\n    date: 1462455240000,\n    open: 49.825,\n    high: 49.92,\n    low: 49.82,\n    close: 49.85,\n    volume: 69014,\n  },\n  {\n    date: 1462455300000,\n    open: 49.8599,\n    high: 49.91,\n    low: 49.83,\n    close: 49.9075,\n    volume: 121545,\n  },\n  {\n    date: 1462455360000,\n    open: 49.9,\n    high: 49.915,\n    low: 49.85,\n    close: 49.9,\n    volume: 82198,\n  },\n  {\n    date: 1462455420000,\n    open: 49.9,\n    high: 49.9,\n    low: 49.85,\n    close: 49.89,\n    volume: 148275,\n  },\n  {\n    date: 1462455480000,\n    open: 49.89,\n    high: 49.95,\n    low: 49.89,\n    close: 49.94,\n    volume: 120703,\n  },\n  {\n    date: 1462455540000,\n    open: 49.94,\n    high: 49.965,\n    low: 49.93,\n    close: 49.94,\n    volume: 55292,\n  },\n  {\n    date: 1462455600000,\n    open: 49.94,\n    high: 49.96,\n    low: 49.9301,\n    close: 49.955,\n    volume: 73422,\n  },\n  {\n    date: 1462455660000,\n    open: 49.95,\n    high: 49.97,\n    low: 49.91,\n    close: 49.9599,\n    volume: 83169,\n  },\n  {\n    date: 1462455720000,\n    open: 49.96,\n    high: 49.97,\n    low: 49.89,\n    close: 49.92,\n    volume: 64027,\n  },\n  {\n    date: 1462455780000,\n    open: 49.92,\n    high: 50,\n    low: 49.92,\n    close: 49.9875,\n    volume: 95210,\n  },\n  {\n    date: 1462455840000,\n    open: 49.99,\n    high: 50.05,\n    low: 49.95,\n    close: 50.01,\n    volume: 235434,\n  },\n  {\n    date: 1462455900000,\n    open: 50.01,\n    high: 50.0201,\n    low: 49.985,\n    close: 50.01,\n    volume: 35881,\n  },\n  {\n    date: 1462455960000,\n    open: 50.015,\n    high: 50.02,\n    low: 49.95,\n    close: 49.96,\n    volume: 125305,\n  },\n  {\n    date: 1462456020000,\n    open: 49.96,\n    high: 49.9799,\n    low: 49.92,\n    close: 49.9301,\n    volume: 45219,\n  },\n  {\n    date: 1462456080000,\n    open: 49.93,\n    high: 49.95,\n    low: 49.91,\n    close: 49.94,\n    volume: 80793,\n  },\n  {\n    date: 1462456140000,\n    open: 49.94,\n    high: 49.99,\n    low: 49.94,\n    close: 49.955,\n    volume: 72081,\n  },\n  {\n    date: 1462456200000,\n    open: 49.96,\n    high: 49.99,\n    low: 49.94,\n    close: 49.985,\n    volume: 27961,\n  },\n  {\n    date: 1462456260000,\n    open: 49.9834,\n    high: 49.9834,\n    low: 49.94,\n    close: 49.96,\n    volume: 49732,\n  },\n  {\n    date: 1462456320000,\n    open: 49.96,\n    high: 49.96,\n    low: 49.89,\n    close: 49.92,\n    volume: 48716,\n  },\n  {\n    date: 1462456380000,\n    open: 49.92,\n    high: 49.95,\n    low: 49.905,\n    close: 49.93,\n    volume: 33774,\n  },\n  {\n    date: 1462456440000,\n    open: 49.92,\n    high: 49.945,\n    low: 49.91,\n    close: 49.93,\n    volume: 31017,\n  },\n  {\n    date: 1462456500000,\n    open: 49.93,\n    high: 49.98,\n    low: 49.93,\n    close: 49.955,\n    volume: 36861,\n  },\n  {\n    date: 1462456560000,\n    open: 49.95,\n    high: 49.96,\n    low: 49.89,\n    close: 49.89,\n    volume: 53847,\n  },\n  {\n    date: 1462456620000,\n    open: 49.88,\n    high: 49.8858,\n    low: 49.85,\n    close: 49.86,\n    volume: 58825,\n  },\n  {\n    date: 1462456680000,\n    open: 49.87,\n    high: 49.87,\n    low: 49.76,\n    close: 49.76,\n    volume: 68164,\n  },\n  {\n    date: 1462456740000,\n    open: 49.76,\n    high: 49.79,\n    low: 49.73,\n    close: 49.77,\n    volume: 61066,\n  },\n  {\n    date: 1462456800000,\n    open: 49.77,\n    high: 49.79,\n    low: 49.75,\n    close: 49.75,\n    volume: 68015,\n  },\n  {\n    date: 1462456860000,\n    open: 49.748,\n    high: 49.78,\n    low: 49.748,\n    close: 49.78,\n    volume: 39768,\n  },\n  {\n    date: 1462456920000,\n    open: 49.7745,\n    high: 49.79,\n    low: 49.765,\n    close: 49.77,\n    volume: 36114,\n  },\n  {\n    date: 1462456980000,\n    open: 49.77,\n    high: 49.84,\n    low: 49.77,\n    close: 49.82,\n    volume: 81943,\n  },\n  {\n    date: 1462457040000,\n    open: 49.83,\n    high: 49.8603,\n    low: 49.81,\n    close: 49.845,\n    volume: 36359,\n  },\n  {\n    date: 1462457100000,\n    open: 49.84,\n    high: 49.9,\n    low: 49.82,\n    close: 49.89,\n    volume: 32860,\n  },\n  {\n    date: 1462457160000,\n    open: 49.89,\n    high: 49.93,\n    low: 49.88,\n    close: 49.91,\n    volume: 37875,\n  },\n  {\n    date: 1462457220000,\n    open: 49.919,\n    high: 49.93,\n    low: 49.91,\n    close: 49.92,\n    volume: 32386,\n  },\n  {\n    date: 1462457280000,\n    open: 49.92,\n    high: 49.92,\n    low: 49.87,\n    close: 49.88,\n    volume: 36847,\n  },\n  {\n    date: 1462457340000,\n    open: 49.889,\n    high: 49.9,\n    low: 49.881,\n    close: 49.9,\n    volume: 28542,\n  },\n  {\n    date: 1462457400000,\n    open: 49.895,\n    high: 49.93,\n    low: 49.89,\n    close: 49.9099,\n    volume: 43903,\n  },\n  {\n    date: 1462457460000,\n    open: 49.91,\n    high: 49.9355,\n    low: 49.909,\n    close: 49.935,\n    volume: 29826,\n  },\n  {\n    date: 1462457520000,\n    open: 49.93,\n    high: 49.9599,\n    low: 49.92,\n    close: 49.925,\n    volume: 152601,\n  },\n  {\n    date: 1462457580000,\n    open: 49.925,\n    high: 50.0101,\n    low: 49.92,\n    close: 50.0101,\n    volume: 94363,\n  },\n  {\n    date: 1462457640000,\n    open: 50.015,\n    high: 50.02,\n    low: 49.96,\n    close: 49.97,\n    volume: 47029,\n  },\n  {\n    date: 1462457700000,\n    open: 49.97,\n    high: 50,\n    low: 49.96,\n    close: 50,\n    volume: 30149,\n  },\n  {\n    date: 1462457760000,\n    open: 50,\n    high: 50,\n    low: 49.95,\n    close: 49.97,\n    volume: 59535,\n  },\n  {\n    date: 1462457820000,\n    open: 49.97,\n    high: 50,\n    low: 49.945,\n    close: 50,\n    volume: 110827,\n  },\n  {\n    date: 1462457880000,\n    open: 50,\n    high: 50.0276,\n    low: 49.99,\n    close: 50,\n    volume: 52295,\n  },\n  {\n    date: 1462457940000,\n    open: 49.99,\n    high: 50.02,\n    low: 49.99,\n    close: 50.015,\n    volume: 61867,\n  },\n  {\n    date: 1462458000000,\n    open: 50.015,\n    high: 50.02,\n    low: 49.99,\n    close: 50,\n    volume: 58383,\n  },\n  {\n    date: 1462458060000,\n    open: 50.01,\n    high: 50.01,\n    low: 49.96,\n    close: 49.97,\n    volume: 82030,\n  },\n  {\n    date: 1462458120000,\n    open: 49.965,\n    high: 49.98,\n    low: 49.96,\n    close: 49.9666,\n    volume: 44088,\n  },\n  {\n    date: 1462458180000,\n    open: 49.96,\n    high: 49.98,\n    low: 49.9167,\n    close: 49.98,\n    volume: 81482,\n  },\n  {\n    date: 1462458240000,\n    open: 49.98,\n    high: 50,\n    low: 49.97,\n    close: 49.9942,\n    volume: 61199,\n  },\n  {\n    date: 1462458300000,\n    open: 49.995,\n    high: 50.01,\n    low: 49.99,\n    close: 49.9999,\n    volume: 69572,\n  },\n  {\n    date: 1462458360000,\n    open: 49.99,\n    high: 50.01,\n    low: 49.98,\n    close: 50,\n    volume: 66375,\n  },\n  {\n    date: 1462458420000,\n    open: 50,\n    high: 50.02,\n    low: 49.99,\n    close: 50,\n    volume: 89685,\n  },\n  {\n    date: 1462458480000,\n    open: 50.005,\n    high: 50.005,\n    low: 49.9,\n    close: 49.9,\n    volume: 107838,\n  },\n  {\n    date: 1462458540000,\n    open: 49.905,\n    high: 49.915,\n    low: 49.87,\n    close: 49.87,\n    volume: 53263,\n  },\n  {\n    date: 1462458600000,\n    open: 49.87,\n    high: 49.905,\n    low: 49.85,\n    close: 49.9,\n    volume: 95315,\n  },\n  {\n    date: 1462458660000,\n    open: 49.9,\n    high: 49.94,\n    low: 49.9,\n    close: 49.925,\n    volume: 73766,\n  },\n  {\n    date: 1462458720000,\n    open: 49.93,\n    high: 49.99,\n    low: 49.93,\n    close: 49.96,\n    volume: 89208,\n  },\n  {\n    date: 1462458780000,\n    open: 49.96,\n    high: 50,\n    low: 49.95,\n    close: 49.99,\n    volume: 90200,\n  },\n  {\n    date: 1462458840000,\n    open: 49.99,\n    high: 49.995,\n    low: 49.9599,\n    close: 49.99,\n    volume: 51680,\n  },\n  {\n    date: 1462458900000,\n    open: 49.98,\n    high: 50.03,\n    low: 49.98,\n    close: 50.03,\n    volume: 159166,\n  },\n  {\n    date: 1462458960000,\n    open: 50.03,\n    high: 50.03,\n    low: 50.01,\n    close: 50.025,\n    volume: 102093,\n  },\n  {\n    date: 1462459020000,\n    open: 50.025,\n    high: 50.03,\n    low: 50,\n    close: 50.02,\n    volume: 56415,\n  },\n  {\n    date: 1462459080000,\n    open: 50.02,\n    high: 50.02,\n    low: 49.955,\n    close: 49.9838,\n    volume: 46333,\n  },\n  {\n    date: 1462459140000,\n    open: 49.9899,\n    high: 49.9899,\n    low: 49.96,\n    close: 49.965,\n    volume: 16392,\n  },\n  {\n    date: 1462459200000,\n    open: 49.96,\n    high: 49.9701,\n    low: 49.94,\n    close: 49.955,\n    volume: 50921,\n  },\n  {\n    date: 1462459260000,\n    open: 49.96,\n    high: 49.9786,\n    low: 49.92,\n    close: 49.925,\n    volume: 84180,\n  },\n  {\n    date: 1462459320000,\n    open: 49.915,\n    high: 49.945,\n    low: 49.91,\n    close: 49.945,\n    volume: 58112,\n  },\n  {\n    date: 1462459380000,\n    open: 49.945,\n    high: 49.99,\n    low: 49.945,\n    close: 49.99,\n    volume: 45467,\n  },\n  {\n    date: 1462459440000,\n    open: 49.9899,\n    high: 49.9899,\n    low: 49.96,\n    close: 49.961,\n    volume: 26997,\n  },\n  {\n    date: 1462459500000,\n    open: 49.965,\n    high: 50.0262,\n    low: 49.96,\n    close: 50.015,\n    volume: 62847,\n  },\n  {\n    date: 1462459560000,\n    open: 50.015,\n    high: 50.02,\n    low: 49.995,\n    close: 50.0066,\n    volume: 39367,\n  },\n  {\n    date: 1462459620000,\n    open: 50.01,\n    high: 50.04,\n    low: 50.01,\n    close: 50.02,\n    volume: 39814,\n  },\n  {\n    date: 1462459680000,\n    open: 50.0235,\n    high: 50.0399,\n    low: 50.015,\n    close: 50.03,\n    volume: 37410,\n  },\n  {\n    date: 1462459740000,\n    open: 50.0355,\n    high: 50.08,\n    low: 50.03,\n    close: 50.04,\n    volume: 126551,\n  },\n  {\n    date: 1462459800000,\n    open: 50.045,\n    high: 50.08,\n    low: 50.04,\n    close: 50.0662,\n    volume: 63011,\n  },\n  {\n    date: 1462459860000,\n    open: 50.06,\n    high: 50.07,\n    low: 50.06,\n    close: 50.063,\n    volume: 20232,\n  },\n  {\n    date: 1462459920000,\n    open: 50.06,\n    high: 50.08,\n    low: 50.06,\n    close: 50.07,\n    volume: 55566,\n  },\n  {\n    date: 1462459980000,\n    open: 50.075,\n    high: 50.0764,\n    low: 50.03,\n    close: 50.0333,\n    volume: 34345,\n  },\n  {\n    date: 1462460040000,\n    open: 50.03,\n    high: 50.05,\n    low: 50.01,\n    close: 50.045,\n    volume: 35222,\n  },\n  {\n    date: 1462460100000,\n    open: 50.05,\n    high: 50.06,\n    low: 50.04,\n    close: 50.05,\n    volume: 23765,\n  },\n  {\n    date: 1462460160000,\n    open: 50.05,\n    high: 50.0555,\n    low: 50.0372,\n    close: 50.0372,\n    volume: 20014,\n  },\n  {\n    date: 1462460220000,\n    open: 50.0399,\n    high: 50.06,\n    low: 50.02,\n    close: 50.045,\n    volume: 26355,\n  },\n  {\n    date: 1462460280000,\n    open: 50.045,\n    high: 50.06,\n    low: 50.04,\n    close: 50.045,\n    volume: 22574,\n  },\n  {\n    date: 1462460340000,\n    open: 50.045,\n    high: 50.09,\n    low: 50.045,\n    close: 50.085,\n    volume: 62563,\n  },\n  {\n    date: 1462460400000,\n    open: 50.0899,\n    high: 50.09,\n    low: 50.07,\n    close: 50.09,\n    volume: 24788,\n  },\n  {\n    date: 1462460460000,\n    open: 50.09,\n    high: 50.13,\n    low: 50.08,\n    close: 50.13,\n    volume: 95401,\n  },\n  {\n    date: 1462460520000,\n    open: 50.125,\n    high: 50.13,\n    low: 50.055,\n    close: 50.095,\n    volume: 60101,\n  },\n  {\n    date: 1462460580000,\n    open: 50.085,\n    high: 50.14,\n    low: 50.085,\n    close: 50.1,\n    volume: 47501,\n  },\n  {\n    date: 1462460640000,\n    open: 50.1,\n    high: 50.1,\n    low: 50.08,\n    close: 50.09,\n    volume: 20880,\n  },\n  {\n    date: 1462460700000,\n    open: 50.085,\n    high: 50.12,\n    low: 50.06,\n    close: 50.1101,\n    volume: 102085,\n  },\n  {\n    date: 1462460760000,\n    open: 50.11,\n    high: 50.13,\n    low: 50.1,\n    close: 50.125,\n    volume: 32148,\n  },\n  {\n    date: 1462460820000,\n    open: 50.12,\n    high: 50.13,\n    low: 50.11,\n    close: 50.11,\n    volume: 55801,\n  },\n  {\n    date: 1462460880000,\n    open: 50.1,\n    high: 50.12,\n    low: 50.09,\n    close: 50.11,\n    volume: 55534,\n  },\n  {\n    date: 1462460940000,\n    open: 50.11,\n    high: 50.13,\n    low: 50.07,\n    close: 50.07,\n    volume: 69029,\n  },\n  {\n    date: 1462461000000,\n    open: 50.08,\n    high: 50.115,\n    low: 50.075,\n    close: 50.11,\n    volume: 55827,\n  },\n  {\n    date: 1462461060000,\n    open: 50.105,\n    high: 50.12,\n    low: 50.1,\n    close: 50.1,\n    volume: 50183,\n  },\n  {\n    date: 1462461120000,\n    open: 50.095,\n    high: 50.1,\n    low: 50.08,\n    close: 50.1,\n    volume: 33017,\n  },\n  {\n    date: 1462461180000,\n    open: 50.101,\n    high: 50.13,\n    low: 50.1,\n    close: 50.115,\n    volume: 29770,\n  },\n  {\n    date: 1462461240000,\n    open: 50.1135,\n    high: 50.13,\n    low: 50.1,\n    close: 50.1,\n    volume: 19684,\n  },\n  {\n    date: 1462461300000,\n    open: 50.1,\n    high: 50.11,\n    low: 50.09,\n    close: 50.095,\n    volume: 34033,\n  },\n  {\n    date: 1462461360000,\n    open: 50.095,\n    high: 50.11,\n    low: 50.09,\n    close: 50.105,\n    volume: 38819,\n  },\n  {\n    date: 1462461420000,\n    open: 50.1068,\n    high: 50.11,\n    low: 50.09,\n    close: 50.1035,\n    volume: 40601,\n  },\n  {\n    date: 1462461480000,\n    open: 50.1072,\n    high: 50.13,\n    low: 50.1,\n    close: 50.13,\n    volume: 39639,\n  },\n  {\n    date: 1462461540000,\n    open: 50.12,\n    high: 50.18,\n    low: 50.12,\n    close: 50.165,\n    volume: 74790,\n  },\n  {\n    date: 1462461600000,\n    open: 50.165,\n    high: 50.175,\n    low: 50.16,\n    close: 50.165,\n    volume: 57345,\n  },\n  {\n    date: 1462461660000,\n    open: 50.16,\n    high: 50.18,\n    low: 50.15,\n    close: 50.15,\n    volume: 48719,\n  },\n  {\n    date: 1462461720000,\n    open: 50.1599,\n    high: 50.19,\n    low: 50.15,\n    close: 50.15,\n    volume: 62787,\n  },\n  {\n    date: 1462461780000,\n    open: 50.14,\n    high: 50.146,\n    low: 50.085,\n    close: 50.106,\n    volume: 108716,\n  },\n  {\n    date: 1462461840000,\n    open: 50.1,\n    high: 50.11,\n    low: 50.07,\n    close: 50.07,\n    volume: 71202,\n  },\n  {\n    date: 1462461900000,\n    open: 50.07,\n    high: 50.09,\n    low: 50.06,\n    close: 50.06,\n    volume: 55134,\n  },\n  {\n    date: 1462461960000,\n    open: 50.06,\n    high: 50.12,\n    low: 50.05,\n    close: 50.115,\n    volume: 43462,\n  },\n  {\n    date: 1462462020000,\n    open: 50.11,\n    high: 50.115,\n    low: 50.09,\n    close: 50.1,\n    volume: 35749,\n  },\n  {\n    date: 1462462080000,\n    open: 50.1,\n    high: 50.125,\n    low: 50.095,\n    close: 50.115,\n    volume: 26517,\n  },\n  {\n    date: 1462462140000,\n    open: 50.115,\n    high: 50.145,\n    low: 50.11,\n    close: 50.12,\n    volume: 39098,\n  },\n  {\n    date: 1462462200000,\n    open: 50.12,\n    high: 50.125,\n    low: 50.11,\n    close: 50.115,\n    volume: 21771,\n  },\n  {\n    date: 1462462260000,\n    open: 50.119,\n    high: 50.15,\n    low: 50.11,\n    close: 50.147,\n    volume: 25822,\n  },\n  {\n    date: 1462462320000,\n    open: 50.1497,\n    high: 50.17,\n    low: 50.14,\n    close: 50.1699,\n    volume: 13973,\n  },\n  {\n    date: 1462462380000,\n    open: 50.16,\n    high: 50.1658,\n    low: 50.15,\n    close: 50.16,\n    volume: 27106,\n  },\n  {\n    date: 1462462440000,\n    open: 50.16,\n    high: 50.165,\n    low: 50.15,\n    close: 50.15,\n    volume: 28268,\n  },\n  {\n    date: 1462462500000,\n    open: 50.155,\n    high: 50.18,\n    low: 50.13,\n    close: 50.18,\n    volume: 31204,\n  },\n  {\n    date: 1462462560000,\n    open: 50.19,\n    high: 50.24,\n    low: 50.19,\n    close: 50.23,\n    volume: 63069,\n  },\n  {\n    date: 1462462620000,\n    open: 50.2255,\n    high: 50.25,\n    low: 50.22,\n    close: 50.2301,\n    volume: 22060,\n  },\n  {\n    date: 1462462680000,\n    open: 50.23,\n    high: 50.24,\n    low: 50.22,\n    close: 50.23,\n    volume: 24735,\n  },\n  {\n    date: 1462462740000,\n    open: 50.235,\n    high: 50.235,\n    low: 50.195,\n    close: 50.21,\n    volume: 31589,\n  },\n  {\n    date: 1462462800000,\n    open: 50.2199,\n    high: 50.25,\n    low: 50.2,\n    close: 50.25,\n    volume: 64324,\n  },\n  {\n    date: 1462462860000,\n    open: 50.25,\n    high: 50.255,\n    low: 50.231,\n    close: 50.231,\n    volume: 23069,\n  },\n  {\n    date: 1462462920000,\n    open: 50.235,\n    high: 50.25,\n    low: 50.23,\n    close: 50.25,\n    volume: 50825,\n  },\n  {\n    date: 1462462980000,\n    open: 50.249,\n    high: 50.27,\n    low: 50.225,\n    close: 50.23,\n    volume: 68397,\n  },\n  {\n    date: 1462463040000,\n    open: 50.23,\n    high: 50.275,\n    low: 50.23,\n    close: 50.25,\n    volume: 53368,\n  },\n  {\n    date: 1462463100000,\n    open: 50.26,\n    high: 50.285,\n    low: 50.26,\n    close: 50.285,\n    volume: 34036,\n  },\n  {\n    date: 1462463160000,\n    open: 50.2899,\n    high: 50.29,\n    low: 50.26,\n    close: 50.28,\n    volume: 26734,\n  },\n  {\n    date: 1462463220000,\n    open: 50.29,\n    high: 50.3,\n    low: 50.265,\n    close: 50.2731,\n    volume: 38338,\n  },\n  {\n    date: 1462463280000,\n    open: 50.28,\n    high: 50.29,\n    low: 50.26,\n    close: 50.285,\n    volume: 42211,\n  },\n  {\n    date: 1462463340000,\n    open: 50.28,\n    high: 50.29,\n    low: 50.245,\n    close: 50.2501,\n    volume: 47675,\n  },\n  {\n    date: 1462463400000,\n    open: 50.25,\n    high: 50.26,\n    low: 50.235,\n    close: 50.255,\n    volume: 39578,\n  },\n  {\n    date: 1462463460000,\n    open: 50.25,\n    high: 50.26,\n    low: 50.24,\n    close: 50.255,\n    volume: 13347,\n  },\n  {\n    date: 1462463520000,\n    open: 50.255,\n    high: 50.26,\n    low: 50.24,\n    close: 50.245,\n    volume: 21086,\n  },\n  {\n    date: 1462463580000,\n    open: 50.24,\n    high: 50.249,\n    low: 50.22,\n    close: 50.23,\n    volume: 33384,\n  },\n  {\n    date: 1462463640000,\n    open: 50.22,\n    high: 50.2499,\n    low: 50.22,\n    close: 50.2499,\n    volume: 22645,\n  },\n  {\n    date: 1462463700000,\n    open: 50.25,\n    high: 50.25,\n    low: 50.21,\n    close: 50.215,\n    volume: 39953,\n  },\n  {\n    date: 1462463760000,\n    open: 50.215,\n    high: 50.22,\n    low: 50.2,\n    close: 50.2,\n    volume: 22979,\n  },\n  {\n    date: 1462463820000,\n    open: 50.2,\n    high: 50.225,\n    low: 50.2,\n    close: 50.22,\n    volume: 60966,\n  },\n  {\n    date: 1462463880000,\n    open: 50.225,\n    high: 50.225,\n    low: 50.185,\n    close: 50.185,\n    volume: 34127,\n  },\n  {\n    date: 1462463940000,\n    open: 50.185,\n    high: 50.195,\n    low: 50.17,\n    close: 50.17,\n    volume: 51087,\n  },\n  {\n    date: 1462464000000,\n    open: 50.172,\n    high: 50.18,\n    low: 50.15,\n    close: 50.15,\n    volume: 48437,\n  },\n  {\n    date: 1462464060000,\n    open: 50.15,\n    high: 50.16,\n    low: 50.14,\n    close: 50.145,\n    volume: 42228,\n  },\n  {\n    date: 1462464120000,\n    open: 50.14,\n    high: 50.15,\n    low: 50.12,\n    close: 50.12,\n    volume: 21056,\n  },\n  {\n    date: 1462464180000,\n    open: 50.12,\n    high: 50.1269,\n    low: 50.11,\n    close: 50.115,\n    volume: 21521,\n  },\n  {\n    date: 1462464240000,\n    open: 50.12,\n    high: 50.13,\n    low: 50.11,\n    close: 50.1169,\n    volume: 37630,\n  },\n  {\n    date: 1462464300000,\n    open: 50.1161,\n    high: 50.12,\n    low: 50.1,\n    close: 50.1,\n    volume: 31983,\n  },\n  {\n    date: 1462464360000,\n    open: 50.1,\n    high: 50.105,\n    low: 50.08,\n    close: 50.105,\n    volume: 62509,\n  },\n  {\n    date: 1462464420000,\n    open: 50.105,\n    high: 50.115,\n    low: 50.1,\n    close: 50.115,\n    volume: 43806,\n  },\n  {\n    date: 1462464480000,\n    open: 50.11,\n    high: 50.12,\n    low: 50.1,\n    close: 50.11,\n    volume: 33881,\n  },\n  {\n    date: 1462464540000,\n    open: 50.11,\n    high: 50.115,\n    low: 50.09,\n    close: 50.095,\n    volume: 9531,\n  },\n  {\n    date: 1462464600000,\n    open: 50.0998,\n    high: 50.105,\n    low: 50.05,\n    close: 50.0664,\n    volume: 50790,\n  },\n  {\n    date: 1462464660000,\n    open: 50.0635,\n    high: 50.1,\n    low: 50.0635,\n    close: 50.085,\n    volume: 27525,\n  },\n  {\n    date: 1462464720000,\n    open: 50.09,\n    high: 50.09,\n    low: 50.05,\n    close: 50.07,\n    volume: 30045,\n  },\n  {\n    date: 1462464780000,\n    open: 50.07,\n    high: 50.095,\n    low: 50.07,\n    close: 50.09,\n    volume: 22683,\n  },\n  {\n    date: 1462464840000,\n    open: 50.0801,\n    high: 50.1,\n    low: 50.08,\n    close: 50.095,\n    volume: 31833,\n  },\n  {\n    date: 1462464900000,\n    open: 50.09,\n    high: 50.11,\n    low: 50.08,\n    close: 50.1,\n    volume: 19375,\n  },\n  {\n    date: 1462464960000,\n    open: 50.1,\n    high: 50.11,\n    low: 50.085,\n    close: 50.085,\n    volume: 22642,\n  },\n  {\n    date: 1462465020000,\n    open: 50.085,\n    high: 50.11,\n    low: 50.0801,\n    close: 50.105,\n    volume: 25183,\n  },\n  {\n    date: 1462465080000,\n    open: 50.11,\n    high: 50.11,\n    low: 50.1,\n    close: 50.11,\n    volume: 35278,\n  },\n  {\n    date: 1462465140000,\n    open: 50.11,\n    high: 50.11,\n    low: 50.05,\n    close: 50.0661,\n    volume: 31279,\n  },\n  {\n    date: 1462465200000,\n    open: 50.07,\n    high: 50.09,\n    low: 50.0664,\n    close: 50.08,\n    volume: 16244,\n  },\n  {\n    date: 1462465260000,\n    open: 50.08,\n    high: 50.085,\n    low: 50.05,\n    close: 50.075,\n    volume: 33439,\n  },\n  {\n    date: 1462465320000,\n    open: 50.08,\n    high: 50.08,\n    low: 50.05,\n    close: 50.055,\n    volume: 24223,\n  },\n  {\n    date: 1462465380000,\n    open: 50.0599,\n    high: 50.065,\n    low: 50.02,\n    close: 50.04,\n    volume: 66373,\n  },\n  {\n    date: 1462465440000,\n    open: 50.035,\n    high: 50.05,\n    low: 50.02,\n    close: 50.04,\n    volume: 30239,\n  },\n  {\n    date: 1462465500000,\n    open: 50.045,\n    high: 50.055,\n    low: 50.035,\n    close: 50.05,\n    volume: 22275,\n  },\n  {\n    date: 1462465560000,\n    open: 50.05,\n    high: 50.055,\n    low: 50.02,\n    close: 50.03,\n    volume: 22722,\n  },\n  {\n    date: 1462465620000,\n    open: 50.04,\n    high: 50.07,\n    low: 50.04,\n    close: 50.06,\n    volume: 16488,\n  },\n  {\n    date: 1462465680000,\n    open: 50.055,\n    high: 50.0569,\n    low: 50.035,\n    close: 50.035,\n    volume: 15591,\n  },\n  {\n    date: 1462465740000,\n    open: 50.03,\n    high: 50.0572,\n    low: 50.015,\n    close: 50.0501,\n    volume: 19413,\n  },\n  {\n    date: 1462465800000,\n    open: 50.06,\n    high: 50.08,\n    low: 50.06,\n    close: 50.06,\n    volume: 13250,\n  },\n  {\n    date: 1462465860000,\n    open: 50.05,\n    high: 50.06,\n    low: 50.04,\n    close: 50.045,\n    volume: 32014,\n  },\n  {\n    date: 1462465920000,\n    open: 50.04,\n    high: 50.045,\n    low: 50,\n    close: 50,\n    volume: 80234,\n  },\n  {\n    date: 1462465980000,\n    open: 50,\n    high: 50.005,\n    low: 49.985,\n    close: 50,\n    volume: 46610,\n  },\n  {\n    date: 1462466040000,\n    open: 50,\n    high: 50.03,\n    low: 50,\n    close: 50.015,\n    volume: 27377,\n  },\n  {\n    date: 1462466100000,\n    open: 50.015,\n    high: 50.03,\n    low: 50.0132,\n    close: 50.015,\n    volume: 27104,\n  },\n  {\n    date: 1462466160000,\n    open: 50.015,\n    high: 50.019,\n    low: 49.99,\n    close: 49.995,\n    volume: 24248,\n  },\n  {\n    date: 1462466220000,\n    open: 49.995,\n    high: 50.015,\n    low: 49.99,\n    close: 50.01,\n    volume: 67528,\n  },\n  {\n    date: 1462466280000,\n    open: 50.015,\n    high: 50.025,\n    low: 50,\n    close: 50,\n    volume: 26555,\n  },\n  {\n    date: 1462466340000,\n    open: 50.0011,\n    high: 50.0171,\n    low: 49.99,\n    close: 49.99,\n    volume: 18294,\n  },\n  {\n    date: 1462466400000,\n    open: 49.995,\n    high: 50,\n    low: 49.99,\n    close: 49.995,\n    volume: 7142,\n  },\n  {\n    date: 1462466460000,\n    open: 49.995,\n    high: 50.03,\n    low: 49.9938,\n    close: 50.025,\n    volume: 35182,\n  },\n  {\n    date: 1462466520000,\n    open: 50.025,\n    high: 50.025,\n    low: 50.01,\n    close: 50.015,\n    volume: 10385,\n  },\n  {\n    date: 1462466580000,\n    open: 50.015,\n    high: 50.025,\n    low: 50,\n    close: 50.015,\n    volume: 28564,\n  },\n  {\n    date: 1462466640000,\n    open: 50.015,\n    high: 50.029,\n    low: 50.005,\n    close: 50.005,\n    volume: 32536,\n  },\n  {\n    date: 1462466700000,\n    open: 50.005,\n    high: 50.04,\n    low: 50,\n    close: 50.03,\n    volume: 27389,\n  },\n  {\n    date: 1462466760000,\n    open: 50.0298,\n    high: 50.0298,\n    low: 49.985,\n    close: 49.995,\n    volume: 37977,\n  },\n  {\n    date: 1462466820000,\n    open: 50,\n    high: 50.05,\n    low: 49.9966,\n    close: 50.04,\n    volume: 28981,\n  },\n  {\n    date: 1462466880000,\n    open: 50.04,\n    high: 50.065,\n    low: 50.035,\n    close: 50.06,\n    volume: 25376,\n  },\n  {\n    date: 1462466940000,\n    open: 50.06,\n    high: 50.07,\n    low: 50.0505,\n    close: 50.055,\n    volume: 16226,\n  },\n  {\n    date: 1462467000000,\n    open: 50.055,\n    high: 50.08,\n    low: 50.055,\n    close: 50.07,\n    volume: 17930,\n  },\n  {\n    date: 1462467060000,\n    open: 50.07,\n    high: 50.075,\n    low: 50.06,\n    close: 50.06,\n    volume: 7244,\n  },\n  {\n    date: 1462467120000,\n    open: 50.07,\n    high: 50.08,\n    low: 50.0601,\n    close: 50.07,\n    volume: 30485,\n  },\n  {\n    date: 1462467180000,\n    open: 50.06,\n    high: 50.08,\n    low: 50.06,\n    close: 50.07,\n    volume: 17709,\n  },\n  {\n    date: 1462467240000,\n    open: 50.0663,\n    high: 50.079,\n    low: 50.06,\n    close: 50.07,\n    volume: 16643,\n  },\n  {\n    date: 1462467300000,\n    open: 50.06,\n    high: 50.09,\n    low: 50.06,\n    close: 50.075,\n    volume: 41826,\n  },\n  {\n    date: 1462467360000,\n    open: 50.08,\n    high: 50.0855,\n    low: 50.065,\n    close: 50.065,\n    volume: 27236,\n  },\n  {\n    date: 1462467420000,\n    open: 50.065,\n    high: 50.08,\n    low: 50.05,\n    close: 50.08,\n    volume: 30092,\n  },\n  {\n    date: 1462467480000,\n    open: 50.075,\n    high: 50.08,\n    low: 50.035,\n    close: 50.045,\n    volume: 28410,\n  },\n  {\n    date: 1462467540000,\n    open: 50.045,\n    high: 50.06,\n    low: 50.04,\n    close: 50.045,\n    volume: 18489,\n  },\n  {\n    date: 1462467600000,\n    open: 50.045,\n    high: 50.06,\n    low: 50.025,\n    close: 50.025,\n    volume: 18633,\n  },\n  {\n    date: 1462467660000,\n    open: 50.03,\n    high: 50.05,\n    low: 50.02,\n    close: 50.036,\n    volume: 24167,\n  },\n  {\n    date: 1462467720000,\n    open: 50.03,\n    high: 50.04,\n    low: 50.01,\n    close: 50.03,\n    volume: 21309,\n  },\n  {\n    date: 1462467780000,\n    open: 50.02,\n    high: 50.03,\n    low: 50,\n    close: 50.005,\n    volume: 22310,\n  },\n  {\n    date: 1462467840000,\n    open: 50,\n    high: 50.03,\n    low: 50,\n    close: 50.02,\n    volume: 18975,\n  },\n  {\n    date: 1462467900000,\n    open: 50.025,\n    high: 50.04,\n    low: 50,\n    close: 50,\n    volume: 16994,\n  },\n  {\n    date: 1462467960000,\n    open: 50,\n    high: 50.02,\n    low: 50,\n    close: 50.02,\n    volume: 34045,\n  },\n  {\n    date: 1462468020000,\n    open: 50.03,\n    high: 50.03,\n    low: 50,\n    close: 50,\n    volume: 16766,\n  },\n  {\n    date: 1462468080000,\n    open: 50,\n    high: 50.01,\n    low: 50,\n    close: 50,\n    volume: 17991,\n  },\n  {\n    date: 1462468140000,\n    open: 50,\n    high: 50.015,\n    low: 50,\n    close: 50,\n    volume: 10964,\n  },\n  {\n    date: 1462468200000,\n    open: 50,\n    high: 50.01,\n    low: 49.98,\n    close: 49.985,\n    volume: 39639,\n  },\n  {\n    date: 1462468260000,\n    open: 49.98,\n    high: 50.02,\n    low: 49.97,\n    close: 50,\n    volume: 87836,\n  },\n  {\n    date: 1462468320000,\n    open: 49.99,\n    high: 50.01,\n    low: 49.98,\n    close: 50.01,\n    volume: 50978,\n  },\n  {\n    date: 1462468380000,\n    open: 50,\n    high: 50.015,\n    low: 49.985,\n    close: 50,\n    volume: 24457,\n  },\n  {\n    date: 1462468440000,\n    open: 50,\n    high: 50.015,\n    low: 49.98,\n    close: 49.99,\n    volume: 52051,\n  },\n  {\n    date: 1462468500000,\n    open: 49.99,\n    high: 50,\n    low: 49.965,\n    close: 50,\n    volume: 73848,\n  },\n  {\n    date: 1462468560000,\n    open: 49.99,\n    high: 49.99,\n    low: 49.96,\n    close: 49.975,\n    volume: 110369,\n  },\n  {\n    date: 1462468620000,\n    open: 49.97,\n    high: 49.9765,\n    low: 49.96,\n    close: 49.965,\n    volume: 85298,\n  },\n  {\n    date: 1462468680000,\n    open: 49.966,\n    high: 49.98,\n    low: 49.965,\n    close: 49.9799,\n    volume: 8644,\n  },\n  {\n    date: 1462468740000,\n    open: 49.98,\n    high: 49.985,\n    low: 49.935,\n    close: 49.9439,\n    volume: 45638,\n  },\n  {\n    date: 1462468800000,\n    open: 49.94,\n    high: 49.965,\n    low: 49.9342,\n    close: 49.965,\n    volume: 21418,\n  },\n  {\n    date: 1462468860000,\n    open: 49.96,\n    high: 49.97,\n    low: 49.92,\n    close: 49.93,\n    volume: 24117,\n  },\n  {\n    date: 1462468920000,\n    open: 49.92,\n    high: 49.94,\n    low: 49.91,\n    close: 49.916,\n    volume: 59261,\n  },\n  {\n    date: 1462468980000,\n    open: 49.9162,\n    high: 49.945,\n    low: 49.9162,\n    close: 49.935,\n    volume: 52757,\n  },\n  {\n    date: 1462469040000,\n    open: 49.93,\n    high: 49.93,\n    low: 49.88,\n    close: 49.91,\n    volume: 74830,\n  },\n  {\n    date: 1462469100000,\n    open: 49.915,\n    high: 49.9199,\n    low: 49.87,\n    close: 49.87,\n    volume: 56586,\n  },\n  {\n    date: 1462469160000,\n    open: 49.8637,\n    high: 49.887,\n    low: 49.855,\n    close: 49.887,\n    volume: 35263,\n  },\n  {\n    date: 1462469220000,\n    open: 49.8837,\n    high: 49.91,\n    low: 49.88,\n    close: 49.91,\n    volume: 31995,\n  },\n  {\n    date: 1462469280000,\n    open: 49.91,\n    high: 49.92,\n    low: 49.89,\n    close: 49.915,\n    volume: 46214,\n  },\n  {\n    date: 1462469340000,\n    open: 49.9136,\n    high: 49.915,\n    low: 49.88,\n    close: 49.9061,\n    volume: 51293,\n  },\n  {\n    date: 1462469400000,\n    open: 49.905,\n    high: 49.92,\n    low: 49.905,\n    close: 49.915,\n    volume: 3463,\n  },\n  {\n    date: 1462469460000,\n    open: 49.915,\n    high: 49.93,\n    low: 49.89,\n    close: 49.92,\n    volume: 54836,\n  },\n  {\n    date: 1462469520000,\n    open: 49.925,\n    high: 49.9399,\n    low: 49.905,\n    close: 49.9399,\n    volume: 60193,\n  },\n  {\n    date: 1462469580000,\n    open: 49.935,\n    high: 49.94,\n    low: 49.9205,\n    close: 49.9264,\n    volume: 24129,\n  },\n  {\n    date: 1462469640000,\n    open: 49.92,\n    high: 49.93,\n    low: 49.89,\n    close: 49.8929,\n    volume: 33930,\n  },\n  {\n    date: 1462469700000,\n    open: 49.8917,\n    high: 49.9,\n    low: 49.88,\n    close: 49.89,\n    volume: 19155,\n  },\n  {\n    date: 1462469760000,\n    open: 49.885,\n    high: 49.91,\n    low: 49.88,\n    close: 49.9,\n    volume: 67748,\n  },\n  {\n    date: 1462469820000,\n    open: 49.9074,\n    high: 49.9074,\n    low: 49.88,\n    close: 49.89,\n    volume: 50390,\n  },\n  {\n    date: 1462469880000,\n    open: 49.89,\n    high: 49.91,\n    low: 49.88,\n    close: 49.8877,\n    volume: 42100,\n  },\n  {\n    date: 1462469940000,\n    open: 49.8808,\n    high: 49.925,\n    low: 49.875,\n    close: 49.92,\n    volume: 43778,\n  },\n  {\n    date: 1462470000000,\n    open: 49.925,\n    high: 49.925,\n    low: 49.9,\n    close: 49.905,\n    volume: 32718,\n  },\n  {\n    date: 1462470060000,\n    open: 49.9099,\n    high: 49.93,\n    low: 49.9,\n    close: 49.91,\n    volume: 19348,\n  },\n  {\n    date: 1462470120000,\n    open: 49.905,\n    high: 49.93,\n    low: 49.9,\n    close: 49.92,\n    volume: 25795,\n  },\n  {\n    date: 1462470180000,\n    open: 49.92,\n    high: 49.93,\n    low: 49.91,\n    close: 49.9234,\n    volume: 13265,\n  },\n  {\n    date: 1462470240000,\n    open: 49.925,\n    high: 49.93,\n    low: 49.91,\n    close: 49.9129,\n    volume: 29496,\n  },\n  {\n    date: 1462470300000,\n    open: 49.91,\n    high: 49.925,\n    low: 49.905,\n    close: 49.9172,\n    volume: 34511,\n  },\n  {\n    date: 1462470360000,\n    open: 49.9101,\n    high: 49.9376,\n    low: 49.91,\n    close: 49.925,\n    volume: 25601,\n  },\n  {\n    date: 1462470420000,\n    open: 49.925,\n    high: 49.943,\n    low: 49.915,\n    close: 49.943,\n    volume: 20163,\n  },\n  {\n    date: 1462470480000,\n    open: 49.94,\n    high: 49.9599,\n    low: 49.93,\n    close: 49.945,\n    volume: 50732,\n  },\n  {\n    date: 1462470540000,\n    open: 49.95,\n    high: 49.96,\n    low: 49.9199,\n    close: 49.92,\n    volume: 29108,\n  },\n  {\n    date: 1462470600000,\n    open: 49.92,\n    high: 49.9399,\n    low: 49.91,\n    close: 49.911,\n    volume: 20443,\n  },\n  {\n    date: 1462470660000,\n    open: 49.91,\n    high: 49.96,\n    low: 49.905,\n    close: 49.9599,\n    volume: 29111,\n  },\n  {\n    date: 1462470720000,\n    open: 49.95,\n    high: 49.955,\n    low: 49.92,\n    close: 49.925,\n    volume: 20041,\n  },\n  {\n    date: 1462470780000,\n    open: 49.925,\n    high: 49.94,\n    low: 49.92,\n    close: 49.94,\n    volume: 17765,\n  },\n  {\n    date: 1462470840000,\n    open: 49.95,\n    high: 49.97,\n    low: 49.945,\n    close: 49.97,\n    volume: 30900,\n  },\n  {\n    date: 1462470900000,\n    open: 49.9665,\n    high: 49.97,\n    low: 49.92,\n    close: 49.92,\n    volume: 26696,\n  },\n  {\n    date: 1462470960000,\n    open: 49.91,\n    high: 49.915,\n    low: 49.875,\n    close: 49.9083,\n    volume: 37389,\n  },\n  {\n    date: 1462471020000,\n    open: 49.9099,\n    high: 49.93,\n    low: 49.88,\n    close: 49.9202,\n    volume: 73289,\n  },\n  {\n    date: 1462471080000,\n    open: 49.9261,\n    high: 49.94,\n    low: 49.9101,\n    close: 49.927,\n    volume: 31048,\n  },\n  {\n    date: 1462471140000,\n    open: 49.925,\n    high: 49.945,\n    low: 49.92,\n    close: 49.94,\n    volume: 33698,\n  },\n  {\n    date: 1462471200000,\n    open: 49.93,\n    high: 49.95,\n    low: 49.92,\n    close: 49.94,\n    volume: 39260,\n  },\n  {\n    date: 1462471260000,\n    open: 49.94,\n    high: 49.945,\n    low: 49.88,\n    close: 49.895,\n    volume: 53055,\n  },\n  {\n    date: 1462471320000,\n    open: 49.895,\n    high: 49.925,\n    low: 49.895,\n    close: 49.92,\n    volume: 17897,\n  },\n  {\n    date: 1462471380000,\n    open: 49.925,\n    high: 49.96,\n    low: 49.91,\n    close: 49.935,\n    volume: 32021,\n  },\n  {\n    date: 1462471440000,\n    open: 49.93,\n    high: 49.9799,\n    low: 49.92,\n    close: 49.96,\n    volume: 27249,\n  },\n  {\n    date: 1462471500000,\n    open: 49.96,\n    high: 49.975,\n    low: 49.95,\n    close: 49.97,\n    volume: 36322,\n  },\n  {\n    date: 1462471560000,\n    open: 49.97,\n    high: 49.98,\n    low: 49.951,\n    close: 49.97,\n    volume: 57495,\n  },\n  {\n    date: 1462471620000,\n    open: 49.975,\n    high: 49.99,\n    low: 49.97,\n    close: 49.99,\n    volume: 34923,\n  },\n  {\n    date: 1462471680000,\n    open: 49.9899,\n    high: 49.9999,\n    low: 49.97,\n    close: 49.99,\n    volume: 43946,\n  },\n  {\n    date: 1462471740000,\n    open: 49.99,\n    high: 50.01,\n    low: 49.97,\n    close: 49.97,\n    volume: 54681,\n  },\n  {\n    date: 1462471800000,\n    open: 49.97,\n    high: 49.97,\n    low: 49.94,\n    close: 49.956,\n    volume: 29406,\n  },\n  {\n    date: 1462471860000,\n    open: 49.9501,\n    high: 49.995,\n    low: 49.95,\n    close: 49.97,\n    volume: 51153,\n  },\n  {\n    date: 1462471920000,\n    open: 49.96,\n    high: 49.97,\n    low: 49.94,\n    close: 49.94,\n    volume: 19180,\n  },\n  {\n    date: 1462471980000,\n    open: 49.94,\n    high: 49.9699,\n    low: 49.93,\n    close: 49.94,\n    volume: 38022,\n  },\n  {\n    date: 1462472040000,\n    open: 49.9472,\n    high: 49.97,\n    low: 49.94,\n    close: 49.96,\n    volume: 22125,\n  },\n  {\n    date: 1462472100000,\n    open: 49.965,\n    high: 49.99,\n    low: 49.96,\n    close: 49.99,\n    volume: 44108,\n  },\n  {\n    date: 1462472160000,\n    open: 49.99,\n    high: 50.01,\n    low: 49.9865,\n    close: 50,\n    volume: 49751,\n  },\n  {\n    date: 1462472220000,\n    open: 50.01,\n    high: 50.01,\n    low: 49.97,\n    close: 50,\n    volume: 36251,\n  },\n  {\n    date: 1462472280000,\n    open: 50,\n    high: 50.02,\n    low: 49.99,\n    close: 50.02,\n    volume: 54045,\n  },\n  {\n    date: 1462472340000,\n    open: 50.02,\n    high: 50.02,\n    low: 49.97,\n    close: 49.97,\n    volume: 32703,\n  },\n  {\n    date: 1462472400000,\n    open: 49.9737,\n    high: 49.98,\n    low: 49.94,\n    close: 49.955,\n    volume: 32578,\n  },\n  {\n    date: 1462472460000,\n    open: 49.9585,\n    high: 49.98,\n    low: 49.94,\n    close: 49.98,\n    volume: 24697,\n  },\n  {\n    date: 1462472520000,\n    open: 49.98,\n    high: 50.02,\n    low: 49.98,\n    close: 49.9992,\n    volume: 61681,\n  },\n  {\n    date: 1462472580000,\n    open: 49.995,\n    high: 50,\n    low: 49.97,\n    close: 49.9999,\n    volume: 32034,\n  },\n  {\n    date: 1462472640000,\n    open: 49.9901,\n    high: 50.02,\n    low: 49.99,\n    close: 50.01,\n    volume: 22780,\n  },\n  {\n    date: 1462472700000,\n    open: 50.015,\n    high: 50.04,\n    low: 50.01,\n    close: 50.015,\n    volume: 43826,\n  },\n  {\n    date: 1462472760000,\n    open: 50.0103,\n    high: 50.0103,\n    low: 49.985,\n    close: 49.985,\n    volume: 18970,\n  },\n  {\n    date: 1462472820000,\n    open: 49.985,\n    high: 50.03,\n    low: 49.985,\n    close: 50.03,\n    volume: 24816,\n  },\n  {\n    date: 1462472880000,\n    open: 50.03,\n    high: 50.03,\n    low: 50,\n    close: 50,\n    volume: 27526,\n  },\n  {\n    date: 1462472940000,\n    open: 50.005,\n    high: 50.005,\n    low: 49.99,\n    close: 49.995,\n    volume: 17206,\n  },\n  {\n    date: 1462473000000,\n    open: 49.99,\n    high: 49.9999,\n    low: 49.95,\n    close: 49.95,\n    volume: 35210,\n  },\n  {\n    date: 1462473060000,\n    open: 49.95,\n    high: 49.975,\n    low: 49.95,\n    close: 49.975,\n    volume: 35860,\n  },\n  {\n    date: 1462473120000,\n    open: 49.98,\n    high: 49.9899,\n    low: 49.95,\n    close: 49.96,\n    volume: 26402,\n  },\n  {\n    date: 1462473180000,\n    open: 49.955,\n    high: 49.97,\n    low: 49.94,\n    close: 49.94,\n    volume: 39815,\n  },\n  {\n    date: 1462473240000,\n    open: 49.94,\n    high: 49.965,\n    low: 49.93,\n    close: 49.965,\n    volume: 15643,\n  },\n  {\n    date: 1462473300000,\n    open: 49.96,\n    high: 49.9665,\n    low: 49.925,\n    close: 49.94,\n    volume: 27095,\n  },\n  {\n    date: 1462473360000,\n    open: 49.935,\n    high: 49.96,\n    low: 49.93,\n    close: 49.96,\n    volume: 29501,\n  },\n  {\n    date: 1462473420000,\n    open: 49.96,\n    high: 49.96,\n    low: 49.92,\n    close: 49.935,\n    volume: 46895,\n  },\n  {\n    date: 1462473480000,\n    open: 49.933,\n    high: 49.94,\n    low: 49.93,\n    close: 49.94,\n    volume: 17595,\n  },\n  {\n    date: 1462473540000,\n    open: 49.935,\n    high: 49.955,\n    low: 49.93,\n    close: 49.935,\n    volume: 27966,\n  },\n  {\n    date: 1462473600000,\n    open: 49.935,\n    high: 49.94,\n    low: 49.93,\n    close: 49.935,\n    volume: 16513,\n  },\n  {\n    date: 1462473660000,\n    open: 49.93,\n    high: 49.935,\n    low: 49.91,\n    close: 49.92,\n    volume: 29831,\n  },\n  {\n    date: 1462473720000,\n    open: 49.92,\n    high: 49.98,\n    low: 49.911,\n    close: 49.98,\n    volume: 55659,\n  },\n  {\n    date: 1462473780000,\n    open: 49.99,\n    high: 50,\n    low: 49.97,\n    close: 49.98,\n    volume: 26000,\n  },\n  {\n    date: 1462473840000,\n    open: 49.98,\n    high: 49.9899,\n    low: 49.955,\n    close: 49.965,\n    volume: 27301,\n  },\n  {\n    date: 1462473900000,\n    open: 49.965,\n    high: 50,\n    low: 49.965,\n    close: 49.985,\n    volume: 25956,\n  },\n  {\n    date: 1462473960000,\n    open: 49.99,\n    high: 50,\n    low: 49.98,\n    close: 49.985,\n    volume: 46587,\n  },\n  {\n    date: 1462474020000,\n    open: 49.98,\n    high: 49.985,\n    low: 49.975,\n    close: 49.985,\n    volume: 43631,\n  },\n  {\n    date: 1462474080000,\n    open: 49.985,\n    high: 50,\n    low: 49.94,\n    close: 49.94,\n    volume: 87771,\n  },\n  {\n    date: 1462474140000,\n    open: 49.94,\n    high: 49.98,\n    low: 49.93,\n    close: 49.9725,\n    volume: 37775,\n  },\n  {\n    date: 1462474200000,\n    open: 49.97,\n    high: 49.9799,\n    low: 49.955,\n    close: 49.955,\n    volume: 26501,\n  },\n  {\n    date: 1462474260000,\n    open: 49.951,\n    high: 49.99,\n    low: 49.95,\n    close: 49.98,\n    volume: 44545,\n  },\n  {\n    date: 1462474320000,\n    open: 49.97,\n    high: 49.985,\n    low: 49.965,\n    close: 49.97,\n    volume: 21491,\n  },\n  {\n    date: 1462474380000,\n    open: 49.97,\n    high: 49.98,\n    low: 49.96,\n    close: 49.98,\n    volume: 30452,\n  },\n  {\n    date: 1462474440000,\n    open: 49.985,\n    high: 50,\n    low: 49.98,\n    close: 49.98,\n    volume: 55905,\n  },\n  {\n    date: 1462474500000,\n    open: 49.98,\n    high: 49.9899,\n    low: 49.97,\n    close: 49.9763,\n    volume: 21515,\n  },\n  {\n    date: 1462474560000,\n    open: 49.975,\n    high: 50,\n    low: 49.96,\n    close: 50,\n    volume: 8939,\n  },\n  {\n    date: 1462474620000,\n    open: 49.99,\n    high: 49.995,\n    low: 49.95,\n    close: 49.97,\n    volume: 44398,\n  },\n  {\n    date: 1462474680000,\n    open: 49.965,\n    high: 49.99,\n    low: 49.96,\n    close: 49.98,\n    volume: 46251,\n  },\n  {\n    date: 1462474740000,\n    open: 49.98,\n    high: 50,\n    low: 49.98,\n    close: 49.985,\n    volume: 20558,\n  },\n  {\n    date: 1462474800000,\n    open: 49.9899,\n    high: 49.9899,\n    low: 49.91,\n    close: 49.92,\n    volume: 46870,\n  },\n  {\n    date: 1462474860000,\n    open: 49.92,\n    high: 49.94,\n    low: 49.92,\n    close: 49.925,\n    volume: 24828,\n  },\n  {\n    date: 1462474920000,\n    open: 49.9269,\n    high: 49.9471,\n    low: 49.9232,\n    close: 49.93,\n    volume: 43753,\n  },\n  {\n    date: 1462474980000,\n    open: 49.935,\n    high: 49.935,\n    low: 49.89,\n    close: 49.9,\n    volume: 77499,\n  },\n  {\n    date: 1462475040000,\n    open: 49.9,\n    high: 49.94,\n    low: 49.895,\n    close: 49.92,\n    volume: 74041,\n  },\n  {\n    date: 1462475100000,\n    open: 49.91,\n    high: 49.93,\n    low: 49.8936,\n    close: 49.92,\n    volume: 56506,\n  },\n  {\n    date: 1462475160000,\n    open: 49.92,\n    high: 49.9299,\n    low: 49.8818,\n    close: 49.8818,\n    volume: 43277,\n  },\n  {\n    date: 1462475220000,\n    open: 49.88,\n    high: 49.92,\n    low: 49.88,\n    close: 49.9025,\n    volume: 43328,\n  },\n  {\n    date: 1462475280000,\n    open: 49.9,\n    high: 49.91,\n    low: 49.88,\n    close: 49.9,\n    volume: 30554,\n  },\n  {\n    date: 1462475340000,\n    open: 49.8939,\n    high: 49.905,\n    low: 49.89,\n    close: 49.896,\n    volume: 21500,\n  },\n  {\n    date: 1462475400000,\n    open: 49.8968,\n    high: 49.9,\n    low: 49.8862,\n    close: 49.895,\n    volume: 41370,\n  },\n  {\n    date: 1462475460000,\n    open: 49.8999,\n    high: 49.905,\n    low: 49.88,\n    close: 49.905,\n    volume: 28194,\n  },\n  {\n    date: 1462475520000,\n    open: 49.91,\n    high: 49.915,\n    low: 49.8942,\n    close: 49.905,\n    volume: 38548,\n  },\n  {\n    date: 1462475580000,\n    open: 49.9,\n    high: 49.91,\n    low: 49.89,\n    close: 49.9033,\n    volume: 36448,\n  },\n  {\n    date: 1462475640000,\n    open: 49.91,\n    high: 49.94,\n    low: 49.895,\n    close: 49.9399,\n    volume: 58848,\n  },\n  {\n    date: 1462475700000,\n    open: 49.935,\n    high: 49.94,\n    low: 49.92,\n    close: 49.93,\n    volume: 29545,\n  },\n  {\n    date: 1462475760000,\n    open: 49.925,\n    high: 49.93,\n    low: 49.905,\n    close: 49.905,\n    volume: 29498,\n  },\n  {\n    date: 1462475820000,\n    open: 49.9,\n    high: 49.93,\n    low: 49.88,\n    close: 49.89,\n    volume: 72159,\n  },\n  {\n    date: 1462475880000,\n    open: 49.89,\n    high: 49.9,\n    low: 49.88,\n    close: 49.885,\n    volume: 23605,\n  },\n  {\n    date: 1462475940000,\n    open: 49.885,\n    high: 49.89,\n    low: 49.86,\n    close: 49.89,\n    volume: 42034,\n  },\n  {\n    date: 1462476000000,\n    open: 49.885,\n    high: 49.94,\n    low: 49.885,\n    close: 49.9147,\n    volume: 56209,\n  },\n  {\n    date: 1462476060000,\n    open: 49.915,\n    high: 49.9372,\n    low: 49.91,\n    close: 49.93,\n    volume: 22822,\n  },\n  {\n    date: 1462476120000,\n    open: 49.9353,\n    high: 49.957,\n    low: 49.91,\n    close: 49.957,\n    volume: 83767,\n  },\n  {\n    date: 1462476180000,\n    open: 49.955,\n    high: 49.96,\n    low: 49.94,\n    close: 49.95,\n    volume: 53826,\n  },\n  {\n    date: 1462476240000,\n    open: 49.95,\n    high: 49.95,\n    low: 49.93,\n    close: 49.94,\n    volume: 25636,\n  },\n  {\n    date: 1462476300000,\n    open: 49.945,\n    high: 49.96,\n    low: 49.935,\n    close: 49.95,\n    volume: 67131,\n  },\n  {\n    date: 1462476360000,\n    open: 49.955,\n    high: 49.98,\n    low: 49.93,\n    close: 49.94,\n    volume: 49833,\n  },\n  {\n    date: 1462476420000,\n    open: 49.94,\n    high: 49.945,\n    low: 49.9031,\n    close: 49.925,\n    volume: 45079,\n  },\n  {\n    date: 1462476480000,\n    open: 49.92,\n    high: 49.93,\n    low: 49.91,\n    close: 49.9224,\n    volume: 12525,\n  },\n  {\n    date: 1462476540000,\n    open: 49.93,\n    high: 49.94,\n    low: 49.92,\n    close: 49.94,\n    volume: 50152,\n  },\n  {\n    date: 1462476600000,\n    open: 49.9364,\n    high: 49.96,\n    low: 49.925,\n    close: 49.942,\n    volume: 62184,\n  },\n  {\n    date: 1462476660000,\n    open: 49.9437,\n    high: 49.95,\n    low: 49.93,\n    close: 49.95,\n    volume: 64137,\n  },\n  {\n    date: 1462476720000,\n    open: 49.95,\n    high: 49.95,\n    low: 49.91,\n    close: 49.92,\n    volume: 18577,\n  },\n  {\n    date: 1462476780000,\n    open: 49.92,\n    high: 49.95,\n    low: 49.915,\n    close: 49.9499,\n    volume: 53769,\n  },\n  {\n    date: 1462476840000,\n    open: 49.949,\n    high: 49.95,\n    low: 49.91,\n    close: 49.92,\n    volume: 40091,\n  },\n  {\n    date: 1462476900000,\n    open: 49.9231,\n    high: 49.95,\n    low: 49.92,\n    close: 49.95,\n    volume: 27972,\n  },\n  {\n    date: 1462476960000,\n    open: 49.95,\n    high: 49.95,\n    low: 49.9035,\n    close: 49.91,\n    volume: 55850,\n  },\n  {\n    date: 1462477020000,\n    open: 49.9099,\n    high: 49.92,\n    low: 49.89,\n    close: 49.9101,\n    volume: 60694,\n  },\n  {\n    date: 1462477080000,\n    open: 49.91,\n    high: 49.915,\n    low: 49.9,\n    close: 49.91,\n    volume: 33355,\n  },\n  {\n    date: 1462477140000,\n    open: 49.915,\n    high: 49.92,\n    low: 49.87,\n    close: 49.876,\n    volume: 61734,\n  },\n  {\n    date: 1462477200000,\n    open: 49.87,\n    high: 49.92,\n    low: 49.86,\n    close: 49.915,\n    volume: 69492,\n  },\n  {\n    date: 1462477260000,\n    open: 49.91,\n    high: 49.935,\n    low: 49.9,\n    close: 49.91,\n    volume: 72806,\n  },\n  {\n    date: 1462477320000,\n    open: 49.91,\n    high: 49.94,\n    low: 49.895,\n    close: 49.935,\n    volume: 83105,\n  },\n  {\n    date: 1462477380000,\n    open: 49.935,\n    high: 49.94,\n    low: 49.91,\n    close: 49.93,\n    volume: 54369,\n  },\n  {\n    date: 1462477440000,\n    open: 49.93,\n    high: 49.94,\n    low: 49.915,\n    close: 49.92,\n    volume: 32745,\n  },\n  {\n    date: 1462477500000,\n    open: 49.925,\n    high: 49.95,\n    low: 49.9,\n    close: 49.93,\n    volume: 100215,\n  },\n  {\n    date: 1462477560000,\n    open: 49.93,\n    high: 49.98,\n    low: 49.93,\n    close: 49.94,\n    volume: 114474,\n  },\n  {\n    date: 1462477620000,\n    open: 49.94,\n    high: 49.99,\n    low: 49.93,\n    close: 49.985,\n    volume: 75025,\n  },\n  {\n    date: 1462477680000,\n    open: 49.985,\n    high: 49.99,\n    low: 49.97,\n    close: 49.975,\n    volume: 86967,\n  },\n  {\n    date: 1462477740000,\n    open: 49.97,\n    high: 49.99,\n    low: 49.93,\n    close: 49.93,\n    volume: 99224,\n  },\n  {\n    date: 1462477800000,\n    open: 49.93,\n    high: 49.96,\n    low: 49.92,\n    close: 49.94,\n    volume: 122633,\n  },\n  {\n    date: 1462477860000,\n    open: 49.94,\n    high: 49.9599,\n    low: 49.92,\n    close: 49.93,\n    volume: 93720,\n  },\n  {\n    date: 1462477920000,\n    open: 49.925,\n    high: 49.93,\n    low: 49.89,\n    close: 49.89,\n    volume: 160662,\n  },\n  {\n    date: 1462477980000,\n    open: 49.9,\n    high: 49.905,\n    low: 49.85,\n    close: 49.865,\n    volume: 418984,\n  },\n  {\n    date: 1462478040000,\n    open: 49.87,\n    high: 49.88,\n    low: 49.835,\n    close: 49.8525,\n    volume: 301979,\n  },\n  {\n    date: 1462478100000,\n    open: 49.85,\n    high: 49.87,\n    low: 49.84,\n    close: 49.861,\n    volume: 123008,\n  },\n  {\n    date: 1462478160000,\n    open: 49.865,\n    high: 49.865,\n    low: 49.815,\n    close: 49.84,\n    volume: 445600,\n  },\n  {\n    date: 1462478220000,\n    open: 49.84,\n    high: 49.87,\n    low: 49.84,\n    close: 49.87,\n    volume: 173961,\n  },\n  {\n    date: 1462478280000,\n    open: 49.87,\n    high: 49.88,\n    low: 49.86,\n    close: 49.87,\n    volume: 252921,\n  },\n  {\n    date: 1462478340000,\n    open: 49.87,\n    high: 49.9,\n    low: 49.87,\n    close: 49.875,\n    volume: 347217,\n  },\n  {\n    date: 1462478400000,\n    open: 49.875,\n    high: 49.95,\n    low: 49.875,\n    close: 49.94,\n    volume: 3056017,\n  },\n  {\n    date: 1462541400000,\n    open: 49.92,\n    high: 49.92,\n    low: 49.75,\n    close: 49.78,\n    volume: 522036,\n  },\n  {\n    date: 1462541460000,\n    open: 49.78,\n    high: 49.905,\n    low: 49.75,\n    close: 49.78,\n    volume: 90888,\n  },\n  {\n    date: 1462541520000,\n    open: 49.78,\n    high: 49.84,\n    low: 49.78,\n    close: 49.79,\n    volume: 101044,\n  },\n  {\n    date: 1462541580000,\n    open: 49.807,\n    high: 49.86,\n    low: 49.79,\n    close: 49.8,\n    volume: 38545,\n  },\n  {\n    date: 1462541640000,\n    open: 49.8,\n    high: 49.83,\n    low: 49.78,\n    close: 49.82,\n    volume: 66423,\n  },\n  {\n    date: 1462541700000,\n    open: 49.82,\n    high: 49.82,\n    low: 49.78,\n    close: 49.79,\n    volume: 66245,\n  },\n  {\n    date: 1462541760000,\n    open: 49.785,\n    high: 49.825,\n    low: 49.7767,\n    close: 49.7767,\n    volume: 70788,\n  },\n  {\n    date: 1462541820000,\n    open: 49.78,\n    high: 49.82,\n    low: 49.78,\n    close: 49.81,\n    volume: 107874,\n  },\n  {\n    date: 1462541880000,\n    open: 49.8,\n    high: 49.81,\n    low: 49.75,\n    close: 49.78,\n    volume: 236650,\n  },\n  {\n    date: 1462541940000,\n    open: 49.785,\n    high: 49.9,\n    low: 49.77,\n    close: 49.89,\n    volume: 96856,\n  },\n  {\n    date: 1462542000000,\n    open: 49.88,\n    high: 49.94,\n    low: 49.86,\n    close: 49.94,\n    volume: 264785,\n  },\n  {\n    date: 1462542060000,\n    open: 49.94,\n    high: 49.9499,\n    low: 49.88,\n    close: 49.89,\n    volume: 52583,\n  },\n  {\n    date: 1462542120000,\n    open: 49.89,\n    high: 49.92,\n    low: 49.87,\n    close: 49.91,\n    volume: 83239,\n  },\n  {\n    date: 1462542180000,\n    open: 49.91,\n    high: 50,\n    low: 49.91,\n    close: 49.97,\n    volume: 122473,\n  },\n  {\n    date: 1462542240000,\n    open: 49.965,\n    high: 49.99,\n    low: 49.94,\n    close: 49.97,\n    volume: 67448,\n  },\n  {\n    date: 1462542300000,\n    open: 49.97,\n    high: 49.985,\n    low: 49.9,\n    close: 49.93,\n    volume: 122265,\n  },\n  {\n    date: 1462542360000,\n    open: 49.93,\n    high: 49.94,\n    low: 49.9,\n    close: 49.9,\n    volume: 62915,\n  },\n  {\n    date: 1462542420000,\n    open: 49.9,\n    high: 49.91,\n    low: 49.8636,\n    close: 49.89,\n    volume: 58806,\n  },\n  {\n    date: 1462542480000,\n    open: 49.88,\n    high: 49.93,\n    low: 49.88,\n    close: 49.895,\n    volume: 46884,\n  },\n  {\n    date: 1462542540000,\n    open: 49.9,\n    high: 49.91,\n    low: 49.87,\n    close: 49.87,\n    volume: 63904,\n  },\n  {\n    date: 1462542600000,\n    open: 49.87,\n    high: 49.895,\n    low: 49.85,\n    close: 49.85,\n    volume: 57226,\n  },\n  {\n    date: 1462542660000,\n    open: 49.85,\n    high: 49.865,\n    low: 49.82,\n    close: 49.865,\n    volume: 152425,\n  },\n  {\n    date: 1462542720000,\n    open: 49.86,\n    high: 49.875,\n    low: 49.83,\n    close: 49.8556,\n    volume: 80598,\n  },\n  {\n    date: 1462542780000,\n    open: 49.86,\n    high: 49.88,\n    low: 49.85,\n    close: 49.88,\n    volume: 103419,\n  },\n  {\n    date: 1462542840000,\n    open: 49.88,\n    high: 49.895,\n    low: 49.86,\n    close: 49.86,\n    volume: 48795,\n  },\n  {\n    date: 1462542900000,\n    open: 49.87,\n    high: 49.89,\n    low: 49.845,\n    close: 49.8535,\n    volume: 68800,\n  },\n  {\n    date: 1462542960000,\n    open: 49.86,\n    high: 49.87,\n    low: 49.85,\n    close: 49.85,\n    volume: 88757,\n  },\n  {\n    date: 1462543020000,\n    open: 49.85,\n    high: 49.88,\n    low: 49.85,\n    close: 49.85,\n    volume: 103618,\n  },\n  {\n    date: 1462543080000,\n    open: 49.85,\n    high: 49.87,\n    low: 49.82,\n    close: 49.86,\n    volume: 71400,\n  },\n  {\n    date: 1462543140000,\n    open: 49.86,\n    high: 49.86,\n    low: 49.85,\n    close: 49.85,\n    volume: 41950,\n  },\n  {\n    date: 1462543200000,\n    open: 49.85,\n    high: 49.88,\n    low: 49.85,\n    close: 49.875,\n    volume: 69527,\n  },\n  {\n    date: 1462543260000,\n    open: 49.885,\n    high: 49.8855,\n    low: 49.86,\n    close: 49.87,\n    volume: 37384,\n  },\n  {\n    date: 1462543320000,\n    open: 49.8659,\n    high: 49.87,\n    low: 49.85,\n    close: 49.85,\n    volume: 44143,\n  },\n  {\n    date: 1462543380000,\n    open: 49.855,\n    high: 49.88,\n    low: 49.85,\n    close: 49.88,\n    volume: 57116,\n  },\n  {\n    date: 1462543440000,\n    open: 49.875,\n    high: 49.9,\n    low: 49.87,\n    close: 49.9,\n    volume: 34178,\n  },\n  {\n    date: 1462543500000,\n    open: 49.9036,\n    high: 49.9036,\n    low: 49.88,\n    close: 49.885,\n    volume: 15054,\n  },\n  {\n    date: 1462543560000,\n    open: 49.89,\n    high: 49.9,\n    low: 49.85,\n    close: 49.865,\n    volume: 56335,\n  },\n  {\n    date: 1462543620000,\n    open: 49.865,\n    high: 49.93,\n    low: 49.855,\n    close: 49.93,\n    volume: 48905,\n  },\n  {\n    date: 1462543680000,\n    open: 49.93,\n    high: 49.955,\n    low: 49.93,\n    close: 49.935,\n    volume: 63140,\n  },\n  {\n    date: 1462543740000,\n    open: 49.94,\n    high: 49.945,\n    low: 49.92,\n    close: 49.945,\n    volume: 28526,\n  },\n  {\n    date: 1462543800000,\n    open: 49.95,\n    high: 49.95,\n    low: 49.92,\n    close: 49.92,\n    volume: 29963,\n  },\n  {\n    date: 1462543860000,\n    open: 49.9299,\n    high: 49.93,\n    low: 49.89,\n    close: 49.905,\n    volume: 37089,\n  },\n  {\n    date: 1462543920000,\n    open: 49.9,\n    high: 49.9099,\n    low: 49.85,\n    close: 49.85,\n    volume: 40795,\n  },\n  {\n    date: 1462543980000,\n    open: 49.85,\n    high: 49.895,\n    low: 49.85,\n    close: 49.8791,\n    volume: 56498,\n  },\n  {\n    date: 1462544040000,\n    open: 49.87,\n    high: 49.9,\n    low: 49.87,\n    close: 49.875,\n    volume: 53558,\n  },\n  {\n    date: 1462544100000,\n    open: 49.88,\n    high: 49.9,\n    low: 49.86,\n    close: 49.86,\n    volume: 41300,\n  },\n  {\n    date: 1462544160000,\n    open: 49.865,\n    high: 49.8865,\n    low: 49.85,\n    close: 49.86,\n    volume: 49114,\n  },\n  {\n    date: 1462544220000,\n    open: 49.8601,\n    high: 49.88,\n    low: 49.84,\n    close: 49.87,\n    volume: 110809,\n  },\n  {\n    date: 1462544280000,\n    open: 49.87,\n    high: 49.88,\n    low: 49.845,\n    close: 49.855,\n    volume: 72195,\n  },\n  {\n    date: 1462544340000,\n    open: 49.855,\n    high: 49.87,\n    low: 49.85,\n    close: 49.86,\n    volume: 79105,\n  },\n  {\n    date: 1462544400000,\n    open: 49.855,\n    high: 49.8699,\n    low: 49.83,\n    close: 49.855,\n    volume: 84091,\n  },\n  {\n    date: 1462544460000,\n    open: 49.855,\n    high: 49.86,\n    low: 49.84,\n    close: 49.8475,\n    volume: 100367,\n  },\n  {\n    date: 1462544520000,\n    open: 49.8499,\n    high: 49.86,\n    low: 49.84,\n    close: 49.85,\n    volume: 52167,\n  },\n  {\n    date: 1462544580000,\n    open: 49.85,\n    high: 49.86,\n    low: 49.84,\n    close: 49.86,\n    volume: 34464,\n  },\n  {\n    date: 1462544640000,\n    open: 49.86,\n    high: 49.87,\n    low: 49.85,\n    close: 49.865,\n    volume: 108877,\n  },\n  {\n    date: 1462544700000,\n    open: 49.8538,\n    high: 49.86,\n    low: 49.79,\n    close: 49.8,\n    volume: 153917,\n  },\n  {\n    date: 1462544760000,\n    open: 49.795,\n    high: 49.82,\n    low: 49.76,\n    close: 49.82,\n    volume: 93044,\n  },\n  {\n    date: 1462544820000,\n    open: 49.8267,\n    high: 49.85,\n    low: 49.81,\n    close: 49.8199,\n    volume: 52422,\n  },\n  {\n    date: 1462544880000,\n    open: 49.815,\n    high: 49.83,\n    low: 49.795,\n    close: 49.83,\n    volume: 46235,\n  },\n  {\n    date: 1462544940000,\n    open: 49.83,\n    high: 49.85,\n    low: 49.82,\n    close: 49.85,\n    volume: 36974,\n  },\n  {\n    date: 1462545000000,\n    open: 49.85,\n    high: 49.89,\n    low: 49.84,\n    close: 49.86,\n    volume: 42784,\n  },\n  {\n    date: 1462545060000,\n    open: 49.85,\n    high: 49.86,\n    low: 49.82,\n    close: 49.82,\n    volume: 51960,\n  },\n  {\n    date: 1462545120000,\n    open: 49.825,\n    high: 49.84,\n    low: 49.82,\n    close: 49.839,\n    volume: 41120,\n  },\n  {\n    date: 1462545180000,\n    open: 49.835,\n    high: 49.91,\n    low: 49.83,\n    close: 49.9,\n    volume: 66238,\n  },\n  {\n    date: 1462545240000,\n    open: 49.8999,\n    high: 49.93,\n    low: 49.89,\n    close: 49.91,\n    volume: 56955,\n  },\n  {\n    date: 1462545300000,\n    open: 49.9199,\n    high: 49.9199,\n    low: 49.87,\n    close: 49.87,\n    volume: 30735,\n  },\n  {\n    date: 1462545360000,\n    open: 49.875,\n    high: 49.89,\n    low: 49.87,\n    close: 49.87,\n    volume: 48017,\n  },\n  {\n    date: 1462545420000,\n    open: 49.875,\n    high: 49.877,\n    low: 49.82,\n    close: 49.825,\n    volume: 47033,\n  },\n  {\n    date: 1462545480000,\n    open: 49.83,\n    high: 49.835,\n    low: 49.79,\n    close: 49.8,\n    volume: 121483,\n  },\n  {\n    date: 1462545540000,\n    open: 49.79,\n    high: 49.84,\n    low: 49.79,\n    close: 49.84,\n    volume: 52448,\n  },\n  {\n    date: 1462545600000,\n    open: 49.83,\n    high: 49.83,\n    low: 49.79,\n    close: 49.81,\n    volume: 55976,\n  },\n  {\n    date: 1462545660000,\n    open: 49.815,\n    high: 49.815,\n    low: 49.77,\n    close: 49.805,\n    volume: 118289,\n  },\n  {\n    date: 1462545720000,\n    open: 49.801,\n    high: 49.84,\n    low: 49.79,\n    close: 49.81,\n    volume: 55402,\n  },\n  {\n    date: 1462545780000,\n    open: 49.81,\n    high: 49.82,\n    low: 49.77,\n    close: 49.78,\n    volume: 48334,\n  },\n  {\n    date: 1462545840000,\n    open: 49.78,\n    high: 49.835,\n    low: 49.77,\n    close: 49.82,\n    volume: 80757,\n  },\n  {\n    date: 1462545900000,\n    open: 49.82,\n    high: 49.82,\n    low: 49.79,\n    close: 49.81,\n    volume: 41924,\n  },\n  {\n    date: 1462545960000,\n    open: 49.805,\n    high: 49.805,\n    low: 49.76,\n    close: 49.77,\n    volume: 133261,\n  },\n  {\n    date: 1462546020000,\n    open: 49.77,\n    high: 49.79,\n    low: 49.77,\n    close: 49.7885,\n    volume: 122427,\n  },\n  {\n    date: 1462546080000,\n    open: 49.79,\n    high: 49.8,\n    low: 49.76,\n    close: 49.775,\n    volume: 154400,\n  },\n  {\n    date: 1462546140000,\n    open: 49.78,\n    high: 49.79,\n    low: 49.77,\n    close: 49.775,\n    volume: 59542,\n  },\n  {\n    date: 1462546200000,\n    open: 49.78,\n    high: 49.78,\n    low: 49.75,\n    close: 49.75,\n    volume: 85127,\n  },\n  {\n    date: 1462546260000,\n    open: 49.755,\n    high: 49.79,\n    low: 49.75,\n    close: 49.775,\n    volume: 131504,\n  },\n  {\n    date: 1462546320000,\n    open: 49.77,\n    high: 49.7765,\n    low: 49.72,\n    close: 49.72,\n    volume: 89872,\n  },\n  {\n    date: 1462546380000,\n    open: 49.73,\n    high: 49.75,\n    low: 49.72,\n    close: 49.75,\n    volume: 71432,\n  },\n  {\n    date: 1462546440000,\n    open: 49.75,\n    high: 49.77,\n    low: 49.74,\n    close: 49.76,\n    volume: 63300,\n  },\n  {\n    date: 1462546500000,\n    open: 49.765,\n    high: 49.8,\n    low: 49.75,\n    close: 49.8,\n    volume: 104504,\n  },\n  {\n    date: 1462546560000,\n    open: 49.8,\n    high: 49.8185,\n    low: 49.79,\n    close: 49.8,\n    volume: 49211,\n  },\n  {\n    date: 1462546620000,\n    open: 49.8,\n    high: 49.805,\n    low: 49.77,\n    close: 49.7765,\n    volume: 33806,\n  },\n  {\n    date: 1462546680000,\n    open: 49.78,\n    high: 49.78,\n    low: 49.74,\n    close: 49.75,\n    volume: 56203,\n  },\n  {\n    date: 1462546740000,\n    open: 49.75,\n    high: 49.8,\n    low: 49.74,\n    close: 49.8,\n    volume: 59653,\n  },\n  {\n    date: 1462546800000,\n    open: 49.81,\n    high: 49.81,\n    low: 49.77,\n    close: 49.77,\n    volume: 37110,\n  },\n  {\n    date: 1462546860000,\n    open: 49.77,\n    high: 49.795,\n    low: 49.76,\n    close: 49.78,\n    volume: 53764,\n  },\n  {\n    date: 1462546920000,\n    open: 49.78,\n    high: 49.805,\n    low: 49.775,\n    close: 49.7899,\n    volume: 37470,\n  },\n  {\n    date: 1462546980000,\n    open: 49.79,\n    high: 49.79,\n    low: 49.75,\n    close: 49.76,\n    volume: 34264,\n  },\n  {\n    date: 1462547040000,\n    open: 49.75,\n    high: 49.755,\n    low: 49.7136,\n    close: 49.715,\n    volume: 31618,\n  },\n  {\n    date: 1462547100000,\n    open: 49.72,\n    high: 49.73,\n    low: 49.66,\n    close: 49.665,\n    volume: 108084,\n  },\n  {\n    date: 1462547160000,\n    open: 49.6699,\n    high: 49.68,\n    low: 49.66,\n    close: 49.675,\n    volume: 37309,\n  },\n  {\n    date: 1462547220000,\n    open: 49.675,\n    high: 49.68,\n    low: 49.66,\n    close: 49.68,\n    volume: 117384,\n  },\n  {\n    date: 1462547280000,\n    open: 49.68,\n    high: 49.7,\n    low: 49.68,\n    close: 49.699,\n    volume: 25792,\n  },\n  {\n    date: 1462547340000,\n    open: 49.69,\n    high: 49.72,\n    low: 49.69,\n    close: 49.705,\n    volume: 54188,\n  },\n  {\n    date: 1462547400000,\n    open: 49.7067,\n    high: 49.7067,\n    low: 49.67,\n    close: 49.68,\n    volume: 57546,\n  },\n  {\n    date: 1462547460000,\n    open: 49.675,\n    high: 49.75,\n    low: 49.675,\n    close: 49.75,\n    volume: 55844,\n  },\n  {\n    date: 1462547520000,\n    open: 49.75,\n    high: 49.785,\n    low: 49.73,\n    close: 49.77,\n    volume: 62730,\n  },\n  {\n    date: 1462547580000,\n    open: 49.77,\n    high: 49.78,\n    low: 49.75,\n    close: 49.7599,\n    volume: 23215,\n  },\n  {\n    date: 1462547640000,\n    open: 49.75,\n    high: 49.7568,\n    low: 49.74,\n    close: 49.7568,\n    volume: 13432,\n  },\n  {\n    date: 1462547700000,\n    open: 49.7545,\n    high: 49.76,\n    low: 49.75,\n    close: 49.76,\n    volume: 14326,\n  },\n  {\n    date: 1462547760000,\n    open: 49.755,\n    high: 49.765,\n    low: 49.74,\n    close: 49.74,\n    volume: 57630,\n  },\n  {\n    date: 1462547820000,\n    open: 49.74,\n    high: 49.76,\n    low: 49.71,\n    close: 49.72,\n    volume: 68163,\n  },\n  {\n    date: 1462547880000,\n    open: 49.7201,\n    high: 49.74,\n    low: 49.72,\n    close: 49.725,\n    volume: 36259,\n  },\n  {\n    date: 1462547940000,\n    open: 49.725,\n    high: 49.83,\n    low: 49.725,\n    close: 49.8,\n    volume: 50959,\n  },\n  {\n    date: 1462548000000,\n    open: 49.8,\n    high: 49.8,\n    low: 49.78,\n    close: 49.79,\n    volume: 28503,\n  },\n  {\n    date: 1462548060000,\n    open: 49.795,\n    high: 49.81,\n    low: 49.77,\n    close: 49.805,\n    volume: 40022,\n  },\n  {\n    date: 1462548120000,\n    open: 49.8001,\n    high: 49.85,\n    low: 49.795,\n    close: 49.8,\n    volume: 69487,\n  },\n  {\n    date: 1462548180000,\n    open: 49.8,\n    high: 49.8,\n    low: 49.775,\n    close: 49.78,\n    volume: 14880,\n  },\n  {\n    date: 1462548240000,\n    open: 49.79,\n    high: 49.835,\n    low: 49.7801,\n    close: 49.8101,\n    volume: 23258,\n  },\n  {\n    date: 1462548300000,\n    open: 49.815,\n    high: 49.8158,\n    low: 49.78,\n    close: 49.8067,\n    volume: 30242,\n  },\n  {\n    date: 1462548360000,\n    open: 49.81,\n    high: 49.83,\n    low: 49.79,\n    close: 49.81,\n    volume: 33804,\n  },\n  {\n    date: 1462548420000,\n    open: 49.8,\n    high: 49.82,\n    low: 49.79,\n    close: 49.8156,\n    volume: 30257,\n  },\n  {\n    date: 1462548480000,\n    open: 49.82,\n    high: 49.88,\n    low: 49.82,\n    close: 49.84,\n    volume: 102934,\n  },\n  {\n    date: 1462548540000,\n    open: 49.84,\n    high: 49.87,\n    low: 49.84,\n    close: 49.85,\n    volume: 26301,\n  },\n  {\n    date: 1462548600000,\n    open: 49.8572,\n    high: 49.8572,\n    low: 49.82,\n    close: 49.84,\n    volume: 23495,\n  },\n  {\n    date: 1462548660000,\n    open: 49.835,\n    high: 49.84,\n    low: 49.79,\n    close: 49.79,\n    volume: 26763,\n  },\n  {\n    date: 1462548720000,\n    open: 49.795,\n    high: 49.83,\n    low: 49.7901,\n    close: 49.83,\n    volume: 26852,\n  },\n  {\n    date: 1462548780000,\n    open: 49.83,\n    high: 49.8399,\n    low: 49.81,\n    close: 49.81,\n    volume: 30137,\n  },\n  {\n    date: 1462548840000,\n    open: 49.805,\n    high: 49.83,\n    low: 49.79,\n    close: 49.82,\n    volume: 28387,\n  },\n  {\n    date: 1462548900000,\n    open: 49.815,\n    high: 49.82,\n    low: 49.78,\n    close: 49.79,\n    volume: 21907,\n  },\n  {\n    date: 1462548960000,\n    open: 49.79,\n    high: 49.79,\n    low: 49.76,\n    close: 49.79,\n    volume: 20656,\n  },\n  {\n    date: 1462549020000,\n    open: 49.78,\n    high: 49.79,\n    low: 49.77,\n    close: 49.78,\n    volume: 13888,\n  },\n  {\n    date: 1462549080000,\n    open: 49.785,\n    high: 49.79,\n    low: 49.765,\n    close: 49.77,\n    volume: 21947,\n  },\n  {\n    date: 1462549140000,\n    open: 49.775,\n    high: 49.805,\n    low: 49.775,\n    close: 49.805,\n    volume: 24232,\n  },\n  {\n    date: 1462549200000,\n    open: 49.8061,\n    high: 49.81,\n    low: 49.79,\n    close: 49.7933,\n    volume: 28808,\n  },\n  {\n    date: 1462549260000,\n    open: 49.79,\n    high: 49.8,\n    low: 49.78,\n    close: 49.78,\n    volume: 19536,\n  },\n  {\n    date: 1462549320000,\n    open: 49.785,\n    high: 49.8,\n    low: 49.78,\n    close: 49.8,\n    volume: 31847,\n  },\n  {\n    date: 1462549380000,\n    open: 49.8,\n    high: 49.816,\n    low: 49.79,\n    close: 49.795,\n    volume: 20209,\n  },\n  {\n    date: 1462549440000,\n    open: 49.795,\n    high: 49.8,\n    low: 49.77,\n    close: 49.78,\n    volume: 47141,\n  },\n  {\n    date: 1462549500000,\n    open: 49.78,\n    high: 49.79,\n    low: 49.77,\n    close: 49.785,\n    volume: 60360,\n  },\n  {\n    date: 1462549560000,\n    open: 49.78,\n    high: 49.79,\n    low: 49.78,\n    close: 49.7801,\n    volume: 8269,\n  },\n  {\n    date: 1462549620000,\n    open: 49.78,\n    high: 49.79,\n    low: 49.76,\n    close: 49.775,\n    volume: 37404,\n  },\n  {\n    date: 1462549680000,\n    open: 49.77,\n    high: 49.78,\n    low: 49.76,\n    close: 49.76,\n    volume: 68899,\n  },\n  {\n    date: 1462549740000,\n    open: 49.76,\n    high: 49.77,\n    low: 49.74,\n    close: 49.7667,\n    volume: 61360,\n  },\n  {\n    date: 1462549800000,\n    open: 49.77,\n    high: 49.78,\n    low: 49.75,\n    close: 49.765,\n    volume: 110738,\n  },\n  {\n    date: 1462549860000,\n    open: 49.765,\n    high: 49.77,\n    low: 49.76,\n    close: 49.76,\n    volume: 39396,\n  },\n  {\n    date: 1462549920000,\n    open: 49.76,\n    high: 49.77,\n    low: 49.75,\n    close: 49.75,\n    volume: 46424,\n  },\n  {\n    date: 1462549980000,\n    open: 49.75,\n    high: 49.7525,\n    low: 49.73,\n    close: 49.73,\n    volume: 46976,\n  },\n  {\n    date: 1462550040000,\n    open: 49.735,\n    high: 49.74,\n    low: 49.71,\n    close: 49.7199,\n    volume: 68800,\n  },\n  {\n    date: 1462550100000,\n    open: 49.715,\n    high: 49.72,\n    low: 49.68,\n    close: 49.7,\n    volume: 69624,\n  },\n  {\n    date: 1462550160000,\n    open: 49.71,\n    high: 49.77,\n    low: 49.71,\n    close: 49.765,\n    volume: 49524,\n  },\n  {\n    date: 1462550220000,\n    open: 49.77,\n    high: 49.77,\n    low: 49.74,\n    close: 49.755,\n    volume: 94587,\n  },\n  {\n    date: 1462550280000,\n    open: 49.755,\n    high: 49.77,\n    low: 49.74,\n    close: 49.75,\n    volume: 55945,\n  },\n  {\n    date: 1462550340000,\n    open: 49.76,\n    high: 49.79,\n    low: 49.75,\n    close: 49.79,\n    volume: 17823,\n  },\n  {\n    date: 1462550400000,\n    open: 49.79,\n    high: 49.795,\n    low: 49.75,\n    close: 49.76,\n    volume: 41978,\n  },\n  {\n    date: 1462550460000,\n    open: 49.755,\n    high: 49.755,\n    low: 49.72,\n    close: 49.74,\n    volume: 65796,\n  },\n  {\n    date: 1462550520000,\n    open: 49.74,\n    high: 49.74,\n    low: 49.71,\n    close: 49.7364,\n    volume: 19325,\n  },\n  {\n    date: 1462550580000,\n    open: 49.74,\n    high: 49.75,\n    low: 49.73,\n    close: 49.73,\n    volume: 20170,\n  },\n  {\n    date: 1462550640000,\n    open: 49.73,\n    high: 49.74,\n    low: 49.72,\n    close: 49.73,\n    volume: 11308,\n  },\n  {\n    date: 1462550700000,\n    open: 49.73,\n    high: 49.75,\n    low: 49.72,\n    close: 49.72,\n    volume: 25233,\n  },\n  {\n    date: 1462550760000,\n    open: 49.725,\n    high: 49.729,\n    low: 49.695,\n    close: 49.725,\n    volume: 46677,\n  },\n  {\n    date: 1462550820000,\n    open: 49.72,\n    high: 49.75,\n    low: 49.71,\n    close: 49.75,\n    volume: 10741,\n  },\n  {\n    date: 1462550880000,\n    open: 49.7462,\n    high: 49.765,\n    low: 49.7462,\n    close: 49.76,\n    volume: 10165,\n  },\n  {\n    date: 1462550940000,\n    open: 49.76,\n    high: 49.7699,\n    low: 49.75,\n    close: 49.7565,\n    volume: 9531,\n  },\n  {\n    date: 1462551000000,\n    open: 49.755,\n    high: 49.76,\n    low: 49.75,\n    close: 49.755,\n    volume: 2939,\n  },\n  {\n    date: 1462551060000,\n    open: 49.755,\n    high: 49.76,\n    low: 49.74,\n    close: 49.7535,\n    volume: 17161,\n  },\n  {\n    date: 1462551120000,\n    open: 49.75,\n    high: 49.75,\n    low: 49.74,\n    close: 49.75,\n    volume: 9288,\n  },\n  {\n    date: 1462551180000,\n    open: 49.745,\n    high: 49.75,\n    low: 49.72,\n    close: 49.75,\n    volume: 35117,\n  },\n  {\n    date: 1462551240000,\n    open: 49.7499,\n    high: 49.75,\n    low: 49.74,\n    close: 49.7464,\n    volume: 18888,\n  },\n  {\n    date: 1462551300000,\n    open: 49.745,\n    high: 49.77,\n    low: 49.74,\n    close: 49.77,\n    volume: 9983,\n  },\n  {\n    date: 1462551360000,\n    open: 49.76,\n    high: 49.7659,\n    low: 49.73,\n    close: 49.74,\n    volume: 63866,\n  },\n  {\n    date: 1462551420000,\n    open: 49.745,\n    high: 49.755,\n    low: 49.73,\n    close: 49.73,\n    volume: 31143,\n  },\n  {\n    date: 1462551480000,\n    open: 49.73,\n    high: 49.735,\n    low: 49.71,\n    close: 49.7235,\n    volume: 45958,\n  },\n  {\n    date: 1462551540000,\n    open: 49.725,\n    high: 49.74,\n    low: 49.72,\n    close: 49.74,\n    volume: 10482,\n  },\n  {\n    date: 1462551600000,\n    open: 49.74,\n    high: 49.755,\n    low: 49.74,\n    close: 49.75,\n    volume: 38533,\n  },\n  {\n    date: 1462551660000,\n    open: 49.75,\n    high: 49.76,\n    low: 49.7,\n    close: 49.71,\n    volume: 69081,\n  },\n  {\n    date: 1462551720000,\n    open: 49.705,\n    high: 49.74,\n    low: 49.705,\n    close: 49.73,\n    volume: 12915,\n  },\n  {\n    date: 1462551780000,\n    open: 49.7356,\n    high: 49.76,\n    low: 49.7356,\n    close: 49.74,\n    volume: 33498,\n  },\n  {\n    date: 1462551840000,\n    open: 49.75,\n    high: 49.76,\n    low: 49.74,\n    close: 49.75,\n    volume: 19611,\n  },\n  {\n    date: 1462551900000,\n    open: 49.755,\n    high: 49.755,\n    low: 49.73,\n    close: 49.735,\n    volume: 63519,\n  },\n  {\n    date: 1462551960000,\n    open: 49.735,\n    high: 49.74,\n    low: 49.7,\n    close: 49.71,\n    volume: 44235,\n  },\n  {\n    date: 1462552020000,\n    open: 49.71,\n    high: 49.75,\n    low: 49.71,\n    close: 49.73,\n    volume: 25044,\n  },\n  {\n    date: 1462552080000,\n    open: 49.735,\n    high: 49.75,\n    low: 49.73,\n    close: 49.745,\n    volume: 27751,\n  },\n  {\n    date: 1462552140000,\n    open: 49.73,\n    high: 49.75,\n    low: 49.73,\n    close: 49.735,\n    volume: 7485,\n  },\n  {\n    date: 1462552200000,\n    open: 49.7301,\n    high: 49.74,\n    low: 49.72,\n    close: 49.74,\n    volume: 25312,\n  },\n  {\n    date: 1462552260000,\n    open: 49.735,\n    high: 49.75,\n    low: 49.73,\n    close: 49.74,\n    volume: 13498,\n  },\n  {\n    date: 1462552320000,\n    open: 49.74,\n    high: 49.745,\n    low: 49.72,\n    close: 49.725,\n    volume: 34494,\n  },\n  {\n    date: 1462552380000,\n    open: 49.72,\n    high: 49.74,\n    low: 49.72,\n    close: 49.73,\n    volume: 8797,\n  },\n  {\n    date: 1462552440000,\n    open: 49.735,\n    high: 49.74,\n    low: 49.72,\n    close: 49.73,\n    volume: 27264,\n  },\n  {\n    date: 1462552500000,\n    open: 49.72,\n    high: 49.75,\n    low: 49.72,\n    close: 49.75,\n    volume: 15303,\n  },\n  {\n    date: 1462552560000,\n    open: 49.745,\n    high: 49.75,\n    low: 49.73,\n    close: 49.74,\n    volume: 22037,\n  },\n  {\n    date: 1462552620000,\n    open: 49.745,\n    high: 49.75,\n    low: 49.74,\n    close: 49.745,\n    volume: 28221,\n  },\n  {\n    date: 1462552680000,\n    open: 49.75,\n    high: 49.755,\n    low: 49.73,\n    close: 49.75,\n    volume: 51864,\n  },\n  {\n    date: 1462552740000,\n    open: 49.75,\n    high: 49.755,\n    low: 49.74,\n    close: 49.745,\n    volume: 42761,\n  },\n  {\n    date: 1462552800000,\n    open: 49.745,\n    high: 49.76,\n    low: 49.73,\n    close: 49.75,\n    volume: 111587,\n  },\n  {\n    date: 1462552860000,\n    open: 49.745,\n    high: 49.76,\n    low: 49.72,\n    close: 49.7299,\n    volume: 92446,\n  },\n  {\n    date: 1462552920000,\n    open: 49.725,\n    high: 49.73,\n    low: 49.72,\n    close: 49.73,\n    volume: 12077,\n  },\n  {\n    date: 1462552980000,\n    open: 49.74,\n    high: 49.76,\n    low: 49.735,\n    close: 49.755,\n    volume: 24071,\n  },\n  {\n    date: 1462553040000,\n    open: 49.76,\n    high: 49.79,\n    low: 49.76,\n    close: 49.78,\n    volume: 23876,\n  },\n  {\n    date: 1462553100000,\n    open: 49.785,\n    high: 49.82,\n    low: 49.78,\n    close: 49.82,\n    volume: 29745,\n  },\n  {\n    date: 1462553160000,\n    open: 49.816,\n    high: 49.816,\n    low: 49.8,\n    close: 49.8,\n    volume: 43202,\n  },\n  {\n    date: 1462553220000,\n    open: 49.81,\n    high: 49.83,\n    low: 49.79,\n    close: 49.79,\n    volume: 41814,\n  },\n  {\n    date: 1462553280000,\n    open: 49.7966,\n    high: 49.81,\n    low: 49.78,\n    close: 49.79,\n    volume: 32007,\n  },\n  {\n    date: 1462553340000,\n    open: 49.793,\n    high: 49.81,\n    low: 49.79,\n    close: 49.8071,\n    volume: 11451,\n  },\n  {\n    date: 1462553400000,\n    open: 49.802,\n    high: 49.81,\n    low: 49.8,\n    close: 49.8,\n    volume: 8500,\n  },\n  {\n    date: 1462553460000,\n    open: 49.8,\n    high: 49.8,\n    low: 49.78,\n    close: 49.785,\n    volume: 17523,\n  },\n  {\n    date: 1462553520000,\n    open: 49.78,\n    high: 49.79,\n    low: 49.77,\n    close: 49.7707,\n    volume: 13978,\n  },\n  {\n    date: 1462553580000,\n    open: 49.77,\n    high: 49.775,\n    low: 49.75,\n    close: 49.775,\n    volume: 24486,\n  },\n  {\n    date: 1462553640000,\n    open: 49.775,\n    high: 49.78,\n    low: 49.77,\n    close: 49.77,\n    volume: 13100,\n  },\n  {\n    date: 1462553700000,\n    open: 49.775,\n    high: 49.785,\n    low: 49.77,\n    close: 49.775,\n    volume: 20483,\n  },\n  {\n    date: 1462553760000,\n    open: 49.775,\n    high: 49.8,\n    low: 49.77,\n    close: 49.7965,\n    volume: 32106,\n  },\n  {\n    date: 1462553820000,\n    open: 49.8,\n    high: 49.87,\n    low: 49.8,\n    close: 49.857,\n    volume: 44772,\n  },\n  {\n    date: 1462553880000,\n    open: 49.8536,\n    high: 49.86,\n    low: 49.84,\n    close: 49.85,\n    volume: 104649,\n  },\n  {\n    date: 1462553940000,\n    open: 49.85,\n    high: 49.8656,\n    low: 49.8325,\n    close: 49.8601,\n    volume: 55424,\n  },\n  {\n    date: 1462554000000,\n    open: 49.865,\n    high: 49.88,\n    low: 49.833,\n    close: 49.88,\n    volume: 45519,\n  },\n  {\n    date: 1462554060000,\n    open: 49.88,\n    high: 49.9,\n    low: 49.872,\n    close: 49.88,\n    volume: 35506,\n  },\n  {\n    date: 1462554120000,\n    open: 49.88,\n    high: 49.9,\n    low: 49.87,\n    close: 49.895,\n    volume: 19472,\n  },\n  {\n    date: 1462554180000,\n    open: 49.89,\n    high: 49.9,\n    low: 49.89,\n    close: 49.895,\n    volume: 7963,\n  },\n  {\n    date: 1462554240000,\n    open: 49.89,\n    high: 49.895,\n    low: 49.87,\n    close: 49.875,\n    volume: 24782,\n  },\n  {\n    date: 1462554300000,\n    open: 49.875,\n    high: 49.8758,\n    low: 49.86,\n    close: 49.87,\n    volume: 10350,\n  },\n  {\n    date: 1462554360000,\n    open: 49.87,\n    high: 49.89,\n    low: 49.87,\n    close: 49.89,\n    volume: 21161,\n  },\n  {\n    date: 1462554420000,\n    open: 49.89,\n    high: 49.93,\n    low: 49.88,\n    close: 49.93,\n    volume: 66554,\n  },\n  {\n    date: 1462554480000,\n    open: 49.93,\n    high: 49.95,\n    low: 49.92,\n    close: 49.94,\n    volume: 48541,\n  },\n  {\n    date: 1462554540000,\n    open: 49.945,\n    high: 49.945,\n    low: 49.91,\n    close: 49.91,\n    volume: 12725,\n  },\n  {\n    date: 1462554600000,\n    open: 49.915,\n    high: 49.92,\n    low: 49.91,\n    close: 49.9176,\n    volume: 15540,\n  },\n  {\n    date: 1462554660000,\n    open: 49.91,\n    high: 49.945,\n    low: 49.91,\n    close: 49.945,\n    volume: 21866,\n  },\n  {\n    date: 1462554720000,\n    open: 49.94,\n    high: 49.95,\n    low: 49.925,\n    close: 49.935,\n    volume: 89940,\n  },\n  {\n    date: 1462554780000,\n    open: 49.93,\n    high: 49.94,\n    low: 49.88,\n    close: 49.9133,\n    volume: 71383,\n  },\n  {\n    date: 1462554840000,\n    open: 49.92,\n    high: 49.96,\n    low: 49.92,\n    close: 49.94,\n    volume: 42099,\n  },\n  {\n    date: 1462554900000,\n    open: 49.94,\n    high: 49.94,\n    low: 49.91,\n    close: 49.9152,\n    volume: 11256,\n  },\n  {\n    date: 1462554960000,\n    open: 49.915,\n    high: 49.93,\n    low: 49.915,\n    close: 49.92,\n    volume: 12108,\n  },\n  {\n    date: 1462555020000,\n    open: 49.93,\n    high: 49.9899,\n    low: 49.9298,\n    close: 49.9736,\n    volume: 35137,\n  },\n  {\n    date: 1462555080000,\n    open: 49.97,\n    high: 49.98,\n    low: 49.97,\n    close: 49.98,\n    volume: 37072,\n  },\n  {\n    date: 1462555140000,\n    open: 49.985,\n    high: 50,\n    low: 49.98,\n    close: 49.9901,\n    volume: 21888,\n  },\n  {\n    date: 1462555200000,\n    open: 50,\n    high: 50,\n    low: 49.97,\n    close: 49.975,\n    volume: 12273,\n  },\n  {\n    date: 1462555260000,\n    open: 49.97,\n    high: 49.99,\n    low: 49.97,\n    close: 49.99,\n    volume: 19970,\n  },\n  {\n    date: 1462555320000,\n    open: 49.99,\n    high: 49.99,\n    low: 49.96,\n    close: 49.96,\n    volume: 29662,\n  },\n  {\n    date: 1462555380000,\n    open: 49.96,\n    high: 49.97,\n    low: 49.96,\n    close: 49.965,\n    volume: 12286,\n  },\n  {\n    date: 1462555440000,\n    open: 49.96,\n    high: 49.98,\n    low: 49.955,\n    close: 49.97,\n    volume: 14858,\n  },\n  {\n    date: 1462555500000,\n    open: 49.98,\n    high: 50.01,\n    low: 49.97,\n    close: 50,\n    volume: 121246,\n  },\n  {\n    date: 1462555560000,\n    open: 50.005,\n    high: 50.005,\n    low: 49.965,\n    close: 49.9963,\n    volume: 31144,\n  },\n  {\n    date: 1462555620000,\n    open: 50,\n    high: 50.02,\n    low: 49.993,\n    close: 49.995,\n    volume: 38079,\n  },\n  {\n    date: 1462555680000,\n    open: 49.995,\n    high: 50.01,\n    low: 49.98,\n    close: 50,\n    volume: 19200,\n  },\n  {\n    date: 1462555740000,\n    open: 50,\n    high: 50.025,\n    low: 49.995,\n    close: 50.01,\n    volume: 28832,\n  },\n  {\n    date: 1462555800000,\n    open: 50.0199,\n    high: 50.0199,\n    low: 49.97,\n    close: 49.98,\n    volume: 30840,\n  },\n  {\n    date: 1462555860000,\n    open: 49.985,\n    high: 49.99,\n    low: 49.96,\n    close: 49.97,\n    volume: 44019,\n  },\n  {\n    date: 1462555920000,\n    open: 49.97,\n    high: 49.99,\n    low: 49.97,\n    close: 49.97,\n    volume: 24172,\n  },\n  {\n    date: 1462555980000,\n    open: 49.97,\n    high: 49.98,\n    low: 49.96,\n    close: 49.9601,\n    volume: 13855,\n  },\n  {\n    date: 1462556040000,\n    open: 49.96,\n    high: 49.97,\n    low: 49.95,\n    close: 49.95,\n    volume: 12130,\n  },\n  {\n    date: 1462556100000,\n    open: 49.95,\n    high: 49.99,\n    low: 49.95,\n    close: 49.98,\n    volume: 23847,\n  },\n  {\n    date: 1462556160000,\n    open: 49.985,\n    high: 50.01,\n    low: 49.98,\n    close: 50.0031,\n    volume: 55711,\n  },\n  {\n    date: 1462556220000,\n    open: 50.0001,\n    high: 50.01,\n    low: 49.99,\n    close: 50,\n    volume: 24411,\n  },\n  {\n    date: 1462556280000,\n    open: 50.01,\n    high: 50.01,\n    low: 49.9736,\n    close: 49.9799,\n    volume: 26829,\n  },\n  {\n    date: 1462556340000,\n    open: 49.98,\n    high: 50,\n    low: 49.96,\n    close: 49.99,\n    volume: 57432,\n  },\n  {\n    date: 1462556400000,\n    open: 49.9944,\n    high: 50.015,\n    low: 49.99,\n    close: 50.01,\n    volume: 21391,\n  },\n  {\n    date: 1462556460000,\n    open: 50.01,\n    high: 50.025,\n    low: 50,\n    close: 50.005,\n    volume: 46600,\n  },\n  {\n    date: 1462556520000,\n    open: 50.005,\n    high: 50.01,\n    low: 49.97,\n    close: 49.97,\n    volume: 40955,\n  },\n  {\n    date: 1462556580000,\n    open: 49.979,\n    high: 49.9868,\n    low: 49.97,\n    close: 49.985,\n    volume: 12977,\n  },\n  {\n    date: 1462556640000,\n    open: 49.985,\n    high: 49.99,\n    low: 49.98,\n    close: 49.9801,\n    volume: 10674,\n  },\n  {\n    date: 1462556700000,\n    open: 49.98,\n    high: 50.0073,\n    low: 49.98,\n    close: 49.98,\n    volume: 49923,\n  },\n  {\n    date: 1462556760000,\n    open: 49.985,\n    high: 50,\n    low: 49.98,\n    close: 49.99,\n    volume: 18769,\n  },\n  {\n    date: 1462556820000,\n    open: 49.99,\n    high: 50.03,\n    low: 49.98,\n    close: 50,\n    volume: 60525,\n  },\n  {\n    date: 1462556880000,\n    open: 50.005,\n    high: 50.0387,\n    low: 50,\n    close: 50.0387,\n    volume: 80464,\n  },\n  {\n    date: 1462556940000,\n    open: 50.0301,\n    high: 50.045,\n    low: 50,\n    close: 50.04,\n    volume: 55703,\n  },\n  {\n    date: 1462557000000,\n    open: 50.045,\n    high: 50.09,\n    low: 50.02,\n    close: 50.06,\n    volume: 121732,\n  },\n  {\n    date: 1462557060000,\n    open: 50.0542,\n    high: 50.0856,\n    low: 50.04,\n    close: 50.0856,\n    volume: 71757,\n  },\n  {\n    date: 1462557120000,\n    open: 50.081,\n    high: 50.09,\n    low: 50.08,\n    close: 50.0836,\n    volume: 48477,\n  },\n  {\n    date: 1462557180000,\n    open: 50.08,\n    high: 50.08,\n    low: 50.07,\n    close: 50.075,\n    volume: 8245,\n  },\n  {\n    date: 1462557240000,\n    open: 50.075,\n    high: 50.085,\n    low: 50.07,\n    close: 50.085,\n    volume: 17124,\n  },\n  {\n    date: 1462557300000,\n    open: 50.085,\n    high: 50.13,\n    low: 50.085,\n    close: 50.1,\n    volume: 72216,\n  },\n  {\n    date: 1462557360000,\n    open: 50.1,\n    high: 50.1,\n    low: 50.06,\n    close: 50.08,\n    volume: 82000,\n  },\n  {\n    date: 1462557420000,\n    open: 50.08,\n    high: 50.1,\n    low: 50.07,\n    close: 50.09,\n    volume: 76920,\n  },\n  {\n    date: 1462557480000,\n    open: 50.0936,\n    high: 50.1299,\n    low: 50.08,\n    close: 50.11,\n    volume: 52797,\n  },\n  {\n    date: 1462557540000,\n    open: 50.1125,\n    high: 50.16,\n    low: 50.1125,\n    close: 50.16,\n    volume: 66158,\n  },\n  {\n    date: 1462557600000,\n    open: 50.155,\n    high: 50.2199,\n    low: 50.15,\n    close: 50.21,\n    volume: 46314,\n  },\n  {\n    date: 1462557660000,\n    open: 50.215,\n    high: 50.22,\n    low: 50.17,\n    close: 50.1701,\n    volume: 26107,\n  },\n  {\n    date: 1462557720000,\n    open: 50.18,\n    high: 50.21,\n    low: 50.17,\n    close: 50.19,\n    volume: 43529,\n  },\n  {\n    date: 1462557780000,\n    open: 50.1865,\n    high: 50.205,\n    low: 50.16,\n    close: 50.195,\n    volume: 32086,\n  },\n  {\n    date: 1462557840000,\n    open: 50.19,\n    high: 50.198,\n    low: 50.17,\n    close: 50.19,\n    volume: 28464,\n  },\n  {\n    date: 1462557900000,\n    open: 50.18,\n    high: 50.24,\n    low: 50.17,\n    close: 50.21,\n    volume: 65102,\n  },\n  {\n    date: 1462557960000,\n    open: 50.2064,\n    high: 50.25,\n    low: 50.2,\n    close: 50.24,\n    volume: 57614,\n  },\n  {\n    date: 1462558020000,\n    open: 50.245,\n    high: 50.26,\n    low: 50.24,\n    close: 50.26,\n    volume: 51693,\n  },\n  {\n    date: 1462558080000,\n    open: 50.26,\n    high: 50.29,\n    low: 50.25,\n    close: 50.28,\n    volume: 60021,\n  },\n  {\n    date: 1462558140000,\n    open: 50.28,\n    high: 50.31,\n    low: 50.27,\n    close: 50.2801,\n    volume: 49518,\n  },\n  {\n    date: 1462558200000,\n    open: 50.285,\n    high: 50.32,\n    low: 50.28,\n    close: 50.3,\n    volume: 74891,\n  },\n  {\n    date: 1462558260000,\n    open: 50.305,\n    high: 50.32,\n    low: 50.275,\n    close: 50.29,\n    volume: 33636,\n  },\n  {\n    date: 1462558320000,\n    open: 50.28,\n    high: 50.31,\n    low: 50.27,\n    close: 50.3,\n    volume: 39413,\n  },\n  {\n    date: 1462558380000,\n    open: 50.3,\n    high: 50.31,\n    low: 50.26,\n    close: 50.26,\n    volume: 28469,\n  },\n  {\n    date: 1462558440000,\n    open: 50.26,\n    high: 50.28,\n    low: 50.25,\n    close: 50.25,\n    volume: 43002,\n  },\n  {\n    date: 1462558500000,\n    open: 50.26,\n    high: 50.29,\n    low: 50.25,\n    close: 50.29,\n    volume: 23944,\n  },\n  {\n    date: 1462558560000,\n    open: 50.298,\n    high: 50.305,\n    low: 50.27,\n    close: 50.3,\n    volume: 57470,\n  },\n  {\n    date: 1462558620000,\n    open: 50.3,\n    high: 50.32,\n    low: 50.2901,\n    close: 50.305,\n    volume: 44622,\n  },\n  {\n    date: 1462558680000,\n    open: 50.305,\n    high: 50.32,\n    low: 50.28,\n    close: 50.28,\n    volume: 66126,\n  },\n  {\n    date: 1462558740000,\n    open: 50.28,\n    high: 50.31,\n    low: 50.27,\n    close: 50.31,\n    volume: 39828,\n  },\n  {\n    date: 1462558800000,\n    open: 50.3,\n    high: 50.3,\n    low: 50.27,\n    close: 50.29,\n    volume: 31464,\n  },\n  {\n    date: 1462558860000,\n    open: 50.29,\n    high: 50.295,\n    low: 50.275,\n    close: 50.28,\n    volume: 20021,\n  },\n  {\n    date: 1462558920000,\n    open: 50.275,\n    high: 50.285,\n    low: 50.2338,\n    close: 50.26,\n    volume: 42620,\n  },\n  {\n    date: 1462558980000,\n    open: 50.265,\n    high: 50.28,\n    low: 50.24,\n    close: 50.245,\n    volume: 36999,\n  },\n  {\n    date: 1462559040000,\n    open: 50.245,\n    high: 50.245,\n    low: 50.21,\n    close: 50.225,\n    volume: 34141,\n  },\n  {\n    date: 1462559100000,\n    open: 50.22,\n    high: 50.23,\n    low: 50.185,\n    close: 50.19,\n    volume: 44834,\n  },\n  {\n    date: 1462559160000,\n    open: 50.193,\n    high: 50.2,\n    low: 50.185,\n    close: 50.199,\n    volume: 11357,\n  },\n  {\n    date: 1462559220000,\n    open: 50.19,\n    high: 50.22,\n    low: 50.18,\n    close: 50.195,\n    volume: 40033,\n  },\n  {\n    date: 1462559280000,\n    open: 50.2,\n    high: 50.23,\n    low: 50.195,\n    close: 50.21,\n    volume: 59710,\n  },\n  {\n    date: 1462559340000,\n    open: 50.215,\n    high: 50.24,\n    low: 50.2001,\n    close: 50.232,\n    volume: 55015,\n  },\n  {\n    date: 1462559400000,\n    open: 50.23,\n    high: 50.235,\n    low: 50.18,\n    close: 50.19,\n    volume: 72386,\n  },\n  {\n    date: 1462559460000,\n    open: 50.19,\n    high: 50.195,\n    low: 50.15,\n    close: 50.179,\n    volume: 73827,\n  },\n  {\n    date: 1462559520000,\n    open: 50.175,\n    high: 50.18,\n    low: 50.16,\n    close: 50.16,\n    volume: 17009,\n  },\n  {\n    date: 1462559580000,\n    open: 50.165,\n    high: 50.185,\n    low: 50.16,\n    close: 50.16,\n    volume: 40129,\n  },\n  {\n    date: 1462559640000,\n    open: 50.16,\n    high: 50.17,\n    low: 50.135,\n    close: 50.16,\n    volume: 27500,\n  },\n  {\n    date: 1462559700000,\n    open: 50.15,\n    high: 50.16,\n    low: 50.14,\n    close: 50.15,\n    volume: 18153,\n  },\n  {\n    date: 1462559760000,\n    open: 50.15,\n    high: 50.165,\n    low: 50.13,\n    close: 50.135,\n    volume: 33656,\n  },\n  {\n    date: 1462559820000,\n    open: 50.125,\n    high: 50.14,\n    low: 50.11,\n    close: 50.135,\n    volume: 29250,\n  },\n  {\n    date: 1462559880000,\n    open: 50.135,\n    high: 50.18,\n    low: 50.135,\n    close: 50.1765,\n    volume: 50127,\n  },\n  {\n    date: 1462559940000,\n    open: 50.17,\n    high: 50.18,\n    low: 50.16,\n    close: 50.175,\n    volume: 40824,\n  },\n  {\n    date: 1462560000000,\n    open: 50.18,\n    high: 50.2,\n    low: 50.175,\n    close: 50.19,\n    volume: 34442,\n  },\n  {\n    date: 1462560060000,\n    open: 50.185,\n    high: 50.205,\n    low: 50.17,\n    close: 50.1999,\n    volume: 79029,\n  },\n  {\n    date: 1462560120000,\n    open: 50.205,\n    high: 50.26,\n    low: 50.2,\n    close: 50.25,\n    volume: 88131,\n  },\n  {\n    date: 1462560180000,\n    open: 50.26,\n    high: 50.28,\n    low: 50.245,\n    close: 50.28,\n    volume: 69653,\n  },\n  {\n    date: 1462560240000,\n    open: 50.28,\n    high: 50.31,\n    low: 50.275,\n    close: 50.305,\n    volume: 74950,\n  },\n  {\n    date: 1462560300000,\n    open: 50.305,\n    high: 50.33,\n    low: 50.28,\n    close: 50.3,\n    volume: 64196,\n  },\n  {\n    date: 1462560360000,\n    open: 50.295,\n    high: 50.3,\n    low: 50.27,\n    close: 50.285,\n    volume: 78860,\n  },\n  {\n    date: 1462560420000,\n    open: 50.285,\n    high: 50.3,\n    low: 50.26,\n    close: 50.261,\n    volume: 29804,\n  },\n  {\n    date: 1462560480000,\n    open: 50.2601,\n    high: 50.28,\n    low: 50.24,\n    close: 50.28,\n    volume: 59480,\n  },\n  {\n    date: 1462560540000,\n    open: 50.27,\n    high: 50.27,\n    low: 50.22,\n    close: 50.2338,\n    volume: 32492,\n  },\n  {\n    date: 1462560600000,\n    open: 50.235,\n    high: 50.24,\n    low: 50.21,\n    close: 50.2199,\n    volume: 48362,\n  },\n  {\n    date: 1462560660000,\n    open: 50.21,\n    high: 50.24,\n    low: 50.21,\n    close: 50.24,\n    volume: 122646,\n  },\n  {\n    date: 1462560720000,\n    open: 50.235,\n    high: 50.24,\n    low: 50.2235,\n    close: 50.2235,\n    volume: 88629,\n  },\n  {\n    date: 1462560780000,\n    open: 50.2236,\n    high: 50.23,\n    low: 50.2,\n    close: 50.225,\n    volume: 36858,\n  },\n  {\n    date: 1462560840000,\n    open: 50.23,\n    high: 50.24,\n    low: 50.22,\n    close: 50.235,\n    volume: 25169,\n  },\n  {\n    date: 1462560900000,\n    open: 50.2332,\n    high: 50.28,\n    low: 50.2332,\n    close: 50.25,\n    volume: 66915,\n  },\n  {\n    date: 1462560960000,\n    open: 50.25,\n    high: 50.25,\n    low: 50.215,\n    close: 50.215,\n    volume: 18936,\n  },\n  {\n    date: 1462561020000,\n    open: 50.215,\n    high: 50.23,\n    low: 50.21,\n    close: 50.23,\n    volume: 19295,\n  },\n  {\n    date: 1462561080000,\n    open: 50.23,\n    high: 50.25,\n    low: 50.22,\n    close: 50.23,\n    volume: 36251,\n  },\n  {\n    date: 1462561140000,\n    open: 50.225,\n    high: 50.24,\n    low: 50.22,\n    close: 50.235,\n    volume: 20846,\n  },\n  {\n    date: 1462561200000,\n    open: 50.24,\n    high: 50.25,\n    low: 50.22,\n    close: 50.25,\n    volume: 93892,\n  },\n  {\n    date: 1462561260000,\n    open: 50.25,\n    high: 50.26,\n    low: 50.23,\n    close: 50.25,\n    volume: 404855,\n  },\n  {\n    date: 1462561320000,\n    open: 50.25,\n    high: 50.285,\n    low: 50.24,\n    close: 50.285,\n    volume: 58467,\n  },\n  {\n    date: 1462561380000,\n    open: 50.2801,\n    high: 50.2801,\n    low: 50.25,\n    close: 50.26,\n    volume: 41889,\n  },\n  {\n    date: 1462561440000,\n    open: 50.27,\n    high: 50.28,\n    low: 50.25,\n    close: 50.25,\n    volume: 33326,\n  },\n  {\n    date: 1462561500000,\n    open: 50.25,\n    high: 50.27,\n    low: 50.25,\n    close: 50.27,\n    volume: 36870,\n  },\n  {\n    date: 1462561560000,\n    open: 50.26,\n    high: 50.28,\n    low: 50.25,\n    close: 50.255,\n    volume: 49509,\n  },\n  {\n    date: 1462561620000,\n    open: 50.26,\n    high: 50.26,\n    low: 50.25,\n    close: 50.26,\n    volume: 31978,\n  },\n  {\n    date: 1462561680000,\n    open: 50.2562,\n    high: 50.26,\n    low: 50.25,\n    close: 50.25,\n    volume: 20850,\n  },\n  {\n    date: 1462561740000,\n    open: 50.255,\n    high: 50.278,\n    low: 50.25,\n    close: 50.25,\n    volume: 110701,\n  },\n  {\n    date: 1462561800000,\n    open: 50.2599,\n    high: 50.27,\n    low: 50.22,\n    close: 50.2264,\n    volume: 112213,\n  },\n  {\n    date: 1462561860000,\n    open: 50.23,\n    high: 50.295,\n    low: 50.225,\n    close: 50.29,\n    volume: 69790,\n  },\n  {\n    date: 1462561920000,\n    open: 50.29,\n    high: 50.315,\n    low: 50.29,\n    close: 50.31,\n    volume: 73631,\n  },\n  {\n    date: 1462561980000,\n    open: 50.31,\n    high: 50.32,\n    low: 50.3001,\n    close: 50.3199,\n    volume: 67072,\n  },\n  {\n    date: 1462562040000,\n    open: 50.31,\n    high: 50.3101,\n    low: 50.29,\n    close: 50.3,\n    volume: 70373,\n  },\n  {\n    date: 1462562100000,\n    open: 50.295,\n    high: 50.295,\n    low: 50.24,\n    close: 50.25,\n    volume: 85303,\n  },\n  {\n    date: 1462562160000,\n    open: 50.255,\n    high: 50.27,\n    low: 50.23,\n    close: 50.24,\n    volume: 64469,\n  },\n  {\n    date: 1462562220000,\n    open: 50.25,\n    high: 50.28,\n    low: 50.25,\n    close: 50.255,\n    volume: 28005,\n  },\n  {\n    date: 1462562280000,\n    open: 50.2501,\n    high: 50.28,\n    low: 50.2501,\n    close: 50.275,\n    volume: 18825,\n  },\n  {\n    date: 1462562340000,\n    open: 50.28,\n    high: 50.31,\n    low: 50.275,\n    close: 50.3,\n    volume: 45745,\n  },\n  {\n    date: 1462562400000,\n    open: 50.305,\n    high: 50.305,\n    low: 50.27,\n    close: 50.27,\n    volume: 37304,\n  },\n  {\n    date: 1462562460000,\n    open: 50.27,\n    high: 50.28,\n    low: 50.26,\n    close: 50.28,\n    volume: 21141,\n  },\n  {\n    date: 1462562520000,\n    open: 50.29,\n    high: 50.295,\n    low: 50.26,\n    close: 50.285,\n    volume: 38071,\n  },\n  {\n    date: 1462562580000,\n    open: 50.2801,\n    high: 50.295,\n    low: 50.255,\n    close: 50.27,\n    volume: 43723,\n  },\n  {\n    date: 1462562640000,\n    open: 50.27,\n    high: 50.3,\n    low: 50.27,\n    close: 50.3,\n    volume: 31283,\n  },\n  {\n    date: 1462562700000,\n    open: 50.3,\n    high: 50.31,\n    low: 50.27,\n    close: 50.29,\n    volume: 69629,\n  },\n  {\n    date: 1462562760000,\n    open: 50.28,\n    high: 50.31,\n    low: 50.28,\n    close: 50.3,\n    volume: 52735,\n  },\n  {\n    date: 1462562820000,\n    open: 50.3,\n    high: 50.305,\n    low: 50.28,\n    close: 50.29,\n    volume: 23375,\n  },\n  {\n    date: 1462562880000,\n    open: 50.29,\n    high: 50.31,\n    low: 50.28,\n    close: 50.2899,\n    volume: 63264,\n  },\n  {\n    date: 1462562940000,\n    open: 50.28,\n    high: 50.31,\n    low: 50.27,\n    close: 50.305,\n    volume: 24592,\n  },\n  {\n    date: 1462563000000,\n    open: 50.31,\n    high: 50.31,\n    low: 50.28,\n    close: 50.2889,\n    volume: 26883,\n  },\n  {\n    date: 1462563060000,\n    open: 50.28,\n    high: 50.29,\n    low: 50.25,\n    close: 50.25,\n    volume: 48553,\n  },\n  {\n    date: 1462563120000,\n    open: 50.245,\n    high: 50.2499,\n    low: 50.21,\n    close: 50.21,\n    volume: 61006,\n  },\n  {\n    date: 1462563180000,\n    open: 50.22,\n    high: 50.24,\n    low: 50.21,\n    close: 50.21,\n    volume: 71603,\n  },\n  {\n    date: 1462563240000,\n    open: 50.21,\n    high: 50.211,\n    low: 50.18,\n    close: 50.1901,\n    volume: 56905,\n  },\n  {\n    date: 1462563300000,\n    open: 50.2,\n    high: 50.21,\n    low: 50.19,\n    close: 50.2099,\n    volume: 35336,\n  },\n  {\n    date: 1462563360000,\n    open: 50.2,\n    high: 50.21,\n    low: 50.19,\n    close: 50.208,\n    volume: 35216,\n  },\n  {\n    date: 1462563420000,\n    open: 50.21,\n    high: 50.235,\n    low: 50.2,\n    close: 50.21,\n    volume: 87654,\n  },\n  {\n    date: 1462563480000,\n    open: 50.2,\n    high: 50.25,\n    low: 50.19,\n    close: 50.2242,\n    volume: 97738,\n  },\n  {\n    date: 1462563540000,\n    open: 50.23,\n    high: 50.245,\n    low: 50.22,\n    close: 50.22,\n    volume: 40049,\n  },\n  {\n    date: 1462563600000,\n    open: 50.225,\n    high: 50.25,\n    low: 50.2106,\n    close: 50.23,\n    volume: 50348,\n  },\n  {\n    date: 1462563660000,\n    open: 50.23,\n    high: 50.25,\n    low: 50.22,\n    close: 50.25,\n    volume: 81244,\n  },\n  {\n    date: 1462563720000,\n    open: 50.24,\n    high: 50.27,\n    low: 50.24,\n    close: 50.245,\n    volume: 52392,\n  },\n  {\n    date: 1462563780000,\n    open: 50.25,\n    high: 50.27,\n    low: 50.24,\n    close: 50.255,\n    volume: 40152,\n  },\n  {\n    date: 1462563840000,\n    open: 50.25,\n    high: 50.26,\n    low: 50.24,\n    close: 50.255,\n    volume: 56050,\n  },\n  {\n    date: 1462563900000,\n    open: 50.26,\n    high: 50.26,\n    low: 50.24,\n    close: 50.24,\n    volume: 41947,\n  },\n  {\n    date: 1462563960000,\n    open: 50.24,\n    high: 50.27,\n    low: 50.24,\n    close: 50.25,\n    volume: 177680,\n  },\n  {\n    date: 1462564020000,\n    open: 50.25,\n    high: 50.26,\n    low: 50.225,\n    close: 50.2364,\n    volume: 67917,\n  },\n  {\n    date: 1462564080000,\n    open: 50.235,\n    high: 50.24,\n    low: 50.2,\n    close: 50.2,\n    volume: 104405,\n  },\n  {\n    date: 1462564140000,\n    open: 50.205,\n    high: 50.21,\n    low: 50.19,\n    close: 50.2099,\n    volume: 56730,\n  },\n  {\n    date: 1462564200000,\n    open: 50.205,\n    high: 50.22,\n    low: 50.17,\n    close: 50.215,\n    volume: 91831,\n  },\n  {\n    date: 1462564260000,\n    open: 50.21,\n    high: 50.24,\n    low: 50.175,\n    close: 50.23,\n    volume: 94161,\n  },\n  {\n    date: 1462564320000,\n    open: 50.23,\n    high: 50.26,\n    low: 50.225,\n    close: 50.235,\n    volume: 69505,\n  },\n  {\n    date: 1462564380000,\n    open: 50.24,\n    high: 50.29,\n    low: 50.235,\n    close: 50.29,\n    volume: 81509,\n  },\n  {\n    date: 1462564440000,\n    open: 50.29,\n    high: 50.3,\n    low: 50.28,\n    close: 50.29,\n    volume: 111442,\n  },\n  {\n    date: 1462564500000,\n    open: 50.285,\n    high: 50.32,\n    low: 50.28,\n    close: 50.31,\n    volume: 101394,\n  },\n  {\n    date: 1462564560000,\n    open: 50.31,\n    high: 50.33,\n    low: 50.3,\n    close: 50.325,\n    volume: 130797,\n  },\n  {\n    date: 1462564620000,\n    open: 50.325,\n    high: 50.34,\n    low: 50.31,\n    close: 50.33,\n    volume: 135468,\n  },\n  {\n    date: 1462564680000,\n    open: 50.335,\n    high: 50.34,\n    low: 50.32,\n    close: 50.33,\n    volume: 148279,\n  },\n  {\n    date: 1462564740000,\n    open: 50.33,\n    high: 50.345,\n    low: 50.31,\n    close: 50.3299,\n    volume: 175403,\n  },\n  {\n    date: 1462564800000,\n    open: 50.325,\n    high: 50.39,\n    low: 50.32,\n    close: 50.39,\n    volume: 2080946,\n  },\n  {\n    date: 1462800600000,\n    open: 50.49,\n    high: 50.5,\n    low: 50.45,\n    close: 50.465,\n    volume: 268024,\n  },\n  {\n    date: 1462800660000,\n    open: 50.4501,\n    high: 50.5,\n    low: 50.37,\n    close: 50.37,\n    volume: 98767,\n  },\n  {\n    date: 1462800720000,\n    open: 50.38,\n    high: 50.5,\n    low: 50.37,\n    close: 50.46,\n    volume: 84999,\n  },\n  {\n    date: 1462800780000,\n    open: 50.45,\n    high: 50.47,\n    low: 50.42,\n    close: 50.44,\n    volume: 40236,\n  },\n  {\n    date: 1462800840000,\n    open: 50.45,\n    high: 50.48,\n    low: 50.42,\n    close: 50.48,\n    volume: 43672,\n  },\n  {\n    date: 1462800900000,\n    open: 50.479,\n    high: 50.49,\n    low: 50.43,\n    close: 50.43,\n    volume: 22774,\n  },\n  {\n    date: 1462800960000,\n    open: 50.43,\n    high: 50.43,\n    low: 50.375,\n    close: 50.41,\n    volume: 144331,\n  },\n  {\n    date: 1462801020000,\n    open: 50.41,\n    high: 50.44,\n    low: 50.38,\n    close: 50.44,\n    volume: 85592,\n  },\n  {\n    date: 1462801080000,\n    open: 50.4302,\n    high: 50.46,\n    low: 50.4,\n    close: 50.445,\n    volume: 63865,\n  },\n  {\n    date: 1462801140000,\n    open: 50.45,\n    high: 50.4864,\n    low: 50.4301,\n    close: 50.485,\n    volume: 56008,\n  },\n  {\n    date: 1462801200000,\n    open: 50.485,\n    high: 50.5,\n    low: 50.44,\n    close: 50.44,\n    volume: 61375,\n  },\n  {\n    date: 1462801260000,\n    open: 50.43,\n    high: 50.44,\n    low: 50.36,\n    close: 50.405,\n    volume: 95962,\n  },\n  {\n    date: 1462801320000,\n    open: 50.4056,\n    high: 50.44,\n    low: 50.39,\n    close: 50.4301,\n    volume: 82157,\n  },\n  {\n    date: 1462801380000,\n    open: 50.43,\n    high: 50.43,\n    low: 50.38,\n    close: 50.395,\n    volume: 54126,\n  },\n  {\n    date: 1462801440000,\n    open: 50.405,\n    high: 50.46,\n    low: 50.405,\n    close: 50.46,\n    volume: 76302,\n  },\n  {\n    date: 1462801500000,\n    open: 50.455,\n    high: 50.555,\n    low: 50.455,\n    close: 50.52,\n    volume: 99856,\n  },\n  {\n    date: 1462801560000,\n    open: 50.52,\n    high: 50.578,\n    low: 50.515,\n    close: 50.57,\n    volume: 50054,\n  },\n  {\n    date: 1462801620000,\n    open: 50.57,\n    high: 50.58,\n    low: 50.55,\n    close: 50.56,\n    volume: 55612,\n  },\n  {\n    date: 1462801680000,\n    open: 50.5537,\n    high: 50.56,\n    low: 50.55,\n    close: 50.56,\n    volume: 23403,\n  },\n  {\n    date: 1462801740000,\n    open: 50.56,\n    high: 50.566,\n    low: 50.5,\n    close: 50.5,\n    volume: 50784,\n  },\n  {\n    date: 1462801800000,\n    open: 50.51,\n    high: 50.51,\n    low: 50.43,\n    close: 50.445,\n    volume: 40384,\n  },\n  {\n    date: 1462801860000,\n    open: 50.44,\n    high: 50.48,\n    low: 50.43,\n    close: 50.45,\n    volume: 193895,\n  },\n  {\n    date: 1462801920000,\n    open: 50.45,\n    high: 50.47,\n    low: 50.44,\n    close: 50.455,\n    volume: 35113,\n  },\n  {\n    date: 1462801980000,\n    open: 50.45,\n    high: 50.485,\n    low: 50.44,\n    close: 50.48,\n    volume: 40157,\n  },\n  {\n    date: 1462802040000,\n    open: 50.48,\n    high: 50.54,\n    low: 50.47,\n    close: 50.5062,\n    volume: 64504,\n  },\n  {\n    date: 1462802100000,\n    open: 50.51,\n    high: 50.53,\n    low: 50.46,\n    close: 50.495,\n    volume: 50775,\n  },\n  {\n    date: 1462802160000,\n    open: 50.49,\n    high: 50.51,\n    low: 50.48,\n    close: 50.495,\n    volume: 42529,\n  },\n  {\n    date: 1462802220000,\n    open: 50.49,\n    high: 50.51,\n    low: 50.48,\n    close: 50.5,\n    volume: 24254,\n  },\n  {\n    date: 1462802280000,\n    open: 50.5,\n    high: 50.52,\n    low: 50.49,\n    close: 50.52,\n    volume: 35331,\n  },\n  {\n    date: 1462802340000,\n    open: 50.52,\n    high: 50.52,\n    low: 50.4728,\n    close: 50.49,\n    volume: 45259,\n  },\n  {\n    date: 1462802400000,\n    open: 50.48,\n    high: 50.56,\n    low: 50.48,\n    close: 50.559,\n    volume: 63099,\n  },\n  {\n    date: 1462802460000,\n    open: 50.56,\n    high: 50.56,\n    low: 50.4875,\n    close: 50.4875,\n    volume: 47565,\n  },\n  {\n    date: 1462802520000,\n    open: 50.49,\n    high: 50.5699,\n    low: 50.485,\n    close: 50.545,\n    volume: 42054,\n  },\n  {\n    date: 1462802580000,\n    open: 50.55,\n    high: 50.585,\n    low: 50.5,\n    close: 50.515,\n    volume: 92604,\n  },\n  {\n    date: 1462802640000,\n    open: 50.515,\n    high: 50.54,\n    low: 50.5,\n    close: 50.53,\n    volume: 39381,\n  },\n  {\n    date: 1462802700000,\n    open: 50.53,\n    high: 50.53,\n    low: 50.485,\n    close: 50.5,\n    volume: 29286,\n  },\n  {\n    date: 1462802760000,\n    open: 50.5,\n    high: 50.53,\n    low: 50.5,\n    close: 50.53,\n    volume: 23414,\n  },\n  {\n    date: 1462802820000,\n    open: 50.53,\n    high: 50.555,\n    low: 50.52,\n    close: 50.54,\n    volume: 29356,\n  },\n  {\n    date: 1462802880000,\n    open: 50.5406,\n    high: 50.5406,\n    low: 50.51,\n    close: 50.5235,\n    volume: 30497,\n  },\n  {\n    date: 1462802940000,\n    open: 50.5296,\n    high: 50.55,\n    low: 50.52,\n    close: 50.55,\n    volume: 26241,\n  },\n  {\n    date: 1462803000000,\n    open: 50.55,\n    high: 50.565,\n    low: 50.5363,\n    close: 50.54,\n    volume: 42502,\n  },\n  {\n    date: 1462803060000,\n    open: 50.53,\n    high: 50.54,\n    low: 50.491,\n    close: 50.495,\n    volume: 47817,\n  },\n  {\n    date: 1462803120000,\n    open: 50.49,\n    high: 50.51,\n    low: 50.47,\n    close: 50.5,\n    volume: 48586,\n  },\n  {\n    date: 1462803180000,\n    open: 50.51,\n    high: 50.535,\n    low: 50.48,\n    close: 50.48,\n    volume: 35381,\n  },\n  {\n    date: 1462803240000,\n    open: 50.4899,\n    high: 50.49,\n    low: 50.45,\n    close: 50.46,\n    volume: 44840,\n  },\n  {\n    date: 1462803300000,\n    open: 50.46,\n    high: 50.47,\n    low: 50.45,\n    close: 50.45,\n    volume: 73753,\n  },\n  {\n    date: 1462803360000,\n    open: 50.453,\n    high: 50.48,\n    low: 50.444,\n    close: 50.46,\n    volume: 51535,\n  },\n  {\n    date: 1462803420000,\n    open: 50.45,\n    high: 50.465,\n    low: 50.42,\n    close: 50.435,\n    volume: 51905,\n  },\n  {\n    date: 1462803480000,\n    open: 50.44,\n    high: 50.47,\n    low: 50.43,\n    close: 50.45,\n    volume: 18834,\n  },\n  {\n    date: 1462803540000,\n    open: 50.45,\n    high: 50.45,\n    low: 50.405,\n    close: 50.41,\n    volume: 28096,\n  },\n  {\n    date: 1462803600000,\n    open: 50.4,\n    high: 50.43,\n    low: 50.4,\n    close: 50.415,\n    volume: 52311,\n  },\n  {\n    date: 1462803660000,\n    open: 50.415,\n    high: 50.445,\n    low: 50.4,\n    close: 50.43,\n    volume: 86203,\n  },\n  {\n    date: 1462803720000,\n    open: 50.43,\n    high: 50.45,\n    low: 50.4,\n    close: 50.4,\n    volume: 52002,\n  },\n  {\n    date: 1462803780000,\n    open: 50.4065,\n    high: 50.42,\n    low: 50.39,\n    close: 50.4,\n    volume: 32427,\n  },\n  {\n    date: 1462803840000,\n    open: 50.4,\n    high: 50.4,\n    low: 50.36,\n    close: 50.37,\n    volume: 49522,\n  },\n  {\n    date: 1462803900000,\n    open: 50.37,\n    high: 50.38,\n    low: 50.32,\n    close: 50.32,\n    volume: 65789,\n  },\n  {\n    date: 1462803960000,\n    open: 50.325,\n    high: 50.37,\n    low: 50.3,\n    close: 50.34,\n    volume: 139339,\n  },\n  {\n    date: 1462804020000,\n    open: 50.335,\n    high: 50.35,\n    low: 50.29,\n    close: 50.305,\n    volume: 52789,\n  },\n  {\n    date: 1462804080000,\n    open: 50.31,\n    high: 50.3138,\n    low: 50.295,\n    close: 50.31,\n    volume: 33644,\n  },\n  {\n    date: 1462804140000,\n    open: 50.3062,\n    high: 50.3062,\n    low: 50.25,\n    close: 50.27,\n    volume: 41646,\n  },\n  {\n    date: 1462804200000,\n    open: 50.2655,\n    high: 50.29,\n    low: 50.25,\n    close: 50.27,\n    volume: 28012,\n  },\n  {\n    date: 1462804260000,\n    open: 50.27,\n    high: 50.3,\n    low: 50.245,\n    close: 50.27,\n    volume: 57404,\n  },\n  {\n    date: 1462804320000,\n    open: 50.27,\n    high: 50.31,\n    low: 50.269,\n    close: 50.28,\n    volume: 52753,\n  },\n  {\n    date: 1462804380000,\n    open: 50.27,\n    high: 50.29,\n    low: 50.245,\n    close: 50.255,\n    volume: 46937,\n  },\n  {\n    date: 1462804440000,\n    open: 50.26,\n    high: 50.27,\n    low: 50.245,\n    close: 50.25,\n    volume: 53176,\n  },\n  {\n    date: 1462804500000,\n    open: 50.2501,\n    high: 50.26,\n    low: 50.24,\n    close: 50.25,\n    volume: 38831,\n  },\n  {\n    date: 1462804560000,\n    open: 50.25,\n    high: 50.26,\n    low: 50.23,\n    close: 50.24,\n    volume: 30255,\n  },\n  {\n    date: 1462804620000,\n    open: 50.24,\n    high: 50.25,\n    low: 50.22,\n    close: 50.25,\n    volume: 35470,\n  },\n  {\n    date: 1462804680000,\n    open: 50.245,\n    high: 50.25,\n    low: 50.205,\n    close: 50.205,\n    volume: 32976,\n  },\n  {\n    date: 1462804740000,\n    open: 50.21,\n    high: 50.21,\n    low: 50.15,\n    close: 50.18,\n    volume: 50367,\n  },\n  {\n    date: 1462804800000,\n    open: 50.18,\n    high: 50.19,\n    low: 50.1701,\n    close: 50.18,\n    volume: 30070,\n  },\n  {\n    date: 1462804860000,\n    open: 50.1701,\n    high: 50.185,\n    low: 50.16,\n    close: 50.174,\n    volume: 34189,\n  },\n  {\n    date: 1462804920000,\n    open: 50.17,\n    high: 50.19,\n    low: 50.165,\n    close: 50.18,\n    volume: 41448,\n  },\n  {\n    date: 1462804980000,\n    open: 50.185,\n    high: 50.2,\n    low: 50.17,\n    close: 50.195,\n    volume: 31115,\n  },\n  {\n    date: 1462805040000,\n    open: 50.1999,\n    high: 50.2556,\n    low: 50.195,\n    close: 50.225,\n    volume: 53015,\n  },\n  {\n    date: 1462805100000,\n    open: 50.23,\n    high: 50.23,\n    low: 50.15,\n    close: 50.17,\n    volume: 55536,\n  },\n  {\n    date: 1462805160000,\n    open: 50.17,\n    high: 50.18,\n    low: 50.14,\n    close: 50.14,\n    volume: 46703,\n  },\n  {\n    date: 1462805220000,\n    open: 50.1422,\n    high: 50.17,\n    low: 50.1364,\n    close: 50.15,\n    volume: 40326,\n  },\n  {\n    date: 1462805280000,\n    open: 50.15,\n    high: 50.21,\n    low: 50.15,\n    close: 50.2,\n    volume: 22032,\n  },\n  {\n    date: 1462805340000,\n    open: 50.19,\n    high: 50.2,\n    low: 50.16,\n    close: 50.169,\n    volume: 42096,\n  },\n  {\n    date: 1462805400000,\n    open: 50.16,\n    high: 50.2,\n    low: 50.16,\n    close: 50.19,\n    volume: 34463,\n  },\n  {\n    date: 1462805460000,\n    open: 50.185,\n    high: 50.185,\n    low: 50.17,\n    close: 50.17,\n    volume: 26725,\n  },\n  {\n    date: 1462805520000,\n    open: 50.17,\n    high: 50.18,\n    low: 50.14,\n    close: 50.14,\n    volume: 53171,\n  },\n  {\n    date: 1462805580000,\n    open: 50.1435,\n    high: 50.17,\n    low: 50.14,\n    close: 50.155,\n    volume: 16231,\n  },\n  {\n    date: 1462805640000,\n    open: 50.16,\n    high: 50.17,\n    low: 50.12,\n    close: 50.14,\n    volume: 33912,\n  },\n  {\n    date: 1462805700000,\n    open: 50.1443,\n    high: 50.17,\n    low: 50.125,\n    close: 50.125,\n    volume: 44264,\n  },\n  {\n    date: 1462805760000,\n    open: 50.1375,\n    high: 50.155,\n    low: 50.13,\n    close: 50.145,\n    volume: 30255,\n  },\n  {\n    date: 1462805820000,\n    open: 50.14,\n    high: 50.16,\n    low: 50.1201,\n    close: 50.15,\n    volume: 60770,\n  },\n  {\n    date: 1462805880000,\n    open: 50.15,\n    high: 50.15,\n    low: 50.13,\n    close: 50.13,\n    volume: 18773,\n  },\n  {\n    date: 1462805940000,\n    open: 50.1365,\n    high: 50.15,\n    low: 50.12,\n    close: 50.13,\n    volume: 29964,\n  },\n  {\n    date: 1462806000000,\n    open: 50.125,\n    high: 50.14,\n    low: 50.08,\n    close: 50.11,\n    volume: 62237,\n  },\n  {\n    date: 1462806060000,\n    open: 50.1036,\n    high: 50.11,\n    low: 50.08,\n    close: 50.105,\n    volume: 48449,\n  },\n  {\n    date: 1462806120000,\n    open: 50.1015,\n    high: 50.11,\n    low: 50.08,\n    close: 50.1,\n    volume: 47693,\n  },\n  {\n    date: 1462806180000,\n    open: 50.1,\n    high: 50.16,\n    low: 50.095,\n    close: 50.1323,\n    volume: 45249,\n  },\n  {\n    date: 1462806240000,\n    open: 50.14,\n    high: 50.16,\n    low: 50.13,\n    close: 50.16,\n    volume: 18646,\n  },\n  {\n    date: 1462806300000,\n    open: 50.16,\n    high: 50.17,\n    low: 50.12,\n    close: 50.13,\n    volume: 62803,\n  },\n  {\n    date: 1462806360000,\n    open: 50.1201,\n    high: 50.15,\n    low: 50.11,\n    close: 50.125,\n    volume: 36299,\n  },\n  {\n    date: 1462806420000,\n    open: 50.12,\n    high: 50.15,\n    low: 50.11,\n    close: 50.1101,\n    volume: 36233,\n  },\n  {\n    date: 1462806480000,\n    open: 50.11,\n    high: 50.15,\n    low: 50.1,\n    close: 50.15,\n    volume: 64580,\n  },\n  {\n    date: 1462806540000,\n    open: 50.15,\n    high: 50.19,\n    low: 50.15,\n    close: 50.15,\n    volume: 55459,\n  },\n  {\n    date: 1462806600000,\n    open: 50.15,\n    high: 50.18,\n    low: 50.14,\n    close: 50.15,\n    volume: 33381,\n  },\n  {\n    date: 1462806660000,\n    open: 50.1466,\n    high: 50.16,\n    low: 50.12,\n    close: 50.12,\n    volume: 34237,\n  },\n  {\n    date: 1462806720000,\n    open: 50.12,\n    high: 50.15,\n    low: 50.085,\n    close: 50.085,\n    volume: 55378,\n  },\n  {\n    date: 1462806780000,\n    open: 50.09,\n    high: 50.1,\n    low: 50.05,\n    close: 50.06,\n    volume: 34456,\n  },\n  {\n    date: 1462806840000,\n    open: 50.06,\n    high: 50.065,\n    low: 50,\n    close: 50.01,\n    volume: 140160,\n  },\n  {\n    date: 1462806900000,\n    open: 50.02,\n    high: 50.03,\n    low: 50.01,\n    close: 50.01,\n    volume: 28692,\n  },\n  {\n    date: 1462806960000,\n    open: 50.015,\n    high: 50.03,\n    low: 50,\n    close: 50.03,\n    volume: 30949,\n  },\n  {\n    date: 1462807020000,\n    open: 50.04,\n    high: 50.04,\n    low: 50.01,\n    close: 50.04,\n    volume: 33984,\n  },\n  {\n    date: 1462807080000,\n    open: 50.035,\n    high: 50.05,\n    low: 50.03,\n    close: 50.035,\n    volume: 23169,\n  },\n  {\n    date: 1462807140000,\n    open: 50.03,\n    high: 50.04,\n    low: 50.02,\n    close: 50.035,\n    volume: 35859,\n  },\n  {\n    date: 1462807200000,\n    open: 50.0365,\n    high: 50.07,\n    low: 50.0362,\n    close: 50.065,\n    volume: 36950,\n  },\n  {\n    date: 1462807260000,\n    open: 50.06,\n    high: 50.11,\n    low: 50.06,\n    close: 50.11,\n    volume: 44519,\n  },\n  {\n    date: 1462807320000,\n    open: 50.11,\n    high: 50.11,\n    low: 50.09,\n    close: 50.11,\n    volume: 45582,\n  },\n  {\n    date: 1462807380000,\n    open: 50.11,\n    high: 50.12,\n    low: 50.09,\n    close: 50.1,\n    volume: 39189,\n  },\n  {\n    date: 1462807440000,\n    open: 50.0999,\n    high: 50.12,\n    low: 50.09,\n    close: 50.115,\n    volume: 9395,\n  },\n  {\n    date: 1462807500000,\n    open: 50.11,\n    high: 50.15,\n    low: 50.11,\n    close: 50.149,\n    volume: 45821,\n  },\n  {\n    date: 1462807560000,\n    open: 50.14,\n    high: 50.15,\n    low: 50.13,\n    close: 50.13,\n    volume: 33776,\n  },\n  {\n    date: 1462807620000,\n    open: 50.13,\n    high: 50.17,\n    low: 50.13,\n    close: 50.17,\n    volume: 26763,\n  },\n  {\n    date: 1462807680000,\n    open: 50.17,\n    high: 50.18,\n    low: 50.16,\n    close: 50.1622,\n    volume: 39611,\n  },\n  {\n    date: 1462807740000,\n    open: 50.165,\n    high: 50.19,\n    low: 50.16,\n    close: 50.19,\n    volume: 46253,\n  },\n  {\n    date: 1462807800000,\n    open: 50.185,\n    high: 50.19,\n    low: 50.17,\n    close: 50.175,\n    volume: 62986,\n  },\n  {\n    date: 1462807860000,\n    open: 50.175,\n    high: 50.18,\n    low: 50.16,\n    close: 50.16,\n    volume: 40658,\n  },\n  {\n    date: 1462807920000,\n    open: 50.165,\n    high: 50.17,\n    low: 50.16,\n    close: 50.165,\n    volume: 17397,\n  },\n  {\n    date: 1462807980000,\n    open: 50.17,\n    high: 50.18,\n    low: 50.16,\n    close: 50.16,\n    volume: 37022,\n  },\n  {\n    date: 1462808040000,\n    open: 50.16,\n    high: 50.18,\n    low: 50.14,\n    close: 50.14,\n    volume: 49178,\n  },\n  {\n    date: 1462808100000,\n    open: 50.145,\n    high: 50.185,\n    low: 50.131,\n    close: 50.185,\n    volume: 51915,\n  },\n  {\n    date: 1462808160000,\n    open: 50.185,\n    high: 50.2,\n    low: 50.17,\n    close: 50.2,\n    volume: 23338,\n  },\n  {\n    date: 1462808220000,\n    open: 50.2,\n    high: 50.22,\n    low: 50.2,\n    close: 50.22,\n    volume: 17517,\n  },\n  {\n    date: 1462808280000,\n    open: 50.215,\n    high: 50.218,\n    low: 50.191,\n    close: 50.195,\n    volume: 32422,\n  },\n  {\n    date: 1462808340000,\n    open: 50.19,\n    high: 50.25,\n    low: 50.19,\n    close: 50.24,\n    volume: 34453,\n  },\n  {\n    date: 1462808400000,\n    open: 50.245,\n    high: 50.25,\n    low: 50.23,\n    close: 50.25,\n    volume: 15006,\n  },\n  {\n    date: 1462808460000,\n    open: 50.25,\n    high: 50.26,\n    low: 50.23,\n    close: 50.25,\n    volume: 61230,\n  },\n  {\n    date: 1462808520000,\n    open: 50.245,\n    high: 50.26,\n    low: 50.22,\n    close: 50.24,\n    volume: 30872,\n  },\n  {\n    date: 1462808580000,\n    open: 50.25,\n    high: 50.27,\n    low: 50.24,\n    close: 50.245,\n    volume: 49572,\n  },\n  {\n    date: 1462808640000,\n    open: 50.2475,\n    high: 50.25,\n    low: 50.24,\n    close: 50.245,\n    volume: 12201,\n  },\n  {\n    date: 1462808700000,\n    open: 50.25,\n    high: 50.29,\n    low: 50.245,\n    close: 50.2899,\n    volume: 25287,\n  },\n  {\n    date: 1462808760000,\n    open: 50.29,\n    high: 50.31,\n    low: 50.28,\n    close: 50.3,\n    volume: 24218,\n  },\n  {\n    date: 1462808820000,\n    open: 50.305,\n    high: 50.33,\n    low: 50.305,\n    close: 50.33,\n    volume: 46281,\n  },\n  {\n    date: 1462808880000,\n    open: 50.325,\n    high: 50.34,\n    low: 50.313,\n    close: 50.33,\n    volume: 57446,\n  },\n  {\n    date: 1462808940000,\n    open: 50.33,\n    high: 50.34,\n    low: 50.32,\n    close: 50.34,\n    volume: 20739,\n  },\n  {\n    date: 1462809000000,\n    open: 50.3328,\n    high: 50.34,\n    low: 50.32,\n    close: 50.32,\n    volume: 25937,\n  },\n  {\n    date: 1462809060000,\n    open: 50.32,\n    high: 50.33,\n    low: 50.31,\n    close: 50.33,\n    volume: 26459,\n  },\n  {\n    date: 1462809120000,\n    open: 50.3239,\n    high: 50.345,\n    low: 50.3239,\n    close: 50.34,\n    volume: 42581,\n  },\n  {\n    date: 1462809180000,\n    open: 50.34,\n    high: 50.34,\n    low: 50.3239,\n    close: 50.335,\n    volume: 13971,\n  },\n  {\n    date: 1462809240000,\n    open: 50.335,\n    high: 50.34,\n    low: 50.31,\n    close: 50.3102,\n    volume: 34317,\n  },\n  {\n    date: 1462809300000,\n    open: 50.31,\n    high: 50.3165,\n    low: 50.2501,\n    close: 50.255,\n    volume: 39249,\n  },\n  {\n    date: 1462809360000,\n    open: 50.26,\n    high: 50.26,\n    low: 50.23,\n    close: 50.2334,\n    volume: 15209,\n  },\n  {\n    date: 1462809420000,\n    open: 50.23,\n    high: 50.25,\n    low: 50.23,\n    close: 50.23,\n    volume: 25570,\n  },\n  {\n    date: 1462809480000,\n    open: 50.2365,\n    high: 50.245,\n    low: 50.22,\n    close: 50.23,\n    volume: 23800,\n  },\n  {\n    date: 1462809540000,\n    open: 50.24,\n    high: 50.245,\n    low: 50.23,\n    close: 50.23,\n    volume: 11506,\n  },\n  {\n    date: 1462809600000,\n    open: 50.23,\n    high: 50.245,\n    low: 50.22,\n    close: 50.22,\n    volume: 37831,\n  },\n  {\n    date: 1462809660000,\n    open: 50.21,\n    high: 50.24,\n    low: 50.1901,\n    close: 50.2369,\n    volume: 26341,\n  },\n  {\n    date: 1462809720000,\n    open: 50.235,\n    high: 50.25,\n    low: 50.22,\n    close: 50.22,\n    volume: 23909,\n  },\n  {\n    date: 1462809780000,\n    open: 50.2255,\n    high: 50.24,\n    low: 50.2,\n    close: 50.2,\n    volume: 33018,\n  },\n  {\n    date: 1462809840000,\n    open: 50.205,\n    high: 50.2055,\n    low: 50.18,\n    close: 50.185,\n    volume: 16093,\n  },\n  {\n    date: 1462809900000,\n    open: 50.2,\n    high: 50.21,\n    low: 50.175,\n    close: 50.2,\n    volume: 34403,\n  },\n  {\n    date: 1462809960000,\n    open: 50.209,\n    high: 50.24,\n    low: 50.209,\n    close: 50.23,\n    volume: 25289,\n  },\n  {\n    date: 1462810020000,\n    open: 50.23,\n    high: 50.26,\n    low: 50.225,\n    close: 50.23,\n    volume: 43924,\n  },\n  {\n    date: 1462810080000,\n    open: 50.23,\n    high: 50.23,\n    low: 50.195,\n    close: 50.21,\n    volume: 21493,\n  },\n  {\n    date: 1462810140000,\n    open: 50.215,\n    high: 50.23,\n    low: 50.21,\n    close: 50.215,\n    volume: 79888,\n  },\n  {\n    date: 1462810200000,\n    open: 50.21,\n    high: 50.22,\n    low: 50.17,\n    close: 50.185,\n    volume: 54210,\n  },\n  {\n    date: 1462810260000,\n    open: 50.18,\n    high: 50.19,\n    low: 50.16,\n    close: 50.19,\n    volume: 78090,\n  },\n  {\n    date: 1462810320000,\n    open: 50.1939,\n    high: 50.195,\n    low: 50.17,\n    close: 50.18,\n    volume: 62626,\n  },\n  {\n    date: 1462810380000,\n    open: 50.18,\n    high: 50.1865,\n    low: 50.17,\n    close: 50.18,\n    volume: 24091,\n  },\n  {\n    date: 1462810440000,\n    open: 50.185,\n    high: 50.22,\n    low: 50.185,\n    close: 50.219,\n    volume: 28809,\n  },\n  {\n    date: 1462810500000,\n    open: 50.215,\n    high: 50.23,\n    low: 50.21,\n    close: 50.23,\n    volume: 16443,\n  },\n  {\n    date: 1462810560000,\n    open: 50.23,\n    high: 50.23,\n    low: 50.22,\n    close: 50.2225,\n    volume: 10745,\n  },\n  {\n    date: 1462810620000,\n    open: 50.225,\n    high: 50.25,\n    low: 50.22,\n    close: 50.25,\n    volume: 37532,\n  },\n  {\n    date: 1462810680000,\n    open: 50.245,\n    high: 50.26,\n    low: 50.23,\n    close: 50.2399,\n    volume: 75764,\n  },\n  {\n    date: 1462810740000,\n    open: 50.24,\n    high: 50.26,\n    low: 50.235,\n    close: 50.25,\n    volume: 13311,\n  },\n  {\n    date: 1462810800000,\n    open: 50.25,\n    high: 50.26,\n    low: 50.24,\n    close: 50.25,\n    volume: 40787,\n  },\n  {\n    date: 1462810860000,\n    open: 50.25,\n    high: 50.25,\n    low: 50.23,\n    close: 50.245,\n    volume: 21223,\n  },\n  {\n    date: 1462810920000,\n    open: 50.24,\n    high: 50.29,\n    low: 50.24,\n    close: 50.285,\n    volume: 28423,\n  },\n  {\n    date: 1462810980000,\n    open: 50.29,\n    high: 50.31,\n    low: 50.265,\n    close: 50.27,\n    volume: 43054,\n  },\n  {\n    date: 1462811040000,\n    open: 50.26,\n    high: 50.28,\n    low: 50.25,\n    close: 50.275,\n    volume: 12423,\n  },\n  {\n    date: 1462811100000,\n    open: 50.275,\n    high: 50.29,\n    low: 50.265,\n    close: 50.279,\n    volume: 20163,\n  },\n  {\n    date: 1462811160000,\n    open: 50.28,\n    high: 50.29,\n    low: 50.255,\n    close: 50.26,\n    volume: 16347,\n  },\n  {\n    date: 1462811220000,\n    open: 50.26,\n    high: 50.29,\n    low: 50.255,\n    close: 50.28,\n    volume: 21438,\n  },\n  {\n    date: 1462811280000,\n    open: 50.285,\n    high: 50.29,\n    low: 50.26,\n    close: 50.275,\n    volume: 9384,\n  },\n  {\n    date: 1462811340000,\n    open: 50.28,\n    high: 50.29,\n    low: 50.26,\n    close: 50.29,\n    volume: 13710,\n  },\n  {\n    date: 1462811400000,\n    open: 50.29,\n    high: 50.29,\n    low: 50.24,\n    close: 50.26,\n    volume: 47295,\n  },\n  {\n    date: 1462811460000,\n    open: 50.25,\n    high: 50.26,\n    low: 50.24,\n    close: 50.24,\n    volume: 11596,\n  },\n  {\n    date: 1462811520000,\n    open: 50.249,\n    high: 50.255,\n    low: 50.23,\n    close: 50.23,\n    volume: 16093,\n  },\n  {\n    date: 1462811580000,\n    open: 50.24,\n    high: 50.2465,\n    low: 50.235,\n    close: 50.24,\n    volume: 11040,\n  },\n  {\n    date: 1462811640000,\n    open: 50.2399,\n    high: 50.26,\n    low: 50.2399,\n    close: 50.25,\n    volume: 6065,\n  },\n  {\n    date: 1462811700000,\n    open: 50.25,\n    high: 50.27,\n    low: 50.25,\n    close: 50.26,\n    volume: 17345,\n  },\n  {\n    date: 1462811760000,\n    open: 50.27,\n    high: 50.27,\n    low: 50.23,\n    close: 50.231,\n    volume: 9914,\n  },\n  {\n    date: 1462811820000,\n    open: 50.24,\n    high: 50.25,\n    low: 50.2,\n    close: 50.2,\n    volume: 31098,\n  },\n  {\n    date: 1462811880000,\n    open: 50.21,\n    high: 50.22,\n    low: 50.205,\n    close: 50.21,\n    volume: 6640,\n  },\n  {\n    date: 1462811940000,\n    open: 50.21,\n    high: 50.211,\n    low: 50.2,\n    close: 50.2035,\n    volume: 12735,\n  },\n  {\n    date: 1462812000000,\n    open: 50.2,\n    high: 50.22,\n    low: 50.2,\n    close: 50.21,\n    volume: 12735,\n  },\n  {\n    date: 1462812060000,\n    open: 50.2,\n    high: 50.22,\n    low: 50.19,\n    close: 50.21,\n    volume: 8863,\n  },\n  {\n    date: 1462812120000,\n    open: 50.21,\n    high: 50.22,\n    low: 50.2,\n    close: 50.2,\n    volume: 12138,\n  },\n  {\n    date: 1462812180000,\n    open: 50.21,\n    high: 50.24,\n    low: 50.21,\n    close: 50.236,\n    volume: 10114,\n  },\n  {\n    date: 1462812240000,\n    open: 50.2341,\n    high: 50.25,\n    low: 50.215,\n    close: 50.215,\n    volume: 16384,\n  },\n  {\n    date: 1462812300000,\n    open: 50.214,\n    high: 50.22,\n    low: 50.2,\n    close: 50.21,\n    volume: 14400,\n  },\n  {\n    date: 1462812360000,\n    open: 50.21,\n    high: 50.22,\n    low: 50.19,\n    close: 50.19,\n    volume: 12670,\n  },\n  {\n    date: 1462812420000,\n    open: 50.195,\n    high: 50.23,\n    low: 50.195,\n    close: 50.225,\n    volume: 14106,\n  },\n  {\n    date: 1462812480000,\n    open: 50.22,\n    high: 50.22,\n    low: 50.19,\n    close: 50.22,\n    volume: 21086,\n  },\n  {\n    date: 1462812540000,\n    open: 50.215,\n    high: 50.23,\n    low: 50.21,\n    close: 50.21,\n    volume: 13657,\n  },\n  {\n    date: 1462812600000,\n    open: 50.21,\n    high: 50.235,\n    low: 50.205,\n    close: 50.22,\n    volume: 18041,\n  },\n  {\n    date: 1462812660000,\n    open: 50.22,\n    high: 50.22,\n    low: 50.185,\n    close: 50.19,\n    volume: 25797,\n  },\n  {\n    date: 1462812720000,\n    open: 50.2,\n    high: 50.21,\n    low: 50.19,\n    close: 50.1999,\n    volume: 6407,\n  },\n  {\n    date: 1462812780000,\n    open: 50.195,\n    high: 50.21,\n    low: 50.19,\n    close: 50.19,\n    volume: 17833,\n  },\n  {\n    date: 1462812840000,\n    open: 50.19,\n    high: 50.2,\n    low: 50.1825,\n    close: 50.185,\n    volume: 16202,\n  },\n  {\n    date: 1462812900000,\n    open: 50.19,\n    high: 50.21,\n    low: 50.19,\n    close: 50.1929,\n    volume: 15523,\n  },\n  {\n    date: 1462812960000,\n    open: 50.19,\n    high: 50.2,\n    low: 50.18,\n    close: 50.1965,\n    volume: 14562,\n  },\n  {\n    date: 1462813020000,\n    open: 50.2,\n    high: 50.21,\n    low: 50.2,\n    close: 50.2,\n    volume: 5664,\n  },\n  {\n    date: 1462813080000,\n    open: 50.21,\n    high: 50.23,\n    low: 50.2,\n    close: 50.2,\n    volume: 41173,\n  },\n  {\n    date: 1462813140000,\n    open: 50.2,\n    high: 50.21,\n    low: 50.19,\n    close: 50.19,\n    volume: 6656,\n  },\n  {\n    date: 1462813200000,\n    open: 50.19,\n    high: 50.21,\n    low: 50.19,\n    close: 50.195,\n    volume: 29578,\n  },\n  {\n    date: 1462813260000,\n    open: 50.19,\n    high: 50.19,\n    low: 50.17,\n    close: 50.175,\n    volume: 8274,\n  },\n  {\n    date: 1462813320000,\n    open: 50.18,\n    high: 50.2,\n    low: 50.18,\n    close: 50.2,\n    volume: 10472,\n  },\n  {\n    date: 1462813380000,\n    open: 50.1925,\n    high: 50.2,\n    low: 50.18,\n    close: 50.185,\n    volume: 15411,\n  },\n  {\n    date: 1462813440000,\n    open: 50.19,\n    high: 50.2,\n    low: 50.18,\n    close: 50.1999,\n    volume: 20731,\n  },\n  {\n    date: 1462813500000,\n    open: 50.2,\n    high: 50.205,\n    low: 50.19,\n    close: 50.2,\n    volume: 18982,\n  },\n  {\n    date: 1462813560000,\n    open: 50.2038,\n    high: 50.2099,\n    low: 50.18,\n    close: 50.19,\n    volume: 21553,\n  },\n  {\n    date: 1462813620000,\n    open: 50.19,\n    high: 50.2,\n    low: 50.1825,\n    close: 50.2,\n    volume: 10529,\n  },\n  {\n    date: 1462813680000,\n    open: 50.195,\n    high: 50.21,\n    low: 50.19,\n    close: 50.195,\n    volume: 27138,\n  },\n  {\n    date: 1462813740000,\n    open: 50.2,\n    high: 50.205,\n    low: 50.18,\n    close: 50.185,\n    volume: 55821,\n  },\n  {\n    date: 1462813800000,\n    open: 50.185,\n    high: 50.195,\n    low: 50.18,\n    close: 50.185,\n    volume: 21854,\n  },\n  {\n    date: 1462813860000,\n    open: 50.19,\n    high: 50.2,\n    low: 50.17,\n    close: 50.195,\n    volume: 44912,\n  },\n  {\n    date: 1462813920000,\n    open: 50.195,\n    high: 50.21,\n    low: 50.19,\n    close: 50.21,\n    volume: 15037,\n  },\n  {\n    date: 1462813980000,\n    open: 50.21,\n    high: 50.25,\n    low: 50.21,\n    close: 50.2497,\n    volume: 19634,\n  },\n  {\n    date: 1462814040000,\n    open: 50.25,\n    high: 50.25,\n    low: 50.21,\n    close: 50.21,\n    volume: 35335,\n  },\n  {\n    date: 1462814100000,\n    open: 50.21,\n    high: 50.25,\n    low: 50.2,\n    close: 50.22,\n    volume: 27614,\n  },\n  {\n    date: 1462814160000,\n    open: 50.22,\n    high: 50.25,\n    low: 50.21,\n    close: 50.25,\n    volume: 10778,\n  },\n  {\n    date: 1462814220000,\n    open: 50.25,\n    high: 50.25,\n    low: 50.21,\n    close: 50.23,\n    volume: 33420,\n  },\n  {\n    date: 1462814280000,\n    open: 50.23,\n    high: 50.24,\n    low: 50.22,\n    close: 50.22,\n    volume: 11080,\n  },\n  {\n    date: 1462814340000,\n    open: 50.22,\n    high: 50.2371,\n    low: 50.21,\n    close: 50.2371,\n    volume: 20795,\n  },\n  {\n    date: 1462814400000,\n    open: 50.24,\n    high: 50.25,\n    low: 50.22,\n    close: 50.23,\n    volume: 33223,\n  },\n  {\n    date: 1462814460000,\n    open: 50.23,\n    high: 50.2386,\n    low: 50.19,\n    close: 50.205,\n    volume: 120992,\n  },\n  {\n    date: 1462814520000,\n    open: 50.2038,\n    high: 50.21,\n    low: 50.17,\n    close: 50.1801,\n    volume: 16992,\n  },\n  {\n    date: 1462814580000,\n    open: 50.19,\n    high: 50.21,\n    low: 50.19,\n    close: 50.19,\n    volume: 12490,\n  },\n  {\n    date: 1462814640000,\n    open: 50.1895,\n    high: 50.19,\n    low: 50.18,\n    close: 50.18,\n    volume: 21472,\n  },\n  {\n    date: 1462814700000,\n    open: 50.17,\n    high: 50.18,\n    low: 50.1525,\n    close: 50.155,\n    volume: 30398,\n  },\n  {\n    date: 1462814760000,\n    open: 50.15,\n    high: 50.185,\n    low: 50.15,\n    close: 50.18,\n    volume: 13929,\n  },\n  {\n    date: 1462814820000,\n    open: 50.18,\n    high: 50.18,\n    low: 50.17,\n    close: 50.18,\n    volume: 11681,\n  },\n  {\n    date: 1462814880000,\n    open: 50.18,\n    high: 50.19,\n    low: 50.17,\n    close: 50.18,\n    volume: 25213,\n  },\n  {\n    date: 1462814940000,\n    open: 50.185,\n    high: 50.19,\n    low: 50.18,\n    close: 50.185,\n    volume: 3011,\n  },\n  {\n    date: 1462815000000,\n    open: 50.1801,\n    high: 50.2,\n    low: 50.18,\n    close: 50.2,\n    volume: 12455,\n  },\n  {\n    date: 1462815060000,\n    open: 50.2,\n    high: 50.22,\n    low: 50.19,\n    close: 50.22,\n    volume: 47959,\n  },\n  {\n    date: 1462815120000,\n    open: 50.22,\n    high: 50.24,\n    low: 50.2125,\n    close: 50.24,\n    volume: 8731,\n  },\n  {\n    date: 1462815180000,\n    open: 50.24,\n    high: 50.24,\n    low: 50.21,\n    close: 50.22,\n    volume: 23471,\n  },\n  {\n    date: 1462815240000,\n    open: 50.22,\n    high: 50.225,\n    low: 50.2,\n    close: 50.225,\n    volume: 12473,\n  },\n  {\n    date: 1462815300000,\n    open: 50.22,\n    high: 50.225,\n    low: 50.2,\n    close: 50.21,\n    volume: 19823,\n  },\n  {\n    date: 1462815360000,\n    open: 50.21,\n    high: 50.231,\n    low: 50.21,\n    close: 50.23,\n    volume: 15396,\n  },\n  {\n    date: 1462815420000,\n    open: 50.23,\n    high: 50.24,\n    low: 50.22,\n    close: 50.2201,\n    volume: 13023,\n  },\n  {\n    date: 1462815480000,\n    open: 50.22,\n    high: 50.2256,\n    low: 50.2,\n    close: 50.2035,\n    volume: 10413,\n  },\n  {\n    date: 1462815540000,\n    open: 50.2,\n    high: 50.22,\n    low: 50.18,\n    close: 50.203,\n    volume: 21833,\n  },\n  {\n    date: 1462815600000,\n    open: 50.2,\n    high: 50.2,\n    low: 50.155,\n    close: 50.18,\n    volume: 18819,\n  },\n  {\n    date: 1462815660000,\n    open: 50.1899,\n    high: 50.2,\n    low: 50.1801,\n    close: 50.2,\n    volume: 9635,\n  },\n  {\n    date: 1462815720000,\n    open: 50.2,\n    high: 50.2,\n    low: 50.175,\n    close: 50.18,\n    volume: 29953,\n  },\n  {\n    date: 1462815780000,\n    open: 50.18,\n    high: 50.19,\n    low: 50.18,\n    close: 50.19,\n    volume: 10349,\n  },\n  {\n    date: 1462815840000,\n    open: 50.1984,\n    high: 50.22,\n    low: 50.195,\n    close: 50.2199,\n    volume: 8027,\n  },\n  {\n    date: 1462815900000,\n    open: 50.21,\n    high: 50.22,\n    low: 50.2,\n    close: 50.2,\n    volume: 12478,\n  },\n  {\n    date: 1462815960000,\n    open: 50.204,\n    high: 50.21,\n    low: 50.18,\n    close: 50.19,\n    volume: 21358,\n  },\n  {\n    date: 1462816020000,\n    open: 50.2,\n    high: 50.22,\n    low: 50.19,\n    close: 50.22,\n    volume: 10537,\n  },\n  {\n    date: 1462816080000,\n    open: 50.22,\n    high: 50.23,\n    low: 50.203,\n    close: 50.21,\n    volume: 16403,\n  },\n  {\n    date: 1462816140000,\n    open: 50.21,\n    high: 50.21,\n    low: 50.2,\n    close: 50.2,\n    volume: 4499,\n  },\n  {\n    date: 1462816200000,\n    open: 50.2,\n    high: 50.23,\n    low: 50.19,\n    close: 50.22,\n    volume: 48077,\n  },\n  {\n    date: 1462816260000,\n    open: 50.22,\n    high: 50.23,\n    low: 50.21,\n    close: 50.215,\n    volume: 14658,\n  },\n  {\n    date: 1462816320000,\n    open: 50.21,\n    high: 50.2265,\n    low: 50.2,\n    close: 50.21,\n    volume: 17153,\n  },\n  {\n    date: 1462816380000,\n    open: 50.215,\n    high: 50.23,\n    low: 50.21,\n    close: 50.2139,\n    volume: 8603,\n  },\n  {\n    date: 1462816440000,\n    open: 50.21,\n    high: 50.21,\n    low: 50.195,\n    close: 50.2068,\n    volume: 36870,\n  },\n  {\n    date: 1462816500000,\n    open: 50.2,\n    high: 50.21,\n    low: 50.195,\n    close: 50.2,\n    volume: 36591,\n  },\n  {\n    date: 1462816560000,\n    open: 50.2,\n    high: 50.2,\n    low: 50.16,\n    close: 50.16,\n    volume: 20438,\n  },\n  {\n    date: 1462816620000,\n    open: 50.16,\n    high: 50.178,\n    low: 50.16,\n    close: 50.17,\n    volume: 27944,\n  },\n  {\n    date: 1462816680000,\n    open: 50.16,\n    high: 50.17,\n    low: 50.15,\n    close: 50.157,\n    volume: 32668,\n  },\n  {\n    date: 1462816740000,\n    open: 50.16,\n    high: 50.16,\n    low: 50.15,\n    close: 50.15,\n    volume: 20502,\n  },\n  {\n    date: 1462816800000,\n    open: 50.16,\n    high: 50.16,\n    low: 50.15,\n    close: 50.1559,\n    volume: 16161,\n  },\n  {\n    date: 1462816860000,\n    open: 50.1538,\n    high: 50.2,\n    low: 50.15,\n    close: 50.1801,\n    volume: 48700,\n  },\n  {\n    date: 1462816920000,\n    open: 50.19,\n    high: 50.19,\n    low: 50.17,\n    close: 50.19,\n    volume: 11268,\n  },\n  {\n    date: 1462816980000,\n    open: 50.181,\n    high: 50.19,\n    low: 50.18,\n    close: 50.184,\n    volume: 8114,\n  },\n  {\n    date: 1462817040000,\n    open: 50.19,\n    high: 50.19,\n    low: 50.16,\n    close: 50.165,\n    volume: 32682,\n  },\n  {\n    date: 1462817100000,\n    open: 50.17,\n    high: 50.179,\n    low: 50.1569,\n    close: 50.16,\n    volume: 15476,\n  },\n  {\n    date: 1462817160000,\n    open: 50.17,\n    high: 50.17,\n    low: 50.145,\n    close: 50.151,\n    volume: 47463,\n  },\n  {\n    date: 1462817220000,\n    open: 50.16,\n    high: 50.17,\n    low: 50.1339,\n    close: 50.15,\n    volume: 30266,\n  },\n  {\n    date: 1462817280000,\n    open: 50.15,\n    high: 50.16,\n    low: 50.12,\n    close: 50.15,\n    volume: 37390,\n  },\n  {\n    date: 1462817340000,\n    open: 50.15,\n    high: 50.155,\n    low: 50.11,\n    close: 50.125,\n    volume: 30095,\n  },\n  {\n    date: 1462817400000,\n    open: 50.13,\n    high: 50.155,\n    low: 50.125,\n    close: 50.15,\n    volume: 25665,\n  },\n  {\n    date: 1462817460000,\n    open: 50.14,\n    high: 50.145,\n    low: 50.1,\n    close: 50.103,\n    volume: 102003,\n  },\n  {\n    date: 1462817520000,\n    open: 50.11,\n    high: 50.119,\n    low: 50.09,\n    close: 50.1011,\n    volume: 28249,\n  },\n  {\n    date: 1462817580000,\n    open: 50.1,\n    high: 50.115,\n    low: 50.09,\n    close: 50.107,\n    volume: 33701,\n  },\n  {\n    date: 1462817640000,\n    open: 50.11,\n    high: 50.135,\n    low: 50.1,\n    close: 50.135,\n    volume: 31307,\n  },\n  {\n    date: 1462817700000,\n    open: 50.13,\n    high: 50.135,\n    low: 50.12,\n    close: 50.12,\n    volume: 19125,\n  },\n  {\n    date: 1462817760000,\n    open: 50.1299,\n    high: 50.13,\n    low: 50.1,\n    close: 50.11,\n    volume: 41294,\n  },\n  {\n    date: 1462817820000,\n    open: 50.1,\n    high: 50.11,\n    low: 50.0684,\n    close: 50.0839,\n    volume: 46052,\n  },\n  {\n    date: 1462817880000,\n    open: 50.08,\n    high: 50.09,\n    low: 50.08,\n    close: 50.0841,\n    volume: 5803,\n  },\n  {\n    date: 1462817940000,\n    open: 50.09,\n    high: 50.11,\n    low: 50.082,\n    close: 50.11,\n    volume: 24551,\n  },\n  {\n    date: 1462818000000,\n    open: 50.11,\n    high: 50.13,\n    low: 50.1,\n    close: 50.12,\n    volume: 24514,\n  },\n  {\n    date: 1462818060000,\n    open: 50.125,\n    high: 50.125,\n    low: 50.11,\n    close: 50.12,\n    volume: 13233,\n  },\n  {\n    date: 1462818120000,\n    open: 50.12,\n    high: 50.15,\n    low: 50.12,\n    close: 50.14,\n    volume: 29266,\n  },\n  {\n    date: 1462818180000,\n    open: 50.14,\n    high: 50.15,\n    low: 50.13,\n    close: 50.15,\n    volume: 10644,\n  },\n  {\n    date: 1462818240000,\n    open: 50.145,\n    high: 50.15,\n    low: 50.14,\n    close: 50.145,\n    volume: 17487,\n  },\n  {\n    date: 1462818300000,\n    open: 50.14,\n    high: 50.14,\n    low: 50.12,\n    close: 50.135,\n    volume: 45880,\n  },\n  {\n    date: 1462818360000,\n    open: 50.135,\n    high: 50.16,\n    low: 50.13,\n    close: 50.145,\n    volume: 16731,\n  },\n  {\n    date: 1462818420000,\n    open: 50.15,\n    high: 50.17,\n    low: 50.145,\n    close: 50.17,\n    volume: 11674,\n  },\n  {\n    date: 1462818480000,\n    open: 50.165,\n    high: 50.175,\n    low: 50.16,\n    close: 50.17,\n    volume: 15846,\n  },\n  {\n    date: 1462818540000,\n    open: 50.1665,\n    high: 50.175,\n    low: 50.14,\n    close: 50.15,\n    volume: 37426,\n  },\n  {\n    date: 1462818600000,\n    open: 50.153,\n    high: 50.17,\n    low: 50.15,\n    close: 50.1636,\n    volume: 21379,\n  },\n  {\n    date: 1462818660000,\n    open: 50.16,\n    high: 50.19,\n    low: 50.16,\n    close: 50.17,\n    volume: 39598,\n  },\n  {\n    date: 1462818720000,\n    open: 50.17,\n    high: 50.18,\n    low: 50.1605,\n    close: 50.18,\n    volume: 16904,\n  },\n  {\n    date: 1462818780000,\n    open: 50.175,\n    high: 50.1799,\n    low: 50.16,\n    close: 50.1672,\n    volume: 22340,\n  },\n  {\n    date: 1462818840000,\n    open: 50.162,\n    high: 50.19,\n    low: 50.16,\n    close: 50.1841,\n    volume: 19267,\n  },\n  {\n    date: 1462818900000,\n    open: 50.187,\n    high: 50.19,\n    low: 50.16,\n    close: 50.16,\n    volume: 18647,\n  },\n  {\n    date: 1462818960000,\n    open: 50.16,\n    high: 50.22,\n    low: 50.16,\n    close: 50.19,\n    volume: 148490,\n  },\n  {\n    date: 1462819020000,\n    open: 50.2,\n    high: 50.2,\n    low: 50.175,\n    close: 50.2,\n    volume: 20827,\n  },\n  {\n    date: 1462819080000,\n    open: 50.2,\n    high: 50.205,\n    low: 50.19,\n    close: 50.205,\n    volume: 11610,\n  },\n  {\n    date: 1462819140000,\n    open: 50.205,\n    high: 50.23,\n    low: 50.2,\n    close: 50.21,\n    volume: 20157,\n  },\n  {\n    date: 1462819200000,\n    open: 50.21,\n    high: 50.23,\n    low: 50.205,\n    close: 50.21,\n    volume: 21672,\n  },\n  {\n    date: 1462819260000,\n    open: 50.21,\n    high: 50.22,\n    low: 50.1901,\n    close: 50.21,\n    volume: 18191,\n  },\n  {\n    date: 1462819320000,\n    open: 50.219,\n    high: 50.23,\n    low: 50.21,\n    close: 50.225,\n    volume: 8274,\n  },\n  {\n    date: 1462819380000,\n    open: 50.22,\n    high: 50.225,\n    low: 50.205,\n    close: 50.21,\n    volume: 55640,\n  },\n  {\n    date: 1462819440000,\n    open: 50.21,\n    high: 50.22,\n    low: 50.21,\n    close: 50.21,\n    volume: 14738,\n  },\n  {\n    date: 1462819500000,\n    open: 50.21,\n    high: 50.225,\n    low: 50.21,\n    close: 50.2201,\n    volume: 15155,\n  },\n  {\n    date: 1462819560000,\n    open: 50.225,\n    high: 50.2399,\n    low: 50.225,\n    close: 50.2299,\n    volume: 14564,\n  },\n  {\n    date: 1462819620000,\n    open: 50.23,\n    high: 50.24,\n    low: 50.225,\n    close: 50.235,\n    volume: 9300,\n  },\n  {\n    date: 1462819680000,\n    open: 50.235,\n    high: 50.235,\n    low: 50.22,\n    close: 50.2265,\n    volume: 10891,\n  },\n  {\n    date: 1462819740000,\n    open: 50.23,\n    high: 50.24,\n    low: 50.2235,\n    close: 50.23,\n    volume: 14093,\n  },\n  {\n    date: 1462819800000,\n    open: 50.23,\n    high: 50.24,\n    low: 50.22,\n    close: 50.2241,\n    volume: 27996,\n  },\n  {\n    date: 1462819860000,\n    open: 50.23,\n    high: 50.27,\n    low: 50.22,\n    close: 50.251,\n    volume: 28463,\n  },\n  {\n    date: 1462819920000,\n    open: 50.25,\n    high: 50.29,\n    low: 50.24,\n    close: 50.285,\n    volume: 38923,\n  },\n  {\n    date: 1462819980000,\n    open: 50.285,\n    high: 50.3,\n    low: 50.26,\n    close: 50.27,\n    volume: 24015,\n  },\n  {\n    date: 1462820040000,\n    open: 50.27,\n    high: 50.27,\n    low: 50.24,\n    close: 50.26,\n    volume: 38577,\n  },\n  {\n    date: 1462820100000,\n    open: 50.2638,\n    high: 50.28,\n    low: 50.2638,\n    close: 50.27,\n    volume: 12102,\n  },\n  {\n    date: 1462820160000,\n    open: 50.27,\n    high: 50.3,\n    low: 50.27,\n    close: 50.2799,\n    volume: 45255,\n  },\n  {\n    date: 1462820220000,\n    open: 50.28,\n    high: 50.3,\n    low: 50.28,\n    close: 50.3,\n    volume: 22203,\n  },\n  {\n    date: 1462820280000,\n    open: 50.295,\n    high: 50.297,\n    low: 50.279,\n    close: 50.29,\n    volume: 28511,\n  },\n  {\n    date: 1462820340000,\n    open: 50.2861,\n    high: 50.3,\n    low: 50.285,\n    close: 50.3,\n    volume: 23349,\n  },\n  {\n    date: 1462820400000,\n    open: 50.3,\n    high: 50.305,\n    low: 50.28,\n    close: 50.29,\n    volume: 44903,\n  },\n  {\n    date: 1462820460000,\n    open: 50.3,\n    high: 50.3,\n    low: 50.29,\n    close: 50.2972,\n    volume: 7334,\n  },\n  {\n    date: 1462820520000,\n    open: 50.2966,\n    high: 50.2966,\n    low: 50.26,\n    close: 50.269,\n    volume: 35491,\n  },\n  {\n    date: 1462820580000,\n    open: 50.2699,\n    high: 50.27,\n    low: 50.25,\n    close: 50.26,\n    volume: 29714,\n  },\n  {\n    date: 1462820640000,\n    open: 50.26,\n    high: 50.2799,\n    low: 50.25,\n    close: 50.25,\n    volume: 23658,\n  },\n  {\n    date: 1462820700000,\n    open: 50.26,\n    high: 50.2667,\n    low: 50.235,\n    close: 50.245,\n    volume: 43387,\n  },\n  {\n    date: 1462820760000,\n    open: 50.245,\n    high: 50.245,\n    low: 50.22,\n    close: 50.225,\n    volume: 17617,\n  },\n  {\n    date: 1462820820000,\n    open: 50.2239,\n    high: 50.23,\n    low: 50.2,\n    close: 50.205,\n    volume: 24717,\n  },\n  {\n    date: 1462820880000,\n    open: 50.205,\n    high: 50.229,\n    low: 50.2,\n    close: 50.2067,\n    volume: 32308,\n  },\n  {\n    date: 1462820940000,\n    open: 50.205,\n    high: 50.21,\n    low: 50.175,\n    close: 50.18,\n    volume: 41011,\n  },\n  {\n    date: 1462821000000,\n    open: 50.18,\n    high: 50.2,\n    low: 50.17,\n    close: 50.185,\n    volume: 39722,\n  },\n  {\n    date: 1462821060000,\n    open: 50.19,\n    high: 50.2,\n    low: 50.18,\n    close: 50.1865,\n    volume: 32239,\n  },\n  {\n    date: 1462821120000,\n    open: 50.195,\n    high: 50.21,\n    low: 50.185,\n    close: 50.21,\n    volume: 15385,\n  },\n  {\n    date: 1462821180000,\n    open: 50.205,\n    high: 50.23,\n    low: 50.2001,\n    close: 50.2201,\n    volume: 13856,\n  },\n  {\n    date: 1462821240000,\n    open: 50.229,\n    high: 50.23,\n    low: 50.205,\n    close: 50.21,\n    volume: 29122,\n  },\n  {\n    date: 1462821300000,\n    open: 50.22,\n    high: 50.225,\n    low: 50.19,\n    close: 50.2,\n    volume: 30063,\n  },\n  {\n    date: 1462821360000,\n    open: 50.21,\n    high: 50.215,\n    low: 50.18,\n    close: 50.186,\n    volume: 59471,\n  },\n  {\n    date: 1462821420000,\n    open: 50.19,\n    high: 50.215,\n    low: 50.18,\n    close: 50.21,\n    volume: 25830,\n  },\n  {\n    date: 1462821480000,\n    open: 50.21,\n    high: 50.21,\n    low: 50.18,\n    close: 50.18,\n    volume: 31859,\n  },\n  {\n    date: 1462821540000,\n    open: 50.19,\n    high: 50.2,\n    low: 50.185,\n    close: 50.195,\n    volume: 20103,\n  },\n  {\n    date: 1462821600000,\n    open: 50.2,\n    high: 50.21,\n    low: 50.186,\n    close: 50.2,\n    volume: 31486,\n  },\n  {\n    date: 1462821660000,\n    open: 50.199,\n    high: 50.22,\n    low: 50.19,\n    close: 50.215,\n    volume: 43336,\n  },\n  {\n    date: 1462821720000,\n    open: 50.2121,\n    high: 50.215,\n    low: 50.19,\n    close: 50.215,\n    volume: 41940,\n  },\n  {\n    date: 1462821780000,\n    open: 50.212,\n    high: 50.23,\n    low: 50.21,\n    close: 50.23,\n    volume: 34273,\n  },\n  {\n    date: 1462821840000,\n    open: 50.23,\n    high: 50.24,\n    low: 50.224,\n    close: 50.23,\n    volume: 20454,\n  },\n  {\n    date: 1462821900000,\n    open: 50.2399,\n    high: 50.245,\n    low: 50.23,\n    close: 50.24,\n    volume: 32701,\n  },\n  {\n    date: 1462821960000,\n    open: 50.23,\n    high: 50.25,\n    low: 50.23,\n    close: 50.24,\n    volume: 24572,\n  },\n  {\n    date: 1462822020000,\n    open: 50.25,\n    high: 50.25,\n    low: 50.22,\n    close: 50.225,\n    volume: 36546,\n  },\n  {\n    date: 1462822080000,\n    open: 50.22,\n    high: 50.2382,\n    low: 50.22,\n    close: 50.22,\n    volume: 33234,\n  },\n  {\n    date: 1462822140000,\n    open: 50.225,\n    high: 50.24,\n    low: 50.21,\n    close: 50.2299,\n    volume: 49938,\n  },\n  {\n    date: 1462822200000,\n    open: 50.23,\n    high: 50.23,\n    low: 50.19,\n    close: 50.205,\n    volume: 24154,\n  },\n  {\n    date: 1462822260000,\n    open: 50.21,\n    high: 50.24,\n    low: 50.19,\n    close: 50.19,\n    volume: 45467,\n  },\n  {\n    date: 1462822320000,\n    open: 50.195,\n    high: 50.205,\n    low: 50.18,\n    close: 50.185,\n    volume: 31527,\n  },\n  {\n    date: 1462822380000,\n    open: 50.18,\n    high: 50.18,\n    low: 50.16,\n    close: 50.1601,\n    volume: 28069,\n  },\n  {\n    date: 1462822440000,\n    open: 50.16,\n    high: 50.16,\n    low: 50.13,\n    close: 50.135,\n    volume: 34898,\n  },\n  {\n    date: 1462822500000,\n    open: 50.13,\n    high: 50.155,\n    low: 50.13,\n    close: 50.15,\n    volume: 42807,\n  },\n  {\n    date: 1462822560000,\n    open: 50.15,\n    high: 50.18,\n    low: 50.15,\n    close: 50.175,\n    volume: 49295,\n  },\n  {\n    date: 1462822620000,\n    open: 50.178,\n    high: 50.18,\n    low: 50.12,\n    close: 50.169,\n    volume: 104829,\n  },\n  {\n    date: 1462822680000,\n    open: 50.1659,\n    high: 50.18,\n    low: 50.15,\n    close: 50.15,\n    volume: 26771,\n  },\n  {\n    date: 1462822740000,\n    open: 50.15,\n    high: 50.185,\n    low: 50.15,\n    close: 50.165,\n    volume: 47885,\n  },\n  {\n    date: 1462822800000,\n    open: 50.16,\n    high: 50.18,\n    low: 50.16,\n    close: 50.16,\n    volume: 26401,\n  },\n  {\n    date: 1462822860000,\n    open: 50.164,\n    high: 50.18,\n    low: 50.16,\n    close: 50.165,\n    volume: 40975,\n  },\n  {\n    date: 1462822920000,\n    open: 50.17,\n    high: 50.18,\n    low: 50.1686,\n    close: 50.175,\n    volume: 37874,\n  },\n  {\n    date: 1462822980000,\n    open: 50.1721,\n    high: 50.195,\n    low: 50.17,\n    close: 50.19,\n    volume: 43000,\n  },\n  {\n    date: 1462823040000,\n    open: 50.19,\n    high: 50.19,\n    low: 50.16,\n    close: 50.17,\n    volume: 48367,\n  },\n  {\n    date: 1462823100000,\n    open: 50.1692,\n    high: 50.175,\n    low: 50.13,\n    close: 50.13,\n    volume: 72425,\n  },\n  {\n    date: 1462823160000,\n    open: 50.135,\n    high: 50.19,\n    low: 50.1301,\n    close: 50.16,\n    volume: 72628,\n  },\n  {\n    date: 1462823220000,\n    open: 50.16,\n    high: 50.2,\n    low: 50.16,\n    close: 50.175,\n    volume: 57663,\n  },\n  {\n    date: 1462823280000,\n    open: 50.1701,\n    high: 50.18,\n    low: 50.17,\n    close: 50.18,\n    volume: 19370,\n  },\n  {\n    date: 1462823340000,\n    open: 50.17,\n    high: 50.19,\n    low: 50.16,\n    close: 50.185,\n    volume: 84062,\n  },\n  {\n    date: 1462823400000,\n    open: 50.18,\n    high: 50.19,\n    low: 50.14,\n    close: 50.145,\n    volume: 66360,\n  },\n  {\n    date: 1462823460000,\n    open: 50.14,\n    high: 50.15,\n    low: 50.12,\n    close: 50.125,\n    volume: 47712,\n  },\n  {\n    date: 1462823520000,\n    open: 50.12,\n    high: 50.13,\n    low: 50.1,\n    close: 50.12,\n    volume: 47713,\n  },\n  {\n    date: 1462823580000,\n    open: 50.12,\n    high: 50.12,\n    low: 50.085,\n    close: 50.085,\n    volume: 43748,\n  },\n  {\n    date: 1462823640000,\n    open: 50.09,\n    high: 50.1,\n    low: 50.08,\n    close: 50.1,\n    volume: 23085,\n  },\n  {\n    date: 1462823700000,\n    open: 50.1,\n    high: 50.11,\n    low: 50.06,\n    close: 50.08,\n    volume: 85834,\n  },\n  {\n    date: 1462823760000,\n    open: 50.075,\n    high: 50.085,\n    low: 50.06,\n    close: 50.085,\n    volume: 90944,\n  },\n  {\n    date: 1462823820000,\n    open: 50.075,\n    high: 50.085,\n    low: 50.07,\n    close: 50.075,\n    volume: 82769,\n  },\n  {\n    date: 1462823880000,\n    open: 50.075,\n    high: 50.08,\n    low: 50.06,\n    close: 50.07,\n    volume: 60284,\n  },\n  {\n    date: 1462823940000,\n    open: 50.07,\n    high: 50.08,\n    low: 50.07,\n    close: 50.075,\n    volume: 83370,\n  },\n  {\n    date: 1462824000000,\n    open: 50.08,\n    high: 50.11,\n    low: 50.07,\n    close: 50.07,\n    volume: 2126916,\n  },\n  {\n    date: 1462887000000,\n    open: 50.33,\n    high: 50.37,\n    low: 50.3,\n    close: 50.31,\n    volume: 251148,\n  },\n  {\n    date: 1462887060000,\n    open: 50.35,\n    high: 50.48,\n    low: 50.26,\n    close: 50.37,\n    volume: 127320,\n  },\n  {\n    date: 1462887120000,\n    open: 50.36,\n    high: 50.43,\n    low: 50.35,\n    close: 50.35,\n    volume: 107909,\n  },\n  {\n    date: 1462887180000,\n    open: 50.3599,\n    high: 50.37,\n    low: 50.29,\n    close: 50.37,\n    volume: 68303,\n  },\n  {\n    date: 1462887240000,\n    open: 50.3715,\n    high: 50.43,\n    low: 50.34,\n    close: 50.41,\n    volume: 47964,\n  },\n  {\n    date: 1462887300000,\n    open: 50.4,\n    high: 50.48,\n    low: 50.38,\n    close: 50.47,\n    volume: 52319,\n  },\n  {\n    date: 1462887360000,\n    open: 50.48,\n    high: 50.51,\n    low: 50.4,\n    close: 50.42,\n    volume: 124822,\n  },\n  {\n    date: 1462887420000,\n    open: 50.42,\n    high: 50.43,\n    low: 50.36,\n    close: 50.38,\n    volume: 36982,\n  },\n  {\n    date: 1462887480000,\n    open: 50.38,\n    high: 50.41,\n    low: 50.35,\n    close: 50.375,\n    volume: 61035,\n  },\n  {\n    date: 1462887540000,\n    open: 50.3801,\n    high: 50.3801,\n    low: 50.26,\n    close: 50.26,\n    volume: 64909,\n  },\n  {\n    date: 1462887600000,\n    open: 50.26,\n    high: 50.27,\n    low: 50.19,\n    close: 50.22,\n    volume: 93210,\n  },\n  {\n    date: 1462887660000,\n    open: 50.229,\n    high: 50.28,\n    low: 50.21,\n    close: 50.2365,\n    volume: 66661,\n  },\n  {\n    date: 1462887720000,\n    open: 50.2399,\n    high: 50.28,\n    low: 50.22,\n    close: 50.28,\n    volume: 37301,\n  },\n  {\n    date: 1462887780000,\n    open: 50.27,\n    high: 50.27,\n    low: 50.2162,\n    close: 50.24,\n    volume: 58652,\n  },\n  {\n    date: 1462887840000,\n    open: 50.23,\n    high: 50.37,\n    low: 50.195,\n    close: 50.35,\n    volume: 96471,\n  },\n  {\n    date: 1462887900000,\n    open: 50.34,\n    high: 50.42,\n    low: 50.32,\n    close: 50.38,\n    volume: 110458,\n  },\n  {\n    date: 1462887960000,\n    open: 50.3793,\n    high: 50.42,\n    low: 50.36,\n    close: 50.38,\n    volume: 112330,\n  },\n  {\n    date: 1462888020000,\n    open: 50.4,\n    high: 50.42,\n    low: 50.38,\n    close: 50.38,\n    volume: 65790,\n  },\n  {\n    date: 1462888080000,\n    open: 50.3899,\n    high: 50.44,\n    low: 50.38,\n    close: 50.43,\n    volume: 28327,\n  },\n  {\n    date: 1462888140000,\n    open: 50.43,\n    high: 50.49,\n    low: 50.43,\n    close: 50.46,\n    volume: 56625,\n  },\n  {\n    date: 1462888200000,\n    open: 50.46,\n    high: 50.49,\n    low: 50.435,\n    close: 50.4833,\n    volume: 37670,\n  },\n  {\n    date: 1462888260000,\n    open: 50.48,\n    high: 50.54,\n    low: 50.45,\n    close: 50.5001,\n    volume: 85293,\n  },\n  {\n    date: 1462888320000,\n    open: 50.5,\n    high: 50.54,\n    low: 50.47,\n    close: 50.531,\n    volume: 41962,\n  },\n  {\n    date: 1462888380000,\n    open: 50.535,\n    high: 50.56,\n    low: 50.53,\n    close: 50.545,\n    volume: 77431,\n  },\n  {\n    date: 1462888440000,\n    open: 50.545,\n    high: 50.57,\n    low: 50.51,\n    close: 50.53,\n    volume: 73751,\n  },\n  {\n    date: 1462888500000,\n    open: 50.529,\n    high: 50.55,\n    low: 50.52,\n    close: 50.545,\n    volume: 96138,\n  },\n  {\n    date: 1462888560000,\n    open: 50.55,\n    high: 50.55,\n    low: 50.52,\n    close: 50.525,\n    volume: 41258,\n  },\n  {\n    date: 1462888620000,\n    open: 50.53,\n    high: 50.54,\n    low: 50.47,\n    close: 50.47,\n    volume: 77159,\n  },\n  {\n    date: 1462888680000,\n    open: 50.465,\n    high: 50.47,\n    low: 50.42,\n    close: 50.42,\n    volume: 44324,\n  },\n  {\n    date: 1462888740000,\n    open: 50.42,\n    high: 50.44,\n    low: 50.41,\n    close: 50.42,\n    volume: 83607,\n  },\n  {\n    date: 1462888800000,\n    open: 50.43,\n    high: 50.43,\n    low: 50.37,\n    close: 50.38,\n    volume: 77456,\n  },\n  {\n    date: 1462888860000,\n    open: 50.38,\n    high: 50.39,\n    low: 50.36,\n    close: 50.37,\n    volume: 40612,\n  },\n  {\n    date: 1462888920000,\n    open: 50.375,\n    high: 50.38,\n    low: 50.36,\n    close: 50.375,\n    volume: 32756,\n  },\n  {\n    date: 1462888980000,\n    open: 50.3799,\n    high: 50.41,\n    low: 50.36,\n    close: 50.41,\n    volume: 59584,\n  },\n  {\n    date: 1462889040000,\n    open: 50.41,\n    high: 50.45,\n    low: 50.41,\n    close: 50.44,\n    volume: 33073,\n  },\n  {\n    date: 1462889100000,\n    open: 50.44,\n    high: 50.44,\n    low: 50.39,\n    close: 50.3911,\n    volume: 38063,\n  },\n  {\n    date: 1462889160000,\n    open: 50.39,\n    high: 50.4,\n    low: 50.36,\n    close: 50.39,\n    volume: 33355,\n  },\n  {\n    date: 1462889220000,\n    open: 50.39,\n    high: 50.43,\n    low: 50.39,\n    close: 50.405,\n    volume: 46611,\n  },\n  {\n    date: 1462889280000,\n    open: 50.405,\n    high: 50.44,\n    low: 50.4,\n    close: 50.42,\n    volume: 34186,\n  },\n  {\n    date: 1462889340000,\n    open: 50.41,\n    high: 50.42,\n    low: 50.3901,\n    close: 50.41,\n    volume: 47510,\n  },\n  {\n    date: 1462889400000,\n    open: 50.4066,\n    high: 50.4066,\n    low: 50.355,\n    close: 50.37,\n    volume: 58201,\n  },\n  {\n    date: 1462889460000,\n    open: 50.37,\n    high: 50.41,\n    low: 50.3515,\n    close: 50.41,\n    volume: 30347,\n  },\n  {\n    date: 1462889520000,\n    open: 50.41,\n    high: 50.44,\n    low: 50.4,\n    close: 50.4,\n    volume: 36016,\n  },\n  {\n    date: 1462889580000,\n    open: 50.3999,\n    high: 50.435,\n    low: 50.39,\n    close: 50.435,\n    volume: 19281,\n  },\n  {\n    date: 1462889640000,\n    open: 50.439,\n    high: 50.46,\n    low: 50.43,\n    close: 50.45,\n    volume: 62320,\n  },\n  {\n    date: 1462889700000,\n    open: 50.445,\n    high: 50.45,\n    low: 50.39,\n    close: 50.42,\n    volume: 89766,\n  },\n  {\n    date: 1462889760000,\n    open: 50.42,\n    high: 50.46,\n    low: 50.41,\n    close: 50.44,\n    volume: 63563,\n  },\n  {\n    date: 1462889820000,\n    open: 50.4401,\n    high: 50.45,\n    low: 50.425,\n    close: 50.425,\n    volume: 29961,\n  },\n  {\n    date: 1462889880000,\n    open: 50.43,\n    high: 50.46,\n    low: 50.42,\n    close: 50.43,\n    volume: 31379,\n  },\n  {\n    date: 1462889940000,\n    open: 50.435,\n    high: 50.465,\n    low: 50.4339,\n    close: 50.465,\n    volume: 58390,\n  },\n  {\n    date: 1462890000000,\n    open: 50.465,\n    high: 50.47,\n    low: 50.42,\n    close: 50.44,\n    volume: 63062,\n  },\n  {\n    date: 1462890060000,\n    open: 50.431,\n    high: 50.44,\n    low: 50.4,\n    close: 50.435,\n    volume: 35750,\n  },\n  {\n    date: 1462890120000,\n    open: 50.4301,\n    high: 50.47,\n    low: 50.405,\n    close: 50.41,\n    volume: 58225,\n  },\n  {\n    date: 1462890180000,\n    open: 50.415,\n    high: 50.42,\n    low: 50.4,\n    close: 50.41,\n    volume: 30472,\n  },\n  {\n    date: 1462890240000,\n    open: 50.41,\n    high: 50.41,\n    low: 50.38,\n    close: 50.4001,\n    volume: 89048,\n  },\n  {\n    date: 1462890300000,\n    open: 50.405,\n    high: 50.41,\n    low: 50.355,\n    close: 50.38,\n    volume: 47642,\n  },\n  {\n    date: 1462890360000,\n    open: 50.38,\n    high: 50.38,\n    low: 50.355,\n    close: 50.36,\n    volume: 17117,\n  },\n  {\n    date: 1462890420000,\n    open: 50.37,\n    high: 50.3768,\n    low: 50.3401,\n    close: 50.37,\n    volume: 69384,\n  },\n  {\n    date: 1462890480000,\n    open: 50.37,\n    high: 50.37,\n    low: 50.35,\n    close: 50.35,\n    volume: 21678,\n  },\n  {\n    date: 1462890540000,\n    open: 50.345,\n    high: 50.36,\n    low: 50.34,\n    close: 50.355,\n    volume: 24168,\n  },\n  {\n    date: 1462890600000,\n    open: 50.355,\n    high: 50.415,\n    low: 50.35,\n    close: 50.4089,\n    volume: 46737,\n  },\n  {\n    date: 1462890660000,\n    open: 50.4,\n    high: 50.41,\n    low: 50.36,\n    close: 50.37,\n    volume: 51920,\n  },\n  {\n    date: 1462890720000,\n    open: 50.37,\n    high: 50.375,\n    low: 50.35,\n    close: 50.355,\n    volume: 32615,\n  },\n  {\n    date: 1462890780000,\n    open: 50.35,\n    high: 50.38,\n    low: 50.35,\n    close: 50.369,\n    volume: 38874,\n  },\n  {\n    date: 1462890840000,\n    open: 50.37,\n    high: 50.4,\n    low: 50.37,\n    close: 50.395,\n    volume: 31557,\n  },\n  {\n    date: 1462890900000,\n    open: 50.3915,\n    high: 50.42,\n    low: 50.39,\n    close: 50.395,\n    volume: 24401,\n  },\n  {\n    date: 1462890960000,\n    open: 50.395,\n    high: 50.46,\n    low: 50.39,\n    close: 50.44,\n    volume: 36039,\n  },\n  {\n    date: 1462891020000,\n    open: 50.4401,\n    high: 50.47,\n    low: 50.43,\n    close: 50.465,\n    volume: 61161,\n  },\n  {\n    date: 1462891080000,\n    open: 50.46,\n    high: 50.475,\n    low: 50.455,\n    close: 50.465,\n    volume: 43307,\n  },\n  {\n    date: 1462891140000,\n    open: 50.46,\n    high: 50.46,\n    low: 50.44,\n    close: 50.44,\n    volume: 27551,\n  },\n  {\n    date: 1462891200000,\n    open: 50.44,\n    high: 50.47,\n    low: 50.44,\n    close: 50.47,\n    volume: 9153,\n  },\n  {\n    date: 1462891260000,\n    open: 50.465,\n    high: 50.49,\n    low: 50.46,\n    close: 50.475,\n    volume: 44824,\n  },\n  {\n    date: 1462891320000,\n    open: 50.48,\n    high: 50.5,\n    low: 50.47,\n    close: 50.48,\n    volume: 24774,\n  },\n  {\n    date: 1462891380000,\n    open: 50.48,\n    high: 50.52,\n    low: 50.48,\n    close: 50.51,\n    volume: 34298,\n  },\n  {\n    date: 1462891440000,\n    open: 50.51,\n    high: 50.53,\n    low: 50.49,\n    close: 50.53,\n    volume: 34403,\n  },\n  {\n    date: 1462891500000,\n    open: 50.525,\n    high: 50.55,\n    low: 50.523,\n    close: 50.535,\n    volume: 45727,\n  },\n  {\n    date: 1462891560000,\n    open: 50.5309,\n    high: 50.55,\n    low: 50.53,\n    close: 50.53,\n    volume: 50999,\n  },\n  {\n    date: 1462891620000,\n    open: 50.54,\n    high: 50.58,\n    low: 50.53,\n    close: 50.57,\n    volume: 83000,\n  },\n  {\n    date: 1462891680000,\n    open: 50.57,\n    high: 50.5915,\n    low: 50.56,\n    close: 50.56,\n    volume: 57974,\n  },\n  {\n    date: 1462891740000,\n    open: 50.56,\n    high: 50.57,\n    low: 50.55,\n    close: 50.55,\n    volume: 34777,\n  },\n  {\n    date: 1462891800000,\n    open: 50.55,\n    high: 50.61,\n    low: 50.55,\n    close: 50.605,\n    volume: 41887,\n  },\n  {\n    date: 1462891860000,\n    open: 50.605,\n    high: 50.62,\n    low: 50.59,\n    close: 50.615,\n    volume: 64383,\n  },\n  {\n    date: 1462891920000,\n    open: 50.61,\n    high: 50.62,\n    low: 50.59,\n    close: 50.61,\n    volume: 50208,\n  },\n  {\n    date: 1462891980000,\n    open: 50.61,\n    high: 50.61,\n    low: 50.595,\n    close: 50.605,\n    volume: 26734,\n  },\n  {\n    date: 1462892040000,\n    open: 50.61,\n    high: 50.61,\n    low: 50.5799,\n    close: 50.605,\n    volume: 24628,\n  },\n  {\n    date: 1462892100000,\n    open: 50.61,\n    high: 50.649,\n    low: 50.6,\n    close: 50.645,\n    volume: 42300,\n  },\n  {\n    date: 1462892160000,\n    open: 50.65,\n    high: 50.65,\n    low: 50.6,\n    close: 50.611,\n    volume: 68207,\n  },\n  {\n    date: 1462892220000,\n    open: 50.6101,\n    high: 50.62,\n    low: 50.58,\n    close: 50.591,\n    volume: 37478,\n  },\n  {\n    date: 1462892280000,\n    open: 50.5947,\n    high: 50.6,\n    low: 50.5601,\n    close: 50.58,\n    volume: 41233,\n  },\n  {\n    date: 1462892340000,\n    open: 50.585,\n    high: 50.59,\n    low: 50.56,\n    close: 50.565,\n    volume: 24256,\n  },\n  {\n    date: 1462892400000,\n    open: 50.565,\n    high: 50.59,\n    low: 50.565,\n    close: 50.58,\n    volume: 34040,\n  },\n  {\n    date: 1462892460000,\n    open: 50.5731,\n    high: 50.611,\n    low: 50.5731,\n    close: 50.611,\n    volume: 50146,\n  },\n  {\n    date: 1462892520000,\n    open: 50.6199,\n    high: 50.6199,\n    low: 50.59,\n    close: 50.591,\n    volume: 26310,\n  },\n  {\n    date: 1462892580000,\n    open: 50.6,\n    high: 50.61,\n    low: 50.58,\n    close: 50.585,\n    volume: 44969,\n  },\n  {\n    date: 1462892640000,\n    open: 50.581,\n    high: 50.595,\n    low: 50.58,\n    close: 50.585,\n    volume: 24041,\n  },\n  {\n    date: 1462892700000,\n    open: 50.59,\n    high: 50.6,\n    low: 50.58,\n    close: 50.58,\n    volume: 29183,\n  },\n  {\n    date: 1462892760000,\n    open: 50.58,\n    high: 50.59,\n    low: 50.555,\n    close: 50.56,\n    volume: 39005,\n  },\n  {\n    date: 1462892820000,\n    open: 50.57,\n    high: 50.6099,\n    low: 50.565,\n    close: 50.58,\n    volume: 46216,\n  },\n  {\n    date: 1462892880000,\n    open: 50.57,\n    high: 50.6095,\n    low: 50.57,\n    close: 50.5775,\n    volume: 23660,\n  },\n  {\n    date: 1462892940000,\n    open: 50.59,\n    high: 50.61,\n    low: 50.58,\n    close: 50.58,\n    volume: 40291,\n  },\n  {\n    date: 1462893000000,\n    open: 50.59,\n    high: 50.62,\n    low: 50.59,\n    close: 50.615,\n    volume: 20999,\n  },\n  {\n    date: 1462893060000,\n    open: 50.615,\n    high: 50.62,\n    low: 50.59,\n    close: 50.595,\n    volume: 35398,\n  },\n  {\n    date: 1462893120000,\n    open: 50.59,\n    high: 50.59,\n    low: 50.55,\n    close: 50.57,\n    volume: 59197,\n  },\n  {\n    date: 1462893180000,\n    open: 50.57,\n    high: 50.58,\n    low: 50.53,\n    close: 50.54,\n    volume: 36973,\n  },\n  {\n    date: 1462893240000,\n    open: 50.5399,\n    high: 50.55,\n    low: 50.51,\n    close: 50.515,\n    volume: 30800,\n  },\n  {\n    date: 1462893300000,\n    open: 50.515,\n    high: 50.525,\n    low: 50.5,\n    close: 50.5199,\n    volume: 58524,\n  },\n  {\n    date: 1462893360000,\n    open: 50.515,\n    high: 50.52,\n    low: 50.49,\n    close: 50.5,\n    volume: 35165,\n  },\n  {\n    date: 1462893420000,\n    open: 50.49,\n    high: 50.54,\n    low: 50.49,\n    close: 50.525,\n    volume: 31751,\n  },\n  {\n    date: 1462893480000,\n    open: 50.52,\n    high: 50.525,\n    low: 50.4964,\n    close: 50.4964,\n    volume: 14737,\n  },\n  {\n    date: 1462893540000,\n    open: 50.4955,\n    high: 50.52,\n    low: 50.49,\n    close: 50.5,\n    volume: 30170,\n  },\n  {\n    date: 1462893600000,\n    open: 50.501,\n    high: 50.55,\n    low: 50.5,\n    close: 50.55,\n    volume: 29838,\n  },\n  {\n    date: 1462893660000,\n    open: 50.5491,\n    high: 50.5699,\n    low: 50.53,\n    close: 50.5699,\n    volume: 37027,\n  },\n  {\n    date: 1462893720000,\n    open: 50.56,\n    high: 50.56,\n    low: 50.53,\n    close: 50.53,\n    volume: 23154,\n  },\n  {\n    date: 1462893780000,\n    open: 50.53,\n    high: 50.5365,\n    low: 50.485,\n    close: 50.4864,\n    volume: 33903,\n  },\n  {\n    date: 1462893840000,\n    open: 50.48,\n    high: 50.52,\n    low: 50.48,\n    close: 50.49,\n    volume: 20693,\n  },\n  {\n    date: 1462893900000,\n    open: 50.485,\n    high: 50.5,\n    low: 50.4701,\n    close: 50.5,\n    volume: 12749,\n  },\n  {\n    date: 1462893960000,\n    open: 50.51,\n    high: 50.52,\n    low: 50.5,\n    close: 50.51,\n    volume: 15340,\n  },\n  {\n    date: 1462894020000,\n    open: 50.5,\n    high: 50.51,\n    low: 50.49,\n    close: 50.4999,\n    volume: 18868,\n  },\n  {\n    date: 1462894080000,\n    open: 50.5,\n    high: 50.52,\n    low: 50.4901,\n    close: 50.52,\n    volume: 13684,\n  },\n  {\n    date: 1462894140000,\n    open: 50.52,\n    high: 50.52,\n    low: 50.5,\n    close: 50.52,\n    volume: 14070,\n  },\n  {\n    date: 1462894200000,\n    open: 50.515,\n    high: 50.55,\n    low: 50.515,\n    close: 50.545,\n    volume: 26225,\n  },\n  {\n    date: 1462894260000,\n    open: 50.54,\n    high: 50.58,\n    low: 50.54,\n    close: 50.56,\n    volume: 57809,\n  },\n  {\n    date: 1462894320000,\n    open: 50.565,\n    high: 50.57,\n    low: 50.54,\n    close: 50.555,\n    volume: 32388,\n  },\n  {\n    date: 1462894380000,\n    open: 50.555,\n    high: 50.58,\n    low: 50.555,\n    close: 50.58,\n    volume: 15247,\n  },\n  {\n    date: 1462894440000,\n    open: 50.575,\n    high: 50.6,\n    low: 50.57,\n    close: 50.5759,\n    volume: 39003,\n  },\n  {\n    date: 1462894500000,\n    open: 50.5755,\n    high: 50.63,\n    low: 50.57,\n    close: 50.62,\n    volume: 36978,\n  },\n  {\n    date: 1462894560000,\n    open: 50.63,\n    high: 50.645,\n    low: 50.62,\n    close: 50.63,\n    volume: 38433,\n  },\n  {\n    date: 1462894620000,\n    open: 50.62,\n    high: 50.63,\n    low: 50.6,\n    close: 50.6,\n    volume: 51484,\n  },\n  {\n    date: 1462894680000,\n    open: 50.6,\n    high: 50.62,\n    low: 50.6,\n    close: 50.61,\n    volume: 22608,\n  },\n  {\n    date: 1462894740000,\n    open: 50.6001,\n    high: 50.63,\n    low: 50.6,\n    close: 50.61,\n    volume: 20250,\n  },\n  {\n    date: 1462894800000,\n    open: 50.61,\n    high: 50.6599,\n    low: 50.61,\n    close: 50.64,\n    volume: 51859,\n  },\n  {\n    date: 1462894860000,\n    open: 50.63,\n    high: 50.64,\n    low: 50.62,\n    close: 50.63,\n    volume: 22079,\n  },\n  {\n    date: 1462894920000,\n    open: 50.6341,\n    high: 50.65,\n    low: 50.63,\n    close: 50.6431,\n    volume: 25880,\n  },\n  {\n    date: 1462894980000,\n    open: 50.64,\n    high: 50.645,\n    low: 50.57,\n    close: 50.58,\n    volume: 45722,\n  },\n  {\n    date: 1462895040000,\n    open: 50.581,\n    high: 50.62,\n    low: 50.581,\n    close: 50.613,\n    volume: 25713,\n  },\n  {\n    date: 1462895100000,\n    open: 50.62,\n    high: 50.626,\n    low: 50.59,\n    close: 50.6,\n    volume: 30951,\n  },\n  {\n    date: 1462895160000,\n    open: 50.6,\n    high: 50.62,\n    low: 50.59,\n    close: 50.59,\n    volume: 38034,\n  },\n  {\n    date: 1462895220000,\n    open: 50.59,\n    high: 50.63,\n    low: 50.58,\n    close: 50.63,\n    volume: 40176,\n  },\n  {\n    date: 1462895280000,\n    open: 50.6201,\n    high: 50.625,\n    low: 50.6,\n    close: 50.6,\n    volume: 46307,\n  },\n  {\n    date: 1462895340000,\n    open: 50.595,\n    high: 50.6036,\n    low: 50.57,\n    close: 50.6036,\n    volume: 39719,\n  },\n  {\n    date: 1462895400000,\n    open: 50.605,\n    high: 50.605,\n    low: 50.582,\n    close: 50.6,\n    volume: 57439,\n  },\n  {\n    date: 1462895460000,\n    open: 50.6,\n    high: 50.64,\n    low: 50.59,\n    close: 50.6356,\n    volume: 32397,\n  },\n  {\n    date: 1462895520000,\n    open: 50.64,\n    high: 50.66,\n    low: 50.635,\n    close: 50.65,\n    volume: 45512,\n  },\n  {\n    date: 1462895580000,\n    open: 50.643,\n    high: 50.67,\n    low: 50.6301,\n    close: 50.635,\n    volume: 27856,\n  },\n  {\n    date: 1462895640000,\n    open: 50.6301,\n    high: 50.6599,\n    low: 50.63,\n    close: 50.65,\n    volume: 39409,\n  },\n  {\n    date: 1462895700000,\n    open: 50.65,\n    high: 50.66,\n    low: 50.64,\n    close: 50.6464,\n    volume: 53057,\n  },\n  {\n    date: 1462895760000,\n    open: 50.65,\n    high: 50.67,\n    low: 50.64,\n    close: 50.65,\n    volume: 74912,\n  },\n  {\n    date: 1462895820000,\n    open: 50.66,\n    high: 50.66,\n    low: 50.65,\n    close: 50.65,\n    volume: 11934,\n  },\n  {\n    date: 1462895880000,\n    open: 50.655,\n    high: 50.655,\n    low: 50.63,\n    close: 50.635,\n    volume: 41990,\n  },\n  {\n    date: 1462895940000,\n    open: 50.64,\n    high: 50.66,\n    low: 50.6349,\n    close: 50.655,\n    volume: 20099,\n  },\n  {\n    date: 1462896000000,\n    open: 50.655,\n    high: 50.68,\n    low: 50.651,\n    close: 50.67,\n    volume: 50398,\n  },\n  {\n    date: 1462896060000,\n    open: 50.68,\n    high: 50.699,\n    low: 50.67,\n    close: 50.695,\n    volume: 57258,\n  },\n  {\n    date: 1462896120000,\n    open: 50.695,\n    high: 50.73,\n    low: 50.695,\n    close: 50.73,\n    volume: 96286,\n  },\n  {\n    date: 1462896180000,\n    open: 50.725,\n    high: 50.74,\n    low: 50.72,\n    close: 50.7358,\n    volume: 104488,\n  },\n  {\n    date: 1462896240000,\n    open: 50.7331,\n    high: 50.74,\n    low: 50.72,\n    close: 50.73,\n    volume: 38429,\n  },\n  {\n    date: 1462896300000,\n    open: 50.725,\n    high: 50.75,\n    low: 50.7231,\n    close: 50.7231,\n    volume: 47818,\n  },\n  {\n    date: 1462896360000,\n    open: 50.73,\n    high: 50.73,\n    low: 50.7,\n    close: 50.7,\n    volume: 52255,\n  },\n  {\n    date: 1462896420000,\n    open: 50.69,\n    high: 50.72,\n    low: 50.69,\n    close: 50.7175,\n    volume: 21930,\n  },\n  {\n    date: 1462896480000,\n    open: 50.72,\n    high: 50.72,\n    low: 50.695,\n    close: 50.7,\n    volume: 23787,\n  },\n  {\n    date: 1462896540000,\n    open: 50.7,\n    high: 50.71,\n    low: 50.69,\n    close: 50.7,\n    volume: 47704,\n  },\n  {\n    date: 1462896600000,\n    open: 50.7,\n    high: 50.707,\n    low: 50.69,\n    close: 50.705,\n    volume: 25080,\n  },\n  {\n    date: 1462896660000,\n    open: 50.71,\n    high: 50.73,\n    low: 50.7,\n    close: 50.73,\n    volume: 25356,\n  },\n  {\n    date: 1462896720000,\n    open: 50.73,\n    high: 50.74,\n    low: 50.701,\n    close: 50.701,\n    volume: 24767,\n  },\n  {\n    date: 1462896780000,\n    open: 50.705,\n    high: 50.71,\n    low: 50.69,\n    close: 50.71,\n    volume: 38270,\n  },\n  {\n    date: 1462896840000,\n    open: 50.71,\n    high: 50.72,\n    low: 50.69,\n    close: 50.695,\n    volume: 11717,\n  },\n  {\n    date: 1462896900000,\n    open: 50.6975,\n    high: 50.715,\n    low: 50.69,\n    close: 50.7,\n    volume: 12745,\n  },\n  {\n    date: 1462896960000,\n    open: 50.7,\n    high: 50.74,\n    low: 50.69,\n    close: 50.72,\n    volume: 103856,\n  },\n  {\n    date: 1462897020000,\n    open: 50.72,\n    high: 50.725,\n    low: 50.69,\n    close: 50.7031,\n    volume: 30451,\n  },\n  {\n    date: 1462897080000,\n    open: 50.705,\n    high: 50.72,\n    low: 50.7,\n    close: 50.71,\n    volume: 67398,\n  },\n  {\n    date: 1462897140000,\n    open: 50.71,\n    high: 50.71,\n    low: 50.69,\n    close: 50.7,\n    volume: 31603,\n  },\n  {\n    date: 1462897200000,\n    open: 50.7052,\n    high: 50.7287,\n    low: 50.695,\n    close: 50.7271,\n    volume: 19478,\n  },\n  {\n    date: 1462897260000,\n    open: 50.73,\n    high: 50.74,\n    low: 50.715,\n    close: 50.74,\n    volume: 37400,\n  },\n  {\n    date: 1462897320000,\n    open: 50.74,\n    high: 50.74,\n    low: 50.72,\n    close: 50.73,\n    volume: 10980,\n  },\n  {\n    date: 1462897380000,\n    open: 50.73,\n    high: 50.77,\n    low: 50.7225,\n    close: 50.765,\n    volume: 70393,\n  },\n  {\n    date: 1462897440000,\n    open: 50.77,\n    high: 50.77,\n    low: 50.75,\n    close: 50.75,\n    volume: 37900,\n  },\n  {\n    date: 1462897500000,\n    open: 50.75,\n    high: 50.76,\n    low: 50.745,\n    close: 50.75,\n    volume: 17342,\n  },\n  {\n    date: 1462897560000,\n    open: 50.7542,\n    high: 50.7665,\n    low: 50.745,\n    close: 50.7559,\n    volume: 25282,\n  },\n  {\n    date: 1462897620000,\n    open: 50.755,\n    high: 50.77,\n    low: 50.75,\n    close: 50.75,\n    volume: 20081,\n  },\n  {\n    date: 1462897680000,\n    open: 50.755,\n    high: 50.76,\n    low: 50.7401,\n    close: 50.75,\n    volume: 30470,\n  },\n  {\n    date: 1462897740000,\n    open: 50.7435,\n    high: 50.75,\n    low: 50.74,\n    close: 50.7436,\n    volume: 17031,\n  },\n  {\n    date: 1462897800000,\n    open: 50.745,\n    high: 50.765,\n    low: 50.74,\n    close: 50.76,\n    volume: 27327,\n  },\n  {\n    date: 1462897860000,\n    open: 50.76,\n    high: 50.77,\n    low: 50.74,\n    close: 50.755,\n    volume: 36647,\n  },\n  {\n    date: 1462897920000,\n    open: 50.75,\n    high: 50.7799,\n    low: 50.75,\n    close: 50.775,\n    volume: 24471,\n  },\n  {\n    date: 1462897980000,\n    open: 50.77,\n    high: 50.775,\n    low: 50.76,\n    close: 50.77,\n    volume: 13423,\n  },\n  {\n    date: 1462898040000,\n    open: 50.7701,\n    high: 50.78,\n    low: 50.7405,\n    close: 50.75,\n    volume: 32314,\n  },\n  {\n    date: 1462898100000,\n    open: 50.75,\n    high: 50.76,\n    low: 50.74,\n    close: 50.76,\n    volume: 43440,\n  },\n  {\n    date: 1462898160000,\n    open: 50.7504,\n    high: 50.7665,\n    low: 50.75,\n    close: 50.76,\n    volume: 31881,\n  },\n  {\n    date: 1462898220000,\n    open: 50.7599,\n    high: 50.78,\n    low: 50.75,\n    close: 50.78,\n    volume: 25336,\n  },\n  {\n    date: 1462898280000,\n    open: 50.7799,\n    high: 50.79,\n    low: 50.76,\n    close: 50.771,\n    volume: 35358,\n  },\n  {\n    date: 1462898340000,\n    open: 50.7742,\n    high: 50.785,\n    low: 50.76,\n    close: 50.76,\n    volume: 14699,\n  },\n  {\n    date: 1462898400000,\n    open: 50.765,\n    high: 50.78,\n    low: 50.75,\n    close: 50.778,\n    volume: 52337,\n  },\n  {\n    date: 1462898460000,\n    open: 50.78,\n    high: 50.79,\n    low: 50.77,\n    close: 50.79,\n    volume: 23568,\n  },\n  {\n    date: 1462898520000,\n    open: 50.79,\n    high: 50.805,\n    low: 50.78,\n    close: 50.8013,\n    volume: 31484,\n  },\n  {\n    date: 1462898580000,\n    open: 50.805,\n    high: 50.805,\n    low: 50.78,\n    close: 50.79,\n    volume: 11784,\n  },\n  {\n    date: 1462898640000,\n    open: 50.79,\n    high: 50.8,\n    low: 50.79,\n    close: 50.8,\n    volume: 10101,\n  },\n  {\n    date: 1462898700000,\n    open: 50.795,\n    high: 50.805,\n    low: 50.78,\n    close: 50.78,\n    volume: 40814,\n  },\n  {\n    date: 1462898760000,\n    open: 50.79,\n    high: 50.79,\n    low: 50.77,\n    close: 50.779,\n    volume: 14971,\n  },\n  {\n    date: 1462898820000,\n    open: 50.775,\n    high: 50.8,\n    low: 50.7699,\n    close: 50.7799,\n    volume: 30005,\n  },\n  {\n    date: 1462898880000,\n    open: 50.7799,\n    high: 50.8,\n    low: 50.7799,\n    close: 50.7832,\n    volume: 28420,\n  },\n  {\n    date: 1462898940000,\n    open: 50.79,\n    high: 50.81,\n    low: 50.79,\n    close: 50.8068,\n    volume: 27475,\n  },\n  {\n    date: 1462899000000,\n    open: 50.805,\n    high: 50.81,\n    low: 50.7832,\n    close: 50.7832,\n    volume: 28633,\n  },\n  {\n    date: 1462899060000,\n    open: 50.79,\n    high: 50.79,\n    low: 50.76,\n    close: 50.77,\n    volume: 22601,\n  },\n  {\n    date: 1462899120000,\n    open: 50.77,\n    high: 50.78,\n    low: 50.76,\n    close: 50.7789,\n    volume: 11395,\n  },\n  {\n    date: 1462899180000,\n    open: 50.775,\n    high: 50.8,\n    low: 50.77,\n    close: 50.8,\n    volume: 29529,\n  },\n  {\n    date: 1462899240000,\n    open: 50.8,\n    high: 50.82,\n    low: 50.7925,\n    close: 50.7925,\n    volume: 66154,\n  },\n  {\n    date: 1462899300000,\n    open: 50.7965,\n    high: 50.82,\n    low: 50.795,\n    close: 50.82,\n    volume: 25517,\n  },\n  {\n    date: 1462899360000,\n    open: 50.82,\n    high: 50.84,\n    low: 50.82,\n    close: 50.8399,\n    volume: 41995,\n  },\n  {\n    date: 1462899420000,\n    open: 50.84,\n    high: 50.85,\n    low: 50.82,\n    close: 50.822,\n    volume: 48401,\n  },\n  {\n    date: 1462899480000,\n    open: 50.82,\n    high: 50.83,\n    low: 50.8,\n    close: 50.825,\n    volume: 25711,\n  },\n  {\n    date: 1462899540000,\n    open: 50.81,\n    high: 50.82,\n    low: 50.8,\n    close: 50.82,\n    volume: 47987,\n  },\n  {\n    date: 1462899600000,\n    open: 50.8299,\n    high: 50.845,\n    low: 50.8,\n    close: 50.84,\n    volume: 45482,\n  },\n  {\n    date: 1462899660000,\n    open: 50.84,\n    high: 50.84,\n    low: 50.8,\n    close: 50.82,\n    volume: 49323,\n  },\n  {\n    date: 1462899720000,\n    open: 50.82,\n    high: 50.845,\n    low: 50.82,\n    close: 50.83,\n    volume: 23888,\n  },\n  {\n    date: 1462899780000,\n    open: 50.83,\n    high: 50.84,\n    low: 50.83,\n    close: 50.83,\n    volume: 17408,\n  },\n  {\n    date: 1462899840000,\n    open: 50.835,\n    high: 50.85,\n    low: 50.83,\n    close: 50.84,\n    volume: 16932,\n  },\n  {\n    date: 1462899900000,\n    open: 50.845,\n    high: 50.845,\n    low: 50.83,\n    close: 50.84,\n    volume: 24568,\n  },\n  {\n    date: 1462899960000,\n    open: 50.85,\n    high: 50.87,\n    low: 50.84,\n    close: 50.86,\n    volume: 70103,\n  },\n  {\n    date: 1462900020000,\n    open: 50.8563,\n    high: 50.87,\n    low: 50.84,\n    close: 50.842,\n    volume: 37089,\n  },\n  {\n    date: 1462900080000,\n    open: 50.84,\n    high: 50.86,\n    low: 50.83,\n    close: 50.855,\n    volume: 22352,\n  },\n  {\n    date: 1462900140000,\n    open: 50.8515,\n    high: 50.87,\n    low: 50.8465,\n    close: 50.87,\n    volume: 36861,\n  },\n  {\n    date: 1462900200000,\n    open: 50.865,\n    high: 50.88,\n    low: 50.85,\n    close: 50.88,\n    volume: 47100,\n  },\n  {\n    date: 1462900260000,\n    open: 50.87,\n    high: 50.895,\n    low: 50.87,\n    close: 50.87,\n    volume: 59398,\n  },\n  {\n    date: 1462900320000,\n    open: 50.862,\n    high: 50.88,\n    low: 50.86,\n    close: 50.86,\n    volume: 27819,\n  },\n  {\n    date: 1462900380000,\n    open: 50.865,\n    high: 50.87,\n    low: 50.84,\n    close: 50.84,\n    volume: 22656,\n  },\n  {\n    date: 1462900440000,\n    open: 50.8405,\n    high: 50.85,\n    low: 50.82,\n    close: 50.8292,\n    volume: 30074,\n  },\n  {\n    date: 1462900500000,\n    open: 50.82,\n    high: 50.84,\n    low: 50.81,\n    close: 50.81,\n    volume: 28837,\n  },\n  {\n    date: 1462900560000,\n    open: 50.81,\n    high: 50.839,\n    low: 50.81,\n    close: 50.835,\n    volume: 25560,\n  },\n  {\n    date: 1462900620000,\n    open: 50.835,\n    high: 50.8399,\n    low: 50.81,\n    close: 50.82,\n    volume: 20932,\n  },\n  {\n    date: 1462900680000,\n    open: 50.815,\n    high: 50.83,\n    low: 50.81,\n    close: 50.8125,\n    volume: 21412,\n  },\n  {\n    date: 1462900740000,\n    open: 50.815,\n    high: 50.8489,\n    low: 50.815,\n    close: 50.83,\n    volume: 33085,\n  },\n  {\n    date: 1462900800000,\n    open: 50.83,\n    high: 50.8339,\n    low: 50.8188,\n    close: 50.83,\n    volume: 28912,\n  },\n  {\n    date: 1462900860000,\n    open: 50.83,\n    high: 50.855,\n    low: 50.83,\n    close: 50.855,\n    volume: 17756,\n  },\n  {\n    date: 1462900920000,\n    open: 50.859,\n    high: 50.86,\n    low: 50.84,\n    close: 50.8599,\n    volume: 66284,\n  },\n  {\n    date: 1462900980000,\n    open: 50.8505,\n    high: 50.86,\n    low: 50.8401,\n    close: 50.855,\n    volume: 20474,\n  },\n  {\n    date: 1462901040000,\n    open: 50.8559,\n    high: 50.865,\n    low: 50.84,\n    close: 50.85,\n    volume: 16777,\n  },\n  {\n    date: 1462901100000,\n    open: 50.8442,\n    high: 50.86,\n    low: 50.842,\n    close: 50.85,\n    volume: 15172,\n  },\n  {\n    date: 1462901160000,\n    open: 50.8415,\n    high: 50.87,\n    low: 50.8415,\n    close: 50.85,\n    volume: 76020,\n  },\n  {\n    date: 1462901220000,\n    open: 50.85,\n    high: 50.85,\n    low: 50.83,\n    close: 50.836,\n    volume: 10780,\n  },\n  {\n    date: 1462901280000,\n    open: 50.8389,\n    high: 50.84,\n    low: 50.82,\n    close: 50.825,\n    volume: 21291,\n  },\n  {\n    date: 1462901340000,\n    open: 50.8237,\n    high: 50.85,\n    low: 50.81,\n    close: 50.83,\n    volume: 48447,\n  },\n  {\n    date: 1462901400000,\n    open: 50.8276,\n    high: 50.8495,\n    low: 50.815,\n    close: 50.84,\n    volume: 60230,\n  },\n  {\n    date: 1462901460000,\n    open: 50.85,\n    high: 50.855,\n    low: 50.83,\n    close: 50.85,\n    volume: 25133,\n  },\n  {\n    date: 1462901520000,\n    open: 50.8599,\n    high: 50.8599,\n    low: 50.839,\n    close: 50.85,\n    volume: 40590,\n  },\n  {\n    date: 1462901580000,\n    open: 50.85,\n    high: 50.855,\n    low: 50.8225,\n    close: 50.855,\n    volume: 28259,\n  },\n  {\n    date: 1462901640000,\n    open: 50.85,\n    high: 50.855,\n    low: 50.82,\n    close: 50.835,\n    volume: 34831,\n  },\n  {\n    date: 1462901700000,\n    open: 50.835,\n    high: 50.84,\n    low: 50.82,\n    close: 50.8301,\n    volume: 18805,\n  },\n  {\n    date: 1462901760000,\n    open: 50.831,\n    high: 50.86,\n    low: 50.83,\n    close: 50.845,\n    volume: 22119,\n  },\n  {\n    date: 1462901820000,\n    open: 50.855,\n    high: 50.86,\n    low: 50.84,\n    close: 50.86,\n    volume: 32313,\n  },\n  {\n    date: 1462901880000,\n    open: 50.86,\n    high: 50.87,\n    low: 50.85,\n    close: 50.86,\n    volume: 28306,\n  },\n  {\n    date: 1462901940000,\n    open: 50.85,\n    high: 50.855,\n    low: 50.8325,\n    close: 50.835,\n    volume: 23965,\n  },\n  {\n    date: 1462902000000,\n    open: 50.835,\n    high: 50.835,\n    low: 50.81,\n    close: 50.82,\n    volume: 27495,\n  },\n  {\n    date: 1462902060000,\n    open: 50.8221,\n    high: 50.83,\n    low: 50.82,\n    close: 50.82,\n    volume: 40028,\n  },\n  {\n    date: 1462902120000,\n    open: 50.825,\n    high: 50.8395,\n    low: 50.807,\n    close: 50.82,\n    volume: 35536,\n  },\n  {\n    date: 1462902180000,\n    open: 50.81,\n    high: 50.82,\n    low: 50.79,\n    close: 50.81,\n    volume: 33905,\n  },\n  {\n    date: 1462902240000,\n    open: 50.81,\n    high: 50.82,\n    low: 50.8,\n    close: 50.815,\n    volume: 18860,\n  },\n  {\n    date: 1462902300000,\n    open: 50.81,\n    high: 50.83,\n    low: 50.81,\n    close: 50.83,\n    volume: 25196,\n  },\n  {\n    date: 1462902360000,\n    open: 50.83,\n    high: 50.85,\n    low: 50.82,\n    close: 50.841,\n    volume: 52631,\n  },\n  {\n    date: 1462902420000,\n    open: 50.85,\n    high: 50.865,\n    low: 50.84,\n    close: 50.85,\n    volume: 27586,\n  },\n  {\n    date: 1462902480000,\n    open: 50.8401,\n    high: 50.865,\n    low: 50.84,\n    close: 50.85,\n    volume: 29468,\n  },\n  {\n    date: 1462902540000,\n    open: 50.85,\n    high: 50.85,\n    low: 50.83,\n    close: 50.839,\n    volume: 12579,\n  },\n  {\n    date: 1462902600000,\n    open: 50.835,\n    high: 50.8533,\n    low: 50.83,\n    close: 50.85,\n    volume: 14377,\n  },\n  {\n    date: 1462902660000,\n    open: 50.84,\n    high: 50.8556,\n    low: 50.84,\n    close: 50.85,\n    volume: 27052,\n  },\n  {\n    date: 1462902720000,\n    open: 50.8401,\n    high: 50.865,\n    low: 50.8401,\n    close: 50.851,\n    volume: 15824,\n  },\n  {\n    date: 1462902780000,\n    open: 50.85,\n    high: 50.87,\n    low: 50.84,\n    close: 50.86,\n    volume: 30307,\n  },\n  {\n    date: 1462902840000,\n    open: 50.86,\n    high: 50.87,\n    low: 50.845,\n    close: 50.87,\n    volume: 31888,\n  },\n  {\n    date: 1462902900000,\n    open: 50.865,\n    high: 50.87,\n    low: 50.855,\n    close: 50.8601,\n    volume: 29610,\n  },\n  {\n    date: 1462902960000,\n    open: 50.86,\n    high: 50.87,\n    low: 50.84,\n    close: 50.85,\n    volume: 30612,\n  },\n  {\n    date: 1462903020000,\n    open: 50.85,\n    high: 50.87,\n    low: 50.85,\n    close: 50.87,\n    volume: 8562,\n  },\n  {\n    date: 1462903080000,\n    open: 50.87,\n    high: 50.89,\n    low: 50.85,\n    close: 50.88,\n    volume: 34287,\n  },\n  {\n    date: 1462903140000,\n    open: 50.885,\n    high: 50.91,\n    low: 50.88,\n    close: 50.9,\n    volume: 59598,\n  },\n  {\n    date: 1462903200000,\n    open: 50.89,\n    high: 50.91,\n    low: 50.89,\n    close: 50.895,\n    volume: 72011,\n  },\n  {\n    date: 1462903260000,\n    open: 50.9,\n    high: 50.905,\n    low: 50.875,\n    close: 50.898,\n    volume: 84612,\n  },\n  {\n    date: 1462903320000,\n    open: 50.895,\n    high: 50.9,\n    low: 50.89,\n    close: 50.9,\n    volume: 14377,\n  },\n  {\n    date: 1462903380000,\n    open: 50.8964,\n    high: 50.9,\n    low: 50.89,\n    close: 50.895,\n    volume: 71210,\n  },\n  {\n    date: 1462903440000,\n    open: 50.9,\n    high: 50.905,\n    low: 50.89,\n    close: 50.9,\n    volume: 53789,\n  },\n  {\n    date: 1462903500000,\n    open: 50.896,\n    high: 50.9,\n    low: 50.8901,\n    close: 50.9,\n    volume: 13133,\n  },\n  {\n    date: 1462903560000,\n    open: 50.895,\n    high: 50.9,\n    low: 50.89,\n    close: 50.9,\n    volume: 23583,\n  },\n  {\n    date: 1462903620000,\n    open: 50.895,\n    high: 50.92,\n    low: 50.895,\n    close: 50.901,\n    volume: 60410,\n  },\n  {\n    date: 1462903680000,\n    open: 50.901,\n    high: 50.915,\n    low: 50.9,\n    close: 50.915,\n    volume: 41316,\n  },\n  {\n    date: 1462903740000,\n    open: 50.9199,\n    high: 50.92,\n    low: 50.9,\n    close: 50.91,\n    volume: 33187,\n  },\n  {\n    date: 1462903800000,\n    open: 50.9,\n    high: 50.91,\n    low: 50.895,\n    close: 50.91,\n    volume: 24469,\n  },\n  {\n    date: 1462903860000,\n    open: 50.905,\n    high: 50.92,\n    low: 50.89,\n    close: 50.89,\n    volume: 48733,\n  },\n  {\n    date: 1462903920000,\n    open: 50.9,\n    high: 50.91,\n    low: 50.9,\n    close: 50.91,\n    volume: 20634,\n  },\n  {\n    date: 1462903980000,\n    open: 50.9037,\n    high: 50.9099,\n    low: 50.86,\n    close: 50.875,\n    volume: 47483,\n  },\n  {\n    date: 1462904040000,\n    open: 50.875,\n    high: 50.9,\n    low: 50.87,\n    close: 50.895,\n    volume: 44781,\n  },\n  {\n    date: 1462904100000,\n    open: 50.895,\n    high: 50.92,\n    low: 50.88,\n    close: 50.9,\n    volume: 132513,\n  },\n  {\n    date: 1462904160000,\n    open: 50.891,\n    high: 50.9289,\n    low: 50.891,\n    close: 50.9236,\n    volume: 67666,\n  },\n  {\n    date: 1462904220000,\n    open: 50.927,\n    high: 50.95,\n    low: 50.92,\n    close: 50.95,\n    volume: 75568,\n  },\n  {\n    date: 1462904280000,\n    open: 50.945,\n    high: 50.97,\n    low: 50.94,\n    close: 50.96,\n    volume: 98503,\n  },\n  {\n    date: 1462904340000,\n    open: 50.9564,\n    high: 50.97,\n    low: 50.9533,\n    close: 50.97,\n    volume: 24317,\n  },\n  {\n    date: 1462904400000,\n    open: 50.9641,\n    high: 50.97,\n    low: 50.95,\n    close: 50.9559,\n    volume: 49120,\n  },\n  {\n    date: 1462904460000,\n    open: 50.955,\n    high: 50.97,\n    low: 50.95,\n    close: 50.965,\n    volume: 63632,\n  },\n  {\n    date: 1462904520000,\n    open: 50.9699,\n    high: 50.97,\n    low: 50.95,\n    close: 50.965,\n    volume: 30268,\n  },\n  {\n    date: 1462904580000,\n    open: 50.964,\n    high: 50.98,\n    low: 50.96,\n    close: 50.97,\n    volume: 29499,\n  },\n  {\n    date: 1462904640000,\n    open: 50.9679,\n    high: 50.97,\n    low: 50.96,\n    close: 50.965,\n    volume: 29119,\n  },\n  {\n    date: 1462904700000,\n    open: 50.965,\n    high: 50.98,\n    low: 50.96,\n    close: 50.979,\n    volume: 40302,\n  },\n  {\n    date: 1462904760000,\n    open: 50.98,\n    high: 50.98,\n    low: 50.95,\n    close: 50.97,\n    volume: 73366,\n  },\n  {\n    date: 1462904820000,\n    open: 50.97,\n    high: 50.99,\n    low: 50.97,\n    close: 50.975,\n    volume: 75342,\n  },\n  {\n    date: 1462904880000,\n    open: 50.98,\n    high: 50.98,\n    low: 50.97,\n    close: 50.9799,\n    volume: 15419,\n  },\n  {\n    date: 1462904940000,\n    open: 50.98,\n    high: 50.99,\n    low: 50.97,\n    close: 50.979,\n    volume: 25475,\n  },\n  {\n    date: 1462905000000,\n    open: 50.98,\n    high: 50.98,\n    low: 50.95,\n    close: 50.95,\n    volume: 53201,\n  },\n  {\n    date: 1462905060000,\n    open: 50.95,\n    high: 50.96,\n    low: 50.94,\n    close: 50.94,\n    volume: 192483,\n  },\n  {\n    date: 1462905120000,\n    open: 50.94,\n    high: 50.955,\n    low: 50.93,\n    close: 50.935,\n    volume: 45506,\n  },\n  {\n    date: 1462905180000,\n    open: 50.93,\n    high: 50.93,\n    low: 50.88,\n    close: 50.91,\n    volume: 61259,\n  },\n  {\n    date: 1462905240000,\n    open: 50.9076,\n    high: 50.9267,\n    low: 50.9076,\n    close: 50.9267,\n    volume: 37550,\n  },\n  {\n    date: 1462905300000,\n    open: 50.9211,\n    high: 50.95,\n    low: 50.91,\n    close: 50.93,\n    volume: 84916,\n  },\n  {\n    date: 1462905360000,\n    open: 50.94,\n    high: 50.94,\n    low: 50.915,\n    close: 50.915,\n    volume: 37559,\n  },\n  {\n    date: 1462905420000,\n    open: 50.92,\n    high: 50.945,\n    low: 50.92,\n    close: 50.94,\n    volume: 41902,\n  },\n  {\n    date: 1462905480000,\n    open: 50.95,\n    high: 50.95,\n    low: 50.94,\n    close: 50.95,\n    volume: 21432,\n  },\n  {\n    date: 1462905540000,\n    open: 50.94,\n    high: 50.9465,\n    low: 50.91,\n    close: 50.9199,\n    volume: 59072,\n  },\n  {\n    date: 1462905600000,\n    open: 50.9171,\n    high: 50.9299,\n    low: 50.91,\n    close: 50.92,\n    volume: 24767,\n  },\n  {\n    date: 1462905660000,\n    open: 50.92,\n    high: 50.92,\n    low: 50.91,\n    close: 50.915,\n    volume: 13861,\n  },\n  {\n    date: 1462905720000,\n    open: 50.9135,\n    high: 50.92,\n    low: 50.91,\n    close: 50.915,\n    volume: 39404,\n  },\n  {\n    date: 1462905780000,\n    open: 50.91,\n    high: 50.935,\n    low: 50.91,\n    close: 50.9225,\n    volume: 61180,\n  },\n  {\n    date: 1462905840000,\n    open: 50.93,\n    high: 50.93,\n    low: 50.89,\n    close: 50.89,\n    volume: 56506,\n  },\n  {\n    date: 1462905900000,\n    open: 50.89,\n    high: 50.9,\n    low: 50.87,\n    close: 50.875,\n    volume: 52929,\n  },\n  {\n    date: 1462905960000,\n    open: 50.88,\n    high: 50.9,\n    low: 50.87,\n    close: 50.879,\n    volume: 41753,\n  },\n  {\n    date: 1462906020000,\n    open: 50.875,\n    high: 50.88,\n    low: 50.86,\n    close: 50.86,\n    volume: 18711,\n  },\n  {\n    date: 1462906080000,\n    open: 50.865,\n    high: 50.865,\n    low: 50.84,\n    close: 50.84,\n    volume: 37037,\n  },\n  {\n    date: 1462906140000,\n    open: 50.8459,\n    high: 50.87,\n    low: 50.845,\n    close: 50.86,\n    volume: 37852,\n  },\n  {\n    date: 1462906200000,\n    open: 50.865,\n    high: 50.865,\n    low: 50.84,\n    close: 50.84,\n    volume: 42469,\n  },\n  {\n    date: 1462906260000,\n    open: 50.845,\n    high: 50.85,\n    low: 50.84,\n    close: 50.85,\n    volume: 17821,\n  },\n  {\n    date: 1462906320000,\n    open: 50.84,\n    high: 50.855,\n    low: 50.84,\n    close: 50.85,\n    volume: 26806,\n  },\n  {\n    date: 1462906380000,\n    open: 50.85,\n    high: 50.855,\n    low: 50.84,\n    close: 50.845,\n    volume: 14385,\n  },\n  {\n    date: 1462906440000,\n    open: 50.85,\n    high: 50.86,\n    low: 50.835,\n    close: 50.86,\n    volume: 79757,\n  },\n  {\n    date: 1462906500000,\n    open: 50.855,\n    high: 50.86,\n    low: 50.85,\n    close: 50.8571,\n    volume: 6077,\n  },\n  {\n    date: 1462906560000,\n    open: 50.85,\n    high: 50.87,\n    low: 50.84,\n    close: 50.869,\n    volume: 49090,\n  },\n  {\n    date: 1462906620000,\n    open: 50.865,\n    high: 50.87,\n    low: 50.86,\n    close: 50.86,\n    volume: 21695,\n  },\n  {\n    date: 1462906680000,\n    open: 50.87,\n    high: 50.88,\n    low: 50.8619,\n    close: 50.875,\n    volume: 25345,\n  },\n  {\n    date: 1462906740000,\n    open: 50.87,\n    high: 50.885,\n    low: 50.86,\n    close: 50.86,\n    volume: 39670,\n  },\n  {\n    date: 1462906800000,\n    open: 50.86,\n    high: 50.87,\n    low: 50.84,\n    close: 50.845,\n    volume: 14552,\n  },\n  {\n    date: 1462906860000,\n    open: 50.84,\n    high: 50.87,\n    low: 50.83,\n    close: 50.87,\n    volume: 40019,\n  },\n  {\n    date: 1462906920000,\n    open: 50.87,\n    high: 50.87,\n    low: 50.855,\n    close: 50.865,\n    volume: 80032,\n  },\n  {\n    date: 1462906980000,\n    open: 50.87,\n    high: 50.87,\n    low: 50.85,\n    close: 50.86,\n    volume: 40860,\n  },\n  {\n    date: 1462907040000,\n    open: 50.86,\n    high: 50.88,\n    low: 50.86,\n    close: 50.875,\n    volume: 34984,\n  },\n  {\n    date: 1462907100000,\n    open: 50.88,\n    high: 50.88,\n    low: 50.85,\n    close: 50.86,\n    volume: 23476,\n  },\n  {\n    date: 1462907160000,\n    open: 50.853,\n    high: 50.86,\n    low: 50.85,\n    close: 50.855,\n    volume: 16840,\n  },\n  {\n    date: 1462907220000,\n    open: 50.855,\n    high: 50.86,\n    low: 50.84,\n    close: 50.845,\n    volume: 30953,\n  },\n  {\n    date: 1462907280000,\n    open: 50.849,\n    high: 50.855,\n    low: 50.83,\n    close: 50.84,\n    volume: 77744,\n  },\n  {\n    date: 1462907340000,\n    open: 50.84,\n    high: 50.86,\n    low: 50.835,\n    close: 50.845,\n    volume: 38721,\n  },\n  {\n    date: 1462907400000,\n    open: 50.845,\n    high: 50.85,\n    low: 50.84,\n    close: 50.845,\n    volume: 7528,\n  },\n  {\n    date: 1462907460000,\n    open: 50.8499,\n    high: 50.86,\n    low: 50.83,\n    close: 50.8484,\n    volume: 87968,\n  },\n  {\n    date: 1462907520000,\n    open: 50.85,\n    high: 50.87,\n    low: 50.84,\n    close: 50.8566,\n    volume: 62281,\n  },\n  {\n    date: 1462907580000,\n    open: 50.86,\n    high: 50.865,\n    low: 50.83,\n    close: 50.83,\n    volume: 36122,\n  },\n  {\n    date: 1462907640000,\n    open: 50.835,\n    high: 50.85,\n    low: 50.835,\n    close: 50.8415,\n    volume: 21010,\n  },\n  {\n    date: 1462907700000,\n    open: 50.84,\n    high: 50.845,\n    low: 50.825,\n    close: 50.84,\n    volume: 60640,\n  },\n  {\n    date: 1462907760000,\n    open: 50.84,\n    high: 50.865,\n    low: 50.84,\n    close: 50.856,\n    volume: 62318,\n  },\n  {\n    date: 1462907820000,\n    open: 50.853,\n    high: 50.87,\n    low: 50.85,\n    close: 50.87,\n    volume: 21179,\n  },\n  {\n    date: 1462907880000,\n    open: 50.87,\n    high: 50.895,\n    low: 50.86,\n    close: 50.86,\n    volume: 91825,\n  },\n  {\n    date: 1462907940000,\n    open: 50.865,\n    high: 50.89,\n    low: 50.86,\n    close: 50.89,\n    volume: 56064,\n  },\n  {\n    date: 1462908000000,\n    open: 50.8835,\n    high: 50.9,\n    low: 50.88,\n    close: 50.89,\n    volume: 53171,\n  },\n  {\n    date: 1462908060000,\n    open: 50.885,\n    high: 50.91,\n    low: 50.88,\n    close: 50.91,\n    volume: 33291,\n  },\n  {\n    date: 1462908120000,\n    open: 50.9,\n    high: 50.92,\n    low: 50.9,\n    close: 50.905,\n    volume: 74919,\n  },\n  {\n    date: 1462908180000,\n    open: 50.907,\n    high: 50.95,\n    low: 50.907,\n    close: 50.93,\n    volume: 94985,\n  },\n  {\n    date: 1462908240000,\n    open: 50.928,\n    high: 50.93,\n    low: 50.9,\n    close: 50.9201,\n    volume: 61799,\n  },\n  {\n    date: 1462908300000,\n    open: 50.93,\n    high: 50.95,\n    low: 50.92,\n    close: 50.935,\n    volume: 39824,\n  },\n  {\n    date: 1462908360000,\n    open: 50.93,\n    high: 50.95,\n    low: 50.93,\n    close: 50.935,\n    volume: 101162,\n  },\n  {\n    date: 1462908420000,\n    open: 50.94,\n    high: 50.9479,\n    low: 50.91,\n    close: 50.93,\n    volume: 52622,\n  },\n  {\n    date: 1462908480000,\n    open: 50.94,\n    high: 50.96,\n    low: 50.93,\n    close: 50.955,\n    volume: 68531,\n  },\n  {\n    date: 1462908540000,\n    open: 50.95,\n    high: 50.955,\n    low: 50.94,\n    close: 50.955,\n    volume: 42542,\n  },\n  {\n    date: 1462908600000,\n    open: 50.96,\n    high: 50.97,\n    low: 50.93,\n    close: 50.95,\n    volume: 119586,\n  },\n  {\n    date: 1462908660000,\n    open: 50.95,\n    high: 50.975,\n    low: 50.945,\n    close: 50.955,\n    volume: 129082,\n  },\n  {\n    date: 1462908720000,\n    open: 50.95,\n    high: 50.96,\n    low: 50.93,\n    close: 50.95,\n    volume: 51020,\n  },\n  {\n    date: 1462908780000,\n    open: 50.94,\n    high: 50.95,\n    low: 50.93,\n    close: 50.93,\n    volume: 33721,\n  },\n  {\n    date: 1462908840000,\n    open: 50.94,\n    high: 50.95,\n    low: 50.93,\n    close: 50.95,\n    volume: 45282,\n  },\n  {\n    date: 1462908900000,\n    open: 50.95,\n    high: 50.95,\n    low: 50.93,\n    close: 50.935,\n    volume: 34717,\n  },\n  {\n    date: 1462908960000,\n    open: 50.935,\n    high: 50.96,\n    low: 50.935,\n    close: 50.955,\n    volume: 58450,\n  },\n  {\n    date: 1462909020000,\n    open: 50.96,\n    high: 50.96,\n    low: 50.95,\n    close: 50.9501,\n    volume: 75347,\n  },\n  {\n    date: 1462909080000,\n    open: 50.9599,\n    high: 50.9599,\n    low: 50.93,\n    close: 50.93,\n    volume: 70184,\n  },\n  {\n    date: 1462909140000,\n    open: 50.935,\n    high: 50.96,\n    low: 50.93,\n    close: 50.95,\n    volume: 44750,\n  },\n  {\n    date: 1462909200000,\n    open: 50.96,\n    high: 50.96,\n    low: 50.93,\n    close: 50.93,\n    volume: 66803,\n  },\n  {\n    date: 1462909260000,\n    open: 50.94,\n    high: 50.94,\n    low: 50.905,\n    close: 50.935,\n    volume: 67627,\n  },\n  {\n    date: 1462909320000,\n    open: 50.94,\n    high: 50.99,\n    low: 50.93,\n    close: 50.99,\n    volume: 168463,\n  },\n  {\n    date: 1462909380000,\n    open: 50.985,\n    high: 51,\n    low: 50.98,\n    close: 51,\n    volume: 90179,\n  },\n  {\n    date: 1462909440000,\n    open: 50.995,\n    high: 51.02,\n    low: 50.99,\n    close: 50.99,\n    volume: 174470,\n  },\n  {\n    date: 1462909500000,\n    open: 51,\n    high: 51.01,\n    low: 50.99,\n    close: 51.005,\n    volume: 54513,\n  },\n  {\n    date: 1462909560000,\n    open: 51,\n    high: 51.005,\n    low: 50.99,\n    close: 50.99,\n    volume: 82285,\n  },\n  {\n    date: 1462909620000,\n    open: 50.99,\n    high: 51,\n    low: 50.99,\n    close: 51,\n    volume: 92605,\n  },\n  {\n    date: 1462909680000,\n    open: 51,\n    high: 51.04,\n    low: 51,\n    close: 51.02,\n    volume: 111277,\n  },\n  {\n    date: 1462909740000,\n    open: 51.015,\n    high: 51.02,\n    low: 50.99,\n    close: 51,\n    volume: 76162,\n  },\n  {\n    date: 1462909800000,\n    open: 51,\n    high: 51.005,\n    low: 50.98,\n    close: 50.99,\n    volume: 140015,\n  },\n  {\n    date: 1462909860000,\n    open: 50.99,\n    high: 51,\n    low: 50.98,\n    close: 50.99,\n    volume: 78033,\n  },\n  {\n    date: 1462909920000,\n    open: 50.99,\n    high: 51.01,\n    low: 50.98,\n    close: 51.005,\n    volume: 132327,\n  },\n  {\n    date: 1462909980000,\n    open: 51.01,\n    high: 51.02,\n    low: 51,\n    close: 51.02,\n    volume: 94648,\n  },\n  {\n    date: 1462910040000,\n    open: 51.02,\n    high: 51.06,\n    low: 51.01,\n    close: 51.05,\n    volume: 213948,\n  },\n  {\n    date: 1462910100000,\n    open: 51.05,\n    high: 51.06,\n    low: 51.04,\n    close: 51.05,\n    volume: 128420,\n  },\n  {\n    date: 1462910160000,\n    open: 51.05,\n    high: 51.06,\n    low: 51.03,\n    close: 51.04,\n    volume: 177479,\n  },\n  {\n    date: 1462910220000,\n    open: 51.04,\n    high: 51.05,\n    low: 51.03,\n    close: 51.041,\n    volume: 118095,\n  },\n  {\n    date: 1462910280000,\n    open: 51.05,\n    high: 51.08,\n    low: 51.04,\n    close: 51.08,\n    volume: 217897,\n  },\n  {\n    date: 1462910340000,\n    open: 51.075,\n    high: 51.1,\n    low: 51.07,\n    close: 51.085,\n    volume: 332355,\n  },\n  {\n    date: 1462910400000,\n    open: 51.09,\n    high: 51.09,\n    low: 51.02,\n    close: 51.02,\n    volume: 2141469,\n  },\n  {\n    date: 1462973400000,\n    open: 51.13,\n    high: 51.14,\n    low: 51.13,\n    close: 51.13,\n    volume: 468332,\n  },\n  {\n    date: 1462973460000,\n    open: 51.13,\n    high: 51.16,\n    low: 51.02,\n    close: 51.14,\n    volume: 194587,\n  },\n  {\n    date: 1462973520000,\n    open: 51.13,\n    high: 51.25,\n    low: 51.13,\n    close: 51.21,\n    volume: 110550,\n  },\n  {\n    date: 1462973580000,\n    open: 51.215,\n    high: 51.33,\n    low: 51.18,\n    close: 51.32,\n    volume: 152522,\n  },\n  {\n    date: 1462973640000,\n    open: 51.3299,\n    high: 51.3775,\n    low: 51.3,\n    close: 51.36,\n    volume: 115397,\n  },\n  {\n    date: 1462973700000,\n    open: 51.36,\n    high: 51.36,\n    low: 51.3,\n    close: 51.32,\n    volume: 80400,\n  },\n  {\n    date: 1462973760000,\n    open: 51.335,\n    high: 51.335,\n    low: 51.2645,\n    close: 51.305,\n    volume: 81939,\n  },\n  {\n    date: 1462973820000,\n    open: 51.3001,\n    high: 51.31,\n    low: 51.24,\n    close: 51.2401,\n    volume: 99379,\n  },\n  {\n    date: 1462973880000,\n    open: 51.24,\n    high: 51.37,\n    low: 51.24,\n    close: 51.365,\n    volume: 77814,\n  },\n  {\n    date: 1462973940000,\n    open: 51.365,\n    high: 51.465,\n    low: 51.35,\n    close: 51.44,\n    volume: 115023,\n  },\n  {\n    date: 1462974000000,\n    open: 51.45,\n    high: 51.46,\n    low: 51.35,\n    close: 51.361,\n    volume: 91194,\n  },\n  {\n    date: 1462974060000,\n    open: 51.36,\n    high: 51.42,\n    low: 51.36,\n    close: 51.41,\n    volume: 77590,\n  },\n  {\n    date: 1462974120000,\n    open: 51.405,\n    high: 51.405,\n    low: 51.32,\n    close: 51.33,\n    volume: 80085,\n  },\n  {\n    date: 1462974180000,\n    open: 51.328,\n    high: 51.33,\n    low: 51.25,\n    close: 51.263,\n    volume: 106618,\n  },\n  {\n    date: 1462974240000,\n    open: 51.26,\n    high: 51.27,\n    low: 51.21,\n    close: 51.25,\n    volume: 60057,\n  },\n  {\n    date: 1462974300000,\n    open: 51.26,\n    high: 51.3023,\n    low: 51.25,\n    close: 51.285,\n    volume: 54900,\n  },\n  {\n    date: 1462974360000,\n    open: 51.285,\n    high: 51.38,\n    low: 51.28,\n    close: 51.375,\n    volume: 79333,\n  },\n  {\n    date: 1462974420000,\n    open: 51.38,\n    high: 51.45,\n    low: 51.37,\n    close: 51.4401,\n    volume: 127841,\n  },\n  {\n    date: 1462974480000,\n    open: 51.4457,\n    high: 51.485,\n    low: 51.43,\n    close: 51.47,\n    volume: 86820,\n  },\n  {\n    date: 1462974540000,\n    open: 51.46,\n    high: 51.56,\n    low: 51.46,\n    close: 51.525,\n    volume: 235334,\n  },\n  {\n    date: 1462974600000,\n    open: 51.52,\n    high: 51.53,\n    low: 51.495,\n    close: 51.52,\n    volume: 85616,\n  },\n  {\n    date: 1462974660000,\n    open: 51.515,\n    high: 51.52,\n    low: 51.5,\n    close: 51.52,\n    volume: 127600,\n  },\n  {\n    date: 1462974720000,\n    open: 51.52,\n    high: 51.55,\n    low: 51.52,\n    close: 51.5311,\n    volume: 45330,\n  },\n  {\n    date: 1462974780000,\n    open: 51.54,\n    high: 51.54,\n    low: 51.5,\n    close: 51.5099,\n    volume: 80296,\n  },\n  {\n    date: 1462974840000,\n    open: 51.51,\n    high: 51.53,\n    low: 51.5,\n    close: 51.505,\n    volume: 35073,\n  },\n  {\n    date: 1462974900000,\n    open: 51.505,\n    high: 51.5299,\n    low: 51.48,\n    close: 51.5055,\n    volume: 88457,\n  },\n  {\n    date: 1462974960000,\n    open: 51.51,\n    high: 51.52,\n    low: 51.5,\n    close: 51.51,\n    volume: 81239,\n  },\n  {\n    date: 1462975020000,\n    open: 51.51,\n    high: 51.52,\n    low: 51.49,\n    close: 51.5,\n    volume: 65610,\n  },\n  {\n    date: 1462975080000,\n    open: 51.49,\n    high: 51.53,\n    low: 51.49,\n    close: 51.521,\n    volume: 31159,\n  },\n  {\n    date: 1462975140000,\n    open: 51.52,\n    high: 51.53,\n    low: 51.5,\n    close: 51.529,\n    volume: 25511,\n  },\n  {\n    date: 1462975200000,\n    open: 51.52,\n    high: 51.53,\n    low: 51.51,\n    close: 51.51,\n    volume: 41698,\n  },\n  {\n    date: 1462975260000,\n    open: 51.51,\n    high: 51.52,\n    low: 51.5,\n    close: 51.5,\n    volume: 30403,\n  },\n  {\n    date: 1462975320000,\n    open: 51.5,\n    high: 51.51,\n    low: 51.44,\n    close: 51.45,\n    volume: 121908,\n  },\n  {\n    date: 1462975380000,\n    open: 51.45,\n    high: 51.47,\n    low: 51.445,\n    close: 51.45,\n    volume: 56579,\n  },\n  {\n    date: 1462975440000,\n    open: 51.4555,\n    high: 51.47,\n    low: 51.45,\n    close: 51.458,\n    volume: 40029,\n  },\n  {\n    date: 1462975500000,\n    open: 51.45,\n    high: 51.45,\n    low: 51.42,\n    close: 51.42,\n    volume: 42840,\n  },\n  {\n    date: 1462975560000,\n    open: 51.42,\n    high: 51.4201,\n    low: 51.36,\n    close: 51.375,\n    volume: 64433,\n  },\n  {\n    date: 1462975620000,\n    open: 51.38,\n    high: 51.4,\n    low: 51.35,\n    close: 51.3501,\n    volume: 88987,\n  },\n  {\n    date: 1462975680000,\n    open: 51.355,\n    high: 51.3595,\n    low: 51.34,\n    close: 51.35,\n    volume: 43186,\n  },\n  {\n    date: 1462975740000,\n    open: 51.3436,\n    high: 51.35,\n    low: 51.31,\n    close: 51.31,\n    volume: 48892,\n  },\n  {\n    date: 1462975800000,\n    open: 51.32,\n    high: 51.325,\n    low: 51.31,\n    close: 51.3199,\n    volume: 36585,\n  },\n  {\n    date: 1462975860000,\n    open: 51.31,\n    high: 51.32,\n    low: 51.295,\n    close: 51.31,\n    volume: 69705,\n  },\n  {\n    date: 1462975920000,\n    open: 51.31,\n    high: 51.31,\n    low: 51.27,\n    close: 51.27,\n    volume: 42421,\n  },\n  {\n    date: 1462975980000,\n    open: 51.275,\n    high: 51.2755,\n    low: 51.25,\n    close: 51.25,\n    volume: 29552,\n  },\n  {\n    date: 1462976040000,\n    open: 51.2525,\n    high: 51.365,\n    low: 51.25,\n    close: 51.36,\n    volume: 63286,\n  },\n  {\n    date: 1462976100000,\n    open: 51.37,\n    high: 51.44,\n    low: 51.3689,\n    close: 51.429,\n    volume: 87200,\n  },\n  {\n    date: 1462976160000,\n    open: 51.42,\n    high: 51.43,\n    low: 51.39,\n    close: 51.43,\n    volume: 44782,\n  },\n  {\n    date: 1462976220000,\n    open: 51.44,\n    high: 51.48,\n    low: 51.435,\n    close: 51.45,\n    volume: 60788,\n  },\n  {\n    date: 1462976280000,\n    open: 51.45,\n    high: 51.49,\n    low: 51.44,\n    close: 51.4799,\n    volume: 57728,\n  },\n  {\n    date: 1462976340000,\n    open: 51.47,\n    high: 51.49,\n    low: 51.45,\n    close: 51.475,\n    volume: 60338,\n  },\n  {\n    date: 1462976400000,\n    open: 51.479,\n    high: 51.51,\n    low: 51.46,\n    close: 51.505,\n    volume: 67036,\n  },\n  {\n    date: 1462976460000,\n    open: 51.5,\n    high: 51.53,\n    low: 51.5,\n    close: 51.525,\n    volume: 64284,\n  },\n  {\n    date: 1462976520000,\n    open: 51.5244,\n    high: 51.5399,\n    low: 51.49,\n    close: 51.49,\n    volume: 69688,\n  },\n  {\n    date: 1462976580000,\n    open: 51.499,\n    high: 51.53,\n    low: 51.499,\n    close: 51.52,\n    volume: 38522,\n  },\n  {\n    date: 1462976640000,\n    open: 51.515,\n    high: 51.54,\n    low: 51.51,\n    close: 51.535,\n    volume: 28644,\n  },\n  {\n    date: 1462976700000,\n    open: 51.535,\n    high: 51.55,\n    low: 51.53,\n    close: 51.55,\n    volume: 42233,\n  },\n  {\n    date: 1462976760000,\n    open: 51.55,\n    high: 51.58,\n    low: 51.54,\n    close: 51.5764,\n    volume: 55704,\n  },\n  {\n    date: 1462976820000,\n    open: 51.58,\n    high: 51.59,\n    low: 51.57,\n    close: 51.57,\n    volume: 40196,\n  },\n  {\n    date: 1462976880000,\n    open: 51.575,\n    high: 51.585,\n    low: 51.56,\n    close: 51.5765,\n    volume: 60675,\n  },\n  {\n    date: 1462976940000,\n    open: 51.5736,\n    high: 51.6,\n    low: 51.57,\n    close: 51.58,\n    volume: 53625,\n  },\n  {\n    date: 1462977000000,\n    open: 51.58,\n    high: 51.65,\n    low: 51.57,\n    close: 51.64,\n    volume: 57778,\n  },\n  {\n    date: 1462977060000,\n    open: 51.62,\n    high: 51.71,\n    low: 51.61,\n    close: 51.6272,\n    volume: 203530,\n  },\n  {\n    date: 1462977120000,\n    open: 51.63,\n    high: 51.65,\n    low: 51.6,\n    close: 51.615,\n    volume: 49615,\n  },\n  {\n    date: 1462977180000,\n    open: 51.62,\n    high: 51.715,\n    low: 51.615,\n    close: 51.699,\n    volume: 103914,\n  },\n  {\n    date: 1462977240000,\n    open: 51.7,\n    high: 51.71,\n    low: 51.68,\n    close: 51.69,\n    volume: 52145,\n  },\n  {\n    date: 1462977300000,\n    open: 51.7,\n    high: 51.73,\n    low: 51.69,\n    close: 51.72,\n    volume: 57407,\n  },\n  {\n    date: 1462977360000,\n    open: 51.725,\n    high: 51.75,\n    low: 51.72,\n    close: 51.745,\n    volume: 139793,\n  },\n  {\n    date: 1462977420000,\n    open: 51.75,\n    high: 51.77,\n    low: 51.74,\n    close: 51.76,\n    volume: 138813,\n  },\n  {\n    date: 1462977480000,\n    open: 51.76,\n    high: 51.78,\n    low: 51.76,\n    close: 51.7611,\n    volume: 67750,\n  },\n  {\n    date: 1462977540000,\n    open: 51.76,\n    high: 51.765,\n    low: 51.655,\n    close: 51.69,\n    volume: 122980,\n  },\n  {\n    date: 1462977600000,\n    open: 51.69,\n    high: 51.71,\n    low: 51.68,\n    close: 51.7,\n    volume: 75334,\n  },\n  {\n    date: 1462977660000,\n    open: 51.7,\n    high: 51.71,\n    low: 51.68,\n    close: 51.7,\n    volume: 112178,\n  },\n  {\n    date: 1462977720000,\n    open: 51.69,\n    high: 51.69,\n    low: 51.58,\n    close: 51.63,\n    volume: 80795,\n  },\n  {\n    date: 1462977780000,\n    open: 51.63,\n    high: 51.6359,\n    low: 51.6,\n    close: 51.62,\n    volume: 37536,\n  },\n  {\n    date: 1462977840000,\n    open: 51.62,\n    high: 51.62,\n    low: 51.595,\n    close: 51.605,\n    volume: 53430,\n  },\n  {\n    date: 1462977900000,\n    open: 51.6,\n    high: 51.64,\n    low: 51.595,\n    close: 51.63,\n    volume: 103689,\n  },\n  {\n    date: 1462977960000,\n    open: 51.625,\n    high: 51.65,\n    low: 51.62,\n    close: 51.62,\n    volume: 37551,\n  },\n  {\n    date: 1462978020000,\n    open: 51.63,\n    high: 51.66,\n    low: 51.61,\n    close: 51.659,\n    volume: 39922,\n  },\n  {\n    date: 1462978080000,\n    open: 51.65,\n    high: 51.69,\n    low: 51.65,\n    close: 51.6699,\n    volume: 60591,\n  },\n  {\n    date: 1462978140000,\n    open: 51.665,\n    high: 51.7,\n    low: 51.665,\n    close: 51.69,\n    volume: 43626,\n  },\n  {\n    date: 1462978200000,\n    open: 51.69,\n    high: 51.72,\n    low: 51.68,\n    close: 51.69,\n    volume: 92844,\n  },\n  {\n    date: 1462978260000,\n    open: 51.68,\n    high: 51.69,\n    low: 51.63,\n    close: 51.65,\n    volume: 111469,\n  },\n  {\n    date: 1462978320000,\n    open: 51.66,\n    high: 51.68,\n    low: 51.65,\n    close: 51.68,\n    volume: 51618,\n  },\n  {\n    date: 1462978380000,\n    open: 51.68,\n    high: 51.69,\n    low: 51.67,\n    close: 51.68,\n    volume: 21462,\n  },\n  {\n    date: 1462978440000,\n    open: 51.68,\n    high: 51.69,\n    low: 51.66,\n    close: 51.675,\n    volume: 62920,\n  },\n  {\n    date: 1462978500000,\n    open: 51.675,\n    high: 51.69,\n    low: 51.66,\n    close: 51.67,\n    volume: 30463,\n  },\n  {\n    date: 1462978560000,\n    open: 51.665,\n    high: 51.68,\n    low: 51.65,\n    close: 51.68,\n    volume: 58443,\n  },\n  {\n    date: 1462978620000,\n    open: 51.68,\n    high: 51.72,\n    low: 51.675,\n    close: 51.715,\n    volume: 36043,\n  },\n  {\n    date: 1462978680000,\n    open: 51.7199,\n    high: 51.735,\n    low: 51.7,\n    close: 51.73,\n    volume: 44052,\n  },\n  {\n    date: 1462978740000,\n    open: 51.73,\n    high: 51.75,\n    low: 51.72,\n    close: 51.75,\n    volume: 72401,\n  },\n  {\n    date: 1462978800000,\n    open: 51.7457,\n    high: 51.76,\n    low: 51.72,\n    close: 51.725,\n    volume: 100138,\n  },\n  {\n    date: 1462978860000,\n    open: 51.72,\n    high: 51.729,\n    low: 51.6,\n    close: 51.6,\n    volume: 123027,\n  },\n  {\n    date: 1462978920000,\n    open: 51.5999,\n    high: 51.5999,\n    low: 51.52,\n    close: 51.525,\n    volume: 49063,\n  },\n  {\n    date: 1462978980000,\n    open: 51.525,\n    high: 51.53,\n    low: 51.51,\n    close: 51.5133,\n    volume: 38657,\n  },\n  {\n    date: 1462979040000,\n    open: 51.52,\n    high: 51.53,\n    low: 51.47,\n    close: 51.47,\n    volume: 82390,\n  },\n  {\n    date: 1462979100000,\n    open: 51.46,\n    high: 51.478,\n    low: 51.38,\n    close: 51.39,\n    volume: 107751,\n  },\n  {\n    date: 1462979160000,\n    open: 51.38,\n    high: 51.42,\n    low: 51.34,\n    close: 51.405,\n    volume: 63422,\n  },\n  {\n    date: 1462979220000,\n    open: 51.41,\n    high: 51.4499,\n    low: 51.41,\n    close: 51.445,\n    volume: 37125,\n  },\n  {\n    date: 1462979280000,\n    open: 51.44,\n    high: 51.49,\n    low: 51.435,\n    close: 51.475,\n    volume: 89144,\n  },\n  {\n    date: 1462979340000,\n    open: 51.475,\n    high: 51.52,\n    low: 51.465,\n    close: 51.51,\n    volume: 41648,\n  },\n  {\n    date: 1462979400000,\n    open: 51.5176,\n    high: 51.55,\n    low: 51.51,\n    close: 51.54,\n    volume: 31529,\n  },\n  {\n    date: 1462979460000,\n    open: 51.54,\n    high: 51.56,\n    low: 51.53,\n    close: 51.53,\n    volume: 43517,\n  },\n  {\n    date: 1462979520000,\n    open: 51.53,\n    high: 51.53,\n    low: 51.47,\n    close: 51.51,\n    volume: 96873,\n  },\n  {\n    date: 1462979580000,\n    open: 51.51,\n    high: 51.54,\n    low: 51.5,\n    close: 51.535,\n    volume: 85441,\n  },\n  {\n    date: 1462979640000,\n    open: 51.525,\n    high: 51.555,\n    low: 51.525,\n    close: 51.535,\n    volume: 60706,\n  },\n  {\n    date: 1462979700000,\n    open: 51.54,\n    high: 51.59,\n    low: 51.54,\n    close: 51.55,\n    volume: 31386,\n  },\n  {\n    date: 1462979760000,\n    open: 51.5499,\n    high: 51.55,\n    low: 51.51,\n    close: 51.51,\n    volume: 32264,\n  },\n  {\n    date: 1462979820000,\n    open: 51.51,\n    high: 51.5201,\n    low: 51.48,\n    close: 51.5201,\n    volume: 40569,\n  },\n  {\n    date: 1462979880000,\n    open: 51.525,\n    high: 51.53,\n    low: 51.51,\n    close: 51.51,\n    volume: 10606,\n  },\n  {\n    date: 1462979940000,\n    open: 51.515,\n    high: 51.55,\n    low: 51.505,\n    close: 51.545,\n    volume: 52839,\n  },\n  {\n    date: 1462980000000,\n    open: 51.54,\n    high: 51.55,\n    low: 51.5205,\n    close: 51.54,\n    volume: 13861,\n  },\n  {\n    date: 1462980060000,\n    open: 51.54,\n    high: 51.545,\n    low: 51.52,\n    close: 51.52,\n    volume: 8934,\n  },\n  {\n    date: 1462980120000,\n    open: 51.53,\n    high: 51.53,\n    low: 51.495,\n    close: 51.53,\n    volume: 46319,\n  },\n  {\n    date: 1462980180000,\n    open: 51.53,\n    high: 51.555,\n    low: 51.52,\n    close: 51.52,\n    volume: 22583,\n  },\n  {\n    date: 1462980240000,\n    open: 51.5272,\n    high: 51.5272,\n    low: 51.49,\n    close: 51.5,\n    volume: 44211,\n  },\n  {\n    date: 1462980300000,\n    open: 51.5,\n    high: 51.51,\n    low: 51.49,\n    close: 51.51,\n    volume: 16433,\n  },\n  {\n    date: 1462980360000,\n    open: 51.51,\n    high: 51.57,\n    low: 51.51,\n    close: 51.55,\n    volume: 45077,\n  },\n  {\n    date: 1462980420000,\n    open: 51.54,\n    high: 51.57,\n    low: 51.52,\n    close: 51.56,\n    volume: 46480,\n  },\n  {\n    date: 1462980480000,\n    open: 51.569,\n    high: 51.58,\n    low: 51.54,\n    close: 51.575,\n    volume: 101546,\n  },\n  {\n    date: 1462980540000,\n    open: 51.57,\n    high: 51.58,\n    low: 51.56,\n    close: 51.57,\n    volume: 76642,\n  },\n  {\n    date: 1462980600000,\n    open: 51.57,\n    high: 51.58,\n    low: 51.56,\n    close: 51.57,\n    volume: 37632,\n  },\n  {\n    date: 1462980660000,\n    open: 51.57,\n    high: 51.58,\n    low: 51.52,\n    close: 51.52,\n    volume: 168637,\n  },\n  {\n    date: 1462980720000,\n    open: 51.51,\n    high: 51.55,\n    low: 51.51,\n    close: 51.55,\n    volume: 29574,\n  },\n  {\n    date: 1462980780000,\n    open: 51.54,\n    high: 51.57,\n    low: 51.54,\n    close: 51.55,\n    volume: 56000,\n  },\n  {\n    date: 1462980840000,\n    open: 51.55,\n    high: 51.55,\n    low: 51.525,\n    close: 51.535,\n    volume: 49225,\n  },\n  {\n    date: 1462980900000,\n    open: 51.535,\n    high: 51.54,\n    low: 51.5,\n    close: 51.525,\n    volume: 66536,\n  },\n  {\n    date: 1462980960000,\n    open: 51.53,\n    high: 51.59,\n    low: 51.53,\n    close: 51.57,\n    volume: 61325,\n  },\n  {\n    date: 1462981020000,\n    open: 51.58,\n    high: 51.58,\n    low: 51.515,\n    close: 51.525,\n    volume: 34299,\n  },\n  {\n    date: 1462981080000,\n    open: 51.525,\n    high: 51.535,\n    low: 51.47,\n    close: 51.48,\n    volume: 38247,\n  },\n  {\n    date: 1462981140000,\n    open: 51.485,\n    high: 51.495,\n    low: 51.47,\n    close: 51.47,\n    volume: 24870,\n  },\n  {\n    date: 1462981200000,\n    open: 51.4759,\n    high: 51.49,\n    low: 51.47,\n    close: 51.48,\n    volume: 40608,\n  },\n  {\n    date: 1462981260000,\n    open: 51.4813,\n    high: 51.49,\n    low: 51.45,\n    close: 51.45,\n    volume: 39273,\n  },\n  {\n    date: 1462981320000,\n    open: 51.455,\n    high: 51.53,\n    low: 51.455,\n    close: 51.5211,\n    volume: 216872,\n  },\n  {\n    date: 1462981380000,\n    open: 51.53,\n    high: 51.53,\n    low: 51.4901,\n    close: 51.495,\n    volume: 27547,\n  },\n  {\n    date: 1462981440000,\n    open: 51.5064,\n    high: 51.52,\n    low: 51.4935,\n    close: 51.51,\n    volume: 14571,\n  },\n  {\n    date: 1462981500000,\n    open: 51.505,\n    high: 51.54,\n    low: 51.505,\n    close: 51.54,\n    volume: 29126,\n  },\n  {\n    date: 1462981560000,\n    open: 51.53,\n    high: 51.535,\n    low: 51.48,\n    close: 51.48,\n    volume: 25448,\n  },\n  {\n    date: 1462981620000,\n    open: 51.48,\n    high: 51.48,\n    low: 51.45,\n    close: 51.46,\n    volume: 50662,\n  },\n  {\n    date: 1462981680000,\n    open: 51.4532,\n    high: 51.4663,\n    low: 51.42,\n    close: 51.43,\n    volume: 39046,\n  },\n  {\n    date: 1462981740000,\n    open: 51.43,\n    high: 51.45,\n    low: 51.41,\n    close: 51.41,\n    volume: 22613,\n  },\n  {\n    date: 1462981800000,\n    open: 51.42,\n    high: 51.42,\n    low: 51.4,\n    close: 51.4071,\n    volume: 36439,\n  },\n  {\n    date: 1462981860000,\n    open: 51.4,\n    high: 51.409,\n    low: 51.39,\n    close: 51.3999,\n    volume: 37396,\n  },\n  {\n    date: 1462981920000,\n    open: 51.4,\n    high: 51.41,\n    low: 51.39,\n    close: 51.4,\n    volume: 33704,\n  },\n  {\n    date: 1462981980000,\n    open: 51.4,\n    high: 51.4089,\n    low: 51.39,\n    close: 51.39,\n    volume: 16303,\n  },\n  {\n    date: 1462982040000,\n    open: 51.4,\n    high: 51.4,\n    low: 51.39,\n    close: 51.4,\n    volume: 13046,\n  },\n  {\n    date: 1462982100000,\n    open: 51.3901,\n    high: 51.405,\n    low: 51.39,\n    close: 51.4,\n    volume: 34037,\n  },\n  {\n    date: 1462982160000,\n    open: 51.4,\n    high: 51.405,\n    low: 51.3699,\n    close: 51.37,\n    volume: 49486,\n  },\n  {\n    date: 1462982220000,\n    open: 51.36,\n    high: 51.38,\n    low: 51.36,\n    close: 51.37,\n    volume: 24303,\n  },\n  {\n    date: 1462982280000,\n    open: 51.37,\n    high: 51.37,\n    low: 51.35,\n    close: 51.36,\n    volume: 24126,\n  },\n  {\n    date: 1462982340000,\n    open: 51.355,\n    high: 51.37,\n    low: 51.35,\n    close: 51.36,\n    volume: 10679,\n  },\n  {\n    date: 1462982400000,\n    open: 51.36,\n    high: 51.37,\n    low: 51.34,\n    close: 51.36,\n    volume: 30698,\n  },\n  {\n    date: 1462982460000,\n    open: 51.36,\n    high: 51.39,\n    low: 51.349,\n    close: 51.39,\n    volume: 54646,\n  },\n  {\n    date: 1462982520000,\n    open: 51.4,\n    high: 51.4,\n    low: 51.36,\n    close: 51.36,\n    volume: 34727,\n  },\n  {\n    date: 1462982580000,\n    open: 51.37,\n    high: 51.375,\n    low: 51.35,\n    close: 51.35,\n    volume: 30200,\n  },\n  {\n    date: 1462982640000,\n    open: 51.35,\n    high: 51.35,\n    low: 51.305,\n    close: 51.305,\n    volume: 32533,\n  },\n  {\n    date: 1462982700000,\n    open: 51.31,\n    high: 51.35,\n    low: 51.31,\n    close: 51.34,\n    volume: 17250,\n  },\n  {\n    date: 1462982760000,\n    open: 51.34,\n    high: 51.3611,\n    low: 51.34,\n    close: 51.34,\n    volume: 54991,\n  },\n  {\n    date: 1462982820000,\n    open: 51.34,\n    high: 51.36,\n    low: 51.33,\n    close: 51.35,\n    volume: 19785,\n  },\n  {\n    date: 1462982880000,\n    open: 51.36,\n    high: 51.39,\n    low: 51.36,\n    close: 51.385,\n    volume: 27917,\n  },\n  {\n    date: 1462982940000,\n    open: 51.385,\n    high: 51.4,\n    low: 51.38,\n    close: 51.4,\n    volume: 6718,\n  },\n  {\n    date: 1462983000000,\n    open: 51.4,\n    high: 51.4,\n    low: 51.38,\n    close: 51.39,\n    volume: 21907,\n  },\n  {\n    date: 1462983060000,\n    open: 51.4,\n    high: 51.4099,\n    low: 51.37,\n    close: 51.37,\n    volume: 21640,\n  },\n  {\n    date: 1462983120000,\n    open: 51.37,\n    high: 51.39,\n    low: 51.36,\n    close: 51.38,\n    volume: 14368,\n  },\n  {\n    date: 1462983180000,\n    open: 51.38,\n    high: 51.4,\n    low: 51.37,\n    close: 51.39,\n    volume: 14742,\n  },\n  {\n    date: 1462983240000,\n    open: 51.39,\n    high: 51.42,\n    low: 51.385,\n    close: 51.42,\n    volume: 22384,\n  },\n  {\n    date: 1462983300000,\n    open: 51.42,\n    high: 51.45,\n    low: 51.42,\n    close: 51.448,\n    volume: 18104,\n  },\n  {\n    date: 1462983360000,\n    open: 51.449,\n    high: 51.45,\n    low: 51.42,\n    close: 51.43,\n    volume: 40637,\n  },\n  {\n    date: 1462983420000,\n    open: 51.435,\n    high: 51.47,\n    low: 51.425,\n    close: 51.47,\n    volume: 36148,\n  },\n  {\n    date: 1462983480000,\n    open: 51.46,\n    high: 51.495,\n    low: 51.45,\n    close: 51.47,\n    volume: 53652,\n  },\n  {\n    date: 1462983540000,\n    open: 51.46,\n    high: 51.46,\n    low: 51.43,\n    close: 51.44,\n    volume: 17221,\n  },\n  {\n    date: 1462983600000,\n    open: 51.4438,\n    high: 51.46,\n    low: 51.44,\n    close: 51.46,\n    volume: 14562,\n  },\n  {\n    date: 1462983660000,\n    open: 51.47,\n    high: 51.48,\n    low: 51.445,\n    close: 51.4495,\n    volume: 16392,\n  },\n  {\n    date: 1462983720000,\n    open: 51.44,\n    high: 51.4401,\n    low: 51.415,\n    close: 51.43,\n    volume: 39191,\n  },\n  {\n    date: 1462983780000,\n    open: 51.43,\n    high: 51.44,\n    low: 51.4017,\n    close: 51.4017,\n    volume: 22353,\n  },\n  {\n    date: 1462983840000,\n    open: 51.4,\n    high: 51.41,\n    low: 51.38,\n    close: 51.38,\n    volume: 19293,\n  },\n  {\n    date: 1462983900000,\n    open: 51.38,\n    high: 51.385,\n    low: 51.37,\n    close: 51.37,\n    volume: 16224,\n  },\n  {\n    date: 1462983960000,\n    open: 51.3662,\n    high: 51.38,\n    low: 51.362,\n    close: 51.37,\n    volume: 17840,\n  },\n  {\n    date: 1462984020000,\n    open: 51.37,\n    high: 51.39,\n    low: 51.37,\n    close: 51.38,\n    volume: 19461,\n  },\n  {\n    date: 1462984080000,\n    open: 51.39,\n    high: 51.4,\n    low: 51.37,\n    close: 51.399,\n    volume: 13137,\n  },\n  {\n    date: 1462984140000,\n    open: 51.395,\n    high: 51.4062,\n    low: 51.39,\n    close: 51.3901,\n    volume: 12489,\n  },\n  {\n    date: 1462984200000,\n    open: 51.395,\n    high: 51.3999,\n    low: 51.365,\n    close: 51.37,\n    volume: 17961,\n  },\n  {\n    date: 1462984260000,\n    open: 51.37,\n    high: 51.39,\n    low: 51.365,\n    close: 51.385,\n    volume: 11359,\n  },\n  {\n    date: 1462984320000,\n    open: 51.38,\n    high: 51.395,\n    low: 51.38,\n    close: 51.38,\n    volume: 20385,\n  },\n  {\n    date: 1462984380000,\n    open: 51.38,\n    high: 51.39,\n    low: 51.36,\n    close: 51.36,\n    volume: 22565,\n  },\n  {\n    date: 1462984440000,\n    open: 51.36,\n    high: 51.3699,\n    low: 51.36,\n    close: 51.365,\n    volume: 4468,\n  },\n  {\n    date: 1462984500000,\n    open: 51.36,\n    high: 51.38,\n    low: 51.36,\n    close: 51.375,\n    volume: 26147,\n  },\n  {\n    date: 1462984560000,\n    open: 51.375,\n    high: 51.38,\n    low: 51.36,\n    close: 51.3685,\n    volume: 18845,\n  },\n  {\n    date: 1462984620000,\n    open: 51.37,\n    high: 51.37,\n    low: 51.32,\n    close: 51.32,\n    volume: 34966,\n  },\n  {\n    date: 1462984680000,\n    open: 51.32,\n    high: 51.32,\n    low: 51.3001,\n    close: 51.315,\n    volume: 15210,\n  },\n  {\n    date: 1462984740000,\n    open: 51.3175,\n    high: 51.375,\n    low: 51.31,\n    close: 51.37,\n    volume: 33836,\n  },\n  {\n    date: 1462984800000,\n    open: 51.375,\n    high: 51.39,\n    low: 51.37,\n    close: 51.38,\n    volume: 19493,\n  },\n  {\n    date: 1462984860000,\n    open: 51.3895,\n    high: 51.41,\n    low: 51.38,\n    close: 51.4,\n    volume: 79293,\n  },\n  {\n    date: 1462984920000,\n    open: 51.4,\n    high: 51.41,\n    low: 51.38,\n    close: 51.38,\n    volume: 38575,\n  },\n  {\n    date: 1462984980000,\n    open: 51.385,\n    high: 51.39,\n    low: 51.375,\n    close: 51.39,\n    volume: 39952,\n  },\n  {\n    date: 1462985040000,\n    open: 51.39,\n    high: 51.4,\n    low: 51.385,\n    close: 51.385,\n    volume: 44342,\n  },\n  {\n    date: 1462985100000,\n    open: 51.385,\n    high: 51.4,\n    low: 51.37,\n    close: 51.37,\n    volume: 18399,\n  },\n  {\n    date: 1462985160000,\n    open: 51.3732,\n    high: 51.38,\n    low: 51.36,\n    close: 51.37,\n    volume: 17259,\n  },\n  {\n    date: 1462985220000,\n    open: 51.37,\n    high: 51.38,\n    low: 51.365,\n    close: 51.37,\n    volume: 10226,\n  },\n  {\n    date: 1462985280000,\n    open: 51.37,\n    high: 51.3701,\n    low: 51.36,\n    close: 51.365,\n    volume: 10921,\n  },\n  {\n    date: 1462985340000,\n    open: 51.37,\n    high: 51.38,\n    low: 51.36,\n    close: 51.38,\n    volume: 33993,\n  },\n  {\n    date: 1462985400000,\n    open: 51.38,\n    high: 51.395,\n    low: 51.35,\n    close: 51.36,\n    volume: 40627,\n  },\n  {\n    date: 1462985460000,\n    open: 51.351,\n    high: 51.351,\n    low: 51.33,\n    close: 51.34,\n    volume: 17600,\n  },\n  {\n    date: 1462985520000,\n    open: 51.34,\n    high: 51.34,\n    low: 51.32,\n    close: 51.33,\n    volume: 21996,\n  },\n  {\n    date: 1462985580000,\n    open: 51.33,\n    high: 51.34,\n    low: 51.31,\n    close: 51.31,\n    volume: 18068,\n  },\n  {\n    date: 1462985640000,\n    open: 51.3064,\n    high: 51.3064,\n    low: 51.27,\n    close: 51.289,\n    volume: 51982,\n  },\n  {\n    date: 1462985700000,\n    open: 51.29,\n    high: 51.29,\n    low: 51.27,\n    close: 51.2864,\n    volume: 13732,\n  },\n  {\n    date: 1462985760000,\n    open: 51.2833,\n    high: 51.2833,\n    low: 51.265,\n    close: 51.27,\n    volume: 19089,\n  },\n  {\n    date: 1462985820000,\n    open: 51.279,\n    high: 51.2899,\n    low: 51.265,\n    close: 51.2899,\n    volume: 22685,\n  },\n  {\n    date: 1462985880000,\n    open: 51.285,\n    high: 51.286,\n    low: 51.26,\n    close: 51.2671,\n    volume: 18005,\n  },\n  {\n    date: 1462985940000,\n    open: 51.27,\n    high: 51.275,\n    low: 51.26,\n    close: 51.27,\n    volume: 25623,\n  },\n  {\n    date: 1462986000000,\n    open: 51.27,\n    high: 51.279,\n    low: 51.26,\n    close: 51.27,\n    volume: 14217,\n  },\n  {\n    date: 1462986060000,\n    open: 51.27,\n    high: 51.29,\n    low: 51.26,\n    close: 51.26,\n    volume: 32162,\n  },\n  {\n    date: 1462986120000,\n    open: 51.265,\n    high: 51.27,\n    low: 51.25,\n    close: 51.2599,\n    volume: 32474,\n  },\n  {\n    date: 1462986180000,\n    open: 51.2574,\n    high: 51.26,\n    low: 51.245,\n    close: 51.252,\n    volume: 52184,\n  },\n  {\n    date: 1462986240000,\n    open: 51.26,\n    high: 51.29,\n    low: 51.255,\n    close: 51.2899,\n    volume: 24209,\n  },\n  {\n    date: 1462986300000,\n    open: 51.28,\n    high: 51.3,\n    low: 51.27,\n    close: 51.3,\n    volume: 20710,\n  },\n  {\n    date: 1462986360000,\n    open: 51.3,\n    high: 51.3299,\n    low: 51.29,\n    close: 51.3299,\n    volume: 16838,\n  },\n  {\n    date: 1462986420000,\n    open: 51.329,\n    high: 51.33,\n    low: 51.3,\n    close: 51.32,\n    volume: 29893,\n  },\n  {\n    date: 1462986480000,\n    open: 51.325,\n    high: 51.34,\n    low: 51.32,\n    close: 51.3265,\n    volume: 36644,\n  },\n  {\n    date: 1462986540000,\n    open: 51.33,\n    high: 51.3428,\n    low: 51.32,\n    close: 51.33,\n    volume: 33329,\n  },\n  {\n    date: 1462986600000,\n    open: 51.3233,\n    high: 51.3233,\n    low: 51.3,\n    close: 51.3,\n    volume: 21303,\n  },\n  {\n    date: 1462986660000,\n    open: 51.3,\n    high: 51.325,\n    low: 51.3,\n    close: 51.31,\n    volume: 21187,\n  },\n  {\n    date: 1462986720000,\n    open: 51.31,\n    high: 51.33,\n    low: 51.309,\n    close: 51.33,\n    volume: 25420,\n  },\n  {\n    date: 1462986780000,\n    open: 51.33,\n    high: 51.3358,\n    low: 51.29,\n    close: 51.29,\n    volume: 24096,\n  },\n  {\n    date: 1462986840000,\n    open: 51.29,\n    high: 51.31,\n    low: 51.285,\n    close: 51.31,\n    volume: 25943,\n  },\n  {\n    date: 1462986900000,\n    open: 51.3063,\n    high: 51.31,\n    low: 51.289,\n    close: 51.289,\n    volume: 17468,\n  },\n  {\n    date: 1462986960000,\n    open: 51.28,\n    high: 51.3,\n    low: 51.28,\n    close: 51.285,\n    volume: 14950,\n  },\n  {\n    date: 1462987020000,\n    open: 51.28,\n    high: 51.2868,\n    low: 51.27,\n    close: 51.2766,\n    volume: 4208,\n  },\n  {\n    date: 1462987080000,\n    open: 51.27,\n    high: 51.3,\n    low: 51.27,\n    close: 51.3,\n    volume: 25872,\n  },\n  {\n    date: 1462987140000,\n    open: 51.295,\n    high: 51.31,\n    low: 51.29,\n    close: 51.31,\n    volume: 2859,\n  },\n  {\n    date: 1462987200000,\n    open: 51.305,\n    high: 51.305,\n    low: 51.28,\n    close: 51.2832,\n    volume: 28854,\n  },\n  {\n    date: 1462987260000,\n    open: 51.28,\n    high: 51.3,\n    low: 51.28,\n    close: 51.28,\n    volume: 20787,\n  },\n  {\n    date: 1462987320000,\n    open: 51.285,\n    high: 51.285,\n    low: 51.25,\n    close: 51.2699,\n    volume: 39525,\n  },\n  {\n    date: 1462987380000,\n    open: 51.265,\n    high: 51.265,\n    low: 51.24,\n    close: 51.24,\n    volume: 34890,\n  },\n  {\n    date: 1462987440000,\n    open: 51.242,\n    high: 51.25,\n    low: 51.21,\n    close: 51.235,\n    volume: 26498,\n  },\n  {\n    date: 1462987500000,\n    open: 51.23,\n    high: 51.2495,\n    low: 51.23,\n    close: 51.2399,\n    volume: 17674,\n  },\n  {\n    date: 1462987560000,\n    open: 51.23,\n    high: 51.2399,\n    low: 51.2,\n    close: 51.21,\n    volume: 31259,\n  },\n  {\n    date: 1462987620000,\n    open: 51.21,\n    high: 51.2199,\n    low: 51.2,\n    close: 51.2,\n    volume: 62556,\n  },\n  {\n    date: 1462987680000,\n    open: 51.209,\n    high: 51.24,\n    low: 51.2,\n    close: 51.22,\n    volume: 30273,\n  },\n  {\n    date: 1462987740000,\n    open: 51.22,\n    high: 51.25,\n    low: 51.22,\n    close: 51.25,\n    volume: 17454,\n  },\n  {\n    date: 1462987800000,\n    open: 51.25,\n    high: 51.2799,\n    low: 51.24,\n    close: 51.2592,\n    volume: 33605,\n  },\n  {\n    date: 1462987860000,\n    open: 51.255,\n    high: 51.26,\n    low: 51.24,\n    close: 51.26,\n    volume: 24625,\n  },\n  {\n    date: 1462987920000,\n    open: 51.26,\n    high: 51.26,\n    low: 51.24,\n    close: 51.24,\n    volume: 18064,\n  },\n  {\n    date: 1462987980000,\n    open: 51.23,\n    high: 51.24,\n    low: 51.22,\n    close: 51.23,\n    volume: 21182,\n  },\n  {\n    date: 1462988040000,\n    open: 51.23,\n    high: 51.255,\n    low: 51.23,\n    close: 51.25,\n    volume: 18673,\n  },\n  {\n    date: 1462988100000,\n    open: 51.25,\n    high: 51.25,\n    low: 51.23,\n    close: 51.23,\n    volume: 13845,\n  },\n  {\n    date: 1462988160000,\n    open: 51.23,\n    high: 51.24,\n    low: 51.2,\n    close: 51.24,\n    volume: 36047,\n  },\n  {\n    date: 1462988220000,\n    open: 51.24,\n    high: 51.26,\n    low: 51.24,\n    close: 51.26,\n    volume: 15485,\n  },\n  {\n    date: 1462988280000,\n    open: 51.27,\n    high: 51.28,\n    low: 51.27,\n    close: 51.28,\n    volume: 23272,\n  },\n  {\n    date: 1462988340000,\n    open: 51.28,\n    high: 51.28,\n    low: 51.24,\n    close: 51.25,\n    volume: 42653,\n  },\n  {\n    date: 1462988400000,\n    open: 51.2501,\n    high: 51.27,\n    low: 51.25,\n    close: 51.27,\n    volume: 23400,\n  },\n  {\n    date: 1462988460000,\n    open: 51.27,\n    high: 51.27,\n    low: 51.22,\n    close: 51.2238,\n    volume: 31844,\n  },\n  {\n    date: 1462988520000,\n    open: 51.225,\n    high: 51.25,\n    low: 51.2101,\n    close: 51.23,\n    volume: 26920,\n  },\n  {\n    date: 1462988580000,\n    open: 51.23,\n    high: 51.23,\n    low: 51.21,\n    close: 51.221,\n    volume: 21943,\n  },\n  {\n    date: 1462988640000,\n    open: 51.22,\n    high: 51.23,\n    low: 51.2,\n    close: 51.21,\n    volume: 19760,\n  },\n  {\n    date: 1462988700000,\n    open: 51.21,\n    high: 51.21,\n    low: 51.1799,\n    close: 51.1899,\n    volume: 33232,\n  },\n  {\n    date: 1462988760000,\n    open: 51.1847,\n    high: 51.1935,\n    low: 51.18,\n    close: 51.19,\n    volume: 45230,\n  },\n  {\n    date: 1462988820000,\n    open: 51.19,\n    high: 51.2,\n    low: 51.18,\n    close: 51.19,\n    volume: 62051,\n  },\n  {\n    date: 1462988880000,\n    open: 51.19,\n    high: 51.198,\n    low: 51.15,\n    close: 51.1501,\n    volume: 28431,\n  },\n  {\n    date: 1462988940000,\n    open: 51.15,\n    high: 51.17,\n    low: 51.15,\n    close: 51.1601,\n    volume: 12852,\n  },\n  {\n    date: 1462989000000,\n    open: 51.165,\n    high: 51.2,\n    low: 51.16,\n    close: 51.1999,\n    volume: 19492,\n  },\n  {\n    date: 1462989060000,\n    open: 51.2,\n    high: 51.2,\n    low: 51.1601,\n    close: 51.18,\n    volume: 30886,\n  },\n  {\n    date: 1462989120000,\n    open: 51.175,\n    high: 51.1899,\n    low: 51.17,\n    close: 51.17,\n    volume: 10745,\n  },\n  {\n    date: 1462989180000,\n    open: 51.1793,\n    high: 51.1793,\n    low: 51.155,\n    close: 51.165,\n    volume: 17322,\n  },\n  {\n    date: 1462989240000,\n    open: 51.163,\n    high: 51.175,\n    low: 51.145,\n    close: 51.145,\n    volume: 31004,\n  },\n  {\n    date: 1462989300000,\n    open: 51.15,\n    high: 51.155,\n    low: 51.125,\n    close: 51.14,\n    volume: 26048,\n  },\n  {\n    date: 1462989360000,\n    open: 51.1385,\n    high: 51.16,\n    low: 51.1385,\n    close: 51.15,\n    volume: 28391,\n  },\n  {\n    date: 1462989420000,\n    open: 51.145,\n    high: 51.15,\n    low: 51.14,\n    close: 51.14,\n    volume: 17541,\n  },\n  {\n    date: 1462989480000,\n    open: 51.14,\n    high: 51.14,\n    low: 51.1136,\n    close: 51.135,\n    volume: 31995,\n  },\n  {\n    date: 1462989540000,\n    open: 51.13,\n    high: 51.13,\n    low: 51.11,\n    close: 51.12,\n    volume: 15498,\n  },\n  {\n    date: 1462989600000,\n    open: 51.12,\n    high: 51.12,\n    low: 51.07,\n    close: 51.08,\n    volume: 48825,\n  },\n  {\n    date: 1462989660000,\n    open: 51.08,\n    high: 51.08,\n    low: 51.06,\n    close: 51.07,\n    volume: 35146,\n  },\n  {\n    date: 1462989720000,\n    open: 51.07,\n    high: 51.0798,\n    low: 51.05,\n    close: 51.064,\n    volume: 43814,\n  },\n  {\n    date: 1462989780000,\n    open: 51.0635,\n    high: 51.0635,\n    low: 51.02,\n    close: 51.02,\n    volume: 28793,\n  },\n  {\n    date: 1462989840000,\n    open: 51.025,\n    high: 51.05,\n    low: 51.02,\n    close: 51.05,\n    volume: 29817,\n  },\n  {\n    date: 1462989900000,\n    open: 51.05,\n    high: 51.1,\n    low: 51.045,\n    close: 51.08,\n    volume: 28728,\n  },\n  {\n    date: 1462989960000,\n    open: 51.08,\n    high: 51.08,\n    low: 51.05,\n    close: 51.05,\n    volume: 50435,\n  },\n  {\n    date: 1462990020000,\n    open: 51.0599,\n    high: 51.06,\n    low: 51.03,\n    close: 51.03,\n    volume: 34308,\n  },\n  {\n    date: 1462990080000,\n    open: 51.035,\n    high: 51.06,\n    low: 51.015,\n    close: 51.05,\n    volume: 49308,\n  },\n  {\n    date: 1462990140000,\n    open: 51.05,\n    high: 51.065,\n    low: 51.05,\n    close: 51.055,\n    volume: 14976,\n  },\n  {\n    date: 1462990200000,\n    open: 51.05,\n    high: 51.06,\n    low: 51.02,\n    close: 51.025,\n    volume: 39125,\n  },\n  {\n    date: 1462990260000,\n    open: 51.035,\n    high: 51.04,\n    low: 51.02,\n    close: 51.02,\n    volume: 14875,\n  },\n  {\n    date: 1462990320000,\n    open: 51.025,\n    high: 51.065,\n    low: 51.025,\n    close: 51.06,\n    volume: 32399,\n  },\n  {\n    date: 1462990380000,\n    open: 51.065,\n    high: 51.1,\n    low: 51.065,\n    close: 51.1,\n    volume: 13285,\n  },\n  {\n    date: 1462990440000,\n    open: 51.1,\n    high: 51.1,\n    low: 51.085,\n    close: 51.09,\n    volume: 22783,\n  },\n  {\n    date: 1462990500000,\n    open: 51.0956,\n    high: 51.1,\n    low: 51.08,\n    close: 51.09,\n    volume: 36233,\n  },\n  {\n    date: 1462990560000,\n    open: 51.09,\n    high: 51.0901,\n    low: 51.0501,\n    close: 51.0501,\n    volume: 38472,\n  },\n  {\n    date: 1462990620000,\n    open: 51.05,\n    high: 51.05,\n    low: 51.03,\n    close: 51.04,\n    volume: 24330,\n  },\n  {\n    date: 1462990680000,\n    open: 51.05,\n    high: 51.07,\n    low: 51.03,\n    close: 51.0613,\n    volume: 30203,\n  },\n  {\n    date: 1462990740000,\n    open: 51.065,\n    high: 51.09,\n    low: 51.06,\n    close: 51.075,\n    volume: 101522,\n  },\n  {\n    date: 1462990800000,\n    open: 51.0701,\n    high: 51.0901,\n    low: 51.055,\n    close: 51.09,\n    volume: 26648,\n  },\n  {\n    date: 1462990860000,\n    open: 51.09,\n    high: 51.115,\n    low: 51.05,\n    close: 51.05,\n    volume: 37532,\n  },\n  {\n    date: 1462990920000,\n    open: 51.05,\n    high: 51.09,\n    low: 51.05,\n    close: 51.08,\n    volume: 24114,\n  },\n  {\n    date: 1462990980000,\n    open: 51.085,\n    high: 51.1,\n    low: 51.075,\n    close: 51.1,\n    volume: 23853,\n  },\n  {\n    date: 1462991040000,\n    open: 51.1,\n    high: 51.13,\n    low: 51.1,\n    close: 51.1288,\n    volume: 14736,\n  },\n  {\n    date: 1462991100000,\n    open: 51.12,\n    high: 51.14,\n    low: 51.12,\n    close: 51.139,\n    volume: 20308,\n  },\n  {\n    date: 1462991160000,\n    open: 51.135,\n    high: 51.135,\n    low: 51.12,\n    close: 51.13,\n    volume: 12098,\n  },\n  {\n    date: 1462991220000,\n    open: 51.129,\n    high: 51.13,\n    low: 51.12,\n    close: 51.13,\n    volume: 18355,\n  },\n  {\n    date: 1462991280000,\n    open: 51.13,\n    high: 51.14,\n    low: 51.11,\n    close: 51.13,\n    volume: 31717,\n  },\n  {\n    date: 1462991340000,\n    open: 51.13,\n    high: 51.14,\n    low: 51.11,\n    close: 51.12,\n    volume: 35745,\n  },\n  {\n    date: 1462991400000,\n    open: 51.12,\n    high: 51.14,\n    low: 51.11,\n    close: 51.13,\n    volume: 18202,\n  },\n  {\n    date: 1462991460000,\n    open: 51.13,\n    high: 51.14,\n    low: 51.12,\n    close: 51.13,\n    volume: 40009,\n  },\n  {\n    date: 1462991520000,\n    open: 51.13,\n    high: 51.14,\n    low: 51.11,\n    close: 51.14,\n    volume: 18005,\n  },\n  {\n    date: 1462991580000,\n    open: 51.13,\n    high: 51.16,\n    low: 51.13,\n    close: 51.16,\n    volume: 38548,\n  },\n  {\n    date: 1462991640000,\n    open: 51.15,\n    high: 51.15,\n    low: 51.11,\n    close: 51.115,\n    volume: 29839,\n  },\n  {\n    date: 1462991700000,\n    open: 51.11,\n    high: 51.1199,\n    low: 51.0901,\n    close: 51.0972,\n    volume: 27104,\n  },\n  {\n    date: 1462991760000,\n    open: 51.1,\n    high: 51.1,\n    low: 51.07,\n    close: 51.09,\n    volume: 33059,\n  },\n  {\n    date: 1462991820000,\n    open: 51.09,\n    high: 51.11,\n    low: 51.09,\n    close: 51.1099,\n    volume: 19312,\n  },\n  {\n    date: 1462991880000,\n    open: 51.1,\n    high: 51.11,\n    low: 51.09,\n    close: 51.105,\n    volume: 32468,\n  },\n  {\n    date: 1462991940000,\n    open: 51.1,\n    high: 51.13,\n    low: 51.1,\n    close: 51.13,\n    volume: 17356,\n  },\n  {\n    date: 1462992000000,\n    open: 51.13,\n    high: 51.155,\n    low: 51.1201,\n    close: 51.15,\n    volume: 14198,\n  },\n  {\n    date: 1462992060000,\n    open: 51.14,\n    high: 51.145,\n    low: 51.12,\n    close: 51.13,\n    volume: 58075,\n  },\n  {\n    date: 1462992120000,\n    open: 51.13,\n    high: 51.13,\n    low: 51.0989,\n    close: 51.105,\n    volume: 27924,\n  },\n  {\n    date: 1462992180000,\n    open: 51.11,\n    high: 51.1165,\n    low: 51.1,\n    close: 51.1,\n    volume: 30898,\n  },\n  {\n    date: 1462992240000,\n    open: 51.11,\n    high: 51.11,\n    low: 51.08,\n    close: 51.08,\n    volume: 39719,\n  },\n  {\n    date: 1462992300000,\n    open: 51.085,\n    high: 51.09,\n    low: 51.035,\n    close: 51.04,\n    volume: 47936,\n  },\n  {\n    date: 1462992360000,\n    open: 51.03,\n    high: 51.04,\n    low: 51,\n    close: 51.01,\n    volume: 72394,\n  },\n  {\n    date: 1462992420000,\n    open: 51.01,\n    high: 51.05,\n    low: 51,\n    close: 51.0344,\n    volume: 89099,\n  },\n  {\n    date: 1462992480000,\n    open: 51.035,\n    high: 51.0401,\n    low: 51,\n    close: 51.0401,\n    volume: 44381,\n  },\n  {\n    date: 1462992540000,\n    open: 51.04,\n    high: 51.05,\n    low: 51.025,\n    close: 51.025,\n    volume: 23240,\n  },\n  {\n    date: 1462992600000,\n    open: 51.02,\n    high: 51.07,\n    low: 51.02,\n    close: 51.04,\n    volume: 39944,\n  },\n  {\n    date: 1462992660000,\n    open: 51.048,\n    high: 51.08,\n    low: 51.0468,\n    close: 51.08,\n    volume: 6404,\n  },\n  {\n    date: 1462992720000,\n    open: 51.08,\n    high: 51.085,\n    low: 51.05,\n    close: 51.065,\n    volume: 40955,\n  },\n  {\n    date: 1462992780000,\n    open: 51.07,\n    high: 51.1,\n    low: 51.065,\n    close: 51.1,\n    volume: 21877,\n  },\n  {\n    date: 1462992840000,\n    open: 51.095,\n    high: 51.1,\n    low: 51.055,\n    close: 51.06,\n    volume: 36251,\n  },\n  {\n    date: 1462992900000,\n    open: 51.06,\n    high: 51.075,\n    low: 51.06,\n    close: 51.075,\n    volume: 22054,\n  },\n  {\n    date: 1462992960000,\n    open: 51.08,\n    high: 51.08,\n    low: 51.05,\n    close: 51.0559,\n    volume: 33091,\n  },\n  {\n    date: 1462993020000,\n    open: 51.05,\n    high: 51.08,\n    low: 51.05,\n    close: 51.08,\n    volume: 16096,\n  },\n  {\n    date: 1462993080000,\n    open: 51.0728,\n    high: 51.1,\n    low: 51.07,\n    close: 51.095,\n    volume: 18982,\n  },\n  {\n    date: 1462993140000,\n    open: 51.09,\n    high: 51.09,\n    low: 51.05,\n    close: 51.05,\n    volume: 45821,\n  },\n  {\n    date: 1462993200000,\n    open: 51.055,\n    high: 51.055,\n    low: 51.01,\n    close: 51.04,\n    volume: 44002,\n  },\n  {\n    date: 1462993260000,\n    open: 51.035,\n    high: 51.05,\n    low: 51.03,\n    close: 51.0468,\n    volume: 32607,\n  },\n  {\n    date: 1462993320000,\n    open: 51.04,\n    high: 51.05,\n    low: 51.03,\n    close: 51.03,\n    volume: 12035,\n  },\n  {\n    date: 1462993380000,\n    open: 51.03,\n    high: 51.04,\n    low: 51,\n    close: 51.015,\n    volume: 61094,\n  },\n  {\n    date: 1462993440000,\n    open: 51.0101,\n    high: 51.04,\n    low: 51,\n    close: 51.04,\n    volume: 21504,\n  },\n  {\n    date: 1462993500000,\n    open: 51.04,\n    high: 51.04,\n    low: 51.02,\n    close: 51.0269,\n    volume: 21183,\n  },\n  {\n    date: 1462993560000,\n    open: 51.025,\n    high: 51.07,\n    low: 51.0201,\n    close: 51.0652,\n    volume: 17983,\n  },\n  {\n    date: 1462993620000,\n    open: 51.065,\n    high: 51.09,\n    low: 51.06,\n    close: 51.09,\n    volume: 38136,\n  },\n  {\n    date: 1462993680000,\n    open: 51.0864,\n    high: 51.095,\n    low: 51.065,\n    close: 51.085,\n    volume: 47556,\n  },\n  {\n    date: 1462993740000,\n    open: 51.085,\n    high: 51.1,\n    low: 51.06,\n    close: 51.079,\n    volume: 27412,\n  },\n  {\n    date: 1462993800000,\n    open: 51.07,\n    high: 51.09,\n    low: 51.07,\n    close: 51.0801,\n    volume: 39221,\n  },\n  {\n    date: 1462993860000,\n    open: 51.08,\n    high: 51.085,\n    low: 51.07,\n    close: 51.08,\n    volume: 24630,\n  },\n  {\n    date: 1462993920000,\n    open: 51.09,\n    high: 51.12,\n    low: 51.08,\n    close: 51.0999,\n    volume: 82176,\n  },\n  {\n    date: 1462993980000,\n    open: 51.095,\n    high: 51.13,\n    low: 51.09,\n    close: 51.125,\n    volume: 40165,\n  },\n  {\n    date: 1462994040000,\n    open: 51.12,\n    high: 51.12,\n    low: 51.08,\n    close: 51.09,\n    volume: 40203,\n  },\n  {\n    date: 1462994100000,\n    open: 51.09,\n    high: 51.09,\n    low: 51.065,\n    close: 51.08,\n    volume: 29588,\n  },\n  {\n    date: 1462994160000,\n    open: 51.085,\n    high: 51.09,\n    low: 51.07,\n    close: 51.0801,\n    volume: 15777,\n  },\n  {\n    date: 1462994220000,\n    open: 51.09,\n    high: 51.1,\n    low: 51.0824,\n    close: 51.09,\n    volume: 19421,\n  },\n  {\n    date: 1462994280000,\n    open: 51.095,\n    high: 51.0963,\n    low: 51.06,\n    close: 51.079,\n    volume: 47311,\n  },\n  {\n    date: 1462994340000,\n    open: 51.07,\n    high: 51.08,\n    low: 51.05,\n    close: 51.06,\n    volume: 32713,\n  },\n  {\n    date: 1462994400000,\n    open: 51.06,\n    high: 51.06,\n    low: 51.02,\n    close: 51.02,\n    volume: 44195,\n  },\n  {\n    date: 1462994460000,\n    open: 51.02,\n    high: 51.02,\n    low: 51,\n    close: 51.005,\n    volume: 54514,\n  },\n  {\n    date: 1462994520000,\n    open: 51,\n    high: 51.02,\n    low: 51,\n    close: 51.015,\n    volume: 37419,\n  },\n  {\n    date: 1462994580000,\n    open: 51.019,\n    high: 51.04,\n    low: 51.01,\n    close: 51.035,\n    volume: 33428,\n  },\n  {\n    date: 1462994640000,\n    open: 51.04,\n    high: 51.04,\n    low: 51.02,\n    close: 51.03,\n    volume: 23917,\n  },\n  {\n    date: 1462994700000,\n    open: 51.03,\n    high: 51.04,\n    low: 51.02,\n    close: 51.025,\n    volume: 38394,\n  },\n  {\n    date: 1462994760000,\n    open: 51.025,\n    high: 51.04,\n    low: 51.02,\n    close: 51.04,\n    volume: 14882,\n  },\n  {\n    date: 1462994820000,\n    open: 51.035,\n    high: 51.075,\n    low: 51.035,\n    close: 51.065,\n    volume: 24579,\n  },\n  {\n    date: 1462994880000,\n    open: 51.07,\n    high: 51.07,\n    low: 51.05,\n    close: 51.06,\n    volume: 44977,\n  },\n  {\n    date: 1462994940000,\n    open: 51.055,\n    high: 51.09,\n    low: 51.04,\n    close: 51.0831,\n    volume: 77951,\n  },\n  {\n    date: 1462995000000,\n    open: 51.087,\n    high: 51.09,\n    low: 51.04,\n    close: 51.051,\n    volume: 54677,\n  },\n  {\n    date: 1462995060000,\n    open: 51.06,\n    high: 51.08,\n    low: 51.04,\n    close: 51.075,\n    volume: 49941,\n  },\n  {\n    date: 1462995120000,\n    open: 51.075,\n    high: 51.11,\n    low: 51.075,\n    close: 51.1,\n    volume: 54917,\n  },\n  {\n    date: 1462995180000,\n    open: 51.09,\n    high: 51.1,\n    low: 51.0701,\n    close: 51.1,\n    volume: 23253,\n  },\n  {\n    date: 1462995240000,\n    open: 51.1,\n    high: 51.125,\n    low: 51.09,\n    close: 51.1101,\n    volume: 74655,\n  },\n  {\n    date: 1462995300000,\n    open: 51.11,\n    high: 51.125,\n    low: 51.07,\n    close: 51.12,\n    volume: 53045,\n  },\n  {\n    date: 1462995360000,\n    open: 51.12,\n    high: 51.13,\n    low: 51.08,\n    close: 51.1,\n    volume: 44525,\n  },\n  {\n    date: 1462995420000,\n    open: 51.11,\n    high: 51.13,\n    low: 51.1059,\n    close: 51.115,\n    volume: 61674,\n  },\n  {\n    date: 1462995480000,\n    open: 51.11,\n    high: 51.12,\n    low: 51.1,\n    close: 51.12,\n    volume: 32310,\n  },\n  {\n    date: 1462995540000,\n    open: 51.115,\n    high: 51.1299,\n    low: 51.08,\n    close: 51.082,\n    volume: 80186,\n  },\n  {\n    date: 1462995600000,\n    open: 51.08,\n    high: 51.0968,\n    low: 51.07,\n    close: 51.0836,\n    volume: 35773,\n  },\n  {\n    date: 1462995660000,\n    open: 51.09,\n    high: 51.1,\n    low: 51.05,\n    close: 51.05,\n    volume: 60556,\n  },\n  {\n    date: 1462995720000,\n    open: 51.05,\n    high: 51.09,\n    low: 51.05,\n    close: 51.0859,\n    volume: 127272,\n  },\n  {\n    date: 1462995780000,\n    open: 51.0899,\n    high: 51.09,\n    low: 51.05,\n    close: 51.065,\n    volume: 61339,\n  },\n  {\n    date: 1462995840000,\n    open: 51.06,\n    high: 51.07,\n    low: 51.06,\n    close: 51.065,\n    volume: 16803,\n  },\n  {\n    date: 1462995900000,\n    open: 51.06,\n    high: 51.08,\n    low: 51.05,\n    close: 51.0699,\n    volume: 76338,\n  },\n  {\n    date: 1462995960000,\n    open: 51.06,\n    high: 51.1,\n    low: 51.055,\n    close: 51.0966,\n    volume: 92175,\n  },\n  {\n    date: 1462996020000,\n    open: 51.09,\n    high: 51.11,\n    low: 51.07,\n    close: 51.08,\n    volume: 121628,\n  },\n  {\n    date: 1462996080000,\n    open: 51.08,\n    high: 51.125,\n    low: 51.07,\n    close: 51.1,\n    volume: 70924,\n  },\n  {\n    date: 1462996140000,\n    open: 51.105,\n    high: 51.12,\n    low: 51.09,\n    close: 51.115,\n    volume: 90710,\n  },\n  {\n    date: 1462996200000,\n    open: 51.11,\n    high: 51.11,\n    low: 51.075,\n    close: 51.08,\n    volume: 106028,\n  },\n  {\n    date: 1462996260000,\n    open: 51.07,\n    high: 51.1,\n    low: 51.07,\n    close: 51.0835,\n    volume: 71504,\n  },\n  {\n    date: 1462996320000,\n    open: 51.0875,\n    high: 51.0875,\n    low: 51.06,\n    close: 51.065,\n    volume: 38845,\n  },\n  {\n    date: 1462996380000,\n    open: 51.061,\n    high: 51.07,\n    low: 51.045,\n    close: 51.055,\n    volume: 91169,\n  },\n  {\n    date: 1462996440000,\n    open: 51.06,\n    high: 51.09,\n    low: 51.05,\n    close: 51.06,\n    volume: 80074,\n  },\n  {\n    date: 1462996500000,\n    open: 51.05,\n    high: 51.075,\n    low: 51.045,\n    close: 51.065,\n    volume: 71004,\n  },\n  {\n    date: 1462996560000,\n    open: 51.065,\n    high: 51.095,\n    low: 51.06,\n    close: 51.07,\n    volume: 139869,\n  },\n  {\n    date: 1462996620000,\n    open: 51.07,\n    high: 51.09,\n    low: 51.05,\n    close: 51.085,\n    volume: 152481,\n  },\n  {\n    date: 1462996680000,\n    open: 51.08,\n    high: 51.1,\n    low: 51.08,\n    close: 51.08,\n    volume: 85893,\n  },\n  {\n    date: 1462996740000,\n    open: 51.085,\n    high: 51.09,\n    low: 51.07,\n    close: 51.085,\n    volume: 120608,\n  },\n  {\n    date: 1462996800000,\n    open: 51.09,\n    high: 51.1,\n    low: 51.05,\n    close: 51.05,\n    volume: 3241880,\n  },\n  {\n    date: 1463059800000,\n    open: 51.2,\n    high: 51.25,\n    low: 51.2,\n    close: 51.22,\n    volume: 295172,\n  },\n  {\n    date: 1463059860000,\n    open: 51.22,\n    high: 51.34,\n    low: 51.2111,\n    close: 51.29,\n    volume: 117186,\n  },\n  {\n    date: 1463059920000,\n    open: 51.3,\n    high: 51.37,\n    low: 51.29,\n    close: 51.3399,\n    volume: 73637,\n  },\n  {\n    date: 1463059980000,\n    open: 51.33,\n    high: 51.3475,\n    low: 51.29,\n    close: 51.32,\n    volume: 42294,\n  },\n  {\n    date: 1463060040000,\n    open: 51.32,\n    high: 51.32,\n    low: 51.245,\n    close: 51.26,\n    volume: 42686,\n  },\n  {\n    date: 1463060100000,\n    open: 51.26,\n    high: 51.31,\n    low: 51.255,\n    close: 51.2602,\n    volume: 46212,\n  },\n  {\n    date: 1463060160000,\n    open: 51.26,\n    high: 51.31,\n    low: 51.26,\n    close: 51.31,\n    volume: 43928,\n  },\n  {\n    date: 1463060220000,\n    open: 51.3,\n    high: 51.305,\n    low: 51.245,\n    close: 51.28,\n    volume: 122418,\n  },\n  {\n    date: 1463060280000,\n    open: 51.28,\n    high: 51.34,\n    low: 51.245,\n    close: 51.335,\n    volume: 81854,\n  },\n  {\n    date: 1463060340000,\n    open: 51.34,\n    high: 51.345,\n    low: 51.27,\n    close: 51.28,\n    volume: 38010,\n  },\n  {\n    date: 1463060400000,\n    open: 51.27,\n    high: 51.28,\n    low: 51.24,\n    close: 51.26,\n    volume: 93066,\n  },\n  {\n    date: 1463060460000,\n    open: 51.26,\n    high: 51.27,\n    low: 51.245,\n    close: 51.265,\n    volume: 83269,\n  },\n  {\n    date: 1463060520000,\n    open: 51.25,\n    high: 51.28,\n    low: 51.24,\n    close: 51.2575,\n    volume: 69405,\n  },\n  {\n    date: 1463060580000,\n    open: 51.26,\n    high: 51.31,\n    low: 51.245,\n    close: 51.286,\n    volume: 58118,\n  },\n  {\n    date: 1463060640000,\n    open: 51.29,\n    high: 51.39,\n    low: 51.29,\n    close: 51.359,\n    volume: 60871,\n  },\n  {\n    date: 1463060700000,\n    open: 51.355,\n    high: 51.38,\n    low: 51.31,\n    close: 51.37,\n    volume: 43437,\n  },\n  {\n    date: 1463060760000,\n    open: 51.37,\n    high: 51.38,\n    low: 51.3,\n    close: 51.33,\n    volume: 79468,\n  },\n  {\n    date: 1463060820000,\n    open: 51.325,\n    high: 51.35,\n    low: 51.3,\n    close: 51.335,\n    volume: 83639,\n  },\n  {\n    date: 1463060880000,\n    open: 51.335,\n    high: 51.34,\n    low: 51.29,\n    close: 51.31,\n    volume: 93975,\n  },\n  {\n    date: 1463060940000,\n    open: 51.3005,\n    high: 51.33,\n    low: 51.3,\n    close: 51.31,\n    volume: 51365,\n  },\n  {\n    date: 1463061000000,\n    open: 51.32,\n    high: 51.32,\n    low: 51.29,\n    close: 51.3,\n    volume: 83927,\n  },\n  {\n    date: 1463061060000,\n    open: 51.308,\n    high: 51.41,\n    low: 51.305,\n    close: 51.4,\n    volume: 85049,\n  },\n  {\n    date: 1463061120000,\n    open: 51.4,\n    high: 51.48,\n    low: 51.4,\n    close: 51.45,\n    volume: 69097,\n  },\n  {\n    date: 1463061180000,\n    open: 51.45,\n    high: 51.48,\n    low: 51.45,\n    close: 51.47,\n    volume: 31652,\n  },\n  {\n    date: 1463061240000,\n    open: 51.475,\n    high: 51.48,\n    low: 51.39,\n    close: 51.39,\n    volume: 71809,\n  },\n  {\n    date: 1463061300000,\n    open: 51.39,\n    high: 51.39,\n    low: 51.3001,\n    close: 51.3001,\n    volume: 39548,\n  },\n  {\n    date: 1463061360000,\n    open: 51.305,\n    high: 51.336,\n    low: 51.3,\n    close: 51.325,\n    volume: 50403,\n  },\n  {\n    date: 1463061420000,\n    open: 51.33,\n    high: 51.34,\n    low: 51.3,\n    close: 51.315,\n    volume: 77320,\n  },\n  {\n    date: 1463061480000,\n    open: 51.315,\n    high: 51.355,\n    low: 51.31,\n    close: 51.31,\n    volume: 27040,\n  },\n  {\n    date: 1463061540000,\n    open: 51.3137,\n    high: 51.37,\n    low: 51.305,\n    close: 51.35,\n    volume: 41556,\n  },\n  {\n    date: 1463061600000,\n    open: 51.35,\n    high: 51.36,\n    low: 51.32,\n    close: 51.34,\n    volume: 86542,\n  },\n  {\n    date: 1463061660000,\n    open: 51.34,\n    high: 51.35,\n    low: 51.325,\n    close: 51.33,\n    volume: 71238,\n  },\n  {\n    date: 1463061720000,\n    open: 51.345,\n    high: 51.38,\n    low: 51.33,\n    close: 51.37,\n    volume: 64301,\n  },\n  {\n    date: 1463061780000,\n    open: 51.37,\n    high: 51.38,\n    low: 51.345,\n    close: 51.3499,\n    volume: 87500,\n  },\n  {\n    date: 1463061840000,\n    open: 51.345,\n    high: 51.39,\n    low: 51.345,\n    close: 51.3899,\n    volume: 30380,\n  },\n  {\n    date: 1463061900000,\n    open: 51.385,\n    high: 51.39,\n    low: 51.37,\n    close: 51.37,\n    volume: 40993,\n  },\n  {\n    date: 1463061960000,\n    open: 51.37,\n    high: 51.38,\n    low: 51.34,\n    close: 51.38,\n    volume: 66083,\n  },\n  {\n    date: 1463062020000,\n    open: 51.38,\n    high: 51.39,\n    low: 51.37,\n    close: 51.375,\n    volume: 23049,\n  },\n  {\n    date: 1463062080000,\n    open: 51.38,\n    high: 51.387,\n    low: 51.345,\n    close: 51.37,\n    volume: 38820,\n  },\n  {\n    date: 1463062140000,\n    open: 51.37,\n    high: 51.39,\n    low: 51.361,\n    close: 51.39,\n    volume: 28428,\n  },\n  {\n    date: 1463062200000,\n    open: 51.4,\n    high: 51.41,\n    low: 51.35,\n    close: 51.36,\n    volume: 65899,\n  },\n  {\n    date: 1463062260000,\n    open: 51.35,\n    high: 51.37,\n    low: 51.35,\n    close: 51.36,\n    volume: 26211,\n  },\n  {\n    date: 1463062320000,\n    open: 51.365,\n    high: 51.37,\n    low: 51.35,\n    close: 51.36,\n    volume: 30542,\n  },\n  {\n    date: 1463062380000,\n    open: 51.35,\n    high: 51.44,\n    low: 51.35,\n    close: 51.44,\n    volume: 33843,\n  },\n  {\n    date: 1463062440000,\n    open: 51.43,\n    high: 51.46,\n    low: 51.425,\n    close: 51.449,\n    volume: 59412,\n  },\n  {\n    date: 1463062500000,\n    open: 51.445,\n    high: 51.4689,\n    low: 51.43,\n    close: 51.46,\n    volume: 33673,\n  },\n  {\n    date: 1463062560000,\n    open: 51.4566,\n    high: 51.46,\n    low: 51.41,\n    close: 51.41,\n    volume: 30327,\n  },\n  {\n    date: 1463062620000,\n    open: 51.41,\n    high: 51.47,\n    low: 51.41,\n    close: 51.455,\n    volume: 63967,\n  },\n  {\n    date: 1463062680000,\n    open: 51.45,\n    high: 51.46,\n    low: 51.41,\n    close: 51.4201,\n    volume: 29059,\n  },\n  {\n    date: 1463062740000,\n    open: 51.42,\n    high: 51.44,\n    low: 51.39,\n    close: 51.4,\n    volume: 28439,\n  },\n  {\n    date: 1463062800000,\n    open: 51.39,\n    high: 51.4,\n    low: 51.3636,\n    close: 51.38,\n    volume: 39717,\n  },\n  {\n    date: 1463062860000,\n    open: 51.375,\n    high: 51.375,\n    low: 51.33,\n    close: 51.365,\n    volume: 48299,\n  },\n  {\n    date: 1463062920000,\n    open: 51.365,\n    high: 51.42,\n    low: 51.36,\n    close: 51.42,\n    volume: 62449,\n  },\n  {\n    date: 1463062980000,\n    open: 51.42,\n    high: 51.4201,\n    low: 51.385,\n    close: 51.39,\n    volume: 55809,\n  },\n  {\n    date: 1463063040000,\n    open: 51.3903,\n    high: 51.43,\n    low: 51.3903,\n    close: 51.43,\n    volume: 41907,\n  },\n  {\n    date: 1463063100000,\n    open: 51.43,\n    high: 51.44,\n    low: 51.4,\n    close: 51.415,\n    volume: 25595,\n  },\n  {\n    date: 1463063160000,\n    open: 51.41,\n    high: 51.4195,\n    low: 51.38,\n    close: 51.409,\n    volume: 36861,\n  },\n  {\n    date: 1463063220000,\n    open: 51.41,\n    high: 51.43,\n    low: 51.41,\n    close: 51.42,\n    volume: 20941,\n  },\n  {\n    date: 1463063280000,\n    open: 51.425,\n    high: 51.43,\n    low: 51.4,\n    close: 51.43,\n    volume: 30188,\n  },\n  {\n    date: 1463063340000,\n    open: 51.425,\n    high: 51.449,\n    low: 51.41,\n    close: 51.415,\n    volume: 63283,\n  },\n  {\n    date: 1463063400000,\n    open: 51.42,\n    high: 51.44,\n    low: 51.405,\n    close: 51.415,\n    volume: 74406,\n  },\n  {\n    date: 1463063460000,\n    open: 51.4,\n    high: 51.42,\n    low: 51.38,\n    close: 51.405,\n    volume: 91810,\n  },\n  {\n    date: 1463063520000,\n    open: 51.405,\n    high: 51.45,\n    low: 51.39,\n    close: 51.39,\n    volume: 140352,\n  },\n  {\n    date: 1463063580000,\n    open: 51.3925,\n    high: 51.42,\n    low: 51.38,\n    close: 51.41,\n    volume: 107207,\n  },\n  {\n    date: 1463063640000,\n    open: 51.4,\n    high: 51.415,\n    low: 51.39,\n    close: 51.414,\n    volume: 79840,\n  },\n  {\n    date: 1463063700000,\n    open: 51.42,\n    high: 51.42,\n    low: 51.4,\n    close: 51.419,\n    volume: 41911,\n  },\n  {\n    date: 1463063760000,\n    open: 51.41,\n    high: 51.42,\n    low: 51.4,\n    close: 51.4,\n    volume: 40643,\n  },\n  {\n    date: 1463063820000,\n    open: 51.405,\n    high: 51.42,\n    low: 51.4,\n    close: 51.42,\n    volume: 23866,\n  },\n  {\n    date: 1463063880000,\n    open: 51.42,\n    high: 51.47,\n    low: 51.415,\n    close: 51.45,\n    volume: 42045,\n  },\n  {\n    date: 1463063940000,\n    open: 51.45,\n    high: 51.49,\n    low: 51.45,\n    close: 51.49,\n    volume: 52200,\n  },\n  {\n    date: 1463064000000,\n    open: 51.5,\n    high: 51.518,\n    low: 51.49,\n    close: 51.495,\n    volume: 84912,\n  },\n  {\n    date: 1463064060000,\n    open: 51.49,\n    high: 51.495,\n    low: 51.44,\n    close: 51.445,\n    volume: 63117,\n  },\n  {\n    date: 1463064120000,\n    open: 51.445,\n    high: 51.46,\n    low: 51.44,\n    close: 51.445,\n    volume: 38645,\n  },\n  {\n    date: 1463064180000,\n    open: 51.44,\n    high: 51.445,\n    low: 51.4,\n    close: 51.41,\n    volume: 59268,\n  },\n  {\n    date: 1463064240000,\n    open: 51.416,\n    high: 51.42,\n    low: 51.37,\n    close: 51.401,\n    volume: 123056,\n  },\n  {\n    date: 1463064300000,\n    open: 51.4,\n    high: 51.42,\n    low: 51.39,\n    close: 51.39,\n    volume: 58594,\n  },\n  {\n    date: 1463064360000,\n    open: 51.395,\n    high: 51.415,\n    low: 51.38,\n    close: 51.409,\n    volume: 48475,\n  },\n  {\n    date: 1463064420000,\n    open: 51.405,\n    high: 51.43,\n    low: 51.4,\n    close: 51.43,\n    volume: 39808,\n  },\n  {\n    date: 1463064480000,\n    open: 51.425,\n    high: 51.425,\n    low: 51.35,\n    close: 51.37,\n    volume: 70851,\n  },\n  {\n    date: 1463064540000,\n    open: 51.373,\n    high: 51.39,\n    low: 51.345,\n    close: 51.365,\n    volume: 58725,\n  },\n  {\n    date: 1463064600000,\n    open: 51.37,\n    high: 51.37,\n    low: 51.34,\n    close: 51.3565,\n    volume: 58788,\n  },\n  {\n    date: 1463064660000,\n    open: 51.3599,\n    high: 51.42,\n    low: 51.345,\n    close: 51.3901,\n    volume: 64170,\n  },\n  {\n    date: 1463064720000,\n    open: 51.39,\n    high: 51.41,\n    low: 51.37,\n    close: 51.41,\n    volume: 27451,\n  },\n  {\n    date: 1463064780000,\n    open: 51.41,\n    high: 51.46,\n    low: 51.41,\n    close: 51.4468,\n    volume: 27297,\n  },\n  {\n    date: 1463064840000,\n    open: 51.45,\n    high: 51.455,\n    low: 51.425,\n    close: 51.43,\n    volume: 35006,\n  },\n  {\n    date: 1463064900000,\n    open: 51.435,\n    high: 51.49,\n    low: 51.43,\n    close: 51.48,\n    volume: 51617,\n  },\n  {\n    date: 1463064960000,\n    open: 51.48,\n    high: 51.49,\n    low: 51.44,\n    close: 51.445,\n    volume: 51931,\n  },\n  {\n    date: 1463065020000,\n    open: 51.45,\n    high: 51.45,\n    low: 51.43,\n    close: 51.44,\n    volume: 20171,\n  },\n  {\n    date: 1463065080000,\n    open: 51.45,\n    high: 51.45,\n    low: 51.41,\n    close: 51.41,\n    volume: 21558,\n  },\n  {\n    date: 1463065140000,\n    open: 51.41,\n    high: 51.43,\n    low: 51.385,\n    close: 51.43,\n    volume: 44532,\n  },\n  {\n    date: 1463065200000,\n    open: 51.43,\n    high: 51.44,\n    low: 51.41,\n    close: 51.41,\n    volume: 68602,\n  },\n  {\n    date: 1463065260000,\n    open: 51.4001,\n    high: 51.4299,\n    low: 51.36,\n    close: 51.36,\n    volume: 51430,\n  },\n  {\n    date: 1463065320000,\n    open: 51.37,\n    high: 51.3768,\n    low: 51.345,\n    close: 51.36,\n    volume: 50302,\n  },\n  {\n    date: 1463065380000,\n    open: 51.35,\n    high: 51.36,\n    low: 51.3,\n    close: 51.31,\n    volume: 109504,\n  },\n  {\n    date: 1463065440000,\n    open: 51.31,\n    high: 51.32,\n    low: 51.25,\n    close: 51.25,\n    volume: 69782,\n  },\n  {\n    date: 1463065500000,\n    open: 51.25,\n    high: 51.305,\n    low: 51.23,\n    close: 51.305,\n    volume: 96224,\n  },\n  {\n    date: 1463065560000,\n    open: 51.3005,\n    high: 51.32,\n    low: 51.29,\n    close: 51.305,\n    volume: 54682,\n  },\n  {\n    date: 1463065620000,\n    open: 51.305,\n    high: 51.3165,\n    low: 51.27,\n    close: 51.28,\n    volume: 31859,\n  },\n  {\n    date: 1463065680000,\n    open: 51.29,\n    high: 51.295,\n    low: 51.27,\n    close: 51.29,\n    volume: 21015,\n  },\n  {\n    date: 1463065740000,\n    open: 51.285,\n    high: 51.3,\n    low: 51.265,\n    close: 51.28,\n    volume: 27272,\n  },\n  {\n    date: 1463065800000,\n    open: 51.285,\n    high: 51.285,\n    low: 51.24,\n    close: 51.27,\n    volume: 48942,\n  },\n  {\n    date: 1463065860000,\n    open: 51.26,\n    high: 51.265,\n    low: 51.24,\n    close: 51.25,\n    volume: 28554,\n  },\n  {\n    date: 1463065920000,\n    open: 51.245,\n    high: 51.255,\n    low: 51.19,\n    close: 51.25,\n    volume: 146878,\n  },\n  {\n    date: 1463065980000,\n    open: 51.245,\n    high: 51.27,\n    low: 51.24,\n    close: 51.26,\n    volume: 22029,\n  },\n  {\n    date: 1463066040000,\n    open: 51.27,\n    high: 51.29,\n    low: 51.26,\n    close: 51.269,\n    volume: 70747,\n  },\n  {\n    date: 1463066100000,\n    open: 51.27,\n    high: 51.275,\n    low: 51.21,\n    close: 51.22,\n    volume: 46276,\n  },\n  {\n    date: 1463066160000,\n    open: 51.22,\n    high: 51.2201,\n    low: 51.15,\n    close: 51.1538,\n    volume: 70167,\n  },\n  {\n    date: 1463066220000,\n    open: 51.15,\n    high: 51.17,\n    low: 51.1,\n    close: 51.105,\n    volume: 96308,\n  },\n  {\n    date: 1463066280000,\n    open: 51.1,\n    high: 51.13,\n    low: 51.08,\n    close: 51.08,\n    volume: 313718,\n  },\n  {\n    date: 1463066340000,\n    open: 51.085,\n    high: 51.11,\n    low: 51.08,\n    close: 51.11,\n    volume: 26890,\n  },\n  {\n    date: 1463066400000,\n    open: 51.11,\n    high: 51.14,\n    low: 51.1,\n    close: 51.13,\n    volume: 38508,\n  },\n  {\n    date: 1463066460000,\n    open: 51.13,\n    high: 51.155,\n    low: 51.11,\n    close: 51.155,\n    volume: 30701,\n  },\n  {\n    date: 1463066520000,\n    open: 51.16,\n    high: 51.165,\n    low: 51.15,\n    close: 51.16,\n    volume: 32020,\n  },\n  {\n    date: 1463066580000,\n    open: 51.15,\n    high: 51.16,\n    low: 51.095,\n    close: 51.0999,\n    volume: 30270,\n  },\n  {\n    date: 1463066640000,\n    open: 51.1,\n    high: 51.105,\n    low: 51.065,\n    close: 51.1,\n    volume: 45377,\n  },\n  {\n    date: 1463066700000,\n    open: 51.105,\n    high: 51.11,\n    low: 51.075,\n    close: 51.08,\n    volume: 24542,\n  },\n  {\n    date: 1463066760000,\n    open: 51.09,\n    high: 51.09,\n    low: 51.05,\n    close: 51.07,\n    volume: 51698,\n  },\n  {\n    date: 1463066820000,\n    open: 51.07,\n    high: 51.1,\n    low: 51.07,\n    close: 51.07,\n    volume: 28979,\n  },\n  {\n    date: 1463066880000,\n    open: 51.07,\n    high: 51.1,\n    low: 51.06,\n    close: 51.09,\n    volume: 59701,\n  },\n  {\n    date: 1463066940000,\n    open: 51.08,\n    high: 51.08,\n    low: 51.06,\n    close: 51.06,\n    volume: 25975,\n  },\n  {\n    date: 1463067000000,\n    open: 51.07,\n    high: 51.07,\n    low: 51.03,\n    close: 51.06,\n    volume: 40446,\n  },\n  {\n    date: 1463067060000,\n    open: 51.0501,\n    high: 51.07,\n    low: 51.0489,\n    close: 51.07,\n    volume: 21763,\n  },\n  {\n    date: 1463067120000,\n    open: 51.08,\n    high: 51.08,\n    low: 51.06,\n    close: 51.07,\n    volume: 39571,\n  },\n  {\n    date: 1463067180000,\n    open: 51.07,\n    high: 51.09,\n    low: 51.06,\n    close: 51.06,\n    volume: 40453,\n  },\n  {\n    date: 1463067240000,\n    open: 51.06,\n    high: 51.07,\n    low: 51.02,\n    close: 51.02,\n    volume: 28871,\n  },\n  {\n    date: 1463067300000,\n    open: 51.025,\n    high: 51.04,\n    low: 51.02,\n    close: 51.036,\n    volume: 32088,\n  },\n  {\n    date: 1463067360000,\n    open: 51.035,\n    high: 51.0499,\n    low: 51.02,\n    close: 51.035,\n    volume: 41142,\n  },\n  {\n    date: 1463067420000,\n    open: 51.0399,\n    high: 51.04,\n    low: 51.025,\n    close: 51.0301,\n    volume: 27122,\n  },\n  {\n    date: 1463067480000,\n    open: 51.035,\n    high: 51.05,\n    low: 51.0238,\n    close: 51.0238,\n    volume: 46035,\n  },\n  {\n    date: 1463067540000,\n    open: 51.02,\n    high: 51.03,\n    low: 51,\n    close: 51.005,\n    volume: 38308,\n  },\n  {\n    date: 1463067600000,\n    open: 51.005,\n    high: 51.015,\n    low: 51,\n    close: 51.005,\n    volume: 15105,\n  },\n  {\n    date: 1463067660000,\n    open: 51.01,\n    high: 51.01,\n    low: 51,\n    close: 51.001,\n    volume: 16505,\n  },\n  {\n    date: 1463067720000,\n    open: 51.0064,\n    high: 51.03,\n    low: 51,\n    close: 51.009,\n    volume: 35300,\n  },\n  {\n    date: 1463067780000,\n    open: 51.005,\n    high: 51.01,\n    low: 51,\n    close: 51,\n    volume: 16646,\n  },\n  {\n    date: 1463067840000,\n    open: 51,\n    high: 51.0305,\n    low: 51,\n    close: 51.028,\n    volume: 65008,\n  },\n  {\n    date: 1463067900000,\n    open: 51.03,\n    high: 51.05,\n    low: 51.015,\n    close: 51.02,\n    volume: 38601,\n  },\n  {\n    date: 1463067960000,\n    open: 51.012,\n    high: 51.03,\n    low: 50.99,\n    close: 51.03,\n    volume: 38000,\n  },\n  {\n    date: 1463068020000,\n    open: 51.03,\n    high: 51.1,\n    low: 51.03,\n    close: 51.06,\n    volume: 24471,\n  },\n  {\n    date: 1463068080000,\n    open: 51.07,\n    high: 51.0796,\n    low: 51.06,\n    close: 51.0699,\n    volume: 21339,\n  },\n  {\n    date: 1463068140000,\n    open: 51.07,\n    high: 51.07,\n    low: 51.03,\n    close: 51.035,\n    volume: 33570,\n  },\n  {\n    date: 1463068200000,\n    open: 51.035,\n    high: 51.08,\n    low: 51.02,\n    close: 51.07,\n    volume: 35255,\n  },\n  {\n    date: 1463068260000,\n    open: 51.065,\n    high: 51.08,\n    low: 51.055,\n    close: 51.07,\n    volume: 14634,\n  },\n  {\n    date: 1463068320000,\n    open: 51.08,\n    high: 51.09,\n    low: 51.05,\n    close: 51.06,\n    volume: 32566,\n  },\n  {\n    date: 1463068380000,\n    open: 51.055,\n    high: 51.06,\n    low: 51.03,\n    close: 51.06,\n    volume: 40120,\n  },\n  {\n    date: 1463068440000,\n    open: 51.055,\n    high: 51.075,\n    low: 51.035,\n    close: 51.075,\n    volume: 23710,\n  },\n  {\n    date: 1463068500000,\n    open: 51.07,\n    high: 51.075,\n    low: 51.02,\n    close: 51.0299,\n    volume: 32234,\n  },\n  {\n    date: 1463068560000,\n    open: 51.02,\n    high: 51.04,\n    low: 51.01,\n    close: 51.04,\n    volume: 25771,\n  },\n  {\n    date: 1463068620000,\n    open: 51.04,\n    high: 51.055,\n    low: 51.02,\n    close: 51.04,\n    volume: 31916,\n  },\n  {\n    date: 1463068680000,\n    open: 51.035,\n    high: 51.06,\n    low: 51.02,\n    close: 51.02,\n    volume: 25021,\n  },\n  {\n    date: 1463068740000,\n    open: 51.02,\n    high: 51.02,\n    low: 50.9901,\n    close: 50.9901,\n    volume: 43172,\n  },\n  {\n    date: 1463068800000,\n    open: 51,\n    high: 51.02,\n    low: 50.98,\n    close: 51.01,\n    volume: 62734,\n  },\n  {\n    date: 1463068860000,\n    open: 51.01,\n    high: 51.015,\n    low: 50.95,\n    close: 50.95,\n    volume: 61633,\n  },\n  {\n    date: 1463068920000,\n    open: 50.95,\n    high: 50.96,\n    low: 50.92,\n    close: 50.935,\n    volume: 23552,\n  },\n  {\n    date: 1463068980000,\n    open: 50.935,\n    high: 51.01,\n    low: 50.935,\n    close: 51.01,\n    volume: 29912,\n  },\n  {\n    date: 1463069040000,\n    open: 51.01,\n    high: 51.06,\n    low: 51.005,\n    close: 51.01,\n    volume: 156778,\n  },\n  {\n    date: 1463069100000,\n    open: 51,\n    high: 51.035,\n    low: 50.99,\n    close: 51.029,\n    volume: 44655,\n  },\n  {\n    date: 1463069160000,\n    open: 51.021,\n    high: 51.06,\n    low: 51.02,\n    close: 51.055,\n    volume: 15865,\n  },\n  {\n    date: 1463069220000,\n    open: 51.06,\n    high: 51.07,\n    low: 51.05,\n    close: 51.06,\n    volume: 18389,\n  },\n  {\n    date: 1463069280000,\n    open: 51.0529,\n    high: 51.07,\n    low: 51.05,\n    close: 51.06,\n    volume: 16952,\n  },\n  {\n    date: 1463069340000,\n    open: 51.066,\n    high: 51.09,\n    low: 51.05,\n    close: 51.0865,\n    volume: 12088,\n  },\n  {\n    date: 1463069400000,\n    open: 51.09,\n    high: 51.11,\n    low: 51.08,\n    close: 51.1,\n    volume: 83487,\n  },\n  {\n    date: 1463069460000,\n    open: 51.1,\n    high: 51.11,\n    low: 51.06,\n    close: 51.06,\n    volume: 58433,\n  },\n  {\n    date: 1463069520000,\n    open: 51.068,\n    high: 51.09,\n    low: 51.06,\n    close: 51.08,\n    volume: 35712,\n  },\n  {\n    date: 1463069580000,\n    open: 51.09,\n    high: 51.11,\n    low: 51.08,\n    close: 51.105,\n    volume: 36838,\n  },\n  {\n    date: 1463069640000,\n    open: 51.1,\n    high: 51.11,\n    low: 51.095,\n    close: 51.1,\n    volume: 44541,\n  },\n  {\n    date: 1463069700000,\n    open: 51.1,\n    high: 51.11,\n    low: 51.1,\n    close: 51.1089,\n    volume: 15590,\n  },\n  {\n    date: 1463069760000,\n    open: 51.105,\n    high: 51.11,\n    low: 51.075,\n    close: 51.08,\n    volume: 28688,\n  },\n  {\n    date: 1463069820000,\n    open: 51.075,\n    high: 51.08,\n    low: 51.03,\n    close: 51.075,\n    volume: 23771,\n  },\n  {\n    date: 1463069880000,\n    open: 51.08,\n    high: 51.11,\n    low: 51.075,\n    close: 51.11,\n    volume: 51237,\n  },\n  {\n    date: 1463069940000,\n    open: 51.11,\n    high: 51.11,\n    low: 51.08,\n    close: 51.08,\n    volume: 36660,\n  },\n  {\n    date: 1463070000000,\n    open: 51.09,\n    high: 51.1,\n    low: 51.06,\n    close: 51.09,\n    volume: 19230,\n  },\n  {\n    date: 1463070060000,\n    open: 51.09,\n    high: 51.1,\n    low: 51.07,\n    close: 51.1,\n    volume: 16089,\n  },\n  {\n    date: 1463070120000,\n    open: 51.11,\n    high: 51.11,\n    low: 51.075,\n    close: 51.08,\n    volume: 13913,\n  },\n  {\n    date: 1463070180000,\n    open: 51.085,\n    high: 51.11,\n    low: 51.085,\n    close: 51.105,\n    volume: 12312,\n  },\n  {\n    date: 1463070240000,\n    open: 51.11,\n    high: 51.115,\n    low: 51.08,\n    close: 51.09,\n    volume: 22535,\n  },\n  {\n    date: 1463070300000,\n    open: 51.09,\n    high: 51.09,\n    low: 51.08,\n    close: 51.08,\n    volume: 3149,\n  },\n  {\n    date: 1463070360000,\n    open: 51.089,\n    high: 51.09,\n    low: 51.065,\n    close: 51.0801,\n    volume: 34357,\n  },\n  {\n    date: 1463070420000,\n    open: 51.085,\n    high: 51.1,\n    low: 51.0657,\n    close: 51.07,\n    volume: 24537,\n  },\n  {\n    date: 1463070480000,\n    open: 51.07,\n    high: 51.09,\n    low: 51.065,\n    close: 51.07,\n    volume: 19391,\n  },\n  {\n    date: 1463070540000,\n    open: 51.07,\n    high: 51.07,\n    low: 51.05,\n    close: 51.07,\n    volume: 13566,\n  },\n  {\n    date: 1463070600000,\n    open: 51.07,\n    high: 51.08,\n    low: 51.065,\n    close: 51.07,\n    volume: 14083,\n  },\n  {\n    date: 1463070660000,\n    open: 51.0603,\n    high: 51.0789,\n    low: 51.06,\n    close: 51.07,\n    volume: 24215,\n  },\n  {\n    date: 1463070720000,\n    open: 51.0665,\n    high: 51.07,\n    low: 51.05,\n    close: 51.0601,\n    volume: 32903,\n  },\n  {\n    date: 1463070780000,\n    open: 51.0664,\n    high: 51.0765,\n    low: 51.06,\n    close: 51.07,\n    volume: 29092,\n  },\n  {\n    date: 1463070840000,\n    open: 51.06,\n    high: 51.08,\n    low: 51.059,\n    close: 51.07,\n    volume: 22940,\n  },\n  {\n    date: 1463070900000,\n    open: 51.07,\n    high: 51.09,\n    low: 51.0632,\n    close: 51.065,\n    volume: 30724,\n  },\n  {\n    date: 1463070960000,\n    open: 51.07,\n    high: 51.07,\n    low: 51.02,\n    close: 51.04,\n    volume: 35365,\n  },\n  {\n    date: 1463071020000,\n    open: 51.03,\n    high: 51.0365,\n    low: 50.95,\n    close: 50.97,\n    volume: 41918,\n  },\n  {\n    date: 1463071080000,\n    open: 50.975,\n    high: 50.99,\n    low: 50.975,\n    close: 50.99,\n    volume: 28614,\n  },\n  {\n    date: 1463071140000,\n    open: 50.99,\n    high: 51.01,\n    low: 50.98,\n    close: 50.98,\n    volume: 20741,\n  },\n  {\n    date: 1463071200000,\n    open: 50.98,\n    high: 51,\n    low: 50.975,\n    close: 50.995,\n    volume: 17520,\n  },\n  {\n    date: 1463071260000,\n    open: 50.995,\n    high: 51,\n    low: 50.97,\n    close: 50.99,\n    volume: 21204,\n  },\n  {\n    date: 1463071320000,\n    open: 50.99,\n    high: 51.02,\n    low: 50.9838,\n    close: 51.01,\n    volume: 10766,\n  },\n  {\n    date: 1463071380000,\n    open: 51.011,\n    high: 51.05,\n    low: 51.011,\n    close: 51.05,\n    volume: 24052,\n  },\n  {\n    date: 1463071440000,\n    open: 51.045,\n    high: 51.08,\n    low: 51.0401,\n    close: 51.06,\n    volume: 13796,\n  },\n  {\n    date: 1463071500000,\n    open: 51.07,\n    high: 51.075,\n    low: 51.06,\n    close: 51.06,\n    volume: 12212,\n  },\n  {\n    date: 1463071560000,\n    open: 51.06,\n    high: 51.1,\n    low: 51.06,\n    close: 51.09,\n    volume: 17564,\n  },\n  {\n    date: 1463071620000,\n    open: 51.08,\n    high: 51.1,\n    low: 51.08,\n    close: 51.1,\n    volume: 3870,\n  },\n  {\n    date: 1463071680000,\n    open: 51.1,\n    high: 51.15,\n    low: 51.1,\n    close: 51.1399,\n    volume: 44472,\n  },\n  {\n    date: 1463071740000,\n    open: 51.13,\n    high: 51.14,\n    low: 51.12,\n    close: 51.1399,\n    volume: 15947,\n  },\n  {\n    date: 1463071800000,\n    open: 51.14,\n    high: 51.15,\n    low: 51.13,\n    close: 51.15,\n    volume: 11892,\n  },\n  {\n    date: 1463071860000,\n    open: 51.14,\n    high: 51.15,\n    low: 51.12,\n    close: 51.14,\n    volume: 21067,\n  },\n  {\n    date: 1463071920000,\n    open: 51.1347,\n    high: 51.15,\n    low: 51.1347,\n    close: 51.1499,\n    volume: 9325,\n  },\n  {\n    date: 1463071980000,\n    open: 51.15,\n    high: 51.17,\n    low: 51.1483,\n    close: 51.15,\n    volume: 44133,\n  },\n  {\n    date: 1463072040000,\n    open: 51.16,\n    high: 51.17,\n    low: 51.15,\n    close: 51.155,\n    volume: 32032,\n  },\n  {\n    date: 1463072100000,\n    open: 51.15,\n    high: 51.16,\n    low: 51.1331,\n    close: 51.14,\n    volume: 15216,\n  },\n  {\n    date: 1463072160000,\n    open: 51.15,\n    high: 51.19,\n    low: 51.15,\n    close: 51.1735,\n    volume: 29640,\n  },\n  {\n    date: 1463072220000,\n    open: 51.1762,\n    high: 51.19,\n    low: 51.16,\n    close: 51.165,\n    volume: 24613,\n  },\n  {\n    date: 1463072280000,\n    open: 51.17,\n    high: 51.18,\n    low: 51.16,\n    close: 51.1607,\n    volume: 16663,\n  },\n  {\n    date: 1463072340000,\n    open: 51.169,\n    high: 51.18,\n    low: 51.16,\n    close: 51.17,\n    volume: 12383,\n  },\n  {\n    date: 1463072400000,\n    open: 51.18,\n    high: 51.21,\n    low: 51.17,\n    close: 51.2068,\n    volume: 22684,\n  },\n  {\n    date: 1463072460000,\n    open: 51.2071,\n    high: 51.22,\n    low: 51.19,\n    close: 51.2,\n    volume: 31924,\n  },\n  {\n    date: 1463072520000,\n    open: 51.21,\n    high: 51.21,\n    low: 51.17,\n    close: 51.17,\n    volume: 19517,\n  },\n  {\n    date: 1463072580000,\n    open: 51.18,\n    high: 51.18,\n    low: 51.16,\n    close: 51.166,\n    volume: 23302,\n  },\n  {\n    date: 1463072640000,\n    open: 51.1699,\n    high: 51.19,\n    low: 51.1699,\n    close: 51.19,\n    volume: 24697,\n  },\n  {\n    date: 1463072700000,\n    open: 51.19,\n    high: 51.19,\n    low: 51.1666,\n    close: 51.175,\n    volume: 14270,\n  },\n  {\n    date: 1463072760000,\n    open: 51.18,\n    high: 51.19,\n    low: 51.16,\n    close: 51.16,\n    volume: 16043,\n  },\n  {\n    date: 1463072820000,\n    open: 51.161,\n    high: 51.185,\n    low: 51.161,\n    close: 51.18,\n    volume: 20613,\n  },\n  {\n    date: 1463072880000,\n    open: 51.185,\n    high: 51.19,\n    low: 51.17,\n    close: 51.18,\n    volume: 8078,\n  },\n  {\n    date: 1463072940000,\n    open: 51.189,\n    high: 51.2,\n    low: 51.18,\n    close: 51.1983,\n    volume: 18271,\n  },\n  {\n    date: 1463073000000,\n    open: 51.2,\n    high: 51.2,\n    low: 51.16,\n    close: 51.16,\n    volume: 17096,\n  },\n  {\n    date: 1463073060000,\n    open: 51.16,\n    high: 51.16,\n    low: 51.1204,\n    close: 51.1204,\n    volume: 36265,\n  },\n  {\n    date: 1463073120000,\n    open: 51.13,\n    high: 51.145,\n    low: 51.12,\n    close: 51.145,\n    volume: 20300,\n  },\n  {\n    date: 1463073180000,\n    open: 51.14,\n    high: 51.14,\n    low: 51.11,\n    close: 51.12,\n    volume: 17628,\n  },\n  {\n    date: 1463073240000,\n    open: 51.12,\n    high: 51.13,\n    low: 51.11,\n    close: 51.1236,\n    volume: 19046,\n  },\n  {\n    date: 1463073300000,\n    open: 51.13,\n    high: 51.15,\n    low: 51.12,\n    close: 51.13,\n    volume: 22894,\n  },\n  {\n    date: 1463073360000,\n    open: 51.1399,\n    high: 51.15,\n    low: 51.13,\n    close: 51.14,\n    volume: 13146,\n  },\n  {\n    date: 1463073420000,\n    open: 51.14,\n    high: 51.15,\n    low: 51.125,\n    close: 51.14,\n    volume: 14327,\n  },\n  {\n    date: 1463073480000,\n    open: 51.14,\n    high: 51.15,\n    low: 51.13,\n    close: 51.1332,\n    volume: 17921,\n  },\n  {\n    date: 1463073540000,\n    open: 51.14,\n    high: 51.17,\n    low: 51.14,\n    close: 51.15,\n    volume: 30490,\n  },\n  {\n    date: 1463073600000,\n    open: 51.155,\n    high: 51.1569,\n    low: 51.13,\n    close: 51.13,\n    volume: 6270,\n  },\n  {\n    date: 1463073660000,\n    open: 51.135,\n    high: 51.15,\n    low: 51.11,\n    close: 51.1299,\n    volume: 23803,\n  },\n  {\n    date: 1463073720000,\n    open: 51.1231,\n    high: 51.145,\n    low: 51.12,\n    close: 51.13,\n    volume: 15084,\n  },\n  {\n    date: 1463073780000,\n    open: 51.13,\n    high: 51.16,\n    low: 51.1201,\n    close: 51.16,\n    volume: 29349,\n  },\n  {\n    date: 1463073840000,\n    open: 51.16,\n    high: 51.215,\n    low: 51.16,\n    close: 51.21,\n    volume: 95922,\n  },\n  {\n    date: 1463073900000,\n    open: 51.21,\n    high: 51.22,\n    low: 51.2,\n    close: 51.215,\n    volume: 19646,\n  },\n  {\n    date: 1463073960000,\n    open: 51.2199,\n    high: 51.22,\n    low: 51.21,\n    close: 51.21,\n    volume: 8615,\n  },\n  {\n    date: 1463074020000,\n    open: 51.2101,\n    high: 51.22,\n    low: 51.19,\n    close: 51.19,\n    volume: 9416,\n  },\n  {\n    date: 1463074080000,\n    open: 51.195,\n    high: 51.2,\n    low: 51.18,\n    close: 51.2,\n    volume: 14362,\n  },\n  {\n    date: 1463074140000,\n    open: 51.2,\n    high: 51.22,\n    low: 51.2,\n    close: 51.2185,\n    volume: 21892,\n  },\n  {\n    date: 1463074200000,\n    open: 51.21,\n    high: 51.21,\n    low: 51.19,\n    close: 51.21,\n    volume: 32849,\n  },\n  {\n    date: 1463074260000,\n    open: 51.21,\n    high: 51.21,\n    low: 51.15,\n    close: 51.17,\n    volume: 42924,\n  },\n  {\n    date: 1463074320000,\n    open: 51.17,\n    high: 51.2,\n    low: 51.168,\n    close: 51.19,\n    volume: 20849,\n  },\n  {\n    date: 1463074380000,\n    open: 51.1916,\n    high: 51.2,\n    low: 51.16,\n    close: 51.185,\n    volume: 34939,\n  },\n  {\n    date: 1463074440000,\n    open: 51.18,\n    high: 51.205,\n    low: 51.18,\n    close: 51.2,\n    volume: 43853,\n  },\n  {\n    date: 1463074500000,\n    open: 51.2,\n    high: 51.22,\n    low: 51.19,\n    close: 51.195,\n    volume: 42210,\n  },\n  {\n    date: 1463074560000,\n    open: 51.195,\n    high: 51.2,\n    low: 51.1438,\n    close: 51.195,\n    volume: 124744,\n  },\n  {\n    date: 1463074620000,\n    open: 51.19,\n    high: 51.2,\n    low: 51.16,\n    close: 51.16,\n    volume: 61460,\n  },\n  {\n    date: 1463074680000,\n    open: 51.16,\n    high: 51.2,\n    low: 51.149,\n    close: 51.19,\n    volume: 51106,\n  },\n  {\n    date: 1463074740000,\n    open: 51.195,\n    high: 51.21,\n    low: 51.18,\n    close: 51.201,\n    volume: 15831,\n  },\n  {\n    date: 1463074800000,\n    open: 51.2,\n    high: 51.22,\n    low: 51.183,\n    close: 51.205,\n    volume: 38321,\n  },\n  {\n    date: 1463074860000,\n    open: 51.206,\n    high: 51.23,\n    low: 51.2,\n    close: 51.22,\n    volume: 23113,\n  },\n  {\n    date: 1463074920000,\n    open: 51.22,\n    high: 51.25,\n    low: 51.21,\n    close: 51.25,\n    volume: 25281,\n  },\n  {\n    date: 1463074980000,\n    open: 51.25,\n    high: 51.29,\n    low: 51.2402,\n    close: 51.29,\n    volume: 79699,\n  },\n  {\n    date: 1463075040000,\n    open: 51.2893,\n    high: 51.29,\n    low: 51.25,\n    close: 51.26,\n    volume: 39541,\n  },\n  {\n    date: 1463075100000,\n    open: 51.26,\n    high: 51.37,\n    low: 51.26,\n    close: 51.34,\n    volume: 164977,\n  },\n  {\n    date: 1463075160000,\n    open: 51.335,\n    high: 51.36,\n    low: 51.33,\n    close: 51.36,\n    volume: 13810,\n  },\n  {\n    date: 1463075220000,\n    open: 51.36,\n    high: 51.37,\n    low: 51.34,\n    close: 51.355,\n    volume: 28895,\n  },\n  {\n    date: 1463075280000,\n    open: 51.355,\n    high: 51.36,\n    low: 51.34,\n    close: 51.36,\n    volume: 20866,\n  },\n  {\n    date: 1463075340000,\n    open: 51.355,\n    high: 51.37,\n    low: 51.35,\n    close: 51.36,\n    volume: 40364,\n  },\n  {\n    date: 1463075400000,\n    open: 51.36,\n    high: 51.39,\n    low: 51.32,\n    close: 51.3366,\n    volume: 47495,\n  },\n  {\n    date: 1463075460000,\n    open: 51.34,\n    high: 51.35,\n    low: 51.32,\n    close: 51.35,\n    volume: 19293,\n  },\n  {\n    date: 1463075520000,\n    open: 51.3425,\n    high: 51.37,\n    low: 51.34,\n    close: 51.37,\n    volume: 23958,\n  },\n  {\n    date: 1463075580000,\n    open: 51.361,\n    high: 51.365,\n    low: 51.34,\n    close: 51.3411,\n    volume: 17280,\n  },\n  {\n    date: 1463075640000,\n    open: 51.35,\n    high: 51.35,\n    low: 51.32,\n    close: 51.35,\n    volume: 20879,\n  },\n  {\n    date: 1463075700000,\n    open: 51.35,\n    high: 51.36,\n    low: 51.35,\n    close: 51.36,\n    volume: 9117,\n  },\n  {\n    date: 1463075760000,\n    open: 51.36,\n    high: 51.38,\n    low: 51.35,\n    close: 51.355,\n    volume: 35144,\n  },\n  {\n    date: 1463075820000,\n    open: 51.35,\n    high: 51.3882,\n    low: 51.35,\n    close: 51.375,\n    volume: 45925,\n  },\n  {\n    date: 1463075880000,\n    open: 51.37,\n    high: 51.375,\n    low: 51.34,\n    close: 51.3599,\n    volume: 23132,\n  },\n  {\n    date: 1463075940000,\n    open: 51.357,\n    high: 51.37,\n    low: 51.35,\n    close: 51.365,\n    volume: 42078,\n  },\n  {\n    date: 1463076000000,\n    open: 51.37,\n    high: 51.44,\n    low: 51.36,\n    close: 51.44,\n    volume: 58586,\n  },\n  {\n    date: 1463076060000,\n    open: 51.44,\n    high: 51.47,\n    low: 51.43,\n    close: 51.44,\n    volume: 56434,\n  },\n  {\n    date: 1463076120000,\n    open: 51.435,\n    high: 51.5,\n    low: 51.435,\n    close: 51.485,\n    volume: 86806,\n  },\n  {\n    date: 1463076180000,\n    open: 51.4862,\n    high: 51.52,\n    low: 51.48,\n    close: 51.5195,\n    volume: 81304,\n  },\n  {\n    date: 1463076240000,\n    open: 51.5189,\n    high: 51.53,\n    low: 51.51,\n    close: 51.52,\n    volume: 43465,\n  },\n  {\n    date: 1463076300000,\n    open: 51.51,\n    high: 51.54,\n    low: 51.51,\n    close: 51.535,\n    volume: 35466,\n  },\n  {\n    date: 1463076360000,\n    open: 51.535,\n    high: 51.565,\n    low: 51.52,\n    close: 51.56,\n    volume: 45007,\n  },\n  {\n    date: 1463076420000,\n    open: 51.5601,\n    high: 51.58,\n    low: 51.53,\n    close: 51.56,\n    volume: 86152,\n  },\n  {\n    date: 1463076480000,\n    open: 51.57,\n    high: 51.57,\n    low: 51.51,\n    close: 51.53,\n    volume: 30425,\n  },\n  {\n    date: 1463076540000,\n    open: 51.53,\n    high: 51.54,\n    low: 51.53,\n    close: 51.54,\n    volume: 11220,\n  },\n  {\n    date: 1463076600000,\n    open: 51.535,\n    high: 51.54,\n    low: 51.5,\n    close: 51.505,\n    volume: 28364,\n  },\n  {\n    date: 1463076660000,\n    open: 51.52,\n    high: 51.555,\n    low: 51.51,\n    close: 51.55,\n    volume: 31650,\n  },\n  {\n    date: 1463076720000,\n    open: 51.545,\n    high: 51.57,\n    low: 51.54,\n    close: 51.55,\n    volume: 28662,\n  },\n  {\n    date: 1463076780000,\n    open: 51.55,\n    high: 51.6,\n    low: 51.55,\n    close: 51.59,\n    volume: 62892,\n  },\n  {\n    date: 1463076840000,\n    open: 51.585,\n    high: 51.65,\n    low: 51.58,\n    close: 51.63,\n    volume: 72097,\n  },\n  {\n    date: 1463076900000,\n    open: 51.63,\n    high: 51.69,\n    low: 51.63,\n    close: 51.655,\n    volume: 57782,\n  },\n  {\n    date: 1463076960000,\n    open: 51.65,\n    high: 51.67,\n    low: 51.65,\n    close: 51.6599,\n    volume: 30906,\n  },\n  {\n    date: 1463077020000,\n    open: 51.65,\n    high: 51.655,\n    low: 51.61,\n    close: 51.62,\n    volume: 20248,\n  },\n  {\n    date: 1463077080000,\n    open: 51.62,\n    high: 51.66,\n    low: 51.62,\n    close: 51.645,\n    volume: 87353,\n  },\n  {\n    date: 1463077140000,\n    open: 51.6499,\n    high: 51.67,\n    low: 51.64,\n    close: 51.665,\n    volume: 40046,\n  },\n  {\n    date: 1463077200000,\n    open: 51.6601,\n    high: 51.675,\n    low: 51.655,\n    close: 51.67,\n    volume: 19689,\n  },\n  {\n    date: 1463077260000,\n    open: 51.67,\n    high: 51.75,\n    low: 51.67,\n    close: 51.71,\n    volume: 204155,\n  },\n  {\n    date: 1463077320000,\n    open: 51.7101,\n    high: 51.719,\n    low: 51.66,\n    close: 51.69,\n    volume: 62764,\n  },\n  {\n    date: 1463077380000,\n    open: 51.69,\n    high: 51.705,\n    low: 51.65,\n    close: 51.66,\n    volume: 47260,\n  },\n  {\n    date: 1463077440000,\n    open: 51.655,\n    high: 51.655,\n    low: 51.61,\n    close: 51.61,\n    volume: 75177,\n  },\n  {\n    date: 1463077500000,\n    open: 51.61,\n    high: 51.625,\n    low: 51.59,\n    close: 51.62,\n    volume: 41098,\n  },\n  {\n    date: 1463077560000,\n    open: 51.62,\n    high: 51.65,\n    low: 51.615,\n    close: 51.64,\n    volume: 50607,\n  },\n  {\n    date: 1463077620000,\n    open: 51.65,\n    high: 51.675,\n    low: 51.64,\n    close: 51.651,\n    volume: 41383,\n  },\n  {\n    date: 1463077680000,\n    open: 51.6501,\n    high: 51.68,\n    low: 51.65,\n    close: 51.67,\n    volume: 48182,\n  },\n  {\n    date: 1463077740000,\n    open: 51.68,\n    high: 51.69,\n    low: 51.665,\n    close: 51.69,\n    volume: 65543,\n  },\n  {\n    date: 1463077800000,\n    open: 51.69,\n    high: 51.69,\n    low: 51.67,\n    close: 51.685,\n    volume: 47054,\n  },\n  {\n    date: 1463077860000,\n    open: 51.675,\n    high: 51.68,\n    low: 51.63,\n    close: 51.63,\n    volume: 70881,\n  },\n  {\n    date: 1463077920000,\n    open: 51.635,\n    high: 51.66,\n    low: 51.63,\n    close: 51.64,\n    volume: 34567,\n  },\n  {\n    date: 1463077980000,\n    open: 51.63,\n    high: 51.635,\n    low: 51.61,\n    close: 51.6201,\n    volume: 24108,\n  },\n  {\n    date: 1463078040000,\n    open: 51.62,\n    high: 51.63,\n    low: 51.6,\n    close: 51.61,\n    volume: 36868,\n  },\n  {\n    date: 1463078100000,\n    open: 51.61,\n    high: 51.64,\n    low: 51.6,\n    close: 51.633,\n    volume: 30557,\n  },\n  {\n    date: 1463078160000,\n    open: 51.64,\n    high: 51.66,\n    low: 51.63,\n    close: 51.65,\n    volume: 19909,\n  },\n  {\n    date: 1463078220000,\n    open: 51.645,\n    high: 51.65,\n    low: 51.62,\n    close: 51.62,\n    volume: 21794,\n  },\n  {\n    date: 1463078280000,\n    open: 51.62,\n    high: 51.65,\n    low: 51.62,\n    close: 51.64,\n    volume: 28334,\n  },\n  {\n    date: 1463078340000,\n    open: 51.64,\n    high: 51.66,\n    low: 51.62,\n    close: 51.62,\n    volume: 79905,\n  },\n  {\n    date: 1463078400000,\n    open: 51.625,\n    high: 51.64,\n    low: 51.6,\n    close: 51.605,\n    volume: 33341,\n  },\n  {\n    date: 1463078460000,\n    open: 51.6,\n    high: 51.61,\n    low: 51.6,\n    close: 51.6,\n    volume: 16938,\n  },\n  {\n    date: 1463078520000,\n    open: 51.6001,\n    high: 51.62,\n    low: 51.6,\n    close: 51.62,\n    volume: 25713,\n  },\n  {\n    date: 1463078580000,\n    open: 51.62,\n    high: 51.62,\n    low: 51.6,\n    close: 51.6,\n    volume: 38875,\n  },\n  {\n    date: 1463078640000,\n    open: 51.6,\n    high: 51.6,\n    low: 51.57,\n    close: 51.6,\n    volume: 29713,\n  },\n  {\n    date: 1463078700000,\n    open: 51.5999,\n    high: 51.61,\n    low: 51.59,\n    close: 51.6,\n    volume: 12039,\n  },\n  {\n    date: 1463078760000,\n    open: 51.6,\n    high: 51.64,\n    low: 51.585,\n    close: 51.64,\n    volume: 65286,\n  },\n  {\n    date: 1463078820000,\n    open: 51.64,\n    high: 51.69,\n    low: 51.64,\n    close: 51.69,\n    volume: 103868,\n  },\n  {\n    date: 1463078880000,\n    open: 51.69,\n    high: 51.75,\n    low: 51.68,\n    close: 51.74,\n    volume: 101669,\n  },\n  {\n    date: 1463078940000,\n    open: 51.745,\n    high: 51.805,\n    low: 51.73,\n    close: 51.8,\n    volume: 161312,\n  },\n  {\n    date: 1463079000000,\n    open: 51.8,\n    high: 51.81,\n    low: 51.78,\n    close: 51.79,\n    volume: 73971,\n  },\n  {\n    date: 1463079060000,\n    open: 51.7905,\n    high: 51.8,\n    low: 51.7701,\n    close: 51.7732,\n    volume: 32884,\n  },\n  {\n    date: 1463079120000,\n    open: 51.77,\n    high: 51.8,\n    low: 51.77,\n    close: 51.8,\n    volume: 53162,\n  },\n  {\n    date: 1463079180000,\n    open: 51.7956,\n    high: 51.8,\n    low: 51.78,\n    close: 51.79,\n    volume: 51491,\n  },\n  {\n    date: 1463079240000,\n    open: 51.7988,\n    high: 51.8,\n    low: 51.77,\n    close: 51.7731,\n    volume: 38769,\n  },\n  {\n    date: 1463079300000,\n    open: 51.775,\n    high: 51.79,\n    low: 51.75,\n    close: 51.75,\n    volume: 49482,\n  },\n  {\n    date: 1463079360000,\n    open: 51.74,\n    high: 51.76,\n    low: 51.73,\n    close: 51.73,\n    volume: 72088,\n  },\n  {\n    date: 1463079420000,\n    open: 51.7385,\n    high: 51.74,\n    low: 51.71,\n    close: 51.72,\n    volume: 74879,\n  },\n  {\n    date: 1463079480000,\n    open: 51.72,\n    high: 51.75,\n    low: 51.72,\n    close: 51.729,\n    volume: 56524,\n  },\n  {\n    date: 1463079540000,\n    open: 51.72,\n    high: 51.725,\n    low: 51.67,\n    close: 51.6985,\n    volume: 70470,\n  },\n  {\n    date: 1463079600000,\n    open: 51.6954,\n    high: 51.73,\n    low: 51.69,\n    close: 51.695,\n    volume: 31242,\n  },\n  {\n    date: 1463079660000,\n    open: 51.69,\n    high: 51.7,\n    low: 51.66,\n    close: 51.66,\n    volume: 43999,\n  },\n  {\n    date: 1463079720000,\n    open: 51.6645,\n    high: 51.7,\n    low: 51.66,\n    close: 51.695,\n    volume: 45219,\n  },\n  {\n    date: 1463079780000,\n    open: 51.69,\n    high: 51.69,\n    low: 51.65,\n    close: 51.6523,\n    volume: 36893,\n  },\n  {\n    date: 1463079840000,\n    open: 51.65,\n    high: 51.68,\n    low: 51.64,\n    close: 51.68,\n    volume: 60713,\n  },\n  {\n    date: 1463079900000,\n    open: 51.67,\n    high: 51.68,\n    low: 51.64,\n    close: 51.655,\n    volume: 44439,\n  },\n  {\n    date: 1463079960000,\n    open: 51.65,\n    high: 51.66,\n    low: 51.635,\n    close: 51.64,\n    volume: 54861,\n  },\n  {\n    date: 1463080020000,\n    open: 51.64,\n    high: 51.665,\n    low: 51.625,\n    close: 51.625,\n    volume: 54219,\n  },\n  {\n    date: 1463080080000,\n    open: 51.625,\n    high: 51.65,\n    low: 51.62,\n    close: 51.63,\n    volume: 54660,\n  },\n  {\n    date: 1463080140000,\n    open: 51.635,\n    high: 51.67,\n    low: 51.62,\n    close: 51.62,\n    volume: 62518,\n  },\n  {\n    date: 1463080200000,\n    open: 51.625,\n    high: 51.65,\n    low: 51.62,\n    close: 51.63,\n    volume: 61080,\n  },\n  {\n    date: 1463080260000,\n    open: 51.63,\n    high: 51.67,\n    low: 51.6235,\n    close: 51.655,\n    volume: 69979,\n  },\n  {\n    date: 1463080320000,\n    open: 51.655,\n    high: 51.665,\n    low: 51.64,\n    close: 51.65,\n    volume: 43366,\n  },\n  {\n    date: 1463080380000,\n    open: 51.65,\n    high: 51.67,\n    low: 51.64,\n    close: 51.665,\n    volume: 75827,\n  },\n  {\n    date: 1463080440000,\n    open: 51.66,\n    high: 51.68,\n    low: 51.66,\n    close: 51.68,\n    volume: 36924,\n  },\n  {\n    date: 1463080500000,\n    open: 51.68,\n    high: 51.695,\n    low: 51.6628,\n    close: 51.67,\n    volume: 53495,\n  },\n  {\n    date: 1463080560000,\n    open: 51.68,\n    high: 51.685,\n    low: 51.6628,\n    close: 51.68,\n    volume: 42412,\n  },\n  {\n    date: 1463080620000,\n    open: 51.68,\n    high: 51.69,\n    low: 51.6601,\n    close: 51.6601,\n    volume: 36471,\n  },\n  {\n    date: 1463080680000,\n    open: 51.6656,\n    high: 51.68,\n    low: 51.65,\n    close: 51.6799,\n    volume: 46724,\n  },\n  {\n    date: 1463080740000,\n    open: 51.67,\n    high: 51.675,\n    low: 51.63,\n    close: 51.6585,\n    volume: 44332,\n  },\n  {\n    date: 1463080800000,\n    open: 51.6538,\n    high: 51.68,\n    low: 51.62,\n    close: 51.64,\n    volume: 40762,\n  },\n  {\n    date: 1463080860000,\n    open: 51.635,\n    high: 51.635,\n    low: 51.61,\n    close: 51.615,\n    volume: 41004,\n  },\n  {\n    date: 1463080920000,\n    open: 51.625,\n    high: 51.63,\n    low: 51.595,\n    close: 51.6,\n    volume: 58650,\n  },\n  {\n    date: 1463080980000,\n    open: 51.595,\n    high: 51.6183,\n    low: 51.59,\n    close: 51.59,\n    volume: 54229,\n  },\n  {\n    date: 1463081040000,\n    open: 51.595,\n    high: 51.62,\n    low: 51.59,\n    close: 51.595,\n    volume: 54413,\n  },\n  {\n    date: 1463081100000,\n    open: 51.595,\n    high: 51.6,\n    low: 51.57,\n    close: 51.575,\n    volume: 31251,\n  },\n  {\n    date: 1463081160000,\n    open: 51.57,\n    high: 51.59,\n    low: 51.57,\n    close: 51.58,\n    volume: 35317,\n  },\n  {\n    date: 1463081220000,\n    open: 51.585,\n    high: 51.59,\n    low: 51.54,\n    close: 51.562,\n    volume: 103684,\n  },\n  {\n    date: 1463081280000,\n    open: 51.5662,\n    high: 51.58,\n    low: 51.56,\n    close: 51.56,\n    volume: 44932,\n  },\n  {\n    date: 1463081340000,\n    open: 51.56,\n    high: 51.63,\n    low: 51.56,\n    close: 51.62,\n    volume: 94396,\n  },\n  {\n    date: 1463081400000,\n    open: 51.625,\n    high: 51.655,\n    low: 51.62,\n    close: 51.655,\n    volume: 81461,\n  },\n  {\n    date: 1463081460000,\n    open: 51.65,\n    high: 51.67,\n    low: 51.63,\n    close: 51.645,\n    volume: 99455,\n  },\n  {\n    date: 1463081520000,\n    open: 51.64,\n    high: 51.66,\n    low: 51.61,\n    close: 51.625,\n    volume: 57301,\n  },\n  {\n    date: 1463081580000,\n    open: 51.62,\n    high: 51.63,\n    low: 51.57,\n    close: 51.58,\n    volume: 57835,\n  },\n  {\n    date: 1463081640000,\n    open: 51.585,\n    high: 51.61,\n    low: 51.56,\n    close: 51.5939,\n    volume: 62110,\n  },\n  {\n    date: 1463081700000,\n    open: 51.599,\n    high: 51.62,\n    low: 51.56,\n    close: 51.58,\n    volume: 58379,\n  },\n  {\n    date: 1463081760000,\n    open: 51.5799,\n    high: 51.59,\n    low: 51.5401,\n    close: 51.575,\n    volume: 57100,\n  },\n  {\n    date: 1463081820000,\n    open: 51.575,\n    high: 51.595,\n    low: 51.56,\n    close: 51.595,\n    volume: 48350,\n  },\n  {\n    date: 1463081880000,\n    open: 51.595,\n    high: 51.63,\n    low: 51.59,\n    close: 51.61,\n    volume: 48797,\n  },\n  {\n    date: 1463081940000,\n    open: 51.6161,\n    high: 51.63,\n    low: 51.6,\n    close: 51.601,\n    volume: 47082,\n  },\n  {\n    date: 1463082000000,\n    open: 51.6,\n    high: 51.63,\n    low: 51.595,\n    close: 51.61,\n    volume: 64393,\n  },\n  {\n    date: 1463082060000,\n    open: 51.605,\n    high: 51.66,\n    low: 51.605,\n    close: 51.635,\n    volume: 86960,\n  },\n  {\n    date: 1463082120000,\n    open: 51.64,\n    high: 51.68,\n    low: 51.63,\n    close: 51.68,\n    volume: 97364,\n  },\n  {\n    date: 1463082180000,\n    open: 51.68,\n    high: 51.685,\n    low: 51.65,\n    close: 51.66,\n    volume: 90786,\n  },\n  {\n    date: 1463082240000,\n    open: 51.66,\n    high: 51.68,\n    low: 51.655,\n    close: 51.665,\n    volume: 60231,\n  },\n  {\n    date: 1463082300000,\n    open: 51.6656,\n    high: 51.69,\n    low: 51.66,\n    close: 51.67,\n    volume: 79752,\n  },\n  {\n    date: 1463082360000,\n    open: 51.665,\n    high: 51.69,\n    low: 51.655,\n    close: 51.67,\n    volume: 130331,\n  },\n  {\n    date: 1463082420000,\n    open: 51.665,\n    high: 51.68,\n    low: 51.63,\n    close: 51.66,\n    volume: 119327,\n  },\n  {\n    date: 1463082480000,\n    open: 51.655,\n    high: 51.68,\n    low: 51.63,\n    close: 51.639,\n    volume: 112467,\n  },\n  {\n    date: 1463082540000,\n    open: 51.635,\n    high: 51.65,\n    low: 51.62,\n    close: 51.625,\n    volume: 93474,\n  },\n  {\n    date: 1463082600000,\n    open: 51.62,\n    high: 51.625,\n    low: 51.55,\n    close: 51.565,\n    volume: 260352,\n  },\n  {\n    date: 1463082660000,\n    open: 51.565,\n    high: 51.57,\n    low: 51.5,\n    close: 51.5,\n    volume: 346841,\n  },\n  {\n    date: 1463082720000,\n    open: 51.505,\n    high: 51.51,\n    low: 51.49,\n    close: 51.5008,\n    volume: 180301,\n  },\n  {\n    date: 1463082780000,\n    open: 51.505,\n    high: 51.51,\n    low: 51.4801,\n    close: 51.495,\n    volume: 85201,\n  },\n  {\n    date: 1463082840000,\n    open: 51.49,\n    high: 51.5,\n    low: 51.49,\n    close: 51.4975,\n    volume: 57895,\n  },\n  {\n    date: 1463082900000,\n    open: 51.49,\n    high: 51.49,\n    low: 51.47,\n    close: 51.48,\n    volume: 184418,\n  },\n  {\n    date: 1463082960000,\n    open: 51.485,\n    high: 51.53,\n    low: 51.48,\n    close: 51.52,\n    volume: 197317,\n  },\n  {\n    date: 1463083020000,\n    open: 51.515,\n    high: 51.53,\n    low: 51.47,\n    close: 51.475,\n    volume: 159858,\n  },\n  {\n    date: 1463083080000,\n    open: 51.47,\n    high: 51.54,\n    low: 51.47,\n    close: 51.53,\n    volume: 310679,\n  },\n  {\n    date: 1463083140000,\n    open: 51.525,\n    high: 51.53,\n    low: 51.49,\n    close: 51.5,\n    volume: 183691,\n  },\n  {\n    date: 1463083200000,\n    open: 51.495,\n    high: 51.52,\n    low: 51.4425,\n    close: 51.51,\n    volume: 2261125,\n  },\n  {\n    date: 1463146200000,\n    open: 51.44,\n    high: 51.48,\n    low: 51.39,\n    close: 51.41,\n    volume: 358417,\n  },\n  {\n    date: 1463146260000,\n    open: 51.44,\n    high: 51.56,\n    low: 51.38,\n    close: 51.48,\n    volume: 173745,\n  },\n  {\n    date: 1463146320000,\n    open: 51.48,\n    high: 51.56,\n    low: 51.48,\n    close: 51.54,\n    volume: 39855,\n  },\n  {\n    date: 1463146380000,\n    open: 51.53,\n    high: 51.5956,\n    low: 51.51,\n    close: 51.59,\n    volume: 39587,\n  },\n  {\n    date: 1463146440000,\n    open: 51.6,\n    high: 51.64,\n    low: 51.53,\n    close: 51.54,\n    volume: 49117,\n  },\n  {\n    date: 1463146500000,\n    open: 51.55,\n    high: 51.6,\n    low: 51.54,\n    close: 51.54,\n    volume: 30453,\n  },\n  {\n    date: 1463146560000,\n    open: 51.55,\n    high: 51.57,\n    low: 51.51,\n    close: 51.51,\n    volume: 47651,\n  },\n  {\n    date: 1463146620000,\n    open: 51.51,\n    high: 51.58,\n    low: 51.49,\n    close: 51.56,\n    volume: 34823,\n  },\n  {\n    date: 1463146680000,\n    open: 51.56,\n    high: 51.6364,\n    low: 51.55,\n    close: 51.6064,\n    volume: 48134,\n  },\n  {\n    date: 1463146740000,\n    open: 51.6,\n    high: 51.68,\n    low: 51.595,\n    close: 51.67,\n    volume: 58634,\n  },\n  {\n    date: 1463146800000,\n    open: 51.67,\n    high: 51.73,\n    low: 51.625,\n    close: 51.69,\n    volume: 84494,\n  },\n  {\n    date: 1463146860000,\n    open: 51.695,\n    high: 51.74,\n    low: 51.66,\n    close: 51.735,\n    volume: 75406,\n  },\n  {\n    date: 1463146920000,\n    open: 51.74,\n    high: 51.79,\n    low: 51.72,\n    close: 51.77,\n    volume: 113677,\n  },\n  {\n    date: 1463146980000,\n    open: 51.76,\n    high: 51.805,\n    low: 51.75,\n    close: 51.8,\n    volume: 86480,\n  },\n  {\n    date: 1463147040000,\n    open: 51.81,\n    high: 51.82,\n    low: 51.74,\n    close: 51.755,\n    volume: 70666,\n  },\n  {\n    date: 1463147100000,\n    open: 51.75,\n    high: 51.77,\n    low: 51.71,\n    close: 51.75,\n    volume: 104348,\n  },\n  {\n    date: 1463147160000,\n    open: 51.75,\n    high: 51.82,\n    low: 51.74,\n    close: 51.79,\n    volume: 48206,\n  },\n  {\n    date: 1463147220000,\n    open: 51.79,\n    high: 51.83,\n    low: 51.775,\n    close: 51.81,\n    volume: 48751,\n  },\n  {\n    date: 1463147280000,\n    open: 51.81,\n    high: 51.82,\n    low: 51.77,\n    close: 51.78,\n    volume: 56460,\n  },\n  {\n    date: 1463147340000,\n    open: 51.78,\n    high: 51.83,\n    low: 51.78,\n    close: 51.7829,\n    volume: 50746,\n  },\n  {\n    date: 1463147400000,\n    open: 51.79,\n    high: 51.82,\n    low: 51.76,\n    close: 51.82,\n    volume: 54003,\n  },\n  {\n    date: 1463147460000,\n    open: 51.8211,\n    high: 51.83,\n    low: 51.78,\n    close: 51.81,\n    volume: 42009,\n  },\n  {\n    date: 1463147520000,\n    open: 51.82,\n    high: 51.825,\n    low: 51.8,\n    close: 51.82,\n    volume: 41302,\n  },\n  {\n    date: 1463147580000,\n    open: 51.8099,\n    high: 51.81,\n    low: 51.68,\n    close: 51.6864,\n    volume: 59434,\n  },\n  {\n    date: 1463147640000,\n    open: 51.6899,\n    high: 51.75,\n    low: 51.66,\n    close: 51.75,\n    volume: 57969,\n  },\n  {\n    date: 1463147700000,\n    open: 51.755,\n    high: 51.8,\n    low: 51.74,\n    close: 51.79,\n    volume: 64674,\n  },\n  {\n    date: 1463147760000,\n    open: 51.78,\n    high: 51.86,\n    low: 51.775,\n    close: 51.85,\n    volume: 76215,\n  },\n  {\n    date: 1463147820000,\n    open: 51.8493,\n    high: 51.8493,\n    low: 51.78,\n    close: 51.8099,\n    volume: 51749,\n  },\n  {\n    date: 1463147880000,\n    open: 51.806,\n    high: 51.84,\n    low: 51.8,\n    close: 51.8101,\n    volume: 47441,\n  },\n  {\n    date: 1463147940000,\n    open: 51.81,\n    high: 51.81,\n    low: 51.75,\n    close: 51.76,\n    volume: 29929,\n  },\n  {\n    date: 1463148000000,\n    open: 51.76,\n    high: 51.78,\n    low: 51.71,\n    close: 51.78,\n    volume: 42412,\n  },\n  {\n    date: 1463148060000,\n    open: 51.78,\n    high: 51.81,\n    low: 51.68,\n    close: 51.73,\n    volume: 60736,\n  },\n  {\n    date: 1463148120000,\n    open: 51.73,\n    high: 51.79,\n    low: 51.73,\n    close: 51.78,\n    volume: 34461,\n  },\n  {\n    date: 1463148180000,\n    open: 51.77,\n    high: 51.81,\n    low: 51.72,\n    close: 51.8,\n    volume: 74024,\n  },\n  {\n    date: 1463148240000,\n    open: 51.8,\n    high: 51.85,\n    low: 51.79,\n    close: 51.85,\n    volume: 42685,\n  },\n  {\n    date: 1463148300000,\n    open: 51.85,\n    high: 51.89,\n    low: 51.8454,\n    close: 51.86,\n    volume: 89450,\n  },\n  {\n    date: 1463148360000,\n    open: 51.86,\n    high: 51.895,\n    low: 51.83,\n    close: 51.86,\n    volume: 72387,\n  },\n  {\n    date: 1463148420000,\n    open: 51.8665,\n    high: 51.87,\n    low: 51.79,\n    close: 51.795,\n    volume: 35115,\n  },\n  {\n    date: 1463148480000,\n    open: 51.8,\n    high: 51.81,\n    low: 51.74,\n    close: 51.74,\n    volume: 30628,\n  },\n  {\n    date: 1463148540000,\n    open: 51.735,\n    high: 51.762,\n    low: 51.7,\n    close: 51.762,\n    volume: 90143,\n  },\n  {\n    date: 1463148600000,\n    open: 51.7699,\n    high: 51.81,\n    low: 51.76,\n    close: 51.78,\n    volume: 52607,\n  },\n  {\n    date: 1463148660000,\n    open: 51.77,\n    high: 51.78,\n    low: 51.745,\n    close: 51.765,\n    volume: 44851,\n  },\n  {\n    date: 1463148720000,\n    open: 51.76,\n    high: 51.77,\n    low: 51.74,\n    close: 51.755,\n    volume: 76424,\n  },\n  {\n    date: 1463148780000,\n    open: 51.76,\n    high: 51.8,\n    low: 51.75,\n    close: 51.8,\n    volume: 42255,\n  },\n  {\n    date: 1463148840000,\n    open: 51.795,\n    high: 51.805,\n    low: 51.77,\n    close: 51.78,\n    volume: 34416,\n  },\n  {\n    date: 1463148900000,\n    open: 51.79,\n    high: 51.81,\n    low: 51.785,\n    close: 51.81,\n    volume: 37829,\n  },\n  {\n    date: 1463148960000,\n    open: 51.8,\n    high: 51.805,\n    low: 51.76,\n    close: 51.78,\n    volume: 52475,\n  },\n  {\n    date: 1463149020000,\n    open: 51.7732,\n    high: 51.79,\n    low: 51.7601,\n    close: 51.775,\n    volume: 15975,\n  },\n  {\n    date: 1463149080000,\n    open: 51.774,\n    high: 51.8164,\n    low: 51.76,\n    close: 51.76,\n    volume: 39444,\n  },\n  {\n    date: 1463149140000,\n    open: 51.7601,\n    high: 51.82,\n    low: 51.7601,\n    close: 51.79,\n    volume: 24990,\n  },\n  {\n    date: 1463149200000,\n    open: 51.79,\n    high: 51.8,\n    low: 51.77,\n    close: 51.8,\n    volume: 34997,\n  },\n  {\n    date: 1463149260000,\n    open: 51.79,\n    high: 51.8015,\n    low: 51.73,\n    close: 51.74,\n    volume: 49948,\n  },\n  {\n    date: 1463149320000,\n    open: 51.74,\n    high: 51.78,\n    low: 51.74,\n    close: 51.7568,\n    volume: 23277,\n  },\n  {\n    date: 1463149380000,\n    open: 51.75,\n    high: 51.77,\n    low: 51.74,\n    close: 51.75,\n    volume: 24412,\n  },\n  {\n    date: 1463149440000,\n    open: 51.755,\n    high: 51.7735,\n    low: 51.73,\n    close: 51.7735,\n    volume: 27193,\n  },\n  {\n    date: 1463149500000,\n    open: 51.775,\n    high: 51.775,\n    low: 51.729,\n    close: 51.735,\n    volume: 32951,\n  },\n  {\n    date: 1463149560000,\n    open: 51.73,\n    high: 51.8099,\n    low: 51.73,\n    close: 51.782,\n    volume: 58182,\n  },\n  {\n    date: 1463149620000,\n    open: 51.79,\n    high: 51.79,\n    low: 51.74,\n    close: 51.765,\n    volume: 44163,\n  },\n  {\n    date: 1463149680000,\n    open: 51.76,\n    high: 51.77,\n    low: 51.75,\n    close: 51.75,\n    volume: 23404,\n  },\n  {\n    date: 1463149740000,\n    open: 51.755,\n    high: 51.78,\n    low: 51.74,\n    close: 51.7401,\n    volume: 35038,\n  },\n  {\n    date: 1463149800000,\n    open: 51.745,\n    high: 51.75,\n    low: 51.71,\n    close: 51.715,\n    volume: 35123,\n  },\n  {\n    date: 1463149860000,\n    open: 51.71,\n    high: 51.71,\n    low: 51.66,\n    close: 51.66,\n    volume: 32449,\n  },\n  {\n    date: 1463149920000,\n    open: 51.66,\n    high: 51.73,\n    low: 51.65,\n    close: 51.7,\n    volume: 46210,\n  },\n  {\n    date: 1463149980000,\n    open: 51.7,\n    high: 51.71,\n    low: 51.675,\n    close: 51.71,\n    volume: 31392,\n  },\n  {\n    date: 1463150040000,\n    open: 51.7,\n    high: 51.71,\n    low: 51.68,\n    close: 51.68,\n    volume: 22908,\n  },\n  {\n    date: 1463150100000,\n    open: 51.68,\n    high: 51.715,\n    low: 51.68,\n    close: 51.699,\n    volume: 26032,\n  },\n  {\n    date: 1463150160000,\n    open: 51.7,\n    high: 51.73,\n    low: 51.7,\n    close: 51.71,\n    volume: 33017,\n  },\n  {\n    date: 1463150220000,\n    open: 51.71,\n    high: 51.719,\n    low: 51.69,\n    close: 51.7019,\n    volume: 21324,\n  },\n  {\n    date: 1463150280000,\n    open: 51.7,\n    high: 51.72,\n    low: 51.68,\n    close: 51.72,\n    volume: 29504,\n  },\n  {\n    date: 1463150340000,\n    open: 51.715,\n    high: 51.75,\n    low: 51.715,\n    close: 51.75,\n    volume: 50015,\n  },\n  {\n    date: 1463150400000,\n    open: 51.745,\n    high: 51.755,\n    low: 51.705,\n    close: 51.725,\n    volume: 55206,\n  },\n  {\n    date: 1463150460000,\n    open: 51.7238,\n    high: 51.74,\n    low: 51.7,\n    close: 51.715,\n    volume: 28371,\n  },\n  {\n    date: 1463150520000,\n    open: 51.71,\n    high: 51.74,\n    low: 51.68,\n    close: 51.68,\n    volume: 34354,\n  },\n  {\n    date: 1463150580000,\n    open: 51.68,\n    high: 51.68,\n    low: 51.63,\n    close: 51.63,\n    volume: 86053,\n  },\n  {\n    date: 1463150640000,\n    open: 51.63,\n    high: 51.6399,\n    low: 51.6,\n    close: 51.63,\n    volume: 38086,\n  },\n  {\n    date: 1463150700000,\n    open: 51.62,\n    high: 51.65,\n    low: 51.62,\n    close: 51.65,\n    volume: 24899,\n  },\n  {\n    date: 1463150760000,\n    open: 51.65,\n    high: 51.67,\n    low: 51.64,\n    close: 51.645,\n    volume: 42468,\n  },\n  {\n    date: 1463150820000,\n    open: 51.65,\n    high: 51.68,\n    low: 51.65,\n    close: 51.67,\n    volume: 37807,\n  },\n  {\n    date: 1463150880000,\n    open: 51.679,\n    high: 51.68,\n    low: 51.66,\n    close: 51.68,\n    volume: 37740,\n  },\n  {\n    date: 1463150940000,\n    open: 51.685,\n    high: 51.69,\n    low: 51.65,\n    close: 51.66,\n    volume: 41243,\n  },\n  {\n    date: 1463151000000,\n    open: 51.655,\n    high: 51.66,\n    low: 51.63,\n    close: 51.65,\n    volume: 59720,\n  },\n  {\n    date: 1463151060000,\n    open: 51.65,\n    high: 51.71,\n    low: 51.65,\n    close: 51.7,\n    volume: 28283,\n  },\n  {\n    date: 1463151120000,\n    open: 51.7,\n    high: 51.75,\n    low: 51.7,\n    close: 51.72,\n    volume: 50587,\n  },\n  {\n    date: 1463151180000,\n    open: 51.72,\n    high: 51.7219,\n    low: 51.69,\n    close: 51.6965,\n    volume: 43152,\n  },\n  {\n    date: 1463151240000,\n    open: 51.7,\n    high: 51.7,\n    low: 51.66,\n    close: 51.68,\n    volume: 41484,\n  },\n  {\n    date: 1463151300000,\n    open: 51.68,\n    high: 51.68,\n    low: 51.63,\n    close: 51.63,\n    volume: 40407,\n  },\n  {\n    date: 1463151360000,\n    open: 51.6307,\n    high: 51.68,\n    low: 51.63,\n    close: 51.67,\n    volume: 40490,\n  },\n  {\n    date: 1463151420000,\n    open: 51.67,\n    high: 51.68,\n    low: 51.645,\n    close: 51.66,\n    volume: 25741,\n  },\n  {\n    date: 1463151480000,\n    open: 51.66,\n    high: 51.66,\n    low: 51.62,\n    close: 51.64,\n    volume: 55328,\n  },\n  {\n    date: 1463151540000,\n    open: 51.63,\n    high: 51.66,\n    low: 51.63,\n    close: 51.66,\n    volume: 15494,\n  },\n  {\n    date: 1463151600000,\n    open: 51.655,\n    high: 51.67,\n    low: 51.645,\n    close: 51.66,\n    volume: 74733,\n  },\n  {\n    date: 1463151660000,\n    open: 51.66,\n    high: 51.72,\n    low: 51.66,\n    close: 51.66,\n    volume: 56689,\n  },\n  {\n    date: 1463151720000,\n    open: 51.6699,\n    high: 51.68,\n    low: 51.65,\n    close: 51.66,\n    volume: 31009,\n  },\n  {\n    date: 1463151780000,\n    open: 51.6536,\n    high: 51.685,\n    low: 51.65,\n    close: 51.65,\n    volume: 42935,\n  },\n  {\n    date: 1463151840000,\n    open: 51.64,\n    high: 51.695,\n    low: 51.64,\n    close: 51.68,\n    volume: 35496,\n  },\n  {\n    date: 1463151900000,\n    open: 51.67,\n    high: 51.69,\n    low: 51.64,\n    close: 51.675,\n    volume: 55265,\n  },\n  {\n    date: 1463151960000,\n    open: 51.675,\n    high: 51.74,\n    low: 51.67,\n    close: 51.7399,\n    volume: 46941,\n  },\n  {\n    date: 1463152020000,\n    open: 51.74,\n    high: 51.7403,\n    low: 51.7,\n    close: 51.7301,\n    volume: 51049,\n  },\n  {\n    date: 1463152080000,\n    open: 51.74,\n    high: 51.74,\n    low: 51.7,\n    close: 51.73,\n    volume: 55279,\n  },\n  {\n    date: 1463152140000,\n    open: 51.72,\n    high: 51.75,\n    low: 51.695,\n    close: 51.74,\n    volume: 44600,\n  },\n  {\n    date: 1463152200000,\n    open: 51.73,\n    high: 51.77,\n    low: 51.71,\n    close: 51.77,\n    volume: 79263,\n  },\n  {\n    date: 1463152260000,\n    open: 51.76,\n    high: 51.78,\n    low: 51.73,\n    close: 51.78,\n    volume: 95978,\n  },\n  {\n    date: 1463152320000,\n    open: 51.77,\n    high: 51.8,\n    low: 51.7612,\n    close: 51.77,\n    volume: 46091,\n  },\n  {\n    date: 1463152380000,\n    open: 51.78,\n    high: 51.81,\n    low: 51.77,\n    close: 51.805,\n    volume: 49870,\n  },\n  {\n    date: 1463152440000,\n    open: 51.8,\n    high: 51.8,\n    low: 51.74,\n    close: 51.76,\n    volume: 47859,\n  },\n  {\n    date: 1463152500000,\n    open: 51.76,\n    high: 51.77,\n    low: 51.7,\n    close: 51.71,\n    volume: 34775,\n  },\n  {\n    date: 1463152560000,\n    open: 51.72,\n    high: 51.764,\n    low: 51.715,\n    close: 51.74,\n    volume: 28008,\n  },\n  {\n    date: 1463152620000,\n    open: 51.73,\n    high: 51.7536,\n    low: 51.705,\n    close: 51.75,\n    volume: 53310,\n  },\n  {\n    date: 1463152680000,\n    open: 51.75,\n    high: 51.78,\n    low: 51.75,\n    close: 51.76,\n    volume: 50833,\n  },\n  {\n    date: 1463152740000,\n    open: 51.77,\n    high: 51.78,\n    low: 51.721,\n    close: 51.75,\n    volume: 47360,\n  },\n  {\n    date: 1463152800000,\n    open: 51.75,\n    high: 51.75,\n    low: 51.71,\n    close: 51.73,\n    volume: 30566,\n  },\n  {\n    date: 1463152860000,\n    open: 51.74,\n    high: 51.76,\n    low: 51.71,\n    close: 51.73,\n    volume: 54653,\n  },\n  {\n    date: 1463152920000,\n    open: 51.725,\n    high: 51.75,\n    low: 51.71,\n    close: 51.73,\n    volume: 61478,\n  },\n  {\n    date: 1463152980000,\n    open: 51.74,\n    high: 51.755,\n    low: 51.715,\n    close: 51.72,\n    volume: 69451,\n  },\n  {\n    date: 1463153040000,\n    open: 51.72,\n    high: 51.73,\n    low: 51.68,\n    close: 51.68,\n    volume: 59335,\n  },\n  {\n    date: 1463153100000,\n    open: 51.68,\n    high: 51.69,\n    low: 51.66,\n    close: 51.689,\n    volume: 44538,\n  },\n  {\n    date: 1463153160000,\n    open: 51.685,\n    high: 51.69,\n    low: 51.66,\n    close: 51.68,\n    volume: 56503,\n  },\n  {\n    date: 1463153220000,\n    open: 51.68,\n    high: 51.77,\n    low: 51.68,\n    close: 51.75,\n    volume: 63433,\n  },\n  {\n    date: 1463153280000,\n    open: 51.75,\n    high: 51.75,\n    low: 51.71,\n    close: 51.745,\n    volume: 49882,\n  },\n  {\n    date: 1463153340000,\n    open: 51.74,\n    high: 51.75,\n    low: 51.72,\n    close: 51.7399,\n    volume: 35083,\n  },\n  {\n    date: 1463153400000,\n    open: 51.73,\n    high: 51.77,\n    low: 51.72,\n    close: 51.72,\n    volume: 48223,\n  },\n  {\n    date: 1463153460000,\n    open: 51.725,\n    high: 51.735,\n    low: 51.69,\n    close: 51.725,\n    volume: 26158,\n  },\n  {\n    date: 1463153520000,\n    open: 51.73,\n    high: 51.74,\n    low: 51.71,\n    close: 51.72,\n    volume: 38430,\n  },\n  {\n    date: 1463153580000,\n    open: 51.72,\n    high: 51.74,\n    low: 51.72,\n    close: 51.72,\n    volume: 25362,\n  },\n  {\n    date: 1463153640000,\n    open: 51.73,\n    high: 51.745,\n    low: 51.693,\n    close: 51.7,\n    volume: 48918,\n  },\n  {\n    date: 1463153700000,\n    open: 51.7,\n    high: 51.715,\n    low: 51.7,\n    close: 51.7,\n    volume: 21317,\n  },\n  {\n    date: 1463153760000,\n    open: 51.7,\n    high: 51.7,\n    low: 51.65,\n    close: 51.65,\n    volume: 28565,\n  },\n  {\n    date: 1463153820000,\n    open: 51.6501,\n    high: 51.67,\n    low: 51.64,\n    close: 51.655,\n    volume: 50273,\n  },\n  {\n    date: 1463153880000,\n    open: 51.65,\n    high: 51.68,\n    low: 51.64,\n    close: 51.68,\n    volume: 26600,\n  },\n  {\n    date: 1463153940000,\n    open: 51.6735,\n    high: 51.7,\n    low: 51.67,\n    close: 51.695,\n    volume: 19074,\n  },\n  {\n    date: 1463154000000,\n    open: 51.7,\n    high: 51.73,\n    low: 51.7,\n    close: 51.71,\n    volume: 43332,\n  },\n  {\n    date: 1463154060000,\n    open: 51.71,\n    high: 51.72,\n    low: 51.68,\n    close: 51.7,\n    volume: 27675,\n  },\n  {\n    date: 1463154120000,\n    open: 51.706,\n    high: 51.71,\n    low: 51.67,\n    close: 51.67,\n    volume: 20601,\n  },\n  {\n    date: 1463154180000,\n    open: 51.677,\n    high: 51.7,\n    low: 51.671,\n    close: 51.68,\n    volume: 23783,\n  },\n  {\n    date: 1463154240000,\n    open: 51.68,\n    high: 51.685,\n    low: 51.64,\n    close: 51.64,\n    volume: 48189,\n  },\n  {\n    date: 1463154300000,\n    open: 51.65,\n    high: 51.68,\n    low: 51.64,\n    close: 51.64,\n    volume: 21903,\n  },\n  {\n    date: 1463154360000,\n    open: 51.64,\n    high: 51.645,\n    low: 51.61,\n    close: 51.61,\n    volume: 25045,\n  },\n  {\n    date: 1463154420000,\n    open: 51.61,\n    high: 51.64,\n    low: 51.605,\n    close: 51.64,\n    volume: 77331,\n  },\n  {\n    date: 1463154480000,\n    open: 51.64,\n    high: 51.66,\n    low: 51.63,\n    close: 51.64,\n    volume: 24055,\n  },\n  {\n    date: 1463154540000,\n    open: 51.64,\n    high: 51.66,\n    low: 51.64,\n    close: 51.66,\n    volume: 18390,\n  },\n  {\n    date: 1463154600000,\n    open: 51.65,\n    high: 51.66,\n    low: 51.635,\n    close: 51.635,\n    volume: 21571,\n  },\n  {\n    date: 1463154660000,\n    open: 51.63,\n    high: 51.635,\n    low: 51.575,\n    close: 51.5999,\n    volume: 66563,\n  },\n  {\n    date: 1463154720000,\n    open: 51.595,\n    high: 51.61,\n    low: 51.59,\n    close: 51.61,\n    volume: 13427,\n  },\n  {\n    date: 1463154780000,\n    open: 51.61,\n    high: 51.63,\n    low: 51.61,\n    close: 51.6165,\n    volume: 15054,\n  },\n  {\n    date: 1463154840000,\n    open: 51.62,\n    high: 51.6299,\n    low: 51.595,\n    close: 51.61,\n    volume: 25589,\n  },\n  {\n    date: 1463154900000,\n    open: 51.6138,\n    high: 51.63,\n    low: 51.59,\n    close: 51.62,\n    volume: 22534,\n  },\n  {\n    date: 1463154960000,\n    open: 51.61,\n    high: 51.62,\n    low: 51.61,\n    close: 51.61,\n    volume: 26291,\n  },\n  {\n    date: 1463155020000,\n    open: 51.61,\n    high: 51.63,\n    low: 51.59,\n    close: 51.6266,\n    volume: 25613,\n  },\n  {\n    date: 1463155080000,\n    open: 51.6201,\n    high: 51.645,\n    low: 51.62,\n    close: 51.625,\n    volume: 27972,\n  },\n  {\n    date: 1463155140000,\n    open: 51.625,\n    high: 51.63,\n    low: 51.59,\n    close: 51.59,\n    volume: 36545,\n  },\n  {\n    date: 1463155200000,\n    open: 51.58,\n    high: 51.5856,\n    low: 51.565,\n    close: 51.57,\n    volume: 36990,\n  },\n  {\n    date: 1463155260000,\n    open: 51.58,\n    high: 51.61,\n    low: 51.57,\n    close: 51.61,\n    volume: 29874,\n  },\n  {\n    date: 1463155320000,\n    open: 51.6,\n    high: 51.61,\n    low: 51.575,\n    close: 51.5753,\n    volume: 26862,\n  },\n  {\n    date: 1463155380000,\n    open: 51.58,\n    high: 51.59,\n    low: 51.57,\n    close: 51.575,\n    volume: 18868,\n  },\n  {\n    date: 1463155440000,\n    open: 51.575,\n    high: 51.61,\n    low: 51.56,\n    close: 51.6,\n    volume: 56415,\n  },\n  {\n    date: 1463155500000,\n    open: 51.6,\n    high: 51.605,\n    low: 51.587,\n    close: 51.5999,\n    volume: 23160,\n  },\n  {\n    date: 1463155560000,\n    open: 51.5901,\n    high: 51.6199,\n    low: 51.59,\n    close: 51.61,\n    volume: 16104,\n  },\n  {\n    date: 1463155620000,\n    open: 51.61,\n    high: 51.64,\n    low: 51.6085,\n    close: 51.625,\n    volume: 47049,\n  },\n  {\n    date: 1463155680000,\n    open: 51.62,\n    high: 51.6263,\n    low: 51.6,\n    close: 51.62,\n    volume: 31511,\n  },\n  {\n    date: 1463155740000,\n    open: 51.625,\n    high: 51.63,\n    low: 51.58,\n    close: 51.595,\n    volume: 44969,\n  },\n  {\n    date: 1463155800000,\n    open: 51.598,\n    high: 51.62,\n    low: 51.59,\n    close: 51.59,\n    volume: 28751,\n  },\n  {\n    date: 1463155860000,\n    open: 51.5925,\n    high: 51.615,\n    low: 51.585,\n    close: 51.585,\n    volume: 32626,\n  },\n  {\n    date: 1463155920000,\n    open: 51.59,\n    high: 51.625,\n    low: 51.59,\n    close: 51.61,\n    volume: 25507,\n  },\n  {\n    date: 1463155980000,\n    open: 51.615,\n    high: 51.63,\n    low: 51.61,\n    close: 51.61,\n    volume: 32025,\n  },\n  {\n    date: 1463156040000,\n    open: 51.61,\n    high: 51.618,\n    low: 51.59,\n    close: 51.59,\n    volume: 20761,\n  },\n  {\n    date: 1463156100000,\n    open: 51.6,\n    high: 51.6,\n    low: 51.59,\n    close: 51.5933,\n    volume: 19624,\n  },\n  {\n    date: 1463156160000,\n    open: 51.59,\n    high: 51.62,\n    low: 51.59,\n    close: 51.61,\n    volume: 22407,\n  },\n  {\n    date: 1463156220000,\n    open: 51.61,\n    high: 51.6125,\n    low: 51.59,\n    close: 51.59,\n    volume: 20572,\n  },\n  {\n    date: 1463156280000,\n    open: 51.59,\n    high: 51.63,\n    low: 51.59,\n    close: 51.6225,\n    volume: 28281,\n  },\n  {\n    date: 1463156340000,\n    open: 51.6299,\n    high: 51.675,\n    low: 51.61,\n    close: 51.665,\n    volume: 81155,\n  },\n  {\n    date: 1463156400000,\n    open: 51.665,\n    high: 51.69,\n    low: 51.66,\n    close: 51.67,\n    volume: 37528,\n  },\n  {\n    date: 1463156460000,\n    open: 51.675,\n    high: 51.68,\n    low: 51.66,\n    close: 51.67,\n    volume: 31016,\n  },\n  {\n    date: 1463156520000,\n    open: 51.675,\n    high: 51.675,\n    low: 51.645,\n    close: 51.65,\n    volume: 17947,\n  },\n  {\n    date: 1463156580000,\n    open: 51.66,\n    high: 51.6888,\n    low: 51.6599,\n    close: 51.679,\n    volume: 48423,\n  },\n  {\n    date: 1463156640000,\n    open: 51.67,\n    high: 51.72,\n    low: 51.67,\n    close: 51.675,\n    volume: 55435,\n  },\n  {\n    date: 1463156700000,\n    open: 51.675,\n    high: 51.7,\n    low: 51.675,\n    close: 51.695,\n    volume: 24570,\n  },\n  {\n    date: 1463156760000,\n    open: 51.6999,\n    high: 51.7099,\n    low: 51.68,\n    close: 51.69,\n    volume: 51720,\n  },\n  {\n    date: 1463156820000,\n    open: 51.6835,\n    high: 51.72,\n    low: 51.6835,\n    close: 51.7063,\n    volume: 31168,\n  },\n  {\n    date: 1463156880000,\n    open: 51.7,\n    high: 51.72,\n    low: 51.67,\n    close: 51.72,\n    volume: 34500,\n  },\n  {\n    date: 1463156940000,\n    open: 51.71,\n    high: 51.72,\n    low: 51.665,\n    close: 51.68,\n    volume: 46174,\n  },\n  {\n    date: 1463157000000,\n    open: 51.689,\n    high: 51.695,\n    low: 51.68,\n    close: 51.69,\n    volume: 19511,\n  },\n  {\n    date: 1463157060000,\n    open: 51.695,\n    high: 51.695,\n    low: 51.68,\n    close: 51.685,\n    volume: 16099,\n  },\n  {\n    date: 1463157120000,\n    open: 51.69,\n    high: 51.7,\n    low: 51.67,\n    close: 51.68,\n    volume: 39149,\n  },\n  {\n    date: 1463157180000,\n    open: 51.68,\n    high: 51.72,\n    low: 51.68,\n    close: 51.71,\n    volume: 28658,\n  },\n  {\n    date: 1463157240000,\n    open: 51.7,\n    high: 51.71,\n    low: 51.685,\n    close: 51.705,\n    volume: 67684,\n  },\n  {\n    date: 1463157300000,\n    open: 51.7,\n    high: 51.72,\n    low: 51.69,\n    close: 51.705,\n    volume: 47637,\n  },\n  {\n    date: 1463157360000,\n    open: 51.7065,\n    high: 51.725,\n    low: 51.703,\n    close: 51.7224,\n    volume: 15800,\n  },\n  {\n    date: 1463157420000,\n    open: 51.721,\n    high: 51.735,\n    low: 51.715,\n    close: 51.72,\n    volume: 26283,\n  },\n  {\n    date: 1463157480000,\n    open: 51.73,\n    high: 51.73,\n    low: 51.695,\n    close: 51.703,\n    volume: 26448,\n  },\n  {\n    date: 1463157540000,\n    open: 51.7,\n    high: 51.7,\n    low: 51.66,\n    close: 51.66,\n    volume: 31458,\n  },\n  {\n    date: 1463157600000,\n    open: 51.665,\n    high: 51.68,\n    low: 51.66,\n    close: 51.67,\n    volume: 26439,\n  },\n  {\n    date: 1463157660000,\n    open: 51.67,\n    high: 51.67,\n    low: 51.635,\n    close: 51.64,\n    volume: 23281,\n  },\n  {\n    date: 1463157720000,\n    open: 51.64,\n    high: 51.64,\n    low: 51.6,\n    close: 51.625,\n    volume: 30674,\n  },\n  {\n    date: 1463157780000,\n    open: 51.625,\n    high: 51.635,\n    low: 51.595,\n    close: 51.6,\n    volume: 53498,\n  },\n  {\n    date: 1463157840000,\n    open: 51.6001,\n    high: 51.606,\n    low: 51.57,\n    close: 51.5701,\n    volume: 22616,\n  },\n  {\n    date: 1463157900000,\n    open: 51.57,\n    high: 51.59,\n    low: 51.55,\n    close: 51.585,\n    volume: 61406,\n  },\n  {\n    date: 1463157960000,\n    open: 51.5837,\n    high: 51.59,\n    low: 51.56,\n    close: 51.59,\n    volume: 28080,\n  },\n  {\n    date: 1463158020000,\n    open: 51.59,\n    high: 51.62,\n    low: 51.59,\n    close: 51.61,\n    volume: 20069,\n  },\n  {\n    date: 1463158080000,\n    open: 51.6,\n    high: 51.63,\n    low: 51.59,\n    close: 51.6201,\n    volume: 24029,\n  },\n  {\n    date: 1463158140000,\n    open: 51.63,\n    high: 51.64,\n    low: 51.62,\n    close: 51.62,\n    volume: 20991,\n  },\n  {\n    date: 1463158200000,\n    open: 51.625,\n    high: 51.63,\n    low: 51.605,\n    close: 51.605,\n    volume: 17551,\n  },\n  {\n    date: 1463158260000,\n    open: 51.6035,\n    high: 51.62,\n    low: 51.595,\n    close: 51.6,\n    volume: 22760,\n  },\n  {\n    date: 1463158320000,\n    open: 51.595,\n    high: 51.61,\n    low: 51.59,\n    close: 51.605,\n    volume: 14853,\n  },\n  {\n    date: 1463158380000,\n    open: 51.61,\n    high: 51.63,\n    low: 51.61,\n    close: 51.62,\n    volume: 10356,\n  },\n  {\n    date: 1463158440000,\n    open: 51.62,\n    high: 51.62,\n    low: 51.59,\n    close: 51.597,\n    volume: 14773,\n  },\n  {\n    date: 1463158500000,\n    open: 51.6,\n    high: 51.61,\n    low: 51.57,\n    close: 51.58,\n    volume: 36265,\n  },\n  {\n    date: 1463158560000,\n    open: 51.58,\n    high: 51.61,\n    low: 51.58,\n    close: 51.6,\n    volume: 15420,\n  },\n  {\n    date: 1463158620000,\n    open: 51.608,\n    high: 51.608,\n    low: 51.57,\n    close: 51.59,\n    volume: 38817,\n  },\n  {\n    date: 1463158680000,\n    open: 51.59,\n    high: 51.59,\n    low: 51.55,\n    close: 51.55,\n    volume: 24836,\n  },\n  {\n    date: 1463158740000,\n    open: 51.55,\n    high: 51.565,\n    low: 51.54,\n    close: 51.56,\n    volume: 75977,\n  },\n  {\n    date: 1463158800000,\n    open: 51.55,\n    high: 51.57,\n    low: 51.54,\n    close: 51.57,\n    volume: 20702,\n  },\n  {\n    date: 1463158860000,\n    open: 51.57,\n    high: 51.59,\n    low: 51.56,\n    close: 51.585,\n    volume: 32744,\n  },\n  {\n    date: 1463158920000,\n    open: 51.58,\n    high: 51.61,\n    low: 51.56,\n    close: 51.61,\n    volume: 18870,\n  },\n  {\n    date: 1463158980000,\n    open: 51.6074,\n    high: 51.615,\n    low: 51.59,\n    close: 51.59,\n    volume: 26933,\n  },\n  {\n    date: 1463159040000,\n    open: 51.59,\n    high: 51.62,\n    low: 51.585,\n    close: 51.62,\n    volume: 20593,\n  },\n  {\n    date: 1463159100000,\n    open: 51.62,\n    high: 51.65,\n    low: 51.62,\n    close: 51.63,\n    volume: 15449,\n  },\n  {\n    date: 1463159160000,\n    open: 51.64,\n    high: 51.65,\n    low: 51.63,\n    close: 51.645,\n    volume: 18928,\n  },\n  {\n    date: 1463159220000,\n    open: 51.645,\n    high: 51.645,\n    low: 51.61,\n    close: 51.625,\n    volume: 27727,\n  },\n  {\n    date: 1463159280000,\n    open: 51.625,\n    high: 51.635,\n    low: 51.6,\n    close: 51.605,\n    volume: 32192,\n  },\n  {\n    date: 1463159340000,\n    open: 51.605,\n    high: 51.64,\n    low: 51.6,\n    close: 51.63,\n    volume: 20422,\n  },\n  {\n    date: 1463159400000,\n    open: 51.64,\n    high: 51.6562,\n    low: 51.635,\n    close: 51.65,\n    volume: 30901,\n  },\n  {\n    date: 1463159460000,\n    open: 51.649,\n    high: 51.655,\n    low: 51.63,\n    close: 51.64,\n    volume: 36256,\n  },\n  {\n    date: 1463159520000,\n    open: 51.63,\n    high: 51.665,\n    low: 51.63,\n    close: 51.665,\n    volume: 15738,\n  },\n  {\n    date: 1463159580000,\n    open: 51.665,\n    high: 51.68,\n    low: 51.64,\n    close: 51.6538,\n    volume: 30352,\n  },\n  {\n    date: 1463159640000,\n    open: 51.655,\n    high: 51.6599,\n    low: 51.64,\n    close: 51.64,\n    volume: 21890,\n  },\n  {\n    date: 1463159700000,\n    open: 51.64,\n    high: 51.67,\n    low: 51.63,\n    close: 51.65,\n    volume: 19403,\n  },\n  {\n    date: 1463159760000,\n    open: 51.65,\n    high: 51.65,\n    low: 51.62,\n    close: 51.62,\n    volume: 24658,\n  },\n  {\n    date: 1463159820000,\n    open: 51.6295,\n    high: 51.64,\n    low: 51.62,\n    close: 51.63,\n    volume: 17951,\n  },\n  {\n    date: 1463159880000,\n    open: 51.62,\n    high: 51.635,\n    low: 51.59,\n    close: 51.6,\n    volume: 71240,\n  },\n  {\n    date: 1463159940000,\n    open: 51.59,\n    high: 51.62,\n    low: 51.59,\n    close: 51.615,\n    volume: 20599,\n  },\n  {\n    date: 1463160000000,\n    open: 51.62,\n    high: 51.62,\n    low: 51.57,\n    close: 51.57,\n    volume: 53550,\n  },\n  {\n    date: 1463160060000,\n    open: 51.575,\n    high: 51.58,\n    low: 51.55,\n    close: 51.57,\n    volume: 36443,\n  },\n  {\n    date: 1463160120000,\n    open: 51.565,\n    high: 51.575,\n    low: 51.56,\n    close: 51.56,\n    volume: 18563,\n  },\n  {\n    date: 1463160180000,\n    open: 51.56,\n    high: 51.575,\n    low: 51.56,\n    close: 51.56,\n    volume: 13380,\n  },\n  {\n    date: 1463160240000,\n    open: 51.5625,\n    high: 51.57,\n    low: 51.515,\n    close: 51.52,\n    volume: 126054,\n  },\n  {\n    date: 1463160300000,\n    open: 51.52,\n    high: 51.53,\n    low: 51.5,\n    close: 51.5,\n    volume: 76471,\n  },\n  {\n    date: 1463160360000,\n    open: 51.5041,\n    high: 51.535,\n    low: 51.5,\n    close: 51.53,\n    volume: 28500,\n  },\n  {\n    date: 1463160420000,\n    open: 51.53,\n    high: 51.545,\n    low: 51.51,\n    close: 51.52,\n    volume: 54331,\n  },\n  {\n    date: 1463160480000,\n    open: 51.51,\n    high: 51.525,\n    low: 51.49,\n    close: 51.5,\n    volume: 52352,\n  },\n  {\n    date: 1463160540000,\n    open: 51.49,\n    high: 51.52,\n    low: 51.485,\n    close: 51.51,\n    volume: 30779,\n  },\n  {\n    date: 1463160600000,\n    open: 51.52,\n    high: 51.52,\n    low: 51.47,\n    close: 51.49,\n    volume: 75771,\n  },\n  {\n    date: 1463160660000,\n    open: 51.49,\n    high: 51.53,\n    low: 51.48,\n    close: 51.525,\n    volume: 36918,\n  },\n  {\n    date: 1463160720000,\n    open: 51.525,\n    high: 51.53,\n    low: 51.5,\n    close: 51.52,\n    volume: 31331,\n  },\n  {\n    date: 1463160780000,\n    open: 51.51,\n    high: 51.53,\n    low: 51.5,\n    close: 51.52,\n    volume: 18717,\n  },\n  {\n    date: 1463160840000,\n    open: 51.51,\n    high: 51.52,\n    low: 51.49,\n    close: 51.51,\n    volume: 25326,\n  },\n  {\n    date: 1463160900000,\n    open: 51.51,\n    high: 51.51,\n    low: 51.49,\n    close: 51.5,\n    volume: 17491,\n  },\n  {\n    date: 1463160960000,\n    open: 51.5,\n    high: 51.51,\n    low: 51.47,\n    close: 51.48,\n    volume: 22927,\n  },\n  {\n    date: 1463161020000,\n    open: 51.49,\n    high: 51.495,\n    low: 51.44,\n    close: 51.44,\n    volume: 97559,\n  },\n  {\n    date: 1463161080000,\n    open: 51.45,\n    high: 51.46,\n    low: 51.41,\n    close: 51.41,\n    volume: 55122,\n  },\n  {\n    date: 1463161140000,\n    open: 51.4101,\n    high: 51.44,\n    low: 51.4101,\n    close: 51.43,\n    volume: 25618,\n  },\n  {\n    date: 1463161200000,\n    open: 51.4399,\n    high: 51.45,\n    low: 51.39,\n    close: 51.4,\n    volume: 60946,\n  },\n  {\n    date: 1463161260000,\n    open: 51.4,\n    high: 51.42,\n    low: 51.39,\n    close: 51.4001,\n    volume: 70570,\n  },\n  {\n    date: 1463161320000,\n    open: 51.4,\n    high: 51.44,\n    low: 51.4,\n    close: 51.435,\n    volume: 14992,\n  },\n  {\n    date: 1463161380000,\n    open: 51.44,\n    high: 51.46,\n    low: 51.43,\n    close: 51.44,\n    volume: 25079,\n  },\n  {\n    date: 1463161440000,\n    open: 51.44,\n    high: 51.4562,\n    low: 51.43,\n    close: 51.45,\n    volume: 8631,\n  },\n  {\n    date: 1463161500000,\n    open: 51.455,\n    high: 51.48,\n    low: 51.45,\n    close: 51.48,\n    volume: 21572,\n  },\n  {\n    date: 1463161560000,\n    open: 51.48,\n    high: 51.4893,\n    low: 51.46,\n    close: 51.485,\n    volume: 85445,\n  },\n  {\n    date: 1463161620000,\n    open: 51.485,\n    high: 51.5,\n    low: 51.48,\n    close: 51.5,\n    volume: 14569,\n  },\n  {\n    date: 1463161680000,\n    open: 51.49,\n    high: 51.5,\n    low: 51.48,\n    close: 51.5,\n    volume: 50809,\n  },\n  {\n    date: 1463161740000,\n    open: 51.49,\n    high: 51.52,\n    low: 51.49,\n    close: 51.51,\n    volume: 15620,\n  },\n  {\n    date: 1463161800000,\n    open: 51.5,\n    high: 51.51,\n    low: 51.44,\n    close: 51.44,\n    volume: 140844,\n  },\n  {\n    date: 1463161860000,\n    open: 51.44,\n    high: 51.44,\n    low: 51.4,\n    close: 51.4,\n    volume: 58041,\n  },\n  {\n    date: 1463161920000,\n    open: 51.4,\n    high: 51.4,\n    low: 51.35,\n    close: 51.359,\n    volume: 105338,\n  },\n  {\n    date: 1463161980000,\n    open: 51.35,\n    high: 51.36,\n    low: 51.33,\n    close: 51.34,\n    volume: 30750,\n  },\n  {\n    date: 1463162040000,\n    open: 51.3499,\n    high: 51.36,\n    low: 51.32,\n    close: 51.34,\n    volume: 56699,\n  },\n  {\n    date: 1463162100000,\n    open: 51.34,\n    high: 51.359,\n    low: 51.325,\n    close: 51.35,\n    volume: 80672,\n  },\n  {\n    date: 1463162160000,\n    open: 51.35,\n    high: 51.36,\n    low: 51.34,\n    close: 51.349,\n    volume: 21241,\n  },\n  {\n    date: 1463162220000,\n    open: 51.35,\n    high: 51.37,\n    low: 51.35,\n    close: 51.36,\n    volume: 32765,\n  },\n  {\n    date: 1463162280000,\n    open: 51.3564,\n    high: 51.375,\n    low: 51.35,\n    close: 51.375,\n    volume: 16939,\n  },\n  {\n    date: 1463162340000,\n    open: 51.375,\n    high: 51.395,\n    low: 51.36,\n    close: 51.37,\n    volume: 46594,\n  },\n  {\n    date: 1463162400000,\n    open: 51.37,\n    high: 51.375,\n    low: 51.33,\n    close: 51.33,\n    volume: 53314,\n  },\n  {\n    date: 1463162460000,\n    open: 51.33,\n    high: 51.335,\n    low: 51.29,\n    close: 51.315,\n    volume: 46822,\n  },\n  {\n    date: 1463162520000,\n    open: 51.31,\n    high: 51.35,\n    low: 51.31,\n    close: 51.34,\n    volume: 19918,\n  },\n  {\n    date: 1463162580000,\n    open: 51.34,\n    high: 51.36,\n    low: 51.32,\n    close: 51.36,\n    volume: 47433,\n  },\n  {\n    date: 1463162640000,\n    open: 51.36,\n    high: 51.37,\n    low: 51.32,\n    close: 51.34,\n    volume: 54647,\n  },\n  {\n    date: 1463162700000,\n    open: 51.3499,\n    high: 51.36,\n    low: 51.34,\n    close: 51.34,\n    volume: 26058,\n  },\n  {\n    date: 1463162760000,\n    open: 51.34,\n    high: 51.34,\n    low: 51.32,\n    close: 51.335,\n    volume: 23870,\n  },\n  {\n    date: 1463162820000,\n    open: 51.3399,\n    high: 51.34,\n    low: 51.32,\n    close: 51.32,\n    volume: 33494,\n  },\n  {\n    date: 1463162880000,\n    open: 51.32,\n    high: 51.34,\n    low: 51.32,\n    close: 51.3299,\n    volume: 27107,\n  },\n  {\n    date: 1463162940000,\n    open: 51.32,\n    high: 51.34,\n    low: 51.31,\n    close: 51.325,\n    volume: 53604,\n  },\n  {\n    date: 1463163000000,\n    open: 51.32,\n    high: 51.35,\n    low: 51.32,\n    close: 51.335,\n    volume: 44433,\n  },\n  {\n    date: 1463163060000,\n    open: 51.339,\n    high: 51.339,\n    low: 51.27,\n    close: 51.27,\n    volume: 31919,\n  },\n  {\n    date: 1463163120000,\n    open: 51.27,\n    high: 51.3,\n    low: 51.27,\n    close: 51.3,\n    volume: 20366,\n  },\n  {\n    date: 1463163180000,\n    open: 51.295,\n    high: 51.33,\n    low: 51.295,\n    close: 51.31,\n    volume: 42701,\n  },\n  {\n    date: 1463163240000,\n    open: 51.315,\n    high: 51.315,\n    low: 51.28,\n    close: 51.3,\n    volume: 28273,\n  },\n  {\n    date: 1463163300000,\n    open: 51.3,\n    high: 51.325,\n    low: 51.3,\n    close: 51.3168,\n    volume: 18113,\n  },\n  {\n    date: 1463163360000,\n    open: 51.31,\n    high: 51.315,\n    low: 51.29,\n    close: 51.305,\n    volume: 29233,\n  },\n  {\n    date: 1463163420000,\n    open: 51.32,\n    high: 51.33,\n    low: 51.2728,\n    close: 51.29,\n    volume: 60718,\n  },\n  {\n    date: 1463163480000,\n    open: 51.3,\n    high: 51.3,\n    low: 51.24,\n    close: 51.255,\n    volume: 41200,\n  },\n  {\n    date: 1463163540000,\n    open: 51.25,\n    high: 51.26,\n    low: 51.22,\n    close: 51.24,\n    volume: 54365,\n  },\n  {\n    date: 1463163600000,\n    open: 51.235,\n    high: 51.25,\n    low: 51.21,\n    close: 51.23,\n    volume: 56064,\n  },\n  {\n    date: 1463163660000,\n    open: 51.23,\n    high: 51.23,\n    low: 51.18,\n    close: 51.206,\n    volume: 81303,\n  },\n  {\n    date: 1463163720000,\n    open: 51.21,\n    high: 51.215,\n    low: 51.18,\n    close: 51.18,\n    volume: 33459,\n  },\n  {\n    date: 1463163780000,\n    open: 51.1862,\n    high: 51.1862,\n    low: 51.14,\n    close: 51.165,\n    volume: 52897,\n  },\n  {\n    date: 1463163840000,\n    open: 51.1668,\n    high: 51.215,\n    low: 51.1668,\n    close: 51.195,\n    volume: 32440,\n  },\n  {\n    date: 1463163900000,\n    open: 51.1917,\n    high: 51.22,\n    low: 51.18,\n    close: 51.22,\n    volume: 36198,\n  },\n  {\n    date: 1463163960000,\n    open: 51.21,\n    high: 51.245,\n    low: 51.21,\n    close: 51.23,\n    volume: 35111,\n  },\n  {\n    date: 1463164020000,\n    open: 51.23,\n    high: 51.235,\n    low: 51.205,\n    close: 51.225,\n    volume: 45937,\n  },\n  {\n    date: 1463164080000,\n    open: 51.215,\n    high: 51.24,\n    low: 51.21,\n    close: 51.23,\n    volume: 18662,\n  },\n  {\n    date: 1463164140000,\n    open: 51.23,\n    high: 51.26,\n    low: 51.22,\n    close: 51.255,\n    volume: 14158,\n  },\n  {\n    date: 1463164200000,\n    open: 51.255,\n    high: 51.27,\n    low: 51.24,\n    close: 51.26,\n    volume: 83450,\n  },\n  {\n    date: 1463164260000,\n    open: 51.26,\n    high: 51.265,\n    low: 51.225,\n    close: 51.25,\n    volume: 39569,\n  },\n  {\n    date: 1463164320000,\n    open: 51.25,\n    high: 51.255,\n    low: 51.23,\n    close: 51.235,\n    volume: 21851,\n  },\n  {\n    date: 1463164380000,\n    open: 51.24,\n    high: 51.27,\n    low: 51.21,\n    close: 51.22,\n    volume: 65284,\n  },\n  {\n    date: 1463164440000,\n    open: 51.21,\n    high: 51.24,\n    low: 51.21,\n    close: 51.21,\n    volume: 95367,\n  },\n  {\n    date: 1463164500000,\n    open: 51.215,\n    high: 51.225,\n    low: 51.2,\n    close: 51.21,\n    volume: 58359,\n  },\n  {\n    date: 1463164560000,\n    open: 51.21,\n    high: 51.23,\n    low: 51.205,\n    close: 51.22,\n    volume: 20484,\n  },\n  {\n    date: 1463164620000,\n    open: 51.2121,\n    high: 51.22,\n    low: 51.19,\n    close: 51.19,\n    volume: 63262,\n  },\n  {\n    date: 1463164680000,\n    open: 51.19,\n    high: 51.19,\n    low: 51.12,\n    close: 51.12,\n    volume: 67563,\n  },\n  {\n    date: 1463164740000,\n    open: 51.13,\n    high: 51.15,\n    low: 51.12,\n    close: 51.13,\n    volume: 61272,\n  },\n  {\n    date: 1463164800000,\n    open: 51.135,\n    high: 51.147,\n    low: 51.12,\n    close: 51.145,\n    volume: 38443,\n  },\n  {\n    date: 1463164860000,\n    open: 51.145,\n    high: 51.145,\n    low: 51.1,\n    close: 51.1027,\n    volume: 47587,\n  },\n  {\n    date: 1463164920000,\n    open: 51.1,\n    high: 51.11,\n    low: 51.07,\n    close: 51.1,\n    volume: 73498,\n  },\n  {\n    date: 1463164980000,\n    open: 51.11,\n    high: 51.12,\n    low: 51.06,\n    close: 51.096,\n    volume: 41813,\n  },\n  {\n    date: 1463165040000,\n    open: 51.0973,\n    high: 51.12,\n    low: 51.07,\n    close: 51.12,\n    volume: 39628,\n  },\n  {\n    date: 1463165100000,\n    open: 51.11,\n    high: 51.1572,\n    low: 51.11,\n    close: 51.135,\n    volume: 31752,\n  },\n  {\n    date: 1463165160000,\n    open: 51.135,\n    high: 51.15,\n    low: 51.12,\n    close: 51.135,\n    volume: 33804,\n  },\n  {\n    date: 1463165220000,\n    open: 51.14,\n    high: 51.1662,\n    low: 51.14,\n    close: 51.14,\n    volume: 31358,\n  },\n  {\n    date: 1463165280000,\n    open: 51.146,\n    high: 51.146,\n    low: 51.11,\n    close: 51.115,\n    volume: 70660,\n  },\n  {\n    date: 1463165340000,\n    open: 51.12,\n    high: 51.1399,\n    low: 51.11,\n    close: 51.1301,\n    volume: 40400,\n  },\n  {\n    date: 1463165400000,\n    open: 51.13,\n    high: 51.15,\n    low: 51.105,\n    close: 51.12,\n    volume: 59059,\n  },\n  {\n    date: 1463165460000,\n    open: 51.125,\n    high: 51.13,\n    low: 51.11,\n    close: 51.1256,\n    volume: 42001,\n  },\n  {\n    date: 1463165520000,\n    open: 51.1225,\n    high: 51.13,\n    low: 51.08,\n    close: 51.1,\n    volume: 70841,\n  },\n  {\n    date: 1463165580000,\n    open: 51.1,\n    high: 51.11,\n    low: 51.08,\n    close: 51.08,\n    volume: 61518,\n  },\n  {\n    date: 1463165640000,\n    open: 51.08,\n    high: 51.09,\n    low: 51.05,\n    close: 51.05,\n    volume: 46503,\n  },\n  {\n    date: 1463165700000,\n    open: 51.05,\n    high: 51.12,\n    low: 51.04,\n    close: 51.1001,\n    volume: 76218,\n  },\n  {\n    date: 1463165760000,\n    open: 51.105,\n    high: 51.11,\n    low: 51.07,\n    close: 51.1,\n    volume: 45562,\n  },\n  {\n    date: 1463165820000,\n    open: 51.11,\n    high: 51.13,\n    low: 51.1,\n    close: 51.11,\n    volume: 50828,\n  },\n  {\n    date: 1463165880000,\n    open: 51.1,\n    high: 51.16,\n    low: 51.1,\n    close: 51.14,\n    volume: 64942,\n  },\n  {\n    date: 1463165940000,\n    open: 51.145,\n    high: 51.15,\n    low: 51.13,\n    close: 51.13,\n    volume: 23617,\n  },\n  {\n    date: 1463166000000,\n    open: 51.14,\n    high: 51.16,\n    low: 51.135,\n    close: 51.14,\n    volume: 25215,\n  },\n  {\n    date: 1463166060000,\n    open: 51.13,\n    high: 51.15,\n    low: 51.1,\n    close: 51.1346,\n    volume: 29848,\n  },\n  {\n    date: 1463166120000,\n    open: 51.14,\n    high: 51.145,\n    low: 51.13,\n    close: 51.135,\n    volume: 20646,\n  },\n  {\n    date: 1463166180000,\n    open: 51.14,\n    high: 51.16,\n    low: 51.085,\n    close: 51.0999,\n    volume: 137556,\n  },\n  {\n    date: 1463166240000,\n    open: 51.1,\n    high: 51.13,\n    low: 51.095,\n    close: 51.13,\n    volume: 24326,\n  },\n  {\n    date: 1463166300000,\n    open: 51.13,\n    high: 51.16,\n    low: 51.12,\n    close: 51.16,\n    volume: 15489,\n  },\n  {\n    date: 1463166360000,\n    open: 51.16,\n    high: 51.17,\n    low: 51.15,\n    close: 51.15,\n    volume: 25272,\n  },\n  {\n    date: 1463166420000,\n    open: 51.155,\n    high: 51.155,\n    low: 51.09,\n    close: 51.1,\n    volume: 72537,\n  },\n  {\n    date: 1463166480000,\n    open: 51.11,\n    high: 51.13,\n    low: 51.1,\n    close: 51.1,\n    volume: 19033,\n  },\n  {\n    date: 1463166540000,\n    open: 51.109,\n    high: 51.11,\n    low: 51.06,\n    close: 51.08,\n    volume: 46520,\n  },\n  {\n    date: 1463166600000,\n    open: 51.0801,\n    high: 51.11,\n    low: 51.08,\n    close: 51.1,\n    volume: 17555,\n  },\n  {\n    date: 1463166660000,\n    open: 51.11,\n    high: 51.13,\n    low: 51.09,\n    close: 51.125,\n    volume: 26540,\n  },\n  {\n    date: 1463166720000,\n    open: 51.13,\n    high: 51.145,\n    low: 51.12,\n    close: 51.13,\n    volume: 39867,\n  },\n  {\n    date: 1463166780000,\n    open: 51.125,\n    high: 51.13,\n    low: 51.12,\n    close: 51.125,\n    volume: 8085,\n  },\n  {\n    date: 1463166840000,\n    open: 51.13,\n    high: 51.145,\n    low: 51.1,\n    close: 51.1,\n    volume: 51965,\n  },\n  {\n    date: 1463166900000,\n    open: 51.1,\n    high: 51.15,\n    low: 51.1,\n    close: 51.145,\n    volume: 29142,\n  },\n  {\n    date: 1463166960000,\n    open: 51.15,\n    high: 51.1783,\n    low: 51.145,\n    close: 51.15,\n    volume: 63409,\n  },\n  {\n    date: 1463167020000,\n    open: 51.15,\n    high: 51.18,\n    low: 51.14,\n    close: 51.18,\n    volume: 41999,\n  },\n  {\n    date: 1463167080000,\n    open: 51.185,\n    high: 51.21,\n    low: 51.17,\n    close: 51.21,\n    volume: 32764,\n  },\n  {\n    date: 1463167140000,\n    open: 51.205,\n    high: 51.215,\n    low: 51.185,\n    close: 51.205,\n    volume: 98693,\n  },\n  {\n    date: 1463167200000,\n    open: 51.2,\n    high: 51.22,\n    low: 51.18,\n    close: 51.2,\n    volume: 47633,\n  },\n  {\n    date: 1463167260000,\n    open: 51.2,\n    high: 51.23,\n    low: 51.19,\n    close: 51.2232,\n    volume: 25450,\n  },\n  {\n    date: 1463167320000,\n    open: 51.22,\n    high: 51.23,\n    low: 51.21,\n    close: 51.215,\n    volume: 20392,\n  },\n  {\n    date: 1463167380000,\n    open: 51.21,\n    high: 51.249,\n    low: 51.21,\n    close: 51.23,\n    volume: 28352,\n  },\n  {\n    date: 1463167440000,\n    open: 51.2356,\n    high: 51.2398,\n    low: 51.205,\n    close: 51.22,\n    volume: 44908,\n  },\n  {\n    date: 1463167500000,\n    open: 51.21,\n    high: 51.215,\n    low: 51.18,\n    close: 51.2036,\n    volume: 57736,\n  },\n  {\n    date: 1463167560000,\n    open: 51.205,\n    high: 51.21,\n    low: 51.175,\n    close: 51.1999,\n    volume: 54836,\n  },\n  {\n    date: 1463167620000,\n    open: 51.195,\n    high: 51.195,\n    low: 51.18,\n    close: 51.19,\n    volume: 19611,\n  },\n  {\n    date: 1463167680000,\n    open: 51.1901,\n    high: 51.1999,\n    low: 51.16,\n    close: 51.17,\n    volume: 33170,\n  },\n  {\n    date: 1463167740000,\n    open: 51.16,\n    high: 51.18,\n    low: 51.16,\n    close: 51.18,\n    volume: 16394,\n  },\n  {\n    date: 1463167800000,\n    open: 51.18,\n    high: 51.18,\n    low: 51.14,\n    close: 51.1511,\n    volume: 42308,\n  },\n  {\n    date: 1463167860000,\n    open: 51.155,\n    high: 51.18,\n    low: 51.15,\n    close: 51.1772,\n    volume: 22821,\n  },\n  {\n    date: 1463167920000,\n    open: 51.17,\n    high: 51.175,\n    low: 51.14,\n    close: 51.15,\n    volume: 39917,\n  },\n  {\n    date: 1463167980000,\n    open: 51.145,\n    high: 51.165,\n    low: 51.125,\n    close: 51.1575,\n    volume: 28039,\n  },\n  {\n    date: 1463168040000,\n    open: 51.1605,\n    high: 51.165,\n    low: 51.12,\n    close: 51.13,\n    volume: 40486,\n  },\n  {\n    date: 1463168100000,\n    open: 51.124,\n    high: 51.175,\n    low: 51.124,\n    close: 51.17,\n    volume: 47609,\n  },\n  {\n    date: 1463168160000,\n    open: 51.17,\n    high: 51.205,\n    low: 51.16,\n    close: 51.2,\n    volume: 60646,\n  },\n  {\n    date: 1463168220000,\n    open: 51.2,\n    high: 51.2,\n    low: 51.18,\n    close: 51.19,\n    volume: 45726,\n  },\n  {\n    date: 1463168280000,\n    open: 51.19,\n    high: 51.2399,\n    low: 51.18,\n    close: 51.226,\n    volume: 88391,\n  },\n  {\n    date: 1463168340000,\n    open: 51.22,\n    high: 51.225,\n    low: 51.19,\n    close: 51.215,\n    volume: 68989,\n  },\n  {\n    date: 1463168400000,\n    open: 51.21,\n    high: 51.23,\n    low: 51.2,\n    close: 51.225,\n    volume: 50055,\n  },\n  {\n    date: 1463168460000,\n    open: 51.225,\n    high: 51.25,\n    low: 51.22,\n    close: 51.24,\n    volume: 78243,\n  },\n  {\n    date: 1463168520000,\n    open: 51.2357,\n    high: 51.24,\n    low: 51.21,\n    close: 51.21,\n    volume: 55131,\n  },\n  {\n    date: 1463168580000,\n    open: 51.21,\n    high: 51.235,\n    low: 51.2,\n    close: 51.235,\n    volume: 44469,\n  },\n  {\n    date: 1463168640000,\n    open: 51.24,\n    high: 51.26,\n    low: 51.225,\n    close: 51.25,\n    volume: 59309,\n  },\n  {\n    date: 1463168700000,\n    open: 51.25,\n    high: 51.26,\n    low: 51.195,\n    close: 51.195,\n    volume: 62693,\n  },\n  {\n    date: 1463168760000,\n    open: 51.19,\n    high: 51.2,\n    low: 51.15,\n    close: 51.18,\n    volume: 86772,\n  },\n  {\n    date: 1463168820000,\n    open: 51.18,\n    high: 51.18,\n    low: 51.13,\n    close: 51.135,\n    volume: 78645,\n  },\n  {\n    date: 1463168880000,\n    open: 51.135,\n    high: 51.14,\n    low: 51.11,\n    close: 51.125,\n    volume: 63063,\n  },\n  {\n    date: 1463168940000,\n    open: 51.121,\n    high: 51.125,\n    low: 51.1,\n    close: 51.12,\n    volume: 64714,\n  },\n  {\n    date: 1463169000000,\n    open: 51.115,\n    high: 51.16,\n    low: 51.09,\n    close: 51.1,\n    volume: 132864,\n  },\n  {\n    date: 1463169060000,\n    open: 51.09,\n    high: 51.1298,\n    low: 51.09,\n    close: 51.115,\n    volume: 130985,\n  },\n  {\n    date: 1463169120000,\n    open: 51.115,\n    high: 51.12,\n    low: 51.085,\n    close: 51.105,\n    volume: 111359,\n  },\n  {\n    date: 1463169180000,\n    open: 51.11,\n    high: 51.13,\n    low: 51.1,\n    close: 51.115,\n    volume: 104307,\n  },\n  {\n    date: 1463169240000,\n    open: 51.115,\n    high: 51.13,\n    low: 51.11,\n    close: 51.115,\n    volume: 93090,\n  },\n  {\n    date: 1463169300000,\n    open: 51.12,\n    high: 51.13,\n    low: 51.085,\n    close: 51.095,\n    volume: 101862,\n  },\n  {\n    date: 1463169360000,\n    open: 51.09,\n    high: 51.13,\n    low: 51.09,\n    close: 51.115,\n    volume: 140395,\n  },\n  {\n    date: 1463169420000,\n    open: 51.119,\n    high: 51.13,\n    low: 51.09,\n    close: 51.105,\n    volume: 119025,\n  },\n  {\n    date: 1463169480000,\n    open: 51.11,\n    high: 51.13,\n    low: 51.1,\n    close: 51.12,\n    volume: 104428,\n  },\n  {\n    date: 1463169540000,\n    open: 51.12,\n    high: 51.13,\n    low: 51.1,\n    close: 51.105,\n    volume: 227741,\n  },\n  {\n    date: 1463169600000,\n    open: 51.1,\n    high: 51.1079,\n    low: 51.06,\n    close: 51.08,\n    volume: 2630306,\n  },\n]\n"
  },
  {
    "path": "packages/component-lib/src/components/charts/scaleAreaChart/KlineChart/index.ts",
    "content": "export * from './KlineChart'\nexport * from './data'\n"
  },
  {
    "path": "packages/component-lib/src/components/charts/scaleAreaChart/ScaleAreaChart.tsx",
    "content": "// import {WithTranslation, withTranslation} from \"react-i18next\";\n// import styled from \"@emotion/styled\";\n// import { IOrigDataItem, IGetDepthDataParams } from './data'\nimport TrendChart from './TrendChart'\nimport DepthChart from './DepthChart'\nimport { ChartType } from '../'\n\nimport { IndicatorProps, WrapperedKlineChart } from './KlineChart'\n\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { TradingInterval } from '@loopring-web/loopring-sdk'\nimport { useSettings } from '../../../stores'\nimport { getTheme } from '@loopring-web/common-resources'\n\nexport interface ScaleAreaChartProps {\n  type: ChartType\n  data: any\n  indicator?: IndicatorProps\n  interval?: sdk.TradingInterval\n  handleMove?: (props: any) => void\n  yAxisDomainPercent?: number // defualt 0.1\n  riseColor?: 'green' | 'red'\n  showTooltip?: boolean\n  showArea?: boolean\n  quoteSymbol?: string\n  showXAxis?: boolean\n  showYAxis?: boolean\n  isHeadTailCompare?: boolean\n  marketPrecision?: number\n  isDailyTrend?: boolean\n  handleMoveOut?: () => void\n  showCartesianGrid?: boolean\n  showClose?: boolean\n}\n\nexport const ScaleAreaChart = ({\n  type,\n  interval,\n  indicator,\n  data,\n  marketPrecision,\n  ...rest\n}: ScaleAreaChartProps) => {\n  const { themeMode, upColor } = useSettings()\n  switch (type) {\n    case ChartType.Trend:\n      return <TrendChart type={type} data={data} {...rest} />\n    case ChartType.Depth:\n      return (\n        <DepthChart\n          data={data}\n          marketPrecision={marketPrecision}\n          colorBase={getTheme(themeMode).colorBase}\n          {...rest}\n        />\n      )\n    case ChartType.Kline:\n      // let dateTimeFormat = '%Y %a %d'\n      let dateTimeFormat = '%x'\n      if (interval) {\n        switch (interval) {\n          case TradingInterval.min1:\n          case TradingInterval.min5:\n          case TradingInterval.min15:\n          case TradingInterval.min30:\n            // dateTimeFormat = '%Y %b %d, %I:%M %p'\n            dateTimeFormat = '%c'\n            break\n          case TradingInterval.hr1:\n          case TradingInterval.hr2:\n          case TradingInterval.hr4:\n          case TradingInterval.hr12:\n            // dateTimeFormat = '%Y %b %d, %I %p'\n            dateTimeFormat = '%c'\n            break\n          case TradingInterval.d1:\n            break\n          case TradingInterval.w1:\n            // dateTimeFormat = '%Y %b %d'\n            break\n          default:\n            break\n        }\n      }\n      return (\n        <WrapperedKlineChart\n          dateTimeFormat={dateTimeFormat}\n          {...indicator}\n          data={data}\n          upColor={upColor}\n          colorBase={getTheme(themeMode).colorBase}\n          marketPrecision={marketPrecision}\n        />\n      )\n    default:\n      return <span>prop \"type\" is not avaible for current chart</span>\n  }\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/charts/scaleAreaChart/TrendChart/ScaleAreaChart.stories.tsx",
    "content": "// also exported from '@storybook/react' if you can deal with breaking changes in 6.1\nimport { Meta, Story } from '@storybook/react'\nimport { ScaleAreaChart } from '../ScaleAreaChart'\nimport { ChartType } from '../../index'\nimport { withTranslation } from 'react-i18next'\nimport styled from '@emotion/styled'\n\nconst Styled = styled.div`\n  flex: 1;\n\n  width: 1000px;\n  height: 500px;\n`\n\n// @ts-ignore\nconst testTrendData: any = [\n  {\n    timeStamp: 150,\n    // low: Math.random() + 1,\n    // high: Math.random() + 6,\n    // open: Math.random() + 3,\n    close: Math.random() + 4,\n    // volume: (Math.random() + 4) * 1500,\n  },\n  {\n    timeStamp: 160,\n    // low: Math.random() + 1,\n    // high: Math.random() + 6,\n    // open: Math.random() + 3,\n    close: Math.random() + 4,\n    // volume: (Math.random() + 4) * 1500,\n  },\n  {\n    timeStamp: 170,\n    // low: Math.random() + 1,\n    // high: Math.random() + 6,\n    // open: Math.random() + 3,\n    close: Math.random() + 4,\n    // volume: (Math.random() + 4) * 1500,\n  },\n  {\n    timeStamp: 180,\n    // low: Math.random() + 1,\n    // high: Math.random() + 6,\n    // open: Math.random() + 3,\n    close: Math.random() + 4,\n    // volume: (Math.random() + 4) * 1500,\n  },\n  {\n    timeStamp: 190,\n    // low: Math.random() + 1,\n    // high: Math.random() + 6,\n    // open: Math.random() + 3,\n    close: Math.random() + 4,\n    // volume: (Math.random() + 4) * 1500,\n  },\n  {\n    timeStamp: 200,\n    // low: Math.random() + 1,\n    // high: Math.random() + 6,\n    // open: Math.random() + 3,\n    close: Math.random() + 4,\n    // volume: (Math.random() + 4) * 1500,\n  },\n  {\n    timeStamp: 210,\n    // low: Math.random() + 1,\n    // high: Math.random() + 6,\n    // open: Math.random() + 3,\n    close: Math.random() + 4,\n    // volume: (Math.random() + 4) * 1500,\n  },\n  {\n    timeStamp: 220,\n    // low: Math.random() + 1,\n    // high: Math.random() + 6,\n    // open: Math.random() + 3,\n    close: Math.random() + 4,\n    // volume: (Math.random() + 4) * 1500,\n  },\n  {\n    timeStamp: 230,\n    // low: Math.random() + 1,\n    // high: Math.random() + 6,\n    // open: Math.random() + 3,\n    close: Math.random() + 4,\n    // volume: (Math.random() + 4) * 1500,\n  },\n  {\n    timeStamp: 240,\n    // low: Math.random() + 1,\n    // high: Math.random() + 6,\n    // open: Math.random() + 3,\n    close: Math.random() + 4,\n    // volume: (Math.random() + 4) * 1500,\n  },\n]\n\nexport const Trend = withTranslation()(() => {\n  return (\n    <>\n      <Styled>\n        <ScaleAreaChart\n          type={ChartType.Trend}\n          data={testTrendData}\n          yAxisDomainPercent={0.2}\n          handleMove={(props) => {\n            console.log(props)\n          }}\n          // showTooltip={false}\n          // riseColor=\"red\"\n          // showArea={false}\n        />\n      </Styled>\n    </>\n  )\n}) as Story\n\nexport default {\n  title: 'Charts/Trend',\n  component: Trend,\n  argTypes: {},\n} as Meta\n"
  },
  {
    "path": "packages/component-lib/src/components/charts/scaleAreaChart/TrendChart/index.tsx",
    "content": "import React, { useCallback, useState } from 'react'\nimport {\n  Area,\n  ComposedChart,\n  Line,\n  ResponsiveContainer,\n  CartesianGrid,\n  Tooltip,\n  XAxis,\n  YAxis,\n} from '@loopring-web/recharts'\nimport moment from 'moment'\nimport { ScaleAreaChartProps } from '../ScaleAreaChart'\nimport { getRenderData } from '../data'\nimport { Box, Typography } from '@mui/material'\nimport styled from '@emotion/styled'\nimport { useSettings } from '@loopring-web/component-lib/src/stores'\nimport {\n  DAT_STRING_FORMAT,\n  DAT_STRING_FORMAT_S,\n  EmptyValueTag,\n  MINT_STRING_FORMAT,\n} from '@loopring-web/common-resources'\nimport { useTheme } from '@emotion/react'\n// import { getValuePrecisionThousand, myLog } from '@loopring-web/common-resources';\n\nconst DEFAULT_YAXIS_DOMAIN = 0.05\n\nconst TooltipStyled = styled(Box)`\n  background: var(--color-pop-bg);\n  border: 1px solid var(--color-border);\n  border-radius: ${({ theme }) => theme.unit * 0.25}px;\n  padding: ${({ theme }) => theme.unit * 2}px ${({ theme }) => theme.unit * 2}px;\n\n  > div:last-of-type {\n    color: var(--color-text-secondary);\n  }\n`\n\nconst TrendChart = ({\n  type,\n  data,\n  yAxisDomainPercent = DEFAULT_YAXIS_DOMAIN,\n  handleMove,\n  showTooltip = true,\n  showArea = true,\n  quoteSymbol,\n  showXAxis = true,\n  showYAxis = true,\n  isHeadTailCompare = false,\n  isDailyTrend = false,\n  handleMoveOut = undefined,\n  showCartesianGrid = false,\n  showClose = true,\n}: ScaleAreaChartProps) => {\n  const theme = useTheme()\n  const userSettings = useSettings()\n  const UP_COLOR = theme.colorBase.success\n  const DOWN_COLOR = theme.colorBase.error\n  const DAILY_TREND_COLOR = theme.colorBase.primary\n  const upColor = userSettings ? userSettings.upColor : 'green'\n  const renderData = getRenderData(type, data)\n  const [priceTrend, setPriceTrend] = useState<'up' | 'down'>(\n    renderData[renderData.length - 1]?.sign === 1 ? 'up' : 'down',\n  )\n  const [currentIndex, setCurrentIndex] = useState(-1)\n  const trendColor =\n    upColor === 'green'\n      ? priceTrend === 'up'\n        ? UP_COLOR\n        : DOWN_COLOR\n      : priceTrend === 'up'\n      ? DOWN_COLOR\n      : UP_COLOR\n  const hasData = data && Array.isArray(data) && !!data.length\n\n  const handleMousemove = useCallback(\n    (props: any) => {\n      if (!hasData) return\n      const { activeTooltipIndex } = props\n\n      // avoid duplicated event\n      const isUpdate = activeTooltipIndex !== currentIndex\n      if (Number.isFinite(activeTooltipIndex) && isUpdate) {\n        setCurrentIndex(activeTooltipIndex)\n        if (renderData[activeTooltipIndex] && renderData[activeTooltipIndex].sign) {\n          setPriceTrend(renderData[activeTooltipIndex].sign === 1 ? 'up' : 'down')\n        }\n        if (handleMove) {\n          handleMove(renderData[activeTooltipIndex])\n        }\n      }\n    },\n    [renderData, handleMove, currentIndex, hasData],\n  )\n\n  const renderTooltipContent = useCallback(\n    (props: any) => {\n      if (!hasData) return\n      if (!props.payload || !props.payload.length || !props.payload[0].payload.timeStamp)\n        return <span></span>\n      const { timeStamp, close, sign: inputSign, change: inputChange } = props.payload[0].payload\n      let change\n      if (inputChange) {\n        change = inputChange\n      } else {\n        const index = data.findIndex((o: any) => o.timeStamp === timeStamp)\n        change =\n          index === 0\n            ? EmptyValueTag\n            : (((close - data[index - 1].close) / data[index - 1].close) * 100).toFixed(2)\n      }\n      const sign = inputChange ? (Number(inputChange || 0) >= 0 ? 1 : -1) : inputSign\n      if (isDailyTrend) {\n        return (\n          <TooltipStyled>\n            <Typography component={'div'} variant={'body1'}>\n              {moment.unix(timeStamp / 1000).format(DAT_STRING_FORMAT)}\n            </Typography>\n            <Box display={'flex'}>\n              <Typography component={'span'} variant={'body1'}>\n                Change:\n              </Typography>\n              <Typography\n                color={\n                  sign !== 1\n                    ? upColor === 'green'\n                      ? DOWN_COLOR\n                      : UP_COLOR\n                    : upColor === 'green'\n                    ? UP_COLOR\n                    : DOWN_COLOR\n                }\n              >\n                &nbsp;{Number(change || 0) > 0 ? `+${change}` : change} %\n              </Typography>\n            </Box>\n          </TooltipStyled>\n        )\n      } else {\n        return (\n          <TooltipStyled>\n            {quoteSymbol && (\n              <Box display={'flex'} alignItems={'center'}>\n                <Typography component={'div'} fontSize={16}>{`${close} ${quoteSymbol}`}</Typography>\n                <Typography\n                  fontSize={16}\n                  color={\n                    sign !== 1\n                      ? upColor === 'green'\n                        ? DOWN_COLOR\n                        : UP_COLOR\n                      : upColor === 'green'\n                      ? UP_COLOR\n                      : DOWN_COLOR\n                  }\n                >\n                  &nbsp;{Number(change || 0) > 0 ? `+${change}` : change} %\n                </Typography>\n              </Box>\n            )}\n            <Typography component={'div'} fontSize={12}>\n              {moment.unix(timeStamp / 1000).format(MINT_STRING_FORMAT)}\n            </Typography>\n          </TooltipStyled>\n        )\n      }\n    },\n    [hasData, isDailyTrend, data, upColor, quoteSymbol],\n  )\n\n  const handleMouseLeave = useCallback(() => {\n    if (handleMoveOut) {\n      handleMoveOut()\n    }\n    setPriceTrend(renderData[renderData.length - 1]?.sign === 1 ? 'up' : 'down')\n  }, [renderData, handleMoveOut])\n\n  React.useEffect(() => {\n    if (!!renderData.length) {\n      setPriceTrend(renderData[renderData.length - 1].sign === 1 ? 'up' : 'down')\n    }\n    if (isHeadTailCompare) {\n      const isUp = (renderData[0]?.close || 0) < (renderData[renderData.length - 1]?.close || 0)\n      setPriceTrend(isUp ? 'up' : 'down')\n    }\n  }, [renderData[0]?.close])\n\n  const customTick = ({ x, y, payload }: any) => {\n    if (!renderData || !renderData.length) {\n      return <span></span>\n    }\n    return (\n      <g transform={`translate(${x}, ${y})`}>\n        <text x={0} y={0} dy={16} fontSize={12} textAnchor='end' fill={theme.colorBase.textThird}>\n          {moment(payload.value).format(DAT_STRING_FORMAT_S)}\n        </text>\n      </g>\n    )\n  }\n\n  const getDynamicYAxisDomain = useCallback(() => {\n    const valueList = renderData.map((o) => o.close)\n    const min = Math.min(...valueList)\n    const max = Math.max(...valueList)\n    if (min / max < 0.1) {\n      return [(dataMin: number) => dataMin * 0.1, (dataMax: number) => dataMax * 2.5]\n    }\n    if (min / max < 0.5) {\n      return [(dataMin: number) => dataMin * 0.5, (dataMax: number) => dataMax * 1.2]\n    }\n    return [\n      (dataMin: number) => dataMin * (1 - yAxisDomainPercent),\n      (dataMax: number) => dataMax * (1 + yAxisDomainPercent),\n    ]\n  }, [renderData, yAxisDomainPercent])\n\n  // const customYAxisTick = (value: any) => {\n  //     const formattedValue = getValuePrecisionThousand((Number.isFinite(value) ? value : Number(value || 0)).toFixed(2), undefined, undefined, 2)\n  //     return formattedValue ?? '0.00'\n  // }\n\n  return (\n    <ResponsiveContainer debounce={100} width={'99%'}>\n      <ComposedChart\n        margin={{ left: 5, right: 10 }}\n        data={renderData}\n        onMouseMove={showTooltip && handleMousemove}\n        onMouseLeave={showTooltip && handleMouseLeave}\n      >\n        <defs>\n          <linearGradient id='colorUv' x1='0' y1='0' x2='0' y2='1'>\n            <stop offset='5%' stopColor={trendColor} stopOpacity={0.3} />\n            <stop offset='90%' stopColor={trendColor} stopOpacity={0} />\n          </linearGradient>\n        </defs>\n        {showCartesianGrid && (\n          <CartesianGrid\n            strokeOpacity={0.3}\n            stroke={'var(--color-text-secondary)'}\n            strokeDasharray='5 5'\n          />\n        )}\n        <XAxis\n          hide={!showXAxis}\n          dataKey={'timeStamp'}\n          tickCount={8}\n          axisLine={true}\n          tickLine={true}\n          tick={customTick}\n          stroke={theme.colorBase.textThird}\n        />\n        <YAxis\n          dataKey='close'\n          orientation={'right'}\n          hide={!showYAxis}\n          axisLine={false}\n          domain={getDynamicYAxisDomain() as any}\n          width={1}\n          tickCount={8}\n          label={\n            showClose\n              ? {\n                  value: 'close',\n                  fontSize: 14,\n                  textAnchor: 'end',\n                  fill: theme.colorBase.textThird,\n                  position: 'insideTopRight',\n                  transform: 'translate(0, 0)',\n                }\n              : undefined\n          }\n          tickFormatter={(value, index) => {\n            // const valueList = renderData.map((o) => o.close)\n            // const min = Math.min(...valueList)\n            // const max = Math.max(...valueList)\n            return index == 0 || index >= 5 ? '' : value\n          }}\n          tick={{\n            fill: theme.colorBase.textThird,\n            fontSize: 12,\n            textAnchor: 'start',\n            width: 34,\n            transform: 'translate(-68, 0)',\n          }}\n          /* tickFormatter={convertValue} */\n          stroke={'var(--color-text-secondary)'}\n        />\n        {hasData && showTooltip && (\n          <Tooltip\n            cursor={{ stroke: '#808080', strokeDasharray: '5 5' }}\n            //  cursor={<CustomCursor/>}\n            position={{ y: 50 }}\n            content={(props) => renderTooltipContent(props)}\n          />\n        )}\n        <Line\n          type='monotone'\n          strokeLinecap='round'\n          strokeWidth={2}\n          dataKey='close'\n          stroke={isDailyTrend ? DAILY_TREND_COLOR : trendColor}\n          dot={isDailyTrend}\n          legendType='none'\n          isAnimationActive={false}\n        />\n        {showArea && (\n          <Area\n            type='monotone'\n            dataKey='close'\n            stroke='false'\n            strokeWidth={2}\n            fillOpacity={1}\n            fill='url(#colorUv)'\n            isAnimationActive={false}\n          />\n        )}\n      </ComposedChart>\n    </ResponsiveContainer>\n  )\n}\n\nexport default TrendChart\n"
  },
  {
    "path": "packages/component-lib/src/components/charts/scaleAreaChart/data.tsx",
    "content": "import { ChartType } from '../'\n\nexport interface IOrigDataItem {\n  timeStamp: number\n  low: number\n  high: number\n  open: number\n  close: number\n  volume: number\n}\n\nexport interface IDataItem {\n  timeStamp: number\n  low: number\n  high: number\n  open: number\n  close: number\n  volume: number\n  sign: 1 | -1\n}\n\nexport interface GetSignParams {\n  type: keyof typeof ChartType\n  data: any\n  dataIndex: number\n  open: number\n  close: number\n  closeDimIdx: number\n}\n\nconst getSign = ({ data, dataIndex, close }: GetSignParams): IDataItem['sign'] => {\n  let sign\n  const closeLastDay = dataIndex !== 0 && data[dataIndex - 1].close\n  sign = dataIndex > 0 && closeLastDay ? (closeLastDay < close ? 1 : -1) : 1\n  return sign as IDataItem['sign']\n}\n\nexport const getRenderData = (\n  type: keyof typeof ChartType,\n  data?: IOrigDataItem[],\n): IDataItem[] => {\n  if (!data || !Array.isArray(data)) return []\n  const closeDimIdx = 3\n  return data.map((o, index) => {\n    if ((o as any).change) {\n      return {\n        ...o,\n        sign: ((o as any).change ?? 0) >= 0 ? 1 : -1\n      }\n    } else {\n      return {\n        ...o,\n        sign: getSign({\n          type,\n          data: data,\n          dataIndex: index,\n          open: o.open,\n          close: o.close,\n          closeDimIdx,\n        }),\n      }\n    }\n  })\n\n}\nexport const getAprRenderData = (\n  type: keyof typeof ChartType,\n  data?: { apy: string; createdAt: number }[],\n): { apy: string; createdAt: number }[] => {\n  if (!data || !Array.isArray(data)) return []\n  return data.map((o, _index) => ({\n    ...o,\n    sign: {\n      ...o,\n    },\n  }))\n}\n\nexport interface IGetDepthDataParams {\n  bidsPrices: number[]\n  bidsAmtTotals: number[]\n  asksPrices: number[]\n  asksAmtTotals: number[]\n}\n\nexport const getDepthData = (data?: IGetDepthDataParams | any) => {\n  if (!data || Array.isArray(data)) return undefined\n  const { bidsPrices, asksPrices, bidsAmtTotals, asksAmtTotals } = data\n  const formattedBidsPrices = bidsPrices.map((price: number) => ({\n    type: 'bids',\n    price,\n  }))\n  const formattedAsksPrices = asksPrices.map((price: number) => ({\n    type: 'asks',\n    price,\n  }))\n  const jointPrices = formattedBidsPrices.concat(formattedAsksPrices)\n  const jointAmtTotals = bidsAmtTotals.concat(asksAmtTotals)\n\n  const fakeData = [\n    {\n      price: formattedBidsPrices[formattedBidsPrices.length - 1]?.price,\n      bids: 0,\n    },\n    {\n      price: formattedAsksPrices[0]?.price,\n      asks: 0,\n    },\n  ]\n\n  const rawAmtTotals = jointAmtTotals.map((amount: number, index: number) =>\n    jointPrices[index].type === 'bids'\n      ? {\n          price: jointPrices[index].price,\n          bids: amount,\n        }\n      : {\n          price: jointPrices[index].price,\n          asks: amount,\n        },\n  )\n\n  const filteredBidsList = rawAmtTotals.filter((o: any) => o.bids)\n  const filteredAsksList = rawAmtTotals.filter((o: any) => o.asks)\n\n  const newData = [...filteredBidsList, ...fakeData, ...filteredAsksList]\n\n  return newData\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/charts/scaleAreaChart/index.ts",
    "content": "export * from './ScaleAreaChart'\nexport * from './data'\nexport * from './KlineChart'\nexport * from './APRChart'\n"
  },
  {
    "path": "packages/component-lib/src/components/datetimerangepicker/index.tsx",
    "content": "import { ConvertToIcon } from '@loopring-web/common-resources'\nimport { MobileDateTimePicker } from '@mui/lab'\nimport { TextField, Box } from '@mui/material'\nimport styled from '@emotion/styled'\nimport moment from 'moment'\nimport { useTranslation } from 'react-i18next'\n\nconst StyledDateTimeRangePicker = styled(Box)`\n  background-color: var(--field-opacity);\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n\n  .MuiOutlinedInput-root {\n    background-color: transparent !important;\n    height: var(--input-height-large);\n  }\n`\n\ntype DateTimeRangePickerProps = {\n  startValue: moment.Moment | null\n  startMinDateTime?: moment.Moment\n  startMaxDateTime?: moment.Moment\n  onStartChange?: (m: moment.Moment | null) => void\n  onStartOpen?: () => void\n\n  endValue: moment.Moment | null\n  endMinDateTime?: moment.Moment\n  endMaxDateTime?: moment.Moment\n  onEndChange?: (m: moment.Moment | null) => void\n  onEndOpen?: () => void\n  customeEndInputPlaceHolder?: string\n}\n\nexport const DateTimeRangePicker = (props: DateTimeRangePickerProps) => {\n  const {\n    startValue,\n    startMinDateTime,\n    startMaxDateTime,\n    onStartChange,\n    onStartOpen,\n\n    endValue,\n    endMinDateTime,\n    endMaxDateTime,\n    onEndChange,\n    onEndOpen,\n\n    customeEndInputPlaceHolder,\n  } = props\n  const { t } = useTranslation()\n  return (\n    <StyledDateTimeRangePicker>\n      <MobileDateTimePicker\n        onOpen={onStartOpen}\n        value={startValue}\n        onChange={onStartChange ?? (() => {})}\n        minDateTime={startMinDateTime}\n        maxDateTime={startMaxDateTime}\n        renderInput={(params) => (\n          <TextField placeholder={t('labelBlindBoxStartTime')} {...params} />\n        )}\n      />\n      <ConvertToIcon fontSize={'large'} htmlColor={'var(--color-text-third)'} />\n      <MobileDateTimePicker\n        onOpen={onEndOpen}\n        value={endValue}\n        onChange={onEndChange ?? (() => {})}\n        minDateTime={endMinDateTime}\n        maxDateTime={endMaxDateTime}\n        renderInput={(params) => (\n          <TextField\n            placeholder={customeEndInputPlaceHolder ?? t('labelBlindBoxEndTime')}\n            {...params}\n          />\n        )}\n      />\n    </StyledDateTimeRangePicker>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/footer/index.tsx",
    "content": "import styled from '@emotion/styled'\nimport { Box, Container, Link, List, Typography } from '@mui/material'\nimport React from 'react'\nimport {\n  DiscordIcon,\n  FooterInterface,\n  LoopringIcon,\n  MediumIcon,\n  TwitterIcon,\n  YoutubeIcon,\n} from '@loopring-web/common-resources'\n\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport { useTheme } from '@emotion/react'\nimport { useSettings } from '../../stores'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nconst LinkStyle = styled(Link)`\n  color: var(--color-text-secondary);\n  line-height: 20px;\n  font-size: 12px;\n\n  &:hover {\n    color: var(--color-text-hover);\n  }\n` as typeof Link\nconst FooterDiv = styled(Box)`\n  background: var(--color-global-bg);\n`\n\nexport const Footer = withTranslation(['layout'])(\n  ({\n    t,\n    linkListMap,\n    mediaList,\n    isLandingPage,\n    isBeta = false,\n  }: {\n    isLandingPage: boolean\n    linkListMap: { [key: string]: FooterInterface[] }\n    mediaList: FooterInterface[]\n    isBeta: boolean\n  } & WithTranslation) => {\n    const { mode } = useTheme()\n    const { isMobile } = useSettings()\n    React.useLayoutEffect(() => {\n      function updateSize() {}\n\n      window.addEventListener('resize', updateSize)\n      updateSize()\n      return () => window.removeEventListener('resize', updateSize)\n    }, [])\n    const linkListMapRender = React.useMemo(() => {\n      return Reflect.ownKeys(linkListMap).map((key) => {\n        return (\n          <Box\n            key={key.toString()}\n            minWidth={120}\n            display={'flex'}\n            flexDirection={'column'}\n            justifyContent={'center'} /* padding={3} */\n          >\n            <Typography\n              color={'var(--color-text-third)'}\n              sx={{ mt: 4, mb: 2 }}\n              variant='body2'\n              component='div'\n            >\n              {t('labelFooter' + key.toString())}\n            </Typography>\n            <Box\n              display={'flex'}\n              flexDirection={'column'}\n              height={'100%'}\n              justifyContent={'flex-start'}\n            >\n              {linkListMap[key.toString()].map((item: any) => {\n                return (\n                  <LinkStyle\n                    key={item.linkName}\n                    target='_blank'\n                    rel='noopener noreferrer'\n                    href={item.linkHref}\n                  >\n                    {t('label' + 'key' + item.linkName)}\n                  </LinkStyle>\n                )\n              })}\n            </Box>\n          </Box>\n        )\n      })\n    }, [linkListMap])\n\n    const medias = React.useMemo(() => {\n      const renderIcon = (name: string) => {\n        switch (name) {\n          case 'Discord':\n            return <DiscordIcon fontSize={'large'} htmlColor={'var(--color-text-third)'} />\n          case 'Twitter':\n            return <TwitterIcon fontSize={'large'} htmlColor={'var(--color-text-third)'} />\n          case 'Youtube':\n            return <YoutubeIcon fontSize={'large'} htmlColor={'var(--color-text-third)'} />\n          case 'Medium':\n            return <MediumIcon fontSize={'large'} htmlColor={'var(--color-text-third)'} />\n        }\n      }\n      return (\n        <List\n          style={{\n            display: 'flex',\n            alignItems: 'flex-start',\n            paddingTop: 0,\n            paddingBottom: 0,\n          }}\n        >\n          {mediaList.map((o, index) => (\n            <Typography paddingRight={2} key={`${o.linkName}-${index}`}>\n              <LinkStyle\n                fontSize={28}\n                display={'inline-block'}\n                width={28}\n                href={o.linkHref}\n                target='_blank'\n                rel='noopener noreferrer'\n              >\n                {renderIcon(o.linkName)}\n              </LinkStyle>\n            </Typography>\n          ))}\n        </List>\n      )\n    }, [mediaList])\n    const { isDevToggle, setIsDevToggle, defaultNetwork } = useSettings()\n\n    return (\n      <FooterDiv component={'footer'} fontSize={'body1'}>\n        {!!(isLandingPage && !isMobile) ? (\n          <Container>\n            <>\n              <Box\n                position={'relative'}\n                // height={size[ 1 ]}\n                flexDirection='row'\n                justifyContent='space-between'\n                alignItems='center'\n                width={'100%'}\n                paddingBottom={4}\n              >\n                <Box display={'flex'} justifyContent={'space-between'} alignItems={'flex-start'}>\n                  <Box\n                    marginTop={4}\n                    marginLeft={-3}\n                    minWidth={100}\n                    alignSelf={'flex-start'}\n                    justifySelf={'center'}\n                    display={'inline-flex'}\n                    alignItems={'center'}\n                  >\n                    <LoopringIcon\n                      htmlColor={'var(--color-text-third)'}\n                      style={{ height: '40px', width: '120px' }}\n                    />\n                  </Box>\n                  {linkListMapRender}\n                  <Box display={'flex'} flexDirection={'column'} width={168}>\n                    <Typography\n                      color='var(--color-text-third)'\n                      variant='body2'\n                      component='p'\n                      sx={{ mt: 4, mb: 2 }}\n                    >\n                      Follow us\n                    </Typography>\n                    <Box>{medias}</Box>\n                  </Box>\n                </Box>\n              </Box>\n              <Typography\n                fontSize={12}\n                component={'p'}\n                textAlign={'center'}\n                paddingBottom={2}\n                color={'var(--color-text-third)'}\n              >\n                {t('labelCopyRight', { year: new Date().getFullYear() })}\n              </Typography>\n            </>\n          </Container>\n        ) : (\n          <Box\n            height={isMobile ? 'auto' : 48}\n            display={'flex'}\n            justifyContent={'center'}\n            alignItems={'center'}\n            width={'100%'}\n            style={{\n              backgroundColor:\n                mode === 'light' ? 'rgba(59, 90, 244, 0.05)' : 'rgba(255, 255, 255, 0.05)',\n            }}\n          >\n            <Container>\n              <Box\n                display={'flex'}\n                flex={1}\n                width={'100%'}\n                justifyContent={'space-between'}\n                alignItems={'center'}\n                flexDirection={isMobile ? 'column' : 'row'}\n              >\n                <Typography\n                  fontSize={12}\n                  component={'span'}\n                  color={\n                    isBeta\n                      ? isDevToggle && defaultNetwork !== sdk.ChainId.MAINNET\n                        ? 'var(--color-star)'\n                        : 'var(--color-warning)'\n                      : 'var(--color-text-third)'\n                  }\n                  paddingLeft={2}\n                  onClick={() => {\n                    if (isBeta && defaultNetwork !== sdk.ChainId.MAINNET) {\n                      setIsDevToggle(!isDevToggle)\n                      window.location.reload()\n                    }\n                  }}\n                  paddingTop={isMobile ? 2 : 0}\n                >\n                  {isBeta\n                    ? t('labelCopyRightBeta')\n                    : t('labelCopyRight', { year: new Date().getFullYear() })}\n                </Typography>\n                <Box paddingY={isMobile ? 2 : 0}>{medias}</Box>\n              </Box>\n            </Container>\n          </Box>\n        )}\n      </FooterDiv>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/header/Header.tsx",
    "content": "import styled from '@emotion/styled'\nimport {\n  AppBar,\n  Box,\n  ClickAwayListener,\n  Container,\n  Divider,\n  IconButton,\n  Slide,\n  SwipeableDrawer,\n  Toolbar,\n  Typography,\n  useScrollTrigger,\n} from '@mui/material'\nimport { Link as RouterLink, useHistory, useLocation, useRouteMatch } from 'react-router-dom'\nimport { useTranslation, WithTranslation, withTranslation } from 'react-i18next'\nimport { HeaderMenuSub, HeadMenuItem, Layer2Item, PopoverPure, TabItemPlus } from '../basic-lib'\nimport { HeaderProps, HeaderToolBarInterface } from './Interface'\nimport {\n  ButtonComponentsMap,\n  CloseIcon,\n  HeaderMenuItemInterface,\n  headerMenuLandingData,\n  HeaderMenuTabStatus,\n  hexToRGB,\n  L1L2_NAME_DEFINED,\n  LoopringLogoIcon,\n  MapChainId,\n  MenuIcon,\n  RouterMainKey,\n  SoursURL,\n  subMenuLayer2,\n} from '@loopring-web/common-resources'\nimport {\n  BtnDownload,\n  BtnNotification,\n  BtnSetting,\n  BtnSettingMobile,\n  ColorSwitch,\n  ProfileMenu,\n  WalletConnectBtn,\n  WalletConnectL1Btn,\n} from './toolbar'\nimport React, { useState } from 'react'\nimport { bindPopper } from 'material-ui-popup-state/es'\nimport { bindTrigger, usePopupState } from 'material-ui-popup-state/hooks'\nimport { useTheme } from '@emotion/react'\nimport _ from 'lodash'\nimport { useSettings } from '../../stores'\nimport KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp'\nimport KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'\n\nconst logoSVG = SoursURL + 'svg/logo.svg'\nconst ToolBarStyled = styled(Toolbar)`\n  && {\n    display: flex;\n    justify-content: space-between;\n    align-items: stretch;\n    padding: 0;\n  }\n`\nconst HeaderStyled = styled(AppBar)`\n  & {\n    z-index: 400;\n    box-shadow: none;\n    height: var(--header-height);\n    margin: 0 auto;\n    background-color: var(--color-box);\n    backdrop-filter: blur(4px);\n    box-sizing: border-box;\n    ${({ theme }) => theme.border.borderConfig({ d_W: 1, c_key: 'blur' })};\n    border-radius: 0;\n    border: 0;\n    &.item-scrolled.MuiAppBar-root.MuiAppBar-positionFixed {\n    }\n  }\n  &.scrollable {\n    background-color: initial;\n  }\n`\n\nconst LogoStyle = styled(Typography)`\n  display: flex;\n  align-items: center;\n  position: relative;\n\n  &:after {\n    content: 'beta';\n    position: absolute;\n    color: var(--color-logo);\n    display: block;\n    font-size: 1rem;\n    line-height: 0.8rem;\n    right: -24px;\n    top: 14px;\n    font-weight: 200;\n    opacity: 0;\n    box-shadow: 0 0 1px 0 var(--color-logo);\n    //border: 1px solid ;\n    border-radius: 2px;\n    padding: 3px 2px;\n  }\n\n  a.MuiButtonBase-root {\n    min-width: auto;\n    border-radius: 0;\n    text-indent: -999999em;\n    background: var(--color-primary);\n    background: var(--color-logo);\n    mask: url(${logoSVG}) space;\n    mask-size: contain;\n    mask-position: center;\n    width: 105px;\n    height: 40px;\n    margin-top: -10px;\n    color: transparent;\n\n    &:hover {\n      background-color: inherit;\n      background: var(--color-logo);\n    }\n  }\n` as typeof Typography\n\nexport const LoopringLogo = React.memo(() => {\n  return (\n    <LogoStyle variant='h6' component='h1'>\n      <IconButton\n        edge='start'\n        aria-label='menu'\n        component={RouterLink}\n        onClick={() => {\n          window.open('https://loopring.io/#', '_blank')\n        }}\n        replace={true}\n        color={'inherit'}\n      >\n        Loopring 路印 loopring protocol 3.6 The first Layer2 Decentralized trading Platform\n      </IconButton>\n    </LogoStyle>\n  )\n})\n\nconst ToolBarItem = ({\n  buttonComponent,\n  notification,\n  account,\n  chainId,\n  isLayer1Only = false,\n  ...props\n}: any) => {\n  const match = useRouteMatch('/:l1/:l2?')\n  const { isMobile } = useSettings()\n  const render = React.useMemo(() => {\n    switch (buttonComponent) {\n      case ButtonComponentsMap.ProfileMenu:\n        // @ts-ignore\n        return <ProfileMenu rounter={match?.params[LAYERMAP['2']] as any} {...props} />\n      case ButtonComponentsMap.Notification:\n        return (\n          <BtnNotification\n            {...props}\n            notification={notification}\n            account={account}\n            chainId={chainId}\n          />\n        )\n      case ButtonComponentsMap.Setting:\n        return isMobile ? <BtnSettingMobile {...props} /> : <BtnSetting {...props} />\n      case ButtonComponentsMap.Download:\n        return <BtnDownload {...props} />\n      case ButtonComponentsMap.ColorSwitch:\n        return <ColorSwitch {...props} />\n      case ButtonComponentsMap.WalletConnect:\n        return isLayer1Only ? (\n          <WalletConnectL1Btn {...props} />\n        ) : (\n          <WalletConnectBtn {...props} accountState={{ account }} />\n        )\n      default:\n        return undefined\n    }\n  }, [buttonComponent, match?.params, props, notification, account])\n  return <TabItemPlus sx={{ display: props.hidden ? 'none' : '' }}>{render}</TabItemPlus>\n}\n\nexport const HideOnScroll = React.forwardRef(({ children, window, ...rest }: any, ref) => {\n  const trigger = useScrollTrigger({\n    target: window ? window() : undefined,\n  })\n\n  return (\n    <Slide {...rest} appear={false} adirection='down' forwardedRef={ref} in={!trigger}>\n      {children}\n    </Slide>\n  )\n})\n\nconst NodeMenuItem = React.memo(\n  ({ label, router, layer, child, handleListKeyDown, ...rest }: HeaderMenuItemInterface & any) => {\n    const { defaultNetwork } = useSettings()\n    const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n    return (\n      <>\n        {layer >= 1 ? (\n          <Layer2Item {...{ ...rest, label, router, child, layer }} />\n        ) : (\n          <Typography\n            variant={'body1'}\n            key={label.id}\n            color={'inherit'}\n            onClick={handleListKeyDown}\n          >\n            {rest.t(label.i18nKey, {\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n              l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n            })}\n          </Typography>\n        )}\n      </>\n    )\n  },\n)\nexport const LAYERMAP = {\n  '1': 'l1',\n  '2': 'l2',\n}\n\ninterface MobileDrawerProps {\n  linkList: {\n    title: string\n    des: string\n    link: string\n    logo?: string\n    onClick: () => void\n    imgMarginRight?: number\n  }[]\n  open: boolean\n  onClose: () => void\n  showSetting: boolean\n  showColorSwitch: boolean\n}\n\nconst mobileDrawerBGColorList = ['#E1E8FF', '#D5FFF0', '#FFE9D9', '#E5E8EE', '#E5E8EE']\n\nconst MobileDrawer = (props: MobileDrawerProps) => {\n  const { linkList, showColorSwitch, showSetting } = props\n  const { t } = useTranslation()\n  const theme = useTheme()\n  return (\n    <SwipeableDrawer PaperProps={{sx: {height: '100%'}}} onOpen={() => {}} open={props.open} anchor='top' onClose={() => {\n      props.onClose()  \n    }}>\n      <Box py={8} px={6} height={'100%'} bgcolor={'var(--color-global-bg)'}>\n        <Box\n          display={'flex'}\n          height={'28px'}\n          justifyContent={'space-between'}\n          alignItems={'center'}\n        >\n          <LoopringLogoIcon\n            fontSize={'large'}\n            style={{ height: 28, width: 28 }}\n            color={'primary'}\n          />\n          <CloseIcon\n            className='custom-size'\n            sx={{\n              fontSize: '24px',\n              cursor: 'pointer',\n            }}\n            onClick={props.onClose}\n          />\n        </Box>\n        <Box my={5} height={'calc(100% - 96px)'} sx={{ overflowY: 'scroll' }}>\n          {linkList.map((item, index) => {\n            return (\n              <Box\n                height={'120px'}\n                borderRadius={'20px'}\n                key={item.title}\n                display={'flex'}\n                flexDirection={'row'}\n                alignItems={'center'}\n                mb={3}\n                px={5}\n                onClick={item.onClick}\n                bgcolor={hexToRGB(\n                  mobileDrawerBGColorList[index % mobileDrawerBGColorList.length],\n                  theme.mode === 'dark' ? 0.2 : 1,\n                )}\n              >\n                <Box width={'100%'} display={'flex'} justifyContent={'space-between'}>\n                  <Box>\n                    <Typography>{item.title}</Typography>\n                    <Typography mt={3} variant={'body2'} color={'var(--color-text-secondary)'}>\n                      {item.des}\n                    </Typography>\n                  </Box>\n                  <Box\n                    mr={item.imgMarginRight ?? 0}\n                    component={'img'}\n                    src={item.logo}\n                    alt={item.title}\n                    height={'44px'}\n                  />\n                </Box>\n              </Box>\n            )\n          })}\n        </Box>\n        <Box\n          display={'flex'}\n          height={'28px'}\n          justifyContent={'space-between'}\n          alignItems={'center'}\n        >\n          {/* <Box /> */}\n          <Box>\n            {showSetting && <ToolBarItem t={t} buttonComponent={ButtonComponentsMap.Setting} />}\n          </Box>\n          <Box>\n            {showColorSwitch && <ToolBarItem buttonComponent={ButtonComponentsMap.ColorSwitch} />}\n          </Box>\n        </Box>\n      </Box>\n    </SwipeableDrawer>\n  )\n}\n\ninterface NestedMobileDrawerProps {\n  linkList: {\n    title: string\n    // des: string,\n    link: string\n    // logo: string,\n    onClick?: () => void\n    id: string\n    subLinkList?: {\n      title: string\n      des: string\n      link: string\n      LogoElement: any\n      onClick: () => void\n      highlighted: boolean\n    }[]\n    highlighted: boolean\n  }[]\n  open: boolean\n  onClose: () => void\n  showSetting: boolean\n  showColorSwitch: boolean\n}\n\nconst NestedMobileDrawer = (props: NestedMobileDrawerProps) => {\n  const { linkList, showColorSwitch, showSetting} = props\n  const { t } = useTranslation()\n  const [selectedItem, setSelectedItem] = useState<string | undefined>(undefined)\n\n  return (\n    <SwipeableDrawer PaperProps={{sx: {height: '100%'}}}  onOpen={() => {}} open={props.open} anchor='top' onClose={props.onClose}>\n      <Box py={8} px={6} height={'100%'} bgcolor={'var(--color-global-bg)'}>\n        <Box\n          display={'flex'}\n          height={'28px'}\n          justifyContent={'space-between'}\n          alignItems={'center'}\n        >\n          <LoopringLogoIcon\n            fontSize={'large'}\n            style={{ height: 28, width: 28 }}\n            color={'primary'}\n          />\n          <CloseIcon\n            className='custom-size'\n            sx={{\n              fontSize: '24px',\n              cursor: 'pointer',\n            }}\n            onClick={props.onClose}\n          />\n        </Box>\n        <Box my={9} height={'calc(100% - 112px)'} sx={{ overflowY: 'scroll' }}>\n          {linkList.map((item) => {\n            const selected = selectedItem === item.id\n            return (\n              <Box\n                key={item.title}\n                display={'flex'}\n                mb={4}\n                px={4}\n                onClick={item.onClick}\n                flexDirection={'column'}\n              >\n                <Box\n                  display={'flex'}\n                  alignItems={'center'}\n                  onClick={() => {\n                    if (selectedItem === item.id) {\n                      setSelectedItem(undefined)\n                    } else {\n                      setSelectedItem(item.id)\n                    }\n                  }}\n                >\n                  <Typography color={item.highlighted ? 'var(--color-primary)' : 'var(--color-text-primary)'} fontSize={'16px'} mr={1}>\n                    {item.title}\n                  </Typography>\n                  {item.subLinkList &&\n                    (selected ? (\n                      <KeyboardArrowUpIcon\n                        className='custom-size'\n                        sx={{ color: 'var(--color-text-primary)', fontSize: '16px' }}\n                      />\n                    ) : (\n                      <KeyboardArrowDownIcon\n                        className='custom-size'\n                        sx={{ color: 'var(--color-text-primary)', fontSize: '16px' }}\n                      />\n                    ))}\n                </Box>\n\n                {item.subLinkList && selected && (\n                  <Box mt={4}>\n                    {item.subLinkList.map((subItem) => {\n                      const LogoElement = subItem.LogoElement\n                      return (\n                        <Box\n                          mb={4}\n                          key={subItem.title}\n                          ml={4}\n                          height={'52px'}\n                          display={'flex'}\n                          alignItems={'center'}\n                          onClick={subItem.onClick}\n                        >\n                          <LogoElement\n                            className='custom-size'\n                            style={{\n                              width: '24px',\n                              height: '24px',\n                              color:\n                                subItem.highlighted\n                                  ? 'var(--color-primary)'\n                                  : 'var(--color-text-primary)',\n                            }}\n                          />\n                          {/* <Box component={'img'} src={subItem.logo} width={'24px'} height={'24px'} /> */}\n                          <Box ml={4}>\n                            <Typography color={subItem.highlighted ? 'var(--color-primary)' : 'var(--color-text-primary)'}>{subItem.title}</Typography>\n                            <Typography variant='body2' color={subItem.highlighted ? 'var(--color-primary)' : 'var(--color-text-secondary)'}>\n                              {subItem.des}\n                            </Typography>\n                          </Box>\n                        </Box>\n                      )\n                    })}\n                  </Box>\n                )}\n              </Box>\n            )\n          })}\n        </Box>\n        <Box\n          display={'flex'}\n          height={'28px'}\n          justifyContent={'space-between'}\n          alignItems={'center'}\n        >\n          <Box display={'flex'}>\n            {showSetting && (\n              <>\n                <Box mr={2}>\n                  <ToolBarItem  t={t} buttonComponent={ButtonComponentsMap.Setting} />\n                </Box>\n                <Box mr={2}>\n                  <ToolBarItem t={t} buttonComponent={ButtonComponentsMap.Notification} />\n                </Box>\n                <Box mr={2}>\n                  <ToolBarItem t={t} buttonComponent={ButtonComponentsMap.Download} />\n                </Box>\n              </>\n            )}\n          </Box>\n          <Box>\n            {showColorSwitch && <ToolBarItem buttonComponent={ButtonComponentsMap.ColorSwitch} />}\n          </Box>\n        </Box>\n      </Box>\n    </SwipeableDrawer>\n  )\n}\n\nexport const Header = withTranslation(['layout', 'landPage', 'common'], { withRef: true })(\n  React.forwardRef(\n    <R extends HeaderToolBarInterface>(\n      {\n        headerMenuData,\n        headerToolBarData,\n        notification,\n        allowTrade,\n        selected,\n        account,\n        chainId,\n        isWrap = true,\n        landBtn,\n        isLandPage = false,\n        isMobile = false,\n        toolBarMap = ButtonComponentsMap,\n        i18n,\n        t,\n        transparent,\n        application,\n        ...rest\n      }: HeaderProps<R> & WithTranslation,\n      ref: React.ForwardedRef<any>,\n    ) => {\n      const history = useHistory()\n      const theme = useTheme()\n      const location = useLocation()\n      const match = useRouteMatch('/:l1/:l2?/:pair?')\n      const getMenuButtons = React.useMemo(() => {\n        return Reflect.ownKeys(headerToolBarData ?? {}).map((item, index) => {\n          return (\n            <ToolBarItem\n              {...{\n                ...headerToolBarData[item],\n                account,\n                chainId,\n                notification,\n                ButtonComponentsMap: toolBarMap,\n                t,\n                i18n,\n                ...rest,\n              }}\n              key={index}\n            />\n          )\n        })\n      }, [account, isMobile, notification, headerToolBarData])\n\n      const getDrawerChoices: any = React.useCallback(\n        ({\n          menuList,\n          layer = 0,\n          // onClose,\n          handleListKeyDown,\n          ...rest\n        }: {\n          menuList: HeaderMenuItemInterface[]\n          layer?: number\n          // onClose?: () => void;\n          handleListKeyDown?: any\n        } & WithTranslation) => {\n          let _obj = {}\n          if (menuList instanceof Array) {\n            _obj[0] = menuList\n          } else {\n            _obj = menuList\n          }\n          return Reflect.ownKeys(_obj).map((key, index) => {\n            return (\n              <Box\n                key={key.toString() + '-' + index}\n                display={'flex'}\n                flexDirection={isMobile || layer > 0 ? 'column' : 'row'}\n              >\n                {!!_obj[key].length &&\n                  _obj[key].reduce(\n                    (prev: JSX.Element[], props: HeaderMenuItemInterface, l2Index: number) => {\n                      const { label, child, status } = props\n\n                      if (status === HeaderMenuTabStatus.hidden) {\n                        return prev\n                      } else {\n                        if (child) {\n                          return [\n                            ...prev,\n                            memoized({\n                              ...props,\n                              layer,\n                              divider: index + 1 !== _obj[key].length,\n                              handleListKeyDown,\n                              ...rest,\n                            }),\n                          ]\n                        }\n\n                        let selectedFlag: boolean | undefined = undefined\n                        if (application === 'web-earn') {\n                          if (label.id === 'portal') {\n                            selectedFlag = match?.params['l1'] === 'portal'\n                          } else if (label.id === 'L2Assets') {\n                            selectedFlag = match?.params['l1'] === 'l2assets'\n                          } else if (label.id === 'dual') {\n                            selectedFlag =\n                              match?.params['l1'] === 'invest' && match?.params['l2'] === 'dual'\n                          } else if (label.id === 'btrade') {\n                            selectedFlag =\n                              match?.params['l1'] === 'trade' && match?.params['l2'] === 'btrade'\n                          } else if (label.id === 'taikoFarming') {\n                            selectedFlag = match?.params['l1'] === 'taiko-farming'\n                          } else {\n                            selectedFlag = false\n                          }\n                        } else {\n                          selectedFlag =\n                            match?.params[LAYERMAP[layer + 1]] &&\n                            new RegExp(label.id?.toLowerCase(), 'ig').test(\n                              match?.params[LAYERMAP[layer + 1]],\n                            )\n                        }\n\n                        return [\n                          ...prev,\n                          <HeadMenuItem\n                            selected={selectedFlag}\n                            {...{\n                              ...props,\n                              allowTrade,\n                              layer,\n                              children: (\n                                <NodeMenuItem\n                                  {...{\n                                    ...props,\n                                    layer,\n                                    child,\n                                    handleListKeyDown,\n                                    ...rest,\n                                  }}\n                                />\n                              ),\n                              style: { textDecoration: 'none' },\n                              key: key.toString() + '-' + layer + l2Index,\n                            }}\n                          />,\n                        ]\n                      }\n                    },\n                    [] as JSX.Element[],\n                  )}\n\n                <Box marginX={2}>{Reflect.ownKeys(_obj).length !== index + 1 && <Divider />}</Box>\n              </Box>\n            )\n          })\n        },\n        [isMobile, selected, account?.readyState, allowTrade],\n      )\n\n      const memoized: any = React.useCallback(\n        ({\n          label,\n          router,\n          child,\n          layer,\n          ref,\n          handleListKeyDown: _handleListKeyDown,\n          ...rest\n        }: any) => (\n          <HeaderMenuSub\n            key={layer + '_' + label.id}\n            {...{\n              ...rest,\n              label,\n              router,\n              allowTrade,\n              child,\n              layer,\n              anchorOrigin: isMobile\n                ? {\n                    vertical: 'right',\n                    horizontal: 'right',\n                  }\n                : { vertical: 'bottom', horizontal: 'left' },\n              selected:\n                match?.params[LAYERMAP[layer + 1]] &&\n                new RegExp(`^${label.id?.toLowerCase()}`, 'ig').test(\n                  match?.params[LAYERMAP[layer + 1]],\n                ),\n              //match?.params.item,\n              //   new RegExp(label.id, \"ig\").test(\n              //   selected.split(\"/\")[1] ? selected.split(\"/\")[1] : selected\n              // ),\n              renderList: ({ handleListKeyDown }: { handleListKeyDown: ({ ...rest }) => any }) => {\n                return getDrawerChoices({\n                  menuList: child,\n                  layer: layer + 1,\n                  handleListKeyDown: () => {\n                    if (_handleListKeyDown) {\n                      _handleListKeyDown()\n                    }\n                    if (handleListKeyDown) {\n                      handleListKeyDown({ ...rest })\n                    }\n                  },\n                  ...rest,\n                })\n              },\n            }}\n          />\n        ),\n        [allowTrade, getDrawerChoices, isMobile, match?.params],\n      )\n\n      // const handleThemeClick = React.useCallback(() => {\n      //   setTheme(themeMode === \"light\" ? ThemeType.dark : ThemeType.light);\n      // }, [themeMode, setTheme]);\n\n      const isMaintaining = false\n      const displayDesktop = React.useMemo(() => {\n        return (\n          <ToolBarStyled>\n            <Box\n              display='flex'\n              alignContent='center'\n              justifyContent={'flex-start'}\n              alignItems={'stretch'}\n              flexDirection={'row'} //!isMobile ? \"row\" : \"column\"}\n            >\n              <LoopringLogo />\n              {!isLandPage &&\n                getDrawerChoices({\n                  menuList: headerMenuData,\n                  i18n,\n                  t,\n                  ...rest,\n                })}\n            </Box>\n            {isLandPage && (\n              <Box mr={'2.5%'}>\n                {getDrawerChoices({\n                  menuList: headerMenuLandingData,\n                  i18n,\n                  t,\n                  ...rest,\n                })}\n              </Box>\n            )}\n            <Box\n              component={'ul'}\n              display='flex'\n              alignItems='center'\n              justifyContent={'flex-end'}\n              color={'textColorSecondary'}\n            >\n              {getMenuButtons}\n              {!!isLandPage && landBtn ? landBtn : <></>}\n            </Box>\n          </ToolBarStyled>\n        )\n      }, [\n        isLandPage,\n        getDrawerChoices,\n        headerMenuData,\n        i18n,\n        t,\n        rest,\n        getMenuButtons,\n        isMaintaining,\n        history,\n      ])\n      const popupState = usePopupState({\n        variant: 'popover',\n        popupId: 'mobile',\n      })\n      const [mobileMenuOpen, setMobileMenuOpen] = useState(false)\n      const { defaultNetwork } = useSettings()\n      const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n      const displayMobile = React.useMemo(() => {\n        const _headerMenuData: HeaderMenuItemInterface[] = (headerMenuData ?? []).reduce(\n          (prev, _item) => {\n            const item = _.cloneDeep(_item)\n            if (item.label.id === RouterMainKey.l2assets) {\n              item.child = { ...subMenuLayer2 }\n            }\n            return [...prev, item]\n          },\n          [] as HeaderMenuItemInterface[],\n        )\n        // @ts-ignore\n        const pair = match?.params?.pair ?? 'LRC-ETH'\n        return (\n          <ToolBarStyled>\n            <Box\n              display='flex'\n              alignContent='center'\n              justifyContent={'flex-start'}\n              alignItems={'stretch'}\n              flexDirection={'row'} //!isMobile ? \"row\" : \"column\"}\n            >\n              <Typography onClick={() => window.open('https://loopring.io/#', '_blank')} display={'inline-flex'} alignItems={'center'}>\n                <LoopringLogoIcon\n                  fontSize={'large'}\n                  style={{ height: 28, width: 28 }}\n                  color={'primary'}\n                />\n              </Typography>\n            </Box>\n            <Box display={'flex'} alignItems={'center'}>\n              {isLandPage && headerMenuLandingData[0] ? (\n                <>\n                  {getMenuButtons}\n                  {landBtn ? landBtn : <></>}\n                  <ClickAwayListener\n                    onClickAway={() => {\n                      popupState.close()\n                    }}\n                  >\n                    <Box\n                      display='flex'\n                      alignContent='center'\n                      justifyContent={'flex-start'}\n                      alignItems={'stretch'}\n                      flexDirection={'row'} //!isMobile ? \"row\" : \"column\"}\n                    >\n                      <Typography\n                        display={'inline-flex'}\n                        alignItems={'center'}\n                        component={'div'}\n                        onClick={() => {\n                          setMobileMenuOpen(true)\n                        }}\n                      >\n                        <MenuIcon\n                          // fontSize={\"large\"}\n                          style={{ height: 28, width: 28 }}\n                          \n                        />\n                      </Typography>\n                      <MobileDrawer\n                        linkList={headerMenuLandingData.map((item) => {\n                          return {\n                            title: t(item.label.i18nKey, {\n                              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                              l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                            }),\n                            des: item.label.description ? t(item.label.description) : '',\n                            link: item.router?.path ?? '',\n                            logo: theme.mode === 'dark' ? item.logo?.dark : item.logo?.light,\n                            onClick: () => {\n                              window.open(item.router?.path ?? '', '_blank')\n                            },\n                          }\n                        })}\n                        open={mobileMenuOpen}\n                        onClose={() => {\n                          setMobileMenuOpen(false)\n                        }}\n\n                        showColorSwitch\n                      />\n                    </Box>\n                  </ClickAwayListener>\n                </>\n              ) : (\n                <>\n                  <Box\n                    component={'ul'}\n                    display='flex'\n                    alignItems='center'\n                    justifyContent={'flex-end'}\n                    color={'textColorSecondary'}\n                    marginRight={1}\n                  >\n                    {getMenuButtons}\n                  </Box>\n                  <ClickAwayListener\n                    onClickAway={() => {\n                      popupState.close()\n                    }}\n                  >\n                    <Box\n                      display='flex'\n                      alignContent='center'\n                      justifyContent={'flex-start'}\n                      alignItems={'stretch'}\n                      flexDirection={'row'} //!isMobile ? \"row\" : \"column\"}\n                    >\n                      <Typography\n                        display={'inline-flex'}\n                        alignItems={'center'}\n                        onClick={() => {\n                          setMobileMenuOpen(true)\n                        }}\n                      >\n                        <MenuIcon\n                          // fontSize={\"large\"}\n                          style={{ height: 28, width: 28 }}\n                          // color={\"primary\"}\n                        />\n                      </Typography>\n\n                      {application === 'webapp' ? (\n                        <NestedMobileDrawer\n                          linkList={_headerMenuData.map((item) => {\n                            const childList = Array.isArray(item.child)\n                              ? item.child\n                              : _.values(item.child).flat()\n                            const hasChildren = childList && childList.length > 0\n\n                            const highlightedMap = new Map([\n                              [ '/pro', '/pro'],\n                              [ '/l2assets/assets/Tokens', '/l2assets'],\n                              [ '/markets', '/markets'],\n                            ])\n                            const highlighted = !hasChildren && highlightedMap.get(history.location.pathname) === item.router?.path\n                            return {\n                              title: t(item.label.i18nKey, {\n                                loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                                l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                              }),\n                              id: item.label.id,\n                              des: item.label.description ? t(item.label.description) : '',\n                              link: item.router?.path ?? '',\n                              logo: theme.mode === 'dark' ? item.logo?.dark : item.logo?.light,\n                              onClick: () => {\n                                if (!hasChildren) {\n                                  history.push(item.router?.path ?? '')\n                                  setMobileMenuOpen(false)\n                                }\n                              },\n                              highlighted,\n                              subLinkList: hasChildren\n                                ? childList.map((subItem) => {\n                                    \n                                    if (\n                                      (history.location.pathname.startsWith('/trade/lite') && subItem.label.id === 'lite') \n                                      || (history.location.pathname.startsWith('/trade/pro') && subItem.label.id === 'pro') \n                                      || (history.location.pathname.startsWith('/trade/btrade') && subItem.label.id === 'btrade') \n                                      || (history.location.pathname.startsWith('/invest/dual') && subItem.label.id === 'dual') \n                                    ) {\n                                      var highlighted = true\n                                    } else {\n                                      highlighted = history.location.pathname === subItem.router?.path\n                                    }\n                                    return {\n                                      title: t(subItem.label.i18nKey),\n                                      des: subItem.label.description\n                                        ? t(subItem.label.description)\n                                        : '',\n                                      link: subItem.router?.path ?? '',\n                                      LogoElement: subItem.label.icon,\n                                      onClick: () => {\n                                        history.push(subItem.router?.path ?? '')\n                                        setMobileMenuOpen(false)\n                                      },\n                                      highlighted\n                                    }\n                                  })\n                                : undefined,\n                            }\n                          })}\n                          open={mobileMenuOpen}\n                          onClose={() => {\n                            setMobileMenuOpen(false)\n                          }}\n                          showSetting={true}\n                          showColorSwitch={false}\n                        />\n                      ) : (\n                        <MobileDrawer\n                          linkList={_headerMenuData.map((item) => {\n                            return {\n                              title: t(item.label.i18nKey),\n                              des: item.label.description ? t(item.label.description) : '',\n                              link: item.router?.path ?? '',\n                              logo: theme.mode === 'dark' ? item.logo?.dark : item.logo?.light,\n                              onClick: () => {\n                                history.push(item.router?.path ?? '')\n                                setMobileMenuOpen(false)\n                              },\n                              imgMarginRight: item.label.id === 'dual' ? -2 : 0,\n                            }\n                          })}\n                          open={mobileMenuOpen}\n                          onClose={() => {\n                            setMobileMenuOpen(false)\n                          }}\n                          showSetting={true}\n                          showColorSwitch={false}\n                        />\n                      )}\n                    </Box>\n                  </ClickAwayListener>\n                </>\n              )}\n            </Box>\n          </ToolBarStyled>\n        )\n      }, [\n        headerMenuData,\n        match?.params,\n        isLandPage,\n        location.pathname,\n        rest,\n        t,\n        getMenuButtons,\n        headerToolBarData,\n        i18n,\n        isMaintaining,\n        popupState,\n        mobileMenuOpen,\n        getDrawerChoices,\n        history,\n      ])\n\n      const paddingStyle = {\n        paddingTop: 0,\n        paddingRight: isLandPage ? theme.unit : theme.unit * 3,\n        paddingBottom: 0,\n        paddingLeft: isLandPage ? theme.unit : theme.unit * 3,\n      }\n\n      return (\n        <HeaderStyled\n          sx={{ '&&&': { background: transparent ? 'transparent' : '' } }}\n          elevation={4}\n          ref={ref}\n          className={`${rest?.className}`}\n        >\n          {isWrap ? (\n            <Container style={paddingStyle} className={'wrap'} maxWidth='lg'>\n              {isMobile ? displayMobile : displayDesktop}\n            </Container>\n          ) : (\n            <Box marginX={2}>{isMobile ? displayMobile : displayDesktop}</Box>\n          )}\n        </HeaderStyled>\n      )\n    },\n  ),\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/header/Interface.ts",
    "content": "import {\n  Account,\n  ButtonComponentsMap,\n  HeaderMenuItemInterface,\n  NOTIFICATIONHEADER,\n} from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nexport interface HeaderToolBarInterface {\n  buttonComponent: number\n  args?: any\n}\nexport interface HeaderProps<R, N = sdk.UserNotification> {\n  headerToolBarData: { [key in ButtonComponentsMap]: R }\n  headerMenuData: HeaderMenuItemInterface[]\n  notification?: NOTIFICATIONHEADER<N>\n  account?: Account\n  chainId: sdk.ChainId\n  allowTrade: {\n    register: { enable: boolean; reason?: string }\n    order: { enable: boolean; reason?: string }\n    joinAmm: { enable: boolean; reason?: string }\n    dAppTrade: { enable: boolean; reason?: string }\n    raw_data: { enable: boolean; reason?: string }\n  }\n  isMobile: boolean\n  isWrap?: boolean\n  selected: string\n  className?: string\n  isLandPage?: boolean\n  toolBarMap?: typeof ButtonComponentsMap\n  transparent?: boolean\n  landBtn?: JSX.Element\n  application: string\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/header/index.ts",
    "content": "export * from './Header'\nexport * from './Interface'\nexport * from './toolbar'\n"
  },
  {
    "path": "packages/component-lib/src/components/header/toolbar/Interface.ts",
    "content": "import React from 'react'\nimport { AccountFull } from '@loopring-web/common-resources'\n\nexport enum WalletNotificationStatus {\n  none = 'none',\n  error = 'error',\n  pending = 'pending',\n  success = 'success',\n}\n\nexport type WalletNotificationInterface = {\n  // status: keyof typeof WalletNotificationStatus\n  message: string\n  handleClick?: (event: React.MouseEvent) => void\n}\n\nexport type WalletConnectBtnProps = {\n  NetWorkItems: JSX.Element | (() => JSX.Element)\n  handleClick: (_e: React.MouseEvent) => void\n  handleClickUnlock: (_e: React.MouseEvent) => void\n  handleClickSignIn: (_e: React.MouseEvent) => void\n  accountState: AccountFull\n  isLayer1Only?: boolean\n  isShowOnUnConnect: boolean\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/header/toolbar/WalletConnect.tsx",
    "content": "import { WalletConnectBtnProps } from './Interface'\nimport { useTranslation } from 'react-i18next'\nimport React from 'react'\nimport {\n  AccountStatus,\n  ChainTests,\n  CircleIcon,\n  gatewayList,\n  getShortAddr,\n  LoadingIcon,\n  LockIcon,\n  myLog,\n  UnConnectIcon,\n  UnlockedIcon,\n} from '@loopring-web/common-resources'\nimport { Typography, Box } from '@mui/material'\nimport { Button, ButtonProps } from '../../basic-lib'\nimport { bindHover, usePopupState } from 'material-ui-popup-state/hooks'\nimport styled from '@emotion/styled'\nimport { useSettings } from '../../../stores'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { useSystem } from '@loopring-web/core'\nimport { useLocation } from 'react-router'\n\n// type ChainId = sdk.ChainId | ChainIdExtends;\nconst WalletConnectBtnStyled = styled(Button)`\n  text-transform: none;\n  min-width: 120px;\n  padding-left: 2px;\n  padding-right: 2px;\n\n  &.wallet-btn {\n    justify-content: center;\n  }\n\n  i {\n    padding-right: ${({ theme }) => theme.unit / 2}px;\n    display: flex;\n    justify-content: center;\n    align-content: space-between;\n\n    svg {\n      height: auto;\n      font-size: ${({ theme }) => theme.fontDefault.h5};\n    }\n  }\n\n  &.wrong-network {\n    background: var(--color-error);\n    color: var(--color-text-primary);\n  }\n`\n\nconst ProviderBox = styled(Box)<ButtonProps & { account?: any }>`\n  display: none;\n  background-image: none;\n  height: 100%;\n  width: 48px;\n  background-size: contain;\n  background-repeat: no-repeat;\n  background-position: center;\n  ${({ account }) => {\n    if (account && account.connectName) {\n      const item = gatewayList.find(({ key }) => key === account.connectName)\n      // connectName: keyof typeof ConnectProviders;\n      return item?.imgSrc\n        ? `\n         display: flex;\n         background-image:url(${item.imgSrc});\n        `\n        : ''\n    }\n  }};\n` as (props: ButtonProps & { account: any }) => JSX.Element\n\nexport const WalletConnectBtn = ({\n  accountState,\n  handleClick,\n  NetWorkItems,\n  handleClickUnlock,\n  handleClickSignIn\n}: WalletConnectBtnProps) => {\n  const { t, i18n } = useTranslation(['layout', 'common'])\n  const { isMobile, defaultNetwork } = useSettings()\n  const { exchangeInfo } = useSystem()\n  const location = useLocation()\n  const isTaikoFarmingButNotTaikoNet = location.pathname === '/taiko-farming' && ![sdk.ChainId.TAIKO, sdk.ChainId.TAIKOHEKLA].includes(defaultNetwork)\n\n  \n  const {label, btnClassname, icon, isLocked} = React.useMemo(() => {\n    const account = accountState?.account\n    var label: string | undefined\n    var btnClassname: string | undefined\n    var icon: JSX.Element | undefined\n    const isLocked = account.readyState === AccountStatus.LOCKED\n    if (account && isTaikoFarmingButNotTaikoNet) {\n      return {\n        btnClassname: 'wrong-network',\n        label: 'labelWrongNetwork',\n        icon: <UnConnectIcon style={{ width: 16, height: 16 }} />,\n        isLocked\n      }\n    } else if (account) {\n      const addressShort = account.accAddress ? getShortAddr(account?.accAddress) : undefined\n      if (addressShort) {\n        label = addressShort\n      }\n      switch (account.readyState) {\n        case AccountStatus.UN_CONNECT:\n          btnClassname = 'un-connect'\n          label = 'labelConnectWallet'\n          break\n        case AccountStatus.LOCKED:\n          btnClassname = 'locked'\n          icon = isMobile ? <CircleIcon fontSize={'large'} color={'error'} /> : <LockIcon color={'error'}  style={{ width: 16, height: 16 }} />\n          break\n        case AccountStatus.ACTIVATED:\n          btnClassname = 'unlocked'\n          icon = <UnlockedIcon stroke='var(--color-success)' sx={{marginLeft: 1, marginBottom: 0.1, marginRight: 0.5}} style={{ width: 16, height: 16 }} />\n          break\n        case AccountStatus.NO_ACCOUNT:\n          btnClassname = 'no-account'\n          icon = <CircleIcon fontSize={'large'} color={'error'} />\n          break\n        case AccountStatus.DEPOSITING:\n          btnClassname = 'depositing'\n          icon = <LoadingIcon color={'primary'} style={{ width: 18, height: 18 }} />\n          break\n        case AccountStatus.NOT_ACTIVE:\n          btnClassname = 'not-active'\n          icon = <CircleIcon fontSize={'large'} htmlColor={'var(--color-warning)'} />\n          break\n        case AccountStatus.ERROR_NETWORK:\n          btnClassname = 'wrong-network'\n          label = 'labelWrongNetwork'\n          icon = <UnConnectIcon style={{ width: 16, height: 16 }} />\n          break\n        default:\n      }\n    } else {\n      label = 'labelConnectWallet'\n    }\n    return {\n      label: label ?? '',\n      btnClassname,\n      icon,\n      isLocked\n    }\n  }, [accountState?.account?.readyState, i18n, isMobile])\n\n  const popupState = usePopupState({\n    variant: 'popover',\n    popupId: `popupId: 'wallet-connect-notification'`,\n  })\n  \n  return (\n    <>\n      {NetWorkItems}\n      { ((isLocked || accountState?.account.readyState === AccountStatus.NOT_ACTIVE) && !isMobile) ? (\n        <Box\n          display={'flex'}\n          paddingLeft={'1.2rem'}\n          borderRadius={'0.4rem'}\n          border={'1px solid var(--color-border)'}\n        >\n          <Box\n            component={'div'}\n            paddingRight={2}\n            onClick={handleClick}\n            paddingY={'5px'}\n            display={'flex'}\n            alignItems={'center'}\n          >\n            <CircleIcon\n              fontSize={'large'}\n              htmlColor={'var(--color-error)'}\n              sx={{ marginLeft: -1 }}\n            />\n            <Typography component={'span'} variant={'body1'} lineHeight={1} color={'inherit'}>\n              {t(label)}\n            </Typography>\n          </Box>\n          {exchangeInfo && <Button\n            color={'error'}\n            size={'small'}\n            sx={{ borderRadius: '4px', height: '34px' }}\n            variant={'contained'}\n            onClick={isLocked ? handleClickUnlock : handleClickSignIn}\n          >\n            <LockIcon\n              sx={{ marginRight: 1, marginBottom: 0.2 }}\n              style={{ width: 16, height: 16 }}\n            />\n            <Typography component={'span'} variant={'body1'}>\n              Sign in First\n            </Typography>\n          </Button>}\n        </Box>\n      ) : (\n        <WalletConnectBtnStyled\n          variant={\n            ['un-connect', 'wrong-network'].findIndex((ele) => btnClassname === ele) !== -1\n              ? 'contained'\n              : 'outlined'\n          }\n          size={\n            ['un-connect', 'wrong-network'].findIndex((ele) => btnClassname === ele) !== -1\n              ? 'small'\n              : 'medium'\n          }\n          color={'primary'}\n          className={`wallet-btn ${btnClassname}`}\n          onClick={handleClick}\n          {...bindHover(popupState)}\n        >\n          {icon ? (\n            <Typography component={'i'} marginLeft={-1}>\n              {icon}\n            </Typography>\n          ) : (\n            <></>\n          )}\n          <Typography component={'span'} variant={'body1'} lineHeight={1} color={'inherit'}>\n            {t(label)}\n          </Typography>\n          {isLocked && (\n            <Box\n              ml={2}\n              borderRadius={'4px'}\n              bgcolor={'var(--color-error)'}\n              display={'flex'}\n              alignItems={'center'}\n              justifyContent={'center'}\n              height={'28px'}\n              width={'28px'}\n              onClick={(e) => {\n                e.stopPropagation()\n                handleClickUnlock(e)\n              }}\n            >\n              <LockIcon style={{ width: 16, height: 16, color: 'var(--color-white)' }} />\n            </Box>\n          )}\n        </WalletConnectBtnStyled>\n      )}\n    </>\n  )\n}\n\nexport const WalletConnectL1Btn = ({\n  accountState,\n  handleClick,\n  NetWorkItems,\n  isShowOnUnConnect,\n}: // isShowOnUnConnect,\nWalletConnectBtnProps) => {\n  const { t } = useTranslation(['layout', 'common'])\n  // const { isMobile } = useSettings();\n  const [label, setLabel] = React.useState<string>(t('labelConnectWallet'))\n\n  const [btnClassname, setBtnClassname] = React.useState<string | undefined>('')\n  const [icon, setIcon] = React.useState<JSX.Element | undefined>()\n\n  React.useEffect(() => {\n    const account = accountState?.account\n    if (account) {\n      const addressShort = account.accAddress ? getShortAddr(account?.accAddress) : undefined\n      if (addressShort) {\n        setLabel(addressShort)\n      }\n      setIcon(undefined)\n\n      myLog('wallet connect account.readyState:', account.readyState)\n\n      switch (account.readyState) {\n        case AccountStatus.UN_CONNECT:\n          setBtnClassname('un-connect')\n          setLabel('labelConnectWallet')\n          break\n        case AccountStatus.LOCKED:\n        case AccountStatus.ACTIVATED:\n        case AccountStatus.NO_ACCOUNT:\n        case AccountStatus.DEPOSITING:\n        case AccountStatus.NOT_ACTIVE:\n          setBtnClassname('unlocked')\n          const chainId = account._chainId as any\n          switch (chainId) {\n            case sdk.ChainId.MAINNET:\n              setIcon(\n                <Typography\n                  paddingRight={1}\n                  color={'var(--color-text-third)'}\n                  display={'inline-flex'}\n                  alignItems={'center'}\n                >\n                  <CircleIcon fontSize={'large'} htmlColor={'var(--color-success)'} />\n                  L1\n                </Typography>,\n                // <CircleIcon fontSize={\"large\"} ChainIdhtmlColor={\"var(--color-success)\"} />\n              )\n              break\n            // case sdk.ChainId.GOERLI:\n            // case ChainIdExtends[]:\n            default:\n              if (ChainTests.includes(Number(chainId))) {\n                setIcon(\n                  <Typography paddingRight={1} color={'var(--color-text-third)'}>\n                    Test\n                  </Typography>,\n                  // <CircleIcon fontSize={\"large\"} htmlColor={\"var(--color-success)\"} />\n                )\n              }\n              break\n            // setIcon(\n            //   <Typography color={'--color-text-third'>{ChainIdExtends[account._chainId]}</Typography>\n            //   // <CircleIcon fontSize={\"large\"} htmlColor={\"var(--color-success)\"} />\n            // );\n          }\n          break\n        case AccountStatus.ERROR_NETWORK:\n          setBtnClassname('wrong-network')\n          setLabel('labelWrongNetwork')\n          setIcon(<UnConnectIcon style={{ width: 16, height: 16 }} />)\n          break\n        default:\n      }\n    } else {\n      setLabel('labelConnectWallet')\n    }\n  }, [accountState?.account?.readyState])\n\n  const _handleClick = (event: React.MouseEvent) => {\n    // debounceCount(event)\n    if (handleClick) {\n      handleClick(event)\n    }\n  }\n\n  const popupState = usePopupState({\n    variant: 'popover',\n    popupId: `popupId: 'wallet-connect-notification'`,\n  })\n  return (\n    <>\n      {NetWorkItems}\n      {(!isShowOnUnConnect || accountState?.account?.readyState !== AccountStatus.UN_CONNECT) && (\n        <WalletConnectBtnStyled\n          variant={\n            ['un-connect', 'wrong-network'].findIndex((ele) => btnClassname === ele) !== -1\n              ? 'contained'\n              : 'outlined'\n          }\n          size={\n            ['un-connect', 'wrong-network'].findIndex((ele) => btnClassname === ele) !== -1\n              ? 'small'\n              : 'medium'\n          }\n          color={'primary'}\n          className={`wallet-btn ${btnClassname}`}\n          onClick={_handleClick}\n          {...bindHover(popupState)}\n        >\n          {icon ? (\n            <Typography component={'i'} marginLeft={-1}>\n              {icon}\n            </Typography>\n          ) : (\n            <></>\n          )}\n          <Typography component={'span'} variant={'body1'} lineHeight={1} color={'inherit'}>\n            {t(label)}\n          </Typography>\n        </WalletConnectBtnStyled>\n      )}\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/header/toolbar/index.tsx",
    "content": "import { Badge, Box, IconButton } from '@mui/material'\nimport {\n  Account,\n  AccountStatus,\n  CircleIcon,\n  DownloadIcon,\n  NotificationIcon,\n  ProfileIcon,\n  SettingIcon,\n  NOTIFICATIONHEADER,\n  ThemeType,\n  DarkIcon,\n  LightIcon,\n} from '@loopring-web/common-resources'\nimport { WithTranslation } from 'react-i18next'\nimport { bindHover, usePopupState } from 'material-ui-popup-state/hooks'\nimport { bindPopper } from 'material-ui-popup-state/es'\nimport { PopoverPure, SubMenu, SubMenuList } from '../../basic-lib'\nimport { SettingPanel } from '../../block/SettingPanel'\nimport { NotificationPanel } from '../../block/NotificationPanel'\nimport React, { useRef, useState } from 'react'\nimport { DownloadPanel } from '../../block/DownloadPanel'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { useSettings } from '../../../stores'\n\nexport const BtnDownload = ({\n  t,\n  url,\n  i18nTitle,\n}: {\n  i18nTitle: string\n  i18nDescription: string\n  url: string\n} & WithTranslation) => {\n  const popupState = usePopupState({\n    variant: 'popover',\n    popupId: 'downloadPop',\n  })\n  return (\n    <Box>\n      <IconButton\n        title={t(i18nTitle)}\n        aria-label={t('labeldownloadApp')}\n        rel='noopener noreferrer'\n        target='_blank'\n        href={url}\n        {...bindHover(popupState)}\n      >\n        <DownloadIcon />\n      </IconButton>\n      <PopoverPure\n        {...bindPopper(popupState)}\n        anchorOrigin={{\n          vertical: 'bottom',\n          horizontal: 'center',\n        }}\n        transformOrigin={{\n          vertical: 'top',\n          horizontal: 'center',\n        }}\n      >\n        <Box minWidth={160}>\n          <DownloadPanel viewMoreUrl={url} />\n        </Box>\n      </PopoverPure>\n    </Box>\n  )\n}\nexport const BtnNotification = <N = sdk.UserNotification,>({\n  notification, //:{notifyMap,myNotifyMap},\n  account,\n  chainId,\n  onClickExclusiveredPacket,\n  showExclusiveRedpacket,\n  exclusiveRedpacketCount,\n}: {\n  notification: NOTIFICATIONHEADER<N>\n  account: Account\n  chainId: sdk.ChainId\n  onClickExclusiveredPacket: () => void\n  showExclusiveRedpacket: boolean\n  exclusiveRedpacketCount: number\n}) => {\n  const popupState = usePopupState({\n    variant: 'popover',\n    popupId: 'notificationPop',\n  })\n  const popupStateEle = bindPopper(popupState)\n  // bindHover(popupState)\n  return (\n    <Box position={'relative'}>\n      <IconButton aria-label={'notification'} {...bindHover(popupState)}>\n        <Badge\n          sx={{ color: 'var(--color-error)' }}\n          badgeContent={\n            notification?.myNotifyMap?.total\n              ? notification.myNotifyMap.total < 999\n                ? notification.myNotifyMap.total\n                : '99+'\n              : ''\n          }\n        >\n          <NotificationIcon />\n        </Badge>\n      </IconButton>\n      {!notification?.myNotifyMap?.total && notification?.notifyMap?.notifications?.length ? (\n        <CircleIcon\n          sx={{\n            position: 'absolute',\n            top: -6,\n            right: -6,\n            pointerEvents: 'none' as any,\n          }}\n          className={'noteit'}\n          fontSize={'large'}\n          htmlColor={'var(--color-error)'}\n        />\n      ) : (\n        <></>\n      )}\n      <PopoverPure\n        {...popupStateEle}\n        anchorOrigin={{\n          vertical: 'bottom',\n          horizontal: 'center',\n        }}\n        transformOrigin={{\n          vertical: 'top',\n          horizontal: 'center',\n        }}\n      >\n        <NotificationPanel\n          closePop={popupStateEle.onMouseLeave as any}\n          exclusiveRedpacketCount={exclusiveRedpacketCount}\n          onClickExclusiveredPacket={onClickExclusiveredPacket}\n          showExclusiveRedpacket={showExclusiveRedpacket}\n          notification={{ ...notification, account, chainId }}\n        />\n      </PopoverPure>\n    </Box>\n  )\n}\n\nexport const BtnSetting = ({ t, label }: any) => {\n  const popupState = usePopupState({\n    variant: 'popover',\n    popupId: 'settingPop',\n  })\n  return (\n    <Box>\n      <IconButton\n        aria-label={t(label)}\n        {...bindHover(popupState)}\n      >\n        <SettingIcon />\n      </IconButton>\n      <PopoverPure\n        anchorOrigin={{\n          vertical: 'bottom',\n          horizontal: 'center',\n        }}\n        transformOrigin={{\n          vertical: 'top',\n          horizontal: 'center',\n        }}\n        {...bindPopper(popupState)}\n      >\n        <Box margin={2} minWidth={320}>\n          <SettingPanel />\n        </Box>\n      </PopoverPure>\n    </Box>\n  )\n}\n\nexport const BtnSettingMobile = ({ t, label }: any) => {\n  const [popupMobileOpen, setPopupMobileOpen] = useState(false)\n  const btn = useRef<HTMLButtonElement>(null)\n  return (\n    <Box>\n      <IconButton\n        ref={btn}\n        aria-label={t(label)}\n        onClick={() => setPopupMobileOpen((prev) => !prev)}        \n      >\n        <SettingIcon />\n      </IconButton>\n      <PopoverPure\n        anchorEl={btn.current}\n        anchorOrigin={{\n          vertical: 'top',\n          horizontal: 'right',\n        }}\n        transformOrigin={{\n          vertical: 'bottom',\n          horizontal: 'right',\n        }}\n\n        open={popupMobileOpen}\n        onClose={() => setPopupMobileOpen(false)}\n      >\n        <Box margin={2} minWidth={320}>\n          <SettingPanel />\n        </Box>\n      </PopoverPure>\n    </Box>\n  )\n}\n\nexport const ProfileMenu = ({ t, label, readyState, router, subMenu }: any) => {\n  const popupState = usePopupState({\n    variant: 'popover',\n    popupId: 'settingPop',\n  })\n  return readyState == AccountStatus.ACTIVATED ? (\n    <Box>\n      <IconButton aria-label={t(label)} size={'large'} {...bindHover(popupState)}>\n        <ProfileIcon />\n      </IconButton>\n      <PopoverPure\n        {...bindPopper(popupState)}\n        anchorOrigin={{\n          vertical: 'bottom',\n          horizontal: 'center',\n        }}\n        transformOrigin={{\n          vertical: 'top',\n          horizontal: 'center',\n        }}\n      >\n        <SubMenu className={'color-light'}>\n          <SubMenuList selected={router} subMenu={{ ...subMenu } as any} />\n        </SubMenu>\n      </PopoverPure>\n    </Box>\n  ) : (\n    <></>\n  )\n}\n\nexport const ColorSwitch = () => {\n  const { setTheme, themeMode } = useSettings()\n\n  const handleThemeClick = React.useCallback(\n    (_e: any) => {\n      setTheme(themeMode === ThemeType.dark ? ThemeType.light : ThemeType.dark)\n    },\n    [themeMode],\n  )\n  return (\n    <IconButton size={'large'} edge={'end'} onClick={handleThemeClick}>\n      {themeMode === ThemeType.dark ? <DarkIcon /> : <LightIcon />}\n    </IconButton>\n  )\n}\n\nexport * from './Interface'\nexport * from './WalletConnect'\n"
  },
  {
    "path": "packages/component-lib/src/components/index.tsx",
    "content": "export * from './basic-lib'\nexport * from './tradePanel'\nexport * from './tableList'\nexport * from './header'\nexport * from './footer'\nexport * from './basic-lib/popover'\nexport * from './modal'\nexport * from './block'\nexport * from './styled'\nexport * from './charts'\nexport * from './toast'\nexport * from './bottomRule'\nexport * from './provider'\nexport * from './share'\nexport * from './carousel'\n"
  },
  {
    "path": "packages/component-lib/src/components/layout/AmmDetail.stories.tsx",
    "content": "import styled from '@emotion/styled'\nimport { Meta, Story } from '@storybook/react'\nimport { MemoryRouter } from 'react-router-dom'\nimport {\n  Box,\n  Breadcrumbs,\n  Container,\n  GlobalStyles,\n  Grid,\n  Hidden,\n  Link,\n  Toolbar,\n  Typography,\n} from '@mui/material'\n\nimport { css, Theme, useTheme } from '@emotion/react'\nimport {\n  AmmDetailExtendProps,\n  AmmInData,\n  AmmPanelType,\n  CoinInfo,\n  EmptyValueTag,\n  FloatTag,\n  globalCss,\n  headerMenuData,\n  headerToolBarData,\n  LinkedIcon,\n  MyAmmLP,\n  PriceTag,\n  YEAR_DAY_FORMAT,\n} from '@loopring-web/common-resources'\n\nimport { account, ammCalcData, coinMap, tradeCalcData } from '../../static'\nimport { withTranslation } from 'react-i18next'\nimport { useSettings } from '../../stores'\nimport moment from 'moment'\nimport { TradeTitle } from '../block'\nimport { Header } from '../header'\nimport React from 'react'\nimport { AmmPanel, AmmProps } from '../tradePanel'\nimport { Currency } from '@loopring-web/loopring-sdk'\n\nconst Style = styled.div``\nconst tradeData: any = {\n  coinA: { belong: 'ETH', balance: 0.3, tradeValue: 0 },\n  coinB: { belong: 'LRC', balance: 1000, tradeValue: 0 },\n}\n\nconst titleInfo: AmmDetailExtendProps<AmmInData<any>, any> = {\n  // tradeCalcData:,\n  ammCalcData: ammCalcData,\n  activity: {\n    ruleType: 'SWAP_VOLUME_RANKING',\n    market: 'LRC-ETH',\n    status: 'NotStarted' as any,\n    totalRewards: 1232141,\n    myRewards: 122,\n    rewardToken: coinMap['USDT'] as CoinInfo<any>,\n    duration: {\n      from: new Date('2021-1-1'),\n      to: new Date(),\n    },\n  },\n  coinAInfo: coinMap[ammCalcData.myCoinA.belong] as CoinInfo<any>,\n  coinBInfo: coinMap[ammCalcData.myCoinB.belong] as CoinInfo<any>,\n  tradeFloat: {\n    change: 1000,\n    timeUnit: '24h',\n    priceU: 1.23123,\n    floatTag: FloatTag.increase,\n    // tagNew: false,\n  },\n  amountU: 197764.89,\n  totalLPToken: 12132131,\n  totalA: 0.002,\n  totalB: 12344,\n  totalAU: 0.002,\n  totalBU: 12344,\n  rewardToken: 'LRC',\n  rewardA: 13,\n  feeA: 121,\n  feeB: 1232,\n  isNew: true,\n  isActivity: false,\n  APR: 56,\n}\nconst myAmm: MyAmmLP<any> = {\n  feeA: 122,\n  feeB: 21,\n  feeU: 0.0012,\n  reward: 123,\n  rewardToken: coinMap.DPR as CoinInfo<any>,\n  balanceA: 12131,\n  balanceB: 0.0012,\n  balanceU: 232,\n}\nconst AmmDetailWrap = withTranslation('common')(({ t, ...rest }: any) => {\n  const ammProps: AmmProps<any, any, any, any> = {\n    ammCalcDataDeposit: ammCalcData,\n    ammCalcDataWithDraw: ammCalcData,\n    refreshRef: React.createRef(),\n    ammDepositData: tradeData,\n    ammWithdrawData: tradeData,\n    // tradeCalcData,\n    handleAmmAddChangeEvent: (data, type) => {\n      console.log('handleAmmAddChangeEvent', data, type)\n    },\n    handleAmmRemoveChangeEvent: (data) => {\n      console.log('handleAmmRemoveChangeEvent', data)\n    },\n    onAmmRemoveClick: (data) => {\n      console.log('onAmmRemoveClick', data)\n    },\n    onAmmAddClick: (data) => {\n      console.log('onAmmAddClick', data)\n    },\n  }\n\n  const WrapAmmPanel = (rest: any) => {\n    return <AmmPanel {...{ ...ammProps, tabSelected: AmmPanelType.Join }} {...rest} />\n  }\n\n  const BoxStyled = styled(Box)`\n    ${({ theme }) => theme.border.defaultFrame({ c_key: '' })};\n    background-color: var(--color-box);\n  `\n  const { currency } = useSettings()\n\n  return (\n    <>\n      <Header\n        account={account}\n        headerMenuData={headerMenuData}\n        headerToolBarData={headerToolBarData}\n        selected={'markets'}\n        notification={undefined}\n        allowTrade={{\n          register: {\n            enable: false,\n            reason: undefined,\n          },\n          order: {\n            enable: false,\n            reason: undefined,\n          },\n          joinAmm: {\n            enable: false,\n            reason: undefined,\n          },\n          dAppTrade: {\n            enable: false,\n            reason: undefined,\n          },\n          raw_data: {\n            enable: false,\n            reason: undefined,\n          },\n        }}\n        isMobile={false}\n      />\n      <Toolbar />\n      <Container maxWidth='lg'>\n        {/*style={{height: '100%' }}*/}\n        <Grid container marginTop={3}>\n          <Grid item xs={8}>\n            <Breadcrumbs aria-label='breadcrumb'>\n              <Link color='textSecondary' href='/'>\n                {t('labelAmmList')}\n              </Link>\n              <Typography\n                color={'textSecondary'}\n                display={'flex'}\n                alignItems={'center'}\n                justifyContent={'center'}\n              >\n                {tradeData.coinA.belong}\n                <LinkedIcon />\n                {tradeData.coinB.belong}\n              </Typography>\n            </Breadcrumbs>\n          </Grid>\n          <Grid item xs={4} alignItems={'center'} justifyContent={'flex-end'} display={'flex'}>\n            <Link href={''} variant={'h6'}>\n              {t('labelBack')}\n            </Link>\n          </Grid>\n        </Grid>\n        <Grid container marginTop={3}>\n          <Grid item xs={7}>\n            <TradeTitle\n              accoun={account}\n              {...{\n                t,\n                ...rest,\n                tReady: rest.ready,\n                tradeCalcData,\n                tradeFloat: {\n                  priceU: +123,\n                  change: '+15%',\n                  timeUnit: '24h',\n                },\n              }}\n            />\n          </Grid>\n          {/*<ButtonListRightStyled item xs={5} minWidth={'328'} display={'flex'} flexDirection={'row'}*/}\n          {/*                       justifyContent={'flex-end'} alignItems={'flex-end'}>*/}\n          {/*    <Button variant={'contained'} size={'small'} color={'primary'}*/}\n          {/*            loading={btnShowTradeStatus === TradeBtnStatus.LOADING ? 'true' : 'false'}*/}\n          {/*            disabled={btnShowTradeStatus === TradeBtnStatus.DISABLED}*/}\n          {/*            onClick={onShowTrade}>{t('labelTrade')}</Button>*/}\n\n          {/*</ButtonListRightStyled>*/}\n        </Grid>\n\n        <Box flex={1} display={'flex'} alignItems={'stretch'} flexDirection='row' marginTop={3}>\n          <Box flex={1} display={'flex'}>\n            <Grid container spacing={2} wrap={'nowrap'}>\n              <Grid\n                item\n                md={5}\n                xs={12}\n                paddingRight={2}\n                display={'flex'}\n                flexDirection={'column'}\n                alignItems={'stretch'}\n                justifyContent={'space-between'}\n              >\n                <BoxStyled\n                  paddingY={3}\n                  paddingX={(1 / 2) * 5}\n                  display={'flex'}\n                  flexDirection={'column'}\n                >\n                  <Typography\n                    component={'p'}\n                    color={'textSecondary'}\n                    display={'flex'}\n                    justifyContent={'space-between'}\n                  >\n                    <Typography component={'span'} style={{ textTransform: 'capitalize' }}>\n                      {t('labelLiquidity')}\n                    </Typography>\n                    <Typography component={'span'} style={{ textTransform: 'uppercase' }}>\n                      {t('labelAPR')}\n                    </Typography>\n                  </Typography>\n                  <Typography\n                    component={'p'}\n                    color={'textPrimary'}\n                    display={'flex'}\n                    justifyContent={'space-between'}\n                    marginTop={1}\n                  >\n                    <>\n                      <Typography component={'span'}>\n                        {' '}\n                        {typeof titleInfo.amountU === 'undefined'\n                          ? EmptyValueTag\n                          : currency === Currency.usd\n                          ? PriceTag.Dollar + titleInfo.amountU\n                          : 0}\n                      </Typography>\n                      <Typography component={'span'}>\n                        {' '}\n                        {titleInfo.APR ? titleInfo.APR : EmptyValueTag}%\n                      </Typography>\n                    </>\n                  </Typography>\n\n                  <Typography\n                    component={'p'}\n                    color={'textSecondary'}\n                    display={'flex'}\n                    justifyContent={'space-between'}\n                    marginTop={2}\n                  >\n                    <Typography component={'span'} color={'textSecondary'}>\n                      <Hidden mdDown>{t('labelLPTotal')}</Hidden>\n                      {t('labelLPTokens')}\n                    </Typography>\n                    <Typography component={'span'} color={'textSecondary'}>\n                      {titleInfo.totalLPToken}\n                    </Typography>\n                  </Typography>\n                  <Typography\n                    component={'p'}\n                    color={'textSecondary'}\n                    display={'flex'}\n                    justifyContent={'space-between'}\n                    marginTop={1}\n                  >\n                    <Typography component={'span'} color={'textSecondary'}>\n                      <Hidden mdDown>{t('labelLPTotal')}</Hidden>\n                      {titleInfo.ammCalcData?.myCoinA.belong}\n                    </Typography>\n\n                    <Typography component={'span'} color={'textSecondary'}>\n                      {titleInfo.totalA}\n                    </Typography>\n                  </Typography>\n                  <Typography\n                    component={'p'}\n                    color={'textSecondary'}\n                    display={'flex'}\n                    justifyContent={'space-between'}\n                    marginTop={1}\n                  >\n                    <Typography component={'span'} color={'textSecondary'}>\n                      <Hidden mdDown>{t('labelLPTotal')}</Hidden>\n                      {titleInfo.ammCalcData?.myCoinB.belong}\n                    </Typography>\n                    <Typography component={'span'} color={'textSecondary'}>\n                      {titleInfo.totalB}\n                    </Typography>\n                  </Typography>\n                </BoxStyled>\n                <BoxStyled\n                  paddingY={3}\n                  paddingX={(1 / 2) * 5}\n                  display={'flex'}\n                  flexDirection={'column'}\n                >\n                  <Typography\n                    component={'p'}\n                    color={'textSecondary'}\n                    display={'flex'}\n                    justifyContent={'space-between'}\n                    alignItems={'center'}\n                  >\n                    <Typography component={'span'} color={'textSecondary'} variant={'body2'}>\n                      {titleInfo.tradeFloat.timeUnit} {t('labelVolume')}\n                    </Typography>\n                    <Typography component={'span'} color={'textSecondary'}>\n                      {t('labelFee')} {/* ' : '*/}\n                    </Typography>\n                  </Typography>\n                  <Typography\n                    component={'p'}\n                    color={'textSecondary'}\n                    display={'flex'}\n                    justifyContent={'space-between'}\n                    marginTop={1}\n                    alignItems={'center'}\n                  >\n                    <Typography component={'span'} variant={'h5'} color={'textPrimary'}>\n                      {PriceTag.Dollar + titleInfo.tradeFloat.priceU}\n                    </Typography>\n                    <Typography\n                      noWrap\n                      textAlign={'center'}\n                      component={'span'}\n                      color={'textSecondary'}\n                      variant={'body2'}\n                      textOverflow={'ellipsis'}\n                      display={'flex'}\n                      alignItems={'center'}\n                    >\n                      <Typography\n                        component={'span'}\n                        color={'inherit'}\n                        variant={'inherit'}\n                        display={'flex'}\n                        flexDirection={'column'}\n                      >\n                        <Typography component={'span'} color={'inherit'} variant={'inherit'}>\n                          {titleInfo.ammCalcData?.myCoinA.belong}\n                        </Typography>\n                        <Typography component={'span'} color={'inherit'} variant={'inherit'}>\n                          {titleInfo.feeA}\n                        </Typography>\n                      </Typography>\n                      <Typography component={'span'} color={'inherit'} variant={'h6'} paddingX={1}>\n                        {' + '}\n                      </Typography>\n                      <Typography\n                        component={'span'}\n                        color={'inherit'}\n                        variant={'inherit'}\n                        display={'flex'}\n                        flexDirection={'column'}\n                      >\n                        <Typography component={'span'} color={'inherit'} variant={'inherit'}>\n                          {titleInfo.ammCalcData?.myCoinB.belong}\n                        </Typography>\n                        <Typography component={'span'} color={'inherit'} variant={'inherit'}>\n                          {titleInfo.feeB}\n                        </Typography>\n                      </Typography>\n                    </Typography>\n                  </Typography>\n                </BoxStyled>\n                <BoxStyled\n                  paddingY={3}\n                  paddingX={(1 / 2) * 5}\n                  display={'flex'}\n                  flexDirection={'column'}\n                >\n                  <Typography\n                    component={'p'}\n                    color={'textSecondary'}\n                    display={'flex'}\n                    justifyContent={'space-between'}\n                  >\n                    <Typography component={'span'} color={'textSecondary'}>\n                      {' '}\n                      {t('labelMyPoolShare')}\n                    </Typography>\n                  </Typography>\n                  <Typography\n                    component={'p'}\n                    color={'textSecondary'}\n                    display={'flex'}\n                    justifyContent={'space-between'}\n                    marginTop={1}\n                  >\n                    <Typography component={'span'} color={'textSecondary'}>\n                      {' '}\n                      {myAmm.balanceA ? myAmm.balanceA : EmptyValueTag}{' '}\n                      {titleInfo.ammCalcData?.myCoinA.belong}{' '}\n                    </Typography>\n                    <Typography component={'span'} color={'textSecondary'} variant={'h6'}>\n                      {' '}\n                      --{' '}\n                    </Typography>\n                  </Typography>\n                  <Typography\n                    component={'p'}\n                    color={'textSecondary'}\n                    display={'flex'}\n                    justifyContent={'space-between'}\n                    marginTop={1}\n                  >\n                    <Typography component={'span'} color={'textSecondary'}>\n                      {' '}\n                      {myAmm.balanceB ? myAmm.balanceA : EmptyValueTag}{' '}\n                      {titleInfo.ammCalcData?.myCoinB.belong}\n                    </Typography>\n                    <Typography component={'span'} color={'textSecondary'} variant={'h6'}>\n                      {' '}\n                      --{' '}\n                    </Typography>\n                  </Typography>\n                </BoxStyled>\n                <BoxStyled\n                  paddingY={3}\n                  paddingX={(1 / 2) * 5}\n                  display={'flex'}\n                  flexDirection={'column'}\n                >\n                  <Box display={'flex'} flexDirection={'row'} justifyContent={'space-between'}>\n                    <Typography display={'flex'} flexDirection={'column'} component={'div'}>\n                      <Typography variant={'body2'} component={'h5'} color={'textSecondary'}>\n                        {t('labelReward')}\n                      </Typography>\n                      <Typography variant={'body1'} component={'span'} color={'textPrimary'}>\n                        {typeof titleInfo.activity === 'undefined' ? (\n                          EmptyValueTag\n                        ) : (\n                          <>\n                            <Typography component={'span'}>\n                              {titleInfo.activity.totalRewards}{' '}\n                            </Typography>\n                            <Typography component={'span'}>\n                              {titleInfo.activity.rewardToken.simpleName}\n                            </Typography>\n                          </>\n                        )}\n                      </Typography>\n                    </Typography>\n                    <Typography\n                      display={'flex'}\n                      flexDirection={'column'}\n                      alignItems={'flex-end'}\n                      component={'div'}\n                    >\n                      <Typography variant={'body2'} component={'h5'} color={'textSecondary'}>\n                        {t('labelMyReward')}\n                      </Typography>\n                      <Typography variant={'body1'} component={'span'} color={'textPrimary'}>\n                        {typeof titleInfo.activity === 'undefined' ? (\n                          EmptyValueTag\n                        ) : (\n                          <>\n                            <Typography component={'span'}>\n                              {myAmm.reward}\n                              <Typography component={'span'}>\n                                {titleInfo.activity.rewardToken.simpleName}\n                              </Typography>\n                            </Typography>\n                          </>\n                        )}\n                      </Typography>\n                    </Typography>\n                  </Box>\n                  <Typography\n                    alignSelf={'flex-start'}\n                    variant={'body2'}\n                    color={'textSecondary'}\n                    component='span'\n                    marginTop={1}\n                  >\n                    {t('labelDate')}:\n                    {typeof titleInfo.activity === 'undefined'\n                      ? EmptyValueTag\n                      : moment(titleInfo.activity.duration.from).format(YEAR_DAY_FORMAT) +\n                        ' - ' +\n                        moment(titleInfo.activity.duration.to).format(YEAR_DAY_FORMAT)}\n                  </Typography>\n                </BoxStyled>\n              </Grid>\n              <Hidden mdDown>\n                <Grid item md={7} paddingRight={2}></Grid>\n              </Hidden>\n            </Grid>\n          </Box>\n          <Box display={'flex'}>\n            <WrapAmmPanel />\n          </Box>\n        </Box>\n      </Container>\n\n      {/*<Footer></Footer>*/}\n    </>\n  )\n})\n\nconst Template: Story<any> = () => {\n  const theme: Theme = useTheme()\n  return (\n    <>\n      <GlobalStyles\n        styles={css`\n      ${globalCss({ theme })};\n\n      body:before {\n        ${\n          theme.mode === 'dark'\n            ? ` \n                        background: var(--color-global-bg);\n                   `\n            : ''\n        }\n      }\n    }\n    `}\n      />\n      <Style>\n        <MemoryRouter initialEntries={['/']}>\n          <AmmDetailWrap />\n        </MemoryRouter>\n      </Style>{' '}\n    </>\n  )\n}\n\nexport default {\n  title: 'components/Layout/AmmDetail',\n  component: Template,\n  argTypes: {},\n} as Meta\n\nexport const AmmDetailStory = Template.bind({})\n// SwitchPanel.args = {}\n"
  },
  {
    "path": "packages/component-lib/src/components/layout/Error.stories.tsx",
    "content": "import { Meta, Story } from '@storybook/react'\nimport { MemoryRouter } from 'react-router-dom'\nimport { Box, Container, GlobalStyles } from '@mui/material'\n\nimport { css, Theme, useTheme } from '@emotion/react'\nimport { globalCss } from '@loopring-web/common-resources'\nimport { useTranslation } from 'react-i18next'\nimport styled from '@emotion/styled'\n\nconst StyleBox = styled(Box)`\n  background-image: url('https://static.loopring.io/assets/images/error_bg.png');\n  background-repeat: no-repeat;\n  background-attachment: fixed;\n  background-position: bottom;\n` as typeof Box\n\nconst ErrorWrap = () => {\n  const { messageKey }: { id?: string; messageKey: string } = {\n    messageKey: 'errorMessageTokenMapIsEmpty',\n  }\n  const { t } = useTranslation('common')\n  return (\n    <>\n      <Container maxWidth='lg'>\n        {/*style={{height: '100%' }}*/}\n        <Box\n          flex={1}\n          display={'flex'}\n          alignItems={'center'}\n          justifyContent={'center'}\n          flexDirection='row'\n          marginTop={4}\n        >\n          <StyleBox height={680} width={120}>\n            {t(messageKey)}\n          </StyleBox>\n        </Box>\n      </Container>\n\n      {/*<Footer></Footer>*/}\n    </>\n  )\n}\n\nconst Template: Story<any> = () => {\n  const theme: Theme = useTheme()\n  return (\n    <>\n      <GlobalStyles\n        styles={css`\n          ${globalCss({ theme })};\n\n          body:before {\n            ${\n              theme.mode === 'dark'\n                ? ` \n                         background: var(--color-global-bg);\n                   `\n                : ''\n            }\n          }\n        }\n        `}\n      ></GlobalStyles>\n      <MemoryRouter initialEntries={['/']}>\n        <ErrorWrap />\n      </MemoryRouter>\n    </>\n  )\n}\n\nexport default {\n  title: 'components/Layout/Error',\n  component: ErrorWrap,\n  argTypes: {},\n} as Meta\n\nexport const ErrorStory = Template.bind({})\n// SwitchPanel.args = {}\n"
  },
  {
    "path": "packages/component-lib/src/components/layout/layer2.stories.tsx",
    "content": "import styled from '@emotion/styled'\nimport { Meta, Story } from '@storybook/react'\nimport { MemoryRouter } from 'react-router-dom'\nimport {\n  Box,\n  Collapse,\n  Container,\n  CssBaseline,\n  GlobalStyles,\n  Grid,\n  Paper,\n  Toolbar,\n  Typography,\n} from '@mui/material'\nimport { Header, HideOnScroll } from '../header'\nimport { css, Theme, useTheme } from '@emotion/react'\nimport { Button, SubMenu, SubMenuList as BasicSubMenuList } from '../basic-lib'\nimport {\n  globalCss,\n  headerMenuData,\n  headerToolBarData,\n  PriceTag,\n  subMenuLayer2,\n} from '@loopring-web/common-resources'\nimport { withTranslation } from 'react-i18next'\nimport { OrderHistoryTable as OrderHistoryTableUI } from '../tableList/orderHistoryTable'\nimport { AssetTitle, AssetTitleProps } from '../block'\nimport { AccountBasePanel, AccountBaseProps } from '../'\nimport React from 'react'\n\nconst Style = styled.div``\nconst SubMenuList = withTranslation('layout', { withRef: true })(BasicSubMenuList)\nconst OrderHistoryTable = withTranslation('common', { withRef: true })(OrderHistoryTableUI)\n\nconst AssetTitleWrap = (rest: any) => {\n  const assetTitleProps: AssetTitleProps = {\n    onShowReceive: () => {},\n    onShowSend: () => {},\n    accountId: 0,\n    setHideL2Assets: () => undefined,\n    hideL2Assets: false,\n    assetInfo: {\n      totalAsset: 123456.789,\n      priceTag: PriceTag.Dollar,\n    },\n  }\n\n  return (\n    <>\n      <Grid item xs={12}>\n        <AssetTitle\n          {...{\n            ...rest,\n            ...assetTitleProps,\n          }}\n        />\n      </Grid>\n    </>\n  )\n}\n\nconst Layer2Wrap = withTranslation('common')(({ t, ...rest }: any) => {\n  const selected = 'assets'\n  const StylePaper = styled(Box)`\n    width: 100%;\n    height: 100%;\n    flex: 1;\n    background: var(--color-box);\n    border-radius: ${({ theme }) => theme.unit}px;\n    padding: ${({ theme }) => theme.unit * 3}px;\n\n    .tableWrapper {\n      ${({ theme }) => theme.border.defaultFrame({ c_key: 'default', d_R: 1 })};\n      // margin-top:  ${({ theme }) => theme.unit * 3}px;\n      // border: 1px solid #252842;\n      // border-radius: ${({ theme }) => theme.unit}px;\n      // padding: 26px;\n    }\n  ` as typeof Paper\n  const accountInfoProps: AccountBaseProps = {\n    __timer__: -1,\n    frozen: false,\n    keySeed: '',\n    qrCodeUrl: '',\n    accAddress: '0x123567243o24o242423098784',\n    accountId: 0,\n    apiKey: '',\n    connectName: 'unknown' as any,\n    eddsaKey: undefined,\n    etherscanUrl: 'https://material-ui.com/components/material-icons/',\n    keyNonce: undefined,\n    nonce: undefined,\n    publicKey: undefined,\n    readyState: 'unknown',\n    level: 'VIP 1',\n    mainBtn: (\n      <Button\n        variant={'contained'}\n        size={'small'}\n        color={'primary'}\n        onClick={() => console.log('my event')}\n      >\n        My button\n      </Button>\n    ),\n  }\n  const hasAccount = true\n  const [showAccountInfo, _setShowAccountInfo] = React.useState(hasAccount)\n  // const handleClick = (_event: React.MouseEvent) => {\n  //   if (showAccountInfo) {\n  //     setShowAccountInfo(false);\n  //   } else {\n  //     setShowAccountInfo(true);\n  //   }\n  //   _event.stopPropagation();\n  // };\n  // headerMenuData[\"as\"].extender = hasAccount ? (\n  //   <IconButton\n  //     disabled={!hasAccount}\n  //     onClick={handleClick}\n  //     aria-label={t(\"labelShowAccountInfo\")}\n  //     color=\"primary\"\n  //   >\n  //     {showAccountInfo ? <HideIcon /> : <ViewIcon />}\n  //   </IconButton>\n  // ) : undefined;\n\n  return (\n    <>\n      <CssBaseline />\n      <HideOnScroll>\n        <Header\n          {...{ ...rest }}\n          headerMenuData={headerMenuData}\n          headerToolBarData={{ ...headerToolBarData }}\n          selected={'markets'}\n        />\n      </HideOnScroll>\n      <Toolbar />\n      {hasAccount ? (\n        <Collapse in={showAccountInfo}>\n          <Container maxWidth='lg'>\n            <Box marginTop={3}>\n              <AccountBasePanel {...{ ...accountInfoProps, t, ...rest }} />\n            </Box>\n          </Container>\n        </Collapse>\n      ) : undefined}\n      <Container maxWidth='lg'>\n        {/*style={{height: '100%' }}*/}\n        <Box\n          flex={1}\n          display={'flex'}\n          alignItems={'stretch'}\n          flexDirection='row'\n          marginTop={3}\n          minWidth={800}\n        >\n          <Box width={200} display={'flex'} justifyContent={'stretch'}>\n            <SubMenu>\n              <SubMenuList selected={selected} subMenu={subMenuLayer2 as any} />\n            </SubMenu>\n          </Box>\n          <Box flex={1} marginLeft={4} height={1600} flexDirection='column'>\n            <Box marginBottom={3}>\n              <AssetTitleWrap />\n            </Box>\n            <StylePaper>\n              <Typography variant={'h5'} component={'h3'}>\n                Orders\n              </Typography>\n              <Box marginTop={2} className='tableWrapper'>\n                <OrderHistoryTable rawData={[]} pageSize={0} {...rest} getOrderList={() => {}} />\n              </Box>\n            </StylePaper>\n          </Box>\n        </Box>\n      </Container>\n      {/*<Footer></Footer>*/}\n    </>\n  )\n})\n\nconst Template: Story<any> = () => {\n  const theme: Theme = useTheme()\n  console.log(theme.mode)\n  return (\n    <>\n      <MemoryRouter initialEntries={['/']}>\n        <GlobalStyles\n          styles={css`\n            ${globalCss({ theme })};\n\n            body:before {\n              ${\n                theme.mode === 'dark'\n                  ? `\n            color: ${theme.colorBase.textPrimary};        \n           \n            background: var(--color-global-bg);\n       `\n                  : ''\n              }\n            }\n          }\n          `}\n        />\n        <Style>\n          <Layer2Wrap />\n        </Style>\n      </MemoryRouter>\n    </>\n  )\n}\n\nexport default {\n  title: 'components/Layout/Layer2',\n  component: Layer2Wrap,\n  argTypes: {},\n} as Meta\n\nexport const Layer2Story = Template.bind({})\n// SwitchPanel.args = {}\n"
  },
  {
    "path": "packages/component-lib/src/components/layout/trade.stories.tsx",
    "content": "import styled from '@emotion/styled'\nimport { Meta, Story } from '@storybook/react'\nimport { MemoryRouter } from 'react-router-dom'\nimport { Box, Container, GlobalStyles, Toolbar } from '@mui/material'\n\nimport { css, Theme, useTheme } from '@emotion/react'\nimport { Header } from '../header'\nimport { globalCss, headerMenuData, headerToolBarData } from '@loopring-web/common-resources'\n\nimport { account, tradeCalcData } from '../../static'\nimport { SwapPanel, SwapProps } from '../tradePanel'\nimport React from 'react'\n\nconst Style = styled.div``\nconst TradeWrap = () => {\n  let tradeData: any = {\n    sell: { belong: undefined },\n    buy: { belong: undefined },\n  }\n  const WrapSwapPanel = () => {\n    let swapProps: SwapProps<any, any, any> = {\n      campaignTagConfig: {\n        SWAP: [],\n        ORDERBOOK: [],\n        MARKET: [],\n        AMM: [],\n        FIAT: [],\n      } as any,\n      refreshRef: React.createRef(),\n      tradeData,\n      // swapTradeData: tradeData,\n      tradeCalcData,\n      onSwapClick: () => {\n        console.log('Swap button click')\n      },\n      handleSwapPanelEvent: async (data: any, switchType: any) => {\n        console.log(data, switchType)\n      },\n    }\n\n    return <SwapPanel<any, any, any> {...swapProps}> </SwapPanel>\n  }\n  return (\n    <>\n      <Header\n        account={account}\n        headerMenuData={headerMenuData}\n        headerToolBarData={headerToolBarData}\n        selected={'markets'}\n        allowTrade={{\n          register: {\n            enable: false,\n            reason: undefined,\n          },\n          order: {\n            enable: false,\n            reason: undefined,\n          },\n          joinAmm: {\n            enable: false,\n            reason: undefined,\n          },\n          dAppTrade: {\n            enable: false,\n            reason: undefined,\n          },\n          raw_data: {\n            enable: false,\n            reason: undefined,\n          },\n        }}\n        isMobile={false}\n        chainId={1}\n      />\n      <Toolbar />\n      <Container maxWidth='lg'>\n        {/*style={{height: '100%' }}*/}\n        <Box flex={1} display={'flex'} alignItems={'stretch'} flexDirection='row' marginTop={4}>\n          <Box flex={1} marginLeft={4} height={500} />\n          <Box display={'flex'}>\n            <WrapSwapPanel />\n          </Box>\n        </Box>\n      </Container>\n\n      {/*<Footer></Footer>*/}\n    </>\n  )\n}\n\nconst Template: Story<any> = () => {\n  const theme: Theme = useTheme()\n  return (\n    <>\n      <GlobalStyles\n        styles={css`\n          ${globalCss({ theme })};\n\n          body:before {\n            ${\n              theme.mode === 'dark'\n                ? ` \n                        background: var(--color-global-bg);\n                   `\n                : ''\n            }\n          }\n        }\n        `}\n      />\n      <Style>\n        {' '}\n        <MemoryRouter initialEntries={['/']}>\n          <TradeWrap />\n        </MemoryRouter>\n      </Style>{' '}\n    </>\n  )\n}\n\nexport default {\n  title: 'components/Layout/Trade',\n  component: TradeWrap,\n  argTypes: {},\n} as Meta\n\nexport const TradeStory = Template.bind({})\n// SwitchPanel.args = {}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/ClosureAnnouncementModal.tsx",
    "content": "import React from 'react'\nimport {\n  Dialog,\n  DialogTitle,\n  DialogContent,\n  DialogActions,\n  Button,\n  Typography,\n  Box,\n  // styled,\n  // useTheme,\n} from '@mui/material'\nimport { withTranslation, WithTranslation } from 'react-i18next'\nimport { AlertIcon, SoursURL } from '@loopring-web/common-resources'\nimport styled from '@emotion/styled'\nimport { useTheme } from '@emotion/react'\n// styled\n\nconst StyledDialog = styled(Dialog)(({ theme }) => ({\n  '& .MuiDialog-paper': {\n    borderRadius: theme.unit * 2,\n    maxWidth: '480px',\n    width: '90vw',\n    maxHeight: '90vh',\n    overflow: 'hidden',\n  },\n}))\n\nconst StyledDialogTitle = styled(DialogTitle)(({ theme }) => ({\n  background: `linear-gradient(135deg, ${theme.colorBase.primary} 0%, ${theme.colorBase.warning} 100%)`,\n  color: theme.colorBase.textPrimary,\n  padding: theme.unit * 2,\n  display: 'flex',\n  alignItems: 'center',\n  gap: theme.unit,\n  fontSize: '1.25rem',\n  fontWeight: 600,\n}))\n\nconst StyledDialogContent = styled(Box)(({ theme }) => ({\n\n  paddingTop: theme.unit * 5,\n  paddingBottom: theme.unit * 2,\n  paddingLeft: theme.unit * 4,\n  paddingRight: theme.unit * 4,\n  maxHeight: '85vh',\n  overflow: 'auto',\n  '&::-webkit-scrollbar': {\n    width: '6px',\n  },\n  '&::-webkit-scrollbar-track': {\n    backgroundColor: theme.colorBase.divide,\n    borderRadius: '3px',\n  },\n  '&::-webkit-scrollbar-thumb': {\n    backgroundColor: theme.colorBase.textSecondary,\n    borderRadius: '3px',\n  },\n}))\n\nconst StyledDialogActions = styled(DialogActions)(({ theme }) => ({\n  padding: theme.unit * 2,\n  borderTop: `1px solid ${theme.colorBase.divide}`,\n}))\n\nconst HighlightDate = styled('span')(({ theme }) => ({\n  backgroundColor: theme.colorBase.warning,\n  color: theme.colorBase.black,\n  padding: '2px 8px',\n  borderRadius: '4px',\n  fontSize: '1.4rem',\n}))\n\nconst SectionTitle = styled(Typography)(({ theme }) => ({\n  fontSize: '1.8rem',\n  fontWeight: 600,\n  color: theme.colorBase.textPrimary,\n  marginBottom: theme.unit,\n  display: 'flex',\n  alignItems: 'center',\n  gap: theme.unit,\n}))\n\nconst BulletList = styled('ul')(({ theme }) => ({\n  paddingLeft: '8px',\n  margin: `${theme.unit}px 0`,\n  listStyle: 'none',\n  '& li': {\n    marginBottom: theme.unit * 0.5,\n    color: theme.colorBase.textSecondary,\n    lineHeight: 1.5,\n    position: 'relative',\n    paddingLeft: '8px',\n    fontSize: '1.3rem',\n  },\n  '& li::before': {\n    content: '\"•\"',\n    color: theme.colorBase.textSecondary,\n    position: 'absolute',\n    left: 0,\n  },\n}))\n\nconst NetworkSection = styled(Box)(({ theme }) => ({\n  backgroundColor: theme.colorBase.box,\n  borderRadius: theme.unit,\n  marginBottom: theme.unit * 2,\n}))\n\nexport const ClosureAnnouncementModal = withTranslation('common')(\n  ({\n    t,\n    open,\n    handleClose,\n  }: WithTranslation & {\n    open: boolean\n    handleClose: () => void\n  }) => {\n    const theme = useTheme()\n\n    return (\n      <StyledDialog\n        open={open}\n        keepMounted\n        onClose={() => {}} // Prevent closing on outside click\n        disableEscapeKeyDown // Prevent closing with Escape key\n        aria-describedby='closure-announcement-dialog'\n      >\n        <StyledDialogContent position={'relative'}>\n          <Typography variant='h2' mb={4}>\n            Loopring DeFi{' '}\n            <Typography\n              variant='h2'\n              bgcolor={'var(--color-primary)'}\n              component={'span'}\n              borderRadius={'17.75px'}\n              color={theme.colorBase.white}\n              px={1}\n            >\n              Closure\n            </Typography>{' '}\n            Announcement\n          </Typography>\n          {/* <Box width={'150px'} sx={{\n            position: 'absolute',\n            top: 5,\n            right: 0\n          }} component={'img'} src={SoursURL + 'svg/closure_logo.svg'}/> */}\n          <Typography variant='body1' sx={{ mb: 2, color: theme.colorBase.textSecondary, fontSize: '1.4rem' }}>\n            Loopring DeFi business will be shut down after <HighlightDate>July 31st, 2025</HighlightDate>, which allows the team to allocate all\n            resources to focus on improving the Loopring Layer2 network.\n          </Typography>\n\n          <Typography variant='body1' sx={{ mb: 0.5, color: theme.colorBase.textSecondary, fontSize: '1.4rem' }}>\n            The impacted usages include:\n          </Typography>\n\n          <BulletList>\n            <Box sx={{'&&': {color: theme.colorBase.textPrimary}} } component={'li'}>Dual Investment</Box>\n            <Box sx={{'&&': {color: theme.colorBase.textPrimary}} } component={'li'}>Portal</Box>\n            <Box sx={{'&&': {color: theme.colorBase.textPrimary}} } component={'li'}>Block Trade</Box>\n            <Box sx={{'&&': {color: theme.colorBase.textPrimary}} } component={'li'}>ETH Staking</Box>\n          </BulletList>\n\n\n          <SectionTitle my={3}>📅 After the Sunset Date (July 31, 2025)</SectionTitle>\n\n          <Box sx={{ mb: 3, mt:3 }}>\n            <Typography variant='h6' sx={{ mb: 1, color: theme.colorBase.textPrimary, fontSize: '1.5rem' }}>\n              🔷 For Existing Positions:\n            </Typography>\n\n            <Typography variant='body2' sx={{ mb: 1,color: theme.colorBase.textPrimary, fontWeight: 600, fontSize: '1.3rem' }}>\n              1. Dual Investment:\n            </Typography>\n            <BulletList>\n              <li>No new subscriptions will be allowed after the sunset date.</li>\n              <li>All existing positions will be settled before July 31st.</li>\n            </BulletList>\n\n            <Typography variant='body2' sx={{ mb: 1,color: theme.colorBase.textPrimary, fontWeight: 600, fontSize: '1.3rem' }}>\n              2. Portal:\n            </Typography>\n            <BulletList>\n              <li>All active positions will be <Typography component=\"span\" fontWeight={600}>force-closed</Typography> after the sunset date.</li>\n            </BulletList>\n\n            <Typography variant='body2' sx={{ mb: 1,color: theme.colorBase.textPrimary, fontWeight: 600, fontSize: '1.3rem' }}>\n              3. ETH Staking:\n            </Typography>\n            <BulletList>\n              <li>No new subscriptions will be accepted.</li>\n              <li>Users holding wstETH, rETH, or CiETH can still:</li>\n              <Box pl={2.5}>\n                <li >\n                Redeem directly on Loopring Layer 2, or\n              </li>\n                <li >\n                Withdraw to Ethereum Layer 1 and interact directly with Lido, Rocket Pool, or the CIAN protocol for redemption.\n              </li>\n              </Box>\n              \n            </BulletList>\n          </Box>\n\n          <NetworkSection>\n            <SectionTitle>🌐 For Users on Taiko and Base Networks:</SectionTitle>\n            <Typography variant='body1' sx={{ mb: 2, color: theme.colorBase.textPrimary, fontSize: '1.4rem' }}>\n              After July 31st, Loopring will cease all services on both the Taiko and Base networks.\n            </Typography>\n            <BulletList>\n              <li>\n                Users who do not withdraw their assets from their Loopring DeFi (Layer 3) account\n                before the sunset date will have their funds <Typography component=\"span\" fontWeight={600}>automatically force-withdrawn</Typography> to the\n                upper layer (Taiko or Base).\n              </li>\n            </BulletList>\n            <Typography\n              variant='body2'\n              sx={{ mt: 1, color: theme.colorBase.textPrimary, fontSize: '1.2rem' }}\n            >\n              Note: Accounts with dust balances (i.e., less than $0.10 USD) will <Typography component=\"span\" fontWeight={600}>not</Typography> trigger a\n              force-withdrawal operation.\n            </Typography>\n          </NetworkSection>\n\n          <NetworkSection>\n            <SectionTitle>🌐 For Ethereum Users:</SectionTitle>\n            <Typography variant='body1' sx={{ mb: 2, color: theme.colorBase.textSecondary, fontSize: '1.4rem' }}>\n              Loopring Layer 2 will continue to operate as usual. All core features—including the <Typography component=\"span\" fontWeight={600}>fully decentralized\n              exchange</Typography>—will remain functional.\n            </Typography>\n            <BulletList>\n              <li>All assets, including tokens and NFTs, remain <Typography component=\"span\" fontWeight={600}>safe and intact</Typography> on Layer 2.</li>\n              <li>\n                However, <Typography component=\"span\" fontWeight={600}>all Loopring DeFi features</Typography> will be permanently disabled after the sunset\n                date.\n              </li>\n            </BulletList>\n          </NetworkSection>\n\n          <Typography variant='body1' sx={{ mt: 3, mb: 2, color: theme.colorBase.textSecondary, fontSize: '1.4rem' }}>\n            Thank you to all our users and community members who have supported Loopring DeFi. While\n            this chapter is closing, we remain committed to building and supporting decentralized\n            infrastructure that empowers users and developers alike.\n          </Typography>\n\n          <Typography variant='body1' sx={{ color: theme.colorBase.textSecondary, fontSize: '1.4rem' }}>\n            If you have any questions, please reach out to our support channels.\n          </Typography>\n\n          <Box sx={{ display: 'flex', justifyContent: 'center', mt: 4, mb: 2 }}>\n            <Button\n              variant='contained'\n              color='primary'\n              onClick={handleClose}\n              sx={{\n                minWidth: '200px',\n                height: '40px',\n                borderRadius: '6px',\n                textTransform: 'none',\n                fontWeight: 600,\n                fontSize: '1.1rem',\n              }}\n            >\n              I Know\n            </Button>\n          </Box>\n        </StyledDialogContent>\n      </StyledDialog>\n    )\n  },\n)"
  },
  {
    "path": "packages/component-lib/src/components/modal/ModalPanelBase.tsx",
    "content": "import { Box, Typography } from '@mui/material'\nimport { Trans, WithTranslation } from 'react-i18next'\nimport { DoneIcon, FailedIcon, RefuseIcon, SoursURL } from '@loopring-web/common-resources'\nimport React from 'react'\nimport { useTheme } from '@emotion/react'\nimport { Button } from '../basic-lib'\nimport { ConnectProviders } from '@loopring-web/web3-provider'\n\nexport const InProgressBasic = ({\n  label,\n  providerName,\n  describe,\n}: {\n  describe: JSX.Element\n  label: string\n  providerName: string\n} & WithTranslation) => {\n  const providerDescribe = React.useMemo(() => {\n    switch (providerName) {\n      case ConnectProviders.MetaMask:\n        return (\n          <Trans i18nKey={'labelMetaMaskProcessDescribe'}>\n            {/*Please adding MetaMask to your browser,*/}\n            Please click approve button on MetaMask popup window. When MetaMask dialog is dismiss,\n            please manually click\n            <img\n              alt='MetaMask'\n              style={{ verticalAlign: 'text-bottom' }}\n              src={SoursURL + 'images/MetaMaskPlugIn.png'}\n            />\n            on your browser toolbar.\n          </Trans>\n        )\n      case ConnectProviders.WalletConnect:\n      case ConnectProviders.Coinbase:\n        return (\n          <Trans i18nKey={'labelWalletConnectProcessDescribe2'}>\n            Please click approve on your device.\n          </Trans>\n        )\n    }\n  }, [providerName])\n  return (\n    <Box\n      flex={1}\n      display={'flex'}\n      alignItems={'center'}\n      justifyContent={'space-between'}\n      flexDirection={'column'}\n    >\n      <Typography component={'h3'} variant={'h3'} marginBottom={3}>\n        {label}\n      </Typography>\n      <Typography\n        component={'p'}\n        display={'flex'}\n        alignItems={'center'}\n        flexDirection={'column'}\n        marginBottom={2}\n      >\n        <img\n          className='loading-gif'\n          alt={'loading'}\n          width='60'\n          src={`${SoursURL}images/loading-line.gif`}\n        />\n      </Typography>\n      {describe}\n      <Typography\n        variant={'body2'}\n        color={'textSecondary'}\n        component={'p'}\n        marginTop={3}\n        alignSelf={'flex-start'}\n        paddingX={5}\n      >\n        {providerDescribe}\n      </Typography>\n    </Box>\n  )\n}\n\nexport const CompletedBasic = ({\n  t,\n  label,\n  describe,\n  onClose,\n}: WithTranslation & {\n  label: string\n  describe: JSX.Element\n  onClose: (event: any) => void\n}) => {\n  const theme = useTheme()\n  return (\n    <Box\n      flex={1}\n      display={'flex'}\n      alignItems={'center'}\n      justifyContent={'space-between'}\n      flexDirection={'column'}\n    >\n      <Typography component={'h3'} variant={'h3'} marginBottom={3}>\n        {label}\n      </Typography>\n      <Typography\n        component={'p'}\n        display={'flex'}\n        alignItems={'center'}\n        flexDirection={'column'}\n        marginBottom={2}\n      >\n        <DoneIcon style={{ width: 60, height: 60, color: theme.colorBase.success }} />\n      </Typography>\n      {describe}\n      <Box marginTop={2} alignSelf={'stretch'} paddingX={5}>\n        <Button variant={'contained'} fullWidth size={'medium'} onClick={onClose}>\n          {t('labelClose')}\n        </Button>\n      </Box>\n    </Box>\n  )\n}\n\nexport const FailedBasic = ({\n  onRetry,\n  describe,\n  label,\n  t,\n}: {\n  describe: JSX.Element\n  onRetry: (event: any) => void\n  label: string\n} & WithTranslation) => {\n  return (\n    <Box\n      flex={1}\n      display={'flex'}\n      alignItems={'center'}\n      justifyContent={'space-between'}\n      flexDirection={'column'}\n    >\n      <Typography component={'h3'} variant={'h3'} marginBottom={3}>\n        {label}\n      </Typography>\n      <Typography\n        component={'p'}\n        display={'flex'}\n        alignItems={'center'}\n        flexDirection={'column'}\n        marginBottom={2}\n      >\n        <FailedIcon color={'error'} style={{ width: 60, height: 60 }} />\n      </Typography>\n      {describe}\n      <Box marginTop={2} alignSelf={'stretch'} paddingX={5}>\n        <Button variant={'contained'} fullWidth size={'medium'} onClick={onRetry}>\n          {t('labelRetry')}\n        </Button>\n      </Box>\n    </Box>\n  )\n}\n\nexport const WarningBasic = ({\n  callback,\n  describe,\n  label,\n  t,\n}: {\n  describe: JSX.Element\n  callback: (event: any) => void\n  label: string\n} & WithTranslation) => {\n  return (\n    <Box\n      flex={1}\n      display={'flex'}\n      alignItems={'center'}\n      justifyContent={'space-between'}\n      flexDirection={'column'}\n    >\n      <Typography component={'h3'} variant={'h3'} marginBottom={3}>\n        {label}\n      </Typography>\n      <Typography\n        color={'var(--color-warning)'}\n        component={'p'}\n        display={'flex'}\n        alignItems={'center'}\n        flexDirection={'column'}\n        marginBottom={2}\n      >\n        <RefuseIcon style={{ width: 60, height: 60 }} />\n      </Typography>\n      {describe}\n      <Box marginTop={2} alignSelf={'stretch'} paddingX={5}>\n        <Button variant={'contained'} fullWidth size={'medium'} onClick={callback}>\n          {t('labelRetry')}\n        </Button>\n      </Box>\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/ModalPanels/AccountBase.tsx",
    "content": "import React from 'react'\nimport { Box, Button, Typography } from '@mui/material'\nimport {\n  CopyIcon,\n  ExitIcon,\n  getShortAddr,\n  LinkIcon,\n  SoursURL,\n} from '@loopring-web/common-resources'\nimport { TFunction, Trans } from 'react-i18next'\nimport styled from '@emotion/styled'\nimport { AccountBaseProps } from './Interface'\nimport { ConnectProviders } from '@loopring-web/web3-provider'\n\nconst BoxStyled = styled(Box)`\n  & .MuiButton-root {\n    color: var(--color-text-secondary);\n\n    &:hover {\n      color: var(--color-text-primary);\n    }\n  }\n\n  & .active {\n  }\n\n  & .unlock {\n    svg {\n      color: var(--color-error);\n    }\n  }\n\n  & .lock {\n    svg {\n      color: var(--color-success);\n    }\n  }\n` as typeof Box\n\nexport const AccountBasePanel = ({\n  onDisconnect,\n  accAddress,\n  level,\n  connectName,\n  etherscanUrl,\n  onCopy,\n  hideVIPlevel,\n  t,\n}: AccountBaseProps & { t: TFunction }) => {\n  const addressShort = getShortAddr(accAddress)\n  const etherscanLink = etherscanUrl + 'address/' + accAddress\n  const connectBy = connectName === ConnectProviders.Unknown ? t('labelWrongNetwork') : connectName\n\n  const getImagePath = React.useMemo(() => {\n    const path = SoursURL + `images/vips/${level.toUpperCase().replace('_', '')}`\n    return (\n      <img\n        alt='VIP'\n        style={{ verticalAlign: 'text-bottom', width: '32px', height: '16px' }}\n        src={`${path}.webp`}\n        // srcSet={`${path}.webp 1x, ${path}.png 1x`}\n      />\n    )\n  }, [level])\n\n  return (\n    <Box\n      display={'flex'}\n      flexDirection={'column'}\n      justifyContent={'flex-start'}\n      alignItems={'center'}\n    >\n      <Typography variant={'body2'} color={'textSecondary'} marginTop={3}>\n        <Trans i18nKey='labelConnectBy' tOptions={{ connectBy }}>\n          Connected with{' '}\n          <Typography variant={'body2'} component={'span'}>\n            {connectName}\n          </Typography>\n          .\n        </Trans>\n      </Typography>\n      <Typography\n        marginTop={1}\n        display={'flex'}\n        alignItems={'center'}\n        justifyContent={'flex-start'}\n      >\n        <Typography paddingRight={1} component={'span'} fontSize={'3rem'}>\n          {addressShort}\n        </Typography>\n        {!hideVIPlevel && level && getImagePath}\n      </Typography>\n\n      <BoxStyled\n        component={'div'}\n        display={'flex'}\n        alignItems={'center'}\n        justifyContent={'space-between'}\n        marginTop={1}\n        alignSelf={'stretch'}\n      >\n        <Button\n          target={'_blank'}\n          href={etherscanLink}\n          rel='noopener noreferrer'\n          startIcon={<LinkIcon fontSize={'small'} />}\n        >\n          <Typography variant={'body2'} marginTop={1 / 2}>\n            {'Etherscan'}\n          </Typography>\n        </Button>\n        <Button\n          startIcon={<CopyIcon fontSize={'small'} />}\n          onClick={() => {\n            if (onCopy) onCopy()\n          }}\n        >\n          <Typography variant={'body2'} marginTop={1 / 2}>\n            {' '}\n            {t('labelCopyClipBoard')}{' '}\n          </Typography>\n        </Button>\n        <Button\n          startIcon={<ExitIcon fontSize={'small'} />}\n          onClick={() => {\n            if (onDisconnect) onDisconnect()\n          }}\n        >\n          <Typography variant={'body2'} marginTop={1 / 2}>\n            {' '}\n            {t('labelDisconnect')}{' '}\n          </Typography>\n        </Button>\n      </BoxStyled>\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/ModalPanels/AddAsset.tsx",
    "content": "import { Box, Typography } from '@mui/material'\nimport { MenuBtnStyled } from '../../styled'\nimport { AddAssetProps } from './Interface'\nimport { useTranslation } from 'react-i18next'\nimport {\n  AddAssetList,\n  AnotherIcon,\n  BackIcon,\n  CardIcon,\n  ExchangeAIcon,\n  IncomingIcon,\n  L1L2_NAME_DEFINED,\n  L1l2Icon,\n  L2l2Icon,\n  MapChainId,\n  OutputIcon,\n} from '@loopring-web/common-resources'\nimport { useSettings, useToggle } from '../../../stores'\n\nconst IconItem = ({ svgIcon }: { svgIcon: string }) => {\n  switch (svgIcon) {\n    case 'IncomingIcon':\n      return <IncomingIcon color={'inherit'} fontSize={'inherit'} sx={{marginRight: 1}}/>\n    case 'CardIcon':\n      return <CardIcon color={'inherit'} fontSize={'inherit'} sx={{marginRight: 1}}/>\n    case 'L2l2Icon':\n      return <L2l2Icon color={'inherit'} fontSize={'inherit'} sx={{marginRight: 1}}/>\n    case 'L1l2Icon':\n      return <L1l2Icon color={'inherit'} fontSize={'inherit'} sx={{marginRight: 1}}/>\n    case 'ExchangeAIcon':\n      return <ExchangeAIcon color={'inherit'} fontSize={'inherit'} sx={{marginRight: 1}}/>\n    case 'OutputIcon':\n      return <OutputIcon color={'inherit'} fontSize={'inherit'} sx={{marginRight: 1}}/>\n    case 'AnotherIcon':\n      return <AnotherIcon color={'inherit'} fontSize={'inherit'} sx={{marginRight: 1}}/>\n  }\n}\nexport const AddAsset = ({\n  symbol,\n  addAssetList,\n  allowTrade,\n  isNewAccount = false,\n  disbaleList\n}: AddAssetProps) => {\n  const { t } = useTranslation('common')\n  const { isMobile, defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const {\n    toggle: { receive },\n  } = useToggle()\n\n  const isLp: boolean = symbol?.startsWith('LP-') ?? false\n  const lpDisaList = [AddAssetList.BuyWithCard.key, AddAssetList.FromExchange.key]\n  return (\n    <Box\n      flex={1}\n      display={'flex'}\n      alignItems={'center'}\n      justifyContent={'space-between'}\n      flexDirection={'column'}\n      width={'var(--modal-width)'}\n    >\n      <Typography\n        component={'h3'}\n        variant={isMobile ? 'h4' : 'h3'}\n        whiteSpace={'pre'}\n        marginBottom={3}\n        marginTop={-1}\n      >\n        {isNewAccount\n          ? t('labelAddAssetTitleActive', {\n              l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n              l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n              l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n              ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n            })\n          : t('labelAddAssetTitle', {\n              symbol,\n              l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n              l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n              l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n              ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n            })}\n      </Typography>\n      <Box\n        display={'flex'}\n        flexDirection={'column'}\n        justifyContent={'center'}\n        flex={1}\n        alignItems={'stretch'}\n        alignSelf={'stretch'}\n        className='modalContent'\n        paddingX={isMobile ? 4 : 5}\n        paddingBottom={4}\n      >\n        <Typography component={'p'} variant={'body1'} color={'textSecondary'} marginBottom={1}>\n          {t('labelAddAssetHowto', {\n            loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n            l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n            l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n            ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n          })}\n        </Typography>\n        <Box flex={1} flexDirection={'column'}>\n          {addAssetList.reduce((prev, item) => {\n            if (\n              !symbol ||\n              (item.key == 'FromAnotherNet' && receive['orbiter']?.includes(symbol)) ||\n              (item.key == 'FromExchange' && receive['layerSwap']?.includes(symbol)) ||\n              !['FromAnotherNet', 'FromExchange'].includes(item.key)\n            ) {\n              prev.push(\n                <Box key={item.key} marginTop={1.5}>\n                  <MenuBtnStyled\n                    variant={'outlined'}\n                    size={'large'}\n                    className={`addAsset ${isMobile ? 'isMobile' : ''}`}\n                    fullWidth\n                    disabled={\n                      !!(item.enableKey && allowTrade[item.enableKey]?.enable === false) ||\n                      (isLp && lpDisaList.includes(item.key)) ||\n                      disbaleList?.includes(item.key)\n                    }\n                    endIcon={<BackIcon sx={{ transform: 'rotate(180deg)' }} />}\n                    onClick={(e) => {\n                      item.handleSelect(e)\n                    }}\n                  >\n                    <Typography\n                      component={'span'}\n                      variant={'inherit'}\n                      color={'inherit'}\n                      display={'inline-flex'}\n                      alignItems={'center'}\n                      lineHeight={'1.2em'}\n                      sx={{\n                        textIndent: 0,\n                        textAlign: 'left',\n                      }}\n                    >\n                      <>{IconItem({ svgIcon: item.svgIcon })}</>\n                      {t('label' + item.key, {\n                        l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                        loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                        l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                        l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                        ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                      })}\n                    </Typography>\n                  </MenuBtnStyled>\n                </Box>,\n              )\n            }\n            return prev\n          }, [] as JSX.Element[])}\n        </Box>\n      </Box>\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/ModalPanels/BasicPanel.tsx",
    "content": "import { Box, Link, Typography, Divider } from '@mui/material'\nimport { TFunction, Trans, withTranslation } from 'react-i18next'\nimport {\n  Account,\n  DoneIcon,\n  FailedIcon,\n  L1L2_NAME_DEFINED,\n  LinkIcon,\n  LoadingIcon,\n  MapChainId,\n  RefuseIcon,\n  SoursURL,\n  SubmitIcon,\n} from '@loopring-web/common-resources'\nimport React from 'react'\n\nimport { Button, TextareaAutosizeStyled } from '../../basic-lib'\nimport { RESULT_INFO } from '@loopring-web/loopring-sdk'\nimport { ConnectProviders } from '@loopring-web/web3-provider'\nimport { DropdownIconStyled } from '../../tradePanel'\nimport { useSettings } from '../../../stores'\nimport { sanitize } from 'dompurify'\nimport styled from '@emotion/styled'\nimport { TransErrorHelp } from '../../block'\n\nexport enum IconType {\n  LoadingIcon,\n  DoneIcon,\n  FailedIcon,\n  RefuseIcon,\n  SubmitIcon,\n  PendingIcon,\n}\n\nexport interface PanelProps {\n  title?: string\n  iconType?: IconType\n  value?: number | string\n  symbol?: string\n  hash?: string\n  info?: any\n  describe1?: any\n  describe2?: any\n  chainInfos?: any\n  txCheck?: {\n    route: string\n    callback: (e?: any) => void\n  }\n  to?: string\n  btnInfo?: {\n    btnTxt?: any\n    param?: { [key: string]: string }\n    callback?: (e?: any) => void\n  }\n  providerName?: ConnectProviders | 'unknown' | undefined\n  link?: {\n    name: string\n    url: string\n  }\n  t: TFunction\n  account?: Account\n  etherscanBaseUrl?: string\n  patch?: any\n  error?: RESULT_INFO\n  errorOptions?: any\n  updateDepositHash?: any\n  className?: string\n  legacyTitleStyle?: boolean\n\n  [key: string]: any\n}\n\nconst BoxStyle = styled(Box)`\n  &.btrade-panel {\n    .status-icon {\n      margin-top: ${({ theme }) => theme.unit * 4}px;\n    }\n\n    .content-main {\n      align-self: stretch;\n\n      & > div {\n        align-self: stretch;\n      }\n    }\n  }\n  & {\n    height: inherit;\n    .content-main {\n      overflow: auto;\n      align-self: stretch;\n      & > div {\n        align-self: stretch;\n      }\n    }\n  }\n`\n\nexport const BasicPanel = withTranslation('common', { withRef: true })(\n  ({\n    t,\n    title,\n    iconType,\n    describe1,\n    describe2,\n    txCheck,\n    btnInfo,\n    providerName,\n    error,\n    errorOptions,\n    className,\n    link,\n    legacyTitleStyle = true,\n  }: PanelProps) => {\n    const isLoading = iconType === IconType.LoadingIcon\n\n    const size = isLoading ? 60 : 60\n\n    // const marginTopIcon = isLoading ? 0 : 8;\n\n    const marginTopDescribe1 = isLoading ? 2 : 3\n\n    // const marginProvider = 9;\n    // const marginTopBtn = link ? 8 : 11;\n\n    const marginToplink = 2\n\n    const iconDiv = React.useMemo(() => {\n      switch (iconType) {\n        case IconType.LoadingIcon:\n          return (\n            <img\n              className='loading-gif'\n              alt={'loading'}\n              width={size}\n              src={`${SoursURL}images/loading-line.gif`}\n            />\n          )\n        case IconType.FailedIcon:\n          return <FailedIcon style={{ color: 'var(--color-error)', width: size, height: size }} />\n        case IconType.SubmitIcon:\n          return <SubmitIcon color={'primary'} style={{ width: size, height: size }} />\n        case IconType.RefuseIcon:\n          return (\n            <RefuseIcon\n              style={{\n                color: 'var(--color-warning)',\n                width: size,\n                height: size,\n              }}\n            />\n          )\n\n        case IconType.DoneIcon:\n          return (\n            <DoneIcon\n              style={{\n                color: 'var(--color-success)',\n                width: size,\n                height: size,\n              }}\n            />\n          )\n        case IconType.PendingIcon:\n          return <LoadingIcon color={'primary'} style={{ width: size, height: size }} />\n      }\n    }, [iconType, size])\n\n    const providerDescribe = React.useMemo(() => {\n      if (providerName) {\n        switch (providerName) {\n          case ConnectProviders.MetaMask:\n          case ConnectProviders.Coinbase:\n            return (\n              <Trans\n                i18nKey={'labelProviderCommonProcessDescribe'}\n                tOptions={{ name: providerName }}\n              >\n                Please click approve button on {providerName} popup window. When\n                {providerName} dialog is dismiss, please manually click\n                <img\n                  alt='MetaMask'\n                  style={{ verticalAlign: 'text-bottom' }}\n                  src={SoursURL + `images/${providerName}PlugIn.png`}\n                />\n                on your browser toolbar.\n              </Trans>\n            )\n          case ConnectProviders.WalletConnect:\n            return (\n              <Trans i18nKey={'labelWalletConnectProcessDescribe2'}>\n                Please click approve on your device.\n              </Trans>\n            )\n          default:\n            break\n        }\n      }\n      return <></>\n    }, [providerName])\n    const [dropdownStatus, setDropdownStatus] = React.useState<'up' | 'down'>('down')\n    const { defaultNetwork, isMobile } = useSettings()\n    const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n\n    return (\n      <>\n        <Box\n          display={'flex'}\n          flexDirection={'column'}\n          alignItems={'flex-start'}\n          alignSelf={'stretch'}\n          marginTop={-4}\n          justifyContent={'stretch'}\n        >\n          {legacyTitleStyle ? (\n            <Typography\n              textAlign={'center'}\n              width={'100%'}\n              marginTop={5}\n              component={'h3'}\n              variant={isMobile ? 'h4' : 'h3'}\n              whiteSpace={'pre'}\n            >\n              {t(title as string, {\n                layer2: L1L2_NAME_DEFINED[network].layer2,\n                l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n              })}\n            </Typography>\n          ) : (\n            <>\n              <Typography\n                display={'flex'}\n                flexDirection={'row'}\n                component={'header'}\n                alignItems={'center'}\n                height={'var(--toolbar-row-height)'}\n                paddingX={3}\n              >\n                {typeof title !== 'string' ? (\n                  title\n                ) : (\n                  <Typography component={'span'} display={'inline-flex'} color={'textPrimary'}>\n                    {t(title, {\n                      layer2: L1L2_NAME_DEFINED[network].layer2,\n                      l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                      loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                      l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                      l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                      ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                      loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n                    })}\n                  </Typography>\n                )}\n              </Typography>\n              <Divider style={{ marginTop: '-1px', width: '100%' }} />\n            </>\n          )}\n        </Box>\n        <BoxStyle\n          flex={1}\n          display={'flex'}\n          alignItems={'center'}\n          flexDirection={'column'}\n          paddingBottom={4}\n          width={'100%'}\n          className={className}\n        >\n          <Box\n            flex={1}\n            display={'flex'}\n            flexDirection={'column'}\n            alignItems={'center'}\n            justifyContent={'space-between'}\n            className={'content-main'}\n          >\n            <Box\n              display={'flex'}\n              flexDirection={'column'}\n              alignItems={'center'}\n              justifyContent={'center'}\n              flex={1}\n            >\n              <Typography\n                component={'div'}\n                display={'flex'}\n                alignItems={'flex-start'}\n                flexDirection={'column'}\n                className={'status-icon'}\n              >\n                {iconDiv}\n              </Typography>\n              {describe1 && (\n                <Box display={'flex'} marginTop={marginTopDescribe1} alignItems={'flex-center'}>\n                  {iconType === IconType.FailedIcon ? (\n                    <Typography\n                      component={'span'}\n                      marginX={3}\n                      whiteSpace={'pre-line'}\n                      variant={'body1'}\n                      marginBottom={2}\n                      alignSelf={'flex-center'}\n                      paddingX={1}\n                      marginY={1}\n                      textAlign={'center'}\n                    >\n                      {error ? (\n                        <Typography\n                          color={'var(--color-error)'}\n                          component={'span'}\n                          variant={'inherit'}\n                          display={'inline-flex'}\n                          alignItems={'center'}\n                          onClick={() =>\n                            setDropdownStatus((prev) => (prev === 'up' ? 'down' : 'up'))\n                          }\n                        >\n                          <TransErrorHelp error={error} options={errorOptions} />\n                          <DropdownIconStyled status={dropdownStatus} fontSize={'medium'} />\n                        </Typography>\n                      ) : typeof describe1 === 'string' ? (\n                        <Typography\n                          color={'var(--color-error)'}\n                          component={'span'}\n                          variant={'inherit'}\n                          display={'inline-flex'}\n                          onClick={() =>\n                            setDropdownStatus((prev) => (prev === 'up' ? 'down' : 'up'))\n                          }\n                          dangerouslySetInnerHTML={{\n                            __html: sanitize(describe1),\n                          }}\n                        />\n                      ) : (\n                        <>{describe1}</>\n                      )}\n                      {dropdownStatus === 'up' && (\n                        <TextareaAutosizeStyled\n                          aria-label='Error Description'\n                          minRows={5}\n                          style={{ maxHeight: '90px', overflow: 'auto' }}\n                          disabled={true}\n                          value={`${JSON.stringify(error)}}`}\n                        />\n                      )}\n                    </Typography>\n                  ) : typeof describe1 === 'string' ? (\n                    <Typography\n                      component={'span'}\n                      variant={'h5'}\n                      whiteSpace={'pre-line'}\n                      textAlign={'center'}\n                      color={\n                        iconType === IconType.SubmitIcon || iconType === IconType.DoneIcon\n                          ? 'var(--color-success)'\n                          : iconType === IconType.RefuseIcon\n                          ? 'var(--color-error)'\n                          : 'textPrimary'\n                      }\n                      marginTop={0}\n                      alignSelf={'flex-center'}\n                      paddingX={2}\n                      sx={{ wordBreak: 'break-all' }}\n                      dangerouslySetInnerHTML={{\n                        __html: sanitize(describe1),\n                      }}\n                    />\n                  ) : (\n                    <Typography\n                      component={'span'}\n                      variant={'h5'}\n                      whiteSpace={'pre-line'}\n                      textAlign={'center'}\n                      color={\n                        iconType === IconType.SubmitIcon || iconType === IconType.DoneIcon\n                          ? 'var(--color-success)'\n                          : iconType === IconType.RefuseIcon\n                          ? 'var(--color-error)'\n                          : 'textPrimary'\n                      }\n                      marginTop={0}\n                      alignSelf={'flex-center'}\n                      paddingX={2}\n                    >\n                      {describe1}\n                    </Typography>\n                  )}\n\n                  {txCheck && (\n                    <Link\n                      target='_blank'\n                      rel='noopener noreferrer'\n                      href={txCheck.route}\n                      display={'inline-block'}\n                      marginTop={1 / 4}\n                    >\n                      <LinkIcon\n                        color={'primary'}\n                        fontSize={'small'}\n                        style={{ verticalAlign: 'middle' }}\n                      />\n                    </Link>\n                  )}\n                </Box>\n              )}\n              {!!describe2 && <>{describe2}</>}\n            </Box>\n            {providerName && (\n              <Typography\n                variant={'body2'}\n                color={'textSecondary'}\n                component={'span'}\n                paddingX={5}\n                alignSelf={'flex-start'}\n              >\n                {providerDescribe}\n              </Typography>\n            )}\n          </Box>\n          {btnInfo && (\n            <Box\n              width={'100%'}\n              display={'flex'}\n              flexDirection={'column'}\n              alignItems={'center'}\n              justifyContent={'flex-end'}\n            >\n              <Box alignSelf={'stretch'} paddingX={5}>\n                <Button\n                  variant={'contained'}\n                  fullWidth\n                  size={'medium'}\n                  onClick={(e?: any) => {\n                    if (btnInfo?.callback) {\n                      btnInfo.callback(e)\n                    }\n                  }}\n                >\n                  {t(btnInfo?.btnTxt, { ...btnInfo?.param })}\n                </Button>\n              </Box>\n\n              {link && (\n                <Box marginTop={marginToplink} alignSelf={'flex-center'} paddingX={0}>\n                  <Link\n                    variant={'body1'}\n                    display={'inline-flex'}\n                    alignItems={'center'}\n                    color={'secondary'}\n                    href={link.url}\n                    target='_blank'\n                    rel='noopener noreferrer'\n                  >\n                    {link.name}\n                    {['Txn Hash', 'Banxa Status'].includes(link.name) && (\n                      <Typography\n                        component={'span'}\n                        paddingLeft={1}\n                        color={'secondary'}\n                        display={'inline-flex'}\n                        alignItems={'center'}\n                      >\n                        <LinkIcon color={'inherit'} fontSize={'medium'} />\n                      </Typography>\n                    )}\n                  </Link>\n                </Box>\n              )}\n            </Box>\n          )}\n        </BoxStyle>\n      </>\n    )\n  },\n)\n\nexport const ConnectBase = (props: PanelProps) => {\n  const propsPatch = {\n    title: 'labelConnectWallet',\n  }\n  return <BasicPanel {...propsPatch} {...props} />\n}\n\nexport const CreateAccountBase = (props: PanelProps) => {\n  const propsPatch = {\n    title: 'labelCreateAccount',\n  }\n  return <BasicPanel {...propsPatch} {...props} />\n}\n\nexport const RetrieveAccountBase = (props: PanelProps) => {\n  const propsPatch = {\n    title: 'labelRetrieveAccount',\n  }\n  return <BasicPanel {...propsPatch} {...props} />\n}\n\nexport const UnlockAccountBase = (props: PanelProps) => {\n  const propsPatch = {\n    ...props,\n    title: 'labelUpdateAccount',\n  }\n\n  return <BasicPanel {...propsPatch} />\n}\n\nexport const UpdateAccountBase = (props: PanelProps) => {\n  const propsPatch = {\n    title: props.patch?.isReset ? 'labelResetAccount' : 'labelUpdateAccount',\n  }\n  return <BasicPanel {...propsPatch} {...props} />\n}\n\nexport const ExportAccountBase = (props: PanelProps) => {\n  const propsPatch = {\n    title: 'labelExportAccount',\n  }\n  return <BasicPanel {...propsPatch} {...props} />\n}\n\nexport const DepositBase = (props: PanelProps) => {\n  return <BasicPanel title={'labelL1toL2'} {...props} />\n}\n\nexport const MintBase = (props: PanelProps) => {\n  const propsPatch = {\n    title: 'labelNFTMint',\n  }\n  return <BasicPanel {...props} {...propsPatch} />\n}\n\nexport const DeployBase = (props: PanelProps) => {\n  const propsPatch = {\n    title: 'labelNFTDeployTitle',\n  }\n  return <BasicPanel {...props} {...propsPatch} />\n}\n\nexport const ForceWithdrawBase = (props: PanelProps) => {\n  const propsPatch = {\n    title: 'labelForceWithdrawTitle',\n  }\n  return <BasicPanel {...props} {...propsPatch} />\n}\nexport const ClaimWithdrawBase = (props: PanelProps) => {\n  const propsPatch = {\n    title: 'labelClaimWithdrawTitle',\n  }\n  return <BasicPanel {...props} {...propsPatch} />\n}\n\nexport const TransferBase = (props: PanelProps) => {\n  const propsPatch = {\n    title: 'labelL2toL2Title',\n  }\n  return <BasicPanel {...propsPatch} {...props} />\n}\n\nexport const WithdrawBase = (props: PanelProps) => {\n  const propsPatch = {\n    title: 'labelL2ToL1Title',\n  }\n  return <BasicPanel {...propsPatch} {...props} />\n}\n\nexport const AmmBase = (props: PanelProps) => {\n  return <BasicPanel title={'labelAMMTitle'} {...props} />\n}\n\nexport const DualBase = (props: PanelProps & { showTitle: boolean }) => {\n  const { showTitle } = props\n  return <BasicPanel title={showTitle ? 'labelDualTitle' : undefined} {...props} />\n}\n\nexport const VaultJoinBase = (\n  props: PanelProps & {\n    title: string\n  },\n) => {\n  // const { showTitle, title } = props\n  return (\n    <BasicPanel\n      className={'vaultJoin'}\n      {...{ title: props.title ?? 'labelValueJoinTitle', ...props }}\n      legacyTitleStyle={false}\n    />\n  )\n}\n\nexport const VaultExitBase = (props: PanelProps & { showTitle: boolean }) => {\n  const { showTitle } = props\n  return (\n    <BasicPanel\n      className={'vaultExit'}\n      title={showTitle ? 'labelVaultExitTitle' : undefined}\n      legacyTitleStyle={false}\n      {...props}\n    />\n  )\n}\n\nexport const VaultBorrowBase = (\n  props: PanelProps & {\n    showTitle: boolean\n  },\n) => {\n  const { showTitle } = props\n  return (\n    <BasicPanel\n      className={'vaultBorrow'}\n      title={showTitle ? 'labelVaultBorrowTitle' : undefined}\n      legacyTitleStyle={false}\n      {...props}\n    />\n  )\n}\n\nexport const VaultRepayBase = (\n  props: PanelProps & {\n    showTitle: boolean\n  },\n) => {\n  const { showTitle } = props\n  return (\n    <BasicPanel\n      className={'vaultRepay'}\n      title={showTitle ? 'labelVaultRepayTitle' : undefined}\n      legacyTitleStyle={false}\n      {...props}\n    />\n  )\n}\n\nexport const VaultTradeBase = (props: PanelProps & { showTitle: boolean }) => {\n  const { showTitle } = props\n  return (\n    <BasicPanel\n      className={'vaultTrade'}\n      title={showTitle ? 'labelVaultTradeTitle' : undefined}\n      legacyTitleStyle={false}\n      {...props}\n    />\n  )\n}\nexport const VaultDustCollectorBase = (\n  props: PanelProps & {\n    showTitle: boolean\n  },\n) => {\n  const { showTitle } = props\n  return (\n    <BasicPanel\n      title={showTitle ? 'Dust Collector' : undefined}\n      legacyTitleStyle={false}\n      {...props}\n    />\n  )\n}\nexport const RedPacketBase = (props: PanelProps) => {\n  const propsPatch = {\n    title: 'labelSendRedPacketTitle',\n  }\n  return <BasicPanel {...propsPatch} {...props} />\n}\n\nexport const RedPacketOpenBase = (props: PanelProps) => {\n  const propsPatch = {\n    title: 'labelRedPacketOpen',\n  }\n  return <BasicPanel {...propsPatch} {...props} />\n}\n\nexport const BtradeBase = (props: PanelProps) => {\n  const propsPatch = {\n    title: 'labelBtradeTitle',\n  }\n\n  return <BasicPanel className={'btrade-panel'} {...props} {...propsPatch} />\n}\n\nexport const TaikoFarmingMintBase = (props: PanelProps) => {\n  return <BasicPanel title={'Mint lrTAIKO'} {...props} />\n}\n\nexport const TaikoFarmingStakeBase = (props: PanelProps) => {\n  return <BasicPanel title={'Taiko Farming'} {...props} />\n}\n\nexport const TaikoFarmingRedeemBase = (props: PanelProps) => {\n  return <BasicPanel title={'Redeem TAIKO'} {...props} />\n}\n\nexport const TransferToTaikoBase = (props: PanelProps) => {\n  return <BasicPanel {...props} />\n}"
  },
  {
    "path": "packages/component-lib/src/components/modal/ModalPanels/BridgePanel.tsx",
    "content": "import { withTranslation, WithTranslation } from 'react-i18next'\nimport { AnotherIcon, MapChainId } from '@loopring-web/common-resources'\nimport React from 'react'\nimport { useSettings } from '../../../stores'\nimport { Box, Typography } from '@mui/material'\nimport { ChevronRight } from '@mui/icons-material'\nimport { SpaceBetweenBox } from '../../../components/basic-lib'\n\n\nexport interface BridgeProps {\n  onClickEthereum: () => void\n}\n\nexport const BridgePanel = withTranslation('common')(\n  ({\n    onClickEthereum,\n  }: BridgeProps) => {\n    return (\n      <Box\n        height={'auto'}\n        width={'var(--modal-width)'}\n        display={'flex'}\n        flexDirection={'column'}\n        px={3}\n        pt={2}\n        pb={4}\n      >\n        <Typography fontSize={24}>Bridge</Typography>\n\n        <Typography variant='body2' mt={7}>\n          To other networks\n        </Typography>\n\n        <SpaceBetweenBox\n          onClick={() => onClickEthereum()}\n          height={'64px'}\n          border={'1px solid var(--color-border)'}\n          borderRadius={'4px'}\n          alignItems={'center'}\n          justifyContent={'space-between'}\n          sx={{ cursor: 'pointer', px: 2, mt: 2 }}\n          leftNode={\n            <Box display='flex' alignItems='center'>\n              <AnotherIcon className='custom-size' sx={{ fontSize: '24px' }}/>\n              <Typography ml={1}>To Ethereum</Typography>\n            </Box>\n          }\n          rightNode={<ChevronRight />}\n        />\n      </Box>\n    )\n  }\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/ModalPanels/CheckActiveStatus.tsx",
    "content": "import {\n  EmptyValueTag,\n  L1L2_NAME_DEFINED,\n  MapChainId,\n  RowConfig,\n} from '@loopring-web/common-resources'\nimport { useTranslation } from 'react-i18next'\nimport { Box, Button, Typography } from '@mui/material'\nimport { useSettings } from '../../../stores'\nimport { CheckActiveStatusProps } from './Interface'\nimport { useTheme } from '@emotion/react'\nimport { DepositRecorder } from './DepositRecorder'\nimport styled from '@emotion/styled'\n\nconst BoxStyle = styled(Box)`\n  .modalContent {\n    .depositRecord {\n      width: 100%;\n      padding: 0 ${({ theme }) => theme.unit}px;\n      background: initial;\n    }\n  }\n`\nexport const CheckActiveStatus = ({\n  account,\n  goSend,\n  goDisconnect,\n  isFeeNotEnough,\n  // isDepositing = false,\n  walletMap,\n  knowDisable,\n  know,\n  onIKnowClick,\n  chainInfos,\n  accAddress,\n  clearDepositHash,\n  chargeFeeTokenList = [],\n  ...props\n}: CheckActiveStatusProps) => {\n  const { t } = useTranslation('common')\n  const theme = useTheme()\n  const { isMobile, defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n\n  return (\n    <BoxStyle\n      flex={1}\n      display={'flex'}\n      alignItems={'center'}\n      flexDirection={'column'}\n      // paddingBottom={4}\n      paddingBottom={4}\n      width={'100%'}\n    >\n      {!know ? (\n        <>\n          <Typography\n            component={'h3'}\n            variant={isMobile ? 'h4' : 'h3'}\n            whiteSpace={'pre'}\n            marginBottom={3}\n            marginTop={-1}\n          >\n            {t('labelActiveAccountTitle', {\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n            })}\n          </Typography>\n          <Box\n            display={'flex'}\n            flexDirection={'column'}\n            justifyContent={'center'}\n            flex={1}\n            alignItems={'stretch'}\n            alignSelf={'stretch'}\n            className='modalContent'\n            paddingX={5 / 2}\n          >\n            <>\n              {chainInfos &&\n              accAddress &&\n              chainInfos?.depositHashes &&\n              chainInfos?.depositHashes[accAddress] &&\n              chainInfos?.depositHashes[accAddress].length &&\n              clearDepositHash ? (\n                <>\n                  <Typography\n                    variant={'body1'}\n                    color={'var(--color-warning)'}\n                    textAlign={'center'}\n                    marginBottom={2}\n                  >\n                    {t('labelDepositWaiting')}\n                  </Typography>\n                  <DepositRecorder\n                    {...({ ...props } as any)}\n                    accAddress={accAddress}\n                    chainInfos={chainInfos}\n                    // clear={clearDepositHash}\n                    t={t}\n                  />\n                  <Box marginTop={3}>\n                    <Button\n                      size={'large'}\n                      variant={'contained'}\n                      fullWidth\n                      disabled={knowDisable}\n                      onClick={onIKnowClick}\n                    >\n                      {t(\n                        isFeeNotEnough.isFeeNotEnough\n                          ? 'labelAddAssetGateBtn'\n                          : 'labelActiveLayer2Btn',\n                        {\n                          l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                          loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                          l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                          l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                          ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                        },\n                      )}\n                    </Button>\n                  </Box>\n                </>\n              ) : (\n                <>\n                  <Typography variant={'body1'} color={'textSecondary'} whiteSpace={'pre-line'}>\n                    {t('labelBenefitL2', {\n                      l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                      loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                      l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                      l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                      ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                    })}\n                  </Typography>\n                  <Box marginTop={3}>\n                    <Button\n                      size={'large'}\n                      variant={'contained'}\n                      fullWidth\n                      disabled={knowDisable}\n                      onClick={onIKnowClick}\n                    >\n                      {t('labelIKnow')}\n                    </Button>\n                  </Box>\n                </>\n              )}\n            </>\n          </Box>\n        </>\n      ) : (\n        <>\n          <Typography\n            component={'h3'}\n            variant={isMobile ? 'h4' : 'h3'}\n            whiteSpace={'pre'}\n            marginTop={-1}\n          >\n            {t('labelActiveAccountTitle', {\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n            })}\n          </Typography>\n          <Box\n            display={'flex'}\n            flexDirection={'column'}\n            justifyContent={'center'}\n            flex={1}\n            alignItems={'stretch'}\n            alignSelf={'stretch'}\n            className='modalContent'\n            paddingX={5 / 2}\n          >\n            {account.isContract ? (\n              <>\n                <Typography\n                  component={'p'}\n                  variant={'h5'}\n                  color={'error'}\n                  marginTop={1}\n                  textAlign={'center'}\n                >\n                  {t('labelActivatedAccountNotSupport', {\n                    l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                    loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                    l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                    l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                    ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                  })}\n                </Typography>\n                <Typography\n                  component={'p'}\n                  variant={'body1'}\n                  color={'textPrimary'}\n                  marginTop={1}\n                  marginBottom={2}\n                >\n                  {t('labelActivatedAccountNotSupportDes', {\n                    loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                    l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                    l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                    ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                  })}\n                </Typography>\n                <Button size={'large'} fullWidth onClick={goDisconnect} variant={'contained'}>\n                  {t('labelDisconnect')}\n                </Button>\n              </>\n            ) : (\n              <>\n                {isFeeNotEnough.isOnLoading ? (\n                  <Typography\n                    color={'var(--color-warning)'}\n                    component={'p'}\n                    variant={'body1'}\n                    marginTop={2}\n                  >\n                    {t('labelFeeCalculating')}\n                  </Typography>\n                ) : isFeeNotEnough.isFeeNotEnough ? (\n                  <></>\n                ) : (\n                  // <Typography\n                  //   color={\"var(--color-warning)\"}\n                  //   component={\"p\"}\n                  //   variant={\"body1\"}\n                  //   marginTop={2}\n                  // >\n                  //   {t(\"labelNotBalancePayForActive\")}\n                  // </Typography>\n                  <Typography color={'textPrimary'} component={'p'} variant={'body1'} marginTop={2}>\n                    {t('labelEnoughBalancePayForActive', {\n                      l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                      loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                      l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                      l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                      ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                    })}\n                  </Typography>\n                )}\n                <Typography\n                  component={'p'}\n                  variant={'body1'}\n                  color={'textPrimary'}\n                  marginTop={2}\n                  marginBottom={1}\n                >\n                  {t('labelActivatedAccountChargeFeeList', {\n                    loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                  })}\n                </Typography>\n                <Box marginTop={1}>\n                  <Typography\n                    height={RowConfig.rowHeight}\n                    color={'var(--color-text-third)'}\n                    display={'flex'}\n                    textAlign={'center'}\n                  >\n                    <Typography\n                      color={'inherit'}\n                      variant={'inherit'}\n                      width={'30%'}\n                      textAlign={'left'}\n                    >\n                      {t('labelToken')}\n                    </Typography>\n                    <Typography color={'inherit'} variant={'inherit'} width={'30%'}>\n                      {t('labelMinRequirement')}\n                    </Typography>\n                    <Typography color={'inherit'} variant={'inherit'} width={'40%'}>\n                      {t('labelAvailability')}\n                    </Typography>\n                  </Typography>\n                  {chargeFeeTokenList?.map((item, index) => (\n                    <Typography\n                      key={index + item.belong}\n                      height={theme.unit * 4}\n                      color={'textPrimary'}\n                      display={'flex'}\n                      textAlign={'center'}\n                    >\n                      <Typography\n                        variant={'inherit'}\n                        color={'inherit'}\n                        width={'30%'}\n                        textAlign={'left'}\n                      >\n                        {item.belong}\n                      </Typography>\n                      <Typography variant={'inherit'} color={'inherit'} width={'30%'}>\n                        {item.fee}\n                      </Typography>\n                      <Typography variant={'inherit'} color={'inherit'} width={'40%'}>\n                        {walletMap && walletMap[item.belong]\n                          ? walletMap[item.belong].count\n                          : EmptyValueTag}\n                      </Typography>\n                    </Typography>\n                  ))}\n                </Box>\n\n                {isFeeNotEnough.isOnLoading ? (\n                  <Typography\n                    color={'var(--color-warning)'}\n                    component={'p'}\n                    variant={'body1'}\n                    marginTop={2}\n                  >\n                    {t('labelFeeCalculating')}\n                  </Typography>\n                ) : (\n                  isFeeNotEnough.isFeeNotEnough && (\n                    <Typography\n                      color={'var(--color-text-third)'}\n                      component={'p'}\n                      variant={'body2'}\n                      marginTop={2}\n                    >\n                      {t('labelHaveInProcessingL1toL2', {\n                        l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                        loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                        l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                        l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                        ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                      })}\n                    </Typography>\n                  )\n                )}\n                <Box marginTop={1}>\n                  <Button size={'large'} variant={'contained'} fullWidth onClick={goSend}>\n                    {t('labelAddAssetGateBtn')}\n                  </Button>\n                </Box>\n              </>\n            )}\n          </Box>\n        </>\n      )}\n    </BoxStyle>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/ModalPanels/CheckImportCollection.tsx",
    "content": "import { BackIcon, DropDownIcon, getShortAddr } from '@loopring-web/common-resources'\nimport { useTranslation } from 'react-i18next'\nimport { Box, ListItemText, Typography } from '@mui/material'\nimport { useSettings } from '../../../stores'\nimport { CheckImportCollectionProps } from './Interface'\nimport React from 'react'\nimport { Button, MenuItem, TextField } from '../../basic-lib'\n\nexport const CheckImportCollection = ({\n  // account,\n  value,\n  onChange,\n  loading = false,\n  contractList = [],\n  disabled = false,\n  onClick,\n}: CheckImportCollectionProps) => {\n  const { t } = useTranslation('common')\n\n  const { isMobile } = useSettings()\n  // const disabled = () => {\n  //   return gDisabled || !tradeData.tokenAddress || !tradeData.collectionMeta;\n  // };\n  return (\n    <Box\n      flex={1}\n      display={'flex'}\n      alignItems={'center'}\n      flexDirection={'column'}\n      paddingBottom={4}\n      width={'100%'}\n    >\n      <Typography\n        component={'h3'}\n        variant={isMobile ? 'h4' : 'h3'}\n        whiteSpace={'pre'}\n        marginBottom={3}\n        marginTop={-1}\n      >\n        {t('labelCheckImportCollectionTitle')}\n      </Typography>\n      <Box\n        display={'flex'}\n        flexDirection={'column'}\n        justifyContent={'center'}\n        flex={1}\n        alignItems={'stretch'}\n        alignSelf={'stretch'}\n        className='modalContent'\n        paddingX={5 / 2}\n      >\n        <TextField\n          id='transferFeeType'\n          select\n          label={'label'}\n          value={value}\n          onChange={(event: React.ChangeEvent<any>) => {\n            onChange(event.target?.value)\n          }}\n          inputProps={{ IconComponent: DropDownIcon }}\n          fullWidth={true}\n        >\n          {contractList.map((item) => {\n            return (\n              <MenuItem key={item} value={item} withnocheckicon={'true'}>\n                <ListItemText\n                  primary={\n                    <Typography\n                      sx={{ display: 'inline' }}\n                      component='span'\n                      variant='body1'\n                      color='text.primary'\n                    >\n                      {getShortAddr(item)}\n                    </Typography>\n                  }\n                />\n              </MenuItem>\n            )\n          })}\n        </TextField>\n        <Button\n          size={'large'}\n          variant={'contained'}\n          fullWidth\n          className={'step'}\n          endIcon={<BackIcon fontSize={'small'} sx={{ transform: 'rotate(180deg)' }} />}\n          loading={!disabled && loading ? 'true' : 'false'}\n          disabled={disabled}\n          onClick={() => onClick(value)}\n        >\n          {t('labelContinue')}\n        </Button>\n      </Box>\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/ModalPanels/ClaimWithdraw.tsx",
    "content": "import { ClaimWithdrawBase, IconType, PanelProps } from './BasicPanel'\nimport { L1L2_NAME_DEFINED, MapChainId, NFTWholeINFO } from '@loopring-web/common-resources'\nimport { Typography } from '@mui/material'\nimport { useSettings } from '../../../stores'\n\nexport const ClaimWithdraw_WaitForAuth = (props: PanelProps & Partial<NFTWholeINFO>) => {\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelClaimWithdrawWaitForAuth', {\n      symbol: props.symbol,\n      value: props.value,\n    }),\n  }\n  return <ClaimWithdrawBase {...propsPatch} {...props} />\n}\n\nexport const ClaimWithdraw_Denied = (props: PanelProps & Partial<NFTWholeINFO>) => {\n  const propsPatch = {\n    iconType: IconType.RefuseIcon,\n    describe1: props.t('labelClaimWithdrawDenied', {\n      symbol: props.symbol,\n      value: props.value,\n    }),\n  }\n  return <ClaimWithdrawBase {...propsPatch} {...props} />\n}\n\nexport const ClaimWithdraw_First_Method_Denied = (props: PanelProps & Partial<NFTWholeINFO>) => {\n  const propsPatch = {\n    iconType: IconType.RefuseIcon,\n    describe1: props.t('labelFirstSignDenied', {\n      symbol: props.symbol,\n      value: props.value,\n    }),\n  }\n  return <ClaimWithdrawBase {...propsPatch} {...props} />\n}\n\nexport const ClaimWithdraw_In_Progress = (props: PanelProps & Partial<NFTWholeINFO>) => {\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelClaimWithdrawInProgress', {\n      symbol: props.symbol,\n      value: props.value,\n    }),\n  }\n  return <ClaimWithdrawBase {...propsPatch} {...props} />\n}\n\nexport const ClaimWithdraw_Failed = (props: PanelProps & Partial<NFTWholeINFO>) => {\n  const propsPatch = {\n    iconType: IconType.FailedIcon,\n    describe1: props.t('labelClaimWithdrawFailed', {\n      symbol: props.symbol,\n      value: props.value,\n    }),\n  }\n  return <ClaimWithdrawBase {...propsPatch} {...props} />\n}\n\nexport const ClaimWithdraw_Submit = (props: PanelProps & Partial<NFTWholeINFO>) => {\n  const { isMobile, defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const propsPatch = {\n    iconType: IconType.SubmitIcon,\n    describe1: props.t('labelClaimWithdrawSubmit', {\n      symbol: props.symbol,\n      value: props.value,\n    }),\n    describe2: (\n      <Typography\n        justifySelf={'stretch'}\n        display={'flex'}\n        flexDirection={'column'}\n        minWidth={'var(--modal-min-width)'}\n        justifyContent={'center'}\n        marginTop={2}\n        paddingX={isMobile ? 1 : 5}\n        color={'var(--color-text-third)'}\n        marginBottom={2}\n      >\n        {props.t('labelTransferDelayConfirm', {\n          l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n          loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n          l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n          l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n          ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n        })}\n      </Typography>\n    ),\n  }\n  return <ClaimWithdrawBase {...propsPatch} {...props} />\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/ModalPanels/ClaimWithdrawPanel.tsx",
    "content": "import { WithTranslation, withTranslation } from 'react-i18next'\n\nimport {\n  FeeInfo,\n  IBData,\n  L1L2_NAME_DEFINED,\n  MapChainId,\n  TOAST_TIME,\n  TradeBtnStatus,\n} from '@loopring-web/common-resources'\nimport React from 'react'\nimport { ClaimProps } from '../../tradePanel'\nimport { Box, Grid, Typography } from '@mui/material'\nimport { Button } from '../../basic-lib'\nimport { useSettings } from '../../../stores'\nimport { Toast, ToastType } from '../../toast'\nimport { useTheme } from '@emotion/react'\nimport { FeeSelect } from './FeeSelect'\n\nexport const ClaimWithdrawPanel = withTranslation(['common', 'error'], {\n  withRef: true,\n})(\n  <T extends IBData<I> & { tradeValueView: string }, I, Fee extends FeeInfo>({\n    t,\n    tradeData,\n    feeInfo,\n    btnInfo,\n    btnStatus,\n    isFeeNotEnough,\n    handleFeeChange,\n    chargeFeeTokenList,\n    disabled,\n    claimType,\n    onClaimClick,\n    isNFT,\n    nftIMGURL,\n  }: ClaimProps<T, I, Fee> & WithTranslation & { assetsData: any[] }) => {\n    const { isMobile, defaultNetwork } = useSettings()\n    const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n    const [open, setOpen] = React.useState(false)\n    const [showFeeModal, setShowFeeModal] = React.useState(false)\n    const handleToggleChange = (value: Fee) => {\n      if (handleFeeChange) {\n        handleFeeChange(value)\n      }\n    }\n    const getDisabled = React.useMemo(() => {\n      return disabled || btnStatus === TradeBtnStatus.DISABLED\n    }, [disabled, btnStatus])\n    const theme = useTheme()\n    return (\n      <Grid\n        className={'confirm'}\n        container\n        paddingLeft={isMobile ? 2 : 5 / 2}\n        paddingRight={isMobile ? 2 : 5 / 2}\n        direction={'column'}\n        alignItems={'stretch'}\n        flex={1}\n        width={`calc(var(--modal-width) - ${(theme.unit * 5) / 2}px)`}\n        // height={isMobile ? \"auto\" : 560}\n        minWidth={'var(--swap-box-width)'}\n        flexWrap={'nowrap'}\n        spacing={2}\n        paddingBottom={5 / 2}\n      >\n        <Grid item xs={12} marginTop={1}>\n          <Box\n            display={'flex'}\n            flexDirection={'column'}\n            justifyContent={'center'}\n            alignItems={'center'}\n            marginBottom={2}\n          >\n            <Typography component={'h4'} variant={isMobile ? 'h4' : 'h3'} whiteSpace={'pre'}>\n              {t('labelRedPacketClaimTitle', {\n                l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n              })}\n            </Typography>\n          </Box>\n        </Grid>\n        <Grid item xs={12}>\n          {isNFT ? (\n            <Box display={'flex'} flexDirection={'column'} alignItems='center'>\n              <img height={8 * theme.unit} src={nftIMGURL} />\n              <Typography color={'textSecondary'} marginTop={1} variant={'body2'}>\n                {tradeData?.tradeValueView + ' NFTs'}\n              </Typography>\n            </Box>\n          ) : (\n            <Typography\n              component={'h5'}\n              marginTop={1}\n              textAlign={'center'}\n              color={'textPrimary'}\n              variant={'h2'}\n            >\n              {tradeData?.tradeValueView + ' ' + tradeData?.belong}\n            </Typography>\n          )}\n        </Grid>\n        <Grid item xs={12}>\n          <Typography color={'var(--color-text-third)'} variant={'body1'}>\n            {t('labelRedPacketFrom')}\n          </Typography>\n          <Typography component={'span'} variant={'body1'} color={'var(--color-text-primary)'}>\n            {t(`labelClaim${claimType}`, { symbol: tradeData?.belong })}\n          </Typography>\n        </Grid>\n\n        <Grid item xs={12}>\n          <Typography color={'var(--color-text-third)'} variant={'body1'}>\n            {t('labelRedPacketTo', {\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n              l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n              l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n              ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n            })}\n          </Typography>\n          <Typography component={'span'} variant={'body1'} color={'var(--color-text-primary)'}>\n            {t('labelToMyL2', {\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n              l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n              l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n              ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n            })}\n          </Typography>\n        </Grid>\n        <Grid item xs={12} alignSelf={'stretch'} position={'relative'}>\n          {!chargeFeeTokenList?.length ? (\n            <Typography>{t('labelFeeCalculating')}</Typography>\n          ) : (\n            <>\n              <FeeSelect\n                chargeFeeTokenList={chargeFeeTokenList}\n                handleToggleChange={(fee: FeeInfo) => {\n                  handleToggleChange(fee as Fee)\n                  setShowFeeModal(false)\n                }}\n                feeInfo={feeInfo as FeeInfo}\n                open={showFeeModal}\n                onClose={() => {\n                  setShowFeeModal(false)\n                }}\n                isFeeNotEnough={isFeeNotEnough.isFeeNotEnough}\n                feeLoading={isFeeNotEnough.isOnLoading}\n                onClickFee={() => setShowFeeModal((prev) => !prev)}\n              />\n            </>\n          )}\n        </Grid>\n\n        <Grid item marginTop={2} alignSelf={'stretch'} paddingBottom={0}>\n          <Button\n            fullWidth\n            variant={'contained'}\n            size={'medium'}\n            color={'primary'}\n            onClick={async () => {\n              if (onClaimClick) {\n                onClaimClick(tradeData)\n              } else {\n                setOpen(true)\n              }\n            }}\n            loading={!getDisabled && btnStatus === TradeBtnStatus.LOADING ? 'true' : 'false'}\n            disabled={getDisabled || btnStatus === TradeBtnStatus.LOADING}\n          >\n            {t(btnInfo?.label ? btnInfo?.label : `labelConfirm`)}\n          </Button>\n        </Grid>\n        <Toast\n          alertText={t('errorBase', { ns: 'error' })}\n          open={open}\n          autoHideDuration={TOAST_TIME}\n          onClose={() => {\n            setOpen(false)\n          }}\n          severity={ToastType.error}\n        />\n      </Grid>\n    )\n  },\n) as <T, I>(props: ClaimProps<T, I> & React.RefAttributes<any>) => JSX.Element\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/ModalPanels/CoinbaseSmartWalletModal.tsx",
    "content": "import {\n  Box,\n  Button,\n  FormControl,\n  FormHelperText,\n  IconButton,\n  Input,\n  InputAdornment,\n  Modal,\n  OutlinedInput,\n  Typography,\n} from '@mui/material'\nimport styled from '@emotion/styled'\nimport { ModalCloseButton } from '../../basic-lib'\nimport { withTranslation } from 'react-i18next'\nimport { AccountStep } from './Interface'\nimport { useOpenModals, useSettings } from '../../../stores'\nimport React from 'react'\nimport { CheckIcon, CloseIcon, ErrorIcon, FailedIcon, hexToRGB, LoadingIcon, LoadingIcon2, SoursURL } from '@loopring-web/common-resources'\nimport { keyframes, useTheme } from '@emotion/react'\nimport ArrowBackIosNewIcon from '@mui/icons-material/ArrowBackIosNew'\nimport Visibility from '@mui/icons-material/Visibility'\nimport VisibilityOff from '@mui/icons-material/VisibilityOff'\nimport { range } from 'lodash'\n\n// 创建旋转动画\nconst spin = keyframes`\n  from {\n    transform: rotate(0deg);\n  }\n  to {\n    transform: rotate(360deg);\n  }\n`\n\n// 旋转的LoadingIcon2组件\nconst RotatingLoadingIcon = styled(LoadingIcon2)`\n  animation: ${spin} 1.5s linear infinite;\n  transform-origin: center;\n`\n\n// 步骤指示器组件定义\nenum StepStatus {\n  INIT = 'init',\n  PROCESSING = 'processing',\n  COMPLETED = 'completed',\n}\n\ninterface Step {\n  rightElement: React.ReactNode\n}\n\ninterface VerticalStepperProps {\n  steps: Step[]\n  currentStep: number\n}\n\nconst StepperContainer = styled(Box)`\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  gap: 20px;\n  width: 100%;\n`\n\nconst StepCircle = styled(Box)<{ status: StepStatus }>`\n  width: 48px;\n  height: 48px;\n  border-radius: 50%;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  background-color: ${({ status, theme }) => \n    status === StepStatus.COMPLETED \n      ? hexToRGB(theme.colorBase.success, 0.1) \n      : hexToRGB(theme.colorBase.boxSecondary, 1)};\n  color: var(--color-text-button);\n  svg {\n    height: 24px;\n    width: 24px;\n  }\n`\n\nconst ConnectingLine = styled(Box)<{ isActive: boolean }>`\n  width: 2px;\n  position: absolute;\n  background: ${({ isActive }) => \n    isActive ? \n    `repeating-linear-gradient(\n      to bottom,\n      var(--color-success),\n      var(--color-success) 4px,\n      transparent 4px,\n      transparent 8px\n    )` : \n    `repeating-linear-gradient(\n      to bottom,\n      var(--field-opacity),\n      var(--field-opacity) 4px,\n      transparent 4px,\n      transparent 8px\n    )`\n  };\n`\n\nconst VerticalStepper: React.FC<VerticalStepperProps> = ({ \n  steps,\n  currentStep, \n}) => {\n  const circleRefs = React.useRef<(HTMLDivElement | null)[]>([]);\n\n  circleRefs.current = circleRefs.current.slice(0, steps.length);\n  const positions = (() => {\n    const positions = circleRefs.current.map((ref) => {\n      if (!ref) return null;\n      const containerRect = ref.parentElement!.getBoundingClientRect()\n      const rect = ref.getBoundingClientRect();\n      return {\n        x: rect.left - containerRect.left,\n        y: rect.top - containerRect.top,\n      };\n    });\n    return positions;\n  })();\n\n\n  return (\n    <StepperContainer position={'relative'}>\n      {steps.map((step, index) => {\n        const status = currentStep > index ? StepStatus.COMPLETED : currentStep === index ? StepStatus.PROCESSING : StepStatus.INIT\n        return (\n          <Box ref={(el: HTMLDivElement | null) => {\n            circleRefs.current[index] = el\n          }} key={index} width={'100%'}>\n            <Box display={'flex'} alignItems={'start'}>\n            <StepCircle\n              status={status}\n            >\n              {status === StepStatus.COMPLETED ? (\n                <CheckIcon\n                  className='custom-size'\n                  sx={{ fontSize: '24px', color: 'var(--color-success)' }}\n                />\n              ) : status === StepStatus.PROCESSING ? (\n                <RotatingLoadingIcon className='custom-size' sx={{ fontSize: '24px' }} />\n              ) : (\n                <></>\n              )}\n            </StepCircle>\n            <Box mt={1} width={'calc(100% - 80px)'}>\n              {step.rightElement}\n            </Box>\n          </Box>\n        </Box>\n      )})}\n      {range(0, steps.length - 1).map((index) => (\n        <React.Fragment key={index}>\n          {index < steps.length - 1 && positions && positions[index] && positions[index + 1] && (\n            <ConnectingLine\n              isActive={currentStep > index}\n              sx={{\n                left: `${23 + (positions[index]?.x || 0)}px`,\n                top: `${(positions[index]?.y || 0) + 52}px`,\n                height: `${\n                  (positions[index + 1]?.y || 0) - (positions[index]?.y || 0) - 56\n                }px`,\n                zIndex: 0,\n              }}\n            />\n          )}\n        </React.Fragment>\n      ))}\n    </StepperContainer>\n  )\n}\n\n\n\n\n\n\nconst Coinbase_Smart_Wallet_Password_Intro = withTranslation('common')(\n  ({ t, onClickConfirm }: { t: any; onClickConfirm: () => void }) => {\n    return (\n      <Box px={3} display={'flex'} flexDirection={'column'} height={'100%'} pb={4}>\n        {/* <ModalCloseButton onClose={onClickClose} t={t} /> */}\n\n        <Typography variant='h4' textAlign='center'>\n          Sign-In Password Required for <br/> Coinbase Smart Wallet\n        </Typography>\n\n        <Box width='100%' marginTop={5}>\n          <Typography color='var(--color-text-secondary)' textAlign='left'>\n            Coinbase Smart Wallet detected.\n            <br />\n            To use Loopring DeFi securely, you’ll need to set a password to locally encrypt your\n            EDDSA signature.\n            <br />\n            When you close the Loopring dApp and return later, you’ll be required to sign in with\n            your password to continue.\n          </Typography>\n        </Box>\n\n        <Box mt={'auto'} width={'100%'} pt={4}>\n          <Button\n          variant='contained'\n          fullWidth\n          size='medium'\n          onClick={() => {\n            onClickConfirm()\n          }}\n        >\n          {t('labelConfirm')}\n        </Button>\n        </Box>\n      </Box>\n    )\n  },\n)\n\nconst isValidPassword = (password: string): boolean => {\n  const hasValidLength = password.length >= 6 && password.length <= 20;\n  \n  const hasLetters = /[a-zA-Z]/.test(password);\n  \n  const hasNumbers = /[0-9]/.test(password);\n\n  const onlyLetterOrNumber = /^[a-zA-Z0-9]+$/.test(password);\n  \n  return hasValidLength && hasLetters && hasNumbers && onlyLetterOrNumber;\n}\n\nconst Coinbase_Smart_Wallet_Password_Set = withTranslation('common')(\n  ({ t, onClickConfirm, onClickBack }: {\n    t: any\n    onClickConfirm: (pwd: string) => void\n    onClickBack: () => void\n  }) => {\n    const [password, setPassword] = React.useState('')\n    const [confirmPassword, setConfirmPassword] = React.useState('')\n    const [showPassword, setShowPassword] = React.useState(false)\n    \n    const error =\n      password && !isValidPassword(password)\n        ? 'format'\n        : confirmPassword && password !== confirmPassword\n        ? 'notMatch'\n        : undefined\n    \n    const handleToggleShowPassword = () => {\n      setShowPassword(!showPassword)\n    }\n\n    const handleConfirm = () => {\n      onClickConfirm(password)\n    }\n\n    return (\n      <Box px={3} display={'flex'} flexDirection={'column'} height={'100%'} pb={3}>\n        <ArrowBackIosNewIcon\n          sx={{\n            position: 'absolute',\n            left: 24,\n            top: 24,\n            cursor: 'pointer',\n            fontSize: '20px',\n            color: 'var(--color-text-secondary)',\n          }}\n          className='custom-size'\n          onClick={onClickBack}\n        />\n        <Typography variant='h4' textAlign='center' mt={2}>\n            Set Password\n        </Typography>\n        <Box mt={4}>\n          <Typography variant='body1' color='var(--color-text-secondary)' mb={1}>\n            Set Password\n          </Typography>\n          <FormControl variant='outlined' fullWidth>\n            <Input\n              type={showPassword ? 'text' : 'password'}\n              value={password}\n              onChange={(e) => setPassword(e.target.value)}\n              endAdornment={\n                showPassword ? (\n                  <VisibilityOff\n                    sx={{\n                      cursor: 'pointer',\n                      fontSize: '20px',\n                      mr: 1,\n                    }}\n                    className='custom-size'\n                    onClick={handleToggleShowPassword}\n                  />\n                ) : (\n                  <Visibility\n                    sx={{\n                      cursor: 'pointer',\n                      fontSize: '20px',\n                      mr: 1,\n                    }}\n                    className='custom-size'\n                    onClick={handleToggleShowPassword}\n                  />\n                )\n              }\n              sx={{\n                backgroundColor: 'transparent',\n                border: '1px solid var(--color-border)',\n                borderRadius: '8px',\n                height: '48px',\n                fontSize: '20px',\n                pl: 1.5,\n              }}\n              disableUnderline\n            />\n          </FormControl>\n          <Typography\n            mt={1.5}\n            variant='body1'\n            color={error === 'format' ? 'var(--color-error)' : 'var(--color-text-secondary)'}\n            mb={1}\n          >\n            *6–20 chars, letters + numbers\n          </Typography>\n        </Box>\n\n        <Box mt={3}>\n          <Typography variant='body1' color='var(--color-text-secondary)' mb={1}>\n            Confirm Password\n          </Typography>\n          <FormControl variant='outlined' fullWidth>\n            <Input\n              disableUnderline\n              type={showPassword ? 'text' : 'password'}\n              value={confirmPassword}\n              onChange={(e) => setConfirmPassword(e.target.value)}\n              sx={{\n                backgroundColor: 'transparent',\n                borderRadius: '8px',\n                border: '1px solid var(--color-border)',\n                height: '48px',\n                fontSize: '20px',\n                pl: 1.5,\n              }}\n            />\n          </FormControl>\n          <Typography\n            mt={1.5}\n            variant='body1'\n            sx={{ opacity: error === 'notMatch' ? 1 : 0 }}\n            color={'var(--color-error)'}\n            mb={1}\n          >\n            Not match\n          </Typography>\n        </Box>\n\n        <Box mt={'auto'} width={'100%'}>\n          <Button\n            variant='contained'\n            fullWidth\n            size='medium'\n            onClick={handleConfirm}\n            disabled={!password || !confirmPassword || !!error}\n          >\n            {t('labelConfirm')}\n          </Button>\n        </Box>\n      </Box>\n    )\n  },\n)\n\nconst Coinbase_Smart_Wallet_Password_Set_Confirm = withTranslation('common')(({onClickProceed}: {onClickProceed: () => void}) => {\n  return (\n    <Box\n      display=\"flex\"\n      flexDirection=\"column\"\n      alignItems=\"center\"\n      justifyContent=\"center\"\n      px={4}\n      py={4}\n      height=\"100%\"\n    >\n      <Box width={90} height={70} component={'img'} src={SoursURL + 'images/coinbase_prompt.png'} mb={7}/>\n        \n      <Typography mb={3}>\n      The following steps require multiple interactions with your Coinbase Smart Wallet.\n      </Typography>\n      <Typography  >\n        If the wallet extension does not automatically prompt you for action, please open it manually to proceed.\n      </Typography>\n      <Button\n        variant=\"contained\"\n        fullWidth\n        sx={{\n          mt: 'auto'\n        }}\n        onClick={onClickProceed}\n      >\n        Proceed\n      </Button>\n    </Box>\n  )\n})\n\nconst Coinbase_Smart_Wallet_Password_Input = withTranslation('common')(\n  ({ t, onClickConfirm, onClickForgetPassword, inputDisabled, showPasswordMismatchError, onInputPassword }: {\n    t: any\n    onClickConfirm: (pwd: string) => void\n    onClickForgetPassword: () => void\n    inputDisabled?: boolean\n    showPasswordMismatchError: boolean\n    onInputPassword: () => void\n  }) => {\n    const [password, setPassword] = React.useState('')\n    const [showPassword, setShowPassword] = React.useState(false)\n\n    const handleToggleShowPassword = () => {\n      setShowPassword(!showPassword)\n    }\n\n    const handleConfirm = () => {\n      onClickConfirm(password)\n    }\n\n    return (\n      <Box px={3} display={'flex'} flexDirection={'column'} height={'100%'} pb={3}>\n        <Typography variant='h4' textAlign='center' mb={4}>\n          {t('labelSignIn')}\n        </Typography>\n\n        <Box>\n          {!inputDisabled && (\n            <>\n              <Typography variant='body1' color='var(--color-text-secondary)' mb={1}>\n                Input Password\n              </Typography>\n              <FormControl variant='outlined' fullWidth>\n                <Input\n                  type={showPassword ? 'text' : 'password'}\n                  value={password}\n                  onChange={(e) => {\n                    setPassword(e.target.value)\n                    onInputPassword()\n                  }}\n                  endAdornment={\n                    showPassword ? (\n                      <VisibilityOff\n                        sx={{\n                          cursor: 'pointer',\n                          fontSize: '20px',\n                          mr: 1,\n                        }}\n                        className='custom-size'\n                        onClick={handleToggleShowPassword}\n                      />\n                    ) : (\n                      <Visibility\n                        sx={{\n                          cursor: 'pointer',\n                          fontSize: '20px',\n                          mr: 1,\n                        }}\n                        className='custom-size'\n                        onClick={handleToggleShowPassword}\n                      />\n                    )\n                  }\n                  sx={{\n                    backgroundColor: 'transparent',\n                    border: '1px solid var(--color-border)',\n                    borderRadius: '8px',\n                    height: '48px',\n                    fontSize: '16px',\n                    pl: 2,\n                  }}\n                  disableUnderline\n                />\n              </FormControl>\n              {showPasswordMismatchError && (\n                <Typography mt={1.5} variant='body1' color='var(--color-error)'>\n                  Authentication failed: password mismatch\n                </Typography>\n              )}\n            </>\n          )}\n          {inputDisabled && (\n            <Typography mt={1.5} variant='body1' color='var(--color-error)' mb={1}>\n              No corresponding password found, please reset password\n            </Typography>\n          )}\n        </Box>\n\n        <Box mt={'auto'} width={'100%'}>\n          <Typography\n            variant='body2'\n            onClick={onClickForgetPassword}\n            sx={{\n              cursor: 'pointer',\n              color: 'var(--color-primary)',\n              textAlign: 'center',\n              mb: 1.5,\n            }}\n          >\n            Forget Password?\n          </Typography>\n          <Button\n            variant='contained'\n            fullWidth\n            size='medium'\n            onClick={handleConfirm}\n            disabled={!password}\n          >\n            {t('labelConfirm')}\n          </Button>\n        </Box>\n      </Box>\n    )\n  },\n)\n\nconst Coinbase_Smart_Wallet_Password_Forget_Password = withTranslation('common')(\n  ({ t, onClickConfirm }: {\n    t: any\n    onClickConfirm: () => void\n  }) => {\n    const theme = useTheme()\n    return (\n      <Box px={3} display={'flex'} flexDirection={'column'} height={'100%'} pb={3}>\n        <Box display={'flex'} justifyContent={'center'} my={2}>\n          <Box\n            component={'img'}\n            width={86}\n            height={79}\n            src={\n              SoursURL +\n              (theme.mode === 'light'\n                ? 'images/coinbase_reset_password_light.png'\n                : 'images/coinbase_reset_password.png')\n            }\n          />\n        </Box>\n        <Typography variant='h4' textAlign='center' mt={2} mb={3}>\n          Reset Loopring DeFi Account & Password\n        </Typography>\n\n        <Box>\n          <Typography color='var(--color-text-third)' fontSize={13} mb={3}>\n            Please note: this operation will not affect your assets - only your EDDSA key will be\n            replaced with a new one.\n          </Typography>\n\n          <Typography color='var(--color-text-third)' fontSize={13} mb={3}>\n            This process requires confirmation via your wallet. Please approve the signature request\n            in your wallet to proceed.\n          </Typography>\n        </Box>\n\n        <Box mt={'auto'} width={'100%'}>\n          <Button variant='contained' fullWidth size='medium' onClick={onClickConfirm}>\n            Confirm\n          </Button>\n        </Box>\n      </Box>\n    )\n  },\n)\n\n\nconst Coinbase_Smart_Wallet_Password_Forget_Password_Confirm = withTranslation('common')(\n  ({ t, onClickConfirm, onClickBack }: {\n    t: any\n    onClickConfirm: () => void\n    onClickBack: () => void\n  }) => {\n    const [isAcknowledged, setIsAcknowledged] = React.useState(false)\n    const theme = useTheme()\n    return (\n      <Box px={3} display={'flex'} flexDirection={'column'} height={'100%'} pb={3}>\n        <ArrowBackIosNewIcon\n          sx={{\n            position: 'absolute',\n            left: 24,\n            top: 24,\n            cursor: 'pointer',\n            fontSize: '20px',\n            color: 'var(--color-text-secondary)',\n          }}\n          className='custom-size'\n          onClick={onClickBack}\n        />\n        <Box display={'flex'} justifyContent={'center'} my={2}>\n          <Box\n            component={'img'}\n            width={86}\n            src={\n              SoursURL +\n              (theme.mode === 'light'\n                ? 'images/coinbase_forget_password_light.png'\n                : 'images/coinbase_forget_password.png')\n            }\n          />\n        </Box>\n\n        <Typography variant='h4' textAlign='center' mt={2} mb={1}>\n          Forget Password\n        </Typography>\n        <Typography color='var(--color-text-secondary)' textAlign='center' mb={4}>\n          You will need to reset your Loopring DeFi account.\n        </Typography>\n\n        <Box>\n          <Typography color='var(--color-text-third)' fontSize={13} mb={2}>\n            Please note:\n            <br />\n            · Any active positions (such as trades in the Loopring Portal) will be automatically\n            closed upon reset.\n            <br />\n            · If you have pending Dual Investment positions, you must wait for them to settle before\n            you can reset your account.\n            <br />\n            <br />\n            For assistance during the reset process, please contact: support@loopring.io\n          </Typography>\n\n          <Box\n            display='flex'\n            alignItems='center'\n            mb={2}\n            sx={{ cursor: 'pointer' }}\n            onClick={() => setIsAcknowledged(!isAcknowledged)}\n          >\n            <Box\n              sx={{\n                width: 16,\n                height: 16,\n                border: '1px solid var(--color-border)',\n                borderRadius: '2px',\n                mr: 1,\n                display: 'flex',\n                alignItems: 'center',\n                justifyContent: 'center',\n                backgroundColor: isAcknowledged ? 'var(--color-primary)' : 'transparent',\n              }}\n            >\n              {isAcknowledged && (\n                <Typography component='span' sx={{ fontSize: '12px', color: 'white' }}>\n                  ✓\n                </Typography>\n              )}\n            </Box>\n            <Typography color='var(--color-primary)'>\n              I acknowledge and would like to proceed.\n            </Typography>\n          </Box>\n        </Box>\n\n        <Box mt={'auto'} width={'100%'}>\n          <Button\n            variant='contained'\n            fullWidth\n            size='medium'\n            onClick={onClickConfirm}\n            disabled={!isAcknowledged}\n          >\n            {t('labelConfirm')}\n          </Button>\n        </Box>\n      </Box>\n    )\n  },\n)\n\nconst Coinbase_Smart_Wallet_Password_Set_Processing = withTranslation('common')(\n  ({ step, showResumeUpdateAccount }: { step: 'keyGenerating' | 'blockConfirming' | 'updatingAccount' | 'completed'; showResumeUpdateAccount: boolean }) => {\n    const { isMobile } = useSettings()\n    \n    return (\n      <Box px={3} display={'flex'} flexDirection={'column'} height={'100%'} pb={3}>\n        <Typography variant={'h4'} textAlign='center' mb={4} mt={2}>\n          Loopring DeFi Account Creation\n        </Typography>\n        \n        <Box display='flex' alignItems='flex-start' mb={4} gap={3}>\n          <Box mt={2}>\n            <VerticalStepper\n              steps={[\n                {\n                  rightElement: (\n                    <Typography variant={isMobile ? 'h5' : 'h4'} mt={isMobile ? 1 : 0} ml={2}>\n                      Sign In & Generate EDDSA Key\n                    </Typography>\n                  ),\n                },\n                {\n                  rightElement: (\n                    <Box ml={2}>\n                      <Typography variant={isMobile ? 'h5' : 'h4'} mt={isMobile ? 1 : 0} mb={1}>\n                        Submit EDDSA Key & Wait for Block Confirmation\n                      </Typography>\n                      <Typography variant={isMobile ? 'body2' : 'body1'} color='var(--color-text-secondary)'>\n                      It requires a certain number of block confirmations. The dApp will automatically monitor the progress and proceed to Step 3 once confirmations are complete.\n                      </Typography>\n                    </Box>\n                  ),\n                },\n                {\n                  rightElement: (\n                    <Typography variant={isMobile ? 'h5' : 'h4'} mt={isMobile ? 1 : 0} ml={2}>\n                       Update Account\n                    </Typography>\n                  ),\n                },\n              ]}\n              currentStep={step === 'keyGenerating' ? 0 : step === 'blockConfirming' ? 1 : step === 'updatingAccount' ? 2 : 3}\n            />\n          </Box>\n        </Box>\n\n        {showResumeUpdateAccount && <Typography textAlign={'center'} color='var(--color-text-secondary)' mt={'auto'} mb={2}>\n          It appears you’ve already generated your EDDSA key, but did not complete the final “Update Account” step in your previous session.\n        </Typography>}\n      </Box>\n    )\n  },\n)\n\nconst Coinbase_Smart_Wallet_Password_Set_Error = withTranslation('common')(\n  ({ onClickConfirm }: { onClickConfirm: () => void }) => {\n    return (\n      <Box px={3} display={'flex'} flexDirection={'column'} height={'100%'} pb={3}>\n        <Box display='flex' justifyContent={'center'} my={4} >\n          <FailedIcon sx={{ color: 'var(--color-error)', fontSize: '72px' }} className='custom-size'/>\n        </Box>\n\n        <Typography mt={4}>\n          We're currently unable to create your Loopring DeFi account, which may be due to network conditions. Please try again later. If the issue persists, feel free to contact us at support@loopring.io for assistance.\n        </Typography>\n\n        <Button sx={{mt: 'auto', mb: 2}} variant='contained' fullWidth onClick={onClickConfirm}>I Know</Button>\n      </Box>\n    )\n  },\n)\n\nconst Coinbase_Smart_Wallet_Password_Get_Error = withTranslation('common')(\n  ({ onClickConfirm }: { onClickConfirm: () => void }) => {\n    return (\n      <Box px={3} display={'flex'} flexDirection={'column'} height={'100%'} pb={3}>\n        <Box display='flex' justifyContent={'center'} my={4} >\n          <FailedIcon sx={{ color: 'var(--color-error)', fontSize: '72px' }} className='custom-size'/>\n        </Box>\n\n        <Typography mt={4}>\n        We're currently unable to retrieve your EDDSA key from the Loopring server, possibly due to network conditions. Please try again later. If the issue persists, don't hesitate to contact us at support@loopring.io for further assistance.\n        </Typography>\n\n        <Button sx={{mt: 'auto', mb: 2}} variant='contained' fullWidth onClick={onClickConfirm}>I Know</Button>\n      </Box>\n    )\n  },\n)\n\nexport {\n  Coinbase_Smart_Wallet_Password_Intro,\n  Coinbase_Smart_Wallet_Password_Set,\n  Coinbase_Smart_Wallet_Password_Set_Confirm,\n  Coinbase_Smart_Wallet_Password_Input,\n  Coinbase_Smart_Wallet_Password_Forget_Password_Confirm,\n  Coinbase_Smart_Wallet_Password_Forget_Password,\n  Coinbase_Smart_Wallet_Password_Set_Processing,\n  Coinbase_Smart_Wallet_Password_Set_Error,\n  Coinbase_Smart_Wallet_Password_Get_Error\n\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/ModalPanels/Connect.tsx",
    "content": "import { ConnectProviders } from '@loopring-web/web3-provider'\nimport { ConnectBase, IconType, PanelProps } from './BasicPanel'\nimport { useSettings } from '../../../stores'\nimport { Box, Typography } from '@mui/material'\n\n// value symbol\nexport const CommonConnectInProgress = (props: PanelProps) => {\n  const { isMobile } = useSettings()\n\n  const providerName = props.providerName\n  const propsPatch = {\n    providerName,\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelProviderProcessing', {\n      name: isMobile\n        ? 'DApp, network:' + props?.network\n        : providerName\n        ? providerName + ', network:' + props?.network\n        : props.t('labelUnknown') + ', network:' + props?.network,\n    }),\n  }\n  return <ConnectBase {...propsPatch} {...props} />\n}\n\nexport const WalletConnectConnectInProgress = (props: PanelProps) => {\n  const propsPatch = {\n    providerName: ConnectProviders.WalletConnect,\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelProviderProcessing', {\n      name: ConnectProviders.WalletConnect,\n    }),\n  }\n  return <ConnectBase {...propsPatch} {...props} />\n}\n\n// value symbol\nexport const ConnectSuccess = (props: PanelProps) => {\n  const propsPatch = {\n    providerName: undefined,\n    iconType: IconType.DoneIcon,\n    describe1: props.t('labelSuccessConnect', {\n      providerName: props.providerName,\n    }),\n    describe2: (\n      <Box display={'flex'} marginTop={0} alignItems={'flex-center'}>\n        <Typography\n          marginX={3}\n          whiteSpace={'pre-line'}\n          variant={'h5'}\n          textAlign={'center'}\n          color={'textPrimary'}\n          component={'div'}\n          marginTop={0}\n          alignSelf={'flex-center'}\n          paddingX={1}\n        >\n          {props.t('labelSuccessConnectDescribe')}\n        </Typography>\n      </Box>\n    ),\n  }\n  return <ConnectBase {...propsPatch} {...props} />\n}\n\n// value symbol\nexport const ConnectFailed = ({ NetWorkItems, providerName, ...props }: PanelProps) => {\n  const propsPatch = {\n    providerName: undefined,\n    iconType: IconType.FailedIcon,\n    describe1: props.t('labelFailedConnect'),\n    describe2: NetWorkItems ? <>{NetWorkItems}</> : '',\n  }\n  return <ConnectBase {...propsPatch} {...props} />\n}\nexport const ConnectReject = ({ NetWorkItems, providerName, ...props }: PanelProps) => {\n  const propsPatch = {\n    providerName: undefined,\n    iconType: IconType.RefuseIcon,\n    describe1: props.t('labelRejectConnect'),\n    describe2: NetWorkItems ? <>{NetWorkItems}</> : '',\n  }\n  return <ConnectBase {...propsPatch} {...props} />\n}\n\nexport const ConnectRejectSwitchNetwork = ({\n  NetWorkItems,\n  providerName,\n  ...props\n}: PanelProps) => {\n  const propsPatch = {\n    title: 'labelRejectSwitchNetwork',\n    // providerName,\n    iconType: IconType.RefuseIcon,\n    describe1: NetWorkItems ? <>{NetWorkItems}</> : '',\n  }\n  return <ConnectBase {...propsPatch} {...props} />\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/ModalPanels/CreateAccount.tsx",
    "content": "import { CreateAccountBase, IconType, PanelProps } from './BasicPanel'\nimport { AlertIcon2, L1L2_NAME_DEFINED, MapChainId } from '@loopring-web/common-resources'\nimport { useSettings } from '../../../stores'\nimport { Button, Checkbox, Modal, Box, Typography } from '@mui/material'\nimport { useState } from 'react'\nimport { Trans } from 'react-i18next'\nimport { useTheme } from '@emotion/react'\nimport { CheckBoxIcon, CheckedIcon } from '@loopring-web/common-resources'\n\n// symbol\nexport const CreateAccount_Approve_WaitForAuth = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelTokenAccess', { symbol: props.symbol }),\n  }\n  return <CreateAccountBase {...props} {...propsPatch} />\n}\n\n// symbol\nexport const CreateAccount_Approve_Denied = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.RefuseIcon,\n    describe1: props.t('labelFailedTokenAccess', { symbol: props.symbol }),\n  }\n  return <CreateAccountBase {...propsPatch} {...props} />\n}\n\n// symbol\nexport const CreateAccount_Approve_Submit = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.SubmitIcon,\n    describe1: props.t('labelSuccessTokenAccess', { symbol: props.symbol }),\n  }\n  return <CreateAccountBase {...propsPatch} {...props} />\n}\n\n// value symbol\nexport const CreateAccount_WaitForAuth = (props: PanelProps) => {\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelL1toL2WaitForAuth', {\n      symbol: props.symbol,\n      loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n    }),\n  }\n  return <CreateAccountBase {...propsPatch} {...props} />\n}\n\n// value symbol\nexport const CreateAccount_Denied = (props: PanelProps) => {\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const propsPatch = {\n    iconType: IconType.RefuseIcon,\n    describe1: props.t('labelCreateAccountDepositDenied', {\n      layer2: L1L2_NAME_DEFINED[network].layer2,\n      symbol: props.symbol,\n    }),\n  }\n  return <CreateAccountBase {...propsPatch} {...props} />\n}\n\n// value symbol\nexport const CreateAccount_Failed = (props: PanelProps) => {\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const propsPatch = {\n    iconType: IconType.FailedIcon,\n    describe1: props.t('labelCreateAccountFailed', {\n      layer2: L1L2_NAME_DEFINED[network].layer2,\n      loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n      value: props.value,\n      symbol: props.symbol,\n    }),\n  }\n  return <CreateAccountBase {...propsPatch} {...props} />\n}\n\n// value symbol\nexport const CreateAccount_Submit = (props: PanelProps) => {\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const propsPatch = {\n    iconType: IconType.SubmitIcon,\n    describe1: props.t('labelCreateAccountSubmit', {\n      layer2: L1L2_NAME_DEFINED[network].layer2,\n      loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n      value: props.value,\n      symbol: props.symbol,\n      count: 30,\n    }),\n  }\n  return <CreateAccountBase {...propsPatch} {...props} />\n}\n\nexport const CreateAccount_EOA_Only_Alert = (props: {\n  onClose: () => void\n  onConfirm: () => void\n}) => {\n  const [acknowledged, setAcknowledged] = useState(false)\n  const theme = useTheme()\n  return (\n    <Box\n      sx={{\n        position: 'absolute',\n        top: '50%',\n        left: '50%',\n        transform: 'translate(-50%, -50%)',\n        borderRadius: 2,\n        width: '90%',\n        maxWidth: '480px',\n      }}\n    >\n      <Box sx={{ textAlign: 'center', mb: 5, mt: 3 }}>\n        <AlertIcon2\n          className='custom-size'\n          sx={{ fontSize: '88px' }}\n          color={theme.colorBase.textPrimary}\n        />\n      </Box>\n\n      <Box sx={{ color: 'var(--color-text-primary)', mb: 3 }}>\n        <Typography>\n          Please ensure that you are activating your Loopring account using an EOA (Externally Owned\n          Account) wallet.\n        </Typography>\n        <Typography sx={{ color: 'var(--color-text-secondary)', mt: 4 }}>\n          Currently, only EOA wallets are supported on the Loopring network. Smart contract wallets\n          are not supported. <br />\n          Depositing assets to a smart wallet on the Loopring network may result in permanent loss\n          of those assets. Please exercise caution.\n        </Typography>\n      </Box>\n\n      <Box sx={{ mb: 3, display: 'flex', alignItems: 'center' }}>\n        <Checkbox\n          checkedIcon={<CheckedIcon />}\n          icon={<CheckBoxIcon />}\n          color='default'\n          sx={{ height: 16, width: 16, mr: 1 }}\n          onChange={(_, checked) => {\n            setAcknowledged(checked)\n          }}\n        />\n        <Typography sx={{ color: 'var(--color-text-primary)' }}>\n          I acknowledge the risk and would like to proceed\n        </Typography>\n      </Box>\n\n      <Button fullWidth variant='contained' onClick={props.onConfirm} disabled={!acknowledged}>\n        Confirm\n      </Button>\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/ModalPanels/CreateRedPacketPanel.tsx",
    "content": "import { useTranslation } from 'react-i18next'\nimport { SwitchPanel, SwitchPanelProps } from '../../basic-lib'\nimport { CreateRedPacketProps, RedPacketStep, TargetRedPacketStep } from '../../tradePanel'\nimport {\n  FeeInfo,\n  LuckyRedPacketList,\n  NFTWholeINFO,\n  RedPacketOrderData,\n  RedPacketOrderType,\n} from '@loopring-web/common-resources'\nimport {\n  HorizontalLabelPositionBelowStepper,\n  TradeMenuList,\n  useBasicTrade,\n} from '../../tradePanel/components'\nimport React from 'react'\nimport { cloneDeep } from 'lodash'\n\nimport {\n  CreateRedPacketScope,\n  CreateRedPacketStepTokenType,\n  CreateRedPacketStepType,\n  CreateRedPacketStepWrap,\n  TargetRedpacktInputAddressStep,\n  TargetRedpacktSelectStep,\n} from '../../tradePanel/components/CreateRedPacketWrap'\nimport { Box, styled } from '@mui/material'\nimport {\n  LuckyTokenAmountType,\n  LuckyTokenClaimType,\n  LuckyTokenViewType,\n} from '@loopring-web/loopring-sdk'\nimport moment from 'moment'\n\nconst BoxStyle = styled(Box)`\n  &.createRedPacket {\n    .container {\n      align-items: center;\n      display: flex;\n    }\n  }\n`\nexport const CreateRedPacketPanel = <\n  T extends Partial<RedPacketOrderData<I>>,\n  I extends any,\n  C = FeeInfo,\n  NFT = NFTWholeINFO,\n>({\n  tradeType,\n  tradeData,\n  disabled,\n  handleOnDataChange,\n  walletMap = {},\n  coinMap = {},\n  tokenMap = {},\n  assetsData,\n  myNFTPanel,\n  onSendTargetRedpacketClick,\n  targetRedPackets,\n  popRedPacket,\n  popRedPacketAmountStr,\n  onClickViewTargetDetail,\n  onCloseRedpacketPop,\n  contacts,\n  isWhiteListed,\n  showExclusiveOption,\n  ...rest\n}: CreateRedPacketProps<T, I, C, NFT> & { assetsData: any[] }) => {\n  const { t, i18n, ready: tReady } = useTranslation(['common', 'error'])\n  const { redPacketConfig } = rest\n  const { onChangeEvent, index, switchData } = useBasicTrade({\n    ...rest,\n    coinMap,\n    type: tradeType,\n    // index,\n    walletMap,\n  } as any)\n  const [panelIndex, setPanelIndex] = React.useState<RedPacketStep | TargetRedPacketStep>(\n    tradeType === RedPacketOrderType.FromNFT ? RedPacketStep.ChooseType : RedPacketStep.TradeType,\n  )\n\n  let steps: string[]\n  if (tradeData.type?.scope === LuckyTokenViewType.TARGET) {\n    if (tradeType === RedPacketOrderType.FromNFT) {\n      steps = [\n        'labelRedPacketChoose', //Prepare NFT metadata\n        'labelRedPacketMain', //labelADMint2\n        'labelRedPacketRecipientList', //labelADMint2\n      ]\n    } else {\n      steps = [\n        'labelRedPacketChooseTarget', //labelADMint2\n        'labelRedPacketTypeTokens', //labelADMint2\n        'labelRedPacketChoose', //Prepare NFT metadata\n        'labelRedPacketMain', //labelADMint2\n        'labelRedPacketRecipientList', //labelADMint2\n      ]\n    }\n  } else {\n    if (tradeType === RedPacketOrderType.FromNFT) {\n      steps = [\n        'labelRedPacketChoose', //Prepare NFT metadata\n        'labelRedPacketMain', //labelADMint2\n      ]\n    } else {\n      steps = [\n        'labelRedPacketTypeTokens', //labelADMint2\n        'labelRedPacketChoose', //Prepare NFT metadata\n        'labelRedPacketMain', //labelADMint2\n      ]\n    }\n  }\n\n  React.useEffect(() => {\n    if (tradeData.type?.scope === LuckyTokenViewType.TARGET) {\n      if (tradeData.target?.redpacketHash) {\n        setActiveStep(TargetRedPacketStep.TargetSend)\n      } else if (!isToken && tradeData.nftData && panelIndex === TargetRedPacketStep.NFTList) {\n        setActiveStep(TargetRedPacketStep.Main)\n      }\n    } else {\n      if (!isToken && tradeData.nftData && panelIndex === RedPacketStep.NFTList) {\n        setActiveStep(RedPacketStep.Main)\n      }\n    }\n  }, [tradeData?.nftData, panelIndex, tradeType, tradeData.target?.redpacketHash])\n  React.useEffect(() => {\n    if (tradeData.tradeType !== RedPacketOrderType.FromNFT) {\n      handleOnDataChange({\n        type: {\n          ...tradeData.type,\n          scope: LuckyTokenViewType.PRIVATE,\n          mode: LuckyTokenClaimType.BLIND_BOX,\n          partition: LuckyTokenAmountType.RANDOM,\n        },\n        tradeType: RedPacketOrderType.BlindBox,\n      } as any)\n    } else {\n      handleOnDataChange({\n        type: {\n          ...tradeData.type,\n          scope: LuckyTokenViewType.PRIVATE,\n          mode: LuckyTokenClaimType.BLIND_BOX,\n          partition: LuckyTokenAmountType.RANDOM,\n        },\n      } as any)\n    }\n  }, [])\n\n  const setActiveStep = React.useCallback(\n    (index: RedPacketStep | TargetRedPacketStep) => {\n      if (tradeData.type?.scope === LuckyTokenViewType.TARGET) {\n        switch (index) {\n          case TargetRedPacketStep.TargetChosse:\n            setPanelIndex(0)\n            break\n          case TargetRedPacketStep.TradeType:\n            if (tradeType === RedPacketOrderType.FromNFT) {\n              setPanelIndex(0)\n            } else {\n              setPanelIndex(1)\n            }\n            break\n          case TargetRedPacketStep.ChooseType:\n            if (tradeType !== RedPacketOrderType.FromNFT) {\n              handleOnDataChange({\n                collectionInfo: undefined,\n                tokenId: undefined,\n                tradeValue: undefined,\n                balance: undefined,\n                nftData: undefined,\n                belong: undefined,\n                tokenAddress: undefined,\n                image: undefined,\n              } as any)\n            }\n            if (tradeType === RedPacketOrderType.FromNFT) {\n              setPanelIndex(0)\n            } else {\n              setPanelIndex(2)\n            }\n            break\n          case TargetRedPacketStep.Main:\n            handleOnDataChange({\n              validSince: Date.now(),\n            } as any)\n            if (tradeType === RedPacketOrderType.FromNFT) {\n              setPanelIndex(1)\n            } else {\n              setPanelIndex(3)\n            }\n            break\n          case TargetRedPacketStep.NFTList:\n            if (tradeType === RedPacketOrderType.FromNFT) {\n              setPanelIndex(2)\n            } else {\n              setPanelIndex(4)\n            }\n            break\n          case TargetRedPacketStep.TargetSend:\n            if (tradeType === RedPacketOrderType.FromNFT) {\n              setPanelIndex(3)\n            } else {\n              setPanelIndex(5)\n            }\n            break\n        }\n      } else {\n        switch (index) {\n          case RedPacketStep.TradeType:\n            setPanelIndex(0)\n            break\n          case RedPacketStep.ChooseType:\n            if (tradeType !== RedPacketOrderType.FromNFT) {\n              handleOnDataChange({\n                collectionInfo: undefined,\n                tokenId: undefined,\n                tradeValue: undefined,\n                balance: undefined,\n                nftData: undefined,\n                belong: undefined,\n                tokenAddress: undefined,\n                image: undefined,\n              } as any)\n            }\n            if (tradeType === RedPacketOrderType.FromNFT) {\n              setPanelIndex(0)\n            } else {\n              setPanelIndex(1)\n            }\n            break\n          case RedPacketStep.Main:\n            handleOnDataChange({\n              validSince: Date.now(),\n            } as any)\n            if (tradeType === RedPacketOrderType.FromNFT) {\n              setPanelIndex(1)\n            } else {\n              setPanelIndex(2)\n            }\n            break\n          case RedPacketStep.NFTList:\n            if (tradeType === RedPacketOrderType.FromNFT) {\n              setPanelIndex(2)\n            } else {\n              setPanelIndex(3)\n            }\n            break\n        }\n      }\n    },\n    [tradeData.type?.scope],\n  )\n  React.useEffect(() => {\n    setPanelIndex((state) => {\n      if (state > 1) {\n        if (tradeData.type?.scope === LuckyTokenViewType.TARGET) {\n          return index + 3\n        } else {\n          return index + 2\n        }\n      } else {\n        return state\n      }\n    })\n  }, [index, tradeData.type?.scope])\n  // LP token should not exist in withdraw panel for now\n  const getWalletMapWithoutLP = React.useCallback(() => {\n    const clonedWalletMap = cloneDeep(walletMap ?? {})\n    const keyList = Object.keys(clonedWalletMap)\n    keyList.forEach((key) => {\n      const [first] = key.split('-')\n      if (first === 'LP') {\n        delete clonedWalletMap[key]\n      }\n    })\n    return clonedWalletMap\n  }, [walletMap])\n  const [selectedType, setSelectType] = React.useState(\n    \n    tradeData.tradeType === RedPacketOrderType.NFT\n      ? LuckyRedPacketList.find((config) => config.tags?.includes('defaultForNFT'))\n      : tradeData.tradeType === RedPacketOrderType.BlindBox\n      ? LuckyRedPacketList.find((config) =>\n          config.tags?.includes('defaultForBlindBox')\n        )\n      : tradeData.tradeType === RedPacketOrderType.FromNFT\n      ? LuckyRedPacketList.find((config) => config.tags?.includes('defaultForFromNFT'))\n      : LuckyRedPacketList.find((config) => config.tags?.includes('defaultForERC20')),\n  )\n\n  const [privateChecked, setPrivateChecked] = React.useState(false)\n  const isToken =\n    tradeType === RedPacketOrderType.TOKEN ||\n    (tradeType === RedPacketOrderType.BlindBox && !tradeData.isNFT)\n  const [showScope, setShowScope] = React.useState(true)\n  const backToScope = () => setShowScope(true)\n  const props: SwitchPanelProps<string> = React.useMemo(() => {\n    const isTarget = tradeData.type?.scope === LuckyTokenViewType.TARGET\n    let showNFT = isTarget\n      ? redPacketConfig.showNFT\n      : redPacketConfig.showNFT && tradeData.type?.scope !== LuckyTokenViewType.PUBLIC\n\n    const tradeMenuListPanel = {\n      key: 'tradeMenuList',\n      element: (\n        <TradeMenuList\n          {...({\n            nonZero: true,\n            sorted: true,\n            selected: switchData.tradeData.belong,\n            tradeData: switchData.tradeData,\n            walletMap: getWalletMapWithoutLP(),\n            t,\n            ...rest,\n            onChangeEvent,\n            coinMap,\n            //oinMap\n          } as any)}\n        />\n      ),\n      toolBarItem: undefined,\n    }\n    const nftListPanel = {\n      key: 'nftList',\n      element: myNFTPanel,\n      toolBarItem: undefined,\n    }\n    const selectTypePanel = {\n      key: 'selectType',\n      element: (\n        <CreateRedPacketStepType\n          {...({\n            ...rest,\n            handleOnDataChange: handleOnDataChange as any,\n            tradeData: {\n              ...tradeData,\n              type: tradeData.type,\n            } as any,\n            disabled,\n            tradeType,\n            selectedType,\n            setActiveStep,\n            activeStep: RedPacketStep.ChooseType,\n            onClickNext: () => {\n              if (tradeData.type?.scope === LuckyTokenViewType.TARGET) {\n                setActiveStep(TargetRedPacketStep.Main)\n              } else {\n                setActiveStep(RedPacketStep.Main)\n              }\n            },\n          } as any)}\n          privateChecked={privateChecked}\n          onChangePrivateChecked={() => {\n            handleOnDataChange({\n              type: {\n                ...tradeData?.type,\n                scope: !privateChecked ? 1 : 0,\n              },\n            } as any)\n            setPrivateChecked(!privateChecked)\n          }}\n          backToScope={backToScope}\n          showNFT={showNFT}\n          onSelecteValue={(item) => {\n            setSelectType(item)\n            if (tradeType === RedPacketOrderType.BlindBox) {\n              handleOnDataChange({\n                isNFT: item.isBlindboxNFT ? true : false,\n                type: {\n                  ...tradeData?.type,\n                  partition: item.value.partition,\n                  mode: item.value.mode,\n                },\n              } as any)\n            } else {\n              handleOnDataChange({\n                type: {\n                  ...tradeData?.type,\n                  partition: item.value.partition,\n                  mode: item.value.mode,\n                },\n              } as any)\n            }\n          }}\n        />\n      ),\n      toolBarItem: undefined,\n    }\n    const tradePanel = {\n      key: 'trade',\n      element: (\n        // @ts-ignore\n        <CreateRedPacketStepWrap\n          {...{\n            ...rest,\n            tradeData,\n            disabled,\n            coinMap,\n            selectedType,\n            handleOnDataChange: handleOnDataChange as any,\n            tradeType,\n            tokenMap,\n            walletMap: getWalletMapWithoutLP(),\n            onChangeEvent,\n            setActiveStep,\n            activeStep: RedPacketStep.Main,\n          }}\n        />\n      ),\n      toolBarItem: undefined,\n    }\n    const selectTokenTypePanel = {\n      key: 'selectTokenType',\n      element: (\n        <CreateRedPacketStepTokenType\n          {...({\n            ...rest,\n            handleOnDataChange: handleOnDataChange as any,\n            disabled,\n            tradeType,\n            setActiveStep,\n            activeStep: RedPacketStep.TradeType,\n            backToScope: backToScope,\n            onClickBack: () => {\n              if (tradeData.type?.scope === LuckyTokenViewType.TARGET) {\n                setActiveStep(TargetRedPacketStep.TargetChosse)\n              } else {\n                backToScope()\n              }\n            },\n            onClickNext: () => {\n              if (tradeData.type?.scope === LuckyTokenViewType.TARGET) {\n                setActiveStep(TargetRedPacketStep.ChooseType)\n              } else {\n                setActiveStep(RedPacketStep.ChooseType)\n              }\n            },\n            showNFT,\n            onChangeTradeType: (tradeType) => {\n              const found =\n                tradeType === RedPacketOrderType.NFT\n                  ? LuckyRedPacketList.find((config) => config.tags?.includes('defaultForNFT'))\n                  : tradeType === RedPacketOrderType.BlindBox\n                  ? LuckyRedPacketList.find((config) =>\n                      config.tags?.includes('defaultForBlindBox'),\n                    )\n                  : tradeType === RedPacketOrderType.FromNFT\n                  ? LuckyRedPacketList.find((config) => config.tags?.includes('defaultForFromNFT'))\n                  : LuckyRedPacketList.find((config) => config.tags?.includes('defaultForERC20'))\n\n              setSelectType(found)\n\n              handleOnDataChange({\n                type: {\n                  ...tradeData?.type,\n                  partition: found!.value.partition,\n                  mode: found!.value.mode,\n                },\n                isNFT:\n                  tradeType === RedPacketOrderType.NFT ||\n                  tradeType === RedPacketOrderType.FromNFT ||\n                  (tradeType === RedPacketOrderType.BlindBox && !redPacketConfig?.showERC20Blindbox)\n                    ? true\n                    : false,\n                tradeType,\n              } as any)\n            },\n          } as any)}\n        />\n      ),\n      toolBarItem: undefined,\n    }\n    const targetSelectPanel = {\n      key: 'targetSelect',\n      element: (\n        <TargetRedpacktSelectStep\n          backToScope={backToScope}\n          onCloseRedpacketPop={onCloseRedpacketPop}\n          popRedPacket={popRedPacket}\n          popRedPacketAmountStr={popRedPacketAmountStr}\n          onClickExclusiveRedpacket={(info) => {\n            handleOnDataChange({\n              target: {\n                ...tradeData.target,\n                redpacketHash: info.hash,\n                maxSendCount: info.remainCount,\n              },\n            } as any)\n            setActiveStep(TargetRedPacketStep.TargetSend)\n          }}\n          targetRedPackets={targetRedPackets}\n          onClickCreateNew={() => {\n            window.scrollTo(0, 0)\n            setActiveStep(TargetRedPacketStep.TradeType)\n          }}\n          onClickViewDetail={(hash) => {\n            onClickViewTargetDetail(hash)\n          }}\n          {...{ ...rest }}\n        />\n      ),\n      toolBarItem: undefined,\n    }\n    const maximumTargetsLength = tradeData.target?.maxSendCount ?? 0\n    const targetInputAddressPanel = {\n      key: 'targetInputAddress',\n      element: (\n        <TargetRedpacktInputAddressStep\n          maximumTargetsLength={maximumTargetsLength}\n          contacts={contacts}\n          addressListString={tradeData.target?.addressListString ?? ''}\n          popupChecked={\n            isWhiteListed\n              ? tradeData.target?.popupChecked !== undefined\n                ? tradeData.target?.popupChecked\n                : true\n              : false\n          }\n          onChangePopupChecked={(popupChecked) => {\n            handleOnDataChange({\n              target: {\n                ...tradeData.target,\n                popupChecked,\n              },\n            } as any)\n          }}\n          onFileInput={(input) => {\n            handleOnDataChange({\n              target: {\n                ...tradeData.target,\n                addressListString: input\n                  .split(';')\n                  .map((value) => value.trim())\n                  .slice(0, maximumTargetsLength)\n                  .join(';\\n'),\n              },\n            } as any)\n          }}\n          onManualEditInput={(input) => {\n            handleOnDataChange({\n              target: {\n                ...tradeData.target,\n                addressListString: input,\n              },\n            } as any)\n          }}\n          onClickSend={() => {\n            onSendTargetRedpacketClick().then(() => {\n              handleOnDataChange({\n                target: undefined,\n              } as any)\n              setActiveStep(TargetRedPacketStep.TargetChosse)\n            })\n          }}\n          onConfirm={(addressList) => {\n            handleOnDataChange({\n              target: {\n                ...tradeData.target,\n                addressListString: [\n                  ...(tradeData.target?.addressListString ? tradeData.target.addressListString.split(';\\n') : []),\n                  ...addressList\n                ].join(';\\n'),\n              },\n            } as any)\n          }}\n          popUpOptionDisabled={isWhiteListed ? false : true}\n          onClickBack={() => {\n            handleOnDataChange({\n              target: undefined,\n            } as any)\n            setActiveStep(TargetRedPacketStep.TargetChosse)\n          }}\n          sentAddresses={tradeData.target?.sentAddresses}\n          clearInput={() => {\n            handleOnDataChange({\n              numbers: undefined,\n              tradeValue: undefined,\n              validSince: Date.now(),\n              validUntil: moment().add('days', 1).toDate().getTime(),\n              giftNumbers: undefined,\n              memo: '',\n            } as any)\n          }}\n        />\n      ),\n      toolBarItem: undefined,\n    }\n    const tokenNFTSelectionPanel = isToken\n      ? tradeMenuListPanel\n      : myNFTPanel\n      ? nftListPanel\n      : undefined\n    return {\n      index: panelIndex,\n      _width: '100%',\n      panelList: [\n        ...(isTarget && tradeData.tradeType !== RedPacketOrderType.FromNFT\n          ? [targetSelectPanel]\n          : []),\n        ...(tradeData.tradeType !== RedPacketOrderType.FromNFT ? [selectTokenTypePanel] : []),\n        selectTypePanel,\n        tradePanel,\n        tokenNFTSelectionPanel as any,\n        ...(isTarget ? [targetInputAddressPanel] : []),\n      ],\n      scrollDisabled:\n        tradeData.type?.scope === LuckyTokenViewType.TARGET &&\n        panelIndex !== TargetRedPacketStep.TargetSend,\n    }\n  }, [\n    tradeData,\n    rest,\n    tradeType,\n    switchData,\n    coinMap,\n    assetsData,\n    rest,\n    walletMap,\n    onChangeEvent,\n    getWalletMapWithoutLP,\n    panelIndex,\n    disabled,\n    tradeData,\n    isToken,\n    tradeData.type?.scope,\n  ])\n\n  let activeStep\n  if (tradeData.type?.scope === LuckyTokenViewType.TARGET) {\n    activeStep = panelIndex === 3 || panelIndex === 4 ? 3 : panelIndex\n  } else {\n    activeStep = panelIndex === 2 || panelIndex === 3 ? 2 : panelIndex\n  }\n  return (\n    <BoxStyle\n      className={walletMap ? 'createRedPacket' : 'loading createRedPacket'}\n      display={'flex'}\n      flex={1}\n      flexDirection={'column'}\n      paddingY={5 / 2}\n      paddingTop={3}\n      paddingBottom={0}\n      alignItems={'center'}\n    >\n      {showScope ? (\n        <CreateRedPacketScope\n          palazaPublicDisabled={tradeData.tradeType === RedPacketOrderType.FromNFT}\n          onClickNext={() => {\n            if (tradeData.type?.scope === LuckyTokenViewType.TARGET) {\n              setActiveStep(TargetRedPacketStep.TargetChosse)\n            } else {\n              setActiveStep(RedPacketStep.TradeType)\n            }\n            setShowScope(false)\n          }}\n          onSelecteScope={(scope) => {\n            if (tradeData.tradeType === RedPacketOrderType.FromNFT) {\n              handleOnDataChange({\n                type: {\n                  ...tradeData?.type,\n                  scope: scope,\n                  mode: LuckyTokenClaimType.BLIND_BOX,\n                  partition: LuckyTokenAmountType.RANDOM,\n                },\n              } as any)\n              setSelectType(LuckyRedPacketList.find((config) => config.tags?.includes('defaultForFromNFT')))\n            } else {\n              const found = LuckyRedPacketList.find((config) =>\n                config.tags?.includes('defaultForBlindBox') \n              )\n              setSelectType(found)\n              handleOnDataChange({\n                type: {\n                  ...tradeData?.type,\n                  scope: scope,\n                  mode: LuckyTokenClaimType.BLIND_BOX,\n                  partition: LuckyTokenAmountType.RANDOM,\n                },\n                isNFT: false,\n                tradeType: RedPacketOrderType.BlindBox,\n              } as any)\n            }\n          }}\n          selectedScope={tradeData.type!.scope!}\n          showBackBtn={tradeData.tradeType === RedPacketOrderType.FromNFT}\n          showExclusiveOption={showExclusiveOption ? true : false}\n        />\n      ) : (\n        <>\n          <HorizontalLabelPositionBelowStepper activeStep={activeStep} steps={steps} />\n          <Box paddingTop={2} display={'flex'} flex={1} width={'100%'} minWidth={240} paddingX={3}>\n            <SwitchPanel {...{ ...rest, tReady, i18n, t, ...props }} />\n          </Box>\n        </>\n      )}\n    </BoxStyle>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/ModalPanels/DeployNFT.tsx",
    "content": "import { DeployBase, IconType, PanelProps } from './BasicPanel'\nimport { NFTWholeINFO } from '@loopring-web/common-resources'\nimport { sanitize } from 'dompurify'\n\nexport const NFTDeploy_WaitForAuth = (props: PanelProps & Partial<NFTWholeINFO>) => {\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelNFTTokenDeployWaitForAuth', {\n      symbol: props.symbol,\n      value: props.value,\n    }),\n  }\n  return <DeployBase {...propsPatch} {...props} />\n}\n\nexport const NFTDeploy_Denied = (props: PanelProps & Partial<NFTWholeINFO>) => {\n  const propsPatch = {\n    iconType: IconType.RefuseIcon,\n    describe1: props.t('labelDeployDenied', {\n      symbol: props.symbol,\n      value: props.value,\n    }),\n  }\n  return <DeployBase {...propsPatch} {...props} />\n}\nexport const NFTDeploy_First_Method_Denied = (props: PanelProps & Partial<NFTWholeINFO>) => {\n  const propsPatch = {\n    iconType: IconType.RefuseIcon,\n    describe1: props.t('labelFirstSignDenied', {\n      symbol: sanitize(props.symbol ?? 'NFT'),\n      value: props.value,\n    }),\n  }\n  return <DeployBase {...propsPatch} {...props} />\n}\nexport const NFTDeploy_In_Progress = (props: PanelProps & Partial<NFTWholeINFO>) => {\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelDeployInProgress', {\n      symbol: sanitize(props.symbol ?? 'NFT'),\n      value: props.value,\n    }),\n  }\n  return <DeployBase {...propsPatch} {...props} />\n}\n\nexport const NFTDeploy_Failed = (props: PanelProps & Partial<NFTWholeINFO>) => {\n  const propsPatch = {\n    iconType: IconType.FailedIcon,\n    describe1: props.t('labelDeployFailed', {\n      symbol: sanitize(props.symbol ?? 'NFT'),\n      value: props.value,\n    }),\n  }\n  return <DeployBase {...propsPatch} {...props} />\n}\n\nexport const NFTDeploy_Submit = (props: PanelProps & Partial<NFTWholeINFO>) => {\n  const propsPatch = {\n    iconType: IconType.SubmitIcon,\n    describe1: props.t('labelDeploySubmit', {\n      symbol: sanitize(props.symbol ?? 'NFT'),\n      value: props.value,\n    }),\n  }\n  return <DeployBase {...propsPatch} {...props} />\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/ModalPanels/Deposit.tsx",
    "content": "import { Trans, useTranslation } from 'react-i18next'\nimport { DepositBase, IconType, PanelProps } from './BasicPanel'\nimport { Box, Link, Typography } from '@mui/material'\nimport {\n  getShortAddr,\n  L1L2_NAME_DEFINED,\n  LinkIcon,\n  MapChainId,\n  SPECIAL_ACTIVATION_NETWORKS,\n} from '@loopring-web/common-resources'\nimport { useSettings } from '../../../stores'\nimport { ChainId } from '@loopring-web/loopring-sdk'\nimport { useSystem } from '@loopring-web/core'\n\nexport const Deposit_Sign_WaitForRefer = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelWaitingRefer'),\n  }\n  return <DepositBase {...props} {...propsPatch} />\n}\n\nexport const Deposit_Approve_WaitForAuth = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelTokenAccess', { symbol: props.symbol }),\n  }\n  return <DepositBase {...props} {...propsPatch} />\n}\n\nexport const Deposit_Approve_Denied = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.RefuseIcon,\n    describe1: props.t('labelFailedTokenAccess', {\n      symbol: props.symbol,\n      value: props.value,\n    }),\n  }\n  return <DepositBase {...propsPatch} {...props} />\n}\n\nexport const Deposit_WaitForAuth = (props: PanelProps) => {\n  const { defaultNetwork } = useSettings()\n  const { app } = useSystem()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const isSpecialActivation = app === 'earn' && SPECIAL_ACTIVATION_NETWORKS.includes(defaultNetwork)\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe1: (\n      <Typography variant='h5' width={'400px'}>\n        {isSpecialActivation\n          ? props.t('labelL1toL2WaitForAuthTaikoEarn', {\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n              symbol: props.symbol,\n              value: props.value,\n              to: props.to ?? '',\n            })\n          : props.t('labelL1toL2WaitForAuth', {\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n              symbol: props.symbol,\n              value: props.value,\n              to: props.to ?? '',\n            })}\n      </Typography>\n    ),\n  }\n  return <DepositBase {...propsPatch} {...props} />\n}\n\nexport const Deposit_Denied = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.RefuseIcon,\n    describe1: props.t('labelL1toL2Denied', {\n      symbol: props.symbol,\n      value: props.value,\n    }),\n  }\n  return <DepositBase {...propsPatch} {...props} />\n}\n\nexport const Deposit_Failed = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.FailedIcon,\n    describe1: props.t('labelL1toL2Failed', {\n      symbol: props.symbol,\n      value: props.value,\n    }),\n  }\n  return <DepositBase {...propsPatch} {...props} />\n}\n\nexport const Deposit_Submit = (props: PanelProps) => {\n  const { defaultNetwork, isMobile } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const { t } = useTranslation()\n  const propsPatch = {\n    iconType: IconType.SubmitIcon,\n    describe1: (\n      <Link\n        fontSize={'inherit'}\n        whiteSpace={'break-spaces'}\n        display={'inline-flex'}\n        alignItems={'center'}\n        style={{ wordBreak: 'break-all' }}\n        target='_blank'\n        rel='noopener noreferrer'\n        href={`${props.etherscanBaseUrl}tx/${props?.hash ?? ''}`}\n      >\n        <Trans\n          i18nKey={'labelL1toL2Submit'}\n          tOptions={{\n            symbol: props.symbol,\n            value: props.value,\n          }}\n        >\n          Add asset submitted.\n          <LinkIcon color={'inherit'} fontSize={'medium'} />\n        </Trans>\n      </Link>\n    ),\n    describe2: (\n      <Box\n        justifySelf={'stretch'}\n        display={'flex'}\n        flexDirection={'column'}\n        minWidth={'var(--modal-min-width)'}\n        justifyContent={'center'}\n        marginTop={2}\n        paddingX={isMobile ? 1 : 0}\n      >\n        <Typography color={'var(--color-warning)'} component={'span'}>\n          {t('labelDepositWaiting')}\n        </Typography>\n        <Typography\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n          component={'span'}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {props.t('labelL1toL2TokenAmount')}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {props.value + ' ' + props.symbol}\n          </Typography>\n        </Typography>\n        <Typography\n          component={'span'}\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n        >\n          <Typography component={'span'} variant={'body1'} color={'var(--color-text-secondary)'}>\n            {props.t('labelL1toL2From')}\n          </Typography>\n          <Typography component={'span'} variant={'body1'} color={'var(--color-text-primary)'}>\n            {'L1: ' + getShortAddr(props.account?.accAddress ?? '')}\n          </Typography>\n        </Typography>\n        <Typography\n          component={'span'}\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n        >\n          <Typography component={'span'} variant={'body1'} color={'var(--color-text-secondary)'}>\n            {props.t('labelL1toL2TO', {\n              l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n              l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n              l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n              ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n            })}\n          </Typography>\n          <Typography component={'span'} variant={'body1'} color={'var(--color-text-primary)'}>\n            {props.to\n              ? `${L1L2_NAME_DEFINED[network].l2Symbol}: ` + getShortAddr(props.to)\n              : t('labelToMyL2', {\n                  l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                  loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                  l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                  l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                  ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                })}\n          </Typography>\n        </Typography>\n      </Box>\n    ),\n  }\n  return <DepositBase {...propsPatch} {...props} />\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/ModalPanels/DepositNFT.tsx",
    "content": "import { DepositBase, IconType, PanelProps } from './BasicPanel'\nimport {\n  getShortAddr,\n  L1L2_NAME_DEFINED,\n  LinkIcon,\n  MapChainId,\n  NFTWholeINFO,\n} from '@loopring-web/common-resources'\nimport { sanitize } from 'dompurify'\nimport { Box, Link, Typography } from '@mui/material'\nimport { Trans, useTranslation } from 'react-i18next'\nimport { useSettings } from '../../../stores'\n\nexport const NFTDeposit_Approve_WaitForAuth = (\n  props: PanelProps & Partial<NFTWholeINFO> & Partial<NFTWholeINFO>,\n) => {\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelNFTAccess', {\n      symbol: props?.symbol ?? 'NFT',\n      l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n      loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n      l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n      l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n      ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n    }),\n  }\n  return <DepositBase {...props} {...propsPatch} />\n}\n\nexport const NFTDeposit_Approve_Denied = (\n  props: PanelProps & Partial<NFTWholeINFO> & Partial<NFTWholeINFO>,\n) => {\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const propsPatch = {\n    iconType: IconType.RefuseIcon,\n    describe1: props.t('labelNFTTokenFailedAccess', {\n      symbol: props?.symbol ?? 'NFT',\n      value: props.value,\n      l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n      loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n      l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n      l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n      ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n    }),\n  }\n  return <DepositBase {...propsPatch} {...props} />\n}\n\nexport const NFTDeposit_WaitForAuth = (props: PanelProps & Partial<NFTWholeINFO>) => {\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelNFTTokenDepositWaitForAuth', {\n      l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n      loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n      l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n      l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n      ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n      symbol: props?.symbol ?? 'NFT',\n      value: props.value,\n    }),\n  }\n  return <DepositBase {...propsPatch} {...props} />\n}\n\nexport const NFTDeposit_Denied = (props: PanelProps & Partial<NFTWholeINFO>) => {\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const propsPatch = {\n    iconType: IconType.RefuseIcon,\n    describe1: props.t('labelL1toL2Denied', {\n      symbol: props?.symbol ?? 'NFT',\n      value: props.value,\n      loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n      l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n      l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n      ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n    }),\n  }\n  return <DepositBase {...propsPatch} {...props} />\n}\n\nexport const NFTDeposit_Failed = (props: PanelProps & Partial<NFTWholeINFO>) => {\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const propsPatch = {\n    iconType: IconType.FailedIcon,\n    describe1: props.t('labelL1toL2Failed', {\n      symbol: sanitize(props.symbol ?? 'NFT').toString(),\n      value: props.value,\n      l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n      loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n      l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n      l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n      ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n    }),\n  }\n  return <DepositBase {...propsPatch} {...props} />\n}\n\nexport const NFTDeposit_Submit = (props: PanelProps & Partial<NFTWholeINFO>) => {\n  const { defaultNetwork, isMobile } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const { t } = useTranslation()\n\n  const propsPatch = {\n    iconType: IconType.SubmitIcon,\n    describe1: (\n      <Link\n        fontSize={'inherit'}\n        whiteSpace={'break-spaces'}\n        display={'inline-flex'}\n        alignItems={'center'}\n        style={{ wordBreak: 'break-all' }}\n        target='_blank'\n        rel='noopener noreferrer'\n        href={`${props.etherscanBaseUrl}tx/${props?.hash ?? ''}`}\n      >\n        <Trans\n          i18nKey={'labelL1toL2Submit'}\n          tOptions={{\n            symbol: sanitize(props.symbol ?? 'NFT').toString(),\n            value: props.value,\n            l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n            loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n            l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n            l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n            ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n          }}\n        >\n          Add asset submitted.\n          <LinkIcon color={'inherit'} fontSize={'medium'} />\n        </Trans>\n      </Link>\n    ),\n    describe2: (\n      <Box\n        justifySelf={'stretch'}\n        display={'flex'}\n        flexDirection={'column'}\n        minWidth={'var(--modal-min-width)'}\n        justifyContent={'center'}\n        marginTop={2}\n        paddingX={isMobile ? 1 : 0}\n      >\n        <Typography component={'span'} color={'var(--color-warning)'}>\n          {t('labelDepositWaiting')}\n        </Typography>\n        <Typography\n          component={'span'}\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n        >\n          <Typography component={'span'} variant={'body1'} color={'var(--color-text-secondary)'}>\n            {props.t('labelL1toL2NFTAmount', {\n              l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n              l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n              l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n              ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n            })}\n          </Typography>\n          <Typography\n            variant={'body1'}\n            component={'span'}\n            color={'var(--color-text-primary)'}\n            textOverflow={'ellipsis'}\n            overflow={'hidden'}\n          >\n            {props.value + ' ' + props.symbol}\n          </Typography>\n        </Typography>\n        <Typography\n          component={'span'}\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n        >\n          <Typography component={'span'} variant={'body1'} color={'var(--color-text-secondary)'}>\n            {props.t('labelL1toL2From', {\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n              l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n              l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n              ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n            })}\n          </Typography>\n          <Typography component={'span'} variant={'body1'} color={'var(--color-text-primary)'}>\n            {'L1: ' + getShortAddr(props.account?.accAddress ?? '')}\n          </Typography>\n        </Typography>\n        <Typography\n          component={'span'}\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n        >\n          <Typography component={'span'} variant={'body1'} color={'var(--color-text-secondary)'}>\n            {props.t('labelL1toL2TO', {\n              l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n              l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n              l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n              ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n            })}\n          </Typography>\n          <Typography component={'span'} variant={'body1'} color={'var(--color-text-primary)'}>\n            {props.to\n              ? `${L1L2_NAME_DEFINED[network].l2Symbol}: ` + getShortAddr(props.to)\n              : t('labelToMyL2', {\n                  l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                  loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                  l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                  l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                  ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                })}\n          </Typography>\n        </Typography>\n      </Box>\n    ),\n  }\n  return <DepositBase {...propsPatch} {...props} />\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/ModalPanels/DepositPanel.tsx",
    "content": "import { DepositProps } from '../../tradePanel/Interface'\nimport { Trans, withTranslation, WithTranslation } from 'react-i18next'\nimport {\n  CoinInfo,\n  CoinMap,\n  IBData,\n  L1L2_NAME_DEFINED,\n  MapChainId,\n  SoursURL,\n  TRADE_TYPE,\n} from '@loopring-web/common-resources'\nimport { ModalBackButton, SwitchPanel, SwitchPanelProps } from '../../basic-lib'\nimport { DepositWrap, TradeMenuList, useBasicTrade } from '../../tradePanel/components'\nimport React from 'react'\nimport { cloneDeep } from 'lodash'\nimport { DepositConfirm } from '../../tradePanel/components/DepositConfirm'\nimport { useSettings } from '../../../stores'\nimport { Box, Typography } from '@mui/material'\n\nexport const DepositPanel = withTranslation('common', { withRef: true })(\n  <\n    T extends {\n      toAddress?: string\n      addressError?: { error: boolean; message: string }\n    } & IBData<I>,\n    I,\n  >({\n    type = TRADE_TYPE.TOKEN,\n    onDepositClick,\n    depositBtnStatus,\n    walletMap = {},\n    coinMap = {},\n    accountReady,\n    addressDefault,\n    allowTrade,\n    isShow,\n    isLoopringSmartWallet,\n    onBack,\n    t,\n    ...rest\n  }: DepositProps<T, I> & WithTranslation) => {\n    const { defaultNetwork } = useSettings()\n    const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n    const { onChangeEvent, index, switchData } = useBasicTrade({\n      ...rest,\n      type,\n      walletMap,\n      coinMap,\n    } as any)\n    const [panelIndex, setPanelIndex] = React.useState(index + 1)\n    const handleConfirm = (index: number) => {\n      setPanelIndex(index)\n    }\n    // const hanleConfirm = () => {};\n    React.useEffect(() => {\n      setPanelIndex(index + 1)\n    }, [index])\n\n    const getFilteredWalletMap = React.useCallback(() => {\n      if (walletMap) {\n        const clonedWalletMap = cloneDeep(walletMap)\n        Object.values(clonedWalletMap).forEach((o: any) => {\n          if (o.belong && o.count && Number(o.count) === 0) {\n            delete clonedWalletMap[o.belong]\n          }\n        })\n        return clonedWalletMap\n      }\n      return {}\n    }, [walletMap])\n\n    const getFilteredCoinMap: any = React.useCallback(() => {\n      if (coinMap && getFilteredWalletMap()) {\n        const clonedCoinMap = cloneDeep(coinMap)\n        const remainList = {}\n        Object.keys(getFilteredWalletMap()).forEach((token) => {\n          if (clonedCoinMap[token]) {\n            remainList[token] = clonedCoinMap[token]\n          }\n        })\n        return remainList\n      }\n      return {}\n    }, [coinMap, getFilteredWalletMap])\n\n    const props: SwitchPanelProps<'tradeMenuList' | 'trade' | 'confirm'> = {\n      index: panelIndex, // show default show\n      panelList: [\n        {\n          key: 'confirm',\n          element: React.useMemo(\n            () => (\n              // @ts-ignore\n              <DepositConfirm\n                {...{\n                  ...rest,\n                  t,\n                  realToAddress: rest.isAllowInputToAddress ? (\n                    rest.realToAddress\n                  ) : (\n                    <Trans\n                      i18nKey={'labelToMyL2WidthAddress'}\n                      tOptions={{\n                        loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                        l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                        l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                        ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                        address: rest.realToAddress,\n                      }}\n                    >\n                      <Typography\n                        color={'inherit'}\n                        variant={'body1'}\n                        display={'flex'}\n                        component={'span'}\n                        sx={{ opacity: 1 }}\n                        paddingLeft={1 / 2}\n                      >\n                        My L2\n                      </Typography>\n                      <Typography\n                        color={'var(--color-text-third)'}\n                        variant={'body2'}\n                        display={'flex'}\n                        component={'span'}\n                        sx={{ opacity: 1 }}\n                        paddingLeft={1 / 2}\n                      >\n                        (address)\n                      </Typography>\n                    </Trans>\n                  ),\n                  tradeData: switchData.tradeData,\n                  onDepositClick,\n                  handleConfirm,\n                }}\n              />\n            ),\n            [rest, handleConfirm, onDepositClick, type, switchData.tradeData],\n          ),\n          toolBarItem: (\n            <ModalBackButton\n              marginTop={0}\n              marginLeft={-2}\n              onBack={() => {\n                setPanelIndex(1)\n              }}\n              {...rest}\n            />\n          ),\n        },\n        {\n          key: 'trade',\n          // onBack,\n          element: React.useMemo(\n            () => (\n              // @ts-ignore\n              <DepositWrap<T, I>\n                key={'trade'}\n                {...{\n                  ...rest,\n                  t,\n                  type,\n                  tradeData: switchData.tradeData,\n                  onChangeEvent,\n                  disabled: !!rest.disabled,\n                  handleConfirm,\n                  onDepositClick,\n                  depositBtnStatus,\n                  walletMap,\n                  coinMap,\n                  addressDefault,\n                  allowTrade,\n                  accountReady,\n                  isLoopringSmartWallet\n                }}\n              />\n            ),\n            [\n              rest,\n              switchData.tradeData,\n              onChangeEvent,\n              // onDepositClick,\n              depositBtnStatus,\n              walletMap,\n              coinMap,\n              addressDefault,\n              allowTrade,\n              isLoopringSmartWallet\n            ],\n          ),\n          toolBarItem: React.useMemo(\n            () => (\n              <>\n                {onBack ? (\n                  <ModalBackButton\n                    marginTop={0}\n                    marginLeft={-2}\n                    onBack={() => {\n                      onBack()\n                    }}\n                    {...rest}\n                  />\n                ) : (\n                  <></>\n                )}\n              </>\n            ),\n            [onBack],\n          ),\n        },\n        {\n          key: 'tradeMenuList',\n          element: React.useMemo(\n            () => (\n              // @ts-ignore\n              <TradeMenuList\n                {...{\n                  nonZero: false,\n                  sorted: true,\n                  t,\n                  ...rest,\n                  onChangeEvent,\n                  //rest.walletMap,\n                  selected: switchData.tradeData.belong,\n                  tradeData: switchData.tradeData,\n                  walletMap: getFilteredWalletMap(),\n                  coinMap: getFilteredCoinMap() as CoinMap<I, CoinInfo<I>>,\n                  //oinMap\n                }}\n              />\n            ),\n            [rest, onChangeEvent, switchData.tradeData, getFilteredWalletMap, getFilteredCoinMap],\n          ),\n          toolBarItem: undefined,\n          // toolBarItem: toolBarItemBack\n        },\n      ],\n    }\n    return !switchData.tradeData?.belong || isLoopringSmartWallet === undefined ? (\n      <Box\n        height={'var(--min-height)'}\n        width={'var(--modal-width)'}\n        display={'flex'}\n        flex={1}\n        justifyContent={'center'}\n        flexDirection={'column'}\n        alignItems={'center'}\n      >\n        <img\n          className='loading-gif'\n          alt={'loading'}\n          width='60'\n          src={`${SoursURL}images/loading-line.gif`}\n        />\n      </Box>\n    ) : (\n      <SwitchPanel {...{ ...rest, t, ...props }} />\n    )\n  },\n) as <T, I>(props: DepositProps<T, I> & React.RefAttributes<any>) => JSX.Element\n\n// export const TransferModal = withTranslation()\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/ModalPanels/DepositRecorder.tsx",
    "content": "import { Box, Link, Typography } from '@mui/material'\nimport styled from '@emotion/styled'\nimport React from 'react'\nimport { TFunction } from 'react-i18next'\nimport {\n  AccountHashInfo,\n  CompleteIcon,\n  getFormattedHash,\n  L1L2_NAME_DEFINED,\n  LinkIcon,\n  MapChainId,\n  WaitingIcon,\n  WarningIcon,\n} from '@loopring-web/common-resources'\nimport { useTheme } from '@emotion/react'\nimport { useSettings } from '../../../stores'\n\nconst BoxStyled = styled(Box)`\n  background: var(--color-box-hover);\n  position: relative;\n  overflow-y: scroll;\n  scrollbar-width: none; /* Firefox */\n  -ms-overflow-style: none; /* Internet Explorer 10+ */\n  &::-webkit-scrollbar {\n    /* WebKit */\n    width: 0;\n  }\n  &:before {\n    content: '';\n    position: absolute;\n    display: block;\n    top: 0;\n    left: 0;\n    right: 0;\n    width: 100%;\n    height: 1px;\n    box-shadow: ${({ theme }) => theme.colorBase.shadowHeader};\n  }\n  border-bottom-left-radius: ${({ theme }) => theme.unit}px;\n  border-bottom-right-radius: ${({ theme }) => theme.unit}px;\n` as typeof Box\n\nexport const DepositRecorder = ({\n  t,\n  accAddress,\n  chainInfos,\n  etherscanUrl,\n  clear,\n}: // updateDepositHash\n{ t: TFunction } & {\n  accAddress: string\n  etherscanUrl: string\n  chainInfos: AccountHashInfo\n  clear?: () => void\n  // updateDepositHash: (depositHash: string, accountAddress: string, status?: 'success' | 'failed') => void\n}) => {\n  const theme = useTheme()\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const depositView = React.useMemo(() => {\n    return (\n      <>\n        {chainInfos &&\n        chainInfos?.depositHashes &&\n        chainInfos?.depositHashes[accAddress] &&\n        chainInfos?.depositHashes[accAddress].length ? (\n          <>\n            <Typography\n              display={'inline-flex'}\n              justifyContent={'space-between'}\n              paddingY={1 / 2}\n              component={'h6'}\n            >\n              <Typography\n                component={'p'}\n                variant={'body2'}\n                color={'text.primary'}\n                paddingBottom={1}\n              >\n                {t('labelL1toL2Hash', {\n                  loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                  l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                  l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                  ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                })}\n              </Typography>\n              {clear && (\n                <Link\n                  variant={'body2'}\n                  paddingBottom={1}\n                  onClick={() => {\n                    clear()\n                  }}\n                >\n                  {t('labelClearAll')}\n                </Link>\n              )}\n            </Typography>\n            {chainInfos?.depositHashes[accAddress].map((txInfo) => {\n              return (\n                <Typography\n                  key={txInfo.hash}\n                  display={'inline-flex'}\n                  justifyContent={'space-between'}\n                  fontSize={'h5'}\n                  paddingY={1 / 2}\n                >\n                  <Link\n                    fontSize={'inherit'}\n                    alignItems={'center'}\n                    display={'inline-flex'}\n                    href={`${etherscanUrl}tx/${txInfo.hash}`}\n                    target={'_blank'}\n                    rel={'noopener noreferrer'}\n                  >\n                    {txInfo.symbol ? (\n                      <Typography component={'span'} color={'text.secondary'}>\n                        {t('labelL1toL2Record', {\n                          symbol: txInfo.symbol,\n                          value: txInfo.value,\n                        })}\n                      </Typography>\n                    ) : (\n                      getFormattedHash(txInfo.hash)\n                    )}\n                    <LinkIcon style={{ marginLeft: `${theme.unit}px` }} fontSize={'small'} />\n                  </Link>\n                  <Typography fontSize={'inherit'} component={'span'}>\n                    {txInfo.status === 'pending' ? (\n                      <WaitingIcon fontSize={'large'} color={'warning'} />\n                    ) : txInfo.status === 'success' ? (\n                      <CompleteIcon fontSize={'large'} color={'success'} />\n                    ) : (\n                      <WarningIcon fontSize={'large'} color={'error'} />\n                    )}\n                  </Typography>\n                </Typography>\n              )\n            })}\n          </>\n        ) : (\n          <Typography\n            display={'flex'}\n            flex={1}\n            justifyContent={'center'}\n            flexDirection={'column'}\n            component={'h6'}\n          >\n            <Typography component={'p'} variant={'body1'} color={'text.secondary'}>\n              {t('labelL1toL2HashEmpty', {\n                loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n              })}\n            </Typography>\n          </Typography>\n        )}\n      </>\n    )\n  }, [network, chainInfos?.depositHashes[accAddress]])\n\n  return (\n    <BoxStyled\n      minHeight={60}\n      maxHeight={180}\n      component={'div'}\n      display={'flex'}\n      paddingX={5}\n      paddingY={1}\n      flex={1}\n      flexDirection={'column'}\n      alignSelf={'flex-end'}\n      className={'depositRecord'}\n    >\n      {depositView}\n    </BoxStyled>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/ModalPanels/Dual.tsx",
    "content": "import { AmmBase, BtradeBase, DualBase, IconType, PanelProps, TaikoFarmingMintBase, TaikoFarmingRedeemBase, TaikoFarmingStakeBase } from './BasicPanel'\nimport { Box, ListItemIcon, ListItemText, Tooltip, Typography } from '@mui/material'\nimport { useSettings } from '../../../stores'\nimport {\n  ConvertToIcon,\n  EmptyValueTag,\n  Info2Icon,\n  YEAR_DAY_MINUTE_FORMAT,\n} from '@loopring-web/common-resources'\nimport moment from 'moment'\nimport { CoinIcon } from '../../basic-lib'\n\n// value symbol\nexport const Dual_Success = (props: PanelProps) => {\n  const { isMobile } = useSettings()\n  const propsPatch = {\n    iconType: IconType.PendingIcon,\n    describe1: (\n      <Typography variant={'h5'} color={'var(--color-primary)'} component={'span'}>\n        {props.t('labelDualProcessing', {\n          symbol: props.symbol,\n          value: props.value,\n        })}\n      </Typography>\n    ),\n    describe2: (\n      <Typography\n        justifySelf={'stretch'}\n        display={'flex'}\n        flexDirection={'column'}\n        minWidth={'var(--modal-min-width)'}\n        justifyContent={'center'}\n        marginTop={2}\n        paddingX={isMobile ? 1 : 5}\n        whiteSpace={'pre-line'}\n        color={'textSecondary'}\n        component={'span'}\n      >\n        {props.t('labelDualProcessingDes')}\n      </Typography>\n    ),\n  }\n  return <DualBase showTitle={false} {...propsPatch} {...props} />\n}\n\n// value symbol\nexport const Dual_Failed = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.FailedIcon,\n    describe1: props.t('labelDualFailed', {\n      symbol: props.symbol,\n      value: props.value,\n    }),\n  }\n  return <DualBase showTitle={true} {...propsPatch} {...props} />\n}\n\nexport const Staking_Success = (props: PanelProps) => {\n  const { isMobile } = useSettings()\n  const { info } = props\n  const propsPatch = {\n    iconType: IconType.DoneIcon,\n    describe1: (\n      <Typography variant={'h5'} color={'var(--color-primary)'} component={'span'}>\n        {props.t('labelStakingSuccess', {\n          symbol: info.symbol,\n        })}\n      </Typography>\n    ),\n    describe2: (\n      <Box\n        justifySelf={'stretch'}\n        display={'flex'}\n        flexDirection={'column'}\n        minWidth={'var(--modal-min-width)'}\n        justifyContent={'center'}\n        marginTop={2}\n        paddingX={isMobile ? 1 : 0}\n      >\n        <Typography\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n          component={'span'}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {props.t('labelDeFiSideAmount')}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {info.amount + ' ' + info.symbol}\n          </Typography>\n        </Typography>\n        <Typography\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n          component={'span'}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {props.t('labelDeFiSideProduct')}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {info?.productId ?? EmptyValueTag}\n          </Typography>\n        </Typography>\n        <Typography\n          component={'span'}\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {props.t('labelDeFiSideSubscribeTime')}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {moment(new Date(info.stakeAt))\n              // .utc()\n              // .startOf(\"days\")\n              .format(YEAR_DAY_MINUTE_FORMAT)}\n          </Typography>\n        </Typography>\n        <Typography\n          component={'span'}\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {props.t('labelDeFiSideLockDuration')}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {info.daysDuration\n              ? '≥ ' + info.daysDuration + ' ' + props.t('labelDay')\n              : EmptyValueTag}\n          </Typography>\n        </Typography>\n      </Box>\n    ),\n  }\n  return <DualBase showTitle={false} {...propsPatch} {...props} />\n}\nexport const Staking_Failed = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.FailedIcon,\n    describe1: props.t('labelStakingFailed', {\n      symbol: props.info?.symbol,\n    }),\n  }\n  return <DualBase showTitle={true} {...propsPatch} {...props} />\n}\n\nexport const Staking_Redeem_Success = (props: PanelProps) => {\n  const { isMobile } = useSettings()\n  const { info } = props\n  const propsPatch = {\n    iconType: IconType.DoneIcon,\n    describe1: (\n      <Typography variant={'h5'} color={'var(--color-primary)'}>\n        {props.t('labelStakingRedeemSuccess', {\n          symbol: info?.symbol,\n        })}\n      </Typography>\n    ),\n    describe2: (\n      <Box\n        justifySelf={'stretch'}\n        display={'flex'}\n        flexDirection={'column'}\n        minWidth={'var(--modal-min-width)'}\n        justifyContent={'center'}\n        marginTop={2}\n        paddingX={isMobile ? 1 : 0}\n      >\n        <Typography\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n          component={'span'}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {props.t('labelDefiStakingRedeem')}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {info.amount + ' ' + info.symbol}\n          </Typography>\n        </Typography>\n        <Typography\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n          component={'span'}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {props.t('labelStakingRedeemRemaining')}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {info.remainAmount && info.remainAmount != '0'\n              ? info.remainAmount + ' ' + info.symbol\n              : EmptyValueTag}\n          </Typography>\n        </Typography>\n\n        <Typography\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n          component={'span'}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {props.t('labelDeFiSideProduct')}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {info?.productId ?? EmptyValueTag}\n          </Typography>\n        </Typography>\n        <Typography\n          component={'span'}\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {props.t('labelStakingRedeemDate')}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {moment(new Date())\n              // .utc()\n              // .startOf(\"days\")\n              .format(YEAR_DAY_MINUTE_FORMAT)}\n          </Typography>\n        </Typography>\n      </Box>\n    ),\n  }\n  return <DualBase showTitle={false} {...propsPatch} {...props} />\n}\n\nexport const Staking_Redeem_Failed = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.FailedIcon,\n    describe1: props.t('labelStakingFailed', {\n      symbol: props.info?.symbol,\n    }),\n  }\n  return <DualBase showTitle={true} {...propsPatch} {...props} />\n}\n\nexport const BtradeDetail = (props: any) => {\n  const { isMobile } = useSettings()\n  const { info } = props\n  const { t } = props\n  return info?.buyToken && info?.sellToken ? (\n    <Box\n      justifySelf={'stretch'}\n      display={'flex'}\n      flexDirection={'column'}\n      minWidth={'var(--modal-min-width)'}\n      justifyContent={'center'}\n      marginTop={0}\n      paddingX={isMobile ? 1 : 5}\n      alignSelf={'stretch'}\n    >\n      <Box display={'flex'} flexDirection={'column'} marginTop={2}>\n        <Typography\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n          component={'span'}\n        >\n          <Typography\n            display={'flex'}\n            variant={'body1'}\n            component={'span'}\n            color={'var(--color-text-secondary)'}\n          >\n            {t(\"labelBtradePlacedAmount\")}\n            <Tooltip title={<>{t(\"labelBtradePlacedAmountTip\")}</>}>\n              <Typography marginLeft={0.5} display={'flex'} alignItems={'center'}>\n                <Info2Icon fontSize={'medium'} htmlColor={'var(--color-text-third)'} />\n              </Typography>\n            </Tooltip>\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {info?.placedAmount}\n          </Typography>\n        </Typography>\n        <Typography\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n          component={'span'}\n        >\n          <Typography\n            display={'flex'}\n            variant={'body1'}\n            component={'span'}\n            color={'var(--color-text-secondary)'}\n          >\n            {t(\"labelBtradeExecutedAmount\")}\n            <Tooltip title={<>{t(\"labelBtradeExecutedAmountTip\")}</>}>\n              <Typography marginLeft={0.5} display={'flex'} alignItems={'center'}>\n                <Info2Icon fontSize={'medium'} htmlColor={'var(--color-text-third)'} />\n              </Typography>\n            </Tooltip>\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {info?.executedAmount}\n          </Typography>\n        </Typography>\n        <Typography\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n          component={'span'}\n        >\n          <Typography\n            display={'flex'}\n            variant={'body1'}\n            component={'span'}\n            color={'var(--color-text-secondary)'}\n          >\n            {t(\"labelBtradeExecutedRate\")}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {info?.executedRate}\n          </Typography>\n        </Typography>\n        <Typography\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n          component={'span'}\n        >\n          <Typography\n            display={'flex'}\n            variant={'body1'}\n            component={'span'}\n            color={'var(--color-text-secondary)'}\n          >\n            {t(\"labelBtradeConvertedAmount\")}\n            <Tooltip title={<>{t(\"labelBtradeConvertedAmountTip\")}</>}>\n              <Typography marginLeft={0.5} display={'flex'} alignItems={'center'}>\n                <Info2Icon fontSize={'medium'} htmlColor={'var(--color-text-third)'} />\n              </Typography>\n            </Tooltip>\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {info?.convertedAmount}\n          </Typography>\n        </Typography>\n        <Typography\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n          component={'span'}\n        >\n          <Typography\n            display={'flex'}\n            variant={'body1'}\n            component={'span'}\n            color={'var(--color-text-secondary)'}\n          >\n            {t(\"labelBtradeSettledAmount\")}\n            <Tooltip title={<>{t(\"labelBtradeSettledAmountTip\")}</>}>\n              <Typography marginLeft={0.5} display={'flex'} alignItems={'center'}>\n                <Info2Icon fontSize={'medium'} htmlColor={'var(--color-text-third)'} />\n              </Typography>\n            </Tooltip>\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {info?.settledAmount}\n          </Typography>\n        </Typography>\n        <Typography\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n          component={'span'}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {props.t('labelPrice')}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {info?.convertStr}\n          </Typography>\n        </Typography>\n        <Typography\n          component={'span'}\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {props.t('labelFee')}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {info?.feeStr ? info?.feeStr + ' ' + info.buyToken.symbol : EmptyValueTag}\n          </Typography>\n        </Typography>\n        {info?.time && (\n          <Typography\n            component={'span'}\n            display={'inline-flex'}\n            justifyContent={'space-between'}\n            marginTop={2}\n          >\n            <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n              {props.t('labelBtradeTime')}\n            </Typography>\n            <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n              {moment(new Date(info.time)).format(YEAR_DAY_MINUTE_FORMAT)}\n            </Typography>\n          </Typography>\n        )}\n      </Box>\n    </Box>\n  ) : (\n    <></>\n  )\n}\n\nexport const BtradeSwap_Delivering = (props: PanelProps) => {\n  const { t } = props\n  const { isMobile } = useSettings()\n\n  const propsPatch = {\n    iconType: IconType.SubmitIcon,\n    describe1: (\n      <Box\n        paddingX={isMobile ? 1 : 5}\n        display={'flex'}\n        flexDirection={'column'}\n        alignItems={'center'}\n      >\n        <Typography color={'var(--color-text-primary)'} variant={'h5'} component={'span'}>\n          {t('labelBtradeSwapDelivering')}\n        </Typography>\n        <Typography\n          color={'var(--color-text-secondary)'}\n          marginTop={2}\n          component={'span'}\n          whiteSpace={'pre-line'}\n          sx={{ wordBreak: 'break-word' }}\n        >\n          {t('labelBtradeSwapDeliverDes')}\n        </Typography>\n      </Box>\n    ),\n    describe2: <BtradeDetail {...props} />,\n  }\n  return <BtradeBase {...propsPatch} {...props} />\n}\nexport const BtradeSwap_Pending = (props: PanelProps) => {\n  const { t } = props\n  const propsPatch = {\n    iconType: IconType.PendingIcon,\n    describe1: (\n      <Typography color={'var(--color-text-primary)'} variant={'h5'} component={'span'}>\n        {t('labelBtradeSwapPending')}\n      </Typography>\n    ),\n    describe2: <BtradeDetail {...props} />,\n  }\n  return <BtradeBase {...propsPatch} {...props} />\n}\n\nexport const BtradeSwap_Settled = (props: PanelProps) => {\n  const { t } = props\n  const propsPatch = {\n    iconType: IconType.DoneIcon,\n    describe1: (\n      <Typography color={'var(--color-text-primary)'} variant={'h5'} component={'span'}>\n        {t('labelBtradeSwapSettled')}\n      </Typography>\n    ),\n    describe2: <BtradeDetail {...props} />,\n  }\n  return <BtradeBase {...propsPatch} {...props} />\n}\n\nexport const BtradeSwap_Failed = (props: PanelProps) => {\n  const { t } = props\n  const propsPatch = {\n    iconType: IconType.FailedIcon,\n    describe1: (\n      <Typography color={'var(--color-text-primary)'} variant={'h5'} component={'span'}>\n        {t('labelBtradeSwapFailed')}\n      </Typography>\n    ),\n    describe2: <BtradeDetail {...props} />,\n  }\n  return <BtradeBase {...propsPatch} {...props} />\n}\n\nexport const AMM_Pending = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.PendingIcon,\n    // describe1: (\n    //   <Typography\n    //     color={\"var(--color-text-primary)\"}\n    //     variant={\"h5\"}\n    //     component={\"span\"}\n    //   >\n    //     {t(\"labelAMMPending\")}\n    //   </Typography>\n    // ),\n  }\n  return <AmmBase {...{ ...props, ...propsPatch }} />\n}\n\nexport const Taiko_Farming_Lock_Success = (props: PanelProps) => {\n  const { isMobile } = useSettings()\n  const { info } = props\n  const propsPatch = {\n    iconType: IconType.DoneIcon,\n    title: props.t('labelTaikoFarming'),\n    describe1: (\n      <Typography variant={'h5'} color={'var(--color-primary)'} component={'span'}>\n        {props.t('labelTaikoFarmingLockSuccess')}\n      </Typography>\n    ),\n    describe2: (\n      <Box\n        justifySelf={'stretch'}\n        display={'flex'}\n        flexDirection={'column'}\n        minWidth={'var(--modal-min-width)'}\n        justifyContent={'center'}\n        marginTop={2}\n        paddingX={isMobile ? 1 : 0}\n      >\n        <Typography\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n          component={'span'}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {props.t('labelDeFiSideAmount')}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {info?.amount + ' ' + info?.symbol}\n          </Typography>\n        </Typography>\n        <Typography\n          component={'span'}\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {props.t('labelDeFiSideSubscribeTime')}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {info?.stakeAt && moment(new Date(info.stakeAt))\n              // .utc()\n              // .startOf(\"days\")\n              .format(YEAR_DAY_MINUTE_FORMAT)}\n          </Typography>\n        </Typography>\n      </Box>\n    ),\n  }\n  return <TaikoFarmingStakeBase showTitle={false} {...propsPatch} {...props} />\n}\nexport const Taiko_Farming_Lock_Failed = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.FailedIcon,\n    describe1: props.t('labelStakingFailed', {\n      symbol: props.info?.symbol,\n    }),\n  }\n  return <TaikoFarmingStakeBase showTitle={true} {...propsPatch} {...props} />\n}\n\nexport const Taiko_Farming_Redeem_Success = (props: PanelProps) => {\n  const { isMobile } = useSettings()\n  const { info } = props\n  const propsPatch = {\n    iconType: IconType.DoneIcon,\n    describe2: (\n      <Box\n        justifySelf={'stretch'}\n        display={'flex'}\n        flexDirection={'column'}\n        minWidth={'var(--modal-min-width)'}\n        justifyContent={'center'}\n        marginTop={2}\n        paddingX={isMobile ? 1 : 0}\n      >\n        <Typography\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n          component={'span'}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            TAIKO Amount \n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {info?.amount}\n          </Typography>\n        </Typography>\n        <Typography\n          component={'span'}\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            Time\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {moment(info?.redeemAt).format(YEAR_DAY_MINUTE_FORMAT)}\n          </Typography>\n        </Typography>\n      </Box>\n    ),\n  }\n  return <TaikoFarmingRedeemBase showTitle={false} {...propsPatch} {...props} />\n}\n\nexport const Taiko_Farming_Redeem_In_Progress = (props: PanelProps) => {\n  const { isMobile } = useSettings()\n  const { info } = props\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe2: (\n      <Box\n        justifySelf={'stretch'}\n        display={'flex'}\n        flexDirection={'column'}\n        minWidth={'var(--modal-min-width)'}\n        justifyContent={'center'}\n        marginTop={2}\n        paddingX={isMobile ? 1 : 3}\n        width={'80%'}\n      >\n        <Typography\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n          component={'span'}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            TAIKO Amount\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {info?.amount}\n          </Typography>\n        </Typography>\n        {/* <Typography\n          component={'span'}\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {props.t(\"labelTime\")}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {info?.mintAt && moment(new Date(info.mintAt)).format(YEAR_DAY_MINUTE_FORMAT)}\n          </Typography>\n        </Typography> */}\n\n      </Box>\n    ),\n  }\n  return <TaikoFarmingRedeemBase showTitle={true} {...propsPatch} {...props} />\n}\n\nexport const Taiko_Farming_Redeem_Failed = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.FailedIcon,\n    describe1: 'Redeem TAIKO Failed',\n  }\n  return <TaikoFarmingRedeemBase showTitle={true} {...propsPatch} {...props} />\n}\n\nexport const Taiko_Farming_Mint_Success = (props: PanelProps) => {\n  const { isMobile } = useSettings()\n  const { info } = props\n  const propsPatch = {\n    iconType: IconType.DoneIcon,\n    title: props.t('Mint lrTAIKO'),\n    describe1: (\n      <Typography variant={'h5'} color={'var(--color-text-primary)'} component={'span'}>\n        {props.t('labelTaikoFarmingMintSuccess')}\n      </Typography>\n    ),\n    describe2: (\n      <Box\n        justifySelf={'stretch'}\n        display={'flex'}\n        flexDirection={'column'}\n        minWidth={'var(--modal-min-width)'}\n        justifyContent={'center'}\n        marginTop={2}\n        paddingX={isMobile ? 1 : 3}\n        width={'80%'}\n      >\n        <Typography\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n          component={'span'}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {props.t(\"labelAmount\")}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {info?.amount + ' ' + info?.symbol}\n          </Typography>\n        </Typography>\n        <Typography\n          component={'span'}\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {props.t(\"labelTime\")}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {info?.mintAt && moment(new Date(info.mintAt)).format(YEAR_DAY_MINUTE_FORMAT)}\n          </Typography>\n        </Typography>\n\n        <Typography mt={3}>\n          {props.t('labelTaikoFarmingMintInfoDes')}\n        </Typography>\n        <Typography\n          component={'p'}\n          onClick={() => window.open('/#/portal/portalHome', '_blank')}\n          sx={{ cursor: 'pointer' }}\n          color={'var(--color-primary)'}\n          mt={1}\n        >{props.t('labelTaikoFarmingMintVisitPortal')}</Typography>\n      </Box>\n    ),\n  }\n  return <TaikoFarmingMintBase showTitle={false} {...propsPatch} {...props} />\n}\n\nexport const Taiko_Farming_Mint_Failed = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.FailedIcon,\n    describe1: props.t('Mint Failed'),\n  }\n  return <TaikoFarmingMintBase showTitle={true} {...propsPatch} {...props} />\n}\n\nexport const Taiko_Farming_Mint_In_Progress = (props: PanelProps) => {\n  const { isMobile } = useSettings()\n  const { info } = props\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelVaultRepayInProgress', {\n      symbol: props.symbol,\n      value: props.value,\n    }),\n    describe2: (\n      <Box\n        justifySelf={'stretch'}\n        display={'flex'}\n        flexDirection={'column'}\n        minWidth={'var(--modal-min-width)'}\n        justifyContent={'center'}\n        marginTop={2}\n        paddingX={isMobile ? 1 : 3}\n        width={'80%'}\n      >\n        <Typography\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n          component={'span'}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {props.t(\"labelAmount\")}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {info?.amount + ' ' + info?.symbol}\n          </Typography>\n        </Typography>\n        <Typography\n          component={'span'}\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {props.t(\"labelTime\")}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {info?.mintAt && moment(new Date(info.mintAt)).format(YEAR_DAY_MINUTE_FORMAT)}\n          </Typography>\n        </Typography>\n\n      </Box>\n    ),\n  }\n  return <TaikoFarmingMintBase showTitle={true} {...propsPatch} {...props} />\n}"
  },
  {
    "path": "packages/component-lib/src/components/modal/ModalPanels/EditContact.tsx",
    "content": "import React from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { useSettings } from '../../../stores'\nimport {\n  AddressError,\n  AlertIcon,\n  CloseIcon,\n  hexToRGB,\n  L1L2_NAME_DEFINED,\n  LoadingIcon,\n  MapChainId,\n  TradeBtnStatus,\n} from '@loopring-web/common-resources'\nimport { Box, Divider, IconButton, InputAdornment, Typography } from '@mui/material'\nimport { Button, ModalBackButton, TextField } from '../../basic-lib'\nimport { FullAddressType } from '../../tradePanel'\nimport styled from '@emotion/styled'\nimport { useTheme } from '@emotion/react'\nconst BoxStyle = styled(Box)`\n  & {\n    height: inherit;\n    .content-main {\n      overflow: scroll;\n      align-self: stretch;\n      & > div {\n        align-self: stretch;\n      }\n    }\n  }\n`\n\nexport const EditContact = ({\n  selectedAddressType,\n  detectedWalletType,\n  addressDefault,\n  isAddressCheckLoading,\n  addName,\n  onChangeName,\n  realAddr,\n  isContactExit,\n  isEdit,\n  handleOnAddressChange,\n  allowToClickIsSure,\n  onChangeAddressType,\n  btnStatus,\n  addrStatus,\n  submitContact,\n  isENSWrong,\n  btnLabel,\n  onBack,\n}) => {\n  const { t } = useTranslation(['common'])\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const label = React.useMemo(() => {\n    if (btnLabel) {\n      const key = btnLabel.split('|')\n      return t(\n        key[0],\n        key && key[1]\n          ? {\n              arg: key[1].toString(),\n              l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n              l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n              l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n              ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n            }\n          : {\n              l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n              l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n              l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n              ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n            },\n      )\n    } else {\n      return t(isEdit ? `labelContactsEditContactBtn` : `labelContactsAddContactBtn`, {\n        l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n        loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n        l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n        l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n        ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n      })\n    }\n  }, [btnLabel, isEdit])\n  const getDisabled = React.useMemo(() => {\n    return btnStatus === TradeBtnStatus.DISABLED\n  }, [btnStatus])\n  const theme = useTheme()\n\n  const isInvalidAddressOrENS =\n    !isAddressCheckLoading && addressDefault && addrStatus === AddressError.InvalidAddr\n  return (\n    <>\n      <Box\n        display={'flex'}\n        flexDirection={'column'}\n        alignItems={'flex-start'}\n        alignSelf={'stretch'}\n        marginTop={-4}\n        maxWidth={'var(--modal-width)'}\n        width={'var(--modal-width)'}\n        //   height={}\n        //   : `calc(var(--modal-width) - ${(theme.unit * 5) / 2}px)`,\n        // _height: `calc(var(--modal-height) + ${theme.unit * 16}px)`,\n        justifyContent={'stretch'}\n      >\n        <Box\n          display={'inline-flex'}\n          flexDirection={'row'}\n          component={'header'}\n          alignItems={'center'}\n          height={'var(--toolbar-row-height)'}\n          paddingX={3}\n        >\n          {onBack ? (\n            <ModalBackButton\n              sx={{ alignSelf: 'center' }}\n              marginTop={0}\n              marginLeft={-2}\n              onBack={onBack}\n              t={t}\n            />\n          ) : (\n            <></>\n          )}\n          <Typography component={'span'} display={'inline-flex'} color={'textPrimary'}>\n            {isEdit ? t('labelContactsEditContact') : t('labelContactsAddContact')}\n          </Typography>\n        </Box>\n        <Divider style={{ marginTop: '-1px', width: '100%' }} />\n      </Box>\n      <BoxStyle\n        flex={1}\n        maxWidth={'var(--modal-width)'}\n        width={'var(--modal-width)'}\n        display={'flex'}\n        alignItems={'center'}\n        flexDirection={'column'}\n        paddingBottom={4}\n        paddingX={3}\n      >\n        {isEdit && isENSWrong && (\n          <Typography\n            marginTop={2}\n            variant={'body1'}\n            component={'span'}\n            padding={1}\n            display={'inline-flex'}\n            bgcolor={hexToRGB(theme.colorBase.warning, 0.2)}\n            borderRadius={2}\n            color={'var(--color-text-button)'}\n          >\n            <AlertIcon color={'warning'} sx={{ marginRight: 1 / 2 }} />\n            {t('labelContactENSAlert')}\n          </Typography>\n        )}\n        <Box\n          flex={1}\n          display={'flex'}\n          flexDirection={'column'}\n          alignItems={'center'}\n          justifyContent={'space-between'}\n          className={'content-main'}\n        >\n          <Box marginTop={4}>\n            <Typography marginBottom={0.5} color={'var(--color-text-third)'}>\n              {t('labelContactsAddressTitle')}\n            </Typography>\n            <>\n              <TextField\n                size={'large'}\n                className={'text-address'}\n                value={addressDefault}\n                disabled={!!isEdit}\n                error={!!isInvalidAddressOrENS}\n                placeholder={t('labelPleaseInputWalletAddress')}\n                onChange={(event) => handleOnAddressChange(event?.target?.value)}\n                fullWidth={true}\n                InputProps={{\n                  style: {\n                    paddingRight: '0',\n                  },\n                  endAdornment: (\n                    <InputAdornment\n                      style={{\n                        cursor: 'pointer',\n                        paddingRight: '.5em',\n                      }}\n                      position='end'\n                    >\n                      {addressDefault !== '' ? (\n                        isAddressCheckLoading ? (\n                          <LoadingIcon width={24} />\n                        ) : (\n                          !isEdit && (\n                            <IconButton\n                              color={'inherit'}\n                              aria-label='Clear'\n                              onClick={() => handleOnAddressChange('')}\n                            >\n                              <CloseIcon />\n                            </IconButton>\n                          )\n                        )\n                      ) : (\n                        ''\n                      )}\n                    </InputAdornment>\n                  ),\n                }}\n              />\n            </>\n            <Box marginLeft={1 / 2}>\n              {isInvalidAddressOrENS ? (\n                <Typography\n                  color={'var(--color-error)'}\n                  variant={'body2'}\n                  marginTop={1 / 4}\n                  alignSelf={'stretch'}\n                  position={'relative'}\n                >\n                  {t('labelInvalidAddress')}\n                </Typography>\n              ) : isContactExit ? (\n                <Typography\n                  color={'var(--color-error)'}\n                  variant={'body2'}\n                  marginTop={1 / 4}\n                  alignSelf={'stretch'}\n                  position={'relative'}\n                >\n                  {t('labelContactsContactExisted')}\n                </Typography>\n              ) : (\n                addressDefault &&\n                realAddr &&\n                !isAddressCheckLoading && (\n                  <Typography\n                    color={'var(--color-text-primary)'}\n                    variant={'body2'}\n                    marginTop={1 / 4}\n                    whiteSpace={'pre-line'}\n                    style={{ wordBreak: 'break-all' }}\n                  >\n                    {realAddr.toLowerCase() === addressDefault.toLowerCase() ? '' : realAddr}\n                  </Typography>\n                )\n              )}\n            </Box>\n          </Box>\n          <Box marginTop={3}>\n            <Typography marginBottom={0.5} color={'var(--color-text-third)'}>\n              {t('labelContactsNameTitle')}\n            </Typography>\n            <TextField\n              size={'large'}\n              className={'text-address'}\n              value={addName}\n              placeholder={t('labelContactsNameDes')}\n              onChange={(e) => {\n                onChangeName(e.target.value)\n              }}\n              fullWidth={true}\n              InputProps={{\n                style: {\n                  paddingRight: '0',\n                },\n                endAdornment: (\n                  <InputAdornment\n                    style={{\n                      cursor: 'pointer',\n                      paddingRight: '.5em',\n                      visibility: addName ? 'visible' : 'hidden',\n                    }}\n                    position='end'\n                  >\n                    <IconButton\n                      color={'inherit'}\n                      aria-label='Clear'\n                      onClick={() => onChangeName('')}\n                    >\n                      <CloseIcon cursor={'pointer'} />\n                    </IconButton>\n                  </InputAdornment>\n                ),\n              }}\n            />\n          </Box>\n\n          <Box marginTop={3}>\n            <FullAddressType\n              detectedWalletType={detectedWalletType}\n              selectedValue={selectedAddressType}\n              handleSelected={onChangeAddressType}\n              disabled={allowToClickIsSure}\n            />\n          </Box>\n        </Box>\n        <Box\n          width={'100%'}\n          display={'flex'}\n          flexDirection={'column'}\n          alignItems={'center'}\n          justifyContent={'flex-end'}\n          marginTop={3}\n        >\n          <Button\n            fullWidth\n            variant={'contained'}\n            size={'medium'}\n            color={'primary'}\n            onClick={() => {\n              submitContact()\n            }}\n            loading={btnStatus === TradeBtnStatus.LOADING && !getDisabled ? 'true' : 'false'}\n            disabled={getDisabled || btnStatus === TradeBtnStatus.LOADING}\n          >\n            {label}\n          </Button>\n        </Box>\n      </BoxStyle>\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/ModalPanels/ExportAccount.tsx",
    "content": "import { ExportAccountBase, IconType, PanelProps } from './BasicPanel'\n\n// symbol\nexport const ExportAccount_Approve_WaitForAuth = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelWaitForAuth'),\n  }\n  return <ExportAccountBase {...props} {...propsPatch} />\n}\n\nexport const ExportAccount_User_Denied = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.RefuseIcon,\n    describe1: props.t('labelSignDenied'),\n  }\n  return <ExportAccountBase {...propsPatch} {...props} />\n}\n\n// symbol\nexport const ExportAccount_Success = (props: PanelProps) => {\n  const describe1 = props.t('labelExportAccountSuccess')\n  const propsPatch = {\n    iconType: IconType.DoneIcon,\n    describe1,\n  }\n  return <ExportAccountBase {...propsPatch} {...props} />\n}\n\n// value symbol\nexport const ExportAccount_Failed = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.FailedIcon,\n    describe1: props.t('labelExportAccountFailed'),\n  }\n  return <ExportAccountBase {...propsPatch} {...props} />\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/ModalPanels/FeeSelect.tsx",
    "content": "import { Box, BoxProps, Divider, Typography } from '@mui/material'\nimport styled from '@emotion/styled'\nimport { useTranslation } from 'react-i18next'\nimport {\n  BackIcon,\n  EmptyValueTag,\n  LoadingIcon,\n  RoundCheckIcon,\n  RoundCircleIcon,\n  myLog,\n} from '@loopring-web/common-resources'\nimport { FeeSelectProps, Modal, FeeSelectModalProps } from '../../../components/tradePanel'\nimport { CoinIcon } from '../../../components/basic-lib'\nimport { OffchainFeeReqType, toBig } from '@loopring-web/loopring-sdk'\n\nconst OptionStyled = styled(Box)<{ checked?: boolean; disabled?: boolean }>`\n  border: 1px solid;\n  border-color: ${({ checked }) => (checked ? 'var(--color-primary)' : 'var(--color-border)')};\n  width: 100%;\n  display: flex;\n  justify-content: space-between;\n  border-radius: ${({ theme }) => theme.unit}px;\n  padding: ${({ theme }) => theme.unit * 1.5}px ${({ theme }) => theme.unit * 2}px;\n  min-height: ${({ theme }) => theme.unit * 8}px;\n  align-items: center;\n  cursor: pointer;\n  opacity: ${({ disabled }) => (disabled ? '0.5' : '1')};\n`\n\ntype OptionType = { checked?: boolean; disabled?: boolean } & BoxProps\n\nconst Option = (props: OptionType) => {\n  const { checked, disabled, children, ...otherProps } = props\n  return (\n    <OptionStyled disabled={disabled} checked={checked} {...otherProps}>\n      {children}\n      {checked ? (\n        <RoundCheckIcon fontSize={'large'} fill={'var(--color-primary)'} />\n      ) : (\n        <RoundCircleIcon fontSize={'large'} />\n      )}\n    </OptionStyled>\n  )\n}\nconst FeeTypeStyled = styled(Box)<{ checked?: boolean }>`\n  border: 1px solid;\n  border-color: ${({ checked }) => (checked ? 'var(--color-primary)' : 'var(--color-border)')};\n  display: flex;\n  justify-content: space-between;\n  border-radius: ${({ theme }) => theme.unit}px;\n  padding: ${({ theme }) => theme.unit * 0.5}px ${({ theme }) => theme.unit * 1.5}px;\n  align-items: center;\n  cursor: pointer;\n  margin-right: ${({ theme }) => 2 * theme.unit}px;\n`\n\nconst BackIconStyled = styled(BackIcon)`\n  transform: rotate(180deg);\n`\n\n\n\nexport const FeeSelectModal = (props: FeeSelectModalProps) => {\n  const { t } = useTranslation()\n  const {\n    open,\n    onClose,\n    chargeFeeTokenList,\n    feeInfo: selectedFeeInfo,\n    handleToggleChange,\n    disableNoToken,\n    withdrawInfos,\n  } = props\n  return (\n    <Modal\n      open={open}\n      onClose={() => {\n        onClose()\n      }}\n      content={\n        <Box marginTop={'-40px'} width={'var(--modal-width)'}>\n          <Typography\n            component={'header'}\n            height={'var(--toolbar-row-height)'}\n            display={'flex'}\n            paddingX={3}\n            justifyContent={'flex-start'}\n            flexDirection={'row'}\n            alignItems={'center'}\n          >\n            <Typography\n              variant={'h4'}\n              component={'span'}\n              display={'inline-flex'}\n              color={'textPrimary'}\n            >\n              {t('labelFee')}\n            </Typography>\n          </Typography>\n          <Divider />\n          <Box width={'100%'} marginY={3} paddingX={3}>\n            {withdrawInfos && (\n              <Box marginBottom={3} display={'flex'}>\n                {Object.keys(withdrawInfos.types).map((key) => {\n                  const type = Number(key)\n                  return (\n                    <FeeTypeStyled\n                      onClick={() => {\n                        withdrawInfos.onChangeType(Number(key))\n                      }}\n                      checked={withdrawInfos.type === type}\n                      key={key}\n                    >\n                      <Typography>{t('withdrawTypeLabel' + withdrawInfos.types[key])}</Typography>\n                    </FeeTypeStyled>\n                  )\n                })}\n              </Box>\n            )}\n            {chargeFeeTokenList?.map((feeInfo, index) => {\n              const inefficient =\n                !feeInfo.count ||\n                toBig(feeInfo.count).isZero() ||\n                toBig(feeInfo.count).lt(feeInfo.fee ?? '0')\n              const disabled = (disableNoToken && !feeInfo.hasToken) || inefficient\n              myLog('inefficient', feeInfo.belong, inefficient)\n              return (\n                <Option\n                  disabled={disabled}\n                  marginBottom={2}\n                  checked={selectedFeeInfo?.belong == feeInfo.belong}\n                  onClick={() => {\n                    if (!disabled) {\n                      handleToggleChange(feeInfo)\n                    }\n                  }}\n                >\n                  <Box display={'flex'}>\n                    <CoinIcon size={32} symbol={feeInfo.belong} />\n                    <Box marginLeft={1}>\n                      <Typography>\n                        {feeInfo.belong}{' '}\n                        {feeInfo.discount && feeInfo.discount !== 1 && (\n                          <Typography\n                            marginLeft={0.5}\n                            component={'span'}\n                            borderRadius={0.5}\n                            paddingX={0.5}\n                            bgcolor={'var(--color-warning)'}\n                          >\n                            {Math.round((1 - feeInfo.discount) * 100)}% OFF\n                          </Typography>\n                        )}\n                      </Typography>\n                      <Typography variant={'body2'} color={'var(--color-text-secondary)'}>\n                        {t('labelFeeAvailablePay', {\n                          available: feeInfo.count ? feeInfo.count : '0.00',\n                          pay: feeInfo.fee,\n                        })}\n                      </Typography>\n                    </Box>\n                  </Box>\n                </Option>\n              )\n            })}\n          </Box>\n        </Box>\n      }\n    />\n  )\n}\n\nexport const FeeSelect = (props: FeeSelectProps) => {\n  const {\n    open,\n    chargeFeeTokenList,\n    disableNoToken,\n    feeInfo: selectedFeeInfo,\n    handleToggleChange,\n    onClose,\n    withdrawInfos,\n    onClickFee,\n    isFeeNotEnough,\n    feeLoading,\n    isFastWithdrawAmountLimit,\n    floatLeft,\n    middleContent,\n    feeNotEnoughContent,\n    networkFeeElement\n  } = props\n\n  const { t } = useTranslation()\n  const defaultNetworkFeeElement = <Typography\n  marginRight={floatLeft ? 1 : 0}\n  component={'span'}\n  color={'inherit'}\n  minWidth={28}\n>\n  {t('labelL2toL2Fee')}:\n</Typography>\n  return (\n    <>\n      <Typography\n        component={'span'}\n        display={'flex'}\n        flexWrap={'wrap'}\n        alignItems={'center'}\n        variant={'body1'}\n        color={'var(--color-text-secondary)'}\n        marginBottom={1}\n        justifyContent={floatLeft ? 'left' : 'space-between'}\n      >\n        {networkFeeElement ? networkFeeElement : defaultNetworkFeeElement}\n        <Box\n          component={'span'}\n          display={'flex'}\n          alignItems={'center'}\n          style={{ cursor: 'pointer' }}\n          onClick={() => onClickFee()}\n        >\n          <Typography marginRight={0.5} color={'var(--color-text-second)'}>\n            {withdrawInfos &&\n              withdrawInfos.types &&\n              (withdrawInfos.type === OffchainFeeReqType.OFFCHAIN_WITHDRAWAL\n                ? t('labelL2toL1Standard')\n                : withdrawInfos.type === OffchainFeeReqType.FAST_OFFCHAIN_WITHDRAWAL\n                ? t('labelL2toL1Fast')\n                : '')}\n          </Typography>\n          {feeLoading ? (\n            <LoadingIcon fontSize={'medium'} htmlColor={'var(--color-text-primary)'}></LoadingIcon>\n          ) : isFastWithdrawAmountLimit ? (\n            <Typography marginLeft={1} component={'span'} color={'var(--color-error)'}>\n              {t('labelL2toL2FeeFastNotAllowEnough')}\n            </Typography>\n          ) : selectedFeeInfo && selectedFeeInfo.belong && selectedFeeInfo.fee ? (\n            selectedFeeInfo.fee + ' ' + selectedFeeInfo.belong\n          ) : (\n            EmptyValueTag + ' ' + selectedFeeInfo?.belong ?? EmptyValueTag\n          )}\n          <BackIconStyled fontSize={'medium'} />\n        </Box>\n      </Typography>\n      <Typography\n        sx={{\n          opacity: !feeLoading && isFeeNotEnough ? 1 : 0,\n          mt: 0.5,\n          pr: 0.5\n        }}\n        color={'var(--color-error)'}\n        textAlign={'right'}\n      >\n        insufficient balance\n      </Typography>\n      {middleContent}\n      <FeeSelectModal\n        open={open}\n        onClose={onClose}\n        chargeFeeTokenList={chargeFeeTokenList}\n        feeInfo={selectedFeeInfo}\n        handleToggleChange={handleToggleChange}\n        disableNoToken={disableNoToken}\n        withdrawInfos={withdrawInfos}\n      />\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/ModalPanels/ForceWithdraw.tsx",
    "content": "import { ForceWithdrawBase, IconType, PanelProps } from './BasicPanel'\nimport { L1L2_NAME_DEFINED, MapChainId, NFTWholeINFO } from '@loopring-web/common-resources'\nimport { useSettings } from '../../../stores'\n\nexport const ForceWithdraw_WaitForAuth = (props: PanelProps & Partial<NFTWholeINFO>) => {\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelForceWithdrawWaitForAuth', {\n      symbol: props.symbol,\n      value: props.value,\n    }),\n  }\n  return <ForceWithdrawBase {...propsPatch} {...props} />\n}\n\nexport const ForceWithdraw_Denied = (props: PanelProps & Partial<NFTWholeINFO>) => {\n  const propsPatch = {\n    iconType: IconType.RefuseIcon,\n    describe1: props.t('labelForceWithdrawDenied', {\n      symbol: props.symbol,\n      value: props.value,\n    }),\n  }\n  return <ForceWithdrawBase {...propsPatch} {...props} />\n}\n\nexport const ForceWithdraw_First_Method_Denied = (props: PanelProps & Partial<NFTWholeINFO>) => {\n  const propsPatch = {\n    iconType: IconType.RefuseIcon,\n    describe1: props.t('labelFirstSignDenied', {\n      symbol: props.symbol,\n      value: props.value,\n    }),\n  }\n  return <ForceWithdrawBase {...propsPatch} {...props} />\n}\n\nexport const ForceWithdraw_In_Progress = (props: PanelProps & Partial<NFTWholeINFO>) => {\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelForceWithdrawInProgress', {\n      symbol: props.symbol,\n      value: props.value,\n    }),\n  }\n  return <ForceWithdrawBase {...propsPatch} {...props} />\n}\n\nexport const ForceWithdraw_Failed = (props: PanelProps & Partial<NFTWholeINFO>) => {\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const propsPatch = {\n    iconType: IconType.FailedIcon,\n    describe1: props.t('labelForceWithdrawFailed', {\n      symbol: props.symbol,\n      value: props.value,\n      loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n      l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n      l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n      ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n    }),\n  }\n  return <ForceWithdrawBase {...propsPatch} {...props} />\n}\n\nexport const ForceWithdraw_Submit = (props: PanelProps & Partial<NFTWholeINFO>) => {\n  const propsPatch = {\n    iconType: IconType.SubmitIcon,\n    describe1: props.t('labelForceWithdrawSubmit', {\n      symbol: props.symbol,\n      value: props.value,\n    }),\n  }\n  return <ForceWithdrawBase {...propsPatch} {...props} />\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/ModalPanels/ForceWithdrawPanel.tsx",
    "content": "import { WithTranslation, withTranslation } from 'react-i18next'\nimport { ModalBackButton, SwitchPanel, SwitchPanelProps } from '../../basic-lib'\nimport { ForceWithdrawProps } from '../../tradePanel'\nimport { IBData, TRADE_TYPE } from '@loopring-web/common-resources'\nimport { TradeMenuList, useBasicTrade } from '../../tradePanel/components'\nimport React from 'react'\nimport { ForceWithdrawWrap } from '../../tradePanel/components/ForceWithdrawWrap'\n\nexport const ForceWithdrawPanel = withTranslation(['common', 'error'], {\n  withRef: true,\n})(\n  <T extends IBData<I>, I>({\n    type = TRADE_TYPE.TOKEN,\n    chargeFeeTokenList,\n    onWithdrawClick,\n    withdrawBtnStatus,\n    assetsData,\n    walletMap = {},\n    coinMap = {},\n    onBack,\n    ...rest\n  }: ForceWithdrawProps<T, I> & WithTranslation & { assetsData: any[] }) => {\n    const { onChangeEvent, index, switchData } = useBasicTrade({\n      ...rest,\n      coinMap,\n      type,\n      walletMap,\n    })\n    const [panelIndex, setPanelIndex] = React.useState(index + 1)\n    React.useEffect(() => {\n      setPanelIndex(index + 1)\n    }, [index])\n\n    // LP token should not exist in withdraw panel for now\n\n    const props: SwitchPanelProps<string> = {\n      index: panelIndex, // show default show\n      panelList: [\n        {\n          key: 'confirm',\n          element: React.useMemo(\n            () => (\n              // @ts-ignore\n              // <ForceWithdrawConfirm\n              //   {...{\n              //     ...rest,\n              //     onWithdrawClick,\n              //     type,\n              //     tradeData: switchData.tradeData,\n              //     handleConfirm,\n              //   }}\n              // />\n              <></>\n            ),\n            [onWithdrawClick, rest, switchData.tradeData, type],\n          ),\n          toolBarItem: (\n            <>\n              <ModalBackButton\n                marginTop={0}\n                marginLeft={-2}\n                onBack={() => {\n                  setPanelIndex(1)\n                }}\n                {...rest}\n              />\n            </>\n          ),\n        },\n        {\n          key: 'trade',\n          element: React.useMemo(\n            () => (\n              // @ts-ignore\n              <ForceWithdrawWrap\n                key={'transfer'}\n                {...{\n                  ...rest,\n                  type,\n                  // handleConfirm,\n                  chargeFeeTokenList: chargeFeeTokenList ? chargeFeeTokenList : [],\n                  tradeData: { ...switchData.tradeData, ...rest.tradeData },\n                  onChangeEvent,\n                  coinMap,\n                  disabled: !!rest.disabled,\n                  onWithdrawClick,\n                  withdrawBtnStatus,\n                  assetsData,\n                  walletMap,\n                }}\n              />\n            ),\n            [\n              rest,\n              type,\n              chargeFeeTokenList,\n              switchData.tradeData,\n              onChangeEvent,\n              coinMap,\n              onWithdrawClick,\n              withdrawBtnStatus,\n              assetsData,\n              walletMap,\n            ],\n          ),\n          toolBarItem: undefined,\n        },\n      ].concat(\n        walletMap && Object.keys(walletMap)?.length\n          ? ([\n              {\n                key: 'tradeMenuList',\n                element: (\n                  <TradeMenuList\n                    {...{\n                      nonZero: true,\n                      sorted: true,\n                      ...rest,\n                      onChangeEvent,\n                      coinMap: Object.keys(walletMap)?.reduce((prev, item) => {\n                        if (coinMap[item]) {\n                          prev[item] = coinMap[item]\n                        }\n                        return prev\n                      }, {} as any),\n                      selected: switchData.tradeData.belong,\n                      tradeData: switchData.tradeData,\n                      walletMap,\n                      //oinMap\n                    }}\n                  />\n                ),\n                toolBarItem: undefined,\n              },\n            ] as any)\n          : [],\n      ),\n    }\n    return <SwitchPanel {...{ ...rest, ...props }} />\n  },\n) as <T, I>(props: ForceWithdrawProps<T, I> & React.RefAttributes<any>) => JSX.Element\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/ModalPanels/HadAccount.tsx",
    "content": "import { AccountBaseProps } from './Interface'\nimport { AccountBasePanel } from './AccountBase'\nimport { Box } from '@mui/material'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport { DepositRecorder } from './DepositRecorder'\nimport { AccountHashInfo } from '@loopring-web/common-resources'\nimport { useTheme } from '@emotion/react'\n\nexport const HadAccount = withTranslation('common')(\n  ({\n    noButton,\n    mainBtn,\n    className,\n    onClose,\n    t,\n    ...props\n  }: WithTranslation &\n    AccountBaseProps & {\n      noButton?: boolean\n      onClose: (e?: any) => void\n      className?: string\n      clearDepositHash: () => void\n      chainInfos: AccountHashInfo\n    }) => {\n    const theme = useTheme()\n\n    return (\n      <Box\n        flex={1}\n        display={'flex'}\n        flexDirection={'column'}\n        justifyContent={'space-between'}\n        alignItems={'center'}\n        className={className}\n      >\n        <Box display={'flex'} flex={1} justifyContent={'center'} alignItems={'center'}>\n          <AccountBasePanel {...props} t={t} />\n        </Box>\n        <>\n          {noButton ? (\n            <Box\n              display={'flex'}\n              marginX={0}\n              marginTop={3}\n              marginBottom={0}\n              alignSelf={'stretch'}\n              paddingX={5}\n              padding={0}\n              sx={{\n                overflow: 'hidden',\n                borderBottomLeftRadius: theme.unit,\n                borderBottomRightRadius: theme.unit,\n              }}\n            >\n              <DepositRecorder {...props} clear={props.clearDepositHash} t={t} />\n            </Box>\n          ) : (\n            // <Box\n            //   display={\"flex\"}\n            //   marginTop={2}\n            //   alignSelf={\"stretch\"}\n            //   paddingX={5}\n            //   flexDirection={\"column\"}\n            //   alignItems={\"center\"}\n            // >\n            //   <Button\n            //     variant={\"contained\"}\n            //     fullWidth\n            //     size={\"medium\"}\n            //     onClick={onClose}\n            //   >\n            //     {t(\"labelClose\")}\n            //   </Button>\n            // </Box>\n            <>\n              <Box\n                display={'flex'}\n                marginTop={2}\n                alignSelf={'stretch'}\n                paddingX={5}\n                flexDirection={'column'}\n                alignItems={'center'}\n              >\n                {mainBtn as any}\n              </Box>\n              <Box\n                display={'flex'}\n                marginX={0}\n                marginTop={3}\n                marginBottom={0}\n                alignSelf={'stretch'}\n                paddingX={5}\n                padding={0}\n              >\n                <DepositRecorder {...props} clear={props.clearDepositHash} t={t} />\n              </Box>\n            </>\n          )}\n        </>\n      </Box>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/ModalPanels/Interface.ts",
    "content": "import { ButtonProps } from '../../basic-lib'\nimport {\n  Account,\n  AccountHashInfo,\n  CAMPAIGNTAGCONFIG,\n  Contact,\n  FeeInfo,\n  NFTWholeINFO,\n  TradeTypes,\n  VendorItem,\n  VendorProviders,\n  WalletMap,\n} from '@loopring-web/common-resources'\nimport React from 'react'\nimport {NFTBurn_User_Denied} from \"./Transfer\";\n\nexport type AccountBaseProps = {\n  level?: string\n  mainBtn?: ((props: ButtonProps) => JSX.Element) | JSX.Element\n  etherscanUrl: string\n  onDisconnect?: any\n  onSwitch?: any\n  onCopy?: any\n  onViewQRCode?: any\n  hideVIPlevel?: boolean\n} & Account\n\nexport enum AccountStep {\n  //l1 should be at top\n  NoAccount,\n  QRCode,\n  HadAccount,\n  Deposit_Sign_WaitForRefer,\n  Deposit_Approve_WaitForAuth,\n  Deposit_Approve_Denied,\n  Deposit_WaitForAuth,\n  Deposit_Denied,\n  Deposit_Failed,\n  Deposit_Submit,\n\n  //L2\n  General_Failed,\n\n  ContinuousBanxaOrder,\n  CheckingActive,\n  AddAssetGateway,\n  SendAssetGateway,\n  SendAssetFromContact,\n  SendNFTGateway,\n  PayWithCard,\n  QRCodeScanner,\n  ThirdPanelReturn,\n  // new\n  // Deposit,\n\n  NFTDeposit_Approve_WaitForAuth,\n  NFTDeposit_Approve_Denied,\n  NFTDeposit_WaitForAuth,\n  NFTDeposit_Denied,\n  NFTDeposit_Failed,\n  NFTDeposit_Submit,\n\n  NFTMint_WaitForAuth,\n  NFTMint_First_Method_Denied,\n  NFTMint_In_Progress,\n  NFTMint_Denied,\n  NFTMint_Failed,\n  NFTMint_Success,\n\n  NFTDeploy_WaitForAuth,\n  NFTDeploy_First_Method_Denied,\n  NFTDeploy_In_Progress,\n  NFTDeploy_Denied,\n  NFTDeploy_Failed,\n  NFTDeploy_Submit,\n\n  RedPacketSend_WaitForAuth,\n  RedPacketSend_First_Method_Denied,\n  RedPacketSend_In_Progress,\n  RedPacketSend_User_Denied,\n  RedPacketSend_Failed,\n  RedPacketSend_Success,\n\n  RedPacketOpen_In_Progress,\n  RedPacketOpen_Failed,\n\n  RedPacketOpen_Claim_In_Progress,\n  RedPacketSend_Claim_Success,\n  RedPacketOpen_Claim_Failed,\n\n  ForceWithdraw_WaitForAuth,\n  ForceWithdraw_First_Method_Denied,\n  ForceWithdraw_In_Progress,\n  ForceWithdraw_Denied,\n  ForceWithdraw_Failed,\n  ForceWithdraw_Submit,\n\n  ClaimWithdraw_WaitForAuth,\n  ClaimWithdraw_Denied,\n  ClaimWithdraw_First_Method_Denied,\n  ClaimWithdraw_In_Progress,\n  ClaimWithdraw_Failed,\n  ClaimWithdraw_Submit,\n\n  Transfer_WaitForAuth,\n  Transfer_First_Method_Denied,\n  Transfer_User_Denied,\n  Transfer_In_Progress,\n  Transfer_Success,\n  Transfer_Failed,\n\n  Transfer_RAMP_WaitForAuth,\n  Transfer_RAMP_First_Method_Denied,\n  Transfer_RAMP_User_Denied,\n  Transfer_RAMP_In_Progress,\n  Transfer_RAMP_Success,\n  Transfer_RAMP_Failed,\n\n  Transfer_BANXA_WaitForAuth,\n  Transfer_BANXA_First_Method_Denied,\n  Transfer_BANXA_User_Denied,\n  Transfer_BANXA_In_Progress,\n  Transfer_BANXA_Success,\n  Transfer_BANXA_Confirm,\n  Transfer_BANXA_Failed,\n\n  Withdraw_WaitForAuth,\n  Withdraw_First_Method_Denied,\n  Withdraw_User_Denied,\n  Withdraw_In_Progress,\n  Withdraw_Success,\n  Withdraw_Failed,\n\n  NFTTransfer_WaitForAuth,\n  NFTTransfer_First_Method_Denied,\n  NFTTransfer_User_Denied,\n  NFTTransfer_In_Progress,\n  NFTTransfer_Success,\n  NFTTransfer_Failed,\n\n  NFTBurn_WaitForAuth,\n  NFTBurn_First_Method_Denied,\n  NFTBurn_User_Denied,\n  NFTBurn_In_Progress,\n  NFTBurn_Success,\n  NFTBurn_Failed,\n\n  NFTWithdraw_WaitForAuth,\n  NFTWithdraw_First_Method_Denied,\n  NFTWithdraw_User_Denied,\n  NFTWithdraw_In_Progress,\n  NFTWithdraw_Success,\n  NFTWithdraw_Failed,\n\n  CreateAccount_EOA_Only_Alert,\n  CreateAccount_Approve_WaitForAuth,\n  CreateAccount_Approve_Denied,\n  CreateAccount_Approve_Submit,\n  CreateAccount_WaitForAuth,\n  CreateAccount_Denied,\n  CreateAccount_Failed,\n  CreateAccount_Submit,\n\n  UpdateAccount,\n  UpdateAccount_Approve_WaitForAuth,\n  UpdateAccount_First_Method_Denied,\n  UpdateAccount_User_Denied,\n  UpdateAccount_Success,\n  UpdateAccount_Failed,\n  UpdateAccount_SmartWallet_NotSupported_Alert,\n\n  // UnlockAccount,\n  UnlockAccount_WaitForAuth,\n  UnlockAccount_User_Denied,\n  UnlockAccount_Success,\n  UnlockAccount_Failed,\n  UnlockAccount_Reset_Key_Confirm,\n\n  ResetAccount_Approve_WaitForAuth,\n  ResetAccount_First_Method_Denied,\n  ResetAccount_User_Denied,\n  ResetAccount_Success,\n  ResetAccount_Failed,\n\n  ExportAccount_Approve_WaitForAuth,\n  ExportAccount_User_Denied,\n  ExportAccount_Success,\n  ExportAccount_Failed,\n\n  Dual_Success,\n  Dual_Failed,\n  Staking_Success,\n  Staking_Failed,\n  Staking_Redeem_Success,\n  Staking_Redeem_Failed,\n\n  BtradeSwap_Pending,\n  BtradeSwap_Delivering,\n  BtradeSwap_Settled,\n  BtradeSwap_Failed,\n\n  AMM_Pending,\n\n  VaultTrade_Success,\n  VaultTrade_Failed,\n  VaultTrade_In_Progress,\n  VaultJoin_Success,\n  VaultJoin_Failed,\n  VaultJoin_In_Progress,\n  VaultRedeem_Success,\n  VaultRedeem_Failed,\n  VaultRedeem_In_Progress,\n  VaultBorrow_Success,\n  VaultBorrow_Failed,\n  VaultBorrow_In_Progress,\n  VaultRepay_Success,\n  VaultRepay_Failed,\n  VaultRepay_In_Progress,\n  VaultDustCollector_Success,\n  VaultDustCollector_Failed,\n  VaultDustCollector_In_Progress,\n\n  Taiko_Farming_Lock_Success,\n  Taiko_Farming_Lock_Failed,\n\n  Taiko_Farming_Redeem_In_Progress,\n  Taiko_Farming_Redeem_Success,\n  Taiko_Farming_Redeem_Failed,\n\n  Taiko_Farming_Mint_Success,\n  Taiko_Farming_Mint_In_Progress,\n  Taiko_Farming_Mint_Failed,\n\n  Transfer_To_Taiko_User_Denied,\n  Transfer_To_Taiko_In_Progress,\n  Transfer_To_Taiko_Success,\n  Transfer_To_Taiko_Failed,\n\n  Coinbase_Smart_Wallet_Password_Intro,\n  Coinbase_Smart_Wallet_Password_Set,\n  Coinbase_Smart_Wallet_Password_Set_Confirm,\n  Coinbase_Smart_Wallet_Password_Set_Processing,\n  Coinbase_Smart_Wallet_Password_Set_Error,\n  Coinbase_Smart_Wallet_Password_Get_Error,\n  Coinbase_Smart_Wallet_Password_Input,\n  Coinbase_Smart_Wallet_Password_Forget_Password_Confirm,\n  Coinbase_Smart_Wallet_Password_Forget_Password,\n\n}\n\n/**\n * @param handleSelect default handleSelect, if item have no private handleSelect function\n */\nexport interface VendorMenuProps {\n  // termUrl: string;\n  type?: TradeTypes\n  banxaRef?: React.Ref<any>\n  vendorList: VendorItem[]\n  handleSelect?: (event: React.MouseEvent, key: string) => void\n  vendorForce: VendorProviders | undefined\n  campaignTagConfig?: CAMPAIGNTAGCONFIG\n  callback?: () => void\n}\n\ninterface InferfaceAssetItem {\n  key: string\n  svgIcon: string\n  enableKey?: string | null\n  handleSelect: (event?: React.MouseEvent) => void\n  type: 'sameLayer' | 'crossLayer' | 'crossChain'\n  cornerTag?: 'Loopring' | '3rd party'\n  description?: string\n}\n\nexport interface AddAssetItem extends InferfaceAssetItem {}\n\nexport interface SendAssetItem extends InferfaceAssetItem {}\n\nexport interface AddAssetProps {\n  symbol?: string\n  addAssetList: AddAssetItem[]\n  isNewAccount?: boolean\n  allowTrade: {\n    [key: string]: { enable?: boolean; reason?: string; show?: boolean }\n  }\n  disbaleList?: string[]\n}\n\nexport interface SendAssetProps {\n  isToL1?: boolean\n  symbol?: string\n  sameLayerAssetList: AddAssetItem[]\n  crossLayerAssetList: AddAssetItem[]\n  crossChainAssetList: AddAssetItem[]\n  allowTrade: {\n    [key: string]: { enable?: boolean; reason?: string; show?: boolean }\n  }\n  toL1Title: string\n}\n\nexport interface SendNFTAssetProps {\n  nftData: Partial<NFTWholeINFO>\n  sendAssetList: AddAssetItem[]\n  isNotAllowToL1?: boolean\n  allowTrade: {\n    [key: string]: { enable?: boolean; reason?: string; show?: boolean }\n  }\n}\n\nexport interface CheckActiveStatusProps<C = FeeInfo> {\n  account: Account & { isContract: boolean | undefined }\n  chargeFeeTokenList: C[]\n  goDisconnect: () => void\n  goSend: () => void\n  isDepositing: boolean\n  walletMap?: WalletMap<any, any>\n  isFeeNotEnough: {\n    isFeeNotEnough: boolean\n    isOnLoading: boolean\n  }\n  onIKnowClick: () => void\n  knowDisable: boolean\n  know: boolean\n  clearDepositHash?: () => void\n  chainInfos?: AccountHashInfo\n  accAddress?: string\n}\n\nexport interface CheckImportCollectionProps {\n  account: Account\n  value: string\n  onChange: (item: string) => void\n  contractList: string[]\n  disabled?: boolean\n  loading?: boolean\n  onClick: (item: string) => void\n}\n\nexport interface SendDialogProps {\n  // onCloseSend: () => void\n  sendInfo: {\n    open: boolean\n    selected: Contact | undefined\n  }\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/ModalPanels/MintNFT.tsx",
    "content": "import { IconType, MintBase, PanelProps } from './BasicPanel'\nimport { L1L2_NAME_DEFINED, MapChainId, NFTWholeINFO } from '@loopring-web/common-resources'\nimport { useSettings } from '../../../stores'\n\nexport const NFTMint_WaitForAuth = (props: PanelProps & Partial<NFTWholeINFO>) => {\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelNFTTokenMintWaitForAuth', {\n      symbol:\n        props.symbol && props.symbol?.length > 10\n          ? props.symbol?.slice(0, 10) + '...'\n          : props.symbol ?? '',\n      value: props.value,\n    }),\n  }\n  return <MintBase {...propsPatch} {...props} />\n}\n\nexport const NFTMint_Denied = (props: PanelProps & Partial<NFTWholeINFO>) => {\n  const propsPatch = {\n    iconType: IconType.RefuseIcon,\n    describe1: props.t('labelMintDenied', {\n      symbol: props.symbol,\n      value: props.value,\n    }),\n  }\n  return <MintBase {...propsPatch} {...props} />\n}\n\nexport const NFTMint_First_Method_Denied = (props: PanelProps & Partial<NFTWholeINFO>) => {\n  const propsPatch = {\n    iconType: IconType.RefuseIcon,\n    describe1: props.t('labelFirstSignDenied', {\n      symbol: props.symbol,\n      value: props.value,\n    }),\n  }\n  return <MintBase {...propsPatch} {...props} />\n}\nexport const NFTMint_In_Progress = (props: PanelProps & Partial<NFTWholeINFO>) => {\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelMintInProgress', {\n      symbol: props.symbol,\n      value: props.value,\n    }),\n  }\n  return <MintBase {...propsPatch} {...props} />\n}\n\nexport const NFTMint_Failed = (props: PanelProps & Partial<NFTWholeINFO>) => {\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const propsPatch = {\n    iconType: IconType.FailedIcon,\n    describe1: props.t('labelMintFailed', {\n      symbol: props.symbol ?? 'NFT',\n      value: props.value,\n      loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n      l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n      l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n      ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n    }),\n  }\n  return <MintBase {...propsPatch} {...props} />\n}\n\nexport const NFTMint_Success = (props: PanelProps & Partial<NFTWholeINFO>) => {\n  const propsPatch = {\n    iconType: IconType.DoneIcon,\n    describe1: props.t('labelMintSuccess', {\n      symbol: props.symbol ?? 'NFT',\n      value: props.value,\n    }),\n  }\n  return <MintBase {...propsPatch} {...props} />\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/ModalPanels/ModalAccount.tsx",
    "content": "import { WithTranslation, withTranslation } from 'react-i18next'\nimport { Box, Modal } from '@mui/material'\nimport {\n  ModalAccountProps,\n  ModalBackButton,\n  ModalCloseButton,\n  ModelPanelStyle,\n  QRButtonStyle,\n} from '../../../index'\n\nexport const ModalAccount = withTranslation('common', { withRef: true })(\n  ({\n    open,\n    onClose,\n    step,\n    isLayer2Only = false,\n    onBack,\n    style,\n    noClose,\n    etherscanBaseUrl,\n    onQRClick,\n    panelList,\n    isWebEarn,\n    ...rest\n  }: ModalAccountProps & WithTranslation) => {\n    // const { w, h } = style ? style : { w: undefined, h: undefined };\n\n    return (\n      <Modal\n        sx={{ zIndex: 2001 }}\n        open={open}\n        onClose={onClose}\n        aria-labelledby='modal-modal-title'\n        aria-describedby='modal-modal-description'\n      >\n        <ModelPanelStyle style={{ boxShadow: '24' }}>\n          <Box display={'flex'} width={'100%'} flexDirection={'column'}>\n            {noClose ? <></> : <ModalCloseButton onClose={onClose} {...rest} />}\n            {onBack ? <ModalBackButton onBack={onBack} {...rest} /> : <></>}\n            {onQRClick ? <QRButtonStyle onQRClick={onQRClick} {...rest} /> : <></>}\n          </Box>\n          {panelList.map((panel, index) => {\n            return (\n              <Box\n                display={step === index ? 'flex' : 'none'}\n                alignItems={'stretch'}\n                flexDirection={'column'}\n                height={panel.height ? panel.height : 'var(--modal-height)'}\n                width={panel.width ? panel.width : 'var(--modal-width)'}\n                key={index}\n              >\n                {panel.view}\n              </Box>\n            )\n          })}\n        </ModelPanelStyle>\n      </Modal>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/ModalPanels/NoAccount.tsx",
    "content": "import { AccountBasePanel } from './AccountBase'\nimport { AccountBaseProps } from './Interface'\nimport { Box, Typography } from '@mui/material'\nimport { AnimationArrow, Button, useSettings } from '../../../index'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport { AccountHashInfo, L1L2_NAME_DEFINED, MapChainId } from '@loopring-web/common-resources'\nimport { DepositRecorder } from './DepositRecorder'\nimport { useTheme } from '@emotion/react'\n\nexport const NoAccount = withTranslation('common')(\n  ({\n    goActiveAccount,\n    className,\n    noButton = false,\n    t,\n    onClose,\n    ...props\n  }: WithTranslation &\n    AccountBaseProps & {\n      noButton?: boolean\n      className?: string\n      goActiveAccount: () => void\n      onClose: (e?: any) => void\n      chainInfos: AccountHashInfo\n      clearDepositHash: () => void\n    }) => {\n    const theme = useTheme()\n    const { defaultNetwork } = useSettings()\n    const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n    return (\n      <Box\n        flex={1}\n        display={'flex'}\n        flexDirection={'column'}\n        justifyContent={'space-between'}\n        alignItems={'center'}\n        className={className}\n        // style={{ transform: \"translateY(-40px)\" }}\n      >\n        <Box\n          display={'flex'}\n          flex={1}\n          marginBottom={5}\n          justifyContent={'center'}\n          alignItems={'center'}\n        >\n          <AccountBasePanel {...props} t={t} />\n        </Box>\n        {noButton ? (\n          <Box\n            display={'flex'}\n            marginX={0}\n            marginTop={3}\n            marginBottom={0}\n            alignSelf={'stretch'}\n            paddingX={5}\n            padding={0}\n            sx={{\n              overflow: 'hidden',\n              borderBottomLeftRadius: theme.unit,\n              borderBottomRightRadius: theme.unit,\n            }}\n          >\n            <DepositRecorder {...props} clear={props.clearDepositHash} t={t} />\n          </Box>\n        ) : (\n          <>\n            <Box\n              display={'flex'}\n              marginTop={2}\n              alignSelf={'stretch'}\n              paddingX={5}\n              flexDirection={'column'}\n              alignItems={'center'}\n            >\n              <Typography variant={'body2'}>\n                {t('labelActivatedAccountDeposit', {\n                  layer2: L1L2_NAME_DEFINED[network].layer2,\n                })}\n              </Typography>\n              <AnimationArrow className={'arrowCta'} />\n              <Button\n                variant={'contained'}\n                fullWidth\n                size={'medium'}\n                onClick={() => {\n                  goActiveAccount()\n                }}\n              >\n                {t('labelActiveL2Btn', {\n                  loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                })}\n              </Button>\n            </Box>\n            <Box\n              display={'flex'}\n              marginX={0}\n              marginTop={3}\n              alignSelf={'stretch'}\n              paddingX={5}\n              padding={0}\n            >\n              <DepositRecorder {...props} clear={props.clearDepositHash} t={t} />\n            </Box>\n          </>\n        )}\n      </Box>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/ModalPanels/QRAddressPanel.tsx",
    "content": "import { Box, Link, Typography } from '@mui/material'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport {\n  Account,\n  CopyIcon,\n  copyToClipBoard,\n  L1L2_NAME_DEFINED,\n  MapChainId,\n  TOAST_TIME,\n} from '@loopring-web/common-resources'\nimport styled from '@emotion/styled'\nimport { useSettings } from '../../../stores'\nimport { Button } from '../../basic-lib'\nimport React from 'react'\nimport { Toast, ToastType } from '../../toast'\nimport { QRCode } from '../QRCode'\n\nconst BoxStyle = styled(Box)`\n  ${({ theme }) => theme.border.defaultFrame({ c_key: 'blur', d_R: 1 / 2, d_W: 0 })};\n  background: var(--provider-agree);\n` as typeof Box\nexport const QRAddressPanel = withTranslation('common')(\n  ({\n    isForL2Send,\n    accAddress,\n    isNewAccount,\n    t,\n    btnInfo,\n  }: //    etherscanUrl,\n  WithTranslation & {\n    btnInfo: {\n      btnTxt: string\n      callback: () => void\n    }\n    etherscanUrl: string\n    isForL2Send: boolean\n    isNewAccount: boolean\n  } & Account) => {\n    const { feeChargeOrder } = useSettings()\n    const [copyToastOpen, setCopyToastOpen] = React.useState(false)\n    const { defaultNetwork } = useSettings()\n    const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n    //     const etherscanLink = etherscanUrl + 'address/' + accAddress;\n    return (\n      <Box\n        flex={1}\n        paddingY={2}\n        paddingX={2}\n        marginTop={-7}\n        display={'flex'}\n        flexDirection={'column'}\n        alignItems={'center'}\n        justifyContent={'center'}\n      >\n        <Typography variant={'h4'} marginBottom={2}>\n          {t('labelReceiveAddress')}\n        </Typography>\n        {!!isForL2Send && (\n          <BoxStyle marginBottom={2}>\n            <Typography\n              variant={'body1'}\n              display={'inline-flex'}\n              alignItems={'baseline'}\n              color={'var(--color-warning)'}\n              paddingY={2}\n              paddingX={5}\n            >\n              {isNewAccount\n                ? t('labelReceiveAddressGuide', {\n                    loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                    symbol: feeChargeOrder?.join(', '),\n                  })\n                : t('labelReceiveAddressGuide', {\n                    loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n\n                    symbol: t('labelAssets', {\n                      loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                    }),\n                  })}\n            </Typography>\n          </BoxStyle>\n        )}\n        <QRCode size={240} url={accAddress} />\n        <Link\n          marginTop={3}\n          variant={'body2'}\n          color={'textSecondary'}\n          sx={{ wordBreak: 'break-all' }}\n          display={'inline-flex'}\n          alignItems={'center'}\n          onClick={(e) => {\n            e.stopPropagation()\n            copyToClipBoard(accAddress)\n            setCopyToastOpen(true)\n          }}\n        >\n          {accAddress}\n          <CopyIcon sx={{ paddingLeft: 1 }} color={'inherit'} fontSize={'large'} />\n        </Link>\n        <Typography paddingX={5} paddingTop={2} paddingBottom={1} variant={'body2'}>\n          {t(isNewAccount ? 'labelReceiveAddressDesActive' : 'labelReceiveAddressDes', {\n            loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n            loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n            l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n            l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n            ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n          })}\n        </Typography>\n        <Box alignSelf={'stretch'} paddingX={5}>\n          <Button\n            variant={'contained'}\n            fullWidth\n            size={'medium'}\n            onClick={(_e?: any) => {\n              if (btnInfo?.callback) {\n                btnInfo.callback()\n              }\n            }}\n          >\n            {btnInfo?.btnTxt}\n          </Button>\n        </Box>\n        <Toast\n          alertText={t('labelCopyAddClip')}\n          open={copyToastOpen}\n          autoHideDuration={TOAST_TIME}\n          onClose={() => {\n            setCopyToastOpen(false)\n          }}\n          severity={ToastType.success}\n        />\n      </Box>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/ModalPanels/RedPacket.tsx",
    "content": "import { IconType, PanelProps, RedPacketBase, RedPacketOpenBase } from './BasicPanel'\nimport { sanitize } from 'dompurify'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\n// value symbol\nexport const RedPacketSend_WaitForAuth = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelWaitForAuth'),\n  }\n  return <RedPacketBase {...propsPatch} {...props} />\n}\n\n// value symbol\nexport const RedPacketSend_First_Method_Denied = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.RefuseIcon,\n    describe1: props.t('labelFirstSignDenied'),\n  }\n  return <RedPacketBase {...propsPatch} {...props} />\n}\n\n// value symbol\nexport const RedPacketSend_User_Denied = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.RefuseIcon,\n    describe1: props.t('labelSignDenied'),\n  }\n  return <RedPacketBase {...propsPatch} {...props} />\n}\n\n// value symbol\nexport const RedPacketSend_In_Progress = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelRedPacketSendInProgress'),\n  }\n  return <RedPacketBase {...propsPatch} {...props} />\n}\n\n// value symbol\nexport const RedPacketSend_Success = (props: PanelProps) => {\n  let propsPatch: any = {\n    iconType: IconType.DoneIcon,\n  }\n  if (props.info.scope === sdk.LuckyTokenViewType.TARGET) {\n    propsPatch = {\n      ...propsPatch,\n      title: 'labelSendRedPacketTitleExclusive',\n      describe1: props.t('labelRedPacketSendSuccess', {\n        symbol: props.symbol,\n        value: props.value,\n      }),\n    }\n  } else {\n    propsPatch = {\n      ...propsPatch,\n      title: 'labelSendRedPacketTitlePublic',\n      describe1: props.t('labelRedPacketSendSuccess', {\n        symbol: props.symbol,\n        value: props.value,\n      }),\n      btnInfo: props?.info?.shared\n        ? {\n            btnTxt: 'labelShareQRCode',\n            callback: props.info.shared,\n          }\n        : props.btnInfo,\n    }\n  }\n\n  return <RedPacketBase {...{ ...props, ...propsPatch }} />\n}\n\n// value symbol\nexport const RedPacketSend_Failed = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.FailedIcon,\n    describe1: props.t('labelRedPacketSendFailed', {\n      symbol: props.symbol,\n      value: props.value,\n    }),\n  }\n  return <RedPacketBase {...propsPatch} {...props} />\n}\n\nexport const NFTRedPacketSend_WaitForAuth = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelWaitForAuth'),\n  }\n  return <RedPacketBase {...propsPatch} {...props} />\n}\n\nexport const NFTRedPacketSend_First_Method_Denied = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.RefuseIcon,\n    describe1: props.t('labelFirstSignDenied'),\n  }\n  return <RedPacketBase {...propsPatch} {...props} />\n}\n\nexport const NFTRedPacketSend_User_Denied = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.RefuseIcon,\n    describe1: props.t('labelSignDenied'),\n  }\n  return <RedPacketBase {...propsPatch} {...props} />\n}\n\nexport const NFTRedPacketSend_In_Progress = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelRedPacketSendInProgress'),\n  }\n  return <RedPacketBase {...propsPatch} {...props} />\n}\n\nexport const NFTRedPacketSend_Success = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.DoneIcon,\n    describe1: props.t('labelRedPacketSendSuccess', {\n      symbol: sanitize(props.symbol ?? 'NFT').toString(),\n      value: props.value,\n    }),\n  }\n  return <RedPacketBase {...propsPatch} {...props} />\n}\n\nexport const NFTRedPacketSend_Failed = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.FailedIcon,\n    describe1: props.t('labelRedPacketSendFailed', {\n      symbol: sanitize(props.symbol ?? 'NFT').toString(),\n      value: props.value,\n    }),\n  }\n  return <RedPacketBase {...propsPatch} {...props} />\n}\n\nexport const RedPacketOpen_In_Progress = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    btnInfo: undefined,\n    title: '',\n  }\n\n  return <RedPacketOpenBase {...propsPatch} {...props} />\n}\n\nexport const RedPacketOpen_Failed = (props: PanelProps) => {\n  const propsPatch = {\n    title: '',\n    iconType: IconType.FailedIcon,\n    describe1: props.t('labelRedPacketOpenFailed'),\n  }\n  return <RedPacketOpenBase {...propsPatch} {...props} />\n}\n\nexport const RedPacketOpen_Claim_In_Progress = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    btnInfo: undefined,\n    title: '',\n  }\n  return <RedPacketOpenBase {...propsPatch} {...props} />\n}\n\nexport const RedPacketSend_Claim_Success = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.DoneIcon,\n    describe1: props.t('labelRedPacketClaimSuccess'),\n  }\n  return <RedPacketOpenBase {...propsPatch} {...props} />\n}\n\nexport const RedPacketOpen_Claim_Failed = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.FailedIcon,\n    describe1: props.t('labelRedPacketOpenFailed'),\n  }\n  return <RedPacketOpenBase {...propsPatch} {...props} />\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/ModalPanels/SendAsset.tsx",
    "content": "import { Box, CardContent, Divider, Tab, Tabs, Tooltip, Typography } from '@mui/material'\nimport styled from '@emotion/styled'\nimport { MenuBtnStyled } from '../../styled'\nimport { AccountStep, AddAssetItem, SendAssetProps } from './Interface'\nimport { useTranslation } from 'react-i18next'\nimport {\n  AlertIcon,\n  AnotherIcon,\n  BackIcon,\n  Contact,\n  ExchangeAIcon,\n  fontDefault,\n  hexToRGB,\n  IncomingIcon,\n  Info2Icon,\n  L1L2_NAME_DEFINED,\n  L1l2Icon,\n  L2l2Icon,\n  MapChainId,\n  OutputIcon,\n  SagaStatus,\n  SendAssetList,\n} from '@loopring-web/common-resources'\nimport { useOpenModals, useSettings, useToggle } from '../../../stores'\n\nimport { Button, CoinIcon, TickCardStyleItem } from '../../basic-lib'\nimport React from 'react'\nimport { useTheme } from '@emotion/react'\nimport { store, useContacts } from '@loopring-web/core'\n\nconst BoxStyled = styled(Box)`` as typeof Box\n\nconst IconItem = ({ svgIcon }: { svgIcon: string }) => {\n  switch (svgIcon) {\n    case 'IncomingIcon':\n      return <IncomingIcon className='custom-size'  color={'inherit'} fontSize={'inherit'} sx={{ marginRight: 1.5, fontSize: '20px' }} />\n    case 'L2l2Icon':\n      return <L2l2Icon className='custom-size'  color={'inherit'} fontSize={'inherit'} sx={{ marginRight: 1.5, fontSize: '20px' }} />\n    case 'L1l2Icon':\n      return <L1l2Icon className='custom-size'  color={'inherit'} fontSize={'inherit'} sx={{ marginRight: 1.5, fontSize: '20px' }} />\n    case 'ExchangeAIcon':\n      return <ExchangeAIcon className='custom-size'  color={'inherit'} fontSize={'inherit'} sx={{ marginRight: 1.5, fontSize: '20px' }} />\n    case 'OutputIcon':\n      return <OutputIcon className='custom-size'  color={'inherit'} fontSize={'inherit'} sx={{ marginRight: 1.5, fontSize: '20px' }} />\n    case 'AnotherIcon':\n      return <AnotherIcon className='custom-size'  color={'inherit'} fontSize={'inherit'} sx={{ marginRight: 1.5, fontSize: '20px' }} />\n  }\n}\nexport const SendAsset = ({\n  sameLayerAssetList,\n  crossChainAssetList,\n  crossLayerAssetList,\n  allowTrade,\n  symbol,\n  isToL1,\n  toL1Title\n}: SendAssetProps) => {\n  const { t } = useTranslation('common')\n  const { defaultNetwork, isMobile } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const {\n    toggle: { send },\n  } = useToggle()\n\n  const filterAndMap = (list: AddAssetItem[]) =>\n    list\n      .filter(\n        (item) =>\n          !symbol ||\n          (item.key === 'SendAssetToAnotherNet' && send['orbiter']?.includes(symbol)) ||\n          !['SendAssetToAnotherNet'].includes(item.key),\n      )\n      .map((item, index) => (\n        <Box key={item.key} marginTop={'-1px'}>\n          <MenuBtnStyled\n            variant={'outlined'}\n            size={'large'}\n            className={`sendAsset  ${isMobile ? 'isMobile' : ''}`}\n            fullWidth\n            disabled={\n              !!(item.enableKey && allowTrade[item.enableKey]?.enable === false) ||\n              (/SendTo?(\\w)+L1/gi.test(item.key) && isToL1)\n            }\n            endIcon={<BackIcon sx={{ transform: 'rotate(180deg)' }} />}\n            onClick={(e) => {\n              item.handleSelect(e)\n            }}\n            sx={{\n              overflow: 'hidden',\n              '& .corner-tag': {\n                background: '#B8BCC7',\n              },\n              '& .title, .description': {\n                color: 'var(--color-text-secondary)',\n              },\n              ':hover': {\n                '& .corner-tag': {\n                  background: 'var(--color-primary)',\n                },\n                '& .title, .description': {\n                  color: 'var(--color-text-primary)',\n                }\n              },\n              borderTopLeftRadius: index === 0 ? '4px' : '0px',\n              borderTopRightRadius: index === 0 ? '4px' : '0px',\n              borderBottomLeftRadius: index === list.length - 1 ? '4px' : '0px',\n              borderBottomRightRadius: index === list.length - 1 ? '4px' : '0px',\n              '&&&&:hover' : {\n                borderColor: 'var(--color-border)'\n              },\n              height: isMobile ? '48px' : '64px',\n              \n           }}\n          >\n            <Box display={'flex'} alignItems={'center'}>\n              <Typography\n                component={'span'}\n                variant={'inherit'}\n                color={'inherit'}\n                display={'flex'}\n                alignItems={'center'}\n                lineHeight={'1.2em'}\n                sx={{\n                  textIndent: 0,\n                  textAlign: 'left',\n                }}\n              >\n                {IconItem({ svgIcon: item.svgIcon })}\n              </Typography>\n              <Box>\n                <Typography\n                  sx={{ textIndent: 0 }}\n                  textAlign={'left'}\n                  color={'var(--color-text-secondary)'}\n                  className='title'\n                  fontSize={\n                    isMobile \n                    ? item.description ? '12px' : '14px'\n                    : item.description ? '14px' : '16px'}\n                >\n                  {t('label' + item.key, {\n                    loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                    l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                    l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                    ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                  })}\n                </Typography>\n                {item.description && (\n                  <Typography\n                    textAlign={'left'}\n                    sx={{ textWrap: 'auto', textIndent: 0 }}\n                    variant='body2'\n                    color={'var(--color-text-primary)'}\n                    mt={0.5}\n                    className='description'\n                    fontSize={isMobile ? '11px' : '12px'}\n                  >\n                    {item.description}\n                  </Typography>\n                )}\n              </Box>\n            </Box>\n          </MenuBtnStyled>\n        </Box>\n      ))\n\n  return (\n    <BoxStyled\n      flex={1}\n      display={'flex'}\n      alignItems={'center'}\n      justifyContent={'space-between'}\n      flexDirection={'column'}\n      width={'var(--modal-width)'}\n    >\n      <Box marginBottom={3} marginTop={-1} display={'flex'} alignItems={'center'}>\n        <Typography\n          component={'h3'}\n          variant={isMobile ? 'h4' : 'h3'}\n          whiteSpace={'pre'}\n          marginRight={1}\n        >\n          {t('labelSendAssetTitle', {\n            symbol,\n            loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n          })}\n        </Typography>\n        <Tooltip title={<>{t('labelSendAssetHowto')}</>}>\n          <span>\n            <Info2Icon fontSize={'large'} htmlColor={'var(--color-text-third)'} />\n          </span>\n        </Tooltip>\n      </Box>\n      <Box\n        display={'flex'}\n        flexDirection={'column'}\n        justifyContent={'center'}\n        flex={1}\n        alignItems={'stretch'}\n        alignSelf={'stretch'}\n        className='modalContent'\n        paddingX={isMobile ? 4 : 5}\n        paddingBottom={4}\n      >\n\n        <Box flex={1} flexDirection={'column'}>\n          <Box mb={5} mt={4}>\n            {filterAndMap(sameLayerAssetList)}\n          </Box>\n          <Box mb={5}>\n            <Typography mb={2} color={'var(--color-text-secondary)'} variant='body2'>{toL1Title}</Typography>\n            {filterAndMap(crossLayerAssetList)}\n          </Box>\n          <Box >\n            {filterAndMap(crossChainAssetList).length > 0 && <Typography mb={2} color={'var(--color-text-secondary)'} variant='body2'>To other networks</Typography>} \n            {filterAndMap(crossChainAssetList)}\n          </Box>\n        </Box>\n      </Box>\n    </BoxStyled>\n  )\n  {\n    /*</WalletConnectPanelStyled>*/\n  }\n}\n\nconst BoxStyle = styled(Box)`\n  & {\n    height: inherit;\n\n    .content-main {\n      overflow: scroll;\n      align-self: stretch;\n\n      & > div {\n        align-self: stretch;\n      }\n    }\n\n    .MuiTab-root.sendType {\n      padding: ${({ theme }) => 3 * theme.unit}px ${({ theme }) => 3 * theme.unit}px;\n\n      &.Mui-selected,\n      &:hover {\n        padding: ${({ theme }) => 3 * theme.unit}px ${({ theme }) => 3 * theme.unit}px;\n        box-sizing: border-box;\n      }\n\n      &:after {\n        display: none;\n      }\n    }\n  }\n`\n\nexport const SendFromContact = (\n  props: {\n    isENSWrong: boolean,\n    selected: string\n  } & Contact,\n) => {\n  const [selected, setSelected] = React.useState(SendAssetList.SendAssetToOtherL1.key)\n  const { defaultNetwork } = useSettings()\n  const { setShowTransfer, setShowWithdraw, setShowEditContact, setShowAccount } = useOpenModals()\n  const { status: contactStatus } = useContacts()\n  const [contact, setContact] = React.useState({\n    ...props,\n  })\n\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const theme = useTheme()\n  const submit = React.useCallback(() => {\n    // : Contact, network: 'SendToOtherL1'| 'SendTOL2', onClose: () => void\n    switch (selected) {\n      case SendAssetList.SendAssetToOtherL1.key:\n        setShowWithdraw({\n          isShow: true,\n          address: contact.contactAddress,\n          name: contact.contactName,\n          addressType: contact.addressType,\n        })\n        setShowAccount({ isShow: false })\n        break\n      case SendAssetList.SendAssetToL2.key:\n        setShowTransfer({\n          isShow: true,\n          address: contact.contactAddress,\n          name: contact.contactName,\n          addressType: contact.addressType,\n        })\n        setShowAccount({ isShow: false })\n        break\n    }\n  }, [selected, contact])\n  const geUpdateContact = (_e) => {\n    setShowEditContact({\n      isShow: true,\n      info: {\n        ...contact,\n        from: AccountStep.SendAssetFromContact,\n      },\n    })\n    setShowAccount({ isShow: false })\n  }\n  const { t } = useTranslation()\n  React.useEffect(() => {\n    if (contactStatus == SagaStatus.UNSET && contact.isENSWrong) {\n      const { contacts } = store.getState().contacts\n      setContact((state) => {\n        const _contact = contacts?.find(\n          (contact) =>\n            contact.contactAddress?.toLowerCase() === state?.contactAddress?.toLowerCase(),\n        )\n        if (contact.isENSWrong && !_contact?.ens) {\n          return {\n            ...state,\n            isENSWrong: false,\n          }\n        }\n        return state\n      })\n    }\n  }, [contactStatus])\n  return (\n    <>\n      <Box\n        display={'flex'}\n        flexDirection={'column'}\n        alignItems={'flex-start'}\n        alignSelf={'stretch'}\n        marginTop={-4}\n        justifyContent={'stretch'}\n      >\n        <Typography\n          display={'flex'}\n          flexDirection={'row'}\n          component={'header'}\n          alignItems={'center'}\n          height={'var(--toolbar-row-height)'}\n          paddingX={3}\n        >\n          <Typography component={'span'} display={'inline-flex'} color={'textPrimary'}>\n            {t('labelContactsNetworkChoose', {\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n              l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n              l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n              ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n              loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n            })}\n          </Typography>\n        </Typography>\n        <Divider style={{ marginTop: '-1px', width: '100%' }} />\n      </Box>\n      <BoxStyle\n        display={'flex'}\n        alignItems={'stretch'}\n        flexDirection={'column'}\n        paddingBottom={4}\n        width={'100%'}\n      >\n        <Box flex={1} display={'flex'} flexDirection={'column'} alignItems={'stretch'}>\n          <Box\n            display={'flex'}\n            flexDirection={'column'}\n            justifyContent={'stretch'}\n            marginTop={2}\n            paddingX={3}\n          >\n            <Typography\n              variant={'body1'}\n              component={'span'}\n              color={'var(--color-text-secondary)'}\n              marginBottom={1}\n            >\n              {t('labelSendToContact')}\n            </Typography>\n            <Box\n              display={'flex'}\n              flexDirection={'column'}\n              alignItems={'stretch'}\n              borderRadius={2}\n              padding={1}\n              bgcolor='var(--field-opacity)'\n            >\n              <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n                {contact?.contactName}\n              </Typography>\n              <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n                {contact?.contactAddress}\n              </Typography>\n              <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n                {contact?.ens}\n              </Typography>\n            </Box>\n            {contact.isENSWrong && (\n              <Button\n                variant={'contained'}\n                sx={{\n                  fontSize: fontDefault.body1,\n                  marginTop: 2,\n                  padding: 1,\n                  color: 'var(--color-text-button)',\n                  display: 'flex',\n                  alignItems: 'center',\n                  background: hexToRGB(theme.colorBase.warning, 0.2),\n                  textAlign: 'left',\n                  borderRadius: 2,\n                  height: 'auto',\n                  '&:hover': {\n                    background: hexToRGB(theme.colorBase.warning, 0.3),\n                  },\n                }}\n                onClick={geUpdateContact}\n                endIcon={<BackIcon fontSize={'large'} sx={{ transform: 'rotate(180deg)' }} />}\n              >\n                <Typography component={'span'} color={'inherit'} display={'inline-flex'}>\n                  <AlertIcon color={'warning'} sx={{ marginRight: 1 / 2, marginTop: '2px' }} />\n                  {t('labelContactENSAlert')}\n                </Typography>\n              </Button>\n            )}\n          </Box>\n          <Tabs\n            variant={'fullWidth'}\n            value={selected}\n            onChange={(_event, value) => setSelected(value)}\n            aria-label='l2-history-tabs'\n            sx={{\n              display: 'flex',\n              flexWrap: 'nowrap',\n            }}\n          >\n            <Tab\n              className={'sendType'}\n              value={SendAssetList.SendAssetToOtherL1.key}\n              key={SendAssetList.SendAssetToOtherL1.key}\n              label={\n                <TickCardStyleItem\n                  className={'btnCard'}\n                  selected={selected == SendAssetList.SendAssetToOtherL1.key}\n                >\n                  <CardContent>\n                    <Typography component={'span'} display={'inline-flex'}>\n                      <CoinIcon size={32} symbol={L1L2_NAME_DEFINED[network].L1Token} />\n                    </Typography>\n                    <Typography paddingLeft={1} display={'flex'} flexDirection={'column'}>\n                      {L1L2_NAME_DEFINED[network].l1ChainName +\n                        '/' +\n                        L1L2_NAME_DEFINED[network].l1Symbol}\n                    </Typography>\n                  </CardContent>\n                </TickCardStyleItem>\n              }\n            />\n            <Tab\n              className={'sendType'}\n              value={SendAssetList.SendAssetToL2.key}\n              key={SendAssetList.SendAssetToL2.key}\n              label={\n                <TickCardStyleItem\n                  selected={selected == SendAssetList.SendAssetToL2.key}\n                  className={'btnCard'}\n                >\n                  <CardContent>\n                    <Typography component={'span'} display={'inline-flex'}>\n                      <CoinIcon size={32} symbol={L1L2_NAME_DEFINED[network].L2Token} />\n                    </Typography>\n                    <Typography paddingLeft={1} display={'flex'} flexDirection={'column'}>\n                      {L1L2_NAME_DEFINED[network].loopringL2 +\n                        '/' +\n                        L1L2_NAME_DEFINED[network].l2Symbol}\n                    </Typography>\n                  </CardContent>\n                </TickCardStyleItem>\n              }\n            />\n          </Tabs>\n        </Box>\n        <Box\n          width={'100%'}\n          display={'flex'}\n          flexDirection={'column'}\n          alignItems={'center'}\n          justifyContent={'flex-end'}\n        >\n          <Box alignSelf={'stretch'} paddingX={3}>\n            <Button\n              disabled={contact.isENSWrong}\n              onClick={submit}\n              variant={'contained'}\n              size={'medium'}\n              fullWidth\n            >\n              {t(contact.isENSWrong ? 'labelENSAddressMismatch' : 'labelContactsNext')}\n            </Button>\n          </Box>\n        </Box>\n      </BoxStyle>\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/ModalPanels/SendNFTAsset.tsx",
    "content": "import { Box, Typography } from '@mui/material'\nimport styled from '@emotion/styled'\nimport { MenuBtnStyled } from '../../styled'\nimport { SendNFTAssetProps } from './Interface'\nimport { useTranslation } from 'react-i18next'\nimport {\n  AnotherIcon,\n  BackIcon,\n  ExchangeAIcon,\n  IncomingIcon,\n  L1L2_NAME_DEFINED,\n  L1l2Icon,\n  L2l2Icon,\n  MapChainId,\n  OutputIcon,\n} from '@loopring-web/common-resources'\nimport { useSettings } from '../../../stores'\n\nconst BoxStyled = styled(Box)`` as typeof Box\n\nconst IconItem = ({ svgIcon }: { svgIcon: string }) => {\n  switch (svgIcon) {\n    case 'IncomingIcon':\n      return <IncomingIcon color={'inherit'} fontSize={'inherit'} sx={{marginRight: 1}}/>\n    case 'L2l2Icon':\n      return <L2l2Icon color={'inherit'} fontSize={'inherit'} sx={{marginRight: 1}}/>\n    case 'L1l2Icon':\n      return <L1l2Icon color={'inherit'} fontSize={'inherit'} sx={{marginRight: 1}}/>\n    case 'ExchangeAIcon':\n      return <ExchangeAIcon color={'inherit'} fontSize={'inherit'} sx={{marginRight: 1}}/>\n    case 'OutputIcon':\n      return <OutputIcon color={'inherit'} fontSize={'inherit'} sx={{marginRight: 1}}/>\n    case 'AnotherIcon':\n      return <AnotherIcon color={'inherit'} fontSize={'inherit'} sx={{marginRight: 1}}/>\n  }\n}\nexport const SendNFTAsset = ({\n  sendAssetList,\n  allowTrade,\n  // nftData,\n  isNotAllowToL1 = false,\n}: SendNFTAssetProps) => {\n  const { t } = useTranslation('common')\n  const { defaultNetwork, isMobile } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  return (\n    <BoxStyled\n      flex={1}\n      display={'flex'}\n      alignItems={'center'}\n      justifyContent={'space-between'}\n      flexDirection={'column'}\n      width={'var(--modal-width)'}\n    >\n      <Typography\n        component={'h3'}\n        variant={isMobile ? 'h4' : 'h3'}\n        whiteSpace={'pre'}\n        marginBottom={3}\n        marginTop={-1}\n      >\n        {t('labelSendAssetTitle', {\n          symbol: 'NFT',\n          loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n          loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n          l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n          l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n          ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n        })}\n      </Typography>\n      <Box\n        display={'flex'}\n        flexDirection={'column'}\n        justifyContent={'center'}\n        flex={1}\n        alignItems={'stretch'}\n        alignSelf={'stretch'}\n        className='modalContent'\n        paddingX={isMobile ? 7 : 10}\n        paddingBottom={4}\n      >\n        <Typography component={'p'} variant={'body1'} color={'textSecondary'} marginBottom={1}>\n          {t('labelSendAssetHowto')}\n        </Typography>\n        {sendAssetList.map((item) => {\n          return (\n            <Box key={item.key} marginTop={1.5}>\n              <MenuBtnStyled\n                variant={'outlined'}\n                size={'large'}\n                className={`sendAsset  ${isMobile ? 'isMobile' : ''}`}\n                fullWidth\n                disabled={\n                  !!(item.enableKey && allowTrade[item.enableKey]?.enable === false) ||\n                  (/SendToMyL1/gi.test(item.key) && isNotAllowToL1)\n                }\n                endIcon={<BackIcon sx={{ transform: 'rotate(180deg)' }} />}\n                onClick={(e) => {\n                  item.handleSelect(e)\n                }}\n              >\n                <Typography\n                  component={'span'}\n                  variant={'inherit'}\n                  color={'inherit'}\n                  display={'inline-flex'}\n                  alignItems={'center'}\n                  lineHeight={'1.2em'}\n                  sx={{\n                    textIndent: 0,\n                    textAlign: 'left',\n                  }}\n                >\n                  <>{IconItem({ svgIcon: item.svgIcon })}</>\n                  {t('label' + item.key, {\n                    loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n                    loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                    l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                    l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                    ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                  })}\n                </Typography>\n              </MenuBtnStyled>\n            </Box>\n          )\n        })}\n      </Box>\n    </BoxStyled>\n  )\n  {\n    /*</WalletConnectPanelStyled>*/\n  }\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/ModalPanels/ThirdPanelReturn.tsx",
    "content": "import { Box, BoxProps, Link, Typography } from '@mui/material'\n\nimport { useSettings } from '../../../stores'\nimport { Button } from '../../basic-lib'\nimport { BackIcon, BANXA_URLS, SoursURL } from '@loopring-web/common-resources'\nimport { MenuBtnStyled } from '../../styled'\nimport styled from '@emotion/styled'\nimport { Trans, useTranslation } from 'react-i18next'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nexport const ThirdPanelReturn = ({\n  title,\n  description,\n  btnInfo,\n}: {\n  title: string | JSX.Element\n  description: string | JSX.Element\n  btnInfo: {\n    btnTxt: string\n    callback: () => void\n  }\n} & any) => {\n  const { isMobile } = useSettings()\n\n  return (\n    <>\n      <Box\n        flex={1}\n        display={'flex'}\n        alignItems={'center'}\n        justifyContent={'space-between'}\n        flexDirection={'column'}\n      >\n        <Typography\n          component={'h3'}\n          variant={isMobile ? 'h4' : 'h3'}\n          whiteSpace={'pre'}\n          marginBottom={3}\n          marginTop={-1}\n        >\n          {title}\n        </Typography>\n\n        <Box\n          display={'flex'}\n          flexDirection={'column'}\n          justifyContent={'center'}\n          flex={1}\n          alignItems={'stretch'}\n          alignSelf={'stretch'}\n          className='modalContent'\n          paddingX={isMobile ? 7 : 5}\n          paddingBottom={4}\n        >\n          <Box display={'flex'} alignItems={'center'} justifyContent={'center'} paddingY={3}>\n            <img\n              className='loading-gif'\n              width='36'\n              src={`${SoursURL}images/loading-line.gif`}\n              alt={'loading-gif'}\n            />\n          </Box>\n          <Typography component={'p'} variant={'body1'} color={'textSecondary'} marginBottom={1}>\n            {description}\n          </Typography>\n        </Box>\n        <Box alignSelf={'stretch'} paddingX={5} marginY={5 / 2}>\n          <Button\n            variant={'contained'}\n            fullWidth\n            size={'medium'}\n            onClick={(e?: any) => {\n              if (btnInfo?.callback) {\n                btnInfo.callback(e)\n              }\n            }}\n          >\n            {btnInfo?.btnTxt}\n          </Button>\n        </Box>\n      </Box>\n    </>\n  )\n}\n\nconst BoxStyle = styled(Box)<BoxProps & { ismobile: boolean | undefined }>`\n  .way-content > div:first-of-type {\n    position: relative;\n    font-size: ${({ theme }) => theme.fontDefault.body1};\n    ${({ theme }) => `\n      padding-bottom: ${10 * theme.unit}px;\n      &:before {\n        display: block;\n        content: \" \";\n        position: absolute;\n        bottom: 0px;\n        left: 0;\n        right: 0;\n        bottom: ${6 * theme.unit}px;\n        margin: 0 ${2 * theme.unit}px;\n        color: var(--color-text-third);\n        border: 1px solid var(--color-text-third);\n        opacity: 0.4;\n      }\n      &:after {\n        display: block;\n        content: \"OR\";\n        position: absolute;\n        width: 32px;\n        height: 32px;\n        line-height: 32px;\n        text-align: center;\n        left: 50%;\n        margin-left: -16px;\n        bottom: ${2 * theme.unit}px;\n        background: ${theme.colorBase.box};\n        color: var(--color-text-third);\n        bottom: 32px;\n      }\n    `}\n    padding-left: 0;\n    padding-right: 0;\n` as (props: BoxProps & { ismobile: boolean | undefined }) => JSX.Element\n\nexport const ContinuousBanxaOrder = ({\n  // _title,\n  // description,\n  chainId,\n  btnInfo,\n  btnInfo2,\n  orderId,\n}: {\n  title: string | JSX.Element\n  chainId: sdk.ChainId\n  orderId: string\n  // description: string | JSX.Element;\n  btnInfo?: {\n    btnTxt: string\n    callback: () => void\n    isLoading?: boolean\n  }\n  btnInfo2?: {\n    btnTxt: string\n    callback: () => void\n    isLoading?: boolean\n  }\n} & any) => {\n  const { isMobile } = useSettings()\n  const { t } = useTranslation()\n  return (\n    <>\n      <BoxStyle\n        flex={1}\n        display={'flex'}\n        alignItems={'center'}\n        justifyContent={'space-between'}\n        flexDirection={'column'}\n        ismobile={isMobile}\n      >\n        <Typography\n          component={'h3'}\n          variant={'h5'}\n          whiteSpace={'pre-line'}\n          marginBottom={3}\n          marginTop={-1}\n          marginX={2}\n          alignSelf={'flex-start'}\n        >\n          {t('labelBanxaTitleCreateAgain')}\n        </Typography>\n        <Box className={'way-content'} display={'flex'} flexDirection={'column'} paddingBottom={3}>\n          <Box marginTop={1.5} component={'div'} marginX={2}>\n            <Typography\n              component={'h4'}\n              variant={'h5'}\n              whiteSpace={'pre'}\n              marginBottom={3}\n              marginTop={-1}\n            >\n              <Trans i18nKey={'labelYouAlreadyHaveAnBanxa'}>\n                You already have an awaiting payment\n                <Link\n                  style={{\n                    cursor: 'pointer',\n                    color: 'var(--color-primary)',\n                    textOverflow: 'ellipsis',\n                    overflow: 'hidden',\n                  }}\n                  target='_blank'\n                  rel='noopener noreferrer'\n                  href={`${BANXA_URLS[chainId]}/status/${orderId}`}\n                >\n                  order\n                </Link>\n                continue , or you can create a new order instead.\n              </Trans>\n            </Typography>\n            <Box display={'flex'} alignItems={'center'} justifyContent={'center'} marginX={2}>\n              <img\n                className='loading-gif'\n                alt={'loading'}\n                width='60'\n                src={`${SoursURL}images/loading-line.gif`}\n              />\n            </Box>\n            <MenuBtnStyled\n              variant={'outlined'}\n              size={'large'}\n              className={`banxaEnter  ${isMobile ? 'isMobile' : ''}`}\n              fullWidth\n              loading={btnInfo?.isLoading ? 'true' : 'false'}\n              disabled={btnInfo?.isLoading}\n              endIcon={<BackIcon sx={{ transform: 'rotate(180deg)' }} />}\n              onClick={(_e) => {\n                btnInfo.callback()\n              }}\n            >\n              <Typography\n                component={'span'}\n                variant={'inherit'}\n                color={'inherit'}\n                display={'inline-flex'}\n                alignItems={'center'}\n                lineHeight={'1.2em'}\n                sx={{\n                  textIndent: 0,\n                  textAlign: 'left',\n                }}\n              >\n                {btnInfo.btnTxt}\n              </Typography>\n            </MenuBtnStyled>\n          </Box>\n          <Box marginTop={1.5} component={'div'} marginX={2}>\n            <Typography\n              component={'h4'}\n              variant={'h5'}\n              whiteSpace={'pre'}\n              marginBottom={3}\n              marginTop={-1}\n            >\n              {t('labelHaveAnBanxaCancel')}\n            </Typography>\n            <MenuBtnStyled\n              variant={'outlined'}\n              size={'large'}\n              className={`banxaEnter  ${isMobile ? 'isMobile' : ''}`}\n              fullWidth\n              loading={btnInfo?.isLoading ? 'true' : 'false'}\n              disabled={btnInfo2?.isLoading}\n              endIcon={<BackIcon sx={{ transform: 'rotate(180deg)' }} />}\n              onClick={(_e) => {\n                btnInfo2.callback()\n              }}\n            >\n              <Typography\n                component={'span'}\n                variant={'inherit'}\n                color={'inherit'}\n                display={'inline-flex'}\n                alignItems={'center'}\n                lineHeight={'1.2em'}\n                sx={{\n                  textIndent: 0,\n                  textAlign: 'left',\n                }}\n              >\n                {btnInfo2.btnTxt}\n              </Typography>\n            </MenuBtnStyled>\n          </Box>\n        </Box>\n      </BoxStyle>\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/ModalPanels/Transfer.tsx",
    "content": "import { BasicPanel, IconType, PanelProps, TransferBase } from './BasicPanel'\nimport { sanitize } from 'dompurify'\nimport { useSettings } from '../../../stores'\nimport { L1L2_NAME_DEFINED, MapChainId } from '@loopring-web/common-resources'\nimport { Typography } from '@mui/material'\n\n// value symbol\nexport const Transfer_WaitForAuth = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelWaitForAuth'),\n  }\n  return <TransferBase {...propsPatch} {...props} />\n}\n\n// value symbol\nexport const Transfer_First_Method_Denied = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.RefuseIcon,\n    describe1: props.t('labelFirstSignDenied'),\n  }\n  return <TransferBase {...propsPatch} {...props} />\n}\n\n// value symbol\nexport const Transfer_User_Denied = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.RefuseIcon,\n    describe1: props.t('labelSignDenied'),\n  }\n  return <TransferBase {...propsPatch} {...props} />\n}\n\n// value symbol\nexport const Transfer_In_Progress = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelL2toL2InProgress'),\n  }\n  return <TransferBase {...propsPatch} {...props} />\n}\n\n// value symbol\nexport const Transfer_Success = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.DoneIcon,\n    describe1: props.t('labelL2toL2Success', {\n      symbol: props.symbol,\n      value: props.value,\n    }),\n  }\n  return <TransferBase {...propsPatch} {...props} />\n}\n\nexport const Transfer_banxa_confirm = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.SubmitIcon,\n    describe1: props.t('labelBanxaConfirmSubmit', { order: props.info.id }),\n  }\n  return <TransferBase {...propsPatch} {...props} />\n}\n\n// value symbol\nexport const Transfer_Failed = (props: PanelProps) => {\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const propsPatch = {\n    iconType: IconType.FailedIcon,\n    describe1: props.t('labelL2toL2Failed', {\n      symbol: props.symbol,\n      value: props.value,\n      loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n      l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n      l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n      ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n    }),\n  }\n  return <TransferBase {...propsPatch} {...props} />\n}\n\nexport const NFTTransfer_WaitForAuth = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelWaitForAuth'),\n  }\n  return <TransferBase {...propsPatch} {...props} />\n}\n\nexport const NFTTransfer_First_Method_Denied = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.RefuseIcon,\n    describe1: props.t('labelFirstSignDenied'),\n  }\n  return <TransferBase {...propsPatch} {...props} />\n}\n\nexport const NFTTransfer_User_Denied = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.RefuseIcon,\n    describe1: props.t('labelSignDenied'),\n  }\n  return <TransferBase {...propsPatch} {...props} />\n}\n\nexport const NFTTransfer_In_Progress = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelL2toL2InProgress'),\n  }\n  return <TransferBase {...propsPatch} {...props} />\n}\n\nexport const NFTTransfer_Success = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.DoneIcon,\n    describe1: props.t('labelL2toL2Success', {\n      symbol: sanitize(props.symbol ?? 'NFT').toString(),\n      value: props.value,\n    }),\n  }\n  return <TransferBase {...propsPatch} {...props} />\n}\n\nexport const NFTTransfer_Failed = (props: PanelProps) => {\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const propsPatch = {\n    iconType: IconType.FailedIcon,\n    describe1: props.t('labelL2toL2Failed', {\n      symbol: sanitize(props.symbol ?? 'NFT').toString(),\n      value: props.value,\n      loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n      l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n      l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n      ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n    }),\n  }\n  return <TransferBase {...propsPatch} {...props} />\n}\n\n\n\nexport const NFTBurn_WaitForAuth = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelWaitForAuth'),\n    title: 'labelL2NFTBurnTitle',\n  }\n  return <TransferBase {...propsPatch} {...props} />\n}\n\nexport const NFTBurn_First_Method_Denied = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.RefuseIcon,\n    describe1: props.t('labelFirstSignDenied'),\n    title: 'labelL2NFTBurnTitle',\n  }\n  return <TransferBase {...propsPatch} {...props} />\n}\n\nexport const NFTBurn_User_Denied = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.RefuseIcon,\n    describe1: props.t('labelSignDenied'),\n    title: 'labelL2NFTBurnTitle',\n  }\n  return <TransferBase {...propsPatch} {...props} />\n}\n\nexport const NFTBurn_In_Progress = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelL2toL2InProgress'),\n    title: 'labelL2NFTBurnTitle',\n  }\n  return <TransferBase {...propsPatch} {...props} />\n}\n\nexport const NFTBurn_Success = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.DoneIcon,\n    describe1: props.t('labelL2NFTBurSuccess', {\n      symbol: sanitize(props.symbol ?? 'NFT').toString(),\n      value: props.value,\n    }),\n    title: 'labelL2NFTBurnTitle',\n  }\n  return <TransferBase {...propsPatch} {...props} />\n}\n\nexport const NFTBurn_Failed = (props: PanelProps) => {\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const propsPatch = {\n    iconType: IconType.FailedIcon,\n    describe1: props.t('labelL2toL2Failed', {\n      symbol: sanitize(props.symbol ?? 'NFT').toString(),\n      value: props.value,\n      loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n      l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n      l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n      ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n    }),\n    title: 'labelL2NFTBurnTitle',\n  }\n  return <TransferBase {...propsPatch} {...props} />\n}\n// value symbol\nexport const General_Failed = (props: PanelProps) => {\n  return (\n    <BasicPanel\n      iconType={IconType.FailedIcon}\n      describe1={\n        <Typography color={'var(--color-error)'}>\n          {props.errorMessage}\n        </Typography>\n      }\n      {...props}\n    />\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/ModalPanels/TransferPanel.tsx",
    "content": "import { WithTranslation, withTranslation } from 'react-i18next'\nimport { ModalBackButton, SwitchPanel, SwitchPanelProps } from '../../basic-lib'\nimport { IBData, SoursURL, TRADE_TYPE } from '@loopring-web/common-resources'\nimport React from 'react'\nimport { TransferProps } from '../../tradePanel'\nimport { TradeMenuList, TransferWrap, useBasicTrade } from '../../tradePanel/components'\nimport { TransferConfirm } from '../../tradePanel/components/TransferConfirm'\nimport { ContactSelection } from '../../tradePanel/components/ContactSelection'\nimport { Box } from '@mui/material';\n\nexport const TransferPanel = withTranslation(['common', 'error'], {\n  withRef: true,\n})(\n  <T extends IBData<I>, I>({\n    walletMap = {},\n    coinMap = {},\n    isThumb = true,\n    type = TRADE_TYPE.TOKEN,\n    chargeFeeTokenList,\n    onTransferClick,\n    transferBtnStatus,\n    assetsData,\n    addrStatus,\n    isAddressCheckLoading,\n    onBack,\n    isFromContact,\n    contact,\n    contacts,\n    ...rest\n  }: TransferProps<T, I> & WithTranslation & { assetsData: any[] }) => {\n    const { onChangeEvent, index, switchData } = useBasicTrade({\n      ...rest,\n      walletMap,\n      coinMap,\n      type,\n    })\n    const [panelIndex, setPanelIndex] = React.useState(index + 1)\n    const handleConfirm = (index: number) => {\n      setPanelIndex(index)\n    }\n    // const hanleConfirm = () => {};\n    React.useEffect(() => {\n      setPanelIndex(index + 1)\n    }, [index])\n\n    const confirmPanel = {\n      key: 'confirm',\n      element: React.useMemo(\n        () => (\n          <TransferConfirm\n            {...{\n              ...rest,\n              onTransferClick,\n              type,\n              tradeData: switchData.tradeData,\n              isThumb,\n              handleConfirm,\n            }}\n          />\n        ),\n        [rest, onTransferClick, type, switchData.tradeData, isThumb],\n      ),\n      toolBarItem: (\n        <ModalBackButton\n          marginTop={0}\n          marginLeft={-2}\n          onBack={() => {\n            setPanelIndex(1)\n          }}\n          {...rest}\n        />\n      ),\n    }\n    const tradePanel = {\n      key: 'trade',\n      element: React.useMemo(\n        () => (\n          // @ts-ignore\n          <TransferWrap\n            key={'trade'}\n            {...{\n              ...rest,\n              type,\n              walletMap,\n              coinMap,\n              chargeFeeTokenList: chargeFeeTokenList || [],\n              tradeData: switchData.tradeData,\n              onChangeEvent,\n              isThumb,\n              disabled: !!rest.disabled,\n              handleConfirm,\n              // onTransferClick,\n              transferBtnStatus,\n              assetsData,\n              addrStatus,\n              isAddressCheckLoading,\n              isFromContact,\n              contact,\n              onClickContact: () => {\n                setPanelIndex(3)\n              },\n            }}\n          />\n        ),\n        [\n          rest,\n          type,\n          chargeFeeTokenList,\n          switchData.tradeData,\n          onChangeEvent,\n          isThumb,\n          onTransferClick,\n          transferBtnStatus,\n          assetsData,\n          addrStatus,\n          isAddressCheckLoading,\n        ],\n      ),\n      toolBarItem: React.useMemo(\n        () => (\n          <>\n            {onBack ? (\n              <ModalBackButton\n                marginTop={0}\n                marginLeft={-2}\n                onBack={() => {\n                  onBack()\n                }}\n                {...rest}\n              />\n            ) : (\n              <></>\n            )}\n          </>\n        ),\n        [onBack],\n      ),\n    }\n    const tokenSelectionPanel = {\n      key: 'tradeMenuList',\n      element: React.useMemo(\n        () => (\n          <TradeMenuList\n            {...{\n              nonZero: true,\n              sorted: true,\n              ...rest,\n              onChangeEvent,\n              walletMap,\n              coinMap,\n              selected: switchData.tradeData.belong,\n              tradeData: switchData.tradeData,\n              //oinMap\n            }}\n          />\n        ),\n        [switchData, rest, onChangeEvent],\n      ),\n      // toolBarItem: undefined,\n      toolBarItem: undefined,\n    }\n    const contactSelectionPanel = {\n      key: 'contactSelection',\n      element: React.useMemo(\n        () => (\n          <ContactSelection\n            key={'contactSelection'}\n            contacts={contacts}\n            onSelect={(address) => {\n              setPanelIndex(1)\n              rest.handleOnAddressChange(address, true)\n            }}\n            scrollHeight={'380px'}\n          />\n        ),\n        [contacts],\n      ),\n      toolBarItem: React.useMemo(\n        () => (\n          <ModalBackButton\n            marginTop={0}\n            marginLeft={-2}\n            onBack={() => {\n              setPanelIndex(1)\n            }}\n            {...rest}\n          />\n        ),\n        [onBack],\n      ),\n    }\n    const props: SwitchPanelProps<string> = {\n      index: panelIndex,\n      panelList: [confirmPanel, tradePanel, tokenSelectionPanel, contactSelectionPanel],\n    }\n\n      return (type == TRADE_TYPE.TOKEN && !switchData.tradeData?.belong) ? <Box\n          flex={1}\n          height={\"var(--min-height)\"}\n          width={\"var(--modal-min-width)\"}\n          justifyContent={'center'}\n          display={'flex'}\n          flexDirection={'column'}\n          alignItems={'center'}\n      >\n          <img\n              className='loading-gif'\n              alt={'loading'}\n              width='60'\n              src={`${SoursURL}images/loading-line.gif`}\n          /></Box> : <SwitchPanel {...{...rest, ...props}} />\n  },\n) as <T, I>(props: TransferProps<T, I> & React.RefAttributes<any>) => JSX.Element\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/ModalPanels/TransferToTaikoAccount.tsx",
    "content": "import { IconType, PanelProps, TransferToTaikoBase } from './BasicPanel'\nimport { useSettings } from '../../../stores'\nimport { L1L2_NAME_DEFINED, MapChainId } from '@loopring-web/common-resources'\n\nexport const Transfer_To_Taiko_WaitForAuth = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelWaitForAuth'),\n  }\n  return <TransferToTaikoBase {...propsPatch} {...props} />\n}\n\nexport const Transfer_To_Taiko_First_Method_Denied = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.RefuseIcon,\n    describe1: props.t('labelFirstSignDenied'),\n  }\n  return <TransferToTaikoBase {...propsPatch} {...props} />\n}\n\nexport const Transfer_To_Taiko_User_Denied = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.RefuseIcon,\n    describe1: props.t('labelSignDenied'),\n  }\n  return <TransferToTaikoBase {...propsPatch} {...props} />\n}\n\nexport const Transfer_To_Taiko_In_Progress = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelL2toL2InProgress'),\n  }\n  return <TransferToTaikoBase {...propsPatch} {...props} />\n}\n\nexport const Transfer_To_Taiko_Success = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.DoneIcon,\n    describe1: props.t('labelL2toL2Success', {\n      symbol: props.symbol,\n      value: props.value,\n    }),\n  }\n  return <TransferToTaikoBase {...propsPatch} {...props} />\n}\n\nexport const Transfer_To_Taiko_banxa_confirm = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.SubmitIcon,\n    describe1: props.t('labelBanxaConfirmSubmit', { order: props.info.id }),\n  }\n  return <TransferToTaikoBase {...propsPatch} {...props} />\n}\n\nexport const Transfer_To_Taiko_Failed = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.FailedIcon,\n    describe1: 'Send to Taiko Failed'\n  }\n  return <TransferToTaikoBase {...propsPatch} {...props} />\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/ModalPanels/TransferToTaikoAccountPanel.tsx",
    "content": "import {\n  AlertIcon,\n  BackIcon,\n  CloseIcon,\n  ContactIcon,\n  hexToRGB,\n  Info2Icon,\n  SearchIcon,\n  TokenType,\n} from '@loopring-web/common-resources'\n\nimport { Box, Button, Input, Tooltip, Typography, Modal } from '@mui/material'\nimport { ModalCloseButton, SpaceBetweenBox } from '../../basic-lib'\nimport { TransferToTaikoAccountProps } from '../../tradePanel'\nimport { CoinIcons } from '../../tableList'\nimport KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'\nimport { FeeSelectModal } from './FeeSelect'\nimport { ContactSelection } from '../../tradePanel/components/ContactSelection'\nimport ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos';\nimport { useTheme } from '@emotion/react'\n\nconst formatTokenList = (tokens: string[]):string => {\n  if (!tokens || tokens.length === 0) return '';\n  if (tokens.length === 1) return tokens[0];\n  if (tokens.length === 2) return `${tokens[0]} and ${tokens[1]}`;\n  \n  const lastToken = tokens[tokens.length - 1];\n  const otherTokens = tokens.slice(0, -1);\n  return `${otherTokens.join(', ')}, and ${lastToken}`;\n}\n\nexport const TransferToTaikoAccountModal = (props: TransferToTaikoAccountProps) => {\n  const {\n    onClickContact,\n    balance,\n    fee,\n    onClickFee,\n    onInputAmount,\n    onInputAddress,\n    token,\n    onClickToken,\n    onClickBalance,\n    feeSelect,\n    contacts,\n    panel,\n    tokenSelection,\n    receiptInput,\n    amountInput,\n    onClickBack,\n    onClickClose,\n    open,\n    supportedTokens,\n    sendBtn,\n    maxAlert,\n    receiptError,\n    receiptClear,\n    showReceiptWarning,\n    onClickConfirm,\n    title,\n    hideContactBtn\n  } = props\n\n  const theme = useTheme();\n  const mainPanel = (\n    <>\n      <Box>\n        <Typography variant={'h3'} textAlign={'center'}>\n          {title}\n        </Typography>\n        <Box mt={6}>\n          <SpaceBetweenBox\n            mb={0.5}\n            leftNode={\n              <Typography fontSize={'14px'} color={'var(--color-text-third)'}>\n                Select Token\n              </Typography>\n            }\n            rightNode={\n              <Typography\n                component={'p'}\n                onClick={onClickBalance}\n                sx={{ textDecoration: 'underline', cursor: 'pointer' }}\n                fontSize={'14px'}\n                color={'var(--color-text-secondary)'}\n              >\n                Available: {balance}\n              </Typography>\n            }\n          />\n          <Input\n            sx={{\n              height: '48px',\n              bgcolor: 'var(--color-bg-secondary)',\n              textAlign: 'right',\n              px: 2,\n              fontSize: '20px',\n            }}\n            placeholder='0.00'\n            disableUnderline\n            fullWidth\n            startAdornment={\n              <Box\n                display={'flex'}\n                alignItems={'center'}\n                component={'div'}\n                sx={{ cursor: 'pointer' }}\n                onClick={onClickToken}\n              >\n                <CoinIcons type={TokenType.single} tokenIcon={[token.coinJSON]} />\n                <Typography ml={0.5} fontSize={'16px'} color={'var(--color-text-primary)'}>\n                  {token.symbol}\n                </Typography>\n                <KeyboardArrowDownIcon\n                  sx={{ ml: 0.5, color: 'var(--color-text-secondary)' }}\n                ></KeyboardArrowDownIcon>\n              </Box>\n            }\n            inputProps={{ sx: { textAlign: 'right' } }}\n            onInput={(e: any) => onInputAmount(e.target.value)}\n            value={amountInput}\n          />\n          <Typography\n            sx={{\n              opacity: maxAlert.show ? 1 : 0,\n              textAlign: 'right',\n              color: 'var(--color-error)',\n              fontSize: '12px',\n              mt: -1,\n            }}\n          >\n            {maxAlert.message || '--'}\n          </Typography>\n        </Box>\n        <Box mt={3}>\n          <Typography mb={0.5} color={'var(--color-text-third)'}>\n            Recipient\n          </Typography>\n          <Input\n            sx={{\n              height: '48px',\n              bgcolor: 'var(--color-bg-secondary)',\n              textAlign: 'right',\n              px: 2,\n              fontSize: '14px',\n            }}\n            placeholder='Recipient'\n            disableUnderline\n            fullWidth\n            endAdornment={\n              <Box display={'flex'} alignItems={'center'}>\n                {receiptClear.show && (\n                  <CloseIcon\n                    onClick={receiptClear.onClick}\n                    className='custom-size'\n                    sx={{\n                      fontSize: '16px',\n                      width: '16px',\n                      height: '16px',\n                      cursor: 'pointer',\n                      color: 'var(--color-text-third)',\n                      mr: 1,\n                    }}\n                  />\n                )}\n                {!hideContactBtn && <ContactIcon\n                  onClick={onClickContact}\n                  className='custom-size'\n                  sx={{ fontSize: '24px', width: '24px', height: '24px', cursor: 'pointer' }}\n                />}\n              </Box>\n            }\n            onInput={(e: any) => onInputAddress(e.target.value)}\n            value={receiptInput}\n          />\n          {receiptError.show && (\n            <Typography\n              sx={{\n                opacity: true ? 1 : 0,\n                textAlign: 'left',\n                color: 'var(--color-error)',\n                fontSize: '12px',\n                mt: 0.5,\n              }}\n            >\n              {receiptError.message}\n            </Typography>\n          )}\n          {showReceiptWarning && (\n            <Typography\n              marginTop={2}\n              variant={'body1'}\n              component={'span'}\n              p={1}\n              px={2}\n              display={'inline-flex'}\n              bgcolor={hexToRGB(theme.colorBase.warning, 0.2)}\n              borderRadius={'4px'}\n              color={'var(--color-warning)'}\n              fontSize={'12px'}\n            >\n              <AlertIcon color={'warning'} sx={{ marginRight: 1 / 2 }} />\n              Please ensure that the recipient's address is capable of properly receiving the\n              assets.\n            </Typography>\n          )}\n        </Box>\n        <Typography mt={3} color={'var(--color-text-third)'} fontSize={'12px'}>\n          Trust Mode: Operated by Loopring's team to maintain liquidity.\n          <br />\n          Supported Assets: {formatTokenList(supportedTokens)}.\n        </Typography>\n      </Box>\n\n      <Box>\n        <SpaceBetweenBox\n          leftNode={\n            <Box display=\"flex\" alignItems=\"center\">\n              <Typography color={'var(--color-text-primary)'}>\n                Transaction Fee\n              </Typography>\n              <Tooltip title={'The total cost of completing the transaction, including network fees, service fees, and other associated charges.'} placement={'top'}>\n                <Typography component=\"span\" marginLeft={0.5} display=\"flex\" alignItems=\"center\">\n                  <Info2Icon fontSize={'small'} color={'inherit'} sx={{ cursor: 'pointer' }} />\n                </Typography>\n              </Tooltip>\n            </Box>\n          }\n          rightNode={\n            <Typography\n              color={'var(--color-text-primary)'}\n              sx={{ cursor: 'pointer' }}\n              onClick={onClickFee}\n              display={'flex'}\n              alignItems={'center'}\n            >\n              {feeSelect.feeLoading ? (\n                <Typography color={'var(--color-warning)'}>calculating</Typography>\n              ) : (\n                fee\n              )}\n              {fee !== '--' && (\n                <ArrowForwardIosIcon sx={{ fontSize: '14px', mb: '1px' }} className='custom-size' />\n              )}\n            </Typography>\n          }\n        />\n        <Typography\n          sx={{\n            opacity: (!feeSelect.feeLoading&& feeSelect.isFeeNotEnough) ? 1 : 0,\n            mt: 0.5,\n          }}\n          color={'var(--color-error)'}\n          textAlign={'right'}\n        >\n          insufficient balance\n        </Typography>\n        <Button\n          disabled={sendBtn.disabled}\n          onClick={sendBtn.onClick}\n          variant='contained'\n          fullWidth\n          sx={{ mt: 3 }}\n        >\n          {sendBtn.text || 'Send'}\n        </Button>\n      </Box>\n    </>\n  )\n  const confirmPanel = (\n    <Box display={'flex'} justifyContent={'space-between'} flexDirection={'column'}>\n      <Typography variant={'h3'} textAlign={'center'}>\n        {title}\n      </Typography>\n      <Box mt={6} mb={4}>\n        <Box mb={4}>\n          <Typography color={'var(--color-text-third)'}>Token Amount</Typography>\n          <Typography mt={1} color={'var(--color-text-primary)'}>{amountInput} {token.symbol}</Typography>\n        </Box>\n        <Box mb={4}>\n          <Typography color={'var(--color-text-third)'}>Recipient</Typography>\n          <Typography mt={1} color={'var(--color-text-primary)'}>{receiptInput}</Typography>\n        </Box>\n        <Box mb={4}>\n          <Typography color={'var(--color-text-third)'}>Fee</Typography>\n          <Typography mt={1} color={'var(--color-text-primary)'}>{fee}</Typography>\n        </Box>\n      </Box>\n\n      <Button\n        onClick={onClickConfirm}\n        variant='contained'\n        fullWidth\n        sx={{ mt: 3 }}\n      >\n        Confirm\n      </Button>\n    </Box>\n  )\n  const tokenSelectPanel = (\n    <Box mt={2}>\n      <Box my={1.5} display={'flex'} alignItems={'center'}>\n        <Input\n          value={tokenSelection.filter}\n          onChange={(e) => tokenSelection.onChangeFilter(e.target.value)}\n          endAdornment={\n            tokenSelection.filter ? (\n              <Box component={'span'} onClick={tokenSelection.onClickClearFilter}>\n                x\n              </Box>\n            ) : (\n              <></>\n            )\n          }\n          placeholder='Search'\n          startAdornment={<SearchIcon sx={{ mr: 1 }} />}\n          sx={{ width: '94%', px: 1, bgcolor: 'var(--field-opacity)' }}\n          disableUnderline\n        />\n        <Typography\n          width={'16%'}\n          component={'span'}\n          onClick={tokenSelection.onClickCancel}\n          textAlign={'right'}\n          sx={{ cursor: 'pointer' }}\n        >\n          Cancel\n        </Typography>\n      </Box>\n      <Box>\n        {tokenSelection.tokens.map((token) => {\n          return (\n            <SpaceBetweenBox\n              alignItems={'center'}\n              key={token.symbol}\n              py={1}\n              px={2.5}\n              mx={-2.5}\n              sx={{\n                ':hover': {\n                  bgcolor: 'var(--color-box-hover)',\n                },\n                cursor: 'pointer',\n              }}\n              onClick={() => tokenSelection.onClickToken(token.symbol)}\n              leftNode={\n                <Box display={'flex'} alignItems={'center'}>\n                  <CoinIcons type={TokenType.single} tokenIcon={token.coinJSON as any} />\n                  <Typography ml={1} fontSize={'14px'} color={'var(--color-text-primary)'}>\n                    {token.symbol}\n                  </Typography>\n                </Box>\n              }\n              rightNode={\n                <Typography\n                  component={'p'}\n                  sx={{ cursor: 'pointer' }}\n                  fontSize={'14px'}\n                  color={'var(--color-text-secondary)'}\n                >\n                  {token.amount}\n                </Typography>\n              }\n            />\n          )\n        })}\n      </Box>\n    </Box>\n  )\n\n  return (\n    <Modal\n      open={open}\n      onClose={onClickClose}\n      aria-labelledby='modal-modal-title'\n      aria-describedby='modal-modal-description'\n    >\n      <Box height={'100%'} display={'flex'} justifyContent={'center'} alignItems={'center'}>\n        <Box bgcolor={'var(--color-box)'}>\n          <Box\n            display={'flex'}\n            width={'100%'}\n            justifyContent={'space-between'}\n            mt={3}\n            px={3}\n            mb={1.5}\n          >\n            <BackIcon\n              sx={{\n                cursor: 'pointer',\n                fontSize: '24px',\n                color: 'var(--color-text-secondary)',\n              }}\n              className='custom-size'\n              onClick={onClickBack}\n            />\n            <CloseIcon\n              sx={{\n                cursor: 'pointer',\n                fontSize: '24px',\n                color: 'var(--color-text-secondary)',\n              }}\n              className='custom-size'\n              onClick={onClickClose}\n            />\n          </Box>\n          <Box\n            display={'flex'}\n            flexDirection={'column'}\n            justifyContent={'space-between'}\n            width={'var(--modal-width)'}\n            height={'530px'}\n            px={panel === 'tokenSelection' ? 2.5 : 4}\n            pb={4}\n          >\n            {panel === 'main' ? (\n              mainPanel\n            ) : panel === 'tokenSelection' ? (\n              tokenSelectPanel\n            ) : panel === 'confirm' ? (\n              confirmPanel\n            ) : (\n              <ContactSelection {...contacts} scrollHeight='388px' />\n            )}\n\n            <FeeSelectModal\n              open={feeSelect.open}\n              onClose={feeSelect.onClose}\n              chargeFeeTokenList={feeSelect.chargeFeeTokenList}\n              feeInfo={feeSelect.feeInfo}\n              handleToggleChange={feeSelect.handleToggleChange}\n              disableNoToken={feeSelect.disableNoToken}\n              withdrawInfos={feeSelect.withdrawInfos}\n            />\n          </Box>\n        </Box>\n      </Box>\n    </Modal>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/ModalPanels/UnlockAccount.tsx",
    "content": "import { Trans } from 'react-i18next'\nimport { IconType, PanelProps, UnlockAccountBase } from './BasicPanel'\nimport { Box, Button, Link, Typography } from '@mui/material'\nimport { WalletType } from '@loopring-web/loopring-sdk'\nimport { FEED_BACK_LINK } from '@loopring-web/common-resources'\nimport { TextareaAutosizeStyled } from '../../basic-lib'\nimport React from 'react'\nimport { DropdownIconStyled } from '../../tradePanel'\nimport { TransErrorHelp } from '../../block'\nimport { Checkbox } from '@mui/material'\nimport { CheckBoxIcon, CheckedIcon } from '@loopring-web/common-resources'\n\n// symbol\nexport const UnlockAccount_WaitForAuth = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelWaitForAuth'),\n  }\n  return <UnlockAccountBase {...props} {...propsPatch} />\n}\n\nexport const UnlockAccount_User_Denied = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.RefuseIcon,\n    describe1: <Trans i18nKey={'labelSignDenied'} />,\n  }\n  return <UnlockAccountBase {...propsPatch} {...props} />\n}\n\n// symbol\nexport const UnlockAccount_Success = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.DoneIcon,\n    describe1: <Trans i18nKey={'labelUnlockAccountSuccess'} />,\n  }\n  return <UnlockAccountBase {...propsPatch} {...props} />\n}\n\nexport const UnlockAccount_Failed = ({\n  error,\n  errorOptions,\n  t,\n  onClickReset,\n  ...props\n}: PanelProps & { walletType?: WalletType; onClickReset: () => void }) => {\n  const isContractOrInCounterFactual =\n    props.walletType && (props.walletType.isContract || props.walletType.isInCounterFactualStatus)\n  const showDropdown =\n    error?.code === 500000 || isContractOrInCounterFactual\n  const [dropdownStatus, setDropdownStatus] = React.useState<'up' | 'down'>('down')\n  const propsPatch = {\n    ...props,\n    iconType: IconType.FailedIcon,\n    describe1: (\n      <>\n        {error ? (\n          <Box display={'flex'} flexDirection={'column'}>\n            <Typography\n              color={'var(--color-error)'}\n              component={'span'}\n              variant={'inherit'}\n              display={'inline-flex'}\n              onClick={() => setDropdownStatus((prev) => (prev === 'up' ? 'down' : 'up'))}\n              justifyContent={'center'}\n              alignItems={'center'}\n            >\n              <TransErrorHelp error={error} options={errorOptions} />\n              {showDropdown && <DropdownIconStyled status={dropdownStatus} fontSize={'medium'} />}\n            </Typography>\n            {isContractOrInCounterFactual && (\n              <Typography color={'textSecondary'} paddingLeft={2}>\n                <Trans i18nKey={'labelConnectUsSimple'} ns={'error'}>\n                  Please\n                  <Link target='_blank' rel='noopener noreferrer' href={FEED_BACK_LINK}>\n                    contact us\n                  </Link>\n                  .\n                </Trans>\n              </Typography>\n            )}\n          </Box>\n        ) : (\n          <Trans i18nKey={'labelUnlockAccountFailed'} />\n        )}\n        {showDropdown &&\n          dropdownStatus === 'up' &&\n          (isContractOrInCounterFactual ? (\n            <TextareaAutosizeStyled\n              aria-label='Error Description'\n              minRows={5}\n              style={{ maxHeight: '90px', overflow: 'auto' }}\n              disabled={true}\n              value={`${JSON.stringify(error)}}`}\n            />\n          ) : (\n            <Box>\n              <Typography textAlign={'left'} variant={'body2'}>\n                {t('labelUnlockErrorLine1Part1')}\n                <Link onClick={onClickReset}>{t('labelUnlockErrorLine1Part2')}</Link>\n                {t('labelUnlockErrorLine1Part3')}\n              </Typography>\n              <Typography\n                textAlign={'left'}\n                onClick={props.resetAccount}\n                marginTop={1}\n                variant={'body2'}\n              >\n                {t('labelUnlockErrorLine2Part1')}\n                <Link onClick={onClickReset}>{t('labelUnlockErrorLine2Part2')}</Link>\n              </Typography>\n            </Box>\n          ))}\n      </>\n    ),\n  }\n  return <UnlockAccountBase {...{ ...propsPatch, t }} />\n}\n\nexport const UnlockAccount_Reset_Key_Confirm = ({\n  t,\n  resetAccount\n}: PanelProps & { walletType?: WalletType; resetAccount: () => void }) => {\n  const [checked, setChecked] = React.useState(false)\n  return (\n    <Box>\n      <Typography textAlign={'center'} mt={3} variant={'h3'}>\n        {t('labelUpdateAccount')}\n      </Typography>\n      <Box padding={4} mt={0}>\n        <Typography textAlign={'left'} color={'var(--color-text-secondary)'}>\n          Please read the following caveats carefully before resetting your EDDSA key:\n          <br />\n          <br />\n          • If you have any unsettled Dual Investment portfolios, your account will be locked until\n          they are settled.\n          <br />\n          • If you have an existing Portal position, you will not be able to reset your L2 on your\n          own.\n          <br />• If you are unsure about the sequence of this operation, please contact us at\n          support@loopring.io and provide your wallet details for assistance.\n          <br />• If you have any pending limit orders, they will be canceled because they are associated with the old L2 keypair.\n        </Typography>\n\n        <Typography\n          textAlign={'left'}\n          color={checked ? 'var(--color-text-primary)' : 'var(--color-text-secondary)'}\n          my={3}\n        >\n          <Checkbox\n            checked={checked}\n            checkedIcon={<CheckedIcon />}\n            icon={<CheckBoxIcon />}\n            color='default'\n            sx={{ height: 16, width: 16, mr: 0.5 }}\n            onChange={() => {\n              setChecked(!checked)\n            }}\n          />\n          I have read the caveats and still want to reset the EDDSA key on my own.\n        </Typography>\n\n        <Button variant={'contained'} disabled={!checked} fullWidth onClick={resetAccount}>\n          Reset EDDSA Key\n        </Button>\n      </Box>\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/ModalPanels/UpdateAccount.tsx",
    "content": "import { TFunction } from 'react-i18next'\nimport { BasicPanel, IconType, PanelProps, UpdateAccountBase } from './BasicPanel'\nimport { Box, Typography } from '@mui/material'\nimport { AnimationArrow, Button, useSettings } from '../../../index'\nimport { AccountBasePanel, AccountBaseProps } from './index'\nimport { DepositRecorder } from './DepositRecorder'\nimport { AccountHashInfo, L1L2_NAME_DEFINED, MapChainId } from '@loopring-web/common-resources'\n\nexport const UpdateAccount = ({\n  t,\n  goUpdateAccount,\n  ...props\n}: { t: TFunction } & AccountBaseProps & {\n    goUpdateAccount?: () => void\n    clearDepositHash: () => void\n    chainInfos: AccountHashInfo\n  }) => {\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  return (\n    <Box\n      flex={1}\n      display={'flex'}\n      flexDirection={'column'}\n      justifyContent={'space-between'}\n      alignItems={'center'}\n    >\n      <Box\n        display={'flex'}\n        flex={1}\n        marginBottom={5}\n        justifyContent={'center'}\n        alignItems={'center'}\n      >\n        <AccountBasePanel {...props} t={t} />\n      </Box>\n      <Box\n        display={'flex'}\n        marginTop={2}\n        alignSelf={'stretch'}\n        paddingX={5}\n        flexDirection={'column'}\n        alignItems={'center'}\n      >\n        <Typography variant={'body2'}>\n          {t('labelActivatedAccountDeposit', {\n            layer2: L1L2_NAME_DEFINED[network].layer2,\n          })}\n        </Typography>\n        <AnimationArrow className={'arrowCta'} />\n        <Button\n          variant={'contained'}\n          fullWidth\n          size={'medium'}\n          onClick={() => {\n            if (goUpdateAccount) {\n              goUpdateAccount()\n            }\n          }}\n        >\n          {t('labelActivateAccount')}\n        </Button>\n      </Box>\n      <Box\n        display={'flex'}\n        marginX={0}\n        marginTop={3}\n        marginBottom={0}\n        alignSelf={'stretch'}\n        paddingX={5}\n        padding={0}\n      >\n        <DepositRecorder {...props} clear={props.clearDepositHash} t={t} />\n      </Box>\n    </Box>\n  )\n}\n\n// symbol\nexport const UpdateAccount_Approve_WaitForAuth = (props: PanelProps) => {\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelWaitForAuth', {\n      layer2: L1L2_NAME_DEFINED[network].layer2,\n      l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n      loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n      l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n      l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n      ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n    }),\n  }\n  return <UpdateAccountBase {...props} {...propsPatch} />\n}\n\nexport const UpdateAccount_First_Method_Denied = (props: PanelProps) => {\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const propsPatch = {\n    iconType: IconType.RefuseIcon,\n    describe1: props.t('labelFirstSignDenied', {\n      layer2: L1L2_NAME_DEFINED[network].layer2,\n      loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n      l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n      loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n      l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n      l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n      ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n    }),\n  }\n  return <UpdateAccountBase {...propsPatch} {...props} />\n}\n\nexport const UpdateAccount_User_Denied = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.RefuseIcon,\n    describe1: props.t('labelSignDenied'),\n  }\n  return <UpdateAccountBase {...propsPatch} {...props} />\n}\n\n// symbol\nexport const UpdateAccount_Success = (props: PanelProps) => {\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const describe1 = props.t(\n    props.patch?.isReset ? 'labelResetAccountSuccess' : 'labelUpdateAccountSuccess',\n    {\n      layer2: L1L2_NAME_DEFINED[network].layer2,\n      l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n      loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n      l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n      l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n      ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n    },\n  )\n  const describe2 = (\n    <Box display={'flex'} marginTop={0} alignItems={'flex-center'}>\n      <Typography\n        marginX={3}\n        whiteSpace={'pre-line'}\n        variant={'h5'}\n        textAlign={'center'}\n        color={'textPrimary'}\n        component={'div'}\n        marginTop={0}\n        alignSelf={'flex-center'}\n        paddingX={1}\n      >\n        {props.t(\n          props.patch?.isReset ? 'labelResetAccountSuccess2' : 'labelUpdateAccountSuccess2',\n          {\n            loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n            l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n            l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n            ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n          },\n        )}\n      </Typography>\n    </Box>\n  )\n  const propsPatch = {\n    iconType: IconType.DoneIcon,\n    describe1,\n    describe2,\n  }\n  return <UpdateAccountBase {...propsPatch} {...props} />\n}\n\n// value symbol\nexport const UpdateAccount_Failed = (props: PanelProps) => {\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const propsPatch = {\n    iconType: IconType.FailedIcon,\n    describe1: props.t('labelUpdateAccountFailed', {\n      loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n    }),\n  }\n  return <UpdateAccountBase {...propsPatch} {...props} />\n}\n\nexport const UpdateAccount_SmartWallet_NotSupported_Alert = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.FailedIcon,\n    describe1: <Typography >Currently, only EOA wallets are supported.\n      <br/>\n      Loopring Smart Wallet support is coming soon.\n      <br/>\n      Stay tuned for updates!\n    </Typography>,\n  }\n  return <BasicPanel {...propsPatch} {...props} title={undefined}/>\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/ModalPanels/Vault.tsx",
    "content": "import {\n  IconType,\n  PanelProps,\n  VaultBorrowBase,\n  VaultDustCollectorBase,\n  VaultExitBase,\n  VaultJoinBase,\n  VaultRepayBase,\n  VaultTradeBase,\n} from './BasicPanel'\nimport { Box, Tooltip, Typography } from '@mui/material'\nimport {\n  AlertIcon,\n  EmptyValueTag,\n  ErrorIcon,\n  hexToRGB,\n  Info2Icon,\n  mapSpecialTokenName,\n  TokenType,\n  YEAR_DAY_MINUTE_FORMAT,\n} from '@loopring-web/common-resources'\nimport moment from 'moment/moment'\nimport React from 'react'\nimport { useSettings } from '../../../stores'\nimport { useTheme } from '@emotion/react'\nimport { CoinIcons } from '../../tableList'\nimport { useTranslation } from 'react-i18next'\nimport { SpaceBetweenBox } from '../../../components/basic-lib'\n\nconst TradeDes2 = (props: PanelProps) => {\n  const { isMobile, coinJson } = useSettings()\n  const theme = useTheme()\n  const {\n    percentage,\n    status,\n    feeStr: amountFee,\n    buyStr: amountBuy,\n    sellStr: amountSell,\n    sellToken: sellSymbol,\n    buyToken: buySymbol,\n    price,\n    time,\n    placedAmount,\n    executedAmount,\n    executedRate,\n    convertedAmount,\n    fromSymbol,\n    toSymbol,\n  } = props?.info ?? {}\n  const {t} = useTranslation()\n  return (\n    <>\n      <Box\n        justifySelf={'stretch'}\n        display={'flex'}\n        flexDirection={'column'}\n        minWidth={'var(--modal-min-width)'}\n        justifyContent={'center'}\n        marginTop={2}\n        paddingX={isMobile ? 1 : 0}\n      >\n        <Typography\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n          component={'span'}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {props.t('labelVaultType')}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {props.t('labelVaultSwap')}\n          </Typography>\n        </Typography>\n        <Typography\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n          component={'span'}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {props.t('labelVaultStatus')}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {props.t('labelVaultTradeStatus', {\n              status,\n              percentage: percentage ? `(${percentage}%)` : '',\n            })}\n          </Typography>\n        </Typography>\n\n        <Typography\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n          component={'span'}\n        >\n          <Typography\n            display={'flex'}\n            alignItems={'center'}\n            variant={'body1'}\n            component={'span'}\n            color={'var(--color-text-secondary)'}\n          >\n            {t('labelVaultPlacedAmount')}\n            <Tooltip title={<>{t('labelVaultPlacedAmountTip')}</>}>\n              <Typography marginLeft={0.5} display={'flex'} alignItems={'center'}>\n                <Info2Icon fontSize={'medium'} htmlColor={'var(--color-text-third)'} />\n              </Typography>\n            </Tooltip>\n          </Typography>\n          <Typography\n            display={'flex'}\n            flexDirection={'row'}\n            alignItems={'center'}\n            variant={'body1'}\n            component={'span'}\n            color={'var(--color-text-primary)'}\n          >\n            <CoinIcons\n              size='small'\n              type={TokenType.single}\n              tokenIcon={[coinJson[sellSymbol], undefined]}\n            />{' '}\n            {placedAmount}\n          </Typography>\n        </Typography>\n        <Typography\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n          component={'span'}\n        >\n          <Typography\n            display={'flex'}\n            alignItems={'center'}\n            variant={'body1'}\n            component={'span'}\n            color={'var(--color-text-secondary)'}\n          >\n            {t('labelVaultExecutedAmount')}\n            <Tooltip title={<>{t('labelVaultExecutedAmountTip')}</>}>\n              <Typography marginLeft={0.5} display={'flex'} alignItems={'center'}>\n                <Info2Icon fontSize={'medium'} htmlColor={'var(--color-text-third)'} />\n              </Typography>\n            </Tooltip>\n          </Typography>\n          <Typography\n            display={'flex'}\n            flexDirection={'row'}\n            alignItems={'center'}\n            variant={'body1'}\n            component={'span'}\n            color={'var(--color-text-primary)'}\n          >\n            {executedAmount !== EmptyValueTag && (\n              <CoinIcons\n                size='small'\n                type={TokenType.single}\n                tokenIcon={[coinJson[sellSymbol], undefined]}\n              />\n            )}{' '}\n            {executedAmount}\n          </Typography>\n        </Typography>\n        <Typography\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n          component={'span'}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {t('labelVaultExecutedRate')}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {executedRate}\n          </Typography>\n        </Typography>\n        <Typography\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n          component={'span'}\n        >\n          <Typography\n            display={'flex'}\n            alignItems={'center'}\n            variant={'body1'}\n            component={'span'}\n            color={'var(--color-text-secondary)'}\n          >\n            {t('labelVaultConvertedAmount')}\n            <Tooltip title={<>{t('labelVaultConvertedAmountTip')}</>}>\n              <Typography marginLeft={0.5} display={'flex'} alignItems={'center'}>\n                <Info2Icon fontSize={'medium'} htmlColor={'var(--color-text-third)'} />\n              </Typography>\n            </Tooltip>\n          </Typography>\n          <Typography\n            display={'flex'}\n            flexDirection={'row'}\n            alignItems={'center'}\n            variant={'body1'}\n            component={'span'}\n            color={'var(--color-text-primary)'}\n          >\n            {convertedAmount !== EmptyValueTag && (\n              <CoinIcons\n                size='small'\n                type={TokenType.single}\n                tokenIcon={[coinJson[buySymbol], undefined]}\n              />\n            )}{' '}\n            {convertedAmount}\n          </Typography>\n        </Typography>\n\n        <Typography\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n          component={'span'}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {props.t('labelVaultPrice')}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {price}\n          </Typography>\n        </Typography>\n        <Typography\n          component={'span'}\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {props.t('labelVaultFee')}\n          </Typography>\n          <Typography\n            variant={'body1'}\n            component={'span'}\n            color={'var(--color-text-primary)'}\n            display={'inline-flex'}\n            alignItems={'center'}\n          >\n            {amountFee ? (\n              <>\n                <CoinIcons\n                  size='small'\n                  type={TokenType.single}\n                  tokenIcon={[coinJson[buySymbol], undefined]}\n                />\n                {amountFee + ' ' + buySymbol}\n              </>\n            ) : (\n              EmptyValueTag\n            )}\n          </Typography>\n        </Typography>\n\n        <Typography\n          component={'span'}\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {props.t('labelVaultTime')}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {moment(time).format(YEAR_DAY_MINUTE_FORMAT)}\n          </Typography>\n        </Typography>\n      </Box>\n      <>\n        {props.isPending && (\n          <Typography\n            marginTop={2}\n            variant={'body1'}\n            component={'span'}\n            padding={1}\n            display={'inline-flex'}\n            width={`calc(100% - ${9 * theme.unit}px)`}\n            bgcolor={hexToRGB(theme.colorBase.warning, 0.2)}\n            borderRadius={2}\n            color={'var(--color-text-primary)'}\n          >\n            <AlertIcon color={'warning'} sx={{ marginRight: 1 / 2 }} />\n            {props.t('labelVaultPendingDes')}\n          </Typography>\n        )}\n      </>\n    </>\n  )\n}\nexport const VaultTrade_Success = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.DoneIcon,\n    describe1: props.t('labelVaultTradeSuccess', {\n      symbol: props.symbol,\n      value: props.value,\n    }),\n    describe2: props.info && <TradeDes2 {...props} />,\n  }\n  return <VaultTradeBase showTitle={true} {...propsPatch} {...props} />\n}\nexport const VaultTrade_Failed = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.FailedIcon,\n    describe1: props.t('labelVaultTradeFailed', {\n      symbol: props.symbol,\n      value: props.value,\n    }),\n    describe2: (\n      <>\n        {props.info && <TradeDes2 {...props} />}\n        {props?.error && props.error?.message && (\n          <Typography variant={'body1'} component={'span'} color={'warning'}>\n            {props.error?.message}\n          </Typography>\n        )}\n      </>\n    ),\n  }\n  return <VaultTradeBase showTitle={true} {...propsPatch} {...props} />\n}\nexport const VaultTrade_In_Progress = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelVaultTradeInProgress', {\n      symbol: props.symbol,\n      value: props.value,\n    }),\n    describe2: props.info && <TradeDes2 {...props} isPending={true} />,\n  }\n  return <VaultTradeBase showTitle={true} {...propsPatch} {...props} />\n}\nconst JoinDes2 = (props: PanelProps) => {\n  const { isMobile, coinJson } = useSettings()\n  const theme = useTheme()\n\n  const { symbol, vSymbol, sum, status, type, time } = props?.info ?? {}\n  return (\n    <>\n      <Box\n        justifySelf={'stretch'}\n        display={'flex'}\n        flexDirection={'column'}\n        minWidth={'var(--modal-min-width)'}\n        justifyContent={'center'}\n        marginTop={2}\n        paddingX={isMobile ? 1 : 0}\n      >\n        <Typography\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n          component={'span'}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {props.t('labelVaultType')}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {type}\n          </Typography>\n        </Typography>\n        <Typography\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n          component={'span'}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {props.t('labelVaultStatus')}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {props.t(`labelVaultJoinStatus`, {\n              status,\n              percentage: '',\n            })}\n          </Typography>\n        </Typography>\n\n        <Typography\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n          component={'span'}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {props.t('labelVaultAmount')}\n          </Typography>\n          <Typography\n            variant={'body1'}\n            component={'span'}\n            color={'var(--color-text-primary)'}\n            display={'inline-flex'}\n            alignItems={'center'}\n          >\n            <CoinIcons\n              size='small'\n              type={TokenType.single}\n              tokenIcon={[coinJson[symbol], undefined]}\n            />\n            {sum + ' ' + mapSpecialTokenName(symbol)}\n          </Typography>\n        </Typography>\n        {/*<Typography*/}\n        {/*  display={'inline-flex'}*/}\n        {/*  justifyContent={'space-between'}*/}\n        {/*  marginTop={2}*/}\n        {/*  component={'span'}*/}\n        {/*>*/}\n        {/*  <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>*/}\n        {/*    {props.t('labelVaultReceive')}*/}\n        {/*  </Typography>*/}\n        {/*  <Typography*/}\n        {/*    variant={'body1'}*/}\n        {/*    component={'span'}*/}\n        {/*    color={'var(--color-text-primary)'}*/}\n        {/*    display={'inline-flex'}*/}\n        {/*    alignItems={'center'}*/}\n        {/*  >*/}\n        {/*    <CoinIcons*/}\n        {/*      size='small'*/}\n        {/*      type={TokenType.vault}*/}\n        {/*      tokenIcon={[coinJson[symbol], undefined]}*/}\n        {/*    />*/}\n        {/*    {sum + ' ' + symbol}*/}\n        {/*  </Typography>*/}\n        {/*</Typography>*/}\n\n        <Typography\n          component={'span'}\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {props.t('labelVaultTime')}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {moment(time).format(YEAR_DAY_MINUTE_FORMAT)}\n          </Typography>\n        </Typography>\n      </Box>\n      <>\n        {props.isPending && (\n          <Typography\n            marginTop={2}\n            variant={'body1'}\n            component={'span'}\n            padding={1}\n            display={'inline-flex'}\n            width={`calc(100% - ${9 * theme.unit}px)`}\n            bgcolor={hexToRGB(theme.colorBase.warning, 0.2)}\n            borderRadius={2}\n            color={'var(--color-text-primary)'}\n          >\n            <AlertIcon color={'warning'} sx={{ marginRight: 1 / 2 }} />\n            {props.t('labelVaultPendingDes')}\n          </Typography>\n        )}\n      </>\n    </>\n  )\n}\nexport const VaultJoin_Success = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.DoneIcon,\n    describe1: props.t('labelVaultJoinSuccess', {\n      symbol: props.symbol,\n      value: props.value,\n    }),\n    describe2: props.info && <JoinDes2 {...props} />,\n  }\n  return <VaultJoinBase title={props.info?.title} {...propsPatch} {...props} />\n}\nexport const VaultJoin_Failed = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.FailedIcon,\n    describe1: props.t('labelVaultJoinFailed', {\n      symbol: props.symbol,\n      value: props.value,\n    }),\n    describe2: (\n      <>\n        {props.info && <JoinDes2 {...props} />}\n        {props?.error && props.error?.message && (\n          <Typography\n            width={'var(--modal-min-width)'}\n            variant={'body1'}\n            component={'span'}\n            color={'warning'}\n          >\n            {props.error?.message}\n          </Typography>\n        )}\n      </>\n    ),\n  }\n  return <VaultJoinBase title={props.info?.title} {...propsPatch} {...props} />\n}\nexport const VaultJoin_In_Progress = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelVaultJoinInProgress', {\n      symbol: props.symbol,\n      value: props.value,\n    }),\n    describe2: props.info && <JoinDes2 {...props} isPending={true} />,\n  }\n  return <VaultJoinBase title={props.info?.title} {...propsPatch} {...props} />\n}\nexport const RedeemDes2 = (\n  props: PanelProps & {\n    isPending?: boolean\n    isNoWrap?: boolean\n    isForcedLiqudation: boolean\n  },\n) => {\n  const { isMobile, coinJson } = useSettings()\n  const theme = useTheme()\n  const { usdValue, usdDebt, usdEquity, profitPercent, profit, time, status, isForcedLiqudation } = props?.info ?? {}\n  const detail = React.useMemo(() => {\n    return (\n      <>\n        <Typography\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n          component={'span'}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {props.t('labelVaultExitType')}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {isForcedLiqudation\n              ? props.t('labelVaultExitTypeForcedLiquidation')\n              : props.t('labelVaultExitTypeClose')}\n          </Typography>\n        </Typography>\n        <Typography\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n          component={'span'}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {props.t('labelVaultExitStatusLabel')}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {props.t('labelVaultExitStatus', { status })}\n          </Typography>\n        </Typography>\n        <Typography\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n          component={'span'}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {props.t('labelVaultExitTotalBalance')}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {usdValue}\n          </Typography>\n        </Typography>\n        <Typography\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n          component={'span'}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {props.t('labelVaultExitTotalDebt')}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {usdDebt}\n          </Typography>\n        </Typography>\n        <Typography\n          component={'span'}\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {props.t('labelVaultExitTotalEquity')}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {usdEquity}\n          </Typography>\n        </Typography>\n        <Typography\n          component={'span'}\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {props.t('labelVaultExitProfit')}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {profit}\n          </Typography>\n        </Typography>\n        <Typography\n          component={'span'}\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {props.t('labelVaultExitProfitPercentage')}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {profitPercent}\n          </Typography>\n        </Typography>\n        <Typography\n          component={'span'}\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n          order={10}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {props.t('labelVaultTime')}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {moment(time).format(YEAR_DAY_MINUTE_FORMAT)}\n          </Typography>\n        </Typography>\n      </>\n    )\n  }, [usdValue, usdDebt, usdEquity, time, isMobile])\n  return props.isNoWrap ? (\n    <>{detail}</>\n  ) : (\n    <>\n      <Box\n        flexDirection={'column'}\n        display={'flex'}\n        alignItems={'stretch'}\n        justifyContent={'space-between'}\n        marginTop={2}\n        marginX={4}\n        borderRadius={1 / 2}\n        paddingY={1}\n        paddingX={isMobile ? 1 : 2}\n        minWidth={'var(--modal-min-width)'}\n        width={`calc(100% - 64px)`}\n        sx={{\n          background: 'var(--field-opacity)',\n        }}\n      >\n        {detail}\n      </Box>\n      {props.isPending && (\n        <Typography\n          marginTop={2}\n          variant={'body1'}\n          component={'span'}\n          padding={1}\n          display={'inline-flex'}\n          width={`calc(100% - ${9 * theme.unit}px)`}\n          bgcolor={hexToRGB(theme.colorBase.warning, 0.2)}\n          borderRadius={2}\n          color={'var(--color-text-primary)'}\n        >\n          <AlertIcon color={'warning'} sx={{ marginRight: 1 / 2 }} />\n          {props.t('labelVaultPendingDes')}\n        </Typography>\n      )}\n    </>\n  )\n}\nexport const VaultRedeem_Success = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.DoneIcon,\n    describe1: props.t('labelVaultRedeemSuccess', {\n      symbol: props.symbol,\n      value: props.value,\n    }),\n    describe2: props.info && <RedeemDes2 {...props} />,\n  }\n  return <VaultExitBase showTitle={true} {...propsPatch} {...props} />\n}\nexport const VaultRedeem_Failed = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.FailedIcon,\n    describe1: props.t('labelVaultRedeemFailed', {\n      symbol: props.symbol,\n      value: props.value,\n    }),\n    describe2: (\n      <>\n        {props.info && <RedeemDes2 {...props} />}\n        {props?.error && props.error?.message && (\n          <Typography\n            width={'var(--modal-min-width)'}\n            variant={'body1'}\n            component={'span'}\n            color={'warning'}\n          >\n            {props.error?.message}\n          </Typography>\n        )}\n      </>\n    ),\n  }\n  return <VaultExitBase showTitle={true} {...propsPatch} {...props} />\n}\nexport const VaultRedeem_In_Progress = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelVaultRedeemInProgress', {\n      symbol: props.symbol,\n      value: props.value,\n    }),\n    describe2: props.info && <RedeemDes2 {...props} isPending={true} />,\n  }\n  return <VaultExitBase showTitle={true} {...propsPatch} {...props} />\n}\n\nexport const BorrowDes2 = (\n  props: PanelProps & {\n    isPending?: boolean\n  },\n) => {\n  const { isMobile, coinJson } = useSettings()\n  const theme = useTheme()\n  const { sum, status, symbol, time } = props?.info ?? {}\n  return (\n    <>\n      <Box\n        justifySelf={'stretch'}\n        display={'flex'}\n        flexDirection={'column'}\n        minWidth={'var(--modal-min-width)'}\n        justifyContent={'center'}\n        marginTop={2}\n        paddingX={isMobile ? 1 : 0}\n      >\n        <Typography\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n          component={'span'}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {props.t('labelVaultBorrowTypeLabel')}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {props.t('labelVaultBorrow')}\n          </Typography>\n        </Typography>\n        <Typography\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n          component={'span'}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {props.t('labelVaultBorrowStatusLabel')}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {props.t('labelVaultBorrowStatus', { status })}\n          </Typography>\n        </Typography>\n\n        <Typography\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n          component={'span'}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {props.t('labelVaultBorrowAmountLabel')}\n          </Typography>\n          <Typography\n            variant={'body1'}\n            component={'span'}\n            color={'var(--color-text-primary)'}\n            display={'inline-flex'}\n            alignItems={'center'}\n          >\n            <CoinIcons\n              size='small'\n              type={TokenType.single}\n              tokenIcon={[coinJson[symbol], undefined]}\n            />\n            {sum + ' ' + symbol}\n          </Typography>\n        </Typography>\n        <Typography\n          component={'span'}\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {props.t('labelVaultTime')}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {moment(time ? time : new Date()).format(YEAR_DAY_MINUTE_FORMAT)}\n          </Typography>\n        </Typography>\n      </Box>\n      <>\n        {props.isPending && (\n          <Typography\n            marginTop={2}\n            variant={'body1'}\n            component={'span'}\n            padding={1}\n            display={'inline-flex'}\n            width={`calc(100% - ${9 * theme.unit}px)`}\n            bgcolor={hexToRGB(theme.colorBase.warning, 0.2)}\n            borderRadius={2}\n            color={'var(--color-text-primary)'}\n          >\n            <AlertIcon color={'warning'} sx={{ marginRight: 1 / 2 }} />\n            {props.t('labelVaultPendingDes')}\n          </Typography>\n        )}\n      </>\n    </>\n  )\n}\n\nexport const VaultBorrow_Success = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.DoneIcon,\n    describe1: props.t('labelVaultBorrowSuccess', {\n      symbol: props.symbol,\n      value: props.value,\n    }),\n    describe2: props.info && <BorrowDes2 {...props} />,\n  }\n  return <VaultBorrowBase showTitle={true} {...propsPatch} {...props} />\n}\nexport const VaultBorrow_Failed = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.FailedIcon,\n    describe1: props.t('labelVaultBorrowFailed', {\n      symbol: props.symbol,\n      value: props.value,\n    }),\n    describe2: (\n      <>\n        {props.info && <BorrowDes2 {...props} />}{' '}\n        {props?.error && props.error?.message && (\n          <Typography\n            width={'var(--modal-min-width)'}\n            variant={'body1'}\n            component={'span'}\n            color={'warning'}\n          >\n            {props.error?.message}\n          </Typography>\n        )}\n      </>\n    ),\n  }\n  return <VaultBorrowBase showTitle={true} {...propsPatch} {...props} />\n}\nexport const VaultBorrow_In_Progress = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelVaultBorrowInProgress', {\n      symbol: props.symbol,\n      value: props.value,\n    }),\n    describe2: props.info && <BorrowDes2 {...props} isPending={true} />,\n  }\n  return <VaultBorrowBase showTitle={true} {...propsPatch} {...props} />\n}\nexport const RepayDes2 = (\n  props: PanelProps & {\n    isPending?: boolean\n  },\n) => {\n  const { isMobile, coinJson } = useSettings()\n  const theme = useTheme()\n  const { status, sum, vSymbol, symbol, time } = props\n  // const { usdValue, usdDebt, usdEquity, forexMap } = props?.info ?? {}\n  return (\n    <>\n      <Box\n        justifySelf={'stretch'}\n        display={'flex'}\n        flexDirection={'column'}\n        minWidth={'var(--modal-min-width)'}\n        justifyContent={'center'}\n        marginTop={2}\n        paddingX={isMobile ? 1 : 0}\n      >\n        <Typography\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n          component={'span'}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {props.t('labelVaultRepayTypeLabel')}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {props.t('labelVaultRepayType')}\n          </Typography>\n        </Typography>\n        <Typography\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n          component={'span'}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {props.t('labelVaultRepayStatusLabel')}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {props.t('labelVaultRepayStatus', { status })}\n          </Typography>\n        </Typography>\n\n        <Typography\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n          component={'span'}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {props.t('labelVaultRepayTotalBalance')}\n          </Typography>\n          <Typography\n            variant={'body1'}\n            component={'span'}\n            color={'var(--color-text-primary)'}\n            display={'inline-flex'}\n            alignItems={'center'}\n          >\n            <CoinIcons\n              size='small'\n              type={TokenType.single}\n              tokenIcon={[coinJson[symbol!], undefined]}\n            />\n            {sum + ' ' + symbol}\n          </Typography>\n        </Typography>\n\n        <Typography\n          component={'span'}\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {props.t('labelVaultTime')}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {moment(time).format(YEAR_DAY_MINUTE_FORMAT)}\n          </Typography>\n        </Typography>\n      </Box>\n      {props.isPending && (\n        <Typography\n          marginTop={2}\n          variant={'body1'}\n          component={'span'}\n          padding={1}\n          display={'inline-flex'}\n          width={`calc(100% - ${9 * theme.unit}px)`}\n          bgcolor={hexToRGB(theme.colorBase.warning, 0.2)}\n          borderRadius={2}\n          color={'var(--color-text-primary)'}\n        >\n          <AlertIcon color={'warning'} sx={{ marginRight: 1 / 2 }} />\n          {props.t('labelVaultPendingDes')}\n        </Typography>\n      )}\n    </>\n  )\n}\n\nexport const VaultRepay_Success = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.DoneIcon,\n    describe1: props.t('labelVaultRepaySuccess', {\n      symbol: props.symbol,\n      value: props.value,\n    }),\n    describe2: props.info && <RepayDes2 {...props} />,\n  }\n  return <VaultRepayBase showTitle={true} {...propsPatch} {...props} />\n}\nexport const VaultRepay_Failed = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.FailedIcon,\n    describe1: props.t('labelVaultRepayFailed', {\n      symbol: props.symbol,\n      value: props.value,\n    }),\n    describe2: (\n      <>\n        {props.info && <RepayDes2 {...props} />}\n        {props?.error && props.error?.message && (\n          <Typography\n            width={'var(--modal-min-width)'}\n            variant={'body1'}\n            component={'span'}\n            color={'warning'}\n            marginTop={2}\n          >\n            {props.error?.message}\n          </Typography>\n        )}\n      </>\n    ),\n  }\n  return <VaultRepayBase showTitle={true} {...propsPatch} {...props} />\n}\nexport const VaultRepay_In_Progress = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelVaultRepayInProgress', {\n      symbol: props.symbol,\n      value: props.value,\n    }),\n    describe2: props.info && <RepayDes2 {...props} isPending={true} />,\n  }\n  return <VaultRepayBase showTitle={true} {...propsPatch} {...props} />\n}\n\nconst DustCollectorDes = (\n  props: PanelProps & {\n    isPending?: boolean\n  },\n) => {\n  const theme = useTheme()\n  const { status, totalValueInCurrency, convertedInUSDT, repaymentInUSDT, time, dusts } = props\n  const { t } = useTranslation()\n  return (\n    <>\n      <Box\n        justifySelf={'stretch'}\n        display={'flex'}\n        flexDirection={'column'}\n        width={'100%'}\n        justifyContent={'center'}\n        marginTop={2}\n        paddingX={3}\n      >\n        <Typography textAlign={'center'} variant='h4'>{repaymentInUSDT ? (repaymentInUSDT + ' USDT') : '--'} </Typography>\n        <Typography textAlign={'center'} mt={1} mb={2} color={'var(--color-text-third)'}>{totalValueInCurrency} </Typography>\n        <Box\n          borderRadius={'8px'}\n          bgcolor={'var(--color-box-secondary)'}\n          paddingX={2.5}\n          paddingY={1}\n        >\n          <SpaceBetweenBox\n            leftNode={<Typography color={'var(--color-text-third)'}>{t('labelVaultRepayment')}</Typography>}\n            rightNode={<Typography>{repaymentInUSDT ? (repaymentInUSDT + ' USDT') : '--'} </Typography>}\n            marginBottom={2}\n          />\n          <SpaceBetweenBox\n            leftNode={<Typography color={'var(--color-text-third)'}>{t('labelVaultTime')}</Typography>}\n            rightNode={<Typography>{moment(time).format(YEAR_DAY_MINUTE_FORMAT)}</Typography>}\n          />\n        </Box>\n        \n        <Box marginBottom={2} mt={2}>\n          {dusts && dusts.map((dust) => {\n            return (\n              <SpaceBetweenBox\n                paddingY={1.5}\n                paddingX={2}\n                marginBottom={1}\n                alignItems={'center'}\n                key={dust.symbol}\n                leftNode={\n                  <Box alignItems={'center'} display={'flex'}>\n                    <CoinIcons type={TokenType.single} tokenIcon={[dust.coinJSON]} />\n                    <Typography marginLeft={1}>{dust.symbol}</Typography>\n                  </Box>\n                }\n                rightNode={\n                  <Box display={'flex'} alignItems={'center'}>\n                    <Box marginRight={1}>\n                      <Typography textAlign={'right'}>{dust.amount}</Typography>\n                      <Typography\n                        color={'var(--color-text-secondary)'}\n                        textAlign={'right'}\n                        variant={'body2'}\n                      >\n                        {dust.valueInCurrency}\n                      </Typography>\n                    </Box>\n                  </Box>\n                }\n              />\n            )\n          })}\n        </Box>\n        {status === 'failed' && (\n          <Box\n            borderRadius={'8px'}\n            display={'flex'}\n            alignItems={'center'}\n            paddingX={2.5}\n            paddingY={1.5}\n            bgcolor={hexToRGB(theme.colorBase.error, 0.2)}\n          >\n            <ErrorIcon sx={{ color: 'var(--color-error)', marginRight: 1 / 2 }} />\n            <Typography>{t('labelVaultErrorOccurred')}</Typography>\n          </Box>\n        )}\n      </Box>\n    </>\n  )\n}\n\nexport const VaultDustCollector_Success = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.DoneIcon,\n    describe1: props.t('labelVaultRepaySuccess', {\n      symbol: props.symbol,\n      value: props.value,\n    }),\n    describe2: props.info && <DustCollectorDes status={'success'} {...props} />,\n  }\n  return <VaultDustCollectorBase showTitle={true} {...propsPatch} {...props} />\n}\nexport const VaultDustCollector_Failed = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.FailedIcon,\n    describe1: props.t('labelVaultRepayFailed', {\n      symbol: props.symbol,\n      value: props.value,\n    }),\n    describe2: (\n      <>\n        {props.info && <DustCollectorDes status={'failed'} {...props} />}\n        {props?.error && props.error?.message && (\n          <Typography\n            width={'var(--modal-min-width)'}\n            variant={'body1'}\n            component={'span'}\n            color={'warning'}\n            marginTop={2}\n          >\n            {props.error?.message}\n          </Typography>\n        )}\n      </>\n    ),\n  }\n  return <VaultDustCollectorBase showTitle={true} {...propsPatch} {...props} />\n}\nexport const VaultDustCollector_In_Progress = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelVaultRepayInProgress', {\n      symbol: props.symbol,\n      value: props.value,\n    }),\n    describe2: props.info && <DustCollectorDes status={'inProgress'} {...props} isPending={true} />,\n  }\n  return <VaultDustCollectorBase showTitle={true} {...propsPatch} {...props} />\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/ModalPanels/Withdraw.tsx",
    "content": "import { IconType, PanelProps, WithdrawBase } from './BasicPanel'\nimport { sanitize } from 'dompurify'\nimport { useSettings } from '../../../stores'\nimport { L1L2_NAME_DEFINED, MapChainId } from '@loopring-web/common-resources'\n\n// value symbol\nexport const Withdraw_WaitForAuth = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelWaitForAuth'),\n  }\n  return <WithdrawBase {...propsPatch} {...props} />\n}\n\n// value symbol\nexport const Withdraw_First_Method_Denied = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.RefuseIcon,\n    describe1: props.t('labelFirstSignDenied'),\n  }\n  return <WithdrawBase {...propsPatch} {...props} />\n}\n\n// value symbol\nexport const Withdraw_User_Denied = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.RefuseIcon,\n    describe1: props.t('labelSignDenied'),\n  }\n  return <WithdrawBase {...propsPatch} {...props} />\n}\n\n// value symbol\nexport const Withdraw_In_Progress = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelL2toL1InProgress'),\n  }\n  return <WithdrawBase {...propsPatch} {...props} />\n}\n\n// value symbol\nexport const Withdraw_Success = (props: PanelProps) => {\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n\n  const propsPatch = {\n    iconType: IconType.DoneIcon,\n    describe1: props.t('labelL2toL1Success', {\n      symbol: props.symbol,\n      value: props.value,\n      layer2: L1L2_NAME_DEFINED[network].layer2,\n      l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n      loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n      l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n      l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n      ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n    }),\n  }\n  return <WithdrawBase {...propsPatch} {...props} />\n}\n\n// value symbol\nexport const Withdraw_Failed = (props: PanelProps) => {\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const propsPatch = {\n    iconType: IconType.FailedIcon,\n    describe1: props.t('labelL2toL1Failed', {\n      symbol: props.symbol,\n      value: props.value,\n      layer2: L1L2_NAME_DEFINED[network].layer2,\n      l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n      loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n      l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n      l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n      ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n    }),\n  }\n  return <WithdrawBase {...propsPatch} {...props} />\n}\n\nexport const NFTWithdraw_WaitForAuth = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelWaitForAuth'),\n  }\n  return <WithdrawBase {...propsPatch} {...props} />\n}\n\nexport const NFTWithdraw_First_Method_Denied = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.RefuseIcon,\n    describe1: props.t('labelFirstSignDenied'),\n  }\n  return <WithdrawBase {...propsPatch} {...props} />\n}\n\nexport const NFTWithdraw_User_Denied = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.RefuseIcon,\n    describe1: props.t('labelSignDenied'),\n  }\n  return <WithdrawBase {...propsPatch} {...props} />\n}\n\nexport const NFTWithdraw_In_Progress = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelL2toL1InProgress'),\n  }\n  return <WithdrawBase {...propsPatch} {...props} />\n}\n\nexport const NFTWithdraw_Success = (props: PanelProps) => {\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const propsPatch = {\n    iconType: IconType.DoneIcon,\n    describe1: props.t('labelL2toL1Success', {\n      symbol: sanitize(props.symbol ?? 'NFT'),\n      value: props.value,\n      layer2: L1L2_NAME_DEFINED[network].layer2,\n      l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n      loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n      l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n      l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n      ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n    }),\n  }\n  return <WithdrawBase {...propsPatch} {...props} />\n}\n\nexport const NFTWithdraw_Failed = (props: PanelProps) => {\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const propsPatch = {\n    iconType: IconType.FailedIcon,\n    describe1: props.t('labelL2toL1Failed', {\n      symbol: sanitize(props.symbol ?? 'NFT'),\n      value: props.value,\n      layer2: L1L2_NAME_DEFINED[network].layer2,\n      l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n      loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n      l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n      l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n      ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n    }),\n  }\n  return <WithdrawBase {...propsPatch} {...props} />\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/ModalPanels/WithdrawPanel.tsx",
    "content": "import { WithTranslation, withTranslation } from 'react-i18next'\nimport { ModalBackButton, SwitchPanel, SwitchPanelProps } from '../../basic-lib'\nimport { WithdrawProps } from '../../tradePanel'\nimport { IBData, SoursURL, TRADE_TYPE } from '@loopring-web/common-resources'\nimport { TradeMenuList, useBasicTrade, WithdrawWrap } from '../../tradePanel/components'\nimport React from 'react'\nimport { cloneDeep } from 'lodash'\nimport { WithdrawConfirm } from '../../tradePanel/components/WithdrawConfirm'\nimport { ContactSelection } from '../../tradePanel/components/ContactSelection'\nimport { Box } from '@mui/material'\n// import { getAllContacts } from \"./TransferPanel\";\n\nexport const WithdrawPanel = withTranslation(['common', 'error'], {\n  withRef: true,\n})(\n  <T extends IBData<I>, I>({\n    type = TRADE_TYPE.TOKEN,\n    chargeFeeTokenList,\n    onWithdrawClick,\n    withdrawBtnStatus,\n    assetsData,\n    walletMap = {},\n    coinMap = {},\n    onBack,\n    isFromContact,\n    contact,\n    contacts,\n    ...rest\n  }: WithdrawProps<T, I> & WithTranslation & { assetsData: any[] }) => {\n    const { onChangeEvent, index, switchData } = useBasicTrade({\n      ...rest,\n      coinMap,\n      type,\n      walletMap,\n    })\n    // const _onChangeEvent = _.debounce((_index: 0 | 1, { to, tradeData }: SwitchData<T>) => {\n    //   onChangeEvent(_index, { to, tradeData })\n    // }, globalSetup.wait)\n\n    const [panelIndex, setPanelIndex] = React.useState(index + 1)\n    const handleConfirm = (index: number) => {\n      setPanelIndex(index)\n    }\n    // React.useEffect(() => {\n    //   return () => {\n    //     _onChangeEvent.cancel()\n    //   }\n    // }, [])\n    // const hanleConfirm = () => {};\n    React.useEffect(() => {\n      setPanelIndex(index + 1)\n    }, [index])\n\n    // LP token should not exist in withdraw panel for now\n    const getWalletMapWithoutLP = React.useCallback(() => {\n      const clonedWalletMap = cloneDeep(walletMap ?? {})\n      const keyList = Object.keys(clonedWalletMap)\n      keyList.forEach((key) => {\n        const [first] = key.split('-')\n        if (first === 'LP') {\n          delete clonedWalletMap[key]\n        }\n      })\n      return clonedWalletMap\n    }, [walletMap])\n\n    const confirmPanel = {\n      key: 'confirm',\n      element: React.useMemo(\n        () => (\n          <WithdrawConfirm\n            {...{\n              ...rest,\n              onWithdrawClick,\n              type,\n              tradeData: switchData.tradeData,\n              handleConfirm,\n            }}\n          />\n        ),\n        [onWithdrawClick, rest, switchData.tradeData, type],\n      ),\n      toolBarItem: (\n        <ModalBackButton\n          marginTop={0}\n          marginLeft={-2}\n          onBack={() => {\n            setPanelIndex(1)\n          }}\n          {...rest}\n        />\n      ),\n    }\n    const tradePanel = {\n      key: 'withdraw',\n      element: React.useMemo(\n        () => (\n          // @ts-ignore\n          <WithdrawWrap\n            key={'withdraw'}\n            {...{\n              ...rest,\n              type,\n              handleConfirm,\n              chargeFeeTokenList: chargeFeeTokenList ? chargeFeeTokenList : [],\n              tradeData: switchData.tradeData,\n              onChangeEvent,\n              coinMap,\n              disabled: rest.disabled,\n              // onWithdrawClick,\n              withdrawBtnStatus,\n              assetsData,\n              walletMap,\n\n              isFromContact,\n              contact,\n              onClickContact: () => {\n                setPanelIndex(3)\n              },\n            }}\n          />\n        ),\n        [\n          rest,\n          type,\n          chargeFeeTokenList,\n          switchData.tradeData,\n          onChangeEvent,\n          coinMap,\n          onWithdrawClick,\n          withdrawBtnStatus,\n          assetsData,\n          walletMap,\n        ],\n      ),\n      toolBarItem: React.useMemo(\n        () => (\n          <>\n            {onBack ? (\n              <ModalBackButton\n                marginTop={0}\n                marginLeft={-2}\n                onBack={() => {\n                  onBack()\n                }}\n                {...rest}\n              />\n            ) : (\n              <></>\n            )}\n          </>\n        ),\n        [onBack],\n      ),\n    }\n    const tokenSelectionPanel = {\n      key: 'tradeMenuList',\n      element: React.useMemo(\n        () => (\n          <TradeMenuList\n            {...{\n              nonZero: true,\n              sorted: true,\n              ...rest,\n              onChangeEvent,\n              coinMap,\n              selected: switchData.tradeData.belong,\n              tradeData: switchData.tradeData,\n              walletMap: getWalletMapWithoutLP(),\n              //oinMap\n            }}\n          />\n        ),\n        [switchData, rest, onChangeEvent, getWalletMapWithoutLP],\n      ),\n      toolBarItem: undefined,\n    }\n\n    const contactSelectionPanel = {\n      key: 'contactSelection',\n      element: React.useMemo(\n        () => (\n          <ContactSelection\n            key={'contactSelection'}\n            contacts={contacts}\n            onSelect={(address) => {\n              setPanelIndex(1)\n              rest.handleOnAddressChange(address, true)\n            }}\n            scrollHeight={rest.isToMyself ? '280px' : '480px'}\n          />\n        ),\n        [contacts],\n      ),\n      toolBarItem: React.useMemo(\n        () => (\n          <ModalBackButton\n            marginTop={0}\n            marginLeft={-2}\n            onBack={() => {\n              setPanelIndex(1)\n            }}\n            {...rest}\n          />\n        ),\n        [onBack],\n      ),\n    }\n\n    const props: SwitchPanelProps<string> = {\n      index: panelIndex, // show default show\n      panelList: [confirmPanel, tradePanel, tokenSelectionPanel, contactSelectionPanel],\n    }\n    return type == TRADE_TYPE.TOKEN && !switchData.tradeData?.belong ? (\n      <Box\n        display={'flex'}\n        height={'var(--min-height)'}\n        width={'var(--modal-width)'}\n        justifyContent={'center'}\n        flexDirection={'column'}\n        alignItems={'center'}\n      >\n        <img\n          className='loading-gif'\n          alt={'loading'}\n          width='60'\n          src={`${SoursURL}images/loading-line.gif`}\n        />\n      </Box>\n    ) : (\n      <SwitchPanel {...{ ...rest, ...props }} />\n    )\n  },\n) as <T, I>(props: WithdrawProps<T, I> & React.RefAttributes<any>) => JSX.Element\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/ModalPanels/index.ts",
    "content": "export * from './Interface'\nexport * from './AccountBase'\n\nexport * from './CreateAccount'\nexport * from './Deposit'\nexport * from './DepositNFT'\nexport * from './Transfer'\nexport * from './Withdraw'\nexport * from './Dual'\nexport {BridgePanel} from './BridgePanel'\n\nexport * from './UpdateAccount'\nexport * from './UnlockAccount'\nexport * from './ExportAccount'\n\nexport * from './QRAddressPanel'\nexport * from './NoAccount'\nexport * from './HadAccount'\nexport * from './ModalAccount'\nexport * from './Connect'\n\nexport * from '../../tradePanel/Deposit/DepositGroup'\nexport * from './TransferPanel'\nexport * from './WithdrawPanel'\nexport * from './DepositPanel'\nexport * from './MintNFT'\nexport * from './DeployNFT'\nexport * from './AddAsset'\nexport * from './SendAsset'\nexport * from './SendNFTAsset'\nexport * from './CheckActiveStatus'\nexport * from './CheckImportCollection'\nexport * from './ForceWithdraw'\nexport * from './ForceWithdrawPanel'\nexport * from './ThirdPanelReturn'\nexport * from './CreateRedPacketPanel'\n\nexport * from './ClaimWithdraw'\nexport * from './RedPacket'\nexport * from './FeeSelect'\nexport * from './EditContact'\nexport { IconType, BasicPanel } from './BasicPanel'\nexport * from './Vault'\nexport {TransferToTaikoAccountModal} from './TransferToTaikoAccountPanel'\nexport {\n  Transfer_To_Taiko_WaitForAuth,\n  Transfer_To_Taiko_First_Method_Denied,\n  Transfer_To_Taiko_User_Denied,\n  Transfer_To_Taiko_In_Progress,\n  Transfer_To_Taiko_Success,\n  Transfer_To_Taiko_banxa_confirm,\n  Transfer_To_Taiko_Failed\n} from './TransferToTaikoAccount'\nexport { \n  Coinbase_Smart_Wallet_Password_Intro,\n  Coinbase_Smart_Wallet_Password_Set,\n  Coinbase_Smart_Wallet_Password_Set_Confirm,\n  Coinbase_Smart_Wallet_Password_Input,\n  Coinbase_Smart_Wallet_Password_Forget_Password_Confirm,\n  Coinbase_Smart_Wallet_Password_Forget_Password\n} from './CoinbaseSmartWalletModal'\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/QRCode/Interface.ts",
    "content": "import { ReactNode } from 'react'\n\nexport interface GatewayItemQRCode {\n  key: string\n  imgSrc: string\n  handleSelect?: (event: React.MouseEvent) => void\n}\n\n/**\n * @param handleSelect default hanldeSelect, if item have no private handleSelect function\n */\nexport interface QRCodePanelProps {\n  title?: string | JSX.Element\n  description?: string | JSX.Element\n}\n\nexport type ModalQRCodeProps = QRCodePanelProps & {\n  open: boolean\n  className?: string\n  onClose: {\n    bivarianceHack(event: {}, reason: 'backdropClick' | 'escapeKeyDown'): void\n  }['bivarianceHack']\n}\nexport type GuardianModalProps = {\n  open: boolean\n  onClose: {\n    bivarianceHack(event: {}, reason: 'backdropClick' | 'escapeKeyDown'): void\n  }['bivarianceHack']\n  title: ReactNode\n  body: ReactNode\n  onBack?: () => void\n  showBackButton?: boolean\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/QRCode/QRCode.tsx",
    "content": "import { WithTranslation, withTranslation } from 'react-i18next'\nimport styled from '@emotion/styled'\nimport { Box, BoxProps, Modal, Typography } from '@mui/material'\nimport { ModalQRCodeProps, QRCodePanelProps } from './Interface'\nimport { ModalCloseButton } from '../../basic-lib'\nimport QRCodeStyling, { Options } from 'qr-code-styling'\nimport { SoursURL } from '@loopring-web/common-resources'\nimport React from 'react'\n\nconst ModalContentStyled = styled(Box)`\n  & > div {\n    background: var(--color-pop-bg);\n    position: absolute;\n    top: 50%;\n    left: 50%;\n    transform: translate(-50%, -50%);\n    width: var(--modal-width);\n  }\n  &.guardianPop .content {\n    padding-top: ${({ theme }) => 5 * theme.unit}px;\n    border-radius: ${({ theme }) => theme.unit}px;\n  }\n`\n\nexport type QCodeProps = {\n  url: string\n  size?: number\n  fgColor1?: string\n  fgColor2?: string\n  bgColor?: string\n  imageInfo?: { imageSrc?: string; size?: number }\n}\nconst qrCode = new QRCodeStyling()\n\nexport const QRCode = ({\n  size = 160,\n  fgColor1 = 'var(--color-primary)',\n  fgColor2 = '#000',\n  bgColor = '#fff',\n  url = 'https://exchange.loopring.io/',\n  imageInfo = {\n    imageSrc: `${SoursURL + 'svg/loopring.svg'}`,\n    size: 40,\n  },\n}: QCodeProps & QRCodePanelProps) => {\n  const ref = React.useRef()\n\n  React.useEffect(() => {\n    if (url) {\n      qrCode.update({\n        type: 'svg',\n        data: url,\n        width: size,\n        height: size,\n        image: imageInfo.imageSrc,\n        dotsOptions: {\n          gradient: {\n            rotation: 45,\n            type: 'linear',\n            colorStops: [\n              {\n                offset: 0,\n                color: fgColor1,\n              },\n              {\n                offset: 1,\n                color: fgColor2,\n              },\n            ],\n          },\n          type: 'dots',\n        },\n        backgroundOptions: {\n          color: bgColor,\n        },\n        imageOptions: {\n          crossOrigin: 'anonymous',\n          margin: 8,\n        },\n        cornersSquareOptions: {\n          type: 'extra-rounded',\n        },\n        cornersDotOptions: {\n          type: 'square',\n        },\n      })\n      if (ref.current) {\n        const boxRef = ref.current as any\n        while (boxRef.hasChildNodes()) {\n          boxRef.removeChild(boxRef.lastChild)\n        }\n        qrCode.append(ref.current)\n      }\n    }\n  }, [url])\n  return <Box ref={ref} />\n}\n\n\nexport const QRCodeV2 = ({ options, ...rest }: { options: Options } & BoxProps) => {\n  const ref = React.useRef<HTMLDivElement>(null)\n  React.useEffect(() => {\n    if (ref.current) {\n      if (ref.current.children[0]) {\n        ref.current.removeChild(ref.current.children[0])\n      }\n      const qrCode = new QRCodeStyling(options)\n      qrCode.append(ref.current)\n    }\n  }, [options, ref])\n  return <Box ref={ref} {...rest} />\n}\n\nexport const QRCodePanel = ({\n  title,\n  description,\n  ...rest\n}: // imageSettings = {\n//   height: 80,\n//   width: 80,\n//   src: `${SoursURL + \"svg/loopring.svg\"}`,\n// },\n// handleClick\nQCodeProps & QRCodePanelProps) => {\n  if (rest.url === undefined) {\n    rest.url = ''\n  }\n  return (\n    <Box\n      display={'flex'}\n      justifyContent={'space-between'}\n      alignItems={'center'}\n      flexDirection={'column'}\n    >\n      {title && (\n        <Typography variant={'h4'} component='h3' className='modalTitle' marginBottom={3}>\n          {title}\n        </Typography>\n      )}\n      <QRCode {...rest} />\n      {description && (\n        <Typography variant={'body1'} marginBottom={3} marginTop={1}>\n          {description}\n        </Typography>\n      )}\n    </Box>\n  )\n}\n\nexport const ModalQRCode = withTranslation('common')(\n  ({ onClose, open, t, ...rest }: QCodeProps & ModalQRCodeProps & WithTranslation) => {\n    return (\n      <Modal\n        open={open}\n        onClose={onClose}\n        aria-labelledby='modal-modal-title'\n        aria-describedby='modal-modal-description'\n      >\n        <ModalContentStyled\n          display={'flex'}\n          alignItems={'center'}\n          justifyContent={'center'}\n          className={rest?.className}\n        >\n          <Box\n            className={'content'}\n            paddingTop={3}\n            paddingBottom={3}\n            display={'flex'}\n            flexDirection={'column'}\n          >\n            <ModalCloseButton onClose={onClose} {...{ ...rest, t }} />\n            <QRCodePanel {...{ ...rest, t }} />\n          </Box>\n        </ModalContentStyled>\n      </Modal>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/QRCode/index.ts",
    "content": "export * from './QRCode'\nexport * from './Interface'\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/RedPacketPanels/Interface.ts",
    "content": "export enum RedPacketViewStep {\n  QRCodePanel,\n  OpenPanel,\n  DetailPanel,\n  TimeOutPanel,\n  PreparePanel,\n  OpenedPanel,\n  RedPacketClock,\n  BlindBoxDetail,\n  Loading,\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/RedPacketPanels/RedPacketModal.tsx",
    "content": "import { WithTranslation, withTranslation } from 'react-i18next'\nimport { Box, Modal } from '@mui/material'\nimport {\n  ModalBackButton,\n  ModalCloseButton,\n  ModalRedPacketProps,\n  RedPacketViewStep,\n} from '../../../index'\nimport SwipeableViews from 'react-swipeable-views'\nimport { CloseRedPacketIcon } from '@loopring-web/common-resources'\nimport styled from '@emotion/styled'\nimport { useTheme } from '@emotion/react'\nimport { isEmpty } from 'lodash'\n\nconst BoxStyle = styled(Box)`\n  .redPacketClose {\n    svg {\n      height: var(--btn-icon-size);\n      width: var(--btn-icon-size);\n    }\n\n    //transform: translateY(-50%) translateX(-50%);\n    //left: 50%;\n    top: ${({ theme }) => 3.5 * theme.unit}px;\n    right: ${({ theme }) => 16 * theme.unit}px;\n  }\n`\n\nexport const ModalRedPacket = withTranslation('common', { withRef: true })(\n  ({\n    // t,\n    open,\n    onClose,\n    step,\n    onBack,\n    panelList,\n    style,\n    ...rest\n  }: ModalRedPacketProps & WithTranslation) => {\n    const theme = useTheme()\n    return (\n      <Modal\n        open={open}\n        onClose={onClose}\n        disableEnforceFocus\n        aria-labelledby='modal-modal-title'\n        aria-describedby='modal-modal-description'\n      >\n        <BoxStyle\n          // width={\"100%\"}\n          // height={`calc(100vh - ${HEADER_HEIGHT}px)`}\n          position={'absolute'}\n          overflow={'scroll'}\n          display={'flex'}\n          top='50%'\n          left='50%'\n          sx={{\n            transform: 'translateY(-50%) translateX(-50%)',\n          }}\n        >\n          {/* hide close button if view redpacket view not rendered */}\n          {step !== RedPacketViewStep.Loading && !isEmpty(panelList[step].view.props) && (\n            <ModalCloseButton\n              closeIcon={<CloseRedPacketIcon htmlColor={'var(--color-text-button)'} />}\n              onClose={onClose}\n              className={'redPacketClose'}\n              {...rest}\n            />\n          )}\n          {onBack ? <ModalBackButton onBack={onBack} {...rest} /> : <></>}\n          <SwipeableViews\n            axis={theme.direction === 'rtl' ? 'x-reverse' : 'x'}\n            index={step}\n            style={{\n              boxShadow: '24',\n              marginTop: 4 * theme.unit,\n              marginLeft: 4 * theme.unit,\n              marginRight: 4 * theme.unit,\n            }}\n          >\n            {panelList.map((panel, index) => {\n              return (\n                <Box\n                  flexDirection={'column'}\n                  flex={1}\n                  display={'flex'}\n                  key={index}\n                  justifyContent={'center'}\n                  alignItems={'center'}\n                >\n                  {panel.view}\n                </Box>\n              )\n            })}\n          </SwipeableViews>\n        </BoxStyle>\n      </Modal>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/RedPacketPanels/index.ts",
    "content": "export * from './RedPacketModal'\nexport * from './Interface'\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/Vault/VaultBorrowPanel.tsx",
    "content": "import {\n  IBData,\n  SoursURL,\n  TokenType,\n  TRADE_TYPE,\n  VaultBorrowData,\n} from '@loopring-web/common-resources'\nimport {\n  CountDownIcon,\n  SwitchPanel,\n  SwitchPanelProps,\n  VaultBorrowProps,\n} from '@loopring-web/component-lib'\nimport React from 'react'\nimport { Box, Typography } from '@mui/material'\nimport { TradeMenuList, useBasicTrade, VaultBorrowWrap } from '../../tradePanel/components'\nimport { useTranslation } from 'react-i18next'\n\nexport const VaultBorrowPanel = <T extends IBData<I>, V extends VaultBorrowData<T>, I>({\n  // onVaultBorrowClick,\n  walletMap = {},\n  coinMap = {},\n  _width,\n  type = TRADE_TYPE.TOKEN,\n  onRefreshData,\n  ...rest\n}: VaultBorrowProps<T, I, V>) => {\n  const { t, i18n } = useTranslation()\n  const [panelIndex, setPanelIndex] = React.useState(0)\n  const onChangeEvent = (index, data) => {\n    if (index !== panelIndex) {\n      if (data.tradeData.belong !== rest.tradeData.belong) {\n        rest.handlePanelEvent && rest.handlePanelEvent(data, \"Tobutton\")\n      }\n      setPanelIndex(index)\n    } else {\n      rest.handlePanelEvent && rest.handlePanelEvent(data, \"Tobutton\")\n    }\n  }\n\n  const props: SwitchPanelProps<'tradeMenuList' | 'trade' | 'confirm'> = {\n    index: panelIndex, // show default show\n    panelList: [\n      {\n        key: 'trade',\n        element: React.useMemo(\n          () => (\n            // @ts-ignore\n            <VaultBorrowWrap\n              key={'trade'}\n              {...{\n                ...rest,\n                type,\n                // tradeData: switchData.tradeData,\n                onChangeEvent,\n                disabled: !!rest.disabled,\n                walletMap,\n                coinMap,\n              }}\n            />\n          ),\n          [rest, onChangeEvent, walletMap, coinMap],\n        ),\n        toolBarItem: React.useMemo(\n          () => (\n            <>\n              <Typography\n                display={'inline-block'}\n                marginLeft={2}\n                component={'span'}\n                visibility={'hidden'}\n                height={0}\n                width={0}\n              >\n                <CountDownIcon onRefreshData={onRefreshData} />\n              </Typography>\n            </>\n          ),\n          [],\n        ),\n      },\n      {\n        key: 'tradeMenuList',\n        element: React.useMemo(\n          () => (\n            // @ts-ignore\n            <TradeMenuList\n              {...{\n                nonZero: false,\n                sorted: true,\n                t,\n                ...rest,\n                onChangeEvent,\n                //rest.walletMap,\n                selected: rest.tradeData?.belong,\n                tradeData: rest.tradeData,\n                walletMap,\n                coinMap,\n                tokenType: TokenType.vault,\n                //oinMap\n              }}\n            />\n          ),\n          [rest, walletMap, coinMap],\n        ),\n        toolBarItem: undefined,\n      },\n    ],\n  }\n  return !rest.tradeData?.belong ? (\n    <Box\n      height={'var(--min-height)'}\n      display={'flex'}\n      justifyContent={'center'}\n      flexDirection={'column'}\n      alignItems={'center'}\n    >\n      <img\n        className='loading-gif'\n        alt={'loading'}\n        width='60'\n        src={`${SoursURL}images/loading-line.gif`}\n      />\n    </Box>\n  ) : (\n    <SwitchPanel\n      className={'vaultBorrow'}\n      _width={'var(--modal-width)'}\n      {...{ ...rest, i18n, t, tReady: true, ...props }}\n    />\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/Vault/VaultExitPanel.tsx",
    "content": "import { useSettings } from '../../../stores'\nimport { L1L2_NAME_DEFINED, MapChainId, TradeBtnStatus } from '@loopring-web/common-resources'\nimport { Box, Divider, Typography, IconButton } from '@mui/material'\nimport { Trans, useTranslation } from 'react-i18next'\nimport { Button } from '../../basic-lib'\nimport React from 'react'\nimport { VaultExitBaseProps } from '../../tradePanel'\nimport CloseIcon from '@mui/icons-material/Close'\n\nexport const VaultExitPanel = ({\n  onSubmitClick,\n  onClose,\n  btnStatus,\n  disabled,\n  confirmLabel = 'labelVaultConfirm',\n  cancelLabel = 'labelVaultCancel',\n}: VaultExitBaseProps) => {\n  const { t } = useTranslation()\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const getDisabled = React.useMemo(() => {\n    return disabled || btnStatus === TradeBtnStatus.DISABLED\n  }, [btnStatus, disabled])\n  const label = React.useMemo(() => {\n    if (confirmLabel) {\n      const key = confirmLabel.split('|')\n      return t(\n        key[0],\n        key && key[1]\n          ? {\n              arg: key[1].toString(),\n              l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n              l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n              l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n              ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n            }\n          : {\n              l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n              l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n              l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n              ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n            },\n      )\n    } else {\n      return t(`labelVaultConfirm`, {\n        l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n        loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n        l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n        l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n        ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n      })\n    }\n  }, [confirmLabel])\n  return (\n    <>\n      <Box sx={{\n        position: 'relative',\n        width: 'var(--modal-width)',\n        maxWidth: '450px',\n        bgcolor: 'var(--color-global-bg)',\n        border: 'none',\n        boxShadow: 24,\n        px: 4,\n        py: 5,\n        borderRadius: 2,\n      }}>\n\n        <Typography variant='h4' component='h2' textAlign='center' mb={4}>\n          Settle\n        </Typography>\n\n        <Typography mb={3}>\n          You can only settle your account after all existing positions have been closed.\n        </Typography>\n\n        <Typography mb={3} variant='body1' color={'var(--color-text-secondary)'}>\n          · If there is a loss (due to an unprofitable trade or interest payments), a portion of\n          your collateral may be used to cover the deficit. In this case, only the remaining\n          collateral will be available for withdrawal from Portal.\n        </Typography>\n\n        <Typography color={'var(--color-text-secondary)'} variant='body1'>\n          · If your trades are profitable, your full collateral will be available for withdrawal,\n          and any profits will be credited to your Loopring DeFi account accordingly.\n        </Typography>\n\n        <Box display='flex' gap={2} mt={4}>\n          <Button variant='outlined' sx={{ height: '40px' }} fullWidth onClick={onClose}>\n            Cancel\n          </Button>\n\n          <Button \n            variant='contained'\n            fullWidth\n            onClick={onSubmitClick}\n            loading={!getDisabled && btnStatus === TradeBtnStatus.LOADING ? 'true' : 'false'}\n            disabled={\n              getDisabled ||\n              btnStatus === TradeBtnStatus.DISABLED ||\n              btnStatus === TradeBtnStatus.LOADING\n            }\n          >\n            Settle\n          </Button>\n        </Box>\n      </Box>\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/Vault/VaultJoinPanel.tsx",
    "content": "import { IBData, SoursURL, TRADE_TYPE, VaultJoinData, VaultLoanType } from '@loopring-web/common-resources'\nimport {\n  CountDownIcon,\n  Modal,\n  SwitchPanel,\n  SwitchPanelProps,\n  useSettings,\n  VaultJoinProps,\n} from '@loopring-web/component-lib'\nimport React from 'react'\nimport { Box, Typography, Divider, Tabs, Tab } from '@mui/material'\nimport { TradeMenuList, VaultJoinWrap } from '../../tradePanel/components'\nimport { useTranslation } from 'react-i18next'\nimport { useTheme } from '@emotion/react'\n\nexport const VaultJoinPanelModal = <T extends IBData<I>, V extends VaultJoinData<I>, I>({\n  onSubmitClick,\n  btnStatus,\n  isActiveAccount,\n  walletMap = {},\n  coinMap = {},\n  onRefreshData,\n  _width,\n  onToggleAddRedeem,\n  isAddOrRedeem,\n  panelIndex,\n  handleConfirm,\n  basicTrade: {onChangeEvent, switchData},\n  modalOpen,\n  onCloseModal,\n  ...rest\n}: VaultJoinProps<T, I, V>) => {\n  const isMobile = useSettings().isMobile\n  const { t, i18n } = useTranslation()\n  const theme = useTheme()\n\n  const props: SwitchPanelProps<'tradeMenuList' | 'trade' | 'confirm'> = {\n    index: panelIndex, // show default show\n    panelList: [\n      {\n        key: 'trade',\n        // onBack,\n        element: React.useMemo(\n          () => (\n            // @ts-ignore\n            <VaultJoinWrap\n              key={'trade'}\n              {...{\n                ...rest,\n                isActiveAccount,\n                tradeData: switchData.tradeData,\n                onChangeEvent,\n                disabled: !!rest.disabled,\n                handleConfirm,\n                onSubmitClick,\n                btnStatus,\n                walletMap,\n                coinMap,\n                isAddOrRedeem,\n              }}\n            />\n          ),\n          [\n            rest,\n            switchData.tradeData,\n            onChangeEvent,\n            onSubmitClick,\n            // onDepositClick,\n            btnStatus,\n            walletMap,\n            coinMap,\n            isAddOrRedeem,\n          ],\n        ),\n        toolBarItem: React.useMemo(\n          () => (\n            <>\n              <Box sx={{ height: '55px' }} className={'toolbarTitle'}>\n                {isActiveAccount ? (\n                  <Typography marginBottom={1.5} variant={'h5'} component={'span'} paddingX={3}>\n                    Supply Collateral\n                  </Typography>\n                ) : (\n                  <Tabs\n                    value={isAddOrRedeem}\n                    onChange={(_, value) => {\n                      onToggleAddRedeem(value)\n                    }}\n                    sx={{marginLeft: 1.5}}\n                  >\n                    <Tab label={'Supply'} value={'Add'} />\n                    <Tab label={'Reduce'} value={'Redeem'} />\n                  </Tabs>\n                )}\n\n                <Typography\n                  display={'inline-block'}\n                  marginLeft={2}\n                  component={'span'}\n                  visibility={'hidden'}\n                  height={0}\n                  width={0}\n                >\n                  <CountDownIcon onRefreshData={onRefreshData} />\n                </Typography>\n                <Divider style={{ marginTop: '2px' }}/>\n              </Box>\n            </>\n          ),\n          [isAddOrRedeem, isActiveAccount],\n        ),\n      },\n      {\n        key: 'tradeMenuList',\n        element: React.useMemo(\n          () => (\n            // @ts-ignore\n            <TradeMenuList\n              {...{\n                nonZero: false,\n                sorted: true,\n                t,\n                ...rest,\n                onChangeEvent,\n                //rest.walletMap,\n                selected: switchData.tradeData.belong,\n                tradeData: switchData.tradeData,\n                walletMap,\n                coinMap,\n                //oinMap\n              }}\n            />\n          ),\n          [rest, onChangeEvent, switchData.tradeData, walletMap, coinMap],\n        ),\n        toolBarItem: undefined,\n      },\n    ],\n  }\n  return (\n    <Modal\n      contentClassName={'vault-wrap'}\n      open={modalOpen}\n      onClose={onCloseModal}\n      content={\n        !switchData.tradeData?.belong ? (\n          <Box\n            height={'580px'}\n            width={'var(--modal-width)'}\n            display={'flex'}\n            justifyContent={'center'}\n            flexDirection={'column'}\n            alignItems={'center'}\n          >\n            <img\n              className='loading-gif'\n              alt={'loading'}\n              width='60'\n              src={`${SoursURL}images/loading-line.gif`}\n            />\n          </Box>\n        ) : isMobile ? (\n          <Box width={'var(--modal-width)'}>\n            <SwitchPanel\n              _width={`calc(var(--modal-width) - ${(theme.unit * 5) / 2}px)`}\n              _height={'auto'}\n              {...{ ...rest, i18n, t, tReady: true, ...props }}\n            />\n          </Box>\n        ) : (\n          <SwitchPanel\n            _width={`calc(var(--modal-width) - ${(theme.unit * 5) / 2}px)`}\n            _height={'auto'}\n            {...{ ...rest, i18n, t, tReady: true, ...props }}\n          />\n        )\n      }\n    />\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/Vault/VaultLoanPanel.tsx",
    "content": "import { Box, BoxProps, Divider, Tab, Tabs, Toolbar, Typography } from '@mui/material'\nimport styled from '@emotion/styled'\nimport { boxLiner, toolBarPanel } from '../../styled'\nimport { useTranslation, WithTranslation } from 'react-i18next'\nimport { useSettings } from '../../../stores'\nimport { IBData, VaultBorrowData, VaultLoanType } from '@loopring-web/common-resources'\nimport { VaultBorrowPanel } from './VaultBorrowPanel'\nimport { VaultRepayPanel } from './VaultRepayPanel'\nimport { useSystem } from '@loopring-web/core'\nimport { VaultBorrowProps, VaultRepayWrapProps } from '../../tradePanel'\n\nexport type VaultLoanProps<T, B, I> = {\n  vaultLoanType: VaultLoanType\n  handleTabChange: (index: VaultLoanType) => void\n  vaultRepayProps: VaultRepayWrapProps<T, B, I>\n  vaultBorrowProps: VaultBorrowProps<T, B, I>\n}\nconst TabPanelBtn = ({ t, value, handleChange }: WithTranslation & any) => {\n  return (\n    <Tabs value={value} onChange={handleChange} aria-label='Amm Method Tab'>\n      <Tab label={t('labelVaultBorrow')} value={VaultLoanType.Borrow} />\n      <Tab label={t('labelVaultRepay')} value={VaultLoanType.Repay} />\n    </Tabs>\n  )\n}\n\nconst WrapStyle = styled(Box)<\n  BoxProps & {\n    _height?: number | string\n    _width?: number | string\n    isMobile: boolean\n  }\n>`\n  ${({ _width, isMobile }) =>\n    isMobile\n      ? `width:100%;height:auto;`\n      : `\n      width: ${\n        typeof _width === 'string'\n          ? _width\n          : typeof _width === 'number'\n          ? _width + 'px'\n          : `var(--swap-box-width)`\n      };\n      height: auto;`}\n  ${({ theme }) => boxLiner({ theme })}\n  ${({ theme }) => toolBarPanel({ theme })}\n  border-radius: ${({ theme }) => theme.unit}px;\n\n  .trade-panel .menu-panel > div {\n    padding: 8px 0px;\n  }\n\n  .trade-panel .coinInput-wrap {\n    background: var(--field-opacity);\n  }\n\n  .MuiToolbar-root {\n    justify-content: space-between;\n  }\n\n  .vaultRepay {\n    .MuiListItem-root {\n      .MuiListItemText-root {\n        align-items: center;\n      }\n\n      width: auto;\n      padding: ${({ theme }) => theme.unit}px ${({ theme }) => theme.unit / 2}px\n        ${({ theme }) => theme.unit}px ${({ theme }) => 2 * theme.unit}px;\n      margin: ${({ theme }) => theme.unit}px ${({ theme }) => 0 * theme.unit}px;\n      ${({ theme }) =>\n        theme.border.defaultFrame({\n          d_W: 1,\n          c_key: 'var(--color-border)',\n        })};\n\n      &:hover {\n        ${({ theme }) =>\n          theme.border.defaultFrame({\n            d_W: 1,\n            c_key: 'var(--color-border-select)',\n          })};\n\n        .MuiSvgIcon-root {\n          fill: var(--color-primary);\n        }\n      }\n    }\n  }\n` as (\n  props: BoxProps & {\n    _height?: number | string\n    _width?: number | string\n    isMobile: boolean\n  },\n) => JSX.Element\nexport const VaultLoanPanel = <T extends IBData<I>, V extends VaultBorrowData<I>, I>({\n  handleTabChange,\n  vaultLoanType,\n  vaultRepayProps,\n  vaultBorrowProps,\n}: VaultLoanProps<T, V, I>) => {\n  const { t } = useTranslation()\n  const { forexMap } = useSystem()\n  const {\n    // defaultNetwork,\n    isMobile,\n  } = useSettings()\n  return (\n    <WrapStyle\n      _width={'var(--modal-width)'}\n      display={'flex'}\n      className={'trade-panel container valut-load'}\n      isMobile={isMobile}\n      paddingTop={'var(--toolbar-row-padding)'}\n      paddingBottom={3}\n      flexDirection={'column'}\n      flexWrap={'nowrap'}\n    >\n      <Toolbar\n        className={'large'}\n        variant={'regular'}\n        sx={{ minHeight: 'var(--header-submenu-item-height) !important' }}\n      >\n        <Box alignSelf={'center'} justifyContent={'flex-start'} display={'flex'} marginLeft={-2}>\n          <Typography variant='h5' ml={2}>Repay</Typography>\n        </Box>\n      </Toolbar>\n      <Divider style={{ marginTop: '-1px' }} />\n      <Box flex={1} className={'trade-panel'} marginTop={1}>\n        {vaultLoanType === VaultLoanType.Borrow && (\n          <Box\n            display={'flex'}\n            justifyContent={'space-evenly'}\n            alignItems={'stretch'}\n            height={'100%'}\n          >\n            <VaultBorrowPanel\n              {...{\n                ...(vaultBorrowProps as any),\n                t,\n                _height: 400,\n              }}\n            />\n          </Box>\n        )}\n        {vaultLoanType === VaultLoanType.Repay && (\n          <Box\n            display={'flex'}\n            justifyContent={'space-evenly'}\n            alignItems={'stretch'}\n            height={'100%'}\n          >\n            <VaultRepayPanel\n              {...{ ...(vaultRepayProps as any), t, _height: 400 }}\n              forexMap={forexMap}\n            />\n          </Box>\n        )}\n      </Box>\n    </WrapStyle>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/Vault/VaultRepayPanel.tsx",
    "content": "import {\n  BackIcon,\n  CurrencyToTag,\n  EmptyValueTag,\n  getValuePrecisionThousand,\n  IBData,\n  PriceTag,\n  TokenType,\n  TRADE_TYPE,\n  VaultRepayData,\n} from '@loopring-web/common-resources'\nimport {\n  EmptyDefault,\n  SwitchPanel,\n  SwitchPanelProps,\n  useSettings,\n  VaultRepayProps,\n} from '@loopring-web/component-lib'\nimport React, { useEffect } from 'react'\nimport { Box, Typography } from '@mui/material'\nimport { TradeMenuList, useBasicTrade, VaultRepayWrap } from '../../tradePanel/components'\nimport { useTranslation } from 'react-i18next'\nexport const VaultRepayPanel = <T extends IBData<I>, V extends VaultRepayData<I>, I>({\n  walletMap = {},\n  coinMap = {},\n  _width,\n  type = TRADE_TYPE.TOKEN,\n  forexMap,\n  initialSymbol,\n  ...rest\n}: VaultRepayProps<T, I, V>) => {\n  const { currency } = useSettings()\n  const { t, i18n } = useTranslation()\n  const { tokenInfo } = rest\n  const { onChangeEvent, index, switchData } = useBasicTrade({\n    ...rest,\n    type,\n    walletMap,\n    coinMap,\n  } as any)\n  useEffect(() => {\n    if (initialSymbol) {\n      onChangeEvent(1, {\n        to: 'button',\n        tradeData: {\n          ...switchData.tradeData,\n          belong: initialSymbol as any,\n        },\n      })\n    }\n  }, [initialSymbol])\n  const props: SwitchPanelProps<'tradeMenuList' | 'trade' | 'confirm'> = {\n    index: index, // show default show\n    panelList: [\n      {\n        key: 'tradeMenuList',\n        element: React.useMemo(\n          () => (\n            // @ts-ignore\n            <TradeMenuList\n              {...{\n                className: 'vaultRepay',\n                nonZero: true,\n                sorted: true,\n                t,\n                ...rest,\n                onChangeEvent: (_index: 0 | 1, data) => {\n                  // @ts-ignore\n                  onChangeEvent(1 ^ _index, data)\n                },\n                hasCancel: false,\n                selected: switchData.tradeData.belong,\n                tradeData: switchData.tradeData,\n                walletMap,\n                coinMap,\n                tokenType: TokenType.vault,\n                contentEle: ({ ele }: { ele: any }) => {\n                  return (\n                    <Typography\n                      component={'span'}\n                      display={'flex'}\n                      flexDirection={'row'}\n                      alignItems={'center'}\n                    >\n                      <Typography\n                        variant={'body1'}\n                        flexDirection={'column'}\n                        display={'flex'}\n                        component={'span'}\n                        alignItems={'flex-end'}\n                        justifyContent={'space-between'}\n                        marginRight={1 / 2}\n                      >\n                        <Typography component='span' color='textPrimary' variant={'body1'}>\n                          {\n                            //   ele?.count || ele.count !== '0'\n                            //   ? getValuePrecisionThousand(\n                            //       ele.count,\n                            //       tokenInfo?.precision ?? 6,\n                            //       tokenInfo?.precision ?? 6,\n                            //     )\n                            //   : EmptyValueTag}\n                            // /\n                          }\n                          {getValuePrecisionThousand(\n                            ele.borrowed,\n                            tokenInfo?.precision ?? 6,\n                            tokenInfo?.precision ?? 6,\n                          )}\n                        </Typography>\n                        <Typography component='span' color='textSecondary' variant={'body2'}>\n                          {PriceTag[CurrencyToTag[currency]] +\n                            getValuePrecisionThousand(\n                              (ele?.usd ?? 0) * (forexMap[currency] ?? 0),\n                              undefined,\n                              undefined,\n                              2,\n                              true,\n                              {\n                                isFait: true,\n                                floor: false,\n                                isAbbreviate: true,\n                                abbreviate: 6,\n                              },\n                            )}\n                        </Typography>\n                      </Typography>\n                      <BackIcon\n                        sx={{ transform: 'rotate(180deg)', fill: 'var(--color-text-primary)' }}\n                      />\n                    </Typography>\n                  )\n                },\n              }}\n              filterWithBorrowed={true}\n            />\n          ),\n          [rest, onChangeEvent, switchData.tradeData, walletMap, coinMap],\n        ),\n        toolBarItem: undefined,\n      },\n      {\n        key: 'trade',\n        element: React.useMemo(\n          () => (\n            <VaultRepayWrap\n              key={'trade'}\n              {...{\n                ...rest,\n                type,\n                tradeData: switchData.tradeData as any,\n                onChangeEvent: (_index: 0 | 1, data) => {\n                  // @ts-ignore\n                  onChangeEvent(1 ^ _index, data)\n                },\n                disabled: !!rest.disabled,\n                walletMap,\n                coinMap,\n              }}\n            />\n          ),\n          [rest, switchData.tradeData, onChangeEvent, walletMap, coinMap],\n        ),\n        toolBarItem: React.useMemo(() => <></>, []),\n      },\n    ],\n  }\n  return Reflect.ownKeys(walletMap)?.length ? (\n    <SwitchPanel _width={'var(--modal-width)'} {...{ ...rest, i18n, t, tReady: true, ...props }} />\n  ) : (\n    <Box\n      // height={'var(--min-height)'}\n      display={'flex'}\n      justifyContent={'center'}\n      flexDirection={'column'}\n      alignItems={'center'}\n      height={rest._height}\n    >\n      <EmptyDefault\n        height={'100%'}\n        message={() => (\n          <Box flex={1} display={'flex'} alignItems={'center'} justifyContent={'center'}>\n            {t('labelNoContent')}\n          </Box>\n        )}\n      />\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/Vault/index.ts",
    "content": "export * from './VaultJoinPanel'\nexport * from './VaultExitPanel'\nexport * from './VaultLoanPanel'\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/WalletConnect/Interface.ts",
    "content": "import { GatewayItem } from '@loopring-web/common-resources'\n\n/**\n * @param handleSelect default hanldeSelect, if item have no private handleSelect function\n */\nexport interface ProviderMenuProps {\n  termUrl: string\n  NetWorkItems?: JSX.Element\n  gatewayList: GatewayItem[]\n  handleSelect?: (event: React.MouseEvent, key: string) => void\n  providerName?: string\n  status?: 'processing'\n}\n\nexport enum WalletConnectStep {\n  Provider,\n  CommonProcessing,\n  WalletConnectProcessing,\n  WalletConnectQRCode,\n  SuccessConnect,\n  FailedConnect,\n  RejectConnect,\n  RejectSwitchNetwork,\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/WalletConnect/ModalWalletConnect.tsx",
    "content": "import { WithTranslation, withTranslation } from 'react-i18next'\nimport { Box, Modal } from '@mui/material'\nimport {\n  ModalBackButton,\n  ModalCloseButton,\n  ModalWalletConnectProps,\n  ModelPanelStyle,\n} from '../../../index'\n\nexport const ModalWalletConnect = withTranslation('common', { withRef: true })(\n  ({\n    // t,\n    open,\n    onClose,\n    step,\n    onBack,\n    panelList,\n    style,\n    ...rest\n  }: ModalWalletConnectProps & WithTranslation) => {\n    return (\n      <Modal\n        open={open}\n        onClose={onClose}\n        disableEnforceFocus\n        aria-labelledby='modal-modal-title'\n        aria-describedby='modal-modal-description'\n      >\n        <ModelPanelStyle style={{ boxShadow: '24' }}>\n          <Box display={'flex'} width={'100%'} flexDirection={'column'}>\n            <ModalCloseButton onClose={onClose} {...rest} />\n            {onBack ? <ModalBackButton onBack={onBack} {...rest} /> : <></>}\n          </Box>\n          {panelList.map((panel, index) => {\n            return (\n              <Box\n                display={step === index ? 'flex' : 'none'}\n                alignItems={'stretch'}\n                height={panel.height ? panel.height : 'var(--modal-height)'}\n                width={panel.width ? panel.width : 'var(--modal-width)'}\n                key={index}\n              >\n                {panel.view}\n              </Box>\n            )\n          })}\n        </ModelPanelStyle>\n      </Modal>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/WalletConnect/ProviderMenu.tsx",
    "content": "import {\n  Box,\n  Checkbox,\n  FormControlLabel as MuiFormControlLabel,\n  Link,\n  Typography,\n} from '@mui/material'\nimport { Trans, WithTranslation } from 'react-i18next'\nimport styled from '@emotion/styled'\nimport { ProviderMenuProps } from './Interface'\nimport {\n  CheckBoxIcon,\n  CheckedIcon,\n  ConvertToIcon,\n  GatewayItem,\n  LOOPRING_DOCUMENT,\n  myLog,\n} from '@loopring-web/common-resources'\nimport React from 'react'\nimport { MenuBtnStyled, shake } from '../../styled'\nimport * as loopringProvider from '@loopring-web/web3-provider'\nimport { useSettings } from '../../../stores'\n\nconst CheckboxStyled = styled(Checkbox)`\n  &.shake {\n    animation: shake 0.82s cubic-bezier(0.36, 0.07, 0.19, 0.97) both;\n  }\n\n  ${shake}\n` as typeof Checkbox\n\nconst BoxContent = styled(Box)`\n  .modalContent {\n    padding-right: ${({ theme }) => theme.unit * 5}px;\n    padding-left: ${({ theme }) => theme.unit * 5}px;\n  }\n\n  @media only screen and (max-width: 768px) {\n    .modalContent {\n      padding-right: ${({ theme }) => theme.unit * 4}px;\n      padding-left: ${({ theme }) => theme.unit * 4}px;\n    }\n  }\n`\nconst BoxStyle = styled(Box)`\n  ${({ theme }) => theme.border.defaultFrame({ c_key: 'blur', d_R: 1 / 2, d_W: 0 })};\n  //background: var(--provider-agree);\n\n  .MuiFormControlLabel-root {\n    font-size: ${({ theme }) => theme.fontDefault.h6};\n    align-items: flex-start;\n    margin-right: 0;\n\n    .MuiTypography-root {\n      padding: ${({ theme }) => theme.unit}px 0;\n    }\n  }\n` as typeof Box\n\nexport const ProviderMenu = ({\n  t,\n  gatewayList,\n  termUrl,\n  handleSelect,\n  NetWorkItems,\n  status,\n  providerName = loopringProvider.ConnectProviders.Unknown,\n}: ProviderMenuProps & WithTranslation) => {\n  const { isMobile, defaultNetwork } = useSettings()\n  const [checkboxValue, setCheckboxValue] = React.useState(false)\n  const [isShake, setIsShake] = React.useState(false)\n\n  React.useEffect(() => {\n    const isAgreed = localStorage.getItem('userTermsAgreed')\n    setCheckboxValue(isAgreed === 'true')\n    setIsShake(false)\n  }, [])\n  const handleCheckboxChange = React.useCallback((_event: any, state: boolean) => {\n    setCheckboxValue(state)\n    localStorage.setItem('userTermsAgreed', String(state))\n  }, [])\n  const _handleSelect = React.useCallback(\n    (event: any, key: string, handleSelect?: (event: React.MouseEvent, key: string) => void) => {\n      if (handleSelect && checkboxValue) {\n        handleSelect(event, key)\n        setIsShake(false)\n      } else if (!checkboxValue) {\n        setIsShake(true)\n        setTimeout(() => {\n          if (isShake) {\n            setIsShake(false)\n          }\n        }, 80)\n      }\n    },\n    [checkboxValue, isShake],\n  )\n  const isProvider = React.useCallback(\n    (key: string) => {\n      if (\n        key === 'WalletConnectV1' &&\n        loopringProvider.connectProvides?.usedWeb3 &&\n        loopringProvider.connectProvides?.usedProvide\n      ) {\n        myLog('connectProvides', 'usedWeb3', '')\n      }\n      return providerName === key\n    },\n    [providerName],\n  )\n  const loadingGif = './static/loading-1.gif'\n  // const  !==  loopringProvider.ConnectProviders.Unknown\n  return (\n    <BoxContent\n      flex={1}\n      display={'flex'}\n      alignItems={'center'}\n      justifyContent={'space-between'}\n      flexDirection={'column'}\n      paddingBottom={4}\n      // sx={{ marginTop: \"-40px\" }}\n    >\n      <Typography\n        component={'h3'}\n        variant={isMobile ? 'h4' : 'h3'}\n        whiteSpace={'pre'}\n        marginBottom={2}\n      >\n        {t('labelConnectWallet')}\n      </Typography>\n      {NetWorkItems && (\n        <Box display={'flex'} justifyContent={'center'} marginBottom={3}>\n          {NetWorkItems}\n        </Box>\n      )}\n      <Box\n        display={'flex'}\n        flexDirection={'column'}\n        justifyContent={'center'}\n        flex={1}\n        alignItems={'stretch'}\n        alignSelf={'stretch'}\n        className='modalContent'\n        marginBottom={3}\n        // paddingX={isMobile ? 7 : 10}\n      >\n        {gatewayList.map((item: GatewayItem) => (\n          <Box key={item.key} marginTop={1.5}>\n            <MenuBtnStyled\n              variant={'outlined'}\n              size={'large'}\n              disabled={\n                item.key == loopringProvider.ConnectProviders.GameStop &&\n                ![1, 5].includes(Number(defaultNetwork))\n              }\n              loadingbg={'var(--field-opacity)'}\n              loading={status === 'processing' && isProvider(item.key) ? 'true' : 'false'}\n              className={`${isMobile ? 'isMobile' : ''} ${\n                isProvider(item.key) ? 'selected provider ' : 'provider'\n              }`}\n              fullWidth\n              onClick={(e) => {\n                _handleSelect(e, item.key, item.handleSelect ? item.handleSelect : handleSelect)\n              }}\n              endIcon={\n                status === 'processing' && isProvider(item.key) ? (\n                  <Typography\n                    display={'flex'}\n                    component={'span'}\n                    alignItems={'center'}\n                    color={'var(--color-text-third)'}\n                    variant={'body2'}\n                    className={'loading'}\n                  >\n                    <img src={loadingGif} height={24} />\n                    <Typography component={'span'} variant={'inherit'}>\n                      {t('labelConnecting')}\n                    </Typography>\n                  </Typography>\n                ) : (\n                  <ConvertToIcon fontSize={'medium'} color={'inherit'} />\n                )\n              }\n            >\n              <Typography\n                color={'inherit'}\n                component={'span'}\n                display={'inline-flex'}\n                fontSize={'inherit'}\n                alignItems={'center'}\n              >\n                <img src={item.imgSrc} alt={item.key} height={36} />\n                <span> {t(item.keyi18n)}</span>\n              </Typography>\n            </MenuBtnStyled>\n          </Box>\n        ))}\n      </Box>\n      <Box\n        display={'flex'}\n        flexDirection={'column'}\n        justifyContent={'center'}\n        flex={1}\n        alignItems={'stretch'}\n        alignSelf={'stretch'}\n        className='modalContent'\n        // paddingX={isMobile ? 7 : 10}\n      >\n        <BoxStyle\n          // paddingX={5 / 3}\n          display={'flex'}\n          flexDirection={'row'}\n          justifyContent={'stretch'}\n          alignItems={'flex-start'}\n        >\n          <MuiFormControlLabel\n            control={\n              <CheckboxStyled\n                className={isShake ? 'shake' : ''}\n                checked={checkboxValue}\n                onChange={handleCheckboxChange}\n                checkedIcon={<CheckedIcon />}\n                icon={<CheckBoxIcon />}\n                color='default'\n              />\n            }\n            label={\n              <Trans i18nKey='labelProviderAgree'>\n                I have read, understand, and agree to the\n                <Link\n                  component={'a'}\n                  href={termUrl}\n                  target='_blank'\n                  rel='noopener noreferrer'\n                  onClick={(_event) => {\n                    window.open(`${LOOPRING_DOCUMENT}terms_en.md`, '_blank')\n                    window.opener = null\n                  }}\n                >\n                  Terms of Service\n                </Link>\n                .\n              </Trans>\n            }\n          />\n        </BoxStyle>\n      </Box>\n    </BoxContent>\n  )\n  {\n    /*</WalletConnectPanelStyled>*/\n  }\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/WalletConnect/WalletConnectQRCode.tsx",
    "content": "import { Box, Link, Typography } from '@mui/material'\nimport { WithTranslation } from 'react-i18next'\nimport { SoursURL } from '@loopring-web/common-resources'\nimport { QRCode } from '../QRCode'\n\nexport const WalletConnectQRCode = ({\n  url,\n  onCopy,\n  t,\n}: { url: string; onCopy: () => void } & WithTranslation) => {\n  return (\n    <Box\n      flex={1}\n      display={'flex'}\n      alignItems={'center'}\n      justifyContent={'space-between'}\n      flexDirection={'column'}\n    >\n      <Typography component={'h3'} variant={'h3'} marginBottom={3} lineHeight={'36px'}>\n        <img\n          style={{ verticalAlign: 'middle' }}\n          src={SoursURL + 'svg/wallet-connect.svg'}\n          alt={'walletConnect'}\n          height={36}\n        />\n        WalletConnect\n      </Typography>\n      <QRCode url={url} size={240} />\n\n      <Box\n        display={'flex'}\n        alignItems={'center'}\n        justifyContent={'center'}\n        flexDirection={'column'}\n      >\n        <Typography variant={'body2'} color={'textSecondary'} marginTop={2}>\n          {t('labelWalletConnectQRCode')}\n        </Typography>\n        <Typography variant={'body2'} component={'p'} marginTop={1} marginBottom={3}>\n          <Link onClick={onCopy}>{t('labelCopyClipBoard')}</Link>\n        </Typography>\n      </Box>\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/WalletConnect/index.ts",
    "content": "export * from './ModalWalletConnect'\nexport * from './Interface'\nexport * from './WalletConnectQRCode'\nexport * from './ProviderMenu'\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/WalletPanels/Interface.ts",
    "content": "export enum GuardianStep {\n  LockAccount_WaitForAuth,\n  LockAccount_User_Denied,\n  LockAccount_Success,\n  LockAccount_Failed,\n\n  Approve_User_Denied,\n  Approve_WaitForAuth,\n  Approve_Success,\n  Approve_Failed,\n  Reject_User_Denied,\n  Reject_WaitForAuth,\n  Reject_Success,\n  Reject_Failed,\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/WalletPanels/LockWallet.tsx",
    "content": "import { Trans, useTranslation } from 'react-i18next'\nimport { BasicPanel, IconType, PanelProps } from '../ModalPanels/BasicPanel'\nimport { Box, Typography } from '@mui/material'\n\nexport const LockWallet = (props: PanelProps) => {\n  const propsPatch = {\n    title: 'labelLockWallet',\n  }\n  return <BasicPanel {...propsPatch} {...props} />\n}\n// symbol\nexport const LockAccount_WaitForAuth = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelWaitForAuth'),\n  }\n  return <LockWallet {...props} {...propsPatch} />\n}\n\nexport const LockAccount_User_Denied = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.RefuseIcon,\n    describe1: <Trans i18nKey={'labelSignDenied'}></Trans>,\n  }\n  return <LockWallet {...propsPatch} {...props} />\n}\n\n// symbol\nexport const LockAccount_Success = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.DoneIcon,\n    describe1: <Trans i18nKey={'labelLockAccountSuccess'}></Trans>,\n  }\n  return <LockWallet {...propsPatch} {...props} />\n}\n\n// value symbol\nexport const LockAccount_Failed = (props: PanelProps & any) => {\n  const { t } = useTranslation('common')\n  const propsPatch = {\n    iconType: IconType.FailedIcon,\n    describe1: (\n      <Box>\n        <Typography component={'p'}>{t('labelLockAccountFailed')}</Typography>\n        <Typography>{props?.error}</Typography>\n      </Box>\n    ),\n  }\n  return <LockWallet {...propsPatch} {...props} />\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/WalletPanels/ModalWallet.tsx",
    "content": "import { WithTranslation, withTranslation } from 'react-i18next'\nimport { Box, Modal } from '@mui/material'\nimport { useTheme } from '@emotion/react'\nimport {\n  ModalBackButton,\n  ModalCloseButton,\n  ModalGuardianProps,\n  QRButtonStyle,\n  SwipeableViewsStyled,\n  SwitchPanelStyled,\n} from '../../../index'\n\nexport const ModalWallet = withTranslation('common', { withRef: true })(\n  ({\n    open,\n    onClose,\n    step,\n    onBack,\n    style,\n    noClose,\n    onQRClick,\n    panelList,\n    ...rest\n  }: ModalGuardianProps & WithTranslation) => {\n    const theme = useTheme()\n    const { w, h } = style ? style : { w: undefined, h: undefined }\n\n    return (\n      <Modal\n        open={open}\n        onClose={onClose}\n        aria-labelledby='modal-modal-title'\n        aria-describedby='modal-modal-description'\n      >\n        <SwitchPanelStyled\n          style={{ boxShadow: '24' }}\n          {...{\n            _height: h ? h : 'var(--modal-height)',\n            _width: w ? w : 'var(--modal-width)',\n          }}\n        >\n          <Box display={'flex'} width={'100%'} flexDirection={'column'}>\n            {noClose ? <></> : <ModalCloseButton onClose={onClose} {...rest} />}\n            {onBack ? <ModalBackButton onBack={onBack} {...rest} /> : <></>}\n            {onQRClick ? <QRButtonStyle onQRClick={onQRClick} {...rest} /> : <></>}\n          </Box>\n\n          <SwipeableViewsStyled\n            animateTransitions={false}\n            axis={theme.direction === 'rtl' ? 'x-reverse' : 'x'}\n            index={step}\n            {...{\n              _height: h ? h : 'var(--modal-height)',\n              _width: w ? w : 'var(--modal-width)',\n            }}\n          >\n            {panelList.map((panel, index) => {\n              return (\n                <Box\n                  display={'flex'}\n                  flexDirection={'column'}\n                  justifyContent={'center'}\n                  alignItems={'center'}\n                  flex={1}\n                  key={index}\n                >\n                  {panel.view}\n                </Box>\n              )\n            })}\n          </SwipeableViewsStyled>\n        </SwitchPanelStyled>\n      </Modal>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/WalletPanels/WalletApprove.tsx",
    "content": "import { Trans } from 'react-i18next'\nimport { BasicPanel, IconType, PanelProps } from '../ModalPanels/BasicPanel'\n\nexport const WalletApprove = (props: PanelProps) => {\n  const propsPatch = {\n    title: 'labelWalletApprove',\n  }\n  return <BasicPanel {...propsPatch} {...props} />\n}\n// symbol\nexport const Approve_WaitForAuth = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelWaitForAuth'),\n  }\n  return <WalletApprove {...props} {...propsPatch} />\n}\n\nexport const Approve_User_Denied = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.RefuseIcon,\n    describe1: <Trans i18nKey={'labelSignDenied'} />,\n  }\n  return <WalletApprove {...propsPatch} {...props} />\n}\n\n// symbol\nexport const Approve_Success = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.DoneIcon,\n    describe1: <Trans i18nKey={'labelApproveSuccess'} />,\n  }\n  return <WalletApprove {...propsPatch} {...props} />\n}\n\n// value symbol\nexport const Approve_Failed = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.FailedIcon,\n    describe1: <Trans i18nKey={'labelApproveFailed'} />,\n  }\n  return <WalletApprove {...propsPatch} {...props} />\n}\n\nexport const HebaoReject = (props: PanelProps) => {\n  const propsPatch = {\n    title: 'labelWalletReject',\n  }\n  return <BasicPanel {...propsPatch} {...props} />\n}\n\n// symbol\nexport const Reject_WaitForAuth = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.LoadingIcon,\n    describe1: props.t('labelWaitForAuth'),\n  }\n  return <HebaoReject {...props} {...propsPatch} />\n}\n\nexport const Reject_User_Denied = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.RefuseIcon,\n    describe1: <Trans i18nKey={'labelSignDenied'} />,\n  }\n  return <HebaoReject {...propsPatch} {...props} />\n}\n\n// symbol\nexport const Reject_Success = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.DoneIcon,\n    describe1: <Trans i18nKey={'labelRejectSuccess'} />,\n  }\n  return <HebaoReject {...propsPatch} {...props} />\n}\n\n// value symbol\nexport const Reject_Failed = (props: PanelProps) => {\n  const propsPatch = {\n    iconType: IconType.FailedIcon,\n    describe1: <Trans i18nKey={'labelRejectFailed'} />,\n  }\n  return <HebaoReject {...propsPatch} {...props} />\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/WalletPanels/index.ts",
    "content": "export * from './Interface'\nexport * from './LockWallet'\nexport * from './ModalWallet'\nexport * from './WalletApprove'\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/accountList_new.stories.tsx",
    "content": "import styled from '@emotion/styled'\nimport React from 'react'\nimport { Meta, Story } from '@storybook/react'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport { MemoryRouter } from 'react-router-dom'\nimport { Box, Button, Grid, Typography } from '@mui/material'\nimport { ModalWalletConnect } from './WalletConnect'\n\nimport {\n  AccountBaseProps,\n  AccountStep as AccountStep,\n  CreateAccount_Approve_Denied,\n  CreateAccount_Approve_Submit,\n  CreateAccount_Approve_WaitForAuth,\n  CreateAccount_Denied,\n  CreateAccount_Failed,\n  CreateAccount_Submit,\n  CreateAccount_WaitForAuth,\n  Deposit_Approve_Denied,\n  Deposit_Approve_WaitForAuth,\n  Deposit_Denied,\n  Deposit_Failed,\n  Deposit_Submit,\n  Deposit_WaitForAuth,\n  ExportAccount_Approve_WaitForAuth,\n  ExportAccount_Failed,\n  ExportAccount_Success,\n  ExportAccount_User_Denied,\n  General_Failed,\n  HadAccount,\n  NoAccount,\n  Transfer_Failed,\n  Transfer_First_Method_Denied,\n  Transfer_In_Progress,\n  Transfer_Success,\n  Transfer_User_Denied,\n  Transfer_WaitForAuth,\n  UpdateAccount,\n  UpdateAccount_Approve_WaitForAuth,\n  UpdateAccount_Failed,\n  UpdateAccount_First_Method_Denied,\n  UpdateAccount_Success,\n  UpdateAccount_User_Denied,\n  Withdraw_Failed,\n  Withdraw_First_Method_Denied,\n  Withdraw_In_Progress,\n  Withdraw_Success,\n  Withdraw_User_Denied,\n  Withdraw_WaitForAuth,\n} from './ModalPanels'\nimport { account } from '../../static'\nimport { ConnectProviders } from '@loopring-web/web3-provider'\nimport { gatewayList } from '@loopring-web/common-resources'\n\nconst Style = styled.div`\n  flex: 1;\n  height: 100%;\n`\n\nconst Template: Story<any> = withTranslation()((rest: WithTranslation) => {\n  gatewayList[0] = {\n    ...gatewayList[0],\n    handleSelect: () => console.log('metaMask 11'),\n  }\n\n  const mainBtn = React.useMemo(() => {\n    return (\n      <Button variant={'contained'} fullWidth size={'medium'} onClick={() => {}}>\n        {'unlock'}\n      </Button>\n    )\n  }, [])\n  const accountInfoProps: AccountBaseProps = {\n    ...account,\n    level: 'VIP 1',\n    etherscanUrl: 'https://material-ui.com/components/material-icons/',\n  }\n  // const accAddress = '0xcEd11e039a5C50927a17a8D4632616DFa8F72BF6'\n\n  const retryBtn = React.useMemo(() => {\n    return {\n      btnTxt: 'retry',\n      callback: () => {},\n    }\n  }, [])\n\n  const closeBtn = React.useMemo(() => {\n    return {\n      btnTxt: 'close',\n      callback: () => {},\n    }\n  }, [])\n\n  const { nameList0, accountList0 } = React.useMemo(() => {\n    const accountMap = {\n      [AccountStep.NoAccount]: {\n        view: (\n          <NoAccount\n            goActiveAccount={function (): void {\n              throw new Error('Function not implemented.')\n            }}\n            onClose={function (_e?: any): void {\n              throw new Error('Function not implemented.')\n            }}\n            clearDepositHash={function (): void {\n              throw new Error('Function not implemented.')\n            }}\n            {...{\n              chainInfos: { depositHashes: {} },\n              ...accountInfoProps,\n              goAddAssetsFromL1: () => {},\n            }}\n          />\n        ),\n      },\n      [AccountStep.UpdateAccount]: {\n        view: (\n          <UpdateAccount\n            clearDepositHash={function (): void {\n              throw new Error('Function not implemented.')\n            }}\n            {...{\n              ...accountInfoProps,\n              chainInfos: { depositHashes: {} },\n              ...rest,\n            }}\n            goUpdateAccount={() => undefined}\n          />\n        ),\n      },\n      [AccountStep.HadAccount]: {\n        view: (\n          <HadAccount\n            clearDepositHash={function (): void {\n              throw new Error('Function not implemented.')\n            }}\n            onClose={function (_e?: any): void {\n              throw new Error('Function not implemented.')\n            }}\n            mainBtn={mainBtn}\n            {...{\n              ...accountInfoProps,\n              chainInfos: { depositHashes: {} },\n            }}\n          />\n        ),\n      },\n    }\n\n    return {\n      nameList0: Object.keys(accountMap),\n      accountList0: Object.values(accountMap),\n    }\n  }, [])\n\n  const { nameList, accountList } = React.useMemo(() => {\n    const accountMap = {\n      [AccountStep.Deposit_Sign_WaitForRefer]: {\n        view: (\n          <Deposit_Approve_WaitForAuth\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              symbol: 'LRC',\n              value: '1.2121',\n            }}\n          />\n        ),\n      },\n      [AccountStep.Deposit_Approve_WaitForAuth]: {\n        view: (\n          <Deposit_Approve_WaitForAuth\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              symbol: 'LRC',\n              value: '1.2121',\n            }}\n          />\n        ),\n      },\n      [AccountStep.Deposit_Approve_Denied]: {\n        view: (\n          <Deposit_Approve_Denied\n            btnInfo={retryBtn}\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              symbol: 'LRC',\n              value: '1.2121',\n            }}\n          />\n        ),\n      },\n\n      [AccountStep.Deposit_WaitForAuth]: {\n        view: (\n          <Deposit_WaitForAuth\n            providerName={ConnectProviders.WalletConnect}\n            {...{\n              ...rest,\n              symbol: 'LRC',\n              value: '1.2121',\n            }}\n          />\n        ),\n      },\n      [AccountStep.Deposit_Denied]: {\n        view: (\n          <Deposit_Denied\n            btnInfo={retryBtn}\n            {...{\n              ...rest,\n              symbol: 'LRC',\n              value: '1.2121',\n            }}\n          />\n        ),\n      },\n      [AccountStep.Deposit_Failed]: {\n        view: (\n          <Deposit_Failed\n            btnInfo={closeBtn}\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              symbol: 'LRC',\n              value: '1.2121',\n            }}\n          />\n        ),\n      },\n      [AccountStep.Deposit_Submit]: {\n        view: (\n          <Deposit_Submit\n            txCheck={{\n              route: '',\n              callback: () => {},\n            }}\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              symbol: 'LRC',\n              value: '1.2121',\n            }}\n          />\n        ),\n      },\n    }\n\n    return {\n      nameList: Object.keys(accountMap),\n      accountList: Object.values(accountMap),\n    }\n  }, [])\n\n  const { nameList2, accountList2 } = React.useMemo(() => {\n    const accountMap = {\n      [AccountStep.General_Failed]: {\n        view: (\n          <General_Failed\n            providerName={account.connectName as ConnectProviders}\n            {...rest}\n          />\n        ),\n      },\n      [AccountStep.Transfer_WaitForAuth]: {\n        view: (\n          <Transfer_WaitForAuth\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              symbol: 'LRC',\n              value: '1.2121',\n            }}\n          />\n        ),\n      },\n      [AccountStep.Transfer_First_Method_Denied]: {\n        view: (\n          <Transfer_First_Method_Denied\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              symbol: 'LRC',\n              value: '1.2121',\n            }}\n          />\n        ),\n      },\n      [AccountStep.Transfer_User_Denied]: {\n        view: (\n          <Transfer_User_Denied\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              symbol: 'LRC',\n              value: '1.2121',\n            }}\n          />\n        ),\n      },\n      [AccountStep.Transfer_In_Progress]: {\n        view: (\n          <Transfer_In_Progress\n            {...{\n              ...rest,\n              symbol: 'LRC',\n              value: '1.2121',\n            }}\n          />\n        ),\n      },\n      [AccountStep.Transfer_Success]: {\n        view: (\n          <Transfer_Success\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              symbol: 'LRC',\n              value: '1.2121',\n            }}\n          />\n        ),\n      },\n      [AccountStep.Transfer_Failed]: {\n        view: (\n          <Transfer_Failed\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              symbol: 'LRC',\n              value: '1.2121',\n            }}\n          />\n        ),\n      },\n    }\n\n    return {\n      nameList2: Object.keys(accountMap),\n      accountList2: Object.values(accountMap),\n    }\n  }, [])\n\n  const { nameList3, accountList3 } = React.useMemo(() => {\n    const accountMap = {\n      [AccountStep.Withdraw_WaitForAuth]: {\n        view: (\n          <Withdraw_WaitForAuth\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              symbol: 'LRC',\n              value: '1.2121',\n            }}\n          />\n        ),\n      },\n      [AccountStep.Withdraw_First_Method_Denied]: {\n        view: (\n          <Withdraw_First_Method_Denied\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              symbol: 'LRC',\n              value: '1.2121',\n            }}\n          />\n        ),\n      },\n      [AccountStep.Withdraw_User_Denied]: {\n        view: (\n          <Withdraw_User_Denied\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              symbol: 'LRC',\n              value: '1.2121',\n            }}\n          />\n        ),\n      },\n      [AccountStep.Withdraw_In_Progress]: {\n        view: (\n          <Withdraw_In_Progress\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              symbol: 'LRC',\n              value: '1.2121',\n            }}\n          />\n        ),\n      },\n      [AccountStep.Withdraw_Success]: {\n        view: (\n          <Withdraw_Success\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              symbol: 'LRC',\n              value: '1.2121',\n            }}\n          />\n        ),\n      },\n      [AccountStep.Withdraw_Failed]: {\n        view: (\n          <Withdraw_Failed\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              symbol: 'LRC',\n              value: '1.2121',\n            }}\n          />\n        ),\n      },\n    }\n\n    return {\n      nameList3: Object.keys(accountMap),\n      accountList3: Object.values(accountMap),\n    }\n  }, [])\n\n  const { nameList4, accountList4 } = React.useMemo(() => {\n    const accountMap = {\n      [AccountStep.CreateAccount_Approve_WaitForAuth]: {\n        view: (\n          <CreateAccount_Approve_WaitForAuth\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              symbol: 'LRC',\n              value: '1.2121',\n            }}\n          />\n        ),\n      },\n      [AccountStep.CreateAccount_Approve_Denied]: {\n        view: (\n          <CreateAccount_Approve_Denied\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              symbol: 'LRC',\n              value: '1.2121',\n            }}\n          />\n        ),\n      },\n      [AccountStep.CreateAccount_Approve_Submit]: {\n        view: (\n          <CreateAccount_Approve_Submit\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              symbol: 'LRC',\n              value: '1.2121',\n            }}\n          />\n        ),\n      },\n      [AccountStep.CreateAccount_WaitForAuth]: {\n        view: (\n          <CreateAccount_WaitForAuth\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              symbol: 'LRC',\n              value: '1.2121',\n            }}\n          />\n        ),\n      },\n      [AccountStep.CreateAccount_Denied]: {\n        view: (\n          <CreateAccount_Denied\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              symbol: 'LRC',\n              value: '1.2121',\n            }}\n          />\n        ),\n      },\n      [AccountStep.CreateAccount_Failed]: {\n        view: (\n          <CreateAccount_Failed\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              symbol: 'LRC',\n              value: '1.2121',\n            }}\n          />\n        ),\n      },\n      [AccountStep.CreateAccount_Submit]: {\n        view: (\n          <CreateAccount_Submit\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              symbol: 'LRC',\n              value: '1.2121',\n            }}\n          />\n        ),\n      },\n    }\n\n    return {\n      nameList4: Object.keys(accountMap),\n      accountList4: Object.values(accountMap),\n    }\n  }, [])\n\n  const { nameList5, accountList5 } = React.useMemo(() => {\n    const accountMap = {\n      [AccountStep.UpdateAccount_Approve_WaitForAuth]: {\n        view: (\n          <UpdateAccount_Approve_WaitForAuth\n            {...{\n              ...rest,\n              providerNam: 'MetaMask',\n            }}\n          />\n        ),\n      },\n      [AccountStep.UpdateAccount_First_Method_Denied]: {\n        view: (\n          <UpdateAccount_First_Method_Denied\n            btnInfo={retryBtn}\n            {...{\n              ...rest,\n            }}\n          />\n        ),\n      },\n      [AccountStep.UpdateAccount_User_Denied]: {\n        view: (\n          <UpdateAccount_User_Denied\n            btnInfo={retryBtn}\n            {...{\n              ...rest,\n            }}\n          />\n        ),\n      },\n      [AccountStep.UpdateAccount_Success]: {\n        view: (\n          <UpdateAccount_Success\n            btnInfo={closeBtn}\n            {...{\n              ...rest,\n            }}\n          />\n        ),\n      },\n      [AccountStep.UpdateAccount_Success]: {\n        view: (\n          <UpdateAccount_Success\n            btnInfo={closeBtn}\n            {...{\n              ...rest,\n            }}\n          />\n        ),\n      },\n      [AccountStep.UpdateAccount_Failed]: {\n        view: (\n          <UpdateAccount_Failed\n            btnInfo={closeBtn}\n            {...{\n              ...rest,\n            }}\n          />\n        ),\n      },\n\n      [AccountStep.ResetAccount_Approve_WaitForAuth]: {\n        view: (\n          <UpdateAccount_Approve_WaitForAuth\n            patch={{ isReset: true }}\n            {...{\n              ...rest,\n              providerNam: 'MetaMask',\n            }}\n          />\n        ),\n      },\n      [AccountStep.ResetAccount_First_Method_Denied]: {\n        view: (\n          <UpdateAccount_First_Method_Denied\n            patch={{ isReset: true }}\n            btnInfo={retryBtn}\n            {...{\n              ...rest,\n            }}\n          />\n        ),\n      },\n      [AccountStep.ResetAccount_User_Denied]: {\n        view: (\n          <UpdateAccount_User_Denied\n            patch={{ isReset: true }}\n            btnInfo={retryBtn}\n            {...{\n              ...rest,\n            }}\n          />\n        ),\n      },\n      [AccountStep.ResetAccount_Success]: {\n        view: (\n          <UpdateAccount_Success\n            patch={{ isReset: true }}\n            btnInfo={closeBtn}\n            {...{\n              ...rest,\n            }}\n          />\n        ),\n      },\n\n      [AccountStep.ExportAccount_Approve_WaitForAuth]: {\n        view: (\n          <ExportAccount_Approve_WaitForAuth\n            patch={{ isReset: true }}\n            btnInfo={closeBtn}\n            {...{\n              ...rest,\n            }}\n          />\n        ),\n      },\n      [AccountStep.ExportAccount_User_Denied]: {\n        view: (\n          <ExportAccount_User_Denied\n            patch={{ isReset: true }}\n            btnInfo={retryBtn}\n            {...{\n              ...rest,\n            }}\n          />\n        ),\n      },\n      [AccountStep.ExportAccount_Success]: {\n        view: (\n          <ExportAccount_Success\n            patch={{ isReset: true }}\n            btnInfo={closeBtn}\n            {...{\n              ...rest,\n            }}\n          />\n        ),\n      },\n      [AccountStep.ExportAccount_Failed]: {\n        view: (\n          <ExportAccount_Failed\n            patch={{ isReset: true }}\n            btnInfo={closeBtn}\n            {...{\n              ...rest,\n            }}\n          />\n        ),\n      },\n    }\n\n    return {\n      nameList5: Object.keys(accountMap),\n      accountList5: Object.values(accountMap),\n    }\n  }, [])\n\n  const fontSize = '30px'\n  const color = 'white'\n  const width = 400\n\n  const w = 540\n  const h = 600\n\n  return (\n    <>\n      <Style>\n        <MemoryRouter initialEntries={['/']}>\n          <Box\n            paddingTop={2}\n            paddingX={2}\n            width={width}\n            display={'flex'}\n            flexDirection={'column'}\n            alignItems={'center'}\n            justifyContent={'center'}\n          >\n            <Typography fontSize={fontSize} color={color} variant={'body2'}>\n              {' '}\n              Old Version{' '}\n            </Typography>\n          </Box>\n          <Grid container spacing={0}>\n            {accountList0.map((panel: any, index: number) => {\n              return (\n                <>\n                  <Box\n                    key={index}\n                    display={'flex'}\n                    flexDirection={'column'}\n                    width={w}\n                    height={h}\n                    padding={2}\n                    justifyContent={'center'}\n                    alignItems={'stretch'}\n                  >\n                    <Typography\n                      marginTop={2}\n                      variant={'body2'}\n                      color={'textSecondary'}\n                      style={{ wordBreak: 'break-all' }}\n                    >\n                      {AccountStep[nameList0[index]]}\n                    </Typography>\n\n                    {panel.view}\n                  </Box>\n                </>\n              )\n            })}\n          </Grid>\n\n          <Box\n            paddingTop={2}\n            paddingX={2}\n            width={width}\n            display={'flex'}\n            flexDirection={'column'}\n            alignItems={'center'}\n            justifyContent={'center'}\n          >\n            <Typography fontSize={fontSize} color={color} variant={'body2'}>\n              {' '}\n              Deposit\n            </Typography>\n          </Box>\n          <Grid container spacing={2}>\n            {accountList.map((panel, index) => {\n              return (\n                <>\n                  <Box\n                    key={index}\n                    display={'flex'}\n                    flexDirection={'column'}\n                    width={w}\n                    height={h}\n                    padding={2}\n                    justifyContent={'center'}\n                    alignItems={'stretch'}\n                  >\n                    <Typography\n                      marginTop={2}\n                      variant={'body2'}\n                      color={'textSecondary'}\n                      style={{ wordBreak: 'break-all' }}\n                    >\n                      {AccountStep[nameList[index]]}\n                    </Typography>\n\n                    {panel.view}\n                  </Box>\n                </>\n              )\n            })}\n          </Grid>\n\n          <Box\n            paddingTop={2}\n            paddingX={2}\n            width={width}\n            display={'flex'}\n            flexDirection={'column'}\n            alignItems={'center'}\n            justifyContent={'center'}\n          >\n            <Typography fontSize={fontSize} color={color} variant={'body2'}>\n              {' '}\n              Transfer{' '}\n            </Typography>\n          </Box>\n\n          <Grid container spacing={2}>\n            {accountList2.map((panel, index) => {\n              return (\n                <>\n                  <Box\n                    key={index}\n                    display={'flex'}\n                    flexDirection={'column'}\n                    width={w}\n                    height={h}\n                    padding={2}\n                    justifyContent={'center'}\n                    alignItems={'stretch'}\n                  >\n                    <Typography\n                      marginTop={2}\n                      variant={'body2'}\n                      color={'textSecondary'}\n                      style={{ wordBreak: 'break-all' }}\n                    >\n                      {AccountStep[nameList2[index]]}\n                    </Typography>\n\n                    {panel.view}\n                  </Box>\n                </>\n              )\n            })}\n          </Grid>\n\n          <Box\n            paddingTop={2}\n            paddingX={2}\n            width={width}\n            display={'flex'}\n            flexDirection={'column'}\n            alignItems={'center'}\n            justifyContent={'center'}\n          >\n            <Typography fontSize={fontSize} color={color} variant={'body2'}>\n              Withdraw\n            </Typography>\n          </Box>\n\n          <Grid container spacing={2}>\n            {accountList3.map((panel, index) => {\n              return (\n                <>\n                  <Box\n                    key={index}\n                    display={'flex'}\n                    flexDirection={'column'}\n                    width={w}\n                    height={h}\n                    padding={2}\n                    justifyContent={'center'}\n                    alignItems={'stretch'}\n                  >\n                    <Typography\n                      marginTop={2}\n                      variant={'body2'}\n                      color={'textSecondary'}\n                      style={{ wordBreak: 'break-all' }}\n                    >\n                      {AccountStep[nameList3[index]]}\n                    </Typography>\n\n                    {panel.view}\n                  </Box>\n                </>\n              )\n            })}\n          </Grid>\n\n          <Box\n            paddingTop={2}\n            paddingX={2}\n            width={width}\n            display={'flex'}\n            flexDirection={'column'}\n            alignItems={'center'}\n            justifyContent={'center'}\n          >\n            <Typography fontSize={fontSize} color={color} variant={'body2'}>\n              {' '}\n              Create Layer2 Account{' '}\n            </Typography>\n          </Box>\n\n          <Grid container spacing={2}>\n            {accountList4.map((panel, index) => {\n              return (\n                <>\n                  <Box\n                    key={index}\n                    display={'flex'}\n                    flexDirection={'column'}\n                    width={w}\n                    height={h}\n                    padding={2}\n                    justifyContent={'center'}\n                    alignItems={'stretch'}\n                  >\n                    <Typography\n                      marginTop={2}\n                      variant={'body2'}\n                      color={'textSecondary'}\n                      style={{ wordBreak: 'break-all' }}\n                    >\n                      {AccountStep[nameList4[index]]}\n                    </Typography>\n\n                    {panel.view}\n                  </Box>\n                </>\n              )\n            })}\n          </Grid>\n\n          <Box\n            paddingTop={2}\n            paddingX={2}\n            width={width}\n            display={'flex'}\n            flexDirection={'column'}\n            alignItems={'center'}\n            justifyContent={'center'}\n          >\n            <Typography fontSize={fontSize} color={color} variant={'body2'}>\n              {' '}\n              Update Layer2 Account{' '}\n            </Typography>\n          </Box>\n\n          <Grid container spacing={2}>\n            {accountList5.map((panel, index) => {\n              return (\n                <>\n                  <Box\n                    key={index}\n                    display={'flex'}\n                    flexDirection={'column'}\n                    width={w}\n                    height={h}\n                    padding={2}\n                    justifyContent={'center'}\n                    alignItems={'stretch'}\n                  >\n                    <Typography\n                      marginTop={2}\n                      variant={'body2'}\n                      color={'textSecondary'}\n                      style={{ wordBreak: 'break-all' }}\n                    >\n                      {AccountStep[nameList5[index]]}\n                    </Typography>\n\n                    {panel.view}\n                  </Box>\n                </>\n              )\n            })}\n          </Grid>\n        </MemoryRouter>\n      </Style>\n    </>\n  )\n}) as Story<any>\n\n// @ts-ignore\nexport const ModalListStory = Template.bind({})\n\nexport default {\n  title: 'components/account_list_new',\n  component: ModalWalletConnect,\n  argTypes: {},\n} as Meta\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/index.ts",
    "content": "export * from './QRCode'\nexport * from './WalletConnect'\nexport * from './ModalPanelBase'\nexport * from './ModalPanels'\nexport * from './WalletPanels'\nexport * from './RedPacketPanels'\nexport * from './setting'\nexport * from './Vault'\nexport * from './ClosureAnnouncementModal'\nexport type ModalBasicProps = {\n  open: boolean\n  onClose: {\n    bivarianceHack(event: {}, reason: 'backdropClick' | 'escapeKeyDown'): void\n  }['bivarianceHack']\n  onBack?: () => void\n  isLayer2Only?: boolean\n  step: number\n  noClose?: boolean\n  style?: any //{w,h}\n  onQRClick?: () => void\n  etherscanBaseUrl: string\n  panelList: Array<{\n    view: JSX.Element\n    onBack?: undefined | (() => void)\n    onClose?: undefined | (() => void)\n    height?: any\n    width?: any\n  }>\n  isWebEarn?: boolean\n}\nexport type ModalWalletConnectProps = ModalBasicProps\nexport type ModalAccountProps = ModalWalletConnectProps\nexport type ModalGuardianProps = ModalWalletConnectProps\nexport type ModalRedPacketProps = ModalBasicProps\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/setting/Interface.ts",
    "content": "export type ModalSettingFeeProps = {\n  open: boolean\n  onClose: {\n    bivarianceHack(event: {}, reason: 'backdropClick' | 'escapeKeyDown'): void\n  }['bivarianceHack']\n  noClose?: boolean\n  style?: any\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/setting/SettingFee.tsx",
    "content": "import { WithTranslation, withTranslation } from 'react-i18next'\nimport {\n  Button,\n  CoinIcon,\n  ModalCloseButton,\n  ModalSettingFeeProps,\n  useOpenModals,\n  useSettings,\n} from '../../../index'\nimport { Box, Link, ListItemIcon, ListItemText, Modal, Typography } from '@mui/material'\nimport { SwitchPanelStyled } from '../../styled'\nimport {\n  DragListIcon,\n  FeeChargeOrderDefaultMap,\n  L1L2_NAME_DEFINED,\n  MapChainId,\n  myLog,\n} from '@loopring-web/common-resources'\nimport {\n  DragDropContext,\n  Draggable,\n  Droppable,\n  DropResult,\n  ResponderProvided,\n} from 'react-beautiful-dnd'\nimport React from 'react'\nimport { useTheme } from '@emotion/react'\n\nexport const PanelStyled = {}\n\nexport const ModalSettingFee = withTranslation('common', { withRef: true })(\n  ({ t, open, onClose, style, ...rest }: ModalSettingFeeProps & WithTranslation) => {\n    const theme = useTheme()\n    const { feeChargeOrder, setFeeChargeOrder, defaultNetwork } = useSettings()\n    const { setShowFeeSetting } = useOpenModals()\n    const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n    const [feeChargeValue, setFeeChargeValue] = React.useState<string[]>(\n      feeChargeOrder ?? FeeChargeOrderDefaultMap.get(defaultNetwork)!,\n    )\n    const onDragEnd = React.useCallback((dropResult: DropResult, provider: ResponderProvided) => {\n      myLog('draggableDone', dropResult, provider)\n      if (dropResult.destination) {\n        const { index: startIndex } = dropResult.source\n        const { index: endIndex } = dropResult.destination\n        setFeeChargeValue((state) => {\n          const result = [].slice.call(state)\n          const [removed] = result.splice(startIndex, 1)\n          result.splice(endIndex, 0, removed)\n          return result\n        })\n        // const result = [].concat(feeChargeValue);\n        // const [removed] = result.splice(startIndex, 1);\n        // result.splice(endIndex, 0, removed);\n      }\n\n      // result: DropResult, provided: ResponderProvided\n    }, [])\n    const getItemStyle = (isDragging: any, draggableStyle: any, index: number) => {\n      return {\n        userSelect: 'none',\n        background: isDragging ? 'var(--color-box-hover)' : '',\n        ...draggableStyle,\n        position: draggableStyle.position === 'fixed' ? 'absolute' : '',\n        //--list-coin-item = 44   +  margin = 16\n        top:\n          draggableStyle.position === 'fixed'\n            ? `calc((var(--list-coin-item) + ${theme.unit * 2}px) * ${index})`\n            : '',\n        left: 0,\n      }\n    }\n    return (\n      <Modal\n        open={open}\n        onClose={onClose}\n        aria-labelledby='modal-modal-title'\n        aria-describedby='modal-modal-description'\n      >\n        <SwitchPanelStyled width={'var(--modal-width)'}>\n          <Box display={'flex'} width={'100%'} flexDirection={'column'}>\n            <ModalCloseButton onClose={onClose} t={t} {...rest} />\n            <Box\n              flex={1}\n              alignItems={'stretch'}\n              display={'flex'}\n              flexDirection={'column'}\n              paddingX={5}\n              paddingBottom={5}\n            >\n              <Typography component={'h4'} variant={'h3'} textAlign={'center'}>\n                {t('labelSettingChargeFeeOrder')}\n              </Typography>\n              <Typography\n                component={'h5'}\n                variant={'body1'}\n                color={'text.secondary'}\n                textAlign={'center'}\n                marginTop={2}\n                marginBottom={3}\n              >\n                {t('labelDesSettingChargeFeeOrder', {\n                  layer2: L1L2_NAME_DEFINED[network].layer2,\n                  l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                  loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                  l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                  l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                  ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                })}\n              </Typography>\n              <Box>\n                <DragDropContext onDragEnd={onDragEnd}>\n                  <Droppable droppableId='chargeList'>\n                    {(provided) => (\n                      <Box\n                        display={'flex'}\n                        position={'relative'}\n                        marginBottom={3}\n                        flexDirection={'column'}\n                        {...provided.droppableProps}\n                        ref={provided.innerRef}\n                      >\n                        {feeChargeValue.map((item, index) => (\n                          <Draggable key={item} draggableId={item} index={index}>\n                            {(draggableProvided, draggableSnapshot) => (\n                              <Box\n                                marginY={1}\n                                paddingY={1}\n                                height={'var(--list-coin-item)'}\n                                display={'inline-flex'}\n                                alignItems={'center'}\n                                justifyContent={'space-between'}\n                                ref={draggableProvided.innerRef}\n                                {...draggableProvided.draggableProps}\n                                {...draggableProvided.dragHandleProps}\n                                style={getItemStyle(\n                                  draggableSnapshot.isDragging,\n                                  draggableProvided.draggableProps.style,\n                                  index,\n                                )}\n                              >\n                                <Typography\n                                  component={'span'}\n                                  variant={'h5'}\n                                  display={'inline-flex'}\n                                  alignItems={'center'}\n                                >\n                                  <ListItemIcon style={{ minWidth: '40px' }}>\n                                    <CoinIcon symbol={item} size={32} />\n                                  </ListItemIcon>\n                                  <ListItemText>\n                                    <Typography marginLeft={1} variant={'h5'}>\n                                      {item}\n                                    </Typography>\n                                  </ListItemText>\n                                </Typography>\n                                <DragListIcon\n                                  htmlColor={'var(--color-text-third)'}\n                                  fontSize={'large'}\n                                />\n                              </Box>\n                            )}\n                          </Draggable>\n                        ))}\n                        {provided.placeholder}\n                      </Box>\n                    )}\n                  </Droppable>\n                </DragDropContext>\n              </Box>\n\n              <Button\n                fullWidth\n                variant={'contained'}\n                size={'medium'}\n                color={'primary'}\n                onClick={() => {\n                  // copyToClipBoard(info)\n                  // setExportAccountToastOpen(true)\n                  setFeeChargeOrder(feeChargeValue)\n                  setShowFeeSetting({ isShow: false })\n                }}\n              >\n                {t(`labelQueryFeeOK`)}\n              </Button>\n              <Typography textAlign={'center'} marginTop={1}>\n                <Link\n                  color={'inherit'}\n                  style={{\n                    textDecoration: 'underline dotted',\n                    color: 'var(--color-text-secondary)',\n                  }}\n                  onClick={() => {\n                    setFeeChargeValue(FeeChargeOrderDefaultMap.get(defaultNetwork)!)\n                  }}\n                >\n                  {t('labelReset')}\n                </Link>\n              </Typography>\n            </Box>\n          </Box>\n        </SwitchPanelStyled>\n      </Modal>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/setting/index.ts",
    "content": "export * from './SettingFee'\nexport * from './Interface'\n"
  },
  {
    "path": "packages/component-lib/src/components/modal/walletList.stories.tsx",
    "content": "import styled from '@emotion/styled'\nimport React from 'react'\nimport { Meta, Story } from '@storybook/react'\nimport { withTranslation } from 'react-i18next'\nimport { MemoryRouter } from 'react-router-dom'\nimport { Box, Button, Grid } from '@mui/material'\nimport { AccountFull, AccountStatus, gatewayList, SagaStatus } from '@loopring-web/common-resources'\nimport {\n  ModalWalletConnect,\n  ProviderMenu,\n  WalletConnectQRCode,\n  WalletConnectStep,\n} from './WalletConnect'\nimport { ModalQRCode, QRCodePanel } from './QRCode'\n\nimport { account } from '../../static'\nimport { WalletConnectBtn } from '../header'\n\nimport {\n  CommonConnectInProgress,\n  ConnectFailed,\n  ConnectReject,\n  ConnectSuccess,\n  WalletConnectConnectInProgress,\n} from '../index'\n\nconst Style = styled.div`\n  flex: 1;\n  height: 100%;\n`\n\nconst accountState: AccountFull = {\n  account: {\n    ...account,\n    _chainId: 1,\n  },\n  status: SagaStatus.DONE,\n  resetAccount: () => undefined,\n  updateAccount: () => undefined,\n}\nconst ConnectButtonWrap = withTranslation('common')((_rest: any) => {\n  return (\n    <>\n      <Grid item xs={3}>\n        <WalletConnectBtn\n          accountState={accountState}\n          handleClick={() => undefined}\n          NetWorkItems={<></>}\n          isShowOnUnConnect\n        />\n      </Grid>\n      <Grid item xs={3}>\n        <WalletConnectBtn\n          isShowOnUnConnect\n          accountState={{\n            ...accountState,\n            account: { ...account, readyState: AccountStatus.NO_ACCOUNT },\n          }}\n          handleClick={() => undefined}\n          NetWorkItems={<></>}\n        />\n      </Grid>\n      <Grid item xs={3}>\n        <WalletConnectBtn\n          isShowOnUnConnect\n          accountState={{\n            ...accountState,\n            account: { ...account, readyState: AccountStatus.DEPOSITING },\n          }}\n          handleClick={() => undefined}\n          NetWorkItems={<></>}\n        />\n      </Grid>\n      <Grid item xs={3}>\n        <WalletConnectBtn\n          isShowOnUnConnect\n          accountState={{\n            ...accountState,\n            account: { ...account, readyState: AccountStatus.NOT_ACTIVE },\n          }}\n          handleClick={() => undefined}\n          NetWorkItems={<></>}\n        />\n      </Grid>\n      <Grid item xs={3}>\n        <WalletConnectBtn\n          isShowOnUnConnect\n          accountState={{\n            ...accountState,\n            account: { ...account, readyState: AccountStatus.ACTIVATED },\n          }}\n          handleClick={() => undefined}\n          NetWorkItems={<></>}\n        />\n      </Grid>\n      <Grid item xs={3}>\n        <WalletConnectBtn\n          isShowOnUnConnect\n          accountState={{\n            ...accountState,\n            account: { ...account, readyState: AccountStatus.ERROR_NETWORK },\n          }}\n          handleClick={() => undefined}\n          NetWorkItems={<></>}\n        />\n      </Grid>\n      <Grid item xs={3}>\n        <WalletConnectBtn\n          isShowOnUnConnect\n          accountState={{\n            ...accountState,\n            account: { ...account, readyState: AccountStatus.LOCKED },\n          }}\n          handleClick={() => undefined}\n          NetWorkItems={<></>}\n        />\n      </Grid>\n      <Grid item xs={3}>\n        <WalletConnectBtn\n          isShowOnUnConnect\n          accountState={{\n            ...accountState,\n            account: {\n              ...account,\n              readyState: AccountStatus.LOCKED,\n              _chainId: 5,\n            },\n          }}\n          handleClick={() => undefined}\n          NetWorkItems={<></>}\n        />\n      </Grid>\n    </>\n  )\n})\n\nconst Template: Story<any> = withTranslation()(({ ...rest }: any) => {\n  const [openWallet, setOpenWallet] = React.useState(false)\n  const [openQRCode, setOpenQRCode] = React.useState(false)\n  gatewayList[0] = {\n    ...gatewayList[0],\n    handleSelect: () => console.log('metaMask 11'),\n  }\n  const url: string = 'xxxxxx'\n  const walletList = React.useMemo(() => {\n    return Object.values({\n      [WalletConnectStep.Provider]: {\n        view: <ProviderMenu gatewayList={gatewayList} {...{ providerName: 'MetaMask', ...rest }} />,\n      },\n      [WalletConnectStep.CommonProcessing]: {\n        view: <CommonConnectInProgress {...rest} />,\n      },\n      [WalletConnectStep.WalletConnectProcessing]: {\n        view: <WalletConnectConnectInProgress {...rest} />,\n      },\n      [WalletConnectStep.WalletConnectQRCode]: {\n        view: <WalletConnectQRCode {...rest} url={url} />,\n      },\n      [WalletConnectStep.SuccessConnect]: {\n        view: <ConnectSuccess {...{ providerName: 'MetaMask', ...rest }} />,\n      },\n      [WalletConnectStep.FailedConnect]: {\n        view: <ConnectFailed {...rest} onRetry={() => {}} />,\n      },\n      [WalletConnectStep.RejectConnect]: {\n        view: <ConnectReject {...rest} onRetry={() => {}} />,\n      },\n    })\n  }, [rest])\n\n  // const accountList = React.useMemo(() => {\n  //     return Object.values({\n  //         [ AccountStep.NoAccount ]: <NoAccount {...{\n  //             ...accountInfoProps, goAddAssetsFromL1: () => {\n  //             }\n  //         }}/>,\n  //         [ AccountStep.Deposit ]: <DepositWrap _height={480} _width={400}  {...{...rest, ...depositProps}} />,\n  //         [ AccountStep.Depositing ]: <Depositing {...{\n  //             providerName: ConnectProviders.MetaMask,\n  //             etherscanLink: accountInfoProps.etherscanUrl, ...rest\n  //         }}/>,\n  //         [ AccountStep.FailedDeposit ]: <FailedDeposit {...rest} label={'depositTitleAndActive'}\n  //                                                       onRetry={() => undefined}\n  //                                                       etherscanLink={accountInfoProps.etherscanUrl}/>,\n  //         [ AccountStep.SignAccount ]: <ApproveAccount  {...{...accountInfoProps, ...rest}}\n  //                                                       goActiveAccount={() => undefined}/>,\n  //         [ AccountStep.ProcessUnlock ]: <ProcessUnlock {...{providerName: ConnectProviders.MetaMask, ...rest}}/>,\n  //         [ AccountStep.SuccessUnlock ]: <SuccessUnlock {...rest}/>,\n  //         [ AccountStep.FailedUnlock ]: <FailedUnlock {...rest} onRetry={() => undefined}/>,\n  //         [ AccountStep.HadAccount ]: <HadAccount mainBtn={mainBtn} {...accountInfoProps}/>,\n  //         [ AccountStep.TokenAccessProcess ]: <TokenAccessProcess {...{\n  //             ...rest,\n  //             coinInfo,\n  //             providerName: ConnectProviders.MetaMask\n  //         }}/>,\n  //         [ AccountStep.DepositApproveProcess ]: <DepositApproveProcess {...{\n  //             ...rest,\n  //             providerName: ConnectProviders.MetaMask\n  //         }}/>,\n  //         [ AccountStep.ActiveAccountProcess ]: <ActiveAccountProcess {...{\n  //             ...rest,\n  //             providerName: ConnectProviders.MetaMask\n  //         }}/>,\n  //         [ AccountStep.FailedTokenAccess ]: <FailedTokenAccess {...{...rest, coinInfo}}/>,\n  //     })\n  //\n  // }, [])\n\n  return (\n    <>\n      <Style>\n        <MemoryRouter initialEntries={['/']}>\n          <h4>Connect Button status</h4>\n          <Grid\n            container\n            spacing={2}\n            alignContent={'center'}\n            justifyContent={'space-around'}\n            marginBottom={2}\n          >\n            <ConnectButtonWrap />\n          </Grid>\n          <Grid container spacing={2}>\n            {walletList.map((panel, index) => {\n              return (\n                <Box\n                  key={index}\n                  display={'flex'}\n                  flexDirection={'column'}\n                  width={480}\n                  height={400}\n                  padding={2}\n                  justifyContent={'center'}\n                  alignItems={'stretch'}\n                >\n                  {panel.view}\n                </Box>\n              )\n            })}\n          </Grid>\n          -----------------------------\n          <Button\n            variant={'outlined'}\n            size={'small'}\n            color={'primary'}\n            style={{ marginRight: 8 }}\n            onClick={() => setOpenWallet(true)}\n          >\n            Connect wallet\n          </Button>\n          <ModalWalletConnect\n            open={openWallet}\n            onClose={() => setOpenWallet(false)}\n            onBack={() => {\n              setOpenWallet(false)\n            }}\n            panelList={walletList}\n            step={WalletConnectStep.WalletConnectQRCode}\n            etherscanBaseUrl={''}\n          />\n          -----------------------------\n          <Button\n            variant={'outlined'}\n            size={'medium'}\n            color={'primary'}\n            onClick={() => setOpenQRCode(true)}\n          >\n            QR Code\n          </Button>\n          <ModalQRCode\n            open={openQRCode}\n            onClose={() => setOpenQRCode(false)}\n            title={'title'}\n            description={'my description'}\n            url='http://www.163.com'\n          />\n          <QRCodePanel\n            {...{ ...rest }}\n            fgColor={'#fff'}\n            bgColor={'rgba(254, 164, 159, 0.38)'}\n            description='Ox123213123123'\n            url='http://www.163.com'\n            handleClick={() => {\n              console.log('click')\n            }}\n          />\n          {/*<WrapTransferPanel/>*/}\n          {/*<WrapDepositPanel/>*/}\n          {/*<WrapWithdrawPanel />*/}\n        </MemoryRouter>\n      </Style>\n    </>\n  )\n}) as Story<any>\n\n// @ts-ignore\nexport const ModalListStory = Template.bind({})\n\nexport default {\n  title: 'components/wallet_list',\n  component: ModalWalletConnect,\n  argTypes: {},\n} as Meta\n"
  },
  {
    "path": "packages/component-lib/src/components/panel/FilterMarketsPanel.tsx",
    "content": "import React from 'react'\nimport { Box, Tab, Tabs, Typography } from '@mui/material'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport SwipeableViews from 'react-swipeable-views'\nimport { useTheme } from '@emotion/react'\n\ninterface TabPanelProps {\n  children?: React.ReactNode\n  index: any\n  value: any\n}\n\nfunction TabPanel(props: TabPanelProps) {\n  const { children, value, index, ...other } = props\n\n  return (\n    <div\n      role='tabpanel'\n      hidden={value !== index}\n      id={`simple-tabpanel-${index}`}\n      aria-labelledby={`simple-tab-${index}`}\n      {...other}\n    >\n      {value === index && (\n        <Box p={3}>\n          <Typography>{children}</Typography>\n        </Box>\n      )}\n    </div>\n  )\n}\n\nexport const FilterMarketPanel = withTranslation('common')(({ t }: WithTranslation) => {\n  const [value, setValue] = React.useState(1)\n  const theme = useTheme()\n\n  const handleChange = (_event: any, newValue: any) => {\n    setValue(newValue)\n  }\n  const handleChangeIndex = (index: number) => {\n    setValue(index)\n  }\n  return (\n    <Box display={'flex'} flexDirection={'column'}>\n      <>\n        <Tabs value={value} onChange={handleChange} aria-label='tabs switch'>\n          <Tab label={t('labelAll')} />\n          <Tab label={t('labelFavorite')} />\n          <Tab label={'ETH'} />\n          <Tab label={'LRC'} />\n        </Tabs>\n        <SwipeableViews\n          axis={theme.direction === 'rtl' ? 'x-reverse' : 'x'}\n          index={value}\n          onChangeIndex={handleChangeIndex}\n        >\n          <TabPanel value={value} index={0}></TabPanel>\n          <TabPanel value={value} index={1}></TabPanel>\n          <TabPanel value={value} index={2}></TabPanel>\n          <TabPanel value={value} index={3}></TabPanel>\n        </SwipeableViews>\n      </>\n    </Box>\n  )\n})\n"
  },
  {
    "path": "packages/component-lib/src/components/panel/Panel.stories.tsx",
    "content": "import styled from '@emotion/styled'\nimport { Meta, Story } from '@storybook/react'\nimport { MemoryRouter } from 'react-router-dom'\nimport { Box, Grid } from '@mui/material'\nimport { FilterMarketPanel } from './FilterMarketsPanel'\n\nconst Style = styled.div`\n  background: var(--color-global-bg);\n\n  height: 100%;\n  flex: 1;\n`\nconst FilterMarketPanelWrap = () => {\n  return <FilterMarketPanel />\n}\n\nconst Template: Story<any> = () => {\n  return (\n    <Style>\n      <MemoryRouter initialEntries={['/']}>\n        <Box>\n          <h4>Panel</h4>\n          <Grid container spacing={2} alignContent={'center'} justifyContent={'space-around'}>\n            <FilterMarketPanelWrap />\n          </Grid>\n        </Box>\n      </MemoryRouter>\n    </Style>\n  )\n}\n\nexport default {\n  title: 'components/Panel',\n  component: FilterMarketPanel,\n  argTypes: {},\n} as Meta\n\nexport const PanelsStory = Template.bind({})\n"
  },
  {
    "path": "packages/component-lib/src/components/panel/index.ts",
    "content": "export * from './FilterMarketsPanel'\n"
  },
  {
    "path": "packages/component-lib/src/components/provider.tsx",
    "content": "import type { Provider as TProvider } from 'react'\n\nexport const provider = (Provider: TProvider<any>, props: any = {}) => [Provider, props]\n\n/**\n * @param providers  inner -> outer\n * @param children\n * @constructor\n * example\n *  <ProviderComposer  providers={[\n *     provider(LocalizationProvider,{dateAdapter:MomentUtils}),\n *     provider(I18nextProvider,{i18n}),\n *     provider(ThemeProvider),\n *   ]}>\n *     <App />\n *  </ProviderComposer>\n */\nexport const ProviderComposer = ({\n  providers,\n  children,\n}: {\n  providers: Array<[TProvider<any>, any]>\n  children: any\n}) => {\n  // @ts-ignore\n  return providers.reduce((children, [Provider, props]: [TProvider<any>, any]) => {\n    // @ts-ignore\n    return <Provider {...props}>{children}</Provider>\n  }, children)\n  // return children;\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/share/Interface.ts",
    "content": "import { SOCIAL_NAME_KEYS } from '@loopring-web/common-resources';\n\nexport type SocialButtonProps = {\n  /** Social Network Enum */\n  socialEnum: SOCIAL_NAME_KEYS\n  size?: number\n  sendShareEvent: (key: SOCIAL_NAME_KEYS) => void\n}\n\nexport type ShareProps = {\n  social: { [key in Partial<SOCIAL_NAME_KEYS>]: SocialButtonProps }\n  size: number\n  loading: boolean\n  imageUrl: string\n  direction?: 'row' | 'column'\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/share/components/SocialButton.tsx",
    "content": "import {\n  SOCIAL_COMPONENT_MAP,\n  // SOCIAL_NAME_KEYS,\n  // SOCIAL_WITH_TITLE,\n} from '@loopring-web/common-resources'\nimport { SocialButtonProps } from '../Interface';\nimport { Avatar } from '@mui/material';\n\n//\n// function getExtraSocialProps({\n//   message,\n//   socialEnum,\n// }: {\n//   message: string\n//   socialEnum: SOCIAL_NAME_KEYS\n// }) {\n//   if (!message) return {}\n//\n//   if (SOCIAL_WITH_TITLE.has(socialEnum)) {\n//     return { title: message }\n//   }\n//\n//   if (socialEnum === SOCIAL_NAME_KEYS.Facebook) {\n//     return { quote: message }\n//   }\n//\n//   return { body: message }\n// }\n\nexport const SocialButton = ({size, socialEnum, sendShareEvent}: SocialButtonProps) => {\n  const {SocialNetworkName, SocialIcon} = SOCIAL_COMPONENT_MAP[ socialEnum ]\n  return (\n    <Avatar\n      variant={'rounded'}\n      // sx={{background:}}\n      className={`shareSocialButton shareSocialButton--${SocialNetworkName}`}\n      onClick={() => sendShareEvent(socialEnum)}>\n      <SocialIcon\n        round\n        size={size}\n        className={`shareSocialIcon shareSocialIcon--${SocialNetworkName}`}\n      />\n    </Avatar>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/share/index.tsx",
    "content": "import styled from '@emotion/styled'\nimport { ShareProps } from './Interface'\nimport { Box, IconButton, Modal, Typography } from '@mui/material'\nimport {\n  DownloadIcon,\n  ExchangeIO,\n  shareDownload,\n  shareOnFacebook,\n  shareOnTwitter,\n  shareViaEmail,\n  SOCIAL_NAME_KEYS,\n  SoursURL,\n} from '@loopring-web/common-resources'\nimport { SocialButton } from './components/SocialButton'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport { ModalCloseButton } from '../basic-lib'\nimport { Carousel, CarouselItem } from '../carousel'\nimport React from 'react'\n\nconst StyleBox = styled(Box)`\n  .shareContainer {\n  }\n\n  .shareLoader {\n  }\n\n  .shareLabel {\n  }\n\n  .shareButtons {\n  }\n\n  .shareSocialButton {\n    background-color: initial;\n    cursor: pointer;\n  }\n\n  .shareSocialIcon {\n  }\n`\n\nexport const Share = ({ social, loading, size, direction = 'row' }: ShareProps) => {\n  return (\n    <StyleBox display={'flex'}>\n      {loading ? (\n        <Box\n          flex={1}\n          height={'100%'}\n          display={'flex'}\n          alignItems={'center'}\n          justifyContent={'center'}\n        >\n          <img\n            alt={'loading'}\n            className='loading-gif'\n            width='36'\n            src={`${SoursURL}images/loading-line.gif`}\n          />\n        </Box>\n      ) : (\n        <Box className={'shareContainer'}>\n          <Box className={'shareButtons'} display={'flex'} flexDirection={direction}>\n            {Object.keys(social).map(\n              (socialNetwork, index) =>\n                social[socialNetwork] && (\n                  <SocialButton\n                    key={index}\n                    socialEnum={social[socialNetwork].socialEnum}\n                    size={size}\n                    sendShareEvent={social[socialNetwork].sendShareEvent}\n                  />\n                ),\n            )}\n          </Box>\n        </Box>\n      )}\n    </StyleBox>\n  )\n}\nconst BoxStyle = styled(Box)`\n  background: var(--color-global-bg);\n\n  & {\n    background: var(--color-box);\n    border-radius: ${({ theme }) => theme.unit}px;\n    //border: 1px solid var(--color-box);\n    //cursor: pointer;\n  }\n\n  .btn-close {\n    svg {\n      height: var(--btn-icon-size);\n      width: var(--btn-icon-size);\n    }\n\n    margin-top: 0;\n    //transform: translateY(-50%) translateX(-50%);\n    //left: 50%;\n    top: ${({ theme }) => 2 * theme.unit}px;\n    right: ${({ theme }) => 1 * theme.unit}px;\n  }\n\n  .shareSocialButton {\n    margin: 0 ${({ theme }) => (1 / 2) * theme.unit}px;\n  }\n\n  .btn {\n    margin: 0 ${({ theme }) => (1 / 2) * theme.unit}px;\n    background: var(--color-primary);\n\n    &:hover {\n      background: var(--color-primary);\n    }\n  }\n`\nexport const ShareModal = withTranslation('common')(\n  ({\n    t,\n    open,\n    onClose,\n    loading,\n    imageList,\n    className = '',\n    onClick,\n    message = '',\n    ipfsProvides,\n    link = ExchangeIO,\n    ...rest\n  }: WithTranslation & {\n    open: boolean\n    onClose: (event: any) => void\n    onClick: (event: any) => void\n    className?: string\n    loading: boolean\n    imageList: CarouselItem[]\n    message: string\n    ipfsProvides: any\n    link\n  }) => {\n    const [selected, setSelected] = React.useState<number>(0)\n    const sendShareEvent = (SOCIAL_NAME: SOCIAL_NAME_KEYS | 'download') => {\n      if (imageList[selected]) {\n        switch (SOCIAL_NAME) {\n          case SOCIAL_NAME_KEYS.Facebook:\n            shareOnFacebook(message, imageList[selected].imageUrl, ipfsProvides.ipfs, link)\n            break\n          case SOCIAL_NAME_KEYS.Twitter:\n            shareOnTwitter(message, imageList[selected].imageUrl, ipfsProvides.ipfs, link)\n            break\n          case SOCIAL_NAME_KEYS.Email:\n            shareViaEmail(\n              message,\n              imageList[selected].imageUrl,\n              ipfsProvides.ipfs,\n              imageList[selected].width,\n              imageList[selected].height,\n            )\n            break\n          case 'download':\n            shareDownload(\n              imageList[selected].name ?? 'LoopringReferral.png',\n              imageList[selected].imageUrl,\n            )\n            break\n        }\n      }\n    }\n    return (\n      <Modal\n        open={open}\n        onClose={onClose}\n        aria-labelledby='modal-modal-title'\n        aria-describedby='modal-modal-description'\n      >\n        <BoxStyle\n          className={'MuiPaper-elevation2'}\n          // width={'var(--modal-width)'}\n          // height={'80vh'}\n          minHeight={'var(--modal-height)'}\n          // height={`calc(100vh - ${HEADER_HEIGHT}px)`}\n          position={'absolute'}\n          display={'flex'}\n          flexDirection={'column'}\n          top='50%'\n          left='50%'\n          sx={{\n            transform: 'translateY(-50%) translateX(-50%)',\n          }}\n        >\n          <ModalCloseButton className='btn-close' onClose={onClose} {...{ ...rest, t }} />\n          <Typography\n            textAlign={'center'}\n            paddingTop={3}\n            component={'h5'}\n            variant={'h4'}\n            color={'textPrimary'}\n          >\n            {t('labelShareReferralCode')}\n          </Typography>\n          <Box\n            alignItems={'stretch'}\n            display={'flex'}\n            paddingX={4}\n            flex={1}\n            width={'100%'}\n            flexDirection={'column'}\n            paddingY={3}\n            overflow={'scroll'}\n          >\n            <Carousel\n              selected={selected}\n              loading={loading}\n              imageList={imageList}\n              handleSelected={setSelected}\n            />\n            <Box\n              display={'flex'}\n              flexDirection={'row'}\n              justifyContent={'center'}\n              alignItems={'center'}\n            >\n              <Share\n                imageUrl={imageList[selected]?.imageUrl ?? ''}\n                loading={loading}\n                size={36}\n                social={\n                  {\n                    [SOCIAL_NAME_KEYS.Facebook]: {\n                      socialEnum: SOCIAL_NAME_KEYS.Facebook,\n                      sendShareEvent,\n                    },\n                    [SOCIAL_NAME_KEYS.Twitter]: {\n                      socialEnum: SOCIAL_NAME_KEYS.Twitter,\n                      sendShareEvent,\n                    },\n                    [SOCIAL_NAME_KEYS.WhatsApp]: {\n                      socialEnum: SOCIAL_NAME_KEYS.Email,\n                      sendShareEvent,\n                    },\n                  } as any\n                }\n              />\n              <IconButton\n                className={'btn'}\n                size={'large'}\n                onClick={() => {\n                  sendShareEvent('download')\n                }}\n              >\n                <DownloadIcon htmlColor={'var(--color-text-button)'} />\n              </IconButton>\n            </Box>\n          </Box>\n        </BoxStyle>\n      </Modal>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/styled.ts",
    "content": "import styled from '@emotion/styled'\nimport { Box, BoxProps, Grid, Typography } from '@mui/material'\nimport { css, Theme, useTheme } from '@emotion/react'\nimport { UpColor } from '@loopring-web/common-resources'\nimport { Button, ButtonProps } from './basic-lib'\nimport { useSettings } from '../stores'\n\n// @ts-ignore\nexport const boxLiner = (_props: { theme: Theme }) => css`\n  background: var(--color-box-linear);\n  border: 0.5px solid var(--color-border);\n  border-radius: ${_props.theme.unit}px;\n\n  textarea,\n  .coinInput-wrap,\n  .btnInput-wrap,\n  .MuiOutlinedInput-root {\n    background: var(--field-opacity);\n    border-color: var(--opacity);\n\n    :hover {\n      border-color: var(--color-border-hover);\n    }\n  }\n\n  .MuiToolbar-root .MuiButtonBase-root.outlined {\n    background-color: var(--field-opacity);\n  }\n`\nexport const TypographyStrong = styled(Typography)`\n  color: var(--color-secoundary);\n` as typeof Typography\nexport const TypographyGood = styled(Typography)`\n  color: var(--color-success);\n` as typeof Typography\nexport const TablePaddingX = (_props: { pLeft: number; pRight: number }) => {\n  const { unit } = useTheme()\n  const { isMobile } = useSettings()\n  return css`\n    .rdg-row,\n    .rdg-header-row {\n      .rdg-cell:first-of-type {\n        padding-left: ${unit * (isMobile ? 1 : 3)}px;\n      }\n\n      .rdg-cell:last-of-type {\n        padding-right: ${unit * (isMobile ? 1 : 3)}px;\n      }\n    }\n  `\n}\nexport const VipStyled = styled(Typography)`\n  margin-left: ${({ theme }) => theme.unit}px;\n  padding: ${({ theme }) => theme.unit / 4}px ${({ theme }) => theme.unit}px;\n  ${({ theme }) => theme.border.defaultFrame({ c_key: 'rgba(0,0,0,0)', d_R: 0.25 })};\n  background-color: var(--vip-bg);\n  height: 2rem;\n  color: var(--vip-text);\n` as typeof Typography\nexport const floatTag = ({ theme, custom }: any) => css`\n  .float-group {\n    font-weight: lighter;\n\n    .float-tag.float-increase {\n      color: ${custom.chg === UpColor.green ? theme.colorBase.success : theme.colorBase.error};\n    }\n\n    .float-tag.float-decrease {\n      color: ${custom.chg === UpColor.green ? theme.colorBase.error : theme.colorBase.success};\n    }\n\n    .float-tag.float-none {\n      color: ${theme.colorBase.textPrimary};\n    }\n  }\n`\nexport const AvatarIconPair = ({ theme }: any) => css`\n  .icon-next {\n    margin-left: -${theme.unit}px;\n  }\n`\nexport const baseTitleCss = ({ theme, custom }: any) => css`\n  height: 72px;\n\n  ${AvatarIconPair({ theme })}\n  h3.MuiTypography-root {\n    font-size: 1.6rem;\n    margin-left: ${theme.unit}px;\n    color: ${theme.colorBase.textSecondary};\n\n    .MuiTypography-root {\n      margin: 0 ${theme.unit / 4}px;\n    }\n\n    .next-coin {\n      color: ${theme.colorBase.textPrimary};\n    }\n  }\n\n  ${floatTag({ theme, custom })};\n\n  .float-chart {\n    margin-left: ${theme.unit}px;\n\n    .chart-change {\n      color: ${theme.colorBase.textSecondary};\n    }\n  }\n`\nexport const ButtonListRightStyled = styled(Grid)`\n  .MuiButton-root:not(:last-child) {\n    margin-right: ${({ theme }) => theme.unit}px;\n  }\n` as typeof Grid\nexport const modalContentBaseStyle = ({ theme }: any) => css`\n  &:focus-visible {\n    outline: 0;\n  }\n\n  display: flex;\n  flex-direction: column;\n  justify-content: space-between;\n  align-items: center;\n  position: absolute;\n  top: 50%;\n  left: 50%;\n  transform: translate(-50%, -50%);\n  padding-top: var(--toolbar-row-padding);\n  border: 0;\n  border-radius: ${theme.unit}px;\n`\nexport const ModelPanelStyle = styled(Box)`\n  ${({ theme }) => modalContentBaseStyle({ theme: theme })};\n  background: var(--color-pop-bg);\n` as typeof Box\n\nexport const SwitchPanelStyled: any = styled(Box)<\n  { _height?: number | string; _width?: number | string } & BoxProps\n>`\n  .MuiModal-root & {\n    .react-swipeable-view-container > div {\n      background: var(--opacity);\n    }\n\n    .container {\n      padding-bottom: 0;\n    }\n  }\n\n  .trade-panel {\n    .react-swipeable-view-container {\n      & > div {\n        padding: 0 ${({ theme }) => (theme.unit * 5) / 2}px ${({ theme }) => theme.unit * 5}px;\n\n        .container {\n          height: 100%;\n          padding-top: 0;\n        }\n      }\n    }\n  }\n\n  && {\n    ${({ theme }) => modalContentBaseStyle({ theme: theme })}\n    ${({ _height, _width, theme }) => `\n     \n      background: ${theme.colorBase.box};\n      .react-swipeable-view-container {\n           height: ${\n             _height && Number.isNaN(_height) ? _height + 'px' : _height ? _height : '100%'\n           } ;\n           width: ${_width && Number.isNaN(_width) ? _width + 'px' : _width ? _width : '100%'};\n           & > div{\n              height:initial;\n              overflow-x: hidden;\n              overflow-y: scroll !important;\n              background: initial;\n              scrollbar-width: none; /* Firefox */\n              -ms-overflow-style: none; /* Internet Explorer 10+ */\n              &::-webkit-scrollbar {\n                /* WebKit */\n                width: 0;\n              }\n           }\n       }\n      \n      .trade-panel{\n        .react-swipeable-view-container {\n           & > div{\n              height: calc(100% -  var(--toolbar-row-padding));\n              padding-bottom:0; \n              overflow-x: hidden;\n              overflow-y: scroll !important;\n              scrollbar-width: none; /* Firefox */\n              -ms-overflow-style: none; /* Internet Explorer 10+ */\n              &::-webkit-scrollbar {\n                /* WebKit */\n                width: 0;\n              }\n          }\n        }\n      }\n      \n    `}\n  }\n\n  &.collectionSelect {\n    background: var(--color-global-bg);\n    align-items: stretch;\n  }\n\n  .MuiModal-root & {\n    .coin-menu {\n      flex: 1;\n      height: 100%;\n    }\n  }\n` as (props: { _height?: number | string; _width?: number | string } & BoxProps) => JSX.Element\n// height:${\n//   _height\n//     ? typeof _height === \"number\"\n//       ? ` calc(${_height + \"px\"} - ${\n//           theme.unit * 4\n//         }px - 2 * var(--toolbar-row-padding)  ) `\n//       : ` calc(${_height} - ${\n//           theme.unit * 4\n//         }px - 2 * var(--toolbar-row-padding)  )`\n//     : \"410px\"\n// } !important;\n\nexport const toolBarPanel = ({ theme }: any) => css`\n  .MuiToolbar-root {\n    align-content: stretch;\n    justify-content: flex-end;\n    box-sizing: border-box;\n    height: var(--toolbar-row-padding-minus);\n    padding: 0 ${(theme.unit * 5) / 2}px;\n    margin-top: var(--toolbar-row-padding-minus);\n\n    .MuiIconButton-root {\n      height: var(--btn-icon-size);\n      width: var(--btn-icon-size);\n      min-width: var(--btn-icon-size);\n      margin: 0;\n      display: flex;\n      padding: 0;\n      justify-content: center;\n      justify-items: center;\n      align-items: center;\n      font-size: ${theme.fontDefault.h4};\n    }\n  }\n`\n\nexport const TableFilterStyled = styled(Box)`\n  margin: 0 ${({ theme }) => theme.unit * 3}px ${({ theme }) => theme.unit * 2}px;\n` as typeof Box\n\nexport const AnimationArrow = styled(Box)`\n  &.arrowCta {\n    transform-origin: center;\n    display: block;\n    height: 12px;\n    width: 12px;\n    border: 9px solid transparent;\n    transform: rotate(45deg) scale(0.5);\n    position: relative;\n    margin: ${({ theme }) => theme.unit * 2}px;\n  }\n\n  &.arrowCta:after,\n  &.arrowCta:before {\n    content: '';\n    display: block;\n    height: inherit;\n    width: inherit;\n    position: absolute;\n    top: 0;\n    left: 0;\n  }\n\n  &.arrowCta:after {\n    border-bottom: 3px solid var(--color-text-primary);\n    border-right: 3px solid var(--color-text-primary);\n    top: 0;\n    left: 0;\n    opacity: 1;\n    animation: bottom-arrow 1.65s infinite;\n  }\n\n  @keyframes bottom-arrow {\n    0% {\n      opacity: 1;\n      transform: translate(0, 0);\n    }\n    45% {\n      opacity: 0;\n      transform: translate(12px, 12px);\n    }\n    46% {\n      opacity: 0;\n      transform: translate(-16px, -16px);\n    }\n    90% {\n      opacity: 1;\n      transform: translate(-6px, -6px);\n    }\n    100% {\n      opacity: 1;\n      transform: translate(-6px, -6px);\n    }\n  }\n\n  &.arrowCta:before {\n    top: 0;\n    left: 0;\n    border-bottom: 3px solid var(--color-text-primary);\n    border-right: 3px solid var(--color-text-primary);\n    animation: top-arrow 1.65s infinite;\n  }\n\n  @keyframes top-arrow {\n    0% {\n      transform: translate(-6px, -6px);\n    }\n    35% {\n      transform: translate(0, 0);\n    }\n    90% {\n      opacity: 1;\n      transform: translate(0, 0);\n    }\n    100% {\n      opacity: 1;\n      transform: translate(0, 0);\n    }\n  }\n` as typeof Box\n\nexport const shake = css`\n  @keyframes shake {\n    10%,\n    90% {\n      transform: translate3d(-1px, 0, 0);\n    }\n    20%,\n    80% {\n      transform: translate3d(2px, 0, 0);\n    }\n    30%,\n    50%,\n    70% {\n      transform: translate3d(-4px, 0, 0);\n    }\n    40%,\n    60% {\n      transform: translate3d(4px, 0, 0);\n    }\n  }\n`\n\nexport const MenuBtnStyled = styled(Button)<ButtonProps>`\n  font-size: ${({ theme }) => theme.fontDefault.body1};\n  background: var(--opacity);\n  color: var(--color-text-secondary);\n  display: flex;\n\n  padding: 0 ${({ theme }) => theme.unit * 3}px;\n  text-indent: 0.5em;\n  position: relative;\n\n  &.addAsset,\n  &.sendAsset {\n    white-space: pre;\n    font-size: ${({ theme }) => theme.fontDefault.h5};\n    justify-content: space-between;\n    flex-direction: row;\n    height: 64px;\n\n    &.isMobile {\n      font-size: 14px;\n      height: 48px;\n    }\n  }\n\n  &.banxaEnter {\n    justify-content: space-between;\n  }\n  &.vaultBtn {\n    border: 0;\n    font-size: ${({ theme }) => theme.fontDefault.h5};\n    color: var(--color-text-primary);\n    justify-content: space-between;\n    .MuiButton-endIcon {\n      color: var(--color-text-Secondary);\n    }\n    &:hover {\n      .MuiButton-endIcon {\n        color: var(--color-primary);\n      }\n    }\n  }\n\n  &.redPacketType {\n    display: flex;\n    flex-direction: column;\n    align-items: flex-start;\n    height: ${({ theme }) => theme.unit * 18}px;\n    text-indent: 0em;\n    text-align: left;\n    padding: ${({ theme }) => theme.unit * 1.5}px ${({ theme }) => theme.unit * 2}px;\n    justify-content: flex-start;\n    .mainTitlte {\n    }\n  }\n\n  &.provider {\n    justify-content: space-between;\n    flex-direction: row;\n    white-space: pre;\n    color: var(--color-text-primary);\n    height: var(--provider-btn-height);\n\n    &:hover {\n      border: 1px solid var(--color-border-select);\n    }\n\n    &.Mui-disabled {\n      .MuiButton-endIcon {\n        color: var(--color-text-disable);\n      }\n    }\n\n    &.selected {\n      border: 1px solid var(--color-border-select);\n\n      &:after {\n        display: none;\n      }\n    }\n\n    &.MuiButton-root {\n      ${\n        // @ts-ignore\n        ({ loading, loadingbg, t }) => {\n          return loading === 'true'\n            ? `\n           pointer-events: none;    \n         \n       `\n            : ''\n        }\n      }\n    }\n\n    .loading {\n      font-size: ${({ theme }) => theme.fontDefault.body2};\n    }\n  }\n\n  &.vendor {\n    justify-content: center;\n    flex-direction: column;\n\n    & > .vendorName {\n      text-indent: -999em;\n      justify-content: center;\n    }\n  }\n\n  &:hover {\n    background: var(--provider-hover);\n    border-color: var(--color-border-select); \n    color: var(--color-text-button-select);\n  }\n\n  &.selected {\n    &.redPacketType {\n      border: 1px solid var(--color-border-select);\n\n      &:after {\n        display: none;\n      }\n    }\n\n    position: relative;\n    background: var(--provider-hover);\n    border-color: var(--opacity);\n    color: var(--color-text-button-select);\n\n    &:after {\n      position: absolute;\n      content: '\\u25CF';\n      text-indent: 0em;\n      color: var(--color-success);\n      display: flex;\n      left: 0;\n      padding-left: ${({ theme }) => (theme.unit * 3) / 2}px;\n      align-items: center;\n      font-size: ${({ theme }) => theme.fontDefault.h5};\n    }\n  }\n` as (props: ButtonProps) => JSX.Element\n\nexport const StyledPaperBg = styled(Box)`\n  background: var(--color-box-third);\n  border-radius: ${({ theme }) => theme.unit}px;\n` as any\n\nexport const MediaLabelStyled = styled(Box)<BoxProps & { colorbg?: string }>`\n  border-radius: 0 0 ${({ theme }) => theme.unit}px 0;\n  padding: ${({ theme }) => theme.unit / 2}px ${({ theme }) => theme.unit}px;\n  color: var(--color-box);\n  font-size: 1.4rem;\n  background: ${({ colorbg }) => (colorbg ? colorbg : 'var(--color-tag)')};\n  cursor: help;\n` as (props: BoxProps & { colorbg?: string }) => JSX.Element\n\nexport const BoxBannerStyle = styled(Box)<\n  BoxProps & { backGroundUrl?: string | number; direction?: 'left' | 'right' }\n>`\n  background-color: var(--color-box);\n\n  .bg:after {\n    display: block;\n    content: '';\n    float: ${({ direction }) => direction};\n    width: 35%;\n    background-repeat: no-repeat;\n    background-position: center;\n    background-size: contain;\n    background-image: url('${({ backGroundUrl }) => backGroundUrl}');\n  }\n\n  &.mobile .bg {\n    position: relative;\n    display: flex;\n    flex-direction: column;\n\n    &:after {\n      opacity: 0.08;\n      z-index: 1;\n      position: absolute;\n      top: 0;\n      width: 100%;\n      height: 100%;\n      pointer-events: none;\n    }\n  }\n` as (\n  props: BoxProps & {\n    backGroundUrl?: string | number\n    direction?: 'left' | 'right'\n  },\n) => JSX.Element\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/QuoteTable/MarketDetail.tsx",
    "content": "import { ChartType, ScaleAreaChart } from '../../charts'\nimport React from 'react'\nimport { Box, Button, Grid, Link, Typography } from '@mui/material'\nimport {\n  AmmHistoryItem,\n  CurrencyToTag,\n  EmptyValueTag,\n  ForexMap,\n  getValuePrecisionThousand,\n  PriceTag,\n  SoursURL,\n  SvgSize,\n  TokenType,\n  VaultSwapStep,\n} from '@loopring-web/common-resources'\nimport { Trans, useTranslation } from 'react-i18next'\nimport { CoinIcons } from '../assetsTable'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { useSettings } from '../../../stores'\nimport { QuoteTableChangedCell } from './QuoteTable'\nimport { ToggleButtonGroup } from '../../basic-lib'\nimport styled from '@emotion/styled'\n\nconst BgButton = styled(Button)<{ customBg: string }>`\n  background-color: ${({ customBg }) => customBg};\n  transition: all 0.2s ease-in-out;\n  &:hover {\n    background-color: ${({ customBg }) => customBg};\n    opacity: 0.8;\n  }\n  &:disabled {\n    background-color: var(--color-button-disabled);\n  }\n  \n`\n\nenum TradingInterval {\n  hr1 = 'hr1',\n  d1 = 'd1',\n  w1 = 'w1',\n  m1 = 'm1',\n}\nconst TimeMarketIntervalData = [\n  {\n    id: TradingInterval.hr1,\n    i18nKey: 'labelProTime1h',\n  },\n  {\n    id: TradingInterval.d1,\n    i18nKey: 'labelProTime1d',\n  },\n  {\n    id: TradingInterval.w1,\n    i18nKey: 'labelProTime1w',\n  },\n  {\n    id: TradingInterval.m1,\n    i18nKey: 'labelProTime1m',\n  },\n]\nenum TimeMarketIntervalDataIndex {\n  hr1,\n  d1,\n  w1,\n  m1,\n}\nexport const MarketDetail = ({\n  tokenInfo,\n  trends,\n  isShow,\n  forexMap,\n  etherscanBaseUrl,\n  isLoading,\n  timeIntervalData = TimeMarketIntervalData,\n  showBtns,\n  onClickBuy,\n  onClickSell\n}: {\n  tokenInfo\n  isLoading?: boolean\n  trends: any\n  isShow: boolean\n  forexMap: ForexMap\n  etherscanBaseUrl: string\n  timeIntervalData: typeof TimeMarketIntervalData\n  showBtns?: boolean\n  onClickBuy?: () => void\n  onClickSell?: () => void\n}) => {\n  const { t } = useTranslation()\n  const { coinJson, currency, upColor } = useSettings()\n  // const [data, setData] = React.useState([])\n  const [timeInterval, setTimeInterval] = React.useState(TradingInterval.hr1)\n  const [trend, setTrend] = React.useState<AmmHistoryItem[] | undefined>([])\n  const handleTimeIntervalChange = React.useCallback(\n    (timeInterval: TradingInterval) => {\n      setTimeInterval(timeInterval)\n      if (trends?.length) {\n        const _trends = trends[TimeMarketIntervalDataIndex[timeInterval]]\n        setTrend(_trends.map(trend => {\n          return {\n            ...trend,\n            change: sdk.toBig(trend.close).minus(_trends[_trends.length - 1].close).div(_trends[_trends.length - 1].close).multipliedBy(100).toFixed(2),\n          }\n        }))\n      }\n    },\n    [trends],\n  ) \n  const priceCall = React.useCallback(\n    (price: any) => {\n      const priceStr = sdk.toBig(price ?? 0).times(forexMap[currency])\n      return getValuePrecisionThousand(priceStr, 5, 4, 2, false, { isFait: true, floor: true })\n    },\n    [forexMap, currency],\n  )\n  \n  \n  React.useEffect(() => {\n    if (isShow && !isLoading) {\n      handleTimeIntervalChange(TradingInterval.hr1)\n    }\n  }, [isShow, isLoading])\n  return tokenInfo?.symbol ? (\n    <>\n      <Box\n        component={'header'}\n        display={'flex'}\n        flexDirection={'row'}\n        justifyContent={'space-between'}\n        width={'100%'}\n      >\n        <Box display={'flex'} flexDirection={'row'} alignItems={'center'}>\n          <Typography\n            paddingLeft={1}\n            component={'span'}\n            display={'inline-flex'}\n            width={\n              tokenInfo.type == TokenType.vault\n                ? (SvgSize.svgSizeHuge * 3) / 2\n                : SvgSize.svgSizeHuge\n            }\n          >\n            {/* eslint-disable-next-line react/jsx-no-undef */}\n            <CoinIcons\n              type={TokenType.single}\n              size={SvgSize.svgSizeHuge}\n              tokenIcon={[\n                coinJson[\n                  tokenInfo.type == TokenType.vault ? tokenInfo?.erc20Symbol : tokenInfo.symbol\n                ],\n              ]}\n            />\n          </Typography>\n          <Typography component={'span'} flexDirection={'column'} display={'flex'}>\n            <Typography\n              variant={'h4'}\n              component={'span'}\n              color={'var(--color-primary)'}\n              display={'inline-flex'}\n            >\n              {tokenInfo.type == TokenType.vault ? tokenInfo?.erc20Symbol : tokenInfo.symbol}\n            </Typography>\n            <Typography\n              component={'span'}\n              display={'inline-flex'}\n              variant={'body1'}\n              color={'textPrimary'}\n              height={'21px'}\n            >\n              {tokenInfo.name}\n            </Typography>\n          </Typography>\n        </Box>\n        <Typography\n          display={'flex'}\n          flexDirection={'column'}\n          justifyContent={'space-between'}\n          alignItems={'flex-end'}\n        >\n          <Typography component={'span'} display={'inline-flex'}>\n            {PriceTag[CurrencyToTag[currency]] + priceCall(tokenInfo.price)}\n          </Typography>\n          <QuoteTableChangedCell value={tokenInfo.percentChange24H} upColor={upColor}>\n            {typeof tokenInfo.percentChange24H !== 'undefined'\n              ? (sdk.toBig(tokenInfo.percentChange24H).gt(0) ? '+' : '') +\n                getValuePrecisionThousand(tokenInfo.percentChange24H, 2, 2, 2, true) +\n                '%'\n              : EmptyValueTag}\n          </QuoteTableChangedCell>\n        </Typography>\n      </Box>\n      <Box\n        width={'100%'}\n        display={'flex'}\n        alignItems={'center'}\n        justifyContent={'center'}\n        marginTop={2}\n        // height={\"60%\"}\n        height={'calc(var(--swap-box-height) - 262px)'}\n        sx={{\n          minHeight: '300px',\n        }}\n        // minHeight={420}\n      >\n        {!trend?.length ? (\n          <img\n            className='loading-gif'\n            alt={'loading'}\n            width='36'\n            src={`${SoursURL}images/loading-line.gif`}\n          />\n        ) : (\n          <ScaleAreaChart\n            showXAxis={true}\n            showYAxis={true}\n            type={ChartType.Trend}\n            data={trend}\n            quoteSymbol={'USDT'}\n            showCartesianGrid\n            showClose={false}\n          />\n        )}\n      </Box>\n      <Grid\n        container\n        spacing={1}\n        marginRight={1}\n        minWidth={296}\n        justifyContent={'center'}\n        marginTop={1}\n      >\n        <ToggleButtonGroup\n          size={'medium'}\n          exclusive\n          {...{\n            ...t,\n            value: timeInterval,\n            onChange: (_, value) => {\n              handleTimeIntervalChange(value)\n            },\n            data: timeIntervalData.map((item) => {\n              return {\n                value: item.id,\n                key: item.i18nKey,\n              }\n            }),\n          }}\n        />\n      </Grid>\n      <Box\n        display={'flex'}\n        flexDirection={'column'}\n        alignItems={'stretch'}\n        justifyContent={'space-between'}\n        width={'100%'}\n        marginTop={2}\n        paddingX={2}\n        paddingY={1}\n        borderRadius={1 / 2}\n        sx={{\n          background: 'var(--field-opacity)',\n        }}\n      >\n        <Typography component={'p'} variant={'h5'}>\n          {t('labelStats')}\n        </Typography>\n        <Typography\n          component={'p'}\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {t('label24Volume')}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {tokenInfo.volume24H\n              ? PriceTag[CurrencyToTag[currency]] +\n                getValuePrecisionThousand(tokenInfo.volume24H, 2, 2, 2, false, {\n                  isAbbreviate: false,\n                  abbreviate: 6,\n                })\n              : EmptyValueTag}\n          </Typography>\n        </Typography>\n        <Typography\n          component={'p'}\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {t('label24PriceChange')}\n          </Typography>\n          <QuoteTableChangedCell value={tokenInfo.percentChange24H} upColor={upColor}>\n            {typeof tokenInfo.percentChange24H !== 'undefined'\n              ? (sdk.toBig(tokenInfo.percentChange24H).gt(0) ? '+' : '') +\n                getValuePrecisionThousand(tokenInfo.percentChange24H, 2, 2, 2, true) +\n                '%'\n              : EmptyValueTag}\n          </QuoteTableChangedCell>\n        </Typography>\n\n        <Typography\n          component={'p'}\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {t('label7dPriceChange')}\n          </Typography>\n\n          <QuoteTableChangedCell value={tokenInfo.percentChange7D} upColor={upColor}>\n            {typeof tokenInfo.percentChange7D !== 'undefined'\n              ? (sdk.toBig(tokenInfo.percentChange7D).gt(0) ? '+' : '') +\n                getValuePrecisionThousand(tokenInfo.percentChange7D, 2, 2, 2, true) +\n                '%'\n              : EmptyValueTag}\n          </QuoteTableChangedCell>\n        </Typography>\n      </Box>\n      <Box\n        display={'flex'}\n        flexDirection={'column'}\n        alignItems={'stretch'}\n        justifyContent={'space-between'}\n        width={'100%'}\n        marginTop={2}\n        paddingX={2}\n        paddingY={1}\n        borderRadius={1 / 2}\n        sx={{\n          background: 'var(--field-opacity)',\n        }}\n      >\n        <Typography component={'p'} variant={'h5'}>\n          {t('labelTokenInfo')}\n        </Typography>\n        <Typography\n          component={'p'}\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {t('labelMarketCap')}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {tokenInfo.marketCap\n              ? PriceTag[CurrencyToTag[currency]] +\n                getValuePrecisionThousand(tokenInfo.marketCap, 2, 2, 2, false, {\n                  isAbbreviate: false,\n                  abbreviate: 6,\n                })\n              : EmptyValueTag}\n          </Typography>\n        </Typography>\n\n        <Typography\n          component={'p'}\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {t('labelTokenSupply')}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {tokenInfo.totalSupply !== 'undefined'\n              ? getValuePrecisionThousand(tokenInfo.totalSupply, 2, 2, 2, false, {\n                  isAbbreviate: false,\n                  abbreviate: 6,\n                })\n              : EmptyValueTag}\n          </Typography>\n        </Typography>\n        <Typography\n          component={'p'}\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n          alignItems={'center'}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {t('labelTokenContractAddress')}\n          </Typography>\n          <Link\n            width={'60%'}\n            display={'inline-flex'}\n            sx={{ wordBreak: 'break-all' }}\n            paddingLeft={1}\n            rel='noopener noreferrer'\n            href={tokenInfo.tokenAddress ? `${etherscanBaseUrl}address/${tokenInfo.tokenAddress}` : undefined}\n            target={'_top'}\n            justifyContent={'flex-end'}\n          >\n            {tokenInfo.tokenAddress ? tokenInfo.tokenAddress : EmptyValueTag}\n          </Link>\n        </Typography>\n        <Typography\n          component={'p'}\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {t('labelTokenWebsite')}\n          </Typography>\n          <Link\n            paddingLeft={2}\n            width={'60%'}\n            display={'inline-flex'}\n            sx={{ wordBreak: 'break-all' }}\n            rel='noopener noreferrer'\n            component={'a'}\n            href={tokenInfo.website}\n            target={'_top'}\n            justifyContent={'flex-end'}\n          >\n            {tokenInfo.website}\n          </Link>\n        </Typography>\n      </Box>\n      <Box\n        display={'flex'}\n        flexDirection={'column'}\n        alignItems={'stretch'}\n        justifyContent={'space-between'}\n        width={'100%'}\n        marginTop={2}\n        paddingX={2}\n        paddingY={1}\n        borderRadius={1 / 2}\n        sx={{\n          background: 'var(--field-opacity)',\n        }}\n      >\n        <Typography component={'p'} variant={'h5'}>\n          {t('labelTokenIntroduce')}\n        </Typography>\n        {tokenInfo.type == TokenType.vault ? (\n          <Typography\n            component={'p'}\n            display={'inline-flex'}\n            justifyContent={'space-between'}\n            marginTop={2}\n          >\n            <Trans\n              i18nKey={'labelTokenVaultDes'}\n              tOptions={{\n                symbol: tokenInfo.erc20Symbol,\n                vSymbol: tokenInfo.symbol,\n              }}\n            >\n              {tokenInfo.symbol} is a token backed 1:1 with {tokenInfo.erc20Symbol}, bringing\n              greater liquidity to Loopring DEX.\n            </Trans>\n          </Typography>\n        ) : (\n          <></>\n        )}\n        \n      </Box>\n      {showBtns && <Box mt={3}>\n        <BgButton onClick={onClickBuy}  sx={{ borderRadius: '4px'}} fullWidth customBg={'var(--color-success)'} variant='contained'>\n          Buy / Long\n        </BgButton>\n        <BgButton onClick={onClickSell} sx={{mt: 2, borderRadius: '4px'}} fullWidth customBg={'var(--color-error)'} variant='contained'>\n          Sell / Short\n        </BgButton>\n      </Box>}\n    </>\n  ) : (\n    <></>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/QuoteTable/MarketTable.tsx",
    "content": "import styled from '@emotion/styled'\nimport { Box, IconButton, Typography } from '@mui/material'\nimport { withTranslation, WithTranslation } from 'react-i18next'\nimport { RouteComponentProps, withRouter } from 'react-router-dom'\nimport {\n  Account,\n  CAMPAIGNTAGCONFIG,\n  CurrencyToTag,\n  EmptyValueTag,\n  ForexMap,\n  getValuePrecisionThousand,\n  PriceTag,\n  RowConfig,\n  RowConfigType,\n  SCENARIO,\n  StarHollowIcon,\n  StarSolidIcon,\n  TickerNew,\n  TokenType,\n} from '@loopring-web/common-resources'\nimport { useSettings } from '../../../stores'\nimport { Button, Column, Table } from '../../basic-lib'\nimport { TablePaddingX } from '../../styled'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport React from 'react'\nimport { TagIconList } from '../../block'\nimport { QuoteTableChangedCell } from './QuoteTable'\nimport { CoinIcons } from '../assetsTable'\n\nconst TableWrapperStyled = styled(Box)`\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n  height: 100%;\n  ${({ theme }) => TablePaddingX({ pLeft: theme.unit * 3, pRight: theme.unit * 3 })}\n`\n\nconst TableStyled = styled(Table)`\n  &.rdg {\n    height: ${(props: any) => {\n      if (props.ispro === 'pro') {\n        return '620px'\n      }\n      if (props.currentheight && props.currentheight > 350) {\n        return props.currentheight + 'px'\n      } else {\n        return '100%'\n      }\n    }};\n\n    --template-columns: ${({ ispro, isMobile }: any) =>\n      ispro || isMobile ? '35% 44% auto' : '30% 30% 30% 10%'} !important;\n\n    .rdg-cell.action {\n      display: flex;\n      justify-content: center;\n      align-items: center;\n    }\n  }\n\n  .textAlignRight {\n    text-align: right;\n\n    .rdg-header-sort-cell {\n      justify-content: flex-end;\n    }\n  }\n  .textAlignLeft {\n    text-align: left;\n\n    .rdg-header-sort-cell {\n      justify-content: flex-start;\n    }\n  }\n\n  .textAlignCenter {\n    text-align: center;\n  }\n` as any\n\nexport interface MarketTableProps<R> {\n  rawData: R[]\n  rowConfig: RowConfigType\n  onItemClick?: (item: R) => void\n  onRowClick?: (item: R) => void\n  campaignTagConfig: CAMPAIGNTAGCONFIG\n  hiddenFav?: boolean\n  actionEle?: JSX.Element\n  // headerRowHeight?: number\n  onVisibleRowsChange?: (startIndex: number) => void\n  account: Account\n  favoriteMarket: string[]\n  handleStartClick: (pair: string, index?: number) => void\n  // addFavoriteMarket: (pair: string) => void\n  // removeFavoriteMarket: (pair: string) => void\n  currentheight?: number\n  showLoading?: boolean\n  isPro?: boolean\n  forexMap: ForexMap<sdk.Currency>\n}\n\nexport const MarketTable = withTranslation('tables')(\n  withRouter(\n    <R = TickerNew & { isFavorite?: boolean },>({\n      t,\n      currentheight = 350,\n      rowConfig = RowConfig,\n      onVisibleRowsChange,\n      campaignTagConfig,\n      rawData,\n      history,\n      onRowClick,\n      favoriteMarket,\n      handleStartClick,\n      hiddenFav = false,\n      actionEle = (row) => {\n        return (\n          <Button\n            variant='outlined'\n            onClick={() => {\n              onItemClick && onItemClick(row)\n            }}\n          >\n            {t('labelDetail')}\n          </Button>\n        )\n      },\n      // addFavoriteMarket,\n      // removeFavoriteMarket,\n      showLoading,\n      account,\n      forexMap,\n      isPro = false,\n      onItemClick,\n      ...rest\n    }: MarketTableProps<R> & WithTranslation & RouteComponentProps) => {\n      const { currency, isMobile, coinJson, upColor } = useSettings()\n      // const handleStartClick = (\n      //   event: React.MouseEvent<HTMLDivElement, MouseEvent>,\n      //   isFavourite: boolean,\n      //   pair: string,\n      // ): void => {\n      //   event.stopPropagation()\n      //   if (isFavourite) {\n      //     dispatch(removeFavoriteMarket(pair))\n      //   } else {\n      //     dispatch(addFavoriteMarket(pair))\n      //   }\n      // }\n      const priceCall = React.useCallback(\n        (price: any) => {\n          const priceStr = sdk.toBig(price ?? 0).times(forexMap[currency])\n          return getValuePrecisionThousand(priceStr, 5, 4, 2, false, {\n            isFait: true,\n            floor: true,\n          })\n        },\n        [forexMap, currency],\n      )\n      const getColumnMode = React.useCallback((): Column<R, unknown>[] => {\n        const basicRender = [\n          {\n            key: 'pair',\n            name: t('labelTxToken'),\n            sortable: true,\n            formatter: ({ row, rowIdx }: any) => {\n              // const isFavourite = favoriteMarket?.includes(row.symbol)\n              const symbol = row?.type === TokenType.vault ? row.erc20Symbol : row.symbol\n              let tokenIcon: [any, any] = [coinJson[symbol], undefined]\n              return (\n                <Box\n                  className='rdg-cell-value'\n                  display={'flex'}\n                  alignItems={'center'}\n                  height={'100%'}\n                >\n                  {!hiddenFav ? (\n                    <Typography marginRight={1} marginLeft={-2}>\n                      <IconButton\n                        style={{ color: 'var(--color-star)' }}\n                        size={'large'}\n                        onClick={(e) => {\n                          e.stopPropagation()\n                          handleStartClick(row.symbol, rowIdx)\n                        }}\n                      >\n                        {row.isFavorite ? (\n                          <StarSolidIcon cursor={'pointer'} />\n                        ) : (\n                          <StarHollowIcon cursor={'pointer'} />\n                        )}\n                      </IconButton>\n                    </Typography>\n                  ) : (\n                    <></>\n                  )}\n                  <CoinIcons type={TokenType.single} tokenIcon={tokenIcon} />\n                  <Typography marginLeft={1} component={'span'}>\n                    {symbol}\n                  </Typography>\n                  &nbsp;\n                  {campaignTagConfig && (\n                    <TagIconList\n                      campaignTagConfig={campaignTagConfig}\n                      symbol={row.symbol}\n                      scenario={\n                        row?.token?.type === TokenType.vault ? SCENARIO.VAULT : SCENARIO.MARKET\n                      }\n                    />\n                  )}\n                </Box>\n              )\n            },\n          },\n          {\n            key: 'price',\n            name: t('labelQuotaLastPrice'),\n            headerCellClass: 'textAlignLeft',\n            cellClass: 'textAlignLeft',\n            sortable: true,\n            formatter: ({ row }: any) => {\n              return (\n                <Typography\n                  className='rdg-cell-value'\n                  display={'inline-flex'}\n                  alignItems={'center'}\n                  whiteSpace={isMobile ? 'pre-line' : 'pre'}\n                  justifyContent={isMobile ? 'flex-end' : 'flex-start'}\n                >\n                  {PriceTag[CurrencyToTag[currency]] + priceCall(row.price)}\n                </Typography>\n              )\n            },\n          },\n          {\n            key: 'change',\n            name: t(isMobile ? 'labelQuota24hChangeLit' : 'labelQuota24hChange'),\n            sortable: true,\n            headerCellClass: isMobile ? 'textAlignRight' : 'textAlignLeft',\n            cellClass: isMobile ? 'textAlignRight' : 'textAlignLeft',\n            formatter: ({ row }: any) => {\n              const value = row.percentChange24H\n              return (\n                <div className={isMobile ? 'rdg-cell-value textAlignRight' : 'rdg-cell-value textAlignLeft'}>\n                  <QuoteTableChangedCell value={value} upColor={upColor}>\n                    {typeof value !== 'undefined'\n                      ? (sdk.toBig(value).gt(0) ? '+' : '') +\n                        getValuePrecisionThousand(value, 2, 2, 2, true) +\n                        '%'\n                      : EmptyValueTag}\n                  </QuoteTableChangedCell>\n                </div>\n              )\n            },\n          },\n        ]\n        const extraRender = [\n          {\n            key: 'volume',\n            name: t('labelQuota24hAmount'),\n            headerCellClass: 'textAlignRight',\n            // resizable: true,\n            sortable: true,\n            formatter: ({ row }: any) => {\n              return (\n                <div className='rdg-cell-value textAlignRight'>\n                  {row.volume24H\n                    ? getValuePrecisionThousand(\n                        row.volume24H,\n                        row.precision,\n                        row.precision,\n                        row.precision,\n                        false,\n                        { isAbbreviate: true, abbreviate: 6 },\n                      )\n                    : EmptyValueTag}\n                </div>\n              )\n            },\n          },\n        ]\n        // const isMobile = [];\n        if (isMobile) {\n          return [...basicRender]\n        }\n        if (isPro) {\n          return [...basicRender]\n        }\n\n        return [...basicRender, ...extraRender]\n      }, [\n        campaignTagConfig,\n        currency,\n        favoriteMarket,\n        forexMap,\n        handleStartClick,\n        history,\n        isMobile,\n        isPro,\n        t,\n        upColor,\n      ])\n\n      const defaultArgs: any = {\n        rawData: [],\n        columnMode: getColumnMode(),\n        generateRows: (rawData: any) => rawData,\n        onRowClick: onRowClick,\n        generateColumns: ({ columnsRaw }: any) => columnsRaw as Column<R, unknown>[],\n        sortMethod: (sortedRows, sortColumn) => {\n          switch (sortColumn) {\n            case 'pair':\n              sortedRows = sortedRows.sort((a, b) => {\n                return a.symbol?.localeCompare(b.symbol)\n              })\n              break\n            case 'price':\n              sortedRows = sortedRows.sort((a, b) => {\n                const [valueA, valueB] = [a.price, b.price]\n                if (a.price && b.price) {\n                  return valueB - valueA\n                }\n                if (valueA && !valueB) {\n                  return -1\n                }\n                if (!valueA && valueB) {\n                  return 1\n                }\n                return 0\n              })\n              break\n            case 'change':\n              sortedRows = sortedRows.sort((a, b) => {\n                const [valueA, valueB] = [a.percentChange24H, b.percentChange24H]\n                if (valueA && valueB) {\n                  return valueB - valueA\n                }\n                if (valueA && !valueB) {\n                  return -1\n                }\n                if (!valueA && valueB) {\n                  return 1\n                }\n                return 0\n              })\n              break\n            case 'volume':\n              sortedRows = sortedRows.sort((a, b) => {\n                // const valueA = a['volume24H']\n                // const valueB = b['volume']\n                const [valueA, valueB] = [a.volume24H, b.volume24H]\n\n                if (valueA && valueB) {\n                  return valueB - valueA\n                }\n                if (valueA && !valueB) {\n                  return -1\n                }\n                if (!valueA && valueB) {\n                  return 1\n                }\n                return 0\n              })\n              break\n            default:\n              return sortedRows\n          }\n          return sortedRows\n        },\n        sortDefaultKey: 'change',\n      }\n\n      return (\n        <TableWrapperStyled>\n          <TableStyled\n            isMobile={isMobile}\n            currentheight={currentheight}\n            ispro={isPro}\n            className={'scrollable'}\n            onRowClick={onRowClick}\n            {...{\n              ...defaultArgs,\n              ...rest,\n              onVisibleRowsChange,\n              rawData,\n              ...rowConfig,\n              showloading: showLoading,\n            }}\n          />\n        </TableWrapperStyled>\n      )\n    },\n  ),\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/QuoteTable/QuoteTable.tsx",
    "content": "import styled from '@emotion/styled'\nimport { Box, Button, IconButton, Typography } from '@mui/material'\nimport { withTranslation, WithTranslation } from 'react-i18next'\nimport { RouteComponentProps, withRouter } from 'react-router-dom'\nimport {\n  Account,\n  CAMPAIGNTAGCONFIG,\n  CurrencyToTag,\n  EmptyValueTag,\n  FloatTag,\n  ForexMap,\n  getValuePrecisionThousand,\n  PriceTag,\n  RowConfig,\n  SCENARIO,\n  StarHollowIcon,\n  StarSolidIcon,\n  Ticker,\n} from '@loopring-web/common-resources'\nimport { Column, Table } from '../../basic-lib'\nimport { TablePaddingX } from '../../styled'\nimport { useSettings } from '@loopring-web/component-lib/src/stores'\nimport { useDispatch } from 'react-redux'\nimport { Currency } from '@loopring-web/loopring-sdk'\nimport React from 'react'\nimport { TagIconList } from '../../block'\n\nconst TableWrapperStyled = styled(Box)`\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n  height: 100%;\n  ${({ theme }) => TablePaddingX({ pLeft: theme.unit * 3, pRight: theme.unit * 3 })}\n`\n\nconst TableStyled = styled(Table)`\n  &.rdg {\n    height: ${(props: any) => {\n      if (props.ispro === 'pro') {\n        return '620px'\n      }\n      if (props.currentheight && props.currentheight > 350) {\n        return props.currentheight + 'px'\n      } else {\n        return '100%'\n      }\n    }};\n\n    --template-columns: ${({ ispro, isMobile }: any) =>\n      ispro || isMobile ? '35% 44% auto' : '240px 220px 100px auto auto auto 132px'} !important;\n\n    .rdg-cell.action {\n      display: flex;\n      justify-content: center;\n      align-items: center;\n    }\n  }\n\n  .textAlignRight {\n    text-align: right;\n\n    .rdg-header-sort-cell {\n      justify-content: flex-end;\n    }\n  }\n\n  .textAlignCenter {\n    text-align: center;\n  }\n` as any\n\nexport type QuoteTableRawDataItem = Ticker & {\n  pair: {\n    coinA: string\n    coinB: string\n  }\n  floatTag: keyof typeof FloatTag\n  coinApriceU: number\n  precision?: number\n  reward?: number\n  rewardToken?: string\n  timeUnit?: '24h'\n}\n\nexport const QuoteTableChangedCell: any = styled.span`\n  color: ${({ theme: { colorBase }, upColor, value }: any) => {\n    const isUpColorGreen = upColor === 'green'\n    return value > 0\n      ? isUpColorGreen\n        ? colorBase.success\n        : colorBase.error\n      : value < 0\n      ? isUpColorGreen\n        ? colorBase.error\n        : colorBase.success\n      : colorBase.textPrimary\n  }};\n`\n\nexport interface QuoteTableProps {\n  rawData: QuoteTableRawDataItem[]\n  rowHeight?: number\n  campaignTagConfig: CAMPAIGNTAGCONFIG\n  headerRowHeight?: number\n  onVisibleRowsChange?: (startIndex: number) => void\n  onRowClick?: (row: QuoteTableRawDataItem, column: any) => void\n  account: Account\n  favoriteMarket: string[]\n  addFavoriteMarket: (pair: string) => void\n  removeFavoriteMarket: (pair: string) => void\n  currentheight?: number\n  showLoading?: boolean\n  isPro?: boolean\n  forexMap: ForexMap<Currency>\n}\n\nexport const QuoteTable = withTranslation('tables')(\n  withRouter(\n    ({\n      t,\n      currentheight = 350,\n      rowHeight = RowConfig.rowHeight,\n      headerRowHeight = RowConfig.rowHeaderHeight,\n      onVisibleRowsChange,\n      campaignTagConfig,\n      rawData,\n      history,\n      onRowClick,\n      favoriteMarket,\n      addFavoriteMarket,\n      removeFavoriteMarket,\n      showLoading,\n      account,\n      forexMap,\n      isPro = false,\n      ...rest\n    }: QuoteTableProps & WithTranslation & RouteComponentProps) => {\n      let userSettings = useSettings()\n      const upColor = userSettings?.upColor\n      const { currency, isMobile } = userSettings\n      const handleStartClick = (\n        event: React.MouseEvent<HTMLDivElement, MouseEvent>,\n        isFavourite: boolean,\n        pair: string,\n      ): void => {\n        event.stopPropagation()\n        if (isFavourite) {\n          dispatch(removeFavoriteMarket(pair))\n        } else {\n          dispatch(addFavoriteMarket(pair))\n        }\n      }\n      const getColumnMode = React.useCallback((): Column<QuoteTableRawDataItem, unknown>[] => {\n        const basicRender = [\n          {\n            key: 'pair',\n            name: t('labelQuotaPair'),\n            sortable: true,\n            formatter: ({ row }: any) => {\n              const { coinA, coinB } = row['pair']\n              const pair = `${coinA}-${coinB}`\n              const isFavourite = favoriteMarket?.includes(pair)\n              return (\n                <Box\n                  className='rdg-cell-value'\n                  display={'flex'}\n                  alignItems={'center'}\n                  height={'100%'}\n                >\n                  <Typography marginRight={1} marginLeft={-2}>\n                    <IconButton\n                      style={{ color: 'var(--color-star)' }}\n                      size={'large'}\n                      onClick={(e: any) => handleStartClick(e, isFavourite, pair)}\n                    >\n                      {isFavourite ? (\n                        <StarSolidIcon cursor={'pointer'} />\n                      ) : (\n                        <StarHollowIcon cursor={'pointer'} />\n                      )}\n                    </IconButton>\n                  </Typography>\n                  <Typography component={'span'}>\n                    {coinA}\n                    <Typography component={'span'} color={'textSecondary'}>\n                      /{coinB}\n                    </Typography>\n                  </Typography>\n                  &nbsp;\n                  {campaignTagConfig && (\n                    <TagIconList\n                      campaignTagConfig={campaignTagConfig}\n                      symbol={pair}\n                      scenario={SCENARIO.MARKET}\n                    />\n                  )}\n                </Box>\n              )\n            },\n          },\n          {\n            key: 'close',\n            name: t('labelQuotaLastPrice'),\n            headerCellClass: 'textAlignRight',\n            cellClass: 'textAlignRight',\n            sortable: true,\n            formatter: ({ row }: any) => {\n              const value = row.close\n              const precision = row['precision'] || 6\n              const price = Number.isFinite(value)\n                ? getValuePrecisionThousand(value, undefined, undefined, precision, true, {\n                    isPrice: true,\n                  })\n                : EmptyValueTag\n\n              const faitPrice = Number.isFinite(value)\n                ? PriceTag[CurrencyToTag[currency]] +\n                  getValuePrecisionThousand(\n                    row.coinApriceU * (forexMap[currency] ?? 0),\n                    undefined,\n                    undefined,\n                    2,\n                    true,\n                    {\n                      isFait: true,\n                    },\n                  )\n                : EmptyValueTag\n              return (\n                <Typography\n                  className='rdg-cell-value'\n                  display={'inline-flex'}\n                  alignItems={'center'}\n                  whiteSpace={isMobile ? 'pre-line' : 'pre'}\n                  justifyContent={isMobile ? 'flex-end' : 'flex-start'}\n                >\n                  <Typography component={'span'} variant={'inherit'}>\n                    {price}\n                  </Typography>\n                  <Typography\n                    component={'span'}\n                    variant={isMobile ? 'body2' : 'body1'}\n                    color={'var(--color-text-third)'}\n                  >\n                    {'/'}\n                    {faitPrice}\n                  </Typography>\n                </Typography>\n              )\n            },\n          },\n          {\n            key: 'change',\n            name: t(isMobile ? 'labelQuota24hChangeLit' : 'labelQuota24hChange'),\n            sortable: true,\n            headerCellClass: 'textAlignCenter',\n            formatter: ({ row }: any) => {\n              const value = row.change\n              return (\n                <div className='rdg-cell-value textAlignRight'>\n                  <QuoteTableChangedCell value={value} upColor={upColor}>\n                    {typeof value !== 'undefined'\n                      ? (row.floatTag === FloatTag.increase ? '+' : '') +\n                        getValuePrecisionThousand(value, 2, 2, 2, true) +\n                        '%'\n                      : EmptyValueTag}\n                  </QuoteTableChangedCell>\n                </div>\n              )\n            },\n          },\n        ]\n        const extraRender = [\n          {\n            key: 'high',\n            name: t('labelQuota24hHigh'),\n            headerCellClass: 'textAlignRight',\n            formatter: ({ row, column }: any) => {\n              const value = row[column.key]\n              const precision = row.precision || 6\n              const price = Number.isFinite(value)\n                ? getValuePrecisionThousand(value, undefined, undefined, precision, true, {\n                    isPrice: true,\n                  })\n                : EmptyValueTag\n              return (\n                <div className='rdg-cell-value textAlignRight'>\n                  <span>{price}</span>\n                </div>\n              )\n            },\n          },\n          {\n            key: 'low',\n            name: t('labelQuota24hLow'),\n            headerCellClass: 'textAlignRight',\n            formatter: ({ row, column }: any) => {\n              const value = row[column.key]\n              const precision = row.precision || 6\n              const price = Number.isFinite(value)\n                ? getValuePrecisionThousand(value, undefined, undefined, precision, true, {\n                    isPrice: true,\n                  })\n                : EmptyValueTag\n              return (\n                <div className='rdg-cell-value textAlignRight'>\n                  <span>{price}</span>\n                </div>\n              )\n            },\n          },\n          {\n            key: 'volume',\n            name: t('labelQuota24hAmount'),\n            headerCellClass: 'textAlignRight',\n            // resizable: true,\n            sortable: true,\n            formatter: ({ row }: any) => {\n              const value = row.volume\n              const precision = row.volume || 6\n              const price =\n                value && value !== '0'\n                  ? getValuePrecisionThousand(value, precision, undefined, undefined, true, {\n                      isTrade: true,\n                    })\n                  : EmptyValueTag\n              return (\n                <div className='rdg-cell-value textAlignRight'>\n                  <span>{price}</span>\n                </div>\n              )\n            },\n          },\n          {\n            key: 'actions',\n            headerCellClass: 'textAlignCenter',\n            name: t('labelQuoteAction'),\n            formatter: ({ row }: any) => {\n              const { coinA, coinB } = row['pair']\n              const tradePair = `${coinA}-${coinB}`\n              return (\n                <div className='rdg-cell-value textAlignCenter'>\n                  <Button\n                    variant='outlined'\n                    onClick={() =>\n                      history.push({\n                        pathname: `/trade/lite/${tradePair}`,\n                      })\n                    }\n                  >\n                    {t('labelTrade')}\n                  </Button>\n                </div>\n              )\n            },\n          },\n        ]\n        // const isMobile = [];\n        if (isMobile) {\n          return [...basicRender]\n        }\n        if (isPro) {\n          return [...basicRender]\n        }\n\n        return [...basicRender, ...extraRender]\n      }, [\n        campaignTagConfig,\n        currency,\n        favoriteMarket,\n        forexMap,\n        handleStartClick,\n        history,\n        isMobile,\n        isPro,\n        t,\n        upColor,\n      ])\n\n      const dispatch = useDispatch()\n\n      const defaultArgs: any = {\n        rawData: [],\n        columnMode: getColumnMode(),\n        generateRows: (rawData: any) => rawData,\n        onRowClick: onRowClick,\n        generateColumns: ({ columnsRaw }: any) =>\n          columnsRaw as Column<QuoteTableRawDataItem, unknown>[],\n        sortMethod: (sortedRows: QuoteTableRawDataItem[], sortColumn: string) => {\n          switch (sortColumn) {\n            case 'pair':\n              sortedRows = sortedRows.sort((a, b) => {\n                const valueA = a.pair.coinA\n                const valueB = b.pair.coinA\n                return valueB.localeCompare(valueA)\n              })\n              break\n            case 'close':\n              sortedRows = sortedRows.sort((a, b) => {\n                const valueA = a['close']\n                const valueB = b['close']\n                if (valueA && valueB) {\n                  return valueB - valueA\n                }\n                if (valueA && !valueB) {\n                  return -1\n                }\n                if (!valueA && valueB) {\n                  return 1\n                }\n                return 0\n              })\n              break\n            case 'change':\n              sortedRows = sortedRows.sort((a, b) => {\n                const valueA = a['change']\n                const valueB = b['change']\n                if (valueA && valueB) {\n                  return valueB - valueA\n                }\n                if (valueA && !valueB) {\n                  return -1\n                }\n                if (!valueA && valueB) {\n                  return 1\n                }\n                return 0\n              })\n              break\n            case 'high':\n              sortedRows = sortedRows.sort((a, b) => {\n                const valueA = a['high']\n                const valueB = b['high']\n                if (valueA && valueB) {\n                  return valueB - valueA\n                }\n                if (valueA && !valueB) {\n                  return -1\n                }\n                if (!valueA && valueB) {\n                  return 1\n                }\n                return 0\n              })\n              break\n            case 'low':\n              sortedRows = sortedRows.sort((a, b) => {\n                const valueA = a['low']\n                const valueB = b['low']\n                if (valueA && valueB) {\n                  return valueB - valueA\n                }\n                if (valueA && !valueB) {\n                  return -1\n                }\n                if (!valueA && valueB) {\n                  return 1\n                }\n                return 0\n              })\n              break\n            case 'volume':\n              sortedRows = sortedRows.sort((a, b) => {\n                const valueA = a['volume']\n                const valueB = b['volume']\n                if (valueA && valueB) {\n                  return valueB - valueA\n                }\n                if (valueA && !valueB) {\n                  return -1\n                }\n                if (!valueA && valueB) {\n                  return 1\n                }\n                return 0\n              })\n              break\n            default:\n              return sortedRows\n          }\n          return sortedRows\n        },\n        sortDefaultKey: 'change',\n      }\n\n      return (\n        <TableWrapperStyled>\n          <TableStyled\n            isMobile={isMobile}\n            currentheight={currentheight}\n            ispro={isPro}\n            className={'scrollable'}\n            {...{\n              ...defaultArgs,\n              ...rest,\n              onVisibleRowsChange,\n              rawData,\n              rowHeight,\n              headerRowHeight,\n              showloading: showLoading,\n            }}\n          />\n        </TableWrapperStyled>\n      )\n    },\n  ),\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/QuoteTable/index.ts",
    "content": "export * from './MarketTable'\nexport * from './QuoteTable'\nexport * from './MarketDetail'\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/ammRecordTable/AmmRecordTable.stories.tsx",
    "content": "import styled from '@emotion/styled'\nimport { Meta, Story } from '@storybook/react'\nimport { MemoryRouter } from 'react-router-dom'\nimport { AmmRecordRow as Row, AmmRecordTable, AmmTradeType } from './index'\nimport { coinMap } from '../../../static'\nimport { CoinInfo } from '@loopring-web/common-resources'\nimport moment from 'moment'\n\nconst Style = styled.div`\n  flex: 1;\n  height: 100%;\n  flex: 1;\n`\n\nconst rawData: Row<any>[] = [\n  {\n    type: AmmTradeType.add,\n    coinA: coinMap['ETH'] as CoinInfo<any>,\n    coinB: coinMap['LRC'] as CoinInfo<any>,\n    totalDollar: 12,\n    amountA: 122,\n    amountB: 231,\n    time: moment().add(-1, 'days').toDate().getTime(),\n  },\n  {\n    type: AmmTradeType.remove,\n    coinA: coinMap['ETH'] as CoinInfo<any>,\n    coinB: coinMap['LRC'] as CoinInfo<any>,\n    totalDollar: 12,\n    amountA: 122,\n    amountB: 231,\n    time: moment().add(-100, 'days').toDate().getTime(),\n  },\n  {\n    type: AmmTradeType.swap,\n    coinA: coinMap['ETH'] as CoinInfo<any>,\n    coinB: coinMap['LRC'] as CoinInfo<any>,\n    totalDollar: 12,\n    amountA: 122,\n    amountB: 231,\n    time: moment().add(-15, 'days').toDate().getTime(),\n  },\n  {\n    type: AmmTradeType.swap,\n    coinA: coinMap['ETH'] as CoinInfo<any>,\n    coinB: coinMap['LRC'] as CoinInfo<any>,\n    totalDollar: 12,\n    amountA: 122,\n    amountB: 231,\n    time: moment().add(-3, 'hours').toDate().getTime(),\n  },\n  {\n    type: AmmTradeType.swap,\n    coinA: coinMap['ETH'] as CoinInfo<any>,\n    coinB: coinMap['LRC'] as CoinInfo<any>,\n    totalDollar: 12,\n    amountA: 122,\n    amountB: 231,\n    time: moment().add(-75, 'second').toDate().getTime(),\n  },\n]\n\nexport const Template: Story<any> = (args: any) => {\n  return (\n    <>\n      <Style>\n        <MemoryRouter initialEntries={['/']}>\n          <AmmRecordTable {...args} />\n        </MemoryRouter>\n      </Style>\n    </>\n  )\n}\n\nTemplate.bind({})\n\nTemplate.args = {\n  rawData: rawData,\n  pagination: {\n    pageSize: 5,\n  },\n}\n\nexport default {\n  title: 'components/TableList/AmmRecordTable',\n  component: AmmRecordTable,\n  argTypes: {},\n} as Meta\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/ammRecordTable/AmmRecordTable.tsx",
    "content": "import React from 'react'\nimport { Box, BoxProps, Typography } from '@mui/material'\nimport { withTranslation, WithTranslation } from 'react-i18next'\nimport moment from 'moment'\nimport { Column, Table, TablePagination, TableProps } from '../../basic-lib'\nimport {\n  CurrencyToTag,\n  EmptyValueTag,\n  ForexMap,\n  getValuePrecisionThousand,\n  globalSetup,\n  PriceTag,\n  RowConfig,\n} from '@loopring-web/common-resources'\nimport { AmmRecordRow as Row, AmmRecordTableProps, AmmTradeType } from './Interface'\nimport { FormatterProps } from 'react-data-grid'\nimport styled from '@emotion/styled'\nimport { TablePaddingX } from '../../styled'\nimport { Currency } from '@loopring-web/loopring-sdk'\nimport { useSettings } from '../../../stores'\nimport { TFunction } from 'i18next'\n\n// height: ${(props: any) => {\n//       if (props.currentheight && props.currentheight > 350) {\n//         return props.currentheight + \"px\";\n//       } else {\n//   return \"100%\";\n// }\n// }};\nconst TableStyled = styled(Box)<BoxProps & { isMobile?: boolean }>`\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n\n  .rdg {\n    ${({ isMobile }) =>\n      !isMobile\n        ? `--template-columns: 280px 240px auto auto !important;`\n        : `--template-columns: 90% 10% !important;`}\n    .rdg-cell.action {\n      display: flex;\n      justify-content: center;\n      align-items: center;\n    }\n  }\n\n  .textAlignRight {\n    text-align: right;\n  }\n\n  ${({ theme }) => TablePaddingX({ pLeft: theme.unit * 3, pRight: theme.unit * 3 })}\n` as (props: { currentheight?: number; isMobile?: boolean } & BoxProps) => JSX.Element\n\nconst columnMode = (\n  { t }: { t: TFunction },\n  currency: Currency,\n  forexMap: ForexMap<Currency>,\n): Column<Row<any>, unknown>[] => [\n  {\n    key: 'style',\n    sortable: false,\n    width: 'auto',\n    minWidth: 240,\n    name: t('labelAmmTableType'),\n    formatter: ({ row }: FormatterProps<Row<any>, unknown>) => {\n      const { type, coinA, coinB, amountA, amountB } = row\n      const isAdd = type === AmmTradeType.add\n      const side = isAdd ? t('labelAmmJoin') : t('labelAmmExit')\n      return (\n        <Box display={'flex'} alignItems={'center'}>\n          <Typography color={isAdd ? 'var(--color-success)' : 'var(--color-error)'}>\n            {side}\n          </Typography>\n          &nbsp;&nbsp;\n          <Typography component={'span'}>\n            {`${getValuePrecisionThousand(amountA, undefined, undefined, undefined, false, {\n              isTrade: true,\n            })} ${coinA.simpleName}`}\n          </Typography>\n          &nbsp; + &nbsp;\n          <Typography component={'span'}>\n            {`${getValuePrecisionThousand(amountB, undefined, undefined, undefined, false, {\n              isTrade: true,\n            })} ${coinB.simpleName}`}\n          </Typography>\n        </Box>\n      )\n    },\n  },\n  {\n    key: 'totalValue',\n    sortable: false,\n    width: 'auto',\n    headerCellClass: 'textAlignCenter',\n    cellClass: 'textAlignCenter',\n    name: t('labelAmmTotalValue'),\n    formatter: ({ row }: FormatterProps<Row<any>, unknown>) => {\n      const { totalDollar } = row\n      return (\n        <Typography component={'span'}>\n          {typeof totalDollar === 'undefined'\n            ? EmptyValueTag\n            : PriceTag[CurrencyToTag[currency]] +\n              getValuePrecisionThousand(\n                (totalDollar || 0) * (forexMap[currency] ?? 0),\n                undefined,\n                undefined,\n                2,\n                true,\n                { isFait: true },\n              )}\n        </Typography>\n      )\n    },\n  },\n  {\n    key: 'time',\n    sortable: false,\n    width: 'auto',\n    headerCellClass: 'textAlignRight',\n    cellClass: 'textAlignRight',\n    name: t('labelAmmTime'),\n    formatter: ({ row }: FormatterProps<Row<any>, unknown>) => {\n      const { time } = row\n      let timeString\n      if (typeof time === 'undefined') {\n        timeString = EmptyValueTag\n      } else {\n        timeString = moment(new Date(time), 'YYYYMMDDHHMM').fromNow()\n      }\n      return (\n        <Typography component={'span'} textAlign={'right'}>\n          {timeString}\n        </Typography>\n      )\n    },\n  },\n]\n\nconst columnModeMobile = (\n  { t }: { t: TFunction },\n  currency: Currency,\n  forexMap: ForexMap<Currency>,\n): Column<Row<any>, unknown>[] => [\n  {\n    key: 'style',\n    sortable: false,\n    width: 'auto',\n    minWidth: 240,\n    name: t('labelAmmTableType'),\n    formatter: ({ row }: FormatterProps<Row<any>, unknown>) => {\n      const { type, coinA, coinB, amountA, amountB } = row\n      const isAdd = type === AmmTradeType.add\n      const side = isAdd ? t('labelAmmJoin') : t('labelAmmExit')\n      return (\n        <Box display={'flex'} alignItems={'center'}>\n          <Typography color={isAdd ? 'var(--color-success)' : 'var(--color-error)'}>\n            {side}\n          </Typography>\n          &nbsp;&nbsp;\n          <Typography component={'span'}>\n            {`${getValuePrecisionThousand(amountA, undefined, undefined, undefined, false, {\n              isTrade: true,\n            })} ${coinA.simpleName}`}\n          </Typography>\n          &nbsp; + &nbsp;\n          <Typography component={'span'}>\n            {`${getValuePrecisionThousand(amountB, undefined, undefined, undefined, false, {\n              isTrade: true,\n            })} ${coinB.simpleName}`}\n          </Typography>\n        </Box>\n      )\n    },\n  },\n  {\n    key: 'totalValue',\n    sortable: false,\n    width: 'auto',\n    cellClass: 'textAlignRight',\n    headerCellClass: 'textAlignRight',\n    name: t('labelAmmTotalValue') + '/' + t('labelAmmTime'),\n    formatter: ({ row }: FormatterProps<Row<any>, unknown>) => {\n      const { totalDollar } = row\n      const time = moment(new Date(row.time), 'YYYYMMDDHHMM').fromNow()\n      return (\n        <Box display={'flex'} flexDirection={'column'} height={'100%'}>\n          <Typography component={'span'}>\n            {typeof totalDollar === 'undefined'\n              ? EmptyValueTag\n              : PriceTag[CurrencyToTag[currency]] +\n                getValuePrecisionThousand(\n                  (totalDollar || 0) * (forexMap[currency] ?? 0),\n                  undefined,\n                  undefined,\n                  undefined,\n                  true,\n                  { isFait: true },\n                )}\n          </Typography>\n          <Typography component={'span'} textAlign={'right'}>\n            {time}\n          </Typography>\n        </Box>\n      )\n    },\n  },\n]\n\nexport const AmmRecordTable = withTranslation('tables')(\n  <T extends { [key: string]: any }>({\n    t,\n    i18n,\n    tReady,\n    handlePageChange,\n    pagination,\n    currentheight,\n    rowHeight = RowConfig.rowHeight,\n    headerRowHeight = RowConfig.rowHeaderHeight,\n    showFilter = true,\n    rawData,\n    scroll = false,\n    wait = globalSetup.wait,\n    currency = Currency.usd,\n    forexMap,\n    ...rest\n  }: AmmRecordTableProps<T> & WithTranslation) => {\n    const [page, setPage] = React.useState(1)\n    const { isMobile } = useSettings()\n    const defaultArgs: TableProps<any, any> = {\n      rawData,\n      columnMode: isMobile\n        ? columnModeMobile({ t }, currency, forexMap)\n        : columnMode({ t }, currency, forexMap),\n      generateRows: (rawData: any) => rawData,\n      generateColumns: ({ columnsRaw }) => columnsRaw as Column<Row<any>, unknown>[],\n    }\n\n    const pageSize = pagination ? pagination.pageSize : 10\n\n    const _handlePageChange = React.useCallback(\n      (currPage: number) => {\n        if (currPage === page) return\n        setPage(currPage)\n        // updateData({actionType: ActionType.page, currPage: page})\n        if (handlePageChange) {\n          handlePageChange({\n            limit: pageSize,\n            offset: (currPage - 1) * pageSize,\n          })\n        }\n      },\n      [handlePageChange, page, pageSize],\n    )\n\n    const height = (currentheight || 0) + (!!rawData.length ? 0 : RowConfig.rowHeaderHeight)\n\n    return (\n      <TableStyled isMobile={isMobile} currentheight={height} className={'amm-record-table'}>\n        <Table\n          {...{\n            ...defaultArgs,\n            t,\n            i18n,\n            tReady,\n            ...rest,\n            rowHeight,\n            headerRowHeight,\n            scroll,\n            rawData: rawData,\n          }}\n        />\n        {pagination && !!rawData.length && (\n          <TablePagination\n            page={page}\n            pageSize={pageSize}\n            total={pagination.total}\n            onPageChange={_handlePageChange}\n          />\n        )}\n      </TableStyled>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/ammRecordTable/Interface.ts",
    "content": "import { CoinInfo, ForexMap } from '@loopring-web/common-resources'\nimport { Currency } from '@loopring-web/loopring-sdk'\n\nexport enum AmmTradeType {\n  add = 'add',\n  swap = 'swap',\n  remove = 'remove',\n}\n\nenum TxStatus {\n  processing = 'processing',\n  processed = 'processed',\n  received = 'received',\n  failed = 'failed',\n}\n\nexport interface AmmRecordRow<C> {\n  totalDollar: number\n  amountA: number\n  amountB: number\n  time: number\n  type: keyof typeof AmmTradeType\n  coinA: CoinInfo<C>\n  coinB: CoinInfo<C>\n  status?: keyof typeof TxStatus\n}\n\nexport type AmmRecordTableProps<T, R = AmmRecordRow<T>> = {\n  rawData: R[]\n  pagination?: {\n    pageSize: number\n    total: number\n  }\n  scroll?: boolean\n  page?: number\n  handlePageChange?: (props: any) => void\n  showFilter?: boolean\n  wait?: number\n  showloading?: boolean\n  currentheight?: number\n  rowHeight?: number\n  headerRowHeight?: number\n  currency?: Currency\n  forexMap: ForexMap<Currency>\n}\n// rowHeight={RowConfig.rowHeight}\n// headerRowHeight={RowConfig.headerRowHeight}\n// currentheight={tableHeight}\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/ammRecordTable/index.ts",
    "content": "export * from './AmmRecordTable'\nexport * from './Interface'\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/ammTable/AmmTable.stories.tsx",
    "content": "import styled from '@emotion/styled'\nimport { Meta, Story } from '@storybook/react'\nimport { withTranslation } from 'react-i18next'\nimport { MemoryRouter } from 'react-router-dom'\nimport { AmmTable, RawDataAmmItem } from './index'\nimport { AmmSideTypes } from './interface'\n\nconst Style = styled.div`\n  flex: 1;\n  height: 100%;\n  flex: 1;\n`\n\nconst rawData: RawDataAmmItem[] = [\n  {\n    side: AmmSideTypes.Join,\n    amount: {\n      from: {\n        key: 'LRC',\n        value: '2333',\n      },\n      to: {\n        key: 'ETH',\n        value: '1.05',\n      },\n    },\n    lpTokenAmount: '1785.65',\n    fee: {\n      key: 'LRC',\n      value: '2.55',\n    },\n    time: 0,\n  },\n  {\n    side: AmmSideTypes.Exit,\n    amount: {\n      from: {\n        key: 'LRC',\n        value: '12333',\n      },\n      to: {\n        key: 'ETH',\n        value: '1.25',\n      },\n    },\n    lpTokenAmount: '1745.23',\n    fee: {\n      key: 'LRC',\n      value: '21.55',\n    },\n    time: 0,\n  },\n]\n\nconst Template: Story<any> = withTranslation()((args: any) => {\n  return (\n    <>\n      <Style>\n        <MemoryRouter initialEntries={['/']}>\n          <AmmTable {...args} />\n        </MemoryRouter>\n      </Style>\n    </>\n  )\n}) as Story<any>\n\nexport const Amm = Template.bind({})\n\nAmm.args = {\n  rawData: rawData,\n  pagination: {\n    pageSize: 5,\n  },\n  showFilter: true,\n}\n\nexport default {\n  title: 'components/TableList/Amm',\n  component: AmmTable,\n  argTypes: {},\n} as Meta\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/ammTable/AmmTable.tsx",
    "content": "import React from 'react'\nimport { Box, BoxProps, Link, Typography } from '@mui/material'\nimport styled from '@emotion/styled'\nimport { TFunction, withTranslation, WithTranslation } from 'react-i18next'\nimport moment from 'moment'\nimport { Column, Table, TablePagination } from '../../basic-lib'\nimport { TableFilterStyled, TablePaddingX } from '../../styled'\nimport { Filter, FilterTradeTypes } from './components/Filter'\nimport {\n  getValuePrecisionThousand,\n  globalSetup,\n  myLog,\n  UNIX_TIMESTAMP_FORMAT,\n} from '@loopring-web/common-resources'\nimport { useSettings } from '../../../stores'\nimport { AmmSideTypes } from './interface'\nimport { Currency } from '@loopring-web/loopring-sdk'\nimport { DateRange } from '@mui/lab'\nimport _ from 'lodash'\nimport { useLocation } from 'react-router-dom'\n\nexport type RawDataAmmItem = {\n  side: AmmSideTypes\n  amount: {\n    from: {\n      key: string\n      value?: string\n    }\n    to: {\n      key: string\n      value?: string\n    }\n  }\n  lpTokenAmount?: string\n  fee: {\n    key: string\n    value?: string\n  }\n  time: number\n}\n\nexport type AmmTableProps = {\n  getAmmpoolList: (props: any) => void\n  rawData: RawDataAmmItem[]\n  filterPairs: string[]\n  showloading: boolean\n  pagination?: {\n    pageSize: number\n    total: number\n  }\n  showFilter?: boolean\n}\n\n// enum TableType {\n//     filter = 'filter',\n//     page = 'page'\n// }\n\nconst TableStyled = styled(Box)<BoxProps & { isMobile?: boolean }>`\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n\n  .rdg {\n    ${({ isMobile }) =>\n      !isMobile\n        ? `--template-columns: 300px auto auto auto !important;`\n        : `--template-columns: 78% 22% !important;`}\n\n    .rdg-row .rdg-cell:first-of-type {\n      display: flex;\n      align-items: center;\n    }\n    .rdg-cell.action {\n      display: flex;\n      justify-content: center;\n      align-items: center;\n    }\n    .textAlignRight {\n      text-align: right;\n    }\n  }\n\n  ${({ theme }) => TablePaddingX({ pLeft: theme.unit * 3, pRight: theme.unit * 3 })}\n` as (props: { isMobile?: boolean } & BoxProps) => JSX.Element\n\nconst StyledSideCell: any = styled(Typography)`\n  color: ${(props: any) => {\n    const {\n      value,\n      theme: { colorBase },\n    } = props\n    return value === AmmSideTypes.Join ? colorBase.success : colorBase.error\n  }};\n`\n\nconst getColumnModeAssets = (\n  t: TFunction,\n  _currency: Currency,\n): Column<RawDataAmmItem, unknown>[] => [\n  {\n    key: 'side',\n    name: t('labelAmmSide'),\n    formatter: ({ row }) => {\n      const tradeType = row['side'] === AmmSideTypes.Join ? t('labelAmmJoin') : t('labelAmmExit')\n      const { from, to } = row['amount']\n      const renderFromValue = getValuePrecisionThousand(\n        from.value,\n        undefined,\n        undefined,\n        undefined,\n        false,\n        { isTrade: true },\n      )\n      const renderToValue = getValuePrecisionThousand(\n        to.value,\n        undefined,\n        undefined,\n        undefined,\n        false,\n        { isTrade: true },\n      )\n      return (\n        <>\n          <StyledSideCell value={row['side']}>{tradeType}</StyledSideCell>\n          <Typography marginLeft={1 / 2}>\n            {`${renderFromValue} ${from.key} + ${renderToValue} ${to.key}`}\n          </Typography>\n        </>\n      )\n    },\n  },\n  {\n    key: 'lpTokenAmount',\n    name: t('labelAmmLpTokenAmount'),\n    headerCellClass: 'textAlignRight',\n    formatter: ({ row }) => {\n      const amount = row['lpTokenAmount']\n      const renderValue =\n        row['side'] === AmmSideTypes.Join\n          ? `+${getValuePrecisionThousand(amount, undefined, undefined, undefined, false, {\n              isTrade: true,\n            })}`\n          : `-${getValuePrecisionThousand(amount, undefined, undefined, undefined, false, {\n              isTrade: true,\n            })}`\n      return <Box className='rdg-cell-value textAlignRight'>{renderValue}</Box>\n    },\n  },\n  {\n    key: 'fee',\n    name: t('labelTxNetworkFee'),\n    headerCellClass: 'textAlignRight',\n    formatter: ({ row }) => {\n      const { key, value } = row['fee']\n      return (\n        <Box className='rdg-cell-value textAlignRight'>\n          {`${getValuePrecisionThousand(value, undefined, undefined, undefined, false, {\n            isTrade: true,\n            floor: false,\n          })} ${key}`}\n        </Box>\n      )\n    },\n  },\n  {\n    key: 'time',\n    name: t('labelAmmRecordTime'),\n    headerCellClass: 'textAlignRight',\n    // minWidth: 400,\n    formatter: ({ row }) => {\n      const time = moment(new Date(row['time']), 'YYYYMMDDHHMM').fromNow()\n      return <Box className='rdg-cell-value textAlignRight'>{time}</Box>\n    },\n  },\n]\n\nconst getColumnModeMobileAssets = (\n  t: TFunction,\n  _currency: Currency,\n): Column<RawDataAmmItem, unknown>[] => [\n  {\n    key: 'side',\n    name: (\n      <Typography\n        height={'100%'}\n        display={'flex'}\n        justifyContent={'space-between'}\n        variant={'inherit'}\n        color={'inherit'}\n        alignItems={'center'}\n      >\n        <span>{t('labelAmmSide')}</span>\n        <span>{t('labelAmmLpTokenAmount') + '/' + t('labelTxNetworkFee')}</span>\n      </Typography>\n    ),\n    formatter: ({ row }) => {\n      const tradeType = row['side'] === AmmSideTypes.Join ? t('labelAmmJoin') : t('labelAmmExit')\n      const { from, to } = row['amount']\n      const renderFromValue = getValuePrecisionThousand(\n        from.value,\n        undefined,\n        undefined,\n        undefined,\n        false,\n        { isTrade: true },\n      )\n      const renderToValue = getValuePrecisionThousand(\n        to.value,\n        undefined,\n        undefined,\n        undefined,\n        false,\n        { isTrade: true },\n      )\n      const { key, value } = row.fee\n\n      return (\n        <Box\n          height={'100%'}\n          width={'100%'}\n          display={'flex'}\n          flexDirection={'row'}\n          alignItems={'center'}\n          justifyContent={'space-between'}\n        >\n          <StyledSideCell component={'span'} value={row.side} variant={'body1'}>\n            {tradeType}\n          </StyledSideCell>\n          <Typography\n            component={'span'}\n            display={'flex'}\n            flexDirection={'column'}\n            justifyContent={'space-around'}\n            alignSelf={'stretch'}\n            alignItems={'flex-end'}\n          >\n            <Typography marginLeft={1 / 2}>\n              {`${renderFromValue} ${from.key} + ${renderToValue} ${to.key}`}\n            </Typography>\n            <Typography variant={'body2'} component={'span'} color={'textSecondary'}>\n              {`Fee: ${getValuePrecisionThousand(value, undefined, undefined, undefined, false, {\n                isTrade: true,\n                floor: false,\n              })} ${key}`}\n            </Typography>\n          </Typography>\n        </Box>\n      )\n    },\n  },\n  {\n    key: 'lpTokenAmmTime',\n    name: t('labelAmmTime'),\n    headerCellClass: 'textAlignRight',\n    formatter: ({ row }) => {\n      // const amount = row[\"lpTokenAmount\"];\n      // const renderValue =\n      //   row[\"side\"] === AmmSideTypes.Join\n      //     ? `+${getValuePrecisionThousand(\n      //         amount,\n      //         undefined,\n      //         undefined,\n      //         undefined,\n      //         false,\n      //         { isTrade: true }\n      //       )}`\n      //     : `-${getValuePrecisionThousand(\n      //         amount,\n      //         undefined,\n      //         undefined,\n      //         undefined,\n      //         false,\n      //         { isTrade: true }\n      //       )}`;\n      const time = moment(new Date(row['time']), 'YYYYMMDDHHMM').fromNow()\n\n      return (\n        <Box\n          height={'100%'}\n          width={'100%'}\n          display={'flex'}\n          flexDirection={'column'}\n          alignItems={'flex-end'}\n          justifyContent={'center'}\n        >\n          <Typography component={'span'} variant={'body2'}>\n            {time}\n          </Typography>\n        </Box>\n      )\n    },\n  },\n]\n\nexport const AmmTable = withTranslation('tables')((props: WithTranslation & AmmTableProps) => {\n  const { search } = useLocation()\n  const searchParams = new URLSearchParams(search)\n  const { t, pagination, showFilter, rawData, filterPairs, getAmmpoolList } = props\n  const [isDropDown, setIsDropDown] = React.useState(true)\n\n  const [page, setPage] = React.useState(1)\n  // const [filterPair, setFilterPair] = React.useState(\"all\");\n\n  const [filterItems, setFilterItems] = React.useState<{\n    filterType: FilterTradeTypes\n    filterDate: DateRange<Date | null>\n    filterPair: string\n  }>({\n    filterType: FilterTradeTypes.allTypes,\n    filterDate: [null, null],\n    filterPair: 'all',\n  })\n  const { currency, isMobile } = useSettings()\n  const defaultArgs: any = {\n    columnMode: isMobile\n      ? getColumnModeMobileAssets(t, currency)\n      : getColumnModeAssets(t, currency),\n    generateRows: (rawData: any) => rawData,\n    generateColumns: ({ columnsRaw }: any) => columnsRaw,\n    style: {\n      backgroundColor: ({ colorBase }: any) => `${colorBase.box}`,\n    },\n  }\n\n  const updateData = _.debounce(\n    async ({ page = 1, type = FilterTradeTypes.allTypes, date = [null, null], pair }: any) => {\n      const start = date\n        ? date[0] && Number(moment(date[0]).format(UNIX_TIMESTAMP_FORMAT))\n        : undefined\n      const end = date\n        ? date[1] && Number(moment(date[1]).format(UNIX_TIMESTAMP_FORMAT))\n        : undefined\n\n      await getAmmpoolList({\n        tokenSymbol: pair,\n        txTypes: type !== FilterTradeTypes.allTypes ? type : '',\n        start,\n        end,\n        offset: (page - 1) * (pagination?.pageSize ?? 10),\n        limit: pagination?.pageSize ?? 10,\n      })\n    },\n    globalSetup.wait,\n  )\n\n  const handleFilterChange = React.useCallback(\n    ({ type, date, pair }) => {\n      let filters = {\n        filterType: type ? type : filterItems.filterType,\n        filterDate: date ? date : filterItems.filterDate,\n        filterPair: pair ? pair : filterItems.filterPair,\n      }\n      setFilterItems(filters)\n      updateData({\n        type: filters.filterType,\n        date: filters.filterDate,\n        pair: filters.filterPair,\n        page: 1,\n      })\n    },\n    [filterItems.filterDate, filterItems.filterPair, filterItems.filterType, updateData],\n  )\n\n  const handlePageChange = React.useCallback(\n    ({ page = 1, type, date, pair }: any) => {\n      setPage(page)\n      myLog('AmmTable page,', page)\n      updateData({ page, type, date, pair })\n    },\n    [updateData],\n  )\n\n  const handleReset = React.useCallback(() => {\n    setFilterItems({\n      filterType: FilterTradeTypes.allTypes,\n      filterDate: [null, null],\n      filterPair: '',\n    })\n    updateData({\n      page: 1,\n      type: FilterTradeTypes.allTypes,\n      date: [null, null],\n      pair: '',\n    })\n  }, [updateData])\n\n  React.useEffect(() => {\n    let filters: any = {}\n    updateData.cancel()\n    if (searchParams.get('pair')) {\n      filters.pair = searchParams.get('pair')\n    }\n    handleFilterChange(filters)\n    return () => {\n      updateData.cancel()\n    }\n  }, [pagination?.pageSize])\n\n  return (\n    <TableStyled isMobile={isMobile}>\n      {showFilter &&\n        (isMobile && isDropDown ? (\n          <Link\n            variant={'body1'}\n            display={'inline-flex'}\n            width={'100%'}\n            justifyContent={'flex-end'}\n            paddingRight={2}\n            onClick={() => setIsDropDown(false)}\n          >\n            {t('labelShowFilter')}\n          </Link>\n        ) : (\n          <TableFilterStyled>\n            <Filter\n              filterPairs={filterPairs}\n              filterPair={filterItems.filterPair}\n              filterType={filterItems.filterType}\n              filterDate={filterItems.filterDate}\n              handleFilterChange={handleFilterChange}\n              handleReset={handleReset}\n            />\n          </TableFilterStyled>\n        ))}\n      <Table {...{ ...defaultArgs, ...props, rawData }} />\n      {!!(pagination && pagination.total) && (\n        <TablePagination\n          page={page}\n          pageSize={pagination.pageSize}\n          total={pagination.total}\n          onPageChange={(page) => handlePageChange({ page })}\n        />\n      )}\n    </TableStyled>\n  )\n})\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/ammTable/components/Filter.tsx",
    "content": "import React from 'react'\nimport styled from '@emotion/styled'\nimport { Grid, MenuItem } from '@mui/material'\nimport { withTranslation, WithTranslation } from 'react-i18next'\nimport { DateRangePicker, TextField } from '../../../basic-lib/form'\nimport { Button } from '../../../basic-lib/btns'\nimport { DropDownIcon } from '@loopring-web/common-resources'\nimport { DateRange } from '@mui/lab'\nimport { useSettings } from '../../../../stores'\n\nexport interface FilterProps {\n  filterPairs: string[]\n  filterType: string\n  filterPair: string\n  filterDate: DateRange<Date | null>\n  handleFilterChange: ({ filterType, filterDate, filterToken }: any) => void\n  handleReset: () => void\n}\n\nconst StyledTextFiled = styled(TextField)`\n  &.MuiTextField-root {\n    max-width: initial;\n  }\n\n  .MuiInputBase-root {\n    width: initial;\n    max-width: initial;\n  }\n`\n\nexport enum FilterTradeTypes {\n  join = 'Add',\n  exit = 'Remove',\n  allTypes = 'all',\n}\n\nexport const Filter = withTranslation('tables', { withRef: true })(\n  ({\n    t,\n    filterPairs,\n    filterType,\n    filterDate,\n    filterPair,\n    handleReset,\n    handleFilterChange,\n  }: FilterProps & WithTranslation) => {\n    const { isMobile } = useSettings()\n\n    const FilterTradeTypeList = [\n      {\n        label: t('labelAmmFilterTypes'),\n        value: FilterTradeTypes.allTypes,\n      },\n      {\n        label: t('labelAmmJoin'),\n        value: FilterTradeTypes.join,\n      },\n      {\n        label: t('labelAmmExit'),\n        value: FilterTradeTypes.exit,\n      },\n    ]\n\n    const rawPairList = [].slice\n      .call(filterPairs)\n      .sort((a: string, b: string) => {\n        return a.localeCompare(b)\n      })\n      .map((pair: string) => ({\n        label: pair,\n        value: pair,\n      }))\n    const formattedRawPairList = [\n      {\n        label: t('labelFilterAllPairs'),\n        value: 'all',\n      },\n      ...rawPairList,\n    ]\n\n    return (\n      <Grid container spacing={2} alignItems={'center'}>\n        <Grid item xs={12} order={isMobile ? 0 : 1} lg={6}>\n          <DateRangePicker\n            value={filterDate}\n            onChange={(date: any) => {\n              handleFilterChange({ date: date })\n            }}\n          />\n        </Grid>\n        <Grid item xs={4} order={isMobile ? 1 : 0} lg={2}>\n          <StyledTextFiled\n            id='table-amm-filter-types'\n            select\n            fullWidth\n            value={filterType}\n            onChange={(event: React.ChangeEvent<{ value: unknown }>) => {\n              handleFilterChange({ type: event.target.value })\n            }}\n            inputProps={{ IconComponent: DropDownIcon }}\n          >\n            {FilterTradeTypeList.map((o) => (\n              <MenuItem key={o.value} value={o.value}>\n                {o.label}\n              </MenuItem>\n            ))}\n          </StyledTextFiled>\n        </Grid>\n        <Grid item xs={4} order={2} lg={2}>\n          <StyledTextFiled\n            id='table-trade-filter-pairs'\n            select\n            fullWidth\n            value={filterPair}\n            onChange={(event: React.ChangeEvent<{ value: unknown }>) => {\n              handleFilterChange({ pair: event.target.value })\n            }}\n            inputProps={{ IconComponent: DropDownIcon }}\n          >\n            {formattedRawPairList.map((o) => (\n              <MenuItem key={o.value} value={o.value}>\n                {o.label}\n              </MenuItem>\n            ))}\n          </StyledTextFiled>\n        </Grid>\n        <Grid item xs={4} order={3} lg={2}>\n          <Button\n            fullWidth\n            variant={'outlined'}\n            size={'medium'}\n            color={'primary'}\n            onClick={handleReset}\n          >\n            {t('labelFilterReset')}\n          </Button>\n          {/* <Button variant={'contained'} size={'small'} color={'primary'}\n                            onClick={handleSearch}>{t('Search')}</Button> */}\n        </Grid>\n      </Grid>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/ammTable/index.ts",
    "content": "export * from './AmmTable'\nexport * from './interface'\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/ammTable/interface.ts",
    "content": "export enum AmmSideTypes {\n  Exit = 'Exit',\n  Join = 'Join',\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/assetsTable/AssetsDefiTable.tsx",
    "content": "import React from 'react'\nimport { Box, BoxProps, Typography, Tooltip } from '@mui/material'\nimport styled from '@emotion/styled'\nimport { TFunction, withTranslation, WithTranslation, Trans } from 'react-i18next'\nimport { Column, Table, Button } from '../../basic-lib'\nimport { TablePaddingX } from '../../styled'\nimport {\n  BackIcon,\n  EmptyValueTag,\n  getValuePrecisionThousand,\n  HiddenTag,\n  Info2Icon,\n  RowConfig,\n  UpColor,\n} from '@loopring-web/common-resources'\nimport { useOpenModals, useSettings } from '../../../stores'\nimport { CoinIcons } from './components/CoinIcons'\nimport ActionMemo from './components/ActionMemo'\nimport { AssetsTableProps, RawDataAssetsItem } from './AssetsTable'\nimport * as sdk from '@loopring-web/loopring-sdk'\nexport type RawDefiAssetsItem = RawDataAssetsItem & {\n  apr: string\n  average: string\n  defiInfo: sdk.DefiMarketInfo\n  baseToken?: string\n}\nconst TableWrap = styled(Box)<BoxProps & { isMobile?: boolean }>`\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n  .rdg {\n    //.rdg-header-row {\n    //  .rdg-cell {\n    //    display: inline-flex;\n    //    align-items: center;\n    //  }\n    //}\n    flex: 1;\n    --template-columns: 16% auto auto 10% 16% !important;\n\n    .rdg-cell:first-of-type {\n      display: flex;\n      align-items: center;\n      margin-top: ${({ theme }) => theme.unit / 8}px;\n    }\n\n    .rdg-cell:last-of-type {\n    }\n\n    .rdg-cell.action {\n      display: flex;\n      justify-content: center;\n      align-items: center;\n    }\n\n    .textAlignRight {\n      text-align: right;\n    }\n  }\n  ${({ theme }) => TablePaddingX({ pLeft: theme.unit * 3, pRight: theme.unit * 3 })}\n` as (props: { isMobile?: boolean } & BoxProps) => JSX.Element\n\nexport const AssetsDefiTable = withTranslation('tables')(\n  <R extends RawDefiAssetsItem>(props: WithTranslation & Partial<AssetsTableProps<R>>) => {\n    const {\n      t,\n      rawData = [],\n      allowTrade,\n      showFilter,\n      getMarketArrayListCallback,\n      disableWithdrawList,\n      hideInvestToken,\n      hideSmallBalances,\n      isLoading = false,\n      setHideSmallBalances,\n      onSend,\n      onReceive,\n      forexMap,\n      rowConfig = RowConfig,\n      hideAssets,\n      onTokenLockHold,\n      tokenLockDetail,\n      searchValue,\n      isWebEarn,\n      ...rest\n    } = props\n    const gridRef = React.useRef(null)\n    const { setShowETHStakingApr } = useOpenModals()\n    const { isMobile, coinJson } = useSettings()\n    const { upColor } = useSettings()\n    const colorRight =\n      upColor === UpColor.green\n        ? ['var(--color-success)', 'var(--color-error)']\n        : ['var(--color-error)', 'var(--color-success)']\n\n    const getColumnModeAssets = (t: TFunction, allowTrade?: any): Column<R, unknown>[] => [\n      {\n        key: 'token',\n        name: t('labelToken'),\n        formatter: ({ row, column }) => {\n          const token = row[column.key]\n          let tokenIcon: [any, any] = [undefined, undefined]\n          const [head, middle, tail] = token.value.split('-')\n          if (token.type === 'lp' && middle && tail) {\n            tokenIcon =\n              coinJson[middle] && coinJson[tail]\n                ? [coinJson[middle], coinJson[tail]]\n                : [undefined, undefined]\n          }\n          if (token.type !== 'lp' && head && head !== 'lp') {\n            tokenIcon = coinJson[head] ? [coinJson[head], undefined] : [undefined, undefined]\n          }\n          return (\n            <>\n              <CoinIcons type={token.type} tokenIcon={tokenIcon} />\n\n              <Typography\n                variant={'inherit'}\n                color={'textPrimary'}\n                display={'flex'}\n                flexDirection={'column'}\n                marginLeft={2}\n                component={'span'}\n                paddingRight={1}\n              >\n                <Typography component={'span'} className={'next-coin'}>\n                  {token.value}\n                </Typography>\n              </Typography>\n            </>\n          )\n        },\n      },\n      {\n        key: 'amount',\n        name: t('labelAmount'),\n        headerCellClass: 'textAlignRight',\n        formatter: ({ row }) => {\n          const value = row.amount\n          const precision = row.precision\n          return (\n            <Box className={'textAlignRight'}>\n              {hideAssets\n                ? HiddenTag\n                : getValuePrecisionThousand(value, precision, precision, undefined, false, {\n                    floor: true,\n                  })}\n            </Box>\n          )\n        },\n      },\n      {\n        key: 'averagePositionCost',\n        name: (\n          <Tooltip title={t('labelAveragePositionCostDes').toString()} placement={'top'}>\n            <Typography\n              display={'inline-flex'}\n              alignItems={'center'}\n              color={'var(--color-text-third)'}\n            >\n              <Trans i18nKey={'labelAveragePositionCost'} ns={'tables'}>\n                Average\n                <Info2Icon color={'inherit'} fontSize={'small'} sx={{ marginLeft: 1 / 2 }} />\n              </Trans>\n            </Typography>\n          </Tooltip>\n        ),\n        headerCellClass: 'textAlignRight',\n        formatter: ({ row }) => {\n          const precision = row.precision\n          return (\n            <Box className={'textAlignRight'}>\n              {hideAssets\n                ? HiddenTag\n                : row.average\n                ? getValuePrecisionThousand(row.average, precision, precision, undefined, false, {\n                    floor: true,\n                  }) + ` ${row?.baseToken}`\n                : EmptyValueTag}\n            </Box>\n          )\n        },\n      },\n      {\n        key: 'apr',\n        name: (\n          <Tooltip title={t('labelDefiAprDes').toString()} placement={'top'}>\n            <Typography\n              display={'inline-flex'}\n              alignItems={'center'}\n              color={'var(--color-text-third)'}\n            >\n              <Trans i18nKey={'labelDefiApr'} ns={'tables'}>\n                APR <Info2Icon color={'inherit'} fontSize={'small'} sx={{ marginLeft: 1 / 2 }} />\n              </Trans>\n            </Typography>\n          </Tooltip>\n        ),\n        headerCellClass: 'textAlignCenter',\n        formatter: ({ row }) => {\n          return (\n            <Button\n              variant={'text'}\n              size={'small'}\n              onClick={() =>\n                setShowETHStakingApr({\n                  isShow: true,\n                  symbol: `${row?.defiInfo?.market}`,\n                  info: row?.defiInfo,\n                })\n              }\n              sx={{\n                padding: 0,\n                justifyContent: 'right',\n                color: row?.apr?.toString().charAt(0) == '-' ? colorRight[1] : colorRight[0],\n              }}\n              endIcon={\n                <BackIcon\n                  fontSize={'small'}\n                  sx={{ transform: 'rotate(180deg)' }}\n                  color={'inherit'}\n                />\n              }\n            >\n              {row.apr && row.apr !== '0.00' ? row.apr + '%' : EmptyValueTag}\n            </Button>\n          )\n        },\n      },\n      {\n        key: 'actions',\n        name: t('labelActions'),\n        headerCellClass: 'textAlignRight',\n        // minWidth: 280,\n        formatter: ({ row }) => {\n          const token = row.token\n          const tokenValue = token.value\n          return (\n            <ActionMemo\n              {...({\n                isLp: false,\n                onSend,\n                onReceive,\n                isInvest: true,\n                tokenValue,\n                disableWithdrawList,\n                isDefi: true,\n                allowTrade,\n                isLeverageETH: false,\n              } as any)}\n            />\n          )\n        },\n      },\n    ]\n    return (\n      <TableWrap isMobile={isMobile}>\n        <Table\n          ref={gridRef}\n          className={'investAsset'}\n          {...{ ...rest, t }}\n          style={{\n            height:\n              rawData.length > 0\n                ? rowConfig.rowHeaderHeight + rawData.length * rowConfig.rowHeight\n                : 350,\n          }}\n          rowHeight={rowConfig.rowHeight}\n          headerRowHeight={rowConfig.rowHeaderHeight}\n          rawData={rawData}\n          generateRows={(rowData: any) => rowData}\n          generateColumns={({ columnsRaw }: any) => columnsRaw as Column<any, unknown>[]}\n          showloading={isLoading}\n          columnMode={getColumnModeAssets(t, allowTrade) as any}\n        />\n      </TableWrap>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/assetsTable/AssetsTable.tsx",
    "content": "import React from 'react'\nimport { Box, BoxProps, Modal, Typography } from '@mui/material'\nimport styled from '@emotion/styled'\nimport { TFunction, withTranslation, WithTranslation } from 'react-i18next'\nimport { Column, Table } from '../../basic-lib'\nimport { Filter } from './components/Filter'\nimport { TablePaddingX } from '../../styled'\nimport {\n  CurrencyToTag,\n  ForexMap,\n  getValuePrecisionThousand,\n  HiddenTag,\n  mapSpecialTokenName,\n  MarketType,\n  PriceTag,\n  RowConfig,\n  TokenType,\n} from '@loopring-web/common-resources'\nimport { useOpenModals, useSettings } from '../../../stores'\nimport { CoinIcons } from './components/CoinIcons'\nimport ActionMemo, { LockedMemo } from './components/ActionMemo'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { XOR } from '../../../types/lib'\nimport { LockDetailPanel } from './components/modal'\nimport _ from 'lodash'\n\nconst TableWrap = styled(Box)<BoxProps & { isMobile?: boolean; lan: string; isWebEarn?: boolean }>`\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n\n  .rdg {\n    flex: 1;\n\n    ${({ isMobile, isWebEarn }) =>\n      isWebEarn\n        ? isMobile\n          ? `--template-columns: 28% 68% 4% !important;`\n          : `--template-columns: 200px 150px auto auto 220px !important;`\n        : isMobile\n        ? `--template-columns: 54% 40% 6% !important;`\n        : `--template-columns: 200px 150px auto auto 184px !important;`}\n    .rdg-cell:first-of-type {\n      display: flex;\n      align-items: center;\n      margin-top: ${({ theme }) => theme.unit / 8}px;\n      padding-left: ${({ isWebEarn }) => isWebEarn && 0};\n    }\n    .rdg-cell:last-of-type {\n      padding-right: ${({ isWebEarn }) => isWebEarn && 0};\n    }\n\n    .rdg-cell.action {\n      display: flex;\n      justify-content: center;\n      align-items: center;\n    }\n\n    .textAlignRight {\n      text-align: right;\n    }\n  }\n\n  .investAsset.rdg {\n    ${({ isMobile }) =>\n      !isMobile\n        ? `--template-columns: 200px 150px auto auto 205px !important;`\n        : `--template-columns: 54% 40% 6% !important;`}\n  }\n}\n\n${({ theme }) => TablePaddingX({ pLeft: theme.unit * 3, pRight: theme.unit * 3 })}\n` as (props: { isMobile?: boolean; lan: string; isWebEarn?: boolean } & BoxProps) => JSX.Element\n\nexport type TradePairItem = {\n  first: string\n  last: string\n}\n\nexport type RawDataAssetsItem = {\n  token: {\n    type: TokenType\n    value: string\n  }\n  amount: string\n  available: string\n  locked: string\n  tradePairList?: TradePairItem[]\n  smallBalance: boolean\n  tokenValueDollar: number\n  precision: number\n  hideDepositButton?: boolean\n  hideWithdrawButton?: boolean\n}\n\nexport type AssetsTableProps<R = RawDataAssetsItem> = {\n  rawData: R[]\n  searchValue?: string\n  isInvest?: boolean\n  pagination?: {\n    pageSize: number\n  }\n  allowTrade?: any\n  tableHeight?: number\n  onVisibleRowsChange?: (props: any) => void\n  showFilter?: boolean\n  onSend: (token: string, isToL1: boolean) => void\n  onReceive: (token: string) => void\n  isLoading?: boolean\n  getMarketArrayListCallback: (token: string) => string[]\n  rowConfig?: typeof RowConfig\n  disableWithdrawList: string[]\n  forexMap: ForexMap<sdk.Currency>\n  onTokenLockHold?: (item: R) => void\n  tokenLockDetail?:\n    | undefined\n    | {\n        list: any[]\n        row: any\n      }\n  hideAssets?: boolean\n  isLeverageETH?: boolean\n  isWebEarn?: boolean\n} & XOR<\n  {\n    hideInvestToken: boolean\n    hideSmallBalances: boolean\n    setHideLpToken: (value: boolean) => void\n    setHideSmallBalances: (value: boolean) => void\n  },\n  {}\n>\n\nexport const AssetsTable = withTranslation('tables')(\n  (props: WithTranslation & AssetsTableProps) => {\n    const {\n      t,\n      isInvest = false,\n      rawData,\n      allowTrade,\n      showFilter,\n      onReceive,\n      onSend,\n      getMarketArrayListCallback,\n      disableWithdrawList,\n      hideInvestToken,\n      hideSmallBalances,\n      setHideLpToken,\n      isLoading = false,\n      setHideSmallBalances,\n      forexMap,\n      rowConfig = RowConfig,\n      hideAssets,\n      onTokenLockHold,\n      tokenLockDetail,\n      searchValue,\n      isWebEarn,\n      ...rest\n    } = props\n    const gridRef = React.useRef(null)\n    const prevScrollTop = React.useRef(0)\n    // const container = React.useRef<HTMLDivElement>(null)\n    const [filter, setFilter] = React.useState({\n      searchValue: searchValue ?? '',\n    })\n    const [pageSize, setPageSize] = React.useState(8)\n    const [{ total, hasMore }, setTotal] = React.useState({ total: 0, hasMore: false })\n    const [page, setPage] = React.useState(1)\n    const [viewData, setViewData] = React.useState<RawDataAssetsItem[]>([])\n    const { language, isMobile, coinJson, currency } = useSettings()\n    const [modalState, setModalState] = React.useState(false)\n    React.useEffect(() => {\n      // let height = gridRef?.current?.offsetHeight\n      // @ts-ignore\n      let height = gridRef?.current?.element?.parentElement?.offsetHeight\n      if (height) {\n        const size = Math.floor((height - RowConfig.rowHeaderHeight) / RowConfig.rowHeight)\n        setPageSize((size >= 8 ? size : 8) * 2)\n      } else {\n        setPageSize(16)\n      }\n    }, [gridRef?.current])\n    const handleScroll = _.debounce(() => {\n      // const currentScrollTop = gridRef?.current?.scrollTop;\n      const currentScrollTop = window.scrollY\n      if (currentScrollTop > prevScrollTop.current) {\n        setPage((prevPage) => prevPage + 1)\n      }\n    }, 200)\n    const updateData = React.useCallback(\n      (page) => {\n        if (isWebEarn) {\n          setViewData(\n            (rawData && rawData.length > 0 ? rawData : []).filter((o) => {\n              return o.amount !== '--'\n            }),\n          )\n          return\n        }\n\n        let resultData = rawData && !!rawData.length ? [...rawData] : []\n        if (hideSmallBalances) {\n          resultData = resultData.filter((o) => !o.smallBalance)\n        }\n        // if (filter.hideLpToken) {\n        if (hideInvestToken) {\n          resultData = resultData.filter((o) => o.token.type === TokenType.single)\n        }\n        if (filter.searchValue) {\n          resultData = resultData.filter((o) =>\n            o.token.value.toLowerCase().includes(filter.searchValue.toLowerCase()),\n          )\n        }\n        if (pageSize * page >= resultData.length) {\n          setTotal({ total: resultData.length, hasMore: false })\n        } else {\n          setTotal({ total: pageSize * (page + 1 / 2), hasMore: true })\n        }\n        setViewData(resultData.slice(0, pageSize * page))\n        // resetTableData(resultData)\n      },\n      [rawData, filter, hideSmallBalances, hideInvestToken, pageSize],\n    )\n\n    React.useEffect(() => {\n      updateData(page)\n    }, [rawData, page])\n    React.useEffect(() => {\n      updateData(1)\n      return () => {\n        handleScroll.cancel()\n      }\n    }, [filter, hideInvestToken, hideSmallBalances])\n    React.useEffect(() => {\n      window.addEventListener('scroll', handleScroll)\n      return () => {\n        window.removeEventListener('scroll', handleScroll)\n      }\n    }, [])\n\n    const handleFilterChange = React.useCallback(\n      (filter: any) => {\n        setFilter(filter)\n      },\n      [setFilter],\n    )\n\n    const getColumnModeAssets = (\n      t: TFunction,\n      allowTrade?: any,\n    ): Column<RawDataAssetsItem, unknown>[] => [\n      {\n        key: 'token',\n        name: t('labelToken'),\n        formatter: ({ row, column }) => {\n          const token = row[column.key]\n          let tokenIcon: [any, any] = [undefined, undefined]\n          const [head, middle, tail] = token.value.split('-')\n          if (token.type === 'lp' && middle && tail) {\n            tokenIcon =\n              coinJson[middle] && coinJson[tail]\n                ? [coinJson[middle], coinJson[tail]]\n                : [undefined, undefined]\n          }\n          if (token.type !== 'lp' && head && head !== 'lp') {\n            tokenIcon = coinJson[head] ? [coinJson[head], undefined] : [undefined, undefined]\n          }\n          return (\n            <>\n              {isWebEarn ? (\n                <Box\n                  sx={{\n                    height: 36,\n                    width: 36,\n                    display: 'flex',\n                    justifyContent: 'center',\n                    alignItems: 'center',\n                    marginLeft: 1,\n                  }}\n                >\n                  <CoinIcons size={'large'} type={token.type} tokenIcon={tokenIcon} />\n                </Box>\n              ) : (\n                <CoinIcons type={token.type} tokenIcon={tokenIcon} />\n              )}\n\n              <Typography\n                variant={'inherit'}\n                color={'textPrimary'}\n                display={'flex'}\n                flexDirection={'column'}\n                marginLeft={2}\n                component={'span'}\n                paddingRight={1}\n              >\n                <Typography component={'span'} className={'next-coin'}>\n                  {mapSpecialTokenName(token.value)}\n                </Typography>\n              </Typography>\n            </>\n          )\n        },\n      },\n      {\n        key: 'amount',\n        name: t('labelAmount'),\n        headerCellClass: 'textAlignRight',\n        formatter: ({ row }) => {\n          const value = row['amount']\n          const precision = row['precision']\n          return (\n            <Box className={'textAlignRight'}>\n              {hideAssets\n                ? HiddenTag\n                : getValuePrecisionThousand(value, precision, precision, undefined, false, {\n                    floor: true,\n                  })}\n            </Box>\n          )\n        },\n      },\n      {\n        key: 'locked',\n        name: isWebEarn ? t('labelLocked2') : t('labelLocked'),\n        headerCellClass: 'textAlignRight',\n        formatter: ({ row }) => {\n          return (\n            <LockedMemo\n              {...{\n                ...row,\n                hideAssets,\n                onTokenLockHold: (row: any) => {\n                  if (row) {\n                    setModalState(true)\n                    onTokenLockHold && onTokenLockHold(row)\n                  }\n                },\n                tokenLockDetail,\n              }}\n            />\n          )\n        },\n      },\n      {\n        key: 'value',\n        name: t('labelAssetsTableValue'),\n        headerCellClass: 'textAlignRight',\n        formatter: ({ row }) => {\n          return (\n            <Box className={'textAlignRight'}>\n              {hideAssets\n                ? HiddenTag\n                : PriceTag[CurrencyToTag[currency]] +\n                  getValuePrecisionThousand(\n                    (row?.tokenValueDollar || 0) * (forexMap[currency] ?? 0),\n                    undefined,\n                    undefined,\n                    undefined,\n                    true,\n                    { isFait: true, floor: true },\n                  )}\n            </Box>\n          )\n        },\n      },\n      {\n        key: 'actions',\n        name: t('labelActions'),\n        headerCellClass: 'textAlignRight',\n        // minWidth: 280,\n        formatter: ({ row }) => {\n          const token = row['token']\n          const isLp = token.type === TokenType.lp\n          const tokenValue = token.value\n          const isDefi = token.type === TokenType.defi || ['CIETH', 'WSTETH', 'RETH'].includes(tokenValue)\n          const isToL1 = token.type !== TokenType.lp\n          const lpPairList = tokenValue.split('-')\n          lpPairList.splice(0, 1)\n          const lpPair = lpPairList.join('-')\n          const renderMarket: MarketType = (isLp ? lpPair : tokenValue) as MarketType\n          return (\n            <Box marginTop={isWebEarn ? '7px' : 0}>\n              <ActionMemo\n                isInvest={isInvest}\n                tokenValue={tokenValue}\n                getMarketArrayListCallback={getMarketArrayListCallback}\n                disableWithdrawList={disableWithdrawList}\n                isLp={isLp}\n                isDefi={isDefi}\n                isToL1={isToL1}\n                allowTrade={allowTrade}\n                market={renderMarket}\n                onReceive={onReceive}\n                onSend={onSend}\n                isLeverageETH={false}\n                isWebEarn={isWebEarn}\n                hideDepositButton={row.hideDepositButton}\n                hideWithdrawButton={row.hideWithdrawButton}\n              />\n            </Box>\n          )\n        },\n      },\n    ]\n    const getColumnMobileAssets = (\n      t: TFunction,\n      allowTrade?: any,\n    ): Column<RawDataAssetsItem, unknown>[] => [\n      {\n        key: 'token',\n        name: '',\n        formatter: ({ row, column }) => {\n          const token = row[column.key]\n          const value = row['amount']\n          const precision = row['precision']\n          let tokenIcon: [any, any] = [undefined, undefined]\n          const [head, middle, tail] = token.value.split('-')\n          if (token.type === 'lp' && middle && tail) {\n            tokenIcon =\n              coinJson[middle] && coinJson[tail]\n                ? [coinJson[middle], coinJson[tail]]\n                : [undefined, undefined]\n          }\n          if (token.type !== 'lp' && head && head !== 'lp') {\n            tokenIcon = coinJson[head] ? [coinJson[head], undefined] : [undefined, undefined]\n          }\n\n          return (\n            <Box display={'flex'} alignItems={'center'}>\n              <Typography width={'32px'} display={'flex'}>\n                <CoinIcons type={token.type} tokenIcon={tokenIcon} />\n              </Typography>\n              <Typography>{token.value}</Typography>\n            </Box>\n          )\n        },\n      },\n      {\n        key: 'locked',\n\n        name: '',\n        headerCellClass: 'textAlignRight',\n        formatter: ({ row, column }) => {\n          const token = row[column.key]\n          const value = row['amount']\n          const precision = row['precision']\n          let tokenIcon: [any, any] = [undefined, undefined]\n          // const [head, middle, tail] = token.value.split('-')\n          // if (token.type === 'lp' && middle && tail) {\n          //   tokenIcon =\n          //     coinJson[middle] && coinJson[tail]\n          //       ? [coinJson[middle], coinJson[tail]]\n          //       : [undefined, undefined]\n          // }\n          // if (token.type !== 'lp' && head && head !== 'lp') {\n          //   tokenIcon = coinJson[head] ? [coinJson[head], undefined] : [undefined, undefined]\n          // }\n          return (\n            <Box\n              height={'100%'}\n              display={'flex'}\n              flexDirection={'column'}\n              alignItems={'end'}\n              justifyContent={'center'}\n            >\n              <Typography display={'flex'}>\n                {hideAssets\n                  ? HiddenTag\n                  : PriceTag[CurrencyToTag[currency]] +\n                    getValuePrecisionThousand(\n                      (row?.tokenValueDollar || 0) * (forexMap[currency] ?? 0),\n                      undefined,\n                      undefined,\n                      undefined,\n                      true,\n                      { isFait: true, floor: true },\n                    )}\n              </Typography>\n              <Typography variant={'body2'} fontSize={'11px'}>\n                {t('labelTotalLocked')}:{' '}\n                {hideAssets\n                  ? HiddenTag\n                  : getValuePrecisionThousand(value, precision, precision, undefined, false, {\n                      floor: true,\n                    })}\n                /\n                {hideAssets\n                  ? HiddenTag\n                  : getValuePrecisionThousand(\n                      row['locked'],\n                      precision,\n                      precision,\n                      undefined,\n                      false,\n                      {\n                        floor: true,\n                      },\n                    )}\n              </Typography>\n            </Box>\n          )\n        },\n      },\n      {\n        key: 'actions',\n        name: '',\n        headerCellClass: 'textAlignRight',\n        // minWidth: 280,\n        formatter: ({ row }) => {\n          const token = row['token']\n          const isLp = token.type === TokenType.lp\n          const tokenValue = token.value\n          const isDefi = token.type === TokenType.defi || ['CIETH', 'WSTETH', 'RETH'].includes(tokenValue)\n          const lpPairList = tokenValue.split('-')\n          lpPairList.splice(0, 1)\n          const lpPair = lpPairList.join('-')\n          const renderMarket: MarketType = (isLp ? lpPair : tokenValue) as MarketType\n          return (\n            <ActionMemo\n              {...{\n                tokenValue,\n                getMarketArrayListCallback,\n                disableWithdrawList,\n                isLp,\n                isDefi,\n                isInvest,\n                allowTrade,\n                market: renderMarket,\n                onReceive,\n                onSend,\n                isLeverageETH: false,\n                isWebEarn: isWebEarn,\n              }}\n            />\n          )\n        },\n      },\n    ]\n\n    return (\n      <TableWrap lan={language} isMobile={isMobile} isWebEarn={isWebEarn}>\n        {!isWebEarn && showFilter && (\n          <Box marginX={2}>\n            <Filter\n              handleFilterChange={handleFilterChange}\n              filter={filter}\n              hideInvestToken={hideInvestToken}\n              hideSmallBalances={hideSmallBalances}\n              setHideLpToken={setHideLpToken}\n              setHideSmallBalances={setHideSmallBalances}\n              noHideInvestToken\n            />\n          </Box>\n        )}\n        <Modal open={modalState} onClose={() => setModalState(false)}>\n          <>\n            <LockDetailPanel tokenLockDetail={tokenLockDetail} />\n          </>\n        </Modal>\n        <Table\n          ref={gridRef}\n          className={isInvest ? 'investAsset' : ''}\n          {...{ ...rest, t }}\n          style={{\n            height:\n              viewData.length > 0\n                ? rowConfig.rowHeaderHeight + viewData.length * rowConfig.rowHeight\n                : 350,\n            minHeight: 0\n          }}\n          rowHeight={rowConfig.rowHeight}\n          headerRowHeight={isMobile ? 0 : rowConfig.rowHeaderHeight}\n          rawData={viewData}\n          generateRows={(rowData: any) => rowData}\n          generateColumns={({ columnsRaw }: any) => columnsRaw as Column<any, unknown>[]}\n          showloading={isLoading}\n          // onScroll={handleScroll}\n          columnMode={\n            (isMobile\n              ? getColumnMobileAssets(t, allowTrade)\n              : getColumnModeAssets(t, allowTrade)) as any\n          }\n        />\n        {hasMore && (\n          <Typography\n            variant={'body1'}\n            display={'inline-flex'}\n            justifyContent={'center'}\n            alignItems={'center'}\n            color={'var(--color-primary)'}\n            textAlign={'center'}\n            paddingY={1}\n          >\n            <img\n              alt={'loading'}\n              className='loading-gif'\n              width='16'\n              src={`./static/loading-1.gif`}\n              style={{ paddingRight: 1, display: 'inline-block' }}\n            />\n            {t('labelLoadingMore')}\n          </Typography>\n        )}\n      </TableWrap>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/assetsTable/VaultAssetsTable.tsx",
    "content": "import React from 'react'\nimport {Box, BoxProps, Typography} from '@mui/material'\nimport styled from '@emotion/styled'\nimport {TFunction, withTranslation, WithTranslation} from 'react-i18next'\nimport {Column, Table} from '../../basic-lib'\nimport {Filter, VaultAssetFilter} from './components/Filter'\nimport {TablePaddingX} from '../../styled'\nimport {\n  BrushIcon,\n\tCurrencyToTag,\n\tEmptyValueTag,\n\tForexMap,\n\tgetValuePrecisionThousand,\n\tHiddenTag,\n\tPriceTag,\n\tRowConfig,\n\tTokenType,\n} from '@loopring-web/common-resources'\nimport {useSettings} from '../../../stores'\nimport {CoinIcons} from './components/CoinIcons'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport {XOR} from '../../../types/lib'\nimport _ from 'lodash'\nimport { Button } from '@mui/material'\nimport Decimal from 'decimal.js'\n\nconst BgButton = styled(Button)<{ customBg: string }>`\n  background-color: ${({ customBg }) => customBg};\n  color: var(--color-text);\n  transition: all 0.2s ease-in-out;\n  &:hover {\n    background-color: ${({ customBg }) => customBg};\n    opacity: 0.8;\n  }\n  &:disabled {\n    background-color: var(--color-button-disabled);\n  }\n  \n`\n\nconst TableWrap = styled(Box)<BoxProps & { isMobile?: boolean; hideActions?: boolean; lan: string }>`\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n\n  .rdg {\n    flex: 1;\n    ${({ hideActions }) =>\n      hideActions\n        ? `--template-columns: 230px 180px auto !important;`\n        : `--template-columns: 200px 150px auto auto !important;`}\n    .rdg-cell:first-of-type {\n      display: flex;\n      align-items: center;\n      margin-top: ${({ theme }) => theme.unit / 8}px;\n    }\n\n    .rdg-cell.action {\n      display: flex;\n      justify-content: center;\n      align-items: center;\n    }\n\n    .textAlignRight {\n      text-align: right;\n    }\n  }\n\n  .investAsset.rdg {\n    ${({ isMobile }) =>\n      !isMobile\n        ? `--template-columns: 200px 150px auto auto 205px !important;`\n        : `--template-columns: 54% 40% 6% !important;`}\n  }\n}\n\n${({ theme }) => TablePaddingX({ pLeft: theme.unit * 3, pRight: theme.unit * 3 })}\n` as (props: { isMobile?: boolean; lan: string } & BoxProps) => JSX.Element\n\nexport type TradePairItem = {\n  first: string\n  last: string\n}\n\nexport type VaultDataAssetsItem = {\n  token: {\n    type: TokenType\n    value: string\n    belongAlice?: string\n  }\n  amount: string\n  available: string\n  locked: string\n  tradePairList?: TradePairItem[]\n  smallBalance: boolean\n  tokenValueDollar: number\n  erc20Symbol: string\n  precision: number\n  equity: string\n  debt: string\n  repayDisabled: boolean\n}\n\nexport type VaultAssetsTableProps<R> = {\n  rawData: R[]\n  searchValue?: string\n  pagination?: {\n    pageSize: number\n  }\n  onRowClick?: (index: number, row: R) => void\n  allowTrade?: any\n  tableHeight?: number\n  onVisibleRowsChange?: (props: any) => void\n  showFilter?: boolean\n  isLoading?: boolean\n  rowConfig?: typeof RowConfig\n  forexMap: ForexMap<sdk.Currency>\n  hideAssets?: boolean\n  actionRow: (props: { row }) => JSX.Element\n  onClickDustCollector: () => void\n  hideActions?: boolean\n  noMinHeight?: boolean\n  hideDustCollector?: boolean\n  onRowClickTrade: ({ row }) => void\n  onRowClickRepay: ({ row }) => void\n} & XOR<\n  {\n    setHideSmallBalances: (status: any) => void\n    hideSmallBalances: boolean\n  },\n  {}\n>\n\nexport const VaultAssetsTable = withTranslation('tables')(\n  <R extends VaultDataAssetsItem>(props: WithTranslation & VaultAssetsTableProps<R>) => {\n    const {\n      t,\n      rawData,\n      allowTrade,\n      showFilter,\n      onRowClick,\n      actionRow,\n      hideSmallBalances,\n      isLoading = false,\n      setHideSmallBalances,\n      forexMap,\n      rowConfig = RowConfig,\n      hideAssets,\n      searchValue,\n      onClickDustCollector,\n      hideActions,\n      noMinHeight,\n      hideDustCollector,\n      onRowClickTrade,\n      onRowClickRepay,\n      ...rest\n    } = props\n    const gridRef = React.useRef(null)\n    const prevScrollTop = React.useRef(0)\n\n    const [filter, setFilter] = React.useState({\n      searchValue: searchValue ?? '',\n    })\n    const [pageSize, setPageSize] = React.useState(8)\n    const [{ total, hasMore }, setTotal] = React.useState({ total: 0, hasMore: false })\n    const [page, setPage] = React.useState(1)\n    const [viewData, setViewData] = React.useState<R[]>([])\n    const { language, isMobile, coinJson, currency } = useSettings()\n    React.useEffect(() => {\n\n      // @ts-ignore - gridRef.current.element is accessible at runtime\n      let height = gridRef?.current?.element?.parentElement?.offsetHeight\n      if (height) {\n        const size = Math.floor((height - RowConfig.rowHeaderHeight) / RowConfig.rowHeight)\n        setPageSize((size >= 8 ? size : 8) * 2)\n      } else {\n        setPageSize(16)\n      }\n    }, [gridRef?.current])\n    const handleScroll = _.debounce(() => {\n\n      const currentScrollTop = window.scrollY\n      if (currentScrollTop > prevScrollTop.current) {\n        setPage((prevPage) => prevPage + 1)\n      }\n    }, 200)\n    const updateData = React.useCallback(\n      (page) => {\n        let resultData = rawData && !!rawData.length ? [...rawData] : []\n\n        \n        if (hideSmallBalances) {\n          const list = ['ETH', 'LRC', 'USDT']\n          resultData = resultData.filter((o) => list.includes(o.erc20Symbol) || !o.smallBalance)\n        }\n\n        if (filter.searchValue) {\n          resultData = resultData.filter((o) =>\n            o.token.value.toLowerCase().includes(filter.searchValue.toLowerCase()),\n          )\n        }\n        if (pageSize * page >= resultData.length) {\n          setTotal({ total: resultData.length, hasMore: false })\n        } else {\n          setTotal({ total: pageSize * (page + 1 / 2), hasMore: true })\n        }\n        setViewData(resultData.slice(0, pageSize * page))\n\n      },\n\t\t\t[rawData, hideSmallBalances, pageSize, filter.searchValue, setTotal, setViewData],\n    )\n\n    React.useEffect(() => {\n      updateData(page)\n    }, [rawData, page])\n    React.useEffect(() => {\n      updateData(1)\n      return () => {\n        handleScroll.cancel()\n      }\n    }, [filter, hideSmallBalances])\n    React.useEffect(() => {\n      window.addEventListener('scroll', handleScroll)\n      return () => {\n        window.removeEventListener('scroll', handleScroll)\n      }\n    }, [])\n\n    const handleFilterChange = React.useCallback(\n      (filter: any) => {\n        setFilter(filter)\n      },\n      [setFilter],\n    )\n\n    const getColumnModeAssets = (t: TFunction): Column<R, unknown>[] => [\n      {\n        key: 'token',\n        name: t('labelToken'),\n        formatter: ({ row }) => {\n          const symbol = row.erc20Symbol\n          let tokenIcon: [any, any] = [coinJson[symbol], undefined]\n          return (\n            <>\n              <CoinIcons type={TokenType.single} tokenIcon={tokenIcon} />\n              <Typography\n                variant={'inherit'}\n                color={'textPrimary'}\n                display={'flex'}\n                flexDirection={'column'}\n                marginLeft={0.5}\n                component={'span'}\n                paddingRight={1}\n              >\n                <Typography component={'span'} className={'next-coin'}>\n                  {row.token.belongAlice ?? row.token.vaule}\n                </Typography>\n              </Typography>\n            </>\n          )\n        },\n      },\n      {\n        key: 'holding',\n        name: 'Holding',\n        headerCellClass: 'textAlignRight',\n        formatter: ({ row }) => {\n          const { amount, precision } = row\n          return (\n            <Box className={'textAlignRight'}>\n              {hideAssets\n                ? HiddenTag\n                : amount && Number(amount) > 0\n                ? getValuePrecisionThousand(amount, precision, precision, undefined, false, {\n                    floor: true,\n                  })\n                : EmptyValueTag}\n            </Box>\n          )\n        },\n      },\n\n      {\n        key: 'debt',\n        name: 'Debt',\n        headerCellClass: 'textAlignRight',\n        formatter: ({ row }) => {\n          return (\n            <Box className={'textAlignRight'}>\n              {hideAssets ? HiddenTag : new Decimal(row.debt).isZero() ? EmptyValueTag : row.debt}\n            </Box>\n          )\n        },\n      },\n      {\n        key: 'equity',\n        name: 'Equity',\n        headerCellClass: 'textAlignRight',\n        formatter: ({ row }) => {\n          return (\n            <Box className={'textAlignRight'}>\n              {hideAssets\n                ? HiddenTag\n                : new Decimal(row.equity).isZero()\n                ? EmptyValueTag\n                : row.equity}\n            </Box>\n          )\n        },\n      },\n      ...(!hideActions\n        ? [\n            {\n              key: 'actions',\n              name: t('labelActions'),\n              headerCellClass: 'textAlignRight',\n              cellClass: 'textAlignRight',\n              formatter: ({ row }) => {\n                return (\n                  <Box\n                    height={'100%'}\n                    display={'flex'}\n                    alignItems={'center'}\n                    justifyContent={'flex-end'}\n                  >\n                    <Button\n                      onClick={(e) => {\n                        e.stopPropagation()\n                        onRowClickTrade({ row })\n                      }}\n                    >\n                      {t('labelTrade')}\n                    </Button>\n                    <Button\n                      sx={{\n                        opacity: row.repayDisabled ? 0.5 : 1,\n                      }}\n                      onClick={(e) => {\n                        e.stopPropagation()\n                        if (row.repayDisabled) return\n                        onRowClickRepay({ row })\n                      }}\n                    >\n                      Repay\n                    </Button>\n                  </Box>\n                )\n              },\n            },\n          ]\n        : []),\n    ]\n\t\tconst getColumnMobileAssets = (t: TFunction): Column<R, unknown>[] => [\n\n      {\n        key: 'token',\n        name: t('labelToken'),\n        formatter: ({ row }) => {\n          const symbol = row.erc20Symbol\n          let tokenIcon: [any, any] = [coinJson[symbol], undefined]\n          return (\n            <>\n              <CoinIcons type={TokenType.single} tokenIcon={tokenIcon} />\n              <Typography\n                variant={'inherit'}\n                color={'textPrimary'}\n                display={'flex'}\n                flexDirection={'column'}\n                marginLeft={0.5}\n                component={'span'}\n                paddingRight={1}\n              >\n                <Typography component={'span'} className={'next-coin'}>\n                  {row.token.belongAlice ?? row.token.vaule}\n                </Typography>\n              </Typography>\n            </>\n          )\n        },\n      },\n      {\n        key: 'holding',\n        name: 'Holding',\n        headerCellClass: 'textAlignLeft',\n        formatter: ({ row }) => {\n          const { amount, precision } = row\n          return (\n            <Box className={'textAlignLeft'}>\n              {hideAssets\n                ? HiddenTag\n                : amount && Number(amount) > 0\n                ? getValuePrecisionThousand(amount, precision, precision, undefined, false, {\n                    floor: true,\n                  })\n                : EmptyValueTag}\n            </Box>\n          )\n        },\n      },\n      {\n        key: 'actions',\n        name: t('labelActions'),\n        headerCellClass: 'textAlignRight',\n\n        formatter: ({ row }) => {\n          return (\n            <Box height={'100%'} display={'flex'} alignItems={'center'} justifyContent={'flex-end'}>\n              <Button\n                onClick={(e) => {\n                  e.stopPropagation()\n                  onRowClickTrade({ row })\n                }}\n                size='small'\n              >\n                {t('labelTrade')}\n              </Button>\n              <Button\n                sx={{\n                  opacity: row.repayDisabled ? 0.5 : 1,\n                }}\n                size='small'\n                onClick={(e) => {\n                  e.stopPropagation()\n                  if (row.repayDisabled) return\n                  onRowClickRepay({ row })\n                }}\n              >\n                Repay\n              </Button>\n            </Box>\n          )\n        },\n      },\n    ]\n\n\n    const MobileCardView = () => {\n      return (\n        <Box display=\"flex\" flexDirection=\"column\" width=\"100%\">\n          {viewData.map((row, index) => {\n            const symbol = row.erc20Symbol;\n            let tokenIcon: [any, any] = [coinJson[symbol], undefined];\n            return (\n              <Box\n                key={`asset-card-${index}`}\n                sx={{\n                  mb: 1.5,\n                  p: 2,\n                  backgroundColor: 'var(--color-box)',\n                }}\n              >\n                <Box display='flex' justifyContent='space-between' alignItems='center' mb={1}>\n                  <Box display='flex' alignItems='center'>\n                    <CoinIcons type={TokenType.single} tokenIcon={tokenIcon} />\n                    <Typography variant='body1' ml={1}>\n                      {row.token.belongAlice ?? row.token.value}\n                    </Typography>\n                  </Box>\n                  <Typography variant='h5'>\n                    {hideAssets\n                      ? HiddenTag\n                      : row.amount && Number(row.amount) > 0\n                      ? getValuePrecisionThousand(\n                          row.amount,\n                          row.precision,\n                          row.precision,\n                          undefined,\n                          false,\n                          {\n                            floor: true,\n                          },\n                        )\n                      : EmptyValueTag}\n                  </Typography>\n                </Box>\n\n                <Box display='flex' flexDirection='column' mb={2}>\n                  <Box mt={3} display='flex' justifyContent='space-between'>\n                    <Typography variant='body2' color='var(--color-text-secondary)'>\n                      Debt\n                    </Typography>\n                    <Typography variant='body1' color='var(--color-text-secondary)'>\n                      {hideAssets\n                        ? HiddenTag\n                        : new Decimal(row.debt).isZero()\n                        ? EmptyValueTag\n                        : row.debt}\n                    </Typography>\n                  </Box>\n                  <Box mt={1.5} display='flex' justifyContent='space-between'>\n                    <Typography variant='body2' color='var(--color-text-secondary)'>\n                      Equity\n                    </Typography>\n                    <Typography variant='body1' color='var(--color-text-secondary)'>\n                      {hideAssets\n                        ? HiddenTag\n                        : new Decimal(row.equity).isZero()\n                        ? EmptyValueTag\n                        : row.equity}\n                    </Typography>\n                  </Box>\n                </Box>\n\n                {!hideActions && (\n                  <Box display='grid' gridTemplateColumns='1fr 1fr' gap={2}>\n                    <BgButton\n                      customBg='var(--color-button-outlined)'\n                      variant='outlined'\n                      fullWidth\n                      size='medium'\n                      onClick={() => onRowClickTrade({ row })}\n                    >\n                      {t('labelTrade')}\n                    </BgButton>\n                    <BgButton\n                      customBg='var(--color-button-outlined)'\n                      variant='outlined'\n                      fullWidth\n                      size='medium'\n                      sx={{\n                        opacity: row.repayDisabled ? 0.5 : 1,\n                      }}\n                      onClick={() => {\n                        if (!row.repayDisabled) {\n                          onRowClickRepay({ row })\n                        }\n                      }}\n                    >\n                      Repay\n                    </BgButton>\n                  </Box>\n                )}\n              </Box>\n            )\n          })}\n        </Box>\n      );\n    };\n\n    return (\n      <TableWrap lan={language} isMobile={isMobile}>\n        {showFilter && (\n          <Box marginX={2} display={'flex'} alignItems={'center'}>\n            <Box>\n              <VaultAssetFilter\n                handleFilterChange={handleFilterChange}\n                filter={filter}\n                hideSmallBalances={hideSmallBalances}\n                setHideSmallBalances={setHideSmallBalances}\n                noHideInvestToken\n              />\n            </Box>\n\n            {!hideDustCollector && <Box\n              sx={{ \n                marginLeft: 3,\n              }}\n              component={'button'}\n              onClick={onClickDustCollector}\n              color={'var(--color-text-primary)'}\n              display={'flex'}\n              alignItems={'center'}\n            >\n              <BrushIcon\n                sx={{ fontSize: '24px', color: 'inherit', marginRight: 0.5 }}\n              />{' '}\n              {t('labelVaultDustCollector')}\n            </Box>}\n          </Box>\n        )}\n        \n        {isMobile ? (\n          <Box padding={2}>\n            <MobileCardView />\n          </Box>\n        ) : (\n          <>\n            <Table\n              ref={gridRef}\n              className={''}\n              {...{ ...rest, t }}\n              style={{\n                height: total > 0 ? rowConfig.rowHeaderHeight + total * rowConfig.rowHeight : 350,\n                minHeight: noMinHeight ? 0 : undefined\n              }}\n              onRowClick={onRowClick as any}\n              rowHeight={rowConfig.rowHeight}\n              headerRowHeight={rowConfig.rowHeaderHeight}\n              rawData={viewData}\n              generateRows={(rowData: any) => rowData}\n              generateColumns={({ columnsRaw }: any) => columnsRaw as Column<any, unknown>[]}\n              showloading={isLoading}\n              columnMode={getColumnModeAssets(t) as any}\n            />\n            {hasMore && (\n              <Typography\n                variant={'body1'}\n                display={'inline-flex'}\n                justifyContent={'center'}\n                alignItems={'center'}\n                color={'var(--color-primary)'}\n                textAlign={'center'}\n                paddingY={1}\n              >\n                <img\n                  alt={'loading'}\n                  className='loading-gif'\n                  width='16'\n                  src={`./static/loading-1.gif`}\n                  style={{ paddingRight: 1, display: 'inline-block' }}\n                />\n                {t('labelLoadingMore')}\n              </Typography>\n            )}\n          </>\n        )}\n      </TableWrap>\n    )\n\t},\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/assetsTable/VaultPositionsTable.tsx",
    "content": "import React from 'react'\nimport { Box, BoxProps, Typography } from '@mui/material'\nimport styled from '@emotion/styled'\nimport { TFunction, withTranslation, WithTranslation } from 'react-i18next'\nimport { Column, Table } from '../../basic-lib'\nimport { VaultAssetFilter } from './components/Filter'\nimport { TablePaddingX } from '../../styled'\nimport { BrushIcon, hexToRGB, HiddenTag, MarginLevelIcon, RowConfig, TokenType } from '@loopring-web/common-resources'\nimport { useSettings } from '../../../stores'\nimport { CoinIcons, CoinIconsNew } from './components/CoinIcons'\nimport _ from 'lodash'\nimport { Button } from '@mui/material'\nimport { useTheme } from '@emotion/react'\nimport { marginLevelType } from '@loopring-web/core/src/hooks/useractions/vault/utils'\n\nconst TableWrap = styled(Box)<BoxProps & { isMobile?: boolean; lan: string }>`\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n\n  .rdg {\n    flex: 1;\n    ${({ isMobile }) =>\n      isMobile\n        ? `--template-columns: 30% auto 50% !important;`\n        : `--template-columns: 250px auto auto 290px !important;`}\n    .rdg-cell:first-of-type {\n      display: flex;\n      align-items: center;\n      margin-top: ${({ theme }) => theme.unit / 8}px;\n    }\n\n    .rdg-cell.action {\n      display: flex;\n      justify-content: center;\n      align-items: center;\n    }\n\n    .textAlignRight {\n      text-align: right;\n    }\n  }\n\n}\n\n${({ theme }) => TablePaddingX({ pLeft: theme.unit * 3, pRight: theme.unit * 3 })}\n` as (props: { isMobile?: boolean; lan: string } & BoxProps) => JSX.Element\n\nexport type PositionItem = {\n  tokenPair: {\n    coinJson: any\n    pair: string\n    leverage: string\n    marginLevel: string\n  }\n  direction: 'long' | 'short'\n  holding: string\n  onClickTrade: () => void\n  onClickClose: () => void\n}\n\nexport type VaultPositionsTableProps = {\n  rawData: PositionItem[]\n  onRowClick?: (index: number, row: PositionItem) => void\n  isLoading?: boolean\n  rowConfig?: typeof RowConfig\n  hideAssets?: boolean\n  showFilter?: boolean\n  hideSmallBalances?: boolean\n  setHideSmallBalances?: (status: boolean) => void\n  hideDustCollector?: boolean\n  onClickDustCollector?: () => void\n}\n\nexport const VaultPositionsTable = withTranslation('tables')(\n  (props: WithTranslation & VaultPositionsTableProps) => {\n    const {\n      t,\n      rawData,\n      onRowClick,\n      rowConfig = RowConfig,\n      hideAssets,\n      showFilter,\n      hideSmallBalances = false,\n      setHideSmallBalances,\n      hideDustCollector = false,\n      onClickDustCollector,\n      isLoading,\n      ...rest\n    } = props\n    const total  = rawData.length\n    const { language, isMobile } = useSettings()\n    const theme = useTheme()\n    const [filter, setFilter] = React.useState({\n      searchValue: '',\n    })\n\n    const handleFilterChange = React.useCallback(\n      (props: { searchValue: string }) => {\n        setFilter(props)\n      },\n      [setFilter]\n    )\n\n    const getColumnModeAssets = (t: TFunction): Column<PositionItem, unknown>[] => [\n      {\n        key: 'token',\n        name: t('labelToken'),\n        formatter: ({ row }) => {\n          return (\n            <Box height={'100%'} display={'flex'} alignItems={'center'}>\n              <CoinIcons type={TokenType.single} tokenIcon={[row.tokenPair.coinJson?.[0]]} />\n\n              <Typography\n                variant={'inherit'}\n                color={'var(--color-text-primary)'}\n                flexDirection={'column'}\n                marginLeft={1}\n                component={'span'}\n                paddingRight={1}\n                width={'80px'}\n              >\n                {row.tokenPair.pair}\n              </Typography>\n             \n            </Box>\n          )\n        },\n      },\n      {\n        key: 'direction',\n        name: 'Direction',\n        headerCellClass: 'textAlignRight',\n        formatter: ({ row }) => {\n          return (\n            <Box\n              className={'textAlignRight'}\n              color={row.direction === 'long' ? 'var(--color-success)' : 'var(--color-error)'}\n            >\n              {row.direction === 'long' ? 'Long' : 'Short'}\n            </Box>\n          )\n        },\n      },\n      {\n        key: 'holding',\n        name: 'Holding',\n        headerCellClass: 'textAlignRight',\n        formatter: ({ row }) => {\n          return <Box className={'textAlignRight'}>{hideAssets ? HiddenTag : row.holding}</Box>\n        },\n      },\n\n      {\n        key: 'actions',\n        name: t('labelActions'),\n        headerCellClass: 'textAlignRight',\n        cellClass: 'textAlignRight',\n        formatter: ({ row }) => {\n          return (\n            <Box height={'100%'} display={'flex'} alignItems={'center'} justifyContent={'flex-end'}>\n              <Button\n                onClick={(e) => {\n                  e.stopPropagation()\n                  row.onClickTrade()\n                }}\n                size={'medium'}\n              >\n                Trade\n              </Button>\n              <Button\n                onClick={(e) => {\n                  e.stopPropagation()\n                  row.onClickClose()\n                }}\n                size={'medium'}\n              >\n                Close\n              </Button>\n            </Box>\n          )\n        },\n      },\n    ]\n    const getColumnMobileAssets = (t: TFunction): Column<PositionItem, unknown>[] => [\n      {\n        key: 'token',\n        name: t('labelToken'),\n        formatter: ({ row }) => {\n          return (\n            <Box height={'100%'} display={'flex'} alignItems={'center'}>\n              <Typography\n                variant={'inherit'}\n                color={'var(--color-text-primary)'}\n                flexDirection={'column'}\n                component={'span'}\n                paddingRight={1}\n                width={'80px'}\n              >\n                {row.tokenPair.pair}\n              </Typography>\n            </Box>\n          )\n        },\n      },\n      {\n        key: 'holding',\n        name: 'Holding',\n        headerCellClass: 'textAlignRight',\n        formatter: ({ row }) => {\n          return <Box className={'textAlignRight'}>\n            <Typography mr={1} component={'span'} color={row.direction === 'long' ? 'var(--color-success)' : 'var(--color-error)'}>{row.direction === 'long' ? 'Long' : 'Short'}</Typography>\n            {hideAssets ? HiddenTag : row.holding}\n            </Box>\n        },\n      },\n\n      {\n        key: 'actions',\n        name: t('labelActions'),\n        headerCellClass: 'textAlignRight',\n        cellClass: 'textAlignRight',\n        formatter: ({ row }) => {\n          return (\n            <Box height={'100%'} display={'flex'} alignItems={'center'} justifyContent={'flex-end'}>\n              <Button\n                onClick={(e) => {\n                  e.stopPropagation()\n                  row.onClickTrade()\n                }}\n                size={'small'}\n              >\n                Trade\n              </Button>\n              <Button\n                onClick={(e) => {\n                  e.stopPropagation()\n                  row.onClickClose()\n                }}\n                size={'small'}\n              >\n                Close\n              </Button>\n            </Box>\n          )\n        },\n      },\n    ]\n\n    return (\n      <TableWrap lan={language} isMobile={isMobile}>\n        {/* {showFilter && (\n          <Box marginX={2} display={'flex'} alignItems={'center'}>\n            <Box>\n              <VaultAssetFilter\n                handleFilterChange={handleFilterChange}\n                filter={filter}\n                hideSmallBalances={hideSmallBalances}\n                setHideSmallBalances={setHideSmallBalances}\n                noHideInvestToken\n              />\n            </Box>\n\n            {!hideDustCollector && <Typography\n              sx={{ cursor: 'pointer' }}\n              component={'span'}\n              onClick={onClickDustCollector}\n              width={'140px'}\n              color={'var(--color-text-primary)'}\n              display={'flex'}\n              alignItems={'center'}\n            >\n              <BrushIcon\n                sx={{ fontSize: '24px', color: 'inherit', marginLeft: 1, marginRight: 0.5 }}\n              />{' '}\n              {t('labelVaultDustCollector')}\n            </Typography>}\n          </Box>\n        )} */}\n        <Table\n          {...rest}\n          style={{\n            height: total > 0 ? rowConfig.rowHeaderHeight + total * rowConfig.rowHeight : 200,\n            minHeight: 0,\n          }}\n          onRowClick={onRowClick as any}\n          rowHeight={rowConfig.rowHeight}\n          headerRowHeight={rowConfig.rowHeaderHeight}\n          rawData={rawData}\n          generateRows={(rowData: any) => rowData}\n          generateColumns={({ columnsRaw }: any) => columnsRaw as Column<any, unknown>[]}\n          showloading={isLoading}\n          columnMode={(isMobile ? getColumnMobileAssets(t) : getColumnModeAssets(t)) as any}\n          t={t}\n          EmptyRowsRenderer={\n            <Box display='flex' justifyContent='center' alignItems='center' mt={9}>\n              <Typography color='var(--color-text-secondary)'>No positions</Typography>\n            </Box>\n          }\n        />\n      </TableWrap>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/assetsTable/assetsTable.stories.tsx",
    "content": "import styled from '@emotion/styled'\nimport { Meta, Story } from '@storybook/react'\nimport { withTranslation } from 'react-i18next'\nimport { MemoryRouter } from 'react-router-dom'\nimport { AssetsTable, RawDataAssetsItem } from './index'\nimport { TokenType } from '@loopring-web/common-resources'\n\nconst Style = styled.div`\n  flex: 1;\n  height: 100%;\n`\nconst rawData: RawDataAssetsItem[] = [\n  {\n    token: {\n      type: TokenType.single,\n      value: 'LRC',\n    },\n    tokenValueDollar: 112,\n    amount: '25987.09324',\n    available: '25987.01234',\n    locked: '5.9873',\n    tradePairList: [\n      {\n        first: 'LRC',\n        last: 'ETH',\n      },\n      {\n        first: 'LRC',\n        last: 'BTC',\n      },\n      {\n        first: 'LRC',\n        last: 'LTC',\n      },\n    ],\n    smallBalance: false,\n  },\n  {\n    token: {\n      type: TokenType.lp,\n      value: 'LP-LRC-USDT',\n    },\n    tokenValueDollar: 112,\n    amount: '987.09324',\n    available: '887.01234',\n    locked: '115.9873',\n    tradePairList: undefined,\n    smallBalance: true,\n  },\n  {\n    token: {\n      type: TokenType.lp,\n      value: 'LP-ETH-USDT',\n    },\n    tokenValueDollar: 112,\n    amount: '15987.09324',\n    available: '15687.01234',\n    locked: '312.9073',\n    tradePairList: undefined,\n    smallBalance: false,\n  },\n  {\n    token: {\n      type: TokenType.single,\n      value: 'LRC',\n    },\n    tokenValueDollar: 112,\n    amount: '25987.09324',\n    available: '25987.01234',\n    locked: '5.9873',\n    tradePairList: [\n      {\n        first: 'LRC',\n        last: 'ETH',\n      },\n      {\n        first: 'LRC',\n        last: 'BTC',\n      },\n      {\n        first: 'LRC',\n        last: 'LTC',\n      },\n    ],\n    smallBalance: false,\n  },\n  {\n    token: {\n      type: TokenType.lp,\n      value: 'LP-LRC-USDT',\n    },\n    tokenValueDollar: 112,\n    amount: '987.09324',\n    available: '887.01234',\n    locked: '115.9873',\n    tradePairList: undefined,\n    smallBalance: true,\n  },\n  {\n    token: {\n      type: TokenType.lp,\n      value: 'LP-ETH-USDT',\n    },\n    tokenValueDollar: 112,\n    amount: '15987.09324',\n    available: '15687.01234',\n    locked: '312.9073',\n    tradePairList: undefined,\n    smallBalance: false,\n  },\n  {\n    token: {\n      type: TokenType.single,\n      value: 'LRC',\n    },\n    tokenValueDollar: 112,\n    amount: '25987.09324',\n    available: '25987.01234',\n    locked: '5.9873',\n    tradePairList: [\n      {\n        first: 'LRC',\n        last: 'ETH',\n      },\n      {\n        first: 'LRC',\n        last: 'BTC',\n      },\n      {\n        first: 'LRC',\n        last: 'LTC',\n      },\n    ],\n    smallBalance: false,\n  },\n  {\n    token: {\n      type: TokenType.lp,\n      value: 'LP-LRC-USDT',\n    },\n    tokenValueDollar: 112,\n    amount: '987.09324',\n    available: '887.01234',\n    locked: '115.9873',\n    tradePairList: undefined,\n    smallBalance: true,\n  },\n  {\n    token: {\n      type: TokenType.lp,\n      value: 'LP-ETH-USDT',\n    },\n    tokenValueDollar: 112,\n    amount: '15987.09324',\n    available: '15687.01234',\n    locked: '312.9073',\n    tradePairList: undefined,\n    smallBalance: false,\n  },\n  {\n    token: {\n      type: TokenType.single,\n      value: 'LRC',\n    },\n    tokenValueDollar: 112,\n    amount: '25987.09324',\n    available: '25987.01234',\n    locked: '5.9873',\n    tradePairList: [\n      {\n        first: 'LRC',\n        last: 'ETH',\n      },\n      {\n        first: 'LRC',\n        last: 'BTC',\n      },\n      {\n        first: 'LRC',\n        last: 'LTC',\n      },\n    ],\n    smallBalance: false,\n  },\n  {\n    token: {\n      type: TokenType.lp,\n      value: 'LP-LRC-USDT',\n    },\n    tokenValueDollar: 112,\n    amount: '987.09324',\n    available: '887.01234',\n    locked: '115.9873',\n    tradePairList: undefined,\n    smallBalance: true,\n  },\n  {\n    token: {\n      type: TokenType.lp,\n      value: 'LP-ETH-USDT',\n    },\n    tokenValueDollar: 112,\n    amount: '15987.09324',\n    available: '15687.01234',\n    locked: '312.9073',\n    tradePairList: undefined,\n    smallBalance: false,\n  },\n]\n\nconst Template: Story<any> = withTranslation()((args: any) => {\n  return (\n    <>\n      <Style>\n        <MemoryRouter initialEntries={['/']}>\n          <AssetsTable {...args} />\n          <div style={{ marginTop: 24 }}>\n            <AssetsTable\n              {...args}\n              pagination={{\n                pageSize: 5,\n              }}\n              showFilter\n            />\n          </div>\n        </MemoryRouter>\n      </Style>\n    </>\n  )\n}) as Story<any>\n//@ts-ignore\nexport const Assets = Template.bind({})\n\nAssets.args = {\n  rawData: rawData,\n  // pagination: {\n  //     pageSize: 5\n  // }\n  onVisibleRowsChange: (data: any) => {\n    console.log(data)\n  },\n}\n\nexport default {\n  title: 'components/TableList/Assets',\n  component: AssetsTable,\n  argTypes: {},\n} as Meta\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/assetsTable/components/ActionMemo.tsx",
    "content": "import React from 'react'\nimport { Box, Grid, ListItemText, MenuItem, Typography } from '@mui/material'\nimport styled from '@emotion/styled'\nimport { Button, Popover, PopoverType, PopoverWrapProps } from '../../../basic-lib'\nimport {\n  EmptyValueTag,\n  getValuePrecisionThousand,\n  HiddenTag,\n  MapChainId,\n  MoreIcon,\n  LEVERAGE_ETH_CONFIG,\n  AmmPanelType,\n  InvestAssetRouter,\n  RouterPath,\n} from '@loopring-web/common-resources'\nimport { useHistory } from 'react-router-dom'\nimport { useOpenModals, useSettings, useToggle } from '../../../../stores'\nimport { RawDataAssetsItem } from '../AssetsTable'\nimport { useTranslation } from 'react-i18next'\n\nconst GridStyled = styled(Grid)`\n  .MuiGrid-item {\n    padding: ${({ theme }) => theme.unit / 4}px 0 0;\n  }\n`\nexport type ActionProps = {\n  tokenValue: any\n  allowTrade?: any\n  market?: `${string}-${string}`\n  isLp: boolean\n  isDefi: boolean\n  isInvest: boolean\n  onSend: (token: string, isToL1: boolean) => void\n  onReceive: (token: string) => void\n\n  getMarketArrayListCallback?: (token: string) => string[]\n  isLeverageETH: boolean\n  isWebEarn?: boolean\n  hideDepositButton?: boolean\n  hideWithdrawButton?: boolean\n}\nconst ActionPopContent = React.memo(\n  ({\n    market,\n    isLp,\n    isDefi,\n    allowTrade,\n    onSend,\n    onReceive,\n    // onShowDeposit,\n    tokenValue,\n    isInvest,\n    // onShowTransfer,\n    // onShowWithdraw,\n    getMarketArrayListCallback,\n    isLeverageETH,\n    isWebEarn,\n  }: ActionProps) => {\n    const history = useHistory()\n    const { t } = useTranslation(['tables', 'common'])\n    const { setShowAmm } = useOpenModals()\n    const { toggle } = useToggle()\n    const _allowTrade = {\n      ...toggle,\n      allowTrade,\n    }\n    const { isMobile } = useSettings()\n    const tradeList = [\n      ...[\n        <MenuItem key={'token-Receive'} onClick={() => onReceive(tokenValue)}>\n          <ListItemText>{isWebEarn ? t('labelDeposit') : t('labelReceive')}</ListItemText>\n        </MenuItem>,\n        <MenuItem key={'token-Send'} onClick={() => onSend(tokenValue, isLp)}>\n          <ListItemText>{isWebEarn ? t('labelWithdraw') : t('labelSend')}</ListItemText>\n        </MenuItem>,\n      ],\n      // ...(isToL1\n      //   ? [\n      //       <MenuItem onClick={() => onShowWithdraw(tokenValue)}>\n      //         <ListItemText>{t(\"labelL2toL1Action\")}</ListItemText>\n      //       </MenuItem>,\n      //     ]\n      //   : []),\n    ]\n    \n    const marketList = (isLp || isWebEarn)\n      ? []\n      : getMarketArrayListCallback &&\n        market &&\n        getMarketArrayListCallback(market).filter((pair) => {\n          const [first, last] = pair.split('-')\n          if (['USDT', 'USDC'].includes(first) || ['USDT', 'USDC'].includes(last)) {\n            return true\n          }\n          return first === market\n        })\n    const { defaultNetwork } = useSettings()\n    const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n    const coins = LEVERAGE_ETH_CONFIG.coins[network]\n    return (\n      <Box borderRadius={'inherit'} minWidth={110}>\n        {isMobile && tradeList.map((item) => <>{item}</>)}\n        {isLp ? (\n          <>\n            <MenuItem\n              disabled={!_allowTrade?.joinAmm?.enable}\n              onClick={() => {\n                setShowAmm({\n                  isShow: true,\n                  type: AmmPanelType.Join,\n                  symbol: market,\n                })\n              }}\n            >\n              <ListItemText>{t('labelPoolTableAddLiquidity')}</ListItemText>\n            </MenuItem>\n            <MenuItem\n              onClick={() => {\n                setShowAmm({\n                  isShow: true,\n                  type: AmmPanelType.Exit,\n                  symbol: market,\n                })\n              }}\n            >\n              <ListItemText>{t('labelPoolTableRemoveLiquidity')}</ListItemText>\n            </MenuItem>\n          </>\n        ) : isDefi || isLeverageETH ? (\n          isInvest && !isMobile ? (\n            <>\n              {tradeList.map((item) => (\n                <>{item}</>\n              ))}\n            </>\n          ) : (\n            <>\n              {!['CIETH', 'WSTETH', 'RETH'].includes(tokenValue) && (\n                <MenuItem\n                  disabled={!_allowTrade?.[`${tokenValue}Invest`]?.enable}\n                  onClick={() => {\n                    if (coins.includes(tokenValue)) {\n                      history.push(`${RouterPath.invest}/${InvestAssetRouter.LEVERAGEETH}`)\n                    } else {\n                      history.push(\n                        `${RouterPath.invest}/${InvestAssetRouter.STAKE}/${tokenValue}-null/invest`,\n                      )\n                    }\n                  }}\n                >\n                  <ListItemText>{t('labelDefiInvest')}</ListItemText>\n                </MenuItem>\n              )}\n              <MenuItem\n                disabled={!_allowTrade?.[`${tokenValue}Invest`]?.enable}\n                onClick={() => {\n                  if (coins.includes(tokenValue)) {\n                    history.push(`${RouterPath.invest}/${InvestAssetRouter.LEVERAGEETH}/redeem`)\n                  } else {\n                    history.push(\n                      `${RouterPath.invest}/${InvestAssetRouter.STAKE}/${tokenValue}-null/redeem`,\n                    )\n                  }\n                }}\n              >\n                <ListItemText>{t('labelDefiRedeem')}</ListItemText>\n              </MenuItem>\n            </>\n          )\n        ) : (\n          marketList?.map((pair) => {\n            const formattedPair = pair.replace('-', ' / ')\n            return (\n              <MenuItem\n                key={pair}\n                onClick={() =>\n                  history.push({\n                    pathname: `/trade/lite/${pair}`,\n                  })\n                }\n              >\n                <ListItemText>{formattedPair}</ListItemText>\n              </MenuItem>\n            )\n          })\n        )}\n      </Box>\n    )\n  },\n)\n\nconst ActionMemo = React.memo((props: ActionProps) => {\n  const { isMobile } = useSettings()\n  const history = useHistory()\n  const { t } = useTranslation('tables')\n  const {\n    allowTrade,\n    tokenValue,\n    onSend,\n    onReceive,\n    isLp,\n    isInvest = false,\n    isDefi,\n    // onShowDeposit,\n    // onShowTransfer,\n    // onShowWithdraw,\n    isLeverageETH,\n    isWebEarn,\n    hideDepositButton,\n    hideWithdrawButton\n  } = props\n  const popoverProps: PopoverWrapProps = {\n    type: PopoverType.click,\n    popupId: 'testPopup',\n    className: 'arrow-none',\n    children: <MoreIcon cursor={'pointer'} />,\n    popoverContent: <ActionPopContent {...props} />,\n    anchorOrigin: {\n      vertical: 'bottom',\n      horizontal: 'right',\n    },\n    transformOrigin: {\n      vertical: 'top',\n      horizontal: 'right',\n    },\n  } as PopoverWrapProps\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const coins = LEVERAGE_ETH_CONFIG.coins[network]\n  return (\n    <GridStyled\n      container\n      spacing={1}\n      justifyContent={isWebEarn ? 'flex-end' : 'space-between'}\n      alignItems={'center'}\n      flexWrap={'nowrap'}\n    >\n      {isMobile ? (\n        <>\n          {((!isLp && allowTrade?.order?.enable) || isLp || isDefi || isLeverageETH) && (\n            <Grid item marginTop={1}>\n              <Popover {...{ ...popoverProps }} />\n            </Grid>\n          )}\n        </>\n      ) : (\n        <>\n          <Box display={'flex'}>\n            {isInvest ? (\n              <>\n                {!['CIETH', 'WSTETH', 'RETH'].includes(tokenValue) && (\n                  <Grid item>\n                    <Button\n                      variant={'text'}\n                      size={'small'}\n                      color={'primary'}\n                      onClick={() => {\n                        if (coins.includes(tokenValue)) {\n                          history.push(`${RouterPath.invest}/${InvestAssetRouter.LEVERAGEETH}`)\n                        } else {\n                          history.push(\n                            `${RouterPath.invest}/${InvestAssetRouter.STAKE}/${tokenValue}-null/invest`,\n                          )\n                        }\n                      }}\n                    >\n                      {t('labelDefiInvest')}\n                    </Button>\n                  </Grid>\n                )}\n                <Grid item>\n                  <Button\n                    variant={'text'}\n                    size={'small'}\n                    color={'primary'}\n                    onClick={() => {\n                      if (coins.includes(tokenValue)) {\n                        history.push(`${RouterPath.invest}/${InvestAssetRouter.LEVERAGEETH}/redeem`)\n                      } else {\n                        history.push(\n                          `${RouterPath.invest}/${InvestAssetRouter.STAKE}/${tokenValue}-null/redeem`,\n                        )\n                      }\n                    }}\n                  >\n                    {t('labelDefiRedeem')}\n                  </Button>\n                </Grid>\n              </>\n            ) : (\n              <>\n                {!hideDepositButton &&<Grid item>\n                  <Button\n                    variant={'text'}\n                    size={'small'}\n                    color={'primary'}\n                    onClick={() => onReceive(tokenValue)}\n                  >\n                    {isWebEarn ? t('labelDeposit') : t('labelReceive')}\n                  </Button>\n                </Grid>}\n                {!hideWithdrawButton && <Grid item>\n                  <Button\n                    variant={'text'}\n                    size={'small'}\n                    color={'primary'}\n                    onClick={() => onSend(tokenValue, isLp)}\n                  >\n                    {isWebEarn ? t('labelWithdraw') : t('labelSend')}\n                  </Button>\n                </Grid>}\n              </>\n            )}\n          </Box>\n          {!isWebEarn && !isLp && !isInvest && allowTrade?.order?.enable && (\n            <Grid item marginTop={1}>\n              <Popover {...{ ...popoverProps }} />\n            </Grid>\n          )}\n          {(isLp || isInvest || isLeverageETH) && (\n            <Grid item marginTop={1}>\n              <Popover {...{ ...popoverProps }} />\n            </Grid>\n          )}\n        </>\n      )}\n    </GridStyled>\n  )\n})\nexport default ActionMemo\n\nexport const LockedMemo = React.memo(\n  (\n    props: Omit<RawDataAssetsItem, 'smallBalance' | 'tokenValueDollar'> & {\n      hideAssets?: boolean\n      onTokenLockHold?: (item: any) => void\n      tokenLockDetail?:\n        | undefined\n        | {\n            list: any[]\n            row: any\n          }\n    },\n  ) => {\n    const { onTokenLockHold, tokenLockDetail, ...row } = props\n    const value = row['locked']\n    const precision = row['precision']\n    // myLog(tokenLockDetail);\n    if (!Number(value)) {\n      return <Box className={'textAlignRight'}>{EmptyValueTag}</Box>\n    } else {\n      return (\n        <Box className={'textAlignRight'}>\n          <Typography\n            display={'inline-flex'}\n            alignItems={'center'}\n            component={'span'}\n            sx={{\n              textDecoration: onTokenLockHold ? 'underline dotted' : '',\n              cursor: 'pointer',\n            }}\n            // @ts-ignore\n            onClick={(e) => {\n              if (onTokenLockHold) {\n                onTokenLockHold(row)\n              }\n            }}\n          >\n            {props.hideAssets\n              ? HiddenTag\n              : getValuePrecisionThousand(value, precision, precision, undefined, false, {\n                  floor: true,\n                })}\n          </Typography>\n        </Box>\n      )\n    }\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/assetsTable/components/CoinIcons.tsx",
    "content": "import React from 'react'\nimport { Avatar, Box, BoxProps, styled, Typography } from '@mui/material'\nimport { CoinInfo, CoinSource, SoursURL, TokenType } from '@loopring-web/common-resources'\nimport { AvatarCoin, VaultTag } from '../../../basic-lib'\nimport { useSettings } from '../../../../stores'\n\nconst BoxStyle = styled(Box)<BoxProps & { size: number }>`\n  ${({ size }) => {\n    return `\n    .logo-icon.dual:last-child {\n      transform: scale(0.6) translate(${size / 6}px, ${size / 6}px);\n    }\n    .logo-icon.vault:last-child {\n      transform: bottom;\n    }\n    `\n  }}\n`\n\nexport const CoinIcons = React.memo(\n  ({\n    tokenIcon,\n    size: _size,\n    type = TokenType.single,\n  }: {\n    tokenIcon: [CoinSource, CoinSource?]\n    size?: number | 'middle' | 'small' | 'large'\n    type?: TokenType\n  }) => {\n    const size = React.useMemo(() => {\n      if (!_size) {\n        return 24\n      } else if (typeof _size === 'string') {\n        switch (_size) {\n          case 'middle':\n            return 24\n          case 'small':\n            return 20\n          case 'large':\n            return 36\n        }\n      } else {\n        return _size\n      }\n    }, [_size])\n\n    const [coinAInfo, coinBInfo] = tokenIcon\n    return (\n      <BoxStyle\n        display={'flex'}\n        justifyContent={'center'}\n        size={size}\n        alignItems={[TokenType.vault].includes(type) ? 'flex-end' : 'initial'}\n      >\n        <Box\n          className={`logo-icon ${type}`}\n          display={'flex'}\n          height={'var(--list-menu-coin-size)'}\n          position={'relative'}\n          zIndex={20}\n          width={'var(--list-menu-coin-size)'}\n          alignItems={'center'}\n          justifyContent={'center'}\n        >\n          {coinAInfo ? (\n            <AvatarCoin\n              imgx={coinAInfo.x}\n              imgy={coinAInfo.y}\n              imgheight={coinAInfo.h}\n              imgwidth={coinAInfo.w}\n              size={size}\n              variant='circular'\n              alt={coinAInfo?.simpleName as string}\n              // src={sellData?.icon}\n              src={\n                'data:image/svg+xml;utf8,' +\n                '<svg width=\"36\" height=\"36\" viewBox=\"0 0 36 36\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M0 0H36V36H0V0Z\"/></svg>'\n              }\n            />\n          ) : (\n            <Avatar\n              variant='circular'\n              alt={coinAInfo?.simpleName as string}\n              style={{\n                height: size ?? 'var(--list-menu-coin-size)',\n                width: size ?? 'var(--list-menu-coin-size)',\n              }}\n              // src={sellData?.icon}\n              src={SoursURL + 'images/icon-default.png'}\n            />\n          )}\n        </Box>\n        {[TokenType.vault].includes(type) && (\n          <Box\n            className={`logo-icon ${type}`}\n            display={'flex'}\n            position={'relative'}\n            zIndex={24}\n            left={-10}\n            top={(Math.pow(size, 1.7) / 50 ) - 3}\n            alignItems={'center'}\n            justifyContent={'center'}\n          >\n            <VaultTag\n              style={{\n                height: size / 2,\n                width: size / 2,\n                transformOrigin: 'bottom',\n              }}\n            />\n          </Box>\n        )}\n        {coinBInfo || [TokenType.dual, TokenType.lp].includes(type) ? (\n          <Box\n            className={`logo-icon ${type}`}\n            display={'flex'}\n            height={'var(--list-menu-coin-size)'}\n            position={'relative'}\n            zIndex={18}\n            left={-8}\n            width={'var(--list-menu-coin-size)'}\n            alignItems={'center'}\n            justifyContent={'center'}\n          >\n            {coinBInfo ? (\n              <AvatarCoin\n                imgx={coinBInfo.x}\n                imgy={coinBInfo.y}\n                imgheight={coinBInfo.h}\n                imgwidth={coinBInfo.w}\n                size={size}\n                variant='circular'\n                alt={coinBInfo?.simpleName as string}\n                // src={sellData?.icon}\n                src={\n                  'data:image/svg+xml;utf8,' +\n                  '<svg width=\"36\" height=\"36\" viewBox=\"0 0 36 36\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M0 0H36V36H0V0Z\"/></svg>'\n                }\n              />\n            ) : (\n              <Avatar\n                variant='circular'\n                alt={coinBInfo?.simpleName as string}\n                style={{\n                  height: size ?? 'var(--list-menu-coin-size)',\n                  width: size ?? 'var(--list-menu-coin-size)',\n                }}\n                // src={sellData?.icon}\n                src={SoursURL + 'images/icon-default.png'}\n              />\n            )}\n          </Box>\n        ) : (\n          <></>\n        )}\n      </BoxStyle>\n    )\n  },\n)\n\nexport const CoinIconsNew = ({\n  tokenIcon,\n  size: _size,\n  secondLogoType,\n  ...rest\n}: {\n  tokenIcon: [CoinSource, CoinSource?]\n  size?: number | 'middle' | 'small' | 'large'\n  secondLogoType?: 'normal' | 'subscript'\n} & BoxProps) => {\n  const size = React.useMemo(() => {\n    if (!_size) {\n      return 24\n    } else if (typeof _size === 'string') {\n      switch (_size) {\n        case 'middle':\n          return 24\n        case 'small':\n          return 20\n        case 'large':\n          return 36\n      }\n    } else {\n      return _size\n    }\n  }, [_size])\n\n  const [coinAInfo, coinBInfo] = tokenIcon\n  return (\n    <Box display={'flex'} justifyContent={'center'} alignItems={'center'} {...rest}>\n      <Box\n        className={`logo-icon`}\n        display={'flex'}\n        height={size}\n        position={'relative'}\n        zIndex={20}\n        width={size}\n        alignItems={'center'}\n        justifyContent={'center'}\n      >\n        {coinAInfo ? (\n          <AvatarCoin\n            imgx={coinAInfo.x}\n            imgy={coinAInfo.y}\n            imgheight={coinAInfo.h}\n            imgwidth={coinAInfo.w}\n            size={size}\n            variant='circular'\n            alt={coinAInfo?.simpleName as string}\n            // src={sellData?.icon}\n            src={\n              'data:image/svg+xml;utf8,' +\n              '<svg width=\"36\" height=\"36\" viewBox=\"0 0 36 36\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M0 0H36V36H0V0Z\"/></svg>'\n            }\n          />\n        ) : (\n          <Avatar\n            variant='circular'\n            alt={coinAInfo?.simpleName as string}\n            style={{\n              height: size ?? 'var(--list-menu-coin-size)',\n              width: size ?? 'var(--list-menu-coin-size)',\n            }}\n            // src={sellData?.icon}\n            src={SoursURL + 'images/icon-default.png'}\n          />\n        )}\n      </Box>\n      {secondLogoType === 'subscript' && coinBInfo && (\n        <Box\n          className={`logo-icon`}\n          display={'flex'}\n          position={'relative'}\n          zIndex={24}\n          left={-20}\n          top={Math.pow(size, 1.7) / 50 + 3}\n          alignItems={'center'}\n          justifyContent={'center'}\n        >\n          <AvatarCoin\n            imgx={coinBInfo.x}\n            imgy={coinBInfo.y}\n            imgheight={coinBInfo.h}\n            imgwidth={coinBInfo.w}\n            size={size / 2}\n            variant='circular'\n            alt={coinBInfo?.simpleName as string}\n            style={{\n              transformOrigin: 'bottom',\n            }}\n            // src={sellData?.icon}\n            src={\n              'data:image/svg+xml;utf8,' +\n              '<svg width=\"36\" height=\"36\" viewBox=\"0 0 36 36\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M0 0H36V36H0V0Z\"/></svg>'\n            }\n          />\n          {/* <VaultTag\n              style={{\n                height: size / 2,\n                width: size / 2,\n                transformOrigin: 'bottom',\n              }}\n            /> */}\n        </Box>\n      )}\n      {secondLogoType !== 'subscript' && coinBInfo && (\n        <Box\n          className={`logo-icon`}\n          display={'flex'}\n          height={'var(--list-menu-coin-size)'}\n          position={'relative'}\n          zIndex={18}\n          left={-8}\n          width={'var(--list-menu-coin-size)'}\n          alignItems={'center'}\n          justifyContent={'center'}\n        >\n          {coinBInfo ? (\n            <AvatarCoin\n              imgx={coinBInfo.x}\n              imgy={coinBInfo.y}\n              imgheight={coinBInfo.h}\n              imgwidth={coinBInfo.w}\n              size={size}\n              variant='circular'\n              alt={coinBInfo?.simpleName as string}\n              // src={sellData?.icon}\n              src={\n                'data:image/svg+xml;utf8,' +\n                '<svg width=\"36\" height=\"36\" viewBox=\"0 0 36 36\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M0 0H36V36H0V0Z\"/></svg>'\n              }\n            />\n          ) : (\n            <Avatar\n              variant='circular'\n              alt={coinBInfo?.simpleName as string}\n              style={{\n                height: size ?? 'var(--list-menu-coin-size)',\n                width: size ?? 'var(--list-menu-coin-size)',\n              }}\n              // src={sellData?.icon}\n              src={SoursURL + 'images/icon-default.png'}\n            />\n          )}\n        </Box>\n      )}\n    </Box>\n  )\n}\n\n\nexport const ColumnCoinDeep = React.memo(\n  ({\n    token: { type = TokenType.single, ...token },\n    isNotRequiredName = false,\n  }: {\n    token: CoinInfo<any> & {\n      type?: TokenType\n    }\n  } & { isNotRequiredName?: boolean }) => {\n    let tokenIcon: [any, any] = [undefined, undefined]\n    const [head, middle, tail] = token?.simpleName?.split('-')\n    const { coinJson } = useSettings()\n    if (type === 'lp' && middle && tail) {\n      tokenIcon =\n        coinJson[middle] && coinJson[tail]\n          ? [coinJson[middle], coinJson[tail]]\n          : [undefined, undefined]\n    }\n    if (type !== 'lp' && head && head !== 'lp') {\n      tokenIcon = coinJson[head] ? [coinJson[head], undefined] : [undefined, undefined]\n    }\n    return (\n      <Box height={'100%'} display={'inline-flex'} alignItems={'center'}>\n        <CoinIcons type={type} tokenIcon={tokenIcon} />\n        <Typography marginLeft={1} component={'span'} color={'textPrimary'}>\n          {token?.simpleName}\n        </Typography>\n        {!isNotRequiredName && (\n          <Typography\n            marginLeft={1 / 2}\n            component={'span'}\n            variant={'body2'}\n            className={'next-company'}\n            color={'textSecondary'}\n          >\n            {token?.name}\n          </Typography>\n        )}\n      </Box>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/assetsTable/components/Filter.tsx",
    "content": "import { Box, Checkbox, Grid } from '@mui/material'\nimport { withTranslation, WithTranslation } from 'react-i18next'\nimport { FormControlLabel, InputSearch } from '../../../'\nimport { CheckBoxIcon, CheckedIcon, TokenType } from '@loopring-web/common-resources'\n\nexport type TokenTypeCol = {\n  type: TokenType\n  value: string\n}\n\nexport interface FilterProps {\n  hideInvestToken?: boolean\n  hideSmallBalances?: boolean\n  setHideLpToken?: (value: boolean) => void\n  setHideSmallBalances?: (value: boolean) => void\n  filter: {\n    searchValue: string\n  }\n  handleFilterChange: (props: { searchValue: string }) => void\n  noHideInvestToken?: boolean\n}\n\nexport enum CheckboxType {\n  smallBalance = 'smallBalance',\n  invest = 'invest',\n}\n\nexport const Filter = withTranslation('tables', { withRef: true })(\n  ({\n    t,\n    handleFilterChange,\n    filter,\n    hideInvestToken,\n    hideSmallBalances,\n    setHideLpToken,\n    setHideSmallBalances,\n    noHideInvestToken\n  }: FilterProps & WithTranslation) => {\n    return (\n      <Grid container spacing={4} justifyContent={'space-between'}>\n        <Grid item>\n          <InputSearch\n            value={filter.searchValue}\n            onChange={(value: any) => {\n              handleFilterChange({ searchValue: value })\n            }}\n          />\n        </Grid>\n\n        <Grid item>\n          {!noHideInvestToken && <FormControlLabel\n            control={\n              <Checkbox\n                checked={hideInvestToken}\n                checkedIcon={<CheckedIcon />}\n                icon={<CheckBoxIcon />}\n                color='default'\n                onChange={(event) => {\n                  if (setHideLpToken) {\n                    setHideLpToken(event.target.checked)\n                  }\n                }}\n              />\n            }\n            label={t('labelHideInvestToken')}\n          />}\n          <FormControlLabel\n            style={{ marginRight: 0, paddingRight: 0 }}\n            control={\n              <Checkbox\n                checked={hideSmallBalances}\n                checkedIcon={<CheckedIcon />}\n                icon={<CheckBoxIcon />}\n                color='default'\n                onChange={(event) => {\n                  if (setHideSmallBalances) {\n                    setHideSmallBalances(event.target.checked)\n                  }\n                }}\n              />\n            }\n            label={t('labelHideSmallBalances')}\n          />\n        </Grid>\n      </Grid>\n    )\n  },\n)\n\n\n\n\n\nexport const VaultAssetFilter = withTranslation('tables', { withRef: true })(\n  ({\n    t,\n    hideSmallBalances,\n    setHideSmallBalances,\n  }: FilterProps & WithTranslation) => {\n    return (\n      <Box display={'flex'} justifyContent={'flex-start'}>\n        <FormControlLabel\n          style={{ marginRight: 0, paddingRight: 0 }}\n          control={\n            <Checkbox\n              checked={hideSmallBalances}\n              checkedIcon={<CheckedIcon />}\n              icon={<CheckBoxIcon />}\n              color='default'\n              onChange={(event) => {\n                if (setHideSmallBalances) {\n                  setHideSmallBalances(event.target.checked)\n                }\n              }}\n            />\n          }\n          label={t('labelHideSmallBalances')}\n        />\n      </Box>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/assetsTable/components/modal.tsx",
    "content": "import { useTranslation } from 'react-i18next'\nimport styled from '@emotion/styled'\nimport { Box, Link, Typography } from '@mui/material'\nimport { useSettings } from '../../../../stores'\nimport { LoadingBlock } from '../../../block'\nimport { CoinIcons } from './CoinIcons'\nimport { L1L2_NAME_DEFINED, MapChainId } from '@loopring-web/common-resources'\n\nconst ContentWrapperStyled = styled(Box)`\n  position: absolute;\n  top: 45%;\n  left: 50%;\n  transform: translate(-50%, -50%);\n  // min-width: ${({ theme }) => theme.unit * 87.5}px;\n  // height: 60%;\n  background-color: var(--color-pop-bg);\n  box-shadow: 0px ${({ theme }) => theme.unit / 2}px ${({ theme }) => theme.unit / 2}px\n    rgba(0, 0, 0, 0.25);\n  padding: 0 ${({ theme }) => theme.unit * 1}px;\n  border-radius: ${({ theme }) => theme.unit / 2}px;\n`\n\nconst HeaderStyled = styled(Box)`\n  display: flex;\n  align-items: center;\n  width: 100%;\n  margin-top: ${({ theme }) => theme.unit * 2}px;\n  margin-bottom: ${({ theme }) => theme.unit * 2}px;\n  padding: 0 ${({ theme }) => theme.unit * 3}px;\n`\n\nexport const LockDetailPanel = ({\n  tokenLockDetail,\n}: {\n  tokenLockDetail?:\n    | undefined\n    | {\n        list: any[]\n        row: any\n      }\n}) => {\n  const { t } = useTranslation()\n  const { isMobile, coinJson, defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const token = tokenLockDetail?.row?.token\n\n  let tokenIcon: [any, any] = [undefined, undefined]\n  if (token) {\n    const [head, middle, tail] = token?.value?.split('-')\n    if (token.type === 'lp' && middle && tail) {\n      tokenIcon =\n        coinJson[middle] && coinJson[tail]\n          ? [coinJson[middle], coinJson[tail]]\n          : [undefined, undefined]\n    }\n    if (token.type !== 'lp' && head && head !== 'lp') {\n      tokenIcon = coinJson[head] ? [coinJson[head], undefined] : [undefined, undefined]\n    }\n  }\n\n  return (\n    <ContentWrapperStyled width={'var(--mobile-full-panel-width)'}>\n      <HeaderStyled\n        flexDirection={isMobile ? 'column' : 'row'}\n        alignItems={'flex-start'}\n        justifyContent={'center'}\n      >\n        <Typography variant={'h4'} display={'flex'} justifyContent={'center'}>\n          {token && <CoinIcons type={token.type} tokenIcon={tokenIcon} size={28} />}\n          <Typography\n            variant={'inherit'}\n            color={'textPrimary'}\n            display={'flex'}\n            flexDirection={'column'}\n            marginLeft={2}\n            component={'span'}\n            paddingRight={1}\n          >\n            <Typography variant={'inherit'} component={'span'} className={'next-coin'}>\n              {t('labelLocketInfo', {\n                symbol: token?.value,\n                l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n              })}\n            </Typography>\n          </Typography>\n        </Typography>\n      </HeaderStyled>\n      <Box borderRadius={'inherit'} minWidth={110} paddingBottom={2}>\n        {tokenLockDetail && tokenLockDetail.list?.length ? (\n          tokenLockDetail.list.map((item) => {\n            return (\n              <Box\n                display={'flex'}\n                key={item.key}\n                flexDirection={'row'}\n                justifyContent={'space-between'}\n                padding={1}\n              >\n                <Typography\n                  display={'inline-flex'}\n                  alignItems={'center'}\n                  component={'span'}\n                  color={'textSecondary'}\n                >\n                  {t(item.key, {\n                    l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                    loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                    l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                    l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                    ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                  })}\n                </Typography>\n\n                <Link\n                  display={'inline-flex'}\n                  alignItems={'center'}\n                  color={'inherit'}\n                  variant={'body1'}\n                  style={{\n                    textDecoration: 'underline dotted',\n                    // color: 'var(--color-text-secondary)',\n                  }}\n                  href={item.link}\n                >\n                  {item.value}\n                </Link>\n              </Box>\n            )\n          })\n        ) : (\n          <LoadingBlock />\n        )}\n      </Box>\n    </ContentWrapperStyled>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/assetsTable/index.ts",
    "content": "export * from './AssetsTable'\nexport {VaultAssetsTable} from './VaultAssetsTable'\nexport * from './AssetsDefiTable'\nexport * from './components/Filter'\nexport * from './components/CoinIcons'\nexport { VaultPositionsTable } from './VaultPositionsTable'"
  },
  {
    "path": "packages/component-lib/src/components/tableList/btradeSwapTable/BtradeSwapTable.tsx",
    "content": "import { WithTranslation, withTranslation } from 'react-i18next'\nimport { useSettings } from '../../../stores'\nimport React from 'react'\nimport { Column, Table, TablePagination } from '../../basic-lib'\nimport { Box, BoxProps, Tooltip, Typography } from '@mui/material'\nimport { TablePaddingX } from '../../styled'\nimport styled from '@emotion/styled'\nimport { FormatterProps } from 'react-data-grid'\nimport { BtradeSwapsType, RawDataBtradeSwapsItem } from './Interface'\nimport {\n  EmptyValueTag,\n  globalSetup,\n  Info2Icon,\n  RowInvestConfig,\n} from '@loopring-web/common-resources'\nimport { useHistory } from 'react-router-dom'\nimport moment from 'moment/moment'\nimport _ from 'lodash'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nconst TableWrapperStyled = styled(Box)<BoxProps & { isMobile?: boolean }>`\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n  height: 100%;\n\n  ${({ theme }) => TablePaddingX({ pLeft: theme.unit * 3, pRight: theme.unit * 3 })};\n\n  & .rdg {\n    ${({ isMobile }) =>\n      !isMobile\n        ? `--template-columns: 33% 20% auto auto auto !important;`\n        : `--template-columns: 33% 32% auto !important;`}\n  }\n`\nconst TableStyled = styled(Table)`\n  &.rdg {\n    height: ${(props: any) => {\n      if (props.ispro === 'pro') {\n        return '620px'\n      }\n      if (props.currentheight && props.currentheight > 350) {\n        return props.currentheight + 'px'\n      } else {\n        return '100%'\n      }\n    }};\n\n    .rdg-cell.action {\n      display: flex;\n      justify-content: center;\n      align-items: center;\n    }\n  }\n\n  .textAlignRight {\n    text-align: right;\n\n    .rdg-header-sort-cell {\n      justify-content: flex-end;\n    }\n  }\n\n  .textAlignCenter {\n    text-align: center;\n  }\n` as any\n\nexport interface BtradeSwapsTableProps<R> {\n  rawData: R[]\n  showloading: boolean\n  onItemClick: (item: R) => void\n  pagination: {\n    pageSize: number\n    total: number\n  }\n  getBtradeOrderList: (props: Omit<sdk.GetOrdersRequest, 'accountId'>) => Promise<any>\n}\n\nexport const BtradeSwapTable = withTranslation(['tables', 'common'])(\n  <R extends RawDataBtradeSwapsItem>(props: BtradeSwapsTableProps<R> & WithTranslation) => {\n    const { rawData, showloading, onItemClick, pagination, getBtradeOrderList, t } = props\n    const [page, setPage] = React.useState(0)\n    // const [_pageSize, setPageSize] = React.useState(pagination?.pageSize);\n\n    const { isMobile, upColor } = useSettings()\n    const history = useHistory()\n    const getColumnModeTransaction = React.useCallback(\n      (): Column<R, unknown>[] => [\n        {\n          key: 'Type',\n          cellClass: 'textAlignLeft',\n          headerCellClass: 'textAlignLeft',\n          name: t('labelBtradeSwapType'),\n          formatter: ({ row }: FormatterProps<R>) => {\n            const colorMap = [\n              [BtradeSwapsType.Settled, 'var(--color-success)'],\n              [BtradeSwapsType.Delivering, 'var(--color-warning)'],\n              [BtradeSwapsType.Failed, 'var(--color-error)'],\n              [BtradeSwapsType.Cancelled, 'var(--color-error)'],\n              [BtradeSwapsType.Pending, 'var(--color-warning)'],\n            ]\n            const found = colorMap.find((x) => x[0] === row?.type)\n\n            return (\n              <Box\n                display={'flex'}\n                justifyContent={'space-between'}\n                paddingRight={3}\n                alignItems={'center'}\n                height={'100%'}\n              >\n                {row?.type === BtradeSwapsType.Delivering ? (\n                  <Tooltip\n                    title={\n                      <Typography whiteSpace={'pre-line'}>\n                        {t('labelBtradeDeliveringDes').toString()}\n                      </Typography>\n                    }\n                  >\n                    <Typography\n                      color={found ? found[1].toString() : ''}\n                      marginLeft={1}\n                      display={'inline-flex'}\n                      alignItems={'center'}\n                    >\n                      {t(\n                        'labelBtrade' +\n                          // @ts-ignore\n                          (row?.type == BtradeSwapsType.Failed ||\n                          // @ts-ignore\n                          row?.type == BtradeSwapsType.Cancelled\n                            ? BtradeSwapsType.Failed.toString()\n                            : row?.type),\n                      )}\n                      <Info2Icon fontSize={'small'} color={'inherit'} sx={{ marginX: 1 / 2 }} />\n                    </Typography>\n                  </Tooltip>\n                ) : (\n                  <Typography color={found ? found[1].toString() : ''} marginLeft={1}>\n                    {t('labelBtrade' + row?.type)}\n                  </Typography>\n                )}\n                <Typography component={'span'} display={'inline-flex'}>\n                  {row\n                    ? `${row.fromAmountDisplay} ${row.fromSymbol} -> ${row.toAmountDisplay} ${row.toSymbol}`\n                    : EmptyValueTag}\n                </Typography>\n              </Box>\n            )\n          },\n        },\n        {\n          key: 'Filled',\n          name: t('labelBtradeSwapFailed'),\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            return <>{row.filledPercent ? row.filledPercent + '%' : EmptyValueTag}</>\n          },\n        },\n        {\n          key: 'Price',\n          name: t('labelBtradeSwapPrice'),\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            return <> {row.price?.value + ' ' + row.price?.key} </>\n          },\n        },\n        {\n          key: 'Fee',\n          name: t('labelBtradeSwapFee'),\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            return (\n              <>\n                {row.feeAmount !== undefined ? row.feeAmount + ' ' + row.feeSymbol : EmptyValueTag}\n              </>\n            )\n          },\n        },\n        {\n          key: 'Time',\n          cellClass: 'textAlignRight',\n          headerCellClass: 'textAlignRight',\n          name: t('labelBtradeSwapTime'),\n          formatter: ({ row }: FormatterProps<R>) => {\n            return <>{moment(new Date(row.time)).fromNow()}</>\n          },\n        },\n      ],\n      [history, upColor, t],\n    )\n    const getColumnMobileTransaction = React.useCallback(\n      (): Column<R, unknown>[] => [\n        {\n          key: 'Type',\n          cellClass: 'textAlignLeft',\n          headerCellClass: 'textAlignLeft',\n          name: t('labelBtradeSwapType'),\n          formatter: ({ row }: FormatterProps<R>) => {\n            const colorMap = [\n              [BtradeSwapsType.Settled, 'var(--color-success)'],\n              [BtradeSwapsType.Delivering, 'var(--color-warning)'],\n              [BtradeSwapsType.Failed, 'var(--color-error)'],\n              [BtradeSwapsType.Cancelled, 'var(--color-error)'],\n              [BtradeSwapsType.Pending, 'var(--color-warning)'],\n            ]\n            const found = colorMap.find((x) => x[0] === row?.type)\n\n            return (\n              <Box\n                display={'flex'}\n                justifyContent={'space-between'}\n                paddingRight={3}\n                flexDirection={'column'}\n                alignItems={'flex-start'}\n                height={'100%'}\n              >\n                {row?.type === BtradeSwapsType.Delivering ? (\n                  <Tooltip title={t('labelBtradeDeliveringDes').toString()}>\n                    <Typography\n                      color={found ? found[1].toString() : ''}\n                      component={'span'}\n                      display={'flex'}\n                    >\n                      {t(\n                        'labelBtrade' +\n                          // @ts-ignore\n                          (row?.type == BtradeSwapsType.Failed ||\n                          // @ts-ignore\n                          row?.type == BtradeSwapsType.Cancelled\n                            ? BtradeSwapsType.Failed.toString()\n                            : row?.type),\n                      )}\n                      <Info2Icon fontSize={'small'} color={'inherit'} sx={{ marginX: 1 / 2 }} />\n                    </Typography>\n                  </Tooltip>\n                ) : (\n                  <Typography\n                    color={found ? found[1].toString() : ''}\n                    component={'span'}\n                    display={'flex'}\n                  >\n                    {t('labelBtrade' + row?.type)}\n                  </Typography>\n                )}\n                <Typography component={'span'} display={'flex'}>\n                  {row\n                    ? `${row.fromAmountDisplay} ${row.fromSymbol} -> ${row.toAmountDisplay} ${row.toSymbol}`\n                    : EmptyValueTag}\n                </Typography>\n              </Box>\n            )\n          },\n        },\n        {\n          key: 'Price',\n          cellClass: 'textAlignRight',\n          headerCellClass: 'textAlignRight',\n          name: t('labelBtradeSwapPrice') + '/' + t('labelBtradeSwapFailed'),\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            return (\n              <Box\n                display={'flex'}\n                justifyContent={'space-between'}\n                paddingRight={3}\n                flexDirection={'column'}\n                alignItems={'flex-end'}\n                height={'100%'}\n              >\n                <Typography component={'span'} display={'flex'}>\n                  {row.price?.value + ' ' + row.price?.key}\n                </Typography>\n                <Typography component={'span'} display={'flex'} color={'textSecondary'}>\n                  {row.filledPercent ? row.filledPercent + '%' : EmptyValueTag}\n                </Typography>\n              </Box>\n            )\n          },\n        },\n        {\n          key: 'Fee',\n          cellClass: 'textAlignRight',\n          headerCellClass: 'textAlignRight',\n          name: t('labelBtradeSwapFee') + '/' + t('labelBtradeSwapTime'),\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            return (\n              <Box\n                display={'flex'}\n                justifyContent={'space-between'}\n                paddingRight={3}\n                flexDirection={'column'}\n                alignItems={'flex-end'}\n                height={'100%'}\n              >\n                <Typography component={'span'} display={'flex'}>\n                  {row.feeAmount !== undefined\n                    ? row.feeAmount + ' ' + row.feeSymbol\n                    : EmptyValueTag}\n                </Typography>\n\n                <Typography component={'span'} display={'flex'} color={'textSecondary'}>\n                  {moment(new Date(row.time)).fromNow()}\n                </Typography>\n              </Box>\n            )\n          },\n        },\n      ],\n      [history, upColor, t],\n    )\n    const updateData = _.debounce(\n      ({\n        // tableType,\n        currPage = page,\n        pageSize = pagination.pageSize,\n      }: {\n        // tableType: TableType;\n        currPage?: number\n        pageSize?: number\n      }) => {\n        getBtradeOrderList({\n          limit: pageSize,\n          offset: (currPage - 1) * pageSize,\n        })\n      },\n      globalSetup.wait,\n    )\n    const handlePageChange = React.useCallback(\n      async (currPage: number) => {\n        // if (currPage === page) return;\n        setPage(currPage)\n        updateData({ currPage: currPage })\n      },\n      [updateData],\n    )\n\n    const defaultArgs: any = {\n      columnMode: isMobile ? getColumnMobileTransaction() : getColumnModeTransaction(),\n      generateRows: (rawData: any) => rawData,\n      generateColumns: ({ columnsRaw }: any) => columnsRaw as Column<any, unknown>[],\n    }\n    // React.useEffect(() => {\n    //   updateData.cancel();\n    //   handlePageChange(1);\n    //   return () => {\n    //     updateData.cancel();\n    //   };\n    // }, [pagination?.pageSize]);\n    React.useEffect(() => {\n      // setPageSize(pagination?.pageSize);\n      updateData.cancel()\n      handlePageChange(1)\n      return () => {\n        updateData.cancel()\n      }\n    }, [pagination?.pageSize])\n\n    return (\n      <TableWrapperStyled isMobile={isMobile}>\n        <TableStyled\n          currentheight={\n            RowInvestConfig.rowHeaderHeight + rawData.length * RowInvestConfig.rowHeight\n          }\n          rowHeight={RowInvestConfig.rowHeight}\n          headerRowHeight={RowInvestConfig.rowHeaderHeight}\n          onRowClick={(_index: number, row: R) => {\n            onItemClick(row)\n          }}\n          // sortMethod={sortMethod}\n          {...{\n            ...defaultArgs,\n            ...props,\n\n            rawData,\n            showloading,\n          }}\n        />\n        {pagination && !!rawData.length && (\n          <TablePagination\n            page={page}\n            pageSize={pagination.pageSize}\n            total={pagination.total}\n            onPageChange={handlePageChange}\n          />\n        )}\n      </TableWrapperStyled>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/btradeSwapTable/Interface.ts",
    "content": "export enum BtradeSwapsType {\n  Settled = 'Settled',\n  Delivering = 'Delivering',\n  Failed = 'Failed',\n  Pending = 'Pending',\n  Cancelled = 'Cancelled',\n}\n\nexport type RawDataBtradeSwapsItem = {\n  type: BtradeSwapsType\n  fromAmount: string\n  fromSymbol: string\n  toAmount: string\n  toSymbol: string\n  fromFAmount: string\n  toFAmount: string\n  price: {\n    key: string\n    value: string\n    from: string\n  }\n  feeAmount: string\n  feeSymbol: string\n  time: number\n  filledPercent: string\n  settledFromAmount: string\n  settledToAmount: string\n  fromAmountDisplay: string\n  toAmountDisplay: string\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/btradeSwapTable/index.ts",
    "content": "export * from './BtradeSwapTable'\nexport * from './Interface'\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/defiTxsTable/DefiStakingTable.tsx",
    "content": "import _ from 'lodash'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport { useSettings } from '../../../stores'\nimport React from 'react'\nimport {\n  EmptyValueTag,\n  getValuePrecisionThousand,\n  globalSetup,\n  HiddenTag,\n  RowInvestConfig,\n} from '@loopring-web/common-resources'\nimport { Column, ModalCloseButton, Table, TablePagination } from '../../basic-lib'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nimport { Box, BoxProps, Modal, Typography } from '@mui/material'\nimport { SwitchPanelStyled, TablePaddingX } from '../../styled'\nimport styled from '@emotion/styled'\nimport { FormatterProps } from 'react-data-grid'\nimport { DefiSideStakingTableProps, RawDataDefiSideStakingItem } from './Interface'\nimport { ConfirmStackingRedeem, DeFiSideDetail } from '../../tradePanel'\nimport ActionMemo from './components/ActionMemo'\nimport moment from 'moment'\n\nconst TableWrapperStyled = styled(Box)<BoxProps & { isMobile?: boolean }>`\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n\n  .rdg {\n    ${({ isMobile }) =>\n      !isMobile\n        ? `--template-columns: 14% auto 16% 16% 11% 11% 160px !important;`\n        : `--template-columns: 24% auto auto 8% !important;`}\n    .rdgCellCenter {\n      height: 100%;\n      justify-content: center;\n      align-items: center;\n    }\n\n    .textAlignRight {\n      text-align: right;\n    }\n\n    .textAlignCenter {\n      text-align: center;\n    }\n\n    .textAlignLeft {\n      text-align: left;\n    }\n  }\n\n  ${({ theme }) => TablePaddingX({ pLeft: theme.unit * 3, pRight: theme.unit * 3 })};\n` as (props: { isMobile?: boolean } & BoxProps) => JSX.Element\nconst TableStyled = styled(Table)`\n  &.rdg {\n    height: ${(props: any) => {\n      if (props.ispro === 'pro') {\n        return '620px'\n      }\n      if (props.currentheight) {\n        return props.currentheight + 'px'\n      }\n    }};\n\n    .rdg-cell.action {\n      display: flex;\n      justify-content: center;\n      align-items: center;\n    }\n  }\n\n  .textAlignRight {\n    text-align: right;\n\n    .rdg-header-sort-cell {\n      justify-content: flex-end;\n    }\n  }\n\n  .textAlignCenter {\n    text-align: center;\n  }\n` as any\nexport const DefiStakingTable = withTranslation(['tables', 'common'])(\n  <R extends RawDataDefiSideStakingItem>(props: DefiSideStakingTableProps<R> & WithTranslation) => {\n    const {\n      rawData,\n      idIndex,\n      pagination,\n      tokenMap,\n      geDefiSideStakingList,\n      showloading,\n      // onDetailClick,\n      redeemItemClick: _redeemItemClick,\n      hideAssets,\n      t,\n    } = props\n    const [openDetail, setOpenDetail] = React.useState(false)\n    const [openAlert, setOpenAlert] = React.useState(false)\n    const [detail, setDetail] = React.useState<R | undefined>(undefined)\n    const { isMobile } = useSettings()\n    const [page, setPage] = React.useState(1)\n    const redeemItemClick = (item: R) => {\n      setDetail(item)\n      const requiredHoldDay = (item.claimableTime - item.stakeAt) / 86400000\n      const holdDay = moment(Date.now()).diff(\n        moment(new Date(item.stakeAt ?? ''))\n          .utc()\n          .startOf('days'),\n        'days',\n        false,\n      )\n      if (requiredHoldDay > holdDay) {\n        setOpenAlert(true)\n      } else {\n        setOpenDetail(false)\n        _redeemItemClick(item)\n      }\n    }\n    const updateData = _.debounce(\n      ({\n        // tableType,\n        currPage = page,\n        pageSize = pagination?.pageSize ?? 10,\n      }: {\n        // tableType: TableType;\n        currPage?: number\n        pageSize?: number\n      }) => {\n        geDefiSideStakingList({\n          limit: pageSize,\n          offset: (currPage - 1) * pageSize,\n        })\n      },\n      globalSetup.wait,\n    )\n\n    const handlePageChange = React.useCallback(\n      (currPage: number) => {\n        if (currPage === page) return\n        setPage(currPage)\n        updateData({ currPage: currPage })\n      },\n      [updateData, page],\n    )\n\n    const getColumnModeTransaction = React.useCallback(\n      (): Column<R, unknown>[] => [\n        {\n          key: 'Product',\n          sortable: false,\n          width: 'auto',\n          name: t('labelDefiStakingProduct'),\n          cellClass: 'textAlignLeft',\n          headerCellClass: 'textAlignLeft',\n          formatter: ({ row }) => {\n            return (\n              <Typography\n                component={'span'}\n                flexDirection={'row'}\n                display={'flex'}\n                height={'100%'}\n                alignItems={'center'}\n              >\n                {row.productId}\n              </Typography>\n            )\n          },\n        },\n        {\n          key: 'Frozen',\n          sortable: false,\n          width: 'auto',\n          cellClass: 'textAlignCenter',\n          headerCellClass: 'textAlignCenter',\n          name: t('labelDefiStakingFrozen'),\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            const tokenInfo = tokenMap[idIndex[row.tokenId ?? '']]\n            const amountStr =\n              row.remainAmount && row.remainAmount !== '0'\n                ? hideAssets\n                  ? HiddenTag\n                  : getValuePrecisionThousand(\n                      sdk.toBig(row.remainAmount).div('1e' + tokenInfo.decimals),\n                      tokenInfo.precision,\n                      tokenInfo.precision,\n                      undefined,\n                      false,\n                      {\n                        floor: false,\n                        // isTrade: true,\n                      },\n                    ) +\n                    ' ' +\n                    tokenInfo.symbol\n                : EmptyValueTag\n\n            return <> {amountStr}</>\n          },\n        },\n        {\n          key: 'Earn',\n          sortable: false,\n          width: 'auto',\n          cellClass: 'textAlignCenter',\n          headerCellClass: 'textAlignCenter',\n          name: t('labelDefiStakingEarn'),\n          formatter: ({ row }) => {\n            const tokenInfo = tokenMap[idIndex[row.tokenId ?? '']]\n            const amountStr =\n              row.totalRewards && row.totalRewards !== '0'\n                ? hideAssets\n                  ? HiddenTag\n                  : getValuePrecisionThousand(\n                      sdk.toBig(row.totalRewards).div('1e' + tokenInfo.decimals),\n                      tokenInfo.precision,\n                      tokenInfo.precision,\n                      undefined,\n                      false,\n                      {\n                        floor: false,\n                        // isTrade: true,\n                      },\n                    ) +\n                    ' ' +\n                    tokenInfo.symbol\n                : EmptyValueTag\n            return <> {amountStr}</>\n          },\n        },\n        {\n          key: 'PreviousEarn',\n          sortable: false,\n          width: 'auto',\n          cellClass: 'textAlignCenter',\n          headerCellClass: 'textAlignCenter',\n          name: t('labelDefiStakingPreviousEarn'),\n          formatter: ({ row }) => {\n            const tokenInfo = tokenMap[idIndex[row.tokenId ?? '']]\n            const amountStr =\n              row.lastDayPendingRewards && row.lastDayPendingRewards !== '0'\n                ? hideAssets\n                  ? HiddenTag\n                  : getValuePrecisionThousand(\n                      sdk.toBig(row.lastDayPendingRewards).div('1e' + tokenInfo.decimals),\n                      tokenInfo.precision,\n                      tokenInfo.precision,\n                      undefined,\n                      false,\n                      {\n                        floor: false,\n                        // isTrade: true,\n                      },\n                    ) +\n                    ' ' +\n                    tokenInfo.symbol\n                : EmptyValueTag\n            return <> {amountStr}</>\n          },\n        },\n        {\n          key: 'Duration',\n          sortable: false,\n          width: 'auto',\n          headerCellClass: 'textAlignRight',\n          cellClass: 'textAlignRight',\n          name: t('labelDefiStakingDuration'),\n          formatter: ({ row }) => {\n            const diff = moment(Date.now()).diff(\n              moment(new Date(row.stakeAt ?? ''))\n                .utc()\n                .startOf('days'),\n              'days',\n              false,\n            )\n            return <>{diff ? diff + ' ' + t('labelDays') : '< 1' + ' ' + t('labelDays')}</>\n          },\n        },\n        {\n          key: 'APR',\n          sortable: false,\n          width: 'auto',\n          cellClass: 'textAlignRight',\n          headerCellClass: 'textAlignRight',\n          name: t('labelDefiStakingARR'),\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            return <>{row.apr && row.apr !== '0.00' ? row.apr + '%' : EmptyValueTag}</>\n          },\n        },\n        {\n          key: 'StakingAction',\n          sortable: false,\n          cellClass: 'textAlignRight',\n          headerCellClass: 'textAlignRight',\n          name: t('labelDefiStakingAction'),\n          formatter: ({ row }) => {\n            return (\n              <ActionMemo\n                {...{\n                  item: row,\n                  redeemItemClick,\n                  onDetailClick: (item: R) => {\n                    setDetail(item)\n                    setOpenDetail(item as any)\n                  },\n                }}\n              />\n            )\n          },\n        },\n      ],\n      [t, tokenMap, idIndex, hideAssets],\n    )\n\n    const getColumnMobileTransaction = React.useCallback(\n      (): Column<R, unknown>[] => [\n        {\n          key: 'Product',\n          sortable: false,\n          width: 'auto',\n          name: t('labelDefiStakingProduct') + '/' + t('labelDefiStakingFrozen'),\n          cellClass: 'textAlignLeft',\n          headerCellClass: 'textAlignLeft',\n          formatter: ({ row }) => {\n            const tokenInfo = tokenMap[idIndex[row.tokenId ?? '']]\n            const amountStr =\n              row.remainAmount && row.remainAmount !== '0'\n                ? (hideAssets\n                    ? HiddenTag\n                    : getValuePrecisionThousand(\n                        sdk.toBig(row.remainAmount).div('1e' + tokenInfo.decimals),\n                        tokenInfo.precision,\n                        tokenInfo.precision,\n                        undefined,\n                        false,\n                        {\n                          floor: false,\n                          // isTrade: true,\n                        },\n                      )) +\n                  ' ' +\n                  tokenInfo.symbol\n                : EmptyValueTag\n\n            return (\n              <Typography\n                component={'span'}\n                flexDirection={'column'}\n                display={'flex'}\n                height={'100%'}\n                alignItems={'center'}\n              >\n                <Typography color={'textPrimary'} variant={'body1'}>\n                  {amountStr}\n                </Typography>\n                <Typography color={'textSecondary'} variant={'body2'}>\n                  {row.productId}\n                </Typography>\n              </Typography>\n            )\n          },\n        },\n        {\n          key: 'Earn',\n          sortable: false,\n          width: 'auto',\n          cellClass: 'textAlignCenter',\n          headerCellClass: 'textAlignCenter',\n          name: t('labelDefiStakingAndPreviousEarn'),\n          formatter: ({ row }) => {\n            const tokenInfo = tokenMap[idIndex[row.tokenId ?? '']]\n            const amountStr =\n              row.lastDayPendingRewards && row.lastDayPendingRewards !== '0'\n                ? hideAssets\n                  ? HiddenTag\n                  : getValuePrecisionThousand(\n                      sdk.toBig(row.lastDayPendingRewards).div('1e' + tokenInfo.decimals),\n                      tokenInfo.precision,\n                      tokenInfo.precision,\n                      undefined,\n                      false,\n                      {\n                        floor: false,\n                        // isTrade: true,\n                      },\n                    )\n                : EmptyValueTag\n            const amountPreviousEarnStr =\n              row.totalRewards && row.totalRewards != '0'\n                ? (hideAssets\n                    ? HiddenTag\n                    : getValuePrecisionThousand(\n                        sdk.toBig(row.totalRewards).div('1e' + tokenInfo.decimals),\n                        tokenInfo.precision,\n                        tokenInfo.precision,\n                        undefined,\n                        false,\n                        {\n                          floor: false,\n                          // isTrade: true,\n                        },\n                      )) +\n                  ' ' +\n                  tokenInfo.symbol\n                : EmptyValueTag\n            return <>{amountStr + '/' + amountPreviousEarnStr}</>\n          },\n        },\n        {\n          key: 'APR',\n          sortable: false,\n          width: 'auto',\n          headerCellClass: 'textAlignRight',\n          cellClass: 'textAlignRight',\n          name: t('labelDefiStakingDuration') + '/' + t('labelDefiStakingARR'),\n          formatter: ({ row }) => {\n            const diff = moment(Date.now()).diff(\n              moment(new Date(row.stakeAt ?? ''))\n                .utc()\n                .startOf('days'),\n              'days',\n              false,\n            )\n            return (\n              <Typography component={'span'} textAlign={'right'}>\n                {diff ? diff + ' ' + t('labelDays') : '< 1' + ' ' + t('labelDays') + '/'}\n                {row.apr && row.apr !== '0.00' && Number(row.apr) !== 0\n                  ? row.apr + '%'\n                  : EmptyValueTag}\n              </Typography>\n            )\n          },\n        },\n        {\n          key: 'StakingAction',\n          sortable: false,\n          cellClass: 'textAlignRight',\n          headerCellClass: 'textAlignRight',\n          name: t('labelDefiStakingAction'),\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            //onDetailClick\n            return (\n              <ActionMemo\n                {...{\n                  item: row,\n                  redeemItemClick,\n                  onDetailClick: (item: R) => {\n                    setDetail(item)\n                    setOpenDetail(item as any)\n                  },\n                }}\n              />\n            )\n          },\n        },\n      ],\n      [t, tokenMap, idIndex],\n    )\n\n    // const [isDropDown, setIsDropDown] = React.useState(true);\n\n    const defaultArgs: any = {\n      columnMode: isMobile ? getColumnMobileTransaction() : getColumnModeTransaction(),\n      generateRows: (rawData: any) => rawData,\n      generateColumns: ({ columnsRaw }: any) => columnsRaw as Column<any, unknown>[],\n    }\n\n    return (\n      <TableWrapperStyled isMobile={isMobile}>\n        <TableStyled\n          currentheight={\n            rawData.length > 0\n              ? RowInvestConfig.rowHeaderHeight + rawData.length * RowInvestConfig.rowHeight\n              : 350\n          }\n          rowHeight={RowInvestConfig.rowHeight}\n          headerRowHeight={RowInvestConfig.rowHeaderHeight}\n          {...{\n            ...defaultArgs,\n            // rowRenderer: RowRenderer,\n            ...props,\n            rawData,\n            showloading,\n          }}\n        />\n        {!!(pagination && pagination.total > pagination.pageSize) && (\n          <TablePagination\n            page={page}\n            pageSize={pagination.pageSize}\n            total={pagination.total}\n            onPageChange={handlePageChange}\n          />\n        )}\n        <Modal\n          open={openDetail}\n          onClose={(_e: any) => setOpenDetail(false)}\n          aria-labelledby='modal-modal-title'\n          aria-describedby='modal-modal-description'\n        >\n          <SwitchPanelStyled width={'var(--modal-width)'}>\n            <ModalCloseButton onClose={(_e: any) => setOpenDetail(false)} t={t} />\n            {detail && (\n              <Box flex={1} paddingY={2} width={'100%'} display={'flex'} flexDirection={'column'}>\n                <Typography\n                  variant={isMobile ? 'h5' : 'h4'}\n                  marginTop={-4}\n                  textAlign={'center'}\n                  paddingBottom={2}\n                >\n                  {t('labelDeFiSideInvestmentDetails', {\n                    ns: 'common',\n                    symbol: 'LRC',\n                  })}\n                </Typography>\n                <DeFiSideDetail\n                  tokenSell={tokenMap[idIndex[detail.tokenId]]}\n                  order={{ ...detail }}\n                  onRedeem={redeemItemClick as any}\n                />\n              </Box>\n            )}\n          </SwitchPanelStyled>\n        </Modal>\n        <ConfirmStackingRedeem\n          open={openAlert}\n          handleClose={(_, isAgree?: boolean) => {\n            setOpenAlert(false)\n            if (isAgree) {\n              _redeemItemClick(detail as any)\n            }\n          }}\n        />\n      </TableWrapperStyled>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/defiTxsTable/DefiStakingTxTable.tsx",
    "content": "import _ from 'lodash'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport { useSettings } from '../../../stores'\nimport React from 'react'\nimport {\n  EmptyValueTag,\n  getShortAddr,\n  getValuePrecisionThousand,\n  globalSetup,\n} from '@loopring-web/common-resources'\nimport { Column, Table, TablePagination } from '../../basic-lib'\nimport { Box, BoxProps, Typography } from '@mui/material'\nimport { TablePaddingX } from '../../styled'\nimport styled from '@emotion/styled'\nimport { FormatterProps } from 'react-data-grid'\nimport { DefiSideStakingTxTableProps, RawDataDefiSideStakingTxItem } from './Interface'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport moment from 'moment'\n\nconst TableStyled = styled(Box)<BoxProps & { isMobile?: boolean }>`\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n\n  .rdg {\n    ${({ isMobile }) =>\n      !isMobile\n        ? `--template-columns: auto 20% 180px auto !important;`\n        : `--template-columns: 24% auto 20% !important;`}\n    .rdgCellCenter {\n      height: 100%;\n      justify-content: center;\n      align-items: center;\n    }\n\n    .textAlignRight {\n      text-align: right;\n    }\n\n    .textAlignCenter {\n      text-align: center;\n    }\n\n    .textAlignLeft {\n      text-align: left;\n    }\n  }\n\n  ${({ theme }) => TablePaddingX({ pLeft: theme.unit * 3, pRight: theme.unit * 3 })}\n` as (props: { isMobile?: boolean } & BoxProps) => JSX.Element\n\nexport const DefiStakingTxTable = withTranslation(['tables', 'common'])(\n  <R extends RawDataDefiSideStakingTxItem>(\n    props: DefiSideStakingTxTableProps<R> & WithTranslation,\n  ) => {\n    const { rawData, idIndex, pagination, tokenMap, getSideStakingTxList, showloading, t } = props\n    const { isMobile } = useSettings()\n    const [page, setPage] = React.useState(1)\n\n    const updateData = _.debounce(\n      ({\n        // tableType,\n        currPage = page,\n        pageSize = pagination?.pageSize ?? 10,\n      }: {\n        // tableType: TableType;\n        currPage?: number\n        pageSize?: number\n      }) => {\n        getSideStakingTxList({\n          limit: pageSize,\n          offset: (currPage - 1) * pageSize,\n        })\n      },\n      globalSetup.wait,\n    )\n\n    // {\n    //   \"accountId\": 10023,\n    //   \"tokenId\": 1,\n    //   \"amount\": \"10000000000000000000000\",\n    //   \"productId\": \"LRC-20221221\",\n    //   \"hash\": \"0x2dc2ee00c80a33e00259cefa72b4a5b48e5d1187c43b101468e1dde77b43f2fa\",\n    //\n    //   \"type\": \"subscribe\",\n    //\n    //   \"createdAt\": 1662086517521,\n    //\n    //   \"updatedAt\": 1662086517521\n    // },\n    const handlePageChange = React.useCallback(\n      (currPage: number) => {\n        if (currPage === page) return\n        setPage(currPage)\n        updateData({ currPage: currPage })\n      },\n      [updateData, page],\n    )\n\n    const getColumnModeTransaction = React.useCallback(\n      (): Column<R, unknown>[] => [\n        {\n          key: 'Type',\n          sortable: false,\n          width: 'auto',\n          name: t('labelDefiStakingTxType'),\n          cellClass: 'textAlignLeft',\n          headerCellClass: 'textAlignLeft',\n          formatter: ({ row }) => {\n            let side = {\n              color: 'var(--color-text-primary)',\n              // @ts-ignore\n              type: `labelStakeTransactionType${row.stakingType}`,\n            }\n            const tokenInfo = tokenMap[idIndex[row.tokenId ?? '']]\n            const amountStr = row.amount\n              ? getValuePrecisionThousand(\n                  sdk.toBig(row.amount).div('1e' + tokenInfo.decimals),\n                  tokenInfo.precision,\n                  tokenInfo.precision,\n                  undefined,\n                  false,\n                  {\n                    floor: false,\n                    // isTrade: true,\n                  },\n                ) +\n                ' ' +\n                tokenInfo.symbol\n              : EmptyValueTag\n            // @ts-ignore\n            switch (row.stakingType) {\n              case sdk.StakeTransactionType.subscribe:\n                side = {\n                  ...side,\n                  color: 'var(--color-success)',\n                }\n                break\n              case sdk.StakeTransactionType.redeem:\n                side = {\n                  ...side,\n                  color: 'var(--color-error)',\n                }\n                break\n              case sdk.StakeTransactionType.claim:\n                side = {\n                  ...side,\n                  color: 'var(--color-warning)',\n                }\n                break\n            }\n\n            return (\n              <Typography\n                component={'span'}\n                flexDirection={'row'}\n                display={'flex'}\n                height={'100%'}\n                alignItems={'center'}\n              >\n                <Typography\n                  component={'span'}\n                  sx={{ textTransform: 'capitalize' }}\n                  color={side.color}\n                  display={'inline'}\n                  minWidth={86}\n                >\n                  {t(side.type)}\n                </Typography>\n                <Typography component={'span'} display={'inline'}>\n                  {amountStr}\n                </Typography>\n              </Typography>\n            )\n          },\n        },\n        {\n          key: 'Product',\n          sortable: false,\n          width: 'auto',\n          name: t('labelDefiStakingTxProduct'),\n          cellClass: 'textAlignCenter',\n          headerCellClass: 'textAlignCenter',\n          formatter: ({ row }) => {\n            return <>{row.productId ? row.productId : EmptyValueTag}</>\n          },\n        },\n        {\n          key: 'HashID',\n          sortable: false,\n          width: 'auto',\n          cellClass: 'textAlignCenter',\n          headerCellClass: 'textAlignCenter',\n          name: t('labelDefiStakingTxHashId'),\n          formatter: ({ row }) => {\n            return <>{row.hash ? getShortAddr(row.hash) : EmptyValueTag}</>\n          },\n        },\n        {\n          key: 'SubscribeTime',\n          sortable: false,\n          width: 'auto',\n          cellClass: 'textAlignRight',\n          headerCellClass: 'textAlignRight',\n          name: t('labelDefiStakingTxRewardsDate'),\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            return (\n              <Typography component={'span'} textAlign={'right'}>\n                {typeof row.createdAt === 'undefined'\n                  ? EmptyValueTag\n                  : moment(new Date(row.createdAt), 'YYYYMMDDHHMM').fromNow()}\n              </Typography>\n            )\n          },\n        },\n      ],\n      [t, tokenMap, idIndex],\n    )\n\n    const getColumnMobileTransaction = React.useCallback(\n      (): Column<R, unknown>[] => [\n        {\n          key: 'Type',\n          sortable: false,\n          width: 'auto',\n          name: t('labelDefiStakingTxType'),\n          cellClass: 'textAlignLeft',\n          headerCellClass: 'textAlignLeft',\n          formatter: ({ row }) => {\n            let side = {\n              color: 'var(--color-text-primary)',\n              // @ts-ignore\n              type: `labelStakeTransactionType${row.stakingType}`,\n            }\n            // @ts-ignore\n            switch (row.stakingType) {\n              case sdk.StakeTransactionType.subscribe:\n                side = {\n                  ...side,\n                  color: 'var(--color-success)',\n                }\n                break\n              case sdk.StakeTransactionType.redeem:\n                side = {\n                  ...side,\n                  color: 'var(--color-error)',\n                }\n                break\n              case sdk.StakeTransactionType.claim:\n                side = {\n                  ...side,\n                  color: 'var(--color-warning)',\n                }\n                break\n            }\n\n            return (\n              <Typography\n                component={'span'}\n                flexDirection={'row'}\n                display={'flex'}\n                height={'100%'}\n                alignItems={'center'}\n              >\n                <Typography\n                  component={'span'}\n                  sx={{ textTransform: 'capitalize' }}\n                  color={side.color}\n                  display={'inline'}\n                  minWidth={86}\n                >\n                  {t(side.type)}\n                </Typography>\n              </Typography>\n            )\n          },\n        },\n        {\n          key: 'Product',\n          sortable: false,\n          width: 'auto',\n          name: t('labelDefiStakingTxAmount') + '/' + t('labelDefiStakingTxProduct'),\n          cellClass: 'textAlignRight',\n          headerCellClass: 'textAlignRight',\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            const tokenInfo = tokenMap[idIndex[row.tokenId ?? '']]\n            const amountStr =\n              row.amount && row.amount != '0'\n                ? getValuePrecisionThousand(\n                    sdk.toBig(row.amount).div('1e' + tokenInfo.decimals),\n                    tokenInfo.precision,\n                    tokenInfo.precision,\n                    undefined,\n                    false,\n                    {\n                      floor: false,\n                      // isTrade: true,\n                    },\n                  ) +\n                  ' ' +\n                  tokenInfo.symbol\n                : EmptyValueTag\n            return (\n              <Typography\n                component={'span'}\n                flexDirection={'column'}\n                display={'flex'}\n                height={'100%'}\n                textAlign={'right'}\n                alignItems={'flex-end'}\n              >\n                <Typography component={'span'} display={'inline'}>\n                  {amountStr}\n                </Typography>\n                <Typography component={'span'} display={'inline'}>\n                  {row.productId}\n                </Typography>\n              </Typography>\n            )\n          },\n        },\n        {\n          key: 'SubscribeTime',\n          sortable: false,\n          width: 'auto',\n          cellClass: 'textAlignRight',\n          headerCellClass: 'textAlignRight',\n          name: t('labelDefiStakingTxRewardsMobileDate'),\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            return (\n              <Typography component={'span'} textAlign={'right'}>\n                {typeof row.createdAt === 'undefined'\n                  ? EmptyValueTag\n                  : moment(new Date(row.createdAt), 'YYYYMMDDHHMM').fromNow()}\n              </Typography>\n            )\n          },\n        },\n      ],\n      [t, tokenMap, idIndex],\n    )\n\n    // const [isDropDown, setIsDropDown] = React.useState(true);\n\n    const defaultArgs: any = {\n      columnMode: isMobile ? getColumnMobileTransaction() : getColumnModeTransaction(),\n      generateRows: (rawData: any) => rawData,\n      generateColumns: ({ columnsRaw }: any) => columnsRaw as Column<any, unknown>[],\n    }\n    React.useEffect(() => {\n      // let filters: any = {};\n      updateData.cancel()\n      updateData({ currPage: 1 })\n\n      return () => {\n        updateData.cancel()\n      }\n    }, [pagination?.pageSize])\n\n    return (\n      <TableStyled isMobile={isMobile}>\n        <Table\n          {...{\n            ...defaultArgs,\n            // rowRenderer: RowRenderer,\n            ...props,\n            rawData,\n            showloading,\n          }}\n        />\n        {pagination && (\n          <TablePagination\n            page={page}\n            pageSize={pagination.pageSize}\n            total={pagination.total}\n            onPageChange={handlePageChange}\n          />\n        )}\n      </TableStyled>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/defiTxsTable/DefiTxsTable.tsx",
    "content": "import _ from 'lodash'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport { useSettings } from '../../../stores'\nimport React from 'react'\nimport {\n  DirectionTag,\n  EmptyValueTag,\n  getValuePrecisionThousand,\n  globalSetup,\n} from '@loopring-web/common-resources'\nimport { Column, Table, TablePagination } from '../../basic-lib'\nimport { Box, BoxProps, Typography } from '@mui/material'\nimport moment from 'moment'\nimport { TablePaddingX } from '../../styled'\nimport styled from '@emotion/styled'\nimport { FormatterProps } from 'react-data-grid'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { DefiTxsTableProps, RawDataDefiTxsItem } from './Interface'\n\nconst TableStyled = styled(Box)<BoxProps & { isMobile?: boolean }>`\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n\n  .rdg {\n    ${({ isMobile }) =>\n      !isMobile\n        ? `--template-columns: auto 20% 180px !important;`\n        : `--template-columns: 100% !important;`}\n    .rdgCellCenter {\n      height: 100%;\n      justify-content: center;\n      align-items: center;\n    }\n\n    .textAlignRight {\n      text-align: right;\n    }\n\n    .textAlignCenter {\n      text-align: center;\n    }\n\n    .textAlignLeft {\n      text-align: left;\n    }\n  }\n\n  ${({ theme }) => TablePaddingX({ pLeft: theme.unit * 3, pRight: theme.unit * 3 })}\n` as (props: { isMobile?: boolean } & BoxProps) => JSX.Element\n\nexport const DefiTxsTable = withTranslation(['tables', 'common'])(\n  <R extends RawDataDefiTxsItem>(props: DefiTxsTableProps<R> & WithTranslation) => {\n    const { rawData, idIndex, pagination, tokenMap, getDefiTxList, showloading, t } = props\n    const { isMobile } = useSettings()\n    const [page, setPage] = React.useState(1)\n\n    const updateData = _.debounce(\n      ({\n        // tableType,\n        currPage = page,\n        pageSize = pagination?.pageSize ?? 10,\n      }: {\n        // tableType: TableType;\n        currPage?: number\n        pageSize?: number\n      }) => {\n        getDefiTxList({\n          limit: pageSize,\n          offset: (currPage - 1) * pageSize,\n        })\n      },\n      globalSetup.wait,\n    )\n\n    const handlePageChange = React.useCallback(\n      (currPage: number) => {\n        if (currPage === page) return\n        setPage(currPage)\n        updateData({ currPage: currPage })\n      },\n      [updateData, page],\n    )\n\n    const getColumnModeTransaction = React.useCallback(\n      (): Column<R, unknown>[] => [\n        {\n          key: 'style',\n          sortable: false,\n          width: 'auto',\n          minWidth: 240,\n          name: t('labelDefiType') + ' ' + t('labelDefiAmount'),\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            const { action, sellToken, buyToken } = row\n            const isJoin = !new RegExp(sdk.DefiAction.Withdraw, 'ig').test(action ?? ' ')\n            const sellTokenInfo =\n              sellToken?.tokenId !== undefined && tokenMap[idIndex[sellToken?.tokenId]]\n            const sellVolume = sdk.toBig(sellToken?.volume ?? 0).div('1e' + sellTokenInfo.decimals)\n            const buyTokenInfo =\n              buyToken?.tokenId !== undefined && tokenMap[idIndex[buyToken?.tokenId]]\n            const buyVolume = sdk.toBig(buyToken?.volume ?? 0).div('1e' + buyTokenInfo.decimals)\n            const side = isJoin ? t('labelDefiJoin') : t('labelDefiExit')\n            return (\n              <Box display={'flex'} alignItems={'center'}>\n                <Typography color={isJoin ? 'var(--color-success)' : 'var(--color-error)'}>\n                  {side}\n                </Typography>\n                &nbsp;&nbsp;\n                <Typography component={'span'}>\n                  {`${getValuePrecisionThousand(\n                    sellVolume,\n                    sellTokenInfo?.precision,\n                    sellTokenInfo?.precision,\n                    sellTokenInfo?.precision,\n                    false,\n                    { isTrade: true, floor: false },\n                  )} ${sellTokenInfo.symbol}`}\n                </Typography>\n                &nbsp;{DirectionTag} &nbsp;\n                <Typography component={'span'}>\n                  {`${getValuePrecisionThousand(\n                    buyVolume,\n                    buyTokenInfo?.precision,\n                    buyTokenInfo?.precision,\n                    buyTokenInfo?.precision,\n                    false,\n                    { isTrade: true, floor: false },\n                  )} ${buyTokenInfo.symbol}`}\n                </Typography>\n              </Box>\n            )\n          },\n        },\n        {\n          key: 'fee',\n          name: t('labelTxTradingFee'),\n          headerCellClass: 'textAlignRight',\n          formatter: ({ row }) => {\n            const { fee } = row\n            const feeTokenInfo = tokenMap[idIndex[fee?.tokenId ?? '']]\n            const renderValue =\n              fee?.volume == '0' || fee?.volume === undefined\n                ? EmptyValueTag\n                : `${getValuePrecisionThousand(\n                    sdk.toBig(fee?.volume).div('1e' + feeTokenInfo.decimals),\n                    feeTokenInfo?.precision,\n                    feeTokenInfo?.precision,\n                    feeTokenInfo?.precision,\n                    false,\n                    { isTrade: false, floor: false },\n                  )} ${feeTokenInfo.symbol}`\n            return <Box className='rdg-cell-value textAlignRight'>{renderValue}</Box>\n          },\n        },\n        {\n          key: 'time',\n          sortable: false,\n          width: 'auto',\n          headerCellClass: 'textAlignRight',\n          cellClass: 'textAlignRight',\n          name: t('labelDefiTime'),\n          formatter: ({ row }) => {\n            const { updatedAt: time } = row\n            let timeString\n            if (typeof time === 'undefined') {\n              timeString = EmptyValueTag\n            } else {\n              timeString = moment(new Date(time), 'YYYYMMDDHHMM').fromNow()\n            }\n            return (\n              <Typography component={'span'} textAlign={'right'}>\n                {timeString}\n              </Typography>\n            )\n          },\n        },\n      ],\n      [t, tokenMap, idIndex],\n    )\n\n    const getColumnMobileTransaction = React.useCallback(\n      (): Column<R, unknown>[] => [\n        {\n          key: 'side',\n          name: (\n            <Typography\n              height={'100%'}\n              display={'flex'}\n              justifyContent={'space-between'}\n              variant={'inherit'}\n              color={'inherit'}\n              alignItems={'center'}\n            >\n              <span>{t('labelDefiType')}</span>\n              <span>{t('labelDefiTime') + '/' + t('labelTxTradingFee')}</span>\n            </Typography>\n          ),\n          headerCellClass: 'textAlignRight',\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            const { action, sellToken, buyToken } = row\n            const isJoin = !new RegExp(sdk.DefiAction.Withdraw, 'ig').test(action ?? ' ')\n            const sellTokenInfo =\n              sellToken?.tokenId !== undefined && tokenMap[idIndex[sellToken?.tokenId]]\n            const sellVolume = sdk.toBig(sellToken?.volume ?? 0).div('1e' + sellTokenInfo.decimals)\n            const buyTokenInfo =\n              buyToken?.tokenId !== undefined && tokenMap[idIndex[buyToken?.tokenId]]\n            const buyVolume = sdk.toBig(buyToken?.volume ?? 0).div('1e' + buyTokenInfo.decimals)\n            const side = isJoin ? t('labelDefiJoin') : t('labelDefiExit')\n            const { fee } = row\n            const feeTokenInfo = tokenMap[idIndex[fee?.tokenId ?? '']]\n            const feeVolume = sdk\n              .toBig(fee?.volume ?? 0)\n              .div('1e' + feeTokenInfo.decimals)\n              .toNumber()\n            const renderFee =\n              feeVolume === 0 || feeVolume === undefined\n                ? EmptyValueTag\n                : `${getValuePrecisionThousand(\n                    feeVolume,\n                    feeTokenInfo?.precision,\n                    feeTokenInfo?.precision,\n                    feeTokenInfo?.precision,\n                    false,\n                    { isTrade: false, floor: false },\n                  )} ${feeTokenInfo.symbol}`\n            const { updatedAt: time } = row\n            let timeString\n            if (typeof time === 'undefined') {\n              timeString = EmptyValueTag\n            } else {\n              timeString = moment(new Date(time), 'YYYYMMDDHHMM').fromNow()\n            }\n            return (\n              <Box\n                display={'flex'}\n                alignItems={'stretch'}\n                justifyContent={'center'}\n                flexDirection={'column'}\n                height={'100%'}\n              >\n                <Typography\n                  component={'span'}\n                  display={'flex'}\n                  flexDirection={'row'}\n                  variant={'body2'}\n                  justifyContent={'space-between'}\n                >\n                  <Typography color={isJoin ? 'var(--color-success)' : 'var(--color-error)'}>\n                    {side}\n                  </Typography>\n                  &nbsp;\n                  <Typography component={'span'}>\n                    <Typography component={'span'}>\n                      {`${getValuePrecisionThousand(\n                        sellVolume,\n                        sellTokenInfo?.precision,\n                        sellTokenInfo?.precision,\n                        sellTokenInfo?.precision,\n                        false,\n                        { isTrade: false, floor: false },\n                      )} ${sellTokenInfo.symbol}`}\n                    </Typography>\n                    &nbsp;{DirectionTag} &nbsp;\n                    <Typography component={'span'}>\n                      {`${getValuePrecisionThousand(\n                        buyVolume,\n                        buyTokenInfo?.precision,\n                        buyTokenInfo?.precision,\n                        buyTokenInfo?.precision,\n                        false,\n                        { isTrade: false, floor: false },\n                      )} ${buyTokenInfo.symbol}`}\n                    </Typography>\n                  </Typography>\n                </Typography>\n                <Typography\n                  component={'span'}\n                  display={'flex'}\n                  flexDirection={'row'}\n                  variant={'body2'}\n                  justifyContent={'space-between'}\n                >\n                  <Typography\n                    variant={'inherit'}\n                    component={'span'}\n                    color={'textSecondary'}\n                    alignSelf={'flex-end'}\n                  >\n                    {`Fee: ${renderFee}`}\n                  </Typography>\n                  <Typography component={'span'} textAlign={'right'} variant={'inherit'}>\n                    {timeString}\n                  </Typography>\n                </Typography>\n              </Box>\n            )\n          },\n        },\n      ],\n      [t, tokenMap, idIndex],\n    )\n\n    // const [isDropDown, setIsDropDown] = React.useState(true);\n\n    const defaultArgs: any = {\n      columnMode: isMobile ? getColumnMobileTransaction() : getColumnModeTransaction(),\n      generateRows: (rawData: any) => rawData,\n      generateColumns: ({ columnsRaw }: any) => columnsRaw as Column<any, unknown>[],\n    }\n    React.useEffect(() => {\n      // let filters: any = {};\n      updateData.cancel()\n      updateData({ currPage: 1 })\n      // handlePageChange(1);\n      // if (searchParams.get(\"types\")) {\n      //   filters.type = searchParams.get(\"types\");\n      // }\n      // handleFilterChange(filters);\n      return () => {\n        updateData.cancel()\n      }\n    }, [pagination?.pageSize])\n\n    return (\n      <TableStyled isMobile={isMobile}>\n        <Table\n          {...{\n            ...defaultArgs,\n            // rowRenderer: RowRenderer,\n            ...props,\n            rawData,\n            showloading,\n          }}\n        />\n        {pagination && (\n          <TablePagination\n            page={page}\n            pageSize={pagination.pageSize}\n            total={pagination.total}\n            onPageChange={handlePageChange}\n          />\n        )}\n      </TableStyled>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/defiTxsTable/Interface.ts",
    "content": "import * as sdk from '@loopring-web/loopring-sdk'\n\nexport type RawDataDefiTxsItem = Partial<sdk.UserDefiTxsHistory>\n\nexport interface DefiTxsTableProps<R = RawDataDefiTxsItem> {\n  // etherscanBaseUrl?: string;\n  rawData: R[]\n  pagination?: {\n    pageSize: number\n    total: number\n  }\n  idIndex: { [key: string]: string }\n  tokenMap: { [key: string]: any }\n\n  getDefiTxList: (props: any) => Promise<void>\n  // filterTokens: string[];\n  // showFilter?: boolean;\n  showloading: boolean\n  // accAddress: string;\n  // accountId: number;\n}\n\nexport interface RawDataDefiSideStakingItem\n  extends sdk.StakeInfoOrigin,\n    Omit<sdk.STACKING_PRODUCT, 'status'> {\n  status_product: number\n}\n\nexport interface DefiSideStakingTableProps<R = RawDataDefiSideStakingItem> {\n  // etherscanBaseUrl?: string;\n  rawData: R[]\n  pagination?: {\n    pageSize: number\n    total: number\n  }\n  idIndex: { [key: string]: string }\n  tokenMap: { [key: string]: any }\n  geDefiSideStakingList: (props: any) => Promise<void>\n  showloading: boolean\n  redeemItemClick: (item: R) => void\n  hideAssets?: boolean\n}\n\nexport type RawDataDefiSideStakingTxItem = sdk.STACKING_TRANSACTIONS & {\n  stakingType: string\n}\n\nexport interface DefiSideStakingTxTableProps<R = RawDataDefiSideStakingTxItem> {\n  // etherscanBaseUrl?: string;\n  rawData: R[]\n  pagination?: {\n    pageSize: number\n    total: number\n  }\n  idIndex: { [key: string]: string }\n  tokenMap: { [key: string]: any }\n  getSideStakingTxList: (props: any) => Promise<void>\n  showloading: boolean\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/defiTxsTable/components/ActionMemo.tsx",
    "content": "import React from 'react'\nimport { Box, Grid, ListItemText, MenuItem } from '@mui/material'\nimport styled from '@emotion/styled'\nimport { Button, Popover, PopoverType, PopoverWrapProps } from '../../../basic-lib'\nimport { MoreIcon } from '@loopring-web/common-resources'\nimport { useSettings } from '../../../../stores'\nimport { RawDataDefiSideStakingItem } from '../Interface'\nimport { useTranslation } from 'react-i18next'\n\nconst GridStyled = styled(Grid)`\n  .MuiGrid-item {\n    padding: ${({ theme }) => theme.unit / 4}px 0 0;\n  }\n`\nexport type ActionProps<R> = {\n  item: R\n  redeemItemClick: (item: R) => void\n  onDetailClick: (item: R) => void\n}\nconst ActionPopContent = React.memo(\n  <R extends RawDataDefiSideStakingItem>({\n    redeemItemClick,\n    onDetailClick,\n    item,\n  }: ActionProps<R>) => {\n    const { t } = useTranslation(['tables', 'common'])\n\n    const { isMobile } = useSettings()\n    const tradeList = [\n      <MenuItem key={'token-Receive'} onClick={() => onDetailClick(item)}>\n        <ListItemText>{t('labelDefiStakingDetail', { ns: 'tables' })}</ListItemText>\n      </MenuItem>,\n      <MenuItem key={'token-Send'} onClick={() => redeemItemClick(item)}>\n        <ListItemText>{t('labelDefiStakingRedeem', { ns: 'tables' })}</ListItemText>\n      </MenuItem>,\n    ]\n\n    return (\n      <Box borderRadius={'inherit'} minWidth={110}>\n        {isMobile &&\n          tradeList.map((item, index) => <React.Fragment key={index}>{item}</React.Fragment>)}\n      </Box>\n    )\n  },\n) as <R extends RawDataDefiSideStakingItem>(props: ActionProps<R>) => JSX.Element\n\nconst ActionMemo = React.memo(<R extends RawDataDefiSideStakingItem>(props: ActionProps<R>) => {\n  const { isMobile } = useSettings()\n  const { t } = useTranslation(['tables', 'common'])\n\n  const { redeemItemClick, onDetailClick, item } = props\n  const popoverProps: PopoverWrapProps = {\n    type: PopoverType.click,\n    popupId: 'testPopup',\n    className: 'arrow-none',\n    children: <MoreIcon cursor={'pointer'} />,\n    popoverContent: <ActionPopContent {...props} />,\n    anchorOrigin: {\n      vertical: 'bottom',\n      horizontal: 'right',\n    },\n    transformOrigin: {\n      vertical: 'top',\n      horizontal: 'right',\n    },\n  } as PopoverWrapProps\n\n  return (\n    <GridStyled\n      container\n      spacing={1}\n      justifyContent={'space-between'}\n      alignItems={'center'}\n      flexWrap={'nowrap'}\n      padding={0}\n      margin={0}\n      height={'100%'}\n    >\n      {isMobile ? (\n        <>\n          <Grid item marginTop={1}>\n            <Popover {...{ ...popoverProps }} />\n          </Grid>\n        </>\n      ) : (\n        <>\n          <Button\n            variant={'text'}\n            size={'small'}\n            color={'primary'}\n            onClick={() => onDetailClick(item)}\n          >\n            {t('labelDefiStakingDetail', { ns: 'tables' })}\n          </Button>\n          <Button\n            variant={'text'}\n            size={'small'}\n            color={'primary'}\n            onClick={() => redeemItemClick(item)}\n          >\n            {t('labelDefiStakingRedeem', { ns: 'tables' })}\n          </Button>\n        </>\n      )}\n    </GridStyled>\n  )\n}) as <R extends RawDataDefiSideStakingItem>(props: ActionProps<R>) => JSX.Element\nexport default ActionMemo\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/defiTxsTable/index.ts",
    "content": "export * from './DefiTxsTable'\nexport * from './Interface'\nexport * from './DefiStakingTable'\nexport * from './DefiStakingTxTable'\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/dualTable/DualTable.tsx",
    "content": "import { WithTranslation, withTranslation } from 'react-i18next'\nimport { useSettings } from '../../../stores'\nimport React from 'react'\nimport { Button, Column, Table } from '../../basic-lib'\nimport { Box, Typography } from '@mui/material'\nimport { TablePaddingX } from '../../styled'\nimport styled from '@emotion/styled'\nimport { FormatterProps } from 'react-data-grid'\nimport { RawDataDualsItem } from './Interface'\nimport {\n  EmptyValueTag,\n  ForexMap,\n  getValuePrecisionThousand,\n  RowDualInvestConfig,\n  UpColor,\n  UpIcon,\n  YEAR_DAY_FORMAT,\n} from '@loopring-web/common-resources'\nimport { useHistory } from 'react-router-dom'\nimport moment from 'moment/moment'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nconst TableWrapperStyled = styled(Box)`\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n  height: 100%;\n  ${({ theme }) => TablePaddingX({ pLeft: theme.unit * 3, pRight: theme.unit * 3 })}\n`\nconst TableStyled = styled(Table)<{ isMobile: boolean }>`\n  &.rdg {\n    --template-columns: ${({ isMobile }: any) =>\n      isMobile ? '20% 44% auto !important' : '18% auto 18% 18% 20% !important'};\n\n    height: ${(props: any) => {\n      if (props.ispro === 'pro') {\n        return '620px'\n      }\n      if (props.currentheight) {\n        return props.currentheight + 'px'\n      } else {\n        return '100%'\n      }\n    }};\n\n    .rdg-cell.action {\n      display: flex;\n      justify-content: center;\n      align-items: center;\n    }\n  }\n  .textAlignRight {\n    text-align: right;\n\n    .rdg-header-sort-cell {\n      justify-content: flex-end;\n    }\n  }\n  .textAlignCenter {\n    text-align: center;\n  }\n` as any\n\nexport interface DualsTableProps<R, C = sdk.Currency> {\n  rawData: R[]\n  showloading: boolean\n  forexMap: ForexMap<C>\n  onItemClick: (item: R) => void\n}\n\nconst ButtonStyled = styled(Button)`\n  & {\n    border-color: var(--color-primary);\n    color: var(--color-primary);\n    font-size: 16px;\n    height: ${({ theme }) => 5 * theme.unit}px;\n    padding-left: ${({ theme }) => 2.5 * theme.unit}px;\n    padding-right: ${({ theme }) => 2.5 * theme.unit}px;\n  }\n`\n\nexport const DualTable = withTranslation(['tables', 'common'])(\n  <R extends RawDataDualsItem>(props: DualsTableProps<R> & WithTranslation) => {\n    const { rawData, showloading, onItemClick, t } = props\n    const { isMobile, upColor } = useSettings()\n    const history = useHistory()\n    const getColumnModeTransaction = React.useCallback(\n      (): Column<R, unknown>[] => [\n        {\n          key: 'Apy',\n          sortable: true,\n          cellClass: 'textAlignLeft',\n          headerCellClass: 'textAlignLeft',\n          name: t('labelDualApy'),\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            return <Box display={'flex'}>{row?.apy ?? EmptyValueTag}</Box>\n          },\n        },\n        {\n          key: 'targetPrice',\n          sortable: true,\n          name: t('labelDualPrice'),\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            const [_upColor, _downColor] =\n              upColor == UpColor.green\n                ? ['var(--color-success)', 'var(--color-error)']\n                : ['var(--color-error)', 'var(--color-success)']\n            return (\n              <Box display='flex' justifyContent={'stretch'} height={'100%'} alignItems={'center'}>\n                <Typography component={'span'}>\n                  {row.strike + ' ' + (row.currentPrice?.quoteUnit ?? row?.currentPrice?.quote)}\n                </Typography>\n                <Typography\n                  component={'span'}\n                  display={'inline-flex'}\n                  alignItems={'center'}\n                  color={'textSecondary'}\n                  variant={'body2'}\n                >\n                  <UpIcon\n                    fontSize={'small'}\n                    // htmlColor={row.isUp ? _upColor : _downColor}\n                    style={{\n                      transform: row.isUp ? '' : 'rotate(-180deg)',\n                    }}\n                  />\n                  {row.settleRatio\n                    ? getValuePrecisionThousand(\n                        sdk\n                          .toBig(row.strike ?? 0)\n                          .minus(row.currentPrice?.currentPrice ?? 0)\n                          .div(row.currentPrice?.currentPrice ?? 1)\n                          .times(100)\n                          .abs(),\n                        2,\n                        2,\n                        2,\n                        true,\n                      ) + '%'\n                    : EmptyValueTag}\n                </Typography>\n              </Box>\n            )\n          },\n        },\n        {\n          key: 'Term',\n          sortable: true,\n          name: t('labelDualTerm'),\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            return <Box display='flex'>{row.term}</Box>\n          },\n        },\n        {\n          key: 'Settlement',\n          sortable: true,\n          name: t('labelDualSettlement'),\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            return (\n              <Box display='flex'>{moment(new Date(row.expireTime)).format(YEAR_DAY_FORMAT)}</Box>\n            )\n          },\n        },\n        {\n          key: 'Action',\n          sortable: false,\n          cellClass: 'textAlignRight',\n          headerCellClass: 'textAlignRight',\n          name: t('labelDualAction'),\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            return (\n              <Typography\n                variant={'inherit'}\n                color={'textPrimary'}\n                display={'inline-flex'}\n                flexDirection={'column'}\n                className={'textAlignRight'}\n                component={'span'}\n              >\n                <ButtonStyled\n                  variant={'outlined'}\n                  size={'medium'}\n                  onClick={(_e) => {\n                    onItemClick(row)\n                  }}\n                >\n                  {t('labelInvestBtn', { ns: 'common' })}\n                </ButtonStyled>\n              </Typography>\n            )\n          },\n        },\n      ],\n      [history, upColor, t],\n    )\n\n    const getColumnMobileTransaction = React.useCallback(\n      (): Column<R, unknown>[] => [\n        {\n          key: 'Apy',\n          sortable: true,\n          cellClass: 'textAlignLeft',\n          headerCellClass: 'textAlignLeft',\n          name: t('labelDualApy'),\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            return <Box display={'flex'}>{row?.apy ?? EmptyValueTag}</Box>\n          },\n        },\n        {\n          key: 'targetPrice',\n          sortable: true,\n          name: t('labelDualPrice'),\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            const [_upColor, _downColor] =\n              upColor == UpColor.green\n                ? ['var(--color-success)', 'var(--color-error)']\n                : ['var(--color-error)', 'var(--color-success)']\n            return (\n              <Box display='flex' justifyContent={'stretch'} height={'100%'} alignItems={'center'}>\n                <Typography component={'span'}>\n                  {row.strike + ' ' + (row.currentPrice?.quoteUnit ?? row?.currentPrice?.quote)}\n                </Typography>\n                <Typography\n                  component={'span'}\n                  display={'inline-flex'}\n                  alignItems={'center'}\n                  color={'textSecondary'}\n                  variant={'body2'}\n                >\n                  <UpIcon\n                    fontSize={'small'}\n                    // htmlColor={row.isUp ? _upColor : _downColor}\n                    style={{\n                      transform: row.isUp ? '' : 'rotate(-180deg)',\n                    }}\n                  />\n                  {row.settleRatio\n                    ? getValuePrecisionThousand(\n                        sdk\n                          .toBig(row.strike ?? 0)\n                          .minus(row.currentPrice?.currentPrice ?? 0)\n                          .div(row.currentPrice?.currentPrice ?? 1)\n                          .times(100)\n                          .abs(),\n                        2,\n                        2,\n                        2,\n                        true,\n                      ) + '%'\n                    : EmptyValueTag}\n                </Typography>\n              </Box>\n            )\n          },\n        },\n        {\n          key: 'Settlement',\n          sortable: true,\n          cellClass: 'textAlignRight',\n          headerCellClass: 'textAlignRight',\n          name: t('labelDualSettlement'),\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            return <>{moment(new Date(row.expireTime)).format(YEAR_DAY_FORMAT)}</>\n          },\n        },\n      ],\n      [t],\n    )\n\n    const defaultArgs: any = {\n      columnMode: isMobile ? getColumnMobileTransaction() : getColumnModeTransaction(),\n      generateRows: (rawData: any) => rawData,\n      generateColumns: ({ columnsRaw }: any) => columnsRaw as Column<any, unknown>[],\n    }\n\n    const sortMethod = React.useCallback(\n      (_sortedRows, sortColumn) => {\n        let _rawData: R[] = []\n        switch (sortColumn) {\n          case 'Apy':\n            _rawData = rawData.sort((a, b) => {\n              const replaced = new RegExp(`[\\\\${sdk.SEP},%]`, 'ig')\n              const valueA = a.apy?.replace(replaced, '') ?? 0\n              const valueB = b.apy?.replace(replaced, '') ?? 0\n              return Number(valueB) - Number(valueA) //.localeCompare(valueA);\n            })\n            // default;\n            break\n          case 'targetPrice':\n            _rawData = rawData.sort((a, b) => {\n              const replaced = new RegExp(`\\\\${sdk.SEP}`, 'ig')\n              const valueA = a.strike?.replace(replaced, '') ?? 0\n              const valueB = b.strike?.replace(replaced, '') ?? 0\n              return Number(valueB) - Number(valueA) //.loc\n            })\n            break\n          case 'Settlement':\n          case 'Term':\n            _rawData = rawData.sort((a, b) => {\n              return b.expireTime - a.expireTime\n            })\n            break\n          default:\n            _rawData = rawData\n        }\n\n        // resetTableData(_rawData)\n        return _rawData\n      },\n      [rawData],\n    )\n\n    return (\n      <TableWrapperStyled>\n        <TableStyled\n          isMobile={isMobile}\n          currentheight={\n            rawData.length > 0\n              ? RowDualInvestConfig.rowHeaderHeight + rawData.length * RowDualInvestConfig.rowHeight\n              : RowDualInvestConfig.minHeight\n          }\n          rowHeight={RowDualInvestConfig.rowHeight}\n          headerRowHeight={RowDualInvestConfig.rowHeaderHeight}\n          onRowClick={(_index: number, row: R) => {\n            onItemClick(row)\n          }}\n          sortMethod={sortMethod}\n          {...{\n            ...defaultArgs,\n            // rowRenderer: RowRenderer,\n            ...props,\n\n            rawData,\n            showloading,\n          }}\n        />\n      </TableWrapperStyled>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/dualTable/Interface.ts",
    "content": "import { DualViewInfo } from '@loopring-web/common-resources'\n\nexport type RawDataDualsItem = DualViewInfo\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/dualTable/index.ts",
    "content": "export * from './DualTable'\nexport * from './Interface'\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/dualTxsTable/DualAssetTable.tsx",
    "content": "import { WithTranslation, withTranslation } from 'react-i18next'\nimport { useSettings } from '../../../stores'\nimport React from 'react'\nimport {\n  AlertIcon,\n  ClockIcon,\n  EmptyValueTag,\n  getValuePrecisionThousand,\n  globalSetup,\n  HiddenTag,\n  MoreIcon,\n  TokenType,\n  YEAR_DAY_MINUTE_FORMAT,\n} from '@loopring-web/common-resources'\nimport { Column, Table, TablePagination } from '../../basic-lib'\nimport { Box, BoxProps, Link, Tooltip, Typography } from '@mui/material'\nimport moment from 'moment'\nimport { TablePaddingX } from '../../styled'\nimport styled from '@emotion/styled'\nimport { FormatterProps } from 'react-data-grid'\nimport { DualAssetTableProps, RawDataDualAssetItem } from './Interface'\nimport { CoinIcons } from '../assetsTable'\nimport _ from 'lodash'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { DUAL_TYPE } from '@loopring-web/loopring-sdk'\n\nconst TableWrapperStyled = styled(Box)<BoxProps & { isMobile: boolean }>`\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n  height: 100%;\n\n  .rdg {\n    ${({ isMobile }) =>\n      !isMobile\n        ? `--template-columns: 16% 15% 20% 105px 14% 80px 110px 90px!important`\n        : `--template-columns: 16% 30% 44% 10% !important;`}\n  }\n\n  ${({ theme }) => TablePaddingX({ pLeft: theme.unit * 3, pRight: theme.unit * 3 })}\n` as (prosp: BoxProps & { isMobile: boolean }) => JSX.Element\nconst TableStyled = styled(Table)`\n  &.rdg {\n    height: ${(props: any) => {\n      return props.currentheight + 'px'\n    }};\n\n    .rdg-cell.action {\n      display: flex;\n      justify-content: center;\n      align-items: center;\n    }\n\n    .logo-icon.dual:last-child {\n      transform: scale(0.6) translate(0, 4px);\n    }\n  }\n\n  .textAlignRight {\n    text-align: right;\n\n    .rdg-header-sort-cell {\n      justify-content: flex-end;\n    }\n  }\n\n  .textAlignCenter {\n    text-align: center;\n  }\n` as any\n\nexport const DualAssetTable = withTranslation(['tables', 'common'])(\n  <R extends RawDataDualAssetItem>(props: DualAssetTableProps<R> & WithTranslation) => {\n    const {\n      rawData,\n      pagination,\n      getDualAssetList,\n      getDetail,\n      dualMarketMap,\n      showloading,\n      showDetail,\n      refresh,\n      cancelReInvest,\n      hideAssets,\n      rowConfig,\n      noMinHeight,\n      t,\n    } = props\n\n    const { isMobile, coinJson } = useSettings()\n    const [page, setPage] = React.useState(1)\n    const updateData = _.debounce(\n      ({\n        // tableType,\n        currPage = page,\n        pageSize = pagination?.pageSize ?? 10,\n      }: {\n        // tableType: TableType;\n        currPage?: number\n        pageSize?: number\n      }) => {\n        getDualAssetList({\n          limit: pageSize,\n          offset: (currPage - 1) * pageSize,\n        })\n      },\n      globalSetup.wait,\n    )\n\n    const handlePageChange = React.useCallback(\n      (currPage: number) => {\n        if (currPage === page) return\n        setPage(currPage)\n        updateData({ currPage: currPage })\n      },\n      [updateData, page],\n    )\n    const getColumnMode = React.useCallback(\n      (): Column<R, unknown>[] => [\n        {\n          key: 'Product',\n          sortable: false,\n          width: 'auto',\n          name: t('labelDualAssetProduct'),\n          cellClass: 'textAlignLeft',\n          headerCellClass: 'textAlignLeft',\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            const {\n              sellSymbol,\n              buySymbol,\n              __raw__: {\n                order: {\n                  dualType,\n                  // investmentStatus,\n                  settlementStatus,\n                  dualReinvestInfo,\n                },\n              },\n            } = row\n            const [base, quote] =\n              dualType === DUAL_TYPE.DUAL_BASE ? [sellSymbol, buySymbol] : [buySymbol, sellSymbol]\n\n            const showClock =\n              dualReinvestInfo?.isRecursive &&\n              settlementStatus?.toUpperCase() == sdk.SETTLEMENT_STATUS.PAID &&\n              dualReinvestInfo?.retryStatus?.toUpperCase() === sdk.DUAL_RETRY_STATUS.RETRYING\n            return (\n              <Typography\n                component={'span'}\n                flexDirection={'row'}\n                display={'flex'}\n                height={'100%'}\n                alignItems={'center'}\n              >\n                <Typography component={'span'} display={'inline-flex'}>\n                  <CoinIcons\n                    type={TokenType.dual}\n                    size={24}\n                    tokenIcon={[coinJson[row.sellSymbol], coinJson[row.buySymbol]]}\n                  />\n                </Typography>\n                <Typography component={'span'} display={'flex'} alignItems={'center'}>\n                  {showClock ? (\n                    <Tooltip title={t('labelDualRetryStatusRetrying').toString()}>\n                      <Typography\n                        component={'span'}\n                        // display={\"inline-flex\"}\n                        alignItems={'center'}\n                        color={'textPrimary'}\n                        display={'inline-flex'}\n                        flexDirection={'row'}\n                      >\n                        {`${base}/${quote}`}\n                        <ClockIcon sx={{ marginLeft: 1 }} color={'warning'} />\n                      </Typography>\n                    </Tooltip>\n                  ) : (\n                    <Typography\n                      component={'span'}\n                      // display={\"inline-flex\"}\n                      color={'textPrimary'}\n                      display={'flex'}\n                      flexDirection={'column'}\n                    >\n                      {`${base}/${quote}`}\n                    </Typography>\n                  )}\n                </Typography>\n              </Typography>\n            )\n          },\n        },\n        {\n          key: 'Frozen',\n          sortable: false,\n          width: 'auto',\n          cellClass: 'textAlignCenter',\n          headerCellClass: 'textAlignCenter',\n          name: t('labelDualAssetFrozen'),\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            if (hideAssets) {\n              return <>{HiddenTag}</>\n            } else if (!row?.amount) {\n              return <>{'-- ' + row.sellSymbol}</>\n            } else {\n              return <>{row?.amount + ' ' + row.sellSymbol}</>\n            }\n          },\n        },\n        {\n          key: 'Return',\n          sortable: false,\n          width: 'auto',\n          name: t('labelDualAssetReturn'),\n          cellClass: 'textAlignCenter',\n          headerCellClass: 'textAlignCenter',\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            const { currentPrice, lessEarnView, greaterEarnView } = getDetail(row)\n            const { base, quote } = currentPrice\n            return (\n              <>\n                {hideAssets\n                  ? HiddenTag\n                  : (lessEarnView === '0' ? EmptyValueTag : lessEarnView) +\n                    ' ' +\n                    base +\n                    '/' +\n                    (greaterEarnView === '0' ? EmptyValueTag : greaterEarnView) +\n                    ' ' +\n                    quote}\n              </>\n            )\n          },\n        },\n        {\n          key: 'Price',\n          sortable: false,\n          width: 'auto',\n          name: t('labelDualAssetPrice'),\n          cellClass: 'textAlignCenter',\n          headerCellClass: 'textAlignCenter',\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            return <>{row?.strike}</>\n          },\n        },\n        {\n          key: 'Settlement_Date',\n          sortable: false,\n          width: 'auto',\n          name: t('labelDualAssetSettlement_Date'),\n          cellClass: 'textAlignCenter',\n          headerCellClass: 'textAlignCenter',\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            return <>{moment(new Date(row.expireTime)).format(YEAR_DAY_MINUTE_FORMAT)}</>\n          },\n        },\n        {\n          key: 'APR',\n          sortable: false,\n          width: 'auto',\n          cellClass: 'textAlignCenter',\n          headerCellClass: 'textAlignCenter',\n          name: t('labelDualAssetAPR'),\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            return <>{row?.apy}</>\n          },\n        },\n        {\n          key: 'Auto',\n          sortable: false,\n          name: t('labelDualAutoReinvest'),\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            return row?.__raw__.order?.dualReinvestInfo?.isRecursive ? (\n              <Link\n                onClick={(_e) => {\n                  cancelReInvest(row)\n                }}\n              >\n                {t('labelDualAssetReInvestEnable')}\n              </Link>\n            ) : (\n              <>{t('labelDualAssetReInvestDisable')} </>\n            )\n          },\n        },\n        {\n          key: 'Action',\n          sortable: false,\n          width: 'auto',\n          cellClass: 'textAlignRight',\n          headerCellClass: 'textAlignRight',\n          name: t('labelDualAssetAction'),\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            const investmentStatus = row.__raw__.order.investmentStatus\n            const showRefresh = investmentStatus === sdk.LABEL_INVESTMENT_STATUS.PROCESSING\n            const dualType = row.__raw__.order?.dualType\n            const isRecursive = row.__raw__.order?.dualReinvestInfo?.isRecursive\n            const newStrike = row.__raw__.order?.dualReinvestInfo?.newStrike\n            const { currentPrice, precisionForPrice, base, currency } = row.__raw__?.currentPrice\n            const currentView = currentPrice\n              ? getValuePrecisionThousand(\n                  currentPrice,\n                  precisionForPrice ?? 6,\n                  precisionForPrice ?? 6,\n                  undefined,\n                  false,\n                )\n              : EmptyValueTag\n            let showAlert = false\n            if (isRecursive && dualType == DUAL_TYPE.DUAL_BASE) {\n              showAlert = sdk\n                .toBig(currentPrice ?? 0)\n                .div(newStrike)\n                .minus(1)\n                .lte(-0.05)\n            } else {\n              showAlert = sdk\n                .toBig(currentPrice ?? 0)\n                .div(newStrike)\n                .minus(1)\n                .gte(0.05)\n            }\n\n            return showRefresh ? (\n              <Link\n                onClick={(_e) => {\n                  refresh(row)\n                }}\n              >\n                {t('labelDualAssetRefresh')}\n              </Link>\n            ) : showAlert ? (\n              <Tooltip\n                title={t('labelDualAutoAlert', {\n                  ns: 'common',\n                  base,\n                  currentPrice: currentView,\n                  quote: currency,\n                  method:\n                    dualType == DUAL_TYPE.DUAL_BASE\n                      ? t('labelDualIsLow', { ns: 'common' })\n                      : t('labelDualIsHigh', { ns: 'common' }),\n                }).toString()}\n              >\n                <Typography display={'inline-flex'} alignItems={'center'}>\n                  <Link paddingRight={1 / 2} onClick={(_e) => showDetail(row)}>\n                    {t('labelDualAssetDetail')}\n                  </Link>\n                  <AlertIcon color={'warning'} />\n                </Typography>\n              </Tooltip>\n            ) : (\n              <Link onClick={(_e) => showDetail(row)}>{t('labelDualAssetDetail')}</Link>\n            )\n          },\n        },\n      ],\n      [coinJson, t, hideAssets],\n    )\n\n    const getColumnMobile = React.useCallback(\n      (): Column<R, unknown>[] => [\n        {\n          key: 'Product',\n          sortable: false,\n          width: 'auto',\n          name: t('labelDualAssetProduct'),\n          cellClass: 'textAlignLeft',\n          headerCellClass: 'textAlignLeft',\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            const {\n              __raw__: {\n                order: { dualType, investmentStatus, settlementStatus, dualReinvestInfo },\n              },\n            } = row\n            // const inAuto = investmentStatus === sdk.LABEL_INVESTMENT_STATUS.PROCESSING\n            const showClock =\n              dualReinvestInfo?.isRecursive &&\n              settlementStatus?.toUpperCase() == sdk.SETTLEMENT_STATUS.PAID &&\n              dualReinvestInfo?.retryStatus?.toUpperCase() === sdk.DUAL_RETRY_STATUS.RETRYING\n            return (\n              <Typography\n                component={'span'}\n                flexDirection={'row'}\n                display={'flex'}\n                height={'100%'}\n                alignItems={'center'}\n              >\n                <Typography component={'span'} display={'inline-flex'}>\n                  <CoinIcons\n                    type={TokenType.dual}\n                    size={24}\n                    tokenIcon={[coinJson[row.sellSymbol], coinJson[row.buySymbol]]}\n                  />\n                </Typography>\n                {showClock && (\n                  <Tooltip title={t('labelDualRetryStatusRetrying').toString()}>\n                    <ClockIcon sx={{ marginLeft: 1 }} color={'warning'} />\n                  </Tooltip>\n                )}\n              </Typography>\n            )\n          },\n        },\n        {\n          key: 'Price',\n          sortable: false,\n          width: 'auto',\n          name: t('labelDualAssetPrice') + '/' + t('labelDualAssetSettlement_Date'),\n          cellClass: 'textAlignCenter',\n          headerCellClass: 'textAlignCenter',\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            const dualType = row.__raw__.order?.dualType\n            const newStrike = row.__raw__.order?.dualReinvestInfo?.newStrike\n            const isRecursive = row.__raw__.order?.dualReinvestInfo?.isRecursive\n            const { currentPrice, precisionForPrice, base, currency } = row.__raw__?.currentPrice ?? {}\n            const currentView = currentPrice\n              ? getValuePrecisionThousand(\n                  currentPrice,\n                  precisionForPrice ?? 6,\n                  precisionForPrice ?? 6,\n                  undefined,\n                  false,\n                )\n              : EmptyValueTag\n            let showAlert = false\n            if (isRecursive && dualType == DUAL_TYPE.DUAL_BASE) {\n              showAlert = sdk.toBig(currentPrice).div(newStrike).minus(1).lte(-0.05)\n            } else {\n              showAlert = sdk.toBig(currentPrice).div(newStrike).minus(1).gte(0.05)\n            }\n\n            return (\n              <Box\n                className={'textAlignRight'}\n                display={'flex'}\n                flexDirection={'column'}\n                height={'100%'}\n                justifyContent={'center'}\n              >\n                {showAlert ? (\n                  <Tooltip\n                    title={t('labelDualAutoAlert', {\n                      ns: 'common',\n                      base,\n                      currentPrice: currentView,\n                      quote: currency,\n                      method:\n                        dualType == DUAL_TYPE.DUAL_BASE\n                          ? t('labelDualIsLow', { ns: 'common' })\n                          : t('labelDualIsHigh', { ns: 'common' }),\n                    }).toString()}\n                  >\n                    <Typography component={'span'}>\n                      {row?.strike}\n                      <AlertIcon color={'warning'} />\n                    </Typography>\n                  </Tooltip>\n                ) : (\n                  <Typography component={'span'}>{row?.strike}</Typography>\n                )}\n                <Typography component={'span'} variant={'body2'} color={'textSecondary'}>\n                  {moment(new Date(row.expireTime)).format(YEAR_DAY_MINUTE_FORMAT)}\n                </Typography>\n              </Box>\n            )\n          },\n        },\n        {\n          key: 'APR',\n          sortable: false,\n          width: 'auto',\n          cellClass: 'textAlignRight',\n          headerCellClass: 'textAlignRight',\n          name: t('labelDualAssetAPR') + '/' + t('labelDualAssetFrozen'),\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            return (\n              <>\n                <Box\n                  className={'textAlignRight'}\n                  display={'flex'}\n                  flexDirection={'column'}\n                  height={'100%'}\n                  justifyContent={'center'}\n                >\n                  <Typography component={'span'}>{row?.apy}</Typography>\n                  <Typography component={'span'} variant={'body2'} color={'textSecondary'}>\n                    {hideAssets ? HiddenTag : row?.amount + ' ' + row.sellSymbol}\n                  </Typography>\n                </Box>\n              </>\n            )\n          },\n        },\n        {\n          key: 'Action',\n          sortable: false,\n          cellClass: 'textAlignRight',\n          headerCellClass: 'textAlignRight',\n          name: 'Action',\n          formatter: ({ row }: FormatterProps<R>) => {\n            return <MoreIcon onClick={() => showDetail(row)} cursor={'pointer'} />\n          },\n        },\n      ],\n      [coinJson, t, hideAssets],\n    )\n\n    const sortMethod = React.useCallback(\n      (_sortedRows, sortColumn) => {\n        let _dualList: R[] = []\n        switch (sortColumn) {\n          case 'Settlement_Date':\n            _dualList = rawData.sort((a, b) => {\n              return b.expireTime - a.expireTime\n            })\n            break\n\n          case 'APR':\n            _dualList = rawData.sort((a, b) => {\n              const replaced = new RegExp(`[\\\\${sdk.SEP},%]`, 'ig')\n              const valueA = a.apy?.replace(replaced, '') ?? 0\n              const valueB = b.apy?.replace(replaced, '') ?? 0\n              return Number(valueB) - Number(valueA)\n            })\n            break\n          default:\n            _dualList = rawData\n        }\n        // resetTableData(_dualList)\n        return _dualList\n      },\n      [rawData],\n    )\n    const defaultArgs: any = {\n      columnMode: isMobile ? getColumnMobile() : getColumnMode(),\n      generateRows: (rawData: any) => rawData,\n      generateColumns: ({ columnsRaw }: any) => columnsRaw as Column<any, unknown>[],\n    }\n    React.useEffect(() => {\n      if (dualMarketMap) {\n        updateData.cancel()\n        updateData({ currPage: 1 })\n      }\n      // let filters: any = {};\n      // handlePageChange(1);\n      // if (searchParams.get(\"types\")) {\n      //   filters.type = searchParams.get(\"types\");\n      // }\n      // handleFilterChange(filters);\n      return () => {\n        updateData.cancel()\n      }\n    }, [pagination?.pageSize, dualMarketMap])\n    return (\n      <TableWrapperStyled isMobile={isMobile}>\n        <TableStyled\n          currentheight={\n            rawData.length\n              ? rowConfig.rowHeaderHeight! + rawData.length * rowConfig.rowHeight!\n              : 350\n          }\n          style={{\n            minHeight:noMinHeight ? 0 : undefined\n          }}\n          rowHeight={rowConfig.rowHeight}\n          headerRowHeight={rowConfig.rowHeaderHeight}\n          sortMethod={sortMethod}\n          {...{\n            ...defaultArgs,\n            // rowRenderer: RowRenderer,\n            ...props,\n            rawData,\n            showloading,\n          }}\n        />\n        {pagination && pagination.total > pagination.pageSize && (\n          <TablePagination\n            page={page}\n            pageSize={pagination.pageSize}\n            total={pagination.total}\n            onPageChange={handlePageChange}\n          />\n        )}\n      </TableWrapperStyled>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/dualTxsTable/DualTxsTable.tsx",
    "content": "import _ from 'lodash'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport { useSettings } from '../../../stores'\nimport React from 'react'\nimport {\n  CompleteIcon,\n  WarningIcon,\n  WaitingIcon,\n  DAY_FORMAT,\n  DirectionTag,\n  EmptyValueTag,\n  getValuePrecisionThousand,\n  globalSetup,\n  MINUTE_FORMAT,\n  YEAR_DAY_MINUTE_FORMAT,\n} from '@loopring-web/common-resources'\nimport { Column, Table, TablePagination } from '../../basic-lib'\nimport { Box, BoxProps, Tooltip, Typography } from '@mui/material'\nimport moment from 'moment'\nimport { TablePaddingX } from '../../styled'\nimport styled from '@emotion/styled'\nimport { FormatterProps } from 'react-data-grid'\nimport { DualTxsTableProps, LABEL_INVESTMENT_STATUS_MAP, RawDataDualTxsItem } from './Interface'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { DUAL_TYPE, LABEL_INVESTMENT_STATUS } from '@loopring-web/loopring-sdk'\n\nconst TableStyled = styled(Box)<BoxProps & { isMobile?: boolean }>`\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n\n  .rdg {\n    ${({ isMobile }) =>\n      !isMobile\n        ? `--template-columns: 30% auto 76px  120px 120px 160px 120px !important;`\n        : `--template-columns: 100% !important;`}\n    .rdgCellCenter {\n      height: 100%;\n      justify-content: center;\n      align-items: center;\n    }\n\n    .textAlignRight {\n      text-align: right;\n    }\n\n    .textAlignCenter {\n      text-align: center;\n    }\n\n    .textAlignLeft {\n      text-align: left;\n    }\n  }\n\n  ${({ theme }) => TablePaddingX({ pLeft: theme.unit * 3, pRight: theme.unit * 3 })}\n` as (props: { isMobile?: boolean } & BoxProps) => JSX.Element\n\nexport const DualTxsTable = withTranslation(['tables', 'common'])(\n  <R extends RawDataDualTxsItem>(props: DualTxsTableProps<R> & WithTranslation) => {\n    const { rawData, idIndex, pagination, tokenMap, getDualTxList, showloading, dualMarketMap, t } =\n      props\n    const { isMobile } = useSettings()\n    const [page, setPage] = React.useState(1)\n\n    const updateData = _.debounce(\n      ({\n        // tableType,\n        currPage = page,\n        pageSize = pagination?.pageSize ?? 10,\n      }: {\n        // tableType: TableType;\n        currPage?: number\n        pageSize?: number\n      }) => {\n        getDualTxList({\n          limit: pageSize,\n          offset: (currPage - 1) * pageSize,\n        })\n      },\n      globalSetup.wait,\n    )\n\n    const handlePageChange = React.useCallback(\n      (currPage: number) => {\n        if (currPage === page) return\n        setPage(currPage)\n        updateData({ currPage: currPage })\n      },\n      [updateData, page],\n    )\n\n    const getColumnModeTransaction = React.useCallback(\n      (): Column<R, unknown>[] => [\n        {\n          sortable: false,\n          width: 'auto',\n          key: 'DualTxsSide',\n          name: t('labelDualTxsSide'),\n          cellClass: 'textAlignLeft',\n          headerCellClass: 'textAlignLeft',\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            const {\n              __raw__: {\n                order: {\n                  settlementStatus,\n                  tokenInfoOrigin: { amountIn, tokenOut, amountOut },\n                  timeOrigin: { expireTime },\n                  investmentStatus,\n                },\n              },\n              // expireTime,\n              sellSymbol,\n            } = row\n            const sellAmount = sdk\n              .toBig(amountIn ? amountIn : 0)\n              .div('1e' + tokenMap[sellSymbol].decimals)\n            const amount = getValuePrecisionThousand(\n              sellAmount,\n              tokenMap[sellSymbol].precision,\n              tokenMap[sellSymbol].precision,\n              tokenMap[sellSymbol].precision,\n              false,\n            )\n            const side =\n              settlementStatus === sdk.SETTLEMENT_STATUS.PAID\n                ? t(LABEL_INVESTMENT_STATUS_MAP.INVESTMENT_RECEIVED)\n                : Date.now() - expireTime >= 0 &&\n                  investmentStatus !== LABEL_INVESTMENT_STATUS.CANCELLED &&\n                  investmentStatus !== LABEL_INVESTMENT_STATUS.FAILED\n                ? t(LABEL_INVESTMENT_STATUS_MAP.DELIVERING)\n                : t(LABEL_INVESTMENT_STATUS_MAP.INVESTMENT_SUBSCRIBE)\n            const statusColor =\n              settlementStatus === sdk.SETTLEMENT_STATUS.PAID\n                ? 'var(--color-tag)'\n                : Date.now() - expireTime >= 0 &&\n                  investmentStatus !== LABEL_INVESTMENT_STATUS.CANCELLED &&\n                  investmentStatus !== LABEL_INVESTMENT_STATUS.FAILED\n                ? 'var(--color-warning)'\n                : 'var(--color-success)'\n            let buySymbol, buyAmount\n            if (tokenOut !== undefined) {\n              buySymbol = tokenMap[idIndex[tokenOut]].symbol\n              buyAmount = getValuePrecisionThousand(\n                sdk.toBig(amountOut ? amountOut : 0).div('1e' + tokenMap[buySymbol].decimals),\n                tokenMap[buySymbol].precision,\n                tokenMap[buySymbol].precision,\n                tokenMap[buySymbol].precision,\n                false,\n              )\n            }\n\n            const sentence =\n              settlementStatus === sdk.SETTLEMENT_STATUS.PAID\n                ? `${amount} ${sellSymbol} ${DirectionTag} ${buyAmount} ${buySymbol} `\n                : Date.now() - expireTime >= 0\n                ? `${amount} ${sellSymbol}`\n                : `${amount} ${sellSymbol}`\n            const pending = (\n              <Typography borderRadius={1} paddingX={1 / 2} bgcolor={'var(--color-warning)'}>\n                {t('labelDualPending')}\n              </Typography>\n            )\n            const failed = (\n              <Typography borderRadius={1} paddingX={1 / 2} bgcolor={'var(--color-error)'}>\n                {t('labelDualFailed')}\n              </Typography>\n            )\n            return (\n              <Box display={'flex'} alignItems={'center'} flexDirection={'row'}>\n                {investmentStatus === sdk.LABEL_INVESTMENT_STATUS.FAILED ||\n                investmentStatus === sdk.LABEL_INVESTMENT_STATUS.CANCELLED ? (\n                  failed\n                ) : investmentStatus === sdk.LABEL_INVESTMENT_STATUS.PROCESSING ? (\n                  pending\n                ) : (\n                  <Typography color={statusColor}>{side}</Typography>\n                )}\n                &nbsp;&nbsp;\n                <Typography component={'span'}>{sentence}</Typography>\n              </Box>\n            )\n          },\n        },\n        {\n          sortable: false,\n          width: 'auto',\n          key: 'Product',\n          name: t('labelDualTxsProduct'),\n          cellClass: 'textAlignCenter',\n          headerCellClass: 'textAlignCenter',\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            const {\n              sellSymbol,\n              buySymbol,\n              __raw__: {\n                order: { dualType },\n              },\n            } = row\n            const [base, quote] =\n              dualType === DUAL_TYPE.DUAL_BASE ? [sellSymbol, buySymbol] : [buySymbol, sellSymbol]\n            return <>{base + '/' + quote}</>\n          },\n        },\n        {\n          sortable: false,\n          width: 'auto',\n          key: 'APR',\n          name: t('labelDualTxAPR'),\n          cellClass: 'textAlignCenter',\n          headerCellClass: 'textAlignCenter',\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            return <>{row?.apy}</>\n          },\n        },\n        {\n          sortable: false,\n          width: 'auto',\n          key: 'TargetPrice',\n          cellClass: 'textAlignCenter',\n          headerCellClass: 'textAlignCenter',\n          name: t('labelDualTxsTargetPrice'),\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            return <>{row?.strike}</>\n          },\n        },\n        {\n          sortable: false,\n          width: 'auto',\n          key: 'Price',\n          cellClass: 'textAlignCenter',\n          headerCellClass: 'textAlignCenter',\n          name: t('labelDualTxsSettlementPrice'),\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            const {\n              __raw__: {\n                order: {\n                  deliveryPrice,\n                  tokenInfoOrigin: { quote },\n                },\n              },\n            } = row\n            return (\n              <>\n                {deliveryPrice\n                  ? getValuePrecisionThousand(\n                      deliveryPrice,\n                      tokenMap[quote]?.precision,\n                      tokenMap[quote]?.precision,\n                      tokenMap[quote]?.precision,\n                      true,\n                      { isFait: true },\n                    )\n                  : EmptyValueTag}\n              </>\n            )\n          },\n        },\n        {\n          sortable: false,\n          width: 'auto',\n          key: 'Settlement_Date',\n          name: t('labelDualTxsSettlement_Date'),\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            return (\n              <Typography\n                height={'100%'}\n                display={'flex'}\n                flexDirection={'row'}\n                alignItems={'center'}\n              >\n                {moment(new Date(row.__raw__.order.timeOrigin.expireTime)).format(\n                  YEAR_DAY_MINUTE_FORMAT,\n                )}\n              </Typography>\n            )\n          },\n        },\n        {\n          key: 'Auto',\n          sortable: true,\n          name: t('labelDualAutoReinvest'),\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            let icon: any = undefined,\n              status = ''\n            let content = ''\n            const {\n              __raw__: {\n                order: { dualReinvestInfo, tokenInfoOrigin, settlementStatus },\n              },\n            } = row\n            switch (dualReinvestInfo?.retryStatus) {\n              case sdk.DUAL_RETRY_STATUS.RETRY_SUCCESS:\n                icon = <CompleteIcon color={'success'} sx={{ paddingLeft: 1 / 2 }} />\n                status = 'labelDualRetryStatusSuccess'\n                content = 'labelDualRetrySuccess'\n                break\n              case sdk.DUAL_RETRY_STATUS.RETRY_FAILED:\n                icon = <WarningIcon color={'error'} sx={{ paddingLeft: 1 / 2 }} />\n                status = 'labelDualRetryStatusError'\n                content = 'labelDualRetryFailed'\n                break\n              case sdk.DUAL_RETRY_STATUS.NO_RETRY:\n                if (dualReinvestInfo?.isRecursive) {\n                  content = 'labelDualAssetReInvestEnable'\n                } else if (\n                  dualReinvestInfo.onceRecursive &&\n                  settlementStatus === sdk.SETTLEMENT_STATUS.PAID &&\n                  tokenInfoOrigin.tokenOut !== tokenInfoOrigin.tokenIn\n                ) {\n                  icon = <WaitingIcon color={'primary'} sx={{ paddingLeft: 1 / 2 }} />\n                  status = 'labelDualRetryStatusTerminated'\n                  content = 'labelDualRetryTerminated'\n                } else {\n                  content = 'labelDualAssetReInvestDisable'\n                }\n                break\n              case sdk.DUAL_RETRY_STATUS.RETRYING:\n                icon = <WaitingIcon color={'primary'} sx={{ paddingLeft: 1 / 2 }} />\n                status = 'labelDualRetryStatusRetrying'\n                content = 'labelDualRetryPending'\n                break\n              default:\n                content = dualReinvestInfo.isRecursive\n                  ? 'labelDualAssetReInvestEnable'\n                  : 'labelDualAssetReInvestDisable'\n            }\n            return icon ? (\n              <Tooltip\n                title={t(status, {\n                  day: dualReinvestInfo.maxDuration\n                    ? dualReinvestInfo.maxDuration / 86400000\n                    : EmptyValueTag,\n                  price: dualReinvestInfo.newStrike ? dualReinvestInfo.newStrike : EmptyValueTag,\n                }).toString()}\n              >\n                <Typography display={'inline-flex'} alignItems={'center'} height={'100%'}>\n                  <>{t(content)}</>\n                  <>{icon}</>\n                </Typography>\n              </Tooltip>\n            ) : (\n              <>{t(content)}</>\n            )\n          },\n        },\n        {\n          key: 'time',\n          name: t('labelDualTxsTime'),\n          headerCellClass: 'textAlignRight',\n          title: t('labelDualAutoInvestTip'),\n          formatter: ({ row }) => {\n            return (\n              <Box\n                className={'textAlignRight'}\n                display={'flex'}\n                flexDirection={'row'}\n                height={'100%'}\n                alignItems={'center'}\n              >\n                <Typography\n                  component={'span'}\n                  paddingRight={1 / 2}\n                  display={'inline-flex'}\n                  alignItems={'center'}\n                >\n                  {moment(new Date(row.__raw__.order?.createdAt), 'YYYYMMDDHHMM').fromNow()}\n                </Typography>\n              </Box>\n            )\n          },\n        },\n      ],\n      [t, tokenMap, idIndex],\n    )\n\n    const getColumnMobileTransaction = React.useCallback(\n      (): Column<R, unknown>[] => [\n        {\n          sortable: false,\n          width: 'auto',\n          key: 'DualTxsSide',\n          name: t('labelDualTxsSide'),\n          cellClass: 'textAlignLeft',\n          headerCellClass: 'textAlignLeft',\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            let icon: any = undefined,\n              status = '',\n              content\n            const {\n              sellSymbol,\n              apy,\n              buySymbol: _marketBuy,\n              __raw__: {\n                order: {\n                  settlementStatus,\n                  dualType,\n                  deliveryPrice,\n                  investmentStatus,\n                  tokenInfoOrigin: { amountIn, tokenOut, amountOut, tokenIn },\n                  timeOrigin: { expireTime },\n                  dualReinvestInfo,\n                },\n              },\n            } = row\n            const sellAmount = sdk\n              .toBig(amountIn ? amountIn : 0)\n              .div('1e' + tokenMap[sellSymbol].decimals)\n            const amount = getValuePrecisionThousand(\n              sellAmount,\n              tokenMap[sellSymbol].precision,\n              tokenMap[sellSymbol].precision,\n              tokenMap[sellSymbol].precision,\n              false,\n            )\n            const side =\n              settlementStatus === sdk.SETTLEMENT_STATUS.PAID\n                ? t(LABEL_INVESTMENT_STATUS_MAP.INVESTMENT_RECEIVED)\n                : Date.now() - expireTime >= 0 &&\n                  investmentStatus !== LABEL_INVESTMENT_STATUS.CANCELLED &&\n                  investmentStatus !== LABEL_INVESTMENT_STATUS.FAILED\n                ? t(LABEL_INVESTMENT_STATUS_MAP.DELIVERING)\n                : t(LABEL_INVESTMENT_STATUS_MAP.INVESTMENT_SUBSCRIBE)\n            const statusColor =\n              settlementStatus === sdk.SETTLEMENT_STATUS.PAID\n                ? 'var(--color-tag)'\n                : Date.now() - expireTime >= 0 &&\n                  investmentStatus !== LABEL_INVESTMENT_STATUS.CANCELLED &&\n                  investmentStatus !== LABEL_INVESTMENT_STATUS.FAILED\n                ? 'var(--color-warning)'\n                : 'var(--color-success)'\n            let buySymbol, buyAmount\n            if (tokenOut !== undefined) {\n              buySymbol = tokenMap[idIndex[tokenOut]].symbol\n              buyAmount = getValuePrecisionThousand(\n                sdk.toBig(amountOut ? amountOut : 0).div('1e' + tokenMap[buySymbol].decimals),\n                tokenMap[buySymbol].precision,\n                tokenMap[buySymbol].precision,\n                tokenMap[buySymbol].precision,\n                false,\n              )\n            }\n\n            const sentence =\n              settlementStatus === sdk.SETTLEMENT_STATUS.PAID\n                ? `${amount} ${sellSymbol} ${DirectionTag} ${buyAmount} ${buySymbol} `\n                : Date.now() - expireTime >= 0\n                ? `${amount} ${sellSymbol}`\n                : `${amount} ${sellSymbol}`\n            const [base, quote] =\n              dualType === DUAL_TYPE.DUAL_BASE ? [sellSymbol, _marketBuy] : [_marketBuy, sellSymbol]\n\n            switch (dualReinvestInfo?.retryStatus) {\n              case sdk.DUAL_RETRY_STATUS.RETRY_SUCCESS:\n                icon = <CompleteIcon color={'success'} sx={{ paddingLeft: 1 / 2 }} />\n                status = 'labelDualRetryStatusSuccess'\n                content = 'labelDualRetrySuccess'\n                break\n              case sdk.DUAL_RETRY_STATUS.RETRY_FAILED:\n                icon = <WarningIcon color={'error'} sx={{ paddingLeft: 1 / 2 }} />\n                status = 'labelDualRetryStatusError'\n                content = 'labelDualRetryFailed'\n                break\n              case sdk.DUAL_RETRY_STATUS.NO_RETRY:\n                if (dualReinvestInfo?.isRecursive) {\n                  content = 'labelDualAssetReInvestEnable'\n                } else if (\n                  dualReinvestInfo.onceRecursive &&\n                  settlementStatus === sdk.SETTLEMENT_STATUS.PAID &&\n                  tokenIn !== tokenOut\n                ) {\n                  icon = <WarningIcon color={'warning'} sx={{ paddingLeft: 1 / 2 }} />\n                  status = 'labelDualRetryStatusTerminated'\n                  content = 'labelDualRetryTerminated'\n                } else {\n                  content = 'labelDualAssetReInvestDisable'\n                }\n                break\n              case sdk.DUAL_RETRY_STATUS.RETRYING:\n                icon = <WaitingIcon color={'primary'} sx={{ paddingLeft: 1 / 2 }} />\n                status = 'labelDualRetryStatusRetrying'\n                content = 'labelDualRetryPending'\n                break\n              default:\n                content = dualReinvestInfo.isRecursive\n                  ? 'labelDualAssetReInvestEnable'\n                  : 'labelDualAssetReInvestDisable'\n            }\n            const recursiveStatus = icon ? (\n              <Tooltip\n                title={t(status, {\n                  day: dualReinvestInfo.maxDuration\n                    ? dualReinvestInfo.maxDuration / 86400000\n                    : EmptyValueTag,\n                  price: dualReinvestInfo.newStrike ? dualReinvestInfo.newStrike : EmptyValueTag,\n                }).toString()}\n              >\n                <Typography display={'inline-flex'} alignItems={'center'} height={'100%'}>\n                  <>{content}</>\n                  <>{icon}</>\n                </Typography>\n              </Tooltip>\n            ) : (\n              <></>\n            )\n            const pending = (\n              <Typography\n                borderRadius={1}\n                paddingX={1 / 2}\n                component={'span'}\n                fontSize={'9px'}\n                bgcolor={'var(--color-warning)'}\n              >\n                {t('labelDualPending')}\n              </Typography>\n            )\n            const failed = (\n              <Typography\n                borderRadius={1}\n                paddingX={1 / 2}\n                component={'span'}\n                fontSize={'9px'}\n                bgcolor={'var(--color-error)'}\n              >\n                {t('labelDualFailed')}\n              </Typography>\n            )\n\n            return (\n              <Box\n                display={'flex'}\n                alignItems={'stretch'}\n                flexDirection={'column'}\n                height={'100%'}\n                justifyContent={'center'}\n              >\n                <Typography\n                  display={'flex'}\n                  flexDirection={'row'}\n                  justifyContent={'space-between'}\n                  variant={'body2'}\n                >\n                  <Typography\n                    component={'span'}\n                    variant={'inherit'}\n                    display={'inline-flex'}\n                    alignItems={'center'}\n                  >\n                    {investmentStatus === sdk.LABEL_INVESTMENT_STATUS.FAILED ||\n                    investmentStatus === sdk.LABEL_INVESTMENT_STATUS.CANCELLED ? (\n                      failed\n                    ) : investmentStatus === sdk.LABEL_INVESTMENT_STATUS.PROCESSING ? (\n                      pending\n                    ) : (\n                      <Typography component={'span'} variant={'inherit'} color={statusColor}>\n                        {side}\n                      </Typography>\n                    )}\n                    &nbsp;\n                    <Typography component={'span'} color={'textPrimary'} variant={'inherit'}>\n                      {sentence}\n                    </Typography>\n                  </Typography>\n                  <Typography\n                    component={'span'}\n                    color={'textPrimary'}\n                    paddingLeft={1}\n                    variant={'body2'}\n                    display={'inline-flex'}\n                    alignItems={'center'}\n                  >\n                    APY: {apy}\n                  </Typography>\n                  <Typography\n                    component={'span'}\n                    color={'textPrimary'}\n                    paddingLeft={1 / 2}\n                    variant={'body2'}\n                    display={'inline-flex'}\n                    alignItems={'center'}\n                  >\n                    {row?.__raw__.order?.dualReinvestInfo?.isRecursive ||\n                    row?.__raw__.order?.dualReinvestInfo?.retryStatus ==\n                      sdk.DUAL_RETRY_STATUS.RETRY_SUCCESS\n                      ? t('labelDualAssetReInvestYes')\n                      : t('labelDualAssetReInvestNo')}\n                    {recursiveStatus}\n                  </Typography>\n                </Typography>\n\n                <Typography\n                  display={'flex'}\n                  flexDirection={'row'}\n                  justifyContent={'space-between'}\n                  variant={'body2'}\n                >\n                  <Typography component={'span'} color={'textSecondary'} variant={'body2'}>\n                    {base + '/' + quote}\n                  </Typography>\n                  <Typography component={'span'} variant={'body2'} paddingLeft={1}>\n                    {` ${t('labelDualTxsSettlement')}:                  \n                    ${\n                      deliveryPrice\n                        ? getValuePrecisionThousand(\n                            deliveryPrice,\n                            tokenMap[quote]?.precision,\n                            tokenMap[quote]?.precision,\n                            tokenMap[quote]?.precision,\n                            true,\n                            { isFait: true },\n                          )\n                        : EmptyValueTag\n                    }\n                    (${t('labelDualTPrice')} : ${row?.strike})\n                    ${moment(new Date(row.__raw__.order.timeOrigin.expireTime)).format(\n                      `${DAY_FORMAT} ${MINUTE_FORMAT}`,\n                    )}\n                    `}\n                  </Typography>\n                </Typography>\n              </Box>\n            )\n          },\n        },\n      ],\n      [t, tokenMap, idIndex],\n    )\n\n    // const [isDropDown, setIsDropDown] = React.useState(true);\n\n    const defaultArgs: any = {\n      columnMode: isMobile ? getColumnMobileTransaction() : getColumnModeTransaction(),\n      generateRows: (rawData: any) => rawData,\n      generateColumns: ({ columnsRaw }: any) => columnsRaw as Column<any, unknown>[],\n    }\n    React.useEffect(() => {\n      if (dualMarketMap) {\n        updateData.cancel()\n        updateData({ currPage: 1 })\n      }\n      return () => {\n        updateData.cancel()\n      }\n    }, [pagination?.pageSize, dualMarketMap])\n\n    return (\n      <TableStyled isMobile={isMobile}>\n        <Table\n          {...{\n            ...defaultArgs,\n            ...props,\n            rawData,\n            showloading,\n          }}\n        />\n        {pagination && (\n          <TablePagination\n            page={page}\n            pageSize={pagination.pageSize}\n            total={pagination.total}\n            onPageChange={handlePageChange}\n          />\n        )}\n      </TableStyled>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/dualTxsTable/Interface.ts",
    "content": "import {\n  DualCurrentPrice,\n  DualViewOrder,\n  RowConfig,\n  RowConfigType,\n} from '@loopring-web/common-resources'\nimport { DualDetailType } from '../../tradePanel'\n\nexport type RawDataDualTxsItem = DualViewOrder & {\n  amount: string\n}\n\nexport type RawDataDualAssetItem = DualViewOrder & {\n  amount: string\n  currentPrice: DualCurrentPrice\n}\n\nexport interface DualAssetTableProps<R> {\n  rawData: R[]\n  getDetail: (item: R) => DualDetailType\n  dualMarketMap: any\n  idIndex: { [key: string]: string }\n  tokenMap: { [key: string]: any }\n  showloading: boolean\n  getDualAssetList: (props: any) => Promise<void>\n  showDetail: (item: R) => void\n  cancelReInvest: (item: R) => void\n  refresh: (item: R) => void\n  hideAssets?: boolean\n  pagination?: {\n    pageSize: number\n    total: number\n  }\n  getProduct: (item: R) => void\n  rowConfig?: typeof RowConfig\n  noMinHeight?: boolean\n}\n\nexport interface DualTxsTableProps<R = RawDataDualTxsItem> {\n  rawData: R[]\n  pagination?: {\n    pageSize: number\n    total: number\n  }\n  idIndex: { [key: string]: string }\n  tokenMap: { [key: string]: any }\n  dualMarketMap: any\n  getDualTxList: (props: any) => Promise<void>\n  showloading: boolean\n}\n\nexport enum LABEL_INVESTMENT_STATUS_MAP {\n  INVESTMENT_RECEIVED = 'labelInvestmentStatusSettled',\n  DELIVERING = 'labelInvestmentStatusDelivering',\n  INVESTMENT_SUBSCRIBE = 'labelInvestmentStatusSubscribe',\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/dualTxsTable/index.ts",
    "content": "export * from './DualTxsTable'\nexport * from './DualAssetTable'\nexport * from './Interface'\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/index.ts",
    "content": "export * from './QuoteTable'\nexport * from './orderHistoryTable'\nexport * from './transactionsTable'\nexport * from './transactionsTable/Interface'\nexport * from './assetsTable'\nexport * from './tradeTable'\nexport * from './tradeRroTable'\nexport * from './poolsTable'\nexport * from './ammRecordTable'\nexport * from './myPoolTable'\nexport * from './ammTable'\nexport * from './tradeRaceTable'\nexport * from './nftTable'\nexport * from './investOverviewTable'\nexport * from './defiTxsTable'\nexport * from './tradeNFTTable'\nexport * from './dualTxsTable'\nexport * from './dualTable'\nexport * from './tradeRaceTable'\nexport * from './redPacketTable'\nexport * from './btradeSwapTable'\nexport * from './rewardTable'\nexport * from './vaultTable'\nexport { TaikoTarmingTxRecordsTable } from './taikoFarmingTable'\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/investOverviewTable/Interface.ts",
    "content": "import { CoinInfo, InvestItem, RowConfig } from '@loopring-web/common-resources'\nimport { TokenInfo, XOR } from '@loopring-web/loopring-sdk'\n\nexport type DepartmentRow = Required<InvestItem & { token: TokenInfo; coinInfo: CoinInfo<any> }>\nexport type RowInvest = DepartmentRow & {\n  isExpanded?: boolean\n  children?: InvestItem[]\n}\n\nexport enum SubRowAction {\n  ToggleSubRow = 'toggleSubRow',\n  UpdateRaw = 'updateRaw',\n  SortRow = 'sortRow',\n}\n\nexport interface InvestRowAction<R = DepartmentRow> {\n  type: SubRowAction\n  symbol?: string\n  sortColumn?: string\n  _des?: 'DESC' | 'ASC' | undefined\n  rows?: R[]\n}\n\ntype FilterExtend = {\n  showFilter: boolean\n  filterValue: string\n  getFilteredData: (filterValue: string) => void\n}\nexport type InvestOverviewTableProps<R = DepartmentRow> = {\n  rawData: R[]\n  wait?: number\n  coinJson: any\n  showLoading?: boolean\n  rowConfig?: typeof RowConfig\n} & XOR<FilterExtend, {}>\n\nexport enum ColumnKey {\n  TYPE = 'TYPE',\n  APR = 'APR',\n  DURATION = 'DURATION',\n  ACTION = 'ACTION',\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/investOverviewTable/InvestOverviewTable.tsx",
    "content": "import React from 'react'\nimport { useTranslation } from 'react-i18next'\n\nimport { Button, CoinIcon, Column, Table } from '../../basic-lib'\nimport {\n  EmptyValueTag,\n  getValuePrecisionThousand,\n  InvestAssetRouter,\n  InvestDuration,\n  InvestMapType,\n  RouterPath,\n  RowConfig,\n  TokenType,\n} from '@loopring-web/common-resources'\nimport { Box, BoxProps, Link, Typography } from '@mui/material'\nimport { ColumnKey, InvestOverviewTableProps, RowInvest, SubRowAction } from './Interface'\nimport styled from '@emotion/styled'\nimport { useHistory } from 'react-router-dom'\nimport { TokenInfo } from '@loopring-web/loopring-sdk'\nimport { TableFilterStyled, TablePaddingX } from '../../styled'\nimport { investRowReducer } from './components/expends'\nimport { Filter } from './components/Filter'\nimport { DropdownIconStyled } from '../../tradePanel'\nimport { useSettings } from '../../../stores'\nimport { InvestColumnKey } from './index'\nimport { ColumnCoinDeep } from '../assetsTable'\n\nconst TableStyled = styled(Box)<{ isMobile?: boolean; hasContent?: boolean } & BoxProps>`\n  & .rdg.rdg {\n    ${({ hasContent }) => (hasContent ? `min-height:initial;` : ``)}\n    // border-radius: ${({ theme }) => theme.unit}px;\n\n    ${({ isMobile }) =>\n      !isMobile\n        ? `--template-columns: 320px auto auto 124px !important;`\n        : ` --template-columns: 46% auto auto !important;\n`}\n    .rdg-cell.action {\n      display: flex;\n      justify-content: flex-end;\n      align-items: center;\n    }\n    & > .rdg-row {\n      border-top: 1px solid var(--color-box-hover);\n    }\n\n    & > .rdg-row.child_row {\n      border-top: none;\n      .rdg-cell:first-of-type {\n        margin-left: ${({ theme }) => 2 * theme.unit}px;\n      }\n      &:hover {\n        background-color: transparent;\n      }\n    }\n    & > .rdg-row.child_row:first-of-type {\n      border-top: 0px solid var(--color-box-hover);\n    }\n    .rdg-row.expends {\n      background-color: var(--color-pop-bg);\n    }\n  }\n\n  .textAlignRight {\n    text-align: right;\n\n    .rdg-header-sort-cell {\n      justify-content: flex-end;\n    }\n  }\n\n  ${({ theme }) => TablePaddingX({ pLeft: theme.unit * 3, pRight: theme.unit * 3 })}\n` as (props: { isMobile?: boolean; hasContent?: boolean } & BoxProps) => JSX.Element\n\nexport const InvestOverviewTable = <R extends RowInvest>({\n  rawData,\n  wait,\n  coinJson,\n  filterValue,\n  getFilteredData,\n  showLoading,\n  showFilter,\n  rowConfig = RowConfig,\n  ...rest\n}: InvestOverviewTableProps<R>) => {\n  const { t, i18n } = useTranslation(['tables', 'common'])\n  const [rows, dispatch] = React.useReducer(investRowReducer, rawData)\n  const history = useHistory()\n\n  React.useEffect(() => {\n    if (rawData.length) {\n      dispatch({\n        rows: rawData,\n        type: SubRowAction.UpdateRaw,\n      })\n    }\n  }, [rawData])\n\n  // myLog(\"Overview\", rows);\n  const handleFilterChange = React.useCallback(\n    ({ searchValue }: any) => {\n      if (getFilteredData) {\n        getFilteredData(searchValue)\n      }\n    },\n    [getFilteredData],\n  )\n  const tableHeight = React.useMemo(() => {\n    return rows.length > 0 ? (rows.length + 1) * rowConfig.rowHeight : 350\n  }, [rows.length, rowConfig])\n  const [isDropDown, setIsDropDown] = React.useState(true)\n\n  const getColumnMode = (): Column<R, unknown>[] => [\n    {\n      key: ColumnKey.TYPE,\n      sortable: false,\n      name: t('labelToken'),\n      formatter: ({ row }) => {\n        switch (row.type) {\n          case InvestMapType.Token:\n            const token = row.coinInfo\n            return <ColumnCoinDeep token={{ ...token, type: TokenType.single }} />\n          default:\n            return (\n              <Typography\n                variant={'inherit'}\n                color={'textPrimary'}\n                display={'inline-flex'}\n                flexDirection={'column'}\n                marginLeft={2}\n                component={'span'}\n                paddingRight={1}\n              >\n                <Typography component={'span'} className={'next-type'}>\n                  {t(row.i18nKey, { ns: 'common' })}\n                </Typography>\n              </Typography>\n            )\n        }\n      },\n    },\n    {\n      key: ColumnKey.APR,\n      sortable: false,\n      name: t('labelAPR'),\n      width: 'auto',\n      maxWidth: 80,\n      cellClass: 'textAlignLeft',\n      headerCellClass: 'textAlignLeftSortable',\n      formatter: ({ row }) => {\n        const [start, end] = row.apr\n        // myLog(\"end\", end);\n        return (\n          <Box className={'textAlignLeft'}>\n            <Typography component={'span'}>\n              {end === 0 && start === 0\n                ? EmptyValueTag\n                : start === end\n                ? getValuePrecisionThousand(end, 2, 2, 2, true) + '%'\n                : end === 0 || start === 0\n                ? getValuePrecisionThousand(end ? end : start, 2, 2, 2, true) + '%'\n                : getValuePrecisionThousand(start, 2, 2, 2, true) +\n                  '% - ' +\n                  getValuePrecisionThousand(end, 2, 2, 2, true) +\n                  '%'}\n            </Typography>\n          </Box>\n        )\n      },\n    },\n    {\n      key: ColumnKey.DURATION,\n      sortable: false,\n      width: 'auto',\n      cellClass: 'textAlignCenter',\n      headerCellClass: 'textAlignCenter',\n      name: t('labelDuration'),\n      formatter: ({ row }) => {\n        const label = (row.duration ?? '').split('|')\n        return (\n          <Box height={'100%'} display={'flex'} justifyContent={'center'} alignItems={'center'}>\n            <Typography component={'span'}>\n              {row.durationType === InvestDuration.Duration\n                ? `${t(label[0], { ns: 'common', arg: label[1] })}`\n                : t('labelInvest' + row.durationType, { ns: 'common' })}\n            </Typography>\n          </Box>\n        )\n        // ${t(\"labelDay\", {\n        //             ns: \"common\",\n        //           })}\n      },\n    },\n    {\n      key: ColumnKey.ACTION,\n      name: t('labelActions'),\n      headerCellClass: 'textAlignRight',\n      cellClass: 'action',\n      formatter: ({ row }) => {\n        switch (row.type) {\n          case InvestMapType.Token:\n            return (\n              <Typography\n                variant={'inherit'}\n                display={'inline-flex'}\n                justifyContent={'flex-end'}\n                alignItems={'center'}\n                className={'textAlignRight'}\n                width={'100%'}\n                sx={{ cursor: 'pointer' }}\n              >\n                <DropdownIconStyled status={row.isExpanded ? 'up' : 'down'} fontSize={'medium'} />\n              </Typography>\n            )\n          default:\n            return (\n              <Typography\n                variant={'inherit'}\n                color={'textPrimary'}\n                display={'inline-flex'}\n                flexDirection={'column'}\n                className={'textAlignRight'}\n                component={'span'}\n              >\n                <Button\n                  variant={'outlined'}\n                  size={'medium'}\n                  onClick={(_e) => {\n                    switch (row.type) {\n                      case InvestMapType.AMM:\n                        history.push(\n                          `${RouterPath.invest}/${InvestAssetRouter.AMM}?search=${row.token.symbol}`,\n                        )\n                        return\n                      case InvestMapType.STAKE:\n                        history.push(\n                          `${RouterPath.invest}/${InvestAssetRouter.STAKE}/${row.token.symbol}-null/invest`,\n                        )\n                        return\n                      case InvestMapType.DUAL:\n                        history.push(\n                          `${RouterPath.invest}/${InvestAssetRouter.DUAL}/${row.token.symbol}-null`,\n                        )\n                        return\n                      case InvestMapType.STAKELRC:\n                        history.push(\n                          `${RouterPath.invest}/${InvestAssetRouter.STAKELRC}/${row.token.symbol}-null`,\n                        )\n                        return\n                      case InvestMapType.LEVERAGEETH:\n                        history.push(`${RouterPath.invest}/${InvestAssetRouter.LEVERAGEETH}`)\n                        return\n                    }\n                  }}\n                >\n                  {t('labelInvestBtn', { ns: 'common' })}\n                </Button>\n              </Typography>\n            )\n        }\n      },\n    },\n  ]\n  const getColumnMobileMode = (): Column<R, unknown>[] => [\n    {\n      key: ColumnKey.TYPE,\n      sortable: false,\n      name: t('labelToken'),\n      formatter: ({ row }) => {\n        switch (row.type) {\n          case InvestMapType.Token:\n            const token: TokenInfo = row.token\n            return (\n              <Box display={'flex'} flexDirection={'row'} alignItems={'center'} height={'100%'}>\n                {token?.symbol && <CoinIcon symbol={token?.symbol} />}\n                <Typography component={'span'} className={'next-coin'}>\n                  {token?.symbol}\n                </Typography>\n                <Typography\n                  marginLeft={1}\n                  component={'span'}\n                  className={'next-company'}\n                  color={'textSecondary'}\n                >\n                  {token?.name}\n                </Typography>\n              </Box>\n            )\n          default:\n            return (\n              <Typography\n                variant={'inherit'}\n                color={'textPrimary'}\n                display={'inline-flex'}\n                flexDirection={'column'}\n                marginLeft={2}\n                component={'span'}\n                paddingRight={1}\n              >\n                <Typography component={'span'} className={'next-type'}>\n                  {t(row.i18nKey, { ns: 'common' })}\n                </Typography>\n              </Typography>\n            )\n        }\n      },\n    },\n    {\n      key: ColumnKey.APR,\n      sortable: false,\n      name: t('labelAPR'),\n      width: 'auto',\n      maxWidth: 80,\n      cellClass: 'textAlignLeft',\n      headerCellClass: 'textAlignLeftSortable',\n      formatter: ({ row }) => {\n        const [start, end] = row.apr\n        // myLog(\"end\", end);\n        return (\n          <Box className={'textAlignLeft'}>\n            <Typography component={'span'}>\n              {end === 0 && start === 0\n                ? EmptyValueTag\n                : start === end\n                ? getValuePrecisionThousand(end, 2, 2, 2, true) + '%'\n                : end === 0 || start === 0\n                ? getValuePrecisionThousand(end ? end : start, 2, 2, 2, true) + '%'\n                : getValuePrecisionThousand(start, 2, 2, 2, true) +\n                  '% - ' +\n                  getValuePrecisionThousand(end, 2, 2, 2, true) +\n                  '%'}\n            </Typography>\n          </Box>\n        )\n      },\n    },\n    {\n      key: ColumnKey.DURATION,\n      sortable: false,\n      width: 'auto',\n      cellClass: 'textAlignCenter',\n      headerCellClass: 'textAlignCenter',\n      name: t('labelDuration'),\n      formatter: ({ row }) => {\n        const label = (row.duration ?? '').split('|')\n        return (\n          <Box height={'100%'} display={'flex'} justifyContent={'center'} alignItems={'center'}>\n            <Typography component={'span'}>\n              {row.durationType === InvestDuration.Duration\n                ? `${t(label[0], { ns: 'common', arg: label[1] })}`\n                : t('labelInvest' + row.durationType, { ns: 'common' })}\n            </Typography>\n          </Box>\n        )\n        // ${t(\"labelDay\", {\n        //             ns: \"common\",\n        //           })}\n      },\n    },\n  ]\n  const { isMobile } = useSettings()\n\n  return (\n    <TableStyled isMobile={isMobile} hasContent={rows?.length > 0 ? true : false}>\n      {showFilter &&\n        (isMobile && isDropDown ? (\n          <Link\n            variant={'body1'}\n            display={'inline-flex'}\n            width={'100%'}\n            justifyContent={'flex-end'}\n            paddingRight={2}\n            onClick={() => setIsDropDown(false)}\n          >\n            {t('labelShowFilter')}\n          </Link>\n        ) : (\n          <Box\n            display={'flex'}\n            flexDirection={'row'}\n            justifyContent={'space-between'}\n            marginLeft={3}\n          >\n            <Typography fontSize={'36px'} variant={isMobile ? 'h3' : 'h1'}>\n              {t('labelTitleOverviewAllPrd', { ns: 'common' })}\n            </Typography>\n            <TableFilterStyled>\n              <Filter\n                {...{\n                  handleFilterChange,\n                  searchValue: filterValue,\n                  // hideSmallBalances,\n                  // setHideSmallBalances,\n                }}\n              />\n            </TableFilterStyled>\n          </Box>\n        ))}\n\n      <Table\n        i18n={i18n}\n        tReady={true}\n        {...{ ...rest, t }}\n        // rowGrouper={_.groupBy}\n        rowClassFn={(row) => {\n          if (\n            row.type !== InvestMapType.Token\n            // row.type === InvestMapType.STAKE ||\n            // row.type === InvestMapType.AMM  || row.type === InvestMapType.AMM\n          ) {\n            return 'child_row'\n          }\n          if (row.isExpanded) {\n            return 'expends'\n          }\n\n          return ''\n        }}\n        onRowClick={(_, row) => {\n          if (row.children) {\n            dispatch({\n              symbol: row.token.symbol,\n              type: SubRowAction.ToggleSubRow,\n            })\n          }\n        }}\n        style={{ height: tableHeight }}\n        rowHeight={rowConfig.rowHeight}\n        headerRowHeight={rowConfig.rowHeaderHeight}\n        rawData={rows}\n        // sortMethod={sortMethod}\n        generateRows={(rowData: any) => rowData}\n        generateColumns={({ columnsRaw }: any) => columnsRaw as Column<any, unknown>[]}\n        sortDefaultKey={InvestColumnKey.APR}\n        columnMode={isMobile ? getColumnMobileMode() : getColumnMode()}\n      />\n    </TableStyled>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/investOverviewTable/components/Filter.tsx",
    "content": "import { Grid } from '@mui/material'\nimport { withTranslation, WithTranslation } from 'react-i18next'\nimport { InputSearch } from '../../../'\n\nexport interface FilterProps {\n  // hideInvestToken: boolean;\n  // hideSmallBalances: boolean;\n  // setHideLpToken: (value: boolean) => void;\n  // setHideSmallBalances: (value: boolean) => void;\n  searchValue: string\n  handleFilterChange: (props: { searchValue: string }) => void\n}\n\nexport enum CheckboxType {\n  smallBalance = 'smallBalance',\n  invest = 'invest',\n}\n\nexport const Filter = withTranslation('tables', { withRef: true })(\n  ({\n    // t,\n    handleFilterChange,\n    searchValue,\n  }: // hideInvestToken,\n  // hideSmallBalances,\n  // // setHideLpToken,\n  // setHideSmallBalances,\n  FilterProps & WithTranslation) => {\n    // myLog(searchValue, \"searchValue\");\n\n    return (\n      <Grid container spacing={4} justifyContent={'space-between'}>\n        <Grid item>\n          <InputSearch\n            value={searchValue}\n            onChange={(value: any) => {\n              handleFilterChange({ searchValue: value })\n            }}\n          />\n        </Grid>\n      </Grid>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/investOverviewTable/components/expends.tsx",
    "content": "import { DepartmentRow, InvestRowAction, RowInvest, SubRowAction } from '../Interface'\nimport { InvestColumnKey } from '../index'\n\nfunction toggleSubRow(rows: RowInvest[], symbol?: string): RowInvest[] {\n  if (rows.length) {\n    let rowIndex = rows.findIndex((r) => r?.token?.symbol === symbol)\n    if (rowIndex === -1) {\n      rowIndex = 0\n    }\n    const row = rows[rowIndex]\n    const { children } = row\n    if (!children) return rows\n\n    const newRows = [...rows]\n    newRows[rowIndex] = { ...row, isExpanded: !row.isExpanded }\n    if (!row.isExpanded) {\n      // @ts-ignore\n      newRows.splice(rowIndex + 1, 0, ...children)\n    } else {\n      newRows.splice(rowIndex + 1, children.length)\n    }\n    return newRows\n  } else {\n    return []\n  }\n}\n\nfunction updateRow(_oldRows: RowInvest[], rows: RowInvest[]): RowInvest[] {\n  return [...rows]\n}\n\nexport const sortMethod = (\n  sortedRows: any[],\n  sortColumn: string,\n  _des: 'DESC' | 'ASC' | undefined,\n) => {\n  let _rawData = [...sortedRows]\n\n  switch (sortColumn) {\n    case InvestColumnKey.TYPE:\n      _rawData = sortedRows.sort((a, b) => {\n        const valueA = a.token.symbol\n        const valueB = b.token.symbol\n        return valueB.localeCompare(valueA)\n      })\n      break\n    case InvestColumnKey.APR:\n      _rawData = sortedRows.sort((a, b) => {\n        return Number(b.apr[1] ?? 0) - Number(a.apr[1] ?? 0)\n        // myLog(\"a.apr[1]\", a.apr[1]);\n      })\n      break\n    default:\n      break\n  }\n  // resetTableData(_rawData)\n  return _rawData\n}\n\nexport function investRowReducer(\n  _rows: DepartmentRow[],\n  { type, symbol, rows, sortColumn, _des }: InvestRowAction | any,\n): DepartmentRow[] {\n  switch (type) {\n    case SubRowAction.ToggleSubRow:\n      return toggleSubRow(_rows, symbol)\n    case SubRowAction.UpdateRaw:\n      return updateRow(_rows, rows ?? [])\n    case SubRowAction.SortRow:\n      return sortMethod(_rows, sortColumn, _des)\n    // case \"deleteSubRow\":\n    //   return deleteSubRow(rows, id);\n    default:\n      return _rows\n  }\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/investOverviewTable/index.ts",
    "content": "import {\n  ColumnKey as InvestColumnKey,\n  DepartmentRow,\n  InvestOverviewTableProps,\n  RowInvest,\n} from './Interface'\n\nexport * from './InvestOverviewTable'\nexport type { InvestOverviewTableProps, RowInvest, DepartmentRow }\nexport { InvestColumnKey }\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/myPoolTable/Interface.ts",
    "content": "import {\n  Account,\n  AmmDetail,\n  CoinKey,\n  ForexMap,\n  MyAmmLP,\n  RowConfig,\n} from '@loopring-web/common-resources'\nimport { Currency, LoopringMap, TokenInfo } from '@loopring-web/loopring-sdk'\nimport { EarningsDetail } from '../rewardTable'\n\nexport type MyPoolRow<R> = MyAmmLP<R> & {\n  ammDetail: AmmDetail<R>\n}\n\nexport type Method<R> = {\n  handleWithdraw: (row: R) => void\n  handleDeposit: (row: R) => void\n  allowTrade?: any\n}\n\nexport type MyPoolTableProps<R> = {\n  rawData: R[]\n  totalAMMClaims?: {\n    detail: EarningsDetail[]\n    totalDollar: string\n  }\n  account: Account\n  title: string | (() => JSX.Element) | JSX.Element\n  totalDollar?: string | number | undefined\n  pagination?: {\n    pageSize: number\n  }\n  filter: { searchValue: string }\n  handleFilterChange: (props: { searchValue: string }) => void\n  forexMap: ForexMap<Currency>\n  idIndex: { [key: string]: string }\n  tokenMap: LoopringMap<TokenInfo & { tradePairs: Array<CoinKey<R>> }>\n  tokenPrices: { [key in keyof R]: number }\n  allowTrade?: any\n  tableHeight?: number\n  showFilter?: boolean\n  hideSmallBalances?: boolean\n  wait?: number\n  showloading?: boolean\n  currency?: Currency\n  rowConfig?: typeof RowConfig\n  setHideSmallBalances?: (value: boolean) => void\n  hideAssets?: boolean\n  totalAMMClaims?: {\n    detail: EarningsDetail[]\n    totalDollar: string\n  }\n  rewardsAPIError?: any\n  getUserRewards?: () => void\n} & Method<R>\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/myPoolTable/MyPoolTable.stories.tsx",
    "content": "import styled from '@emotion/styled'\nimport { Meta, Story } from '@storybook/react'\nimport { MemoryRouter } from 'react-router-dom'\nimport { MyPoolRow as Row, MyPoolTable } from './index'\nimport { coinMap } from '../../../static'\nimport { CoinInfo } from '@loopring-web/common-resources'\n\nconst Style = styled.div`\n  flex: 1;\n  height: 100%;\n  flex: 1;\n`\n\n// @ts-ignore\nconst rawData: Row<any>[] = [\n  {\n    feeA: 122,\n    feeB: 21,\n    feeU: 0.0012,\n    reward: 123,\n    rewardToken: coinMap['USDT'] as CoinInfo<any>,\n    feeA24: 122,\n    feeB24: 122,\n    feeU24: 0.0012,\n    reward24: 123,\n    reward224: 123,\n    rewardU24: 123,\n    extraU24: 123,\n    extraRewards24: [\n      {\n        tokenSymbol: 'LRC',\n        amount: 100,\n      },\n    ],\n    balanceA: 12131,\n    balanceB: 0.0012,\n    balanceU: 232,\n    balanceAStr: '',\n    balanceBStr: '',\n    ammDetail: {\n      coinA: 'ETH',\n      coinB: 'LRC',\n      address: '',\n      market: 'ETH-LRC',\n      coinAInfo: coinMap['ETH'] as CoinInfo<any>,\n      coinBInfo: coinMap['LRC'] as CoinInfo<any>,\n      amountU: 12,\n      totalLPToken: 12132131,\n      totalA: 0.002,\n      totalB: 12344,\n\n      APR: 56,\n      isNew: true,\n      isActivity: false,\n    },\n  },\n  {\n    feeA: 122,\n    feeB: 21,\n    feeU: 0.0012,\n    reward: 123,\n    rewardToken: coinMap['USDT'] as CoinInfo<any>,\n    feeA24: 122,\n    feeB24: 122,\n    feeU24: 0.0012,\n    reward24: 123,\n    reward224: 123,\n    rewardU24: 123,\n    extraU24: 123,\n    extraRewards24: [\n      {\n        tokenSymbol: 'LRC',\n        amount: 100,\n      },\n    ],\n    balanceA: 12131,\n    balanceB: 0.0012,\n    balanceU: 232,\n    balanceAStr: '',\n    balanceBStr: '',\n    ammDetail: {\n      coinA: 'ETH',\n      coinB: 'LRC',\n      address: '',\n      market: 'ETH-LRC',\n      coinAInfo: coinMap['ETH'] as CoinInfo<any>,\n      coinBInfo: coinMap['LRC'] as CoinInfo<any>,\n      totalLPToken: 12132131,\n      totalA: 0.002,\n      totalB: 12344,\n\n      APR: 56,\n      isNew: true,\n      isActivity: false,\n    },\n  },\n  {\n    feeA: 122,\n    feeB: 21,\n    feeU: 0.0012,\n    reward: 123,\n    rewardToken: coinMap['USDT'] as CoinInfo<any>,\n    feeA24: 122,\n    feeB24: 122,\n    feeU24: 0.0012,\n    reward24: 123,\n    reward224: 123,\n    rewardU24: 123,\n    extraU24: 123,\n    extraRewards24: [\n      {\n        tokenSymbol: 'LRC',\n        amount: 100,\n      },\n    ],\n    balanceA: 12131,\n    balanceB: 0.0012,\n    balanceU: 232,\n    balanceAStr: '',\n    balanceBStr: '',\n    ammDetail: {\n      coinA: 'ETH',\n      coinB: 'LRC',\n      address: '',\n      market: 'ETH-LRC',\n      coinAInfo: coinMap['ETH'] as CoinInfo<any>,\n      coinBInfo: coinMap['LRC'] as CoinInfo<any>,\n      // amountU: 12,\n      totalLPToken: 12132131,\n      totalA: 0.002,\n      totalB: 12344,\n\n      APR: 56,\n      isNew: true,\n      isActivity: false,\n    },\n  },\n]\n\nexport const Template: Story<any> = (args: any) => {\n  return (\n    <>\n      <Style>\n        <MemoryRouter initialEntries={['/']}>\n          <MyPoolTable {...args} />\n        </MemoryRouter>\n      </Style>\n    </>\n  )\n}\n\nTemplate.bind({})\n\nTemplate.args = {\n  rawData: rawData,\n  pagination: {\n    pageSize: 5,\n  },\n}\n\nexport default {\n  title: 'components/TableList/MyPoolTable',\n  component: MyPoolTable,\n  argTypes: {},\n} as Meta\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/myPoolTable/MyPoolTable.tsx",
    "content": "import React from 'react'\nimport { Box, BoxProps, Grid, Tooltip, Typography } from '@mui/material'\nimport { withTranslation, WithTranslation } from 'react-i18next'\nimport { Button, Popover, PopoverPure, PopoverType, PopoverWrapProps } from '../../basic-lib'\nimport { Column, Table } from '../../basic-lib/'\nimport {\n  AssetTabIndex,\n  CurrencyToTag,\n  EmptyValueTag,\n  getValuePrecisionThousand,\n  HiddenTag,\n  MoreIcon,\n  PriceTag,\n  RowConfig,\n  TokenType,\n  RouterPath,\n} from '@loopring-web/common-resources'\nimport { MyPoolRow, MyPoolTableProps } from './Interface'\nimport styled from '@emotion/styled'\nimport { TableFilterStyled, TablePaddingX } from '../../styled'\nimport { bindPopper, usePopupState } from 'material-ui-popup-state/hooks'\nimport { bindHover } from 'material-ui-popup-state/es'\nimport { useSettings } from '../../../stores'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { Filter } from './components/Filter'\nimport { AmmAPRDetail, AmmPairDetail, AmmRewardsDetail } from '../../block'\nimport { ActionPopContent, DetailRewardPanel } from './components/ActionPop'\nimport { CoinIcons } from '../assetsTable'\nimport { useHistory } from 'react-router-dom'\n\nconst TableStyled = styled(Box)<BoxProps & { isMobile?: boolean }>`\n  .rdg {\n    ${({ isMobile }) =>\n      !isMobile\n        ? `--template-columns: 200px 80px auto auto 200px !important;`\n        : `--template-columns: 16% 60% auto 8% !important;`}\n    height: calc(86px * 5 + var(--header-row-height));\n\n    .rdg-cell.action {\n      display: flex;\n      justify-content: center;\n      align-items: center;\n    }\n  }\n\n  .textAlignRight {\n    text-align: right;\n  }\n\n  .textAlignRightSortable {\n    display: flex;\n    justify-content: flex-end;\n  }\n\n  ${({ theme }) => TablePaddingX({ pLeft: theme.unit * 3, pRight: theme.unit * 3 })}\n  .assetWrap & {\n    .titleSummary.mobile {\n      margin-top: ${({ theme }) => theme.unit * 5}px;\n      flex-direction: row;\n    }\n  }\n\n  .titleSummary.mobile {\n    flex-direction: row;\n  }\n` as (props: { isMobile?: boolean } & BoxProps) => JSX.Element\n\nconst PoolStyle = styled(Box)`\n  &.MuiTypography-body1 {\n    font-size: ${({ theme }) => theme.fontDefault.body1};\n  }\n\n  .MuiButton-root:not(:first-of-type) {\n    margin-left: ${({ theme }) => theme.unit}px;\n  }\n` as typeof Box\n\nexport const MyPoolTable = withTranslation('tables')(\n  <R extends MyPoolRow<{ [key: string]: any }>>({\n    t,\n    i18n,\n    tReady,\n    allowTrade,\n    handleFilterChange,\n    filter,\n    totalDollar,\n    showFilter = true,\n    rawData,\n    title,\n    totalAMMClaims,\n    handleWithdraw,\n    handleDeposit,\n    hideSmallBalances = false,\n    setHideSmallBalances,\n    currency = CurrencyToTag.USD,\n    showloading,\n    tableHeight,\n    tokenMap,\n    forexMap,\n    rowConfig = RowConfig,\n    hideAssets,\n    rewardsAPIError,\n    getUserRewards,\n  }: MyPoolTableProps<R> & WithTranslation) => {\n    const { isMobile, coinJson } = useSettings()\n    const history = useHistory()\n\n    const getPopoverState = React.useCallback((label: string) => {\n      return usePopupState({\n        variant: 'popover',\n        popupId: `popup-poolsLiq-${label}`,\n      })\n    }, [])\n    const getPopoverRewardState = React.useCallback((label: string) => {\n      return usePopupState({\n        variant: 'popover',\n        popupId: `popup-poolsReward-${label}`,\n      })\n    }, [])\n    const getPopoverAprState = React.useCallback((label: string) => {\n      return usePopupState({\n        variant: 'popover',\n        popupId: `popup-poolsApr-${label}`,\n      })\n    }, [])\n    const columnMode = (): Column<R, unknown>[] => {\n      return [\n        {\n          key: 'pools',\n          sortable: false,\n          width: 'auto',\n          minWidth: 240,\n          name: t('labelPool'),\n          formatter: ({ row }) => {\n            return (\n              <PoolStyle\n                display={'flex'}\n                flexDirection={'row'}\n                alignItems={'center'}\n                justifyContent={'flex-start'}\n                height={'100%'}\n              >\n                <CoinIcons\n                  type={TokenType.lp}\n                  tokenIcon={[coinJson[row.ammDetail?.coinA], coinJson[row.ammDetail?.coinB]]}\n                />\n                <Typography\n                  variant={'inherit'}\n                  color={'textPrimary'}\n                  display={'flex'}\n                  flexDirection={'column'}\n                  marginLeft={2}\n                  component={'span'}\n                  paddingRight={1}\n                >\n                  <Typography component={'span'} className={'next-coin'}>\n                    <Typography variant='inherit' component={'span'} className={'next-coin'}>\n                      {row.ammDetail?.coinAInfo?.simpleName}\n                    </Typography>\n                    <Typography variant='inherit' component={'i'}>\n                      /\n                    </Typography>\n                    <Typography variant='inherit' component={'span'} title={'buy'}>\n                      {row.ammDetail?.coinBInfo?.simpleName}\n                    </Typography>\n                  </Typography>\n                </Typography>\n              </PoolStyle>\n            )\n          },\n        },\n        {\n          key: 'APR',\n          sortable: true,\n          name: t('labelAPR'),\n          width: 'auto',\n          maxWidth: 80,\n          headerCellClass: 'textAlignRightSortable',\n          formatter: ({ row, rowIdx }) => {\n            const APR =\n              typeof row?.ammDetail?.APR !== undefined && row?.ammDetail?.APR\n                ? row.ammDetail.APR\n                : EmptyValueTag\n            const popoverState = getPopoverAprState(rowIdx.toString())\n            return (\n              <Box className={'textAlignRight'}>\n                <Typography\n                  component={'span'}\n                  style={\n                    APR === 0 || typeof APR === 'undefined' || APR == EmptyValueTag\n                      ? {}\n                      : {\n                          cursor: 'pointer',\n                          textDecoration: 'underline dotted',\n                        }\n                  }\n                  {...bindHover(popoverState)}\n                >\n                  {APR === 0 || typeof APR === 'undefined' || APR == EmptyValueTag\n                    ? EmptyValueTag\n                    : getValuePrecisionThousand(APR, 2, 2, 2, true) + '%'}\n                </Typography>\n                {!(APR === 0 || typeof APR === 'undefined' || APR == EmptyValueTag) && (\n                  <PopoverPure\n                    className={'arrow-top-center'}\n                    {...bindPopper(popoverState)}\n                    anchorOrigin={{\n                      vertical: 'top',\n                      horizontal: 'center',\n                    }}\n                    transformOrigin={{\n                      vertical: 'bottom',\n                      horizontal: 'center',\n                    }}\n                  >\n                    <AmmAPRDetail {...row?.ammDetail?.APRs} />\n                  </PopoverPure>\n                )}\n              </Box>\n            )\n          },\n        },\n        {\n          key: 'liquidity',\n          sortable: true,\n          width: 'auto',\n          headerCellClass: 'textAlignRightSortable',\n          name: t('labelMyLiquidity'),\n          formatter: ({ row, rowIdx }) => {\n            const popState = getPopoverState(rowIdx.toString())\n            if (!row || !row.ammDetail) {\n              return <Box display={'flex'} justifyContent={'flex-end'} alignItems={'center'} />\n            }\n            const {\n              // totalAmmValueDollar,\n              balanceU,\n              balanceA,\n              balanceB,\n              ammDetail: { coinAInfo, coinBInfo },\n            } = row as any\n            // const coinAIcon: any = coinJson[coinAInfo.simpleName];\n            // const coinBIcon: any = coinJson[coinBInfo.simpleName];\n            return (\n              <Box\n                height={'100%'}\n                display={'flex'}\n                justifyContent={'flex-end'}\n                alignItems={'center'}\n              >\n                <Box {...bindHover(popState)}>\n                  <Typography\n                    component={'span'}\n                    style={{\n                      cursor: 'pointer',\n                      textDecoration: 'underline dotted',\n                    }}\n                  >\n                    {typeof balanceU === 'undefined'\n                      ? EmptyValueTag\n                      : hideAssets\n                      ? HiddenTag\n                      : PriceTag[CurrencyToTag[currency]] +\n                        getValuePrecisionThousand(\n                          (balanceU || 0) * (forexMap[currency] ?? 0),\n                          undefined,\n                          undefined,\n                          2,\n                          true,\n                          { isFait: true, floor: true },\n                        )}\n                  </Typography>\n                </Box>\n                <PopoverPure\n                  className={'arrow-top-center'}\n                  {...bindPopper(popState)}\n                  anchorOrigin={{\n                    vertical: 'top',\n                    horizontal: 'center',\n                  }}\n                  transformOrigin={{\n                    vertical: 'bottom',\n                    horizontal: 'center',\n                  }}\n                >\n                  <AmmPairDetail\n                    coinA={coinAInfo?.simpleName}\n                    coinB={coinBInfo?.simpleName}\n                    balanceA={balanceA}\n                    balanceB={balanceB}\n                  />\n                </PopoverPure>\n              </Box>\n            )\n          },\n        },\n        {\n          key: 'rewards',\n          name: t('label24Rewards'),\n          headerCellClass: 'textAlignRight',\n          formatter: ({ row, rowIdx }) => {\n            const {\n              rewardToken,\n              rewardToken2,\n              reward24,\n              reward224,\n              extraRewards24,\n              ammDetail: { coinAInfo, coinBInfo },\n            } = row\n            let dollarReward24 = 0\n            const popState = getPopoverRewardState(rowIdx.toString())\n            if (!(typeof row.rewardU24 === 'undefined' || row.rewardU24 === 0)) {\n              dollarReward24 += row.rewardU24\n            }\n            if (!(typeof row.feeU24 === 'undefined' || row.feeU24 === 0)) {\n              dollarReward24 += row.feeU24\n            }\n            if (!(typeof row.extraU24 === 'undefined' || row.extraU24 === 0)) {\n              dollarReward24 += row.extraU24\n              // dollarReward24 += row.feeU24;\n            }\n            return (\n              <Box className={'textAlignRight'} height={'100%'}>\n                <Typography\n                  component={'span'}\n                  style={\n                    dollarReward24 === 0\n                      ? {}\n                      : {\n                          cursor: 'pointer',\n                          textDecoration: 'underline dotted',\n                        }\n                  }\n                  {...bindHover(popState)}\n                >\n                  {dollarReward24 === 0\n                    ? EmptyValueTag\n                    : hideAssets\n                    ? HiddenTag\n                    : PriceTag[CurrencyToTag[currency]] +\n                      getValuePrecisionThousand(\n                        (dollarReward24 || 0) * (forexMap[currency] ?? 0),\n                        undefined,\n                        undefined,\n                        2,\n                        true,\n                        { isFait: true, floor: true },\n                      )}\n                </Typography>\n                <PopoverPure\n                  className={'arrow-top-center'}\n                  {...bindPopper(popState)}\n                  anchorOrigin={{\n                    vertical: 'top',\n                    horizontal: 'center',\n                  }}\n                  transformOrigin={{\n                    vertical: 'bottom',\n                    horizontal: 'center',\n                  }}\n                >\n                  {coinAInfo && (\n                    <AmmRewardsDetail\n                      feeA={row.feeA24}\n                      feeB={row.feeB24}\n                      coinA={coinAInfo.simpleName}\n                      coinB={coinBInfo.simpleName}\n                      rewards={\n                        [\n                          ...(reward24\n                            ? [\n                                {\n                                  tokenSymbol: rewardToken,\n                                  amount: reward24,\n                                },\n                              ]\n                            : []),\n                          ...(reward224\n                            ? [\n                                {\n                                  tokenSymbol: rewardToken2,\n                                  amount: reward224,\n                                },\n                              ]\n                            : []),\n                        ] as any[]\n                      }\n                      extraRewards={extraRewards24}\n                      tokenMap={tokenMap}\n                    />\n                  )}\n                </PopoverPure>\n              </Box>\n            )\n          },\n        },\n        {\n          key: 'action',\n          name: t('labelActions'),\n          headerCellClass: 'textAlignRight',\n          formatter: ({ row }) => {\n            return (\n              <PoolStyle\n                display={'flex'}\n                flexDirection={'column'}\n                alignItems={'flex-end'}\n                justifyContent={'center'}\n                height={'100%'}\n              >\n                <Box display={'flex'} marginRight={-1}>\n                  {handleDeposit && (\n                    <Button\n                      variant={'text'}\n                      size={'small'}\n                      disabled={!allowTrade?.joinAmm?.enable}\n                      onClick={() => {\n                        handleDeposit(row)\n                      }}\n                    >\n                      {t('labelPoolTableAddLiquidity')}\n                    </Button>\n                  )}\n                  {handleWithdraw && (\n                    <Button\n                      variant={'text'}\n                      size={'small'}\n                      onClick={() => {\n                        handleWithdraw(row)\n                      }}\n                    >\n                      {t('labelPoolTableRemoveLiquidity')}\n                    </Button>\n                  )}\n                </Box>\n              </PoolStyle>\n            )\n          },\n        },\n      ]\n    }\n    const columnModeMobile = (): Column<R, unknown>[] => {\n      return [\n        {\n          key: 'pools',\n          sortable: false,\n          width: 'auto',\n          name: t('labelPool'),\n          formatter: ({ row }) => {\n            return (\n              <PoolStyle\n                display={'flex'}\n                flexDirection={'column'}\n                alignContent={'flex-start'}\n                justifyContent={'center'}\n                height={'100%'}\n              >\n                <CoinIcons\n                  size={18}\n                  type={TokenType.lp}\n                  tokenIcon={[coinJson[row.ammDetail?.coinA], coinJson[row.ammDetail?.coinB]]}\n                />\n                <Typography\n                  variant={'body2'}\n                  color={'textPrimary'}\n                  display={'flex'}\n                  flexDirection={'column'}\n                  marginLeft={0}\n                  component={'span'}\n                  paddingRight={1}\n                >\n                  <Typography component={'span'} className={'next-coin'}>\n                    <Typography variant='inherit' component={'span'} className={'next-coin'}>\n                      {row.ammDetail?.coinAInfo?.simpleName}\n                    </Typography>\n                    <Typography variant='inherit' component={'i'}>\n                      /\n                    </Typography>\n                    <Typography variant='inherit' component={'span'} title={'buy'}>\n                      {row.ammDetail?.coinBInfo?.simpleName}\n                    </Typography>\n                  </Typography>\n                </Typography>\n              </PoolStyle>\n            )\n          },\n        },\n        {\n          key: 'liquidity',\n          sortable: true,\n          headerCellClass: 'textAlignRightSortable',\n          name: t('labelMyLiquidity'), //+ \"/\" + t(\"labelFeeEarned\")\n          formatter: ({ row }) => {\n            if (!row || !row.ammDetail) {\n              return <Box display={'flex'} justifyContent={'flex-end'} alignItems={'center'} />\n            }\n            const {\n              balanceU,\n              balanceA,\n              balanceB,\n              ammDetail: { coinAInfo, coinBInfo },\n            } = row as any\n\n            return (\n              <Box\n                className={'textAlignRight'}\n                display={'flex'}\n                flexDirection={'column'}\n                height={'100%'}\n                justifyContent={'center'}\n              >\n                <Typography component={'span'}>\n                  {typeof balanceU === 'undefined'\n                    ? EmptyValueTag\n                    : hideAssets\n                    ? HiddenTag\n                    : PriceTag[CurrencyToTag[currency]] +\n                      getValuePrecisionThousand(\n                        (balanceU || 0) * (forexMap[currency] ?? 0),\n                        undefined,\n                        undefined,\n                        2,\n                        true,\n                        { isFait: true, floor: true },\n                      )}\n                </Typography>\n                <Typography component={'span'} variant={'body2'} color={'textSecondary'}>\n                  {hideAssets\n                    ? HiddenTag + `  +  ` + HiddenTag\n                    : getValuePrecisionThousand(balanceA, undefined, 2, 2, true, {\n                        isAbbreviate: true,\n                        abbreviate: 3,\n                      }) +\n                      ' ' +\n                      coinAInfo?.simpleName +\n                      `  +  ` +\n                      getValuePrecisionThousand(balanceB, undefined, 2, 2, true, {\n                        isAbbreviate: true,\n                        abbreviate: 3,\n                      }) +\n                      ' ' +\n                      coinBInfo?.simpleName}\n                </Typography>\n              </Box>\n            )\n          },\n        },\n        {\n          key: 'APR',\n          sortable: true,\n          name: t('labelAPR'),\n          width: 'auto',\n          maxWidth: 80,\n          headerCellClass: 'textAlignRightSortable',\n          formatter: ({ row }) => {\n            const APR =\n              typeof row?.ammDetail?.APR !== undefined && row.ammDetail.APR\n                ? row.ammDetail.APR\n                : EmptyValueTag\n            return (\n              <Box className={'textAlignRight'}>\n                <Typography component={'span'}>\n                  {APR === EmptyValueTag || typeof APR === 'undefined'\n                    ? EmptyValueTag\n                    : getValuePrecisionThousand(APR, 2, 2, 2, true) + '%'}\n                </Typography>\n              </Box>\n            )\n          },\n        },\n        {\n          key: 'action',\n          name: '',\n          headerCellClass: 'textAlignRight',\n          formatter: ({ row }) => {\n            const popoverProps: PopoverWrapProps = {\n              type: PopoverType.click,\n              popupId: 'testPopup',\n              className: 'arrow-none',\n              children: <MoreIcon cursor={'pointer'} />,\n              popoverContent: (\n                <ActionPopContent {...{ row, allowTrade, handleWithdraw, handleDeposit, t }} />\n              ),\n              anchorOrigin: {\n                vertical: 'bottom',\n                horizontal: 'right',\n              },\n              transformOrigin: {\n                vertical: 'top',\n                horizontal: 'right',\n              },\n            } as PopoverWrapProps\n            return (\n              <Grid item marginTop={1}>\n                <Popover {...{ ...popoverProps }} />\n              </Grid>\n            )\n          },\n        },\n      ]\n    }\n\n    const nanToEmptyTag = (value: any, prefix: string) => {\n      return value === 'NaN' ? EmptyValueTag : prefix + value\n    }\n\n    return (\n      <TableStyled isMobile={isMobile} className={`${rawData?.length > 0 ? 'min-height' : ''}`}>\n        {\n          <TableFilterStyled\n            display={'flex'}\n            justifyContent={'space-between'}\n            alignItems={'center'}\n            className={`titleSummary ${isMobile ? 'mobile' : ''}`}\n            flexDirection={isMobile ? 'column' : 'row'}\n          >\n            <>{title}</>\n            {showFilter && (\n              <Filter\n                {...{\n                  handleFilterChange,\n                  filter,\n                  hideSmallBalances,\n                  setHideSmallBalances,\n                }}\n              />\n            )}\n          </TableFilterStyled>\n        }\n        <Box\n          display={'flex'}\n          flexDirection={'row'}\n          justifyContent={'space-between'}\n          alignItems={'center'}\n        >\n          {totalDollar !== undefined ? (\n            <Typography component={'h4'} variant={'h3'} marginX={3}>\n              {totalDollar\n                ? hideAssets\n                  ? HiddenTag\n                  : nanToEmptyTag(\n                      getValuePrecisionThousand(\n                        sdk.toBig(totalDollar).times(forexMap[currency] ?? 0),\n                        undefined,\n                        undefined,\n                        2,\n                        true,\n                        { isFait: true, floor: true },\n                      ),\n                      PriceTag[CurrencyToTag[currency]],\n                    )\n                : EmptyValueTag}\n            </Typography>\n          ) : (\n            ''\n          )}\n          {totalAMMClaims ? (\n            rewardsAPIError && getUserRewards ? (\n              <Button\n                sx={{ marginRight: 3 }}\n                onClick={() => {\n                  getUserRewards && getUserRewards()\n                }}\n                size={'small'}\n                variant={'outlined'}\n              >\n                {t('labelRewardRefresh', { ns: 'common' })}\n              </Button>\n            ) : (\n              <Typography\n                paddingRight={3}\n                display={'flex'}\n                flexDirection={'row'}\n                alignItems={'center'}\n              >\n                <Typography variant={'body1'} marginRight={2} component={'span'}>\n                  {t('labelAMMClaimableEarnings', { ns: 'common' })}\n                </Typography>\n\n                {totalAMMClaims.totalDollar !== '0' ? (\n                  <>\n                    <Tooltip\n                      componentsProps={{\n                        tooltip: {\n                          sx: {\n                            width: 'var(--mobile-full-panel-width)',\n                          },\n                        },\n                      }}\n                      className={'detailPanel'}\n                      title={<DetailRewardPanel detailList={totalAMMClaims.detail} />}\n                    >\n                      <Typography\n                        display={'inline-flex'}\n                        alignItems={'center'}\n                        component={'span'}\n                        color={'textPrimary'}\n                        marginRight={2}\n                        sx={{\n                          textDecoration: 'underline dotted',\n                          cursor: 'pointer',\n                        }}\n                      >\n                        {hideAssets\n                          ? HiddenTag\n                          : PriceTag[CurrencyToTag[currency]] +\n                            getValuePrecisionThousand(\n                              sdk.toBig(totalAMMClaims.totalDollar).times(forexMap[currency] ?? 0),\n                              undefined,\n                              undefined,\n                              2,\n                              true,\n                              { isFait: true, floor: true },\n                            )}\n                      </Typography>\n                    </Tooltip>\n                    <Button\n                      variant={'contained'}\n                      size={'small'}\n                      onClick={() => {\n                        history.push(`${RouterPath.l2assetsDetail}/${AssetTabIndex.Rewards}`)\n                      }}\n                    >\n                      {t('labelClaimBtn', { ns: 'common' })}\n                    </Button>\n                  </>\n                ) : (\n                  <Typography variant={'inherit'} component={'span'} color={'textPrimary'}>\n                    {EmptyValueTag}\n                  </Typography>\n                )}\n              </Typography>\n            )\n          ) : (\n            <></>\n          )}\n        </Box>\n\n        <Table\n          rowHeight={rowConfig.rowHeight}\n          headerRowHeight={rowConfig.rowHeaderHeight}\n          style={{ height: tableHeight }}\n          rawData={rawData}\n          showloading={showloading}\n          columnMode={isMobile ? columnModeMobile() : (columnMode() as any)}\n          sortDefaultKey={'liquidity'}\n          generateRows={(rawData) => rawData}\n          generateColumns={({ columnsRaw }) => columnsRaw as Column<any, any>[]}\n          sortMethod={(sortedRows: R[], sortColumn: string) => {\n            switch (sortColumn) {\n              case 'liquidity':\n                sortedRows = sortedRows.sort((a, b) => {\n                  const valueA = a.balanceU\n                  const valueB = b.balanceU\n\n                  if (valueA && valueB) {\n                    return valueB - valueA\n                  }\n                  if (valueA && !valueB) {\n                    return -1\n                  }\n                  if (!valueA && valueB) {\n                    return 1\n                  }\n                  return 0\n                })\n                break\n              case 'APR':\n                sortedRows = sortedRows.sort((a, b) => {\n                  const valueA = a.ammDetail.APR || 0\n                  const valueB = b.ammDetail.APR || 0\n                  if (valueA && valueB) {\n                    return valueB - valueA\n                  }\n                  if (valueA && !valueB) {\n                    return -1\n                  }\n                  if (!valueA && valueB) {\n                    return 1\n                  }\n                  return 0\n                })\n                break\n              default:\n                return sortedRows\n            }\n            return sortedRows\n          }}\n          {...{\n            t,\n            i18n,\n            tReady,\n          }}\n        />\n      </TableStyled>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/myPoolTable/components/ActionPop.tsx",
    "content": "import React from 'react'\nimport { Box, ListItemText, MenuItem, Typography } from '@mui/material'\nimport { useTranslation } from 'react-i18next'\nimport {\n  EmptyValueTag,\n  getValuePrecisionThousand,\n  HiddenTag,\n  myLog,\n  TokenType,\n} from '@loopring-web/common-resources'\nimport { EarningsDetail } from '../../rewardTable'\nimport styled from '@emotion/styled'\nimport { CoinIcons } from '../../assetsTable'\nimport { useSettings } from '../../../../stores'\n\nexport const ActionPopContent = React.memo(\n  ({ row, allowTrade, handleWithdraw, handleDeposit, t }: any) => {\n    return (\n      <Box borderRadius={'inherit'} minWidth={110}>\n        {allowTrade?.joinAmm?.enable && (\n          <MenuItem onClick={() => handleDeposit(row)}>\n            <ListItemText>{t('labelPoolTableAddLiquidity', { ns: 'tables' })}</ListItemText>\n          </MenuItem>\n        )}\n        <MenuItem onClick={() => handleWithdraw(row)}>\n          <ListItemText>{t('labelPoolTableRemoveLiquidity', { ns: 'tables' })}</ListItemText>\n        </MenuItem>\n      </Box>\n    )\n  },\n)\n\nconst ContentWrapperStyled = styled(Box)`\n  padding: 0 ${({ theme }) => theme.unit * 1}px;\n  border-radius: ${({ theme }) => theme.unit / 2}px;\n`\nexport const DetailRewardPanel = ({\n  detailList,\n  hideAssets = false,\n}: {\n  detailList?: EarningsDetail[]\n  hideAssets?: boolean\n}) => {\n  const { t } = useTranslation()\n  myLog('detailLis', detailList)\n  const { coinJson } = useSettings()\n\n  return (\n    <ContentWrapperStyled flexDirection={'column'} display={'flex'}>\n      <Typography\n        display={'inline-flex'}\n        alignItems={'center'}\n        component={'span'}\n        color={'textSecondary'}\n        marginBottom={1}\n      >\n        {t(`labelClaimTypePROTOCOL_FEE`)}\n      </Typography>\n      {detailList?.map((item) => {\n        if (item.amount === '0') {\n          return <React.Fragment key={item.toString()} />\n        } else {\n          return (\n            <Box\n              display={'flex'}\n              alignItems={'center'}\n              justifyContent={'space-between'}\n              flexDirection={'row'}\n              key={item.toString()}\n            >\n              <Box\n                component={'span'}\n                className={'logo-icon'}\n                display={'flex'}\n                height={'var(--list-menu-coin-size)'}\n                width={'var(--list-menu-coin-size)'}\n                alignItems={'center'}\n                justifyContent={'flex-start'}\n              >\n                <CoinIcons type={TokenType.single} tokenIcon={[coinJson[item.token]]} />\n                <Typography\n                  component={'span'}\n                  color={'var(--color-text-primary)'}\n                  variant={'body1'}\n                  marginLeft={1 / 2}\n                  height={20}\n                  lineHeight={'20px'}\n                >\n                  {item.token}\n                </Typography>\n              </Box>\n\n              <Typography\n                component={'span'}\n                color={'var(--color-text-primary)'}\n                variant={'body1'}\n                height={20}\n                marginLeft={10}\n                lineHeight={'20px'}\n              >\n                {item.amount == '0'\n                  ? EmptyValueTag\n                  : hideAssets\n                  ? HiddenTag\n                  : getValuePrecisionThousand(\n                      item.amountStr,\n                      item.precision,\n                      item.precision,\n                      undefined,\n                      false,\n                      {\n                        floor: true,\n                      },\n                    ) +\n                    ' ' +\n                    item.token}\n              </Typography>\n            </Box>\n          )\n        }\n      })}\n    </ContentWrapperStyled>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/myPoolTable/components/Filter.tsx",
    "content": "import { Box, Checkbox, FormControlLabel } from '@mui/material'\nimport { InputSearch } from '../../../basic-lib'\nimport { CheckBoxIcon, CheckedIcon } from '@loopring-web/common-resources'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport { useSettings } from '../../../../stores'\nimport { useTheme } from '@emotion/react'\n\nexport interface FilterProps {\n  hideSmallBalances: boolean\n  setHideSmallBalances?: (value: boolean) => void\n  filter: {\n    searchValue: string\n  }\n  handleFilterChange: (props: { searchValue: string }) => void\n}\n\nexport const Filter = withTranslation('tables', { withRef: true })(\n  ({\n    t,\n    handleFilterChange,\n    filter,\n    hideSmallBalances,\n    setHideSmallBalances,\n  }: FilterProps & WithTranslation) => {\n    const { isMobile } = useSettings()\n    const theme = useTheme()\n    return (\n      <Box display={'flex'} alignItems={'center'} justifyContent={'space-between'}>\n        <Box>\n          {setHideSmallBalances && (\n            <FormControlLabel\n              style={{\n                marginRight: 0,\n                paddingRight: 0,\n                fontSize: isMobile ? theme.fontDefault.body2 : theme.fontDefault.body1,\n              }}\n              control={\n                <Checkbox\n                  checked={hideSmallBalances}\n                  checkedIcon={<CheckedIcon />}\n                  icon={<CheckBoxIcon />}\n                  color='default'\n                  onChange={(event) => {\n                    setHideSmallBalances(event.target.checked)\n                  }}\n                />\n              }\n              label={t('labelHideSmallBalances')}\n            />\n          )}\n        </Box>\n\n        <Box marginLeft={2} width={isMobile ? '60%' : 'initial'}>\n          <InputSearch\n            value={filter.searchValue}\n            onChange={(value: any) => {\n              handleFilterChange({ searchValue: value })\n            }}\n          />\n        </Box>\n      </Box>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/myPoolTable/index.ts",
    "content": "export * from './MyPoolTable'\nexport * from './Interface'\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/nftTable/Interface.ts",
    "content": "// export enum TsNFTTradeTypes {\n//   deposit = \"DEPOSIT\",\n//   withdraw = \"WITHDRAW\",\n//   transfer = \"TRANSFER\",\n// }\n\nimport { UserNFTTxsHistory, UserNFTTxTypes } from '@loopring-web/loopring-sdk'\nimport { DateRange } from '@mui/lab'\n\nexport enum TsTradeStatus {\n  processing = 'processing',\n  processed = 'processed',\n  received = 'received',\n  failed = 'failed',\n}\n\nexport enum TxnDetailStatus {\n  processed = 'PROCESSED',\n  processing = 'PROCESSING',\n  received = 'RECEIVED',\n  failed = 'FAILED',\n}\n\nexport type TxnDetailProps = UserNFTTxsHistory & { metadata?: any } & {\n  time: string\n  fee: {\n    unit: string\n    value: number\n  }\n  storageInfo: {\n    accountId: number\n    storageId: number\n    tokenId: number\n  }\n  blockId: number\n  indexInBlock: number\n  memo?: string\n  createdAt: string\n  nftData: string\n  etherscanBaseUrl?: string\n}\nexport type NFTTableFilter = {\n  txType?: UserNFTTxTypes\n  limit?: number\n  duration?: DateRange<Date | string>\n  page: number\n}\n\nexport type NFTTableProps<Row> = NFTTableFilter & {\n  etherscanBaseUrl?: string\n  rawData: Row[]\n  showFilter?: boolean\n  pagination?: {\n    pageSize: number\n    total: number\n  }\n  getTxnList: (filter: NFTTableFilter) => Promise<void>\n\n  // showFilter?: boolean;\n  showloading: boolean\n  accAddress: string\n  accountId: number\n  // accAddress?: string;\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/nftTable/TsNFTTable.tsx",
    "content": "import React from 'react'\nimport styled from '@emotion/styled'\nimport { Box, BoxProps, Link, Typography } from '@mui/material'\nimport { Trans, WithTranslation, withTranslation } from 'react-i18next'\nimport moment from 'moment'\nimport { BoxNFT, Column, NftImage, Table, TablePagination } from '../../basic-lib'\nimport {\n  CompleteIcon,\n  DepositIcon,\n  DirectionTag,\n  EmptyValueTag,\n  EXPLORE_TYPE,\n  Explorer,\n  getFormattedHash,\n  getShortAddr,\n  getValuePrecisionThousand,\n  L1L2_NAME_DEFINED,\n  MapChainId,\n  MintIcon,\n  RedPacketIcon,\n  RowConfig,\n  TransferIcon,\n  WaitingIcon,\n  WarningIcon,\n  WithdrawIcon,\n} from '@loopring-web/common-resources'\nimport { TableFilterStyled, TablePaddingX } from '../../styled'\n\nimport { NFTTableFilter, NFTTableProps, TsTradeStatus, TxnDetailProps } from './Interface'\nimport { Filter } from './components/Filter'\nimport { ChainId, NFT_IMAGE_SIZES, TxNFTType } from '@loopring-web/loopring-sdk'\nimport { useSettings } from '../../../stores'\nimport { sanitize } from 'dompurify'\n\nconst TYPE_COLOR_MAPPING = [\n  { type: TsTradeStatus.processed, color: 'success' },\n  { type: TsTradeStatus.processing, color: 'warning' },\n  { type: TsTradeStatus.received, color: 'warning' },\n  { type: TsTradeStatus.failed, color: 'error' },\n]\n\nconst CellStatus = ({ row: { status } }: any) => {\n  const RenderValue = styled.div`\n    display: flex;\n    align-items: center;\n    color: ${({ theme }) =>\n      theme.colorBase[`${TYPE_COLOR_MAPPING.find((o) => o.type === status)?.color}`]};\n\n    & svg {\n      width: 24px;\n      height: 24px;\n    }\n  `\n  const svg =\n    status === 'processed' ? (\n      <CompleteIcon color={'success'} />\n    ) : status === 'processing' || status === 'received' ? (\n      <WaitingIcon color={'warning'} />\n    ) : (\n      <WarningIcon color={'error'} />\n    )\n  const RenderValueWrapper = <RenderValue>{svg}</RenderValue>\n  return RenderValueWrapper\n}\n\nconst TableStyled = styled(Box)<BoxProps & { isMobile?: boolean }>`\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n\n  .rdg {\n    ${({ isMobile }) =>\n      isMobile\n        ? `--template-columns: 60% 40% !important;`\n        : `--template-columns: 20% 15% 20% 15% 20% 10% !important;`}\n    .rdgCellCenter {\n      height: 100%;\n      justify-content: center;\n      align-items: center;\n    }\n\n    .textAlignRight {\n      text-align: right;\n    }\n\n    .textAlignCenter {\n      text-align: center;\n    }\n\n    .textAlignLeft {\n      text-align: left;\n    }\n  }\n\n  ${({ theme }) => TablePaddingX({ pLeft: theme.unit * 3, pRight: theme.unit * 3 })}\n` as (props: { isMobile?: boolean } & BoxProps) => JSX.Element\n\nexport const TsNFTTable = withTranslation(['tables', 'common'])(\n  <Row extends TxnDetailProps>({\n    accAddress,\n    showFilter = true,\n    rawData,\n    page,\n    pagination,\n    txType,\n    getTxnList,\n    duration,\n    showloading,\n    etherscanBaseUrl,\n    accountId,\n    t,\n    ...props\n  }: NFTTableProps<Row> & WithTranslation) => {\n    const [isDropDown, setIsDropDown] = React.useState(true)\n    const { isMobile, defaultNetwork } = useSettings()\n    const isTaiko = [ChainId.TAIKO, ChainId.TAIKOHEKLA].includes(defaultNetwork)\n    const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n    const handleFilterChange = (filter: Partial<NFTTableFilter>) => {\n      getTxnList({\n        page: filter.page ?? page,\n        txType:\n          filter.txType !== undefined\n            ? // @ts-ignore\n              filter.txType == 0\n              ? undefined\n              : filter.txType\n            : txType,\n        duration: filter.duration ?? duration,\n      })\n    }\n\n    const getColumnModeTransaction = React.useCallback(\n      (): Column<Row, Row>[] => [\n        {\n          key: 'side',\n          name: t('labelTxSide'),\n          formatter: ({ row }) => {\n            return (\n              <Box className='rdg-cell-value' title={row.nftTxType} display={'flex'}>\n                {row.metadata?.imageSize ? (\n                  <Box\n                    display={'flex'}\n                    alignItems={'center'}\n                    justifyContent={'center'}\n                    height={RowConfig.rowHeight + 'px'}\n                    width={RowConfig.rowHeight + 'px'}\n                    padding={1 / 4}\n                    style={{ background: 'var(--field-opacity)' }}\n                  >\n                    {row.metadata?.imageSize && (\n                      <NftImage\n                        alt={sanitize(row.metadata?.name ?? EmptyValueTag)}\n                        onError={() => undefined}\n                        src={row.metadata?.imageSize[NFT_IMAGE_SIZES.small]}\n                      />\n                    )}\n                  </Box>\n                ) : (\n                  <BoxNFT\n                    display={'flex'}\n                    alignItems={'center'}\n                    justifyContent={'center'}\n                    height={RowConfig.rowHeight + 'px'}\n                    width={RowConfig.rowHeight + 'px'}\n                  />\n                )}\n                <Typography\n                  color={'inherit'}\n                  flex={1}\n                  display={'inline-flex'}\n                  alignItems={'center'}\n                  paddingLeft={1}\n                >\n                  {t(`labelNFTType${TxNFTType[row.nftTxType]}`)}\n                </Typography>\n              </Box>\n            )\n          },\n        },\n        {\n          key: 'amount',\n          name: t('labelTxAmount'),\n          headerCellClass: 'textAlignLeft',\n          formatter: ({ row }: { row: Row }) => {\n            const hasSymbol =\n              row.nftTxType === TxNFTType[TxNFTType.TRANSFER]\n                ? row?.receiverAddress?.toLowerCase().trim() === accAddress?.toLowerCase().trim()\n                  ? '+'\n                  : '-'\n                : row.nftTxType === TxNFTType[TxNFTType.DEPOSIT] ||\n                  row.nftTxType === TxNFTType[TxNFTType.MINT]\n                ? '+'\n                : row.nftTxType === TxNFTType[TxNFTType.WITHDRAW]\n                ? '-'\n                : // @ts-ignore\n                row.nftTxType === TxNFTType[TxNFTType.SEND_LUCKY_TOKEN]\n                ? '-'\n                : // @ts-ignore\n                row.nftTxType === TxNFTType[TxNFTType.SEND_BACK_LUCKY_TOKEN]\n                ? '+'\n                : // @ts-ignore\n                row.nftTxType === TxNFTType[TxNFTType.WITHDRAW_LUCKY_TOKEN]\n                ? '+'\n                : ''\n            return (\n              <>\n                <Typography variant={'body1'} component={'span'} marginRight={1}>\n                  {hasSymbol}\n                  {row.amount ?? EmptyValueTag}\n                </Typography>\n                <Typography variant={'body1'} component={'span'}>\n                  {getFormattedHash(row.nftData)}\n                </Typography>\n              </>\n            )\n          },\n        },\n        {\n          key: 'from',\n          name: t('labelTxFrom'),\n          headerCellClass: 'textAlignRight',\n          cellClass: 'textAlignRight',\n          formatter: ({ row }) => {\n            const receiverAddress =\n              row.nftTxType === TxNFTType[TxNFTType.WITHDRAW]\n                ? getShortAddr(row.withdrawalInfo.recipient, isMobile)\n                : getShortAddr(row.receiverAddress, isMobile)\n            const senderAddress = getShortAddr(row.senderAddress)\n            const [from, to] =\n              row.nftTxType === TxNFTType[TxNFTType.TRANSFER]\n                ? row.receiverAddress?.toLowerCase().trim() === accAddress?.toLowerCase().trim()\n                  ? [senderAddress, `${L1L2_NAME_DEFINED[network].l2Symbol}`]\n                  : [`${L1L2_NAME_DEFINED[network].l2Symbol}`, receiverAddress]\n                : row.nftTxType === TxNFTType[TxNFTType.DEPOSIT]\n                ? [\n                    `${L1L2_NAME_DEFINED[network].l1Symbol}`,\n                    `${L1L2_NAME_DEFINED[network].l2Symbol}`,\n                  ]\n                : row.nftTxType === TxNFTType[TxNFTType.MINT]\n                ? [\n                    `${L1L2_NAME_DEFINED[network].l2Symbol} Mint`,\n                    `${L1L2_NAME_DEFINED[network].l2Symbol}`,\n                  ]\n                : row.nftTxType === TxNFTType[TxNFTType.WITHDRAW]\n                ? [`${L1L2_NAME_DEFINED[network].l2Symbol}`, receiverAddress]\n                : // @ts-ignore\n                row.nftTxType === TxNFTType[TxNFTType.SEND_BACK_LUCKY_TOKEN]\n                ? [\n                    `${L1L2_NAME_DEFINED[network].l2Symbol} Red Packet`,\n                    `${L1L2_NAME_DEFINED[network].l2Symbol}`,\n                  ]\n                : // @ts-ignore\n                row.nftTxType === TxNFTType[TxNFTType.SEND_LUCKY_TOKEN]\n                ? [\n                    `${L1L2_NAME_DEFINED[network].l2Symbol}`,\n                    `${L1L2_NAME_DEFINED[network].l2Symbol} Red Packet`,\n                  ]\n                : // @ts-ignore\n                row.nftTxType === TxNFTType[TxNFTType.WITHDRAW_LUCKY_TOKEN]\n                ? [\n                    `${L1L2_NAME_DEFINED[network].l2Symbol} Red Packet`,\n                    `${L1L2_NAME_DEFINED[network].l2Symbol}`,\n                  ]\n                : ['', '']\n            const hash = row.txHash !== '' ? row.txHash : row.hash\n            let path =\n              row.txHash !== ''\n                ? etherscanBaseUrl + `/tx/${row.txHash}`\n                : Explorer +\n                  `tx/${row.hash}-${EXPLORE_TYPE['NFT' + row.nftTxType.toUpperCase()]}-${\n                    row.storageInfo.accountId\n                  }-${row.storageInfo.tokenId}-${row.storageInfo.storageId}`\n            return (\n              <Box\n                className='rdg-cell-value textAlignRight'\n                display={'inline-flex'}\n                justifyContent={'flex-end'}\n                alignItems={'center'}\n              >\n                <Link\n                  style={{\n                    cursor: 'pointer',\n                    color: 'var(--color-primary)',\n                  }}\n                  target='_blank'\n                  rel='noopener noreferrer'\n                  href={path}\n                  title={hash}\n                >\n                  {from && to ? from + ` ${DirectionTag} ` + to : ''}\n                </Link>\n                <Box marginLeft={1}>\n                  <CellStatus {...{ row }} />\n                </Box>\n              </Box>\n            )\n          },\n        },\n        {\n          key: 'fee',\n          name: t('labelTxNetworkFee'),\n          headerCellClass: 'textAlignRight',\n          formatter: ({ row }) => {\n            const fee = row['fee'] ?? {}\n            const renderValue = `${getValuePrecisionThousand(\n              fee.value,\n              undefined,\n              undefined,\n              undefined,\n              false,\n              {\n                floor: false,\n                isTrade: true,\n              },\n            )} ${fee.unit}`\n            return <Box className='rdg-cell-value textAlignRight'>{renderValue}</Box>\n          },\n        },\n        {\n          key: 'memo',\n          name: t('labelTxMemo'),\n          headerCellClass: 'textAlignCenter',\n          formatter: ({ row }) => (\n            <Box\n              title={row.memo}\n              className='rdg-cell-value textAlignCenter'\n              dangerouslySetInnerHTML={{\n                __html: sanitize(row?.memo ?? EmptyValueTag) ?? '',\n              }}\n            />\n          ),\n        },\n        {\n          key: 'time',\n          name: t('labelTxTime'),\n          headerCellClass: 'textAlignRight',\n          formatter: ({ row }) => {\n            const value = row.updatedAt\n            const hasValue = Number.isFinite(value)\n            const renderValue = hasValue\n              ? moment(new Date(value), 'YYYYMMDDHHMM').fromNow()\n              : EmptyValueTag\n            return <Box className='rdg-cell-value textAlignRight'>{renderValue}</Box>\n          },\n        },\n      ],\n      [etherscanBaseUrl],\n    )\n\n    const getColumnMobileTransaction = React.useCallback(\n      (): Column<any, unknown>[] => [\n        {\n          key: 'amount',\n          name: (\n            <Typography\n              height={'100%'}\n              display={'flex'}\n              justifyContent={'space-between'}\n              variant={'inherit'}\n              color={'inherit'}\n              alignItems={'center'}\n            >\n              <span>{t('labelTransactions')}</span>\n              <span>{t('labelTxAmount') + ' / ' + t('labelTxNetworkFee')}</span>\n            </Typography>\n          ),\n          cellClass: 'textAlignLeft',\n          headerCellClass: 'textAlignLeft',\n          formatter: ({ row }) => {\n            // const hasValue = Number.isFinite(row.amount);\n            let side, hasSymbol, sideIcon\n            switch (row.nftTxType) {\n              case TxNFTType[TxNFTType.DEPOSIT]:\n                side = t('labelReceive')\n                hasSymbol = '+'\n                sideIcon = <DepositIcon fontSize={'inherit'} />\n                break\n              case TxNFTType[TxNFTType.TRANSFER]:\n                side = t('labelSendL2')\n                hasSymbol =\n                  row.receiverAddress?.toLowerCase() === accAddress?.toLowerCase() ? '+' : '-'\n                sideIcon = <TransferIcon fontSize={'inherit'} />\n                break\n              case TxNFTType[TxNFTType.MINT]:\n                side = t('labelMint')\n                sideIcon = <MintIcon fontSize={'inherit'} />\n                hasSymbol = '+'\n                break\n              // @ts-ignore\n              case TxNFTType[TxNFTType.SEND_LUCKY_TOKEN]:\n                side = t('labelNFTTypeSEND_LUCKY_TOKEN')\n                sideIcon = <RedPacketIcon fontSize={'inherit'} />\n                hasSymbol = '-'\n                break\n              // @ts-ignore\n              case TxNFTType[TxNFTType.SEND_BACK_LUCKY_TOKEN]:\n                side = t('labelNFTTypeSEND_BACK_LUCKY_TOKEN')\n                sideIcon = <RedPacketIcon fontSize={'inherit'} />\n                hasSymbol = '+'\n                break\n              // @ts-ignore\n              case TxNFTType[TxNFTType.WITHDRAW_LUCKY_TOKEN]:\n                side = t('labelNFTTypeWITHDRAW_LUCKY_TOKEN')\n                sideIcon = <RedPacketIcon fontSize={'inherit'} />\n                hasSymbol = '+'\n                break\n              case TxNFTType[TxNFTType.WITHDRAW]:\n              default:\n                hasSymbol = '-'\n                sideIcon = <WithdrawIcon fontSize={'inherit'} />\n                side = t('labelSendL1')\n            }\n            // const renderValue = hasValue ? row.amount : EmptyValueTag;\n\n            const renderFee = `Fee: ${getValuePrecisionThousand(\n              row.fee.value,\n              undefined,\n              undefined,\n              undefined,\n              false,\n              {\n                floor: false,\n                isTrade: true,\n              },\n            )} ${row.fee.unit}`\n            return (\n              <Box\n                flex={1}\n                display={'flex'}\n                alignItems={'center'}\n                justifyContent={'flex-start'}\n                title={side}\n              >\n                <Typography\n                  display={'flex'}\n                  marginRight={1}\n                  variant={'h3'}\n                  alignItems={'center'}\n                  flexDirection={'column'}\n                  width={'60px'}\n                >\n                  <Typography\n                    fontSize={20}\n                    width={'60px'}\n                    justifyContent={'center'}\n                    display={'inline-flex'}\n                    alignItems={'center'}\n                  >\n                    {row.metadata?.imageSize ? (\n                      <BoxNFT\n                        display={'flex'}\n                        alignItems={'center'}\n                        justifyContent={'center'}\n                        height={24 + 'px'}\n                        width={24 + 'px'}\n                      >\n                        <img height={24} src={row.metadata?.imageSize[NFT_IMAGE_SIZES.small]} />\n                      </BoxNFT>\n                    ) : (\n                      sideIcon\n                    )}\n                  </Typography>\n                  <Typography fontSize={10} marginTop={0}>\n                    {side}\n                  </Typography>\n                </Typography>\n                <Box display={'flex'} flex={1} flexDirection={'column'}>\n                  <Typography\n                    display={'inline-flex'}\n                    justifyContent={'flex-end'}\n                    alignItems={'center'}\n                  >\n                    {hasSymbol}\n                    {row.amount ?? EmptyValueTag}\n                  </Typography>\n                  <Typography color={'textSecondary'} variant={'body2'}>\n                    {renderFee}\n                  </Typography>\n                </Box>\n              </Box>\n            )\n          },\n        },\n        {\n          key: 'from',\n          name: t('labelTxFrom') + ' / ' + t('labelTxTime'),\n          headerCellClass: 'textAlignRight',\n          cellClass: 'textAlignRight',\n          formatter: ({ row }) => {\n            const receiverAddress =\n              row.nftTxType === TxNFTType[TxNFTType.WITHDRAW]\n                ? getShortAddr(row.withdrawalInfo.recipient, isMobile)\n                : getShortAddr(row.receiverAddress, isMobile)\n\n            const senderAddress = getShortAddr(row.senderAddress, isMobile)\n\n            const [from, to] =\n              row.nftTxType === TxNFTType[TxNFTType.TRANSFER]\n                ? row.receiverAddress?.toLowerCase() === accAddress?.toLowerCase()\n                  ? [senderAddress, `${L1L2_NAME_DEFINED[network].l2Symbol}`]\n                  : [`${L1L2_NAME_DEFINED[network].l2Symbol}`, receiverAddress]\n                : row.nftTxType === TxNFTType[TxNFTType.DEPOSIT]\n                ? [\n                    `${L1L2_NAME_DEFINED[network].l1Symbol}`,\n                    `${L1L2_NAME_DEFINED[network].l2Symbol}`,\n                  ]\n                : row.nftTxType === TxNFTType[TxNFTType.MINT]\n                ? ['Mint', `${L1L2_NAME_DEFINED[network].l2Symbol}`]\n                : row.nftTxType === TxNFTType[TxNFTType.WITHDRAW]\n                ? [`${L1L2_NAME_DEFINED[network].l2Symbol}`, receiverAddress]\n                : ['', '']\n            const hash = row.txHash !== '' ? row.txHash : row.hash\n            const path =\n              row.txHash !== ''\n                ? etherscanBaseUrl + `/tx/${row.txHash}`\n                : Explorer + `tx/${row.hash}-${EXPLORE_TYPE[row.nftTxType.toUpperCase()]}`\n\n            const hasValue = Number.isFinite(row.updatedAt)\n            const renderTime = hasValue\n              ? moment(new Date(row.updatedAt), 'YYYYMMDDHHMM').fromNow()\n              : EmptyValueTag\n\n            return (\n              <Box\n                display={'flex'}\n                flex={1}\n                flexDirection={'column'}\n                onClick={() => {\n                  window.open(path, '_blank')\n                  window.opener = null\n                }}\n              >\n                <Typography\n                  display={'inline-flex'}\n                  justifyContent={'flex-end'}\n                  alignItems={'center'}\n                >\n                  <Typography\n                    style={{\n                      cursor: 'pointer',\n                    }}\n                    color={'var(--color-primary)'}\n                    title={hash}\n                  >\n                    {from + ` ${DirectionTag} ` + to}\n                  </Typography>\n                  <Typography marginLeft={1}>\n                    <CellStatus {...{ row }} />\n                  </Typography>\n                </Typography>\n                <Typography color={'textSecondary'} variant={'body2'}>\n                  {renderTime}\n                </Typography>\n              </Box>\n            )\n          },\n        },\n      ],\n      [etherscanBaseUrl, isMobile, t],\n    )\n    const defaultArgs: any = {\n      columnMode: isMobile ? getColumnMobileTransaction() : getColumnModeTransaction(),\n      generateRows: (rawData: any) => rawData,\n      generateColumns: ({ columnsRaw }: any) => columnsRaw as Column<any, unknown>[],\n    }\n\n    return (\n      <TableStyled isMobile={isMobile}>\n        {showFilter &&\n          (isMobile && isDropDown ? (\n            <Link\n              variant={'body1'}\n              display={'inline-flex'}\n              width={'100%'}\n              justifyContent={'flex-end'}\n              paddingRight={2}\n              onClick={() => setIsDropDown(false)}\n            >\n              {t('labelShowFilter')}\n            </Link>\n          ) : (\n            <TableFilterStyled>\n              <Filter\n                {...{\n                  rawData,\n                  handleFilterChange,\n                  filterType: txType,\n                  filterDate: duration,\n                }}\n              />\n            </TableFilterStyled>\n          ))}\n        <Table className={'scrollable'} {...{ ...defaultArgs, ...props, rawData, showloading }} />\n        {accountId && showFilter && !isTaiko && (\n          <Typography\n            display={'flex'}\n            justifyContent={'flex-end'}\n            textAlign={'right'}\n            paddingRight={5 / 2}\n            paddingY={1}\n          >\n            <Trans i18nKey={'labelGoExplore'} ns={'common'}>\n              View transactions on\n              <Link\n                display={'inline-flex'}\n                target='_blank'\n                rel='noopener noreferrer'\n                href={Explorer + `/account/${accountId}`}\n                paddingLeft={1 / 2}\n              >\n                block explorer\n              </Link>\n            </Trans>\n          </Typography>\n        )}\n\n        {!!(pagination && pagination.total) && (\n          <TablePagination\n            page={page}\n            pageSize={pagination.pageSize}\n            total={pagination.total}\n            onPageChange={(page) => {\n              handleFilterChange({ page })\n            }}\n          />\n        )}\n      </TableStyled>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/nftTable/components/Filter.tsx",
    "content": "import React from 'react'\nimport styled from '@emotion/styled'\nimport { Grid, MenuItem } from '@mui/material'\nimport { withTranslation, WithTranslation } from 'react-i18next'\nimport { Button, DateRangePicker, TextField } from '../../../basic-lib'\nimport { DropDownIcon } from '@loopring-web/common-resources'\nimport { DateRange } from '@mui/lab'\nimport { TxNFTType, UserNFTTxTypes } from '@loopring-web/loopring-sdk'\nimport { NFTTableFilter } from '../Interface'\nimport { useSettings } from '../../../../stores'\n\nexport interface FilterProps {\n  handleFilterChange: (filter: Partial<NFTTableFilter>) => void\n  filterDate?: DateRange<Date | string>\n  filterType?: UserNFTTxTypes\n  // handleReset: () => void;\n  marketArray?: string[]\n}\n\n// export enum FilterOrderTypes {\n//   allTypes = \"All Types\",\n//   buy = \"Buy\",\n//   sell = \"Sell\",\n// }\n\nconst StyledTextFiled = styled(TextField)`\n  &.MuiTextField-root {\n    max-width: initial;\n  }\n  .MuiInputBase-root {\n    width: initial;\n    max-width: initial;\n  }\n`\n\nexport const Filter = withTranslation('tables', { withRef: true })(\n  ({ t, filterType, filterDate, handleFilterChange }: FilterProps & WithTranslation) => {\n    const { isMobile } = useSettings()\n    const transactionTypeList = [\n      {\n        label: t(`labelTxNFTFilter${TxNFTType.ALL}`),\n        value: 0,\n      },\n      {\n        label: t(`labelTxNFTFilter${TxNFTType.DEPOSIT}`),\n        value: UserNFTTxTypes[TxNFTType.DEPOSIT],\n      },\n      {\n        label: t(`labelTxNFTFilter${TxNFTType.WITHDRAW}`),\n        value: UserNFTTxTypes[TxNFTType.WITHDRAW],\n      },\n      {\n        label: t(`labelTxNFTFilter${TxNFTType.TRANSFER}`),\n        value: UserNFTTxTypes[TxNFTType.TRANSFER],\n      },\n      {\n        label: t(`labelTxNFTFilter${TxNFTType.MINT}`),\n        value: UserNFTTxTypes[TxNFTType.MINT],\n      },\n    ]\n    return (\n      <Grid container spacing={2}>\n        <Grid item xs={12} order={isMobile ? 0 : 1} lg={6}>\n          <DateRangePicker\n            value={filterDate ?? [null, null]}\n            onChange={(date: any) => {\n              handleFilterChange({ duration: date })\n            }}\n          />\n        </Grid>\n        <Grid item xs={6} order={isMobile ? 1 : 0} lg={2}>\n          <StyledTextFiled\n            id='table-transaction-trade-types'\n            select\n            fullWidth\n            value={filterType ?? 0}\n            placeholder={`labelTxNFTFilter${TxNFTType.ALL}`}\n            onChange={(event: React.ChangeEvent<{ value: unknown }>) => {\n              let txType: any = event.target.value as UserNFTTxTypes\n\n              handleFilterChange({\n                txType,\n              })\n            }}\n            inputProps={{ IconComponent: DropDownIcon }}\n          >\n            {transactionTypeList.map((o) => (\n              <MenuItem key={o.value} value={o.value}>\n                {o.label}\n              </MenuItem>\n            ))}\n          </StyledTextFiled>\n        </Grid>\n        <Grid item xs={6} order={3} lg={2}>\n          <Button\n            fullWidth\n            variant={'outlined'}\n            size={'medium'}\n            color={'primary'}\n            onClick={() => {\n              handleFilterChange({\n                duration: [null, null],\n                txType: '' as any,\n              })\n            }}\n          >\n            {t('labelFilterReset')}\n          </Button>\n        </Grid>\n      </Grid>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/nftTable/components/modal.tsx",
    "content": "import { WithTranslation, withTranslation } from 'react-i18next'\nimport styled from '@emotion/styled'\nimport { Box, Grid, Typography } from '@mui/material'\nimport moment from 'moment'\nimport {\n  EmptyValueTag,\n  L1L2_NAME_DEFINED,\n  MapChainId,\n  YEAR_DAY_MINUTE_FORMAT,\n} from '@loopring-web/common-resources'\nimport { TxType } from '@loopring-web/loopring-sdk'\nimport React from 'react'\nimport { TxnDetailProps } from '../Interface'\nimport { useSettings } from '../../../../stores'\n\n// import { getValuePrecisionThousand } from '@loopring-web/common-resources';\n\nconst ContentWrapperStyled = styled(Box)`\n  top: 45%;\n  left: 50%;\n  transform: translate(-50%, -50%);\n  width: 70%;\n  min-width: ${({ theme }) => theme.unit * 87.5}px;\n  height: 75%;\n  background-color: var(--color-box);\n  box-shadow: 0px ${({ theme }) => theme.unit / 2}px ${({ theme }) => theme.unit / 2}px\n    rgba(0, 0, 0, 0.25);\n  border-radius: ${({ theme }) => theme.unit}px;\n  position: absolute;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n`\n\nconst HeaderStyled = styled(Box)`\n  position: absolute;\n  top: 0;\n  z-index: 22;\n  width: 100%;\n  height: ${({ theme }) => theme.unit * 7.5}px;\n  box-shadow: 0px ${({ theme }) => theme.unit / 4}px ${({ theme }) => theme.unit}px\n    rgba(0, 0, 0, 0.25);\n  border-radius: ${({ theme }) => theme.unit}px ${({ theme }) => theme.unit}px 0px 0px;\n  display: flex;\n  align-items: center;\n`\n\nconst GridContainerStyled = styled(Grid)`\n  margin-top: ${({ theme }) => theme.unit * 7.5}px;\n  flex-direction: column;\n  width: auto;\n`\n\nconst GridItemStyled = styled(Grid)`\n  display: flex;\n  align-items: baseline;\n  margin-bottom: ${({ theme }) => theme.unit * 3}px;\n`\n\nconst EthHshStyled = styled(Typography)`\n  cursor: pointer;\n  text-decoration: underline;\n`\n\nconst TypographyStyled = styled(Typography)`\n  color: var(--color-text-secondary);\n  width: ${({ theme }) => theme.unit * 20}px;\n`\n\nconst InfoValueStyled = styled(Box)`\n  // max-width: ${({ theme }) => theme.unit * 32}px;\n  word-break: break-all;\n  font-size: 1.4rem;\n  color: ${(props: any) => (props.hash ? 'var(--color-secondary)' : 'var(--color-text-primary)')};\n` as any\n\nconst StatusStyled = styled(Typography)<any>`\n  color: ${({ theme, status }) =>\n    status === 'processed'\n      ? theme.colorBase.success\n      : status === 'processing'\n      ? theme.colorBase.warning\n      : status === 'failed'\n      ? theme.colorBase.error\n      : theme.colorBase.secondaryHover};\n`\n\nexport const TxnDetailPanel = withTranslation('common', { withRef: true })(\n  React.forwardRef(\n    (\n      {\n        t,\n        txType,\n        hash,\n        txHash,\n        status,\n        time,\n        from,\n        to,\n        amount,\n        fee,\n        memo,\n        etherscanBaseUrl,\n      }: TxnDetailProps & WithTranslation,\n      ref: React.ForwardedRef<any>,\n    ) => {\n      const { defaultNetwork } = useSettings()\n      const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n      const headerLabel =\n        txType === TxType.DEPOSIT\n          ? 'labelDTxnDetailHeader'\n          : txType === TxType.OFFCHAIN_WITHDRAWAL\n          ? 'labelWTxnDetailHeader'\n          : 'labelTTxnDetailHeader'\n\n      const renderStatus =\n        status.toUpperCase() === 'PROCESSED'\n          ? t('labelTxnDetailProcessed')\n          : status.toUpperCase() === 'PROCESSING' || status.toUpperCase() === 'RECEIVED'\n          ? t('labelTxnDetailProcessing')\n          : t('labelTxnDetailFailed')\n\n      return (\n        <ContentWrapperStyled ref={ref} tabIndex={-1}>\n          <HeaderStyled>\n            <Typography variant={'h4'} marginLeft={4}>\n              {t(headerLabel)}\n            </Typography>\n          </HeaderStyled>\n          <GridContainerStyled container flexDirection={'column'}>\n            <GridItemStyled item>\n              <TypographyStyled>\n                {t('labelTxnDetailHash', {\n                  layer2: L1L2_NAME_DEFINED[network].layer2,\n                })}\n              </TypographyStyled>\n              <InfoValueStyled>{hash}</InfoValueStyled>\n            </GridItemStyled>\n            {txHash && (\n              <GridItemStyled item>\n                <TypographyStyled>\n                  {t('labelTxnDetailHashLv1', {\n                    layer2: L1L2_NAME_DEFINED[network].layer2,\n                  })}\n                </TypographyStyled>\n                <InfoValueStyled>\n                  <EthHshStyled\n                    color={'var(--color-secondary)'}\n                    onClick={() => {\n                      window.open(`${etherscanBaseUrl}tx/${txHash}`)\n                      window.opener = null\n                    }}\n                  >\n                    {txHash}\n                  </EthHshStyled>\n                  {/* <a target={'_blank'} href={`${etherscanBaseUrl}tx/${txHash}`}>\n                        {txHash}</a> */}\n                </InfoValueStyled>\n              </GridItemStyled>\n            )}\n            <GridItemStyled item>\n              <TypographyStyled>{t('labelTxnDetailStatus')}</TypographyStyled>\n              {/* <StatusStyled status={status}>{status.toUpperCase()}</StatusStyled> */}\n              <StatusStyled status={status}>{renderStatus}</StatusStyled>\n            </GridItemStyled>\n            <GridItemStyled item>\n              <TypographyStyled>{t('labelTxnDetailTime')}</TypographyStyled>\n              <InfoValueStyled>{moment(time).format(YEAR_DAY_MINUTE_FORMAT)}</InfoValueStyled>\n            </GridItemStyled>\n            <GridItemStyled item>\n              <TypographyStyled>{t('labelTxnDetailFrom')}</TypographyStyled>\n              <InfoValueStyled hash={from}>{from || EmptyValueTag}</InfoValueStyled>\n            </GridItemStyled>\n            <GridItemStyled item>\n              <TypographyStyled>{t('labelTxnDetailTo')}</TypographyStyled>\n              <InfoValueStyled hash={to}>{to || EmptyValueTag}</InfoValueStyled>\n            </GridItemStyled>\n            <GridItemStyled item>\n              <TypographyStyled>{t('labelTxnDetailAmount')}</TypographyStyled>\n              <InfoValueStyled>{amount}</InfoValueStyled>\n            </GridItemStyled>\n            <GridItemStyled item>\n              <TypographyStyled>{t('labelTxnDetailFee')}</TypographyStyled>\n              <InfoValueStyled>{fee}</InfoValueStyled>\n            </GridItemStyled>\n            <GridItemStyled item>\n              <TypographyStyled>{t('labelTxnDetailMemo')}</TypographyStyled>\n              <InfoValueStyled>{memo || EmptyValueTag}</InfoValueStyled>\n            </GridItemStyled>\n          </GridContainerStyled>\n        </ContentWrapperStyled>\n      )\n    },\n  ),\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/nftTable/index.ts",
    "content": "export * from './TsNFTTable'\nexport * from './Interface'\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/orderHistoryTable/OrderHistoryTable.tsx",
    "content": "import React from 'react'\nimport {\n  Button,\n  CancelAllOrdersAlert,\n  CancelOneOrdersAlert,\n  PopoverPure,\n  QuoteTableRawDataItem,\n} from '../../index'\nimport styled from '@emotion/styled'\nimport {\n  Box,\n  BoxProps,\n  ClickAwayListener,\n  Grid,\n  Link,\n  Modal,\n  Tooltip,\n  Typography,\n} from '@mui/material'\nimport { DateRange } from '@mui/lab'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport moment from 'moment'\nimport { bindPopper, usePopupState } from 'material-ui-popup-state/hooks'\nimport {\n  CompleteIcon,\n  DirectionTag,\n  DropDownIcon,\n  EmptyValueTag,\n  getValuePrecisionThousand,\n  globalSetup,\n  RowConfig,\n  TableType,\n  TradeStatus,\n  TradeTypes,\n  UNIX_TIMESTAMP_FORMAT,\n  YEAR_DAY_MINUTE_FORMAT,\n} from '@loopring-web/common-resources'\nimport { Column, Table, TablePagination } from '../../basic-lib'\nimport { Filter, FilterOrderTypes } from './components/Filter'\nimport { OrderDetailPanel } from './components/modal'\nimport { TableFilterStyled, TablePaddingX } from '../../styled'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nimport { useSettings } from '../../../stores'\nimport _ from 'lodash'\nimport { useLocation } from 'react-router-dom'\n\nconst CancelColHeaderStyled = styled(Typography)`\n  display: flex;\n  align-items: center;\n  color: ${({ empty }: any) =>\n    empty === 'true' ? 'var(--color-text-third)' : 'var(--color-primary)'};\n  cursor: ${({ empty }: any) => (empty === 'true' ? 'not-allowed' : 'pointer')};\n` as any\n\nexport type OrderPair = {\n  from: {\n    key: string\n    value: number\n  }\n  to: {\n    key: string\n    value: number\n  }\n}\n\nexport interface OrderHistoryRow {\n  side: keyof typeof TradeTypes\n  orderType: sdk.OrderType\n  amount: OrderPair\n  average: number\n  filledAmount: OrderPair\n  time: number\n  hash: string\n  status: keyof typeof TradeStatus\n  sortColumn: string\n  filterColumn: string\n  actionsStatus: object\n  tradeChannel: string\n  extraOrderInfo: {\n    extraOrderType: string\n    isTriggerd: boolean\n    stopPrice: string\n    stopSide: string\n  }\n  __raw__: any\n}\n\nexport enum DetailRole {\n  maker = 'maker',\n  taker = 'taker',\n}\n\nexport type OrderDetailItem = {\n  market: string\n  amount: number\n  filledPrice: string\n  time: number\n  fee: {\n    key: string\n    value: string\n  }\n  volumeToken: string\n}\n\nexport type OrderHistoryTableDetailItem = {\n  amount: OrderPair\n  filledPrice: {\n    value: string | number\n    precision?: number\n  }\n  fee: {\n    key: string\n    value: string | number\n    precision?: number\n  }\n  role: string\n  time: number\n  volume?: number\n  orderId: string\n}\n\nexport type OrderHistoryRawDataItem = {\n  market: string\n  side: TradeTypes\n  amount: OrderPair\n  average: number | string\n  price: {\n    key: string\n    value: number\n  }\n  time: number\n  status: TradeStatus\n  hash: string\n  orderId: string\n  extraOrderInfo?: {\n    extraOrderType: string\n    isTriggerd: boolean\n    stopPrice: string\n    stopSide: string\n  }\n  __raw__: any\n}\n\nconst TableStyled = styled(Box)<\n  BoxProps & {\n    isMobile?: boolean\n    isopen?: string\n    ispro?: string\n    isStopLimit?: boolean\n  }\n>`\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n\n  .rdg {\n    ${({ isMobile, isopen, ispro, isStopLimit }) =>\n      !isMobile\n        ? `--template-columns: ${\n            isopen === 'open'\n              ? ispro === 'pro'\n                ? `auto auto ${isStopLimit ? 234 : 250}px auto auto ${\n                    isStopLimit ? '110px' : ''\n                  } auto auto`\n                : `auto auto ${isStopLimit ? 200 : 230}px auto auto ${\n                    isStopLimit ? 'auto' : ''\n                  } 130px 140px`\n              : ispro === 'pro'\n              ? `auto auto  ${isStopLimit ? 234 : 250}px auto  ${\n                  isStopLimit ? '110px' : ''\n                } auto auto`\n              : `auto auto ${isStopLimit ? 200 : 230}px auto 130px ${\n                  isStopLimit ? 'auto' : ''\n                } 130px 130px`\n          } !important;`\n        : `--template-columns: 14% 62% 24% !important;`}\n    .rdg-cell:last-of-type {\n      display: flex;\n      justify-content: flex-end;\n    }\n  }\n\n  .textAlignRight {\n    text-align: right;\n  }\n\n  ${({ theme }) => TablePaddingX({ pLeft: theme.unit * 3, pRight: theme.unit * 3 })}\n` as (\n  props: {\n    isMobile?: boolean\n    isopen?: string\n    ispro?: string\n    isStopLimit?: boolean\n  } & BoxProps,\n) => JSX.Element\n\nexport interface OrderHistoryTableProps {\n  rawData: OrderHistoryRawDataItem[]\n  pagination?: {\n    pageSize: number\n    total: number\n  }\n  showFilter?: boolean\n  getOrderList: (props: Omit<sdk.GetOrdersRequest, 'accountId'>) => Promise<any>\n  userOrderDetailList?: any[]\n  getUserOrderDetailTradeList?: (\n    props?: Omit<sdk.GetUserTradesRequest, 'accountId'>,\n  ) => Promise<void>\n  showLoading?: boolean\n  marketArray?: string[]\n  showDetailLoading?: boolean\n  isOpenOrder?: boolean\n  cancelOrder: ({ orderHash, clientOrderId }: any) => Promise<void>\n  cancelOrderByHashList?: (orderHashList: string) => Promise<void>\n  isScroll?: boolean\n  isPro?: boolean\n  handleScroll?: (event: React.UIEvent<HTMLDivElement>, isOpen?: boolean) => Promise<void>\n  clearOrderDetail?: () => void\n  onRowClick?: (rowIdx: number, row: QuoteTableRawDataItem, column: any) => void\n  isStopLimit?: boolean\n}\n\nexport const OrderHistoryTable = withTranslation('tables')(\n  (props: OrderHistoryTableProps & WithTranslation) => {\n    const { search } = useLocation()\n    const searchParams = new URLSearchParams(search)\n    const {\n      t,\n      rawData,\n      pagination,\n      showFilter,\n      getOrderList,\n      showLoading,\n      marketArray,\n      showDetailLoading,\n      /* getOrderDetail, */ /* orderDetailList, */ cancelOrder,\n      isOpenOrder = false,\n      isScroll,\n      handleScroll,\n      isPro = false,\n      clearOrderDetail,\n      cancelOrderByHashList,\n      userOrderDetailList,\n      getUserOrderDetailTradeList,\n      onRowClick,\n      isStopLimit,\n    } = props\n    const { isMobile } = useSettings()\n\n    const actionColumns = ['status']\n    const [filterType, setFilterType] = React.useState(FilterOrderTypes.allTypes)\n    const [filterDate, setFilterDate] = React.useState<DateRange<Date | string>>([null, null])\n    const [filterToken, setFilterToken] = React.useState<string>('all')\n    const [page, setPage] = React.useState(1)\n    const [modalState, setModalState] = React.useState(false)\n    const [currOrderId, setCurrOrderId] = React.useState('')\n    const [showCancelAllAlert, setShowCancelAllAlert] = React.useState(false)\n    const [showCancelOneAlert, setShowCancelOndAlert] = React.useState<{\n      open: boolean\n      row?: OrderHistoryRawDataItem\n    }>({\n      open: false,\n      row: undefined,\n    })\n\n    const updateData = _.debounce(\n      async ({\n        isOpen = isOpenOrder,\n        actionType,\n        currFilterType = filterType,\n        currFilterDate = filterDate,\n        currFilterToken = filterToken,\n        currPage = page,\n      }) => {\n        if (actionType === TableType.filter) {\n          currPage = 1\n          setPage(1)\n        }\n        const types =\n          currFilterType === FilterOrderTypes.buy\n            ? 'BUY'\n            : currFilterType === FilterOrderTypes.sell\n            ? 'SELL'\n            : ''\n        const start = Number(moment(currFilterDate[0]).format(UNIX_TIMESTAMP_FORMAT))\n        const end = Number(moment(currFilterDate[1]).format(UNIX_TIMESTAMP_FORMAT))\n        await getOrderList({\n          limit: pagination?.pageSize ?? 10,\n          offset: (currPage - 1) * (pagination?.pageSize ?? 10),\n          side: [types] as sdk.Side[],\n          market: currFilterToken === 'all' ? '' : currFilterToken,\n          start: Number.isNaN(start) ? -1 : start,\n          end: Number.isNaN(end) ? -1 : end,\n          status: isOpen\n            ? ['processing']\n            : ['processed', 'failed', 'cancelled', 'cancelling', 'expired'],\n        })\n      },\n      globalSetup.wait,\n    )\n\n    const handleFilterChange = React.useCallback(\n      async ({\n        isOpen = isOpenOrder,\n        type = filterType,\n        date = filterDate,\n        token = filterToken,\n        currPage = page,\n      }) => {\n        setFilterType(type)\n        setFilterDate(date)\n        setFilterToken(token)\n        await updateData({\n          isOpen: isOpen,\n          actionType: TableType.filter,\n          currFilterType: type,\n          currFilterDate: date,\n          currFilterToken: token,\n          currPage: currPage,\n        })\n      },\n      [updateData, filterDate, filterType, filterToken, page],\n    )\n\n    const handlePageChange = React.useCallback(\n      async (page: number) => {\n        setPage(page)\n        await updateData({ actionType: TableType.page, currPage: page })\n      },\n      [updateData],\n    )\n\n    const handleReset = React.useCallback(async () => {\n      setFilterType(FilterOrderTypes.allTypes)\n      setFilterDate([null, null])\n      setFilterToken('all')\n      await updateData({\n        TableType: TableType.filter,\n        currFilterType: FilterOrderTypes.allTypes,\n        currFilterDate: [null, null],\n        currFilterToken: 'all',\n      })\n    }, [updateData])\n    const handleOrderClick = React.useCallback(\n      async (row: OrderHistoryRawDataItem) => {\n        if (clearOrderDetail) {\n          clearOrderDetail()\n        }\n        setCurrOrderId(row.orderId)\n        setModalState(true)\n        if (getUserOrderDetailTradeList) {\n          await getUserOrderDetailTradeList({\n            orderHash: row.hash,\n          })\n        }\n      },\n      [clearOrderDetail, getUserOrderDetailTradeList],\n    )\n\n    React.useEffect(() => {\n      let filters: any = {}\n      updateData.cancel()\n      if (searchParams.get('market')) {\n        filters.token = searchParams.get('market')\n      }\n      filters.isOpen = isOpenOrder\n      handleFilterChange(filters)\n      return () => {\n        updateData.cancel()\n      }\n    }, [pagination?.pageSize, isOpenOrder])\n\n    const stopLimitColumn = React.useCallback((): Column<OrderHistoryRow, unknown>[] => {\n      if (isStopLimit) {\n        return [\n          {\n            key: 'Condition',\n            name: t('labelStopLimitStopPrice'),\n            headerCellClass: 'textAlignRight',\n            formatter: ({ row }: any) => {\n              return (\n                <Tooltip\n                  style={{ cursor: 'pointer', whiteSpace: 'pre-line' }}\n                  className='rdg-cell-value textAlignRight'\n                  title={\n                    <Typography color={'inherit'} whiteSpace={'pre-line'} variant={'inherit'}>\n                      {row?.extraOrderInfo?.isTriggered\n                        ? t('labelStopLimitTriggered', {\n                            time: row.extraOrderInfo?.triggeredTime\n                              ? moment(new Date(row.extraOrderInfo?.triggeredTime)).format(\n                                  YEAR_DAY_MINUTE_FORMAT,\n                                )\n                              : '',\n                            interpolation: {\n                              escapeValue: false,\n                            },\n                          })\n                        : t('labelStopLimitWaitingTrigger')}\n                    </Typography>\n                  }\n                >\n                  <Box\n                    style={{ cursor: 'pointer' }}\n                    className='rdg-cell-value textAlignRight'\n                    display={'inline-flex'}\n                    justifyContent={'center'}\n                    alignItems={'center'}\n                  >\n                    <Typography component={'span'} paddingRight={1 / 2}>\n                      {row.extraOrderInfo?.stopSide == sdk.STOP_SIDE.LESS_THAN_AND_EQUAL\n                        ? '≤'\n                        : '≥'}\n                      {row.extraOrderInfo?.stopPrice}\n                    </Typography>\n                    {row?.extraOrderInfo?.isTriggered && <CompleteIcon color={'success'} />}\n                  </Box>\n                </Tooltip>\n              )\n            },\n          },\n        ]\n      } else {\n        return []\n      }\n    }, [isStopLimit])\n    const CellStatus = React.useCallback(\n      ({ row, rowIdx }: any) => {\n        const value = row.status\n        const popupId = `status-orderTable-${rowIdx}`\n        const rightState = usePopupState({\n          variant: 'popover',\n          popupId: popupId,\n        })\n        const RenderValue: any = styled(Typography)`\n          position: relative;\n          display: flex;\n          justify-content: flex-end;\n          align-items: center;\n\n          color: ${({ theme }) => {\n            const { colorBase } = theme\n            return value === TradeStatus.Processed\n              ? colorBase.success\n              : value === TradeStatus.Expired\n              ? colorBase.textSecondary\n              : colorBase.textPrimary\n          }};\n          height: 100%;\n\n          & svg {\n            font-size: 14px;\n            transition: fill 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;\n            transform: ${() => (rightState.isOpen ? 'rotate(180deg)' : '')};\n          }\n        `\n\n        let actualValue = ''\n        switch (value) {\n          case TradeStatus.Processing:\n            actualValue = t('labelOrderProcessing')\n            break\n          case TradeStatus.Processed:\n            actualValue = t('labelOrderProcessed')\n            break\n          case TradeStatus.Cancelling:\n            actualValue = t('labelOrderCancelling')\n            break\n          case TradeStatus.Cancelled:\n            actualValue = t('labelOrderCancelled')\n            break\n          case TradeStatus.Expired:\n            actualValue = t('labelOrderExpired')\n            break\n          case TradeStatus.Waiting:\n            actualValue = t('labelOrderWaiting')\n            break\n          default:\n            break\n        }\n\n        return (\n          <>\n            {isMobile ? (\n              <RenderValue\n                whiteSpace={'pre-line'}\n                style={{ wordBreak: 'break-all' }}\n                className={'textAlignLeft'}\n                variant={'body2'}\n                component={'span'}\n              >\n                {actualValue}\n              </RenderValue>\n            ) : (\n              <RenderValue\n                component={'span'}\n                className={`rdg-cell-value textAlignRight`}\n                onClick={() => handleOrderClick(row)}\n              >\n                <Typography\n                  component={'span'}\n                  whiteSpace={'pre-line'}\n                  variant={'body1'}\n                  color={'inherit'}\n                >\n                  {actualValue}\n                </Typography>\n\n                <DropDownIcon htmlColor={'var(--color-text-third)'} fontSize={'large'} />\n              </RenderValue>\n            )}\n          </>\n        )\n      },\n      [handleOrderClick, isMobile, t],\n    )\n\n    const getPopoverState = React.useCallback((label: number) => {\n      return usePopupState({\n        variant: 'popover',\n        popupId: `popup-cancel-order-${label}`,\n      })\n    }, [])\n\n    const getColumnModeOrderHistory = (): Column<OrderHistoryRow, unknown>[] => [\n      {\n        key: 'types',\n        name: t('labelOrderTypes'),\n        formatter: ({ row }) => {\n          let renderValue = ''\n          if (row.extraOrderInfo?.extraOrderType == 'STOP_LIMIT') {\n            renderValue = t('labelOrderStopLimitOrder')\n          } else {\n            switch (row.orderType) {\n              case 'AMM':\n                renderValue = t('labelOrderMarketOrder')\n                break\n              case 'LIMIT_ORDER':\n                renderValue = t('labelOrderLimitOrder')\n                break\n              case 'MAKER_ONLY':\n                renderValue = t('labelOrderLimitOrder')\n                break\n              case 'TAKER_ONLY':\n                renderValue = t('labelOrderLimitOrder')\n                break\n              default:\n                break\n            }\n          }\n\n          return <div className='rdg-cell-value'>{renderValue}</div>\n        },\n      },\n      {\n        key: 'channels',\n        name: t('labelOrderChannels'),\n        formatter: ({ row }) => {\n          const value = row['tradeChannel']\n          let renderChannel = ''\n          switch (value) {\n            case 'MIXED':\n              renderChannel = t('labelOrderChannelsMixed')\n              break\n            case 'AMM_POOL':\n              renderChannel = t('labelOrderChannelsSwap')\n              break\n            case 'ORDER_BOOK':\n              renderChannel = t('labelOrderChannelsOrderBook')\n              break\n            default:\n              break\n          }\n          return <div className='rdg-cell-value'>{renderChannel}</div>\n        },\n      },\n      {\n        key: 'amount',\n        name: t('labelOrderAmount'),\n        formatter: ({ row, column }) => {\n          const { from, to } = row[column.key]\n          const precisionFrom = row.amount.from?.['precision']\n          const precisionTo = row.amount.to?.['precision']\n          const { key: keyFrom, value: valueFrom } = from\n          const { key: keyTo, value: valueTo } = to\n          const renderValue = `${getValuePrecisionThousand(\n            valueFrom,\n            precisionFrom,\n            precisionFrom,\n          )} ${keyFrom} ${DirectionTag} ${getValuePrecisionThousand(\n            valueTo,\n            precisionTo,\n            precisionTo,\n          )} ${keyTo}`\n          return (\n            <div className='rdg-cell-value' title={renderValue}>\n              {renderValue}\n            </div>\n          )\n        },\n      },\n      {\n        key: 'average',\n        name: t('labelOrderAverage'),\n        headerCellClass: 'textAlignRight',\n        formatter: ({ row, column }) => {\n          const value = row[column.key]\n          const precisionMarket = row['precisionMarket']\n          const renderValue = value\n            ? getValuePrecisionThousand(value, undefined, undefined, precisionMarket, true, {\n                isPrice: true,\n              })\n            : EmptyValueTag\n          return <div className='rdg-cell-value textAlignRight'>{renderValue}</div>\n        },\n      },\n      {\n        key: 'price',\n        name: t('labelOrderPrice'),\n        headerCellClass: 'textAlignRight',\n        formatter: ({ row }) => {\n          const value = row['price'].value\n          const precisionMarket = row['precisionMarket']\n          const hasValue = Number.isFinite(value)\n          const renderValue = hasValue\n            ? getValuePrecisionThousand(value, undefined, undefined, precisionMarket, true, {\n                isPrice: true,\n              })\n            : EmptyValueTag\n          return (\n            <div className='rdg-cell-value textAlignRight'>\n              <span>{renderValue}</span>\n            </div>\n          )\n        },\n      },\n      ...[].concat(stopLimitColumn() as never[]),\n      {\n        key: 'time',\n        name: t('labelOrderTime'),\n        headerCellClass: 'textAlignRight',\n        formatter: ({ row, column }) => {\n          const value = row[column.key]\n          const renderValue = Number.isFinite(value)\n            ? moment(new Date(row['time']), 'YYYYMMDDHHMM').fromNow()\n            : EmptyValueTag\n          return (\n            <div className='rdg-cell-value textAlignRight'>\n              <span>{renderValue}</span>\n            </div>\n          )\n        },\n      },\n      {\n        key: 'status',\n        headerCellClass: 'textAlignRight',\n        name: t('labelOrderStatus'),\n        formatter: ({ row, column, rowIdx }) => (\n          <>\n            <CellStatus {...{ row, column, rowIdx }} />\n          </>\n        ),\n      },\n    ]\n\n    const getColumnModeOpenHistory = (isEmpty: boolean): Column<OrderHistoryRow, unknown>[] => [\n      {\n        key: 'types',\n        name: t('labelOrderTypes'),\n        formatter: ({ row }) => {\n          let renderValue = ''\n          if (row.extraOrderInfo?.extraOrderType == 'STOP_LIMIT') {\n            renderValue = t('labelOrderStopLimitOrder')\n          } else {\n            switch (row.orderType) {\n              case 'AMM':\n                renderValue = t('labelOrderAmm')\n                break\n              case 'LIMIT_ORDER':\n                renderValue = t('labelOrderLimitOrder')\n                break\n              case 'MAKER_ONLY':\n                renderValue = t('labelOrderMaker')\n                break\n              case 'TAKER_ONLY':\n                renderValue = t('labelOrderTaker')\n                break\n              default:\n                break\n            }\n          }\n\n          return <div className='rdg-cell-value'>{renderValue}</div>\n        },\n      },\n      {\n        key: 'channels',\n        name: t('labelOrderChannels'),\n        formatter: ({ row }) => {\n          const value = row['tradeChannel']\n          let renderChannel = ''\n          switch (value) {\n            case 'MIXED':\n              renderChannel = t('labelOrderChannelsMixed')\n              break\n            case 'AMM_POOL':\n              renderChannel = t('labelOrderChannelsAMM')\n              break\n            case 'ORDER_BOOK':\n              renderChannel = t('labelOrderChannelsOrderBook')\n              break\n            default:\n              break\n          }\n          return <div className='rdg-cell-value'>{renderChannel}</div>\n        },\n      },\n      {\n        key: 'amount',\n        name: t('labelOrderAmount'),\n        formatter: ({ row, column }) => {\n          const { from, to } = row[column.key]\n          const { key: keyFrom, value: valueFrom } = from\n          const { key: keyTo, value: valueTo } = to\n          const precisionFrom = row.amount.from?.['precision']\n          const precisionTo = row.amount.to?.['precision']\n          const renderValue = `${getValuePrecisionThousand(\n            valueFrom,\n            precisionFrom,\n            precisionFrom,\n          )} ${keyFrom} ${DirectionTag} ${getValuePrecisionThousand(\n            valueTo,\n            precisionTo,\n            precisionTo,\n          )} ${keyTo}`\n          return (\n            <div className='rdg-cell-value' title={renderValue}>\n              {renderValue}\n            </div>\n          )\n        },\n      },\n      {\n        key: 'price',\n        name: t('labelOrderPrice'),\n        headerCellClass: 'textAlignRight',\n        formatter: ({ row }) => {\n          const value = row['price'].value\n          const precisionMarket = row['precisionMarket']\n          const hasValue = Number.isFinite(value)\n          const renderValue = hasValue\n            ? getValuePrecisionThousand(\n                value,\n                precisionMarket,\n                precisionMarket,\n                precisionMarket,\n                true,\n                { isPrice: true },\n              )\n            : EmptyValueTag\n          return (\n            <div className='rdg-cell-value textAlignRight'>\n              <span>{renderValue}</span>\n            </div>\n          )\n        },\n      },\n      {\n        key: 'completion',\n        name: t('labelOrderCompletion'),\n        headerCellClass: 'textAlignRight',\n        formatter: ({ row }) => {\n          const rawValue = row['completion']\n          const renderValue = `${(rawValue * 100).toFixed(2)}%`\n          return <div className='rdg-cell-value textAlignRight'>{renderValue}</div>\n        },\n      },\n      ...[].concat(stopLimitColumn() as never[]),\n      {\n        key: 'time',\n        name: t('labelOrderTime'),\n        headerCellClass: 'textAlignRight',\n        formatter: ({ row, column }) => {\n          const value = row[column.key]\n          const renderValue = Number.isFinite(value)\n            ? moment(new Date(row['time']), 'YYYYMMDDHHMM').fromNow()\n            : EmptyValueTag\n          return (\n            <div className='rdg-cell-value textAlignRight'>\n              <span>{renderValue}</span>\n            </div>\n          )\n        },\n      },\n      {\n        key: 'cancel',\n        headerCellClass: 'textAlignRight',\n        name: (\n          <CancelColHeaderStyled\n            empty={isEmpty ? 'true' : 'false'}\n            onClick={isEmpty ? undefined : () => setShowCancelAllAlert(true)}\n          >\n            {t('labelOrderCancelAll')}\n          </CancelColHeaderStyled>\n        ),\n        formatter: ({ row }: any) => {\n          return (\n            <>\n              <Box\n                onClick={(_e: any) => {\n                  setShowCancelOndAlert({ open: true, row })\n                }}\n                style={{ cursor: 'pointer' }}\n                className='rdg-cell-value textAlignRight'\n              >\n                <Typography component={'span'} color={'var(--color-primary)'}>\n                  {t('labelOrderCancelOrder')}\n                </Typography>\n              </Box>\n            </>\n          )\n        },\n      },\n    ]\n    const getColumnModeMobileOrderHistory = (): Column<OrderHistoryRow, unknown>[] => [\n      {\n        key: 'types',\n        name: t('labelOrderTypes') + '/' + t('labelOrderChannels'),\n        formatter: ({ row }) => {\n          let renderChannel = '',\n            renderValue = ''\n          switch (row.tradeChannel) {\n            case 'MIXED':\n              renderChannel = t('labelOrderChannelsMixed')\n              break\n            case 'AMM_POOL':\n              renderChannel = t('labelOrderChannelsSwap')\n              break\n            case 'ORDER_BOOK':\n              renderChannel = t('labelOrderChannelsOrderBook')\n              break\n            default:\n              break\n          }\n          if (row?.extraOrderInfo?.extraOrderType) {\n            renderValue = t('labelOrderStopLimitOrder')\n          } else {\n            switch (row.orderType) {\n              case 'AMM':\n                renderValue = t('labelOrderMarketOrder')\n                break\n              case 'LIMIT_ORDER':\n                renderValue = t('labelOrderLimitOrder')\n                break\n              case 'MAKER_ONLY':\n                renderValue = t('labelOrderLimitOrder')\n                break\n              case 'TAKER_ONLY':\n                renderValue = t('labelOrderLimitOrder')\n                break\n              default:\n                break\n            }\n          }\n          return (\n            <Box\n              height={'100%'}\n              width={'100%'}\n              display={'flex'}\n              flexDirection={'column'}\n              alignItems={'flex-start'}\n              justifyContent={'center'}\n            >\n              <Typography>{renderValue}</Typography>\n              <Typography color={'textSecondary'} variant={'body2'}>\n                {renderChannel}\n              </Typography>\n            </Box>\n          )\n        },\n      },\n      {\n        key: 'amount',\n        name: t('labelOrderAmount') + '/' + t('labelOrderAverage'),\n        headerCellClass: 'textAlignRight',\n        formatter: ({ row, column, rowIdx }) => {\n          const { from, to } = row[column.key]\n          const precisionFrom = row.amount.from?.['precision']\n          const precisionTo = row.amount.to?.['precision']\n          const { key: keyFrom, value: valueFrom } = from\n          const { key: keyTo, value: valueTo } = to\n          const renderValue = `${getValuePrecisionThousand(\n            valueFrom,\n            precisionFrom,\n            precisionFrom,\n          )} ${keyFrom} ${DirectionTag} ${getValuePrecisionThousand(\n            valueTo,\n            precisionTo,\n            precisionTo,\n          )} ${keyTo}`\n          const average = row.average\n            ? getValuePrecisionThousand(\n                row.average,\n                undefined,\n                undefined,\n                row['precisionMarket'],\n                true,\n                { isPrice: true },\n              )\n            : EmptyValueTag\n          return (\n            <Box\n              height={'100%'}\n              width={'100%'}\n              display={'flex'}\n              flexDirection={'column'}\n              alignItems={'flex-end'}\n              justifyContent={'center'}\n            >\n              <Typography component={'span'}>{renderValue}</Typography>\n\n              <Typography\n                component={'span'}\n                color={'textSecondary'}\n                display={'flex'}\n                justifyContent={'space-between'}\n                variant={'body2'}\n                width={'100%'}\n              >\n                <CellStatus {...{ row, column, rowIdx }} />\n                <Typography component={'span'} color={'textSecondary'}>\n                  {average}\n                </Typography>\n              </Typography>\n            </Box>\n          )\n        },\n      },\n      {\n        key: 'price',\n        name: t('labelOrderPrice') + '/' + t('labelOrderTime'),\n        headerCellClass: 'textAlignRight',\n        formatter: ({ row }) => {\n          const value = row['price'].value\n          const precisionMarket = row['precisionMarket']\n          const hasValue = Number.isFinite(value)\n          const time = Number.isFinite(value)\n            ? moment(new Date(row['time']), 'YYYYMMDDHHMM').fromNow()\n            : EmptyValueTag\n          const renderValue = hasValue\n            ? getValuePrecisionThousand(value, undefined, undefined, precisionMarket, true, {\n                isPrice: true,\n              })\n            : EmptyValueTag\n          return (\n            <Box\n              height={'100%'}\n              width={'100%'}\n              display={'flex'}\n              flexDirection={'column'}\n              alignItems={'flex-end'}\n              justifyContent={'center'}\n            >\n              <Typography>{renderValue}</Typography>\n              <Typography color={'textSecondary'} variant={'body2'}>\n                {time}\n              </Typography>\n            </Box>\n          )\n        },\n      },\n    ]\n    const getColumnModeMobileOpenHistory = (\n      isEmpty: boolean,\n    ): Column<OrderHistoryRow, unknown>[] => [\n      {\n        key: 'types',\n        name: t('labelOrderTypes') + '/' + t('labelOrderChannels'),\n        formatter: ({ row }) => {\n          let renderChannel = '',\n            renderValue = ''\n          switch (row.tradeChannel) {\n            case 'MIXED':\n              renderChannel = t('labelOrderChannelsMixed')\n              break\n            case 'AMM_POOL':\n              renderChannel = t('labelOrderChannelsSwap')\n              break\n            case 'ORDER_BOOK':\n              renderChannel = t('labelOrderChannelsOrderBook')\n              break\n            default:\n              break\n          }\n          if (row.extraOrderInfo?.extraOrderType == 'STOP_LIMIT') {\n            renderValue = t('labelOrderStopLimitOrder')\n          } else {\n            switch (row.orderType) {\n              case 'AMM':\n                renderValue = t('labelOrderMarketOrder')\n                break\n              case 'LIMIT_ORDER':\n                renderValue = t('labelOrderLimitOrder')\n                break\n              case 'MAKER_ONLY':\n                renderValue = t('labelOrderLimitOrder')\n                break\n              case 'TAKER_ONLY':\n                renderValue = t('labelOrderLimitOrder')\n                break\n              default:\n                break\n            }\n          }\n          return (\n            <Box\n              height={'100%'}\n              width={'100%'}\n              display={'flex'}\n              flexDirection={'column'}\n              alignItems={'flex-start'}\n              justifyContent={'center'}\n            >\n              <Typography>{renderValue}</Typography>\n              <Typography color={'textSecondary'} variant={'body2'}>\n                {renderChannel}\n              </Typography>\n            </Box>\n          )\n        },\n      },\n      {\n        key: 'amount',\n        headerCellClass: 'textAlignRight',\n        name: t('labelOrderAmount') + '/' + t('labelOrderPrice'),\n        formatter: ({ row, column }) => {\n          const { from, to } = row[column.key]\n          const precisionFrom = row.amount.from?.['precision']\n          const precisionTo = row.amount.to?.['precision']\n          const { key: keyFrom, value: valueFrom } = from\n          const { key: keyTo, value: valueTo } = to\n          const renderValue = `${getValuePrecisionThousand(\n            valueFrom,\n            precisionFrom,\n            precisionFrom,\n          )} ${keyFrom} ${DirectionTag} ${getValuePrecisionThousand(\n            valueTo,\n            precisionTo,\n            precisionTo,\n          )} ${keyTo}`\n          //@ts-ignore\n          const hasValue = Number.isFinite(row['price']?.value)\n          const price = hasValue\n            ? getValuePrecisionThousand(\n                //@ts-ignore\n                row['price']?.value,\n                row['precisionMarket'],\n                row['precisionMarket'],\n                row['precisionMarket'],\n                true,\n                { isPrice: true },\n              )\n            : EmptyValueTag\n          const completion = `${(row['completion'] * 100).toFixed(2)}%`\n\n          return (\n            <Box\n              height={'100%'}\n              width={'100%'}\n              display={'flex'}\n              flexDirection={'column'}\n              alignItems={'flex-end'}\n              justifyContent={'center'}\n            >\n              <Typography>{renderValue}</Typography>\n              <Typography\n                color={'textSecondary'}\n                display={'flex'}\n                justifyContent={'space-between'}\n                variant={'body2'}\n                width={'100%'}\n              >\n                <Typography color={'inherit'} variant={'inherit'}>\n                  {completion}\n                </Typography>\n                <Typography color={'inherit'} variant={'inherit'}>\n                  {price}\n                </Typography>\n              </Typography>\n            </Box>\n          )\n        },\n      },\n      {\n        key: 'time',\n        name: (\n          <CancelColHeaderStyled\n            empty={isEmpty ? 'true' : 'false'}\n            onClick={isEmpty ? undefined : () => setShowCancelAllAlert(true)}\n          >\n            {t('labelOrderCancelAll')}\n          </CancelColHeaderStyled>\n        ),\n        headerCellClass: 'textAlignRight',\n        formatter: ({ row, rowIdx }) => {\n          const time = Number.isFinite(row.time)\n            ? moment(new Date(row.time), 'YYYYMMDDHHMM').fromNow()\n            : EmptyValueTag\n          const orderHash = row.hash\n          const clientOrderId = row['orderId']\n          const popState = getPopoverState(rowIdx)\n          const handleClose = () => {\n            popState.setOpen(false)\n          }\n          // @ts-ignore\n          const handleRequestCancel = async (e: MouseEvent<any>) => {\n            e.preventDefault()\n            await cancelOrder({ orderHash, clientOrderId })\n            handleClose()\n          }\n          return (\n            <>\n              <Box\n                onClick={(_e: any) => {\n                  setShowCancelOndAlert({ open: true, row: row as any })\n                }}\n                style={{ cursor: 'pointer' }}\n                className='rdg-cell-value textAlignRight'\n              >\n                <Typography component={'span'} color={'var(--color-primary)'}>\n                  {t('labelOrderCancelOrder')}\n                </Typography>\n                <Typography color={'textSecondary'} variant={'body2'}>\n                  {time}\n                </Typography>\n              </Box>\n\n              <PopoverPure\n                className={isPro ? 'arrow-top-right' : 'arrow-top-center'}\n                {...bindPopper(popState)}\n                anchorOrigin={{\n                  vertical: 'top',\n                  horizontal: 'center',\n                }}\n                transformOrigin={{\n                  vertical: 'bottom',\n                  horizontal: 'center',\n                }}\n              >\n                <ClickAwayListener onClickAway={() => popState.setOpen(false)}>\n                  <Box padding={2}>\n                    <Typography marginBottom={1}>{t('labelOrderCancelConfirm')}</Typography>\n                    <Grid\n                      container\n                      spacing={1}\n                      display={'flex'}\n                      justifyContent={'flex-end'}\n                      alignItems={'center'}\n                    >\n                      <Grid item>\n                        <Button variant={'outlined'} onClick={handleClose}>\n                          {t('labelOrderCancel')}\n                        </Button>\n                      </Grid>\n                      <Grid item>\n                        <Button variant={'contained'} size={'small'} onClick={handleRequestCancel}>\n                          {t('labelOrderConfirm')}\n                        </Button>\n                      </Grid>\n                    </Grid>\n                  </Box>\n                </ClickAwayListener>\n              </PopoverPure>\n            </>\n          )\n        },\n      },\n    ]\n    const actualColumns = isOpenOrder\n      ? isMobile\n        ? getColumnModeMobileOpenHistory(rawData.length === 0)\n        : getColumnModeOpenHistory(rawData.length === 0)\n      : isMobile\n      ? getColumnModeMobileOrderHistory()\n      : getColumnModeOrderHistory()\n\n    const defaultArgs: any = {\n      columnMode: actualColumns,\n      generateRows: (rawData: any) => rawData,\n      onRowClick: isPro ? onRowClick : null,\n      generateColumns: ({ columnsRaw }: any) =>\n        columnsRaw as Column<OrderHistoryRawDataItem, unknown>[],\n      actionColumns,\n    }\n\n    const handleCancelAll = React.useCallback(async () => {\n      const openOrdresList = rawData\n        .filter((o) => o.status === 'processing')\n        .map((o) => o.hash)\n        .join(',')\n      if (cancelOrderByHashList) {\n        await cancelOrderByHashList(openOrdresList)\n      }\n    }, [rawData, cancelOrderByHashList])\n    const handleCancelOne = React.useCallback(async () => {\n      if (showCancelOneAlert?.row) {\n        const orderHash = showCancelOneAlert?.row?.hash\n        const clientOrderId = showCancelOneAlert?.row?.orderId\n        await cancelOrder({ orderHash, clientOrderId })\n      }\n    }, [showCancelOneAlert])\n    const [isDropDown, setIsDropDown] = React.useState(true)\n\n    return (\n      <TableStyled\n        isMobile={isMobile}\n        isStopLimit={isStopLimit}\n        isopen={isOpenOrder ? 'open' : 'history'}\n        ispro={isPro ? 'pro' : 'lite'}\n      >\n        {showFilter &&\n          (isMobile && isDropDown ? (\n            <Link\n              variant={'body1'}\n              display={'inline-flex'}\n              width={'100%'}\n              justifyContent={'flex-end'}\n              paddingRight={2}\n              onClick={() => setIsDropDown(false)}\n            >\n              {t('labelShowFilter')}\n            </Link>\n          ) : (\n            <TableFilterStyled>\n              <Filter\n                marketArray={marketArray}\n                filterDate={filterDate}\n                filterType={filterType}\n                filterToken={filterToken}\n                handleReset={handleReset}\n                handleFilterChange={handleFilterChange}\n              />\n            </TableFilterStyled>\n          ))}\n        <Table\n          className={isScroll ? 'scrollable' : undefined}\n          onRowClick={isOpenOrder ? undefined : (_index, row) => handleOrderClick(row as any)}\n          onScroll={handleScroll ? (e) => handleScroll(e, isOpenOrder) : undefined}\n          style={{\n            height:\n              isOpenOrder && !isScroll\n                ? RowConfig.rowHeaderHeight + rawData.length * RowConfig.rowHeight\n                : 'initial',\n          }}\n          {...{ ...defaultArgs, ...props, rawData, showloading: showLoading }}\n        />\n        <CancelAllOrdersAlert\n          open={showCancelAllAlert}\n          handleCancelAll={handleCancelAll}\n          handleClose={() => setShowCancelAllAlert(false)}\n        />\n        <CancelOneOrdersAlert\n          open={showCancelOneAlert.open}\n          handleCancelOne={handleCancelOne}\n          handleClose={() => setShowCancelOndAlert({ open: false, row: undefined })}\n        />\n        <Modal open={modalState} onClose={() => setModalState(false)}>\n          <OrderDetailPanel\n            rawData={userOrderDetailList || []}\n            showLoading={showDetailLoading}\n            orderId={currOrderId}\n          />\n        </Modal>\n        {pagination && !!rawData.length && (\n          <TablePagination\n            page={page}\n            pageSize={pagination.pageSize}\n            total={pagination.total}\n            onPageChange={handlePageChange}\n          />\n        )}\n      </TableStyled>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/orderHistoryTable/SingleOrderHistoryTable.tsx",
    "content": "import { Box, BoxProps, Typography } from '@mui/material'\nimport { Column, generateColumns, Table } from '../../basic-lib'\nimport { OrderDetailItem } from './OrderHistoryTable'\nimport { withTranslation, WithTranslation } from 'react-i18next'\nimport { EmptyValueTag, getValuePrecisionThousand, myLog } from '@loopring-web/common-resources'\nimport styled from '@emotion/styled'\nimport moment from 'moment'\nimport { TablePaddingX } from '../../styled'\nimport { useSettings } from '../../../stores'\n\ninterface Row {\n  amount: number\n  tradingPrice: number\n  filledPrice: string\n  time: number\n  total: {\n    key: string\n    value: number\n  }\n  fee: { value: number; key: string }\n  sortColumn: string\n  filterColumn: string\n  actionsStatus: object\n}\n\nconst TableStyled = styled(Box)<BoxProps & { isMobile?: boolean }>`\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n  height: auto;\n\n  .rdg {\n    ${({ isMobile }) =>\n      !isMobile\n        ? `--template-columns: auto auto auto auto 180px !important;`\n        : `--template-columns: 40% 40% 20% !important;`}\n  }\n\n  .textAlignRight {\n    text-align: right;\n  }\n\n  ${({ theme }) => TablePaddingX({ pLeft: theme.unit * 3, pRight: theme.unit * 3 })}\n` as (props: { isMobile?: boolean } & BoxProps) => JSX.Element\n\nexport interface SingleOrderHistoryTableProps {\n  rawData: OrderDetailItem[]\n  showloading?: boolean\n}\n\nexport const SingleOrderHistoryTable = withTranslation('tables')(\n  (props: SingleOrderHistoryTableProps & WithTranslation) => {\n    const { t } = props\n    const getColumnModeSingleHistory = (): Column<Row, unknown>[] => {\n      return [\n        {\n          key: 'amount',\n          name: props.t('labelOrderAmount'),\n          formatter: ({ row }) => {\n            const value = row['amount']\n            const renderValue = `${getValuePrecisionThousand(value, undefined, undefined, 6)}`\n            return <div className='rdg-cell-value'>{renderValue}</div>\n          },\n        },\n        {\n          key: 'filledPrice',\n          name: props.t('labelOrderFilledPrice'),\n          headerCellClass: 'textAlignRight',\n          formatter: ({ row, column }) => {\n            const value = row[column.key]\n            const renderValue = value\n              ? getValuePrecisionThousand(value, undefined, undefined, undefined, true, {\n                  isPrice: true,\n                })\n              : EmptyValueTag\n            return <div className='rdg-cell-value textAlignRight'>{renderValue}</div>\n          },\n        },\n        {\n          key: 'fee',\n          name: props.t('labelOrderFee'),\n          headerCellClass: 'textAlignRight',\n          formatter: ({ row, column }) => {\n            myLog(666, row['fee'])\n            const value = row[column.key].value\n            const token = row[column.key].key\n            const renderValue = value\n              ? `${getValuePrecisionThousand(value, undefined, undefined, undefined, false, {\n                  floor: false,\n                })} ${token}`\n              : EmptyValueTag\n            return <div className='rdg-cell-value textAlignRight'>{renderValue}</div>\n          },\n        },\n        {\n          key: 'role',\n          name: props.t('labelOrderRole'),\n          headerCellClass: 'textAlignRight',\n          formatter: ({ row }) => {\n            const renderValue = row['fee'].value ? props.t('labelTaker') : props.t('labelMaker')\n            return <div className='rdg-cell-value textAlignRight'>{renderValue}</div>\n          },\n        },\n        {\n          key: 'time',\n          name: props.t('labelOrderTime'),\n          headerCellClass: 'textAlignRight',\n          formatter: ({ row, column }) => {\n            const value = row[column.key]\n            const renderValue = Number.isFinite(value)\n              ? moment(new Date(row['time']), 'YYYYMMDDHHMM').fromNow()\n              : EmptyValueTag\n            return (\n              <div className='rdg-cell-value textAlignRight'>\n                <span>{renderValue}</span>\n              </div>\n            )\n          },\n        },\n      ]\n    }\n    const getColumnModeMobileSingleHistory = (): Column<Row, unknown>[] => {\n      return [\n        {\n          key: 'amount',\n          name: t('labelOrderAmount') + '/' + t('labelOrderFilledPrice'),\n          headerCellClass: 'textAlignRight',\n          formatter: ({ row }) => {\n            const renderValue = `${getValuePrecisionThousand(row.amount, undefined, undefined, 6)}`\n            const filledPrice = row.filledPrice\n              ? `${getValuePrecisionThousand(\n                  Number(row.filledPrice),\n                  undefined,\n                  undefined,\n                  undefined,\n                  true,\n                  { isPrice: true },\n                )} `\n              : EmptyValueTag\n            return (\n              <Box\n                height={'100%'}\n                width={'100%'}\n                display={'flex'}\n                flexDirection={'column'}\n                alignItems={'flex-end'}\n                justifyContent={'center'}\n              >\n                <Typography component={'span'}>{renderValue}</Typography>\n                <Typography color={'textSecondary'}> {filledPrice}</Typography>\n              </Box>\n            )\n          },\n        },\n        {\n          key: 'fee',\n          name: props.t('labelOrderFee'),\n          headerCellClass: 'textAlignRight',\n          formatter: ({ row }) => {\n            const value = row.fee.value\n            const token = row.fee.key\n            const renderValue = value\n              ? `${getValuePrecisionThousand(value, undefined, undefined, undefined, false, {\n                  floor: false,\n                })} ${token}`\n              : EmptyValueTag\n            return <div className='rdg-cell-value textAlignRight'>{renderValue}</div>\n          },\n        },\n        {\n          key: 'role',\n          name: t('labelOrderRole') + '/' + t('labelOrderTime'),\n          headerCellClass: 'textAlignRight',\n          formatter: ({ row }) => {\n            const renderValue = row['fee'].value ? props.t('labelTaker') : props.t('labelMaker')\n            const time = Number.isFinite(row.time)\n              ? moment(new Date(row.time), 'YYYYMMDDHHMM').fromNow()\n              : EmptyValueTag\n\n            return (\n              <Box\n                height={'100%'}\n                width={'100%'}\n                display={'flex'}\n                flexDirection={'column'}\n                alignItems={'flex-end'}\n                justifyContent={'center'}\n              >\n                <Typography>{renderValue}</Typography>\n                <Typography color={'textSecondary'} variant={'body2'}>\n                  {time}\n                </Typography>\n              </Box>\n            )\n          },\n        },\n      ]\n    }\n    const { isMobile } = useSettings()\n    const defaultArgs: any = {\n      rawData: [],\n      columnMode: isMobile ? getColumnModeMobileSingleHistory() : getColumnModeSingleHistory(),\n      generateRows: (rawData: any) => rawData,\n      generateColumns,\n    }\n    return (\n      <TableStyled isMobile={isMobile}>\n        <Table\n          className={'scrollable'}\n          {...{\n            ...defaultArgs,\n            ...props,\n            rawData: props.rawData,\n            showloading: props.showloading,\n          }}\n        />\n      </TableStyled>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/orderHistoryTable/components/Filter.tsx",
    "content": "import React from 'react'\nimport styled from '@emotion/styled'\nimport { Grid, MenuItem } from '@mui/material'\nimport { withTranslation, WithTranslation } from 'react-i18next'\nimport { DateRangePicker, TextField } from '../../../'\nimport { Button } from '../../../basic-lib/btns'\nimport { DropDownIcon } from '@loopring-web/common-resources'\nimport { DateRange } from '@mui/lab'\n\nexport interface FilterProps {\n  handleFilterChange: ({ filterType, filterDate, filterToken }: any) => void\n  filterDate: DateRange<Date | string>\n  filterType: FilterOrderTypes\n  filterToken: string\n  handleReset: () => void\n  marketArray?: string[]\n}\n\nexport enum FilterOrderTypes {\n  allTypes = 'all',\n  buy = 'Buy',\n  sell = 'Sell',\n}\n\nconst StyledTextFiled = styled(TextField)`\n  &.MuiTextField-root {\n    max-width: initial;\n  }\n  .MuiInputBase-root {\n    width: initial;\n    max-width: initial;\n  }\n`\n\nexport const Filter = withTranslation('tables', { withRef: true })(\n  ({\n    t,\n    filterDate,\n    filterToken,\n    handleFilterChange,\n    handleReset,\n    marketArray = [],\n  }: FilterProps & WithTranslation) => {\n    const getTokenTypeList = React.useCallback(() => {\n      return [\n        {\n          label: t('labelOrderFilterAllPairs'),\n          value: 'all',\n        },\n        ...Array.from(new Set(marketArray)).map((token) => ({\n          label: token,\n          value: token,\n        })),\n      ]\n    }, [t, marketArray])\n\n    return (\n      <Grid container spacing={2}>\n        <Grid item xs={12} lg={4}>\n          <DateRangePicker\n            value={filterDate}\n            onChange={(date: any) => {\n              handleFilterChange({ date: date })\n            }}\n          />\n        </Grid>\n        <Grid item xs={6} lg={2}>\n          <StyledTextFiled\n            id='table-order-token-types'\n            select\n            fullWidth\n            value={filterToken}\n            onChange={(event: React.ChangeEvent<{ value: string }>) => {\n              handleFilterChange({ token: event.target.value })\n            }}\n            inputProps={{ IconComponent: DropDownIcon }}\n          >\n            {getTokenTypeList().map((o) => (\n              <MenuItem key={o.value} value={o.value}>\n                {o.label}\n              </MenuItem>\n            ))}\n          </StyledTextFiled>\n        </Grid>\n        <Grid item xs={6} lg={2}>\n          <Button\n            fullWidth\n            variant={'outlined'}\n            size={'medium'}\n            color={'primary'}\n            onClick={handleReset}\n          >\n            {t('labelFilterReset')}\n          </Button>\n        </Grid>\n      </Grid>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/orderHistoryTable/components/modal.tsx",
    "content": "import { withTranslation } from 'react-i18next'\nimport styled from '@emotion/styled'\nimport { Box, Typography } from '@mui/material'\nimport { SingleOrderHistoryTable } from '../SingleOrderHistoryTable'\nimport { TFunction } from 'i18next'\nimport { OrderDetailItem } from '../OrderHistoryTable'\nimport { useSettings } from '../../../../stores'\n\nexport enum TxnDetailStatus {\n  processed = 'PROCESSED',\n  processing = 'PROCESSING',\n  received = 'RECEIVED',\n  failed = 'FAILED',\n}\n\nconst ContentWrapperStyled = styled(Box)`\n  position: absolute;\n  top: 45%;\n  left: 50%;\n  transform: translate(-50%, -50%);\n  min-width: ${({ theme }) => theme.unit * 87.5}px;\n  background-color: var(--color-box);\n  box-shadow: 0px ${({ theme }) => theme.unit / 2}px ${({ theme }) => theme.unit / 2}px\n    rgba(0, 0, 0, 0.25);\n  padding: 0 ${({ theme }) => theme.unit * 1}px;\n  border-radius: ${({ theme }) => theme.unit / 2}px;\n`\n\nconst HeaderStyled = styled(Box)`\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  width: 100%;\n  margin-top: ${({ theme }) => theme.unit * 2}px;\n  margin-bottom: ${({ theme }) => theme.unit * 2}px;\n  padding: 0 ${({ theme }) => theme.unit * 3}px;\n`\n\nexport const OrderDetailPanel = withTranslation('tables', { withRef: true })(\n  ({\n    rawData,\n    t,\n    showLoading,\n    orderId,\n  }: {\n    rawData: OrderDetailItem[]\n    showLoading?: boolean\n    t: TFunction\n    orderId: string\n  }) => {\n    const { isMobile } = useSettings()\n    const volume = rawData.map((o) => o.amount).reduce((prev, curr) => (prev || 0) + (curr || 0), 0)\n    const volumeToken = rawData[0]?.volumeToken\n    return (\n      <ContentWrapperStyled width={isMobile ? 'var(--mobile-full-panel-width)' : 900}>\n        <HeaderStyled flexDirection={isMobile ? 'column' : 'row'} alignItems={'flex-start'}>\n          <Typography variant={'h6'} display={'flex'}>\n            <Typography>{t('labelOrderDetailTradingVolume')} :&nbsp;</Typography>\n            <Typography>\n              {volume}&nbsp;{volumeToken}\n            </Typography>\n          </Typography>\n          <Typography variant={'h6'} display={'flex'}>\n            <Typography> {t('labelOrderDetailOrderId')} : &nbsp; </Typography>\n            <Typography>\n              {isMobile\n                ? `${orderId.substring(0, 10)}...${orderId.substring(orderId.length - 10)}`\n                : orderId}\n            </Typography>\n          </Typography>\n        </HeaderStyled>\n        <SingleOrderHistoryTable rawData={rawData} showloading={showLoading} />\n      </ContentWrapperStyled>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/orderHistoryTable/index.ts",
    "content": "export * from './OrderHistoryTable'\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/poolsTable/Interface.ts",
    "content": "import {\n  Account,\n  AmmDetail,\n  CAMPAIGNTAGCONFIG,\n  // ForexMap,\n  RowConfig,\n} from '@loopring-web/common-resources'\n// import { Currency } from \"@loopring-web/loopring-sdk\";\n\nexport type PoolRow<T> = AmmDetail<T>\ntype FilterExtend = {\n  showFilter?: boolean\n  filterValue: string\n  getFilteredData: (filterValue: string) => void\n}\nexport type PoolTableProps<R extends PoolRow<T>, T = any> = {\n  rawData: R[]\n  handleWithdraw: (row: R) => void\n  handleDeposit: (row: R) => void\n  campaignTagConfig?: CAMPAIGNTAGCONFIG\n  wait?: number\n  tableHeight?: number\n  showLoading?: boolean\n  rowConfig?: typeof RowConfig\n  forexValue?: number\n} & FilterExtend\n\nexport type IconColumnProps<R> = {\n  row: R\n  account: Account\n  size?: number\n  campaignTagConfig?: CAMPAIGNTAGCONFIG\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/poolsTable/PoolsTable.stories.tsx",
    "content": "import styled from '@emotion/styled'\nimport { Meta, Story } from '@storybook/react'\nimport { MemoryRouter } from 'react-router-dom'\nimport { PoolRow, PoolsTable } from './index'\nimport { coinMap } from '../../../static'\nimport { CoinInfo, FloatTag } from '@loopring-web/common-resources'\n\nconst Style = styled.div`\n  flex: 1;\n  height: 100%;\n  flex: 1;\n`\n\nconst rawData: PoolRow<any>[] = [\n  {\n    coinA: 'ETH',\n    coinB: 'LRC',\n    address: '',\n    market: 'ETH-LRC',\n    coinAInfo: coinMap['ETH'] as CoinInfo<any>,\n    coinBInfo: coinMap['LRC'] as CoinInfo<any>,\n    amountU: 12,\n    totalLPToken: 12132131,\n    totalA: 0.002,\n    totalB: 12344,\n    tradeFloat: {\n      change: 1000,\n      timeUnit: '24h',\n      priceU: 1.23123,\n      floatTag: FloatTag.increase,\n      reward: 12312,\n    },\n    APR: 56,\n    isNew: true,\n    isActivity: false,\n  },\n  {\n    coinA: 'ETH',\n    coinB: 'LRC',\n    address: '',\n    market: 'ETH-LRC',\n    coinAInfo: coinMap['ETH'] as CoinInfo<any>,\n    coinBInfo: coinMap['LRC'] as CoinInfo<any>,\n    amountU: 12,\n    totalLPToken: 12132131,\n    totalA: 0.002,\n    totalB: 12344,\n    tradeFloat: {\n      change: 1000,\n      timeUnit: '24h',\n      priceU: 1.23123,\n      floatTag: FloatTag.increase,\n      reward: 12312,\n    },\n    APR: 56,\n    isNew: true,\n    isActivity: false,\n  },\n]\n\nexport const PoolTable: Story<any> = (args: any) => {\n  return (\n    <>\n      <Style>\n        <MemoryRouter initialEntries={['/']}>\n          <PoolsTable {...args} />\n        </MemoryRouter>\n      </Style>\n    </>\n  )\n}\n\nPoolTable.bind({})\n\nPoolTable.args = {\n  rawData: rawData,\n  pagination: {\n    pageSize: 5,\n  },\n}\n\nexport default {\n  title: 'components/TableList',\n  component: PoolsTable,\n  argTypes: {},\n} as Meta\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/poolsTable/PoolsTable.tsx",
    "content": "import React from 'react'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport { bindPopper, bindHover } from 'material-ui-popup-state'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nimport {\n  Button,\n  Column,\n  InputSearch,\n  NewTagIcon,\n  Popover,\n  PopoverPure,\n  PopoverType,\n  PopoverWrapProps,\n  Table,\n  TableProps,\n} from '../../basic-lib'\nimport {\n  CurrencyToTag,\n  EmptyValueTag,\n  getValuePrecisionThousand,\n  globalSetup,\n  MoreIcon,\n  PriceTag,\n  RowConfig,\n  RowInvestConfig,\n  SCENARIO,\n  TokenType,\n} from '@loopring-web/common-resources'\nimport { Box, BoxProps, Grid, Typography } from '@mui/material'\nimport { PoolRow, PoolTableProps } from './Interface'\nimport styled from '@emotion/styled'\nimport { FormatterProps } from 'react-data-grid'\n\nimport { useSettings, useToggle } from '../../../stores'\nimport { TablePaddingX } from '../../styled'\nimport { AmmAPRDetail, AmmPairDetail, TagIconList } from '../../block'\nimport { ActionPopContent } from '../myPoolTable/components/ActionPop'\nimport { CoinIcons } from '../assetsTable'\nimport _ from 'lodash'\nimport { useHistory, useLocation } from 'react-router-dom'\nimport { usePopupState } from 'material-ui-popup-state/hooks'\n\nconst TableStyled = styled(Box)<{ isMobile?: boolean } & BoxProps>`\n  .rdg {\n    border-radius: ${({ theme }) => theme.unit}px;\n\n    ${({ isMobile }) =>\n      !isMobile\n        ? `--template-columns: 240px auto auto auto 200px !important;`\n        : ` --template-columns: 16% 50% auto 8% !important;\n`}\n    .rdg-cell.action {\n      display: flex;\n      justify-content: flex-end;\n      align-items: center;\n    }\n  }\n\n  .textAlignRight {\n    text-align: right;\n\n    .rdg-header-sort-cell {\n      justify-content: flex-end;\n    }\n  }\n\n  ${({ theme }) => TablePaddingX({ pLeft: theme.unit * 3, pRight: theme.unit * 3 })}\n` as (props: { isMobile?: boolean } & BoxProps) => JSX.Element\n\nexport const PoolsTable = withTranslation(['tables', 'common'])(\n  <T extends PoolRow<any>>({\n    t,\n    i18n,\n    tReady,\n    campaignTagConfig,\n    showFilter = true,\n    rawData,\n    filterValue: _filterValue,\n    getFilteredData,\n    wait = globalSetup.wait,\n    showLoading,\n    handleWithdraw,\n    handleDeposit,\n    rowConfig = RowConfig,\n    forexValue = 1,\n    ...rest\n  }: WithTranslation & PoolTableProps<T>) => {\n    const { currency, isMobile, coinJson } = useSettings()\n    const { search, pathname } = useLocation()\n    const { toggle } = useToggle()\n    const searchParams = new URLSearchParams(search)\n    const history = useHistory()\n    const [filterValue, setFilterValue] = React.useState(_filterValue ?? '')\n\n    const updateData = _.debounce(({ searchValue = '' }: { searchValue: string }) => {\n      getFilteredData(searchValue)\n    }, wait)\n    const handleFilterChange = React.useCallback(async ({ searchValue }: any) => {\n      setFilterValue(searchValue)\n      searchParams.set('search', searchValue ?? '')\n      history.push({\n        pathname,\n        search: searchParams.toString(),\n      })\n      updateData({ searchValue })\n    }, [])\n\n    const sortMethod = React.useCallback(\n      (_sortedRows, sortColumn) => {\n        let _rawData: T[] = []\n        switch (sortColumn) {\n          case 'pools':\n            _rawData = rawData.sort((a, b) => {\n              const valueA = a.coinAInfo.simpleName\n              const valueB = b.coinAInfo.simpleName\n              return valueB.localeCompare(valueA)\n            })\n            break\n          case 'liquidity':\n            _rawData = rawData.sort((a, b) => {\n              return sdk\n                .toBig(b.amountU?.replaceAll(sdk.SEP, '') ?? 0)\n                .minus(a.amountU?.replaceAll(sdk.SEP, '') ?? 0)\n                .toNumber()\n            })\n            break\n          case 'volume24':\n            _rawData = rawData.sort((a, b) => {\n              return sdk\n                .toBig(b?.tradeFloat?.priceU ?? 0)\n                .minus(a?.tradeFloat?.priceU ?? 0)\n                .toNumber()\n            })\n            break\n          case 'APR':\n            _rawData = rawData.sort((a, b) => {\n              return sdk\n                .toBig(b.APR ?? 0)\n                .minus(a.APR ?? 0)\n                .toNumber()\n            })\n            break\n          default:\n            _rawData = rawData\n        }\n        return _rawData\n      },\n      [rawData],\n    )\n\n    const getPopoverState = React.useCallback((label: string) => {\n      return usePopupState({\n        variant: 'popover',\n        popupId: `popup-poolsTable-${label}`,\n      })\n    }, [])\n    const columnMode = (): Column<T, any>[] => [\n      {\n        key: 'pools',\n        sortable: true,\n        width: 'auto',\n        minWidth: 240,\n        name: t('labelPool'),\n        formatter: ({ row }: FormatterProps<T>) => {\n          return (\n            <Box\n              flex={1}\n              height={'100%'}\n              alignContent={'center'}\n              display={'flex'}\n              alignItems={'center'}\n            >\n              <CoinIcons\n                type={TokenType.lp}\n                tokenIcon={[coinJson[row.coinA], coinJson[row.coinB]]}\n              />\n              <Typography\n                variant={'inherit'}\n                color={'textPrimary'}\n                display={'flex'}\n                flexDirection={'row'}\n                marginLeft={2}\n                component={'span'}\n                paddingRight={1}\n              >\n                <Typography component={'span'} className={'next-coin'}>\n                  <Typography variant='inherit' component={'span'} className={'next-coin'}>\n                    {row.coinAInfo?.simpleName}\n                  </Typography>\n                  <Typography variant='inherit' component={'i'}>\n                    /\n                  </Typography>\n                  <Typography variant='inherit' component={'span'} title={'buy'}>\n                    {row.coinBInfo?.simpleName}\n                  </Typography>\n                </Typography>\n                <Typography\n                  variant='inherit'\n                  component={'span'}\n                  display={'inline-flex'}\n                  title={'buy'}\n                  alignItems={'center'}\n                  paddingLeft={1 / 2}\n                >\n                  {campaignTagConfig && (\n                    <TagIconList\n                      scenario={SCENARIO.AMM}\n                      campaignTagConfig={campaignTagConfig}\n                      symbol={row.market}\n                    />\n                  )}\n                  {row.isNew && <NewTagIcon />}\n                </Typography>\n              </Typography>\n            </Box>\n          )\n        },\n      },\n      {\n        key: 'liquidity',\n        sortable: true,\n        width: 'auto',\n        headerCellClass: 'textAlignRight',\n        name: t('labelLiquidity'),\n        formatter: ({ row, rowIdx }) => {\n          const { coinA, coinB, totalAStr, totalBStr, amountU } = row\n          const popoverState = getPopoverState(rowIdx.toString())\n          return (\n            <Box className={'textAlignRight'}>\n              <Typography\n                {...bindHover(popoverState)}\n                paddingTop={1}\n                component={'span'}\n                style={{\n                  cursor: 'pointer',\n                  textDecoration: 'underline dotted',\n                }}\n              >\n                {typeof amountU === 'undefined' || !Number(amountU)\n                  ? EmptyValueTag\n                  : PriceTag[CurrencyToTag[currency]] +\n                    getValuePrecisionThousand(\n                      sdk.toBig(amountU).times(forexValue),\n                      undefined,\n                      undefined,\n                      2,\n                      true,\n                      { isFait: true },\n                    )}\n              </Typography>\n              <PopoverPure\n                className={'arrow-top-center'}\n                {...bindPopper(popoverState)}\n                anchorOrigin={{\n                  vertical: 'top',\n                  horizontal: 'center',\n                }}\n                transformOrigin={{\n                  vertical: 'bottom',\n                  horizontal: 'center',\n                }}\n              >\n                <AmmPairDetail\n                  coinA={coinA as any}\n                  coinB={coinB as any}\n                  balanceA={totalAStr}\n                  balanceB={totalBStr}\n                />\n              </PopoverPure>\n            </Box>\n          )\n        },\n      },\n      {\n        key: 'volume24',\n        sortable: true,\n        width: 'auto',\n        minWidth: 156,\n        headerCellClass: 'textAlignRight',\n        name: t('label24TradeVolume'),\n        formatter: ({ row }) => {\n          const { priceU } = row?.tradeFloat ?? {}\n          return (\n            <Box className={'textAlignRight'}>\n              <Typography component={'span'}>\n                {priceU\n                  ? PriceTag[CurrencyToTag[currency]] +\n                    getValuePrecisionThousand(\n                      sdk.toBig(priceU).times(forexValue),\n                      undefined,\n                      undefined,\n                      2,\n                      true,\n                      { isFait: true },\n                    )\n                  : EmptyValueTag}\n              </Typography>\n            </Box>\n          )\n        },\n      },\n      {\n        key: 'APR',\n        sortable: true,\n        name: t('labelAPR'),\n        width: 'auto',\n        maxWidth: 68,\n        headerCellClass: 'textAlignRight',\n        formatter: ({ row, rowIdx }) => {\n          const APR = typeof row.APR !== undefined && row.APR ? row?.APR : EmptyValueTag\n          const popoverState = getPopoverState(rowIdx.toString())\n          return (\n            <Box className={'textAlignRight'}>\n              <Typography\n                component={'span'}\n                style={\n                  APR === 0 || typeof APR === 'undefined' || APR == EmptyValueTag\n                    ? {}\n                    : {\n                        cursor: 'pointer',\n                        textDecoration: 'underline dotted',\n                      }\n                }\n                {...bindHover(popoverState)}\n              >\n                {APR === 0 || typeof APR === 'undefined' || APR == EmptyValueTag\n                  ? EmptyValueTag\n                  : getValuePrecisionThousand(APR, 2, 2, 2, true) + '%'}\n              </Typography>\n              {!(APR === 0 || typeof APR === 'undefined' || APR == EmptyValueTag) && (\n                <PopoverPure\n                  className={'arrow-top-center'}\n                  {...bindPopper(popoverState)}\n                  anchorOrigin={{\n                    vertical: 'top',\n                    horizontal: 'center',\n                  }}\n                  transformOrigin={{\n                    vertical: 'bottom',\n                    horizontal: 'center',\n                  }}\n                >\n                  <AmmAPRDetail {...row.APRs} />\n                </PopoverPure>\n              )}\n            </Box>\n          )\n        },\n      },\n      {\n        key: 'action',\n        name: t('labelAction'),\n        // maxWidth: 120,\n        width: 'auto',\n        headerCellClass: `textAlignRight`,\n        cellClass: () => `action`,\n        formatter: ({ row }) => {\n          return (\n            <Box className={'action'} marginRight={-1}>\n              <Button\n                // href={`liquidity/pools/coinPair/${\n                //   row?.coinAInfo?.simpleName + \"-\" + row?.coinBInfo?.simpleName\n                // }`}\n                // disabled={!allowTrade?.joinAmm?.enable}\n                className={'btn'}\n                variant={'text'}\n                size={'small'}\n                onClick={() => {\n                  handleDeposit(row as any)\n                  // handleWithdraw(row);\n                }}\n              >\n                {t('labelTradePool')}\n              </Button>\n              <Button\n                variant={'text'}\n                size={'small'}\n                onClick={() => {\n                  handleWithdraw(row as any)\n                }}\n              >\n                {t('labelPoolTableRemoveLiquidity')}\n              </Button>\n            </Box>\n          )\n        },\n      },\n    ]\n    const columnModeMobile = (): Column<T, any>[] => [\n      {\n        key: 'pools',\n        sortable: true,\n        width: 'auto',\n        name: t('labelPool'),\n        formatter: ({ row }: FormatterProps<T>) => {\n          return (\n            <Box\n              flex={1}\n              height={'100%'}\n              alignContent={'center'}\n              display={'flex'}\n              alignItems={'center'}\n            >\n              <CoinIcons\n                type={TokenType.lp}\n                tokenIcon={[coinJson[row.coinA], coinJson[row.coinB]]}\n              />\n              {/*<Typography*/}\n              {/*  variant={\"inherit\"}*/}\n              {/*  color={\"textPrimary\"}*/}\n              {/*  display={\"flex\"}*/}\n              {/*  flexDirection={\"column\"}*/}\n              {/*  marginLeft={2}*/}\n              {/*  component={\"span\"}*/}\n              {/*  paddingRight={1}*/}\n              {/*>*/}\n              {/*  <Typography component={\"span\"} className={\"next-coin\"}>*/}\n              {/*    <Typography*/}\n              {/*      variant=\"inherit\"*/}\n              {/*      component={\"span\"}*/}\n              {/*      className={\"next-coin\"}*/}\n              {/*    >*/}\n              {/*      {row.coinAInfo?.simpleName}*/}\n              {/*    </Typography>*/}\n              {/*    <Typography variant=\"inherit\" component={\"i\"}>*/}\n              {/*      /*/}\n              {/*    </Typography>*/}\n              {/*    <Typography*/}\n              {/*      variant=\"inherit\"*/}\n              {/*      component={\"span\"}*/}\n              {/*      title={\"buy\"}*/}\n              {/*    >*/}\n              {/*      {row.coinBInfo?.simpleName}*/}\n              {/*    </Typography>*/}\n              {/*  </Typography>*/}\n              {/*  {campaignTagConfig && (*/}\n              {/*    <TagIconList*/}\n              {/*      scenario={SCENARIO.AMM}*/}\n              {/*      campaignTagConfig={campaignTagConfig}*/}\n              {/*      symbol={row.market}*/}\n              {/*    />*/}\n              {/*  )}*/}\n              {/*  {row.isNew && <NewTagIcon />}*/}\n              {/*</Typography>*/}\n            </Box>\n          )\n        },\n      },\n      {\n        key: 'liquidity',\n        sortable: true,\n        headerCellClass: 'textAlignRight',\n        name: t('labelLiquidity'),\n        formatter: ({ row }) => {\n          const { coinA, coinB, totalA, totalB, amountU } = row as any\n          return (\n            <Box\n              className={'textAlignRight'}\n              display={'flex'}\n              flexDirection={'column'}\n              height={'100%'}\n              justifyContent={'center'}\n            >\n              <Typography component={'span'}>\n                {typeof amountU === 'undefined' || !Number(amountU)\n                  ? EmptyValueTag\n                  : PriceTag[CurrencyToTag[currency]] +\n                    getValuePrecisionThousand(\n                      sdk.toBig(amountU).times(forexValue),\n                      undefined,\n                      undefined,\n                      2,\n                      true,\n                      { isFait: true },\n                    )}\n              </Typography>\n              <Typography component={'span'} variant={'body2'} color={'textSecondary'}>\n                {getValuePrecisionThousand(totalA, undefined, 2, 2, true, {\n                  isAbbreviate: true,\n                  abbreviate: 3,\n                }) +\n                  ' ' +\n                  coinA +\n                  `  +  ` +\n                  getValuePrecisionThousand(totalB, undefined, 2, 2, true, {\n                    isAbbreviate: true,\n                    abbreviate: 3,\n                  }) +\n                  ' ' +\n                  coinB}\n              </Typography>\n            </Box>\n          )\n        },\n      },\n      {\n        key: 'volume24',\n        sortable: true,\n        width: 'auto',\n        headerCellClass: 'textAlignRight',\n        name: t('label24VolumeSimple', { ns: 'common' }) + '/' + t('labelAPR'),\n        formatter: ({ row }) => {\n          const { priceU } = row?.tradeFloat ?? {}\n          const APR = typeof row.APR !== undefined && row.APR ? row?.APR : EmptyValueTag\n\n          return (\n            <Box\n              className={'textAlignRight'}\n              display={'flex'}\n              flexDirection={'column'}\n              justifyContent={'center'}\n              height={'100%'}\n              alignItems={'flex-end'}\n            >\n              <Box className={'textAlignRight'} display={'inline-flex'}>\n                <Typography component={'span'}>\n                  {priceU\n                    ? PriceTag[CurrencyToTag[currency]] +\n                      getValuePrecisionThousand(\n                        sdk.toBig(priceU).times(forexValue),\n                        undefined,\n                        undefined,\n                        2,\n                        true,\n                        { isFait: true },\n                      )\n                    : EmptyValueTag}\n                </Typography>\n              </Box>\n              <Typography component={'span'} variant={'body2'} color={'textSecondary'}>\n                APR:\n                {APR === EmptyValueTag || typeof APR === 'undefined'\n                  ? EmptyValueTag\n                  : getValuePrecisionThousand(APR, 2, 2, 2, true) + '%'}\n              </Typography>\n            </Box>\n          )\n        },\n      },\n      {\n        key: 'action',\n        name: '',\n        headerCellClass: 'textAlignRight',\n        formatter: ({ row }) => {\n          const popoverProps: PopoverWrapProps = {\n            type: PopoverType.click,\n            popupId: 'testPopup',\n            className: 'arrow-none',\n            children: <MoreIcon cursor={'pointer'} />,\n            popoverContent: <ActionPopContent {...{ row, allowTrade: toggle,handleWithdraw, handleDeposit, t }} />,\n            anchorOrigin: {\n              vertical: 'bottom',\n              horizontal: 'right',\n            },\n            transformOrigin: {\n              vertical: 'top',\n              horizontal: 'right',\n            },\n          } as PopoverWrapProps\n          return (\n            <Grid item marginTop={1}>\n              <Popover {...{ ...popoverProps }} />\n            </Grid>\n          )\n        },\n      },\n    ]\n    const defaultArgs: TableProps<any, any> = {\n      rawData,\n      columnMode: isMobile ? columnModeMobile() : columnMode(),\n      generateRows: (rawData: any) => rawData,\n      generateColumns: ({ columnsRaw }) => columnsRaw as Column<T, any>[],\n    }\n    return (\n      <TableStyled flex={1} flexDirection={'column'} display={'flex'} isMobile={isMobile}>\n        <Box marginY={3} display={'flex'} justifyContent={'space-between'} alignItems={'center'}>\n          <Typography variant={isMobile ? 'h3' : 'h1'}>\n            {t('labelTitleOverviewAllPrd', { ns: 'common' })}\n          </Typography>\n          {showFilter && (\n            <Box\n              display={'inline-flex'}\n              flexDirection={'row'}\n              justifyContent={'center'}\n              paddingX={3}\n              alignItems={'center'}\n            >\n              <InputSearch\n                key={'search'}\n                className={'search'}\n                aria-label={'search'}\n                placeholder={t('labelFilter')}\n                value={filterValue}\n                onChange={(value: any) => handleFilterChange({ searchValue: value })}\n              />\n            </Box>\n          )}\n        </Box>\n\n        <Table\n          style={{\n            height: (rawData.length + 1) * RowInvestConfig.rowHeight,\n            minHeight: '350px',\n          }}\n          {...{\n            ...defaultArgs,\n            t,\n            i18n,\n            tReady,\n            ...rest,\n            rawData: rawData,\n            rowHeight: rowConfig.rowHeight,\n            rowHeaderHeight: rowConfig.rowHeaderHeight,\n            showloading: showLoading,\n            sortMethod,\n            sortDefaultKey: 'liquidity',\n          }}\n        />\n      </TableStyled>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/poolsTable/index.ts",
    "content": "export * from './PoolsTable'\nexport * from './Interface'\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/redPacketTable/Interface.ts",
    "content": "import * as sdk from '@loopring-web/loopring-sdk'\nimport { ClaimToken, CoinInfo, ForexMap, TokenType } from '@loopring-web/common-resources'\nimport { XOR } from '../../../types/lib'\n\nexport type RawDataRedPacketRecordsItem = {\n  token: (CoinInfo<any> | sdk.UserNFTBalanceInfo) & { type: TokenType }\n  type: sdk.LuckyTokenType\n  status: sdk.LuckyTokenItemStatus\n  validSince: number\n  validUntil: number\n  totalCount: number\n  remainCount: number\n  totalAmount: string\n  remainAmount: string\n  createdAt: number\n  rawData: sdk.LuckyTokenItemForReceive\n}\nexport type RawDataRedPacketReceivesItem = {\n  token: (CoinInfo<any> | sdk.UserNFTBalanceInfo) & { type: TokenType }\n  amount: string\n  type: sdk.LuckyTokenType\n  status: sdk.LuckyTokenItemStatus\n  claimAt: number\n  sender: string\n  rawData: any\n}\nexport type RawDataRedPacketBlindBoxReceivesItem = {\n  token: (CoinInfo<any> | sdk.UserNFTBalanceInfo) & { type: TokenType }\n  amount: string\n  type: sdk.LuckyTokenType\n  status: sdk.LuckyTokenItemStatus\n  claimAt: number\n  sender: string\n  rawData: any\n}\n\nexport type RawDataRedPacketClaimItem = {\n  token: CoinInfo<any> & { type: TokenType }\n  amountStr: string\n  volume: number\n  rawData: any\n}\nexport type RawDataNFTRedPacketClaimItem = Omit<RawDataRedPacketClaimItem, 'token'> & {\n  token: sdk.UserNFTBalanceInfo & { type: TokenType.nft }\n}\nexport type RawDataRedPacketDetailItem = {\n  accountStr: string\n  isSelf: boolean\n  amountStr: string\n  createdAt: number\n  rawData: any\n  isMax: boolean\n  helper?: string\n}\n\nexport type RedPacketClaimTableProps<R, C = sdk.Currency> = {\n  rawData: R[]\n  showloading: boolean\n  forexMap: ForexMap<C>\n  onItemClick: (item: ClaimToken) => void\n  onViewMoreClick?: (type: 'NFTs' | 'blindbox') => void\n  etherscanBaseUrl: string\n  isNFT?: boolean\n  getClaimRedPacket: (props: any) => void\n  totalLuckyTokenNFTBalance?: number\n  hideAssets?: boolean\n  blindBoxBalance?: number\n} & XOR<\n  {\n    pagination?: {\n      pageSize: number\n      total: number\n    }\n    page?: number\n  },\n  {}\n>\n\nexport interface RedPacketRecordsTableProps<R, C = sdk.Currency> {\n  rawData: R[]\n  tokenType: TokenType\n  showloading: boolean\n  forexMap: ForexMap<C>\n  onItemClick: (item: sdk.LuckyTokenItemForReceive) => void\n  etherscanBaseUrl: string\n  pagination?: {\n    pageSize: number\n    total: number\n  }\n  getMyRedPacketRecordTxList: (props: any) => void\n  tableType: 'token' | 'NFT' | 'blindbox'\n}\n\nexport interface RedPacketReceiveTableProps<R, C = sdk.Currency> {\n  rawData: R[]\n  tokenType: TokenType\n  showloading: boolean\n  forexMap: ForexMap<C>\n  etherscanBaseUrl: string\n  pagination?: {\n    pageSize: number\n    total: number\n  }\n  onItemClick: (item: sdk.LuckTokenHistory) => void\n  onClaimItem: (item: sdk.LuckTokenHistory) => void\n  getRedPacketReceiveList: (props: any) => void\n  showActionableRecords: boolean\n  isUncliamedNFT?: boolean\n  page: number\n  setPage: (item: number) => void\n}\n\nexport interface RedPacketBlindBoxReceiveTableProps<R, C = sdk.Currency> {\n  rawData: R[]\n  showloading: boolean\n  forexMap: ForexMap<C>\n  etherscanBaseUrl: string\n  pagination?: {\n    pageSize: number\n    total: number\n  }\n  onItemClick: (\n    item: sdk.LuckyTokenBlindBoxItemReceive,\n    pageInfo?: { offset: number; limit: number; filter: any },\n  ) => any\n  onItemClickOpen: (\n    item: sdk.LuckyTokenBlindBoxItemReceive,\n    pageInfo?: { offset: number; limit: number; filter: any },\n  ) => any\n  getRedPacketReceiveList: (props: any) => void\n  showActionableRecords: boolean\n  isUnclaimed?: boolean\n  page: number\n  setPage: (item: number) => void\n}\n\nexport enum LuckyTokenItemStatusMap {\n  SUBMITTING = 0,\n  NOT_EFFECTIVE = 1,\n  PENDING = 2,\n  COMPLETED = 3,\n  OVER_DUE = 4,\n  FAILED = 5,\n}\n\nexport interface aRedPacketDetailTableProps<R, C = sdk.Currency> {\n  rawData: R[]\n  showloading: boolean\n  forexMap: ForexMap<C>\n  onItemClick: (item: R) => void\n  etherscanBaseUrl: string\n  getClaimRedPacket: (props: any) => void\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/redPacketTable/RedPacketBlindBoxReceiveTable.tsx",
    "content": "import styled from '@emotion/styled'\nimport { Box, Tooltip, Typography } from '@mui/material'\nimport { TablePaddingX } from '../../styled'\nimport { BoxNFT, Button, Column, NftImageStyle, Table, TablePagination } from '../../basic-lib'\nimport {\n  CoinInfo,\n  EmptyValueTag,\n  getValuePrecisionThousand,\n  globalSetup,\n  hexToRGB,\n  myLog,\n  RowConfig,\n  TokenType,\n  YEAR_DAY_MINUTE_FORMAT,\n} from '@loopring-web/common-resources'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport {\n  RawDataRedPacketBlindBoxReceivesItem,\n  RedPacketBlindBoxReceiveTableProps,\n} from './Interface'\nimport React from 'react'\nimport { FormatterProps } from 'react-data-grid'\nimport _ from 'lodash'\nimport moment from 'moment'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { ColumnCoinDeep } from '../assetsTable'\nimport TextTooltip from './textTooltip'\nimport { useTheme } from '@emotion/react'\n\nconst TableWrapperStyled = styled(Box)`\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n  height: 100%;\n  ${({ theme }) => TablePaddingX({ pLeft: theme.unit * 3, pRight: theme.unit * 3 })}\n`\nconst TableStyled = styled(Table)<{ isUnclaimed: boolean }>`\n  &.rdg {\n    --template-columns: 25% 25% 25% 25% !important;\n\n    height: ${(props: any) => {\n      if (props.ispro === 'pro') {\n        return '620px'\n      }\n      if (props.currentheight && props.currentheight > 350) {\n        return props.currentheight + 'px'\n      } else {\n        return '100%'\n      }\n    }};\n\n    .rdg-cell.action {\n      display: flex;\n      justify-content: center;\n      align-items: center;\n    }\n  }\n\n  .textAlignRight {\n    text-align: right;\n\n    .rdg-header-sort-cell {\n      justify-content: flex-end;\n    }\n  }\n\n  .textAlignCenter {\n    text-align: center;\n  }\n` as any\nconst RowHeight = 55\nexport const RedPacketBlindBoxReceiveTable = withTranslation(['tables', 'common'])(\n  <R extends RawDataRedPacketBlindBoxReceivesItem>(\n    props: RedPacketBlindBoxReceiveTableProps<R> & WithTranslation,\n  ) => {\n    const {\n      getRedPacketReceiveList,\n      pagination,\n      rawData,\n      showloading,\n      t,\n      onItemClick,\n      showActionableRecords,\n      isUnclaimed,\n      page,\n      setPage,\n      onItemClickOpen\n    } = props\n    const updateData = _.debounce(async ({ page = 1, filter = {} }: any) => {\n      await getRedPacketReceiveList({\n        offset: (page - 1) * (pagination?.pageSize ?? 10),\n        limit: pagination?.pageSize ?? 10,\n        filter: {\n          ...filter,\n          statuses: showActionableRecords\n            ? [0] // 0 is for sdk.BlindBoxStatus.NOT_OPENED\n            : undefined,\n        },\n      })\n    }, globalSetup.wait)\n    const theme = useTheme()\n\n    const handlePageChange = React.useCallback(\n      ({ page = 1 }: any) => {\n        setPage(page)\n        myLog('RedPacket Receive page,', page)\n        updateData({\n          page,\n        })\n      },\n      [updateData],\n    )\n    React.useEffect(() => {\n      updateData.cancel()\n      handlePageChange({ page: 1 })\n      return () => {\n        updateData.cancel()\n      }\n    }, [showActionableRecords])\n    const exclusiveTag = (\n      <Typography\n        marginLeft={0.5}\n        borderRadius={1}\n        paddingX={0.5}\n        bgcolor={hexToRGB(theme.colorBase.warning, 0.5)}\n        color={'var(--color-warning)'}\n      >\n        {t('labelRedPacketExclusiveTag', { ns: 'common' })}\n      </Typography>\n    )\n    const columnModeTransaction = [\n      {\n        key: 'Token',\n        name: t('labelToken'),\n        formatter: ({ row }: FormatterProps<R>) => {\n          const isTarget = row.rawData.luckyToken.type.scope === sdk.LuckyTokenViewType.TARGET\n          if (row.rawData.luckyToken.isNft) {\n            const metadata = row.rawData.luckyToken.nftTokenInfo?.metadata\n            return (\n              <Box\n                className='rdg-cell-value'\n                height={'100%'}\n                display={'flex'}\n                alignItems={'center'}\n              >\n                {metadata?.imageSize ? (\n                  <Box display={'flex'} alignItems={'center'} justifyContent={'center'}>\n                    {metadata?.imageSize && (\n                      <NftImageStyle\n                        src={metadata?.imageSize[sdk.NFT_IMAGE_SIZES.small]}\n                        style={{\n                          width: `${theme.unit * 3}px`,\n                          height: `${theme.unit * 3}px`,\n                          borderRadius: '4px',\n                        }}\n                      />\n                    )}\n                  </Box>\n                ) : (\n                  <BoxNFT\n                    display={'flex'}\n                    alignItems={'center'}\n                    justifyContent={'center'}\n                    height={RowConfig.rowHeight + 'px'}\n                    width={RowConfig.rowHeight + 'px'}\n                  />\n                )}\n                <Typography\n                  color={'inherit'}\n                  display={'inline-block'}\n                  alignItems={'center'}\n                  paddingLeft={1}\n                  overflow={'hidden'}\n                  textOverflow={'ellipsis'}\n                  component={'span'}\n                >\n                  {metadata?.base?.name ?? 'NFT'}\n                </Typography>\n                {isTarget && exclusiveTag}\n              </Box>\n            )\n          } else {\n            const _token = row.token as CoinInfo<any> & { type: TokenType }\n            return (\n              <Box height={'100%'} display={'flex'} alignItems={'center'}>\n                <ColumnCoinDeep\n                  token={{\n                    ..._token,\n                    name: '', // for not displaying name here\n                  }}\n                />\n                {isTarget && exclusiveTag}\n              </Box>\n            )\n          }\n        },\n      },\n      {\n        key: 'Amount',\n        name: t('labelAmount'),\n        formatter: ({ row }: FormatterProps<R>) => {\n          const { token } = row\n          if (token && token.type === TokenType.single) {\n            const { decimals, precision } = token as unknown as {\n              decimals: number\n              precision: number\n            }\n            return (\n              <>\n                {row.rawData.claim.amount\n                  ? getValuePrecisionThousand(\n                      sdk.toBig(row.rawData.claim.amount).div('1e' + decimals),\n                      precision,\n                      precision,\n                      precision,\n                      false,\n                    )\n                  : EmptyValueTag}\n              </>\n            )\n          } else {\n            return <>{row.rawData.claim.amount ? row.rawData.claim.amount : EmptyValueTag}</>\n          }\n        },\n      },\n      {\n        key: 'ReceiveTime',\n        cellClass: 'textAlignRight',\n        headerCellClass: 'textAlignRight',\n        name: t('labelReceiveTime'),\n        formatter: ({ row }: FormatterProps<R>) => {\n          return <>{moment(new Date(row.claimAt), 'YYYYMMDDHHMM').fromNow()}</>\n        },\n      },\n      {\n        key: 'Status',\n        cellClass: 'textAlignRight',\n        headerCellClass: 'textAlignRight',\n        name: t('labelRecordStatus'),\n        formatter: ({ row }: FormatterProps<R>) => {\n          if (row.rawData.luckyToken.validUntil > Date.now()) {\n            return (\n              <Tooltip\n                title={\n                  <>\n                    {t('labelRedpacketCantOpen', {\n                      time: moment(row.rawData.luckyToken.validUntil).format(\n                        YEAR_DAY_MINUTE_FORMAT,\n                      ),\n                      interpolation: {\n                        escapeValue: false,\n                      },\n                    })}\n                  </>\n                }\n              >\n                <span style={{ borderBottom: '1px dotted' }}>\n                  {t('labelRedPacketOpen', { ns: 'common' })}\n                </span>\n              </Tooltip>\n            )\n          } else if (row.rawData.claim.status === sdk.BlindBoxStatus.OPENED) {\n            return <>{t('labelBlindBoxOpend')}</>\n          } else if (row.rawData.claim.status === sdk.BlindBoxStatus.EXPIRED) {\n            return <>{t('labelBlindBoxExpired')}</>\n          } else if (row.rawData.claim.status === sdk.BlindBoxStatus.NOT_OPENED) {\n            return (\n              <Box display={'flex'} flexDirection={'column'} alignItems={'end'}>\n                <Button size={'small'} onClick={(_e) => {\n                  _e.stopPropagation()\n                  onItemClickOpen(row.rawData, {\n                    offset: (page - 1) * (pagination?.pageSize ?? 10),\n                    limit: pagination?.pageSize ?? 10,\n                    filter: {\n                      statuses: showActionableRecords\n                        ? [0] // 0 is for sdk.BlindBoxStatus.NOT_OPENED\n                        : undefined,\n                    },\n                  })\n                }} variant={'text'}>\n                  {t('labelRedPacketOpen', { ns: 'common' })}\n                </Button>\n                <Typography>\n                  {t('labelBlindBoxExpiredTime', {\n                    time: moment(row.rawData.luckyToken.nftExpireTime).format(\n                      YEAR_DAY_MINUTE_FORMAT,\n                    ),\n                    interpolation: {\n                      escapeValue: false,\n                    },\n                  })}\n                </Typography>\n              </Box>\n            )\n          }\n        },\n      },\n    ] as Column<R, unknown>[]\n    const columnModeTransactionUnClaimed = [\n      {\n        key: 'Token',\n        name: t('labelToken'),\n        formatter: ({ row }: FormatterProps<R>) => {\n          if (row.rawData.luckyToken.isNft) {\n            const metadata = row.rawData.luckyToken.nftTokenInfo?.metadata\n            return (\n              <Box\n                className='rdg-cell-value'\n                height={'100%'}\n                display={'flex'}\n                alignItems={'center'}\n              >\n                {metadata?.imageSize ? (\n                  <Box display={'flex'} alignItems={'center'} justifyContent={'center'}>\n                    {metadata?.imageSize && (\n                      <NftImageStyle\n                        src={metadata?.imageSize[sdk.NFT_IMAGE_SIZES.small]}\n                        style={{\n                          width: `${theme.unit * 3}px`,\n                          height: `${theme.unit * 3}px`,\n                          borderRadius: '4px',\n                        }}\n                      />\n                    )}\n                  </Box>\n                ) : (\n                  <BoxNFT\n                    display={'flex'}\n                    alignItems={'center'}\n                    justifyContent={'center'}\n                    height={RowConfig.rowHeight + 'px'}\n                    width={RowConfig.rowHeight + 'px'}\n                  />\n                )}\n                <Typography\n                  color={'inherit'}\n                  flex={1}\n                  display={'inline-block'}\n                  alignItems={'center'}\n                  paddingLeft={1}\n                  overflow={'hidden'}\n                  textOverflow={'ellipsis'}\n                  component={'span'}\n                >\n                  {metadata?.base?.name ?? 'NFT'}\n                </Typography>\n              </Box>\n            )\n          } else {\n            const _token = row.token as CoinInfo<any> & { type: TokenType }\n            return (\n              <ColumnCoinDeep\n                token={{\n                  ..._token,\n                  name: '', // for not displaying name here\n                }}\n              />\n            )\n          }\n        },\n      },\n      {\n        key: 'RevealTime',\n        cellClass: 'textAlignRight',\n        headerCellClass: 'textAlignRight',\n        name: (\n          <TextTooltip text={t('labelRevealTime')} tooltipTitle={t('labelRevealTimeTooltip')} />\n        ),\n        formatter: ({ row }: FormatterProps<R>) => {\n          return (\n            <>\n              {moment(new Date(row.rawData.luckyToken.validUntil)).format(YEAR_DAY_MINUTE_FORMAT)}\n            </>\n          )\n        },\n      },\n\n      {\n        key: 'ExpiredTime',\n        cellClass: 'textAlignRight',\n        headerCellClass: 'textAlignRight',\n        name: (\n          <TextTooltip text={t('labelExpiredTime')} tooltipTitle={t('labelExpiredTimeTooltip')} />\n        ),\n        formatter: ({ row }: FormatterProps<R>) => {\n          return (\n            <>{moment(new Date(row.rawData.claim.expireTime)).format(YEAR_DAY_MINUTE_FORMAT)}</>\n          )\n        },\n      },\n      {\n        key: 'Status',\n        cellClass: 'textAlignRight',\n        headerCellClass: 'textAlignRight',\n        name: t('labelAction'),\n        formatter: ({ row }: FormatterProps<R>) => {\n          if (row.rawData.luckyToken.validUntil > Date.now()) {\n            return (\n              <Tooltip\n                title={\n                  <>\n                    {t('labelRedpacketCantOpen', {\n                      time: moment(row.rawData.luckyToken.validUntil).format(\n                        YEAR_DAY_MINUTE_FORMAT,\n                      ),\n                      interpolation: {\n                        escapeValue: false,\n                      },\n                    })}\n                  </>\n                }\n              >\n                <span style={{ borderBottom: '1px dotted', marginRight: `${theme.unit * 2}px` }}>\n                  {t('labelRedPacketOpen', { ns: 'common' })}\n                </span>\n              </Tooltip>\n            )\n          } else if (row.rawData.claim.status === sdk.BlindBoxStatus.OPENED) {\n            return <>{t('labelBlindBoxOpend')}</>\n          } else if (row.rawData.claim.status === sdk.BlindBoxStatus.EXPIRED) {\n            return <>{t('labelBlindBoxExpired')}</>\n          } else if (row.rawData.claim.status === sdk.BlindBoxStatus.NOT_OPENED) {\n            return (\n              <Button size={'small'} onClick={(_e) => {\n                _e.stopPropagation()\n                onItemClickOpen(row.rawData, {\n                  offset: (page - 1) * (pagination?.pageSize ?? 10),\n                  limit: pagination?.pageSize ?? 10,\n                  filter: {\n                    statuses: showActionableRecords\n                      ? [0] // 0 is for sdk.BlindBoxStatus.NOT_OPENED\n                      : undefined,\n                  },\n                })\n              }} variant={'text'}>\n                {t('labelRedPacketOpen', { ns: 'common' })}\n              </Button>\n            )\n          }\n        },\n      },\n    ] as Column<R, unknown>[]\n    const defaultArgs: any = {\n      columnMode: isUnclaimed ? columnModeTransactionUnClaimed : columnModeTransaction,\n      generateRows: (rawData: any) => rawData,\n      generateColumns: ({ columnsRaw }: any) => columnsRaw as Column<any, unknown>[],\n    }\n\n    return (\n      <TableWrapperStyled>\n        <TableStyled\n          isUnclaimed={isUnclaimed}\n          currentheight={RowConfig.rowHeaderHeight + rawData.length * RowHeight}\n          rowHeight={RowHeight}\n          onRowClick={(_index: number, row: R) => {\n            onItemClick(row.rawData, {\n              offset: (page - 1) * (pagination?.pageSize ?? 10),\n              limit: pagination?.pageSize ?? 10,\n              filter: {\n                statuses: showActionableRecords\n                  ? [0] // 0 is for sdk.BlindBoxStatus.NOT_OPENED\n                  : undefined,\n              },\n            })\n          }}\n          sortMethod={React.useCallback(\n            (_sortedRows, sortColumn) => {\n              let resultRows: R[] = []\n              switch (sortColumn) {\n                case 'Token':\n                  resultRows = rawData.sort((a: R, b: R) => {\n                    if (a.token.type == TokenType.nft) {\n                      return (a.token as any)?.metadata?.base?.name?.localeCompare(\n                        (b.token as any)?.metadata?.base?.name,\n                      )\n                    } else {\n                      return (a.token as any)?.simpleName.localeCompare(\n                        (b.token as any)?.simpleName,\n                      )\n                    }\n                  })\n                  break\n                case 'Amount':\n                  resultRows = rawData.sort((a: R, b: R) => {\n                    return a.amount.localeCompare(b.amount)\n                  })\n                  break\n                case 'Time':\n                  resultRows = rawData.sort((a: R, b: R) => {\n                    return b.claimAt - a.claimAt\n                  })\n                  break\n                default:\n              }\n              return resultRows\n            },\n            [rawData],\n          )}\n          headerRowHeight={RowConfig.rowHeaderHeight}\n          {...{\n            ...defaultArgs,\n            // rowRenderer: RowRenderer,\n            ...props,\n\n            rawData,\n            showloading,\n          }}\n        />\n        {!!(pagination && pagination.total) && (\n          <TablePagination\n            page={page}\n            pageSize={pagination.pageSize}\n            total={pagination.total}\n            onPageChange={(page) => handlePageChange({ page })}\n          />\n        )}\n      </TableWrapperStyled>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/redPacketTable/RedPacketClaimTable.tsx",
    "content": "import styled from '@emotion/styled'\nimport { Box, Link, Typography } from '@mui/material'\nimport { TablePaddingX } from '../../styled'\nimport { Column, NftImage, Table, TablePagination } from '../../basic-lib'\nimport { WithTranslation, withTranslation } from 'react-i18next'\n\nimport {\n  RawDataNFTRedPacketClaimItem,\n  RawDataRedPacketClaimItem,\n  RedPacketClaimTableProps,\n} from './Interface'\nimport { useHistory } from 'react-router-dom'\nimport { useSettings } from '../../../stores'\nimport React from 'react'\nimport { FormatterProps } from 'react-data-grid'\nimport {\n  CurrencyToTag,\n  EmptyValueTag,\n  getValuePrecisionThousand,\n  globalSetup,\n  HiddenTag,\n  myLog,\n  PriceTag,\n  RowConfig,\n  TokenType,\n} from '@loopring-web/common-resources'\nimport { ColumnCoinDeep } from '../assetsTable'\nimport _ from 'lodash'\nimport { useTheme } from '@emotion/react'\nimport { SoursURL } from '@loopring-web/loopring-sdk'\n\nconst TableWrapperStyled = styled(Box)`\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n  height: 99%;\n  ${({ theme }) => TablePaddingX({ pLeft: theme.unit * 3, pRight: theme.unit * 3 })}\n`\nconst TableStyled = styled(Table)`\n  &.rdg {\n    height: ${(props: any) => {\n      if (props.ispro === 'pro') {\n        return '620px'\n      }\n      if (props.currentheight && props.currentheight > 350) {\n        return props.currentheight + 'px'\n      } else {\n        return '100%'\n      }\n    }};\n\n    .rdg-cell.action {\n      display: flex;\n      justify-content: center;\n      align-items: center;\n    }\n  }\n\n  .textAlignRight {\n    text-align: right;\n\n    .rdg-header-sort-cell {\n      justify-content: flex-end;\n    }\n  }\n\n  .textAlignCenter {\n    text-align: center;\n  }\n` as any\n\nexport const RedPacketClaimTable = withTranslation(['tables', 'common'])(\n  <R extends RawDataRedPacketClaimItem | RawDataNFTRedPacketClaimItem>(\n    props: RedPacketClaimTableProps<R> & WithTranslation,\n  ) => {\n    const {\n      rawData,\n      forexMap,\n      showloading,\n      onItemClick,\n      onViewMoreClick,\n      getClaimRedPacket,\n      pagination,\n      page,\n      isNFT = false,\n      totalLuckyTokenNFTBalance,\n      hideAssets,\n      blindBoxBalance,\n      t,\n    } = props\n    const history = useHistory()\n    const { currency } = useSettings()\n    const updateData = _.debounce(async ({ page = 1 }: any) => {\n      await getClaimRedPacket({\n        offset: (page - 1) * (pagination?.pageSize ?? 10),\n        limit: pagination?.pageSize ?? 10,\n      })\n    }, globalSetup.wait)\n\n    const handlePageChange = React.useCallback(\n      ({ page = 1 }: any) => {\n        myLog('RedPacket Receive page,', page)\n        updateData({\n          page,\n        })\n      },\n      [updateData],\n    )\n    React.useEffect(() => {\n      updateData.cancel()\n      handlePageChange({ page: 1 })\n      // updateData({});\n      return () => {\n        updateData.cancel()\n      }\n    }, [])\n    const theme = useTheme()\n    const getColumnModeTransaction = React.useCallback((): Column<R, unknown>[] => {\n      return [\n        {\n          key: 'Token',\n          sortable: true,\n          cellClass: 'textAlignLeft',\n          headerCellClass: 'textAlignLeft',\n          name: t('labelToken'),\n          formatter: ({ row: { token } }: FormatterProps<R>) => {\n            if (token.type !== TokenType.nft) {\n              if ((token.icon && token.simpleName === 'NFTs') || token.simpleName === 'Blind Box') {\n                return (\n                  <Box\n                    className='rdg-cell-value'\n                    height={'100%'}\n                    display={'flex'}\n                    alignItems={'center'}\n                  >\n                    <Box\n                      display={'flex'}\n                      alignItems={'center'}\n                      justifyContent={'center'}\n                      // style={{ background: \"var(--field-opacity)\" }}\n                    >\n                      <NftImage\n                        alt={token.simpleName}\n                        onError={() => undefined}\n                        src={token.icon}\n                        width={28}\n                        height={28}\n                      />\n                    </Box>\n                    <Typography\n                      color={'inherit'}\n                      flex={1}\n                      display={'inline-flex'}\n                      alignItems={'center'}\n                      marginLeft={0.5}\n                      overflow={'hidden'}\n                      textOverflow={'ellipsis'}\n                      component={'span'}\n                    >\n                      {token.simpleName}\n                    </Typography>\n                  </Box>\n                )\n              } else {\n                return <ColumnCoinDeep isNotRequiredName={true} token={token as any} />\n              }\n            } else {\n              return <></>\n            }\n          },\n        },\n        {\n          key: 'Amount',\n          sortable: true,\n          name: t('labelAmount'),\n          formatter: ({ row }: FormatterProps<R>) => {\n            return <Box display={'flex'}>{hideAssets ? HiddenTag : row.amountStr}</Box>\n          },\n        },\n        {\n          key: 'Value',\n          sortable: true,\n          name: t('labelValue'),\n          formatter: ({ row }: FormatterProps<R>) => {\n            return (\n              <Box display='flex'>\n                {row.volume !== undefined\n                  ? hideAssets\n                    ? HiddenTag\n                    : PriceTag[CurrencyToTag[currency]] +\n                      getValuePrecisionThousand(\n                        (row.volume || 0) * (forexMap[currency] ?? 0),\n                        2,\n                        2,\n                        2,\n                        true,\n                        { isFait: true },\n                      )\n                  : EmptyValueTag}\n              </Box>\n            )\n          },\n        },\n        {\n          key: 'Actions',\n          name: t('labelActions'),\n          headerCellClass: 'textAlignRight',\n          cellClass: 'textAlignRight',\n          formatter: ({ row }) => {\n            if (row.token.type === TokenType.single && row.token.name === 'NFTs') {\n              return <Link onClick={() => onViewMoreClick!('NFTs')}>View More</Link>\n            } else if (row.token.type === TokenType.single && row.token.name === 'Blind Box') {\n              return <Link onClick={() => onViewMoreClick!('blindbox')}>View More</Link>\n            } else {\n              return <Link onClick={() => onItemClick(row.rawData)}>{t('labelClaim')}</Link>\n            }\n          },\n        },\n      ]\n    }, [history, t, hideAssets, currency])\n\n    const NFTrow = {\n      token: {\n        icon:\n          theme.mode === 'dark'\n            ? SoursURL + 'images/nft_dark.png'\n            : SoursURL + 'images/nft_light.png',\n        name: 'NFTs',\n        simpleName: 'NFTs',\n        description: '',\n        company: '',\n        type: TokenType.single,\n      },\n      amountStr: totalLuckyTokenNFTBalance ? totalLuckyTokenNFTBalance.toString() : EmptyValueTag,\n      volume: undefined,\n    }\n\n    const blindboxRow = {\n      token: {\n        icon:\n          theme.mode === 'dark'\n            ? SoursURL + 'images/blindbox_dark.png'\n            : SoursURL + 'images/blindbox_light.png',\n        name: 'Blind Box',\n        simpleName: 'Blind Box',\n        description: '',\n        company: '',\n        type: TokenType.single,\n      },\n      amountStr: blindBoxBalance ? blindBoxBalance.toString() : EmptyValueTag,\n      volume: undefined,\n    }\n    const defaultArgs: any = {\n      columnMode: getColumnModeTransaction(),\n      generateRows: (rawData: any) => rawData,\n      generateColumns: ({ columnsRaw }: any) => columnsRaw as Column<any, unknown>[],\n    }\n    const sortMethod = React.useCallback(\n      (_sortedRows, sortColumn) => {\n        let resultRows: R[] = []\n        switch (sortColumn) {\n          case 'Token':\n            resultRows = rawData.sort((a: R, b: R) => {\n              if (a.token.type == TokenType.nft) {\n                return (a.token as any)?.metadata?.base?.name?.localeCompare(\n                  (b.token as any)?.metadata?.base?.name,\n                )\n              } else {\n                return (a.token as any)?.simpleName.localeCompare((b.token as any)?.simpleName)\n              }\n            })\n            break\n          case 'Amount':\n            resultRows = rawData.sort((a: R, b: R) => {\n              return a.amountStr.localeCompare(b.amountStr)\n            })\n            break\n          case 'Value':\n            resultRows = rawData.sort((a: R, b: R) => {\n              return b.volume - a.volume\n            })\n            break\n          default:\n        }\n        return resultRows\n      },\n      [rawData],\n    )\n\n    return (\n      <TableWrapperStyled>\n        <TableStyled\n          currentheight={\n            pagination\n              ? undefined\n              : RowConfig.rowHeaderHeight + rawData.length * RowConfig.rowHeight\n          }\n          rowHeight={RowConfig.rowHeight}\n          headerRowHeight={RowConfig.rowHeaderHeight}\n          onRowClick={(_index: number, row: R) => {\n            const isNFTsOrBlindbox =\n              row.token.type === TokenType.single &&\n              (row.token.name === 'NFTs' || row.token.name === 'Blind Box')\n            if (!isNFTsOrBlindbox) {\n              onItemClick(row.rawData)\n            }\n          }}\n          sortMethod={sortMethod}\n          {...{\n            ...defaultArgs,\n            // rowRenderer: RowRenderer,\n            ...props,\n\n            rawData: [\n              ...(isNFT ? [] : [NFTrow, blindboxRow]), // if isNFT then not show nft row, else shows.\n              ...rawData,\n            ],\n            showloading,\n          }}\n        />\n        {!!(pagination && pagination.total && page !== undefined) && (\n          <TablePagination\n            page={page}\n            pageSize={pagination.pageSize}\n            total={pagination.total}\n            onPageChange={(page) => handlePageChange({ page })}\n          />\n        )}\n      </TableWrapperStyled>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/redPacketTable/RedPacketReceiveTable.tsx",
    "content": "import styled from '@emotion/styled'\nimport { Box, Tooltip, Typography } from '@mui/material'\nimport { TablePaddingX } from '../../styled'\nimport { BoxNFT, Button, Column, NftImageStyle, Table, TablePagination } from '../../basic-lib'\nimport {\n  CoinInfo,\n  globalSetup,\n  hexToRGB,\n  myLog,\n  RowConfig,\n  TokenType,\n  YEAR_DAY_MINUTE_FORMAT,\n} from '@loopring-web/common-resources'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport { RawDataRedPacketReceivesItem, RedPacketReceiveTableProps } from './Interface'\nimport { useHistory } from 'react-router-dom'\nimport React from 'react'\nimport { FormatterProps } from 'react-data-grid'\nimport _ from 'lodash'\nimport moment from 'moment'\nimport { ColumnCoinDeep } from '../assetsTable'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport TextTooltip from './textTooltip'\nimport { useTheme } from '@emotion/react'\n\nconst TableWrapperStyled = styled(Box)`\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n  height: 100%;\n  ${({ theme }) => TablePaddingX({ pLeft: theme.unit * 3, pRight: theme.unit * 3 })}\n`\nconst TableStyled = styled(Table)<{ isUnClaimedNFT: boolean; isNFT: boolean }>`\n  &.rdg {\n    --template-columns: ${({ isUnClaimedNFT, isNFT }) =>\n      isUnClaimedNFT\n        ? '25% 25% 25% 25% !important'\n        : isNFT\n        ? '25% 25% 25% 25% !important'\n        : '33% 33% 33% !important'};\n\n    height: ${(props: any) => {\n      if (props.ispro === 'pro') {\n        return '620px'\n      }\n      if (props.currentheight && props.currentheight > 350) {\n        return props.currentheight + 'px'\n      } else {\n        return '100%'\n      }\n    }};\n\n    .rdg-cell.action {\n      display: flex;\n      justify-content: center;\n      align-items: center;\n    }\n  }\n\n  .textAlignRight {\n    text-align: right;\n\n    .rdg-header-sort-cell {\n      justify-content: flex-end;\n    }\n  }\n\n  .textAlignCenter {\n    text-align: center;\n  }\n` as any\n\nexport const RedPacketReceiveTable = withTranslation(['tables', 'common'])(\n  <R extends RawDataRedPacketReceivesItem>(\n    props: RedPacketReceiveTableProps<R> & WithTranslation,\n  ) => {\n    const {\n      tokenType,\n      getRedPacketReceiveList,\n      pagination,\n      rawData,\n      showloading,\n      t,\n      onItemClick,\n      onClaimItem,\n      showActionableRecords,\n      isUncliamedNFT,\n      setPage,\n      page,\n    } = props\n    // const { isMobile, upColor } = useSettings();\n    const history = useHistory()\n\n    const updateData = _.debounce(async ({ page = 1, filter = {} }: any) => {\n      await getRedPacketReceiveList({\n        offset: (page - 1) * (pagination?.pageSize ?? 12),\n        limit: pagination?.pageSize ?? 12,\n        filter: {\n          ...filter,\n          statuses: tokenType === TokenType.nft && showActionableRecords ? [0] : undefined,\n        },\n      })\n    }, globalSetup.wait)\n\n    const handlePageChange = React.useCallback(\n      ({ page = 1 }: any) => {\n        setPage(page)\n        myLog('RedPacket Receive page,', page)\n        updateData({\n          page,\n          filter: { isNft: tokenType === TokenType.nft },\n        })\n      },\n      [updateData, tokenType],\n    )\n    React.useEffect(() => {\n      updateData.cancel()\n      handlePageChange({ page: 1 })\n      return () => {\n        updateData.cancel()\n      }\n    }, [tokenType, showActionableRecords])\n    const theme = useTheme()\n    const fromBlindboxTag = (\n      <Tooltip title={<>{t('labelRedpacketFromBlindbox')}</>}>\n        <img\n          width={24}\n          height={24}\n          style={{ marginLeft: `${theme.unit}px` }}\n          src={\n            theme.mode === 'dark'\n              ? sdk.SoursURL + '/images/from_blindbox_dark.png'\n              : sdk.SoursURL + '/images/from_blindbox_light.png'\n          }\n        />\n      </Tooltip>\n    )\n    const exclusiveTag = (\n      <Typography\n        marginLeft={0.5}\n        borderRadius={1}\n        paddingX={0.5}\n        bgcolor={hexToRGB(theme.colorBase.warning, 0.5)}\n        color={'var(--color-warning)'}\n      >\n        {t('labelRedPacketExclusiveTag', { ns: 'common' })}\n      </Typography>\n    )\n    const getColumnModeTransactionUnclaimedNFT = React.useCallback(\n      (): Column<R, unknown>[] => [\n        {\n          key: 'Token',\n          cellClass: 'textAlignLeft',\n          headerCellClass: 'textAlignLeft',\n          name: t('labelToken'),\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            const { token } = row\n            const { metadata } = token as sdk.UserNFTBalanceInfo\n            return (\n              <Box\n                className='rdg-cell-value'\n                height={'100%'}\n                display={'flex'}\n                alignItems={'center'}\n              >\n                {metadata?.imageSize ? (\n                  <Box display={'flex'} alignItems={'center'} justifyContent={'center'}>\n                    {metadata?.imageSize && (\n                      <NftImageStyle\n                        src={metadata?.imageSize[sdk.NFT_IMAGE_SIZES.small]}\n                        style={{\n                          width: `${theme.unit * 3}px`,\n                          height: `${theme.unit * 3}px`,\n                          borderRadius: '4px',\n                        }}\n                      />\n                    )}\n                  </Box>\n                ) : (\n                  <BoxNFT\n                    display={'flex'}\n                    alignItems={'center'}\n                    justifyContent={'center'}\n                    height={RowConfig.rowHeight + 'px'}\n                    width={RowConfig.rowHeight + 'px'}\n                  />\n                )}\n                <Typography\n                  color={'inherit'}\n                  display={'inline-block'}\n                  alignItems={'center'}\n                  paddingLeft={1}\n                  overflow={'hidden'}\n                  textOverflow={'ellipsis'}\n                  component={'span'}\n                >\n                  {metadata?.base?.name ?? 'NFT'}\n                </Typography>\n                {row.type.mode === sdk.LuckyTokenClaimType.BLIND_BOX && fromBlindboxTag}\n                {row.type.scope === sdk.LuckyTokenViewType.TARGET && exclusiveTag}\n              </Box>\n            )\n          },\n        },\n        {\n          key: 'Amount',\n          cellClass: 'textAlignCenter',\n          headerCellClass: 'textAlignCenter',\n          name: t('labelAmount'),\n          formatter: ({ row }: FormatterProps<R>) => {\n            return <>{`${row.amount}`}</>\n          },\n        },\n        {\n          key: 'ExpiredTime',\n          name: (\n            <TextTooltip text={t('labelExpiredTime')} tooltipTitle={t('labelExpiredTimeTooltip')} />\n          ),\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            return (\n              <>{moment(new Date(row.rawData.claim.expireTime)).format(YEAR_DAY_MINUTE_FORMAT)}</>\n            )\n          },\n        },\n        {\n          key: 'Action',\n          cellClass: 'textAlignRight',\n          headerCellClass: 'textAlignRight',\n          name: 'Action',\n          formatter: ({ row }: FormatterProps<R>) => {\n            if (row.rawData.claim.status === sdk.ClaimRecordStatus.WAITING_CLAIM) {\n              return (\n                <Button\n                  onClick={(e) => {\n                    e.stopPropagation()\n                    onClaimItem(row.rawData)\n                  }}\n                >\n                  {t('labelBlindBoxCalim')}\n                </Button>\n              )\n            } else if (row.rawData.claim.status === sdk.ClaimRecordStatus.EXPIRED) {\n              return <Box>{t('labelBlindBoxExpired')}</Box>\n            } else if (row.rawData.claim.status === sdk.ClaimRecordStatus.CLAIMED) {\n              return <Box>{t('labelBlindBoxClaimed')}</Box>\n            } else if (row.rawData.claim.status === sdk.ClaimRecordStatus.CLAIMING) {\n              return <Box>{t('labelRedPacketClaiming')}</Box>\n            }\n            return <></>\n          },\n        },\n      ],\n      [history, t, tokenType],\n    )\n    const getColumnModeTransaction = React.useCallback(\n      (): Column<R, unknown>[] => [\n        {\n          key: 'Token',\n          cellClass: 'textAlignLeft',\n          headerCellClass: 'textAlignLeft',\n          name: t('labelToken'),\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            const { token } = row\n            if (token.type === TokenType.single) {\n              const _token = token as CoinInfo<any> & { type: TokenType }\n              return (\n                <Box height={'100%'} display={'flex'} alignItems={'center'}>\n                  <ColumnCoinDeep\n                    token={{\n                      ..._token,\n                      name: '', // for not displaying name here\n                    }}\n                  />\n                  {row.type.mode === sdk.LuckyTokenClaimType.BLIND_BOX && fromBlindboxTag}\n                  {row.type.scope === sdk.LuckyTokenViewType.TARGET && exclusiveTag}\n                </Box>\n              )\n            } else {\n              const { metadata } = token as sdk.UserNFTBalanceInfo\n              return (\n                <Box\n                  className='rdg-cell-value'\n                  height={'100%'}\n                  display={'flex'}\n                  alignItems={'center'}\n                >\n                  {metadata?.imageSize ? (\n                    <Box\n                      display={'flex'}\n                      alignItems={'center'}\n                      justifyContent={'center'}\n                      height={RowConfig.rowHeight + 'px'}\n                      width={RowConfig.rowHeight + 'px'}\n                      padding={1 / 4}\n                    >\n                      {metadata?.imageSize && (\n                        <NftImageStyle\n                          src={metadata?.imageSize[sdk.NFT_IMAGE_SIZES.small]}\n                          style={{\n                            width: `${theme.unit * 3}px`,\n                            height: `${theme.unit * 3}px`,\n                            borderRadius: '4px',\n                          }}\n                        />\n                      )}\n                    </Box>\n                  ) : (\n                    <BoxNFT\n                      display={'flex'}\n                      alignItems={'center'}\n                      justifyContent={'center'}\n                      height={RowConfig.rowHeight + 'px'}\n                      width={RowConfig.rowHeight + 'px'}\n                    />\n                  )}\n                  <Typography\n                    color={'inherit'}\n                    display={'inline-block'}\n                    alignItems={'center'}\n                    paddingLeft={1}\n                    overflow={'hidden'}\n                    textOverflow={'ellipsis'}\n                    component={'span'}\n                  >\n                    {metadata?.base?.name ?? 'NFT'}\n                  </Typography>\n                  {row.type.mode === sdk.LuckyTokenClaimType.BLIND_BOX && fromBlindboxTag}\n                  {row.type.scope === sdk.LuckyTokenViewType.TARGET && exclusiveTag}\n                </Box>\n              )\n            }\n          },\n        },\n        {\n          key: 'Amount',\n          cellClass: 'textAlignCenter',\n          headerCellClass: 'textAlignCenter',\n          name: t('labelAmount'),\n          formatter: ({ row }: FormatterProps<R>) => {\n            return <>{`${row.amount}`}</>\n          },\n        },\n        ...(tokenType === TokenType.nft\n          ? [\n              {\n                key: 'Action',\n                cellClass: 'textAlignRight',\n                headerCellClass: 'textAlignRight',\n                name: t('labelRecordStatus'),\n                formatter: ({ row }: FormatterProps<R>) => {\n                  if (row.rawData.claim.status === sdk.ClaimRecordStatus.WAITING_CLAIM) {\n                    return (\n                      <Button\n                        onClick={(e) => {\n                          e.stopPropagation()\n                          onClaimItem(row.rawData)\n                        }}\n                      >\n                        {t('labelBlindBoxCalim')}\n                      </Button>\n                    )\n                  } else if (row.rawData.claim.status === sdk.ClaimRecordStatus.EXPIRED) {\n                    return <Box>{t('labelBlindBoxExpired')}</Box>\n                  } else if (row.rawData.claim.status === sdk.ClaimRecordStatus.CLAIMED) {\n                    return <Box>{t('labelBlindBoxClaimed')}</Box>\n                  } else if (row.rawData.claim.status === sdk.ClaimRecordStatus.CLAIMING) {\n                    return <Box>{t('labelRedPacketClaiming')}</Box>\n                  } else {\n                    return <></>\n                  }\n                },\n              },\n            ]\n          : []),\n        {\n          key: 'Time',\n          cellClass: 'textAlignRight',\n          headerCellClass: 'textAlignRight',\n          name: t('labelReceiveTime'),\n          formatter: ({ row }: FormatterProps<R>) => {\n            return <>{moment(new Date(row.claimAt), 'YYYYMMDDHHMM').fromNow()}</>\n          },\n        },\n      ],\n      [history, t, tokenType],\n    )\n\n    const defaultArgs: any = {\n      columnMode: isUncliamedNFT\n        ? getColumnModeTransactionUnclaimedNFT()\n        : getColumnModeTransaction(),\n      generateRows: (rawData: any) => rawData,\n      generateColumns: ({ columnsRaw }: any) => columnsRaw as Column<any, unknown>[],\n    }\n\n    return (\n      <TableWrapperStyled>\n        <TableStyled\n          isUnClaimedNFT={isUncliamedNFT ? true : false}\n          isNFT={tokenType === TokenType.nft}\n          currentheight={RowConfig.rowHeaderHeight + rawData.length * RowConfig.rowHeight}\n          rowHeight={RowConfig.rowHeight}\n          onRowClick={(_index: number, row: R) => {\n            onItemClick(row.rawData)\n          }}\n          sortMethod={React.useCallback(\n            (_sortedRows, sortColumn) => {\n              let resultRows: R[] = []\n              switch (sortColumn) {\n                case 'Token':\n                  resultRows = rawData.sort((a: R, b: R) => {\n                    if (a.token.type == TokenType.nft) {\n                      return (a.token as any)?.metadata?.base?.name?.localeCompare(\n                        (b.token as any)?.metadata?.base?.name,\n                      )\n                    } else {\n                      return (a.token as any)?.simpleName.localeCompare(\n                        (b.token as any)?.simpleName,\n                      )\n                    }\n                  })\n                  break\n                case 'Amount':\n                  resultRows = rawData.sort((a: R, b: R) => {\n                    return a.amount.localeCompare(b.amount)\n                  })\n                  break\n                case 'Time':\n                  resultRows = rawData.sort((a: R, b: R) => {\n                    return b.claimAt - a.claimAt\n                  })\n                  break\n                default:\n              }\n              return resultRows\n            },\n            [rawData],\n          )}\n          headerRowHeight={RowConfig.rowHeaderHeight}\n          {...{\n            ...defaultArgs,\n            // rowRenderer: RowRenderer,\n            ...props,\n\n            rawData,\n            showloading,\n          }}\n        />\n        {!!(pagination && pagination.total) && (\n          <TablePagination\n            page={page}\n            pageSize={pagination.pageSize}\n            total={pagination.total}\n            onPageChange={(page) => handlePageChange({ page })}\n          />\n        )}\n      </TableWrapperStyled>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/redPacketTable/RedPacketRecodTable.tsx",
    "content": "import styled from '@emotion/styled'\nimport { Box, Tooltip, Typography } from '@mui/material'\nimport { TablePaddingX } from '../../styled'\nimport { BoxNFT, Column, NftImageStyle, Table, TablePagination } from '../../basic-lib'\nimport { CoinInfo, globalSetup, hexToRGB, myLog, RowConfig, SoursURL, TokenType } from '@loopring-web/common-resources'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nimport {\n  LuckyTokenItemStatusMap,\n  RawDataRedPacketRecordsItem,\n  RedPacketRecordsTableProps,\n} from './Interface'\nimport { useHistory } from 'react-router-dom'\nimport React from 'react'\nimport { FormatterProps } from 'react-data-grid'\nimport _ from 'lodash'\nimport moment from 'moment'\nimport { ColumnCoinDeep } from '../assetsTable'\nimport { useTheme } from '@emotion/react'\n\nconst TableWrapperStyled = styled(Box)`\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n  height: 100%;\n  ${({ theme }) => TablePaddingX({ pLeft: theme.unit * 3, pRight: theme.unit * 3 })}\n`\nconst TableStyled = styled(Table)<{ isBlindbox: boolean }>`\n  &.rdg {\n    --template-columns: ${({ isBlindbox }) =>\n      isBlindbox ? '30% 25% 25% 20% !important' : '22% 12% 24% auto auto auto !important'};\n\n    height: ${(props: any) => {\n      if (props.ispro === 'pro') {\n        return '620px'\n      }\n      if (props.currentheight && props.currentheight > 350) {\n        return props.currentheight + 'px'\n      } else {\n        return '100%'\n      }\n    }};\n\n    .rdg-cell.action {\n      display: flex;\n      justify-content: center;\n      align-items: center;\n    }\n  }\n\n  .textAlignRight {\n    text-align: right;\n\n    .rdg-header-sort-cell {\n      justify-content: flex-end;\n    }\n  }\n\n  .textAlignCenter {\n    text-align: center;\n  }\n` as any\n\nexport const RedPacketRecordTable = withTranslation(['tables', 'common'])(\n  <R extends RawDataRedPacketRecordsItem>(\n    props: RedPacketRecordsTableProps<R> & WithTranslation,\n  ) => {\n    const {\n      getMyRedPacketRecordTxList,\n      pagination,\n      rawData,\n      showloading,\n      onItemClick,\n      tokenType,\n      tableType,\n      t,\n    } = props\n    const history = useHistory()\n    const [page, setPage] = React.useState(1)\n\n    const updateData = _.debounce(async ({ page = 1, filter = {} }: any) => {\n      await getMyRedPacketRecordTxList({\n        offset: (page - 1) * (pagination?.pageSize ?? 10),\n        limit: pagination?.pageSize ?? 10,\n        filter,\n      })\n    }, globalSetup.wait)\n\n    const handlePageChange = React.useCallback(\n      ({ page = 1 }: any) => {\n        setPage(page)\n        myLog('AmmTable page,', page)\n        updateData({\n          page,\n          filter: {\n            isNft: tableType === 'NFT' ? true : tableType === 'token' ? false : undefined,\n            modes: tableType === 'blindbox' ? 2 : [0, 1],\n          },\n        })\n      },\n      [updateData, tableType],\n    )\n    const theme = useTheme()\n    const getColumnModeTransaction = React.useCallback(\n      (): Column<R, unknown>[] => [\n        {\n          key: 'Token',\n          cellClass: 'textAlignLeft',\n          headerCellClass: 'textAlignLeft',\n          name: t('labelRecordToken'),\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            const {token} = row\n            const blindBoxTag = (\n              <Tooltip title={<>{t('labelRedpacketFromBlindbox')}</>}>\n                <img\n                  width={24}\n                  height={24}\n                  style={{ marginLeft: `${0.5 * theme.unit}px` }}\n                  src={\n                    theme.mode === 'dark'\n                      ? sdk.SoursURL + '/images/from_blindbox_dark.png'\n                      : sdk.SoursURL + '/images/from_blindbox_light.png'\n                  }\n                />\n              </Tooltip>\n            )\n            const exclusiveTag = <Typography marginLeft={0.5} borderRadius={1} paddingX={0.5} bgcolor={hexToRGB(theme.colorBase.warning, 0.5)} color={'var(--color-warning)'}>Exclusive </Typography>\n            if (token.type === TokenType.single) {\n              const _token = token as CoinInfo<any> & { type: TokenType }\n              return (\n                <Box display={'flex'} alignItems={'center'} height={'100%'}>\n                  <ColumnCoinDeep\n                    token={{\n                      ..._token,\n                      name: '', // for not displaying name here\n                    }}\n                  />\n                  {row.type.mode === sdk.LuckyTokenClaimType.BLIND_BOX && tableType !== 'blindbox' && blindBoxTag}\n                  {row.type.scope === sdk.LuckyTokenViewType.TARGET && exclusiveTag}\n                </Box>\n              )\n            } else {\n              const { metadata } = token as sdk.UserNFTBalanceInfo\n              return (\n                <Box\n                  className='rdg-cell-value'\n                  height={'100%'}\n                  display={'flex'}\n                  alignItems={'center'}\n                >\n                  {metadata?.imageSize ? (\n                    <Box display={'flex'} alignItems={'center'} justifyContent={'center'}>\n                      {metadata?.imageSize && (\n                        <NftImageStyle\n                          src={metadata?.imageSize[sdk.NFT_IMAGE_SIZES.small]}\n                          style={{\n                            width: `${theme.unit * 3}px`,\n                            height: `${theme.unit * 3}px`,\n                            borderRadius: '4px',\n                          }}\n                        />\n                      )}\n                    </Box>\n                  ) : (\n                    <BoxNFT\n                      display={'flex'}\n                      alignItems={'center'}\n                      justifyContent={'center'}\n                      height={RowConfig.rowHeight + 'px'}\n                      width={RowConfig.rowHeight + 'px'}\n                    />\n                  )}\n                  <Typography\n                    color={'inherit'}\n                    display={'inline-flex'}\n                    alignItems={'center'}\n                    paddingLeft={1}\n                    overflow={'hidden'}\n                    textOverflow={'ellipsis'}\n                    component={'span'}\n                  >\n                    {metadata?.base?.name ?? 'NFT'}\n                  </Typography>\n                  {row.type.mode === sdk.LuckyTokenClaimType.BLIND_BOX && tableType !== 'blindbox' && blindBoxTag}\n                  {row.type.scope === sdk.LuckyTokenViewType.TARGET && exclusiveTag}\n                </Box>\n              )\n            }\n          },\n        },\n        {\n          key: 'Amount',\n          name: t('labelRecordAmount'),\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            return <>{row.totalAmount}</>\n          },\n        },\n        ...(tableType !== 'blindbox'\n          ? [\n              {\n                key: 'Type',\n                name: t('labelRecordType'),\n                formatter: ({ row }: FormatterProps<R, unknown>) => {\n                  return (\n                    <>\n                      {t(\n                        row.type.mode === sdk.LuckyTokenClaimType.RELAY\n                          ? 'labelLuckyRelayToken'\n                          : row.type.mode === sdk.LuckyTokenClaimType.BLIND_BOX\n                          ? 'labelLuckyBlindBox'\n                          : row.type.partition === sdk.LuckyTokenAmountType.AVERAGE\n                          ? 'labelRedPacketSendAverageTitle'\n                          : 'labelRedPacketSenRandomTitle',\n\n                        { ns: 'common' },\n                      ) +\n                        ' — ' +\n                        t(`labelRedPacketViewType${row?.type?.scope ?? 0}`, {\n                          ns: 'common',\n                        })}\n                    </>\n                  )\n                },\n              },\n            ]\n          : []),\n\n        {\n          key: 'Status',\n          name: t('labelRecordStatus'),\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            const statusMap = [\n              [0, t(`labelRedPacketStatusNotStarted`, { ns: 'common' })],\n              [1, t(`labelRedPacketStatusNotStarted`, { ns: 'common' })],\n              [2, t(`labelRedPacketStatusStarted`, { ns: 'common' })],\n              [3, t(`labelRedPacketStatusEnded`, { ns: 'common' })],\n              [4, t(`labelRedPacketStatusEnded`, { ns: 'common' })],\n              [5, t(`labelRedPacketStatusEnded`, { ns: 'common' })],\n            ] as [number, string][]\n            const found = statusMap.find((x) => x[0] === LuckyTokenItemStatusMap[row.status])\n            return <>{found ? found[1] : ''}</>\n          },\n        },\n        ...(tableType !== 'blindbox'\n          ? [\n              {\n                key: 'Number',\n                sortable: true,\n                cellClass: 'textAlignCenter',\n                headerCellClass: 'textAlignCenter',\n                name: t('labelRecordNumber'),\n                formatter: ({ row }: FormatterProps<R, unknown>) => {\n                  return <>{`${row.totalCount - row.remainCount}/${row.totalCount}`}</>\n                },\n              },\n            ]\n          : []),\n        {\n          key: 'Time',\n          cellClass: 'textAlignRight',\n          headerCellClass: 'textAlignRight',\n          name: t('labelRecordTime'),\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            return <>{moment(new Date(row.createdAt), 'YYYYMMDDHHMM').fromNow()}</>\n          },\n        },\n      ],\n      [history, onItemClick, t],\n    )\n    React.useEffect(() => {\n      updateData.cancel()\n      handlePageChange({ page: 1 })\n      // updateData({});\n      return () => {\n        updateData.cancel()\n      }\n    }, [tokenType, tableType])\n\n    const defaultArgs: any = {\n      columnMode: getColumnModeTransaction(),\n      generateRows: (rawData: any) => rawData,\n      generateColumns: ({ columnsRaw }: any) => columnsRaw as Column<any, unknown>[],\n    }\n\n    return (\n      <TableWrapperStyled>\n        <TableStyled\n          isBlindbox={tableType === 'blindbox'}\n          currentheight={RowConfig.rowHeaderHeight + rawData.length * RowConfig.rowHeight}\n          onRowClick={(_index: number, row: R) => {\n            onItemClick(row.rawData)\n          }}\n          rowHeight={RowConfig.rowHeight}\n          headerRowHeight={RowConfig.rowHeaderHeight}\n          sortMethod={React.useCallback(\n            (_sortedRows, sortColumn) => {\n              let resultRows: R[] = []\n              switch (sortColumn) {\n                case 'Token':\n                  resultRows = rawData.sort((a: R, b: R) => {\n                    if (a.token.type == TokenType.nft) {\n                      return (a.token as any)?.metadata?.base?.name?.localeCompare(\n                        (b.token as any)?.metadata?.base?.name,\n                      )\n                    } else {\n                      return (a.token as any)?.simpleName.localeCompare(\n                        (b.token as any)?.simpleName,\n                      )\n                    }\n                  })\n                  break\n                case 'Amount':\n                  resultRows = rawData.sort((a: R, b: R) => {\n                    return a.totalAmount.localeCompare(b.totalAmount)\n                  })\n                  break\n                case 'Number':\n                  resultRows = rawData.sort((a: R, b: R) => {\n                    return b.totalCount - a.totalCount\n                  })\n                  break\n                case 'Time':\n                  resultRows = rawData.sort((a: R, b: R) => {\n                    return b.createdAt - a.createdAt\n                  })\n                  break\n                default:\n              }\n              return resultRows\n            },\n            [rawData],\n          )}\n          {...{\n            ...defaultArgs,\n            ...props,\n            rawData,\n            showloading,\n          }}\n        />\n        {!!(pagination && pagination.total) && (\n          <TablePagination\n            page={page}\n            pageSize={pagination.pageSize}\n            total={pagination.total}\n            onPageChange={(page) => handlePageChange({ page })}\n          />\n        )}\n      </TableWrapperStyled>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/redPacketTable/index.ts",
    "content": "export * from './RedPacketRecodTable'\nexport * from './RedPacketClaimTable'\nexport * from './RedPacketReceiveTable'\nexport * from './Interface'\nexport * from './RedPacketBlindBoxReceiveTable'\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/redPacketTable/textTooltip.tsx",
    "content": "import { Tooltip } from '@mui/material'\n\ntype TextTooltipProps = {\n  tooltipTitle: string\n  text: string\n}\nconst TextTooltip = ({ tooltipTitle, text }: TextTooltipProps) => {\n  return (\n    <Tooltip placement='top' title={tooltipTitle}>\n      <span style={{ borderBottom: '1px dotted' }}>{text}</span>\n    </Tooltip>\n  )\n}\nexport default TextTooltip\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/rewardTable/ReferralsTable.tsx",
    "content": "import { WithTranslation, withTranslation } from 'react-i18next'\nimport { useSettings } from '../../../stores'\nimport React from 'react'\nimport {\n  EmptyValueTag,\n  getShortAddr,\n  globalSetup,\n  RowConfig,\n  YEAR_DAY_FORMAT,\n} from '@loopring-web/common-resources'\nimport { Column, Table, TablePagination } from '../../basic-lib'\nimport { Box, BoxProps, Typography } from '@mui/material'\nimport moment from 'moment'\nimport { TablePaddingX } from '../../styled'\nimport styled from '@emotion/styled'\nimport _ from 'lodash'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nexport type ReferralsRow = sdk.ReferDownsides & {\n  amount: { unit: string; value: string }\n}\nconst TableWrapperStyled = styled(Box)<BoxProps & { isMobile: boolean }>`\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n  height: 100%;\n\n  ${({ theme }) => TablePaddingX({ pLeft: theme.unit * 3, pRight: theme.unit * 3 })}\n` as (prosp: BoxProps & { isMobile: boolean }) => JSX.Element\nconst TableStyled = styled(Table)`\n  &.rdg {\n    min-height: 240px;\n    height: ${(props: any) => {\n      return props.currentheight + 'px'\n    }};\n\n    .rdg-cell.action {\n      display: flex;\n      justify-content: center;\n      align-items: center;\n    }\n\n    .logo-icon.dual:last-child {\n      transform: scale(0.6) translate(0, 4px);\n    }\n  }\n\n  .textAlignRight {\n    text-align: right;\n\n    .rdg-header-sort-cell {\n      justify-content: flex-end;\n    }\n  }\n\n  .textAlignCenter {\n    text-align: center;\n  }\n` as any\n\nexport const ReferralsTable = withTranslation(['tables', 'common'])(\n  <R extends ReferralsRow>(\n    props: {\n      rawData: R[]\n      pagination: {\n        pageSize: number\n        total: number\n      }\n      getList: (props: { limit: number; offset: number }) => void\n      showloading: boolean\n    } & WithTranslation,\n  ) => {\n    const { rawData, pagination, getList, showloading, t } = props\n\n    const { isMobile } = useSettings()\n    const [page, setPage] = React.useState(1)\n    const updateData = _.debounce(\n      ({\n        // tableType,\n        currPage = page,\n        pageSize = pagination?.pageSize ?? 10,\n      }: {\n        // tableType: TableType;\n        currPage?: number\n        pageSize?: number\n      }) => {\n        getList({\n          limit: pageSize,\n          offset: (currPage - 1) * pageSize,\n        })\n      },\n      globalSetup.wait,\n    )\n\n    const handlePageChange = React.useCallback(\n      (currPage: number) => {\n        if (currPage === page) return\n        setPage(currPage)\n        updateData({ currPage: currPage })\n      },\n      [updateData, page],\n    )\n\n    const getColumnMode = React.useCallback(\n      (): Column<R, unknown>[] => [\n        {\n          key: 'time',\n          name: t('labelReferralsTableTime'),\n          headerCellClass: 'textAlignLeft',\n          cellClass: 'textAlignLeft',\n          formatter: ({ row }) => {\n            return (\n              <>\n                {Number.isFinite(row.startAt)\n                  ? moment(new Date(row.startAt), 'YYYYMMDDHHMM').format(YEAR_DAY_FORMAT)\n                  : EmptyValueTag}\n              </>\n            )\n          },\n        },\n        {\n          key: 'referee',\n          name: t('labelReferralsTableReferee'),\n          headerCellClass: 'textAlignCenter',\n          cellClass: 'textAlignCenter',\n          formatter: ({ row }) => {\n            return (\n              <Typography component={'span'} color={'inherit'} title={row.address}>\n                {getShortAddr(row.address)}\n              </Typography>\n            )\n          },\n        },\n        {\n          key: 'Rewards',\n          name: t('labelReferralsTableAmount'),\n          headerCellClass: 'textAlignRight',\n          cellClass: 'textAlignRight',\n          formatter: ({ row }) => {\n            return (\n              <>\n                {row.amount?.value} {row.amount?.unit}\n              </>\n            )\n          },\n        },\n      ],\n      [],\n    )\n\n    const defaultArgs: any = {\n      columnMode: getColumnMode(),\n      generateRows: (rawData: any) => rawData,\n      generateColumns: ({ columnsRaw }: any) => columnsRaw as Column<any, unknown>[],\n    }\n    React.useEffect(() => {\n      updateData.cancel()\n      updateData({ currPage: 1 })\n      return () => {\n        updateData.cancel()\n      }\n    }, [pagination?.pageSize])\n    return (\n      <TableWrapperStyled isMobile={isMobile}>\n        <TableStyled\n          currentheight={RowConfig.rowHeaderHeight + rawData.length * RowConfig.rowHeight}\n          {...{\n            ...defaultArgs,\n            // rowRenderer: RowRenderer,\n            ...props,\n            rawData,\n            showloading,\n          }}\n        />\n        {pagination && pagination.total > pagination.pageSize && (\n          <TablePagination\n            page={page}\n            pageSize={pagination.pageSize}\n            total={pagination.total}\n            onPageChange={handlePageChange}\n          />\n        )}\n      </TableWrapperStyled>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/rewardTable/RefundTable.tsx",
    "content": "import { WithTranslation, withTranslation } from 'react-i18next'\nimport { useSettings } from '../../../stores'\nimport React from 'react'\nimport {\n  EmptyValueTag,\n  globalSetup,\n  RowConfig,\n  YEAR_DAY_FORMAT,\n} from '@loopring-web/common-resources'\nimport { Column, Table, TablePagination } from '../../basic-lib'\nimport { Box, BoxProps } from '@mui/material'\nimport moment from 'moment'\nimport { TablePaddingX } from '../../styled'\nimport styled from '@emotion/styled'\nimport _ from 'lodash'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nexport type RefundRow = sdk.ReferSelf & {\n  amount: { unit: string; value: string }\n}\nconst TableWrapperStyled = styled(Box)<BoxProps & { isMobile: boolean }>`\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n  height: 100%;\n\n  ${({ theme }) => TablePaddingX({ pLeft: theme.unit * 3, pRight: theme.unit * 3 })}\n` as (prosp: BoxProps & { isMobile: boolean }) => JSX.Element\nconst TableStyled = styled(Table)`\n  &.rdg {\n    min-height: 240px;\n    height: ${(props: any) => {\n      return props.currentheight + 'px'\n    }};\n\n    .rdg-cell.action {\n      display: flex;\n      justify-content: center;\n      align-items: center;\n    }\n\n    .logo-icon.dual:last-child {\n      transform: scale(0.6) translate(0, 4px);\n    }\n  }\n\n  .textAlignRight {\n    text-align: right;\n\n    .rdg-header-sort-cell {\n      justify-content: flex-end;\n    }\n  }\n\n  .textAlignCenter {\n    text-align: center;\n  }\n` as any\n\nexport const RefundTable = withTranslation(['tables', 'common'])(\n  <R extends RefundRow>(\n    props: {\n      rawData: R[]\n      pagination: {\n        pageSize: number\n        total: number\n      }\n      getList: (props: { limit: number; offset: number }) => void\n      showloading: boolean\n    } & WithTranslation,\n  ) => {\n    const { rawData, pagination, getList, showloading, t } = props\n\n    const { isMobile } = useSettings()\n    const [page, setPage] = React.useState(1)\n    const updateData = _.debounce(\n      ({\n        // tableType,\n        currPage = page,\n        pageSize = pagination?.pageSize ?? 10,\n      }: {\n        // tableType: TableType;\n        currPage?: number\n        pageSize?: number\n      }) => {\n        getList({\n          limit: pageSize,\n          offset: (currPage - 1) * pageSize,\n        })\n      },\n      globalSetup.wait,\n    )\n\n    const handlePageChange = React.useCallback(\n      (currPage: number) => {\n        if (currPage === page) return\n        setPage(currPage)\n        updateData({ currPage: currPage })\n      },\n      [updateData, page],\n    )\n\n    const getColumnMode = React.useCallback(\n      (): Column<R, unknown>[] => [\n        {\n          key: 'time',\n          name: t('labelRefundTableTime'),\n          headerCellClass: 'textAlignLeft',\n          cellClass: 'textAlignLeft',\n          formatter: ({ row }) => {\n            return (\n              <>\n                {Number.isFinite(row.startAt)\n                  ? moment(new Date(row.startAt), 'YYYYMMDDHHMM').format(YEAR_DAY_FORMAT)\n                  : EmptyValueTag}\n              </>\n            )\n          },\n        },\n        {\n          key: 'Rewards',\n          name: t('labelRefundTableAmount'),\n          headerCellClass: 'textAlignRight',\n          cellClass: 'textAlignRight',\n          formatter: ({ row }) => {\n            return (\n              <>\n                {row.amount?.value} {row.amount?.unit}\n              </>\n            )\n          },\n        },\n      ],\n      [],\n    )\n\n    const defaultArgs: any = {\n      columnMode: getColumnMode(),\n      generateRows: (rawData: any) => rawData,\n      generateColumns: ({ columnsRaw }: any) => columnsRaw as Column<any, unknown>[],\n    }\n    React.useEffect(() => {\n      updateData.cancel()\n      updateData({ currPage: 1 })\n      return () => {\n        updateData.cancel()\n      }\n    }, [pagination?.pageSize])\n    return (\n      <TableWrapperStyled isMobile={isMobile}>\n        <TableStyled\n          currentheight={RowConfig.rowHeaderHeight + rawData.length * RowConfig.rowHeight}\n          {...{\n            ...defaultArgs,\n            ...props,\n            rawData,\n            showloading,\n          }}\n        />\n        {pagination && pagination.total > pagination.pageSize && (\n          <TablePagination\n            page={page}\n            pageSize={pagination.pageSize}\n            total={pagination.total}\n            onPageChange={handlePageChange}\n          />\n        )}\n      </TableWrapperStyled>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/rewardTable/RewardTable.tsx",
    "content": "import styled from '@emotion/styled'\nimport { Box } from '@mui/material'\nimport { TablePaddingX } from '../../styled'\nimport { TFunction, WithTranslation, withTranslation } from 'react-i18next'\nimport { Column, Table } from '../../basic-lib'\nimport moment from 'moment'\nimport { EmptyValueTag } from '@loopring-web/common-resources'\n\ninterface Row {\n  amount: string\n  time: number\n}\n\nconst TableStyled = styled(Box)`\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n  height: auto;\n\n  .rdg {\n    --template-columns: auto auto !important;\n    min-height: ${({ theme }) => theme.unit * 30}px !important;\n  }\n\n  .textAlignRight {\n    text-align: right;\n  }\n\n  ${({ theme }) => TablePaddingX({ pLeft: theme.unit * 3, pRight: theme.unit * 3 })}\n` as typeof Box\n\nconst getColumnModeRewardTable = (\n  t: TFunction,\n  chosenCardInfo?: string,\n): Column<Row, unknown>[] => {\n  return [\n    {\n      key: 'amount',\n      name: t('labelRewardTableAmount'),\n      formatter: ({ row, column }) => {\n        const value = row[column.key]\n        const renderValue = `${value} ${chosenCardInfo}`\n        // const renderValue = `${getValuePrecisionThousand(valueFrom, undefined, undefined, precisionFrom)} ${keyFrom} \\u2192 ${getValuePrecisionThousand(valueTo, precisionTo, precisionTo, precisionTo)} ${keyTo}`\n        return <div className='rdg-cell-value'>{renderValue}</div>\n      },\n    },\n    {\n      key: 'time',\n      name: t('labelRewardTableTime'),\n      headerCellClass: 'textAlignRight',\n      formatter: ({ row, column }) => {\n        const value = row[column.key]\n        const renderValue = Number.isFinite(value)\n          ? moment(new Date(row['time']), 'YYYYMMDDHHMM').fromNow()\n          : EmptyValueTag\n        return (\n          <div className='rdg-cell-value textAlignRight'>\n            <span>{renderValue}</span>\n          </div>\n        )\n      },\n    },\n  ]\n}\n\nexport interface RewardTableProps {\n  rawData: Row[]\n  chosenCardInfo?: string\n}\n\nexport const RewardTable = withTranslation('tables')(\n  ({ chosenCardInfo, rawData, t }: RewardTableProps & WithTranslation) => {\n    const defaultArgs: any = {\n      rawData: [],\n      columnMode: getColumnModeRewardTable(t, chosenCardInfo),\n      // generateRows,\n      generateRows: (rawData: any) => rawData,\n      // generateColumns,\n      generateColumns: ({ columnsRaw }: any) => columnsRaw as Column<Row, unknown>[],\n    }\n    return (\n      <TableStyled>\n        <Table {...{ ...defaultArgs, rawData: rawData }} />\n      </TableStyled>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/rewardTable/RewardsTable.tsx",
    "content": "import { useTranslation, WithTranslation, withTranslation } from 'react-i18next'\nimport { useSettings } from '../../../stores'\nimport React from 'react'\nimport {\n  CurrencyToTag,\n  EmptyValueTag,\n  ForexMap,\n  getValuePrecisionThousand,\n  HiddenTag,\n  myLog,\n  PriceTag,\n  RowConfig,\n  TokenType,\n} from '@loopring-web/common-resources'\nimport { Column, Table } from '../../basic-lib'\nimport { Box, BoxProps, Link, Tooltip, Typography } from '@mui/material'\nimport { TablePaddingX } from '../../styled'\nimport styled from '@emotion/styled'\nimport { CoinIcons } from '../assetsTable'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nexport type EarningsDetail = {\n  amountStr: string\n  amount: string\n  name?: string\n  claimType: sdk.CLAIM_TYPE\n  tokenValueDollar: string\n  token: string\n  precision: number\n}\nexport type EarningsRow = {\n  token: {\n    type: TokenType\n    value: string\n  }\n  detail: Array<EarningsDetail>\n  precision: number\n  amountStr: string\n  amount: string\n  tokenValueDollar: number\n  rawData: any\n}\nconst TableWrapperStyled = styled(Box)<BoxProps & { isMobile: boolean }>`\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n  height: 100%;\n\n  ${({ theme }) => TablePaddingX({ pLeft: theme.unit * 3, pRight: theme.unit * 3 })}\n` as (prosp: BoxProps & { isMobile: boolean }) => JSX.Element\nconst TableStyled = styled(Table)`\n  &.rdg {\n    min-height: 240px;\n    height: ${(props: any) => {\n      return props.currentheight + 'px'\n    }};\n\n    .rdg-cell.action {\n      display: flex;\n      justify-content: center;\n      align-items: center;\n    }\n\n    .logo-icon.dual:last-child {\n      transform: scale(0.6) translate(0, 4px);\n    }\n  }\n\n  .textAlignRight {\n    text-align: right;\n\n    .rdg-header-sort-cell {\n      justify-content: flex-end;\n    }\n  }\n\n  .textAlignCenter {\n    text-align: center;\n  }\n` as any\nconst ContentWrapperStyled = styled(Box)`\n  padding: 0 ${({ theme }) => theme.unit * 1}px;\n  border-radius: ${({ theme }) => theme.unit / 2}px;\n`\n\nexport const DetailRewardPanel = ({\n  detailList,\n  hideAssets = false,\n}: {\n  detailList?: EarningsDetail[]\n  hideAssets?: boolean\n}) => {\n  const { t } = useTranslation()\n  myLog('detailLis', detailList)\n  return (\n    <ContentWrapperStyled>\n      {detailList?.map((item, index) => {\n        if (item.amount === '0') {\n          return <React.Fragment key={item.toString()} />\n        } else {\n          return (\n            <Box\n              display={'flex'}\n              key={index}\n              flexDirection={'row'}\n              justifyContent={'space-between'}\n              padding={1}\n            >\n              <Typography\n                display={'inline-flex'}\n                alignItems={'center'}\n                component={'span'}\n                color={'textSecondary'}\n              >\n                {Reflect.ownKeys(sdk.CLAIM_TYPE)?.includes(item.claimType?.toUpperCase() ?? '')\n                  ? t(`labelClaimType${item.claimType}`)\n                  : item?.name\n                  ? item?.name\n                  : t('labelClaimOtherRewards')}\n              </Typography>\n              <Typography\n                display={'inline-flex'}\n                alignItems={'center'}\n                component={'span'}\n                color={'textPrimary'}\n              >\n                {item.amount == '0'\n                  ? EmptyValueTag\n                  : hideAssets\n                  ? HiddenTag\n                  : getValuePrecisionThousand(\n                      item.amountStr,\n                      item.precision,\n                      item.precision,\n                      undefined,\n                      false,\n                      {\n                        floor: true,\n                      },\n                    ) +\n                    ' ' +\n                    item.token}\n              </Typography>\n            </Box>\n          )\n        }\n      })}\n    </ContentWrapperStyled>\n  )\n}\n\nexport const RewardsTable = withTranslation(['tables', 'common'])(\n  <R extends EarningsRow>(\n    props: {\n      hideAssets?: boolean\n      forexMap: ForexMap<sdk.Currency>\n      rawData: R[]\n      onItemClick: (item: any) => void\n      onDetail: (item: any) => void\n      showloading: boolean\n    } & WithTranslation,\n  ) => {\n    const { forexMap, hideAssets, rawData, onItemClick, showloading, t } = props\n\n    const { currency, isMobile, coinJson } = useSettings()\n\n    const getColumnMode = React.useCallback(\n      (): Column<R, unknown>[] => [\n        {\n          key: 'token',\n          name: t('labelToken'),\n          formatter: ({ row, column }) => {\n            const token = row[column.key]\n            let tokenIcon: [any, any] = [undefined, undefined]\n            const [head, middle, tail] = token.value.split('-')\n            if (token.type === 'lp' && middle && tail) {\n              tokenIcon =\n                coinJson[middle] && coinJson[tail]\n                  ? [coinJson[middle], coinJson[tail]]\n                  : [undefined, undefined]\n            }\n            if (token.type !== 'lp' && head && head !== 'lp') {\n              tokenIcon = coinJson[head] ? [coinJson[head], undefined] : [undefined, undefined]\n            }\n            return (\n              <Box\n                display={'inline-flex'}\n                height={'100%'}\n                flexDirection={'row'}\n                alignItems={'center'}\n              >\n                <CoinIcons type={token.type} tokenIcon={tokenIcon} />\n                <Typography\n                  variant={'inherit'}\n                  color={'textPrimary'}\n                  display={'flex'}\n                  flexDirection={'column'}\n                  marginLeft={2}\n                  component={'span'}\n                  paddingRight={1}\n                >\n                  <Typography component={'span'} className={'next-coin'}>\n                    {token.value}\n                  </Typography>\n                </Typography>\n              </Box>\n            )\n          },\n        },\n        {\n          key: 'amount',\n          name: t('labelAmount'),\n          headerCellClass: 'textAlignRight',\n          formatter: ({ row }) => {\n            const value = row.amountStr\n            const precision = row.precision\n            return (\n              <Box\n                className={'textAlignRight'}\n                // onClick={() => {\n                //   onDetail(row)\n                // }}\n              >\n                {row.amount === '0' ? (\n                  EmptyValueTag\n                ) : (\n                  <Tooltip\n                    componentsProps={{\n                      tooltip: {\n                        sx: {\n                          width: 'var(--mobile-full-panel-width)',\n                        },\n                      },\n                    }}\n                    className={'detailPanel'}\n                    title={<DetailRewardPanel hideAssets={hideAssets} detailList={row.detail} />}\n                  >\n                    <Typography\n                      display={'inline-flex'}\n                      alignItems={'center'}\n                      component={'span'}\n                      sx={{\n                        textDecoration: 'underline dotted',\n                        cursor: 'pointer',\n                      }}\n                    >\n                      {hideAssets\n                        ? HiddenTag\n                        : getValuePrecisionThousand(value, precision, precision, undefined, false, {\n                            floor: true,\n                          })}\n                    </Typography>\n                  </Tooltip>\n                )}\n              </Box>\n            )\n          },\n        },\n        {\n          key: 'value',\n          name: t('labelAssetsTableValue'),\n          headerCellClass: 'textAlignRight',\n          formatter: ({ row }) => {\n            return (\n              <Box className={'textAlignRight'}>\n                {row.amount === '0'\n                  ? EmptyValueTag\n                  : hideAssets\n                  ? HiddenTag\n                  : PriceTag[CurrencyToTag[currency]] +\n                    getValuePrecisionThousand(\n                      (row?.tokenValueDollar || 0) * (forexMap[currency] ?? 0),\n                      undefined,\n                      undefined,\n                      undefined,\n                      true,\n                      { isFait: true, floor: true },\n                    )}\n              </Box>\n            )\n          },\n        },\n        {\n          key: 'Actions',\n          name: t('labelActions'),\n          headerCellClass: 'textAlignRight',\n          cellClass: 'textAlignRight',\n          formatter: ({ row }) => {\n            return (\n              <Box className={'textAlignRight'}>\n                {row.amount === '0' ? (\n                  EmptyValueTag\n                ) : (\n                  <Link onClick={() => onItemClick(row)}>{t('labelClaim')}</Link>\n                )}\n              </Box>\n            )\n          },\n        },\n      ],\n      [hideAssets, forexMap, currency],\n    )\n\n    const defaultArgs: any = {\n      columnMode: getColumnMode(),\n      generateRows: (rawData: any) => rawData,\n      generateColumns: ({ columnsRaw }: any) => columnsRaw as Column<any, unknown>[],\n    }\n\n    return (\n      <TableWrapperStyled isMobile={isMobile}>\n        <TableStyled\n          currentheight={RowConfig.rowHeaderHeight + rawData.length * RowConfig.rowHeight}\n          {...{\n            ...defaultArgs,\n            ...props,\n            rawData,\n            showloading,\n          }}\n        />\n      </TableWrapperStyled>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/rewardTable/index.ts",
    "content": "export * from './ReferralsTable'\nexport * from './RewardTable'\nexport * from './RefundTable'\nexport * from './RewardsTable'\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/tableList.stories.tsx",
    "content": "import styled from '@emotion/styled'\nimport { Meta, Story } from '@storybook/react'\nimport { withTranslation } from 'react-i18next'\nimport { MemoryRouter } from 'react-router-dom'\nimport { QuoteTable, QuoteTableRawDataItem } from './QuoteTable/QuoteTable'\nimport { OrderHistoryTable } from './orderHistoryTable'\nimport { RawDataTransactionItem, TransactionTable } from './transactionsTable'\nimport { OrderHistoryRawDataItem } from './orderHistoryTable/OrderHistoryTable'\nimport { TradeStatus, TradeTypes } from '@loopring-web/common-resources'\nimport { TradeRaceTable } from './index'\n\nconst Style = styled.div`\n  flex: 1;\n  height: 100%;\n  flex: 1;\n`\n\n// type RawDataItem = (string | number | number[] | string[])[] | {}\n\nconst rawDatacoinBPrice: QuoteTableRawDataItem[] = [\n  {\n    pair: {\n      coinA: 'LRC',\n      coinB: 'BUSD',\n    },\n    close: 12.4,\n    floatTag: 'decrease',\n    change: 8.12,\n    high: 123.34,\n    low: 23.41,\n    volume: 21759000,\n    changeU: 21759000,\n    closeU: 21759000,\n    coinApriceU: 21759000,\n    precision: 3,\n    priceU: 3,\n    reward: 3,\n    rewardToken: '3',\n    timeUnit: '24h',\n    open: 100,\n    __rawTicker__: {} as any,\n  },\n]\n\nconst rawDataOrderHistory: OrderHistoryRawDataItem[] = [\n  {\n    market: 'ETH-LRC',\n    side: TradeTypes.Sell,\n    amount: {\n      from: { key: 'ETH', value: 1231 },\n      to: { key: 'ETH', value: 1231 },\n    },\n    average: '12',\n    // filledAmount: OrderPair;\n    price: {\n      key: 'ETH',\n      value: 1231,\n    },\n    time: 1223,\n    status: TradeStatus.Expired,\n    hash: 'xxxxxxxxxxx',\n    orderId: 'xxxxxx',\n    __raw__: {} as any,\n  },\n  {\n    market: 'ETH-LRC',\n    side: TradeTypes.Sell,\n    amount: {\n      from: { key: 'ETH', value: 1231 },\n      to: { key: 'ETH', value: 1231 },\n    },\n    average: '12',\n    // filledAmount: OrderPair;\n    price: {\n      key: 'ETH',\n      value: 1231,\n    },\n    time: 1223,\n    status: TradeStatus.Expired,\n    hash: 'xxxxxxxxxxx',\n    orderId: 'xxxxxx',\n    __raw__: {} as any,\n  },\n  {\n    market: 'ETH-LRC',\n    side: TradeTypes.Sell,\n    amount: {\n      from: { key: 'ETH', value: 1231 },\n      to: { key: 'ETH', value: 1231 },\n    },\n    average: '12',\n    // filledAmount: OrderPair;\n    price: {\n      key: 'ETH',\n      value: 1231,\n    },\n    time: 1223,\n    status: TradeStatus.Expired,\n    hash: 'xxxxxxxxxxx',\n    orderId: 'xxxxxx',\n    __raw__: {} as any,\n  },\n  {\n    market: 'ETH-LRC',\n    side: TradeTypes.Sell,\n    amount: {\n      from: { key: 'ETH', value: 1231 },\n      to: { key: 'ETH', value: 1231 },\n    },\n    average: '12',\n    // filledAmount: OrderPair;\n    price: {\n      key: 'ETH',\n      value: 1231,\n    },\n    time: 1223,\n    status: TradeStatus.Expired,\n    hash: 'xxxxxxxxxxx',\n    orderId: 'xxxxxx',\n    __raw__: {} as any,\n  },\n]\n\nconst rawDataTransaction: RawDataTransactionItem[] = []\nconst rawRank: any[] = [\n  {\n    rank: 1,\n    address: '0x...1',\n    xxx: 'xxx',\n  },\n  {\n    rank: 2,\n    address: '0x...1',\n    xxx: 'xxx',\n  },\n  {\n    rank: 3,\n    address: '0x...1',\n    xxx: 'xxx',\n  },\n  {\n    rank: 4,\n    address: '0x...1',\n    xxx: 'xxx',\n  },\n]\n\nconst Template: Story<any> = withTranslation()((args: any) => {\n  const { type } = args\n  return (\n    <>\n      <Style>\n        <MemoryRouter initialEntries={['/']}>\n          {type === 'coinBPrice' ? (\n            <QuoteTable {...args} />\n          ) : type === 'orderHistory' ? (\n            <OrderHistoryTable {...args} />\n          ) : type === 'rank' ? (\n            <TradeRaceTable {...args} />\n          ) : (\n            <TransactionTable {...args} />\n          )}\n        </MemoryRouter>\n      </Style>\n    </>\n  )\n}) as Story<any>\n\n// @ts-ignore\nexport const OrderHistory = Template.bind({})\n// @ts-ignore\nexport const Quote = Template.bind({})\n// @ts-ignore\nexport const Transaction = Template.bind({})\n// @ts-ignore\nexport const TradeRace = Template.bind({})\n\nQuote.args = {\n  rawData: rawDatacoinBPrice,\n  type: 'coinBPrice',\n  onVisibleRowsChange: (data: any) => {\n    console.log(data)\n  },\n}\n\nOrderHistory.args = {\n  rawData: rawDataOrderHistory,\n  type: 'orderHistory',\n  showFilter: true,\n  // pagination: {\n  //     pageSize: 5\n  // }\n}\n\nTransaction.args = {\n  rawData: rawDataTransaction,\n  type: 'transaction',\n  pagination: {\n    pageSize: 5,\n  },\n  showFilter: true,\n}\nTradeRace.args = {\n  rawData: rawRank,\n  type: 'rank',\n  column: [\n    {\n      key: 'rank',\n      label: 'rank',\n    },\n    {\n      key: 'address',\n      label: 'address',\n    },\n    {\n      key: 'xxx',\n      label: 'xxx',\n    },\n  ],\n}\nexport default {\n  title: 'components/TableList',\n  component: QuoteTable,\n  argTypes: {},\n} as Meta\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/taikoFarmingTable/Interface.ts",
    "content": "import * as sdk from '@loopring-web/loopring-sdk'\n\nexport type RawDataDefiTxsItem = Partial<sdk.UserDefiTxsHistory>\n\nexport interface DefiTxsTableProps<R = RawDataDefiTxsItem> {\n  rawData: R[]\n  pagination?: {\n    pageSize: number\n    total: number\n  }\n  idIndex: { [key: string]: string }\n  tokenMap: { [key: string]: any }\n  getDefiTxList: (props: any) => Promise<void>\n  showloading: boolean\n}\n\nexport interface RawDataDefiSideStakingItem\n  extends sdk.StakeInfoOrigin,\n    Omit<sdk.STACKING_PRODUCT, 'status'> {\n  status_product: number\n}\n\nexport interface DefiSideStakingTableProps<R = RawDataDefiSideStakingItem> {\n  rawData: R[]\n  pagination?: {\n    pageSize: number\n    total: number\n  }\n  idIndex: { [key: string]: string }\n  tokenMap: { [key: string]: any }\n  geDefiSideStakingList: (props: any) => Promise<void>\n  showloading: boolean\n  redeemItemClick: (item: R) => void\n  hideAssets?: boolean\n  noMinHeight?: boolean\n}\n\nexport type RawDataTaikoFarmingTxItem = sdk.STACKING_TRANSACTIONS & {\n  stakingType: string\n}\n\nexport interface TaikoFarmingTxTableProps<R = RawDataTaikoFarmingTxItem> {\n  rawData: R[]\n  pagination?: {\n    pageSize: number\n    total: number\n  }\n  idIndex: { [key: string]: string }\n  tokenMap: { [key: string]: any }\n  getSideStakingTxList: (props: any) => Promise<void>\n  showloading: boolean\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/taikoFarmingTable/TaikoFarmingPortfolioTable.tsx",
    "content": "import _ from 'lodash'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport { useSettings } from '../../../stores'\nimport React from 'react'\nimport { globalSetup, RowInvestConfig, TokenType } from '@loopring-web/common-resources'\nimport { Column, ModalCloseButton, Table, TablePagination } from '../../basic-lib'\n\nimport { Box, BoxProps, Modal, Typography } from '@mui/material'\nimport { SwitchPanelStyled, TablePaddingX } from '../../styled'\nimport styled from '@emotion/styled'\nimport { DefiSideStakingTableProps } from './Interface'\nimport { ConfirmStackingRedeem } from '../../tradePanel'\nimport { CoinIcons } from '../assetsTable'\n\nconst TableWrapperStyled = styled(Box)<BoxProps & { isMobile?: boolean }>`\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n\n  .rdg {\n    ${({ isMobile }) =>\n      !isMobile\n        ? `--template-columns: 33% 34% 33% !important;`\n        : `--template-columns: 33% 34% 33% !important;`}\n    .rdgCellCenter {\n      height: 100%;\n      justify-content: center;\n      align-items: center;\n    }\n\n    .textAlignRight {\n      text-align: right;\n    }\n\n    .textAlignCenter {\n      text-align: center;\n    }\n\n    .textAlignLeft {\n      text-align: left;\n    }\n  }\n\n  ${({ theme }) => TablePaddingX({ pLeft: theme.unit * 3, pRight: theme.unit * 3 })};\n` as (props: { isMobile?: boolean } & BoxProps) => JSX.Element\nconst TableStyled = styled(Table)`\n  &.rdg {\n    height: ${(props: any) => {\n      if (props.ispro === 'pro') {\n        return '620px'\n      }\n      if (props.currentheight) {\n        return props.currentheight + 'px'\n      }\n    }};\n\n    .rdg-cell.action {\n      display: flex;\n      justify-content: center;\n      align-items: center;\n    }\n  }\n\n  .textAlignRight {\n    text-align: right;\n\n    .rdg-header-sort-cell {\n      justify-content: flex-end;\n    }\n  }\n\n  .textAlignCenter {\n    text-align: center;\n  }\n` as any\n\ninterface Item {\n  coinJSON: any\n  tokenSymbol: string\n  amount: string\n  value: string\n}\nexport const TaikoFarmingPortfolioTable = withTranslation(['tables', 'common'])(\n  <R extends Item>(props: DefiSideStakingTableProps<R> & WithTranslation) => {\n    const {\n      rawData,\n      idIndex,\n      pagination,\n      tokenMap,\n      geDefiSideStakingList,\n      showloading,\n      // onDetailClick,\n      redeemItemClick: _redeemItemClick,\n      hideAssets,\n      noMinHeight,\n      t,\n    } = props\n    const [openDetail, setOpenDetail] = React.useState(false)\n    const [openAlert, setOpenAlert] = React.useState(false)\n    const [detail, setDetail] = React.useState<R | undefined>(undefined)\n    const { isMobile } = useSettings()\n    const [page, setPage] = React.useState(1)\n    const updateData = _.debounce(\n      ({\n        // tableType,\n        currPage = page,\n        pageSize = pagination?.pageSize ?? 10,\n      }: {\n        // tableType: TableType;\n        currPage?: number\n        pageSize?: number\n      }) => {\n        geDefiSideStakingList({\n          limit: pageSize,\n          offset: (currPage - 1) * pageSize,\n        })\n      },\n      globalSetup.wait,\n    )\n\n    const handlePageChange = React.useCallback(\n      (currPage: number) => {\n        if (currPage === page) return\n        setPage(currPage)\n        updateData({ currPage: currPage })\n      },\n      [updateData, page],\n    )\n\n    const getColumnModeTransaction = React.useCallback(\n      (): Column<R, unknown>[] => [\n        {\n          key: 'token',\n          sortable: false,\n          width: 'auto',\n          cellClass: 'textAlignLeft',\n          headerCellClass: 'textAlignLeft',\n          name: t('labelToken'),\n          formatter: ({ row }) => {\n            return (\n              <Box height={'100%'} display={'flex'} alignItems={'center'}>\n                <CoinIcons type={TokenType.single} tokenIcon={[row.coinJSON]} />\n                <Typography\n                  ml={1}\n                  component={'span'}\n                >\n                  {row.tokenSymbol}\n                </Typography>\n              </Box>\n            )\n          },\n        },\n        {\n          key: 'Amount',\n          sortable: false,\n          width: 'auto',\n          cellClass: 'textAlignCenter',\n          headerCellClass: 'textAlignCenter',\n          name: t('labelAmount'),\n          formatter: ({ row }) => {\n            return <> {row.amount}</>\n          },\n        },\n        {\n          key: 'Value',\n          sortable: false,\n          width: 'auto',\n          cellClass: 'textAlignRight',\n          headerCellClass: 'textAlignRight',\n          name: t('labelValue'),\n          formatter: ({ row }) => {\n            return <> {row.value}</>\n          },\n        },\n      ],\n      [t, tokenMap, idIndex, hideAssets],\n    )\n\n    const getColumnMobileTransaction = React.useCallback(\n      (): Column<R, unknown>[] => [\n        {\n          key: 'token',\n          sortable: false,\n          width: 'auto',\n          cellClass: 'textAlignLeft',\n          headerCellClass: 'textAlignLeft',\n          name: t('labelToken'),\n          formatter: ({ row }) => {\n            return (\n              <>\n                <CoinIcons type={TokenType.single} tokenIcon={[row.coinJSON]} />\n                <Typography\n                  ml={2}\n                  component={'span'}\n                >\n                  {row.tokenSymbol}\n                </Typography>\n              </>\n            )\n          },\n        },\n        {\n          key: 'Amount',\n          sortable: false,\n          width: 'auto',\n          cellClass: 'textAlignCenter',\n          headerCellClass: 'textAlignCenter',\n          name: t('labelAmount'),\n          formatter: ({ row }) => {\n            return <> {row.amount}</>\n          },\n        },\n        {\n          key: 'Value',\n          sortable: false,\n          width: 'auto',\n          cellClass: 'textAlignRight',\n          headerCellClass: 'textAlignRight',\n          name: t('labelValue'),\n          formatter: ({ row }) => {\n            return <> {row.value}</>\n          },\n        },\n      ],\n      [t, tokenMap, idIndex],\n    )\n\n\n    const defaultArgs: any = {\n      columnMode: isMobile ? getColumnMobileTransaction() : getColumnModeTransaction(),\n      generateRows: (rawData: any) => rawData,\n      generateColumns: ({ columnsRaw }: any) => columnsRaw as Column<any, unknown>[],\n    }\n\n    return (\n      <TableWrapperStyled isMobile={isMobile}>\n        <TableStyled\n          currentheight={\n            rawData.length > 0\n              ? RowInvestConfig.rowHeaderHeight + rawData.length * RowInvestConfig.rowHeight\n              : 350\n          }\n          rowHeight={RowInvestConfig.rowHeight}\n          headerRowHeight={RowInvestConfig.rowHeaderHeight}\n          style={{\n            minHeight:noMinHeight ? 0 : undefined\n          }}\n          {...{\n            ...defaultArgs,\n            ...props,\n            rawData,\n            showloading,\n          }}\n        />\n        {!!(pagination && pagination.total > pagination.pageSize) && (\n          <TablePagination\n            page={page}\n            pageSize={pagination.pageSize}\n            total={pagination.total}\n            onPageChange={handlePageChange}\n          />\n        )}\n        <Modal\n          open={openDetail}\n          onClose={(_e: any) => setOpenDetail(false)}\n          aria-labelledby='modal-modal-title'\n          aria-describedby='modal-modal-description'\n        >\n          <SwitchPanelStyled width={'var(--modal-width)'}>\n            <ModalCloseButton onClose={(_e: any) => setOpenDetail(false)} t={t} />\n            {detail && (\n              <Box flex={1} paddingY={2} width={'100%'} display={'flex'} flexDirection={'column'}>\n                <Typography\n                  variant={isMobile ? 'h5' : 'h4'}\n                  marginTop={-4}\n                  textAlign={'center'}\n                  paddingBottom={2}\n                >\n                  {t('labelDeFiSideInvestmentDetails', {\n                    ns: 'common',\n                    symbol: 'LRC',\n                  })}\n                </Typography>\n              </Box>\n            )}\n          </SwitchPanelStyled>\n        </Modal>\n        <ConfirmStackingRedeem\n          open={openAlert}\n          handleClose={(_, isAgree?: boolean) => {\n            setOpenAlert(false)\n            if (isAgree) {\n              _redeemItemClick(detail as any)\n            }\n          }}\n        />\n      </TableWrapperStyled>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/taikoFarmingTable/TaikoTarmingTxRecordsTable.tsx",
    "content": "import _ from 'lodash'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport { useSettings } from '../../../stores'\nimport React from 'react'\nimport {\n  EmptyValueTag,\n  getShortAddr,\n  getValuePrecisionThousand,\n  globalSetup,\n  Info2Icon,\n} from '@loopring-web/common-resources'\nimport { Column, Table, TablePagination } from '../../basic-lib'\nimport { Box, BoxProps, Tooltip, Typography } from '@mui/material'\nimport { TablePaddingX } from '../../styled'\nimport styled from '@emotion/styled'\nimport { FormatterProps } from 'react-data-grid'\nimport { RawDataTaikoFarmingTxItem, TaikoFarmingTxTableProps } from './Interface'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport moment from 'moment'\n\nconst TableStyled = styled(Box)<BoxProps & { isMobile?: boolean }>`\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n\n  .rdg {\n    ${({ isMobile }) =>\n      !isMobile\n        ? `--template-columns: 30% 40% 30% !important;`\n        : `--template-columns: 20% 45% 35% !important;`}\n    .rdgCellCenter {\n      height: 100%;\n      justify-content: center;\n      align-items: center;\n    }\n\n    .textAlignRight {\n      text-align: right;\n    }\n\n    .textAlignCenter {\n      text-align: center;\n    }\n\n    .textAlignLeft {\n      text-align: left;\n    }\n  }\n\n  ${({ theme }) => TablePaddingX({ pLeft: theme.unit * 3, pRight: theme.unit * 3 })}\n` as (props: { isMobile?: boolean } & BoxProps) => JSX.Element\n\nexport const TaikoTarmingTxRecordsTable = withTranslation(['tables', 'common'])(\n  <R extends RawDataTaikoFarmingTxItem>(\n    props: TaikoFarmingTxTableProps<R> & WithTranslation,\n  ) => {\n    const { rawData, idIndex, pagination, tokenMap, getSideStakingTxList, showloading, t } = props\n    const { isMobile } = useSettings()\n    const [page, setPage] = React.useState(1)\n\n    const updateData = _.debounce(\n      ({\n        // tableType,\n        currPage = page,\n        pageSize = pagination?.pageSize ?? 10,\n      }: {\n        // tableType: TableType;\n        currPage?: number\n        pageSize?: number\n      }) => {\n        getSideStakingTxList({\n          limit: pageSize,\n          offset: (currPage - 1) * pageSize,\n        })\n      },\n      globalSetup.wait,\n    )\n\n    const handlePageChange = React.useCallback(\n      (currPage: number) => {\n        if (currPage === page) return\n        setPage(currPage)\n        updateData({ currPage: currPage })\n      },\n      [updateData, page],\n    )\n\n    const getColumnModeTransaction = React.useCallback(\n      (): Column<R, unknown>[] => [\n        {\n          key: 'Type',\n          sortable: false,\n          width: 'auto',\n          name: t('labelDefiStakingTxType'),\n          cellClass: 'textAlignLeft',\n          headerCellClass: 'textAlignLeft',\n          formatter: ({ row }) => {\n            let side = {\n              color: 'var(--color-text-primary)',\n              // @ts-ignore\n              type: `labelStakeTransactionType${row.stakingType}`,\n            }\n            const tokenInfo = tokenMap[idIndex[row.tokenId ?? '']]\n            \n            const amountStr = row.amount\n              ? getValuePrecisionThousand(\n                  sdk.toBig(row.amount).div('1e' + tokenInfo.decimals),\n                  tokenInfo.precision,\n                  tokenInfo.precision,\n                  undefined,\n                  false,\n                  {\n                    floor: false,\n                    // isTrade: true,\n                  },\n                ) +\n                ' ' +\n                (row.stakingType === sdk.StakeTransactionType.claim ? 'lrTAIKO' : tokenInfo.symbol)\n              : EmptyValueTag\n            switch (row.stakingType) {\n              case sdk.StakeTransactionType.subscribe:\n                side = {\n                  color: 'var(--color-success)',\n                  type: 'labelLock',\n                }\n                break\n              case sdk.StakeTransactionType.redeem:\n                side = {\n                  ...side,\n                  color: 'var(--color-success)',\n                }\n                break\n              case sdk.StakeTransactionType.claim:\n                side = {\n                  ...side,\n                  color: 'var(--color-success)',\n                }\n                break\n            }\n            \n\n            return (\n              <Typography\n                component={'span'}\n                flexDirection={'row'}\n                display={'flex'}\n                height={'100%'}\n                alignItems={'center'}\n              >\n                <Tooltip\n                  title={\n                    'If you have used lrTAIKO as collateral to invest in Portal and incurred a loss, the compensation will be deducted from your locked TAIKO balance. This settlement involves transferring a portion of your locked TAIKO to the Loopring operator to cover the loss.'\n                  }\n                >\n                  <Typography\n                    component={'span'}\n                    sx={{ textTransform: 'capitalize' }}\n                    color={side.color}\n                    display={'flex'}\n                    minWidth={120}\n                    alignItems={'center'}\n                  >\n                    {row.stakingType === sdk.StakeTransactionType.redeem\n                      ? 'Settlement'\n                      : t(side.type)}\n                    {row.stakingType === sdk.StakeTransactionType.redeem && (\n                      <Info2Icon sx={{ ml: 0.5, mt: 0.25, color: 'var(--color-text-secondary)' }} />\n                    )}\n                  </Typography>\n                </Tooltip>\n                <Typography component={'span'} display={'inline'}>\n                  {amountStr}\n                </Typography>\n              </Typography>\n            )\n          },\n        },\n        {\n          key: 'HashID',\n          sortable: false,\n          width: 'auto',\n          cellClass: 'textAlignCenter',\n          headerCellClass: 'textAlignCenter',\n          name: 'Hash',\n          formatter: ({ row }) => {\n            return <>{row.hash ? getShortAddr(row.hash) : EmptyValueTag}</>\n          },\n        },\n        {\n          key: 'SubscribeTime',\n          sortable: false,\n          width: 'auto',\n          cellClass: 'textAlignRight',\n          headerCellClass: 'textAlignRight',\n          name: t('labelLockTime'),\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            return (\n              <Typography component={'span'} textAlign={'right'}>\n                {typeof row.createdAt === 'undefined'\n                  ? EmptyValueTag\n                  : moment(new Date(row.createdAt), 'YYYYMMDDHHMM').fromNow()}\n              </Typography>\n            )\n          },\n        },\n      ],\n      [t, tokenMap, idIndex],\n    )\n\n    const getColumnMobileTransaction = React.useCallback(\n      (): Column<R, unknown>[] => [\n        {\n          key: 'Type',\n          sortable: false,\n          width: 'auto',\n          name: t('labelDefiStakingTxType'),\n          cellClass: 'textAlignLeft',\n          headerCellClass: 'textAlignLeft',\n          formatter: ({ row }) => {\n            let side = {\n              color: 'var(--color-text-primary)',\n              // @ts-ignore\n              type: `labelStakeTransactionType${row.stakingType}`,\n            }\n            // @ts-ignore\n            switch (row.stakingType) {\n              case sdk.StakeTransactionType.subscribe:\n                side = {\n                  ...side,\n                  color: 'var(--color-success)',\n                }\n                break\n              case sdk.StakeTransactionType.redeem:\n                side = {\n                  ...side,\n                  color: 'var(--color-error)',\n                }\n                break\n              case sdk.StakeTransactionType.claim:\n                side = {\n                  ...side,\n                  color: 'var(--color-warning)',\n                }\n                break\n            }\n\n            return (\n              <Typography\n                component={'span'}\n                flexDirection={'row'}\n                display={'flex'}\n                height={'100%'}\n                alignItems={'center'}\n              >\n                <Typography\n                  component={'span'}\n                  sx={{ textTransform: 'capitalize' }}\n                  color={side.color}\n                  display={'inline'}\n                  minWidth={86}\n                >\n                  {t(side.type)}\n                </Typography>\n              </Typography>\n            )\n          },\n        },\n        {\n          key: 'Product',\n          sortable: false,\n          width: 'auto',\n          name: t('labelDefiStakingTxAmount'),\n          cellClass: 'textAlignRight',\n          headerCellClass: 'textAlignRight',\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            const tokenInfo = tokenMap[idIndex[row.tokenId ?? '']]\n            const amountStr =\n              row.amount && row.amount != '0'\n                ? getValuePrecisionThousand(\n                    sdk.toBig(row.amount).div('1e' + tokenInfo.decimals),\n                    tokenInfo.precision,\n                    tokenInfo.precision,\n                    undefined,\n                    false,\n                    {\n                      floor: false,\n                      // isTrade: true,\n                    },\n                  ) +\n                  ' ' +\n                  tokenInfo.symbol\n                : EmptyValueTag\n            return (\n              <Box\n                display={'flex'}\n                height={'100%'}\n                width={'100%'}\n                alignItems={'center'}\n              >\n                <Typography textAlign={'right'} width={'100%'}>\n                  {amountStr}\n                </Typography>\n              </Box>\n            )\n          },\n        },\n        {\n          key: 'SubscribeTime',\n          sortable: false,\n          width: 'auto',\n          cellClass: 'textAlignRight',\n          headerCellClass: 'textAlignRight',\n          name: t('labelLockTime'),\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            return (\n              <Typography component={'span'} textAlign={'right'}>\n                {typeof row.createdAt === 'undefined'\n                  ? EmptyValueTag\n                  : moment(new Date(row.createdAt), 'YYYYMMDDHHMM').fromNow()}\n              </Typography>\n            )\n          },\n        },\n      ],\n      [t, tokenMap, idIndex],\n    )\n\n\n    const defaultArgs: any = {\n      columnMode: isMobile ? getColumnMobileTransaction() : getColumnModeTransaction(),\n      generateRows: (rawData: any) => rawData,\n      generateColumns: ({ columnsRaw }: any) => columnsRaw as Column<any, unknown>[],\n    }\n    React.useEffect(() => {\n      updateData.cancel()\n      updateData({ currPage: 1 })\n\n      return () => {\n        updateData.cancel()\n      }\n    }, [pagination?.pageSize])\n\n    return (\n      <TableStyled isMobile={isMobile}>\n        <Table\n          {...{\n            ...defaultArgs,\n            ...props,\n            rawData,\n            showloading,\n          }}\n        />\n        {pagination && (\n          <TablePagination\n            page={page}\n            pageSize={pagination.pageSize}\n            total={pagination.total}\n            onPageChange={handlePageChange}\n          />\n        )}\n      </TableStyled>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/taikoFarmingTable/index.ts",
    "content": "\nexport * from './Interface'\nexport { TaikoTarmingTxRecordsTable } from './TaikoTarmingTxRecordsTable'\nexport { TaikoFarmingPortfolioTable } from './TaikoFarmingPortfolioTable'\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/tradeNFTTable/Interface.ts",
    "content": "export type NFTTradeFilter = {\n  side: undefined | 'SELL' | 'BUY'\n  limit?: number\n  offset?: number\n  start?: number\n  end?: number\n  // pageSize:number,\n  // duration?: DateRange<Date | string>;\n  page?: number\n}\n\nexport enum FilterTradeNFTTypes {\n  // maker = \"Maker\",\n  // taker = \"Taker\",\n  allTypes = 'all',\n  sell = 'sell',\n  buy = 'buy',\n  self = 'self',\n}\n\nexport type NFTTradeProps<Row> = NFTTradeFilter & {\n  etherscanBaseUrl?: string\n  rawData: Row[]\n  pagination?: {\n    pageSize: number\n    total: number\n    page: number\n  }\n  idIndex: { [key: string]: string }\n  tokenMap: any\n  getTradeList: (filter: NFTTradeFilter) => Promise<void>\n  showFilter?: boolean\n  showLoading: boolean\n  accAddress: string\n  accountId: number\n  currentHeight: number\n  rowHeight?: number\n  headerRowHeight?: number\n  // accAddress?: string;\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/tradeNFTTable/TradeNFTTable.tsx",
    "content": "import React from 'react'\nimport { Box, BoxProps, Link, Typography } from '@mui/material'\nimport styled from '@emotion/styled'\nimport { TFunction, Trans, withTranslation, WithTranslation } from 'react-i18next'\nimport moment from 'moment'\n\nimport { BoxNFT, Column, NftImage, Table, TablePagination } from '../../basic-lib'\nimport { TableFilterStyled, TablePaddingX } from '../../styled'\nimport { Filter, FilterTradeTypes } from './components/Filter'\n\nimport {\n  EmptyValueTag,\n  Explorer,\n  getShortAddr,\n  getValuePrecisionThousand,\n  globalSetup,\n  RowConfig,\n  TableType,\n  UNIX_TIMESTAMP_FORMAT,\n} from '@loopring-web/common-resources'\nimport { useSettings } from '../../../stores'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { Currency, NFT_IMAGE_SIZES } from '@loopring-web/loopring-sdk'\nimport _ from 'lodash'\nimport { FilterTradeNFTTypes, NFTTradeProps } from './Interface'\nimport { DateRange } from '@mui/lab'\n\nconst StyledSideCell: any = styled(Typography)`\n  color: ${(props: any) => {\n    const {\n      value,\n      theme: { colorBase },\n    } = props\n    return value === FilterTradeNFTTypes.sell ? colorBase.success : colorBase.error\n  }};\n`\n\nconst TableStyled = styled(Box)<\n  BoxProps & {\n    isMobile?: boolean\n    currentheight?: number\n  }\n>`\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n\n  .rdg {\n    height: ${(props: any) => props.currentheight}px;\n\n    ${({ isMobile }) =>\n      !isMobile\n        ? `--template-columns: 50% auto 20% auto  !important; `\n        : ` --template-columns: 70% 30% !important;`}\n    .rdg-cell.action {\n      display: flex;\n      justify-content: center;\n      align-items: center;\n    }\n\n    .rdg-header-row {\n    }\n\n    .textAlignRight {\n      text-align: right;\n    }\n  }\n\n  ${({ theme }) => TablePaddingX({ pLeft: theme.unit * 3, pRight: theme.unit * 3 })}\n` as (\n  props: {\n    isMobile?: boolean\n    currentheight?: number\n  } & BoxProps,\n) => JSX.Element\n\nconst getColumnModeAssets = (\n  t: TFunction,\n  _currency: Currency,\n  tokenMap: any,\n  accountId: number,\n  filterType: FilterTradeNFTTypes,\n): Column<sdk.UserNFTTradeHistory, unknown>[] => {\n  return [\n    {\n      key: 'side',\n      name: t('labelTradeNFTSide'),\n      formatter: ({ row }) => {\n        let { nftAmount, metadata, bInfo, sInfo } = row\n        metadata = {\n          ...metadata,\n          ...metadata?.base,\n        }\n        let tradeType, fromAddr\n        if (filterType === FilterTradeNFTTypes.buy && bInfo.accountId === accountId) {\n          tradeType = FilterTradeNFTTypes.buy\n          fromAddr = sInfo.address\n        } else if (filterType === FilterTradeNFTTypes.sell && sInfo.accountId === accountId) {\n          tradeType = FilterTradeNFTTypes.sell\n          fromAddr = bInfo.address\n        } else if (sInfo.accountId === accountId && bInfo.accountId === accountId) {\n          tradeType = FilterTradeNFTTypes.self\n          fromAddr = ''\n        } else if (bInfo.accountId === accountId) {\n          tradeType = FilterTradeNFTTypes.buy\n          fromAddr = sInfo.address\n        } else {\n          tradeType = FilterTradeNFTTypes.sell\n          fromAddr = bInfo.address\n        }\n        // const amount = Number(nftAmount ?? 0);// getValuePrecisionThousand( Number(nftAmount??0) , 0, 0, 0);\n        return (\n          <Box className='rdg-cell-value' height={'100%'} display={'flex'} alignItems={'center'}>\n            {metadata?.imageSize ? (\n              <Box\n                display={'flex'}\n                alignItems={'center'}\n                justifyContent={'center'}\n                height={RowConfig.rowHeight + 'px'}\n                width={RowConfig.rowHeight + 'px'}\n                padding={1 / 4}\n                style={{ background: 'var(--field-opacity)' }}\n              >\n                {metadata?.imageSize && (\n                  <NftImage\n                    alt={metadata?.base?.name}\n                    onError={() => undefined}\n                    src={metadata?.imageSize[NFT_IMAGE_SIZES.small]}\n                  />\n                )}\n              </Box>\n            ) : (\n              <BoxNFT\n                display={'flex'}\n                alignItems={'center'}\n                justifyContent={'center'}\n                height={RowConfig.rowHeight + 'px'}\n                width={RowConfig.rowHeight + 'px'}\n              />\n            )}\n            <Typography\n              color={'inherit'}\n              flex={1}\n              display={'inline-flex'}\n              alignItems={'center'}\n              paddingLeft={1}\n              overflow={'hidden'}\n              textOverflow={'ellipsis'}\n              component={'span'}\n            >\n              <StyledSideCell value={tradeType} marginRight={1}>\n                {tradeType === FilterTradeNFTTypes.buy\n                  ? t('labelFilterTradeNFTBuy')\n                  : tradeType === FilterTradeNFTTypes.self\n                  ? t('labelFilterTradeNFTSelf')\n                  : t('labelFilterTradeNFTSell')}\n              </StyledSideCell>\n              <span>\n                {`${Number(nftAmount)} * ${\n                  metadata?.base?.name ? metadata?.base?.name : t('labelUnknown', { ns: 'common' })\n                } ${\n                  tradeType === FilterTradeNFTTypes.buy\n                    ? t('labelFrom')\n                    : tradeType === FilterTradeNFTTypes.sell\n                    ? t('labelTo')\n                    : ''\n                } ${fromAddr && getShortAddr(fromAddr)}`}\n              </span>\n            </Typography>\n          </Box>\n        )\n      },\n    },\n    {\n      key: 'price',\n      name: t('labelTradeNFTUnitPrice'),\n      headerCellClass: 'textAlignRight',\n      formatter: ({ row }) => {\n        // const {value} = row[ \"price\" ];\n        let { price, feeTokenSymbol } = row\n        let erc20Info = tokenMap[feeTokenSymbol]\n        // const precision = row[ \"precision\" ] || 6;\n        const renderValue = price\n          ? getValuePrecisionThousand(\n              price,\n              undefined,\n              undefined,\n              erc20Info?.precision ?? undefined,\n              true,\n              { isPrice: true },\n            ) +\n            ' ' +\n            erc20Info.symbol\n          : EmptyValueTag\n        return <Box className='rdg-cell-value textAlignRight'>{renderValue}</Box>\n      },\n    },\n    {\n      key: 'fee',\n      name: t('labelTradeFee'),\n      headerCellClass: 'textAlignRight',\n      formatter: ({ row }) => {\n        let { sInfo, bInfo, feeTokenSymbol } = row\n        let feeAmount\n\n        if (filterType == FilterTradeNFTTypes.sell && sInfo.accountId === accountId) {\n          feeAmount = sInfo.feeAmount\n        } else if (filterType == FilterTradeNFTTypes.buy && bInfo.accountId === accountId) {\n          feeAmount = bInfo.feeAmount\n        } else if (bInfo.accountId === accountId && sInfo.accountId === accountId) {\n          feeAmount = sdk.toBig(bInfo.feeAmount).plus(sInfo.feeAmount)\n        } else if (bInfo.accountId === accountId) {\n          feeAmount = bInfo.feeAmount\n        } else {\n          feeAmount = sInfo.feeAmount\n        }\n        let feeTokenInfo = tokenMap[feeTokenSymbol]\n        const fee = feeAmount\n          ? sdk\n              .toBig(feeAmount ?? 0)\n              .div('1e' + feeTokenInfo.decimals)\n              .toString()\n          : undefined\n        const renderValue = fee\n          ? getValuePrecisionThousand(\n              fee,\n              feeTokenInfo?.precision ?? undefined,\n              feeTokenInfo?.precision ?? undefined,\n              feeTokenInfo?.precision ?? undefined,\n              true,\n              { isPrice: true },\n            ) +\n            ' ' +\n            feeTokenInfo.symbol\n          : EmptyValueTag\n        // return (\n        // const {key, value} = row[ \"fee\" ];\n        // myLog({value})\n        return <div className='rdg-cell-value textAlignRight'>{`${renderValue}`}</div>\n      },\n    },\n    {\n      key: 'time',\n      name: t('labelTradeTime'),\n      headerCellClass: 'textAlignRight',\n      // minWidth: 400,\n      formatter: ({ row }) => {\n        const time = moment(new Date(row.createdAt), 'YYYYMMDDHHMM').fromNow()\n        return <div className='rdg-cell-value textAlignRight'>{time}</div>\n      },\n    },\n  ]\n}\n\nconst getColumnModeMobileAssets = (\n  t: TFunction,\n  _currency: Currency,\n  tokenMap: any,\n  accountId: number,\n  filterType: FilterTradeNFTTypes,\n): Column<sdk.UserNFTTradeHistory, unknown>[] => {\n  return [\n    {\n      key: 'side',\n      name: t('labelTradeNFTSide') + '/' + t('labelTradeNFTUnitPrice'),\n      formatter: ({ row }) => {\n        let { nftAmount, metadata, price, feeTokenSymbol, bInfo, sInfo } = row\n        metadata = {\n          ...metadata,\n          ...metadata?.base,\n        }\n        let tradeType, fromAddr\n        if (filterType === FilterTradeNFTTypes.buy && bInfo.accountId === accountId) {\n          tradeType = FilterTradeNFTTypes.buy\n          fromAddr = sInfo.address\n        } else if (filterType === FilterTradeNFTTypes.sell && sInfo.accountId === accountId) {\n          tradeType = FilterTradeNFTTypes.sell\n          fromAddr = bInfo.address\n        } else if (sInfo.accountId === accountId && bInfo.accountId === accountId) {\n          tradeType = FilterTradeNFTTypes.self\n          fromAddr = ''\n        } else if (bInfo.accountId === accountId) {\n          tradeType = FilterTradeNFTTypes.buy\n          fromAddr = sInfo.address\n        } else {\n          tradeType = FilterTradeNFTTypes.sell\n          fromAddr = bInfo.address\n        }\n        let erc20Info = tokenMap[feeTokenSymbol]\n        const renderValue = price\n          ? getValuePrecisionThousand(\n              price,\n              undefined,\n              undefined,\n              erc20Info?.precision ?? undefined,\n              true,\n              { isPrice: true },\n            ) +\n            ' ' +\n            erc20Info.symbol\n          : EmptyValueTag\n        return (\n          <Box className='rdg-cell-value' height={'100%'} display={'flex'} alignItems={'center'}>\n            {metadata?.imageSize ? (\n              <Box\n                display={'flex'}\n                alignItems={'center'}\n                justifyContent={'center'}\n                height={RowConfig.rowHeight + 'px'}\n                width={RowConfig.rowHeight + 'px'}\n                padding={1 / 4}\n                style={{ background: 'var(--field-opacity)' }}\n              >\n                {metadata?.imageSize && (\n                  <NftImage\n                    alt={metadata?.base?.name}\n                    onError={() => undefined}\n                    src={metadata?.imageSize[NFT_IMAGE_SIZES.small]}\n                  />\n                )}\n              </Box>\n            ) : (\n              <BoxNFT\n                display={'flex'}\n                alignItems={'center'}\n                justifyContent={'center'}\n                height={RowConfig.rowHeight + 'px'}\n                width={RowConfig.rowHeight + 'px'}\n              />\n            )}\n            <Box display={'flex'} flexDirection={'column'}>\n              <Typography\n                color={'inherit'}\n                flex={1}\n                display={'inline-flex'}\n                alignItems={'center'}\n                paddingLeft={1}\n                overflow={'hidden'}\n                textOverflow={'ellipsis'}\n                component={'span'}\n              >\n                <StyledSideCell value={tradeType} marginRight={1}>\n                  {tradeType === FilterTradeNFTTypes.buy\n                    ? t('labelFilterTradeNFTBuy')\n                    : t('labelFilterTradeNFTSell')}\n                </StyledSideCell>\n                <span>\n                  {`${Number(nftAmount)}  ${\n                    metadata?.base?.name\n                      ? metadata?.base?.name\n                      : t('labelUnknown', { ns: 'common' })\n                  } ${\n                    tradeType === FilterTradeNFTTypes.buy\n                      ? t('labelFrom')\n                      : tradeType === FilterTradeNFTTypes.sell\n                      ? t('labelTo')\n                      : ''\n                  } ${fromAddr && getShortAddr(fromAddr)}`}\n                </span>\n              </Typography>\n              <Typography\n                color={'inherit'}\n                flex={1}\n                display={'inline-flex'}\n                alignItems={'center'}\n                paddingLeft={1}\n                component={'span'}\n              >\n                {t('labelUPrice') + renderValue}\n              </Typography>\n            </Box>\n          </Box>\n        )\n      },\n    },\n    {\n      key: 'fee',\n      name: t('labelTradeFee'),\n      cellClass: 'textAlignRight',\n      headerCellClass: 'textAlignRight',\n      formatter: ({ row }) => {\n        let { sInfo, bInfo, feeTokenSymbol } = row\n        const time = moment(new Date(row.createdAt), 'YYYYMMDDHHMM').fromNow()\n        let feeAmount\n        if (filterType == FilterTradeNFTTypes.sell && sInfo.accountId === accountId) {\n          feeAmount = sInfo.feeAmount\n        } else if (filterType == FilterTradeNFTTypes.buy && bInfo.accountId === accountId) {\n          feeAmount = bInfo.feeAmount\n        } else if (bInfo.accountId === accountId && sInfo.accountId === accountId) {\n          feeAmount = sdk.toBig(bInfo.feeAmount).plus(sInfo.feeAmount)\n        } else if (bInfo.accountId === accountId) {\n          feeAmount = bInfo.feeAmount\n        } else {\n          feeAmount = sInfo.feeAmount\n        }\n\n        let feeTokenInfo = tokenMap[feeTokenSymbol]\n        const fee = sdk\n          .toBig(feeAmount)\n          .div('1e' + feeTokenInfo.decimals)\n          .toString()\n        const renderValue = fee\n          ? getValuePrecisionThousand(\n              fee,\n              undefined,\n              undefined,\n              feeTokenInfo?.precision ?? undefined,\n              true,\n              { isPrice: true },\n            ) +\n            ' ' +\n            feeTokenInfo.symbol\n          : EmptyValueTag\n        // return (\n        // const {key, value} = row[ \"fee\" ];\n        // myLog({value})\n        return (\n          <Box display={'flex'} flexDirection={'column'}>\n            <Typography variant={'body1'} component={'span'}>\n              {`${renderValue} ${feeTokenSymbol}`}\n            </Typography>\n            <Typography color={'var(--color-text-third)'} variant={'body2'} component={'span'}>\n              {time}\n            </Typography>\n          </Box>\n        )\n      },\n    },\n  ]\n}\n\nexport const TradeNFTTable = withTranslation('tables')(\n  <Row extends sdk.UserNFTTradeHistory>({\n    t,\n    pagination,\n    showFilter,\n    // idIndex,\n    tokenMap,\n    // filterPairs = [],\n    rawData,\n    currentHeight,\n    rowHeight = RowConfig.rowHeight,\n    getTradeList,\n    headerRowHeight = RowConfig.rowHeaderHeight,\n    showLoading = false,\n    accAddress,\n    accountId,\n    ...rest\n  }: WithTranslation & NFTTradeProps<Row>) => {\n    // const {search} = useLocation();\n    // const searchParams = new URLSearchParams(search);\n    const [filterType, setFilterType] = React.useState(FilterTradeNFTTypes.allTypes)\n    const [filterDate, setFilterDate] = React.useState<DateRange<string | Date>>([null, null])\n    const { currency, isMobile, defaultNetwork } = useSettings()\n    const isTaiko = [sdk.ChainId.TAIKO, sdk.ChainId.TAIKOHEKLA].includes(defaultNetwork)\n    const defaultArgs: any = {\n      columnMode: isMobile\n        ? getColumnModeMobileAssets(t, currency, tokenMap, accountId, filterType)\n        : getColumnModeAssets(t, currency, tokenMap, accountId, filterType),\n      generateRows: (rawData: any) => rawData,\n      generateColumns: ({ columnsRaw }: any) => columnsRaw as Column<Row, unknown>[],\n      style: {\n        backgroundColor: ({ colorBase }: any) => `${colorBase.box}`,\n      },\n    }\n    // myLog('TradeNFTTable', rawData, pagination)\n\n    const pageSize = pagination ? pagination.pageSize : 10\n\n    const updateData = _.debounce(\n      ({\n        // isSell,\n        // page,\n        tableType,\n        // tableType,\n        // currFilterPair = filterPair,\n        currFilterDate = filterDate,\n        currPage = pagination?.page || 1,\n        currFilterType = filterType,\n      }) => {\n        if (tableType === TableType.filter) {\n          currPage = 1\n        }\n\n        const start = currFilterDate[0]\n          ? Number(moment(currFilterDate[0]).format(UNIX_TIMESTAMP_FORMAT))\n          : undefined\n        const end = currFilterDate[1]\n          ? Number(moment(currFilterDate[1]).format(UNIX_TIMESTAMP_FORMAT))\n          : undefined\n        // const market =\n        //   currFilterPair === \"all\" ? \"\" : currFilterPair.replace(/\\s+/g, \"\");\n        if (getTradeList) {\n          getTradeList({\n            start: start,\n            end: end,\n            limit: pagination?.pageSize ?? 10,\n            offset: (currPage - 1) * (pagination?.pageSize ?? 10),\n            page: currPage,\n            side:\n              currFilterType === FilterTradeNFTTypes.allTypes\n                ? undefined\n                : currFilterType.toUpperCase(),\n          })\n        }\n      },\n      globalSetup.wait,\n      //[filterPair, filterType, pageSize, getUserTradeList, pagination]\n    )\n\n    const handleFilterChange = React.useCallback(\n      ({ type = filterType, date = [null, null] }) => {\n        setFilterType(type)\n        setFilterDate(date as any)\n        updateData({\n          tableType: TableType.filter,\n          currFilterType: type,\n          currFilterData: date,\n        })\n      },\n      [updateData, filterType],\n    )\n\n    const handlePageChange = React.useCallback(\n      (page: number) => {\n        updateData({ tableType: TableType.page, currPage: page })\n      },\n      [updateData],\n    )\n\n    const handleReset = () => {\n      setFilterType(FilterTradeNFTTypes.allTypes)\n      setFilterDate([null, null])\n      // setFilterPair(\"all\");\n      // setFilterDate(date);\n      updateData({\n        tableType: 'filter',\n        currFilterType: FilterTradeTypes.allTypes,\n        currFilterDate: [null, null],\n        currPage: 1,\n      })\n    }\n    // const tradeposition = isL2Trade === true ? \"layer2\" : \"swap\";\n    const [isDropDown, setIsDropDown] = React.useState(true)\n\n    React.useEffect(() => {\n      let filters: any = {}\n      updateData.cancel()\n      handleFilterChange(filters)\n      return () => {\n        updateData.cancel()\n      }\n    }, [pagination?.pageSize])\n    return (\n      <TableStyled isMobile={isMobile} currentheight={currentHeight}>\n        {showFilter &&\n          (isMobile && isDropDown ? (\n            <Link\n              variant={'body1'}\n              display={'inline-flex'}\n              width={'100%'}\n              justifyContent={'flex-end'}\n              paddingRight={2}\n              onClick={() => setIsDropDown(false)}\n            >\n              {t('labelShowFilter')}\n            </Link>\n          ) : (\n            <TableFilterStyled>\n              <Filter\n                {...{\n                  filterDate,\n                  handleFilterChange,\n                  filterType,\n                  handleReset,\n                }}\n              />\n            </TableFilterStyled>\n          ))}\n        <Table\n          className={'scrollable'}\n          {...{\n            ...defaultArgs,\n            rowHeight,\n            headerRowHeight,\n            showloading: showLoading,\n            ...rest,\n            rawData: rawData ?? [],\n          }}\n        />\n        {accountId && showFilter && !isTaiko && (\n          <Typography\n            display={'flex'}\n            justifyContent={'flex-end'}\n            textAlign={'right'}\n            paddingRight={5 / 2}\n            paddingY={1}\n            component={'span'}\n          >\n            <Trans i18nKey={'labelGoExplore'} ns={'common'}>\n              View transactions on\n              <Link\n                display={'inline-flex'}\n                target='_blank'\n                rel='noopener noreferrer'\n                href={Explorer + `/account/${accountId}`}\n                paddingLeft={1 / 2}\n              >\n                block explorer\n              </Link>\n            </Trans>\n          </Typography>\n        )}\n        {pagination && (\n          <TablePagination\n            height={rowHeight}\n            page={pagination.page}\n            pageSize={pageSize}\n            total={pagination.total}\n            onPageChange={handlePageChange}\n          />\n        )}\n      </TableStyled>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/tradeNFTTable/components/Filter.tsx",
    "content": "import React from 'react'\nimport styled from '@emotion/styled'\nimport { Grid, MenuItem } from '@mui/material'\nimport { withTranslation, WithTranslation } from 'react-i18next'\nimport { Button, DateRangePicker, TextField } from '../../../basic-lib'\nimport { DropDownIcon } from '@loopring-web/common-resources'\nimport { FilterTradeNFTTypes } from '../Interface'\nimport { useSettings } from '../../../../stores'\nimport { DateRange } from '@mui/lab'\n\nexport interface FilterProps {\n  filterDate?: DateRange<Date | string>\n  filterType: FilterTradeNFTTypes\n  handleReset: () => void\n  handleFilterChange: ({ type, date }: any) => void\n}\n\nconst StyledTextFiled = styled(TextField)`\n  &.MuiTextField-root {\n    max-width: initial;\n  }\n\n  .MuiInputBase-root {\n    width: initial;\n    max-width: initial;\n  }\n`\n\nexport enum FilterTradeTypes {\n  maker = 'Maker',\n  taker = 'Taker',\n  allTypes = 'all',\n}\n\nexport const Filter = withTranslation('tables', { withRef: true })(\n  ({\n    t,\n    filterDate = [null, null],\n    filterType,\n    // filterPairs = [],\n    // filterPair,\n    handleReset,\n    handleFilterChange,\n  }: // marketMap,\n  FilterProps & WithTranslation) => {\n    const FilterTradeTypeList = [\n      {\n        label: t('labelFilterTradeNFTAll'),\n        value: FilterTradeNFTTypes.allTypes,\n      },\n      {\n        label: t('labelFilterTradeNFTSell'),\n        value: FilterTradeNFTTypes.sell,\n      },\n      {\n        label: t('labelFilterTradeNFTBuy'),\n        value: FilterTradeNFTTypes.buy,\n      },\n    ]\n\n    const { isMobile } = useSettings()\n    return (\n      <Grid container spacing={2} alignItems={'center'}>\n        <Grid item xs={6} md={3} order={isMobile ? 1 : 0}>\n          <StyledTextFiled\n            id='table-amm-filter-types'\n            select\n            fullWidth\n            value={filterType}\n            onChange={(event: React.ChangeEvent<{ value: unknown }>) => {\n              handleFilterChange({ type: event.target.value })\n            }}\n            inputProps={{ IconComponent: DropDownIcon }}\n          >\n            {FilterTradeTypeList.map((o) => (\n              <MenuItem key={o.value} value={o.value}>\n                {o.label}\n              </MenuItem>\n            ))}\n          </StyledTextFiled>\n        </Grid>\n        <Grid item xs={12} md={6} order={isMobile ? 0 : 1}>\n          <DateRangePicker\n            value={filterDate}\n            onChange={(date: any) => {\n              handleFilterChange({ date: date })\n            }}\n          />\n        </Grid>\n        <Grid item xs={6} md={3} order={2}>\n          <Button\n            fullWidth\n            variant={'outlined'}\n            size={'medium'}\n            color={'primary'}\n            onClick={handleReset}\n          >\n            {t('labelFilterReset')}\n          </Button>\n        </Grid>\n      </Grid>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/tradeNFTTable/index.ts",
    "content": "export * from './TradeNFTTable'\nexport * from './Interface'\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/tradeRaceTable/TradeRaceTable.tsx",
    "content": "import { PlaceComponent, Table } from '../../basic-lib'\nimport { withTranslation } from 'react-i18next'\nimport { getShortAddr } from '@loopring-web/common-resources'\nimport { Box } from '@mui/material'\n\nexport const TradeRaceTable = withTranslation('tables')(\n  <R extends object>({\n    rawData,\n    column,\n    showloading,\n    scrollable,\n  }: {\n    rawData: R\n    column: { key: string; label: string }[]\n    showloading: boolean\n    scrollable: boolean\n  }) => {\n    const defaultArgs: any = {\n      columnMode: column.length\n        ? column.map((item, index) => ({\n            key: item.key,\n            name: item.label,\n            width: 'auto',\n            headerCellClass:\n              index == 0\n                ? 'textAlignLeft'\n                : column.length == index + 1\n                ? 'textAlignRight'\n                : `textAlignCenter`,\n            cellClass:\n              index == 0\n                ? 'textAlignLeft'\n                : column.length == index + 1\n                ? 'rdg-cell-value textAlignRight'\n                : 'rdg-cell-value textAlignCenter',\n            formatter: ({ row }: any) => {\n              if (/address/gi.test(item.key.toLowerCase())) {\n                return getShortAddr(row[item.key])\n              } else if (/rank/gi.test(item.key.toLowerCase())) {\n                return (\n                  <Box className='rdg-cell-value'>\n                    <PlaceComponent rank={row.rank} />\n                  </Box>\n                )\n              } else {\n                return row[item.key] ?? ''\n              }\n            },\n          }))\n        : [],\n      generateRows: (rawData: R) => rawData,\n      generateColumns: ({ columnsRaw }: any) => columnsRaw,\n    }\n\n    return (\n      <Table\n        className={scrollable ? 'scrollable' : ''}\n        {...{\n          ...defaultArgs,\n          rawData: rawData,\n          showloading,\n        }}\n      />\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/tradeRaceTable/TradeRaceTableConfig.tsx",
    "content": "import React from 'react'\nimport styled from '@emotion/styled'\nimport { Box } from '@mui/material'\nimport { TablePaddingX } from '../../styled'\nimport { Column, PlaceComponent, Table } from '../../basic-lib'\nimport { withTranslation } from 'react-i18next'\nimport { getShortAddr, RowConfig } from '@loopring-web/common-resources'\n\nconst TableStyled = styled(Box)<{ height: number | undefined | string }>`\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n\n  .rdg {\n    height: ${({ height }) => height}px;\n    --template-columns: 10% auto auto !important;\n    height: auto;\n\n    .rdgCellCenter {\n      height: 100%;\n      justify-content: center;\n      align-items: center;\n    }\n\n    .textAlignRight {\n      text-align: right;\n    }\n\n    .textAlignCenter {\n      text-align: center;\n    }\n\n    .textAlignLeft {\n      text-align: left;\n    }\n  }\n\n  ${({ theme }) => TablePaddingX({ pLeft: theme.unit * 3, pRight: theme.unit * 3 })}\n` as typeof Box\n\nexport const TradeRaceTableConfig = withTranslation('tables')(\n  ({ rawData, column, showloading, scrollable, t, ...props }: any) => {\n    const getColumnMode = React.useCallback(\n      (): Column<any, unknown>[] =>\n        column.length\n          ? column.map((item: any, index: number) => ({\n              key: item.key,\n              name: item.label,\n              width: 'auto',\n              headerCellClass:\n                index == 0\n                  ? 'textAlignLeft'\n                  : column.length == index + 1\n                  ? 'textAlignRight'\n                  : `textAlignCenter`,\n              cellClass:\n                index == 0\n                  ? 'textAlignLeft'\n                  : column.length == index + 1\n                  ? 'rdg-cell-value textAlignRight'\n                  : 'rdg-cell-value textAlignCenter',\n              formatter: ({ row }: any) => {\n                if (/address/gi.test(item.key.toLowerCase())) {\n                  return getShortAddr(row[item.key])\n                }\n\n                if (/rank/gi.test(item.key.toLowerCase())) {\n                  const value = row[item.key]\n                  return (\n                    <Box className='rdg-cell-value'>\n                      <PlaceComponent rank={value} />\n                    </Box>\n                  )\n                }\n                return row[item.key] ?? ''\n              },\n            }))\n          : [],\n      [],\n    )\n\n    const defaultArgs: any = {\n      columnMode: getColumnMode(),\n      generateRows: (rawData: any) => rawData,\n      generateColumns: ({ columnsRaw }: any) => columnsRaw as Column<any, unknown>[],\n    }\n\n    return (\n      <TableStyled height={(rawData.length + 1) * RowConfig.rowHeight}>\n        <Table\n          className={'scrollable'}\n          rawData={rawData}\n          {...{ ...defaultArgs, ...props, showloading }}\n        />\n      </TableStyled>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/tradeRaceTable/index.ts",
    "content": "export { TradeRaceTable } from './TradeRaceTable'\n// export { TradeRaceTableConfig } from \"./TradeRaceTableConfig\";\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/tradeRroTable/TradePro.tsx",
    "content": "import { Box, BoxProps, Typography } from '@mui/material'\nimport { TFunction, withTranslation, WithTranslation } from 'react-i18next'\nimport moment from 'moment'\nimport { Column, Table } from '../../basic-lib'\nimport {\n    EmptyValueTag,\n    getValuePrecisionThousand,\n    MarketRowHeight,\n    SECOND_FORMAT,\n    TradeTypes,\n} from '@loopring-web/common-resources'\nimport { RawDataTradeItem } from '../tradeTable'\nimport { useSettings } from '../../../stores'\nimport styled from '@emotion/styled'\nimport { TablePaddingX } from '../../styled'\nimport { Currency, MarketInfo } from '@loopring-web/loopring-sdk'\n\nexport type TradeProTableProps = {\n    rawData: RawDataTradeItem[]\n    precision: number\n    marketInfo: MarketInfo\n    currentheight?: number\n    rowHeight?: number\n    headerRowHeight?: number\n}\n\nconst TableStyled = styled(Box)`\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n\n  .rdg {\n    height: ${(props: any) => props.currentheight}px;\n    //--template-columns: 300px 120px auto auto !important;\n\n    .rdg-cell.action {\n      display: flex;\n      justify-content: center;\n      align-items: center;\n    }\n\n    .rdg-header-row {\n      font-size: ${({theme}) => theme.fontDefault.body2};\n      color: var(--color-text-third);\n      // background-color: inherit !important;\n    }\n\n    .text-align-right {\n      text-align: right;\n    }\n  }\n\n  ${({theme}) => TablePaddingX({pLeft: theme.unit * 2, pRight: theme.unit * 2})}\n` as (props: { currentheight?: number } & BoxProps) => JSX.Element\n\nexport const TradePro = withTranslation('tables')(\n    ({\n         t,\n         rawData,\n         marketInfo,\n         // quotePrecision,\n         currentheight,\n         rowHeight = MarketRowHeight,\n         headerRowHeight = MarketRowHeight,\n         // tokenMap,\n         precision,\n         ...rest\n     }: WithTranslation & TradeProTableProps) => {\n        const {currency, isMobile} = useSettings()\n        // @ts-ignore\n        const [, baseSymbol, quoteSymbol] = marketInfo?.market?.match(/(\\w+)-(\\w+)/i)\n        const getColumnModeAssets = (\n            t: TFunction,\n            _currency: Currency,\n            // quotePrecision,\n            baseSymbol: string,\n            quoteSymbol: string,\n            precision: number,\n        ): Column<Required<RawDataTradeItem>, unknown>[] => [\n            ...[\n                {\n                    key: 'price',\n                    name: t('labelTradeProPrice', {symbol: quoteSymbol}),\n                    // @ts-ignore\n                    formatter: ({row}) => {\n                        const color =\n                            row?.side === TradeTypes.Buy ? 'var(--color-error)' : 'var(--color-success)'\n                        const {value} = row?.price ?? {}\n\n                        // const precision = row['precision'] || 6\n                        const renderValue = value\n                            ? getValuePrecisionThousand(value, undefined, undefined, precision, true)\n                            : EmptyValueTag\n\n                        return (\n                            <Box className='rdg-cell-value'>\n                                <Typography\n                                    textAlign={'left'}\n                                    color={color}\n                                    variant={'body2'}\n                                    lineHeight={`${MarketRowHeight}px`}\n                                >\n                                    {renderValue}\n                                </Typography>\n                            </Box>\n                        )\n                    },\n                },\n                {\n                    key: 'amount',\n                    name: t('labelTradeProAmount', {symbol: baseSymbol}),\n                    headerCellClass: 'text-align-right',\n                    // @ts-ignore\n                    formatter: ({row}) => {\n                        const {volume} = row['amount']\n                        // getValuePrecisionThousand(volume, precision, precision, precision, true)\n                        // const value =\n                        return (\n                            <Box className='rdg-cell-value'>\n                                <Typography\n                                    className=' text-align-right'\n                                    textAlign={'right'}\n                                    variant={'body2'}\n                                    lineHeight={`${MarketRowHeight}px`}\n                                >\n                                    {volume ? volume : EmptyValueTag}\n                                </Typography>\n                            </Box>\n                        )\n                    },\n                },\n            ],\n            ...(isMobile\n                ? []\n                : [\n                    {\n                        key: 'time',\n                        name: t('labelTradeTime'),\n                        headerCellClass: 'text-align-right',\n                        // @ts-ignore\n                        formatter: ({row}) => {\n                            const time = moment(new Date(row['time'])).format(SECOND_FORMAT) //,M-DD\n                            return (\n                                <Box className='rdg-cell-value'>\n                                    <Typography\n                                        className=' text-align-right'\n                                        textAlign={'right'}\n                                        variant={'body2'}\n                                        lineHeight={`${MarketRowHeight}px`}\n                                    >\n                                        {time}\n                                    </Typography>\n                                </Box>\n                            )\n                        },\n                    },\n                ]),\n        ]\n        const defaultArgs: any = {\n            rawData: rawData,\n            columnMode: getColumnModeAssets(\n                t,\n                currency,\n                // quotePrecision,\n                baseSymbol,\n                quoteSymbol,\n                precision,\n            ).filter((o) => !o.hidden),\n            generateRows: (rawData: any) => rawData,\n            generateColumns: ({columnsRaw}: any) => columnsRaw as Column<RawDataTradeItem, unknown>[],\n            style: {\n                // backgroundColor: ({colorBase}: any) => `${colorBase.box}`\n            },\n        }\n\n        return (\n            <TableStyled currentheight={currentheight}>\n                <Table\n                    currentheight={currentheight}\n                    {...{\n                        ...defaultArgs,\n                        rawData: rawData,\n                        // quotePrecision,\n                        rowHeight,\n                        headerRowHeight,\n                        ...rest,\n                    }}\n                />\n            </TableStyled>\n        )\n    },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/tradeRroTable/index.ts",
    "content": "export * from './TradePro'\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/tradeRroTable/tradeTable.stories.tsx",
    "content": "import styled from '@emotion/styled'\nimport { Meta, Story } from '@storybook/react'\nimport { withTranslation } from 'react-i18next'\nimport { MemoryRouter } from 'react-router-dom'\nimport { TradePro } from './index'\nimport { RawDataTradeItem } from '../tradeTable'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nconst Style = styled.div`\n  flex: 1;\n  height: 100%;\n  flex: 1;\n`\n\nconst rawData: RawDataTradeItem[] = [\n  {\n    role: sdk.OrderMakerType.maker,\n    amount: {\n      from: {\n        key: 'LRC',\n        value: 2333,\n      },\n      to: {\n        key: 'ETH',\n        value: 1.05,\n      },\n      volume: 1111,\n    },\n    price: {\n      key: 'ETH',\n      value: 1785.65,\n    },\n    fee: {\n      key: 'LRC',\n      value: 2.55,\n    },\n    time: 0,\n    __raw__: {},\n  },\n  {\n    role: sdk.OrderMakerType.maker,\n    amount: {\n      from: {\n        key: 'LRC',\n        value: 2333,\n      },\n      to: {\n        key: 'ETH',\n        value: 1.05,\n      },\n      volume: 1111,\n    },\n    price: {\n      key: 'ETH',\n      value: 1785.65,\n    },\n    fee: {\n      key: 'LRC',\n      value: 2.55,\n    },\n    time: 0,\n    __raw__: {},\n  },\n  {\n    role: sdk.OrderMakerType.maker,\n    amount: {\n      from: {\n        key: 'LRC',\n        value: 2333,\n      },\n      to: {\n        key: 'ETH',\n        value: 1.05,\n      },\n      volume: 1111,\n    },\n    price: {\n      key: 'ETH',\n      value: 1785.65,\n    },\n    fee: {\n      key: 'LRC',\n      value: 2.55,\n    },\n    time: 0,\n    __raw__: {},\n  },\n  {\n    role: sdk.OrderMakerType.maker,\n    amount: {\n      from: {\n        key: 'LRC',\n        value: 2333,\n      },\n      to: {\n        key: 'ETH',\n        value: 1.05,\n      },\n      volume: 1111,\n    },\n    price: {\n      key: 'ETH',\n      value: 1785.65,\n    },\n    fee: {\n      key: 'LRC',\n      value: 2.55,\n    },\n    time: 0,\n    __raw__: {},\n  },\n  {\n    role: sdk.OrderMakerType.maker,\n    amount: {\n      from: {\n        key: 'LRC',\n        value: 2333,\n      },\n      to: {\n        key: 'ETH',\n        value: 1.05,\n      },\n      volume: 1111,\n    },\n    price: {\n      key: 'ETH',\n      value: 1785.65,\n    },\n    fee: {\n      key: 'LRC',\n      value: 2.55,\n    },\n    time: 0,\n    __raw__: {},\n  },\n]\n\nconst Template: Story<any> = withTranslation()((args: any) => {\n  return (\n    <>\n      <Style>\n        <MemoryRouter initialEntries={['/']}>\n          <TradePro {...args} />\n        </MemoryRouter>\n      </Style>\n    </>\n  )\n}) as Story<any>\n\n// @ts-ignore\nexport const Trade = Template.bind({})\n\nTrade.args = {\n  rawData: rawData,\n  pagination: {\n    pageSize: 5,\n  },\n  showFilter: true,\n}\n\nexport default {\n  title: 'components/TableList/TradePro',\n  component: TradePro,\n  argTypes: {},\n} as Meta\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/tradeTable/TradeTable.tsx",
    "content": "import React from 'react'\nimport { Box, BoxProps, Link, Typography } from '@mui/material'\nimport styled from '@emotion/styled'\nimport { TFunction, Trans, withTranslation, WithTranslation } from 'react-i18next'\nimport moment from 'moment'\nimport { Column, Table, TablePagination } from '../../basic-lib'\nimport { TableFilterStyled, TablePaddingX } from '../../styled'\nimport { Filter, FilterTradeTypes } from './components/Filter'\n\nimport {\n  DirectionTag,\n  EmptyValueTag,\n  Explorer,\n  getValuePrecisionThousand,\n  globalSetup,\n  RowConfig,\n  TableType,\n} from '@loopring-web/common-resources'\nimport { useSettings } from '../../../stores'\nimport { DateRange } from '@mui/lab'\nimport { Currency, MarketTradeInfo } from '@loopring-web/loopring-sdk'\nimport { XOR } from '../../../types/lib'\nimport { useLocation } from 'react-router-dom'\nimport _ from 'lodash'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nexport enum TradeItemCounterparty {\n  orderbook = 'Orderbook',\n  pool = 'Pool',\n}\n\nexport type RawDataTradeItem = {\n  // side: keyof typeof TradeTypes;\n  role: sdk.OrderMakerType\n  amount: {\n    from: {\n      key: string\n      value: number | undefined\n    }\n    to: {\n      key: string\n      value: number | undefined\n    }\n    volume?: number\n  }\n  counterParty?: TradeItemCounterparty\n  price: {\n    key: string\n    value: number | undefined\n  }\n  fee: {\n    key: string\n    value: number | undefined\n  }\n  time: number\n  __raw__: Partial<MarketTradeInfo>\n}\n\nexport type TradeTableProps = {\n  rawData: RawDataTradeItem[]\n\n  // getUserTradeList?: (param: Omit<GetUserTradesRequest, 'accountId'>) => void;\n  getUserTradeList?: (param: {\n    market?: string\n    page: number\n    total?: number\n    pageSize: number\n    // offset: (page - 1) * pageSize,\n    // limit: pageSize,\n    orderHash?: any\n    fillTypes?: any\n    fromId?: any\n  }) => void\n  pagination?: {\n    page: number\n    pageSize: number\n    total: number\n  }\n\n  currentheight?: number\n  rowHeight?: number\n  headerRowHeight?: number\n  isL2Trade?: boolean\n  marketMap?: any\n  showLoading?: boolean\n  accAddress?: string\n  accountId?: number\n} & XOR<{ showFilter: true; filterPairs: string[] }, { showFilter?: false }>\n\nconst TableStyled = styled(Box)<\n  BoxProps & {\n    isMobile?: boolean\n    currentheight?: number\n    tradeposition: string\n  }\n>`\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n\n  .rdg {\n    height: ${(props: any) => props.currentheight}px;\n\n    ${({ isMobile, tradeposition }) =>\n      !isMobile\n        ? `--template-columns: ${\n            tradeposition === 'swap'\n              ? '300px 120px auto auto !important;'\n              : '100px 340px auto 120px auto auto !important;'\n          }`\n        : ` --template-columns: 40% 40% 20%  !important;`}\n\n    .rdg-cell.action {\n      display: flex;\n      justify-content: center;\n      align-items: center;\n    }\n\n    .rdg-header-row {\n      // background-color: inherit !important;\n    }\n\n    .textAlignRight {\n      text-align: right;\n    }\n  }\n\n  ${({ theme }) => TablePaddingX({ pLeft: theme.unit * 3, pRight: theme.unit * 3 })}\n` as (\n  props: {\n    isMobile?: boolean\n    currentheight?: number\n    tradeposition: string\n  } & BoxProps,\n) => JSX.Element\n\nconst getColumnModeAssets = (\n  t: TFunction,\n  _currency: Currency,\n  tokenMap: any,\n  isL2Trade: boolean,\n): Column<RawDataTradeItem, unknown>[] => {\n  if (isL2Trade) {\n    return [\n      {\n        key: 'role',\n        name: t('labelTradeRole'),\n        formatter: ({ row }) => {\n          const value = row['role']\n          const renderValue =\n            value === sdk.OrderMakerType.maker ? t('labelTradeRoleMaker') : t('labelTradeRoleTaker')\n          return <Box className='rdg-cell-value'>{renderValue}</Box>\n        },\n      },\n      {\n        key: 'side',\n        name: t('labelTradeSide'),\n        formatter: ({ row }) => {\n          // const tradeType = row[ 'side' ] === TradeTypes.Buy ? t('labelBuy') : t('labelSell')\n          const { from, to } = row['amount']\n          const precisionFrom = tokenMap ? tokenMap[from.key]?.precision : undefined\n          const precisionTo = tokenMap ? tokenMap[to.key]?.precision : undefined\n          const fromValue = from.value\n            ? getValuePrecisionThousand(from.value, precisionFrom, precisionFrom)\n            : EmptyValueTag\n          const toValue = to.value\n            ? getValuePrecisionThousand(to.value, precisionTo, precisionTo)\n            : EmptyValueTag\n\n          return (\n            <Box className='rdg-cell-value' height={'100%'} display={'flex'} alignItems={'center'}>\n              <Typography>\n                {`${fromValue} ${from.key} ${DirectionTag} ${toValue} ${to.key}`}\n              </Typography>\n            </Box>\n          )\n        },\n      },\n      {\n        key: 'counterparty',\n        name: t('labelTradeConterparty'),\n        formatter: ({ row }) => {\n          const value = row['counterParty']\n          const renderValue =\n            value === TradeItemCounterparty.orderbook\n              ? t('labelTradeCounterpartyOrderbook')\n              : t('labelTradeCounterpartyPool')\n          return <Box className='rdg-cell-value'>{renderValue}</Box>\n        },\n      },\n      {\n        key: 'price',\n        name: t('labelTradePrice'),\n        headerCellClass: 'textAlignRight',\n        formatter: ({ row }) => {\n          const { value } = row['price']\n          const precision = row['precision'] || 6\n          const renderValue = value\n            ? getValuePrecisionThousand(value, undefined, undefined, precision, true, {\n                isPrice: true,\n              })\n            : EmptyValueTag\n          return <Box className='rdg-cell-value textAlignRight'>{renderValue}</Box>\n        },\n      },\n      {\n        key: 'fee',\n        name: t('labelTxTradingFee'),\n        headerCellClass: 'textAlignRight',\n        formatter: ({ row }) => {\n          const { key, value } = row['fee']\n          // myLog({value})\n          return <div className='rdg-cell-value textAlignRight'>{`${value} ${key}`}</div>\n        },\n      },\n      {\n        key: 'time',\n        name: t('labelTradeTime'),\n        headerCellClass: 'textAlignRight',\n        // minWidth: 400,\n        formatter: ({ row }) => {\n          const time = moment(new Date(row['time']), 'YYYYMMDDHHMM').fromNow()\n          return <div className='rdg-cell-value textAlignRight'>{time}</div>\n        },\n      },\n    ]\n  } else {\n    return [\n      {\n        key: 'side',\n        name: t('labelTradeSide'),\n        formatter: ({ row }) => {\n          // const tradeType = row[ 'side' ] === TradeTypes.Buy ? t('labelBuy') : t('labelSell')\n          const { from, to } = row['amount']\n          const precisionFrom = tokenMap ? tokenMap[from.key]?.precision : undefined\n          const precisionTo = tokenMap ? tokenMap[to.key]?.precision : undefined\n          const fromValue = from.value\n            ? getValuePrecisionThousand(from.value, precisionFrom, precisionFrom)\n            : EmptyValueTag\n          const toValue = to.value\n            ? getValuePrecisionThousand(to.value, precisionTo, precisionTo)\n            : EmptyValueTag\n\n          return (\n            <Box className='rdg-cell-value' height={'100%'} display={'flex'} alignItems={'center'}>\n              <Typography>\n                {`${fromValue} ${from.key} ${DirectionTag} ${toValue} ${to.key}`}\n              </Typography>\n            </Box>\n          )\n        },\n      },\n      {\n        key: 'price',\n        name: t('labelTradePrice'),\n        headerCellClass: 'textAlignRight',\n        formatter: ({ row }) => {\n          const { value } = row['price']\n          const precision = row['precision'] || 6\n          const renderValue = value\n            ? getValuePrecisionThousand(value, undefined, undefined, precision, true, {\n                isPrice: true,\n              })\n            : EmptyValueTag\n          return <Box className='rdg-cell-value textAlignRight'>{renderValue}</Box>\n        },\n      },\n      {\n        key: 'fee',\n        name: t('labelTxTradingFee'),\n        headerCellClass: 'textAlignRight',\n        formatter: ({ row }) => {\n          const { key, value } = row['fee']\n          // myLog({value})\n          return <div className='rdg-cell-value textAlignRight'>{`${value} ${key}`}</div>\n        },\n      },\n      {\n        key: 'time',\n        name: t('labelTradeTime'),\n        headerCellClass: 'textAlignRight',\n        // minWidth: 400,\n        formatter: ({ row }) => {\n          const time = moment(new Date(row['time']), 'YYYYMMDDHHMM').fromNow()\n          return <div className='rdg-cell-value textAlignRight'>{time}</div>\n        },\n      },\n    ]\n  }\n}\n\nconst getColumnModeMobileAssets = (\n  t: TFunction,\n  _currency: Currency,\n  tokenMap: any,\n  isL2Trade: boolean,\n): Column<RawDataTradeItem, unknown>[] => {\n  return [\n    ...(isL2Trade\n      ? [\n          {\n            key: 'role',\n            name: t('labelTradeRole') + '/' + t('labelTradeConterparty'),\n            // @ts-ignore\n            formatter: ({ row }) => {\n              const value = row['role']\n              const renderValue =\n                value === sdk.OrderMakerType.maker\n                  ? t('labelTradeRoleMaker')\n                  : t('labelTradeRoleTaker')\n              const counterParty =\n                row.counterParty === TradeItemCounterparty.orderbook\n                  ? t('labelTradeCounterpartyOrderbook')\n                  : t('labelTradeCounterpartyPool')\n              return (\n                <Box\n                  className='rdg-cell-value'\n                  display={'flex'}\n                  flexDirection={'column'}\n                  justifyContent={'center'}\n                  height={'100%'}\n                >\n                  <Typography>{renderValue}</Typography>\n                  <Typography color={'textSecondary'} variant={'body2'}>\n                    {counterParty}\n                  </Typography>\n                </Box>\n              )\n            },\n          },\n        ]\n      : []),\n    {\n      key: 'side',\n      name: t('labelTradeSide') + '/' + t('labelTxTradingFee'),\n      headerCellClass: 'textAlignRight',\n      formatter: ({ row }) => {\n        // const tradeType = row[ 'side' ] === TradeTypes.Buy ? t('labelBuy') : t('labelSell')\n        const { from, to } = row['amount']\n        const precisionFrom = tokenMap ? tokenMap[from.key]?.precision : undefined\n        const precisionTo = tokenMap ? tokenMap[to.key]?.precision : undefined\n        const fromValue = from.value\n          ? getValuePrecisionThousand(from.value, precisionFrom, precisionFrom)\n          : EmptyValueTag\n        const toValue = to.value\n          ? getValuePrecisionThousand(to.value, precisionTo, precisionTo)\n          : EmptyValueTag\n        const { key, value } = row['fee']\n\n        return (\n          <Box\n            className='rdg-cell-value'\n            display={'flex'}\n            flexDirection={'column'}\n            justifyContent={'center'}\n            alignItems={'flex-end'}\n            textAlign={'right'}\n            height={'100%'}\n          >\n            <Typography variant={'body2'}>\n              {`${fromValue} ${from.key} ${DirectionTag} ${toValue} ${to.key}`}\n            </Typography>\n            <Typography variant={'body2'} color={'textSecondary'}>\n              {t('labelFee', { ns: 'common' }) + `: ${value} ${key}`}\n            </Typography>\n          </Box>\n        )\n      },\n    },\n    {\n      key: 'price',\n      name: t('labelTradePrice') + '/' + t('labelTradeTime'),\n      headerCellClass: 'textAlignRight',\n      formatter: ({ row }) => {\n        const precision = row['precision'] || 6\n        const time = moment(new Date(row['time']), 'YYYYMMDDHHMM').fromNow()\n        const renderValue = row.price\n          ? getValuePrecisionThousand(\n              row.price.value,\n              undefined,\n              undefined,\n              precision,\n              true,\n              // { isPrice: true }\n            )\n          : EmptyValueTag\n\n        return (\n          <Box\n            className='rdg-cell-value textAlignRight'\n            display={'flex'}\n            flexDirection={'column'}\n            justifyContent={'center'}\n            height={'100%'}\n          >\n            <Typography>{renderValue}</Typography>\n            <Typography color={''} textOverflow={'ellipsis'} variant={'body2'}>\n              {time}\n            </Typography>\n          </Box>\n        )\n      },\n    },\n  ]\n}\n\nexport const TradeTable = withTranslation('tables')(\n  ({\n    t,\n    pagination,\n    showFilter,\n    filterPairs = [],\n    rawData,\n    currentheight,\n    rowHeight = RowConfig.rowHeight,\n    headerRowHeight = RowConfig.rowHeaderHeight,\n    tokenMap = undefined,\n    isL2Trade = false,\n    getUserTradeList,\n    showLoading = false,\n    accAddress,\n    accountId,\n    ...rest\n  }: WithTranslation & TradeTableProps & { tokenMap?: any }) => {\n    const { search } = useLocation()\n    const searchParams = new URLSearchParams(search)\n    const [filterType, setFilterType] = React.useState(FilterTradeTypes.allTypes)\n    const [filterDate, setFilterDate] = React.useState<DateRange<string | Date>>([null, null])\n    const [filterPair, setFilterPair] = React.useState('all')\n    // const [page, setPage] = React.useState(1);\n    // const [totalData, setTotalData] = React.useState<RawDataTradeItem[]>(rawData)\n    const { currency, isMobile, defaultNetwork } = useSettings()\n    const isTaiko = [sdk.ChainId.TAIKO, sdk.ChainId.TAIKOHEKLA].includes(defaultNetwork)\n    const defaultArgs: any = {\n      columnMode: isMobile\n        ? getColumnModeMobileAssets(t, currency, tokenMap, isL2Trade)\n        : getColumnModeAssets(t, currency, tokenMap, isL2Trade),\n      generateRows: (rawData: any) => rawData,\n      generateColumns: ({ columnsRaw }: any) => columnsRaw as Column<RawDataTradeItem, unknown>[],\n      style: {\n        backgroundColor: ({ colorBase }: any) => `${colorBase.box}`,\n      },\n    }\n\n    const pageSize = pagination ? pagination.pageSize : 10\n\n    const updateData = _.debounce(\n      ({\n        tableType,\n        currFilterPair = filterPair,\n        currPage = pagination?.page || 1,\n        currFilterType = filterType,\n      }) => {\n        if (tableType === 'filter') {\n          currPage = 1\n        }\n        const market = currFilterPair === 'all' ? '' : currFilterPair.replace(/\\s+/g, '')\n        if (getUserTradeList) {\n          getUserTradeList({\n            ...pagination,\n            pageSize,\n            market,\n            page: currPage,\n            fillTypes: currFilterType !== 'all' ? currFilterType : '',\n          })\n        }\n      },\n      globalSetup.wait,\n      //[filterPair, filterType, pageSize, getUserTradeList, pagination]\n    )\n\n    const handleFilterChange = React.useCallback(\n      ({ type = filterType, date = filterDate, pair = filterPair }) => {\n        setFilterType(type)\n        setFilterDate(date)\n        setFilterPair(pair)\n        updateData({\n          tableType: TableType.filter,\n          currFilterType: type,\n          currFilterDate: date,\n          currFilterPair: pair,\n        })\n      },\n      [updateData, filterDate, filterType, filterPair],\n    )\n\n    const handlePageChange = React.useCallback(\n      (page: number) => {\n        updateData({ tableType: TableType.page, currPage: page })\n      },\n      [updateData],\n    )\n\n    const handleReset = () => {\n      setFilterType(FilterTradeTypes.allTypes)\n      setFilterDate([null, null])\n      setFilterPair('all')\n      updateData({\n        tableType: 'filter',\n        currFilterType: FilterTradeTypes.allTypes,\n        currFilterDate: [null, null],\n        currFilterPair: 'all',\n        currPage: 1,\n      })\n    }\n    const tradeposition = isL2Trade === true ? 'layer2' : 'swap'\n    const [isDropDown, setIsDropDown] = React.useState(true)\n\n    React.useEffect(() => {\n      let filters: any = {}\n      updateData.cancel()\n      if (searchParams.get('market')) {\n        filters.pair = searchParams.get('market')\n      }\n      handleFilterChange(filters)\n      return () => {\n        updateData.cancel()\n      }\n    }, [pagination?.pageSize])\n    return (\n      <TableStyled isMobile={isMobile} currentheight={currentheight} tradeposition={tradeposition}>\n        {showFilter &&\n          (isMobile && isDropDown ? (\n            <Link\n              variant={'body1'}\n              display={'inline-flex'}\n              width={'100%'}\n              justifyContent={'flex-end'}\n              paddingRight={2}\n              onClick={() => setIsDropDown(false)}\n            >\n              {t('labelShowFilter')}\n            </Link>\n          ) : (\n            <TableFilterStyled>\n              <Filter\n                {...{\n                  filterPairs,\n                  handleFilterChange,\n                  filterType,\n                  filterDate,\n                  filterPair,\n                  handleReset,\n                }}\n              />\n            </TableFilterStyled>\n          ))}\n        <Table\n          className={'scrollable'}\n          {...{\n            ...defaultArgs,\n            rowHeight,\n            headerRowHeight,\n            showloading: showLoading,\n            ...rest,\n            rawData: rawData,\n          }}\n        />\n        {accountId && showFilter && !isTaiko && (\n          <Typography\n            display={'flex'}\n            justifyContent={'flex-end'}\n            textAlign={'right'}\n            paddingRight={5 / 2}\n            paddingY={1}\n          >\n            <Trans i18nKey={'labelGoExplore'} ns={'common'}>\n              View transactions on\n              <Link\n                display={'inline-flex'}\n                target='_blank'\n                rel='noopener noreferrer'\n                href={Explorer + `/account/${accountId}`}\n                paddingLeft={1 / 2}\n              >\n                block explorer\n              </Link>\n            </Trans>\n          </Typography>\n        )}\n        {pagination && (\n          <TablePagination\n            height={rowHeight}\n            page={pagination.page}\n            pageSize={pageSize}\n            total={pagination.total}\n            onPageChange={handlePageChange}\n          />\n        )}\n      </TableStyled>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/tradeTable/components/Filter.tsx",
    "content": "import React from 'react'\nimport styled from '@emotion/styled'\nimport { Grid, MenuItem } from '@mui/material'\nimport { withTranslation, WithTranslation } from 'react-i18next'\nimport { TextField } from '../../../basic-lib/form'\nimport { Button } from '../../../basic-lib/btns'\nimport { DropDownIcon } from '@loopring-web/common-resources'\nimport { DateRange } from '@mui/lab'\n\nexport interface FilterProps {\n  // rawData: RawDataTradeItem[];\n  filterDate: DateRange<Date | string>\n  filterType: FilterTradeTypes\n  filterPair: string\n  handleReset: () => void\n  handleFilterChange: ({ type, date }: any) => void\n  marketMap?: any\n  filterPairs: string[]\n}\n\nconst StyledTextFiled = styled(TextField)`\n  &.MuiTextField-root {\n    max-width: initial;\n  }\n  .MuiInputBase-root {\n    width: initial;\n    max-width: initial;\n  }\n`\n\nexport enum FilterTradeTypes {\n  maker = 'Maker',\n  taker = 'Taker',\n  allTypes = 'all',\n}\n\nexport const Filter = withTranslation('tables', { withRef: true })(\n  ({\n    t,\n    // filterDate,\n    // filterType,\n    filterPairs = [],\n    filterPair,\n    handleReset,\n    handleFilterChange,\n  }: // marketMap,\n  FilterProps & WithTranslation) => {\n    const rawPairList = [].slice\n      .call(filterPairs)\n      // .map((item: string) => item.replace(\"-\", \" - \"))\n      .sort((a: string, b: string) => {\n        return a.localeCompare(b)\n      })\n\n    const formattedRawPairList = [\n      {\n        label: t('labelFilterAllPairs'),\n        value: 'all',\n      },\n      ...Array.from(new Set(rawPairList)).map((pair: string) => ({\n        label: pair, //.replace(\"-\", \" - \"),\n        value: pair,\n      })),\n    ]\n\n    return (\n      <Grid container spacing={2} alignItems={'center'}>\n        <Grid item xs={6} lg={2}>\n          <StyledTextFiled\n            id='table-trade-filter-pairs'\n            select\n            fullWidth\n            value={filterPair}\n            onChange={(event: React.ChangeEvent<{ value: unknown }>) => {\n              handleFilterChange({ pair: event.target.value })\n            }}\n            inputProps={{ IconComponent: DropDownIcon }}\n          >\n            {formattedRawPairList.map((o) => (\n              <MenuItem key={o.value} value={o.value}>\n                {o.label}\n              </MenuItem>\n            ))}\n          </StyledTextFiled>\n        </Grid>\n        <Grid item xs={6} lg={2}>\n          <Button\n            fullWidth\n            variant={'outlined'}\n            size={'medium'}\n            color={'primary'}\n            onClick={handleReset}\n          >\n            {t('labelFilterReset')}\n          </Button>\n        </Grid>\n      </Grid>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/tradeTable/index.ts",
    "content": "export * from './TradeTable'\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/tradeTable/tradeTable.stories.tsx",
    "content": "import styled from '@emotion/styled'\nimport { Meta, Story } from '@storybook/react'\nimport { withTranslation } from 'react-i18next'\nimport { MemoryRouter } from 'react-router-dom'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nimport { RawDataTradeItem, TradeItemCounterparty, TradeTable } from './index'\n\nconst Style = styled.div`\n  flex: 1;\n  height: 100%;\n  flex: 1;\n`\n\nconst rawData: RawDataTradeItem[] = [\n  {\n    role: sdk.OrderMakerType.maker,\n    amount: {\n      from: {\n        key: 'eth',\n        value: 1234,\n      },\n      to: {\n        key: 'let',\n        value: 5678,\n      },\n      volume: 1234,\n    },\n    counterParty: TradeItemCounterparty.orderbook,\n    price: {\n      key: 'ETH',\n      value: 1200,\n    },\n    fee: {\n      key: 'LRC',\n      value: 0.1,\n    },\n    time: Date.now(),\n    __raw__: {} as any,\n  },\n  {\n    role: sdk.OrderMakerType.maker,\n    amount: {\n      from: {\n        key: 'eth',\n        value: 1234,\n      },\n      to: {\n        key: 'let',\n        value: 5678,\n      },\n      volume: 1234,\n    },\n    counterParty: TradeItemCounterparty.orderbook,\n    price: {\n      key: 'ETH',\n      value: 1200,\n    },\n    fee: {\n      key: 'LRC',\n      value: 0.1,\n    },\n    time: Date.now(),\n    __raw__: {} as any,\n  },\n  {\n    role: sdk.OrderMakerType.maker,\n    amount: {\n      from: {\n        key: 'eth',\n        value: 1234,\n      },\n      to: {\n        key: 'let',\n        value: 5678,\n      },\n      volume: 1234,\n    },\n    counterParty: TradeItemCounterparty.orderbook,\n    price: {\n      key: 'ETH',\n      value: 1200,\n    },\n\n    fee: {\n      key: 'LRC',\n      value: 0.1,\n    },\n    time: Date.now(),\n    __raw__: {} as any,\n  },\n  {\n    role: sdk.OrderMakerType.maker,\n    amount: {\n      from: {\n        key: 'eth',\n        value: 1234,\n      },\n      to: {\n        key: 'let',\n        value: 5678,\n      },\n      volume: 1234,\n    },\n    counterParty: TradeItemCounterparty.orderbook,\n    price: {\n      key: 'ETH',\n      value: 1200,\n    },\n    fee: {\n      key: 'LRC',\n      value: 0.1,\n    },\n    time: Date.now(),\n    __raw__: {} as any,\n  },\n]\n\nconst Template: Story<any> = withTranslation()((args: any) => {\n  return (\n    <>\n      <Style>\n        <MemoryRouter initialEntries={['/']}>\n          <TradeTable {...args} />\n        </MemoryRouter>\n      </Style>\n    </>\n  )\n}) as Story<any>\n\n// @ts-ignore\nexport const Trade = Template.bind({})\n\nTrade.args = {\n  rawData: rawData,\n  pagination: {\n    pageSize: 5,\n  },\n  showFilter: true,\n}\n\nexport default {\n  title: 'components/TableList/Trade',\n  component: TradeTable,\n  argTypes: {},\n} as Meta\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/transactionsTable/Interface.ts",
    "content": "import * as sdk from '@loopring-web/loopring-sdk'\n\n// export type TransactionSide = {\n//     address: string;\n//     env: string;\n// }\n\nexport enum TransactionStatus {\n  processing = 'processing',\n  processed = 'processed',\n  received = 'received',\n  failed = 'failed',\n}\n\nexport const TransactionTradeTypes = {\n  allTypes:\n    `${sdk.UserTxTypes.DEPOSIT},${sdk.UserTxTypes.TRANSFER},${sdk.UserTxTypes.DELEGATED_FORCE_WITHDRAW},${sdk.UserTxTypes.OFFCHAIN_WITHDRAWAL},` +\n    `${sdk.UserTxTypes.FORCE_WITHDRAWAL},` +\n    `${sdk.UserTxTypes.WITHDRAW_LUCKY_TOKEN},${sdk.UserTxTypes.SEND_LUCKY_TOKEN},${sdk.UserTxTypes.SEND_BACK_LUCKY_TOKEN},` +\n    `${sdk.UserTxTypes.UNIFIED_CLAIM},${sdk.UserTxTypes.L2_STAKING},` +\n    `${sdk.UserTxTypes.DUAL_INVESTMENT},${'change_password'}`,\n  receive: `${sdk.UserTxTypes.DEPOSIT}`,\n  send: `${sdk.UserTxTypes.TRANSFER},${sdk.UserTxTypes.OFFCHAIN_WITHDRAWAL},${sdk.UserTxTypes.OFFCHAIN_WITHDRAWAL}`,\n  forceWithdraw: `${sdk.UserTxTypes.DELEGATED_FORCE_WITHDRAW}`,\n  redPacket: `${sdk.UserTxTypes.WITHDRAW_LUCKY_TOKEN},${sdk.UserTxTypes.SEND_LUCKY_TOKEN},${sdk.UserTxTypes.SEND_BACK_LUCKY_TOKEN}`,\n}\n\nexport enum TransactionTradeViews {\n  allTypes = 'ALL',\n  receive = 'RECEIVE',\n  send = 'SEND',\n  forceWithdraw = 'FORCE_WITHDRAWAL',\n  redPacket = 'RED_PACKET',\n}\n\nexport type RawDataTransactionItem = {\n  side: sdk.UserTxTypes\n  // token?: string,\n  // tradeType: TransactionTradeTypes,\n  // from: string;\n  // to: string;\n  amount: {\n    unit: string\n    value: number\n  }\n  fee: {\n    unit: string\n    value: number\n  }\n  memo?: string\n  time: number\n  txnHash: string\n  status: TransactionStatus\n  path?: string\n} & Partial<sdk.UserTx>\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/transactionsTable/TransactionTable.tsx",
    "content": "import styled from '@emotion/styled'\nimport { Box, BoxProps, Link, Typography } from '@mui/material'\nimport { Trans, WithTranslation, withTranslation } from 'react-i18next'\nimport moment from 'moment'\nimport { Column, Table, TablePagination } from '../../basic-lib'\nimport {\n  CompleteIcon,\n  DepositIcon,\n  DirectionTag,\n  EmptyValueTag,\n  EXPLORE_TYPE,\n  Explorer,\n  getShortAddr,\n  getValuePrecisionThousand,\n  globalSetup,\n  L1L2_NAME_DEFINED,\n  MapChainId,\n  mapSpecialTokenName,\n  RedPacketIcon,\n  RewardIcon,\n  TableType,\n  TransferIcon,\n  UNIX_TIMESTAMP_FORMAT,\n  WaitingIcon,\n  WarningIcon,\n  WithdrawIcon,\n} from '@loopring-web/common-resources'\nimport { Filter } from './components/Filter'\nimport { TableFilterStyled, TablePaddingX } from '../../styled'\nimport {\n  RawDataTransactionItem,\n  TransactionStatus,\n  TransactionTradeTypes,\n  TransactionTradeViews,\n} from './Interface'\nimport { DateRange } from '@mui/lab'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nimport React from 'react'\nimport { useSettings } from '../../../stores'\nimport { useLocation } from 'react-router-dom'\nimport _ from 'lodash'\n\nexport type TxsFilterProps = {\n  tokenSymbol?: string\n  start?: number\n  end?: number\n  offset?: number\n  limit?: number\n  types?: sdk.UserTxTypes[] | string\n}\n\nconst TYPE_COLOR_MAPPING = [\n  { type: TransactionStatus.processed, color: 'success' },\n  { type: TransactionStatus.processing, color: 'warning' },\n  { type: TransactionStatus.received, color: 'warning' },\n  { type: TransactionStatus.failed, color: 'error' },\n]\n\nconst CellStatus = ({ row }: any) => {\n  const status = row['status']\n  const RenderValue = styled.div`\n    display: flex;\n    align-items: center;\n    color: ${({ theme }) =>\n      theme.colorBase[`${TYPE_COLOR_MAPPING.find((o) => o.type === status)?.color}`]};\n\n    & svg {\n      width: 24px;\n      height: 24px;\n    }\n  `\n  const svg =\n    status === 'processed' ? (\n      <CompleteIcon color={'success'} />\n    ) : status === 'processing' || status === 'received' ? (\n      <WaitingIcon color={'warning'} />\n    ) : (\n      <WarningIcon color={'error'} />\n    )\n  return <RenderValue>{svg}</RenderValue>\n}\n\nconst MemoCellStyled = styled(Box)`\n  max-width: 100px;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n  text-align: right;\n`\n\nconst TableStyled = styled(Box)<BoxProps & { isMobile?: boolean }>`\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n\n  .rdg {\n    ${({ isMobile }) =>\n      !isMobile\n        ? `--template-columns: 192px auto auto auto 120px 120px !important;`\n        : `--template-columns: 60% 40% !important;`}\n    .rdgCellCenter {\n      height: 100%;\n      justify-content: center;\n      align-items: center;\n    }\n\n    .textAlignRight {\n      text-align: right;\n    }\n\n    .textAlignCenter {\n      text-align: center;\n    }\n\n    .textAlignLeft {\n      text-align: left;\n    }\n  }\n\n  ${({ theme }) => TablePaddingX({ pLeft: theme.unit * 3, pRight: theme.unit * 3 })}\n` as (props: { isMobile?: boolean } & BoxProps) => JSX.Element\n\nexport interface TransactionTableProps {\n  etherscanBaseUrl?: string\n  rawData: RawDataTransactionItem[]\n  pagination?: {\n    pageSize: number\n    total: number\n  }\n  getTxnList: ({ tokenSymbol, start, end, limit, offset, types }: TxsFilterProps) => Promise<void>\n  filterTokens: string[]\n  showFilter?: boolean\n  showloading: boolean\n  accAddress: string\n  accountId: number\n}\n\nexport const TransactionTable = withTranslation(['tables', 'common'])(\n  (props: TransactionTableProps & WithTranslation) => {\n    const {\n      rawData,\n      pagination,\n      showFilter,\n      getTxnList,\n      filterTokens,\n      showloading,\n      etherscanBaseUrl,\n      accAddress,\n      accountId,\n      t,\n    } = props\n    const { isMobile, defaultNetwork } = useSettings()\n    const isTaiko = [sdk.ChainId.TAIKO, sdk.ChainId.TAIKOHEKLA].includes(defaultNetwork)\n    const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n    const { search } = useLocation()\n    const searchParams = new URLSearchParams(search)\n    const [page, setPage] = React.useState(1)\n    const [filterType, setFilterType] = React.useState<TransactionTradeViews>(\n      TransactionTradeViews.allTypes,\n    )\n    const [filterDate, setFilterDate] = React.useState<DateRange<Date | string>>(['', ''])\n    const [filterToken, setFilterToken] = React.useState<string>('all')\n\n    const updateData = _.debounce(\n      ({\n        tableType,\n        currFilterType = filterType,\n        currFilterDate = filterDate,\n        currFilterToken = filterToken,\n        currPage = page,\n        pageSize = pagination?.pageSize ?? 10,\n      }: {\n        tableType: TableType\n        currFilterType?: TransactionTradeViews\n        currFilterDate?: DateRange<Date | string>\n        currFilterToken?: string\n        currPage?: number\n        pageSize?: number\n      }) => {\n        if (tableType === 'filter') {\n          currPage = 1\n          setPage(1)\n        }\n        const tokenSymbol = currFilterToken === 'all' ? '' : currFilterToken\n        const formattedType = currFilterType.toUpperCase()\n        const types =\n          formattedType === TransactionTradeViews.receive\n            ? TransactionTradeTypes.receive //UserTxTypes.DEPOSIT\n            : formattedType === TransactionTradeViews.send\n            ? TransactionTradeTypes.send\n            : formattedType.toUpperCase() === TransactionTradeViews.forceWithdraw\n            ? TransactionTradeTypes.forceWithdraw\n            : TransactionTradeTypes.allTypes\n        const start = Number(moment(currFilterDate[0]).format(UNIX_TIMESTAMP_FORMAT))\n        const end = Number(moment(currFilterDate[1]).format(UNIX_TIMESTAMP_FORMAT))\n        getTxnList({\n          limit: pageSize,\n          offset: (currPage - 1) * pageSize,\n          types,\n          tokenSymbol: tokenSymbol,\n          start: Number.isNaN(start) ? -1 : start,\n          end: Number.isNaN(end) ? -1 : end,\n        })\n      },\n      globalSetup.wait,\n    )\n\n    const handleFilterChange = React.useCallback(\n      ({ type = filterType, date = filterDate, token = filterToken }) => {\n        setFilterType(type)\n        setFilterDate(date)\n        setFilterToken(token)\n\n        updateData({\n          tableType: TableType.filter,\n          currFilterType: type,\n          currFilterDate: date,\n          currFilterToken: token,\n        })\n      },\n      [updateData, filterDate, filterType, filterToken],\n    )\n\n    const handleReset = React.useCallback(() => {\n      setFilterType(TransactionTradeViews.allTypes)\n      setFilterDate([null, null])\n      setFilterToken('all')\n      updateData({\n        tableType: TableType.filter,\n        currFilterType: TransactionTradeViews.allTypes,\n        currFilterDate: [null, null],\n        currFilterToken: 'all',\n      })\n    }, [updateData])\n\n    const handlePageChange = React.useCallback(\n      (currPage: number) => {\n        if (currPage === page) return\n        setPage(currPage)\n        updateData({ tableType: TableType.page, currPage: currPage })\n      },\n      [updateData, page],\n    )\n\n    const getColumnModeTransaction = React.useCallback(\n      (): Column<any, unknown>[] => [\n        {\n          key: 'side',\n          name: t('labelTxSide'),\n          formatter: ({ row }) => {\n            const value = row.side\n            const renderValue =\n              value.toLowerCase() === sdk.UserTxTypes.TRANSFER &&\n              row.receiverAddress?.toUpperCase() === accAddress?.toUpperCase()\n                ? t(`labelTypeReceive`)\n                : t(`labelType${value?.toUpperCase()}`)\n            return (\n              <Box\n                className='rdg-cell-value'\n                flex={1}\n                display={'flex'}\n                alignItems={'center'}\n                justifyContent={'flex-start'}\n                height={'100%'}\n              >\n                {renderValue}\n              </Box>\n            )\n          },\n        },\n        {\n          key: 'amount',\n          name: t('labelTxAmount'),\n          headerCellClass: 'textAlignRight',\n          formatter: ({ row }) => {\n            const { unit, value } = row['amount']\n            const hasValue = Number.isFinite(value) && value > 0\n            const hasSymbol =\n              row.side.toLowerCase() === sdk.UserTxTypes.DELEGATED_FORCE_WITHDRAW\n                ? ''\n                : row.side.toLowerCase() === sdk.UserTxTypes.TRANSFER // TransactionTradeTypes.transfer\n                ? row.receiverAddress?.toUpperCase() === accAddress?.toUpperCase()\n                  ? '+'\n                  : '-'\n                : row.side.toLowerCase() === sdk.UserTxTypes.DEPOSIT //TransactionTradeTypes.deposit\n                ? '+'\n                : /chain_withdrawal/i.test(row.side.toLowerCase()) //TransactionTradeTypes.withdraw\n                ? '-'\n                : row.side.toLowerCase() === sdk.UserTxTypes.SEND_LUCKY_TOKEN\n                ? '-'\n                : row.side.toLowerCase() === sdk.UserTxTypes.SEND_BACK_LUCKY_TOKEN\n                ? '+'\n                : row.side.toLowerCase() === sdk.UserTxTypes.WITHDRAW_LUCKY_TOKEN\n                ? '+'\n                : row.side.toLowerCase() === sdk.UserTxTypes.UNIFIED_CLAIM\n                ? '+'\n                : ''\n\n            const renderValue = hasValue\n              ? `${getValuePrecisionThousand(value, undefined, undefined, undefined, false, {\n                  isTrade: true,\n                })}`\n              : EmptyValueTag\n            return (\n              <Box\n                className='rdg-cell-value textAlignRight'\n                title={`${hasSymbol}  ${\n                  row.side !== sdk.UserTxTypes.DELEGATED_FORCE_WITHDRAW\n                    ? hasValue\n                      ? `${renderValue} ${unit}`\n                      : renderValue\n                    : ''\n                }`}\n              >\n                {hasSymbol}\n                {row.side !== sdk.UserTxTypes.DELEGATED_FORCE_WITHDRAW && hasValue\n                  ? `${renderValue} ${mapSpecialTokenName(unit)}`\n                  : renderValue}\n              </Box>\n            )\n          },\n        },\n        {\n          key: 'fee',\n          name: t('labelTxNetworkFee'),\n          headerCellClass: 'textAlignRight',\n          formatter: ({ row }) => {\n            const fee = row.fee\n            const renderValue =\n              fee.value === 0 || fee.value === undefined\n                ? EmptyValueTag\n                : `${getValuePrecisionThousand(fee.value, undefined, undefined, undefined, false, {\n                    floor: false,\n                    isTrade: true,\n                  })} ${fee.unit}`\n            return <Box className='rdg-cell-value textAlignRight'>{renderValue}</Box>\n          },\n        },\n        {\n          key: 'from',\n          name: t('labelTxFrom'),\n          headerCellClass: 'textAlignRight',\n          cellClass: 'textAlignRight',\n          formatter: ({ row }) => {\n            const receiverAddress = /chain_withdrawal/i.test(row.side.toLowerCase())\n              ? // row.side.toLowerCase() === sdk.UserTxTypes.OFFCHAIN_WITHDRAWAL\n                row.withdrawalInfo\n                ? getShortAddr(row.withdrawalInfo.recipient, isMobile)\n                : ''\n              : getShortAddr(row.receiverAddress, isMobile)\n            const senderAddress = getShortAddr(row.senderAddress)\n            // myLog(\"receiverAddress\", row.receiverAddress);\n            // if (/chain_withdrawal/i.test(row.side.toLowerCase())) {\n            //   myLog(\"receiverAddress\", row.receiverAddress);\n            // }\n            const [from, to] =\n              row.side.toLowerCase() == sdk.UserTxTypes.DELEGATED_FORCE_WITHDRAW\n                ? [\n                    t('labelForceWithdrawDes', {\n                      address: getShortAddr(row.withdrawalInfo?.recipient),\n                      layer2: L1L2_NAME_DEFINED[network].layer2,\n                      l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                      loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                      l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                      l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                      ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                    }),\n                    '',\n                  ]\n                : [\n                    sdk.UserTxTypes.L2_STAKING,\n                    sdk.UserTxTypes.UNIFIED_CLAIM,\n                    sdk.UserTxTypes.DUAL_INVESTMENT,\n                    sdk.UserTxTypes.SEND_LUCKY_TOKEN,\n                    sdk.UserTxTypes.TRANSFER,\n                    sdk.UserTxTypes.WITHDRAW_LUCKY_TOKEN,\n                  ].includes(row.side.toLowerCase())\n                ? row.receiverAddress?.toUpperCase() === accAddress?.toUpperCase()\n                  ? [senderAddress, `${L1L2_NAME_DEFINED[network].l2Symbol}`]\n                  : [`${L1L2_NAME_DEFINED[network].l2Symbol}`, receiverAddress]\n                : row.side.toLowerCase() === sdk.UserTxTypes.DEPOSIT\n                ? [\n                    row.senderAddress.toLowerCase() !== accAddress\n                      ? `${L1L2_NAME_DEFINED[network].l1Symbol} ` + senderAddress\n                      : `${L1L2_NAME_DEFINED[network].l1Symbol}`,\n                    `${L1L2_NAME_DEFINED[network].l2Symbol}`,\n                  ]\n                : /chain_withdrawal/i.test(row.side.toLowerCase()) //sdk.UserTxTypes.OFFCHAIN_WITHDRAWAL\n                ? [\n                    `${L1L2_NAME_DEFINED[network].l2Symbol}`,\n                    row.withdrawalInfo?.recipient?.toUpperCase() === accAddress.toUpperCase()\n                      ? `${L1L2_NAME_DEFINED[network].l1Symbol}`\n                      : `${L1L2_NAME_DEFINED[network].l1Symbol} ` + receiverAddress,\n                  ]\n                : ['', '']\n            const hash = row.txHash !== '' ? row.txHash : row.hash\n            let path: string | undefined\n            if (\n              [\n                sdk.UserTxTypes.L2_STAKING,\n                sdk.UserTxTypes.UNIFIED_CLAIM,\n                sdk.UserTxTypes.DUAL_INVESTMENT,\n                sdk.UserTxTypes.SEND_LUCKY_TOKEN,\n                sdk.UserTxTypes.WITHDRAW_LUCKY_TOKEN,\n                'change_pwd',\n              ].includes(row.side.toLowerCase())\n            ) {\n              path =\n                row.txHash !== ''\n                  ? etherscanBaseUrl +\n                    `/tx/${row.txHash.slice(0, 6)}-${row.txHash.slice(row.txHash - 4)}`\n                  : [sdk.ChainId.TAIKO, sdk.ChainId.TAIKOHEKLA].includes(defaultNetwork)\n                  ? undefined\n                  : Explorer +\n                    `tx/${row.hash}-transfer-${row.storageInfo.accountId}-${row.storageInfo.tokenId}-${row.storageInfo.storageId}`\n            } else {\n              path =\n                row.txHash !== ''\n                  ? etherscanBaseUrl + `/tx/${row.txHash}`\n                  : [sdk.ChainId.TAIKO, sdk.ChainId.TAIKOHEKLA].includes(defaultNetwork)\n                  ? undefined\n                  : Explorer + `tx/${row.hash}-${EXPLORE_TYPE[row.txType.toUpperCase()]}`\n            }\n            return (\n              <Box\n                className='rdg-cell-value textAlignRight'\n                display={'inline-flex'}\n                justifyContent={'flex-end'}\n                alignItems={'center'}\n                title={hash}\n              >\n                <Link\n                  style={{\n                    cursor: path ? 'pointer' : 'text',\n                    color: path ? 'var(--color-primary)' : 'var(--color-text-primary)',\n                    textOverflow: 'ellipsis',\n                    overflow: 'hidden',\n                  }}\n                  maxWidth={148}\n                  target='_blank'\n                  rel='noopener noreferrer'\n                  href={path}\n                  title={from && to ? from + ` ${DirectionTag} ` + to : from + to}\n                >\n                  {row.side.toLowerCase() === 'change_pwd'\n                    ? `${hash.slice(0, 6)}...${hash.slice(hash.length - 4)}`\n                    : from && to\n                    ? from + ` ${DirectionTag} ` + to\n                    : from + to}\n                </Link>\n                <Box marginLeft={1}>\n                  <CellStatus {...{ row }} />\n                </Box>\n              </Box>\n            )\n          },\n        },\n        {\n          key: 'status',\n          name: t('labelTxMemo'),\n          headerCellClass: 'textAlignCenter',\n          formatter: ({ row }) => (\n            <MemoCellStyled title={row['memo']} className='rdg-cell-value textAlignLeft'>\n              {row['memo'] || EmptyValueTag}\n            </MemoCellStyled>\n          ),\n        },\n        {\n          key: 'time',\n          name: t('labelTxTime'),\n          headerCellClass: 'textAlignRight',\n          formatter: ({ row }) => {\n            const value = row['time']\n            const hasValue = Number.isFinite(value)\n            const renderValue = hasValue\n              ? moment(new Date(row['time']), 'YYYYMMDDHHMM').fromNow()\n              : EmptyValueTag\n            return <Box className='rdg-cell-value textAlignRight'>{renderValue}</Box>\n          },\n        },\n      ],\n      [t, accAddress, isMobile, etherscanBaseUrl],\n    )\n\n    const getColumnMobileTransaction = React.useCallback(\n      (): Column<any, unknown>[] => [\n        {\n          key: 'amount',\n          name: (\n            <Typography\n              height={'100%'}\n              display={'flex'}\n              justifyContent={'space-between'}\n              variant={'inherit'}\n              color={'inherit'}\n              alignItems={'center'}\n            >\n              <span>{t('labelTransactions')}</span>\n              <span>{t('labelTxAmount') + ' / ' + t('labelTxNetworkFee')}</span>\n            </Typography>\n          ),\n          cellClass: 'textAlignRight',\n          headerCellClass: 'textAlignLeft',\n          formatter: ({ row }) => {\n            const { unit, value } = row['amount']\n            const hasValue = Number.isFinite(value)\n            const side =\n              row.side.toLowerCase() === sdk.UserTxTypes.TRANSFER &&\n              row.receiverAddress?.toUpperCase() === accAddress?.toUpperCase()\n                ? t(`labelTypeReceive`)\n                : t(`labelType${row.side?.toUpperCase()}`)\n\n            const hasSymbol =\n              row.side.toLowerCase() === sdk.UserTxTypes.DELEGATED_FORCE_WITHDRAW\n                ? ''\n                : // t(\"labelForceWithdrawTotalDes\", {\n                //     address: getShortAddr(row.withdrawalInfo?.recipient),\n                //     symbol: row.symbol,\n                //   })\n                row.side.toLowerCase() === sdk.UserTxTypes.TRANSFER\n                ? row['receiverAddress']?.toUpperCase() === accAddress?.toUpperCase()\n                  ? '+'\n                  : '-'\n                : row.side.toLowerCase() === sdk.UserTxTypes.DEPOSIT\n                ? '+'\n                : row.side.toLowerCase() === sdk.UserTxTypes.DELEGATED_FORCE_WITHDRAW\n                ? '-'\n                : row.side.toLowerCase() === sdk.UserTxTypes.SEND_LUCKY_TOKEN\n                ? '-'\n                : row.side.toLowerCase() === sdk.UserTxTypes.SEND_BACK_LUCKY_TOKEN\n                ? '+'\n                : row.side.toLowerCase() === sdk.UserTxTypes.WITHDRAW_LUCKY_TOKEN\n                ? '+'\n                : row.side.toLowerCase() === sdk.UserTxTypes.UNIFIED_CLAIM\n                ? '+'\n                : ''\n            const sideIcon =\n              row.side.toLowerCase() === sdk.UserTxTypes.DELEGATED_FORCE_WITHDRAW ? (\n                <WithdrawIcon fontSize={'inherit'} />\n              ) : row.side.toLowerCase() === sdk.UserTxTypes.DEPOSIT ? (\n                <DepositIcon fontSize={'inherit'} />\n              ) : row.side.toLowerCase() === sdk.UserTxTypes.TRANSFER ? (\n                <TransferIcon fontSize={'inherit'} />\n              ) : row.side.toLowerCase() === sdk.UserTxTypes.SEND_LUCKY_TOKEN ? (\n                <RedPacketIcon fontSize={'inherit'} />\n              ) : row.side.toLowerCase() === sdk.UserTxTypes.WITHDRAW_LUCKY_TOKEN ? (\n                <RedPacketIcon fontSize={'inherit'} />\n              ) : row.side.toLowerCase() === sdk.UserTxTypes.UNIFIED_CLAIM ? (\n                <RewardIcon fontSize={'inherit'} />\n              ) : (\n                <WithdrawIcon fontSize={'inherit'} />\n              )\n            const renderValue = hasValue\n              ? `${getValuePrecisionThousand(value, undefined, undefined, undefined, false, {\n                  isTrade: true,\n                })}`\n              : EmptyValueTag\n\n            const renderFee = `Fee: ${getValuePrecisionThousand(\n              row.fee.value,\n              undefined,\n              undefined,\n              undefined,\n              false,\n              {\n                floor: false,\n                isTrade: true,\n              },\n            )} ${row.fee.unit}`\n            return (\n              <Box\n                flex={1}\n                display={'flex'}\n                alignItems={'center'}\n                justifyContent={'flex-start'}\n                height={'100%'}\n                title={`${hasSymbol}  ${renderValue} ${unit}`}\n              >\n                <Typography\n                  display={'flex'}\n                  marginRight={1}\n                  variant={'h3'}\n                  alignItems={'center'}\n                  flexDirection={'column'}\n                  width={'62px'}\n                >\n                  {sideIcon}\n                  <Typography\n                    component={'span'}\n                    fontSize={10}\n                    marginTop={-1}\n                    textOverflow={'ellipsis'}\n                  >\n                    {side}\n                  </Typography>\n                </Typography>\n                <Box display={'flex'} flex={1} flexDirection={'column'}>\n                  <Typography\n                    display={'inline-flex'}\n                    justifyContent={'flex-end'}\n                    alignItems={'center'}\n                  >\n                    {hasSymbol + renderValue + ' ' + unit}\n                  </Typography>\n                  <Typography color={'textSecondary'} variant={'body2'}>\n                    {renderFee}\n                  </Typography>\n                </Box>\n              </Box>\n            )\n          },\n        },\n        {\n          key: 'from',\n          name: t('labelTxFrom') + ' / ' + t('labelTxTime'),\n          headerCellClass: 'textAlignRight',\n          cellClass: 'textAlignRight',\n          formatter: ({ row }) => {\n            // row.side.toLowerCase() === sdk.UserTxTypes.OFFCHAIN_WITHDRAWAL\n            const receiverAddress = /chain_withdrawal/i.test(row.side.toLowerCase())\n              ? getShortAddr(row.withdrawalInfo.recipient, isMobile)\n              : getShortAddr(row.receiverAddress, isMobile)\n\n            const senderAddress = getShortAddr(row.senderAddress, isMobile)\n            const [from, to] =\n              row.side.toLowerCase() === sdk.UserTxTypes.DELEGATED_FORCE_WITHDRAW\n                ? [\n                    t('labelForceWithdrawDes', {\n                      address: getShortAddr(row.withdrawalInfo?.recipient),\n                      l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                      loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                      l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                      l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                      ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                    }),\n                    '',\n                  ]\n                : row.side.toLowerCase() === sdk.UserTxTypes.TRANSFER\n                ? row['receiverAddress']?.toUpperCase() === accAddress?.toUpperCase()\n                  ? [senderAddress, L1L2_NAME_DEFINED[network].l2Symbol]\n                  : [L1L2_NAME_DEFINED[network].l2Symbol, receiverAddress]\n                : row.side.toLowerCase() === sdk.UserTxTypes.DEPOSIT\n                ? [\n                    row.senderAddress.toLowerCase() !== accAddress\n                      ? `${L1L2_NAME_DEFINED[network].l1Symbol} ` + senderAddress\n                      : `${L1L2_NAME_DEFINED[network].l1Symbol}`,\n                    L1L2_NAME_DEFINED[network].l2Symbol,\n                  ]\n                : /chain_withdrawal/i.test(row.side.toLowerCase()) //sdk.UserTxTypes.OFFCHAIN_WITHDRAWAL\n                ? [\n                    L1L2_NAME_DEFINED[network].l2Symbol,\n                    row.withdrawalInfo?.recipient?.toUpperCase() === accAddress.toUpperCase()\n                      ? `${L1L2_NAME_DEFINED[network].l1Symbol}`\n                      : `${L1L2_NAME_DEFINED[network].l1Symbol} ` + receiverAddress,\n                  ]\n                : ['', '']\n            const hash = row.txHash !== '' ? row.txHash : row.hash\n            const path =\n              row.txHash !== ''\n                ? etherscanBaseUrl + `/tx/${row.txHash}`\n                : Explorer + `tx/${row.hash}-${EXPLORE_TYPE[row.txType.toUpperCase()]}`\n\n            const hasValue = Number.isFinite(row.time)\n            const renderTime = hasValue\n              ? moment(new Date(row.time), 'YYYYMMDDHHMM').fromNow()\n              : EmptyValueTag\n\n            return (\n              <Box\n                display={'flex'}\n                flex={1}\n                title={hash}\n                flexDirection={'column'}\n                onClick={() => {\n                  window.open(path, '_blank')\n                  window.opener = null\n                }}\n              >\n                <Typography\n                  display={'inline-flex'}\n                  justifyContent={'flex-end'}\n                  alignItems={'center'}\n                >\n                  <Link\n                    style={{\n                      cursor: 'pointer',\n                      color: 'var(--color-primary)',\n                      textOverflow: 'ellipsis',\n                      overflow: 'hidden',\n                    }}\n                    maxWidth={148}\n                    target='_blank'\n                    rel='noopener noreferrer'\n                    href={path}\n                    title={from && to ? from + ` ${DirectionTag} ` + to : from + to}\n                  >\n                    {from && to ? from + ` ${DirectionTag} ` + to : from + to}\n                  </Link>\n                  <Typography marginLeft={1}>\n                    <CellStatus {...{ row }} />\n                  </Typography>\n                </Typography>\n                <Typography color={'textSecondary'} variant={'body2'}>\n                  {renderTime}\n                </Typography>\n              </Box>\n            )\n          },\n        },\n      ],\n      [t, accAddress, isMobile, etherscanBaseUrl],\n    )\n    const [isDropDown, setIsDropDown] = React.useState(true)\n\n    const defaultArgs: any = {\n      columnMode: isMobile ? getColumnMobileTransaction() : getColumnModeTransaction(),\n      generateRows: (rawData: any) => rawData,\n      generateColumns: ({ columnsRaw }: any) => columnsRaw as Column<any, unknown>[],\n    }\n    React.useEffect(() => {\n      let filters: any = {}\n      updateData.cancel()\n      if (searchParams.get('types')) {\n        filters.type = searchParams.get('types')\n      }\n      handleFilterChange(filters)\n      return () => {\n        updateData.cancel()\n      }\n    }, [pagination?.pageSize])\n\n    return (\n      <TableStyled isMobile={isMobile}>\n        {showFilter &&\n          (isMobile && isDropDown ? (\n            <Link\n              variant={'body1'}\n              display={'inline-flex'}\n              width={'100%'}\n              justifyContent={'flex-end'}\n              paddingRight={2}\n              onClick={() => setIsDropDown(false)}\n            >\n              {t('labelShowFilter')}\n            </Link>\n          ) : (\n            <TableFilterStyled>\n              <Filter\n                filterTokens={filterTokens}\n                // originalData={rawData}\n                filterDate={filterDate}\n                filterType={filterType}\n                filterToken={filterToken}\n                handleFilterChange={handleFilterChange}\n                handleReset={handleReset}\n              />\n            </TableFilterStyled>\n          ))}\n        <Table\n          {...{\n            ...defaultArgs,\n            // rowRenderer: RowRenderer,\n            ...props,\n            rawData,\n            showloading,\n          }}\n        />\n        {accountId && showFilter && !isTaiko && (\n          <Typography\n            display={'flex'}\n            justifyContent={'flex-end'}\n            textAlign={'right'}\n            paddingRight={5 / 2}\n            paddingY={1}\n          >\n            <Trans i18nKey={'labelGoExplore'} ns={'common'}>\n              View transactions on\n              <Link\n                display={'inline-flex'}\n                target='_blank'\n                rel='noopener noreferrer'\n                href={Explorer + `/account/${accountId}`}\n                paddingLeft={1 / 2}\n              >\n                block explorer\n              </Link>\n            </Trans>\n          </Typography>\n        )}\n        {pagination && (\n          <TablePagination\n            page={page}\n            pageSize={pagination.pageSize}\n            total={pagination.total}\n            onPageChange={handlePageChange}\n          />\n        )}\n      </TableStyled>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/transactionsTable/components/Filter.tsx",
    "content": "import React from 'react'\nimport styled from '@emotion/styled'\nimport { Box, Grid, MenuItem } from '@mui/material'\nimport { withTranslation, WithTranslation } from 'react-i18next'\nimport { DateRangePicker, TextField } from '../../../basic-lib/form'\nimport { Button } from '../../../basic-lib/btns'\nimport { DropDownIcon } from '@loopring-web/common-resources'\nimport { DateRange } from '@mui/lab'\nimport { useSettings } from '../../../../stores'\nimport { TransactionTradeViews } from '../Interface'\n\nexport interface FilterProps {\n  filterTokens: string[]\n  filterDate: DateRange<Date | string>\n  filterType: TransactionTradeViews\n  filterToken: string\n  handleFilterChange: ({ type, date }: any) => void\n  handleReset: () => void\n}\n\nconst StyledTextFiled = styled(TextField)`\n  &.MuiTextField-root {\n    max-width: initial;\n  }\n  .MuiInputBase-root {\n    width: initial;\n    max-width: initial;\n  }\n`\n\nconst StyledBtnBox = styled(Box)`\n  display: flex;\n  margin-left: 40%;\n\n  button:first-of-type {\n    margin-right: 8px;\n  }\n`\n\nexport const Filter = withTranslation('tables', { withRef: true })(\n  ({\n    t,\n    filterTokens = [],\n    filterDate,\n    filterType,\n    filterToken,\n    handleFilterChange,\n    handleReset,\n  }: FilterProps & WithTranslation) => {\n    const { isMobile } = useSettings()\n    const transactionTypeList = [\n      {\n        label: t('labelTxFilterALL'),\n        value: TransactionTradeViews.allTypes,\n      },\n      {\n        label: t('labelTxFilterRECEIVE'),\n        value: TransactionTradeViews.receive,\n      },\n      {\n        label: t('labelTxFilterSEND'),\n        value: TransactionTradeViews.send,\n      },\n      {\n        label: t('labelTxFilterFORCEWITHDRAW'),\n        value: TransactionTradeViews.forceWithdraw,\n      },\n      // {\n      //   label: t(\"labelTxFilterDEPOSIT\"),\n      //   value: TransactionTradeTypes.deposit,\n      // },\n      //\n      // {\n      //   label: t(\"labelTxFilterTRANSFER\"),\n      //   value: TransactionTradeTypes.transfer,\n      // },\n      // {\n      //   label: t(\"labelTxFilterWITHDRAW\"),\n      //   value: TransactionTradeTypes.withdraw,\n      // },\n      // {\n      //   label: t(\"labelTxFilterFORCEWITHDRAW\"),\n      //   value: TransactionTradeTypes.forceWithdraw,\n      // },\n    ]\n\n    const tokenTypeList: { label: string; value: string }[] = [\n      {\n        label: t('labelTxFilterAllTokens'),\n        value: 'all',\n      },\n      ...Array.from(filterTokens)\n        .sort((a: string, b: string) => {\n          return a.localeCompare(b)\n        })\n        .map((token: string) => ({\n          label: token,\n          value: token,\n        })),\n    ]\n\n    return (\n      <Grid container spacing={isMobile ? 1 : 2} alignItems={'center'}>\n        <Grid item xs={12} order={isMobile ? 0 : 1} lg={6}>\n          <DateRangePicker\n            value={filterDate}\n            onChange={(date: any) => {\n              handleFilterChange({ date: date })\n            }}\n          />\n        </Grid>\n        <Grid item xs={4} order={isMobile ? 1 : 0} lg={2} sx={{ display: 'none' }}>\n          <StyledTextFiled\n            id='table-transaction-trade-types'\n            select\n            fullWidth\n            value={filterType}\n            onChange={(event: React.ChangeEvent<{ value: unknown }>) => {\n              handleFilterChange({ type: event.target.value })\n            }}\n            inputProps={{ IconComponent: DropDownIcon }}\n          >\n            {transactionTypeList.map((o) => (\n              <MenuItem key={o.value} value={o.value}>\n                {o.label}\n              </MenuItem>\n            ))}\n          </StyledTextFiled>\n        </Grid>\n        <Grid item xs={4} order={2} lg={2}>\n          <StyledTextFiled\n            id='table-transaction-token-types'\n            select\n            fullWidth\n            value={filterToken}\n            onChange={(event: React.ChangeEvent<{ value: string }>) => {\n              handleFilterChange({ token: event.target.value })\n            }}\n            inputProps={{ IconComponent: DropDownIcon }}\n          >\n            {tokenTypeList.map((o) => (\n              <MenuItem key={o.value} value={o.value}>\n                {o.label}\n              </MenuItem>\n            ))}\n          </StyledTextFiled>\n        </Grid>\n        <Grid item xs={4} order={3} lg={2}>\n          <StyledBtnBox>\n            <Button\n              fullWidth\n              variant={'outlined'}\n              size={'medium'}\n              color={'primary'}\n              onClick={handleReset}\n            >\n              {t('labelFilterReset')}\n            </Button>\n          </StyledBtnBox>\n        </Grid>\n      </Grid>\n    )\n  },\n)\n\nexport const Filter2 = Filter\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/transactionsTable/components/modal.tsx",
    "content": "import { WithTranslation, withTranslation } from 'react-i18next'\nimport styled from '@emotion/styled'\nimport { Box, Grid, Typography } from '@mui/material'\nimport moment from 'moment'\nimport { EmptyValueTag, YEAR_DAY_SECOND_FORMAT } from '@loopring-web/common-resources'\nimport { TxType } from '@loopring-web/loopring-sdk'\nimport React from 'react'\n\n// import { getValuePrecisionThousand } from '@loopring-web/common-resources';\n\nexport enum TxnDetailStatus {\n  processed = 'PROCESSED',\n  processing = 'PROCESSING',\n  received = 'RECEIVED',\n  failed = 'FAILED',\n}\n\nexport type TxnDetailProps = {\n  txType?: TxType\n  hash: string\n  txHash: string\n  status: keyof typeof TxnDetailStatus\n  time: string\n  from: string\n  to: string\n  amount: string\n  fee: string\n  memo?: string\n  etherscanBaseUrl?: string\n}\n\nconst ContentWrapperStyled = styled(Box)`\n  top: 45%;\n  left: 50%;\n  transform: translate(-50%, -50%);\n  width: 70%;\n  min-width: ${({ theme }) => theme.unit * 87.5}px;\n  height: 75%;\n  background-color: var(--color-box);\n  box-shadow: 0px ${({ theme }) => theme.unit / 2}px ${({ theme }) => theme.unit / 2}px\n    rgba(0, 0, 0, 0.25);\n  border-radius: ${({ theme }) => theme.unit}px;\n  position: absolute;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n`\n\nconst HeaderStyled = styled(Box)`\n  position: absolute;\n  top: 0;\n  z-index: 22;\n  width: 100%;\n  height: ${({ theme }) => theme.unit * 7.5}px;\n  box-shadow: 0px ${({ theme }) => theme.unit / 4}px ${({ theme }) => theme.unit}px\n    rgba(0, 0, 0, 0.25);\n  border-radius: ${({ theme }) => theme.unit}px ${({ theme }) => theme.unit}px 0px 0px;\n  display: flex;\n  align-items: center;\n`\n\nconst GridContainerStyled = styled(Grid)`\n  margin-top: ${({ theme }) => theme.unit * 7.5}px;\n  flex-direction: column;\n  width: auto;\n`\n\nconst GridItemStyled = styled(Grid)`\n  display: flex;\n  align-items: baseline;\n  margin-bottom: ${({ theme }) => theme.unit * 3}px;\n`\n\nconst EthHshStyled = styled(Typography)`\n  cursor: pointer;\n  text-decoration: underline;\n`\n\nconst TypographyStyled = styled(Typography)`\n  color: var(--color-text-secondary);\n  width: ${({ theme }) => theme.unit * 20}px;\n`\n\nconst InfoValueStyled = styled(Box)`\n  // max-width: ${({ theme }) => theme.unit * 32}px;\n  word-break: break-all;\n  font-size: 1.4rem;\n  color: ${(props: any) => (props.hash ? 'var(--color-secondary)' : 'var(--color-text-primary)')};\n` as any\n\nconst StatusStyled = styled(Typography)<any>`\n  color: ${({ theme, status }) =>\n    status === 'processed'\n      ? theme.colorBase.success\n      : status === 'processing'\n      ? theme.colorBase.warning\n      : status === 'failed'\n      ? theme.colorBase.error\n      : theme.colorBase.secondaryHover};\n`\n\nexport const TxnDetailPanel = withTranslation('common', { withRef: true })(\n  React.forwardRef(\n    (\n      {\n        t,\n        txType,\n        hash,\n        txHash,\n        status,\n        time,\n        from,\n        to,\n        amount,\n        fee,\n        memo,\n        etherscanBaseUrl,\n      }: TxnDetailProps & WithTranslation,\n      ref: React.ForwardedRef<any>,\n    ) => {\n      const headerLabel =\n        txType === TxType.DEPOSIT\n          ? 'labelDTxnDetailHeader'\n          : txType === TxType.OFFCHAIN_WITHDRAWAL\n          ? 'labelWTxnDetailHeader'\n          : 'labelTTxnDetailHeader'\n\n      const renderStatus =\n        status.toUpperCase() === 'PROCESSED'\n          ? t('labelTxnDetailProcessed')\n          : status.toUpperCase() === 'PROCESSING' || status.toUpperCase() === 'RECEIVED'\n          ? t('labelTxnDetailProcessing')\n          : t('labelTxnDetailFailed')\n\n      return (\n        <ContentWrapperStyled ref={ref} tabIndex={-1}>\n          <HeaderStyled>\n            <Typography variant={'h4'} marginLeft={4}>\n              {t(headerLabel)}\n            </Typography>\n          </HeaderStyled>\n          <GridContainerStyled container flexDirection={'column'}>\n            <GridItemStyled item>\n              <TypographyStyled>{t('labelTxnDetailHash')}</TypographyStyled>\n              <InfoValueStyled>{hash}</InfoValueStyled>\n            </GridItemStyled>\n            {txHash && (\n              <GridItemStyled item>\n                <TypographyStyled>{t('labelTxnDetailHashLv1')}</TypographyStyled>\n                <InfoValueStyled>\n                  <EthHshStyled\n                    color={'var(--color-secondary)'}\n                    onClick={() => {\n                      window.open(`${etherscanBaseUrl}tx/${txHash}`)\n                      window.opener = null\n                    }}\n                  >\n                    {txHash}\n                  </EthHshStyled>\n                </InfoValueStyled>\n              </GridItemStyled>\n            )}\n            <GridItemStyled item>\n              <TypographyStyled>{t('labelTxnDetailStatus')}</TypographyStyled>\n              <StatusStyled status={status}>{renderStatus}</StatusStyled>\n            </GridItemStyled>\n            <GridItemStyled item>\n              <TypographyStyled>{t('labelTxnDetailTime')}</TypographyStyled>\n              <InfoValueStyled>{moment(time).format(YEAR_DAY_SECOND_FORMAT)}</InfoValueStyled>\n            </GridItemStyled>\n            <GridItemStyled item>\n              <TypographyStyled>{t('labelTxnDetailFrom')}</TypographyStyled>\n              <InfoValueStyled hash={from}>{from || EmptyValueTag}</InfoValueStyled>\n            </GridItemStyled>\n            <GridItemStyled item>\n              <TypographyStyled>{t('labelTxnDetailTo')}</TypographyStyled>\n              <InfoValueStyled hash={to}>{to || EmptyValueTag}</InfoValueStyled>\n            </GridItemStyled>\n            <GridItemStyled item>\n              <TypographyStyled>{t('labelTxnDetailAmount')}</TypographyStyled>\n              <InfoValueStyled>{amount}</InfoValueStyled>\n            </GridItemStyled>\n            <GridItemStyled item>\n              <TypographyStyled>{t('labelTxnDetailFee')}</TypographyStyled>\n              <InfoValueStyled>{fee}</InfoValueStyled>\n            </GridItemStyled>\n            <GridItemStyled item>\n              <TypographyStyled>{t('labelTxnDetailMemo')}</TypographyStyled>\n              <InfoValueStyled>{memo || EmptyValueTag}</InfoValueStyled>\n            </GridItemStyled>\n          </GridContainerStyled>\n        </ContentWrapperStyled>\n      )\n    },\n  ),\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/transactionsTable/index.ts",
    "content": "export * from './TransactionTable'\nexport * from './Interface'\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/vaultTable/Interface.ts",
    "content": "import * as sdk from '@loopring-web/loopring-sdk'\n\nexport enum VaultRecordType {\n  borrow = 'borrow',\n  open = 'open',\n  closeout = 'closeout',\n  margin = 'margin',\n  repay = 'repay',\n  trade = 'trade',\n  convert = 'convert',\n  redeem = 'redeem',\n  closeShort = 'closeShort',\n}\n\nexport type RawDataVaultTxItem = {\n  type: VaultRecordType\n  status: sdk.VaultOperationStatus\n  vSymbol: string\n  vTokenB: string\n  erc20SymbolB: string\n  erc20Symbol: string\n  mainContentRender: string | JSX.Element\n  fillAmount: string\n  percentage: string\n  feeStr: string\n  feeTokenSymbol: string\n  feeErc20Symbol: string\n  raw_data: { operation: sdk.VaultOperation; order: sdk.VaultOrder }\n  // fromAmount: string\n  // fromSymbol: string\n  // toAmount: string\n  // toSymbol: string\n  // fromFAmount: string\n  // toFAmount: string\n  // price: {\n  //   key: string\n  //   value: string\n  //   from: string\n  // }\n  // feeAmount: string\n  // feeSymbol: string\n  // time: number\n  // filledPercent: string\n  // settledFromAmount: string\n  // settledToAmount: string\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/vaultTable/VaultTxTable.tsx",
    "content": "import { WithTranslation, useTranslation, withTranslation } from 'react-i18next'\nimport { useSettings } from '../../../stores'\nimport React from 'react'\nimport { Column, EmptyDefault, SpaceBetweenBox, Table, TablePagination } from '../../basic-lib'\nimport { Box, BoxProps, Button, Tooltip, Typography } from '@mui/material'\nimport { TablePaddingX } from '../../styled'\nimport styled from '@emotion/styled'\nimport { FormatterProps } from 'react-data-grid'\nimport { RawDataVaultTxItem, VaultRecordType } from './Interface'\nimport {\n  DoneIcon,\n  EmptyValueTag,\n  FailedIcon,\n  globalSetup,\n  Info2Icon,\n  LoadingIcon,\n  RowInvestConfig,\n  TokenType,\n  YEAR_DAY_MINUTE_FORMAT,\n  hexToRGB,\n  ErrorIcon,\n  mapSpecialTokenName\n} from '@loopring-web/common-resources'\nimport { useHistory } from 'react-router-dom'\nimport moment from 'moment'\nimport _ from 'lodash'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { RedeemDes2 } from '../../modal'\nimport { CoinIcons } from '../assetsTable'\nimport {\n  CoinIcon,\n} from '@loopring-web/component-lib'\nimport { useTheme } from '@mui/material'\nimport Decimal from 'decimal.js'\n\nconst TableWrapperStyled = styled(Box)<BoxProps & { isMobile?: boolean }>`\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n  height: 100%;\n\n  ${({ theme }) => TablePaddingX({ pLeft: theme.unit * 3, pRight: theme.unit * 3 })};\n\n  & .rdg {\n    ${({ isMobile }) =>\n      !isMobile\n        ? `--template-columns: 16% 38% auto auto auto !important;`\n        : `--template-columns: 16% 40% auto !important;`}\n  }\n`\nconst TableStyled = styled(Table)`\n  &.rdg {\n    height: ${(props: any) => {\n      if (props.ispro === 'pro') {\n        return '620px'\n      }\n      if (props.currentheight && props.currentheight > 350) {\n        return props.currentheight + 'px'\n      } else {\n        return '100%'\n      }\n    }};\n\n    .rdg-cell.action {\n      display: flex;\n      justify-content: center;\n      align-items: center;\n    }\n  }\n\n  .textAlignRight {\n    text-align: right;\n\n    .rdg-header-sort-cell {\n      justify-content: flex-end;\n    }\n  }\n\n  .textAlignCenter {\n    text-align: center;\n  }\n` as any\n\nexport interface VaultTxsTableProps<R> {\n  rawData: R[]\n  showloading: boolean\n  onItemClick: (item: R) => void\n  pagination: {\n    pageSize: number\n    total: number\n  }\n  getOrderList: (props: Omit<sdk.GetOrdersRequest, 'accountId'>) => Promise<any>\n}\n\nexport const VaultTxTable = withTranslation(['tables', 'common'])(\n  <R extends RawDataVaultTxItem>(props: VaultTxsTableProps<R> & WithTranslation) => {\n    const { rawData, showloading, pagination, getOrderList, t } = props\n    const [page, setPage] = React.useState(0)\n    const { isMobile, upColor } = useSettings()\n    const history = useHistory()\n    const getColumnModeTransaction = React.useCallback(\n      (): Column<R, unknown>[] => [\n        {\n          key: 'Type',\n          cellClass: 'textAlignLeft',\n          headerCellClass: 'textAlignLeft',\n          name: t('labelVaultTxType'),\n          formatter: ({ row }: FormatterProps<R>) => {\n            const isForcedCloseOut =\n              ((row.raw_data.operation.operateSubType as string) === 'VAULT_FORCE_SETTLEMENT' ||\n                (row.raw_data.operation.operateSubType as string) === 'VAULT_FORCE_WITHDRAW') &&\n              row.type === VaultRecordType.closeout\n\n             \n            if (row.erc20Symbol === 'USDT' && row.type === 'trade') {\n              var longOrShort: 'long' | 'short' | undefined = 'long'\n            } else if (row.erc20Symbol !== 'USDT' && row.type === 'trade') {\n              longOrShort = 'short'\n            } else {\n              longOrShort = undefined\n            }\n            \n            const upColorStr = upColor === 'green' ? 'var(--color-success)' : 'var(--color-error)'\n            const downColorStr = upColor === 'green' ? 'var(--color-error)' : 'var(--color-success)'\n            return (\n              <Box\n                display={'flex'}\n                justifyContent={'space-between'}\n                paddingRight={3}\n                alignItems={'center'}\n                height={'100%'}\n              >\n                <Typography\n                  color={\n                    longOrShort === 'long' \n                      ? upColorStr\n                      : longOrShort === 'short'\n                      ? downColorStr\n                      : 'var(--color-text-primary)'\n                  }\n                  component={'span'}\n                  display={'flex'}\n                  alignItems={'center'}\n                >\n                  {longOrShort === 'long'\n                    ? t('labelVaultBuyLong')\n                    : longOrShort === 'short'\n                    ? t('labelVaultSellShort')\n                    : isForcedCloseOut\n                    ? t(`labelVaultcloseoutForced`)\n                    : t(`labelVault${row.type}`)}\n                </Typography>\n              </Box>\n            )\n          },\n        },\n        {\n          key: 'Filled',\n          name: t('labelVaultTxFilled'),\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            return <>{row.mainContentRender}</>\n          },\n        },\n        {\n          key: 'status',\n          name: t('labelVaultTxStatus'),\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            const color = [\n              sdk.VaultOperationStatus.VAULT_STATUS_SUCCEED,\n              'VAULT_STATUS_EARNING',\n            ].includes(row.status)\n              ? 'var(--color-success)'\n              : [\n                  sdk.VaultOperationStatus.VAULT_STATUS_PENDING,\n                  sdk.VaultOperationStatus.VAULT_STATUS_PROCESSING,\n                ].includes(row.status)\n              ? 'var(--color-primary)'\n              : row.status === sdk.VaultOperationStatus.VAULT_STATUS_FAILED\n              ? 'var(--color-error)'\n              : 'var(--color-text-primary)'\n            return (\n              <Typography\n                variant={'body1'}\n                display={'inline-flex'}\n                justifyContent={'center'}\n                alignItems={'center'}\n                color={color}\n              >\n                {t(`labelVault${row.status}`) +\n                  `${\n                    row.type === VaultRecordType.trade &&\n                    row.status !== sdk.VaultOperationStatus.VAULT_STATUS_FAILED\n                      ? '(' + row.percentage + '%)'\n                      : ''\n                  }`}\n              </Typography>\n            )\n          },\n        },\n        {\n          key: 'Time',\n          cellClass: 'textAlignRight',\n          headerCellClass: 'textAlignRight',\n          name: t('labelVaultTxTime'),\n          formatter: ({ row }: FormatterProps<R>) => {\n            return <>{moment(row?.raw_data?.operation?.createdAt).fromNow()}</>\n          },\n        },\n        {\n          key: 'Action',\n          cellClass: 'textAlignRight',\n          headerCellClass: 'textAlignRight',\n          name: 'Action',\n          formatter: ({ row }: FormatterProps<R>) => {\n            return (\n              <Button variant={'text'} onClick={() => props.onItemClick(row)}>\n                {t('labelDetails')}\n              </Button>\n            )\n          },\n        },\n      ],\n      [t, props],\n    )\n    const getColumnMobileTransaction = React.useCallback(\n      (): Column<R, unknown>[] => [\n        {\n          key: 'Type',\n          cellClass: 'textAlignLeft',\n          headerCellClass: 'textAlignLeft',\n          name: t('labelVaultTxType'),\n          formatter: ({ row }: FormatterProps<R>) => {\n            \n            \n            return (\n              <Box\n                display={'flex'}\n                justifyContent={'space-between'}\n                paddingRight={3}\n                alignItems={'center'}\n                height={'100%'}\n              >\n                <Typography component={'span'} display={'flex'}>\n                  {t(`labelVault${row.type}`)}\n                </Typography>\n              </Box>\n            )\n          },\n        },\n        {\n          key: 'Filled',\n          name: t('labelVaultTxFilled'),\n          formatter: ({ row }: FormatterProps<R, unknown>) => {\n            return (\n              <>\n                {row.mainContentRender}\n              </>\n            )\n          },\n        },\n        {\n          key: 'statusTime',\n          cellClass: 'textAlignRight',\n          headerCellClass: 'textAlignRight',\n\n          name: t('labelVaultTxStatus') + '/' + t('labelVaultTxTime'),\n          formatter: ({ row }: FormatterProps<R>) => {\n            const color =\n              row.status === sdk.VaultOperationStatus.VAULT_STATUS_SUCCEED\n                ? 'var(--color-success)'\n                : row.status === sdk.VaultOperationStatus.VAULT_STATUS_PENDING\n                ? 'var(--color-primary)'\n                : row.status === sdk.VaultOperationStatus.VAULT_STATUS_FAILED\n                ? 'var(--color-error)'\n                : 'var(--color-text-primary)'\n            return (\n              <Box\n                display={'flex'}\n                justifyContent={'space-between'}\n                paddingRight={3}\n                alignItems={'center'}\n                height={'100%'}\n              >\n                <Typography\n                  component={'span'}\n                  color={color}\n                  variant={'body1'}\n                  display={'inline-flex'}\n                  justifyContent={'center'}\n                  alignItems={'center'}\n                >\n                  {t(`labelVault${row.status}`) +\n                    `${\n                      row.type === VaultRecordType.trade &&\n                      row.status !== sdk.VaultOperationStatus.VAULT_STATUS_FAILED\n                        ? '(' + row.percentage + '%)'\n                        : ''\n                    }`}\n                </Typography>\n                <Typography>{moment(row?.raw_data?.order?.createdAt).fromNow()}</Typography>\n              </Box>\n            )\n          },\n        },\n      ],\n      [history, upColor, t],\n    )\n    const updateData = _.debounce(\n      ({\n\n        currPage = page,\n        pageSize = pagination.pageSize,\n      }: {\n\n        currPage?: number\n        pageSize?: number\n      }) => {\n        getOrderList({\n          limit: pageSize,\n          offset: (currPage - 1) * pageSize,\n        })\n      },\n      globalSetup.wait,\n    )\n    const handlePageChange = React.useCallback(\n      async (currPage: number) => {\n\n        setPage(currPage)\n        updateData({ currPage: currPage })\n      },\n      [updateData],\n    )\n\n    const defaultArgs: any = {\n      columnMode: isMobile ? getColumnMobileTransaction() : getColumnModeTransaction(),\n      generateRows: (rawData: any) => rawData,\n      generateColumns: ({ columnsRaw }: any) => columnsRaw as Column<any, unknown>[],\n    }\n\n    React.useEffect(() => {\n\n      updateData.cancel()\n      handlePageChange(1)\n      return () => {\n        updateData.cancel()\n      }\n    }, [pagination?.pageSize])\n\n    return (\n      <TableWrapperStyled isMobile={isMobile}>\n        <TableStyled\n          currentheight={\n            RowInvestConfig.rowHeaderHeight + rawData.length * RowInvestConfig.rowHeight\n          }\n          rowHeight={RowInvestConfig.rowHeight}\n          headerRowHeight={RowInvestConfig.rowHeaderHeight}\n          onRowClick={(_, row) => {\n            props.onItemClick(row)\n          }}\n          {...{\n            ...defaultArgs,\n            ...props,\n\n            rawData,\n            showloading,\n          }}\n        />\n        {pagination && !!rawData.length && (\n          <TablePagination\n            page={page}\n            pageSize={pagination.pageSize}\n            total={pagination.total}\n            onPageChange={handlePageChange}\n          />\n        )}\n      </TableWrapperStyled>\n    )\n  },\n)\nexport const VaultCloseDetail = withTranslation(['common'])(\n  <R extends RawDataVaultTxItem>({\n    t,\n    vaultCloseDetail,\n  }: {\n    vaultCloseDetail: R & any\n  } & WithTranslation) => {\n    return (\n      <Box flex={1} display={'flex'} flexDirection={'column'}>\n        <Box\n          display={'flex'}\n          flexDirection={'column'}\n          justifyContent={'center'}\n          width={'100%'}\n          alignItems={'center'}\n        >\n          {vaultCloseDetail.statusType === 'failed' ? (\n            <FailedIcon style={{ color: 'var(--color-error)', width: 64, height: 64 }} />\n          ) : vaultCloseDetail.statusType === 'processing' ? (\n            <LoadingIcon color={'primary'} style={{ width: 64, height: 64 }} />\n          ) : (\n            <DoneIcon\n              style={{\n                color: 'var(--color-success)',\n                width: 64,\n                height: 64,\n              }}\n            />\n          )}\n          <Typography\n            marginTop={2}\n            variant={'body1'}\n            component={'span'}\n            color={'var(--color-text-primary)'}\n          >\n            {vaultCloseDetail.statusLabel}\n          </Typography>\n        </Box>\n        <Box\n          display={'flex'}\n          flexDirection={'column'}\n          alignItems={'stretch'}\n          justifyContent={'space-between'}\n          padding={2}\n          margin={2}\n          borderRadius={1 / 2}\n          sx={{\n            background: 'var(--field-opacity)',\n          }}\n        >\n          <RedeemDes2 t={t} isNoWrap={true} info={{ ...vaultCloseDetail }} />\n          <Typography\n            display={'inline-flex'}\n            justifyContent={'space-between'}\n            marginTop={2}\n            component={'span'}\n            order={9}\n          >\n            <Typography display={'flex'} flexDirection={'row'} alignItems={'center'} variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n              {t('labelVaultExitCloseAmount')}\n            </Typography>\n            <Box display={'flex'} flexDirection={'row'} alignItems={'center'}>\n              <CoinIcon\n                tokenImageKey={vaultCloseDetail.tokenSymbol}\n                symbol={vaultCloseDetail.tokenSymbol}\n                type={TokenType.single}\n              />\n              <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n                {vaultCloseDetail?.amount}\n              </Typography>\n            </Box>\n          </Typography>\n        </Box>\n        {\n          <Box\n            display={'flex'}\n            flexDirection={'column'}\n            alignItems={'stretch'}\n            justifyContent={'space-between'}\n            padding={2}\n            margin={2}\n            borderRadius={1 / 2}\n            sx={{\n              background: 'var(--field-opacity)',\n            }}\n          >\n            <Typography component={'p'} variant={'h5'} color={'var(--color-text-secondary)'}>\n              {t('labelVaultRedeemDetail')}\n            </Typography>\n            {vaultCloseDetail?.executionHistory.length ? (\n              vaultCloseDetail?.executionHistory?.map((item, index) => {\n                return (\n                  <Typography\n                    key={index}\n                    variant={'body1'}\n                    component={'p'}\n                    display={'inline-flex'}\n                    justifyContent={'space-between'}\n                    marginTop={2}\n                    color={'var(--color-text-primary)'}\n                  >\n                    {item}\n                  </Typography>\n                )\n              })\n            ) : (\n              <Box flex={1} height={'100%'} width={'100%'}>\n                <EmptyDefault\n                  style={{ alignSelf: 'center' }}\n                  height={'100%'}\n                  message={() => (\n                    <Box flex={1} display={'flex'} alignItems={'center'} justifyContent={'center'}>\n                      {t('labelNoContent')}\n                    </Box>\n                  )}\n                />\n              </Box>\n            )}\n          </Box>\n        }\n      </Box>\n    )\n  },\n)\n\nexport const VaultOperationDetail = (props: {\n  statusColor: string\n  statusLabel: string\n  statusType: \"success\" | \"processing\" | \"failed\"\n  time: number\n  type: 'VAULT_BORROW' | 'VAULT_MARGIN_CALL' | 'VAULT_REPAY' | 'VAULT_OPEN_POSITION' | 'VAULT_JOIN_REDEEM' | 'VAULT_CLOSE_SHORT'\n  amount: string\n  amountSymbol: string\n}) => {\n  const { coinJson } = useSettings()\n  const { statusColor, statusLabel, time, type, statusType, amount, amountSymbol } = props\n  const { t } = useTranslation()\n  return (\n    <Box flex={1} display={'flex'} flexDirection={'column'}>\n      <Box\n        display={'flex'}\n        flexDirection={'column'}\n        justifyContent={'center'}\n        width={'100%'}\n        alignItems={'center'}\n      >\n        {statusType === 'failed' ? (\n          <FailedIcon style={{ color: 'var(--color-error)', width: 64, height: 64 }} />\n        ) : statusType === 'processing' ? (\n          <LoadingIcon color={'primary'} style={{ width: 64, height: 64 }} />\n        ) : (\n          <DoneIcon\n            style={{\n              color: 'var(--color-success)',\n              width: 64,\n              height: 64,\n            }}\n          />\n        )}\n        <Typography\n          marginTop={2}\n          variant={'body1'}\n          component={'span'}\n          color={'var(--color-text-primary)'}\n        >\n          {statusLabel}\n        </Typography>\n      </Box>\n      <Box\n        display={'flex'}\n        flexDirection={'column'}\n        alignItems={'stretch'}\n        justifyContent={'space-between'}\n        padding={2}\n        margin={2}\n        borderRadius={1 / 2}\n        sx={{\n          background: 'var(--field-opacity)',\n        }}\n      >\n        <Typography\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n          component={'span'}\n          order={9}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {t('labelType')}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {type === 'VAULT_OPEN_POSITION'\n              ? t('labelVaultJoin')\n              : type === 'VAULT_MARGIN_CALL'\n              ? t('labelVaultMarginCall')\n              : type === 'VAULT_BORROW'\n              ? t('labelVaultBorrow')\n              : type === 'VAULT_JOIN_REDEEM'\n              ? t('labelVaultJoinRedeem')\n              : type === 'VAULT_CLOSE_SHORT'\n              ? t('labelVaultCloseShort')\n              : t('labelVaultRepay')}\n          </Typography>\n        </Typography>\n        <Typography\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n          component={'span'}\n          order={9}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {t('labelVaultStatus')}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={statusColor}>\n            {statusLabel}\n          </Typography>\n        </Typography>\n        <Typography\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n          component={'span'}\n          order={9}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {type === 'VAULT_BORROW' || type === 'VAULT_REPAY' || type === 'VAULT_JOIN_REDEEM' || type === 'VAULT_CLOSE_SHORT'\n              ? t('labelVaultAmount')\n              : t('labelVaultCollateral')}\n          </Typography>\n          <Typography\n            display={'flex'}\n            flexDirection={'row'}\n            alignItems={'center'}\n            variant={'body1'}\n            component={'span'}\n            color={'var(--color-text-primary)'}\n          >\n            {amount ? (\n              <>\n                <CoinIcons\n                  size='small'\n                  type={TokenType.single}\n                  tokenIcon={[coinJson[amountSymbol], undefined]}\n                />{' '}\n                <Typography marginLeft={(type === 'VAULT_MARGIN_CALL' || type === 'VAULT_OPEN_POSITION') ? 0.5 : 0}>{amount} {mapSpecialTokenName(amountSymbol)}</Typography>\n              </>\n            ) : (\n              EmptyValueTag\n            )}\n          </Typography>\n        </Typography>\n        <Typography\n          component={'span'}\n          display={'inline-flex'}\n          justifyContent={'space-between'}\n          marginTop={2}\n          order={10}\n        >\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n            {t('labelVaultTime')}\n          </Typography>\n          <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n            {time && moment(time).format(YEAR_DAY_MINUTE_FORMAT)}\n          </Typography>\n        </Typography>\n      </Box>\n    </Box>\n  )\n}\n\nexport const VaultTradeDetail = withTranslation(['common'])(\n  (\n    props: {\n      statusColor: string\n      statusLabel: string\n      statusType: \"success\" | \"processing\" | \"failed\"\n      fromSymbol: string\n      toSymbol: string\n      placedAmount: string\n      executedAmount: string\n      executedRate: string\n      convertedAmount: string\n      price: string\n      feeSymbol: string\n      feeAmount: string\n      time: number\n    } & WithTranslation,\n  ) => {\n    const {\n      statusColor,\n      statusLabel,\n      statusType,\n      fromSymbol,\n      toSymbol,\n      placedAmount,\n      executedAmount,\n      executedRate,\n      convertedAmount,\n      price,\n      feeSymbol,\n      feeAmount,\n      time,\n    } = props\n    const { coinJson } = useSettings()\n    const { t } = useTranslation()\n    return (\n      <Box flex={1} display={'flex'} flexDirection={'column'}>\n        <Box\n          display={'flex'}\n          flexDirection={'column'}\n          justifyContent={'center'}\n          width={'100%'}\n          alignItems={'center'}\n        >\n          {statusType === 'failed' ? (\n            <FailedIcon style={{ color: 'var(--color-error)', width: 64, height: 64 }} />\n          ) : statusType === 'processing' ? (\n            <LoadingIcon color={'primary'} style={{ width: 64, height: 64 }} />\n          ) : (\n            <DoneIcon\n              style={{\n                color: 'var(--color-success)',\n                width: 64,\n                height: 64,\n              }}\n            />\n          )}\n          <Typography\n            marginTop={2}\n            variant={'body1'}\n            component={'span'}\n            color={'var(--color-text-primary)'}\n          >\n            {statusLabel}\n          </Typography>\n        </Box>\n        <Box\n          display={'flex'}\n          flexDirection={'column'}\n          alignItems={'stretch'}\n          justifyContent={'space-between'}\n          padding={2}\n          margin={2}\n          borderRadius={1 / 2}\n          sx={{\n            background: 'var(--field-opacity)',\n          }}\n        >\n          <Typography\n            display={'inline-flex'}\n            justifyContent={'space-between'}\n            marginTop={2}\n            component={'span'}\n            order={9}\n          >\n            <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n              {t('labelType')}\n            </Typography>\n            <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n              {t('labelVaultSwap')}\n            </Typography>\n          </Typography>\n          <Typography\n            display={'inline-flex'}\n            justifyContent={'space-between'}\n            marginTop={2}\n            component={'span'}\n            order={9}\n          >\n            <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n              {t('labelVaultStatus')}\n            </Typography>\n            <Typography variant={'body1'} component={'span'} color={statusColor}>\n              {statusLabel}\n            </Typography>\n          </Typography>\n          <Typography\n            display={'inline-flex'}\n            justifyContent={'space-between'}\n            marginTop={2}\n            component={'span'}\n            order={9}\n          >\n            <Typography display={'flex'} alignItems={'center'} variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n              {t('labelVaultPlacedAmount')}\n              <Tooltip title={<>{t('labelVaultPlacedAmountTip')}</>}>\n                <Typography marginLeft={0.5} display={'flex'} alignItems={'center'}>\n                  <Info2Icon fontSize={'medium'} htmlColor={'var(--color-text-third)'} />\n                </Typography>\n              </Tooltip>\n            </Typography>\n            <Typography\n              display={'flex'}\n              flexDirection={'row'}\n              alignItems={'center'}\n              variant={'body1'}\n              component={'span'}\n              color={'var(--color-text-primary)'}\n            >\n              <CoinIcons\n                size='small'\n                type={TokenType.single}\n                tokenIcon={[coinJson[fromSymbol], undefined]}\n              />{' '}\n              {placedAmount} {fromSymbol}\n            </Typography>\n          </Typography>\n          <Typography\n            display={'inline-flex'}\n            justifyContent={'space-between'}\n            marginTop={2}\n            component={'span'}\n            order={9}\n          >\n            <Typography display={'flex'} alignItems={'center'} variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n              {t('labelVaultExecutedAmount')}\n              <Tooltip title={<>{t(\"labelVaultExecutedAmountTip\")}</>}>\n              <Typography marginLeft={0.5} display={'flex'} alignItems={'center'}>\n                <Info2Icon fontSize={'medium'} htmlColor={'var(--color-text-third)'} />\n              </Typography>\n            </Tooltip>\n            </Typography>\n            <Typography\n              display={'flex'}\n              flexDirection={'row'}\n              alignItems={'center'}\n              variant={'body1'}\n              component={'span'}\n              color={'var(--color-text-primary)'}\n            >\n              <CoinIcons\n                size='small'\n                type={TokenType.single}\n                tokenIcon={[coinJson[fromSymbol], undefined]}\n              />{' '}\n              {executedAmount} {fromSymbol}\n            </Typography>\n          </Typography>\n          <Typography\n            display={'inline-flex'}\n            justifyContent={'space-between'}\n            marginTop={2}\n            component={'span'}\n            order={9}\n          >\n            <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n              {t('labelVaultExecutedRate')}\n            </Typography>\n            <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n              {executedRate}\n            </Typography>\n          </Typography>\n          <Typography\n            display={'inline-flex'}\n            justifyContent={'space-between'}\n            marginTop={2}\n            component={'span'}\n            order={9}\n          >\n            <Typography display={'flex'} alignItems={'center'} variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n              {t('labelVaultConvertedAmount')}\n              <Tooltip title={<>{t(\"labelVaultConvertedAmountTip\")}</>}>\n              <Typography marginLeft={0.5} display={'flex'} alignItems={'center'}>\n                <Info2Icon fontSize={'medium'} htmlColor={'var(--color-text-third)'} />\n              </Typography>\n            </Tooltip>\n            </Typography>\n\n            <Typography\n              display={'flex'}\n              flexDirection={'row'}\n              alignItems={'center'}\n              variant={'body1'}\n              component={'span'}\n              color={'var(--color-text-primary)'}\n            >\n              <CoinIcons\n                size='small'\n                type={TokenType.single}\n                tokenIcon={[coinJson[toSymbol], undefined]}\n              />{' '}\n              {convertedAmount} {toSymbol}\n            </Typography>\n          </Typography>\n          <Typography\n            display={'inline-flex'}\n            justifyContent={'space-between'}\n            marginTop={2}\n            component={'span'}\n            order={9}\n          >\n            <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n              {t('labelVaultPrice')}\n            </Typography>\n            <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n              {price}\n            </Typography>\n          </Typography>\n          <Typography\n            display={'inline-flex'}\n            justifyContent={'space-between'}\n            marginTop={2}\n            component={'span'}\n            order={9}\n          >\n            <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n              {t('labelVaultTxFee')}\n            </Typography>\n\n            <Typography\n              display={'flex'}\n              flexDirection={'row'}\n              alignItems={'center'}\n              variant={'body1'}\n              component={'span'}\n              color={'var(--color-text-primary)'}\n            >\n              <CoinIcons\n                size='small'\n                type={TokenType.single}\n                tokenIcon={[coinJson[feeSymbol], undefined]}\n              />{' '}\n              {feeAmount} {feeSymbol}\n            </Typography>\n          </Typography>\n          <Typography\n            component={'span'}\n            display={'inline-flex'}\n            justifyContent={'space-between'}\n            marginTop={2}\n            order={10}\n          >\n            <Typography variant={'body1'} component={'span'} color={'var(--color-text-secondary)'}>\n              {t('labelVaultTime')}\n            </Typography>\n            <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n              {time && moment(time).format(YEAR_DAY_MINUTE_FORMAT)}\n            </Typography>\n          </Typography>\n        </Box>\n      </Box>\n    )\n  },\n)\n\ntype VaultConvertDetailProps = {\n  totalValueInCurrency: string\n  convertedInUSDT: string\n  repaymentInUSDT?: string\n  time: number\n  dusts: {\n    symbol: string\n    coinJSON: any\n    amount: string\n    valueInCurrency: string\n  }[]\n  status: 'success' | 'processing' | 'failed'\n}\n\nexport const VaultConvertDetail = (props: VaultConvertDetailProps) => {\n  const { totalValueInCurrency, convertedInUSDT, repaymentInUSDT, time, dusts, status } = props\n  const theme = useTheme()\n  const { t } = useTranslation('tables')\n  const iconDiv = React.useMemo(() => {\n    switch (status) {\n      case 'failed':\n        return (\n          <Box\n            width={'100%'}\n            marginBottom={2}\n            display={'flex'}\n            flexDirection={'column'}\n            alignItems={'center'}\n          >\n            <FailedIcon style={{ color: 'var(--color-error)', width: 64, height: 64 }} />\n            <Typography marginTop={1}>{t('labelVaultVAULT_STATUS_FAILED')}</Typography>\n          </Box>\n        )\n      case 'success':\n        return (\n          <Box\n            width={'100%'}\n            marginBottom={2}\n            display={'flex'}\n            flexDirection={'column'}\n            alignItems={'center'}\n          >\n            <DoneIcon\n              style={{\n                color: 'var(--color-success)',\n                width: 64,\n                height: 64,\n              }}\n            />\n            <Typography marginTop={1}>{t('labelVaultVAULT_STATUS_SUCCEED')}</Typography>\n          </Box>\n        )\n      case 'processing':\n        return (\n          <Box\n            width={'100%'}\n            marginBottom={2}\n            display={'flex'}\n            flexDirection={'column'}\n            alignItems={'center'}\n          >\n            <LoadingIcon color={'primary'} style={{ width: 64, height: 64 }} />\n            <Typography marginTop={1}>{t('labelVaultVAULT_STATUS_PROCESSING')}</Typography>\n          </Box>\n        )\n    }\n  }, [status])\n  return (\n    <Box\n      justifySelf={'stretch'}\n      display={'flex'}\n      flexDirection={'column'}\n      width={'100%'}\n      justifyContent={'center'}\n      marginTop={2}\n      paddingX={3}\n    >\n      {iconDiv}\n      <Typography textAlign={'center'} variant='h4'>{repaymentInUSDT ? (repaymentInUSDT + ' USDT') : '--'} </Typography>\n      <Typography textAlign={'center'} mt={1} mb={2} color={'var(--color-text-third)'}>{totalValueInCurrency} </Typography>\n      <Box borderRadius={'8px'} bgcolor={'var(--color-box-secondary)'} paddingX={2.5} paddingY={1}>\n\n        <SpaceBetweenBox\n          leftNode={\n            <Typography color={'var(--color-text-third)'}>{t('labelVaultRepayment')}</Typography>\n          }\n          rightNode={\n            <Typography>{repaymentInUSDT ? repaymentInUSDT + ' USDT' : '--'} </Typography>\n          }\n          marginBottom={2}\n        />\n        <SpaceBetweenBox\n          leftNode={\n            <Typography color={'var(--color-text-third)'}>{t('labelVaultTime')}</Typography>\n          }\n          rightNode={\n            <Typography>{time ? moment(time).format(YEAR_DAY_MINUTE_FORMAT) : '--'}</Typography>\n          }\n        />\n      </Box>\n      <Box marginBottom={2} mt={2}>\n        {dusts &&\n          dusts.map((dust) => {\n            return (\n              <SpaceBetweenBox\n                paddingY={1.5}\n                paddingX={2}\n                marginBottom={1}\n                alignItems={'center'}\n                key={dust.symbol}\n                leftNode={\n                  <Box alignItems={'center'} display={'flex'}>\n                    <CoinIcons type={TokenType.single} tokenIcon={[dust.coinJSON]} />\n                    <Typography marginLeft={1}>{dust.symbol}</Typography>\n                  </Box>\n                }\n                rightNode={\n                  <Box display={'flex'} alignItems={'center'}>\n                    <Box marginRight={1}>\n                      <Typography textAlign={'right'}>{dust.amount}</Typography>\n                      <Typography\n                        color={'var(--color-text-secondary)'}\n                        textAlign={'right'}\n                        variant={'body2'}\n                      >\n                        {dust.valueInCurrency}\n                      </Typography>\n                    </Box>\n                  </Box>\n                }\n              />\n            )\n          })}\n      </Box>\n      {status === 'failed' && (\n        <Box\n          borderRadius={'8px'}\n          display={'flex'}\n          alignItems={'center'}\n          paddingX={2.5}\n          paddingY={1.5}\n          bgcolor={hexToRGB(theme.colorBase.error, 0.2)}\n        >\n          <ErrorIcon sx={{ color: 'var(--color-error)', marginRight: 1 / 2 }} />\n          <Typography>{t('labelVaultErrorOccurred')}</Typography>\n        </Box>\n      )}\n    </Box>\n  )\n}\n\n"
  },
  {
    "path": "packages/component-lib/src/components/tableList/vaultTable/index.ts",
    "content": "export { type VaultTxsTableProps, VaultTxTable, VaultCloseDetail } from './VaultTxTable'\nexport { type RawDataVaultTxItem, VaultRecordType } from './Interface'\n"
  },
  {
    "path": "packages/component-lib/src/components/text-tooltip/index.tsx",
    "content": "import { Tooltip } from '@mui/material'\n\ntype TextTooltipProps = {\n  tooltipTitle: string\n  text: string\n}\nconst TextTooltip = ({ tooltipTitle, text }: TextTooltipProps) => {\n  return (\n    <Tooltip placement='top' title={tooltipTitle}>\n      <span style={{ borderBottom: '1px dotted' }}>{text}</span>\n    </Tooltip>\n  )\n}\nexport default TextTooltip\n"
  },
  {
    "path": "packages/component-lib/src/components/toast/index.tsx",
    "content": "import { Alert, AlertTitle, Box, Snackbar, SnackbarOrigin, Typography } from '@mui/material'\nimport {\n  AlertIcon,\n  ErrorIcon,\n  GoodIcon,\n  InfoIcon,\n  SnackbarMessage,\n} from '@loopring-web/common-resources'\nimport styled from '@emotion/styled'\nimport { withTranslation, WithTranslation } from 'react-i18next'\nimport React from 'react'\nimport { VendorIconItem } from '../tradePanel'\n\nexport enum ToastType {\n  success = 'success',\n  error = 'error',\n  warning = 'warning',\n  info = 'info',\n}\n\nexport type TOASTOPEN = {\n  open: boolean\n  content: JSX.Element | string\n  type: ToastType\n  [key: string]: any\n}\nexport type TOSTOBJECT = {\n  toastOpen: TOASTOPEN\n  setToastOpen: (state: TOASTOPEN) => void\n  closeToast: () => void\n}\n\nexport interface ToastProps {\n  open: boolean\n  severity?: ToastType\n  alertText: string | JSX.Element\n  autoHideDuration?: number\n  onClose: () => void\n  snackbarOrigin?: SnackbarOrigin\n}\n\nconst AlertStyled = styled(Alert)`\n  svg:first-of-type {\n    width: 2rem;\n    height: 2rem;\n    margin-top: 0.2rem;\n  }\n`\n\nexport const Toast = withTranslation('common')(\n  ({\n    t,\n    open,\n    severity = ToastType.success,\n    alertText,\n    autoHideDuration = 2000,\n    onClose,\n    snackbarOrigin,\n  }: ToastProps & WithTranslation) => {\n    const renderTitle =\n      severity === 'success'\n        ? t('labelSuccessfully')\n        : severity === 'warning'\n        ? t('labelWarning')\n        : severity === 'error'\n        ? t('labelFailure')\n        : t('labelPrompt')\n\n    const renderIcon =\n      severity === 'success' ? (\n        <GoodIcon htmlColor={'var(--color-success)'} />\n      ) : severity === 'warning' ? (\n        <AlertIcon htmlColor={'var(--color-warning)'} />\n      ) : severity === 'error' ? (\n        <ErrorIcon htmlColor={'var(--color-error)'} />\n      ) : (\n        <InfoIcon htmlColor={'var(--color-secondary)'} />\n      )\n\n    return (\n      <Snackbar\n        open={open}\n        autoHideDuration={autoHideDuration}\n        onClose={onClose}\n        anchorOrigin={snackbarOrigin}\n      >\n        <AlertStyled icon={renderIcon} severity={severity}>\n          <AlertTitle>{renderTitle}</AlertTitle>\n          <Typography variant={'h6'} color={'var(--color-text-secondary)'}>\n            {alertText}\n          </Typography>\n        </AlertStyled>\n      </Snackbar>\n    )\n  },\n)\n\nexport const NoticeSnack = ({\n  messageInfo,\n  handleClose,\n  open,\n  actionEle,\n}: {\n  open: boolean\n  handleClose: () => void\n  actionEle: JSX.Element\n  messageInfo: SnackbarMessage\n}) => {\n  return (\n    <Snackbar\n      key={messageInfo ? messageInfo.key : undefined}\n      open={open}\n      autoHideDuration={20000}\n      sx={{\n        pointerEvents: 'all',\n        flexDirection: 'column',\n        top: '80% !important',\n        height: 'fit-content',\n        '.MuiPaper-root': { background: 'var(--color-pop-bg)' },\n      }}\n      onClose={handleClose}\n      message={\n        <Box display={'flex'} flexDirection={'column'}>\n          {messageInfo.svgIcon && VendorIconItem({ svgIcon: messageInfo.svgIcon })}\n          <Typography component={'span'} display={'block'} marginY={1}>\n            {messageInfo ? messageInfo.message : undefined}\n          </Typography>\n        </Box>\n      }\n      action={actionEle}\n      anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}\n    />\n  )\n}\nexport const NoticePanelSnackBar = ({\n  noticeSnacksElEs,\n}: {\n  noticeSnacksElEs: Array<typeof NoticeSnack>\n}) => {\n  return (\n    <>\n      {noticeSnacksElEs.map((item, index) => {\n        return <React.Fragment key={index}>{item as any}</React.Fragment>\n      })}\n    </>\n  )\n}\n\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/Amm/AmmPanel.tsx",
    "content": "import { AmmChgData, AmmDepositWrap, AmmWithdrawWrap } from '../components'\nimport { Box, BoxProps, Tab, Tabs, Toolbar } from '@mui/material'\nimport {\n  AmmExitData,\n  AmmInData,\n  AmmJoinData,\n  IBData,\n  AmmPanelType,\n} from '@loopring-web/common-resources'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport React from 'react'\nimport { CountDownIcon } from '../components/tool/Refresh'\nimport styled from '@emotion/styled'\nimport { boxLiner, toolBarPanel } from '../../styled'\nimport { AmmProps } from './Interface'\nimport { useSettings } from '../../../stores'\n\nconst WrapStyle = styled(Box)<\n  BoxProps & {\n    _height?: number | string\n    _width?: number | string\n    isMobile: boolean\n  }\n>`\n  ${({ _width, isMobile }) =>\n    isMobile\n      ? `width:100%;height:auto;`\n      : `       \n      width: ${\n        typeof _width === 'string'\n          ? _width\n          : typeof _width === 'number'\n          ? _width + 'px'\n          : `var(--swap-box-width)`\n      };\n      height: auto;`}\n  ${({ theme }) => boxLiner({ theme })}\n  ${({ theme }) => toolBarPanel({ theme })}\n  border-radius: ${({ theme }) => theme.unit}px;\n  .trade-panel .coinInput-wrap {\n    background: var(--field-opacity);\n  }\n  .MuiToolbar-root {\n    //padding-left:0;\n    justify-content: space-between;\n    padding: 0 ${({ theme }) => (theme.unit * 5) / 2}px;\n  }\n` as (\n  props: BoxProps & {\n    _height?: number | string\n    _width?: number | string\n    isMobile: boolean\n  },\n) => JSX.Element\n\nconst TabPanelBtn = ({ t, value, handleChange }: WithTranslation & any) => {\n  return (\n    <Tabs value={value} onChange={handleChange} aria-label='Amm Method Tab'>\n      <Tab label={t('labelLiquidityDeposit')} value={0} />\n      <Tab label={t('labelLiquidityWithdraw')} value={1} />\n    </Tabs>\n  )\n}\n\nexport const AmmPanel = withTranslation('common', { withRef: true })(\n  <\n    T extends AmmJoinData<C extends IBData<I> ? C : IBData<I>>,\n    TW extends AmmExitData<C extends IBData<I> ? C : IBData<I>>,\n    I,\n    ACD extends AmmInData<I>,\n    C = IBData<I>,\n  >({\n    t,\n    tabSelected = AmmPanelType.Join,\n    ammDepositData,\n    ammWithdrawData,\n    disableDeposit,\n    disableWithdraw,\n    handleAmmAddChangeEvent,\n    handleAmmRemoveChangeEvent,\n    ammCalcDataDeposit,\n    ammCalcDataWithDraw,\n    tokenDepositAProps,\n    tokenDepositBProps,\n    tokenWithDrawAProps,\n    tokenWithDrawBProps,\n    ammDepositBtnStatus,\n    ammWithdrawBtnStatus,\n    ammDepositBtnI18nKey,\n    ammWithdrawBtnI18nKey,\n    onRefreshData,\n    refreshRef,\n    onAmmAddClick,\n    onAmmRemoveClick,\n    // onAmmAddChangeEvent,\n    // onRemoveChangeEvent,\n    handleError,\n    height,\n    width,\n    anchors,\n    propsLPExtends,\n    propsAExtends,\n    propsBExtends,\n    ammType,\n    handleTabChange,\n    // coinAPrecision,\n    // coinBPrecision,\n    ...rest\n  }: AmmProps<T, TW, I, ACD, C> & WithTranslation) => {\n    const _onChangeAddEvent = React.useCallback(\n      async ({ tradeData, type }: AmmChgData<T>) => {\n        handleAmmAddChangeEvent(tradeData, type)\n        // if (typeof onAmmAddChangeEvent == \"function\") {\n        //   onAmmAddChangeEvent({ tradeData, type } as AmmChgData<T>);\n        // }\n      },\n      [handleAmmAddChangeEvent],\n    )\n\n    const _onChangeRemoveEvent = React.useCallback(\n      async ({\n        tradeData,\n      }: // type,\n      // percentage\n      { tradeData: TW } & { type: 'lp'; percentage?: number }) => {\n        handleAmmRemoveChangeEvent(tradeData)\n        // if (typeof onRemoveChangeEvent == \"function\") {\n        //   onRemoveChangeEvent({ tradeData, type } as AmmWithdrawChgData<TW>);\n        // }\n      },\n      [handleAmmRemoveChangeEvent],\n    )\n\n    // const panelList: Pick<\n    //   PanelContent<\"ammJoin\" | \"ammExit\">,\n    //   \"key\" | \"element\"\n    // >[] = [\n    //   {\n    //     key: \"ammJoin\",\n    //     element: React.useMemo(\n    //       () => (\n    //\n    //       ),\n    //       [\n    //         t,\n    //         rest,\n    //         anchors,\n    //         disableDeposit,\n    //         ammDepositBtnStatus,\n    //         ammDepositBtnI18nKey,\n    //         ammCalcDataDeposit,\n    //         // onAmmAddClick,\n    //         handleError,\n    //         // _onChangeAddEvent,\n    //         ammDepositData,\n    //         tokenDepositAProps,\n    //         tokenDepositBProps,\n    //       ]\n    //     ),\n    //   },\n    //   {\n    //     key: \"ammExit\",\n    //     element: React.useMemo(\n    //       () => (\n    //\n    //       ),\n    //       [\n    //         t,\n    //         rest,\n    //         anchors,\n    //         disableWithdraw,\n    //         ammWithdrawBtnStatus,\n    //         ammWithdrawBtnI18nKey,\n    //         ammCalcDataWithDraw,\n    //         // onAmmRemoveClick,\n    //         // handleError,\n    //         // _onChangeRemoveEvent,\n    //         ammWithdrawData,\n    //         tokenWithDrawAProps,\n    //         tokenWithDrawBProps,\n    //       ]\n    //     ),\n    //   },\n    // ];\n    // const theme = useTheme();\n    const { isMobile } = useSettings()\n\n    return (\n      <WrapStyle\n        display={'flex'}\n        className={'trade-panel container'}\n        isMobile={isMobile}\n        paddingTop={'var(--toolbar-row-padding)'}\n        paddingBottom={3}\n        flexDirection={'column'}\n        flexWrap={'nowrap'}\n      >\n        <Toolbar className={'large'} variant={'regular'}>\n          <Box alignSelf={'center'} justifyContent={'flex-start'} display={'flex'} marginLeft={-2}>\n            <TabPanelBtn\n              {...{\n                t,\n                value: ammType,\n                handleChange: (_e: any, value: any) => handleTabChange(value),\n                ...rest,\n              }}\n            />\n          </Box>\n          <Box alignSelf={'center'}>\n            <CountDownIcon onRefreshData={onRefreshData} ref={refreshRef} />\n          </Box>\n        </Toolbar>\n\n        <Box flex={1} className={'trade-panel'}>\n          {ammType === AmmPanelType.Join && (\n            <Box\n              display={'flex'}\n              justifyContent={'space-evenly'}\n              alignItems={'stretch'}\n              height={'100%'}\n              padding={5 / 2}\n              // key={panelList[0].key}\n            >\n              <AmmDepositWrap<T, I, ACD, C>\n                key={'ammJoin'}\n                {...{\n                  t,\n                  ...rest,\n                  anchors,\n                  disableDeposit,\n                  ammDepositBtnStatus,\n                  ammDepositBtnI18nKey,\n                  ammCalcData: ammCalcDataDeposit,\n                  onAmmAddClick,\n                  onAddChangeEvent: _onChangeAddEvent,\n                  ammData: ammDepositData,\n                  tokenAProps: { ...tokenDepositAProps },\n                  tokenBProps: { ...tokenDepositBProps },\n                  propsAExtends,\n                  propsBExtends,\n                }}\n              />\n            </Box>\n          )}\n          {ammType === AmmPanelType.Exit && (\n            <Box\n              display={'flex'}\n              justifyContent={'space-evenly'}\n              alignItems={'stretch'}\n              height={'100%'}\n              padding={5 / 2}\n            >\n              <AmmWithdrawWrap<TW, I, ACD, C>\n                key={'ammExit'}\n                {...{\n                  t,\n                  ...rest,\n                  anchors,\n                  disableWithdraw,\n                  ammWithdrawBtnStatus,\n                  ammWithdrawBtnI18nKey,\n                  ammCalcData: ammCalcDataWithDraw,\n                  onAmmRemoveClick,\n                  handleError,\n                  propsLPExtends,\n                  selectedPercentage: -1,\n                  onRemoveChangeEvent: _onChangeRemoveEvent,\n                  ammData: ammWithdrawData,\n                  tokenAProps: { ...tokenWithDrawAProps },\n                  tokenBProps: { ...tokenWithDrawBProps },\n                }}\n              />\n            </Box>\n          )}\n        </Box>\n      </WrapStyle>\n    )\n  },\n) as <\n  T extends AmmJoinData<C extends IBData<I> ? C : IBData<I>>,\n  TW extends AmmExitData<C extends IBData<I> ? C : IBData<I>>,\n  I,\n  ACD extends AmmInData<I>,\n  C = IBData<I>,\n>(\n  props: AmmProps<T, TW, I, ACD, C> & React.RefAttributes<any>,\n) => JSX.Element\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/Amm/Interface.tsx",
    "content": "import { InputButtonProps } from '../../basic-lib'\nimport {\n  AccountStatus,\n  AmmExitData,\n  AmmJoinData,\n  AmmPanelType,\n  CoinInfo,\n  IBData,\n} from '@loopring-web/common-resources'\nimport { AmmDepositBaseProps, AmmWithdrawBaseProps } from '../components'\n\n/**\n *\n */\nexport type AmmPanelBaseProps<T, TW, I, ACD, C> = {\n  ammDepositData: T\n  ammWithdrawData: TW\n  tabSelected?: AmmPanelType\n  disableDeposit?: boolean\n  disableWithdraw?: boolean\n  ammCalcDataDeposit: ACD\n  ammCalcDataWithDraw: ACD\n  tokenDepositAProps?: Partial<InputButtonProps<C, I, CoinInfo<I>>>\n  tokenDepositBProps?: Partial<InputButtonProps<C, I, CoinInfo<I>>>\n  tokenWithDrawAProps?: Partial<InputButtonProps<C, I, CoinInfo<I>>>\n  tokenWithDrawBProps?: Partial<InputButtonProps<C, I, CoinInfo<I>>>\n  ammDepositBtnI18nKey?: string\n  ammWithdrawBtnI18nKey?: string\n  height?: number\n  width?: number\n}\n\nexport type AmmProps<\n  T extends AmmJoinData<C extends IBData<I> ? C : IBData<I>>,\n  TW extends AmmExitData<C extends IBData<I> ? C : IBData<I>>,\n  I,\n  ACD,\n  C = IBData<I>,\n> = AmmPanelBaseProps<T, TW, I, ACD, C> & {\n  handleAmmAddChangeEvent: (data: T, focusOn: 'coinA' | 'coinB') => void\n  handleAmmRemoveChangeEvent: (data: TW) => void\n  // onAmmAddChangeEvent?: (data: AmmChgData<T>) => AmmChgData<T>;\n  // onRemoveChangeEvent?: (\n  //   data: AmmWithdrawChgData<TW>\n  // ) => AmmWithdrawChgData<TW>;\n  refreshRef: React.Ref<any>\n  onRefreshData?: () => void\n  accStatus?: AccountStatus\n  coinAPrecision?: number\n  coinBPrecision?: number\n  ammType: AmmPanelType\n  handleTabChange: (index: AmmPanelType) => void\n} & AmmWithdrawBaseProps<TW, I> &\n  AmmDepositBaseProps<T, I>\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/Amm/index.ts",
    "content": "export * from './AmmPanel'\nexport * from './Interface'\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/Deposit/DepositGroup.tsx",
    "content": "import { DepositGroupProps, DepositPanelType } from './Interface'\nimport { IBData } from '@loopring-web/common-resources'\nimport { PanelContent } from '../../basic-lib'\nimport { DepositPanel } from '../../modal/ModalPanels/DepositPanel'\nimport { VendorMenu } from './VendorMenu'\nimport { Box, BoxProps, Toolbar, Typography } from '@mui/material'\nimport { useTheme } from '@emotion/react'\nimport { DepositTitleGroup, DepositTitleNewGroup } from './DepositTitle'\nimport React from 'react'\nimport SwipeableViews from 'react-swipeable-views'\nimport styled from '@emotion/styled'\nimport { useTranslation } from 'react-i18next'\nimport { useSettings } from '../../../stores'\n\nconst ToolbarStyle = styled(Toolbar)`\n  .MuiTabs-root {\n    flex: 1;\n    .MuiTab-root {\n      display: inline-flex;\n      flex-direction: row;\n    }\n  }\n`\nconst BoxStyle = styled(Box)<BoxProps & { isMobile: boolean | undefined }>`\n  .trade-panel {\n    width: 100%;\n    height: 240px;\n  }\n  .isNew .trade-panel {\n    height: 308px;\n  }\n\n  .react-swipeable-view-container {\n    .trade-panel .react-swipeable-view-container {\n      & > div {\n        padding: 0;\n        & > .MuiGrid-container {\n          padding: 0;\n        }\n      }\n      padding: 0;\n    }\n  }\n\n  .way-content > div:first-of-type {\n    position: relative;\n    font-size: ${({ theme }) => theme.fontDefault.body1};\n\n    ${({ isMobile, theme }) =>\n      isMobile\n        ? `\n        padding-bottom:  ${10 * theme.unit}px;\n         &:before {\n          display: block;\n          content: \" \";\n          position: absolute;\n          bottom:  0px;\n          left:0;          \n          right:0;\n          bottom: ${6 * theme.unit}px;\n          margin: 0 ${2 * theme.unit}px;\n          color: var(--color-text-third);\n          border: 1px solid var(--color-text-third);\n          opacity: 0.4;\n       }\n      &:after {\n        display: block;\n        content: \"OR\";\n        position: absolute;\n        width: 32px;\n        height: 32px;\n        line-height: 32px;\n        text-align: center;\n        left:50%;\n        margin-left: -16px;\n        bottom: ${2 * theme.unit}px;\n        background: ${theme.colorBase.box};\n        color: var(--color-text-third);\n      }`\n        : ` \n        &:before {\n          display: block;\n          content: \" \";\n          position: absolute;\n          right: ${-theme.unit}px;\n          bottom: 0;\n          top:0;\n          height: 100%;\n          color: var(--color-text-third);\n          border-right: 1px solid var(--color-divide);\n       }\n      &:after {\n        display: block;\n        content: \"OR\";\n        position: absolute;\n        bottom: 50%;\n        width: 32px;\n        height: 32px;\n        line-height: 32px;\n        text-align: center;\n        right: ${-3 * theme.unit}px;\n        background: ${theme.colorBase.box};\n        color: var(--color-text-third);\n      }`}\n  }\n  padding-left: 0;\n  padding-right: 0;\n` as (props: BoxProps & { isMobile: boolean | undefined }) => JSX.Element\n\nexport const DepositGroup = <T extends IBData<I>, I>({\n  depositProps,\n  vendorMenuProps,\n  tabIndex = DepositPanelType.Deposit,\n}: // onTabChange,\nDepositGroupProps<T, I>) => {\n  const theme = useTheme()\n  const { t } = useTranslation(['common'])\n  const { isMobile } = useSettings()\n  const [_tabIndex, setTabIndex] = React.useState<DepositPanelType>(\n    tabIndex ?? DepositPanelType.Deposit,\n  )\n\n  React.useEffect(() => {\n    setTabIndex(tabIndex)\n  }, [tabIndex])\n\n  const panelList: Pick<PanelContent<'Deposit' | 'Vendor'>, 'key' | 'element'>[] = [\n    {\n      key: 'Deposit',\n      element: <DepositPanel {...{ ...depositProps }} />,\n    },\n    {\n      key: 'Vendor',\n      element: <VendorMenu {...{ ...vendorMenuProps }} />,\n    },\n  ]\n\n  return (\n    <BoxStyle\n      isMobile={isMobile}\n      display={'flex'}\n      height={'auto'}\n      flexDirection={'column'}\n      flexWrap={'nowrap'}\n      paddingX={3}\n      marginTop={-4}\n      paddingBottom={3}\n    >\n      <Box marginBottom={3} marginTop={isMobile ? 0 : 3}>\n        <Typography component={'h4'} variant={'h4'} marginRight={1} textAlign={'center'}>\n          {depositProps.isNewAccount\n            ? t('labelCreateLayer2Title', { layer2: 'Layer 2' })\n            : t('labelAddAsset')}\n        </Typography>\n      </Box>\n      <Box\n        display={'flex'}\n        flexDirection={'row'}\n        justifyContent={'center'}\n        alignItems={'center'}\n        marginBottom={2}\n      >\n        {depositProps.isNewAccount ? (\n          <Box\n            minWidth={'320px'}\n            width={isMobile ? 'auto' : `calc(2 *  var(--modal-width) - ${(theme.unit * 5) / 2}px)`}\n            display={'flex'}\n          >\n            <Box\n              className={'content way-content isNew'}\n              display={'flex'}\n              flex={1}\n              flexDirection={isMobile ? 'column' : 'row'}\n              justifyContent={'space-around'}\n            >\n              {panelList.map((panel, index) => {\n                return (\n                  <Box\n                    width={isMobile ? 'auto' : '48%'}\n                    key={index}\n                    minHeight={isMobile ? '320' : '280'}\n                  >\n                    <Box\n                      flex={1}\n                      display={'flex'}\n                      flexDirection={'row'}\n                      justifyContent={'space-around'}\n                      marginBottom={2}\n                      paddingLeft={4}\n                    >\n                      {DepositTitleNewGroup()[index]}\n                    </Box>\n                    {panel.element}\n                  </Box>\n                )\n              })}\n            </Box>\n          </Box>\n        ) : (\n          <Box minHeight={240} width={`calc(var(--swap-box-width) + ${theme.unit * 5}px)`}>\n            <ToolbarStyle className={'large'} variant={'regular'}>\n              <DepositTitleGroup\n                onTabChange={(index) => {\n                  setTabIndex(index)\n                }}\n                tabIndex={_tabIndex}\n              />\n            </ToolbarStyle>\n            <SwipeableViews axis={theme.direction === 'rtl' ? 'x-reverse' : 'x'} index={_tabIndex}>\n              {panelList.map((panel, index) => {\n                return <React.Fragment key={index}>{panel.element}</React.Fragment>\n              })}\n            </SwipeableViews>\n          </Box>\n        )}\n      </Box>\n    </BoxStyle>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/Deposit/DepositTitle.tsx",
    "content": "import { Tab, Tabs, Typography } from '@mui/material'\nimport { Info2Icon, L1L2_NAME_DEFINED, MapChainId } from '@loopring-web/common-resources'\nimport React from 'react'\nimport { bindPopper, usePopupState } from 'material-ui-popup-state/hooks'\nimport { bindHover } from 'material-ui-popup-state'\nimport { Trans, useTranslation } from 'react-i18next'\nimport { PopoverPure } from '../../basic-lib'\nimport { DepositPanelType } from './Interface'\nimport { useSettings } from '../../../stores'\n\nexport const DepositTitle = ({ title, description, isHideDes = false }: any) => {\n  const { t } = useTranslation()\n  const { isMobile, defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n\n  const popupState = usePopupState({\n    variant: 'popover',\n    popupId: `popupId-deposit`,\n  })\n  return (\n    <Typography display={'inline-flex'} alignItems={'center'}>\n      <Typography\n        component={'span'}\n        variant={isMobile ? 'h4' : 'h3'}\n        whiteSpace={'pre-line'}\n        marginRight={1}\n        className={'depositTitle'}\n      >\n        {title ? title : t('depositTitle')}\n      </Typography>\n      {!isHideDes && (\n        <>\n          <Info2Icon\n            {...bindHover(popupState)}\n            fontSize={isMobile ? 'medium' : 'large'}\n            htmlColor={'var(--color-text-third)'}\n          />\n          <PopoverPure\n            className={'arrow-center'}\n            {...bindPopper(popupState)}\n            anchorOrigin={{\n              vertical: 'bottom',\n              horizontal: 'center',\n            }}\n            transformOrigin={{\n              vertical: 'top',\n              horizontal: 'center',\n            }}\n          >\n            <Typography padding={2} component={'p'} variant={'body2'} whiteSpace={'pre-line'}>\n              <Trans\n                i18nKey={description ? description : 'labelDepositDescription'}\n                tOptions={{\n                  l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                }}\n              >\n                Once your deposit is confirmed on Ethereum, it will be added to your balance within\n                2 minutes.\n              </Trans>\n            </Typography>\n          </PopoverPure>\n        </>\n      )}\n    </Typography>\n  )\n}\nconst ThirdPartTitle = React.memo(() => {\n  const { t } = useTranslation()\n  const popupState = usePopupState({\n    variant: 'popover',\n    popupId: `popupId-ThirdPart`,\n  })\n  return (\n    <>\n      <Typography component={'span'} variant={'h5'} marginRight={1}>\n        {t('labelVendor')}\n      </Typography>\n      <Info2Icon\n        {...bindHover(popupState)}\n        fontSize={'medium'}\n        htmlColor={'var(--color-text-third)'}\n      />\n      <PopoverPure\n        className={'arrow-center'}\n        {...bindPopper(popupState)}\n        anchorOrigin={{\n          vertical: 'bottom',\n          horizontal: 'center',\n        }}\n        transformOrigin={{\n          vertical: 'top',\n          horizontal: 'center',\n        }}\n      >\n        <Typography padding={2} component={'p'} variant={'body2'} whiteSpace={'pre-line'}>\n          <Trans i18nKey={'labelL1toL2Vendor'}>\n            Make an order form third Loopring-parter, Once your order confirmed by Loopring, it will\n            be added to your balance within 2 minutes.\n          </Trans>\n        </Typography>\n      </PopoverPure>\n    </>\n  )\n})\n\nexport const DepositTitleGroup = ({\n  tabIndex,\n  onTabChange,\n  title,\n  description,\n}: {\n  title?: string\n  description?: string\n  tabIndex: DepositPanelType\n  onTabChange: (index: DepositPanelType) => void\n  // (event: React.SyntheticEvent, value: DepositTabIndex) => void;\n}) => {\n  return (\n    <>\n      <Tabs variant={'fullWidth'} value={tabIndex} onChange={(_e, value) => onTabChange(value)}>\n        <Tab\n          value={DepositPanelType.Deposit}\n          label={<DepositTitle title={title} description={description} />}\n        />\n        <Tab value={DepositPanelType.ThirdPart} label={<ThirdPartTitle />} />\n      </Tabs>\n    </>\n  )\n}\n\nexport const DepositTitleNewGroup = () => {\n  return [\n    <Typography component={'span'}>\n      <DepositTitle />\n    </Typography>,\n    <Typography component={'span'}>\n      <ThirdPartTitle />\n    </Typography>,\n  ]\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/Deposit/Interface.tsx",
    "content": "import { DepositProps } from '../Interface'\nimport { VendorMenuProps } from '../../modal'\n\nexport enum DepositPanelType {\n  Deposit = 0,\n  ThirdPart = 1,\n}\n\nexport type DepositGroupProps<T, I> = {\n  depositProps: DepositProps<T, I>\n  vendorMenuProps: VendorMenuProps\n  tabIndex?: DepositPanelType\n  // onTabChange: (value: DepositPanelType) => void;\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/Deposit/VendorMenu.tsx",
    "content": "import { Avatar, Box, Typography } from '@mui/material'\nimport { MenuBtnStyled } from '../../styled'\nimport { VendorMenuProps } from '../../modal/ModalPanels/Interface'\nimport { useTranslation } from 'react-i18next'\nimport {\n  BanxaIcon,\n  RampIcon,\n  SCENARIO,\n  TradeBtnStatus,\n  TradeTypes,\n  VendorProviders,\n} from '@loopring-web/common-resources'\nimport { useTheme } from '@emotion/react'\nimport { useSettings } from '../../../stores'\nimport { TagIconList } from '../../block'\nimport { CoinIcon } from '../../basic-lib'\n\nexport const VendorIconItem = ({ svgIcon }: { svgIcon: string }) => {\n  const theme = useTheme()\n  switch (svgIcon) {\n    case 'BanxaIcon':\n      return (\n        <BanxaIcon\n          style={{\n            height: '24px',\n            width: '103px',\n          }}\n          fontColor={theme.colorBase.textPrimary}\n        />\n      )\n    case 'RampIcon':\n      return (\n        <RampIcon\n          style={{\n            height: '24px',\n            width: '114px',\n          }}\n          fontColor={theme.colorBase.textPrimary}\n        />\n      )\n  }\n}\n\nexport const VendorMenu = ({\n  vendorList,\n  banxaRef,\n  // handleSelect,\n  campaignTagConfig,\n  type = TradeTypes.Buy,\n  vendorForce,\n}: VendorMenuProps) => {\n  const { t } = useTranslation()\n  const { isMobile } = useSettings()\n  const theme = useTheme()\n  return (\n    <Box\n      flex={1}\n      display={'flex'}\n      alignItems={'center'}\n      justifyContent={'space-between'}\n      flexDirection={'column'}\n    >\n      <Typography variant={isMobile ? 'h4' : 'h3'} whiteSpace={'pre'} component={'h4'}>\n        {type === 'Buy' ? t('labelL1toL2ThirdPartOn') : t('labelL1toL2ThirdPartOff')}\n      </Typography>\n      <Box\n        display={'flex'}\n        flexDirection={'column'}\n        justifyContent={'center'}\n        flex={1}\n        alignItems={'stretch'}\n        alignSelf={'stretch'}\n        className='modalContent'\n        paddingX={3}\n        paddingTop={1}\n      >\n        <Typography color={'textSecondary'} variant={'body1'} marginBottom={1}>\n          {t('labelWhatProvider')}\n        </Typography>\n        {vendorList.map((item) => (\n          <Box key={item.key} marginTop={1.5} width={'100%'}>\n            <MenuBtnStyled\n              variant={'outlined'}\n              size={'large'}\n              id={item.key + (type == TradeTypes.Buy ? '-on' : '-off')}\n              ref={\n                item.key === VendorProviders.Banxa && type === TradeTypes.Buy ? banxaRef : undefined\n              }\n              className={`${isMobile ? 'isMobile' : ''} ${\n                vendorForce === item.key ? 'selected vendor' : 'vendor'\n              }`}\n              fullWidth\n              style={{\n                height:\n                  item.flag && item.flag.startDate < Date.now() && Date.now() < item.flag.endDate\n                    ? 56\n                    : '',\n                flexDirection: 'row',\n                display: 'flex',\n                justifyContent: 'space-between',\n              }}\n              loading={\n                item.btnStatus && item.btnStatus === TradeBtnStatus.LOADING ? 'true' : 'false'\n              }\n              disabled={\n                item.btnStatus &&\n                [TradeBtnStatus.LOADING, TradeBtnStatus.DISABLED].includes(item.btnStatus)\n              }\n              onClick={(e) => {\n                if (item.handleSelect) {\n                  item.handleSelect(e)\n                }\n              }}\n            >\n              <Box display={'flex'}>\n                {VendorIconItem({ svgIcon: item.svgIcon })}\n                {campaignTagConfig && (\n                  <TagIconList\n                    scenario={SCENARIO.FIAT}\n                    size={'var(--svg-size-large)'}\n                    campaignTagConfig={campaignTagConfig}\n                    symbol={`${item.key}-${type == TradeTypes.Buy ? 'on' : 'off'}`}\n                  />\n                )}\n                {type == TradeTypes.Sell && (\n                  <Avatar\n                    alt={'BETA'}\n                    style={{\n                      width: 'auto',\n                      height: 'var(--svg-size-medium)',\n                      marginRight: theme.unit / 2,\n                    }}\n                    variant={'square'}\n                    src={'https://static.loopring.io/assets/svg/beta.png'}\n                  />\n                )}\n              </Box>\n              <Box display={'flex'} alignItems={'center'}>\n                {item.key === 'Ramp' ? (\n                  <>\n                    <CoinIcon symbol={'ETH'} />\n                    <CoinIcon symbol={'USDC'} />\n                    <CoinIcon symbol={'LRC'} />\n                  </>\n                ) : (\n                  <>\n                    <CoinIcon symbol={'ETH'} />\n                    <CoinIcon symbol={'USDC'} />\n                    <CoinIcon symbol={'USDT'} />\n                    <CoinIcon symbol={'LRC'} />\n                  </>\n                )}\n              </Box>\n\n              {/*{item.flag &&*/}\n              {/*  item.flag.startDate < Date.now() &&*/}\n              {/*  Date.now() < item.flag.endDate && (*/}\n              {/*    <>*/}\n              {/*      <Typography*/}\n              {/*        component={\"span\"}*/}\n              {/*        variant={\"body2\"}*/}\n              {/*        color={\"var(--color-warning)\"}*/}\n              {/*      >*/}\n              {/*        {t(item.flag.highLight ?? \"\")}*/}\n              {/*      </Typography>*/}\n              {/*      /!*<Typography position={\"absolute\"} right={8} top={4}>*!/*/}\n              {/*      /!*  {item.flag.tag}*!/*/}\n              {/*      /!*</Typography>*!/*/}\n              {/*    </>*/}\n              {/*  )}*/}\n            </MenuBtnStyled>\n          </Box>\n        ))}\n      </Box>\n    </Box>\n  )\n  {\n    /*</WalletConnectPanelStyled>*/\n  }\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/Deposit/index.ts",
    "content": "export * from './DepositGroup'\nexport * from './Interface'\nexport * from '../../modal/ModalPanels/DepositPanel'\nexport * from './DepositTitle'\nexport * from './VendorMenu'\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/ExportAccount/index.tsx",
    "content": "import { ExportAccountProps } from '../Interface'\nimport { withTranslation, WithTranslation } from 'react-i18next'\nimport { SwitchPanel, SwitchPanelProps } from '../../basic-lib'\nimport { ExportAccountWrap } from '../components'\nimport React from 'react'\n\nexport const ExportAccountPanel = withTranslation('common', { withRef: true })(\n  ({\n    exportAccountProps,\n    setExportAccountToastOpen,\n    ...rest\n  }: ExportAccountProps & WithTranslation) => {\n    const props: SwitchPanelProps<'tradeMenuList' | 'trade'> = {\n      index: 0, // show default show\n      panelList: [\n        {\n          key: 'trade',\n          element: React.useMemo(\n            () => (\n              <ExportAccountWrap\n                key={'transfer'}\n                {...{\n                  exportAccountProps,\n                  setExportAccountToastOpen,\n                  ...rest,\n                }}\n              />\n            ),\n            [exportAccountProps, rest, setExportAccountToastOpen],\n          ),\n          toolBarItem: undefined,\n        },\n      ],\n    }\n    return <SwitchPanel {...{ ...rest, ...props }} />\n  },\n)\n\n// export const TransferModal = withTranslation()\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/Interface.ts",
    "content": "import {\n  BtradeType,\n  CAMPAIGNTAGCONFIG,\n  CoinKey,\n  FeeInfo,\n  IBData,\n  MarketType,\n  NFTWholeINFO,\n  SCENARIO,\n  TradeBaseType,\n  TradeCalcProData,\n  TradeProType,\n  WithdrawType,\n  WithdrawTypes,\n} from '@loopring-web/common-resources'\nimport {\n  BasicACoinTradeHookProps,\n  ClaimExtendProps,\n  CreateRedPacketViewProps,\n  DefaultProps,\n  DepositExtendProps,\n  DepositInfoProps as _DepositInfoProps,\n  ExportAccountExtendProps,\n  ForceWithdrawViewProps,\n  NFTDeployViewProps,\n  NFTDepositViewProps,\n  NFTMetaViewProps,\n  NFTMintAdvanceViewProps,\n  NFTMintViewProps,\n  ResetExtendProps,\n  ResetInfoProps as _ResetInfoProps,\n  TransferExtendProps,\n  TransferInfoProps as _TransferInfoProps,\n  WithdrawExtendProps,\n} from './components/Interface'\nimport {\n  SwapData,\n  SwapTradeBaseEventProps,\n  SwapTradeBaseProps,\n  VaultBorrowBaseProps,\n  VaultRepayWrapProps,\n} from './components'\nimport {\n  StopTradeLimitInfoProps,\n  TradeLimitInfoProps,\n  TradeMarketInfoProps,\n  TradeProBaseEventProps,\n} from './tradePro/Interface'\nimport React from 'react'\nimport { TOASTOPEN } from '../toast'\nimport { VaultExitBaseProps, VaultJoinBaseProps } from './components/VaultWrap'\nimport { GetContactsResponse } from '@loopring-web/loopring-sdk'\n\nexport type SwapTradeData<T> = {\n  sell: T\n  buy: T\n  isChecked?: boolean\n  slippage: number | string\n  __cache__?: {\n    [key: string]: any\n  }\n  btradeType?: BtradeType\n}\n\nexport type LimitTradeData<T> = {\n  price: T\n  base: T\n  quote: T\n  type: TradeProType\n  isChecked?: boolean\n}\n\nexport type StopLimitTradeData<T> = {\n  price: T\n  stopPrice: T\n  base: T\n  quote: T\n  type: TradeProType\n}\nexport type MarketTradeData<T> = {\n  // price: T,\n  base: T\n  quote: T\n  type: TradeProType\n  isChecked?: boolean\n  slippage: number | string\n  __cache__?: {\n    [key: string]: any\n  }\n}\n\nexport type { SwapData }\n\nexport type ModalProps = {\n  open: boolean\n  onClose: {\n    bivarianceHack(event: {}, reason: 'backdropClick' | 'escapeKeyDown'): void\n  }['bivarianceHack']\n  btnDisable?: boolean\n}\n\nexport type ResetProps<T> = ResetExtendProps<T>\nexport type ExportAccountProps = ExportAccountExtendProps\nexport type DepositProps<T, I> = BasicACoinTradeHookProps<T, I> & DepositExtendProps<T>\nexport type WithdrawProps<T, I, C = FeeInfo> = BasicACoinTradeHookProps<T, I> &\n  WithdrawExtendProps<T, I, C>\nexport type TransferProps<T, I, C = FeeInfo> = BasicACoinTradeHookProps<T, I> &\n  TransferExtendProps<T, I, C>\n\nexport type ClaimProps<T, I, C = FeeInfo> = BasicACoinTradeHookProps<T, I> & ClaimExtendProps<T, C>\n\nexport type ResetInfoProps<T, I> = DefaultProps<T, I> & _ResetInfoProps<T>\n\nexport type DepositInfoProps<T, I> = DefaultProps<T, I> & _DepositInfoProps\n\nexport type CreateRedPacketProps<T, I, C = FeeInfo, _NFT = NFTWholeINFO> = Omit<\n  BasicACoinTradeHookProps<T, I>,\n  'type'\n> &\n  CreateRedPacketViewProps<T, I, C>\n\nexport type TransferInfoProps<T, I> = DefaultProps<T, I> & _TransferInfoProps<CoinKey<I>>\n\nexport type SwapInfoProps<T, I, TCD> = SwapTradeBaseProps<T, I, TCD>\n\nexport type NFTDepositProps<T, I> = NFTDepositViewProps<T, I>\n\nexport type NFTMintProps<ME, MI, I, C = FeeInfo> = Omit<NFTMintViewProps<ME, MI, I, C>, 'metaData'>\nexport type NFTMetaProps<T, Co, C = FeeInfo> = Omit<NFTMetaViewProps<T, Co, C>, 'nftMeta'>\n\nexport type NFTMintAdvanceProps<T, Co, I, C = FeeInfo> = NFTMintAdvanceViewProps<T, Co, I, C>\n\nexport type NFTDeployProps<T, I, C = FeeInfo> = NFTDeployViewProps<T, I, C>\nexport type ForceWithdrawProps<T, I, C = FeeInfo> = BasicACoinTradeHookProps<T, I> &\n  ForceWithdrawViewProps<T, I, C>\n\n/**\n *  @type SwapProps\n *  @param swapTradeData: SwapTradeData<T>\n *  @callback handleSwapPanelEvent {\n *      @param type='buy'|'sell'|'exchange'\n *      @param to='menu'|'button' to the view of list for select item\n *      @param SwapData<T>\n *  }\n *  @callback onSwapClick :(\n *      @param SwapData<T>\n *  )  => void {\n *  @param tradeCalcData TradeCalcData<I>\n *  @param swapBtnStatus='disable'|'loading'\n *  @param tokenSellProps i18n done string\n *  @param tokenBuyProps i18n done string\n *  @callback onChangeEvent?: (\n *      @param index=0|1  0：when view on type button, 1: when view on type menu\n *      @param data: SwapData<T>\n *  ) => SwapData<T>\n */\nexport type SwapProps<T, I, TCD> = {\n  refreshRef: React.Ref<any>\n  onRefreshData?: () => void\n  titleI8nKey?: string\n  toPro?: () => void\n  tradeData: SwapTradeData<T>\n  campaignTagConfig?: CAMPAIGNTAGCONFIG\n  handleSwapPanelEvent: (data: SwapData<SwapTradeData<T>>, switchType: SwapType) => Promise<void>\n  market?: MarketType\n  onChangeEvent?: (index: 0 | 1, data: SwapData<SwapTradeData<T>>) => SwapData<SwapTradeData<T>>\n  setToastOpen?: (state: TOASTOPEN) => void\n  scenario?: SCENARIO\n  _width?: string\n  hideSecondConfirmation?: boolean\n  scrollDisabled?: boolean\n  bTradeTutorial?: {\n    show: boolean\n    onToggle: () => void\n    checked: boolean\n  }\n} & SwapInfoProps<T, I, TCD> &\n  SwapTradeBaseEventProps<T, I> &\n  SwapTradeBaseProps<T, I, TCD>\n\nexport type TradeLimitProps<L, T, TCD extends TradeCalcProData<I>, I> = {\n  tradeData: L | undefined\n  handleSubmitEvent: (data: L) => Promise<void>\n  onChangeEvent: (data: L, formType: TradeBaseType) => L\n} & TradeLimitInfoProps<T, TCD, I> &\n  TradeProBaseEventProps<L, T, I>\n\nexport type TradeStopLimitProps<L, T, TCD extends TradeCalcProData<I>, I> = {\n  tradeData: L\n  handleSubmitEvent: (data: L) => Promise<void>\n  onChangeEvent: (data: L, formType: TradeBaseType) => L\n} & StopTradeLimitInfoProps<T, TCD, I> &\n  TradeProBaseEventProps<L, T, I>\n\nexport type TradeMarketProps<\n  M extends MarketTradeData<T>,\n  T extends IBData<I>,\n  TCD extends TradeCalcProData<I>,\n  I = CoinKey<any>,\n> = {\n  tradeData: M | undefined\n  handleSubmitEvent: (data: M) => Promise<void>\n  onChangeEvent: (data: M, formType: TradeBaseType) => M\n} & TradeMarketInfoProps<T, TCD, I> &\n  TradeProBaseEventProps<M, T, I>\n\nexport type SwitchData<T> = {\n  to: 'menu' | 'button'\n  tradeData: T\n}\n\nexport enum SwitchType {\n  TO_MENU = 'Tomenu',\n  TO_BTN = 'Tobutton',\n}\n\nexport enum SwapType {\n  BUY_CLICK = 'buyTomenu',\n  SEll_CLICK = 'sellTomenu',\n  EXCHANGE_CLICK = 'exchange',\n  BUY_SELECTED = 'buyTobutton',\n  SELL_SELECTED = 'sellTobutton',\n}\n\nexport type ModalPanelProps = {\n  open: boolean\n  contentClassName?: string\n  onClose: {\n    bivarianceHack(event: {}, reason: 'backdropClick' | 'escapeKeyDown'): void\n  }['bivarianceHack']\n  content: JSX.Element\n  _height?: number | string\n  _width?: number | string\n}\n\nexport type FeeSelectModalProps = {\n  open: boolean\n  onClose: () => void\n  chargeFeeTokenList: FeeInfo[]\n  feeInfo: FeeInfo | undefined\n  handleToggleChange: (value: FeeInfo) => void\n  disableNoToken?: boolean \n  withdrawInfos?: {\n    types: Partial<WithdrawTypes>\n    type: WithdrawType\n    onChangeType: (w: WithdrawType) => void\n  }\n}\n\nexport type FeeSelectProps = {\n  chargeFeeTokenList: FeeInfo[]\n  handleToggleChange: (value: FeeInfo) => void\n  feeInfo?: FeeInfo\n  disableNoToken?: boolean\n  open: boolean\n  onClose: () => void\n  onClickFee: () => void\n  feeLoading: boolean\n  isFeeNotEnough: boolean\n  isFastWithdrawAmountLimit?: boolean\n  withdrawInfos?: {\n    types: Partial<WithdrawTypes>\n    type: WithdrawType\n    onChangeType: (w: WithdrawType) => void\n  }\n  floatLeft?: boolean\n  middleContent?: JSX.Element\n  feeNotEnoughContent?: JSX.Element\n  networkFeeElement?: JSX.Element\n}\n\nexport type VaultJoinProps<T, I, V> = BasicACoinTradeHookProps<T, I> & VaultJoinBaseProps<T, I, V>\nexport type VaultBorrowProps<T, I, V> = BasicACoinTradeHookProps<T, I> &\n  VaultBorrowBaseProps<T, I, V>\nexport type VaultRepayProps<T, I, V> = BasicACoinTradeHookProps<T, I> & VaultRepayWrapProps<T, I, V>\nexport type VaultExitProps = VaultExitBaseProps\nexport type TransferToTaikoAccountProps = {\n  title: string\n  onClickContact: () => void\n  onClickToken: () => void\n  onClickFee: () => void\n\n  onInputAmount: (str: string) => void\n  onInputAddress: (str: string) => void\n  onClickBalance: () => void\n  onClickBack: () => void\n  onClickClose: () => void\n  fee: string\n  balance: string\n  token: {\n    coinJSON: any\n    symbol: string\n  }\n  feeSelect: FeeSelectProps\n  panel: 'main' | 'contacts' | 'tokenSelection' | 'confirm'\n  contacts: {\n    onSelect: (address: string) => void\n    scrollHeight: string\n  } & Pick<GetContactsResponse, 'contacts'> \n  tokenSelection: {\n    filter: string\n    tokens: {\n      symbol: string\n      coinJSON: any[]\n      amount: string\n    }[]\n    onChangeFilter: (str: string) => void\n    onClickClearFilter: () => void\n    onClickCancel: () => void\n    onClickToken: (symbol: string) => void\n  }\n  receiptInput: string\n  amountInput: string\n  open: boolean\n  supportedTokens: string[]\n  sendBtn: {\n    disabled: boolean,\n    onClick: () => void\n    text?: string   \n  }\n  maxAlert: {\n    show: boolean,\n    message: string,\n  }\n  receiptError: {\n    show: boolean,\n    message: string,\n  }\n  receiptClear: {\n    show: boolean,\n    onClick: () => void,\n  }\n  showReceiptWarning: boolean\n  onClickConfirm: () => void\n  retrySend: () => void\n  hideContactBtn?: boolean\n}\n\nexport * from './components/Interface'\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/ModalPanel.tsx",
    "content": "import { Box, BoxProps, Modal as MuiModal } from '@mui/material'\nimport {\n  AccountStep,\n  ActiveAccountPanel,\n  AnotherNetworkNotice,\n  ClaimProps,\n  CollectionAdvanceProps,\n  DeFiStackRedeemWrap,\n  DeFiStakeRedeemWrapProps,\n  DeployNFTWrap,\n  DepositPanel,\n  DepositProps,\n  ExportAccountPanel,\n  InformationForAccountFrozen,\n  LayerswapNotice,\n  ModalCloseButton,\n  modalContentBaseStyle,\n  ModalPanelProps,\n  NFTDeployProps,\n  RedPacketViewStep,\n  ResetAccountConfirmationPanel,\n  ResetPanel,\n  ResetProps,\n  TransferPanel,\n  TransferProps,\n  useOpenModals,\n  useSettings,\n  WithdrawPanel,\n  WithdrawProps,\n  EditContact,\n  TransferToTaikoAccountModal,\n  TransferToTaikoAccountProps,\n  BridgePanel,\n} from '../..'\nimport {\n  Account,\n  CollectionMeta,\n  FeeInfo,\n  IBData,\n  SendAssetList,\n  TRADE_TYPE,\n  TradeNFT,\n} from '@loopring-web/common-resources'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport { useTheme } from '@emotion/react'\nimport styled from '@emotion/styled'\nimport { CollectionAdvanceWrap } from './components/CollectionAdvanceWrap'\nimport { ClaimWithdrawPanel } from '../modal/ModalPanels/ClaimWithdrawPanel'\nimport { TargetRedpacketWrap } from './components/TargetRedpacketWrap'\nimport { TransferNFTBurn } from './components'\n\nconst BoxStyle = styled(Box)<{ _height?: number | string; _width?: number | string } & BoxProps>`\n  display: flex;\n  align-items: center;\n  flex-direction: column;\n  justify-content: center;\n  ${({ theme }) => modalContentBaseStyle({ theme: theme })}\n  background: var(--color-pop-bg);\n\n  .trade-wrap {\n    margin-top: -26px;\n  }\n  > .vault-wrap {\n    .vaultSwap {\n      .MuiToolbar-root {\n        > .MuiTypography-root:first-of-type {\n          align-self: flex-end;\n          font-size: ${({ theme }) => theme.fontDefault.h5};\n          padding: 0 ${({ theme }) => 3 * theme.unit}px;\n          margin-bottom: ${({ theme }) => 1.5 * theme.unit}px;\n        }\n        > .toolButton {\n          height: 100%;\n          align-items: center;\n        }\n        .MuiTypography-root {\n          height: auto;\n        }\n        margin-bottom: ${({ theme }) => 2 * theme.unit}px;\n        border-bottom: var(--color-divide) 1px solid;\n        .record {\n          visibility: hidden;\n        }\n      }\n    }\n    margin-top: -32px;\n    .MuiToolbar-root {\n      height: 48px;\n      padding: 0;\n    }\n    .toolbarTitle {\n      position: absolute;\n      top: 0;\n      left: 0;\n      right: 0;\n      bottom: 0;\n      display: flex;\n      flex-direction: column;\n      justify-content: flex-end;\n    }\n  }\n\n  > .vault-wrap {\n    .vaultSwap {\n      .MuiToolbar-root {\n        > .MuiTypography-root:first-of-type {\n          align-self: flex-end;\n          font-size: ${({ theme }) => theme.fontDefault.h5};\n          padding: 0 ${({ theme }) => 3 * theme.unit}px;\n          margin-bottom: ${({ theme }) => 1.5 * theme.unit}px;\n        }\n\n        > .toolButton {\n          height: 100%;\n          align-items: center;\n        }\n\n        .MuiTypography-root {\n          height: auto;\n        }\n\n        margin-bottom: ${({ theme }) => 2 * theme.unit}px;\n        border-bottom: var(--color-divide) 1px solid;\n\n        .record {\n          visibility: hidden;\n        }\n      }\n    }\n\n    margin-top: -32px;\n\n    .MuiToolbar-root {\n      height: 48px;\n      padding: 0;\n    }\n\n    .toolbarTitle {\n      position: absolute;\n      top: 0;\n      left: 0;\n      right: 0;\n      bottom: 0;\n      display: flex;\n      flex-direction: column;\n      justify-content: flex-end;\n    }\n  }\n\n  .trade-panel {\n    position: relative;\n    height: ${({ _height }) =>\n      _height && Number.isNaN(_height) ? _height + 'px' : _height ? _height : 'auto'};\n\n    &.valut-load {\n      padding: 0;\n      border: 0;\n\n      .react-swipeable-view-container {\n        & > div {\n          padding: 0 ${({ theme }) => (theme.unit * 5) / 2}px 0px;\n        }\n      }\n    }\n\n    .react-swipeable-view-container {\n      & > div {\n        padding: 0 ${({ theme }) => (theme.unit * 5) / 2}px ${({ theme }) => theme.unit * 5}px;\n        overflow-x: hidden;\n        overflow-y: scroll !important;\n        background: initial;\n        scrollbar-width: none; /* Firefox */\n        -ms-overflow-style: none; /* Internet Explorer 10+ */\n\n        &::-webkit-scrollbar {\n          /* WebKit */\n          width: 0;\n        }\n\n        .container {\n          height: 100%;\n          padding-top: 0;\n        }\n      }\n    }\n  }\n` as (props: { _height?: number | string; _width?: number | string } & BoxProps) => JSX.Element\n\nexport const Modal = withTranslation('common')(\n  ({\n    open,\n    onClose,\n    content,\n    _height,\n    contentClassName,\n    _width,\n    ...rest\n  }: ModalPanelProps & WithTranslation) => {\n    const { isMobile } = useSettings()\n    return (\n      <MuiModal\n        open={open}\n        onClose={onClose}\n        aria-labelledby='modal-modal-title'\n        aria-describedby='modal-modal-description'\n      >\n        <BoxStyle\n          style={{ boxShadow: '24' }}\n          {...{\n            _width: _width ?? `var(--modal-width)`,\n            _height: _height,\n          }}\n        >\n          <Box display={'flex'} width={'100%'} flexDirection={'column'}>\n            <ModalCloseButton onClose={onClose} {...rest} />\n          </Box>\n          <Box\n            className={contentClassName}\n            maxWidth={isMobile ? 'var(--modal-min-width)' : 'inherit'}\n          >\n            {content}\n          </Box>\n        </BoxStyle>\n      </MuiModal>\n    )\n  },\n)\n\nexport const ModalPanel = <\n  T extends IBData<I>,\n  N extends IBData<I> & TradeNFT<I, any>,\n  C extends CollectionMeta,\n  I,\n  F = FeeInfo,\n>({\n  transferProps,\n  withdrawProps,\n  depositProps,\n  nftTransferProps,\n  nftWithdrawProps,\n  nftDeployProps,\n  resetProps,\n  claimProps,\n  nftBurnProps,\n  activeAccountProps,\n  collectionAdvanceProps,\n  sideStackRedeemProps,\n  contactAddProps,\n  assetsData,\n  account,\n  baseURL,\n  transferToTaikoProps,\n  ...rest\n}: {\n  _width?: number | string\n  _height?: number | string\n  nftBurnProps: TransferProps<T, I>\n  contactAddProps: any\n  transferProps: TransferProps<T, I>\n  withdrawProps: WithdrawProps<T, I>\n  baseURL: string\n  nftTransferProps: TransferProps<N, I>\n  claimProps: ClaimProps<T, I>\n  nftWithdrawProps: WithdrawProps<N, I>\n  nftDeployProps: NFTDeployProps<N & { broker: string }, I, F>\n  depositProps: DepositProps<T, I>\n  sideStackRedeemProps: DeFiStakeRedeemWrapProps<T, I, any>\n\n  collectionAdvanceProps: CollectionAdvanceProps<C>\n\n  resetProps: ResetProps<F>\n  activeAccountProps: ResetProps<F>\n  assetsData: any[]\n  exportAccountProps: any\n  account: Account\n  setExportAccountToastOpen: any\n  transferToTaikoProps: TransferToTaikoAccountProps\n}) => {\n  const { isMobile } = useSettings()\n  const {\n    modals,\n    setShowTransfer,\n    setShowDeposit,\n    setShowWithdraw,\n    setShowResetAccount,\n    setShowActiveAccount,\n    setShowExportAccount,\n    setShowNFTTransfer,\n    setShowNFTWithdraw,\n    setShowNFTDeploy,\n    setShowAccount,\n    setShowClaimWithdraw,\n    setShowCollectionAdvance,\n    setShowSideStakingRedeem,\n    setShowTargetRedpacketPop,\n    setShowRedPacket,\n    setShowEditContact,\n    setShowTransferToTaikoAccount,\n    setShowBridge,\n  } = useOpenModals()\n\n  const {\n    isShowTransfer,\n    isShowWithdraw,\n    isShowDeposit,\n    isShowNFTTransfer,\n    isShowNFTWithdraw,\n    isShowNFTDeploy,\n    isShowResetAccount,\n    isShowExportAccount,\n    isShowTradeIsFrozen,\n    isShowActiveAccount,\n    isShowCollectionAdvance,\n    isShowLayerSwapNotice,\n    isShowAnotherNetwork,\n    isShowClaimWithdraw,\n    isShowSideStakingRedeem,\n    isShowTargetRedpacketPop,\n    isShowEditContact,\n    isShowBridge,\n  } = modals\n  const theme = useTheme()\n  \n  const etherscanBaseUrl = 'https://etherscan.io/'\n  return (\n    <>\n      <Modal\n        open={isShowClaimWithdraw.isShow}\n        contentClassName={'trade-wrap'}\n        onClose={() => setShowClaimWithdraw({ isShow: false, claimToken: undefined as any })}\n        content={\n          <ClaimWithdrawPanel\n            {...{\n              ...rest,\n              ...claimProps,\n              assetsData,\n              // _width: `calc(var(--modal-width) - ${(theme.unit * 5) / 2}px)`,\n              // //    _height: DEFAULT_TRANSFER_HEIGHT + 100, ...transferProps, assetsData,\n              // _height: \"auto\",\n            }}\n          />\n        }\n      />\n      <Modal\n        open={isShowTransfer.isShow}\n        contentClassName={'trade-wrap'}\n        onClose={() => {\n          isShowTransfer.info?.onCloseCallBack && isShowTransfer.info?.onCloseCallBack()\n          setShowTransfer({ isShow: false })\n        }}\n        content={\n          <TransferPanel<any, any>\n            {...{\n              ...rest,\n              _width: `calc(var(--modal-width) - ${(theme.unit * 5) / 2}px)`,\n              //    _height: DEFAULT_TRANSFER_HEIGHT + 100, ...transferProps, assetsData,\n              _height: 'auto',\n              ...transferProps,\n              assetsData,\n            }}\n          />\n        }\n      />\n      <TransferToTaikoAccountModal\n        {...transferToTaikoProps}\n      />\n\n      <Modal\n        open={isShowWithdraw.isShow}\n        contentClassName={'trade-wrap'}\n        onClose={() => {\n          isShowWithdraw.info?.onCloseCallBack && isShowWithdraw.info?.onCloseCallBack()\n          setShowWithdraw({ isShow: false })\n        }}\n        content={\n          <WithdrawPanel<any, any>\n            {...{\n              ...rest,\n              _width: `calc(var(--modal-width) - ${(theme.unit * 5) / 2}px)`,\n              _height: isMobile\n                ? 'auto'\n                : 480 + (withdrawProps.withdrawMode?.showTrustUI ? 100 : 0) + (withdrawProps.isToMyself ? 0 : 100),\n              ...withdrawProps,\n              assetsData,\n              isFromContact: isShowWithdraw.address ? true : false,\n              contact: isShowWithdraw.address\n                ? {\n                    address: isShowWithdraw.address!,\n                    name: isShowWithdraw.name!,\n                  }\n                : undefined,\n            }}\n          />\n        }\n      />\n\n      <Modal\n        open={isShowNFTTransfer.isShow && !isShowNFTTransfer.info?.isBurn}\n        contentClassName={'trade-wrap'}\n        onClose={() => setShowNFTTransfer({ isShow: false })}\n        content={\n          <TransferPanel\n            {...{\n              ...nftTransferProps,\n              _width: isMobile ? 'var(--mobile-full-panel-width)' : 440,\n              _height: isMobile ? 'auto' : 600,\n              isThumb: false,\n              type: TRADE_TYPE.NFT,\n              baseURL,\n              assetsData,\n            }}\n            onBack={() => {\n              setShowNFTTransfer({ isShow: false })\n              setShowAccount({\n                isShow: true,\n                step: AccountStep.SendNFTGateway,\n              })\n            }}\n          />\n        }\n      />\n      <Modal\n        open={isShowNFTWithdraw.isShow}\n        contentClassName={'trade-wrap'}\n        onClose={() => setShowNFTWithdraw({ isShow: false })}\n        content={\n          <WithdrawPanel\n            {...{\n              // _width: isMobile ? \"var(--mobile-full-panel-width)\" : 440,\n              _width: `calc(var(--modal-width) - ${(theme.unit * 5) / 2}px)`,\n              //    _height: DEFAULT_TRANSFER_HEIGHT + 100, ...transferProps, assetsData,\n              _height: isMobile ? 'auto' : 500,\n              isThumb: false,\n              ...nftWithdrawProps,\n              type: TRADE_TYPE.NFT,\n              baseURL,\n              assetsData,\n              isFromContact: isShowNFTWithdraw.address ? true : false,\n              contact: isShowNFTWithdraw.address\n                ? {\n                    address: isShowNFTWithdraw.address!,\n                    name: isShowNFTWithdraw.name!,\n                  }\n                : undefined,\n            }}\n            onBack={() => {\n              setShowNFTWithdraw({ isShow: false })\n              setShowAccount({\n                isShow: true,\n                step: AccountStep.SendNFTGateway,\n              })\n            }}\n          />\n        }\n      />\n      <Modal\n        open={isShowNFTDeploy.isShow}\n        contentClassName={'trade-wrap'}\n        onClose={() => setShowNFTDeploy({ isShow: false })}\n        content={\n          <DeployNFTWrap<any, any, any>\n            {...{\n              ...nftDeployProps,\n              assetsData,\n            }}\n          />\n        }\n      />\n      <Modal\n        open={isShowDeposit.isShow}\n        contentClassName={'trade-wrap'}\n        onClose={() => setShowDeposit({ isShow: false })}\n        content={\n          <DepositPanel\n            {...{\n              ...rest,\n              _width: `calc(var(--modal-width) - ${(theme.unit * 5) / 2}px)`,\n              _height: 'auto',\n              ...depositProps,\n            }}\n          />\n        }\n      />\n      <Modal\n        open={isShowNFTTransfer.isShow && isShowNFTTransfer.info?.isBurn}\n        contentClassName={'trade-wrap'}\n        onClose={() => setShowNFTTransfer({ isShow: false })}\n        content={\n          <Box width={`var(--modal-width)`} marginBottom={5 / 2}>\n            <TransferNFTBurn\n              {...{\n                ...rest,\n                ...(nftBurnProps as any),\n              }}\n            />\n          </Box>\n        }\n      />\n      <Modal\n        open={isShowResetAccount.isShow}\n        onClose={() => setShowResetAccount({ ...isShowResetAccount, isShow: false })}\n        content={\n          isShowResetAccount.info?.confirmationType ? (\n            <ResetAccountConfirmationPanel\n              onConfirmation={() =>\n                setShowResetAccount({\n                  ...isShowResetAccount,\n                  info: { ...isShowResetAccount.info, confirmationType: undefined },\n                })\n              }\n              type={isShowResetAccount?.info?.confirmationType}\n            />\n          ) : (\n            <ResetPanel<any, any>\n              {...{\n                ...rest,\n                _width: `calc(var(--modal-width) - ${(theme.unit * 5) / 2}px)`,\n                _height: `auto`,\n                ...resetProps,\n                assetsData,\n              }}\n            />\n          )\n        }\n      />\n      <Modal\n        open={isShowActiveAccount.isShow}\n        onClose={() => setShowActiveAccount({ ...isShowActiveAccount, isShow: false })}\n        content={\n          isShowActiveAccount?.info?.confirmationType ? (\n            <ResetAccountConfirmationPanel\n              onConfirmation={() =>\n                setShowActiveAccount({\n                  ...isShowActiveAccount,\n                  info: { ...isShowActiveAccount.info, confirmationType: undefined },\n                })\n              }\n              type={isShowActiveAccount?.info?.confirmationType}\n            />\n          ) : (\n            <ActiveAccountPanel<any, any>\n              {...{\n                ...rest,\n                _width: `calc(var(--modal-width) - ${(theme.unit * 5) / 2}px)`,\n                _height: `auto`,\n                ...activeAccountProps,\n              }}\n            />\n          )\n        }\n      />\n      <Modal\n        open={isShowExportAccount.isShow}\n        onClose={() => setShowExportAccount({ ...isShowExportAccount, isShow: false })}\n        content={\n          <ExportAccountPanel\n            {...{\n              ...rest,\n              _width: `calc(var(--modal-width) - ${(theme.unit * 5) / 2}px)`,\n              _height: `calc(var(--modal-height) + ${theme.unit * 16}px)`,\n            }}\n          />\n        }\n      />\n      <Modal\n        open={isShowExportAccount.isShow}\n        onClose={() => setShowExportAccount({ ...isShowExportAccount, isShow: false })}\n        content={\n          <ExportAccountPanel\n            {...{\n              ...rest,\n              _width: `calc(var(--modal-width) - ${(theme.unit * 5) / 2}px)`,\n              _height: `calc(var(--modal-height) + ${theme.unit * 16}px)`,\n            }}\n          />\n        }\n      />\n      <InformationForAccountFrozen\n        open={isShowTradeIsFrozen.isShow}\n        type={isShowTradeIsFrozen.type ?? 'Action'}\n        messageKey={isShowTradeIsFrozen.messageKey ?? 'labelNoticeForForAccountFrozen'}\n      />\n      <LayerswapNotice open={isShowLayerSwapNotice.isShow} account={account} />\n      <AnotherNetworkNotice open={isShowAnotherNetwork.isShow} account={account} />\n      <Modal\n        open={isShowCollectionAdvance?.isShow}\n        onClose={() => setShowCollectionAdvance({ isShow: false })}\n        content={\n          <CollectionAdvanceWrap\n            {...{\n              ...rest,\n              // _width: `calc(var(--modal-width) - ${(theme.unit * 5) / 2}px)`,\n              // _height: `calc(var(--modal-height) - ${theme.unit * 6}px)`,\n              ...collectionAdvanceProps,\n            }}\n          />\n        }\n      />\n      <Modal\n        open={isShowSideStakingRedeem.isShow}\n        contentClassName={'trade-wrap hasLinerBg'}\n        onClose={() => setShowSideStakingRedeem({ isShow: false })}\n        content={\n          <Box\n            maxWidth='var(--modal-width)'\n            flex={1}\n            display={'flex'}\n            paddingX={5 / 2}\n            paddingBottom={5 / 2}\n          >\n            <DeFiStackRedeemWrap isJoin={false} {...(sideStackRedeemProps as any)} />\n          </Box>\n        }\n      />\n      <Modal\n        // maxWidth={'md'}\n        open={isShowTargetRedpacketPop.isShow}\n        onClose={() => {\n          setShowTargetRedpacketPop({ isShow: false, info: {} })\n        }}\n        content={\n          <TargetRedpacketWrap\n            exclusiveRedPackets={isShowTargetRedpacketPop.info.exclusiveRedPackets}\n            onClickOpenExclusive={(redpacket) => {\n              setShowTargetRedpacketPop({ isShow: false, info: {} })\n              setShowRedPacket({\n                isShow: true,\n                info: {\n                  ...redpacket,\n                },\n                step: RedPacketViewStep.OpenPanel,\n              })\n            }}\n          />\n        }\n      />\n      <Modal\n        // maxWidth={'md'}\n        open={isShowEditContact.isShow}\n        onClose={() => {\n          setShowEditContact({ isShow: false, info: {} })\n        }}\n        content={\n          <EditContact\n            {...{\n              ...contactAddProps,\n            }}\n            onBack={\n              isShowEditContact?.info?.from === AccountStep.SendAssetFromContact\n                ? () => {\n                    setShowAccount({\n                      isShow: true,\n                      step: AccountStep.SendAssetFromContact,\n                      info: {\n                        ...contactAddProps?.isEdit?.item,\n                        select: SendAssetList.SendAssetToOtherL1.key,\n                      },\n                    })\n                    setShowEditContact({ isShow: false, info: {} })\n                  }\n                : undefined\n            }\n            // contacts={isShowAccount.info?.contacts}\n            // setToast={setToast}\n          />\n        }\n      />\n      <Modal\n        open={isShowBridge.isShow}\n        contentClassName={'trade-wrap'}\n        onClose={() => {\n          setShowBridge({ \n            isShow: false\n          })\n        }}\n        content={\n          <BridgePanel\n            {...{\n              ...rest,\n              _width: `calc(var(--modal-width) - ${(theme.unit * 5) / 2}px)`,\n              _height: 'auto',\n              symbol: isShowBridge.symbol,\n              etherscanBaseUrl,\n              onClickEthereum: () => {\n                setShowBridge({\n                  isShow: false\n                })\n                setShowTransferToTaikoAccount({\n                  isShow: true,\n                  from: 'bridge'\n                })\n              }\n            }}\n          />\n        }\n      />\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/Panel.stories.tsx",
    "content": "import styled from '@emotion/styled'\nimport { SwapPanel } from './Swap'\nimport { Meta, Story } from '@storybook/react'\nimport { MemoryRouter } from 'react-router-dom'\nimport { Box, Grid } from '@mui/material'\nimport {\n  AccountStatus,\n  AmmExitData,\n  AmmInData,\n  AmmJoinData,\n  IBData,\n  SlippageTolerance,\n  TRADE_TYPE,\n  TradeBtnStatus,\n  AmmPanelType,\n} from '@loopring-web/common-resources'\nimport {\n  ammCalcData,\n  coinMap,\n  CoinType,\n  DUALCALCDATA,\n  TOKEN_INFO,\n  tradeCalcData,\n  walletMap,\n} from '../../static'\nimport { Button } from '../basic-lib'\nimport { ResetPanel } from './Reset'\nimport { useTranslation } from 'react-i18next'\nimport {\n  AmmPanel,\n  AmmProps,\n  DepositProps,\n  DualWrap,\n  DualWrapProps,\n  ResetProps,\n  SwapProps,\n  SwapTradeData,\n  SwitchData,\n  TransferProps,\n  WithdrawProps,\n} from './index'\n\nimport { DepositPanel, TransferPanel, WithdrawPanel } from '../modal'\n\nimport { useDispatch } from 'react-redux'\nimport {\n  setShowAmm,\n  setShowDeposit,\n  setShowResetAccount,\n  setShowSwap,\n  setShowTransfer,\n  setShowWithdraw,\n} from '../../stores'\nimport { SlippagePanel } from './components'\nimport React from 'react'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { boxLiner } from '../styled'\n\nconst Style = styled.div`\n  background: var(--color-global-bg);\n\n  height: 100%;\n  flex: 1;\n`\nconst BoxLinear = styled(Box)`\n  && {\n    ${({ theme }) => boxLiner({ theme })};\n  }\n`\nlet tradeData: any = {}\n// @ts-ignore\nlet depositProps: DepositProps<any, any> = {\n  toIsAddressCheckLoading: false,\n  referIsLoopringAddress: false,\n  referIsAddressCheckLoading: false,\n  type: TRADE_TYPE.NFT,\n  isNewAccount: false,\n  tradeData,\n  coinMap,\n  walletMap,\n  depositBtnStatus: TradeBtnStatus.AVAILABLE,\n  onDepositClick: (tradeData: SwapTradeData<CoinType>) => {\n    console.log('Swap button click', tradeData)\n  },\n  handlePanelEvent: async (props: SwitchData<any>, switchType: 'Tomenu' | 'Tobutton') => {\n    return new Promise(() => {\n      setTimeout(() => {\n        console.log('wait 100, with props', props, switchType)\n        //res();\n      }, 500)\n    })\n  },\n}\nlet withdrawProps: Partial<WithdrawProps<any, any>> = {\n  disabled: false,\n  type: TRADE_TYPE.TOKEN,\n  isContractAddress: false,\n  isFeeNotEnough: {\n    isFeeNotEnough: false,\n    isOnLoading: false,\n  },\n  isAddressCheckLoading: false,\n  isCFAddress: false,\n  tradeData,\n  coinMap,\n  walletMap,\n  withdrawBtnStatus: TradeBtnStatus.AVAILABLE,\n\n  onWithdrawClick: (tradeData: SwapTradeData<CoinType>) => {\n    console.log('Swap button click', tradeData)\n  },\n  handlePanelEvent: async (props: SwitchData<any>, switchType: 'Tomenu' | 'Tobutton') => {\n    return new Promise((res: any) => {\n      setTimeout(() => {\n        console.log('wait 100, with props', props, switchType)\n        res()\n      }, 500)\n    })\n  },\n  withdrawType: sdk.OffchainFeeReqType.OFFCHAIN_WITHDRAWAL,\n  withdrawTypes: {\n    // [sdk.OffchainFeeReqType.FAST_OFFCHAIN_WITHDRAWAL]: \"Fast\",\n    [sdk.OffchainFeeReqType.OFFCHAIN_WITHDRAWAL]: 'Standard',\n  },\n  feeInfo: { belong: 'ETH', fee: 0.001, __raw__: '' as any },\n  // @ts-ignore\n  chargeFeeTokenList: [\n    { belong: 'ETH', fee: 0.001, __raw__: '' as any },\n    { belong: 'LRC', fee: '1', __raw__: '' as any },\n  ],\n  handleOnAddressChange: (value: any) => {\n    console.log('handleOnAddressChange', value)\n  },\n  handleFeeChange(value: { belong: string; fee: number | string; __raw__?: any }): void {\n    console.log('handleWithdrawFee', value)\n  },\n  handleWithdrawTypeChange: (value: any) => {\n    console.log(value)\n  },\n}\nlet transferProps: Partial<TransferProps<any, any>> = {\n  isFeeNotEnough: {\n    isFeeNotEnough: false,\n    isOnLoading: false,\n  },\n  tradeData,\n  coinMap,\n  walletMap,\n  transferBtnStatus: TradeBtnStatus.AVAILABLE,\n  onTransferClick: async (tradeData: any) => {\n    console.log('Swap button click', tradeData)\n  },\n  handlePanelEvent: async (props: SwitchData<any>, switchType: 'Tomenu' | 'Tobutton') => {\n    return new Promise((res: any) => {\n      setTimeout(() => {\n        console.log('wait 100, with props', props, switchType)\n        res()\n      }, 500)\n    })\n  },\n  handleFeeChange(value: { belong: string; fee: number | string; __raw__?: any }): void {\n    console.log('handleWithdrawFee', value)\n  },\n  feeInfo: { belong: 'ETH', fee: 0.001, __raw__: '' as any },\n  // @ts-ignore\n  chargeFeeTokenList: [\n    { belong: 'ETH', fee: 0.001, __raw__: '' as any },\n    { belong: 'LRC', fee: '1', __raw__: '' as any },\n  ],\n  handleOnAddressChange: (value: any) => {\n    console.log('handleOnAddressChange', value)\n  },\n}\nlet resetProps: ResetProps<any> = {\n  isFeeNotEnough: {\n    isFeeNotEnough: false,\n    isOnLoading: false,\n  },\n  chargeFeeTokenList: [\n    { belong: 'ETH', fee: 0.001, __raw__: '' as any },\n    { belong: 'LRC', fee: '1', __raw__: '' as any },\n  ],\n  feeInfo: { belong: 'ETH', fee: 0.001, __raw__: '' as any },\n  handleFeeChange(value: { belong: string; fee: number | string; __raw__?: any }): void {\n    console.log('handleWithdrawFee', value)\n  },\n  onResetClick({}): void {},\n}\n// resetBtnStatus: TradeBtnStatus.AVAILABLE,\n//   handlePanelEvent: async (\n//     props: SwitchData<any>,\n//     switchType: \"Tomenu\" | \"Tobutton\"\n//   ) => {\n//     return new Promise((res: any) => {\n//       setTimeout(() => {\n//         console.log(\"wait 100, with props\", props, switchType);\n//         res();\n//       }, 500);\n//     });\n//   },\n//   fee: { count: 234, price: 123 },\n// let swapProps: SwapProps<IBData<string>, string, any> = {\n//   refreshRef: React.createRef(),\n//   tradeData: {\n//     sell: { belong: undefined },\n//     buy: { belong: undefined },\n//     slippage: \"\",\n//   } as any,\n//   tradeCalcData,\n//   onSwapClick: (tradeData) => {\n//     console.log(\"Swap button click\", tradeData);\n//   },\n//   handleSwapPanelEvent: async (data: any, switchType: any) => {\n//     console.log(data, switchType);\n//   },\n// };\n// @ts-ignore\nlet _ammProps: AmmProps<AmmJoinData<IBData<any>>, AmmExitData<IBData<any>>, any, AmmInData<any>> = {\n  refreshRef: React.createRef(),\n  // @ts-ignore\n  ammDepositData: {\n    coinA: { belong: 'ETH', balance: 0.3, tradeValue: 0 },\n    coinB: { belong: 'LRC', balance: 1000, tradeValue: 0 },\n    slippage: '',\n  },\n  // @ts-ignore\n  ammWithdrawData: {\n    coinLP: { belong: 'LP-ETH-LRC', balance: 0.3, tradeValue: 0 },\n    slippage: '',\n  },\n  // tradeCalcData,\n  ammCalcDataDeposit: ammCalcData,\n  ammCalcDataWithDraw: ammCalcData,\n  handleAmmAddChangeEvent: (data, type) => {\n    console.log('handleAmmAddChangeEvent', data, type)\n  },\n  handleAmmRemoveChangeEvent: (data) => {\n    return console.log('handleAmmRemoveChangeEvent', data)\n  },\n  onAmmRemoveClick: (data) => {\n    console.log('onAmmRemoveClick', data)\n  },\n  onAmmAddClick: (data) => {\n    console.log('onAmmAddClick', data)\n  },\n}\n\nconst WrapTransferPanel = (rest: any) => {\n  const dispatch = useDispatch()\n  dispatch(setShowTransfer({ isShow: false }))\n  return (\n    <>\n      <Grid item sm={6}>\n        <TransferPanel {...{ ...rest, ...transferProps }} />\n      </Grid>\n      <Grid item sm={6}>\n        <TransferPanel {...rest} />\n      </Grid>\n    </>\n  )\n}\nconst WrapWithdrawPanel = (rest: any) => {\n  const dispatch = useDispatch()\n  dispatch(setShowDeposit({ isShow: false }))\n\n  return (\n    <>\n      <Grid item sm={6}>\n        <WithdrawPanel {...withdrawProps} {...rest} />\n      </Grid>\n      <Grid item sm={6}>\n        <WithdrawPanel {...rest}> </WithdrawPanel>\n      </Grid>\n    </>\n  )\n}\nconst WrapDepositPanel = (rest: any) => {\n  // const [open, setOpen] = useState(false)\n  const dispatch = useDispatch()\n  dispatch(setShowDeposit({ isShow: false }))\n  const { t } = useTranslation('common')\n  return (\n    <>\n      <Grid item sm={6}>\n        <DepositPanel {...{ ...rest, ...depositProps }} />\n      </Grid>\n      <Grid item sm={6}>\n        <DepositPanel\n          {...{\n            ...rest,\n            ...depositProps,\n\n            title: t('labelDepositTitleAndActive'),\n            description: 'labelDepositAndActiveDescription',\n          }}\n        />\n      </Grid>\n      <Grid item sm={12}>\n        {/*<Button onClick={() => setOpen(true)}> open</Button>*/}\n      </Grid>\n    </>\n  )\n}\nconst WrapResetPanel = (rest: any) => {\n  const dispatch = useDispatch()\n  dispatch(setShowResetAccount({ isShow: false }))\n  return (\n    <>\n      <Grid item sm={6}>\n        <ResetPanel {...resetProps} {...rest} />\n      </Grid>\n      <Grid item sm={6}>\n        <ResetPanel {...rest}> </ResetPanel>\n      </Grid>\n      <Grid item sm={12} />\n    </>\n  )\n}\nconst WrapSwapPanel = (rest: any) => {\n  let tradeData: any = {\n    sell: { belong: undefined },\n    buy: { belong: undefined },\n  }\n  let swapProps: SwapProps<IBData<string>, string, any> = {\n    refreshRef: React.createRef(),\n    campaignTagConfig: {\n      SWAP: [],\n      ORDERBOOK: [],\n      MARKET: [],\n      AMM: [],\n      FIAT: [],\n    } as any,\n    tradeData: tradeData,\n    isStob: true,\n    tradeCalcData,\n    onSwapClick: () => {\n      console.log('Swap button click', tradeData)\n    },\n    handleSwapPanelEvent: async (data: any, switchType: any) => {\n      console.log(data, switchType)\n    },\n  }\n\n  setTimeout(() => {\n    // console.log('swapProps update')\n    // swapProps.swapTradeData = {sell: {belong: \"ETH\"}, buy: {belong: \"LRC\"}} as any;\n  }, 500)\n  setTimeout(() => {\n    swapProps.tradeCalcData = { ...tradeCalcData, StoB: 1.123 }\n  }, 800)\n\n  return (\n    <>\n      <Grid item sm={6}>\n        <SwapPanel {...swapProps} {...rest} />\n      </Grid>\n    </>\n  )\n}\nconst WrapDualPanel = (rest: any) => {\n  const dualWrapProps: DualWrapProps<any, any, any> = {\n    refreshRef: React.createRef(),\n    disabled: false,\n    btnInfo: undefined,\n    tokenMap: TOKEN_INFO.tokenMap as any,\n    isLoading: false,\n    onRefreshData: () => undefined,\n    onSubmitClick: () => undefined,\n    onChangeEvent: (item) => {\n      console.log(item)\n    },\n\n    dualCalcData: DUALCALCDATA,\n    tokenSell: TOKEN_INFO.tokenMap['LRC'],\n    btnStatus: TradeBtnStatus.AVAILABLE,\n    accStatus: AccountStatus.ACTIVATED,\n  }\n  return (\n    <>\n      <BoxLinear width={'80%'} padding={3} sx={{ background: 'var(--color-box-linear)' }}>\n        <DualWrap {...dualWrapProps} {...rest} />\n      </BoxLinear>\n    </>\n  )\n}\nconst WrapAmmPanel = (rest: any) => {\n  // let tradeData: any = {\n  //     coinA: {belong: 'ETH', balance: 0.3, tradeValue: 0},\n  //     coinB: {belong: 'LRC', balance: 1000, tradeValue: 0}\n  // };\n  let ammProps: AmmProps<AmmJoinData<IBData<any>>, any, AmmInData<any>, any> = {\n    ..._ammProps,\n    // refreshRef: React.createRef(),\n    // ammDepositData: tradeData,\n    // AmmExitData: {coinLP:{belong: 'ETH', balance: 0.3, tradeValue: 0}},\n    // // tradeCalcData,\n    // ammCalcDataDeposit: ammCalcData,\n    // ammCalcDataWithDraw: ammCalcData,\n    // handleAmmAddChangeEvent: (data, type) => {\n    //     console.log('handleAmmAddChangeEvent', data, type);\n    // },\n    // handleAmmRemoveChangeEvent: (data, type) => {\n    //     console.log('handleAmmRemoveChangeEvent', data, type);\n    // },\n    // onAmmRemoveClick: (data) => {\n    //     console.log('onAmmRemoveClick', data);\n    // },\n    // onAmmAddClick: (data) => {\n    //     console.log('onAmmAddClick', data);\n    // }\n  }\n\n  return (\n    <>\n      <Grid item sm={6}>\n        <AmmPanel {...{ ...ammProps, tabSelected: AmmPanelType.Join }} {...rest} />\n      </Grid>\n      <Grid item sm={6}>\n        <AmmPanel\n          {...{\n            ...ammProps,\n            tabSelected: AmmPanelType.Join,\n            ammDepositBtnStatus: TradeBtnStatus.LOADING,\n          }}\n          {...rest}\n        />\n      </Grid>\n      <Grid item sm={6}>\n        <AmmPanel {...{ ...ammProps, tabSelected: AmmPanelType.Exit }} {...rest} />\n      </Grid>\n      <Grid item sm={6}>\n        <AmmPanel\n          {...{\n            ...ammProps,\n            tabSelected: AmmPanelType.Exit,\n            ammWithdrawBtnStatus: TradeBtnStatus.DISABLED,\n          }}\n          {...rest}\n        />\n      </Grid>\n    </>\n  )\n}\n\nconst ModalPanelWrap = () => {\n  return (\n    <></>\n    // <ModalPanel\n    //   depositProps={depositProps as DepositProps<any, any>}\n    //   transferProps={transferProps as TransferProps<any, any>}\n    //   withdrawProps={withdrawProps as WithdrawProps<any, any>}\n    //   nftTransferProps={transferProps as TransferProps<any, any>}\n    //   nftWithdrawProps={withdrawProps as WithdrawProps<any, any>}\n    //   resetProps={resetProps}\n    //   assetsData={{} as any}\n    //   exportAccountProps={{} as any}\n    //   setExportAccountToastOpen={{} as any}\n    //   activeAccountProps={{} as any}\n    //   // nftMintAdvanceProps={{} as any}\n    //   nftDeployProps={{} as any}\n    //   account={{} as any}\n    //   baseURL={\"\"}\n    //   collectionAdvanceProps={{} as any}\n    //   dualTradeProps={{} as any}\n    // />\n  )\n}\n\nconst Template: Story<any> = () => {\n  const dispatch = useDispatch()\n  const { t, ...rest } = useTranslation()\n  const slippageArray: Array<number | string> = SlippageTolerance.concat(`slippage:0.8`) as Array<\n    number | string\n  >\n  return (\n    <Style>\n      <MemoryRouter initialEntries={['/']}>\n        <Box>\n          <h4>Slippage bloc</h4>\n          <Grid container spacing={2}>\n            <SlippagePanel\n              {...{\n                ...rest,\n                t,\n                handleChange: () => {},\n                slippageList: slippageArray,\n                slippage: 0.5,\n              }}\n            />\n          </Grid>\n\n          <h4>SwapPanel</h4>\n          <Grid container spacing={2} alignContent={'center'} justifyContent={'space-around'}>\n            <WrapSwapPanel />\n          </Grid>\n          <h4>DualPanel</h4>\n          <Grid container spacing={2} alignContent={'center'} justifyContent={'space-around'}>\n            <WrapDualPanel />\n          </Grid>\n\n          <h4>DepositPanel</h4>\n          <Grid container spacing={2} alignContent={'center'} justifyContent={'space-around'}>\n            <WrapDepositPanel />\n          </Grid>\n          <h4>ResetPanel</h4>\n          <Grid container spacing={2} alignContent={'center'} justifyContent={'space-around'}>\n            <WrapResetPanel />\n          </Grid>\n          <h4>TransferPanel</h4>\n          <Grid container spacing={2} alignContent={'center'} justifyContent={'space-around'}>\n            <WrapTransferPanel />\n          </Grid>\n          <h4>WithdrawPanel</h4>\n          <Grid container spacing={2} alignContent={'center'} justifyContent={'space-around'}>\n            <WrapWithdrawPanel />\n          </Grid>\n          <h4>AmmPanel</h4>\n          <Grid container spacing={2} alignContent={'center'} justifyContent={'space-around'}>\n            <WrapAmmPanel />\n          </Grid>\n\n          <h4>Open modal btn group</h4>\n          <Grid container spacing={2} alignContent={'center'} justifyContent={'space-around'}>\n            <Grid item xs={2}>\n              <Button\n                variant={'contained'}\n                size={'small'}\n                color={'primary'}\n                onClick={() => dispatch(setShowTransfer({ isShow: true }))}\n              >\n                Open Transfer\n              </Button>\n            </Grid>\n            <Grid item xs={6} display={'flex'} justifyContent={'space-around'}>\n              <Button\n                variant={'contained'}\n                size={'small'}\n                color={'primary'}\n                onClick={() => dispatch(setShowDeposit({ isShow: true }))}\n              >\n                Open Deposit\n              </Button>\n\n              <Button\n                variant={'outlined'}\n                size={'small'}\n                color={'primary'}\n                onClick={() =>\n                  dispatch(\n                    setShowDeposit({\n                      isShow: true,\n                      props: {\n                        title: t('depositTitleAndActive'),\n                      },\n                    }),\n                  )\n                }\n              >\n                Open Deposit & active acct\n              </Button>\n            </Grid>\n            <Grid item xs={2}>\n              <Button\n                variant={'contained'}\n                size={'small'}\n                color={'primary'}\n                onClick={() => dispatch(setShowResetAccount({ isShow: true }))}\n              >\n                Open Rest Private key\n              </Button>\n            </Grid>\n            <Grid item xs={2}>\n              <Button\n                variant={'contained'}\n                size={'small'}\n                color={'primary'}\n                onClick={() => dispatch(setShowWithdraw({ isShow: true }))}\n              >\n                Open Withdraw\n              </Button>\n            </Grid>\n            <Grid item xs={2}>\n              <Button\n                variant={'contained'}\n                size={'small'}\n                color={'primary'}\n                onClick={() =>\n                  dispatch(\n                    setShowAmm({\n                      isShow: true,\n                      type: AmmPanelType.Exit,\n                    }),\n                  )\n                }\n              >\n                Open Amm WithDraw\n              </Button>\n            </Grid>\n            <Grid item xs={2}>\n              <Button\n                variant={'contained'}\n                size={'small'}\n                color={'primary'}\n                onClick={() => dispatch(setShowAmm({ isShow: true, type: AmmPanelType.Join }))}\n              >\n                Open Amm Deposit\n              </Button>\n            </Grid>\n            <Grid item xs={2}>\n              <Button\n                variant={'contained'}\n                size={'small'}\n                color={'primary'}\n                onClick={() => dispatch(setShowSwap({ isShow: true }))}\n              >\n                Open trade\n              </Button>\n            </Grid>\n          </Grid>\n          <ModalPanelWrap />\n        </Box>\n      </MemoryRouter>\n    </Style>\n  )\n}\n\nexport default {\n  title: 'components/Swap&TradePanel',\n  component: WrapSwapPanel,\n  argTypes: {},\n} as Meta\n\nexport const SwapPanelStory = Template.bind({})\n// SwitchPanel.args = {}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/Reset/ActiveAccountPanel.tsx",
    "content": "import { ResetProps } from '../Interface'\nimport { withTranslation, WithTranslation } from 'react-i18next'\nimport { FeeInfo, IBData } from '@loopring-web/common-resources'\nimport { SwitchPanel, SwitchPanelProps } from '../../basic-lib'\nimport React from 'react'\nimport { ResetWrap } from '../components'\n\nexport const ActiveAccountPanel = withTranslation('common', { withRef: true })(\n  <T extends FeeInfo>({ ...rest }: ResetProps<T> & WithTranslation) => {\n    const props: SwitchPanelProps<'tradeMenuList' | 'trade'> = {\n      index: 0, // show default show\n      panelList: [\n        {\n          key: 'trade',\n          element: (\n            <ResetWrap<T>\n              key={'Reset'}\n              {...{\n                ...rest,\n              }}\n            />\n          ),\n          toolBarItem: undefined,\n        },\n      ],\n    }\n    return <SwitchPanel {...{ ...rest, ...props }} />\n  },\n) as <T extends IBData<I>, I>(props: ResetProps<T> & React.RefAttributes<any>) => JSX.Element\n\n// export const TransferModal = withTranslation()\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/Reset/ConfirmationPanel.tsx",
    "content": "import { withTranslation, WithTranslation } from 'react-i18next'\nimport { Box, Button, Typography } from '@mui/material'\n\nexport const ResetAccountConfirmationPanel = withTranslation('common', { withRef: true })(\n  ({\n    type,\n    t,\n    onConfirmation,\n  }: {\n    type: 'lockedReset' | 'unlockedWithDual' | 'unlockedWithoutDual'\n    onConfirmation: () => void\n  } & WithTranslation) => {\n    return (\n      <Box display={'flex'} flexDirection={'column'} width={'var(--modal-width)'} padding={2}>\n        <Typography textAlign={'center'} marginBottom={2} variant={'h3'}>\n          {t(\"labelResetLoopringL2\")}\n        </Typography>\n        {type === 'lockedReset' ? (\n          <>\n            <Typography marginBottom={2} color={'var(--color-text-secondary)'}>\n              {t(\"labelResetlockedReset1\")}\n            </Typography>\n            <Typography marginBottom={2} color={'var(--color-text-secondary)'}>\n              {t(\"labelResetlockedReset2\")}\n            </Typography>\n          </>\n        ) : type === 'unlockedWithDual' ? (\n          <>\n            <Typography marginBottom={2} color={'var(--color-text-secondary)'}>\n              {t(\"labelResetunlockedWithDual1\")}\n            </Typography>\n            <Typography marginBottom={2} color={'var(--color-text-secondary)'}>\n              {t(\"labelResetunlockedWithDual2\")}\n            </Typography>\n          </>\n        ) : (\n          <>\n            <Typography marginBottom={2} color={'var(--color-text-secondary)'}>\n              {t(\"labelResetunlockedWithoutDual\")}\n            </Typography>\n          </>\n        )}\n        <Button onClick={() => onConfirmation()} sx={{ alignSelf: 'end' }} variant={'contained'}>\n          {t(\"labelOK\")}\n        </Button>\n      </Box>\n    )\n  },\n)\n\n// export const TransferModal = withTranslation()\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/Reset/ResetPanel.tsx",
    "content": "import { ResetProps } from '../Interface'\nimport { withTranslation, WithTranslation } from 'react-i18next'\nimport { FeeInfo, IBData } from '@loopring-web/common-resources'\nimport { SwitchPanel, SwitchPanelProps } from '../../basic-lib'\nimport { ResetWrap } from '../components'\nimport React from 'react'\n\nexport const ResetPanel = withTranslation('common', { withRef: true })(\n  <T extends FeeInfo>({\n    onResetClick,\n    resetBtnStatus,\n    chargeFeeTokenList,\n    assetsData,\n    ...rest\n  }: ResetProps<T> & WithTranslation) => {\n    const props: SwitchPanelProps<'tradeMenuList' | 'trade'> = {\n      index: 0, // show default show\n      panelList: [\n        {\n          key: 'trade',\n          element: (\n            <ResetWrap<T>\n              key={'transfer'}\n              {...{\n                ...rest,\n                resetBtnStatus,\n                chargeFeeTokenList,\n                onResetClick,\n                assetsData,\n              }}\n            />\n          ),\n          toolBarItem: undefined,\n        },\n      ],\n    }\n    return <SwitchPanel {...{ ...rest, ...props }} />\n  },\n) as <T extends IBData<I>, I>(props: ResetProps<T> & React.RefAttributes<any>) => JSX.Element\n\n// export const TransferModal = withTranslation()\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/Reset/index.ts",
    "content": "export * from './ResetPanel'\nexport * from './ActiveAccountPanel'\nexport * from './ConfirmationPanel'\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/Swap/index.tsx",
    "content": "import { SwapProps, SwapTradeData, SwapType } from '../Interface'\nimport { withTranslation, WithTranslation } from 'react-i18next'\nimport React, { useCallback, useState } from 'react'\nimport { Box, Checkbox, Grid, Popover, Switch, Tooltip, Typography } from '@mui/material'\nimport { SwitchPanel, SwitchPanelProps } from '../../basic-lib'\nimport {\n  BtradeTradeCalcData,\n  CheckBoxIcon,\n  CheckedIcon,\n  defaultBlockTradeSlipage,\n  IBData,\n  Info2Icon,\n  myLog,\n  OrderListIcon,\n  RecordTabIndex,\n  RouterPath,\n  SCENARIO,\n  SlippageBtradeTolerance,\n  SlippageTolerance,\n  SwapSettingIcon,\n  SwapTradeCalcData,\n  TokenType,\n  TradeCalcData,\n  VaultTradeCalcData,\n} from '@loopring-web/common-resources'\nimport { SlippagePanel, SwapData, SwapMenuList, SwapTradeWrap } from '../components'\nimport { CountDownIcon } from '../components/tool/Refresh'\nimport { IconButtonStyled } from '../components/Styled'\nimport { useHistory } from 'react-router-dom'\nimport { TagIconList } from '../../block'\nimport { useSettings } from '../../../stores'\nimport styled from '@emotion/styled'\nimport { useTheme } from '@emotion/react'\nimport { ToastType } from '../../toast'\n\nconst PopoverStyled = styled(Popover)`\n  .MuiPaper-elevation2 {\n    box-shadow: none;\n    padding: 0;\n    width: 250px;\n  }\n\n  .MuiBackdrop-root {\n    background: transparent;\n  }\n`\n\nexport const SwapPanel = withTranslation('common', { withRef: true })(\n  <\n    T extends IBData<I>,\n    I,\n    TCD extends BtradeTradeCalcData<I> | SwapTradeCalcData<I> | VaultTradeCalcData<T>,\n  >({\n    disabled,\n    tradeCalcData,\n    swapBtnStatus,\n    tokenSellProps,\n    tokenBuyProps,\n    handleSwapPanelEvent,\n    handleError,\n    onSwapClick,\n    toPro,\n    market,\n    onRefreshData,\n    campaignTagConfig,\n    refreshRef,\n    tradeData,\n    setToastOpen,\n    titleI8nKey = 'swapTitle',\n    scenario = SCENARIO.SWAP,\n    hideSecondConfirmation,\n    bTradeTutorial,\n    marginLevelChange,\n    vaultLeverage,\n    refreshTime,\n    ...rest\n  }: SwapProps<T, I, TCD> & WithTranslation & {}) => {\n    let history = useHistory()\n    const [index, setIndex] = React.useState(0)\n    const [type, setType] = React.useState<'buy' | 'sell' | 'exchange'>('buy')\n    const [to, setTo] = React.useState<'button' | 'menu'>('button')\n    const onChangeEvent = (_index: 0 | 1, { type, to, tradeData }: SwapData<SwapTradeData<T>>) => {\n      myLog('hookSwap onChangeEvent', tradeData)\n      if (_index !== index) {\n        setIndex(_index)\n      }\n      switch (type) {\n        case 'exchange':\n          setType('buy')\n          break\n        default:\n          setType(type)\n      }\n      setTo(to)\n\n      handleSwapPanelEvent &&\n        handleSwapPanelEvent(\n          {\n            to,\n            tradeData,\n            type,\n          },\n          (type === 'exchange' ? 'exchange' : `${type}To${to}`) as SwapType,\n        )\n      myLog('hookSwap panelEventNext', tradeData.slippage, tradeData)\n    }\n    const [anchorEl, setAnchorEl] = useState<HTMLButtonElement | null>(null)\n    const [settingPopoverOpen, setSettingPopoverOpen] = useState(false)\n    const settingPopoverId = settingPopoverOpen ? 'setting-popover' : undefined\n    const { slippage, swapSecondConfirmation, setSwapSecondConfirmation } = useSettings()\n    const onSwitchChangeCallback = useCallback(() => {\n      setToastOpen &&\n        setToastOpen({\n          open: true,\n          content: rest.t('labelSwapSettingToggleSuccess', {\n            onOrOff: !swapSecondConfirmation ? 'on' : 'off',\n          }),\n          type: ToastType.success,\n        })\n      setSwapSecondConfirmation(!swapSecondConfirmation)\n    }, [swapSecondConfirmation, setSwapSecondConfirmation, setToastOpen])\n    const onSlippageChangeCallBack = React.useCallback(\n      (slippage: number | string, customSlippage: number | string | undefined) => {\n        myLog('hookSwap slippage', slippage, tradeData)\n        onChangeEvent(0, {\n          tradeData: {\n            ...tradeData,\n            slippage: slippage,\n            __cache__: {\n              ...tradeData?.__cache__,\n              customSlippage: customSlippage,\n            },\n          },\n          type: 'sell',\n          to: 'button',\n        })\n      },\n      [tradeData, onChangeEvent],\n    )\n    const theme = useTheme()\n    const props: SwitchPanelProps<'tradeMenuList' | 'trade'> = {\n      index: index, // show default show\n      panelList: [\n        {\n          key: 'trade',\n          element: React.useMemo(() => {\n            myLog('hookSwap view tradeData', tradeData)\n            return (\n              // @ts-ignore\n              <SwapTradeWrap<T, I, TCD>\n                key={'trade'}\n                {...{\n                  ...rest,\n                  tradeData,\n                  tradeCalcData,\n                  onSwapClick,\n                  onChangeEvent,\n                  disabled,\n                  swapBtnStatus,\n                  tokenSellProps,\n                  tokenBuyProps,\n                  handleError,\n                  marginLevelChange\n                }}\n              />\n            )\n          }, [\n            rest,\n            tradeCalcData,\n            onSwapClick,\n            tradeData,\n            onChangeEvent,\n            disabled,\n            swapBtnStatus,\n            tokenSellProps,\n            tokenBuyProps,\n            handleError,\n          ]),\n          toolBarItem: React.useMemo(\n            () => (\n              <>\n                <Typography\n                  marginTop={1}\n                  height={'100%'}\n                  display={'inline-flex'}\n                  variant={'h5'}\n                  alignItems={'center'}\n                  alignSelf={'self-start'}\n                  component={'span'}\n                >\n                  {rest.t(titleI8nKey)}\n                  <Typography\n                    component={'span'}\n                    paddingLeft={1}\n                    display={'flex'}\n                    alignItems={'center'}\n                  >\n                    {campaignTagConfig && (\n                      <TagIconList\n                        scenario={scenario}\n                        campaignTagConfig={campaignTagConfig}\n                        symbol={market as string}\n                      />\n                    )}\n                  </Typography>\n                </Typography>\n\n                <Box alignSelf={'flex-end'} display={'flex'} className={'toolButton'}>\n                  <Typography display={'inline-block'} marginLeft={2} component={'span'}>\n                    <IconButtonStyled\n                      onClick={(e) => {\n                        setSettingPopoverOpen(true)\n                        setAnchorEl(e.currentTarget)\n                      }}\n                      sx={{ backgroundColor: 'var(--field-opacity)' }}\n                      className={'switch outlined'}\n                      aria-label='to Transaction'\n                      aria-describedby={settingPopoverId}\n                      size={'large'}\n                    >\n                      <SwapSettingIcon htmlColor={theme.colorBase.logo} />\n                    </IconButtonStyled>\n                    <PopoverStyled\n                      id={settingPopoverId}\n                      open={settingPopoverOpen}\n                      anchorEl={anchorEl}\n                      onClose={() => {\n                        setSettingPopoverOpen(false)\n                        setAnchorEl(null)\n                      }}\n                      anchorOrigin={{\n                        vertical: 'bottom',\n                        horizontal: 'left',\n                      }}\n                      sx={{ background: 'transparent' }}\n                    >\n                      <Box paddingX={2} paddingTop={2} paddingBottom={4}>\n                        <Box paddingBottom={1}>\n                          <Typography marginBottom={1} component={'span'}>\n                            {rest.t('labelSwapSettingTitle')}\n                          </Typography>\n                          <Typography\n                            marginBottom={1}\n                            paddingLeft={1}\n                            variant={'body2'}\n                            color={'var(--color-text-third)'}\n                            component={'span'}\n                          >\n                            {rest.t('swapTolerance')}\n                          </Typography>\n                        </Box>\n                        <SlippagePanel\n                          t={rest.t}\n                          max={100}\n                          slippageList={\n                            (tradeCalcData as BtradeTradeCalcData<I>)?.isBtrade ||\n                            (tradeCalcData as VaultTradeCalcData<T>)?.isVault\n                              ? (SlippageBtradeTolerance.concat(`slippage:${slippage}`) as Array<\n                                  number | string\n                                >)\n                              : (SlippageTolerance.concat(`slippage:${slippage}`) as Array<\n                                  number | string\n                                >)\n                          }\n                          slippage={\n                            tradeData?.slippage\n                              ? tradeData?.slippage\n                              : tradeCalcData?.slippage\n                              ? tradeCalcData?.slippage\n                              : defaultBlockTradeSlipage\n                          }\n                          handleChange={(slippage, customSlippage) => {\n                            onSlippageChangeCallBack(slippage, customSlippage)\n                          }}\n                        />\n                        {bTradeTutorial?.show && (\n                          <Box\n                            marginTop={1.5}\n                            display={'flex'}\n                            alignItems={'center'}\n                            justifyContent={'space-between'}\n                          >\n                            <Typography color={'var(--color-text-secondary)'}>\n                              {rest.t(\"Block Trade Tutorial\")}\n                            </Typography>\n\n                            <Switch\n                              checked={bTradeTutorial?.checked}\n                              onChange={(_event, _checked) => {\n                                bTradeTutorial?.onToggle()\n                              }}\n                            />\n                          </Box>\n                        )}\n                        {(tradeCalcData as any).isVault && !vaultLeverage?.hideLeverage && (\n                          <Grid\n                            container\n                            justifyContent={'space-between'}\n                            direction={'row'}\n                            alignItems={'center'}\n                            height={24}\n                            marginTop={2.5}\n                          >\n                            <Typography\n                              component={'span'}\n                              variant='body2'\n                              color={'textSecondary'}\n                              display={'inline-flex'}\n                              alignItems={'center'}\n                            >\n                              {' ' + rest.t('labelVaultLeverage')}\n                            </Typography>\n                            <Typography\n                              component={'span'}\n                              variant='body2'\n                              color={'textSecondary'}\n                              display={'inline-flex'}\n                              alignItems={'center'}\n                              sx={{textDecoration: 'underline', cursor: 'pointer'}}\n                              mr={1.5}\n                              onClick={() => {\n                                vaultLeverage?.onClickLeverage && vaultLeverage?.onClickLeverage()\n                              }}\n                            >\n                              {vaultLeverage?.leverage}x\n                            </Typography>\n                            \n                          </Grid>\n                        )}\n                        {!hideSecondConfirmation && (\n                          <Grid\n                            container\n                            justifyContent={'space-between'}\n                            direction={'row'}\n                            alignItems={'center'}\n                            height={24}\n                            marginTop={1}\n                          >\n                            <Tooltip\n                              title={rest.t('labelSwapSettingSecondConfirmTootip').toString()}\n                              placement={'bottom'}\n                            >\n                              <Typography\n                                component={'span'}\n                                variant='body2'\n                                color={'textSecondary'}\n                                display={'inline-flex'}\n                                alignItems={'center'}\n                              >\n                                <Info2Icon\n                                  fontSize={'small'}\n                                  color={'inherit'}\n                                  sx={{ marginX: 1 / 2 }}\n                                />\n                                {' ' + rest.t('labelSwapSettingSecondConfirm')}\n                              </Typography>\n                            </Tooltip>\n                            <Switch\n                              onChange={() => {\n                                onSwitchChangeCallback()\n                              }}\n                              checked={swapSecondConfirmation !== false}\n                            />\n                          </Grid>\n                        )}\n                      </Box>\n                    </PopoverStyled>\n                  </Typography>\n                  <Typography display={'inline-block'} marginLeft={2} component={'span'}>\n                    <CountDownIcon countDownSeconds={refreshTime} onRefreshData={onRefreshData} ref={refreshRef} />\n                  </Typography>\n                  <Typography\n                    display={'inline-block'}\n                    marginLeft={2}\n                    component={'span'}\n                    className={'record'}\n                  >\n                    <IconButtonStyled\n                      onClick={() => {\n                        // @ts-ignore\n                        tradeCalcData.isBtrade\n                          ? history.push(\n                              `${RouterPath.l2records}/${RecordTabIndex.BtradeSwapRecords}?market=${market}`,\n                            )\n                          : // @ts-ignore\n                          tradeCalcData.isVault\n                          ? history.push(\n                              `${RouterPath.l2records}/${RecordTabIndex.VaultRecords}?market=${market}`,\n                            )\n                          : history.push(\n                              `${RouterPath.l2records}/${RecordTabIndex.Trades}?market=${market}`,\n                            )\n                      }}\n                      sx={{ backgroundColor: 'var(--field-opacity)' }}\n                      className={'switch outlined'}\n                      aria-label='to Transaction'\n                      size={'large'}\n                    >\n                      <OrderListIcon fill={theme.colorBase.logo} fontSize={'large'} />\n                    </IconButtonStyled>\n                  </Typography>\n                </Box>\n              </>\n            ),\n            [\n              onRefreshData,\n              settingPopoverOpen,\n              swapSecondConfirmation,\n              onSwitchChangeCallback,\n              onSlippageChangeCallBack,\n              tradeData,\n              theme,\n            ],\n          ),\n        },\n        {\n          key: 'tradeMenuList',\n          element: React.useMemo(\n            () => (\n              // @ts-ignore\n              <SwapMenuList<T, I, TCD>\n                key={'tradeMenuList'}\n                {...{\n                  ...rest,\n                  tokenType: (tradeCalcData as VaultTradeCalcData<T>)?.isVault\n                    ? TokenType.vault\n                    : undefined,\n                  onChangeEvent,\n                  tradeCalcData,\n                  swapData: {\n                    tradeData,\n                    type,\n                    to,\n                  },\n                }}\n              />\n            ),\n            [onChangeEvent, tradeCalcData, type, to, rest],\n          ),\n          toolBarItem: undefined,\n        },\n      ],\n    }\n    return (\n      <SwitchPanel\n        className={`hasLinerBg ${rest?.classWrapName}`}\n        {...{ ...rest, ...props, size: 'large' }}\n      />\n    )\n  },\n) as <T extends IBData<I>, I, TCD extends TradeCalcData<I>>(\n  props: SwapProps<T, I, TCD> & React.RefAttributes<any>,\n) => JSX.Element\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/AddressType.tsx",
    "content": "import { Box, IconButton, MenuItem, Typography } from '@mui/material'\nimport { useTranslation } from 'react-i18next'\nimport styled from '@emotion/styled'\nimport React, { ForwardedRef } from 'react'\nimport {\n  AddressItemType,\n  CloseIcon,\n  EXCHANGE_TYPE,\n  Info2Icon,\n  RoundCheckIcon,\n  RoundCircleIcon,\n  WALLET_TYPE,\n  hexToRGB,\n} from '@loopring-web/common-resources'\nimport { MenuItemProps, TextField } from '../../basic-lib'\nimport { useOpenModals } from '../../../stores'\nimport { useAddressTypeLists } from './hook/useAddressType'\nimport { useTheme } from '@emotion/react'\n\nconst MenuItemStyle = styled(MenuItem)<MenuItemProps<any> & { maxWidth?: string | number }>`\n  height: auto;\n  max-width: ${({ maxWidth }) => (maxWidth ? maxWidth : 'auto')};\n  border: 1px solid;\n  border-color: ${({ checked }) => (checked ? 'var(--color-primary)' : 'var(--color-border)')};\n  width: 100%;\n  display: flex;\n  justify-content: space-between;\n  border-radius: ${({ theme }) => theme.unit}px;\n  padding: ${({ theme }) => 2 * theme.unit}px;\n  min-height: ${({ theme }) => theme.unit * 8}px;\n  align-items: center;\n  cursor: pointer;\n  flex-direction: row;\n  margin-top: ${({ theme }) => 2 * theme.unit}px;\n` as (props: MenuItemProps<any> & { maxWidth?: string | number }) => JSX.Element\n\nconst WarningBoxStyled = styled(Box)`\n  width: 100%;\n  display: flex;\n  justify-content: space-between;\n  border-radius: ${({ theme }) => theme.unit}px;\n  padding: ${({ theme }) => 2 * theme.unit}px;\n  min-height: ${({ theme }) => theme.unit * 8}px;\n  align-items: center;\n  cursor: pointer;\n  flex-direction: row;\n  background: ${({ theme }) => hexToRGB(theme.colorBase.warning, 0.2)};\n`\n\nexport const WalletItemOptions = React.memo(\n  React.forwardRef(\n    <T extends WALLET_TYPE | EXCHANGE_TYPE>(\n      {\n        description,\n        label,\n        myValue,\n        selectedValue,\n        maxWidth,\n        disabled = false,\n        handleSelected,\n      }: {\n        myValue: T\n        handleSelected: (value: WALLET_TYPE | EXCHANGE_TYPE) => void\n        selectedValue: T | undefined\n      } & AddressItemType<T>,\n      ref: ForwardedRef<any>,\n    ) => {\n      return (\n        <MenuItemStyle\n          ref={ref}\n          disabled={disabled}\n          value={myValue}\n          maxWidth={maxWidth}\n          // onClick={}\n          // sx={{ maxWidth: maxWidth ? maxWidth : \"fit-content\" }}\n          onClick={() => {\n            handleSelected(myValue)\n          }}\n        >\n          <Box width={'100%'} component={'span'}>\n            <Typography color={'textPrimary'}>{label}</Typography>\n            <Typography\n              component={'span'}\n              whiteSpace={'pre-line'}\n              variant={'body2'}\n              color={'textSecondary'}\n            >\n              {description}\n            </Typography>\n          </Box>\n          {selectedValue === myValue ? (\n            <RoundCheckIcon fontSize={'large'} fill={'var(--color-primary)'} />\n          ) : (\n            <RoundCircleIcon fontSize={'large'} />\n          )}\n        </MenuItemStyle>\n      )\n    },\n  ),\n)\nexport const TransferAddressType = <T extends WALLET_TYPE>({\n  selectedValue,\n  handleSelected,\n  disabled,\n  detectedWalletType,\n}: {\n  selectedValue: WALLET_TYPE | EXCHANGE_TYPE | undefined\n  handleSelected: (value: WALLET_TYPE | EXCHANGE_TYPE) => void\n  disabled: boolean\n  detectedWalletType: WALLET_TYPE\n}) => {\n  const { t } = useTranslation('common')\n  const { walletListFn } = useAddressTypeLists<T>()\n  const theme = useTheme()\n  const desMenuItem = React.useMemo(() => {\n    return (\n      <WarningBoxStyled>\n        <Info2Icon fontSize={'large'} htmlColor={theme.colorBase.warning}></Info2Icon>\n        <Typography marginLeft={1} fontSize={'13px'}>\n          {t('labelWalletTypeDes')}\n        </Typography>\n      </WarningBoxStyled>\n    )\n  }, [t])\n\n  const [open, setOpen] = React.useState(false)\n  const onClose = () => {\n    setOpen(false)\n  }\n  const {\n    setShowOtherExchange,\n    modals: { isShowOtherExchange },\n  } = useOpenModals()\n\n  React.useEffect(() => {\n    if (isShowOtherExchange.agree) {\n      handleSelected(EXCHANGE_TYPE.Others)\n      onClose()\n    }\n  }, [isShowOtherExchange.agree])\n\n  const onOpen = () => {\n    setOpen(true)\n    setShowOtherExchange({ isShow: false, agree: false })\n  }\n  // const walletType = WALLET_TYPE.EOA\n  return (\n    <TextField\n      size={'large'}\n      select\n      disabled={disabled}\n      fullWidth\n      variant='outlined'\n      value={selectedValue ?? ''}\n      SelectProps={{\n        open,\n        onClose,\n        onOpen,\n        autoWidth: false,\n        renderValue: (selectedValue) =>\n          walletListFn(detectedWalletType).find((item) => item.value === selectedValue)?.label ??\n          '',\n      }}\n      label={\n        <Typography color={'var(--color-text-third)'}>{t('labelL2toL1AddressType')}</Typography>\n      }\n    >\n      <Box maxWidth={'480px'} padding={5}>\n        <IconButton\n          sx={{\n            position: 'absolute',\n            right: 20,\n            top: 20,\n          }}\n          size={'large'}\n          edge={'end'}\n          onClick={onClose}\n        >\n          <CloseIcon />\n        </IconButton>\n        <Typography textAlign={'center'} marginBottom={3} variant={'h3'}>\n          {t('labelL2toL1AddressType')}\n        </Typography>\n        {desMenuItem}\n        {walletListFn(detectedWalletType).map(\n          ({ value, label, description, disabled, maxWidth }) => (\n            <WalletItemOptions\n              key={value}\n              value={value}\n              myValue={value}\n              handleSelected={(value) => {\n                if (value === EXCHANGE_TYPE.Others) {\n                  setShowOtherExchange({ isShow: true })\n                } else {\n                  handleSelected(value as T)\n                  onClose()\n                }\n                // handleSelected(value);\n                // onClose();\n              }}\n              maxWidth={maxWidth}\n              selectedValue={selectedValue}\n              label={label}\n              description={description}\n              disabled={disabled}\n            />\n          ),\n        )}\n      </Box>\n    </TextField>\n  )\n}\n\nexport const FullAddressType = <T extends EXCHANGE_TYPE>({\n  selectedValue,\n  handleSelected,\n  disabled,\n  detectedWalletType,\n}: {\n  selectedValue: WALLET_TYPE | EXCHANGE_TYPE | undefined\n  handleSelected: (value: WALLET_TYPE | EXCHANGE_TYPE) => void\n  disabled: boolean\n  detectedWalletType: WALLET_TYPE\n}) => {\n  const { t } = useTranslation('common')\n  const { walletListFn } = useAddressTypeLists<T>()\n  const {\n    setShowOtherExchange,\n    modals: { isShowOtherExchange },\n  } = useOpenModals()\n  const [open, setOpen] = React.useState(false)\n  const onClose = () => {\n    setOpen(false)\n  }\n  React.useEffect(() => {\n    if (isShowOtherExchange.agree) {\n      handleSelected(EXCHANGE_TYPE.Others)\n      onClose()\n    }\n  }, [isShowOtherExchange.agree])\n\n  const onOpen = () => {\n    setOpen(true)\n    setShowOtherExchange({ isShow: false, agree: false })\n  }\n\n  return (\n    <TextField\n      size={'large'}\n      select\n      disabled={disabled}\n      fullWidth\n      variant='outlined'\n      value={selectedValue ?? ''}\n      SelectProps={{\n        open,\n        onClose,\n        onOpen,\n        autoWidth: false,\n        renderValue: (selectedValue) =>\n          walletListFn(detectedWalletType).find((item) => item.value === selectedValue)?.label ??\n          '',\n      }}\n      label={\n        <Typography color={'var(--color-text-third)'}>{t('labelL2toL1AddressType')}</Typography>\n      }\n    >\n      <Box maxWidth={'480px'} padding={5}>\n        <IconButton\n          sx={{\n            position: 'absolute',\n            right: 20,\n            top: 20,\n          }}\n          size={'large'}\n          edge={'end'}\n          onClick={onClose}\n        >\n          <CloseIcon />\n        </IconButton>\n        <Typography textAlign={'center'} marginBottom={3} variant={'h3'}>\n          {t('labelL2toL1AddressType')}\n        </Typography>\n        <MenuItemStyle disabled={true} value={-1}>\n          <Typography component={'span'}>{t('labelExchangeTypeDes')}</Typography>\n        </MenuItemStyle>\n        {walletListFn(detectedWalletType).map(\n          ({ value, label, description, disabled, maxWidth }) => (\n            <WalletItemOptions\n              key={value}\n              value={value}\n              myValue={value}\n              handleSelected={async (value) => {\n                if (value === EXCHANGE_TYPE.Others) {\n                  setShowOtherExchange({ isShow: true })\n                } else {\n                  handleSelected(value)\n                  onClose()\n                }\n              }}\n              selectedValue={selectedValue}\n              label={label}\n              maxWidth={maxWidth}\n              description={description}\n              disabled={disabled}\n            />\n          ),\n        )}\n      </Box>\n    </TextField>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/AmmWrap/AmmDeposit.tsx",
    "content": "import {\n  AmmInData,\n  AmmJoinData,\n  defaultSlipage,\n  EmptyValueTag,\n  IBData,\n  L1L2_NAME_DEFINED,\n  LinkedIcon,\n  MapChainId,\n  ReverseIcon,\n  SlippageTolerance,\n  TradeBtnStatus,\n} from '@loopring-web/common-resources'\nimport { WithTranslation } from 'react-i18next'\nimport { AmmDepositWrapProps } from './Interface'\nimport { InputCoin, LinkActionStyle, PopoverPure } from '../../../basic-lib'\nimport React from 'react'\nimport { usePopupState } from 'material-ui-popup-state/hooks'\nimport { Box, Grid, Typography } from '@mui/material'\nimport { bindHover, bindPopover } from 'material-ui-popup-state/es'\nimport { SlippagePanel } from '../tool'\nimport { SvgStyled } from './styled'\nimport { useSettings } from '../../../../stores'\nimport { ButtonStyle, IconButtonStyled } from '../Styled'\n\nexport const AmmDepositWrap = <\n  T extends AmmJoinData<C extends IBData<I> ? C : IBData<I>>,\n  I,\n  ACD extends AmmInData<I>,\n  C = IBData<I>,\n>({\n  t,\n  disabled,\n  isStob,\n  switchStobEvent,\n  ammDepositBtnStatus,\n  ammCalcData,\n  ammDepositBtnI18nKey,\n  onAmmAddClick,\n  tokenAProps,\n  tokenBProps,\n  onAddChangeEvent,\n  ammData,\n  propsAExtends = {},\n  propsBExtends = {},\n  // coinAPrecision,\n  // coinBPrecision,\n  ...rest\n}: AmmDepositWrapProps<T, I, ACD, C> & WithTranslation) => {\n  const coinARef = React.useRef()\n  const coinBRef = React.useRef()\n  const { slippage, defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const slippageArray: Array<number | string> = SlippageTolerance.concat(\n    `slippage:${slippage}`,\n  ) as Array<number | string>\n\n  const [_isStoB, setIsStoB] = React.useState(isStob ?? true)\n  const stob = React.useMemo(() => {\n    if (ammCalcData && ammCalcData?.lpCoinA && ammCalcData?.lpCoinB && ammCalcData.AtoB) {\n      let price: string\n      if (_isStoB) {\n        price = `1 ${ammCalcData?.lpCoinA?.belong} \\u2248 ${\n          ammCalcData.AtoB ? ammCalcData.AtoB : EmptyValueTag\n        } ${ammCalcData?.lpCoinB?.belong}`\n      } else {\n        price = `1 ${ammCalcData?.lpCoinB?.belong} \\u2248 ${\n          ammCalcData.BtoA ? ammCalcData.BtoA : EmptyValueTag\n        } ${ammCalcData?.lpCoinA?.belong}`\n      }\n      return (\n        <>\n          {price}\n          <IconButtonStyled\n            size={'small'}\n            aria-label={t('tokenExchange')}\n            onClick={() => setIsStoB(!_isStoB)}\n          >\n            <ReverseIcon />\n          </IconButtonStyled>\n        </>\n      )\n    } else {\n      return EmptyValueTag\n    }\n  }, [_isStoB, ammCalcData])\n  const getDisabled = () => {\n    return disabled || ammCalcData === undefined || ammCalcData.coinInfoMap === undefined\n  }\n  const handleError = () => {\n    if (\n      ammDepositBtnStatus === TradeBtnStatus.DISABLED &&\n      ammDepositBtnI18nKey &&\n      (/labelAMMNoEnough/.test(ammDepositBtnI18nKey) || /labelAMMMax/.test(ammDepositBtnI18nKey))\n    ) {\n      return { error: true }\n    }\n    return { error: false }\n  }\n\n  const handleCountChange = React.useCallback(\n    (ibData: IBData<I>, _name: string, _ref: any) => {\n      const focus: 'coinA' | 'coinB' = _ref?.current === coinARef.current ? 'coinA' : 'coinB'\n      if (ammData[focus].tradeValue !== ibData.tradeValue) {\n        onAddChangeEvent({\n          tradeData: { ...ammData, [focus]: ibData },\n          type: focus,\n        })\n      }\n    },\n    [ammData, onAddChangeEvent],\n  )\n  const propsA: any = {\n    label: t('labelTokenAmount'),\n    subLabel: t('labelAvailable'),\n    placeholderText: '0.00',\n    maxAllow: true,\n    ...tokenAProps,\n    handleError,\n    handleCountChange,\n    ...rest,\n  }\n  const propsB: any = {\n    label: t('labelTokenAmount'),\n    subLabel: t('labelAvailable'),\n    placeholderText: '0.00',\n    maxAllow: true,\n    ...tokenBProps,\n    handleError,\n    handleCountChange,\n    ...rest,\n  }\n  const popupState = usePopupState({\n    variant: 'popover',\n    popupId: 'slippagePop',\n  })\n  const _onSlippageChange = React.useCallback(\n    (slippage: number | string, customSlippage: number | string | undefined) => {\n      popupState.close()\n      onAddChangeEvent({\n        tradeData: {\n          ...ammData,\n          slippage: slippage,\n          __cache__: {\n            ...ammData.__cache__,\n            customSlippage: customSlippage,\n          },\n        },\n        type: 'coinA',\n      })\n    },\n    [ammData, onAddChangeEvent],\n  )\n  const label = React.useMemo(() => {\n    if (ammDepositBtnI18nKey) {\n      const key = ammDepositBtnI18nKey.split('|')\n      return t(\n        key[0],\n        key && key[1]\n          ? {\n              arg: key[1].toString(),\n              l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n              l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n              l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n              ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n            }\n          : {\n              l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n              l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n              l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n              ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n            },\n      )\n    } else {\n      return t(`labelAddLiquidityBtn`, {\n        l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n        loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n        l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n        l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n        ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n      })\n    }\n  }, [ammDepositBtnI18nKey])\n\n  return (\n    <Grid\n      className={ammCalcData ? '' : 'loading'}\n      container\n      direction={'column'}\n      justifyContent={'space-between'}\n      alignItems={'center'}\n      flex={1}\n      height={'100%'}\n    >\n      <Grid\n        item\n        marginTop={3}\n        display={'flex'}\n        alignSelf={'stretch'}\n        justifyContent={''}\n        alignItems={'stretch'}\n        flexDirection={'column'}\n      >\n        <InputCoin<any, I, any>\n          ref={coinARef}\n          disabled={getDisabled() || ammDepositBtnStatus === TradeBtnStatus.LOADING}\n          {...{\n            ...propsA,\n            name: 'coinA',\n            isHideError: true,\n            order: 'right',\n            inputData: ammData ? ammData.coinA : ({} as any),\n            coinMap: ammCalcData ? ammCalcData.coinInfoMap : ({} as any),\n            ...propsAExtends,\n            // coinPrecision: coinAPrecision,\n          }}\n        />\n        <Box alignSelf={'center'} marginY={1}>\n          <SvgStyled>\n            {/* <LinkedIcon /> */}\n            <LinkedIcon fontSize={'large'} htmlColor={'var(--color-text-third)'} />\n          </SvgStyled>\n        </Box>\n        <InputCoin<any, I, any>\n          ref={coinBRef}\n          disabled={getDisabled() || ammDepositBtnStatus === TradeBtnStatus.LOADING}\n          {...{\n            ...propsB,\n            name: 'coinB',\n            isHideError: true,\n            order: 'right',\n            inputData: ammData ? ammData.coinB : ({} as any),\n            coinMap: ammCalcData ? ammCalcData.coinInfoMap : ({} as any),\n            ...propsBExtends,\n            // coinPrecision: coinBPrecision,\n          }}\n        />\n      </Grid>\n\n      <Grid item>\n        <Typography component={'p'} variant={'body1'} height={24} lineHeight={'24px'}>\n          {stob}\n        </Typography>\n      </Grid>\n      <Grid item alignSelf={'stretch'}>\n        <Grid container direction={'column'} spacing={1} alignItems={'stretch'}>\n          <Grid item paddingBottom={3} sx={{ color: 'text.secondary' }}>\n            <Grid\n              container\n              justifyContent={'space-between'}\n              direction={'row'}\n              alignItems={'center'}\n              height={24}\n            >\n              <Typography component={'p'} variant='body2' color={'textSecondary'}>\n                {t('swapTolerance')}\n              </Typography>\n              {ammCalcData ? (\n                <>\n                  <Typography\n                    {...bindHover(popupState)}\n                    component={'span'}\n                    variant='body2'\n                    color={'textPrimary'}\n                  >\n                    <LinkActionStyle>\n                      {ammData.slippage\n                        ? ammData.slippage\n                        : ammCalcData.slippage\n                        ? ammCalcData.slippage\n                        : 0.5}\n                      %\n                    </LinkActionStyle>\n                    <PopoverPure\n                      className={'arrow-right'}\n                      {...bindPopover(popupState)}\n                      {...{\n                        anchorOrigin: {\n                          vertical: 'bottom',\n                          horizontal: 'right',\n                        },\n                        transformOrigin: {\n                          vertical: 'top',\n                          horizontal: 'right',\n                        },\n                      }}\n                    >\n                      <SlippagePanel\n                        {...{\n                          ...rest,\n                          t,\n                          handleChange: _onSlippageChange,\n                          slippageList: slippageArray,\n                          slippage: ammData.slippage\n                            ? ammData.slippage\n                            : ammCalcData.slippage\n                            ? ammCalcData.slippage\n                            : defaultSlipage,\n                        }}\n                      />\n                    </PopoverPure>\n                  </Typography>\n                </>\n              ) : (\n                EmptyValueTag\n              )}\n            </Grid>\n\n            <Grid\n              container\n              justifyContent={'space-between'}\n              direction={'row'}\n              alignItems={'center'}\n              marginTop={1 / 2}\n            >\n              <Typography component={'p'} variant='body2' color={'textSecondary'}>\n                {t('labelNetworkFee')}\n              </Typography>\n              <Typography component={'p'} variant='body2' color={'textPrimary'}>\n                {ammCalcData?.fee && ammCalcData?.fee != '0'\n                  ? ammCalcData.fee + ' ' + ammCalcData.myCoinB.belong\n                  : EmptyValueTag}\n              </Typography>\n            </Grid>\n          </Grid>\n          <Grid item>\n            <ButtonStyle\n              variant={'contained'}\n              size={'large'}\n              color={'primary'}\n              onClick={() => {\n                onAmmAddClick(ammData)\n              }}\n              loading={\n                !getDisabled() && ammDepositBtnStatus === TradeBtnStatus.LOADING ? 'true' : 'false'\n              }\n              disabled={\n                getDisabled() ||\n                ammDepositBtnStatus === TradeBtnStatus.DISABLED ||\n                ammDepositBtnStatus === TradeBtnStatus.LOADING\n              }\n              fullWidth={true}\n            >\n              {label}\n            </ButtonStyle>\n          </Grid>\n        </Grid>\n      </Grid>\n    </Grid>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/AmmWrap/AmmWithdraw.tsx",
    "content": "import {\n  AmmExitData,\n  AmmInData,\n  CoinInfo,\n  defaultSlipage,\n  EmptyValueTag,\n  ExchangeIcon,\n  getValuePrecisionThousand,\n  IBData,\n  L1L2_NAME_DEFINED,\n  MapChainId,\n  myLog,\n  ReverseIcon,\n  SlippageTolerance,\n  TokenType,\n  TradeBtnStatus,\n} from '@loopring-web/common-resources'\nimport { AmmWithdrawWrapProps } from './Interface'\nimport { WithTranslation } from 'react-i18next'\nimport React from 'react'\nimport { usePopupState } from 'material-ui-popup-state/hooks'\nimport { Box, Grid, Link, Typography } from '@mui/material'\nimport {\n  BtnPercentage,\n  ButtonStyle,\n  CoinIcons,\n  IconButtonStyled,\n  InputCoin,\n  LinkActionStyle,\n  PopoverPure,\n} from '../../../index'\nimport { bindHover, bindPopover } from 'material-ui-popup-state/es'\nimport { SlippagePanel } from '../tool'\nimport { useSettings } from '../../../../stores'\nimport { SvgStyled } from './styled'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nimport _ from 'lodash'\n\nexport const AmmWithdrawWrap = <\n  T extends AmmExitData<C extends IBData<I> ? C : IBData<I>>,\n  I,\n  ACD extends AmmInData<I>,\n  C = IBData<I>,\n>({\n  t,\n  disabled,\n  isStob,\n  switchStobEvent,\n  ammWithdrawBtnStatus,\n  ammCalcData,\n  onAmmRemoveClick,\n  tokenLPProps,\n  anchors,\n  ammWithdrawBtnI18nKey,\n  onRemoveChangeEvent,\n  handleError,\n  propsLPExtends = {},\n  ammData,\n  ...rest\n}: AmmWithdrawWrapProps<T, I, ACD, C> & WithTranslation) => {\n  const { coinJson, slippage, defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const coinLPRef = React.useRef()\n  const tokenAIcon = coinJson[ammCalcData?.lpCoinA?.belong as string]\n  const tokenBIcon = coinJson[ammCalcData?.lpCoinB?.belong as string]\n  const slippageArray: Array<number | string> = SlippageTolerance.concat(\n    `slippage:${slippage}`,\n  ) as Array<number | string>\n  const [isPercentage, setIsPercentage] = React.useState(true)\n\n  const percentage = React.useMemo(() => {\n    return ammData?.coinLP?.tradeValue && ammData.coinLP.balance\n      ? getValuePrecisionThousand(\n          (ammData.coinLP.tradeValue / ammData.coinLP.balance) * 100,\n          2,\n          2,\n          2,\n          false,\n        )\n      : 0\n  }, [ammData?.coinLP?.tradeValue, ammData.coinLP.balance])\n\n  const label = React.useMemo(() => {\n    if (ammWithdrawBtnI18nKey) {\n      const key = ammWithdrawBtnI18nKey.split('|')\n      return t(\n        key[0],\n        key && key[1]\n          ? {\n              arg: key[1].toString(),\n              l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n              l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n              l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n              ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n            }\n          : {\n              l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n              l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n              l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n              ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n            },\n      )\n    } else {\n      return t(`labelRemoveLiquidityBtn`, {\n        l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n        loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n        l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n        l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n        ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n      })\n    }\n  }, [ammWithdrawBtnI18nKey])\n\n  const [_isStoB, setIsStoB] = React.useState(isStob ?? true)\n  const stob = React.useMemo(() => {\n    if (ammCalcData && ammCalcData?.lpCoinA && ammCalcData?.lpCoinB && ammCalcData.AtoB) {\n      let price: string\n      if (_isStoB) {\n        price = `1 ${ammCalcData?.lpCoinA?.belong} \\u2248 ${\n          ammCalcData.AtoB ? ammCalcData.AtoB : EmptyValueTag\n        } ${ammCalcData?.lpCoinB?.belong}`\n      } else {\n        price = `1 ${ammCalcData?.lpCoinB?.belong} \\u2248 ${\n          ammCalcData.BtoA ? ammCalcData.BtoA : EmptyValueTag\n        } ${ammCalcData?.lpCoinA?.belong}`\n      }\n      return (\n        <>\n          {price}\n          <IconButtonStyled\n            size={'small'}\n            aria-label={t('tokenExchange')}\n            onClick={() => setIsStoB(!_isStoB)}\n          >\n            <ReverseIcon />\n          </IconButtonStyled>\n        </>\n      )\n    } else {\n      return EmptyValueTag\n    }\n  }, [_isStoB, ammCalcData])\n\n  const getDisabled = () => {\n    return disabled || ammCalcData === undefined || ammCalcData.coinInfoMap === undefined\n  }\n\n  const handleCountChange = React.useCallback(\n    (ibData: IBData<I>, _ref: any) => {\n      // myLog(_ref?.current, coinLPRef.current);\n      if (_ref) {\n        if (ammData?.coinLP.tradeValue !== ibData.tradeValue && ammData?.coinLP.balance) {\n          onRemoveChangeEvent({\n            tradeData: { ...ammData, coinLP: ibData },\n            type: 'lp',\n          })\n        }\n      } else {\n        onRemoveChangeEvent({\n          tradeData: { ...ammData, coinLP: ibData },\n          type: 'lp',\n        })\n      }\n    },\n    [ammData, onRemoveChangeEvent, coinLPRef],\n  )\n\n  const onPercentage = (value: any) => {\n    if (ammData?.coinLP && ammData?.coinLP?.belong) {\n      myLog('selected', Number(value))\n\n      // setSelectedPercentage(value);\n      const cloneLP = _.cloneDeep(ammData.coinLP)\n\n      cloneLP.tradeValue = sdk\n        .toBig(cloneLP?.balance ?? 0)\n        .times(value)\n        .div(100)\n        .toNumber()\n\n      handleCountChange(cloneLP, null)\n    }\n  }\n\n  const _onSlippageChange = React.useCallback(\n    (slippage: number | string, customSlippage: number | string | undefined) => {\n      popupState.close()\n      onRemoveChangeEvent({\n        tradeData: {\n          ...ammData,\n          slippage: slippage,\n          __cache__: {\n            ...ammData.__cache__,\n            customSlippage: customSlippage,\n          },\n        },\n        type: 'lp',\n      })\n    },\n    [ammData, onRemoveChangeEvent],\n  )\n\n  const propsLP: any = {\n    label: t('labelTokenAmount'),\n    subLabel: t('labelAvailable'),\n    placeholderText: '0.00',\n    maxAllow: true,\n    ...tokenLPProps,\n    handleError,\n    ...rest,\n  }\n\n  const popupState = usePopupState({\n    variant: 'popover',\n    popupId: 'slippagePop',\n  })\n\n  // const { label, stob } = useAmmViewData({\n  //   i18nKey: ammWithdrawBtnI18nKey,\n  //   t,\n  //   _isStoB,\n  //   ammCalcData,\n  //   _onSwitchStob,\n  //   isAdd: false,\n  // });\n\n  const showPercentage = percentage < 0 || percentage > 100 ? EmptyValueTag + '%' : `${percentage}%`\n  const lpTradeValue = ammData?.coinLP?.tradeValue\n  let lpBalance: any = ammData?.coinLP?.balance\n  lpBalance = parseFloat(lpBalance)\n  const showLP =\n    lpBalance && lpTradeValue && lpTradeValue > 0 && lpTradeValue <= lpBalance\n      ? getValuePrecisionThousand(lpTradeValue, 2, 6)\n      : '0'\n\n  const miniA = ammData?.coinA?.tradeValue\n    ? getValuePrecisionThousand(ammData?.coinA?.tradeValue)\n    : EmptyValueTag\n\n  const miniB = ammData?.coinB?.tradeValue\n    ? getValuePrecisionThousand(ammData?.coinB?.tradeValue)\n    : EmptyValueTag\n  return (\n    <Grid\n      className={ammCalcData ? '' : 'loading'}\n      container\n      direction={'column'}\n      justifyContent={'space-between'}\n      alignItems={'center'}\n      flex={1}\n      height={'100%'}\n      overflow={'hidden'}\n    >\n      <Grid\n        item\n        display={'flex'}\n        alignSelf={'stretch'}\n        alignItems={'stretch'}\n        flexDirection={'column'}\n      >\n        <Typography alignSelf={'flex-end'}>\n          <Link\n            onClick={() =>\n              ammWithdrawBtnStatus !== TradeBtnStatus.LOADING && setIsPercentage(!isPercentage)\n            }\n          >\n            {t('labelAmmSwitch')}\n          </Link>\n        </Typography>\n        <Typography alignSelf={'center'} variant={'h2'}>\n          {showPercentage}\n        </Typography>\n        <Grid item xs={12} hidden={!isPercentage} height={87}>\n          <Box\n            display={'flex'}\n            flexDirection={'column'}\n            alignItems={'center'}\n            justifyContent={'space-between'}\n          >\n            <Typography alignSelf={'center'} variant={'body1'} marginTop={1} lineHeight={'22px'}>\n              {t('labelLpAmount', { value: showLP })}\n            </Typography>\n            <Box alignSelf={'stretch'} marginTop={1} marginX={2} height={49}>\n              <BtnPercentage\n                disabled={getDisabled() || ammWithdrawBtnStatus === TradeBtnStatus.LOADING}\n                selected={percentage}\n                anchors={[\n                  {\n                    value: 0,\n                    label: '0',\n                  },\n                  {\n                    value: 25,\n                    label: '',\n                  },\n                  {\n                    value: 50,\n                    label: '',\n                  },\n                  {\n                    value: 75,\n                    label: '',\n                  },\n                  {\n                    value: 100,\n                    label: t('labelAvaiable:') + '100%',\n                  },\n                ]}\n                handleChanged={onPercentage}\n              />\n            </Box>\n          </Box>\n        </Grid>\n\n        <Grid item xs={12} hidden={isPercentage} minHeight={86} paddingTop={1}>\n          <InputCoin<IBData<I>, I, CoinInfo<I>>\n            ref={coinLPRef}\n            disabled={getDisabled()}\n            {...{\n              ...propsLP,\n              handleCountChange: (data, _name, ref) => handleCountChange(data, ref),\n              isHideError: true,\n              isShowCoinInfo: false,\n              order: 'right',\n              inputData: ammData ? ammData.coinLP : ({} as any),\n              coinMap: ammCalcData ? ammCalcData.coinInfoMap : ({} as any),\n            }}\n          />\n        </Grid>\n\n        <Box alignSelf={'center'} marginY={1}>\n          <SvgStyled>\n            <ExchangeIcon fontSize={'large'} htmlColor={'var(--color-text-third)'} />\n          </SvgStyled>\n        </Box>\n        <Box\n          borderRadius={1}\n          style={{ background: 'var(--color-table-header-bg)' }}\n          alignItems={'stretch'}\n          display={'flex'}\n          paddingY={1}\n          paddingX={2}\n          flexDirection={'column'}\n        >\n          <Typography variant={'body1'} color={'textSecondary'} alignSelf={'flex-start'}>\n            {t('labelMinReceive')}\n          </Typography>\n          <Box\n            marginTop={1}\n            display={'flex'}\n            flexDirection={'row'}\n            alignItems={'center'}\n            justifyContent={'space-between'}\n          >\n            <Box\n              component={'span'}\n              display={'flex'}\n              flexDirection={'row'}\n              alignItems={'center'}\n              className={'logo-icon'}\n              height={'var(--withdraw-coin-size)'}\n              justifyContent={'flex-start'}\n              marginRight={1 / 2}\n            >\n              <CoinIcons size={18} type={TokenType.single} tokenIcon={[tokenAIcon]} />\n              <Typography variant={'body1'} component={'span'} paddingLeft={1}>\n                {ammData?.coinA?.belong}\n              </Typography>\n            </Box>\n            <Typography variant={'body1'}>{miniA}</Typography>\n          </Box>\n          <Box\n            marginTop={1}\n            display={'flex'}\n            flexDirection={'row'}\n            alignItems={'center'}\n            justifyContent={'space-between'}\n          >\n            <Box\n              component={'span'}\n              display={'flex'}\n              flexDirection={'row'}\n              alignItems={'center'}\n              className={'logo-icon'}\n              height={'var(--withdraw-coin-size)'}\n              justifyContent={'flex-start'}\n              marginRight={1 / 2}\n            >\n              <CoinIcons size={18} type={TokenType.single} tokenIcon={[tokenBIcon]} />\n              <Typography variant={'body1'} component={'span'} paddingLeft={1}>\n                {ammData?.coinB?.belong}\n              </Typography>\n            </Box>\n            <Typography variant={'body1'}>{miniB}</Typography>\n          </Box>\n        </Box>\n      </Grid>\n\n      <Grid item>\n        <Typography component={'p'} variant='body2' height={24} lineHeight={'24px'}>\n          {stob}\n        </Typography>\n      </Grid>\n      <Grid item alignSelf={'stretch'}>\n        <Grid container direction={'column'} spacing={1} alignItems={'stretch'}>\n          <Grid item paddingBottom={3} sx={{ color: 'text.secondary' }}>\n            <Grid\n              container\n              justifyContent={'space-between'}\n              direction={'row'}\n              alignItems={'center'}\n              height={24}\n            >\n              <Typography component={'p'} variant='body2' color={'textSecondary'}>\n                {t('swapTolerance')}\n              </Typography>\n              <Typography component={'p'} variant='body2' color={'textPrimary'}>\n                {ammCalcData ? (\n                  <>\n                    <Typography\n                      {...bindHover(popupState)}\n                      component={'span'}\n                      variant='body2'\n                      color={'textPrimary'}\n                    >\n                      <LinkActionStyle>\n                        {ammData.slippage\n                          ? ammData.slippage\n                          : ammCalcData?.slippage\n                          ? ammCalcData?.slippage\n                          : 0.5}\n                        %\n                      </LinkActionStyle>\n                      <PopoverPure\n                        className={'arrow-right'}\n                        {...bindPopover(popupState)}\n                        {...{\n                          anchorOrigin: {\n                            vertical: 'bottom',\n                            horizontal: 'right',\n                          },\n                          transformOrigin: {\n                            vertical: 'top',\n                            horizontal: 'right',\n                          },\n                        }}\n                      >\n                        <SlippagePanel\n                          {...{\n                            ...rest,\n                            t,\n                            handleChange: _onSlippageChange,\n                            slippageList: slippageArray,\n                            slippage:\n                              ammData && ammData.slippage ? ammData.slippage : defaultSlipage,\n                          }}\n                        />\n                      </PopoverPure>\n                    </Typography>\n                  </>\n                ) : (\n                  EmptyValueTag\n                )}\n              </Typography>\n            </Grid>\n\n            <Grid\n              container\n              justifyContent={'space-between'}\n              direction={'row'}\n              alignItems={'center'}\n              marginTop={1 / 2}\n            >\n              <Typography component={'p'} variant='body2' color={'textSecondary'}>\n                {t('labelNetworkFee')}\n              </Typography>\n              <Typography component={'p'} variant='body2' color={'textPrimary'}>\n                {ammCalcData?.fee && ammCalcData?.fee != '0'\n                  ? ammCalcData.fee + ' ' + ammCalcData.myCoinB.belong\n                  : EmptyValueTag}\n              </Typography>\n            </Grid>\n          </Grid>\n          <Grid item>\n            <ButtonStyle\n              variant={'contained'}\n              size={'large'}\n              color={'primary'}\n              onClick={() => {\n                onAmmRemoveClick(ammData)\n                // setSelectedPercentage(0);\n              }}\n              loading={\n                !getDisabled() && ammWithdrawBtnStatus === TradeBtnStatus.LOADING ? 'true' : 'false'\n              }\n              disabled={\n                getDisabled() ||\n                ammWithdrawBtnStatus === TradeBtnStatus.DISABLED ||\n                ammWithdrawBtnStatus === TradeBtnStatus.LOADING\n              }\n              fullWidth={true}\n            >\n              {label}\n            </ButtonStyle>\n          </Grid>\n        </Grid>\n      </Grid>\n    </Grid>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/AmmWrap/Interface.ts",
    "content": "import { InputButtonProps } from '../../../basic-lib'\nimport { CoinInfo, TradeBtnStatus } from '@loopring-web/common-resources'\n\nexport type AmmChgData<AT> = {\n  type: 'coinA' | 'coinB'\n  tradeData: AT\n}\nexport type AmmWithdrawChgData<AT> = {\n  type: 'lp'\n  tradeData: AT\n}\n\nexport type AmmDepositBaseProps<T, I> = {\n  ammDepositBtnStatus?: keyof typeof TradeBtnStatus | undefined\n  onAmmAddClick: (AmmSendData: T) => void | any\n  ammDepositBtnI18nKey?: string\n  propsAExtends?: Partial<InputButtonProps<T, I, unknown>>\n  propsBExtends?: Partial<InputButtonProps<T, I, unknown>>\n} & Partial<Pick<InputButtonProps<T, I, unknown>, 'handleError'>>\n\nexport type AmmDepositExtendProps<T, I, C, ACD> = {\n  isStob?: boolean\n  switchStobEvent?: (_isStoB: boolean) => void\n  disabled?: boolean\n  onAddChangeEvent: (data: AmmChgData<T>) => void\n  tokenAProps?: Partial<InputButtonProps<C, I, CoinInfo<I>>>\n  tokenBProps?: Partial<InputButtonProps<C, I, CoinInfo<I>>>\n  ammCalcData: ACD\n}\nexport type AmmDepositWrapProps<T, I, ACD, C> = AmmDepositBaseProps<T, I> &\n  AmmDepositExtendProps<T, I, C, ACD> & {\n    ammData: T\n    coinAPrecision?: number\n    coinBPrecision?: number\n  }\n\nexport type AmmWithdrawBaseProps<T, I> = {\n  ammWithdrawBtnStatus?: keyof typeof TradeBtnStatus | undefined\n  onAmmRemoveClick: (AmmSendData: T) => void | any\n  ammWithdrawBtnI18nKey?: string\n  anchors?: number[]\n  propsLPExtends?: Partial<InputButtonProps<T, I, unknown>>\n} & Partial<Pick<InputButtonProps<T, I, unknown>, 'handleError'>>\nexport type AmmWithdrawExtendProps<T, I, C, ACD> = {\n  disabled?: boolean\n  isStob?: boolean\n  switchStobEvent?: (_isStoB: boolean) => void\n  onRemoveChangeEvent: (data: AmmWithdrawChgData<T>) => void\n  tokenLPProps?: Partial<InputButtonProps<C, I, CoinInfo<I>>>\n  ammCalcData: ACD\n}\nexport type AmmWithdrawWrapProps<T, I, ACD, C> = AmmWithdrawBaseProps<T, I> &\n  AmmWithdrawExtendProps<T, I, C, ACD> & {\n    ammData: T\n    selectedPercentage: number // anchor\n  }\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/AmmWrap/index.ts",
    "content": "// this is a private component, only used in panel component\n// please do not export this index to global\n// export * from './Interface'\nexport * from './Interface'\nexport * from './AmmDeposit'\nexport * from './AmmWithdraw'\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/AmmWrap/styled.ts",
    "content": "import styled from '@emotion/styled'\n\nexport const SvgStyled = styled.div`\n  & svg {\n    width: 24px;\n    height: 24px;\n  }\n`\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/BanxaConfirm.tsx",
    "content": "import { useTranslation } from 'react-i18next'\nimport { Box, Grid, Typography } from '@mui/material'\nimport {\n  EmptyValueTag,\n  FeeInfo,\n  IBData,\n  TOAST_TIME,\n  TradeBtnStatus,\n} from '@loopring-web/common-resources'\nimport {\n  BanxaViewProps,\n  Button,\n  FeeSelect,\n  Toast,\n  ToastType,\n} from '../../index'\nimport { useSettings } from '../../../stores'\nimport React from 'react'\n\nexport const BanxaConfirm = <T extends IBData<I>, I, C extends FeeInfo>({\n  tradeData,\n  onTransferClick,\n  disabled,\n  isFeeNotEnough,\n  handleFeeChange,\n  chargeFeeTokenList,\n  transferBtnStatus,\n  transferI18nKey,\n  feeInfo,\n  memo,\n  balanceNotEnough,\n  offBanxaValue,\n}: BanxaViewProps<T, I, C> & {\n  balanceNotEnough: {\n    isEnough: boolean\n    reason?: string\n  }\n}) => {\n  const { isMobile } = useSettings()\n  const { t } = useTranslation()\n  const [open, setOpen] = React.useState(false)\n  const [showFeeModal, setShowFeeModal] = React.useState(false)\n  const handleToggleChange = (value: C) => {\n    if (handleFeeChange) {\n      handleFeeChange(value)\n    }\n  }\n  const getDisabled = React.useMemo(() => {\n    return disabled || transferBtnStatus === TradeBtnStatus.DISABLED\n  }, [disabled, transferBtnStatus])\n  return (\n    <Grid\n      className={'confirm'}\n      container\n      paddingLeft={isMobile ? 2 : 5 / 2}\n      paddingRight={isMobile ? 2 : 5 / 2}\n      direction={'column'}\n      alignItems={'stretch'}\n      flex={1}\n      height={'100%'}\n      minWidth={240}\n      flexWrap={'nowrap'}\n      spacing={2}\n    >\n      <Grid item xs={12}>\n        <Box\n          display={'flex'}\n          flexDirection={'column'}\n          justifyContent={'center'}\n          alignItems={'center'}\n          marginBottom={2}\n        >\n          <Typography component={'h4'} variant={isMobile ? 'h4' : 'h3'} whiteSpace={'pre'}>\n            {t('labelL2toBanxaTitle')}\n          </Typography>\n        </Box>\n      </Grid>\n      <Grid item xs={12}>\n        <Typography color={'var(--color-text-third)'} variant={'body1'}>\n          {t('labelL2toL2TokenAmount')}\n        </Typography>\n        <Typography color={'textPrimary'} marginTop={1} variant={'body1'}>\n          {tradeData?.tradeValue + ' '}\n          {tradeData?.belong}\n        </Typography>\n        {balanceNotEnough.isEnough && (\n          <Typography\n            color={'var(--color-error)'}\n            variant={'body2'}\n            marginTop={1 / 4}\n            alignSelf={'stretch'}\n            position={'relative'}\n          >\n            {t(\n              // @ts-ignore\n              balanceNotEnough?.reason == 1 ? 'labelBanxaFeeNoBalance' : 'labelRampNoBalance',\n              { belong: tradeData?.belong },\n            )}\n          </Typography>\n        )}\n      </Grid>\n      <Grid item xs={12}>\n        <Typography color={'var(--color-text-third)'} variant={'body1'}>\n          {t('labelFiatAmount')}\n        </Typography>\n        <Typography color={'textPrimary'} marginTop={1} variant={'body1'}>\n          {offBanxaValue?.fiat_amount + ' ' + offBanxaValue?.fiat_code}\n        </Typography>\n      </Grid>\n      <Grid item xs={12}>\n        <Typography color={'var(--color-text-third)'} variant={'body1'}>\n          {t('labelL2toL2AddressType')}\n        </Typography>\n        <Typography color={'textPrimary'} marginTop={1} variant={'body1'}>\n          {t('labelWalletTypeOptions', { type: 'Banxa' })}\n        </Typography>\n      </Grid>\n\n      <Grid item xs={12}>\n        <Typography color={'var(--color-text-third)'} variant={'body1'}>\n          {t('labelMemo')}\n        </Typography>\n        <Typography color={'textPrimary'} marginTop={1} variant={'body1'}>\n          {memo ?? EmptyValueTag}\n        </Typography>\n      </Grid>\n\n      <Grid item xs={12} alignSelf={'stretch'} position={'relative'}>\n        {!chargeFeeTokenList?.length ? (\n          <Typography>{t('labelFeeCalculating')}</Typography>\n        ) : (\n          <>\n            <FeeSelect\n              chargeFeeTokenList={chargeFeeTokenList}\n              handleToggleChange={(fee: FeeInfo) => {\n                handleToggleChange(fee as C)\n                setShowFeeModal(false)\n              }}\n              feeInfo={feeInfo as FeeInfo}\n              open={showFeeModal}\n              onClose={() => {\n                setShowFeeModal(false)\n              }}\n              isFeeNotEnough={isFeeNotEnough.isFeeNotEnough}\n              feeLoading={isFeeNotEnough.isOnLoading}\n              onClickFee={() => setShowFeeModal((prev) => !prev)}\n            />\n          </>\n        )}\n      </Grid>\n\n      <Grid item marginTop={2} alignSelf={'stretch'} paddingBottom={0}>\n        <Button\n          fullWidth\n          variant={'contained'}\n          size={'medium'}\n          color={'primary'}\n          onClick={async () => {\n            if (onTransferClick) {\n              await onTransferClick({ ...tradeData, memo } as unknown as T)\n            } else {\n              setOpen(true)\n            }\n          }}\n          loading={!getDisabled && transferBtnStatus === TradeBtnStatus.LOADING ? 'true' : 'false'}\n          disabled={getDisabled || transferBtnStatus === TradeBtnStatus.LOADING}\n        >\n          {t(transferI18nKey ?? `labelConfirm`)}\n        </Button>\n      </Grid>\n      <Toast\n        alertText={t('errorBase', { ns: 'error' })}\n        open={open}\n        autoHideDuration={TOAST_TIME}\n        onClose={() => {\n          setOpen(false)\n        }}\n        severity={ToastType.error}\n      />\n    </Grid>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/BasicACoinInput.tsx",
    "content": "import { CoinInfo, CoinMap, IBData } from '@loopring-web/common-resources'\nimport { WithTranslation } from 'react-i18next'\nimport React from 'react'\nimport { BasicACoinInputProps } from './Interface'\nimport { InputCoin, InputCoinProps } from '../../basic-lib'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nexport const BasicACoinInput = <T extends Partial<IBData<I>>, I>({\n  t,\n  tradeData,\n  onChangeEvent,\n  coinMap,\n  walletMap,\n  disabled,\n  handleError,\n  inputCoinRef,\n  inputCoinProps,\n  inputCoinDefaultProps,\n  className,\n  tokenNotEnough = 'tokenNotEnough',\n  ...rest\n}: BasicACoinInputProps<T, I> & WithTranslation) => {\n  const getDisabled = () => {\n    if (disabled || tradeData === undefined || walletMap === undefined || coinMap === undefined) {\n      return true\n    } else {\n      return false\n    }\n  }\n  const handleOnClick = React.useCallback(\n    (_event: React.MouseEvent, _ref: any) => {\n      onChangeEvent(1, {\n        tradeData: { ...tradeData, tradeValue: 0 },\n        to: 'menu',\n      })\n    },\n    [tradeData, onChangeEvent],\n  )\n  const handleCountChange: any = React.useCallback(\n    (_tradeData: T, _name: string, _ref: any) => {\n      //const focus: 'buy' | 'sell' = _ref?.current === buyRef.current ? 'buy' : 'sell';\n      if (tradeData.tradeValue !== _tradeData.tradeValue) {\n        onChangeEvent(0, {\n          tradeData: { ...tradeData, ..._tradeData },\n          to: 'button',\n        })\n      }\n\n      // onCoinValueChange(ibData);\n    },\n    [onChangeEvent, tradeData],\n  )\n\n  if (typeof handleError !== 'function') {\n    handleError = ({ belong, balance, tradeValue }: T) => {\n      const minimum = inputCoinProps?.minimum ?? inputCoinDefaultProps?.minimum\n      const maxValue = inputCoinProps?.maxValue\n      if (\n        (typeof tradeValue !== 'undefined' && balance && balance < tradeValue) ||\n        (tradeValue && !balance)\n      ) {\n        return {\n          error: true,\n          message: t(tokenNotEnough, { belong: belong }),\n        }\n      } else if (\n        typeof tradeValue !== 'undefined' &&\n        minimum !== undefined &&\n        tradeValue < Number(minimum)\n      ) {\n        return {\n          error: true,\n          message: t('errorMinError', {\n            value: minimum,\n            ns: ['error', 'common'],\n          }),\n        }\n      } else if (\n        typeof tradeValue !== 'undefined' &&\n        maxValue !== undefined &&\n        sdk.toBig(tradeValue).gt(maxValue)\n      ) {\n        return {\n          error: true,\n          message: t('errorMaxError', {\n            value: maxValue,\n            ns: ['error', 'common'],\n          }),\n        }\n      }\n      return { error: false, message: '' }\n    }\n  }\n\n  const _inputCoinProps: InputCoinProps<T, CoinInfo<I>, I> = {\n    subLabel: t('tokenMax'),\n    emptyText: t('tokenSelectToken'),\n    placeholderText: '0.00',\n    maxAllow: true,\n    order: 'right',\n    handleError: handleError as any,\n    handleCountChange,\n    handleOnClick,\n    label: t('labelInput'),\n    ...inputCoinDefaultProps,\n    ...inputCoinProps,\n    ...rest,\n  } as InputCoinProps<T, CoinInfo<I>, I>\n\n  return (\n    <InputCoin\n      ref={inputCoinRef}\n      isShowCoinIcon={true}\n      disabled={getDisabled()}\n      className={className}\n      {...{\n        ...(_inputCoinProps as any),\n        inputData: tradeData ? tradeData : ({} as T),\n        coinMap: coinMap ? coinMap : ({} as CoinMap<I, CoinInfo<I>>),\n      }}\n    />\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/BasicACoinTrade.tsx",
    "content": "import { CoinInfo, CoinMap, IBData } from '@loopring-web/common-resources'\nimport { WithTranslation } from 'react-i18next'\nimport React from 'react'\nimport { BasicACoinTradeProps } from './Interface'\nimport { InputButton, InputButtonProps, InputMaxButton } from '../../basic-lib'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { getOptionalDecimal } from '@loopring-web/core'\n\nexport const BasicACoinTrade = <T extends Partial<IBData<I>>, I>({\n  t,\n  tradeData,\n  onChangeEvent,\n  coinMap,\n  walletMap,\n  disabled,\n  inputButtonDefaultProps,\n  handleError,\n  inputBtnRef,\n  inputButtonProps,\n  className,\n  isMaxBtn = false,\n  tokenNotEnough = 'tokenNotEnough',\n  ...rest\n}: BasicACoinTradeProps<T, I> & WithTranslation) => {\n  const getDisabled = () => {\n    if (disabled || tradeData === undefined || walletMap === undefined || coinMap === undefined) {\n      return true\n    } else {\n      return false\n    }\n  }\n  const handleOnClick = React.useCallback(\n    (_event: React.MouseEvent, _ref: any) => {\n      onChangeEvent(1, {\n        tradeData: { ...tradeData, tradeValue: 0 },\n        to: 'menu',\n      })\n    },\n    [tradeData, onChangeEvent],\n  )\n  const handleCountChange: any = React.useCallback(\n    (_tradeData: T, _name: string, _ref: any) => {\n      //const focus: 'buy' | 'sell' = _ref?.current === buyRef.current ? 'buy' : 'sell';\n      if (tradeData.tradeValue !== _tradeData.tradeValue) {\n        onChangeEvent(0, {\n          tradeData: { ...tradeData, ..._tradeData },\n          to: 'button',\n        })\n      }\n\n      // onCoinValueChange(ibData);\n    },\n    [onChangeEvent, tradeData],\n  )\n\n  if (typeof handleError !== 'function') {\n    handleError = ({ belong, balance, tradeValue }: T) => {\n      const minimum = inputButtonProps?.minimum ?? inputButtonDefaultProps?.minimum\n      const maxValue = inputButtonProps?.maxValue\n      if (\n        (typeof tradeValue !== 'undefined' && balance && balance < tradeValue) ||\n        (getOptionalDecimal(tradeValue)?.gt('0') && !balance)\n      ) {\n        return {\n          error: true,\n          message: t(tokenNotEnough, { belong: belong }),\n        }\n      } else if (\n        typeof tradeValue !== 'undefined' &&\n        minimum !== undefined &&\n        tradeValue < Number(minimum)\n      ) {\n        return {\n          error: true,\n          message: t('errorMinError', {\n            value: minimum,\n            ns: ['error', 'common'],\n          }),\n        }\n      } else if (\n        typeof tradeValue !== 'undefined' &&\n        maxValue !== undefined &&\n        sdk.toBig(tradeValue).gt(maxValue)\n      ) {\n        return {\n          error: true,\n          message: t('errorMaxError', {\n            value: maxValue,\n            ns: ['error', 'common'],\n          }),\n        }\n      }\n      return { error: false, message: '' }\n    }\n  }\n\n  const inputBtnProps: InputButtonProps<T, CoinInfo<I>, I> = {\n    subLabel: t('tokenMax'),\n    emptyText: t('tokenSelectToken'),\n    placeholderText: '0.00',\n    maxAllow: true,\n    handleError: handleError as any,\n    handleCountChange,\n    handleOnClick,\n    label: t('labelInput'),\n    ...inputButtonDefaultProps,\n    ...inputButtonProps,\n    ...rest,\n  } as InputButtonProps<T, CoinInfo<I>, I>\n\n  return isMaxBtn ? (\n    <InputMaxButton\n      ref={inputBtnRef}\n      isShowCoinIcon={true}\n      disabled={getDisabled()}\n      className={className}\n      {...{\n        ...(inputBtnProps as any),\n        inputData: tradeData ? tradeData : ({} as T),\n        coinMap: coinMap ? coinMap : ({} as CoinMap<I, CoinInfo<I>>),\n      }}\n    />\n  ) : (\n    <InputButton\n      ref={inputBtnRef}\n      isShowCoinIcon={true}\n      disabled={getDisabled()}\n      className={className}\n      {...{\n        ...(inputBtnProps as any),\n        inputData: tradeData ? tradeData : ({} as T),\n        coinMap: coinMap ? coinMap : ({} as CoinMap<I, CoinInfo<I>>),\n      }}\n    />\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/BasicANFTTrade.tsx",
    "content": "import {\n  CoinInfo,\n  CoinMap,\n  IBData,\n  ImageIcon,\n  NFTWholeINFO,\n  TRADE_TYPE,\n} from '@loopring-web/common-resources'\nimport { Trans, useTranslation } from 'react-i18next'\nimport React, { ForwardedRef } from 'react'\nimport { BasicANFTTradeProps } from './Interface'\nimport {\n  InputButton,\n  InputButtonProps,\n  InputCoin,\n  InputCoinProps,\n  InputSize,\n} from '../../basic-lib'\nimport { Avatar, Box, Typography } from '@mui/material'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport styled from '@emotion/styled'\n\nconst BoxInput = styled(Box)`\n  & .main-label {\n    color: var(--color-text-secondary);\n    font-size: ${({ theme }) => theme.fontDefault.body1};\n  }\n` as typeof Box\nexport const _BasicANFTTrade = <T extends IBData<I> & Partial<NFTWholeINFO>, I extends any>(\n  {\n    tradeData,\n    onChangeEvent,\n    disabled,\n    isBalanceLimit,\n    handleError: _handleError,\n    inputNFTRef,\n    baseURL,\n    getIPFSString,\n    inputNFTProps,\n    inputNFTDefaultProps,\n    // isSelected = false,\n    // isRequired = false,\n    isThumb,\n    ...rest\n  }: BasicANFTTradeProps<T, I>,\n  _ref: ForwardedRef<any>,\n) => {\n  const { t } = useTranslation('common')\n  const getDisabled = () => {\n    return disabled || tradeData === undefined\n  }\n\n  const handleCountChange: any = React.useCallback(\n    (_tradeData: T, _name: string, _ref: any) => {\n      //const focus: 'buy' | 'sell' = _ref?.current === buyRef.current ? 'buy' : 'sell';\n      if ((tradeData as T)?.tradeValue !== _tradeData.tradeValue) {\n        onChangeEvent &&\n          onChangeEvent(0, {\n            tradeData: { ...tradeData, ..._tradeData },\n            to: 'button',\n          })\n      }\n    },\n    [onChangeEvent, tradeData],\n  )\n  const handleOnClick = React.useCallback(\n    (_event: React.MouseEvent, _ref: any) => {\n      onChangeEvent(1, {\n        tradeData: { ...tradeData, tradeValue: 0 },\n        to: 'menu',\n      })\n    },\n    [tradeData, onChangeEvent],\n  )\n  let handleError: any\n  if (typeof _handleError !== 'function') {\n    handleError = ({ balance, tradeValue }: T) => {\n      if (\n        (isBalanceLimit &&\n          balance &&\n          typeof tradeValue !== 'undefined' &&\n          isBalanceLimit &&\n          sdk.toBig(balance).lt(tradeValue)) ||\n        (typeof tradeValue !== 'undefined' && Number(tradeValue) < 1)\n      ) {\n        return {\n          error: true,\n          message: t('tokenNotEnough', { belong: 'NFT' }),\n        }\n      }\n      return { error: false, message: '' }\n    }\n  } else {\n    handleError = _handleError\n  }\n  const CoinIconElement =\n    isThumb && tradeData?.nftData ? (\n      tradeData?.image ? (\n        <img\n          alt={tradeData?.belong ? tradeData?.belong : 'NFT'}\n          width={'100%'}\n          height={'100%'}\n          src={getIPFSString(tradeData.image, baseURL)}\n        />\n      ) : (\n        <Avatar\n          sx={{\n            bgcolor: 'var(--color-border-disable2)',\n            width: '100%',\n            height: '100%',\n          }}\n          variant={'circular'}\n        >\n          <ImageIcon />\n        </Avatar>\n      )\n    ) : undefined\n  const noSelectElement = React.useMemo(() => {\n    const inputCoinProps: InputCoinProps<T, I, CoinInfo<I>> = {\n      subLabel: t('labelAvailable'),\n      placeholderText: '0',\n      decimalsLimit: 0,\n      allowDecimals: false,\n      isHideError: true,\n      isShowCoinInfo: !!isThumb,\n      isShowCoinIcon: false,\n      CoinIconElement,\n      order: 'right',\n      noBalance: '0',\n      // coinLabelStyle ,\n      coinPrecision: 0,\n      maxAllow: isBalanceLimit,\n      handleError: handleError as any,\n      handleCountChange,\n      ...inputNFTDefaultProps,\n      ...inputNFTProps,\n      ...rest,\n    } as InputCoinProps<T, I, CoinInfo<I>>\n    return (\n      <InputCoin<T, I, CoinInfo<I>>\n        ref={inputNFTRef}\n        disabled={getDisabled()}\n        {...{\n          ...inputCoinProps,\n          inputData: tradeData\n            ? {\n                ...tradeData,\n                belong: tradeData?.belong ? tradeData?.belong : 'NFT',\n              }\n            : ({} as T),\n          coinMap: {} as CoinMap<I, CoinInfo<I>>,\n        }}\n      />\n    )\n  }, [\n    tradeData,\n    getDisabled,\n    isBalanceLimit,\n    handleError,\n    inputNFTRef,\n    inputNFTProps,\n    inputNFTDefaultProps,\n    rest?.isSelected,\n  ])\n  const chooseElement = React.useMemo(() => {\n    const inputBtnProps: InputButtonProps<T, any, I> = {\n      subLabel: t('labelAvailable'),\n      emptyText: t('labelChooseNFT'),\n      placeholderText: '0',\n      decimalsLimit: 0,\n      allowDecimals: false,\n      CoinIconElement,\n      order: 'right',\n      noBalance: '0',\n      coinPrecision: 0,\n      maxAllow: isBalanceLimit,\n      handleError: handleError as any,\n      handleCountChange,\n      handleOnClick: handleOnClick as any,\n      ...inputNFTDefaultProps,\n\n      ...inputNFTProps,\n      ...rest,\n    } as InputButtonProps<T, any, I>\n    return (\n      <InputButton\n        ref={inputNFTRef}\n        disabled={getDisabled()}\n        fullwidth={true}\n        {...{\n          ...inputBtnProps,\n          inputData: tradeData\n            ? {\n                ...tradeData,\n                belong: tradeData?.belong ? tradeData?.belong : t('tokenSelectNFTToken'),\n              }\n            : ({} as T),\n          coinMap: {} as CoinMap<I, CoinInfo<I>>,\n        }}\n      />\n    )\n  }, [\n    tradeData,\n    getDisabled,\n    isBalanceLimit,\n    handleError,\n    inputNFTRef,\n    inputNFTProps,\n    inputNFTDefaultProps,\n    rest?.isSelected,\n  ])\n  return <>{rest?.isSelected ? chooseElement : noSelectElement}</>\n}\nexport const BasicANFTTrade = React.memo(React.forwardRef(_BasicANFTTrade)) as <\n  T extends IBData<I> & Partial<NFTWholeINFO>,\n  I extends any,\n>(\n  props: BasicANFTTradeProps<T, I>,\n  ref: ForwardedRef<any>,\n) => JSX.Element\n\nexport const NFTInput = React.memo(\n  <T extends IBData<I> & Partial<NFTWholeINFO>, I extends any>({\n    isThumb,\n    tradeData,\n    isBalanceLimit = true,\n    onCopy,\n    inputNFTDefaultProps,\n    inputNFTRef,\n    type,\n    disabled,\n    getIPFSString,\n    baseURL,\n    fullwidth,\n    ...rest\n  }: BasicANFTTradeProps<T, I> & {\n    onCopy?: (content: string) => Promise<void>\n    type?: TRADE_TYPE.NFT\n  }) => {\n    const { t } = useTranslation('common')\n    return (\n      <>\n        {isThumb ? (\n          <Box\n            display={'inline-flex'}\n            alignItems={'center'}\n            justifyContent={'space-between'}\n            height={'auto'}\n            width={'100%'}\n          >\n            <BasicANFTTrade\n              {...{\n                ...rest,\n                t,\n                isThumb,\n                type,\n                baseURL,\n                fullwidth,\n                getIPFSString,\n                disabled,\n                walletMap: {},\n                tradeData,\n                isBalanceLimit,\n                inputNFTDefaultProps: {\n                  label: rest?.isSelected ? (\n                    <Typography\n                      component={'span'}\n                      variant={'body1'}\n                      color={'textSecondary'}\n                      className={'main-label'}\n                      paddingBottom={1 / 2}\n                      display={'inline-flex'}\n                      height={24}\n                      lineHeight={24}\n                      alignItems={'center'}\n                    >\n                      {inputNFTDefaultProps?.label ? (\n                        inputNFTDefaultProps?.label\n                      ) : (\n                        <Trans\n                          i18nKey={'labelChooseNFT'}\n                          tOptions={{\n                            required: rest?.isRequired ? '\\uFE61' : '',\n                          }}\n                        >\n                          Choose NFT\n                          <Typography component={'span'} variant={'inherit'} color={'error'}>\n                            {'\\uFE61'}\n                          </Typography>\n                        </Trans>\n                      )}\n                    </Typography>\n                  ) : (\n                    <Typography\n                      variant={'body1'}\n                      component={'span'}\n                      color={'var(--color-text-secondary)'}\n                      className={'main-label'}\n                      paddingBottom={1 / 2}\n                    >\n                      {t(\n                        typeof inputNFTDefaultProps?.label === 'string'\n                          ? inputNFTDefaultProps?.label\n                          : 'labelNFTTitle',\n                      )}\n                    </Typography>\n                  ),\n                },\n                inputNFTRef,\n                ...(typeof rest?.isSelected !== undefined\n                  ? ({\n                      isSelected: rest?.isSelected,\n                      isRequired: !!rest?.isRequired,\n                      // handleOnChoose,\n                    } as any)\n                  : {}),\n              }}\n            />\n          </Box>\n        ) : (\n          <BoxInput>\n            <BasicANFTTrade\n              isThumb={isThumb}\n              {...{\n                ...rest,\n                type,\n                t,\n                disabled,\n                walletMap: {},\n                tradeData,\n                inputNFTDefaultProps: {\n                  ...{ size: InputSize.small, label: t('labelTokenAmount') },\n                  ...(inputNFTDefaultProps as any),\n                },\n                getIPFSString,\n                baseURL,\n                isBalanceLimit,\n                inputNFTRef,\n              }}\n            />\n          </BoxInput>\n        )}\n      </>\n    )\n  },\n) as <T extends IBData<I> & Partial<NFTWholeINFO>, I extends any>(\n  props: BasicANFTTradeProps<T, I> & {\n    onCopy?: (content: string) => Promise<void>\n    type?: TRADE_TYPE.NFT\n  },\n) => JSX.Element\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/CollectionAdvanceWrap.tsx",
    "content": "import { Trans, useTranslation } from 'react-i18next'\nimport { bindPopper, usePopupState } from 'material-ui-popup-state/hooks'\nimport React, { useState } from 'react'\nimport { Box, Grid, Typography } from '@mui/material'\nimport {\n  CollectionMeta,\n  CollectionMetaJSON,\n  copyToClipBoard,\n  Info2Icon,\n  TOAST_TIME,\n  TradeBtnStatus,\n} from '@loopring-web/common-resources'\nimport { bindHover } from 'material-ui-popup-state/es'\nimport { Button, PopoverPure, TextareaAutosizeStyled } from '../../basic-lib'\nimport { CollectionAdvanceProps } from '../Interface'\nimport styled from '@emotion/styled'\nimport { useSettings } from '../../../stores'\nimport { Toast, ToastType } from '../../toast'\n\nconst GridStyle = styled(Grid)`\n  .coinInput-wrap {\n    border: 1px solid var(--color-border);\n  }\n\n  .MuiInputLabel-root {\n    font-size: ${({ theme }) => theme.fontDefault.body2};\n  }\n` as typeof Grid\nexport const CollectionAdvanceWrap = <T extends Partial<CollectionMeta>>({\n  handleDataChange,\n  btnInfo,\n  btnStatus,\n  disabled = false,\n  allowTrade,\n  metaData,\n  onSubmitClick,\n}: CollectionAdvanceProps<T>) => {\n  const { t } = useTranslation(['common'])\n  const { isMobile } = useSettings()\n  const styles = isMobile\n    ? { flex: 1, width: 'var(--swap-box-width)' }\n    : { width: 'var(--modal-width)' }\n  const [copyToastOpen, setCopyToastOpen] = useState({\n    isShow: false,\n    type: 'json',\n  })\n  const popupState = usePopupState({\n    variant: 'popover',\n    popupId: `popupId-nftMint`,\n  })\n  const getDisabled = React.useMemo(() => {\n    return disabled || allowTrade.collectionNFT === true || btnStatus === TradeBtnStatus.DISABLED\n  }, [disabled, btnStatus])\n  // @ts-ignore\n  return (\n    <GridStyle\n      // className={walletMap ? \"\" : \"loading\"}\n      style={styles}\n      paddingBottom={3}\n      container\n      paddingLeft={5 / 2}\n      paddingRight={5 / 2}\n      direction={'column'}\n      justifyContent={'space-between'}\n      alignItems={'center'}\n      flex={1}\n      height={'100%'}\n    >\n      <Grid item>\n        <Box\n          display={'flex'}\n          flexDirection={'row'}\n          justifyContent={'center'}\n          alignItems={'center'}\n          marginBottom={2}\n        >\n          <Typography component={'h4'} variant={'h3'} marginRight={1}>\n            {t('labelCollectionMetaTitle')}\n          </Typography>\n          <Info2Icon\n            {...bindHover(popupState)}\n            fontSize={'large'}\n            htmlColor={'var(--color-text-third)'}\n          />\n        </Box>\n        <PopoverPure\n          className={'arrow-center'}\n          {...bindPopper(popupState)}\n          anchorOrigin={{\n            vertical: 'bottom',\n            horizontal: 'center',\n          }}\n          transformOrigin={{\n            vertical: 'top',\n            horizontal: 'center',\n          }}\n        >\n          <Typography padding={2} component={'p'} variant={'body2'} whiteSpace={'pre-line'}>\n            This is a quick way to import Collection metaData information, please make sure the\n            metaData json include name & tileUri\n          </Typography>\n        </PopoverPure>\n      </Grid>\n      <Typography\n        component={'span'}\n        display={'flex'}\n        alignItems={'center'}\n        alignSelf={'flex-start'}\n        marginBottom={1}\n        color={'textSecondary'}\n        variant={'body2'}\n      >\n        <Trans i18nKey={'labelCollectionAdvanceJSON'}>\n          NFT Collection information follow this format\n        </Trans>\n        <Typography\n          variant={'inherit'}\n          color={'var(--color-primary)'}\n          marginLeft={1}\n          onClick={() => {\n            const metaDemo: Partial<CollectionMetaJSON> = {\n              banner_uri: 'ipfs://`${cid  (storage image type media)}`',\n              avatar_uri: 'ipfs://`${cid  (storage image type media)}`',\n              tile_uri: 'ipfs://`${cid  (storage image type media)}`',\n              name: '`${COLLECTION_NAME (string, required)}`',\n              description: '`${COLLECTION_DESCRIPTION}`',\n            }\n            copyToClipBoard(JSON.stringify(metaDemo))\n            setCopyToastOpen({ isShow: true, type: 'json' })\n          }}\n        >\n          {t('labelCopyDemo')}\n        </Typography>\n      </Typography>\n      <TextareaAutosizeStyled\n        minRows={15}\n        maxRows={20}\n        style={{\n          overflowX: 'hidden',\n          resize: 'vertical',\n          width: '100%',\n        }}\n        placeholder={`Please input a validate JSON format collection metadata information, name and tileUri is required.`}\n        onChange={(_event) => {\n          const value = _event.target.value\n          handleDataChange(value ?? '')\n        }}\n        value={metaData}\n      />\n      <Grid item marginTop={3} alignSelf={'stretch'}>\n        <Button\n          fullWidth\n          variant={'contained'}\n          size={'medium'}\n          color={'primary'}\n          onClick={async () => {\n            await onSubmitClick()\n          }}\n          loading={!getDisabled && btnStatus === TradeBtnStatus.LOADING ? 'true' : 'false'}\n          disabled={getDisabled || btnStatus === TradeBtnStatus.LOADING}\n        >\n          {btnInfo\n            ? t(btnInfo.label, { ns: ['error', 'common'], ...btnInfo.params })\n            : t(`labelCollectionCreatBtn`)}\n        </Button>\n      </Grid>\n      <Toast\n        alertText={\n          copyToastOpen.type === 'json'\n            ? t('labelCopyMetaClip')\n            : copyToastOpen.type === 'url'\n            ? t('labelCopyUrlClip')\n            : t('labelCopyAddClip')\n        }\n        open={copyToastOpen.isShow}\n        autoHideDuration={TOAST_TIME}\n        onClose={() => {\n          setCopyToastOpen({ isShow: false, type: '' })\n        }}\n        severity={ToastType.success}\n      ></Toast>\n    </GridStyle>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/CollectionManageWrap.tsx",
    "content": "import { useTranslation } from 'react-i18next'\nimport React from 'react'\nimport { Box, Tab, Tabs, Tooltip, Typography } from '@mui/material'\n\nimport { useOpenModals, useSettings } from '../../../stores'\nimport {\n  CollectionMeta,\n  EmptyValueTag,\n  Info2Icon,\n  NFTWholeINFO,\n  TOAST_TIME,\n} from '@loopring-web/common-resources'\nimport { Button, NFTList } from '../../basic-lib'\nimport { CollectionManageProps, CollectionMethod } from './Interface'\nimport styled from '@emotion/styled'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { Toast, ToastType } from '../../toast'\nimport { sanitize } from 'dompurify'\n\nconst BoxStyle = styled(Box)`\n  .nft-list-wrap {\n    padding: 0 0;\n  }\n`\nexport const CollectionManageWrap = <Co extends CollectionMeta, NFT extends Partial<NFTWholeINFO>>({\n  onNFTSelected,\n  onFilterNFT,\n  collection,\n  filter,\n  baseURL,\n  listNFT,\n  total,\n  toastObj,\n  page,\n  isLoading,\n  selectedNFTS = [],\n  getIPFSString,\n  onNFTSelectedMethod,\n}: CollectionManageProps<Co, NFT>) => {\n  const { t } = useTranslation(['common'])\n  const { isMobile } = useSettings()\n  const [tab, setTab] = React.useState<sdk.LegacyNFT | 'all'>(sdk.LegacyNFT.undecided)\n\n  const handleTabChange = React.useCallback(\n    (_e, value) => {\n      let _filter = { ...filter }\n      setTab(value)\n      switch (value) {\n        case 'all':\n          if (tab === 'all') {\n            return\n          }\n          _filter = { ...filter, legacyFilter: 'all', page: 1 }\n          break\n        case sdk.LegacyNFT.undecided:\n          if (tab === sdk.LegacyNFT.undecided) {\n            return\n          }\n          _filter = {\n            ...filter,\n            legacyFilter: sdk.LegacyNFT.undecided,\n            page: 1,\n          }\n          break\n        case sdk.LegacyNFT.outside:\n          if (tab === sdk.LegacyNFT.outside) {\n            return\n          }\n          _filter = { ...filter, legacyFilter: sdk.LegacyNFT.outside, page: 1 }\n          break\n        case sdk.LegacyNFT.inside:\n          if (tab === sdk.LegacyNFT.inside) {\n            return\n          }\n          _filter = { ...filter, legacyFilter: sdk.LegacyNFT.inside, page: 1 }\n          break\n      }\n      onFilterNFT({ ..._filter })\n    },\n    [filter, onFilterNFT],\n  )\n  const { setNFTMetaNotReady } = useOpenModals()\n\n  const Btn = React.useMemo(() => {\n    switch (tab) {\n      case sdk.LegacyNFT.undecided:\n        return (\n          <Button\n            disabled={!selectedNFTS?.length}\n            onClick={() => {\n              onNFTSelectedMethod(selectedNFTS, CollectionMethod.moveIn)\n            }}\n            variant={'contained'}\n            size={'small'}\n            sx={{ marginLeft: 1, height: 24, fontSize: '1.2rem' }}\n          >\n            {t('labelMoveIn', { symbol: t('labelImportCollectionMove') })}\n          </Button>\n        )\n      case sdk.LegacyNFT.outside:\n        return (\n          <Button\n            disabled={!selectedNFTS?.length}\n            onClick={() => {\n              onNFTSelectedMethod(selectedNFTS, CollectionMethod.moveOut)\n            }}\n            variant={'contained'}\n            size={'small'}\n            sx={{ marginLeft: 1, height: 24, fontSize: '1.2rem' }}\n          >\n            {t('labelMoveOut', { symbol: t('labelImportCollectionMove') })}\n          </Button>\n        )\n      case sdk.LegacyNFT.inside:\n        return (\n          <Button\n            disabled={!selectedNFTS?.length}\n            onClick={() => {\n              onNFTSelectedMethod(selectedNFTS, CollectionMethod.moveOut)\n            }}\n            variant={'contained'}\n            size={'small'}\n            sx={{ marginLeft: 1, height: 24, fontSize: '1.2rem' }}\n          >\n            {t('labelMoveOut', { symbol: t('labelImportCollectionMove') })}\n          </Button>\n        )\n      case 'all':\n        return <></>\n    }\n  }, [onNFTSelectedMethod, selectedNFTS, t, tab])\n  // @ts-ignore\n  return (\n    <Box\n      // className={walletMap ? \"\" : \"loading\"}\n      display={'flex'}\n      flex={1}\n      flexDirection={'column'}\n      alignItems={'stretch'}\n      width={'100%'}\n    >\n      {isMobile ? (\n        <Typography>\n          Sorry Mobile web is not support this feature, Please try it on website\n        </Typography>\n      ) : (\n        <Box\n          display={'flex'}\n          flex={1}\n          marginTop={2}\n          flexDirection={'column'}\n          alignItems={'stretch'}\n        >\n          <Typography display={'inline-flex'}>\n            <Typography color={'var(--color-text-third)'}>{t('labelNFTCollectionName')}</Typography>\n            <Typography\n              component={'pre'}\n              paddingLeft={1}\n              color={'var(--color-text-primary)'}\n              width={150}\n              overflow={'hidden'}\n              textOverflow={'ellipsis'}\n              dangerouslySetInnerHTML={{\n                __html: sanitize(collection?.name?.toString() ?? EmptyValueTag) ?? '',\n              }}\n            />\n          </Typography>\n\n          <Box\n            display={'flex'}\n            flexDirection={'row'}\n            justifyContent={'space-between'}\n            alignItems={'center'}\n            marginTop={1}\n          >\n            <Tabs\n              value={tab}\n              onChange={handleTabChange}\n              aria-label='Collection Manage Tab'\n              sx={{ marginLeft: -2 }}\n            >\n              {[sdk.LegacyNFT.undecided, sdk.LegacyNFT.outside, sdk.LegacyNFT.inside, 'all'].map(\n                (item) => {\n                  return (\n                    <Tab\n                      key={item.toString()}\n                      value={item.toString()}\n                      label={\n                        <Tooltip\n                          placement={'top'}\n                          title={t(`labelImportCollection${item}Des`).toString()}\n                        >\n                          <Typography\n                            component={'span'}\n                            display={'inline-flex'}\n                            alignItems={'center'}\n                          >\n                            <Info2Icon\n                              fontSize={'small'}\n                              htmlColor={'var(--color-text-secondary)'}\n                              sx={{ marginRight: 1 / 2 }}\n                            />\n\n                            {t(`labelImportCollection${item}`)}\n                          </Typography>\n                        </Tooltip>\n                      }\n                    />\n                  )\n                },\n              )}\n            </Tabs>\n            {tab !== 'all' && (\n              <Box display={'flex'} flexDirection={'row'} justifyContent={'flex-end'}>\n                <Button\n                  variant={'outlined'}\n                  size={'small'}\n                  sx={{ marginLeft: 1 }}\n                  onClick={() => {\n                    onNFTSelected('addAll')\n                  }}\n                >\n                  {t('labelSelectAll')}\n                </Button>\n                <Button\n                  variant={'outlined'}\n                  size={'small'}\n                  sx={{ marginLeft: 1 }}\n                  onClick={() => {\n                    onNFTSelected('removeAll')\n                  }}\n                >\n                  {t('labelCancelAll')}\n                </Button>\n                {Btn}\n              </Box>\n            )}\n          </Box>\n          <BoxStyle flex={1} display={'flex'}>\n            <NFTList\n              onPageChange={(page: number) => {\n                onFilterNFT({ ...filter, page })\n              }}\n              setNFTMetaNotReady={setNFTMetaNotReady}\n              isManage={false}\n              isSelectOnly={tab !== 'all'}\n              isMultipleSelect={tab !== 'all'}\n              getIPFSString={getIPFSString}\n              baseURL={baseURL}\n              nftList={listNFT}\n              isLoading={isLoading}\n              total={total}\n              page={page}\n              size={'small'}\n              selected={selectedNFTS}\n              onClick={async (_item) => {\n                if (tab !== 'all') {\n                  onNFTSelected(_item as NFT)\n                }\n              }}\n            />\n          </BoxStyle>\n        </Box>\n      )}\n      <Toast\n        alertText={toastObj.toastOpen?.content ?? ''}\n        severity={toastObj.toastOpen?.type ?? ToastType.success}\n        open={toastObj.toastOpen?.open ?? false}\n        autoHideDuration={TOAST_TIME}\n        onClose={toastObj.closeToast}\n      />\n    </Box>\n  )\n  // Undecided  12\n  // Others 100\n  // Current Collection 100\n  // All 1000\n  // Search\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/ContactSelection.tsx",
    "content": "import { Avatar, Box, InputAdornment, OutlinedInput, Typography } from '@mui/material'\nimport { SearchIcon, CloseIcon, SoursURL, hexToRGB } from '@loopring-web/common-resources'\nimport { useSettings } from '../../../stores'\nimport { useTheme } from '@emotion/react'\nimport styled from '@emotion/styled'\nimport React, { JSX } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { AddressTypeTag } from '../../basic-lib'\n\ntype SingleContactProps = {\n  editing: boolean\n  name: string\n  address: string\n  addressType?: (typeof sdk.AddressType)[sdk.AddressTypeKeys]\n  onSelect: (address: string) => void\n  hidden: boolean\n}\n\nconst AvatarContainer = styled(Box)`\n  background-color: white;\n  border-radius: 20px;\n  width: 40px;\n  height: 40px;\n`\nconst getInitials = (name: string) => {\n  let initials\n  const nameSplit = name.split(' ')\n  const nameLength = nameSplit.length\n  if (nameLength > 1) {\n    initials = nameSplit[0].substring(0, 1) + nameSplit[nameLength - 1].substring(0, 1)\n  } else if (nameLength === 1) {\n    initials = nameSplit[0].substring(0, 1)\n  } else return\n\n  return initials.toUpperCase()\n}\n// @ts-ignore\nexport const InitialNameAvatar = React.memo(\n  ({\n    name,\n    ...rest\n  }: {\n    name: string\n  } & any) => {\n    const theme = useTheme()\n    return (\n      <AvatarContainer {...rest}>\n        <Avatar\n          sx={{\n            bgcolor: hexToRGB(theme.colorBase.warning, 0.5),\n            color: theme.colorBase.warning,\n            fontSize: '16px',\n          }}\n        >\n          {getInitials(name)}\n        </Avatar>\n      </AvatarContainer>\n    )\n  },\n) as ({\n  name,\n  ...rest\n}: {\n  name: string\n} & any) => JSX.Element\n\nexport const SingleContact = (props: SingleContactProps) => {\n  const { editing, name, address, addressType, hidden, onSelect } = props\n\n  return (\n    <Box\n      style={{ cursor: 'pointer' }}\n      paddingY={2}\n      display={hidden ? 'none' : 'flex'}\n      justifyContent={'space-between'}\n      onClick={() => {\n        onSelect(address)\n      }}\n    >\n      <Box display={'flex'}>\n        <InitialNameAvatar name={name}></InitialNameAvatar>\n        <Box marginLeft={1}>\n          {editing ? (\n            <OutlinedInput size={'small'} value={name} />\n          ) : (\n            <>\n              <Typography component={'span'} display={'flex-inline'} paddingRight={1}>\n                {name}\n              </Typography>\n              <AddressTypeTag addressType={addressType} />\n            </>\n          )}\n          <Typography>{address}</Typography>\n        </Box>\n      </Box>\n    </Box>\n  )\n}\n\nconst CloseIconStyled = styled(CloseIcon)`\n  position: absolute;\n  top: 55%;\n  transform: translateY(-50%);\n  right: ${({ theme }) => theme.unit}px;\n  cursor: pointer;\n`\n\n// OutlinedInput\ntype ContactSelectionProps = {\n  onSelect: (address: string) => void\n  scrollHeight: string\n} & Pick<sdk.GetContactsResponse, 'contacts'>\nexport const ContactSelection = (props: ContactSelectionProps) => {\n  // const { t } = useTranslation();\n  const { onSelect, contacts, scrollHeight } = props\n  const { isMobile } = useSettings()\n  const theme = useTheme()\n  const [inputValue, setInputValue] = React.useState('')\n  const handleOnFiler = (value: string) => {\n    setInputValue(value)\n  }\n  const filterContacts = inputValue\n    ? contacts.filter((contact) => {\n        return (\n          contact.contactAddress.toLowerCase().includes(inputValue.toLowerCase()) ||\n          contact.contactName.toLowerCase().includes(inputValue.toLowerCase())\n        )\n      })\n    : contacts\n  const { t } = useTranslation()\n\n  const normalView = (\n    <>\n      <Box width={'100%'}>\n        <OutlinedInput\n          style={{\n            background: theme.colorBase.box,\n            borderColor: theme.colorBase.border,\n          }}\n          fullWidth\n          className={'search'}\n          aria-label={'search'}\n          placeholder={'Search'}\n          startAdornment={\n            <InputAdornment position='start'>\n              <SearchIcon color={'inherit'} />\n            </InputAdornment>\n          }\n          value={inputValue}\n          endAdornment={\n            <CloseIconStyled\n              htmlColor={'var(--color-text-third)'}\n              style={{ visibility: inputValue ? 'visible' : 'hidden' }}\n              onClick={() => {\n                handleOnFiler('')\n              }}\n            />\n          }\n          onChange={(e) => {\n            handleOnFiler(e.target.value)\n          }}\n        />\n        <Box sx={{overflowY: 'auto'}} height={scrollHeight}>\n          {filterContacts &&\n            filterContacts.map((contact) => {\n              return (\n                <SingleContact\n                  key={contact.contactAddress}\n                  name={contact.contactName}\n                  address={contact.contactAddress}\n                  addressType={contact.addressType}\n                  editing={false}\n                  onSelect={onSelect}\n                  hidden={contact.addressType === sdk.AddressType.OFFICIAL}\n                />\n              )\n            })}\n        </Box>\n      </Box>\n    </>\n  )\n  const loadingView = (\n    <Box height={'100%'} display={'flex'} justifyContent={'center'} alignItems={'center'}>\n      <img\n        className='loading-gif'\n        alt={'loading'}\n        width='36'\n        src={`${SoursURL}images/loading-line.gif`}\n      />\n    </Box>\n  )\n  const emptyView = (\n    <Box height={'100%'} display={'flex'} justifyContent={'center'} alignItems={'center'}>\n      <Typography color={'var(--color-text-third)'}>{t('labelContactsNoContact')}</Typography>\n    </Box>\n  )\n\n  return (\n    <Box\n      // container\n      paddingLeft={isMobile ? 2 : 3}\n      paddingRight={isMobile ? 2 : 3}\n      // fle direction={\"column\"}\n      alignItems={'stretch'}\n      flex={1}\n      height={'100%'}\n      flexWrap={'nowrap'}\n      // spacing={2}\n    >\n      <Box>\n        <Box\n          display={'flex'}\n          flexDirection={'column'}\n          justifyContent={'center'}\n          alignItems={'center'}\n          marginBottom={2}\n        >\n          <Typography\n            component={'h4'}\n            variant={isMobile ? 'h4' : 'h3'}\n            whiteSpace={'pre'}\n            marginRight={1}\n          >\n            {t('labelContactsSelectReciepient')}\n          </Typography>\n        </Box>\n      </Box>\n      {contacts === undefined ? loadingView : contacts.length === 0 ? emptyView : normalView}\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/CreateCollectionWrap.tsx",
    "content": "import { Box, FormLabel, Grid, Tooltip, Typography } from '@mui/material'\nimport React from 'react'\nimport {\n  BtnInfo,\n  Button,\n  ImageUploadWrapper,\n  IpfsFile,\n  IPFSSourceUpload,\n  TextareaAutosizeStyled,\n  TextField,\n} from '../../basic-lib'\nimport { Trans, useTranslation } from 'react-i18next'\nimport {\n  CollectionMeta,\n  GET_IPFS_STRING,\n  htmlDecode,\n  Info2Icon,\n  TradeBtnStatus,\n} from '@loopring-web/common-resources'\nimport { useSettings } from '../../../stores'\n\nexport type CreateCollectionViewProps<Co> = {\n  keys: { [key: string]: undefined | IpfsFile }\n  onFilesLoad: (key: string, value: IpfsFile) => void\n  onDelete: (key: string) => void\n  btnStatus: TradeBtnStatus\n  resetEdit?: () => void\n  btnInfo?: BtnInfo\n  isEdit?: boolean\n  disabled?: boolean\n  onSubmitClick: () => Promise<void>\n  handleOnDataChange: (key: string, value: any) => void\n  collectionValue: Co\n  getIPFSString: GET_IPFS_STRING\n  baseURL: string\n}\n\nexport const CreateCollectionWrap = <T extends Partial<CollectionMeta>>({\n  keys,\n  onFilesLoad,\n  onDelete,\n  btnStatus,\n  btnInfo,\n  isEdit,\n  resetEdit,\n  disabled,\n  handleOnDataChange,\n  collectionValue,\n  onSubmitClick,\n  getIPFSString,\n  baseURL,\n}: CreateCollectionViewProps<T>) => {\n  const { t } = useTranslation('common')\n  const getDisabled = React.useMemo(() => {\n    return disabled || btnStatus === TradeBtnStatus.DISABLED\n  }, [disabled, btnStatus])\n\n  const { isMobile } = useSettings()\n  return (\n    <ImageUploadWrapper\n      flex={1}\n      alignItems={'stretch'}\n      display={'flex'}\n      justifyContent={'center'}\n      flexDirection={'column'}\n      marginBottom={2}\n      padding={5 / 2}\n      maxWidth={680}\n    >\n      <Grid container flex={1} spacing={2}>\n        <Grid\n          item\n          xs={12}\n          position={'relative'}\n          display={'flex'}\n          flexDirection={isMobile ? 'column' : 'row'}\n          justifyContent={'space-between'}\n        >\n          <Box>\n            <Typography\n              component={'span'}\n              variant={'body1'}\n              display={'inline-flex'}\n              color={'var(--color-text-secondary)'}\n              marginBottom={1}\n            >\n              <Trans i18nKey={'labelTileUri'}>\n                Tile (Dimensions: 5:7)\n                <Typography component={'span'} variant={'inherit'} color={'error'}>\n                  {'\\uFE61'}\n                </Typography>\n              </Trans>\n            </Typography>\n            <Box width={isMobile ? '100%' : 180}>\n              <IPFSSourceUpload\n                typographyProps={{}}\n                buttonProps={{}}\n                height={'calc( 100% * 7 / 5)'}\n                getIPFSString={getIPFSString}\n                baseURL={baseURL}\n                buttonText={''}\n                value={keys?.tileUri ?? undefined}\n                onDelete={() => {\n                  onDelete('tileUri')\n                }}\n                onChange={(value) => {\n                  onFilesLoad('tileUri', value)\n                }}\n              />\n            </Box>\n          </Box>\n        </Grid>\n\n        <Grid\n          item\n          xs={12}\n          position={'relative'}\n          display={'flex'}\n          flexDirection={isMobile ? 'column' : 'row'}\n          justifyContent={'space-between'}\n        >\n          <Box marginBottom={isMobile ? '2' : '0'}>\n            <Typography\n              component={'h4'}\n              variant={'body1'}\n              textAlign={'left'}\n              marginBottom={1}\n              color={'var(--color-text-secondary)'}\n            >\n              {t('labelAvatar')}\n            </Typography>\n            <Box width={isMobile ? '100%' : 100}>\n              <IPFSSourceUpload\n                typographyProps={{}}\n                buttonProps={{}}\n                height={'100%'}\n                getIPFSString={getIPFSString}\n                baseURL={baseURL}\n                title={'labelAvatarDes'}\n                buttonText={''}\n                value={keys?.avatar ?? undefined}\n                onDelete={() => {\n                  onDelete('avatar')\n                }}\n                onChange={(value) => {\n                  onFilesLoad('avatar', value)\n                }}\n              />\n            </Box>\n          </Box>\n        </Grid>\n\n        <Grid item xs={12} position={'relative'}>\n          <Typography\n            component={'h4'}\n            variant={'body1'}\n            textAlign={'left'}\n            marginBottom={1}\n            color={'var(--color-text-secondary)'}\n          >\n            {t('labelBanner')}\n          </Typography>\n          <Box maxWidth={400}>\n            <IPFSSourceUpload\n              height={'calc( 100%/ 3)'}\n              typographyProps={{}}\n              buttonProps={{}}\n              getIPFSString={getIPFSString}\n              baseURL={baseURL}\n              buttonText={''}\n              value={keys?.banner ?? undefined}\n              onDelete={() => {\n                onDelete('banner')\n              }}\n              onChange={(value) => {\n                onFilesLoad('banner', value)\n              }}\n            />\n          </Box>\n        </Grid>\n        <Grid item xs={12} display={'flex'} flexDirection={'column'} position={'relative'}>\n          <Box display={'flex'} flexDirection={'column'} alignItems={'center'} marginBottom={2}>\n            <TextField\n              value={collectionValue?.name ? htmlDecode(collectionValue.name ?? '').toString() : ''}\n              inputProps={{ maxLength: 28 }}\n              fullWidth\n              label={\n                <Typography\n                  component={'span'}\n                  variant={'body1'}\n                  color={'var(--color-text-secondary)'}\n                  marginBottom={1}\n                >\n                  <Trans i18nKey={'labelCollectionName'}>\n                    Collection Name\n                    <Typography component={'span'} variant={'inherit'} color={'error'}>\n                      {'\\uFE61'}\n                    </Typography>\n                  </Trans>\n                </Typography>\n              }\n              type={'text'}\n              onChange={(e: React.ChangeEvent<{ value: string }>) =>\n                handleOnDataChange('name', e.target.value)\n              }\n            />\n          </Box>\n        </Grid>\n        <Grid item xs={12} display={'flex'} flexDirection={'column'} position={'relative'}>\n          <FormLabel>\n            <Tooltip\n              placement={'left-start'}\n              title={t('labelCollectionDescriptionTooltips').toString()}\n            >\n              <Typography\n                component={'h4'}\n                variant={'body1'}\n                textAlign={'left'}\n                marginBottom={1}\n                alignItems={'center'}\n                display={'inline-flex'}\n                color={'var(--color-text-secondary)'}\n              >\n                <Trans i18nKey={'labelCollectionDescription'}>\n                  Description\n                  <Info2Icon fontSize={'small'} color={'inherit'} sx={{ marginX: 1 / 2 }} />\n                </Trans>\n              </Typography>\n            </Tooltip>\n          </FormLabel>\n\n          <Box flex={1}>\n            <TextareaAutosizeStyled\n              aria-label='Description'\n              minRows={5}\n              value={\n                collectionValue?.description\n                  ? htmlDecode(collectionValue.description ?? '').toString()\n                  : ''\n              }\n              style={{\n                overflowX: 'hidden',\n                resize: 'vertical',\n                height: '100%',\n                margin: 0,\n              }}\n              maxLength={1000}\n              onChange={(event) => handleOnDataChange('description', event.target.value)}\n              draggable={true}\n            />\n          </Box>\n        </Grid>\n\n        <Grid item xs={12} display={'flex'} flexDirection={'row'} justifyContent={'space-between'}>\n          {isEdit && resetEdit && (\n            <Box width={'50%'} marginRight={1}>\n              <Button\n                variant={'outlined'}\n                size={'large'}\n                fullWidth\n                onClick={resetEdit}\n                // sx={{ marginRight: 1 }}\n                className={'MuiContained-sizeMedium'}\n              >\n                {t('labelEditRestCollectionBtn')}\n              </Button>\n            </Box>\n          )}\n          <Button\n            variant={'contained'}\n            size={'medium'}\n            color={'primary'}\n            fullWidth\n            loading={!getDisabled && btnStatus === TradeBtnStatus.LOADING ? 'true' : 'false'}\n            disabled={getDisabled || btnStatus === TradeBtnStatus.LOADING}\n            // disabled={isLoading ||}\n            onClick={() => {\n              onSubmitClick()\n            }}\n          >\n            {btnInfo\n              ? t(btnInfo.label, btnInfo.params)\n              : isEdit\n              ? t(`labelEditCollectionBtn`)\n              : t(`labelCollectionCreateBtn`)}\n          </Button>\n        </Grid>\n      </Grid>\n    </ImageUploadWrapper>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/CreateRedPacketWrap.tsx",
    "content": "import {\n  Box,\n  CardContent,\n  Checkbox,\n  FormControlLabel,\n  FormLabel,\n  Grid,\n  IconButton,\n  Tab,\n  Tooltip,\n  Typography,\n  // TextField as MuiTextField,\n} from '@mui/material'\nimport React from 'react'\nimport {\n  Button,\n  CardStyleItem,\n  InputButtonProps,\n  InputCoin,\n  InputSearch,\n  NftImageStyle,\n  Tabs,\n  TextField,\n} from '../../basic-lib'\nimport { useTranslation, WithTranslation, withTranslation, Trans } from 'react-i18next'\nimport {\n  BackIcon,\n  CoinInfo,\n  EmptyValueTag,\n  FeeInfo,\n  getValuePrecisionThousand,\n  IBData,\n  LuckyRedPacketItem,\n  REDPACKET_ORDER_LIMIT,\n  RedPacketOrderData,\n  SoursURL,\n  TradeBtnStatus,\n  REDPACKET_ORDER_NFT_LIMIT,\n  Info2Icon,\n  RedPacketOrderType,\n  ScopePublic,\n  HelpIcon,\n  TokenType,\n  CheckBoxIcon,\n  CheckedIcon,\n  YEAR_DAY_MINUTE_FORMAT,\n  ScopeQR,\n  ScopeTarget,\n  isAddress,\n  LuckyRedPacketList,\n  myLog,\n  BlindBoxIcon,\n  NormalRedpacketIcon,\n} from '@loopring-web/common-resources'\nimport { useSettings } from '../../../stores'\nimport {\n  CreateRedPacketViewProps,\n  RedPacketStep,\n  SwitchData,\n  TargetRedPacketStep,\n  TargetRedpacktInputAddressStepProps,\n  TargetRedpacktSelectStepProps,\n} from '../Interface'\nimport { MenuBtnStyled } from '../../styled'\nimport styled from '@emotion/styled'\nimport { BasicACoinTrade } from './BasicACoinTrade'\nimport { BtnMain } from './tool'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport moment from 'moment'\nimport { NFTInput } from './BasicANFTTrade'\nimport { DateTimeRangePicker } from '../../datetimerangepicker'\nimport BigNumber from 'bignumber.js'\nimport { CoinIcons, FeeSelect, InitialNameAvatar, Modal } from '../../../components'\nimport { useTheme } from '@emotion/react'\nimport { useHistory } from 'react-router'\nimport { TFunction } from 'i18next'\n\nconst StyledTextFiled = styled(TextField)``\n\nconst RedPacketBoxStyle = styled(Box)`\n  padding-top: ${({ theme }) => theme.unit}px;\n\n  .MuiFormGroup-root {\n    align-items: flex-start;\n  }\n\n  .coinInput-wrap {\n    border: 1px solid var(--color-border);\n  }\n\n  .MuiInputLabel-root {\n    font-size: ${({ theme }) => theme.fontDefault.body2};\n  }\n\n  .MuiButtonBase-root.step {\n    padding-left: ${({ theme }) => theme.unit * 4}px;\n    padding-right: ${({ theme }) => theme.unit * 4}px;\n  }\n\n  //width: 100%;\n  //display: flex;\n  textarea {\n    background: var(--field-opacity);\n    border-color: var(--opacity);\n\n    :hover {\n      border-color: var(--color-border-hover);\n    }\n  }\n`\n\nexport const CreateRedPacketStepWrap = withTranslation()(\n  <T extends Partial<RedPacketOrderData<I>>, I, F extends FeeInfo>({\n    btnStatus,\n    btnInfo,\n    disabled,\n    tradeType,\n    handleFeeChange,\n    handleOnDataChange,\n    onCreateRedPacketClick,\n    walletMap,\n    tradeData,\n    coinMap,\n    tokenMap,\n    isFeeNotEnough,\n    setActiveStep,\n    feeInfo,\n    chargeFeeTokenList,\n    lastFailed,\n    selectedType,\n    minimum,\n    maximum,\n    idIndex,\n    selectNFTDisabled,\n    redPacketConfig,\n    ...rest\n  }: CreateRedPacketViewProps<T, I, F> & {\n    selectedType: LuckyRedPacketItem\n  } & WithTranslation) => {\n    const { t } = useTranslation('common')\n\n    const inputButtonDefaultProps = {\n      label:\n        selectedType.value.partition == sdk.LuckyTokenAmountType.AVERAGE\n          ? t('labelAmountEach')\n          : t('labelRedPacketTotalAmount'),\n      decimalsLimit: (tokenMap && tokenMap[tradeData?.belong as string])?.precision ?? 8,\n      minimum,\n      placeholderText: tradeData?.belong\n        ? t('labelRedPacketsMinRange', { value: minimum }) +\n          (sdk.toBig(maximum ?? 0).lt(sdk.toBig(tradeData.balance ?? 0))\n            ? ' - ' + t('labelRedPacketsMaxRange', { value: maximum })\n            : '')\n        : '0.00',\n    }\n\n    const inputNFTButtonDefaultProps: Partial<InputButtonProps<T, I, CoinInfo<I>>> = {\n      label:\n        selectedType.value.partition == sdk.LuckyTokenAmountType.AVERAGE\n          ? t('labelAmountEach')\n          : t('labelRedPacketTotalAmount'),\n      decimalsLimit: 0,\n      minimum,\n      placeholderText: '0',\n    }\n    // const [dayValue, setDayValue] = React.useState<Moment | null>(moment());\n    // const [durationValue, setDurationValue] = React.useState<number>(1);\n\n    const getDisabled = React.useMemo(() => {\n      return disabled || btnStatus === TradeBtnStatus.DISABLED\n    }, [disabled, btnStatus])\n    const [showFeeModal, setShowFeeModal] = React.useState(false)\n    const inputBtnRef = React.useRef()\n    const inputSplitRef = React.useRef()\n    const isToken =\n      tradeType === RedPacketOrderType.TOKEN ||\n      (tradeType === RedPacketOrderType.BlindBox && !tradeData.isNFT)\n    const { total: redPacketTotalValue, splitValue } = React.useMemo(() => {\n      // if (tradeType == TRADE_TYPE.TOKEN) {\n      //\n      // } else {\n      //   const splitValue =\n      //     selectedType.value.value == 2\n      //       ? (tradeData?.tradeValue ?? 0) / (tradeData?.numbers ?? 1)\n      //       : tradeData?.tradeValue ?? 0;\n      //   return {\n      //     total: tradeData.tradeValue ?? EmptyValueTag,\n      //     splitValue: splitValue && EmptyValueTag,\n      //   };\n      // }\n      if (tradeData?.tradeValue && tradeData.belong && tokenMap) {\n        const splitValue =\n          selectedType.value.partition == sdk.LuckyTokenAmountType.RANDOM\n            ? sdk.toBig(tradeData?.tradeValue ?? 0).div(tradeData?.numbers ?? 1)\n            : sdk.toBig(tradeData?.tradeValue ?? 0)\n        const total =\n          selectedType.value.partition == sdk.LuckyTokenAmountType.AVERAGE\n            ? sdk.toBig(tradeData?.tradeValue ?? 0).times(tradeData?.numbers ?? 0)\n            : sdk.toBig(tradeData?.tradeValue ?? 0)\n        if (isToken) {\n          return {\n            total:\n              tokenMap[tradeData?.belong as string] &&\n              getValuePrecisionThousand(\n                total,\n                tokenMap[tradeData?.belong as string].precision,\n                tokenMap[tradeData?.belong as string].precision,\n                tokenMap[tradeData?.belong as string].precision,\n                false,\n                // { isFait: true }\n              ) +\n                ' ' +\n                tradeData.belong,\n            splitValue:\n              tokenMap[tradeData?.belong as string] &&\n              getValuePrecisionThousand(\n                splitValue,\n                tokenMap[tradeData?.belong as string].precision,\n                tokenMap[tradeData?.belong as string].precision,\n                tokenMap[tradeData?.belong as string].precision,\n                false,\n                // { isFait: true }\n              ) +\n                ' ' +\n                tradeData.belong,\n          }\n        } else {\n          return {\n            total:\n              getValuePrecisionThousand(\n                total,\n                0,\n                0,\n                1,\n                false,\n                // { isFait: true }\n              ) +\n              ' ' +\n              (total.gt(1) ? 'NFTs' : 'NFT'),\n            splitValue:\n              getValuePrecisionThousand(\n                splitValue.toFixed(0, 1),\n                0,\n                0,\n                1,\n                false,\n                // { isFait: true }\n              ) +\n              ' ' +\n              'NFT',\n          }\n        }\n      } else {\n        return {\n          total: EmptyValueTag,\n          splitValue:\n            selectedType.value.partition == sdk.LuckyTokenAmountType.AVERAGE && EmptyValueTag,\n        }\n      }\n    }, [tradeData, tradeData?.numbers, selectedType.value.partition, coinMap, tradeType])\n    const inputSplitProps = React.useMemo(() => {\n      const inputSplitProps: any = {\n        label:\n          selectedType.value.partition == sdk.LuckyTokenAmountType.AVERAGE\n            ? t('labelQuantity')\n            : t('labelSplit'), //t(\"labelTokenAmount\"),\n        placeholderText: t('labelQuantity'),\n        isHideError: true,\n        isShowCoinInfo: false,\n        handleCountChange: (ibData: IBData<any>, _name: string, _ref: any) => {\n          handleOnDataChange({\n            numbers: ibData.tradeValue,\n          } as unknown as Partial<T>)\n        },\n        fullWidth: true,\n      }\n      let inputSplitExtendProps = {},\n        balance: any = undefined\n      if (tradeData?.tradeValue && Number(tradeData?.tradeValue) && maximum) {\n        if (selectedType.value.partition === sdk.LuckyTokenAmountType.AVERAGE) {\n          balance = sdk\n            .toBig(tradeData?.balance ?? 0)\n            .div(tradeData.tradeValue)\n            .toFixed(0, 1)\n        } else {\n          balance = sdk\n            .toBig(tradeData.tradeValue)\n            .div(Number(minimum) ?? 1)\n            .toFixed(0, 1)\n        }\n\n        balance = sdk.toBig(balance).lte(REDPACKET_ORDER_LIMIT) ? balance : REDPACKET_ORDER_LIMIT\n\n        inputSplitExtendProps = {\n          // maxAllow: true,\n          // subLabel: t(\"labelAvailable\"),\n          // handleError: (data: any) => {\n          //   handleOnDataChange({\n          //     numbers: data.tradeValue,\n          //   } as unknown as Partial<T>);\n          //   if (data.tradeValue && data.tradeValue > data.balance) {\n          //     return {\n          //       error: true,\n          //     };\n          //   }\n          //   return {\n          //     error: false,\n          //   };\n          // },\n          inputData: {\n            belong:\n              selectedType.value.partition == sdk.LuckyTokenAmountType.AVERAGE\n                ? t('labelQuantity')\n                : t('labelSplit'),\n            tradeValue: tradeData?.numbers,\n            balance: balance,\n          },\n        }\n      } else {\n        inputSplitExtendProps = {\n          // maxAllow: false,\n          // subLabel: \"\",\n          // handleError: () => undefined,\n          inputData: {\n            belong:\n              selectedType.value.partition == sdk.LuckyTokenAmountType.AVERAGE\n                ? t('labelAmountEach')\n                : t('labelSplit'),\n            tradeValue: tradeData?.numbers,\n            // count: tradeData?.numbers,\n          },\n        }\n      }\n      return {\n        ...inputSplitProps,\n        ...inputSplitExtendProps,\n      }\n    }, [tradeData?.numbers, selectedType.value.partition, maximum, minimum, tradeType])\n    const handleToggleChange = (value: F) => {\n      if (handleFeeChange) {\n        handleFeeChange(value)\n      }\n    }\n    const _balance = React.useMemo(() => {\n      if (\n        tradeData.belong !== undefined &&\n        // tradeData?.numbers &&\n        // @ts-ignore\n        // tradeData.numbers !== \"0\" &&\n        tradeData.balance &&\n        tradeType === RedPacketOrderType.NFT\n      ) {\n        if (selectedType.value.partition == sdk.LuckyTokenAmountType.AVERAGE) {\n          const value = BigNumber.min(tradeData.balance, REDPACKET_ORDER_NFT_LIMIT).toString()\n          return sdk\n            .toBig(value)\n            .div(tradeData?.numbers && tradeData?.numbers != 0 ? tradeData?.numbers : 1)\n            .toFixed(0, 1)\n        } else {\n          return BigNumber.min(tradeData.balance, REDPACKET_ORDER_NFT_LIMIT).toString()\n        }\n      } else if (\n        selectedType.value.partition == sdk.LuckyTokenAmountType.AVERAGE &&\n        tradeData.belong !== undefined &&\n        tradeData?.numbers &&\n        // @ts-ignore\n        tradeData.numbers !== '0' &&\n        tradeData.balance\n      ) {\n        return sdk.toBig(tradeData.balance).div(tradeData.numbers).toString()\n      } else {\n        return tradeData.balance\n      }\n    }, [selectedType.value.partition, tradeData.balance, tradeData?.numbers])\n    const { isMobile } = useSettings()\n\n    const startDateTime = tradeData.validSince ? moment(tradeData.validSince) : null\n    const endDateTime = tradeData.validUntil ? moment(tradeData.validUntil) : null\n    const now = moment()\n\n    const startMinDateTime = endDateTime\n      ? moment.max(now, endDateTime.clone().subtract(7, 'days'))\n      : now\n    const startMaxDateTime = endDateTime ? endDateTime.clone() : now.clone().add(1, 'days')\n\n    const endMinDateTime = startDateTime ? moment.max(now, startDateTime.clone()) : now\n\n    const timeRangeMaxInSeconds = isToken\n      ? redPacketConfig.timeRangeMaxInSecondsToken\n      : redPacketConfig.timeRangeMaxInSecondsNFT\n    // ?? 14 * 24 * 60 * 60;\n    const endMaxDateTime = startDateTime\n      ? startDateTime.clone().add(timeRangeMaxInSeconds, 'seconds')\n      : undefined\n    // @ts-ignore\n    return (\n      <RedPacketBoxStyle className={'redPacket'} justifyContent={'center'}>\n        <Box marginY={1} display={'flex'}>\n          <Box\n            display={'flex'}\n            flexDirection={'row'}\n            justifyContent={'flex-start'}\n            alignItems={'center'}\n            marginBottom={1}\n          >\n            <Typography\n              component={'h4'}\n              variant={isMobile ? 'body1' : 'h5'}\n              whiteSpace={'pre'}\n              marginRight={1}\n            >\n              {t(\n                selectedType.value.mode == sdk.LuckyTokenClaimType.BLIND_BOX\n                  ? 'labelLuckyBlindBox'\n                  : selectedType.value.mode == sdk.LuckyTokenClaimType.RELAY\n                  ? 'labelRelayRedPacket'\n                  : selectedType.value.partition == sdk.LuckyTokenAmountType.AVERAGE\n                  ? 'labelRedPacketSendAverageTitle'\n                  : 'labelRedPacketSenRandomTitle',\n              ) +\n                ' — ' +\n                t(`labelRedPacketViewType${tradeData?.type?.scope ?? 0}`)}\n            </Typography>\n          </Box>\n        </Box>\n        <Box\n          marginY={1}\n          display={'flex'}\n          alignSelf={'stretch'}\n          position={'relative'}\n          flexDirection={'column'}\n        >\n          {isToken ? (\n            // @ts-ignore\n            <BasicACoinTrade\n              {...{\n                ...rest,\n                t,\n                type: 'TOKEN',\n                disabled,\n                walletMap,\n                tradeData:\n                  selectedType.value.partition == sdk.LuckyTokenAmountType.AVERAGE &&\n                  tradeData?.numbers\n                    ? {\n                        ...tradeData,\n                        balance: _balance,\n                      }\n                    : (tradeData as T),\n                coinMap,\n                inputButtonDefaultProps,\n                inputBtnRef,\n              }}\n            />\n          ) : (\n            <NFTInput\n              {...({\n                ...rest,\n                t,\n                fullwidth: true,\n                isThumb: true,\n                isSelected: true,\n                type: tradeType,\n                subLabel: t('labelTokenNFTMaxRedPack'),\n                disabled,\n                tradeData: {\n                  ...tradeData,\n                  balance:\n                    tradeData.type?.mode === sdk.LuckyTokenClaimType.BLIND_BOX\n                      ? Math.min(\n                          (tradeData.giftNumbers ?? 1) * REDPACKET_ORDER_NFT_LIMIT,\n                          tradeData.balance ?? 0,\n                        )\n                      : tradeData.type?.partition === sdk.LuckyTokenAmountType.AVERAGE\n                      ? Math.min(REDPACKET_ORDER_NFT_LIMIT, tradeData.balance ?? 0)\n                      : Math.min(\n                          (tradeData.numbers ?? 1) * REDPACKET_ORDER_NFT_LIMIT,\n                          tradeData.balance ?? 0,\n                        ),\n                },\n                handleError: ({ balance: _balance }: T) => {\n                  return { error: false, message: '' }\n                },\n\n                onChangeEvent: (_index: 0 | 1, { to, tradeData: newTradeData }: SwitchData<T>) => {\n                  if (_index === 1) {\n                    if (selectNFTDisabled) return\n                    handleOnDataChange({\n                      collectionInfo: undefined,\n                      tokenId: undefined,\n                      tradeValue: undefined,\n                      balance: undefined,\n                      nftData: undefined,\n                      belong: undefined,\n                      image: undefined,\n                    } as T)\n                    if (tradeData.type?.scope === sdk.LuckyTokenViewType.TARGET) {\n                      setActiveStep(TargetRedPacketStep.NFTList)\n                    } else {\n                      setActiveStep(RedPacketStep.NFTList)\n                    }\n                  } else if (to === 'button') {\n                    handleOnDataChange({\n                      tradeValue: newTradeData.tradeValue,\n                      belong: newTradeData.belong,\n                      balance: tradeData.balance,\n                      nftData: newTradeData.nftData,\n                    } as any)\n                  }\n                },\n                inputNFTDefaultProps: inputNFTButtonDefaultProps,\n                inputNFTRef: inputBtnRef,\n              } as any)}\n            />\n          )}\n\n          <Typography\n            display={'flex'}\n            width={'100%'}\n            justifyContent={'flex-end'}\n            color={'textSecondary'}\n          >\n            {t('labelAssetAmount', {\n              value: getValuePrecisionThousand(tradeData.balance, 8, 8, 8, false),\n            })}\n          </Typography>\n        </Box>\n\n        {tradeData.type?.mode === sdk.LuckyTokenClaimType.BLIND_BOX && (\n          <Box\n            marginY={1}\n            display={'flex'}\n            alignSelf={'stretch'}\n            justifyContent={'stretch'}\n            flexDirection={'column'}\n            position={'relative'}\n          >\n            <InputCoin<any, I, any>\n              // ref={inputSplitRef}\n              label={t('labelBlindBoxRedPacketWithGift')}\n              placeholderText={t('labelQuantity')}\n              isHideError={false}\n              isShowCoinInfo={false}\n              // handleError={(data: any) => {\n              //   handleOnDataChange({\n              //     giftNumbers: data.tradeValue,\n              //   } as unknown as Partial<T>);\n              //   return {\n              //     error:\n              //       tradeData.giftNumbers &&\n              //       tradeData.numbers &&\n              //       tradeData.giftNumbers > tradeData.numbers\n              //         ? true\n              //         : false,\n              //   };\n              // }}\n              name={'giftnumbers'}\n              order={'right'}\n              handleCountChange={(data) => {\n                handleOnDataChange({\n                  giftNumbers: data.tradeValue,\n                } as unknown as Partial<T>)\n              }}\n              inputData={{\n                belong:\n                  selectedType.value.partition == sdk.LuckyTokenAmountType.AVERAGE\n                    ? t('labelQuantity')\n                    : t('labelSplit'),\n                tradeValue: tradeData?.giftNumbers,\n              }}\n              coinMap={{}}\n              coinPrecision={undefined}\n              disabled={disabled}\n              // inputError={\n              //   tradeData.giftNumbers &&\n              //   tradeData.numbers &&\n              //   tradeData.giftNumbers > tradeData.numbers\n              //     ? { error: true }\n              //     : { error: false }\n              // }\n            />\n          </Box>\n        )}\n        <Box\n          marginY={1}\n          display={'flex'}\n          alignSelf={'stretch'}\n          justifyContent={'stretch'}\n          flexDirection={'column'}\n          position={'relative'}\n        >\n          <InputCoin<any, I, any>\n            ref={inputSplitRef}\n            {...{\n              ...inputSplitProps,\n              name: 'numbers',\n              order: 'right',\n              handleCountChange: (data) => {\n                handleOnDataChange({\n                  numbers: data.tradeValue,\n                } as unknown as Partial<T>)\n              },\n              coinMap: {},\n              coinPrecision: undefined,\n            }}\n            disabled={disabled}\n          />\n        </Box>\n        <Box marginY={1} display={'flex'} alignSelf={'stretch'}>\n          <StyledTextFiled\n            label={\n              <Typography component={'span'} color={'var(--color-text-third)'}>\n                {t('labelRedPacketMemo')}\n              </Typography>\n            }\n            value={tradeData.memo}\n            onChange={(event) =>\n              handleOnDataChange({\n                memo: event.target.value, //event?.target?.value,\n              } as unknown as Partial<T>)\n            }\n            size={'large'}\n            inputProps={{\n              placeholder: t('labelRedPacketMemoPlaceholder'),\n              maxLength: 25,\n            }}\n            fullWidth={true}\n          />\n        </Box>\n        <Box marginY={1} display={'flex'} alignSelf={'stretch'} flexDirection={'column'}>\n          <FormLabel>\n            <Typography\n              variant={'body1'}\n              component={'span'}\n              lineHeight={'20px'}\n              display={'inline-flex'}\n              alignItems={'center'}\n              className={'main-label'}\n              color={'var(--color-text-third)'}\n            >\n              {selectedType.value.mode === sdk.LuckyTokenClaimType.BLIND_BOX\n                ? t('labelRedPacketTimeRangeBlindbox')\n                : t('labelRedPacketTimeRange')}\n              <Tooltip\n                title={\n                  tradeData.type?.mode === sdk.LuckyTokenClaimType.BLIND_BOX\n                    ? tradeData.isNFT\n                      ? t('labelRedPacketTimeRangeBlindboxDes')!\n                      : t('labelRedPacketTimeRangeBlindboxDesERC20')!\n                    : t('labelRedPacketTimeRangeDes')!\n                }\n              >\n                <IconButton>\n                  <Info2Icon />\n                </IconButton>\n              </Tooltip>\n            </Typography>\n          </FormLabel>\n          <Box marginTop={1}>\n            <DateTimeRangePicker\n              startValue={startDateTime}\n              startMinDateTime={startMinDateTime}\n              startMaxDateTime={startMaxDateTime}\n              onStartChange={(m) => {\n                handleOnDataChange({\n                  validSince: m ? m.toDate().getTime() : undefined,\n                  validUntil: m ? m.clone().add(1, 'days').toDate().getTime() : undefined,\n                } as unknown as Partial<T>)\n              }}\n              onStartOpen={() => {\n                handleOnDataChange({\n                  validUntil: undefined,\n                } as unknown as Partial<T>)\n              }}\n              endValue={endDateTime}\n              endMinDateTime={endMinDateTime}\n              endMaxDateTime={endMaxDateTime}\n              onEndChange={(m) => {\n                if (\n                  startDateTime &&\n                  m &&\n                  startDateTime?.toDate().getTime() > m?.toDate().getTime()\n                ) {\n                  handleOnDataChange({\n                    validUntil: endDateTime,\n                  } as unknown as Partial<T>)\n                } else {\n                  const maximunTimestamp = startDateTime\n                    ? moment(startDateTime).add(timeRangeMaxInSeconds, 'seconds').toDate().getTime()\n                    : 0\n                  handleOnDataChange({\n                    validUntil: m\n                      ? m.toDate().getTime() > maximunTimestamp\n                        ? maximunTimestamp\n                        : m.toDate().getTime()\n                      : undefined,\n                  } as unknown as Partial<T>)\n                }\n              }}\n              customeEndInputPlaceHolder={\n                tradeData.type?.mode === sdk.LuckyTokenClaimType.BLIND_BOX\n                  ? t('labelBlindBoxEndDate2')\n                  : undefined\n              }\n            />\n          </Box>\n        </Box>\n        <Box\n          marginY={1}\n          display={'flex'}\n          alignSelf={'stretch'}\n          position={'relative'}\n          flexDirection={'column'}\n        >\n          {!chargeFeeTokenList?.length ? (\n            <Typography component={'span'}>{t('labelFeeCalculating')}</Typography>\n          ) : (\n            <>\n              <FeeSelect\n                chargeFeeTokenList={chargeFeeTokenList}\n                handleToggleChange={(fee: FeeInfo) => {\n                  handleToggleChange(fee as F)\n                  setShowFeeModal(false)\n                }}\n                feeInfo={feeInfo as FeeInfo}\n                open={showFeeModal}\n                onClose={() => {\n                  setShowFeeModal(false)\n                }}\n                isFeeNotEnough={isFeeNotEnough && isFeeNotEnough.isFeeNotEnough}\n                feeLoading={isFeeNotEnough && isFeeNotEnough.isOnLoading}\n                onClickFee={() => setShowFeeModal((prev) => !prev)}\n                floatLeft\n              />\n            </>\n          )}\n        </Box>\n        <Box marginY={1} display={'flex'} flexDirection={'column'} alignSelf={'stretch'}>\n          <Typography\n            display={'inline-flex'}\n            alignItems={'center'}\n            justifyContent={'center'}\n            variant={'h3'}\n            component={'span'}\n            color={'textPrimary'}\n            width={'100%'}\n            textAlign={'center'}\n          >\n            {redPacketTotalValue}\n          </Typography>\n          <Typography\n            display={'inline-flex'}\n            alignItems={'center'}\n            justifyContent={'center'}\n            variant={'body2'}\n            component={'span'}\n            color={'var(--color-text-third)'}\n            width={'100%'}\n            textAlign={'center'}\n          >\n            {selectedType.value.partition == sdk.LuckyTokenAmountType.AVERAGE\n              ? t('labelRedPacketsSplitCommonDetail', { value: splitValue })\n              : t('labelRedPacketsSplitLuckyDetail')}\n          </Typography>\n        </Box>\n        <Box marginY={1} display={'flex'} alignSelf={'stretch'}>\n          {lastFailed && (\n            <Typography\n              component={'span'}\n              paddingBottom={1}\n              textAlign={'center'}\n              color={'var(--color-warning)'}\n            >\n              {t('labelConfirmAgainByFailed')}\n            </Typography>\n          )}\n        </Box>\n        <Box\n          marginY={1}\n          display={'flex'}\n          alignSelf={'stretch'}\n          flexDirection={'row'}\n          justifyContent={'space-between'}\n        >\n          <Box width={'48%'}>\n            <Button\n              variant={'outlined'}\n              size={'medium'}\n              fullWidth\n              className={'step'}\n              startIcon={<BackIcon fontSize={'small'} />}\n              color={'primary'}\n              sx={{ height: 'var(--btn-medium-height)' }}\n              onClick={() => {\n                if (tradeData.type?.scope === sdk.LuckyTokenViewType.TARGET) {\n                  setActiveStep(TargetRedPacketStep.ChooseType)\n                } else {\n                  setActiveStep(RedPacketStep.ChooseType)\n                }\n                handleOnDataChange({\n                  numbers: undefined,\n                  tradeValue: undefined,\n                  validSince: Date.now(),\n                  validUntil: moment().add('days', 1).toDate().getTime(),\n                  giftNumbers: undefined,\n                  memo: '',\n                } as any)\n              }}\n            >\n              {t(`labelMintBack`)}\n            </Button>\n          </Box>\n          <Box width={'50%'}>\n            <Button\n              fullWidth\n              variant={'contained'}\n              size={'medium'}\n              color={'primary'}\n              onClick={() => {\n                onCreateRedPacketClick()\n              }}\n              loading={!getDisabled && btnStatus === TradeBtnStatus.LOADING ? 'true' : 'false'}\n              disabled={getDisabled || btnStatus === TradeBtnStatus.LOADING}\n            >\n              {btnInfo?.label ? t(btnInfo.label, btnInfo.params) : t(`labelCreateRedPacketBtn`)}\n            </Button>\n          </Box>\n        </Box>\n\n        <Box marginTop={4} display={'flex'} alignSelf={'stretch'}>\n          <Typography\n            paddingBottom={0}\n            display={'inline-flex'}\n            alignItems={'center'}\n            justifyContent={'center'}\n            variant={'body2'}\n            component={'span'}\n            color={'textSecondary'}\n            width={'100%'}\n            textAlign={'center'}\n          >\n            {tradeData.isNFT\n              ? t('labelBlindBoxExpirationExplainationForNFT')\n              : tradeData.type?.mode === sdk.LuckyTokenClaimType.BLIND_BOX\n              ? t('labelBlindBoxExpirationExplainationForTokenBlindbox')\n              : t('labelBlindBoxExpirationExplainationForToken')}\n          </Typography>\n        </Box>\n      </RedPacketBoxStyle>\n    )\n  },\n) as <T extends Partial<RedPacketOrderData<I>>, I, F extends FeeInfo>(\n  props: CreateRedPacketViewProps<T, I, F> & {\n    selectedType: LuckyRedPacketItem\n  },\n) => JSX.Element\n\nexport const CreateRedPacketStepType = withTranslation()(\n  <T extends RedPacketOrderData<I>, I, C = FeeInfo>({\n    // handleOnSelectedType,\n    tradeType,\n    tradeData,\n    // handleOnDataChange,\n    setActiveStep,\n    backToScope,\n    selectedType,\n    disabled = false,\n    btnInfo,\n    onClickNext,\n    showNFT,\n    onSelecteValue,\n    redPacketConfig,\n    handleOnDataChange,\n    t,\n  }: Omit<CreateRedPacketViewProps<T, I, C>, 'tokenMap'> & {\n    selectedType: LuckyRedPacketItem\n    // setSelectType: (value: LuckyRedPacketItem) => void;\n  } & WithTranslation) => {\n    const { isMobile } = useSettings()\n    const getDisabled = React.useMemo(() => {\n      return disabled\n    }, [disabled])\n    const showERC20Blindbox = redPacketConfig.showERC20Blindbox\n\n    const isTokens =\n      (tradeType === RedPacketOrderType.BlindBox && !tradeData.isNFT) ||\n      tradeType === RedPacketOrderType.TOKEN\n\n    const setIsTokens = React.useCallback(\n      (isTokens: boolean) => {\n        myLog('isTokens', tradeData)\n        myLog('isTokens', isTokens)\n        if (tradeType === RedPacketOrderType.BlindBox) {\n          handleOnDataChange({\n            ...tradeData,\n            isNFT: !isTokens,\n          })\n        } else {\n          handleOnDataChange({\n            ...tradeData,\n            tradeType: isTokens ? RedPacketOrderType.TOKEN : RedPacketOrderType.NFT,\n          })\n        }\n      },\n      [tradeData],\n    )\n\n    const showList = LuckyRedPacketList.filter((item) =>\n      tradeType === RedPacketOrderType.FromNFT\n        ? tradeData.type?.mode === sdk.LuckyTokenClaimType.BLIND_BOX\n          ? item.tags?.includes('showInBlindBox')\n          : item.tags?.includes('showInNormal')\n        : tradeType === RedPacketOrderType.BlindBox\n        ? item.tags?.includes('showInBlindBox')\n        : item.tags?.includes('showInNormal'),\n    )\n\n    const enabledList = LuckyRedPacketList.filter((item) =>\n      tradeType === RedPacketOrderType.FromNFT\n        ? tradeData.type?.mode === sdk.LuckyTokenClaimType.BLIND_BOX\n          ? item.tags?.includes('enableInBlindBox')\n          : item.tags?.includes('enableInNFTS')\n        : tradeType === RedPacketOrderType.BlindBox\n        ? item.tags?.includes('enableInBlindBox')\n        : tradeType === RedPacketOrderType.TOKEN\n        ? item.tags?.includes('enableInERC20')\n        : item.tags?.includes('enableInNFTS'),\n    ).filter((item) =>\n      tradeData.type?.scope === sdk.LuckyTokenViewType.TARGET\n        ? !item.tags?.includes('disabledForExclusive')\n        : true,\n    )\n    myLog('tradeData.type?.mode', tradeData.type?.mode)\n    return (\n      <RedPacketBoxStyle\n        className={isMobile ? 'mobile redPacket' : ''}\n        justifyContent={'flex-start'}\n        flexDirection={'column'}\n        alignItems={'center'}\n        width={'100%'}\n        maxWidth={850}\n      >\n        <Box\n          display={'flex'}\n          flexDirection={'column'}\n          alignItems={'stretch'}\n          alignSelf={'stretch'}\n          minHeight={300}\n          paddingY={2}\n          marginTop={2}\n          marginBottom={5}\n        >\n          <Typography\n            component={'h4'}\n            variant={isMobile ? 'body1' : 'h4'}\n            whiteSpace={'pre'}\n            marginRight={1}\n            marginBottom={2}\n            display={'flex'}\n            alignItems={'center'}\n          >\n            {t(\n              selectedType.value.mode == sdk.LuckyTokenClaimType.BLIND_BOX\n                ? 'labelLuckyBlindBox'\n                : 'labelNormalRedPacketTitle',\n            ) +\n              ' — ' +\n              t(`labelRedPacketViewType${tradeData?.type?.scope ?? 0}`)}\n            {tradeType === RedPacketOrderType.BlindBox && (\n              <Tooltip title={t('labelBlindBoxHint')}>\n                <Box marginLeft={1} height={24}>\n                  <HelpIcon htmlColor={'var(--color-text-secondary)'} fontSize={'large'} />\n                </Box>\n              </Tooltip>\n            )}\n          </Typography>\n\n          {tradeType === RedPacketOrderType.FromNFT ? (\n            <Tabs\n              value={\n                tradeData.type?.mode === sdk.LuckyTokenClaimType.BLIND_BOX ? 'BlindBox' : 'Normal'\n              }\n              onChange={(_event, value) => {\n                const found = value === 'Normal'\n                  ? LuckyRedPacketList.find((config) =>\n                  config.tags?.includes('enableInNFTS') && config.value.partition === sdk.LuckyTokenAmountType.RANDOM,\n                )\n                  : LuckyRedPacketList.find((config) =>\n                  config.value.partition === sdk.LuckyTokenAmountType.RANDOM &&\n                  config.value.mode === sdk.LuckyTokenClaimType.BLIND_BOX\n                ) \n                onSelecteValue!(found!)\n              }}\n              aria-label='l2-history-tabs'\n              variant='scrollable'\n            >\n              <Tab sx={{ marginLeft: -2 }} value={'Normal'} label='Normal' />\n              <Tab value={'BlindBox'} label='Blind Box' />\n            </Tabs>\n          ) : (\n            <Tabs\n              value={isTokens ? 'Tokens' : 'NFT'}\n              onChange={(_event, value) => {\n                setIsTokens(value === 'Tokens')\n              }}\n              aria-label='l2-history-tabs'\n              variant='scrollable'\n            >\n              <Tab sx={{ marginLeft: -2 }} value={'Tokens'} label={t('labelAssetTokens')} />\n              {tradeData.type?.scope !== sdk.LuckyTokenViewType.PUBLIC && (\n                <Tab value={'NFT'} label={t('labelRedpacketNFTS')} />\n              )}\n            </Tabs>\n          )}\n          <Box display={'flex'} justifyContent={'space-between'} marginTop={2}>\n            {showList.map((item: LuckyRedPacketItem, index) => {\n              const enabled = enabledList.find((enableItem) => enableItem.value === item.value)\n              return (\n                <Box width={'31.5%'} key={index}>\n                  <Box key={item.value.value} marginBottom={1}>\n                    <MenuBtnStyled\n                      variant={'outlined'}\n                      size={'large'}\n                      className={`${isMobile ? 'isMobile' : ''} ${\n                        selectedType.value.value === item.value.value\n                          ? 'selected redPacketType '\n                          : 'redPacketType'\n                      }`}\n                      disabled={!enabled}\n                      fullWidth\n                      onClick={(_e) => {\n                        onSelecteValue && onSelecteValue(item)\n                      }}\n                      sx={{\n                        '&&&&': {\n                          borderRadius: 2,\n                        },\n                        '&&&&.Mui-disabled': {\n                          backgroundColor: 'transparent',\n                          borderStyle: 'solid',\n                          opacity: 0.25,\n                        },\n                      }}\n                    >\n                      <Typography\n                        variant={'body1'}\n                        display={'inline-flex'}\n                        marginBottom={1 / 2}\n                        alignItems={'flex-start'}\n                        component={'span'}\n                        color={'var(--color-text-primary)'}\n                      >\n                        {t(item.labelKey)}\n                      </Typography>\n                      <Typography\n                        variant={'body1'}\n                        display={'inline-flex'}\n                        justifyContent={'flex-start'}\n                        component={'span'}\n                        color={'var(--color-text-secondary)'}\n                      >\n                        {t(item.desKey)}\n                      </Typography>\n                    </MenuBtnStyled>\n                  </Box>\n                </Box>\n              )\n            })}\n          </Box>\n        </Box>\n\n        <Box\n          width={'100%'}\n          alignSelf={'stretch'}\n          paddingBottom={1}\n          display={'flex'}\n          flexDirection={'row'}\n          justifyContent={'center'}\n        >\n          <Box width={'33%'} marginRight={'2%'}>\n            <Button\n              variant={'outlined'}\n              size={'medium'}\n              fullWidth\n              className={'step'}\n              startIcon={<BackIcon fontSize={'small'} />}\n              color={'primary'}\n              sx={{ height: 'var(--btn-medium-height)' }}\n              onClick={() => {\n                if (tradeType === RedPacketOrderType.FromNFT) {\n                  backToScope()\n                } else {\n                  if (tradeData.type?.scope === sdk.LuckyTokenViewType.TARGET) {\n                    setActiveStep(TargetRedPacketStep.TradeType)\n                  } else {\n                    setActiveStep(RedPacketStep.TradeType)\n                  }\n                }\n              }}\n            >\n              {t(`labelMintBack`)}\n            </Button>\n          </Box>\n          <Box width={'33%'}>\n            <BtnMain\n              {...{\n                defaultLabel: 'labelContinue',\n                fullWidth: true,\n                btnInfo: btnInfo,\n                disabled: () => getDisabled,\n                onClick: () => {\n                  onClickNext()\n                },\n              }}\n            />\n          </Box>\n        </Box>\n      </RedPacketBoxStyle>\n    )\n  },\n)\nexport const CreateRedPacketStepTokenType = withTranslation()(\n  <T extends RedPacketOrderData<I>, I, C = FeeInfo>({\n    tradeType,\n    // setActiveStep,\n    disabled = false,\n    btnInfo,\n    onClickNext,\n    onClickBack,\n    showNFT,\n    t,\n    onChangeTradeType,\n  }: Omit<CreateRedPacketViewProps<T, I, C>, 'tradeData' | 'tokenMap'> & WithTranslation) => {\n    const { isMobile } = useSettings()\n    const getDisabled = React.useMemo(() => {\n      return disabled\n    }, [disabled])\n    const isNormal = tradeType === RedPacketOrderType.TOKEN || tradeType === RedPacketOrderType.NFT\n\n    return (\n      <RedPacketBoxStyle\n        display={'flex'}\n        flexDirection={'column'}\n        width={'100%'}\n        maxWidth={720}\n        paddingX={isMobile ? 2 : 10}\n        className='modalConte'\n        position={'absolute'}\n        height={'100%'}\n        maxHeight={'480px'}\n        justifyContent={'space-evenly'}\n      >\n        <Grid container spacing={7} justifyContent={'center'}>\n          <Grid item xs={4} display={'flex'} marginBottom={2}>\n            <CardStyleItem\n              className={isNormal ? 'btnCard column selected' : 'btnCard column'}\n              sx={{ height: '100%' }}\n              onClick={() => onChangeTradeType!(RedPacketOrderType.TOKEN)}\n            >\n              <CardContent sx={{ alignItems: 'center', paddingTop: 4 }}>\n                <Typography component={'span'} display={'inline-flex'}>\n                  <NormalRedpacketIcon\n                    htmlColor={'var(--color-text-primary)'}\n                    style={{ width: 64, height: 64 }}\n                  />\n                </Typography>\n                <Typography component={'span'} variant={'h5'} marginTop={2}>\n                  {t('labelLuckyTokenNormal')}\n                </Typography>\n              </CardContent>\n            </CardStyleItem>\n          </Grid>\n          <Grid item xs={4} display={'flex'} marginBottom={2}>\n            <CardStyleItem\n              className={\n                tradeType === RedPacketOrderType.BlindBox\n                  ? 'btnCard column selected'\n                  : 'btnCard column'\n              }\n              sx={{ height: '100%' }}\n              onClick={() => onChangeTradeType!(RedPacketOrderType.BlindBox)}\n            >\n              <CardContent sx={{ alignItems: 'center', paddingTop: 4 }}>\n                <Typography component={'span'} display={'inline-flex'}>\n                  <Typography component={'span'} display={'inline-flex'}>\n                    <BlindBoxIcon\n                      htmlColor={'var(--color-text-primary)'}\n                      style={{ width: 64, height: 64 }}\n                    />\n                  </Typography>\n                </Typography>\n                <Typography component={'span'} variant={'h5'} marginTop={2}>\n                  {t('labelRedpacketBlindBox')}\n                </Typography>\n              </CardContent>\n            </CardStyleItem>\n          </Grid>\n        </Grid>\n        <Box\n          width={'100%'}\n          alignSelf={'stretch'}\n          paddingBottom={1}\n          display={'flex'}\n          flexDirection={'row'}\n          justifyContent={'space-between'}\n        >\n          <Box width={'48%'}>\n            <Button\n              variant={'outlined'}\n              size={'medium'}\n              fullWidth\n              className={'step'}\n              startIcon={<BackIcon fontSize={'small'} />}\n              color={'primary'}\n              sx={{ height: 'var(--btn-medium-height)' }}\n              onClick={() => {\n                onClickBack()\n              }}\n            >\n              {t(`labelMintBack`)}\n            </Button>\n          </Box>\n          <Box width={'48%'}>\n            <BtnMain\n              {...{\n                defaultLabel: 'labelContinue',\n                fullWidth: true,\n                btnInfo: btnInfo,\n                disabled: () => getDisabled,\n                onClick: () => {\n                  onClickNext()\n                },\n              }}\n            />\n          </Box>\n        </Box>\n      </RedPacketBoxStyle>\n    )\n  },\n)\n\nconst ScopeOption = styled(Box)<{ selected?: boolean; disabled?: boolean }>`\n  display: flex;\n  border: 1px solid\n    ${({ selected }) => (selected ? 'var(--color-border-select)' : 'var(--color-border)')};\n  padding: ${({ theme }) => 3 * theme.unit}px;\n  border-radius: ${({ theme }) => theme.unit}px;\n  width: 47%;\n  cursor: ${({ disabled }) => (disabled ? '' : 'pointer')};\n  opacity: ${({ disabled }) => (disabled ? '0.5' : '')};\n`\ntype CreateRedPacketScopeProps = {\n  selectedScope: sdk.LuckyTokenViewType\n  onSelecteScope: (scope: sdk.LuckyTokenViewType) => void\n  onClickNext: () => void\n  palazaPublicDisabled: boolean\n  exclusiveDisabled: boolean\n  showBackBtn: boolean\n  showExclusiveOption: boolean\n}\nexport const CreateRedPacketScope = withTranslation()(\n  ({\n    selectedScope,\n    onClickNext,\n    onSelecteScope,\n    palazaPublicDisabled,\n    exclusiveDisabled,\n    showBackBtn,\n    showExclusiveOption,\n    t,\n  }: CreateRedPacketScopeProps & WithTranslation) => {\n    const theme = useTheme()\n    const history = useHistory()\n    return (\n      <Box\n        width={'100%'}\n        display={'flex'}\n        flexDirection={'column'}\n        paddingX={8}\n        paddingTop={4}\n        paddingBottom={8}\n      >\n        <Box marginBottom={6}>\n          <Box display={'flex'} alignItems={'center'} marginBottom={2}>\n            <Typography marginRight={0.5} variant={'h4'}>\n              {t('labelLuckyTokenViewTypePublic')}\n            </Typography>\n            <Tooltip title={t('labelRedPacketPublicTooltip')}>\n              <Box>\n                <HelpIcon htmlColor={'var(--color-text-secondary)'} fontSize={'large'} />\n              </Box>\n            </Tooltip>\n          </Box>\n          <Box display={'flex'} justifyContent={'space-between'}>\n            {/* {palazaPublicDisabled && ( */}\n            <ScopeOption\n              onClick={() => {\n                !palazaPublicDisabled && onSelecteScope(sdk.LuckyTokenViewType.PUBLIC)\n              }}\n              selected={selectedScope === sdk.LuckyTokenViewType.PUBLIC}\n              disabled={palazaPublicDisabled}\n            >\n              <Box marginRight={0.5}>\n                <Typography>{t('labelRedPacketPlazaPublic')}</Typography>\n                <Typography color={'var(--color-text-secondary)'}>\n                  {t('labelRedPacketPlazaPublicDes')}\n                </Typography>\n              </Box>\n              <Box width={theme.unit * 8}>\n                <ScopePublic color={'var(--color-text-secondary)'} />\n              </Box>\n            </ScopeOption>\n            {/* )} */}\n            <ScopeOption\n              onClick={() => onSelecteScope(sdk.LuckyTokenViewType.PRIVATE)}\n              selected={selectedScope === sdk.LuckyTokenViewType.PRIVATE}\n            >\n              <Box marginRight={0.5}>\n                <Typography>{t('labelRedPacketQRPublic')}</Typography>\n                <Typography color={'var(--color-text-secondary)'}>\n                  {t('labelRedPacketQRPublicDes')}\n                </Typography>\n              </Box>\n              <Box width={theme.unit * 8}>\n                <ScopeQR color={'var(--color-text-secondary)'} />\n              </Box>\n            </ScopeOption>\n          </Box>\n        </Box>\n        {showExclusiveOption && (\n          <Box marginBottom={12}>\n            <Box display={'flex'} alignItems={'center'} marginBottom={2}>\n              <Typography marginRight={0.5} variant={'h4'}>\n                {t('labelLuckyTokenViewTypePrivate')}{' '}\n              </Typography>\n              <Tooltip\n                title={\n                  <Trans\n                    i18nKey={'labelRedPacketPrivateTooltip'}\n                    components={{\n                      p: (\n                        <Typography\n                          whiteSpace={'pre-line'}\n                          component={'span'}\n                          variant={'body1'}\n                          display={'block'}\n                          color={'textSecondary'}\n                          paddingY={1}\n                        />\n                      ),\n                      br: <br />,\n                      li: (\n                        <Typography\n                          whiteSpace={'pre-line'}\n                          component={'ol'}\n                          display={'list-item'}\n                          variant={'body1'}\n                          color={'textSecondary'}\n                        />\n                      ),\n                    }}\n                  />\n                }\n              >\n                <Box>\n                  <HelpIcon htmlColor={'var(--color-text-secondary)'} fontSize={'large'} />\n                </Box>\n              </Tooltip>\n            </Box>\n            <Box display={'flex'} justifyContent={'space-between'}>\n              <ScopeOption\n                onClick={() => {\n                  !exclusiveDisabled && onSelecteScope(sdk.LuckyTokenViewType.TARGET)\n                }}\n                selected={selectedScope === sdk.LuckyTokenViewType.TARGET}\n                disabled={exclusiveDisabled}\n              >\n                <Box marginRight={0.5}>\n                  <Typography>{t('labelRedPacketExclusive')}</Typography>\n                  <Typography color={'var(--color-text-secondary)'}>\n                    {t('labelRedPacketExclusiveDes')}\n                  </Typography>\n                </Box>\n                <Box width={theme.unit * 8}>\n                  <ScopeTarget color={'var(--color-text-secondary)'} />\n                </Box>\n              </ScopeOption>\n            </Box>\n          </Box>\n        )}\n        <Box display={'flex'} justifyContent={'center'} width={'100%'}>\n          {showBackBtn && (\n            <Box width={'45%'} marginRight={'5%'}>\n              <Button\n                variant={'outlined'}\n                size={'medium'}\n                fullWidth\n                className={'step'}\n                startIcon={<BackIcon fontSize={'small'} />}\n                color={'primary'}\n                sx={{ height: 'var(--btn-medium-height)' }}\n                onClick={() => {\n                  history.goBack()\n                }}\n              >\n                {t(`labelMintBack`)}\n              </Button>\n            </Box>\n          )}\n          <Box width={'45%'}>\n            <BtnMain\n              {...{\n                defaultLabel: 'labelContinue',\n                fullWidth: true,\n                disabled: () => false,\n                onClick: () => {\n                  onClickNext()\n                },\n              }}\n            />\n          </Box>\n        </Box>\n      </Box>\n    )\n  },\n)\n\nconst TargetRedpacktOption = styled(Box)<{ selected: boolean }>`\n  display: flex;\n  border: 1px solid\n    ${({ selected }) => (selected ? 'var(--color-border-select)' : 'var(--color-border)')};\n  padding: ${({ theme }) => 2 * theme.unit}px;\n  border-radius: ${({ theme }) => 0.5 * theme.unit}px;\n  width: 31%;\n  margin-right: 2%;\n  margin-bottom: 2%;\n  flex-direction: column;\n  cursor: pointer;\n`\n\nexport const ReceiptListModal = (props: {\n  open: boolean\n  onClose: () => void\n  targets: string[]\n  t: TFunction<'translation', undefined>\n}) => {\n  const { open, t, onClose, targets } = props\n  return (\n    <Modal\n      open={open}\n      onClose={onClose}\n      content={\n        <Box\n          flex={1}\n          display={'flex'}\n          alignItems={'center'}\n          justifyContent={'space-between'}\n          flexDirection={'column'}\n          width={'var(--modal-width)'}\n          padding={5}\n          paddingTop={2}\n          paddingBottom={9}\n        >\n          <Typography variant={'h3'}>{t('labelRedpacketRecipientList')}</Typography>\n          <Typography marginTop={0.5} color={'var(--color-text-secondary)'}>\n            {t('labelRedPacketTotal', {\n              count: targets.length,\n            })}\n          </Typography>\n\n          {targets.length > 0 ? (\n            <Box\n              borderRadius={1}\n              bgcolor={'var(--field-opacity)'}\n              marginTop={3}\n              paddingX={3}\n              paddingY={2}\n              width={'100%'}\n              height={362}\n              overflow={'scroll'}\n            >\n              <Typography>{targets.map((target) => target + ';').join('\\n')}</Typography>\n            </Box>\n          ) : (\n            <Box\n              display={'flex'}\n              width={'100%'}\n              justifyContent={'center'}\n              alignItems={'center'}\n              flexDirection={'column'}\n              height={362}\n            >\n              <img width={85} src={SoursURL + '/images/receipt_empty.png'} />\n              <Typography textAlign={'center'} width={'50%'} marginTop={2.5} variant={'body2'}>\n                {t('labelRedpacketreceiptListEmpty')}\n              </Typography>\n            </Box>\n          )}\n        </Box>\n      }\n    />\n  )\n}\n\nexport const TargetRedpacktSelectStep = withTranslation()(\n  (props: TargetRedpacktSelectStepProps & WithTranslation) => {\n    const {\n      onClickCreateNew,\n      targetRedPackets,\n      onClickExclusiveRedpacket,\n      onClickViewDetail,\n      popRedPacket,\n      popRedPacketAmountStr,\n      onCloseRedpacketPop,\n      backToScope,\n      idIndex,\n      t,\n    } = props\n    const theme = useTheme()\n    const { coinJson, isMobile } = useSettings()\n    const [showReceipts, setShowReceipts] = React.useState(false)\n    // const [enlarged, setEnlarged] = React.useState(false)\n\n    return (\n      <RedPacketBoxStyle\n        height={'100%'}\n        maxHeight={'580px'}\n        justifyContent={'left'}\n        width={'100%'}\n        maxWidth={1152}\n        paddingX={isMobile ? 2 : 5}\n        position={'absolute'}\n        overflow={'scroll'}\n      >\n        <Box\n          display={'flex'}\n          alignItems={'center'}\n          flexDirection={'column'}\n          marginX={9}\n          marginTop={2}\n          padding={2.5}\n          borderBottom={'1px solid var(--color-border)'}\n          height={'216px'}\n        >\n          <Typography variant={'h4'} width={'100%'} marginBottom={7}>\n            {t('labelTargetRedpacketOption1')}\n          </Typography>\n          <Button\n            variant={'contained'}\n            onClick={() => {\n              onClickCreateNew()\n            }}\n          >\n            {t('labelRedpacketCreateNew')}\n          </Button>\n        </Box>\n        <Box\n          // height={'290px'}\n          marginX={9}\n          marginTop={3}\n          // bgcolor={'var(--color-global-bg)'}\n          padding={2.5}\n          // border={'1px solid var(--color-border)'}\n          borderRadius={2}\n          position={'relative'}\n        >\n          <Box display={'flex'} justifyContent={'space-between'} width={'100%'}>\n            <Typography variant={'h4'} marginBottom={3}>\n              {t('labelTargetRedpacketOption2')}{' '}\n            </Typography>\n            <Typography fontSize={'13px'} marginBottom={3}>\n              {t('labelRedpacketExclusiveReady', { count: targetRedPackets.length })}\n            </Typography>\n          </Box>\n          {targetRedPackets?.length > 0 ? (\n            <Box width={'100%'}>\n              <Box display={'flex'} flexWrap={'wrap'} maxHeight={'190px'}>\n                {targetRedPackets &&\n                  targetRedPackets\n                    .filter((redpacket) => (redpacket.tokenAmount as any).remainTargetCount > 0)\n                    .map((redpacket) => (\n                      <TargetRedpacktOption\n                        onClick={() => {\n                          onClickExclusiveRedpacket({\n                            hash: redpacket.hash,\n                            remainCount: (redpacket.tokenAmount as any).remainTargetCount as number,\n                          })\n                        }}\n                        selected={false}\n                        key={redpacket.hash}\n                      >\n                        <Box\n                          display={'flex'}\n                          marginBottom={1}\n                          justifyContent={'space-between'}\n                          alignItems={'start'}\n                        >\n                          <Box display={'flex'}>\n                            {redpacket.isNft ? (\n                              <NftImageStyle\n                                src={redpacket.nftTokenInfo?.metadata?.imageSize['240-240']}\n                                style={{\n                                  width: `${theme.unit * 4}px`,\n                                  height: `${theme.unit * 4}px`,\n                                  borderRadius: `${theme.unit * 0.5}px`,\n                                }}\n                              />\n                            ) : (\n                              <Box width={theme.unit * 4} height={theme.unit * 4}>\n                                <CoinIcons\n                                  size={theme.unit * 4}\n                                  type={TokenType.single}\n                                  tokenIcon={[coinJson[idIndex[redpacket.tokenId]]]}\n                                />\n                              </Box>\n                            )}\n                            <Box width={'125px'} marginLeft={1} marginBottom={1}>\n                              <Typography\n                                textOverflow={'ellipsis'}\n                                whiteSpace={'nowrap'}\n                                overflow={'hidden'}\n                              >\n                                {redpacket.isNft\n                                  ? redpacket.nftTokenInfo?.metadata?.base.name\n                                  : idIndex[redpacket.tokenId]}\n                              </Typography>\n                              <Typography variant={'body2'} color={'var(--color-text-secondary)'}>\n                                {redpacket.type.mode === sdk.LuckyTokenClaimType.BLIND_BOX\n                                  ? t('labelLuckyBlindBox')\n                                  : redpacket.type.mode === sdk.LuckyTokenClaimType.RELAY\n                                  ? t('labelRelayRedPacket')\n                                  : redpacket.type.partition === sdk.LuckyTokenAmountType.RANDOM\n                                  ? t('labelLuckyRedPacket')\n                                  : t('labelNormalRedPacket')}\n                              </Typography>\n                            </Box>\n                          </Box>\n                          <Typography\n                            onClick={(e) => {\n                              e.stopPropagation()\n                              onClickViewDetail(redpacket.hash)\n                            }}\n                            color={'var(--color-primary)'}\n                          >\n                            {t('labelRedPacketExclusiveViewDetails')}\n                          </Typography>\n                        </Box>\n                        <hr\n                          style={{\n                            background: 'var(--color-border)',\n                            border: 'none',\n                            height: '0.5px',\n                          }}\n                        />\n                        <Box\n                          marginTop={1}\n                          marginLeft={5}\n                          display={'flex'}\n                          justifyContent={'space-between'}\n                        >\n                          <Typography color={'var(--color-text-secondary)'}>\n                            {t('labelRedpacketSentMaxLimit')}\n                          </Typography>\n                          <Typography color={'var(--color-text-secondary)'}>\n                            {redpacket.tokenAmount.totalCount -\n                              (redpacket.tokenAmount as any).remainTargetCount}{' '}\n                            / {redpacket.tokenAmount.totalCount}\n                          </Typography>\n                        </Box>\n                      </TargetRedpacktOption>\n                    ))}\n              </Box>\n            </Box>\n          ) : (\n            <Box\n              display={'flex'}\n              justifyContent={'center'}\n              alignItems={'center'}\n              flexDirection={'column'}\n              width={'100%'}\n            >\n              <img\n                height={160}\n                width={160}\n                src={SoursURL + '/images/exclusive_redpacket_empty.png'}\n              />\n              <Typography marginTop={-2.5} variant={'body2'} textAlign={'center'}>\n                {t('labelTargetRedpacketNoRedpacket')}\n              </Typography>\n              <Typography width={'300px'} marginTop={1} variant={'body2'} textAlign={'center'}>\n                {t('labelTargetRedpacketNoRedpacketDes')}\n              </Typography>\n            </Box>\n          )}\n\n          {/* {targetRedPackets?.length > 0 && (\n            <BiArrow\n              sx={{\n                position: 'absolute',\n                bottom: 10,\n                left: '50%',\n                transform: enlarged ? 'rotate(180deg)' : 'none',\n              }}\n              onClick={() => setEnlarged(!enlarged)}\n            />\n          )} */}\n        </Box>\n\n        {/* <Box width={'100%'} marginTop={10} display={'flex'} justifyContent={'center'}>\n          <Box width={'48%'} marginRight={'4%'}>\n            <Button\n              variant={'outlined'}\n              size={'medium'}\n              fullWidth\n              className={'step'}\n              startIcon={<BackIcon fontSize={'small'} />}\n              color={'primary'}\n              sx={{ height: 'var(--btn-medium-height)' }}\n              onClick={() => {\n                backToScope()\n              }}\n            >\n              {t(`labelMintBack`)}\n            </Button>\n          </Box>\n          <Box width={'48%'}>\n            <BtnMain\n              {...{\n                defaultLabel: 'labelRedpacketCreateNew',\n                fullWidth: true,\n                disabled: () => false,\n                onClick: () => {\n                  onClickCreateNew()\n                },\n              }}\n            />\n          </Box>\n        </Box> */}\n        <Modal\n          open={popRedPacket ? true : false}\n          onClose={() => {\n            onCloseRedpacketPop()\n          }}\n          content={\n            <Box\n              flex={1}\n              display={'flex'}\n              alignItems={'center'}\n              justifyContent={'space-between'}\n              flexDirection={'column'}\n              width={'var(--modal-width)'}\n              padding={5}\n              paddingTop={2}\n            >\n              {popRedPacket?.luckyToken!.isNft ? (\n                <NftImageStyle\n                  src={popRedPacket?.luckyToken.nftTokenInfo?.metadata?.imageSize['240-240']}\n                  style={{\n                    width: `${theme.unit * 8}px`,\n                    height: `${theme.unit * 8}px`,\n                    borderRadius: `${theme.unit * 0.5}px`,\n                  }}\n                />\n              ) : (\n                <Box width={theme.unit * 8} height={theme.unit * 8}>\n                  <CoinIcons\n                    size={theme.unit * 8}\n                    type={TokenType.single}\n                    tokenIcon={[coinJson[idIndex[popRedPacket?.tokenId ?? 0]]]}\n                  />\n                </Box>\n              )}\n              {popRedPacketAmountStr && <Typography>{popRedPacketAmountStr}</Typography>}\n              <Box marginTop={4} width={'100%'} marginBottom={10}>\n                {popRedPacket?.luckyToken.type.mode === sdk.LuckyTokenClaimType.BLIND_BOX && (\n                  <Box marginBottom={1} display={'flex'} justifyContent={'space-between'}>\n                    <Typography color={'var(--color-text-secondary)'}>\n                      {t('labelRedpacketGiftRedPacket')}\n                    </Typography>\n                    <Typography>{popRedPacket.luckyToken.tokenAmount.giftCount}</Typography>\n                  </Box>\n                )}\n                <Box marginBottom={1} display={'flex'} justifyContent={'space-between'}>\n                  <Typography color={'var(--color-text-secondary)'}>\n                    {t('labelRedpacketRedPacketscount')}\n                  </Typography>\n                  <Typography>{popRedPacket?.luckyToken.tokenAmount.totalCount}</Typography>\n                </Box>\n                <Box marginBottom={1} display={'flex'} justifyContent={'space-between'}>\n                  <Typography color={'var(--color-text-secondary)'}>\n                    {t('labelBlindBoxStartTime')}\n                  </Typography>\n                  <Typography>\n                    {moment(popRedPacket?.luckyToken.validSince).format(YEAR_DAY_MINUTE_FORMAT)}\n                  </Typography>\n                </Box>\n                <Box marginBottom={1} display={'flex'} justifyContent={'space-between'}>\n                  <Typography color={'var(--color-text-secondary)'}>\n                    {popRedPacket?.luckyToken.type.mode === sdk.LuckyTokenClaimType.BLIND_BOX\n                      ? t('labelRedpacketRevealTime')\n                      : t('labelBlindBoxEndTime')}\n                  </Typography>\n                  <Typography>\n                    {moment(popRedPacket?.luckyToken.validUntil).format(YEAR_DAY_MINUTE_FORMAT)}\n                  </Typography>\n                </Box>\n                <Box marginBottom={1} display={'flex'} justifyContent={'space-between'}>\n                  <Typography color={'var(--color-text-secondary)'}>\n                    {t('labelRedpacketBestwishes')}\n                  </Typography>\n                  <Typography>{popRedPacket?.luckyToken.info.memo}</Typography>\n                </Box>\n              </Box>\n\n              <Button\n                onClick={() => {\n                  setShowReceipts(true)\n                }}\n                sx={{ marginBottom: 2 }}\n                variant={'text'}\n              >\n                {t('labelRedpacketRecipients')}\n              </Button>\n              <Button\n                onClick={() => {\n                  popRedPacket &&\n                    onClickExclusiveRedpacket({\n                      hash: popRedPacket.hash,\n                      remainCount: (popRedPacket?.luckyToken.tokenAmount as any)\n                        .remainTargetCount as number,\n                    })\n                  onCloseRedpacketPop()\n                }}\n                fullWidth\n                variant={'contained'}\n              >\n                {t('labelContinue')}\n              </Button>\n            </Box>\n          }\n        />\n        <ReceiptListModal\n          open={popRedPacket && showReceipts ? true : false}\n          onClose={() => setShowReceipts(false)}\n          t={t}\n          targets={(popRedPacket && (popRedPacket as any).targets) ?? []}\n        />\n      </RedPacketBoxStyle>\n    )\n  },\n)\n\nconst MultiLineInput = styled('textarea')`\n  background: transparent;\n  height: 150px;\n  border: 1px solid var(--color-border);\n  outline: none;\n  color: var(--color-text-primary);\n  padding: ${({ theme }) => theme.unit * 1}px;\n  border-radius: ${({ theme }) => theme.unit * 0.5}px;\n  width: 100%;\n  ::placeholder {\n    color: var(--color-text-secondary);\n    font-family: Roboto;\n  }\n`\nconst isAddressValid = (address: string, previousAddress: string[]) => {\n  return isAddress(address)\n}\nconst getValidAddresses = (input: string, sentAddress: string[]) => {\n  const addresses = input\n    .split(';')\n    .filter((str) => str.trim())\n    .map((str) => str.trim())\n  return addresses.filter((str, index) => {\n    return isAddressValid(str, addresses.slice(0, index).concat(sentAddress))\n  })\n}\nconst getInvalidAddresses = (input: string, sentAddress: string[]) => {\n  const addresses = input\n    .split(';')\n    .filter((str) => str.trim())\n    .map((str) => str.trim())\n  return addresses.filter((str, index) => {\n    return !isAddressValid(str, addresses.slice(0, index).concat(sentAddress))\n  })\n}\n\nexport const TargetRedpacktInputAddressStep = withTranslation()(\n  (props: TargetRedpacktInputAddressStepProps & WithTranslation) => {\n    const {\n      contacts,\n      popupChecked,\n      addressListString,\n      onChangePopupChecked,\n      onFileInput,\n      onClickSend,\n      onConfirm,\n      onManualEditInput,\n      popUpOptionDisabled,\n      maximumTargetsLength,\n      onClickBack,\n      sentAddresses,\n      clearInput,\n      t,\n    } = props\n    const theme = useTheme()\n    const { isMobile } = useSettings()\n    const [showContactModal, setShowContactModal] = React.useState(false)\n    const [showPopUpTips, setShowPopUpTips] = React.useState(false)\n    const [inputDisabled, setInputDisabled] = React.useState(false)\n    const [showChangeTips, setShowChangeTips] = React.useState<{\n      previousInputType?: 'text' | 'contact' | 'edit'\n      show: boolean\n      confirmCallBack?: () => void\n      contactImportCaches?: string[]\n    }>({\n      show: false,\n    })\n    const [showAddressReview, setShowAddressReview] = React.useState(false)\n    const [selectedAddresses, setSelectedAddresses] = React.useState([] as string[])\n    const [search, setSearch] = React.useState('')\n    const overMaximum =\n      getValidAddresses(addressListString, sentAddresses ?? []).length > maximumTargetsLength\n\n    return (\n      <RedPacketBoxStyle\n        height={'100%'}\n        maxHeight={'480px'}\n        justifyContent={'left'}\n        maxWidth={1152}\n        paddingX={isMobile ? 2 : 5}\n        position={'absolute'}\n        width={'100%'}\n      >\n        <Modal\n          open={showContactModal}\n          onClose={() => {\n            setShowContactModal(false)\n          }}\n          content={\n            <Box\n              display={'flex'}\n              flexDirection={'column'}\n              width={'var(--modal-width)'}\n              padding={5}\n              paddingTop={2}\n            >\n              <Typography marginBottom={3} variant={'h4'}>\n                {t('labelRedpacketContactImport')}\n              </Typography>\n              <InputSearch\n                onChange={(e) => {\n                  setSearch(e as unknown as string)\n                }}\n                value={search}\n              />\n              <Box height={300} marginTop={2} marginBottom={2} overflow={'scroll'}>\n                {contacts\n                  ?.filter((contact) => {\n                    return contact.contactAddress && contact.contactName && search\n                      ? contact.contactAddress.toLowerCase().includes(search.toLowerCase()) ||\n                          contact.contactName.toLowerCase().includes(search.toLowerCase())\n                      : true\n                  })\n                  .map((contact) => {\n                    return (\n                      <Box\n                        marginBottom={2}\n                        key={contact.contactAddress}\n                        display={'flex'}\n                        alignItems={'start'}\n                        justifyContent={'space-between'}\n                      >\n                        <Box display={'flex'}>\n                          <InitialNameAvatar name={contact.contactName} />\n                          <Box marginLeft={1}>\n                            <Typography>{contact.contactName}</Typography>\n                            <Typography variant={'body2'}>{contact.contactAddress}</Typography>\n                          </Box>\n                        </Box>\n                        <Checkbox\n                          onChange={() => {\n                            const newSelectedAddresses = selectedAddresses.find(\n                              (addr) => addr === contact.contactAddress,\n                            )\n                              ? selectedAddresses.filter((addr) => addr !== contact.contactAddress)\n                              : [contact.contactAddress, ...selectedAddresses]\n                            setSelectedAddresses(newSelectedAddresses)\n                          }}\n                          checked={\n                            selectedAddresses.find((addr) => addr === contact.contactAddress)\n                              ? true\n                              : false\n                          }\n                        />\n                      </Box>\n                    )\n                  })}\n              </Box>\n              <Typography marginBottom={1}>\n                {t('labelRedpacketExclusiveSelected', { count: selectedAddresses.length })}\n              </Typography>\n              <Box>\n                <Button\n                  onClick={() => {\n                    setShowChangeTips({\n                      ...showChangeTips,\n                      contactImportCaches: selectedAddresses,\n                      previousInputType: 'contact',\n                    })\n                    setInputDisabled(true)\n                    onConfirm(selectedAddresses)\n                    setShowContactModal(false)\n                  }}\n                  variant={'contained'}\n                  fullWidth\n                  disabled={\n                    selectedAddresses.length === 0 ||\n                    selectedAddresses.length > maximumTargetsLength\n                  }\n                >\n                  {selectedAddresses.length > maximumTargetsLength\n                    ? t('labelRedPacketMaxValueExceeded')\n                    : t('labelConfirm')}\n                </Button>\n              </Box>\n            </Box>\n          }\n        />\n        <Modal\n          open={showPopUpTips}\n          onClose={() => {\n            setShowPopUpTips(false)\n          }}\n          content={\n            <Box\n              display={'flex'}\n              flexDirection={'column'}\n              width={'var(--modal-width)'}\n              padding={5}\n              paddingTop={2}\n            >\n              <Typography textAlign={'center'} marginBottom={3} variant={'h4'}>\n                {t('labelRedpacketTips')}\n              </Typography>\n              <Typography marginBottom={3}>{t('labelRedpacketPopPpDes')}</Typography>\n\n              <Box marginTop={3}>\n                <Button\n                  onClick={() => {\n                    setShowPopUpTips(false)\n                  }}\n                  variant={'contained'}\n                  fullWidth\n                >\n                  {t('labelConfirm')}\n                </Button>\n              </Box>\n            </Box>\n          }\n        />\n        <Modal\n          open={showChangeTips.show}\n          onClose={() => {\n            setShowChangeTips({\n              ...showChangeTips,\n              show: false,\n            })\n          }}\n          content={\n            <Box\n              display={'flex'}\n              flexDirection={'column'}\n              width={'var(--modal-width)'}\n              padding={5}\n              paddingTop={2}\n            >\n              <Typography textAlign={'center'} marginBottom={3} variant={'h4'}>\n                {t('labelRedpacketTips')}\n              </Typography>\n              <Typography marginBottom={3}>{t('labelRedpacketChangeImportTips')}</Typography>\n\n              <Box height={48} marginTop={3}>\n                <Button\n                  sx={{\n                    width: '48%',\n                    height: '100%',\n                    marginRight: '4%',\n                  }}\n                  onClick={() => {\n                    setShowChangeTips({\n                      ...showChangeTips,\n                      show: false,\n                    })\n                  }}\n                  variant={'outlined'}\n                >\n                  {t('labelCancel')}\n                </Button>\n                <Button\n                  sx={{\n                    width: '48%',\n                    height: '100%',\n                  }}\n                  onClick={() => {\n                    showChangeTips.confirmCallBack && showChangeTips.confirmCallBack()\n                  }}\n                  variant={'contained'}\n                >\n                  {t('labelConfirm')}\n                </Button>\n              </Box>\n            </Box>\n          }\n        />\n        <Modal\n          open={showAddressReview}\n          onClose={() => {\n            setShowAddressReview(false)\n          }}\n          content={\n            <Box\n              display={'flex'}\n              flexDirection={'column'}\n              width={'var(--modal-width)'}\n              padding={5}\n              paddingTop={2}\n            >\n              <Typography textAlign={'center'} marginBottom={3} variant={'h4'}>\n                {t('labelRedpacketAddressesReview')}\n              </Typography>\n              <Box\n                borderRadius={1}\n                padding={1}\n                border={'1px solid var(--color-border)'}\n                overflow={'scroll'}\n              >\n                <Typography marginBottom={3} height={theme.unit * 20}>\n                  {addressListString &&\n                    addressListString\n                      .split(';')\n                      .filter((str) => str.trim())\n                      .map((str, index) => (\n                        <>\n                          <Typography\n                            color={\n                              isAddressValid(\n                                str.trim(),\n                                addressListString\n                                  .split(';')\n                                  .filter((str) => str.trim())\n                                  .slice(0, index)\n                                  .concat(sentAddresses ?? []),\n                              )\n                                ? 'var(--color-text-primary)'\n                                : 'var(--color-error)'\n                            }\n                            component={'span'}\n                          >\n                            {str}\n                          </Typography>{' '}\n                          ;<br />\n                        </>\n                      ))}\n\n                  {/* This list contains 2 valid addresses, <Typography component={'span'} color={'var(--color-error)'}>1 invalid addresses</Typography>.  To proceed, invalid addresses will be automatically removed from the list. */}\n                </Typography>\n              </Box>\n              <Typography marginTop={2} marginBottom={3}>\n                {t('labelRedpacketAddressesReviewPart1', {\n                  count: getValidAddresses(addressListString, sentAddresses ?? []).length,\n                })}{' '}\n                <Typography component={'span'} color={'var(--color-error)'}>\n                  {t('labelRedpacketAddressesReviewPart2', {\n                    count: getInvalidAddresses(addressListString, sentAddresses ?? []).length,\n                  })}\n                </Typography>\n                {t('labelRedpacketAddressesReviewPart3')}\n              </Typography>\n\n              <Box height={48} marginTop={3}>\n                <Button\n                  sx={{\n                    width: '48%',\n                    height: '100%',\n                    marginRight: '4%',\n                  }}\n                  onClick={() => {\n                    setShowAddressReview(false)\n                  }}\n                  variant={'outlined'}\n                >\n                  {t('labelCancel')}\n                </Button>\n                <Button\n                  sx={{\n                    width: '48%',\n                    height: '100%',\n                  }}\n                  onClick={() => {\n                    setShowAddressReview(false)\n                    setShowChangeTips({\n                      ...showChangeTips,\n                      contactImportCaches: undefined,\n                      previousInputType: undefined,\n                      confirmCallBack: undefined,\n                    })\n                    onClickSend()\n                  }}\n                  variant={'contained'}\n                >\n                  {t('labelConfirm')}\n                </Button>\n              </Box>\n              {/* <Box marginTop={3}>\n\n              </Box> */}\n            </Box>\n          }\n        />\n\n        <Typography marginTop={4} marginBottom={0.5}>\n          {t('labelRedPacketExclusive')}\n        </Typography>\n        <Typography color={'var(--color-text-secondary)'}>\n          {t('labelExclusiveWhitelistDes')}\n        </Typography>\n\n        <Box marginTop={3} borderRadius={1} paddingRight={2}>\n          <MultiLineInput\n            disabled={inputDisabled}\n            onInput={(e) => {\n              setShowChangeTips({\n                ...showChangeTips,\n                previousInputType: 'edit',\n              })\n              onManualEditInput(e.currentTarget.value)\n            }}\n            value={addressListString}\n            placeholder={`eg:0x60eEB5870ebEf49ce7cDc354dac49906CF8d9285;\\n0xF61f3C9cEcB8d206DeA1faEd99A693e6d3BAAEf2;`}\n          />\n          <Box marginTop={2} display={'flex'} justifyContent={'space-between'}>\n            <Box display={'flex'} alignItems={'center'}>\n              <Typography\n                color={\n                  maximumTargetsLength -\n                    getValidAddresses(addressListString, sentAddresses ?? []).length <\n                  0\n                    ? 'var(--color-error)'\n                    : ''\n                }\n                marginRight={2}\n              >\n                {maximumTargetsLength -\n                  getValidAddresses(addressListString, sentAddresses ?? []).length >=\n                0\n                  ? t('labelSendRedPacketMax', {\n                      count:\n                        maximumTargetsLength -\n                        getValidAddresses(addressListString, sentAddresses ?? []).length,\n                    })\n                  : t('labelRedPacketMaxValueExceeded')}\n              </Typography>\n              {\n                <Button\n                  onClick={(_e) => {\n                    onManualEditInput('')\n                    setInputDisabled(false)\n                    setShowChangeTips({\n                      show: false,\n                      previousInputType: undefined,\n                    })\n                  }}\n                  variant={'outlined'}\n                >\n                  {t('labelSendRedPacketClear')}\n                </Button>\n              }\n            </Box>\n\n            <Box>\n              <FormControlLabel\n                control={\n                  <input\n                    onInput={(e) => {\n                      const reader = new FileReader()\n                      reader.onload = (event) => {\n                        setInputDisabled(true)\n                        onFileInput(event.target?.result ? (event.target.result as string) : '')\n                        setShowChangeTips({\n                          ...showChangeTips,\n                          previousInputType: 'text',\n                        })\n                      }\n                      e.currentTarget.files && reader.readAsText(e.currentTarget.files[0])\n                      e.currentTarget.value = ''\n                    }}\n                    style={{ display: 'none' }}\n                    id='file-upload'\n                    type='file'\n                    accept='.txt'\n                  />\n                }\n                label={\n                  <Button\n                    onClick={(e) => {\n                      const parentNode = e.currentTarget.parentNode as any\n                      if (\n                        showChangeTips.previousInputType &&\n                        showChangeTips.previousInputType !== 'text'\n                      ) {\n                        setShowChangeTips({\n                          ...showChangeTips,\n                          show: true,\n                          confirmCallBack() {\n                            setShowChangeTips((showChangeTips) => ({\n                              ...showChangeTips,\n                              show: false,\n                            }))\n                            parentNode.click()\n                            onManualEditInput('')\n                          },\n                        })\n                      } else {\n                        parentNode.click()\n                      }\n                    }}\n                    variant={'outlined'}\n                  >\n                    {t('labelRedpacketTextimport')}\n                  </Button>\n                }\n              />\n              <Button\n                onClick={(_e) => {\n                  if (\n                    showChangeTips.previousInputType &&\n                    showChangeTips.previousInputType !== 'contact'\n                  ) {\n                    setShowChangeTips({\n                      ...showChangeTips,\n                      show: true,\n                      confirmCallBack() {\n                        setShowChangeTips((showChangeTips) => ({\n                          ...showChangeTips,\n                          show: false,\n                        }))\n                        onManualEditInput('')\n                        setSelectedAddresses([])\n                        setShowContactModal(true)\n                      },\n                    })\n                  } else {\n                    setSelectedAddresses([])\n                    setShowContactModal(true)\n                  }\n                }}\n                variant={'outlined'}\n              >\n                {t('labelRedpacketContactImport')}\n              </Button>\n            </Box>\n          </Box>\n        </Box>\n\n        <Typography variant={'h5'} marginTop={5} marginBottom={1.5}>\n          {t('labelRedpacketNotificationDisplay')}\n        </Typography>\n        <Box display={'flex'}>\n          <Box width={'45%'} marginRight={'10%'}>\n            <FormControlLabel\n              control={\n                <Checkbox\n                  // checked={popupChecked}\n                  checked\n                  checkedIcon={<CheckedIcon />}\n                  icon={<CheckBoxIcon />}\n                  color='default'\n                />\n              }\n              label={t('labelRedpacketBadge')}\n            />\n            <Box marginLeft={3}>\n              <Typography marginBottom={3} color={'var(--color-text-secondary)'}>\n                {t('labelRedpacketRedDotDes')}\n              </Typography>\n              <img width={260} src={SoursURL + 'images/target_option_red_dot.png'} />\n            </Box>\n          </Box>\n          <Box width={'45%'}>\n            <FormControlLabel\n              control={\n                <Checkbox\n                  checked={popupChecked}\n                  onChange={(_event: any, _state: boolean) => {\n                    if (popUpOptionDisabled) {\n                      setShowPopUpTips(true)\n                    } else {\n                      onChangePopupChecked(!popupChecked)\n                    }\n                  }}\n                  checkedIcon={<CheckedIcon />}\n                  icon={<CheckBoxIcon />}\n                  color='default'\n                />\n              }\n              label={\n                <Typography display={'flex'} alignItems={'center'}>\n                  <Typography marginRight={0.5}>{t('labelRedpacketPopUp')}</Typography>{' '}\n                  <Tooltip title={t('labelRedpacketPopUpTooltip')}>\n                    <span>\n                      <Info2Icon />\n                    </span>\n                  </Tooltip>{' '}\n                </Typography>\n              }\n            />\n            <Box marginLeft={3}>\n              <Typography marginBottom={3} color={'var(--color-text-secondary)'}>\n                {t('labelRedpacketPopPpDes')}\n              </Typography>\n              <img width={300} src={SoursURL + 'images/target_option_pop.png'} />\n            </Box>\n          </Box>\n        </Box>\n\n        <Box marginTop={10} display={'flex'} justifyContent={'center'}>\n          <Box width={'40%'} marginRight={'10%'} marginBottom={4}>\n            <Button\n              variant={'outlined'}\n              size={'medium'}\n              fullWidth\n              className={'step'}\n              startIcon={<BackIcon fontSize={'small'} />}\n              color={'primary'}\n              sx={{ height: 'var(--btn-medium-height)' }}\n              onClick={() => {\n                setShowChangeTips({ show: false })\n                setInputDisabled(false)\n                onClickBack()\n                clearInput()\n              }}\n            >\n              {t('labelMintBack')}\n            </Button>\n          </Box>\n          <Box width={'40%'} marginBottom={4}>\n            {overMaximum ? (\n              <Button\n                variant={'contained'}\n                size={'medium'}\n                fullWidth\n                color={'primary'}\n                sx={{ height: 'var(--btn-medium-height)' }}\n                disabled\n              >\n                {t('labelRedPacketMaxValueExceeded')}\n              </Button>\n            ) : (\n              <BtnMain\n                {...{\n                  defaultLabel: 'labelRedpacketPrepareRedPacket',\n                  fullWidth: true,\n                  disabled: () => {\n                    return (\n                      getValidAddresses(addressListString, sentAddresses ?? []).length === 0 ||\n                      overMaximum\n                    )\n                  },\n                  onClick: () => {\n                    if (getInvalidAddresses(addressListString, sentAddresses ?? []).length > 0) {\n                      setShowAddressReview(true)\n                    } else {\n                      setShowChangeTips({\n                        ...showChangeTips,\n                        contactImportCaches: undefined,\n                        previousInputType: undefined,\n                        confirmCallBack: undefined,\n                      })\n                      onClickSend()\n                    }\n                  },\n                }}\n              />\n            )}\n          </Box>\n        </Box>\n      </RedPacketBoxStyle>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/DeFiWrap/DeFiStackOneSideWrap.tsx",
    "content": "import {\n  DeFiSideCalcData,\n  EmptyValueTag,\n  getValuePrecisionThousand,\n  HelpIcon,\n  IBData,\n  Info2Icon,\n  L1L2_NAME_DEFINED,\n  MapChainId,\n  myLog,\n  TradeBtnStatus,\n  YEAR_DAY_MINUTE_FORMAT,\n} from '@loopring-web/common-resources'\nimport { DeFiSideType, DeFiSideWrapProps } from './Interface'\nimport { Trans, useTranslation } from 'react-i18next'\nimport React from 'react'\nimport { Box, Grid, Tooltip, Typography } from '@mui/material'\nimport { InputCoin, Button } from '../../../basic-lib'\nimport { ButtonStyle } from '../Styled'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport moment from 'moment'\nimport styled from '@emotion/styled'\nimport { useSettings } from '../../../../stores'\n\nconst GridStyle = styled(Grid)`\n  input::placeholder {\n    font-size: ${({ theme }) => theme.fontDefault.h5};\n  }\n  .coinInput-wrap {\n    background-color: var(--color-global-bg);\n    border: 1px solid var(--color-border);\n  }\n`\n\nexport const DeFiSideDetail = ({\n  // stakeViewInfo,\n  tokenSell,\n  order,\n  onRedeem,\n}: DeFiSideType) => {\n  const { t } = useTranslation()\n  // myLog(\n  //   moment(new Date(order.stakeAt ?? \"\"))\n  //     .utc()\n  //     .startOf(\"days\")\n  //     .toString()\n  // );\n  const diff = moment(Date.now()).diff(\n    moment(new Date(order.stakeAt ?? ''))\n      .utc()\n      .startOf('days'),\n    'days',\n    false,\n  )\n  return (\n    <Box flex={1}>\n      <Box\n        display={'flex'}\n        flexDirection={'column'}\n        alignItems={'stretch'}\n        justifyContent={'space-between'}\n        paddingX={3}\n      >\n        <Typography\n          variant={'body1'}\n          display={'inline-flex'}\n          alignItems={'center'}\n          justifyContent={'space-between'}\n          paddingBottom={2}\n        >\n          <Typography\n            component={'span'}\n            variant={'inherit'}\n            color={'textSecondary'}\n            display={'inline-flex'}\n            alignItems={'center'}\n          >\n            <Trans i18nKey={'labelDeFiSideAmount'}>Amount</Trans>\n          </Typography>\n          <Typography component={'span'} variant={'inherit'}>\n            {order.remainAmount && order.remainAmount != '0'\n              ? getValuePrecisionThousand(\n                  sdk.toBig(order.remainAmount).div('1e' + tokenSell.decimals),\n                  tokenSell.precision,\n                  tokenSell.precision,\n                  tokenSell.precision,\n                  false,\n                  { floor: false, isAbbreviate: true },\n                ) +\n                ' ' +\n                tokenSell.symbol\n              : EmptyValueTag}\n          </Typography>\n        </Typography>\n        <Typography\n          variant={'body1'}\n          display={'inline-flex'}\n          alignItems={'center'}\n          justifyContent={'space-between'}\n          paddingBottom={2}\n        >\n          <Typography\n            component={'span'}\n            variant={'inherit'}\n            color={'textSecondary'}\n            display={'inline-flex'}\n            alignItems={'center'}\n          >\n            {t('labelDeFiSideProduct')}\n          </Typography>\n          <Typography component={'span'} variant={'inherit'}>\n            {order?.productId ?? EmptyValueTag}\n          </Typography>\n        </Typography>\n        <Typography\n          variant={'body1'}\n          display={'inline-flex'}\n          alignItems={'center'}\n          justifyContent={'space-between'}\n          paddingBottom={2}\n        >\n          <Typography\n            component={'span'}\n            variant={'inherit'}\n            color={'textSecondary'}\n            display={'inline-flex'}\n            alignItems={'center'}\n          >\n            {t('labelDeFiSidePoolShare')}\n          </Typography>\n          <Typography component={'span'} variant={'inherit'}>\n            {order?.remainAmount && order?.staked && order.staked != '0'\n              ? getValuePrecisionThousand(\n                  sdk.toBig(order.remainAmount).div(order.staked).times(100),\n                  2,\n                  2,\n                  undefined,\n                ) + '%'\n              : EmptyValueTag}\n          </Typography>\n        </Typography>\n        <Typography\n          variant={'body1'}\n          display={'inline-flex'}\n          alignItems={'center'}\n          justifyContent={'space-between'}\n          paddingBottom={2}\n        >\n          <Typography\n            component={'span'}\n            variant={'inherit'}\n            color={'textSecondary'}\n            display={'inline-flex'}\n            alignItems={'center'}\n          >\n            <Trans i18nKey={'labelDeFiSidePoolAPR'}>APR</Trans>\n          </Typography>\n          <Typography component={'span'} variant={'inherit'}>\n            {order.apr && order.apr !== '0.00' ? order.apr + '%' : EmptyValueTag}\n          </Typography>\n        </Typography>{' '}\n        <Typography\n          variant={'body1'}\n          display={'inline-flex'}\n          alignItems={'center'}\n          justifyContent={'space-between'}\n          paddingBottom={2}\n        >\n          <Typography\n            component={'span'}\n            variant={'inherit'}\n            color={'textSecondary'}\n            display={'inline-flex'}\n            alignItems={'center'}\n          >\n            <Trans i18nKey={'labelDeFiSideCumulativeEarnings'}>Cumulative Earnings</Trans>\n          </Typography>\n          <Typography component={'span'} variant={'inherit'}>\n            {order.totalRewards && order.totalRewards != '0'\n              ? getValuePrecisionThousand(\n                  sdk.toBig(order.totalRewards).div('1e' + tokenSell.decimals),\n                  tokenSell.precision,\n                  tokenSell.precision,\n                  undefined,\n                  false,\n                  { floor: false, isAbbreviate: true },\n                ) +\n                ' ' +\n                tokenSell.symbol\n              : EmptyValueTag}\n          </Typography>\n        </Typography>\n        <Typography\n          variant={'body1'}\n          display={'inline-flex'}\n          alignItems={'center'}\n          justifyContent={'space-between'}\n          paddingBottom={2}\n        >\n          <Typography\n            component={'span'}\n            variant={'inherit'}\n            color={'textSecondary'}\n            display={'inline-flex'}\n            alignItems={'center'}\n          >\n            <Trans i18nKey={'labelDeFiSidePreviousEarnings'}>Previous Day's Earnings</Trans>\n          </Typography>\n          <Typography component={'span'} variant={'inherit'}>\n            {order.lastDayPendingRewards && order.lastDayPendingRewards != '0'\n              ? getValuePrecisionThousand(\n                  sdk.toBig(order.lastDayPendingRewards).div('1e' + tokenSell.decimals),\n                  tokenSell.precision,\n                  tokenSell.precision,\n                  undefined,\n                  false,\n                  { floor: false, isAbbreviate: true },\n                ) +\n                ' ' +\n                tokenSell.symbol\n              : EmptyValueTag}\n          </Typography>\n        </Typography>\n        <Typography\n          variant={'body1'}\n          display={'inline-flex'}\n          alignItems={'center'}\n          justifyContent={'space-between'}\n          paddingBottom={2}\n        >\n          <Typography\n            component={'span'}\n            variant={'inherit'}\n            color={'textSecondary'}\n            display={'inline-flex'}\n            alignItems={'center'}\n          >\n            <Trans i18nKey={'labelDeFiSideLockDuration'}>Lock duration to claim reward</Trans>\n          </Typography>\n          <Typography component={'span'} variant={'inherit'}>\n            {'≥ ' + (order.claimableTime - order.stakeAt) / 86400000 + ' ' + t('labelDay')}\n          </Typography>\n        </Typography>{' '}\n        <Typography\n          variant={'body1'}\n          display={'inline-flex'}\n          alignItems={'center'}\n          justifyContent={'space-between'}\n          paddingBottom={2}\n        >\n          <Typography\n            component={'span'}\n            variant={'inherit'}\n            color={'textSecondary'}\n            display={'inline-flex'}\n            alignItems={'center'}\n          >\n            <Trans i18nKey={'labelDeFiSideSubscribeTime'}>Subscribe Time</Trans>\n          </Typography>\n          <Typography component={'span'} variant={'inherit'}>\n            {moment(new Date(order.stakeAt))\n              // .utc()\n              // .startOf(\"days\")\n              .format(YEAR_DAY_MINUTE_FORMAT)}\n          </Typography>\n        </Typography>\n        <Typography\n          variant={'body1'}\n          display={'inline-flex'}\n          alignItems={'center'}\n          justifyContent={'space-between'}\n          paddingBottom={2}\n        >\n          <Typography\n            component={'span'}\n            variant={'inherit'}\n            color={'textSecondary'}\n            display={'inline-flex'}\n            alignItems={'center'}\n          >\n            <Trans i18nKey={'labelDeFiSideHoldingTime'}>Holding Time</Trans>\n          </Typography>\n          <Typography component={'span'} variant={'inherit'}>\n            {diff ? diff + ' ' + t('labelDays') : '< 1' + ' ' + t('labelDays')}\n          </Typography>\n        </Typography>\n        <Typography\n          variant={'body1'}\n          display={'inline-flex'}\n          alignItems={'center'}\n          justifyContent={'space-between'}\n          paddingTop={4}\n          paddingBottom={2}\n        >\n          <Button\n            fullWidth\n            size={'large'}\n            variant={'contained'}\n            color={'primary'}\n            onClick={() => {\n              onRedeem(order)\n            }}\n          >\n            {t('labelDefiStakingRedeem')}\n          </Button>\n        </Typography>\n      </Box>\n    </Box>\n  )\n}\nexport const DeFiSideWrap = <T extends IBData<I>, I, ACD extends DeFiSideCalcData<T>>({\n  disabled,\n  isJoin,\n  btnInfo,\n  onSubmitClick,\n  switchStobEvent,\n  onChangeEvent,\n  handleError,\n  deFiSideCalcData,\n  accStatus,\n  tokenSell,\n  isLoading,\n  btnStatus,\n  tokenSellProps,\n  minSellAmount,\n  maxSellAmount,\n  setShowLRCStakePopup,\n  ...rest\n}: DeFiSideWrapProps<T, I, ACD>) => {\n  // @ts-ignore\n  const coinSellRef = React.useRef()\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const { t } = useTranslation()\n  const getDisabled = React.useMemo(() => {\n    return disabled || deFiSideCalcData === undefined\n  }, [btnStatus, deFiSideCalcData, disabled])\n\n  const handleCountChange = React.useCallback(\n    (ibData: T, _name: string, _ref: any) => {\n      if (deFiSideCalcData.coinSell.tradeValue !== ibData.tradeValue) {\n        myLog('defi handleCountChange', _name, ibData)\n        onChangeEvent({\n          tradeData: { ...ibData },\n        })\n      }\n    },\n    [deFiSideCalcData, onChangeEvent],\n  )\n  const propsSell = {\n    label: t('tokenEnterPaymentToken'),\n    subLabel: t('tokenMax'),\n    emptyText: t('tokenSelectToken'),\n    placeholderText:\n      minSellAmount && maxSellAmount\n        ? t('labelInvestMaxDefi', {\n            minValue: getValuePrecisionThousand(\n              minSellAmount,\n              tokenSell.precision,\n              tokenSell.precision,\n              tokenSell.precision,\n              false,\n              { floor: false, isAbbreviate: true },\n            ),\n            maxValue: getValuePrecisionThousand(\n              maxSellAmount,\n              tokenSell.precision,\n              tokenSell.precision,\n              tokenSell.precision,\n              false,\n              { floor: false, isAbbreviate: true },\n            ),\n          })\n        : // <Typography variant={\"body1\"} color={\"var(--color-text-third)\"}>\n          //\n          // </Typography>\n          '0.00',\n    isShowCoinInfo: true,\n    isShowCoinIcon: true,\n    maxAllow: true,\n    ...tokenSellProps,\n    handleError: (data: any) => {\n      if (\n        data.tradeValue &&\n        (data.tradeValue > data.balance ||\n          sdk.toBig(data.tradeValue).gt(maxSellAmount) ||\n          sdk.toBig(data.tradeValue).lt(minSellAmount))\n      ) {\n        return {\n          error: true,\n        }\n      }\n      return {\n        error: false,\n      }\n    },\n    handleCountChange: handleCountChange as any,\n    ...rest,\n  } as any\n\n  const label = React.useMemo(() => {\n    if (btnInfo?.label) {\n      const key = btnInfo?.label.split('|')\n      return t(\n        key[0],\n        key && key[1]\n          ? {\n              arg: key[1],\n              layer2: L1L2_NAME_DEFINED[network].layer2,\n              l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n              l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n              l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n              ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n            }\n          : {\n              layer2: L1L2_NAME_DEFINED[network].layer2,\n              l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n              l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n              l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n              ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n            },\n      )\n    } else {\n      return isJoin\n        ? t(`labelInvestBtn`, {\n            layer2: L1L2_NAME_DEFINED[network].layer2,\n            l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n            loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n            l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n            l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n            ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n          })\n        : t(`labelRedeemBtn`, {\n            layer2: L1L2_NAME_DEFINED[network].layer2,\n            l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n            loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n            l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n            l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n            ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n          })\n    }\n  }, [isJoin, t, btnInfo])\n\n  const daysDuration = Math.ceil(\n    Number(deFiSideCalcData?.stakeViewInfo?.rewardPeriod ?? 0) / 86400000,\n  )\n  let dalyEarn = deFiSideCalcData?.stakeViewInfo?.dalyEarn\n    ? getValuePrecisionThousand(\n        sdk\n          .toBig(deFiSideCalcData.stakeViewInfo.dalyEarn)\n          .div('1e' + tokenSell.decimals)\n          .div(100),\n        tokenSell.precision,\n        tokenSell.precision,\n        tokenSell.precision,\n        false,\n      )\n    : undefined\n  dalyEarn = dalyEarn && dalyEarn !== '0' ? dalyEarn + ' ' + tokenSell.symbol : EmptyValueTag\n  myLog('deFiSideCalcData.stakeViewInfo', deFiSideCalcData.stakeViewInfo)\n  return (\n    <GridStyle\n      className={deFiSideCalcData ? '' : 'loading'}\n      container\n      direction={'column'}\n      justifyContent={'space-between'}\n      alignItems={'center'}\n      flex={1}\n      height={'100%'}\n    >\n      <Grid\n        item\n        display={'flex'}\n        justifyContent={'space-between'}\n        alignItems={'center'}\n        flexDirection={'row'}\n        width={'100%'}\n        className={'MuiToolbar-root'}\n      >\n        <Typography\n          height={'100%'}\n          display={'inline-flex'}\n          variant={'h5'}\n          alignItems={'center'}\n          alignSelf={'self-start'}\n        >\n          {t('labelInvestLRCTitle')}\n          <HelpIcon\n            fontSize={'large'}\n            color={'inherit'}\n            sx={{ marginLeft: 1, cursor: 'pointer' }}\n            onClick={() => {\n              setShowLRCStakePopup({ isShow: true, confirmationNeeded: false })\n            }}\n          />\n        </Typography>\n      </Grid>\n      <Grid\n        item\n        marginTop={2}\n        paddingTop={2}\n        paddingBottom={3}\n        flexDirection={'column'}\n        display={'flex'}\n        alignSelf={'stretch'}\n        alignItems={'stretch'}\n        borderTop={'1px solid var(--color-border)'}\n        borderBottom={'1px solid var(--color-border)'}\n      >\n        <InputCoin<T, I, any>\n          ref={coinSellRef}\n          disabled={getDisabled}\n          {...{\n            ...propsSell,\n            name: 'coinSell',\n            isHideError: true,\n            order: 'right',\n            inputData: deFiSideCalcData ? deFiSideCalcData.coinSell : ({} as any),\n            coinMap: {},\n            coinPrecision: tokenSell.precision,\n          }}\n          label={<Typography color={'var(--color-text-secondary)'}>Amount</Typography>}\n        />\n      </Grid>\n      <>\n        {/* <Grid item alignSelf={'stretch'} marginTop={3 / 2} marginBottom={3}>\n          <Typography\n            component={'span'}\n            display={'inline-flex'}\n            color={'textSecondary'}\n          >\n            <Trans i18nKey={'labelInvestLRCStakingLockAlert'}>\n              Your assets for investment will be locked until your redemption.\n            </Trans>\n          </Typography>\n        </Grid> */}\n        <Box marginTop={3} width={'100%'} borderRadius={1}>\n          <Grid container justifyContent={'space-between'} direction={'row'} alignItems={'center'}>\n            <Tooltip title={t('labelLRCStakeAPRTooltips').toString()} placement={'top'} key={'APR'}>\n              <Typography\n                component={'p'}\n                color={'textSecondary'}\n                display={'inline-flex'}\n                alignItems={'center'}\n              >\n                <Trans i18nKey={'labelLRCStakeAPR'}>\n                  APR\n                  <Info2Icon fontSize={'small'} color={'inherit'} sx={{ marginX: 1 / 2 }} />\n                </Trans>\n              </Typography>\n            </Tooltip>\n            <Typography component={'p'} color={'var(--color-success)'}>\n              {deFiSideCalcData?.stakeViewInfo?.apr &&\n              deFiSideCalcData?.stakeViewInfo?.apr !== '0.00'\n                ? deFiSideCalcData.stakeViewInfo.apr + '%'\n                : EmptyValueTag}\n            </Typography>\n          </Grid>\n\n          <Grid\n            container\n            justifyContent={'space-between'}\n            direction={'row'}\n            alignItems={'center'}\n            marginTop={2}\n          >\n            <Tooltip title={t('labelLRCStakeEarnTooltips').toString()} placement={'top'}>\n              <Typography\n                component={'p'}\n                color={'textSecondary'}\n                display={'inline-flex'}\n                alignItems={'center'}\n              >\n                <Trans i18nKey={'labelLRCStakeEarn'}>\n                  Earn\n                  <Info2Icon fontSize={'small'} color={'inherit'} sx={{ marginX: 1 / 2 }} />\n                </Trans>\n              </Typography>\n            </Tooltip>\n            <Typography component={'p'} color={'textPrimary'}>\n              {dalyEarn}\n            </Typography>\n          </Grid>\n          <Grid\n            container\n            justifyContent={'space-between'}\n            direction={'row'}\n            alignItems={'center'}\n            marginTop={2}\n          >\n            <Tooltip\n              title={t('labelLRCStakeDurationTooltips', {\n                day: daysDuration ? daysDuration : EmptyValueTag,\n              }).toString()}\n              placement={'top'}\n            >\n              <Typography\n                component={'p'}\n                color={'textSecondary'}\n                display={'inline-flex'}\n                alignItems={'center'}\n              >\n                <Trans i18nKey={'labelLRCStakeDuration'}>\n                  Duration\n                  <Info2Icon fontSize={'small'} color={'inherit'} sx={{ marginX: 1 / 2 }} />\n                </Trans>\n              </Typography>\n            </Tooltip>\n            <Typography component={'p'} color={'textPrimary'}>\n              {daysDuration ? '≥ ' + daysDuration + ' ' + t('labelDay') : EmptyValueTag}\n            </Typography>\n          </Grid>\n        </Box>\n\n        {/* <Grid item alignSelf={'stretch'} marginTop={3} >\n          <Typography\n            component={'p'}\n            color={'var(--color-text-secondary)'}\n            display={'inline-flex'}\n            alignItems={'center'}\n          >\n            <Trans\n              i18nKey={'labelLRCStakeRiskDes'}\n              tOptions={{\n                loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n              }}\n            >\n              The staked LRC is locked in Loopring L2 and won't be able to used for other purpose\n              although it can be redeemed any time; while if the staking is redeemed before 90 days,\n              the accumulated reward will be dismissed.\n            </Trans>\n          </Typography>\n        </Grid> */}\n      </>\n\n      <Grid item alignSelf={'stretch'} marginTop={4}>\n        <Grid container direction={'column'} spacing={1} alignItems={'stretch'}>\n          <Grid item>\n            <ButtonStyle\n              fullWidth\n              variant={'contained'}\n              size={'large'}\n              color={'primary'}\n              onClick={() => {\n                onSubmitClick()\n              }}\n              loading={!getDisabled && btnStatus === TradeBtnStatus.LOADING ? 'true' : 'false'}\n              disabled={\n                getDisabled ||\n                btnStatus === TradeBtnStatus.LOADING ||\n                btnStatus === TradeBtnStatus.DISABLED\n              }\n            >\n              {label}\n            </ButtonStyle>\n          </Grid>\n        </Grid>\n      </Grid>\n    </GridStyle>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/DeFiWrap/DeFiStackRedeemWrap.tsx",
    "content": "import {\n  CheckBoxIcon,\n  CheckedIcon,\n  DeFiSideRedeemCalcData,\n  EmptyValueTag,\n  getValuePrecisionThousand,\n  IBData,\n  L1L2_NAME_DEFINED,\n  MapChainId,\n  myLog,\n  TradeBtnStatus,\n} from '@loopring-web/common-resources'\nimport { DeFiStakeRedeemWrapProps } from './Interface'\nimport { Trans, useTranslation } from 'react-i18next'\nimport React from 'react'\nimport { Checkbox, FormControlLabel as MuiFormControlLabel, Grid, Typography } from '@mui/material'\nimport { InputCoin } from '../../../basic-lib'\nimport { ButtonStyle } from '../Styled'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport styled from '@emotion/styled'\nimport { useSettings } from '../../../../stores'\n\nconst GridStyle = styled(Grid)`\n  input::placeholder {\n    font-size: ${({ theme }) => theme.fontDefault.h5};\n  }\n\n  div {\n    textarea,\n    .coinInput-wrap,\n    .btnInput-wrap,\n    .MuiOutlinedInput-root {\n      background: var(--field-opacity);\n      border-color: var(--opacity);\n\n      :hover {\n        border-color: var(--color-border-hover);\n      }\n    }\n  }\n`\nexport const DeFiStackRedeemWrap = <T extends IBData<I>, I, ACD extends DeFiSideRedeemCalcData<T>>({\n  disabled,\n  isJoin,\n  btnInfo,\n  onSubmitClick,\n  switchStobEvent,\n  onChangeEvent,\n  handleError,\n  deFiSideRedeemCalcData,\n  accStatus,\n  tokenSell,\n  isLoading,\n  btnStatus,\n  minSellAmount,\n  maxSellAmount,\n  isFullTime,\n  ...rest\n}: DeFiStakeRedeemWrapProps<T, I, ACD>) => {\n  // @ts-ignore\n  const coinSellRef = React.useRef()\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const { t } = useTranslation()\n  const [agree, setAgree] = React.useState(!isJoin && !isFullTime ? false : true)\n  const getDisabled = React.useMemo(() => {\n    return disabled || deFiSideRedeemCalcData === undefined\n  }, [btnStatus, deFiSideRedeemCalcData, disabled])\n\n  const handleCountChange = React.useCallback(\n    (ibData: T, _name: string, _ref: any) => {\n      if (deFiSideRedeemCalcData.coinSell.tradeValue !== ibData.tradeValue) {\n        myLog('defi handleCountChange', _name, ibData)\n        onChangeEvent({\n          tradeData: { ...ibData },\n        })\n      }\n    },\n    [deFiSideRedeemCalcData, onChangeEvent],\n  )\n  const propsSell = {\n    label: t('tokenEnterPaymentToken'),\n    subLabel: t('tokenMax'),\n    emptyText: t('tokenSelectToken'),\n    placeholderText: '0.00',\n    isShowCoinInfo: true,\n    isShowCoinIcon: true,\n    maxAllow: true,\n    isHideError: false,\n    handleError: (data: any) => {\n      const value = sdk.toBig(data.balance).minus(data.tradeValue)\n      if (data.tradeValue && data.tradeValue > data.balance) {\n        return {\n          error: true,\n          message: t('tokenNotEnough', { belong: data.belong }),\n        }\n      } else if (value.lt(minSellAmount) && !value.eq(0)) {\n        return {\n          error: true,\n          message: t('labelRemainingAmount', {\n            symbol:\n              getValuePrecisionThousand(\n                minSellAmount,\n                tokenSell.precision,\n                tokenSell.precision,\n                tokenSell.precision,\n                false,\n              ) +\n              ' ' +\n              deFiSideRedeemCalcData.coinSell.belong,\n          }),\n        }\n      } else if (data.tradeValue && sdk.toBig(data.tradeValue).lt(minSellAmount)) {\n        return {\n          error: true,\n        }\n      }\n      return {\n        error: false,\n      }\n    },\n    handleCountChange: handleCountChange as any,\n    ...rest,\n  } as any\n\n  const label = React.useMemo(() => {\n    if (btnInfo?.label) {\n      const key = btnInfo?.label.split('|')\n      return t(\n        key[0],\n        key && key[1]\n          ? {\n              arg: key[1],\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n              l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n              l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n              ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n            }\n          : {\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n              l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n              l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n              ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n            },\n      )\n    } else {\n      return t(`labelRedeemBtn`, {\n        loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n        l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n        l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n        ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n      })\n    }\n  }, [t, btnInfo, network])\n\n  const { currentTotalEarnings, remainingEarn, forfeitedEarn, forfeitedEarnColor } =\n    React.useMemo(() => {\n      const { remainAmount, totalRewards } = deFiSideRedeemCalcData.stakeViewInfo\n      const tradeVol = sdk\n        .toBig(deFiSideRedeemCalcData.coinSell.tradeValue ?? 0)\n        .times('1e' + tokenSell.decimals)\n      const rateEarn = tradeVol.gt(0)\n        ? tradeVol.div(remainAmount).times(totalRewards)\n        : sdk.toBig(remainAmount).div(remainAmount).times(totalRewards)\n      // .toBig(remainAmount)\n      // .div(remainAmount)\n      return {\n        currentTotalEarnings:\n          totalRewards !== '0'\n            ? getValuePrecisionThousand(\n                sdk.toBig(totalRewards).div('1e' + tokenSell.decimals),\n                tokenSell.precision,\n                tokenSell.precision,\n                undefined,\n                false,\n              ) +\n              ' ' +\n              deFiSideRedeemCalcData.coinSell.belong\n            : EmptyValueTag,\n        ...(tradeVol.gt(remainAmount) || deFiSideRedeemCalcData.coinSell.tradeValue == undefined\n          ? {\n              forfeitedEarn: EmptyValueTag,\n              forfeitedEarnColor: 'var(--color-text-primary)',\n            }\n          : {\n              forfeitedEarnColor: 'var(--color-error)',\n              forfeitedEarn: rateEarn.gt(0)\n                ? '-' +\n                  getValuePrecisionThousand(\n                    rateEarn.div('1e' + tokenSell.decimals),\n                    tokenSell.precision,\n                    tokenSell.precision,\n                    undefined,\n                    false,\n                  ) +\n                  ' ' +\n                  deFiSideRedeemCalcData.coinSell.belong\n                : EmptyValueTag,\n            }),\n\n        remainingEarn:\n          tradeVol.lte(remainAmount) &&\n          rateEarn.gt(0) &&\n          sdk.toBig(totalRewards).minus(rateEarn).gt(0)\n            ? getValuePrecisionThousand(\n                sdk\n                  .toBig(totalRewards)\n                  .minus(rateEarn)\n                  .div('1e' + tokenSell.decimals),\n                tokenSell.precision,\n                tokenSell.precision,\n                undefined,\n                false,\n              ) +\n              ' ' +\n              deFiSideRedeemCalcData.coinSell.belong\n            : EmptyValueTag,\n      }\n    }, [deFiSideRedeemCalcData.stakeViewInfo, deFiSideRedeemCalcData.coinSell.tradeValue])\n  myLog(\n    'deFiSideRedeemCalcData.stakeViewInfo',\n    deFiSideRedeemCalcData.stakeViewInfo,\n    deFiSideRedeemCalcData.coinSell,\n  )\n  return (\n    <GridStyle\n      className={deFiSideRedeemCalcData ? '' : 'loading'}\n      container\n      direction={'column'}\n      justifyContent={'space-between'}\n      alignItems={'center'}\n      flex={1}\n      height={'100%'}\n    >\n      <Grid\n        item\n        display={'flex'}\n        justifyContent={'space-between'}\n        alignItems={'center'}\n        flexDirection={'row'}\n        width={'100%'}\n        className={'MuiToolbar-root'}\n      >\n        <Typography\n          height={'100%'}\n          display={'inline-flex'}\n          variant={'h5'}\n          alignItems={'center'}\n          alignSelf={'self-start'}\n        >\n          {t('labelInvestLRCTitle')}\n        </Typography>\n      </Grid>\n      <Grid\n        item\n        marginTop={1}\n        flexDirection={'column'}\n        display={'flex'}\n        alignSelf={'stretch'}\n        alignItems={'stretch'}\n      >\n        <InputCoin<T, I, any>\n          ref={coinSellRef}\n          disabled={getDisabled}\n          {...{\n            ...propsSell,\n            name: 'coinSell',\n            order: 'right',\n            inputData: deFiSideRedeemCalcData ? deFiSideRedeemCalcData.coinSell : ({} as any),\n            coinMap: {},\n            coinPrecision: tokenSell.precision,\n          }}\n        />\n      </Grid>\n      {isFullTime ? (\n        <>\n          <Grid\n            container\n            justifyContent={'space-between'}\n            direction={'row'}\n            alignItems={'center'}\n            marginTop={2}\n          >\n            <Typography\n              component={'p'}\n              variant={'body2'}\n              color={'textSecondary'}\n              display={'inline-flex'}\n              alignItems={'center'}\n            >\n              {t('labelLRCStakeProduct')}\n            </Typography>\n            <Typography component={'p'} variant={'body2'} color={'textPrimary'}>\n              {(deFiSideRedeemCalcData?.stakeViewInfo as any)?.productId}\n            </Typography>\n          </Grid>\n          <Grid item alignSelf={'stretch'} marginTop={3}>\n            <Typography\n              component={'p'}\n              variant='body1'\n              color={'var(--color-text-third)'}\n              display={'inline-flex'}\n              alignItems={'center'}\n            >\n              <Trans i18nKey={'labelLRCStakeRedeemDes'}>\n                The staked LRC is locked in Loopring L2 and won't be able to used for other purpose\n                although it can be redeemed any time; while if the staking is redeemed before 90\n                days, the accumulated reward will be dismissed.\n              </Trans>\n            </Typography>\n          </Grid>\n        </>\n      ) : (\n        <>\n          <Grid\n            container\n            justifyContent={'space-between'}\n            direction={'row'}\n            alignItems={'center'}\n            marginTop={2}\n          >\n            <Typography\n              component={'p'}\n              variant={'body2'}\n              color={'textSecondary'}\n              display={'inline-flex'}\n              alignItems={'center'}\n            >\n              <Trans i18nKey={'labelLRCStakeCurrentEarn'}>Current Total Earnings</Trans>\n            </Typography>\n            <Typography component={'p'} variant={'body2'} color={'textPrimary'}>\n              {currentTotalEarnings}\n            </Typography>\n          </Grid>\n          <Grid\n            container\n            justifyContent={'space-between'}\n            direction={'row'}\n            alignItems={'center'}\n            marginTop={2}\n          >\n            <Typography\n              component={'p'}\n              variant={'body2'}\n              color={'textSecondary'}\n              display={'inline-flex'}\n              alignItems={'center'}\n            >\n              <Trans i18nKey={'labelLRCStakeForfeitedReward'}>Forfeited Reward</Trans>\n            </Typography>\n            <Typography component={'p'} variant={'body2'} color={forfeitedEarnColor}>\n              {forfeitedEarn}\n            </Typography>\n          </Grid>\n          <Grid\n            container\n            justifyContent={'space-between'}\n            direction={'row'}\n            alignItems={'center'}\n            marginTop={2}\n          >\n            <Typography\n              component={'p'}\n              variant={'body2'}\n              color={'textSecondary'}\n              display={'inline-flex'}\n              alignItems={'center'}\n            >\n              <Trans i18nKey={'labelLRCStakeRemainingEarnings'}>Remaining Earnings</Trans>\n            </Typography>\n            <Typography component={'p'} variant={'body2'} color={'textPrimary'}>\n              {remainingEarn}\n            </Typography>\n          </Grid>\n          <Grid\n            container\n            justifyContent={'space-between'}\n            direction={'row'}\n            alignItems={'center'}\n            marginTop={2}\n          >\n            <Typography\n              component={'p'}\n              variant={'body2'}\n              color={'textSecondary'}\n              display={'inline-flex'}\n              alignItems={'center'}\n            >\n              {t('labelLRCStakeProduct')}\n            </Typography>\n            <Typography component={'p'} variant={'body2'} color={'textPrimary'}>\n              {(deFiSideRedeemCalcData?.stakeViewInfo as any)?.productId}\n            </Typography>\n          </Grid>\n          <Grid\n            container\n            justifyContent={'space-between'}\n            direction={'row'}\n            alignItems={'center'}\n            marginTop={5}\n          >\n            <MuiFormControlLabel\n              sx={{\n                alignItems: 'flex-start',\n                marginTop: 1 / 2,\n              }}\n              control={\n                <Checkbox\n                  checked={agree}\n                  onChange={(_event: any, state: boolean) => {\n                    setAgree(state)\n                  }}\n                  checkedIcon={<CheckedIcon />}\n                  icon={<CheckBoxIcon />}\n                  color='default'\n                />\n              }\n              label={\n                <Typography\n                  variant={'body1'}\n                  color={'textSecondary'}\n                  sx={{ wordBreak: 'break-all' }}\n                >\n                  {t('labelLRCStakeRedeemAgree')}\n                </Typography>\n              }\n            />\n          </Grid>\n        </>\n      )}\n\n      <Grid item alignSelf={'stretch'} marginTop={2}>\n        <Grid container direction={'column'} spacing={1} alignItems={'stretch'}>\n          <Grid item>\n            <ButtonStyle\n              fullWidth\n              variant={'contained'}\n              size={'medium'}\n              color={'primary'}\n              onClick={() => {\n                onSubmitClick()\n              }}\n              loading={!getDisabled && btnStatus === TradeBtnStatus.LOADING ? 'true' : 'false'}\n              disabled={\n                getDisabled ||\n                btnStatus === TradeBtnStatus.LOADING ||\n                btnStatus === TradeBtnStatus.DISABLED ||\n                !agree\n              }\n            >\n              {label}\n            </ButtonStyle>\n          </Grid>\n        </Grid>\n      </Grid>\n    </GridStyle>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/DeFiWrap/Interface.ts",
    "content": "import { BtnInfo, InputButtonProps } from '../../../basic-lib'\nimport {\n  AccountStatus,\n  CoinInfo,\n  DeFiChgType,\n  MarketType,\n  TradeBtnStatus,\n} from '@loopring-web/common-resources'\nimport React from 'react'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { RawDataDefiSideStakingItem } from '../../../tableList'\n\nexport type DeFiChgData<T> = {\n  type: DeFiChgType\n  tradeData?: undefined | T\n}\nexport type DeFiWrapProps<T, I, ACD> = {\n  isStoB?: boolean\n  isJoin: boolean\n  disabled?: boolean\n  btnInfo?: BtnInfo\n  refreshRef: React.Ref<any>\n  onRefreshData?: (shouldFeeUpdate?: boolean, clearTrade?: boolean) => void\n  isLoading: boolean\n  market: MarketType\n  maxBuyVol?: string\n  maxSellVol?: string\n  confirmShowLimitBalance: boolean\n  // btnStatus: keyof typeof TradeBtnStatus | undefined;\n  onSubmitClick: () => void\n  onConfirm: () => void\n  switchStobEvent?: (_isStoB: boolean) => void\n  onChangeEvent: (data: DeFiChgData<T>) => void\n  handleError?: (data: T) => void\n  tokenSellProps?: Partial<InputButtonProps<T, I, CoinInfo<I>>>\n  tokenBuyProps?: Partial<InputButtonProps<T, I, CoinInfo<I>>>\n  deFiCalcData: ACD\n  tokenSell: sdk.TokenInfo\n  tokenBuy: sdk.TokenInfo\n  btnStatus?: keyof typeof TradeBtnStatus | undefined\n  accStatus?: AccountStatus\n  type: string\n  title: string\n  isLeverageETH?: boolean\n  apr?: string\n  setShowRETHStakePopup?: (props: { isShow: boolean; [key: string]: any }) => void\n  setShowWSTETHStakePopup?: (props: { isShow: boolean; [key: string]: any }) => void\n  setShowLeverageETHPopup?: (props: { isShow: boolean; [key: string]: any }) => void\n  onAprDetail: () => void\n}\n\nexport type DeFiSideType<R = RawDataDefiSideStakingItem> = {\n  tokenSell: sdk.TokenInfo\n  order: R\n  onRedeem: (item: R) => void\n}\nexport type DeFiSideWrapProps<T, I, ACD> = {\n  isJoin: true\n  disabled?: boolean\n  btnInfo?: BtnInfo\n  isLoading: boolean\n  minSellAmount: string\n  maxSellAmount: string\n  onSubmitClick: () => void\n  switchStobEvent?: (_isStoB: boolean) => void\n  onChangeEvent: (data: { tradeData?: undefined | T }) => void\n  handleError?: (data: T) => void\n  tokenSellProps?: Partial<InputButtonProps<T, I, CoinInfo<I>>>\n  deFiSideCalcData: ACD\n  tokenSell: sdk.TokenInfo\n  btnStatus?: keyof typeof TradeBtnStatus | undefined\n  accStatus?: AccountStatus\n}\n\nexport type DeFiStakeRedeemWrapProps<T, _I, ACD> = {\n  isJoin: false\n  isFullTime: boolean\n  disabled?: boolean\n  btnInfo?: BtnInfo\n  isLoading: boolean\n  minSellAmount: string\n  maxSellAmount: string\n  onSubmitClick: () => void\n  switchStobEvent?: (_isStoB: boolean) => void\n  onChangeEvent: (data: { tradeData?: undefined | T }) => void\n  handleError?: (data: T) => void\n  deFiSideRedeemCalcData: ACD\n  tokenSell: sdk.TokenInfo\n  btnStatus?: keyof typeof TradeBtnStatus | undefined\n  accStatus?: AccountStatus\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/DeFiWrap/deFiWrap.tsx",
    "content": "import {\n  BackIcon,\n  DeFiCalcData,\n  DeFiChgType,\n  EmptyValueTag,\n  getValuePrecisionThousand,\n  HelpIcon,\n  IBData,\n  Info2Icon,\n  L1L2_NAME_DEFINED,\n  MapChainId,\n  myLog,\n  OrderListIcon,\n  RecordTabIndex,\n  ReverseIcon,\n  RouterPath,\n  TokenType,\n  TradeBtnStatus,\n  UpColor,\n} from '@loopring-web/common-resources'\nimport { DeFiWrapProps } from './Interface'\nimport { Trans, useTranslation } from 'react-i18next'\nimport React from 'react'\nimport { Box, Divider, Grid, Tooltip, Typography } from '@mui/material'\nimport { Button, InputCoin } from '../../../basic-lib'\nimport { ButtonStyle, IconButtonStyled } from '../Styled'\nimport { CountDownIcon } from '../tool/Refresh'\nimport { useHistory } from 'react-router-dom'\nimport BigNumber from 'bignumber.js'\nimport styled from '@emotion/styled'\nimport { useSettings } from '../../../../stores'\nimport { useTheme } from '@emotion/react'\nimport { CoinIcons } from '../../../tableList'\n\nconst BoxStyle = styled(Box)`\n  ul {\n    list-style: disc;\n    padding-left: ${({ theme }) => theme.unit}px;\n  }\n`\nconst InputCoinStyled = styled(InputCoin)`\n  &&& .coinInput-wrap {\n    background-color: var(--color-global-bg);\n    border: 1px solid var(--color-border);\n  }\n`\n\nexport const DeFiWrap = <T extends IBData<I>, I, ACD extends DeFiCalcData<T>>({\n  disabled,\n  isJoin,\n  isStoB,\n  btnInfo,\n  refreshRef,\n  onRefreshData,\n  onSubmitClick,\n  onConfirm,\n  type,\n  confirmShowLimitBalance,\n  switchStobEvent,\n  onChangeEvent,\n  handleError,\n  deFiCalcData,\n  accStatus,\n  tokenSell,\n  tokenBuy,\n  isLoading,\n  btnStatus,\n  tokenSellProps,\n  tokenBuyProps,\n  maxSellVol,\n  maxBuyVol,\n  market,\n  title,\n  setShowRETHStakePopup,\n  setShowWSTETHStakePopup,\n  setShowLeverageETHPopup,\n  isLeverageETH,\n  apr,\n  onAprDetail,\n  ...rest\n}: DeFiWrapProps<T, I, ACD>) => {\n  // @ts-ignore\n  const [, baseSymbol, _quoteSymbol] = market.match(/(\\w+)-(\\w+)/i)\n  const coinSellRef = React.useRef()\n  const { t } = useTranslation()\n  const theme = useTheme()\n  const { defaultNetwork, coinJson } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const history = useHistory()\n  const [_isStoB, setIsStoB] = React.useState(isStoB ?? true)\n  const { upColor } = useSettings()\n  const colorRight =\n    upColor === UpColor.green\n      ? ['var(--color-success)', 'var(--color-error)']\n      : ['var(--color-error)', 'var(--color-success)']\n  const showVal =\n    deFiCalcData.coinSell?.belong && deFiCalcData.coinBuy?.belong && deFiCalcData?.AtoB\n\n  const convertStr = React.useMemo(() => {\n    return deFiCalcData.coinSell && deFiCalcData.coinBuy\n      ? _isStoB\n        ? `1 ${deFiCalcData.coinSell.belong} \\u2248 ${\n            // @ts-ignore\n            // eslint-disable-next-line eqeqeq\n            deFiCalcData?.AtoB && deFiCalcData?.AtoB !== 'NaN'\n              ? getValuePrecisionThousand(\n                  deFiCalcData?.AtoB,\n                  tokenBuy.precision,\n                  tokenBuy.precision,\n                  tokenBuy.precision,\n                  false,\n                  { floor: true },\n                )\n              : EmptyValueTag\n          } ${deFiCalcData.coinBuy.belong}`\n        : `1 ${deFiCalcData.coinBuy.belong}  \\u2248 ${\n            // @ts-ignore\n            deFiCalcData.BtoA && deFiCalcData?.BtoA !== 'NaN'\n              ? getValuePrecisionThousand(\n                  deFiCalcData?.BtoA,\n                  tokenSell.precision,\n                  tokenSell.precision,\n                  tokenSell.precision,\n                  false,\n                  { floor: true },\n                )\n              : EmptyValueTag\n          } ${deFiCalcData.coinSell.belong}`\n      : t('labelCalculating')\n  }, [\n    deFiCalcData?.AtoB,\n    deFiCalcData.BtoA,\n    deFiCalcData.coinBuy,\n    deFiCalcData.coinSell,\n    _isStoB,\n    t,\n  ])\n\n  const getDisabled = React.useMemo(() => {\n    return disabled || deFiCalcData === undefined || deFiCalcData.AtoB === undefined\n  }, [btnStatus, deFiCalcData, disabled])\n\n  const handleCountChange = React.useCallback(\n    (ibData: T, _name: string, _ref: any) => {\n      const focus: DeFiChgType =\n        _ref?.current === coinSellRef.current ? DeFiChgType.coinSell : DeFiChgType.coinBuy\n\n      if (deFiCalcData[focus].tradeValue !== ibData.tradeValue) {\n        myLog('defi handleCountChange', _name, ibData)\n\n        onChangeEvent({\n          tradeData: { ...ibData },\n          type: focus,\n        })\n      }\n    },\n    [deFiCalcData, onChangeEvent],\n  )\n  const propsSell = {\n    label: t('labelETHStakingEnterPaymentToken'),\n    subLabel: t('tokenMax'),\n    emptyText: t('tokenSelectToken'),\n    placeholderText: '0.00',\n    isShowCoinInfo: true,\n    isShowCoinIcon: true,\n    maxAllow: true,\n    ...tokenSellProps,\n    handleError: handleError as any,\n    handleCountChange: handleCountChange as any,\n    ...rest,\n  } as any\n  const label = React.useMemo(() => {\n    if (btnInfo?.label) {\n      const key = btnInfo?.label.split('|')\n      return t(\n        key[0],\n        key && key[1]\n          ? {\n              arg: key[1],\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n              l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n              l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n              ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n            }\n          : {\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n              l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n              l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n              ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n            },\n      )\n    } else {\n      return isJoin\n        ? t(`labelInvestBtn`, {\n            loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n            l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n            l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n            ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n          })\n        : t(`labelRedeemBtn`, {\n            loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n            l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n            l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n            ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n          })\n    }\n  }, [isJoin, t, btnInfo])\n\n  const maxValue =\n    tokenBuy &&\n    tokenBuy.symbol &&\n    maxBuyVol &&\n    `${getValuePrecisionThousand(\n      new BigNumber(maxBuyVol ?? 0).div('1e' + tokenBuy.decimals),\n      tokenBuy.precision,\n      tokenBuy.precision,\n      tokenBuy.precision,\n      false,\n      { floor: true },\n    )} ${tokenBuy.symbol}`\n\n  const fee =\n    deFiCalcData?.fee && deFiCalcData.fee !== '0'\n      ? deFiCalcData?.fee + ` ${tokenBuy.symbol}`\n      : EmptyValueTag\n\n  return (\n    <Box\n      className={deFiCalcData ? '' : 'loading'}\n      flexDirection={'column'}\n      justifyContent={'space-between'}\n      alignItems={'center'}\n      display={'flex'}\n      flex={1}\n      height={'100%'}\n    >\n      <Box\n        display={'flex'}\n        justifyContent={'space-between'}\n        alignItems={'center'}\n        flexDirection={'row'}\n        width={'100%'}\n        className={'MuiToolbar-root'}\n      >\n        <Typography\n          height={'100%'}\n          display={'inline-flex'}\n          variant={'h5'}\n          alignItems={'center'}\n          alignSelf={'center'}\n        >\n          {title}\n          <HelpIcon\n            fontSize={'large'}\n            color={'inherit'}\n            sx={{ marginLeft: 1, cursor: 'pointer' }}\n            onClick={() => {\n              if (isLeverageETH) {\n                setShowLeverageETHPopup &&\n                  setShowLeverageETHPopup({ isShow: true, confirmationNeeded: false })\n              } else if (market === 'RETH-ETH') {\n                setShowRETHStakePopup &&\n                  setShowRETHStakePopup({ isShow: true, confirmationNeeded: false })\n              } else if (market === 'WSTETH-ETH') {\n                setShowWSTETHStakePopup &&\n                  setShowWSTETHStakePopup({ isShow: true, confirmationNeeded: false })\n              }\n            }}\n          />\n        </Typography>\n        <Box alignSelf={'flex-end'} display={'flex'}>\n          <CountDownIcon onRefreshData={onRefreshData} ref={refreshRef} />\n          <Typography display={'inline-block'} marginLeft={2}>\n            <IconButtonStyled\n              onClick={() => {\n                if (isLeverageETH) {\n                  history.push(`${RouterPath.l2records}/leverageETHRecords`)\n                } else {\n                  history.push(\n                    `${RouterPath.l2records}/${RecordTabIndex.DefiRecords}?market=${market}`,\n                  )\n                }\n              }}\n              sx={{ backgroundColor: 'var(--field-opacity)' }}\n              className={'switch outlined'}\n              aria-label='to Transaction'\n              size={'large'}\n            >\n              <OrderListIcon fill={theme.colorBase.logo} fontSize={'large'} />\n            </IconButtonStyled>\n          </Typography>\n        </Box>\n      </Box>\n      <Divider sx={{ width: '100%', marginY: 1 }} />\n      <Box flexDirection={'column'} display={'flex'} alignSelf={'stretch'} alignItems={'stretch'}>\n        <InputCoinStyled\n          ref={coinSellRef}\n          disabled={getDisabled}\n          {...{\n            ...propsSell,\n            name: 'coinSell',\n            isHideError: true,\n            order: 'right',\n            inputData: deFiCalcData ? deFiCalcData.coinSell : ({} as any),\n            coinMap: {},\n            coinPrecision: tokenSell && tokenSell.precision,\n          }}\n        />\n      </Box>\n      <Divider sx={{ width: '100%', marginY: 3 }} />\n      <Grid container spacing={1} alignItems={'stretch'} flex={1}>\n        <Grid\n          item\n          xs={12}\n          direction={'row'}\n          display={'flex'}\n          marginBottom={1}\n          justifyContent={'space-between'}\n        >\n          <Typography component={'p'} variant='body2' color={'textSecondary'}>\n            {t('labelReceiveToken')}\n          </Typography>\n          <Typography\n            component={'p'}\n            variant='body2'\n            color={'textPrimary'}\n            alignItems={'center'}\n            display={'inline-flex'}\n          >\n            {deFiCalcData?.coinBuy?.tradeValue ? (\n              <>\n                <CoinIcons\n                  size={'small'}\n                  type={TokenType.single}\n                  tokenIcon={[coinJson[deFiCalcData.coinBuy.belong]]}\n                />\n                <span style={{ marginRight: 1 / 2 }}>\n                  {deFiCalcData.coinBuy.tradeValue + ' ' + deFiCalcData.coinBuy.belong}\n                </span>\n              </>\n            ) : (\n              EmptyValueTag\n            )}\n          </Typography>\n        </Grid>\n        {isJoin && (\n          <Grid\n            item\n            xs={12}\n            direction={'row'}\n            display={'flex'}\n            marginBottom={1}\n            justifyContent={'space-between'}\n          >\n            <Box display={'flex'} flexDirection={'row'}>\n              <Tooltip title={t('labelLRCStakeAPRTooltips')}>\n                <Typography\n                  component={'p'}\n                  variant='body2'\n                  color={'textSecondary'}\n                  display={'inline-flex'}\n                  alignItems={'center'}\n                >\n                  {t('labelAPR')}\n                  <Info2Icon color={'inherit'} sx={{ marginLeft: 1 / 2 }} />\n                </Typography>\n              </Tooltip>\n            </Box>\n            <Button\n              variant={'text'}\n              size={'small'}\n              onClick={() => onAprDetail()}\n              sx={{\n                padding: 0,\n                justifyContent: 'right',\n                color: apr?.toString().charAt(0) == '-' ? colorRight[1] : colorRight[0],\n              }}\n              endIcon={\n                <BackIcon\n                  fontSize={'small'}\n                  sx={{ transform: 'rotate(180deg)' }}\n                  color={'inherit'}\n                />\n              }\n            >\n              {apr ? `${(apr.toString().charAt(0) == '-' ? '' : '+') + apr + '%'}` : EmptyValueTag}\n            </Button>\n          </Grid>\n        )}\n\n        <Grid\n          item\n          xs={12}\n          direction={'row'}\n          display={'flex'}\n          marginBottom={1}\n          justifyContent={'space-between'}\n        >\n          <Typography component={'p'} variant='body2' color={'textSecondary'}>\n            {t('labelDefiRate')}\n          </Typography>\n          <Typography component={'p'} variant='body2' color={'textPrimary'}>\n            {showVal ? convertStr : t('labelCalculating')}\n            <IconButtonStyled\n              size={'small'}\n              aria-label={t('tokenExchange')}\n              onClick={() => setIsStoB(!_isStoB)}\n            >\n              <ReverseIcon />\n            </IconButtonStyled>\n          </Typography>\n        </Grid>\n        {isJoin && (\n          <Grid\n            item\n            xs={12}\n            direction={'row'}\n            display={'flex'}\n            marginBottom={1}\n            justifyContent={'space-between'}\n          >\n            <Typography component={'p'} variant='body2' color={'textSecondary'}>\n              {t('labelDefiDuration')}\n            </Typography>\n            <Typography component={'p'} variant='body2' color={'textPrimary'}>\n              {t('labelFlexible')}\n            </Typography>\n          </Grid>\n        )}\n        <Grid\n          item\n          xs={12}\n          direction={'row'}\n          display={'flex'}\n          marginBottom={1}\n          justifyContent={'space-between'}\n        >\n          <Tooltip title={t('labelTradingFeeTooltips')}>\n            <Typography\n              component={'p'}\n              variant='body2'\n              color={'textSecondary'}\n              display={'inline-flex'}\n              alignItems={'center'}\n            >\n              {t('labelTradingFee')}\n              <Info2Icon color={'inherit'} sx={{ marginLeft: 1 / 2 }} />\n            </Typography>\n          </Tooltip>\n\n          <Typography component={'p'} variant='body2' color={'textPrimary'}>\n            {fee}\n          </Typography>\n        </Grid>\n      </Grid>\n\n      <Box\n        marginTop={3}\n        alignSelf={'stretch'}\n        display={'flex'}\n        flexDirection={'column'}\n        alignItems={'stretch'}\n      >\n        <ButtonStyle\n          fullWidth\n          variant={'contained'}\n          size={'medium'}\n          color={'primary'}\n          onClick={() => {\n            onSubmitClick()\n          }}\n          loading={!getDisabled && btnStatus === TradeBtnStatus.LOADING ? 'true' : 'false'}\n          disabled={\n            getDisabled ||\n            btnStatus === TradeBtnStatus.LOADING ||\n            btnStatus === TradeBtnStatus.DISABLED\n          }\n        >\n          {label}\n        </ButtonStyle>\n        {confirmShowLimitBalance && (\n          <BoxStyle display={'flex'} flexDirection={'column'}>\n            {isJoin ? (\n              <Typography\n                variant={'body1'}\n                component={'p'}\n                display={'flex'}\n                marginTop={1}\n                flexDirection={'column'}\n                color={'var(--color-warning)'}\n              >\n                <Trans i18nKey={'labelDefiMaxBalanceJoin'} tOptions={{ maxValue }}>\n                  The quota is almost sold out and can't fulfil your complete order. You can only\n                  subscribe {{ maxValue }} now. Loopring will setup the pool soon, please revisit\n                  for subscription later.\n                </Trans>\n              </Typography>\n            ) : (\n              <Typography\n                variant={'body1'}\n                component={'p'}\n                display={'flex'}\n                marginTop={1}\n                flexDirection={'column'}\n                color={'var(--color-warning)'}\n              >\n                <Typography component={'span'} variant={'inherit'} color={'inherit'}>\n                  <Trans i18nKey={'labelDefiMaxBalanceLeverage'} tOptions={{ maxValue }}>\n                    Loopring rebalance pool can't satisfy your complete request. You can only redeem{' '}\n                    {{ maxValue }} now. For the remaining investment, you can choose one of the\n                    approaches\n                  </Trans>\n                </Typography>\n                <Typography component={'span'} variant={'inherit'} color={'inherit'} marginTop={1}>\n                  <ul>\n                    {isLeverageETH ? (\n                      <Trans\n                        i18nKey={'labelDefiMaxBalance1Leverage'}\n                        components={{ li: <li /> }}\n                        tOptions={{\n                          symbol: baseSymbol,\n                          type,\n                          loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                          l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                          l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                          ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                        }}\n                      >\n                        <li>Wait some time for Loopring to seto for redeem</li>\n                      </Trans>\n                    ) : (\n                      <Trans\n                        i18nKey={'labelDefiMaxBalance1'}\n                        components={{ li: <li /> }}\n                        tOptions={{\n                          symbol: baseSymbol,\n                          type,\n                          loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                          l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                          l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                          ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                        }}\n                      >\n                        <li>Withdraw wstETH to L1 and trade through CRV or LIDO directly</li>\n                        <li>Wait some time for Loopring to seto for redeem</li>\n                      </Trans>\n                    )}\n                  </ul>\n                </Typography>\n              </Typography>\n            )}\n          </BoxStyle>\n        )}\n      </Box>\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/DeFiWrap/index.tsx",
    "content": "export * from './Interface'\nexport * from './deFiWrap'\nexport * from './DeFiStackOneSideWrap'\nexport * from './DeFiStackRedeemWrap'\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/DeployNFTWrap.tsx",
    "content": "import { FeeInfo, TradeBtnStatus, TradeNFT } from '@loopring-web/common-resources'\nimport { NFTDeployViewProps } from './Interface'\nimport { useTranslation } from 'react-i18next'\nimport React from 'react'\nimport { Box, Grid, Link, Toolbar, Typography } from '@mui/material'\nimport { Button, ModalBackButton } from '../../basic-lib'\nimport { FeeSelect } from '../../../components/modal'\n\nexport const DeployNFTWrap = <\n  T extends TradeNFT<I, any> & { broker: string },\n  I,\n  C extends FeeInfo,\n>({\n  tradeData,\n  title,\n  btnInfo,\n  nftDeployBtnStatus,\n  onNFTDeployClick,\n  chargeFeeTokenList = [],\n  feeInfo,\n  disabled,\n  isFeeNotEnough,\n  handleFeeChange,\n  onBack,\n  assetsData = [],\n}: NFTDeployViewProps<T, I, C>) => {\n  const { t } = useTranslation(['common'])\n  const [showFeeModal, setShowFeeModal] = React.useState(false)\n\n  const getDisabled = React.useMemo(() => {\n    if (disabled || nftDeployBtnStatus === TradeBtnStatus.DISABLED) {\n      return true\n    } else {\n      return false\n    }\n  }, [nftDeployBtnStatus, disabled])\n\n  const handleToggleChange = (value: C) => {\n    if (handleFeeChange) {\n      handleFeeChange(value)\n    }\n  }\n  // @ts-ignore\n  return (\n    <Box flex={1}>\n      {!!onBack && (\n        <Toolbar variant={'dense'}>\n          <ModalBackButton marginTop={0} marginLeft={-2} onBack={onBack} t={t} />\n        </Toolbar>\n      )}\n      <Box flex={1}>\n        <Grid\n          className={assetsData ? '' : 'loading'}\n          paddingBottom={3}\n          container\n          marginTop={0}\n          paddingLeft={5 / 2}\n          paddingRight={5 / 2}\n          direction={'column'}\n          justifyContent={'space-between'}\n          alignItems={'center'}\n          flex={1}\n          height={'100%'}\n        >\n          <Grid item>\n            <Box\n              display={'flex'}\n              flexDirection={'row'}\n              justifyContent={'center'}\n              alignItems={'center'}\n              /* textAlign={'center'} */ marginBottom={2}\n            >\n              <Typography component={'h4'} variant={'h3'} marginRight={1}>\n                {title ? title : t('nftDeployTitle')}\n              </Typography>\n            </Box>\n          </Grid>\n\n          <Grid item marginTop={2} alignSelf={'stretch'}>\n            <Box\n              display={'flex'}\n              alignItems={'flex-start'}\n              justifyContent={'space-between'}\n              position={'relative'}\n              flexDirection={'column'}\n            >\n              <Typography component={'h6'} color={'text.primary'} variant={'h4'}>\n                {t('labelNFTDetail')}\n              </Typography>\n              {/*<Typography*/}\n              {/*  display={\"inline-flex\"}*/}\n              {/*  variant={\"body1\"}*/}\n              {/*  marginTop={2}*/}\n              {/*>*/}\n              {/*  <Typography color={\"var(--color-text-third)\"} width={160}>*/}\n              {/*    {t(\"labelNFTName\")}*/}\n              {/*  </Typography>*/}\n              {/*  <Typography*/}\n              {/*    color={\"var(--color-text-third)\"}*/}\n              {/*    title={tradeData?.name}*/}\n              {/*  >*/}\n              {/*    {tradeData?.name}*/}\n              {/*  </Typography>*/}\n              {/*</Typography>*/}\n\n              {/*<Typography*/}\n              {/*  display={\"inline-flex\"}*/}\n              {/*  variant={\"body1\"}*/}\n              {/*  marginTop={2}*/}\n              {/*>*/}\n              {/*  <Typography color={\"var(--color-text-third)\"} width={160}>*/}\n              {/*    {t(\"labelNFTID\")}*/}\n              {/*  </Typography>*/}\n              {/*  <Typography*/}\n              {/*    color={\"var(--color-text-third)\"}*/}\n              {/*    maxWidth={300}*/}\n              {/*    title={tradeData?.nftId}*/}\n              {/*  >*/}\n              {/*    {tradeData?.nftIdView ?? \"\"}*/}\n              {/*  </Typography>*/}\n              {/*</Typography>*/}\n              <Typography display={'inline-flex'} variant={'body1'} marginTop={2}>\n                <Typography color={'var(--color-text-third)'} width={160}>\n                  {t('labelNFTTYPE')}\n                </Typography>\n                <Typography color={'var(--color-text-third)'} title={tradeData?.nftType}>\n                  {tradeData.nftType}\n                </Typography>\n              </Typography>\n              <Typography display={'inline-flex'} variant={'body1'} marginTop={2}>\n                <Typography color={'var(--color-text-third)'} width={160}>\n                  {t('labelNFTContractAddress')}\n                </Typography>\n                <Link\n                  fontSize={'inherit'}\n                  whiteSpace={'break-spaces'}\n                  style={{ wordBreak: 'break-all' }}\n                >\n                  {tradeData.tokenAddress}\n                </Link>\n              </Typography>\n              <Typography display={'inline-flex'} variant={'body1'} marginTop={2}>\n                <Typography color={'var(--color-text-third)'} width={160}>\n                  {t('labelNFTDeployBroker')}\n                </Typography>\n                <Link\n                  fontSize={'inherit'}\n                  whiteSpace={'break-spaces'}\n                  style={{ wordBreak: 'break-all' }}\n                >\n                  {tradeData.broker}\n                </Link>\n              </Typography>\n            </Box>\n          </Grid>\n          <Grid item alignSelf={'stretch'} position={'relative'} marginTop={2}>\n            {!chargeFeeTokenList?.length ? (\n              <Typography>{t('labelFeeCalculating')}</Typography>\n            ) : (\n              <>\n                <FeeSelect\n                  chargeFeeTokenList={chargeFeeTokenList}\n                  handleToggleChange={(fee: FeeInfo) => {\n                    handleToggleChange(fee as C)\n                    setShowFeeModal(false)\n                  }}\n                  feeInfo={feeInfo as FeeInfo}\n                  open={showFeeModal}\n                  onClose={() => {\n                    setShowFeeModal(false)\n                  }}\n                  isFeeNotEnough={isFeeNotEnough.isFeeNotEnough}\n                  feeLoading={isFeeNotEnough.isOnLoading}\n                  onClickFee={() => setShowFeeModal((prev) => !prev)}\n                />\n              </>\n            )}\n          </Grid>\n          <Grid item marginTop={3} alignSelf={'stretch'}>\n            <Button\n              fullWidth\n              variant={'contained'}\n              size={'medium'}\n              color={'primary'}\n              onClick={() => {\n                onNFTDeployClick(tradeData)\n              }}\n              loading={\n                !getDisabled && nftDeployBtnStatus === TradeBtnStatus.LOADING ? 'true' : 'false'\n              }\n              disabled={getDisabled || nftDeployBtnStatus === TradeBtnStatus.LOADING}\n            >\n              {btnInfo ? t(btnInfo.label, btnInfo.params) : t(`labelNFTDeployBtn`)}\n            </Button>\n          </Grid>\n        </Grid>\n      </Box>\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/DepositConfirm.tsx",
    "content": "import { EmptyValueTag, IBData, TOAST_TIME } from '@loopring-web/common-resources'\nimport { WithTranslation } from 'react-i18next'\nimport React from 'react'\nimport { Box, Grid, Typography } from '@mui/material'\nimport { Button, DepositTitle, Toast, ToastType, useSettings } from '../../../index'\nimport { DepositViewProps } from './Interface'\n\nexport const DepositConfirm = <\n  T extends {\n    toAddress?: string\n    addressError?: { error: boolean; message?: string }\n  } & IBData<I>,\n  I,\n>({\n  t,\n  tradeData,\n  onDepositClick,\n  handleConfirm,\n  title,\n  lastFailed,\n  realToAddress,\n}: // ...rest\nDepositViewProps<T, I> & {\n  handleConfirm: (index: number) => void\n} & WithTranslation) => {\n  const { isMobile } = useSettings()\n  const [open, setOpen] = React.useState(false)\n\n  return (\n    <Grid\n      className={'confirm'}\n      container\n      paddingLeft={isMobile ? 2 : 5 / 2}\n      paddingRight={isMobile ? 2 : 5 / 2}\n      direction={'column'}\n      alignItems={'stretch'}\n      flex={1}\n      height={'100%'}\n      minWidth={240}\n      flexWrap={'nowrap'}\n      spacing={2}\n    >\n      <Grid item xs={12}>\n        <Box\n          display={'flex'}\n          flexDirection={'column'}\n          justifyContent={'center'}\n          alignItems={'center'}\n          marginBottom={2}\n        >\n          <DepositTitle title={title ? t(title) : undefined} isHideDes={true} />\n        </Box>\n      </Grid>\n      <Grid item xs={12}>\n        <Typography color={'var(--color-text-third)'} variant={'body1'}>\n          {t('labelL2toL2TokenAmount')}\n        </Typography>\n        <Typography color={'textPrimary'} marginTop={1} variant={'body1'}>\n          {tradeData?.tradeValue}\n          <Typography component={'span'} color={'textSecondary'} marginLeft={1 / 2}>\n            {tradeData?.belong}\n          </Typography>\n        </Typography>\n      </Grid>\n      <Grid item xs={12}>\n        <Typography color={'var(--color-text-third)'} variant={'body1'}>\n          {t('labelDepositTo')}\n        </Typography>\n        <Typography color={'textPrimary'} marginTop={1} variant={'body1'}>\n          {realToAddress}\n        </Typography>\n      </Grid>\n      <Grid item marginTop={2} alignSelf={'stretch'} paddingBottom={0}>\n        {lastFailed && (\n          <Typography paddingBottom={1} textAlign={'center'} color={'var(--color-warning)'}>\n            {t('labelConfirmAgainByFailedWithBalance', {\n              symbol: ` ${tradeData?.belong}` ?? EmptyValueTag,\n              count: tradeData?.balance,\n            })}\n          </Typography>\n        )}\n        <Button\n          fullWidth\n          variant={'contained'}\n          size={'medium'}\n          color={'primary'}\n          onClick={async () => {\n            if (onDepositClick) {\n              await onDepositClick({ ...tradeData } as unknown as T)\n            } else {\n              setOpen(true)\n            }\n            handleConfirm(1)\n          }}\n        >\n          {t('labelConfirm')}\n        </Button>\n      </Grid>\n      <Toast\n        alertText={t('errorBase', { ns: 'error' })}\n        open={open}\n        autoHideDuration={TOAST_TIME}\n        onClose={() => {\n          setOpen(false)\n        }}\n        severity={ToastType.error}\n      />\n    </Grid>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/DepositNFTWrap.tsx",
    "content": "import {\n  CloseIcon,\n  LoadingIcon,\n  myLog,\n  SoursURL,\n  TradeBtnStatus,\n  TradeNFT,\n} from '@loopring-web/common-resources'\nimport { useTranslation } from 'react-i18next'\nimport React from 'react'\nimport { Box, Grid, Typography } from '@mui/material'\nimport { EmptyDefault, IconClearStyled, InputSize, TGItemData, ToggleButtonGroup } from '../../'\nimport { Button, TextField, useSettings } from '../../../index'\nimport { NFTDepositViewProps } from './Interface'\nimport { NFTInput } from './BasicANFTTrade'\nimport { NFTType } from '@loopring-web/loopring-sdk'\nimport styled from '@emotion/styled'\n\nconst GridStyle = styled(Grid)`\n  .coinInput-wrap {\n    .input-wrap {\n      //background: var(--field-opacity);\n      border-radius: ${({ theme }) => theme.unit / 2}px;\n      border: 1px solid var(--color-border);\n    }\n  }\n\n  .MuiInputLabel-root {\n    font-size: ${({ theme }) => theme.fontDefault.body2};\n  }\n` as typeof Grid\nconst NFT_TYPE: TGItemData[] = [\n  {\n    value: NFTType.ERC1155,\n    key: 'ERC1155',\n    label: 'ERC1155',\n    disabled: false,\n  },\n  {\n    value: NFTType.ERC721,\n    key: 'ERC721',\n    label: 'ERC721', // after 18n\n    disabled: false,\n  },\n]\n\nexport const DepositNFTWrap = <T extends TradeNFT<I, any>, I>({\n  disabled,\n  walletMap,\n  tradeData,\n  getIPFSString,\n  btnInfo,\n  baseURL = `https://${process.env.REACT_APP_API_URL}`,\n  handleOnNFTDataChange,\n  nftDepositBtnStatus,\n  isNFTCheckLoading,\n  onNFTDepositClick,\n}: // wait = globalSetup.wait,\nNFTDepositViewProps<T, I>) => {\n  const { t } = useTranslation(['common'])\n\n  const inputBtnRef = React.useRef()\n\n  const getDisabled = React.useMemo(() => {\n    return disabled || nftDepositBtnStatus === TradeBtnStatus.DISABLED\n  }, [nftDepositBtnStatus, disabled])\n\n  React.useMemo(() => {\n    return disabled || nftDepositBtnStatus === TradeBtnStatus.DISABLED\n  }, [nftDepositBtnStatus, disabled])\n\n  myLog(getDisabled, 'getDisabled')\n  const { isMobile } = useSettings()\n  // const styles = isMobile\n  //   ? { flex: 1, width: \"var(--swap-box-width)\" }\n  //   : { width: \"var(--modal-width)\" };\n\n  // @ts-ignore\n  return (\n    <Box\n      flex={1}\n      flexDirection={'column'}\n      display={'flex'}\n      paddingX={5 / 2}\n      alignContent={'space-between'}\n    >\n      <GridStyle\n        className={walletMap ? '' : 'loading'}\n        container\n        flex={1}\n        marginTop={0}\n        spacing={2}\n      >\n        <Grid item xs={12} md={5} alignItems={'center'} order={isMobile ? 1 : 0}>\n          <Box flex={1} display={'flex'} position={'relative'} width={'auto'} minHeight={200}>\n            <img\n              style={{\n                opacity: 0,\n                width: '100%',\n                padding: 16,\n                height: '100%',\n                display: 'block',\n              }}\n              alt={'ipfs'}\n              src={SoursURL + 'svg/ipfs.svg'}\n            />\n            <Box\n              style={{\n                position: 'absolute',\n                top: 0,\n                right: 0,\n                left: 0,\n                bottom: 0,\n                height: '100%',\n                width: '100%',\n              }}\n            >\n              {tradeData.image ? (\n                <Box\n                  flex={1}\n                  display={'flex'}\n                  alignItems={'center'}\n                  height={'100%'}\n                  justifyContent={'center'}\n                >\n                  <img alt={'NFT'} width={'100%'} src={getIPFSString(tradeData?.image, baseURL)} />\n                </Box>\n              ) : isNFTCheckLoading ? (\n                <Box\n                  flex={1}\n                  display={'flex'}\n                  alignItems={'center'}\n                  height={'100%'}\n                  justifyContent={'center'}\n                >\n                  <LoadingIcon fontSize={'large'} />\n                </Box>\n              ) : (\n                <Box\n                  flex={1}\n                  display={'flex'}\n                  alignItems={'center'}\n                  height={'100%'}\n                  justifyContent={'center'}\n                >\n                  <EmptyDefault\n                    // width={\"100%\"}\n                    height={'100%'}\n                    message={() => (\n                      <Box\n                        flex={1}\n                        display={'flex'}\n                        alignItems={'center'}\n                        justifyContent={'center'}\n                      >\n                        {t('labelNoContent')}\n                      </Box>\n                    )}\n                  />\n                </Box>\n              )}\n            </Box>\n          </Box>\n        </Grid>\n        <Grid item xs={12} md={7} paddingBottom={2} order={isMobile ? 0 : 1}>\n          <Box>\n            <Grid container maxWidth={'inherit'}>\n              <Grid item xs={12} marginTop={2} alignSelf={'stretch'}>\n                <Box\n                  display={'flex'}\n                  alignItems={'center'}\n                  justifyContent={'space-between'}\n                  position={'relative'}\n                >\n                  <TextField\n                    value={tradeData?.tokenAddress}\n                    label={t('labelNFTContractAddress')}\n                    placeholder={t('depositNFTAddressLabelPlaceholder')}\n                    onChange={(event) =>\n                      handleOnNFTDataChange({\n                        tokenAddress: event.target?.value,\n                      } as T)\n                    }\n                    fullWidth={true}\n                  />\n                  {tradeData.tokenAddress && tradeData.tokenAddress !== '' ? (\n                    isNFTCheckLoading ? (\n                      <LoadingIcon\n                        width={24}\n                        style={{\n                          top: '32px',\n                          right: '8px',\n                          position: 'absolute',\n                        }}\n                      />\n                    ) : (\n                      <IconClearStyled\n                        color={'inherit'}\n                        size={'small'}\n                        style={{ top: '30px' }}\n                        aria-label='Clear'\n                        onClick={() => handleOnNFTDataChange({ tokenAddress: '' } as T)}\n                      >\n                        <CloseIcon />\n                      </IconClearStyled>\n                    )\n                  ) : (\n                    ''\n                  )}\n                </Box>\n              </Grid>\n              <Grid item xs={12} marginTop={2} alignSelf={'stretch'}>\n                <Box\n                  display={'flex'}\n                  alignItems={'center'}\n                  justifyContent={'space-between'}\n                  position={'relative'}\n                >\n                  <TextField\n                    value={tradeData.nftIdView}\n                    label={t('labelNFTTId')}\n                    placeholder={t('depositNFTIdLabelPlaceholder')}\n                    onChange={(event) =>\n                      handleOnNFTDataChange({\n                        nftIdView: event.target?.value,\n                        nftId: '',\n                      } as T)\n                    }\n                    helperText={\n                      isMobile ? (\n                        <></>\n                      ) : (\n                        <Typography\n                          variant={'body2'}\n                          component={'span'}\n                          textAlign={'left'}\n                          display={'inherit'}\n                          whiteSpace={'pre-line'}\n                          sx={{ wordBreak: 'break-all' }}\n                        >\n                          {tradeData.nftId}\n                        </Typography>\n                      )\n                    }\n                    fullWidth={true}\n                  />\n                  {tradeData.nftIdView && tradeData.nftIdView !== '' ? (\n                    isNFTCheckLoading ? (\n                      <LoadingIcon\n                        width={24}\n                        style={{\n                          top: '32px',\n                          right: '8px',\n                          position: 'absolute',\n                        }}\n                      />\n                    ) : (\n                      <IconClearStyled\n                        color={'inherit'}\n                        size={'small'}\n                        style={{ top: '30px' }}\n                        aria-label='Clear'\n                        onClick={() =>\n                          handleOnNFTDataChange({\n                            nftIdView: '',\n                            nftId: '',\n                          } as T)\n                        }\n                      >\n                        <CloseIcon />\n                      </IconClearStyled>\n                    )\n                  ) : (\n                    ''\n                  )}\n                </Box>\n              </Grid>\n              <Grid item xs={12} marginTop={2} alignSelf={'stretch'}>\n                <Box\n                  display={'flex'}\n                  flexDirection={'row'}\n                  justifyContent={'space-between'}\n                  alignContent={'center'}\n                >\n                  <Box>\n                    <Box>\n                      <Typography color={'textSecondary'} marginBottom={1} variant={'body2'}>\n                        {t('labelNFTType')}\n                      </Typography>\n                      <ToggleButtonGroup\n                        exclusive\n                        fullWidth\n                        {...{\n                          data: NFT_TYPE,\n                          value: tradeData?.nftType ?? 0,\n                        }}\n                        onChange={(_e, value) => {\n                          handleOnNFTDataChange({ nftType: value } as T)\n                        }}\n                        size={'medium'}\n                      />\n                    </Box>\n                    <Box\n                      marginTop={2}\n                      display={'flex'}\n                      alignItems={'center'}\n                      justifyContent={'center'}\n                    >\n                      {isNFTCheckLoading ? (\n                        <LoadingIcon fontSize={'large'} />\n                      ) : (\n                        <NFTInput\n                          {...({ t } as any)}\n                          isThumb={false}\n                          inputNFTDefaultProps={{\n                            size: InputSize.small,\n                            label: t('labelNFTDepositInputTitle'),\n                          }}\n                          disabled={\n                            !(\n                              tradeData.nftIdView &&\n                              tradeData.nftId &&\n                              tradeData.tokenAddress &&\n                              tradeData.balance !== undefined\n                            )\n                          }\n                          baseURL={baseURL}\n                          type={'NFT'}\n                          inputNFTRef={inputBtnRef}\n                          onChangeEvent={(_index, data) =>\n                            handleOnNFTDataChange({\n                              tradeValue: data.tradeData?.tradeValue ?? '0',\n                            } as T)\n                          }\n                          tradeData={\n                            {\n                              ...tradeData,\n                              belong: tradeData?.tokenAddress ?? undefined,\n                            } as any\n                          }\n                          walletMap={walletMap}\n                        />\n                      )}\n                    </Box>\n                  </Box>\n                </Box>\n              </Grid>\n              <Grid item xs={12} marginTop={3} alignSelf={'stretch'}>\n                <Button\n                  fullWidth\n                  variant={'contained'}\n                  size={'medium'}\n                  color={'primary'}\n                  onClick={() => {\n                    onNFTDepositClick(tradeData)\n                  }}\n                  loading={\n                    !getDisabled && nftDepositBtnStatus === TradeBtnStatus.LOADING\n                      ? 'true'\n                      : 'false'\n                  }\n                  disabled={getDisabled || nftDepositBtnStatus === TradeBtnStatus.LOADING}\n                >\n                  {btnInfo ? t(btnInfo.label, btnInfo.params) : t(`labelNFTDepositBtn`)}\n                </Button>\n              </Grid>\n            </Grid>\n          </Box>\n        </Grid>\n      </GridStyle>\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/DepositWrap.tsx",
    "content": "import {\n  AccountStatus,\n  AddressError,\n  Bridge,\n  CloseIcon,\n  globalSetup,\n  IBData,\n  L1L2_NAME_DEFINED,\n  LoadingIcon,\n  MapChainId,\n  SoursURL,\n  TRADE_TYPE,\n  TradeBtnStatus,\n  FailedIcon\n} from '@loopring-web/common-resources'\nimport { Trans, WithTranslation } from 'react-i18next'\nimport React from 'react'\nimport { Box, Grid, Link, Typography } from '@mui/material'\nimport {\n  Button,\n  DepositTitle,\n  GridWrapStyle,\n  IconClearStyled,\n  TextField,\n  useSettings,\n} from '../../../index'\nimport { DepositViewProps } from './Interface'\nimport { BasicACoinTrade } from './BasicACoinTrade'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nexport const DepositWrap = <\n  T extends {\n    accountReady?: AccountStatus\n    toAddress?: string\n    addressError?: { error: boolean; message?: string }\n  } & IBData<I>,\n  I,\n>({\n  t,\n  disabled,\n  walletMap,\n  tradeData,\n  coinMap,\n  title,\n  isHideDes,\n  description,\n  btnInfo,\n  depositBtnStatus,\n  accountReady,\n  onDepositClick,\n  isNewAccount,\n  handleError,\n  addressDefault,\n  chargeFeeTokenList,\n  onChangeEvent,\n  handleClear,\n  handleConfirm,\n  isAllowInputToAddress,\n  toIsAddressCheckLoading,\n  // toIsLoopringAddress,\n  realToAddress,\n  isToAddressEditable,\n  toAddressStatus,\n  wait = globalSetup.wait,\n  allowTrade,\n  toAddress,\n  handleAddressChange,\n  isLoopringSmartWallet,\n  onClose,\n  ...rest\n}: DepositViewProps<T, I> & {\n  accountReady?: AccountStatus\n  handleConfirm: (index: number) => void\n} & WithTranslation) => {\n  const inputBtnRef = React.useRef()\n  let { feeChargeOrder, isMobile, defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const [minFee, setMinFee] = React.useState<{ minFee: string } | undefined>(undefined)\n  const getDisabled = React.useMemo(() => {\n    return disabled || depositBtnStatus === TradeBtnStatus.DISABLED\n  }, [depositBtnStatus, disabled])\n\n  const inputButtonDefaultProps = {\n    label: [sdk.ChainId.TAIKO, sdk.ChainId.TAIKOHEKLA].includes(defaultNetwork) ? t('depositLabelEnterTokenEarn') : t('depositLabelEnterToken'),\n  }\n  const isNewAlert = React.useMemo(() => {\n    if (isNewAccount && chargeFeeTokenList && tradeData && tradeData.belong) {\n      const index = chargeFeeTokenList?.findIndex(({ belong }) => belong === tradeData.belong)\n\n      if (index === -1) {\n        setMinFee(undefined)\n        return (\n          <Typography\n            color={'var(--color-error)'}\n            component={'p'}\n            variant={'body1'}\n            marginBottom={1}\n          >\n            {t('labelIsNotFeeToken', {\n              l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n              l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n              l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n              ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n              symbols: chargeFeeTokenList.slice(0, chargeFeeTokenList.length - 1).map((item) => item.belong ?? '').join(', '),\n              lastSymbol: chargeFeeTokenList[chargeFeeTokenList.length - 1].belong,\n            })}\n          </Typography>\n        )\n      }\n      const Max = sdk\n        .toBig(chargeFeeTokenList[index].fee.toString().replaceAll(sdk.SEP, ''))\n        .times(4)\n      setMinFee({\n        minFee: t('labelMinFeeForActive', {\n          symbol: tradeData.belong.toString(),\n          fee: Max.toString(),\n        }),\n      })\n      if (!tradeData?.tradeValue || Max.lte(tradeData.tradeValue ?? 0)) {\n        return <></>\n      } else {\n        return (\n          <>\n            <Typography\n              color={'var(--color-error)'}\n              component={'p'}\n              variant={'body1'}\n              marginBottom={1}\n            >\n              {t('labelIsNotEnoughFeeToken', {\n                symbol: tradeData.belong,\n                fee: Max.toString(),\n              })}\n            </Typography>\n          </>\n        )\n      }\n    } else if (isNewAccount) {\n      setMinFee(undefined)\n      return (\n        // <Typography color={\"var(--color-text-secondary)\"}>\n        //   <Typography></Typography>\n        //   <Typography></Typography>\n        // </Typography>\n        <Typography\n          color={'var(--color-text-third)'}\n          component={'p'}\n          variant={'body1'}\n          marginBottom={1}\n        >\n          {t('labelIsNotFeeToken', {\n            loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n            l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n            l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n            ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n            symbols: chargeFeeTokenList?.slice(0, chargeFeeTokenList.length - 1).map((item) => item.belong ?? '').join(', '),\n            lastSymbol: chargeFeeTokenList ? chargeFeeTokenList[chargeFeeTokenList.length - 1].belong : '',\n          })}\n        </Typography>\n      )\n    } else {\n      return <></>\n    }\n  }, [isNewAccount, chargeFeeTokenList, tradeData, t, feeChargeOrder])\n  \n  if (isNewAccount && isLoopringSmartWallet) {\n    return <Box\n      flex={1}\n      display={'flex'}\n      alignItems={'center'}\n      height={'100%'}\n      justifyContent={'space-evenly'}\n      flexDirection={'column'}\n      paddingX={2}\n    >\n      <FailedIcon style={{ height: 60, width: 60 }} color={'error'} />\n      <Typography textAlign={'center'} variant={'body1'} component={'span'}>\n        {t(\"labelSmartWalletDepositError1\")}<br/>\n        {t(\"labelSmartWalletDepositError2\")}<br/>\n        {t(\"labelSmartWalletDepositError3\")}\n\n      </Typography>\n      <Button\n        fullWidth\n        variant={'contained'}\n        size={'medium'}\n        color={'primary'}\n        onClick={onClose}\n      >\n        {t(\"labelClose\")}\n      </Button>\n    </Box>\n\n  }\n\n  return (\n    <GridWrapStyle\n      className={'deposit-wrap'}\n      container\n      paddingTop={isMobile ? 1 : '0'}\n      paddingLeft={5 / 2}\n      paddingRight={5 / 2}\n      direction={'column'}\n      justifyContent={'space-between'}\n      alignItems={'center'}\n      flex={1}\n      height={'100%'}\n      minWidth={'220px'}\n    >\n      <DepositTitle title={title ? t(title) : undefined} isHideDes={isHideDes} />\n      <Grid item marginTop={2} alignSelf={'stretch'}>\n        <BasicACoinTrade\n          {...{\n            ...rest,\n            t,\n            type: TRADE_TYPE.TOKEN,\n            disabled,\n            onChangeEvent,\n            walletMap,\n            tradeData,\n            coinMap,\n            inputButtonDefaultProps,\n            placeholderText: minFee?.minFee ? minFee.minFee : '0.00',\n            inputBtnRef: inputBtnRef,\n          }}\n        />\n        {isNewAccount && <>{isNewAlert}</>}\n      </Grid>\n      {isAllowInputToAddress ? (\n        <Grid item marginTop={2} alignSelf={'stretch'} position={'relative'}>\n          <Box display={isToAddressEditable ? 'inherit' : 'none'}>\n            <TextField\n              className={'text-address'}\n              value={toAddress ?? ''}\n              error={!!realToAddress && toAddressStatus !== AddressError.NoError}\n              label={t('depositLabelTo')}\n              disabled={!isToAddressEditable}\n              placeholder={t('depositLabelPlaceholder')}\n              onChange={(_event) => {\n                handleAddressChange && handleAddressChange(_event.target.value)\n              }}\n              fullWidth={true}\n            />\n            {toAddress ? (\n              toIsAddressCheckLoading ? (\n                <LoadingIcon\n                  width={24}\n                  style={{ top: '32px', right: '8px', position: 'absolute' }}\n                />\n              ) : (\n                isToAddressEditable && (\n                  <IconClearStyled\n                    color={'inherit'}\n                    size={'small'}\n                    style={{ top: '30px' }}\n                    aria-label='Clear'\n                    onClick={() => {\n                      handleClear()\n                    }}\n                  >\n                    <CloseIcon />\n                  </IconClearStyled>\n                )\n              )\n            ) : (\n              ''\n            )}\n\n            <Box marginLeft={1 / 2}>\n              {realToAddress && toAddressStatus !== AddressError.NoError ? (\n                <Typography\n                  color={'var(--color-error)'}\n                  variant={'body2'}\n                  marginTop={1 / 2}\n                  alignSelf={'stretch'}\n                  position={'relative'}\n                >\n                  {t('labelInvalidAddress')}\n                </Typography>\n              ) : toAddress && realToAddress && !toIsAddressCheckLoading ? (\n                <Typography\n                  color={'var(--color-text-primary)'}\n                  variant={'body2'}\n                  marginTop={1 / 2}\n                  style={{ wordBreak: 'break-all' }}\n                  whiteSpace={'pre-line'}\n                >\n                  {realToAddress}\n                </Typography>\n              ) : (\n                <></>\n              )}\n            </Box>\n          </Box>\n          {!isToAddressEditable &&\n            (!realToAddress ? (\n              <Box>\n                <Typography color={'var(--color-text-third)'} variant={'body1'}>\n                  {t('labelBridgeSendTo')}\n                </Typography>\n                <Typography\n                  display={'inline-flex'}\n                  variant={tradeData.toAddress?.startsWith('0x') ? 'body2' : 'body1'}\n                  style={{ wordBreak: 'break-all' }}\n                  color={'textSecondary'}\n                >\n                  {tradeData.toAddress}\n                </Typography>\n              </Box>\n            ) : toIsAddressCheckLoading ? (\n              <Box display={'flex'} alignItems={'center'} justifyContent={'center'}>\n                <img\n                  className='loading-gif'\n                  alt={'loading'}\n                  width='36'\n                  src={`${SoursURL}images/loading-line.gif`}\n                />\n              </Box>\n            ) : realToAddress && toAddressStatus !== AddressError.NoError ? (\n              <Typography variant={'body1'} color={'var(--color-warning)'}>\n                {toAddressStatus === AddressError.ENSResolveFailed ? (\n                  <>{t('labelENSShouldConnect')}</>\n                ) : (\n                  <Trans\n                    i18nKey={'labelInvalidAddressClick'}\n                    tOptions={{\n                      way: t(`labelPayLoopringL2`, {\n                        layer2: L1L2_NAME_DEFINED[network].layer2,\n                        l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                        loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                        l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                        l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                        ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                      }),\n                      token: 'ERC20 ',\n                    }}\n                  >\n                    Invalid Wallet Address, Pay Loopring L2 of ERC20 is disabled!\n                    <Link\n                      alignItems={'center'}\n                      display={'inline-flex'}\n                      href={Bridge}\n                      target={'_blank'}\n                      rel={'noopener noreferrer'}\n                      color={'textSecondary'}\n                    >\n                      Click to input another receive address\n                    </Link>\n                    ,\n                  </Trans>\n                )}\n              </Typography>\n            ) : (\n              <>\n                <Box>\n                  <Typography color={'var(--color-text-third)'} minWidth={40}>\n                    {t('labelReceiveAddress')}\n                  </Typography>\n                  <Typography\n                    display={'inline-flex'}\n                    variant={'body2'}\n                    style={{ wordBreak: 'break-all' }}\n                    whiteSpace={'pre-line'}\n                    color={'textSecondary'}\n                  >\n                    {realToAddress}\n                  </Typography>\n                </Box>\n              </>\n            ))}\n        </Grid>\n      ) : (\n        <>\n          {toAddress && toAddressStatus !== AddressError.NoError ? (\n            <Typography variant={'body1'} color={'textSecondary'}>\n              {toAddressStatus === AddressError.ENSResolveFailed ? (\n                <>{t('labelENSShouldConnect')}</>\n              ) : toAddressStatus === AddressError.TimeOut ? (\n                <Trans\n                  i18nKey={'labelTimeoutAddressClick'}\n                  tOptions={{\n                    layer2: L1L2_NAME_DEFINED[network].layer2,\n                    l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                    loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                    l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                    l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                    ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                  }}\n                  components={{\n                    a: (\n                      <Link\n                        alignItems={'center'}\n                        display={'inline-flex'}\n                        target={'_blank'}\n                        onClick={() => {\n                          handleAddressChange && handleAddressChange(toAddress ?? '')\n                        }}\n                        rel={'noopener noreferrer'}\n                        color={'textPrimary'}\n                      />\n                    ),\n                  }}\n                >\n                  L1 Account checking request was rejected or some unknown error occurred, please\n                  <a>Retry</a>\n                </Trans>\n              ) : (\n                <Trans\n                  i18nKey={'labelInvalidAddressClick'}\n                  tOptions={{\n                    way: t(`labelPayLoopringL2`, {\n                      layer2: L1L2_NAME_DEFINED[network].layer2,\n                      l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                      loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                      l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                      l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                      ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                    }),\n                    token: 'ERC20 ',\n                  }}\n                >\n                  Invalid Wallet Address, Pay Loopring L2 of ERC20 is disabled!\n                  <Link\n                    alignItems={'center'}\n                    display={'inline-flex'}\n                    href={Bridge}\n                    target={'_blank'}\n                    rel={'noopener noreferrer'}\n                    color={'textSecondary'}\n                  >\n                    Click to input another receive address\n                  </Link>\n                  ,\n                </Trans>\n              )}\n            </Typography>\n          ) : (\n            <></>\n          )}\n        </>\n      )}\n\n      <Grid item marginTop={2} alignSelf={'stretch'}>\n        {tradeData.belong === 'ETH' && (\n          <Typography\n            color={'var(--color-warning)'}\n            component={'p'}\n            variant={'body1'}\n            marginBottom={1}\n          >\n            {t('labelIsETHDepositAlert')}\n          </Typography>\n        )}\n        <Button\n          fullWidth\n          variant={'contained'}\n          size={'medium'}\n          color={'primary'}\n          onClick={() => {\n            accountReady == AccountStatus.UN_CONNECT\n              ? onDepositClick(tradeData)\n              : handleConfirm && handleConfirm(0)\n          }}\n          loading={!getDisabled && depositBtnStatus === TradeBtnStatus.LOADING ? 'true' : 'false'}\n          disabled={getDisabled || depositBtnStatus === TradeBtnStatus.LOADING}\n        >\n          {btnInfo ? t(btnInfo.label, btnInfo.params) : t(`labelDeposit`)}\n        </Button>\n      </Grid>\n    </GridWrapStyle>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/DualWrap/Interface.ts",
    "content": "import { BtnInfo, InputButtonProps } from '../../../basic-lib'\nimport {\n  AccountStatus,\n  CoinInfo,\n  DualCurrentPrice,\n  DualViewBase,\n  DualViewInfo,\n  DualViewType,\n  TradeBtnStatus,\n} from '@loopring-web/common-resources'\nimport { TokenInfo } from '@loopring-web/loopring-sdk'\nimport React from 'react'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nexport enum DualDisplayMode {\n  nonBeginnerMode = 1,\n  beginnerModeStep1,\n  beginnerModeStep2,\n}\nexport type DualDetailType = {\n  dualViewInfo: DualViewBase & (Partial<sdk.UserDualTxsHistory> | Partial<sdk.DualProductAndPrice>)\n  currentPrice: DualCurrentPrice\n  lessEarnView: string\n  greaterEarnView: string\n  lessEarnTokenSymbol: string\n  greaterEarnTokenSymbol: string\n  isOrder?: boolean\n  dualProducts?: DualViewInfo[]\n  getProduct?: () => void\n  order: any | undefined\n  __raw__?: any\n}\nexport type DualChgData<T> = {\n  tradeData?: undefined | T\n}\nexport type DualWrapProps<T, I, DUAL> = {\n  disabled?: boolean\n  btnInfo?: BtnInfo\n  refreshRef: React.Ref<any>\n  onRefreshData?: (shouldFeeUpdate?: boolean, clearTrade?: boolean) => void\n  isLoading: boolean\n  tokenMap: { [key: string]: TokenInfo }\n  // maxSellVol?: string;\n  onSubmitClick: () => void\n  onChangeEvent: (data: DualChgData<T>) => void\n  handleError?: (data: T) => void\n  tokenSellProps?: Partial<InputButtonProps<T, I, CoinInfo<I>>>\n  dualCalcData: DUAL\n  tokenSell: TokenInfo\n  btnStatus?: keyof typeof TradeBtnStatus | undefined\n  accStatus?: AccountStatus\n  dualProducts?: DualViewInfo[]\n  toggle: { enable: boolean; reason?: string | undefined }\n  viewType?: DualViewType\n  setShowAutoDefault: (show: boolean) => void\n  showAutoDefault: boolean\n}\n\nexport type DualDetailProps<\n  R = { isRenew: boolean; renewTargetPrice?: string; renewDuration?: number },\n> = DualDetailType & {\n  coinSell: R\n  btnConfirm?: any\n  onChange: (props: R) => void\n  isPriceEditable: boolean\n  dualProducts: DualViewInfo[]\n  getProduct?: () => void\n  displayMode?: DualDisplayMode\n  toggle: { enable: boolean; reason?: string }\n  inputPart?: JSX.Element | undefined\n  showClock?: boolean\n  setShowAutoDefault: (show: boolean) => void\n  onChangeOrderReinvest: (\n    info: { on: boolean; renewTargetPrice?: string; renewDuration?: number },\n    item: R,\n  ) => void\n  showAutoDefault: boolean\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/DualWrap/ModifyParameter.tsx",
    "content": "import {\n  BtnPercentage,\n  ButtonStyle,\n  CoinIcons,\n  DualDetailProps,\n  TickCardStyleItem,\n  useSettings,\n} from '@loopring-web/component-lib'\nimport React from 'react'\nimport { Box, Divider, Grid, Tooltip, Typography } from '@mui/material'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { DUAL_TYPE } from '@loopring-web/loopring-sdk'\nimport { Mark } from '@mui/base/SliderUnstyled/SliderUnstyledProps'\nimport { Trans, useTranslation } from 'react-i18next'\nimport {\n  DAY_MINUTE_FORMAT,\n  getValuePrecisionThousand,\n  Info2Icon,\n  TokenType,\n  WarningIcon2,\n} from '@loopring-web/common-resources'\nimport moment from 'moment'\nimport _ from 'lodash'\nimport BigNumber from 'bignumber.js'\n\nexport const ModifyParameter = ({\n  dualViewInfo,\n  coinSell,\n  onClose,\n  onChange,\n  isPriceEditable,\n  dualProducts,\n  btnConfirm,\n  // getProduct,\n  maxDuration = 10,\n  isOrder,\n  onChangeOrderReinvest\n}: DualDetailProps & { maxDuration?: number; onClose: () => void }) => {\n  const { t } = useTranslation()\n  const { coinJson } = useSettings()\n  const {\n    stepLength,\n    // strike,\n    currentPrice: { currentPrice, precisionForPrice, base, quote, quoteUnit },\n  } = dualViewInfo\n\n  const stepEle = React.useMemo(() => {\n    if (isPriceEditable) {\n      const listELE: JSX.Element[] = []\n      const method = dualViewInfo.dualType === DUAL_TYPE.DUAL_BASE ? 'plus' : 'minus'\n      // let method = sdk\n      //   .toBig(currentPrice ?? 0)\n      //   .minus(strike ?? 0)\n      //   .gte(0)? 'minus'  : 'plus'\n\n      let start = sdk.toBig(stepLength ?? 0).times(\n        sdk\n          .toBig(currentPrice ?? 0)\n          .div(stepLength ?? 1)\n          .toFixed(0),\n      )\n\n      // if(strike)\n      if (method === 'minus' && start.gt(currentPrice ?? 0)) {\n        start = sdk.toBig(start).minus(stepLength ?? 0)\n      } else if (method === 'plus' && start.lt(currentPrice ?? 0)) {\n        start = sdk.toBig(start).plus(stepLength ?? 0)\n      }\n      const strikes = _.range(12).map((index) =>\n        method === 'minus'\n          ? start.minus(sdk.toBig(stepLength ?? 0).times(index) ?? 0)\n          : start.plus(sdk.toBig(stepLength ?? 0).times(index) ?? 0),\n      )\n      let strikes2: BigNumber[]\n      if (\n        !strikes.find((strike) => coinSell.renewTargetPrice && strike.eq(coinSell.renewTargetPrice))\n      ) {\n        strikes2 = [sdk.toBig(coinSell.renewTargetPrice ?? 0), ...strikes.slice(0, 11)]\n      } else {\n        strikes2 = strikes\n      }\n      return strikes2\n        .sort((a, b) =>\n          a\n            .minus(b)\n            .times(method === 'minus' ? '-1' : '1')\n            .toNumber(),\n        )\n        .map((item, index) => {\n          const dualProduct = dualProducts?.find((dualProduct) =>\n            sdk.toBig(dualProduct.strike).eq(item),\n          )\n          const value = item.toString()\n          return (\n            <Grid item key={index} xs={3}>\n              <TickCardStyleItem\n                selected={item.eq(coinSell.renewTargetPrice ?? 0)}\n                className={\n                  item.eq(coinSell.renewTargetPrice ?? 0)\n                    ? 'btnCard dualInvestCard selected dualPrice'\n                    : 'btnCard dualInvestCard dualPrice'\n                }\n                // selected={coinSell.renewTargetPrice ?? 0}\n                onClick={() =>\n                  onChange({\n                    ...coinSell,\n                    renewDuration: coinSell.renewDuration,\n                    renewTargetPrice: value,\n                  })\n                }\n              >\n                <Typography\n                  variant={'body1'}\n                  component={'span'}\n                  display={'flex'}\n                  flexDirection={'column'}\n                  alignItems={'center'}\n                  justifyContent={'center'}\n                  width={'100%'}\n                >\n                  <Typography\n                    variant={'inherit'}\n                    component={'span'}\n                    display={'flex'}\n                    flexDirection={'column'}\n                  >\n                    {value}\n                  </Typography>\n                  <Typography\n                    component={'span'}\n                    display={'flex'}\n                    variant={'body2'}\n                    flexDirection={'column'}\n                    color={'textSecondary'}\n                  >\n                    {dualProduct && t('labelDualModifyAPR', { value: dualProduct.apy })}\n                  </Typography>\n                </Typography>\n              </TickCardStyleItem>\n            </Grid>\n          )\n        })\n    } else {\n      return []\n    }\n  }, [dualProducts, coinSell.renewDuration, , coinSell?.renewTargetPrice, isPriceEditable])\n\n  return (\n    <Box marginTop={-4}>\n      <Typography\n        component={'header'}\n        height={'var(--toolbar-row-height)'}\n        display={'flex'}\n        paddingX={3}\n        flexDirection={'row'}\n        alignItems={'center'}\n      >\n        <Typography component={'span'} display={'inline-flex'}>\n          {/* eslint-disable-next-line react/jsx-no-undef */}\n          <CoinIcons\n            type={TokenType.dual}\n            size={32}\n            tokenIcon={[coinJson[dualViewInfo.sellSymbol], coinJson[dualViewInfo.buySymbol]]}\n          />\n        </Typography>\n        <Typography component={'span'} display={'inline-flex'} color={'textPrimary'}>\n          {t('labelDualModifyParameter')}\n        </Typography>\n      </Typography>\n      <Divider />\n      {isPriceEditable && (\n        <>\n          <Typography\n            component={'span'}\n            variant={'body1'}\n            display={'flex'}\n            flexDirection={'column'}\n            sx={{\n              background: 'var(--vip-bg)',\n            }}\n            padding={2}\n            marginBottom={2}\n          >\n            <Typography\n              component={'span'}\n              color={'textPrimary'}\n              display={'inline-flex'}\n              alignItems={'center'}\n            >\n              <WarningIcon2\n                htmlColor={'var(--color-warning)'}\n                fontSize={'large'}\n                sx={{\n                  marginRight: 1,\n                }}\n              />\n              {t('labelDualModifySettlementDateDes')}\n            </Typography>\n            <Typography component={'span'} color={'textPrimary'}>\n              <WarningIcon2\n                color={'warning'}\n                fontSize={'large'}\n                sx={{\n                  visibility: 'hidden',\n                  marginRight: 1,\n                }}\n              />\n              {t('labelDualModifySettlementDate', {\n                date: moment(new Date(dualViewInfo.expireTime)).format(DAY_MINUTE_FORMAT),\n                interpolation: {\n                  escapeValue: false,\n                },\n              })}\n            </Typography>\n          </Typography>\n          <Box display={'flex'} margin={2} flexDirection={'column'}>\n            <Typography\n              variant={'body1'}\n              component={'span'}\n              display={'inline-flex'}\n              color={'textPrimary'}\n              paddingBottom={1}\n            >\n              <Trans\n                i18nKey={'labelDualCurrentPrice'}\n                tOptions={{\n                  price:\n                    // PriceTag[CurrencyToTag[currency]] +\n                    getValuePrecisionThousand(\n                      currentPrice,\n                      precisionForPrice,\n                      precisionForPrice,\n                      undefined,\n                    ),\n                  symbol: base,\n                  baseSymbol: /USD/gi.test(quoteUnit ?? '') ? 'USDT' : quoteUnit,\n                }}\n              >\n                LRC Current price:\n                <Typography\n                  component={'span'}\n                  display={'inline-flex'}\n                  color={'textPrimary'}\n                  paddingLeft={1}\n                >\n                  price\n                </Typography>\n                :\n              </Trans>\n            </Typography>\n            <Grid container spacing={2}>\n              {stepEle}\n            </Grid>\n          </Box>\n        </>\n      )}\n      <Grid item xs={12}>\n        <Tooltip title={t('labelDualEditDurationDes').toString()}>\n          <Typography\n            component={'span'}\n            variant={'body1'}\n            color={'textPrimary'}\n            display={'inline-flex'}\n            alignItems={'center'}\n            paddingX={2}\n            marginY={1}\n          >\n            <Trans i18nKey={'labelDualEditDuration'}>\n              Modify Longest Settlement Date\n              <Info2Icon fontSize={'small'} color={'inherit'} sx={{ marginX: 1 / 2 }} />\n            </Trans>\n          </Typography>\n        </Tooltip>\n        <Box padding={4}>\n          <BtnPercentage\n            selected={Number(coinSell.renewDuration ?? 7)}\n            handleChanged={(value) => {\n              onChange({\n                ...coinSell,\n                renewDuration: value,\n              })\n            }}\n            anchors={\n              Array.from({ length: maxDuration }, (_, index) => ({\n                value: index + 1,\n                label:\n                  (index + 1) % 5 == 0 || index == 0 || index == maxDuration - 1\n                    ? t('labelDayDisplay', { item: index + 1 })\n                    : '',\n              })) as Mark[]\n            }\n            min={1}\n            max={maxDuration}\n            valueLabelDisplay='on'\n            valuetext={(item) => t('labelDayDisplay', { item })}\n            step={1}\n          />\n        </Box>\n      </Grid>\n      <Grid item xs={12}>\n        <Box paddingX={2} marginY={2}>\n          {btnConfirm ? (\n            btnConfirm\n          ) : (\n            <ButtonStyle\n              fullWidth\n              variant={'contained'}\n              size={'medium'}\n              color={'primary'}\n              onClick={() => {\n                if (isOrder) {\n                  onChangeOrderReinvest({\n                    on: true,\n                    renewDuration: coinSell.renewDuration,\n                    renewTargetPrice: coinSell.renewTargetPrice\n                  }, coinSell);\n                  onClose()\n                } else {\n                  onClose()\n                }\n              }}\n            >\n              {t('labelDualModifyConfirm')}\n            </ButtonStyle>\n          )}\n        </Box>\n      </Grid>\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/DualWrap/ModifySetting.tsx",
    "content": "import {\n  BtnPercentage,\n  ButtonStyle,\n  OutlineSelect,\n  OutlineSelectItem,\n  useSettings,\n} from '@loopring-web/component-lib'\nimport { Box, Divider, FormControlLabel, Grid, Switch, Typography } from '@mui/material'\nimport { Mark } from '@mui/base'\nimport { Trans, useTranslation } from 'react-i18next'\nimport { DropDownIcon, Info2Icon } from '@loopring-web/common-resources'\n\nexport const ModifySetting = ({\n  onClose,\n  maxDuration = 10,\n}: {\n  maxDuration?: number\n  onClose: () => void\n}) => {\n  const { t } = useTranslation()\n  const { dualAuto, setDualDefault } = useSettings()\n  return (\n    <Box marginTop={-4}>\n      <Typography\n        component={'header'}\n        height={'var(--toolbar-row-height)'}\n        display={'flex'}\n        paddingX={3}\n        flexDirection={'row'}\n        alignItems={'center'}\n      >\n        <Typography component={'span'} display={'inline-flex'} color={'textPrimary'}>\n          {t('labelDualAutoReinvest')}\n        </Typography>\n      </Typography>\n      <Divider />\n      <Grid item xs={12}>\n        <Box paddingX={3} display={'flex'} justifyContent={'space-between'}>\n          <Typography\n            component={'span'}\n            variant={'body1'}\n            color={'textPrimary'}\n            display={'inline-flex'}\n            alignItems={'center'}\n          >\n            <Trans i18nKey={'labelDualDefaultAutoTitle'}>Default Enable Auto Reinvest</Trans>\n          </Typography>\n\n          <Typography component={'span'} variant={'inherit'}>\n            <FormControlLabel\n              sx={{\n                marginRight: 0,\n              }}\n              onChange={(_e, checked) => {\n                setDualDefault({\n                  ...dualAuto,\n                  auto: checked,\n                })\n              }}\n              control={<Switch color={'primary'} checked={dualAuto.auto} />}\n              label={''}\n            />\n          </Typography>\n        </Box>\n      </Grid>\n      <Grid item xs={12}>\n        <Box paddingX={3} display={'flex'} justifyContent={'space-between'}>\n          <Typography\n            component={'span'}\n            variant={'body1'}\n            color={'textPrimary'}\n            display={'inline-flex'}\n            alignItems={'center'}\n            marginY={1}\n          >\n            <Trans i18nKey={'labelDualLongestSettlementDuration'}>\n              Modify Longest Settlement Date\n              <Info2Icon fontSize={'small'} color={'inherit'} sx={{ marginX: 1 / 2 }} />\n            </Trans>\n          </Typography>\n          <OutlineSelect\n            aria-label={t('Dual Longest Settlement')}\n            IconComponent={DropDownIcon}\n            id='DualLongestSettlement'\n            value={dualAuto.day !== 'auto' ? 7 : dualAuto.day}\n            autoWidth\n            onChange={(e) => {\n              setDualDefault({\n                ...dualAuto,\n                day: e.target.value as unknown as any,\n              })\n            }}\n          >\n            <OutlineSelectItem value={7}>{t('labelDualLongestSettlementFixed')}</OutlineSelectItem>\n            <OutlineSelectItem value={'auto'}>\n              {t('labelDualLongestSettlementAutomatic')}\n            </OutlineSelectItem>\n          </OutlineSelect>\n        </Box>\n        <Box paddingX={5} marginTop={1}>\n          {dualAuto?.day !== 'auto' && (\n            <BtnPercentage\n              selected={Number(dualAuto?.day ?? 7)}\n              handleChanged={(value) => {\n                setDualDefault({\n                  ...dualAuto,\n                  day: value,\n                })\n              }}\n              anchors={\n                Array.from({ length: maxDuration }, (_, index) => ({\n                  value: index + 1,\n                  label:\n                    (index + 1) % 5 == 0 || index == 0 || index == maxDuration - 1\n                      ? t('labelDayDisplay', { item: index + 1 })\n                      : '',\n                })) as Mark[]\n              }\n              min={1}\n              max={maxDuration}\n              valueLabelDisplay='on'\n              valuetext={(item) => t('labelDayDisplay', { item })}\n              step={1}\n            />\n          )}\n        </Box>\n      </Grid>\n      <Grid item xs={12}>\n        <Box paddingX={3} marginY={2}>\n          <ButtonStyle\n            fullWidth\n            variant={'contained'}\n            size={'medium'}\n            color={'primary'}\n            onClick={() => {\n              onClose()\n            }}\n          >\n            {t('labelDualSettingConfirm')}\n          </ButtonStyle>\n        </Box>\n      </Grid>\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/DualWrap/dualDetail.tsx",
    "content": "import { DualDetailProps, DualDisplayMode } from './Interface'\nimport React from 'react'\nimport { Trans, useTranslation } from 'react-i18next'\nimport { useSettings } from '../../../../stores'\nimport {\n  BackIcon,\n  DualCurrentPrice,\n  DualViewBase,\n  EmptyValueTag,\n  getValuePrecisionThousand,\n  Info2Icon,\n  MoreIcon,\n  myLog,\n  SoursURL,\n  UpColor,\n  WarningIcon2,\n  YEAR_DAY_MINUTE_FORMAT,\n} from '@loopring-web/common-resources'\nimport {\n  Box,\n  Divider,\n  Switch,\n  FormControlLabel,\n  Link,\n  Modal,\n  Tooltip,\n  Typography,\n  Tab,\n  IconButton,\n} from '@mui/material'\nimport { ModalCloseButton, Tabs } from '../../../basic-lib'\nimport { ModifyParameter } from './ModifyParameter'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport moment from 'moment/moment'\nimport styled from '@emotion/styled'\nimport { SwitchPanelStyled } from '../../../styled'\nimport { LABEL_INVESTMENT_STATUS_MAP } from '../../../tableList'\nimport { CancelDualAlert } from '../tool'\nimport { ModifySetting } from './ModifySetting'\nimport { confirmation } from '@loopring-web/core'\n\nconst BoxChartStyle = styled(Box)`\n  background-clip: content-box;\n  background-size: contain;\n  background-repeat: no-repeat;\n  min-height: 176px;\n  width: 100%;\n  &.mobile {\n    min-height: 122px;\n  }\n\n  &.dualHL {\n    background-image: url('${SoursURL}/images/dualHL.png');\n  }\n  &.dualHH {\n    background-image: url('${SoursURL}/images/dualHH.png');\n  }\n  &.dualLL {\n    background-image: url('${SoursURL}/images/dualLL.png');\n  }\n  &.dualLH {\n    background-image: url('${SoursURL}/images/dualLH.png');\n  }\n  .point {\n    position: absolute;\n    display: flex;\n    flex-direction: column;\n    align-items: center;\n    // top: ${({ theme }) => theme.unit}px;\n  }\n  .point1 {\n    top: 50%;\n    transform: translateY(-50%);\n    right: ${({ theme }) => theme.unit}px;\n    justify-content: flex-end;\n\n    //left: 50%;\n    //transform: translateX(-50%);\n  }\n  .point2 {\n    top: ${({ theme }) => theme.unit}px;\n    left: ${({ theme }) => theme.unit}px;\n  }\n  .returnV {\n    position: absolute;\n    bottom: 0;\n    height: 50%;\n    width: 50%;\n    left: 50%;\n    display: flex;\n    align-items: center;\n    justify-content: left;\n    text-indent: 0;\n    padding-left: ${({ theme }) => 2 * theme.unit}px;\n    //text-align: left;\n  }\n  .returnV2 {\n    color: var(--color-warning);\n  }\n  .returnV1 {\n    color: var(--color-success);\n    top: 0;\n  }\n`\nexport enum DualDetailTab {\n  less = 0,\n  greater = 1,\n}\nexport const DualDes = ({\n  dualViewInfo,\n  currentPrice,\n  isOrder,\n}: {\n  currentPrice: DualCurrentPrice\n  isOrder: boolean\n  dualViewInfo: DualViewBase & (Partial<sdk.UserDualTxsHistory> | Partial<sdk.DualProductAndPrice>)\n}) => {\n  const { t } = useTranslation(['common', 'tables'])\n  const { upColor } = useSettings()\n  const { precisionForPrice, quoteUnit } = currentPrice\n  const quoteAlice = /USD/gi.test(quoteUnit ?? '') ? 'USDT' : quoteUnit\n\n  const targetView = React.useMemo(() => {\n    return dualViewInfo?.strike\n      ? getValuePrecisionThousand(\n          dualViewInfo.strike,\n          precisionForPrice,\n          precisionForPrice,\n          precisionForPrice,\n          true,\n          { floor: true },\n        )\n      : EmptyValueTag\n  }, [dualViewInfo?.strike])\n  return (\n    <Box\n      display={'flex'}\n      flexDirection={'column'}\n      alignItems={'stretch'}\n      justifyContent={'space-between'}\n      marginX={2}\n      marginBottom={isOrder ? 2 : 0}\n      paddingX={2}\n      paddingTop={1}\n      borderRadius={1 / 2}\n      order={isOrder ? 0 : 0}\n      sx={{\n        background: 'var(--field-opacity)',\n      }}\n    >\n      {isOrder && (\n        <>\n          <Typography\n            variant={'body1'}\n            display={'inline-flex'}\n            alignItems={'center'}\n            justifyContent={'space-between'}\n            paddingBottom={1}\n            order={0}\n          >\n            <Typography\n              component={'span'}\n              variant={'inherit'}\n              color={'textSecondary'}\n              display={'inline-flex'}\n              alignItems={'center'}\n            >\n              <Trans i18nKey={'labelDualStatus'}>Status</Trans>\n            </Typography>\n            <Typography component={'span'} variant={'inherit'} color={dualViewInfo?.statusColor}>\n              {dualViewInfo?.side ?? ''}\n            </Typography>\n          </Typography>\n          <Typography\n            variant={'body1'}\n            display={'inline-flex'}\n            alignItems={'center'}\n            justifyContent={'space-between'}\n            paddingBottom={1}\n            order={1}\n          >\n            <Typography\n              component={'span'}\n              variant={'inherit'}\n              color={'textSecondary'}\n              display={'inline-flex'}\n              alignItems={'center'}\n            >\n              {t('labelDualAmount')}\n            </Typography>\n            <Typography component={'span'} variant={'inherit'} color={'textPrimary'}>\n              {dualViewInfo?.amount}\n            </Typography>\n          </Typography>\n          {dualViewInfo.outSymbol && (\n            <Typography\n              variant={'body1'}\n              display={'inline-flex'}\n              alignItems={'center'}\n              justifyContent={'space-between'}\n              paddingBottom={1}\n              order={2}\n            >\n              <Typography\n                component={'span'}\n                variant={'inherit'}\n                color={'textSecondary'}\n                display={'inline-flex'}\n                alignItems={'center'}\n              >\n                {t('labelDualTxsSettlement')}\n              </Typography>\n              <Typography component={'span'} variant={'inherit'}>\n                {dualViewInfo.outAmount + ' ' + dualViewInfo.outSymbol}\n              </Typography>\n            </Typography>\n          )}\n          {dualViewInfo?.deliveryPrice && (\n            <Typography\n              variant={'body1'}\n              display={'inline-flex'}\n              alignItems={'center'}\n              justifyContent={'space-between'}\n              paddingBottom={1}\n              order={4}\n            >\n              <Typography\n                component={'span'}\n                variant={'inherit'}\n                color={'textSecondary'}\n                display={'inline-flex'}\n                alignItems={'center'}\n              >\n                {t('labelDualDeliver')}\n              </Typography>\n              <Typography\n                component={'span'}\n                variant={'inherit'}\n                color={upColor == UpColor.green ? 'var(--color-success)' : 'var(--color-error)'}\n              >\n                {dualViewInfo.deliveryPrice + ' ' + quoteAlice}\n              </Typography>\n            </Typography>\n          )}\n          {dualViewInfo.enterTime && (\n            <>\n              <Typography\n                variant={'body1'}\n                display={'inline-flex'}\n                alignItems={'center'}\n                justifyContent={'space-between'}\n                paddingBottom={1}\n                order={9}\n              >\n                <Typography\n                  component={'span'}\n                  variant={'inherit'}\n                  color={'textSecondary'}\n                  display={'inline-flex'}\n                  alignItems={'center'}\n                >\n                  {t('labelDualSubDate')}\n                </Typography>\n                <Typography component={'span'} variant={'inherit'} color={'textPrimary'}>\n                  {moment(new Date(dualViewInfo.enterTime)).format(YEAR_DAY_MINUTE_FORMAT)}\n                </Typography>\n              </Typography>\n\n              <Typography\n                variant={'body1'}\n                display={'inline-flex'}\n                alignItems={'center'}\n                justifyContent={'space-between'}\n                paddingBottom={1}\n                order={7}\n              >\n                <Typography\n                  component={'span'}\n                  variant={'inherit'}\n                  color={'textSecondary'}\n                  display={'inline-flex'}\n                  alignItems={'center'}\n                >\n                  {t('labelDualAuto')}\n                </Typography>\n\n                {dualViewInfo.autoIcon && dualViewInfo?.autoStatus ? (\n                  <Tooltip\n                    title={t(dualViewInfo?.autoStatus, {\n                      day: dualViewInfo.maxDuration\n                        ? dualViewInfo.maxDuration / 86400000\n                        : EmptyValueTag,\n                      price: dualViewInfo.newStrike ? dualViewInfo.newStrike : EmptyValueTag,\n                    }).toString()}\n                  >\n                    <Typography\n                      component={'span'}\n                      display={'inline-flex'}\n                      alignItems={'center'}\n                      variant={'inherit'}\n                      color={'textPrimary'}\n                    >\n                      <>{t(dualViewInfo?.autoContent ?? '')}</>\n                      <>{dualViewInfo.autoIcon}</>\n                    </Typography>\n                  </Tooltip>\n                ) : (\n                  <Typography component={'span'} variant={'inherit'} color={'textPrimary'}>\n                    {dualViewInfo?.autoContent ?? ''}\n                  </Typography>\n                )}\n              </Typography>\n            </>\n          )}\n        </>\n      )}\n      <Typography\n        variant={'body1'}\n        display={'inline-flex'}\n        alignItems={'center'}\n        justifyContent={'space-between'}\n        paddingBottom={1}\n        order={8}\n      >\n        <Tooltip title={t('labelDualCurrentAPRDes').toString()}>\n          <Typography\n            component={'span'}\n            variant={'inherit'}\n            color={'textSecondary'}\n            display={'inline-flex'}\n            alignItems={'center'}\n          >\n            <Trans i18nKey={'labelDualCurrentAPR'}>\n              APR\n              <Info2Icon fontSize={'small'} color={'inherit'} sx={{ marginX: 1 / 2 }} />\n            </Trans>\n          </Typography>\n        </Tooltip>\n        <Typography\n          component={'span'}\n          variant={'inherit'}\n          color={upColor == UpColor.green ? 'var(--color-success)' : 'var(--color-error)'}\n        >\n          {dualViewInfo?.apy}\n        </Typography>\n      </Typography>\n\n      <Typography\n        variant={'body1'}\n        display={'inline-flex'}\n        alignItems={'center'}\n        justifyContent={'space-between'}\n        paddingBottom={1}\n        order={3}\n      >\n        <Tooltip title={t('labelDualTargetPriceDes').toString()}>\n          <Typography\n            component={'span'}\n            variant={'inherit'}\n            color={'textSecondary'}\n            display={'inline-flex'}\n            alignItems={'center'}\n          >\n            <Trans i18nKey={'labelDualTargetPrice2'}>\n              Target Price\n              <Info2Icon fontSize={'small'} color={'inherit'} sx={{ marginX: 1 / 2 }} />\n            </Trans>\n          </Typography>\n        </Tooltip>\n        <Typography component={'span'} variant={'inherit'} color={'textPrimary'}>\n          {targetView + ' ' + quoteAlice}\n        </Typography>\n      </Typography>\n\n      <Typography\n        variant={'body1'}\n        display={'inline-flex'}\n        alignItems={'center'}\n        justifyContent={'space-between'}\n        paddingBottom={1}\n        order={5}\n      >\n        <Typography\n          component={'span'}\n          variant={'inherit'}\n          color={'textSecondary'}\n          display={'inline-flex'}\n          alignItems={'center'}\n        >\n          {t('labelDualSettleDate')}\n        </Typography>\n        <Typography component={'span'} variant={'inherit'} color={'textPrimary'}>\n          {moment(new Date(dualViewInfo.expireTime)).format(YEAR_DAY_MINUTE_FORMAT)}\n        </Typography>\n      </Typography>\n      <Typography\n        variant={'body1'}\n        display={'inline-flex'}\n        alignItems={'center'}\n        justifyContent={'space-between'}\n        paddingBottom={1}\n        order={6}\n      >\n        <Typography\n          component={'span'}\n          variant={'inherit'}\n          color={'textSecondary'}\n          display={'inline-flex'}\n          alignItems={'center'}\n        >\n          {t('labelDualSettleDateDur')}\n        </Typography>\n        <Typography component={'span'} variant={'inherit'} color={'textPrimary'}>\n          {getValuePrecisionThousand(\n            (dualViewInfo.expireTime -\n              (isOrder && dualViewInfo.enterTime ? dualViewInfo.enterTime : Date.now())) /\n              (1000 * 60 * 60 * 24),\n            1,\n            1,\n            1,\n            true,\n            { floor: true },\n          )}\n        </Typography>\n      </Typography>\n    </Box>\n  )\n}\n\nexport const DualDetail = ({\n  isOrder = false,\n  displayMode = DualDisplayMode.nonBeginnerMode,\n  isPriceEditable = true,\n  coinSell,\n  toggle,\n  btnConfirm,\n  inputPart,\n  showClock = false,\n  setShowAutoDefault,\n  showAutoDefault,\n  ...rest\n}: DualDetailProps) => {\n  const {\n    dualViewInfo,\n    currentPrice,\n    lessEarnView,\n    greaterEarnView,\n    onChange,\n    onChangeOrderReinvest,\n  } = rest\n  const [showEdit, setShowEdit] = React.useState(false)\n  const { t } = useTranslation(['common', 'tables'])\n  const { upColor, isMobile } = useSettings()\n  const { base, quote, precisionForPrice, quoteUnit } = currentPrice\n  const [tab, setTab] = React.useState<DualDetailTab>(DualDetailTab.less)\n  const currentView = React.useMemo(\n    () =>\n      base\n        ? getValuePrecisionThousand(\n            currentPrice.currentPrice,\n            precisionForPrice,\n            precisionForPrice,\n            precisionForPrice,\n            true,\n            { floor: true },\n          )\n        : EmptyValueTag,\n    [dualViewInfo.currentPrice.currentPrice, precisionForPrice],\n  )\n  const quoteAlice = /USD/gi.test(quoteUnit ?? '') ? 'USDT' : quoteUnit\n\n  const renewTargetPriceView = React.useMemo(() => {\n    return coinSell?.renewTargetPrice\n      ? getValuePrecisionThousand(\n          coinSell?.renewTargetPrice,\n          precisionForPrice,\n          precisionForPrice,\n          undefined,\n          true,\n          { floor: true },\n        )\n      : EmptyValueTag\n  }, [coinSell?.renewTargetPrice])\n  const targetView = React.useMemo(() => {\n    return dualViewInfo?.strike\n      ? getValuePrecisionThousand(\n          dualViewInfo.strike,\n          precisionForPrice,\n          precisionForPrice,\n          precisionForPrice,\n          true,\n          { floor: true },\n        )\n      : EmptyValueTag\n  }, [dualViewInfo?.strike])\n  myLog(\n    'dualViewInfo?.__raw__?.order?.investmentStatus',\n    dualViewInfo?.__raw__?.order?.investmentStatus,\n  )\n  const [showCancelOneAlert, setShowCancelOneAlert] = React.useState({\n    open: false,\n    row: undefined as any,\n  })\n  return (\n    <>\n      <Modal\n        open={showAutoDefault}\n        onClose={() => setShowAutoDefault(false)}\n        aria-labelledby='modal-modal-title'\n        aria-describedby='modal-modal-description'\n      >\n        <SwitchPanelStyled width={'var(--modal-width)'}>\n          <Box display={'flex'} width={'100%'} flexDirection={'column'}>\n            <ModalCloseButton onClose={() => setShowAutoDefault(false)} t={t} />\n            <ModifySetting onClose={() => setShowAutoDefault(false)} />\n          </Box>\n        </SwitchPanelStyled>\n      </Modal>\n      <Modal\n        open={showEdit}\n        onClose={() => setShowEdit(false)}\n        aria-labelledby='modal-modal-title'\n        aria-describedby='modal-modal-description'\n      >\n        <SwitchPanelStyled width={'var(--modal-width)'}>\n          <Box display={'flex'} width={'100%'} flexDirection={'column'}>\n            <ModalCloseButton onClose={() => setShowEdit(false)} t={t} {...rest} />\n            <ModifyParameter\n              toggle={toggle}\n              onClose={() => setShowEdit(false)}\n              {...rest}\n              btnConfirm={btnConfirm}\n              coinSell={coinSell}\n              isPriceEditable={isPriceEditable}\n              isOrder={isOrder}\n            />\n          </Box>\n        </SwitchPanelStyled>\n      </Modal>\n      <CancelDualAlert\n        open={showCancelOneAlert.open}\n        row={showCancelOneAlert.row}\n        handleCancelOne={async () => {\n          onChangeOrderReinvest({ on: false }, coinSell)\n        }}\n        handleClose={() => setShowCancelOneAlert({ open: false, row: undefined })}\n      />\n\n      <Box display={'flex'} flexDirection={'column'}>\n        {isOrder && showClock && (\n          <Typography\n            component={'span'}\n            variant={'body1'}\n            display={'flex'}\n            flexDirection={'column'}\n            sx={{\n              background: 'var(--vip-bg)',\n            }}\n            padding={2}\n            marginBottom={2}\n          >\n            <Typography\n              component={'span'}\n              color={'textPrimary'}\n              display={'inline-flex'}\n              alignItems={'center'}\n            >\n              <WarningIcon2\n                color={'warning'}\n                fontSize={'large'}\n                sx={{\n                  marginRight: 1,\n                }}\n              />\n              {t('labelDualAutoSearchingDes')}\n            </Typography>\n          </Typography>\n        )}\n        {displayMode !== DualDisplayMode.beginnerModeStep2 && (\n          <DualDes dualViewInfo={dualViewInfo} currentPrice={currentPrice} isOrder={isOrder} />\n        )}\n        {inputPart ? <>{inputPart}</> : <></>}\n        {(displayMode !== DualDisplayMode.beginnerModeStep2 && toggle?.enable && !isOrder) ||\n        isOrder ? (\n          // RETRY_SUCCESS  ｜ RETRY_FAILED  ｜ isRecursive=false\n          <Box\n            display={'flex'}\n            order={isOrder ? 1 : 2}\n            marginBottom={isOrder ? 2 : 2}\n            flexDirection={'column'}\n          >\n            <Box display={'flex'} flexDirection={'column'} paddingX={2}>\n              <Box display={'flex'} justifyContent={'space-between'}>\n                <Tooltip title={t('labelDualAutoTitleDes').toString()}>\n                  <Typography\n                    component={'span'}\n                    variant={'body1'}\n                    color={'textSecondary'}\n                    display={'inline-flex'}\n                    alignItems={'center'}\n                  >\n                    <Trans i18nKey={'labelDualAutoTitle'}>\n                      Auto Reinvest\n                      <Info2Icon fontSize={'small'} color={'inherit'} sx={{ marginX: 1 / 2 }} />\n                    </Trans>\n                  </Typography>\n                </Tooltip>\n                <Typography component={'span'} variant={'inherit'}>\n                  <FormControlLabel\n                    sx={{\n                      marginRight: 0,\n                    }}\n                    disabled={\n                      [\n                        sdk.DUAL_RETRY_STATUS.RETRY_SUCCESS,\n                        sdk.DUAL_RETRY_STATUS.RETRY_FAILED,\n                      ].includes(dualViewInfo?.__raw__?.order?.dualReinvestInfo.retryStatus) ||\n                      (dualViewInfo?.side === t(LABEL_INVESTMENT_STATUS_MAP.DELIVERING) &&\n                        !coinSell.isRenew)\n                    }\n                    onChange={(_e, checked) => {\n                      if (isOrder) {\n                        if (coinSell.isRenew) {\n                          setShowCancelOneAlert({\n                            open: true,\n                            row: {\n                              expireTime: dualViewInfo.__raw__?.order?.timeOrigin?.expireTime,\n                            },\n                          })\n                        } else {\n                          setShowEdit(true)\n                        }\n                      } else {\n                        onChange({\n                          ...coinSell,\n                          isRenew: checked,\n                        })\n                      }\n                    }}\n                    control={<Switch color={'primary'} checked={coinSell.isRenew} />}\n                    label={''}\n                  />\n                  <IconButton onClick={() => setShowAutoDefault(true)}>\n                    <MoreIcon />\n                  </IconButton>\n                </Typography>\n              </Box>\n\n              <Typography\n                component={'span'}\n                variant={'body2'}\n                color={'var(--color-text-third)'}\n                display={'inline-flex'}\n                alignItems={'center'}\n                paddingBottom={1}\n              >\n                {coinSell.isRenew && (\n                  <Trans i18nKey={'labelDualAutoDetail'}>\n                    Auto Reinvest will try to find a new product which based on the following rule\n                    at 16:00 on the settlement day.\n                  </Trans>\n                )}\n              </Typography>\n            </Box>\n            {coinSell.isRenew && (\n              <Box\n                display={'flex'}\n                flexDirection={'column'}\n                sx={{\n                  background: 'var(--field-opacity)',\n                }}\n                paddingY={1}\n                marginX={2}\n                borderRadius={1 / 2}\n              >\n                <Box\n                  display={'flex'}\n                  justifyContent={'space-between'}\n                  paddingBottom={1}\n                  paddingX={2}\n                >\n                  <Tooltip title={t(`labelDualAuto${dualViewInfo?.dualType}PriceDes`).toString()}>\n                    <Typography\n                      component={'span'}\n                      variant={'body1'}\n                      color={'textSecondary'}\n                      display={'inline-flex'}\n                      alignItems={'center'}\n                    >\n                      <Trans i18nKey={`labelDualAuto${dualViewInfo?.dualType}Price`}>\n                        type Price\n                        <Info2Icon fontSize={'small'} color={'inherit'} sx={{ marginX: 1 / 2 }} />\n                      </Trans>\n                    </Typography>\n                  </Tooltip>\n                  {isPriceEditable ? (\n                    <Link\n                      onClick={() => {\n                        setShowEdit(true)\n                      }}\n                      component={'a'}\n                      variant={'body1'}\n                      display={'inline-flex'}\n                      alignItems={'center'}\n                    >\n                      {renewTargetPriceView + ' ' + quoteAlice}\n                      <BackIcon fontSize={'small'} sx={{ transform: 'rotate(180deg)' }} />\n                    </Link>\n                  ) : (\n                    <Typography component={'span'} variant={'body1'}>\n                      {renewTargetPriceView + ' ' + quoteAlice}\n                    </Typography>\n                  )}\n                </Box>\n                <Box display={'flex'} justifyContent={'space-between'} paddingX={2}>\n                  <Tooltip title={t(`labelDualAutoDurationDes`).toString()}>\n                    <Typography\n                      component={'span'}\n                      variant={'body1'}\n                      color={'textSecondary'}\n                      display={'inline-flex'}\n                      alignItems={'center'}\n                    >\n                      <Trans i18nKey={`labelDualAutoDuration`}>\n                        Duration\n                        <Info2Icon fontSize={'small'} color={'inherit'} sx={{ marginX: 1 / 2 }} />\n                      </Trans>\n                    </Typography>\n                  </Tooltip>\n                  <Link\n                    onClick={() => {\n                      setShowEdit(true)\n                    }}\n                    component={'a'}\n                    variant={'body1'}\n                    display={'inline-flex'}\n                    alignItems={'center'}\n                  >\n                    {t('labelDayDisplay', { item: coinSell.renewDuration })}\n                    <BackIcon fontSize={'inherit'} sx={{ transform: 'rotate(180deg)' }} />\n                  </Link>\n                </Box>\n              </Box>\n            )}\n          </Box>\n        ) : (\n          <></>\n        )}\n        {displayMode === DualDisplayMode.beginnerModeStep2 && (\n          <Box paddingX={2} marginTop={2} order={isOrder ? 1 : 3}>\n            <Typography variant={'h5'} marginBottom={0}>\n              {t('labelDualBeginnerAtSettlementDay')}\n            </Typography>\n            <Typography color={'textSecondary'} marginBottom={1}>\n              {t('labelDualBeginnerIndexPriceDes')}\n            </Typography>\n            <Typography\n              textAlign={'center'}\n              color={'var(--color-text-third)'}\n              variant={'body2'}\n              paddingBottom={1}\n            >\n              {t('labelDualBeginnerLockingDes')}\n            </Typography>\n          </Box>\n        )}\n        {displayMode !== DualDisplayMode.beginnerModeStep1 && (\n          <>\n            <Box paddingBottom={1} order={isOrder ? 4 : 4}>\n              <Divider sx={{ borderWidth: 2, marginBottom: 2 }} />\n              <Box\n                display={'flex'}\n                flexDirection={'row'}\n                paddingX={2}\n                alignItems={'center'}\n                justifyContent={'space-between'}\n                paddingBottom={2}\n              >\n                <Typography\n                  variant={isMobile ? 'h5' : 'h5'}\n                  component={'span'}\n                  color={'textPrimary'}\n                >\n                  {t('labelDualSettlementCalculator')}\n                </Typography>\n                {/*<Typography component={'span'} variant={'body1'} color={'textSecondary'}>*/}\n                {/*  <Typography component={'span'} variant={'inherit'}>*/}\n                {/*    {t('labelDualCurrentPrice3', {*/}\n                {/*      symbol: base,*/}\n                {/*    })}*/}\n                {/*  </Typography>*/}\n                {/*  <Typography*/}\n                {/*    component={'span'}*/}\n                {/*    variant={'inherit'}*/}\n                {/*    paddingLeft={1 / 2}*/}\n                {/*    color={upColor == UpColor.green ? 'var(--color-error)' : 'var(--color-success)'}*/}\n                {/*  >*/}\n                {/*    {currentView + ' ' + quoteAlice}*/}\n                {/*  </Typography>*/}\n                {/*</Typography>*/}\n              </Box>\n              <Box\n                display={'flex'}\n                alignItems={'stretch'}\n                flexDirection={'column'}\n                paddingX={2}\n                justifyContent={'space-between'}\n                paddingBottom={2}\n              >\n                <Tabs\n                  className={'btnOutLineTab'}\n                  variant={'fullWidth'}\n                  value={tab}\n                  onChange={(_e, newVaule) => setTab(newVaule)}\n                  sx={{ marginBottom: 2 }}\n                >\n                  <Tab\n                    key={DualDetailTab.less}\n                    value={DualDetailTab.less}\n                    label={\n                      <Typography component={'span'} color={'inherit'}>\n                        {t(\n                          dualViewInfo.isUp\n                            ? 'labelDualNewPriceLessThan'\n                            : 'labelDualNewPriceLessOrEqualThan',\n                          {\n                            value: targetView,\n                            base: currentPrice.base,\n                            quote: quoteAlice,\n                          },\n                        )}\n                      </Typography>\n                    }\n                  />\n                  <Tab\n                    key={DualDetailTab.greater}\n                    value={DualDetailTab.greater}\n                    label={\n                      <Typography component={'span'} color={'inherit'}>\n                        {t(\n                          dualViewInfo.isUp\n                            ? 'labelDualNewPriceGreaterThanOrEqual'\n                            : 'labelDualNewPriceGreaterThan',\n                          {\n                            value: targetView,\n                            quote: quoteAlice,\n                            base: base,\n                          },\n                        )}\n                      </Typography>\n                    }\n                  />\n                </Tabs>\n                <BoxChartStyle\n                  className={`${isMobile ? 'mobile' : ''} dual${\n                    sdk.toBig(currentPrice.currentPrice ?? 0).gte(dualViewInfo.strike) ? 'H' : 'L'\n                  }${tab == DualDetailTab.greater ? 'H' : 'L'}`}\n                  // greater={}\n                  // isUp={}\n                  height={128}\n                  width={'100%'}\n                  position={'relative'}\n                >\n                  <Box className={'point1 point'}>\n                    {/*<Typography variant={'body2'} whiteSpace={'pre'} color={'textPrimary'}>*/}\n                    {/*  {t('labelDualTargetPrice3')}*/}\n                    {/*</Typography>*/}\n                    <Typography>{targetView + ' ' + quoteAlice}</Typography>\n                  </Box>\n                  <Box\n                    className={'point2 point'}\n                    whiteSpace={'pre'}\n                    sx={{\n                      top: 0,\n                      left: 0,\n                      // left: sdk\n                      //   .toBig(dualViewInfo.currentPrice?.currentPrice ?? 0)\n                      //   .minus(dualViewInfo.strike)\n                      //   .gte(0)\n                      //   ? '75%'\n                      //   : '25%',\n                    }}\n                  >\n                    <Typography\n                      display={'inline-block'}\n                      width={'120px'}\n                      whiteSpace={'pre-wrap'}\n                      // flexWrap={'wrap'}\n                      // variant={'body2'}\n                      color={'textPrimary'}\n                      component={'span'}\n                      // alignItems={'center'}\n                    >\n                      <Trans\n                        i18nKey={'labelDualCurrentPrice2'}\n                        tOptions={{\n                          price: ' ' + currentView,\n                          symbol: '', //base,\n                          baseSymbol: quoteAlice,\n                        }}\n                      >\n                        LRC Current price:\n                        <Typography\n                          component={'span'}\n                          color={\n                            upColor == UpColor.green ? 'var(--color-error)' : 'var(--color-success)'\n                          }\n                        >\n                          price\n                        </Typography>\n                      </Trans>\n                    </Typography>\n                  </Box>\n                  <Box className={'returnV1 returnV'}>\n                    <Typography variant={'body2'} color={'inherit'} whiteSpace={'pre-line'}>\n                      {quote &&\n                        t('labelDualReturn', {\n                          symbol:\n                            (greaterEarnView === '0' ? EmptyValueTag : greaterEarnView) +\n                            ' ' +\n                            quote,\n                        })}\n                    </Typography>\n                  </Box>\n                  <Box className={'returnV2 returnV'}>\n                    <Typography variant={'body2'} color={'inherit'} whiteSpace={'pre-line'}>\n                      {base &&\n                        t('labelDualReturn', {\n                          symbol:\n                            (lessEarnView === '0' ? EmptyValueTag : lessEarnView) + ' ' + base,\n                        })}\n                    </Typography>\n                  </Box>\n                  <Box className={'backView'}>\n                    <Box\n                      className={'line'}\n                      width={\n                        sdk\n                          .toBig(dualViewInfo.currentPrice?.currentPrice ?? 0)\n                          .minus(dualViewInfo.strike)\n                          .gte(0)\n                          ? '75%'\n                          : '25%'\n                      }\n                    />\n                  </Box>\n                </BoxChartStyle>\n              </Box>\n            </Box>\n          </>\n        )}\n      </Box>\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/DualWrap/dualWrap.tsx",
    "content": "import React from 'react'\nimport {\n  DualCalcData,\n  DualViewInfo,\n  EmptyValueTag,\n  getValuePrecisionThousand,\n  IBData,\n  L1L2_NAME_DEFINED,\n  MapChainId,\n  myLog,\n  TradeBtnStatus,\n} from '@loopring-web/common-resources'\nimport { DualDisplayMode, DualWrapProps } from './Interface'\nimport { useTranslation } from 'react-i18next'\nimport { Box, Grid, Typography } from '@mui/material'\nimport { useSettings } from '../../../../stores'\nimport { ButtonStyle } from '../Styled'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { DualDetail } from './dualDetail'\nimport { InputCoin, InputMaxCoin } from '../../../basic-lib'\nimport BigNumber from 'bignumber.js'\n\nexport const DualWrap = <\n  T extends IBData<I> & { isRenew: boolean; targetPrice: string; duration: string },\n  I,\n  DUAL extends DualCalcData<R>,\n  R extends DualViewInfo,\n>({\n  refreshRef,\n  disabled,\n  btnInfo,\n  isLoading,\n  onRefreshData,\n  onSubmitClick,\n  onChangeEvent,\n  tokenSellProps,\n  dualCalcData,\n  handleError,\n  tokenSell,\n  btnStatus,\n  tokenMap,\n  accStatus,\n  isBeginnerMode,\n  dualProducts,\n  toggle,\n  setShowAutoDefault,\n  showAutoDefault,\n  ...rest\n}: DualWrapProps<T, I, DUAL> & {\n  isBeginnerMode: boolean\n  // setConfirmDualAutoInvest: (state: boolean) => void\n}) => {\n  const coinSellRef = React.useRef()\n  const { t } = useTranslation()\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const priceSymbol = dualCalcData?.dualViewInfo?.currentPrice?.quote\n  const [displayMode, setDisplayMode] = React.useState<DualDisplayMode>(\n    isBeginnerMode ? DualDisplayMode.beginnerModeStep1 : DualDisplayMode.nonBeginnerMode,\n  )\n  const getDisabled = React.useMemo(() => {\n    return disabled || dualCalcData === undefined\n  }, [btnStatus, dualCalcData, disabled])\n\n  const handleCountChange = React.useCallback(\n    (ibData: T, _name: string, _ref: any) => {\n      if (dualCalcData['coinSell'].tradeValue !== ibData.tradeValue) {\n        myLog('dual handleCountChange', _name, ibData)\n\n        onChangeEvent({\n          tradeData: { ...dualCalcData?.coinSell, ...ibData },\n        })\n      }\n    },\n    [dualCalcData, onChangeEvent],\n  )\n\n  const propsSell = {\n    label: t('labelTokenEnterDualToken'),\n    subLabel: t('labelTokenMaxBalance'),\n    emptyText: t('tokenSelectToken'),\n    placeholderText: dualCalcData.miniSellVol\n      ? t('labelInvestMiniDual', {\n          value: getValuePrecisionThousand(\n            sdk.toBig(dualCalcData.miniSellVol).div('1e' + dualCalcData.sellToken?.decimals),\n            dualCalcData.sellToken?.precision,\n            dualCalcData.sellToken?.precision,\n            dualCalcData.sellToken?.precision,\n            false,\n            { floor: false, isAbbreviate: true },\n          ),\n        })\n      : '0.00',\n    maxAllow: true,\n    noBalance: EmptyValueTag,\n    name: 'coinSell',\n    isHideError: true,\n    order: 'left' as any,\n    decimalsLimit: tokenSell?.precision,\n    coinPrecision: tokenSell?.precision,\n    inputData: {\n      ...(dualCalcData ? dualCalcData.coinSell : ({} as any)),\n      max: BigNumber.min(\n        dualCalcData.maxSellAmount ?? 0,\n        dualCalcData?.coinSell?.balance ?? 0,\n        dualCalcData?.quota ?? 0,\n      ),\n    },\n    coinMap: {},\n    ...tokenSellProps,\n    handleError: handleError as any,\n    handleCountChange,\n    isShowCoinInfo: true,\n    isShowCoinIcon: true,\n    // CoinIconElement: tokenSell.symbol,\n    ...rest,\n  } as any\n  const label = React.useMemo(() => {\n    if (btnInfo?.label) {\n      const key = btnInfo?.label.split('|')\n      return t(\n        key[0],\n        key && key[1]\n          ? {\n              arg: key[1],\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n              l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n              l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n              ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n            }\n          : {\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n              l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n              l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n              ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n            },\n      )\n    } else {\n      return displayMode === DualDisplayMode.beginnerModeStep1\n        ? t('labelContinue', {\n            loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n            l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n            l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n            ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n          })\n        : t(`labelInvestBtn`, {\n            loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n            l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n            l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n            ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n          })\n    }\n  }, [t, btnInfo])\n  const lessEarnView = React.useMemo(\n    () =>\n      dualCalcData?.lessEarnVol && tokenMap[dualCalcData.lessEarnTokenSymbol]\n        ? getValuePrecisionThousand(\n            sdk\n              .toBig(dualCalcData?.lessEarnVol ?? 0)\n              .times(sdk.toBig(1).plus(dualCalcData!.dualViewInfo.settleRatio))\n              .div('1e' + tokenMap[dualCalcData.lessEarnTokenSymbol].decimals),\n            tokenMap[dualCalcData.lessEarnTokenSymbol].precision,\n            tokenMap[dualCalcData.lessEarnTokenSymbol].precision,\n            tokenMap[dualCalcData.lessEarnTokenSymbol].precision,\n            false,\n            { floor: true },\n          )\n        : EmptyValueTag,\n    [dualCalcData.lessEarnTokenSymbol, dualCalcData.lessEarnVol, tokenMap, dualCalcData!.dualViewInfo?.settleRatio],\n  )\n  const greaterEarnView = React.useMemo(\n    () =>\n      dualCalcData?.greaterEarnVol && tokenMap[dualCalcData.greaterEarnTokenSymbol]\n        ? getValuePrecisionThousand(\n            sdk\n              .toBig(dualCalcData?.greaterEarnVol)\n              .times(sdk.toBig(1).plus(dualCalcData!.dualViewInfo.settleRatio))\n              .div('1e' + tokenMap[dualCalcData.greaterEarnTokenSymbol].decimals),\n            tokenMap[dualCalcData.greaterEarnTokenSymbol].precision,\n            tokenMap[dualCalcData.greaterEarnTokenSymbol].precision,\n            tokenMap[dualCalcData.greaterEarnTokenSymbol].precision,\n            false,\n            { floor: true },\n          )\n        : EmptyValueTag,\n    [dualCalcData.greaterEarnTokenSymbol, dualCalcData.greaterEarnVol, tokenMap, dualCalcData.dualViewInfo?.settleRatio],\n  )\n\n  const totalQuota = React.useMemo(\n    () =>\n      dualCalcData.quota && dualCalcData.sellToken\n        ? getValuePrecisionThousand(\n            dualCalcData.quota,\n            dualCalcData.sellToken.precision,\n            dualCalcData.sellToken.precision,\n            dualCalcData.sellToken.precision,\n            false,\n            { floor: false, isAbbreviate: true },\n          )\n        : EmptyValueTag,\n    [dualCalcData],\n  )\n\n  // const renewDuration =\n  //   !dualCalcData?.coinSell?.renewDuration && dualCalcData?.dualViewInfo\n  //     ? calc < 1\n  //       ? Math.ceil(calc)\n  //       : Math.floor(calc)\n  //     : dualCalcData.coinSell?.renewDuration ?? 0\n\n  const inputView = displayMode !== DualDisplayMode.beginnerModeStep2 && (\n    <Grid\n      item\n      xs={12}\n      flexDirection={'column'}\n      alignItems={'stretch'}\n      justifyContent={'space-between'}\n      display={'flex'}\n    >\n      <Box\n        paddingX={2}\n        display={'flex'}\n        alignItems={'stretch'}\n        justifyContent={'space-between'}\n        flexDirection={'column'}\n      >\n        <InputCoin<any, I, any>\n          ref={coinSellRef}\n          disabled={getDisabled}\n          {...{\n            ...propsSell,\n          }}\n        />\n        <Typography\n          variant={'body1'}\n          display={'inline-flex'}\n          alignItems={'center'}\n          justifyContent={'space-between'}\n          paddingTop={1}\n          paddingBottom={2}\n        >\n          <Typography component={'span'} variant={'inherit'} color={'textSecondary'}>\n            {t('labelDualQuota')}\n          </Typography>\n          <Typography component={'span'} variant={'inherit'} color={'textPrimary'}>\n            {totalQuota + ' ' + dualCalcData.coinSell.belong}\n          </Typography>\n        </Typography>\n      </Box>\n    </Grid>\n  )\n\n  return (\n    <Grid\n      className={dualCalcData.dualViewInfo ? '' : 'loading'}\n      container\n      justifyContent={'space-between'}\n      alignItems={'stretch'}\n      flex={1}\n      height={'100%'}\n    >\n      {dualCalcData.dualViewInfo && priceSymbol && (\n        <>\n          <Grid\n            item\n            xs={12}\n            // order={isMobile ? 1 : 0}\n            flexDirection={'column'}\n            alignItems={'stretch'}\n            justifyContent={'space-between'}\n          >\n            <DualDetail\n              dualViewInfo={\n                {\n                  ...dualCalcData.dualViewInfo,\n                  ...dualCalcData?.dualViewInfo?.__raw__?.info,\n                  ...dualCalcData.coinSell,\n                } as any\n              }\n              coinSell={{\n                ...dualCalcData.coinSell,\n                renewTargetPrice: dualCalcData?.dualViewInfo?.__raw__?.info?.strike,\n              }}\n              setShowAutoDefault={setShowAutoDefault}\n              showAutoDefault={showAutoDefault}\n              currentPrice={dualCalcData.dualViewInfo.currentPrice}\n              lessEarnTokenSymbol={dualCalcData.lessEarnTokenSymbol}\n              greaterEarnTokenSymbol={dualCalcData.greaterEarnTokenSymbol}\n              lessEarnView={lessEarnView}\n              greaterEarnView={greaterEarnView}\n              displayMode={displayMode}\n              isPriceEditable={false}\n              dualProducts={dualProducts ?? []}\n              toggle={toggle}\n              inputPart={\n                displayMode !== DualDisplayMode.beginnerModeStep2 ? (\n                  <Box\n                    display={'flex'}\n                    alignItems={'stretch'}\n                    justifyContent={'space-between'}\n                    flexDirection={'column'}\n                    order={1}\n                    marginTop={2}\n                    marginBottom={1}\n                  >\n                    <Box paddingX={2}>\n                      <InputMaxCoin<any, I, any>\n                        ref={coinSellRef}\n                        disabled={getDisabled}\n                        {...{\n                          ...propsSell,\n                        }}\n                      />\n                    </Box>\n                    <Typography\n                      variant={'body1'}\n                      display={'inline-flex'}\n                      alignItems={'center'}\n                      paddingX={2}\n                      paddingBottom={1}\n                    >\n                      <Typography component={'span'} variant={'inherit'} color={'textSecondary'}>\n                        {t('labelDualQuota')}\n                      </Typography>\n                      <Typography\n                        component={'span'}\n                        variant={'inherit'}\n                        color={'textPrimary'}\n                        marginLeft={1 / 2}\n                      >\n                        {totalQuota + ' ' + dualCalcData.coinSell.belong}\n                      </Typography>\n                    </Typography>\n                  </Box>\n                ) : undefined\n              }\n              onChange={(data) => {\n                onChangeEvent({\n                  tradeData: {\n                    ...dualCalcData?.coinSell,\n                    isRenew: data.isRenew,\n                    renewTargetPrice: data.renewTargetPrice,\n                    renewDuration: data.renewDuration,\n                  } as any,\n                })\n              }}\n            />\n          </Grid>\n          <Grid item xs={12}>\n            <Box paddingX={2} marginY={2}>\n              <ButtonStyle\n                fullWidth\n                variant={'contained'}\n                size={'medium'}\n                color={'primary'}\n                onClick={() => {\n                  if (!btnInfo?.label && displayMode === DualDisplayMode.beginnerModeStep1) {\n                    setDisplayMode(DualDisplayMode.beginnerModeStep2)\n                  } else {\n                    onSubmitClick()\n                  }\n                }}\n                loading={!getDisabled && btnStatus === TradeBtnStatus.LOADING ? 'true' : 'false'}\n                disabled={\n                  getDisabled ||\n                  btnStatus === TradeBtnStatus.LOADING ||\n                  btnStatus === TradeBtnStatus.DISABLED\n                }\n              >\n                {label}\n              </ButtonStyle>\n            </Box>\n          </Grid>\n        </>\n      )}\n    </Grid>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/DualWrap/index.tsx",
    "content": "export * from './Interface'\nexport * from './dualWrap'\nexport * from './dualDetail'\nexport * from './ModifySetting'\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/ExportAccountWrap.tsx",
    "content": "import React from 'react'\nimport { WithTranslation } from 'react-i18next'\nimport { Box, Grid, TextareaAutosize, Typography } from '@mui/material'\nimport { Button } from '../../basic-lib'\nimport { ExportAccountExtendProps } from './Interface'\nimport styled from '@emotion/styled'\nimport { copyToClipBoard, NoPhotosIcon } from '@loopring-web/common-resources'\nimport { useSettings } from '../../../stores'\n\nconst TextareaAutosizeStyled = styled(TextareaAutosize)`\n  width: 100%;\n  padding: ${({ theme }: any) => theme.unit * 2}px;\n  color: var(--color-text-secondary);\n  background: var(--color-global-bg);\n` as any\n\nexport const ExportAccountWrap = ({\n  t,\n  setExportAccountToastOpen,\n  ...rest\n}: ExportAccountExtendProps & WithTranslation) => {\n  const [info, setInfo] = React.useState<any>()\n  const {\n    exportAccountProps: { accountInfo },\n  } = rest\n  const { isMobile } = useSettings()\n\n  React.useEffect(() => {\n    if (accountInfo) {\n      try {\n        const info = JSON.stringify(accountInfo, null, 4)\n        setInfo(info)\n      } finally {\n      }\n    }\n  }, [accountInfo])\n\n  return (\n    <Grid\n      container\n      paddingLeft={5 / 2}\n      paddingRight={5 / 2}\n      direction={'column'}\n      justifyContent={'space-between'}\n      alignItems={'center'}\n      flex={1}\n      height={'100%'}\n    >\n      <Grid item>\n        <Typography\n          component={'h4'}\n          textAlign={'center'}\n          variant={isMobile ? 'h4' : 'h3'}\n          whiteSpace={'pre'}\n          marginBottom={2}\n        >\n          {t('labelExportAccount')}\n        </Typography>\n\n        <Typography\n          variant={'body2'}\n          textAlign={'center'}\n          color={'var(--color-text-third)'}\n          marginBottom={2}\n        >\n          <NoPhotosIcon style={{ fontSize: 42 }} htmlColor={'var(--color-text-third)'} />\n          <Box>{t('labelExportAccountNoPhotos')}</Box>\n        </Typography>\n      </Grid>\n\n      <Grid item alignSelf={'stretch'} marginBottom={1} position={'relative'}>\n        <Typography component={'p'} variant='body1' color={'var(--color-text-third)'}>\n          {t('labelExportAccountDescription')}\n        </Typography>\n      </Grid>\n\n      <Grid item alignSelf={'stretch'} position={'relative'}>\n        <TextareaAutosizeStyled disabled maxRows={15} defaultValue={info} />\n      </Grid>\n\n      <Grid item marginTop={2} alignSelf={'stretch'}>\n        <Button\n          fullWidth\n          variant={'contained'}\n          size={'medium'}\n          color={'primary'}\n          onClick={() => {\n            copyToClipBoard(info)\n            setExportAccountToastOpen(true)\n          }}\n        >\n          {t(`labelExportAccountCopy`)}\n        </Button>\n      </Grid>\n    </Grid>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/ForceWithdrawConfirm.tsx",
    "content": "import { WithTranslation } from 'react-i18next'\nimport { Box, Grid, ListItem, ListItemText, Typography } from '@mui/material'\nimport {\n  FeeInfo,\n  IBData,\n  L1L2_NAME_DEFINED,\n  MapChainId,\n  TOAST_TIME,\n} from '@loopring-web/common-resources'\nimport { Button, ForceWithdrawViewProps, Toast, ToastType } from '../../index'\nimport { useSettings } from '../../../stores'\nimport React from 'react'\nimport { ListStyle } from './ForceWithdrawWrap'\n\nexport const ForceWithdrawConfirm = <T extends IBData<I>, I, C extends FeeInfo>({\n  t,\n  handleConfirm,\n  tradeData,\n  realAddr,\n  onWithdrawClick,\n  feeInfo,\n}: Partial<ForceWithdrawViewProps<T, I, C>> & {\n  handleConfirm: (index: number) => void\n} & WithTranslation) => {\n  const { isMobile, defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const [open, setOpen] = React.useState(false)\n  return (\n    <Grid\n      className={'confirm'}\n      container\n      paddingLeft={isMobile ? 2 : 5 / 2}\n      paddingRight={isMobile ? 2 : 5 / 2}\n      direction={'column'}\n      alignItems={'stretch'}\n      flex={1}\n      height={'100%'}\n      minWidth={240}\n      flexWrap={'nowrap'}\n      spacing={2}\n      width={'100%'}\n    >\n      <Grid item xs={12}>\n        <Box\n          display={'flex'}\n          flexDirection={'column'}\n          justifyContent={'center'}\n          alignItems={'center'}\n          marginBottom={2}\n        >\n          <Typography\n            component={'h4'}\n            variant={isMobile ? 'h4' : 'h3'}\n            whiteSpace={'pre'}\n            marginRight={1}\n          >\n            {t('labelForceWithdrawTitle')}\n          </Typography>\n        </Box>\n      </Grid>\n      <Grid item xs={12}>\n        <Typography color={'var(--color-text-third)'} variant={'body1'}>\n          {t('labelForceWithdrawAddress')}\n        </Typography>\n        <Typography color={'textPrimary'} marginTop={1} variant={'body1'}>\n          {realAddr}\n        </Typography>\n      </Grid>\n\n      <Grid item xs={12}>\n        <Typography color={'var(--color-text-third)'} variant={'body1'}>\n          {t('labelForceWithdrawToken')}\n        </Typography>\n        <Typography color={'textPrimary'} marginTop={1} variant={'body1'}>\n          {tradeData?.balance + ' ' + tradeData?.belong}\n        </Typography>\n      </Grid>\n      <Grid item xs={12}>\n        <Typography color={'var(--color-text-third)'} variant={'body1'}>\n          {t('labelForceWithdrawFee')}\n        </Typography>\n        <Typography color={'textPrimary'} marginTop={1} variant={'body1'}>\n          {feeInfo?.fee + ' '} {feeInfo?.belong}\n        </Typography>\n      </Grid>\n\n      <Grid item alignSelf={'stretch'} position={'relative'}>\n        <Typography display={'inline-flex'}>\n          <ListStyle>\n            <ListItem>\n              <ListItemText>\n                {t('labelForceWithdrawConfirm', {\n                  l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                  loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                  l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                  l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                  ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                })}\n              </ListItemText>\n            </ListItem>\n            <ListItem>\n              <ListItemText>\n                {t('labelForceWithdrawConfirm1', {\n                  l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                  loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                  l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                  l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                  ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                })}\n              </ListItemText>\n            </ListItem>\n          </ListStyle>\n        </Typography>\n      </Grid>\n\n      <Grid item marginTop={2} alignSelf={'stretch'} paddingBottom={0}>\n        <Button\n          fullWidth\n          variant={'contained'}\n          size={'medium'}\n          color={'primary'}\n          onClick={async () => {\n            if (onWithdrawClick) {\n              await onWithdrawClick({ ...tradeData } as unknown as T)\n            } else {\n              setOpen(true)\n            }\n            handleConfirm(1)\n          }}\n        >\n          {t('labelConfirm')}\n        </Button>\n      </Grid>\n      <Toast\n        alertText={t('errorBase', { ns: 'error' })}\n        open={open}\n        autoHideDuration={TOAST_TIME}\n        onClose={() => {\n          setOpen(false)\n        }}\n        severity={ToastType.error}\n      />\n    </Grid>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/ForceWithdrawWrap.tsx",
    "content": "import { Trans, WithTranslation } from 'react-i18next'\nimport React from 'react'\nimport { bindHover } from 'material-ui-popup-state/es'\nimport { bindPopper, usePopupState } from 'material-ui-popup-state/hooks'\nimport { Box, Grid, List, ListItem, ListItemText, Typography } from '@mui/material'\nimport {\n  AssetsRawDataItem,\n  CloseIcon,\n  DropDownIcon,\n  FeeInfo,\n  globalSetup,\n  IBData,\n  Info2Icon,\n  L1L2_NAME_DEFINED,\n  LoadingIcon,\n  MapChainId,\n  TRADE_TYPE,\n  TradeBtnStatus,\n} from '@loopring-web/common-resources'\nimport { FeeSelect, ForceWithdrawViewProps, InputButtonDefaultProps, PopoverPure } from '../..'\nimport { Button, IconClearStyled, TextField, useSettings } from '../../../index'\nimport { BasicACoinTrade } from './BasicACoinTrade'\nimport styled from '@emotion/styled'\n\nexport const ListStyle = styled(List)`\n  li {\n    height: auto;\n    padding: 0;\n\n    &:before {\n      content: '•';\n      padding-top: ${({ theme }) => theme.unit}px;\n      color: var(--color-warning);\n      display: inline-flex;\n      padding-right: ${({ theme }) => theme.unit}px;\n    }\n\n    display: inline-flex;\n\n    &:hover {\n      background-color: initial;\n    }\n  }\n\n  //list-style: disc outside;\n  //list-style: ;\n  .MuiListItemText-root span {\n    color: var(--color-warning);\n    line-height: 1.2em;\n    padding-bottom: 0;\n  }\n\n  font-size: ${({ theme }) => theme.fontDefault.body1};\n` as typeof List\nexport const ForceWithdrawWrap = <T extends IBData<I>, I, C extends FeeInfo>({\n  t,\n  disabled,\n  walletMap,\n  tradeData,\n  coinMap,\n  withdrawI18nKey,\n  addressDefault,\n  isNotAvailableAddress,\n  isActiveAccount,\n  isLoopringAddress = false,\n  chargeFeeTokenList = [],\n  feeInfo,\n  lastFailed,\n  // handleConfirm,\n  isFeeNotEnough,\n  onWithdrawClick,\n  withdrawBtnStatus,\n  handleFeeChange,\n  handleOnAddressChange,\n  isAddressCheckLoading,\n  addrStatus,\n  realAddr,\n  wait = globalSetup.wait,\n  assetsData = [],\n  ...rest\n}: ForceWithdrawViewProps<T, I, C> &\n  WithTranslation & {\n    assetsData: AssetsRawDataItem[]\n    // handleConfirm: (index: number) => void;\n  }) => {\n  const { isMobile, defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const [showFeeModal, setShowFeeModal] = React.useState(false)\n  const popupState = usePopupState({\n    variant: 'popover',\n    popupId: `popupId-withdraw`,\n  })\n\n  const inputBtnRef = React.useRef()\n\n  const getDisabled = React.useMemo(() => {\n    return disabled || withdrawBtnStatus === TradeBtnStatus.DISABLED\n  }, [disabled, withdrawBtnStatus])\n  const inputButtonDefaultProps: InputButtonDefaultProps<T, I> = {\n    label: t('labelForceWithdrawEnterToken'),\n    disableInputValue: true,\n    maxAllow: false,\n    disabled: !Object.keys(walletMap ?? {}).length,\n    subLabel: '',\n  }\n\n  const handleToggleChange = (value: C) => {\n    if (handleFeeChange) {\n      handleFeeChange(value)\n    }\n  }\n  // @ts-ignore\n  return (\n    <Grid\n      className={walletMap ? '' : 'loading'}\n      container\n      paddingLeft={5 / 2}\n      paddingRight={5 / 2}\n      direction={'column'}\n      justifyContent={'space-between'}\n      alignItems={'center'}\n      flex={1}\n      minWidth={240}\n      height={'100%'}\n      flexWrap={'nowrap'}\n      spacing={2}\n    >\n      <Grid item>\n        <Box\n          display={'flex'}\n          flexDirection={'row'}\n          justifyContent={'center'}\n          alignItems={'center'} /* marginBottom={2} */\n        >\n          <Typography\n            component={'h4'}\n            variant={isMobile ? 'h4' : 'h3'}\n            whiteSpace={'pre'}\n            marginRight={1}\n          >\n            {t('labelForceWithdrawTitle')}\n          </Typography>\n          <Info2Icon\n            {...bindHover(popupState)}\n            fontSize={'large'}\n            htmlColor={'var(--color-text-third)'}\n          />\n        </Box>\n        <PopoverPure\n          className={'arrow-center'}\n          {...bindPopper(popupState)}\n          anchorOrigin={{\n            vertical: 'bottom',\n            horizontal: 'center',\n          }}\n          transformOrigin={{\n            vertical: 'top',\n            horizontal: 'center',\n          }}\n        >\n          <Typography padding={2} maxWidth={490} variant={'body2'} whiteSpace={'pre-line'}>\n            <Trans\n              i18nKey='labelForceWithdrawDes'\n              tOptions={{\n                l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n              }}\n            >\n              If the receipt account doesn't activate the Loopring L2 account, you will be able to\n              withdraw the token from L2 to Ethereum L1. Usually only when you sent the token to the\n              L2 account of a wrong Btrade address that doesn't support Loopring L2, you will need\n              to do this so that you will be able to claim the token back.\n            </Trans>\n          </Typography>\n        </PopoverPure>\n      </Grid>\n      <Grid item alignSelf={'stretch'} position={'relative'}>\n        <Typography display={'inline-flex'}>\n          <ListStyle>\n            <ListItem>\n              <ListItemText>\n                {t('labelForceWithdrawConfirm', {\n                  l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                  loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                  l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                  l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                  ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                })}\n              </ListItemText>\n            </ListItem>\n            <ListItem>\n              <ListItemText>\n                {t('labelForceWithdrawConfirm1', {\n                  l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                  loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                  l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                  l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                  ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                })}\n              </ListItemText>\n            </ListItem>\n          </ListStyle>\n        </Typography>\n      </Grid>\n      <Grid item alignSelf={'stretch'} position={'relative'}>\n        <>\n          <TextField\n            className={'text-address'}\n            value={addressDefault}\n            error={\n              realAddr !== '' &&\n              isNotAvailableAddress &&\n              (walletMap !== undefined || Reflect.ownKeys(walletMap ?? {})?.length > 0)\n            }\n            placeholder={t('labelPleaseForceWithdrawAddress')}\n            onChange={(event) => handleOnAddressChange(event?.target?.value)}\n            label={t('labelForceWithdrawAddress')}\n            SelectProps={{ IconComponent: DropDownIcon }}\n            fullWidth={true}\n          />\n\n          {addressDefault !== '' ? (\n            isAddressCheckLoading ? (\n              <LoadingIcon width={24} style={{ top: 48, right: '8px', position: 'absolute' }} />\n            ) : (\n              <IconClearStyled\n                color={'inherit'}\n                size={'small'}\n                style={{ top: 46 }}\n                aria-label='Clear'\n                onClick={() => handleOnAddressChange('')}\n              >\n                <CloseIcon />\n              </IconClearStyled>\n            )\n          ) : (\n            ''\n          )}\n          {addressDefault !== '' &&\n            !isAddressCheckLoading &&\n            (walletMap === undefined || !Object.keys(walletMap).length) &&\n            (isNotAvailableAddress && realAddr === '' ? (\n              <Typography\n                color={'var(--color-error)'}\n                variant={'body2'}\n                marginTop={1 / 4}\n                alignSelf={'stretch'}\n                position={'relative'}\n              >\n                {t('labelInvalidAddress')}\n              </Typography>\n            ) : isLoopringAddress && isActiveAccount ? (\n              <Typography\n                color={'var(--color-error)'}\n                variant={'body2'}\n                marginTop={1 / 4}\n                alignSelf={'stretch'}\n                position={'relative'}\n              >\n                {t('labelForceWithdrawNotAvailable', {\n                  l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                  loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                  l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                  l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                  ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                })}\n              </Typography>\n            ) : (\n              <Typography\n                color={'var(--color-error)'}\n                variant={'body2'}\n                marginTop={1 / 4}\n                alignSelf={'stretch'}\n                position={'relative'}\n              >\n                {t('labelForceWithdrawNoToken')}\n              </Typography>\n            ))}\n        </>\n      </Grid>\n\n      {!isAddressCheckLoading &&\n        !isNotAvailableAddress &&\n        walletMap !== undefined &&\n        !!Object.keys(walletMap).length && (\n          <Grid item alignSelf={'stretch'} position={'relative'}>\n            {\n              // @ts-ignore\n              <BasicACoinTrade\n                {...{\n                  ...rest,\n                  type: TRADE_TYPE.TOKEN,\n                  t,\n                  walletMap,\n                  tradeData: {\n                    ...tradeData,\n                    tradeValue: tradeData.balance,\n                  },\n                  coinMap,\n                  inputButtonDefaultProps,\n                  inputBtnRef: inputBtnRef,\n                }}\n              />\n            }\n          </Grid>\n        )}\n\n      <Grid item alignSelf={'stretch'} position={'relative'}>\n        {!chargeFeeTokenList?.length ? (\n          <Typography>{t('labelFeeCalculating')}</Typography>\n        ) : (\n          <>\n            <FeeSelect\n              chargeFeeTokenList={chargeFeeTokenList}\n              handleToggleChange={(fee: FeeInfo) => {\n                handleToggleChange(fee as C)\n                setShowFeeModal(false)\n              }}\n              feeInfo={feeInfo as FeeInfo}\n              open={showFeeModal}\n              onClose={() => {\n                setShowFeeModal(false)\n              }}\n              isFeeNotEnough={isFeeNotEnough.isFeeNotEnough}\n              feeLoading={isFeeNotEnough.isOnLoading}\n              onClickFee={() => setShowFeeModal((prev) => !prev)}\n            />\n          </>\n        )}\n      </Grid>\n\n      <Grid item alignSelf={'stretch'} paddingBottom={0}>\n        {lastFailed && (\n          <Typography paddingBottom={1} textAlign={'center'} color={'var(--color-warning)'}>\n            {t('labelConfirmAgainByFailed', {\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n              l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n              l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n              ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n            })}\n          </Typography>\n        )}\n        <Button\n          fullWidth\n          variant={'contained'}\n          size={'medium'}\n          color={'primary'}\n          onClick={() => {\n            // handleConfirm(0);\n            onWithdrawClick({ ...tradeData } as unknown as T)\n          }}\n          loading={withdrawBtnStatus === TradeBtnStatus.LOADING && !getDisabled ? 'true' : 'false'}\n          disabled={getDisabled || withdrawBtnStatus === TradeBtnStatus.LOADING}\n        >\n          {t(withdrawI18nKey ?? 'labelForceWithdrawBtn')}\n        </Button>\n      </Grid>\n    </Grid>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/ImportCollectionWrap.tsx",
    "content": "import { ImportCollectionStep, ImportCollectionViewProps } from './Interface'\nimport { Trans, useTranslation } from 'react-i18next'\nimport React from 'react'\nimport { Box, Link, ListItemText, Typography } from '@mui/material'\nimport {\n  AddIcon,\n  BackIcon,\n  CollectionMeta,\n  DropDownIcon,\n  getShortAddr,\n  NFTWholeINFO,\n  SoursURL,\n  ViewMoreIcon,\n  RouterPath,\n  NFTSubRouter,\n} from '@loopring-web/common-resources'\nimport { Button, CollectionInput, EmptyDefault, MenuItem, TextField } from '../../basic-lib'\nimport styled from '@emotion/styled'\nimport { useSettings } from '../../../stores'\nimport { CollectionManageWrap } from './CollectionManageWrap'\nimport { NFTMedia } from '../../block'\nimport { useHistory } from 'react-router-dom'\nimport { BtnMain, HorizontalLabelPositionBelowStepper } from './tool'\n\nconst MintAdStyle = styled(Box)`\n  .MuiFormGroup-root {\n    align-items: flex-start;\n  }\n\n  .coinInput-wrap {\n    border: 1px solid var(--color-border);\n  }\n\n  .MuiInputLabel-root {\n    font-size: ${({ theme }) => theme.fontDefault.body2};\n  }\n\n  .MuiButtonBase-root.step {\n    padding-left: ${({ theme }) => theme.unit * 4}px;\n    padding-right: ${({ theme }) => theme.unit * 4}px;\n  }\n`\n\nconst steps = [\n  'labelImportCollection1', //Prepare NFT metadata\n  'labelImportCollection2', //labelADMint2\n  'labelImportCollection3', //Preview & Mint NFT\n]\n\nexport const ImportCollectionWrap = <Co extends CollectionMeta, NFT extends Partial<NFTWholeINFO>>({\n  onContractChange,\n  onContractNext,\n  setStep,\n  onCollectionChange,\n  onCollectionNext,\n  onNFTSelected,\n  onNFTSelectedMethod,\n  step,\n  data,\n  baseURL,\n  getIPFSString,\n  disabled,\n  onLoading,\n}: ImportCollectionViewProps<Co, NFT>) => {\n  const { t } = useTranslation(['common'])\n  const { isMobile } = useSettings()\n  const history = useHistory()\n  const {\n    contractList,\n    selectContract,\n    collectionInputProps,\n    selectCollection,\n    nftProps,\n    selectNFTList,\n  } = data\n  // myLog(\"ImportCollectionWrap\", contractList);\n\n  const panelList: Array<{\n    view: JSX.Element\n    onBack?: undefined | (() => void)\n    height?: any\n    width?: any\n  }> = React.useMemo(() => {\n    return [\n      {\n        view: (\n          <Box\n            marginTop={3}\n            display={'flex'}\n            justifyContent={'space-around'}\n            flexDirection={'column'}\n            alignItems={'stretch'}\n            width={'100%'}\n            maxWidth={'760px'}\n            flex={1}\n          >\n            <Box\n              display={'flex'}\n              alignItems={'flex-start'}\n              flexDirection={'column'}\n              justifyContent={'stretch'}\n            >\n              <TextField\n                id='ContractAddress'\n                select\n                label={t('labelSelectContractAddress')}\n                value={selectContract?.value ?? ''}\n                onChange={(event: React.ChangeEvent<any>) => {\n                  onContractChange(event.target?.value)\n                }}\n                inputProps={{ IconComponent: DropDownIcon }}\n                fullWidth={true}\n              >\n                {contractList.map((item, index) => {\n                  return (\n                    <MenuItem\n                      key={item.toString() + index}\n                      value={item}\n                      selected={item === selectContract?.value ?? \"'\"}\n                      withnocheckicon={'true'}\n                    >\n                      <ListItemText\n                        primary={\n                          <Typography\n                            sx={{ display: 'inline' }}\n                            component='span'\n                            variant='body1'\n                            color='text.primary'\n                          >\n                            {getShortAddr(item)}\n                          </Typography>\n                        }\n                      />\n                    </MenuItem>\n                  )\n                })}\n              </TextField>\n              {selectContract && (\n                <Box\n                  display={'flex'}\n                  flexDirection={'row'}\n                  marginTop={2}\n                  width={'100%'}\n                  justifyContent={'center'}\n                >\n                  {!onLoading ? (\n                    selectContract.total ? (\n                      <>\n                        {selectContract?.list?.map((item, index) => {\n                          return (\n                            <Box\n                              key={item?.tokenId + index.toString()}\n                              marginRight={2}\n                              width={60}\n                              height={60}\n                              borderRadius={1}\n                              display={'flex'}\n                              overflow={'hidden'}\n                            >\n                              <NFTMedia\n                                item={item as NFT}\n                                index={index}\n                                shouldPlay={false}\n                                onNFTError={() => undefined}\n                                isOrigin={false}\n                                getIPFSString={getIPFSString}\n                                baseURL={baseURL}\n                              />\n                            </Box>\n                          )\n                        })}\n                        {selectContract.total > 3 && (\n                          <Box\n                            marginRight={2}\n                            width={60}\n                            height={60}\n                            borderRadius={1}\n                            display={'flex'}\n                            overflow={'hidden'}\n                            alignItems={'center'}\n                            justifyContent={'center'}\n                            border={'1px var(--color-border-disable) solid'}\n                          >\n                            <ViewMoreIcon\n                              fontSize={'large'}\n                              htmlColor={'var(--color-text-secondary)'}\n                            />\n                          </Box>\n                        )}\n                      </>\n                    ) : (\n                      <Box flex={1} alignItems={'center'}>\n                        <EmptyDefault\n                          message={() => (\n                            <Box\n                              flex={1}\n                              display={'flex'}\n                              alignItems={'center'}\n                              justifyContent={'center'}\n                            >\n                              No NFT\n                            </Box>\n                          )}\n                        />\n                      </Box>\n                    )\n                  ) : (\n                    <Box\n                      flex={1}\n                      display={'flex'}\n                      alignItems={'center'}\n                      height={'90%'}\n                      width={'100%'}\n                      justifyContent={'center'}\n                    >\n                      <img\n                        className='loading-gif'\n                        alt={'loading'}\n                        width='36'\n                        src={`${SoursURL}images/loading-line.gif`}\n                      />\n                    </Box>\n                  )}\n                </Box>\n              )}\n            </Box>\n            <Box\n              width={'100%'}\n              paddingX={isMobile ? 2 : 0}\n              marginTop={2}\n              flexDirection={'row'}\n              display={'flex'}\n              justifyContent={'space-between'}\n            >\n              <BtnMain\n                {...{\n                  defaultLabel: 'labelContinue',\n                  fullWidth: true,\n                  disabled: () => {\n                    return disabled || !selectContract || !selectContract?.total\n                  },\n                  onClick: () => {\n                    setStep(ImportCollectionStep.SELECTCOLLECTION)\n                    onContractNext(selectContract?.value ?? '')\n                  },\n                }}\n              />\n            </Box>\n          </Box>\n        ),\n        // onBack: () => setStep(CreateCollectionStep.ChooseMethod)\n      },\n      {\n        view: (\n          <Box\n            marginTop={3}\n            display={'flex'}\n            justifyContent={'flex-start'}\n            flexDirection={'column'}\n            alignItems={'flex-start'}\n            width={'100%'}\n            maxWidth={'760px'}\n          >\n            <Typography\n              variant={'body1'}\n              color={'textSecondary'}\n              marginBottom={2}\n              textAlign={'center'}\n              whiteSpace={'pre-line'}\n            >\n              {t('labelImportChooseCollection')}\n            </Typography>\n\n            {onLoading ? (\n              <Box\n                flex={1}\n                display={'flex'}\n                alignItems={'center'}\n                height={'90%'}\n                width={'100%'}\n                justifyContent={'center'}\n              >\n                <img\n                  className='loading-gif'\n                  alt={'loading'}\n                  width='36'\n                  src={`${SoursURL}images/loading-line.gif`}\n                />\n              </Box>\n            ) : collectionInputProps?.collectionListProps?.total > 0 ? (\n              <>\n                <Box\n                  width={'100%'}\n                  paddingTop={2}\n                  paddingX={isMobile ? 2 : 0}\n                  alignItems={'center'}\n                >\n                  <CollectionInput\n                    {...{\n                      ...(collectionInputProps as any),\n                      collection: selectCollection,\n\n                      onSelected: (item: Co) => {\n                        collectionInputProps?.onSelected && collectionInputProps.onSelected(item)\n                        onCollectionChange(item)\n                      },\n                    }}\n                    fullWidth={true}\n                    collectionListProps={{\n                      ...collectionInputProps.collectionListProps,\n                      size: 'small',\n                    }}\n                    size={isMobile ? 'small' : 'large'}\n                    showCopy={true}\n                  />\n                  <Typography component={'p'} variant={'body1'} marginTop={1}>\n                    <Trans i18nKey={'labelORCreateCollection'}>\n                      or\n                      <Link\n                        href={`/#${RouterPath.nft}/${NFTSubRouter.addLegacyCollection}/${selectContract?.value}`}\n                        variant={'body1'}\n                        target={'_self'}\n                      >\n                        Create Collection\n                      </Link>\n                    </Trans>\n                  </Typography>\n                </Box>\n                <Box\n                  width={'100%'}\n                  paddingX={isMobile ? 2 : 0}\n                  marginTop={2}\n                  flexDirection={'row'}\n                  display={'flex'}\n                  justifyContent={'space-between'}\n                >\n                  <Button\n                    variant={'outlined'}\n                    size={'medium'}\n                    color={'primary'}\n                    className={'step'}\n                    sx={{ height: 'var(--btn-medium-height)' }}\n                    startIcon={<BackIcon fontSize={'small'} />}\n                    onClick={() => {\n                      onCollectionChange(undefined)\n                      setStep(ImportCollectionStep.SELECTCONTRACT)\n                    }}\n                  >\n                    {t(`labelMintBack`)}\n                  </Button>\n\n                  <BtnMain\n                    {...{\n                      defaultLabel: 'labelMintNext',\n                      btnInfo: undefined, //btnInfo,\n                      disabled: () => {\n                        return disabled || !selectCollection\n                      },\n                      onClick: () => {\n                        setStep(ImportCollectionStep.SELECTNFT)\n                        selectCollection && onCollectionNext(selectCollection)\n                      },\n                    }}\n                  />\n                </Box>\n              </>\n            ) : (\n              <>\n                <Box\n                  width={'100%'}\n                  paddingX={isMobile ? 2 : 0}\n                  marginTop={2}\n                  flexDirection={'row'}\n                  display={'flex'}\n                  justifyContent={'space-between'}\n                >\n                  <Button\n                    variant={'outlined'}\n                    size={'medium'}\n                    color={'primary'}\n                    className={'step'}\n                    sx={{ height: 'var(--btn-medium-height)' }}\n                    startIcon={<BackIcon fontSize={'small'} />}\n                    onClick={() => {\n                      onCollectionChange(undefined)\n                      setStep(ImportCollectionStep.SELECTCONTRACT)\n                    }}\n                  >\n                    {t(`labelMintBack`)}\n                  </Button>\n                  <Button\n                    variant={'contained'}\n                    size={'medium'}\n                    sx={{ height: 'var(--btn-medium-height)', marginLeft: 2 }}\n                    color={'primary'}\n                    className={'step'}\n                    fullWidth={true}\n                    startIcon={<AddIcon fontSize={'large'} />}\n                    href={`/#${RouterPath.nft}/${NFTSubRouter.addLegacyCollection}/${selectContract?.value}`}\n                  >\n                    {t(`labelCreateLegacyCollection`)}\n                  </Button>\n                </Box>\n              </>\n            )}\n          </Box>\n        ),\n      },\n      {\n        view: (\n          <Box\n            marginTop={3}\n            display={'flex'}\n            justifyContent={'flex-start'}\n            flexDirection={'column'}\n            alignItems={'stretch'}\n            width={'100%'}\n            // maxWidth={\"760px\"}\n          >\n            {selectCollection && (\n              <CollectionManageWrap\n                baseURL={baseURL}\n                getIPFSString={getIPFSString}\n                collection={selectCollection}\n                selectedNFTS={selectNFTList}\n                onNFTSelected={onNFTSelected as any}\n                onNFTSelectedMethod={onNFTSelectedMethod}\n                {...nftProps}\n              />\n            )}\n            <Box\n              width={'100%'}\n              paddingX={isMobile ? 2 : 0}\n              marginTop={2}\n              flexDirection={'row'}\n              display={'flex'}\n              justifyContent={'space-between'}\n            >\n              <Button\n                className={'step'}\n                startIcon={<BackIcon fontSize={'small'} />}\n                sx={{ height: 'var(--btn-medium-height)' }}\n                variant={'outlined'}\n                size={'medium'}\n                color={'primary'}\n                onClick={() => {\n                  setStep(ImportCollectionStep.SELECTCOLLECTION)\n                  selectCollection && onCollectionChange(undefined)\n                }}\n              >\n                {t(`labelMintBack`)}\n              </Button>\n              <BtnMain\n                {...{\n                  defaultLabel: t('labelDoneBtn'),\n                  btnInfo: undefined,\n                  disabled: () => {\n                    return disabled || !selectCollection\n                  },\n                  onClick: () => {\n                    history.push(`${RouterPath.nft}/${NFTSubRouter.myCollection}`)\n                  },\n                }}\n              />\n            </Box>\n          </Box>\n        ),\n      },\n    ]\n  }, [\n    t,\n    selectContract,\n    contractList,\n    onLoading,\n    isMobile,\n    collectionInputProps,\n    selectCollection,\n    baseURL,\n    selectNFTList,\n    onNFTSelected,\n    onNFTSelectedMethod,\n    nftProps,\n    onContractChange,\n    disabled,\n    setStep,\n    onContractNext,\n    onCollectionChange,\n    onCollectionNext,\n  ])\n\n  // @ts-ignore\n  return (\n    <Box\n      // className={walletMap ? \"\" : \"loading\"}\n      display={'flex'}\n      flex={1}\n      flexDirection={'column'}\n      padding={5 / 2}\n      alignItems={'center'}\n    >\n      <HorizontalLabelPositionBelowStepper activeStep={step} steps={steps} />\n      <MintAdStyle\n        flex={1}\n        marginTop={2}\n        paddingX={isMobile ? 2 : 5}\n        display={'flex'}\n        justifyContent={'center'}\n        alignItems={'stretch'}\n        width={'100%'}\n      >\n        {panelList.map((panel, index) => {\n          return <React.Fragment key={index}>{step === index ? panel.view : <></>}</React.Fragment>\n        })}\n      </MintAdStyle>\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/ImportRedPacketWrap.tsx",
    "content": "import { Trans } from 'react-i18next'\nimport { Box, Typography } from '@mui/material'\nimport { QRCodeUpload } from '../../basic-lib/panel/QRCodeUpload'\nimport React from 'react'\n\nexport const ImportRedPacketWrap = React.forwardRef(({}, _ref: React.ForwardedRef<any>) => {\n  // @ts-ignore\n  return (\n    <Box\n      // className={walletMap ? \"\" : \"loading\"}\n      display={'flex'}\n      flex={1}\n      flexDirection={'column'}\n      padding={5 / 2}\n      alignItems={'stretch'}\n    >\n      <Typography\n        component={'p'}\n        variant={'h5'}\n        display={'inline-flex'}\n        color={'var(--color-text-secondary)'}\n        marginBottom={1}\n        textAlign={'center'}\n        justifyContent={'center'}\n      >\n        <Trans i18nKey={'labelImportRedPacket'}>Import QR code to receive red packet</Trans>\n      </Typography>\n      <Box display={'flex'} flex={1}>\n        <QRCodeUpload ref={_ref} />\n      </Box>\n    </Box>\n  )\n})\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/Interface.ts",
    "content": "import {\n  BtnInfo,\n  BtnInfoProps,\n  InputButtonProps,\n  InputCoinProps,\n  IpfsFile,\n  SwitchPanelProps,\n} from '../../basic-lib'\nimport React, { ChangeEvent } from 'react'\nimport { XOR } from '../../../types/lib'\nimport { CollectionInputProps } from './tool'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { TOSTOBJECT } from '../../toast'\nimport {\n  Account,\n  AccountStatus,\n  AddressError,\n  AssetsRawDataItem,\n  BanxaOrder,\n  CLAIM_TYPE,\n  CoinInfo,\n  CoinKey,\n  CoinMap,\n  EXCHANGE_TYPE,\n  FeeInfo,\n  GET_IPFS_STRING,\n  LuckyRedPacketItem,\n  NFTWholeINFO,\n  RedPacketOrderType,\n  RequireOne,\n  TRADE_TYPE,\n  TradeBtnStatus,\n  WALLET_TYPE,\n  WalletCoin,\n  WalletMap,\n  WithdrawType,\n  WithdrawTypes,\n  ContactType,\n  RedPacketConfig,\n  TokenType,\n} from '@loopring-web/common-resources'\n\nexport enum RedPacketStep {\n  TradeType = 0,\n  ChooseType = 1,\n  Main = 2,\n  NFTList = 3,\n}\nexport enum TargetRedPacketStep {\n  TargetChosse = 0,\n  TradeType = 1,\n  ChooseType = 2,\n  Main = 3,\n  NFTList = 4,\n  TargetSend = 5,\n}\n\n/**\n * private props\n */\nexport type TradeMenuListProps<T, I> = {\n  nonZero: boolean\n  sorted: boolean\n  walletMap: WalletMap<I, WalletCoin<I>>\n  _height?: string | number\n  coinMap: CoinMap<I, CoinInfo<I>>\n  onChangeEvent: (index: 0 | 1, data: SwitchData<T>) => void\n  selected?: string\n  tradeData: T\n  tokenType?: TokenType\n  className?: string\n  hasCancel?: boolean\n  contentEle?: ({ ele }: { ele: any }) => JSX.Element\n  filterWithBorrowed?: boolean\n}\n\n/**\n * private props\n */\nexport type SwitchData<T> = {\n  to: 'menu' | 'button'\n  tradeData: T\n}\n\nexport type TransferInfoProps<C> = {\n  transferI18nKey?: string\n  transferBtnStatus?: keyof typeof TradeBtnStatus | undefined\n  chargeFeeTokenList: Array<C>\n  activeAccountPrice: string | undefined\n  // activeAccountFeeList?: Array<C>;\n  feeInfo: C | undefined\n  isFeeNotEnough: {\n    isFeeNotEnough: boolean\n    isOnLoading: boolean\n  }\n}\n\nexport type TransferExtendProps<T, I, C> = {\n  isThumb?: boolean\n  addressDefault?: string\n  sureItsLayer2: WALLET_TYPE | EXCHANGE_TYPE | undefined\n  handleSureItsLayer2: (sure: WALLET_TYPE | EXCHANGE_TYPE) => void\n  realAddr?: string\n  isLoopringAddress?: boolean\n  isSmartContractAddress?: boolean\n  isAddressCheckLoading?: boolean\n  isSameAddress?: boolean\n  isActiveAccountFee?: boolean | 'not allow'\n  addrStatus: AddressError\n  onTransferClick: (data: T, isFirstTime?: boolean) => Promise<void>\n  handleFeeChange: (value: C) => void\n  handleOnAddressChange: (value: string | undefined | I, isContactSelection?: boolean) => void\n  isActiveAccount?: boolean\n  feeWithActive?: boolean\n  handleOnFeeWithActive: (value: boolean) => void\n  wait?: number\n  onBack?: () => void\n  memo: string\n  handleOnMemoChange: (e: ChangeEvent<HTMLInputElement>) => void\n  contact?: { address: string; name: string; addressType: typeof sdk.AddressType }\n  isFromContact?: boolean\n  loopringSmartWalletVersion?: { isLoopringSmartWallet: boolean; version?: string }\n  isENSWrong?: boolean\n  ens?: string\n  geUpdateContact: () => void\n  // contacts?: { address: string; name: string; addressType: typeof sdk.AddressType }[]\n} & Pick<sdk.GetContactsResponse, 'contacts'> &\n  TransferInfoProps<C>\n\nexport type TransferViewProps<T, I, C = CoinKey<I> | string> = TransferExtendProps<T, I, C> &\n  BasicACoinTradeViewProps<T, I> & {\n    onClickContact: () => void\n  }\n\nexport type RampViewProps<T, I, C = CoinKey<I>> = TransferViewProps<T, I, C>\nexport type BanxaViewProps<T, I, C = CoinKey<I>> = TransferViewProps<T, I, C> & {\n  offBanxaValue?: BanxaOrder\n}\n\n/**\n * private props\n */\nexport type ResetInfoProps<C> = {\n  assetsData?: any[]\n  resetBtnStatus?: keyof typeof TradeBtnStatus | undefined\n  chargeFeeTokenList: Array<C>\n  feeInfo: C\n  disabled?: boolean\n  isFeeNotEnough: {\n    isFeeNotEnough: boolean\n    isOnLoading: boolean\n  }\n  handleFeeChange: (value: C) => void\n} & XOR<\n  {\n    walletMap: WalletMap<any>\n    goToDeposit: () => void\n    isNewAccount?: boolean\n    isReset?: boolean\n  },\n  {}\n>\n\nexport type ResetExtendProps<C> = {\n  onResetClick: (props: { isNotFirstTime?: boolean; isReset?: boolean }) => void\n} & ResetInfoProps<C>\n\nexport type ResetViewProps<C extends FeeInfo> = ResetExtendProps<C>\n\nexport type ExportAccountExtendProps = {\n  exportAccountProps: any\n  setExportAccountToastOpen: (value: boolean) => void\n}\n\n/**\n * private props\n */\nexport type DepositInfoProps = {\n  depositBtnStatus?: keyof typeof TradeBtnStatus | undefined\n  title?: string\n  description?: string\n  chargeFeeTokenList?: FeeInfo[]\n  isNewAccount: boolean\n  addressDefault?: string\n  // handleOnAddressChange?: (value: string | undefined | I) => void;\n  // handleAddressError?: (\n  //   address: string\n  // ) => { error: boolean; message?: string | JSX.Element } | undefined;\n  wait?: number\n} & BtnInfoProps\n\nexport type DepositExtendProps<T> = {\n  isThumb?: boolean\n  title?: string\n  isHideDes?: boolean\n  allowTrade?: any\n  toAddressStatus: AddressError\n  isAllowInputToAddress?: boolean\n  onDepositClick: (data: T) => void\n  toIsAddressCheckLoading: boolean\n  // toIsLoopringAddress: boolean;\n  toAddress?: string\n  realToAddress?: string | JSX.Element\n  handleClear: () => void\n  isToAddressEditable: boolean\n  onBack?: () => void\n  accountReady?: AccountStatus | undefined\n  handleAddressChange: (address: string) => void\n  isLoopringSmartWallet?: boolean\n  onClose: () => void\n} & DepositInfoProps\n\nexport type DepositViewProps<T, I> = BasicACoinTradeViewProps<T, I> & DepositExtendProps<T>\n\nexport type WithdrawInfoProps<C> = {\n  withdrawI18nKey?: string\n  withdrawBtnStatus?: keyof typeof TradeBtnStatus | undefined\n  chargeFeeTokenList: Array<C>\n  feeInfo: C\n  isFeeNotEnough: {\n    isFeeNotEnough: boolean\n    isOnLoading: boolean\n  }\n}\n\nexport type WithdrawExtendProps<T, I, C> = {\n  isThumb?: boolean\n  addressDefault: string\n  accAddr: string\n  isNotAvailableAddress:\n    | 'isCFAddress'\n    | 'isContract1XAddress'\n    | 'isContractAddress'\n    | 'isLoopringAddress'\n    | 'isSameAddress'\n    | undefined\n  withdrawType: WithdrawType\n  realAddr?: string\n  isAddressCheckLoading: boolean\n  isCFAddress: boolean\n  isLoopringAddress?: boolean\n  isContractAddress: boolean\n  isFastWithdrawAmountLimit?: boolean\n  addrStatus: AddressError\n  disableWithdrawList?: string[]\n  onWithdrawClick: (data: T, isFirstTime?: boolean) => void\n  handleFeeChange: (value: C) => void\n  handleWithdrawTypeChange: (value: WithdrawType) => void\n  handleOnAddressChange: (value: string | undefined | I, isContactSelection?: boolean) => void\n  wait?: number\n  onBack?: () => void\n  isToMyself?: boolean\n  sureIsAllowAddress: WALLET_TYPE | EXCHANGE_TYPE | undefined\n  handleSureIsAllowAddress: (value: WALLET_TYPE | EXCHANGE_TYPE) => void\n  contact?: { address: string; name: string; addressType?: typeof sdk.AddressType }\n  isFromContact?: boolean\n  // onClickContact?: () => void\n  loopringSmartWalletVersion?: { isLoopringSmartWallet: boolean; version?: string }\n  isENSWrong?: boolean\n  ens?: string\n  title?: string\n  geUpdateContact: () => void\n  withdrawMode?: {\n    mode: 'fast' | 'normal',\n    fastModeSupportedTokens: string[],\n    onChange: (mode: 'fast' | 'normal') => void\n    fastMode: undefined | {\n      fee: string,\n      time: string\n    }\n    fastMaxAlert: {\n      show: boolean,\n      message: string\n    }\n    showFastMode: boolean\n    normalMode: undefined | {\n      fee: string,\n      time: string\n    }\n    showTrustUI: boolean\n  }\n  // contacts?: { address: string; name: string; addressType: sdk.AddressType }[]\n} & Pick<sdk.GetContactsResponse, 'contacts'> &\n  WithdrawInfoProps<C>\n\nexport type WithdrawViewProps<T, I, C = CoinKey<I> | string> = BasicACoinTradeViewProps<T, I> &\n  WithdrawExtendProps<T, I, C> & {\n    onClickContact: () => void\n  }\n\nexport type ForceWithdrawExtendProps<T, I, C> = {\n  addressDefault: string\n  // accAddr: string;\n  realAddr: string\n  isActiveAccount: boolean\n  isNotAvailableAddress: boolean\n  isAddressCheckLoading: boolean\n  isLoopringAddress: boolean\n  addrStatus: AddressError\n  // disableWithdrawList?: string[];\n  onWithdrawClick: (data: T, isFirstTime?: boolean) => void\n  handleFeeChange: (value: C) => void\n  handleOnAddressChange: (value: string | undefined | I) => void\n  wait?: number\n  onBack?: () => void\n} & WithdrawInfoProps<C>\nexport type ForceWithdrawViewProps<T, I, C = CoinKey<I> | string> = BasicACoinTradeViewProps<T, I> &\n  ForceWithdrawExtendProps<T, I, C>\n\nexport type inputNFTProps<T, I, C = CoinInfo<I>> = RequireOne<InputCoinProps<T, I, C>, 'label'>\nexport type InputButtonDefaultProps<T, I, C = CoinInfo<I>> = RequireOne<\n  Partial<InputButtonProps<T, I, C>>,\n  'label'\n>\nexport type InputCoinDefaultProps<T, I, C = CoinInfo<I>> = RequireOne<\n  Partial<InputCoinProps<T, I, C>>,\n  'label'\n>\n\nexport type DefaultProps<T, I> = {\n  tradeData: T\n  disabled?: boolean\n  lastFailed?: boolean\n  selectNFTDisabled?: boolean\n  tokenNotEnough?: string\n} & (\n  | {\n      type: TRADE_TYPE.TOKEN\n      coinMap: CoinMap<I, CoinInfo<I>>\n      walletMap: WalletMap<I, WalletCoin<I>>\n    }\n  | {\n      type: TRADE_TYPE.NFT\n      coinMap?: CoinMap<I, CoinInfo<I>>\n      walletMap?: WalletMap<I, WalletCoin<I>>\n      baseURL?: string\n      getIPFSString?: GET_IPFS_STRING\n    }\n)\n\ntype DefaultWithMethodProps<T, I> = DefaultProps<T, I>\n\nexport type BasicACoinTradeViewProps<T, I> = Omit<DefaultWithMethodProps<T, I>, 'lastFailed'> & {\n  lastFailed?: boolean\n  baseURL?: string\n  getIPFSString?: (url: string | undefined, basicUrl: string) => string\n  onChangeEvent: (index: 0 | 1, data: SwitchData<T>) => void\n} & Pick<InputButtonProps<T, I, CoinInfo<I>> | InputCoinProps<T, I, CoinInfo<I>>, 'handleError'>\n\nexport type BasicACoinTradeProps<T, I> = BasicACoinTradeViewProps<T, I> & {\n  type?: TRADE_TYPE.TOKEN\n  inputBtnRef: React.Ref<any>\n  inputButtonProps?: InputButtonDefaultProps<I, CoinInfo<I>>\n  inputButtonDefaultProps?: InputButtonDefaultProps<I, CoinInfo<I>>\n  className?: string\n  isMaxBtn?: boolean\n}\nexport type BasicACoinInputProps<T, I> = BasicACoinTradeViewProps<T, I> & {\n  type?: TRADE_TYPE.TOKEN\n  inputCoinRef: React.Ref<any>\n  inputCoinProps?: InputCoinDefaultProps<I, CoinInfo<I>>\n  inputCoinDefaultProps?: InputCoinDefaultProps<I, CoinInfo<I>>\n  className?: string\n  tokenNotEnough?: string\n}\n\nexport type BasicANFTTradeProps<T, I> = (Omit<\n  BasicACoinTradeViewProps<T, I>,\n  'coinMap' | 'lastFailed' | 'walletMap'\n> & {\n  type: TRADE_TYPE.NFT\n  baseURL: string\n  fullwidth?: boolean\n  getIPFSString: GET_IPFS_STRING\n  isBalanceLimit?: boolean\n  inputNFTRef: React.Ref<any>\n  inputNFTProps?: inputNFTProps<I, CoinInfo<I>>\n  inputNFTDefaultProps: inputNFTProps<I, CoinInfo<I>>\n}) &\n  XOR<\n    {\n      isThumb: true\n      isRequired: boolean\n      isSelected: boolean\n      onChangeEvent?: (index: 0 | 1, data: SwitchData<T>) => SwitchData<T>\n      handlePanelEvent?: (props: SwitchData<T>, switchType: 'Tomenu' | 'Tobutton') => Promise<void>\n      myNFTPanel: JSX.Element\n    },\n    { isThumb?: boolean }\n  >\n\nexport type BasicACoinTradeHookProps<T, I> = DefaultWithMethodProps<T, I> & {\n  type?: TRADE_TYPE\n  handlePanelEvent?: (props: SwitchData<T>, switchType: 'Tomenu' | 'Tobutton') => Promise<void>\n  onChangeEvent?: (index: 0 | 1, data: SwitchData<T>) => SwitchData<T>\n  inputButtonProps?: InputButtonDefaultProps<T, I>\n} & Partial<SwitchPanelProps<any>>\n\nexport type NFTDepositInfoProps<T, I> = DefaultWithMethodProps<T, I> & {\n  nftDepositBtnStatus?: keyof typeof TradeBtnStatus | undefined\n  title?: string\n  description?: string\n  chargeFeeList?: FeeInfo[]\n  addressDefault?: string\n  handleOnAddressChange?: (value: string | undefined | I) => void\n  handleAddressError?: (\n    address: string,\n  ) => { error: boolean; message?: string | JSX.Element } | undefined\n  wait?: number\n} & BtnInfoProps\nexport type NFTDepositViewProps<T, I> = NFTDepositExtendProps<T, I>\nexport type NFTDepositExtendProps<T, I> = {\n  isThumb?: boolean\n  baseURL: string\n  getIPFSString: GET_IPFS_STRING\n  isNFTCheckLoading?: boolean\n  handleOnNFTDataChange: (data: T) => void\n  onNFTDepositClick: (data: T) => void\n  allowTrade?: any\n} & NFTDepositInfoProps<T, I>\n\nexport type NFTMintInfoProps<C> = {\n  nftMintBtnStatus?: keyof typeof TradeBtnStatus | undefined\n  title?: string\n  description?: string\n  chargeFeeTokenList?: Array<C>\n  feeInfo: C\n  // isAvailableId?: boolean;\n  isFeeNotEnough: {\n    isFeeNotEnough: boolean\n    isOnLoading: boolean\n  }\n  handleFeeChange: (value: C) => void\n  wait?: number\n} & BtnInfoProps\n\nexport type NFTMetaInfoProps<C> = {\n  nftMetaBtnStatus?: keyof typeof TradeBtnStatus | undefined\n  title?: string\n  description?: string\n  chargeFeeTokenList?: Array<C>\n  feeInfo: C\n  // isNFTCheckLoading?: boolean;\n  // isAvailableId?: boolean;\n  isFeeNotEnough: {\n    isFeeNotEnough: boolean\n    isOnLoading: boolean\n  }\n  handleFeeChange: (value: C) => void\n  wait?: number\n} & BtnInfoProps\n\nexport type NFTMintExtendProps<T, C = FeeInfo> = {\n  isThumb?: boolean\n  handleMintDataChange: (data: Partial<T>) => void\n  onNFTMintClick: (isFirstMint?: boolean) => void\n  allowTrade?: any\n  amountHandleError?: (\n    data: T,\n    ref: React.ForwardedRef<any>,\n  ) => { error: boolean; message?: string | JSX.Element } | void\n} & NFTMintInfoProps<C>\n\nexport type NFTMetaExtendProps<T, C = FeeInfo> = {\n  handleOnMetaChange: (data: Partial<T>) => void\n  onMetaClick: (data: Partial<T>, isFirstMint?: boolean) => void\n  userAgree: boolean\n  handleUserAgree: (value: boolean) => void\n  allowTrade?: any\n} & NFTMetaInfoProps<C>\n\nexport type NFTMintViewProps<ME, MI, I, C> = {\n  tradeData: MI\n  metaData: ME\n  disabled?: boolean\n  coinMap?: CoinMap<I, CoinInfo<I>>\n  walletMap?: WalletMap<I, WalletCoin<I>>\n  mintService: any\n  baseURL: string\n  getIPFSString: GET_IPFS_STRING\n} & NFTMintExtendProps<MI, C>\nexport type NFTMetaViewProps<T, Co, C> = {\n  nftMeta: T\n  domain: string\n  baseURL: string\n  collection?: Co | undefined\n  collectionInputProps: CollectionInputProps<Co>\n  disabled?: boolean\n} & NFTMetaExtendProps<T, C>\nexport type NFTMetaBlockProps<T, Co, I, C> = NFTMetaViewProps<T, Co, C> & {\n  mintData: Partial<I>\n  handleMintDataChange: (data: Partial<I>) => void\n  amountHandleError?: (\n    data: Partial<I>,\n    ref: React.ForwardedRef<any>,\n  ) => { error: boolean; message?: string | JSX.Element } | void\n}\n\n// export type NFTMintViewWholeProps<T, C> = {\n//   metaData: Partial<T>;\n//   disabled?: boolean;\n// } & NFTMintExtendProps<T, C>;\n\nexport type NFTDeployInfoProps<T, I, C> = DefaultWithMethodProps<T, I> & {\n  nftDeployBtnStatus?: keyof typeof TradeBtnStatus | undefined\n  title?: string\n  description?: string\n  assetsData?: any[]\n  chargeFeeTokenList: Array<C>\n  feeInfo: C\n  isFeeNotEnough: {\n    isFeeNotEnough: boolean\n    isOnLoading: boolean\n  }\n  handleFeeChange: (value: C) => void\n  wait?: number\n} & BtnInfoProps\n\nexport type NFTDeployExtendProps<T, I, C> = {\n  onBack: () => void\n  handleOnNFTDataChange: (data: T) => void\n  onNFTDeployClick: (data: T, isFirstTime?: boolean) => void\n  allowTrade?: any\n} & NFTDeployInfoProps<T, I, C>\n\nexport type NFTDeployViewProps<T, I, C> = NFTDeployExtendProps<T, I, C>\n\nexport type NFTMintAdvanceInfoProps<T, I, C> = DefaultWithMethodProps<T, I> & {\n  nftMintBtnStatus?: keyof typeof TradeBtnStatus | undefined\n  title?: string\n  description?: string\n  chargeFeeTokenList?: Array<C>\n  feeInfo: C\n  isNFTCheckLoading?: boolean\n  isNotAvailableTokenAddress?: undefined | { reason: string }\n  isNotAvailableCID?: undefined | { reason: string }\n  isFeeNotEnough: {\n    isFeeNotEnough: boolean\n    isOnLoading: boolean\n  }\n  handleFeeChange: (value: C) => void\n  wait?: number\n} & BtnInfoProps\n\nexport type NFTMintAdvanceExtendProps<T, Co, I, C = FeeInfo> = {\n  isThumb?: boolean\n  baseURL: string\n  getIPFSString: GET_IPFS_STRING\n  collectionInputProps: CollectionInputProps<Co>\n  handleOnNFTDataChange: (data: Partial<T>) => void\n  onNFTMintClick: (data: T, isFirstMint?: boolean) => void\n  allowTrade?: any\n  etherscanBaseUrl: string\n} & NFTMintAdvanceInfoProps<T, I, C>\nexport type NFTMintAdvanceViewProps<T, Co, I, C> = NFTMintAdvanceExtendProps<T, Co, I, C>\n\nexport type CollectionAdvanceProps<_T> = {\n  handleDataChange: (data: string) => void\n  onSubmitClick: () => Promise<void>\n  allowTrade?: any\n  disabled?: boolean\n  btnStatus: TradeBtnStatus\n  // handleError: (error: { code: number; message: string }) => void;\n  metaData: string\n} & BtnInfoProps\n\nexport enum ImportCollectionStep {\n  SELECTCONTRACT = 0,\n  SELECTCOLLECTION = 1,\n  SELECTNFT = 2,\n}\n\nexport type CollectionManageData<NFT> = {\n  listNFT: NFT[]\n  page: number\n  total: number\n  toastObj: TOSTOBJECT\n  onFilterNFT: (filter: {\n    legacyFilter: sdk.LegacyNFT | 'all'\n    limit: number\n    page: number\n  }) => Promise<void>\n  isLoading: boolean\n  filter: any\n}\nexport type ImportCollectionViewProps<Co, NFT> = {\n  account: Account\n  onContractChange: (item: string | undefined) => void\n  onContractNext: (item: string) => void\n  onCollectionChange: (item: Co | undefined) => void\n  onCollectionNext: (item: Co) => void\n  onNFTSelected: (item: NFT) => void\n  onNFTSelectedMethod: (item: NFT[], method: CollectionMethod) => void\n  step: ImportCollectionStep\n  baseURL: string\n  setStep: (step: ImportCollectionStep) => void\n  disabled?: boolean\n  getIPFSString: GET_IPFS_STRING\n  onLoading?: boolean\n  onClick: (item: string) => void\n  data: {\n    contractList: string[]\n    selectContract:\n      | {\n          value: string\n          total?: number\n          list?: sdk.UserNFTBalanceInfo[]\n        }\n      | undefined\n    selectCollection: Co | undefined\n    selectNFTList: NFT[]\n    collectionInputProps: CollectionInputProps<any>\n    nftProps: CollectionManageData<NFT>\n  }\n}\n\nexport enum CollectionMethod {\n  moveOut = 'moveOut',\n  moveIn = 'moveIn',\n}\n\nexport type CollectionManageProps<Co, NFT> = {\n  collection: Partial<Co>\n  selectedNFTS: NFT[]\n  onNFTSelected: (item: NFT | 'addAll' | 'removeAll') => void\n  baseURL: string\n  getIPFSString: GET_IPFS_STRING\n  onNFTSelectedMethod: (item: NFT[], method: CollectionMethod) => void\n} & CollectionManageData<NFT>\n\nexport type ImportRedPacketProps = {\n  btnStatus: TradeBtnStatus\n  btnInfo?: BtnInfo\n  disabled?: boolean\n  //\n}\nexport type ImportRedPacketExtendsProps<T> = {\n  handleOnDataChange: (value: Partial<T>) => void\n  onSubmitClick: () => Promise<void>\n  onFilesLoad: (key: string, value: IpfsFile) => void\n  onDelete: (key: string) => void\n} & ImportRedPacketProps\n\nexport type ImportRedPacketViewProps<T> = ImportRedPacketExtendsProps<T>\n\nexport type ClaimInfoProps<Fee> = {\n  btnInfo?: BtnInfo\n  btnStatus?: TradeBtnStatus | undefined\n  chargeFeeTokenList: Array<Fee>\n  feeInfo: Fee\n  isFeeNotEnough: {\n    isFeeNotEnough: boolean\n    isOnLoading: boolean\n  }\n}\n\nexport type ClaimExtendProps<T, Fee> = {\n  onClaimClick: (data: Partial<T>, isHardwareRetry?: boolean) => void\n  tradeData: Partial<T>\n  lastFailed: boolean\n  tradeType: TRADE_TYPE\n  claimType: CLAIM_TYPE\n  handleFeeChange: (value: Fee) => void\n  isNFT: boolean\n  nftIMGURL?: string\n} & ClaimInfoProps<Fee>\n\nexport type CreateRedPacketInfoProps<Fee = FeeInfo> = {\n  btnStatus: TradeBtnStatus\n  btnInfo?: BtnInfo\n  minimum: string | undefined\n  maximum: string | undefined\n  chargeFeeTokenList: Array<Fee>\n  feeInfo: Fee\n  isFeeNotEnough: {\n    isFeeNotEnough: boolean\n    isOnLoading: boolean\n  }\n  disabled?: boolean\n  //\n}\nexport type CreateRedPacketExtendsProps<T, F> = {\n  tradeType: RedPacketOrderType\n  handleOnDataChange: (value: Partial<T>) => void\n  handleFeeChange: (value: F) => void\n  onCreateRedPacketClick: () => Promise<void>\n  onBack?: () => void\n  assetsData: AssetsRawDataItem[]\n  onChangePrivateChecked?: () => void\n  privateChecked?: boolean\n  backToScope: () => void\n  onSendTargetRedpacketClick: () => Promise<void>\n  targetRedPackets: sdk.LuckyTokenItemForReceive[]\n  popRedPacket: sdk.LuckTokenClaimDetail | undefined\n  popRedPacketAmountStr: string | undefined\n  onClickViewTargetDetail: (hash: string) => void\n  onCloseRedpacketPop: () => void\n  contacts?: ContactType[]\n  isWhiteListed?: boolean\n  showExclusiveOption?: boolean\n  redPacketConfig: RedPacketConfig\n} & CreateRedPacketInfoProps<F>\n\nexport type CreateRedPacketViewProps<T, I, F, NFT = NFTWholeINFO> = CreateRedPacketExtendsProps<\n  T,\n  F\n> &\n  XOR<\n    BasicACoinTradeProps<T, I>,\n    BasicANFTTradeProps<T, I> & {\n      handleOnChoose: (value: NFT) => void\n      selectNFT: NFT\n    }\n  > & {\n    setActiveStep: (step: RedPacketStep | TargetRedPacketStep) => void\n    activeStep: RedPacketStep\n    tokenMap: { [key: string]: sdk.TokenInfo }\n    idIndex: { [key: string]: string }\n    backToScope: () => void\n    onClickNext: () => void\n    onClickBack: () => void\n    showNFT: boolean\n    onChangeTradeType?: (tradeType: RedPacketOrderType) => void\n    onSelecteValue?: (item: LuckyRedPacketItem) => void\n  }\n\nexport type TargetRedpacktSelectStepProps = {\n  onClickCreateNew: () => void\n  targetRedPackets: sdk.LuckyTokenItemForReceive[]\n  onClickExclusiveRedpacket: (info: { hash: string; remainCount: number }) => void\n  onClickViewDetail: (hash: string) => void\n  onCloseRedpacketPop: () => void\n  popRedPacket: sdk.LuckTokenClaimDetail | undefined\n  popRedPacketAmountStr: string | undefined\n  backToScope: () => void\n  idIndex: { [key: string]: string }\n}\n\nexport type TargetRedpacktInputAddressStepProps = {\n  popupChecked: boolean\n  onChangePopupChecked: (popupChecked: boolean) => void\n  onFileInput: (input: string) => void\n  addressListString: string\n  onClickSend: () => void\n  contacts?: ContactType[]\n  onConfirm: (list: string[]) => void\n  onManualEditInput: (text: string) => void\n  popUpOptionDisabled: boolean\n  maximumTargetsLength: number\n  onClickBack: () => void\n  sentAddresses?: string[]\n  clearInput: () => void\n}\n\n/**\n * private props\n */\nexport type VaultJoinInfoProps = {\n  btnStatus?: keyof typeof TradeBtnStatus | undefined\n  title?: string\n  description?: string\n  chargeFeeTokenList?: FeeInfo[]\n  wait?: number\n} & BtnInfoProps\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/MintAdvanceNFTWrap.tsx",
    "content": "import { NFTMintAdvanceViewProps } from './Interface'\nimport { Trans, useTranslation } from 'react-i18next'\nimport React from 'react'\nimport {\n  Box,\n  Checkbox,\n  FormControlLabel,\n  FormControlLabel as MuiFormControlLabel,\n  Link,\n  Radio,\n  Typography,\n} from '@mui/material'\nimport {\n  BackIcon,\n  CheckBoxIcon,\n  CheckedIcon,\n  CloseIcon,\n  EmptyValueTag,\n  FeeInfo,\n  getShortAddr,\n  Info2Icon,\n  L1L2_NAME_DEFINED,\n  LoadingIcon,\n  MapChainId,\n  myLog,\n  RefreshIcon,\n  SoursURL,\n  TOAST_TIME,\n  TradeBtnStatus,\n  TradeNFT,\n} from '@loopring-web/common-resources'\nimport {\n  Button,\n  CollectionInput,\n  EmptyDefault,\n  InputSize,\n  NftImage,\n  RadioGroupStyle,\n  TextField,\n  TGItemData,\n} from '../../basic-lib'\nimport { IconClearStyled } from './Styled'\nimport { NFTInput } from './BasicANFTTrade'\nimport { CollectionMeta, DEPLOYMENT_STATUS, NFTType } from '@loopring-web/loopring-sdk'\nimport styled from '@emotion/styled'\nimport { useSettings } from '../../../stores'\nimport { Toast, ToastType } from '../../toast'\nimport { BtnMain, HorizontalLabelPositionBelowStepper } from './tool'\nimport { FeeSelect } from '../../../components/modal'\n\nexport enum AdMethod {\n  HasData = 'HasData',\n  NoData = 'NoData',\n}\n\nconst MintAdStyle = styled(Box)`\n  .MuiFormGroup-root {\n    align-items: flex-start;\n  }\n\n  .coinInput-wrap {\n    border: 1px solid var(--color-border);\n  }\n\n  .MuiInputLabel-root {\n    font-size: ${({ theme }) => theme.fontDefault.body2};\n  }\n\n  .MuiButtonBase-root.step {\n    padding-left: ${({ theme }) => theme.unit * 4}px;\n    padding-right: ${({ theme }) => theme.unit * 4}px;\n  }\n`\n\nconst NFT_TYPE: TGItemData[] = [\n  {\n    value: NFTType.ERC1155,\n    key: 'ERC1155',\n    label: 'ERC1155',\n    disabled: false,\n  },\n]\n\nconst steps = [\n  'labelADMint1', //Prepare NFT metadata\n  'labelADMint2', //labelADMint2\n  'labelADMint3', //Preview & Mint NFT\n]\n\nexport enum MintStep {\n  SELECTWAY = 0,\n  INPUTCID = 1,\n  MINT = 2,\n}\n\nexport const MintAdvanceNFTWrap = <\n  T extends TradeNFT<I, Co>,\n  Co extends CollectionMeta,\n  I extends any,\n  C extends FeeInfo,\n>({\n  disabled: gDisabled,\n  walletMap,\n  tradeData,\n  btnInfo,\n  baseURL,\n  handleOnNFTDataChange,\n  nftMintBtnStatus,\n  isFeeNotEnough,\n  handleFeeChange,\n  chargeFeeTokenList,\n  feeInfo,\n  isNotAvailableCID,\n  isNotAvailableTokenAddress,\n  isNFTCheckLoading,\n  collectionInputProps,\n  onNFTMintClick,\n  getIPFSString,\n  etherscanBaseUrl,\n}: NFTMintAdvanceViewProps<T, Co, I, C>) => {\n  const { t } = useTranslation(['common'])\n  const { isMobile, defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const [activeStep, setActiveStep] = React.useState(MintStep.SELECTWAY)\n  const [address, setAddress] = React.useState(tradeData?.tokenAddress)\n  const [cid, setCid] = React.useState(tradeData?.nftIdView)\n  const [metaDataMissDataInfo, setMetaDataMissDataInfo] = React.useState<string[]>([])\n  const [metaDataErrorDataInfo, setMetaDataErrorDataInfo] = React.useState<string[]>([])\n  const [checked, setChecked] = React.useState(true)\n  const {\n    collectionListProps: { copyToastOpen },\n  } = collectionInputProps\n  const inputBtnRef = React.useRef()\n  const [showFeeModal, setShowFeeModal] = React.useState(false)\n  myLog('showFeeModal', showFeeModal)\n  React.useEffect(() => {\n    if (address !== tradeData?.tokenAddress && tradeData?.tokenAddress !== '') {\n      setAddress(tradeData?.tokenAddress)\n      if (!tradeData?.tokenAddress) {\n        setActiveStep(MintStep.SELECTWAY)\n      }\n    }\n  }, [tradeData?.tokenAddress])\n  React.useEffect(() => {\n    if (cid !== tradeData?.nftIdView && tradeData?.nftIdView !== '') {\n      setCid(tradeData?.nftIdView)\n      if (!tradeData.tokenAddress) {\n        setActiveStep(MintStep.SELECTWAY)\n      } else if (!tradeData?.nftIdView) {\n        setActiveStep(MintStep.INPUTCID)\n      }\n    }\n  }, [tradeData?.nftIdView])\n  const checkMeta = React.useCallback(() => {\n    const checkResult = ['collection_metadata'].reduce((prev, item) => {\n      if (!tradeData[item]) {\n        prev.push(item)\n      }\n      return prev\n    }, [] as string[])\n\n    const checkErrorResult = ['name', 'image', 'royaltyPercentage'].reduce((prev, item) => {\n      if (item === 'royaltyPercentage' && tradeData[item] === undefined) {\n        prev.push('royalty_percentage')\n      } else if (item !== 'royaltyPercentage' && !tradeData[item]) {\n        prev.push(item)\n      }\n      return prev\n    }, [] as string[])\n\n    if (\n      tradeData.nftId &&\n      (checkErrorResult.length ||\n        !(\n          tradeData.royaltyPercentage !== undefined &&\n          Number.isInteger(tradeData.royaltyPercentage) &&\n          tradeData.royaltyPercentage >= 0 &&\n          tradeData.royaltyPercentage <= 10\n        ))\n    ) {\n      setMetaDataErrorDataInfo(checkErrorResult)\n      setChecked(false)\n    } else {\n      setMetaDataErrorDataInfo([])\n    }\n    if (tradeData.nftId && checkResult.length) {\n      setMetaDataMissDataInfo(checkResult)\n      setChecked(false)\n    } else {\n      setMetaDataMissDataInfo([])\n      setChecked(true)\n    }\n  }, [tradeData])\n  React.useEffect(() => {\n    if (tradeData?.nftId) {\n      checkMeta()\n    }\n  }, [tradeData?.nftId])\n\n  const handleToggleChange = React.useCallback(\n    (value: C) => {\n      if (handleFeeChange) {\n        handleFeeChange(value)\n      }\n    },\n    [handleFeeChange],\n  )\n\n  myLog('mint tradeData', tradeData)\n  const methodLabel = React.useCallback(\n    ({ key }: { key: string }) => {\n      return (\n        <>\n          <Typography component={'span'} variant={'body1'} color={'textPrimary'}>\n            {t(`label${key}`)}\n          </Typography>\n        </>\n      )\n    },\n    [t],\n  )\n  const [method, setMethod] = React.useState(AdMethod.NoData)\n  const handleMethodChange = React.useCallback((_e: any, value: any) => {\n    setMethod(value)\n  }, [])\n  const [src, setSrc] = React.useState<string>('')\n\n  const [error, setError] = React.useState(false)\n\n  const panelList: Array<{\n    view: JSX.Element\n    onBack?: undefined | (() => void)\n    height?: any\n    width?: any\n  }> = React.useMemo(() => {\n    return [\n      {\n        view: (\n          <Box\n            marginTop={3}\n            display={'flex'}\n            justifyContent={'flex-start'}\n            flexDirection={'column'}\n            alignItems={'flex-start'}\n            width={'100%'}\n            maxWidth={'760px'}\n          >\n            <Typography component={'h4'} variant={'h5'} marginBottom={2}>\n              {t('labelADMintSelect')}\n            </Typography>\n            <Box\n              display={'flex'}\n              alignItems={'flex-start'}\n              flexDirection={isMobile ? 'column' : 'row'}\n              justifyContent={'stretch'}\n            >\n              <RadioGroupStyle\n                row={false}\n                aria-label='withdraw'\n                name='withdraw'\n                value={method}\n                onChange={handleMethodChange}\n              >\n                {Object.keys(AdMethod).map((key) => {\n                  return (\n                    <React.Fragment key={key}>\n                      <FormControlLabel\n                        value={key}\n                        control={<Radio />}\n                        label={methodLabel({ key })}\n                      />\n                    </React.Fragment>\n                  )\n                })}\n              </RadioGroupStyle>\n            </Box>\n            {method === AdMethod.HasData && (\n              <Box width={'100%'} paddingTop={2} paddingX={isMobile ? 2 : 0} position={'relative'}>\n                <TextField\n                  value={address}\n                  label={t('labelNFTContractAddress')}\n                  error={!!isNotAvailableTokenAddress}\n                  disabled={isNFTCheckLoading}\n                  placeholder={t('depositNFTAddressLabelPlaceholder')}\n                  onChange={\n                    (event) => {\n                      const tokenAddress = event.target.value\n                      setAddress(tokenAddress)\n                      if (/^0x[a-fA-F0-9]{40}$/g.test(tokenAddress)) {\n                        handleOnNFTDataChange({\n                          tokenAddress,\n                        } as T)\n                      } else {\n                        handleOnNFTDataChange({\n                          tokenAddress: '',\n                        } as T)\n                      }\n                    }\n\n                    // handleOnNFTDataChange({\n                    //   tokenAddress: event.target?.value,\n                    // } as T)\n                  }\n                  fullWidth={true}\n                />\n                {address &&\n                  (isNFTCheckLoading ? (\n                    <LoadingIcon\n                      width={24}\n                      style={{ top: 48, right: '8px', position: 'absolute' }}\n                    />\n                  ) : (\n                    <IconClearStyled\n                      color={'inherit'}\n                      size={'small'}\n                      style={{ top: 46 }}\n                      aria-label='Clear'\n                      onClick={() => {\n                        setAddress('')\n                        handleOnNFTDataChange({\n                          tokenAddress: '',\n                        } as T)\n                      }}\n                    >\n                      <CloseIcon />\n                    </IconClearStyled>\n                  ))}\n\n                {isNotAvailableTokenAddress && (\n                  <Typography\n                    color={'var(--color-error)'}\n                    variant={'body2'}\n                    marginTop={1 / 4}\n                    alignSelf={'stretch'}\n                    position={'relative'}\n                  >\n                    {t(isNotAvailableTokenAddress.reason, {\n                      ns: ['error', 'common'],\n                    })}\n                  </Typography>\n                )}\n              </Box>\n            )}\n            {method === AdMethod.NoData && (\n              <Box width={'100%'} paddingTop={2} paddingX={isMobile ? 2 : 0}>\n                <CollectionInput\n                  {...{\n                    ...(collectionInputProps as any),\n                    collection: tradeData.collectionMeta as any,\n                    onSelected: (item: Co) => {\n                      collectionInputProps.onSelected(item)\n                      handleOnNFTDataChange({\n                        tokenAddress: item.contractAddress ?? '',\n                      } as T)\n                    },\n                  }}\n                  fullWidth={true}\n                  size={isMobile ? 'small' : 'large'}\n                  showCopy={true}\n                />\n              </Box>\n            )}\n            <Typography display={'inline-block'} marginTop={4}>\n              <Trans i18nKey={'labelNFTGuid'}>\n                Please fill in the appropriate collection metadata field value in your NFT metadata\n                with this string first, then upload it to IPFS to retrieve the CID to continue.\n                <Link\n                  target='_blank'\n                  rel='noopener noreferrer'\n                  href={\n                    'https://desk.zoho.com/portal/loopring/en/kb/articles/collection-implementation-in-loopring-l2'\n                  }\n                  paddingLeft={1}\n                >\n                  Follow this Guide\n                  <Info2Icon\n                    style={{ cursor: 'pointer', marginLeft: '4px' }}\n                    fontSize={'medium'}\n                    htmlColor={'var(--color-text-third)'}\n                  />\n                </Link>\n              </Trans>\n            </Typography>\n            <Box width={'100%'} paddingX={isMobile ? 2 : 0} marginTop={2}>\n              <BtnMain\n                {...{\n                  defaultLabel: 'labelMintNext',\n                  fullWidth: true,\n                  disabled: () => {\n                    return gDisabled || !tradeData.tokenAddress || !tradeData.collectionMeta\n                  },\n                  btnStatus: nftMintBtnStatus,\n                  onClick: () => {\n                    setActiveStep(MintStep.INPUTCID)\n                  },\n                }}\n              />\n            </Box>\n          </Box>\n        ),\n        // onBack: () => setStep(CreateCollectionStep.ChooseMethod)\n      },\n      {\n        view: (\n          <Box\n            marginTop={3}\n            display={'flex'}\n            justifyContent={'flex-start'}\n            flexDirection={'column'}\n            alignItems={'flex-start'}\n            width={'100%'}\n            maxWidth={'760px'}\n          >\n            <Typography variant={'h5'} marginBottom={2}>\n              {t('labelMintIPFSCIDDes')}\n            </Typography>\n            <Box\n              display={'flex'}\n              alignItems={'center'}\n              flexDirection={'column'}\n              justifyContent={'space-between'}\n              position={'relative'}\n              alignSelf={'stretch'}\n            >\n              <Typography\n                component={'span'}\n                display={'flex'}\n                alignItems={'flex-start'}\n                alignSelf={'flex-start'}\n                marginBottom={1}\n                color={'textSecondary'}\n                variant={'body2'}\n              >\n                <Trans i18nKey={'labelNFTCid'}>IPFS CID :(Store Metadata Information),</Trans>\n              </Typography>\n              <TextField\n                value={cid}\n                label={''}\n                title={t('labelNFTCid')}\n                error={!!(tradeData.nftIdView !== '' && !isNFTCheckLoading && isNotAvailableCID)}\n                disabled={isNFTCheckLoading}\n                placeholder={t('mintNFTAddressLabelPlaceholder')}\n                onChange={(event) => {\n                  const cid = event.target?.value\n                  setCid(cid)\n                  if (\n                    /^(Qm[1-9A-HJ-NP-Za-km-z]{44,}|b[A-Za-z2-7]{58,}|B[A-Z2-7]{58,}|z[1-9A-HJ-NP-Za-km-z]{48,}|F[0-9A-F]{50,})$/.test(\n                      cid,\n                    )\n                  ) {\n                    handleOnNFTDataChange({\n                      nftIdView: cid,\n                      nftId: '',\n                    } as T)\n                  } else {\n                    handleOnNFTDataChange({\n                      nftIdView: '',\n                      nftId: '',\n                    } as T)\n                  }\n                }}\n                fullWidth={true}\n              />\n              {cid && cid !== '' ? (\n                isNFTCheckLoading ? (\n                  <LoadingIcon\n                    width={24}\n                    style={{\n                      top: '32px',\n                      right: '8px',\n                      position: 'absolute',\n                    }}\n                  />\n                ) : (\n                  <IconClearStyled\n                    color={'inherit'}\n                    size={'small'}\n                    style={{ top: '30px' }}\n                    aria-label='Clear'\n                    onClick={() => {\n                      setCid('')\n                      handleOnNFTDataChange({\n                        nftIdView: '',\n                        nftId: '',\n                      } as T)\n                    }}\n                  >\n                    <CloseIcon />\n                  </IconClearStyled>\n                )\n              ) : (\n                ''\n              )}\n              {isNotAvailableCID && tradeData?.nftIdView && tradeData?.nftIdView !== '' ? (\n                <Typography\n                  color={'var(--color-error)'}\n                  variant={'body1'}\n                  alignSelf={'stretch'}\n                  position={'relative'}\n                  component={'span'}\n                  whiteSpace={'pre-line'}\n                >\n                  {t('labelInvalidCID') +\n                    '\\n Reason: ' +\n                    t(isNotAvailableCID.reason, { ns: 'error' })}\n                </Typography>\n              ) : (\n                <>\n                  {tradeData?.nftId && tradeData.tokenAddress && tradeData?.nftIdView !== '' && (\n                    <Typography\n                      color={'var(--color-text-primary)'}\n                      variant={'body2'}\n                      whiteSpace={'break-spaces'}\n                      marginTop={1 / 4}\n                      component={'span'}\n                      width={'100%'}\n                      style={{ wordBreak: 'break-all' }}\n                    >\n                      {tradeData?.nftId}\n                    </Typography>\n                  )}\n                </>\n              )}\n              {!!(\n                tradeData.nftId &&\n                tradeData.tokenAddress &&\n                tradeData.collectionMeta &&\n                tradeData.collectionMeta.contractAddress\n              ) &&\n                (metaDataErrorDataInfo.length ? (\n                  <Box display={'flex'} flexDirection={'column'} width={'100%'}>\n                    <Typography\n                      color={'error'}\n                      variant={'body1'}\n                      alignSelf={'stretch'}\n                      position={'relative'}\n                      component={'span'}\n                      marginTop={2}\n                      whiteSpace={'pre-line'}\n                    >\n                      {t('labelCollectionMetaError', {\n                        type: metaDataErrorDataInfo.length\n                          ? '`' + metaDataErrorDataInfo.join('`, `') + '`'\n                          : t('labelCollectionMetaErrorType'),\n                      })}\n                    </Typography>\n                  </Box>\n                ) : metaDataMissDataInfo.length ? (\n                  <Box display={'flex'} flexDirection={'column'} width={'100%'}>\n                    <Typography\n                      color={'var(--color-warning)'}\n                      variant={'body1'}\n                      alignSelf={'stretch'}\n                      position={'relative'}\n                      component={'span'}\n                      marginTop={2}\n                      whiteSpace={'pre-line'}\n                    >\n                      {t('labelCollectionMetaMiss', {\n                        type: '`' + metaDataMissDataInfo.join('`, `') + '`',\n                      })}\n                    </Typography>\n                    <MuiFormControlLabel\n                      control={\n                        <Checkbox\n                          checked={checked}\n                          onChange={(_event: any, state: boolean) => {\n                            setChecked(state)\n                          }}\n                          checkedIcon={<CheckedIcon />}\n                          icon={<CheckBoxIcon />}\n                          color='default'\n                        />\n                      }\n                      label={t('labelBtradeUnderstand')}\n                    />\n                  </Box>\n                ) : (\n                  //   : !tradeData.collectionMeta.name ||\n                  //   !tradeData.collectionMeta.tileUri ? (\n                  //   <Typography\n                  //     color={\"var(--color-warning)\"}\n                  //     variant={\"body1\"}\n                  //     alignSelf={\"stretch\"}\n                  //     position={\"relative\"}\n                  //     component={\"span\"}\n                  //     marginTop={2}\n                  //     whiteSpace={\"pre-line\"}\n                  //   >\n                  //     {t(\"labelCollectionMetaNoNameORTileUri\", {\n                  //       type: [\n                  //         ...(!tradeData.collectionMeta.name ? [\"name\"] : []),\n                  //         ...(!tradeData.collectionMeta.tileUri\n                  //           ? [\"tile_uri\"]\n                  //           : []),\n                  //       ],\n                  //     })}\n                  //   </Typography>\n                  // )\n                  <></>\n                ))}\n            </Box>\n            <Box\n              width={'100%'}\n              paddingX={isMobile ? 2 : 0}\n              marginTop={2}\n              flexDirection={'row'}\n              display={'flex'}\n              justifyContent={'space-between'}\n            >\n              <Button\n                variant={'outlined'}\n                size={'medium'}\n                color={'primary'}\n                className={'step'}\n                sx={{ height: 'var(--btn-medium-height)' }}\n                startIcon={<BackIcon fontSize={'small'} />}\n                onClick={() => {\n                  setActiveStep(MintStep.SELECTWAY)\n                  setCid('')\n                  handleOnNFTDataChange({\n                    nftIdView: '',\n                    nftId: '',\n                    tradeValue: undefined,\n                  } as T)\n                }}\n              >\n                {t(`labelMintBack`)}\n              </Button>\n\n              <BtnMain\n                {...{\n                  defaultLabel: 'labelMintNext',\n                  btnInfo: undefined, //btnInfo,\n                  disabled: () => {\n                    return (\n                      gDisabled ||\n                      !!isNotAvailableCID ||\n                      !tradeData.nftId ||\n                      !!metaDataErrorDataInfo.length ||\n                      !checked\n                    )\n                  },\n                  btnStatus: nftMintBtnStatus,\n                  onClick: () => {\n                    setActiveStep(MintStep.MINT)\n                    setSrc(getIPFSString(tradeData?.image, baseURL))\n                  },\n                }}\n              />\n            </Box>\n          </Box>\n        ),\n      },\n      {\n        view: (\n          <>\n            <Box\n              marginTop={2}\n              flex={1}\n              alignSelf={'stretch'}\n              display={'flex'}\n              paddingX={isMobile ? 0 : 4}\n              flexDirection={isMobile ? 'column' : 'row'}\n            >\n              <Box\n                display={'flex'}\n                position={'relative'}\n                width={'auto'}\n                minHeight={200}\n                minWidth={380}\n              >\n                <img\n                  style={{\n                    opacity: 0,\n                    width: '100%',\n                    padding: 16,\n                    height: '100%',\n                    display: 'block',\n                  }}\n                  alt={'ipfs'}\n                  src={SoursURL + 'svg/ipfs.svg'}\n                />\n                <Box\n                  style={{\n                    position: 'absolute',\n                    top: 0,\n                    right: 0,\n                    left: 0,\n                    bottom: 0,\n                    height: '100%',\n                    width: '100%',\n                  }}\n                >\n                  {!!(tradeData?.nftId && tradeData.image) ? (\n                    <Box\n                      alignSelf={'stretch'}\n                      flex={1}\n                      display={'flex'}\n                      style={{ background: 'var(--field-opacity)' }}\n                      alignItems={'center'}\n                      height={'100%'}\n                      justifyContent={'center'}\n                    >\n                      {error ? (\n                        <Box\n                          flex={1}\n                          display={'flex'}\n                          alignItems={'center'}\n                          justifyContent={'center'}\n                          sx={{ cursor: 'pointer' }}\n                          onClick={async (event) => {\n                            event.stopPropagation()\n                            setError(false)\n                            setSrc(getIPFSString(tradeData?.image, baseURL))\n                          }}\n                        >\n                          <RefreshIcon style={{ height: 36, width: 36 }} />\n                        </Box>\n                      ) : (\n                        <NftImage alt={src} src={src} onError={() => setError(true)} />\n                      )}\n                    </Box>\n                  ) : (\n                    <Box\n                      flex={1}\n                      display={'flex'}\n                      alignItems={'center'}\n                      height={'100%'}\n                      justifyContent={'center'}\n                    >\n                      <EmptyDefault\n                        // width={\"100%\"}\n                        height={'100%'}\n                        message={() => (\n                          <Box\n                            flex={1}\n                            display={'flex'}\n                            alignItems={'center'}\n                            justifyContent={'center'}\n                          >\n                            {t('labelNoContent')}\n                          </Box>\n                        )}\n                      />\n                    </Box>\n                  )}\n                </Box>\n              </Box>\n              <Box\n                flex={1}\n                display={'flex'}\n                flexDirection={'column'}\n                justifyContent={'space-between'}\n                alignItems={'stretch'}\n                paddingLeft={isMobile ? 0 : 2}\n              >\n                <Box display={'flex'} flexDirection={'column'} alignItems={'stretch'}>\n                  <Typography\n                    component={'span'}\n                    display={'inline-flex'}\n                    justifyContent={'space-between'}\n                    variant={'body1'}\n                    marginBottom={2}\n                  >\n                    <Typography color={'textSecondary'} component={'span'} marginRight={1}>\n                      {t('labelNFTName')}\n                    </Typography>\n                    <Typography\n                      component={'span'}\n                      color={'var(--color-text-third)'}\n                      whiteSpace={'break-spaces'}\n                      style={{ wordBreak: 'break-all' }}\n                      title={tradeData.name}\n                    >\n                      {tradeData.name ?? EmptyValueTag}\n                    </Typography>\n                  </Typography>\n                  <Typography\n                    component={'span'}\n                    display={'inline-flex'}\n                    justifyContent={'space-between'}\n                    variant={'body1'}\n                    marginBottom={2}\n                  >\n                    <Typography color={'textSecondary'} component={'span'} marginRight={1}>\n                      {t('labelNFTType')}\n                    </Typography>\n                    <Typography\n                      component={'span'}\n                      color={'var(--color-text-third)'}\n                      whiteSpace={'break-spaces'}\n                      style={{ wordBreak: 'break-all' }}\n                      title={NFT_TYPE[0].label}\n                    >\n                      {NFT_TYPE[0].label}\n                    </Typography>\n                  </Typography>\n\n                  <Typography\n                    component={'span'}\n                    display={'inline-flex'}\n                    justifyContent={'space-between'}\n                    variant={'body1'}\n                    marginBottom={2}\n                  >\n                    <Typography color={'textSecondary'} component={'span'} marginRight={1}>\n                      {t('labelNFTContractAddress')}\n                    </Typography>\n                    {tradeData.collectionMeta &&\n                    tradeData.collectionMeta.deployStatus == DEPLOYMENT_STATUS.DEPLOYED ? (\n                      <Link\n                        fontSize={'inherit'}\n                        whiteSpace={'break-spaces'}\n                        style={{\n                          wordBreak: 'break-all',\n                          color: 'var(--color-text-third)',\n                        }}\n                        target='_blank'\n                        title={tradeData.collectionMeta.contractAddress}\n                        rel='noopener noreferrer'\n                        href={`${etherscanBaseUrl}token/${tradeData.collectionMeta.contractAddress}`}\n                      >\n                        {tradeData.collectionMeta.contractAddress}\n                      </Link>\n                    ) : (\n                      <Typography\n                        component={'span'}\n                        color={'var(--color-text-third)'}\n                        title={'Counter Factual NFT' + tradeData?.collectionMeta?.contractAddress}\n                      >\n                        {t('labelCounterFactualNFT', {\n                          l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                          loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                          l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                          l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                          ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                        }) + getShortAddr(tradeData?.collectionMeta?.contractAddress ?? '')}\n                      </Typography>\n                    )}\n                  </Typography>\n\n                  <Typography\n                    component={'span'}\n                    display={'inline-flex'}\n                    justifyContent={'space-between'}\n                    variant={'body1'}\n                    marginBottom={2}\n                  >\n                    <Typography color={'textSecondary'} component={'span'} marginRight={1}>\n                      {t('labelNFTCollection')}\n                    </Typography>\n                    <Typography\n                      component={'span'}\n                      color={'var(--color-text-third)'}\n                      whiteSpace={'break-spaces'}\n                      display={'inline-flex'}\n                      alignItems={'center'}\n                      style={{ wordBreak: 'break-all' }}\n                      title={tradeData.collectionMeta?.contractAddress}\n                    >\n                      {tradeData.collectionMeta?.name}\n                    </Typography>\n                  </Typography>\n\n                  <NFTInput\n                    {...({ t } as any)}\n                    isThumb={false}\n                    baseURL={baseURL}\n                    isBalanceLimit={true}\n                    inputNFTDefaultProps={{\n                      subLabel: t('tokenNFTMaxMINT'),\n                      size: InputSize.small,\n                      label: (\n                        <Trans i18nKey={'labelNFTMintInputTitle'}>\n                          Amount\n                          <Typography component={'span'} variant={'inherit'} color={'error'}>\n                            {'\\uFE61'}\n                          </Typography>\n                        </Trans>\n                      ),\n                    }}\n                    // disabled={!(tradeData?.nftId && tradeData.tokenAddress)}\n                    type={'NFT'}\n                    inputNFTRef={inputBtnRef}\n                    onChangeEvent={(_index, data) =>\n                      handleOnNFTDataChange({\n                        tradeValue: data.tradeData?.tradeValue ?? '0',\n                      } as T)\n                    }\n                    tradeData={\n                      {\n                        ...tradeData,\n                        belong: tradeData?.tokenAddress ?? 'NFT',\n                      } as any\n                    }\n                    walletMap={walletMap}\n                  />\n\n                  <Box marginTop={2} alignSelf={'stretch'}>\n                    {!chargeFeeTokenList?.length ? (\n                      <Typography>{t('labelFeeCalculating')}</Typography>\n                    ) : (\n                      <>\n                        <FeeSelect\n                          chargeFeeTokenList={chargeFeeTokenList}\n                          handleToggleChange={(fee: FeeInfo) => {\n                            handleToggleChange(fee as C)\n                            setShowFeeModal(false)\n                          }}\n                          feeInfo={feeInfo as FeeInfo}\n                          open={showFeeModal}\n                          onClose={() => {\n                            setShowFeeModal(false)\n                          }}\n                          isFeeNotEnough={isFeeNotEnough.isFeeNotEnough}\n                          feeLoading={isFeeNotEnough.isOnLoading}\n                          onClickFee={() => setShowFeeModal((prev) => !prev)}\n                        />\n                      </>\n                    )}\n                  </Box>\n                </Box>\n                <Box\n                  width={'100%'}\n                  paddingX={isMobile ? 2 : 0}\n                  marginTop={2}\n                  flexDirection={'row'}\n                  display={'flex'}\n                  justifyContent={'space-between'}\n                >\n                  <Button\n                    variant={'outlined'}\n                    size={'medium'}\n                    className={'step'}\n                    startIcon={<BackIcon fontSize={'small'} />}\n                    color={'primary'}\n                    sx={{ height: 'var(--btn-medium-height)' }}\n                    onClick={() => {\n                      setActiveStep(MintStep.INPUTCID)\n\n                      handleOnNFTDataChange({\n                        tradeValue: undefined,\n                        // collectionMeta: undefined,\n                        // tokenAddress:undefined,\n                      } as T)\n                    }}\n                  >\n                    {t(`labelMintBack`)}\n                  </Button>\n                  <BtnMain\n                    {...{\n                      defaultLabel: t('labelMintSubmitBtn'),\n                      btnStatus: nftMintBtnStatus,\n                      btnInfo: btnInfo,\n                      disabled: () => {\n                        return gDisabled || nftMintBtnStatus === TradeBtnStatus.DISABLED\n                      },\n                      onClick: () => {\n                        // setActiveStep(MintSte)\n                        onNFTMintClick(tradeData)\n                      },\n                    }}\n                  />\n                </Box>\n              </Box>\n            </Box>\n          </>\n        ),\n      },\n    ]\n  }, [\n    t,\n    isMobile,\n    method,\n    handleMethodChange,\n    address,\n    isNotAvailableTokenAddress,\n    isNFTCheckLoading,\n    collectionInputProps,\n    tradeData,\n    cid,\n    isNotAvailableCID,\n    metaDataErrorDataInfo,\n    metaDataMissDataInfo,\n    checked,\n    error,\n    src,\n    etherscanBaseUrl,\n    baseURL,\n    walletMap,\n    chargeFeeTokenList,\n    feeInfo,\n    isFeeNotEnough.isOnLoading,\n    isFeeNotEnough.isFeeNotEnough,\n    handleToggleChange,\n    btnInfo,\n    methodLabel,\n    handleOnNFTDataChange,\n    gDisabled,\n    getIPFSString,\n    nftMintBtnStatus,\n    onNFTMintClick,\n    showFeeModal,\n  ])\n\n  // @ts-ignore\n  return (\n    <Box\n      className={walletMap ? '' : 'loading'}\n      display={'flex'}\n      flex={1}\n      flexDirection={'column'}\n      padding={5 / 2}\n      alignItems={'center'}\n    >\n      <HorizontalLabelPositionBelowStepper activeStep={activeStep} steps={steps} />\n      <MintAdStyle\n        flex={1}\n        marginTop={2}\n        paddingX={isMobile ? 2 : 5}\n        display={'flex'}\n        justifyContent={'center'}\n        alignItems={'flex-start'}\n        width={'100%'}\n      >\n        {panelList.map((panel, index) => {\n          return (\n            <React.Fragment key={index}>{activeStep === index ? panel.view : <></>}</React.Fragment>\n          )\n        })}\n      </MintAdStyle>\n      {copyToastOpen && (\n        <Toast\n          alertText={\n            copyToastOpen?.type === 'json'\n              ? t('labelCopyMetaClip')\n              : copyToastOpen.type === 'url'\n              ? t('labelCopyUrlClip')\n              : t('labelCopyAddClip')\n          }\n          open={copyToastOpen?.isShow}\n          autoHideDuration={TOAST_TIME}\n          onClose={() => {\n            collectionInputProps?.collectionListProps?.setCopyToastOpen({\n              isShow: false,\n              type: '',\n            })\n          }}\n          severity={ToastType.success}\n        />\n      )}\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/MintNFTBlock.tsx",
    "content": "import { NFTMetaBlockProps } from './Interface'\nimport { Trans, useTranslation } from 'react-i18next'\nimport React from 'react'\nimport { Box, FormLabel, Grid, GridProps, Tooltip, Typography } from '@mui/material'\nimport {\n  CoinInfo,\n  CoinMap,\n  CollectionMeta,\n  FeeInfo,\n  Info2Icon,\n  MintTradeNFT,\n  myLog,\n  NFTMETA,\n  TradeBtnStatus,\n} from '@loopring-web/common-resources'\nimport { Button, InputCoin, InputSize, TextareaAutosizeStyled, TextField } from '../../basic-lib'\n\nimport styled from '@emotion/styled'\nimport { useSettings } from '../../../stores'\nimport { NFTInput } from './BasicANFTTrade'\nimport { Properties } from './tool/Property'\nimport { CollectionInput } from './tool'\n\nconst GridStyle = styled(Grid)<GridProps>`\n  .coinInput-wrap {\n    border: 1px solid var(--color-border);\n  }\n\n  .MuiInputLabel-root {\n    font-size: ${({ theme }) => theme.fontDefault.body2};\n  }\n\n  .main-label,\n  .sub-label {\n    color: var(--color-text-secondary);\n    font-size: ${({ theme }) => theme.fontDefault.body1};\n  }\n` as (props: GridProps) => JSX.Element\n\nexport const MintNFTBlock = <\n  T extends Partial<NFTMETA>,\n  Co extends CollectionMeta,\n  I extends Partial<MintTradeNFT<any>>,\n  C extends FeeInfo,\n>({\n  disabled,\n  nftMeta,\n  mintData,\n  btnInfo,\n  // collection,\n  nftMetaBtnStatus,\n  handleOnMetaChange,\n  handleMintDataChange,\n  baseURL,\n  domain,\n  collectionInputProps,\n  onMetaClick,\n}: NFTMetaBlockProps<T, Co, I, C>) => {\n  const { t } = useTranslation(['common'])\n  const { isMobile } = useSettings()\n  const inputBtnRef = React.useRef()\n  const [_collection, setCollection] = React.useState<Co | undefined>(\n    collectionInputProps?.collection ?? undefined,\n  )\n  React.useEffect(() => {\n    setCollection(collectionInputProps.collection)\n  }, [collectionInputProps?.collection?.contractAddress])\n  const getDisabled = React.useMemo(() => {\n    return disabled || nftMetaBtnStatus === TradeBtnStatus.DISABLED\n  }, [disabled, nftMetaBtnStatus])\n  myLog('mint nftMeta', nftMeta, mintData)\n\n  const _handleMintDataChange = React.useCallback(\n    (_mintData: Partial<I>) => {\n      handleMintDataChange({ ..._mintData })\n    },\n    [handleMintDataChange],\n  )\n  // @ts-ignore\n  return (\n    <Box flex={1} flexDirection={'column'} display={'flex'} alignContent={'space-between'}>\n      <GridStyle\n        className={isMobile ? 'isMobile' : ''}\n        flex={1}\n        display={'flex'}\n        container\n        spacing={2}\n        alignContent={'flex-start'}\n      >\n        <Grid item xs={12} md={6}>\n          <TextField\n            value={nftMeta.name}\n            fullWidth\n            disabled={disabled}\n            inputProps={{ maxLength: 32 }}\n            label={\n              <Typography component={'span'} variant={'body1'} color={'textSecondary'}>\n                <Trans i18nKey={'labelMintName'}>\n                  Name\n                  <Typography component={'span'} variant={'inherit'} color={'error'}>\n                    {'\\uFE61'}\n                  </Typography>\n                </Trans>\n              </Typography>\n            }\n            type={'text'}\n            onChange={(event) => handleOnMetaChange({ name: event.target.value } as Partial<T>)}\n          />\n        </Grid>\n        <Grid item xs={12} md={6}>\n          <CollectionInput\n            {...{\n              ...collectionInputProps,\n              collection: _collection,\n              domain,\n              isRequired: true,\n              onSelected: (item: Co) => {\n                setCollection(item)\n                handleOnMetaChange({\n                  collection: item,\n                } as any)\n              },\n            }}\n            size={isMobile ? 'small' : 'medium'}\n            fullWidth={true}\n          />\n        </Grid>\n        <Grid item xs={12} md={6}>\n          <InputCoin\n            handleCountChange={(data) =>\n              handleOnMetaChange({\n                royaltyPercentage: data.tradeValue,\n              } as unknown as Partial<T>)\n            }\n            {...{\n              maxAllow: true,\n              placeholderText: '0',\n              allowDecimals: false,\n              handleError: (data) => {\n                if (data.tradeValue && data.tradeValue > data.balance) {\n                  return {\n                    error: true,\n                  }\n                }\n                return {\n                  error: false,\n                }\n              },\n              // size = InputSize.middle,\n              isHideError: true,\n              isShowCoinInfo: false,\n              order: 'right',\n              noBalance: '0',\n              coinPrecision: 0,\n              subLabel: t('labelMintRoyaltyPercentageRange'),\n              label: (\n                <Tooltip\n                  title={t('labelMintRoyaltyPercentageTooltips').toString()}\n                  placement={'top'}\n                >\n                  <Typography\n                    component={'span'}\n                    variant={'inherit'}\n                    display={'inline-flex'}\n                    alignItems={'center'}\n                  >\n                    <Trans i18nKey={'labelMintRoyaltyPercentage'}>\n                      Royalty(%)\n                      <Typography component={'span'} variant={'inherit'} color={'error'}>\n                        {'\\uFE61'}\n                      </Typography>\n                      <Info2Icon fontSize={'small'} color={'inherit'} sx={{ marginX: 1 / 2 }} />\n                    </Trans>\n                  </Typography>\n                </Tooltip>\n              ),\n              size: InputSize.small,\n              inputData: {\n                balance: 10,\n                tradeValue: nftMeta.royaltyPercentage ?? 0,\n                belong: 'royaltyPercentage' as any,\n              },\n              disabled,\n              coinMap: {} as CoinMap<I, CoinInfo<I>>,\n            }}\n          />\n        </Grid>\n        <Grid item xs={12} md={6}>\n          <NFTInput\n            {...({ t } as any)}\n            isThumb={false}\n            baseURL={baseURL}\n            isBalanceLimit={true}\n            inputNFTDefaultProps={{\n              subLabel: t('tokenNFTMaxMINT'),\n              size: InputSize.small,\n              isHideError: false,\n              label: (\n                <Trans i18nKey={'labelNFTMintInputTitle'}>\n                  Amount\n                  <Typography component={'span'} variant={'inherit'} color={'error'}>\n                    {'\\uFE61'}\n                  </Typography>\n                </Trans>\n              ),\n            }}\n            // disabled={!(nftMintData.nftId && nftMintData.tokenAddress)}\n            type={'NFT'}\n            inputNFTRef={inputBtnRef}\n            onChangeEvent={(_index, data) =>\n              _handleMintDataChange({\n                ...data.tradeData,\n              } as unknown as Partial<I>)\n            }\n            handleError={(data) => {\n              if (!data.tradeValue || data.tradeValue > data.balance) {\n                return {\n                  error: true,\n                  // message: `Not enough ${belong} perform a deposit`,\n                }\n              }\n              return {\n                error: false,\n              }\n            }}\n            // handleError={(data: I, ref) => {\n            //   if (amountHandleError) {\n            //     amountHandleError(data, ref);\n            //   }\n            // }}\n            tradeData={\n              {\n                ...mintData,\n                belong: mintData.tokenAddress ?? 'NFT',\n                balance: mintData.nftBalance,\n              } as any\n            }\n            disabled={disabled}\n            walletMap={{}}\n          />\n        </Grid>\n        <Grid item xs={12} md={12} flex={1}>\n          <FormLabel>\n            <Tooltip title={t('labelMintDescriptionTooltips').toString()} placement={'top'}>\n              <Typography\n                variant={'body2'}\n                component={'span'}\n                lineHeight={'20px'}\n                display={'inline-flex'}\n                alignItems={'center'}\n                className={'main-label'}\n              >\n                <Trans i18nKey={'labelMintDescription'}>\n                  Description\n                  <Info2Icon fontSize={'small'} color={'inherit'} sx={{ marginX: 1 / 2 }} />\n                </Trans>\n              </Typography>\n            </Tooltip>\n          </FormLabel>\n          <TextareaAutosizeStyled\n            aria-label='NFT Description'\n            minRows={2}\n            maxRows={5}\n            disabled={disabled}\n            style={{\n              overflowX: 'hidden',\n              resize: 'vertical',\n            }}\n            maxLength={1000}\n            onChange={(event) =>\n              handleOnMetaChange({\n                description: event.target.value,\n              } as unknown as Partial<T>)\n            }\n            draggable={true}\n          />\n        </Grid>\n        <Grid item xs={12} md={12}>\n          <FormLabel>\n            <Tooltip title={t('labelMintPropertyTooltips').toString()} placement={'top'}>\n              <Typography\n                component={'span'}\n                variant={'body2'}\n                lineHeight={'20px'}\n                display={'inline-flex'}\n                alignItems={'center'}\n                className={'main-label'}\n              >\n                <Trans i18nKey={'labelMintProperty'}>\n                  Properties\n                  <Info2Icon fontSize={'small'} color={'inherit'} sx={{ marginX: 1 / 2 }} />\n                </Trans>\n              </Typography>\n            </Tooltip>\n          </FormLabel>\n          <Box marginTop={1}>\n            <Properties\n              disabled={disabled}\n              handleChange={(properties) =>\n                handleOnMetaChange({\n                  properties: properties,\n                } as unknown as Partial<T>)\n              }\n              properties={nftMeta.properties ?? [{ key: '', value: '' }]}\n            />\n          </Box>\n        </Grid>\n        <Grid item xs={12} display={'flex'}>\n          {btnInfo?.label === 'labelNFTMintNoMetaBtn' && (\n            <Typography\n              color={'var(--color-warning)'}\n              component={'p'}\n              variant={'body1'}\n              marginBottom={1}\n              style={{ wordBreak: 'break-all' }}\n            >\n              <Trans i18nKey={'labelNFTMintNoMetaDetail'}>\n                Your NFT nftMeta should identify\n                <em style={{ fontWeight: 600 }}>\n                  name, image & royalty_percentage(number from 0 to 10)\n                </em>\n                .\n              </Trans>\n            </Typography>\n          )}\n          <Button\n            fullWidth\n            variant={'contained'}\n            size={'medium'}\n            color={'primary'}\n            onClick={() => {\n              onMetaClick(nftMeta as T)\n            }}\n            loading={!getDisabled && nftMetaBtnStatus === TradeBtnStatus.LOADING ? 'true' : 'false'}\n            disabled={getDisabled || nftMetaBtnStatus === TradeBtnStatus.LOADING}\n          >\n            {btnInfo ? t(btnInfo.label, btnInfo.params) : t(`labelNFTMetaBtn`)}\n          </Button>\n        </Grid>\n      </GridStyle>\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/MintNFTConfirm.tsx",
    "content": "import { NFTMintViewProps } from './Interface'\nimport { useTranslation } from 'react-i18next'\nimport React from 'react'\nimport { Box, Grid, Link, Typography } from '@mui/material'\nimport {\n  EmptyValueTag,\n  FeeInfo,\n  getShortAddr,\n  IPFS_LOOPRING_SITE,\n  LinkIcon,\n  MetaProperty,\n  MintTradeNFT,\n  NFTMETA,\n  RefreshIcon,\n  RowConfig,\n  SoursURL,\n  TradeBtnStatus,\n} from '@loopring-web/common-resources'\nimport {\n  Button,\n  Column,\n  EmptyDefault,\n  NftImage,\n  Table,\n  TextareaAutosizeStyled,\n} from '../../basic-lib'\nimport styled from '@emotion/styled'\nimport { useSettings } from '../../../stores'\nimport { FeeSelect } from '../../../components/modal'\n\nconst GridStyle = styled(Grid)`\n  .coinInput-wrap {\n    border: 1px solid var(--color-border);\n  }\n\n  .MuiInputLabel-root {\n    font-size: ${({ theme }) => theme.fontDefault.body2};\n  }\n` as typeof Grid\nconst TableStyle = styled(Table)`\n  &.rdg {\n    min-height: 60px;\n    height: ${(props: any) => {\n      if (props.currentheight) {\n        return props.currentheight + 2 + 'px'\n      } else {\n        return '100%'\n      }\n    }};\n  }\n`\n\nexport const MintNFTConfirm = <\n  ME extends Partial<NFTMETA>,\n  MI extends Partial<MintTradeNFT<any>>,\n  I,\n  C extends FeeInfo,\n>({\n  disabled,\n  tradeData: nftMintData,\n  metaData,\n  btnInfo,\n  nftMintBtnStatus,\n  isFeeNotEnough,\n  handleFeeChange,\n  chargeFeeTokenList,\n  feeInfo,\n  baseURL,\n  onNFTMintClick,\n  mintService,\n  getIPFSString,\n}: NFTMintViewProps<ME, MI, I, C>) => {\n  const { t, ...rest } = useTranslation(['common'])\n  const { isMobile } = useSettings()\n  const [showFeeModal, setShowFeeModal] = React.useState(false)\n  const getDisabled = React.useMemo(() => {\n    return disabled || nftMintBtnStatus === TradeBtnStatus.DISABLED\n  }, [disabled, nftMintBtnStatus])\n  const [error, setError] = React.useState(false)\n  const [src, setSrc] = React.useState(getIPFSString(metaData?.image, baseURL))\n  React.useEffect(() => {\n    setError(false)\n    setSrc(getIPFSString(metaData?.image ?? '', baseURL))\n  }, [metaData?.image])\n  const handleToggleChange = (value: C) => {\n    if (handleFeeChange) {\n      handleFeeChange(value)\n    }\n  }\n  const rawData =\n    metaData.properties?.reduce((prev, item) => {\n      if (!!item.key?.trim() && !!item.value?.trim()) {\n        return [...prev, item]\n      } else {\n        return prev\n      }\n    }, [] as Array<MetaProperty>) ?? []\n\n  // myLog(\"mint nftMintData\", nftMintData);\n\n  // @ts-ignore\n  return (\n    <Box\n      flex={1}\n      flexDirection={'column'}\n      display={'flex'}\n      alignContent={'space-between'}\n      padding={5 / 2}\n    >\n      <GridStyle container flex={1} spacing={2}>\n        <Grid item xs={12} md={5} alignItems={'center'}>\n          <Box>\n            <Grid container maxWidth={'inherit'} spacing={2}>\n              <Grid item xs={12}>\n                <Box flex={1} display={'flex'} position={'relative'} width={'auto'} minHeight={200}>\n                  <img\n                    style={{\n                      opacity: 0,\n                      width: '100%',\n                      padding: 16,\n                      height: '100%',\n                      display: 'block',\n                    }}\n                    alt={'ipfs'}\n                    src={SoursURL + 'svg/ipfs.svg'}\n                  />\n                  <Box\n                    style={{\n                      position: 'absolute',\n                      top: 0,\n                      right: 0,\n                      left: 0,\n                      bottom: 0,\n                      height: '100%',\n                      width: '100%',\n                    }}\n                  >\n                    {metaData.image ? (\n                      <Box\n                        alignSelf={'stretch'}\n                        flex={1}\n                        display={'flex'}\n                        style={{ background: 'var(--field-opacity)' }}\n                        alignItems={'center'}\n                        height={'100%'}\n                        justifyContent={'center'}\n                      >\n                        {error ? (\n                          <Box\n                            flex={1}\n                            display={'flex'}\n                            alignItems={'center'}\n                            justifyContent={'center'}\n                            sx={{ cursor: 'pointer' }}\n                            onClick={async (event) => {\n                              event.stopPropagation()\n                              setError(false)\n                              setSrc(getIPFSString(metaData?.image, baseURL))\n                            }}\n                          >\n                            <RefreshIcon style={{ height: 36, width: 36 }} />\n                          </Box>\n                        ) : (\n                          <NftImage alt={src} src={src} onError={() => setError(true)} />\n                        )}\n                      </Box>\n                    ) : (\n                      <Box\n                        flex={1}\n                        display={'flex'}\n                        alignItems={'center'}\n                        height={'100%'}\n                        justifyContent={'center'}\n                      >\n                        <EmptyDefault\n                          // width={\"100%\"}\n                          height={'100%'}\n                          message={() => (\n                            <Box\n                              flex={1}\n                              display={'flex'}\n                              alignItems={'center'}\n                              justifyContent={'center'}\n                            >\n                              {t('labelNoContent')}\n                            </Box>\n                          )}\n                        />\n                      </Box>\n                    )}\n                  </Box>\n                </Box>\n              </Grid>\n              <Grid item xs={12} alignSelf={'stretch'}>\n                {!chargeFeeTokenList?.length ? (\n                  <Typography>{t('labelFeeCalculating')}</Typography>\n                ) : (\n                  <>\n                    <FeeSelect\n                      chargeFeeTokenList={chargeFeeTokenList}\n                      handleToggleChange={(fee: FeeInfo) => {\n                        handleToggleChange(fee as C)\n                        setShowFeeModal(false)\n                      }}\n                      feeInfo={feeInfo as FeeInfo}\n                      open={showFeeModal}\n                      onClose={() => {\n                        setShowFeeModal(false)\n                      }}\n                      isFeeNotEnough={isFeeNotEnough.isFeeNotEnough}\n                      feeLoading={isFeeNotEnough.isOnLoading}\n                      onClickFee={() => setShowFeeModal((prev) => !prev)}\n                    />\n                  </>\n                )}\n              </Grid>\n            </Grid>\n          </Box>\n        </Grid>\n        <Grid item xs={12} md={7}>\n          <Typography component={'h4'} variant={'h5'} marginBottom={2}>\n            {t('labelConfirmMint')}\n          </Typography>\n          <Box>\n            <Grid container maxWidth={'inherit'} spacing={2}>\n              <Grid item xs={12} alignSelf={'stretch'}>\n                <Typography\n                  component={'span'}\n                  display={'inline-flex'}\n                  flexDirection={isMobile ? 'column' : 'row'}\n                  variant={'body1'}\n                >\n                  <Typography color={'textSecondary'} component={'span'} marginRight={1}>\n                    {t('labelNFTName')}\n                  </Typography>\n                  <Typography\n                    component={'span'}\n                    color={'var(--color-text-third)'}\n                    whiteSpace={'break-spaces'}\n                    style={{ wordBreak: 'break-all' }}\n                    title={metaData.name}\n                  >\n                    {metaData.name ?? EmptyValueTag}\n                  </Typography>\n                </Typography>\n              </Grid>\n              <Grid item xs={12} alignSelf={'stretch'}>\n                <Typography\n                  component={'span'}\n                  display={'inline-flex'}\n                  flexDirection={isMobile ? 'column' : 'row'}\n                  variant={'body1'}\n                >\n                  <Typography component={'span'} color={'textSecondary'} marginRight={1}>\n                    {t('labelNFTID')}\n                  </Typography>\n                  <Link\n                    whiteSpace={'break-spaces'}\n                    style={{\n                      wordBreak: 'break-all',\n                      color: 'var(--color-text-third)',\n                    }}\n                    display={'inline-flex'}\n                    title={nftMintData.nftId}\n                    href={`${IPFS_LOOPRING_SITE}${nftMintData.cid}`}\n                    target='_blank'\n                    rel='noopener noreferrer'\n                  >\n                    #\n                    {' ' +\n                      getShortAddr(\n                        nftMintData?.nftIdView ? nftMintData.nftIdView : nftMintData.nftId ?? '',\n                      )}{' '}\n                    <LinkIcon color={'inherit'} fontSize={'medium'} />\n                  </Link>\n                </Typography>\n              </Grid>\n              <Grid item xs={12} alignSelf={'stretch'}>\n                <Typography\n                  component={'span'}\n                  display={'inline-flex'}\n                  flexDirection={isMobile ? 'column' : 'row'}\n                  variant={'body1'}\n                >\n                  <Typography component={'span'} color={'textSecondary'} marginRight={1}>\n                    {t('labelNFTContractAddress')}\n                  </Typography>\n                  <Typography\n                    component={'span'}\n                    color={'var(--color-text-third)'}\n                    whiteSpace={'break-spaces'}\n                    style={{ wordBreak: 'break-all' }}\n                  >\n                    {nftMintData.tokenAddress}\n                  </Typography>\n                </Typography>\n              </Grid>\n              <Grid item xs={12} alignSelf={'stretch'}>\n                <Typography\n                  display={'inline-flex'}\n                  flexDirection={isMobile ? 'column' : 'row'}\n                  variant={'body1'}\n                >\n                  <Typography component={'span'} color={'textSecondary'} marginRight={1}>\n                    {t('labelNFTType')}\n                  </Typography>\n                  <Typography\n                    component={'span'}\n                    color={'var(--color-text-third)'}\n                    whiteSpace={'break-spaces'}\n                    style={{ wordBreak: 'break-all' }}\n                    title={'ERC1155'}\n                  >\n                    {'ERC1155'}\n                  </Typography>\n                </Typography>\n              </Grid>\n              <Grid item xs={12}>\n                <Typography\n                  display={'inline-flex'}\n                  flexDirection={isMobile ? 'column' : 'row'}\n                  variant={'body1'}\n                >\n                  <Typography component={'span'} color={'textSecondary'} marginRight={1}>\n                    {t('labelNFTAmount')}\n                  </Typography>\n                  <Typography\n                    component={'span'}\n                    color={'var(--color-text-third)'}\n                    whiteSpace={'break-spaces'}\n                    style={{ wordBreak: 'break-all' }}\n                    title={'ERC1155'}\n                  >\n                    {nftMintData.tradeValue}\n                  </Typography>\n                </Typography>\n              </Grid>\n              <Grid item xs={12} alignSelf={'stretch'}>\n                <Typography color={'textSecondary'} marginRight={1}>\n                  {t('labelNFTDescription')}\n                </Typography>\n                <Box flex={1}>\n                  {metaData.description ? (\n                    <TextareaAutosizeStyled\n                      aria-label='NFT Description'\n                      minRows={2}\n                      maxRows={5}\n                      disabled={true}\n                      value={metaData.description}\n                    />\n                  ) : (\n                    <Typography\n                      color={'var(--color-text-third)'}\n                      whiteSpace={'break-spaces'}\n                      style={{ wordBreak: 'break-all' }}\n                      title={'ERC1155'}\n                      component={'span'}\n                    >\n                      {EmptyValueTag}\n                    </Typography>\n                  )}\n                </Box>\n              </Grid>\n              <Grid item xs={12} alignSelf={'stretch'}>\n                <Typography variant={'body1'} color={'textSecondary'}>\n                  {t('labelNFTProperty')}\n                </Typography>\n                {rawData.length ? (\n                  <Box marginTop={1} sx={{ backgroundColor: 'var(--color-global-bg)' }}>\n                    <TableStyle\n                      className={'properties_table'}\n                      rawData={rawData}\n                      {...{\n                        ...rest,\n                        tReady: true,\n                        t,\n                        currentheight: (rawData.length + 1) * RowConfig.rowHeight,\n                        columnMode: [\n                          {\n                            key: 'key',\n                            name: t('labelMintPropertyKey'),\n                            // formatter: ({ row }: any) => <>{row?.key}</>,\n                          },\n                          {\n                            key: 'value',\n                            name: t('labelMintPropertyValue'),\n                            // formatter: ({ row }: any) => <>{row?.value}</>,\n                          },\n                        ],\n                        generateRows: (rawData: any) => rawData,\n                        generateColumns: ({ columnsRaw }: any) =>\n                          columnsRaw as Column<any, unknown>[],\n                      }}\n                    />\n                  </Box>\n                ) : (\n                  <Typography\n                    color={'var(--color-text-third)'}\n                    whiteSpace={'break-spaces'}\n                    style={{ wordBreak: 'break-all' }}\n                    title={'ERC1155'}\n                    component={'span'}\n                  >\n                    {EmptyValueTag}\n                  </Typography>\n                )}\n              </Grid>\n              <Grid item xs={4} alignSelf={'stretch'}>\n                <Button\n                  fullWidth\n                  variant={'outlined'}\n                  size={'medium'}\n                  sx={{ height: 40 }}\n                  color={'primary'}\n                  onClick={() => {\n                    mintService.backMetaDataSetup()\n                  }}\n                >\n                  {t('labelMintPreview')}\n                </Button>\n              </Grid>\n              <Grid item xs={8} alignSelf={'stretch'}>\n                <Button\n                  fullWidth\n                  variant={'contained'}\n                  size={'medium'}\n                  color={'primary'}\n                  onClick={() => {\n                    onNFTMintClick()\n                  }}\n                  loading={\n                    !getDisabled && nftMintBtnStatus === TradeBtnStatus.LOADING ? 'true' : 'false'\n                  }\n                  disabled={getDisabled || nftMintBtnStatus === TradeBtnStatus.LOADING}\n                >\n                  {btnInfo ? t(btnInfo.label, btnInfo.params) : t(`labelNFTMintBtn`)}\n                </Button>\n              </Grid>\n            </Grid>\n          </Box>\n        </Grid>\n      </GridStyle>\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/RampConfirm.tsx",
    "content": "import { useTranslation } from 'react-i18next'\nimport { Box, Grid, Typography } from '@mui/material'\nimport {\n  EmptyValueTag,\n  FeeInfo,\n  IBData,\n  NFTWholeINFO,\n  TOAST_TIME,\n  TradeBtnStatus,\n} from '@loopring-web/common-resources'\nimport {\n  Button,\n  FeeSelect,\n  RampViewProps,\n  Toast,\n  ToastType,\n} from '../../index'\nimport { useSettings } from '../../../stores'\nimport React from 'react'\nexport const RampConfirm = <T extends IBData<I> & Partial<NFTWholeINFO>, I, C extends FeeInfo>({\n  tradeData,\n  onTransferClick,\n  realAddr,\n  disabled,\n  isFeeNotEnough,\n  handleFeeChange,\n  chargeFeeTokenList,\n  transferBtnStatus,\n  transferI18nKey,\n  feeInfo,\n  memo,\n  balanceNotEnough,\n}: RampViewProps<T, I, C> & { balanceNotEnough: boolean }) => {\n  const { isMobile } = useSettings()\n  const { t } = useTranslation()\n  const [open, setOpen] = React.useState(false)\n  const [showFeeModal, setShowFeeModal] = React.useState(false)\n  const handleToggleChange = (value: C) => {\n    if (handleFeeChange) {\n      handleFeeChange(value)\n    }\n  }\n  const getDisabled = React.useMemo(() => {\n    return disabled || transferBtnStatus === TradeBtnStatus.DISABLED\n  }, [disabled, transferBtnStatus])\n  return (\n    <Grid\n      className={'confirm'}\n      container\n      paddingLeft={isMobile ? 2 : 5 / 2}\n      paddingRight={isMobile ? 2 : 5 / 2}\n      direction={'column'}\n      alignItems={'stretch'}\n      flex={1}\n      height={'100%'}\n      minWidth={240}\n      flexWrap={'nowrap'}\n      spacing={2}\n    >\n      <Grid item xs={12}>\n        <Box\n          display={'flex'}\n          flexDirection={'column'}\n          justifyContent={'center'}\n          alignItems={'center'}\n          marginBottom={2}\n        >\n          <Typography component={'h4'} variant={isMobile ? 'h4' : 'h3'} whiteSpace={'pre'}>\n            {t('labelL2toRampTitle')}\n          </Typography>\n        </Box>\n      </Grid>\n      <Grid item xs={12}>\n        <Typography color={'var(--color-text-third)'} variant={'body1'}>\n          {t('labelL2toL2TokenAmount')}\n        </Typography>\n        <Typography color={'textPrimary'} marginTop={1} variant={'body1'}>\n          {tradeData?.tradeValue + ' '}\n          {tradeData?.belong}\n        </Typography>\n        {balanceNotEnough && (\n          <Typography\n            color={'var(--color-error)'}\n            variant={'body2'}\n            marginTop={1 / 4}\n            alignSelf={'stretch'}\n            position={'relative'}\n          >\n            {t('labelRampNoBalance', { belong: tradeData?.belong })}\n          </Typography>\n        )}\n      </Grid>\n      <Grid item xs={12}>\n        <Typography color={'var(--color-text-third)'} variant={'body1'}>\n          {t('labelL2toL2Address')}\n        </Typography>\n        <Typography color={'textPrimary'} marginTop={1} variant={'body1'}>\n          {realAddr}\n        </Typography>\n      </Grid>\n      <Grid item xs={12}>\n        <Typography color={'var(--color-text-third)'} variant={'body1'}>\n          {t('labelL2toL2AddressType')}\n        </Typography>\n        <Typography color={'textPrimary'} marginTop={1} variant={'body1'}>\n          {t('labelWalletTypeOptions', { type: 'Ramp' })}\n        </Typography>\n      </Grid>\n      <Grid item xs={12}>\n        <Typography color={'var(--color-text-third)'} variant={'body1'}>\n          {t('labelMemo')}\n        </Typography>\n        <Typography color={'textPrimary'} marginTop={1} variant={'body1'}>\n          {memo ?? EmptyValueTag}\n        </Typography>\n      </Grid>\n\n      <Grid item xs={12} alignSelf={'stretch'} position={'relative'}>\n        {!chargeFeeTokenList?.length ? (\n          <Typography>{t('labelFeeCalculating')}</Typography>\n        ) : (\n          <>\n            <FeeSelect\n                  chargeFeeTokenList={chargeFeeTokenList}\n                  handleToggleChange={(fee: FeeInfo) => {\n                    handleToggleChange(fee as C)\n                    setShowFeeModal(false)\n                  }}\n                  feeInfo={feeInfo as FeeInfo}\n                  open={showFeeModal}\n                  onClose={() => {\n                    setShowFeeModal(false)\n                  }}\n                  isFeeNotEnough={isFeeNotEnough.isFeeNotEnough}\n                  feeLoading={isFeeNotEnough.isOnLoading}\n                  onClickFee={() => setShowFeeModal((prev) => !prev)}\n                />\n          </>\n        )}\n      </Grid>\n\n      <Grid item marginTop={2} alignSelf={'stretch'} paddingBottom={0}>\n        <Button\n          fullWidth\n          variant={'contained'}\n          size={'medium'}\n          color={'primary'}\n          onClick={async () => {\n            if (onTransferClick) {\n              await onTransferClick({ ...tradeData, memo } as unknown as T)\n            } else {\n              setOpen(true)\n            }\n          }}\n          loading={!getDisabled && transferBtnStatus === TradeBtnStatus.LOADING ? 'true' : 'false'}\n          disabled={getDisabled || transferBtnStatus === TradeBtnStatus.LOADING}\n        >\n          {t(transferI18nKey ?? `labelConfirm`)}\n        </Button>\n      </Grid>\n      <Toast\n        alertText={t('errorBase', { ns: 'error' })}\n        open={open}\n        autoHideDuration={TOAST_TIME}\n        onClose={() => {\n          setOpen(false)\n        }}\n        severity={ToastType.error}\n      />\n    </Grid>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/ResetWrap.tsx",
    "content": "import { Trans, WithTranslation } from 'react-i18next'\nimport React from 'react'\nimport { Grid, InputAdornment, Link, TextField, Tooltip, Typography } from '@mui/material'\nimport {\n  EmptyValueTag,\n  FeeInfo,\n  Info2Icon,\n  L1L2_NAME_DEFINED,\n  MapChainId,\n  TradeBtnStatus,\n} from '@loopring-web/common-resources'\nimport { Button } from '../../basic-lib'\nimport { ResetViewProps } from './Interface'\nimport { useSettings } from '../../../stores'\nimport { FeeSelect } from '../../../components/modal'\n\nexport const ResetWrap = <T extends FeeInfo>({\n  t,\n  resetBtnStatus,\n  onResetClick,\n  isNewAccount = false,\n  isFeeNotEnough,\n  feeInfo,\n  disabled = false,\n  chargeFeeTokenList = [],\n  goToDeposit,\n  walletMap,\n  isReset = false,\n  handleFeeChange,\n}: ResetViewProps<T> & WithTranslation) => {\n  const [showFeeModal, setShowFeeModal] = React.useState(false)\n  const { referralCode, setReferralCode } = useSettings()\n  const [value, setValue] = React.useState(referralCode)\n  const { isMobile, defaultNetwork } = useSettings()\n\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const getDisabled = React.useMemo(() => {\n    return disabled || resetBtnStatus === TradeBtnStatus.DISABLED\n  }, [disabled, resetBtnStatus])\n\n  const handleToggleChange = (value: T) => {\n    if (handleFeeChange) {\n      handleFeeChange(value)\n    }\n  }\n  const onRefChange = (e: any) => {\n    const regex = /^[0-9\\b]+$/\n    if (e?.target?.value === '' || regex.test(e?.target.value)) {\n      setValue(e.target.value)\n      if (e.target.value.length >= 5) {\n        setReferralCode(e.target.value)\n      }\n\n      // searchParams.set('referralcode', e.target.value)\n      // history.replace({ search: searchParams.toString() })\n    }\n  }\n\n  return (\n    <Grid\n      container\n      direction={'column'}\n      justifyContent={'space-between'}\n      alignItems={'center'}\n      flex={1}\n      paddingLeft={5 / 2}\n      paddingRight={5 / 2}\n      height={'100%'}\n      minWidth={320}\n    >\n      <Grid item marginBottom={2}>\n        <Typography\n          component={'h4'}\n          textAlign={'center'}\n          variant={isMobile ? 'h4' : 'h3'}\n          whiteSpace={'pre'}\n          marginBottom={2}\n        >\n          {isNewAccount\n            ? t('labelActiveAccountTitle', {\n                loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n              })\n            : t('resetTitle', { layer2: L1L2_NAME_DEFINED[network].layer2 })}\n        </Typography>\n        <Typography component={'p'} variant='body1' color={'var(--color-text-secondary)'}>\n          {isNewAccount\n            ? t('labelActiveAccountDescription', {\n                layer2: L1L2_NAME_DEFINED[network].layer2,\n                l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n              })\n            : t('labelResetDescription', {\n                layer2: L1L2_NAME_DEFINED[network].layer2,\n                l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n              })}\n        </Typography>\n      </Grid>\n\n      <Grid item alignSelf={'stretch'} position={'relative'} marginTop={1}>\n        {!chargeFeeTokenList?.length ? (\n          <Typography>{t('labelFeeCalculating')}</Typography>\n        ) : (\n          <>\n\n            <FeeSelect\n              disableNoToken={true}\n              chargeFeeTokenList={chargeFeeTokenList}\n              handleToggleChange={(fee: FeeInfo) => {\n                handleToggleChange(fee as T)\n                setShowFeeModal(false)\n              }}\n              feeInfo={feeInfo}\n              open={showFeeModal}\n              onClose={() => {\n                setShowFeeModal(false)\n              }}\n              middleContent={\n                <>\n                  {isNewAccount && feeInfo?.fee?.toString() == '0' ? (\n                    <Typography color={'var(--color-success)'} marginLeft={1} component={'span'}>\n                      {t('labelFriendsPayActivation', {\n                        l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                        loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                        l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                        l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                        ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                      })}\n                    </Typography>\n                  ) : (\n                    ''\n                  )}\n                  {isNewAccount && (\n                    <Typography\n                      component={'span'}\n                      display={'flex'}\n                      alignItems={'center'}\n                      variant={'body1'}\n                      color={'var(--color-text-secondary)'}\n                      marginTop={1}\n                      marginBottom={1}\n                    >\n                      {t('labelYourBalance', {\n                        balance:\n                          walletMap && feeInfo && feeInfo.belong && walletMap[feeInfo.belong]\n                            ? walletMap[feeInfo.belong]?.count + ' ' + feeInfo.belong\n                            : EmptyValueTag + ' ' + (feeInfo && feeInfo?.belong),\n                        layer2: L1L2_NAME_DEFINED[network].layer2,\n                        l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                        loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                        l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                        l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                        ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                      })}\n                    </Typography>\n                  )}\n                </>\n              }\n              isFeeNotEnough={isFeeNotEnough && isFeeNotEnough.isFeeNotEnough}\n              feeLoading={isFeeNotEnough && isFeeNotEnough.isOnLoading}\n              onClickFee={() => setShowFeeModal((prev) => !prev)}\n              feeNotEnoughContent={\n                <Typography marginLeft={1} component={'span'} color={'var(--color-error)'}>\n                  {isNewAccount && goToDeposit ? (\n                    <Trans i18nKey={'labelActiveAccountFeeNotEnough'}>\n                      Insufficient balance\n                      <Link\n                        onClick={() => {\n                          goToDeposit()\n                        }}\n                        variant={'body2'}\n                      >\n                        Add assets\n                      </Link>\n                    </Trans>\n                  ) : (\n                    t('labelL2toL2FeeNotEnough')\n                  )}\n                </Typography>\n              }\n            />\n          </>\n        )}\n      </Grid>\n      {isNewAccount && !isReset && (\n        <Grid item alignSelf={'stretch'} position={'relative'} marginTop={2}>\n          <Tooltip title={t('labelReferralToolTip').toString()}>\n            <Typography\n              component={'span'}\n              variant={'body1'}\n              color={'textSecondary'}\n              display={'inline-flex'}\n              alignItems={'center'}\n              marginBottom={1}\n            >\n              <Trans i18nKey={'labelReferralCode'}>\n                Referral Code (Optional)\n                <Info2Icon fontSize={'small'} color={'inherit'} sx={{ marginX: 1 / 2 }} />\n              </Trans>\n            </Typography>\n          </Tooltip>\n          <TextField\n            value={value}\n            fullWidth\n            variant={'outlined'}\n            inputProps={{ maxLength: 10 }}\n            InputProps={{\n              startAdornment: (\n                <InputAdornment position='start'>\n                  <Typography\n                    color={'var(--color-text-third)'}\n                    variant={'body1'}\n                    component={'span'}\n                    paddingX={1 / 2}\n                  >\n                    #\n                  </Typography>\n                </InputAdornment>\n              ),\n            }}\n            type={'text'}\n            onChange={onRefChange}\n            // onChange={(event) =>\n            //   handleOnMetaChange({ name: event.target.value } as Partial<T>)\n            // }\n          />\n        </Grid>\n      )}\n\n      <Grid item marginTop={4} alignSelf={'stretch'}>\n        <Button\n          fullWidth\n          variant={'contained'}\n          size={'medium'}\n          color={'primary'}\n          onClick={() => {\n            if (onResetClick) {\n              onResetClick({})\n            }\n          }}\n          loading={!getDisabled && resetBtnStatus === TradeBtnStatus.LOADING ? 'true' : 'false'}\n          disabled={\n            getDisabled ||\n            resetBtnStatus === TradeBtnStatus.DISABLED ||\n            resetBtnStatus === TradeBtnStatus.LOADING\n          }\n        >\n          {isNewAccount ? t(`labelActiveAccountBtn`) : t(`resetLabelBtn`)}\n        </Button>\n      </Grid>\n    </Grid>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/Styled.ts",
    "content": "import styled from '@emotion/styled'\nimport {\n  Box,\n  Grid,\n  IconButton,\n  IconProps,\n  LinearProgress,\n  linearProgressClasses,\n  Tabs,\n} from '@mui/material'\nimport { css } from '@emotion/react'\nimport { Button } from '../../basic-lib'\nimport { DropDownIcon } from '@loopring-web/common-resources'\n\n\nexport const FeeTokenItemWrapper = styled(Box)`\n  background-color: var(--color-global-bg);\n` as typeof Box\n\nexport const DropdownIconStyled = styled(DropDownIcon)<IconProps>`\n  transform: rotate(\n    ${({ status }: any) => {\n      return status === 'down' ? '0deg' : '180deg'\n    }}\n  );\n` as unknown as (props: IconProps & { status: string }) => JSX.Element\n\nexport const BorderLinearProgress = styled(LinearProgress)(({ theme }) => ({\n  height: 10,\n  borderRadius: 5,\n  [`&.${linearProgressClasses.colorPrimary}`]: {\n    backgroundColor: theme.colorBase.textSecondary, //theme.palette.grey[theme.palette.mode === 'light' ? 200 : 800],\n  },\n  [`& .${linearProgressClasses.bar}`]: {\n    borderRadius: 5,\n    backgroundColor: theme.colorBase.primary,\n  },\n}))\nexport const IconClearStyled = styled(IconButton)`\n  position: absolute;\n  top: 20px;\n  right: 4px;\n` as typeof IconButton\n\nexport const IconButtonStyled = styled(IconButton)`\n  .MuiToolbar-root &.MuiButtonBase-root {\n    svg {\n    }\n\n    &.outlined {\n      background-color: var(--color-box);\n      margin: 0 ${({ theme }) => theme.unit / 2}px;\n      ${({ theme }) => theme.border.defaultFrame({ c_key: 'transparent' })};\n\n      &:last-child {\n        margin-right: 0;\n      }\n    }\n  }\n` as typeof IconButton\n\nconst cssAutoRefresh = (_props: any) => css`\n  @keyframes rotate {\n    25% {\n      transform: rotate(-135deg);\n    }\n    50% {\n      transform: rotate(-135deg);\n    }\n    75% {\n      transform: rotate(-315deg);\n    }\n    100% {\n      transform: rotate(-315deg);\n    }\n  }\n\n  @keyframes hide1 {\n    25% {\n      left: -0.5em;\n      opacity: 0;\n    }\n    50% {\n      left: 0;\n      opacity: 1;\n    }\n  }\n\n  @keyframes hide2 {\n    25% {\n      right: -0.5em;\n      opacity: 0;\n    }\n    50% {\n      right: 0;\n      opacity: 1;\n    }\n  }\n\n  @keyframes container {\n    25% {\n      transform: translate3d(0, -50%, 0);\n      width: 0.5em;\n    }\n    50% {\n      transform: translate3d(-100%, -50%, 0);\n      width: 0.5em;\n    }\n    75% {\n      transform: translate3d(-50%, -50%, 0);\n      width: 1em;\n    }\n  }\n`\nexport const CountDownStyled = styled(Box)<{countDownSeconds?: number}>`\n  ${({ theme }) => cssAutoRefresh({ theme })}\n  width: var(--btn-icon-size);\n  height: var(--btn-icon-size);\n  position: relative;\n  background-size: 68%;\n  background-repeat: no-repeat;\n  background-position: center;\n\n  &.outlined {\n    background-color: var(--field-opacity);\n    margin: 0 ${({ theme }) => theme.unit / 2}px;\n    ${({ theme }) => theme.border.defaultFrame({ c_key: 'transparent' })};\n    text-align: center;\n    line-height: var(--btn-icon-size);\n\n    &:last-child {\n      margin-right: 0;\n    }\n  }\n\n  &.logo {\n    background-image: ${({ color }) =>\n      `url(\"data:image/svg+xml,%3Csvg width='34' height='27' viewBox='0 0 34 27' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fillRule='evenodd' clipRule='evenodd' d='M19.354 12.7874H33.4527V12.8709L11.4393 26.1381L22.351 17.5019L19.354 12.7874ZM11.1439 0V26.3259L0 17.5228L11.1439 0Z' fill='${encodeURIComponent(\n        color ? (color as string) : 'var(--auto-refresh-color)',\n      )}'/%3E%3C/svg%3E%0A\")`};\n  }\n\n  &.countdown {\n    font-size: ${({ theme }) => theme.fontDefault.h6};\n    display: inline-block;\n    color: var(--color-primary);\n\n    .circle {\n      font-size: ${({ theme }) => theme.fontDefault.h4};\n      width: 1em;\n      height: 1em;\n      position: absolute;\n      left: 50%;\n      top: 50%;\n      transform: translate3d(-50%, -50%, 0);\n      animation: container ${({countDownSeconds}) => countDownSeconds ? `${(countDownSeconds - 1) * 2}s` : 'var(--durationInternal)'} steps(1) infinite;\n      overflow: hidden;\n\n      &::before,\n      &::after {\n        display: block;\n        content: '';\n        box-sizing: border-box;\n        border: .125em solid transparent;\n        border-radius: 50%;\n        position: absolute;\n        top: 0;\n        bottom: 0;\n        width: 1em;\n        transform: rotate(45deg);\n        animation-timing-function: linear, steps(1);\n        animation-duration: ${({countDownSeconds}) => countDownSeconds ? `${(countDownSeconds - 1) * 2}s` : 'var(--durationInternal)'}, ${({countDownSeconds}) => countDownSeconds ? `${(countDownSeconds - 1) * 2}s` : 'var(--durationInternal)'};\n        animation-iteration-count: infinite, infinite;\n      }\n\n      &::before {\n        border-color: ${({ color }) =>\n          color\n            ? `transparent transparent ${color} ${color}`\n            : 'transparent transparent var(--auto-refresh-color) var(--auto-refresh-color)'};\n        animation-name: rotate, hide1;\n        left: 0;\n      }\n\n      &::after {\n        border-color: ${({ color }) =>\n          color\n            ? `${color} ${color} transparent transparent`\n            : 'var(--auto-refresh-color) var(--auto-refresh-color) transparent transparent'};\n        animation-delay: ${({countDownSeconds}) => countDownSeconds ? `${(countDownSeconds - 1) / 2}s` : 'var(--delay)'}, ${({countDownSeconds}) => countDownSeconds ? `${(countDownSeconds - 1) / 2}s` : 'var(--delay)'};\n        animation-name: rotate, hide2;\n        right: 0;\n      }\n    }\n` as typeof Box\n\nexport const ButtonStyle = styled(Button)`\n  font-size: 1.6rem;\n  &.MuiButton-root.Mui-disabled {\n  ${({ loading }) => {\n    return (\n      loading === 'true' &&\n      ` &.vaultInProcessing{\n           &::after{  \n           \n           }\n         }`\n    )\n  }}` as typeof Button\n\nexport const TabsStyle = styled(Tabs)`\n  &&.trade-tabs {\n    background: var(--color-global-bg);\n    min-height: 28px;\n    height: 28px;\n    border-radius: ${({ theme }) => theme.unit / 2}px;\n    margin-top: ${({ theme }) => theme.unit * 2}px;\n\n    .MuiTab-fullWidth.MuiTab-root {\n      min-height: 28px;\n      height: 28px;\n      line-height: 28px;\n      padding: 0;\n      font-size: ${({ theme }) => theme.fontDefault.h6};\n      &:focus-visible,\n      &:active:after {\n        background-color: initial;\n      }\n      &.Mui-selected {\n        overflow: unset;\n        border-radius: ${({ theme }) => theme.unit / 2}px;\n        color: var(--color-text-button);\n        min-height: 28px;\n        height: 28px;\n\n        &.trade-tab-buy {\n          background: var(--color-success);\n        }\n\n        &.trade-tab-sell {\n          background: var(--color-error);\n        }\n\n        &.trade-tab-quantity,\n        &.trade-tab-speed {\n          background: var(--color-primary);\n        }\n\n        &.trade-tab-sell:after,\n        &.trade-tab-speed:after {\n          background-color: var(--color-error);\n          mask-size: cover;\n          mask-image: url('data:image/svg+xml,\\\n           <svg width=\"17\" height=\"28\" viewBox=\"0 0 17 28\" fill=\"white\" xmlns=\"http://www.w3.org/2000/svg\">\\\n           <path d=\"M0 0H12.4213C15.1599 0 17.0886 2.68993 16.2098 5.28363L9.43321 25.2836C8.88302 26.9074 7.35922 28 5.64476 28H0V0Z\" />\\\n           </svg>');\n          top: 0;\n          height: 28px;\n          left: -8px;\n          width: 17px;\n          transform: rotate(180deg);\n        }\n\n        &.trade-tab-buy:after,\n        &.trade-tab-quantity:after {\n          background-color: var(--color-success);\n          mask-size: cover;\n          mask-image: url('data:image/svg+xml,\\\n           <svg width=\"17\" height=\"28\" viewBox=\"0 0 17 28\" fill=\"white\" xmlns=\"http://www.w3.org/2000/svg\">\\\n           <path d=\"M0 0H12.4213C15.1599 0 17.0886 2.68993 16.2098 5.28363L9.43321 25.2836C8.88302 26.9074 7.35922 28 5.64476 28H0V0Z\" />\\\n           </svg>');\n          top: 0;\n          left: auto;\n          height: 28px;\n          right: -8px;\n          width: 17px;\n        }\n\n        &.trade-tab-quantity:after,\n        &.trade-tab-speed:after {\n          background-color: var(--color-primary);\n          margin: 0;\n        }\n      }\n    }\n  }\n` as typeof Tabs\n\nconst loadingGif = './static/loading-1.gif'\nexport const GridWrapStyle = styled(Grid)`\n  &.loading {\n    position: relative;\n\n    &:after {\n      content: '';\n      display: block;\n      position: absolute;\n      top: 0;\n      left: 0;\n      right: 0;\n      bottom: 0;\n      background: url(${loadingGif}) no-repeat 50% 50%;\n      background-size: 80px;\n    }\n  }\n` as typeof Grid\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/SwapWrap/Interface.ts",
    "content": "import { SwapTradeData, SwitchData } from '../../Interface'\nimport { InputButtonProps } from '../../../basic-lib'\nimport { CoinInfo, TokenType, TradeBtnStatus } from '@loopring-web/common-resources'\n\nexport type SwapData<ST> = {\n  type: 'buy' | 'sell' | 'exchange'\n} & SwitchData<ST>\n\nexport type SwapMenuListProps<T, TCD> = {\n  tokenType?: TokenType\n  swapData: SwapData<SwapTradeData<T>>\n  onChangeEvent: (index: 0 | 1, data: SwapData<SwapTradeData<T>>) => void\n  tradeCalcData: TCD\n}\n\n/**\n * private props\n */\nexport type SwapTradeBaseProps<T, I, TCD> = {\n  disabled?: boolean\n  isStob?: boolean\n  swapBtnI18nKey?: string\n  swapBtnStatus?: keyof typeof TradeBtnStatus | undefined\n  tradeCalcData: TCD\n  tokenSellProps?: Partial<InputButtonProps<T, I, CoinInfo<I>>>\n  tokenBuyProps?: Partial<InputButtonProps<T, I, CoinInfo<I>>>\n  classWrapName?: string\n  BtnEle?: JSX.Element\n  marginLevelChange?: {\n    from: {\n      marginLevel: string\n      type: 'safe' | 'warning' | 'danger' \n    }\n    to: {\n      marginLevel: string\n      type: 'safe' | 'warning' | 'danger'\n    }\n  }\n  vaultLeverage?: {\n    leverage: string\n    hideLeverage: boolean\n    onClickLeverage: () => void\n  }\n}\nexport type SwapTradeBaseEventProps<T, I> = {\n  onSwapClick: () => void | any\n  onCancelClick?: () => void | any\n} & Partial<Pick<InputButtonProps<T, I, unknown>, 'handleError'>>\n\nexport type SwapTradeExtendProps<T> = {\n  switchStobEvent?: (value: boolean) => void\n  onChangeEvent: (index: 0 | 1, data: SwapData<SwapTradeData<T>>) => void\n}\nexport type SwapTradeProps<T, I, TCD> = SwapTradeBaseProps<T, I, TCD> &\n  SwapTradeExtendProps<T> &\n  SwapTradeBaseEventProps<T, I> & {\n    tradeData: SwapTradeData<T>\n  }\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/SwapWrap/SwapMenuList.tsx",
    "content": "import { SwitchData } from '../../Interface'\nimport { IBData, TradeCalcData } from '@loopring-web/common-resources'\nimport { WithTranslation } from 'react-i18next'\nimport React from 'react'\nimport { TradeMenuList } from '../tool'\nimport { SwapMenuListProps } from './Interface'\n\nexport function SwapMenuList<T extends IBData<I>, I, TCD extends TradeCalcData<I>>({\n  onChangeEvent,\n  tradeCalcData,\n  swapData,\n  tokenType,\n  ...rest\n}: SwapMenuListProps<T, TCD> & WithTranslation) {\n  const selected: string | undefined = swapData.tradeData[swapData.type].belong\n    ? swapData.tradeData[swapData.type]?.belong\n    : ''\n  const tradeData = swapData.tradeData[swapData.type]\n  const coinMap =\n    swapData.type === 'sell' ? tradeCalcData?.coinInfoMap : (tradeCalcData?.buyCoinInfoMap as any)\n  const walletMap = tradeCalcData?.walletMap as any //IBData<I>\n  const handleOnChangeIndex = React.useCallback(\n    (index: 0 | 1, { tradeData, to }: SwitchData<IBData<I>>) => {\n      onChangeEvent(index, {\n        ...swapData,\n        tradeData: { ...swapData.tradeData, [swapData.type]: tradeData },\n        to: to,\n      })\n    },\n    [swapData, onChangeEvent],\n  )\n  return (\n    <TradeMenuList\n      {...{\n        tokenType,\n        nonZero: false,\n        sorted: true,\n        ...rest,\n        selected,\n        tradeData,\n        coinMap,\n        walletMap,\n        onChangeEvent: handleOnChangeIndex,\n      }}\n    />\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/SwapWrap/SwapTradeWrap.tsx",
    "content": "import { SwapTradeData } from '../../Interface'\nimport {\n  BtradeTradeCalcData,\n  BtradeType,\n  CoinInfo,\n  CoinMap,\n  defaultSlipage,\n  EmptyValueTag,\n  getValuePrecisionThousand,\n  IBData,\n  Info2Icon,\n  L1L2_NAME_DEFINED,\n  MapChainId,\n  myLog,\n  ReverseIcon,\n  SwapExchangeIcon,\n  SwapTradeCalcData,\n  TradeBtnStatus,\n  VaultSwapStep,\n  VaultTradeCalcData,\n} from '@loopring-web/common-resources'\nimport { Trans, WithTranslation } from 'react-i18next'\nimport React from 'react'\nimport { Box, Grid, Tooltip, Typography, Link, Tab } from '@mui/material'\nimport { InputButton } from '../../../basic-lib'\nimport { SwapTradeProps } from './Interface'\nimport { useSettings } from '../../../../stores'\nimport { ButtonStyle, IconButtonStyled, TabsStyle } from '../Styled'\nimport { useHistory } from 'react-router-dom'\nimport styled from '@emotion/styled'\nimport { marginLevelTypeToColor } from '../VaultWrap/utils'\nimport { numberFormat } from '@loopring-web/core'\nimport EastIcon from '@mui/icons-material/East';\n\nconst GridStyle = styled(Grid)`\n  .buyInput {\n    margin-top: ${({ theme }) => 1 * theme.unit}px;\n  }\n\n  .iconChange {\n    top: var(--input-height-swap);\n    transform: translateY(-50%);\n  }\n`\nexport const SwapTradeWrap = <\n  T extends IBData<I>,\n  I,\n  TCD extends BtradeTradeCalcData<I> | VaultTradeCalcData<I> | SwapTradeCalcData<I>,\n>({\n  t,\n  onChangeEvent,\n  isStob,\n  switchStobEvent,\n  tradeData,\n  disabled,\n  handleError,\n  swapBtnStatus,\n  onSwapClick,\n  swapBtnI18nKey,\n  tradeCalcData,\n  tokenSellProps,\n  tokenBuyProps,\n  onCancelClick,\n  BtnEle,\n  covertOnClickPreCheck,\n  marginLevelChange,\n  ...rest\n}: SwapTradeProps<T, I, TCD> & WithTranslation) => {\n  const sellRef = React.useRef()\n  const buyRef = React.useRef()\n  const history = useHistory()\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const [_isStoB, setIsStoB] = React.useState(typeof isStob !== 'undefined' ? isStob : true)\n\n  const buySymbol = (tradeCalcData as any)?.belongBuyAlice ?? tradeData?.buy?.belong\n  const sellSymbol = (tradeCalcData as any)?.belongSellAlice ?? tradeData?.sell?.belong\n  const _onSwitchStob = React.useCallback(\n    (_event: any) => {\n      setIsStoB(!_isStoB)\n      if (typeof switchStobEvent === 'function') {\n        switchStobEvent(!_isStoB)\n      }\n    },\n    [switchStobEvent, _isStoB],\n  )\n\n  const getDisabled = React.useCallback(() => {\n    return disabled || tradeCalcData === undefined || tradeCalcData.coinInfoMap === undefined\n  }, [disabled, tradeCalcData])\n\n  const handleOnClick = React.useCallback(\n    (_event: React.MouseEvent, _name: string, ref: any) => {\n      const focus: 'buy' | 'sell' = ref.current === buyRef.current ? 'buy' : 'sell'\n      onChangeEvent(1, {\n        tradeData,\n        type: focus,\n        to: 'menu',\n      })\n    },\n    [tradeData, onChangeEvent],\n  )\n  const handleCountChange = React.useCallback(\n    (ibData: IBData<I>, _name: string, _ref: any) => {\n      const focus: 'buy' | 'sell' = _ref?.current === buyRef.current ? 'buy' : 'sell'\n      if (tradeData[focus].tradeValue !== ibData.tradeValue) {\n        onChangeEvent(0, {\n          tradeData: { ...tradeData, [focus]: ibData },\n          type: focus,\n          to: 'button',\n        })\n      }\n    },\n    [tradeData, onChangeEvent],\n  )\n  const covertOnClick = React.useCallback(() => {\n    onChangeEvent(0, {\n      tradeData: {\n        sell: tradeData.buy,\n        buy: tradeData.sell,\n      } as SwapTradeData<T>,\n      type: 'exchange',\n      to: 'button',\n    })\n  }, [tradeData, onChangeEvent])\n\n  if (typeof handleError !== 'function') {\n    handleError = ({ belong, balance, tradeValue }: any) => {\n      if (balance < tradeValue || (tradeValue && !balance)) {\n        const _error = {\n          error: true,\n          message: t('tokenNotEnough', { belong: belong }),\n        }\n        return _error\n      }\n      return { error: false, message: '' }\n    }\n  }\n  const propsSell = {\n    label: t('tokenEnterPaymentToken'),\n    subLabel: t('tokenMax'),\n    emptyText: t('tokenSelectToken'),\n    placeholderText: '0.00',\n    maxAllow: true,\n    ...tokenSellProps,\n    isShowCoinInfo: true,\n    isShowCoinIcon: true,\n    handleError,\n    handleCountChange,\n    handleOnClick,\n    ...rest,\n  } as any\n  const propsBuy = {\n    label: t('tokenEnterReceiveToken'),\n    // subLabel: t('tokenHave'),\n    emptyText: t('tokenSelectToken'),\n    placeholderText: '0.00',\n    maxAllow: false,\n    ...tokenBuyProps,\n    isShowCoinInfo: true,\n    isShowCoinIcon: true,\n    handleCountChange,\n    handleOnClick,\n    ...rest,\n  } as any\n  const label = React.useMemo(() => {\n    myLog(swapBtnI18nKey, 'swapBtnI18nKey useMemo')\n    const keyParams = {\n      layer2: L1L2_NAME_DEFINED[network].layer2,\n      l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n      loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n      l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n      l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n      ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n    }\n    if (swapBtnI18nKey) {\n      const key = swapBtnI18nKey.split('|')\n      if (key) {\n        return t(\n          key[0],\n          key && key[1]\n            ? {\n                arg: key[1],\n                ...keyParams,\n              }\n            : {\n                ...keyParams,\n              },\n        )\n      } else {\n        return t(swapBtnI18nKey, {\n          ...keyParams,\n        })\n      }\n    } else {\n      const label = (tradeCalcData as any)?.isBtrade\n        ? `labelBtradeSwapBtn`\n        : (tradeCalcData as any)?.isVault\n        ? `labelVaultSwapBtn`\n        : `swapBtn`\n      return t(label, {\n        ...keyParams,\n      })\n    }\n  }, [t, swapBtnI18nKey, network, tradeCalcData])\n  const showVal = buySymbol && sellSymbol && tradeCalcData?.StoB\n  const isL2Swap = !((tradeCalcData as any)?.isBtrade || (tradeCalcData as any)?.isVault)\n  const convertStr = _isStoB\n    ? `1 ${sellSymbol} \\u2248 ${\n        tradeCalcData.StoB && tradeCalcData.StoB !== 'NaN' ? tradeCalcData.StoB : EmptyValueTag\n      } ${buySymbol}`\n    : `1 ${buySymbol} \\u2248 ${\n        tradeCalcData.BtoS && tradeCalcData.BtoS !== 'NaN' ? tradeCalcData.BtoS : EmptyValueTag\n      } ${sellSymbol}`\n  const priceImpactColor = (tradeCalcData as any)?.priceImpactColor\n    ? (tradeCalcData as any).priceImpactColor\n    : 'textPrimary'\n  const priceImpact =\n    (tradeCalcData as any)?.priceImpact !== undefined\n      ? getValuePrecisionThousand(\n          (tradeCalcData as any).priceImpact,\n          undefined,\n          undefined,\n          2,\n          true,\n        ) + ' %'\n      : EmptyValueTag\n\n  const fee =\n    tradeCalcData && tradeCalcData.fee\n      ? `${tradeCalcData.fee} ${buySymbol}` //(parseFloat(tradeCalcData.fee) / 100).toString() + \"%\"\n      : EmptyValueTag\n  myLog('tradeCalcDatatradeCalcData', tradeCalcData)\n  myLog('tradeCalcDatatradeCalcData', tradeData)\n\n  const userTakerRate =\n    tradeCalcData && tradeCalcData.feeTakerRate\n      ? (tradeCalcData.feeTakerRate / 100).toString()\n      : EmptyValueTag\n  const tradeCostMin =\n    tradeCalcData && tradeCalcData.tradeCost\n      ? `${tradeCalcData.tradeCost} ${buySymbol}` //(parseFloat(tradeCalcData.fee) / 100).toString() + \"%\"\n      : EmptyValueTag\n\n  const minimumConverted =\n    tradeCalcData && tradeCalcData.minimumConverted\n      ? `${tradeCalcData.minimumConverted}  ${buySymbol}`\n      : EmptyValueTag\n  const { isMobile } = useSettings()\n\n  return (\n    <GridStyle\n      className={tradeCalcData ? 'trade-panel' : 'trade-panel loading'}\n      paddingLeft={5 / 2}\n      paddingRight={5 / 2}\n      container\n      direction={'column'}\n      flexWrap={'nowrap'}\n      justifyContent={'space-between'}\n      flex={isMobile ? '1' : 'initial'}\n      height={'100%'}\n    >\n      {(tradeCalcData as any)?.isBtrade && (\n        <Box\n          className={'tool-bar'}\n          display={'flex'}\n          alignItems={'center'}\n          justifyContent={'center'}\n        >\n          <Box component={'header'} width={'100%'}>\n            <TabsStyle\n              className={'trade-tabs swap'}\n              variant={'fullWidth'}\n              value={tradeData.btradeType}\n              onChange={(_e, value) =>\n                onChangeEvent(0, {\n                  tradeData: {\n                    ...tradeData,\n                    btradeType: value,\n                  } as SwapTradeData<T>,\n                  type: (tradeCalcData as unknown as any)?.lastStepAt ?? 'sell',\n                  to: 'button',\n                })\n              }\n            >\n              <Tab\n                className={'trade-tab-quantity'}\n                value={BtradeType.Quantity}\n                label={t('labelBtrade' + BtradeType.Quantity)}\n              />\n              <Tab\n                className={'trade-tab-speed'}\n                value={BtradeType.Speed}\n                label={t('labelBtrade' + BtradeType.Speed)}\n              />\n            </TabsStyle>\n          </Box>\n        </Box>\n      )}\n      <Grid\n        item\n        marginTop={!isL2Swap ? 1 : 3}\n        display={'flex'}\n        alignSelf={'stretch'}\n        justifyContent={'flex-start'}\n        alignItems={'stretch'}\n        flexDirection={'column'}\n        flexBasis={'initial'}\n        position={'relative'}\n      >\n        <InputButton<any, I, CoinInfo<I>>\n          ref={sellRef}\n          disabled={getDisabled()}\n          className={'swapWrap'}\n          order={'left'}\n          {...{\n            ...propsSell,\n            isHideError: true,\n            inputData: tradeData ? tradeData.sell : ({} as any),\n            coinMap:\n              tradeCalcData && tradeCalcData.coinInfoMap\n                ? tradeCalcData.coinInfoMap\n                : ({} as CoinMap<I, CoinInfo<I>>),\n          }}\n        />\n        <Box\n          className={'iconChange'}\n          alignSelf={'center'}\n          marginY={1}\n          position={'absolute'}\n          zIndex={99}\n          sx={{\n            boxSizing: 'border-box',\n            border: '3px solid var(--color-box)',\n            background: 'var(--color-box-secondary)',\n            borderRadius: '50%',\n          }}\n        >\n          <IconButtonStyled\n            size={'large'}\n            sx={{\n              height: 'var(--btn-icon-size-large) !important',\n              width: 'var(--btn-icon-size-large) !important',\n            }}\n            onClick={() => {\n              if (!covertOnClickPreCheck || covertOnClickPreCheck()) {\n                covertOnClick()\n              }\n            }}\n            aria-label={t('tokenExchange')}\n          >\n            <SwapExchangeIcon fontSize={'large'} htmlColor={'var(--color-text-primary)'} />\n          </IconButtonStyled>\n        </Box>\n\n        <InputButton<any, I, CoinInfo<I>>\n          ref={buyRef}\n          disabled={getDisabled()}\n          className={'swapWrap buyInput'}\n          order={'left'}\n          {...{\n            ...propsBuy,\n            // maxAllow:false,\n            isHideError: true,\n\n            inputData: tradeData ? tradeData.buy : ({} as any),\n            coinMap:\n              tradeCalcData && tradeCalcData.coinInfoMap\n                ? tradeCalcData.coinInfoMap\n                : ({} as CoinMap<I, CoinInfo<I>>),\n          }}\n        />\n        {!isL2Swap ? (\n          <Typography\n            variant={'body1'}\n            display={'inline-flex'}\n            alignItems={'center'}\n            justifyContent={'space-between'}\n            paddingTop={1}\n            paddingBottom={2}\n          >\n            <Tooltip title={t('labelBtradeQuoteDes').toString()}>\n              <Typography\n                component={'span'}\n                variant={'inherit'}\n                alignItems={'center'}\n                display={'inline-flex'}\n                color={'textSecondary'}\n              >\n                <Info2Icon fontSize={'small'} color={'inherit'} sx={{ marginX: 1 / 2 }} />\n                {t('labelBtradeQuote')}\n              </Typography>\n            </Tooltip>\n\n            <Typography component={'span'} variant={'inherit'} color={'textPrimary'}>\n              {tradeCalcData?.totalQuota\n                ? tradeCalcData?.totalQuota + ' ' + sellSymbol\n                : EmptyValueTag}\n            </Typography>\n          </Typography>\n        ) : (\n          <></>\n        )}\n        {(tradeCalcData as any)?.isVault && (tradeCalcData as any).step !== VaultSwapStep.Edit && (\n          \n          <Box className={'cover'} onClick={onCancelClick} />\n        )}\n      </Grid>\n\n      <Grid item display={'flex'} alignItems={'center'} justifyContent={'center'}>\n        <Typography\n          variant='body1'\n          textAlign={'center'}\n          lineHeight={'24px'}\n          paddingY={2}\n          display={'inline-flex'}\n          alignItems={'center'}\n          justifyContent={'center'}\n        >\n          {showVal ? (\n            <>\n              {convertStr}\n              <IconButtonStyled\n                size={'small'}\n                aria-label={t('tokenExchange')}\n                onClick={_onSwitchStob}\n                // style={{transform: 'rotate(90deg)'}}\n              >\n                <ReverseIcon />\n              </IconButtonStyled>\n            </>\n          ) : (\n            t('labelCalculating')\n          )}\n        </Typography>\n      </Grid>\n\n      {!isL2Swap ? (\n        <>\n          <Grid item paddingBottom={3} sx={{ color: 'text.secondary' }}>\n            {(tradeCalcData as any)?.isVault && tradeCalcData && tradeCalcData.borrowVol ? (\n              <Grid\n                container\n                justifyContent={'space-between'}\n                direction={'row'}\n                alignItems={'center'}\n                marginTop={1 / 2}\n              >\n                <Tooltip\n                  title={t('labelTobeBorrowedtips', {\n                    rate: userTakerRate,\n                    value: tradeCostMin,\n                  }).toString()}\n                  placement={'top'}\n                >\n                  <Typography\n                    component={'p'}\n                    variant='body2'\n                    color={'textSecondary'}\n                    display={'inline-flex'}\n                    alignItems={'center'}\n                  >\n                    <Info2Icon fontSize={'small'} color={'inherit'} sx={{ marginX: 1 / 2 }} />\n                    {' ' + t('labelTobeBorrowed')}\n                  </Typography>\n                </Tooltip>\n                <Typography component={'p'} variant='body2' color={'textPrimary'}>\n                  {tradeCalcData && tradeCalcData.borrowVol\n                    ? `${tradeCalcData.borrowStr} ${sellSymbol}` //(parseFloat(tradeCalcData.fee) / 100).toString() + \"%\"\n                    : EmptyValueTag}\n                </Typography>\n              </Grid>\n            ) : undefined}\n            {(tradeCalcData as any)?.isVault && tradeCalcData && tradeCalcData.borrowVol ? (\n              <Grid\n                container\n                justifyContent={'space-between'}\n                direction={'row'}\n                alignItems={'center'}\n                marginTop={1 / 2}\n              >\n                <Tooltip title={t('labelVaultMarginLevelDes')} placement={'top'}>\n                  <Typography\n                    component={'p'}\n                    variant='body2'\n                    color={'textSecondary'}\n                    display={'inline-flex'}\n                    alignItems={'center'}\n                  >\n                    <Info2Icon fontSize={'small'} color={'inherit'} sx={{ marginX: 1 / 2 }} />\n                    {' ' + t('labelVaultMarginLevel')}\n                  </Typography>\n                </Tooltip>\n\n                <Typography component={'p'} variant='body2' color={'textPrimary'}>\n                  <Typography\n                    display={'flex'}\n                    alignItems={'center'}\n                    marginLeft={0.5}\n                    component={'p'}\n                    variant='body2'\n                    color={'textPrimary'}\n                  >\n                    {marginLevelChange ? (\n                      <>\n                        <Typography color={marginLevelTypeToColor(marginLevelChange.from.type)}>\n                          {numberFormat(marginLevelChange.from.marginLevel, { fixed: 2 })}\n                        </Typography>\n                        <EastIcon sx={{ marginX: 0.5 }} />\n                        <Typography color={marginLevelTypeToColor(marginLevelChange.to.type)}>\n                          {numberFormat(marginLevelChange.to.marginLevel, { fixed: 2 })}\n                        </Typography>\n                      </>\n                    ) : (\n                      EmptyValueTag\n                    )}\n                  </Typography>\n                </Typography>\n              </Grid>\n            ) : undefined}\n            {(tradeCalcData as any)?.isVault && tradeCalcData && tradeCalcData.borrowVol ? (\n              <Grid\n                container\n                justifyContent={'space-between'}\n                direction={'row'}\n                alignItems={'center'}\n                marginTop={1 / 2}\n              >\n                <Tooltip title={t('labelHourlyInterestRateTips')} placement={'top'}>\n                  <Typography\n                    component={'p'}\n                    variant='body2'\n                    color={'textSecondary'}\n                    display={'inline-flex'}\n                    alignItems={'center'}\n                  >\n                    <Info2Icon fontSize={'small'} color={'inherit'} sx={{ marginX: 1 / 2 }} />\n                    {' ' + t('labelHourlyInterestRate')}\n                  </Typography>\n                </Tooltip>\n                <Typography component={'p'} variant='body2' color={'textPrimary'}>\n                  {tradeCalcData &&\n                    (tradeCalcData as any).hourlyRateInPercent &&\n                    (tradeCalcData as any).yearlyRateInPercent &&\n                    `${(tradeCalcData as any).hourlyRateInPercent}% (APR: ${\n                      (tradeCalcData as any).yearlyRateInPercent\n                    }%)`}\n                </Typography>\n              </Grid>\n            ) : undefined}\n            <Grid\n              container\n              justifyContent={'space-between'}\n              direction={'row'}\n              alignItems={'center'}\n              marginTop={1 / 2}\n            >\n              <Tooltip\n                title={t('labelBtradeFeeTooltips', {\n                  feeRate: `${(tradeCalcData as any).maxFeeBips / 100}%`,\n                }).toString()}\n                placement={'top'}\n              >\n                <Typography\n                  component={'p'}\n                  variant='body2'\n                  color={'textSecondary'}\n                  display={'inline-flex'}\n                  alignItems={'center'}\n                >\n                  <Info2Icon fontSize={'small'} color={'inherit'} sx={{ marginX: 1 / 2 }} />\n                  {' ' + t('labelTradingFeeEst')}\n                </Typography>\n              </Tooltip>\n              <Typography component={'p'} variant='body2' color={'textPrimary'}>\n                {fee}\n              </Typography>\n            </Grid>\n            <Grid\n              container\n              justifyContent={'space-between'}\n              direction={'row'}\n              alignItems={'center'}\n              marginTop={1 / 2}\n            >\n              <Tooltip title={t('labelSwapMinConvertedTooltip').toString()} placement={'top'}>\n                <Typography\n                  component={'p'}\n                  variant='body2'\n                  color={'textSecondary'}\n                  display={'inline-flex'}\n                  alignItems={'center'}\n                >\n                  <Info2Icon fontSize={'small'} color={'inherit'} sx={{ marginX: 1 / 2 }} />\n                  {t('labelSwapMinConverted')}\n                </Typography>\n              </Tooltip>\n              <Typography component={'p'} variant='body2' color={'textPrimary'}>\n                {minimumConverted}\n              </Typography>\n            </Grid>\n\n            <Grid\n              container\n              justifyContent={'space-between'}\n              direction={'row'}\n              alignItems={'center'}\n              height={24}\n            >\n              <Tooltip title={t('labelBtradeToleranceTooltips').toString()} placement={'top'}>\n                <Typography\n                  component={'p'}\n                  variant='body2'\n                  color={'textSecondary'}\n                  display={'inline-flex'}\n                  alignItems={'center'}\n                >\n                  <Info2Icon fontSize={'small'} color={'inherit'} sx={{ marginX: 1 / 2 }} />\n                  {' ' + t('swapTolerance')}\n                </Typography>\n              </Tooltip>\n\n              <Typography component={'p'} variant='body2'>\n                {tradeCalcData\n                  ? (tradeData.slippage\n                      ? tradeData.slippage\n                      : tradeCalcData.slippage\n                      ? tradeCalcData.slippage\n                      : defaultSlipage) + '%'\n                  : EmptyValueTag}\n              </Typography>\n            </Grid>\n          </Grid>\n        </>\n      ) : (\n        <>\n          <Grid item paddingBottom={3} sx={{ color: 'text.secondary' }}>\n            <Grid\n              container\n              justifyContent={'space-between'}\n              direction={'row'}\n              alignItems={'center'}\n              marginTop={1 / 2}\n            >\n              <Tooltip\n                title={t('labelSwapFeeTooltips', {\n                  rate: userTakerRate,\n                  value: tradeCostMin,\n                }).toString()}\n                placement={'top'}\n              >\n                <Typography\n                  component={'p'}\n                  variant='body2'\n                  color={'textSecondary'}\n                  display={'inline-flex'}\n                  alignItems={'center'}\n                >\n                  <Info2Icon fontSize={'small'} color={'inherit'} sx={{ marginX: 1 / 2 }} />\n                  {' ' + t('labelTradingFeeEst')}\n                </Typography>\n              </Tooltip>\n              <Typography component={'p'} variant='body2' color={'textPrimary'}>\n                {fee}\n              </Typography>\n            </Grid>\n\n            <Grid\n              container\n              justifyContent={'space-between'}\n              direction={'row'}\n              alignItems={'center'}\n              marginTop={1 / 2}\n            >\n              <Tooltip title={t('labelSwapPriceImpactTooltips').toString()} placement={'top'}>\n                <Typography\n                  display={'inline-flex'}\n                  component={'span'}\n                  variant='body2'\n                  color={'textSecondary'}\n                  alignItems={'center'}\n                >\n                  <Info2Icon fontSize={'small'} color={'inherit'} sx={{ marginX: 1 / 2 }} />\n                  {' ' + t('swapPriceImpact')}\n                </Typography>\n              </Tooltip>\n              <Typography component={'p'} color={priceImpactColor} variant='body2'>\n                {priceImpact}\n              </Typography>\n            </Grid>\n            <Grid\n              container\n              justifyContent={'space-between'}\n              direction={'row'}\n              alignItems={'center'}\n              marginTop={1 / 2}\n            >\n              <Tooltip title={t('labelSwapMinConvertedTooltip').toString()} placement={'top'}>\n                <Typography\n                  component={'p'}\n                  variant='body2'\n                  color={'textSecondary'}\n                  display={'inline-flex'}\n                  alignItems={'center'}\n                >\n                  <Info2Icon fontSize={'small'} color={'inherit'} sx={{ marginX: 1 / 2 }} />\n                  {t('labelSwapMinConverted')}\n                </Typography>\n              </Tooltip>\n              <Typography component={'p'} variant='body2' color={'textPrimary'}>\n                {minimumConverted}\n              </Typography>\n            </Grid>\n            <Grid\n              container\n              justifyContent={'space-between'}\n              direction={'row'}\n              alignItems={'center'}\n              height={24}\n            >\n              <Tooltip title={t('labelSwapToleranceTooltips').toString()} placement={'top'}>\n                <Typography\n                  component={'p'}\n                  variant='body2'\n                  color={'textSecondary'}\n                  display={'inline-flex'}\n                  alignItems={'center'}\n                >\n                  <Info2Icon fontSize={'small'} color={'inherit'} sx={{ marginX: 1 / 2 }} />\n                  {' ' + t('swapTolerance')}\n                </Typography>\n              </Tooltip>\n\n              <Typography component={'p'} variant='body2'>\n                {tradeCalcData\n                  ? (tradeData.slippage\n                      ? tradeData.slippage\n                      : tradeCalcData.slippage\n                      ? tradeCalcData.slippage\n                      : defaultSlipage) + '%'\n                  : EmptyValueTag}\n              </Typography>\n            </Grid>\n          </Grid>\n        </>\n      )}\n\n      <Grid item alignSelf={'stretch'}>\n        {(tradeCalcData as any)?.isVault && BtnEle ? (\n          <>{BtnEle}</>\n        ) : (\n          <ButtonStyle\n            variant={'contained'}\n            size={'large'}\n            color={'primary'}\n            onClick={() => {\n              onSwapClick()\n            }}\n            loading={!getDisabled() && swapBtnStatus === TradeBtnStatus.LOADING ? 'true' : 'false'}\n            disabled={\n              getDisabled() ||\n              swapBtnStatus === TradeBtnStatus.DISABLED ||\n              swapBtnStatus === TradeBtnStatus.LOADING\n            }\n            fullWidth={true}\n          >\n            {label}\n          </ButtonStyle>\n        )}\n      </Grid>\n      {isL2Swap && (tradeCalcData as any)?.isShowBtradeAllow && (\n        <Grid\n          item\n          marginTop={3}\n          display={'flex'}\n          alignSelf={'stretch'}\n          justifyContent={'flex-start'}\n          alignItems={'stretch'}\n          flexDirection={'column'}\n          flexBasis={'initial'}\n        >\n          <Typography\n            variant={'body2'}\n            color={'textSecondary'}\n            borderRadius={1}\n            paddingY={2}\n            paddingX={1}\n          >\n            <Trans\n              i18nKey={'labelGoBtradeSwap'}\n              components={{\n                a: (\n                  <Link\n                    onClick={() => {\n                      history.push('/trade/btrade/' + sellSymbol + '-' + buySymbol)\n                    }}\n                    target='_blank'\n                    rel='noopener noreferrer'\n                    variant={'inherit'}\n                    color={'primary'}\n                  />\n                ),\n              }}\n            >\n              Swapping on the DEX will result in a large Price Impact (loss of assets). We recommend\n              using the <a>Block Trade</a> option to help minimize potential losses.\n            </Trans>\n          </Typography>\n        </Grid>\n      )}\n    </GridStyle>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/SwapWrap/index.ts",
    "content": "// this is a private component, only used in panel component\n// please do not export this index to global\n\n// export * from './Interface'\nexport * from './SwapTradeWrap'\nexport * from './SwapMenuList'\nexport * from './Interface'\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/TargetRedpacketWrap.tsx",
    "content": "import { useTranslation } from 'react-i18next'\nimport { Box, Typography, Tooltip, DialogTitle, DialogContent } from '@mui/material'\nimport { CoinSource, SoursURL, TokenType } from '@loopring-web/common-resources'\nimport { Button, NftImageStyle } from '../../basic-lib'\nimport { useTheme } from '@emotion/react'\nimport { CoinIcons } from '../../tableList'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nexport const TargetRedpacketWrap = (props: {\n  exclusiveRedPackets?: (sdk.LuckyTokenItemForReceive & {\n    tokenIcon: CoinSource\n    tokenName: string\n  })[]\n  onClickOpenExclusive: (redpacket: sdk.LuckyTokenItemForReceive) => void\n}) => {\n  const { exclusiveRedPackets, onClickOpenExclusive } = props\n  const { t } = useTranslation(['common'])\n  const theme = useTheme()\n  return (\n    <>\n      <DialogTitle>\n        <Typography variant={'h3'} marginTop={2} textAlign={'center'}>\n          {t('labelExclusiveRedpacket')}\n        </Typography>\n      </DialogTitle>\n      <DialogContent style={{ width: '480px', height: '480px' }}>\n        <Box marginTop={5} paddingX={4}>\n          {exclusiveRedPackets &&\n            exclusiveRedPackets.map((redpacket) => (\n              <Box\n                display={'flex'}\n                paddingX={2.5}\n                paddingY={1.5}\n                borderRadius={1}\n                bgcolor={'var(--field-opacity)'}\n                justifyContent={'space-between'}\n                marginBottom={2}\n                key={redpacket.hash}\n              >\n                <Box display={'flex'} alignItems={'center'}>\n                  {redpacket.isNft ? (\n                    <NftImageStyle\n                      src={redpacket.nftTokenInfo?.metadata?.imageSize['240-240']}\n                      style={{\n                        width: `${theme.unit * 4}px`,\n                        height: `${theme.unit * 4}px`,\n                        borderRadius: `${theme.unit * 0.5}px`,\n                      }}\n                    />\n                  ) : (\n                    <Box width={theme.unit * 4} height={theme.unit * 4}>\n                      <CoinIcons\n                        size={theme.unit * 4}\n                        type={TokenType.single}\n                        tokenIcon={[redpacket.tokenIcon]}\n                      />\n                    </Box>\n                  )}\n\n                  <Typography\n                    whiteSpace={'nowrap'}\n                    maxWidth={'150px'}\n                    overflow={'hidden'}\n                    textOverflow={'ellipsis'}\n                    marginLeft={1}\n                    marginRight={1}\n                  >\n                    {redpacket.tokenName}\n                  </Typography>\n\n                  {redpacket.type.mode === sdk.LuckyTokenClaimType.BLIND_BOX && (\n                    <Tooltip title={<>{t('labelRedpacketFromBlindbox')}</>}>\n                      <img\n                        width={24}\n                        height={24}\n                        style={{ marginLeft: `${0.5 * theme.unit}px` }}\n                        src={\n                          theme.mode === 'dark'\n                            ? SoursURL + '/images/from_blindbox_dark.png'\n                            : SoursURL + '/images/from_blindbox_light.png'\n                        }\n                      />\n                    </Tooltip>\n                  )}\n                </Box>\n                <Button\n                  variant={'contained'}\n                  onClick={() => {\n                    onClickOpenExclusive(redpacket)\n                  }}\n                >\n                  {t('labelRedPacketOpen')}\n                </Button>\n              </Box>\n            ))}\n        </Box>\n      </DialogContent>\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/TransferConfirm.tsx",
    "content": "\nimport { WithTranslation } from 'react-i18next'\nimport { Box, Grid, Typography } from '@mui/material'\nimport {\n  EmptyValueTag,\n  FeeInfo,\n  getShortAddr,\n  IBData,\n  L1L2_NAME_DEFINED,\n  MapChainId,\n  NFTWholeINFO,\n  TOAST_TIME,\n} from '@loopring-web/common-resources'\nimport { Button, Toast, ToastType, useAddressTypeLists } from '../../index'\nimport { TransferViewProps } from './Interface'\nimport { useSettings } from '../../../stores'\nimport React from 'react'\nimport { sanitize } from 'dompurify'\n\nexport const TransferConfirm = <T extends IBData<I> & Partial<NFTWholeINFO>, I, C extends FeeInfo>({\n  t,\n  sureItsLayer2,\n  handleConfirm,\n  tradeData,\n  lastFailed,\n  onTransferClick,\n  realAddr,\n  type,\n  feeInfo,\n  feeWithActive,\n  memo,\n}: Partial<TransferViewProps<T, I, C>> & {\n  handleConfirm: (index: number) => void\n} & WithTranslation) => {\n  const { isMobile, defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const { walletList } = useAddressTypeLists()\n  const [open, setOpen] = React.useState(false)\n  return (\n    <Grid\n      className={'confirm'}\n      container\n      paddingLeft={isMobile ? 2 : 5 / 2}\n      paddingRight={isMobile ? 2 : 5 / 2}\n      direction={'column'}\n      alignItems={'stretch'}\n      flex={1}\n      height={'100%'}\n      minWidth={240}\n      flexWrap={'nowrap'}\n      spacing={2}\n    >\n      <Grid item xs={12}>\n        <Box\n          display={'flex'}\n          flexDirection={'column'}\n          justifyContent={'center'}\n          alignItems={'center'}\n          marginBottom={2}\n        >\n          <Typography component={'h4'} variant={isMobile ? 'h4' : 'h3'} whiteSpace={'pre'}>\n            {t('labelL2toL2Title', {\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n            })}\n          </Typography>\n        </Box>\n      </Grid>\n      <Grid item xs={12}>\n        <Typography color={'var(--color-text-third)'} variant={'body1'}>\n          {t('labelL2toL2TokenAmount')}\n        </Typography>\n        <Typography color={'textPrimary'} marginTop={1} variant={'body1'}>\n          {tradeData?.tradeValue}\n          <Typography\n            component={'span'}\n            color={'textSecondary'}\n            dangerouslySetInnerHTML={{\n              __html:\n                sanitize(\n                  type === 'NFT'\n                    ? ' \\u2A09 ' + tradeData?.name ?? 'NFT'\n                    : ` ${tradeData?.belong}` ?? EmptyValueTag,\n                ) ?? '',\n            }}\n          />\n        </Typography>\n      </Grid>\n      <Grid item xs={12}>\n        <Typography color={'var(--color-text-third)'} variant={'body1'}>\n          {t('labelL2toL2Address')}\n        </Typography>\n        <Typography color={'textPrimary'} marginTop={1} variant={'body1'}>\n          {realAddr}\n        </Typography>\n      </Grid>\n      <Grid item xs={12}>\n        <Typography color={'var(--color-text-third)'} variant={'body1'}>\n          {t('labelL2toL2AddressType')}\n        </Typography>\n        <Typography color={'textPrimary'} marginTop={1} variant={'body1'}>\n          {walletList.find((item) => item.value === sureItsLayer2)?.label}\n        </Typography>\n      </Grid>\n      <Grid item xs={12}>\n        <Typography color={'var(--color-text-third)'} variant={'body1'}>\n          {feeWithActive\n            ? t('labelL2toL2FeeWithActive', {\n                addr: getShortAddr(realAddr ?? ''),\n              })\n            : t('labelL2toL2Fee')}\n        </Typography>\n        <Typography color={'textPrimary'} marginTop={1} variant={'body1'}>\n          {feeInfo?.fee + ' '} {feeInfo?.belong}\n        </Typography>\n      </Grid>\n\n      <Grid item xs={12}>\n        <Typography color={'var(--color-text-third)'} variant={'body1'}>\n          {t('labelMemo')}\n        </Typography>\n        <Typography color={'textPrimary'} marginTop={1} variant={'body1'}>\n          {memo ?? EmptyValueTag}\n        </Typography>\n      </Grid>\n\n      <Grid item marginTop={2} alignSelf={'stretch'} paddingBottom={0}>\n        <Button\n          fullWidth\n          variant={'contained'}\n          size={'medium'}\n          color={'primary'}\n          onClick={async () => {\n            if (onTransferClick) {\n              await onTransferClick({ ...tradeData, memo } as unknown as T)\n            } else {\n              setOpen(true)\n            }\n            handleConfirm(1)\n          }}\n        >\n          {t('labelConfirm')}\n        </Button>\n      </Grid>\n      <Toast\n        alertText={t('errorBase', { ns: 'error' })}\n        open={open}\n        autoHideDuration={TOAST_TIME}\n        onClose={() => {\n          setOpen(false)\n        }}\n        severity={ToastType.error}\n      />\n    </Grid>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/TransferNFTBurn.tsx",
    "content": "import { Trans, useTranslation } from 'react-i18next'\nimport React from 'react'\nimport { Box, Divider, Grid, Typography } from '@mui/material'\nimport { bindHover } from 'material-ui-popup-state'\nimport { bindPopper, usePopupState } from 'material-ui-popup-state/hooks'\nimport {\n  FeeInfo,\n  GET_IPFS_STRING,\n  IBData,\n  Info2Icon,\n  L1L2_NAME_DEFINED,\n  MapChainId,\n  NFTWholeINFO,\n  TRADE_TYPE,\n  TradeBtnStatus,\n  myLog,\n} from '@loopring-web/common-resources'\nimport { Button, FeeSelect, InputSize, SwitchData, TransferProps } from '../../index'\nimport { PopoverPure } from '../..'\nimport { NFTInput } from './BasicANFTTrade'\nimport { useSettings } from '../../../stores'\nimport styled from '@emotion/styled'\n\nconst BoxStyle = styled(Box)`\n  .coinInput-wrap,\n  .btnInput-wrap,\n  .MuiOutlinedInput-root {\n    background: var(--field-opacity);\n    border-color: var(--opacity);\n\n    :hover {\n      border-color: var(--color-border-hover);\n    }\n  }\n`\nexport const TransferNFTBurn = <T extends IBData<I> & Partial<NFTWholeINFO>, I, C extends FeeInfo>({\n  type = TRADE_TYPE.NFT,\n  transferBtnStatus,\n  disabled,\n  walletMap,\n  handleFeeChange,\n  chargeFeeTokenList,\n  feeInfo,\n  isFeeNotEnough,\n  onTransferClick,\n  transferI18nKey,\n  tradeData,\n  handlePanelEvent,\n  ...rest\n}: TransferProps<T, I, C> & {\n  getIPFSString: GET_IPFS_STRING\n  assetsData: any[]\n}) => {\n  const { t } = useTranslation()\n  const inputBtnRef = React.useRef()\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n\n  myLog('Burn tradeData', tradeData)\n  const inputButtonDefaultProps = {\n    label: t('labelL2toL2EnterToken'),\n    size: InputSize.middle,\n  }\n\n  const [showFeeModal, setShowFeeModal] = React.useState(false)\n\n  const popupState = usePopupState({\n    variant: 'popover',\n    popupId: `popupId-transfer`,\n  })\n\n\tconst getDisabled = React.useMemo(() => {\n\t\treturn disabled || transferBtnStatus === TradeBtnStatus.DISABLED\n\t}, [disabled, transferBtnStatus])\n\tconst handleToggleChange = (value: C) => {\n\t\tif (handleFeeChange) {\n\t\t\thandleFeeChange(value)\n\t\t}\n\t}\n\treturn (\n\t\t<BoxStyle\n\t\t\twidth={'var(--modal-width)'} className={'transfer-wrap'}>\n\t\t\t<Typography\n\t\t\t\tcomponent={'header'}\n\t\t\t\theight={'calc(var(--toolbar-row-height) - 16px)'}\n\t\t\t\tdisplay={'flex'}\n\t\t\t\tpaddingX={3}\n\t\t\t\tjustifyContent={'flex-start'}\n\t\t\t\tflexDirection={'row'}\n\t\t\t\talignItems={'center'}\n\t\t\t>\n\t\t\t\t<Typography variant={'h5'} component={'span'} display={'inline-flex'} color={'textPrimary'}>\n\t\t\t\t\t{t('labelL2NFTBurnTitle', {\n\t\t\t\t\t\tloopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n\t\t\t\t\t})}\n\t\t\t\t</Typography>\n\t\t\t\t<Info2Icon\n\t\t\t\t\t{...bindHover(popupState)}\n\t\t\t\t\tsx={{\n\t\t\t\t\t\tmarginLeft: 1\n\t\t\t\t\t}}\n\t\t\t\t\tfontSize={'medium'}\n\t\t\t\t\thtmlColor={'var(--color-text-third)'}\n\t\t\t\t/>\n\t\t\t</Typography>\n\t\t\t<PopoverPure\n\t\t\t\tclassName={'arrow-center'}\n\t\t\t\t{...bindPopper(popupState)}\n\t\t\t\tanchorOrigin={{\n\t\t\t\t\tvertical: 'bottom',\n\t\t\t\t\thorizontal: 'center',\n\t\t\t\t}}\n\t\t\t\ttransformOrigin={{\n\t\t\t\t\tvertical: 'top',\n\t\t\t\t\thorizontal: 'center',\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<Typography padding={2} maxWidth={450} variant={'body1'} whiteSpace={'pre-line'}>\n\t\t\t\t\t<Trans\n\t\t\t\t\t\ti18nKey='labelL2NFTBurnTip'\n\t\t\t\t\t\ttOptions={{\n\t\t\t\t\t\t\tl1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n\t\t\t\t\t\t\tloopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n\t\t\t\t\t\t\tloopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n\t\t\t\t\t\t\tl2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n\t\t\t\t\t\t\tl1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n\t\t\t\t\t\t\tethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\tTransfer to any valid Ethereum addresses instantly. Please make sure the recipient\n\t\t\t\t\t\taddress accepts Loopring layer-2 payments before you proceed.\n\t\t\t\t\t</Trans>\n\t\t\t\t</Typography>\n\t\t\t</PopoverPure>\n\t\t\t<Divider/>\n\t\t\t<Grid container\n\t\t\t      marginY={3}\n\t\t\t      paddingX={3}\n\t\t\t      spacing={2}>\n\t\t\t\t<Grid item xs={12} alignSelf={'stretch'} position={'relative'}>\n\t\t\t\t\t<NFTInput\n\t\t\t\t\t\t{...({\n\t\t\t\t\t\t\t...rest,\n\t\t\t\t\t\t\tt,\n\t\t\t\t\t\t\tgetIPFSString: rest?.getIPFSString ?? (() => '' as any),\n\t\t\t\t\t\t\tdisabled,\n\t\t\t\t\t\t\twalletMap,\n\t\t\t\t\t\t\ttradeData,\n\t\t\t\t\t\t\tonChangeEvent:async (_index: 0 | 1, { to, tradeData }: SwitchData<T>) => {\n\t\t\t\t\t\t\t\thandlePanelEvent &&\thandlePanelEvent({ to, tradeData }, `Tobutton` as any)\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tinputNFTDefaultProps: {...inputButtonDefaultProps, label: '', size: InputSize.middle},\n\t\t\t\t\t\t\tinputNFTRef: inputBtnRef,\n\t\t\t\t\t\t} as any)}\n\t\t\t\t\t/>\n\t\t\t\t</Grid>\n\t\t\t\t<Grid item xs={12} alignSelf={'stretch'} position={'relative'}>\n\t\t\t\t\t{!chargeFeeTokenList?.length ? (\n\t\t\t\t\t\t<Typography>{t('labelFeeCalculating')}</Typography>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t<FeeSelect\n\t\t\t\t\t\t\t\tchargeFeeTokenList={chargeFeeTokenList}\n\t\t\t\t\t\t\t\thandleToggleChange={(fee: FeeInfo) => {\n\t\t\t\t\t\t\t\t\thandleToggleChange(fee as C)\n\t\t\t\t\t\t\t\t\tsetShowFeeModal(false)\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\tfeeInfo={feeInfo as FeeInfo}\n\t\t\t\t\t\t\t\topen={showFeeModal}\n\t\t\t\t\t\t\t\tonClose={() => {\n\t\t\t\t\t\t\t\t\tsetShowFeeModal(false)\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\tisFeeNotEnough={isFeeNotEnough.isFeeNotEnough}\n\t\t\t\t\t\t\t\tfeeLoading={isFeeNotEnough.isOnLoading}\n\t\t\t\t\t\t\t\tonClickFee={() => setShowFeeModal((prev) => !prev)}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</>\n\t\t\t\t\t)}\n\t\t\t\t</Grid>\n\t\t\t\t<Grid item xs={12} alignSelf={'stretch'} paddingBottom={0}>\n\t\t\t\t\t<Button\n\t\t\t\t\t\tfullWidth\n\t\t\t\t\t\tvariant={'contained'}\n\t\t\t\t\t\tsize={'medium'}\n\t\t\t\t\t\tcolor={'primary'}\n\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\tonTransferClick({...tradeData} as unknown as T)\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tloading={!getDisabled && transferBtnStatus === TradeBtnStatus.LOADING ? 'true' : 'false'}\n\t\t\t\t\t\tdisabled={\n\t\t\t\t\t\t\tgetDisabled ||\n\t\t\t\t\t\t\ttransferBtnStatus === TradeBtnStatus.LOADING\n\t\t\t\t\t\t}\n\t\t\t\t\t>\n\t\t\t\t\t\t{t(transferI18nKey ?? `labelL2toL2Btn`)}\n\t\t\t\t\t</Button>\n\t\t\t\t</Grid>\n\t\t\t</Grid>\n\t\t</BoxStyle>\n\t)\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/TransferWrap.tsx",
    "content": "import { Trans, WithTranslation } from 'react-i18next'\nimport React from 'react'\nimport {\n  Box,\n  Checkbox,\n  FormControlLabel as MuiFormControlLabel,\n  Grid,\n  IconButton,\n  InputAdornment,\n  Typography,\n} from '@mui/material'\nimport { bindHover } from 'material-ui-popup-state/es'\nimport { bindPopper, usePopupState } from 'material-ui-popup-state/hooks'\nimport {\n  AddressError,\n  AlertIcon,\n  BackIcon,\n  CheckBoxIcon,\n  CheckedIcon,\n  CloseIcon,\n  ContactIcon,\n  copyToClipBoard,\n  DropDownIcon,\n  EmptyValueTag,\n  EXCHANGE_TYPE,\n  FeeInfo,\n  fontDefault,\n  globalSetup,\n  hexToRGB,\n  IBData,\n  Info2Icon,\n  L1L2_NAME_DEFINED,\n  LoadingIcon,\n  MapChainId,\n  myLog,\n  NFTWholeINFO,\n  TOAST_TIME,\n  TradeBtnStatus,\n  WALLET_TYPE,\n} from '@loopring-web/common-resources'\nimport {\n  Button,\n  FeeSelect,\n  GridWrapStyle,\n  InputSize,\n  TextField,\n  Toast,\n  ToastType,\n} from '../../index'\nimport { PopoverPure } from '../../'\nimport { TransferViewProps } from './Interface'\nimport { BasicACoinTrade } from './BasicACoinTrade'\nimport { NFTInput } from './BasicANFTTrade'\nimport { useSettings } from '../../../stores'\nimport { TransferAddressType } from './AddressType'\nimport { useTheme } from '@emotion/react'\n\nexport const TransferWrap = <T extends IBData<I> & Partial<NFTWholeINFO>, I, C extends FeeInfo>({\n  t,\n  disabled,\n  walletMap,\n  tradeData,\n  // @ts-ignore\n  coinMap,\n  transferI18nKey,\n  type,\n  memo,\n  chargeFeeTokenList,\n  activeAccountPrice,\n  feeInfo,\n  lastFailed,\n  isFeeNotEnough,\n  handleSureItsLayer2,\n  handleFeeChange,\n  isThumb,\n  transferBtnStatus,\n  addressDefault,\n  handleOnAddressChange,\n  sureItsLayer2,\n  wait = globalSetup.wait,\n  assetsData = [],\n  realAddr,\n  isLoopringAddress,\n  addrStatus,\n  handleConfirm,\n  handleOnMemoChange,\n  isAddressCheckLoading,\n  isSameAddress,\n  isSmartContractAddress,\n  baseURL,\n  isActiveAccount,\n  isActiveAccountFee,\n  feeWithActive,\n  handleOnFeeWithActive,\n  contact,\n  isFromContact,\n  onClickContact,\n  loopringSmartWalletVersion,\n  isENSWrong,\n  ens,\n  geUpdateContact,\n  // addressType,\n  ...rest\n}: TransferViewProps<T, I, C> &\n  WithTranslation & {\n    assetsData: any[]\n    handleConfirm: (index: number) => void\n  }) => {\n  const inputBtnRef = React.useRef()\n  const { isMobile, defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n\n  // addressType\n\n  const inputButtonDefaultProps = {\n    label: t('labelL2toL2EnterToken'),\n    size: InputSize.middle,\n  }\n\n  const [showFeeModal, setShowFeeModal] = React.useState(false)\n\n  const popupState = usePopupState({\n    variant: 'popover',\n    popupId: `popupId-transfer`,\n  })\n\n  const getDisabled = React.useMemo(() => {\n    return disabled || transferBtnStatus === TradeBtnStatus.DISABLED\n  }, [disabled, transferBtnStatus])\n\n  const [copyToastOpen, setCopyToastOpen] = React.useState(false)\n  const onCopy = React.useCallback(\n    async (content: string) => {\n      await copyToClipBoard(content)\n      setCopyToastOpen(true)\n    },\n    [setCopyToastOpen],\n  )\n  const handleToggleChange = (value: C) => {\n    if (handleFeeChange) {\n      handleFeeChange(value)\n    }\n  }\n  const isInvalidAddressOrENS =\n    !isAddressCheckLoading &&\n    addressDefault &&\n    [AddressError.InvalidAddr, AddressError.IsNotLoopringContract].includes(addrStatus)\n  const detectedWalletType =\n    loopringSmartWalletVersion === undefined\n      ? undefined\n      : loopringSmartWalletVersion.isLoopringSmartWallet\n      ? WALLET_TYPE.Loopring\n      : isSmartContractAddress\n      ? WALLET_TYPE.OtherSmart\n      : WALLET_TYPE.EOA\n\n  const isExchange = React.useMemo(() => {\n    return !!(sureItsLayer2 && sureItsLayer2 in EXCHANGE_TYPE)\n  }, [sureItsLayer2, sureItsLayer2])\n\n  const isOtherSmartWallet = detectedWalletType === WALLET_TYPE.OtherSmart\n  const theme = useTheme()\n  myLog('transferWrap', realAddr)\n  const view = React.useMemo(() => {\n    if (isOtherSmartWallet && realAddr) {\n      return (\n        <Typography\n          color={'var(--color-error)'}\n          variant={'body2'}\n          marginTop={1 / 4}\n          alignSelf={'stretch'}\n          position={'relative'}\n        >\n          {t('labelNotOtherSmartWallet', {\n            loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n            l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n            loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n            l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n            l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n            ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n          })}\n        </Typography>\n      )\n    } else if (isInvalidAddressOrENS && addressDefault) {\n      return (\n        <Typography\n          color={'var(--color-error)'}\n          variant={'body2'}\n          marginTop={1 / 4}\n          alignSelf={'stretch'}\n          position={'relative'}\n        >\n          {t(`labelL2toL2${addrStatus}`)}\n        </Typography>\n      )\n    } else if (isExchange && addressDefault) {\n      return (\n        <Typography\n          color={'var(--color-error)'}\n          variant={'body2'}\n          marginTop={1 / 4}\n          alignSelf={'stretch'}\n          position={'relative'}\n        >\n          {t('labelNotExchangeEOA', {\n            layer2: L1L2_NAME_DEFINED[network].layer2,\n            l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n            loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n            l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n            l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n            ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n          })}\n        </Typography>\n      )\n    } else if (isSameAddress && addressDefault) {\n      return (\n        <Typography\n          color={'var(--color-error)'}\n          variant={'body2'}\n          marginTop={1 / 4}\n          alignSelf={'stretch'}\n          position={'relative'}\n        >\n          {t('labelInvalidisSameAddress', {\n            way: t('labelL2toL2', {\n              layer2: L1L2_NAME_DEFINED[network].layer2,\n              l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n              l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n              l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n              ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n            }),\n          })}\n        </Typography>\n      )\n    } else {\n      return (\n        <>\n          {addressDefault && realAddr && !isAddressCheckLoading && (\n            <Typography\n              color={'var(--color-text-primary)'}\n              variant={'body2'}\n              marginTop={1 / 4}\n              whiteSpace={'pre-line'}\n              style={{ wordBreak: 'break-all' }}\n            >\n              {realAddr}\n            </Typography>\n          )}\n          {!isAddressCheckLoading &&\n            addressDefault &&\n            addrStatus === AddressError.NoError &&\n            isActiveAccount === false && (\n              <Box>\n                {isActiveAccount === false && realAddr && (\n                  <Typography\n                    color={'var(--color-error)'}\n                    lineHeight={1.2}\n                    variant={'body2'}\n                    marginTop={1 / 2}\n                    marginLeft={'-2px'}\n                    display={'inline-flex'}\n                  >\n                    <Trans\n                      i18nKey={'labelL2toL2AddressNotLoopring'}\n                      tOptions={{\n                        l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                        loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                        l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                        l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                        ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                      }}\n                    >\n                      <AlertIcon color={'inherit'} fontSize={'medium'} sx={{ marginRight: 1 }} />\n                      This address does not have an activated Loopring L2. Please ensure the\n                      recipient can access Loopring L2 before sending.\n                    </Trans>\n                  </Typography>\n                )}\n                {!isActiveAccountFee && realAddr ? (\n                  <MuiFormControlLabel\n                    sx={{\n                      alignItems: 'flex-start',\n                      marginTop: 1 / 2,\n                    }}\n                    control={\n                      <Checkbox\n                        checked={feeWithActive}\n                        onChange={(_event: any, state: boolean) => {\n                          handleOnFeeWithActive(state)\n                        }}\n                        checkedIcon={<CheckedIcon />}\n                        icon={<CheckBoxIcon />}\n                        color='default'\n                      />\n                    }\n                    label={\n                      <Typography\n                        whiteSpace={'pre-line'}\n                        component={'span'}\n                        variant={'body1'}\n                        display={'block'}\n                        color={'textSecondary'}\n                        paddingTop={1 / 2}\n                      >\n                        {t('labelL2toL2AddressFeeActiveFee', {\n                          value: activeAccountPrice,\n                          layer2: L1L2_NAME_DEFINED[network].layer2,\n                          l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                          loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                          l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                          l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                          ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                        })}\n                      </Typography>\n                    }\n                  />\n                ) : (\n                  <></>\n                )}\n              </Box>\n            )}\n        </>\n      )\n    }\n  }, [\n    addressDefault,\n    isActiveAccount,\n    isActiveAccountFee,\n    feeWithActive,\n    addrStatus,\n    realAddr,\n    isAddressCheckLoading,\n    activeAccountPrice,\n    isInvalidAddressOrENS,\n    isExchange,\n    isOtherSmartWallet,\n    isSameAddress,\n    isLoopringAddress,\n    isAddressCheckLoading,\n  ])\n\n  return (\n    <GridWrapStyle\n      className={'transfer-wrap'}\n      container\n      paddingLeft={isMobile ? 2 : 5 / 2}\n      paddingRight={isMobile ? 2 : 5 / 2}\n      direction={'column'}\n      alignItems={'stretch'}\n      flex={1}\n      height={'100%'}\n      minWidth={240}\n      spacing={2}\n      flexWrap={'nowrap'}\n    >\n      <Grid item>\n        <Box\n          display={'flex'}\n          flexDirection={'row'}\n          justifyContent={'center'}\n          alignItems={'center'}\n          marginBottom={2}\n        >\n          <Typography\n            component={'h4'}\n            variant={isMobile ? 'h4' : 'h3'}\n            whiteSpace={'pre'}\n            marginRight={1}\n          >\n            {t('labelL2toL2Title', {\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n            })}\n          </Typography>\n          <Info2Icon\n            {...bindHover(popupState)}\n            fontSize={'large'}\n            htmlColor={'var(--color-text-third)'}\n          />\n        </Box>\n        <PopoverPure\n          className={'arrow-center'}\n          {...bindPopper(popupState)}\n          anchorOrigin={{\n            vertical: 'bottom',\n            horizontal: 'center',\n          }}\n          transformOrigin={{\n            vertical: 'top',\n            horizontal: 'center',\n          }}\n        >\n          <Typography padding={2} maxWidth={450} variant={'body1'} whiteSpace={'pre-line'}>\n            <Trans\n              i18nKey='transferDescription'\n              tOptions={{\n                l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n                loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n              }}\n            >\n              Transfer to any valid Ethereum addresses instantly. Please make sure the recipient\n              address accepts Loopring layer-2 payments before you proceed.\n            </Trans>\n          </Typography>\n        </PopoverPure>\n      </Grid>\n\n      <Grid item alignSelf={'stretch'} position={'relative'}>\n        {type === 'NFT' ? (\n          <NFTInput\n            {...({\n              ...rest,\n              isThumb,\n              type,\n              onCopy,\n              t,\n              baseURL: baseURL ?? '',\n              getIPFSString: rest.getIPFSString ?? (() => '' as any),\n              disabled,\n              walletMap,\n              tradeData,\n              coinMap,\n              inputNFTDefaultProps: { label: '', size: InputSize.middle },\n              inputNFTRef: inputBtnRef,\n            } as any)}\n          />\n        ) : (\n          <BasicACoinTrade\n            {...{\n              ...rest,\n              type,\n              t,\n              disabled,\n              walletMap,\n              tradeData,\n              coinMap,\n              inputButtonDefaultProps,\n              inputBtnRef: inputBtnRef,\n            }}\n          />\n        )}\n      </Grid>\n\n      <Grid item alignSelf={'stretch'} position={'relative'}>\n        <TextField\n          size={'large'}\n          className={'text-address'}\n          value={addressDefault}\n          error={!!(isInvalidAddressOrENS || isSameAddress || isENSWrong)}\n          label={t('labelL2toL2Address')}\n          placeholder={t('labelL2toL2AddressInput')}\n          onChange={(event) => handleOnAddressChange(event?.target?.value)}\n          disabled={!chargeFeeTokenList.length}\n          SelectProps={{ IconComponent: DropDownIcon }}\n          fullWidth={true}\n          InputProps={{\n            style: {\n              paddingRight: '0',\n            },\n            endAdornment: isFromContact ? undefined : (\n              <InputAdornment\n                style={{\n                  cursor: 'pointer',\n                  paddingRight: '4px',\n                }}\n                position='end'\n              >\n                {addressDefault !== '' ? (\n                  isAddressCheckLoading ? (\n                    <LoadingIcon width={24} />\n                  ) : (\n                    <IconButton\n                      color={'inherit'}\n                      size={'small'}\n                      aria-label='Clear'\n                      onClick={() => handleOnAddressChange('')}\n                    >\n                      <CloseIcon />\n                    </IconButton>\n                  )\n                ) : (\n                  ''\n                )}\n                <IconButton\n                  color={'inherit'}\n                  size={'large'}\n                  onClick={() => {\n                    onClickContact()\n                  }}\n                >\n                  <ContactIcon />\n                </IconButton>\n              </InputAdornment>\n            ),\n          }}\n        />\n        <Box marginLeft={1 / 2}>{view}</Box>\n        {isENSWrong && (\n          <>\n            <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n              {ens}\n            </Typography>\n            <Button\n              variant={'contained'}\n              sx={{\n                fontSize: fontDefault.body1,\n                marginTop: 2,\n                padding: 1,\n                color: 'var(--color-text-button)',\n                display: 'flex',\n                alignItems: 'center',\n                background: hexToRGB(theme.colorBase.warning, 0.2),\n                textAlign: 'left',\n                borderRadius: 2,\n                height: 'auto',\n                '&:hover': {\n                  background: hexToRGB(theme.colorBase.warning, 0.3),\n                },\n              }}\n              onClick={geUpdateContact}\n              endIcon={<BackIcon fontSize={'large'} sx={{ transform: 'rotate(180deg)' }} />}\n            >\n              <Typography component={'span'} color={'inherit'} display={'inline-flex'}>\n                <AlertIcon color={'warning'} sx={{ marginRight: 1 / 2, marginTop: '2px' }} />\n                {t('labelContactENSAlert')}\n              </Typography>\n            </Button>\n          </>\n        )}\n      </Grid>\n\n      <Grid item alignSelf={'stretch'} position={'relative'}>\n        <TransferAddressType\n          detectedWalletType={detectedWalletType!}\n          selectedValue={sureItsLayer2}\n          handleSelected={handleSureItsLayer2}\n          disabled={\n            isSameAddress ||\n            isAddressCheckLoading ||\n            addrStatus !== AddressError.NoError ||\n            !realAddr\n          }\n        />\n      </Grid>\n\n      <Grid item alignSelf={'stretch'} position={'relative'}>\n        <TextField\n          size={'large'}\n          value={memo}\n          label={t('labelL2toL2Memo')}\n          placeholder={t('labelL2toL2MemoPlaceholder')}\n          onChange={handleOnMemoChange}\n          fullWidth={true}\n        />\n      </Grid>\n\n      <Grid item alignSelf={'stretch'} position={'relative'}>\n        {!chargeFeeTokenList?.length ? (\n          <Typography>{t('labelFeeCalculating')}</Typography>\n        ) : (\n          <>\n            <FeeSelect\n              chargeFeeTokenList={chargeFeeTokenList}\n              handleToggleChange={(fee: FeeInfo) => {\n                handleToggleChange(fee as C)\n                setShowFeeModal(false)\n              }}\n              feeInfo={feeInfo as FeeInfo}\n              open={showFeeModal}\n              onClose={() => {\n                setShowFeeModal(false)\n              }}\n              isFeeNotEnough={isFeeNotEnough.isFeeNotEnough}\n              feeLoading={isFeeNotEnough.isOnLoading}\n              onClickFee={() => setShowFeeModal((prev) => !prev)}\n            />\n          </>\n        )}\n      </Grid>\n\n      <Grid item alignSelf={'stretch'} paddingBottom={0}>\n        <Button\n          fullWidth\n          variant={'contained'}\n          size={'medium'}\n          color={'primary'}\n          onClick={() => {\n            handleConfirm(0)\n          }}\n          loading={!getDisabled && transferBtnStatus === TradeBtnStatus.LOADING ? 'true' : 'false'}\n          disabled={\n            getDisabled ||\n            transferBtnStatus === TradeBtnStatus.LOADING ||\n            isExchange ||\n            isOtherSmartWallet\n          }\n        >\n          {t(transferI18nKey ?? `labelL2toL2Btn`)}\n        </Button>\n      </Grid>\n\n      <Toast\n        alertText={t('labelCopyAddClip')}\n        open={copyToastOpen}\n        autoHideDuration={TOAST_TIME}\n        onClose={() => {\n          setCopyToastOpen(false)\n        }}\n        severity={ToastType.success}\n      />\n    </GridWrapStyle>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/VaultWrap/Interface.ts",
    "content": "import { InputButtonProps } from '../../../basic-lib'\nimport { CoinInfo, ForexMap, IBData, TradeBtnStatus } from '@loopring-web/common-resources'\nimport { BasicACoinTradeViewProps, SwitchData } from '../Interface'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport React from 'react'\n\nexport type VaultJoinBaseProps<T, I, V> = {\n  btnStatus?: keyof typeof TradeBtnStatus | undefined\n  onSubmitClick: (data: T) => void | any\n  btnI18nKey?: string\n  propsExtends?: Partial<InputButtonProps<T, I, unknown>>\n  vaultJoinData: V\n  tradeData: T\n  isActiveAccount: boolean\n  onRefreshData: () => void\n  refreshRef: React.Ref<any>\n  onToggleAddRedeem: (value: 'Add' | 'Redeem') => void\n  isAddOrRedeem: 'Add' | 'Redeem'\n  panelIndex: number\n  handleConfirm: (index: number) => void\n  basicTrade: { onChangeEvent: any; switchData: any }\n  modalOpen: boolean\n  onCloseModal: () => void,\n} & Partial<Pick<InputButtonProps<T, I, unknown>, 'handleError'>>\n\nexport type VaultJoinExtendProps<T, I, C = IBData<I>> = {\n  switchStobEvent?: (_isStoB: boolean) => void\n  disabled?: boolean\n  onChangeEvent: (index: 0 | 1, data: SwitchData<T>) => void\n  tokenProps?: Partial<InputButtonProps<C, I, CoinInfo<I>>>\n  onBack: () => {}\n  marginLevelChange: {\n    from: {\n      marginLevel: string\n      type: 'safe' | 'warning' | 'danger' \n    }\n    to: {\n      marginLevel: string\n      type: 'safe' | 'warning' | 'danger'\n    }\n  } | undefined\n  holdingCollateral?: string\n}\nexport type VaultJoinWrapProps<T, I, V> = VaultJoinBaseProps<T, I, V> & VaultJoinExtendProps<T, I>\n\nexport type VaultExitBaseProps = {\n  btnStatus?: keyof typeof TradeBtnStatus | undefined\n  onSubmitClick: () => void | any\n  vaultExitBtnI18nKey?: string\n  onClose: () => void\n  confirmLabel?: string\n  cancelLabel?: string\n  disabled?: boolean\n}\n\n// export type VaultExitWrapProps = VaultExitBaseProps\nexport type VaultBorrowBaseProps<T, I, B> = {\n  disabled?: boolean\n  vaultBorrowBtnStatus?: keyof typeof TradeBtnStatus | undefined\n  vaultBorrowBtnI18nKey?: string\n  onVaultBorrowClick: () => void | any\n  tokenProps?: Partial<InputButtonProps<T, I, CoinInfo<I>>>\n  onChangeEvent: (index: 0 | 1, data: SwitchData<T>) => void\n  vaultBorrowData: B\n  propsExtends?: Partial<InputButtonProps<T, I, CoinInfo<I>>>\n  tradeData: T\n  onRefreshData: () => void\n  refreshRef: React.Ref<any>\n  marginLevelChange: {\n    from: {\n      marginLevel: string\n      type: 'safe' | 'warning' | 'danger' \n    }\n    to: {\n      marginLevel: string\n      type: 'safe' | 'warning' | 'danger'\n    }\n  } | undefined\n  userLeverage: string\n  onClickLeverage: () => void\n  hideLeverage?: boolean\n}\nexport type VaultBorrowWrapProps<T, I, B> = BasicACoinTradeViewProps<T, I> &\n  VaultBorrowBaseProps<T, I, B>\n\nexport type VaultRepayWrapProps<T, I, VR> = BasicACoinTradeViewProps<T, I> & {\n  disabled?: boolean\n  vaultRepayBtnStatus?: keyof typeof TradeBtnStatus | undefined\n  onVaultRepayClick: () => void | any\n  vaultRepayBtnI18nKey?: string\n  tokenProps?: Partial<InputButtonProps<T, I, CoinInfo<I>>>\n  propsExtends?: Partial<InputButtonProps<T, I, CoinInfo<I>>>\n  vaultRepayData: VR\n  tradeData: T\n  forexMap: ForexMap<sdk.Currency>\n  tokenInfo?: sdk.VaultToken\n  marginLevelChange: {\n    from: {\n      marginLevel: string\n      type: 'safe' | 'warning' | 'danger' \n    }\n    to: {\n      marginLevel: string\n      type: 'safe' | 'warning' | 'danger'\n    }\n  } | undefined\n  initialSymbol: string | undefined\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/VaultWrap/VaultBorrow.tsx",
    "content": "import {\n  EmptyValueTag,\n  IBData,\n  L1L2_NAME_DEFINED,\n  MapChainId,\n  myLog,\n  TokenType,\n  TRADE_TYPE,\n  TradeBtnStatus,\n  VaultBorrowData,\n} from '@loopring-web/common-resources'\nimport {\n  CoinIcon,\n} from '@loopring-web/component-lib'\nimport { VaultBorrowWrapProps } from './Interface'\nimport React from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { useSettings } from '../../../../stores'\nimport { Grid, Typography, Divider, Box } from '@mui/material'\nimport { BasicACoinTrade } from '../BasicACoinTrade'\nimport { ButtonStyle } from '../Styled'\nimport { marginLevelTypeToColor } from './utils'\nimport { numberFormat } from '@loopring-web/core'\nimport EastIcon from '@mui/icons-material/East';\n\nexport const VaultBorrowWrap = <\n  T extends IBData<I> & { erc20Symbol: string },\n  V extends VaultBorrowData<T>,\n  I,\n>({\n  disabled,\n  vaultBorrowBtnStatus,\n  vaultBorrowBtnI18nKey,\n  onVaultBorrowClick,\n  tokenProps,\n  onChangeEvent,\n  vaultBorrowData,\n  walletMap,\n  tradeData,\n  coinMap,\n  propsExtends,\n  marginLevelChange,\n  userLeverage,\n  onClickLeverage,\n  hideLeverage,\n  ...rest\n}: VaultBorrowWrapProps<T, I, V>) => {\n  \n  const inputBtnRef = React.useRef()\n  const { t, i18n } = useTranslation()\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n\n  const getDisabled = () => {\n    return disabled || vaultBorrowData === undefined || vaultBorrowData?.coinInfoMap === undefined\n  }\n  const inputButtonDefaultProps = {\n    label: t('labelVaultBrowserToken'),\n    subLabel: t('labelVaultMaxBrowserLabel'),\n    tokenType: TokenType.vault,\n    placeholderText: vaultBorrowData.minBorrowStr\n      ? t('labelInvestMiniDual', {\n          value: vaultBorrowData.minBorrowStr,\n        })\n      : '0.00',\n    tokenImageKey: vaultBorrowData?.tradeData?.erc20Symbol,\n    belongAlice: vaultBorrowData?.tradeData?.erc20Symbol,\n  }\n  const label = React.useMemo(() => {\n    if (vaultBorrowBtnI18nKey) {\n      const key = vaultBorrowBtnI18nKey.split('|')\n      return t(\n        key[0],\n        key && key[1]\n          ? {\n              arg: key[1].toString(),\n              l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n              l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n              l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n              ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n            }\n          : {\n              l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n              l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n              l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n              ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n            },\n      )\n    } else {\n      return t(`labelVaultBorrowBtn`, {\n        l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n        loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n        l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n        l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n        ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n      })\n    }\n  }, [vaultBorrowBtnI18nKey])\n  return (\n    <Box\n      className={vaultBorrowData ? '' : 'loading'}\n      flexDirection={'column'}\n      justifyContent={'space-between'}\n      alignItems={'center'}\n      flex={1}\n      display={'flex'}\n      height={'auto'}\n    >\n      <Box\n        flexDirection={'column'}\n        display={'flex'}\n        alignSelf={'stretch'}\n        alignItems={'stretch'}\n        // borderBottom={'1px solid var(--color-border)'}\n      >\n        <BasicACoinTrade\n          {...{\n            ...rest,\n            type: TRADE_TYPE.TOKEN,\n            t,\n            i18n,\n            tReady: true,\n            disabled,\n            onChangeEvent,\n            walletMap,\n            tradeData,\n            coinMap,\n            inputButtonDefaultProps,\n            ...tokenProps,\n            inputBtnRef,\n            tokenNotEnough: 'labelVaultBorrowNotEnough',\n          }}\n        />\n      </Box>\n      <Divider sx={{ width: '100%', marginY: 3 }} />\n      <Grid container spacing={1} marginTop={0} alignItems={'stretch'}>\n        {!hideLeverage && <Grid\n          item\n          xs={12}\n          direction={'row'}\n          display={'flex'}\n          marginBottom={1}\n          justifyContent={'space-between'}\n          alignItems={'center'}\n        >\n          <Typography\n            component={'p'}\n            variant='body2'\n            color={'textSecondary'}\n            display={'inline-flex'}\n            alignItems={'center'}\n          >\n            {t('labelVaultLeverage')}\n          </Typography>\n          <Box display={'flex'} flexDirection={'row'} alignItems={'center'}>            \n            <Typography onClick={onClickLeverage} marginLeft={0.5} component={'p'} variant='body2' color={'textPrimary'} sx={{ cursor: 'pointer', textDecoration: 'underline' }}>\n              {userLeverage}x\n            </Typography>\n          </Box>\n        </Grid>}\n        <Grid\n          item\n          xs={12}\n          direction={'row'}\n          display={'flex'}\n          marginBottom={1}\n          justifyContent={'space-between'}\n          alignItems={'center'}\n        >\n          <Typography\n            component={'p'}\n            variant='body2'\n            color={'textSecondary'}\n            display={'inline-flex'}\n            alignItems={'center'}\n          >\n            {t('labelVaultBorrowed')}\n          </Typography>\n          <Box display={'flex'} flexDirection={'row'} alignItems={'center'}>\n            {vaultBorrowData.borrowedAmt !== '0' && vaultBorrowData.borrowedAmt ? (\n              <CoinIcon\n                tokenImageKey={vaultBorrowData.erc20Symbol}\n                symbol={vaultBorrowData.belong}\n                type={TokenType.vault}\n              />\n            ) : undefined}\n            <Typography marginLeft={0.5} component={'p'} variant='body2' color={'textPrimary'}>\n              {vaultBorrowData.borrowedAmt !== '0' && vaultBorrowData.borrowedAmt\n                ? vaultBorrowData.borrowedStr + ' ' + (vaultBorrowData as any).erc20Symbol\n                : EmptyValueTag}\n            </Typography>\n          </Box>\n        </Grid>\n        \n        <Grid\n          item\n          xs={12}\n          direction={'row'}\n          display={'flex'}\n          marginBottom={1}\n          justifyContent={'space-between'}\n          alignItems={'center'}\n        >\n          <Typography\n            component={'p'}\n            variant='body2'\n            color={'textSecondary'}\n            display={'inline-flex'}\n            alignItems={'center'}\n          >\n            {t('labelHourlyInterestRate')}\n          </Typography>\n          <Box display={'flex'} flexDirection={'row'} alignItems={'center'}>\n            <Typography marginLeft={0.5} component={'p'} variant='body2' color={'textPrimary'}>\n              {vaultBorrowData &&\n              (vaultBorrowData as any).hourlyRateInPercent &&\n              (vaultBorrowData as any).yearlyRateInPercent\n                ? `${(vaultBorrowData as any).hourlyRateInPercent}% (APR: ${\n                    (vaultBorrowData as any).yearlyRateInPercent\n                  }%)`\n                : EmptyValueTag}\n            </Typography>\n          </Box>\n        </Grid>\n        <Grid\n          item\n          xs={12}\n          direction={'row'}\n          display={'flex'}\n          marginBottom={1}\n          justifyContent={'space-between'}\n          alignItems={'center'}\n        >\n          <Typography\n            component={'p'}\n            variant='body2'\n            color={'textSecondary'}\n            display={'inline-flex'}\n            alignItems={'center'}\n          >\n            {t('labelVaultMarginLevel')}\n          </Typography>\n          <Box display={'flex'} flexDirection={'row'} alignItems={'center'}>\n            <Typography display={'flex'} alignItems={'center'} marginLeft={0.5} component={'p'} variant='body2' color={'textPrimary'}>\n              {marginLevelChange ? (\n                <>\n                  <Typography color={marginLevelTypeToColor(marginLevelChange.from.type)}>\n                    {numberFormat(marginLevelChange.from.marginLevel, {fixed: 2})}\n                  </Typography>\n                  <EastIcon sx={{marginX: 0.5}}/>\n                  <Typography color={marginLevelTypeToColor(marginLevelChange.to.type)}>\n                    {numberFormat(marginLevelChange.to.marginLevel, {fixed: 2})}\n                  </Typography>\n                </>\n              ) : (\n                EmptyValueTag\n              )}\n            </Typography>\n          </Box>\n        </Grid>\n      </Grid>\n\n      <Box\n        marginTop={1.5}\n        alignSelf={'stretch'}\n        display={'flex'}\n        flexDirection={'column'}\n        alignItems={'stretch'}\n      >\n        <ButtonStyle\n          variant={'contained'}\n          size={'large'}\n          color={'primary'}\n          onClick={() => {\n            onVaultBorrowClick()\n          }}\n          loading={\n            !getDisabled() && vaultBorrowBtnStatus === TradeBtnStatus.LOADING ? 'true' : 'false'\n          }\n          disabled={\n            getDisabled() ||\n            vaultBorrowBtnStatus === TradeBtnStatus.DISABLED ||\n            vaultBorrowBtnStatus === TradeBtnStatus.LOADING\n          }\n          fullWidth={true}\n        >\n          {label}\n        </ButtonStyle>\n      </Box>\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/VaultWrap/VaultJoin.tsx",
    "content": "import {\n  CoinInfo,\n  EmptyValueTag,\n  getValuePrecisionThousand,\n  IBData,\n  Info2Icon,\n  L1L2_NAME_DEFINED,\n  MapChainId,\n  mapSpecialTokenName,\n  TokenType,\n  TRADE_TYPE,\n  TradeBtnStatus,\n  VaultJoinData,\n} from '@loopring-web/common-resources'\nimport { Trans, useTranslation } from 'react-i18next'\nimport { VaultJoinWrapProps } from './Interface'\nimport React from 'react'\nimport { Box, Grid, Tooltip, Typography } from '@mui/material'\nimport { useSettings } from '../../../../stores'\nimport { ButtonStyle } from '../Styled'\nimport { BasicACoinTrade } from '../BasicACoinTrade'\nimport { InputButtonDefaultProps } from '../Interface'\nimport { BasicACoinInput } from '../BasicACoinInput'\nimport { CoinIcon } from '@loopring-web/component-lib'\nimport InfoIcon from '@mui/icons-material/Info'\nimport { numberFormat } from '@loopring-web/core'\nimport { marginLevelTypeToColor } from './utils'\nimport EastIcon from '@mui/icons-material/East'\n\nexport const VaultJoinWrap = <T extends IBData<I>, I, V extends VaultJoinData>({\n  disabled,\n  btnStatus,\n  tradeData,\n  vaultJoinData,\n  btnI18nKey,\n  onSubmitClick,\n  onChangeEvent,\n  propsExtends = {},\n  isActiveAccount,\n  // coinAPrecision,\n  // coinBPrecision,\n  tokenProps,\n  marginLevelChange,\n  holdingCollateral,\n  ...rest\n}: VaultJoinWrapProps<T, I, V>) => {\n  const { t, ...i18n } = useTranslation()\n  const inputBtnRef = React.useRef()\n  // const inputCoinRef = React.useRef()\n\n  let { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  // const [minFee] = React.useState<{ minFee: string } | undefined>(undefined)\n  const getDisabled = React.useMemo(() => {\n    return disabled || btnStatus === TradeBtnStatus.DISABLED\n  }, [btnStatus, disabled])\n\n  const inputButtonDefaultProps: InputButtonDefaultProps<I, CoinInfo<I>> = {\n    label: t('labelEnterToken'),\n    focusOnInput: true,\n  }\n  // myLog('VaultJoinWrap inputBtnRef', inputBtnRef)\n  const label = React.useMemo(() => {\n    if (btnI18nKey) {\n      const key = btnI18nKey.split('|')\n      return t(\n        key[0],\n        key && key[1]\n          ? {\n              arg: key[1].toString(),\n              l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n              l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n              l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n              ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n            }\n          : {\n              l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n              l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n              l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n              ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n            },\n      )\n    } else {\n      return t(isActiveAccount ? `labelVaultJoinBtn` : `labelVaultConfirm`, {\n        l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n        loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n        l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n        l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n        ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n      })\n    }\n  }, [btnI18nKey, isActiveAccount, network, t])\n\n  return (\n    <Grid\n      className={vaultJoinData ? '' : 'loading'}\n      container\n      direction={'column'}\n      justifyContent={'space-between'}\n      alignItems={'center'}\n      flex={1}\n      height={'270px'}\n      paddingX={3}\n    >\n      <Grid\n        item\n        marginTop={3}\n        display={'flex'}\n        alignSelf={'stretch'}\n        justifyContent={''}\n        alignItems={'stretch'}\n        flexDirection={'column'}\n      >\n        <BasicACoinTrade\n          {...{\n            ...rest,\n            ...i18n,\n            t,\n            tReady: true,\n            tradeData: tradeData as any,\n            type: TRADE_TYPE.TOKEN,\n            disabled,\n            onChangeEvent: onChangeEvent as any,\n            inputButtonDefaultProps: {\n              ...inputButtonDefaultProps,\n              disableBelong: !isActiveAccount,\n              label: \"Amount\",\n            },\n            placeholderText: '0.00',\n            inputBtnRef,\n            tokenNotEnough: t(\n              rest.isAddOrRedeem === 'Add'\n                ? `labelVaultJoinNotEnough`\n                : `labelVaultRedeemNotEnough`,\n              { arg: tradeData.belong },\n            ),\n            ...tokenProps,\n          }}\n        />\n      </Grid>\n      <Grid item alignSelf={'stretch'} marginTop={2}>\n        <Grid container direction={'column'} spacing={1} alignItems={'stretch'}>\n          {/* <Grid item paddingBottom={1} sx={{ color: 'text.secondary' }}>\n            {rest.isAddOrRedeem === 'Add' ? (\n              <Grid\n                container\n                justifyContent={'space-between'}\n                direction={'row'}\n                alignItems={'center'}\n                height={24}\n              >\n                <Tooltip title={t('labelVaultTotalQuoteDes').toString()}>\n                  <Typography\n                    component={'span'}\n                    variant='body2'\n                    color={'textSecondary'}\n                    alignItems={'center'}\n                    display={'flex'}\n                  >\n                    <Trans i18nKey={'labelVaultTotalQuote'}>\n                      {t('labelVaultQuota')}\n                      <Info2Icon fontSize={'small'} color={'inherit'} sx={{ marginX: 1 / 2 }} />\n                    </Trans>\n                  </Typography>\n                </Tooltip>\n\n                {vaultJoinData && vaultJoinData?.maxShowVal ? (\n                  <Typography component={'span'} variant='body2' color={'textPrimary'}>\n                    {vaultJoinData?.maxShowVal + ' ' + mapSpecialTokenName(vaultJoinData?.belong as string) }\n                  </Typography>\n                ) : (\n                  EmptyValueTag\n                )}\n              </Grid>\n            ) : (\n              <Grid\n                container\n                justifyContent={'space-between'}\n                direction={'row'}\n                alignItems={'center'}\n                height={24}\n              >\n                <Typography\n                  component={'span'}\n                  variant='body2'\n                  color={'textSecondary'}\n                  alignItems={'center'}\n                  display={'flex'}\n                >\n                  {t('labelVaultHoldingCollateral')}\n                </Typography>\n\n                {holdingCollateral ? (\n                  <Typography component={'span'} variant='body2' color={'textPrimary'}>\n                    {holdingCollateral + ' ' + mapSpecialTokenName(vaultJoinData?.belong as string)}\n                  </Typography>\n                ) : (\n                  EmptyValueTag\n                )}\n              </Grid>\n            )}\n\n            {!isActiveAccount ? (\n              <Grid\n                container\n                justifyContent={'space-between'}\n                direction={'row'}\n                alignItems={'center'}\n                marginTop={1 / 2}\n              >\n                <Typography\n                  component={'span'}\n                  variant='body2'\n                  color={'textSecondary'}\n                  alignItems={'center'}\n                  display={'inline-flex'}\n                >\n                  {t('labelVaultMarginLevel')}\n                </Typography>\n                <Box display={'flex'} flexDirection={'row'} alignItems={'center'}>\n                  {marginLevelChange ? (\n                    <>\n                      <Typography color={marginLevelTypeToColor(marginLevelChange.from.type)}>\n                        {numberFormat(marginLevelChange.from.marginLevel, { fixed: 2 })}\n                      </Typography>\n                      <EastIcon sx={{ marginX: 0.5 }} />\n                      <Typography color={marginLevelTypeToColor(marginLevelChange.to.type)}>\n                        {numberFormat(marginLevelChange.to.marginLevel, { fixed: 2 })}\n                      </Typography>\n                    </>\n                  ) : (\n                    EmptyValueTag\n                  )}\n                </Box>\n              </Grid>\n            ) : null}\n          </Grid> */}\n\n          <Grid sx={{opacity: rest.isAddOrRedeem === 'Redeem' ? 1 : 0}} item display={'flex'} marginBottom={1}>\n            <InfoIcon sx={{ marginRight: 1, color: 'var(--color-text-secondary)' }} />\n            <Typography color={'var(--color-text-secondary)'} variant={'body2'}>\n              {t('labelVaultRedeemAlert')}\n            </Typography>\n          </Grid>\n          <Grid item>\n            <ButtonStyle\n              sx={{textTransform: 'none'}}\n              variant={'contained'}\n              size={'large'}\n              color={'primary'}\n              onClick={() => {\n                onSubmitClick(tradeData)\n              }}\n              loading={!getDisabled && btnStatus === TradeBtnStatus.LOADING ? 'true' : 'false'}\n              disabled={\n                getDisabled ||\n                btnStatus === TradeBtnStatus.DISABLED ||\n                btnStatus === TradeBtnStatus.LOADING\n              }\n              fullWidth={true}\n            >\n              {label}\n            </ButtonStyle>\n          </Grid>\n        </Grid>\n      </Grid>\n    </Grid>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/VaultWrap/VaultRepay.tsx",
    "content": "import {\n  BackIcon,\n  EmptyValueTag,\n  getValuePrecisionThousand,\n  IBData,\n  L1L2_NAME_DEFINED,\n  MapChainId,\n  myLog,\n  TokenType,\n  TradeBtnStatus,\n  VaultRepayData,\n} from '@loopring-web/common-resources'\nimport { VaultRepayWrapProps } from './Interface'\nimport { useTranslation } from 'react-i18next'\nimport React from 'react'\nimport { Grid, Typography, Box, Divider } from '@mui/material'\nimport { ButtonStyle } from '../Styled'\nimport { useSettings } from '../../../../stores'\nimport { BasicACoinTrade } from '../BasicACoinTrade'\nimport {\n  CoinIcon,\n} from '@loopring-web/component-lib'\nimport { numberFormat } from '@loopring-web/core'\nimport { marginLevelTypeToColor } from './utils'\nimport EastIcon from '@mui/icons-material/East';\n\nexport const VaultRepayWrap = <\n  T extends IBData<any> & { borrowed: string; max: string },\n  I,\n  VR extends VaultRepayData<T>,\n>({\n  disabled,\n  vaultRepayBtnStatus,\n  onVaultRepayClick,\n  vaultRepayBtnI18nKey,\n  tokenProps,\n  propsExtends,\n  tradeData,\n  vaultRepayData,\n  onChangeEvent,\n  walletMap,\n  tokenInfo,\n  handleError,\n  marginLevelChange,\n  ...rest\n}: VaultRepayWrapProps<T, I, VR>) => {\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const coinRef = React.useRef()\n\n  const { t, i18n } = useTranslation()\n  const getDisabled = () => {\n    return (\n      disabled ||\n      vaultRepayData?.tradeData === undefined ||\n      vaultRepayData?.coinInfoMap === undefined\n    )\n  }\n  const inputButtonDefaultProps = {\n    label: t('labelTokenAmount'),\n    subLabel: '',\n    placeholderText: vaultRepayData.minRepayStr\n      ? t('labelInvestMiniDual', {\n          value: vaultRepayData.minRepayStr,\n        })\n      : '0.00',\n    maxAllow: true,\n    tokenType: TokenType.vault,\n    order: 'right',\n    tokenImageKey: vaultRepayData?.tradeData?.erc20Symbol,\n    belongAlice: vaultRepayData?.tradeData?.erc20Symbol,\n    // maxValue: vaultRepayData?.tradeData?.borrowed,\n  }\n  const label = React.useMemo(() => {\n    if (vaultRepayBtnI18nKey) {\n      const key = vaultRepayBtnI18nKey.split('|')\n      return t(\n        key[0],\n        key && key[1]\n          ? {\n              arg: key[1].toString(),\n              l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n              l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n              l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n              ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n            }\n          : {\n              l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n              l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n              l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n              ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n            },\n      )\n    } else {\n      return t(`labelVaultRepayBtn`, {\n        l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n        loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n        l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n        l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n        ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n      })\n    }\n  }, [vaultRepayBtnI18nKey, network])\n\n  return (\n    <Box\n      className={vaultRepayData ? '' : 'loading'}\n      flexDirection={'column'}\n      justifyContent={'space-between'}\n      alignItems={'center'}\n      flex={1}\n      display={'flex'}\n      height={'100%'}\n    >\n      <Box\n        flexDirection={'column'}\n        display={'flex'}\n        alignSelf={'stretch'}\n        alignItems={'stretch'}\n        // borderBottom={'1px solid var(--color-border)'}\n      >\n        <BasicACoinTrade\n          isMaxBtn={true}\n          inputBtnRef={coinRef}\n          {...{\n            ...rest,\n            t,\n            i18n,\n            tReady: true,\n            disabled,\n            onChangeEvent: onChangeEvent as any,\n            walletMap,\n            tradeData: tradeData as any,\n            coinMap: vaultRepayData?.coinInfoMap as any,\n            inputButtonDefaultProps,\n            ...tokenProps,\n            tokenNotEnough: 'labelVaultRepayNotEnough'\n          }}\n        />\n      </Box>\n      <Divider sx={{ width: '100%', marginY: 2 }} />\n      <Grid container spacing={1} alignItems={'stretch'}>\n        <Grid\n          item\n          xs={12}\n          direction={'row'}\n          display={'flex'}\n          marginBottom={1}\n          justifyContent={'space-between'}\n          alignItems={'center'}\n        >\n          <Typography\n            component={'p'}\n            variant='body2'\n            color={'textSecondary'}\n            display={'inline-flex'}\n            alignItems={'center'}\n          >\n            {t('labelVaultRepayBalance')}\n          </Typography>\n          <Box display={'flex'} flexDirection={'row'} alignItems={'center'}>\n            <CoinIcon\n              tokenImageKey={(vaultRepayData as any).erc20Symbol}\n              symbol={vaultRepayData.belong}\n              type={TokenType.vault}\n            />\n            <Typography component={'p'} variant='body2' color={'textPrimary'}>\n              {getValuePrecisionThousand(\n                vaultRepayData?.tradeData?.balance,\n                tokenInfo?.vaultTokenAmounts.qtyStepScale ?? 6,\n                tokenInfo?.vaultTokenAmounts.qtyStepScale ?? 6,\n              ) +\n                ' ' +\n                (vaultRepayData as any).erc20Symbol}\n            </Typography>\n          </Box>\n        </Grid>\n        <Grid\n          item\n          xs={12}\n          direction={'row'}\n          display={'flex'}\n          marginBottom={1}\n          justifyContent={'space-between'}\n          alignItems={'center'}\n        >\n          <Typography\n            component={'p'}\n            variant='body2'\n            color={'textSecondary'}\n            display={'inline-flex'}\n            alignItems={'center'}\n          >\n            {t('labelRepayQuota')}\n          </Typography>\n          <Box display={'flex'} flexDirection={'row'} alignItems={'center'}>\n            <CoinIcon\n              tokenImageKey={(vaultRepayData as any).erc20Symbol}\n              symbol={vaultRepayData.belong}\n              type={TokenType.vault}\n            />\n            <Typography component={'p'} variant='body2' color={'textPrimary'}>\n              {getValuePrecisionThousand(\n                vaultRepayData?.tradeData?.borrowed,\n                tokenInfo?.precision ?? 6,\n                tokenInfo?.precision ?? 6,\n              ) +\n                ' ' +\n                (vaultRepayData as any).erc20Symbol}\n            </Typography>\n          </Box>\n        </Grid>\n        <Grid\n          item\n          xs={12}\n          direction={'row'}\n          display={'flex'}\n          marginBottom={1}\n          justifyContent={'space-between'}\n          alignItems={'center'}\n        >\n          <Typography\n            component={'p'}\n            variant='body2'\n            color={'textSecondary'}\n            display={'inline-flex'}\n            alignItems={'center'}\n          >\n            {t('labelVaultMarginLevel')}\n          </Typography>\n          <Box display={'flex'} flexDirection={'row'} alignItems={'center'}>\n          <Typography display={'flex'} alignItems={'center'} marginLeft={0.5} component={'p'} variant='body2' color={'textPrimary'}>\n              {marginLevelChange ? (\n                <>\n                  <Typography color={marginLevelTypeToColor(marginLevelChange.from.type)}>\n                    {numberFormat(marginLevelChange.from.marginLevel, {fixed: 2})}\n                  </Typography>\n                  <EastIcon sx={{marginX: 0.5}}/>\n                  <Typography color={marginLevelTypeToColor(marginLevelChange.to.type)}>\n                    {numberFormat(marginLevelChange.to.marginLevel, {fixed: 2})}\n                  </Typography>\n                </>\n              ) : (\n                EmptyValueTag\n              )}\n            </Typography>\n          </Box>\n        </Grid>\n      </Grid>\n\n      <Grid marginTop={2} container spacing={2}>\n        <Grid item xs={6}>\n          <ButtonStyle\n            variant={'outlined'}\n            size={'medium'}\n            sx={{ height: 40 }}\n            onClick={() => {\n              onChangeEvent(1, {\n                tradeData: { ...tradeData, tradeValue: 0 },\n                to: 'menu',\n              })\n            }}\n            startIcon={<BackIcon />}\n            fullWidth={true}\n          >\n            {t('labelBack')}\n          </ButtonStyle>\n        </Grid>\n        <Grid item xs={6}>\n          <ButtonStyle\n            variant={'contained'}\n            size={'medium'}\n            color={'primary'}\n            onClick={() => {\n              onVaultRepayClick()\n            }}\n            loading={\n              !getDisabled() && vaultRepayBtnStatus === TradeBtnStatus.LOADING ? 'true' : 'false'\n            }\n            disabled={\n              getDisabled() ||\n              vaultRepayBtnStatus === TradeBtnStatus.DISABLED ||\n              vaultRepayBtnStatus === TradeBtnStatus.LOADING\n            }\n            fullWidth={true}\n          >\n            {label}\n          </ButtonStyle>\n        </Grid>\n      </Grid>\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/VaultWrap/index.ts",
    "content": "// this is a private component, only used in panel component\n// please do not export this index to global\n// export * from './Interface'\nexport * from './Interface'\nexport * from './VaultJoin'\nexport * from './VaultBorrow'\nexport * from './VaultRepay'\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/VaultWrap/styled.ts",
    "content": "import styled from '@emotion/styled'\n\nexport const SvgStyled = styled.div`\n  & svg {\n    width: 24px;\n    height: 24px;\n  }\n`\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/VaultWrap/utils.ts",
    "content": "export const marginLevelTypeToColor = (type: 'safe' | 'warning' | 'danger') => {\n  return type === 'safe'\n    ? 'var(--color-success)'\n    : type === 'warning'\n    ? 'var(--color-warning)'\n    : 'var(--color-error)'\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/WithdrawConfirm.tsx",
    "content": "import { useTranslation } from 'react-i18next'\nimport { Box, Grid, Typography } from '@mui/material'\nimport {\n  EmptyValueTag,\n  FeeInfo,\n  IBData,\n  L1L2_NAME_DEFINED,\n  MapChainId,\n  NFTWholeINFO,\n  TOAST_TIME,\n} from '@loopring-web/common-resources'\nimport { Button, Toast, ToastType, useAddressTypeLists } from '../../index'\nimport { WithdrawViewProps } from './Interface'\nimport { useSettings } from '../../../stores'\nimport React from 'react'\nimport { sanitize } from 'dompurify'\n\nexport const WithdrawConfirm = <T extends IBData<I> & Partial<NFTWholeINFO>, I, C extends FeeInfo>({\n  handleConfirm,\n  tradeData,\n  onWithdrawClick,\n  realAddr,\n  lastFailed,\n  type,\n  feeInfo,\n  isToMyself,\n  sureIsAllowAddress,\n}: Partial<WithdrawViewProps<T, I, C>> & {\n  handleConfirm: (index: number) => void\n}) => {\n  const { t } = useTranslation()\n  const { isMobile, defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const [open, setOpen] = React.useState(false)\n  const { walletList, exchangeList } = useAddressTypeLists()\n  return (\n    <Grid\n      className={'confirm'}\n      container\n      paddingLeft={isMobile ? 2 : 5 / 2}\n      paddingRight={isMobile ? 2 : 5 / 2}\n      direction={'column'}\n      alignItems={'stretch'}\n      flex={1}\n      height={'100%'}\n      minWidth={240}\n      flexWrap={'nowrap'}\n      spacing={2}\n    >\n      <Grid item xs={12}>\n        <Box\n          display={'flex'}\n          flexDirection={'column'}\n          justifyContent={'center'}\n          alignItems={'center'}\n          marginBottom={2}\n        >\n          <Typography\n            component={'h4'}\n            variant={isMobile ? 'h4' : 'h3'}\n            whiteSpace={'pre'}\n            marginRight={1}\n          >\n            {(tradeData as NFTWholeINFO)?.isCounterFactualNFT &&\n            (tradeData as NFTWholeINFO)?.deploymentStatus === 'NOT_DEPLOYED'\n              ? t('labelL2ToL1DeployTitle', { l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol })\n              : isToMyself\n              ? t('labelL2ToMyL1Title', { l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol })\n              : t('labelL2ToOtherL1Title', { l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol })}\n          </Typography>\n        </Box>\n      </Grid>\n      <Grid item xs={12}>\n        <Typography color={'var(--color-text-third)'} variant={'body1'}>\n          {t('labelL2toL2TokenAmount')}\n        </Typography>\n        <Typography color={'textPrimary'} marginTop={1} variant={'body1'}>\n          {tradeData?.tradeValue}\n          <Typography\n            component={'span'}\n            color={'textSecondary'}\n            dangerouslySetInnerHTML={{\n              __html:\n                sanitize(\n                  type === 'NFT'\n                    ? ' \\u2A09 ' + tradeData?.name ?? 'NFT'\n                    : ` ${tradeData?.belong}` ?? EmptyValueTag,\n                ) ?? '',\n            }}\n          />\n        </Typography>\n      </Grid>\n      <Grid item xs={12}>\n        <Typography color={'var(--color-text-third)'} variant={'body1'}>\n          {t('labelL2toL2Address')}\n        </Typography>\n        <Typography color={'textPrimary'} marginTop={1} variant={'body1'}>\n          {realAddr}\n        </Typography>\n      </Grid>\n      {!isToMyself && (\n        <Grid item xs={12}>\n          <Typography color={'var(--color-text-third)'} variant={'body1'}>\n            {t('labelL2toL1AddressType')}\n          </Typography>\n          <Typography color={'textPrimary'} marginTop={1} variant={'body1'}>\n            {\n              [...walletList, ...exchangeList].find((item) => item.value === sureIsAllowAddress)\n                ?.label\n            }\n          </Typography>\n        </Grid>\n      )}\n      <Grid item xs={12}>\n        <Typography color={'var(--color-text-third)'} variant={'body1'}>\n          {t('labelForceWithdrawFee')}\n        </Typography>\n        <Typography color={'textPrimary'} marginTop={1} variant={'body1'}>\n          {feeInfo?.fee + ' '} {feeInfo?.belong}\n        </Typography>\n      </Grid>\n\n      <Grid item marginTop={2} alignSelf={'stretch'} paddingBottom={0}>\n        {lastFailed && (\n          <Typography paddingBottom={1} textAlign={'center'} color={'var(--color-warning)'}>\n            {t('labelConfirmAgainByFailedWithBalance', {\n              symbol: type === 'NFT' ? 'NFT' : ` ${tradeData?.belong}` ?? EmptyValueTag,\n              count: tradeData?.balance,\n            })}\n          </Typography>\n        )}\n        <Button\n          fullWidth\n          variant={'contained'}\n          size={'medium'}\n          color={'primary'}\n          onClick={async () => {\n            if (onWithdrawClick) {\n              await onWithdrawClick({ ...tradeData } as unknown as T)\n            } else {\n              setOpen(true)\n            }\n            handleConfirm(1)\n          }}\n        >\n          {t('labelConfirm')}\n        </Button>\n      </Grid>\n      <Toast\n        alertText={t('errorBase', { ns: 'error' })}\n        open={open}\n        autoHideDuration={TOAST_TIME}\n        onClose={() => {\n          setOpen(false)\n        }}\n        severity={ToastType.error}\n      />\n    </Grid>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/WithdrawWrap.tsx",
    "content": "import { Trans, WithTranslation } from 'react-i18next'\nimport React, { useState } from 'react'\nimport { bindHover } from 'material-ui-popup-state/es'\nimport { bindPopper, usePopupState } from 'material-ui-popup-state/hooks'\nimport { Box, Checkbox, Grid, IconButton, InputAdornment, Tooltip, Typography } from '@mui/material'\nimport {\n  AddressError,\n  AlertIcon,\n  AssetsRawDataItem,\n  BackIcon,\n  CheckBoxIcon,\n  CheckedIcon,\n  CloseIcon,\n  ContactIcon,\n  copyToClipBoard,\n  DropDownIcon,\n  EmptyValueTag,\n  FeeInfo,\n  fontDefault,\n  globalSetup,\n  hexToRGB,\n  IBData,\n  Info2Icon,\n  L1L2_NAME_DEFINED,\n  LoadingIcon,\n  MapChainId,\n  NFTWholeINFO,\n  TOAST_TIME,\n  TradeBtnStatus,\n  WALLET_TYPE,\n  WithdrawType,\n} from '@loopring-web/common-resources'\nimport { CustomCheckBox, FeeSelect, GridWrapStyle, InputSize, PopoverPure, SpaceBetweenBox, Toast, ToastType } from '../..'\nimport { Button, TextField, useSettings } from '../../../index'\nimport { WithdrawViewProps } from './Interface'\nimport { BasicACoinTrade } from './BasicACoinTrade'\nimport { NFTInput } from './BasicANFTTrade'\nimport { FullAddressType } from './AddressType'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { useTheme } from '@emotion/react'\nimport { useSystem } from '@loopring-web/core'\nimport RadioButtonCheckedIcon from '@mui/icons-material/RadioButtonChecked'\nimport RadioButtonUncheckedIcon from '@mui/icons-material/RadioButtonUnchecked';\n\n\nconst formatTokenList = (tokens: string[]):string => {\n  if (!tokens || tokens.length === 0) return '';\n  if (tokens.length === 1) return tokens[0];\n  if (tokens.length === 2) return `${tokens[0]} and ${tokens[1]}`;\n  \n  const lastToken = tokens[tokens.length - 1];\n  const otherTokens = tokens.slice(0, -1);\n  return `${otherTokens.join(', ')}, and ${lastToken}`;\n}\n\nexport const WithdrawWrap = <\n  T extends IBData<I> | (NFTWholeINFO & IBData<I>),\n  I,\n  C extends FeeInfo,\n>({\n  t,\n  title,\n  disabled,\n  walletMap,\n  tradeData,\n  coinMap,\n  type,\n  withdrawI18nKey,\n  addressDefault,\n  accAddr,\n  isNotAvailableAddress,\n  withdrawType,\n  chargeFeeTokenList = [],\n  feeInfo,\n  lastFailed,\n  handleConfirm,\n  isFeeNotEnough,\n  withdrawBtnStatus,\n  handleFeeChange,\n  handleWithdrawTypeChange,\n  handleOnAddressChange,\n  isAddressCheckLoading,\n  isCFAddress,\n  isLoopringAddress,\n  isContractAddress,\n  isFastWithdrawAmountLimit,\n  addrStatus,\n  disableWithdrawList = [],\n  wait = globalSetup.wait,\n  assetsData = [],\n  realAddr,\n  isThumb,\n  baseURL,\n  isToMyself = false,\n  sureIsAllowAddress,\n  handleSureIsAllowAddress,\n  contact,\n  isFromContact,\n  onClickContact,\n  loopringSmartWalletVersion,\n  isENSWrong,\n  ens,\n  geUpdateContact,\n  withdrawMode,\n  ...rest\n}: WithdrawViewProps<T, I, C> &\n  WithTranslation & {\n    assetsData: AssetsRawDataItem[]\n    handleConfirm: (index: number) => void\n  }) => {\n  const { isMobile, defaultNetwork } = useSettings()\n  const { app } = useSystem()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const theme = useTheme()\n\n  const [dropdownStatus, setDropdownStatus] = React.useState<'up' | 'down'>('down')\n  const popupState = usePopupState({\n    variant: 'popover',\n    popupId: `popupId-withdraw`,\n  })\n\n  const [copyToastOpen, setCopyToastOpen] = useState(false)\n  const onCopy = React.useCallback(\n    async (content: string) => {\n      copyToClipBoard(content)\n      setCopyToastOpen(true)\n    },\n    [setCopyToastOpen],\n  )\n\n  const inputBtnRef = React.useRef()\n\n  const getDisabled = React.useMemo(() => {\n    return disabled || withdrawBtnStatus === TradeBtnStatus.DISABLED\n  }, [disabled, withdrawBtnStatus])\n  const inputButtonDefaultProps = {\n    label: t('labelL2toL1EnterToken'),\n    // loading: isFeeNotEnough.isOnLoading,\n  }\n\n  const handleToggleChange = (value: C) => {\n    if (handleFeeChange) {\n      handleFeeChange(value)\n    }\n  }\n\n  const _handleWithdrawTypeChange = React.useCallback(\n    (e: WithdrawType) => {\n      if (handleWithdrawTypeChange) {\n        handleWithdrawTypeChange(e as any)\n      }\n    },\n    [handleWithdrawTypeChange],\n  )\n\n  const isInvalidAddressOrENS =\n    !isAddressCheckLoading && addressDefault && addrStatus === AddressError.InvalidAddr\n  const allowToClickIsSure = React.useMemo(() => {\n    return isAddressCheckLoading || addrStatus === AddressError.InvalidAddr || !realAddr\n  }, [addrStatus, isAddressCheckLoading, realAddr])\n  const isEarn = app === 'earn';\n  const label = React.useMemo(() => {\n    if (isEarn) {\n      return t('labelWithdrawBtn')\n    } else if (withdrawI18nKey) {\n      const key = withdrawI18nKey.split('|')\n      return t(\n        key[0],\n        key && key[1]\n          ? {\n              arg: key[1],\n              l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n              l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n              l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n              ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n            }\n          : {\n              l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n              l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n              l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n              ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n            },\n      )\n    } else {\n      return t(\n        (tradeData as NFTWholeINFO)?.isCounterFactualNFT &&\n          (tradeData as NFTWholeINFO)?.deploymentStatus === 'NOT_DEPLOYED'\n          ? `labelSendL1DeployBtn`\n          : `labelSendL1Btn`,\n        {\n          layer2: L1L2_NAME_DEFINED[network].layer2,\n          l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n          loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n          l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n          l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n          ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n        },\n      )\n    }\n  }, [t, tradeData, withdrawI18nKey])\n  const detectedWalletType = loopringSmartWalletVersion?.isLoopringSmartWallet\n    ? WALLET_TYPE.Loopring\n    : isContractAddress\n    ? WALLET_TYPE.OtherSmart\n    : WALLET_TYPE.EOA\n\n  return (\n    <GridWrapStyle\n      className={'withdraw-wrap'}\n      container\n      paddingLeft={5 / 2}\n      paddingRight={5 / 2}\n      direction={'column'}\n      justifyContent={'space-between'}\n      alignItems={'center'}\n      flex={1}\n      minWidth={240}\n      height={'100%'}\n      flexWrap={'nowrap'}\n      spacing={2}\n    >\n      <Grid item>\n        <Box\n          display={'flex'}\n          flexDirection={'row'}\n          justifyContent={'center'}\n          alignItems={'center'} /* marginBottom={2} */\n        >\n          <Typography\n            component={'h4'}\n            variant={isMobile ? 'h4' : 'h3'}\n            whiteSpace={'pre'}\n            marginRight={1}\n          >\n            {isEarn\n              ? t('labelWithdrawBtn')\n              : title\n              ? title\n              : (tradeData as NFTWholeINFO)?.isCounterFactualNFT &&\n                (tradeData as NFTWholeINFO)?.deploymentStatus === 'NOT_DEPLOYED'\n              ? t('labelL2ToL1DeployTitle', { l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol })\n              : isToMyself\n              ? t('labelL2ToMyL1Title', { l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol })\n              : t('labelL2ToOtherL1Title', { l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol })}\n          </Typography>\n          <Info2Icon\n            {...bindHover(popupState)}\n            fontSize={'large'}\n            htmlColor={'var(--color-text-third)'}\n          />\n        </Box>\n        <PopoverPure\n          className={'arrow-center'}\n          {...bindPopper(popupState)}\n          anchorOrigin={{\n            vertical: 'bottom',\n            horizontal: 'center',\n          }}\n          transformOrigin={{\n            vertical: 'top',\n            horizontal: 'center',\n          }}\n        >\n          <Typography padding={2} maxWidth={490} variant={'body2'} whiteSpace={'pre-line'}>\n            <Trans\n              i18nKey='withdrawDescription'\n              tOptions={{\n                l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n              }}\n            >\n              Your withdrawal will be processed in the next batch, which usually takes 30 minutes to\n              2 hours. (There will be a large delay if the Ethereum gas price exceeds 500 GWei.）\n            </Trans>\n          </Typography>\n        </PopoverPure>\n      </Grid>\n\n      <Grid item alignSelf={'stretch'} position={'relative'}>\n        {type === 'NFT' ? (\n          <NFTInput\n            {...({\n              ...rest,\n              isThumb,\n              type,\n              onCopy,\n              t,\n              baseURL: baseURL ?? '',\n              getIPFSString: rest.getIPFSString ?? (() => '' as any),\n              disabled,\n              walletMap,\n              tradeData,\n              coinMap,\n              inputNFTDefaultProps: { label: '', size: InputSize.middle },\n              inputNFTRef: inputBtnRef,\n            } as any)}\n          />\n        ) : (\n          <BasicACoinTrade\n            {...{\n              ...rest,\n              type,\n              t,\n              disabled,\n              walletMap,\n              tradeData,\n              coinMap,\n              inputButtonDefaultProps,\n              inputBtnRef: inputBtnRef,\n            }}\n          />\n        )}\n      </Grid>\n\n      <Grid item alignSelf={'stretch'} position={'relative'} className={'address-wrap'}>\n        {!isToMyself ? (\n          <>\n            <TextField\n              size={'large'}\n              className={'text-address'}\n              value={addressDefault}\n              error={!!(isNotAvailableAddress || isInvalidAddressOrENS || isENSWrong)}\n              placeholder={t('labelPleaseInputWalletAddress')}\n              onChange={(event) => handleOnAddressChange(event?.target?.value)}\n              label={t('labelL2toL1Address', {\n                l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n              })}\n              SelectProps={{ IconComponent: DropDownIcon }}\n              fullWidth={true}\n              InputProps={{\n                style: {\n                  paddingRight: '0',\n                },\n                endAdornment: isFromContact ? undefined : (\n                  <InputAdornment\n                    style={{\n                      cursor: 'pointer',\n                      paddingRight: '0',\n                    }}\n                    position='end'\n                  >\n                    {addressDefault !== '' ? (\n                      isAddressCheckLoading ? (\n                        <LoadingIcon width={24} />\n                      ) : (\n                        <IconButton\n                          color={'inherit'}\n                          size={'small'}\n                          aria-label='Clear'\n                          onClick={() => handleOnAddressChange('')}\n                        >\n                          <CloseIcon />\n                        </IconButton>\n                      )\n                    ) : (\n                      ''\n                    )}\n                    <IconButton\n                      color={'inherit'}\n                      size={'large'}\n                      aria-label='Clear'\n                      onClick={() => {\n                        onClickContact!()\n                      }}\n                    >\n                      <ContactIcon />\n                    </IconButton>\n                  </InputAdornment>\n                ),\n              }}\n            />\n          </>\n        ) : (\n          <Typography variant={'body2'} lineHeight={'20px'} color={'var(--color-text-third)'}>\n            {t('labelL2toL1MyAddress', { l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol })}\n\n            {!!isAddressCheckLoading && (\n              <LoadingIcon width={24} style={{ top: 20, right: '8px', position: 'absolute' }} />\n            )}\n          </Typography>\n        )}\n        <Box marginLeft={1 / 2}>\n          {isInvalidAddressOrENS ? (\n            <Typography\n              color={'var(--color-error)'}\n              variant={'body2'}\n              marginTop={1 / 4}\n              alignSelf={'stretch'}\n              position={'relative'}\n            >\n              {t('labelInvalidAddress')}\n            </Typography>\n          ) : isNotAvailableAddress ? (\n            <Typography\n              color={'var(--color-error)'}\n              variant={'body2'}\n              marginTop={1 / 4}\n              alignSelf={'stretch'}\n              position={'relative'}\n            >\n              {t(`labelInvalid${isNotAvailableAddress}`, {\n                token: type === 'NFT' ? 'NFT' : tradeData.belong,\n                way: t(`labelL2toL1`, {\n                  layer2: L1L2_NAME_DEFINED[network].layer2,\n                  l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                  loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                  l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                  l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                  ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                }),\n              })}\n            </Typography>\n          ) : (\n            <>\n              {addressDefault && realAddr && !isAddressCheckLoading && (\n                <Typography\n                  color={'var(--color-text-primary)'}\n                  variant={'body2'}\n                  marginTop={1 / 4}\n                  whiteSpace={'pre-line'}\n                  style={{ wordBreak: 'break-all' }}\n                >\n                  {realAddr}\n                </Typography>\n              )}\n            </>\n          )}\n          {isENSWrong && (\n            <>\n              <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n                {ens}\n              </Typography>\n              <Button\n                variant={'contained'}\n                sx={{\n                  fontSize: fontDefault.body1,\n                  marginTop: 2,\n                  padding: 1,\n                  color: 'var(--color-text-button)',\n                  display: 'flex',\n                  alignItems: 'center',\n                  background: hexToRGB(theme.colorBase.warning, 0.2),\n                  textAlign: 'left',\n                  borderRadius: 2,\n                  height: 'auto',\n                  '&:hover': {\n                    background: hexToRGB(theme.colorBase.warning, 0.3),\n                  },\n                }}\n                onClick={geUpdateContact}\n                endIcon={<BackIcon fontSize={'large'} sx={{ transform: 'rotate(180deg)' }} />}\n              >\n                <Typography component={'span'} color={'inherit'} display={'inline-flex'}>\n                  <AlertIcon color={'warning'} sx={{ marginRight: 1 / 2, marginTop: '2px' }} />\n                  {t('labelContactENSAlert')}\n                </Typography>\n              </Button>\n            </>\n          )}\n        </Box>\n      </Grid>\n      {!isToMyself && (\n        <Grid item alignSelf={'stretch'} position={'relative'} className={'address-type-wrap'}>\n          <FullAddressType\n            detectedWalletType={detectedWalletType}\n            selectedValue={sureIsAllowAddress}\n            handleSelected={handleSureIsAllowAddress}\n            disabled={allowToClickIsSure}\n          />\n        </Grid>\n      )}\n\n      {withdrawMode?.showTrustUI && (\n        <Box width={'100%'} pl={2} mb={isToMyself ? 5 : 2} mt={isToMyself ? 5 : 3}>\n          {withdrawMode?.showFastMode && (\n            <SpaceBetweenBox\n              borderRadius={'4px 4px 0 0'}\n              px={2}\n              py={0.5}\n              leftNode={\n                <Box display={'flex'} alignItems={'center'}>\n                  <Box mr={1.5}>\n                    <CustomCheckBox\n                      checked={withdrawMode.mode === 'fast'}\n                      onCheck={() => {\n                        withdrawMode.onChange('fast')\n                      }}\n                    />\n                  </Box>\n                  <Box>\n                    <Tooltip\n                      title={\n                        <Typography color={'var(--color-text-secondary)'} fontSize={'11px'}>\n                          Trust Mode: Operated by Loopring’s team to maintain liquidity. <br />\n                          Supported Assets: {formatTokenList(withdrawMode.fastModeSupportedTokens)}.\n                        </Typography>\n                      }\n                    >\n                      <Typography display={'flex'} alignItems={'center'}>\n                        Trust Mode <Info2Icon sx={{ ml: 0.5, color: 'var(--color-text-third)' }} />\n                      </Typography>\n                    </Tooltip>\n                    <Typography variant='body2'>{withdrawMode.fastMode?.fee ?? '--'}</Typography>\n                    {withdrawMode.fastMaxAlert.show && (\n                      <Typography color={'var(--color-error)'} variant='body2'>\n                        {withdrawMode.fastMaxAlert.message}\n                      </Typography>\n                    )}\n                  </Box>\n                </Box>\n              }\n              alignItems={'center'}\n              rightNode={\n                <Typography variant='body2'>{withdrawMode.fastMode?.time ?? '--'}</Typography>\n              }\n              border={'1px solid var(--color-border)'}\n              borderBottom={'none'}\n            />\n          )}\n          <SpaceBetweenBox\n            borderRadius={withdrawMode?.showFastMode ? '0 0 4px 4px' : '4px'}\n            px={2}\n            py={0.5}\n            leftNode={\n              <Box display={'flex'} alignItems={'center'}>\n                <Box mr={1.5}>\n                  <CustomCheckBox\n                    checked={withdrawMode?.mode === 'normal'}\n                    onCheck={() => {\n                      withdrawMode?.onChange('normal')\n                    }}\n                  />\n                </Box>\n\n                <Box>\n                  <Tooltip\n                    title={\n                      'Assets are transferred between Loopring and Ethereum using Loopring’s official bridge contract.'\n                    }\n                  >\n                    <Typography>\n                      {withdrawMode?.showTrustUI ? 'Trustless Mode' : 'Normal Mode'}\n                    </Typography>\n                  </Tooltip>\n                  <Typography variant='body2'>{withdrawMode?.normalMode?.fee ?? '--'}</Typography>\n                </Box>\n              </Box>\n            }\n            alignItems={'center'}\n            rightNode={\n              <Typography variant='body2'>{withdrawMode?.normalMode?.time ?? '--'}</Typography>\n            }\n            border={'1px solid var(--color-border)'}\n          />\n        </Box>\n      )}\n\n      <Grid\n        item\n        alignSelf={'stretch'}\n        position={'relative'}\n        className={'fee-wrap'}\n        mt={withdrawMode?.showTrustUI ? 0 : 1}\n      >\n        {!chargeFeeTokenList?.length ? (\n          <Typography>{t('labelFeeCalculating')}</Typography>\n        ) : (\n          <>\n            <FeeSelect\n              chargeFeeTokenList={chargeFeeTokenList}\n              handleToggleChange={(feeInfo) => {\n                handleToggleChange(feeInfo as C)\n                setDropdownStatus('down')\n              }}\n              feeInfo={feeInfo}\n              open={dropdownStatus === 'up'}\n              onClose={() => {\n                setDropdownStatus('down')\n              }}\n              onClickFee={() => setDropdownStatus((prev) => (prev === 'up' ? 'down' : 'up'))}\n              feeLoading={isFeeNotEnough.isOnLoading}\n              isFeeNotEnough={isFeeNotEnough.isFeeNotEnough}\n              isFastWithdrawAmountLimit={isFastWithdrawAmountLimit}\n              networkFeeElement={\n                withdrawMode?.showTrustUI ? (\n                  <Tooltip\n                    title={\n                      'The total cost of completing the transaction, including network fees, service fees, and other associated charges.'\n                    }\n                  >\n                    <Typography\n                      display={'flex'}\n                      alignItems={'center'}\n                      marginRight={0}\n                      component={'span'}\n                      color={'inherit'}\n                      minWidth={28}\n                    >\n                      Transaction Fee{' '}\n                      <Info2Icon sx={{ ml: 0.5, color: 'var(--color-text-third)' }} />\n                    </Typography>\n                  </Tooltip>\n                ) : (\n                  <Typography\n                    display={'flex'}\n                    alignItems={'center'}\n                    marginRight={0}\n                    component={'span'}\n                    color={'inherit'}\n                    minWidth={28}\n                  >\n                    Network Fee\n                  </Typography>\n                )\n              }\n            />\n          </>\n        )}\n      </Grid>\n\n      <Grid item alignSelf={'stretch'} paddingBottom={0} mt={withdrawMode?.showTrustUI ? 5 : 10}>\n        {lastFailed && (\n          <Typography paddingBottom={1} textAlign={'center'} color={'var(--color-warning)'}>\n            {t('labelConfirmAgainByFailedWithBalance', {\n              symbol: type === 'NFT' ? 'NFT' : ` ${tradeData?.belong}` ?? EmptyValueTag,\n              count: tradeData?.balance,\n            })}\n          </Typography>\n        )}\n        <Button\n          fullWidth\n          variant={'contained'}\n          size={'medium'}\n          color={'primary'}\n          onClick={() => {\n            handleConfirm(0)\n            // onWithdrawClick(tradeData);\n          }}\n          loading={withdrawBtnStatus === TradeBtnStatus.LOADING && !getDisabled ? 'true' : 'false'}\n          disabled={getDisabled || withdrawBtnStatus === TradeBtnStatus.LOADING}\n        >\n          {label}\n        </Button>\n      </Grid>\n      <Toast\n        alertText={t('labelCopyAddClip')}\n        open={copyToastOpen}\n        autoHideDuration={TOAST_TIME}\n        onClose={() => {\n          setCopyToastOpen(false)\n        }}\n        severity={ToastType.success}\n      />\n    </GridWrapStyle>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/hook/BasicACoinPanelHook.tsx",
    "content": "import { IBData, MintTradeNFT, TRADE_TYPE } from '@loopring-web/common-resources'\nimport { BasicACoinTradeHookProps } from '../Interface'\nimport React from 'react'\nimport { SwitchData } from '../../Interface'\nimport { ToolBarItemBack } from '../tool'\nimport { debounceTime, Subject } from 'rxjs'\n\nexport const useBasicTrade = <\n  T extends Partial<IBData<I> & MintTradeNFT<I> & { [key: string]: any }>,\n  I,\n>({\n  tradeData,\n  handlePanelEvent,\n  walletMap = {},\n  coinMap,\n  type = TRADE_TYPE.TOKEN,\n  ...rest\n}: BasicACoinTradeHookProps<T, I>) => {\n  tradeData = tradeData ? tradeData : ({} as T)\n  // data used on trade input btn click to menu list and back to the input data transfer\n  const [switchData, setSwitchData] = React.useState<SwitchData<T>>({\n    to: 'button',\n    tradeData,\n  } as SwitchData<T>)\n  // index is switch panel index number 1 is btn view\n  const [index, setIndex] = React.useState(0)\n  React.useEffect(() => {\n    if (tradeData !== switchData.tradeData) {\n      setSwitchData({ ...switchData, tradeData: tradeData })\n    }\n  }, [tradeData?.tradeValue, tradeData?.belong, tradeData?.balance])\n\n  const panelEventSubject = new Subject<{ _index: 0 | 1; switchData: SwitchData<T> } | undefined>()\n\n  const onChangeEvent = (_index: 0 | 1, { to, tradeData }: SwitchData<T>) => {\n    panelEventSubject.next({ _index: _index, switchData: { to, tradeData } })\n  }\n  const panelEventNext = React.useCallback(\n    async ({\n      _index,\n      switchData: { to, tradeData: newTradeData },\n    }: {\n      _index: 0 | 1\n      switchData: SwitchData<T>\n    }) => {\n      if (handlePanelEvent) {\n        await handlePanelEvent({ to, tradeData: newTradeData }, `To${to}` as any)\n      }\n      if (typeof rest?.onChangeEvent == 'function') {\n        setSwitchData(rest.onChangeEvent(_index, { to, tradeData: newTradeData }))\n      } else {\n        const _newTradeData = {\n          ...tradeData,\n          ...newTradeData,\n        }\n        if (to === 'menu') {\n          setSwitchData({ tradeData: _newTradeData, to })\n        } else if (to === 'button' && type === 'TOKEN') {\n          const balance = _newTradeData.belong ? walletMap[_newTradeData.belong]?.count : 0\n          const tradeValue = _newTradeData.tradeValue ? _newTradeData.tradeValue : undefined\n          setSwitchData({\n            tradeData: {\n              ..._newTradeData,\n              tradeValue,\n              balance: balance,\n            },\n            to,\n          })\n        } else if (to === 'button' && type === 'NFT') {\n          const count = _newTradeData.balance\n          const tradeValue = _newTradeData.tradeValue ? _newTradeData.tradeValue : undefined\n          setSwitchData({\n            tradeData: {\n              ..._newTradeData,\n              tradeValue,\n              balance: count,\n            },\n            to,\n          })\n        }\n      }\n      if (_index !== index) {\n        setIndex(_index)\n      }\n    },\n    [handlePanelEvent, rest, index, tradeData, type, walletMap],\n  )\n\n  React.useEffect(() => {\n    panelEventSubject.pipe(debounceTime(200)).subscribe((result) => {\n      if (result) {\n        panelEventNext(result)\n      }\n    })\n    return () => {\n      panelEventSubject.unsubscribe()\n    }\n  }, [panelEventSubject])\n\n  const toolBarItemBack = React.useMemo(\n    () => <ToolBarItemBack onChangeEvent={onChangeEvent} tradeData={tradeData} />,\n    [tradeData, onChangeEvent],\n  )\n  return {\n    //toolbar UI\n    toolBarItemBack,\n    //Data, panel and function\n    onChangeEvent,\n    index,\n    switchData: {\n      ...switchData,\n    },\n  }\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/hook/useAddressType.ts",
    "content": "import {\n  AddressItemType,\n  EXCHANGE_TYPE,\n  L1L2_NAME_DEFINED,\n  MapChainId,\n  WALLET_TYPE,\n} from '@loopring-web/common-resources'\nimport { useTranslation } from 'react-i18next'\nimport { useSettings } from '../../../../stores'\n\nexport const useAddressTypeLists = <T extends WALLET_TYPE | EXCHANGE_TYPE>() => {\n  const { t } = useTranslation('common')\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const walletList: AddressItemType<T>[] = [\n    {\n      label: t('labelWalletTypeOptions', {\n        l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n        loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n        l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n        l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n        ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n        type: t(`labelWalletType${WALLET_TYPE.EOA}`, {\n          l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n          loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n          l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n          l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n          ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n        }),\n      }),\n      value: WALLET_TYPE.EOA as T,\n      description: t(`label${WALLET_TYPE.EOA}Des`, {\n        l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n        loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n        l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n        l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n        ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n      }),\n    },\n    {\n      label: t('labelWalletTypeOptions', {\n        l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n        loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n        l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n        l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n        ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n        type: t(`labelWalletType${WALLET_TYPE.Loopring}`, {\n          l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n          loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n          l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n          l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n          ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n        }),\n      }),\n      value: WALLET_TYPE.Loopring as T,\n      description: t(`label${WALLET_TYPE.Loopring}Des`, {\n        l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n        loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n        l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n        l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n        ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n      }),\n    },\n    {\n      label: t('labelWalletTypeOptions', {\n        l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n        loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n        l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n        l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n        ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n        type: t(`labelWalletType${WALLET_TYPE.OtherSmart}`, {\n          l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n          loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n          l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n          l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n          ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n        }),\n      }),\n      disabled: true,\n      value: WALLET_TYPE.OtherSmart as T,\n      description: t(`label${WALLET_TYPE.OtherSmart}Des`, {\n        l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n        loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n        l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n        l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n        ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n      }),\n    },\n    {\n      label: t(WALLET_TYPE.Exchange),\n      value: WALLET_TYPE.Exchange as T,\n      disabled: true,\n      description: t(`label${WALLET_TYPE.Exchange}Des`, {\n        l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n        loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n        l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n        l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n        ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n      }),\n    },\n  ]\n  const walletListFn: (type: WALLET_TYPE) => AddressItemType<T>[] = (type: WALLET_TYPE) => {\n    if (type === WALLET_TYPE.Exchange) throw 'wrong type'\n    return [\n      {\n        label: t('labelWalletTypeOptions', {\n          l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n          loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n          l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n          l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n          ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n          loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n          type: t(`labelWalletType${WALLET_TYPE.EOA}`, {\n            l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n            loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n            l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n            l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n            ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n            loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n          }),\n        }),\n        disabled: type === WALLET_TYPE.EOA ? false : true,\n        value: WALLET_TYPE.EOA as T,\n        description: t(`label${WALLET_TYPE.EOA}Des`, {\n          l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n          loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n          l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n          l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n          ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n          loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n        }),\n      },\n      {\n        label: t('labelWalletTypeOptions', {\n          l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n          loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n          l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n          l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n          ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n          type: t(`labelWalletType${WALLET_TYPE.Loopring}`, {\n            l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n            loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n            l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n            l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n            ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n            loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n          }),\n        }),\n        disabled: type === WALLET_TYPE.Loopring ? false : true,\n        value: WALLET_TYPE.Loopring as T,\n        description: t(`label${WALLET_TYPE.Loopring}Des`, {\n          l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n          loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n          l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n          l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n          ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n          loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n        }),\n      },\n      {\n        label: t('labelWalletTypeOptions', {\n          l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n          loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n          l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n          l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n          ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n          loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n          type: t(`labelWalletType${WALLET_TYPE.OtherSmart}`, {\n            l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n            loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n            l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n            l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n            ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n            loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n          }),\n        }),\n        disabled: type === WALLET_TYPE.OtherSmart ? false : true,\n        value: WALLET_TYPE.OtherSmart as T,\n        description: t(`label${WALLET_TYPE.OtherSmart}Des`, {\n          l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n          loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n          l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n          l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n          ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n          loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n        }),\n      },\n      {\n        label: t(`labelExchange${EXCHANGE_TYPE.Binance}`, {\n          l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n          loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n          l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n          l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n          ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n          loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n        }),\n        disabled: type === WALLET_TYPE.EOA ? false : true,\n        value: EXCHANGE_TYPE.Binance as T,\n        description: t('labelContactsBinanceNotSupportted', {\n          l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n          loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n          l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n          l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n          ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n          loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n        }),\n      },\n      {\n        label: t(`labelExchange${EXCHANGE_TYPE.Huobi}`, {\n          l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n          loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n          l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n          l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n          ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n          loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n        }),\n        disabled: type === WALLET_TYPE.EOA ? false : true,\n        value: EXCHANGE_TYPE.Huobi as T,\n        description: t('labelContactsHuobiNotSupportted', {\n          l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n          loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n          l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n          l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n          ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n          loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n        }),\n      },\n      {\n        label: t(`labelExchange${EXCHANGE_TYPE.Others}`, {\n          l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n          loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n          l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n          l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n          ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n          loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n        }),\n        disabled: type === WALLET_TYPE.EOA ? false : true,\n        value: EXCHANGE_TYPE.Others as T,\n        description: t('labelContactsOtherExchangesNotSupportted', {\n          l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n          loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n          l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n          l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n          ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n          loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n        }),\n      },\n    ]\n  }\n  const nonExchangeList: AddressItemType<T>[] = [\n    {\n      label: t(`labelNonExchangeType`, {\n        l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n        loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n        l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n        l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n        ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n        loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n      }),\n      value: EXCHANGE_TYPE.NonExchange as T,\n      disabled: false,\n      description: t(`labelNonExchangeTypeDes`, {\n        l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n        loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n        l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n        l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n        ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n        loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n      }),\n    },\n  ]\n  const exchangeList: AddressItemType<T>[] = [\n    {\n      label: t(`labelExchange${EXCHANGE_TYPE.Binance}`, {\n        l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n        loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n        l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n        l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n        ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n        loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n      }),\n      value: EXCHANGE_TYPE.Binance as T,\n      disabled: false,\n      description: t(`labelExchange${EXCHANGE_TYPE.Binance}Des`, {\n        l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n        loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n        l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n        l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n        ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n        loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n      }),\n      maxWidth: 'initial',\n    },\n    {\n      label: t(`labelExchange${EXCHANGE_TYPE.Huobi}`, {\n        l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n        loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n        l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n        l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n        ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n        loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n      }),\n      value: EXCHANGE_TYPE.Huobi as T,\n      disabled: false,\n      description: t(`labelExchange${EXCHANGE_TYPE.Huobi}Des`, {\n        l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n        loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n        l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n        l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n        ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n        loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n      }),\n      maxWidth: 'initial',\n    },\n    {\n      label: t(`labelExchange${EXCHANGE_TYPE.Others}`, {\n        l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n        loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n        l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n        l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n        ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n        loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n      }),\n      value: EXCHANGE_TYPE.Others as T,\n      disabled: false,\n      description: t(`labelExchange${EXCHANGE_TYPE.Others}Des`, {\n        l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n        loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n        l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n        l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n        ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n        loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n      }),\n      maxWidth: 'initial',\n    },\n  ]\n  return {\n    walletList,\n    walletListFn,\n    nonExchangeList,\n    exchangeList,\n  }\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/index.ts",
    "content": "// this is a private component, only used in panel component\n\n// please do not export this index to global\nexport * from './DepositWrap'\nexport * from './ResetWrap'\nexport * from './WithdrawWrap'\nexport * from './TransferWrap'\nexport * from './TransferNFTBurn'\nexport * from './SwapWrap'\nexport * from './AmmWrap'\nexport * from './VaultWrap'\nexport * from './hook/BasicACoinPanelHook'\nexport * from './tool'\nexport * from './ExportAccountWrap'\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/tool/Dialogs.tsx",
    "content": "import {\n  Box,\n  Checkbox,\n  Dialog,\n  DialogActions,\n  DialogContent,\n  DialogContentText,\n  DialogTitle,\n  FormControlLabel as MuiFormControlLabel,\n  IconButton,\n  Link,\n  List,\n  ListItem,\n  Tooltip,\n  Typography,\n} from '@mui/material'\n\nimport { Trans, useTranslation, WithTranslation, withTranslation } from 'react-i18next'\nimport { Button, CoinIcon, TextField } from '../../../basic-lib'\nimport React from 'react'\nimport { ConnectProviders } from '@loopring-web/web3-provider'\nimport styled from '@emotion/styled'\nimport { useOpenModals, useSettings } from '../../../../stores'\nimport { useTheme } from '@emotion/react'\n\nimport {\n  Account,\n  Bridge,\n  CheckBoxIcon,\n  CheckedIcon,\n  CloseIcon,\n  copyToClipBoard,\n  DAY_MINUTE_FORMAT,\n  DualInvestConfirmType,\n  getValuePrecisionThousand,\n  Info2Icon,\n  L1L2_NAME_DEFINED,\n  MapChainId,\n  RiskAlertIcon,\n  RiskIcon,\n  SoursURL,\n  TradeDefi,\n  TradeProType,\n} from '@loopring-web/common-resources'\nimport { useHistory, useLocation } from 'react-router-dom'\nimport BigNumber from 'bignumber.js'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport moment from 'moment/moment'\n\n// const ModelStyle = styled(Box)`\n//   ${({ theme }) => modalContentBaseStyle({ theme: theme })};\n//   background: ${({ theme }) => theme.colorBase.box};\n// ` as typeof Box\nconst RiskStyle = styled(Dialog)`\n  .MuiPaper-root {\n    width: var(--modal-width);\n    background: var(--color-box);\n  }\n\n  .MuiDialogTitle-root {\n    margin: ${({ theme }) => 5 * theme.unit}px 0 ${({ theme }) => 1 * theme.unit}px;\n    display: flex;\n    flex-direction: column;\n    align-content: center;\n    align-items: center;\n  }\n\n  .infomation {\n    ul {\n      background: var(--color-box-enhance);\n      display: flex;\n      flex-direction: column;\n      justify-content: stretch;\n      padding: 0 ${({ theme }) => 2 * theme.unit}px;\n      ${({ theme }) => theme.border.defaultFrame({ c_key: 'rgba(0,0,0,0)', d_R: 0.5 })};\n\n      li {\n        height: var(--row-height);\n        display: flex;\n        flex-direction: row;\n        align-items: center;\n        justify-content: space-between;\n      }\n    }\n  }\n\n  .MuiDialogActions-root {\n    > :not(:first-of-type) {\n      margin-left: 0px !important;\n    }\n  }\n\n  .titleContent {\n    margin: ${({ theme }) => 2 * theme.unit}px 0 0 0;\n  }\n\n  .detail {\n    margin: 0 0 ${({ theme }) => 2 * theme.unit}px 0;\n\n    .des {\n      font-size: ${({ theme }) => theme.fontDefault.body1};\n      color: var(--color-text-secondary);\n    }\n  }\n`\nexport type RiskInformation = {\n  label: string | JSX.Element\n  value: string | JSX.Element\n  color: string\n}\nexport const RiskComponent = ({\n  open,\n  handleClose,\n  handleConfirm,\n  infos,\n  description,\n  checkElement,\n  hasNoIcon = false,\n  isAgree = true,\n  confirmLabel = 'labelRiskAgree',\n  cancelLabel = 'labelRiskCancel',\n  strongBtn = 'cancel',\n  title,\n}: {\n  open: boolean\n  handleClose: () => void\n  handleConfirm: () => void\n  hasNoIcon?: boolean\n  infos?: RiskInformation[]\n  description?: JSX.Element[]\n  checkElement?: JSX.Element\n  strongBtn?: string\n  isAgree?: boolean // if mutiple when all aggree set true\n  confirmLabel?: string\n  cancelLabel?: string\n  title: string | JSX.Element | (() => JSX.Element)\n}) => {\n  const { t } = useTranslation('common')\n  const size = 60\n  // myLog('title', title)\n  return (\n    <RiskStyle open={open} onClose={(_) => handleClose()} >\n      <DialogTitle>\n        <>\n          {!hasNoIcon && (\n            <RiskAlertIcon\n              sx={{ width: size, height: size }}\n              fontSize={'inherit'}\n              className={'main-icon'}\n            />\n          )}\n          {typeof title === 'string' ? (\n            <Typography variant={'h4'} component={'span'} className={'titleContent'}>\n              {title}\n            </Typography>\n          ) : (\n            <> {title}</>\n          )}\n        </>\n      </DialogTitle>\n      {infos && (\n        <DialogContent className={'infomation'}>\n          <Box component={'ul'}>\n            {infos.map(({ label, value, color }, index) => {\n              return (\n                <Box component='li' key={index}>\n                  {typeof label === 'string' ? (\n                    <Typography component={'span'} color={'var(--color-text-secondary)'}>\n                      {label}\n                    </Typography>\n                  ) : (\n                    <React.Fragment> {label}</React.Fragment>\n                  )}\n                  <Typography color={color} component={'span'} textAlign={'right'}>\n                    {value}\n                  </Typography>\n                </Box>\n              )\n            })}\n          </Box>\n        </DialogContent>\n      )}\n\n      <DialogContent className={'detail'}>\n        {description &&\n          description.map((item, index) => {\n            return (\n              <Typography\n                color={'inherit'}\n                component={'div'}\n                className={'des'}\n                marginTop={1}\n                key={index}\n              >\n                {item}\n              </Typography>\n            )\n          })}\n      </DialogContent>\n      <DialogActions\n        sx={{\n          display: 'flex',\n          justifyContent: 'stretch',\n          flexDirection: 'column',\n          alignItems: 'stretch',\n        }}\n      >\n        {checkElement && (\n          <Box marginBottom={2} display={'flex'}>\n            {checkElement}\n          </Box>\n        )}\n        <Box\n          display={'flex'}\n          justifyContent={'space-between'}\n          width={'100%'}\n          className={'action-btn'}\n          flexDirection={'row'}\n          alignItems={'center'}\n        >\n          <Box width={'48%'}>\n            <Button\n              sx={{ height: '4rem' }}\n              variant={strongBtn === 'cancel' ? 'contained' : 'outlined'}\n              size={'medium'}\n              onClick={(_) => handleClose()}\n              color={'primary'}\n              fullWidth\n            >\n              {t(cancelLabel)}\n            </Button>\n          </Box>\n          <Box width={'48%'}>\n            <Button\n              sx={{ height: '4rem' }}\n              variant={strongBtn == 'cancel' ? 'outlined' : 'contained'}\n              size={'medium'}\n              disabled={!isAgree}\n              fullWidth\n              onClick={(_) => handleConfirm()}\n            >\n              {t(confirmLabel)}\n            </Button>\n          </Box>\n        </Box>\n      </DialogActions>\n    </RiskStyle>\n  )\n}\nconst DialogStyle = styled(Dialog)`\n  &.MuiDialog-root {\n    z-index: 2002;\n  }\n  .MuiList-root {\n    list-style: inside;\n    .MuiListItem-root {\n      display: list-item;\n      margin-bottom: ${({ theme }) => theme.unit}px;\n      height: auto;\n      padding: ${({ theme }) => theme.unit}px 0;\n      font-size: ${({ theme }) => theme.fontDefault.body1};\n      line-height: 1.5em;\n    }\n  }\n\n  .MuiDialogContentText-root {\n    white-space: pre-line;\n  }\n`\n\nexport const CancelAllOrdersAlert = withTranslation('common', {\n  withRef: true,\n})(\n  ({\n    t,\n    open,\n    handleCancelAll,\n    handleClose,\n  }: WithTranslation & {\n    open: boolean\n    handleCancelAll: () => void\n    handleClose: (event: MouseEvent, isAgree?: boolean) => void\n  }) => {\n    return (\n      <Dialog\n        open={open}\n        keepMounted\n        onClose={(e: MouseEvent) => handleClose(e)}\n        aria-describedby='alert-dialog-cancel-all-orders-description'\n      >\n        <DialogTitle style={{ padding: '2.4rem', paddingBottom: '1.6rem' }}>\n          {t('labelCancelAllOrders')}\n        </DialogTitle>\n        <DialogActions style={{ padding: '2.4rem', paddingTop: 0 }}>\n          <Button variant={'outlined'} size={'medium'} onClick={(e) => handleClose(e as any)}>\n            {t('labelCancel')}\n          </Button>\n          <Button\n            variant={'contained'}\n            size={'small'}\n            onClick={(e) => {\n              handleCancelAll()\n              handleClose(e as any, true)\n            }}\n            color={'primary'}\n          >\n            {t('labelConfirm')}\n          </Button>\n        </DialogActions>\n      </Dialog>\n    )\n  },\n)\nexport const CancelDualAlert = withTranslation('common', {\n  withRef: true,\n})(\n  ({\n    t,\n    open,\n    handleCancelOne,\n    handleClose,\n    row,\n  }: WithTranslation & {\n    open: boolean\n    row: any\n    handleCancelOne: () => Promise<void>\n    handleClose: (event: MouseEvent, isAgree?: boolean) => void\n  }) => {\n    return (\n      <Dialog\n        open={open}\n        keepMounted\n        onClose={(e: MouseEvent) => handleClose(e)}\n        aria-describedby='alert-dialog-cancel-all-orders-description'\n      >\n        <DialogTitle style={{ padding: '2.4rem', paddingBottom: '1.6rem' }}>\n          {t('labelDualAutoCancelConfirm')}\n        </DialogTitle>\n        <DialogContent>\n          <DialogContentText>\n            <Typography component={'span'} variant={'body1'} color={'inherit'}>\n              {t('labelDualAutoCancelConfirmDes')}\n            </Typography>\n          </DialogContentText>\n        </DialogContent>\n        <DialogContent className={'infomation'}>\n          <DialogContentText>\n            <Box component={'ul'}>\n              <Box component='li'>\n                <Typography component={'span'} variant={'body1'} color={'inherit'}>\n                  {t('labelDualModifySettlementDateDialog')}\n                </Typography>\n\n                <Typography\n                  color={'textPrimary'}\n                  component={'span'}\n                  textAlign={'right'}\n                  paddingLeft={1}\n                >\n                  {moment(new Date(row?.expireTime)).format(DAY_MINUTE_FORMAT)}\n                </Typography>\n              </Box>\n            </Box>\n          </DialogContentText>\n        </DialogContent>\n\n        <DialogActions style={{ padding: '2.4rem', paddingTop: 0 }}>\n          <Button variant={'outlined'} size={'medium'} onClick={(e) => handleClose(e as any)}>\n            {t('labelDualAutoCancelOrder')}\n          </Button>\n          <Button\n            variant={'contained'}\n            size={'small'}\n            onClick={async (e) => {\n              await handleCancelOne()\n              handleClose(e as any, true)\n            }}\n            color={'primary'}\n          >\n            {t('labelConfirm')}\n          </Button>\n        </DialogActions>\n      </Dialog>\n    )\n  },\n)\n\nexport const CancelOneOrdersAlert = withTranslation('common', {\n  withRef: true,\n})(\n  ({\n    t,\n    open,\n    handleCancelOne,\n    handleClose,\n  }: WithTranslation & {\n    open: boolean\n    handleCancelOne: () => Promise<void>\n    handleClose: (event: MouseEvent, isAgree?: boolean) => void\n  }) => {\n    return (\n      <Dialog\n        open={open}\n        keepMounted\n        onClose={(e: MouseEvent) => handleClose(e)}\n        aria-describedby='alert-dialog-cancel-all-orders-description'\n      >\n        <DialogTitle style={{ padding: '2.4rem', paddingBottom: '1.6rem' }}>\n          {t('labelOrderCancelConfirm')}\n        </DialogTitle>\n        <DialogActions style={{ padding: '2.4rem', paddingTop: 0 }}>\n          <Button variant={'outlined'} size={'medium'} onClick={(e) => handleClose(e as any)}>\n            {t('labelOrderCancelOrder')}\n          </Button>\n          <Button\n            variant={'contained'}\n            size={'small'}\n            onClick={async (e) => {\n              await handleCancelOne()\n              handleClose(e as any, true)\n            }}\n            color={'primary'}\n          >\n            {t('labelConfirm')}\n          </Button>\n        </DialogActions>\n      </Dialog>\n    )\n  },\n)\nexport const AlertNotSupport = withTranslation('common')(\n  ({\n    t,\n    open,\n    handleClose,\n  }: WithTranslation & {\n    open: boolean\n    handleClose: (event: MouseEvent) => void\n  }) => {\n    return (\n      <Dialog\n        open={open}\n        keepMounted\n        onClose={(e: MouseEvent) => handleClose(e)}\n        aria-describedby='alert-dialog-slide-description'\n      >\n        <DialogTitle> {t('labelNotSupportTitle')}</DialogTitle>\n        <DialogContent>\n          <DialogContentText id='alert-dialog-slide-description'>\n            <Trans i18nKey={'labelNotAllowTrade'} />\n          </DialogContentText>\n        </DialogContent>\n        <DialogActions>\n          <Button variant={'outlined'} size={'medium'} onClick={(e) => handleClose(e as any)}>\n            {t('labelConfirm')}\n          </Button>\n        </DialogActions>\n      </Dialog>\n    )\n  },\n)\n\nexport const AlertImpact = ({\n  open,\n  handleClose,\n  handleConfirm,\n  variance,\n  marketPrice,\n  settlementPrice,\n  symbol,\n}: {\n  open: boolean\n  handleClose: () => void\n  handleConfirm: () => void\n  variance: string\n  marketPrice: string\n  settlementPrice: string\n  symbol: string\n}) => {\n  const { t } = useTranslation('common')\n  const label: RiskInformation[] = [\n    {\n      label: t('labelExpectedSettlementPrice'),\n      value: `${settlementPrice} ${symbol}`,\n      color: 'var(--color-text-primary)',\n    },\n    {\n      label: t('labelCurrentMarketPrice'),\n      value: `${marketPrice} ${symbol}`,\n      color: 'var(--color-text-primary)',\n    },\n    {\n      label: t('labelPriceVariance'),\n      value: `${variance}%`,\n      color: 'var(--color-error)',\n    },\n  ]\n\n  return (\n    <RiskComponent\n      title={t('labelLargePriceVariance')}\n      open={open}\n      infos={label}\n      description={[\n        <Trans i18nKey={'labelImpactExtraNewGreat'} tOptions={{ value: variance }}>\n          This trade will result in a loss of {variance}% of the position’s market value. To\n          proceed, tap Continue to confirm you understand and acknowledge the risk.\n        </Trans>,\n      ]}\n      handleClose={handleClose}\n      handleConfirm={handleConfirm}\n    />\n  )\n}\n\nexport const ConfirmImpact = ({\n  open,\n  handleClose,\n  handleConfirm,\n  priceImpact,\n  color,\n  shouldInputAgree,\n}: {\n  open: boolean\n  handleClose: () => void\n  handleConfirm: () => void\n  priceImpact: string\n  color: string\n  shouldInputAgree: boolean\n}) => {\n  const { t } = useTranslation('common')\n  const [agree, setAgree] = React.useState('')\n\n  React.useEffect(() => {\n    if (open) {\n      setAgree(shouldInputAgree ? '' : 'AGREE')\n    }\n  }, [open, shouldInputAgree])\n\n  const label: RiskInformation[] = [\n    {\n      label: t('labelPriceImpact'),\n      value: `${priceImpact}%`,\n      color: color,\n    },\n  ]\n\n  return (\n    <RiskComponent\n      title={t('labelHighPriceImpacTitle')}\n      open={open}\n      infos={label}\n      description={[\n        <Trans\n          i18nKey={shouldInputAgree ? 'labelPriceImpactDes1' : 'labelPriceImpactDes2'}\n          tOptions={{ value: priceImpact }}\n          components={{\n            t: <Typography component={'span'} color={'textPrimary'} />,\n          }}\n        >\n          This trade will affect the pool price by more than {priceImpact}%，which is too high. It\n          may result in significant slippage and potential losses. If you acknowledge the risk and\n          wish to proceed, type the ‘AGREE’ and tap ‘Proceed Anyway’ to confirm again.\n        </Trans>,\n      ]}\n      isAgree={agree === 'AGREE'}\n      handleClose={handleClose}\n      handleConfirm={handleConfirm}\n      checkElement={\n        shouldInputAgree ? (\n          <TextField\n            autoFocus\n            value={agree}\n            onChange={(event) => {\n              setAgree(event.target.value)\n            }}\n            margin='dense'\n            id='agree'\n            type='text'\n            fullWidth\n          />\n        ) : undefined\n      }\n    />\n  )\n}\n\nexport const SmallOrderAlert = ({\n  open,\n  handleClose,\n  handleConfirm,\n  estimatedFee,\n  feePercentage,\n  minimumReceived,\n}: // symbol,\n{\n  open: boolean\n  handleClose: () => void\n  handleConfirm: () => void\n  estimatedFee: string\n  feePercentage: string\n  minimumReceived: string\n}) => {\n  const { t } = useTranslation('common')\n  const label: RiskInformation[] = [\n    {\n      label: t('labelSmallOrderAlertLine3'),\n      value: `${estimatedFee}`,\n      color: 'var(--color-text-primary)',\n    },\n    {\n      label: t('labelSmallOrderAlertLine5'),\n      value: `${minimumReceived}`,\n      color: 'var(--color-text-primary)',\n    },\n    {\n      label: t('labelSmallOrderAlertLine4'),\n      value: `${feePercentage}%`,\n      color: 'var(--color-error)',\n    },\n  ]\n\n  return (\n    <RiskComponent\n      title={t('labelSmallOrderAlertLine')}\n      open={open}\n      infos={label}\n      handleClose={handleClose}\n      handleConfirm={handleConfirm}\n    />\n  )\n}\n\nexport const AlertLimitPriceRisk = withTranslation('common')(\n  ({\n    t,\n    value,\n    open,\n    handleClose,\n    handleConfirm,\n    price,\n    priceSymbol,\n    fromAmount,\n    fromSymbol,\n    toSymbol,\n    toAmount,\n  }: WithTranslation & {\n    open: boolean\n    value: string\n    handleClose: () => void\n    handleConfirm: () => void\n    fromSymbol: string\n    fromAmount: string | number\n    toSymbol: string\n    toAmount: string | number\n    price: string | number\n    priceSymbol: string\n    // handleClose: (event: MouseEvent, isAgree?: boolean) => void\n    // handleConfirm: () => void\n  }) => {\n    const label: RiskInformation[] = [\n      {\n        label: t('labelExpectedSettlementPrice'),\n        value: `${price} ${priceSymbol}`,\n        color: 'var(--color-text-primary)',\n      },\n      {\n        label: t('labelSell'),\n        value: `${fromAmount} ${fromSymbol}`,\n        color: 'var(--color-text-primary)',\n      },\n      {\n        label: t('labelBuy'),\n        value: `${toAmount} ${toSymbol}`,\n        color: 'var(--color-error)',\n      },\n    ]\n\n    return (\n      <RiskComponent\n        hasNoIcon={true}\n        title={t('labelLimitImpactTitle')}\n        open={open}\n        infos={label}\n        description={[\n          <Trans\n            i18nKey={'labelPriceExtraGreat'}\n            tOptions={{ compare: value ? t(value) : '> | <' }}\n          >\n            The price you set is greater or less than 20% the market price. Are you sure you want to\n            make this order?\n          </Trans>,\n        ]}\n        handleClose={handleClose}\n        handleConfirm={handleConfirm}\n      />\n    )\n  },\n)\n\nexport const SwapSecondConfirmation = withTranslation('common')(\n  ({\n    t,\n    open,\n    handleClose,\n    handleConfirm,\n    fromSymbol,\n    fromAmount,\n    toSymbol,\n    toAmount,\n    userTakerRate,\n    tradeCostMin,\n    estimateFee,\n    priceImpactColor,\n    priceImpact,\n    minimumReceived,\n    slippage,\n  }: WithTranslation & {\n    open: boolean\n    handleClose: () => void\n    handleConfirm: () => void\n    fromSymbol: string\n    fromAmount: string\n    toSymbol: string\n    toAmount: string\n    userTakerRate: string\n    tradeCostMin: string\n    estimateFee: string\n    priceImpactColor: string\n    priceImpact: string\n    minimumReceived: string\n    slippage: string\n  }) => {\n    // const { isMobile } = useSettings()\n    // const network = MapChainId[defaultNetwork] ?? MapChainId[1];\n    const infos = [\n      {\n        label: (\n          <Tooltip\n            title={t('labelSwapFeeTooltips', {\n              rate: userTakerRate,\n              value: tradeCostMin,\n            }).toString()}\n            placement={'top'}\n          >\n            <Typography\n              component={'span'}\n              variant='body2'\n              color={'textSecondary'}\n              display={'inline-flex'}\n              alignItems={'center'}\n            >\n              <Info2Icon fontSize={'small'} color={'inherit'} sx={{ marginX: 1 / 2 }} />\n              {t('swapFee')}\n            </Typography>\n          </Tooltip>\n        ),\n        value: estimateFee,\n        color: 'var(--color-text-primary)',\n      },\n      {\n        label: (\n          <Tooltip title={t('labelSwapPriceImpactTooltips').toString()} placement={'top'}>\n            <Typography\n              component={'span'}\n              variant='body2'\n              color={'textSecondary'}\n              display={'inline-flex'}\n              alignItems={'center'}\n            >\n              <Info2Icon fontSize={'small'} color={'inherit'} sx={{ marginX: 1 / 2 }} />\n              {' ' + t('swapPriceImpact')}\n            </Typography>\n          </Tooltip>\n        ),\n        value: priceImpact,\n        color: priceImpactColor,\n      },\n      {\n        label: (\n          <Tooltip title={t('labelSwapMinReceiveTooltips').toString()} placement={'top'}>\n            <Typography\n              component={'span'}\n              variant='body2'\n              color={'textSecondary'}\n              display={'inline-flex'}\n              alignItems={'center'}\n            >\n              <Info2Icon fontSize={'small'} color={'inherit'} sx={{ marginX: 1 / 2 }} />\n              {' ' + t('swapMinReceive')}\n            </Typography>\n          </Tooltip>\n        ),\n        value: minimumReceived,\n        color: 'var(--color-text-primary)',\n      },\n      {\n        label: (\n          <Tooltip title={t('labelSwapToleranceTooltips').toString()} placement={'top'}>\n            <Typography\n              component={'span'}\n              variant='body2'\n              color={'textSecondary'}\n              display={'inline-flex'}\n              alignItems={'center'}\n            >\n              <Info2Icon fontSize={'small'} color={'inherit'} sx={{ marginX: 1 / 2 }} />\n              {' ' + t('swapTolerance')}\n            </Typography>\n          </Tooltip>\n        ),\n        value: `${slippage}%`,\n        color: 'var(--color-text-primary)',\n      },\n    ]\n\n    return (\n      <RiskComponent\n        hasNoIcon={true}\n        title={\n          <Box\n            key={'title'}\n            width={'100%'}\n            display={'flex'}\n            flexDirection={'column'}\n            justifyContent={'center'}\n          >\n            <Typography component={'span'} variant={'h3'} textAlign={'center'}>\n              {t('labelSwapSecondConfirmTitle')}\n            </Typography>\n            <Box display={'flex'} marginY={2} alignItems={'center'} justifyContent={'center'}>\n              <Box display={'flex'} flexDirection={'column'} alignItems={'center'} width={'45%'}>\n                <CoinIcon symbol={fromSymbol} size={42} />\n                <Typography marginTop={1.5} marginBottom={1} color={'var(--color-text-secondary)'}>\n                  {t('labelFrom')}\n                </Typography>\n                <Typography>\n                  {fromAmount} {fromSymbol}\n                </Typography>\n              </Box>\n              <Box display={'flex'} justifyContent={'center'} width={'10%'}>\n                <Typography variant={'h4'}>{'\\u2192'}</Typography>\n              </Box>\n              <Box width={'45%'} display={'flex'} flexDirection={'column'} alignItems={'center'}>\n                <CoinIcon symbol={toSymbol} size={42} />\n                <Typography marginTop={1.5} marginBottom={1} color={'textSecondary'}>\n                  {t('labelTo')}\n                </Typography>\n                <Typography>\n                  {toAmount} {toSymbol}\n                </Typography>\n              </Box>\n            </Box>\n          </Box>\n        }\n        open={open}\n        infos={infos}\n        strongBtn={'confirm'}\n        confirmLabel={'labelConfirm'}\n        handleClose={handleClose}\n        handleConfirm={handleConfirm}\n      />\n    )\n  },\n)\nexport const WrongNetworkGuide = withTranslation('common', {\n  withRef: true,\n})(\n  ({\n    t,\n    open,\n    handleClose,\n  }: WithTranslation & {\n    open: boolean\n    handleClose: (event: MouseEvent, isAgree?: boolean) => void\n  }) => {\n    const { defaultNetwork } = useSettings()\n    const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n    return (\n      <DialogStyle\n        open={open}\n        keepMounted\n        onClose={(e: MouseEvent) => handleClose(e)}\n        aria-describedby='alert-dialog-slide-description'\n      >\n        <DialogTitle>\n          {t('labelWrongNetworkGuideTitle', {\n            l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n          })}\n        </DialogTitle>\n        <DialogContent>\n          <DialogContentText>\n            <Typography component={'span'} variant={'body1'} color={'inherit'}>\n              {t('labelWrongNetworkGuide', {\n                l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n              })}\n            </Typography>\n          </DialogContentText>\n        </DialogContent>\n        <DialogActions>\n          <Button variant={'outlined'} size={'medium'} onClick={(e) => handleClose(e as any)}>\n            {t('labelOK')}\n          </Button>\n        </DialogActions>\n      </DialogStyle>\n    )\n  },\n)\n\nexport const ConfirmLinkCopy = withTranslation('common', {\n  withRef: true,\n})(\n  ({\n    t,\n    open,\n    handleClose,\n    setCopyToastOpen,\n  }: WithTranslation & {\n    open: boolean\n    setCopyToastOpen: (vale: boolean) => void\n    handleClose: (event: MouseEvent, isAgree?: boolean) => void\n  }) => {\n    const { search } = useLocation()\n    const searchParams = new URLSearchParams(search)\n    return (\n      <DialogStyle\n        open={open}\n        keepMounted\n        onClose={(e: MouseEvent) => handleClose(e)}\n        aria-describedby='alert-dialog-slide-description'\n      >\n        <DialogTitle>\n          <Typography component={'span'} variant={'h4'} textAlign={'center'}>\n            {t('labelOpenInWalletTitle')}\n          </Typography>\n        </DialogTitle>\n        <DialogContent>\n          <DialogContentText id='alert-dialog-slide-description'>\n            <Typography component={'span'} variant={'body1'} color={'inherit'}>\n              <Trans i18nKey={'labelOpenInWalletDetail'}>\n                labelOpenInWalletDetail URL for adding fund has been copied. You can choose either\n                way to continue:\n              </Trans>\n            </Typography>\n          </DialogContentText>\n          <List sx={{ marginTop: 2 }}>\n            <ListItem>\n              <Trans i18nKey={'labelOpenInWalletDetailLi1'}>\n                Open your wallet app and paste the url in its internal Dapp browser\n              </Trans>\n            </ListItem>\n            <ListItem>\n              <Trans i18nKey={'labelOpenInWalletDetailLi2'}>\n                Open your desktop Chrome browser and paste the url in Chrome\n              </Trans>\n            </ListItem>\n          </List>\n        </DialogContent>\n\n        <DialogActions>\n          <Button\n            variant={'contained'}\n            fullWidth\n            onClick={(e) => {\n              copyToClipBoard(Bridge + `?${searchParams.toString()}`)\n              setCopyToastOpen(true)\n              handleClose(e as any)\n            }}\n          >\n            {t('labelCopyClipBoard')}\n          </Button>\n        </DialogActions>\n        <DialogContent>\n          <Typography component={'p'} marginY={2}>\n            {t('labelCopyManually')}\n          </Typography>\n          <TextField\n            disabled={true}\n            fullWidth={true}\n            value={Bridge + `?${searchParams.toString()}`}\n          />\n        </DialogContent>\n      </DialogStyle>\n    )\n  },\n)\n\nexport const InformationForCoinBase = withTranslation('common', {\n  withRef: true,\n})(\n  ({\n    t,\n    open,\n    handleClose,\n  }: WithTranslation & {\n    open: boolean\n    handleClose: (event: MouseEvent, notShow?: boolean) => void\n  }) => {\n    const providers = Object.keys(ConnectProviders).filter((item) => item !== 'unknown')\n    return (\n      <DialogStyle\n        open={open}\n        keepMounted\n        onClose={(e: MouseEvent) => handleClose(e)}\n        aria-describedby='alert-dialog-slide-description'\n      >\n        <DialogTitle> {t('labelInformation')}</DialogTitle>\n        <DialogContent>\n          <DialogContentText id='alert-dialog-slide-description'>\n            <Trans i18nKey={'labelNoticeForProvider'} tOptions={{ name: providers.join(',') }}>\n              Loopring only support and maintain {providers.join(',')} plugin for Wallet Connect, if\n              your installed other Wallet plugin, please make sure it's the\n              {providers.join(',')} popup.\n            </Trans>\n            <Link target='_top' rel='noopener noreferrer' href={'./#/document/plugin_guide.md'}>\n              {t('labelGuid')}\n            </Link>\n          </DialogContentText>\n        </DialogContent>\n        <DialogActions>\n          <Button\n            variant={'contained'}\n            size={'small'}\n            onClick={(e) => {\n              handleClose(e as any, true)\n            }}\n            color={'primary'}\n          >\n            {t('labelIKnow')}\n          </Button>\n        </DialogActions>\n      </DialogStyle>\n    )\n  },\n)\n\nexport const InformationForNoMetaNFT = withTranslation('common', {\n  withRef: true,\n})(\n  ({\n    t,\n    open,\n    method,\n    handleClose,\n  }: WithTranslation & {\n    open: boolean\n    method?: string\n    handleClose: (event: MouseEvent, isAgree?: boolean) => void\n  }) => {\n    return (\n      <DialogStyle\n        open={open}\n        onClose={(e: MouseEvent) => handleClose(e, false)}\n        aria-describedby='alert-dialog-slide-description'\n      >\n        <DialogTitle> {t('labelInformation')}</DialogTitle>\n        <DialogContent>\n          <DialogContentText id='alert-dialog-slide-description'>\n            <Trans\n              i18nKey={'labelNoticeForNoMetaNFT'}\n              tOptions={{ method: t('label' + method).toLowerCase() }}\n            >\n              Your Minted NFT does not contain Metadata or media information. Are you sure you still\n              wish to {{ method }} this NFT?\n            </Trans>\n          </DialogContentText>\n        </DialogContent>\n        <DialogActions>\n          <Button\n            variant={'outlined'}\n            size={'medium'}\n            onClick={(e) => handleClose(e as any, false)}\n          >\n            {t('labelNo')}\n          </Button>\n          <Button\n            variant={'contained'}\n            size={'small'}\n            onClick={(e) => {\n              handleClose(e as any, true)\n            }}\n            color={'primary'}\n          >\n            {t('labelYes')}\n          </Button>\n        </DialogActions>\n      </DialogStyle>\n    )\n  },\n)\nexport const InformationForAccountFrozen = withTranslation('common', {\n  withRef: true,\n})(\n  ({\n    t,\n    open,\n    type,\n    messageKey = 'labelNoticeForForAccountFrozen',\n  }: // handleClose,\n  WithTranslation & {\n    open: boolean\n    type: string\n    messageKey?: string\n    // handleClose: (event: MouseEvent, isAgree?: boolean) => void;\n  }) => {\n    const { setShowTradeIsFrozen } = useOpenModals()\n    return (\n      <DialogStyle\n        open={open}\n        onClose={() => setShowTradeIsFrozen({ isShow: false })}\n        aria-describedby='alert-dialog-slide-description'\n        maxWidth={'xs'}\n      >\n        <DialogTitle> Account Locked - Unable to Operate</DialogTitle>\n        <DialogContent>\n          <DialogContentText id='alert-dialog-slide-description'>\n            {t(messageKey, { type })}\n          </DialogContentText>\n        </DialogContent>\n        <DialogActions>\n          <Button\n            variant={'contained'}\n            size={'small'}\n            onClick={() => {\n              setShowTradeIsFrozen({ isShow: false })\n            }}\n            color={'primary'}\n          >\n            {t('labelOK')}\n          </Button>\n        </DialogActions>\n      </DialogStyle>\n    )\n  },\n)\n\nexport const LayerswapNotice = withTranslation('common', {\n  withRef: true,\n})(\n  ({\n    t,\n    open,\n    account,\n  }: WithTranslation & {\n    open: boolean\n    account: Account\n  }) => {\n    const [agree, setAgree] = React.useState(false)\n    const { defaultNetwork } = useSettings()\n    const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n    React.useEffect(() => {\n      if (!open) {\n        setAgree(false)\n      }\n    }, [open])\n    const { setShowLayerSwapNotice } = useOpenModals()\n    return (\n      <DialogStyle\n        open={open}\n        onClose={() => setShowLayerSwapNotice({ isShow: false })}\n        aria-describedby='alert-dialog-slide-description'\n      >\n        <DialogTitle> {t('labelInformation')}</DialogTitle>\n        <DialogContent>\n          <DialogContentText id='alert-dialog-slide-description'>\n            <Trans\n              i18nKey={'labelLayerSwapUnderstandDes'}\n              tOptions={{\n                loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n                loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n              }}\n            >\n              LayerSwap is a 3rd party App service provider to help move tokens from exchange to\n              Loopring L2 directly. If you have any concerns regarding their service, please check\n              out their\n              <Link\n                target='_blank'\n                rel='noopener noreferrer'\n                href={'https://www.layerswap.io/blog/guide/Terms_of_Service'}\n              >\n                TOS\n              </Link>\n              .\n            </Trans>\n          </DialogContentText>\n          <MuiFormControlLabel\n            control={\n              <Checkbox\n                checked={agree}\n                onChange={(_event: any, state: boolean) => {\n                  setAgree(state)\n                }}\n                checkedIcon={<CheckedIcon />}\n                icon={<CheckBoxIcon />}\n                color='default'\n              />\n            }\n            label={t('labelLayerSwapUnderstand')}\n          />\n        </DialogContent>\n        <DialogActions>\n          <Button\n            variant={'contained'}\n            size={'small'}\n            disabled={!agree}\n            onClick={() => {\n              window.open(\n                `https://www.layerswap.io/?destNetwork=loopring_mainnet&destAddress=${account.accAddress}&lockNetwork=true&lockAddress=true&addressSource=loopringWeb`,\n              )\n              window.opener = null\n              setShowLayerSwapNotice({ isShow: false })\n            }}\n            color={'primary'}\n          >\n            {t('labelIUnderStand')}\n          </Button>\n        </DialogActions>\n      </DialogStyle>\n    )\n  },\n)\nexport const AnotherNetworkNotice = withTranslation('common', {\n  withRef: true,\n})(\n  ({\n    t,\n    open,\n  }: WithTranslation & {\n    open: boolean\n    account: Account\n  }) => {\n    const [agree, setAgree] = React.useState(false)\n    const { defaultNetwork } = useSettings()\n    const theme = useTheme()\n    const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n    React.useEffect(() => {\n      if (!open) {\n        setAgree(false)\n      }\n    }, [open])\n\n    const {\n      setShowAnotherNetworkNotice,\n      modals: { isShowAnotherNetwork },\n    } = useOpenModals()\n    return (\n      <DialogStyle\n        open={open}\n        onClose={() => setShowAnotherNetworkNotice({ isShow: false })}\n        aria-describedby='alert-dialog-slide-description'\n      >\n        <DialogTitle sx={{ marginBottom: 2, display: 'inline-flex', alignItems: 'center' }}>\n          <RiskIcon htmlColor={'var(--color-warning)'} fontSize={'large'} />\n          <Typography component={'span'} color={'var(--color-warning)'} variant={'h5'} paddingX={1}>\n            {t('labelRiskReminder')}\n          </Typography>\n        </DialogTitle>\n        <DialogContent>\n          <DialogContentText id='alert-dialog-slide-description' sx={{ marginBottom: 2 }}>\n            <Trans\n              i18nKey={'labelAnotherNetworkDes'}\n              tOptions={{\n                layer2: L1L2_NAME_DEFINED[network].layer2,\n                l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n              }}\n            >\n              <Typography component={'span'} color={'textPrimary'}>\n                Orbiter.finance\n              </Typography>\n              is a 3rd party App service provider to help move tokens from exchange to Loopring L2\n              directly. If you have any concerns regarding their service, please check out their\n              <Link\n                target='_blank'\n                rel='noopener noreferrer'\n                href={'https://get.orbiter.finance/Orbiter_Finance_Terms_of_Use.pdf'}\n              >\n                TOS\n              </Link>\n              .\n            </Trans>\n          </DialogContentText>\n          <DialogContentText\n            id='alert-dialog-slide-description'\n            sx={{ marginBottom: 2, display: 'flex', justifyContent: 'center' }}\n          >\n            <img\n              width={'60%'}\n              src={`${SoursURL}images/orbiter_${theme.mode}.webp`}\n              alt={'orbiter'}\n            />\n          </DialogContentText>\n          <DialogContentText id='alert-dialog-slide-description' sx={{ marginBottom: 2 }}>\n            <Trans\n              i18nKey={'labelAnotherNetworkDes2'}\n              tOptions={{\n                layer2: L1L2_NAME_DEFINED[network].layer2,\n                l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n              }}\n            >\n              Note: Please ensure to check out the \"Change Account\" option and input the recipient's\n              address carefully. If you want to send token to network other than l1ChainName, the\n              recipient address must be different than the sender address.\n            </Trans>\n          </DialogContentText>\n\n          {/*<DialogContentText id='alert-dialog-slide-description' sx={{ marginBottom: 2 }}>*/}\n          {/*  <Trans*/}\n          {/*    i18nKey={'labelAnotherNetworkDes3'}*/}\n          {/*    tOptions={{*/}\n          {/*      layer2: L1L2_NAME_DEFINED[network].layer2,*/}\n          {/*      l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,*/}\n          {/*      loopringL2: L1L2_NAME_DEFINED[network].loopringL2,*/}\n          {/*      l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,*/}\n          {/*      l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,*/}\n          {/*      ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,*/}\n          {/*    }}*/}\n          {/*  >*/}\n          {/*    If you want to send token to network other than l1ChainName, the recipient address*/}\n          {/*    must be different than the sender address; else you will lose that asset for ever.*/}\n          {/*  </Trans>*/}\n          {/*</DialogContentText>*/}\n\n          <MuiFormControlLabel\n            control={\n              <Checkbox\n                checked={agree}\n                onChange={(_event: any, state: boolean) => {\n                  setAgree(state)\n                }}\n                checkedIcon={<CheckedIcon />}\n                icon={<CheckBoxIcon />}\n                color='default'\n              />\n            }\n            label={t('labelAnotherNetworkUnderstand')}\n          />\n        </DialogContent>\n        <DialogActions>\n          <Button\n            variant={'contained'}\n            size={'small'}\n            disabled={!agree}\n            onClick={() => {\n              window.open(isShowAnotherNetwork?.info?.url)\n              window.opener = null\n              setShowAnotherNetworkNotice({ isShow: false })\n            }}\n            color={'primary'}\n          >\n            {t('labelIUnderStand')}\n          </Button>\n        </DialogActions>\n      </DialogStyle>\n    )\n  },\n)\n\nexport const OtherExchangeDialog = withTranslation('common', {\n  withRef: true,\n})(\n  ({\n    t,\n    open,\n    handleClose,\n  }: WithTranslation & {\n    open: boolean\n    handleClose: (event: MouseEvent, notShow?: boolean) => void\n  }) => {\n    const [agree, setAgree] = React.useState(false)\n    const { defaultNetwork } = useSettings()\n    const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n    React.useEffect(() => {\n      if (!open) {\n        setAgree(false)\n      }\n    }, [open])\n    return (\n      <DialogStyle\n        open={open}\n        keepMounted\n        onClose={(e: MouseEvent) => handleClose(e)}\n        aria-describedby='alert-dialog-slide-description'\n      >\n        <DialogTitle> {t('labelConfirmBtrade')}</DialogTitle>\n        <DialogContent>\n          <Trans\n            i18nKey={'labelConfirmDetail'}\n            tOptions={{\n              loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n              l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n              l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n              ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n            }}\n          >\n            <Typography marginBottom={2} variant={'body1'} color={'textSecondary'}>\n              Before withdrawing, please check with your Btrade support that they accept deposits\n              from smart contracts.\n            </Typography>\n            <Typography marginBottom={2} variant={'body1'} color={'textSecondary'}>\n              L2 to L1 withdrawing is via a smart contract. The Btrade depositing address may not be\n              able to acknowledge the tokens deposited automatically.\n            </Typography>\n            <Typography marginBottom={2} variant={'body1'} color={'textSecondary'}>\n              If the deposited tokens do not appear at the Btrade address within 24 hours, please\n              contact your Btrade support to manually acknowledge this transaction.\n            </Typography>\n          </Trans>\n          <MuiFormControlLabel\n            control={\n              <Checkbox\n                checked={agree}\n                onChange={(_event: any, state: boolean) => {\n                  setAgree(state)\n                }}\n                checkedIcon={<CheckedIcon />}\n                icon={<CheckBoxIcon />}\n                color='default'\n              />\n            }\n            label={t('labelBtradeUnderstand')}\n          />\n        </DialogContent>\n        <DialogActions>\n          <Button variant={'outlined'} size={'medium'} onClick={(e) => handleClose(e as any)}>\n            {t('labelDisAgreeConfirm')}\n          </Button>\n          <Button\n            variant={'contained'}\n            size={'small'}\n            disabled={!agree}\n            onClick={(e) => {\n              handleClose(e as any, true)\n            }}\n            color={'primary'}\n          >\n            {t('labelAgreeConfirm')}\n          </Button>\n        </DialogActions>\n      </DialogStyle>\n    )\n  },\n)\n\nexport const ConfirmDefiBalanceIsLimit = withTranslation('common')(\n  ({\n    t,\n    open,\n    type,\n    defiData,\n    handleClose,\n  }: WithTranslation & {\n    open: boolean\n    type: string\n    defiData: TradeDefi<any>\n    handleClose: (event: MouseEvent, isAgree?: boolean) => void\n  }) => {\n    const { defaultNetwork } = useSettings()\n    const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n    const maxValue =\n      defiData.buyToken?.symbol &&\n      `${getValuePrecisionThousand(\n        new BigNumber(defiData?.maxBuyVol ?? 0).div('1e' + defiData.buyToken?.decimals),\n        defiData.buyToken?.precision,\n        defiData.buyToken?.precision,\n        defiData.buyToken?.precision,\n        false,\n        { floor: true },\n      )} ${defiData.buyToken?.symbol}`\n\n    return (\n      <Dialog\n        open={open}\n        keepMounted\n        onClose={(e: MouseEvent) => handleClose(e)}\n        aria-describedby='alert-dialog-slide-description'\n      >\n        <DialogTitle> {t('labelInformation')}</DialogTitle>\n        <DialogContent>\n          <DialogContentText id='alert-dialog-slide-description'>\n            {new BigNumber(defiData?.maxSellVol ?? 0).gte(defiData?.miniSellVol ?? 0) && (\n              <Typography>\n                <Trans i18nKey={'labelDefiMaxBalance'} tOptions={{ maxValue }}>\n                  Your Redeem order is too large and cannot be withdrawn immediately, you can only\n                  redeem {{ maxValue }}\n                </Trans>\n              </Typography>\n            )}\n            <Typography>\n              <Trans\n                i18nKey={'labelDefiMaxBalance1'}\n                tOptions={{\n                  type,\n                  loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n                  loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                  l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                  l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                  ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                }}\n              >\n                or you can\n                <List sx={{ marginTop: 2 }}>\n                  <ListItem>Withdraw to L1 and redeem through crv or lido</ListItem>\n                  <ListItem>Wait some time and wait for pool liquidity</ListItem>\n                </List>\n              </Trans>\n            </Typography>\n          </DialogContentText>\n        </DialogContent>\n        <DialogActions>\n          <Button variant={'outlined'} size={'medium'} onClick={(e) => handleClose(e as any)}>\n            {t('labelDisAgreeConfirm')}\n          </Button>\n          <Button\n            variant={'contained'}\n            size={'small'}\n            onClick={(e) => {\n              handleClose(e as any, true)\n            }}\n            color={'primary'}\n          >\n            {t('labelAgreeConfirm')}\n          </Button>\n        </DialogActions>\n      </Dialog>\n    )\n  },\n)\n\nexport const ConfirmAmmExitMiniOrder = withTranslation('common')(\n  ({\n    t,\n    open,\n    type,\n    handleClose,\n  }: WithTranslation & {\n    open: boolean\n  } & (\n      | {\n          type: 'Disabled'\n          handleClose: (event: any) => void\n        }\n      | {\n          type: 'Mini'\n          handleClose: (event: any, isAgree?: boolean) => void\n        }\n    )) => {\n    return (\n      <DialogStyle\n        open={open}\n        keepMounted\n        onClose={(e: MouseEvent) => handleClose(e)}\n        aria-describedby='alert-dialog-slide-description'\n      >\n        <DialogTitle> {t('labelInformation')}</DialogTitle>\n        <DialogContent>\n          <DialogContentText id='alert-dialog-slide-description'>\n            {t(type === 'Disabled' ? 'labelAmmExitMiniOrderDisabled' : 'labelAmmExitMiniOrderMini')}\n          </DialogContentText>\n        </DialogContent>\n        <DialogActions>\n          {type === 'Disabled' ? (\n            <Button\n              variant={'contained'}\n              size={'small'}\n              onClick={(e) => {\n                handleClose(e)\n              }}\n              color={'primary'}\n            >\n              {t('labelIKnow')}\n            </Button>\n          ) : (\n            <>\n              <Button variant={'outlined'} size={'medium'} onClick={(e) => handleClose(e as any)}>\n                {t('labelDisAgreeConfirm')}\n              </Button>\n              <Button\n                variant={'contained'}\n                size={'small'}\n                onClick={(e) => {\n                  handleClose(e as any, true)\n                }}\n                color={'primary'}\n              >\n                {t('labelAgreeConfirm')}\n              </Button>\n            </>\n          )}\n        </DialogActions>\n      </DialogStyle>\n    )\n  },\n)\nexport const ConfirmStackingRedeem = withTranslation('common')(\n  ({\n    t,\n    open,\n    handleClose,\n  }: WithTranslation & {\n    open: boolean\n    handleClose: (event: MouseEvent, isAgree?: boolean) => void\n  }) => {\n    const { setShowLayerSwapNotice } = useOpenModals()\n    return (\n      <DialogStyle\n        open={open}\n        onClose={() => setShowLayerSwapNotice({ isShow: false })}\n        aria-describedby='alert-dialog-slide-description'\n      >\n        <DialogTitle> {t('labelInformation')}</DialogTitle>\n        <DialogContent>\n          <DialogContentText id='alert-dialog-slide-description'>\n            <Trans i18nKey={'labelStackingAgreeRedeem'} />\n          </DialogContentText>\n        </DialogContent>\n        <DialogActions>\n          <Button variant={'outlined'} size={'medium'} onClick={(e) => handleClose(e as any)}>\n            {t('labelOrderCancel')}\n          </Button>\n          <Button\n            variant={'contained'}\n            size={'small'}\n            onClick={(e) => {\n              handleClose(e as any, true)\n            }}\n            color={'primary'}\n          >\n            {t('labelAgreeRedeem')}\n          </Button>\n        </DialogActions>\n      </DialogStyle>\n    )\n  },\n)\n\nexport const ConfirmDefiNOBalance = withTranslation('common')(\n  ({\n    t,\n    isJoin,\n    open,\n    market,\n    type,\n    handleClose,\n    isLeverage,\n  }: WithTranslation & {\n    open: boolean\n    type: symbol\n    market: `${string}-${string}`\n    isJoin: boolean\n    handleClose: (event: any) => void\n    isLeverage: boolean\n  }) => {\n    // @ts-ignore\n    const [, baseSymbol, _quoteSymbol] = market.match(/(\\w+)-(\\w+)/i)\n    const { defaultNetwork } = useSettings()\n    const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n    return (\n      <DialogStyle\n        open={open}\n        keepMounted\n        onClose={(e: MouseEvent) => handleClose(e)}\n        aria-describedby='alert-dialog-slide-description'\n      >\n        <DialogTitle> {t('labelInformation')}</DialogTitle>\n        <DialogContent>\n          <DialogContentText id='alert-dialog-slide-description'>\n            {isJoin ? (\n              <Typography component={'span'}>\n                <Trans i18nKey={'labelDefiNoBalanceJoin'}>\n                  No quota available. Loopring will setup the pool soon, please revisit for\n                  subscription later.\n                </Trans>\n              </Typography>\n            ) : (\n              <Typography component={'span'} display={'flex'} flexDirection={'column'}>\n                <Trans\n                  i18nKey={isLeverage ? 'labelDefiNoBalanceLeverage' : 'labelDefiNoBalance'}\n                  components={{ span: <span /> }}\n                >\n                  <Typography component={'span'} marginBottom={3}>\n                    Loopring rebalance pool can't satisfy your complete request now.\n                  </Typography>\n                  <Typography component={'span'}>\n                    For the remaining investment, you can choose one of the approaches.\n                  </Typography>\n                </Trans>\n                {!isLeverage && (\n                  <List sx={{ marginTop: 1 }}>\n                    <Trans\n                      i18nKey={'labelDefiNoBalanceList'}\n                      components={{ li: <li /> }}\n                      tOptions={{\n                        symbol: baseSymbol,\n                        type,\n                        loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n                        loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                        l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                        l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                        ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                      }}\n                    >\n                      <ListItem style={{ marginBottom: 0 }}>\n                        Withdraw WSTETH to L1 and trade through CRV or LIDO directly\n                      </ListItem>\n                      <ListItem style={{ marginBottom: 0 }}>\n                        Wait some time for Loopring to setup the rebalance pool again, then revist\n                        the page for redeem\n                      </ListItem>\n                    </Trans>\n                  </List>\n                )}\n              </Typography>\n            )}\n          </DialogContentText>\n        </DialogContent>\n        <DialogActions>\n          <Button\n            variant={'contained'}\n            size={'small'}\n            onClick={(e) => {\n              handleClose(e)\n            }}\n            color={'primary'}\n          >\n            {t('labelIKnow')}\n          </Button>\n        </DialogActions>\n      </DialogStyle>\n    )\n  },\n)\n\nexport const ConfirmInvestDefiServiceUpdate = withTranslation('common')(\n  ({\n    t,\n    open,\n    handleClose,\n    isCianETHJoin\n  }: WithTranslation & {\n    open: boolean\n    handleClose: (event: any) => void\n    isCianETHJoin: boolean\n  }) => {\n    const history = useHistory()\n    return (\n      <Dialog\n        open={open}\n        keepMounted\n        onClose={(e: MouseEvent) => handleClose(e)}\n        aria-describedby='alert-dialog-slide-description'\n      >\n        <DialogTitle> {t('labelInformation')}</DialogTitle>\n        <DialogContent>\n          <DialogContentText id='alert-dialog-slide-description'>\n            <Typography\n              whiteSpace={'pre-line'}\n              component={'span'}\n              variant={'body1'}\n              display={'block'}\n              color={'textSecondary'}\n            >\n              {isCianETHJoin ? t('labelDefiCloseCian') : t('labelDefiClose')}\n            </Typography>\n          </DialogContentText>\n        </DialogContent>\n        <DialogActions>\n          <Button\n            variant={'contained'}\n            size={'small'}\n            onClick={(e) => {\n              history.goBack()\n              handleClose(e)\n            }}\n            color={'primary'}\n          >\n            {t('labelIKnow')}\n          </Button>\n        </DialogActions>\n      </Dialog>\n    )\n  },\n)\nexport const ConfirmInvestDefiRisk = withTranslation('common')(\n  ({\n    t,\n    open,\n    type,\n    handleClose,\n    confirmationNeeded,\n  }: WithTranslation & {\n    open: boolean\n    type: 'WSETH' | 'RETH' | 'CiETH'\n    confirmationNeeded: boolean\n    handleClose: (event: any, isAgree?: boolean) => void\n  }) => {\n    const [agree, setAgree] = React.useState(false)\n    const { defaultNetwork } = useSettings()\n    const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n    React.useEffect(() => {\n      if (!open) {\n        setAgree(false)\n      }\n    }, [open])\n    return (\n      <Dialog\n        open={open}\n        keepMounted\n        onClose={(e: MouseEvent) => handleClose(e)}\n        aria-describedby='alert-dialog-slide-description'\n      >\n        <DialogTitle> {t(`label${type}DefiRiskTitle`)}</DialogTitle>\n        <DialogContent>\n          <DialogContentText id='alert-dialog-slide-description'>\n            <Trans\n              i18nKey={`label${type}DefiRisk`}\n              tOptions={{\n                layer2: L1L2_NAME_DEFINED[network].layer2,\n                l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n              }}\n              components={{\n                p: (\n                  <Typography\n                    whiteSpace={'pre-line'}\n                    component={'span'}\n                    variant={'body1'}\n                    display={'block'}\n                    marginBottom={1}\n                    color={'textSecondary'}\n                  />\n                ),\n              }}\n            >\n              <Typography\n                whiteSpace={'pre-line'}\n                component={'span'}\n                variant={'body1'}\n                display={'block'}\n                marginBottom={1}\n                color={'textSecondary'}\n              >\n                Lido is a liquid staking solution for ETH 2.0 backed by industry-leading staking\n                providers. Lido lets users stake their ETH - without locking assets or maintaining\n                infrastructure.\n              </Typography>\n              <Typography\n                whiteSpace={'pre-line'}\n                component={'span'}\n                variant={'body1'}\n                marginBottom={1}\n                display={'block'}\n                color={'textSecondary'}\n              >\n                When using Lido to stake your ETH on the Ethereum beacon chain, users will receive a\n                token (stETH), which represents their ETH on the Ethereum beacon chain on a 1:1\n                basis. It effectively acts as a bridge bringing ETH 2.0’s staking rewards to ETH\n                1.0.\n              </Typography>\n              <Typography\n                whiteSpace={'pre-line'}\n                component={'span'}\n                variant={'body1'}\n                marginBottom={1}\n                display={'block'}\n                color={'textSecondary'}\n              >\n                wstETH is the wrapped version of stETH. The total amount of wstETH doesn’t change\n                after users receive the token. Instead, the token’s value increase over time to\n                reflect ETH staking rewards earned.\n              </Typography>\n            </Trans>\n            {type === 'CiETH' && (\n              <Trans\n                i18nKey={'labelDefiWithdrawFee'}\n                components={{\n                  p: (\n                    <Typography\n                      whiteSpace={'pre-line'}\n                      component={'span'}\n                      variant={'body1'}\n                      display={'block'}\n                      marginBottom={1}\n                      color={'textSecondary'}\n                    />\n                  ),\n                }}\n              />\n            )}\n          </DialogContentText>\n          {confirmationNeeded && (\n            <MuiFormControlLabel\n              control={\n                <Checkbox\n                  checked={agree}\n                  onChange={(_event: any, state: boolean) => {\n                    setAgree(state)\n                  }}\n                  checkedIcon={<CheckedIcon />}\n                  icon={<CheckBoxIcon />}\n                  color='default'\n                />\n              }\n              label={t('labelDefiAgree')}\n            />\n          )}\n        </DialogContent>\n        {type !== 'CiETH' && (\n          <DialogContent>\n            <DialogContentText id='alert-dialog-defiRisk2'>\n              <Trans\n                i18nKey={`label${type}DefiRisk2`}\n                tOptions={{\n                  layer2: L1L2_NAME_DEFINED[network].layer2,\n                  l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                  loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                  l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                  l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                  ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                }}\n              >\n                <Typography\n                  whiteSpace={'pre-line'}\n                  component={'span'}\n                  variant={'body2'}\n                  marginTop={2}\n                  display={'block'}\n                  color={'var(--color-text-third)'}\n                >\n                  It is important to note that users can't redeem wstETH for ETH until phase 2 of\n                  Ethereum 2.0. However, users are able to trade wstETH for ETH on various exchanges\n                  at market prices.\n                </Typography>\n                <Typography\n                  whiteSpace={'pre-line'}\n                  component={'span'}\n                  variant={'body2'}\n                  marginTop={2}\n                  display={'block'}\n                  color={'var(--color-text-third)'}\n                >\n                  Loopring will provide a pool to allow users to trade wstETH for ETH directly on\n                  Layer 2. The pool will rebalance periodically when it reaches a specific\n                  threshold. If there is not enough inventory on Layer 2, user can always withdraw\n                  their wstETH tokens to Layer 1 and swap for ETH in Lido, Curve, or 1inch.\n                </Typography>\n              </Trans>\n            </DialogContentText>\n          </DialogContent>\n        )}\n        <DialogActions>\n          <Button\n            variant={'contained'}\n            size={'small'}\n            disabled={confirmationNeeded ? !agree : false}\n            onClick={(e) => {\n              handleClose(e as any, true)\n            }}\n            color={'primary'}\n          >\n            {t('labelIKnow')}\n          </Button>\n        </DialogActions>\n      </Dialog>\n    )\n  },\n)\n\nexport const ConfirmInvestDualGainRisk = withTranslation('common')(\n  ({\n    t,\n    open,\n    handleClose,\n  }: WithTranslation & {\n    open: boolean\n    handleClose: (event: any, isAgree?: boolean) => void\n  }) => {\n    const { defaultNetwork } = useSettings()\n    const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n    const [agree, setAgree] = React.useState(false)\n    return (\n      <Dialog\n        open={open}\n        sx={{ zIndex: 2000 }}\n        keepMounted\n        onClose={(e: MouseEvent) => handleClose(e)}\n        aria-describedby='alert-dialog-slide-description'\n      >\n        <DialogTitle> {t('labelInvestDualGainTitle')}</DialogTitle>\n        <IconButton\n          aria-label='close'\n          onClick={handleClose}\n          sx={{\n            position: 'absolute',\n            right: 8,\n            top: 8,\n          }}\n        >\n          <CloseIcon />\n        </IconButton>\n        <DialogContent>\n          <Box>\n            <Trans\n              i18nKey={'labelInvestDualGainGuid'}\n              tOptions={{\n                layer2: L1L2_NAME_DEFINED[network].layer2,\n                loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n                l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n              }}\n              components={{\n                p: (\n                  <Typography\n                    whiteSpace={'pre-line'}\n                    component={'span'}\n                    variant={'body1'}\n                    display={'block'}\n                    color={'textSecondary'}\n                    paddingY={1 / 2}\n                  />\n                ),\n                ol: <ol style={{ listStyle: 'decimal', paddingLeft: 24 }} />,\n                li: (\n                  <Typography\n                    whiteSpace={'pre-line'}\n                    component={'li'}\n                    display={'list-item'}\n                    variant={'body1'}\n                    color={'textSecondary'}\n                  />\n                ),\n                h5: (\n                  <Typography\n                    whiteSpace={'pre-line'}\n                    component={'h5'}\n                    variant={'h5'}\n                    display={'block'}\n                    color={'textPrimary'}\n                    paddingY={2}\n                  />\n                ),\n              }}\n            >\n              <p>\n                Covered Gain is an investment strategy to sell digital assets at your Target Price\n                and earn interest while waiting.\n              </p>\n              <p>On the Settlement Date, there can be 2 scenarios:</p>\n              <ol>\n                <li>Market Price &gt; Target Price</li>\n                <li>Market Price ≤ Target Price</li>\n              </ol>\n              <h5>Market Price &gt; Target Price</h5>\n              <p>Your original investment and earned interest will be sold at the target price.</p>\n              <p>\n                This order is then closed regardless of whether \"Auto Reinvest\" is enabled or not.\n              </p>\n              <h5>Market Price ≤ Target Price</h5>\n              <p>Your original investment and earned interest won’t be sold.</p>\n              <p>\n                If you enable the “Auto Reinvest” feature, Loopring will automatically subscribe to\n                a suitable dual investment product based on the agreed terms until you either\n                successfully sell crypto at your desired price or disable the feature.\n              </p>\n              <h5>Auto Reinvest</h5>\n              <p>\n                When you enable the “Auto Reinvest” feature, Loopring will automatically reinvest\n                your funds into a new product with the same target price when the previous product\n                expires, continuing until you successfully sell your crypto at your Target Price. If\n                there isn’t an available product within 2 hours after the previous settlement, the\n                order will be automatically closed.\n              </p>\n              <p>Sell Price: the Target Price at which you want to sell your crypto.</p>\n              <p>\n                Longest Settlement Date: your acceptable investment period. If no suitable products\n                are available within this range, “Auto Reinvest” will not subscribe to any products\n                for you, even if it's enabled.\n              </p>\n            </Trans>\n          </Box>\n          <MuiFormControlLabel\n            control={\n              <Checkbox\n                checked={agree}\n                onChange={(_event: any, state: boolean) => {\n                  setAgree(state)\n                }}\n                checkedIcon={<CheckedIcon />}\n                icon={<CheckBoxIcon />}\n                color='default'\n              />\n            }\n            label={t('labelDualAgree')}\n          />\n        </DialogContent>\n\n        <DialogActions>\n          <Button\n            variant={'contained'}\n            size={'small'}\n            disabled={!agree}\n            onClick={(e) => {\n              handleClose(e as any, agree)\n            }}\n            color={'primary'}\n          >\n            {t('labelIKnow')}\n          </Button>\n        </DialogActions>\n      </Dialog>\n    )\n  },\n)\nexport const ConfirmInvestDualDipRisk = withTranslation('common')(\n  ({\n    t,\n    open,\n    handleClose,\n  }: WithTranslation & {\n    open: boolean\n    handleClose: (event: any, isAgree?: boolean) => void\n  }) => {\n    const { defaultNetwork } = useSettings()\n    const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n    const [agree, setAgree] = React.useState(false)\n    return (\n      <Dialog\n        open={open}\n        sx={{ zIndex: 2000 }}\n        keepMounted\n        onClose={(e: MouseEvent) => handleClose(e)}\n        aria-describedby='alert-dialog-slide-description'\n      >\n        <DialogTitle> {t('labelInvestDualDipTitle')}</DialogTitle>\n        <IconButton\n          aria-label='close'\n          onClick={handleClose}\n          sx={{\n            position: 'absolute',\n            right: 8,\n            top: 8,\n          }}\n        >\n          <CloseIcon />\n        </IconButton>\n        <DialogContent>\n          <DialogContentText id='alert-dialog-slide-description'>\n            <Trans\n              i18nKey={'labelInvestDualDipGuid'}\n              tOptions={{\n                layer2: L1L2_NAME_DEFINED[network].layer2,\n                loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n                l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n              }}\n              components={{\n                p: (\n                  <Typography\n                    whiteSpace={'pre-line'}\n                    component={'span'}\n                    variant={'body1'}\n                    display={'block'}\n                    color={'textSecondary'}\n                    paddingY={1 / 2}\n                  />\n                ),\n                ol: <ol style={{ listStyle: 'decimal', paddingLeft: 24 }} />,\n                li: (\n                  <Typography\n                    whiteSpace={'pre-line'}\n                    component={'li'}\n                    display={'list-item'}\n                    variant={'body1'}\n                    color={'textSecondary'}\n                  />\n                ),\n                h5: (\n                  <Typography\n                    whiteSpace={'pre-line'}\n                    component={'h5'}\n                    variant={'h5'}\n                    display={'block'}\n                    color={'textPrimary'}\n                    paddingTop={2}\n                  />\n                ),\n              }}\n            >\n              <p>\n                Covered Gain is an investment strategy to sell digital assets at your Target Price\n                and earn interest while waiting.\n              </p>\n              <p>On the Settlement Date, there can be 2 scenarios:</p>\n              <ol>\n                <li>Market Price &gt; Target Price</li>\n                <li>Market Price ≤ Target Price</li>\n              </ol>\n              <h5>Market Price &gt; Target Price</h5>\n              <p>Your original investment and earned interest will be sold at the target price.</p>\n              <p>\n                This order is then closed regardless of whether \"Auto Reinvest\" is enabled or not.\n              </p>\n              <h5>Market Price ≤ Target Price</h5>\n              <p>Your original investment and earned interest won’t be sold.</p>\n              <p>\n                If you enable the “Auto Reinvest” feature, Loopring will automatically subscribe to\n                a suitable dual investment product based on the agreed terms until you either\n                successfully sell crypto at your desired price or disable the feature.\n              </p>\n              <h5>Auto Reinvest</h5>\n              <p>\n                When you enable the “Auto Reinvest” feature, Loopring will automatically reinvest\n                your funds into a new product with the same target price when the previous product\n                expires, continuing until you successfully sell your crypto at your Target Price. If\n                there isn’t an available product within 2 hours after the previous settlement, the\n                order will be automatically closed.\n              </p>\n              <p>Sell Price: the Target Price at which you want to sell your crypto.</p>\n              <p>\n                Longest Settlement Date: your acceptable investment period. If no suitable products\n                are available within this range, “Auto Reinvest” will not subscribe to any products\n                for you, even if it's enabled.\n              </p>\n            </Trans>\n          </DialogContentText>\n          <MuiFormControlLabel\n            control={\n              <Checkbox\n                checked={agree}\n                onChange={(_event: any, state: boolean) => {\n                  setAgree(state)\n                }}\n                checkedIcon={<CheckedIcon />}\n                icon={<CheckBoxIcon />}\n                color='default'\n              />\n            }\n            label={t('labelDualAgree')}\n          />\n        </DialogContent>\n\n        <DialogActions>\n          <Button\n            variant={'contained'}\n            size={'small'}\n            disabled={!agree}\n            onClick={(e) => {\n              handleClose(e as any, agree)\n            }}\n            color={'primary'}\n          >\n            {t('labelIKnow')}\n          </Button>\n        </DialogActions>\n      </Dialog>\n    )\n  },\n)\nexport const ConfirmInvestDualAutoRisk = withTranslation('common')(\n  ({\n    t,\n    open,\n    handleClose,\n  }: WithTranslation & {\n    open: boolean\n    handleClose: (event: any, isAgree?: boolean) => void\n  }) => {\n    const { defaultNetwork } = useSettings()\n    const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n    const [agree, setAgree] = React.useState(false)\n    return (\n      <Dialog\n        open={open}\n        sx={{ zIndex: 2000 }}\n        keepMounted\n        onClose={(e: MouseEvent) => handleClose(e)}\n        aria-describedby='alert-dialog-slide-description'\n      >\n        <DialogTitle> {t('labelInvestDualAutoTitle')}</DialogTitle>\n        <IconButton\n          aria-label='close'\n          onClick={handleClose}\n          sx={{\n            position: 'absolute',\n            right: 8,\n            top: 8,\n          }}\n        >\n          <CloseIcon />\n        </IconButton>\n        <DialogContent>\n          <DialogContentText id='alert-dialog-slide-description'>\n            <Trans\n              i18nKey={'labelInvestDualAutoCheck'}\n              tOptions={{\n                layer2: L1L2_NAME_DEFINED[network].layer2,\n                loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n                l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n              }}\n              components={{\n                p: (\n                  <Typography\n                    whiteSpace={'pre-line'}\n                    component={'span'}\n                    variant={'body1'}\n                    display={'block'}\n                    color={'textPrimary'}\n                    paddingY={1}\n                  />\n                ),\n              }}\n            >\n              <p>\n                Auto Reinvest will automatically reinvest your investment and earned interest into a\n                new term with the same Target Price once the previous term expires, continuing until\n                you successfully buy or sell crypto. If there isn’t an available product within 2\n                hours after the previous settlement, the order will be automatically closed and your\n                investment and earned interest will be unlocked.\n              </p>\n              <p>\n                Reinvest Target Price: The Target Price at which you want to buy or sell crypto.\n              </p>\n              <p>\n                Longest Settlement Date: The maximum duration available for selecting the settlement\n                period. Auto Reinvest will automatically match products with settlement periods that\n                do not exceed the Longest Settlement Date.\n              </p>\n            </Trans>\n          </DialogContentText>\n          <MuiFormControlLabel\n            control={\n              <Checkbox\n                checked={agree}\n                onChange={(_event: any, state: boolean) => {\n                  setAgree(state)\n                }}\n                checkedIcon={<CheckedIcon />}\n                icon={<CheckBoxIcon />}\n                color='default'\n              />\n            }\n            label={t('labelDualAgree')}\n          />\n        </DialogContent>\n\n        <DialogActions>\n          <Button\n            variant={'contained'}\n            size={'small'}\n            disabled={!agree}\n            onClick={(e) => {\n              handleClose(e as any, agree)\n            }}\n            color={'primary'}\n          >\n            {t('labelIKnow')}\n          </Button>\n        </DialogActions>\n      </Dialog>\n    )\n  },\n)\n\nexport const ConfirmInvestDualRisk = withTranslation('common')(\n  ({\n    t,\n    open,\n    USDCOnly,\n    handleClose,\n  }: WithTranslation & {\n    open: boolean\n    USDCOnly: boolean\n    handleClose: (event: any, isAgree?: DualInvestConfirmType | undefined) => void\n  }) => {\n    const { defaultNetwork } = useSettings()\n    const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n    const [{ agree1, agree2, agree3, agree4, agree5 }, setAgree] = React.useState({\n      agree1: false,\n      agree2: false,\n      agree3: false,\n      agree4: false,\n      agree5: false,\n    })\n    // const { language } = useSettings();\n\n    return (\n      <Dialog\n        open={open}\n        keepMounted\n        onClose={(e: MouseEvent) => handleClose(e, undefined)}\n        aria-describedby='alert-dialog-slide-description'\n      >\n        <DialogTitle> {t('labelDualRiskTitle')}</DialogTitle>\n        <IconButton\n          aria-label='close'\n          onClick={handleClose}\n          sx={{\n            position: 'absolute',\n            right: 8,\n            top: 8,\n          }}\n        >\n          <CloseIcon />\n        </IconButton>\n\n        {USDCOnly ? (\n          <DialogContent>\n            <DialogContentText id='alert-dialog-slide-description'>\n              <Trans\n                i18nKey={'labelInvestDualTutorialCheck4'}\n                tOptions={{\n                  layer2: L1L2_NAME_DEFINED[network].layer2,\n                  loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n                  l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                  loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                  l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                  l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                  ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                }}\n              >\n                <Typography\n                  whiteSpace={'pre-line'}\n                  component={'span'}\n                  variant={'body1'}\n                  display={'block'}\n                  color={'textPrimary'}\n                >\n                  Dual Investment offers you a chance to sell cryptocurrency high or buy\n                  cryptocurrency low at your desired price on your desired date. Once subscribed,\n                  users are not able to cancel or redeem the subscription until the Settlement\n                  Date.\\n You may be better off holding your cryptocurrency, and may be required to\n                  trade your cryptocurrency at a less favorable rate of exchange than the market\n                  rate on Settlement Date. Cryptocurrency trading is subject to high market risk.\n                  Please make your trades cautiously. There may be no recourse for any losses.\n                </Typography>\n              </Trans>\n            </DialogContentText>\n            <DialogContentText>\n              <Trans\n                i18nKey={'labelInvestDualTutorialContent2'}\n                tOptions={{\n                  layer2: L1L2_NAME_DEFINED[network].layer2,\n                  loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n                  loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                  l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                  l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                  ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                }}\n                components={{\n                  p: <Typography color={'textSecondary'} paddingY={1 / 2} />,\n                  h6: <Typography color={'textPrimary'} paddingY={1} />,\n                }}\n              >\n                <Typography\n                  whiteSpace={'pre-line'}\n                  component={'span'}\n                  variant={'body1'}\n                  display={'block'}\n                  color={'textPrimary'}\n                >\n                  When you enable the “Auto Reinvest” feature, Loopring will automatically reinvest\n                  your funds into a new product with the same target price when the previous product\n                  expires, continuing until you successfully buy crypto at your desired price. If\n                  there isn’t an available product within 2 hours after the previous settlement, the\n                  order will be automatically closed. Buy Price: the Target Price at which you want\n                  to buy crypto. Longest Settlement Date: your acceptable investment period. If no\n                  suitable products are available within this range, “Auto Reinvest” will not\n                  subscribe to any products for you, even if it's enabled.\n                </Typography>\n              </Trans>\n            </DialogContentText>\n            <MuiFormControlLabel\n              control={\n                <Checkbox\n                  checked={agree5}\n                  onChange={(_event: any, state: boolean) => {\n                    setAgree((_state) => ({\n                      ..._state,\n                      agree5: state,\n                    }))\n                  }}\n                  checkedIcon={<CheckedIcon />}\n                  icon={<CheckBoxIcon />}\n                  color='default'\n                />\n              }\n              label={t('labelInvestDualTutorialCheck5')}\n            />\n          </DialogContent>\n        ) : (\n          <DialogContent>\n            <DialogContentText id='alert-dialog-slide-description'>\n              <Trans\n                i18nKey={'labelInvestDualTutorialContent'}\n                tOptions={{\n                  layer2: L1L2_NAME_DEFINED[network].layer2,\n                  loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n                  loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                  l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                  l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                  ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                }}\n              >\n                <Typography\n                  whiteSpace={'pre-line'}\n                  component={'span'}\n                  variant={'body1'}\n                  display={'block'}\n                  color={'textPrimary'}\n                >\n                  Dual Investment offers you a chance to sell cryptocurrency high or buy\n                  cryptocurrency low at your desired price on your desired date. Once subscribed,\n                  users are not able to cancel or redeem the subscription until the Settlement\n                  Date.\\n You may be better off holding your cryptocurrency, and may be required to\n                  trade your cryptocurrency at a less favorable rate of exchange than the market\n                  rate on Settlement Date. Cryptocurrency trading is subject to high market risk.\n                  Please make your trades cautiously. There may be no recourse for any losses.\n                </Typography>\n              </Trans>\n            </DialogContentText>\n            {/* <DialogContentText marginTop={1/2} color={'var(--color-text-primary)'} variant={'h6'}> {t('labelDualAutoReinvest')}</DialogContentText> */}\n            <DialogContentText>\n              <Trans\n                i18nKey={'labelInvestDualTutorialContent2'}\n                tOptions={{\n                  layer2: L1L2_NAME_DEFINED[network].layer2,\n                  loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n                  loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                  l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                  l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                  ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                }}\n                components={{\n                  p: <Typography color={'textSecondary'} paddingY={1 / 2} />,\n                  h6: <Typography color={'textPrimary'} paddingY={1 / 2} />,\n                }}\n              >\n                <Typography\n                  whiteSpace={'pre-line'}\n                  component={'span'}\n                  variant={'body1'}\n                  display={'block'}\n                  color={'textPrimary'}\n                >\n                  When you enable the “Auto Reinvest” feature, Loopring will automatically reinvest\n                  your funds into a new product with the same target price when the previous product\n                  expires, continuing until you successfully buy crypto at your desired price. If\n                  there isn’t an available product within 2 hours after the previous settlement, the\n                  order will be automatically closed. Buy Price: the Target Price at which you want\n                  to buy crypto. Longest Settlement Date: your acceptable investment period. If no\n                  suitable products are available within this range, “Auto Reinvest” will not\n                  subscribe to any products for you, even if it's enabled.\n                </Typography>\n              </Trans>\n            </DialogContentText>\n            <MuiFormControlLabel\n              control={\n                <Checkbox\n                  checked={agree1}\n                  onChange={(_event: any, state: boolean) => {\n                    setAgree((_state) => ({\n                      ..._state,\n                      agree1: state,\n                    }))\n                  }}\n                  checkedIcon={<CheckedIcon />}\n                  icon={<CheckBoxIcon />}\n                  color='default'\n                />\n              }\n              label={t('labelInvestDualTutorialCheck1')}\n            />\n            <MuiFormControlLabel\n              control={\n                <Checkbox\n                  checked={agree2}\n                  onChange={(_event: any, state: boolean) => {\n                    setAgree((_state) => ({\n                      ..._state,\n                      agree2: state,\n                    }))\n                  }}\n                  checkedIcon={<CheckedIcon />}\n                  icon={<CheckBoxIcon />}\n                  color='default'\n                />\n              }\n              label={t('labelInvestDualTutorialCheck2')}\n            />\n            <MuiFormControlLabel\n              sx={{ marginTop: 0.5 }}\n              control={\n                <Checkbox\n                  checked={agree3}\n                  onChange={(_event: any, state: boolean) => {\n                    setAgree((_state) => ({\n                      ..._state,\n                      agree3: state,\n                    }))\n                  }}\n                  checkedIcon={<CheckedIcon />}\n                  icon={<CheckBoxIcon />}\n                  color='default'\n                />\n              }\n              label={t('labelInvestDualTutorialCheck3')}\n            />\n            <MuiFormControlLabel\n              sx={{ marginTop: 1 }}\n              control={\n                <Checkbox\n                  checked={agree4}\n                  onChange={(_event: any, state: boolean) => {\n                    setAgree((_state) => ({\n                      ..._state,\n                      agree4: state,\n                    }))\n                  }}\n                  checkedIcon={<CheckedIcon />}\n                  icon={<CheckBoxIcon />}\n                  color='default'\n                />\n              }\n              label={t('labelInvestDualTutorialCheck4')}\n            />\n            <MuiFormControlLabel\n              control={\n                <Checkbox\n                  checked={agree5}\n                  onChange={(_event: any, state: boolean) => {\n                    setAgree((_state) => ({\n                      ..._state,\n                      agree5: state,\n                    }))\n                  }}\n                  checkedIcon={<CheckedIcon />}\n                  icon={<CheckBoxIcon />}\n                  color='default'\n                />\n              }\n              label={t('labelInvestDualTutorialCheck5')}\n            />\n          </DialogContent>\n        )}\n\n        <DialogActions>\n          <Button\n            variant={'contained'}\n            size={'small'}\n            disabled={USDCOnly ? !agree5 : !agree1 || !agree2 || !agree3 || !agree4 || !agree5}\n            onClick={(e) => {\n              handleClose(\n                e as any,\n                USDCOnly ? DualInvestConfirmType.USDCOnly : DualInvestConfirmType.all,\n              )\n            }}\n            color={'primary'}\n          >\n            {t('labelIKnow')}\n          </Button>\n        </DialogActions>\n      </Dialog>\n    )\n  },\n)\nexport const ConfirmInvestLRCStakeRisk = withTranslation('common')(\n  ({\n    t,\n    open,\n    handleClose,\n    confirmationNeeded,\n  }: WithTranslation & {\n    open: boolean\n    confirmationNeeded: boolean\n    handleClose: (event: any, isAgree?: boolean) => void\n  }) => {\n    const { defaultNetwork } = useSettings()\n    const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n    const [agree, setAgree] = React.useState(false)\n    React.useEffect(() => {\n      if (!open) {\n        setAgree(false)\n      }\n    }, [open])\n    return (\n      <Dialog\n        open={open}\n        keepMounted\n        onClose={(e: MouseEvent) => handleClose(e)}\n        aria-describedby='alert-dialog-slide-description'\n      >\n        <DialogTitle> {t(`labelLRCStakingTitle`)}</DialogTitle>\n        <DialogContent>\n          <DialogContentText id='alert-dialog-slide-description'>\n            <Trans\n              i18nKey={`labelLRCStakingRisk`}\n              tOptions={{\n                layer2: L1L2_NAME_DEFINED[network].layer2,\n                loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n                loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n              }}\n              components={{\n                p: (\n                  <Typography\n                    whiteSpace={'pre-line'}\n                    component={'span'}\n                    variant={'body1'}\n                    display={'block'}\n                    marginBottom={1}\n                    color={'textSecondary'}\n                  />\n                ),\n              }}\n            >\n              <Typography\n                whiteSpace={'pre-line'}\n                component={'span'}\n                variant={'body1'}\n                display={'block'}\n                marginBottom={1}\n                color={'textSecondary'}\n              >\n                LRC staking is incentivized through an allocated portion of the Loopring protocol\n                fee; the exact percentage is determined by the Loopring DAO. The APY is updated\n                daily based on the allocated amount from previous day’s fee. Any LRC holder can\n                participate in LRC staking via L2 to accumulate daily rewards. The assets must be\n                staked for a minimum of 90 days to receive rewards.\n              </Typography>\n            </Trans>\n          </DialogContentText>\n          {confirmationNeeded && (\n            <MuiFormControlLabel\n              control={\n                <Checkbox\n                  checked={agree}\n                  onChange={(_event: any, state: boolean) => {\n                    setAgree(state)\n                  }}\n                  checkedIcon={<CheckedIcon />}\n                  icon={<CheckBoxIcon />}\n                  color='default'\n                />\n              }\n              label={t('labelLRCStakingAgree')}\n            />\n          )}\n        </DialogContent>\n        <DialogContent>\n          <DialogContentText id='alert-dialog-defiRisk2'>\n            <Trans\n              i18nKey={`labelLRCStakingRisk2`}\n              tOptions={{\n                layer2: L1L2_NAME_DEFINED[network].layer2,\n                loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n                loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n              }}\n            >\n              <Typography\n                whiteSpace={'pre-line'}\n                component={'span'}\n                variant={'body2'}\n                marginTop={2}\n                display={'block'}\n                color={'var(--color-text-third)'}\n              >\n                The staked LRC will be locked in Loopring L2, meaning it cannot be used for other\n                purposes. You may redeem your LRC at any time; however, doing so before the 90-day\n                minimum requirement will forfeit any accumulated reward.\n              </Typography>\n            </Trans>\n          </DialogContentText>\n        </DialogContent>\n        <DialogActions>\n          <Button\n            variant={'contained'}\n            size={'small'}\n            disabled={confirmationNeeded ? !agree : false}\n            onClick={(e) => {\n              handleClose(e as any, true)\n            }}\n            color={'primary'}\n          >\n            {t('labelIKnow')}\n          </Button>\n        </DialogActions>\n      </Dialog>\n    )\n  },\n)\n\nexport const ConfirmBtradeSwapRisk = withTranslation('common')(\n  ({\n    t,\n    open,\n    handleClose,\n  }: WithTranslation & {\n    open: boolean\n    handleClose: (event: any, isAgree?: boolean) => void\n  }) => {\n    const [agree, setAgree] = React.useState(false)\n    React.useEffect(() => {\n      if (!open) {\n        setAgree(false)\n      }\n    }, [open])\n    return (\n      <Dialog\n        open={open}\n        keepMounted\n        onClose={(e: MouseEvent) => handleClose(e)}\n        aria-describedby='alert-dialog-slide-description'\n      >\n        <DialogTitle> {t(`labelBtradeSwapTitleDes`)}</DialogTitle>\n        <DialogContent>\n          <DialogContentText id='alert-dialog-defiRisk2'>\n            <Trans\n              i18nKey={`labelBtradeSwapContentDes`}\n              components={{\n                p: (\n                  <Typography\n                    whiteSpace={'pre-line'}\n                    component={'span'}\n                    variant={'body1'}\n                    display={'block'}\n                    marginBottom={1}\n                    color={'textSecondary'}\n                  />\n                ),\n                h6: (\n                  <Typography\n                    component={'h6'}\n                    whiteSpace={'pre-line'}\n                    variant={'h5'}\n                    display={'block'}\n                    marginBottom={1}\n                    marginTop={1}\n                    fontWeight='600'\n                    color={'textPrimary'}\n                  />\n                ),\n                li: <li style={{ display: 'list', listStyle: 'inside' }} />,\n                ul: <ul style={{ display: 'initial' }} />,\n              }}\n            />\n          </DialogContentText>\n          <MuiFormControlLabel\n            control={\n              <Checkbox\n                checked={agree}\n                onChange={(_event: any, state: boolean) => {\n                  setAgree(state)\n                }}\n                checkedIcon={<CheckedIcon />}\n                icon={<CheckBoxIcon />}\n                color='default'\n              />\n            }\n            label={t('labelLRCStakingAgree')}\n          />\n        </DialogContent>\n        <DialogActions>\n          <Button\n            variant={'contained'}\n            size={'small'}\n            disabled={!agree}\n            onClick={(e) => {\n              handleClose(e as any, true)\n            }}\n            color={'primary'}\n          >\n            {t('labelIKnow')}\n          </Button>\n        </DialogActions>\n      </Dialog>\n    )\n  },\n)\n\nexport const ConfirmStopLimitRisk = withTranslation('common')(\n  ({\n    t,\n    open,\n    handleClose,\n    baseSymbol,\n    quoteSymbol,\n    tradeType,\n    limitPrice,\n    stopPrice,\n    baseValue,\n    quoteValue,\n    stopSide,\n    onSubmit,\n  }: WithTranslation & {\n    open: boolean\n    handleClose: (event: any) => void\n  } & Partial<{\n      baseSymbol: string\n      quoteSymbol: string\n      tradeType: TradeProType\n      baseValue: string | number\n      quoteValue: string | number\n      limitPrice: string\n      stopPrice: string\n      stopSide: sdk.STOP_SIDE\n      onSubmit: (event: any) => void\n    }>) => {\n    return (\n      <Dialog\n        open={open}\n        keepMounted\n        onClose={(e: MouseEvent) => handleClose(e)}\n        aria-describedby='alert-dialog-slide-description'\n        sx={{ width: 'var(--swap-box-width)' }}\n      >\n        <DialogTitle>\n          {t(`labelStopLimit`, {\n            symbol1: baseSymbol,\n            tradeType: tradeType ? tradeType[0].toUpperCase() + tradeType.substring(1) : '', //tradeType,\n          })}\n        </DialogTitle>\n        <DialogContent>\n          <DialogContentText\n            id='alert-dialog-stopLimit'\n            sx={{ display: 'flex', flexDirection: 'column' }}\n          >\n            <Typography\n              component={'span'}\n              display={'inline-flex'}\n              justifyContent={'space-between'}\n              marginTop={2}\n            >\n              <Typography\n                variant={'body1'}\n                component={'span'}\n                color={'var(--color-text-secondary)'}\n              >\n                {baseSymbol + ' / ' + quoteSymbol}\n              </Typography>\n              <Typography\n                variant={'body1'}\n                component={'span'}\n                color={\n                  tradeType == TradeProType.sell ? 'var(--color-error)' : 'var(--color-success)'\n                }\n                // color={\"var(--color-text-primary)\"}\n              >\n                {t('labelStopLimitType', {\n                  tradeType: tradeType ? tradeType[0].toUpperCase() + tradeType.substring(1) : '',\n                })}\n              </Typography>\n            </Typography>\n            <Typography\n              component={'span'}\n              display={'inline-flex'}\n              justifyContent={'space-between'}\n              marginTop={2}\n            >\n              <Typography\n                variant={'body1'}\n                component={'span'}\n                color={'var(--color-text-secondary)'}\n              >\n                {t('labelStopLimitStopPrice')}\n              </Typography>\n              <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n                {stopPrice + ' ' + quoteSymbol}\n              </Typography>\n            </Typography>\n            <Typography\n              component={'span'}\n              display={'inline-flex'}\n              justifyContent={'space-between'}\n              marginTop={2}\n            >\n              <Typography\n                variant={'body1'}\n                component={'span'}\n                color={'var(--color-text-secondary)'}\n              >\n                {t('labelStopLimitPriceLimitPrice')}\n              </Typography>\n              <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n                {limitPrice + ' ' + quoteSymbol}\n              </Typography>\n            </Typography>\n            <Typography\n              component={'span'}\n              display={'inline-flex'}\n              justifyContent={'space-between'}\n              marginTop={2}\n            >\n              <Typography\n                variant={'body1'}\n                component={'span'}\n                color={'var(--color-text-secondary)'}\n              >\n                {t('labelStopLimitAmount')}\n              </Typography>\n              <Typography variant={'body1'} component={'span'} color={'var(--color-text-primary)'}>\n                {baseValue + ' ' + baseSymbol}\n              </Typography>\n            </Typography>\n          </DialogContentText>\n          <DialogContentText id='alert-dialog-stopLimit'>\n            <Trans\n              i18nKey={`labelStopLimitDes`}\n              tOptions={{\n                value1: baseValue,\n                value2: quoteValue,\n                symbol2: quoteSymbol,\n                symbol1: baseSymbol,\n                stopPrice,\n                limitPrice,\n                tradeType,\n                from:\n                  stopSide == sdk.STOP_SIDE.GREAT_THAN_AND_EQUAL\n                    ? t('labelStopLimitFromGoesUp')\n                    : t('labelStopLimitFromDropsDown'),\n                behavior:\n                  stopSide == sdk.STOP_SIDE.GREAT_THAN_AND_EQUAL\n                    ? t('labelStopLimitBehaviorAbove')\n                    : t('labelStopLimitBehaviorBelow'),\n              }}\n              components={{\n                p: (\n                  <Typography\n                    whiteSpace={'pre-line'}\n                    component={'span'}\n                    variant={'body1'}\n                    display={'block'}\n                    marginY={1}\n                    color={'textSecondary'}\n                    sx={{ background: 'var(--field-opacity)' }}\n                    borderRadius={1 / 2}\n                    padding={1}\n                  />\n                ),\n              }}\n            >\n              <p>\n                If the last price goes up to or above value Symbol2 , and order to tradeType value2\n                Symbol1 at a price of price Symbol2 will be placed.\n              </p>\n            </Trans>\n          </DialogContentText>\n        </DialogContent>\n\n        <DialogActions>\n          <Button variant={'outlined'} size={'medium'} onClick={(e) => handleClose(e as any)}>\n            {t('labelStopLimitCancel')}\n          </Button>\n          <Button\n            variant={'contained'}\n            size={'small'}\n            // fullWidth={true}\n            onClick={(e) => {\n              // handleClose(e as any);\n              if (typeof onSubmit === 'function') {\n                onSubmit(e)\n              }\n            }}\n            color={'primary'}\n          >\n            {t('labelStopLimitConfirm')}\n          </Button>\n        </DialogActions>\n      </Dialog>\n    )\n  },\n)\nexport const ConfirmVaultRisk = withTranslation('common')(\n  ({\n    t,\n    open,\n    handleClose,\n  }: WithTranslation & {\n    open: boolean\n    handleClose: (event: any, isAgree?: boolean) => void\n  }) => {\n    const [agree, setAgree] = React.useState(false)\n    React.useEffect(() => {\n      if (!open) {\n        setAgree(false)\n      }\n    }, [open])\n    return (\n      <Dialog\n        open={open}\n        keepMounted\n        onClose={(e: MouseEvent) => handleClose(e)}\n        aria-describedby='alert-dialog-slide-description'\n      >\n        <DialogTitle> {t(`labelVaultTitleRisk`)}</DialogTitle>\n        <DialogContent>\n          <DialogContentText id='alert-dialog-defiRisk2'>\n            <Trans\n              i18nKey={`labelVaultRiskDes`}\n              components={{\n                p: (\n                  <Typography\n                    whiteSpace={'pre-line'}\n                    component={'span'}\n                    variant={'body1'}\n                    display={'block'}\n                    marginBottom={1}\n                    color={'textSecondary'}\n                  />\n                ),\n                h6: (\n                  <Typography\n                    component={'h6'}\n                    whiteSpace={'pre-line'}\n                    variant={'h5'}\n                    display={'block'}\n                    marginBottom={1}\n                    marginTop={1}\n                    fontWeight='600'\n                    color={'textPrimary'}\n                  />\n                ),\n                li: <li style={{ display: 'list', listStyle: 'disc' }} />,\n                ul: <ol style={{ listStyle: 'decimal', paddingLeft: 12 }} />,\n              }}\n            />\n          </DialogContentText>\n          <MuiFormControlLabel\n            control={\n              <Checkbox\n                checked={agree}\n                onChange={(_event: any, state: boolean) => {\n                  setAgree(state)\n                }}\n                checkedIcon={<CheckedIcon />}\n                icon={<CheckBoxIcon />}\n                color='default'\n              />\n            }\n            label={t('labelLRCStakingAgree')}\n          />\n        </DialogContent>\n        <DialogActions>\n          <Button\n            variant={'contained'}\n            size={'small'}\n            disabled={!agree}\n            onClick={(e) => {\n              handleClose(e as any, true)\n            }}\n            color={'primary'}\n          >\n            {t('labelIKnow')}\n          </Button>\n        </DialogActions>\n      </Dialog>\n    )\n  },\n)\n\nexport const VaultSwapCancel = withTranslation('common', {\n  withRef: true,\n})(\n  ({\n    t,\n    open,\n    handleClose,\n  }: WithTranslation & {\n    open: boolean\n    handleClose: (event: any, isAgree?: boolean) => void\n  }) => {\n    return (\n      <DialogStyle\n        open={open}\n        keepMounted\n        onClose={(e: MouseEvent) => handleClose(e)}\n        aria-describedby='alert-dialog-slide-description'\n      >\n        <DialogTitle> {t('labelInformation')}</DialogTitle>\n        <DialogContent>\n          <DialogContentText id='alert-dialog-slide-description'>\n            <Trans i18nKey={'labelVaultSwapCancel'}>\n              You are borrowing tokens.\\n Are you sure you want to change the token pair or exit the\n              trade?\n            </Trans>\n          </DialogContentText>\n        </DialogContent>\n        <DialogActions>\n          <DialogActions>\n            <Button variant={'outlined'} size={'medium'} onClick={(e) => handleClose(e as any)}>\n              {t('labelNo')}\n            </Button>\n            <Button\n              variant={'contained'}\n              size={'small'}\n              onClick={(e) => {\n                handleClose(e as any, true)\n              }}\n              color={'primary'}\n            >\n              {t('labelYes')}\n            </Button>\n          </DialogActions>\n        </DialogActions>\n      </DialogStyle>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/tool/FeeList.tsx",
    "content": "import { MuToggleButtonGroupStyle } from '../../../basic-lib'\nimport { ToggleButton } from '@mui/material'\nimport { FeeInfo } from '@loopring-web/common-resources'\n\nexport const FeeToggle = <C extends FeeInfo>({\n  chargeFeeTokenList,\n  handleToggleChange,\n  feeInfo,\n  disableNoToken = false,\n}: {\n  chargeFeeTokenList: Array<C>\n  handleToggleChange: (value: C) => void\n  feeInfo: C\n  disableNoToken?: boolean\n}) => {\n  return (\n    <MuToggleButtonGroupStyle\n      size={'small'}\n      value={chargeFeeTokenList.findIndex((ele) => feeInfo?.belong === ele.belong)}\n      exclusive\n      onChange={(_e, value: number) => {\n        handleToggleChange(chargeFeeTokenList[value])\n      }}\n    >\n      {chargeFeeTokenList?.map((feeInfo, index) => (\n        <ToggleButton\n          key={feeInfo.belong + index}\n          value={index}\n          aria-label={feeInfo.belong}\n          disabled={disableNoToken && !feeInfo.hasToken}\n        >\n          {feeInfo.belong}\n        </ToggleButton>\n      ))}\n    </MuToggleButtonGroupStyle>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/tool/Property.tsx",
    "content": "import { AddIcon, DeleteIcon, MetaProperty, PROPERTY_LIMIT } from '@loopring-web/common-resources'\nimport { Trans, useTranslation } from 'react-i18next'\nimport { Button, TextField } from '../../../basic-lib'\nimport { Box, Grid, IconButton, Typography } from '@mui/material'\nimport React, { ForwardedRef } from 'react'\n\nexport const Properties = ({\n  properties = [],\n  handleChange,\n  disabled = false,\n}: {\n  disabled?: boolean\n  properties: MetaProperty[]\n  handleChange: (properties: Array<Partial<MetaProperty>>) => void\n}) => {\n  const { t } = useTranslation()\n  const _handleChange = React.useCallback(\n    (_property: Partial<MetaProperty>, index: number) => {\n      let _properties = [...properties]\n      _properties[index] = { ...(_properties[index] ?? {}), ..._property }\n      handleChange(_properties)\n      // properties.filter((item,_index) => index!== )\n      // properties[index]\n    },\n    [properties, handleChange],\n  )\n  const onDelete = React.useCallback(\n    (index: number) => {\n      let _properties = [...properties]\n      if (_properties.length > 1) {\n        handleChange(_properties.filter((_item, _index) => _index !== index))\n      }\n    },\n    [handleChange, properties],\n  )\n  const addItem = React.useCallback(() => {\n    if (properties.length < PROPERTY_LIMIT) {\n      let _properties = [...properties, { key: '', value: '' }]\n      handleChange(_properties)\n    }\n  }, [handleChange, properties])\n  React.useEffect(() => {\n    if (!properties.length) {\n      addItem()\n    }\n  }, [])\n  return (\n    <Box>\n      {properties.map((property, index) => (\n        <Grid container key={index} spacing={2} marginBottom={1.5} alignItems={'center'}>\n          <Property\n            disabled={disabled}\n            property={property}\n            index={index}\n            handleChange={_handleChange}\n            onDelete={onDelete}\n          />\n        </Grid>\n      ))}\n      {properties.length < PROPERTY_LIMIT && (\n        <Box paddingTop={1}>\n          <Button\n            startIcon={<AddIcon />}\n            size={'small'}\n            disabled={disabled}\n            variant={'outlined'}\n            // variant={\"contained\"}\n            onClick={addItem}\n            title={t('labelPropertyAdd')}\n          >\n            {t('labelPropertyAdd')}\n          </Button>\n        </Box>\n      )}\n    </Box>\n  )\n}\nexport const Property = React.memo(\n  React.forwardRef(\n    (\n      {\n        property,\n        index,\n        handleChange,\n        onDelete,\n        disabled = false,\n      }: {\n        disabled?: boolean\n        property: MetaProperty\n        index: number\n        handleChange: (property: Partial<MetaProperty>, index: number) => void\n        onDelete: (index: number) => void\n      },\n      ref: ForwardedRef<any>,\n    ) => {\n      // const [,] = React.useState<Partial<MetaProperty>>();\n      const _handleChange = React.useCallback(\n        (_property: Partial<MetaProperty>) => {\n          handleChange({ ...property, ..._property }, index)\n        },\n        [handleChange, index, property],\n      )\n\n      return (\n        <>\n          <Grid item xs={5} ref={ref}>\n            <TextField\n              disabled={disabled}\n              value={property.key}\n              inputProps={{ maxLength: 10 }}\n              fullWidth\n              label={<Trans i18nKey={'labelMintPropertyKey'}>key</Trans>}\n              type={'text'}\n              onChange={(e) => _handleChange({ key: e.target.value })}\n            />\n          </Grid>\n          <Grid item xs={6}>\n            <TextField\n              disabled={disabled}\n              value={property.value}\n              inputProps={{ maxLength: 20 }}\n              fullWidth\n              label={<Trans i18nKey={'labelMintPropertyValue'}>value</Trans>}\n              type={'text'}\n              onChange={(e) => _handleChange({ value: e.target.value })}\n            />\n          </Grid>\n          <Grid item xs={1} display={'flex'} alignItems={'center'} justifyContent={'center'}>\n            <Typography color={'var(--color-button-icon)'}>\n              <IconButton\n                sx={{ marginTop: 3 }}\n                edge={'end'}\n                size={'large'}\n                disabled={disabled}\n                // disabled={properties.length === 1 ? true : false}\n                onClick={() => onDelete(index)}\n              >\n                <DeleteIcon />\n              </IconButton>\n            </Typography>\n          </Grid>\n        </>\n      )\n    },\n  ),\n)\n// export const PropertyReview = React.memo(\n//   React.forwardRef(\n//     ({\n//       property,\n//       index,\n//       handleChange,\n//       onDelete,\n//     }: {\n//       property: MetaProperty;\n//       index: number;\n//       handleChange: (property: Partial<MetaProperty>, index: number) => void;\n//       onDelete: (index: number) => void;\n//     }) => {\n//       // const [,] = React.useState<Partial<MetaProperty>>();\n//       const _handleChange = React.useCallback(\n//         (_property: Partial<MetaProperty>) => {\n//           handleChange({ ...property, ..._property }, index);\n//         },\n//         [handleChange, index, property]\n//       );\n//\n//       return (\n//         <>\n//           <Grid item xs={5}>\n//             <TextField\n//               value={property.key}\n//               fullWidth\n//               label={<Trans i18nKey={\"labelMintPropertyKey\"}>key</Trans>}\n//               type={\"text\"}\n//               onChange={(e) => _handleChange({ key: e.target.value })}\n//             />\n//           </Grid>\n//           <Grid item xs={6}>\n//             <TextField\n//               value={property.value}\n//               fullWidth\n//               label={<Trans i18nKey={\"labelMintPropertyValue\"}>value</Trans>}\n//               type={\"text\"}\n//               onChange={(e) => _handleChange({ value: e.target.value })}\n//             />\n//           </Grid>\n//           <Grid\n//             item\n//             xs={1}\n//             display={\"flex\"}\n//             alignItems={\"center\"}\n//             justifyContent={\"center\"}\n//           >\n//             <IconButton\n//               sx={{ marginTop: 3 }}\n//               edge={\"end\"}\n//               // disabled={properties.length === 1 ? true : false}\n//               onClick={() => onDelete(index)}\n//             >\n//               <DeleteIcon color={\"error\"} />\n//             </IconButton>\n//           </Grid>\n//         </>\n//       );\n//     }\n//   )\n// );\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/tool/Refresh.tsx",
    "content": "import { CountDownStyled } from '../Styled'\nimport { Box, Typography } from '@mui/material'\nimport React from 'react'\nimport { globalSetup, refreshTime } from '@loopring-web/common-resources'\nimport * as _ from 'lodash'\nimport { useTheme } from '@emotion/react'\n\n// @ts-ignore\nexport const CountDownIcon = React.memo(\n  React.forwardRef(\n    (\n      { onRefreshData, wait = globalSetup.wait, countDownSeconds }: { wait?: number; onRefreshData?: () => void, countDownSeconds?: number },\n      ref,\n    ) => {\n      const countDownRef = React.useRef<any>()\n      // React.createRef\n      const [refreshCount, setRefreshCount] = React.useState(0)\n      const nodeTimer = React.useRef<NodeJS.Timeout | -1>(-1)\n      const logoTimer = React.useRef<NodeJS.Timeout | -1>(-1)\n      React.useEffect(() => {\n        if (refreshCount === 0 && onRefreshData) {\n          onRefreshData()\n        }\n      }, [refreshCount])\n      // React.useEffect(()=>{\n      //\n      // },[shouldRefresh])\n\n      const startCountDown = React.useCallback(() => {\n        //@ts-ignore\n        if (countDownRef && countDownRef.current) {\n          //@ts-ignore\n          countDownRef.current?.classList.add('countdown')\n          //@ts-ignore\n          countDownRef.current?.classList?.remove('logo')\n          // setRefreshCount(refreshTime-1);\n          if (nodeTimer.current !== -1) {\n            clearInterval(nodeTimer.current as NodeJS.Timeout)\n          }\n          nodeTimer.current = setInterval(decreaseNum, 1000)\n        }\n      }, [countDownRef, nodeTimer])\n      const refresh = React.useCallback(\n        _.debounce(() => {\n          //@ts-ignore\n          if (countDownRef && countDownRef.current) {\n            // setRefreshCount(0)\n            if (nodeTimer.current !== -1) {\n              clearInterval(nodeTimer.current as NodeJS.Timeout)\n            }\n            if (logoTimer.current !== -1) {\n              clearTimeout(logoTimer.current as NodeJS.Timeout)\n            }\n            //@ts-ignore\n            countDownRef.current?.classList?.remove('countdown')\n            //@ts-ignore\n            countDownRef.current?.classList?.add('logo')\n            setRefreshCount(0)\n            logoTimer.current = setTimeout(() => {\n              startCountDown()\n            }, 1000 - wait)\n          }\n        }, wait),\n        [],\n      )\n\n      const decreaseNum = React.useCallback(\n        () =>\n          setRefreshCount((prev) => {\n            if (prev > 1) {\n              return prev - 1\n            } else if (prev == 1) {\n              //@ts-ignore\n              countDownRef?.current?.classList?.remove('countdown')\n              //@ts-ignore\n              countDownRef?.current?.classList?.add('logo')\n\n              return 0\n            } else {\n              //@ts-ignore\n              countDownRef?.current?.classList?.add('countdown')\n              //@ts-ignore\n              countDownRef?.current?.classList?.remove('logo')\n              return refreshTime - 1\n            }\n          }),\n        [setRefreshCount, countDownRef, refreshTime],\n      )\n\n      const cleanSubscribe = React.useCallback(() => {\n        clearInterval(nodeTimer.current as NodeJS.Timeout)\n        clearTimeout(logoTimer.current as NodeJS.Timeout)\n      }, [nodeTimer, logoTimer])\n      React.useEffect(() => {\n        // _refresh();\n        return cleanSubscribe\n      }, [])\n      const theme = useTheme()\n      return (\n        <Box ref={ref}>\n          <CountDownStyled\n            ref={countDownRef}\n            component={'button'}\n            className={'clock-loading outlined logo'}\n            onClick={refresh}\n            color={theme.colorBase.logo}\n            countDownSeconds={countDownSeconds}\n          >\n            <Typography component={'span'} className={'text-count'}></Typography>\n            <Box className={'circle'} />\n          </CountDownStyled>\n        </Box>\n      )\n    },\n  ),\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/tool/SlippagePanel.tsx",
    "content": "import { TGItemJSXInterface, ToggleButtonGroup } from '../../../basic-lib'\nimport React from 'react'\nimport CurrencyInput from 'react-currency-input-field'\nimport { globalSetup, myLog } from '@loopring-web/common-resources'\nimport styled from '@emotion/styled'\nimport { Box, FormHelperText, InputAdornment } from '@mui/material'\nimport { TFunction } from 'react-i18next'\nimport { useFocusRef } from '../../../basic-lib/form/hooks'\nimport { useSettings } from '../../../../stores'\n\nconst Styled = styled(Box)`\n  .MuiFormHelperText-root {\n    font-size: ${({ theme }) => theme.fontDefault.body2};\n    color: var(--color-error);\n  }\n  .MuiToggleButtonGroup-root {\n    .MuiToggleButtonGroup-grouped:first-of-type {\n      margin-left: -1px;\n    }\n    display: flex;\n    flex: 1;\n    flex-wrap: wrap;\n\n    justify-content: flex-start;\n    align-content: space-between;\n  }\n`\nconst suffix = '%'\n\nconst InputStyled = styled(CurrencyInput)`\n  position: relative;\n  color: var(--color-text-primary);\n\n  ::placeholder {\n    color: var(--color-placeholder);\n  }\n  height: 2.4rem;\n  width: 92px; \n  padding: .3rem .3rem .3rem .8rem;\n  background: var(--color-box);\n  ${({ theme }) => theme.border.defaultFrame({ d_R: 1 / 2, c_key: 'var(--color-border)' })};\n  text-align: left;\n  min-width: 0;\n  padding-right: 2rem;\n\n  .MuiButtonBase-root & {\n  }\n\n  :focus {\n    outline: 0;\n    border-color: transparent;\n  }\n\n}\n\n` as typeof CurrencyInput\nconst CUSTOMER_SLIPPAGE_NAME = 'customerSlippage'\nexport const SlippagePanel = ({\n  slippageList,\n  slippage,\n  wait = globalSetup.wait,\n  handleChange,\n  max = 100,\n  alertMax = 5,\n  ...rest\n}: { t: TFunction } & {\n  slippageList: Array<number | string>\n  slippage: number | string\n  wait?: number\n  max?: number\n  alertMax?: number\n  handleChange: (newValue: any, customValue: any) => void\n}) => {\n  let { slippage: _slippage } = useSettings()\n  const [customSlippage, setCustomSlippage] = React.useState<string | number | 'N'>(_slippage)\n  const [showAlert, setShowAlert] = React.useState<boolean>(\n    _slippage !== 'N' && _slippage > alertMax,\n  )\n  // const [cValue, setCValue] = React.useState<number | 'N'>(_slippage);\n  const inputEle = useFocusRef({\n    shouldFocusOn: false,\n    value: _slippage,\n  })\n  const [value, setValue] = React.useState(slippage)\n  const _handleChange = (event: React.MouseEvent<HTMLElement> | any, newValue: number | string) => {\n    if (event.target !== inputEle.current && newValue !== undefined) {\n      if (newValue && newValue !== 'N') {\n        setValue(newValue)\n        handleChange(newValue, !slippageList.includes(customSlippage) ? customSlippage : undefined)\n      }\n    } else if (event.target?.name === CUSTOMER_SLIPPAGE_NAME && event.type === 'change') {\n      var _value = event.target?.value ?? ''\n      _value = _value.replace(suffix, '')\n      if (Number(_value) < max) {\n        setValue(_value)\n        setCustomSlippage(_value)\n        if (_value >= alertMax) {\n          setShowAlert(true)\n        } else {\n          setShowAlert(false)\n        }\n      } else {\n        setShowAlert(true)\n        setValue(max)\n        setCustomSlippage(max - 1)\n      }\n    } else {\n    }\n    event.preventDefault()\n  }\n  const handleOnBlur = React.useCallback(() => {\n    try {\n      if (customSlippage !== 'N' && value !== 'N') {\n        handleChange(value, !slippageList.includes(customSlippage) ? customSlippage : undefined)\n      }\n    } catch (e) {\n      myLog('ignore handleOnBlur', e)\n    }\n  }, [value, customSlippage])\n\n  const toggleData = React.useMemo(\n    () =>\n      slippageList.reduce((pre, value, index) => {\n        let item: TGItemJSXInterface\n        if (RegExp('slippage:').test(value.toString())) {\n          item = {\n            value: customSlippage,\n            JSX: (\n              <Box\n                position={'relative'}\n                className={'MuiInputBase-root'}\n                display={'flex'}\n                flexDirection={'row'}\n              >\n                <InputStyled\n                  className={'MuiInputBase-sizeSmall MuiInputBase-root '}\n                  ref={inputEle}\n                  name={CUSTOMER_SLIPPAGE_NAME}\n                  allowDecimals={true}\n                  decimalsLimit={2}\n                  decimalSeparator='.'\n                  groupSeparator=','\n                  placeholder={rest.t('labelCustomer')}\n                  onChange={_handleChange as any}\n                  onMouseOut={(_e) => {\n                    handleOnBlur()\n                  }}\n                  onBlur={() => {\n                    handleOnBlur()\n                  }}\n                  defaultValue={customSlippage === 'N' ? '' : customSlippage}\n                  maxLength={5}\n                  autoComplete={'off'}\n                  // suffix={suffix}\n                />\n                <InputAdornment\n                  style={{\n                    zIndex: 99,\n                    position: 'absolute',\n                    right: 8,\n                    top: '50%',\n                    transform: 'translateY(-50%)',\n                    height: '100%',\n                    maxHeight: 'auto',\n                  }}\n                  position={'end'}\n                >\n                  {suffix}\n                </InputAdornment>\n              </Box>\n            ),\n            notWrap: true,\n            key: 'custom' + '-' + index,\n          }\n        } else {\n          item = {\n            value: value,\n            JSX: <span>{value}%</span>,\n            tlabel: value + '%',\n            key: value + '-' + index,\n          }\n        }\n\n        pre.push(item)\n        return pre\n      }, [] as TGItemJSXInterface[]),\n    [customSlippage, _handleChange],\n  )\n\n  return (\n    <Styled\n      className={'MuiPaper-elevation2'}\n      flexDirection={'column'}\n      height={'var(--slippage-pop-height)'}\n      width={'var(--slippage-pop-width)'}\n      padding={2}\n      display={'flex'}\n    >\n      <ToggleButtonGroup\n        className={'slippage'}\n        exclusive\n        {...{ ...rest, tgItemJSXs: toggleData, value: value, size: 'small' }}\n        onChange={_handleChange}\n      />\n\n      {showAlert && <FormHelperText>{rest.t('labelSlippageAlert')}</FormHelperText>}\n    </Styled>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/tool/ToolBarItems.tsx",
    "content": "import { Box, Grid, Step, StepLabel, Stepper } from '@mui/material'\nimport { BackIcon, DropDownIcon, TradeBtnStatus } from '@loopring-web/common-resources'\nimport { SwitchData } from '../../Interface'\nimport { IconButtonStyled } from '../Styled'\nimport { useTranslation } from 'react-i18next'\nimport { useSettings } from '../../../../stores'\nimport { BtnInfo, Button } from '../../../index'\nimport styled from '@emotion/styled'\nimport React from 'react'\n\nexport const ToolBarItemBack = <T extends any>({\n  onChangeEvent,\n  tradeData,\n}: {\n  tradeData: T\n  onChangeEvent: (index: 0 | 1, data: SwitchData<T>) => Promise<void> | void\n}) => {\n  return (\n    <Grid container justifyContent={'flex-start'}>\n      <IconButtonStyled\n        edge='start'\n        sx={{ transform: 'rotate(90deg)', transformOrigin: '50%' }}\n        className={'switch'}\n        color='inherit'\n        onClick={() => {\n          onChangeEvent(0, { tradeData, to: 'button' })\n        }}\n        aria-label='to Professional'\n      >\n        <DropDownIcon />\n      </IconButtonStyled>\n    </Grid>\n  )\n}\n\nconst BoxStyle = styled(Box)`\n  .MuiSvgIcon-root.MuiSvgIcon-fontSizeMedium {\n    height: var(--btn-icon-size-large);\n    width: var(--btn-icon-size-large);\n\n    .MuiStepIcon-text {\n      font-size: ${({ theme }) => theme.fontDefault.body1};\n      fill: var(--color-text-button);\n    }\n  }\n\n  .MuiStepConnector-root.Mui-active .MuiStepConnector-line {\n    border-color: var(--color-primary);\n  }\n` as typeof Grid\n\nexport function HorizontalLabelPositionBelowStepper({\n  activeStep,\n  steps,\n}: {\n  activeStep: number\n  steps: string[]\n}) {\n  const { t } = useTranslation('common')\n  const { isMobile } = useSettings()\n  return (\n    <>\n      <BoxStyle sx={{ width: '100%' }} marginTop={isMobile ? 3 : 0}>\n        <Stepper activeStep={activeStep} alternativeLabel>\n          {steps.map((label) => (\n            <Step key={label}>\n              <StepLabel>{t(label)}</StepLabel>\n            </Step>\n          ))}\n        </Stepper>\n      </BoxStyle>\n    </>\n  )\n}\n\nexport const BtnMain = React.memo(\n  ({\n    defaultLabel = 'labelMintNext',\n    btnInfo,\n    disabled,\n    onClick,\n    btnStatus,\n    fullWidth,\n  }: {\n    defaultLabel?: string\n    btnInfo?: BtnInfo\n    disabled: () => boolean\n    onClick: () => void\n    fullWidth?: boolean\n    btnStatus?: keyof typeof TradeBtnStatus\n  }) => {\n    const { t } = useTranslation()\n    return (\n      <Button\n        variant={'contained'}\n        size={'medium'}\n        color={'primary'}\n        fullWidth={fullWidth}\n        className={'step'}\n        endIcon={<BackIcon fontSize={'small'} sx={{ transform: 'rotate(180deg)' }} />}\n        loading={!disabled() && btnStatus === TradeBtnStatus.LOADING ? 'true' : 'false'}\n        disabled={disabled() || btnStatus === TradeBtnStatus.LOADING}\n        onClick={onClick}\n      >\n        {btnInfo ? t(btnInfo.label, btnInfo.params) : t(defaultLabel)}\n      </Button>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/tool/TradeMenuList.tsx",
    "content": "import { CoinInfo, CoinKey, IBData } from '@loopring-web/common-resources'\nimport { WithTranslation } from 'react-i18next'\nimport React from 'react'\nimport { CoinMenu, InputSelect, InputSelectProps } from '../../../basic-lib'\nimport { Box, Link, Typography } from '@mui/material'\nimport { TradeMenuListProps } from '../Interface'\nimport { useTheme } from '@emotion/react'\n\nexport const TradeMenuList = <T extends IBData<I>, I>({\n  nonZero,\n  sorted,\n  t,\n  onChangeEvent,\n  walletMap,\n  selected,\n  tradeData,\n  coinMap,\n  _height,\n  tokenType,\n  className,\n  hasCancel = true,\n  filterWithBorrowed,\n  ...rest\n}: TradeMenuListProps<T, I> & WithTranslation) => {\n  const ref = React.useRef<any>(null)\n  const inputSelectProps: InputSelectProps<I> = {\n    placeholder: 'tokenSearchCoin',\n    focusOnInput: true,\n    allowScroll: true,\n    selected: '',\n    panelRender: () => <></>,\n  }\n  const theme = useTheme()\n  const backElement = React.useMemo(\n    () => (\n      <Typography fontSize={'body1'} color='textPrimary'>\n        <Link\n          style={{ color: 'var(--color-text-primary)', textAlign: 'right' }}\n          onClick={() => {\n            onChangeEvent(0, { tradeData, to: 'button' })\n          }}\n        >\n          {t('labelCancel')}\n        </Link>\n      </Typography>\n    ),\n    [onChangeEvent, tradeData],\n  )\n  const filterBy = (coinInfo: CoinInfo<I>, filterString: string) => {\n    return filterString && filterString.length\n      ? RegExp(filterString, 'i').test(coinInfo.simpleName as string)\n      : true\n  }\n\n  const panelRender = ({ selected, value }: any) => {\n    return (\n      <CoinMenu\n        className={className}\n        tokenType={tokenType}\n        height={\n          _height\n            ? typeof _height === 'number'\n              ? ` calc(${_height + 'px'}  - 2 * var(--toolbar-row-padding) - ${theme.unit * 3}px ) `\n              : ` calc(${_height}  - 2 * var(--toolbar-row-padding) - ${theme.unit * 3}px )`\n            : '460px'\n        }\n        {...{\n          coinMap: coinMap, //swapData.type === 'sell' ? tradeCalcData?.sellCoinInfoMap : tradeCalcData?.buyCoinInfoMap as any,\n          filterBy,\n          nonZero,\n          sorted,\n          // height: '410px',\n          filterString: value && value.trim() ? value : undefined,\n          handleSelect: (_event: any, itemKey: CoinKey<I>) => {\n            onChangeEvent(0, {\n              ...{ tradeData: { ...tradeData, belong: itemKey } },\n              to: 'button',\n            })\n          },\n          walletMap: walletMap, //tradeCalcData?.walletMap as any,\n          selected,\n          t,\n          ...rest,\n        }}\n        filterWithBorrowed={filterWithBorrowed}\n        ref={ref}\n      />\n    )\n  }\n  return (\n    <Box\n      className={'menu-panel'}\n      flexDirection={'column'}\n      flex={1}\n      height={'100%'}\n      display={'flex'}\n    >\n      <InputSelect\n        {...{\n          ...{ ...inputSelectProps, selected },\n          backElement: hasCancel ? backElement : undefined,\n          panelRender,\n          hasCancel,\n          t,\n          ...rest,\n        }}\n      />\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/components/tool/index.ts",
    "content": "// this is a private component, only used in panel component\n// please do not export this index to global\nexport * from './SlippagePanel'\nexport * from './ToolBarItems'\nexport * from './TradeMenuList'\nexport * from '../SwapWrap/SwapMenuList'\nexport * from './Dialogs'\nexport * from '../../Deposit/DepositTitle'\nexport * from '../../../basic-lib/form/input/CollectionInput'\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/index.ts",
    "content": "export * from './Swap'\nexport * from './Reset'\nexport * from './Interface'\nexport * from './ModalPanel'\nexport * from './components/Styled'\nexport * from './Amm'\nexport * from './components/tool/Dialogs'\nexport * from './tradePro'\nexport * from './ExportAccount'\nexport * from './components/DepositNFTWrap'\nexport * from './components/DeployNFTWrap'\nexport * from './components/MintNFTConfirm'\nexport * from './components/MintAdvanceNFTWrap'\nexport * from './components/MintNFTBlock'\nexport * from './Deposit'\nexport * from './components/tool/FeeList'\nexport * from './components/DeFiWrap'\nexport * from './components/DualWrap'\nexport * from './components/ImportRedPacketWrap'\nexport * from './components/CollectionAdvanceWrap'\nexport * from './components/ImportCollectionWrap'\nexport * from '../basic-lib/form/input/CollectionInput'\nexport * from './components/CreateCollectionWrap'\nexport * from './components/CollectionManageWrap'\nexport * from './components/RampConfirm'\nexport * from './components/tool/Refresh'\nexport * from './components/BanxaConfirm'\nexport * from './components/ImportRedPacketWrap'\nexport * from './components/hook/useAddressType'\nexport * from './components/BasicACoinTrade'\nexport { FullAddressType } from './components/AddressType'\nexport { InitialNameAvatar } from './components/ContactSelection'\nexport * from './components/VaultWrap'\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/tradePro/Interface.ts",
    "content": "import { InputButtonProps } from '../../basic-lib'\nimport {\n  CoinInfo,\n  TradeBaseType,\n  TradeBtnStatus,\n  TradeCalcProData,\n  TradeProType,\n} from '@loopring-web/common-resources'\nimport React from 'react'\n\nexport type TradeLimitInfoProps<T, TCD extends TradeCalcProData<I>, I> = {\n  tradeLimitI18nKey?: string\n  tradeLimitBtnStyle?: React.CSSProperties\n  tradeCalcProData: Partial<TCD>\n  tradeLimitBtnStatus?: keyof typeof TradeBtnStatus | undefined\n  tokenPriceProps?: Partial<InputButtonProps<T, I, CoinInfo<I>>>\n  tokenBaseProps?: Partial<InputButtonProps<T, I, CoinInfo<I>>>\n  tokenQuoteProps?: Partial<InputButtonProps<T, I, CoinInfo<I>>>\n}\nexport type StopTradeLimitInfoProps<T, TCD extends TradeCalcProData<I>, I> = {\n  stopPriceProps?: Partial<InputButtonProps<T, I, CoinInfo<I>>>\n  // stopRange: [string | undefined, string | undefined];\n} & TradeLimitInfoProps<T, TCD, I>\n\nexport type TradeMarketInfoProps<T, TCD extends TradeCalcProData<I>, I> = {\n  tradeMarketI18nKey?: string\n  tradeMarketBtnStyle?: React.CSSProperties\n  tradeCalcProData: Partial<TCD>\n  tradeMarketBtnStatus?: keyof typeof TradeBtnStatus | undefined\n  tokenBaseProps?: Partial<InputButtonProps<T, I, CoinInfo<I>>>\n  tokenQuoteProps?: Partial<InputButtonProps<T, I, CoinInfo<I>>>\n}\n\nexport type TradeProBaseEventProps<X, T, I> = {\n  disabled?: boolean\n  tradeType: TradeProType\n  handleChangeIndex?: (index: TradeProType) => X\n  // onSwapClick: (tradeData: SwapTradeData<T>) => void | any,\n} & Partial<Pick<InputButtonProps<T, I, unknown>, 'handleError'>>\n\nexport type TradeCommonProps<X, T, TCD, I> = {\n  type: 'limit' | 'market'\n  tradeData: X\n  i18nKey: string\n  tradeCalcProData: TCD\n  onChangeEvent: (data: X, formType: TradeBaseType) => X\n  tradeBtnBaseStatus?: keyof typeof TradeBtnStatus | undefined\n  handleCountChange?: (ibData: T, name: string, ref: React.ForwardedRef<any>) => void\n  // tokenPriceProps?: Partial<InputButtonProps<T, I, CoinInfo<I>>>,\n  tokenBaseProps?: Partial<InputButtonProps<T, I, CoinInfo<I>>>\n  tokenQuoteProps?: Partial<InputButtonProps<T, I, CoinInfo<I>>>\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/tradePro/hookCommon.tsx",
    "content": "import React from 'react'\nimport { TradeCommonProps, TradeProBaseEventProps } from './Interface'\nimport {\n  IBData,\n  L1L2_NAME_DEFINED,\n  MapChainId,\n  myLog,\n  TradeBaseType,\n  TradeCalcProData,\n  TradeProType,\n} from '@loopring-web/common-resources'\nimport { WithTranslation } from 'react-i18next'\nimport { LimitTradeData, MarketTradeData } from '../Interface'\nimport { InputSize } from '../../basic-lib'\nimport _ from 'lodash'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { useSettings } from '../../../stores'\n\nexport const useCommon = <\n  X extends LimitTradeData<T> | MarketTradeData<T>,\n  T extends IBData<I>,\n  TCD extends TradeCalcProData<I>,\n  I,\n>({\n  t,\n  type,\n  i18nKey,\n  tradeCalcProData,\n  tradeBtnBaseStatus,\n  tradeData,\n  tradeType,\n  handleCountChange,\n  onChangeEvent,\n  tokenBaseProps,\n  tokenQuoteProps,\n  disabled,\n  handleChangeIndex,\n  ...rest\n}: TradeProBaseEventProps<X, T, I> & TradeCommonProps<X, T, TCD, I> & WithTranslation) => {\n  const quoteRef = React.useRef()\n  const baseRef = React.useRef()\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const [selectedPercentage, setSelectedPercentage] = React.useState(0)\n  // const [tabIndex, setTabIndex] = React.useState<TradeProType>(tradeData.type ?? TradeProType.buy);\n  const [inputError, setInputError] = React.useState<{\n    error: boolean\n    message?: string | JSX.Element\n  }>({\n    error: false,\n    message: '',\n  })\n  React.useEffect(() => {\n    const inputType = tradeType === TradeProType.sell ? 'base' : 'quote'\n    if (tradeData[inputType].tradeValue && tradeData[inputType].balance) {\n      const _data = tradeData[inputType] //.tradeValue\n      const value = sdk\n        .toBig(_data.tradeValue ?? '')\n        .div(sdk.toBig(_data.balance))\n        .times(100)\n        .toFixed()\n      setSelectedPercentage(Number(value))\n    } else {\n      setSelectedPercentage(0)\n    }\n  }, [tradeData['base'].tradeValue, tradeData['quote'].tradeValue])\n\n  const handleError = React.useCallback(\n    ({ belong, balance, tradeValue }: any, ref?) => {\n      if (typeof rest.handleError !== 'function') {\n        if (balance < tradeValue || (tradeValue && !balance)) {\n          const _error = {\n            error: true,\n            message: t('tokenNotEnough', { belong: belong }),\n          }\n          setInputError(_error)\n          return _error\n        }\n        setInputError({ error: false, message: '' })\n        return { error: false, message: '' }\n      } else {\n        return rest.handleError({ belong, balance, tradeValue } as any, ref)\n      }\n    },\n    [rest.handleError, setInputError],\n  )\n  const _handleCountChange = React.useCallback(\n    (ibData: T, name: string, _ref: any) => {\n      if (handleCountChange) {\n        handleCountChange(ibData, name, _ref)\n      } else {\n        const _tradeData = {\n          ...tradeData,\n          [name]: ibData,\n        }\n        onChangeEvent(_tradeData, TradeBaseType[name])\n      }\n    },\n    [tradeData, type, tradeType],\n  )\n\n  const propsBase = React.useMemo(() => {\n    return {\n      label: t('labelProBaseLabel'),\n      subLabel: tradeType === TradeProType.sell ? t('tokenMax') : undefined,\n      emptyText: t('tokenSelectToken'),\n      placeholderText: '0.00',\n      size: InputSize.small,\n      order: '\"right\"' as any,\n      coinLabelStyle: { color: 'var(--color-text-secondary)' },\n      isShowCoinIcon: false,\n      ...tokenBaseProps,\n      handleError: tradeType === TradeProType.sell ? handleError : undefined,\n      maxAllow: tradeType === TradeProType.sell,\n      ...rest,\n    }\n  }, [tokenBaseProps, tradeType, TradeProType])\n  const propsQuote = React.useMemo(() => {\n    return {\n      label: t('labelProQuoteLabel'),\n      subLabel: tradeType === TradeProType.buy ? t('tokenMax') : undefined,\n      emptyText: t('tokenSelectToken'),\n      placeholderText: '0.00',\n      size: InputSize.small,\n      order: '\"right\"' as any,\n      coinLabelStyle: { color: 'var(--color-text-secondary)' },\n      isShowCoinIcon: false,\n      ...tokenQuoteProps,\n      handleError: tradeType === TradeProType.buy ? handleError : undefined,\n      maxAllow: tradeType === TradeProType.buy,\n      ...rest,\n    }\n  }, [tokenQuoteProps, tradeType, TradeProType])\n  const getDisabled = React.useCallback(() => {\n    return disabled || tradeCalcProData === undefined || tradeCalcProData.coinInfoMap === undefined\n  }, [disabled, tradeCalcProData])\n  const _handleChangeIndex = React.useCallback(\n    (index: TradeProType) => {\n      // setTabIndex(index)\n      if (handleChangeIndex) {\n        tradeData = handleChangeIndex(index)\n      } else {\n        tradeData.type = index\n        setSelectedPercentage(0)\n      }\n      onChangeEvent(tradeData, TradeBaseType.tab)\n    },\n    [tradeData],\n  )\n\n  const btnLabel = React.useMemo(() => {\n    const key = i18nKey.split('|')\n    return t(key[0], {\n      arg: key[1],\n      tradeType: tradeType === TradeProType.sell ? t('labelProSell') : t('labelProBuy'),\n      symbol: tradeCalcProData.coinBase,\n      layer2: L1L2_NAME_DEFINED[network].layer2,\n      loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n      loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n      l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n      l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n      ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n    })\n  }, [inputError, t, i18nKey, tradeType, tradeCalcProData])\n\n  const onPercentage = React.useCallback(\n    (value: any) => {\n      myLog('hookCommon onPercentage:', value, tradeData)\n      const inputType = tradeType === TradeProType.sell ? 'base' : 'quote'\n      setSelectedPercentage(value)\n      const tradeCoin = _.cloneDeep(tradeData[inputType])\n      if (tradeCoin && tradeCoin.balance) {\n        tradeCoin.tradeValue = sdk\n          .toBig(tradeCoin.balance)\n          .times(sdk.toBig(value))\n          .div(100)\n          .toNumber()\n        _handleCountChange(tradeCoin, inputType, {\n          current: 'percentage',\n        } as React.Ref<any>)\n      }\n    },\n    [_handleCountChange, tradeType, tradeData],\n  )\n  return {\n    quoteRef,\n    baseRef,\n    btnLabel,\n    getDisabled,\n    handleCountChange: _handleCountChange,\n    selectedPercentage,\n    onPercentage,\n    inputError,\n    _handleChangeIndex,\n    i18nKey,\n    tradeCalcProData,\n    tradeBtnBaseStatus,\n    propsBase,\n    propsQuote,\n  }\n}\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/tradePro/index.ts",
    "content": "export * from './limitTrade'\nexport * from './marketTrade'\nexport * from './stopLimitTrade'\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/tradePro/limitTrade.tsx",
    "content": "import { WithTranslation, withTranslation } from 'react-i18next'\nimport { BtnPercentage, InputCoin, InputSize } from '../../basic-lib'\nimport { LimitTradeData, TradeLimitProps } from '../Interface'\nimport {\n    CoinInfo,\n    CoinKey,\n    CoinMap,\n    CurrencyToTag,\n    IBData,\n    PriceTag,\n    TradeBtnStatus,\n    TradeCalcProData,\n    TradeProType,\n} from '@loopring-web/common-resources'\nimport {\n    Box,\n\n    Tab,\n} from '@mui/material'\nimport { TabsStyle } from '../components/Styled'\nimport { useCommon } from './hookCommon'\nimport { Button } from './../../index'\nimport React from 'react'\nimport { useSettings } from '../../../stores'\n\nexport const LimitTrade = withTranslation('common', {withRef: true})(\n    <\n        L extends LimitTradeData<T>,\n        T extends IBData<I>,\n        TCD extends TradeCalcProData<I>,\n        I = CoinKey<any>,\n    >({\n          tradeData = {type: TradeProType.sell} as L,\n          ...props\n      }: TradeLimitProps<L, T, TCD, I> & WithTranslation) => {\n        const {\n            t,\n            tradeType,\n            tradeLimitI18nKey,\n            tradeLimitBtnStatus,\n            tradeLimitBtnStyle,\n            tokenPriceProps,\n            handleSubmitEvent,\n            onChangeEvent,\n        } = props\n        const {currency} = useSettings()\n        const priceRef = React.useRef()\n        const {\n            quoteRef,\n            baseRef,\n            btnLabel,\n            getDisabled,\n            _handleChangeIndex,\n            // inputError,\n            tradeCalcProData,\n            tradeBtnBaseStatus,\n            handleCountChange,\n            propsBase,\n            propsQuote,\n            onPercentage,\n            selectedPercentage,\n        } = useCommon({\n            type: 'limit',\n            ...(props as any),\n            tradeData,\n            tradeType,\n            onChangeEvent,\n            i18nKey: tradeLimitI18nKey ? tradeLimitI18nKey : 'labelProLimitBtn',\n            tradeBtnBaseStatus: tradeLimitBtnStatus,\n        })\n        const propsPrice = React.useMemo(() => {\n            return {\n                label: t('labelProPrice'),\n                subLabel: `\\u2248 ${PriceTag[CurrencyToTag[currency]]}`,\n                emptyText: t('tokenSelectToken'),\n                placeholderText: '0.00',\n                size: InputSize.small,\n                order: '\"right\"' as any,\n                coinPrecision: 2,\n                coinLabelStyle: {color: 'var(--color-text-secondary)'},\n                isShowCoinIcon: false,\n                ...tokenPriceProps,\n                handleCountChange,\n                maxAllow: false,\n                t,\n            }\n        }, [tradeType, TradeProType, tokenPriceProps, handleCountChange])\n\n        return (\n            <Box flex={1} display={'flex'} flexDirection={'column'} alignItems={'stretch'}>\n                <Box\n                    className={'tool-bar'}\n                    paddingX={2}\n                    display={'flex'}\n                    alignItems={'center'}\n                    justifyContent={'center'}\n                >\n                    <Box component={'header'} width={'100%'}>\n                        <TabsStyle\n                            className={'trade-tabs pro-tabs'}\n                            variant={'fullWidth'}\n                            value={tradeType}\n                            onChange={(_e, index) => _handleChangeIndex(index)}\n                        >\n                            <Tab className={'trade-tab-buy'} value={TradeProType.buy} label={t('labelProBuy')}/>\n                            <Tab\n                                className={'trade-tab-sell'}\n                                value={TradeProType.sell}\n                                label={t('labelProSell')}\n                            />\n                        </TabsStyle>\n                    </Box>\n                </Box>\n                <Box className={'trade-panel'} paddingX={2} paddingTop={2}>\n                    <Box paddingTop={2}>\n                        <InputCoin<any, I, CoinInfo<I>>\n                            ref={priceRef as any}\n                            name={'price'}\n                            disabled={false}\n                            {...({\n                                ...propsPrice,\n                                isShowCoinInfo: true,\n                                isShowCoinIcon: false,\n                                maxAllow: false,\n                                isHideError: true,\n                                inputData: tradeData ? tradeData.price : ({} as any),\n                                coinMap:\n                                    tradeCalcProData && tradeCalcProData.coinInfoMap\n                                        ? tradeCalcProData.coinInfoMap\n                                        : ({} as CoinMap<I, CoinInfo<I>>),\n                            } as any)}\n                        />\n                    </Box>\n                    <Box paddingTop={2}>\n                        <InputCoin<any, I, CoinInfo<I>>\n                            ref={baseRef as any}\n                            name={'base'}\n                            disabled={getDisabled()}\n                            {...{\n                                ...propsBase,\n                                // maxAllow:false,\n                                isShowCoinInfo: true,\n                                isShowCoinIcon: false,\n                                isHideError: true,\n                                handleCountChange,\n                                inputData: tradeData ? tradeData.base : ({} as any),\n                                coinMap:\n                                    tradeCalcProData && tradeCalcProData.coinInfoMap\n                                        ? tradeCalcProData.coinInfoMap\n                                        : ({} as CoinMap<I, CoinInfo<I>>),\n                            }}\n                        />\n                    </Box>\n                    <Box alignSelf={'center'} paddingTop={4} paddingX={1}>\n                        <BtnPercentage\n                            step={1}\n                            // valuetext={(value)=>`${value}%`}\n                            getAriaLabel={(value) => `${value}%`}\n                            valueLabelFormat={(value) => `${value}%`}\n                            valueLabelDisplay={'on'}\n                            selected={selectedPercentage}\n                            anchors={[\n                                {\n                                    value: 0,\n                                    label: '',\n                                },\n                                {\n                                    value: 25,\n                                    label: '',\n                                },\n                                {\n                                    value: 50,\n                                    label: '',\n                                },\n                                {\n                                    value: 75,\n                                    label: '',\n                                },\n                                {\n                                    value: 100,\n                                    label: '',\n                                },\n                            ]}\n                            handleChanged={onPercentage}\n                        />\n                    </Box>\n                    <Box paddingTop={2}>\n                        <InputCoin<any, I, CoinInfo<I>>\n                            ref={quoteRef}\n                            name={'quote'}\n                            disabled={getDisabled()}\n                            {...{\n                                ...propsQuote,\n                                isHideError: true,\n                                isShowCoinInfo: true,\n                                isShowCoinIcon: false,\n                                handleCountChange,\n                                inputData: tradeData ? tradeData.quote : ({} as any),\n                                coinMap:\n                                    tradeCalcProData && tradeCalcProData.coinInfoMap\n                                        ? tradeCalcProData.coinInfoMap\n                                        : ({} as CoinMap<I, CoinInfo<I>>),\n                            }}\n                        />\n                    </Box>\n                </Box>\n                <Box className={'info-panel'} paddingX={2} paddingTop={2}></Box>\n                {/*{tradeCalcProData.isNotMatchMarketPrice && (*/}\n                {/*  <Box paddingX={2} paddingTop={2}>*/}\n                {/*    <MuiFormControlLabel*/}\n                {/*      sx={{ alignItems: 'flex-start' }}*/}\n                {/*      control={*/}\n                {/*        <Checkbox*/}\n                {/*          checked={tradeCalcProData?.isChecked ? true : false}*/}\n                {/*          onChange={() => {*/}\n                {/*            onChangeEvent(*/}\n                {/*              {*/}\n                {/*                ...tradeData,*/}\n                {/*                isChecked: !tradeCalcProData?.isChecked,*/}\n                {/*              },*/}\n                {/*              TradeBaseType.checkMarketPrice,*/}\n                {/*            )*/}\n                {/*          }}*/}\n                {/*          checkedIcon={<CheckedIcon />}*/}\n                {/*          icon={<CheckBoxIcon />}*/}\n                {/*          color='default'*/}\n                {/*        />*/}\n                {/*      }*/}\n                {/*      label={*/}\n                {/*        <Typography variant={'body2'}>*/}\n                {/*          <Trans*/}\n                {/*            i18nKey={'labelExpectSettlementLimitPrice'}*/}\n                {/*            interpolation={{ escapeValue: false }}*/}\n                {/*            tOptions={{*/}\n                {/*              symbolBase: tradeCalcProData.coinBase,*/}\n                {/*              symbolQuote: tradeCalcProData.coinQuote,*/}\n                {/*              price: tradeData.price.tradeValue,*/}\n                {/*              marketPrice: tradeCalcProData.marketPrice,*/}\n                {/*              marketRatePrice: tradeCalcProData.marketRatePrice,*/}\n                {/*            }}*/}\n                {/*          >*/}\n                {/*            The expected settlement price from this order is symbol = xxxx, while the*/}\n                {/*            current market price from a trusted oracle is symbol = xxx. There is a 10.45%*/}\n                {/*            variance observed. To proceed, tap here to confirm you understand and*/}\n                {/*            acknowledge the risk.*/}\n                {/*          </Trans>*/}\n                {/*        </Typography>*/}\n                {/*      }*/}\n                {/*    />*/}\n                {/*  </Box>*/}\n                {/*)}*/}\n                <Box paddingX={2} paddingTop={2}>\n                    {/*{getDisabled()} {tradeBtnBaseStatus}*/}\n                    <Button\n                        variant={'contained'}\n                        size={'medium'}\n                        color={tradeType === TradeProType.sell ? 'error' : 'success'}\n                        loadingbg={\n                            tradeType === TradeProType.sell ? 'var(--color-error)' : 'var(--color-success)'\n                        }\n                        style={tradeLimitBtnStyle}\n                        onClick={() => {\n                            handleSubmitEvent(tradeData)\n                        }}\n                        loading={\n                            !getDisabled() && tradeBtnBaseStatus === TradeBtnStatus.LOADING ? 'true' : 'false'\n                        }\n                        disabled={\n                            getDisabled() ||\n                            tradeBtnBaseStatus === TradeBtnStatus.DISABLED ||\n                            tradeBtnBaseStatus === TradeBtnStatus.LOADING\n                        }\n                        fullWidth={true}\n                    >\n                        {btnLabel}\n                    </Button>\n                </Box>\n            </Box>\n        )\n    },\n) as <\n    L extends LimitTradeData<T>,\n    T extends IBData<I>,\n    TCD extends TradeCalcProData<I>,\n    I = CoinKey<any>,\n>(\n    props: TradeLimitProps<L, T, TCD, I>,\n) => JSX.Element\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/tradePro/marketTrade.tsx",
    "content": "import { WithTranslation, withTranslation } from 'react-i18next'\nimport { MarketTradeData, TradeMarketProps } from '../Interface'\nimport {\n  CoinInfo,\n  CoinKey,\n  CoinMap,\n  defaultSlipage,\n  EmptyValueTag,\n  getValuePrecisionThousand,\n  IBData,\n  Info2Icon,\n  SlippageTolerance,\n  TradeBaseType,\n  TradeBtnStatus,\n  TradeCalcProData,\n  TradeProType,\n} from '@loopring-web/common-resources'\nimport { Box, Grid, Tab, Tooltip, Typography } from '@mui/material'\nimport { BtnPercentage, InputCoin, LinkActionStyle, PopoverPure } from '../../basic-lib'\nimport { useCommon } from './hookCommon'\nimport { ButtonStyle, TabsStyle } from '../components/Styled'\nimport { bindHover, bindPopover } from 'material-ui-popup-state/es'\nimport { SlippagePanel } from '../components'\nimport React from 'react'\nimport { usePopupState } from 'material-ui-popup-state/hooks'\nimport { useSettings } from '../../../stores'\n\nexport const MarketTrade = withTranslation('common', { withRef: true })(\n  <\n    M extends MarketTradeData<T>,\n    T extends IBData<I>,\n    TCD extends TradeCalcProData<I>,\n    I = CoinKey<any>,\n  >({\n    tradeData = {} as M,\n    ...props\n  }: TradeMarketProps<M, T, TCD, I> & WithTranslation) => {\n    // const {slippage} = useSettings();\n    // onChangeEvent?: (data:L,type:TradeProType) => L,\n    const { slippage } = useSettings()\n    const slippageArray: Array<number | string> = SlippageTolerance.concat(\n      `slippage:${slippage}`,\n    ) as Array<number | string>\n    const {\n      t,\n      // disabled,\n      tradeMarketI18nKey,\n      tradeMarketBtnStyle,\n      tradeType,\n      tradeMarketBtnStatus,\n      handleSubmitEvent,\n      onChangeEvent,\n      // ...rest\n    } = props\n\n    const {\n      quoteRef,\n      baseRef,\n      btnLabel,\n      getDisabled,\n      _handleChangeIndex,\n      // inputError,\n      tradeCalcProData,\n      tradeBtnBaseStatus,\n      propsBase,\n      propsQuote,\n      onPercentage,\n      handleCountChange,\n      selectedPercentage,\n    } = useCommon({\n      type: 'market',\n      ...(props as any),\n      tradeData,\n      tradeType,\n      onChangeEvent,\n      i18nKey: tradeMarketI18nKey ? tradeMarketI18nKey : 'labelProMarketBtn',\n      tradeBtnBaseStatus: tradeMarketBtnStatus,\n    })\n    const popupState = usePopupState({\n      variant: 'popover',\n      popupId: 'slippagePop',\n    })\n    const _onSlippageChange = React.useCallback(\n      (slippage: number | string, customSlippage: number | string | undefined) => {\n        popupState.close()\n        onChangeEvent(\n          {\n            ...tradeData,\n            slippage: slippage,\n            __cache__: {\n              ...tradeData.__cache__,\n              customSlippage: customSlippage,\n            },\n          },\n          TradeBaseType.slippage,\n        )\n      },\n      [tradeData, onChangeEvent],\n    )\n\n    const priceImpactColor = tradeCalcProData?.priceImpactColor\n      ? tradeCalcProData.priceImpactColor\n      : 'textPrimary'\n    const priceImpact =\n      tradeCalcProData?.priceImpact !== undefined\n        ? getValuePrecisionThousand(tradeCalcProData.priceImpact, 2, undefined, undefined, false, {\n            floor: true,\n          }) + ' %'\n        : EmptyValueTag\n\n    const fee =\n      tradeCalcProData && tradeCalcProData.fee\n        ? `${tradeCalcProData.fee} ${\n            tradeType === TradeProType.sell ? tradeData.quote?.belong : tradeData.base?.belong\n          }` //(parseFloat(tradeCalcData.fee) / 100).toString() + \"%\"\n        : EmptyValueTag\n\n    const userTakerRate =\n      tradeCalcProData && tradeCalcProData.feeTakerRate\n        ? (tradeCalcProData.feeTakerRate / 100).toString()\n        : EmptyValueTag\n\n    const tradeCostMin =\n      tradeCalcProData && tradeCalcProData.tradeCost\n        ? `${tradeCalcProData.tradeCost} ${tradeData.quote?.belong}` //(parseFloat(tradeCalcData.fee) / 100).toString() + \"%\"\n        : EmptyValueTag\n    const minimumConverted =\n      tradeCalcProData && tradeCalcProData.minimumConverted\n        ? `${tradeCalcProData.minimumConverted}  ${\n            tradeType === TradeProType.buy ? tradeData.base.belong : tradeData.quote.belong\n          }`\n        : EmptyValueTag\n\n    return (\n      <Box flex={1} display={'flex'} flexDirection={'column'} alignItems={'stretch'}>\n        <Box\n          className={'tool-bar'}\n          paddingX={2}\n          display={'flex'}\n          alignItems={'center'}\n          justifyContent={'center'}\n        >\n          <Box component={'header'} width={'100%'}>\n            <TabsStyle\n              className={'trade-tabs pro-tabs'}\n              variant={'fullWidth'}\n              value={tradeType}\n              onChange={(_e, index) => _handleChangeIndex(index)}\n            >\n              <Tab className={'trade-tab-buy'} value={TradeProType.buy} label={t('labelProBuy')} />\n              <Tab\n                className={'trade-tab-sell'}\n                value={TradeProType.sell}\n                label={t('labelProSell')}\n              />\n            </TabsStyle>\n          </Box>\n        </Box>\n        <Box className={'trade-panel'} paddingTop={2} paddingX={2}>\n          <Box paddingTop={2}>\n            <InputCoin<any, I, CoinInfo<I>>\n              ref={baseRef as any}\n              name={'base'}\n              disabled={getDisabled()}\n              {...{\n                ...propsBase,\n                // maxAllow:false,\n                isShowCoinInfo: true,\n                isShowCoinIcon: false,\n                handleCountChange,\n                isHideError: true,\n                inputData: tradeData ? tradeData.base : ({} as any),\n                coinMap:\n                  tradeCalcProData && tradeCalcProData.coinInfoMap\n                    ? tradeCalcProData.coinInfoMap\n                    : ({} as CoinMap<I, CoinInfo<I>>),\n              }}\n            />\n          </Box>\n          {/*</Grid>*/}\n          {/*<Grid item>*/}\n          <Box alignSelf={'center'} paddingTop={4} paddingX={1}>\n            <BtnPercentage\n              step={25}\n              // valuetext={(value)=>`${value}%`}\n              getAriaLabel={(value) => `${value}%`}\n              valueLabelFormat={(value) => `${value}%`}\n              valueLabelDisplay={'on'}\n              selected={selectedPercentage}\n              anchors={[\n                {\n                  value: 0,\n                  label: '',\n                },\n                {\n                  value: 25,\n                  label: '',\n                },\n                {\n                  value: 50,\n                  label: '',\n                },\n                {\n                  value: 75,\n                  label: '',\n                },\n                {\n                  value: 100,\n                  label: '',\n                },\n              ]}\n              handleChanged={onPercentage}\n            />\n          </Box>\n          <Box paddingTop={2}>\n            <InputCoin<any, I, CoinInfo<I>>\n              ref={quoteRef}\n              name={'quote'}\n              disabled={getDisabled()}\n              {...{\n                ...propsQuote,\n                isHideError: true,\n                handleCountChange,\n                isShowCoinInfo: true,\n                isShowCoinIcon: false,\n                inputData: tradeData ? tradeData.quote : ({} as any),\n                coinMap:\n                  tradeCalcProData && tradeCalcProData.coinInfoMap\n                    ? tradeCalcProData.coinInfoMap\n                    : ({} as CoinMap<I, CoinInfo<I>>),\n              }}\n            />\n          </Box>\n          {/*</Grid>*/}\n          {/*<Grid item>*/}\n\n          {/*< label={tradeCalcProData.baseToken} coinMap={tradeCalcProData.coinMap} />*/}\n        </Box>\n        <Box paddingTop={2} paddingX={2}>\n          <Grid container direction={'column'} spacing={1} alignItems={'stretch'}>\n            <Grid item marginBottom={1} sx={{ color: 'text.secondary' }}>\n              <Grid\n                container\n                justifyContent={'space-between'}\n                direction={'row'}\n                alignItems={'center'}\n                marginTop={1 / 2}\n              >\n                <Tooltip\n                  title={t('labelSwapFeeTooltips', {\n                    rate: userTakerRate,\n                    value: tradeCostMin,\n                  }).toString()}\n                  placement={'top'}\n                >\n                  <Typography\n                    component={'p'}\n                    variant='body2'\n                    color={'textSecondary'}\n                    display={'inline-flex'}\n                    alignItems={'center'}\n                  >\n                    <Info2Icon fontSize={'small'} color={'inherit'} sx={{ marginX: 1 / 2 }} />\n                    {' ' + t('labelTradingFeeEst')}\n                  </Typography>\n                </Tooltip>\n                <Typography component={'p'} variant='body2' color={'textPrimary'}>\n                  {fee}\n                </Typography>\n              </Grid>\n              <Grid\n                container\n                justifyContent={'space-between'}\n                direction={'row'}\n                alignItems={'center'}\n                height={24}\n              >\n                <Tooltip title={t('labelSwapToleranceTooltips').toString()} placement={'top'}>\n                  <Typography\n                    component={'p'}\n                    variant='body2'\n                    color={'textSecondary'}\n                    display={'inline-flex'}\n                    alignItems={'center'}\n                  >\n                    <Info2Icon fontSize={'small'} color={'inherit'} sx={{ marginX: 1 / 2 }} />\n                    {' ' + t('swapTolerance')}\n                  </Typography>\n                </Tooltip>\n                <Typography component={'p'} variant='body2'>\n                  {tradeCalcProData ? (\n                    <>\n                      <Typography\n                        {...bindHover(popupState)}\n                        component={'span'}\n                        color={'textPrimary'}\n                      >\n                        <LinkActionStyle>\n                          {tradeData.slippage\n                            ? tradeData.slippage\n                            : tradeCalcProData.slippage\n                            ? tradeCalcProData.slippage\n                            : defaultSlipage}\n                          %\n                        </LinkActionStyle>\n                        <PopoverPure\n                          className={'arrow-right'}\n                          {...bindPopover(popupState)}\n                          {...{\n                            anchorOrigin: {\n                              vertical: 'bottom',\n                              horizontal: 'right',\n                            },\n                            transformOrigin: {\n                              vertical: 'top',\n                              horizontal: 'right',\n                            },\n                          }}\n                        >\n                          <SlippagePanel\n                            {...{\n                              t,\n                              handleChange: _onSlippageChange,\n                              slippageList: slippageArray,\n                              slippage: tradeData.slippage\n                                ? tradeData.slippage\n                                : tradeCalcProData.slippage\n                                ? tradeCalcProData.slippage\n                                : defaultSlipage,\n                            }}\n                          />\n                        </PopoverPure>\n                      </Typography>\n                    </>\n                  ) : (\n                    EmptyValueTag\n                  )}\n                </Typography>\n              </Grid>\n              <Grid\n                container\n                justifyContent={'space-between'}\n                direction={'row'}\n                alignItems={'center'}\n                marginTop={1 / 2}\n              >\n                <Tooltip title={t('labelSwapPriceImpactTooltips').toString()} placement={'top'}>\n                  <Typography\n                    component={'p'}\n                    variant='body2'\n                    color={'textSecondary'}\n                    display={'inline-flex'}\n                    alignItems={'center'}\n                  >\n                    <Info2Icon fontSize={'small'} color={'inherit'} sx={{ marginX: 1 / 2 }} />\n                    {' ' + t('swapPriceImpact')}\n                  </Typography>\n                </Tooltip>\n                <Typography component={'p'} color={priceImpactColor} variant='body2'>\n                  {priceImpact}\n                </Typography>\n              </Grid>\n              <Grid\n                container\n                justifyContent={'space-between'}\n                direction={'row'}\n                alignItems={'center'}\n                marginTop={1 / 2}\n              >\n                <Tooltip title={t('labelSwapMinReceiveTooltips').toString()} placement={'top'}>\n                  <Typography\n                    component={'p'}\n                    variant='body2'\n                    color={'textSecondary'}\n                    display={'inline-flex'}\n                    alignItems={'center'}\n                  >\n                    <Info2Icon fontSize={'small'} color={'inherit'} sx={{ marginX: 1 / 2 }} />\n                    {' ' + t('labelSwapMinConverted')}\n                  </Typography>\n                </Tooltip>\n                <Typography component={'p'} variant='body2' color={'textPrimary'}>\n                  {minimumConverted !== EmptyValueTag ? minimumConverted : EmptyValueTag}\n                </Typography>\n              </Grid>\n            </Grid>\n            {/*<Grid item >*/}\n            {/*  isNotMatchMarketPrice*/}\n            {/*  marketPrice*/}\n            {/*  marketRatePrice*/}\n            {/*  */}\n            {/*</Grid>*/}\n            {/*{tradeCalcProData.isNotMatchMarketPrice && (*/}\n            {/*  <Grid item marginBottom={1}>*/}\n            {/*    <MuiFormControlLabel*/}\n            {/*      sx={{ alignItems: 'flex-start' }}*/}\n            {/*      control={*/}\n            {/*        <Checkbox*/}\n            {/*          checked={tradeCalcProData?.isChecked ? true : false}*/}\n            {/*          onChange={() => {*/}\n            {/*            onChangeEvent(*/}\n            {/*              {*/}\n            {/*                ...tradeData,*/}\n            {/*                isChecked: !tradeCalcProData?.isChecked,*/}\n            {/*              },*/}\n            {/*              tradeCalcProData?.lastStepAt === TradeBaseType.quote*/}\n            {/*                ? TradeBaseType.quote*/}\n            {/*                : TradeBaseType.base,*/}\n            {/*            )*/}\n            {/*          }}*/}\n            {/*          checkedIcon={<CheckedIcon />}*/}\n            {/*          icon={<CheckBoxIcon />}*/}\n            {/*          color='default'*/}\n            {/*        />*/}\n            {/*      }*/}\n            {/*      label={*/}\n            {/*        <Typography variant={'body2'}>*/}\n            {/*          <Trans*/}\n            {/*            i18nKey={'labelExpectSettlementPrice'}*/}\n            {/*            interpolation={{ escapeValue: false }}*/}\n            {/*            tOptions={{*/}\n            {/*              // ,symbolBuy*/}\n            {/*              symbolSell: tradeData.base.belong,*/}\n            {/*              symbolBuy: tradeData.quote.belong,*/}\n            {/*              stob:*/}\n            {/*                tradeType === TradeProType.sell*/}\n            {/*                  ? tradeCalcProData.StoB*/}\n            {/*                  : tradeCalcProData.BtoS,*/}\n            {/*              marketPrice: tradeCalcProData.marketPrice,*/}\n            {/*              marketRatePrice: tradeCalcProData.marketRatePrice,*/}\n            {/*            }}*/}\n            {/*          >*/}\n            {/*            The expected settlement price from this order is symbol = value, while the*/}\n            {/*            current market price from a trusted oracle is symbol= marketPrice. There is*/}\n            {/*            marketRatePrice% variance observed. Please acknowledge the risk if you still*/}\n            {/*            want to continue.*/}\n            {/*          </Trans>*/}\n            {/*        </Typography>*/}\n            {/*      }*/}\n            {/*    />*/}\n            {/*  </Grid>*/}\n            {/*)}*/}\n          </Grid>\n        </Box>\n        <Box paddingTop={2} paddingX={2}>\n          <ButtonStyle\n            variant={'contained'}\n            size={'medium'}\n            color={tradeType === TradeProType.sell ? 'error' : 'success'}\n            loadingbg={\n              tradeType === TradeProType.sell ? 'var(--color-error)' : 'var(--color-success)'\n            }\n            style={{ ...tradeMarketBtnStyle }}\n            onClick={() => {\n              handleSubmitEvent(tradeData)\n            }}\n            loading={\n              !getDisabled() && tradeBtnBaseStatus === TradeBtnStatus.LOADING ? 'true' : 'false'\n            }\n            disabled={\n              getDisabled() ||\n              tradeBtnBaseStatus === TradeBtnStatus.DISABLED ||\n              tradeBtnBaseStatus === TradeBtnStatus.LOADING\n            }\n            fullWidth={true}\n          >\n            {btnLabel}\n          </ButtonStyle>\n        </Box>\n      </Box>\n    )\n  },\n) as <\n  M extends MarketTradeData<T>,\n  T extends IBData<I>,\n  TCD extends TradeCalcProData<I>,\n  I = CoinKey<any>,\n>(\n  props: TradeMarketProps<M, T, TCD, I>,\n) => JSX.Element\n"
  },
  {
    "path": "packages/component-lib/src/components/tradePanel/tradePro/stopLimitTrade.tsx",
    "content": "import { WithTranslation, withTranslation } from 'react-i18next'\nimport { BtnPercentage, InputCoin, InputSize } from '../../basic-lib'\nimport {\n  LimitTradeData,\n  StopLimitTradeData,\n  TradeLimitProps,\n  TradeStopLimitProps,\n} from '../Interface'\nimport {\n  CoinInfo,\n  CoinKey,\n  CoinMap,\n  CurrencyToTag,\n  IBData,\n  Info2Icon,\n  PriceTag,\n  TradeBaseType,\n  TradeBtnStatus,\n  TradeCalcProData,\n  TradeProType,\n} from '@loopring-web/common-resources'\nimport { Box, Icon, Tab, Tooltip } from '@mui/material'\nimport { TabsStyle } from '../components/Styled'\nimport { useCommon } from './hookCommon'\nimport { Button } from './../../index'\nimport React from 'react'\nimport { useSettings } from '../../../stores'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport styled from '@emotion/styled'\n\nconst BoxStyle = styled(Box)`\n  .stopPrice {\n    input::placeholder {\n      white-space: pre-wrap;\n      font-size: 10px;\n      position: absolute;\n      height: fit-content;\n      align-items: center;\n      top: 50%;\n      left: 50%;\n      width: 90%;\n      transform: translate(-50%, -50%);\n    }\n    .MuiGrid-grid-xs-3 {\n      z-index: 2;\n    }\n  }\n  .limit-price {\n    .MuiGrid-grid-xs-3 {\n      z-index: 2;\n    }\n  }\n` as typeof Box\nexport const StopLimitTrade = withTranslation('common', { withRef: true })(\n  <\n    L extends StopLimitTradeData<T>,\n    T extends IBData<I>,\n    TCD extends TradeCalcProData<I>,\n    I = CoinKey<any>,\n  >({\n    tradeData = { type: TradeProType.sell } as L,\n    ...props\n  }: TradeStopLimitProps<L, T, TCD, I> & WithTranslation) => {\n    const {\n      t,\n      tradeType,\n      tradeLimitI18nKey,\n      tradeLimitBtnStatus,\n      tradeLimitBtnStyle,\n      tokenPriceProps,\n      stopPriceProps,\n      handleSubmitEvent,\n      onChangeEvent,\n    } = props\n    const { currency } = useSettings()\n    const priceRef = React.useRef()\n    const stopPriceRef = React.useRef()\n    const {\n      quoteRef,\n      baseRef,\n      btnLabel,\n      getDisabled,\n      _handleChangeIndex,\n      // inputError,\n      tradeCalcProData,\n      tradeBtnBaseStatus,\n      handleCountChange,\n      propsBase,\n      propsQuote,\n      onPercentage,\n      selectedPercentage,\n    } = useCommon({\n      type: 'limit',\n      ...(props as any),\n      tradeData,\n      tradeType,\n      onChangeEvent,\n      i18nKey: tradeLimitI18nKey ? tradeLimitI18nKey : 'labelProLimitBtn',\n      tradeBtnBaseStatus: tradeLimitBtnStatus,\n    })\n    const propsPrice = React.useMemo(() => {\n      return {\n        label: (\n          <Box display={'flex'} alignItems={'center'}>\n            {tradeType === TradeProType.buy ? t('labelStopPrice') : t('labelStopPriceSell')}\n            <Tooltip sx={{ marginLeft: 1 / 2 }} title={t('labelStopStopPriceDes')}>\n              <Icon>\n                <Info2Icon fontSize={'medium'} />\n              </Icon>\n            </Tooltip>\n          </Box>\n        ),\n        subLabel: `\\u2248 ${PriceTag[CurrencyToTag[currency]]}`,\n        emptyText: t('tokenSelectToken'),\n        placeholderText: '0.00',\n        size: InputSize.small,\n        order: '\"right\"' as any,\n        coinPrecision: 2,\n        coinLabelStyle: { color: 'var(--color-text-secondary)' },\n        isShowCoinIcon: false,\n        ...tokenPriceProps,\n        handleCountChange,\n        maxAllow: false,\n        t,\n      }\n    }, [tradeType, TradeProType, tokenPriceProps, handleCountChange])\n    const propsStopPrice = React.useMemo(() => {\n      return {\n        label: (\n          <Box display={'flex'} alignItems={'center'}>\n            {t('labelStopStopPrice')}\n            <Tooltip sx={{ marginLeft: 1 / 2 }} title={t('labelStopStopPriceDes')}>\n              <Icon>\n                <Info2Icon fontSize={'medium'} />\n              </Icon>\n            </Tooltip>\n          </Box>\n        ),\n        subLabel: `\\u2248 ${PriceTag[CurrencyToTag[currency]]}`,\n        emptyText: t('tokenSelectToken'),\n        placeholderText:\n          tradeCalcProData.stopRange &&\n          tradeCalcProData.stopRange[0] &&\n          tradeCalcProData.stopRange[1]\n            ? t('labelStopLimitMinMax', {\n                minValue: tradeCalcProData.stopRange[0],\n                maxValue: tradeCalcProData.stopRange[1],\n              })\n            : '0.00',\n        size: InputSize.small,\n        order: '\"right\"' as any,\n        coinPrecision: 2,\n        coinLabelStyle: { color: 'var(--color-text-secondary)' },\n        isShowCoinIcon: false,\n        ...stopPriceProps,\n        handleCountChange,\n        maxAllow: false,\n        handleError: (data: T) => {\n          if (\n            data.tradeValue &&\n            tradeCalcProData.stopRange &&\n            tradeCalcProData.stopRange[1] &&\n            tradeCalcProData.stopRange[0] &&\n            (sdk\n              .toBig(data.tradeValue)\n              .gt(tradeCalcProData.stopRange[1]?.replaceAll(sdk.SEP, '')) ||\n              sdk.toBig(data.tradeValue).lt(tradeCalcProData.stopRange[0]?.replaceAll(sdk.SEP, '')))\n          ) {\n            return {\n              error: true,\n            }\n          }\n          return {\n            error: false,\n          }\n        },\n        t,\n      }\n    }, [tradeType, TradeProType, stopPriceProps, handleCountChange])\n\n    return (\n      <BoxStyle flex={1} display={'flex'} flexDirection={'column'} alignItems={'stretch'}>\n        <Box\n          className={'tool-bar'}\n          paddingX={2}\n          display={'flex'}\n          alignItems={'center'}\n          justifyContent={'center'}\n        >\n          <Box component={'header'} width={'100%'}>\n            <TabsStyle\n              className={'trade-tabs pro-tabs'}\n              variant={'fullWidth'}\n              value={tradeType}\n              onChange={(_e, index) => _handleChangeIndex(index)}\n            >\n              <Tab className={'trade-tab-buy'} value={TradeProType.buy} label={t('labelProBuy')} />\n              <Tab\n                className={'trade-tab-sell'}\n                value={TradeProType.sell}\n                label={t('labelProSell')}\n              />\n            </TabsStyle>\n          </Box>\n        </Box>\n        <Box className={'trade-panel'} paddingX={2} paddingTop={2}>\n          <Box paddingTop={2}>\n            <InputCoin<any, I, CoinInfo<I>>\n              ref={stopPriceRef as any}\n              name={TradeBaseType.stopPrice}\n              className={'stopPrice'}\n              disabled={false}\n              {...({\n                ...propsStopPrice,\n                isShowCoinInfo: true,\n                isShowCoinIcon: false,\n                maxAllow: false,\n                isHideError: true,\n                inputData: tradeData ? tradeData.stopPrice : ({} as any),\n                coinMap:\n                  tradeCalcProData && tradeCalcProData.coinInfoMap\n                    ? tradeCalcProData.coinInfoMap\n                    : ({} as CoinMap<I, CoinInfo<I>>),\n              } as any)}\n            />\n          </Box>\n          <Box paddingTop={2}>\n            <InputCoin<any, I, CoinInfo<I>>\n              ref={priceRef as any}\n              name={TradeBaseType.price}\n              disabled={false}\n              className={'limit-price'}\n              {...({\n                ...propsPrice,\n                isShowCoinInfo: true,\n                isShowCoinIcon: false,\n                maxAllow: false,\n                isHideError: true,\n                inputData: tradeData ? tradeData.price : ({} as any),\n                coinMap:\n                  tradeCalcProData && tradeCalcProData.coinInfoMap\n                    ? tradeCalcProData.coinInfoMap\n                    : ({} as CoinMap<I, CoinInfo<I>>),\n              } as any)}\n            />\n          </Box>\n          <Box paddingTop={2}>\n            <InputCoin<any, I, CoinInfo<I>>\n              ref={baseRef as any}\n              name={TradeBaseType.base}\n              disabled={getDisabled()}\n              {...{\n                ...propsBase,\n                // maxAllow:false,\n                isShowCoinInfo: true,\n                isShowCoinIcon: false,\n                isHideError: true,\n                handleCountChange,\n                inputData: tradeData ? tradeData.base : ({} as any),\n                coinMap:\n                  tradeCalcProData && tradeCalcProData.coinInfoMap\n                    ? tradeCalcProData.coinInfoMap\n                    : ({} as CoinMap<I, CoinInfo<I>>),\n              }}\n            />\n          </Box>\n          {/*</Grid>*/}\n          {/*<Grid item>*/}\n          <Box alignSelf={'center'} paddingTop={4} paddingX={1}>\n            <BtnPercentage\n              step={1}\n              // valuetext={(value)=>`${value}%`}\n              getAriaLabel={(value) => `${value}%`}\n              valueLabelFormat={(value) => `${value}%`}\n              valueLabelDisplay={'on'}\n              selected={selectedPercentage}\n              anchors={[\n                {\n                  value: 0,\n                  label: '',\n                },\n                {\n                  value: 25,\n                  label: '',\n                },\n                {\n                  value: 50,\n                  label: '',\n                },\n                {\n                  value: 75,\n                  label: '',\n                },\n                {\n                  value: 100,\n                  label: '',\n                },\n              ]}\n              handleChanged={onPercentage}\n            />\n          </Box>\n          <Box paddingTop={2}>\n            <InputCoin<any, I, CoinInfo<I>>\n              ref={quoteRef}\n              name={TradeBaseType.quote}\n              disabled={getDisabled()}\n              {...{\n                ...propsQuote,\n                isHideError: true,\n                isShowCoinInfo: true,\n                isShowCoinIcon: false,\n                handleCountChange,\n                inputData: tradeData ? tradeData.quote : ({} as any),\n                coinMap:\n                  tradeCalcProData && tradeCalcProData.coinInfoMap\n                    ? tradeCalcProData.coinInfoMap\n                    : ({} as CoinMap<I, CoinInfo<I>>),\n              }}\n            />\n          </Box>\n        </Box>\n        <Box className={'info-panel'} paddingX={2} paddingTop={2}></Box>\n        <Box paddingX={2} paddingTop={2}>\n          {/*{getDisabled()} {tradeBtnBaseStatus}*/}\n          <Button\n            variant={'contained'}\n            size={'medium'}\n            color={tradeType === TradeProType.sell ? 'error' : 'success'}\n            loadingbg={\n              tradeType === TradeProType.sell ? 'var(--color-error)' : 'var(--color-success)'\n            }\n            style={tradeLimitBtnStyle}\n            onClick={() => {\n              handleSubmitEvent(tradeData)\n            }}\n            loading={\n              !getDisabled() && tradeBtnBaseStatus === TradeBtnStatus.LOADING ? 'true' : 'false'\n            }\n            disabled={\n              getDisabled() ||\n              tradeBtnBaseStatus === TradeBtnStatus.DISABLED ||\n              tradeBtnBaseStatus === TradeBtnStatus.LOADING\n            }\n            fullWidth={true}\n          >\n            {btnLabel}\n          </Button>\n        </Box>\n      </BoxStyle>\n    )\n  },\n) as <\n  L extends LimitTradeData<T>,\n  T extends IBData<I>,\n  TCD extends TradeCalcProData<I>,\n  I = CoinKey<any>,\n>(\n  props: TradeLimitProps<L, T, TCD, I>,\n) => JSX.Element\n"
  },
  {
    "path": "packages/component-lib/src/index.ts",
    "content": "/**\n * @example\n * export const HeadMenuItem = withTranslation()(styled(({}:InterFaceProps & WithTranslation)=><></>)``\n * ) as  React.ComponentType<InterFaceProps>;\n */\n\nexport * from './stores'\nexport * from './components'\n\nexport * from './static'\nexport {VaultPage, useGetVaultAssets, useVaultMarket} from './sharedPages'\n\n// export * from \"./@loopring-web/common-resources\";\n"
  },
  {
    "path": "packages/component-lib/src/react-app-env.d.ts",
    "content": "/// <reference types=\"react-scripts\" />\n"
  },
  {
    "path": "packages/component-lib/src/reportWebVitals.ts",
    "content": "import { ReportHandler } from 'web-vitals'\n\nconst reportWebVitals = (onPerfEntry?: ReportHandler) => {\n  if (onPerfEntry && onPerfEntry instanceof Function) {\n    import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {\n      getCLS(onPerfEntry)\n      getFID(onPerfEntry)\n      getFCP(onPerfEntry)\n      getLCP(onPerfEntry)\n      getTTFB(onPerfEntry)\n    })\n  }\n}\n\nexport default reportWebVitals\n"
  },
  {
    "path": "packages/component-lib/src/setupTests.ts",
    "content": "// jest-dom adds custom jest matchers for asserting on DOM nodes.\n// allows you to do things like:\n// expect(element).toHaveTextContent(/react/i)\n// learn more: https://github.com/testing-library/jest-dom\nimport '@testing-library/jest-dom'\n"
  },
  {
    "path": "packages/component-lib/src/sharedPages/VaultPage/components/DashBoardPanel.tsx",
    "content": "import {\n  Box,\n  Container,\n  Typography,\n  Modal,\n  Tooltip,\n  Button,\n  Divider,\n  IconButton,\n  Tab, \n  Tabs,\n  styled,\n} from '@mui/material'\nimport ArrowForwardIcon from '@mui/icons-material/ArrowForward'\nimport React from 'react'\nimport {\n  MarginLevelIcon,\n  PriceTag,\n  CurrencyToTag,\n  HiddenTag,\n  getValuePrecisionThousand,\n  EmptyValueTag,\n  VaultAction,\n  L1L2_NAME_DEFINED,\n  UpColor,\n  Info2Icon,\n  SoursURL,\n  RouterPath,\n  VaultKey,\n  TradeBtnStatus,\n  WarningIcon2,\n  hexToRGB,\n  OrderListIcon,\n  ViewIcon,\n  HideIcon,\n} from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport {\n  MarketDetail,\n  ModalCloseButton,\n  ModalCloseButtonPosition,\n  SwitchPanelStyled,\n  VaultAssetsTable,\n  Button as MyButton,\n  VaultJoinPanelModal,\n  VaultPositionsTable,\n  Toast,\n  useSettings,\n} from '@loopring-web/component-lib'\nimport { Trans } from 'react-i18next'\nimport {\n  fiatNumberDisplay,\n  useVaultJoin,\n  VaultAccountInfoStatus,\n  ViewAccountTemplate,\n  WalletConnectL2Btn,\n} from '@loopring-web/core'\nimport {\n  AutoRepayConfirmModal,\n  CloseAllConfirmModal,\n  CloseConfirmModal,\n  CollateralDetailsModal,\n  DebtModal,\n  DustCollectorModal,\n  DustCollectorUnAvailableModal,\n  LeverageModal,\n  MaximumCreditModal,\n  NoAccountHintModal,\n  SmallOrderAlert,\n  SupplyCollateralHintModal,\n  VaultSwapModal\n} from './modals'\nimport { marginLevelTypeToColor } from '@loopring-web/component-lib/src/components/tradePanel/components/VaultWrap/utils'\nimport { marginLevelType } from '@loopring-web/core/src/hooks/useractions/vault/utils'\nimport { useVaultDashboard } from '../hooks/useVaultDashBoard'\nimport { VaultDashBoardPanelUIProps } from '../interface'\nimport { useVaultSwap } from '../hooks/useVaultSwap'\n\nconst BgButton = styled(Button)<{ customBg: string }>`\n  background-color: ${({ customBg }) => customBg};\n  transition: all 0.2s ease-in-out;\n  &:hover {\n    background-color: ${({ customBg }) => customBg};\n    opacity: 0.8;\n  }\n  &:disabled {\n    background-color: var(--color-button-disabled);\n  }\n  \n`\n\nconst zeroTag = '0.0'\nconst VaultDashBoardPanelUI: React.FC<VaultDashBoardPanelUIProps> = ({\n  t,\n  forexMap,\n  theme,\n  currency,\n  hideAssets,\n  upColor,\n  showMarginLevelAlert,\n  vaultAccountInfo,\n  localState,\n  setLocalState,\n  colors,\n  assetPanelProps,\n  marketProps,\n  vaultTokenMap,\n  vaultTickerMap,\n  VaultDustCollector,\n  isShowVaultJoin,\n  detail,\n  setShowDetail,\n  hideLeverage,\n  activeInfo,\n  walletMap,\n  _vaultAccountInfo,\n  tokenPrices,\n  getValueInCurrency,\n  history,\n  etherscanBaseUrl,\n  onClickCollateralManagement,\n  onClickSettle,\n  onClickPortalTrade,\n  liquidationThreshold,\n  liquidationPenalty,\n  assetsTab,\n  onChangeAssetsTab,\n  onClickRecord,\n  vaultPositionsTableProps,\n  onClickHideShowAssets,\n  vaultAccountActive,\n  totalEquity,\n  showSettleBtn,\n  btnsDisabled,\n  onClickBuy,\n  onClickSell,\n  didAccountSignIn\n  \n}) => {\n  const { isMobile } = useSettings()\n  const boxSx = {\n    my: isMobile ? 2 : 2,\n    width: isMobile ? '50%' : '25%',\n  }\n  const activeView = (\n    <>\n      {showMarginLevelAlert && (\n        <Box\n          paddingY={1}\n          paddingX={2.5}\n          borderRadius={'8px'}\n          bgcolor={hexToRGB(theme.colorBase.error, 0.2)}\n          display={'flex'}\n          marginTop={3}\n        >\n          <WarningIcon2\n            color={'error'}\n            style={{\n              width: '24px',\n              height: '24px',\n            }}\n          />\n          <Typography marginLeft={0.5}>{t('labelVaultMarginLevelAlert')}</Typography>\n        </Box>\n      )}\n      <Box\n        display={'flex'}\n        flexDirection={'column'}\n        mt={3}\n        px={4}\n        pt={3}\n        pb={5}\n        border={'1px solid var(--color-border)'}\n        borderRadius={1.5}\n        position={'relative'}\n      >\n        <Box\n          bgcolor={'var(--color-box-third)'}\n          position={'absolute'}\n          height={'40px'}\n          px={2.5}\n          left={0}\n          top={0}\n          display={'flex'}\n          justifyContent={'center'}\n          alignItems={'center'}\n          borderRadius={'4px 0 4px 0'}\n        >\n          <Typography>Cross Account</Typography>\n        </Box>\n        <Box\n          display={'flex'}\n          flexDirection={isMobile ? 'column' : 'row'}\n          alignItems={isMobile ? 'end' : 'center'}\n          alignSelf={'flex-end'}\n        >\n          <Button\n            disabled={btnsDisabled}\n            onClick={onClickCollateralManagement}\n            sx={{ width: 'auto' }}\n            variant='contained'\n          >\n            Collateral Management\n          </Button>\n          {showSettleBtn && (\n            <BgButton\n              customBg='var(--color-button-outlined)'\n              onClick={onClickSettle}\n              sx={{\n                width: 'auto',\n                ml: 1.5,\n                mt: isMobile ? 2 : 0,\n                color: theme.mode === 'light' ? 'var(--color-black)' : 'var(--color-white)',\n              }}\n              variant='contained'\n              disabled={btnsDisabled}\n            >\n              Settle\n            </BgButton>\n          )}\n        </Box>\n\n        <Box mt={1.5} display={'flex'} alignItems={'center'}>\n          <Box mr={0.5}>\n            <Typography color={'var(--color-text-secondary)'} variant='h3' fontSize={'14px'}>\n              Total Equity\n            </Typography>\n          </Box>\n\n          {hideAssets ? (\n            <HideIcon\n              className='custom-size'\n              sx={{\n                fontSize: '20px',\n                color: 'var(--color-text-secondary)',\n                cursor: 'pointer',\n              }}\n              onClick={onClickHideShowAssets}\n            />\n          ) : (\n            <ViewIcon\n              className='custom-size'\n              sx={{\n                fontSize: '20px',\n                color: 'var(--color-text-secondary)',\n                cursor: 'pointer',\n              }}\n              onClick={onClickHideShowAssets}\n            />\n          )}\n        </Box>\n        <Typography mt={1} variant='h2'>\n          {vaultAccountActive ? (hideAssets ? HiddenTag : totalEquity) : zeroTag}\n        </Typography>\n\n        <Box mt={isMobile ? 2 : 4} display={'flex'} flexWrap={'wrap'} flexDirection={'row'}>\n          <Box sx={boxSx}>\n            <Typography component={'h4'} variant={'body1'} color={'textSecondary'}>\n              {t('labelVaultTotalCollateral')}\n            </Typography>\n            <Typography\n              component={'span'}\n              marginTop={1}\n              display={'inline-flex'}\n              variant={'body1'}\n              color={'textPrimary'}\n              fontSize={'20px'}\n              alignItems={'center'}\n            >\n              {vaultAccountActive\n                ? hideAssets\n                  ? HiddenTag\n                  : PriceTag[CurrencyToTag[currency]] +\n                    getValuePrecisionThousand(\n                      Number(vaultAccountInfo?.totalCollateralOfUsdt ?? 0) *\n                        (forexMap[currency] ?? 0),\n                      2,\n                      2,\n                      2,\n                      false,\n                      { isFait: true, floor: true },\n                    )\n                : zeroTag}\n              {vaultAccountActive && (\n                <Typography\n                  sx={{ cursor: 'pointer' }}\n                  color={'var(--color-primary)'}\n                  marginLeft={1.5}\n                  component={'span'}\n                  onClick={() => {\n                    setLocalState({\n                      ...localState,\n                      modalStatus: 'collateralDetails',\n                    })\n                  }}\n                >\n                  {t('labelVaultDetails')}\n                </Typography>\n              )}\n            </Typography>\n          </Box>\n          <Box sx={boxSx}>\n            <Typography\n              component={'h4'}\n              variant={'body1'}\n              color={'textSecondary'}\n              display={'flex'}\n              alignItems={'center'}\n            >\n              {t('labelVaultMarginLevel')}\n              <Tooltip\n                title={\n                  <Box>\n                    <Typography marginBottom={1} variant={'body2'}>\n                      {t('labelVaultMarginLevelTooltips')}\n                    </Typography>\n                    <Typography marginBottom={1} variant={'body2'}>\n                      {t('labelVaultMarginLevelTooltips2')}\n                    </Typography>\n                    <Typography marginBottom={1} variant={'body2'}>\n                      {t('labelVaultMarginLevelTooltips3')}\n                    </Typography>\n                    <Typography color={'var(--color-success)'} marginBottom={1} variant={'body2'}>\n                      {t('labelVaultMarginLevelTooltips4')}\n                    </Typography>\n                    <Typography marginBottom={1} variant={'body2'}>\n                      {t('labelVaultMarginLevelTooltips5')}\n                    </Typography>\n                    <Typography color={'var(--color-warning)'} marginBottom={1} variant={'body2'}>\n                      {t('labelVaultMarginLevelTooltips6')}\n                    </Typography>\n                    <Typography marginBottom={1} variant={'body2'}>\n                      {t('labelVaultMarginLevelTooltips7')}\n                    </Typography>\n                    <Typography color={'var(--color-error)'} marginBottom={1} variant={'body2'}>\n                      {t('labelVaultMarginLevelTooltips8', {\n                        liqMarginLevel: liquidationThreshold,\n                      })}\n                    </Typography>\n                    <Typography marginBottom={1} variant={'body2'}>\n                      {t('labelVaultMarginLevelTooltips9')}\n                    </Typography>\n                    <Typography\n                      color={'var(--color-text-primary)'}\n                      marginBottom={1}\n                      variant={'body2'}\n                    >\n                      {t('labelVaultMarginLevelTooltips10', {\n                        liqMarginLevel: liquidationThreshold,\n                      })}\n                    </Typography>\n                    <Typography marginBottom={1} variant={'body2'}>\n                      {t('labelVaultMarginLevelTooltips11', {\n                        liqMarginLevel: liquidationThreshold,\n                      })}\n                    </Typography>\n                  </Box>\n                }\n                placement={isMobile ? 'bottom' : 'right'}\n              >\n                <Box display={'flex'} alignItems={'center'}>\n                  <Info2Icon color={'inherit'} sx={{ marginLeft: 1 / 2 }} />\n                </Box>\n              </Tooltip>\n            </Typography>\n\n            {(() => {\n              if (!vaultAccountActive) {\n                return (\n                  <Typography\n                    component={'span'}\n                    display={'inline-flex'}\n                    alignItems={'center'}\n                    marginTop={1}\n                    sx={{ fontSize: '20px', marginRight: 1 / 2 }}\n                  >\n                    {zeroTag}\n                  </Typography>\n                )\n              }\n              const item = vaultAccountInfo?.marginLevel ?? '0'\n              return (\n                <>\n                  {vaultAccountInfo?.marginLevel ? (\n                    <Typography\n                      component={'span'}\n                      display={'inline-flex'}\n                      alignItems={'center'}\n                      marginTop={1}\n                      variant={'body1'}\n                      fontSize={'16px'}\n                      color={marginLevelTypeToColor(marginLevelType(item))}\n                    >\n                      <MarginLevelIcon\n                        className='custom-size'\n                        sx={{ fontSize: '20px', marginRight: 1 / 2 }}\n                      />\n                      {item}\n                    </Typography>\n                  ) : (\n                    <Typography\n                      component={'span'}\n                      display={'inline-flex'}\n                      alignItems={'center'}\n                      marginTop={1}\n                      sx={{ fontSize: '20px', marginRight: 1 / 2 }}\n                    >\n                      <MarginLevelIcon\n                        className='custom-size'\n                        sx={{ fontSize: '20px', marginRight: 1 / 2 }}\n                      />\n                      {EmptyValueTag}\n                    </Typography>\n                  )}\n                </>\n              )\n            })()}\n          </Box>\n          <Box sx={boxSx}>\n            <Tooltip title={t('labelVaultTotalDebtTooltips').toString()} placement={'top'}>\n              <Typography\n                component={'h4'}\n                variant={'body1'}\n                color={'textSecondary'}\n                display={'flex'}\n                alignItems={'center'}\n              >\n                {t('labelVaultTotalDebt')}\n                <Info2Icon color={'inherit'} sx={{ marginLeft: 1 / 2 }} />\n              </Typography>\n            </Tooltip>\n            <Typography\n              component={'span'}\n              marginTop={1}\n              display={'inline-flex'}\n              variant={'body1'}\n              color={'textPrimary'}\n              fontSize={'20px'}\n              alignItems={'center'}\n            >\n              {vaultAccountActive\n                ? hideAssets\n                  ? HiddenTag\n                  : PriceTag[CurrencyToTag[currency]] +\n                    getValuePrecisionThousand(\n                      Number(vaultAccountInfo?.totalDebtOfUsdt ?? 0) * (forexMap[currency] ?? 0),\n                      2,\n                      2,\n                      2,\n                      false,\n                      { isFait: true, floor: true },\n                    )\n                : zeroTag}\n              {vaultAccountActive && (\n                <Typography\n                  sx={{ cursor: 'pointer' }}\n                  color={'var(--color-primary)'}\n                  marginLeft={1.5}\n                  component={'span'}\n                  onClick={() => {\n                    setLocalState({\n                      ...localState,\n                      modalStatus: 'debt',\n                    })\n                  }}\n                >\n                  {t('labelVaultDetails')}\n                </Typography>\n              )}\n            </Typography>\n          </Box>\n          <Box sx={boxSx}>\n            <Typography component={'h4'} variant={'body1'} color={'textSecondary'}>\n              {t('labelVaultProfit')}\n            </Typography>\n            <Typography\n              component={'span'}\n              display={'flex'}\n              marginTop={1}\n              variant={'body1'}\n              color={'textPrimary'}\n              fontSize={'20px'}\n            >\n              {(() => {\n                const profit =\n                  (vaultAccountInfo as any)?.accountType === 0\n                    ? sdk\n                        .toBig(vaultAccountInfo?.totalEquityOfUsdt ?? 0)\n                        .minus(vaultAccountInfo?.totalCollateralOfUsdt ?? 0)\n                    : sdk\n                        .toBig(vaultAccountInfo?.totalBalanceOfUsdt ?? 0)\n                        .minus(vaultAccountInfo?.totalDebtOfUsdt ?? 0)\n                const colorsId = upColor === UpColor.green ? [0, 1] : [1, 0]\n                const colorIs = profit.gte(0) ? colorsId[0] : colorsId[1]\n                return (\n                  <>\n                    {vaultAccountActive ? (\n                      <Box display={'flex'} alignItems={'center'}>\n                        <Typography\n                          component={'span'}\n                          display={'flex'}\n                          variant={'body1'}\n                          color={'textPrimary'}\n                          fontSize={'20px'}\n                        >\n                          {hideAssets\n                            ? HiddenTag\n                            : PriceTag[CurrencyToTag[currency]] +\n                              getValuePrecisionThousand(\n                                profit.times(forexMap[currency] ?? 0).toString(),\n                                2,\n                                2,\n                                2,\n                                false,\n                                {\n                                  isFait: false,\n                                  floor: true,\n                                },\n                              )}\n                        </Typography>\n                        <Typography\n                          component={'span'}\n                          display={'flex'}\n                          variant={'body1'}\n                          marginLeft={1.5}\n                          color={colors[colorIs]}\n                          fontSize={'20px'}\n                        >\n                          {getValuePrecisionThousand(\n                            profit\n                              ?.div(\n                                Number(vaultAccountInfo?.totalCollateralOfUsdt)\n                                  ? vaultAccountInfo?.totalCollateralOfUsdt\n                                  : 1,\n                              )\n                              .times(100) ?? 0,\n                            2,\n                            2,\n                            2,\n                            false,\n                            {\n                              isFait: false,\n                              floor: true,\n                            },\n                          )}\n                          %\n                        </Typography>\n                      </Box>\n                    ) : (\n                      zeroTag\n                    )}\n                  </>\n                )\n              })()}\n            </Typography>\n          </Box>\n          {!hideLeverage && (\n            <Box sx={boxSx} position={'relative'}>\n              <Typography component={'h4'} variant={'body1'} color={'textSecondary'}>\n                {t('labelVaultLeverage')}\n              </Typography>\n              <Typography\n                component={'span'}\n                marginTop={1}\n                display={'inline-flex'}\n                variant={'body1'}\n                color={'textPrimary'}\n                fontSize={'20px'}\n                alignItems={'center'}\n              >\n                {vaultAccountInfo?.leverage && vaultAccountActive\n                  ? `${vaultAccountInfo?.leverage}x`\n                  : EmptyValueTag}\n                {vaultAccountActive && (\n                  <Typography\n                    sx={{ cursor: 'pointer' }}\n                    color={'var(--color-primary)'}\n                    marginLeft={1.5}\n                    component={'span'}\n                    onClick={() => {\n                      setLocalState({\n                        ...localState,\n                        modalStatus: 'leverage',\n                      })\n                    }}\n                  >\n                    {t('labelVaultDetails')}\n                  </Typography>\n                )}\n              </Typography>\n              <Typography\n                marginTop={0.5}\n                width={'200px'}\n                color={'var(--color-text-secondary)'}\n                variant={'body2'}\n              >\n                {t('labelVaultMaximumCredit')}:{' '}\n                {(vaultAccountInfo as any)?.maxCredit &&\n                getValueInCurrency((vaultAccountInfo as any)?.maxCredit) &&\n                vaultAccountActive\n                  ? fiatNumberDisplay(\n                      getValueInCurrency((vaultAccountInfo as any)?.maxCredit),\n                      currency,\n                    )\n                  : zeroTag}\n              </Typography>\n            </Box>\n          )}\n          <Box sx={boxSx} position={'relative'}>\n            <Tooltip\n              title={\n                'The minimum health factor (margin level) at which a position becomes subject to forced liquidation.'\n              }\n              placement={'top'}\n            >\n              <Typography\n                component={'h4'}\n                variant={'body1'}\n                color={'textSecondary'}\n                display={'flex'}\n                alignItems={'center'}\n              >\n                Liquidation Threshold\n                <Info2Icon color={'inherit'} sx={{ marginLeft: 1 / 2 }} />\n              </Typography>\n            </Tooltip>\n\n            <Typography\n              component={'span'}\n              marginTop={1}\n              display={'inline-flex'}\n              variant={'body1'}\n              color={'textPrimary'}\n              fontSize={'20px'}\n              alignItems={'center'}\n            >\n              {vaultAccountActive ? liquidationThreshold : zeroTag}\n            </Typography>\n          </Box>\n          <Box sx={boxSx} position={'relative'}>\n            <Tooltip\n              title={\n                'The percentage of the position size deducted during liquidation to prevent bad debt.'\n              }\n              placement={'top'}\n            >\n              <Typography\n                component={'h4'}\n                variant={'body1'}\n                color={'textSecondary'}\n                display={'flex'}\n                alignItems={'center'}\n              >\n                Liquidation Penalty\n                <Info2Icon color={'inherit'} sx={{ marginLeft: 1 / 2 }} />\n              </Typography>\n            </Tooltip>\n            <Typography\n              component={'span'}\n              marginTop={1}\n              display={'inline-flex'}\n              variant={'body1'}\n              color={'textPrimary'}\n              fontSize={'20px'}\n              alignItems={'center'}\n            >\n              {vaultAccountActive ? liquidationPenalty : zeroTag}\n            </Typography>\n          </Box>\n        </Box>\n      </Box>\n      <Box\n        flex={1}\n        display={'flex'}\n        flexDirection={'column'}\n        border={'var(--color-border) 1px solid'}\n        borderRadius={1.5}\n        marginY={3}\n        paddingY={2}\n        px={2}\n      >\n        <Box mb={3} display={'flex'} justifyContent={'space-between'} alignItems={'flex-start'}>\n          <Tabs\n            variant={'scrollable'}\n            value={assetsTab}\n            onChange={(_, value) => onChangeAssetsTab(value)}\n          >\n            <Tab value={'assetsView'} label={'Assets'} />\n            <Tab value={'positionsView'} label={'Positions'} />\n          </Tabs>\n\n          <Button\n            variant={'text'}\n            startIcon={<OrderListIcon fontSize={'inherit'} color={'inherit'} />}\n            sx={{ mr: 2, mt: 1.5, color: 'var(--color-text-primary)' }}\n            onClick={onClickRecord}\n          >\n            {t('labelVaultRecord')}\n          </Button>\n        </Box>\n\n        {assetsTab === 'assetsView' ? (\n          <VaultAssetsTable\n            {...assetPanelProps}\n            onRowClick={(index, row) => {\n              // @ts-ignore\n              marketProps.onRowClick(index, {\n                // @ts-ignore\n                ...vaultTokenMap[row.name],\n                // @ts-ignore\n                cmcTokenId: vaultTickerMap[row.erc20Symbol].tokenId,\n                ...vaultTickerMap[row.erc20Symbol],\n              })\n            }}\n            onClickDustCollector={() => {\n              if (VaultDustCollector.enable) {\n                setLocalState({\n                  ...localState,\n                  modalStatus: 'dustCollector',\n                })\n              } else {\n                setLocalState({\n                  ...localState,\n                  modalStatus: 'dustCollectorUnavailable',\n                })\n              }\n            }}\n            showFilter\n          />\n        ) : (\n          <VaultPositionsTable {...vaultPositionsTableProps} />\n        )}\n\n        <Button\n          onClick={onClickPortalTrade}\n          size={isMobile ? 'medium' : 'large'}\n          variant='contained'\n          sx={{ mt: isMobile ? 3 : 5, mb: 3, alignSelf: 'center', width: '200px' }}\n        >\n          Portal Trade\n        </Button>\n      </Box>\n\n      <Modal\n        open={detail?.isShow && !isShowVaultJoin?.isShow}\n        onClose={() => setShowDetail({ isShow: false })}\n      >\n        <SwitchPanelStyled width={'var(--modal-width)'}>\n          <ModalCloseButton t={t} onClose={(_e: any) => setShowDetail({ isShow: false } as any)} />\n          <Box\n            display={'flex'}\n            flexDirection={'column'}\n            alignItems={'flex-start'}\n            alignSelf={'stretch'}\n            justifyContent={'stretch'}\n            marginTop={-5}\n          >\n            <Typography\n              display={'flex'}\n              flexDirection={'row'}\n              component={'header'}\n              alignItems={'center'}\n              height={'var(--toolbar-row-height)'}\n              paddingX={3}\n            >\n              {detail?.detail?.tokenInfo.erc20Symbol ?? detail?.detail?.tokenInfo.symbol}\n            </Typography>\n            <Divider style={{ marginTop: '-1px', width: '100%' }} />\n            <Box\n              maxHeight={'60vh'}\n              overflow={'scroll'}\n              flex={1}\n              display={'flex'}\n              flexDirection={'column'}\n            >\n              {vaultAccountInfo &&\n                walletMap &&\n                ([sdk.VaultAccountStatus.IN_STAKING].includes(vaultAccountInfo?.accountStatus) ||\n                  activeInfo?.hash) && (\n                  <>\n                    <Box\n                      display='flex'\n                      flexDirection={'column'}\n                      alignItems={'center'}\n                      alignSelf={'center'}\n                      justifyContent={'center'}\n                      margin={4}\n                    >\n                      <Typography variant={'h2'} component={'h4'} color={'inherit'}>\n                        {!hideAssets\n                          ? walletMap[detail?.detail?.tokenInfo.symbol!]?.count\n                            ? getValuePrecisionThousand(\n                                walletMap[detail?.detail?.tokenInfo.symbol!]?.count ?? 0,\n                                vaultTokenMap[detail?.detail?.tokenInfo.symbol!].precision,\n                                vaultTokenMap[detail?.detail?.tokenInfo.symbol!].precision,\n                                undefined,\n                                false,\n                                {\n                                  isFait: false,\n                                  floor: true,\n                                },\n                              )\n                            : '0.00'\n                          : HiddenTag}\n                      </Typography>\n                      <Typography variant={'body1'} color={'textSecondary'} component={'span'}>\n                        {!hideAssets\n                          ? walletMap[detail?.detail?.tokenInfo.symbol!]?.count\n                            ? PriceTag[CurrencyToTag[currency]] +\n                              getValuePrecisionThousand(\n                                sdk\n                                  .toBig(walletMap[detail?.detail?.tokenInfo.symbol!]!.count)\n                                  .times(tokenPrices?.[detail?.detail?.tokenInfo.symbol!] || 0)\n                                  .times(forexMap[currency] ?? 0),\n                                2,\n                                2,\n                                2,\n                                false,\n                                {\n                                  isFait: false,\n                                  floor: true,\n                                },\n                              )\n                            : PriceTag[CurrencyToTag[currency]] + '0.00'\n                          : HiddenTag}\n                      </Typography>\n                    </Box>\n                    <Divider style={{ marginTop: '-1px', width: '100%' }} />\n                  </>\n                )}\n              <Box padding={3} flex={1} display={'flex'} flexDirection={'column'}>\n                <MarketDetail\n                  etherscanBaseUrl={etherscanBaseUrl}\n                  isShow={detail.isShow}\n                  forexMap={forexMap}\n                  isLoading={detail.isLoading}\n                  showBtns={\n                    vaultAccountInfo &&\n                    [sdk.VaultAccountStatus.IN_STAKING].includes(vaultAccountInfo?.accountStatus)\n                  }\n                  onClickBuy={() => onClickBuy(detail?.detail)}\n                  onClickSell={() => onClickSell(detail?.detail)}\n                  {...{ ...detail?.detail }}\n                />\n              </Box>\n            </Box>\n            {!(\n              (vaultAccountInfo &&\n                [sdk.VaultAccountStatus.IN_STAKING].includes(vaultAccountInfo?.accountStatus)) ||\n              activeInfo?.hash\n            ) && (\n              <>\n                <Divider style={{ marginTop: '-1px', width: '100%' }} />\n                <Box\n                  padding={3}\n                  paddingY={1}\n                  display={'flex'}\n                  flexDirection={'column'}\n                  alignItems={'flex-end'}\n                  alignSelf={'stretch'}\n                  justifyContent={'stretch'}\n                >\n                  <MyButton\n                    size={'medium'}\n                    onClick={() => {\n                      setShowDetail({ isShow: false })\n                      _vaultAccountInfo.onJoinPop({})\n                    }}\n                    loading={'false'}\n                    variant={'contained'}\n                    sx={{ minWidth: 'var(--walletconnect-width)' }}\n                    disabled={\n                      _vaultAccountInfo.joinBtnStatus === TradeBtnStatus.DISABLED ||\n                      _vaultAccountInfo.joinBtnStatus === TradeBtnStatus.LOADING\n                    }\n                  >\n                    {_vaultAccountInfo.joinBtnLabel}\n                  </MyButton>\n                </Box>\n              </>\n            )}\n          </Box>\n        </SwitchPanelStyled>\n      </Modal>\n    </>\n  )\n  const inactiveView = (\n    <Box display={'flex'} mt={3} mb={5} flexDirection={isMobile ? 'column' : 'row'} justifyContent={isMobile ? 'center' : 'space-between'} alignItems={isMobile ? 'flex-start' : 'center'}>\n      <Box\n        display={'flex'}\n        flexDirection={'column'}\n        justifyContent={'center'}\n        alignItems={'flex-start'}\n        padding={2}\n        minHeight={isMobile ? 'auto' : '400px'}\n        width={'100%'}\n        mt={isMobile ? 2 : 10}\n      >\n        <Typography\n          variant={isMobile ? 'h5' : 'h4'}\n          mb={isMobile ? 5 : 2}\n          maxWidth={'90%'}\n        >\n          Loopring Portal functions as an isolated margin account allowing users to borrow and lend tokens using collateral.\n        </Typography>\n        <Typography\n          variant={isMobile ? 'h5' : 'h4'}\n          mb={5}\n          maxWidth={'90%'}\n        >\n          It enables leveraged trading and provides access to assets beyond Ethereum.\n        </Typography>\n        <WalletConnectL2Btn width={isMobile ? '200px' : '250px'} size={isMobile ? 'medium' : 'large'} />\n      </Box>\n      <Box\n        component={'img'}\n        width={isMobile ? '80%' : '40%'}\n        mt={8}\n        src={\n          SoursURL +\n          (theme.mode === 'dark' ? '/images/portal_demo_dark.png' : '/images/portal_demo_light.png')\n        }\n      />\n    </Box>\n  )\n  return (\n    <Box flex={1} display={'flex'} flexDirection={'column'}>\n      <Container\n        maxWidth='lg'\n        style={{\n          display: 'flex',\n          flexDirection: 'column',\n          flex: 1,\n        }}\n      >\n        {activeView}\n        {/* {didAccountSignIn ? activeView : inactiveView} */}\n      </Container>\n    </Box>\n  )\n}\n\nexport const VaultDashBoardPanel = ({\n  vaultAccountInfo: _vaultAccountInfo,\n  closeShowLeverage,\n  showLeverage,\n}: {\n  vaultAccountInfo: VaultAccountInfoStatus\n  closeShowLeverage: () => void\n  showLeverage: { show: boolean; closeAfterChange: boolean }\n}) => {\n  const {\n    collateralDetailsModalProps,\n    maximumCreditModalProps,\n    leverageModalProps,\n    debtModalProps,\n    dustCollectorModalProps,\n    dustCollectorUnAvailableModalProps,\n    vaultDashBoardPanelUIProps,\n    noAccountHintModalProps,\n    supplyCollateralHintModalProps,\n    closeConfirmModalProps,\n    autoRepayModalProps\n  } = useVaultDashboard({ showLeverage, closeShowLeverage })\n  const {vaultSwapModalProps, smallOrderAlertProps, toastProps, closeAllConfirmModalProps} = useVaultSwap()\n  const joinVaultProps = useVaultJoin()\n  return (\n    <>\n      <VaultDashBoardPanelUI\n        {...vaultDashBoardPanelUIProps}\n        vaultAccountInfo={_vaultAccountInfo.vaultAccountInfo}\n      />\n      <VaultJoinPanelModal {...joinVaultProps} />\n      <CollateralDetailsModal {...collateralDetailsModalProps} />\n      <MaximumCreditModal {...maximumCreditModalProps} />\n      <LeverageModal {...leverageModalProps} />\n      <DebtModal {...debtModalProps} />\n      <DustCollectorModal {...dustCollectorModalProps} />\n      <DustCollectorUnAvailableModal {...dustCollectorUnAvailableModalProps} />\n      <NoAccountHintModal {...noAccountHintModalProps} />\n      <VaultSwapModal {...vaultSwapModalProps} />\n      <SmallOrderAlert {...smallOrderAlertProps} />\n      <SupplyCollateralHintModal {...supplyCollateralHintModalProps} />\n      <Toast {...toastProps} />\n      <CloseConfirmModal {...closeConfirmModalProps}/>\n      <CloseAllConfirmModal {...closeAllConfirmModalProps}/>\n      <AutoRepayConfirmModal {...autoRepayModalProps}/>\n    </>\n  ) \n}\n"
  },
  {
    "path": "packages/component-lib/src/sharedPages/VaultPage/components/HomePanel.tsx",
    "content": "import { Box, Container, Divider, IconButton, Modal, Typography } from '@mui/material'\nimport React from 'react'\nimport {\n  CurrencyToTag,\n  EmptyValueTag,\n  getValuePrecisionThousand,\n  HiddenTag,\n  LoadIcon,\n  PriceTag,\n  RouterPath,\n  SoursURL,\n  TradeBtnStatus,\n  VaultAction,\n  VaultIcon,\n  VaultKey,\n  VaultTradeIcon,\n} from '@loopring-web/common-resources'\nimport {\n  BoxBannerStyle,\n  Button,\n  MarketDetail,\n  MarketTable,\n  ModalCloseButton,\n  useSettings,\n  SwitchPanelStyled,\n  useOpenModals,\n} from '@loopring-web/component-lib'\nimport { useTranslation } from 'react-i18next'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport {\n  makeVaultLayer2,\n  useSystem,\n  useVaultLayer2,\n  VaultAccountInfoStatus,\n  useVaultMap,\n} from '@loopring-web/core'\nimport { useHistory } from 'react-router-dom'\nimport { useTheme } from '@emotion/react'\nimport { useVaultMarket } from '../hooks/useVaultMarket'\nimport { symbol } from 'prop-types'\n\nexport const VaultHomePanel = ({\n  vaultAccountInfo: { joinBtnLabel, joinBtnStatus, onJoinPop, onGoToSwap },\n}: {\n  vaultAccountInfo: VaultAccountInfoStatus\n}) => {\n  const { isMobile } = useSettings()\n  const { forexMap, etherscanBaseUrl } = useSystem()\n  const theme = useTheme()\n  const { t } = useTranslation()\n  const { vaultAccountInfo, activeInfo } = useVaultLayer2()\n  const { tokenMap: vaultTokenMap, tokenPrices } = useVaultMap()\n  const {\n    modals: { isShowConfirmedVault, isShowVaultJoin },\n  } = useOpenModals()\n  const history = useHistory()\n  const tableRef = React.useRef<HTMLDivElement>()\n  const { marketProps: vaultMarketProps, detail, setShowDetail } = useVaultMarket({ tableRef })\n  const walletMap = makeVaultLayer2({ needFilterZero: true }).vaultLayer2Map ?? {}\n  const { hideL2Assets, currency } = useSettings()\n  return (\n    <Box flex={1} display={'flex'} flexDirection={'column'}>\n      {/* <BoxBannerStyle className={isMobile ? 'mobile' : ''} direction={'right'}>\n        <Container\n          maxWidth='lg'\n          style={{\n            display: 'flex',\n            flexDirection: 'column',\n            flex: 1,\n          }}\n        >\n          <Box marginY={3} display={'flex'} justifyContent={'space-between'}>\n            <Box\n              flex={1}\n              maxWidth={440}\n              display={'flex'}\n              flexDirection={'column'}\n              justifyContent={'center'}\n            >\n              <Typography component={'h2'} variant={'h3'}>\n                {t('labelTitleVault')}\n              </Typography>\n\n              <Typography component={'p'} variant={'body1'}>\n                {t('labelTitleVaultDes')}\n              </Typography>\n              <Box marginY={2} display={'flex'} flexDirection={'row'}>\n                {(vaultAccountInfo &&\n                  [sdk.VaultAccountStatus.IN_STAKING].includes(vaultAccountInfo?.accountStatus)) ||\n                activeInfo?.hash ? (\n                  <Button\n                    size={'medium'}\n                    onClick={() => {\n                      history.push(`${RouterPath.vault}/${VaultKey.VAULT_DASHBOARD}`)\n                    }}\n                    loading={'false'}\n                    variant={'contained'}\n                    sx={{ minWidth: 'var(--walletconnect-width)' }}\n                  >\n                    {t('labelGoVaultDashBoard')}\n                  </Button>\n                ) : (\n                  <Button\n                    size={'medium'}\n                    onClick={onJoinPop}\n                    loading={'false'}\n                    variant={'contained'}\n                    sx={{ minWidth: 'var(--walletconnect-width)' }}\n                    disabled={\n                      joinBtnStatus === TradeBtnStatus.DISABLED ||\n                      joinBtnStatus === TradeBtnStatus.LOADING\n                    }\n                  >\n                    {joinBtnLabel}\n                  </Button>\n                )}\n              </Box>\n            </Box>\n            {!isMobile && (\n              <Box>\n                <VaultIcon\n                  style={{\n                    width: 180,\n                    height: 180,\n                  }}\n                  primary={theme.colorBase.textPrimary}\n                  secondary={theme.colorBase.textSecondary}\n                  fill={theme.colorBase.textPrimary}\n                />\n              </Box>\n            )}\n          </Box>\n        </Container>\n      </BoxBannerStyle> */}\n      {/* <Box\n        flex={1}\n        display={'flex'}\n        flexDirection={'column'}\n        sx={{\n          background: 'var(--color-pop-bg)',\n        }}\n        mt={6}\n      > */}\n      <Container\n        maxWidth='lg'\n        sx={{\n          display: 'flex',\n          flexDirection: 'column',\n          background: 'var(--color-pop-bg)',\n          flex: 1,\n          mt: 6,\n          mb: 4,\n          borderRadius: '8px',\n        }}\n      >\n        <MarketTable {...{ ...vaultMarketProps }} hiddenFav={true} />\n      </Container>\n\n      <Modal\n        open={detail?.isShow && !isShowConfirmedVault?.isShow && !isShowVaultJoin?.isShow}\n        onClose={() => setShowDetail({ isShow: false })}\n      >\n        <SwitchPanelStyled width={'var(--modal-width)'}>\n          <ModalCloseButton t={t} onClose={(_e: any) => setShowDetail({ isShow: false } as any)} />\n          <Box\n            display={'flex'}\n            flexDirection={'column'}\n            alignItems={'flex-start'}\n            alignSelf={'stretch'}\n            justifyContent={'stretch'}\n            marginTop={-5}\n          >\n            <Typography\n              display={'flex'}\n              flexDirection={'row'}\n              component={'header'}\n              alignItems={'center'}\n              height={'var(--toolbar-row-height)'}\n              paddingX={3}\n            >\n              {detail?.detail?.tokenInfo.erc20Symbol ?? detail?.detail?.tokenInfo.symbol}\n            </Typography>\n            <Divider style={{ marginTop: '-1px', width: '100%' }} />\n            <Box\n              maxHeight={'60vh'}\n              overflow={'scroll'}\n              flex={1}\n              display={'flex'}\n              flexDirection={'column'}\n            >\n              {vaultAccountInfo &&\n                walletMap &&\n                ([sdk.VaultAccountStatus.IN_STAKING].includes(vaultAccountInfo?.accountStatus) ||\n                  activeInfo?.hash) && (\n                  <>\n                    <Box\n                      display='flex'\n                      flexDirection={'column'}\n                      alignItems={'center'}\n                      alignSelf={'center'}\n                      justifyContent={'center'}\n                      margin={4}\n                    >\n                      <Typography variant={'h2'} component={'h4'} color={'inherit'}>\n                        {!hideL2Assets\n                          ? walletMap[detail?.detail?.tokenInfo.symbol]?.count\n                            ? getValuePrecisionThousand(\n                                walletMap[detail?.detail?.tokenInfo.symbol]?.count ?? 0,\n                                vaultTokenMap[detail?.detail?.tokenInfo.symbol].precision,\n                                vaultTokenMap[detail?.detail?.tokenInfo.symbol].precision,\n                                undefined,\n                                false,\n                                {\n                                  isFait: false,\n                                  floor: true,\n                                },\n                              )\n                            : '0.00'\n                          : HiddenTag}\n                      </Typography>\n                      <Typography variant={'body1'} color={'textSecondary'} component={'span'}>\n                        {!hideL2Assets\n                          ? walletMap[detail?.detail?.tokenInfo.symbol]?.count\n                            ? PriceTag[CurrencyToTag[currency]] +\n                              getValuePrecisionThousand(\n                                sdk\n                                  .toBig(walletMap[detail?.detail?.tokenInfo.symbol]?.count)\n                                  .times(tokenPrices?.[detail?.detail?.tokenInfo.symbol] || 0)\n                                  .times(forexMap[currency] ?? 0),\n                                2,\n                                2,\n                                2,\n                                false,\n                                {\n                                  isFait: false,\n                                  floor: true,\n                                },\n                              )\n                            : PriceTag[CurrencyToTag[currency]] + '0.00'\n                          : HiddenTag}\n                      </Typography>\n                      {/* <Box marginTop={2} display={'flex'} flexDirection={'row'}>\n                        <Box\n                          display={'flex'}\n                          flexDirection={'column'}\n                          marginRight={5}\n                          alignItems={'center'}\n                        >\n                          <IconButton\n                            sx={{\n                              height: 'var(--svg-size-huge) !important',\n                              width: 'var(--svg-size-huge) !important',\n                              border: 'solid 0.5px var(--color-border)',\n                            }}\n                            size={'large'}\n                            onClick={() => {\n                              history.push(\n                                `${RouterPath.vault}/${VaultKey.VAULT_DASHBOARD}/${VaultAction.VaultLoan}?symbol=${detail?.detail?.tokenInfo.symbol}`,\n                              )\n                            }}\n                          >\n                            <Box\n                              component={'img'}\n                              src={`${SoursURL}svg/vault_loan_${theme.mode}.svg`}\n                            />\n                          </IconButton>\n                          <Typography\n                            marginTop={1 / 2}\n                            component={'span'}\n                            variant={'body2'}\n                            color={'textSecondary'}\n                            display={'inline-flex'}\n                            alignItems={'center'}\n                            textAlign={'center'}\n                            sx={{\n                              textIndent: 0,\n                              textAlign: 'center',\n                            }}\n                          >\n                            {t('labelVaultLoanBtn')}\n                          </Typography>\n                        </Box>\n                        <Box display={'flex'} flexDirection={'column'} alignItems={'center'}>\n                          <IconButton\n                            sx={{\n                              height: 'var(--svg-size-huge) !important',\n                              width: 'var(--svg-size-huge) !important',\n                              border: 'solid 0.5px var(--color-border)',\n                            }}\n                            size={'large'}\n                            onClick={() => {\n                              history.push(\n                                `${RouterPath.vault}/${VaultKey.VAULT_DASHBOARD}/${VaultAction.VaultSwap}?symbol=${detail?.detail?.tokenInfo.symbol}`,\n                              )\n                            }}\n                          >\n                            <Box\n                              component={'img'}\n                              src={`${SoursURL}svg/vault_trade_${theme.mode}.svg`}\n                            />\n                          </IconButton>\n                          <Typography\n                            component={'span'}\n                            variant={'body2'}\n                            display={'inline-flex'}\n                            textAlign={'center'}\n                            alignItems={'center'}\n                            color={'textSecondary'}\n                            marginTop={1 / 2}\n                            sx={{\n                              textIndent: 0,\n                              textAlign: 'center',\n                            }}\n                          >\n                            {t('labelVaultTradeSimpleBtn')}\n                          </Typography>\n                        </Box>\n                      </Box> */}\n                    </Box>\n                    <Divider style={{ marginTop: '-1px', width: '100%' }} />\n                  </>\n                )}\n              <Box padding={3} flex={1} display={'flex'} flexDirection={'column'}>\n                <MarketDetail\n                  etherscanBaseUrl={etherscanBaseUrl}\n                  isShow={detail.isShow}\n                  forexMap={forexMap}\n                  isLoading={detail.isLoading}\n                  showBtns={\n                    vaultAccountInfo &&\n                    [sdk.VaultAccountStatus.IN_STAKING].includes(vaultAccountInfo?.accountStatus)\n                  }\n                  onClickBuy={() => {\n                    const symbol = detail.detail?.tokenInfo.symbol?.slice(2)\n                    if (symbol === 'USDT') {\n                      onGoToSwap({ isSell: true })\n                    } else {\n                      onGoToSwap({ symbol})\n                    }\n                    \n                  }}\n                  onClickSell={() => {\n                    const symbol = detail.detail?.tokenInfo.symbol?.slice(2)\n                    if (symbol === 'USDT') {\n                      onGoToSwap({ isSell: false })  \n                    } else {\n                      onGoToSwap({ symbol, isSell: true })\n                    }\n                  }}\n                  {...{ ...detail?.detail }}\n                />\n              </Box>\n            </Box>\n            {!(\n              (vaultAccountInfo &&\n                [sdk.VaultAccountStatus.IN_STAKING].includes(vaultAccountInfo?.accountStatus)) ||\n              activeInfo?.hash\n            ) && (\n              <>\n                <Divider style={{ marginTop: '-1px', width: '100%' }} />\n                <Box\n                  padding={3}\n                  paddingY={1}\n                  display={'flex'}\n                  flexDirection={'column'}\n                  alignItems={'flex-end'}\n                  alignSelf={'stretch'}\n                  justifyContent={'stretch'}\n                >\n                  <Button\n                    size={'medium'}\n                    onClick={() => {\n                      history.push('/portal/portalDashboard')\n                      setShowDetail({ isShow: false })\n                      onJoinPop({})\n                    }}\n                    loading={'false'}\n                    variant={'contained'}\n                    sx={{ minWidth: 'var(--walletconnect-width)' }}\n                    disabled={\n                      joinBtnStatus === TradeBtnStatus.DISABLED ||\n                      joinBtnStatus === TradeBtnStatus.LOADING\n                    }\n                  >\n                    {joinBtnLabel}\n                  </Button>\n                </Box>\n              </>\n            )}\n          </Box>\n        </SwitchPanelStyled>\n      </Modal>\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/sharedPages/VaultPage/components/ModalWrap.tsx",
    "content": "import React from 'react'\nimport {\n  useNotify,\n  useVaultJoin,\n  useVaultLayer2,\n  useVaultLoan,\n  useVaultMap,\n  useVaultRedeem,\n} from '@loopring-web/core'\nimport {\n  Modal,\n  SmallOrderAlert,\n  SwapPanel,\n  Toast,\n  useOpenModals,\n  VaultExitPanel,\n  VaultJoinPanel,\n  VaultJoinPanelModal,\n  VaultLoanPanel,\n  VaultSwapCancel,\n} from '@loopring-web/component-lib'\nimport { useTheme } from '@emotion/react'\nimport {\n  TOAST_TIME,\n  TokenType,\n  TRADE_TYPE,\n  VaultAction,\n  VaultLoanType,\n  VaultSwapStep,\n} from '@loopring-web/common-resources'\nimport { useVaultSwapExtends } from './useVaultSwapExtends'\nimport { useTranslation } from 'react-i18next'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nexport const ModalVaultWrap = ({onClickLeverage}: {onClickLeverage: () => void}) => {\n  const { t } = useTranslation()\n  const { getVaultMap, tokenMap: vaultTokenMao, idIndex: vaultIndex, coinMap } = useVaultMap()\n  const theme = useTheme()\n  const { campaignTagConfig } = useNotify().notifyMap ?? {}\n  const {\n    modals: { isShowVaultExit, isShowVaultJoin, isShowVaultSwap, isShowVaultLoan },\n    setShowVaultJoin,\n    setShowVaultExit,\n    setShowVaultLoan,\n    setShowVaultSwap,\n    setShowNoVaultAccount,\n  } = useOpenModals()\n  const { vaultAccountInfo } = useVaultLayer2()\n  const [{ openCancel, shouldClose }, setOpenCancel] = React.useState({\n    openCancel: false,\n    shouldClose: false,\n  })\n  const exitVaultProps = useVaultRedeem()\n  // const {\n  //   // isMarketInit,\n  //   // toastOpen,\n  //   // closeToast,\n  //   // tradeCalcData,\n  //   // tradeData,\n  //   // swapBtnI18nKey,\n  //   // swapBtnStatus,\n  //   // handleSwapPanelEvent,\n  //   // refreshData,\n  //   // refreshRef,\n  //   // onSwapClick,\n  //   // tradeVault,\n  //   // isSwapLoading,\n  //   // market,\n  //   // isMobile,\n  //   // disabled,\n  //   // cancelBorrow,\n  //   // borrowedAmount,\n  //   // marginLevelChange,\n  //   // showSmallTradePrompt,\n  //   // setShowSmallTradePrompt,\n  //   // hideLeverage\n  // } = useVaultSwap({ path: 'portal' })\n  // const { BtnEle, maxEle } = useVaultSwapExtends({\n  //   tradeCalcData,\n  //   swapBtnI18nKey,\n  //   swapBtnStatus,\n  //   onSwapClick,\n  //   isSwapLoading,\n  //   disabled,\n  //   handleSwapPanelEvent,\n  //   tradeData,\n  //   toastOpen,\n  //   borrowedAmount\n  // })\n  const { vaultRepayProps, vaultBorrowProps, vaultLoanType, handleTabChange } = useVaultLoan()\n  return (\n    <>\n      {/* <Toast\n        alertText={toastOpen?.content ?? ''}\n        open={toastOpen?.open ?? false}\n        autoHideDuration={TOAST_TIME}\n        onClose={closeToast}\n        severity={toastOpen.type}\n      /> */}\n      {/* <Modal\n        contentClassName={'vault-wrap'}\n        open={isShowVaultSwap.isShow}\n        onClose={() => {\n          if (\n            (tradeCalcData as any)?.isVault &&\n            (tradeCalcData as any).step !== VaultSwapStep.Edit\n          ) {\n            setOpenCancel({ openCancel: true, shouldClose: true })\n          } else {\n            setShowVaultSwap({ isShow: false })\n          }\n        }}\n        content={\n          tradeData ? (\n            // @ts-ignore\n            <SwapPanel\n              _width={'var(--modal-width)'}\n              classWrapName={'vaultSwap'}\n              titleI8nKey={'labelVaultSwap'}\n              tokenBuyProps={{\n                tokenImageKey: tradeData?.buy?.belong?.slice(2),\n                belongAlice: tradeData?.buy?.belong?.slice(2),\n                tokenType: TokenType.vault,\n                disableInputValue: isMarketInit,\n                disabled: isSwapLoading || isMarketInit,\n                decimalsLimit: vaultTokenMao[tradeData?.buy?.belong?.toString() ?? '']?.precision,\n                allowDecimals: vaultTokenMao[tradeData?.buy?.belong?.toString() ?? '']?.precision\n                  ? true\n                  : false,\n              }}\n              covertOnClickPreCheck={() => {\n                if (\n                  (tradeCalcData as any)?.isVault &&\n                  (tradeCalcData as any).step !== VaultSwapStep.Edit\n                ) {\n                  setOpenCancel({ openCancel: true, shouldClose: true })\n                  return false\n                } else {\n                  return true\n                }\n              }}\n              onCancelClick={() => {\n                setOpenCancel({ openCancel: true, shouldClose: false })\n              }}\n              BtnEle={BtnEle}\n              tokenSellProps={{\n                decimalsLimit:\n                  vaultTokenMao[tradeData?.sell?.belong?.toString() ?? '']?.vaultTokenAmounts\n                    ?.qtyStepScale,\n                allowDecimals: vaultTokenMao[tradeData?.sell?.belong?.toString() ?? '']\n                  ?.vaultTokenAmounts?.qtyStepScale\n                  ? true\n                  : false,\n                tokenImageKey: tradeData?.sell?.belong?.slice(2),\n                belongAlice: tradeData?.sell?.belong?.slice(2),\n                tokenType: TokenType.vault,\n                subEle: maxEle,\n                subLabel: undefined,\n                disableInputValue: isMarketInit,\n                disabled: isSwapLoading || isMarketInit,\n                placeholderText:\n                  tradeCalcData.sellMaxAmtStr && tradeCalcData.sellMaxAmtStr !== ''\n                    ? t('labelBtradeSwapMiniMax', {\n                        minValue: tradeCalcData.sellMinAmtStr,\n                        maxValue: tradeCalcData.sellMaxAmtStr,\n                      })\n                    : t('labelBtradeSwapMini', {\n                        minValue: tradeCalcData.sellMinAmtStr,\n                      }),\n              }}\n              campaignTagConfig={campaignTagConfig}\n              tradeCalcData={tradeCalcData}\n              tradeData={tradeData as any}\n              onSwapClick={onSwapClick}\n              swapBtnI18nKey={swapBtnI18nKey}\n              swapBtnStatus={swapBtnStatus}\n              handleSwapPanelEvent={handleSwapPanelEvent}\n              onRefreshData={refreshData}\n              refreshRef={refreshRef}\n              tradeVault={tradeVault}\n              market={market}\n              isMobile={isMobile}\n              marginLevelChange={marginLevelChange!}\n              vaultLeverage={{\n                onClickLeverage: onClickLeverage,\n                leverage: vaultAccountInfo?.leverage ?? '0',\n                hideLeverage\n              }}\n              refreshTime={10}\n            />\n          ) : (\n            <></>\n          )\n        }\n      /> */}\n      {/* <SmallOrderAlert\n        open={showSmallTradePrompt.show}\n        handleClose={() => {\n          setShowSmallTradePrompt({\n            show: false,\n            estimatedFee: undefined,\n            minimumConverted: undefined,\n            feePercentage: undefined,\n          })\n        }}\n        handleConfirm={() => {\n          onSwapClick()\n        }}\n        estimatedFee={showSmallTradePrompt.estimatedFee ?? ''}\n        feePercentage={showSmallTradePrompt.feePercentage ?? ''}\n        minimumReceived={showSmallTradePrompt.minimumConverted ?? ''}\n      /> */}\n      <Modal\n        contentClassName={'vault-wrap'}\n        open={isShowVaultExit.isShow}\n        _width={'var(--modal-width)'}\n        onClose={() => {\n          setShowVaultExit({ isShow: false })\n        }}\n        content={<VaultExitPanel {...{ ...exitVaultProps }} />}\n      />\n      <Modal\n        open={isShowVaultLoan.isShow}\n        onClose={() => {\n          setShowVaultLoan({ isShow: false })\n        }}\n        content={\n          <VaultLoanPanel\n            vaultRepayProps={vaultRepayProps as any}\n            vaultBorrowProps={{...vaultBorrowProps, onClickLeverage} as any}\n            vaultLoanType={vaultLoanType as VaultLoanType}\n            handleTabChange={handleTabChange}\n          />\n        }\n      />\n      {/* <VaultSwapCancel\n        open={openCancel}\n        handleClose={(_, isAgree) => {\n          setOpenCancel({ openCancel: false, shouldClose: false })\n          if (isAgree) {\n            cancelBorrow(shouldClose)\n          }\n        }}\n      /> */}\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/sharedPages/VaultPage/components/TradePanel.tsx",
    "content": "import { Box, Typography } from '@mui/material'\nimport { useVaultSwap } from '../hooks/useVaultSwap'\nimport { VaultSwapView } from './VaultSwapView'\nimport { CloseIcon } from '@loopring-web/common-resources'\nimport { useConfirmation } from '@loopring-web/core/src/stores/localStore/confirmation'\n// import { SmallOrderAlert, Toast } from '../components/'\nimport { CloseAllConfirmModal } from './modals'\nimport { SmallOrderAlert, Toast } from '../../../components'\nimport { useSettings } from '../../../stores'\n\n\nexport const VaultTradePanel = () => {\n  const { vaultSwapModalProps, smallOrderAlertProps, toastProps, closeAllConfirmModalProps } = useVaultSwap()\n  const { confirmation, setShowVaultTradeHint } = useConfirmation()\n  const isMobile = useSettings().isMobile\n  return (\n    <Box display={'flex'} justifyContent={'center'} flexDirection={isMobile ? 'column' : 'row'} position='relative' my={5} alignItems={'start'}>\n      <Box\n        sx={{\n          position: 'relative',\n          height: confirmation.showVaultTradeHint ? 'auto' : 0,\n          borderRadius: '8px',\n          py: 2,\n          px: 3,\n          border: '1px solid var(--color-border)',\n          opacity: confirmation.showVaultTradeHint ? 1 : 0,\n          width: isMobile ? '92%' : '20%',\n          ml: isMobile ? '4%' : 0,\n          mr: isMobile ? '4%' : 3,\n          mb: isMobile ? 4 : 0,\n        }}\n      >\n        <Typography>Portal Trade</Typography>\n        <Typography mt={2} color={'var(--color-text-secondary)'}>\n          Loopring Portal functions as an isolated margin account, allowing users to borrow and lend\n          tokens using collateral. It enables leveraged trading and provides access to assets beyond\n          Ethereum.\n        </Typography>\n        <CloseIcon\n          onClick={() => setShowVaultTradeHint(false)}\n          fontSize={'large'}\n          sx={{\n            position: 'absolute',\n            top: 8,\n            right: 8,\n            cursor: 'pointer',\n            color: 'var(--color-text-secondary)',\n          }}\n        />\n      </Box>\n      <VaultSwapView {...vaultSwapModalProps} />\n      <Box width={'20%'} />\n      <SmallOrderAlert {...smallOrderAlertProps} />\n      <Toast {...toastProps} />\n      <CloseAllConfirmModal {...closeAllConfirmModalProps}/>\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/sharedPages/VaultPage/components/VaultPageUI.tsx",
    "content": "import { Box, Button, Container, Divider, Tab, Tabs, Typography } from '@mui/material'\nimport React from 'react'\nimport { HelpIcon, LOOPRING_DOCUMENT, OrderListIcon, SoursURL, VaultKey } from '@loopring-web/common-resources'\nimport {\n  Button as LoopringButton,\n  ConfirmVaultRisk,\n  EmptyDefault,\n  useSettings,\n} from '@loopring-web/component-lib'\nimport { VaultDashBoardPanel } from '../components/DashBoardPanel'\nimport { VaultHomePanel } from './HomePanel'\nimport { ModalVaultWrap } from '../components/ModalWrap'\nimport { useTranslation } from 'react-i18next'\nimport { VaultTradePanel } from '../components/TradePanel'\nimport { useModals } from '../hooks/useModals'\nimport { CloseConfirmModal } from './modals'\n\n\nexport interface VaultPageUIProps {\n  tabIndex: VaultKey\n  error: boolean\n  showLeverage: { show: boolean; closeAfterChange: boolean }\n  isShowConfirmedVault: { isShow: boolean }\n  vaultAccountInfo: any\n  marketArray: any[]\n  handleTabChange: (event: any, value: VaultKey) => void\n  handleConfirmVaultRiskClose: (event: any, isAgree: boolean) => void\n  toggleLeverage: () => void\n  closeLeverage: () => void\n  handleRecordClick: () => void\n  handleTutorialClick: () => void\n  getVaultMap: () => void\n}\n\nexport const VaultPageUI: React.FC<VaultPageUIProps> = ({\n  tabIndex,\n  error,\n  showLeverage,\n  isShowConfirmedVault,\n  vaultAccountInfo,\n  marketArray,\n  handleTabChange,\n  handleConfirmVaultRiskClose,\n  toggleLeverage,\n  closeLeverage,\n  handleRecordClick,\n  handleTutorialClick,\n  getVaultMap,\n}) => {\n  const { t } = useTranslation()\n  const { isMobile } = useSettings()\n  const { closeConfirmModalProps } = useModals()\n  return (\n    <Box flex={1} display={'flex'} flexDirection={'column'}>\n      <Container\n        maxWidth='lg'\n        style={{\n          display: 'flex',\n          flexDirection: 'column',\n        }}\n      >\n        <Box\n          display={'flex'}\n          justifyContent={'space-between'}\n          alignItems={'center'}\n          flexDirection={'row'}\n        >\n          <Tabs\n            variant={'scrollable'}\n            value={tabIndex}\n            sx={{\n              marginLeft: -2,\n            }}\n            onChange={handleTabChange}\n          >\n            <Tab\n              value={VaultKey.VAULT_DASHBOARD}\n              label={\n                <Typography display={'inline-flex'} alignItems={'center'}>\n                  <Typography\n                    component={'span'}\n                    variant={'h5'}\n                    whiteSpace={'pre'}\n                    className={'invest-Overview-Title'}\n                    color={\n                      tabIndex === VaultKey.VAULT_DASHBOARD\n                        ? 'var(--color-text-primary)'\n                        : 'var(--color-text-secondary)'\n                    }\n                  >\n                    {t('labelVaultHomeTitle')}\n                  </Typography>\n                </Typography>\n              }\n            />\n            <Tab\n              value={VaultKey.VAULT_HOME}\n              label={\n                <Typography display={'inline-flex'} alignItems={'center'}>\n                  <Typography\n                    component={'span'}\n                    variant={'h5'}\n                    whiteSpace={'pre'}\n                    className={'invest-Balance-Title'}\n                    color={\n                      tabIndex === VaultKey.VAULT_HOME\n                        ? 'var(--color-text-primary)'\n                        : 'var(--color-text-secondary)'\n                    }\n                  >\n                    {t('labelVaultMarketTitle')}\n                  </Typography>\n                </Typography>\n              }\n            />\n            <Tab\n              value={VaultKey.VAULT_TRADE}\n              label={\n                <Typography display={'inline-flex'} alignItems={'center'}>\n                  <Typography\n                    component={'span'}\n                    variant={'h5'}\n                    whiteSpace={'pre'}\n                    marginRight={1}\n                    className={'invest-Trade-Title'}\n                    color={\n                      tabIndex === VaultKey.VAULT_TRADE\n                        ? 'var(--color-text-primary)'\n                        : 'var(--color-text-secondary)'\n                    }\n                  >\n                    Trade\n                  </Typography>\n                </Typography>\n              }\n            />\n          </Tabs>\n          <Box\n            display={'flex'}\n            flexDirection={'row'}\n            marginTop={isMobile ? 2 : 'inherit'}\n            justifyContent={'space-between'}\n          >\n            <Button\n              startIcon={<HelpIcon fontSize={'inherit'} color={'inherit'} />}\n              variant={'text'}\n              onClick={() => {\n                window.open(`${LOOPRING_DOCUMENT}vault_tutorial_en.md`, '_blank')\n                window.opener = null\n              }}\n              sx={{ marginLeft: 2, color: 'var(--color-text-primary)' }}\n            >\n              {t('labelVaultTutorial')}\n            </Button>\n          </Box>\n        </Box>\n      </Container>\n      <Divider />\n      {!error && marketArray?.length ? (\n        <>\n          <ModalVaultWrap onClickLeverage={toggleLeverage} />\n          {tabIndex === VaultKey.VAULT_DASHBOARD && (\n            <VaultDashBoardPanel\n              vaultAccountInfo={vaultAccountInfo}\n              closeShowLeverage={closeLeverage}\n              showLeverage={showLeverage}\n            />\n          )}\n          {tabIndex === VaultKey.VAULT_HOME && (\n            <VaultHomePanel vaultAccountInfo={vaultAccountInfo} />\n          )}\n          {tabIndex === VaultKey.VAULT_TRADE && (\n            <VaultTradePanel vaultAccountInfo={vaultAccountInfo} />\n          )}\n        </>\n      ) : (\n        <Box\n          key={'empty'}\n          flexDirection={'column'}\n          display={'flex'}\n          justifyContent={'center'}\n          flex={1}\n          alignItems={'center'}\n        >\n          <EmptyDefault\n            emptyPic={\n              <img className='loading-gif' width='36' src={`${SoursURL}images/loading-line.gif`} />\n            }\n            message={() => {\n              return error ? (\n                <LoopringButton onClick={getVaultMap} variant={'contained'}>\n                  {t('labelVaultRefresh')}\n                </LoopringButton>\n              ) : (\n                <></>\n              )\n            }}\n          />\n        </Box>\n      )}\n      <ConfirmVaultRisk\n        open={isShowConfirmedVault.isShow}\n        handleClose={handleConfirmVaultRiskClose}\n      />\n      <CloseConfirmModal {...closeConfirmModalProps} />\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/sharedPages/VaultPage/components/VaultSwapView.tsx",
    "content": "import { Box, Typography, Modal, IconButton, Slider, Checkbox, Tooltip, Switch, Grid, Input, Select, MenuItem, Button as MuiButton } from '@mui/material'\nimport { CoinIcons, CountDownIcon, IconButtonStyled, InputSearch, SpaceBetweenBox, useSettings } from '@loopring-web/component-lib'\nimport { CheckBoxIcon, CheckedIcon, CloseIcon, CompleteIcon, EmptyValueTag, hexToRGB, Info2Icon, LoadingIcon, ReverseIcon, SwapSettingIcon, TokenType, WaitingIcon } from '@loopring-web/common-resources'\nimport { numberFormat } from '@loopring-web/core'\nimport _ from 'lodash';\nimport { useTranslation } from 'react-i18next';\nimport Decimal from 'decimal.js';\n// import styled from '@emotion/styled';\nimport { SlippagePanel } from '@loopring-web/component-lib/src/components/tradePanel/components';\nimport KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'\nimport { useTheme } from '@emotion/react';\nimport React from 'react';\nimport { marginLevelTypeToColor } from '@loopring-web/component-lib/src/components/tradePanel/components/VaultWrap/utils';\nimport EastIcon from '@mui/icons-material/East';\nimport { Popover } from '@mui/material';\nimport { styled } from '@mui/material';\n\nconst PopoverStyled = styled(Popover)`\n  .MuiPaper-elevation2 {\n    box-shadow: none;\n    padding: 0;\n    width: 250px;\n  }\n\n  .MuiBackdrop-root {\n    background: transparent;\n  }\n`\n\nconst BgButton = styled(MuiButton)<{ customBg: string }>`\n  background-color: ${({ customBg }) => customBg};\n  transition: all 0.2s ease-in-out;\n  &:hover {\n    background-color: ${({ customBg }) => customBg};\n    opacity: 0.8;\n  }\n  &:disabled {\n    background-color: var(--color-button-disabled);\n  }\n  \n`\n\n\nexport interface VaultSwapViewProps {\n  open: boolean\n  onClose: () => void\n  setting: {\n    hideLeverage?: boolean\n    onClickSettingLeverage: () => void\n    leverage: number\n    onSwitchChange: () => void\n    secondConfirmationChecked: boolean\n    settingPopoverOpen: boolean\n    onCloseSettingPopover: () => void\n    onClickSettingBtn: () => void\n    slippageList: string[]\n    currentSlippage: string\n    onSlippageChange: (slippage: string, customSlippage: string) => void\n  }\n  countdown: {\n    countDownSeconds: number\n    onRefreshData: () => void\n    ref: React.RefObject<any>\n  }\n  isLongOrShort: 'long' | 'short'\n  onClickBalance: () => void\n  onClickToken: () => void\n  balance: string\n  token: {\n    symbol: string\n    coinJSON: any\n  }\n  onInputAmount: (amount: string) => void\n  amountInput: string\n  inputPlaceholder: string\n  inputAlert: {\n    show: boolean\n    message: string\n    type: 'error' | 'warning' | 'success'\n    icon?: 'completed' | 'wait'\n  }\n  swapRatio: string\n  onClickReverse: () => void\n  maxTradeValue: string\n  borrowed: string\n  totalQuota: string\n  marginLevelChange: {\n    from: {\n      type: 'danger' | 'safe' | 'warning'\n      marginLevel: string\n    }\n    to?: {\n      type: 'danger' | 'safe' | 'warning'\n      marginLevel: string\n    } \n  }\n  hourlyInterestRate: string\n  tradingFee: string\n  tradingFeeDescription: string\n  slippageTolerance: string\n  myPositions:\n    | {\n        tokenSymbol: string\n        longOrShort: 'Long' | 'Short'\n        marginLevel: string\n        leverage: string\n        amount: string\n        // marketPrice: string\n        onClickLeverage: () => void\n        onClickTrade: () => void\n        onClickClose: () => void\n      }[]\n    | undefined\n  positionTypeSelection: {\n    onChange: (value: string) => void\n    items: [\n      {\n        label: string\n        value: string\n        tooltipTitle: string\n      },\n    ]\n    value: string\n  }\n  leverageSelection: {\n    onChange: (value: string) => void\n    items: [\n      {\n        label: string\n        value: string\n        disabled?: boolean\n      },\n    ]\n    value: string\n  }\n  ratioSlider: {\n    currentRatio?: number\n    onClickRatio: (no: number) => void\n  }\n  hideOther: boolean\n  onClickHideOther: () => void\n  onClickLongShort: (v: 'long' | 'short') => void\n  tokenSelection: {\n    show: boolean,\n    search: string,\n    onInputSearch: (search: string) => void\n    tokens: {\n      coinJSON: any,\n      symbol: string,\n      amount: string,\n      onClick: () => void\n    }[]\n    onClickCancel: () => void\n  }\n  tradeBtn: {\n    disabled: boolean,\n    label?: string\n    onClick: () => void\n    loading?: boolean\n    bgColor?: string\n  }\n  mainViewRef: React.RefObject<HTMLDivElement>\n  onClickCloseAll: () => void\n  onClickMax: () => void\n  amounInUSDT: string\n  moreToBeBorrowed: string\n  showMyPositions: boolean\n  showLeverageSelect: boolean\n}\n\nexport const VaultSwapView = (props: VaultSwapViewProps) => {\n  const {\n    moreToBeBorrowed,\n    onClickMax,\n    amounInUSDT,\n    setting: {\n      hideLeverage,\n      onClickSettingLeverage,\n      leverage,\n      onSwitchChange,\n      secondConfirmationChecked,\n      onCloseSettingPopover,\n      settingPopoverOpen,\n      onClickSettingBtn,\n      slippageList,\n      currentSlippage,\n      onSlippageChange,\n    },\n    countdown,\n    isLongOrShort,\n    onClickBalance,\n    balance,\n    onClickToken,\n    token,\n    onInputAmount,\n    amountInput,\n    inputPlaceholder,\n    inputAlert,\n    swapRatio,\n    onClickReverse,\n    maxTradeValue,\n    borrowed,\n    totalQuota,\n    marginLevelChange,\n    hourlyInterestRate,\n    tradingFee,\n    tradingFeeDescription,\n    slippageTolerance ,\n    myPositions,\n    leverageSelection,\n    positionTypeSelection,\n    ratioSlider,\n    hideOther,\n    onClickHideOther,\n    onClickLongShort,\n    tokenSelection,\n    tradeBtn,\n    mainViewRef,\n    onClickCloseAll,\n    showMyPositions,\n    showLeverageSelect\n  } = props\n  const { t } = useTranslation()\n  const theme = useTheme()\n  const settingPopoverId = 'setting'\n  const anchorRef = React.useRef<HTMLButtonElement>(null);\n  const isMobile = useSettings().isMobile\n\n  const mainView = (\n    <Box\n      bgcolor={'var(--color-box)'}\n      border={'1px solid var(--color-border)'}\n      borderRadius={'12px'}\n      display={'flex'}\n      alignItems={'center'}\n      flexDirection={'column'}\n      position={'relative'}\n      ref={mainViewRef}\n      sx={{\n        width: isMobile ? '92%' : 'var(--modal-width)',\n        mx: isMobile ? '4%' : 0,\n      }}\n    >\n      <Box\n        px={3}\n        py={2}\n        borderBottom={'1px solid var(--color-divide)'}\n        display={'flex'}\n        justifyContent={'space-between'}\n        width={'100%'}\n        alignItems={'center'}\n      >\n        <Box display={'flex'} flexDirection={'row'} alignItems={'center'}>\n          <Typography mr={1 / 2} variant='h4'>\n            Portal Trade\n          </Typography>\n          <Tooltip\n            title={\n              \"To trade on Portal with leverage, you first need to borrow assets. If you're unable to execute the full amount, a portion of the borrowed assets may remain unused. The Auto Repay feature ensures any remaining borrowed assets are automatically repaid, helping you avoid unnecessary interest charges.\"\n            }\n            sx={{ ml: 1 / 2 }}\n          >\n            <Typography display={'flex'} alignItems={'center'}>\n              <Info2Icon color={'inherit'} />\n            </Typography>\n          </Tooltip>\n        </Box>\n\n        <Box display={'flex'} alignItems={'center'}>\n          <Box>\n            <IconButtonStyled\n              onClick={(e) => {\n                onClickSettingBtn()\n              }}\n              sx={{ backgroundColor: 'var(--field-opacity)' }}\n              className={'switch outlined'}\n              aria-label='to Transaction'\n              aria-describedby={settingPopoverId}\n              size={'large'}\n              ref={anchorRef}\n            >\n              <SwapSettingIcon htmlColor={'var(--color-logo)'} />\n            </IconButtonStyled>\n            <PopoverStyled\n              id={settingPopoverId}\n              open={settingPopoverOpen}\n              onClose={onCloseSettingPopover}\n              anchorOrigin={{\n                vertical: 'bottom',\n                horizontal: 'left',\n              }}\n              sx={{ background: 'transparent' }}\n              anchorEl={anchorRef.current}\n            >\n              <Box\n                paddingX={2}\n                paddingTop={2}\n                paddingBottom={4}\n                display={'flex'}\n                flexDirection={'column'}\n              >\n                <Box paddingBottom={1}>\n                  <Typography marginBottom={1} component={'span'}>\n                    {t('labelSwapSettingTitle')}\n                  </Typography>\n                  <Typography\n                    marginBottom={1}\n                    paddingLeft={1}\n                    variant={'body2'}\n                    color={'var(--color-text-third)'}\n                    component={'span'}\n                  >\n                    {t('swapTolerance')}\n                  </Typography>\n                </Box>\n                <SlippagePanel\n                  t={t}\n                  max={100}\n                  slippageList={slippageList}\n                  slippage={currentSlippage}\n                  handleChange={(slippage, customSlippage) => {\n                    onSlippageChange(slippage, customSlippage)\n                  }}\n                />\n                {!hideLeverage && (\n                  <Grid\n                    container\n                    justifyContent={'space-between'}\n                    direction={'row'}\n                    alignItems={'center'}\n                    height={24}\n                    marginTop={2.5}\n                  >\n                    <Typography\n                      component={'span'}\n                      variant='body2'\n                      color={'textSecondary'}\n                      display={'inline-flex'}\n                      alignItems={'center'}\n                    >\n                      {' ' + t('labelVaultLeverage')}\n                    </Typography>\n                    <Typography\n                      component={'span'}\n                      variant='body2'\n                      color={'textSecondary'}\n                      display={'inline-flex'}\n                      alignItems={'center'}\n                      sx={{ textDecoration: 'underline', cursor: 'pointer' }}\n                      mr={1.5}\n                      onClick={onClickSettingLeverage}\n                    >\n                      {leverage}x\n                    </Typography>\n                  </Grid>\n                )}\n                <Grid\n                  container\n                  justifyContent={'space-between'}\n                  direction={'row'}\n                  alignItems={'center'}\n                  height={24}\n                  marginTop={1}\n                >\n                  <Tooltip\n                    title={t('labelSwapSettingSecondConfirmTootip').toString()}\n                    placement={'bottom'}\n                  >\n                    <Typography\n                      component={'span'}\n                      variant='body2'\n                      color={'textSecondary'}\n                      display={'inline-flex'}\n                      alignItems={'center'}\n                    >\n                      <Info2Icon fontSize={'small'} color={'inherit'} sx={{ marginX: 1 / 2 }} />\n                      {' ' + t('labelSwapSettingSecondConfirm')}\n                    </Typography>\n                  </Tooltip>\n                  <Switch\n                    onChange={() => {\n                      onSwitchChange()\n                    }}\n                    checked={secondConfirmationChecked}\n                  />\n                </Grid>\n              </Box>\n            </PopoverStyled>\n          </Box>\n\n          <Box display={'inline-block'} ml={2} component={'span'}>\n            <CountDownIcon {...countdown} />\n          </Box>\n          {/* <IconButton\n            sx={{\n              ml: 1,\n            }}\n            size={'large'}\n            aria-label={t('labelClose')}\n            color={'inherit'}\n            onClick={(event) => {\n              onClose()\n            }}\n          >\n            <CloseIcon />\n          </IconButton> */}\n        </Box>\n      </Box>\n\n      <Box width={'100%'} ref={mainViewRef}>\n        <Box mt={2} width={'100%'} px={3}>\n          <BgButton\n            variant='contained'\n            sx={{\n              clipPath: 'polygon(0 0, 100% 0, 90% 100%, 0 100%, 0 0)',\n              width: '52%',\n              borderRadius: '4px',\n              borderTopRightRadius: '0',\n              borderBottomRightRadius: '0',\n              color:\n                isLongOrShort === 'long' || theme.mode === 'dark'\n                  ? 'var(--color-text)'\n                  : 'var(--color-black)',\n            }}\n            customBg={\n              isLongOrShort === 'long' ? 'var(--color-success)' : 'var(--color-box-secondary)'\n            }\n            onClick={() => onClickLongShort('long')}\n          >\n            Buy / Long\n          </BgButton>\n          <BgButton\n            variant='contained'\n            sx={{\n              clipPath: 'polygon(10% 0, 100% 0, 100% 100%, 0 100%, 10% 0)',\n              width: '52%',\n              borderRadius: '4px',\n              borderTopLeftRadius: '0',\n              borderBottomLeftRadius: '0',\n              ml: '-4%',\n              color:\n                isLongOrShort === 'short' || theme.mode === 'dark'\n                  ? 'var(--color-text)'\n                  : 'var(--color-black)',\n            }}\n            customBg={\n              isLongOrShort === 'short' ? 'var(--color-error)' : 'var(--color-box-secondary)'\n            }\n            onClick={() => onClickLongShort('short')}\n          >\n            Sell / Short\n          </BgButton>\n        </Box>\n\n        <Box mt={2} width={'100%'} px={3}>\n          {/* <Tooltip\n            title={\n              positionTypeSelection.items.find((item) => item.value === positionTypeSelection.value)\n                ?.tooltipTitle ?? ''\n            }\n          > */}\n          <Select\n            value={positionTypeSelection.value}\n            onChange={(e, v) => positionTypeSelection.onChange(e.target.value)}\n            displayEmpty\n            size='small'\n          >\n            {positionTypeSelection.items.map((item) => (\n              <MenuItem key={item.value} value={item.value}>\n                {item.label}\n              </MenuItem>\n            ))}\n          </Select>\n          {/* </Tooltip> */}\n\n          {showLeverageSelect && <Select\n            value={leverageSelection.value}\n            sx={{ ml: 2 }}\n            size='small'\n            onChange={(e, v) => leverageSelection.onChange(e.target.value)}\n            label={leverageSelection.value + 'x'}\n            displayEmpty\n          >\n            {leverageSelection.items.map((item) => (\n              <MenuItem disabled={item.disabled} key={item.value} value={item.value}>\n                {item.label}\n              </MenuItem>\n            ))}\n          </Select>}\n        </Box>\n        <Box mt={2} width={'100%'} px={3}>\n          <Typography mb={0.5} fontSize={'14px'} color={'var(--color-text-third)'}>\n            Amount\n          </Typography>\n          {/* <SpaceBetweenBox\n              mb={0.5}\n              leftNode={\n                <Typography fontSize={'14px'} color={'var(--color-text-third)'}>\n                  Amount\n                </Typography>\n              }\n              rightNode={\n                \n              }\n            /> */}\n          <Input\n            sx={{\n              height: '48px',\n              bgcolor: 'var(--color-bg-secondary)',\n              textAlign: 'right',\n              px: 2,\n              fontSize: '20px',\n            }}\n            placeholder={inputPlaceholder}\n            disableUnderline\n            fullWidth\n            startAdornment={\n              <Box\n                display={'flex'}\n                alignItems={'center'}\n                component={'div'}\n                sx={{ cursor: 'pointer' }}\n                onClick={onClickToken}\n              >\n                <CoinIcons type={TokenType.single} tokenIcon={[token.coinJSON]} />\n                <Typography ml={0.5} fontSize={'16px'} color={'var(--color-text-primary)'}>\n                  {token.symbol}\n                </Typography>\n                <KeyboardArrowDownIcon\n                  sx={{ ml: 0.5, color: 'var(--color-text-secondary)' }}\n                ></KeyboardArrowDownIcon>\n              </Box>\n            }\n            inputProps={{ sx: { textAlign: 'right' } }}\n            onInput={(e: any) => onInputAmount(e.target.value)}\n            value={amountInput}\n          />\n          <Box\n            display={'flex'}\n            justifyContent={'end'}\n            alignItems={'center'}\n            sx={{\n              opacity: inputAlert.show ? 1 : 0,\n              mt: -1,\n              color:\n                inputAlert.type === 'error'\n                  ? 'var(--color-error)'\n                  : inputAlert.type === 'warning'\n                  ? 'var(--color-warning)'\n                  : 'var(--color-success)',\n            }}\n          >\n            {inputAlert.icon === 'wait' ? (\n              <WaitingIcon />\n            ) : (\n              inputAlert.icon === 'completed' && <CompleteIcon />\n            )}\n            <Typography\n              sx={{\n                textAlign: 'right',\n                color:\n                  inputAlert.type === 'error'\n                    ? 'var(--color-error)'\n                    : inputAlert.type === 'warning'\n                    ? 'var(--color-warning)'\n                    : 'var(--color-success)',\n                fontSize: '12px',\n                ml: 0.5,\n              }}\n            >\n              {inputAlert.message || '--'}\n            </Typography>\n          </Box>\n        </Box>\n        <Box mx={3}>\n          <Slider\n            value={ratioSlider.currentRatio ? ratioSlider.currentRatio * 100 : 0}\n            onChange={(e, value) => {\n              ratioSlider.onClickRatio(\n                new Decimal(value as number).div(100).toDecimalPlaces(2).toNumber(),\n              )\n            }}\n            min={0}\n            max={100}\n            valueLabelDisplay={'on'}\n            valueLabelFormat={(value) => `${new Decimal(value).toFixed(0)}%`}\n            step={1}\n            marks={[\n              { value: 0, label: '' },\n              { value: 25, label: '' },\n              { value: 50, label: '' },\n              { value: 75, label: '' },\n              { value: 100, label: '' },\n            ]}\n            size='small'\n          />\n        </Box>\n        <Box\n          borderRadius={'8px'}\n          mx={3}\n          mt={2}\n          display={'flex'}\n          bgcolor={'var(--color-bg)'}\n          border={'1px solid var(--color-border)'}\n          justifyContent={'center'}\n          alignItems={'center'}\n          height={'48px'}\n        >\n          <Typography fontSize={16}>{amounInUSDT}</Typography>\n        </Box>\n        <Box mt={2} width={'100%'} display={'flex'} justifyContent={'center'}>\n          <Typography fontSize='12px' display={'flex'} alignItems={'center'}>\n            {swapRatio} <ReverseIcon sx={{ ml: 0.5, cursor: 'pointer' }} onClick={onClickReverse} />\n          </Typography>\n        </Box>\n        <Box pb={2} mt={2} width={'100%'} px={3} borderBottom={'1px solid var(--color-border)'}>\n          <SpaceBetweenBox\n            leftNode={\n              <Tooltip title={`The quantity you currently hold.`}>\n                <Typography\n                  display={'flex'}\n                  alignItems={'center'}\n                  variant={'body2'}\n                  color={'var(--color-text-third)'}\n                >\n                  Available <Info2Icon sx={{ ml: 0.5 }} />\n                </Typography>\n              </Tooltip>\n            }\n            rightNode={\n              <Typography\n                component={'p'}\n                onClick={onClickBalance}\n                sx={{ textDecoration: 'underline', cursor: 'pointer' }}\n                variant={'body2'}\n                color={'var(--color-text-primary)'}\n              >\n                {balance}\n              </Typography>\n            }\n          />\n          <SpaceBetweenBox\n            leftNode={\n              <Tooltip\n                title={\n                  <>\n                    Max = Current holdings + borrowing limit\n                    <br />\n                    The borrowing limit is determined by the value of your collateral and your net\n                    equity in this portal account. If the requested amount exceeds your current\n                    holdings, the system will automatically borrow the required asset.\n                  </>\n                }\n              >\n                <Typography\n                  display={'flex'}\n                  alignItems={'center'}\n                  variant={'body2'}\n                  color={'var(--color-text-third)'}\n                >\n                  Max <Info2Icon sx={{ ml: 0.5 }} />\n                </Typography>\n              </Tooltip>\n            }\n            rightNode={\n              <Typography\n                onClick={onClickMax}\n                sx={{ textDecoration: 'underline', cursor: 'pointer' }}\n                variant={'body2'}\n                color={'var(--color-text-primary)'}\n              >\n                {maxTradeValue}\n              </Typography>\n            }\n            mt={1}\n          />\n          <SpaceBetweenBox\n            mt={1}\n            leftNode={\n              <Tooltip\n                title={\n                  'The amount borrowed from the system to fulfill the trade request, subject to an hourly interest rate.'\n                }\n              >\n                <Typography\n                  display={'flex'}\n                  alignItems={'center'}\n                  variant={'body2'}\n                  color={'var(--color-text-third)'}\n                >\n                  Borrow <Info2Icon sx={{ ml: 0.5 }} />\n                </Typography>\n              </Tooltip>\n            }\n            rightNode={\n              <Typography variant={'body2'} color={'var(--color-text-primary)'}>\n                {moreToBeBorrowed}\n              </Typography>\n            }\n          />\n        </Box>\n        <Box mt={2} width={'100%'} px={3}>\n          <SpaceBetweenBox\n            leftNode={\n              <Tooltip title={'Total Quota is the maximum allowable trading amount.'}>\n                <Typography\n                  display={'flex'}\n                  alignItems={'center'}\n                  variant={'body2'}\n                  color={'var(--color-text-third)'}\n                >\n                  Total Quota <Info2Icon sx={{ ml: 0.5 }} />\n                </Typography>\n              </Tooltip>\n            }\n            rightNode={\n              <Typography variant={'body2'} color={'var(--color-text-primary)'}>\n                {totalQuota}\n              </Typography>\n            }\n          />\n          <SpaceBetweenBox\n            mt={1}\n            leftNode={\n              <Typography\n                display={'flex'}\n                alignItems={'center'}\n                variant={'body2'}\n                color={'var(--color-text-third)'}\n              >\n                Margin Level\n              </Typography>\n            }\n            rightNode={\n              <Box display={'flex'} alignItems={'center'}>\n                {marginLevelChange ? (\n                  <>\n                    <Typography color={marginLevelTypeToColor(marginLevelChange.from.type)}>\n                      {numberFormat(marginLevelChange.from.marginLevel, { fixed: 2 })}\n                    </Typography>\n                    {marginLevelChange.to && (\n                      <>\n                        <EastIcon sx={{ marginX: 0.5 }} />\n                        <Typography color={marginLevelTypeToColor(marginLevelChange.to.type)}>\n                          {numberFormat(marginLevelChange.to.marginLevel, { fixed: 2 })}\n                        </Typography>\n                      </>\n                    )}\n                  </>\n                ) : (\n                  EmptyValueTag\n                )}\n              </Box>\n            }\n          />\n\n          <SpaceBetweenBox\n            mt={1}\n            leftNode={\n              <Tooltip title={tradingFeeDescription}>\n                <Typography\n                  display={'flex'}\n                  alignItems={'center'}\n                  variant={'body2'}\n                  color={'var(--color-text-third)'}\n                >\n                  Trading Fee (est.) <Info2Icon sx={{ ml: 0.5 }} />\n                </Typography>\n              </Tooltip>\n            }\n            rightNode={\n              <Typography variant={'body2'} color={'var(--color-text-primary)'}>\n                {tradingFee}\n              </Typography>\n            }\n          />\n          <SpaceBetweenBox\n            mt={1}\n            leftNode={\n              <Tooltip\n                title={\n                  'Your trade will revert if the price changes unfavorably by more than this percentage.'\n                }\n              >\n                <Typography\n                  display={'flex'}\n                  alignItems={'center'}\n                  variant={'body2'}\n                  color={'var(--color-text-third)'}\n                >\n                  Slippage Tolerance <Info2Icon sx={{ ml: 0.5 }} />\n                </Typography>\n              </Tooltip>\n            }\n            rightNode={\n              <Typography variant={'body2'} color={'var(--color-text-primary)'}>\n                {slippageTolerance}\n              </Typography>\n            }\n          />\n          <BgButton\n            sx={{\n              mt: 2,\n              mb: 3,\n              fontSize: 'clamp(10px, 5vw, 16px)',\n              lineHeight: 1.2,\n            }}\n            variant='contained'\n            customBg={tradeBtn.bgColor}\n            size='large'\n            fullWidth\n            onClick={tradeBtn.onClick}\n            disabled={tradeBtn.disabled}\n          >\n            {tradeBtn.loading ? (\n              <LoadingIcon className='custom-size' sx={{ fontSize: 24 }} />\n            ) : tradeBtn.label ? (\n              <Typography color={'inherit'} noWrap={false}>\n                {tradeBtn.label}\n              </Typography>\n            ) : isLongOrShort === 'long' ? (\n              'Buy / Long'\n            ) : (\n              'Sell / Short'\n            )}\n          </BgButton>\n        </Box>\n        <Box bgcolor={'var(--color-box-secondary)'} width={'100%'} height={'4px'}></Box>\n\n        {showMyPositions && <Box width={'100%'} my={3} pt={2}>\n          <Typography px={3} variant='h5' mb={2}>\n            My Positions\n          </Typography>\n          <Box px={3} display={'flex'} justifyContent={'space-between'} alignItems={'center'}>\n            <Typography display={'flex'} alignItems={'center'} color={'var(--color-text-third)'}>\n              <Checkbox\n                checked={hideOther}\n                onChange={() => {\n                  onClickHideOther()\n                }}\n                sx={{\n                  width: '16px',\n                  height: '16px',\n                  mr: 1,\n                  ml: -0.25,\n                }}\n                checkedIcon={<CheckedIcon />}\n                icon={<CheckBoxIcon />}\n                color='default'\n              />\n              Hide other tokens\n            </Typography>\n\n            {/* <BgButton\n                variant='contained'\n                size='small'\n                customBg='var(--color-button-outlined)'\n                onClick={onClickCloseAll}\n                sx={{\n                  fontSize: '11px',\n                  borderRadius: '4px',\n                  width: '70px',\n                  height: '24px',\n                }}\n              >\n                Close All\n              </BgButton> */}\n          </Box>\n\n          <Box>\n            {myPositions?.length === 0 && (\n              <Box\n                width={'100%'}\n                height={'150px'}\n                display={'flex'}\n                justifyContent={'center'}\n                alignItems={'center'}\n              >\n                <Typography variant='body2'>No positions</Typography>\n              </Box>\n            )}\n            {myPositions?.map((item) => {\n              return (\n                <Box\n                  key={item.tokenSymbol}\n                  py={3}\n                  px={3}\n                  borderBottom={'1px solid var(--color-border)'}\n                >\n                  <Box display={'flex'} alignItems={'center'}>\n                    <Typography fontSize={'17px'}>{item.tokenSymbol}</Typography>\n                    <Typography\n                      ml={1}\n                      fontSize={'12px'}\n                      borderRadius={'4px'}\n                      px={1}\n                      color={\n                        item.longOrShort === 'Long'\n                          ? theme.colorBase.success\n                          : theme.colorBase.error\n                      }\n                      bgcolor={hexToRGB(\n                        item.longOrShort === 'Long'\n                          ? theme.colorBase.success\n                          : theme.colorBase.error,\n                        0.2,\n                      )}\n                    >\n                      {item.longOrShort}\n                    </Typography>\n                    {/* <Box\n                          color={\n                            marginLevelType(item.marginLevel) === 'warning'\n                              ? theme.colorBase.warning\n                              : marginLevelType(item.marginLevel) === 'danger'\n                              ? theme.colorBase.error\n                              : theme.colorBase.success\n                          }\n                          bgcolor={hexToRGB(\n                            marginLevelType(item.marginLevel) === 'warning'\n                              ? theme.colorBase.warning\n                              : marginLevelType(item.marginLevel) === 'danger'\n                              ? theme.colorBase.error\n                              : theme.colorBase.success,\n                            0.2,\n                          )}\n                          ml={1}\n                          display={'flex'}\n                          alignItems={'center'}\n                          fontSize={'13px'}\n                          borderRadius={'4px'}\n                          py={0.15}\n                          px={0.5}\n                        >\n                          <MarginLevelIcon sx={{ mr: 0.5 }} />\n                          {item.marginLevel}\n                        </Box> */}\n                  </Box>\n                  <Typography variant='body2' color={'var(--color-text-third)'}>\n                    Cross {item.leverage}\n                  </Typography>\n                  <Box display={'flex'} alignItems={'center'} mt={2.5}>\n                    <Box>\n                      <Typography variant='body2'>Amount</Typography>\n                      <Typography>{item.amount}</Typography>\n                    </Box>\n                    {/* <Box ml={'30%'}>\n                    <Typography variant='body2'>Market Price (USDT)</Typography>\n                    <Typography>{item.marketPrice}</Typography>\n                  </Box> */}\n                  </Box>\n                  <Box display={'flex'} alignItems={'center'} mt={2.5}>\n                    <BgButton\n                      variant='contained'\n                      size='small'\n                      customBg='var(--color-button-outlined)'\n                      sx={{\n                        width: '32%',\n                        borderRadius: '4px',\n                        fontSize: '14px',\n                        color: theme.mode === 'light' ? 'var(--color-black)' : 'var(--color-white)',\n                      }}\n                      onClick={item.onClickTrade}\n                    >\n                      Trade\n                    </BgButton>\n                    <BgButton\n                      variant='contained'\n                      size='small'\n                      customBg='var(--color-button-outlined)'\n                      sx={{\n                        width: '32%',\n                        ml: '2%',\n                        borderRadius: '4px',\n                        fontSize: '14px',\n                        color: theme.mode === 'light' ? 'var(--color-black)' : 'var(--color-white)',\n                      }}\n                      onClick={item.onClickClose}\n                    >\n                      Close\n                    </BgButton>\n                  </Box>\n                </Box>\n              )\n            })}\n          </Box>\n        </Box>}\n      </Box>\n\n      {/* <Box width={'100%'} mt={2} px={3}>\n          <BgButton\n            variant='contained'\n            customBg={isLongOrShort === 'long' ? 'var(--color-success)' : 'var(--color-error)'}\n            size='large'\n            fullWidth\n            onClick={tradeBtn.onClick}\n            disabled={tradeBtn.disabled}\n          >\n            {tradeBtn.loading ? (\n              <LoadingIcon className='custom-size' sx={{ fontSize: 24 }} />\n            ) : tradeBtn.label ? (\n              tradeBtn.label\n            ) : isLongOrShort === 'long' ? (\n              'Buy/Long'\n            ) : (\n              'Sell/Short'\n            )}\n          </BgButton>\n        </Box> */}\n    </Box>\n  )\n\n  const tokenSelectionModal = (\n    <Modal\n      sx={{\n        height: '100%',\n        display: 'flex',\n        justifyContent: 'center',\n        alignItems: 'center',\n      }}\n      open={tokenSelection.show}\n      onClose={tokenSelection.onClickCancel}\n    >\n      <Box\n        bgcolor={'var(--color-box)'}\n        width={'350px'}\n        maxWidth={'90%'}\n        height={'400px'}\n        overflow={'auto'}\n        borderRadius={1}\n        display={'flex'}\n        flexDirection={'column'}\n        py={4}\n        \n      >\n        <Box px={2.5} display={'flex'} justifyContent={'space-between'} alignItems={'center'}>\n          <InputSearch\n            value={tokenSelection.search}\n            style={{ width: '80%' }}\n            onChange={(value: string) => {\n              tokenSelection.onInputSearch(value)\n            }}\n          />\n          <Typography sx={{ cursor: 'pointer' }} onClick={tokenSelection.onClickCancel}>\n            Cancel\n          </Typography>\n        </Box>\n        <Box\n          display={'flex'}\n          flexDirection={'column'}\n          mt={2}\n          height={'85%'}\n          \n          sx={{ overflowY: 'auto' }}\n        >\n          {tokenSelection.tokens.map((item) => (\n            <SpaceBetweenBox\n              px={2.5}\n              onClick={item.onClick}\n              py={1}\n              alignItems={'center'}\n              leftNode={\n                <Box display={'flex'} alignItems={'center'}>\n                  <CoinIcons type={TokenType.single} tokenIcon={[item.coinJSON, undefined]} />\n                  <Typography ml={1.5}>{item.symbol}</Typography>\n                </Box>\n              }\n              rightNode={\n                <Typography color={'var(--color-text-secondary)'}>{item.amount}</Typography>\n              }\n              key={item.symbol}\n              sx={{\n                cursor: 'pointer',\n                '&:hover': {\n                  bgcolor: 'var(--color-box-hover)',\n                },\n              }}\n            />\n          ))}\n        </Box>\n      </Box>\n    </Modal>\n  )\n\n  return (\n    <>\n      {mainView}\n      {tokenSelectionModal}\n    </>\n  )\n}\n\n"
  },
  {
    "path": "packages/component-lib/src/sharedPages/VaultPage/components/modals.tsx",
    "content": "import { Box, Typography, Modal, Divider, IconButton, Slider, Checkbox, Tooltip, Popover, Switch, Grid, Button as MuiButton, Input, Select, MenuItem, ButtonProps, styled, CircularProgress } from '@mui/material'\nimport { AvatarCoin, Button, CoinIcon, CoinIcons, CountDownIcon, IconButtonStyled, InputSearch, Loading, LoadingStyled, ModalCloseButtonPosition, SpaceBetweenBox, SwapTradeData } from '@loopring-web/component-lib'\nimport { BackIcon, CheckBoxIcon, CheckedIcon, CloseIcon, CompleteIcon, EmptyValueTag, hexToRGB, Info2Icon, InfoIcon, LoadingIcon, mapSpecialTokenName, MarginLevelIcon, OrderListIcon, ReverseIcon, SwapSettingIcon, TokenType, WaitingIcon } from '@loopring-web/common-resources'\nimport { numberFormat, VaultTradeTradeData, ViewAccountTemplate } from '@loopring-web/core'\nimport AddIcon from '@mui/icons-material/Add';\nimport RemoveIcon from '@mui/icons-material/Remove';\nimport _ from 'lodash';\nimport ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos';\nimport { useTranslation } from 'react-i18next';\nimport Decimal from 'decimal.js';\nimport {\n  CollateralDetailsModalProps,\n  MaximumCreditModalProps,\n  LeverageModalProps,\n  DebtModalProps,\n  DustCollectorProps,\n  DustCollectorUnAvailableModalProps\n} from '../interface';\n// import styled from '@emotion/styled';\nimport { RiskComponent, RiskInformation, SlippagePanel } from '@loopring-web/component-lib/src/components/tradePanel/components';\nimport KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'\nimport { useTheme } from '@emotion/react';\nimport { current } from '@reduxjs/toolkit';\nimport React from 'react';\nimport { marginLevelTypeToColor } from '@loopring-web/component-lib/src/components/tradePanel/components/VaultWrap/utils';\nimport EastIcon from '@mui/icons-material/East';\nimport { marginLevelType } from '@loopring-web/core/src/hooks/useractions/vault/utils';\nimport { VaultSwapViewProps, VaultSwapView } from './VaultSwapView';\n\nexport const CollateralDetailsModal = (props: CollateralDetailsModalProps) => {\n  const { open, onClose, collateralTokens, totalCollateral, maxCredit, onClickMaxCredit, coinJSON } = props\n  const { t } = useTranslation()\n  return (\n    <Modal open={open} onClose={onClose}>\n      <Box height={'100%'} display={'flex'} justifyContent={'center'} alignItems={'center'}>\n        <Box\n          bgcolor={'var(--color-box)'}\n          width={'var(--modal-width)'}\n          height={'600px'}\n          borderRadius={1}\n          display={'flex'}\n          flexDirection={'column'}\n        >\n          <Box\n            paddingX={1.5}\n            paddingY={1.5}\n            display={'flex'}\n            justifyContent={'space-between'}\n            alignItems={'center'}\n          >\n            <Typography variant={'h5'}>{t('labelVaultCollateralDetails')}</Typography>\n            <CloseIcon\n              style={{\n                height: '20px',\n                width: '20px',\n              }}\n              sx={{\n                cursor: 'pointer',\n                fontSize: '24px',\n                marginRight: 1.5,\n                color: 'var(--color-text-third)',\n              }}\n              onClick={onClose}\n            />\n          </Box>\n          <Divider style={{ marginTop: '-1px', width: '100%' }} />\n          <Box paddingX={3}>\n            <Box marginTop={3}>\n              <Box>\n                <Typography variant={'body2'} color={'var(--color-text-third)'}>\n                  {t('labelVaultTotalCollateral')}\n                </Typography>\n                <Typography mt={0.5} variant={'h4'}>\n                  {totalCollateral}\n                </Typography>\n              </Box>\n              <Box mt={3}>\n                <Typography variant={'body2'} color={'var(--color-text-third)'}>\n                  {t('labelVaultMaximumCredit')}\n                </Typography>\n                <Typography mt={0.5} variant={'h4'}>\n                  {maxCredit}\n                </Typography>\n              </Box>\n            </Box>\n            \n            <Typography\n              marginBottom={3}\n              marginTop={2}\n              variant='body2'\n              color={'var(--color-text-secondary)'}\n              px={2}\n              py={1}\n              bgcolor={'var(--color-box-secondary)'}\n              borderRadius={'8px'}\n              display={'flex'}\n              flexDirection={'row'}\n            >\n              <InfoIcon sx={{ mt: 0.5, marginRight: 1, color: 'var(--color-text-secondary)' }} />\n              <Typography>\n                {t('labelVaultMaximumCreditDes')}{' '}\n                <Box component=\"span\" sx={{ whiteSpace: 'nowrap', display: 'inline' }}>\n                  <Typography\n                    component={'span'}\n                    onClick={onClickMaxCredit}\n                    color={'var(--color-primary)'}\n                    sx={{ cursor: 'pointer' }}\n                  >\n                    {t('labelLearnMore2')}\n                  </Typography>\n                </Box>\n              </Typography>\n              \n            </Typography>\n            {collateralTokens.map((token) => {\n              return (\n                <Box\n                  borderRadius={'8px'}\n                  border={'1px solid var(--color-border)'}\n                  paddingX={2}\n                  paddingY={1.5}\n                  marginBottom={2}\n                  key={token.name}\n                >\n                  <SpaceBetweenBox\n                    alignItems={'center'}\n                    leftNode={\n                      <Box display={'flex'} alignItems={'center'}>\n                        <CoinIcons type={TokenType.single} tokenIcon={[coinJSON]} />\n                        <Typography marginLeft={1}>{mapSpecialTokenName(token.name)}</Typography>\n                      </Box>\n                    }\n                    rightNode={\n                      <Box>\n                        <Typography textAlign={'right'}>{token.amount}</Typography>\n                        <Typography\n                          color={'var(--color-text-secondary)'}\n                          textAlign={'right'}\n                          variant={'body2'}\n                        >\n                          {token.valueInCurrency}\n                        </Typography>\n                      </Box>\n                    }\n                  />\n                </Box>\n              )\n            })}\n          </Box>\n        </Box>\n      </Box>\n    </Modal>\n  )\n}\nexport const MaximumCreditModal = (props: MaximumCreditModalProps) => {\n  const { open, onClose, onClickBack, collateralFactors, maxLeverage } = props\n  const { t } = useTranslation()\n  return (\n    <Modal open={open} onClose={onClose}>\n      <Box height={'100%'} display={'flex'} justifyContent={'center'} alignItems={'center'}>\n        <Box\n          bgcolor={'var(--color-box)'}\n          width={'var(--modal-width)'}\n          height={'600px'}\n          borderRadius={1}\n          display={'flex'}\n          flexDirection={'column'}\n          sx={{\n            overflowY: 'scroll'\n          }}\n        >\n          <Box\n            paddingX={1.5}\n            paddingY={1.5}\n            display={'flex'}\n            justifyContent={'space-between'}\n            alignItems={'center'}\n          >\n            <Box display={'flex'} alignItems={'center'}>\n              <BackIcon sx={{ marginRight: 2,cursor: 'pointer' }} onClick={onClickBack}/>\n              <Typography variant={'h5'}>{t('labelVaultMaximumCredit')}</Typography>\n            </Box>\n            <CloseIcon\n              style={{\n                height: '20px',\n                width: '20px',\n              }}\n              sx={{\n                cursor: 'pointer',\n                fontSize: '24px',\n                marginRight: 1.5,\n                color: 'var(--color-text-third)',\n              }}\n              onClick={onClose}\n            />\n          </Box>\n          <Divider style={{ marginTop: '-1px', width: '100%' }} />\n          <Box paddingX={3}>\n            <Typography\n              marginTop={2}\n              marginBottom={2}\n              color={'var(--color-warning)'}\n            >\n              {t('labelVaultMaximumLeverage')}: {maxLeverage}x\n            </Typography>\n            <Typography\n              marginTop={3}\n              marginBottom={2}\n              variant='body2'\n              color={'var(--color-text-secondary)'}\n            >\n              {t('labelVaultMaximumCreditDesLong')}{' '}\n            </Typography>\n            <Typography marginBottom={2} variant='body2' color={'var(--color-text-secondary)'}>\n              {t('labelVaultMaximumCreditFormula')}\n            </Typography>\n            <Typography  marginTop={4} color={'var(--color-text-secondary)'} variant='h5'>\n              {t('labelVaultPriceFactor')}\n            </Typography>\n            <Box\n              marginTop={2}\n              marginBottom={3}\n              padding={2.5}\n              bgcolor={'var(--color-box-secondary)'}\n              borderRadius={'8px'}\n            >\n              {collateralFactors.map((collateralFactor, index) => {\n                return (\n                  <SpaceBetweenBox\n                    key={collateralFactor.name}\n                    marginTop={index === 0 ? 0 : 2}\n                    leftNode={\n                      <Typography color={'var(--color-text-secondary)'}>\n                        {collateralFactor.name}\n                      </Typography>\n                    }\n                    rightNode={<Typography>{collateralFactor.collateralFactor}</Typography>}\n                  />\n                )\n              })}\n            </Box>\n            \n          </Box>\n        </Box>\n      </Box>\n    </Modal>\n  )\n}\n\nexport const LeverageModal = (props: LeverageModalProps) => {\n  const {\n    open,\n    onClose,\n    onClickMaxCredit,\n    currentLeverage,\n    onClickReduce,\n    onClickAdd,\n    maxLeverage,\n    onClickLeverage,\n    borrowAvailable,\n    borrowed,\n    maximumCredit,\n    isLoading\n  } = props\n  const { t } = useTranslation()\n  return (\n    <Modal open={open} onClose={onClose}>\n      <Box\n        height={'100%'}\n        display={'flex'}\n        justifyContent={'center'}\n        alignItems={'center'}\n        position={'relative'}\n      >\n        {isLoading && (\n          <Loading\n            size={40}\n            sx={{\n              position: 'absolute',\n              top: '50%',\n              left: '50%',\n              transform: 'translate(-50%, -50%)',\n            }}\n          />\n        )}\n        <Box\n          bgcolor={'var(--color-box)'}\n          width={'var(--modal-width)'}\n          height={'620px'}\n          borderRadius={1}\n          display={'flex'}\n          flexDirection={'column'}\n        >\n          <Box\n            paddingX={1.5}\n            paddingY={1.5}\n            display={'flex'}\n            justifyContent={'space-between'}\n            alignItems={'center'}\n          >\n            <Typography variant={'h5'}>{t('labelVaultLeverage')}</Typography>\n            <CloseIcon\n              style={{\n                height: '20px',\n                width: '20px',\n              }}\n              sx={{\n                cursor: 'pointer',\n                fontSize: '24px',\n                marginRight: 1.5,\n                color: 'var(--color-text-third)',\n              }}\n              onClick={onClose}\n            />\n          </Box>\n          <Divider style={{ marginTop: '-1px', width: '100%' }} />\n          <Box paddingX={3}>\n            <Box\n              borderRadius={'4px'}\n              padding={1}\n              justifyContent={'space-between'}\n              marginTop={4}\n              marginBottom={2.5}\n              display={'flex'}\n              bgcolor={'var(--color-box-secondary)'}\n              alignItems={'center'}\n            >\n              <IconButton onClick={onClickReduce}>\n                <RemoveIcon\n                  sx={{\n                    cursor: 'pointer',\n                    color: 'var(--color-text-secondary)',\n                    fontSize: '16px',\n                  }}\n                />\n              </IconButton>\n\n              <Typography>\n                {currentLeverage\n                  ? `${numberFormat(currentLeverage, { fixed: 0 })}x`\n                  : EmptyValueTag}\n              </Typography>\n              <IconButton onClick={onClickAdd}>\n                <AddIcon\n                  sx={{\n                    cursor: 'pointer',\n                    color: 'var(--color-text-secondary)',\n                    fontSize: '16px',\n                  }}\n                />\n              </IconButton>\n            </Box>\n            <Box sx={{ width: '100%' }}>\n              {(() => {\n                const unitValue = 10\n                const valueForLeverage = (leverage: number) => (leverage - 1) * unitValue\n                const leverageForValue = (value: number) => Math.round(value / unitValue) + 1\n                return (\n                  <Slider\n                    aria-label='Always visible'\n                    value={currentLeverage ? valueForLeverage(currentLeverage) : 0}\n                    onChange={(_, _value) => {\n                      onClickLeverage(leverageForValue(_value as number))\n                    }}\n                    max={valueForLeverage(maxLeverage)}\n                    marks={_.range(1, maxLeverage + 1).map((number) => ({\n                      value: valueForLeverage(number),\n                      label: `${number}x`,\n                    }))}\n                  />\n                )\n              })()}\n            </Box>\n            <Box\n              marginTop={2}\n              marginBottom={3}\n              padding={2.5}\n              bgcolor={'var(--color-box-secondary)'}\n              borderRadius={'8px'}\n            >\n              <SpaceBetweenBox\n                leftNode={\n                  <Typography color={'var(--color-text-secondary)'}>\n                    {t('labelVaultAvailableBorrow')}\n                  </Typography>\n                }\n                rightNode={<Typography>{borrowAvailable}</Typography>}\n                marginBottom={2}\n              />\n              <SpaceBetweenBox\n                leftNode={\n                  <Typography color={'var(--color-text-secondary)'}>\n                    {t('labelVaultBorrowed')}\n                  </Typography>\n                }\n                rightNode={<Typography>{borrowed}</Typography>}\n                marginBottom={2}\n              />\n              <SpaceBetweenBox\n                leftNode={\n                  <Typography color={'var(--color-text-secondary)'}>\n                    {t('labelVaultMaximumCredit')}\n                  </Typography>\n                }\n                rightNode={<Typography>{maximumCredit}</Typography>}\n              />\n            </Box>\n            <Typography\n              marginBottom={3}\n              marginTop={3}\n              variant='body2'\n              color={'var(--color-text-secondary)'}\n            >\n              {t('labelVaultMaximumCreditDes')}{' '}\n              <Typography\n                component={'span'}\n                onClick={onClickMaxCredit}\n                variant='body2'\n                color={'var(--color-primary)'}\n                sx={{ cursor: 'pointer' }}\n              >\n                {t('labelLearnMore2')}\n              </Typography>\n            </Typography>\n          </Box>\n          <Divider style={{ marginTop: '-1px', width: '100%' }} />\n          <Box paddingX={3} marginTop={3}>\n            <Typography marginBottom={2} variant='body2' color={'var(--color-text-secondary)'}>\n              {t('labelVaultLeverageRisk1')}\n            </Typography>\n            <Typography marginBottom={2} variant='body2' color={'var(--color-text-secondary)'}>\n              {t('labelVaultLeverageRisk2')}\n            </Typography>\n            <Typography marginBottom={2} variant='body2' color={'var(--color-text-secondary)'}>\n              {t('labelVaultLeverageRisk3')}\n            </Typography>\n          </Box>\n        </Box>\n      </Box>\n    </Modal>\n  )\n}\n\nexport const DebtModal = (props: DebtModalProps) => {\n  const {\n    open,\n    onClose,\n    borrowedVaultTokens,\n    totalFundingFee,\n    totalBorrowed,\n    totalDebt,\n  } = props\n  const { t } = useTranslation()\n  return (\n    <Modal open={open} onClose={onClose}>\n      <Box height={'100%'} display={'flex'} justifyContent={'center'} alignItems={'center'}>\n        <Box\n          bgcolor={'var(--color-box)'}\n          width={'var(--modal-width)'}\n          height={'620px'}\n          borderRadius={1}\n          display={'flex'}\n          flexDirection={'column'}\n        >\n          <Box\n            paddingX={1.5}\n            paddingY={1.5}\n            display={'flex'}\n            justifyContent={'space-between'}\n            alignItems={'center'}\n          >\n            <Typography variant={'h5'}>{t('labelVaultDebt')}</Typography>\n            <CloseIcon\n              style={{\n                height: '20px',\n                width: '20px',\n              }}\n              sx={{\n                cursor: 'pointer',\n                fontSize: '24px',\n                marginRight: 1.5,\n                color: 'var(--color-text-third)',\n              }}\n              onClick={onClose}\n            />\n          </Box>\n          <Divider style={{ marginTop: '-1px', width: '100%' }} />\n          <Box paddingX={3}>\n            <Box\n              borderRadius={'8px'}\n              padding={2}\n              marginTop={4}\n              marginBottom={2}\n              bgcolor={'var(--color-box-secondary)'}\n            >\n              <Typography marginBottom={2} fontSize={'16px'}>{t('labelVaultDebtDetails')}</Typography>\n              <SpaceBetweenBox\n                marginBottom={2}\n                leftNode={\n                  <Typography color={'var(--color-text-secondary)'}>\n                    {t('labelVaultTotalDebt')}\n                  </Typography>\n                }\n                rightNode={\n                  <Typography>\n                    {totalDebt}\n                  </Typography>\n                }\n              />\n              <SpaceBetweenBox\n                marginBottom={2}\n                leftNode={\n                  <Typography color={'var(--color-text-secondary)'}>\n                    {t('labelVaultTotalBorrowed')}\n                  </Typography>\n                }\n                rightNode={\n                  <Typography>\n                    {totalBorrowed}\n                  </Typography>\n                }\n              />\n              <SpaceBetweenBox\n                leftNode={\n                  <Typography color={'var(--color-text-secondary)'}>\n                    {t('labelVaultTotalFundingFee')}\n                  </Typography>\n                }\n                rightNode={\n                  <Typography>\n                    {totalFundingFee}\n                  </Typography>\n                }\n              />\n            </Box>  \n            <Typography fontSize={'16px'} marginBottom={2}>{t('labelVaultBorrowed')}</Typography>\n          </Box>\n          <Divider style={{ width: '100%' }} />\n          <Box paddingX={3} marginTop={3}>\n            {borrowedVaultTokens && borrowedVaultTokens.length > 0 ? borrowedVaultTokens.map(token => {\n              return (\n                <SpaceBetweenBox\n                  key={token.symbol}\n                  marginBottom={2}\n                  paddingX={2}\n                  paddingY={1.5}\n                  borderRadius={'8px'}\n                  border={'1px solid var(--color-border)'}\n                  alignItems={'center'}\n                  onClick={token.onClick}\n                  leftNode={\n                    <Box display={'flex'} alignItems={'center'}>\n                      <CoinIcons type={TokenType.single} tokenIcon={[token.coinJSON]} />\n                      <Typography marginLeft={1}>{token.symbol}</Typography>\n                    </Box>\n                  }\n                  rightNode={\n                    <Box display={'flex'} alignItems={'center'}>\n                      <Box marginRight={1}>\n                        <Typography textAlign={'right'}>{token.amount}</Typography>\n                        <Typography\n                          color={'var(--color-text-secondary)'}\n                          textAlign={'right'}\n                          variant={'body2'}\n                        >\n                          {token.valueInCurrency}\n                        </Typography>\n                      </Box>\n                    </Box>\n                  }\n                />\n              )\n            }) : <Typography mt={4} textAlign={'center'} color={'var(--color-text-third)'} >{t('labelEmptyDefault')}</Typography>}\n          </Box>\n        </Box>\n      </Box>\n    </Modal>\n  )\n}\n\nexport const DustCollectorModal = (props: DustCollectorProps) => {\n  const {\n    open,\n    converting,\n    onClose,\n    totalValueInUSDT,\n    totalValueInCurrency,\n    onClickConvert,\n    convertBtnDisabled,\n    onClickRecords,\n  } = props\n  const { t } = useTranslation()\n  return (\n    <Modal open={open} onClose={onClose}>\n      <Box height={'100%'} display={'flex'} justifyContent={'center'} alignItems={'center'}>\n        <Box\n          bgcolor={'var(--color-box)'}\n          width={'var(--modal-width)'}\n          height={'500px'}\n          borderRadius={1}\n          display={'flex'}\n          flexDirection={'column'}\n          sx={{ overflowY: 'scroll' }}\n          position={'relative'}\n        >\n          {converting && <Loading size={40} sx={{\n            position: 'absolute',\n            top: '50%',\n            left: '50%',\n            transform: 'translate(-50%, -50%)'\n          }}/>}\n          <Box\n            paddingX={1.5}\n            paddingY={1.5}\n            display={'flex'}\n            justifyContent={'space-between'}\n            alignItems={'center'}\n          >\n            <Typography variant={'h5'}>{t('labelDustCollectorDetail')}</Typography>\n            <Box>\n              <OrderListIcon\n                style={{\n                  height: '20px',\n                  width: '20px',\n                }}\n                sx={{\n                  cursor: 'pointer',\n                  marginRight: 1.5,\n                  color: 'var(--color-text-third)',\n                }}\n                onClick={onClickRecords}\n              />\n              <CloseIcon\n                style={{\n                  height: '20px',\n                  width: '20px',\n                }}\n                sx={{\n                  cursor: 'pointer',\n                  marginRight: 1.5,\n                  color: 'var(--color-text-third)',\n                }}\n                onClick={onClose}\n              />\n            </Box>\n          </Box>\n          <Divider style={{ marginTop: '-1px', width: '100%' }} />\n          <Box paddingX={3} paddingTop={5} paddingBottom={4}>\n            {(props.dusts && props.dusts.length > 0) ? props.dusts.map((dust) => {\n              return (\n                <SpaceBetweenBox\n                  marginBottom={1}\n                  key={dust.symbol}\n                  leftNode={\n                    <Box display={'flex'} alignItems={'center'}>\n                      <Checkbox\n                        checked={dust.checked}\n                        checkedIcon={<CheckedIcon />}\n                        icon={<CheckBoxIcon />}\n                        color='default'\n                        onChange={dust.onCheck}\n                      />\n                      <CoinIcons type={TokenType.single} tokenIcon={[dust.coinJSON]} />\n                      <Typography sx={{ marginLeft: 1 }}>{dust.symbol}</Typography>\n                    </Box>\n                  }\n                  rightNode={\n                    <Box>\n                      <Typography textAlign={'right'}>{dust.amount}</Typography>\n                      <Typography\n                        color={'var(--color-text-secondary)'}\n                        textAlign={'right'}\n                        variant={'body2'}\n                      >\n                        {dust.valueInCurrency}\n                      </Typography>\n                    </Box>\n                  }\n                />\n              )\n            }) : <Typography textAlign={'center'} color={'var(--color-text-third)'} >{t('labelVaultNoDust')}</Typography>}\n          </Box>\n          <Divider style={{ width: '100%' }} />\n          <Box paddingX={3}>\n            <SpaceBetweenBox\n              marginTop={3}\n              leftNode={\n                <Typography display={'flex'} alignItems={'center'} color={'var(--color-text-third)'}>\n                  {t('labelVaultValueEst')}\n                  <Tooltip\n                    title={\n                      'The token price changes dynamically, the dust value you see here may be inconsistent with the final value.'\n                    }\n                    placement={'bottom'}\n                  >\n                    <IconButton>\n                      <Info2Icon sx={{ color: 'var(--color-text-secondary)', marginLeft: 1 / 2 }} />\n                    </IconButton>\n                  </Tooltip>\n                </Typography>\n              }\n              rightNode={\n                <Typography>\n                  {totalValueInUSDT} USDT / {totalValueInCurrency}\n                </Typography>\n              }\n            />\n            <Typography marginBottom={3} color={'var(--color-text-secondary)'} marginTop={5}>\n              {t('labelVaultDustCollectorDes')}\n            </Typography>\n            <Button\n              sx={{ marginTop: 6, marginBottom: 4 }}\n              disabled={convertBtnDisabled}\n              fullWidth\n              onClick={onClickConvert}\n              variant={'contained'}\n            >\n              {t('labelVaultConvert')}\n            </Button>\n          </Box>\n        </Box>\n      </Box>\n    </Modal>\n  )\n}\n\nexport const DustCollectorUnAvailableModal = (props: DustCollectorUnAvailableModalProps) => {\n  const {\n    open,\n    onClose,\n  } = props\n  const { t } = useTranslation()\n  return (\n    <Modal open={open} onClose={onClose}>\n      <Box height={'100%'} display={'flex'} justifyContent={'center'} alignItems={'center'}>\n        <Box\n          bgcolor={'var(--color-box)'}\n          width={'var(--modal-width)'}\n          height={'200px'}\n          borderRadius={1}\n          display={'flex'}\n          flexDirection={'column'}\n          justifyContent={'center'}\n          alignItems={'center'}\n          position={'relative'}\n        >\n          <CloseIcon\n            style={{\n              height: '20px',\n              width: '20px',\n            }}\n            sx={{\n              cursor: 'pointer',\n              fontSize: '24px',\n              marginRight: 1.5,\n              color: 'var(--color-text-third)',\n              position: 'absolute',\n              top: 16,\n              right: 16,\n            }}\n            onClick={onClose}\n          />\n          <Typography variant={'h3'}>{t('labelVaultDustCollectorUnavailableTitle')}</Typography>\n          <Typography color={'var(--color-text-secondary)'} mt={6}>\n            {t('labelVaultDustCollectorUnavailableDes')}\n          </Typography>\n        </Box>\n      </Box>\n    </Modal>\n  )\n}\nexport interface NoAccountHintModalProps {\n\n    open: boolean\n    onClose: () => void\n    dialogBtn: React.ReactNode\n    title: string\n    des: React.ReactNode\n}\nexport const NoAccountHintModal = (props: NoAccountHintModalProps) => {\n  const { open, onClose, title, dialogBtn, des } = props\n  const { t } = useTranslation()\n  return (\n    <Modal open={open} onClose={onClose} sx={{ zIndex: 1000 }}>\n      <Box height={'100%'} display={'flex'} justifyContent={'center'} alignItems={'center'}>\n        <Box\n          padding={5}\n          bgcolor={'var(--color-box)'}\n          width={'var(--modal-width)'}\n          borderRadius={1}\n          display={'flex'}\n          alignItems={'center'}\n          flexDirection={'column'}\n          position={'relative'}\n        >\n          <ModalCloseButtonPosition right={2} top={2} t={t} onClose={onClose} />\n          <ViewAccountTemplate\n            className={'inModal'}\n            activeViewTemplate={\n              <>\n                <Typography marginBottom={3} variant={'h4'}>\n                  {t(title)}\n                </Typography>\n                <Typography\n                  whiteSpace={'pre-line'}\n                  component={'span'}\n                  variant={'body1'}\n                  color={'textSecondary'}\n                  marginBottom={3}\n                  textAlign={'left'}\n                  width={'100%'}\n                >\n                  {des}\n                </Typography>\n                <>{dialogBtn}</>\n              </>\n            }\n          />\n        </Box>\n      </Box>\n    </Modal>\n  )\n}\nexport interface SmallOrderAlertProps {\n  open: boolean\n  handleClose: () => void\n  handleConfirm: () => void\n  estimatedFee: string\n  feePercentage: string\n  minimumReceived: string\n}\nexport const SmallOrderAlert = (props: SmallOrderAlertProps) => {\n  const { open, handleClose, handleConfirm, estimatedFee, feePercentage, minimumReceived } = props\n  const { t } = useTranslation('common')\n  const label: RiskInformation[] = [\n    {\n      label: t('labelSmallOrderAlertLine3'),\n      value: `${estimatedFee}`,\n      color: 'var(--color-text-primary)',\n    },\n    {\n      label: t('labelSmallOrderAlertLine5'),\n      value: `${minimumReceived}`,\n      color: 'var(--color-text-primary)',\n    },\n    {\n      label: t('labelSmallOrderAlertLine4'),\n      value: `${feePercentage}%`,\n      color: 'var(--color-error)',\n    },\n  ]\n\n  return (\n    <RiskComponent\n      title={t('labelSmallOrderAlertLine')}\n      open={open}\n      infos={label}\n      handleClose={handleClose}\n      handleConfirm={handleConfirm}\n    />\n  )\n}\n\n\nexport const VaultSwapModal = (props: VaultSwapViewProps) => {\n  const { open, onClose } = props\n\n  return (\n    <Modal\n      sx={{\n        height: '100%',\n        display: 'flex',\n        justifyContent: 'center',\n        alignItems: 'center',\n      }}\n      open={open}\n      onClose={onClose}\n    >\n      <VaultSwapView {...props} />\n    </Modal>\n  )\n}\n\nexport interface SupplyCollateralHintModalProps {\n  open: boolean \n  onClose: () => void\n  onClickSupply: () => void\n}\n\nexport const SupplyCollateralHintModal = (props: SupplyCollateralHintModalProps) => {\n  const { open, onClose, onClickSupply} = props\n  return (\n    <Modal open={open} onClose={onClose}>\n      <Box height={'100%'} display={'flex'} justifyContent={'center'} alignItems={'center'}>\n        <Box\n          bgcolor={'var(--color-box)'}\n          width={'450px'}\n          borderRadius={1}\n          display={'flex'}\n          flexDirection={'column'}\n          px={2.5}\n        >\n          <SpaceBetweenBox\n            leftNode={\n              <Typography py={3} variant='h3'>\n                Supply Collateral\n              </Typography>\n            }\n            rightNode={\n              <CloseIcon\n                className='custom-size'\n                sx={{ mt: '12px', fontSize: 24, color: 'var(--color-text-secondary)', cursor: 'pointer' }}\n                onClick={onClose}\n              />\n            }\n          />\n          <Typography mt={1.5} color={'var(--color-text-secondary)'}>To initiate a trade in Portal, please add collateral to your account.</Typography>\n          <Button onClick={onClickSupply} sx={{ mt: 5, mb: 4 }} variant={'contained'} fullWidth>\n            Supply Collateral\n          </Button>\n        </Box>\n      </Box>\n    </Modal>\n  )\n}\n\nexport interface SettleConfirmModalProps {\n  open: boolean \n  onClose: () => void\n  onConfirm: () => void\n}\n\nexport const SettleConfirmModal = (props: SettleConfirmModalProps) => {\n  const { open, onClose, onConfirm } = props\n  const { t } = useTranslation('common')\n  return (\n    <Modal\n      open={open}\n      onClose={onClose}\n      aria-labelledby='modal-modal-title'\n      aria-describedby='modal-modal-description'\n    >\n      <Box\n        sx={{\n          position: 'absolute',\n          top: '50%',\n          left: '50%',\n          transform: 'translate(-50%, -50%)',\n          width: 'var(--modal-width)',\n          maxWidth: '450px',\n          bgcolor: 'var(--color-global-bg)',\n          // padding: 3,\n          px: 4,\n          py: 5,\n          borderRadius: 2,\n        }}\n      >\n        <IconButton\n          sx={{\n            position: 'absolute',\n            right: 8,\n            top: 8,\n          }}\n          onClick={onClose}\n          aria-label='close'\n        >\n          <CloseIcon />\n        </IconButton>\n\n        <Typography variant='h4' component='h2' textAlign='center' mb={4}>\n          Settle\n        </Typography>\n\n        <Typography mb={3}>\n          You can only settle your account after all existing positions have been closed.\n        </Typography>\n\n        <Typography mb={3} variant='body1' color={'var(--color-text-secondary)'}>\n          · If there is a loss (due to an unprofitable trade or interest payments), a portion of\n          your collateral may be used to cover the deficit. In this case, only the remaining\n          collateral will be available for withdrawal from Portal.\n        </Typography>\n\n        <Typography color={'var(--color-text-secondary)'} variant='body1'>\n          · If your trades are profitable, your full collateral will be available for withdrawal,\n          and any profits will be credited to your Loopring DeFi account accordingly.\n        </Typography>\n\n        <Box display='flex' gap={2} mt={4}>\n          <Button variant='outlined' sx={{height: '40px'}} fullWidth onClick={onClose}>\n            Cancel\n          </Button>\n\n          <Button variant='contained' fullWidth onClick={onConfirm}>\n            Settle\n          </Button>\n        </Box>\n      </Box>\n    </Modal>\n  )\n};\n\nexport interface CloseAllConfirmModalProps {\n  open: boolean \n  onClose: () => void\n  onConfirm: () => void\n}\n\nexport const CloseAllConfirmModal = (props: CloseAllConfirmModalProps) => {\n  const { open, onClose, onConfirm } = props\n  return (\n    <Modal open={open} onClose={onClose}>\n      <Box height={'100%'} display={'flex'} justifyContent={'center'} alignItems={'center'}>\n        <Box\n          bgcolor={'var(--color-global-bg)'}\n          width={'450px'}\n          borderRadius={2}\n          display={'flex'}\n          flexDirection={'column'}\n          p={4}\n          position={'relative'}\n        >\n          <IconButton\n            className='custom-size'\n            sx={{\n              position: 'absolute',\n              right: 8,\n              top: 8,\n              color: 'var(--color-text-secondary)',\n              fontSize: '16px'\n            }}\n            onClick={onClose}\n            aria-label='close'\n          >\n            <CloseIcon />\n          </IconButton>\n          <Box display={'flex'} justifyContent={'space-between'} alignItems={'center'} mb={4}>\n            <Typography variant={'h4'} component={'h2'} textAlign={'center'} width={'100%'}>\n              Close All Position\n            </Typography>\n          </Box>\n\n          <Typography mb={5}>\n            This operation will close all existing positions in your account.\n          </Typography>\n\n          <Box display='flex' gap={2} mt={2}>\n            <Button variant='outlined' sx={{height: '40px'}} fullWidth onClick={onClose}>\n              Cancel\n            </Button>\n\n            <Button variant='contained' fullWidth onClick={onConfirm}>\n              Confirm\n            </Button>\n          </Box>\n        </Box>\n      </Box>\n    </Modal>\n  )\n}\n\nexport interface CloseConfirmModalProps {\n  open: boolean \n  onClose: () => void\n  onConfirm: () => void\n}\n\nexport const CloseConfirmModal = (props: CloseConfirmModalProps) => {\n  const { open, onClose, onConfirm } = props\n  return (\n    <Modal open={open} onClose={onClose} disableAutoFocus disableEnforceFocus disableScrollLock>\n      <Box height={'100%'} display={'flex'} justifyContent={'center'} alignItems={'center'}>\n        <Box\n          bgcolor={'var(--color-global-bg)'}\n          width={'450px'}\n          borderRadius={2}\n          display={'flex'}\n          flexDirection={'column'}\n          p={4}\n          position={'relative'}\n        >\n          <IconButton\n            className='custom-size'\n            sx={{\n              position: 'absolute',\n              right: 8,\n              top: 8,\n              color: 'var(--color-text-secondary)',\n              fontSize: '16px'\n            }}\n            onClick={onClose}\n            aria-label='close'\n          >\n            <CloseIcon />\n          </IconButton>\n          <Box display={'flex'} justifyContent={'space-between'} alignItems={'center'} mb={4}>\n            <Typography variant={'h4'} component={'h2'} textAlign={'center'} width={'100%'}>\n              Close Position\n            </Typography>\n          </Box>\n\n          <Typography mb={2}>\n            Executing this operation will fully close the SHORT or LONG position associated with the\n            selected token, eliminating any positive or negative exposure. Additionally, the\n            corresponding debt will be repaid.\n          </Typography>\n          <Typography color={'var(--color-text-secondary)'} mb={2}>\n            · For a LONG position: Your held asset will be sold for USDT, and any USDT debt will be\n            repaid.\n          </Typography>\n          <Typography color={'var(--color-text-secondary)'} mb={4}>\n            · For a SHORT position: You will need to borrow USDT to purchase the token required for\n            debt repayment. In other words, your debt will shift from the original token to USDT.\n          </Typography>\n\n          <Box display='flex' gap={2} mt={2}>\n            <Button variant='outlined' sx={{height: '40px'}} fullWidth onClick={onClose}>\n              Cancel\n            </Button>\n\n            <Button variant='contained' fullWidth onClick={onConfirm}>\n              Confirm\n            </Button>\n          </Box>\n        </Box>\n      </Box>\n    </Modal>\n  )\n}\nexport interface AutoRepayModalProps {\n  open: boolean\n  onClose: () => void\n  onConfirm: () => void\n}\n\nexport const AutoRepayConfirmModal = ({\n  open,\n  onClose,\n  onConfirm,\n}: AutoRepayModalProps) => {\n  return (\n    <Modal\n      open={open}\n      onClose={onClose}\n      aria-labelledby=\"auto-repay-confirm-modal\"\n      aria-describedby=\"auto-repay-confirm-description\"\n    >\n      <Box\n        sx={{\n          position: 'absolute',\n          top: '50%',\n          left: '50%',\n          transform: 'translate(-50%, -50%)',\n          width: { xs: '90%', sm: 480 },\n          maxWidth: '100%',\n          bgcolor: 'var(--color-box-secondary)',\n          px: 4,\n          py: 8,\n          borderRadius: '8px',\n        }}\n      >\n        <Box>\n          <Typography>\n            It looks like you're holding the same asset as your debt. To avoid\n            extra interest charges, consider repaying your debt with your\n            holdings now.\n          </Typography>\n\n          <Box display=\"flex\" justifyContent=\"center\" mt={6}>\n            <Button\n              variant=\"contained\"\n              onClick={onConfirm}\n              fullWidth\n            >\n              I Know\n            </Button>\n          </Box>\n        </Box>\n      </Box>\n    </Modal>\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/sharedPages/VaultPage/components/useVaultSwapExtends.tsx",
    "content": "import React from 'react'\nimport {\n  EmptyValueTag,\n  getValuePrecisionThousand,\n  Info2Icon,\n  L1L2_NAME_DEFINED,\n  MapChainId,\n  myLog,\n  TradeBtnStatus,\n  WaitingIcon,\n  CompleteIcon,\n  VaultSwapStep,\n  ToastType,\n  hexToRGB,\n  AlertIcon,\n  ErrorIcon,\n  WarningIcon,\n} from '@loopring-web/common-resources'\nimport { Box, Grid, Link, Tooltip, Typography, Stepper, StepLabel, Step } from '@mui/material'\nimport { ButtonStyle, SwapType, useSettings } from '@loopring-web/component-lib'\nimport { useTranslation } from 'react-i18next'\nimport { useTheme } from '@emotion/react'\nenum ActiveStep {\n  Edit = 0,\n  Borrow = 0,\n  Swap = 1,\n  Swaping = 1,\n}\n\nexport const useVaultSwapExtends = ({\n  tradeCalcData,\n  swapBtnI18nKey,\n  swapBtnStatus,\n  onSwapClick,\n  disabled,\n  handleSwapPanelEvent,\n  tradeData,\n  isSwapLoading,\n  // btnBorrowStatus,\n  // onBorrowClick,\n  // borrowBtnI18nKey,\n  toastOpen,\n  borrowedAmount\n}) => {\n  const { t } = useTranslation()\n  const { defaultNetwork, coinJson } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const label = React.useMemo(() => {\n    myLog(swapBtnI18nKey, 'swapBtnI18nKey useMemo')\n    const keyParams = {\n      layer2: L1L2_NAME_DEFINED[network].layer2,\n      l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n      loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n      l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n      l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n      ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n    }\n    if (swapBtnI18nKey) {\n      const key = swapBtnI18nKey.split('|')\n      if (key) {\n        return t(\n          key[0],\n          key && key[1]\n            ? {\n                arg: key[1],\n                ...keyParams,\n              }\n            : {\n                ...keyParams,\n              },\n        )\n      } else {\n        return t(swapBtnI18nKey, {\n          ...keyParams,\n        })\n      }\n    } else {\n      const label = `labelVaultSwapBtn`\n      return t(label, {\n        ...keyParams,\n      })\n    }\n  }, [swapBtnI18nKey, network, tradeCalcData, t])\n  const labelBorrowHint = React.useMemo(() => {\n    const keyParams = {\n      layer2: L1L2_NAME_DEFINED[network].layer2,\n      l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n      loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n      l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n      l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n      ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n    }\n    if (toastOpen?.type == ToastType.error && toastOpen?.step == VaultSwapStep.Borrow) {\n      return (\n        <Box marginLeft={0.5} display={'flex'} alignItems={'center'} color={'var(--color-error)'}>\n          <WarningIcon />\n          <Typography marginLeft={0.5} color={'var(--color-error)'} fontSize={'12px'}>\n            {t('labelVaultActiveLoanError2', {\n              symbol: tradeCalcData.belongSellAlice,\n              value: borrowedAmount\n            })}\n          </Typography>\n        </Box>\n      )\n    } else if (\n      tradeCalcData?.step === VaultSwapStep.Swap ||\n      tradeCalcData?.step === VaultSwapStep.Swaping\n    ) {\n      return (\n        <Box marginLeft={0.5} display={'flex'} alignItems={'center'} color={'var(--color-success)'}>\n          <CompleteIcon />\n          <Typography marginLeft={0.5} color={'var(--color-success)'} fontSize={'12px'}>\n            {t('labelVaultActiveLoanSuccessful', {\n              symbol: tradeCalcData.belongSellAlice,\n              value: borrowedAmount\n            })}\n          </Typography>\n        </Box>\n      )\n    } else if (\n      tradeCalcData.step === VaultSwapStep.Borrow &&\n      swapBtnStatus === TradeBtnStatus.LOADING\n    ) {\n      return (\n        <Box marginLeft={0.5} display={'flex'} alignItems={'center'} color={'var(--color-warning)'}>\n          <WaitingIcon />\n          <Typography marginLeft={0.5} color={'var(--color-warning)'} fontSize={'12px'}>\n            {t('labelBorrowing', {\n              symbol: tradeCalcData.belongSellAlice,\n              value: borrowedAmount,\n            })}\n          </Typography>\n        </Box>\n      )\n    } else if (swapBtnI18nKey && tradeCalcData?.isRequiredBorrow) {\n      let key = swapBtnI18nKey.split('|')\n      if (key) {\n        const i18nKey = key.shift()\n        return t(\n          i18nKey,\n          key?.length\n            ? key.reduce(\n                (prev, item, index) => {\n                  prev[`arg${index ? index : ''}`] = item\n                  return prev\n                },\n                { ...keyParams },\n              )\n            : {\n                ...keyParams,\n              },\n        )\n      } else {\n        return t(swapBtnI18nKey, {\n          ...keyParams,\n        })\n      }\n    } else {\n      return ''\n    }\n  }, [swapBtnI18nKey, network, tradeCalcData, tradeCalcData?.step, swapBtnStatus, toastOpen?.type, toastOpen?.step, borrowedAmount])\n\n  const getDisabled =\n    disabled || tradeCalcData === undefined || tradeCalcData.coinInfoMap === undefined\n  const maxEle = React.useMemo(() => {\n    return (\n      <Box display={'flex'} flexDirection={'row'} justifyContent={'flex-end'}>\n        <Tooltip title={t('labelVaultSwapBorrowTip')}>\n          <Link\n            variant={'body2'}\n            color={'textSecondary'}\n            display={'inline-flex'}\n            alignItems={'center'}\n            justifyContent={'flex-end'}\n            className={\n              tradeData?.sell?.balance !== '0'\n                ? `max-allow ${isSwapLoading ? 'disabled' : ''}`\n                : `no-balance ${isSwapLoading ? 'disabled' : ''}`\n            }\n            onClick={() => {\n              handleSwapPanelEvent(\n                {\n                  type: 'sell',\n                  tradeData: {\n                    ...tradeData,\n                    sell: {\n                      ...tradeData?.sell,\n                      tradeValue: tradeData?.sell?.balance,\n                    },\n                  },\n                },\n                SwapType.SELL_SELECTED,\n              )\n            }}\n          >\n            <Info2Icon fontSize={'small'} color={'inherit'} sx={{ marginX: 1 / 2 }} />\n            <span>{t('labelVaultSwapBorrow')}</span>\n            <span>\n              {tradeData?.sell?.balance !== '0' ? tradeData?.sell?.balance : EmptyValueTag}\n            </span>\n          </Link>\n        </Tooltip>\n        {/*<Tooltip title={t('labelVaultSwapHoldTip')}>*/}\n        <Link\n          variant={'body2'}\n          color={'textSecondary'}\n          display={'inline-flex'}\n          alignItems={'center'}\n          justifyContent={'flex-end'}\n          marginX={1}\n          className={\n            tradeData?.sell?.count > 0\n              ? `max-allow ${isSwapLoading ? 'disabled' : ''}`\n              : `no-balance ${isSwapLoading ? 'disabled' : ''}`\n          }\n          onClick={() => {\n            handleSwapPanelEvent(\n              {\n                type: 'sell',\n                tradeData: {\n                  ...tradeData,\n                  sell: {\n                    ...tradeData?.sell,\n                    tradeValue: tradeData?.sell?.count,\n                  },\n                },\n              },\n              SwapType.SELL_SELECTED,\n            )\n          }}\n        >\n          {/*<Info2Icon fontSize={'small'} color={'inherit'} sx={{ marginX: 1 / 2 }} />*/}\n          <span>{t('labelVaultSwapHold')}</span>\n          <span>\n            {tradeData?.sell?.count > 0\n              ? getValuePrecisionThousand(\n                  tradeData?.sell?.count,\n                  tradeCalcData?.sellPrecision,\n                  tradeCalcData?.sellPrecision,\n                  tradeCalcData?.sellPrecision,\n                  false,\n                )\n              : EmptyValueTag}\n          </span>\n        </Link>\n        {/*</Tooltip>*/}\n      </Box>\n    )\n  }, [tradeData])\n  const theme = useTheme()\n\n  const BtnEle = React.useMemo(() => {\n    return (\n      <Grid container spacing={2}>\n        {toastOpen?.type == ToastType.error && toastOpen?.step == VaultSwapStep.Borrow ? (\n          <Grid item xs={12}>\n            <Typography\n              marginY={1}\n              width={'100%'}\n              variant={'body1'}\n              component={'span'}\n              padding={1}\n              display={'inline-flex'}\n              bgcolor={hexToRGB(theme.colorBase.error, 0.2)}\n              borderRadius={2}\n              color={'var(--color-text-button)'}\n            >\n              <ErrorIcon color={'error'} sx={{ marginRight: 1 / 2 }} />\n              {t('labelVaultActiveLoanError', { symbol: tradeCalcData.belongSellAlice, value: '' })}\n            </Typography>\n          </Grid>\n        ) : (\n          (tradeCalcData as any)?.showHasBorrow && (\n            <Grid item xs={12}>\n              <Typography\n                marginY={1}\n                width={'100%'}\n                variant={'body1'}\n                component={'span'}\n                padding={1}\n                display={'inline-flex'}\n                bgcolor={hexToRGB(theme.colorBase.warning, 0.2)}\n                borderRadius={2}\n                color={'var(--color-text-button)'}\n              >\n                <AlertIcon color={'warning'} sx={{ marginRight: 1 / 2 }} />\n                {t('labelVaultActiveLoanAlert')}\n              </Typography>\n            </Grid>\n          )\n        )}\n        <>\n          {tradeCalcData?.isRequiredBorrow && (\n            <>\n              <Grid item xs={7}>\n                <Stepper activeStep={Number(ActiveStep[tradeCalcData.step])}>\n                  {[\n                    { label: t('labelStep1Borrow'), value: VaultSwapStep.Borrow },\n                    {\n                      label: t('labelStep2Swap'),\n                      value: VaultSwapStep.Swap,\n                    },\n                  ].map(({ label, value }) => {\n                    return (\n                      <Step key={label}>\n                        <StepLabel\n                          error={\n                            toastOpen.type == ToastType.error &&\n                            toastOpen.step == tradeCalcData.step\n                          }\n                          sx={{ width: '120px' }}\n                        >\n                          {label}\n                        </StepLabel>\n                      </Step>\n                    )\n                  })}\n                </Stepper>\n              </Grid>\n              <Grid item xs={5} display={'flex'} justifyContent={'flex-end'}>\n                \n              </Grid>\n              \n            </>\n          )}\n        </>\n        {labelBorrowHint && (\n                <Grid item xs={12}>\n                  <Typography\n                    variant={'body2'}\n                    component={'span'}\n                    color={'error'}\n                    display={'inline-flex'}\n                    alignItems={'center'}\n                  >\n                    {labelBorrowHint}\n                  </Typography>\n                </Grid>\n              )}\n        <Grid item xs={12}>\n          <ButtonStyle\n            variant={'contained'}\n            size={'large'}\n            color={'primary'}\n            onClick={() => {\n              onSwapClick()\n            }}\n            loading={!getDisabled && swapBtnStatus === TradeBtnStatus.LOADING ? 'true' : 'false'}\n            disabled={\n              getDisabled ||\n              swapBtnStatus === TradeBtnStatus.DISABLED ||\n              swapBtnStatus === TradeBtnStatus.LOADING\n            }\n            fullWidth={true}\n          >\n            {tradeCalcData?.isRequiredBorrow ? t('labelBorrowSwap') : label}\n          </ButtonStyle>\n        </Grid>\n      </Grid>\n    )\n  }, [swapBtnStatus, onSwapClick, getDisabled, label])\n  return {\n    BtnEle,\n    maxEle,\n  }\n}\n"
  },
  {
    "path": "packages/component-lib/src/sharedPages/VaultPage/hooks/useModals.ts",
    "content": "\nimport {\n  ToastType,\n} from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport {\n  useOpenModals,\n} from '@loopring-web/component-lib'\nimport {\n  useVaultLayer2,\n} from '@loopring-web/core'\nimport _ from 'lodash'\nimport { closePositionAndRepayIfNeeded } from '../utils'\nimport { CloseConfirmModalProps } from '../components/modals'\n\nexport const useModals = (): { closeConfirmModalProps: CloseConfirmModalProps } => {\n  const { updateVaultLayer2 } = useVaultLayer2()\n  const {\n    modals: {\n      isShowVaultCloseConfirm,\n    },\n    setShowVaultCloseConfirm,\n    setShowGlobalToast,\n  } = useOpenModals()\n  return {\n    closeConfirmModalProps: {\n      open: isShowVaultCloseConfirm.isShow,\n      onClose: () => {\n        setShowVaultCloseConfirm({ isShow: false, symbol: undefined })\n      },\n      onConfirm: async () => {\n        const { symbol } = isShowVaultCloseConfirm\n        setShowVaultCloseConfirm({ isShow: false, symbol: undefined })\n        closePositionAndRepayIfNeeded(symbol!)\n          .then((response2) => {\n            if (response2?.operation.status === sdk.VaultOperationStatus.VAULT_STATUS_FAILED) {\n              throw new Error('failed')\n            }\n            setShowGlobalToast({\n              isShow: true,\n              info: {\n                content: 'Closed position successfully',\n                type: ToastType.success,\n              },\n            })\n          })\n          .catch(() => {\n            setShowGlobalToast({\n              isShow: true,\n              info: {\n                content: 'Close position failed',\n                type: ToastType.error,\n              },\n            })\n          })\n          .finally(() => {\n            updateVaultLayer2({})\n          })\n      },\n    },\n  }\n}"
  },
  {
    "path": "packages/component-lib/src/sharedPages/VaultPage/hooks/useVaultDashBoard.tsx",
    "content": "import {\n  Box,\n  Typography,\n  Button,\n} from '@mui/material'\n\nimport React, { useEffect } from 'react'\nimport {\n  PriceTag,\n  CurrencyToTag,\n  EmptyValueTag,\n  VaultAction,\n  L1L2_NAME_DEFINED,\n  MapChainId,\n  SoursURL,\n  RouterPath,\n  VaultKey,\n  TradeBtnStatus,\n  VaultLoanType,\n  SUBMIT_PANEL_CHECK,\n  SUBMIT_PANEL_AUTO_CLOSE,\n  fnType,\n  SagaStatus,\n  AccountStatus,\n  myLog,\n  TokenType,\n  globalSetup,\n  MarketType,\n  ToastType,\n} from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport {\n  useOpenModals,\n  useSettings,\n  AccountStep,\n  useToggle,\n  VaultDataAssetsItem,\n  VaultAssetsTableProps,\n  setShowWrongNetworkGuide,\n  Button as MyButton,\n  setHideSmallBalances,\n} from '@loopring-web/component-lib'\nimport { Trans, useTranslation } from 'react-i18next'\nimport {\n  accountReducer,\n  accountStaticCallBack,\n  DAYS,\n  fiatNumberDisplay,\n  getTimestampDaysLater,\n  LoopringAPI,\n  makeVaultLayer2,\n  numberFormat,\n  numberFormatThousandthPlace,\n  numberStringListSum,\n  store,\n  useAccount,\n  useVaultAccountInfo,\n  useSystem,\n  useTokenMap,\n  useVaultLayer2,\n  useVaultMap,\n  useVaultTicker,\n  useWalletLayer2,\n  VaultAccountInfoStatus,\n  WalletConnectL2Btn,\n  // useVaultSwap,\n  MAPFEEBIPS,\n  vaultSwapDependAsync,\n  useToast,\n  toPercent,\n  bipsToPercent,\n  tryFn,\n} from '@loopring-web/core'\nimport { useTheme } from '@emotion/react'\nimport { useVaultMarket } from './useVaultMarket'\nimport { useHistory, useLocation, useRouteMatch } from 'react-router'\nimport { utils, BigNumber } from 'ethers'\nimport Decimal from 'decimal.js'\nimport _, { keys } from 'lodash'\nimport { CollateralDetailsModalProps, DebtModalProps, DustCollectorProps, DustCollectorUnAvailableModalProps, LeverageModalProps, MaximumCreditModalProps, VaultDashBoardPanelUIProps } from '../interface'\nimport { PositionItem, VaultPositionsTableProps } from '@loopring-web/component-lib/src/components/tableList/assetsTable/VaultPositionsTable'\nimport { AutoRepayModalProps, CloseConfirmModalProps, NoAccountHintModalProps, SettleConfirmModalProps, SmallOrderAlertProps, SupplyCollateralHintModalProps, VaultSwapModalProps } from '../components/modals'\nimport { useVaultSwap } from './useVaultSwap'\nimport { checkHasTokenNeedRepay, closePositionAndRepayIfNeeded, filterPositions, repayIfNeeded } from '../utils'\nimport { promiseAllSequently } from '@loopring-web/core/src/utils/promise'\n\nconst VaultPath = `${RouterPath.vault}/:item/:method?`\n\nconst parseVaultTokenStatus = (status: number) => ({\n  show: status & 1,\n  join: status & 2,\n  exit: status & 4,\n  loan: status & 8,\n  repay: status & 16,\n})\n\nexport const useGetVaultAssets = <R extends VaultDataAssetsItem>({\n  onClickTrade,\n  onClickRepay\n}: {\n  onClickTrade: (symbol: string) => void\n  onClickRepay: (symbol: string) => void\n  // onClickRepay: (symbol: string) => void\n}): VaultAssetsTableProps<R> & {\n  totalAsset: string\n  [key: string]: any\n  \n} => {\n  const _vaultAccountInfo = useVaultAccountInfo()\n  let match: any = useRouteMatch(VaultPath)\n  const history = useHistory()\n  const { search, pathname } = useLocation()\n  const searchParams = new URLSearchParams(search)\n  const { t } = useTranslation(['common'])\n\n  const {\n    vaultAccountInfoStatus,\n    vaultAccountInfo,\n    activeInfo,\n    onJoinPop,\n    onGoToSwap,\n    onBorrowPop,\n    onRedeemPop,\n  } = _vaultAccountInfo\n  const [assetsRawData, setAssetsRawData] = React.useState<R[]>([])\n  const [totalAsset, setTotalAsset] = React.useState<string>(EmptyValueTag)\n  const { account } = useAccount()\n  const { allowTrade, forexMap } = useSystem()\n\n  const {\n    setShowNoVaultAccount,\n    setShowVaultSwap,\n    setShowVaultLoan,\n    modals: {\n      isShowNoVaultAccount: { isShow: showNoVaultAccount, whichBtn, ...btnProps },\n    },\n  } = useOpenModals()\n\n  const { isMobile, defaultNetwork, hideL2Assets, hideSmallBalances, setHideSmallBalances } =\n    useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const btnClickCallbackArray = {\n    [fnType.ERROR_NETWORK]: [\n      function () {\n        store.dispatch(accountReducer.changeShowModel({ _userOnModel: false }))\n        store.dispatch(setShowWrongNetworkGuide({ isShow: true }))\n      },\n    ],\n    [fnType.UN_CONNECT]: [\n      function (key: VaultAction) {\n        setShowNoVaultAccount({ isShow: true, whichBtn: key })\n      },\n    ],\n    [fnType.NO_ACCOUNT]: [\n      function (key: VaultAction) {\n        setShowNoVaultAccount({ isShow: true, whichBtn: key })\n      },\n    ],\n    [fnType.DEPOSITING]: [\n      function (key: VaultAction) {\n        setShowNoVaultAccount({ isShow: true, whichBtn: key })\n      },\n    ],\n    [fnType.NOT_ACTIVE]: [\n      function (key: VaultAction) {\n        setShowNoVaultAccount({ isShow: true, whichBtn: key })\n      },\n    ],\n    [fnType.LOCKED]: [\n      function (key: VaultAction) {\n        setShowNoVaultAccount({ isShow: true, whichBtn: key })\n      },\n    ],\n    [fnType.ACTIVATED]: [\n      (\n        accountStatus: sdk.VaultAccountStatus,\n        activeInfo: {\n          hash: string\n          isInActive: true\n        },\n        key: any,\n      ) => {\n        if (\n          [sdk.VaultAccountStatus.IN_STAKING].includes(accountStatus as any) ||\n          activeInfo?.hash\n        ) {\n          switch (key) {\n            case VaultAction.VaultJoin:\n              onJoinPop({})\n              // setShowVaultJoin({ isShow: true, info: { isActiveAccount: false } })\n              break\n            case VaultAction.VaultExit:\n              onRedeemPop({ isShow: true })\n              break\n            case VaultAction.VaultLoan:\n              onBorrowPop({ isShow: true })\n              break\n            case VaultAction.VaultSwap:\n              onGoToSwap({})\n              break\n          }\n        } else if (\n          [sdk.VaultAccountStatus.IN_REDEEM].includes(vaultAccountInfo?.accountStatus as any)\n        ) {\n          setShowNoVaultAccount({\n            isShow: true,\n            des: 'labelRedeemDesMessage',\n            title: 'labelRedeemTitle',\n          })\n        } else {\n          setShowNoVaultAccount({\n            isShow: true,\n            whichBtn: VaultAction.VaultJoin,\n            des: 'labelJoinDesMessage',\n            title: 'labelVaultJoinTitle',\n          })\n        }\n      },\n      [vaultAccountInfo?.accountStatus, activeInfo?.hash],\n    ],\n  }\n  const onActionBtnClick = (props: string) => {\n    accountStaticCallBack(btnClickCallbackArray, [props])\n  }\n  React.useEffect(() => {\n    if (\n      match?.params?.item == VaultKey.VAULT_DASHBOARD &&\n      vaultAccountInfoStatus === SagaStatus.UNSET\n    ) {\n      const { vaultAccountInfo } = store.getState().vaultLayer2\n      if (vaultAccountInfo?.accountStatus) {\n        if ([sdk.VaultAccountStatus.IN_STAKING].includes(vaultAccountInfo?.accountStatus as any)) {\n          if (match?.params?.method) {\n            switch (match?.params?.method) {\n              case VaultAction.VaultJoin:\n                onJoinPop({})\n                // setShowVaultJoin({ isShow: true, info: { isActiveAccount: false } })\n                break\n              case VaultAction.VaultExit:\n                onRedeemPop({ isShow: true, symbol: searchParams.get('symbol') })\n                break\n              case VaultAction.VaultLoan:\n                onBorrowPop({ isShow: true, symbol: searchParams.get('symbol') })\n                break\n              case VaultAction.VaultSwap:\n                onGoToSwap({ symbol: searchParams.get('symbol') })\n                break\n            }\n            history.replace(`${RouterPath.vault}/${VaultKey.VAULT_DASHBOARD}`)\n          }\n        }\n      } else {\n        \n      }\n    }\n  }, [vaultAccountInfoStatus, match?.params?.item, match?.params?.method])\n  \n  const { status: walletL2Status } = useWalletLayer2()\n  const getAssetsRawData = () => {\n    const {\n      // vaultLayer2: { vaultAccountInfo },\n      tokenMap: {\n        // tokenMap: erc20TokenMap,\n        idIndex: erc20IdIndex,\n      },\n      vaultLayer2: {vaultLayer2},\n\n      invest: {\n        vaultMap: { tokenMap,  tokenPrices, marketMap },\n      },\n    } = store.getState()\n    const walletMap = makeVaultLayer2({ needFilterZero: false }).vaultLayer2Map ?? {}\n    myLog('asdfhsjdhfjsd', tokenMap, walletMap)\n    if (\n      tokenMap &&\n      !!Object.keys(tokenMap).length &&\n      !!Object.keys(walletMap ?? {}).length\n    ) {\n      const data: Array<any> = Object.keys(tokenMap ?? {})\n      .map((key, _index) => {\n        let item: any\n        let tokenInfo = {\n          ...tokenMap[key],\n          token: key,\n          erc20Symbol: erc20IdIndex[tokenMap[key].tokenId],\n        }\n        const erc20Symbol = key.slice(2)\n        if (walletMap && walletMap[key]) {\n          tokenInfo = {\n            ...tokenInfo,\n            detail: walletMap[key],\n            erc20Symbol: erc20IdIndex[tokenMap[key].tokenId],\n          }\n          const totalAmount = utils.formatUnits(vaultLayer2?.[key].total ?? 0, tokenMap[key].decimals)\n\n          const borrowedAmount = sdk.toBig(tokenInfo.detail?.borrowed ?? 0)\n\n          const tokenValueDollar = new Decimal(totalAmount).times(tokenPrices?.[tokenInfo.symbol] ?? 0)\n          const tokenBorrowedValueDollar = borrowedAmount?.times(tokenPrices?.[tokenInfo.symbol] ?? 0)\n          const isSmallBalance = tokenValueDollar.lt(1) \n            && tokenBorrowedValueDollar.lt(1)\n          \n          const minRepayAmount = utils.formatUnits(\n            tokenInfo.vaultTokenAmounts.minLoanAmount,\n            tokenInfo.decimals,\n          )\n          \n          item = {\n            token: {\n              type: TokenType.vault,\n              value: key,\n              belongAlice: erc20Symbol,\n            },\n            amount: totalAmount?.toString(),\n            available: tokenInfo?.detail?.count ?? 0,\n            smallBalance: isSmallBalance,\n            tokenValueDollar: tokenValueDollar.toString(),\n            name: tokenInfo.token,\n            erc20Symbol,\n            debt:borrowedAmount.toString(),\n            equity: numberFormat(tokenInfo.detail?.equity ?? '0', {\n              fixed: tokenInfo.precision,\n              removeTrailingZero: true,\n              fixedRound: Decimal.ROUND_FLOOR,\n            }),\n            repayDisabled:\n              borrowedAmount.isZero() ||\n              new Decimal(totalAmount).isZero() ||\n              new Decimal(totalAmount).lt(minRepayAmount) ||\n              borrowedAmount.lte(minRepayAmount),\n          }\n        } else {\n          item = {\n            ...tokenInfo,\n            token: {\n              type: TokenType.vault,\n              value: key,\n              belongAlice: erc20Symbol,\n            },\n            amount: 0,\n            available: 0,\n            locked: 0,\n            smallBalance: true,\n            tokenValueDollar: 0,\n            name: key,\n            tokenValueYuan: 0,\n            erc20Symbol,\n            debt: '0',\n            equity: '0',\n            repayDisabled: true\n          }\n        }\n        if (item) {\n          let precision = tokenMap[item.token.value].precision\n          return {\n            ...item,\n            precision: precision,\n\n            // holding: '100-todo',\n            // equity: '100-todo',\n          }\n        } else {\n          return undefined\n        }\n      })\n      .filter((token) => {\n        const tokenInfo: sdk.VaultToken = tokenMap[token.name] \n        if (\n          _.values(marketMap).every(\n            (market) => market.baseTokenId !== tokenInfo.vaultTokenId && market.quoteTokenId !== tokenInfo.vaultTokenId,\n          )\n        ) {\n          return false\n        }\n        const status = tokenMap['LV' + token.erc20Symbol].vaultTokenAmounts.status as number\n        return token && parseVaultTokenStatus(status).loan && parseVaultTokenStatus(status).repay\n      }).sort((a, b) => {\n        const deltaDollar = b.tokenValueDollar - a.tokenValueDollar\n        const deltaAmount = sdk.toBig(b.amount).minus(a.amount).toNumber()\n        const deltaName = b.token.value < a.token.value ? 1 : -1\n        return deltaDollar !== 0 ? deltaDollar : deltaAmount !== 0 ? deltaAmount : deltaName\n      })\n      const totalAssets = data.reduce(\n        (pre, item) => pre.plus(sdk.toBig(item.tokenValueDollar)),\n        sdk.toBig(0),\n      )\n      setAssetsRawData(data)\n      setTotalAsset(totalAssets.toString())\n    } else {\n      setAssetsRawData([])\n      setTotalAsset(EmptyValueTag)\n    }\n  }\n  const startWorker = _.debounce(getAssetsRawData, globalSetup.wait)\n  React.useEffect(() => {\n    if (\n      showNoVaultAccount &&\n      vaultAccountInfoStatus === SagaStatus.UNSET &&\n      vaultAccountInfo?.accountStatus && walletL2Status === SagaStatus.UNSET &&\n      whichBtn &&\n      vaultAccountInfo?.accountStatus === sdk.VaultAccountStatus.IN_STAKING\n    ) {\n      onActionBtnClick(whichBtn)\n    }\n    // enableBtn()\n  }, [\n    whichBtn,\n    walletL2Status,\n    vaultAccountInfo?.accountStatus,\n    activeInfo,\n    assetsRawData,\n    // tokenPriceStatus,\n  ])\n  const walletLayer2Callback = React.useCallback(() => {\n    startWorker()\n  }, [])\n  React.useEffect(() => {\n    if (vaultAccountInfoStatus === SagaStatus.UNSET) {\n      walletLayer2Callback()\n    }\n  }, [vaultAccountInfoStatus])\n  const onRowClick = React.useCallback(\n    ({ row }: { row: R }) => {\n      \n      if ([sdk.VaultAccountStatus.IN_STAKING].includes(vaultAccountInfo?.accountStatus ?? '')) {\n        history.push('/portal/portalDashboard')\n        onGoToSwap({ symbol: row?.token?.value })\n      } else {\n        history.push('/portal')\n        setShowNoVaultAccount({\n          isShow: true,\n          whichBtn: VaultAction.VaultJoin,\n          des: 'labelJoinDesMessage',\n          title: 'labelVaultJoinTitle',\n        })\n      }\n    },\n    [vaultAccountInfo?.accountStatus],\n  )\n  return {\n    btnProps,\n    onBtnClose: () => {\n      setShowNoVaultAccount({ isShow: false, whichBtn: undefined })\n    },\n    forexMap,\n    rawData: assetsRawData as R[],\n    hideAssets: hideL2Assets,\n    allowTrade,\n    setHideSmallBalances,\n    hideSmallBalances,\n    showFilter: true,\n    totalAsset,\n    showNoVaultAccount,\n    actionRow: ({ row }) => {\n      return (\n        <Button\n          onClick={(e) => {\n            e.stopPropagation()\n            onRowClick({ row })\n          }}\n        >\n          {t('labelTrade')}\n        </Button>\n      )\n    },\n    onRowClick: (_, row) => {\n      onRowClick({ row })\n    },\n    positionOpend: [sdk.VaultAccountStatus.IN_REDEEM, sdk.VaultAccountStatus.IN_STAKING]\n      .includes(vaultAccountInfo?.accountStatus as any),\n    onRowClickTrade: ({ row }: { row: R }) => {\n      // debugger\n      onClickTrade(row?.token?.value)\n      // if ([sdk.VaultAccountStatus.IN_STAKING].includes(vaultAccountInfo?.accountStatus ?? '')) {\n      //   history.push('/portal/portalDashboard')\n      //   onSwapPop({ symbol: row?.token?.value })\n      // } else {\n      //   history.push('/portal/portalDashboard')\n\n      //   // setstate\n      //   // setShowNoVaultAccount({\n      //   //   isShow: true,\n      //   //   whichBtn: VaultAction.VaultJoin,\n      //   //   des: 'labelJoinDesMessage',\n      //   //   title: 'labelVaultJoinTitle',\n      //   // })\n      // }\n    },\n    onRowClickRepay: ({ row }: { row: R }) => {\n      onClickRepay(row?.token?.value)\n    },\n    //   onClickRepay(row?.token?.value)\n    //   // if ([sdk.VaultAccountStatus.IN_STAKING].includes(vaultAccountInfo?.accountStatus ?? '')) {\n    //   //   history.push('/portal/portalDashboard')\n    //   //   // todo repay\n    //   // } else {\n    //   //   history.push('/portal')\n    //   //   setShowNoVaultAccount({\n    //   //     isShow: true,\n    //   //     whichBtn: VaultAction.VaultJoin,\n    //   //     des: 'labelJoinDesMessage',\n    //   //     title: 'labelVaultJoinTitle',\n    //   //   })\n    //   // }\n    // },\n    noMinHeight: true\n  }\n}\n\n\n\nexport const useVaultDashboard = ({\n  showLeverage,\n  closeShowLeverage,\n}: {\n  showLeverage: { show: boolean; closeAfterChange: boolean }\n  closeShowLeverage: () => void\n}): {\n  vaultDashBoardPanelUIProps: Omit<VaultDashBoardPanelUIProps, 'showLeverage' | 'closeShowLeverage'> \n  dustCollectorUnAvailableModalProps: DustCollectorUnAvailableModalProps\n  dustCollectorModalProps: DustCollectorProps\n  debtModalProps: DebtModalProps\n  leverageModalProps: LeverageModalProps\n  maximumCreditModalProps: MaximumCreditModalProps\n  collateralDetailsModalProps: CollateralDetailsModalProps\n  noAccountHintModalProps: NoAccountHintModalProps\n  // vaultSwapModalProps: VaultSwapModalProps\n  // smallOrderAlertProps: SmallOrderAlertProps\n  supplyCollateralHintModalProps: SupplyCollateralHintModalProps\n  closeConfirmModalProps: CloseConfirmModalProps\n  settleConfirmModalProps: SettleConfirmModalProps\n  autoRepayModalProps: AutoRepayModalProps\n} => {\n  const _vaultAccountInfo = useVaultAccountInfo()\n  \n  const {\n    vaultAccountInfo,\n    activeInfo,\n    tokenFactors,\n    maxLeverage,\n    collateralTokens,\n    onGoToSwap,\n    onJoinPop,\n    onRepayPop,\n    onRedeemPop,\n    joinBtnStatus,\n    joinBtnLabel,\n  } = _vaultAccountInfo\n  const { t } = useTranslation()\n\n  const {\n    setShowNoVaultAccount,\n    modals: {\n      isShowNoVaultAccount: { isShow: showNoVaultAccount, ...btnProps },\n      isShowVaultJoin,\n      isShowVaultCloseConfirm\n    },\n    setShowAccount,\n    setShowVaultSwap,\n    setShowVaultCloseConfirm,\n    setShowGlobalToast\n  } = useOpenModals()\n\n  const { forexMap, etherscanBaseUrl, getValueInCurrency, exchangeInfo } = useSystem()\n  const {\n    isMobile,\n    currency,\n    hideL2Assets: hideAssets,\n    upColor,\n    defaultNetwork,\n    coinJson,\n    setHideL2Assets,\n    slippage,\n    hideSmallBalances,\n    setHideSmallBalances\n  } = useSettings()\n  const {setToastOpen, closeToast} =useToast()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const priceTag = PriceTag[CurrencyToTag[currency]]\n \n\n  const colors = ['var(--color-success)', 'var(--color-error)', 'var(--color-warning)']\n  const theme = useTheme()\n  const tableRef = React.useRef<HTMLDivElement>()\n  const { detail, setShowDetail, marketProps } = useVaultMarket({ tableRef })\n  const walletMap = makeVaultLayer2({ needFilterZero: true }).vaultLayer2Map ?? {}\n  const {\n    tokenMap: vaultTokenMap,\n    tokenPrices,\n    idIndex: vaultIdIndex,\n    marketMap,\n    marketArray,\n  } = useVaultMap()\n  const { tokenMap, idIndex } = useTokenMap()\n\n  const history = useHistory()\n  const { vaultTickerMap } = useVaultTicker()\n\n  const [localState, setLocalState] = React.useState({\n    modalStatus: 'noModal' as\n      | 'noModal'\n      | 'collateralDetails'\n      | 'collateralDetailsMaxCredit'\n      | 'leverage'\n      | 'leverageMaxCredit'\n      | 'debt'\n      | 'dustCollector'\n      | 'dustCollectorUnavailable'\n      | 'supplyCollateralHint'\n      | 'settleConfirm'\n      | 'autoRepayConfirm',\n    unselectedDustSymbol: [] as string[],\n    leverageLoading: false,\n    checkedAutoRepay: false,\n    penaltyFeeBips: undefined as undefined | number,\n    liquidationMarginLevel: undefined as undefined | string,\n  })\n  const assetPanelProps = useGetVaultAssets({\n    onClickTrade(symbol) {\n      if (sdk.VaultAccountStatus.IN_STAKING === vaultAccountInfo?.accountStatus) {\n        if (symbol === 'LVUSDT') {\n          onGoToSwap({ symbol: 'ETH'})\n        } else {\n          onGoToSwap({ symbol: symbol.slice(2) })\n        }\n      } else {\n        setLocalState({\n          ...localState,\n          modalStatus: 'supplyCollateralHint',\n        })\n      }\n    },\n    onClickRepay(symbol) {\n      if (sdk.VaultAccountStatus.IN_STAKING === vaultAccountInfo?.accountStatus) {\n        onRepayPop({ symbol: symbol.slice(2) })\n      } else {\n        setLocalState({\n          ...localState,\n          modalStatus: 'supplyCollateralHint',\n        })\n      }\n    },\n    // onClickTrade(symbol) {\n    //   if (sdk.VaultAccountStatus.IN_STAKING === vaultAccountInfo?.accountStatus) {\n    //     onRe({ symbol: symbol })\n    //   } else {\n    //     setLocalState({\n    //       ...localState,\n    //       modalStatus: 'supplyCollateralHint',\n    //     })\n    //   }\n    // },\n  })\n  const { account } = useAccount()\n  const { updateVaultLayer2 } = useVaultLayer2()\n  const {\n    toggle: { VaultDustCollector },\n  } = useToggle()\n\n  const changeLeverage = async (leverage: number) => {\n    setLocalState({\n      ...localState,\n      leverageLoading: true,\n    })\n    const response = await LoopringAPI.vaultAPI\n      ?.submitLeverage(\n        {\n          request: {\n            accountId: account.accountId.toString(),\n            leverage: leverage.toString(),\n          },\n          apiKey: account.apiKey,\n        },\n        '1',\n      )\n      .finally(() => {\n        setTimeout(() => {\n          setLocalState({\n            ...localState,\n            leverageLoading: false,\n          })\n        }, 500)\n      })\n\n    if ((response as any)?.resultInfo?.code) {\n      if (response.resultInfo.message.includes('ERR_VAULT_LEVERAGE_TOO_LARGE')) {\n        setShowAccount({\n          isShow: true,\n          step: AccountStep.General_Failed,\n          info: {\n            errorMessage: t('labelVaultChangeLeverageFailedTooSmall'),\n            title: t('labelVaultChangeLeverageFailed'),\n          },\n        })\n      } else {\n        setShowAccount({\n          isShow: true,\n          step: AccountStep.General_Failed,\n          info: {\n            errorMessage: t('labelUnknown'),\n            title: t('labelVaultChangeLeverageFailed'),\n          },\n        })\n      }\n      throw response\n    }\n    updateVaultLayer2({})\n  }\n  const dustsAssets = vaultAccountInfo?.userAssets?.filter((asset) => {\n    const foundKey = keys(marketMap).find((key) => {\n      const market = marketMap[key]\n      // @ts-ignore\n      return market.baseTokenId === asset.tokenId\n    })\n    const minimum = foundKey && marketMap[foundKey].minTradeAmount.base\n    return (\n      minimum &&\n      new Decimal(asset.total).greaterThan('0') &&\n      new Decimal(asset.total).lessThan(minimum)\n    )\n  })\n  const dusts = dustsAssets?.map((asset) => {\n    // @ts-ignore\n    const token = vaultTokenMap[vaultIdIndex[asset.tokenId]]\n    const vaultSymbol = token.symbol\n    const originSymbol = vaultSymbol.slice(2)\n    const checked = !localState.unselectedDustSymbol.includes(originSymbol)\n    const price = tokenPrices[vaultSymbol]\n    return {\n      symbol: originSymbol,\n      coinJSON: coinJson[originSymbol],\n      amount: numberFormat(utils.formatUnits(asset.total, token.decimals), {\n        fixed: token.precision,\n        removeTrailingZero: true,\n      }),\n      checked,\n      valueInCurrency:\n        price &&\n        getValueInCurrency(\n          new Decimal(price).mul(utils.formatUnits(asset.total, token.decimals)).toString(),\n        )\n          ? fiatNumberDisplay(\n              getValueInCurrency(\n                new Decimal(price).mul(utils.formatUnits(asset.total, token.decimals)).toString(),\n              ),\n              currency,\n            )\n          : EmptyValueTag,\n      onCheck() {\n        if (checked) {\n          setLocalState({\n            ...localState,\n\n            unselectedDustSymbol: localState.unselectedDustSymbol.concat(originSymbol),\n          })\n        } else {\n          setLocalState({\n            ...localState,\n            unselectedDustSymbol: localState.unselectedDustSymbol.filter(\n              (symbol) => symbol !== originSymbol,\n            ),\n          })\n        }\n      },\n    }\n  })\n  const checkedDusts = dustsAssets?.filter((asset) => {\n    const token = vaultTokenMap[vaultIdIndex[asset.tokenId!]]\n    const vaultSymbol = token.symbol\n    const originSymbol = vaultSymbol.slice(2)\n    return !localState.unselectedDustSymbol.includes(originSymbol)\n  })\n\n  const totalDustsInUSDT = checkedDusts\n    ? numberFormat(\n        numberStringListSum(\n          checkedDusts.map((asset) => {\n            // @ts-ignore\n            const token = vaultTokenMap[vaultIdIndex[asset.tokenId]]\n            const vaultSymbol = token.symbol\n            const price = tokenPrices[vaultSymbol]\n            return new Decimal(price).mul(utils.formatUnits(asset.total, token.decimals)).toString()\n          }),\n        ),\n        { fixed: 2, removeTrailingZero: true }, // 2 is USDT precision\n      )\n    : undefined\n  const totalDustsInCurrency =\n    totalDustsInUSDT && getValueInCurrency(totalDustsInUSDT)\n      ? fiatNumberDisplay(getValueInCurrency(totalDustsInUSDT), currency)\n      : EmptyValueTag\n\n  const [converting, setConverting] = React.useState(false)\n  const convert = async () => {\n    if (!checkedDusts || !exchangeInfo) return\n    setConverting(true)\n    try {\n      const { broker } = await LoopringAPI.userAPI?.getAvailableBroker({\n        type: 4,\n      })!\n      const dustTransfers = await Promise.all(\n        checkedDusts.map(async (asset) => {\n          const tokenId = asset.tokenId as unknown as number\n          const { offchainId } = await LoopringAPI.userAPI?.getNextStorageId(\n            {\n              accountId: account.accountId,\n              sellTokenId: tokenId,\n            },\n            account.apiKey,\n          )!\n          return {\n            exchange: exchangeInfo.exchangeAddress,\n            payerAddr: account.accAddress,\n            payerId: account.accountId,\n            payeeId: 0,\n            payeeAddr: broker,\n            storageId: offchainId,\n            token: {\n              tokenId: tokenId,\n              volume: asset.total,\n            },\n            maxFee: {\n              tokenId: tokenId,\n              volume: '0',\n            },\n            validUntil: getTimestampDaysLater(DAYS),\n            memo: '',\n          }\n        }),\n      )\n      const dustList = checkedDusts.map((dust) => {\n        const vaultToken = vaultTokenMap[vaultIdIndex[dust.tokenId!]]\n        const price = tokenPrices[vaultToken.symbol]\n        const originTokenSymbol = vaultToken.symbol.slice(2)\n        return {\n          symbol: originTokenSymbol,\n          coinJSON: coinJson[originTokenSymbol],\n          amount: numberFormat(utils.formatUnits(dust.total, vaultToken.decimals), {\n            fixed: vaultToken.precision,\n            removeTrailingZero: true,\n          }),\n          amountRaw: utils.formatUnits(dust.total, vaultToken.decimals),\n          valueInCurrency:\n            price &&\n            getValueInCurrency(\n              new Decimal(price).mul(utils.formatUnits(dust.total, vaultToken.decimals)).toString(),\n            )\n              ? fiatNumberDisplay(\n                  getValueInCurrency(\n                    new Decimal(price)\n                      .mul(utils.formatUnits(dust.total, vaultToken.decimals))\n                      .toString(),\n                  ),\n                  currency,\n                )\n              : undefined,\n          valueInCurrencyRaw: price\n            ? getValueInCurrency(\n                new Decimal(price)\n                  .mul(utils.formatUnits(dust.total, vaultToken.decimals))\n                  .toString(),\n              )\n            : undefined,\n        }\n      })\n      setShowAccount({\n        isShow: true,\n        step: AccountStep.VaultDustCollector_In_Progress,\n        info: {\n          totalValueInCurrency: fiatNumberDisplay(\n            numberStringListSum(dustList.map((dust) => dust.valueInCurrencyRaw ?? '0')),\n            currency,\n          ),\n          convertedInUSDT: numberFormat(\n            numberStringListSum(dustList.map((dust) => dust.valueInCurrencyRaw ?? '0')),\n            { fixed: 2 },\n          ),\n          repaymentInUSDT: undefined,\n          time: undefined,\n          dusts: dustList.map((dust) => {\n            return {\n              symbol: dust.symbol,\n              coinJSON: dust.coinJSON,\n              amount: dust.amount,\n              valueInCurrency: dust.valueInCurrency,\n            }\n          }),\n        },\n      })\n\n      const response = await LoopringAPI.vaultAPI?.submitDustCollector(\n        {\n          dustTransfers: dustTransfers,\n          apiKey: account.apiKey,\n          accountId: account.accountId,\n          eddsaKey: account.eddsaKey.sk,\n        },\n        '1',\n      )\n      if (\n        (response as sdk.RESULT_INFO).code ||\n        (response as sdk.RESULT_INFO).message ||\n        !response\n      ) {\n        throw response\n      }\n      setLocalState({\n        ...localState,\n        modalStatus: 'noModal',\n        unselectedDustSymbol: [],\n      })\n      updateVaultLayer2({})\n      await sdk.sleep(SUBMIT_PANEL_CHECK)\n      const response2 = await LoopringAPI?.vaultAPI?.getVaultGetOperationByHash(\n        {\n          accountId: account?.accountId?.toString(),\n          hash: response.hash,\n        },\n        account.apiKey,\n        '1',\n      )\n      if (response2?.raw_data?.operation?.status == sdk.VaultOperationStatus.VAULT_STATUS_FAILED) {\n        throw sdk.VaultOperationStatus.VAULT_STATUS_FAILED\n      }\n      setConverting(false)\n\n      const status =\n        response2?.raw_data?.operation?.status === sdk.VaultOperationStatus.VAULT_STATUS_SUCCEED\n          ? 'success'\n          : 'pending'\n\n      setShowAccount({\n        isShow: store.getState().modals.isShowAccount.isShow,\n        step:\n          status == 'success'\n            ? AccountStep.VaultDustCollector_Success\n            : AccountStep.VaultDustCollector_In_Progress,\n        info: {\n          totalValueInCurrency: fiatNumberDisplay(\n            numberStringListSum(dustList.map((dust) => dust.valueInCurrencyRaw ?? '0')),\n            currency,\n          ),\n          convertedInUSDT: numberFormat(\n            numberStringListSum(dustList.map((dust) => dust.valueInCurrencyRaw ?? '0')),\n            { fixed: 2 },\n          ),\n          repaymentInUSDT: numberFormat(utils.formatUnits(response2!.operation.amountOut, 6), {\n            fixed: 2,\n          }),\n          time: response2?.operation.createdAt,\n          dusts: dustList.map((dust) => {\n            return {\n              symbol: dust.symbol,\n              coinJSON: dust.coinJSON,\n              amount: dust.amount,\n              valueInCurrency: dust.valueInCurrency,\n            }\n          }),\n        },\n      })\n      await sdk.sleep(SUBMIT_PANEL_AUTO_CLOSE)\n      updateVaultLayer2({})\n    } finally {\n      setConverting(false)\n    }\n  }\n\n  const showMarginLevelAlert =\n    vaultAccountInfo?.marginLevel && new Decimal(vaultAccountInfo.marginLevel).lessThan('1.15')\n\n  const collateralToken =\n    vaultAccountInfo &&\n    vaultAccountInfo.collateralInfo &&\n    tokenMap[idIndex[vaultAccountInfo.collateralInfo.collateralTokenId]]\n      ? tokenFactors.find(\n          (token) =>\n            token.symbol ===\n            tokenMap[idIndex[vaultAccountInfo.collateralInfo.collateralTokenId]].symbol,\n        )\n      : undefined\n\n  const hideLeverage = (vaultAccountInfo as any)?.accountType === 0\n  const [assetsTab, setAssetsTab] = React.useState('assetsView' as 'assetsView' | 'positionsView')\n  const {vaultLayer2, status: vaultLayer2Status} = useVaultLayer2()\n  const vaultPositionsTableProps: VaultPositionsTableProps = {\n    rawData: filterPositions(vaultLayer2!, vaultTokenMap, tokenPrices)\n    .map((symbol) => {\n      const originSymbol = symbol.slice(2)\n      const asset = vaultLayer2 ? vaultLayer2[symbol] : undefined\n      const tokenInfo = vaultTokenMap?.[symbol]\n      if (!asset || !tokenInfo) return undefined\n      const position = new Decimal(\n        utils.formatUnits(BigNumber.from(asset.netAsset).add(asset.interest), tokenInfo.decimals),\n      )\n      if (symbol === 'LVUSDT' || position.isZero())\n        return undefined\n      \n      return {\n        tokenPair: {\n          coinJson: [coinJson[originSymbol], coinJson['USDT']],\n          pair: `${originSymbol}/USDT`,\n          leverage: vaultAccountInfo?.leverage + 'x',\n          marginLevel: vaultAccountInfo?.marginLevel ?? '',\n        },\n        direction: position.isPos() ? 'long' : 'short' as 'long' | 'short',\n        holding: numberFormatThousandthPlace(position.abs().toString(), {\n          fixed: tokenInfo.precision,\n          removeTrailingZero: true\n        }),\n        onClickTrade: () => {\n          onGoToSwap({ symbol: originSymbol }) \n        },\n        onClickClose: () => {\n          // setShowGlobalToast({\n          //   isShow: true,\n          //   info: {\n          //     content: 'aaa',\n          //     type: ToastType.error\n          //   }\n          // })\n          // setToastOpenset({\n          //   open: true,\n          //   content: 'e.message',\n          //   type: ToastType.error\n          // })\n          setShowVaultCloseConfirm({\n            isShow: true,\n            symbol: symbol\n          })\n          // closePosition(symbol)\n          // .then(response2 => {\n          //   if (response2?.operation.status === sdk.VaultOperationStatus.VAULT_STATUS_FAILED) {\n          //     throw new Error('failed')\n          //   }\n            \n          //   setShowGlobalToast({\n          //     isShow: true,\n          //     info: {\n          //       content: 'Closed position successfully',\n          //       type: ToastType.success\n          //     }\n          //   })\n          // }).catch((e) => {\n          //   setShowGlobalToast({\n          //     isShow: true,\n          //     info: {\n          //       content: 'Close position failed',\n          //       type: ToastType.error\n          //     }\n          //   })\n          // }).finally(() => {\n          //   updateVaultLayer2({})\n          // })\n        },\n        valueInUSD: position.abs().mul(tokenPrices[symbol])\n      }\n    }),\n    onRowClick: (index: number, row: PositionItem) => {},\n    isLoading: false,\n    hideAssets: hideAssets,\n    showFilter: true,\n    onClickDustCollector: () => {\n      if (VaultDustCollector.enable) {\n        setLocalState({\n          ...localState,\n          modalStatus: 'dustCollector',\n        })\n      } else {\n        setLocalState({\n          ...localState,\n          modalStatus: 'dustCollectorUnavailable',\n        })\n      }\n    },\n    hideDustCollector: false,\n    hideSmallBalances: hideSmallBalances,\n    setHideSmallBalances: setHideSmallBalances,\n  }\n\n  \n  const vaultDashBoardPanelUIProps = {\n    vaultAccountInfo,\n    activeInfo,\n    tokenFactors,\n    maxLeverage,\n    collateralTokens,\n    t,\n    forexMap,\n    etherscanBaseUrl,\n    getValueInCurrency,\n    exchangeInfo,\n    isMobile,\n    currency,\n    hideAssets,\n    upColor,\n    defaultNetwork,\n    coinJson,\n    network,\n    isShowVaultJoin,\n    setShowAccount,\n    // setShowVaultLoan,\n    priceTag,\n    // onActionBtnClick,\n    showNoVaultAccount,\n    setShowNoVaultAccount,\n    btnProps,\n    colors,\n    theme,\n    tableRef,\n    detail,\n    setShowDetail,\n    marketProps,\n    walletMap,\n    vaultTokenMap,\n    tokenPrices,\n    vaultIdIndex,\n    marketMap,\n    marketArray,\n    tokenMap,\n    idIndex,\n    history,\n    vaultTickerMap,\n    localState,\n    setLocalState,\n    account,\n    updateVaultLayer2,\n    VaultDustCollector,\n    changeLeverage,\n    dustsAssets,\n    dusts,\n    checkedDusts,\n    totalDustsInUSDT,\n    totalDustsInCurrency,\n    converting,\n    setConverting,\n    convert,\n    showMarginLevelAlert: showMarginLevelAlert ? true : false,\n    collateralToken,\n    hideLeverage,\n    assetPanelProps,\n    marginLevel: vaultAccountInfo?.marginLevel ?? '',\n    _vaultAccountInfo: _vaultAccountInfo,\n    onClickCollateralManagement: () => {\n      if (vaultAccountInfo?.accountStatus === sdk.VaultAccountStatus.IN_REDEEM) {\n        setShowNoVaultAccount({\n          isShow: true,\n          des: 'labelRedeemDesMessage',\n          title: 'labelRedeemTitle',\n        })\n      } else {\n        onJoinPop({})\n      }\n    },\n    onClickSettle: () => {\n      onRedeemPop({})\n    },\n    liquidationThreshold: localState.liquidationMarginLevel\n      ? localState.liquidationMarginLevel\n      : EmptyValueTag,\n    liquidationPenalty: localState.penaltyFeeBips\n      ? toPercent(localState.penaltyFeeBips * 100, 2)\n      : EmptyValueTag,\n    onClickPortalTrade: () => {\n      if (vaultAccountInfo?.accountStatus === sdk.VaultAccountStatus.IN_STAKING) {\n        onGoToSwap({})\n      } else {\n        setLocalState({\n          ...localState,\n          modalStatus: 'supplyCollateralHint',\n        })\n      }\n    },\n    assetsTab: assetsTab,\n    onChangeAssetsTab: (tab: 'assetsView' | 'positionsView') => {\n      setAssetsTab(tab)\n    },\n    onClickRecord: () => {\n      history.push('/l2assets/history/VaultRecords')\n    },\n    vaultPositionsTableProps,\n    onClickHideShowAssets: () => {\n      setHideL2Assets(!hideAssets)\n    },\n    vaultAccountActive: vaultAccountInfo?.accountStatus === sdk.VaultAccountStatus.IN_STAKING,\n    totalEquity: tryFn(\n      () =>\n        fiatNumberDisplay(\n          getValueInCurrency(\n            new Decimal(vaultAccountInfo!.totalEquityOfUsdt)\n              .add(vaultAccountInfo!.totalCollateralOfUsdt)\n              .toString(),\n          ),\n          currency,\n        ),\n      () => EmptyValueTag,\n    ),\n    showSettleBtn: vaultAccountInfo?.accountStatus === sdk.VaultAccountStatus.IN_STAKING,\n    btnsDisabled: account.readyState !== AccountStatus.ACTIVATED,\n    onClickBuy: (detail) => {\n      const symbol = detail?.tokenInfo.symbol?.slice(2)\n      if (symbol === 'USDT') {\n        onGoToSwap({ isSell: true })\n      } else {\n        onGoToSwap({ symbol })\n      }\n    },\n    onClickSell: (detail) => {\n      const symbol = detail?.tokenInfo.symbol?.slice(2)\n      if (symbol === 'USDT') {\n        onGoToSwap({ isSell: false })\n      } else {\n        onGoToSwap({ symbol })\n      }\n    },\n    didAccountSignIn: account.readyState === AccountStatus.ACTIVATED,\n  }\n  const noVaultAccountDialogBtn = (() => {\n    switch (account.readyState) {\n      case AccountStatus.UN_CONNECT:\n      case AccountStatus.LOCKED:\n      case AccountStatus.NO_ACCOUNT:\n      case AccountStatus.NOT_ACTIVE:\n        return <WalletConnectL2Btn />\n      case AccountStatus.DEPOSITING:\n        return (\n          <Box\n            flex={1}\n            display={'flex'}\n            justifyContent={'center'}\n            flexDirection={'column'}\n            alignItems={'center'}\n          >\n            <img\n              className='loading-gif'\n              alt={'loading'}\n              width='60'\n              src={`${SoursURL}images/loading-line.gif`}\n            />\n            <Typography marginY={3} variant={isMobile ? 'h4' : 'h1'} textAlign={'center'}>\n              {t('describeTitleOpenAccounting', {\n                l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n              })}\n            </Typography>\n          </Box>\n        )\n      case AccountStatus.ERROR_NETWORK:\n        return (\n          <Box\n            flex={1}\n            display={'flex'}\n            justifyContent={'center'}\n            flexDirection={'column'}\n            alignItems={'center'}\n          >\n            <Typography marginY={3} variant={isMobile ? 'h4' : 'h1'} textAlign={'center'}>\n              {t('describeTitleOnErrorNetwork', {\n                connectName: account.connectName,\n              })}\n            </Typography>\n          </Box>\n        )\n      case AccountStatus.ACTIVATED:\n        if (sdk.VaultAccountStatus.IN_REDEEM === vaultAccountInfo?.accountStatus) {\n          return (\n            <Box\n              flex={1}\n              display={'flex'}\n              justifyContent={'center'}\n              flexDirection={'column'}\n              alignItems={'center'}\n            >\n              <img\n                className='loading-gif'\n                alt={'loading'}\n                width='60'\n                src={`${SoursURL}images/loading-line.gif`}\n              />\n            </Box>\n          )\n        } else if (\n          [sdk.VaultAccountStatus.UNDEFINED, sdk.VaultAccountStatus.FREE].includes(\n            (vaultAccountInfo?.accountStatus ?? '') as any,\n          ) ||\n          vaultAccountInfo == undefined ||\n          vaultAccountInfo?.accountStatus == undefined\n        ) {\n          return (\n            <MyButton\n              size={'medium'}\n              className={'vaultInProcessing'}\n              onClick={() => {\n                setShowNoVaultAccount({ isShow: false, whichBtn: undefined })\n                onJoinPop(true)\n              }}\n              variant={'contained'}\n              fullWidth={true}\n              sx={{ minWidth: 'var(--walletconnect-width)' }}\n              loading={(joinBtnStatus === TradeBtnStatus.LOADING ? 'true' : 'false') as any}\n              disabled={\n                joinBtnStatus === TradeBtnStatus.DISABLED ||\n                joinBtnStatus === TradeBtnStatus.LOADING\n              }\n            >\n              {joinBtnLabel}\n            </MyButton>\n          )\n        } else if (\n          activeInfo?.hash ||\n          (vaultAccountInfo?.accountStatus &&\n            sdk.VaultAccountStatus.IN_STAKING !== vaultAccountInfo?.accountStatus)\n        ) {\n          return (\n            <Box\n              flex={1}\n              display={'flex'}\n              justifyContent={'center'}\n              flexDirection={'column'}\n              alignItems={'center'}\n            >\n              <img\n                className='loading-gif'\n                alt={'loading'}\n                width='60'\n                src={`${SoursURL}images/loading-line.gif`}\n              />\n              <Typography marginY={3} variant={'body1'} textAlign={'center'}>\n                {t('labelVaultAccountWait', {\n                  l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                })}\n              </Typography>\n            </Box>\n          )\n        } else {\n          return (\n            <MyButton\n              size={'medium'}\n              className={'vaultInProcessing'}\n              onClick={() => {\n                setShowNoVaultAccount({ isShow: false, whichBtn: undefined })\n              }}\n              loading={'false'}\n              variant={'contained'}\n              fullWidth={true}\n              sx={{ minWidth: 'var(--walletconnect-width)' }}\n            >\n              {t('labelVaultCloseBtn')}\n            </MyButton>\n          )\n        }\n      default:\n        return <></>\n    }\n  })()\n  React.useEffect(() => {\n    if (!account.apiKey) return\n    LoopringAPI.vaultAPI?.getVaultConfig(account.apiKey, '1').then((res) => {\n      if (res && res.data.penaltyFeeBips !== undefined) {\n        setLocalState((state) => ({\n          ...state,\n          penaltyFeeBips: res.data.penaltyFeeBips,\n          liquidationMarginLevel: res.data.liquidationMarginLevel,\n        }))\n      }\n    })\n  }, [account.apiKey])\n\n  React.useEffect(() => {\n    if (localState.checkedAutoRepay || vaultLayer2Status !== SagaStatus.UNSET) return\n    \n    const list = checkHasTokenNeedRepay()\n    if (list.length > 0) {\n      setLocalState((state) => ({\n        ...state,\n        modalStatus: 'autoRepayConfirm',\n        checkedAutoRepay: true\n      }))\n    } else {\n      setLocalState((state) => ({\n        ...state,\n        checkedAutoRepay: true\n      }))\n    }\n  }, [vaultLayer2Status, localState.checkedAutoRepay])\n  \n  return {\n    // vaultSwapModalProps: vaultSwapModalProps,\n    vaultDashBoardPanelUIProps,\n    dustCollectorUnAvailableModalProps: {\n      open: localState.modalStatus === 'dustCollectorUnavailable' && !showLeverage.show,\n      onClose: () => {\n        setLocalState({\n          ...localState,\n          modalStatus: 'noModal',\n        })\n      },\n    },\n    dustCollectorModalProps: {\n      open: localState.modalStatus === 'dustCollector' && !showLeverage.show,\n      onClose: () => {\n        setLocalState({\n          ...localState,\n          modalStatus: 'noModal',\n          unselectedDustSymbol: [],\n        })\n      },\n      converting,\n      dusts,\n      onClickConvert: convert,\n      convertBtnDisabled: (dusts?.find((dust) => dust.checked) ? false : true) || converting,\n      totalValueInCurrency: totalDustsInCurrency,\n      totalValueInUSDT: totalDustsInUSDT ?? EmptyValueTag,\n      onClickRecords: () => {\n        history.push('/l2assets/history/VaultRecords')\n      },\n    },\n    debtModalProps: {\n      open: localState.modalStatus === 'debt' && !showLeverage.show,\n      onClose: () => {\n        setLocalState({\n          ...localState,\n          modalStatus: 'noModal',\n        })\n      },\n      borrowedVaultTokens: vaultAccountInfo?.userAssets\n        ?.filter((asset) => new Decimal(asset.borrowed).greaterThan('0'))\n        .map((asset) => {\n          const vaultSymbol = vaultIdIndex[asset.tokenId as unknown as number] as unknown as string\n          const vaultToken = vaultTokenMap[vaultSymbol]\n          const originSymbol = vaultSymbol?.replace('LV', '')\n          const price = tokenPrices[vaultSymbol]\n          const borrowedAmount = vaultToken\n            ? utils.formatUnits(asset.borrowed, vaultToken.decimals)\n            : undefined\n          return {\n            symbol: vaultSymbol?.slice(2),\n            coinJSON: coinJson[originSymbol],\n            amount: borrowedAmount\n              ? numberFormat(borrowedAmount, {\n                  fixed: vaultToken?.precision,\n                  removeTrailingZero: true,\n                })\n              : EmptyValueTag,\n            valueInCurrency:\n              price &&\n              borrowedAmount &&\n              getValueInCurrency(new Decimal(price).mul(borrowedAmount).toString())\n                ? fiatNumberDisplay(\n                    getValueInCurrency(new Decimal(price).mul(borrowedAmount).toString()),\n                    currency,\n                  )\n                : EmptyValueTag,\n            onClick: () => {\n              setShowVaultLoan({\n                isShow: true,\n                info: { symbol: vaultSymbol },\n                type: VaultLoanType.Repay,\n              })\n            },\n          }\n        }),\n      totalDebt:\n        vaultAccountInfo?.totalDebtOfUsdt && getValueInCurrency(vaultAccountInfo?.totalDebtOfUsdt)\n          ? fiatNumberDisplay(getValueInCurrency(vaultAccountInfo?.totalDebtOfUsdt), currency)\n          : EmptyValueTag,\n      totalFundingFee:\n        vaultAccountInfo?.totalInterestOfUsdt &&\n        getValueInCurrency(vaultAccountInfo?.totalInterestOfUsdt)\n          ? fiatNumberDisplay(getValueInCurrency(vaultAccountInfo?.totalInterestOfUsdt), currency)\n          : EmptyValueTag,\n      totalBorrowed:\n        vaultAccountInfo?.totalBorrowedOfUsdt &&\n        getValueInCurrency(vaultAccountInfo?.totalBorrowedOfUsdt)\n          ? fiatNumberDisplay(getValueInCurrency(vaultAccountInfo?.totalBorrowedOfUsdt), currency)\n          : EmptyValueTag,\n    },\n    leverageModalProps: {\n      isLoading: localState.leverageLoading,\n      open:\n        localState.modalStatus === 'leverage' ||\n        (showLeverage.show && localState.modalStatus !== 'leverageMaxCredit'),\n      onClose: () => {\n        closeShowLeverage()\n        setLocalState({\n          ...localState,\n          modalStatus: 'noModal',\n        })\n      },\n      onClickMaxCredit: () => {\n        setLocalState({\n          ...localState,\n          modalStatus: 'leverageMaxCredit',\n        })\n      },\n      maxLeverage: maxLeverage ? Number(maxLeverage) : 0,\n      onClickReduce: async () => {\n        if (!vaultAccountInfo?.leverage) return\n        await changeLeverage(Number(vaultAccountInfo?.leverage) - 1)\n        if (showLeverage.show && showLeverage.closeAfterChange) {\n          closeShowLeverage()\n        }\n      },\n      onClickAdd: async () => {\n        if (!vaultAccountInfo?.leverage) return\n        await changeLeverage(Number(vaultAccountInfo?.leverage) + 1)\n        if (showLeverage.show && showLeverage.closeAfterChange) {\n          closeShowLeverage()\n        }\n      },\n      onClickLeverage: async (leverage) => {\n        await changeLeverage(leverage)\n        if (showLeverage.show && showLeverage.closeAfterChange) {\n          closeShowLeverage()\n        }\n      },\n      currentLeverage: vaultAccountInfo?.leverage ? Number(vaultAccountInfo?.leverage) : 0,\n      maximumCredit:\n        (vaultAccountInfo as any)?.maxCredit &&\n        getValueInCurrency((vaultAccountInfo as any)?.maxCredit)\n          ? fiatNumberDisplay(getValueInCurrency((vaultAccountInfo as any)?.maxCredit), currency)\n          : EmptyValueTag,\n      borrowed:\n        vaultAccountInfo?.totalBorrowedOfUsdt &&\n        getValueInCurrency(vaultAccountInfo?.totalBorrowedOfUsdt)\n          ? fiatNumberDisplay(getValueInCurrency(vaultAccountInfo?.totalBorrowedOfUsdt), currency)\n          : EmptyValueTag,\n      borrowAvailable:\n        vaultAccountInfo &&\n        collateralToken &&\n        getValueInCurrency(\n          new Decimal(vaultAccountInfo.totalEquityOfUsdt)\n            .add(vaultAccountInfo.totalCollateralOfUsdt)\n            .mul(vaultAccountInfo.leverage)\n            .mul(collateralToken.factor)\n            .minus(vaultAccountInfo.totalBorrowedOfUsdt)\n            .toString(),\n        )\n          ? fiatNumberDisplay(\n              getValueInCurrency(\n                new Decimal(vaultAccountInfo.totalEquityOfUsdt)\n                  .add(vaultAccountInfo.totalCollateralOfUsdt)\n                  .mul(vaultAccountInfo.leverage)\n                  .mul(collateralToken.factor)\n                  .minus(vaultAccountInfo.totalBorrowedOfUsdt)\n                  .toString(),\n              ),\n              currency,\n            )\n          : EmptyValueTag,\n    },\n    maximumCreditModalProps: {\n      open:\n        localState.modalStatus === 'leverageMaxCredit' ||\n        (localState.modalStatus === 'collateralDetailsMaxCredit' && !showLeverage.show),\n      onClose: () => {\n        setLocalState({\n          ...localState,\n          modalStatus: 'noModal',\n        })\n      },\n      onClickBack: () => {\n        if (localState.modalStatus === 'collateralDetailsMaxCredit') {\n          setLocalState({\n            ...localState,\n            modalStatus: 'collateralDetails',\n          })\n        } else if (localState.modalStatus === 'leverageMaxCredit') {\n          setLocalState({\n            ...localState,\n            modalStatus: 'leverage',\n          })\n        }\n      },\n      collateralFactors:\n        tokenFactors?.map((tokenFactor) => ({\n          name: tokenFactor.symbol,\n          collateralFactor: numberFormat(tokenFactor.factor, { fixed: 1 }),\n        })) ?? [],\n      maxLeverage: maxLeverage ?? EmptyValueTag,\n    },\n    collateralDetailsModalProps: {\n      open: localState.modalStatus === 'collateralDetails' && !showLeverage.show,\n      onClose: () => {\n        setLocalState({\n          ...localState,\n          modalStatus: 'noModal',\n        })\n      },\n      onClickMaxCredit: () => {\n        setLocalState({\n          ...localState,\n          modalStatus: 'collateralDetailsMaxCredit',\n        })\n      },\n\n      collateralTokens: (collateralTokens ?? []).map((collateralToken) => {\n        const tokenSymbol = idIndex[collateralToken.collateralTokenId]\n        const amount =\n          collateralToken.collateralTokenAmount && tokenMap[tokenSymbol]\n            ? utils.formatUnits(\n                collateralToken.collateralTokenAmount,\n                tokenMap[tokenSymbol].decimals,\n              )\n            : undefined\n        return {\n          name: tokenSymbol,\n          amount: amount\n            ? numberFormat(amount, {\n                fixed: tokenMap[tokenSymbol].precision,\n                removeTrailingZero: true,\n              })\n            : EmptyValueTag,\n          logo: '',\n          valueInCurrency:\n            amount &&\n            tokenPrices['LV' + tokenSymbol] &&\n            forexMap &&\n            forexMap[currency] &&\n            getValueInCurrency(new Decimal(tokenPrices['LV' + tokenSymbol]).mul(amount).toString())\n              ? fiatNumberDisplay(\n                  getValueInCurrency(\n                    new Decimal(tokenPrices['LV' + tokenSymbol]).mul(amount).toString(),\n                  ),\n                  currency,\n                )\n              : EmptyValueTag,\n        }\n      }),\n      maxCredit:\n        (vaultAccountInfo as any)?.maxCredit &&\n        getValueInCurrency((vaultAccountInfo as any)?.maxCredit)\n          ? numberFormatThousandthPlace(getValueInCurrency((vaultAccountInfo as any)?.maxCredit), {\n              fixed: 2,\n              currency,\n            })\n          : EmptyValueTag,\n      totalCollateral:\n        vaultAccountInfo?.totalCollateralOfUsdt &&\n        getValueInCurrency(vaultAccountInfo?.totalCollateralOfUsdt)\n          ? numberFormatThousandthPlace(\n              getValueInCurrency(vaultAccountInfo?.totalCollateralOfUsdt),\n              {\n                fixed: 2,\n                currency,\n              },\n            )\n          : EmptyValueTag,\n      coinJSON:\n        vaultAccountInfo?.collateralInfo &&\n        coinJson[idIndex[vaultAccountInfo.collateralInfo.collateralTokenId]],\n    },\n    noAccountHintModalProps: {\n      open: showNoVaultAccount && !isShowVaultJoin?.isShow,\n      onClose: () => setShowNoVaultAccount({ isShow: false, whichBtn: undefined }),\n      title: t(btnProps.title),\n      des: (\n        <Trans\n          i18nKey={btnProps.des}\n          tOptions={{\n            layer2: L1L2_NAME_DEFINED[network].layer2,\n            l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n            loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n            l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n            l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n            ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n          }}\n        />\n      ),\n      dialogBtn: noVaultAccountDialogBtn,\n    },\n    // smallOrderAlertProps: smallOrderAlertProps,\n    supplyCollateralHintModalProps: {\n      open: localState.modalStatus === 'supplyCollateralHint',\n      onClose: () => {\n        setLocalState({ ...localState, modalStatus: 'noModal' })\n      },\n      onClickSupply: () => {\n        setLocalState({ ...localState, modalStatus: 'noModal' })\n        onJoinPop({})\n      },\n    },\n    closeConfirmModalProps: {\n      open: isShowVaultCloseConfirm.isShow,\n      onClose: () => {\n        setShowVaultCloseConfirm({ isShow: false, symbol: undefined })\n      },\n      onConfirm: async () => {\n        const { symbol } = isShowVaultCloseConfirm\n        setShowVaultCloseConfirm({ isShow: false, symbol: undefined })\n        closePositionAndRepayIfNeeded(symbol!)\n          .then(response2 => {\n            if (response2?.operation.status === sdk.VaultOperationStatus.VAULT_STATUS_FAILED) {\n              throw new Error('failed')\n            }\n            setShowGlobalToast({\n              isShow: true,\n              info: {\n                content: 'Closed position successfully',\n                type: ToastType.success\n              }\n            })\n          }).catch((e) => {\n            setShowGlobalToast({\n              isShow: true,\n              info: {\n                content: 'Close position failed',\n                type: ToastType.error\n              }\n            })\n          }).finally(() => {\n            \n            updateVaultLayer2({})\n          })\n      },\n    },\n    settleConfirmModalProps: {\n      open: localState.modalStatus === 'settleConfirm',\n      onClose: () => {\n        setLocalState({\n          ...localState,\n          modalStatus: 'noModal'\n        })\n      },\n      onConfirm: async () => {\n\n      },\n    },\n    autoRepayModalProps: {\n      open: localState.modalStatus === 'autoRepayConfirm',\n      onClose: () => {\n        setLocalState({\n          ...localState,\n          modalStatus: 'noModal'\n        })\n      },\n      onConfirm: async () => {\n        const list = checkHasTokenNeedRepay()\n        setLocalState({\n          ...localState,\n          modalStatus: 'noModal'\n        })\n        await promiseAllSequently(list.map((symbol) => {\n          return () => repayIfNeeded(symbol).catch(() => {})\n        }))\n        updateVaultLayer2({})\n      },\n    },\n  }\n}"
  },
  {
    "path": "packages/component-lib/src/sharedPages/VaultPage/hooks/useVaultMarket.ts",
    "content": "import React from 'react'\n\nimport {\n  myLog,\n  RouterPath,\n  RowConfig,\n  RowConfigType,\n  SagaStatus,\n  TickerNew,\n  VAULT_MARKET_REFRESH,\n  VaultKey,\n} from '@loopring-web/common-resources'\nimport { LoopringAPI, useTokenMap, useVaultMap, useVaultTicker, useMarket } from '@loopring-web/core'\nimport { useHistory } from 'react-router-dom'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport _ from 'lodash'\n\nexport const useVaultMarket = <\n  R extends TickerNew & { cmcTokenId: number; isFavorite: boolean },\n  T = sdk.TokenInfo,\n>({\n  tableRef,\n  rowConfig = RowConfig,\n}: {\n  tableRef: React.Ref<any>\n  rowConfig?: RowConfigType\n}) => {\n  let history = useHistory()\n  const { tokenMap } = useTokenMap()\n  const { tokenMap: vaultTokenMap, marketMap: vaultMarketMap } = useVaultMap()\n\n  const [detail, setShowDetail] = React.useState<{\n    isShow: boolean\n    isLoading?: boolean\n    row?: R\n    detail?: { tokenInfo: Partial<sdk.DatacenterTokenInfo & sdk.TokenInfo>; trends: any }\n  }>({\n    isShow: false,\n    isLoading: true,\n  })\n  const autoRefresh = React.useRef<NodeJS.Timeout | -1>(-1)\n  const { status: vaultTickerStatus, vaultTickerMap, updateVaultTickers } = useVaultTicker()\n  const handleRowClick = React.useCallback(async (_index, row) => {\n    setShowDetail({\n      isShow: true,\n      isLoading: true,\n      row,\n      detail: {\n        tokenInfo: {\n          ...tokenMap[row?.erc20Symbol ?? ''],\n          ...row,\n          name: ''\n        },\n        trends: undefined,\n      },\n    })\n    try {\n      const [\n        tokneInfoDetail,\n        // quoteTokenTrend,\n        ...quoteTokenTrends\n      ] = await Promise.all([\n        LoopringAPI?.exchangeAPI?.getTokenInfo({\n          cmcTokenId: row.cmcTokenId,\n          // cmcTokenId\n          // token: tokenMap[row?.erc20Symbol ?? '']?.address,\n          currency: 'USD',\n        }),\n        // LoopringAPI?.exchangeAPI?.getQuoteTokenInfo({\n        //   cmcTokenId: row.cmcTokenId,\n        //   currency: 'USD',\n        // }),\n        LoopringAPI?.exchangeAPI?.getQuoteTokenInfo({\n          cmcTokenId: row.cmcTokenId,\n          currency: 'USD',\n          //@ts-ignore\n          range: sdk.DatacenterRange.RANGE_ONE_HOUR,\n        }),\n        LoopringAPI?.exchangeAPI?.getQuoteTokenInfo({\n          cmcTokenId: row.cmcTokenId,\n          currency: 'USD',\n          //@ts-ignore\n          range: sdk.DatacenterRange.RANGE_ONE_DAY,\n        }),\n        LoopringAPI?.exchangeAPI?.getQuoteTokenInfo({\n          cmcTokenId: row.cmcTokenId,\n          currency: 'USD',\n          //@ts-ignore\n          range: sdk.DatacenterRange.RANGE_ONE_WEEK,\n        }),\n        LoopringAPI?.exchangeAPI?.getQuoteTokenInfo({\n          cmcTokenId: row.cmcTokenId,\n          currency: 'USD',\n          //@ts-ignore\n          range: sdk.DatacenterRange.RANGE_ONE_MONTH,\n        }),\n        // LoopringAPI?.exchangeAPI?.getQuoteTokenOhlcv({\n        //   token: tokenMap[row?.erc20Symbol ?? ''].address,\n        //   currency: 'USD',\n        //   //@ts-ignore\n        //   range: sdk.OHLCVDatacenterRange.OHLCV_RANGE_ONE_YEAR,\n        // }),\n      ])\n      if (\n        (tokneInfoDetail as sdk.RESULT_INFO).code ||\n        (tokneInfoDetail as sdk.RESULT_INFO).message\n        // ||\n        // (quoteTokenTrend as sdk.RESULT_INFO).code ||\n        // (quoteTokenTrend as sdk.RESULT_INFO).message\n      ) {\n        // throw tokneInfoDetail\n      }\n      setShowDetail({\n        isShow: true,\n        isLoading: false,\n        row,\n        detail: {\n          tokenInfo: {\n            ...tokenMap[row?.erc20Symbol ?? ''],\n            ...(tokneInfoDetail && tokneInfoDetail.list && tokneInfoDetail.list[0]),\n            ...row,\n            name: tokneInfoDetail && tokneInfoDetail.list && tokneInfoDetail.list[0].name\n            // symbol: row.symbol,\n          },\n          trends: [\n            ...quoteTokenTrends?.map((item) => {\n              return item?.list?.reverse().map((trend: string[]) => {\n                const [\n                  timestamp,\n                  price,\n                  volume24H,\n                  volumeChange24H,\n                  percentChange1H,\n                  percentChange24H,\n                  percentChange7D,\n                  percentChange30D,\n                  marketCap,\n                ] = trend\n                return {\n                  close: Number(price).toFixed(2),\n                  timeStamp: Number(timestamp),\n                  timestamp,\n                  price,\n                  volume24H,\n                  volumeChange24H,\n                  percentChange1H,\n                  percentChange24H,\n                  percentChange7D,\n                  percentChange30D,\n                  marketCap,\n                }\n              })\n            }),\n          ] as any,\n        },\n      })\n    } catch (e) {\n      myLog('handleRowClick', e)\n    }\n    //\n  }, [])\n  const handleItemClick = React.useCallback(\n    (row: R) => {\n      history.push(`${RouterPath.vault}/${VaultKey.VAULT_DASHBOARD}`)\n    },\n    [history],\n  )\n  const _marketProps = useMarket<R, T>({\n    tableRef,\n    handleItemClick: handleRowClick,\n    handleRowClick,\n    tickerMap: vaultTickerMap as any,\n    tokenMap: vaultTokenMap,\n  })\n  const marketProps = {\n    ..._marketProps,\n    rawData: _marketProps.rawData.filter((item) => {\n      if (\n        _.values(vaultMarketMap).every(\n          (market) =>\n            market.baseTokenId !== vaultTokenMap['LVUSDC']?.tokenId &&\n            market.quoteTokenId !== vaultTokenMap['LVUSDC']?.tokenId,\n        ) &&\n        item.symbol === 'LVUSDC'\n      ) {\n        return false\n      }\n      return true\n    }),\n  }\n  const autoReCalc = React.useCallback(() => {\n    updateVaultTickers()\n    if (autoRefresh.current !== -1) {\n      clearTimeout(autoRefresh.current as NodeJS.Timeout)\n    }\n    autoRefresh.current = setTimeout(() => {\n      autoReCalc()\n    }, VAULT_MARKET_REFRESH)\n  }, [])\n  React.useEffect(() => {\n    autoReCalc()\n    return () => {\n      if (autoRefresh.current !== -1) {\n        clearTimeout(autoRefresh.current as NodeJS.Timeout)\n      }\n    }\n  }, [])\n  React.useEffect(() => {\n    if (vaultTickerStatus === SagaStatus.UNSET && vaultTickerMap) {\n      // const data = getFilteredTickList();\n      marketProps.handleTableFilterChange({})\n    }\n  }, [vaultTickerStatus])\n\n  return { marketProps, detail, setShowDetail }\n}\n"
  },
  {
    "path": "packages/component-lib/src/sharedPages/VaultPage/hooks/useVaultPage.ts",
    "content": "import { useHistory, useRouteMatch } from 'react-router-dom'\nimport React from 'react'\nimport {\n  confirmation,\n  store,\n  useVaultAccountInfo,\n  useVaultMap,\n} from '@loopring-web/core'\nimport {\n  RouterPath,\n  VaultKey,\n  SagaStatus,\n  RecordTabIndex,\n} from '@loopring-web/common-resources'\nimport { useOpenModals } from '@loopring-web/component-lib'\nimport { useConfirmation } from '@loopring-web/core/src/stores/localStore/confirmation'\nimport { VaultAccountStatus } from '@loopring-web/loopring-sdk'\n\nexport const useVaultPage = () => {\n  const VaultPath = `${RouterPath.vault}/:item`\n  let match: any = useRouteMatch(VaultPath)\n  const history = useHistory()\n  const vaultAccountInfo = useVaultAccountInfo()\n  const { status: vaultStatus, getVaultMap, marketArray } = useVaultMap()\n  const [tabIndex, setTabIndex] = React.useState<VaultKey | undefined>(() => {\n    return (\n      Object.values(VaultKey).find(\n        (item) => item.toLowerCase() === match?.params?.item?.toLowerCase(),\n      ) ?? undefined\n    )\n  })\n\n  const {\n    setShowVaultJoin,\n    setShowConfirmedVault,\n    modals: { isShowConfirmedVault },\n  } = useOpenModals()\n  const { setConfirmedOpenVaultPosition } = useConfirmation()\n\n  const [error, setError] = React.useState(false)\n  const [showLeverage, setShowLeverage] = React.useState({ show: false, closeAfterChange: false })\n\n  React.useEffect(() => {\n    const { marketArray } = store.getState().invest.vaultMap\n    if (vaultStatus === SagaStatus.UNSET && marketArray?.length) {\n      setError(false)\n    } else if (vaultStatus === SagaStatus.ERROR) {\n      setError(true)\n    }\n  }, [vaultStatus])\n\n  const handleTabChange = (_e: any, value: VaultKey) => {\n    history.push(`${RouterPath.vault}/${value}`)\n  }\n  React.useEffect(() => {\n    setTabIndex(\n      Object.values(VaultKey).find(\n        (item) => item.toLowerCase() === match?.params?.item?.toLowerCase(),\n      )\n    )\n  }, [match?.params?.item])\n\n  const handleConfirmVaultRiskClose = (_e: any, isAgree: boolean) => {\n    if (!isAgree) {\n      history.push(`${RouterPath.vault}/${VaultKey.VAULT_DASHBOARD}`)\n      setShowConfirmedVault({ isShow: false })\n    } else {\n      history.push(`${RouterPath.vault}/${VaultKey.VAULT_DASHBOARD}`)\n      setConfirmedOpenVaultPosition()\n      setShowVaultJoin({ isShow: true, info: { isActiveAccount: true } })\n      setShowConfirmedVault({ isShow: false })\n    }\n  }\n\n  const toggleLeverage = () => {\n    setShowLeverage({ show: !showLeverage.show, closeAfterChange: true })\n  }\n\n  const closeLeverage = () => {\n    setShowLeverage({ show: false, closeAfterChange: false })\n  }\n\n  const handleRecordClick = () => {\n    history.push(`${RouterPath.l2records}/${RecordTabIndex.VaultRecords}`)\n  }\n\n  const handleTutorialClick = () => {\n    window.open(`${LOOPRING_DOCUMENT}vault_tutorial_en.md`, '_blank')\n    window.opener = null\n  }\n\n  return {\n    tabIndex: tabIndex\n      ? tabIndex\n      : vaultAccountInfo?.vaultAccountInfo?.accountStatus === VaultAccountStatus.IN_STAKING\n      ? VaultKey.VAULT_DASHBOARD\n      : VaultKey.VAULT_TRADE,\n    error,\n    showLeverage,\n    isShowConfirmedVault,\n    vaultAccountInfo,\n    marketArray,\n    getVaultMap,\n    handleTabChange,\n    handleConfirmVaultRiskClose,\n    toggleLeverage,\n    closeLeverage,\n    handleRecordClick,\n    handleTutorialClick,\n  }\n}\n"
  },
  {
    "path": "packages/component-lib/src/sharedPages/VaultPage/hooks/useVaultSwap.ts",
    "content": "import * as sdk from '@loopring-web/loopring-sdk'\nimport React from 'react'\nimport { useGetSet } from 'react-use'\n\nimport {\n  AccountStatus,\n  CustomErrorWithCode,\n  EmptyValueTag,\n  getValuePrecisionThousand,\n  L1L2_NAME_DEFINED,\n  MapChainId,\n  MarketType,\n  myLog,\n  RouterPath,\n  SDK_ERROR_MAP_TO_UI,\n  SUBMIT_PANEL_AUTO_CLOSE,\n  SUBMIT_PANEL_CHECK,\n  TOAST_TIME,\n  TradeBtnStatus,\n  UIERROR_CODE,\n  VaultKey,\n  VaultSwapStep,\n} from '@loopring-web/common-resources'\nimport {\n  AccountStep,\n  ToastType,\n  useOpenModals,\n  useSettings,\n  useToggle,\n} from '@loopring-web/component-lib'\nimport { useTranslation } from 'react-i18next'\n\nimport BigNumberJS from 'bignumber.js'\nimport {\n  btradeOrderbookService,\n  DAYS,\n  getTimestampDaysLater,\n  isNumberStr,\n  l2CommonService,\n  LoopringAPI,\n  MAPFEEBIPS,\n  numberFormat,\n  numberFormatThousandthPlace,\n  onchainHashInfo,\n\n  store,\n  tryFn,\n  useAccount,\n  useSocket,\n  useSystem,\n  useToast,\n  useTokenMap,\n  useVaultAccountInfo,\n  useVaultLayer2,\n  useVaultMap,\n  VaultBorrowTradeData,\n  vaultSwapDependAsync,\n  toPercent,\n  strNumDecimalPlacesLessThan,\n  useSubmitBtn,\n} from '@loopring-web/core'\nimport { merge } from 'rxjs'\nimport Decimal from 'decimal.js'\nimport { calcMarinLevel, marginLevelType } from '@loopring-web/core/src/hooks/useractions/vault/utils'\nimport { CloseAllConfirmModalProps } from '../components/modals'\nimport { utils, BigNumber } from 'ethers'\nimport _ from 'lodash'\nimport { closePositionsAndRepayIfNeeded, filterPositions, repayIfNeeded } from '../utils'\nimport { useHistory, useLocation } from 'react-router'\nimport { useAppKitNetwork } from '@reown/appkit/react'\nimport { useConfirmation } from '@loopring-web/core/src/stores/localStore/confirmation'\n\nconst tWrap = (t: any, label: string, chainId: number) => {\n  const [theLable, ...rest] = label.split('|')\n  const obj = _.fromPairs(rest.map((value, index) => [index === 0 ? 'arg' : 'arg' + index, value]))\n  const network = MapChainId[chainId]\n  return t(theLable, {\n    ...obj,\n    l1ChainName: network ? L1L2_NAME_DEFINED[network].l1ChainName : undefined,\n    loopringL2: network ? L1L2_NAME_DEFINED[network].loopringL2 : undefined,\n    l2Symbol: network ? L1L2_NAME_DEFINED[network].l2Symbol : undefined,\n    l1Symbol: network ? L1L2_NAME_DEFINED[network].l1Symbol : undefined,\n    ethereumL1: network ? L1L2_NAME_DEFINED[network].ethereumL1 : undefined,\n  })\n}\n\nconst calcDexWrap = <R>(input: {\n  info: R\n  input: string\n  sell: string\n  buy: string\n  isAtoB: boolean\n  marketArr: string[]\n  tokenMap: sdk.LoopringMap<sdk.TokenInfo>\n  marketMap: sdk.LoopringMap<sdk.MarketInfo>\n  depth: sdk.DepthData\n  feeBips: string\n  slipBips: string\n}) => {\n  const output = sdk.calcDex<R>(input)\n\n  return {\n    ...output,\n    amountB: output?.amountB !== 'NaN' ? output?.amountB : undefined,\n    feeBips: output?.feeBips !== 'NaN' ? output?.feeBips : undefined,\n    amountS: output?.amountS !== 'NaN' ? output?.amountS : undefined,\n    sellVol: output?.amountS !== 'NaN' ? output?.amountS : undefined,\n    buyVol: output?.amountB !== 'NaN' ? output?.amountB : undefined,\n    amountBSlipped: {\n      minReceived:\n        output?.amountBSlipped?.minReceived !== 'NaN'\n          ? output?.amountBSlipped?.minReceived\n          : undefined,\n      minReceivedVal:\n        output?.amountBSlipped?.minReceivedVal !== 'NaN'\n          ? output?.amountBSlipped?.minReceivedVal\n          : undefined,\n    },\n  }\n}\n\nexport type VaultTradeTradeData = VaultBorrowTradeData & { borrowAvailable: string }\n\n\n\n\n  \n// }\nexport const useVaultSwap = () => {\n  const borrowHash = React.useRef<null | { hash: string; timer?: any }>(null)\n  const refreshRef = React.useRef()\n  const mainViewRef = React.useRef<HTMLDivElement>(null)\n  const timerRef = React.useRef<NodeJS.Timeout | null>(null)\n\n  const { tokenMap: originTokenMap } = useTokenMap()\n  const { account } = useAccount()\n  const {\n    tokenMap,\n    marketMap,\n    marketArray,\n    getVaultMap,\n    tokenPrices: vaultTokenPrices,\n  } = useVaultMap()\n  const {\n    setShowSupport,\n    setShowTradeIsFrozen,\n    modals: { isShowVaultSwap },\n    setShowAccount,\n    setShowVaultJoin,\n    setShowGlobalToast,\n    setShowVaultCloseConfirm,\n    setShowConfirmedVault\n  } = useOpenModals()\n  const {\n    toggle: { VaultInvest },\n  } = useToggle()\n\n  const { t } = useTranslation(['common', 'error'])\n\n  const { exchangeInfo, allowTrade } = useSystem()\n  const { updateVaultLayer2, vaultLayer2 } = useVaultLayer2()\n  const { sendSocketTopic, socketEnd } = useSocket()\n  const subjectBtradeOrderbook = React.useMemo(() => btradeOrderbookService.onSocket(), [])\n\n  const { toastOpen, setToastOpen, closeToast } = useToast()\n  const { coinJson, swapSecondConfirmation, setSwapSecondConfirmation, slippage, setSlippage } =\n    useSettings()\n\n  const { chainInfos, updateVaultBorrowHash } = onchainHashInfo.useOnChainInfo()\n  const { vaultAccountInfo, maxLeverage } = useVaultAccountInfo()\n\n  const initLocalState = {\n    hideOther: false,\n    isLongOrShort: undefined as 'long' | 'short' | undefined,\n    showTokenSelection: false,\n    amount: '',\n    selectedToken: undefined as string | undefined,\n    isSwapRatioReversed: false,\n    borrowedAmount: undefined as string | undefined,\n    tokenSelectionInput: '',\n    showSetting: false,\n    isSwapLoading: false,\n    showSmallTradePrompt: {\n      show: false,\n      estimatedFee: undefined as string | undefined,\n      minimumConverted: undefined as string | undefined,\n      feePercentage: undefined as string | undefined,\n    },\n    swapStatus: {\n      status: 'init',\n      borrowAmount: '10',\n    } as {\n      status: 'borrowing' | 'swapping' | 'init'\n      borrowAmount?: string\n    },\n    maxBorrowableSellToken: undefined as string | undefined,\n    depth: undefined as sdk.DepthData | undefined,\n    slideValue: 0,\n    closeAllConfirmModal: {\n      show: false,\n      symbol: undefined as undefined | string\n    }\n  }\n  const [getLocalState, setLocalState] = useGetSet(initLocalState)\n\n  const refreshData = async () => {\n    const {\n      account,\n      settings: { defaultNetwork },\n      invest: {\n        vaultMap: { marketMap },\n      },\n    } = store.getState()\n    const market: MarketType = `LV${getSelectedTokenSymbol()}-LVUSDT`\n    myLog('useVaultSwap: refreshData', market)\n\n    if (!market || !sellToken || !buyToken) return\n    \n    getVaultMap()\n    updateVaultLayer2({})\n\n    if (chainInfos.vaultBorrowHashes && chainInfos.vaultBorrowHashes[account.accAddress]?.length) {\n      chainInfos.vaultBorrowHashes[account.accAddress].forEach(({ hash }) => {\n        LoopringAPI?.vaultAPI\n          ?.getVaultGetOperationByHash(\n            {\n              accountId: account.accountId?.toString(),\n              hash,\n            },\n            account.apiKey,\n          )\n          .then(({ operation }) => {\n            if (\n              [\n                sdk.VaultOperationStatus.VAULT_STATUS_SUCCEED,\n                sdk.VaultOperationStatus.VAULT_STATUS_FAILED,\n              ].includes(operation.status)\n            ) {\n              updateVaultBorrowHash(\n                operation.hash,\n                account.accAddress,\n                operation.status === sdk.VaultOperationStatus.VAULT_STATUS_FAILED\n                  ? 'failed'\n                  : 'success',\n              )\n            }\n          })\n      })\n    }\n\n    const { depth } = await vaultSwapDependAsync({\n      market: marketMap[market]?.vaultMarket as MarketType,\n      tokenMap,\n    })\n    setLocalState((state) => ({\n      ...state,\n      depth,\n    }))\n    const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n    const networkWallet: sdk.NetworkWallet = [\n      sdk.NetworkWallet.ETHEREUM,\n      sdk.NetworkWallet.GOERLI,\n      sdk.NetworkWallet.SEPOLIA,\n    ].includes(network as sdk.NetworkWallet)\n      ? sdk.NetworkWallet.ETHEREUM\n      : sdk.NetworkWallet[network]\n    const item = marketMap[market]\n    if (depth?.symbol && item?.wsMarket) {\n      sendSocketTopic({\n        [sdk.WsTopicType.btradedepth]: {\n          showOverlap: false,\n          markets: [item.wsMarket],\n          level: 0,\n          count: 50,\n          snapshot: false,\n        },\n        [sdk.WsTopicType.l2Common]: {\n          address: account.accAddress,\n          network: networkWallet,\n        },\n      })\n    } else {\n      socketEnd()\n    }\n\n    LoopringAPI.vaultAPI\n      ?.getMaxBorrowable(\n        {\n          accountId: account.accountId,\n          symbol: sellToken.symbol.slice(2),\n        },\n        account.apiKey,\n        '1',\n      )\n      .then((maxBorrowable) => {\n        const tokenPrice = vaultTokenPrices[sellToken.symbol]\n        const maxBorrowableOfSellToken = numberFormat(\n          new Decimal(maxBorrowable!.maxBorrowableOfUsdt).div(tokenPrice).toString(),\n          {\n            fixed: sellToken.vaultTokenAmounts.qtyStepScale,\n            removeTrailingZero: true,\n            fixedRound: Decimal.ROUND_FLOOR,\n          },\n        )\n        setLocalState((state) => ({\n          ...state,\n          maxBorrowableSellToken: maxBorrowableOfSellToken,\n        }))\n      })\n  }\n\n  const localState = getLocalState()\n  const showSmallTradePrompt = localState.showSmallTradePrompt\n\n  const setIsSwapLoading = (loading: boolean) => {\n    setLocalState((state) => ({\n      ...state,\n      isSwapLoading: loading,\n    }))\n  }\n  const setShowSmallTradePrompt = (showSmallTradePrompt: {\n    show: boolean\n    estimatedFee: string | undefined\n    minimumConverted: string | undefined\n    feePercentage: string | undefined\n  }) => {\n    setLocalState((state) => ({\n      ...state,\n      showSmallTradePrompt,\n    }))\n  }\n  \n  const { pathname, search } = useLocation()\n  const searchParams = new URLSearchParams(search)\n\n  const isOnPortalTradeRoute = pathname === RouterPath.vault + '/' + VaultKey.VAULT_TRADE\n\n  const getSelectedTokenSymbol = () => {\n    const localState = getLocalState()\n    return localState.selectedToken\n      ? localState.selectedToken\n      : searchParams.get('symbol')\n      ? searchParams.get('symbol')\n      : 'ETH'\n  }\n  const isLongOrShort = localState.isLongOrShort \n    ? localState.isLongOrShort\n    : searchParams.get('isSell') === 'true'\n      ? 'short'\n      : 'long'\n  const selectedTokenSymbol = getSelectedTokenSymbol()\n  const selectedVTokenSymbol = 'LV' + selectedTokenSymbol\n  const selectedVTokenInfo = tokenMap ? tokenMap[selectedVTokenSymbol] : undefined\n\n  const LVUSDTInfo = tokenMap ? tokenMap['LVUSDT'] : undefined\n  const USDTInfo = originTokenMap ? originTokenMap['USDT'] : undefined\n  const sellToken = isLongOrShort === 'long' ? LVUSDTInfo : selectedVTokenInfo\n  const sellTokenOriginSymbol =\n    isLongOrShort === 'long' ? 'USDT' : selectedVTokenSymbol.slice(2)\n  const buyToken = isLongOrShort === 'long' ? selectedVTokenInfo : LVUSDTInfo\n  const buyTokenOriginSymbol =\n    isLongOrShort === 'long' ? selectedVTokenSymbol.slice(2) : 'USDT'\n\n  const market: MarketType = `${selectedVTokenSymbol}-LVUSDT`\n  const marketInfo = marketMap ? marketMap[market] : undefined\n\n  const smallTradePromptAmtBN = sellToken\n    ? isLongOrShort === 'long'\n      ? marketInfo?.minTradePromptAmount?.quote\n      : marketInfo?.minTradePromptAmount?.base\n    : undefined\n\n  const smallAmtFeeBips = marketInfo?.upSlippageFeeBips as unknown as number\n\n  const sellTokenAsset = sellToken && vaultLayer2 ? vaultLayer2[sellToken.symbol] : undefined\n\n  const borrowAble = localState.maxBorrowableSellToken\n    ? localState.maxBorrowableSellToken\n    : undefined\n  \n  const userMaxSellValueWithoutBorrow =\n    sellToken\n      ? numberFormat(\n          utils.formatUnits(\n            BigNumber.from(sellTokenAsset?.total ?? 0),\n            sellToken?.decimals,\n          ),\n          {\n            fixed: sellToken.vaultTokenAmounts.qtyStepScale,\n            removeTrailingZero: true,\n            fixedRound: Decimal.ROUND_FLOOR,\n          },\n        )\n      : undefined\n      \n  const userMaxSellValue =\n    sellToken\n      ? numberFormat(\n          utils.formatUnits(\n            BigNumber.from(sellTokenAsset?.total ?? 0).add(\n              utils.parseUnits(borrowAble ?? '0', sellToken?.decimals),\n            ),\n            sellToken?.decimals,\n          ),\n          {\n            fixed: sellToken.vaultTokenAmounts.qtyStepScale,\n            removeTrailingZero: true,\n            fixedRound: Decimal.ROUND_FLOOR,\n          },\n        )\n      : undefined\n\n  const slippageReal = slippage ? (slippage === 'N' ? 0.1 : slippage) : 0.1\n  const maxAmountCalcDexOutput =\n    sellToken && buyToken && localState.depth && marketInfo\n      ? calcDexWrap<sdk.VaultMarket>({\n          info: marketInfo as sdk.VaultMarket,\n          input: userMaxSellValue ?? '0',\n          sell: sellToken.symbol,\n          buy: buyToken.symbol,\n          isAtoB: isLongOrShort === 'long',\n          marketArr: marketArray,\n          tokenMap,\n          marketMap: marketMap as any,\n          depth: localState.depth,\n          feeBips: (marketInfo.feeBips ?? MAPFEEBIPS).toString(),\n          slipBips: slippageReal.toString(),\n        })\n      : undefined\n  const maxAmountWithoutBorrowCalcDexOutput =\n    sellToken && buyToken && localState.depth && marketInfo\n      ? calcDexWrap<sdk.VaultMarket>({\n          info: marketInfo as sdk.VaultMarket,\n          input: userMaxSellValueWithoutBorrow ?? '0',\n          sell: sellToken.symbol,\n          buy: buyToken.symbol,\n          isAtoB: isLongOrShort === 'long',\n          marketArr: marketArray,\n          tokenMap,\n          marketMap: marketMap as any,\n          depth: localState.depth,\n          feeBips: (marketInfo.feeBips ?? MAPFEEBIPS).toString(),\n          slipBips: slippageReal.toString(),\n        })\n      : undefined\n\n  const userMaxTradeValue =\n    isLongOrShort === 'short' ? userMaxSellValue : maxAmountCalcDexOutput?.amountB\n  const userMaxTradeValueWithoutBorrow =\n    isLongOrShort === 'short'\n      ? userMaxSellValueWithoutBorrow\n      : maxAmountWithoutBorrowCalcDexOutput?.amountB\n\n  const preCalcDexOutput =\n    sellToken && buyToken && localState.depth && marketInfo\n      ? calcDexWrap<sdk.VaultMarket>({\n          info: marketInfo as sdk.VaultMarket,\n          input: localState.amount ?? '0',\n          sell: sellToken.symbol,\n          buy: buyToken.symbol,\n          isAtoB: isLongOrShort === 'short',\n          marketArr: marketArray,\n          tokenMap,\n          marketMap: marketMap as any,\n          depth: localState.depth,\n          feeBips: (marketInfo.feeBips ?? MAPFEEBIPS).toString(),\n          slipBips: slippageReal.toString(),\n        })\n      : undefined\n\n  const sellAmountEstimate =\n    preCalcDexOutput?.amountS && sellToken\n      ? numberFormat(preCalcDexOutput?.amountS, { fixed: sellToken.decimals })\n      : undefined\n  const sellAmountEstimateBN =\n    sellToken && sellAmountEstimate && sellAmountEstimate !== 'NaN'\n      ? utils.parseUnits(sellAmountEstimate, sellToken.decimals)\n      : undefined\n\n  const maxFeeBips =\n    sellAmountEstimateBN && smallTradePromptAmtBN && sellAmountEstimateBN.lt(smallTradePromptAmtBN)\n      ? smallAmtFeeBips\n      : marketInfo?.feeBips ?? MAPFEEBIPS\n\n  const calcDexOutput =\n    sellToken && buyToken && localState.depth && marketInfo\n      ? calcDexWrap<sdk.VaultMarket>({\n          info: marketInfo as sdk.VaultMarket,\n          input: localState.amount ?? '0',\n          sell: sellToken.symbol,\n          buy: buyToken.symbol,\n          isAtoB: isLongOrShort === 'short',\n          marketArr: marketArray,\n          tokenMap,\n          marketMap: marketMap as any,\n          depth: localState.depth,\n          feeBips: maxFeeBips.toString(),\n          slipBips: slippageReal.toString(),\n        })\n      : undefined\n\n  \n  const swapRatio = tryFn(\n    () => {\n      return localState.isSwapRatioReversed\n        ? `1 USDT ≈ ${numberFormat(new Decimal(1).div(localState.depth!.mid_price).toString(), {\n            fixed: 6,\n            removeTrailingZero: true,\n          })} ${selectedTokenSymbol}`\n        : `1 ${selectedTokenSymbol} ≈ ${numberFormat(localState.depth!.mid_price.toString(), {\n            fixed: marketInfo!.precisionForPrice,\n            removeTrailingZero: true,\n          })} USDT`\n    },\n    (e) => {\n      return EmptyValueTag\n    },\n  )\n\n  const sellAmount =\n    calcDexOutput?.amountS && calcDexOutput.amountS !== 'NaN' && sellToken\n      ? numberFormat(calcDexOutput?.amountS, { fixed: sellToken.decimals })\n      : undefined\n  const sellAmountBN =\n    sellToken && sellAmount ? utils.parseUnits(sellAmount, sellToken.decimals) : undefined\n\n  const buyAmount =\n    calcDexOutput?.amountB && calcDexOutput.amountB !== 'NaN' && buyToken\n      ? numberFormat(calcDexOutput?.amountB, { fixed: buyToken.decimals })\n      : undefined\n  const buyAmountBN =\n    buyToken && buyAmount ? utils.parseUnits(buyAmount, buyToken.decimals) : undefined\n\n  const amounInUSDT = isLongOrShort === 'long' ? sellAmount : buyAmount\n\n  const borrowRequired =\n    sellToken && sellAmountBN\n      ? sellAmountBN.gt(\n          sellTokenAsset?.total && sellTokenAsset?.total !== 'NaN' ? sellTokenAsset?.total : 0,\n        )\n      : false\n\n  const moreToBeBorrowedBN = tryFn(\n    () => {\n      const subbed =\n        sellToken && borrowRequired && sellAmountBN\n          ? sellAmountBN.sub(sellTokenAsset?.total ?? 0)\n          : undefined\n      const oneUnit = utils.parseUnits(\n        '1',\n        sellToken!.decimals - sellToken!.vaultTokenAmounts?.qtyStepScale,\n      )\n      const floorred = subbed?.div(oneUnit).mul(oneUnit)\n      if (subbed && floorred && floorred.eq(subbed)) {\n        return floorred\n      } else {\n        return floorred?.add(oneUnit)\n      }\n    },\n    () => undefined,\n  )\n    \n\n  const moreToBeBorrowed = moreToBeBorrowedBN\n    ? utils.formatUnits(moreToBeBorrowedBN, sellToken?.decimals)\n    : undefined\n\n  const feeAmountBN = calcDexOutput?.amountBSlipped?.minReceived\n    ? BigNumber.from(calcDexOutput?.amountBSlipped?.minReceived ?? 0)\n        .mul(maxFeeBips)\n        .div(10000)\n    : undefined\n  const feeAmount =\n    feeAmountBN && buyToken ? utils.formatUnits(feeAmountBN, buyToken.decimals) : undefined\n  const totalSellQuota = tryFn(\n    () => {\n      const value =\n        isLongOrShort === 'long'\n          ? new Decimal(\n              utils.formatUnits(localState.depth!.asks_volTotal, LVUSDTInfo!.decimals),\n            )\n          : new Decimal(\n              utils.formatUnits(localState.depth!.bids_amtTotal, selectedVTokenInfo!.decimals),\n            )\n      return value.mul('0.99').toString()\n    },\n    () => undefined,\n  )\n  const totalTradeQuota = tryFn(\n    () => {\n      const value = new Decimal(\n              utils.formatUnits(localState.depth!.bids_amtTotal, selectedVTokenInfo!.decimals),\n            )\n      return value.mul('0.99').toString()\n    },\n    () => undefined,\n  )\n\n  \n\n  const maxSellValue = Decimal.min(userMaxSellValue ?? '0', totalSellQuota ?? '0').toString()\n  const maxTradeValue = Decimal.min(userMaxTradeValue ?? '0', totalTradeQuota ?? '0').toString()\n\n  const tradeMinAmt = tryFn(\n    () => {\n      const quoteMinAmtInfo = utils.formatUnits(\n        marketInfo!.minTradeAmount.base,\n        selectedVTokenInfo!.decimals,\n      )\n      const sellDust = utils.formatUnits(\n        selectedVTokenInfo!.orderAmounts.dust,\n        selectedVTokenInfo!.decimals,\n      )\n      return BigNumberJS.max(sellDust, quoteMinAmtInfo).toString()\n    },\n    () => undefined,\n  )\n  const tradeBtnStatus = (() => {\n    if (vaultAccountInfo?.accountStatus !== sdk.VaultAccountStatus.IN_STAKING) {\n      return {\n        label: undefined,\n        disabled: false,\n      }\n    }\n    if ((!tokenMap || !vaultTokenPrices) && sellToken) {\n      return {\n        label: undefined,\n        disabled: true,\n      }\n    }\n    if (!sellToken || !buyToken || !tradeMinAmt || !sellAmount) {\n      return {\n        label: undefined,\n        disabled: true,\n      }\n    }\n\n    const { account } = store.getState()\n    const sellTokenSymbol = sellToken.symbol\n\n    const tradeValue = localState.amount ?? '0'\n    const sellExceed = maxTradeValue ? new Decimal(maxTradeValue).lt(tradeValue ?? 0) : false\n    const amtValid = !!(\n      tradeValue &&\n      tradeMinAmt &&\n      sdk.toBig(tradeValue).gte(tradeMinAmt) &&\n      !sellExceed\n    )\n\n    const notEnough = userMaxTradeValue ? sdk.toBig(userMaxTradeValue).lt(tradeValue) : true\n    if (localState.isSwapLoading || localState.swapStatus.status !== 'init') {\n      return {\n        label: undefined,\n        disabled: true,\n      }\n    } else {\n      if (account.readyState === AccountStatus.ACTIVATED) {\n        if (!sellAmountBN || !buyAmountBN || !sellAmountBN.gt('0') || !buyAmountBN.gt('0')) {\n          return {\n            label: 'labelEnterAmount',\n            disabled: true,\n          }\n        } else if (notEnough) {\n          return {\n            label: 'labelVaultBorrowNotEnough',\n            disabled: true,\n          }\n        } else if (sellExceed) {\n          const maxOrderSize = maxTradeValue + ' ' + sellTokenSymbol\n          return {\n            label: maxTradeValue ? `labelLimitMax| ${maxOrderSize}` : `labelVaultTradeInsufficient`,\n            disabled: true,\n          }\n        } else if (\n          borrowRequired &&\n          localState.swapStatus.status === 'init' &&\n          moreToBeBorrowedBN &&\n          BigNumber.from(sellToken.vaultTokenAmounts?.minLoanAmount).gt(moreToBeBorrowedBN)\n        ) {\n          return {\n            label: `labelTradeVaultMiniBorrow|${\n              getValuePrecisionThousand(\n                utils.formatUnits(sellToken.vaultTokenAmounts?.minLoanAmount, sellToken.decimals),\n                sellToken.vaultTokenAmounts?.qtyStepScale,\n                sellToken.vaultTokenAmounts?.qtyStepScale,\n                sellToken.vaultTokenAmounts?.qtyStepScale,\n                false,\n                { floor: false, isAbbreviate: true },\n              ) +\n              ' ' +\n              sellTokenSymbol.slice(2)\n            }|${\n              getValuePrecisionThousand(\n                utils.formatUnits(\n                  BigNumber.from(sellToken.vaultTokenAmounts?.minLoanAmount).add(\n                    sellTokenAsset?.total ?? 0,\n                  ),\n                  sellToken.decimals,\n                ),\n                sellToken.vaultTokenAmounts?.qtyStepScale,\n                sellToken.vaultTokenAmounts?.qtyStepScale,\n                sellToken.vaultTokenAmounts?.qtyStepScale,\n                false,\n                { floor: false, isAbbreviate: true },\n              ) +\n              ' ' +\n              sellTokenSymbol.slice(2)\n            }`,\n            disabled: true,\n          }\n        } else if (!amtValid) {\n          // const sellSymbol = tradeData?.sell.belong\n          if (tradeMinAmt === undefined || tradeMinAmt === 'NaN') {\n            return {\n              label: 'labelEnterAmount',\n              disabled: true,\n            }\n          } else {\n            const minOrderSize =\n              selectedVTokenInfo &&\n              getValuePrecisionThousand(\n                sdk.toBig(tradeMinAmt ?? 0), //.div(\"1e\" + sellToken.decimals),\n                selectedVTokenInfo.vaultTokenAmounts?.qtyStepScale,\n                selectedVTokenInfo.vaultTokenAmounts?.qtyStepScale,\n                selectedVTokenInfo.vaultTokenAmounts?.qtyStepScale,\n                false,\n                { floor: false, isAbbreviate: true },\n              )\n            if (isNaN(Number(minOrderSize))) {\n              return {\n                label: `labelLimitMin| ${EmptyValueTag + ' ' + selectedTokenSymbol}`,\n                disabled: true,\n              }\n            } else {\n              return {\n                label: `labelLimitMin| ${minOrderSize + ' ' + selectedTokenSymbol}`,\n                disabled: true,\n              }\n            }\n          }\n        } else {\n          return {\n            label: undefined,\n            disabled: false,\n          }\n        }\n      } else {\n        return {\n          label: undefined,\n          disabled: false,\n        }\n      }\n    }\n  })()\n  \n  const myPositions = (() => {\n    return filterPositions(vaultLayer2!, tokenMap, vaultTokenPrices)\n      .map((symbol) => {\n        const asset = vaultLayer2 ? vaultLayer2[symbol] : undefined\n        const tokenInfo = tokenMap?.[symbol]\n        if (!asset || !tokenInfo) return undefined\n        const position = new Decimal(utils.formatUnits(BigNumber.from(asset.netAsset).add(asset.interest), tokenInfo.decimals))\n        if (\n          symbol === 'LVUSDT' ||\n          position.isZero() ||\n          (localState.hideOther && symbol !== selectedVTokenSymbol)\n        )\n          return undefined\n\n        return {\n          tokenSymbol: symbol.slice(2),\n          longOrShort: position.isPos() ? 'Long' : 'Short',\n          marginLevel: vaultAccountInfo?.marginLevel\n            ? numberFormat(vaultAccountInfo.marginLevel, { fixed: 2 })\n            : EmptyValueTag,\n          leverage: vaultAccountInfo?.leverage + 'x',\n          amount: numberFormat(position.abs().toString(), { fixed: tokenInfo.precision, removeTrailingZero: true }),\n          // onClickLeverage: () => {},\n          onClickTrade: () => {\n            mainViewRef.current?.scrollTo(0, 0)\n            setLocalState({\n              ...localState,\n              selectedToken: symbol.slice(2),\n              amount: '',\n              slideValue: 0,\n            })\n          },\n          onClickClose: () => {\n            setShowVaultCloseConfirm({ isShow: true, symbol: symbol })\n          },\n        }\n      })\n      .filter((item) => {\n        return item !== undefined\n      })\n  })()\n\n  const restartTimer = () => {\n    if (timerRef.current) {\n      clearInterval(timerRef.current)\n    }\n    timerRef.current = setInterval(() => {\n      refreshRef.current && (refreshRef.current as any).firstElementChild.click()\n    }, 10 * 1000)\n\n    refreshRef.current && (refreshRef.current as any).firstElementChild.click()\n  }\n  const clearData = () => {\n    setLocalState(initLocalState)\n  }\n\n  const swapSubmit = async () => {\n    const { depth } = localState\n    const account = store.getState().account\n    setIsSwapLoading(true)\n    try {\n      const ok =\n        account.readyState === AccountStatus.ACTIVATED &&\n        sellToken &&\n        buyToken &&\n        exchangeInfo &&\n        selectedVTokenInfo &&\n        sellAmountBN &&\n        buyAmountBN\n      if (!ok) {\n        throw new Error('invalid data')\n      }\n\n      const storageId = await LoopringAPI.userAPI?.getNextStorageId(\n        {\n          accountId: account.accountId,\n          sellTokenId: sellToken?.vaultTokenId ?? 0,\n        },\n        account.apiKey,\n      )\n      const request: sdk.VaultOrderRequest = {\n        exchange: exchangeInfo.exchangeAddress,\n        storageId: storageId!.orderId,\n        accountId: account.accountId,\n        sellToken: {\n          tokenId: sellToken?.vaultTokenId ?? 0,\n          volume: sellAmountBN.toString(),\n        },\n        buyToken: {\n          tokenId: buyToken?.vaultTokenId ?? 0,\n          volume: buyAmountBN.toString(),\n        },\n        validUntil: getTimestampDaysLater(DAYS),\n        maxFeeBips: maxFeeBips,\n        fillAmountBOrS: false,\n        allOrNone: false,\n        eddsaSignature: '',\n        clientOrderId: '',\n        orderType: sdk.OrderTypeResp.TakerOnly,\n        fastMode: false,\n      }\n      myLog('useVaultSwap: submitOrder request', request)\n      // const selectedVTokenInfo = 'selectedVTokenInfo'\n      const item = {\n        fromSymbol: sellToken.symbol,\n        fromAmount: utils.formatUnits(sellAmountBN, sellToken.decimals),\n        settledFromAmount: undefined,\n        toSymbol: buyToken.symbol,\n        feeAmount: feeAmount,\n        settledToAmount: undefined,\n      }\n      const info: any = {\n        sellToken: sellToken.symbol.slice(2),\n        buyToken: buyToken.symbol.slice(2),\n        sellVToken: sellToken.symbol,\n        buyVToken: buyToken.symbol,\n        sellStr: getValuePrecisionThousand(\n          utils.formatUnits(sellAmountBN, sellToken.decimals),\n          sellToken.vaultTokenAmounts?.qtyStepScale,\n          sellToken.vaultTokenAmounts?.qtyStepScale,\n          sellToken.vaultTokenAmounts?.qtyStepScale,\n          false,\n          { floor: false },\n        ),\n        buyStr: getValuePrecisionThousand(\n          utils.formatUnits(buyAmountBN, buyToken.decimals),\n          buyToken.precision,\n          buyToken.precision,\n          buyToken.precision,\n          false,\n          { floor: false },\n        ),\n        price: getValuePrecisionThousand(\n          depth?.mid_price,\n          selectedVTokenInfo.precision,\n          selectedVTokenInfo.precision,\n          selectedVTokenInfo.precision,\n          false,\n          { floor: false },\n        ),\n        sellFStr: undefined,\n        buyFStr: undefined,\n        convertStr: swapRatio,\n        feeStr: undefined,\n        time: Date.now(),\n        fromSymbol: sellToken.symbol,\n        toSymbol: buyToken.symbol,\n        placedAmount:\n          tokenMap &&\n          item.fromSymbol &&\n          sellToken.symbol.slice(2) &&\n          item.fromAmount &&\n          sdk.toBig(item.fromAmount).gt(0)\n            ? `${getValuePrecisionThousand(\n                sdk.toBig(item.fromAmount),\n                undefined,\n                undefined,\n                tokenMap[item.fromSymbol].precision,\n                false,\n                { isAbbreviate: true },\n              )} ${sellToken.symbol.slice(2)}`\n            : EmptyValueTag,\n        executedAmount: EmptyValueTag,\n        executedRate: EmptyValueTag,\n        convertedAmount: EmptyValueTag,\n        settledAmount: EmptyValueTag,\n      }\n\n      setShowAccount({\n        isShow: true,\n        step: AccountStep.VaultTrade_In_Progress,\n        info: {\n          percentage: undefined,\n          status: t('labelPending'),\n          ...info,\n        },\n      })\n      const response1 = await LoopringAPI.vaultAPI?.submitVaultOrder(\n        {\n          request,\n          privateKey: account.eddsaKey.sk,\n          apiKey: account.apiKey,\n        },\n        '1',\n      )\n      if ((response1 as sdk.RESULT_INFO).code || (response1 as sdk.RESULT_INFO).message) {\n        throw new CustomErrorWithCode({\n          code: (response1 as sdk.RESULT_INFO).code,\n          message: (response1 as sdk.RESULT_INFO).message,\n          ...SDK_ERROR_MAP_TO_UI[(response1 as sdk.RESULT_INFO)?.code ?? UIERROR_CODE.UNKNOWN],\n        })\n      } else {\n        setLocalState((state) => ({\n          ...state,\n          swapStatus: {\n            status: 'init',\n          },\n        }))\n        l2CommonService.sendUserUpdate()\n        await sdk.sleep(SUBMIT_PANEL_CHECK)\n        if (refreshRef.current) {\n          // @ts-ignore\n          refreshRef.current.firstElementChild.click()\n        }\n        const response2: { hash: string } | any =\n          await LoopringAPI.vaultAPI?.getVaultGetOperationByHash(\n            {\n              accountId: account.accountId as any,\n              // @ts-ignore\n              hash: response1.hash,\n            },\n            account.apiKey,\n            '1',\n          )\n        const item = {\n          fromSymbol: sellToken.symbol,\n          fromAmount: sdk.toBig(response2.order.amountS).div('1e' + sellToken.decimals),\n          settledFromAmount: sdk.toBig(response2.order.fillAmountS).div('1e' + sellToken.decimals),\n          toSymbol: buyToken.symbol,\n          settledToAmount: sdk.toBig(response2.order.fillAmountB).div('1e' + buyToken.decimals),\n          feeAmount: sdk.toBig(response2.order.fee).div('1e' + buyToken.decimals),\n        }\n        const info: any = {\n          sellToken: sellToken.symbol.slice(2),\n          buyToken: buyToken.symbol.slice(2),\n          sellFStr: getValuePrecisionThousand(\n            item.settledFromAmount,\n            sellToken.vaultTokenAmounts?.qtyStepScale,\n            sellToken.vaultTokenAmounts?.qtyStepScale,\n            sellToken.vaultTokenAmounts?.qtyStepScale,\n            false,\n            { floor: false },\n          ),\n          buyFStr: getValuePrecisionThousand(\n            item.settledToAmount,\n            buyToken.precision,\n            buyToken.precision,\n            buyToken.precision,\n            false,\n            { floor: false },\n          ),\n          price: getValuePrecisionThousand(\n            depth?.mid_price,\n            selectedVTokenInfo.precision,\n            selectedVTokenInfo.precision,\n            selectedVTokenInfo.precision,\n            false,\n            { floor: false },\n          ),\n          convertStr: swapRatio,\n          feeStr: feeAmount,\n          time: Date.now(),\n          fromSymbol: sellToken.symbol,\n          toSymbol: buyToken.symbol,\n          placedAmount:\n            tokenMap && item.fromSymbol && item.fromAmount && sdk.toBig(item.fromAmount).gt(0)\n              ? `${getValuePrecisionThousand(\n                  sdk.toBig(item.fromAmount),\n                  undefined,\n                  undefined,\n                  tokenMap[item.fromSymbol].precision,\n                  false,\n                  { isAbbreviate: true },\n                )} ${sellToken.symbol.slice(2)}`\n              : EmptyValueTag,\n          executedAmount:\n            tokenMap &&\n            item.fromSymbol &&\n            sellToken.symbol.slice(2) &&\n            item.settledFromAmount &&\n            sdk.toBig(item.settledFromAmount).gt(0)\n              ? `${getValuePrecisionThousand(\n                  sdk.toBig(item.settledFromAmount),\n                  undefined,\n                  undefined,\n                  tokenMap[item.fromSymbol].precision,\n                  false,\n                  { isAbbreviate: true },\n                )} ${sellToken.symbol.slice(2)}`\n              : EmptyValueTag,\n          executedRate:\n            tokenMap &&\n            item.fromSymbol &&\n            item.settledFromAmount &&\n            item.fromAmount &&\n            sdk.toBig(item.fromAmount).gt(0)\n              ? `${sdk\n                  .toBig(item.settledFromAmount)\n                  .div(item.fromAmount)\n                  .multipliedBy('100')\n                  .toFixed(2)}%`\n              : EmptyValueTag,\n          convertedAmount:\n            tokenMap &&\n            item.toSymbol &&\n            buyToken.symbol.slice(2) &&\n            item.settledToAmount &&\n            sdk.toBig(item.settledToAmount).gt(0)\n              ? `${getValuePrecisionThousand(\n                  sdk.toBig(item.settledToAmount),\n                  undefined,\n                  undefined,\n                  tokenMap[item.toSymbol].precision,\n                  false,\n                  { isAbbreviate: true },\n                )} ${buyToken.symbol.slice(2)}`\n              : EmptyValueTag,\n          settledAmount:\n            tokenMap &&\n            item.toSymbol &&\n            item.settledToAmount &&\n            item.feeAmount &&\n            sdk.toBig(item.settledToAmount).gt(0)\n              ? `${getValuePrecisionThousand(\n                  sdk.toBig(item.settledToAmount).minus(item.feeAmount),\n                  undefined,\n                  undefined,\n                  tokenMap[item.toSymbol].precision,\n                  false,\n                  { isAbbreviate: true },\n                )} ${item.toSymbol}`\n              : EmptyValueTag,\n        }\n        if (\n          response2?.raw_data?.operation?.status === sdk.VaultOperationStatus.VAULT_STATUS_FAILED\n        ) {\n          setShowAccount({\n            isShow: store.getState().modals.isShowAccount.isShow,\n            step: AccountStep.VaultTrade_Failed,\n            info: {\n              ...info,\n              price: response2?.raw_data.order.price,\n              percentage: '',\n              status: t('labelFailed'),\n            },\n          })\n          return\n        }\n        const status = [sdk.VaultOperationStatus.VAULT_STATUS_SUCCEED].includes(\n          response2?.raw_data?.operation?.status,\n        )\n          ? 'labelSuccessfully'\n          : 'labelPending'\n\n        setShowAccount({\n          isShow: store.getState().modals.isShowAccount.isShow,\n          step:\n            status === 'labelSuccessfully'\n              ? AccountStep.VaultTrade_Success\n              : AccountStep.VaultTrade_In_Progress,\n          info: {\n            price: response2?.raw_data.order.price,\n            percentage: sdk\n              .toBig(response2?.raw_data?.order?.fillAmountS ?? 0)\n              .div(response2?.raw_data?.order?.amountS ?? 1)\n              .times(100)\n              .toFixed(2),\n            status: t(status),\n            ...info,\n          },\n        })      \n        sdk.sleep(SUBMIT_PANEL_AUTO_CLOSE).then(() => {\n          l2CommonService.sendUserUpdate()\n          if (\n            store.getState().modals.isShowAccount.isShow &&\n            [AccountStep.VaultTrade_Success, AccountStep.VaultTrade_In_Progress].includes(\n              store.getState().modals.isShowAccount.step,\n            )\n          ) {\n            setShowAccount({ isShow: false })\n          }\n        })\n        setLocalState((state) => ({\n          ...state,\n          amount: '',\n        }))\n      }\n    } catch (error: any) {\n      if ([102024, 102025, 114001, 114002].includes(error?.code || 0)) {\n      } else {\n        sdk.dumpError400(error)\n      }\n      setShowAccount({\n        isShow: false,\n      })\n      setToastOpen({\n        open: true,\n        type: ToastType.error,\n        content: t('labelVaultTradeFailed') + ' ' + t(error.messageKey, { ns: 'error' }),\n        step: VaultSwapStep.Swap,\n      })\n    } finally {\n      \n      setLocalState((state) => {\n        return {\n          ...state,\n          swapStatus: { status: 'init' },\n          isSwapLoading: false,\n        }\n      })\n\n      await sdk.sleep(1000)\n      updateVaultLayer2({})\n      await sdk.sleep(1000)\n      repayIfNeeded(selectedVTokenSymbol)\n      .finally(() => {\n        return repayIfNeeded('LVUSDT')\n      })\n      .finally(() => {\n        updateVaultLayer2({})\n      })\n    }\n  }\n  const borrowSubmit = async () => {\n    const { account } = store.getState()\n\n    setLocalState((state) => ({\n      ...state,\n      swapStatus: {\n        status: 'borrowing',\n        borrowAmount: moreToBeBorrowed,\n      },\n      isSwapLoading: true,\n    }))\n\n    try {\n      if (exchangeInfo && sellAmountBN && sellToken && moreToBeBorrowedBN) {\n        const vaultBorrowRequest: sdk.VaultBorrowRequest = {\n          accountId: account.accountId,\n          token: {\n            tokenId: sellToken.vaultTokenId as unknown as number,\n            volume: moreToBeBorrowedBN.toString(),\n          },\n          timestamp: Date.now(),\n        }\n        let response = await LoopringAPI.vaultAPI?.submitVaultBorrow(\n          {\n            request: vaultBorrowRequest,\n            privateKey: account.eddsaKey?.sk,\n            apiKey: account.apiKey,\n          },\n          '1',\n        )\n        if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n          throw response\n        }\n\n        const recursiveCheckBorrow = async (hash: string) => {\n          const { account } = store.getState()\n          return LoopringAPI.vaultAPI\n            ?.getVaultGetOperationByHash(\n              {\n                accountId: account.accountId?.toString(),\n                hash: hash,\n              },\n              account.apiKey,\n            )\n            .then(({ operation }) => {\n              if (sdk.VaultOperationStatus.VAULT_STATUS_SUCCEED === operation?.status) {\n                l2CommonService.sendUserUpdate()\n                setLocalState((state) => {\n                  return {\n                    ...state,\n                    swapStatus: {\n                      status: 'swapping',\n                      borrowAmount: moreToBeBorrowed,\n                    },\n                  }\n                })\n              } else if (sdk.VaultOperationStatus.VAULT_STATUS_FAILED === operation?.status) {\n                l2CommonService.sendUserUpdate()\n                throw operation\n              } else {\n                return sdk.sleep(SUBMIT_PANEL_CHECK).then(() => {\n                  return recursiveCheckBorrow(hash)\n                })\n              }\n            })\n        }\n        // borrowHash.current = { hash: (response as any).hash }\n        await recursiveCheckBorrow((response as any).hash)\n        return swapSubmit()\n      }\n    } catch (e) {\n      const code =\n        (e as any)?.message === sdk.VaultOperationStatus.VAULT_STATUS_FAILED\n          ? UIERROR_CODE.ERROR_ORDER_FAILED\n          : (e as sdk.RESULT_INFO)?.code ?? UIERROR_CODE.UNKNOWN\n      const error = new CustomErrorWithCode({\n        code,\n        message: (e as sdk.RESULT_INFO)?.message,\n        ...SDK_ERROR_MAP_TO_UI[code],\n      })\n      setToastOpen({\n        open: true,\n        type: ToastType.error,\n        content: t('labelVaultBorrowFailed') + ' ' + t(error.messageKey, { ns: 'error' }),\n        step: VaultSwapStep.Borrow,\n      })\n      setLocalState((state) => {\n        return {\n          ...state,\n          swapStatus: { status: 'init' },\n          isSwapLoading: false,\n        }\n      })\n    }\n  }\n  const history = useHistory()\n  const {\n    confirmation: { confirmedOpenVaultPosition },\n  } = useConfirmation()\n  const _onClickTradeBtn = async () => {\n    if (!allowTrade?.order?.enable) {\n      setShowSupport({ isShow: true })\n      setIsSwapLoading(false)\n      return\n    }\n    if ((market && !marketMap[market]?.enabled) || !VaultInvest.enable) {\n      setShowTradeIsFrozen({\n        isShow: true,\n        type: 'Vault',\n      })\n      setIsSwapLoading(false)\n      return\n    }\n   \n    if (vaultAccountInfo?.accountStatus !== sdk.VaultAccountStatus.IN_STAKING) {\n      if (!confirmedOpenVaultPosition) {\n        setShowConfirmedVault({ isShow: true })  \n      } else {\n        history.push(`${RouterPath.vault}/${VaultKey.VAULT_DASHBOARD}`)\n        setShowConfirmedVault({ isShow: false })  \n        setShowVaultJoin({ isShow: true})\n      }\n      return\n    }\n\n    if (\n      smallTradePromptAmtBN &&\n      sellAmountBN &&\n      BigNumber.from(smallTradePromptAmtBN).gt(sellAmountBN) &&\n      !showSmallTradePrompt.show\n    ) {\n      const minimumConverted = tryFn(\n        () => {\n          return numberFormatThousandthPlace(\n            sdk\n              .toBig(calcDexOutput!.amountB!)\n              .times(sdk.toBig(1).minus(sdk.toBig(slippageReal).div('10000')))\n              .toString(),\n            { fixed: buyToken!.precision, removeTrailingZero: true },\n          )\n        },\n        () => '0',\n      )\n      setShowSmallTradePrompt({\n        show: true,\n        feePercentage: maxFeeBips ? new Decimal(maxFeeBips).div('100').toFixed(2) : '',\n        estimatedFee: feeAmount + ' ' + buyTokenOriginSymbol,\n        minimumConverted: minimumConverted + ' ' + buyTokenOriginSymbol,\n      })\n      return\n    }\n\n    if (borrowRequired) {\n      borrowSubmit()\n    } else {\n      swapSubmit()\n    }\n  }\n  const { chainId: _chainId } = useAppKitNetwork()\n  const chainId = Number(_chainId)\n  const { btnStatus, onBtnClick: onClickTradeBtn, btnLabel, isAccountActive } = useSubmitBtn({\n    availableTradeCheck: (a: any) => ({\n      tradeBtnStatus: tradeBtnStatus.disabled ? TradeBtnStatus.DISABLED : localState.isSwapLoading ? TradeBtnStatus.LOADING : TradeBtnStatus.AVAILABLE,\n      label: tradeBtnStatus.label,\n    }),\n    isLoading: localState.isSwapLoading,\n    submitCallback: _onClickTradeBtn,\n  })\n\n\n  React.useEffect(() => {\n    if (isOnPortalTradeRoute && refreshRef.current) {\n      restartTimer()\n    } else {\n      timerRef.current && clearInterval(timerRef.current)\n      clearData()\n      if (borrowHash?.current?.hash) {\n        updateVaultBorrowHash(borrowHash?.current?.hash, account.accAddress)\n      }\n      setToastOpen({ open: false, content: '', type: ToastType.info, step: '' })\n    }\n    return () => {\n      if (borrowHash?.current?.hash) {\n        updateVaultBorrowHash(borrowHash?.current?.hash, account.accAddress)\n      }\n      if (borrowHash.current?.timer) {\n        clearTimeout(borrowHash.current?.timer)\n        setIsSwapLoading(false)\n        borrowHash.current = null\n      }\n    }\n  }, [isOnPortalTradeRoute, refreshRef.current])\n  React.useEffect(() => {\n    const subscription = merge(subjectBtradeOrderbook).subscribe(({ btradeOrderbookMap }) => {\n      const localState = getLocalState()\n      const {\n        invest: {\n          vaultMap: { marketMap },\n        },\n      } = store.getState()\n      const item = marketMap && marketMap[market]\n      if (\n        item &&\n        btradeOrderbookMap &&\n        item?.wsMarket &&\n        btradeOrderbookMap[item.wsMarket] &&\n        localState.depth?.symbol &&\n        item.wsMarket === btradeOrderbookMap[item.wsMarket]?.symbol\n      ) {\n        setLocalState({\n          ...localState,\n          depth: { ...btradeOrderbookMap[item.wsMarket], symbol: localState.depth.symbol },\n        })\n        myLog('useVaultSwap: depth', btradeOrderbookMap[item.wsMarket])\n      }\n    })\n    return () => {\n      subscription.unsubscribe()\n    }\n  }, [market])\n\n  \n  const [showCloseAllConfirm, setShowCloseAllConfirm] = React.useState({\n    show: false\n  })\n  \n  const closeAllConfirmModalProps: CloseAllConfirmModalProps = {\n    open: showCloseAllConfirm.show,\n    onClose: () => {\n      setShowCloseAllConfirm({\n        show: false\n      })\n    },\n    onConfirm: async () => {\n      const symbols = filterPositions(vaultLayer2!, tokenMap, vaultTokenPrices)\n      closePositionsAndRepayIfNeeded(symbols)\n        .then((resList) => {\n          const foundErr = resList.find(\n            (res) => res.operation.status === sdk.VaultOperationStatus.VAULT_STATUS_FAILED,\n          )\n          if (foundErr) {\n            throw new Error('failed')\n          }\n          setShowGlobalToast({\n            isShow: true,\n            info: {\n              content: 'Closed position successfully',\n              type: ToastType.success,\n            },\n          })\n        })\n        .catch((e) => {\n          setShowGlobalToast({\n            isShow: true,\n            info: {\n              content: 'Close position failed',\n              type: ToastType.error,\n            },\n          })\n        })\n        .finally(() => {\n          setShowCloseAllConfirm({\n            show: false\n          })\n          updateVaultLayer2({})\n        })\n    }\n  }\n  \n  const vaultSwapModalProps = {\n    onClickCloseAll: () => {\n      setShowCloseAllConfirm({\n        show: true,\n      })\n    },\n    mainViewRef,\n    open: isShowVaultSwap.isShow,\n    hideOther: localState.hideOther,\n    onClickHideOther: () => {\n      setLocalState({\n        ...localState,\n        hideOther: !localState.hideOther,\n      })\n    },\n    onClose: () => {},\n    setting: {\n      hideLeverage: true,\n      onClickSettingLeverage: () => {},\n      leverage: 1,\n      onSwitchChange: () => {\n        setSwapSecondConfirmation(!swapSecondConfirmation)\n      },\n      secondConfirmationChecked: swapSecondConfirmation ?? false,\n      settingPopoverOpen: localState.showSetting,\n      onCloseSettingPopover: () => {\n        setLocalState({\n          ...localState,\n          showSetting: false,\n        })\n      },\n      onClickSettingBtn: () => {\n        setLocalState({\n          ...localState,\n          showSetting: !localState.showSetting,\n        })\n      },\n      slippageList: ['0.1', '0.5', '1', `slippage:${slippage}`],\n      currentSlippage: slippage,\n      onSlippageChange: (_slippage, customSlippage) => {\n        setSlippage(_slippage)\n      },\n    },\n    countdown: {\n      countDownSeconds: 10,\n      onRefreshData: () => {\n        refreshData()\n      },\n      ref: refreshRef,\n    },\n    isLongOrShort: isLongOrShort,\n    onClickBalance: () => {\n      userMaxTradeValueWithoutBorrow &&\n        setLocalState({\n          ...localState,\n          amount: numberFormat(userMaxTradeValueWithoutBorrow, {\n            fixed: selectedVTokenInfo!.vaultTokenAmounts.qtyStepScale,\n            removeTrailingZero: true,\n            fixedRound: Decimal.ROUND_FLOOR,\n          }),\n        })\n    },\n    onClickMax: () => {\n      maxTradeValue &&\n        setLocalState({\n          ...localState,\n          amount: numberFormat(maxTradeValue, {\n            fixed: selectedVTokenInfo?.vaultTokenAmounts.qtyStepScale,\n            fixedRound: Decimal.ROUND_FLOOR,\n            removeTrailingZero: true,\n          }),\n        })\n    },\n    onClickToken: () => {\n      setLocalState({\n        ...localState,\n        showTokenSelection: true,\n      })\n    },\n    balance: tryFn(\n      () => {\n        if (new Decimal(userMaxSellValueWithoutBorrow!).lessThanOrEqualTo('0'))\n          return '0 ' + sellTokenOriginSymbol\n        return (\n          numberFormatThousandthPlace(userMaxSellValueWithoutBorrow!, {\n            fixed: sellToken!.vaultTokenAmounts.qtyStepScale,\n            removeTrailingZero: true,\n            fixedRound: Decimal.ROUND_FLOOR,\n          }) +\n          ' ' +\n          sellTokenOriginSymbol\n        )\n      },\n      () => {\n        return EmptyValueTag + ' ' + sellTokenOriginSymbol\n      },\n    ),\n    token: {\n      symbol: selectedTokenSymbol,\n      coinJSON: coinJson[selectedTokenSymbol],\n    },\n    onInputAmount: (amount: string) => {\n      if (\n        amount &&\n        (!isNumberStr(amount) ||\n          !selectedVTokenInfo ||\n          !strNumDecimalPlacesLessThan(\n            amount,\n            selectedVTokenInfo.vaultTokenAmounts.qtyStepScale + 1,\n          ))\n      )\n        return\n      setLocalState({\n        ...localState,\n        slideValue: 0,\n        amount,\n      })\n    },\n    inputPlaceholder: tradeMinAmt\n      ? `Min ${numberFormat(tradeMinAmt, {\n          fixed: selectedVTokenInfo?.vaultTokenAmounts.qtyStepScale,\n          removeTrailingZero: true,\n          fixedRound: Decimal.ROUND_CEIL,\n        })}`\n      : '0.00',\n    amountInput: localState.amount,\n    inputAlert: {\n      show: btnStatus !== TradeBtnStatus.AVAILABLE || localState.swapStatus.status !== 'init',\n      type:\n        tradeBtnStatus.label !== undefined\n          ? 'error'\n          : localState.swapStatus.status === 'borrowing'\n          ? 'warning'\n          : localState.swapStatus.status === 'swapping'\n          ? 'success'\n          : undefined,\n      message: tryFn(\n        () => {\n          if (tradeBtnStatus.label) return tWrap(t, tradeBtnStatus.label, chainId ?? 1)\n          if (localState.swapStatus.status === 'borrowing') {\n            return (\n              localState.swapStatus.borrowAmount &&\n              sellToken &&\n              `Borrowing ${numberFormatThousandthPlace(localState.swapStatus.borrowAmount!, {\n                fixed: sellToken.vaultTokenAmounts.qtyStepScale,\n                removeTrailingZero: true,\n              })} ${sellTokenOriginSymbol}`\n            )\n          } else if (localState.swapStatus.status === 'swapping') {\n            return (\n              localState.swapStatus.borrowAmount &&\n              sellToken &&\n              `Borrowed ${numberFormatThousandthPlace(localState.swapStatus.borrowAmount!, {\n                fixed: sellToken.vaultTokenAmounts.qtyStepScale,\n                removeTrailingZero: true,\n              })} ${sellTokenOriginSymbol}`\n            )\n          }\n        },\n        () => '',\n      ),\n      icon:\n        localState.swapStatus.status === 'borrowing'\n          ? 'wait'\n          : localState.swapStatus.status === 'swapping'\n          ? 'completed'\n          : undefined,\n    },\n    swapRatio,\n    onClickReverse: () => {\n      setLocalState({\n        ...localState,\n        isSwapRatioReversed: !localState.isSwapRatioReversed,\n      })\n    },\n    amounInUSDT: amounInUSDT\n      ? numberFormatThousandthPlace(amounInUSDT, {\n          fixed: LVUSDTInfo?.precisionForOrder,\n          removeTrailingZero: true,\n        }) + ' USDT'\n      : EmptyValueTag + ' USDT',\n    maxTradeValue: tryFn(\n      () => {\n        return (\n          numberFormatThousandthPlace(maxSellValue, {\n            fixed: sellToken?.vaultTokenAmounts.qtyStepScale,\n            fixedRound: Decimal.ROUND_FLOOR,\n            removeTrailingZero: true,\n          }) +\n          ' ' +\n          sellTokenOriginSymbol\n        )\n      },\n      () => EmptyValueTag + ' ' + sellTokenOriginSymbol,\n    ),\n    borrowed: tryFn(\n      () => {\n        if (new Decimal(sellTokenAsset!.borrowed).lessThanOrEqualTo(0)) return EmptyValueTag\n        return (\n          numberFormatThousandthPlace(\n            utils.formatUnits(sellTokenAsset!.borrowed!, sellToken?.decimals),\n            {\n              fixed: sellToken!.precision,\n              fixedRound: Decimal.ROUND_FLOOR,\n              removeTrailingZero: true,\n            },\n          ) +\n          ' ' +\n          sellTokenOriginSymbol\n        )\n      },\n      () => EmptyValueTag,\n    ),\n    moreToBeBorrowed: tryFn(\n      () => {\n        return (\n          numberFormatThousandthPlace(moreToBeBorrowed!, {\n            fixed: sellToken!.vaultTokenAmounts.qtyStepScale,\n            fixedRound: Decimal.ROUND_CEIL,\n            removeTrailingZero: true,\n          }) +\n          ' ' +\n          sellTokenOriginSymbol\n        )\n      },\n      () => EmptyValueTag,\n    ),\n    totalQuota: tryFn(\n      () =>\n        numberFormatThousandthPlace(totalSellQuota!, {\n          fixed: sellToken?.vaultTokenAmounts.qtyStepScale,\n          fixedRound: Decimal.ROUND_FLOOR,\n          removeTrailingZero: true,\n        }) +\n        ' ' +\n        sellTokenOriginSymbol,\n      () => EmptyValueTag,\n    ),\n    marginLevelChange: tryFn(\n      () => {\n        if (moreToBeBorrowed && new Decimal(moreToBeBorrowed).greaterThan('0')) {\n          const moreToBorrowInUSD =\n            moreToBeBorrowed && new Decimal(moreToBeBorrowed).greaterThan('0')\n              ? new Decimal(moreToBeBorrowed).mul(vaultTokenPrices[sellToken!.symbol!]).toString()\n              : undefined\n          var nextMarginLevel = calcMarinLevel(\n            vaultAccountInfo!.totalCollateralOfUsdt,\n            vaultAccountInfo!.totalDebtOfUsdt,\n            vaultAccountInfo!.totalBalanceOfUsdt,\n            moreToBorrowInUSD!,\n            '0',\n          )\n        }\n\n        return {\n          from: {\n            marginLevel: vaultAccountInfo!.marginLevel,\n            type: marginLevelType(vaultAccountInfo!.marginLevel),\n          },\n          to: nextMarginLevel\n            ? {\n                marginLevel: nextMarginLevel,\n                type: marginLevelType(nextMarginLevel!),\n              }\n            : undefined,\n        }\n      },\n      () => undefined,\n    ),\n    tradeBtn: {\n      disabled: btnStatus === TradeBtnStatus.DISABLED,\n      onClick: () => {\n        onClickTradeBtn()\n      },\n      label: btnLabel\n        ? tWrap(t, btnLabel, chainId ?? 1)\n        : vaultAccountInfo?.accountStatus === sdk.VaultAccountStatus.FREE\n        ? 'Supply Collateral'\n        : isLongOrShort === 'long'\n        ? 'Buy / Long'\n        : 'Sell / Short',\n      loading: localState.isSwapLoading,\n      bgColor:\n        !isAccountActive || vaultAccountInfo?.accountStatus === sdk.VaultAccountStatus.FREE\n          ? 'var(--color-primary)'\n          : isLongOrShort === 'long'\n          ? 'var(--color-success)'\n          : 'var(--color-error)',\n    },\n    hourlyInterestRate:\n      sellTokenAsset?.borrowed && new Decimal(sellTokenAsset.borrowed).gt(0) && sellToken\n        ? toPercent(sellToken.interestRate, 7)\n        : EmptyValueTag,\n    tradingFee: tryFn(\n      () => {\n        if (new Decimal(feeAmount!).lessThanOrEqualTo('0')) {\n          return EmptyValueTag + ' ' + buyTokenOriginSymbol\n        }\n        return (\n          numberFormatThousandthPlace(feeAmount!, {\n            fixed: buyToken!.precision,\n            removeTrailingZero: true,\n          }) +\n          ' ' +\n          buyTokenOriginSymbol\n        )\n      },\n      () => EmptyValueTag + ' ' + buyTokenOriginSymbol,\n    ),\n    tradingFeeDescription: tryFn(\n      () => {\n        const feeBips = maxFeeBips ?? marketInfo?.feeBips ?? MAPFEEBIPS\n        return `The trading fee is ${toPercent((feeBips / 100).toString(), 2)}.`\n      },\n      () => '',\n    ),\n    slippageTolerance: `${slippageReal}%`,\n    onClickLongShort: (v: 'long' | 'short') => {\n      setLocalState({\n        ...localState,\n        isLongOrShort: v,\n        maxBorrowableSellToken: undefined,\n        slideValue: 0,\n        amount: '',\n        depth: undefined,\n      })\n      restartTimer()\n    },\n    myPositions,\n    showMyPositions: account.readyState === 'ACTIVATED',\n    leverageSelection: {\n      value: vaultAccountInfo?.leverage,\n\n      onChange: async (value: string) => {\n        await LoopringAPI.vaultAPI\n          ?.submitLeverage(\n            {\n              request: {\n                accountId: account.accountId.toString(),\n                leverage: value,\n              },\n              apiKey: account.apiKey,\n            },\n            '1',\n          )\n          .finally(() => {\n            refreshData()\n          })\n      },\n      items: maxLeverage\n        ? _.range(1, Number(maxLeverage) + 1).map((leverage: number) => ({\n            label: `${leverage}x`,\n            value: leverage.toString(),\n            disabled: false,\n          }))\n          .concat(Number(vaultAccountInfo?.leverage) > Number(maxLeverage) ? [\n             {\n              label: vaultAccountInfo?.leverage + 'x',\n              value: vaultAccountInfo?.leverage ?? '',\n              disabled: true,\n            },\n          ] : [])\n        : [],\n    },\n    positionTypeSelection: {\n      value: 'cross',\n      onChange: () => {},\n      items: [\n        {\n          label: 'Cross Position',\n          value: 'cross',\n          tooltipTitle:\n            'All positions within this account share a single health factor, determined by the real-time prices of your collateral, holdings, and debts. If the health factor falls below the liquidation threshold, all positions under this account are subject to liquidation.',\n        },\n      ],\n    },\n    ratioSlider: {\n      currentRatio: localState.slideValue,\n      onClickRatio: (no: number) => {\n        if (!maxTradeValue || new Decimal(maxTradeValue).eq('0')) return\n        setLocalState((state) => {\n          return {\n            ...state,\n            amount: new Decimal(maxTradeValue)\n              .mul(new Decimal(no))\n              .toDecimalPlaces(selectedVTokenInfo?.vaultTokenAmounts.qtyStepScale)\n              .toString(),\n            slideValue: no,\n          }\n        })\n      },\n    },\n\n    tokenSelection: {\n      show: localState.showTokenSelection,\n      search: localState.tokenSelectionInput,\n      onClickCancel: () => {\n        setLocalState({\n          ...localState,\n          showTokenSelection: false,\n          tokenSelectionInput: '',\n        })\n      },\n      tokens: tokenMap\n        ? _.keys(tokenMap)\n            .map((symbol) => {\n              const asset = vaultLayer2 ? vaultLayer2[symbol] : undefined\n              const tokenInfo = tokenMap[symbol]\n              return tokenInfo\n                ? {\n                    symbol: symbol.slice(2),\n                    amount: numberFormatThousandthPlace(\n                      utils.formatUnits(asset?.total ?? '0', tokenInfo.decimals),\n                      { fixed: tokenInfo.precision, removeTrailingZero: true },\n                    ),\n                    coinJSON: coinJson[symbol.slice(2)],\n                    onClick: () => {\n                      setLocalState({\n                        ...localState,\n                        showTokenSelection: false,\n                        selectedToken: symbol === 'LVUSDT' ? 'ETH' : symbol.slice(2),\n                        tokenSelectionInput: '',\n                        amount: '',\n                        slideValue: 0,\n                        depth: undefined,\n                      })\n                      restartTimer()\n                      refreshData()\n                    },\n                  }\n                : undefined\n            })\n            .filter(\n              (item) =>\n                item !== undefined &&\n                !['USDT', 'USDC', 'LRTAIKO'].includes(item?.symbol) &&\n                (!localState.tokenSelectionInput ||\n                  item.symbol.toLowerCase().includes(localState.tokenSelectionInput.toLowerCase())),\n            )\n        : [],\n      onInputSearch: (v: string) => {\n        setLocalState({\n          ...localState,\n          tokenSelectionInput: v,\n          amount: '',\n        })\n      },\n    },\n    showLeverageSelect: account.readyState === AccountStatus.ACTIVATED,\n  }\n\n  const smallOrderAlertProps = {\n    open: showSmallTradePrompt.show,\n    handleClose: () => {\n      setShowSmallTradePrompt({\n        show: false,\n        estimatedFee: undefined,\n        minimumConverted: undefined,\n        feePercentage: undefined,\n      })\n    },\n    handleConfirm: () => {\n      setShowSmallTradePrompt({\n        show: false,\n        estimatedFee: undefined,\n        minimumConverted: undefined,\n        feePercentage: undefined,\n      })\n      if (borrowRequired) {\n        borrowSubmit()\n      } else {\n        swapSubmit()\n      }\n    },\n    estimatedFee: showSmallTradePrompt.estimatedFee ?? '',\n    feePercentage: showSmallTradePrompt.feePercentage ?? '',\n    minimumReceived: showSmallTradePrompt.minimumConverted ?? '',\n  }\n\n  const toastProps = {\n    alertText: toastOpen?.content ?? '',\n    open: toastOpen?.open ?? false,\n    autoHideDuration: TOAST_TIME,\n    onClose: closeToast,\n    severity: toastOpen?.type,\n  }\n  return {\n    vaultSwapModalProps,\n    smallOrderAlertProps,\n    toastProps,\n    closeAllConfirmModalProps,\n  }\n}\n"
  },
  {
    "path": "packages/component-lib/src/sharedPages/VaultPage/index.tsx",
    "content": "\n\n\nimport {\n  useSettings,\n} from '@loopring-web/component-lib'\nimport { useVaultPage } from './hooks/useVaultPage'\nimport { VaultPageUI } from './components/VaultPageUI'\nexport { useVaultMarket } from './hooks/useVaultMarket'\nexport { useGetVaultAssets } from './hooks/useVaultDashBoard'\n\nexport const VaultPage = () => {\n  const props = useVaultPage()\n\n  return (\n    <VaultPageUI\n      {...props}\n    />\n  )\n}\n"
  },
  {
    "path": "packages/component-lib/src/sharedPages/VaultPage/interface.ts",
    "content": "import { ReactNode } from 'react'\nimport {\n  CurrencyToTag,\n  VaultAction,\n  UpColor,\n  ForexMap,\n} from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport {\n  ModalStatePlayLoad,\n} from '@loopring-web/component-lib'\nimport { TFunction } from 'react-i18next'\nimport { Theme } from '@emotion/react'\nimport { VaultPositionsTableProps } from '@loopring-web/component-lib/src/components/tableList/assetsTable/VaultPositionsTable'\n\nexport interface VaultDashBoardPanelUIProps {\n  t: TFunction;\n  forexMap: ForexMap;\n  theme: Theme;\n  currency: CurrencyToTag;\n  hideAssets: boolean;\n  upColor: keyof typeof UpColor;\n  showMarginLevelAlert: boolean;\n  vaultAccountInfo?: sdk.VaultAccountInfo;\n  localState: any;\n  setLocalState: (state: any) => void;\n  colors: string[];\n  assetPanelProps: any;\n  marketProps: any;\n  vaultTokenMap: any;\n  vaultTickerMap: any;\n  VaultDustCollector: any;\n  isShowVaultJoin: ModalStatePlayLoad;\n  detail: any;\n  setShowDetail: (detail: any) => void;\n  hideLeverage: boolean;\n  activeInfo: any;\n  walletMap: any;\n  _vaultAccountInfo: any;\n  tokenPrices: any;\n  getValueInCurrency: (value: string) => string;\n  history: any;\n  etherscanBaseUrl: string;\n  onClickCollateralManagement: () => void;\n  onClickSettle: () => void;\n  onClickPortalTrade: () => void;\n  liquidationThreshold: string;\n  liquidationPenalty: string;\n  assetsTab: 'assetsView' | 'positionsView';\n  onChangeAssetsTab: (tab: 'assetsView' | 'positionsView') => void;\n  onClickRecord: () => void;\n  vaultPositionsTableProps: VaultPositionsTableProps;\n  onClickHideShowAssets: () => void;\n  vaultAccountActive: boolean\n  totalEquity: string\n  showSettleBtn: boolean\n  btnsDisabled: boolean\n  onClickBuy: (market: any) => void;\n  onClickSell: (market: any) => void;\n  didAccountSignIn: boolean\n}\n\nexport interface CollateralDetailsModalProps {\n  open: boolean;\n  onClose: () => void;\n  onClickMaxCredit: () => void;\n  collateralTokens: {\n    name: string;\n    logo: string;\n    amount: string;\n    valueInCurrency: string;\n  }[];\n  totalCollateral: string;\n  maxCredit: string;\n  coinJSON: any;\n}\n\nexport interface MaximumCreditModalProps {\n  open: boolean;\n  onClose: () => void;\n  onClickBack: () => void;\n  collateralFactors: {\n    name: string;\n    collateralFactor: string;\n  }[];\n  maxLeverage: string;\n}\n\nexport interface LeverageModalProps {\n  open: boolean;\n  maxLeverage: number;\n  onClose: () => void;\n  onClickMaxCredit: () => void;\n  onClickReduce: () => void;\n  onClickAdd: () => void;\n  onClickLeverage: (leverage: number) => void;\n  currentLeverage: number | undefined;\n  borrowAvailable: string;\n  borrowed: string;\n  maximumCredit: string;\n  isLoading: boolean;\n}\n\nexport interface DebtModalProps {\n  open: boolean\n  onClose: () => void\n  totalFundingFee: string\n  totalBorrowed: string\n  totalDebt: string\n  borrowedVaultTokens:\n    | {\n        symbol: string\n        coinJSON: any\n        amount: string\n        valueInCurrency: string\n        onClick: () => void\n      }[]\n    | undefined\n}\n\nexport interface DustCollectorUnAvailableModalProps {\n  open: boolean\n  onClose: () => void\n}\n\nexport interface DustCollectorProps {\n  open: boolean\n  converting: boolean\n  onClose: () => void\n  dusts?: {\n      symbol: string;\n      amount: string;\n      valueInCurrency: string;\n      checked: boolean;\n      coinJSON: any;\n      onCheck: () => void;\n    }[]\n  totalValueInUSDT: string\n  totalValueInCurrency: string\n  onClickConvert: () => void\n  onClickRecords: () => void\n  convertBtnDisabled: boolean\n}"
  },
  {
    "path": "packages/component-lib/src/sharedPages/VaultPage/utils.ts",
    "content": "import { DAYS, getTimestampDaysLater, LoopringAPI, NETWORKEXTEND, VaultLayer2Map, withRetry } from \"@loopring-web/core\"\nimport { ChainId, ConnectorNames, toBig, VaultToken } from \"@loopring-web/loopring-sdk\"\nimport { ConnectProviders, connectProvides } from \"@loopring-web/web3-provider\"\n\nimport {\n  SUBMIT_PANEL_CHECK,\n} from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport {\n  numberFormat,\n  store,\n\n  MAPFEEBIPS,\n  vaultSwapDependAsync,\n  bignumberFix\n} from '@loopring-web/core'\nimport { utils, BigNumber } from 'ethers'\nimport Decimal from 'decimal.js'\nimport _, { keys } from 'lodash'\nimport { promiseAllSequently } from \"@loopring-web/core/src/utils/promise\"\nimport { updateVaultLayer2 } from \"@loopring-web/core/src/stores/vaultLayer2/reducer\"\n\nconst checkIfNeedRepay = (symbol: string) => {\n  const {\n    vaultLayer2: { vaultLayer2 },\n    invest: {\n      vaultMap: {\n        tokenMap\n      },\n    },\n  } = store.getState()\n  const asset = vaultLayer2?.[symbol]\n  const tokenInfo = tokenMap[symbol]\n  if (!asset) return false\n  \n  const minLoanAmount = tokenInfo?.vaultTokenAmounts?.minLoanAmount\n  const repayVolume = BigNumber.from(asset.borrowed).lte(BigNumber.from(asset.total)) \n    ? asset.borrowed \n    : asset.total\n  return new Decimal(asset?.borrowed ?? '0').gt('0') &&\n    new Decimal(asset?.total ?? '0').gt('0') &&\n    (!minLoanAmount || toBig(repayVolume ?? '0').gte(minLoanAmount))\n}\n\nexport const checkHasTokenNeedRepay = () => {\n  const {\n    vaultLayer2: { vaultLayer2 },\n  } = store.getState()\n  return vaultLayer2\n    ? keys(vaultLayer2).filter((symbol) => checkIfNeedRepay(symbol) && symbol !== 'undefined')\n    : []\n}\n\nexport const repayIfNeeded = async (symbol: string) => {\n  \n  const {\n    vaultLayer2: { vaultLayer2 },\n    invest: {\n      vaultMap: {\n        tokenMap,\n      },\n    },\n    system: { exchangeInfo, chainId },\n    account\n  } = store.getState()\n  const asset = vaultLayer2?.[symbol]\n  const tokenInfo = tokenMap[symbol] as VaultToken\n\n  if (!checkIfNeedRepay(symbol)) return\n  const [{ broker }, { offchainId }] = await Promise.all([\n    LoopringAPI.userAPI!.getAvailableBroker({\n      type: 4,\n    }),\n    LoopringAPI.userAPI!.getNextStorageId(\n      {\n        accountId: account.accountId,\n        sellTokenId: tokenInfo.vaultTokenId,\n      },\n      account.apiKey,\n    ),\n  ])\n  const volume = BigNumber.from(asset!.borrowed).lte(BigNumber.from(asset!.total)) \n    ? asset!.borrowed \n    : asset!.total\n  const volumeFixed = bignumberFix(\n    BigNumber.from(volume),\n    tokenInfo.decimals,\n    tokenInfo.vaultTokenAmounts.qtyStepScale,\n    'FLOOR'\n  )\n    \n\n  const request = {\n    exchange: exchangeInfo!.exchangeAddress,\n    payerAddr: account.accAddress,\n    payerId: account.accountId,\n    payeeId: 0,\n    payeeAddr: broker,\n    storageId: offchainId,\n    token: {\n      tokenId: tokenInfo.vaultTokenId,\n      volume: volumeFixed.toString(),\n    },\n    maxFee: {\n      tokenId: tokenInfo.vaultTokenId,\n      volume: '0',\n    },\n    validUntil: getTimestampDaysLater(DAYS),\n    memo: '',\n  }\n\n\n  return await LoopringAPI.vaultAPI?.submitVaultRepay(\n    {\n    \n      request: request,\n      web3: connectProvides.usedWeb3 as any,\n      chainId: chainId === NETWORKEXTEND.NONETWORK ? ChainId.MAINNET : chainId,\n      walletType: (ConnectProviders[account.connectName] ??\n        account.connectName) as unknown as ConnectorNames,\n      eddsaKey: account.eddsaKey.sk,\n      apiKey: account.apiKey,\n    },\n    {\n      accountId: account.accountId,\n      counterFactualInfo: account.eddsaKey.counterFactualInfo,\n    },\n    '1'\n  )\n}\n\nconst recursiveCheckHash = async (hash: string): Promise<{\n  operation: sdk.VaultOperation;\n  order: sdk.VaultOrder;\n  raw_data: {\n    operation: sdk.VaultOperation;\n    order: sdk.VaultOrder;\n};\n}> => {\n  const { account } = store.getState()\n  return LoopringAPI.vaultAPI!.getVaultGetOperationByHash(\n    {\n      accountId: account.accountId as any,\n      // @ts-ignore\n      hash: hash,\n    },\n    account.apiKey,\n    '1',\n  ).then((res) => {\n    if (res.operation.status === sdk.VaultOperationStatus.VAULT_STATUS_PROCESSING || res.operation.status === sdk.VaultOperationStatus.VAULT_STATUS_PENDING) {\n      return sdk.sleep(2000)\n      .then(() => {\n        return recursiveCheckHash(hash)\n      })\n    } else if (res.operation.status === sdk.VaultOperationStatus.VAULT_STATUS_FAILED) {\n      throw res\n    } else {\n      return res\n    }\n  })\n}\n\nconst closeShort = async (symbol: string) => {\n  const {\n    invest: {\n      vaultMap: { tokenMap },\n    },\n    account,\n  } = store.getState()\n  \n  const res = await LoopringAPI.vaultAPI?.closeShort(\n    {\n      request: {\n        accountId: account.accountId,\n        tokenId: tokenMap[symbol].vaultTokenId,\n        timestamp: Date.now(),\n      },\n    },\n    account.apiKey,\n    account.eddsaKey.sk,\n  )\n  if ((res as sdk.RESULT_INFO).code || (res as sdk.RESULT_INFO).message) {\n    throw res\n  } else {\n    const hash = (res as {hash: string}).hash\n    return recursiveCheckHash(hash)\n  }\n}\n\nconst closeLongDust = async (symbol: string) => {\n  const {\n    vaultLayer2: { vaultLayer2 },\n    invest: {\n      vaultMap: { tokenMap },\n    },\n    account,\n    system: { exchangeInfo },\n  } = store.getState()\n  const vaultAsset = vaultLayer2![symbol]\n  const closeTokenInfo = tokenMap[symbol]\n  const tokenId = closeTokenInfo.vaultTokenId\n\n  const { offchainId } = await LoopringAPI.userAPI?.getNextStorageId(\n    {\n      accountId: account.accountId,\n      sellTokenId: tokenId,\n    },\n    account.apiKey,\n  )!\n  const { broker } = await LoopringAPI.userAPI?.getAvailableBroker({\n    type: 4,\n  })!\n\n  const dustTransfer = {\n    exchange: exchangeInfo!.exchangeAddress,\n    payerAddr: account.accAddress,\n    payerId: account.accountId,\n    payeeId: 0,\n    payeeAddr: broker,\n    storageId: offchainId,\n    token: {\n      tokenId: tokenId,\n      volume: vaultAsset.total,\n    },\n    maxFee: {\n      tokenId: tokenId,\n      volume: '0',\n    },\n    validUntil: getTimestampDaysLater(DAYS),\n    memo: '',\n  }\n\n  const res = await LoopringAPI.vaultAPI?.submitDustCollector(\n    {\n      dustTransfers: [dustTransfer],\n      apiKey: account.apiKey,\n      accountId: account.accountId,\n      eddsaKey: account.eddsaKey.sk,\n    },\n    '1',\n  )\n  if ((res as sdk.RESULT_INFO).code || (res as sdk.RESULT_INFO).message) {\n    throw res\n  } else {\n    const hash = (res as {hash: string}).hash\n    return recursiveCheckHash(hash)\n  }\n}\n\nconst closeLongDustIfNeeded = async (symbol: string) => {\n  const {\n    vaultLayer2: { vaultLayer2 }\n  } = store.getState()\n  const vaultAsset = vaultLayer2 && symbol ? vaultLayer2[symbol] : undefined\n  if (!vaultAsset || !new Decimal(vaultAsset.netAsset).isPos()) {\n    return undefined\n  } else {\n    return closeLongDust(symbol)\n  }\n}\n\nconst closeLong = async (symbol: string, depth: sdk.DepthData) => {\n  const {\n    vaultLayer2: { vaultLayer2 },\n    invest: {\n      vaultMap: { tokenMap, marketMap, marketArray },\n    },\n    account,\n    settings: { slippage },\n    system: { exchangeInfo },\n  } = store.getState()\n  const vaultAsset = vaultLayer2![symbol]\n  const sellToken = tokenMap[symbol] as VaultToken\n  const buyToken = tokenMap['LVUSDT']\n  const storageId = await LoopringAPI.userAPI?.getNextStorageId(\n    {\n      accountId: account.accountId,\n      sellTokenId: sellToken?.vaultTokenId ?? 0,\n    },\n    account.apiKey,\n  )\n  const market = `${symbol}-LVUSDT`\n  const marketInfo = marketMap[market] as sdk.VaultMarket\n\n  const slippageReal = Math.max(1, slippage === 'N' ? 1 : slippage)\n  \n  const sellAmountBN = bignumberFix(\n    BigNumber.from(vaultAsset.total).abs(),\n    sellToken.decimals,\n    sellToken.vaultTokenAmounts.qtyStepScale,\n    'FLOOR',\n  )\n  const output = sdk.calcDex({\n    info: marketInfo,\n    input: utils.formatUnits(\n      sellAmountBN.toString(),\n      tokenMap[symbol].decimals,\n    ),\n    sell: sellToken.symbol,\n    buy: buyToken.symbol,\n    isAtoB: true,\n    marketArr: marketArray,\n    tokenMap: tokenMap,\n    marketMap: marketMap as any,\n    depth: depth!,\n    feeBips: (marketInfo.feeBips ?? MAPFEEBIPS).toString(),\n    slipBips: slippageReal.toString(),\n  })\n\n  const buyAmountBN = utils.parseUnits(\n    numberFormat(output!.amountB!, { fixed: buyToken.decimals }),\n    buyToken.decimals,\n  )\n  const request: sdk.VaultOrderRequest = {\n    exchange: exchangeInfo!.exchangeAddress,\n    storageId: storageId!.orderId,\n    accountId: account.accountId,\n    sellToken: {\n      tokenId: sellToken?.vaultTokenId ?? 0,\n      volume: sellAmountBN.toString(),\n    },\n    buyToken: {\n      tokenId: buyToken?.vaultTokenId ?? 0,\n      volume: buyAmountBN.toString(),\n    },\n    validUntil: getTimestampDaysLater(DAYS),\n    maxFeeBips: MAPFEEBIPS,\n    fillAmountBOrS: false,\n    allOrNone: false,\n    eddsaSignature: '',\n    clientOrderId: '',\n    orderType: sdk.OrderTypeResp.TakerOnly,\n    fastMode: false,\n  }\n  const response = await LoopringAPI.vaultAPI?.submitVaultOrder(\n    {\n      request,\n      privateKey: account.eddsaKey.sk,\n      apiKey: account.apiKey,\n    },\n    '1',\n  )\n  if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n    throw response\n  } else {\n    const hash = (response as {hash: string}).hash\n    return recursiveCheckHash(hash)\n  }\n  \n}\n\nconst checkIsDust = async (symbol: string) => {\n  const {\n    vaultLayer2: { vaultLayer2 },\n    invest: {\n      vaultMap: { tokenMap, marketMap, marketArray },\n    },\n    settings: { slippage },\n  } = store.getState()\n  const vaultAsset = vaultLayer2![symbol]\n  const sellToken = tokenMap[symbol]\n  const buyToken = tokenMap['LVUSDT']\n  const market = `${symbol}-LVUSDT`\n  const marketInfo = marketMap[market] as sdk.VaultMarket\n  const { depth } = await vaultSwapDependAsync({\n    market: (marketInfo as any).vaultMarket,\n    tokenMap: tokenMap,\n  })\n\n  const slippageReal = slippage === 'N' ? 0.1 : slippage\n  const output = sdk.calcDex({\n    info: marketInfo,\n    input: utils.formatUnits(BigNumber.from(vaultAsset.netAsset).abs().toString(), sellToken.decimals),\n    sell: sellToken.symbol,\n    buy: buyToken.symbol,\n    isAtoB: true,\n    marketArr: marketArray,\n    tokenMap: tokenMap,\n    marketMap: marketMap as any,\n    depth: depth!,\n    feeBips: (marketInfo.feeBips ?? MAPFEEBIPS).toString(),\n    slipBips: slippageReal.toString(),\n  })\n  const USDTAmount = output!.amountB!\n  return { isDust: new Decimal(USDTAmount).lt('10'), depth }\n}\n\nconst closePosition = async (symbol: string) => {\n\n\n  const {\n    vaultLayer2: { vaultLayer2 },\n    system: { exchangeInfo },\n  } = store.getState()\n  const vaultAsset = vaultLayer2 && symbol ? vaultLayer2[symbol] : undefined\n  if (!symbol || !vaultAsset || !exchangeInfo || new Decimal(vaultAsset.netAsset).isZero())\n    throw new Error('error')\n\n  if (!new Decimal(vaultAsset.netAsset).isPos()) {\n    var response = await closeShort(symbol)\n  } else {\n    const { isDust, depth } = await checkIsDust(symbol)\n    if (isDust) {\n      response = await closeLongDust(symbol)\n    } else {\n      response = await withRetry(closeLong, 2)(symbol, depth!)\n    }\n  }\n\n  return response\n}\n\nexport const closePositionAndRepayIfNeeded = async (symbol: string) => {\n  const response = await closePosition(symbol)\n  updateVaultLayer2({})\n  sdk.sleep(2 * 1000).then(() => {\n    return promiseAllSequently(\n      [symbol, 'LVUSDT'].map((symbol) => () => repayIfNeeded(symbol).catch(() => undefined)),\n    )\n  })\n  return response\n}\n\nconst closePositions = async (symbols: string[]) => {\n  return promiseAllSequently(\n    symbols.map((symbol) => async () => {\n      const res = await closePosition(symbol)\n      await sdk.sleep(500)\n      return res \n    }),\n  ) as Promise<{\n    operation: sdk.VaultOperation;\n    order: sdk.VaultOrder;\n  }[]>\n}\n\nexport const closePositionsAndRepayIfNeeded = async (symbols: string[]) => {\n  const responses = await closePositions(symbols)\n  updateVaultLayer2({})\n  await sdk.sleep(500)\n  await promiseAllSequently(\n    symbols.concat('LVUSDT').map((symbol) => () => repayIfNeeded(symbol).catch(() => undefined)),\n  )\n  return responses\n}\n\nexport const filterPositions = (vaultLayer2: VaultLayer2Map<any>, tokenMap: sdk.LoopringMap<sdk.TokenInfo>, tokenPrices: sdk.LoopringMap<string>) => {\n  return _.keys(vaultLayer2).filter((symbol) => {\n    const asset = vaultLayer2 ? vaultLayer2[symbol] : undefined\n    const tokenInfo = tokenMap?.[symbol]\n    const tokenPrice = tokenPrices?.[symbol]\n    \n    if (!asset || !tokenInfo || !tokenPrice) return false\n    const position = new Decimal(\n      utils.formatUnits(BigNumber.from(asset.netAsset).add(asset.interest), tokenInfo.decimals),\n    )\n    const positionValue = position.abs().times(tokenPrice)\n\n    return symbol !== 'LVUSDT' && positionValue.greaterThan('10')\n  })\n}"
  },
  {
    "path": "packages/component-lib/src/sharedPages/index.ts",
    "content": "export {VaultPage, useGetVaultAssets, useVaultMarket} from './VaultPage'"
  },
  {
    "path": "packages/component-lib/src/static.ts",
    "content": "import {\n  Account,\n  AccountStatus,\n  AmmInData,\n  BanxaOrder,\n  CoinInfo,\n  CoinMap,\n  DualCalcData,\n  DualViewInfo,\n  ForexMap,\n  HeaderMenuItemInterface,\n  TradeCalcData,\n  WalletCoin,\n  WalletMap,\n} from '@loopring-web/common-resources'\nimport { List } from 'immutable'\nimport { ConnectProviders } from '@loopring-web/web3-provider'\nimport { Currency, DUAL_TYPE, LuckyTokenItemForReceive } from '@loopring-web/loopring-sdk'\n\nexport const account: Account = {\n  hasUnknownCollection: true,\n  __timer__: -1,\n  frozen: false,\n  accAddress: 'xxxxxxxxxxxxxxxxxxx',\n  qrCodeUrl: '',\n  readyState: AccountStatus.UN_CONNECT,\n  accountId: -1,\n  apiKey: '',\n  eddsaKey: '',\n  publicKey: {},\n  level: '',\n  keySeed: '',\n  nonce: undefined,\n  keyNonce: undefined,\n  connectName: ConnectProviders.Unknown,\n}\nexport const coinMap: CoinMap<CoinType, CoinInfo<CoinType>> = {\n  ETH: {\n    icon: 'https://exchange.loopring.io/assets/images/ethereum/assets/0x9A0aBA393aac4dFbFf4333B06c407458002C6183/logo.png',\n    name: 'ETH',\n    simpleName: 'ETH',\n    description: '',\n    company: 'ETH',\n  },\n  LRC: {\n    icon: 'https://exchange.loopring.io/assets/images/ethereum/assets/0x565aBA393aac4dFbFf4333B06c407458002C6183/logo.png',\n    name: 'LRC',\n    simpleName: 'LRC',\n    description: '',\n    company: 'LRC',\n  },\n  USDT: {\n    icon: 'https://exchange.loopring.io/assets/images/ethereum/assets/0x565aBA393aac4dFbFf4333B06c407458002C6183/logo.png',\n    name: 'USDT',\n    simpleName: 'USDT',\n    description: '',\n    company: 'USDT',\n  },\n  USDC: {\n    icon: 'https://exchange.loopring.io/assets/images/ethereum/assets/0x565aBA393aac4dFbFf4333B06c407458002C6183/logo.png',\n    name: 'USDC',\n    simpleName: 'USDC',\n    description: '',\n    company: 'USDC',\n  },\n  LRCA: {\n    icon: 'red',\n    name: 'LRCA',\n    simpleName: 'LRCA',\n    description: '',\n    company: 'LRC',\n  },\n  LRCB: {\n    icon: 'red',\n    name: 'LRCA',\n    simpleName: 'LRCB',\n    description: '',\n    company: 'LRC',\n  },\n  DPR: {\n    icon: 'blue',\n    name: 'DPR',\n    simpleName: 'DPR',\n    description: '',\n    company: 'DPR',\n  },\n  CCB: {\n    icon: 'blue',\n    name: 'CCB',\n    simpleName: 'CCB',\n    description: '',\n    company: 'ETH',\n  },\n  OKB: {\n    icon: 'blue',\n    name: 'OKB',\n    simpleName: 'OKB',\n    description: '',\n    company: 'ETH',\n  },\n  CRV: {\n    icon: 'blue',\n    name: 'CRV',\n    simpleName: 'CRV',\n    description: '',\n    company: 'CRV',\n  },\n  TEST: {\n    icon: 'blue',\n    name: 'TEST',\n    simpleName: 'TEST',\n    description: '',\n    company: 'TEST',\n  },\n  TEST2: {\n    icon: 'blue',\n    name: 'TEST3',\n    simpleName: 'TEST2',\n    description: '',\n    company: 'CRV',\n  },\n  TEST3: {\n    icon: 'blue',\n    name: 'TEST3',\n    simpleName: 'TEST3',\n    description: '',\n    company: 'TEST3',\n  },\n}\nexport const walletMap = {\n  ETH: {\n    belong: 'ETH',\n    count: 11,\n  },\n  LRC: {\n    belong: 'LRC',\n    count: 11111111111111,\n  },\n}\n\nexport enum ButtonComponentsMap {\n  Download,\n  Notification,\n  Theme,\n  Language,\n}\n\nexport const inputProps = {\n  label: 'Enter Payment Token',\n  subLabel: 'Max',\n  emptyText: 'Select Token',\n  placeholderText: '0.00',\n  coinMap: coinMap,\n}\n\nexport const coinType = {\n  ETH: 'ETH',\n  USDT: 'USDT',\n  USDC: 'USDC',\n  LRC: 'LRC',\n  CRV: 'CRV',\n  DPR: 'DPR',\n  CCB: 'CCB',\n  OKB: 'OKB',\n  LRCA: 'LRCA',\n  LRCB: 'LRCB',\n  TEST: 'TEST',\n  TEST2: 'TEST2',\n  TEST3: 'TEST3',\n}\n\nexport const tradeCalcData: TradeCalcData<CoinType> = {\n  isBtrade: false,\n  coinSell: 'ETH', //name\n  coinBuy: 'LRC',\n  BtoS: '1,11',\n  StoB: '1,11',\n  buyPrecision: 5,\n  sellPrecision: 7,\n  coinInfoMap: coinMap,\n  sellCoinInfoMap: coinMap,\n  buyCoinInfoMap: coinMap,\n  walletMap: walletMap as WalletMap<CoinType, WalletCoin<CoinType>>,\n  slippage: 0.5,\n  priceImpact: '12',\n  priceImpactColor: 'var(--color-success)',\n  minimumReceived: '1%',\n  fee: '1%',\n} as any\nexport const ammCalcData: AmmInData<CoinType> = {\n  myCoinA: { belong: 'ETH', balance: 1000, tradeValue: 0 },\n  myCoinB: { belong: 'LRC', balance: 1000, tradeValue: 0 },\n  lpCoinA: { belong: 'ETH', balance: 1000, tradeValue: 0 },\n  lpCoinB: { belong: 'LRC', balance: 122, tradeValue: 0 },\n  lpCoin: { belong: 'ETH', balance: 1000, tradeValue: 0 },\n  AtoB: 50,\n  BtoA: 50,\n  coinInfoMap: coinMap,\n  slippage: 0.5,\n  fee: '0.01',\n  fees: {},\n  percentage: '0.01',\n}\n\nexport const layer2ItemData = List<HeaderMenuItemInterface>([\n  {\n    label: {\n      id: 'lite',\n      i18nKey: 'labelClassic',\n      description: 'Simple and easy-to-user interface',\n    },\n    router: { path: '' },\n  },\n  {\n    label: {\n      id: 'pro',\n      i18nKey: 'labelAdvanced',\n      description: 'Full access to all trading tools',\n    },\n    router: { path: '' },\n  },\n])\nexport const TOKEN_INFO = {\n  tokenMap: {\n    ETH: {\n      type: 'ETH',\n      tokenId: 0,\n      symbol: 'ETH',\n      name: 'Ethereum',\n      address: '0x0000000000000000000000000000000000000000',\n      decimals: 18,\n      precision: 7,\n      precisionForOrder: 3,\n      orderAmounts: {\n        minimum: '5000000000000000',\n        maximum: '1000000000000000000000',\n        dust: '200000000000000',\n      },\n      luckyTokenAmounts: {\n        minimum: '50000000000000',\n        maximum: '1000000000000000000000',\n        dust: '50000000000000',\n      },\n      fastWithdrawLimit: '100000000000000000000',\n      gasAmounts: {\n        distribution: '85000',\n        deposit: '100000',\n      },\n      enabled: true,\n      isLpToken: false,\n      tradePairs: ['LRC', 'USDT', 'USDC'],\n    },\n    LRC: {\n      type: 'erc20Trade',\n      tokenId: 1,\n      symbol: 'LRC',\n      name: 'Loopring',\n      address: '0xfc28028d9b1f6966fe74710653232972f50673be',\n      decimals: 18,\n      precision: 3,\n      precisionForOrder: 3,\n      orderAmounts: {\n        minimum: '5000000000000000000',\n        maximum: '5000000000000000000000000',\n        dust: '5000000000000000000',\n      },\n      luckyTokenAmounts: {\n        minimum: '50000000000000000',\n        maximum: '5000000000000000000000000',\n        dust: '50000000000000000',\n      },\n      fastWithdrawLimit: '750000000000000000000000',\n      gasAmounts: {\n        distribution: '101827',\n        deposit: '200000',\n      },\n      enabled: true,\n      isLpToken: false,\n      tradePairs: ['ETH'],\n    },\n    USDT: {\n      type: 'erc20Trade',\n      tokenId: 2,\n      symbol: 'USDT',\n      name: 'USDT',\n      address: '0xd4e71c4bb48850f5971ce40aa428b09f242d3e8a',\n      decimals: 6,\n      precision: 2,\n      precisionForOrder: 3,\n      orderAmounts: {\n        minimum: '5000000',\n        maximum: '2000000000000',\n        dust: '250000',\n      },\n      luckyTokenAmounts: {\n        minimum: '50000',\n        maximum: '200000000000',\n        dust: '50000',\n      },\n      fastWithdrawLimit: '250000000000',\n      gasAmounts: {\n        distribution: '106233',\n        deposit: '200000',\n      },\n      enabled: true,\n      isLpToken: false,\n      tradePairs: ['ETH', 'DAI'],\n    },\n    'LP-LRC-ETH': {\n      type: 'erc20Trade',\n      tokenId: 4,\n      symbol: 'LP-LRC-ETH',\n      name: 'AMM-LRC-ETH',\n      address: '0xfeb069407df0e1e4b365c10992f1bc16c078e34b',\n      decimals: 8,\n      precision: 6,\n      precisionForOrder: 3,\n      orderAmounts: {\n        minimum: '100000000',\n        maximum: '10000000000000000000',\n        dust: '100000000',\n      },\n      luckyTokenAmounts: {\n        minimum: '100000000',\n        maximum: '10000000000000000000',\n        dust: '100000000',\n      },\n      fastWithdrawLimit: '20000000000',\n      gasAmounts: {\n        distribution: '150000',\n        deposit: '200000',\n      },\n      enabled: true,\n      isLpToken: true,\n    },\n    'LP-ETH-USDT': {\n      type: 'erc20Trade',\n      tokenId: 7,\n      symbol: 'LP-ETH-USDT',\n      name: 'LP-ETH-USDT',\n      address: '0x049a02fa9bc6bd54a2937e67d174cc69a9194f8e',\n      decimals: 8,\n      precision: 6,\n      precisionForOrder: 3,\n      orderAmounts: {\n        minimum: '100000000',\n        maximum: '10000000000000',\n        dust: '100000000',\n      },\n      luckyTokenAmounts: {\n        minimum: '100000000',\n        maximum: '10000000000000',\n        dust: '100000000',\n      },\n      fastWithdrawLimit: '20000000000',\n      gasAmounts: {\n        distribution: '150000',\n        deposit: '200000',\n      },\n      enabled: true,\n      isLpToken: true,\n    },\n    DAI: {\n      type: 'erc20Trade',\n      tokenId: 6,\n      symbol: 'DAI',\n      name: 'dai',\n      address: '0xcd2c81b322a5b530b5fa3432e57da6803b0317f7',\n      decimals: 18,\n      precision: 6,\n      precisionForOrder: 3,\n      orderAmounts: {\n        minimum: '10000000000000000000',\n        maximum: '100000000000000000000000',\n        dust: '10000000000000000',\n      },\n      luckyTokenAmounts: {\n        minimum: '10000000000000000000',\n        maximum: '100000000000000000000000',\n        dust: '10000000000000000000',\n      },\n      fastWithdrawLimit: '10000000000000000000000',\n      gasAmounts: {\n        distribution: '150000',\n        deposit: '200000',\n      },\n      enabled: true,\n      isLpToken: false,\n      tradePairs: ['USDT'],\n    },\n    USDC: {\n      type: 'USDC',\n      tokenId: 8,\n      symbol: 'USDC',\n      name: 'USDC',\n      address: '0x47525e6a5def04c9a56706e93f54cc70c2e8f165',\n      decimals: 6,\n      precision: 6,\n      precisionForOrder: 3,\n      orderAmounts: {\n        minimum: '1000',\n        maximum: '10000000000000000000',\n        dust: '100',\n      },\n      luckyTokenAmounts: {\n        minimum: '1000000',\n        maximum: '10000000000',\n        dust: '1000000',\n      },\n      fastWithdrawLimit: '20000000000000000000',\n      gasAmounts: {\n        distribution: '150000',\n        deposit: '200000',\n      },\n      enabled: true,\n      isLpToken: false,\n      tradePairs: ['ETH'],\n    },\n    'LP-USDC-ETH': {\n      type: 'LP-USDC-ETH',\n      tokenId: 9,\n      symbol: 'LP-USDC-ETH',\n      name: 'LP-USDC-ETH',\n      address: '0xf37cf4ced77b985708d591acc6bfd08586ab3409',\n      decimals: 8,\n      precision: 7,\n      precisionForOrder: 3,\n      orderAmounts: {\n        minimum: '100000',\n        maximum: '1000000000000000000000000000000000000000',\n        dust: '10000',\n      },\n      luckyTokenAmounts: {\n        minimum: '1000000000000000',\n        maximum: '10000000000000000000',\n        dust: '1000000000000000',\n      },\n      fastWithdrawLimit: '20000000000000000000',\n      gasAmounts: {\n        distribution: '150000',\n        deposit: '200000',\n      },\n      enabled: true,\n      isLpToken: true,\n    },\n  },\n  idIndex: {\n    '0': 'ETH',\n    '1': 'LRC',\n    '2': 'USDT',\n    '4': 'LP-LRC-ETH',\n    '6': 'DAI',\n    '7': 'LP-ETH-USDT',\n    '8': 'USDC',\n    '9': 'LP-USDC-ETH',\n  },\n  marketMap: {\n    'LRC-ETH': {\n      baseTokenId: 1,\n      enabled: true,\n      market: 'LRC-ETH',\n      orderbookAggLevels: 5,\n      precisionForPrice: 6,\n      quoteTokenId: 0,\n      status: 3,\n      isSwapEnabled: true,\n      createdAt: 1617967800000,\n    },\n    'ETH-USDT': {\n      baseTokenId: 0,\n      enabled: true,\n      market: 'ETH-USDT',\n      orderbookAggLevels: 3,\n      precisionForPrice: 3,\n      quoteTokenId: 2,\n      status: 3,\n      isSwapEnabled: true,\n      createdAt: 1617972300000,\n    },\n    'DAI-USDT': {\n      baseTokenId: 6,\n      enabled: true,\n      market: 'DAI-USDT',\n      orderbookAggLevels: 2,\n      precisionForPrice: 4,\n      quoteTokenId: 2,\n      status: 3,\n      isSwapEnabled: true,\n      createdAt: 0,\n    },\n    'USDC-ETH': {\n      baseTokenId: 8,\n      enabled: true,\n      market: 'USDC-ETH',\n      orderbookAggLevels: 3,\n      precisionForPrice: 3,\n      quoteTokenId: 0,\n      status: 3,\n      isSwapEnabled: true,\n      createdAt: 1636974420000,\n    },\n  },\n}\n\nexport type CoinType = typeof coinType\nexport const DUALVIEWINFO: DualViewInfo = {\n  apy: '57.49%',\n  settleRatio: '0.1656',\n  term: 'a day',\n  productId: 'LRC-USDT-220907-0.36-P-USDT',\n  expireTime: 1662537600000,\n  currentPrice: {\n    quote: 'USDC',\n    base: 'LRC',\n    precisionForPrice: 3,\n    currentPrice: 0.4482078,\n    quoteUnit: 'USD',\n  },\n  __raw__: {\n    info: {\n      baseSize: '111',\n      productId: 'LRC-USDT-220907-0.36-P-USDT',\n      base: 'LRC',\n      quote: 'USDT',\n      currency: 'USDT',\n      createTime: 1662336421000,\n      expireTime: 1662537600000,\n      strike: '0.36',\n      expired: false,\n      dualType: 'DUAL_CURRENCY' as DUAL_TYPE,\n      ratio: 0.46,\n      profit: '',\n    },\n    index: {\n      index: '0.36206575',\n      base: 'LRC',\n      quote: 'USDT',\n      indexTime: 1662446738246,\n    },\n    rule: {\n      base: 'LRC',\n      quote: 'USDT',\n      currency: 'USDT',\n      basePrecision: 8,\n      currencyPrecision: 8,\n      baseMin: '20',\n      currencyMin: '50',\n      baseMax: '200000',\n      currencyMax: '200000',\n      granulation: 10,\n      baseProfitStep: 4,\n    },\n  },\n  strike: '0.36',\n  isUp: false,\n  sellSymbol: 'USDC',\n  buySymbol: 'LRC',\n}\nexport const DUALCALCDATA: DualCalcData<DualViewInfo> = {\n  balance: {},\n  coinSell: {\n    balance: 100,\n    belong: 'USDC',\n    tradeValue: undefined,\n  },\n  quota: '1000',\n  feeTokenSymbol: 'LRC',\n  feeVol: undefined,\n  greaterEarnTokenSymbol: '',\n  greaterEarnVol: '',\n  lessEarnTokenSymbol: '',\n  lessEarnVol: '',\n  maxFeeBips: 0,\n  maxSellAmount: '',\n  miniSellVol: '',\n  sellToken: TOKEN_INFO.tokenMap['USDC'],\n  sellVol: '',\n  dualViewInfo: DUALVIEWINFO,\n}\n\nexport const FOREXMAP: ForexMap<Currency> = {\n  [Currency.usd]: 1,\n  [Currency.cny]: 6.7,\n} as any\nexport const REDPACKETMOCK: LuckyTokenItemForReceive = {\n  hash: '',\n  sender: {\n    accountId: 10008,\n    address: '0xxxxxxxx',\n    ens: '',\n  },\n  champion: {\n    accountId: 10008,\n    address: '0xxxxxxxx',\n    ens: '',\n    amount: 100000,\n  },\n  tokenId: 1,\n  tokenAmount: {\n    totalCount: 10,\n    remainCount: 0,\n    totalAmount: '100000000000000000',\n    remainAmount: '0',\n  } as any,\n  type: {\n    partition: 0,\n    scope: 0,\n    mode: 0,\n  },\n  //@ts-ignore\n  status: 'RANDOM',\n  validSince: 1662669827,\n  validUntil: 1662769827,\n  info: {\n    memo: 'Best wishes Best wishes Best  wishes wishes Best wishes Best wishes Best wishes Best wishes Best wishes',\n    signer: '',\n    signerUrl: '',\n    logoUrl: '',\n  },\n  templateNo: 0,\n  createdAt: 1662769827,\n}\nexport const LUCKTOKENLIST = [\n  {\n    id: 117080,\n    hash: '0x2635dc5a575d8b2972bfa60db73667b0eb236ec1314885f5a0b42e15165ca806',\n    sender: {\n      accountId: 41441,\n      address: '0x85992e1fc5f0f1a6edb6f4dac3a072fb0426b6c5',\n      ens: '',\n    },\n    champion: {\n      accountId: 83208,\n      address: '0x8bc49232d786cbaddc699b0e57783ccda913aeea',\n      ens: '',\n      amount: '121163022576739548',\n    },\n    tokenId: 1,\n    tokenAmount: {\n      totalCount: 2,\n      remainCount: 0,\n      totalAmount: '220000000000000000',\n      remainAmount: '0',\n    },\n    type: {\n      partition: 0,\n      scope: 0,\n      mode: 1,\n    },\n    status: 'COMPLETED',\n    validSince: 1672331822000,\n    validUntil: 1672418222000,\n    info: {\n      memo: '10LRC to carl.loopring.eth > 2 part nft collection',\n      signer: '',\n      signerUrl: '',\n      logoUrl: '',\n    },\n    templateNo: 0,\n    createdAt: 1672245500416,\n    isNft: false,\n  },\n  {\n    id: 117076,\n    hash: '0x2f5c482b0711f5204491fe31ee927f0dde79906e2261a8e46106dd309ad0100f',\n    sender: {\n      accountId: 41441,\n      address: '0x85992e1fc5f0f1a6edb6f4dac3a072fb0426b6c5',\n      ens: '',\n    },\n    champion: {\n      accountId: 66702,\n      address: '0x4a860d9764882ca402d380964f81438c407765fd',\n      ens: '',\n      amount: '137774109408598431',\n    },\n    tokenId: 1,\n    tokenAmount: {\n      totalCount: 2,\n      remainCount: 0,\n      totalAmount: '220000000000000000',\n      remainAmount: '0',\n    },\n    type: {\n      partition: 0,\n      scope: 0,\n      mode: 1,\n    },\n    status: 'COMPLETED',\n    validSince: 1672231875000,\n    validUntil: 1672318275000,\n    info: {\n      memo: '10LRC to carl.loopring.eth > 2 part nft collection',\n      signer: '',\n      signerUrl: '',\n      logoUrl: '',\n    },\n    templateNo: 0,\n    createdAt: 1672145547112,\n    isNft: false,\n  },\n]\n\nexport const mockReturn: { order: BanxaOrder } = {\n  order: {\n    id: 'dd734aec66eb781ecc7f7bb01274ec63',\n    account_id: '324a77f69fc5797c2afbe67efefddbba',\n    account_reference: '0xff7d59d9316eba168837e3ef924bcdfd64b237d8',\n    order_type: 'CRYPTO-SELL',\n    payment_type: null,\n    ref: null,\n    fiat_code: 'AUD',\n    fiat_amount: 0,\n    coin_code: 'USDC',\n    coin_amount: 0,\n    wallet_address: null,\n    wallet_address_tag: null,\n    fee: null,\n    fee_tax: null,\n    payment_fee: null,\n    payment_fee_tax: null,\n    commission: null,\n    tx_hash: null,\n    tx_confirms: 0,\n    created_date: '30-Nov-2022',\n    created_at: '30-Nov-2022 17:48:25',\n    status: 'pendingPayment',\n    completed_at: null,\n    merchant_fee: null,\n    merchant_commission: null,\n    meta_data: null,\n    blockchain: { id: 30, code: 'LRC', description: 'Loopring ' },\n  },\n}\n"
  },
  {
    "path": "packages/component-lib/src/stores/index.ts",
    "content": "export * from './reducer/settings'\nexport * from './reducer/modals'\nexport * from './reducer/toggle'\n"
  },
  {
    "path": "packages/component-lib/src/stores/reducer/modals/hook.ts",
    "content": "import { useDispatch, useSelector } from 'react-redux'\nimport { ModalState, ModalStatePlayLoad, Transaction } from './interface'\nimport {\n  setNFTMetaNotReady,\n  setShowAccount,\n  setShowActiveAccount,\n  setShowAmm,\n  setShowAnotherNetworkNotice,\n  setShowClaimWithdraw,\n  setShowCollectionAdvance,\n  setShowConnect,\n  setShowDeposit,\n  setShowDual,\n  setShowExportAccount,\n  setShowFeeSetting,\n  setShowGlobalToast,\n  setShowIFrame,\n  setShowLayerSwapNotice,\n  setShowNFTDeploy,\n  setShowNFTDeposit,\n  setShowNFTDetail,\n  setShowNFTMintAdvance,\n  setShowNFTTransfer,\n  setShowNFTWithdraw,\n  setShowOtherExchange,\n  setShowRedPacket,\n  setShowResetAccount,\n  setShowSideStakingRedeem,\n  setShowSupport,\n  setShowSwap,\n  setShowTargetRedpacketPop,\n  setShowTradeIsFrozen,\n  setShowTransfer,\n  setShowWithdraw,\n  setShowWrongNetworkGuide,\n  setShowEditContact,\n  setShowVaultJoin,\n  setShowVaultExit,\n  setShowVaultSwap,\n  setShowVaultLoan,\n  setShowNoVaultAccount,\n  setShowConfirmedVault,\n  setShowETHStakingApr,\n  setShowTransferToTaikoAccount,\n  setShowVaultCloseConfirm,\n  setShowBridge,\n  setShowClosureAnnouncement,\n} from './reducer'\n\nimport React from 'react'\nimport {\n  CLAIM_TYPE,\n  ClaimToken,\n  DualViewInfo,\n  NFTWholeINFO,\n  TradeNFT,\n  AmmPanelType,\n  CoinSource,\n  Contact,\n  VaultAction,\n} from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { ToggleState } from '../toggle'\nimport { ToastType } from '../../../components'\n\nexport const useOpenModals = () => {\n  const dispatch = useDispatch()\n  const toggle = useSelector((state: any) => state.toggle) as ToggleState\n  return {\n    modals: useSelector((state: any) => state.modals) as ModalState,\n    setShowRedPacket: React.useCallback(\n      (\n        state: ModalStatePlayLoad & {\n          step?: number\n          info?: { [key: string]: any }\n        },\n      ) => dispatch(setShowRedPacket(state)),\n      [dispatch],\n    ),\n    setNFTMetaNotReady: React.useCallback(\n      (\n        state: ModalStatePlayLoad & {\n          step?: number\n          info?: { [key: string]: any }\n        },\n      ) => dispatch(setNFTMetaNotReady(state)),\n      [dispatch],\n    ),\n    setShowSupport: React.useCallback(\n      (state: ModalStatePlayLoad & Transaction) => dispatch(setShowSupport(state)),\n      [dispatch],\n    ),\n    setShowOtherExchange: React.useCallback(\n      (\n        state: ModalStatePlayLoad & {\n          agree?: boolean\n        } & Transaction,\n      ) => dispatch(setShowOtherExchange(state)),\n      [dispatch],\n    ),\n    setShowWrongNetworkGuide: React.useCallback(\n      (state: ModalStatePlayLoad & Transaction) => dispatch(setShowWrongNetworkGuide(state)),\n      [dispatch],\n    ),\n\n    setShowTransfer: React.useCallback(\n      (state: ModalStatePlayLoad & Transaction & Contact) => {\n        if (!toggle.transfer.enable && state.isShow) {\n          dispatch(setShowTradeIsFrozen({ isShow: true, type: 'Transfer' }))\n          return\n        }\n        dispatch(setShowTransfer(state))\n      },\n      [dispatch, toggle.transfer.enable],\n    ),\n    setShowTransferToTaikoAccount: React.useCallback(\n      (state: ModalStatePlayLoad & { from?: string }) => {\n        if (toggle.transferToTaikoAccount.enable) {\n          dispatch(setShowTransferToTaikoAccount(state))\n        } else {\n          dispatch(setShowTradeIsFrozen({ isShow: true, type: 'TransferToTaikoAccount' }))\n        }\n      },\n      [dispatch, toggle.transferToTaikoAccount.enable],\n    ),\n    setShowNFTDeploy: React.useCallback(\n      (state: ModalStatePlayLoad & Transaction) => {\n        dispatch(setShowNFTDeploy(state))\n      },\n      [dispatch],\n    ),\n    setShowDeposit: React.useCallback(\n      (state: ModalStatePlayLoad & Transaction & { partner?: boolean }) => {\n        if (!toggle.deposit.enable && state.isShow) {\n          dispatch(setShowTradeIsFrozen({ isShow: true, type: 'Deposit' }))\n          return \n        }\n        dispatch(setShowDeposit(state))\n      },\n      [dispatch, toggle.deposit.enable],\n    ),\n    setShowWithdraw: React.useCallback(\n      (state: ModalStatePlayLoad & Transaction & Contact) => {\n        if (!toggle.withdraw.enable && state.isShow) {\n          dispatch(setShowTradeIsFrozen({ isShow: true, type: 'Withdraw' }))\n          return\n        } \n        dispatch(setShowWithdraw(state))\n      },\n      [dispatch, toggle.withdraw.enable],\n    ),\n    setShowNFTDetail: React.useCallback(\n      (state: ModalStatePlayLoad & Partial<NFTWholeINFO>) => {\n        dispatch(setShowNFTDetail(state))\n      },\n      [dispatch],\n    ),\n    setShowNFTTransfer: React.useCallback(\n      (state: ModalStatePlayLoad & Partial<NFTWholeINFO>) => {\n        if (toggle.transferNFT.enable) {\n          dispatch(setShowNFTTransfer(state))\n        } else {\n          dispatch(setShowTradeIsFrozen({ isShow: true, type: 'Transfer' }))\n        }\n      },\n      [dispatch, toggle.transferNFT.enable],\n    ),\n    setShowNFTDeposit: React.useCallback(\n      (state: ModalStatePlayLoad & Partial<TradeNFT<any, any>>) => {\n        if (toggle.depositNFT.enable) {\n          dispatch(setShowNFTDeposit(state))\n        } else {\n          dispatch(setShowTradeIsFrozen({ isShow: true, type: 'Deposit' }))\n        }\n      },\n      [dispatch, toggle.depositNFT.enable],\n    ),\n    setShowCollectionAdvance: React.useCallback(\n      (state: ModalStatePlayLoad & Partial<TradeNFT<any, any>>) => {\n        if (toggle.collectionNFT.enable) {\n          dispatch(setShowCollectionAdvance(state))\n        } else {\n          dispatch(setShowCollectionAdvance({ isShow: true, type: 'Collection' }))\n        }\n      },\n      [dispatch, toggle.collectionNFT.enable],\n    ),\n    setShowNFTMintAdvance: React.useCallback(\n      (state: ModalStatePlayLoad & Partial<TradeNFT<any, any>>) => {\n        if (toggle.mintNFT.enable) {\n          dispatch(setShowNFTMintAdvance(state))\n        } else {\n          dispatch(setShowTradeIsFrozen({ isShow: true, type: 'Mint' }))\n        }\n      },\n      [dispatch, toggle.mintNFT.enable],\n    ),\n    setShowNFTWithdraw: React.useCallback(\n      (state: ModalStatePlayLoad & Partial<NFTWholeINFO>) => {\n        if (toggle.withdrawNFT.enable) {\n          dispatch(setShowNFTWithdraw(state))\n        } else {\n          dispatch(setShowTradeIsFrozen({ isShow: true, type: 'Withdraw' }))\n        }\n      },\n      [dispatch, toggle.withdrawNFT.enable],\n    ),\n\n    setShowResetAccount: React.useCallback(\n      (state: ModalStatePlayLoad) => {\n        if (!toggle.updateAccount.enable && state.isShow) {\n          dispatch(setShowTradeIsFrozen({ isShow: true, type: 'reset-account' }))\n          return\n        } \n        dispatch(setShowResetAccount(state))\n      },\n      [dispatch, toggle.updateAccount.enable],\n    ),\n    setShowActiveAccount: React.useCallback(\n      (state: ModalStatePlayLoad) => {\n        if (toggle.updateAccount.enable) {\n          dispatch(setShowActiveAccount(state))\n        } else {\n          dispatch(setShowTradeIsFrozen({ isShow: true, type: 'active-account' }))\n        }\n      },\n      [dispatch, toggle.updateAccount.enable],\n    ),\n    setShowAmm: React.useCallback(\n      (state: ModalStatePlayLoad & Transaction & { type?: AmmPanelType }) =>\n        dispatch(setShowAmm(state)),\n      [dispatch],\n    ),\n    setShowSwap: React.useCallback(\n      (state: ModalStatePlayLoad) => dispatch(setShowSwap(state)),\n      [dispatch],\n    ),\n    setShowAccount: React.useCallback(\n      (\n        state: ModalStatePlayLoad & {\n          step?: number\n          error?: sdk.RESULT_INFO\n          info?: { [key: string]: any }\n        },\n      ) => dispatch(setShowAccount(state)),\n      [dispatch],\n    ),\n    setShowDual: React.useCallback(\n      (state: ModalStatePlayLoad & { dualInfo: DualViewInfo | undefined }) =>\n        dispatch(setShowDual(state)),\n      [dispatch],\n    ),\n    setShowClaimWithdraw: React.useCallback(\n      (\n        state: ModalStatePlayLoad & {\n          claimToken?: ClaimToken\n          claimType?: CLAIM_TYPE\n        },\n      ) => {\n        if (toggle.claim.enable) {\n          dispatch(setShowClaimWithdraw(state))\n        } else {\n          dispatch(setShowTradeIsFrozen({ isShow: true, type: 'Claim' }))\n        }\n      },\n      [dispatch, toggle.claim.enable],\n    ),\n    setShowConnect: React.useCallback(\n      (\n        state: ModalStatePlayLoad & {\n          step?: number\n          error?: sdk.RESULT_INFO\n          info?: { [key: string]: any }\n        },\n      ) => dispatch(setShowConnect(state)),\n      [dispatch],\n    ),\n    setShowIFrame: React.useCallback(\n      (state: ModalStatePlayLoad & { url: string }) => dispatch(setShowIFrame(state)),\n      [dispatch],\n    ),\n    setShowExportAccount: React.useCallback(\n      (state: ModalStatePlayLoad) => dispatch(setShowExportAccount(state)),\n      [dispatch],\n    ),\n    setShowFeeSetting: React.useCallback(\n      (state: ModalStatePlayLoad) => dispatch(setShowFeeSetting(state)),\n      [dispatch],\n    ),\n    setShowLayerSwapNotice: React.useCallback(\n      (state: ModalStatePlayLoad) => dispatch(setShowLayerSwapNotice(state)),\n      [dispatch],\n    ),\n    setShowAnotherNetworkNotice: React.useCallback(\n      (state: ModalStatePlayLoad) => dispatch(setShowAnotherNetworkNotice(state)),\n      [dispatch],\n    ),\n    setShowTradeIsFrozen: React.useCallback(\n      (state: ModalStatePlayLoad & { type?: string; messageKey?: string }) =>\n        dispatch(setShowTradeIsFrozen(state)),\n      [dispatch],\n    ),\n    setShowSideStakingRedeem: React.useCallback(\n      (state: ModalStatePlayLoad & { symbol?: string }) =>\n        dispatch(setShowSideStakingRedeem(state)),\n      [dispatch],\n    ),\n    setShowGlobalToast: React.useCallback(\n      (state: {\n        isShow: boolean\n        info: {\n          content?: string\n          type: ToastType\n          messageKey?: string\n        }\n      }) => dispatch(setShowGlobalToast(state)),\n      [dispatch],\n    ),\n    setShowTargetRedpacketPop: React.useCallback(\n      (state: {\n        isShow: boolean\n        info: {\n          exclusiveRedPackets?: (sdk.LuckyTokenItemForReceive & {\n            tokenIcon: CoinSource\n            tokenName: string\n          })[]\n        }\n      }) => dispatch(setShowTargetRedpacketPop(state)),\n      [dispatch],\n    ),\n    setShowEditContact: React.useCallback(\n      (state: { isShow: boolean; info?: any }) => dispatch(setShowEditContact(state)),\n      [dispatch],\n    ),\n    setShowETHStakingApr: React.useCallback(\n      (state: ModalStatePlayLoad & Transaction) => dispatch(setShowETHStakingApr(state)),\n      [dispatch],\n    ),\n    setShowVaultExit: React.useCallback(\n      (state: ModalStatePlayLoad & Transaction) => dispatch(setShowVaultExit(state)),\n      [dispatch],\n    ),\n    setShowVaultJoin: React.useCallback(\n      (state: ModalStatePlayLoad & Transaction) => dispatch(setShowVaultJoin(state)),\n      [dispatch],\n    ),\n    setShowVaultSwap: React.useCallback(\n      (state: ModalStatePlayLoad & Transaction & {isSell?: boolean}) => dispatch(setShowVaultSwap(state)),\n      [dispatch],\n    ),\n    setShowVaultLoan: React.useCallback(\n      (state: ModalStatePlayLoad & Transaction & { type?: string }) =>\n        dispatch(setShowVaultLoan(state)),\n      [dispatch],\n    ),\n    setShowVaultCloseConfirm: React.useCallback(\n      (state: ModalStatePlayLoad & Transaction ) =>\n        dispatch(setShowVaultCloseConfirm(state)),\n      [dispatch],\n    ),\n    setShowNoVaultAccount: React.useCallback(\n      (\n        state: ModalStatePlayLoad &\n          Transaction & { whichBtn?: VaultAction | undefined; des?: string; title?: string },\n      ) => dispatch(setShowNoVaultAccount(state)),\n      [dispatch],\n    ),\n    setShowConfirmedVault: React.useCallback(\n      (state: ModalStatePlayLoad) => dispatch(setShowConfirmedVault(state)),\n      [dispatch],\n    ),\n    setShowBridge: React.useCallback(\n      (state: ModalStatePlayLoad) => dispatch(setShowBridge(state)),\n      [dispatch],\n    ),\n    setShowClosureAnnouncement: React.useCallback(\n      (state: ModalStatePlayLoad) => dispatch(setShowClosureAnnouncement(state)),\n      [dispatch],\n    ),\n  }\n}\n"
  },
  {
    "path": "packages/component-lib/src/stores/reducer/modals/index.ts",
    "content": "export * from './hook'\nexport * from './interface'\nexport * from './reducer'\n"
  },
  {
    "path": "packages/component-lib/src/stores/reducer/modals/interface.ts",
    "content": "import {\n  CLAIM_TYPE,\n  ClaimToken,\n  DualViewInfo,\n  NFTWholeINFO,\n  TradeNFT,\n  AmmPanelType,\n  VaultAction,\n  CoinSource,\n  ToastType,\n  Contact,\n} from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nexport enum ModalType {\n  transfer = 'transfer',\n  deposit = 'deposit',\n  withdraw = 'withdraw',\n}\n\nexport type ModalTypeKeys = keyof typeof ModalType\n\nexport type ModalStatePlayLoad = {\n  isShow: boolean\n  info?: { [key: string]: any }\n}\nexport type Transaction = {\n  symbol?: undefined | string\n}\n\nexport interface ModalState {\n  isShowSupport: ModalStatePlayLoad\n  isShowNFTMetaNotReady: ModalStatePlayLoad\n  isShowOtherExchange: ModalStatePlayLoad & {\n    agree?: boolean\n  }\n  isWrongNetworkGuide: ModalStatePlayLoad\n  isShowClaimWithdraw: ModalStatePlayLoad & {\n    claimToken: ClaimToken | undefined\n    claimType: CLAIM_TYPE | undefined\n  }\n  isShowTransfer: ModalStatePlayLoad & Transaction & Contact\n  isShowWithdraw: ModalStatePlayLoad & Transaction & Contact\n  isShowDeposit: ModalStatePlayLoad & Transaction & { partner?: boolean }\n  isShowNFTDetail: ModalStatePlayLoad & Partial<NFTWholeINFO>\n  isShowNFTTransfer: ModalStatePlayLoad & Partial<TradeNFT<any, any>> & Contact\n  isShowNFTWithdraw: ModalStatePlayLoad & Partial<TradeNFT<any, any>> & Contact\n  isShowNFTDeploy: ModalStatePlayLoad & Partial<TradeNFT<any, any>>\n  isShowNFTDeposit: ModalStatePlayLoad & Partial<TradeNFT<any, any>>\n  isShowNFTMintAdvance: ModalStatePlayLoad & Partial<TradeNFT<any, any>>\n  isShowCollectionAdvance: ModalStatePlayLoad\n  isShowDual: ModalStatePlayLoad & { dualInfo: DualViewInfo | undefined }\n  isShowResetAccount: ModalStatePlayLoad\n  isShowActiveAccount: ModalStatePlayLoad\n  isShowExportAccount: ModalStatePlayLoad\n  isShowLayerSwapNotice: ModalStatePlayLoad\n  isShowAnotherNetwork: ModalStatePlayLoad\n  isShowSwap: ModalStatePlayLoad\n  isShowAmm: ModalStatePlayLoad & Transaction & { type?: AmmPanelType }\n  isShowTradeIsFrozen: ModalStatePlayLoad & {\n    type?: string\n    messageKey?: string\n  }\n  isShowConnect: ModalStatePlayLoad & {\n    step: number\n    error?: sdk.RESULT_INFO\n    info?: { [key: string]: any }\n  }\n  isShowEditContact: ModalStatePlayLoad & {\n    error?: sdk.RESULT_INFO\n    info?: { [key: string]: any }\n  }\n  isShowAccount: ModalStatePlayLoad & {\n    step: number\n    error?: sdk.RESULT_INFO\n    // info?: { [key: string]: any };\n  }\n  isShowRedPacket: ModalStatePlayLoad & {\n    step: number\n    // info?: { [key: string]: any };\n  }\n  isShowFeeSetting: ModalStatePlayLoad\n  isShowIFrame: ModalStatePlayLoad & { url: string }\n  isShowSideStakingRedeem: ModalStatePlayLoad & { symbol?: string }\n  isShowGlobalToast: {\n    isShow: boolean\n    info: {\n      id?: string\n      messageKey?: string\n      content?: string\n      type: ToastType\n    } & any\n  }\n  isShowTargetRedpacketPop: {\n    isShow: boolean\n    info: {\n      exclusiveRedPackets?: (sdk.LuckyTokenItemForReceive & {\n        tokenIcon: CoinSource\n        tokenName: string\n      })[]\n    }\n  }\n  isShowETHStakingApr: ModalStatePlayLoad & { symbol?: string }\n  isShowVaultExit: ModalStatePlayLoad & Transaction\n  isShowVaultJoin: ModalStatePlayLoad & Transaction\n  isShowVaultSwap: ModalStatePlayLoad & Transaction & {isSell?: boolean}\n  isShowVaultLoan: ModalStatePlayLoad &\n    Transaction & {\n      type: string\n    }\n  isShowVaultCloseConfirm: ModalStatePlayLoad & Transaction \n  isShowNoVaultAccount: ModalStatePlayLoad & { whichBtn: VaultAction | undefined; des?: string }\n  isShowConfirmedVault: ModalStatePlayLoad\n  isShowTransferToTaikoAccount: ModalStatePlayLoad & { from?: string }\n  isShowBridge: ModalStatePlayLoad & Partial<Transaction>\n  isShowClosureAnnouncement: ModalStatePlayLoad\n}\n"
  },
  {
    "path": "packages/component-lib/src/stores/reducer/modals/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { ModalState, ModalStatePlayLoad, Transaction } from './interface'\nimport {\n  CLAIM_TYPE,\n  ClaimToken,\n  DualViewInfo,\n  NFTWholeINFO,\n  TradeNFT,\n  AmmPanelType,\n  VaultLoanType,\n  VaultAction,\n  CoinSource,\n  Contact,\n  ToastType,\n} from '@loopring-web/common-resources'\nimport { RESULT_INFO, LuckyTokenItemForReceive } from '@loopring-web/loopring-sdk'\n\nconst initialState: ModalState = {\n  isShowGlobalToast: {\n    isShow: false,\n    info: {\n      content: '',\n      type: ToastType.info,\n    },\n  },\n  isShowNFTMetaNotReady: { isShow: false },\n  isShowRedPacket: { isShow: false, step: 0 },\n  isShowSupport: { isShow: false },\n  isShowOtherExchange: { isShow: false },\n  isWrongNetworkGuide: { isShow: false },\n  isShowTransfer: { isShow: false, symbol: undefined },\n  isShowWithdraw: { isShow: false, symbol: undefined },\n  isShowDeposit: { isShow: false, symbol: undefined },\n  isShowResetAccount: { isShow: false },\n  isShowActiveAccount: { isShow: false },\n  isShowExportAccount: { isShow: false },\n  isShowSwap: { isShow: false },\n  isShowAmm: { isShow: false, type: AmmPanelType.Join },\n  isShowConnect: { isShow: false, step: 0 },\n  isShowAccount: { isShow: false, step: 0 },\n  isShowLayerSwapNotice: { isShow: false },\n  isShowAnotherNetwork: { isShow: false },\n  isShowFeeSetting: { isShow: false },\n  isShowTradeIsFrozen: { isShow: false, type: '' },\n  isShowIFrame: { isShow: false, url: '' },\n  isShowNFTTransfer: { isShow: false },\n  isShowNFTWithdraw: { isShow: false },\n  isShowNFTDeposit: { isShow: false },\n  isShowNFTMintAdvance: { isShow: false },\n  isShowDual: { isShow: false, dualInfo: undefined },\n  isShowCollectionAdvance: { isShow: false },\n  isShowNFTDeploy: { isShow: false },\n  isShowNFTDetail: { isShow: false },\n  isShowEditContact: { isShow: false },\n  isShowClaimWithdraw: {\n    isShow: false,\n    claimToken: undefined,\n    claimType: undefined,\n  },\n  isShowSideStakingRedeem: { isShow: false, symbol: undefined },\n  isShowTargetRedpacketPop: { isShow: false, info: {} },\n  isShowETHStakingApr: { isShow: false, symbol: undefined },\n  isShowVaultExit: { isShow: false },\n  isShowVaultJoin: { isShow: false },\n  isShowVaultSwap: { isShow: false, isSell: undefined },\n  isShowVaultLoan: { isShow: false, type: VaultLoanType.Borrow, symbol: undefined },\n  isShowVaultCloseConfirm: { isShow: false, symbol: undefined },\n  isShowNoVaultAccount: { isShow: false, whichBtn: undefined },\n  isShowConfirmedVault: { isShow: false },\n  isShowTransferToTaikoAccount: { isShow: false, from: undefined },\n  isShowBridge: { isShow: false, symbol: undefined, info: undefined },\n  isShowClosureAnnouncement: { isShow: false },\n}\n\nexport const modalsSlice: Slice<ModalState> = createSlice({\n  name: 'modals',\n  initialState,\n  reducers: {\n    setShowGlobalToast(\n      state,\n      action: PayloadAction<{\n        isShow: boolean\n        info: {\n          content: string\n          messageKey: string\n          type: ToastType\n        }\n      }>,\n    ) {\n      const { isShow, info } = action.payload\n      state.isShowGlobalToast = {\n        isShow,\n        info,\n      }\n    },\n    setNFTMetaNotReady(\n      state,\n      action: PayloadAction<{\n        isShow: boolean\n        step?: number\n        info?: { [key: string]: any }\n      }>,\n    ) {\n      const { isShow, info } = action.payload\n      state.isShowNFTMetaNotReady = {\n        isShow,\n        info,\n      }\n    },\n    setShowRedPacket(\n      state,\n      action: PayloadAction<{\n        isShow: boolean\n        step?: number\n        info?: { [key: string]: any }\n      }>,\n    ) {\n      const { isShow, step, info } = action.payload\n      state.isShowRedPacket = {\n        isShow,\n        step: step ? step : 0,\n        info,\n      }\n    },\n    setShowIFrame(state, action: PayloadAction<{ isShow: boolean; url: string }>) {\n      const { isShow, url } = action.payload\n      state.isShowIFrame = {\n        isShow,\n        url,\n      }\n    },\n    setShowSupport(state, action: PayloadAction<ModalStatePlayLoad>) {\n      const { isShow } = action.payload\n      state.isShowSupport.isShow = isShow\n    },\n    setShowOtherExchange(\n      state,\n      action: PayloadAction<\n        ModalStatePlayLoad & {\n          agree?: boolean\n        }\n      >,\n    ) {\n      const { isShow, agree, ...rest } = action.payload\n      state.isShowOtherExchange = {\n        isShow,\n        agree: isShow ? false : agree,\n        ...rest,\n      }\n    },\n    setShowWrongNetworkGuide(state, action: PayloadAction<ModalStatePlayLoad>) {\n      const { isShow } = action.payload\n      state.isWrongNetworkGuide.isShow = isShow\n    },\n    setShowAmm(\n      state,\n      action: PayloadAction<ModalStatePlayLoad & Transaction & { type: AmmPanelType }>,\n    ) {\n      const { isShow, symbol, info, type } = action.payload\n      state.isShowAmm = {\n        isShow,\n        symbol,\n        info,\n        type,\n      }\n    },\n    setShowSwap(state, action: PayloadAction<ModalStatePlayLoad>) {\n      const { isShow } = action.payload\n      state.isShowSwap.isShow = isShow\n    },\n    setShowNFTDetail(state, action: PayloadAction<ModalStatePlayLoad & Partial<NFTWholeINFO>>) {\n      const { isShow, ...rest } = action.payload\n      state.isShowNFTDetail = {\n        isShow,\n\n        ...rest,\n      }\n    },\n    setShowNFTTransfer(state, action: PayloadAction<ModalStatePlayLoad & NFTWholeINFO>) {\n      const { isShow, nftData, nftType, total, locked, info, ...rest } = action.payload\n      state.isShowNFTTransfer = {\n        isShow,\n        nftData,\n        nftType,\n        info,\n        ...rest,\n        balance: total ? Number(total) - Number(locked ?? 0) : 0,\n      }\n    },\n    setShowNFTDeploy(state, action: PayloadAction<ModalStatePlayLoad & NFTWholeINFO>) {\n      const { isShow, nftData, nftType, total, locked, info, ...rest } = action.payload\n      state.isShowNFTDeploy = {\n        isShow,\n        nftData,\n        nftType,\n        info,\n        ...rest,\n        balance: total ? Number(total) - Number(locked ?? 0) : 0,\n      }\n    },\n\n    setShowNFTDeposit(state, action: PayloadAction<ModalStatePlayLoad & TradeNFT<any, any>>) {\n      const { isShow, nftData, nftType, ...rest } = action.payload\n      state.isShowNFTDeposit = {\n        isShow,\n        nftType,\n        ...rest,\n      }\n    },\n    setShowCollectionAdvance(state, action: PayloadAction<ModalStatePlayLoad & any>) {\n      const { isShow, info } = action.payload\n      state.isShowCollectionAdvance = {\n        isShow,\n        info,\n      }\n    },\n    setShowNFTMintAdvance(state, action: PayloadAction<ModalStatePlayLoad & TradeNFT<any, any>>) {\n      const { isShow, nftData, nftType, ...rest } = action.payload\n      state.isShowNFTMintAdvance = {\n        isShow,\n        nftData,\n        nftType,\n        ...rest,\n      }\n    },\n    setShowNFTWithdraw(state, action: PayloadAction<ModalStatePlayLoad & NFTWholeINFO>) {\n      const { isShow, nftData, nftType, total, locked, info, ...rest } = action.payload\n      state.isShowNFTWithdraw = {\n        isShow,\n        nftData,\n        nftType,\n        info,\n        ...rest,\n        balance: total ? Number(total) - Number(locked ?? 0) : 0,\n      }\n    },\n    setShowTransfer(state, action: PayloadAction<ModalStatePlayLoad & Transaction & Contact>) {\n      const { isShow, symbol, info, name, address, addressType } = action.payload\n      state.isShowTransfer = {\n        isShow,\n        symbol,\n        info,\n        name,\n        address,\n        addressType,\n      }\n    },\n    setShowTransferToTaikoAccount(state, action: PayloadAction<ModalStatePlayLoad & { from?: string }>) {\n      const { isShow, info, from } = action.payload\n      state.isShowTransferToTaikoAccount = {\n        isShow,\n        info,\n        from\n      }\n    },\n    setShowWithdraw(state, action: PayloadAction<ModalStatePlayLoad & Transaction & Contact>) {\n      const { isShow, symbol, info, name, address, addressType } = action.payload\n      state.isShowWithdraw = {\n        isShow,\n        symbol,\n        info,\n        name,\n        address,\n        addressType,\n      }\n    },\n    setShowDeposit(\n      state,\n      action: PayloadAction<ModalStatePlayLoad & Transaction & { partner: boolean }>,\n    ) {\n      const { isShow, symbol, partner } = action.payload\n      state.isShowDeposit = {\n        isShow,\n        symbol,\n        partner,\n      }\n    },\n    setShowResetAccount(state, action: PayloadAction<ModalStatePlayLoad>) {\n      const { isShow, info } = action.payload\n      state.isShowResetAccount.isShow = isShow\n      state.isShowResetAccount.info = info\n    },\n    setShowActiveAccount(state, action: PayloadAction<ModalStatePlayLoad>) {\n      const { isShow, info } = action.payload\n      state.isShowActiveAccount.isShow = isShow\n      state.isShowActiveAccount.info = info\n    },\n    setShowExportAccount(state, action: PayloadAction<ModalStatePlayLoad>) {\n      const { isShow } = action.payload\n      state.isShowExportAccount.isShow = isShow\n    },\n    setShowDual(\n      state,\n      action: PayloadAction<ModalStatePlayLoad & { dualInfo: DualViewInfo | undefined }>,\n    ) {\n      const { isShow, dualInfo } = action.payload\n      if (dualInfo) {\n        state.isShowDual = {\n          isShow,\n          dualInfo,\n        }\n      } else {\n        state.isShowDual.isShow = false\n        state.isShowDual.dualInfo = undefined\n      }\n    },\n    setShowConnect(\n      state,\n      action: PayloadAction<{\n        isShow: boolean\n        step?: number\n        error?: RESULT_INFO\n        info?: { [key: string]: any }\n      }>,\n    ) {\n      const { isShow, step, error, info } = action.payload\n      state.isShowConnect = {\n        isShow,\n        step: step ? step : 0,\n        error: error ?? undefined,\n        info: info ?? undefined,\n      }\n    },\n    setShowAccount(\n      state,\n      action: PayloadAction<{\n        isShow: boolean\n        step?: number\n        error?: RESULT_INFO\n        info?: { [key: string]: any }\n      }>,\n    ) {\n      const { isShow, step, error, info } = action.payload\n      state.isShowAccount = {\n        isShow,\n        step: step ? step : 0,\n        error: error ?? undefined,\n        info: info ?? undefined,\n      }\n    },\n    setShowFeeSetting(state, action: PayloadAction<{ isShow: boolean }>) {\n      const { isShow } = action.payload\n      state.isShowFeeSetting = {\n        isShow,\n      }\n    },\n    setShowLayerSwapNotice(state, action: PayloadAction<{ isShow: boolean }>) {\n      const { isShow } = action.payload\n      state.isShowLayerSwapNotice = {\n        isShow,\n      }\n    },\n    setShowAnotherNetworkNotice(state, action: PayloadAction<{ isShow: boolean; info: any }>) {\n      const { isShow, info } = action.payload\n      state.isShowAnotherNetwork = {\n        isShow,\n        info,\n      }\n    },\n    setShowTradeIsFrozen(\n      state,\n      action: PayloadAction<{\n        isShow: boolean\n        type: string\n        messageKey?: string\n      }>,\n    ) {\n      const { isShow, type, messageKey } = action.payload\n      state.isShowTradeIsFrozen = {\n        isShow,\n        type,\n        messageKey,\n      }\n    },\n    setShowClaimWithdraw(\n      state,\n      action: PayloadAction<\n        ModalStatePlayLoad & {\n          claimToken: ClaimToken\n          claimType: CLAIM_TYPE\n        }\n      >,\n    ) {\n      const { isShow, claimToken, claimType } = action.payload\n      state.isShowClaimWithdraw = {\n        isShow,\n        claimToken,\n        claimType,\n      }\n    },\n    setShowSideStakingRedeem(\n      state,\n      action: PayloadAction<ModalStatePlayLoad & { symbol?: string }>,\n    ) {\n      const { isShow, symbol } = action.payload\n      state.isShowSideStakingRedeem = {\n        isShow,\n        symbol,\n      }\n    },\n    setShowEditContact(\n      state,\n      action: PayloadAction<\n        ModalStatePlayLoad & {\n          info: any\n        }\n      >,\n    ) {\n      const { isShow, info } = action.payload\n      state.isShowEditContact = {\n        isShow,\n        info,\n      }\n    },\n    setShowTargetRedpacketPop(\n      state,\n      action: PayloadAction<\n        ModalStatePlayLoad & {\n          info: {\n            exclusiveRedPackets?: (LuckyTokenItemForReceive & {\n              tokenIcon: CoinSource\n              tokenName: string\n            })[]\n          }\n        }\n      >,\n    ) {\n      const {\n        isShow,\n        info: { exclusiveRedPackets },\n      } = action.payload\n      state.isShowTargetRedpacketPop = {\n        isShow,\n        info: {\n          exclusiveRedPackets,\n        },\n      }\n    },\n    setShowETHStakingApr(state, action: PayloadAction<ModalStatePlayLoad & { symbol?: string }>) {\n      const { isShow, symbol, info } = action.payload\n      state.isShowETHStakingApr = {\n        isShow,\n        symbol,\n        info,\n      }\n    },\n    setShowVaultExit(state, action: PayloadAction<ModalStatePlayLoad & Transaction>) {\n      state.isShowVaultExit = { ...action.payload }\n    },\n    setShowVaultJoin(state, action: PayloadAction<ModalStatePlayLoad & Transaction>) {\n      state.isShowVaultJoin = { ...action.payload }\n    },\n    setShowVaultSwap(state, action: PayloadAction<ModalStatePlayLoad & Transaction & { isSell?: boolean }>) {\n      state.isShowVaultSwap = { ...action.payload }\n    },\n    setShowVaultLoan(\n      state,\n      action: PayloadAction<ModalStatePlayLoad & Transaction & { type: string }>,\n    ) {\n      state.isShowVaultLoan = { ...action.payload }\n    },\n    setShowVaultCloseConfirm(\n      state,\n      action: PayloadAction<ModalStatePlayLoad & Transaction >,\n    ) {\n      state.isShowVaultCloseConfirm = { ...action.payload }\n    },\n    setShowNoVaultAccount(\n      state,\n      action: PayloadAction<ModalStatePlayLoad & { whichBtn: VaultAction | undefined }>,\n    ) {\n      state.isShowNoVaultAccount = { ...action.payload }\n    },\n    setShowConfirmedVault(state, action: PayloadAction<ModalStatePlayLoad>) {\n      state.isShowConfirmedVault = action.payload\n    },\n    setShowBridge(state, action: PayloadAction<ModalStatePlayLoad & Partial<Transaction & { contactName?: string }>>) {\n      state.isShowBridge = action.payload\n    },\n    setShowClosureAnnouncement(state, action: PayloadAction<ModalStatePlayLoad>) {\n      state.isShowClosureAnnouncement = action.payload\n    },\n  },\n})\nexport const {\n  setShowNFTDeploy,\n  setShowNFTDetail,\n  setShowNFTTransfer,\n  setShowNFTDeposit,\n  setShowNFTWithdraw,\n  setShowNFTMintAdvance,\n  setShowCollectionAdvance,\n  setShowTransfer,\n  setShowWithdraw,\n  setShowDeposit,\n  setShowResetAccount,\n  setShowExportAccount,\n  setShowDual,\n  setShowSwap,\n  setShowAmm,\n  setShowConnect,\n  setShowAccount,\n  setShowFeeSetting,\n  setShowActiveAccount,\n  setShowIFrame,\n  setShowTradeIsFrozen,\n  setShowSupport,\n  setShowWrongNetworkGuide,\n  setShowOtherExchange,\n  setShowLayerSwapNotice,\n  setShowClaimWithdraw,\n  setShowRedPacket,\n  setNFTMetaNotReady,\n  setShowSideStakingRedeem,\n  setShowAnotherNetworkNotice,\n  setShowGlobalToast,\n  setShowTargetRedpacketPop,\n  setShowEditContact,\n  setShowETHStakingApr,\n  setShowVaultExit,\n  setShowVaultJoin,\n  setShowVaultSwap,\n  setShowVaultLoan,\n  setShowVaultCloseConfirm,\n  setShowNoVaultAccount,\n  setShowConfirmedVault,\n  setShowBridge,\n  setShowTransferToTaikoAccount,\n  setShowClosureAnnouncement\n} = modalsSlice.actions\n"
  },
  {
    "path": "packages/component-lib/src/stores/reducer/settings/hook.ts",
    "content": "import { useDispatch, useSelector } from 'react-redux'\nimport {\n  setCoinJson,\n  setCurrency,\n  setDefaultNetwork,\n  setFeeChargeOrder,\n  setHideL2Action,\n  setHideL2Assets,\n  setHideLpToken,\n  setHideSmallBalances,\n  setIsDevToggle,\n  setIsMobile,\n  setDualDefault,\n  setLanguage,\n  setLayouts,\n  setPlatform,\n  setReferralCode,\n  setSlippage,\n  setStopLimitLayouts,\n  setSwapSecondConfirmation,\n  setTheme,\n  setUpColor,\n  setBTradeShowTutorial\n} from './reducer'\nimport { PlatFormType, SettingsState } from './interface'\nimport {\n  CurrencyToTag,\n  LanguageKeys,\n  LanguageType,\n  ThemeKeys,\n  ThemeType,\n  UpColor,\n} from '@loopring-web/common-resources'\nimport React from 'react'\nimport { Layouts } from 'react-grid-layout'\n\nexport function useSettings(): SettingsState & {\n  setPlatform(value: keyof typeof PlatFormType): void\n  setTheme(value: ThemeKeys): void\n  setDefaultNetwork(value: 1 | 5 | number): void\n  setUpColor(value: keyof typeof UpColor): void\n  setCurrency(value: CurrencyToTag): void\n  setLanguage(value: LanguageKeys): void\n  setSlippage(value: 'N' | number): void\n  setCoinJson(value: any): void\n  setHideL2Assets(value: boolean): void\n  setHideL2Action(value: boolean): void\n  setHideLpToken(value: boolean): void\n  setHideSmallBalances(value: boolean): void\n  setLayouts(value: Layouts): void\n  setStopLimitLayouts(value: Layouts): void\n  setFeeChargeOrder(value: string[]): void\n  setIsMobile(value: boolean): void\n  setSwapSecondConfirmation(value: boolean): void\n  setIsDevToggle(value: boolean): void\n  setReferralCode(value: string): void\n  setDualDefault(vaule: { auto: boolean; day: number | 'auto' }): void\n  setBTradeShowTutorial(value: boolean): void\n} {\n  const settings: SettingsState = useSelector((state: any) => state.settings)\n  const dispatch = useDispatch()\n  React.useEffect(() => {\n    if (['usd', 'cny'].includes(settings.currency)) {\n      dispatch(setCurrency(settings?.currency?.toUpperCase()))\n    }\n  }, [])\n\n  return {\n    ...settings,\n    setReferralCode: React.useCallback(\n      (value: string) => dispatch(setReferralCode(value)),\n      [dispatch],\n    ),\n    setDefaultNetwork: React.useCallback(\n      (value: number) => dispatch(setDefaultNetwork(value)),\n      [dispatch],\n    ),\n    setTheme: React.useCallback(\n      (value: keyof typeof ThemeType) => dispatch(setTheme(value)),\n      [dispatch],\n    ),\n    setLanguage: React.useCallback(\n      (value: keyof typeof LanguageType) => dispatch(setLanguage(value)),\n      [dispatch],\n    ),\n    setPlatform: React.useCallback(\n      (value: keyof typeof PlatFormType) => dispatch(setPlatform(value)),\n      [dispatch],\n    ),\n    setCurrency: React.useCallback(\n      (value: CurrencyToTag) => dispatch(setCurrency(value)),\n      [dispatch],\n    ),\n    setUpColor: React.useCallback(\n      (value: keyof typeof UpColor) => dispatch(setUpColor(value)),\n      [dispatch],\n    ),\n    setSlippage: React.useCallback(\n      (value: 'N' | number) => dispatch(setSlippage(value)),\n      [dispatch],\n    ),\n    setCoinJson: React.useCallback((value: any) => dispatch(setCoinJson(value)), [dispatch]),\n    setHideL2Assets: React.useCallback(\n      (value: boolean) => dispatch(setHideL2Assets(value)),\n      [dispatch],\n    ),\n    setHideL2Action: React.useCallback(\n      (value: boolean) => dispatch(setHideL2Action(value)),\n      [dispatch],\n    ),\n    setHideLpToken: React.useCallback(\n      (value: boolean) => dispatch(setHideLpToken(value)),\n      [dispatch],\n    ),\n    setHideSmallBalances: React.useCallback(\n      (value: boolean) => dispatch(setHideSmallBalances(value)),\n      [dispatch],\n    ),\n    setLayouts: React.useCallback((value: Layouts) => dispatch(setLayouts(value)), [dispatch]),\n    setStopLimitLayouts: React.useCallback(\n      (value: Layouts) => dispatch(setStopLimitLayouts(value)),\n      [dispatch],\n    ),\n    setFeeChargeOrder: React.useCallback(\n      (value: string[]) => dispatch(setFeeChargeOrder(value)),\n      [dispatch],\n    ),\n    setIsDevToggle: React.useCallback(\n      (value: boolean) => dispatch(setIsDevToggle(value)),\n      [dispatch],\n    ),\n    setIsMobile: React.useCallback((value: boolean) => dispatch(setIsMobile(value)), [dispatch]),\n    setSwapSecondConfirmation: React.useCallback(\n      (value: boolean) => dispatch(setSwapSecondConfirmation(value)),\n      [dispatch],\n    ),\n    setDualDefault: React.useCallback(\n      (value: { auto: boolean; day: number | 'auto' }) => dispatch(setDualDefault(value)),\n      [dispatch],\n    ),\n    setBTradeShowTutorial: React.useCallback(\n      (value: boolean) => dispatch(setBTradeShowTutorial(value)),\n      [dispatch],\n    ),\n  }\n}\n"
  },
  {
    "path": "packages/component-lib/src/stores/reducer/settings/index.ts",
    "content": "export * from './hook'\nexport * from './interface'\nexport * from './reducer'\n"
  },
  {
    "path": "packages/component-lib/src/stores/reducer/settings/interface.ts",
    "content": "import {\n  CoinSource,\n  CurrencyToTag,\n  LanguageKeys,\n  ThemeKeys,\n  UpColor,\n} from '@loopring-web/common-resources'\nimport { Layouts } from 'react-grid-layout'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nexport enum PlatFormType {\n  mobile = 'mobile',\n  desktop = 'desktop',\n  tablet = 'tablet',\n}\n\nexport type PlatFormKeys = keyof typeof PlatFormType\n\nexport interface SettingsState {\n  themeMode: ThemeKeys\n  language: LanguageKeys\n  platform: PlatFormKeys\n  currency: CurrencyToTag\n  upColor: keyof typeof UpColor\n  slippage: number | 'N'\n  coinJson: {\n    [key: string]: CoinSource\n  }\n  hideL2Assets: boolean\n  hideL2Action: boolean\n  hideInvestToken: boolean\n  isMobile: boolean\n  hideSmallBalances: boolean\n  proLayout: Layouts\n  stopLimitLayout: Layouts\n  feeChargeOrder: string[]\n  swapSecondConfirmation: boolean | undefined\n  defaultNetwork: sdk.ChainId\n  referralCode: string\n  isDevToggle: boolean\n  dualAuto: { auto: boolean; day: number | 'auto' }\n  bTradeShowTutorial: boolean\n}\n"
  },
  {
    "path": "packages/component-lib/src/stores/reducer/settings/reducer.ts",
    "content": "import { createSlice, PayloadAction } from '@reduxjs/toolkit'\nimport { PlatFormType, SettingsState } from './interface'\nimport {\n  i18n,\n  LanguageKeys,\n  layoutConfigs,\n  stopLimitLayoutConfigs,\n  ThemeKeys,\n  ThemeType,\n  UpColor,\n  CurrencyToTag,\n  NetworkMap,\n  FeeChargeOrderDefaultMap,\n} from '@loopring-web/common-resources'\nimport moment from 'moment'\nimport { Slice } from '@reduxjs/toolkit/src/createSlice'\nimport { Layouts } from 'react-grid-layout'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nconst initialState: SettingsState = {\n  themeMode: ThemeType.dark, //localStore.getItem('ThemeType')?localStore.getItem('ThemeType') as ThemeKeys :ThemeType.dark,\n  language: i18n.language as LanguageKeys, //localStore.getItem('LanguageKey')?localStore.getItem('LanguageKey') as LanguageKeys: i18n.language as LanguageKeys,\n  platform: PlatFormType.desktop,\n  currency: CurrencyToTag.USD, //localStore.getItem('Currency')?localStore.getItem('Currency') as keyof typeof Currency: Currency.usd,\n  upColor: UpColor.green, //localStore.getItem('UpColor')?localStore.getItem('UpColor') as keyof typeof UpColor: UpColor.green,\n  coinJson: {},\n  slippage: 'N',\n  feeChargeOrder: FeeChargeOrderDefaultMap.get(sdk.ChainId.MAINNET)!,\n  hideL2Assets: false,\n  hideL2Action: true,\n  hideInvestToken: false,\n  hideSmallBalances: true,\n  isMobile: false,\n  proLayout: layoutConfigs[0].layouts,\n  stopLimitLayout: stopLimitLayoutConfigs[0].layouts,\n  swapSecondConfirmation: true,\n  defaultNetwork: NetworkMap['ETHEREUM']?.chainId ?? 1,\n  referralCode: '',\n  isDevToggle: false,\n  dualAuto: { auto: true, day: 'auto' },\n  bTradeShowTutorial: true\n}\n\nexport const settingsSlice: Slice<SettingsState> = createSlice({\n  name: 'settings',\n  initialState,\n  reducers: {\n    setReferralCode(state, action: PayloadAction<string>) {\n      const referralCode = action.payload\n      const regex = /^[0-9\\b]+$/\n      if (regex.test(referralCode) && referralCode.length < 8) {\n        state.referralCode = action.payload\n      } else {\n        state.referralCode = ''\n      }\n    },\n    setDefaultNetwork(state, action: PayloadAction<sdk.ChainId>) {\n      state.defaultNetwork = action.payload\n    },\n    setIsDevToggle(state, action: PayloadAction<boolean>) {\n      state.isDevToggle = action.payload\n    },\n    setTheme(state, action: PayloadAction<ThemeKeys>) {\n      // localStore.setItem('ThemeType',action.payload)\n      state.themeMode = action.payload\n    },\n    setLanguage(state, action: PayloadAction<LanguageKeys>) {\n      i18n.changeLanguage(action.payload)\n      if (action.payload) {\n        // action.payload === 'en_US' ? moment.locale('en') : moment.locale(action.payload.toLocaleLowerCase());\n        action.payload === 'en_US'\n          ? moment.updateLocale('en', {\n              relativeTime: {\n                future: (diff) => (diff == 'just now' ? diff : `in ${diff}`),\n                past: (diff) => (diff == 'just now' ? diff : `${diff} ago`),\n                s: 'just now',\n                ss: 'just now',\n              },\n            })\n          : moment.updateLocale('zh-cn', {\n              relativeTime: {\n                future: '%s后',\n                past: '%s前',\n                s: '几秒',\n                ss: '%d 秒',\n                m: '1 分钟',\n                mm: '%d 分钟',\n                h: '1 小时',\n                hh: '%d 小时',\n                d: '1 天',\n                dd: '%d 天',\n                w: '1 周',\n                ww: '%d 周',\n                M: '1 个月',\n                MM: '%d 个月',\n                y: '1 年',\n                yy: '%d 年',\n              },\n            })\n        state.language = action.payload\n      }\n    },\n    setIsMobile(state, action: PayloadAction<boolean>) {\n      // localStore.setItem('UpColor',action.payload)\n      state.isMobile = action.payload\n    },\n    setPlatform(state, action: PayloadAction<keyof typeof PlatFormType>) {\n      state.platform = action.payload\n    },\n    setCurrency(state, action: PayloadAction<CurrencyToTag>) {\n      if (['usd', 'cyn'].includes(action.payload)) {\n        // @ts-ignore\n        state.currency = action?.payload?.toUpperCase()\n      } else {\n        state.currency = action.payload\n      }\n    },\n    setUpColor(state, action: PayloadAction<keyof typeof UpColor>) {\n      // localStore.setItem('UpColor',action.payload)\n      state.upColor = action.payload\n    },\n    setSlippage(state, action: PayloadAction<'N' | number>) {\n      // localStore.setItem('UpColor',action.payload)\n      state.slippage = action.payload\n    },\n    setCoinJson(state, action: PayloadAction<any>) {\n      // localStore.setItem('UpColor',action.payload)\n      state.coinJson = action.payload\n    },\n    setHideL2Assets(state, action: PayloadAction<boolean>) {\n      state.hideL2Assets = action.payload\n    },\n    setHideL2Action(state, action: PayloadAction<boolean>) {\n      state.hideL2Action = action.payload\n    },\n    setHideLpToken(state, action: PayloadAction<boolean>) {\n      state.hideInvestToken = action.payload\n    },\n    setHideSmallBalances(state, action: PayloadAction<boolean>) {\n      state.hideSmallBalances = action.payload\n    },\n    setFeeChargeOrder(state, action: PayloadAction<string[]>) {\n      state.feeChargeOrder = action.payload\n    },\n    setLayouts(state, action: PayloadAction<Layouts>) {\n      // localStore.setItem('UpColor',action.payload)\n      const result: Layouts = {\n        ...state.proLayout,\n        ...action.payload,\n      }\n      state.proLayout = result\n    },\n    setStopLimitLayouts(state, action: PayloadAction<Layouts>) {\n      // localStore.setItem('UpColor',action.payload)\n      const result: Layouts = {\n        ...state.stopLimitLayout,\n        ...action.payload,\n      }\n      state.stopLimitLayout = result\n    },\n    setSwapSecondConfirmation(state, action: PayloadAction<boolean>) {\n      state.swapSecondConfirmation = action.payload\n    },\n    setDualDefault(state, action: PayloadAction<{ auto: boolean; day: number | 'auto' }>) {\n      state.dualAuto = action.payload\n    },\n    setBTradeShowTutorial(state, action: PayloadAction<boolean>) {\n      state.bTradeShowTutorial = action.payload\n    },\n  },\n})\nexport const {\n  setLayouts,\n  setStopLimitLayouts,\n  setTheme,\n  setLanguage,\n  setPlatform,\n  setCurrency,\n  setUpColor,\n  setSlippage,\n  setCoinJson,\n  setFeeChargeOrder,\n  setHideL2Assets,\n  setHideLpToken,\n  setHideL2Action,\n  setHideSmallBalances,\n  setIsMobile,\n  setSwapSecondConfirmation,\n  setDefaultNetwork,\n  setReferralCode,\n  setIsDevToggle,\n  setDualDefault,\n  setBTradeShowTutorial\n} = settingsSlice.actions\n// export const { setTheme,setPlatform,setLanguage } = settingsSlice.actions\n"
  },
  {
    "path": "packages/component-lib/src/stores/reducer/toggle/hook.ts",
    "content": "import { useDispatch, useSelector } from 'react-redux'\nimport { ToggleState } from './interface'\nimport { updateToggleStatus } from './reducer'\nimport React from 'react'\n\nexport function useToggle() {\n  const toggle: ToggleState = useSelector((state: any) => state.toggle)\n  const dispatch = useDispatch()\n  return {\n    toggle,\n    updateToggleStatus: React.useCallback(() => {\n      dispatch(updateToggleStatus(undefined))\n    }, [dispatch]),\n  }\n}\n"
  },
  {
    "path": "packages/component-lib/src/stores/reducer/toggle/index.ts",
    "content": "export * from './hook'\nexport * from './reducer'\nexport * from './interface'\n"
  },
  {
    "path": "packages/component-lib/src/stores/reducer/toggle/interface.ts",
    "content": "import { Account } from '@loopring-web/common-resources'\n\nexport type ToggleState = {\n  order: { enable: boolean; reason?: string }\n  joinAmm: { enable: boolean; reason?: string }\n  exitAmm: { enable: boolean; reason?: string }\n  transfer: { enable: boolean; reason?: string }\n  transferNFT: { enable: boolean; reason?: string }\n  deposit: { enable: boolean; reason?: string }\n  depositNFT: { enable: boolean; reason?: string }\n  withdraw: { enable: boolean; reason?: string }\n  withdrawNFT: { enable: boolean; reason?: string }\n  mintNFT: { enable: boolean; reason?: string }\n  deployNFT: { enable: boolean; reason?: string }\n  updateAccount: { enable: boolean; reason?: string }\n  defiInvest: { enable: boolean; reason?: string }\n  WSTETHInvest: { enable: boolean; reason?: string }\n  RETHInvest: { enable: boolean; reason?: string }\n  dualInvest: { enable: boolean; reason?: string }\n  leverageETHInvest: { enable: boolean; reason?: string }\n  collectionNFT: { enable: boolean; reason?: string }\n  claim: { enable: boolean; reason?: string }\n  redPacketNFTV1: { enable: boolean; reason?: string }\n  LRCStackInvest: { enable: boolean; reason?: string }\n  BTradeInvest: { enable: boolean; reason?: string }\n  StopLimit: { enable: boolean; reason?: string }\n  VaultInvest: {\n    enable: boolean\n    reason?: string\n  }\n  VaultDustCollector: { enable: boolean; reason?: string }\n  // @ts-ignore\n  send: {\n    orbiter: string[]\n  }\n  // @ts-ignore\n  receive: {\n    layerSwap: string[]\n    orbiter: string[]\n  }\n  CIETHInvest: { enable: boolean; reason?: string }\n  redpacket_exclusive: { enable: boolean; reason?: string }\n  [key: string]: { enable?: boolean; reason?: string; [key: string]: any }\n  dual_reinvest: { enable: boolean; reason?: string }\n  taikoFarming: { enable: boolean; reason?: string }\n  whiteList: any\n  // @ts-ignore\n  isSupperUser: any\n  rabbitWithdraw: { enable: boolean; reason?: string }\n  transferToTaikoAccount: { enable: boolean; reason?: string }\n}\n\nexport type TogglePlayLoad = Partial<ToggleState> & {\n  account?: Account\n  chainId: any\n}\n"
  },
  {
    "path": "packages/component-lib/src/stores/reducer/toggle/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { SliceCaseReducers } from '@reduxjs/toolkit/src/createSlice'\nimport { TogglePlayLoad, ToggleState } from './interface'\nimport { MapChainId } from '@loopring-web/common-resources'\n\nconst initialState: ToggleState = {\n  order: { enable: true },\n  joinAmm: { enable: true },\n  exitAmm: { enable: true },\n  transfer: { enable: true },\n  transferNFT: { enable: true },\n  deposit: { enable: true },\n  depositNFT: { enable: true },\n  withdraw: { enable: true },\n  withdrawNFT: { enable: true },\n  mintNFT: { enable: true },\n  deployNFT: { enable: true },\n  updateAccount: { enable: true },\n  collectionNFT: { enable: true },\n  WSTETHInvest: { enable: true },\n  RETHInvest: { enable: true },\n  leverageETHInvest: { enable: true },\n  defiInvest: { enable: true },\n  dualInvest: { enable: true },\n  claim: { enable: true },\n  redPacketNFTV1: { enable: true },\n  LRCStackInvest: { enable: true },\n  BTradeInvest: { enable: true },\n  StopLimit: { enable: true },\n  send: {\n    orbiter: ['ETH'],\n  },\n  receive: {\n    layerSwap: ['ETH', 'LRC', 'USDC'],\n    orbiter: ['ETH'],\n  },\n  CIETHInvest: { enable: true },\n  redpacket_exclusive: { enable: true },\n  dual_reinvest: { enable: true },\n  VaultInvest: { enable: true },\n  VaultDustCollector: { enable: true },\n  taikoFarming: { enable: false },\n  rabbitWithdraw: { enable: true },\n  transferToTaikoAccount: {enable: true},\n  whiteList: {},\n  isSupperUser: false as any,\n  \n}\n\nexport const toggleSlice: Slice<ToggleState> = createSlice<\n  ToggleState,\n  SliceCaseReducers<ToggleState>\n>({\n  name: 'toggle',\n  initialState: initialState,\n  reducers: {\n    updateToggleStatus(state, action: PayloadAction<TogglePlayLoad>) {\n      const { account, chainId, ...rest } = action.payload\n      // let toggle = {}\n      Reflect.ownKeys(state).forEach((key) => {\n        if (rest.hasOwnProperty(key) && rest[key.toString()] !== undefined) {\n          state[key.toString()] = rest[key.toString()] as any\n          // toggle[key.toString()] = rest[key.toString()] as any\n        }\n      })\n      const network = MapChainId[chainId] ?? MapChainId[1]\n      let isSupperUser = false,\n        list: any = []\n      if (\n        account &&\n        account.accAddress &&\n        state?.whiteList &&\n        state?.whiteList[network?.toUpperCase()] &&\n        state?.whiteList[network?.toUpperCase()]\n      ) {\n        // const toggle = _.cloneDeep(_toggle)\n        const newToggle = {\n          ...state,\n        }\n        state?.whiteList[network?.toUpperCase()].forEach((item: string) => {\n          // @ts-ignore\n          isSupperUser = item?.superUserAddress?.find(\n            (addr: string) => addr?.toLowerCase() == account?.accAddress?.toLowerCase(),\n          )\n          if (isSupperUser) {\n            // @ts-ignore\n            item?.superUserFunction?.forEach((fn: string) => {\n              const key: string | undefined = Reflect.ownKeys(newToggle).find(\n                // @ts-ignore\n                (_toggle: string) => _toggle?.toUpperCase() == fn?.toUpperCase(),\n              )\n              if (key && newToggle[key].enable == false && state[key].reason === 'no view') {\n                state[key] = { ...newToggle[key], enable: true, reason: 'whiteList' }\n                list.push(key)\n              }\n            })\n          }\n        })\n      }\n\n      // updateToggleStatus(state, action: PayloadAction<Partial<ToggleState>>) {\n      //   const rest = action.payload\n      //   Reflect.ownKeys(state).forEach((key) => {\n      //     if (rest.hasOwnProperty(key) && rest[key.toString()] !== undefined) {\n      //       state[key.toString()] = rest[key.toString()] as any\n      //     }\n      //   })\n      // },\n    },\n  },\n})\nexport const { updateToggleStatus } = toggleSlice.actions\n"
  },
  {
    "path": "packages/component-lib/src/types/lib.ts",
    "content": "export type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never }\nexport type XOR<T, U> = T | U extends { [key: string]: any }\n  ? (Without<T, U> & U) | (Without<U, T> & T)\n  : T | U\n\n// export type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>\n"
  },
  {
    "path": "packages/component-lib/src/utils/closureAnnouncementUtils.ts",
    "content": "const CLOSURE_ANNOUNCEMENT_KEY = 'loopring_closure_announcement_dismissed'\n\nexport const isClosureAnnouncementDismissed = (): boolean => {\n  try {\n    return localStorage.getItem(CLOSURE_ANNOUNCEMENT_KEY) === 'true'\n  } catch (error) {\n    return false\n  }\n}\n\nexport const setClosureAnnouncementDismissed = (): void => {\n  try {\n    localStorage.setItem(CLOSURE_ANNOUNCEMENT_KEY, 'true')\n  } catch (error) {\n    console.warn('Failed to save closure announcement state:', error)\n  }\n}"
  },
  {
    "path": "packages/component-lib/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.build.json\",\n  \"compilerOptions\": {\n    \"jsx\": \"react-jsx\",\n    \"noUnusedLocals\": true,\n    \"noUnusedParameters\": true,\n    \"resolveJsonModule\": true,\n    \"allowSyntheticDefaultImports\": true,\n    \"baseUrl\": \"./src\",\n    \"rootDir\": \"./src\"\n  },\n  \"include\": [\n    \"src\",\n    \"src/**/*.json\",\n    \"src/*\"\n  ],\n  \"exclude\": [\n    \"node_modules\",\n    \"build\",\n    \"dist\",\n    \"example\",\n    \"rollup.config.js\"\n  ]\n}\n"
  },
  {
    "path": "packages/component-lib/tsconfig.test.json",
    "content": "{\n  \"extends\": \"./tsconfig.json\",\n  \"compilerOptions\": {\n    \"module\": \"commonjs\"\n  },\n  \"include\": [\n    \"src\",\n    \"src/**/*.json\",\n    \"src/*\"\n  ]\n}\n"
  },
  {
    "path": "packages/core/.babelrc",
    "content": "{\n  \"presets\": [\n    \"@babel/typescript\",\n    \"@babel/preset-env\",\n    \"@babel/preset-react\",\n    \"@emotion/babel-preset-css-prop\",\n    [\n      \"@babel/env\",\n      {\n        \"modules\": false\n      }\n    ]\n  ],\n  \"plugins\": [\n    \"@babel/plugin-proposal-class-properties\"\n  ]\n}\n"
  },
  {
    "path": "packages/core/.eslintignore",
    "content": "*.css\n*.scss\n*.svg"
  },
  {
    "path": "packages/core/.eslintrc.json",
    "content": "{\n  \"plugins\": [\n    \"react-hooks\"\n  ],\n  \"extends\": [\n    \"react-app\"\n  ],\n  \"overrides\": [\n    {\n      \"files\": [\n        \"**/*.tsx\",\n        \"**/*.ts\"\n      ],\n      \"rules\": {\n        \"import/no-anonymous-default-export\": \"off\",\n        \"@typescript-eslint/no-unused-vars\": \"warn\",\n        \"@typescript-eslint/ban-types\": \"off\",\n        \"react-hooks/rules-of-hooks\": \"error\",\n        \"react-hooks/exhaustive-deps\": \"warn\"\n      }\n    }\n  ]\n}\n"
  },
  {
    "path": "packages/core/.gitignore",
    "content": "\n# See https://help.github.com/ignore-files/ for more about ignoring files.\n\n# dependencies\nnode_modules\n\n# builds\nbuild\ndist\n.rpt2_cache\n\n# misc\n.DS_Store\n.env\n.env.local\n.env.development.local\n.env.test.local\n.env.production.local\n.idea/**\n.vscode/**\n./lib/**\n\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\nsrc/assets\nstorybook-static\n\n\n"
  },
  {
    "path": "packages/core/.travis.yml",
    "content": "language: node_js\nnode_js:\n  - 8\nenv:\n  - SKIP_PREFLIGHT_CHECK=true\n"
  },
  {
    "path": "packages/core/README.md",
    "content": "# component-lib\n\n> Loopring UI component lib\n\n[![NPM](https://img.shields.io/npm/v/component-lib.svg)](https://www.npmjs.com/package/component-lib) [![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)\n\n## Install\n\n```bash\nnpm install --save component-lib\n```\n\n## Usage\n\n```tsx\nimport * as React from 'react'\n\n<\nProviderComposer\nproviders = {\n    [\n        provider(LocalizationProvider, {dateAdapter: MomentUtils}),\n    provider(I18nextProvider, {i18n}),\n    provider(ThemeProvider),\n]\n}>\n<\nStory\n{...\n    context\n}\n/>\n</ProviderComposer>\n</Global><Global styles={\n    `${globalCss}`\n}\n>\n<\nProviderComposer\nproviders = {\n    [\n        provider(LocalizationProvider, {dateAdapter: MomentUtils}),\n    provider(I18nextProvider, {i18n}),\n    provider(ThemeProvider),\n]\n}>\n<\nStory\n{...\n    context\n}\n/>\n</ProviderComposer>\n</Global>\n\n\"@loopring-web/static-resource\": \"file:../static-resource/src\",\n\n```\n\n## License\n\nMIT © [Loopring dev Team](https://github.com/Loopring dev Team)\n\n---\n\nThis hook is created using [create-react-hook](https://github.com/hermanya/create-react-hook).\n"
  },
  {
    "path": "packages/core/package.json",
    "content": "{\n  \"name\": \"@loopring-web/core\",\n  \"version\": \"1.0.0\",\n  \"main\": \"src/index.ts\",\n  \"private\": true,\n  \"resolutions\": {\n    \"**/@emotion/styled\": \"^11.1.5\"\n  },\n  \"dependencies\": {\n    \"@loopring-web/common-resources\": \"1.0.0\",\n    \"@loopring-web/component-lib\": \"1.0.0\",\n    \"react-scripts\": \"5.0.1\",\n    \"cross-env\": \"^7.0.3\"\n  },\n  \"scripts\": {\n    \"rollup:build\": \"rollup --config --no-stdin\",\n    \"release:version\": \"lerna version --exact --no-changelog --no-push --no-git-tag-version\",\n    \"release:build\": \"lerna run --parallel --scope \\\"@loopring-web/*\\\" build\",\n    \"test\": \"react-scripts-rewired test\",\n    \"eject\": \"react-scripts eject\"\n  },\n  \"eslintConfig\": {\n    \"extends\": [\n      \"react-app\"\n    ],\n    \"overrides\": [\n      {\n        \"files\": [\n          \"**/*.stories.*\"\n        ],\n        \"rules\": {\n          \"import/no-anonymous-default-export\": \"off\"\n        }\n      },\n      {\n        \"files\": [\n          \"**/*.stories.*\"\n        ],\n        \"rules\": {\n          \"import/no-anonymous-default-export\": \"off\"\n        }\n      }\n    ]\n  },\n  \"browserslist\": {\n    \"production\": [\n      \"last 2 chrome version\",\n      \"last 2 firefox version\",\n      \"last 2 safari version\"\n    ],\n    \"development\": [\n      \"last 1 chrome version\",\n      \"last 1 firefox version\",\n      \"last 1 safari version\"\n    ]\n  },\n  \"devDependencies\": {\n    \"@emotion/react\": \"^11.1.5\",\n    \"@emotion/server\": \"^11.0.0\",\n    \"@rollup/plugin-commonjs\": \"^18.0.0\",\n    \"@rollup/plugin-node-resolve\": \"^11.2.1\",\n    \"@rollup/plugin-typescript\": \"^8.2.1\",\n    \"@rollup/plugin-url\": \"^6.0.0\",\n    \"@testing-library/jest-dom\": \"^5.11.4\",\n    \"@testing-library/react\": \"^11.1.0\",\n    \"@testing-library/user-event\": \"^12.1.10\",\n    \"@types/d3-format\": \"^2.0.0\",\n    \"@types/d3-time-format\": \"^3.0.0\",\n    \"@typescript-eslint/eslint-plugin\": \"^4.21.0\",\n    \"arr-flatten\": \"^1.1.0\",\n    \"babel-plugin-react-require\": \"^3.1.3\",\n    \"repeat-element\": \"^1.1.3\",\n    \"rollup\": \"2.30\",\n    \"rollup-plugin-font\": \"^1.1.1\",\n    \"rollup-plugin-json\": \"^4.0.0\",\n    \"rollup-plugin-peer-deps-external\": \"^2.2.4\",\n    \"rollup-plugin-svg\": \"^2.0.0\",\n    \"rollup-plugin-typescript2\": \"^0.30.0\",\n    \"snapdragon-node\": \"^3.0.0\",\n    \"storybook-addon-redux-listener\": \"^0.1.7\",\n    \"storybook-react-router\": \"^1.0.8\"\n  }\n}\n"
  },
  {
    "path": "packages/core/rollup.config.js",
    "content": "import ts from 'rollup-plugin-typescript2'\nimport typescript from 'typescript'\nimport commonjs from '@rollup/plugin-commonjs'\nimport resolve from '@rollup/plugin-node-resolve'\nimport external from 'rollup-plugin-peer-deps-external'\nimport svg from 'rollup-plugin-svg'\nimport url from '@rollup/plugin-url'\nimport json from 'rollup-plugin-json'\n// importfont  from \"rollup-plugin-font\";\n\n// import pkg from './package.json'\n\nexport default {\n  input: './src/DualListPanel.tsx',\n  output: [\n    {\n      file: './dist/bundle.cjs', //pkg.main,\n      format: 'cjs',\n      preferConst: true,\n      interop: false,\n      //exports: 'named',\n      sourcemap: true,\n    },\n    {\n      file: './dist/bundle.js', //pkg.module,\n      format: 'es',\n      preferConst: true,\n      //exports: 'named',\n      sourcemap: true,\n    },\n  ],\n  plugins: [\n    external(),\n    url({ exclude: ['**/*.svg'] }),\n    url({\n      include: ['**/*.ttf', '**/*.eot', '**/*.woff', '**/*.woff2'],\n      limit: Infinity,\n    }),\n    resolve(),\n    ts({ typescript }),\n    svg(),\n    commonjs({ extensions: ['.js', '.ts'] }),\n    json({\n      // 默认情况下将解析所有JSON文件,\n      // 但您可以专门包含/排除文件\n      // exclude: [ 'node_modules/foo/**', 'node_modules/bar/**' ],\n      // exclude: [ 'node_modules/foo/**', 'node_modules/bar/**' ],\n\n      // 对于 tree-shaking, 属性将声明为\n      // 变量, 使用 `var` 或者 `const`\n      preferConst: true, // 默认是 false\n\n      // 为生成的默认导出指定缩进 —\n      // 默认为 '\\t'\n      indent: '  ',\n\n      // 忽略缩进并生成最小的代码\n      compact: true, // 默认是 false\n\n      // 为JSON对象的每个属性生成一个命名导出\n      namedExports: true, // 默认是 true\n    }),\n    //font()\n  ],\n}\n"
  },
  {
    "path": "packages/core/src/TimeoutCheckProvider.tsx",
    "content": "import { AccountStatus, myLog } from '@loopring-web/common-resources'\nimport { debounce } from 'lodash'\nimport React from 'react'\nimport { accountServices } from './services/account/accountServices'\nimport { UserStorage } from './storage'\nimport { store } from './index'\n\nconst WindowEvent = {\n  Click: 'click',\n  Scroll: 'scroll',\n  Mouseover: 'mouseover',\n}\n\nconst events = [WindowEvent.Click, WindowEvent.Mouseover, WindowEvent.Scroll]\n\nconst forceReset = debounce(() => {\n  // myLog('active!!!!! reset active time!!!! ')\n  UserStorage.checkTimeout(true)\n}, 100)\n\nexport const TimeoutCheckProvider = ({ children }: { children: React.ReactNode }) => {\n  React.useEffect(() => {\n    events.forEach((event: string) => {\n      document.addEventListener(event, forceReset)\n    })\n\n    const handler = setInterval(() => {\n      if (UserStorage.checkTimeout()) {\n        // timeout\n        const account = store.getState().account\n\n        if (account.readyState === AccountStatus.ACTIVATED) {\n          myLog('[*****] got timeout! try to lock!!!!!')\n          accountServices.sendAccountLock()\n        }\n      }\n    }, 1000)\n\n    return () => {\n      events.forEach((event: string) => {\n        document.removeEventListener(event, forceReset)\n      })\n      if (handler) {\n        clearInterval(handler)\n      }\n    }\n  }, [])\n\n  return <>{children}</>\n}\n"
  },
  {
    "path": "packages/core/src/abi/erc20ABI.ts",
    "content": "export default [\n  {\n    constant: true,\n    inputs: [],\n    name: 'name',\n    outputs: [\n      {\n        name: '',\n        type: 'string',\n      },\n    ],\n    payable: false,\n    stateMutability: 'view',\n    type: 'function',\n  },\n  {\n    constant: false,\n    inputs: [\n      {\n        name: '_spender',\n        type: 'address',\n      },\n      {\n        name: '_value',\n        type: 'uint256',\n      },\n    ],\n    name: 'approve',\n    outputs: [\n      {\n        name: '',\n        type: 'bool',\n      },\n    ],\n    payable: false,\n    stateMutability: 'nonpayable',\n    type: 'function',\n  },\n  {\n    constant: true,\n    inputs: [],\n    name: 'totalSupply',\n    outputs: [\n      {\n        name: '',\n        type: 'uint256',\n      },\n    ],\n    payable: false,\n    stateMutability: 'view',\n    type: 'function',\n  },\n  {\n    constant: false,\n    inputs: [\n      {\n        name: '_from',\n        type: 'address',\n      },\n      {\n        name: '_to',\n        type: 'address',\n      },\n      {\n        name: '_value',\n        type: 'uint256',\n      },\n    ],\n    name: 'transferFrom',\n    outputs: [\n      {\n        name: '',\n        type: 'bool',\n      },\n    ],\n    payable: false,\n    stateMutability: 'nonpayable',\n    type: 'function',\n  },\n  {\n    constant: true,\n    inputs: [],\n    name: 'decimals',\n    outputs: [\n      {\n        name: '',\n        type: 'uint8',\n      },\n    ],\n    payable: false,\n    stateMutability: 'view',\n    type: 'function',\n  },\n  {\n    constant: true,\n    inputs: [\n      {\n        name: '_owner',\n        type: 'address',\n      },\n    ],\n    name: 'balanceOf',\n    outputs: [\n      {\n        name: 'balance',\n        type: 'uint256',\n      },\n    ],\n    payable: false,\n    stateMutability: 'view',\n    type: 'function',\n  },\n  {\n    constant: true,\n    inputs: [],\n    name: 'symbol',\n    outputs: [\n      {\n        name: '',\n        type: 'string',\n      },\n    ],\n    payable: false,\n    stateMutability: 'view',\n    type: 'function',\n  },\n  {\n    constant: false,\n    inputs: [\n      {\n        name: '_to',\n        type: 'address',\n      },\n      {\n        name: '_value',\n        type: 'uint256',\n      },\n    ],\n    name: 'transfer',\n    outputs: [\n      {\n        name: '',\n        type: 'bool',\n      },\n    ],\n    payable: false,\n    stateMutability: 'nonpayable',\n    type: 'function',\n  },\n  {\n    constant: true,\n    inputs: [\n      {\n        name: '_owner',\n        type: 'address',\n      },\n      {\n        name: '_spender',\n        type: 'address',\n      },\n    ],\n    name: 'allowance',\n    outputs: [\n      {\n        name: '',\n        type: 'uint256',\n      },\n    ],\n    payable: false,\n    stateMutability: 'view',\n    type: 'function',\n  },\n  {\n    payable: true,\n    stateMutability: 'payable',\n    type: 'fallback',\n  },\n  {\n    anonymous: false,\n    inputs: [\n      {\n        indexed: true,\n        name: 'owner',\n        type: 'address',\n      },\n      {\n        indexed: true,\n        name: 'spender',\n        type: 'address',\n      },\n      {\n        indexed: false,\n        name: 'value',\n        type: 'uint256',\n      },\n    ],\n    name: 'Approval',\n    type: 'event',\n  },\n  {\n    anonymous: false,\n    inputs: [\n      {\n        indexed: true,\n        name: 'from',\n        type: 'address',\n      },\n      {\n        indexed: true,\n        name: 'to',\n        type: 'address',\n      },\n      {\n        indexed: false,\n        name: 'value',\n        type: 'uint256',\n      },\n    ],\n    name: 'Transfer',\n    type: 'event',\n  },\n]"
  },
  {
    "path": "packages/core/src/abi/index.ts",
    "content": "import erc20ABI from './erc20ABI'\nimport taikoDepositABI from './taikoDepositABI'\n\nexport { taikoDepositABI, erc20ABI }\n"
  },
  {
    "path": "packages/core/src/abi/taikoDepositABI.ts",
    "content": "export default [\n  {\n    inputs: [{ internalType: 'address', name: '_exchange', type: 'address' }],\n    stateMutability: 'nonpayable',\n    type: 'constructor',\n  },\n  {\n    anonymous: false,\n    inputs: [\n      { indexed: false, internalType: 'address', name: 'from', type: 'address' },\n      { indexed: false, internalType: 'address', name: 'to', type: 'address' },\n      { indexed: false, internalType: 'address', name: 'token', type: 'address' },\n      { indexed: false, internalType: 'uint96', name: 'amount', type: 'uint96' },\n      { indexed: false, internalType: 'uint256', name: 'duration', type: 'uint256' },\n    ],\n    name: 'Deposited',\n    type: 'event',\n  },\n  {\n    inputs: [\n      { internalType: 'address', name: 'from', type: 'address' },\n      { internalType: 'address', name: 'to', type: 'address' },\n      { internalType: 'address', name: 'tokenAddress', type: 'address' },\n      { internalType: 'uint96', name: 'amount', type: 'uint96' },\n      { internalType: 'uint256', name: 'duration', type: 'uint256' },\n      { internalType: 'bytes', name: 'extraData', type: 'bytes' },\n    ],\n    name: 'deposit',\n    outputs: [],\n    stateMutability: 'payable',\n    type: 'function',\n  },\n  {\n    inputs: [],\n    name: 'exchange',\n    outputs: [{ internalType: 'address', name: '', type: 'address' }],\n    stateMutability: 'view',\n    type: 'function',\n  },\n]"
  },
  {
    "path": "packages/core/src/api_wrapper/index.ts",
    "content": "import {\n  AmmpoolAPI,\n  ChainId,\n  DefiAPI,\n  DelegateAPI,\n  ExchangeAPI,\n  GlobalAPI,\n  LuckTokenAPI,\n  NFTAPI,\n  UserAPI,\n  WalletAPI,\n  WsAPI,\n  ContactAPI,\n  VaultAPI,\n  RabbitWithdrawAPI\n} from '@loopring-web/loopring-sdk'\n\nexport class LoopringAPI {\n  public static userAPI: UserAPI | undefined = undefined\n  public static exchangeAPI: ExchangeAPI | undefined = undefined\n  public static ammpoolAPI: AmmpoolAPI | undefined = undefined\n  public static walletAPI: WalletAPI | undefined = undefined\n  public static wsAPI: WsAPI | undefined = undefined\n  public static nftAPI: NFTAPI | undefined = undefined\n  public static delegate: DelegateAPI | undefined = undefined\n  public static globalAPI: GlobalAPI | undefined = undefined\n  public static defiAPI: DefiAPI | undefined = undefined\n  public static luckTokenAPI: LuckTokenAPI | undefined = undefined\n  public static contactAPI: ContactAPI | undefined = undefined\n  public static vaultAPI: VaultAPI | undefined = undefined\n  public static rabbitWithdrawAPI: RabbitWithdrawAPI | undefined = undefined\n  public static __chainId__: ChainId | undefined = undefined\n  public static InitApi = (chainId: ChainId) => {\n    LoopringAPI.userAPI = new UserAPI({ chainId }, 15000)\n    LoopringAPI.luckTokenAPI = new LuckTokenAPI({ chainId }, 15000)\n    LoopringAPI.exchangeAPI = new ExchangeAPI({ chainId }, 15000)\n    LoopringAPI.globalAPI = new GlobalAPI({ chainId }, 25000)\n    LoopringAPI.ammpoolAPI = new AmmpoolAPI({ chainId }, 15000)\n    LoopringAPI.walletAPI = new WalletAPI({ chainId }, 15000)\n    LoopringAPI.wsAPI = new WsAPI({ chainId }, 15000)\n    LoopringAPI.nftAPI = new NFTAPI({ chainId }, 15000)\n    LoopringAPI.delegate = new DelegateAPI({ chainId }, 15000)\n    LoopringAPI.defiAPI = new DefiAPI({ chainId }, 12000)\n    LoopringAPI.contactAPI = new ContactAPI({ chainId }, 15000)\n    LoopringAPI.vaultAPI = new VaultAPI({ chainId }, 15000)\n    LoopringAPI.rabbitWithdrawAPI = new RabbitWithdrawAPI({ chainId }, 15000)\n    LoopringAPI.__chainId__ = chainId\n  }\n  public static setBaseURL = (baseURL: string, {\n    walletAPIURL,\n    rabbitWithdrawAPIURL\n  }: {\n    walletAPIURL?: string\n    rabbitWithdrawAPIURL?: string\n  }) => {\n    LoopringAPI.userAPI?.setBaseUrl(baseURL)\n    LoopringAPI.luckTokenAPI?.setBaseUrl(baseURL)\n    LoopringAPI.exchangeAPI?.setBaseUrl(baseURL)\n    LoopringAPI.globalAPI?.setBaseUrl(baseURL)\n    LoopringAPI.ammpoolAPI?.setBaseUrl(baseURL)\n    LoopringAPI.walletAPI?.setBaseUrl(walletAPIURL ? walletAPIURL : baseURL)\n    LoopringAPI.wsAPI?.setBaseUrl(baseURL)\n    LoopringAPI.nftAPI?.setBaseUrl(baseURL)\n    LoopringAPI.delegate?.setBaseUrl(baseURL)\n    LoopringAPI.defiAPI?.setBaseUrl(baseURL)\n    LoopringAPI.contactAPI?.setBaseUrl(baseURL)\n    LoopringAPI.vaultAPI?.setBaseUrl(baseURL)\n    LoopringAPI.rabbitWithdrawAPI?.setBaseUrl(rabbitWithdrawAPIURL ? rabbitWithdrawAPIURL : baseURL)\n  }\n}\n\nexport { getContractTypeByNetwork } from './wallet'"
  },
  {
    "path": "packages/core/src/api_wrapper/wallet.ts",
    "content": "import { ContractType } from \"@loopring-web/loopring-sdk\";\nimport { LoopringAPI } from \"./\"\n\nexport const getContractTypeByNetwork = async ( wallet: string ,network?: string) => {\n  const res = await LoopringAPI.walletAPI!.getContractType({\n    wallet: wallet\n  })\n  const data = (res.raw_data as any).data as ContractType[]\n  if (network && data?.find(ele => ele.network === network)) {\n    return data?.find(ele => ele.network === network);\n  } else {\n    return data && data[0]\n  }\n}"
  },
  {
    "path": "packages/core/src/component/BtnConnect.tsx",
    "content": "import { withTranslation } from 'react-i18next'\nimport { accountStaticCallBack, btnClickMap, btnLabel, isCoinbaseSmartWallet, LoopringAPI, store, useAccount, useSystem, useUpdateAccount } from '../index'\nimport {\n  Button,\n  useSettings,\n  ButtonProps,\n  useOpenModals,\n  AccountStep,\n} from '@loopring-web/component-lib'\nimport React from 'react'\nimport _ from 'lodash'\n\nimport {\n  coinbaseSmartWalletChains,\n  fnType,\n  i18n,\n  L1L2_NAME_DEFINED,\n  LoadingIcon,\n  MapChainId,\n  SagaStatus,\n} from '@loopring-web/common-resources'\nimport { ChainId, NetworkWallet, toBig } from '@loopring-web/loopring-sdk'\nimport { useAppKit } from '@reown/appkit/react'\n\nexport const WalletConnectL2Btn = withTranslation(['common'], {\n  withRef: true,\n})(({ t, btnLabelProps = {}, btnClickMapProps = {}, className, size = 'large', width }: any) => {\n  const { status: accountStatus, account } = useAccount()\n  const { defaultNetwork } = useSettings()\n  const { app, exchangeInfo } = useSystem()\n\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n\n  const _btnLabel = Object.assign(_.cloneDeep(btnLabel), {\n    [fnType.ERROR_NETWORK]: [\n      function () {\n        return `labelWrongNetwork`\n      },\n    ],\n    ...btnLabelProps,\n  })\n\n\n  const labelUI = React.useMemo(() => {\n    if (!exchangeInfo || ![SagaStatus.UNSET, SagaStatus.DONE].includes(accountStatus))\n      return <LoadingIcon style={{ width: 18, height: 18, color: 'var(--color-text-button)' }} />\n    return t(\n      accountStaticCallBack(_btnLabel, [\n        {\n          chainId: defaultNetwork,\n          isEarn: app === 'earn',\n          readyState: account.readyState,\n        },\n      ]),\n      {\n        loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n        l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n        l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n        ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n      },\n    )\n  }, [accountStatus, account.readyState, i18n.language, defaultNetwork, app, exchangeInfo])\n\n  const _btnClickMap = Object.assign(_.cloneDeep({ ...btnClickMap, ...btnClickMapProps }), {})\n  const { setShowDeposit, setShowAccount } = useOpenModals()\n  const { goUpdateAccount } = useUpdateAccount()\n  return (\n    <Button\n      variant={'contained'}\n      size={size}\n      color={'primary'}\n      fullWidth={true}\n      style={{ maxWidth: '280px' }}\n      className={className}\n      sx={{\n        width: width\n      }}\n      onClick={() => {\n        accountStaticCallBack(_btnClickMap, [{\n          chainId: defaultNetwork,\n          isEarn: app === 'earn',\n          readyState: account.readyState,\n          specialActivation: async () => {\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.UpdateAccount_Approve_WaitForAuth\n            })\n            const {account} = store.getState()\n            const [walletType, coinbaseSW] = await Promise.all([\n              LoopringAPI?.walletAPI?.getWalletType({\n                wallet: account.accAddress,\n                network: MapChainId[defaultNetwork] as NetworkWallet,\n              }),\n              isCoinbaseSmartWallet(account.accAddress, defaultNetwork as ChainId),\n            ])\n\n            const isActivationSupported =\n              !walletType?.walletType?.isContract ||\n              (coinbaseSW && coinbaseSmartWalletChains.includes(defaultNetwork))\n            if (!isActivationSupported) {\n              setShowAccount({\n                isShow: true,\n                step: AccountStep.UpdateAccount_SmartWallet_NotSupported_Alert\n              })\n              return \n            }\n            \n            const feeInfo = await LoopringAPI?.globalAPI?.getActiveFeeInfo({\n              accountId: account._accountIdNotActive,\n            })\n            \n            const { userBalances } = await LoopringAPI?.globalAPI?.getUserBalanceForFee({\n              accountId: account._accountIdNotActive!,\n            })\n\n            const found = Object.keys(feeInfo.fees).find((key) => {\n              const fee = feeInfo.fees[key].fee\n              const foundBalance = userBalances[feeInfo.fees[key].tokenId]\n              return (foundBalance && toBig(foundBalance.total).gte(fee)) || toBig(fee).eq('0')\n            })\n            await goUpdateAccount({\n              isFirstTime: true,\n              isReset: false,\n              // @ts-ignore\n              feeInfo: {\n                token: feeInfo.fees[found!].fee,\n                belong: found!,\n                fee: feeInfo.fees[found!].fee,\n                feeRaw: feeInfo.fees[found!].fee,\n              },\n            })\n          },\n          specialActivationDeposit: async () => {\n            const {account} = store.getState()\n            const [walletType, coinbaseSW] = await Promise.all([\n              LoopringAPI?.walletAPI?.getWalletType({\n                wallet: account.accAddress,\n                network: MapChainId[defaultNetwork] as NetworkWallet,\n              }),\n              isCoinbaseSmartWallet(account.accAddress, defaultNetwork as ChainId),\n            ])\n\n            const isActivationSupported =\n              !walletType?.walletType?.isContract ||\n              (coinbaseSW && coinbaseSmartWalletChains.includes(defaultNetwork))\n            if (!isActivationSupported) {\n              setShowAccount({\n                isShow: true,\n                step: AccountStep.UpdateAccount_SmartWallet_NotSupported_Alert\n              })\n              return \n            }\n            setShowDeposit({isShow: true})\n          },\n          exchangeInfoLoaded: exchangeInfo ? true : false\n        }])\n      }}\n    >\n      {labelUI}\n    </Button>\n  )\n}) as (props: ButtonProps & { [key: string]: any }) => JSX.Element\n\nexport const BtnConnectL1 = withTranslation(['common', 'layout'], {\n  withRef: true,\n})(({ t }: any) => {\n  const {\n    status: accountStatus,\n    account: { readyState },\n  } = useAccount()\n  const {\n    exchangeInfo\n  } = useSystem()\n  const labelUI = React.useMemo(() => {\n    if (!exchangeInfo || accountStatus !== SagaStatus.UNSET) return <LoadingIcon style={{ width: 18, height: 18, color: 'var(--color-text-button)' }} />\n    return t(\n      accountStatus === SagaStatus.UNSET\n        ? accountStaticCallBack(Object.assign(_.cloneDeep(btnLabel)))\n        : 'labelConnectWallet',\n      {\n        loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n        l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n        l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n        ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n      },\n    )\n  }, [accountStatus, exchangeInfo])\n  \n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const modal = useAppKit()\n\n  return (\n    <>\n      <Button\n        variant={'contained'}\n        size={'large'}\n        color={'primary'}\n        fullWidth={true}\n        style={{ maxWidth: '280px' }}\n        onClick={() => {\n          modal.open()\n        }}\n      >\n        {labelUI}\n      </Button>\n    </>\n  )\n}) as typeof Button\n"
  },
  {
    "path": "packages/core/src/component/NotificationItem.tsx",
    "content": "import React from 'react'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { useHistory } from 'react-router-dom'\nimport { Button, useSettings } from '@loopring-web/component-lib'\nimport {\n  ConvertToIcon,\n  L1L2_NAME_DEFINED,\n  Layer2RouterID,\n  MapChainId,\n  MessageIcon,\n  RouterPath,\n} from '@loopring-web/common-resources'\nimport { useTranslation } from 'react-i18next'\nimport { Box, IconButton, Link, Snackbar, Typography } from '@mui/material'\nimport moment from 'moment'\nimport styled from '@emotion/styled'\nimport { useNotification, useNotificationFunc } from '../hooks'\n\nconst BoxStyle = styled(Box)`\n  .point {\n    right: 4px;\n    top: 4px;\n    position: absolute;\n    width: 8px;\n    height: 8px;\n    background: var(--color-error);\n    border-radius: 50%;\n  }\n  &.headerItem {\n    padding: 0;\n    .MuiGrid-item {\n      padding: 0;\n    }\n    .message {\n      word-wrap: break-word;\n      text-overflow: ellipsis;\n      overflow: hidden;\n      white-space: nowrap;\n      width: 274px;\n      display: inline-block;\n      margin-top: ${({ theme }) => (1 / 2) * theme.unit}px;\n      svg {\n        display: none;\n      }\n    }\n    .time {\n      margin-top: ${({ theme }) => (1 / 2) * theme.unit}px;\n      font-size: ${({ theme }) => theme.fontDefault.body2};\n    }\n    .point {\n      width: 4px;\n      height: 4px;\n      right: 0;\n      top: 0;\n    }\n  }\n`\nexport const NoticePop = ({\n  isShow,\n  setNotificationPush,\n  ...rest\n}: sdk.UserNotification & {\n  isShow: boolean\n  setNotificationPush: (props: { isShow: boolean; item: any }) => void\n}) => {\n  const history = useHistory()\n  const { t } = useTranslation()\n  const { onReadClick } = useNotificationFunc({})\n  // const [open, setOpen] = React.useState(false)\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n\n  const handleClose = () => {\n    onReadClick(0, rest)\n    setNotificationPush({ isShow: false, item: null })\n  }\n  const ele = useNotification({\n    ...rest,\n    index: 0,\n    onReadClick,\n  })\n  const actionEle = React.useMemo(() => {\n    return (\n      <Box display={'inline-flex'} justifyContent={'flex-end'} flexDirection={'row-reverse'}>\n        <Button\n          sx={{ marginLeft: 1 }}\n          variant={'contained'}\n          size={'small'}\n          color={'primary'}\n          onClick={() => {\n            ele?.active\n              ? ele?.active()\n              : history.push(`/#${RouterPath.layer2}/${Layer2RouterID.notification}`)\n            handleClose()\n          }}\n        >\n          {t('labelDetail')}\n        </Button>\n        <Button\n          sx={{ marginLeft: 1 }}\n          variant={'text'}\n          size={'medium'}\n          onClick={() => {\n            handleClose()\n          }}\n        >\n          {t('labelClose')}\n        </Button>\n      </Box>\n    )\n  }, [ele])\n  return (\n    <Snackbar\n      open={isShow}\n      autoHideDuration={20000}\n      ContentProps={{\n        sx: {\n          flexDirection: 'column',\n        },\n      }}\n      sx={{\n        pointerEvents: 'all',\n        flexDirection: 'column',\n        top: '80% !important',\n        height: 'fit-content',\n        '.MuiPaper-root': { background: 'var(--color-pop-bg)' },\n      }}\n      onClose={handleClose}\n      message={\n        <Box\n          display={'flex'}\n          flexDirection={'column'}\n          justifyContent={'start'}\n          alignItems={'flex-start'}\n        >\n          <Typography variant={'body1'} color={'textSecondary'}>\n            {t(ele.i18nKey, {\n              l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n              l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n              l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n              ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n            })}\n          </Typography>\n          <Typography variant={'body1'} color={'textPrimary'} marginTop={1} className={'message'}>\n            {rest.message}\n          </Typography>\n\n          <Typography\n            variant={'body1'}\n            color={'textSecondary'}\n            marginTop={1}\n            textAlign={'center'}\n            className={'time'}\n          >\n            {t('labelNotificationTime', {\n              time: moment(rest.createAt).fromNow(),\n              interpolation: {\n                escapeValue: false,\n              },\n            })}\n          </Typography>\n        </Box>\n      }\n      action={actionEle}\n      anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}\n    />\n  )\n}\n\nexport const NotificationItem = React.memo(\n  ({\n    index,\n    onReadClick,\n    className = '',\n    size = 'large',\n    noAction = false,\n    ...rest\n  }: sdk.UserNotification & {\n    index: number\n    className?: string\n    noAction?: boolean\n    size?: 'small' | 'medium' | 'large'\n    onReadClick?: (index: number, rest: any) => void\n  }) => {\n    const { message, createAt } = rest\n    const { defaultNetwork } = useSettings()\n    const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n    const { t } = useTranslation()\n    const { onReadClick: defaultOnRead } = useNotificationFunc({})\n    const ele = useNotification({\n      index,\n      onReadClick: defaultOnRead,\n      ...rest,\n    })\n    const _onReadIconClick = onReadClick ? onReadClick : defaultOnRead\n    return (\n      <BoxStyle display={'flex'} justifyContent={'stretch'} paddingY={1} className={className}>\n        <Box position={'relative'} marginRight={2}>\n          <IconButton\n            disabled={rest.read}\n            color={'secondary'}\n            size={size}\n            onClick={() => {\n              _onReadIconClick(index, rest)\n            }}\n          >\n            <MessageIcon color={'inherit'} />\n          </IconButton>\n          {!rest.read && <Typography className={'point'} component={'i'} display={'block'} />}\n        </Box>\n        <Box\n          onClick={() => noAction && onReadClick && onReadClick(index, rest)}\n          flex={1}\n          display={'flex'}\n          flexDirection={'column'}\n          alignItems={'flex-start'}\n        >\n          <Typography variant={'body1'} color={'textSecondary'}>\n            {t(ele.i18nKey, {\n              l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n              loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n              l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n              l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n              ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n            })}\n          </Typography>\n          {!noAction && ele.active ? (\n            <Link\n              variant={'body1'}\n              color={'textPrimary'}\n              marginTop={1}\n              onClick={() => ele.active()}\n              className={'message'}\n              display={'inline-flex'}\n              justifyContent={'space-between'}\n              alignItems={'center'}\n              width={'100%'}\n            >\n              <span>{message}</span>\n              <ConvertToIcon fontSize={'medium'} color={'inherit'} />\n            </Link>\n          ) : (\n            <Typography variant={'body1'} color={'textPrimary'} marginTop={1} className={'message'}>\n              {message}\n            </Typography>\n          )}\n          <Typography\n            variant={'body1'}\n            color={'textSecondary'}\n            marginTop={1}\n            textAlign={'center'}\n            className={'time'}\n          >\n            {t('labelNotificationTime', {\n              time: moment(createAt).fromNow(),\n              interpolation: {\n                escapeValue: false,\n              },\n            })}\n          </Typography>\n        </Box>\n      </BoxStyle>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/core/src/component/index.ts",
    "content": "export * from './BtnConnect'\nexport * from './styled'\nexport * from './NotificationItem'\n"
  },
  {
    "path": "packages/core/src/component/styled.ts",
    "content": "import styled from '@emotion/styled'\nimport { Box, Grid } from '@mui/material'\nimport { TablePaddingX } from '@loopring-web/component-lib'\nimport { LAYOUT } from '../defs'\n\nexport const StylePaper = styled(Box)`\n  display: flex;\n  flex-direction: column;\n  width: 100%;\n  flex: 1;\n  background: var(--color-box-third);\n  border-radius: ${({ theme }) => theme.unit}px;\n  margin-bottom: ${({ theme }) => 2 * theme.unit}px;\n  .title {\n    font-size: ${({ theme }) => theme.unit * 3}px;\n    margin-left: ${({ theme }) => 3 * theme.unit}px;\n    margin-top: ${({ theme }) => 3 * theme.unit}px;\n  }\n\n  .tableWrapper {\n    display: flex;\n    margin-top: ${({ theme }) => 3 * theme.unit}px;\n    flex: 1;\n    .rdg {\n      flex: 1;\n    }\n  }\n\n  .extraTradeClass {\n    .rdg-header-row {\n      background-color: inherit !important;\n    }\n  }\n` as typeof Box\n\nexport const TableWrapStyled = styled(Box)`\n  & {\n    .toolbar {\n      padding: 0;\n    }\n    border-radius: ${({ theme }) => theme.unit}px;\n    .rdg {\n      .rdg-header-row {\n        border-radius: ${({ theme }) => theme.unit}px ${({ theme }) => theme.unit}px 0 0;\n      }\n    }\n  }\n\n  &.min-height .rdg {\n    min-height: initial;\n  }\n\n  & .min-height .rdg {\n    min-height: initial;\n  }\n\n  ${({ theme }) => TablePaddingX({ pLeft: theme.unit * 3, pRight: theme.unit * 3 })};\n  &.fixed {\n    position: relative;\n    .toolbar {\n      position: fixed;\n      top: ${LAYOUT.HEADER_HEIGHT}px;\n      @media (min-width: 1200px) {\n        max-width: calc(1200px - 48px);\n      }\n      max-width: calc(100% - ${({ theme }) => 6 * theme.unit}px);\n      z-index: 209;\n      background: var(--color-box);\n    }\n  }\n` as typeof Grid\n\nexport const TableProWrapStyled = styled(Box)`\n  & {\n    .toolbar {\n      padding: 0;\n    }\n    background: var(--color-pop-bg);\n    border-radius: ${({ theme }) => theme.unit}px;\n    .rdg {\n      .rdg-header-row {\n        border-radius: ${({ theme }) => theme.unit}px ${({ theme }) => theme.unit}px 0 0;\n        background: var(--color-pop-bg) !important;\n      }\n    }\n  }\n  ${({ theme }) => TablePaddingX({ pLeft: theme.unit * 3, pRight: theme.unit * 3 })};\n  &.fixed {\n    position: relative;\n    .toolbar {\n      position: fixed;\n      top: ${LAYOUT.HEADER_HEIGHT}px;\n      @media (min-width: 1200px) {\n        max-width: calc(1200px - 48px);\n      }\n\n      max-width: calc(100% - ${({ theme }) => 6 * theme.unit}px);\n      z-index: 209;\n      background: var(--color-box);\n    }\n  }\n` as typeof Grid\nexport const FixedStyle = styled(Box)`\n  @media only screen and (min-height: 784px) and (min-width: 1024px) {\n    position: fixed;\n  }\n` as typeof Box\n//    ${({theme}) => theme.border.defaultFrame({c_key: 'blur', d_R: 1})};\n"
  },
  {
    "path": "packages/core/src/defs/index.ts",
    "content": "import * as sdk from '@loopring-web/loopring-sdk'\n\nexport enum ActionResultCode {\n  NoError,\n  DataNotReady,\n  GetAccError,\n  GenEddsaKeyError,\n  UpdateAccountError,\n}\n\nexport type EddsaKey = { eddsaKey: any; accInfo?: sdk.AccountInfo }\n\nexport const LAYOUT = {\n  HEADER_HEIGHT: 64,\n  FOOT_COMMON_HEIGHT: 48,\n}\n\nexport const REFRESH_RATE = 1000\n\nexport const DAYS = 30\n\nexport const BIGO = sdk.toBig(0)\n\nexport const MAPFEEBIPS = 200\n"
  },
  {
    "path": "packages/core/src/hookConnect.tsx",
    "content": "import React from 'react'\nimport {\n  OutlineSelect,\n  OutlineSelectItem,\n  setShowAccount,\n  useOpenModals,\n  useSettings,\n  WalletConnectStep,\n} from '@loopring-web/component-lib'\nimport {\n  ConnectProviders,\n  connectProvides,\n  ErrorType,\n  ProcessingStep,\n  ProcessingType,\n} from '@loopring-web/web3-provider'\nimport {\n  AccountStatus,\n  BaseIcon,\n  ChainETHEREUMIcon,\n  ChainGOERLIIcon,\n  ChainTAIKOIcon,\n  DoneIcon,\n  DropDownIcon,\n  L1L2_NAME_DEFINED,\n  MapChainId,\n  myLog,\n  NetworkMap,\n  SagaStatus,\n  SoursURL,\n  SPECIAL_ACTIVATION_NETWORKS,\n  ThemeType,\n  UIERROR_CODE,\n} from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { accountReducer, useAccount } from './stores/account'\nimport { resetDepositData, resetTransferData, resetWithdrawData, useModalData, useSystem } from './stores'\nimport { checkAccount, networkUpdate, resetLayer12Data, useConnectHook } from './services'\nimport { REFRESH_RATE } from './defs'\nimport { createImageFromInitials, store, WalletConnectL2Btn } from './index'\nimport { useTranslation } from 'react-i18next'\nimport { Avatar, Box, Button, Modal, SelectChangeEvent, Typography } from '@mui/material'\nimport { updateAccountStatus } from './stores/account/reducer'\nimport styled from '@emotion/styled'\nimport { useAppKit } from '@reown/appkit/react'\n\nexport const OutlineSelectStyle = styled(OutlineSelect)`\n  &.walletModal {\n    background: var(--field-opacity);\n    height: var(--row-height);\n  }\n\n  .MuiAvatar-root {\n    background: var(--color-white);\n    margin-right: ${({ theme }) => theme.unit}px;\n    width: 20px;\n    height: 20px;\n    position: relative;\n\n    svg {\n      position: absolute;\n      width: 18px;\n      height: 18px;\n      left: 50%;\n      top: 50%;\n      transform: translate(-50%, -50%);\n    }\n  }\n\n  &.test .MuiSelect-outlined .label {\n    display: inline-flex;\n\n    &:after {\n      color: var(--network-text);\n      content: ' test';\n      padding-left: 0.5em;\n      display: inline-flex;\n      font-size: var(body2);\n    }\n  }\n\n  .MuiSelect-outlined.MuiSelect-outlined {\n    padding-right: ${({ theme }) => theme.unit * 3}px;\n    padding-left: ${({ theme }) => theme.unit * 3}px;\n    display: inline-flex;\n    align-items: center;\n  }\n\n  &.mobile .MuiSelect-outlined.MuiSelect-outlined {\n    padding-left: 0px;\n    padding-right: ${({ theme }) => theme.unit * 2}px;\n  }\n\n  &.header {\n    .MuiSelect-outlined {\n    }\n\n    &.mobile {\n      .MuiAvatar-root {\n        display: flex;\n      }\n\n      .label {\n        display: none;\n      }\n\n      padding-left: 0;\n      padding-right: ${({ theme }) => theme.unit * 4}px;\n      position: relative;\n    }\n  }\n` as typeof OutlineSelect\nexport const OutlineSelectItemStyle = styled(OutlineSelectItem)`\n  .MuiAvatar-root {\n    width: 24px;\n    height: 24px;\n\n    svg {\n      width: 20px;\n      height: 20px;\n    }\n\n    background: var(--color-white);\n    margin-right: ${({ theme }) => theme.unit}px;\n  }\n\n  &.provider-test .label {\n    &:after {\n      content: ' test';\n      padding-left: 0.5em;\n      display: inline-flex;\n      font-size: var(body2);\n      color: var(--network-text);\n    }\n  }\n` as typeof OutlineSelectItem\nconst Icon = ({ label = '' }: { label: string }) => {\n  switch (label) {\n    case 'GOERLI':\n      return (\n        <Box component={'span'} display={'flex'} alignItems={'center'}>\n          <ChainGOERLIIcon style={{width: 20, height: 20}} />\n        </Box>\n      )\n    case 'ETHEREUM':\n      return (\n        <Box component={'span'} display={'flex'} alignItems={'center'}>\n          <ChainETHEREUMIcon style={{width: 20, height: 20}} /> \n        </Box>\n      )\n    case 'SEPOLIA':\n      return (\n        <Box component={'span'} display={'flex'} alignItems={'center'}>\n          <Box component={'img'} src={createImageFromInitials(20, 'Sepolia', '#56a7c9')}/> \n        </Box>\n      )\n    case 'TAIKO':\n      return (\n        <Box component={'span'} display={'flex'} alignItems={'center'}>\n          <ChainTAIKOIcon style={{width: 20, height: 20}} />\n        </Box>\n      )\n    case 'TAIKOHEKLA':\n      return (\n        <Box component={'span'} display={'flex'} alignItems={'center'}>\n          <Box component={'img'} src={createImageFromInitials(20, 'TAIKOHEKLA', '#E91898')}/> \n        </Box>\n      )\n    case 'BASE':\n      return (\n        <Box component={'span'} display={'flex'} alignItems={'center'}>\n          <BaseIcon style={{width: 20, height: 20}} />\n        </Box>\n      )\n    case 'BASESEPOLIA':\n      return (\n        <Box component={'span'} display={'flex'} alignItems={'center'}>\n          <Box component={'img'} src={createImageFromInitials(20, 'BASESEPOLIA', '#E91898')}/> \n        </Box>\n      )\n    default:\n      const child = label.split(' ')?.map((item) => item[0])\n      return <Avatar component={'span'} variant='circular' children={child} />\n  }\n}\nconst onConnect = async (accAddress: string, chainId: any) => {\n  const {\n    settings: { defaultNetwork },\n    account: { readyState, accAddress: _accAddress },\n  } = store.getState()\n  if (\n    _accAddress?.toLowerCase() === accAddress?.toUpperCase() &&\n    defaultNetwork.toString() == chainId.toString() &&\n    [\n      AccountStatus.NO_ACCOUNT,\n      AccountStatus.DEPOSITING,\n      AccountStatus.NOT_ACTIVE,\n      AccountStatus.LOCKED,\n    ].includes(readyState as AccountStatus)\n  ) {\n    myLog('After connect >>,onChinId change')\n  } else {\n    myLog('After connect >>,network part start: step1 networkUpdate')\n    store.dispatch(updateAccountStatus({ _chainId: chainId }))\n    const networkFlag = await networkUpdate(chainId)\n    if (networkFlag) {\n      resetLayer12Data()\n      checkAccount(accAddress, chainId !== 'unknown' ? chainId : undefined)\n    }\n    store.dispatch(resetWithdrawData(undefined))\n    store.dispatch(resetTransferData(undefined))\n    store.dispatch(resetDepositData(undefined))\n  }\n}\nconst onDisConnect = async () => {\n  resetLayer12Data()\n  store.dispatch(resetWithdrawData(undefined))\n  store.dispatch(resetTransferData(undefined))\n  store.dispatch(resetDepositData(undefined))\n}\nexport const callSwitchChain = async (_chainId: string | number) => {\n  const { defaultNetwork, themeMode } = store.getState().settings\n  if (Number(defaultNetwork) !== Number(_chainId)) {\n    try {\n      await connectProvides.sendChainIdChange(defaultNetwork, themeMode === ThemeType.dark)\n    } catch (error) {\n      throw { code: UIERROR_CODE.ERROR_SWITCH_ETHEREUM }\n    }\n    if (defaultNetwork && Number(defaultNetwork) !== Number(await connectProvides?.usedWeb3?.eth?.getChainId())) {\n      throw { code: UIERROR_CODE.ERROR_SWITCH_ETHEREUM }\n    }\n  }\n}\n\nexport const useSelectNetwork = ({ className }: { className?: string }) => {\n  const { t } = useTranslation()\n  const { defaultNetwork: _defaultNetwork, isMobile } = useSettings()\n  const {\n    account: { connectName, accAddress },\n  } = useAccount()\n  const [defaultNetwork, setDefaultNetwork] = React.useState<number | undefined>(_defaultNetwork)\n\n  const handleOnNetworkSwitch = React.useCallback(\n    async (value: sdk.ChainId) => {\n      myLog('defaultNetwork', value)\n      const account = store.getState().account\n      setDefaultNetwork((state) => {\n        if (Number(value) !== Number(state)) {\n          if (account.readyState !== AccountStatus.UN_CONNECT) {\n            if (connectProvides?.usedWeb3 && connectProvides.usedProvide) {\n              onConnect(account.accAddress, value)\n            } else {\n              onDisConnect()\n              return state\n            }\n          } else {\n            networkUpdate(Number(value))\n          }\n        }\n        return value\n      })\n    },\n    [defaultNetwork],\n  )\n  React.useEffect(() => {\n    setDefaultNetwork((state) => {\n      if (_defaultNetwork && state !== _defaultNetwork) {\n        networkUpdate()\n        return Number(_defaultNetwork)\n      } else {\n        return state\n      }\n    })\n  }, [_defaultNetwork])\n\n  const disable = React.useCallback(\n    (id: any) => {\n      myLog(connectName, ConnectProviders.WalletConnect)\n      if (connectName == ConnectProviders.GameStop.toString()) {\n        return ![1, 5].includes(Number(id))\n      } else if (\n        (connectProvides.usedProvide as any)?.session &&\n        (connectProvides.usedProvide as any)?.namespace\n      ) {\n        // @ts-ignore\n        const optionalChains = connectProvides.usedProvide?.session?.namespaces[\n          (connectProvides.usedProvide as any).namespace\n        ]?.chains ?? [`${(connectProvides.usedProvide as any).namespace}:${defaultNetwork}`]\n        return !optionalChains.includes(\n          `${(connectProvides.usedProvide as any).namespace}:${Number(id)}`,\n        )\n      }\n      return false\n    },\n    [connectName, connectProvides.usedProvide, defaultNetwork],\n  )\n  const { open } = useAppKit()\n  const NetWorkItems: JSX.Element = React.useMemo(() => {\n    myLog('defaultNetwork NetWorkItems', defaultNetwork)\n    \n    return (\n      <>\n        {defaultNetwork && NetworkMap[defaultNetwork] && (\n          <OutlineSelectItemStyle\n            sx={{ \n              cursor: 'pointer',\n              borderRadius: '4px',\n              marginRight: 1,\n              border: '1px solid var(--color-border)',\n              height: isMobile ? '32px' : '36px',\n              minHeight: isMobile ? '32px' : '36px',\n              paddingX: isMobile ? 1 : undefined,\n            }}\n            onClick={() => open({ view: 'Networks' })}\n            disabled={disable(defaultNetwork)}\n            className={`viewNetwork${defaultNetwork} ${\n              NetworkMap[defaultNetwork]?.isTest ? 'provider-test' : ''\n            }`}\n            aria-label={NetworkMap[defaultNetwork].label}\n            value={defaultNetwork}\n          >\n            <Typography component={'span'} display={'inline-flex'} alignItems={'center'}>\n              <Icon label={MapChainId[defaultNetwork]} />\n            </Typography>\n            <DropDownIcon sx={{marginLeft: 0.5}} />\n          </OutlineSelectItemStyle>\n        )}\n      </>\n    )\n  }, [defaultNetwork, NetworkMap, connectName, connectProvides.usedProvide, accAddress])\n  React.useEffect(() => {}, [])\n\n  return {\n    NetWorkItems,\n    handleOnNetworkSwitch,\n  }\n}\n\nexport function useConnect(_props: { state: keyof typeof SagaStatus }) {\n  const {\n    account,\n    shouldShow,\n    resetAccount,\n    statusUnset: statusAccountUnset,\n    setShouldShow,\n    status: accountStatus,\n  } = useAccount()\n  // const {updateWalletLayer2, resetLayer2} = useWalletLayer2()\n\n  const { resetWithdrawData, resetTransferData, resetDepositData } = useModalData()\n\n  const { setShowConnect } = useOpenModals()\n  const [stateAccount, setStateAccount] = React.useState<keyof typeof SagaStatus>('DONE')\n  React.useEffect(() => {\n    if (stateAccount === SagaStatus.PENDING && accountStatus === SagaStatus.DONE) {\n      setStateAccount('DONE')\n      statusAccountUnset()\n    }\n  }, [stateAccount, accountStatus])\n  const handleConnect = React.useCallback(\n    async ({\n      accounts,\n      chainId,\n    }: {\n      accounts: string\n      provider: any\n      chainId: sdk.ChainId | 'unknown'\n    }) => {\n      const accAddress = accounts[0]\n      await onConnect(accAddress, chainId)\n      setShouldShow(false)\n      setShowConnect({\n        isShow: !!shouldShow ?? false,\n        step: WalletConnectStep.SuccessConnect,\n      })\n      await sdk.sleep(REFRESH_RATE)\n      setShowConnect({ isShow: false, step: WalletConnectStep.SuccessConnect })\n    },\n    [\n      resetWithdrawData,\n      resetTransferData,\n      resetDepositData,\n      setShouldShow,\n      setShowConnect,\n      shouldShow,\n    ],\n  )\n\n  const handleAccountDisconnect = React.useCallback(\n    async ({ reason, code }: { reason?: string; code?: number }) => {\n      myLog('handleAccountDisconnect:', account, reason, code)\n      resetAccount({ shouldUpdateProvider: true })\n      setStateAccount(SagaStatus.PENDING)\n      onDisConnect()\n    },\n    [account],\n  )\n\n  const handleProcessing = React.useCallback(\n    ({ opts, type }: { type: ProcessingType; opts: any }) => {\n      if (type == ProcessingType.nextStep) {\n        if (opts.step !== undefined && opts.step == ProcessingStep.showQrcode) {\n          store.dispatch(accountReducer.updateAccountStatus({ qrCodeUrl: opts.QRcode }))\n          setShowConnect({\n            isShow: false,\n          })\n        } else {\n          const { qrCodeUrl } = opts\n          if (qrCodeUrl) {\n            store.dispatch(accountReducer.updateAccountStatus({ qrCodeUrl }))\n            setShowConnect({\n              isShow: true,\n              step: WalletConnectStep.WalletConnectQRCode,\n            })\n          }\n        }\n      }\n      // const { qrCodeUrl } = opts;\n    },\n    [setShowConnect],\n  )\n\n  const handleError = React.useCallback(\n    (props: { type: keyof typeof ErrorType; opts?: any }) => {\n      if (!!account.accAddress) {\n        myLog('try to resetAccount...')\n        resetAccount()\n      }\n\n      statusAccountUnset()\n      setShowAccount({ isShow: false })\n      if (props?.opts?.error?.code === -32002) {\n      } else if (\n        props?.opts?.connectName === ConnectProviders.WalletConnect &&\n        props?.opts?.error &&\n        props?.opts?.error?.code === UIERROR_CODE.ERROR_WALLECTCONNECT_MANUALLY_CLOSE\n      ) {\n        setShowConnect({ isShow: false })\n      } else {\n      }\n    },\n    [\n      account._chainId,\n      account.accAddress,\n      shouldShow,\n      statusAccountUnset,\n      setShowConnect,\n      resetAccount,\n    ],\n  )\n\n  useConnectHook({\n    handleAccountDisconnect,\n    handleProcessing,\n    handleError,\n    handleConnect,\n  })\n}\nconst ViewAccountTemplateStyle = styled(Box)`\n  &.inModal,\n  &.inBlock {\n    > .MuiTypography-root {\n      font-size: ${({ theme }) => theme.fontDefault.body1};\n      line-height: 1.2em;\n      font-weight: 400;\n    }\n    > h1.MuiTypography-root {\n      font-size: ${({ theme }) => theme.fontDefault.h5};\n      line-height: 1.2em;\n      font-weight: 500;\n    }\n  }\n`\nexport const ViewAccountTemplate = React.memo(\n  ({\n    activeViewTemplate,\n    className,\n    size = 'large'\n  }: {\n    activeViewTemplate: JSX.Element\n    className?: string\n    size?: string\n    onClickCompleteSignIn?: () => void\n  }) => {\n    const { account } = useAccount()\n    const { t } = useTranslation(['common', 'layout'])\n    const { isMobile, defaultNetwork } = useSettings()\n    const { app } = useSystem()\n    const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n\n    const isSpecialActivation = app === 'earn' && SPECIAL_ACTIVATION_NETWORKS.includes(defaultNetwork)\n\n    const viewTemplate = React.useMemo(() => {\n      switch (account.readyState) {\n        case AccountStatus.UN_CONNECT:\n          return (\n            <ViewAccountTemplateStyle\n              flex={1}\n              className={className}\n              display={'flex'}\n              justifyContent={'center'}\n              flexDirection={'column'}\n              alignItems={'center'}\n              maxWidth={'calc(1200px - 32px)'}\n              alignSelf={'center'}\n            >\n              <Typography\n                maxWidth={'1156px'}\n                marginY={3}\n                variant={isMobile ? 'h4' : 'h1'}\n                textAlign={'center'}\n              >\n                {t('describeTitleConnectToWallet', {\n                  layer2: L1L2_NAME_DEFINED[network].layer2,\n                  l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                })}\n              </Typography>\n              <WalletConnectL2Btn size={size} />\n            </ViewAccountTemplateStyle>\n          )\n          break\n        case AccountStatus.LOCKED:\n          return (\n            <ViewAccountTemplateStyle\n              flex={1}\n              className={className}\n              display={'flex'}\n              justifyContent={'center'}\n              flexDirection={'column'}\n              alignItems={'center'}\n              maxWidth={'calc(1200px - 32px)'}\n              alignSelf={'center'}\n            >\n              <Typography marginY={3} variant={isMobile ? 'h4' : 'h1'} textAlign={'center'}>\n                {t('describeTitleLocked')}\n              </Typography>\n              <WalletConnectL2Btn size={size} />\n            </ViewAccountTemplateStyle>\n          )\n          break\n        case AccountStatus.NO_ACCOUNT:\n          return (\n            <ViewAccountTemplateStyle\n              flex={1}\n              className={className}\n              display={'flex'}\n              justifyContent={'center'}\n              flexDirection={'column'}\n              alignItems={'center'}\n              maxWidth={isSpecialActivation ? 'calc(800px)' : 'calc(1200px - 32px)'}\n              alignSelf={'center'}\n            >\n              <Typography\n                marginY={3}\n                variant={isMobile ? 'h4' : 'h1'}\n                whiteSpace={'pre-line'}\n                textAlign={'center'}\n              >\n                {isSpecialActivation\n                  ? t('labelEarnDepositDes')\n                  : t('describeTitleNoAccount', {\n                      layer2: L1L2_NAME_DEFINED[network].layer2,\n                      loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                      l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                    })}\n              </Typography>\n              <WalletConnectL2Btn size={size} />\n            </ViewAccountTemplateStyle>\n          )\n          break\n        case AccountStatus.NOT_ACTIVE:\n          return (\n            <ViewAccountTemplateStyle\n              flex={1}\n              className={className}\n              display={'flex'}\n              justifyContent={'center'}\n              flexDirection={'column'}\n              alignItems={'center'}\n              maxWidth={isSpecialActivation ? 'calc(800px)' : 'calc(1200px - 32px)'}\n              alignSelf={'center'}\n            >\n              {isSpecialActivation ? (\n                <>\n                  <DoneIcon\n                    style={{ color: 'var(--color-success)', width: '64px', height: '64px' }}\n                  />\n                  <Typography marginY={3} variant={isMobile ? 'h4' : 'h1'} textAlign={'center'}>\n                    {t(\"labelAccountCreatedHint\")}\n                  </Typography>\n                  <WalletConnectL2Btn size={size} />\n                </>\n              ) : (\n                <>\n                  <Typography marginY={3} variant={isMobile ? 'h4' : 'h1'} textAlign={'center'}>\n                    {t('describeTitleNotActive', {\n                      layer2: 'Layer 2',\n                      loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                      l1ChainName: 'Ethereum',\n                    })}\n                  </Typography>\n                  <WalletConnectL2Btn size={size} />\n                </>\n              )}\n            </ViewAccountTemplateStyle>\n          )\n          break\n        case AccountStatus.DEPOSITING:\n          return (\n            <ViewAccountTemplateStyle\n              flex={1}\n              className={className}\n              display={'flex'}\n              justifyContent={'center'}\n              flexDirection={'column'}\n              alignItems={'center'}\n              maxWidth={isSpecialActivation ? 'calc(800px)' : 'calc(1200px - 32px)'}\n              alignSelf={'center'}\n            >\n              <img\n                className='loading-gif'\n                alt={'loading'}\n                width='60'\n                src={`${SoursURL}images/loading-line.gif`}\n              />\n              <Typography marginY={3} variant={isMobile ? 'h4' : 'h1'} textAlign={'center'}>\n                {isSpecialActivation\n                  ? t('labelEarnDepositDes')\n                  : t('describeTitleOpenAccounting', {\n                      l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                    })}\n              </Typography>\n            </ViewAccountTemplateStyle>\n          )\n          break\n        case AccountStatus.ERROR_NETWORK:\n          return (\n            <ViewAccountTemplateStyle\n              flex={1}\n              className={className}\n              display={'flex'}\n              justifyContent={'center'}\n              flexDirection={'column'}\n              alignItems={'center'}\n              maxWidth={'calc(1200px - 32px)'}\n              alignSelf={'center'}\n            >\n              <Typography marginY={3} variant={isMobile ? 'h4' : 'h1'} textAlign={'center'}>\n                {t('describeTitleOnErrorNetwork', {\n                  connectName: account.connectName,\n                })}\n              </Typography>\n            </ViewAccountTemplateStyle>\n          )\n          break\n        case AccountStatus.ACTIVATED:\n          return activeViewTemplate\n        default:\n          break\n      }\n    }, [account.readyState, account.connectName, isMobile, t, activeViewTemplate, isSpecialActivation])\n\n    return (\n      <>\n        {viewTemplate}\n      </>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/core/src/hooks/common/index.ts",
    "content": "export * from './useAddrCheck'\nexport * from './useAllowances'\nexport * from './useBtnStatus'\nexport * from './usePairMatch'\nexport * from './useToast'\nexport * from './useTrade'\nexport * from './useGetOrderHistorys'\nexport * from './useHookBtn'\nexport * from './useMyCollection'\nexport * from './useMyNFTCollection'\nexport * from './useCollectionManage'\nexport * from './useCollectionImport'\nexport * from './useNFT'\nexport * from './useIsHebao'\nexport * from './useNotification'\nexport * from './useInjectWeb3Modal'\nexport { useUserWallets } from './useUserWallets'\nexport { useThrottle } from './useThrottle'\nexport { useDebouncedCallback } from './useDebounce'\nexport { useMarket } from './useMarket'"
  },
  {
    "path": "packages/core/src/hooks/common/useAddrCheck.ts",
    "content": "import React from 'react'\nimport { connectProvides } from '@loopring-web/web3-provider'\nimport {\n  AddressError,\n  globalSetup,\n  myLog,\n  SDK_ERROR_MAP_TO_UI,\n  UIERROR_CODE,\n  NetworkMap,\n  CustomError,\n  ErrorMap,\n  HEBAO_CONTRACT_MAP,\n} from '@loopring-web/common-resources'\nimport _ from 'lodash'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { checkAddr } from '../../utils'\nimport { getContractTypeByNetwork, LoopringAPI, store, useAccount, useContacts, useSystem } from '../../index'\nimport { ToastType, useOpenModals, useSettings } from '@loopring-web/component-lib'\n\nexport const useAddressCheck = (checkLayer2Status: boolean = true) => {\n  const [address, setAddress] = React.useState<string>('')\n  const _address = React.useRef<string>('')\n  const { chainId } = useSystem()\n  const { defaultNetwork } = useSettings()\n  const [{ realAddr, ens, isENSWrong }, setRealAddr] = React.useState<{\n    realAddr: string\n    ens: string\n    isENSWrong: boolean\n  }>({\n    realAddr: '',\n    ens: '',\n    isENSWrong: false,\n  })\n  // const [ens, setENS] = React.useState<string>('')\n\n  const [addrStatus, setAddrStatus] = React.useState<AddressError>(AddressError.NoError)\n  const [checkAddAccountId, setCheckAddaccountId] = React.useState<number | undefined>()\n  const [isAddressCheckLoading, setIsAddressCheckLoading] = React.useState(false)\n  const [isLoopringAddress, setIsLoopringAddress] = React.useState(false)\n  const [isActiveAccount, setIsActiveAccount] = React.useState(false)\n  const [isActiveAccountFee, setIsActiveAccountFee] = React.useState<boolean | 'not allow'>(false)\n  const [isSameAddress, setIsSameAddress] = React.useState(false)\n  const [isCFAddress, setIsCFAddress] = React.useState(false)\n  const [isContractAddress, setIsContractAddress] = React.useState(false)\n  const [isContract1XAddress, setIsContract1XAddress] = React.useState(false)\n  const [loopringSmartWalletVersion, setLoopringSmartWalletVersion] = React.useState(\n    undefined as { isLoopringSmartWallet: boolean; version?: string } | undefined,\n  )\n  const { setShowGlobalToast } = useOpenModals()\n  const {\n    account: { accAddress, apiKey, accountId },\n  } = useAccount()\n  const { updateContacts } = useContacts()\n\n  const check = React.useCallback(async (address: any, web3: any) => {\n    try {\n      if (LoopringAPI.walletAPI && LoopringAPI.exchangeAPI) {\n        if (\n          /^0x[a-fA-F0-9]{40}$/g.test(address) ||\n          /.*\\.eth$/gi.test(address) ||\n          (/^\\d{5,8}$/g.test(address) && Number(address) > 10000)\n        ) {\n          myLog('address update ', address)\n          setIsAddressCheckLoading(true)\n          const { realAddr, addressErr, isContract, ens } = await checkAddr(address, web3)\n          if (_address.current == address) {\n            setRealAddr({ realAddr, ens, isENSWrong: false })\n            setAddrStatus(addressErr)\n            if (isContract) {\n              setIsContractAddress(isContract)\n            }\n            if (addressErr === AddressError.NoError) {\n              const [{ walletType }, response, _contractType] =\n                await Promise.all([\n                  LoopringAPI.walletAPI.getWalletType({\n                    wallet: realAddr,\n                    network: sdk.NetworkWallet[NetworkMap[defaultNetwork]?.walletType],\n                  }),\n                  LoopringAPI.exchangeAPI.getAccount({\n                    owner: realAddr,\n                  }),\n                  getContractTypeByNetwork(realAddr, sdk.NetworkWallet[NetworkMap[defaultNetwork]?.walletType])\n                ])\n              // for debounce & promise clean  (next user input sync function will cover by async)\n              if (_address.current == address) {\n                if (walletType && walletType?.isInCounterFactualStatus) {\n                  setIsCFAddress(true)\n                } else {\n                  setIsCFAddress(false)\n                }\n                if (walletType && walletType.isContract) {\n                  setIsContractAddress(true)\n                } else {\n                  setIsContractAddress(false)\n                }\n                if (walletType && walletType.loopringWalletContractVersion !== '') {\n                  setLoopringSmartWalletVersion({\n                    isLoopringSmartWallet: true,\n                    version: walletType.loopringWalletContractVersion,\n                  })\n                } else {\n                  setLoopringSmartWalletVersion({\n                    isLoopringSmartWallet: false,\n                  })\n                }\n                if (walletType && walletType.loopringWalletContractVersion?.startsWith('V1_')) {\n                  setIsContract1XAddress(true)\n                } else {\n                  setIsContract1XAddress(false)\n                }\n\n                if (\n                  _contractType &&\n                  _contractType.network !== NetworkMap[defaultNetwork].walletType\n                ) {\n                  setIsLoopringAddress(true)\n                  setAddrStatus(AddressError.InvalidAddr)\n                  setIsActiveAccount(false)\n                  setIsActiveAccountFee('not allow')\n                } else if (\n                  realAddr &&\n                  _contractType?.network &&\n                  _contractType?.network === NetworkMap[defaultNetwork].walletType &&\n                  (_contractType as any)?.extra?.createWalletFromInfo?.fromWallet &&\n                  (_contractType as any)?.extra?.createWalletFromInfo?.fromWallet?.toLowerCase() ===\n                    realAddr.toLowerCase()\n                ) {\n                  setIsLoopringAddress(true)\n                  setIsActiveAccount(\n                    response &&\n                      ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message)\n                      ? false\n                      : response?.accInfo?.nonce !== 0,\n                  )\n                  setIsActiveAccountFee('not allow')\n                } else if (\n                  response &&\n                  ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message)\n                ) {\n                  setIsLoopringAddress(false)\n                  setIsActiveAccount(false)\n                  setIsActiveAccountFee(false)\n                } else {\n                  setIsLoopringAddress(true)\n                  setIsActiveAccount(response.accInfo.nonce !== 0)\n                  setIsActiveAccountFee(\n                    response.accInfo.nonce === 0 &&\n                      /FirstUpdateAccountPaid/gi.test(response.accInfo.tags ?? ''),\n                  )\n                  setCheckAddaccountId(response.accInfo.accountId)\n                }\n              }\n            } else {\n              setIsCFAddress(false)\n              setIsLoopringAddress(false)\n              setLoopringSmartWalletVersion({\n                isLoopringSmartWallet: false,\n              })\n            }\n          }\n          myLog('address update async', address, realAddr)\n          setIsAddressCheckLoading(false)\n        } else {\n          throw new CustomError(ErrorMap.ERROR_ADDRESS_CHECK_ERROR) // Error('wrong address format')\n        }\n      } else {\n        throw new CustomError(ErrorMap.ERROR_WRONG_APIKEY)\n      }\n    } catch (error) {\n      error = {\n        ...(error as any),\n        ...LoopringAPI?.walletAPI?.genErr(error as any),\n      }\n      // @ts-ignore\n      if (_address?.current == address && error?.code == sdk.LoopringErrorCode.HTTP_ERROR) {\n        _address.current = ''\n        setAddrStatus(AddressError.TimeOut)\n        setRealAddr({ realAddr: '', ens: '', isENSWrong: false })\n        setIsAddressCheckLoading(false)\n      } else {\n        setAddrStatus(address === '' ? AddressError.EmptyAddr : AddressError.InvalidAddr)\n        myLog('address update address async', address, error)\n        setRealAddr({ realAddr: '', ens: '', isENSWrong: false })\n        _address.current = ''\n        setIsLoopringAddress(false)\n        setIsAddressCheckLoading(false)\n      }\n      if (address !== '' && (error as any)?.code !== 500000) {\n        setShowGlobalToast({\n          isShow: true,\n          info: {\n            type: ToastType.info,\n            messageKey: (\n              SDK_ERROR_MAP_TO_UI[(error as any)?.code ?? UIERROR_CODE.ERROR_ADDRESS_CHECK_ERROR] ??\n              SDK_ERROR_MAP_TO_UI[UIERROR_CODE.ERROR_ADDRESS_CHECK_ERROR]\n            )?.messageKey,\n          },\n        })\n      }\n    }\n  }, [defaultNetwork])\n\n  const debounceCheck = _.debounce(\n    async (address) => {\n      myLog('address update sync', address)\n      const found = store\n        .getState()\n        .contacts?.contacts?.find((contact) => contact.contactAddress === address)\n      const listNoCheckRequired = [\n        sdk.AddressType.LOOPRING_HEBAO_CF,\n        sdk.AddressType.LOOPRING_HEBAO_CONTRACT_1_1_6,\n        sdk.AddressType.LOOPRING_HEBAO_CONTRACT_1_2_0,\n        sdk.AddressType.LOOPRING_HEBAO_CONTRACT_2_0_0,\n        sdk.AddressType.LOOPRING_HEBAO_CONTRACT_2_1_0,\n        sdk.AddressType.LOOPRING_HEBAO_CONTRACT_2_2_0,\n        sdk.AddressType.LOOPRING_HEBAO_CONTRACT_3_0_0,\n        sdk.AddressType.EXCHANGE_OTHER,\n        sdk.AddressType.EXCHANGE_BINANCE,\n        sdk.AddressType.EXCHANGE_OKX,\n        sdk.AddressType.EXCHANGE_HUOBI,\n        sdk.AddressType.EXCHANGE_COINBASE,\n        sdk.AddressType.CONTRACT,\n        sdk.AddressType.EOA\n      ]\n      if (found && listNoCheckRequired.includes(found.addressType)) {\n        let ens = '',\n          isENSWrong = false\n        if (found?.ens && connectProvides?.usedWeb3) {\n          const ensAddr = await connectProvides?.usedWeb3.eth?.ens?.getAddress(found?.ens)\n          if (ensAddr?.toLowerCase() !== address?.toLowerCase()) {\n            isENSWrong = true\n          }\n        }\n        setRealAddr({ realAddr: address, ens, isENSWrong })\n        switch (found.addressType) {\n          case sdk.AddressType.LOOPRING_HEBAO_CF:\n          case sdk.AddressType.LOOPRING_HEBAO_CONTRACT_1_1_6:\n          case sdk.AddressType.LOOPRING_HEBAO_CONTRACT_1_2_0:\n          case sdk.AddressType.LOOPRING_HEBAO_CONTRACT_2_0_0:\n          case sdk.AddressType.LOOPRING_HEBAO_CONTRACT_2_1_0:\n          case sdk.AddressType.LOOPRING_HEBAO_CONTRACT_2_2_0:\n          case sdk.AddressType.LOOPRING_HEBAO_CONTRACT_3_0_0: {\n            if (found.addressType === sdk.AddressType.LOOPRING_HEBAO_CF) {\n              // recheck CF Wallet\n              const walletTypeResponse = await LoopringAPI.walletAPI?.getWalletType({\n                wallet: realAddr,\n                network: sdk.NetworkWallet[NetworkMap[defaultNetwork]?.walletType],\n              })\n              setIsCFAddress(!!walletTypeResponse?.walletType?.isInCounterFactualStatus)\n              if (\n                !walletTypeResponse?.walletType?.isInCounterFactualStatus &&\n                walletTypeResponse?.walletType?.loopringWalletContractVersion\n              ) {\n                const addressType: number | string = HEBAO_CONTRACT_MAP.find(\n                  (x) => x[0] === walletTypeResponse?.walletType?.loopringWalletContractVersion,\n                )![1]\n                await LoopringAPI.contactAPI?.updateContact(\n                  {\n                    // contactAddress: found.xaddress,\n                    // isHebao: isHebao ? true : false,\n                    // contactName: found.name,\n                    ...found,\n                    isHebao: true,\n                    accountId: accountId,\n                    addressType: addressType as number,\n                  },\n                  apiKey,\n                )\n                updateContacts()\n              }\n            } else {\n              setIsCFAddress(false)\n            }\n            setIsContractAddress(true)\n            setIsContract1XAddress(\n              found.addressType === sdk.AddressType.LOOPRING_HEBAO_CONTRACT_1_1_6 ||\n                found.addressType === sdk.AddressType.LOOPRING_HEBAO_CONTRACT_1_2_0,\n            )\n            setLoopringSmartWalletVersion({\n              isLoopringSmartWallet: true,\n              version: undefined,\n            })\n            setAddrStatus(AddressError.NoError)\n            if (checkLayer2Status) {\n              try {\n                const response = await LoopringAPI.exchangeAPI?.getAccount({\n                  owner: address, //realAddr != \"\" ? realAddr : address,\n                })\n                if (\n                  (response &&\n                    ((response as sdk.RESULT_INFO).code ||\n                      (response as sdk.RESULT_INFO).message)) ||\n                  !response\n                ) {\n                  setIsLoopringAddress(false)\n                  setIsActiveAccount(false)\n                  setIsActiveAccountFee(false)\n                } else {\n                  setIsLoopringAddress(true)\n                  setIsActiveAccount(response.accInfo.nonce !== 0)\n                  setIsActiveAccountFee(\n                    response.accInfo.nonce === 0 &&\n                      /FirstUpdateAccountPaid/gi.test(response.accInfo.tags ?? ''),\n                  )\n                }\n              } catch {}\n              setIsAddressCheckLoading(false)\n            }\n            break\n          }\n          case sdk.AddressType.EXCHANGE_OTHER:\n          case sdk.AddressType.EXCHANGE_BINANCE:\n          case sdk.AddressType.EXCHANGE_OKX:\n          case sdk.AddressType.EXCHANGE_HUOBI:\n          case sdk.AddressType.EXCHANGE_COINBASE: {\n            setIsLoopringAddress(false)\n            setIsActiveAccount(false)\n            setIsActiveAccountFee(false)\n            setIsCFAddress(false)\n            setIsContractAddress(false)\n            setIsContract1XAddress(false)\n            setLoopringSmartWalletVersion({\n              isLoopringSmartWallet: false,\n            })\n            setAddrStatus(AddressError.NoError)\n            break\n          }\n          case sdk.AddressType.CONTRACT: {\n            setIsLoopringAddress(false)\n            setIsActiveAccount(false)\n            setIsActiveAccountFee(false)\n            setIsCFAddress(false)\n            setIsContractAddress(true)\n            setIsContract1XAddress(false)\n            setLoopringSmartWalletVersion({\n              isLoopringSmartWallet: false,\n            })\n            setAddrStatus(AddressError.IsNotLoopringContract)\n            break\n          }\n          case sdk.AddressType.EOA: {\n            setIsCFAddress(false)\n            setIsContractAddress(false)\n            setIsContract1XAddress(false)\n            setLoopringSmartWalletVersion({\n              isLoopringSmartWallet: false,\n            })\n            setAddrStatus(AddressError.NoError)\n            if (checkLayer2Status) {\n              setIsAddressCheckLoading(true)\n              try {\n                const response = await LoopringAPI.exchangeAPI?.getAccount({\n                  owner: address, //realAddr != \"\" ? realAddr : address,\n                })\n                if (\n                  (response &&\n                    ((response as sdk.RESULT_INFO).code ||\n                      (response as sdk.RESULT_INFO).message)) ||\n                  !response\n                ) {\n                  setIsLoopringAddress(false)\n                  setIsActiveAccount(false)\n                  setIsActiveAccountFee(false)\n                } else {\n                  setIsLoopringAddress(true)\n                  setIsActiveAccount(response.accInfo.nonce !== 0)\n                  setIsActiveAccountFee(\n                    response.accInfo.nonce === 0 &&\n                      /FirstUpdateAccountPaid/gi.test(response.accInfo.tags ?? ''),\n                  )\n                }\n              } catch {}\n              setIsAddressCheckLoading(false)\n            }\n            break\n          }\n        }\n      } else {\n        check(address, connectProvides.usedWeb3)\n      }\n    },\n    globalSetup.wait,\n    { maxWait: 1000, leading: false, trailing: true },\n  )\n  const initAddresss = () => {\n    setRealAddr({ realAddr: '', ens: '', isENSWrong: false })\n    setAddrStatus(AddressError.NoError)\n    setCheckAddaccountId(undefined)\n    setIsLoopringAddress(false)\n    setIsActiveAccount(false)\n    setIsActiveAccountFee(false)\n    setIsSameAddress(false)\n    setIsCFAddress(false)\n    setIsContractAddress(false)\n    setIsContract1XAddress(false)\n    setLoopringSmartWalletVersion(undefined)\n  }\n\n  React.useEffect(() => {\n    // myLog(\"checkAddress\", address, _address.current, isAddressCheckLoading);\n    myLog('current address', _address.current, address)\n    if (_address.current !== address) {\n      if (isAddressCheckLoading == true) {\n        //to async norsure should deleted\n        initAddresss()\n        debounceCheck.cancel()\n      }\n      _address.current = address\n      debounceCheck(address)\n    }\n\n    return () => {\n      debounceCheck.cancel()\n    }\n  }, [address, chainId])\n  const reCheck = React.useCallback(() => {\n    debounceCheck(address)\n    _address.current = address\n    return () => {\n      debounceCheck.cancel()\n    }\n  }, [address])\n\n  React.useEffect(() => {\n    setIsSameAddress(realAddr.toLowerCase() === accAddress.toLowerCase())\n  }, [realAddr, accAddress])\n  return {\n    address,\n    ens,\n    realAddr,\n    checkAddAccountId,\n    setAddress,\n    addrStatus,\n    isAddressCheckLoading,\n    isLoopringAddress,\n    isActiveAccount,\n    isCFAddress,\n    isSameAddress,\n    isContract1XAddress,\n    isContractAddress,\n    isActiveAccountFee,\n    isENSWrong,\n    loopringSmartWalletVersion,\n    reCheck,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/common/useAllowances.ts",
    "content": "import BigNumber from 'bignumber.js'\nimport { LoopringAPI, useSystem, useTokenMap } from '../../index'\nimport React from 'react'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nexport function useAllowances({ owner, symbol }: { owner: string; symbol: string }) {\n  const { tokenMap } = useTokenMap()\n  const { status: systemStatus } = useSystem()\n\n  const [allowanceInfo, setAllowanceInfo] = React.useState<{\n    allowance: BigNumber\n    needCheck: boolean\n    tokenInfo: sdk.TokenInfo\n  }>()\n\n  const updateAllowance = React.useCallback(\n    async (symbol: string) => {\n      if (owner && tokenMap && LoopringAPI.exchangeAPI && symbol) {\n        const tokenInfo = tokenMap[symbol]\n\n        if (tokenInfo) {\n          let allowance = sdk.toBig(0)\n          let needCheck = false\n\n          if (tokenInfo?.symbol.toUpperCase() !== 'ETH') {\n            const { tokenAllowances } = await LoopringAPI.exchangeAPI.getAllowances({\n              owner,\n              token: [tokenInfo.address],\n            })\n            allowance = sdk.toBig(tokenAllowances.get(tokenInfo.address) ?? '')\n            needCheck = true\n          }\n\n          setAllowanceInfo({\n            allowance,\n            needCheck,\n            tokenInfo,\n          })\n        } else {\n          setAllowanceInfo(undefined)\n        }\n      }\n    },\n    [tokenMap, owner],\n  )\n\n  React.useEffect(() => {\n    updateAllowance(symbol)\n  }, [owner, symbol, systemStatus])\n\n  return {\n    allowanceInfo,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/common/useBtnStatus.ts",
    "content": "import React from 'react'\nimport { BtnInfo } from '@loopring-web/component-lib'\nimport { TradeBtnStatus } from '@loopring-web/common-resources'\n\nexport function useBtnStatus() {\n  const [btnStatus, setBtnStatus] = React.useState<TradeBtnStatus>(TradeBtnStatus.AVAILABLE)\n\n  const [btnInfo, setBtnInfo] = React.useState<BtnInfo | undefined>(undefined)\n\n  const setLabelAndParams = React.useCallback(\n    (label: string, params: { [key: string]: string }) => {\n      setBtnInfo({ label, params })\n    },\n    [setBtnInfo],\n  )\n\n  const resetBtnInfo = React.useCallback(() => {\n    setBtnInfo(undefined)\n  }, [setBtnInfo])\n\n  const enableBtn = React.useCallback(() => {\n    setBtnStatus(TradeBtnStatus.AVAILABLE)\n  }, [setBtnStatus])\n\n  const disableBtn = React.useCallback(() => {\n    setBtnStatus(TradeBtnStatus.DISABLED)\n  }, [setBtnStatus])\n\n  const setLoadingBtn = React.useCallback(() => {\n    setBtnStatus(TradeBtnStatus.LOADING)\n  }, [setBtnStatus])\n\n  React.useEffect(() => {\n    enableBtn()\n  }, [])\n\n  return {\n    btnInfo,\n    btnStatus,\n    setLabelAndParams,\n    resetBtnInfo,\n    enableBtn,\n    disableBtn,\n    setLoadingBtn,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/common/useCollectionImport.ts",
    "content": "import { BigNumber } from 'bignumber.js'\nimport React from 'react'\nimport {\n  Account,\n  CollectionMeta,\n  CustomError,\n  ErrorMap,\n  L2CollectionFilter,\n  NFTSubRouter,\n  NFTWholeINFO,\n  RouterPath,\n} from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport {\n  getIPFSString,\n  LoopringAPI,\n  makeMeta,\n  useAccount,\n  useCollectionManage,\n  useMyCollection,\n  useWalletL2Collection,\n} from '../../index'\nimport { ImportCollectionStep, ImportCollectionViewProps } from '@loopring-web/component-lib'\nimport { useHistory, useRouteMatch } from 'react-router-dom'\n\n// const enum MINT_VIEW_STEP {\n//   METADATA,\n//   MINT_CONFIRM,\n// }\nBigNumber.config({ EXPONENTIAL_AT: 100 })\n\nexport const useCollectionImport = <\n  Co extends CollectionMeta,\n  NFT extends Partial<NFTWholeINFO>,\n>(): ImportCollectionViewProps<Co, NFT> => {\n  const { account } = useAccount()\n  const history = useHistory()\n  let match: any = useRouteMatch('/nft/importLegacyCollection/:id?')\n  const stepList = match?.params?.id?.split('--')\n  const contract = stepList && stepList[0]?.startsWith('0x') && stepList[0]\n  const contractId = stepList && stepList[1]\n  const [step, setStep] = React.useState<ImportCollectionStep>(ImportCollectionStep.SELECTCONTRACT)\n  const { legacyContract } = useWalletL2Collection()\n\n  const [onLoading, setOnLoading] = React.useState<boolean>(false)\n\n  // const [contractList, setContractList] = React.useState<string[]>([\"\"]);\n  const [selectContract, setSelectContract] = React.useState<\n    { value: string; total?: number; list?: sdk.UserNFTBalanceInfo[] } | undefined\n  >(undefined)\n  const [filter, setFilter] = React.useState<{\n    isLegacy: boolean\n    tokenAddress: string\n  }>({\n    isLegacy: true,\n    tokenAddress: selectContract?.value ?? '',\n  })\n  const { onPageChange: onCollectionPageChange, ...collectionListProps } = useMyCollection<Co>(\n    filter as any,\n  )\n  const [selectCollection, setSelectCollection] = React.useState<Co | undefined>(undefined)\n  const onContractChange = React.useCallback(\n    async (item) => {\n      setSelectContract({ value: item })\n      setOnLoading(true)\n      let _filter = { offset: 0 }\n      if (LoopringAPI.userAPI) {\n        const { userNFTBalances, totalNum } = await LoopringAPI.userAPI\n          .getUserNFTLegacyBalance(\n            {\n              collectionId: -1,\n              accountId: account.accountId,\n              tokenAddress: item,\n              limit: 3,\n              ..._filter,\n              metadata: true, // close metadata\n            },\n            account.apiKey,\n          )\n          .catch((_error) => {\n            throw new CustomError(ErrorMap.TIME_OUT)\n          })\n        setSelectContract((state) => ({\n          ...state,\n          value: item,\n          list: userNFTBalances,\n          total: totalNum,\n        }))\n      }\n      setOnLoading(false)\n    },\n    [account.accountId, account.apiKey],\n  )\n  React.useEffect(() => {\n    if (\n      collectionListProps.isLoading === false &&\n      selectCollection === undefined &&\n      collectionListProps.total\n    ) {\n      onCollectionChange(collectionListProps.collectionList[0])\n    }\n    ;() => {\n      setSelectCollection(undefined)\n    }\n  }, [collectionListProps.isLoading])\n\n  const { collection, selectedNFTS, onNFTSelected, baseURL, onNFTSelectedMethod, ...nftProps } =\n    useCollectionManage<Co, NFT>({ collection: selectCollection })\n  const onCollectionChange = React.useCallback((item: Co | undefined) => {\n    setSelectCollection(item)\n  }, [])\n\n  const onContractNext = React.useCallback(\n    async (value: string) => {\n      const _filter = {\n        isLegacy: true,\n        tokenAddress: value,\n      }\n      setFilter(_filter)\n      setOnLoading(true)\n      collectionListProps.collectionList = []\n      onCollectionPageChange(1, _filter)\n    },\n    [collectionListProps],\n  )\n\n  const onCollectionNext = React.useCallback(() => {}, [])\n\n  const onClick = React.useCallback(() => {}, [])\n  React.useEffect(() => {\n    if (stepList && contract) {\n      onContractChange(contract)\n      onContractNext(contract)\n      setStep(ImportCollectionStep.SELECTCOLLECTION)\n    } else if (stepList && contractId) {\n      setStep(ImportCollectionStep.SELECTNFT)\n    } else {\n      if (legacyContract?.length) {\n        onContractChange(legacyContract[0])\n      }\n      setStep(ImportCollectionStep.SELECTCONTRACT)\n    }\n  }, [legacyContract])\n  React.useEffect(() => {\n    if (!collectionListProps.isLoading && onLoading === true) {\n      setOnLoading(false)\n    }\n  }, [collectionListProps.isLoading])\n\n  return {\n    account: account as Account,\n    onContractChange,\n    onContractNext,\n    onCollectionChange,\n    onCollectionNext,\n    onNFTSelected,\n    onNFTSelectedMethod,\n    step,\n    baseURL,\n    getIPFSString,\n    setStep: (item) => {\n      switch (item) {\n        case ImportCollectionStep.SELECTCOLLECTION:\n          history.replace(\n            `${RouterPath.nft}/${NFTSubRouter.importLegacyCollection}/${selectContract?.value}`,\n          )\n          break\n        case ImportCollectionStep.SELECTNFT:\n          history.replace(\n            `${RouterPath.nft}/${NFTSubRouter.importLegacyCollection}/${selectContract?.value}--${selectCollection?.id}`,\n          )\n          break\n        case ImportCollectionStep.SELECTCONTRACT:\n        default:\n          history.replace(`${RouterPath.nft}/${NFTSubRouter.importLegacyCollection}`)\n          break\n      }\n      setStep(item)\n    },\n    disabled: false,\n    onLoading,\n    onClick,\n    data: {\n      contractList: legacyContract,\n      selectContract,\n      selectNFTList: selectedNFTS as NFT[],\n      selectCollection,\n      collectionInputProps: {\n        collection: selectCollection,\n        collectionListProps: {\n          onPageChange: React.useCallback(\n            (page: number, _filter?: L2CollectionFilter | undefined) => {\n              onCollectionPageChange(page, { ...filter, ..._filter })\n            },\n            [filter],\n          ),\n          ...collectionListProps,\n        },\n        domain: LoopringAPI.delegate?.getCollectionDomain(),\n        makeMeta,\n      } as any,\n      nftProps: nftProps as any,\n    },\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/common/useCollectionManage.ts",
    "content": "import { BigNumber } from 'bignumber.js'\nimport React from 'react'\nimport { CollectionMeta, NFTLimit, NFTWholeINFO } from '@loopring-web/common-resources'\nimport {\n  getIPFSString,\n  LoopringAPI,\n  store,\n  useAccount,\n  useNFTListDeep,\n  useSystem,\n  useToast,\n} from '../../index'\nimport { CollectionManageProps, CollectionMethod, ToastType } from '@loopring-web/component-lib'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { useTranslation } from 'react-i18next'\nimport { nextAccountSyncStatus } from '../../stores/account/reducer'\n\nBigNumber.config({ EXPONENTIAL_AT: 100 })\n\nexport const useCollectionManage = <Co extends CollectionMeta, NFT extends Partial<NFTWholeINFO>>({\n  collection,\n  pageSize = NFTLimit,\n}: {\n  collection?: CollectionMeta | undefined\n  pageSize?: number\n}): CollectionManageProps<Co, NFT> => {\n  const { account } = useAccount()\n  const { chainId } = useSystem()\n  const { t } = useTranslation()\n  const [filter, setFilter] = React.useState({})\n  const toastObj = useToast()\n  const { renderNFTPromise, nftListReduce } = useNFTListDeep()\n\n  const [selectedNFTS, setSelectedNFTS] = React.useState<NFT[]>([])\n  const [{ listNFT, total, page }, setListNFTValue] = React.useState<{\n    listNFT: NFT[]\n    total: number\n    page: number\n  }>({\n    listNFT: [],\n    total: 0,\n    page: 1,\n  })\n  const [isLoading, setIsLoading] = React.useState(false)\n  const onFilterNFT = React.useCallback(\n    async (props: { legacyFilter?: sdk.LegacyNFT | 'all'; limit?: number; page?: number }) => {\n      if (collection && LoopringAPI.userAPI) {\n        onNFTSelected('removeAll')\n        setFilter(props)\n        setIsLoading(true)\n        const { legacyFilter = sdk.LegacyNFT.undecided, limit = pageSize, page: _page = 1 } = props\n        const response = await LoopringAPI.userAPI.getUserNFTLegacyBalance(\n          {\n            accountId: account.accountId,\n            tokenAddress: collection.contractAddress,\n            // @ts-ignore\n            collectionId: legacyFilter !== 'all' ? collection?.id : undefined,\n            filter: legacyFilter !== 'all' ? legacyFilter : undefined,\n            offset: (_page - 1) * limit,\n            limit,\n            metadata: true,\n          },\n          account.apiKey,\n        )\n        if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n        } else {\n          setListNFTValue({\n            total: response.totalNum,\n            page: _page,\n            listNFT: nftListReduce(response.userNFTBalances),\n          })\n          setIsLoading(false)\n          renderNFTPromise({ nftLists: response.userNFTBalances as any }).then((meta: any[]) => {\n            if (page === _page) {\n              setListNFTValue((state) => {\n                return {\n                  ...state,\n                  listNFT: state.listNFT?.map((item, index) => {\n                    return {\n                      ...item,\n                      ...meta[index],\n                      tokenAddress: item.tokenAddress?.toLowerCase(),\n                      // etherscanBaseUrl,\n                    }\n                  }),\n                }\n              })\n            }\n          })\n        }\n        setIsLoading(false)\n      }\n    },\n    [collection],\n  )\n  const { baseURL } = useSystem()\n  const onNFTSelected = React.useCallback(\n    (_item: NFT | 'addAll' | 'removeAll') => {\n      if (_item === 'addAll') {\n        setSelectedNFTS(listNFT)\n      } else if (_item === 'removeAll') {\n        setSelectedNFTS([])\n      } else {\n        setSelectedNFTS((state) => {\n          let has = false\n          const previewList = (state ?? []).reduce((prev, item) => {\n            if (_item.nftData === item.nftData) {\n              has = true\n              return prev\n            } else {\n              return [...prev, item]\n            }\n          }, [] as NFT[])\n          return has ? previewList : [_item, ...selectedNFTS]\n        })\n      }\n    },\n    [selectedNFTS, listNFT],\n  )\n  const onNFTSelectedMethod = React.useCallback(\n    async (items: NFT[], method: CollectionMethod) => {\n      let hashList: string[] = []\n      if (collection && items.length && collection?.id) {\n        let collectionId: number = 0\n        hashList = items.reduce((prev, item) => {\n          return [...prev, item.nftData ?? '']\n        }, [] as string[])\n        setIsLoading(true)\n        switch (method) {\n          case CollectionMethod.moveOut:\n            collectionId = 0\n            break\n          case CollectionMethod.moveIn:\n            collectionId = Number(collection?.id)\n            break\n          default:\n            break\n        }\n        const response = await LoopringAPI.userAPI?.submitUpdateNFTLegacyCollection(\n          {\n            accountId: account.accountId,\n            nftHashes: hashList,\n            collectionId,\n          },\n          chainId as any,\n          account.apiKey,\n          account.eddsaKey.sk,\n        )\n        if (\n          response &&\n          ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message)\n        ) {\n          toastObj.setToastOpen({\n            open: true,\n            type: ToastType.error,\n            content: t('labelNFTMoveFailed'),\n          })\n        } else {\n          toastObj.setToastOpen({\n            open: true,\n            type: ToastType.success,\n            content: t('labelNFTMoveSuccess'),\n          })\n        }\n        LoopringAPI.nftAPI\n          ?.getHadUnknownCollection({\n            accountId: account.accountId,\n          })\n          .then((_response) => {\n            if ((_response as unknown as sdk.RESULT_INFO)?.code) {\n              return\n            }\n            store.dispatch(\n              nextAccountSyncStatus({ ...store.getState().account, hasUnknownCollection: _response }),\n            )\n          })\n        onFilterNFT({ ...filter })\n      }\n    },\n    [filter],\n  )\n  React.useEffect(() => {\n    if (collection?.id && account.accountId) {\n      onNFTSelected('removeAll')\n      onFilterNFT({})\n    }\n  }, [collection?.id])\n  return {\n    collection: (collection ?? {}) as Partial<Co>,\n    selectedNFTS,\n    onNFTSelected,\n    total,\n    toastObj,\n    page,\n    listNFT,\n    baseURL,\n    getIPFSString,\n    onNFTSelectedMethod,\n    onFilterNFT,\n    isLoading,\n    filter,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/common/useDebounce.ts",
    "content": "import _ from \"lodash\"\nimport { useEffect, useRef } from \"react\";\n\nexport function useDebouncedCallback<A extends any[]>(\n  callback: (...args: A) => void,\n  wait: number\n) {\n  // track args & timeout handle between calls\n  const argsRef = useRef<A>();\n  const timeout = useRef<ReturnType<typeof setTimeout>>();\n\n  function cleanup() {\n    if(timeout.current) {\n      clearTimeout(timeout.current);\n    }\n  }\n\n  // make sure our timeout gets cleared if\n  // our consuming component gets unmounted\n  useEffect(() => cleanup, []);\n\n  return function debouncedCallback(\n    ...args: A\n  ) {\n    // capture latest args\n    argsRef.current = args;\n\n    // clear debounce timer\n    cleanup();\n\n    // start waiting again\n    timeout.current = setTimeout(() => {\n      if(argsRef.current) {\n        callback(...argsRef.current);\n      }\n    }, wait);\n  };\n}"
  },
  {
    "path": "packages/core/src/hooks/common/useGetOrderHistorys.ts",
    "content": "import React from 'react'\nimport { RawDataTradeItem } from '@loopring-web/component-lib'\n\nimport { Side, toBig, GetUserTradesRequest } from '@loopring-web/loopring-sdk'\nimport {\n  store,\n  LoopringAPI,\n  useAccount,\n  volumeToCount,\n  volumeToCountAsBigNumber,\n} from '../../index'\nimport { TradeTypes } from '@loopring-web//common-resources'\n\nexport function useGetOrderHistorys() {\n  const [userTrades, setUserTrades] = React.useState<RawDataTradeItem[]>([])\n  const [showLoading, setShowLoading] = React.useState(true)\n  const [userOrderDetailList, setUserOrderDetailList] = React.useState<any[]>([])\n\n  const {\n    account: { accountId, apiKey },\n  } = useAccount()\n\n  const tokenMap = store.getState().tokenMap.tokenMap\n\n  const getUserTrade = React.useCallback(\n    async (props?: Omit<GetUserTradesRequest, 'accountId'>) => {\n      if (LoopringAPI && LoopringAPI.userAPI && accountId && apiKey && tokenMap) {\n        const userTrades = await LoopringAPI.userAPI.getUserTrades(\n          {\n            ...props,\n            accountId,\n          },\n          apiKey,\n        )\n        return userTrades\n      }\n    },\n    [accountId, apiKey, tokenMap],\n  )\n\n  const getUserOrderDetailTradeList = React.useCallback(\n    async (props?: Omit<GetUserTradesRequest, 'accountId'>) => {\n      if (LoopringAPI && LoopringAPI.userAPI && accountId && apiKey && tokenMap) {\n        const userTrades = await getUserTrade({ ...props })\n        if (userTrades && userTrades.userTrades) {\n          setUserOrderDetailList(\n            userTrades.userTrades.map((o) => {\n              const marketList = o.market.split('-')\n              // due to AMM case, we cannot use first index\n              // const side = o.side === 'BUY' ? TradeTypes.Buy : TradeTypes.Sell\n              const tokenFirst = marketList[marketList.length - 2]\n              const tokenLast = marketList[marketList.length - 1]\n              const baseToken = o.side === 'BUY' ? tokenFirst : tokenLast\n              const quoteToken = o.side === 'BUY' ? tokenLast : tokenFirst\n\n              const volumeToken = o.side === 'BUY' ? baseToken : quoteToken\n              const volume = volumeToCount(volumeToken, o.volume)\n              const feeKey = o.side === 'BUY' ? baseToken : quoteToken\n\n              return {\n                market: o.market,\n                amount: volume,\n                filledPrice: o.price,\n                time: Number(o.tradeTime),\n                volumeToken,\n                fee: {\n                  key: feeKey,\n                  value: o.fee ? volumeToCount(feeKey, o.fee) : undefined,\n                },\n              }\n            }),\n          )\n        }\n      }\n    },\n    [accountId, apiKey, getUserTrade, tokenMap],\n  )\n\n  const getUserTradeList = React.useCallback(async () => {\n    if (LoopringAPI && LoopringAPI.userAPI && accountId && apiKey && tokenMap) {\n      const userTrades = await getUserTrade()\n\n      if (userTrades && userTrades.userTrades) {\n        setUserTrades(\n          // @ts-ignore\n          userTrades.userTrades.map((o) => {\n            const marketList = o.market.split('-')\n            // due to AMM case, we cannot use first index\n            const side = o.side === Side.Buy ? TradeTypes.Buy : TradeTypes.Sell\n            const tokenFirst = marketList[marketList.length - 2]\n            const tokenLast = marketList[marketList.length - 1]\n            const baseToken = side === TradeTypes.Buy ? tokenFirst : tokenLast\n            const quoteToken = side === TradeTypes.Buy ? tokenLast : tokenFirst\n\n            // const amt = toBig(o.volume).times(o.price).toString()\n\n            const feeKey = o.side === Side.Buy ? baseToken : quoteToken\n\n            return {\n              side: side,\n              price: {\n                key: baseToken,\n                // value: StringToNumberWithPrecision(o.price, baseToken)\n                value: toBig(o.price).toNumber(),\n              },\n              fee: {\n                key: feeKey,\n                // value: VolToNumberWithPrecision(o.fee, quoteToken),\n                value: feeKey ? volumeToCount(feeKey, o.fee)?.toFixed(6) : undefined,\n              },\n              time: Number(o.tradeTime),\n              amount: {\n                from: {\n                  key: baseToken,\n                  // value: VolToNumberWithPrecision(o.volume, baseToken),\n                  value: baseToken ? volumeToCount(baseToken, o.volume) : undefined,\n                },\n                to: {\n                  key: quoteToken,\n                  // value: VolToNumberWithPrecision(amt, quoteToken)\n                  value: baseToken\n                    ? volumeToCountAsBigNumber(baseToken, o.volume)?.times(o.price).toNumber()\n                    : undefined,\n                },\n              },\n            }\n          }),\n        )\n        setShowLoading(false)\n      }\n    }\n  }, [accountId, apiKey, getUserTrade, tokenMap])\n\n  React.useEffect(() => {\n    getUserTradeList()\n  }, [getUserTradeList])\n\n  // useCustomDCEffect(async() => {\n\n  //     if (!LoopringAPI.userAPI || !accountId || !apiKey) {\n  //         return\n  //     }\n\n  //     const response = await LoopringAPI.userAPI.getUserTrades({accountId: accountId}, apiKey)\n\n  //     let userTrades: RawDataTradeItem[] = []\n\n  //     response.userTrades.forEach((item: UserTrade, index: number) => {\n  //     })\n\n  //     setUserTrades(userTrades)\n\n  // }, [accountId, apiKey, LoopringAPI.userAPI])\n\n  return {\n    userTrades,\n    showLoading,\n    userOrderDetailList,\n    getUserOrderDetailTradeList,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/common/useHookBtn.ts",
    "content": "import React, { useEffect } from 'react'\nimport { AccountStatus, coinbaseSmartWalletChains, fnType, MapChainId, TradeBtnStatus } from '@loopring-web/common-resources'\nimport * as _ from 'lodash'\nimport { accountStaticCallBack, btnClickMap, btnLabel } from '../help'\nimport { useAccount, useSystem, useWalletLayer2 } from '../../stores'\nimport { AccountStep, useOpenModals, useSettings } from '@loopring-web/component-lib'\nimport { ChainId, NetworkWallet, toBig } from '@loopring-web/loopring-sdk'\nimport { LoopringAPI } from '../../api_wrapper'\nimport { useUpdateAccount } from '../../hooks/useractions'\nimport { isCoinbaseSmartWallet } from '../../utils'\n\nexport const useSubmitBtn = ({\n  availableTradeCheck,\n  isLoading,\n  submitCallback,\n  ...rest\n}: {\n  // [ key: string ]: any,\n  submitCallback: (...props: any[]) => any\n  availableTradeCheck: (...props: any[]) => {\n    tradeBtnStatus: TradeBtnStatus\n    label: string | undefined\n  }\n  isLoading: boolean\n}) => {\n  // let {calcTradeParams} = usePageTradePro();\n  let { account,  } = useAccount()\n  let { app, exchangeInfo } = useSystem()\n  let { defaultNetwork } = useSettings()\n  const { goUpdateAccount } = useUpdateAccount()\n  const { setShowDeposit, setShowAccount } = useOpenModals()\n\n  const btnStatus = React.useMemo((): TradeBtnStatus | undefined => {\n    if (account.readyState === AccountStatus.ACTIVATED) {\n      if (isLoading) {\n        // myLog(\"tradeBtnStatus\", TradeBtnStatus.LOADING);\n        return TradeBtnStatus.LOADING\n      } else {\n        const { tradeBtnStatus } = availableTradeCheck(rest)\n        // myLog(\"tradeBtnStatus\", tradeBtnStatus);\n        return tradeBtnStatus\n      }\n    } else {\n      return TradeBtnStatus.AVAILABLE\n    }\n  }, [account.readyState, availableTradeCheck, isLoading, rest])\n\n  const btnStyle: Partial<React.CSSProperties> | undefined = React.useMemo(():\n    | Partial<React.CSSProperties>\n    | undefined => {\n    if (account.readyState === AccountStatus.ACTIVATED) {\n      return undefined\n    } else {\n      return { backgroundColor: 'var(--color-primary)' }\n    }\n  }, [account.readyState])\n\n  const _btnLabelArray = Object.assign(_.cloneDeep(btnLabel), {\n    [fnType.ACTIVATED]: [\n      (rest: any) => {\n        const { label } = availableTradeCheck(rest)\n        return label\n      },\n    ],\n  })\n  const _btnLabel = React.useMemo((): string => {\n    if (!exchangeInfo) {\n      return '...'\n    }\n    return accountStaticCallBack(_btnLabelArray, [{\n      ...rest,\n      chainId: defaultNetwork,\n      isEarn: app === 'earn',\n      readyState: account.readyState,\n    }])\n  }, [_btnLabelArray, rest, app, defaultNetwork, account.readyState, exchangeInfo])\n\n  const btnClickCallbackArray = Object.assign(_.cloneDeep(btnClickMap), {\n    [fnType.ACTIVATED]: [submitCallback],\n  })\n  const onBtnClick = React.useCallback(\n    (props?: any) => {\n      accountStaticCallBack(btnClickCallbackArray, [{\n        ...props,\n        chainId: defaultNetwork,\n        isEarn: app === 'earn',\n        readyState: account.readyState,\n        specialActivation: async () => {\n          const [walletType, coinbaseSW] = await Promise.all([\n            LoopringAPI?.walletAPI?.getWalletType({\n              wallet: account.accAddress,\n              network: MapChainId[defaultNetwork] as NetworkWallet,\n            }),\n            isCoinbaseSmartWallet(account.accAddress, defaultNetwork as ChainId),\n          ])\n\n          const isActivationSupported =\n            !walletType?.walletType?.isContract ||\n            (coinbaseSW && coinbaseSmartWalletChains.includes(defaultNetwork))\n          if (!isActivationSupported) {\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.UpdateAccount_SmartWallet_NotSupported_Alert,\n            })\n            return\n          }\n          const feeInfo = await LoopringAPI?.globalAPI?.getActiveFeeInfo({\n            accountId: account._accountIdNotActive,\n          })\n          const { userBalances } = await LoopringAPI?.globalAPI?.getUserBalanceForFee({\n            accountId: account._accountIdNotActive!,\n          })\n          const found = Object.keys(feeInfo.fees).find((key) => {\n            const fee = feeInfo.fees[key].fee\n            const foundBalance = userBalances[feeInfo.fees[key].tokenId]\n            return (foundBalance && toBig(foundBalance.total).gte(fee)) || toBig(fee).eq('0')\n          })\n          await goUpdateAccount({\n            isFirstTime: true,\n            isReset: false,\n            // @ts-ignore\n            feeInfo: {\n              token: feeInfo.fees[found!].fee,\n              belong: found!,\n              fee: feeInfo.fees[found!].fee,\n              feeRaw: feeInfo.fees[found!].fee,\n            },\n          })\n        },\n        specialActivationDeposit: async () => {\n          const [walletType, coinbaseSW] = await Promise.all([\n            LoopringAPI?.walletAPI?.getWalletType({\n              wallet: account.accAddress,\n              network: MapChainId[defaultNetwork] as NetworkWallet,\n            }),\n            isCoinbaseSmartWallet(account.accAddress, defaultNetwork as ChainId),\n          ])\n\n          const isActivationSupported =\n            !walletType?.walletType?.isContract ||\n            (coinbaseSW && coinbaseSmartWalletChains.includes(defaultNetwork))\n          if (!isActivationSupported) {\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.UpdateAccount_SmartWallet_NotSupported_Alert,\n            })\n            return\n          } \n          setShowDeposit({isShow: true})\n        },\n        exchangeInfoLoaded: exchangeInfo ? true : false,\n      }])\n    },\n    [btnClickCallbackArray, app, defaultNetwork, account],\n  )\n\n  return {\n    btnStatus,\n    onBtnClick,\n    btnLabel: _btnLabel,\n    btnStyle,\n    isAccountActive: account.readyState === AccountStatus.ACTIVATED,\n    // btnClickCallbackArray\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/common/useInjectWeb3Modal.ts",
    "content": "import React from 'react'\nimport { SUPPORTING_NETWORKS, SagaStatus, SoursURL, myLog } from '@loopring-web/common-resources'\nimport { setDefaultNetwork, useSettings } from '@loopring-web/component-lib'\n\nimport { accountServices, checkAccount, isSameEVMAddress, store, useAccount, useSelectNetwork, useSystem, useWalletLayer1 } from '@loopring-web/core'\nimport { ConnectProviders, connectProvides, walletServices } from '@loopring-web/web3-provider'\nimport { clearSystem, updateSystem } from '@loopring-web/core/src/stores/system/reducer'\nimport { updateAccountStatus, cleanAccountStatus } from '@loopring-web/core/src/stores/account/reducer'\nimport { useDispatch } from 'react-redux'\nimport { providers } from 'ethers'\nimport Web3 from 'web3'\nimport { useTheme } from '@emotion/react'\nimport { ChainId, toHex } from '@loopring-web/loopring-sdk'\nimport { createAppKit, useAppKitEvents, useAppKitTheme, useAppKitAccount, useAppKitProvider, useAppKitNetwork } from \"@reown/appkit/react\";\nimport { mainnet, sepolia, base, baseSepolia, taiko, taikoHekla, Chain } from \"@reown/appkit/networks\";\n\nimport { Ethers5Adapter } from \"@reown/appkit-adapter-ethers5\";\nconst projectId = process.env.REACT_APP_WALLET_CONNECT_V2_ID!\n\nconst networks: Chain[] = [\n  mainnet,\n  sepolia,\n  base,\n  baseSepolia,\n  { ...taiko, name: 'Taiko' },\n  taikoHekla,\n]\n\nconst metadata = {\n  name: process.env.REACT_APP_NAME!,\n  description: process.env.REACT_APP_NAME!,\n  url: process.env.REACT_APP_DOMAIN!,\n  icons: ['https://static.loopring.io/assets/svg/logo.svg'],\n}\nconst chainIds = SUPPORTING_NETWORKS.map(Number)\n\nexport const appKit = createAppKit({\n  adapters: [new Ethers5Adapter()],\n  metadata: metadata,\n  networks: networks.filter((item) => chainIds.includes(item.id)),\n  projectId,\n  chainImages: {\n    167000: `${SoursURL}earn/taiko.svg`,\n    8453: `${SoursURL}images/base.webp`,\n  },\n  enableInjected: true,\n  featuredWalletIds: [\n    'c57ca95b47569778a828d19178114f4db188b89b763c899ba0be274e97267d96',\n    'fd20dc426fb37566d803205b19bbc1d4096b248ac04548e3cfb6b3a38bd033aa',\n  ],\n  features: {\n    analytics: true,\n    email: false,\n    socials: false,\n    swaps: false,\n    onramp: false,\n    history: true,\n    send: false,\n  },\n})\n\n\nexport const useInjectWeb3Modal = (type: 'MAIN' | 'EARN' | 'BRIDGE' | 'GUARDIAN') => {\n  \n  const { status } = useSystem()\n  const { currency } = useSettings()\n  const { address } = useAppKitAccount()\n  const { chainId: _chainId } = useAppKitNetwork()\n  const chainId = typeof _chainId === 'number' ? _chainId : Number(_chainId)\n  const { walletProvider } = useAppKitProvider('eip155')\n  const { resetAccount, account: {accAddress} } = useAccount()\n\n  const event = useAppKitEvents()\n  const dispatch = useDispatch()\n  const { mode } = useTheme()\n  const { setThemeMode } = useAppKitTheme()\n  const { updateWalletLayer1 } = useWalletLayer1()\n  const { defaultNetwork } = useSettings()\n  React.useEffect(() => {\n    setThemeMode(mode)\n  }, [mode])\n\n  const combinedEvent = ['DISCONNECT_SUCCESS', 'DISCONNECT_ERROR'].includes(event.data.event)\n    ? event.data.event\n    : !isSameEVMAddress(address || '', accAddress)\n    ? 'ADDRESS_CHANGED'\n    : event.data.event \n\n  const checkEvent = React.useCallback(() => {\n    if (['DISCONNECT_SUCCESS', 'DISCONNECT_ERROR'].includes(combinedEvent)) {\n      if (type === 'BRIDGE') {\n        resetAccount()\n        walletServices.sendDisconnect('', 'customer click disconnect')\n        updateSystem({ chainId })\n        store.dispatch(setDefaultNetwork(undefined))\n      } else {\n        walletServices.sendDisconnect('', 'customer click disconnect')\n        resetAccount()\n        store.dispatch(setDefaultNetwork(undefined))\n      }\n    }  \n    if ([\"SWITCH_NETWORK\", \"INITIALIZE\", 'CONNECT_SUCCESS', 'CONNECT_ERROR'].includes(combinedEvent)) {\n      store.dispatch(\n        clearSystem(undefined)\n      );\n      store.dispatch(\n        updateSystem({\n          chainId,\n        }),\n      )\n      store.dispatch(setDefaultNetwork(chainId))\n    }  \n    if (['ADDRESS_CHANGED'].includes(combinedEvent)) {\n      if (address) {\n        if ((address.toLowerCase() !== accAddress?.toLowerCase()) || (defaultNetwork && chainId !== defaultNetwork)) { \n          accountServices.sendAccountLock()\n          checkAccount(address, chainId)\n        } else if (chainId && chainIds.includes(chainId)) {\n          checkAccount(address, chainId)\n        }\n      }\n    }\n  }, [combinedEvent, walletProvider, chainId, address, accAddress, defaultNetwork])\n  React.useEffect(() => {\n    checkEvent()\n  }, [combinedEvent])\n  React.useEffect(() => {\n    ;(async () => {\n      if (type === 'BRIDGE' && address && status === SagaStatus.DONE) {\n        updateWalletLayer1()\n      }\n    })()\n  }, [address, walletProvider, chainId, status, accAddress, defaultNetwork])\n  React.useEffect(() => {\n    if (type === 'BRIDGE' && address) {\n      store.dispatch(\n        updateSystem({\n          chainId,\n        }),\n      )\n      store.dispatch(setDefaultNetwork(chainId))\n      checkAccount(address, chainId)\n    }\n  }, [address])\n  React.useEffect(() => {\n    if (walletProvider) {\n      if ((walletProvider as any).isMetaMask) {\n        dispatch(\n          updateAccountStatus({\n            connectName: ConnectProviders.MetaMask,\n          }),\n        )\n      } else if ((walletProvider as any).isWalletConnect) {\n        dispatch(\n          updateAccountStatus({\n            connectName: ConnectProviders.WalletConnect,\n          }),\n        )\n      } else if ((walletProvider as any).isCoinbaseWallet) {\n        dispatch(\n          updateAccountStatus({\n            connectName: ConnectProviders.Coinbase,\n          }),\n        )\n      } else {\n        dispatch(\n          updateAccountStatus({\n            connectName: ConnectProviders.Unknown,\n          }),\n        )\n      }\n      connectProvides.usedProvide = new providers.Web3Provider(walletProvider as any)\n      // @ts-ignore\n      connectProvides.usedWeb3 = new Web3(walletProvider as any)\n    } else {\n      dispatch(\n        updateAccountStatus({\n          connectName: ConnectProviders.Unknown,\n        }),\n      )\n    }\n  }, [walletProvider])\n}\n"
  },
  {
    "path": "packages/core/src/hooks/common/useIsHebao.ts",
    "content": "import React from 'react'\nimport { LoopringAPI, useAccount } from '../../index'\nimport { NetworkWallet } from '@loopring-web/loopring-sdk'\nimport { MapChainId, NetworkMap } from '@loopring-web/common-resources'\nimport { useSettings } from '@loopring-web/component-lib'\n\nexport const useIsHebao = () => {\n  const [isHebao, setIsHebao] = React.useState<boolean | undefined>(undefined)\n  const {\n    account: { accAddress },\n  } = useAccount()\n  const { defaultNetwork } = useSettings()\n  React.useEffect(() => {\n    setIsHebao(undefined)\n    LoopringAPI.walletAPI\n      ?.getWalletType({\n        wallet: accAddress,\n        network: MapChainId[defaultNetwork] as NetworkWallet\n      })\n      .then((walletType) => {\n        const isHebao = walletType?.walletType?.loopringWalletContractVersion !== ''\n        setIsHebao(isHebao)\n      })\n  }, [accAddress])\n  return {\n    isHebao,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/common/useMarket.ts",
    "content": "import {\n  RowConfig,\n  RowConfigType,\n  TableFilterParams,\n  TickerNew,\n} from '@loopring-web/common-resources'\nimport React, { useCallback } from 'react'\nimport {\n  favoriteVaultMarket as favoriteMarketReducer,\n  LAYOUT,\n  store,\n  TokenMap,\n  useAccount,\n  useSystem,\n} from '@loopring-web/core'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nexport const useMarket = <\n  R extends TickerNew & { cmcTokenId: number; isFavorite: boolean },\n  T = sdk.TokenInfo,\n>({\n  tableRef,\n  rowConfig = RowConfig,\n  tickerMap,\n  handleRowClick,\n  handleItemClick,\n  tokenMap = store.getState()?.tokenMap?.tokenMap,\n}: {\n  tickerMap: { [key: string]: R }\n  tableRef: React.Ref<any>\n  rowConfig?: RowConfigType\n  handleRowClick?: (index: number, props: T & R) => void\n  handleItemClick?: (index: number, props: T & R) => void\n  tokenMap: TokenMap<any>\n}) => {\n  const { account } = useAccount()\n  // const { marketMap, tokenMap } = useTokenMap()\n  const [tableTabValue, setTableTabValue] = React.useState(TableFilterParams.all)\n  const [searchValue, setSearchValue] = React.useState<string>('')\n  const [filteredData, setFilteredData] = React.useState<(sdk.TokenInfo & R)[]>([])\n  const [tableHeight, setTableHeight] = React.useState(0)\n  const { favoriteMarket, removeMarket, addMarket } = favoriteMarketReducer.useFavoriteVaultMarket()\n\n  // const { tickList } = useQuote()\n  const handleCurrentScroll = React.useCallback((currentTarget, tableRef) => {\n    if (currentTarget && tableRef.current) {\n      const calcHeight = tableRef.current?.offsetTop - LAYOUT.HEADER_HEIGHT - currentTarget.scrollY\n      if (calcHeight < 2) {\n        tableRef.current.classList.add('fixed')\n      } else {\n        tableRef.current.classList.remove('fixed')\n      }\n    }\n  }, [])\n  const currentScroll = React.useCallback(\n    (event) => {\n      handleCurrentScroll(event.currentTarget, tableRef)\n    },\n    [handleCurrentScroll, tableRef],\n  )\n\n  const handleTableFilterChange = React.useCallback(\n    ({\n      type = tableTabValue,\n      // keyword,\n      ...rest\n    }: {\n      type?: TableFilterParams\n      keyword?: string\n    }) => {\n      let filter = ''\n      const favoriteMarket = store.getState().localStore.favoriteVaultMarket\n      setSearchValue((state) => {\n        filter = state\n        if (rest.hasOwnProperty('keyword')) {\n          filter = rest.keyword ?? ''\n        }\n        return filter\n      })\n      let data: Array<R & sdk.TokenInfo> = Object.values(tickerMap) ?? []\n      data = data\n      .filter((item) => {\n        if (!(item as any).vaultTokenAmounts) {\n          return false\n        }\n        const status = (item as any).vaultTokenAmounts.status as number\n        return item.enabled && status & 1\n      })\n      .map((item) => {\n        return {\n          ...tokenMap[item.symbol],\n          ...item,\n          isFavorite: favoriteMarket?.includes(item.symbol),\n        }\n      })\n      if (type === TableFilterParams.favourite) {\n        // myLog(\"tickList\", data);\n        data = data.filter((item) => {\n          return favoriteMarket?.includes(item.symbol)\n        })\n      }\n      if (filter) {\n        data = data.filter((o: any) => {\n          return new RegExp(filter, 'ig').test(o.symbol)\n        })\n      }\n      setFilteredData(data)\n      setTableHeight(\n        (rowConfig.rowHeaderHeight ?? RowConfig.rowHeaderHeight) +\n          data.length * (rowConfig?.rowHeight ?? RowConfig.rowHeaderHeight),\n      )\n    },\n    [\n      tickerMap,\n      tableTabValue,\n\n      searchValue,\n\n      // swapRankingList,\n      // getFilteredTickList,\n    ],\n  )\n\n  const handleTabChange = useCallback(\n    (_event: any, newValue: TableFilterParams) => {\n      // if (tickList?.length) {\n      setTableTabValue(newValue)\n      handleTableFilterChange({\n        keyword: searchValue,\n        type: newValue,\n      })\n      // }\n    },\n    [handleTableFilterChange, searchValue],\n  )\n\n  const handleSearchChange = React.useCallback(\n    (value) => {\n      handleTableFilterChange({ keyword: value, type: tableTabValue })\n    },\n    [tableTabValue],\n  )\n  const { forexMap } = useSystem()\n\n  return {\n    campaignTagConfig: {} as any,\n    tableTabValue,\n    handleTabChange,\n    searchValue,\n    handleStartClick: (symbol: string, rowIdx) => {\n      if (favoriteMarket.includes(symbol)) {\n        removeMarket(symbol)\n      } else {\n        addMarket(symbol)\n      }\n      handleTableFilterChange({})\n    },\n    favoriteMarket,\n    handleSearchChange,\n    addFavoriteMarket: addMarket,\n    showLoading: !Object.keys(tickerMap ?? {})?.length,\n    // tickList,\n    rawData: filteredData,\n    currentheight: tableHeight,\n    onRowClick: handleRowClick,\n    account,\n    forexMap,\n    rowConfig,\n    handleTableFilterChange,\n    onItemClick: handleItemClick,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/common/useMyCollection.ts",
    "content": "import { BigNumber } from 'bignumber.js'\nimport React, { useState } from 'react'\nimport { SagaStatus, CollectionMeta, L2CollectionFilter } from '@loopring-web/common-resources'\nimport { getIPFSString, LoopringAPI, makeMeta, useSystem, useWalletL2Collection } from '../../index'\nimport { CollectionListProps } from '@loopring-web/component-lib'\n\n// const enum MINT_VIEW_STEP {\n//   METADATA,\n//   MINT_CONFIRM,\n// }\nBigNumber.config({ EXPONENTIAL_AT: 100 })\n\nexport const useMyCollection = <C extends CollectionMeta>(\n  filter?: L2CollectionFilter,\n): CollectionListProps<C> => {\n  const [collectionList, setCollectionList] = React.useState<C[]>([])\n  const [copyToastOpen, setCopyToastOpen] = React.useState({\n    isShow: false,\n    type: 'json',\n  })\n  const [isLoading, setIsLoading] = React.useState(true)\n  const domain = LoopringAPI.delegate?.getCollectionDomain() ?? ''\n  const {\n    status: walletL2CollectionStatus,\n    walletL2Collection,\n    total,\n    page: page_reudex,\n    updateWalletL2Collection,\n  } = useWalletL2Collection()\n  const { etherscanBaseUrl, baseURL } = useSystem()\n  const [page, setPage] = useState(1)\n\n  const onPageChange = (page: number, filter?: L2CollectionFilter) => {\n    setPage(page)\n    setIsLoading(true)\n    updateWalletL2Collection({ page, filter })\n  }\n\n  const renderCollection = React.useCallback(async () => {\n    // let mediaPromise: any[] = [];\n    setCollectionList(walletL2Collection as C[])\n    setIsLoading(false)\n  }, [etherscanBaseUrl, page, walletL2Collection])\n  React.useEffect(() => {\n    onPageChange(1, filter)\n  }, [])\n\n  React.useEffect(() => {\n    if (walletL2CollectionStatus === SagaStatus.UNSET && page_reudex === page) {\n      renderCollection()\n    }\n  }, [walletL2CollectionStatus, page, page_reudex])\n  return {\n    setCopyToastOpen,\n    collectionList,\n    etherscanBaseUrl,\n    onPageChange,\n    domain,\n    makeMeta,\n    total,\n    page,\n    isLoading,\n    copyToastOpen,\n    baseURL,\n    getIPFSString,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/common/useMyNFTCollection.ts",
    "content": "import { CollectionMeta, SagaStatus } from '@loopring-web/common-resources'\nimport React from 'react'\nimport {\n  getIPFSString,\n  LoopringAPI,\n  makeMeta,\n  useSystem,\n  useWalletL2NFTCollection,\n} from '../../index'\nimport { useHistory, useLocation } from 'react-router-dom'\n\nexport const useMyNFTCollection = <C extends CollectionMeta>() => {\n  const { etherscanBaseUrl, baseURL } = useSystem()\n  const history = useHistory()\n  const { search, ...rest } = useLocation()\n  const searchParams = new URLSearchParams(search)\n  const defaultPage = Number(searchParams.get('collectionPage')) ?? 1\n  const [page, setPage] = React.useState(defaultPage ? defaultPage : -1)\n  const [collectionList, setCollectionList] = React.useState<C[]>([])\n  const [isLoading, setIsLoading] = React.useState(true)\n  const [copyToastOpen, setCopyToastOpen] = React.useState({\n    isShow: false,\n    type: 'json',\n  })\n  const domain = LoopringAPI.delegate?.getCollectionDomain() ?? ''\n\n  const {\n    status: walletL2NFTCollectionStatus,\n    total,\n    walletL2NFTCollection,\n    page: page_reudex,\n    updateWalletL2NFTCollection,\n  } = useWalletL2NFTCollection()\n\n  const onPageChange = (page: number) => {\n    setPage(page)\n    setIsLoading(true)\n    searchParams.set('collectionPage', page.toString())\n    history.replace({ ...rest, search: searchParams.toString() })\n    updateWalletL2NFTCollection({ page })\n  }\n\n  const renderCollection = React.useCallback(async () => {\n    // let mediaPromise: any[] = [];\n    setCollectionList(walletL2NFTCollection as C[])\n    setIsLoading(false)\n  }, [etherscanBaseUrl, page, walletL2NFTCollection])\n\n  React.useEffect(() => {\n    onPageChange(defaultPage && defaultPage !== -1 ? defaultPage : 1)\n  }, [])\n\n  React.useEffect(() => {\n    if (walletL2NFTCollectionStatus === SagaStatus.UNSET && page_reudex === page) {\n      // const { walletL2NFTCollection } = store.getState().walletL2NFTCollection;\n      renderCollection()\n    }\n  }, [walletL2NFTCollectionStatus, page, page_reudex])\n\n  return {\n    setCopyToastOpen,\n    collectionList,\n    etherscanBaseUrl,\n    onPageChange,\n    domain,\n    makeMeta,\n    total,\n    page,\n    isLoading,\n    copyToastOpen,\n    baseURL,\n    getIPFSString,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/common/useNFT.tsx",
    "content": "import * as sdk from '@loopring-web/loopring-sdk'\nimport {\n  IPFS_LOOPRING_SITE,\n  LOOPRING_NFT_METADATA,\n  LOOPRING_TAKE_NFT_META_KET,\n  myLog,\n  NFTWholeINFO,\n} from '@loopring-web/common-resources'\nimport { LoopringAPI } from '../../api_wrapper'\nimport { BigNumber } from 'bignumber.js'\nimport { connectProvides } from '@loopring-web/web3-provider'\nimport Web3 from 'web3'\nimport React from 'react'\nimport { getIPFSString } from '../../utils'\nimport { useSystem } from '../../stores'\nimport { getMediaType } from '@loopring-web/component-lib'\n\nexport const useNFTListDeep = <T extends Partial<NFTWholeINFO>>() => {\n  const { baseURL } = useSystem()\n\n  const getMetaFromContractORIpfs = ({\n    tokenAddress,\n    nftId,\n    isCounterFactualNFT,\n    deploymentStatus,\n    metadata,\n  }: sdk.UserNFTBalanceInfo): Promise<LOOPRING_NFT_METADATA | {}> => {\n    if (!!metadata?.imageSize?.original) {\n      return Promise.resolve({})\n    } else if (\n      LoopringAPI.nftAPI &&\n      tokenAddress &&\n      (!metadata?.uri ||\n        tokenAddress.toLowerCase() ===\n          '0x1cACC96e5F01e2849E6036F25531A9A064D2FB5f'.toLowerCase()) &&\n      nftId &&\n      (!isCounterFactualNFT ||\n        (isCounterFactualNFT && deploymentStatus !== sdk.DEPLOYMENT_STATUS.NOT_DEPLOYED))\n    ) {\n      const _id = new BigNumber(nftId ?? '', 16)\n      myLog('nftId', _id, _id.toString())\n      return LoopringAPI?.nftAPI\n        ?.getContractNFTMeta({\n          _id: _id.toString(),\n          // @ts-ignore\n          nftId,\n          web3: connectProvides.usedWeb3 as unknown as Web3,\n          tokenAddress,\n        })\n        .then((response) => {\n          if ((response as sdk.RESULT_INFO).code) {\n            console.log('Contract NFTMeta error:', response)\n            return {}\n          } else {\n            return Reflect.ownKeys(LOOPRING_TAKE_NFT_META_KET).reduce((prev, key) => {\n              return { ...prev, [key]: response[key] }\n            }, {} as LOOPRING_NFT_METADATA)\n          }\n        })\n        .catch((_error) => {\n          return {}\n        })\n    } else {\n      try {\n        const cid = LoopringAPI?.nftAPI?.ipfsNftIDToCid(nftId ?? '')\n        const uri = IPFS_LOOPRING_SITE + cid\n        return fetch(uri)\n          .then((response) => response.json())\n          .catch((_error) => {\n            return {}\n          })\n      } catch (e) {\n        return Promise.resolve({})\n      }\n    }\n  }\n  const nftListReduce = (items: sdk.UserNFTBalanceInfo[]) => {\n    return items.map((item) => {\n      return {\n        ...item,\n        nftIdView: new BigNumber(item?.nftId ?? '0', 16).toString(),\n        image: item.metadata?.uri,\n        ...item.metadata?.base,\n        ...item.metadata?.extra,\n      }\n    }) as any\n  }\n\n  const infoDetail = React.useCallback(async (item: Partial<NFTWholeINFO>) => {\n    const nftData: sdk.NftData = item.nftData as sdk.NftData\n    let [nftMap] = await Promise.all([\n      LoopringAPI.nftAPI?.getInfoForNFTTokens({\n        nftDatas: [nftData],\n      }),\n    ])\n    const nftToken: Partial<sdk.NFTTokenInfo> =\n      nftMap && nftMap[nftData as sdk.NftData] ? nftMap[nftData as sdk.NftData] : {}\n    let tokenInfo: NFTWholeINFO = {\n      ...item,\n      ...item.metadata?.base,\n      ...item.metadata?.extra,\n      pendingOnSync:\n        item.metadata?.base && Object.keys(item.metadata?.base)?.length > 0 ? false : true,\n      ...nftToken,\n    } as NFTWholeINFO\n    tokenInfo = {\n      ...tokenInfo,\n      nftIdView: new BigNumber(tokenInfo.nftId ?? '0', 16).toString(),\n      nftBalance: tokenInfo.total ? Number(tokenInfo.total) - Number(tokenInfo.locked ?? 0) : 0,\n    }\n    if (!tokenInfo.name) {\n      const meta = (await getMetaFromContractORIpfs(tokenInfo)) as LOOPRING_NFT_METADATA\n      let metadata_tokenId: number | undefined = undefined\n      if (meta.hasOwnProperty('tokenId')) {\n        metadata_tokenId = meta['tokenId']\n        delete meta['tokenId']\n      }\n\n      if (meta && Reflect.ownKeys(meta ?? {}).length > 0 && (meta.name || meta.image)) {\n        tokenInfo = Object.assign(metadata_tokenId !== undefined ? { metadata_tokenId } : {}, {\n          ...tokenInfo,\n          ...(meta as any),\n          animationUrl: (meta as any)?.animation_url,\n          royaltyPercentage: (meta as any)?.royalty_percentage,\n          isFailedLoadMeta: false,\n        })\n      } else {\n        tokenInfo = {\n          ...tokenInfo,\n          isFailedLoadMeta: true,\n        }\n      }\n    } else {\n      tokenInfo = {\n        ...tokenInfo,\n        isFailedLoadMeta: false,\n      }\n    }\n    if (\n      tokenInfo.hasOwnProperty('animationUrl') &&\n      tokenInfo.animationUrl &&\n      tokenInfo?.animationUrl !== ''\n    ) {\n      try {\n        const req = await fetch(getIPFSString(tokenInfo?.animationUrl, baseURL), {\n          method: 'HEAD',\n        })\n        tokenInfo.__mediaType__ = getMediaType(req?.headers?.get('content-type') ?? '')\n      } catch (error) {\n        console.log('nft animationUrl', error)\n      }\n\n      // myLog(\"animationUrl\", \"content-type\", req.headers.get(\"content-type\"));\n    }\n\n    return tokenInfo\n  }, [])\n\n  const renderNFTPromise = React.useCallback(async ({ nftLists }: { nftLists: T[] }) => {\n    let mediaPromise: any[] = []\n    for (const nftBalanceItem of nftLists) {\n      mediaPromise.push(infoDetail(nftBalanceItem))\n    }\n    return Promise.all(mediaPromise)\n  }, [])\n\n  return { renderNFTPromise, infoDetail, nftListReduce }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/common/useNotification.ts",
    "content": "import * as sdk from '@loopring-web/loopring-sdk'\nimport {\n  InvestAssetRouter,\n  MapChainId,\n  RecordTabIndex,\n  RouterPath,\n  SDK_ERROR_MAP_TO_UI,\n} from '@loopring-web/common-resources'\nimport { useHistory } from 'react-router-dom'\nimport React from 'react'\nimport { LoopringAPI } from '../../api_wrapper'\nimport { TOASTOPEN, ToastType, useSettings } from '@loopring-web/component-lib'\nimport { useAccount, useNotify } from '../../stores'\nimport { useTranslation } from 'react-i18next'\n\nexport const useNotificationFunc = <R extends sdk.UserNotification>({\n  setToastOpen,\n}: {\n  setToastOpen?: (state: TOASTOPEN) => void\n}) => {\n  const { account } = useAccount()\n  const { t } = useTranslation()\n  const { defaultNetwork } = useSettings()\n  const { getUserNotify } = useNotify()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const networkWallet: sdk.NetworkWallet = [\n    sdk.NetworkWallet.ETHEREUM,\n    sdk.NetworkWallet.GOERLI,\n    sdk.NetworkWallet.SEPOLIA,\n  ].includes(network as sdk.NetworkWallet)\n    ? sdk.NetworkWallet.ETHEREUM\n    : sdk.NetworkWallet[network]\n  const onReadClick = React.useCallback(\n    async (_index: number, item: R) => {\n      try {\n        const response = await LoopringAPI.userAPI?.submitNotificationReadOne(\n          {\n            id: item.id,\n            accountId: account.accountId,\n          },\n          account?.eddsaKey?.sk,\n          account.apiKey,\n        )\n        if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n          throw response\n        } else {\n        }\n      } catch (error) {\n        let errorItem\n        if (typeof (error as sdk.RESULT_INFO)?.code === 'number') {\n          errorItem = SDK_ERROR_MAP_TO_UI[(error as sdk.RESULT_INFO)?.code ?? 700001]\n        } else {\n          errorItem = SDK_ERROR_MAP_TO_UI[700012]\n        }\n        setToastOpen &&\n          setToastOpen({\n            open: true,\n            type: ToastType.error,\n            content: 'error : ' + errorItem ? t(errorItem.messageKey) : (error as any)?.message,\n          })\n      }\n      getUserNotify()\n    },\n    [account.accAddress],\n  )\n  // setShowLoading(true)\n  const onReadAllClick = React.useCallback(async () => {\n    try {\n      const response = await LoopringAPI.userAPI?.submitNotificationReadAll(\n        {\n          network: networkWallet,\n          accountId: account.accountId,\n        },\n        account?.eddsaKey?.sk,\n        account.apiKey,\n      )\n      if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n        throw response\n      } else {\n      }\n      getUserNotify()\n    } catch (error) {\n      let errorItem\n      if (typeof (error as sdk.RESULT_INFO)?.code === 'number') {\n        errorItem = SDK_ERROR_MAP_TO_UI[(error as sdk.RESULT_INFO)?.code ?? 700001]\n      } else {\n        errorItem = SDK_ERROR_MAP_TO_UI[700012]\n      }\n      setToastOpen &&\n        setToastOpen({\n          open: true,\n          type: ToastType.error,\n          content: 'error : ' + errorItem ? t(errorItem.messageKey) : (error as any)?.message,\n        })\n    }\n  }, [account.accAddress])\n\n  const onClearAllClick = React.useCallback(async () => {\n    try {\n      const response = await LoopringAPI.userAPI?.submitNotificationClear(\n        {\n          network: networkWallet,\n          accountId: account.accountId,\n        },\n        account?.eddsaKey?.sk,\n        account.apiKey,\n      )\n      if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n        throw response\n      } else {\n      }\n      getUserNotify()\n    } catch (error) {\n      let errorItem\n      if (typeof (error as sdk.RESULT_INFO)?.code === 'number') {\n        errorItem = SDK_ERROR_MAP_TO_UI[(error as sdk.RESULT_INFO)?.code ?? 700001]\n      } else {\n        errorItem = SDK_ERROR_MAP_TO_UI[700012]\n      }\n      setToastOpen &&\n        setToastOpen({\n          open: true,\n          type: ToastType.error,\n          content: 'error : ' + errorItem ? t(errorItem.messageKey) : (error as any)?.message,\n        })\n    }\n  }, [account.accAddress])\n  return {\n    onReadClick,\n    onReadAllClick,\n    onClearAllClick,\n  }\n}\nexport const useNotification = <R extends sdk.UserNotification>({\n  onReadClick,\n  index,\n  ...rest\n}: R & {\n  index: number\n  onReadClick: (index: number, rest: any) => void\n}) => {\n  const history = useHistory()\n  const { messageType, redirectionContext } = rest\n  let ele: any = {\n    i18nKey: '',\n    active: undefined,\n  }\n  const params = JSON.parse(redirectionContext ? redirectionContext : '{}')\n  switch (messageType) {\n    case sdk.NotificationMessageType.L1_CREATED:\n      ele.i18nKey = 'labelActiveL1successfulNote' //Active L1 Account successful\n      ele.active = undefined\n      break\n    case sdk.NotificationMessageType.L2_CREATED:\n      ele.i18nKey = 'labelActiveL2successfulNote' //Active L2 Account successful\n      ele.active = undefined\n      break\n    case sdk.NotificationMessageType.L1_CREATING:\n      ele.i18nKey = 'labelActivatingL1AccountNote' //Active L2 Account successful\n      ele.active = undefined\n      break\n    case sdk.NotificationMessageType.L1_RECEIVE:\n      ele.i18nKey = 'labelL1ReceiveNote'\n      ele.active = undefined\n      break\n    case sdk.NotificationMessageType.L1_SEND:\n      ele.i18nKey = 'labelL1SendNote'\n      ele.active = undefined\n      break\n    case sdk.NotificationMessageType.L2_RECEIVE:\n      ele.i18nKey = 'labelL2ReceiveNote'\n      ele.active = () => {\n        onReadClick(index, rest)\n        history.push(`${RouterPath.l2records}/${RecordTabIndex.Transactions}`)\n      }\n      break\n    case sdk.NotificationMessageType.L2_SEND:\n      ele.i18nKey = 'labelL2SendNote'\n      ele.active = undefined\n      ele.active = () => {\n        onReadClick(index, rest)\n        history.push(`${RouterPath.l2records}/${RecordTabIndex.Transactions}`)\n      }\n      break\n    case sdk.NotificationMessageType.DEPOSIT:\n      ele.i18nKey = 'labelL2DepositNote'\n      ele.active = () => {\n        onReadClick(index, rest)\n        history.push(`${RouterPath.l2records}/${RecordTabIndex.Transactions}`)\n      }\n      break\n    case sdk.NotificationMessageType.WITHDRAW:\n      ele.i18nKey = 'labelL2WithdrawNote'\n      ele.active = () => {\n        onReadClick(index, rest)\n        history.push(`${RouterPath.l2records}/${RecordTabIndex.Transactions}`)\n      }\n      break\n    case sdk.NotificationMessageType.DUAL_SETTLED:\n      ele.i18nKey = 'labelL2DualNote'\n      ele.active = () => {\n        onReadClick(index, rest)\n        history.push(\n          `${RouterPath.l2records}/${RecordTabIndex.DualRecords}?hash=${params.hash} &show=detail`,\n        )\n      }\n      break\n    case sdk.NotificationMessageType.DUAL_RECURES_ORDER_SWAP:\n      ele.i18nKey = 'labelL2DualNote'\n      ele.active = () => {\n        onReadClick(index, rest)\n        history.push(\n          `${RouterPath.l2records}/${RecordTabIndex.DualRecords}?hash=${params.hash} &show=detail`,\n        )\n      }\n      break\n    case sdk.NotificationMessageType.DUAL_RECURES_RETRY_FAILED:\n      ele.i18nKey = 'labelL2DualNote'\n      ele.active = () => {\n        onReadClick(index, rest)\n        history.push(\n          `${RouterPath.l2records}/${RecordTabIndex.DualRecords}?hash=${params.hash} &show=detail`,\n        )\n      }\n      break\n    case sdk.NotificationMessageType.DUAL_RECURES_RETRY_SUCCESS:\n      ele.i18nKey = 'labelL2DualNote'\n      ele.active = () => {\n        onReadClick(index, rest)\n        history.push(\n          `${RouterPath.investBalance}/${InvestAssetRouter.DUAL}?hash=${params.hash} &show=detail`,\n        )\n      }\n      break\n    case sdk.NotificationMessageType.DUAL_PRICE_ALERT:\n      ele.i18nKey = 'labelL2DualNote'\n      ele.active = () => {\n        onReadClick(index, rest)\n        history.push(\n          `${RouterPath.investBalance}/${InvestAssetRouter.DUAL}?hash=${params.hash} &show=detail`,\n        )\n      }\n      break\n    default:\n      ele.i18nKey = 'labelNotificationLabel'\n      ele.active = () => {\n        onReadClick(index, rest)\n        history.push(\n          `${RouterPath.investBalance}/${InvestAssetRouter.DUAL}?hash=${params.hash} &show=detail`,\n        )\n      }\n\n      break\n  }\n  return ele\n}\n"
  },
  {
    "path": "packages/core/src/hooks/common/usePairMatch.ts",
    "content": "import { useRouteMatch } from 'react-router-dom'\nimport { useTokenMap } from '../../stores/token'\nimport { getExistedMarket } from '@loopring-web/loopring-sdk'\nimport { MarketType } from '@loopring-web/common-resources'\n\nexport function usePairMatch({\n  path,\n  coinA = 'LRC',\n  coinB = 'ETH',\n  marketArray = undefined,\n  tokenMap = undefined,\n}: {\n  path: string\n  coinA?: string\n  coinB?: string\n  marketArray?: string[]\n  tokenMap?: any\n}): {\n  realMarket: MarketType | undefined\n  realPair: any\n} {\n  const { coinMap, tokenMap: _tokenMap, marketArray: _marketArray } = useTokenMap()\n  if (marketArray) {\n  } else {\n    marketArray = _marketArray\n    tokenMap = _tokenMap\n  }\n  const match: any = useRouteMatch(`${path}/:market`)\n\n  // const [pair, setPair] = useState<{ coinAInfo: CoinInfo<C> | undefined, coinBInfo: CoinInfo<C> | undefined }>({ coinAInfo: undefined, coinBInfo: undefined})\n  // const [realMarket, setRealMarket] = useState('')\n  // React.useEffect(()=>{\n\n  if (!coinMap || !tokenMap || !marketArray) {\n    return { realMarket: undefined, realPair: undefined }\n  }\n\n  let market = match?.params?.market\n  // myLog('router pair',market)\n  // let coinA = \"LRC\";\n  //\n  // let coinB = \"ETH\";\n\n  let realMarket: MarketType | undefined = `${coinA}-${coinB}`\n\n  let coinAInfo = coinMap[coinA]\n  let coinBInfo = coinMap[coinB]\n\n  if (market) {\n    const matchRes = market.match(/(\\w+)-(\\w+)/i)\n\n    if (matchRes && matchRes.length >= 3 && coinMap[matchRes[1]] && coinMap[matchRes[2]]) {\n      coinA = matchRes[1]\n      coinB = matchRes[2]\n    }\n    const marketTemp = getExistedMarket(marketArray, coinA, coinB).market\n    if (marketTemp) {\n      realMarket = marketTemp\n      coinAInfo = coinMap[coinA]\n      coinBInfo = coinMap[coinB]\n    } else {\n      if (tokenMap[coinA]) {\n        coinAInfo = coinMap[coinA]\n        coinB = tokenMap[coinA]?.tradePairs[0]\n        coinBInfo = coinMap[coinB]\n        realMarket = `${coinA}-${coinB}`\n      } else {\n        // @ts-ignore\n        ;[_, coinA, coinB] = marketArray[0]?.match(/(\\w+)-(\\w+)/i) ?? ['', 'LRC', 'ETH']\n        coinAInfo = coinMap[coinA]\n        coinBInfo = coinMap[coinB]\n        realMarket = `${coinA}-${coinB}`\n      }\n    }\n  }\n\n  // setPair({ coinAInfo, coinBInfo, })\n  // setRealMarket(realMarket)\n  // },[])\n  return {\n    realMarket,\n    realPair: { coinAInfo, coinBInfo },\n    // setPair,\n    // setMarket,\n  }\n}\n\nexport const isTradePairMarket = (tradePair: MarketType, market: MarketType) => {\n  const [_, base, quote] = tradePair.match(/(\\w+)-(\\w+)/i) ?? []\n  return (\n    market.toUpperCase() === `${base}-${quote}`.toUpperCase() ||\n    market.toUpperCase() === `${quote}-${base}`.toUpperCase()\n  )\n}\n"
  },
  {
    "path": "packages/core/src/hooks/common/useThrottle.ts",
    "content": "import _ from \"lodash\"\nimport { useCallback, useEffect, useRef } from \"react\";\n\nexport function useThrottle(cb, delay) {\n  const options = { leading: true, trailing: false }; // add custom lodash options\n  const cbRef = useRef(cb);\n  // use mutable ref to make useCallback/throttle not depend on `cb` dep\n  useEffect(() => { cbRef.current = cb; });\n  return useCallback(\n    _.throttle((...args) => cbRef.current(...args), delay, options),\n    [delay]\n  );\n}"
  },
  {
    "path": "packages/core/src/hooks/common/useToast.ts",
    "content": "import React from 'react'\nimport { TOASTOPEN, ToastType, TOSTOBJECT } from '@loopring-web/component-lib'\n\nexport const useToast = (): TOSTOBJECT => {\n  const [toastOpen, setToastOpen] = React.useState<TOASTOPEN>({\n    open: false,\n    content: '',\n    type: ToastType.info,\n  })\n\n  const closeToast = React.useCallback(() => {\n    setToastOpen((state) => {\n      return {\n        ...state,\n        content: '',\n        open: false,\n      }\n    })\n  }, [setToastOpen])\n\n  return {\n    toastOpen,\n    setToastOpen,\n    closeToast,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/common/useTrade.ts",
    "content": "import React from 'react'\n\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nimport {\n  AccountStatus,\n  defaultSlipage,\n  getValuePrecisionThousand,\n  myError,\n  myLog,\n} from '@loopring-web/common-resources'\nimport {\n  DAYS,\n  getTimestampDaysLater,\n  MAPFEEBIPS,\n  OrderInfoPatch,\n  store,\n  useAccount,\n  useAmmMap,\n  useSystem,\n  useTicker,\n  useTokenMap,\n} from '../../index'\nimport * as _ from 'lodash'\nimport BigNumber from 'bignumber.js'\n\nexport const DefaultFeeBips = '1'\n\nexport enum PriceLevel {\n  Normal,\n  Lv1,\n  Lv2,\n}\n\nexport type ReqParams = {\n  isBuy?: boolean\n\n  price?: number\n  amountBase?: number\n  amountQuote?: number\n  base?: string\n  quote?: string\n  market?: string\n\n  tokenMap?: sdk.LoopringMap<sdk.TokenInfo>\n  marketArray?: string[]\n  marketMap?: any\n\n  exchangeAddress?: string\n  accountId?: number\n  storageId?: number\n\n  feeBips?: string\n\n  // key is ETH or USDT\n  tokenAmtMap?: { [key: string]: sdk.TokenAmount }\n  tokenMarketMap?: { [key: string]: sdk.TokenAmount }\n\n  ammPoolSnapshot?: sdk.AmmPoolSnapshot\n  depth?: sdk.DepthData\n  slippage?: string\n}\n\nexport function makeMarketReq({\n  isBuy,\n\n  amountBase,\n  amountQuote,\n  base,\n  quote,\n\n  tokenMap,\n  marketArray,\n  marketMap,\n\n  exchangeAddress,\n  accountId,\n  storageId,\n\n  feeBips,\n  // tokenAmtMap,\n  tokenMarketMap,\n  depth,\n  ammPoolSnapshot,\n  slippage = (defaultSlipage * 100).toString(),\n}: ReqParams) {\n  if (\n    !tokenMap ||\n    !exchangeAddress ||\n    !marketArray ||\n    accountId === undefined ||\n    !base ||\n    !quote ||\n    (!depth && !ammPoolSnapshot)\n  ) {\n    return {\n      sellUserOrderInfo: undefined,\n      buyUserOrderInfo: undefined,\n      minOrderInfo: undefined,\n      calcTradeParams: undefined,\n      marketRequest: undefined,\n    }\n  }\n\n  if (isBuy === undefined) {\n    isBuy = true\n  }\n\n  if (feeBips === undefined) {\n    feeBips = DefaultFeeBips\n  }\n\n  if (!storageId) {\n    storageId = 0\n  }\n\n  const baseTokenInfo = tokenMap[base]\n  const quoteTokenInfo = tokenMap[quote]\n\n  const sellTokenInfo = isBuy ? quoteTokenInfo : baseTokenInfo\n  const buyTokenInfo = isBuy ? baseTokenInfo : quoteTokenInfo\n\n  let input = (\n    amountBase !== undefined ? amountBase : amountQuote !== undefined ? amountQuote : 0\n  )?.toString()\n\n  const sell = sellTokenInfo.symbol\n  const buy = buyTokenInfo.symbol\n\n  // buy. amountSell is not null.\n  const isAtoB = (isBuy && amountQuote !== undefined) || (!isBuy && amountBase !== undefined)\n\n  const calcTradeParams = sdk.getOutputAmount({\n    input,\n    sell,\n    buy,\n    isAtoB,\n    marketArr: marketArray,\n    tokenMap: tokenMap as any,\n    marketMap: marketMap as any,\n    depth: depth as sdk.DepthData,\n    ammPoolSnapshot: ammPoolSnapshot,\n    feeBips: feeBips ? feeBips.toString() : DefaultFeeBips,\n    takerRate: '0',\n    slipBips: slippage,\n  })\n\n  let minOrderInfo,\n    totalFeeRaw,\n    totalFee,\n    tradeCost,\n    feeTakerRate,\n    maxFeeBips: number = MAPFEEBIPS,\n    buyUserOrderInfo,\n    sellUserOrderInfo\n  if (tokenMarketMap && slippage) {\n    buyUserOrderInfo = tokenMarketMap[buy] ? tokenMarketMap[buy].userOrderInfo : undefined\n    sellUserOrderInfo = tokenMarketMap[sell] ? tokenMarketMap[sell].userOrderInfo : undefined\n    const minSymbol = buy\n    const inputAmount = buyUserOrderInfo\n\n    const minInput = sdk\n      .toBig(inputAmount?.minAmount ?? '')\n      .div(sdk.toBig(1).minus(sdk.toBig(slippage).div(10000)))\n      .div('1e' + buyTokenInfo.decimals)\n      .toString()\n    feeTakerRate = buyUserOrderInfo?.takerRate\n    const calcForMinAmt = sdk.getOutputAmount({\n      input: minInput,\n      sell,\n      buy,\n      isAtoB: false,\n      marketArr: marketArray,\n      tokenMap: tokenMap as any,\n      marketMap: marketMap as any,\n      depth: depth as sdk.DepthData,\n      ammPoolSnapshot,\n      feeBips: feeBips ? feeBips.toString() : DefaultFeeBips,\n      takerRate: '0',\n      slipBips: slippage,\n    })\n\n    myLog(\n      `inputAmount ${minSymbol} minAmount:`,\n      inputAmount?.minAmount,\n      `, Market minAmount: with slippage:${slippage}:`,\n      sdk\n        .toBig(inputAmount?.minAmount ?? '')\n        .div(sdk.toBig(1).minus(sdk.toBig(slippage).div(10000)))\n        .toString(),\n      `, dustToken:`,\n      sell,\n    )\n\n    /*** calc for Price Impact ****/\n    const sellMinAmtInfo = tokenMarketMap[sellTokenInfo.symbol]\n    const sellMinAmtInput = sdk\n      .toBig(sellMinAmtInfo.baseOrderInfo.minAmount)\n      .div('1e' + sellTokenInfo.decimals)\n      .toString()\n\n    const calcForPriceImpact = sdk.getOutputAmount({\n      input: sellMinAmtInput,\n      sell,\n      buy,\n      isAtoB: true,\n      marketArr: marketArray,\n      tokenMap: tokenMap as any,\n      marketMap: marketMap as any,\n      depth: depth as sdk.DepthData,\n      ammPoolSnapshot,\n      feeBips: feeBips ? feeBips.toString() : DefaultFeeBips,\n      takerRate: '0',\n      slipBips: '10',\n    })\n    myLog(\n      'calcForPriceImpact input:',\n      sellMinAmtInput,\n      ', calcForPriceImpact basePrice: ',\n      sdk.toBig(calcForPriceImpact?.output).div(sellMinAmtInput).toNumber(),\n    )\n    const basePrice = sdk.toBig(calcForPriceImpact?.output).div(sellMinAmtInput)\n    const tradePrice = sdk\n      .toBig(calcTradeParams?.amountBOutSlip?.minReceivedVal ?? 0)\n      .div(isAtoB ? input.toString() : calcTradeParams?.output)\n    const priceImpact = sdk\n      .toBig(1)\n      .minus(sdk.toBig(tradePrice).div(basePrice ?? 1))\n      .minus(0.001)\n    if (calcTradeParams && priceImpact.gte(0)) {\n      calcTradeParams.priceImpact = priceImpact.toFixed(4, 1)\n    } else {\n      calcTradeParams && (calcTradeParams.priceImpact = '0')\n    }\n    myLog(\n      'calcTradeParams input:',\n      input.toString(),\n      ', calcTradeParams Price: ',\n      sdk\n        .toBig(calcTradeParams?.amountBOutSlip?.minReceivedVal ?? 0)\n        .div(input.toString())\n        .toNumber(),\n      `isBuy:${isAtoB}, ${isAtoB ? input.toString() : calcTradeParams?.output} tradePrice: `,\n      tradePrice.toString(),\n      'basePrice: ',\n      basePrice?.toString(),\n      'toBig(tradePrice).div(basePrice)',\n      sdk\n        .toBig(tradePrice)\n        .div(basePrice ?? 1)\n        .toNumber(),\n      'priceImpact (1-tradePrice/basePrice) - 0.001',\n      priceImpact.toNumber(),\n      'priceImpact view',\n      calcTradeParams?.priceImpact,\n    )\n\n    /**** calc for min Cost ****/\n    tradeCost = tokenMarketMap[buy].tradeCost\n    let dustToken = tokenMap[buy]\n    let sellToken = tokenMap[sell]\n    let calcForMinCostInput = BigNumber.max(\n      sdk.toBig(tradeCost).times(2),\n      dustToken.orderAmounts.dust,\n    )\n\n    myLog(dustToken.symbol)\n\n    const tradeCostInput = sdk\n      .toBig(calcForMinCostInput)\n      .div(sdk.toBig(1).minus(sdk.toBig(slippage).div(10000)))\n      .div('1e' + tokenMap[buy].decimals)\n      .toString()\n    const calcForMinCost = sdk.getOutputAmount({\n      input: tradeCostInput,\n      sell,\n      buy,\n      isAtoB: false,\n      marketArr: marketArray,\n      tokenMap: tokenMap as any,\n      marketMap: marketMap as any,\n      depth: depth as sdk.DepthData,\n      ammPoolSnapshot,\n      feeBips: feeBips ? feeBips.toString() : DefaultFeeBips,\n      takerRate: '0',\n      slipBips: slippage,\n    })\n    const minAmt = BigNumber.max(sellToken.orderAmounts.dust, calcForMinCost?.amountS ?? 0)\n    minOrderInfo = {\n      minAmount: minAmt,\n      minAmtShow:\n        minAmt &&\n        sdk\n          .toBig(minAmt)\n          .times(1.1)\n          .div('1e' + tokenMap[sell].decimals)\n          .toNumber(),\n      symbol: sell,\n      minAmtCheck: sdk.toBig(calcTradeParams?.amountS ?? 0).gte(sdk.toBig(minAmt).times(1.1) ?? 0),\n    }\n\n    if (\n      tradeCost &&\n      calcTradeParams &&\n      calcTradeParams.amountBOutSlip?.minReceived &&\n      feeTakerRate\n    ) {\n      let value = sdk\n        .toBig(calcTradeParams.amountBOutSlip?.minReceived)\n        .times(feeTakerRate)\n        .div(10000)\n\n      myLog(\n        'input Accounts',\n        calcTradeParams?.amountS,\n        '100 U calcForMinAmt:',\n        calcForMinAmt?.amountS,\n      )\n\n      let validAmt = !!(\n        calcTradeParams?.amountS &&\n        calcForMinAmt?.amountS &&\n        sdk.toBig(calcTradeParams?.amountS).gte(calcForMinAmt.amountS)\n      )\n\n      myLog(\n        `${minSymbol} tradeCost:`,\n        tradeCost,\n        'useTakeRate Fee:',\n        value.toString(),\n        'calcForMinAmt?.amountS:',\n        calcForMinAmt?.amountS,\n        `is setup minTrade amount, ${calcForMinAmt?.amountS}:`,\n        validAmt,\n      )\n\n      if (!validAmt) {\n        if (sdk.toBig(tradeCost).gte(value)) {\n          totalFeeRaw = sdk.toBig(tradeCost)\n        } else {\n          totalFeeRaw = value\n        }\n        myLog(\n          'maxFeeBips update for tradeCost before value:',\n          maxFeeBips,\n          'totalFeeRaw',\n          totalFeeRaw.toString(),\n        )\n        maxFeeBips = Math.ceil(\n          totalFeeRaw.times(10000).div(calcTradeParams.amountBOutSlip?.minReceived).toNumber(),\n        )\n        myLog('maxFeeBips update for tradeCost after value:', maxFeeBips)\n      } else {\n        totalFeeRaw = sdk.toBig(value)\n      }\n\n      totalFee = getValuePrecisionThousand(\n        totalFeeRaw.div('1e' + tokenMap[minSymbol].decimals).toString(),\n        tokenMap[minSymbol].precision,\n        tokenMap[minSymbol].precision,\n        tokenMap[minSymbol].precision,\n        false,\n        { floor: true },\n      )\n      tradeCost = getValuePrecisionThousand(\n        sdk\n          .toBig(tradeCost)\n          .div('1e' + tokenMap[minSymbol].decimals)\n          .toString(),\n        tokenMap[minSymbol].precision,\n        tokenMap[minSymbol].precision,\n        tokenMap[minSymbol].precision,\n        false,\n        { floor: true },\n      )\n\n      myLog('totalFee view value:', totalFee, tradeCost)\n      myLog('tradeCost view value:', tradeCost)\n    }\n  } else {\n    myError('undefined minOrderInfo')\n  }\n\n  const tradeChannel = calcTradeParams\n    ? calcTradeParams.exceedDepth\n      ? sdk.TradeChannel.BLANK\n      : sdk.TradeChannel.MIXED\n    : undefined\n  const orderType = calcTradeParams\n    ? calcTradeParams.exceedDepth\n      ? sdk.OrderType.ClassAmm\n      : sdk.OrderType.TakerOnly\n    : undefined\n\n  const sellTokenVol3: sdk.TokenVolumeV3 = {\n    tokenId: sellTokenInfo.tokenId,\n    volume: calcTradeParams?.amountS as string,\n  }\n\n  const buyTokenVol3: sdk.TokenVolumeV3 = {\n    tokenId: buyTokenInfo.tokenId,\n    volume: calcTradeParams?.amountBOutSlip.minReceived as string,\n  }\n\n  const marketRequest: sdk.SubmitOrderRequestV3 = {\n    exchange: exchangeAddress,\n    accountId,\n    storageId,\n    sellToken: sellTokenVol3,\n    buyToken: buyTokenVol3,\n    allOrNone: false,\n    validUntil: getTimestampDaysLater(DAYS),\n    maxFeeBips,\n    fillAmountBOrS: false, // amm only false\n    orderType,\n    tradeChannel,\n    eddsaSignature: '',\n  }\n\n  return {\n    sellUserOrderInfo,\n    buyUserOrderInfo,\n    minOrderInfo,\n    calcTradeParams: {\n      ...calcTradeParams,\n      maxFeeBips,\n    },\n    marketRequest,\n    totalFee,\n    maxFeeBips,\n    feeTakerRate,\n    tradeCost,\n  }\n}\n\nexport function makeLimitReq({\n  isBuy,\n  depth,\n  price,\n  amountBase,\n  amountQuote,\n  base,\n  quote,\n  tokenMap,\n\n  exchangeAddress,\n  accountId,\n  storageId,\n\n  feeBips,\n  tokenAmtMap,\n}: ReqParams) {\n  if (\n    !tokenMap ||\n    !exchangeAddress ||\n    !depth ||\n    accountId === undefined ||\n    !base ||\n    !quote ||\n    (!amountBase && !amountQuote)\n  ) {\n    myLog('got empty input!')\n    return {\n      sellUserOrderInfo: undefined,\n      buyUserOrderInfo: undefined,\n      calcTradeParams: undefined,\n      limitRequest: undefined,\n    }\n  }\n\n  if (price === undefined) {\n    price = 0\n  }\n\n  if (isBuy === undefined) {\n    isBuy = true\n  }\n\n  if (feeBips === undefined) {\n    feeBips = DefaultFeeBips\n  }\n\n  if (!storageId) {\n    storageId = 0\n  }\n\n  const baseTokenInfo = tokenMap[base]\n  const quoteTokenInfo = tokenMap[quote]\n\n  const sellTokenInfo = isBuy ? quoteTokenInfo : baseTokenInfo\n  const buyTokenInfo = isBuy ? baseTokenInfo : quoteTokenInfo\n\n  const sell = sellTokenInfo.symbol\n  const buy = buyTokenInfo.symbol\n\n  const sellUserOrderInfo =\n    tokenAmtMap && tokenAmtMap[sell] ? tokenAmtMap[sell].userOrderInfo : undefined\n\n  const buyUserOrderInfo =\n    tokenAmtMap && tokenAmtMap[buy] ? tokenAmtMap[buy].userOrderInfo : undefined\n\n  let baseVol: any = undefined\n  let quoteVol: any = undefined\n\n  let baseVolShow: any = undefined\n  let quoteVolShow: any = undefined\n\n  if (amountBase !== undefined) {\n    baseVolShow = amountBase\n    baseVol = sdk.toBig(baseVolShow).times('1e' + baseTokenInfo.decimals)\n    quoteVolShow = sdk.toBig(amountBase).times(sdk.toBig(price)).toFixed(quoteTokenInfo.precision)\n    quoteVol = sdk\n      .toBig(amountBase)\n      .times(sdk.toBig(price))\n      .times('1e' + quoteTokenInfo.decimals)\n  } else if (amountQuote !== undefined) {\n    baseVolShow = sdk.toBig(amountQuote).div(sdk.toBig(price)).toFixed(baseTokenInfo.precision)\n    baseVol = sdk\n      .toBig(amountQuote)\n      .div(sdk.toBig(price))\n      .times('1e' + baseTokenInfo.decimals)\n    quoteVolShow = amountQuote\n    quoteVol = sdk.toBig(amountQuote).times('1e' + quoteTokenInfo.decimals)\n  } else {\n    throw Error('no amount info!')\n  }\n\n  const baseTokenVol3: sdk.TokenVolumeV3 = {\n    tokenId: baseTokenInfo.tokenId,\n    volume: baseVol.toFixed(0, 0),\n  }\n\n  const quoteTokenVol3: sdk.TokenVolumeV3 = {\n    tokenId: quoteTokenInfo.tokenId,\n    volume: quoteVol.toFixed(0, 0),\n  }\n\n  let minOrderInfo: (sdk.OrderInfo & OrderInfoPatch) | undefined = undefined\n\n  if (sellUserOrderInfo && buyUserOrderInfo) {\n    if (!isBuy) {\n      minOrderInfo = _.cloneDeep(buyUserOrderInfo)\n      const minAmount = sdk\n        .toBig(minOrderInfo.minAmount)\n        .div('1e' + buyTokenInfo.decimals)\n        .div(sdk.toBig(price))\n      minOrderInfo.minAmtShow = minAmount.toNumber()\n      minOrderInfo.minAmount = minAmount.times('1e' + sellTokenInfo.decimals).toString()\n      minOrderInfo.symbol = sell\n      minOrderInfo.minAmtCheck = baseVol.gte(sdk.toBig(minOrderInfo.minAmount))\n    } else {\n      minOrderInfo = _.cloneDeep(buyUserOrderInfo)\n      minOrderInfo.minAmtShow = sdk\n        .toBig(minOrderInfo.minAmount)\n        .div('1e' + buyTokenInfo.decimals)\n        .toNumber()\n      minOrderInfo.symbol = buy\n      minOrderInfo.minAmtCheck = baseVol.gte(sdk.toBig(minOrderInfo.minAmount))\n    }\n  } else {\n    // throw Error('undefined minOrderInfo')\n    myError('undefined minOrderInfo')\n  }\n\n  const takerRate =\n    tokenAmtMap && tokenAmtMap[baseTokenInfo.symbol]\n      ? tokenAmtMap[baseTokenInfo.symbol].userOrderInfo.takerRate\n      : 0\n\n  const maxFeeBips = parseInt(sdk.toBig(feeBips).plus(sdk.toBig(takerRate)).toString())\n\n  const sellToken = isBuy ? quoteTokenVol3 : baseTokenVol3\n  const buyToken = isBuy ? baseTokenVol3 : quoteTokenVol3\n\n  const limitRequest: sdk.SubmitOrderRequestV3 = {\n    exchange: exchangeAddress,\n    accountId,\n    storageId,\n    sellToken,\n    buyToken,\n    allOrNone: false,\n    validUntil: getTimestampDaysLater(DAYS),\n    maxFeeBips: MAPFEEBIPS,\n    fillAmountBOrS: false, // amm only false\n    orderType: sdk.OrderType.LimitOrder,\n    tradeChannel: sdk.TradeChannel.MIXED,\n    eddsaSignature: '',\n  }\n\n  // myLog('limitRequest:', limitRequest)\n  let priceImpact = 0\n\n  const ask1 = depth.asks_prices[0]\n  const bid1 = depth.bids_prices[depth.bids_prices.length - 1]\n\n  if (isBuy && ask1 && price > ask1) {\n    priceImpact = (price - ask1) / ask1\n  } else if (!isBuy && bid1 && price < bid1) {\n    priceImpact = (bid1 - price) / bid1\n  }\n\n  const calcTradeParams = {\n    isBuy,\n    priceImpact,\n    baseVol: baseVol.toFixed(),\n    baseVolShow,\n    quoteVol: quoteVol.toFixed(),\n    quoteVolShow,\n    takerRate,\n    feeBips,\n    maxFeeBips,\n  }\n\n  return {\n    sellUserOrderInfo,\n    buyUserOrderInfo,\n    minOrderInfo,\n    calcTradeParams,\n    limitRequest,\n  }\n}\n\nexport function usePlaceOrder() {\n  const { account } = useAccount()\n\n  const { tokenMap, marketArray } = useTokenMap()\n  const { tickerMap } = useTicker()\n  const { ammMap } = useAmmMap()\n\n  const { exchangeInfo } = useSystem()\n\n  const getTokenAmtMap = React.useCallback(\n    (params: ReqParams) => {\n      const { amountMap } = store.getState().amountMap\n      if (ammMap && marketArray && amountMap) {\n        let base = params.base\n\n        let quote = params.quote\n\n        let market = params.market\n\n        let ammMarket: string\n\n        if (market) {\n          const result = market.match(/([\\w,#]+)-([\\w,#]+)/i)\n\n          if (result) {\n            ;[, base, quote] = result\n          }\n        }\n\n        const existedMarket = sdk.getExistedMarket(marketArray, base, quote)\n\n        params.base = existedMarket.baseShow\n        params.quote = existedMarket.quoteShow\n        market = existedMarket.market\n        ammMarket = existedMarket.amm as string\n\n        const tokenAmtMap = amountMap\n          ? ammMap[ammMarket]\n            ? amountMap[ammMarket]\n            : amountMap[market as string]\n          : undefined\n        const tokenMarketMap = amountMap ? amountMap[market as string] : undefined\n\n        const feeBips = ammMap[ammMarket] ? ammMap[ammMarket].__rawConfig__.feeBips : 0\n        return {\n          feeBips,\n          tokenAmtMap,\n          tokenMarketMap,\n        }\n      } else {\n        return {\n          feeBips: undefined,\n          tokenAmtMap: undefined,\n          tokenMarketMap: undefined,\n        }\n      }\n    },\n    [ammMap, marketArray],\n  )\n\n  // {isBuy, amountB or amountS, (base, quote / market), feeBips, takerRate, depth, ammPoolSnapshot, slippage, }\n  const makeMarketReqInHook = React.useCallback(\n    (params: ReqParams) => {\n      const { tokenAmtMap, tokenMarketMap, feeBips } = getTokenAmtMap(params)\n\n      // myLog('makeMarketReqInHook tokenAmtMap:', tokenAmtMap, feeBips)\n\n      if (exchangeInfo) {\n        const fullParams: ReqParams = {\n          ...params,\n          exchangeAddress: exchangeInfo.exchangeAddress,\n          accountId: account.accountId,\n          tokenMap,\n          feeBips: feeBips ? feeBips.toString() : DefaultFeeBips,\n          tokenAmtMap,\n          tokenMarketMap,\n        }\n        return makeMarketReq(fullParams)\n      } else {\n        return {\n          sellUserOrderInfo: undefined,\n          buyUserOrderInfo: undefined,\n          minOrderInfo: undefined,\n          calcTradeParams: undefined,\n          marketRequest: undefined,\n        }\n      }\n    },\n    [getTokenAmtMap, exchangeInfo, account.accountId, tokenMap],\n  )\n\n  // {isBuy, price, amountB or amountS, (base, quote / market), feeBips, takerRate, }\n  const makeLimitReqInHook = React.useCallback(\n    (params: ReqParams) => {\n      const { tokenAmtMap, feeBips } = getTokenAmtMap(params)\n\n      myLog('makeLimitReqInHook tokenAmtMap:', tokenAmtMap, feeBips)\n\n      if (exchangeInfo) {\n        const fullParams: ReqParams = {\n          ...params,\n          exchangeAddress: exchangeInfo.exchangeAddress,\n          accountId: account.accountId,\n          tokenMap,\n          feeBips: feeBips ? feeBips.toString() : DefaultFeeBips,\n          tokenAmtMap: tokenAmtMap,\n        }\n        return makeLimitReq(fullParams)\n      } else {\n        myLog('makeLimitReqInHook error no tokenAmtMap', tokenAmtMap)\n        return {\n          sellUserOrderInfo: undefined,\n          buyUserOrderInfo: undefined,\n          minOrderInfo: undefined,\n          calcTradeParams: undefined,\n          limitRequest: undefined,\n        }\n      }\n    },\n    [getTokenAmtMap, exchangeInfo, account.accountId, tokenMap],\n  )\n\n  const makeStopLimitReqInHook = React.useCallback(\n    <T extends ReqParams & { stopLimitPrice?: string | number }>(params: T) => {\n      const { tokenAmtMap, feeBips } = getTokenAmtMap(params)\n      const { tickerMap } = store.getState().tickerMap\n      myLog('makeLimitReqInHook tokenAmtMap:', tokenAmtMap, feeBips)\n      let sellUserOrderInfo: any = undefined,\n        buyUserOrderInfo: any = undefined,\n        minOrderInfo: any = undefined,\n        calcTradeParams: any = undefined,\n        stopLimitRequest: any = undefined,\n        stopSide: any = undefined\n\n      if (exchangeInfo && params?.depth?.symbol && params.quote && tickerMap) {\n        const ticker = tickerMap[params.depth.symbol]\n\n        let midStopPrice = ticker?.close\n        if (params.stopLimitPrice == undefined) {\n          params.stopLimitPrice = 0\n        }\n\n        stopSide = midStopPrice\n          ? sdk.toBig(params.stopLimitPrice).lte(midStopPrice)\n            ? sdk.STOP_SIDE.LESS_THAN_AND_EQUAL\n            : sdk.STOP_SIDE.GREAT_THAN_AND_EQUAL\n          : undefined\n        myLog(\n          'stopSide',\n          stopSide,\n          'stopLimitPrice',\n          midStopPrice,\n          'stopLimitPrice',\n          params.stopLimitPrice,\n        )\n        const fullParams: T = {\n          ...params,\n          exchangeAddress: exchangeInfo.exchangeAddress,\n          accountId: account.accountId,\n          tokenMap,\n          feeBips: feeBips ? feeBips.toString() : DefaultFeeBips,\n          tokenAmtMap: tokenAmtMap,\n        }\n        const result = makeLimitReq(fullParams)\n        sellUserOrderInfo = result.sellUserOrderInfo\n        buyUserOrderInfo = result.buyUserOrderInfo\n        minOrderInfo = result.minOrderInfo\n        calcTradeParams = result.calcTradeParams\n        stopLimitRequest = {\n          ...result.limitRequest,\n          stopPrice: params.stopLimitPrice,\n          stopSide,\n          extraOrderType: sdk.EXTRAORDER_TYPE.STOP_LIMIT,\n        }\n      } else {\n        myLog('makeLimitReqInHook error no tokenAmtMap', tokenAmtMap)\n      }\n      return {\n        // stopRange,\n        sellUserOrderInfo,\n        buyUserOrderInfo,\n        minOrderInfo,\n        calcTradeParams,\n        stopLimitRequest,\n      }\n    },\n    [getTokenAmtMap, exchangeInfo, account.accountId, tokenMap, tickerMap],\n  )\n\n  return {\n    makeMarketReqInHook,\n    makeLimitReqInHook,\n    makeStopLimitReqInHook,\n  }\n}\n\nexport const getPriceImpactInfo = (\n  calcTradeParams: any,\n  accountStatus: keyof typeof AccountStatus | 'unknown',\n  isMarket: boolean = true,\n) => {\n  let priceImpact: any = calcTradeParams?.priceImpact\n    ? parseFloat(calcTradeParams?.priceImpact) * 100\n    : undefined\n  let priceImpactColor = 'var(--color-success)'\n\n  let priceLevel = PriceLevel.Normal\n\n  if (isMarket) {\n    if (priceImpact) {\n      if (priceImpact > 0.1 && priceImpact <= 1) {\n        priceImpactColor = 'var(--color-success)'\n      } else if (priceImpact > 1 && priceImpact <= 3) {\n        priceImpactColor = 'textPrimary'\n      } else if (priceImpact > 3 && priceImpact <= 5) {\n        priceImpactColor = 'var(--color-warning)'\n      } else if (priceImpact > 5 && priceImpact <= 10) {\n        priceImpactColor = 'var(--color-error)'\n        priceLevel = PriceLevel.Lv1\n      } else if (priceImpact > 10) {\n        priceImpactColor = 'var(--color-error)'\n        priceLevel = PriceLevel.Lv2\n      }\n    } else {\n      priceImpactColor = 'var(--color-text-primary)'\n    }\n  } else {\n    if (priceImpact > 10) {\n      priceImpactColor = 'var(--color-error)'\n      priceLevel = PriceLevel.Lv1\n    }\n  }\n\n  return {\n    value: priceImpact,\n    priceImpactColor:\n      accountStatus === AccountStatus.ACTIVATED ? priceImpactColor : 'var(--color-text-primary)',\n    priceLevel,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/common/useUserWallets.ts",
    "content": "import React from 'react'\nimport { SagaStatus } from '@loopring-web/common-resources'\nimport { useWalletLayer1, useWalletLayer2, useVaultLayer2,store } from '../../stores'\n\nexport const useUserWallets = (): {\n  updateUserWallets: () => void\n} => {\n  const { updateWalletLayer1 } = useWalletLayer1()\n  const { updateWalletLayer2 } = useWalletLayer2()\n  const { updateVaultLayer2 } = useVaultLayer2()\n\n  const updateUserWallets = React.useCallback(() => {\n    const walletLayer1Status = store.getState().walletLayer1.status\n    const walletLayer2Status = store.getState().walletLayer2.status\n    const vaultLayer2Status = store.getState().vaultLayer2.status\n    if (walletLayer1Status !== SagaStatus.PENDING) {\n      updateWalletLayer1()\n    }\n    if (walletLayer2Status !== SagaStatus.PENDING) {\n      updateWalletLayer2()\n    }\n    if (vaultLayer2Status !== SagaStatus.PENDING) {\n      updateVaultLayer2({})\n    }\n  }, [\n    updateWalletLayer1,\n    updateWalletLayer2,\n    updateVaultLayer2,\n  ])\n\n  return { updateUserWallets }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/help/coinPairInit.ts",
    "content": "export function coinPairInit({ coinKey, _tradeCalcData, tokenMap, coinMap }: any) {\n  if (coinKey) {\n    const [_match, sell, buy] = coinKey.match(/(\\w+)-(\\w+)/i)\n    // @ts-ignore\n    if (sell && coinMap && coinMap[sell]) {\n      _tradeCalcData.coinSell = sell\n    } // @ts-ignore\n    if (\n      sell !== buy &&\n      buy &&\n      -1 !== tokenMap[sell].tradePairs.findIndex((ele: any) => ele === buy)\n    ) {\n      _tradeCalcData.coinBuy = buy\n      return _tradeCalcData\n    }\n  }\n  if (!_tradeCalcData.coinSell || _tradeCalcData.coinSell === '') {\n    _tradeCalcData.coinSell = 'LRC'\n    _tradeCalcData.coinBuy = 'ETH'\n    return _tradeCalcData\n  }\n  if (\n    !_tradeCalcData.coinBuy ||\n    _tradeCalcData.coinBuy === '' ||\n    _tradeCalcData.coinBuy === 'undefined'\n  ) {\n    // @ts-ignore\n    if (tokenMap && tokenMap[_tradeCalcData.coinSell]?.tradePairs) {\n      _tradeCalcData.coinBuy = tokenMap[_tradeCalcData.coinSell]?.tradePairs[0]\n    } else {\n      _tradeCalcData.coinSell = 'LRC'\n      _tradeCalcData.coinBuy = 'ETH'\n    }\n  }\n  return _tradeCalcData\n}\n"
  },
  {
    "path": "packages/core/src/hooks/help/connectStatusCallback.tsx",
    "content": "import {\n  AccountStep,\n  setShowAccount,\n  setShowWrongNetworkGuide,\n} from '@loopring-web/component-lib'\nimport { AccountStatus, fnType, myLog, SPECIAL_ACTIVATION_NETWORKS } from '@loopring-web/common-resources'\nimport { accountReducer, store, unlockAccount, appKit } from '../../index'\nimport _ from 'lodash'\nimport { ChainId } from '@loopring-web/loopring-sdk'\n\nexport const accountStaticCallBack = (\n  onclickMap: { [key: number]: [fn: (props: any) => any, args?: any[]] },\n  deps?: any[],\n) => {\n  const { readyState } = store.getState().account\n\n  let fn, args\n  ;[fn, args] = onclickMap[readyState] ? onclickMap[readyState] : []\n  if (typeof fn === 'function') {\n    args = [...(args ?? []), ...(deps ?? [])] as [props: any]\n    return fn.apply(this, args)\n  }\n}\nconst activeBtnLabelFn = function (options?: {chainId: ChainId, isEarn: boolean, readyState: AccountStatus}) {\n  const isSpecialActivation = options?.isEarn && SPECIAL_ACTIVATION_NETWORKS.includes(options.chainId)\n  if (isSpecialActivation) {\n    return options?.readyState === AccountStatus.NOT_ACTIVE ? 'Complete Sign in' : 'labelDeposit'\n  } else {\n    return 'labelDepositAndActiveBtn'\n  }\n}\n\nexport const btnLabel = {\n  [fnType.UN_CONNECT]: [\n    function () {\n      return `labelConnectWallet`\n    },\n  ],\n  [fnType.ERROR_NETWORK]: [\n    function () {\n      return `labelWrongNetwork`\n    },\n  ],\n  [fnType.NO_ACCOUNT]: [activeBtnLabelFn],\n  [fnType.DEFAULT]: [activeBtnLabelFn],\n  [fnType.DEPOSITING]: [activeBtnLabelFn],\n  [fnType.NOT_ACTIVE]: [activeBtnLabelFn],\n  [fnType.ACTIVATED]: [\n    function () {\n      return undefined\n    },\n  ],\n  [fnType.LOCKED]: [\n    function () {\n      return `labelUnLockLayer2`\n    },\n  ],\n}\nexport const goActiveAccount = async (options?: {\n  chainId: ChainId\n  isEarn: boolean\n  readyState: AccountStatus\n  specialActivation: () => Promise<void>\n  specialActivationDeposit: () => Promise<void>\n}) => {\n  const isSpecialActivation = options?.isEarn && SPECIAL_ACTIVATION_NETWORKS.includes(options.chainId)\n  if (isSpecialActivation) {\n    if (options.readyState === AccountStatus.NOT_ACTIVE) {\n      return options.specialActivation()\n    } else {\n      return options.specialActivationDeposit()\n    }\n  } else {\n    store.dispatch(accountReducer.changeShowModel({ _userOnModel: false }))\n    store.dispatch(setShowAccount({ isShow: true, step: AccountStep.CreateAccount_EOA_Only_Alert }))\n  }\n}\nexport const geDepositingActive = () => {\n  // const { system, localStore, account } = store.getState();\n  // const isDepositing =\n  //   localStore.chainHashInfos[system?.chainId].depositHashes[\n  //     account?.accAddress\n  //     ];\n  // if(isDepositing){\n  //\n  // }else{\n  //\n  // }\n}\n\nexport const btnClickMap: {\n  [key: string]: [fn: (props: any) => any, args?: any[]]\n} = {\n  [fnType.ERROR_NETWORK]: [\n    function () {\n      store.dispatch(accountReducer.changeShowModel({ _userOnModel: false }))\n      store.dispatch(setShowWrongNetworkGuide({ isShow: true }))\n    },\n  ],\n  [fnType.UN_CONNECT]: [\n    function () {\n      myLog('UN_CONNECT!')\n      appKit.open()\n    },\n  ],\n  [fnType.NO_ACCOUNT]: [goActiveAccount],\n  [fnType.DEPOSITING]: [goActiveAccount],\n  [fnType.NOT_ACTIVE]: [goActiveAccount],\n  [fnType.LOCKED]: [\n    async function () {\n      unlockAccount()\n      store.dispatch(accountReducer.changeShowModel({ _userOnModel: true }))\n    },\n  ],\n}\n\nexport const btnConnectL1kMap = Object.assign(_.cloneDeep(btnClickMap), {\n  [fnType.ACTIVATED]: [\n    function () {\n      appKit.open()\n    },\n  ],\n  [fnType.NO_ACCOUNT]: [\n    function () {\n      appKit.open()\n    },\n  ],\n  [fnType.DEPOSITING]: [\n    function () {\n      appKit.open()\n    },\n  ],\n  [fnType.NOT_ACTIVE]: [\n    function () {\n      appKit.open()\n      \n    },\n  ],\n  [fnType.LOCKED]: [\n    function () {\n      appKit.open()\n    },\n  ],\n})\n"
  },
  {
    "path": "packages/core/src/hooks/help/formatPrice.ts",
    "content": "import { getExistedMarket, toBig } from '@loopring-web/loopring-sdk'\nimport { store } from '../../index'\n\nexport function formatedVal(rawData: string, base: string, quote: string) {\n  const { marketMap, marketArray } = store.getState().tokenMap\n\n  if (!rawData || !base || !quote || !marketMap || !marketArray) {\n    return ''\n  }\n\n  const { market } = getExistedMarket(marketArray, base, quote)\n  const marketInfo = marketMap[market]\n\n  const showVal = toBig(rawData).toFixed(marketInfo.precisionForPrice)\n\n  return showVal\n}\n"
  },
  {
    "path": "packages/core/src/hooks/help/index.ts",
    "content": "export * from './coinPairInit'\nexport * from './connectStatusCallback'\nexport * from './makeCache'\nexport * from './makeTickView'\nexport * from './makeUIAmmActivityMap'\nexport * from './makeWallet'\nexport * from './marketTable'\nexport * from './volumeToCount'\nexport * from './useAmmTotalValue'\nexport * from './marketPairHelp'\nexport * from './makeInvest'\nexport * from './makeDual'\nexport * from './marketRedPacket'\nexport * from './makeDefiSideStaking'\nexport * from './providorConnect'\nexport * from './makeMarketTrend'\nexport {parseRabbitConfig, parseRabbitConfig2, networkById} from './parseRabbitConfig'\n"
  },
  {
    "path": "packages/core/src/hooks/help/makeCache.ts",
    "content": "import { store } from '../../index'\nimport { setSlippage } from '@loopring-web/component-lib'\n\ntype Cache = {\n  customSlippage?: number\n}\nexport const makeCache = (__cache__: Cache) => {\n  if (typeof __cache__.customSlippage !== undefined) {\n    store.dispatch(setSlippage(__cache__.customSlippage as number))\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/help/makeDefiSideStaking.ts",
    "content": "import * as sdk from '@loopring-web/loopring-sdk'\nimport { DUAL_TYPE, toBig } from '@loopring-web/loopring-sdk'\nimport {\n  DeFiSideCalcData,\n  DeFiSideRedeemCalcData,\n  DualViewInfo,\n  DualViewOrder,\n  getValuePrecisionThousand,\n  IBData,\n  myLog,\n} from '@loopring-web/common-resources'\nimport moment from 'moment'\nimport { BigNumber } from 'bignumber.js'\n\nexport const makeDefiSideStaking = (\n  info: sdk.DualProductAndPrice,\n  index: sdk.DualIndex,\n  rule: sdk.DualRulesCoinsInfo,\n  sellSymbol: string,\n  buySymbol: string,\n  market: sdk.DefiMarketInfo,\n): DualViewInfo => {\n  const { expireTime, strike, ratio, profit, dualType } = info\n  const { precisionForPrice } = market\n  myLog('makeDualViewItem', expireTime, strike, ratio, dualType)\n  const [base, quote] =\n    dualType.toUpperCase() === DUAL_TYPE.DUAL_BASE\n      ? [sellSymbol, buySymbol]\n      : [buySymbol, sellSymbol]\n\n  const settleRatio = toBig(profit).times(ratio).toFixed(6, BigNumber.ROUND_DOWN)\n\n  const apy = toBig(settleRatio)\n    .div((expireTime - Date.now()) / 86400000)\n    .times(36500) // year APY\n  const term = moment().to(new Date(expireTime), true)\n  return {\n    apy: (getValuePrecisionThousand(apy, 2, 2, 2, true) + '%') as any,\n    settleRatio,\n    term,\n    strike,\n    isUp: dualType.toUpperCase() === DUAL_TYPE.DUAL_BASE ? true : false,\n    productId: info.productId,\n    expireTime,\n    currentPrice: {\n      base,\n      quote,\n      precisionForPrice,\n      currentPrice: Number(index.index),\n      quoteUnit: quote, //index.quote,\n    },\n    sellSymbol,\n    buySymbol,\n    __raw__: {\n      info,\n      index,\n      rule,\n    },\n  }\n}\n\nexport const calcSideStaking = <T>({\n  inputValue,\n  deFiSideCalcData,\n  tokenSell,\n}: {\n  inputValue: string\n  isJoin: true\n  deFiSideCalcData: DeFiSideCalcData<T>\n  tokenSell: sdk.TokenInfo\n}): {\n  minSellVol: string | undefined\n  maxSellVol: string | undefined\n  sellVol: string\n  isJoin: true\n  deFiSideCalcData: DeFiSideCalcData<T>\n} => {\n  const sellVol = sdk.toBig(inputValue ? inputValue : 0).times('1e' + tokenSell.decimals)\n  let dalyEarn: undefined | string = undefined\n  if (\n    inputValue &&\n    deFiSideCalcData.stakeViewInfo.apr &&\n    deFiSideCalcData.stakeViewInfo.apr !== '' &&\n    deFiSideCalcData.stakeViewInfo.apr !== '0.00'\n  ) {\n    dalyEarn = sdk.toBig(sellVol).times(deFiSideCalcData.stakeViewInfo.apr).div(365).toString()\n  } else {\n    dalyEarn = undefined\n  }\n  const maxSellAmount = sdk\n    .toBig(deFiSideCalcData.stakeViewInfo.maxAmount)\n    .div('1e' + tokenSell.decimals)\n    .toString()\n  const minSellAmount = sdk\n    .toBig(deFiSideCalcData.stakeViewInfo.minAmount)\n    .div('1e' + tokenSell.decimals)\n    .toString()\n  if (deFiSideCalcData.stakeViewInfo.symbol) {\n    return {\n      sellVol: sellVol.toString(),\n      deFiSideCalcData: {\n        ...deFiSideCalcData,\n        stakeViewInfo: {\n          ...deFiSideCalcData.stakeViewInfo,\n          minSellVol: deFiSideCalcData.stakeViewInfo.minAmount,\n          maxSellVol: deFiSideCalcData.stakeViewInfo.maxAmount,\n          maxSellAmount,\n          minSellAmount,\n          dalyEarn,\n        },\n      },\n      isJoin: true,\n      minSellVol: deFiSideCalcData.stakeViewInfo.minAmount,\n      maxSellVol: deFiSideCalcData.stakeViewInfo.maxAmount,\n    }\n  } else {\n    return {\n      sellVol: sellVol.toString(),\n      deFiSideCalcData: {\n        ...deFiSideCalcData,\n        stakeViewInfo: {\n          ...deFiSideCalcData?.stakeViewInfo,\n          minSellVol: undefined,\n          maxSellVol: undefined,\n          maxSellAmount,\n          minSellAmount,\n          dalyEarn,\n        },\n      },\n      isJoin: true,\n      minSellVol: undefined,\n      maxSellVol: undefined,\n    }\n  }\n}\n\nexport const calcRedeemStaking = <T extends IBData<any>, R>({\n  inputValue,\n  // isJoin,\n  deFiSideRedeemCalcData: { stakeViewInfo, coinSell, ...rest },\n  tokenSell,\n}: {\n  inputValue: string\n  isJoin: false\n  deFiSideRedeemCalcData: DeFiSideRedeemCalcData<T>\n  tokenSell: sdk.TokenInfo\n}): {\n  minSellVol: string | undefined\n  maxSellVol: string | undefined\n  sellVol: string\n  isJoin: boolean\n  deFiSideRedeemCalcData: DeFiSideRedeemCalcData<T, R>\n} => {\n  let sellVol\n  if (inputValue?.toString() == coinSell.balance?.toString()) {\n    sellVol = (stakeViewInfo as any).remainAmount\n  } else {\n    sellVol = sdk.toBig(inputValue ? inputValue : 0).times('1e' + tokenSell.decimals)\n  }\n\n  const maxSellAmount = sdk\n    .toBig((stakeViewInfo as any)?.maxAmount)\n    .div('1e' + tokenSell.decimals)\n    .toString()\n  const minSellAmount = sdk\n    .toBig((stakeViewInfo as any).minAmount)\n    .div('1e' + tokenSell.decimals)\n    .toString()\n\n  if ((stakeViewInfo as any).symbol) {\n    return {\n      sellVol: sellVol.toString(),\n      deFiSideRedeemCalcData: {\n        ...rest,\n        coinSell,\n        stakeViewInfo: {\n          ...(stakeViewInfo as any),\n          minSellVol: (stakeViewInfo as any).minAmount,\n          maxSellVol: (stakeViewInfo as any).maxAmount,\n          maxSellAmount,\n          minSellAmount,\n        },\n      },\n      isJoin: true,\n      minSellVol: (stakeViewInfo as any).minAmount,\n      maxSellVol: (stakeViewInfo as any).maxAmount,\n    }\n  } else {\n    return {\n      sellVol: sellVol.toString(),\n      deFiSideRedeemCalcData: {\n        ...rest,\n        coinSell,\n        stakeViewInfo: {\n          ...(stakeViewInfo as any),\n          minSellVol: undefined,\n          maxSellVol: undefined,\n          maxSellAmount,\n          minSellAmount,\n        },\n      },\n      isJoin: true,\n      minSellVol: undefined,\n      maxSellVol: undefined,\n    }\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/help/makeDual.ts",
    "content": "import * as sdk from '@loopring-web/loopring-sdk'\nimport { DUAL_TYPE, toBig } from '@loopring-web/loopring-sdk'\nimport {\n  DualViewInfo,\n  DualViewOrder,\n  getValuePrecisionThousand,\n} from '@loopring-web/common-resources'\nimport moment from 'moment'\nimport { BigNumber } from 'bignumber.js'\n\nexport const makeDualViewItem = (\n  info: sdk.DualProductAndPrice,\n  index: sdk.DualIndex,\n  rule: sdk.DualRulesCoinsInfo,\n  sellSymbol: string,\n  buySymbol: string,\n  market: sdk.DefiMarketInfo,\n): DualViewInfo => {\n  const { expireTime, strike, ratio, profit, dualType } = info\n  // @ts-ignore\n  const { precisionForPrice, stepLength } = market\n  // myLog('makeDualViewItem', expireTime, strike, ratio, dualType)\n  const [base, quote] =\n    dualType.toUpperCase() === DUAL_TYPE.DUAL_BASE\n      ? [sellSymbol, buySymbol]\n      : [buySymbol, sellSymbol]\n\n  const settleRatio = toBig(profit).times(ratio).toFixed(6, BigNumber.ROUND_DOWN)\n\n  const apy = toBig(settleRatio)\n    .div((expireTime - Date.now()) / 86400000)\n    .times(36500) // year APY\n  const term = moment().to(new Date(expireTime), true)\n  return {\n    apy: (getValuePrecisionThousand(apy, 2, 2, 2, true) + '%') as any,\n    settleRatio,\n    term,\n    strike,\n    isUp: dualType.toUpperCase() === DUAL_TYPE.DUAL_BASE ? true : false,\n    productId: info.productId,\n    expireTime,\n    currentPrice: {\n      base,\n      quote,\n      precisionForPrice,\n      currentPrice: Number(index.index),\n      quoteUnit: quote, //quote index.quote,\n    },\n    sellSymbol,\n    buySymbol,\n    stepLength,\n    __raw__: {\n      info,\n      index,\n      rule,\n    },\n  }\n}\n\nexport const makeDualOrderedItem = (\n  props: sdk.UserDualTxsHistory,\n  sellSymbol: string,\n  buySymbol: string,\n  currentPrice: number,\n  market: sdk.DefiMarketInfo,\n): DualViewOrder => {\n  const {\n    settleRatio,\n    dualType,\n    strike,\n    productId,\n    createdAt,\n    timeOrigin: { expireTime },\n  } = props\n  const [base, quote] =\n    dualType.toUpperCase() === DUAL_TYPE.DUAL_BASE\n      ? [sellSymbol, buySymbol]\n      : [buySymbol, sellSymbol]\n\n  const apy = toBig(settleRatio)\n    .div((expireTime - createdAt) / 86400000)\n    .times(36500) // year APY\n  const term = moment().to(new Date(expireTime), true)\n  const { precisionForPrice, stepLength } = market ?? {}\n\n  return {\n    apy: (getValuePrecisionThousand(apy, 2, 2, 2, true) + '%') as any,\n    settleRatio: settleRatio.toString(), // quote Interest\n    term,\n    strike: strike.toString(),\n    isUp: dualType.toUpperCase() === DUAL_TYPE.DUAL_BASE ? true : false,\n    productId,\n    enterTime: createdAt,\n    expireTime,\n    stepLength,\n    currentPrice: {\n      precisionForPrice,\n      base,\n      quote,\n      currentPrice: currentPrice ?? {},\n      quoteUnit: quote, //quote index.quote,\n    },\n    sellSymbol,\n    buySymbol,\n    __raw__: {\n      order: props,\n    },\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/help/makeInvest.ts",
    "content": "import {\n  CoinMap,\n  InvestMapType,\n  InvestOpenType,\n  VaultMarketExtends,\n} from '@loopring-web/common-resources'\nimport { DepartmentRow, RowInvest } from '@loopring-web/component-lib'\nimport { InvestTokenTypeMap, store, btradeReducer } from '../../stores'\nimport { LoopringAPI } from '../../api_wrapper'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { uniq } from 'lodash'\n\nexport const makeInvestRow = <R extends RowInvest>(\n  investTokenTypeMap: InvestTokenTypeMap,\n  key: string,\n): R => {\n  const { coinMap } = store.getState().tokenMap\n  const info = investTokenTypeMap[key].detail\n  const coinInfo = coinMap[info.token.symbol]\n\n  let item = {\n    ...investTokenTypeMap[key].detail,\n    coinInfo,\n    i18nKey: '' as any,\n    children: [],\n    isExpanded: false,\n    type: InvestMapType.Token,\n  } as unknown as R\n  const children = InvestOpenType.reduce((prev, type) => {\n    if (investTokenTypeMap[key][type]) {\n      let _row: any = investTokenTypeMap[key][type]\n      const coinInfo = coinMap[item.token.symbol]\n      _row = { ..._row, coinInfo, token: item.token }\n      prev.push(_row as DepartmentRow)\n    }\n    return prev\n  }, [] as DepartmentRow[])\n  item.children = children\n  return item\n}\n\nexport const makeDefiInvestReward = async () => {\n  const { apiKey, accountId } = store.getState().account\n  if (LoopringAPI.defiAPI && apiKey && accountId) {\n    // @ts-ignore\n    const { totalRewards } = await LoopringAPI.defiAPI.getDefiReward({ accountId }, apiKey)\n    return totalRewards ?? 0\n  }\n  return '0'\n}\n\nexport const findDualMarket = (marketArray: string[], pairASymbol: string, pairBSymbol: string) =>\n  marketArray.find((item) => {\n    const regExp = new RegExp(\n      `^(\\\\w+-)?(${pairASymbol}-${pairBSymbol}|${pairBSymbol}-${pairASymbol})$`,\n      'i',\n    )\n    return regExp.test(item)\n  })\n\nexport const makeBtrade = (btradeMarkets: any) => {\n  if (btradeMarkets) {\n    const {\n      markets: marketMap,\n      pairs,\n      marketArr: marketArray,\n      tokenArr: marketCoins,\n    } = sdk.makeMarkets({ markets: btradeMarkets })\n    const tradeMap = Reflect.ownKeys(pairs ?? {}).reduce((prev, key) => {\n      const tradePairs = pairs[key as string]?.tokenList?.sort()\n      prev[key] = {\n        ...pairs[key as string],\n        tradePairs,\n      }\n      return prev\n    }, {})\n    if (!marketArray?.length) {\n      store.dispatch(\n        btradeReducer.getBtradeMapStatus({\n          marketArray,\n          marketCoins,\n          marketMap,\n          tradeMap,\n        }),\n      )\n    }\n  }\n}\n\n/**\n * @property vaultTokenAmounts.status\n *  show: bit 0\n *  join: bit 1\n *  exit: bit 2\n *  loan: bit 3\n *  repay:bit 4\n * @param vaultTokenMap\n * @param vaultMarkets\n * @param enabled\n */\nexport const makeVault = (\n  vaultTokenMap: sdk.VaultToken[] | undefined,\n  vaultMarkets: sdk.VaultMarket[] | undefined,\n  enabled?: 'isFormLocal' | undefined,\n) => {\n  const {\n    idIndex: erc20IdIndex,\n    // tokenMap:erc20TokenMap\n  } = store.getState().tokenMap\n  if (vaultTokenMap && vaultMarkets && erc20IdIndex) {\n    let { tokensMap, coinMap, idIndex, addressIndex } = sdk.makeMarket(vaultTokenMap as any)\n    let erc20Array = [],\n      erc20Map = {}\n\n    const reformat: VaultMarketExtends[] = vaultMarkets.reduce((prev, ele) => {\n      if (/-/gi.test(ele.market) && ele.enabled) {\n        const item = {\n          ...ele,\n          enabled: enabled ?? ele.enabled,\n          vaultMarket: ele.market,\n          market: ele.market.replace(/(\\w+)-(\\w+)-(\\w+)/, '$2-$3'),\n          originalBaseSymbol: erc20IdIndex[tokensMap[idIndex[ele.baseTokenId]].tokenId],\n          originalQuoteSymbol: erc20IdIndex[tokensMap[idIndex[ele.quoteTokenId]].tokenId],\n        }\n        prev.push(item)\n        // const erc20Symbol = erc20IdIndex[tokensMap[idIndex[ele.baseTokenId]]?.tokenId]\n        // @ts-ignore\n        return prev\n      } else {\n        return prev as VaultMarketExtends[]\n      }\n    }, [] as VaultMarketExtends[])\n    const joinTokenMap = Reflect.ownKeys(tokensMap).reduce((prev, key) => {\n      const status = (\n        tokensMap[key.toString()] as sdk.VaultToken\n      )?.vaultTokenAmounts?.status?.toString(2)\n      if (status[0] == '1' && status[1] == '1') {\n        prev = {\n          ...prev,\n          [key]: tokensMap[key.toString()] as sdk.VaultToken,\n        }\n      }\n      const erc20Symbol = erc20IdIndex[tokensMap[key.toString()]?.tokenId]\n      // @ts-ignore\n      erc20Array.push(erc20Symbol)\n      erc20Map[erc20Symbol] = {\n        ...tokensMap[key.toString()],\n      }\n      return prev\n    }, {} as { [key: string]: sdk.VaultToken & sdk.TokenInfo })\n    const {\n      markets: marketMap,\n      pairs,\n      marketArr: marketArray,\n    } = sdk.makeMarketsWithIdIndex({ \n      markets: reformat, \n    },undefined,\n    idIndex)\n    const marketCoins = uniq(\n      reformat.map(market => {\n        return [market.baseTokenId, market.quoteTokenId]\n      }).flat().map(id => idIndex[id])\n    ) \n    let tokenMap: any = tokensMap\n    const tradeMap = Reflect.ownKeys(pairs ?? {}).reduce((prev, key) => {\n      const tradePairs = pairs[key as string]?.tokenList?.sort()\n      prev[key] = {\n        ...pairs[key as string],\n        tradePairs,\n      }\n      const erc20Symbol = erc20IdIndex[tokensMap[key.toString()].tokenId]\n      tokenMap[key.toString()] = {\n        ...tokensMap[key.toString()],\n        erc20Symbol,\n        belongAlice: erc20Symbol,\n        tradePairs: pairs[key.toString()].tokenList,\n      }\n      return prev\n    }, {})\n    const _coinMap = Reflect.ownKeys(coinMap).reduce((prev, ele) => {\n      const erc20Symbol = erc20IdIndex[tokensMap[ele.toString()].tokenId]\n      prev[ele.toString()] = {\n        ...coinMap[ele.toString()],\n        belongAlice: erc20Symbol,\n        erc20Symbol: erc20Symbol,\n      }\n      return prev\n    }, {} as CoinMap<any, any>)\n    return {\n      marketArray,\n      marketCoins,\n      marketMap,\n      tradeMap,\n      coinMap: _coinMap,\n      pairs,\n      idIndex,\n      addressIndex,\n      tokenMap,\n      joinTokenMap,\n      erc20Array,\n      erc20Map,\n    }\n    // }\n  } else {\n    return {\n      marketMap: undefined,\n      pairs: undefined,\n      marketArray: undefined,\n      marketCoins: undefined,\n      tokenMap: undefined,\n      coinMap: undefined,\n      idIndex: undefined,\n      addressIndex: undefined,\n      erc20Array: undefined,\n      erc20Map: undefined,\n    }\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/help/makeMarketTrend.ts",
    "content": "export const makeMarketTrend = () => {}\n"
  },
  {
    "path": "packages/core/src/hooks/help/makeTickView.ts",
    "content": "import { LoopringMap, TickerData, toBig } from '@loopring-web/loopring-sdk'\nimport { store } from '../../index'\nimport { volumeToCount } from './volumeToCount'\nimport { TickerMap } from '../../stores'\nimport {\n  getValuePrecisionThousand,\n  Ticker,\n  TickerNew,\n  TickerNewMap,\n  TokenType,\n} from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nexport const makeTickView = (tick: TickerData) => {\n  const { tokenPrices } = store.getState().tokenPrices\n  // const { forexMap } = store.getState().system;\n  if (tick && tick.base && tick.quote) {\n    const price = tokenPrices[tick.base]\n    const volume = volumeToCount(tick.quote, tick.quote_token_volume)\n    const priceU = toBig(volume ? volume : 0).times(price)\n\n    const change = tick.change && tick.change !== 0 ? tick.change * 100 : undefined\n    const qPrice = tick.quote === 'DAI' ? 1 : tokenPrices[tick.quote] || 0\n    const closeU = toBig(tick.close).times(qPrice).toNumber()\n    // const extraTickerInfo = makeTickView(item);\n\n    return {\n      ...tick,\n      changeU: toBig(tick.close - (tick.open ?? 0)).toNumber(),\n      volume: volume ? Number(volume) : undefined,\n      closeDollar: closeU,\n      timeUnit: '24h',\n      priceU: priceU.toNumber(),\n      floatTag: tick.close > tick.open ? 'increase' : 'decrease',\n      change: change,\n      close: isNaN(tick.close) ? undefined : tick.close,\n      high: tick.high === 0 ? undefined : tick.high,\n      low: tick.low === 0 ? undefined : tick.low,\n      reward: 0,\n      rewardToken: '',\n      __rawTicker__: tick,\n    } as Ticker\n  }\n}\nexport const makeTickerMap = <R extends { [key: string]: any }>({\n  tickerMap,\n}: {\n  tickerMap: LoopringMap<TickerData>\n}): TickerMap<{ [key: string]: any }> => {\n  const { forexMap } = store.getState().system\n  const { tokenPrices } = store.getState().tokenPrices\n\n  return Reflect.ownKeys(tickerMap).reduce((prev: TickerMap<R>, key) => {\n    const item = tickerMap[key as any]\n    if (item && item.quote && forexMap && tokenPrices[item.quote]) {\n      const price = tokenPrices[item.quote]\n      const volume = volumeToCount(item.symbol.split('-')[1], item.quote_token_volume)\n      const priceU = toBig(volume ? volume : 0).times(price)\n      const change = item.change && item.change !== 0 ? item.change * 100 : undefined\n\n      const extraTickerInfo = makeTickView(item)\n\n      prev[key as keyof R] = {\n        ...item,\n        ...extraTickerInfo,\n        timeUnit: '24h',\n        priceU: priceU?.toNumber() === 0 ? undefined : priceU?.toNumber(),\n        volume: volume ? volume.toString() : undefined,\n        floatTag: item.close > item.open ? 'increase' : 'decrease',\n        change: change,\n        close: isNaN(item.close) ? undefined : item.close,\n        high: item.high === 0 ? undefined : item.high,\n        low: item.low === 0 ? undefined : item.low,\n        // APR: 0,\n        reward: 0,\n        rewardToken: '',\n        __rawTicker__: item,\n      } as unknown as Ticker\n    }\n    return prev\n  }, {} as TickerMap<R>)\n}\n\nexport const makeTokenTickerView = ({\n  item,\n  isVault = false,\n}: {\n  item: sdk.DatacenterTokenInfoSimple\n  isVault?: boolean\n}) => {\n  const {\n    tokenMap: { tokenMap: erc20TokenMap },\n    invest: {\n      vaultMap: { erc20Map, idIndex },\n    },\n  } = store.getState()\n  const tokenInfo = erc20TokenMap[item.symbol]\n  const volume = getValuePrecisionThousand(\n    item.volume24H,\n    tokenInfo.precision,\n    tokenInfo.precision,\n    undefined,\n  ) //volumeToCount(item.symbol, item.volume24H)\n  const priceU = sdk.toBig(item.volume24H ?? 0).times(item.price ?? 0)\n  const change = getValuePrecisionThousand(item.percentChange24H ?? 0, 2, 2, 2)\n  // @ts-ignore\n  return {\n    ...tokenInfo,\n    ...item,\n    timeUnit: '24h',\n    volume,\n    priceU,\n    change,\n    type: isVault ? TokenType.vault : TokenType.single,\n    erc20Symbol: tokenInfo.symbol,\n    symbol: isVault ? idIndex[erc20Map[tokenInfo.symbol].vaultTokenId] : tokenInfo.symbol,\n    __rawTicker__: item,\n    rawData: item,\n  } as unknown as TickerNew\n}\nexport const makeTokenTickerMap = <R>({\n  rawData,\n  isVault,\n}: {\n  rawData: sdk.DatacenterTokenInfoSimple[]\n  isVault?: boolean\n}): TickerNewMap<R> => {\n  return rawData.reduce((prev: TickerNewMap<R>, item) => {\n    const key = item.symbol\n    if (item && item.symbol && item.price) {\n      const {\n        invest: {\n          vaultMap: { tokenMap },\n        },\n      } = store.getState()\n      const priceU = sdk.toBig(item.volume24H ?? 0).times(item.price ?? 0)\n      const change = getValuePrecisionThousand(item.percentChange24H ?? 0, 2, 2, 2)\n      // @ts-ignore\n      prev[key] = {\n        // ...tokenInfo,\n        ...item,\n        ...tokenMap['LV' + item.symbol],\n        timeUnit: '24h',\n        volume: item.volume24H,\n        priceU,\n        change,\n        type: TokenType.vault,\n        erc20Symbol: item.symbol,\n        symbol: 'LV' + item.symbol,\n        __rawTicker__: item,\n        rawData: item,\n      } as unknown as TickerNew\n    }\n    return prev\n  }, {} as TickerNewMap<R>)\n}\n"
  },
  {
    "path": "packages/core/src/hooks/help/makeUIAmmActivityMap.ts",
    "content": "import {\n  AmmPoolActivityRule,\n  AmmPoolActivityStatus,\n  AmmUserRewardMap,\n  LoopringMap,\n  toBig,\n  TokenInfo,\n} from '@loopring-web/loopring-sdk'\nimport {\n  AmmActivity,\n  AmmCardProps,\n  getValuePrecisionThousand,\n  MyAmmLP,\n  myError,\n  TokenType,\n} from '@loopring-web/common-resources'\nimport {\n  AmmDetailStore,\n  makeWalletLayer2,\n  MyAmmLPMap,\n  store,\n  VolToNumberWithPrecision,\n} from '../../index'\nimport BigNumber from 'bignumber.js'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { volumeToCount, volumeToCountAsBigNumber } from './volumeToCount'\nimport { coinMap, EarningsRow } from '@loopring-web/component-lib'\nimport _ from 'lodash'\n\nexport const makeClaimRewards = <R = EarningsRow>(totalClaims: sdk.ClaimItem[]) => {\n  const { idIndex, tokenMap } = store.getState().tokenMap\n  const { tokenPrices } = store.getState().tokenPrices\n  const list = totalClaims.reduce((prev, _item) => {\n    let tokenValueDollar = 0,\n      amountStr: any\n    const item = {\n      ..._item,\n    }\n    const tokenInfo: TokenInfo = tokenMap[idIndex[item.tokenId]]\n    if (tokenInfo.symbol) {\n      let totalAmount = sdk.toBig(0)\n      // @ts-ignore\n      item.claimableInfo = item.claimable?.map((_claimable) => {\n        totalAmount.plus(_claimable.amount)\n        const amountStr = volumeToCountAsBigNumber(tokenInfo?.symbol, _claimable?.amount ?? 0)\n        const tokenValueDollar = amountStr?.times(tokenPrices[tokenInfo.symbol])\n        return {\n          ..._claimable,\n          amountStr: amountStr?.toString(),\n          tokenValueDollar: tokenValueDollar?.toString(),\n          token: tokenInfo.symbol,\n          precision: tokenInfo.precision,\n        }\n      })\n\n      // @ts-ignore\n      amountStr = volumeToCountAsBigNumber(tokenInfo.symbol, _item.sum)\n      // amountStr = volumeToCountAsBigNumber(tokenInfo.symbol, 1000000000)\n      tokenValueDollar = amountStr?.times(tokenPrices[tokenInfo.symbol])\n      prev[tokenInfo.symbol] = {\n        token: {\n          type: TokenType.single,\n          value: tokenInfo.symbol,\n        },\n        detail: item.claimableInfo,\n        precision: tokenInfo.precision,\n        tokenValueDollar: tokenValueDollar.toString(),\n        amountStr: amountStr.toString(),\n        // @ts-ignore\n        amount: _item?.sum,\n        rawData: item,\n      } as unknown as R\n      // prev.push()\n    }\n    return prev\n  }, {} as { [key: string]: R })\n  return list\n}\nexport type AmmActivityViewMap<R, I> = {\n  [key in keyof R]?: AmmActivity<I>[] | undefined\n}\nexport const makeUIAmmActivityMap = <\n  R extends { [key: string]: any },\n  I extends { [key: string]: any },\n>(\n  {\n    ammActivityMap,\n    type,\n    ammPoolActivityStatus,\n  }: {\n    ammActivityMap: LoopringMap<LoopringMap<AmmPoolActivityRule[]>> | undefined\n    type?: 'AMM_MINING' | 'SWAP_VOLUME_RANKING' | 'ORDERBOOK_MINING' | undefined\n    ammPoolActivityStatus: AmmPoolActivityStatus[]\n  },\n  myReward: AmmUserRewardMap | undefined,\n): Array<AmmCardProps<I>> => {\n  const { coinMap, tokenMap, idIndex } = store.getState().tokenMap\n\n  let ammActivityViewMap: AmmActivityViewMap<R, I> = {}\n  if (ammActivityMap) {\n    const genView = (ammActivityMapItem: any) => {\n      let ammActivityViewMapTmp: AmmActivityViewMap<R, I> = {}\n      ammPoolActivityStatus.forEach((status: AmmPoolActivityStatus) => {\n        if (ammActivityMapItem[status]) {\n          // @ts-ignore\n          ammActivityMapItem[status].reduce(\n            (prev: AmmActivityViewMap<R, I>, ammPoolActivityRule: AmmPoolActivityRule) => {\n              if (coinMap && ammPoolActivityRule.awardRules[0] && idIndex && tokenMap) {\n                // @ts-ignore\n                const { current } = myReward\n                  ? myReward[ammPoolActivityRule.market]\n                  : { current: undefined }\n\n                const symbol = idIndex[ammPoolActivityRule.awardRules[0].tokenId as any]\n                const totalRewards = VolToNumberWithPrecision(\n                  ammPoolActivityRule.awardRules[0].volume,\n                  symbol,\n                )\n                const myRewardVol = current?.currentRewards[0]?.volume ?? 0\n\n                const item = {\n                  // @ts-ignore\n                  market: ammPoolActivityRule.market,\n                  status: ammPoolActivityRule.status,\n                  ruleType: ammPoolActivityRule.ruleType,\n                  rewardToken: coinMap[symbol],\n                  totalRewards: Number(totalRewards),\n                  maxSpread: (ammPoolActivityRule?.maxSpread || 0) * 100,\n                  myRewards:\n                    status === AmmPoolActivityStatus.InProgress &&\n                    myReward &&\n                    myReward[ammPoolActivityRule.market]\n                      ? volumeToCount(symbol, myRewardVol)\n                      : 0,\n                  duration: {\n                    from: new Date(ammPoolActivityRule?.rangeFrom),\n                    to: new Date(ammPoolActivityRule?.rangeTo),\n                  },\n                  isPass: AmmPoolActivityStatus.EndOfGame === status,\n                }\n                if (prev[ammPoolActivityRule.market]) {\n                  // @ts-ignore\n                  prev[ammPoolActivityRule.market].push(item)\n                } else {\n                  // @ts-ignore\n                  prev[ammPoolActivityRule.market] = [item]\n                }\n\n                // return prev;\n              }\n              return prev\n            },\n            ammActivityViewMapTmp,\n          )\n        }\n      })\n\n      return ammActivityViewMapTmp\n    }\n\n    if (type === undefined) {\n      const keys = Object.keys(ammActivityMap)\n      keys.forEach((item: any, _ind: number) => {\n        const newMap = genView(ammActivityMap[item])\n        const copiedNewMap = _.cloneDeep(newMap)\n        ammActivityViewMap = { ...ammActivityViewMap, [item]: copiedNewMap }\n      })\n    } else {\n      ammActivityViewMap = genView(ammActivityMap[type])\n    }\n  }\n\n  const resultArray = makeAsCard(ammActivityViewMap)\n  return resultArray\n}\n\nconst makeAsCard = <_R extends { [key: string]: any }, I extends { [key: string]: any }>(\n  ammActivityViewMap: any,\n  _myReward?: any,\n): Array<AmmCardProps<I>> => {\n  const { coinMap } = store.getState().tokenMap\n  const { ammMap } = store.getState().amm.ammMap\n  const { tokenPrices } = store.getState().tokenPrices\n  try {\n    if (ammActivityViewMap && coinMap) {\n      // @ts-ignore\n      // return ammActivityViewMap.map()\n      let finalArray = [] as any[]\n      const catogoriedMap = Object.keys(ammActivityViewMap)\n      catogoriedMap.forEach((item) => {\n        const basicArray = Object.keys(ammActivityViewMap[item]).reduce(\n          (prev: Array<AmmCardProps<I>>, key: string) => {\n            const activities = ammActivityViewMap[item][key]\n\n            const _ammInfo = ammMap[key as string]\n            if (activities) {\n              //_ammInfo && _ammInfo.coinA && coinMap &&\n\n              // @ts-ignore\n              const itemArray = activities.map((item: AmmActivity) => {\n                const matchRes = (item.market as string).replace('AMM-', '').match(/(\\w+)-(\\w+)/i)\n\n                if (matchRes) {\n                  const coinAInfo = coinMap[matchRes[1]]\n                  const coinBInfo = coinMap[matchRes[2]]\n                  const coinApriceU = tokenPrices ? tokenPrices[coinAInfo?.simpleName] : 0\n                  const coinBpriceU = tokenPrices ? tokenPrices[coinBInfo?.simpleName] : 0\n                  const rewardTokenU = tokenPrices ? tokenPrices[item?.rewardToken?.simpleName] : 0\n                  // myLog('matchRes:', matchRes, ' coinAInfo:', coinAInfo, ' coinBInfo:', coinBInfo)\n                  return {\n                    ..._.cloneDeep(_ammInfo),\n                    coinAInfo,\n                    coinBInfo,\n                    coinApriceU,\n                    coinBpriceU,\n                    activity: {\n                      ...item,\n                      rewardTokenU: rewardTokenU,\n                    },\n                  }\n                }\n\n                return {}\n              })\n              prev = [...prev, ...itemArray]\n            }\n            return prev\n          },\n          [] as Array<AmmCardProps<I>>,\n        ) as Array<AmmCardProps<I>>\n\n        finalArray = [...finalArray, ...basicArray]\n      })\n      return finalArray\n    } else {\n      return [] as Array<AmmCardProps<I>>\n    }\n  } catch (error: any) {\n    myError(error)\n    return []\n  }\n}\ntype Value = undefined | number | string\nexport type SummaryMyInvest = {\n  rewardU: Value\n  feeU: Value\n  investDollar?: Value\n  ammPoolDollar?: Value\n  stakeETHDollar?: Value\n  dualStakeDollar?: Value\n  leverageETHDollar?: Value\n  taikoFarmingDollar?: Value\n}\nexport const makeSummaryMyAmm = <C extends { [key: string]: any }>({\n  userRewardsMap,\n}: {\n  userRewardsMap: AmmUserRewardMap | undefined\n}): {\n  myAmmLPMap: MyAmmLPMap<C> | undefined\n  rewardU: string\n  feeU: string\n} => {\n  const { idIndex, tokenMap } = store.getState().tokenMap\n  const { ammMap } = store.getState().amm.ammMap\n  if (ammMap && idIndex && tokenMap) {\n    return Object.keys(ammMap).reduce(\n      (prev, key) => {\n        let ammInfo = ammMap[key]\n        if (ammInfo) {\n          const value = getMyAmmInfo({\n            ammInfo,\n            ammUserReward: userRewardsMap && userRewardsMap[key],\n          })\n\n          return {\n            myAmmLPMap: {\n              ...prev.myAmmLPMap,\n              [ammInfo.market]: value,\n            },\n            rewardU: value.rewardU\n              ? toBig(value.rewardU).plus(prev.rewardU).toString()\n              : prev.rewardU,\n            feeU: value.feeU ? toBig(value.feeU).plus(prev.feeU).toString() : prev.feeU,\n          }\n        } else {\n          return prev\n        }\n      },\n      {\n        myAmmLPMap: {} as any,\n        rewardU: '0',\n        feeU: '0',\n      } as any,\n    )\n  } else {\n    return {\n      myAmmLPMap: {} as any,\n      rewardU: '0',\n      feeU: '0',\n    }\n  }\n}\n/** userRewradCalc **/\nconst getRewardCalc = ({\n  ammInfo,\n  ammUserReward,\n}: {\n  ammInfo: AmmDetailStore<any>\n  ammUserReward?: {\n    current: sdk.AmmUserReward\n    lastDay: sdk.AmmUserReward\n  }\n}) => {\n  let rewardToken,\n    rewardToken2,\n    feeA,\n    feeB,\n    feeU,\n    reward,\n    reward2,\n    rewardU,\n    feeA24,\n    feeB24,\n    feeU24,\n    reward24,\n    reward224,\n    rewardU24,\n    extraRewards24: any[] = [],\n    extraU24 = 0\n  const { current, lastDay } = ammUserReward ?? {}\n  const { tokenPrices } = store.getState().tokenPrices\n  const { idIndex } = store.getState().tokenMap\n\n  if (current) {\n    rewardToken = current.currentRewards[0]\n      ? idIndex[current.currentRewards[0].tokenId as number]\n      : undefined\n    rewardToken2 = current.currentRewards[1]\n      ? idIndex[current.currentRewards[1].tokenId as number]\n      : undefined\n    feeA = volumeToCountAsBigNumber(ammInfo.coinA, current?.feeRewards[0] ?? 0) ?? toBig(0)\n    feeB = volumeToCountAsBigNumber(ammInfo.coinB, current?.feeRewards[1] ?? 0) ?? toBig(0)\n    feeU = feeA\n      .times(tokenPrices[ammInfo.coinA] ? tokenPrices[ammInfo.coinA] : 0)\n      .plus(feeB.times(tokenPrices[ammInfo.coinB] ? tokenPrices[ammInfo.coinB] : 0))\n    reward = rewardToken\n      ? (volumeToCountAsBigNumber(rewardToken, current.currentRewards[0].volume) as BigNumber)\n      : toBig(0)\n    reward2 = rewardToken2\n      ? (volumeToCountAsBigNumber(rewardToken2, current.currentRewards[1].volume) as BigNumber)\n      : toBig(0)\n    reward = reward ? reward : toBig(0)\n    reward2 = reward2 ? reward2 : toBig(0)\n    rewardU = reward\n      .times(rewardToken ? tokenPrices[rewardToken] : 1)\n      .plus(reward2.times(rewardToken2 ? tokenPrices[rewardToken2] : 1))\n    if (lastDay) {\n      feeA24 = volumeToCountAsBigNumber(ammInfo.coinA, lastDay?.feeRewards[0] ?? 0) ?? toBig(0)\n      feeB24 = volumeToCountAsBigNumber(ammInfo.coinB, lastDay.feeRewards[1] ?? 0) ?? toBig(0)\n      feeU24 = feeA24\n        .times(tokenPrices[ammInfo.coinA] ? tokenPrices[ammInfo.coinA] : 0)\n        .plus(feeB24.times(tokenPrices[ammInfo.coinB] ? tokenPrices[ammInfo.coinB] : 0))\n      reward24 = rewardToken\n        ? (volumeToCountAsBigNumber(\n            rewardToken,\n            lastDay?.currentRewards[0]?.volume ?? 0,\n          ) as BigNumber)\n        : toBig(0)\n      reward224 = rewardToken2\n        ? (volumeToCountAsBigNumber(\n            rewardToken2,\n            lastDay?.currentRewards[1]?.volume ?? 0,\n          ) as BigNumber)\n        : toBig(0)\n      rewardU24 = reward24\n        .times(rewardToken ? tokenPrices[rewardToken] : 1)\n        .plus(reward24.times(rewardToken2 ? tokenPrices[rewardToken2] : 1))\n      extraU24 = 0\n      extraRewards24 = lastDay?.extraRewards?.map((item: any) => {\n        const tokenSymbol = idIndex[item.tokenId as number]\n        const extraItem = volumeToCountAsBigNumber(tokenSymbol, item.volume ?? 0)\n        extraU24 += (extraItem ?? toBig(0)).times(tokenPrices[tokenSymbol] ?? 1).toNumber()\n        return {\n          tokenSymbol,\n          amount: extraItem?.toNumber(),\n        }\n      })\n    }\n  }\n  return {\n    rewardToken: rewardToken ? coinMap[rewardToken] : undefined,\n    rewardToken2: rewardToken2 ? coinMap[rewardToken2] : undefined,\n    feeA: feeA ? feeA.toNumber() : undefined,\n    feeB: feeB ? feeB.toNumber() : undefined,\n    reward: reward ? reward.toNumber() : undefined,\n    reward2: reward2 ? reward2.toNumber() : undefined,\n    rewardU: rewardU ? rewardU.toNumber() : undefined,\n    feeU: feeU ? feeU.toNumber() : undefined,\n    feeA24: feeA24 ? feeA24.toNumber() : undefined,\n    feeB24: feeB24 ? feeB24.toNumber() : undefined,\n    feeU24: feeU24 ? feeU24.toNumber() : undefined,\n    reward24: reward24 ? reward24.toNumber() : undefined,\n    reward224: reward224 ? reward224.toNumber() : undefined,\n    rewardU24: rewardU24 ? rewardU24.toNumber() : undefined,\n    extraRewards24: extraRewards24,\n    extraU24: extraU24 ? extraU24 : undefined,\n  }\n}\n/** userAmmAsset&Reward **/\nconst getMyAmmInfo = <C>({ ammInfo, ammUserReward }: any) => {\n  let rewards\n  const { tokenPrices } = store.getState().tokenPrices\n  const { tokenMap, idIndex } = store.getState().tokenMap\n  if (ammUserReward) {\n    rewards = getRewardCalc({\n      ammInfo,\n      ammUserReward,\n    })\n  }\n  let coinA, coinB\n  if (ammInfo.coinA) {\n    coinA = ammInfo.coinA\n    coinB = ammInfo.coinB\n  } else if (ammInfo.tokens && ammInfo.tokens.pooled) {\n    coinA = idIndex[ammInfo.tokens.pooled[0]]\n    coinB = idIndex[ammInfo.tokens.pooled[1]]\n  } else {\n    ;[, coinA, coinB] = ammInfo.market.match(/(\\w+)(-\\w+)?/i)\n  }\n  let balanceA, balanceB, balanceU\n  const { walletMap } = makeWalletLayer2({ needFilterZero: false })\n\n  if (walletMap && walletMap['LP-' + ammInfo.market] && ammInfo.totalLPToken) {\n    // @ts-ignore\n    const ratio = sdk.toBig(walletMap['LP-' + ammInfo.market]?.count ?? 0).div(ammInfo.totalLPToken)\n    balanceA = ratio.times(ammInfo.totalA)\n    balanceB = ratio.times(ammInfo.totalB)\n    balanceU = balanceA.times(tokenPrices[coinA]).plus(balanceB.times(tokenPrices[ammInfo.coinB]))\n  }\n\n  return {\n    ...rewards,\n    balanceA: balanceA ? balanceA.toNumber() : undefined,\n    balanceB: balanceB ? balanceB.toNumber() : undefined,\n    balanceAStr: getValuePrecisionThousand(\n      balanceA,\n      tokenMap[coinA].precision,\n      tokenMap[coinA].precision,\n      undefined,\n      false,\n    ),\n    balanceBStr: getValuePrecisionThousand(\n      balanceB,\n      tokenMap[coinB].precision,\n      tokenMap[coinB].precision,\n      undefined,\n      false,\n    ),\n    balanceU: balanceU ? balanceU.toNumber() : undefined,\n  } as MyAmmLP<C>\n}\n\n// export const makeMyAmmWithSnapshot = <C extends { [key: string]: any }>(\n//   market: any,\n//   _walletMap: WalletMapExtend<C> | undefined,\n//   ammUserRewardMap: AmmUserRewardMap | undefined,\n//   snapShotData?:\n//     | {\n//         tickerData?: TickerData | undefined;\n//         ammPoolSnapshot: AmmPoolSnapshot | undefined;\n//       }\n//     | undefined\n// ) => {\n//   const { coinMap, idIndex, tokenMap } = store.getState().tokenMap;\n//   const { tokenPrices } = store.getState().tokenPrices;\n//   const [, coinA, coinB] = market.match(/(\\w+)-(\\w+)/i);\n//   let _myAmm: Partial<MyAmmLP<C>> = {};\n//   if (\n//     ammUserRewardMap &&\n//     ammUserRewardMap[\"AMM-\" + market] &&\n//     snapShotData &&\n//     snapShotData.ammPoolSnapshot\n//   ) {\n//     const ammUserReward = ammUserRewardMap[\"AMM-\" + market];\n//     if (coinMap && tokenMap && idIndex) {\n//       // _myAmm = getOneRewardInfo({\n//       //   coinA,\n//       //   coinB,\n//       //   ammUserReward,\n//       //   idIndex,\n//       //   tokenPrices,\n//       //   walletMap: _walletMap,\n//       //   snapShotData,\n//       // });\n//       return _myAmm as MyAmmLP<C>;\n//     }\n//   }\n//   return {\n//     feeA: undefined,\n//     feeB: undefined,\n//     feeU: undefined,\n//     reward: undefined,\n//     rewardToken: undefined as any,\n//     balanceA: undefined,\n//     balanceB: undefined,\n//     balanceU: undefined,\n//   };\n// };\n\n// export const makeMyAmmWithStat = <C extends { [key: string]: any }>(\n//   market: any,\n//   _walletMap: WalletMapExtend<C> | undefined,\n//   ammUserRewardMap: AmmUserRewardMap | undefined,\n//   ammDetail: AmmDetailStore<C>\n// ) => {\n//   const { coinMap, idIndex, tokenMap } = store.getState().tokenMap;\n//   const { tokenPrices } = store.getState().tokenPrices;\n//   const [, coinA, coinB] = market.match(/(\\w+)-(\\w+)/i);\n//   let _myAmm = {},\n//     result = {};\n//   if (ammUserRewardMap) {\n//     const ammUserReward = ammUserRewardMap[\"AMM-\" + market];\n//     result = getRewardCalc({\n//       coinA,\n//       coinB,\n//       ammUserReward,\n//       idIndex,\n//       tokenPrices,\n//     });\n//   }\n//\n//   let balanceA, balanceB, balanceU;\n//\n//   if (_walletMap && _walletMap[\"LP-\" + coinA + \"-\" + coinB] && coinMap) {\n//     // @ts-ignore\n//     const totalLpAmount = _walletMap[\"LP-\" + coinA + \"-\" + coinB].count || 0;\n//     // const ratio = new BigNumber(_walletMap[ 'LP-' + coinA + '-' + coinB ].count).div(ammDetail.totalLPToken);\n//     const ratio = totalLpAmount / (ammDetail.totalLPToken || 1);\n//     // balanceA = ratio.times(volumeToCountAsBigNumber(coinA, ammDetail.totalA ? ammDetail.totalA : 0) || 1);\n//     balanceA = ratio * (ammDetail.totalA || 0);\n//     // balanceB = ratio.times(volumeToCountAsBigNumber(coinB, ammDetail.totalB ? ammDetail.totalB : 0) || 1);\n//     balanceB = ratio * (ammDetail.totalB || 0);\n//     // @ts-ignore\n//     // balanceU = balanceA.times(fiatPrices[ coinA ] ? fiatPrices[ coinA ].price : 0).plus(balanceB.times(fiatPrices[ coinB ] ? fiatPrices[ coinB ].price : 0))\n//\n//     // WARNING! NOT ACCERATE\n//     balanceU =\n//       balanceA * (tokenPrices[coinA] ? tokenPrices[coinA] : 0) +\n//       balanceB * (tokenPrices[coinB] ? tokenPrices[coinB] : 0);\n//     const isSmallBalance = balanceU < 1;\n//\n//     _myAmm = {\n//       balanceA: balanceA,\n//       balanceB: balanceB,\n//       balanceAStr: getValuePrecisionThousand(\n//         balanceA,\n//         tokenMap[coinA].precision,\n//         tokenMap[coinA].precision,\n//         undefined\n//       ),\n//       balanceBStr: getValuePrecisionThousand(\n//         balanceB,\n//         tokenMap[coinB].precision,\n//         tokenMap[coinB].precision,\n//         undefined\n//       ),\n//       balanceU: balanceU,\n//       totalLpAmount: totalLpAmount,\n//       smallBalance: isSmallBalance,\n//       ammDetail: {\n//         ...ammDetail,\n//         coinAInfo: coinA ? coinMap[coinA] : undefined,\n//         coinBInfo: coinB ? coinMap[coinB] : undefined,\n//       },\n//     };\n//   }\n//   return {\n//     ...result,\n//     ..._myAmm,\n//   };\n// };\n"
  },
  {
    "path": "packages/core/src/hooks/help/makeWallet.ts",
    "content": "import { BIGO, numberFormat, store } from '../../index'\nimport { AccountStatus, CoinKey, WalletCoin, WalletMap } from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport BigNumber from 'bignumber.js'\nimport Decimal from 'decimal.js'\nimport { utils } from 'ethers'\n\nexport const VaultBorrowFault = 1\n\nexport type WalletMapExtend<C> = {\n  [K in CoinKey<C>]?: WalletCoin<C> & {\n    detail: sdk.UserBalanceInfo\n  }\n}\n\nexport const makeWalletLayer2 = <\n  C extends {\n    [key: string]: any\n  },\n>({\n  needFilterZero,\n  isActive = false,\n  _isToL1,\n}: {\n  needFilterZero: boolean\n  isActive?: boolean\n  _isToL1?: boolean\n  _isTotal?: boolean\n}): {\n  walletMap: WalletMapExtend<C> | undefined\n} => {\n  const { walletLayer2 } = store.getState().walletLayer2\n  const { tokenMap } = store.getState().tokenMap\n  const { readyState } = store.getState().account\n  let walletMap: WalletMapExtend<C> | undefined\n\n  if (walletLayer2) {\n    walletMap = Reflect.ownKeys(walletLayer2).reduce((prev, item) => {\n      const { total, locked } = walletLayer2[item as string]\n      const countBig = sdk.toBig(total).minus(sdk.toBig(locked))\n\n      if (needFilterZero && countBig.eq(BIGO)) {\n        return prev\n      }\n      if (_isToL1 && /^LP-/gi.test(item.toString())) {\n        return prev\n      }\n\n      return {\n        ...prev,\n        [item]: {\n          belong: item,\n          count: sdk.fromWEI(tokenMap, item, countBig.toString()),\n          detail: walletLayer2[item as string],\n        },\n      }\n    }, {} as WalletMapExtend<C>)\n  }\n  if (isActive) {\n    return { walletMap }\n  } else if (readyState === AccountStatus.ACTIVATED) {\n    return { walletMap }\n  } else {\n    return { walletMap: undefined }\n  }\n}\nexport const makeWalletLayer2NoStatus = <\n  C extends {\n    [key: string]: any\n  },\n>({\n  needFilterZero,\n  _isToL1,\n}: {\n  needFilterZero: boolean\n  _isToL1?: boolean\n}): {\n  walletMap: WalletMapExtend<C> | undefined\n} => {\n  const { walletLayer2 } = store.getState().walletLayer2\n  const { tokenMap } = store.getState().tokenMap\n  let walletMap: WalletMapExtend<C> | undefined\n\n  if (walletLayer2) {\n    walletMap = Reflect.ownKeys(walletLayer2).reduce((prev, item) => {\n      const { total, locked } = walletLayer2[item as string]\n      const countBig = sdk.toBig(total).minus(sdk.toBig(locked))\n\n      if (needFilterZero && countBig.eq(BIGO)) {\n        return prev\n      }\n      if (_isToL1 && /^LP-/gi.test(item.toString())) {\n        return prev\n      }\n\n      return {\n        ...prev,\n        [item]: {\n          belong: item,\n          count: sdk.fromWEI(tokenMap, item, countBig.toString()),\n          detail: walletLayer2[item as string],\n        },\n      }\n    }, {} as WalletMapExtend<C>)\n  }\n  return { walletMap }\n}\n\nexport const makeVaultLayer2 = <\n  C extends {\n    [key: string]: any\n  },\n  _I = WalletCoin<C> & {\n    detail: any\n  },\n>({\n  needFilterZero,\n}: // _isTotal,\n{\n  needFilterZero: boolean\n}): {\n  vaultLayer2Map: WalletMap<C> | undefined\n} => {\n  const { vaultAccountInfo,vaultLayer2 } = store.getState().vaultLayer2\n  const {\n    invest: {\n      vaultMap: { tokenMap, idIndex },\n    },\n    tokenMap: { idIndex: erc20IdIndex },\n  } = store.getState()\n  const { readyState } = store.getState().account\n  let vaultLayer2Map: WalletMap<C> | undefined\n  if (vaultAccountInfo?.userAssets && idIndex) {\n    vaultLayer2Map = vaultAccountInfo?.userAssets.reduce((prev, item) => {\n      const symbol = idIndex[item.tokenId]\n      const vaultToken = tokenMap[symbol]\n      const vaultAsset=(vaultLayer2 &&  vaultLayer2[symbol]) ??{}\n      const countBig = sdk.toBig(vaultAsset?.l2balance ?? 0).minus(vaultAsset?.locked ?? 0)\n      if (needFilterZero && countBig.eq(BIGO) && !vaultToken) {\n        return prev\n      }\n      const erc20Symbol = erc20IdIndex && erc20IdIndex[vaultToken?.tokenId ?? '']\n      return {\n        ...prev,\n        [symbol]: {\n          belongAlice: erc20Symbol,\n          erc20Symbol,\n          belong: symbol,\n          asset: numberFormat(utils.formatUnits(item?.total ?? 0, vaultToken.decimals), {\n            fixed: vaultToken.precision,\n            fixedRound: Decimal.ROUND_DOWN,\n            removeTrailingZero: true\n          }),\n          count: countBig\n            .div('1e' + vaultToken.decimals)\n            .toFixed(vaultToken.qtyStepScale ?? vaultToken.precision, BigNumber.ROUND_DOWN),\n          detail: item,\n          borrowed: numberFormat(utils.formatUnits(item?.borrowed ?? 0, vaultToken.decimals), {\n            fixed: vaultToken.precision,\n            fixedRound: Decimal.ROUND_UP,\n            removeTrailingZero: true\n          }),\n          equity: numberFormat(utils.formatUnits(item?.netAsset ?? 0, vaultToken.decimals), {\n            fixed: vaultToken.precision,\n            fixedRound: Decimal.ROUND_DOWN,\n            removeTrailingZero: true\n          }),\n        },\n      }\n    }, {} as WalletMap<C>)\n  }\n  if (readyState === AccountStatus.ACTIVATED) {\n    return { vaultLayer2Map }\n  } else {\n    return { vaultLayer2Map: undefined }\n  }\n}\n\nexport const makeVaultAvaiable2 = <\n  C extends {\n    [key: string]: any\n  },\n>({\n  fault = VaultBorrowFault,\n}: // needFilterZero,\n{\n  // needFilterZero: boolean\n  fault?: number\n}): {\n  vaultAvaiable2Map: WalletMap<C> | undefined\n} => {\n  const {\n    vaultLayer2: { vaultAccountInfo, vaultLayer2 },\n    tokenMap: {\n      // tokenMap: erc20TokenMap,\n      idIndex: erc20IdIndex,\n    },\n    // tokenPrices: { tokenPrices },\n    invest: {\n      vaultMap: { tokenMap, marketCoins, idIndex: vaultIdIndex, tokenPrices },\n    },\n  } = store.getState()\n  //@ts-ignore\n  const { maxBorrowableOfUsdt, accountStatus } = vaultAccountInfo ?? {}\n  if (accountStatus && accountStatus === sdk.VaultAccountStatus.IN_STAKING) {\n    let vaultAvaiable2Map: WalletMap<C> | undefined = marketCoins?.reduce((prev, item) => {\n      const vaultSymbol = vaultIdIndex[tokenMap[item].vaultTokenId]\n      const erc20Symbol = vaultSymbol.slice(2)\n      const price = tokenPrices[vaultSymbol] ?? (vaultSymbol == 'USDT' ? 1 : 1)\n      const vaultToken = tokenMap[vaultSymbol]\n      const status = vaultToken?.vaultTokenAmounts?.status?.toString(2)\n      if (status[1] == '1') {\n        let borrowed = sdk\n          .toBig((vaultLayer2 && vaultLayer2[vaultSymbol]?.borrowed) ?? 0)\n          .div('1e' + vaultToken.decimals)\n          .toFixed(vaultToken?.vaultTokenAmounts?.qtyStepScale ?? vaultToken.precision, 0)\n        borrowed = parseFloat(borrowed) == 0 ? 0 : borrowed\n        let walletCoin = {\n          erc20Symbol,\n          belongAlice: erc20Symbol,\n          belong: vaultSymbol,\n          borrowed: borrowed,\n          count: price\n            ? sdk\n                .toBig(maxBorrowableOfUsdt ?? 0)\n                .div(price ? price : 1)\n                .times(fault)\n                .toFixed(\n                  vaultToken?.vaultTokenAmounts?.qtyStepScale ?? vaultToken.precision,\n                  BigNumber.ROUND_DOWN,\n                )\n            : 0,\n        }\n        prev[item] = {\n          ...walletCoin,\n        }\n      }\n\n      return prev\n    }, {} as WalletMap<C>)\n    return { vaultAvaiable2Map }\n  } else {\n    return { vaultAvaiable2Map: undefined }\n  }\n}\n\nexport const makeVaultRepay = <\n  C extends {\n    [key: string]: any\n  },\n>({\n  needFilterZero,\n}: {\n  needFilterZero: boolean\n}): {\n  vaultAvaiable2Map: WalletMap<C> | undefined\n} => {\n  const {\n    vaultLayer2: { vaultAccountInfo },\n    tokenMap: {\n      // tokenMap: erc20TokenMap,\n      idIndex: erc20IdIndex,\n    },\n    invest: {\n      vaultMap: { tokenMap, idIndex: vaultIdIndex, tokenPrices },\n    },\n  } = store.getState()\n  const { accountStatus, userAssets } = vaultAccountInfo ?? {}\n  if (accountStatus && accountStatus === sdk.VaultAccountStatus.IN_STAKING) {\n    let vaultAvaiable2Map: WalletMap<C> | undefined = userAssets?.reduce((prev, item) => {\n      const vaultSymbol = vaultIdIndex[item?.tokenId ?? '']\n      const erc20Symbol = erc20IdIndex[tokenMap[vaultSymbol]?.tokenId ?? '']\n      // const price = tokenPrices[erc20Symbol] ?? 0\n      const vaultToken = tokenMap[vaultSymbol]\n      const status = vaultToken?.vaultTokenAmounts?.status?.toString(2)\n      if (\n        status?.[4] == '1' &&\n        ((vaultSymbol && needFilterZero && sdk.toBig(item.borrowed).gt(0)) || !needFilterZero)\n      ) {\n        const borrowed = sdk\n          .toBig(item.borrowed)\n          .div('1e' + vaultToken.decimals)\n          .toFixed(vaultToken?.vaultTokenAmounts?.qtyStepScale ?? vaultToken.precision, 0)\n        // .toFixed(tokenInfo.precision, 0)\n        const price = tokenPrices[vaultSymbol] ?? 0\n        let walletCoin = {\n          erc20Symbol,\n          belongAlice: erc20Symbol,\n          belong: vaultSymbol,\n          count: sdk\n            .toBig(item.total)\n            .div('1e' + vaultToken.decimals)\n            .toString(),\n          borrowed,\n          usd: sdk.toBig(borrowed).times(price).toString(),\n        }\n        // @ts-ignore\n        prev[vaultSymbol] = {\n          ...walletCoin,\n        }\n      }\n\n      return prev\n    }, {} as WalletMap<C>)\n    return { vaultAvaiable2Map }\n  } else {\n    return { vaultAvaiable2Map: undefined }\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/help/marketPairHelp.ts",
    "content": "import {\n  ammMapReducer,\n  LoopringAPI,\n  store,\n  tickerReducer,\n  volumeToCountAsBigNumber,\n} from '../../index'\n\nimport {\n  CustomError,\n  ErrorMap,\n  getValuePrecisionThousand,\n  IBData,\n  MarketType,\n  Ticker,\n} from '@loopring-web/common-resources'\nimport BigNumber from 'bignumber.js'\nimport { SwapTradeData } from '@loopring-web/component-lib'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nexport const swapDependAsync = async (\n  market: MarketType,\n  level?: number,\n  limit?: number,\n): Promise<{\n  ammPoolSnapshot: sdk.AmmPoolSnapshot | undefined\n  tickMap: sdk.LoopringMap<sdk.TickerData>\n  depth: sdk.DepthData\n}> => {\n  const { ammMap } = store.getState().amm.ammMap\n  const poolAddress = ammMap['AMM-' + market]?.address\n  if (LoopringAPI.ammpoolAPI && LoopringAPI.exchangeAPI) {\n    try {\n      const [{ depth }, { ammPoolSnapshot }, { tickMap }] = await Promise.all([\n        LoopringAPI.exchangeAPI.getMixDepth({ market, level, limit }),\n        poolAddress\n          ? LoopringAPI.ammpoolAPI.getAmmPoolSnapshot({ poolAddress })\n          : Promise.resolve({ ammPoolSnapshot: undefined }),\n        LoopringAPI.exchangeAPI.getMixTicker({ market: market }),\n      ])\n      store.dispatch(tickerReducer.updateTicker(tickMap))\n      const { ammMap } = store.getState().amm.ammMap\n      const ammInfo = ammMap['AMM-' + market]\n      if (ammPoolSnapshot && ammInfo) {\n        store.dispatch(\n          ammMapReducer.updateRealTimeAmmMap({\n            ammPoolStats: {\n              ['AMM-' + market]: {\n                ...ammInfo.__rawConfig__,\n                liquidity: [ammPoolSnapshot.pooled[0].volume, ammPoolSnapshot.pooled[1].volume],\n                lpLiquidity: ammPoolSnapshot.lp.volume,\n              },\n            },\n          }),\n        )\n      }\n      return {\n        ammPoolSnapshot: ammPoolSnapshot,\n        tickMap,\n        depth,\n      }\n    } catch (error) {\n      throw error\n    }\n  } else {\n    throw new Error('api not ready')\n  }\n}\n\nexport const dexSwapDependAsync = ({\n  market,\n  level = 0,\n  limit,\n  tokenMap,\n}: {\n  market: MarketType\n  level?: number\n  limit?: number\n  tokenMap?: any\n}): Promise<{\n  depth: sdk.DepthData | undefined\n}> => {\n  return new Promise((resolve, reject) => {\n    if (LoopringAPI.ammpoolAPI && LoopringAPI.exchangeAPI) {\n      Promise.all([\n        LoopringAPI.defiAPI?.getBtradeDepth({\n          request: {\n            market,\n            level,\n            limit,\n          },\n          tokenMap,\n        }),\n      ])\n        .then(([responseDepth]) => {\n          resolve({\n            depth: responseDepth?.depth,\n          })\n        })\n        .catch()\n    } else {\n      reject(new CustomError(ErrorMap.NO_SDK))\n    }\n  })\n}\n\nexport const calcPriceByAmmTickMapDepth = <_C>({\n  market,\n  tradePair,\n  dependencyData: { ticker, ammPoolSnapshot, depth },\n  noGetValuePrecisionThousand\n}: {\n  market: MarketType\n  tradePair: MarketType\n  dependencyData: {\n    ticker: Ticker | undefined\n    ammPoolSnapshot: any\n    depth: any\n  },\n  noGetValuePrecisionThousand?: boolean\n}): {\n  stob: string | undefined\n  btos: string | undefined\n  close: string | undefined\n} => {\n  const { tokenMap, idIndex, marketMap } = store.getState().tokenMap\n  // const  = store.getState().pageTradeLite.pageTradeLite;\n  // @ts-ignore\n  const [, coinSell] = tradePair.match(/(\\w+)-(\\w+)/i)\n  // @ts-ignore\n  const [, coinA, coinB] = market.match(/(\\w+)-(\\w+)/i)\n  let stob: number | string | undefined | BigNumber = undefined,\n    btos: number | string | undefined | BigNumber = undefined,\n    close: number | string | undefined = undefined\n  if (coinA && coinB && tokenMap && marketMap && idIndex && marketMap[market]) {\n    //first getValue from  ammPoolSnapshot\n    if (ammPoolSnapshot) {\n      const poolATokenVol: sdk.TokenVolumeV3 = ammPoolSnapshot.pooled[0]\n      const poolBTokenVol: sdk.TokenVolumeV3 = ammPoolSnapshot.pooled[1]\n      stob = volumeToCountAsBigNumber(idIndex[poolBTokenVol.tokenId], poolBTokenVol.volume)?.div(\n        volumeToCountAsBigNumber(idIndex[poolATokenVol.tokenId], poolATokenVol.volume) || 1,\n      )\n      // @ts-ignore\n      btos = noGetValuePrecisionThousand\n        ? new BigNumber(1).div(stob ?? 1).toNumber()\n        : getValuePrecisionThousand(\n            new BigNumber(1).div(stob ?? 1).toNumber(),\n            tokenMap[coinA].precision,\n            tokenMap[coinA].precision,\n            tokenMap[coinA].precision,\n            true,\n          ) // .toFixed(tokenMap[idIndex[poolATokenVol.tokenId]].precision))\n      let precision = marketMap[market].precisionForPrice\n        ? marketMap[market].precisionForPrice\n        : tokenMap[coinB].precision\n      stob = noGetValuePrecisionThousand\n        ? stob\n        : getValuePrecisionThousand(stob, precision, precision, precision, true)\n\n      // stob = Number(stob?.toFixed(tokenMap[idIndex[poolBTokenVol.tokenId]].precision))\n      close = stob?.toString()\n      if (coinSell !== coinA) {\n        stob = btos\n        btos = close\n      }\n      // myLog('pairDetailDone stob from amm:', stob)\n    }\n\n    //second getValue from tickerData\n    if ((stob === '0.00' || !stob) && ticker) {\n      // const tickerData = tickerMap[ market ]\n      let precision = marketMap[market].precisionForPrice\n        ? marketMap[market].precisionForPrice\n        : tokenMap[coinB].precision\n      close = noGetValuePrecisionThousand\n        ? ticker.close\n        : getValuePrecisionThousand(ticker.close, precision, precision, precision, true)\n      stob = close\n      btos =\n        Number(ticker.close) !== 0\n          ? noGetValuePrecisionThousand\n            ? 1 / ticker.close\n            : getValuePrecisionThousand(\n                1 / ticker.close,\n                tokenMap[coinA].precision,\n                tokenMap[coinA].precision,\n                tokenMap[coinA].precision,\n                true,\n              )\n          : 0\n      if (!ticker.__rawTicker__.base === coinSell) {\n        stob = btos\n        btos = close\n      }\n    }\n\n    //last check from depth\n    if ((stob === '0.00' || !stob) && depth) {\n      let precision = marketMap[market].precisionForPrice\n        ? marketMap[market].precisionForPrice\n        : tokenMap[coinB].precision\n      close = noGetValuePrecisionThousand\n        ? depth.mid_price\n        : getValuePrecisionThousand(depth.mid_price, precision, precision, precision, true)\n      stob = close\n      btos =\n        Number(close) !== 0\n          ? noGetValuePrecisionThousand\n            ? 1 / Number(close)\n            : getValuePrecisionThousand(\n                1 / Number(close),\n                tokenMap[coinA].precision,\n                tokenMap[coinA].precision,\n                tokenMap[coinA].precision,\n                true,\n              )\n          : 0\n      if (!tradePair === depth.symbol) {\n        stob = btos\n        btos = close\n      }\n    }\n\n    // const isValidS2B = (stob !== 0 && stob !== undefined && !isNaN(stob))\n    return {\n      btos: btos as string,\n      stob: stob as string,\n      close: close as string,\n    }\n  }\n  return {\n    btos: undefined,\n    stob: undefined,\n    close: undefined,\n  }\n}\nexport const reCalcStoB = <T extends SwapTradeData<IBData<C>>, C extends any>({\n  tokenMap,\n  market,\n  tradeData,\n  tradePair,\n  marketMap,\n  noGetValuePrecisionThousand,\n}: {\n  market: MarketType\n  tradeData: T\n  tradePair: MarketType\n  marketMap?: any\n  tokenMap?: any\n  noGetValuePrecisionThousand?: boolean\n}): { stob: string; btos: string } | undefined => {\n  const {\n    marketMap: _marketMap,\n    // marketArray: _marketArray,\n    tokenMap: _tokenMap,\n  } = store.getState().tokenMap\n  if (tokenMap && marketMap) {\n  } else {\n    // marketArray = _marketArray;\n    tokenMap = _tokenMap\n    marketMap = _marketMap\n  }\n  // const marketPrecision =  ? marketMap[market].precisionForPrice : 4;\n  //@ts-ignore\n  const [, coinA, coinB] = market.match(/([\\w,#]+)-([\\w,#]+)/i)\n  // const tokenA = tokenMap[coinA];\n  // const tokenB =;\n  if (tradeData?.sell.tradeValue && tradeData?.buy.tradeValue && tradeData?.sell.tradeValue !== 0) {\n    const sellBig = sdk.toBig(tradeData?.sell.tradeValue ?? '')\n    const buyBig = sdk.toBig(tradeData?.buy.tradeValue ?? '')\n    const marketPrecision = marketMap[market].precisionForPrice\n      ? marketMap[market].precisionForPrice\n      : tokenMap[coinB].precision\n    let stob, btos\n\n    if (market === tradePair) {\n      stob = noGetValuePrecisionThousand\n        ? buyBig.div(sellBig).toString()\n        : getValuePrecisionThousand(\n            buyBig.div(sellBig).toString(),\n            marketPrecision,\n            marketPrecision,\n            undefined,\n            true,\n          )\n      btos = noGetValuePrecisionThousand\n        ? sellBig.div(buyBig).toString()\n        : getValuePrecisionThousand(sellBig.div(buyBig).toString(), 6, 6, undefined, true)\n    } else {\n      stob = noGetValuePrecisionThousand\n        ? buyBig.div(sellBig).toString()\n        : getValuePrecisionThousand(buyBig.div(sellBig).toString(), 6, 6, undefined, true)\n      btos = noGetValuePrecisionThousand\n        ? sellBig.div(buyBig).toString()\n        : getValuePrecisionThousand(\n            sellBig.div(buyBig).toString(),\n            marketPrecision,\n            marketPrecision,\n            undefined,\n            true,\n          )\n    }\n    return { stob, btos }\n  } else {\n    return undefined\n  }\n}\n\nexport const marketInitCheck = ({\n  market,\n  type,\n  defaultValue = 'LRC-ETH',\n  marketArray,\n  tokenMap,\n  marketMap,\n  defaultA = 'LRC',\n  coinMap,\n}: // defaultB = 'ETH',\n{\n  market: string\n  type?: 'sell' | 'buy'\n  defaultValue?: string\n  marketArray?: any\n  tokenMap?: any\n  marketMap?: any\n  coinMap?: any\n  defaultA?: string | null\n  defaultB?: string | null\n}): { tradePair: MarketType } => {\n  const {\n    coinMap: _coinMap,\n    marketMap: _marketMap,\n    marketArray: _marketArray,\n    tokenMap: _tokenMap,\n  } = store.getState().tokenMap\n  if (coinMap) {\n  } else {\n    coinMap = _coinMap\n  }\n  if (marketArray) {\n  } else {\n    marketArray = _marketArray\n    tokenMap = _tokenMap\n    marketMap = _marketMap\n    coinMap = _coinMap\n  }\n  const { ammMap } = store.getState().amm.ammMap\n  if (coinMap && tokenMap && marketMap && marketArray && ammMap) {\n    let coinA: string = '#null',\n      coinB: string = '#null'\n    const result = market.match(/([\\w,#]+)-([\\w,#]+)/i)\n    if (market && result) {\n      ;[, coinA, coinB] = result\n    }\n    let whichCoinIndex = [coinA, coinB].findIndex((item) => item !== '#null')\n    if (whichCoinIndex !== -1 && coinMap[[coinA, coinB][whichCoinIndex]] === undefined) {\n      whichCoinIndex === 0 ? (coinA = defaultA as any) : (coinB = defaultA as any)\n    }\n    if (whichCoinIndex === -1) {\n      whichCoinIndex = 0\n      coinA = defaultA as any\n    }\n    if (type === 'sell' && coinB !== '#null') {\n      if (!tokenMap[coinA]?.tradePairs?.includes(coinB as never)) {\n        coinB = tokenMap[coinA]?.tradePairs ? tokenMap[coinA]?.tradePairs[0] : undefined\n      }\n    } else if (coinB === '#null' || coinA === '#null') {\n      if (\n        !tokenMap[[coinA, coinB][whichCoinIndex]]?.tradePairs.includes(\n          [coinA, coinB][whichCoinIndex ^ 1] as never,\n        )\n      ) {\n        whichCoinIndex == 0\n          ? (coinB = tokenMap[[coinA, coinB][whichCoinIndex]]?.tradePairs[0])\n          : (coinA = tokenMap[[coinA, coinB][whichCoinIndex]]?.tradePairs[0])\n      }\n    }\n    return { tradePair: `${coinA}-${coinB}` }\n  }\n\n  return { tradePair: defaultValue as MarketType }\n}\n\nexport const Limit = 14\n\nexport const vaultSwapDependAsync = ({\n  market,\n  level = 0,\n  limit,\n  tokenMap,\n}: {\n  market: MarketType\n  level?: number\n  limit?: number\n  tokenMap?: any\n}): Promise<{\n  depth: sdk.DepthData | undefined\n}> => {\n  return new Promise((resolve, reject) => {\n    if (LoopringAPI.vaultAPI) {\n      Promise.all([\n        LoopringAPI.vaultAPI?.getVaultDepth({\n          request: {\n            market,\n            level,\n            limit,\n          },\n          tokenMap,\n        }, '1'),\n      ])\n        .then(([responseDepth]) => {\n          resolve({\n            depth: responseDepth?.depth,\n          })\n        })\n        .catch()\n    } else {\n      reject(new CustomError(ErrorMap.NO_SDK))\n    }\n  })\n}\n"
  },
  {
    "path": "packages/core/src/hooks/help/marketRedPacket.ts",
    "content": "import * as sdk from '@loopring-web/loopring-sdk'\nimport { RawDataRedPacketDetailItem } from '@loopring-web/component-lib'\nimport { getShortAddr, getValuePrecisionThousand } from '@loopring-web/common-resources'\nimport { volumeToCountAsBigNumber } from './volumeToCount'\nimport { store } from '../../stores'\n\nexport const getUserReceiveList = (\n  claimList: sdk.LuckTokenClaim[],\n  tokenInfo: sdk.TokenInfo,\n  champion?: {\n    accountId: number\n    address: string\n    ens: string\n    amount: string | number\n  },\n): { list: RawDataRedPacketDetailItem[] } => {\n  const { accountId } = store.getState().account\n  const list: RawDataRedPacketDetailItem[] = claimList.reduce((prev, item) => {\n    const amountStr =\n      getValuePrecisionThousand(\n        volumeToCountAsBigNumber(tokenInfo.symbol, item.amount),\n        tokenInfo.precision,\n        tokenInfo.precision,\n        undefined,\n        false,\n        {\n          floor: false,\n        },\n      ) +\n      ' ' +\n      tokenInfo.symbol\n\n    const redPacketDetailItem: RawDataRedPacketDetailItem = {\n      accountStr: item.claimer?.ens ? item.claimer.ens : getShortAddr(item.claimer?.address ?? ''),\n      isSelf: accountId === item.claimer.accountId,\n      amountStr,\n      helper: (item.helper?.address\n        ? item.helper?.ens\n          ? item.helper.ens\n          : getShortAddr(item.helper.address.toString())\n        : ''\n      ).toString(),\n      createdAt: item.createdAt,\n      isMax: prev.find(item => item.isMax) ? false : champion?.accountId === item.claimer.accountId && champion?.amount === item.amount,\n      rawData: item,\n    }\n    return [...prev, redPacketDetailItem]\n  }, [] as RawDataRedPacketDetailItem[])\n\n  return { list }\n}\nexport const getUserNFTReceiveList = (\n  claimList: sdk.LuckTokenClaim[],\n  _nftInfo: sdk.UserNFTBalanceInfo,\n  champion?: {\n    accountId: number\n    address: string\n    ens: string\n    amount: string | number\n  },\n): { list: RawDataRedPacketDetailItem[] } => {\n  const { accountId } = store.getState().account\n  const list: RawDataRedPacketDetailItem[] = claimList.reduce((prev, item) => {\n    const amountStr =\n      'x ' +\n      getValuePrecisionThousand(item.amount, 0, 0, undefined, false, {\n        floor: false,\n      })\n\n    const redPacketDetailItem: RawDataRedPacketDetailItem = {\n      accountStr: item.claimer?.ens ? item.claimer.ens : getShortAddr(item.claimer?.address ?? ''),\n      isSelf: accountId === item.claimer.accountId,\n      amountStr,\n      helper: (item.referrer?.address\n        ? item.referrer?.ens\n          ? item.referrer.ens\n          : getShortAddr(item.referrer.address.toString())\n        : ''\n      ).toString(),\n      createdAt: item.createdAt,\n      isMax: prev.find(item => item.isMax) ? false : champion?.accountId === item.claimer.accountId && champion?.amount === item.amount,\n      rawData: item,\n    }\n    return [...prev, redPacketDetailItem]\n  }, [] as RawDataRedPacketDetailItem[])\n\n  return { list }\n}\nexport const amountStrCallback = (\n  tokenMap: any,\n  idIndex: any,\n  tokenId: any,\n  tokenAmount: string,\n) => {\n  const tokenInfo = tokenMap[idIndex[tokenId] ?? '']\n\n  if (tokenInfo && tokenAmount) {\n    const symbol = tokenInfo.symbol\n    const amount = getValuePrecisionThousand(\n      volumeToCountAsBigNumber(symbol, tokenAmount),\n      tokenInfo.precision,\n      tokenInfo.precision,\n      undefined,\n      false,\n      {\n        floor: false,\n        // isTrade: true,\n      },\n    )\n    return {\n      amountStr: amount + ' ' + symbol,\n      amount,\n    }\n  }\n  return {}\n\n  // tokenMap[]\n}\nexport const amountStrNFTCallback = (nftInfo: sdk.UserNFTBalanceInfo, tokenAmount: string) => {\n  if (nftInfo && tokenAmount) {\n    const symbol = 'NFT(s)' // nftInfo?.metadata?.base?.name ?? \"NFT\";\n    const amount = getValuePrecisionThousand(tokenAmount, 0, 0, undefined, false, {\n      floor: false,\n      // isTrade: true,\n    })\n    return {\n      amountStr: amount + ' ' + symbol,\n      amount,\n    }\n  }\n  return {}\n  // tokenMap[]\n}\n\nexport const makeViewCard = (luckToken: sdk.LuckyTokenItemForReceive) => {\n  const {\n    account,\n    localStore: { redPacketHistory },\n    tokenMap: { idIndex, tokenMap },\n    system: { chainId },\n  } = store.getState()\n  let claim: string | undefined = undefined\n  let claimed = false\n  if (\n    redPacketHistory[chainId] &&\n    redPacketHistory[chainId][account.accAddress] &&\n    redPacketHistory[chainId][account.accAddress][luckToken.hash]\n  ) {\n    const redPacket = redPacketHistory[chainId][account.accAddress][luckToken.hash]\n    claim = redPacketHistory[chainId][account.accAddress][luckToken.hash].claim\n    if (luckToken.type.mode === sdk.LuckyTokenClaimType.BLIND_BOX) {\n      claimed = redPacket.blindboxClaimed ? true : false\n    } else {\n      claimed = claim ? true : false\n    }\n  }\n  const tokenInfo = tokenMap[idIndex[luckToken.tokenId] ?? '']\n  // if ()\n\n  return {\n    chainId,\n    account,\n    amountStr: luckToken.isNft\n      ? amountStrNFTCallback(luckToken.nftTokenInfo as any, luckToken.tokenAmount.totalAmount)\n          .amount\n      : amountStrCallback(tokenMap, idIndex, luckToken.tokenId, luckToken.tokenAmount.totalAmount)\n          .amountStr,\n    myAmountStr:\n      claim &&\n      (luckToken.isNft\n        ? amountStrNFTCallback(luckToken.nftTokenInfo as any, claim).amountStr\n        : amountStrCallback(tokenMap, idIndex, luckToken.tokenId, claim).amountStr),\n    tokenInfo,\n    claim,\n    claimed,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/help/marketTable.ts",
    "content": "import * as sdk from '@loopring-web/loopring-sdk'\nimport { LoopringAPI, store, tradeItemToTableDataItem } from '../../index'\nimport { AmmRecordRow, AmmTradeType, RawDataTradeItem } from '@loopring-web/component-lib'\nimport { volumeToCount } from './volumeToCount'\nimport { myError, myLog } from '@loopring-web/common-resources'\n\nexport const getUserTrades = (market: string) => {\n  if (!LoopringAPI.userAPI) {\n    return undefined\n  }\n  const { accountId, apiKey } = store.getState().account\n  return LoopringAPI.userAPI\n    .getUserTrades({ accountId, market }, apiKey)\n    .then((response: { totalNum: any; userTrades: sdk.UserTrade[]; raw_data: any }) => {\n      return response.userTrades\n    })\n}\nexport const makeMarketArray = (\n  _coinKey: any,\n  marketTrades: sdk.MarketTradeInfo[],\n): RawDataTradeItem[] => {\n  let tradeArray: Array<Partial<RawDataTradeItem>> = []\n\n  const { tokenMap } = store.getState().tokenMap\n\n  marketTrades.forEach((item: sdk.MarketTradeInfo) => {\n    try {\n      if (tokenMap) {\n        tradeArray.push(tradeItemToTableDataItem(item))\n      }\n    } catch (error: any) {\n      myError(error)\n    }\n  })\n  return tradeArray as RawDataTradeItem[]\n}\n\nexport const getUserAmmTransaction = ({ address, offset, limit, txStatus }: any) => {\n  const { accountId, apiKey } = store.getState().account\n  return LoopringAPI.ammpoolAPI\n    ?.getUserAmmPoolTxs(\n      {\n        accountId,\n        ammPoolAddress: address,\n        limit,\n        offset,\n        txStatus,\n      },\n      apiKey,\n    )\n    .then(({ userAmmPoolTxs, totalNum }) => {\n      return {\n        userAmmPoolTxs,\n        totalNum,\n      }\n    })\n}\n\n// getAmmPoolTxs\nexport const getRecentAmmTransaction = ({ address, offset, limit }: any) => {\n  return LoopringAPI.ammpoolAPI\n    ?.getAmmPoolTxs({\n      poolAddress: address,\n      limit,\n      offset,\n    })\n    .then(({ transactions, totalNum }) => {\n      return {\n        ammPoolTrades: transactions,\n        totalNum,\n      }\n    })\n}\n\nexport const makeMyAmmMarketArray = <C extends { [key: string]: any }>(\n  _coinKey: string | undefined,\n  marketTransaction: sdk.UserAmmPoolTx[],\n): AmmRecordRow<C>[] => {\n  const tradeArray: Array<Partial<AmmRecordRow<C>> & { totalBalance: number }> = []\n  const { tokenMap, coinMap, idIndex } = store.getState().tokenMap\n\n  if (marketTransaction) {\n    marketTransaction.forEach((item: sdk.UserAmmPoolTx) => {\n      try {\n        if (\n          coinMap &&\n          tokenMap &&\n          idIndex\n          /* && !(coinKey && tokenMap['LP-'+coinKey].tokenId !== item.lpToken.tokenId) */\n        ) {\n          // @ts-ignore\n          const [, coinA, coinB] = idIndex[item.lpToken.tokenId].match(/LP-(\\w+)-(\\w+)/i)\n          const balance = item.lpToken.actualAmount\n\n          tradeArray.push({\n            type: item.txType === sdk.AmmTxType.JOIN ? AmmTradeType.add : AmmTradeType.remove,\n            totalDollar: 0,\n            totalBalance: Number(balance),\n            amountA: volumeToCount(coinA, item.poolTokens[0]?.actualAmount),\n            amountB: volumeToCount(coinB, item.poolTokens[1]?.actualAmount),\n            time: Number(item.updatedAt),\n            // @ts-ignore\n            coinA: coinMap[coinA],\n            // @ts-ignore\n            coinB: coinMap[coinB],\n            status: item.txStatus,\n          })\n        }\n        return tradeArray\n      } catch (error: any) {\n        //CATCHERROR:\n        myLog('marketTransaction::', error)\n        // new CustomError()\n      }\n    })\n  }\n  return tradeArray as AmmRecordRow<C>[]\n}\n"
  },
  {
    "path": "packages/core/src/hooks/help/parseRabbitConfig.ts",
    "content": "import { MapChainId } from \"@loopring-web/common-resources\"\nimport { ChainId } from \"@loopring-web/loopring-sdk\"\n\nexport const parseRabbitConfig = (\n  config: any,\n  fromNetwork: string,\n  idIndex: any,\n): {\n  toTaikoNetwork: string | undefined\n  toTaikoNetworkSupportedTokens: string[]\n  toL1SupportedTokens: string[]\n} => {\n  if (!config)\n    return {\n      toTaikoNetwork: undefined,\n      toTaikoNetworkSupportedTokens: [],\n      toL1SupportedTokens: [],\n    }\n  const toNetworks: string[] = config.fromToNetworks[fromNetwork] ?? []\n  const toTaikoNetwork = toNetworks.find((net) =>\n    [ChainId.TAIKO, ChainId.TAIKOHEKLA].map((id) => MapChainId[id]).includes(net),\n  )\n  const networkL2TokenIds = config.networkL2TokenIds[fromNetwork] ?? []\n  const toTaikoNetworkL1Tokens = toTaikoNetwork\n    ? config.networkL1Tokens[toTaikoNetwork] ?? {}\n    : {}\n  const toSelfL1Tokens = config.networkL1Tokens[fromNetwork]\n  const toTaikoNetworkSupportedTokens = networkL2TokenIds\n    .map((id: number) => {\n      return idIndex[id]\n    })\n    .filter((symbol) => {\n      return toTaikoNetworkL1Tokens[symbol]\n    })\n  const toL1SupportedTokens = networkL2TokenIds\n    .map((id: number) => {\n      return idIndex[id]\n    })\n    .filter((symbol) => {\n      return toSelfL1Tokens[symbol]\n    })\n\n  return {\n    toTaikoNetwork: toTaikoNetwork,\n    toTaikoNetworkSupportedTokens,\n    toL1SupportedTokens: toL1SupportedTokens as string[],\n  }\n}\nexport const networkById = (id: ChainId) => {\n  return MapChainId[id] ? (167009 === id ? 'TAIKO' : MapChainId[id]) : undefined\n}\n\nexport const parseRabbitConfig2 = (\n  config: any,\n  fromNetwork: string,\n  fromNetworkIdIndex: any,\n): {\n  toOtherNetworks: {\n    network: string\n    supportedTokens: string[]\n  }[]\n  agentId?: number\n  agentAddr?: string\n  exchange?: string\n} => {\n  if (!config)\n    return {\n      toOtherNetworks: [],\n    }\n  const toNetworks: string[] = config.fromToNetworks[fromNetwork] ?? []\n\n  const toOtherNetworks = toNetworks.filter(otherNetwork => otherNetwork !== fromNetwork).map((otherNetwork) => {\n    const networkL2TokenIds = config.networkL2TokenIds[fromNetwork] ?? []\n    const toOtherNetworkL1Tokens = config.networkL1Tokens[otherNetwork] ?? {}\n    const supportedTokens = networkL2TokenIds\n      .map((id: number) => {\n        return fromNetworkIdIndex[id]\n      })\n      .filter((symbol) => {\n        return toOtherNetworkL1Tokens[symbol]\n      })\n    \n    return {\n      network: otherNetwork,\n      supportedTokens,\n      // agentId,\n      // agentAddr,\n      // exchange,\n    }\n  })\n  const agentId = config.networkL2AgentAccountIds[fromNetwork]\n  const agentAddr = config.networkL2AgentAddresses[fromNetwork]\n  const exchange = config.networkExchanges[fromNetwork]\n  return {\n    toOtherNetworks,\n    agentId,\n    agentAddr,\n    exchange,\n  }\n}"
  },
  {
    "path": "packages/core/src/hooks/help/providorConnect.ts",
    "content": "import { accountReducer, store } from '../../stores'\nimport {\n  ConnectProviders,\n  connectProvides,\n  ErrorType,\n  walletServices,\n} from '@loopring-web/web3-provider'\nimport { myLog, SUPPORTING_NETWORKS, ThemeType } from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { updateSystem } from '../../stores/system/reducer'\nimport { setDefaultNetwork } from '@loopring-web/component-lib'\n\nconst providerCallback = async () => {\n  const { defaultNetwork } = store.getState().settings\n  if (connectProvides.usedProvide) {\n    let chainId: sdk.ChainId = Number(await connectProvides.usedWeb3?.eth.getChainId())\n    if (!SUPPORTING_NETWORKS.includes(chainId.toString())) {\n      chainId = sdk.ChainId.MAINNET\n    }\n    if (chainId !== defaultNetwork) {\n      store.dispatch(updateSystem({ chainId }))\n      store.dispatch(setDefaultNetwork(chainId))\n    }\n    return\n  }\n}\nexport const metaMaskCallback = async () => {\n  const { defaultNetwork, themeMode, isMobile } = store.getState().settings\n\n  if (!isMobile) {\n    store.dispatch(\n      accountReducer.updateAccountStatus({\n        connectName: ConnectProviders.MetaMask,\n      }),\n    )\n  }\n\n  await connectProvides.MetaMask({\n    darkMode: themeMode === ThemeType.dark,\n    chainId: defaultNetwork.toString(),\n  })\n  if (isMobile) {\n    myLog('connectProvides', connectProvides)\n    store.dispatch(\n      accountReducer.updateAccountStatus({\n        connectName: connectProvides.provideName,\n      }),\n    )\n  }\n\n  providerCallback()\n}\nexport const CoinbaseCallback = async () => {\n  const { defaultNetwork, themeMode } = store.getState().settings\n  store.dispatch(\n    accountReducer.updateAccountStatus({\n      connectName: ConnectProviders.Coinbase,\n    }),\n  )\n  await connectProvides.Coinbase({\n    darkMode: themeMode === ThemeType.dark,\n    chainId: defaultNetwork.toString(),\n  })\n\n  providerCallback()\n}\nexport const gameStopCallback = async () => {\n  const { defaultNetwork, themeMode } = store.getState().settings\n  store.dispatch(\n    accountReducer.updateAccountStatus({\n      connectName: ConnectProviders.GameStop,\n    }),\n  )\n  await connectProvides.GameStop({\n    darkMode: themeMode === ThemeType.dark,\n    chainId: defaultNetwork.toString(),\n  })\n  // statusAccountUnset();\n  providerCallback()\n}\nexport const walletConnectCallback = async () => {\n  const { defaultNetwork, themeMode } = store.getState().settings\n  store.dispatch(\n    accountReducer.updateAccountStatus({\n      connectName: ConnectProviders.WalletConnect,\n    }),\n  )\n  try {\n    await connectProvides\n      .WalletConnect({\n        darkMode: themeMode === ThemeType.dark,\n        chainId: defaultNetwork,\n      })\n      .catch((error) => {\n        throw error\n      })\n  } catch (error) {\n    walletServices.sendError(ErrorType.FailedConnect, {\n      connectName: ConnectProviders.WalletConnect,\n      error: (error as any)?.message ?? error,\n    })\n  }\n  providerCallback()\n}\n\n// export const walletConnectV1Callback = async () => {\n//   const { themeMode } = store.getState().settings\n//   store.dispatch(\n//     accountReducer.updateAccountStatus({\n//       connectName: ConnectProviders.WalletConnectV1,\n//     }),\n//   )\n//   if (!window.process) {\n//     window.process = process\n//   }\n//\n//   // await connectProvides.WalletConnectV1({\n//   //   darkMode: themeMode === ThemeType.dark,\n//   //   // chainId: defaultNetwork,\n//   // })\n//   providerCallback()\n// }\n"
  },
  {
    "path": "packages/core/src/hooks/help/useAmmTotalValue.ts",
    "content": "import React from 'react'\nimport { volumeToCount, useWalletLayer2, useTokenPrices, useSystem } from '../../index'\nimport { Currency } from '@loopring-web/loopring-sdk'\n\nexport const useAmmTotalValue = () => {\n  const { walletLayer2 } = useWalletLayer2()\n  const { tokenPrices } = useTokenPrices()\n  const { forexMap } = useSystem()\n\n  type GetAmmLiquidityProps = {\n    market: string\n    balance?: number\n    currency?: Currency\n  }\n\n  const getAmmLiquidity = React.useCallback(\n    ({ market, balance, currency = Currency.usd }: GetAmmLiquidityProps) => {\n      const price = tokenPrices && tokenPrices[market]\n      let curBalance = 0\n      if (balance) {\n        curBalance = balance\n      } else {\n        // if balance is not given, use walletl2 total lp token balance instead\n        curBalance = Number(\n          Object.entries(walletLayer2 || {}).find(([token]) => token === market)?.[1].total || 0,\n        )\n      }\n      const formattedBalance = volumeToCount(market, curBalance)\n      const unit = forexMap[currency]\n      return (price || 0) * (formattedBalance || 0) * (unit as number)\n    },\n    [forexMap, tokenPrices, walletLayer2],\n  )\n\n  return {\n    getAmmLiquidity,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/help/volumeToCount.ts",
    "content": "import { store } from '../../index'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport BigNumber from 'bignumber.js'\n\nexport const volumeToCount = (\n  symbol: string,\n  volumn: string | number | BigNumber,\n  tokenMap = store.getState().tokenMap.tokenMap,\n): number | undefined => {\n  const result = volumeToCountAsBigNumber(symbol, volumn, tokenMap)\n  return result ? result.toNumber() : undefined\n}\n\nexport const volumeToCountAsBigNumber = (\n  symbol: string,\n  volumn: string | number | BigNumber,\n  tokenMap = store.getState().tokenMap.tokenMap,\n): BigNumber | undefined => {\n  if (tokenMap && tokenMap[symbol] && typeof volumn !== 'undefined') {\n    try {\n      return sdk.toBig(volumn).div('1e' + tokenMap[symbol].decimals)\n    } catch (error: any) {\n      throw error\n    }\n  } else {\n    return undefined\n  }\n}\n\n\nexport const volumeToBigIntCount = (\n    symbol: string,\n    volumn: string | number | bigint,\n    tokenMap = store.getState().tokenMap.tokenMap,\n): string | undefined => {\n  const result = volumeToCountAsBigInt(symbol, volumn, tokenMap)\n  return result ? result.toString(10) : undefined\n}\nexport const volumeToCountAsBigInt = (\n    symbol: string,\n    volumn: string | number | bigint,\n    tokenMap = store.getState().tokenMap.tokenMap,\n): bigint | undefined => {\n  if (tokenMap && tokenMap[symbol] && typeof volumn !== 'undefined') {\n    try {\n      return BigInt(volumn) / BigInt(Number('1e' + tokenMap[symbol].decimals))\n      // return toBig(volumn).div('1e' + tokenMap[symbol].decimals)\n    } catch (error: any) {\n      throw error\n    }\n  } else {\n    return undefined\n  }\n}\n\n\nexport const getTokenNameFromTokenId = (\n  tokenId: number | string,\n  tokenMap = store.getState().tokenMap.tokenMap,\n) => {\n  if (tokenMap) {\n    const valueList = Object.values(tokenMap)\n    const hasToken = valueList.find((o) => o.tokenId === tokenId)\n    if (hasToken) {\n      return hasToken.symbol\n    }\n    return ''\n  }\n  return ''\n}\n"
  },
  {
    "path": "packages/core/src/hooks/index.ts",
    "content": "export * from './common'\nexport * from './help'\nexport * from './useractions'\nexport * from './rooters'\n"
  },
  {
    "path": "packages/core/src/hooks/rooters/index.ts",
    "content": "export * from './useLocationChange'\n"
  },
  {
    "path": "packages/core/src/hooks/rooters/useLocationChange.ts",
    "content": "import { useLocation } from 'react-router-dom'\nimport { Location } from 'history'\nimport React from 'react'\n\nconst usePrevious = (value: Location<any>): Location<any> => {\n  const ref = React.useRef<Location<any>>()\n  React.useEffect(() => {\n    ref.current = value\n  })\n  return ref.current as Location<any>\n}\nexport const useLocationChange = (\n  action: (locatin: Location<any>, prevLocation: Location<any>) => void,\n) => {\n  const location = useLocation()\n  const prevLocation = usePrevious(location)\n  React.useEffect(() => {\n    action(location, prevLocation)\n  }, [location])\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/hookAmmCommon.ts",
    "content": "import React from 'react'\nimport {\n  AccountStatus,\n  SagaStatus,\n  AmmDetail,\n  myLog,\n  ErrorMap,\n} from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport {\n  LoopringAPI,\n  useTokenMap,\n  useSocket,\n  useToast,\n  usePageAmmPool,\n  store,\n  useAmmMap,\n  AmmDetailStore,\n  useTicker,\n  makeWalletLayer2,\n  calcPriceByAmmTickMapDepth,\n  initSlippage,\n  useWalletLayer2Socket,\n  useUserRewards,\n} from '../../index'\nimport { ToastType, useOpenModals } from '@loopring-web/component-lib'\nimport { useTranslation } from 'react-i18next'\n\nconst useAmmSocket = ({ market }: { market: string }) => {\n  const { sendSocketTopic, socketEnd } = useSocket()\n  const { ammMap } = useAmmMap()\n  React.useEffect(() => {\n    const ammInfo: AmmDetail<any> = ammMap['AMM-' + market]\n    if (ammInfo?.address) {\n      sendSocketTopic({\n        [sdk.WsTopicType.ammpool]: ammInfo?.address ? [ammInfo.address] : [],\n        [sdk.WsTopicType.ticker]: [`${ammInfo.market}`],\n      })\n    } else {\n      socketEnd()\n    }\n    return () => {\n      socketEnd()\n    }\n  }, [market])\n}\n\nexport function usePairInit({ ammInfo }: { ammInfo: AmmDetailStore<any> }) {\n  const { tickerMap } = useTicker()\n  const { coinMap, tokenMap } = useTokenMap()\n  const [pairInit] = React.useState(() => {\n    let coinACount = 0,\n      coinBCount = 0,\n      percentage = 0\n    const coinLp = 'LP-' + ammInfo.market\n\n    const { walletMap } = makeWalletLayer2({ needFilterZero: false })\n    let ammCalcData: any = {\n      coinInfoMap: coinMap,\n    }\n    const lpToken = tokenMap[coinLp]\n    const { totalLPToken, totalA, totalB } = ammInfo\n\n    const {\n      close: _close,\n      stob,\n      btos,\n    } = calcPriceByAmmTickMapDepth({\n      market: ammInfo.market as any,\n      tradePair: ammInfo.market as any,\n      dependencyData: {\n        ammPoolSnapshot: {\n          poolName: ammInfo.name,\n          poolAddress: ammInfo.address,\n          pooled: [\n            {\n              tokenId: tokenMap[ammInfo.coinA].tokenId,\n              volume: ammInfo.tokens?.pooled[0] ?? 0,\n            },\n            {\n              tokenId: tokenMap[ammInfo.coinB].tokenId,\n              volume: ammInfo.tokens?.pooled[1] ?? 0,\n            },\n          ], //[ammInfo., TokenVolumeV3];\n          lp: {\n            tokenId: lpToken?.tokenId,\n            volume: ammInfo.tokens.lp,\n          },\n          risky: false,\n        },\n        ticker: tickerMap[ammInfo?.market],\n        depth: undefined,\n      },\n    })\n    ammCalcData = {\n      ...ammCalcData,\n      AtoB: stob,\n      BtoA: btos,\n      myCoinA: {\n        belong: ammInfo.coinA,\n        balance: walletMap ? walletMap[ammInfo?.coinA ?? '']?.count : undefined,\n        tradeValue: undefined,\n      },\n      myCoinB: {\n        belong: ammInfo.coinB,\n        balance: walletMap ? walletMap[ammInfo?.coinB ?? 0]?.count : undefined,\n        tradeValue: undefined,\n      },\n    }\n\n    const lpBalance = walletMap ? walletMap[coinLp ?? '']?.count : 0\n    if (totalA && totalLPToken && totalB) {\n      percentage = totalLPToken\n        ? sdk\n            .toBig(lpBalance ?? 0)\n            .div(totalLPToken)\n            .toNumber()\n        : 0\n      coinACount = totalA * percentage\n      coinBCount = totalB * percentage\n    }\n    ammCalcData = {\n      ...ammCalcData,\n      lpCoin: { belong: coinLp, balance: lpBalance },\n      lpCoinA: {\n        belong: ammInfo.coinA,\n        balance: coinACount,\n      },\n      lpCoinB: {\n        belong: ammInfo.coinB,\n        balance: coinBCount,\n      },\n      percentage,\n    }\n\n    return {\n      ammJoin: {\n        ammData: {\n          coinA: { ...ammCalcData.myCoinA, tradeValue: undefined },\n          coinB: { ...ammCalcData.myCoinB, tradeValue: undefined },\n          coinLP: { ...ammCalcData.lpCoin, tradeValue: undefined },\n          slippage: initSlippage,\n        },\n        ammCalcData,\n      },\n      ammExit: {\n        ammData: {\n          coinA: { ...ammCalcData.myCoinA, tradeValue: undefined },\n          coinB: { ...ammCalcData.myCoinB, tradeValue: undefined },\n          coinLP: { ...ammCalcData.lpCoin, tradeValue: undefined },\n          slippage: initSlippage,\n        },\n        ammCalcData,\n        // ...feePatch,\n      },\n    }\n  })\n  return { ...pairInit }\n}\n\nexport const useAmmCommon = ({ market }: { market: string }) => {\n  const { t } = useTranslation()\n  const { getUserRewards } = useUserRewards()\n\n  const { toastOpen, setToastOpen, closeToast } = useToast()\n  const { updateRealTimeAmmMap, ammMap } = useAmmMap()\n  const { marketArray, tokenMap } = useTokenMap()\n  const { setShowAccount } = useOpenModals()\n\n  const { updatePageAmmExit, updatePageAmmJoin } = usePageAmmPool()\n  const ammInfo = ammMap['AMM-' + market]\n  const { ammExit, ammJoin } = usePairInit({\n    ammInfo,\n  })\n  const updateAmmPoolSnapshot = React.useCallback(async () => {\n    const { ammMap } = store.getState().amm.ammMap\n    myLog('ammCommon', 'market', market)\n    if (market && market && LoopringAPI.ammpoolAPI) {\n      const ammInfo: any = ammMap['AMM-' + market]\n      LoopringAPI.ammpoolAPI\n        .getAmmPoolSnapshot({\n          poolAddress: ammInfo.address,\n        })\n        .then((response) => {\n          if (\n            !response ||\n            (response as sdk.RESULT_INFO).code ||\n            (response as sdk.RESULT_INFO).message\n          ) {\n            throw (response as sdk.RESULT_INFO).message\n          }\n          const { ammPoolSnapshot } = response\n          updateRealTimeAmmMap({\n            ammPoolStats: {\n              ['AMM-' + market]: {\n                ...ammMap['AMM-' + market].__rawConfig__,\n                liquidity: [ammPoolSnapshot.pooled[0].volume, ammPoolSnapshot.pooled[1].volume],\n                lpLiquidity: ammPoolSnapshot.lp.volume,\n              },\n            } as any,\n          })\n        })\n    }\n    await Promise.race([updateExitFee, updateJoinFee])\n    setShowAccount({ isShow: false })\n  }, [marketArray, market])\n  const refreshRef = React.createRef()\n  const getFee = async (\n    requestType: sdk.OffchainFeeReqType.AMM_EXIT | sdk.OffchainFeeReqType.AMM_JOIN,\n  ) => {\n    const account = store.getState().account\n    const { ammMap } = store.getState().amm.ammMap\n    const ammInfo = ammMap['AMM-' + market]\n    if (\n      ammInfo?.coinB &&\n      LoopringAPI.userAPI &&\n      account.status == SagaStatus.UNSET &&\n      account.readyState == AccountStatus.ACTIVATED &&\n      tokenMap\n    ) {\n      const feeToken: sdk.TokenInfo = tokenMap[ammInfo.coinB ?? '']\n      const request: sdk.GetOffchainFeeAmtRequest = {\n        accountId: account.accountId,\n        requestType,\n        tokenSymbol: ammInfo?.coinB,\n      }\n\n      const { fees } = await LoopringAPI.userAPI?.getOffchainFeeAmt(request, account.apiKey)\n\n      const feeRaw = fees[ammInfo.coinB] ? fees[ammInfo.coinB].fee : 0\n      const fee = sdk\n        .toBig(feeRaw)\n        .div('1e' + feeToken.decimals)\n        .toNumber()\n\n      // myLog(\"new fee:\", fee.toString());\n      return {\n        fee,\n        feeRaw,\n        fees,\n      }\n    } else {\n      throw 'not ready'\n    }\n  }\n\n  const updateExitFee = React.useCallback(async () => {\n    const account = store.getState().account\n    if (account.readyState === AccountStatus.ACTIVATED && ammInfo?.coinB) {\n      try {\n        const feeInfo = await getFee(sdk.OffchainFeeReqType.AMM_EXIT)\n        const { walletMap } = makeWalletLayer2({ needFilterZero: false })\n        const { ammExit: _ammExit } = store.getState()._router_pageAmmPool\n        let { ammCalcData, ammData } = _ammExit\n        const lpBalance = walletMap ? walletMap['LP-' + ammInfo.market]?.count : 0\n        let percentage, coinACount, coinBCount\n        if (ammInfo.totalA && ammInfo.totalLPToken && ammInfo.totalB) {\n          percentage = sdk\n            .toBig(lpBalance ?? 0)\n            .div(ammInfo?.totalLPToken ? ammInfo?.totalLPToken : 1) //totalLPToken ? lpBalance / totalLPToken : 0;\n          coinACount = sdk.toBig(ammInfo.totalA).times(percentage)\n          coinBCount = sdk.toBig(ammInfo.totalB).times(percentage)\n        }\n        if (!ammCalcData) {\n          ammCalcData = ammExit.ammCalcData\n          ammData = ammExit.ammData\n        }\n        updatePageAmmExit({\n          ammData: {\n            ...ammData,\n            coinLP: {\n              ...ammData?.coinLP,\n              balance: lpBalance,\n            } as any,\n          },\n          ammCalcData: {\n            ...ammCalcData,\n            lpCoin: {\n              ...ammCalcData?.lpCoin,\n              balance: lpBalance,\n            },\n            lpCoinA: {\n              ...ammCalcData?.lpCoinA,\n              balance: coinACount,\n            },\n            lpCoinB: {\n              ...ammCalcData?.lpCoinB,\n              balance: coinBCount,\n            },\n            percentage,\n            fee: feeInfo?.fee,\n            fees: feeInfo?.fees,\n          } as any,\n          fee: feeInfo?.fee,\n          fees: feeInfo?.fees,\n        })\n      } catch (error) {\n        console.log(error)\n        setToastOpen({\n          open: true,\n          type: ToastType.error,\n          content: t(ErrorMap.NO_NETWORK_ERROR.messageKey, {\n            ns: ToastType.error,\n          }),\n        })\n      }\n    } else {\n      const {\n        ammExit: { ammCalcData },\n      } = store.getState()._router_pageAmmPool\n      if (!ammCalcData) {\n        updatePageAmmExit({\n          ammData: {\n            ...ammExit.ammData,\n            coinLP: {\n              ...ammExit.ammData?.coinLP,\n              balance: undefined,\n            } as any,\n          },\n          ammCalcData: {\n            ...ammExit.ammCalcData,\n            lpCoin: {\n              ...ammExit.ammCalcData.lpCoin,\n              balance: undefined,\n            },\n            lpCoinA: {\n              ...ammExit.ammCalcData.lpCoinA,\n              balance: undefined,\n            },\n            lpCoinB: {\n              ...ammExit.ammCalcData.lpCoinB,\n              balance: undefined,\n            },\n            percentage: 0,\n            fee: undefined,\n            fees: undefined,\n          } as any,\n          fee: undefined,\n          fees: undefined,\n        })\n      }\n    }\n  }, [ammExit])\n  const updateJoinFee = React.useCallback(async () => {\n    const account = store.getState().account\n\n    if (ammInfo?.market && account.readyState === AccountStatus.ACTIVATED) {\n      const feeInfo = await getFee(sdk.OffchainFeeReqType.AMM_JOIN)\n      const { walletMap } = makeWalletLayer2({ needFilterZero: false })\n      const { ammJoin: _ammJoin } = store.getState()._router_pageAmmPool\n      let { ammCalcData, ammData } = _ammJoin\n      if (!ammCalcData) {\n        ammCalcData = ammJoin.ammCalcData\n        ammData = ammJoin.ammData\n      }\n      const coinA = {\n        ...ammData?.coinA,\n        balance: walletMap ? walletMap[ammInfo.coinA]?.count : undefined,\n      } as any\n      const coinB = {\n        ...ammData?.coinB,\n        balance: walletMap ? walletMap[ammInfo.coinB]?.count : undefined,\n      } as any\n      updatePageAmmJoin({\n        ammData: {\n          ...ammData,\n          coinA,\n          coinB,\n        },\n        ammCalcData: {\n          ...ammCalcData,\n          myCoinA: coinA,\n          myCoinB: coinB,\n          fee: feeInfo?.fee,\n          fees: feeInfo?.fees,\n        } as any,\n        fee: feeInfo?.fee,\n        fees: feeInfo?.fees,\n      })\n    } else {\n      const {\n        ammJoin: { ammCalcData },\n      } = store.getState()._router_pageAmmPool\n      if (!ammCalcData) {\n        updatePageAmmJoin({\n          ammData: {\n            ...ammJoin.ammData,\n            coinA: {\n              ...ammJoin.ammData.coinA,\n              balance: undefined,\n            } as any,\n            coinB: {\n              ...ammJoin.ammData.coinB,\n              balance: undefined,\n            } as any,\n          },\n          ammCalcData: {\n            ...ammJoin.ammCalcData,\n            myCoinA: {\n              ...ammJoin.ammCalcData.myCoinA,\n              balance: undefined,\n            },\n            myCoinB: {\n              ...ammJoin.ammCalcData.myCoinB,\n              balance: undefined,\n            },\n            fee: 0,\n            fees: undefined,\n          } as any,\n          fee: 0,\n          fees: undefined,\n        })\n      }\n    }\n  }, [ammJoin])\n\n  const walletLayer2Callback = React.useCallback(async () => {\n    getUserRewards()\n  }, [])\n\n  useWalletLayer2Socket({ walletLayer2Callback })\n  useAmmSocket({ market })\n\n  return {\n    toastOpen,\n    setToastOpen,\n    closeToast,\n    refreshRef,\n    updateAmmPoolSnapshot,\n    getFee,\n    ammExit,\n    ammJoin,\n    updateExitFee,\n    updateJoinFee,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/hookAmmExit.ts",
    "content": "import React from 'react'\nimport {\n  AccountStatus,\n  AmmExitData,\n  getValuePrecisionThousand,\n  IBData,\n  myLog,\n  SDK_ERROR_MAP_TO_UI,\n  SUBMIT_PANEL_QUICK_AUTO_CLOSE,\n  TradeBtnStatus,\n} from '@loopring-web/common-resources'\nimport { setShowTradeIsFrozen, ToastType, useToggle } from '@loopring-web/component-lib'\nimport {\n  DAYS,\n  getTimestampDaysLater,\n  IdMap,\n  LoopringAPI,\n  makeCache,\n  store,\n  useAccount,\n  useAmmMap,\n  usePageAmmPool,\n  useSubmitBtn,\n  useTokenMap,\n  useUserRewards,\n  useWalletLayer2Socket,\n  walletLayer2Service,\n} from '../../index'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { useTranslation } from 'react-i18next'\n\nexport const useAmmExit = ({\n  market,\n  // getFee,\n  setToastOpen,\n  setConfirmExitSmallOrder,\n  updateExitFee,\n  refreshRef,\n}: // ammCalcDefault,\n// ammDataDefault,\n{\n  market: string\n  updateExitFee: () => Promise<void>\n  // getFee: (requestType: sdk.OffchainFeeReqType.AMM_EXIT) => any;\n  setToastOpen: any\n  setConfirmExitSmallOrder: (props: { open: boolean; type: 'Disabled' | 'Mini' }) => void\n  refreshRef: React.Ref<any>\n  // ammCalcDefault: Partial<AmmExitData<any>>;\n  // ammDataDefault: Partial<AmmJoinData<IBData<string>, string>>;\n}) => {\n  const {\n    ammExit: { fees, request, ammCalcData, ammData },\n    updatePageAmmExit,\n  } = usePageAmmPool()\n  const { t } = useTranslation(['common', ToastType.error])\n  const [isLoading, setIsLoading] = React.useState(false)\n  const { idIndex, tokenMap } = useTokenMap()\n  const { ammMap } = useAmmMap()\n  const { account } = useAccount()\n  const ammInfo = ammMap['AMM-' + market]\n  const {\n    toggle: { exitAmm },\n  } = useToggle()\n  const [lpMinAmt, setLpMinAmt] = React.useState<any>(undefined)\n  const lpToken = tokenMap['LP-' + ammInfo.market]\n\n  const availableTradeCheck = React.useCallback((): {\n    tradeBtnStatus: TradeBtnStatus\n    label: string\n  } => {\n    const ammInfo = ammMap['AMM-' + market]\n    if (account.readyState === AccountStatus.ACTIVATED) {\n      const { ammData, fee } = store.getState()._router_pageAmmPool.ammExit\n      const validAmt = ammData?.coinLP?.tradeValue\n        ? sdk\n            .toBig(ammData?.coinLP?.tradeValue ?? 0)\n            .gte(sdk.toBig(lpMinAmt?.replaceAll(sdk.SEP, '') ?? 0))\n        : false\n      myLog('availableTradeCheck AMM exit validAmt: fee, lpMinAmt', fee, lpMinAmt?.toString())\n\n      if (isLoading || !(ammInfo !== undefined && ammInfo?.market)) {\n        return { tradeBtnStatus: TradeBtnStatus.LOADING, label: '' }\n      } else {\n        if (\n          ammData === undefined ||\n          ammData?.coinLP?.tradeValue === undefined ||\n          ammData?.coinLP?.tradeValue === 0 ||\n          fee === undefined ||\n          !lpMinAmt ||\n          fee === 0\n        ) {\n          myLog('will DISABLED! ', ammData, fee)\n          return {\n            tradeBtnStatus: TradeBtnStatus.DISABLED,\n            label: 'labelEnterAmount',\n          }\n        } else if (!validAmt) {\n          return {\n            tradeBtnStatus: TradeBtnStatus.DISABLED,\n            label: `labelLimitMin| ${lpMinAmt} ${ammData?.coinLP?.belong} `,\n          }\n        }\n      }\n      return {\n        tradeBtnStatus: TradeBtnStatus.AVAILABLE,\n        label: '',\n      }\n    }\n    return { tradeBtnStatus: TradeBtnStatus.AVAILABLE, label: '' }\n  }, [account.readyState, ammMap, ammInfo, isLoading, lpMinAmt])\n  const submitAmmExit = React.useCallback(async () => {\n    setIsLoading(true)\n    // updatePageAmmExitBtn({ btnStatus: TradeBtnStatus.LOADING });\n\n    if (ammInfo?.exitDisable) {\n      setShowTradeIsFrozen({\n        isShow: true,\n        messageKey: 'labelNoticeForMarketFrozen',\n        type: t('labelAmmExit') + ` ${ammInfo?.__rawConfig__.name}`,\n      })\n      setIsLoading(false)\n    } else if (!exitAmm.enable) {\n      setShowTradeIsFrozen({\n        isShow: true,\n        type: t('labelAmmExit') + ` ${ammInfo?.__rawConfig__.name}`,\n      })\n      setIsLoading(false)\n    } else {\n      sendRequest()\n    }\n  }, [request, account, t, updatePageAmmExit])\n\n  const onSubmitBtnClick = React.useCallback(\n    async (_props) => {\n      const ammExit = store.getState()._router_pageAmmPool.ammExit\n      if (ammExit.ammData.coinLP.tradeValue && ammExit.volB_show) {\n        // quoteValue < feeValue\n        const validAmt =\n          ammData?.coinLP?.tradeValue && ammExit.volB_show\n            ? sdk.toBig(ammExit.volB_show).gte(ammExit.fee)\n            : false\n        // Lp value 15% will be charge for Fee should confirm, so for quote token is 15%*2 = 0.3\n        const validMiniAmt =\n          ammData?.coinLP?.tradeValue && ammExit.volB_show\n            ? sdk.toBig(ammExit.volB_show * 0.3).gte(ammExit.fee)\n            : false\n        if (!validAmt) {\n          // quoteValue < feeValue\n          setConfirmExitSmallOrder({ open: true, type: 'Disabled' })\n        } else if (!validMiniAmt) {\n          // Lp value 15% will be charge for Fee should confirm, so for quote token is 15%*2 = 0.3\n          setConfirmExitSmallOrder({ open: true, type: 'Mini' })\n        } else {\n          submitAmmExit()\n        }\n      }\n    },\n    [tokenMap, submitAmmExit],\n  )\n  const { btnStatus, onBtnClick, btnLabel } = useSubmitBtn({\n    availableTradeCheck,\n    isLoading,\n    submitCallback: onSubmitBtnClick,\n  })\n\n  const updateMiniTradeValue = React.useCallback(() => {\n    const {\n      ammExit: {\n        fees,\n        ammCalcData,\n        ammData: { slippage },\n      },\n    } = store.getState()._router_pageAmmPool\n    const ammPoolSnapshot: any = {\n      poolName: ammInfo.name,\n      poolAddress: ammInfo.address,\n      pooled: [\n        {\n          tokenId: tokenMap[ammInfo.coinA].tokenId,\n          volume: ammInfo.tokens.pooled[0],\n        },\n        {\n          tokenId: tokenMap[ammInfo.coinB].tokenId,\n          volume: ammInfo.tokens.pooled[1],\n        },\n      ], //[ammInfo., TokenVolumeV3];\n      lp: {\n        tokenId: tokenMap['LP-' + ammInfo.market].tokenId,\n        volume: ammInfo.tokens?.lp as any,\n      },\n      risky: false,\n    }\n\n    if (ammCalcData && ammCalcData.lpCoin?.belong) {\n      const { miniLpVal } = sdk.makeExitAmmPoolMini(\n        '0',\n        ammPoolSnapshot,\n        tokenMap as any,\n        idIndex as IdMap,\n      )\n      let miniFeeLpWithSlippageVal = ''\n\n      const slippageReal = sdk\n        .toBig(slippage ?? 0.1)\n        .div(100)\n        .toString()\n      if (fees) {\n        const result = sdk.makeExitAmmCoverFeeLP(\n          fees,\n          ammPoolSnapshot,\n          tokenMap,\n          idIndex,\n          slippageReal,\n        )\n        miniFeeLpWithSlippageVal = result.miniFeeLpWithSlippageVal\n      }\n      setLpMinAmt(() => {\n        const miniVal = sdk\n          .toBig(\n            sdk.toBig(miniFeeLpWithSlippageVal ?? 0).gte(miniLpVal)\n              ? miniFeeLpWithSlippageVal\n              : miniLpVal,\n          )\n          .times(1.1)\n        myLog(\n          'updateMiniTradeValue: miniFeeLpWithSlippage, miniLpVal, miniVal = great one * 1.1 ',\n          miniFeeLpWithSlippageVal.toString(),\n          miniLpVal.toString(),\n          miniVal.toString(),\n        )\n        return getValuePrecisionThousand(\n          miniVal,\n          lpToken.precision,\n          lpToken.precision,\n          lpToken.precision,\n          false,\n          { floor: false },\n        )\n      })\n    }\n  }, [tokenMap, idIndex])\n  React.useEffect(() => {\n    // const quote: TokenVolumeV3 = ammPoolSnapshot.pooled[1];\n    if (ammInfo?.market && fees && ammData.slippage) {\n      myLog('updateMiniTradeValue: fees, slippage', fees, ammData.slippage, ammInfo?.totalLPToken)\n      updateMiniTradeValue()\n    }\n  }, [ammInfo?.tokens?.pooled, fees, ammData.slippage])\n  React.useEffect(() => {\n    updateExitFee()\n  }, [ammInfo?.tokens?.pooled])\n\n  const handleAmmPoolEvent = React.useCallback(\n    (data: AmmExitData<IBData<any>>, _type: 'coinA' | 'coinB') => {\n      const ammExit = store.getState()._router_pageAmmPool.ammExit\n      const ammInfo = ammMap['AMM-' + market]\n      const { slippage } = data\n\n      const slippageReal = sdk.toBig(slippage).div(100).toString()\n\n      let newAmmData = {\n        ...ammData,\n        ...ammExit.ammData,\n      }\n\n      let rawVal: any = data.coinLP.tradeValue\n\n      let ammDataPatch = {}\n\n      if (rawVal === undefined) {\n        rawVal = '0'\n      }\n      const ammPoolSnapshot: any = {\n        poolName: ammInfo.name,\n        poolAddress: ammInfo.address,\n        pooled: [\n          {\n            tokenId: tokenMap[ammInfo.coinA].tokenId,\n            volume: ammInfo.tokens.pooled[0],\n          },\n          {\n            tokenId: tokenMap[ammInfo.coinB].tokenId,\n            volume: ammInfo.tokens.pooled[1],\n          },\n        ], //[ammInfo., TokenVolumeV3];\n        lp: {\n          tokenId: tokenMap['LP-' + ammInfo.market].tokenId,\n          volume: ammInfo.tokens?.lp as any,\n        },\n        risky: false,\n      }\n\n      if (data.coinLP.tradeValue !== undefined && ammExit.ammCalcData) {\n        const { volA_show, volB_show, request } = sdk.makeExitAmmPoolRequest2(\n          rawVal.toString(),\n          slippageReal,\n          account.accAddress,\n          ammExit.ammCalcData?.fees as sdk.LoopringMap<sdk.OffchainFeeInfo>,\n          ammPoolSnapshot,\n          tokenMap as any,\n          idIndex as IdMap,\n          0,\n        )\n\n        newAmmData.coinA = { ...ammData.coinA, tradeValue: volA_show as any }\n        newAmmData.coinB = { ...ammData.coinB, tradeValue: volB_show as any }\n        ammDataPatch = { request, volA_show, volB_show }\n        updatePageAmmExit({\n          ...ammDataPatch,\n          ammData: {\n            ...newAmmData,\n            coinLP: data.coinLP,\n            slippage: data.slippage,\n          },\n        })\n      }\n    },\n    [market],\n  )\n  const sendRequest = React.useCallback(async () => {\n    const ammExit = store.getState()._router_pageAmmPool.ammExit\n    try {\n      if (\n        LoopringAPI.ammpoolAPI &&\n        LoopringAPI.userAPI &&\n        ammExit.request &&\n        account?.eddsaKey?.sk &&\n        ammInfo?.domainSeparator\n      ) {\n        // let req = _.cloneDeep(request);\n        const patch: sdk.AmmPoolRequestPatch = {\n          chainId: store.getState().system.chainId as sdk.ChainId,\n          ammName: ammInfo?.__rawConfig__.name ?? '',\n          poolAddress: ammInfo?.address ?? '',\n          eddsaKey: account.eddsaKey.sk,\n        }\n        const burnedReq: sdk.GetNextStorageIdRequest = {\n          accountId: account.accountId,\n          sellTokenId: ammExit.request.exitTokens.burned.tokenId as number,\n        }\n        const storageId0 = await LoopringAPI.userAPI.getNextStorageId(burnedReq, account.apiKey)\n\n        myLog('exit ammpool request:', {\n          ...ammExit.request,\n          domainSeparator: ammInfo.domainSeparator,\n          storageId: storageId0.offchainId,\n          validUntil: getTimestampDaysLater(DAYS),\n        })\n\n        const response = await LoopringAPI.ammpoolAPI\n          .exitAmmPool(\n            {\n              ...ammExit.request,\n              domainSeparator: ammInfo.domainSeparator,\n              storageId: storageId0.offchainId,\n              validUntil: getTimestampDaysLater(DAYS),\n            },\n            patch,\n            account.apiKey,\n          )\n          .finally()\n        if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n          throw response\n        } else {\n          setToastOpen({\n            open: true,\n            type: ToastType.success,\n            content: t('labelExitAmmSuccess'),\n          })\n        }\n\n        if (ammExit.ammData?.__cache__) {\n          makeCache(ammExit.ammData?.__cache__)\n        }\n      } else {\n        throw new Error('api not ready')\n      }\n    } catch (error: any) {\n      if (error?.message === 'api not ready') {\n        setToastOpen({\n          open: true,\n          type: ToastType.error,\n          content: t('labelExitAmmFailed'),\n        })\n      } else if ((error as sdk.RESULT_INFO)?.code) {\n        const errorItem = SDK_ERROR_MAP_TO_UI[(error as sdk.RESULT_INFO)?.code ?? 700001]\n        if ([102024, 102025, 114001, 114002].includes((error as sdk.RESULT_INFO)?.code || 0)) {\n          await updateExitFee()\n        }\n        setToastOpen({\n          open: true,\n          type: ToastType.error,\n          content:\n            t('labelExitAmmFailed') +\n            ' error: ' +\n            (errorItem\n              ? t(errorItem.messageKey, { ns: ToastType.error })\n              : (error as sdk.RESULT_INFO).message),\n        })\n      } else if (error?.message) {\n        sdk.dumpError400(error)\n        setToastOpen({\n          open: true,\n          type: ToastType.error,\n          content: t('labelExitAmmFailed'),\n        })\n      }\n    }\n    updatePageAmmExit({\n      ammData: {\n        ...ammData,\n        ...{\n          coinLP: { ...ammData.coinLP, tradeValue: 0 },\n        },\n      },\n    })\n\n    walletLayer2Service.sendUserUpdate()\n    // @ts-ignore\n    refreshRef?.current?.firstElementChild.click()\n    await sdk.sleep(SUBMIT_PANEL_QUICK_AUTO_CLOSE)\n    setIsLoading(false)\n    // await updateExitFee();\n  }, [ammData, account, ammInfo])\n\n  const walletLayer2Callback = React.useCallback(async () => {\n    updateExitFee()\n  }, [])\n\n  useWalletLayer2Socket({ walletLayer2Callback })\n\n  return {\n    ammCalcData,\n    ammData: ammData,\n    propsLPExtends: {\n      coinPrecision: tokenMap['LP-' + ammInfo.market].precision,\n    },\n    handleAmmPoolEvent,\n    btnStatus,\n    onAmmClick: onBtnClick,\n    btnI18nKey: btnLabel,\n    // updateExitFee,\n    exitSmallOrderCloseClick: (isAgree = false) => {\n      if (isAgree) {\n        submitAmmExit()\n      }\n    },\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/hookAmmJoin.ts",
    "content": "import React from 'react'\nimport {\n  AccountStatus,\n  AmmJoinData,\n  getValuePrecisionThousand,\n  IBData,\n  myLog,\n  SDK_ERROR_MAP_TO_UI,\n  TradeBtnStatus,\n} from '@loopring-web/common-resources'\nimport { ToastType, useOpenModals, useToggle } from '@loopring-web/component-lib'\nimport {\n  DAYS,\n  getTimestampDaysLater,\n  LoopringAPI,\n  makeCache,\n  store,\n  useAccount,\n  useAmmMap,\n  usePageAmmPool,\n  useSubmitBtn,\n  useSystem,\n  useTokenMap,\n  useUserRewards,\n  useWalletLayer2Socket,\n  walletLayer2Service,\n} from '../../index'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nimport { useTranslation } from 'react-i18next'\n\nimport _ from 'lodash'\n\n// ----------calc hook -------\n\nexport const useAmmJoin = ({\n  updateJoinFee,\n  setToastOpen,\n  market,\n  refreshRef,\n}: // ammCalcDefault,\n// ammDataDefault,\n{\n  market: string\n  updateJoinFee: () => Promise<void>\n  setToastOpen: any\n  refreshRef: React.Ref<any>\n  // ammCalcDefault: Partial<AmmInData<any>>;\n  // ammDataDefault: Partial<AmmJoinData<IBData<string>, string>>;\n}) => {\n  const {\n    ammJoin: { request, ammCalcData, ammData },\n    updatePageAmmJoin,\n  } = usePageAmmPool()\n  const [[maxCoinA, maxCoinB], setMaxLp] = React.useState<[any, any]>([Infinity, Infinity])\n  const { t } = useTranslation(['common', 'error'])\n  const [isLoading, setIsLoading] = React.useState(false)\n  const { tokenMap, idIndex, marketMap } = useTokenMap()\n  const { allowTrade } = useSystem()\n  const { ammMap } = useAmmMap()\n  const ammInfo = ammMap['AMM-' + market]\n\n  const { setShowSupport, setShowTradeIsFrozen } = useOpenModals()\n  const {\n    toggle: { joinAmm },\n  } = useToggle()\n  const { account } = useAccount()\n\n  const [baseMinAmt, setBaseMinAmt] = React.useState<any>()\n  const [quoteMinAmt, setQuoteMinAmt] = React.useState<any>()\n\n  const availableTradeCheck = React.useCallback((): {\n    tradeBtnStatus: TradeBtnStatus\n    label: string\n  } => {\n    if (account.readyState === AccountStatus.ACTIVATED) {\n      const { ammData } = store.getState()._router_pageAmmPool.ammJoin\n      const times = 10\n      const validAmt1 = ammData?.coinA?.tradeValue\n        ? ammData?.coinA?.tradeValue >= times * baseMinAmt\n        : false\n      const validAmt2 = ammData?.coinB?.tradeValue\n        ? ammData?.coinB?.tradeValue >= times * quoteMinAmt\n        : false\n\n      myLog('btnLabelActiveCheck ammJOin validAmt1:', validAmt1, ' validAmt2:', validAmt2)\n\n      if (isLoading || !(ammInfo !== undefined && ammInfo?.market)) {\n        return { tradeBtnStatus: TradeBtnStatus.LOADING, label: '' }\n      } else {\n        if (account.readyState === AccountStatus.ACTIVATED) {\n          if (\n            ammData === undefined ||\n            ammData?.coinA.tradeValue === undefined ||\n            ammData?.coinB.tradeValue === undefined ||\n            ammData.coinA.tradeValue === 0 ||\n            ammData.coinB.tradeValue === 0\n          ) {\n            return {\n              tradeBtnStatus: TradeBtnStatus.DISABLED,\n              label: 'labelEnterAmount',\n            }\n          } else if (sdk.toBig(ammData.coinA.tradeValue).gt(ammData.coinA.balance)) {\n            return {\n              tradeBtnStatus: TradeBtnStatus.DISABLED,\n              label: `labelAMMNoEnough|${ammData.coinA.belong}`,\n            }\n          } else if (sdk.toBig(ammData.coinB.tradeValue).gt(ammData.coinB.balance)) {\n            return {\n              tradeBtnStatus: TradeBtnStatus.DISABLED,\n              label: `labelAMMNoEnough|${ammData.coinB.belong}`,\n            }\n          } else if (!validAmt1 || !validAmt2) {\n            const tokenA = tokenMap[ammInfo.coinA ?? '']\n            const tokenB = tokenMap[ammInfo.coinB ?? '']\n            const viewBaseMintAmt = getValuePrecisionThousand(\n              times * baseMinAmt,\n              tokenA?.precisionForOrder ?? 4,\n              tokenA?.precisionForOrder ?? 4,\n              tokenA?.precisionForOrder ?? 2,\n              false,\n              { floor: false, isAbbreviate: true },\n            )\n            const viewQuoteMintAmt = getValuePrecisionThousand(\n              times * quoteMinAmt,\n              tokenB?.precisionForOrder ?? 4,\n              tokenB?.precisionForOrder ?? 4,\n              tokenB?.precisionForOrder ?? 2,\n              false,\n              { floor: false, isAbbreviate: true },\n            )\n            return {\n              tradeBtnStatus: TradeBtnStatus.DISABLED,\n              label: `labelLimitMin| ${viewBaseMintAmt} ${ammData?.coinA.belong}  ${t(\n                'labelAmmMinAnd',\n              )} ${viewQuoteMintAmt} ${ammData?.coinB.belong}`,\n            }\n          } else if (\n            !Number.isFinite(maxCoinA) &&\n            !Number.isFinite(maxCoinB) &&\n            (sdk.toBig(ammData.coinA.tradeValue).gt(maxCoinA) ||\n              sdk.toBig(ammData.coinB.tradeValue).gt(maxCoinB))\n          ) {\n            return {\n              tradeBtnStatus: TradeBtnStatus.DISABLED,\n              label: `labelAMMMax| ${t('labelAMMMaxAND', {\n                coinA: `${maxCoinA} ${ammData.coinA.belong}`,\n                coinB: `${maxCoinB} ${ammData.coinB.belong}`,\n              })}`,\n            }\n          }\n          return {\n            tradeBtnStatus: TradeBtnStatus.AVAILABLE,\n            label: '',\n          }\n        }\n      }\n      return {\n        tradeBtnStatus: TradeBtnStatus.AVAILABLE,\n        label: '',\n      }\n    }\n    return { tradeBtnStatus: TradeBtnStatus.AVAILABLE, label: '' }\n  }, [account.readyState, ammMap, ammInfo, isLoading, baseMinAmt, quoteMinAmt, maxCoinA, maxCoinB])\n\n  const onAmmClick = React.useCallback(\n    async function (props) {\n      setIsLoading(true)\n      if (!allowTrade.order.enable) {\n        setShowSupport({ isShow: true })\n        setIsLoading(false)\n      } else if (ammInfo?.joinDisable) {\n        setShowTradeIsFrozen({\n          isShow: true,\n          messageKey: 'labelNoticeForMarketFrozen',\n          type: t('labelAmmJoin') + ` ${ammInfo?.__rawConfig__.name}`,\n        })\n        setIsLoading(false)\n      } else if (!joinAmm.enable) {\n        setShowTradeIsFrozen({\n          isShow: true,\n          type: t('labelAmmJoin') + ` ${ammInfo?.__rawConfig__.name}`,\n        })\n        setIsLoading(false)\n      } else {\n        if (!LoopringAPI.ammpoolAPI || !LoopringAPI.userAPI || !request || !account?.eddsaKey?.sk) {\n          myLog('onAmmJoin ammpoolAPI:', LoopringAPI.ammpoolAPI, 'joinRequest:', request)\n\n          setToastOpen({\n            open: true,\n            type: ToastType.success,\n            content: t('labelJoinAmmFailed'),\n          })\n          setIsLoading(false)\n          walletLayer2Service.sendUserUpdate()\n          return\n        }\n\n        const patch: sdk.AmmPoolRequestPatch = {\n          chainId: store.getState().system.chainId as sdk.ChainId,\n          ammName: ammInfo?.__rawConfig__.name ?? '',\n          poolAddress: ammInfo?.address ?? '',\n          eddsaKey: account.eddsaKey.sk,\n        }\n\n        let req = _.cloneDeep(request)\n\n        try {\n          const request0: sdk.GetNextStorageIdRequest = {\n            accountId: account.accountId,\n            sellTokenId: req.joinTokens.pooled[0].tokenId as number,\n          }\n          const storageId0 = await LoopringAPI.userAPI.getNextStorageId(request0, account.apiKey)\n\n          const request_1: sdk.GetNextStorageIdRequest = {\n            accountId: account.accountId,\n            sellTokenId: req.joinTokens.pooled[1].tokenId as number,\n          }\n          const storageId1 = await LoopringAPI.userAPI.getNextStorageId(request_1, account.apiKey)\n\n          req.storageIds = [storageId0.offchainId, storageId1.offchainId]\n\n          req.validUntil = getTimestampDaysLater(DAYS)\n          if (ammInfo?.domainSeparator) {\n            req.domainSeparator = ammInfo?.domainSeparator\n          }\n\n          myLog('join ammpool req:', req)\n          let response\n          if (store.getState().system.chainId === 5 && /CLRC-USDT/gi.test(ammInfo.name)) {\n            console.log('Test case for new amm join, please do not submit request', req)\n          } else {\n            response = await LoopringAPI.ammpoolAPI.joinAmmPool(req, patch, account.apiKey)\n          }\n\n          myLog('join ammpool response:', response)\n\n          updatePageAmmJoin({\n            ammData: {\n              ...ammData,\n              ...{\n                coinA: { ...ammData.coinA, tradeValue: 0 },\n                coinB: { ...ammData.coinB, tradeValue: 0 },\n              },\n            },\n          })\n\n          if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n            const errorItem = SDK_ERROR_MAP_TO_UI[(response as sdk.RESULT_INFO)?.code ?? 700001]\n            setToastOpen({\n              open: true,\n              type: ToastType.error,\n              content:\n                t('labelJoinAmmFailed') +\n                ' error: ' +\n                (errorItem\n                  ? t(errorItem.messageKey, { ns: 'error' })\n                  : (response as sdk.RESULT_INFO).message),\n            })\n          } else {\n            setToastOpen({\n              open: true,\n              type: ToastType.success,\n              content: t('labelJoinAmmSuccess'),\n            })\n          }\n        } catch (reason: any) {\n          sdk.dumpError400(reason)\n          setToastOpen({\n            open: true,\n            type: ToastType.error,\n            content: t('labelJoinAmmFailed'),\n          })\n        } finally {\n          setIsLoading(false)\n          walletLayer2Service.sendUserUpdate()\n          // @ts-ignore\n          refreshRef?.current?.firstElementChild.click()\n        }\n\n        if (props.__cache__) {\n          makeCache(props.__cache__)\n        }\n      }\n    },\n    [request, ammData, account, t, allowTrade],\n  )\n  const { btnStatus, onBtnClick, btnLabel } = useSubmitBtn({\n    availableTradeCheck,\n    isLoading,\n    submitCallback: onAmmClick,\n  })\n\n  const handleAmmPoolEvent = React.useCallback(\n    (data: AmmJoinData<IBData<any>>, type: 'coinA' | 'coinB') => {\n      if (!data || !tokenMap || !data.coinA.belong || !data.coinB.belong) {\n        myLog('handleJoin return ', data)\n        return\n      }\n      const {\n        ammJoin: { ammCalcData },\n      } = store.getState()._router_pageAmmPool\n      const { ammMap } = store.getState().amm.ammMap\n      const ammInfo = ammMap['AMM-' + market]\n      const { slippage } = data\n\n      const slippageReal = sdk.toBig(slippage).div(100).toString()\n\n      const isAtoB = type === 'coinA'\n      const tokenCoinA = tokenMap[ammInfo.coinA]\n      const tokenCoinB = tokenMap[ammInfo.coinB]\n\n      const rawA = data.coinA.tradeValue ? data.coinA.tradeValue.toString() : '0'\n      const rawB = data.coinB.tradeValue ? data.coinB.tradeValue.toString() : '0'\n      const rawVal = isAtoB ? rawA : rawB\n      const rawValMatchForRawVal = isAtoB ? rawB : rawA\n      const lpToken = tokenMap['LP-' + ammInfo.market]\n\n      const ammPoolSnapshot: any = {\n        poolName: ammInfo.name,\n        poolAddress: ammInfo.address,\n        pooled: [\n          {\n            tokenId: tokenCoinA.tokenId,\n            volume: ammInfo.tokens.pooled[0],\n          },\n          {\n            tokenId: tokenCoinB.tokenId,\n            volume: ammInfo.tokens.pooled[1],\n          },\n        ], //[ammInfo., TokenVolumeV3];\n        lp: {\n          tokenId: lpToken.tokenId,\n          volume: ammInfo.tokens?.lp as any,\n        },\n        risky: false,\n      }\n      const { request } = sdk.makeJoinAmmPoolRequest(\n        rawVal,\n        isAtoB,\n        slippageReal,\n        account.accAddress,\n        ammCalcData?.fees,\n        ammPoolSnapshot,\n        tokenMap as any,\n        idIndex as any,\n        0,\n        0,\n        rawValMatchForRawVal,\n      )\n\n      const newData = _.cloneDeep(data)\n\n      if (ammInfo.tokens?.lp && sdk.toBig(ammInfo.tokens?.lp ?? 0).gt(0)) {\n        if (isAtoB) {\n          newData.coinB.tradeValue =\n            rawA !== '0'\n              ? (sdk\n                  .toBig(request.joinTokens.pooled[1].volume)\n                  .div('1e' + tokenCoinB.decimals)\n                  .toFixed(marketMap[ammInfo.market].precisionForPrice) as any)\n              : undefined\n        } else {\n          newData.coinA.tradeValue =\n            rawB !== '0'\n              ? (sdk\n                  .toBig(request.joinTokens.pooled[0].volume)\n                  .div('1e' + tokenCoinA.decimals)\n                  .toFixed(marketMap[ammInfo.market].precisionForPrice) as any)\n              : undefined\n        }\n      }\n\n      if (ammCalcData?.fee) {\n        const { request: maxResult } = sdk.makeJoinAmmPoolRequest(\n          sdk.toBig(data.coinB.balance).minus(ammCalcData?.fee).toString(),\n          false,\n          slippageReal,\n          account.accAddress,\n          ammCalcData?.fees,\n          ammPoolSnapshot,\n          tokenMap as any,\n          idIndex as any,\n          0,\n          0,\n          undefined,\n        )\n        if (ammInfo.tokens?.lp && sdk.toBig(ammInfo.tokens?.lp ?? 0).gt(0)) {\n          setMaxLp([\n            sdk\n              .toBig(maxResult.joinTokens.pooled[0].volume)\n              .div('1e' + tokenCoinA.decimals)\n              .toFixed(marketMap[ammInfo.market].precisionForPrice),\n            sdk\n              .toBig(maxResult.joinTokens.pooled[1].volume)\n              .div('1e' + tokenCoinB.decimals)\n              .toFixed(marketMap[ammInfo.market].precisionForPrice),\n          ])\n        }\n      }\n\n      myLog('raw request:', request)\n\n      updatePageAmmJoin({\n        request,\n        ammData: {\n          coinA: newData.coinA as IBData<string>,\n          coinB: newData.coinB as IBData<string>,\n          coinLP: ammData.coinLP,\n          slippage,\n        },\n      })\n    },\n    [market],\n  )\n\n  const walletLayer2Callback = React.useCallback(async () => {\n    updateJoinFee()\n    // getUserRewards()\n    const account = store.getState().account\n    if (ammInfo?.market && account.readyState === AccountStatus.ACTIVATED) {\n      const baseT = tokenMap[ammInfo.coinA]\n      const quoteT = tokenMap[ammInfo.coinB]\n      setBaseMinAmt(\n        baseT\n          ? sdk\n              .toBig(baseT.orderAmounts.minimum)\n              .div('1e' + baseT.decimals)\n              .toNumber()\n          : undefined,\n      )\n      setQuoteMinAmt(\n        quoteT\n          ? sdk\n              .toBig(quoteT.orderAmounts.minimum)\n              .div('1e' + quoteT.decimals)\n              .toNumber()\n          : undefined,\n      )\n    }\n  }, [])\n\n  useWalletLayer2Socket({ walletLayer2Callback })\n\n  return {\n    ammCalcData,\n    ammData,\n    handleAmmPoolEvent,\n    btnStatus,\n    onAmmClick: onBtnClick,\n    btnI18nKey: btnLabel,\n    updatePageAmmJoin,\n    propsAExtends: {\n      coinPrecision: tokenMap[ammInfo.coinA].precision,\n    },\n    propsBExtends: {\n      coinPrecision: tokenMap[ammInfo.coinB].precision,\n    },\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/hookSwap.ts",
    "content": "import * as sdk from '@loopring-web/loopring-sdk'\nimport React from 'react'\nimport {\n  BIGO,\n  calcPriceByAmmTickMapDepth,\n  DefaultFeeBips,\n  getPriceImpactInfo,\n  getTimestampDaysLater,\n  isTradePairMarket,\n  LoopringAPI,\n  makeWalletLayer2,\n  MAPFEEBIPS,\n  MarketCalcParams,\n  marketInitCheck,\n  PriceLevel,\n  reCalcStoB,\n  store,\n  swapDependAsync,\n  useAccount,\n  useAmmMap,\n  useAmount,\n  useBtradeMap,\n  usePageTradeLite,\n  usePairMatch,\n  useSocket,\n  useSubmitBtn,\n  useSystem,\n  useTicker,\n  useToast,\n  useTokenMap,\n  useTokenPrices,\n  useWalletLayer2,\n  useWalletLayer2Socket,\n  walletLayer2Service,\n} from '../../index'\n\nimport {\n  AccountStatus,\n  CoinMap,\n  defaultSlipage,\n  EmptyValueTag,\n  getShowStr,\n  getValuePrecisionThousand,\n  IBData,\n  MarketType,\n  myLog,\n  RouterPath,\n  SagaStatus,\n  SDK_ERROR_MAP_TO_UI,\n  SwapTradeCalcData,\n  TradeBtnStatus,\n  WalletMap,\n} from '@loopring-web/common-resources'\nimport {\n  SwapData,\n  SwapTradeData,\n  SwapType,\n  ToastType,\n  useOpenModals,\n  useSettings,\n  useToggle,\n} from '@loopring-web/component-lib'\nimport { useTranslation } from 'react-i18next'\nimport { useHistory } from 'react-router-dom'\n\nimport BigNumber from 'bignumber.js'\n\nexport enum ShowWitchAle3t1 {\n  AlertImpact = 'AlertImpact',\n  SwapSecondConfirmation = 'SwapSecondConfirmation',\n  ConfirmImpact = 'ConfirmImpact',\n  SmallPrice = 'SmallPrice',\n}\n\nexport const useAlert = () => {\n  const [confirmed, setConfirmed] = React.useState<[boolean, boolean]>([false, false])\n  const [showAlert, setShowWhich] = React.useState<{\n    isShow: boolean\n    step: 1 | 2\n    showWitch: '' | ShowWitchAle3t1\n  }>({\n    isShow: false,\n    step: 1,\n    showWitch: '',\n  })\n  return {\n    showAlert,\n    confirmed,\n    setShowWhich,\n    setConfirmed,\n  }\n}\n\nconst useSwapSocket = () => {\n  const { sendSocketTopic, socketEnd } = useSocket()\n  const { ammMap } = useAmmMap()\n  const { pageTradeLite } = usePageTradeLite()\n  React.useEffect(() => {\n    if (pageTradeLite.market) {\n      sendSocketTopic({\n        [sdk.WsTopicType.ammpool]: ammMap['AMM-' + pageTradeLite.market]\n          ? [ammMap['AMM-' + pageTradeLite.market].address]\n          : [],\n        [sdk.WsTopicType.mixorder]: {\n          markets: [pageTradeLite.market],\n          level: 0,\n          count: 50,\n          snapshot: true,\n        },\n      })\n    } else {\n      socketEnd()\n    }\n    return () => {\n      socketEnd()\n    }\n  }, [pageTradeLite?.market])\n}\n\nexport const useSwap = <\n  T extends SwapTradeData<IBData<C>>,\n  C extends { [key: string]: any },\n  CAD extends SwapTradeCalcData<T>,\n>({\n  path,\n}: {\n  path: string\n}) => {\n  //High: No not Move!!!!!!\n  const { realMarket } = usePairMatch({ path })\n  const { t } = useTranslation(['common', 'error'])\n  const history = useHistory()\n  const refreshRef = React.createRef()\n  const { toastOpen, setToastOpen, closeToast } = useToast()\n  const { isMobile, swapSecondConfirmation } = useSettings()\n  const { setShowSupport, setShowTradeIsFrozen } = useOpenModals()\n  const { account, status: accountStatus } = useAccount()\n  const { marketArray: bTradeMarketArray } = useBtradeMap()\n  const {\n    toggle: { order },\n  } = useToggle()\n  /** loaded from loading **/\n  const { exchangeInfo, allowTrade } = useSystem()\n  const { coinMap, tokenMap, marketArray, marketCoins, marketMap } = useTokenMap()\n  const { ammMap } = useAmmMap()\n  /** init Ticker ready from ui-backend load**/\n  const { tickerMap } = useTicker()\n  /** get store value **/\n  /** after unlock **/\n  const { amountMap, getAmount, status: amountStatus } = useAmount()\n  const { status: walletLayer2Status } = useWalletLayer2()\n  const [sellMinAmt, setSellMinAmt] = React.useState<string>()\n  const [tradeData, setTradeData] = React.useState<T | undefined>(undefined)\n  const [tradeCalcData, setTradeCalcData] = React.useState<CAD & { [key: string]: any }>({\n    coinInfoMap: marketCoins?.reduce((prev: any, item: string | number) => {\n      return { ...prev, [item]: coinMap ? coinMap[item] : {} }\n    }, {} as CoinMap<C>),\n  } as CAD)\n  /** redux storage **/\n  const {\n    pageTradeLite,\n    updatePageTradeLite,\n    __SUBMIT_LOCK_TIMER__,\n    __TOAST_AUTO_CLOSE_TIMER__,\n    __DAYS__,\n  } = usePageTradeLite()\n  /*** api prepare ***/\n  // const [pair, setPair] = React.useState(realPair);\n  const [isSwapLoading, setIsSwapLoading] = React.useState(false)\n  /***confirm  ***/\n  const [storageId, setStorageId] = React.useState<{\n    orderId: number\n    offchainId: number\n  }>({} as any)\n  const { tokenPrices } = useTokenPrices()\n\n  const showSwapSecondConfirmation = swapSecondConfirmation !== false\n  const isSmallOrder =\n    tradeData && tradeData.buy.tradeValue\n      ? tokenPrices[tradeData.buy.belong] * tradeData.buy.tradeValue < 100\n      : false\n  const resetMarket = (_market: MarketType, type: 'sell' | 'buy') => {\n    const { tradePair } = marketInitCheck({ market: _market, type })\n    const [_, sellToken, buyToken] = (tradePair ?? '').match(/(\\w+)-(\\w+)/i)\n    let { market } = sdk.getExistedMarket(marketArray, sellToken, buyToken)\n    setIsMarketStatus((state) => {\n      return {\n        tradePair,\n        market,\n        isMarketInit: state.market !== market,\n      }\n    })\n    if (coinMap && tokenMap && marketMap && marketArray) {\n      // const { tradePair } = marketInitCheck({ market: _market, type });\n      // @ts-ignore\n      const [, coinA, coinB] = tradePair.match(/([\\w,#]+)-([\\w,#]+)/i)\n      let walletMap: WalletMap<any> | undefined\n      if (\n        account.readyState === AccountStatus.ACTIVATED &&\n        walletLayer2Status === SagaStatus.UNSET\n      ) {\n        if (!Object.keys(tradeCalcData.walletMap ?? {}).length) {\n          walletMap = makeWalletLayer2({ needFilterZero: true }).walletMap as WalletMap<any>\n        }\n        walletMap = tradeCalcData.walletMap as WalletMap<any>\n      }\n      const tradeDataTmp: any = {\n        sell: {\n          belong: coinA,\n          tradeValue: 0,\n          balance: walletMap ? walletMap[coinA]?.count : 0,\n        },\n        buy: {\n          belong: coinB,\n          tradeValue: 0,\n          balance: walletMap ? walletMap[coinB]?.count : 0,\n        },\n      }\n\n      const sellCoinInfoMap = tokenMap[coinB]?.tradePairs?.reduce(\n        (prev: any, item: string | number) => {\n          return { ...prev, [item]: coinMap[item] }\n        },\n        {} as CoinMap<C>,\n      )\n\n      const buyCoinInfoMap = tokenMap[coinA].tradePairs?.reduce(\n        (prev: any, item: string | number) => {\n          return { ...prev, [item]: coinMap[item] }\n        },\n        {} as CoinMap<C>,\n      )\n\n      setTradeCalcData((state) => {\n        return {\n          ...state,\n          walletMap,\n          coinSell: coinA,\n          coinBuy: coinB,\n          sellPrecision: tokenMap[coinA as string]?.precision,\n          buyPrecision: tokenMap[coinB as string]?.precision,\n          sellCoinInfoMap,\n          buyCoinInfoMap,\n          priceImpact: '',\n          priceImpactColor: 'inherit',\n          minimumReceived: undefined,\n          StoB: undefined,\n          BtoS: undefined,\n          fee: undefined,\n          feeTakerRate: undefined,\n          tradeCost: undefined,\n          isShowBtradeAllow: false,\n        }\n      })\n      setTradeData({ ...tradeDataTmp })\n      history.push(`${RouterPath.lite}/${_market}`)\n      updatePageTradeLite({ market, tradePair })\n      myLog('hookSwap: Market change getAmount', market)\n    }\n  }\n  const [{ market, isMarketInit }, setIsMarketStatus] = React.useState<{\n    market: MarketType\n    tradePair?: MarketType\n    isMarketInit?: boolean\n  }>({} as any)\n  React.useEffect(() => {\n    resetMarket(realMarket ?? '#null-#null', 'sell')\n  }, [])\n\n  const clearData = (calcTradeParams: Partial<MarketCalcParams> | null | undefined) => {\n    setTradeData((state) => {\n      return {\n        ...state,\n        sell: { ...state?.sell, tradeValue: undefined },\n        buy: { ...state?.buy, tradeValue: undefined },\n        isChecked: undefined,\n      } as T\n    })\n    setTradeCalcData((state) => {\n      return {\n        ...state,\n        minimumReceived: undefined,\n        priceImpact: undefined,\n        fee: undefined,\n        isNotMatchMarketPrice: undefined,\n        marketPrice: undefined,\n        marketRatePrice: undefined,\n        isChecked: undefined,\n        isShowBtradeAllow: false,\n      }\n    })\n    updatePageTradeLite({\n      market,\n      maxFeeBips: MAPFEEBIPS,\n      calcTradeParams: {\n        ...calcTradeParams,\n        // takerRate: undefined,\n        // feeBips: undefined,\n        output: undefined,\n        sellAmt: undefined,\n        buyAmt: undefined,\n        amountS: undefined,\n        amountBOut: undefined,\n        amountBOutWithoutFee: undefined,\n        amountBOutSlip: undefined,\n        priceImpact: undefined,\n      },\n    })\n  }\n  // @ts-ignore\n  const availableTradeCheck = React.useCallback((): {\n    tradeBtnStatus: TradeBtnStatus\n    label: string | undefined\n  } => {\n    if (!tokenMap && !tokenPrices) {\n      return {\n        label: undefined,\n        tradeBtnStatus: TradeBtnStatus.DISABLED,\n      }\n    }\n    const account = store.getState().account\n    const sellToken = tokenMap[tradeData?.sell.belong as string]\n    const buyToken = tokenMap[tradeData?.buy.belong as string]\n\n    const { calcTradeParams } = pageTradeLite\n\n    if (!sellToken || !buyToken || !calcTradeParams || storageId?.orderId == undefined) {\n      return {\n        label: undefined,\n        tradeBtnStatus: TradeBtnStatus.DISABLED,\n      }\n    }\n    const walletMap = makeWalletLayer2({ needFilterZero: true }).walletMap ?? {}\n\n    let validAmt = !!(\n      calcTradeParams?.amountS &&\n      sellMinAmt &&\n      sdk.toBig(calcTradeParams?.amountS).gte(sdk.toBig(sellMinAmt))\n    )\n\n    const sellExceed = sdk.toBig(sellToken?.orderAmounts?.maximum).lt(calcTradeParams.amountS ?? 0)\n\n    const buyExceed = sdk\n      .toBig(buyToken?.orderAmounts?.maximum)\n      .lt(calcTradeParams?.amountBOutSlip?.minReceived ?? 0)\n\n    if (sellExceed || buyExceed) {\n      validAmt = false\n    }\n\n    const notEnough = sdk\n      .toBig(walletMap[sellToken.symbol]?.count ?? 0)\n      .lt(calcTradeParams.sellAmt ?? 0)\n\n    const sellMaxVal = sdk.toBig(sellToken?.orderAmounts?.maximum).div('1e' + sellToken.decimals)\n    const buyMaxVal = sdk.toBig(buyToken?.orderAmounts?.maximum).div('1e' + buyToken.decimals)\n\n    if (isSwapLoading || isMarketInit) {\n      return {\n        label: undefined,\n        tradeBtnStatus: TradeBtnStatus.LOADING,\n      }\n    } else {\n      if (account.readyState === AccountStatus.ACTIVATED) {\n        if (!calcTradeParams || !calcTradeParams.sellAmt || !calcTradeParams.buyAmt) {\n          myLog(\n            'hookSwap: calcTradeParams.baseAmt:',\n            calcTradeParams.sellAmt,\n            ' calcTradeParams.quoteAmt:',\n            calcTradeParams.buyAmt,\n          )\n\n          return {\n            label: 'labelEnterAmount',\n            tradeBtnStatus: TradeBtnStatus.DISABLED,\n          }\n        } else if (notEnough) {\n          return {\n            label: `labelArgNoEnough| ${tradeData?.sell.belong}`,\n            tradeBtnStatus: TradeBtnStatus.DISABLED,\n          }\n        } else if (sellExceed) {\n          const maxOrderSize = sellMaxVal + ' ' + tradeData?.sell.belong\n          return {\n            label: `labelLimitMax| ${maxOrderSize}`,\n            tradeBtnStatus: TradeBtnStatus.DISABLED,\n          }\n        } else if (buyExceed) {\n          const maxOrderSize = buyMaxVal + ' ' + tradeData?.buy.belong\n          return {\n            label: `labelLimitMax| ${maxOrderSize}`,\n            tradeBtnStatus: TradeBtnStatus.DISABLED,\n          }\n        } else if (!validAmt) {\n          //!validAmt) {\n          const sellSymbol = tradeData?.sell.belong\n\n          if (sellMinAmt === undefined || !sellSymbol || sellMinAmt === 'NaN') {\n            return {\n              label: 'labelEnterAmount',\n              tradeBtnStatus: TradeBtnStatus.DISABLED,\n            }\n          } else {\n            const sellToken = tokenMap[sellSymbol]\n            // //VolToNumberWithPrecision(sellMinAmt ?? '', sellSymbol as any)\n            const minOrderSize = getValuePrecisionThousand(\n              sdk.toBig(sellMinAmt ?? 0).div('1e' + sellToken.decimals),\n              sellToken.precision,\n              sellToken.precision,\n              sellToken.precision,\n              false,\n              { floor: false, isAbbreviate: true },\n            )\n            if (isNaN(Number(minOrderSize))) {\n              return {\n                label: `labelLimitMin| ${EmptyValueTag + ' ' + sellSymbol}`,\n                tradeBtnStatus: TradeBtnStatus.DISABLED,\n              }\n            } else {\n              return {\n                label: `labelLimitMin| ${minOrderSize + ' ' + sellSymbol}`,\n                tradeBtnStatus: TradeBtnStatus.DISABLED,\n              }\n            }\n          }\n        } else {\n          return {\n            label: undefined,\n            tradeBtnStatus: TradeBtnStatus.AVAILABLE,\n          }\n        }\n      } else {\n        return {\n          label: undefined,\n          tradeBtnStatus: TradeBtnStatus.AVAILABLE,\n        }\n      }\n    }\n  }, [\n    tokenMap,\n    tradeCalcData?.isChecked,\n    tradeCalcData?.isNotMatchMarketPrice,\n    tradeData?.sell.belong,\n    tradeData?.buy.belong,\n    pageTradeLite,\n    sellMinAmt,\n    isMarketInit,\n    isSwapLoading,\n    storageId.orderId,\n  ])\n  /*** Btn related function ***/\n  const swapFunc = React.useCallback(async () => {\n    let { calcTradeParams, tradeChannel, orderType, maxFeeBips } = pageTradeLite\n    if (\n      !LoopringAPI.userAPI ||\n      !tokenMap ||\n      !exchangeInfo ||\n      !calcTradeParams ||\n      account.readyState !== AccountStatus.ACTIVATED\n    ) {\n      setToastOpen({\n        open: true,\n        type: ToastType.error,\n        content: t('labelSwapFailed'),\n      })\n      setIsSwapLoading(false)\n\n      return\n    }\n    const sell = tradeData?.sell.belong as string\n    const buy = tradeData?.buy.belong as string\n    const sellToken = tokenMap[sell]\n    const buyToken = tokenMap[buy]\n    try {\n      const request: sdk.SubmitOrderRequestV3 = {\n        exchange: exchangeInfo.exchangeAddress,\n        accountId: account.accountId,\n        storageId: storageId.orderId,\n        sellToken: {\n          tokenId: sellToken.tokenId,\n          volume: calcTradeParams.amountS as string,\n        },\n        buyToken: {\n          tokenId: buyToken.tokenId,\n          volume: calcTradeParams.amountBOutSlip?.minReceived as string,\n        },\n        allOrNone: false,\n        validUntil: getTimestampDaysLater(__DAYS__),\n        // maxFeeBips: parseInt(totalFee as string),\n        maxFeeBips: maxFeeBips ?? MAPFEEBIPS,\n        fillAmountBOrS: false, // amm only false\n        orderType,\n        tradeChannel,\n        eddsaSignature: '',\n      }\n      myLog('submitOrder request', request)\n      const response: { hash: string } | any = await LoopringAPI.userAPI.submitOrder(\n        request,\n        account.eddsaKey.sk,\n        account.apiKey,\n      )\n      if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n        const errorItem = SDK_ERROR_MAP_TO_UI[(response as sdk.RESULT_INFO)?.code ?? 700001]\n        if ((response as sdk.RESULT_INFO).code === 114002) {\n          getAmount({ market })\n          clearData(calcTradeParams)\n        }\n        setToastOpen({\n          open: true,\n          type: ToastType.error,\n          content:\n            t('labelSwapFailed') +\n            ' error: ' +\n            (errorItem\n              ? t(errorItem.messageKey, { ns: 'error' })\n              : (response as sdk.RESULT_INFO).message),\n        })\n      } else {\n        getStorageId()\n        await sdk.sleep(__TOAST_AUTO_CLOSE_TIMER__)\n        const resp = await LoopringAPI.userAPI.getOrderDetails(\n          {\n            accountId: account.accountId,\n            orderHash: response.hash,\n          },\n          account.apiKey,\n        )\n        myLog('hookSwap:-----> resp:', resp)\n        if (resp.orderDetail?.status !== undefined) {\n          myLog('hookSwap:resp.orderDetail:', resp.orderDetail)\n          switch (resp.orderDetail?.status) {\n            case sdk.OrderStatus.cancelled:\n              const baseAmount = sdk.toBig(resp.orderDetail.volumes.baseAmount)\n              const baseFilled = sdk.toBig(resp.orderDetail.volumes.baseFilled)\n              const quoteAmount = sdk.toBig(resp.orderDetail.volumes.quoteAmount)\n              const quoteFilled = sdk.toBig(resp.orderDetail.volumes.quoteFilled)\n              const percentage1 = baseAmount.eq(BIGO) ? 0 : baseFilled.div(baseAmount).toNumber()\n              const percentage2 = quoteAmount.eq(BIGO) ? 0 : quoteFilled.div(quoteAmount).toNumber()\n              myLog('hookSwap:percentage1:', percentage1, ' percentage2:', percentage2)\n              if (percentage1 === 0 || percentage2 === 0) {\n                setToastOpen({\n                  open: true,\n                  type: ToastType.warning,\n                  content: t('labelSwapCancelled'),\n                })\n              } else {\n                setToastOpen({\n                  open: true,\n                  type: ToastType.success,\n                  content: t('labelSwapSuccess'),\n                })\n              }\n              break\n            case sdk.OrderStatus.processed:\n              setToastOpen({\n                open: true,\n                type: ToastType.success,\n                content: t('labelSwapSuccess'),\n              })\n              break\n            default:\n              setToastOpen({\n                open: true,\n                type: ToastType.error,\n                content: t('labelSwapFailed'),\n              })\n          }\n        }\n        walletLayer2Service.sendUserUpdate()\n        clearData(calcTradeParams)\n      }\n    } catch (reason: any) {\n      sdk.dumpError400(reason)\n      setToastOpen({\n        open: true,\n        type: ToastType.error,\n        content: t('labelSwapFailed'),\n      })\n    }\n    await sdk.sleep(__SUBMIT_LOCK_TIMER__)\n    setIsSwapLoading(false)\n  }, [\n    pageTradeLite,\n    tokenMap,\n    exchangeInfo,\n    account.readyState,\n    account.accountId,\n    account.apiKey,\n    account.eddsaKey.sk,\n    tradeData?.sell?.belong,\n    tradeData?.buy?.belong,\n    __SUBMIT_LOCK_TIMER__,\n    setToastOpen,\n    t,\n    __DAYS__,\n    getAmount,\n    market,\n    __TOAST_AUTO_CLOSE_TIMER__,\n    updatePageTradeLite,\n  ])\n\n  const { showAlert, confirmed, setShowWhich, setConfirmed } = useAlert()\n\n  const doShowAlert = () => {\n    const { priceLevel } = getPriceImpactInfo(pageTradeLite.calcTradeParams, account.readyState)\n    myLog('hookSwap:---- swapCalculatorCallback priceLevel:', priceLevel)\n    setConfirmed((state) => {\n      if (isSmallOrder) {\n        state[1] = false\n      } else {\n        state[1] = true\n      }\n      setShowWhich(() => {\n        if (tradeCalcData?.isNotMatchMarketPrice) {\n          return { isShow: true, step: 1, showWitch: ShowWitchAle3t1.AlertImpact }\n        } else if (priceLevel === PriceLevel.Lv1 || priceLevel === PriceLevel.Lv2) {\n          return { isShow: true, step: 1, showWitch: ShowWitchAle3t1.ConfirmImpact }\n        } else if (isSmallOrder) {\n          state[0] = true\n          return { isShow: true, step: 2, showWitch: ShowWitchAle3t1.SmallPrice }\n        } else if (showSwapSecondConfirmation) {\n          return { isShow: true, step: 1, showWitch: ShowWitchAle3t1.SwapSecondConfirmation }\n        } else {\n          state[0] = true\n          return { isShow: false, step: 2, showWitch: '' }\n        }\n      })\n      return state\n    })\n  }\n  React.useEffect(() => {\n    if (confirmed[0] === true && confirmed[1] === true) {\n      swapFunc()\n      setConfirmed([false, false])\n    }\n  }, [confirmed[0], confirmed[1]])\n\n  const swapCalculatorCallback = React.useCallback(async () => {\n    setIsSwapLoading(true)\n    if (!allowTrade.order.enable) {\n      setShowSupport({ isShow: true })\n      setIsSwapLoading(false)\n    } else if (!order.enable) {\n      setShowTradeIsFrozen({ isShow: true, type: 'Swap' })\n      setIsSwapLoading(false)\n    } else {\n      doShowAlert()\n    }\n  }, [\n    pageTradeLite.calcTradeParams,\n    account.readyState,\n    allowTrade.order.enable,\n    order.enable,\n    setShowSupport,\n    setShowTradeIsFrozen,\n    swapFunc,\n    showSwapSecondConfirmation,\n    isSmallOrder,\n  ])\n  const {\n    btnStatus: swapBtnStatus,\n    onBtnClick: onSwapClick,\n    btnLabel: swapBtnI18nKey,\n  } = useSubmitBtn({\n    availableTradeCheck,\n    isLoading: isSwapLoading || (isMarketInit ?? false),\n    submitCallback: swapCalculatorCallback,\n  })\n\n  /*** Btn related end ***/\n  const toPro = React.useCallback(() => {\n    history.push({\n      pathname: `${RouterPath.pro}/${market}`,\n    })\n  }, [market])\n\n  const should15sRefresh = React.useCallback(() => {\n    if (market) {\n      // updateDepth()\n      callPairDetailInfoAPIs()\n      // marketTradeTableCallback();\n    }\n  }, [market])\n  /*** table related end ***/\n  const getStorageId = React.useCallback(async () => {\n    if (\n      tradeCalcData?.coinSell &&\n      tokenMap &&\n      tokenMap[tradeCalcData.coinSell] &&\n      LoopringAPI.userAPI\n    ) {\n      // setStorageId({} as any)\n      const storageId = await LoopringAPI.userAPI.getNextStorageId(\n        {\n          accountId: account.accountId,\n          sellTokenId: tokenMap[tradeCalcData.coinSell].tokenId,\n        },\n        account.apiKey,\n      )\n      if ((storageId as sdk.RESULT_INFO).code) {\n        setToastOpen({\n          open: true,\n          content: 'error: getStorageId',\n          type: ToastType.error,\n        })\n      } else {\n        setStorageId(storageId)\n      }\n    } else {\n      setStorageId({} as any)\n    }\n  }, [tradeCalcData?.coinSell, account, tokenMap])\n  React.useEffect(() => {\n    if (accountStatus === SagaStatus.UNSET) {\n      const account = store.getState().account\n      // walletLayer2Callback()\n      if (account.readyState === AccountStatus.ACTIVATED) {\n        getAmount({ market })\n      }\n    }\n  }, [accountStatus, market])\n  React.useEffect(() => {\n    if (accountStatus === SagaStatus.UNSET) {\n      const account = store.getState().account\n      if (account.readyState === AccountStatus.ACTIVATED && tradeCalcData?.coinSell) {\n        getStorageId()\n      }\n    }\n  }, [accountStatus, tradeCalcData?.coinSell])\n\n  const walletLayer2Callback = React.useCallback(async () => {\n    // let walletMap: WalletMap<any> | undefined = undefined\n    if (account.readyState === AccountStatus.ACTIVATED) {\n      refreshAmmPoolSnapshot()\n    } else {\n      if (tradeCalcData.coinSell && tradeCalcData.coinBuy) {\n        setTradeData((state) => {\n          return {\n            ...state,\n            sell: { belong: tradeCalcData.coinSell },\n            buy: { belong: tradeCalcData.coinBuy },\n          } as T\n        })\n      }\n      updatePageTradeLite({\n        market: market as MarketType,\n        feeBips: 0,\n        totalFee: 0,\n        takerRate: 0,\n        calcTradeParams: {},\n        priceImpactObj: undefined,\n      })\n      setTradeCalcData((state) => {\n        return {\n          ...state,\n          walletMap: {},\n          isShowBtradeAllow: false,\n          minimumReceived: undefined,\n          priceImpact: undefined,\n          fee: undefined,\n        }\n      })\n    }\n  }, [tradeData, market, tradeCalcData, marketArray, ammMap, account.readyState])\n\n  useSwapSocket()\n  useWalletLayer2Socket({ walletLayer2Callback })\n\n  /*** user Action function ***/\n  //High: effect by wallet state update\n  const handleSwapPanelEvent = async (\n    swapData: SwapData<SwapTradeData<IBData<C>>>,\n    swapType: any,\n  ): Promise<void> => {\n    const { tradeData: _tradeData } = swapData\n    myLog('hookSwap: handleSwapPanelEvent', swapType, _tradeData)\n    switch (swapType) {\n      case SwapType.SEll_CLICK:\n      case SwapType.BUY_CLICK:\n        return\n      case SwapType.SELL_SELECTED:\n        myLog('hookSwap: handleSwapPanelEvent _tradeData', _tradeData)\n        if (_tradeData?.sell.belong !== tradeData?.sell.belong) {\n          resetMarket(\n            `${_tradeData?.sell?.belong ?? `#null`}-${_tradeData?.buy?.belong ?? `#null`}`,\n            'sell',\n          )\n        } else {\n          reCalculateDataWhenValueChange(\n            _tradeData,\n            `${_tradeData?.sell.belong}-${_tradeData?.buy.belong}`,\n            'sell',\n          )\n        }\n        // throttleSetValue('sell', _tradeData)\n        break\n      case SwapType.BUY_SELECTED:\n        //type = 'buy'\n        if (_tradeData?.buy.belong !== tradeData?.buy.belong) {\n          resetMarket(\n            `${_tradeData?.sell?.belong ?? `#null`}-${_tradeData?.buy?.belong ?? `#null`}`,\n            'buy',\n          )\n        } else {\n          reCalculateDataWhenValueChange(\n            _tradeData,\n            `${_tradeData?.sell.belong}-${_tradeData?.buy.belong}`,\n            'buy',\n          )\n        }\n        break\n      case SwapType.EXCHANGE_CLICK:\n        const { close } = pageTradeLite\n        let btos: string = '0'\n        if (close) {\n          // @ts-ignore\n          const [, _coinA] = market.match(/(\\w+)-(\\w+)/i)\n          btos = getValuePrecisionThousand(\n            1 / Number(typeof close === 'number' ? close : close.replaceAll(sdk.SEP, '')),\n            tokenMap[_coinA].precision,\n            tokenMap[_coinA].precision,\n            tokenMap[_coinA].precision,\n            true,\n          ) // .toFixed(tokenMap[idIndex[poolATokenVol.tokenId]].precision))\n        }\n        const _tradeCalcData: any = {\n          ...tradeCalcData,\n          coinSell: tradeCalcData.coinBuy,\n          sellPrecision: tokenMap[tradeCalcData.coinBuy as string].precision,\n          coinBuy: tradeCalcData.coinSell,\n          buyPrecision: tokenMap[tradeCalcData.coinSell as string].precision,\n          sellCoinInfoMap: tradeCalcData.buyCoinInfoMap,\n          buyCoinInfoMap: tradeCalcData.sellCoinInfoMap,\n          StoB: market === `${tradeCalcData.coinBuy}-${tradeCalcData.coinSell}` ? close : btos,\n          BtoS: market === `${tradeCalcData.coinBuy}-${tradeCalcData.coinSell}` ? btos : close,\n          isShowBtradeAllow: false,\n          priceImpact: undefined,\n          priceImpactColor: 'inherit',\n          minimumReceived: undefined,\n          fee: undefined,\n          feeTakerRate: undefined,\n          tradeCost: undefined,\n          isNotMatchMarketPrice: undefined,\n          marketPrice: undefined,\n          marketRatePrice: undefined,\n          isChecked: undefined,\n        }\n\n        myLog('hookSwap:Exchange,tradeCalcData,_tradeCalcData', tradeCalcData, _tradeCalcData)\n        callPairDetailInfoAPIs()\n        updatePageTradeLite({\n          market,\n          tradePair: `${tradeCalcData.coinBuy}-${tradeCalcData.coinSell}`,\n          calcTradeParams: {\n            ...pageTradeLite.calcTradeParams,\n            isReverse: !pageTradeLite.calcTradeParams,\n            amountS: undefined,\n            output: undefined,\n          },\n        })\n        setSellMinAmt(undefined)\n        setTradeCalcData(_tradeCalcData)\n        setTradeData((state) => {\n          const walletMap = makeWalletLayer2({ needFilterZero: true }).walletMap\n          return {\n            ...(state ?? {}),\n            sell: {\n              belong: _tradeCalcData.coinSell,\n              tradeValue: undefined,\n              balance: walletMap ? walletMap[_tradeCalcData.coinSell as string]?.count : 0,\n            },\n            buy: {\n              belong: _tradeCalcData.coinBuy,\n              tradeValue: undefined,\n              balance: walletMap ? walletMap[_tradeCalcData.coinBuy as string]?.count : 0,\n            },\n          } as T\n        })\n\n        break\n      default:\n        break\n    }\n  }\n\n  React.useEffect(() => {\n    myLog(\n      'hookSwap: pageTradeLite.deep amountStatus storageId',\n      storageId,\n      amountStatus,\n      pageTradeLite?.depth?.symbol,\n      market,\n    )\n    if (\n      amountStatus == SagaStatus.UNSET &&\n      pageTradeLite.depth &&\n      pageTradeLite.depth.symbol === market\n    ) {\n      refreshAmmPoolSnapshot()\n      setIsMarketStatus((state) => {\n        return {\n          ...state,\n          isMarketInit: false,\n        }\n      })\n    }\n  }, [\n    pageTradeLite.depth,\n    tradeCalcData.coinBuy,\n    account.readyState,\n    storageId,\n    amountStatus,\n    market,\n  ])\n\n  React.useEffect(() => {\n    if (market) {\n      //@ts-ignore\n      if (refreshRef.current) {\n        myLog('hookSwap: pageTradeLite, click', market)\n        // @ts-ignore\n        refreshRef.current.firstElementChild.click()\n        should15sRefresh()\n      }\n    }\n  }, [market])\n  const refreshAmmPoolSnapshot = React.useCallback(() => {\n    const { ticker, ammPoolSnapshot, depth, lastStepAt, tradePair, market } = pageTradeLite\n    if (\n      tradeData &&\n      lastStepAt &&\n      tradeCalcData.coinSell === tradeData['sell'].belong &&\n      tradeCalcData.coinBuy === tradeData['buy'].belong &&\n      tradeData[lastStepAt].tradeValue &&\n      tradeData[lastStepAt].tradeValue !== 0\n    ) {\n      reCalculateDataWhenValueChange(tradeData, tradePair, lastStepAt)\n    } else if (\n      tradeCalcData.coinSell &&\n      tradeCalcData.coinBuy &&\n      (`${tradeCalcData.coinSell}-${tradeCalcData.coinBuy}` === market ||\n        `${tradeCalcData.coinBuy}-${tradeCalcData.coinSell}` === market)\n    ) {\n      const walletMap = makeWalletLayer2({ needFilterZero: true }).walletMap\n      let { stob, btos, close } = calcPriceByAmmTickMapDepth({\n        market: market as any,\n        tradePair: `${tradeCalcData.coinSell}-${tradeCalcData.coinBuy}`,\n        dependencyData: { ticker, ammPoolSnapshot, depth },\n        noGetValuePrecisionThousand: true\n      })\n      const result = reCalcStoB({\n        market,\n        tradeData: tradeData as SwapTradeData<IBData<unknown>>,\n        tradePair: tradePair as any,\n        noGetValuePrecisionThousand: true\n      })\n      const reserveInfo = sdk.getReserveInfo(tradeCalcData.coinSell as string, tradeCalcData.coinBuy as string, marketArray, tokenMap, marketMap)\n      setTradeCalcData((state) => {\n        return { \n          ...state, \n          walletMap,\n          StoB: getValuePrecisionThousand(\n            result ? result.stob : stob,\n            undefined,\n            reserveInfo?.isReverse ? 6 : marketMap[market].precisionForPrice,\n            reserveInfo?.isReverse ? 6 : marketMap[market].precisionForPrice,\n            true\n          ),\n          BtoS: getValuePrecisionThousand(\n            result ? result.btos : btos,\n            undefined,\n            !reserveInfo?.isReverse ? 6 : marketMap[market].precisionForPrice,\n            !reserveInfo?.isReverse ? 6 : marketMap[market].precisionForPrice,\n            true,\n          ),\n        }\n      })\n      setTradeData({\n        ...tradeData,\n        sell: {\n          ...tradeData?.sell,\n          belong: tradeCalcData.coinSell,\n          balance: walletMap ? walletMap[tradeCalcData.coinSell as string]?.count : 0,\n        },\n        buy: {\n          ...tradeData?.buy,\n          belong: tradeCalcData.coinBuy,\n        },\n      } as T)\n      // } as T)\n\n      updatePageTradeLite({ market, close })\n    }\n  }, [market, pageTradeLite, tradeData, tradeCalcData, setTradeCalcData])\n\n  const callPairDetailInfoAPIs = React.useCallback(async () => {\n    if (market && ammMap && LoopringAPI.exchangeAPI) {\n      try {\n        const { depth, ammPoolSnapshot } = await swapDependAsync(market)\n        if (depth) {\n          const { tickerMap } = store.getState().tickerMap\n          myLog('hookSwap: pageTradeLite', 'depth')\n          updatePageTradeLite({\n            market,\n            depth,\n            ammPoolSnapshot,\n            ticker: tickerMap[market],\n          })\n        }\n      } catch (error: any) {\n        myLog('hookSwap: error:', error, 'go to LRC-ETH')\n        setToastOpen({\n          open: true,\n          content: 'error: resetMarket',\n          type: ToastType.error,\n        })\n      }\n    }\n  }, [market, ammMap, tickerMap])\n  const reCalculateDataWhenValueChange = React.useCallback(\n    (_tradeData, _tradePair?, type?) => {\n      const walletMap = makeWalletLayer2({ needFilterZero: true }).walletMap\n      const { ammPoolSnapshot, depth, tradePair, close } =\n        store.getState()._router_pageTradeLite.pageTradeLite\n      const { amountMap } = store.getState().amountMap\n      let calcForMinAmt, calcForMinCost, calcForPriceImpact\n      myLog('hookSwap:reCalculateDataWhenValueChange', tradeData, _tradePair, type)\n      if (depth && market && _tradePair && isTradePairMarket(_tradePair, market) && _tradeData) {\n        const coinA = _tradeData.sell.belong\n        const coinB = _tradeData.buy.belong\n        _tradeData.sell.balance = walletMap ? walletMap[coinA]?.count : 0\n\n        const sellToken = tokenMap[coinA as string]\n        const buyToken = tokenMap[coinB as string]\n\n        const isAtoB = type === 'sell'\n\n        let input: any = isAtoB ? _tradeData.sell.tradeValue : _tradeData.buy.tradeValue\n        input = input === undefined || isNaN(Number(input)) ? 0 : Number(input)\n        let slippage = sdk\n          .toBig(\n            _tradeData.slippage && !isNaN(_tradeData.slippage)\n              ? _tradeData.slippage\n              : defaultSlipage,\n          )\n          .times(100)\n          .toString()\n        let totalFee: any = undefined\n        let feeTakerRate: any = undefined\n        let feeBips: any = undefined\n        let takerRate: any = undefined\n        let buyMinAmtInfo: any = undefined\n        let sellMinAmtInfo: any = undefined\n        let tradeCost: any = undefined\n        let basePrice: any = undefined\n        let tradePrice: any = undefined\n        let maxFeeBips: any = MAPFEEBIPS\n\n        if (amountMap && amountMap[market as string] && ammMap) {\n          myLog(`hookSwap: amountMap[${market}]:`, amountMap[market as string])\n\n          const ammMarket = `AMM-${market}`\n          // const amount = ammMap[ammMarket]\n          //   ? amountMap[ammMarket]\n          //   : amountMap[market as string];\n          const amountMarket = amountMap[market as string]\n\n          buyMinAmtInfo = amountMarket[_tradeData['buy'].belong as string]\n          sellMinAmtInfo = amountMarket[_tradeData['sell'].belong as string]\n          // myLog(`buyMinAmtInfo,sellMinAmtInfo: AMM-${market}, ${_tradeData[ 'buy' ].belong}`, buyMinAmtInfo, sellMinAmtInfo)\n\n          takerRate = buyMinAmtInfo ? buyMinAmtInfo.userOrderInfo.takerRate : 0\n          feeBips = ammMap[ammMarket] ? ammMap[ammMarket].__rawConfig__.feeBips : DefaultFeeBips\n\n          feeTakerRate =\n            amountMarket[_tradeData['buy'].belong as string] &&\n            amountMarket[_tradeData['buy'].belong as string].userOrderInfo.takerRate\n          tradeCost = amountMarket[_tradeData['buy'].belong as string].tradeCost\n\n          const minAmountInput = BigNumber.max(\n            buyMinAmtInfo.userOrderInfo.minAmount,\n            tokenMap[buyToken.symbol].orderAmounts.dust,\n          )\n            .div(sdk.toBig(1).minus(sdk.toBig(slippage).div(10000)))\n            .div('1e' + buyToken.decimals)\n            .toString()\n\n          calcForMinAmt = sdk.getOutputAmount({\n            input: minAmountInput,\n            sell: coinA,\n            buy: coinB,\n            isAtoB: false,\n            marketArr: marketArray as string[],\n            tokenMap: tokenMap as any,\n            marketMap: marketMap as any,\n            depth,\n            ammPoolSnapshot: ammPoolSnapshot,\n            feeBips: feeBips ? feeBips.toString() : DefaultFeeBips,\n            takerRate: '0',\n            slipBips: slippage,\n          })\n\n          myLog(\n            'hookSwap:buyMinAmtInfo.userOrderInfo.minAmount:',\n            buyMinAmtInfo.userOrderInfo.minAmount,\n            `buyMinAmtInfo.userOrderInfo.minAmount, with slippage:${slippage}`,\n            sdk\n              .toBig(buyMinAmtInfo.userOrderInfo.minAmount)\n              .div(sdk.toBig(1).minus(sdk.toBig(slippage).div(10000)))\n              .toString(),\n          )\n\n          /*** calc for Price Impact ****/\n          const sellMinAmtInput = sdk\n            .toBig(sellMinAmtInfo.baseOrderInfo.minAmount)\n            .div('1e' + sellToken.decimals)\n            .toString()\n\n          calcForPriceImpact = sdk.getOutputAmount({\n            input: sellMinAmtInput,\n            sell: coinA,\n            buy: coinB,\n            isAtoB: true,\n            marketArr: marketArray as string[],\n            tokenMap: tokenMap as any,\n            marketMap: marketMap as any,\n            depth,\n            ammPoolSnapshot: ammPoolSnapshot,\n            feeBips: feeBips ? feeBips.toString() : DefaultFeeBips,\n            takerRate: '0',\n            slipBips: '10',\n          })\n\n          basePrice = sdk.toBig(calcForPriceImpact?.output).div(sellMinAmtInput)\n\n          myLog(\n            'hookSwap:calcForPriceImpact input: ',\n            sellMinAmtInput,\n            ', output: ',\n            sdk.toBig(calcForPriceImpact?.output).div(sellMinAmtInput).toNumber(),\n            ', calcForPriceImpact:',\n            calcForPriceImpact?.amountBOutSlip?.minReceivedVal,\n            ', calcForPriceImpact basePrice: ',\n            basePrice.toNumber(),\n          )\n\n          /**** calc for min Cost ****/\n          const dustToken = buyToken\n          let calcForMinCostInput = BigNumber.max(\n            sdk.toBig(tradeCost).times(2),\n            sdk.toBig(dustToken.orderAmounts.dust),\n          )\n\n          const tradeCostInput = calcForMinCostInput\n            .div(sdk.toBig(1).minus(sdk.toBig(slippage).div(10000)))\n            .div('1e' + dustToken.decimals)\n            .toString()\n\n          myLog(\n            'hookSwap:tradeCost*2:',\n            sdk.toBig(tradeCost).times(2).toString(),\n            'buyToken.orderAmounts.dust',\n            buyToken.orderAmounts.dust,\n            'calcForMinCostInput',\n            calcForMinCostInput.toString(),\n            `calcForMinCostInput, with slippage:${slippage}`,\n            calcForMinCostInput.div(sdk.toBig(1).minus(sdk.toBig(slippage).div(10000))).toString(),\n            'calcForMinCost, Input',\n            tradeCostInput,\n          )\n\n          calcForMinCost = sdk.getOutputAmount({\n            input: tradeCostInput,\n            sell: coinA,\n            buy: coinB,\n            isAtoB: false,\n            marketArr: marketArray as string[],\n            tokenMap: tokenMap as any,\n            marketMap: marketMap as any,\n            depth,\n            ammPoolSnapshot: ammPoolSnapshot,\n            feeBips: feeBips ? feeBips.toString() : DefaultFeeBips,\n            takerRate: '0',\n            slipBips: slippage,\n          })\n          const minAmt = BigNumber.max(\n            sellToken.orderAmounts.dust,\n            calcForMinCost?.amountS ?? 0,\n          ).times(1.1)\n          setSellMinAmt(minAmt.toString())\n          myLog(\n            `hookSwap:calcForMinAmt.amountS`,\n            sdk\n              .toBig(calcForMinAmt?.amountS ?? 0)\n              .div('1e' + tokenMap[_tradeData['sell'].belong as string].decimals)\n              .toString(),\n            'calcForMinCost.amountS',\n            sdk\n              .toBig(calcForMinCost?.amountS ?? 0)\n              .div('1e' + tokenMap[_tradeData['sell'].belong as string].decimals)\n              .toString(),\n          )\n        }\n        const calcTradeParams = sdk.getOutputAmount({\n          input: input.toString(),\n          sell: coinA,\n          buy: coinB,\n          isAtoB,\n          marketArr: marketArray as string[],\n          tokenMap: tokenMap as any,\n          marketMap: marketMap as any,\n          depth,\n          ammPoolSnapshot: ammPoolSnapshot,\n          feeBips: feeBips ? feeBips.toString() : DefaultFeeBips,\n          takerRate: '0',\n          slipBips: slippage,\n        })\n\n        const minSymbol = _tradeData.buy.belong\n        tradePrice = sdk\n          .toBig(calcTradeParams?.amountBOutSlip?.minReceivedVal ?? 0)\n          .div(isAtoB ? input.toString() : calcTradeParams?.output)\n        const priceImpact = sdk\n          .toBig(1)\n          .minus(sdk.toBig(tradePrice).div(basePrice ?? 1))\n          .minus(0.001)\n        if (calcTradeParams && priceImpact.gte(0)) {\n          calcTradeParams.priceImpact = priceImpact.toFixed(4, 1)\n        } else {\n          calcTradeParams && (calcTradeParams.priceImpact = '0')\n        }\n\n        if (\n          tradeCost &&\n          calcTradeParams &&\n          calcTradeParams.amountBOutSlip?.minReceived &&\n          feeTakerRate\n        ) {\n          let value = sdk\n            .toBig(calcTradeParams.amountBOutSlip?.minReceived)\n            .times(feeTakerRate)\n            .div(10000)\n\n          myLog(\n            'hookSwap:input Accounts',\n            calcTradeParams?.amountS,\n            '100 U calcForMinAmt:',\n            calcForMinAmt?.amountS,\n          )\n\n          let validAmt = !!(\n            calcTradeParams?.amountS &&\n            calcForMinAmt?.amountS &&\n            sdk.toBig(calcTradeParams?.amountS).gte(calcForMinAmt.amountS)\n          )\n          let totalFeeRaw\n\n          myLog(\n            `hookSwap:${minSymbol} tradeCost:`,\n            tradeCost,\n            'useTakeRate Fee:',\n            value.toString(),\n            'calcForMinAmt?.amountS:',\n            calcForMinAmt?.amountS,\n            `is setup minTrade amount, ${calcForMinAmt?.amountS}:`,\n            validAmt,\n          )\n\n          if (!validAmt) {\n            if (sdk.toBig(tradeCost).gte(value)) {\n              totalFeeRaw = sdk.toBig(tradeCost)\n            } else {\n              totalFeeRaw = value\n            }\n            myLog(\n              'hookSwap:maxFeeBips update for tradeCost before value:',\n              maxFeeBips,\n              'totalFeeRaw',\n              totalFeeRaw.toString(),\n            )\n            maxFeeBips = Math.ceil(\n              totalFeeRaw.times(10000).div(calcTradeParams.amountBOutSlip?.minReceived).toNumber(),\n            )\n            myLog('hookSwap:maxFeeBips update for tradeCost after value:', maxFeeBips)\n          } else {\n            totalFeeRaw = sdk.toBig(value)\n          }\n\n          totalFee = getValuePrecisionThousand(\n            totalFeeRaw.div('1e' + tokenMap[minSymbol].decimals).toString(),\n            tokenMap[minSymbol].precision,\n            tokenMap[minSymbol].precision,\n            tokenMap[minSymbol].precision,\n            false,\n            { floor: true },\n          )\n          tradeCost = getValuePrecisionThousand(\n            sdk\n              .toBig(tradeCost)\n              .div('1e' + tokenMap[minSymbol].decimals)\n              .toString(),\n            tokenMap[minSymbol].precision,\n            tokenMap[minSymbol].precision,\n            tokenMap[minSymbol].precision,\n            false,\n            { floor: true },\n          )\n\n          myLog('hookSwap:totalFee view value:', totalFee, tradeCost)\n        }\n\n        const minimumReceived = getValuePrecisionThousand(\n          sdk\n            .toBig(calcTradeParams?.amountBOutSlip?.minReceivedVal ?? 0)\n            .minus(totalFee)\n            .toString(),\n          tokenMap[minSymbol].precision,\n          tokenMap[minSymbol].precision,\n          tokenMap[minSymbol].precision,\n          false,\n          { floor: true },\n        )\n        const minimumConverted = calcTradeParams?.amountBOut\n          ? getValuePrecisionThousand(\n              sdk\n                .toBig(calcTradeParams.amountBOut)\n                .times(sdk.toBig(1).minus(sdk.toBig(slippage).div('10000')))\n                .div('1e' + tokenMap[minSymbol].decimals)\n                .toString(),\n              tokenMap[minSymbol].precision,\n              tokenMap[minSymbol].precision,\n              tokenMap[minSymbol].precision,\n              false,\n              { floor: true },\n            )\n          : undefined\n\n        const priceImpactObj = getPriceImpactInfo(calcTradeParams, account.readyState)\n        let _tradeCalcData: CAD & { [key: string]: any } = {\n          priceImpact: priceImpactObj.value.toString(),\n          priceImpactColor: priceImpactObj.priceImpactColor,\n          minimumReceived: !minimumReceived?.toString().startsWith('-')\n            ? minimumReceived\n            : undefined,\n          fee: totalFee,\n          feeTakerRate,\n          tradeCost,\n          minimumConverted,\n        } as CAD\n        _tradeData[isAtoB ? 'buy' : 'sell'].tradeValue = getShowStr(calcTradeParams?.output)\n\n        const result = reCalcStoB({\n          market,\n          tradeData: _tradeData as SwapTradeData<IBData<unknown>>,\n          tradePair: tradePair as any,\n        })\n        if (result && result.stob && sdk.toBig(result.stob?.replaceAll(sdk.SEP, '')).gt(0)) {\n          _tradeCalcData.StoB = result.stob\n          _tradeCalcData.BtoS = result.btos\n        } else {\n          if (close) {\n            // @ts-ignore\n            const [, _coinA] = market.match(/(\\w+)-(\\w+)/i)\n            let _btos = getValuePrecisionThousand(\n              1 / Number(close.replaceAll(sdk.SEP, '')),\n              tokenMap[_coinA].precision,\n              tokenMap[_coinA].precision,\n              tokenMap[_coinA].precision,\n              true,\n            ) // .toFixed(tokenMap[idIndex[poolATokenVol.tokenId]].precision))\n\n            if (market === tradePair) {\n              _tradeCalcData.StoB = close\n              _tradeCalcData.BtoS = _btos\n            } else {\n              _tradeCalcData.StoB = _btos\n              _tradeCalcData.BtoS = close\n            }\n          }\n        }\n        if (tokenPrices) {\n          const marketPrice = sdk\n            .toBig(tokenPrices[_tradeData.sell.belong])\n            .div(tokenPrices[_tradeData.buy.belong])\n          const marketRatePrice = marketPrice.div(_tradeCalcData.StoB?.replaceAll(sdk.SEP, '') ?? 1)\n          const isNotMatchMarketPrice = marketRatePrice.gt(1.05)\n          _tradeCalcData.isNotMatchMarketPrice = isNotMatchMarketPrice\n          _tradeCalcData.marketPrice = getValuePrecisionThousand(\n            marketPrice.toString(),\n            tokenMap[_tradeData.buy.belong].precision,\n            tokenMap[_tradeData.buy.belong].precision,\n            undefined,\n          )\n\n          _tradeCalcData.marketRatePrice = marketRatePrice.minus(1).times(100).toFixed(2)\n          myLog(\n            'hookSwap: stob',\n            _tradeCalcData.StoB,\n            marketPrice.toString(),\n            'marketPriceRate',\n            _tradeCalcData.marketRatePrice,\n            isNotMatchMarketPrice,\n          )\n        }\n        let isShowBtradeAllow = false\n        if (\n          priceImpactObj.value &&\n          priceImpactObj.value > 1 &&\n          bTradeMarketArray &&\n          (bTradeMarketArray.includes(_tradeData.buy.belong + '-' + _tradeData.sell.belong) ||\n            bTradeMarketArray.includes(_tradeData.sell.belong + '-' + _tradeData.buy.belong))\n        ) {\n          isShowBtradeAllow = true\n        }\n\n        updatePageTradeLite({\n          market,\n          calcTradeParams: {\n            ...calcTradeParams,\n            feeBips: feeBips ? feeBips : DefaultFeeBips,\n            takerRate: takerRate ? takerRate : 0,\n          } as any,\n          priceImpactObj,\n          lastStepAt: type,\n          feeBips,\n          takerRate,\n          sellMinAmtInfo: sellMinAmtInfo as any,\n          buyMinAmtInfo: buyMinAmtInfo as any,\n          totalFee,\n          maxFeeBips,\n          feeTakerRate,\n          tradeCost,\n        })\n        //setOutput(calcTradeParams)\n        if (account.readyState !== AccountStatus.ACTIVATED) {\n          // @ts-ignore\n          _tradeCalcData.priceImpact = undefined\n          _tradeCalcData.minimumReceived = undefined\n        }\n        if (_tradeData?.isChecked !== undefined) {\n          myLog('hookSwap: tradeCalcData?.isChecked', _tradeData)\n          _tradeCalcData.isChecked = _tradeData.isChecked\n        }\n        setTradeCalcData((state) => ({\n          ...state,\n          ..._tradeCalcData,\n          isShowBtradeAllow,\n          lastStepAt: type,\n          walletMap,\n        }))\n        setTradeData((state) => ({\n          ...state,\n          ..._tradeData,\n        }))\n      }\n    },\n    [\n      account.readyState,\n      amountMap,\n      pageTradeLite,\n      tradeCalcData,\n      tradeData,\n      coinMap,\n      tokenMap,\n      marketMap,\n      marketArray,\n      bTradeMarketArray,\n    ],\n  )\n\n  return {\n    tradeCalcData,\n    tradeData,\n    handleSwapPanelEvent,\n    onSwapClick,\n    swapBtnI18nKey,\n    swapBtnStatus,\n    toastOpen,\n    closeToast,\n    should15sRefresh,\n    market,\n    refreshRef,\n    isSwapLoading,\n    toPro,\n    isMarketInit,\n    isMobile,\n    setToastOpen,\n    showAlert,\n    pageTradeLite,\n    // setShowWhich,\n    // setConfirmed,\n    handleClose: () => {\n      setShowWhich((state) => ({ ...state, isShow: false }))\n      setConfirmed([false, false])\n      setIsSwapLoading(false)\n    },\n    handleConfirm: () => {\n      if (showAlert.step == 1 && confirmed[1] == false) {\n        setShowWhich(() => ({ step: 2, showWitch: ShowWitchAle3t1.SmallPrice, isShow: true }))\n      } else {\n        setShowWhich((state) => ({ ...state, isShow: false }))\n      }\n      setConfirmed((state) => {\n        state[showAlert.step - 1] = true\n        return state\n      })\n    },\n    priceLevel: getPriceImpactInfo(pageTradeLite.calcTradeParams, account.readyState),\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/index.ts",
    "content": "export * from './useCheckAccStatus'\nexport * from './useAccountModal'\nexport * from './useActiveAccount'\nexport * from './useDeposit'\nexport * from './useExportAccount'\nexport * from './useNFTDeploy'\nexport * from './useNFTDeposit'\nexport * from './useNFTTransfer'\nexport * from './useNFTWithdraw'\nexport * from './useReset'\nexport * from './useTransfer'\nexport * from './useUpdateAccount'\nexport * from './useVendor'\nexport * from './useWithdraw'\nexport * from './useForceWithdraw'\nexport * from './useDefiTrade'\nexport * from './useCollectionAdvanceMeta'\nexport * from './useNFTMintAdvance'\nexport * from './useDualTrade'\nexport * from './useEditCollection'\nexport * from './useRampConfirm'\nexport * from './useBanxaConfirm'\nexport * from './useCreateRedPacket'\nexport * from './useRedpacket'\nexport * from './useStakeTrade'\nexport * from './useStakeTradeExit'\nexport * from './useBtrade'\nexport * from './hookSwap'\nexport * from './useDualEdit'\nexport * from './useContactAdd'\nexport * from './useContact'\nexport * from './useStakingAprTrend'\nexport * from './useNFTBurn'\nexport * from './vault'\nexport * from './useContactAdd'\nexport * from './useContact'\nexport {useTransferToTaikoAccount} from './useTransferToTaikoAccount'\nexport { useTaikoLock } from './useTaikoLock'\nexport { useCoinbaseWalletPassword } from './useCoinbaseWalletPassword'\n\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/useAccountModal.ts",
    "content": "import { store, useAccount } from '../../index'\nimport { AccountStep, useOpenModals } from '@loopring-web/component-lib'\nimport React from 'react'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { sleep, WalletType } from '@loopring-web/loopring-sdk'\nimport { useAccountHook } from '../../services/account/useAccountHook'\nimport { SUBMIT_PANEL_DOUBLE_QUICK_AUTO_CLOSE } from '@loopring-web/common-resources'\n\nexport function useAccountModal() {\n  const { shouldShow, setShouldShow, statusUnset: statusAccountUnset } = useAccount()\n  const { setShowAccount } = useOpenModals()\n  const handleErrorAccount = React.useCallback(() => {\n    statusAccountUnset()\n  }, [statusAccountUnset])\n  const handleLockAccount = React.useCallback(() => {\n    statusAccountUnset()\n  }, [setShowAccount, shouldShow, statusAccountUnset])\n  const handleNoAccount = React.useCallback(\n    (_data: any) => {\n      statusAccountUnset()\n      setShowAccount({\n        isShow: shouldShow ?? false,\n        step: AccountStep.NoAccount,\n      })\n    },\n    [setShowAccount, shouldShow, statusAccountUnset],\n  )\n  const handleDepositingAccount = React.useCallback(async () => {\n    setShowAccount({\n      isShow: shouldShow ?? false,\n      step: AccountStep.Deposit_Submit,\n    })\n    await sleep(3000)\n    setShouldShow(false)\n    setShowAccount({ isShow: false })\n    statusAccountUnset()\n  }, [setShouldShow, setShowAccount, shouldShow, statusAccountUnset])\n  const handleErrorApproveToken = React.useCallback(() => {\n    setShowAccount({\n      isShow: shouldShow ?? false,\n      step: AccountStep.Deposit_WaitForAuth,\n    })\n  }, [setShowAccount, shouldShow])\n  const handleErrorDepositSign = React.useCallback(() => {\n    setShowAccount({\n      isShow: shouldShow ?? false,\n      step: AccountStep.Deposit_Failed,\n    })\n  }, [setShowAccount, shouldShow])\n  const handleProcessDeposit = React.useCallback(() => {\n    setShowAccount({\n      isShow: shouldShow ?? false,\n      step: AccountStep.Deposit_Approve_WaitForAuth,\n    })\n  }, [setShowAccount, shouldShow])\n  const handleSignAccount = React.useCallback(() => {\n    statusAccountUnset()\n    setShowAccount({\n      isShow: shouldShow ?? false,\n      step: AccountStep.UpdateAccount,\n    })\n  }, [setShowAccount, shouldShow, statusAccountUnset])\n  const handleSignDeniedByUser = React.useCallback(() => {\n    setShowAccount({\n      isShow: shouldShow ?? false,\n      step: AccountStep.UnlockAccount_User_Denied,\n    })\n  }, [setShowAccount, shouldShow])\n  const handleSignError = React.useCallback(\n    ({ error, walletType }: { error?: sdk.RESULT_INFO; walletType?: WalletType }) => {\n      setShowAccount({\n        isShow: shouldShow ?? false,\n        step: AccountStep.UnlockAccount_Failed,\n        error,\n        info: { walletType },\n      })\n    },\n    [setShowAccount, shouldShow],\n  )\n  const handleProcessSign = React.useCallback(() => {\n    setShowAccount({\n      isShow: shouldShow ?? false,\n      step: AccountStep.UnlockAccount_WaitForAuth,\n    })\n  }, [setShowAccount, shouldShow])\n  const handleAccountActive = React.useCallback(async () => {\n    setShouldShow(false)\n    statusAccountUnset()\n    await sdk.sleep(SUBMIT_PANEL_DOUBLE_QUICK_AUTO_CLOSE)\n    if (store.getState().modals.isShowAccount.isShow) {\n      setShowAccount({ isShow: false })\n    }\n  }, [setShouldShow, setShowAccount, statusAccountUnset])\n  useAccountHook({\n    handleErrorAccount,\n    handleLockAccount, // clear private data\n    handleNoAccount, //\n    handleDepositingAccount,\n    handleErrorApproveToken,\n    handleErrorDepositSign,\n    handleProcessDeposit, // two or one step\n    handleSignAccount, //unlock or update account  sgin\n    handleProcessSign,\n    handleSignError,\n    handleSignDeniedByUser,\n    // handleProcessAccountCheck,\n    handleAccountActive,\n  })\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/useActiveAccount.ts",
    "content": "import { AccountStep, ResetProps, useOpenModals } from '@loopring-web/component-lib'\n\nimport {\n  useBtnStatus,\n  useUpdateAccount,\n  useChargeFees,\n  useModalData,\n  makeWalletLayer2,\n  useWalletLayer2,\n  store,\n} from '../../index'\nimport { updateActiveAccountData as updateActiveAccountDataRedux } from '@loopring-web/core'\n\nimport { LIVE_FEE_TIMES, myLog, SagaStatus, WalletMap } from '@loopring-web/common-resources'\nimport React from 'react'\n\nexport const useActiveAccount = <T>(): {\n  activeAccountProps: ResetProps<T>\n  activeAccountCheckFeeIsEnough: (props?: { isRequiredAPI: true; intervalTime?: number }) => void\n} => {\n  const { btnStatus, enableBtn, disableBtn } = useBtnStatus()\n  const {\n    setShowActiveAccount,\n    setShowAccount,\n    modals: {\n      isShowActiveAccount: { isShow, info },\n    },\n  } = useOpenModals()\n  const { status: walletLayer2Status } = useWalletLayer2()\n  const [walletMap, setWalletMap] = React.useState(\n    makeWalletLayer2({ needFilterZero: true, isActive: true }).walletMap ?? ({} as WalletMap<any>),\n  )\n  const { goUpdateAccount } = useUpdateAccount()\n  const { activeAccountValue } = useModalData()\n  const {\n    chargeFeeTokenList,\n    isFeeNotEnough,\n    handleFeeChange,\n    checkFeeIsEnough,\n    resetIntervalTime,\n  } = useChargeFees({\n    isActiveAccount: true,\n    requestType: 'UPDATE_ACCOUNT_BY_NEW' as any,\n    updateData: ({ fee, chargeFeeTokenList, isFeeNotEnough }) => {\n      const { activeAccountValue } = store.getState()._router_modalData\n      // const { tags } = store.getState().account;\n      myLog('activeAccountValue feeInfo', fee, isFeeNotEnough)\n\n      store.dispatch(\n        updateActiveAccountDataRedux({\n          ...activeAccountValue,\n          fee,\n          isFeeNotEnough,\n          chargeFeeList:\n            chargeFeeTokenList && chargeFeeTokenList.length\n              ? chargeFeeTokenList\n              : activeAccountValue?.chargeFeeList && activeAccountValue?.chargeFeeList.length\n              ? activeAccountValue?.chargeFeeList\n              : [],\n        }),\n      )\n    },\n  })\n  const walletLayer2Callback = React.useCallback(() => {\n    const walletMap = makeWalletLayer2({ needFilterZero: true, isActive: true }).walletMap ?? {}\n    setWalletMap(walletMap)\n    checkFeeIsEnough()\n  }, [])\n  React.useEffect(() => {\n    if (walletLayer2Callback && walletLayer2Status === SagaStatus.UNSET) {\n      walletLayer2Callback()\n    }\n  }, [walletLayer2Status])\n  React.useEffect(() => {\n    if (isFeeNotEnough.isFeeNotEnough) {\n      disableBtn()\n    } else {\n      enableBtn()\n    }\n  }, [isFeeNotEnough.isFeeNotEnough])\n  React.useEffect(() => {\n    if (isShow) {\n      checkFeeIsEnough({ isRequiredAPI: true, intervalTime: LIVE_FEE_TIMES })\n    } else {\n      resetIntervalTime()\n    }\n    return () => {\n      resetIntervalTime()\n    }\n  }, [isShow])\n\n  const activeAccountProps: ResetProps<any> = {\n    onResetClick: ({\n      isNotFirstTime = false,\n      isReset = false,\n    }: {\n      isNotFirstTime?: boolean\n      isReset?: boolean\n    }) => {\n      if (activeAccountValue?.fee?.belong && activeAccountValue?.fee?.__raw__) {\n        setShowActiveAccount({ isShow: false })\n        goUpdateAccount({\n          isFirstTime: !isNotFirstTime,\n          isReset,\n          feeInfo: activeAccountValue.fee,\n        })\n      }\n    },\n    isReset: info?.isReset,\n    isNewAccount: true,\n    resetBtnStatus: btnStatus,\n    goToDeposit: () => {\n      setShowActiveAccount({ isShow: false })\n      setShowAccount({ isShow: true, step: AccountStep.AddAssetGateway })\n      // setShowDeposit({ isShow: true });\n    },\n    walletMap,\n    chargeFeeTokenList,\n    isFeeNotEnough,\n    handleFeeChange,\n    feeInfo: activeAccountValue.fee,\n  }\n\n  return {\n    activeAccountProps,\n    activeAccountCheckFeeIsEnough: checkFeeIsEnough,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/useBanxaConfirm.ts",
    "content": "import {\n  AccountStatus,\n  AddressError,\n  BANXA_URLS,\n  BanxaOrder,\n  CoinMap,\n  CustomErrorWithCode,\n  Explorer,\n  FeeInfo,\n  IBData,\n  myLog,\n  SDK_ERROR_MAP_TO_UI,\n  TOAST_TIME,\n  TRADE_TYPE,\n  UIERROR_CODE,\n  WALLET_TYPE,\n  WalletMap,\n} from '@loopring-web/common-resources'\nimport { NETWORKEXTEND, store, useAccount, useModalData, useSystem, useTokenMap } from '../../stores'\nimport { AccountStep, useOpenModals } from '@loopring-web/component-lib'\nimport React from 'react'\nimport { makeWalletLayer2 } from '../help'\nimport {\n  OffFaitCommon,\n  offFaitService,\n  useChargeFees,\n  useWalletLayer2Socket,\n  walletLayer2Service,\n} from '../../services'\nimport { useBtnStatus } from '../common'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { LoopringAPI } from '../../api_wrapper'\nimport { ConnectProviders, connectProvides } from '@loopring-web/web3-provider'\nimport { getTimestampDaysLater } from '../../utils'\nimport { DAYS } from '../../defs'\nimport { RAMP_SELL_PANEL } from './useVendor'\nimport { BalanceReason, banxaApiCall, BanxaCheck, banxaService } from '../../services'\nimport { ChainId } from '@loopring-web/loopring-sdk'\nimport _ from 'lodash'\nimport { useWalletInfo } from '../../stores/localStore/walletInfo'\nimport Web3 from 'web3'\nimport { isAccActivated } from './useCheckAccStatus'\nimport { useRouteMatch } from 'react-router-dom'\nimport { useLocation } from 'react-use'\nimport { merge } from 'rxjs'\nimport { useTranslation } from 'react-i18next'\n\nexport const useBanxaConfirm = <T extends IBData<I>, I, _C extends FeeInfo>({\n  setSellPanel,\n}: {\n  sellPanel: RAMP_SELL_PANEL\n  setSellPanel: (value: RAMP_SELL_PANEL) => void\n}) => {\n  const { t } = useTranslation()\n  const match: any = useRouteMatch('/trade/fiat/:tab?')\n  const { href } = useLocation()\n  const search = href?.split('?')[1] ?? ''\n  const searchParams = new URLSearchParams(search)\n  const subject = React.useMemo(() => merge(banxaService.onSocket(), offFaitService.onSocket()), [])\n\n  const nodeTimer = React.useRef<NodeJS.Timeout | -1>(-1)\n\n  const { exchangeInfo, chainId } = useSystem()\n\n  const {\n    allowTrade: { raw_data },\n  } = useSystem()\n  const legalEnable = (raw_data as any)?.legal?.enable\n  const { tokenMap, totalCoinMap } = useTokenMap()\n  const {\n    setShowAccount,\n    modals: {\n      isShowAccount: { info },\n    },\n  } = useOpenModals()\n  const { account } = useAccount()\n  const [balanceNotEnough, setBalanceNotEnough] = React.useState<{\n    isEnough: boolean\n    reason?: BalanceReason\n  }>({ isEnough: false })\n  const { offBanxaValue, updateOffBanxaData } = useModalData()\n  const {\n    processRequestBanxaTransfer: processRequest,\n    chargeFeeTokenList,\n    isFeeNotEnough,\n    handleFeeChange,\n    feeInfo,\n    checkFeeIsEnough,\n  } = useBanxaTransPost()\n  const [walletMap, setWalletMap] = React.useState(\n    makeWalletLayer2({ needFilterZero: true }).walletMap ?? ({} as WalletMap<T>),\n  )\n  const walletLayer2Callback = React.useCallback(() => {\n    const walletMap = makeWalletLayer2({ needFilterZero: true }).walletMap ?? {}\n    setWalletMap(walletMap)\n  }, [])\n\n  useWalletLayer2Socket({ walletLayer2Callback })\n\n  const { btnStatus, enableBtn, disableBtn } = useBtnStatus()\n  const { transferBanxaValue, updateTransferBanxaData } = useModalData()\n\n  React.useEffect(() => {\n    if (\n      info?.transferBanxa === AccountStep.Transfer_BANXA_Failed &&\n      info?.trigger == 'checkFeeIsEnough'\n    ) {\n      checkFeeIsEnough()\n    }\n  }, [info?.transferBanxa])\n  const restTransfer = React.useCallback(() => {\n    const {\n      _router_modalData: { offBanxaValue },\n    } = store.getState()\n    if (offBanxaValue && offBanxaValue.id && offBanxaValue.status === 'waitingPayment') {\n      const memo = `banxa-off:${offBanxaValue.id}`\n      const walletMap = makeWalletLayer2({ needFilterZero: true })?.walletMap ?? {}\n      setShowAccount({ isShow: false })\n      checkFeeIsEnough({ isRequiredAPI: true })\n\n      updateTransferBanxaData({\n        belong: offBanxaValue.coin_code,\n        tradeValue: offBanxaValue.coin_amount,\n        balance: walletMap[offBanxaValue?.coin_code ?? '']?.count,\n        address: offBanxaValue.wallet_address ?? '',\n        memo,\n        // fee: feeInfo,//transferBanxaValue.fee,\n      })\n      setSellPanel(RAMP_SELL_PANEL.BANXA_CONFIRM)\n    } else {\n      setSellPanel(RAMP_SELL_PANEL.LIST)\n    }\n  }, [offBanxaValue])\n\n  const checkBtnStatus = React.useCallback(() => {\n    const transferBanxaValue = store.getState()._router_modalData.transferBanxaValue\n    const walletMap = makeWalletLayer2({ needFilterZero: true }).walletMap ?? {}\n    if (\n      tokenMap &&\n      chargeFeeTokenList.length &&\n      isFeeNotEnough &&\n      !isFeeNotEnough.isFeeNotEnough &&\n      transferBanxaValue.belong &&\n      tokenMap[transferBanxaValue.belong] &&\n      transferBanxaValue.fee &&\n      transferBanxaValue.fee.belong &&\n      transferBanxaValue.address\n    ) {\n      const sellToken = tokenMap[transferBanxaValue.belong]\n      const feeToken = tokenMap[transferBanxaValue.fee.belong]\n      const feeRaw = transferBanxaValue.fee.feeRaw ?? transferBanxaValue.fee.__raw__?.feeRaw ?? 0\n      const fee = sdk.toBig(feeRaw)\n\n      const balance = sdk\n        .toBig(walletMap[transferBanxaValue.belong]?.count ?? 0)\n        .times('1e' + sellToken.decimals)\n      myLog('transferBanxaValue balance', balance)\n\n      const tradeValue = sdk\n        .toBig(transferBanxaValue.tradeValue ?? 0)\n        .times('1e' + sellToken.decimals)\n      const isExceedBalance = tradeValue\n        .plus(feeToken.tokenId === sellToken.tokenId ? fee : '0')\n        .gt(balance)\n      myLog('isExceedBalance', isExceedBalance, fee.toString(), tradeValue.toString())\n      if (tradeValue && !isExceedBalance) {\n        enableBtn()\n        return\n      } else {\n        disableBtn()\n        if (isExceedBalance && feeToken.tokenId === sellToken.tokenId) {\n          setBalanceNotEnough({\n            isEnough: true,\n            reason: BalanceReason.FeeAndBalance,\n          })\n        } else if (isExceedBalance) {\n          setBalanceNotEnough({\n            isEnough: true,\n            reason: BalanceReason.Balance,\n          })\n        }\n      }\n    }\n    disableBtn()\n  }, [\n    chargeFeeTokenList.length,\n    disableBtn,\n    enableBtn,\n    isFeeNotEnough.isFeeNotEnough,\n    tokenMap,\n    transferBanxaValue.address,\n    transferBanxaValue.balance,\n    transferBanxaValue.belong,\n    transferBanxaValue.fee?.feeRaw,\n    transferBanxaValue.tradeValue,\n  ])\n\n  React.useEffect(() => {\n    const offBanxaValue = store.getState()._router_modalData.offBanxaValue\n    if (\n      match?.params?.tab?.toLowerCase() === 'sell'.toLowerCase() &&\n      searchParams.get('orderId') &&\n      searchParams.get('orderId')?.toLowerCase() == offBanxaValue?.id?.toLowerCase()\n    ) {\n      restTransfer()\n    }\n  }, [match.params?.tab, offBanxaValue?.id, searchParams.get('orderId')])\n\n  React.useEffect(() => {\n    checkBtnStatus()\n  }, [chargeFeeTokenList, feeInfo?.belong, isFeeNotEnough?.isFeeNotEnough, transferBanxaValue])\n\n  const onTransferClick = React.useCallback(\n    async (isFirstTime: boolean = true) => {\n      const { transferBanxaValue, offBanxaValue } = store.getState()._router_modalData\n\n      const { accountId, accAddress, readyState, apiKey, eddsaKey } = account\n      if (\n        readyState === AccountStatus.ACTIVATED &&\n        tokenMap &&\n        LoopringAPI.userAPI &&\n        exchangeInfo &&\n        connectProvides.usedWeb3 &&\n        transferBanxaValue.address !== '*' &&\n        transferBanxaValue.address &&\n        transferBanxaValue?.fee &&\n        offBanxaValue &&\n        offBanxaValue.id &&\n        offBanxaValue.wallet_address?.toLowerCase() === transferBanxaValue.address.toLowerCase() &&\n        transferBanxaValue?.fee.belong &&\n        eddsaKey?.sk\n      ) {\n        try {\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.Transfer_BANXA_WaitForAuth,\n          })\n\n          const sellToken = tokenMap[transferBanxaValue.belong as string]\n          const feeToken = tokenMap[transferBanxaValue.fee.belong]\n          const feeRaw =\n            transferBanxaValue.fee.feeRaw ?? transferBanxaValue.fee.__raw__?.feeRaw ?? 0\n          const fee = sdk.toBig(feeRaw)\n\n          const tradeValue = sdk\n            .toBig(transferBanxaValue.tradeValue ?? 0)\n            .times('1e' + sellToken.decimals)\n          const finalVol = tradeValue\n          const transferVol = finalVol.toFixed(0, 0)\n\n          const [storageId, { data }] = await Promise.all([\n            LoopringAPI.userAPI?.getNextStorageId(\n              {\n                accountId,\n                sellTokenId: sellToken.tokenId,\n              },\n              apiKey,\n            ),\n            banxaApiCall({\n              chainId: chainId as ChainId,\n              method: sdk.ReqMethod.GET,\n              url: `/api/orders/${offBanxaValue.id}`,\n              query: '',\n              payload: {},\n              account,\n            }),\n          ])\n          if (data?.order?.status !== 'waitingPayment' || !data?.order?.wallet_address) {\n            offFaitService.banxaCheckStatus({\n              data: data?.order,\n            })\n\n            throw new CustomErrorWithCode({\n              ...SDK_ERROR_MAP_TO_UI[UIERROR_CODE.ERROR_OFF_RAMP_EXPIRED],\n              code: UIERROR_CODE.ERROR_OFF_RAMP_EXPIRED,\n              message: 'Banxa Expired',\n            })\n            // throw new CustomError(ErrorMap.ERROR_OFF_RAMP_EXPIRED);\n          }\n          const req: sdk.OriginTransferRequestV3 = {\n            exchange: exchangeInfo.exchangeAddress,\n            payerAddr: accAddress,\n            payerId: accountId,\n            payeeAddr: transferBanxaValue.address,\n            payeeId: 0,\n            storageId: storageId?.offchainId,\n            token: {\n              tokenId: sellToken.tokenId,\n              volume: transferVol,\n            },\n            maxFee: {\n              tokenId: feeToken.tokenId,\n              volume: fee.toString(), // TEST: fee.toString(),\n            },\n            validUntil: getTimestampDaysLater(DAYS),\n            memo: transferBanxaValue.memo,\n          }\n\n          myLog('transfer req:', req)\n\n          processRequest(req, isFirstTime)\n        } catch (e: any) {\n          if (e?.code === UIERROR_CODE.ERROR_OFF_RAMP_EXPIRED) {\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.Transfer_BANXA_Failed,\n              error: {\n                code: UIERROR_CODE.UNKNOWN,\n                message: t(\n                  e.code && e.messageKey\n                    ? e.messageKey\n                    : SDK_ERROR_MAP_TO_UI[UIERROR_CODE.UNKNOWN].messageKey,\n                  { ns: 'error' },\n                ),\n              } as sdk.RESULT_INFO,\n            })\n          } else {\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.Transfer_BANXA_Failed,\n              error: {\n                code: UIERROR_CODE.UNKNOWN,\n                message: e.message,\n              } as sdk.RESULT_INFO,\n            })\n          }\n          // transfer failed\n        }\n      } else {\n        return\n      }\n    },\n    [account, tokenMap, exchangeInfo, setShowAccount, processRequest],\n  )\n\n  const checkOrderStatus = _.debounce(async (_order: BanxaOrder) => {\n    if (nodeTimer.current) {\n      clearTimeout(nodeTimer.current as NodeJS.Timeout)\n    }\n    //@ts-ignore\n    _order = {\n      ..._order,\n      // id: \"54737597f1ae4daffd9ed5891cfa68dc\",\n    }\n    myLog('banxa check Order ', _order.id)\n    try {\n      const {\n        data: { order },\n      } = await banxaApiCall({\n        chainId: chainId as ChainId,\n        method: sdk.ReqMethod.GET,\n        url: `/api/orders/${_order.id}`,\n        query: '',\n        payload: {},\n        account,\n      })\n      myLog('banxa check Order ', order)\n\n      if (order.status === 'waitingPayment' && order.wallet_address && order.coin_code) {\n        updateOffBanxaData({ order })\n        banxaService.KYCDone()\n        console.log('BANXA KYC Done BANXA order Info:', order)\n      } else {\n        setTimeout(() => {\n          checkOrderStatus(order)\n        }, 1000 * 15)\n      }\n    } catch (e) {\n      if (_order && _order.id && _order.status && _order.status === 'pendingPayment') {\n        setTimeout(() => {\n          checkOrderStatus(_order)\n        }, 1000 * 15)\n      }\n    }\n  }, 100)\n\n  React.useEffect(() => {\n    const subscription = subject.subscribe((props) => {\n      myLog('Banxa subscription ', props)\n      switch (props.status) {\n        case OffFaitCommon.OffFaitCancel:\n          setSellPanel(RAMP_SELL_PANEL.LIST)\n          clearTimeout(nodeTimer.current as NodeJS.Timeout)\n          break\n        case BanxaCheck.CheckOrderStatus:\n          myLog('Banxa checkOrderStatus')\n          // @ts-ignore\n          checkOrderStatus(props.data.order)\n          break\n        case BanxaCheck.OrderHide:\n          myLog('Banxa Order OrderHide')\n          clearTimeout(nodeTimer.current as NodeJS.Timeout)\n          break\n        case BanxaCheck.OrderEnd:\n          clearTimeout(nodeTimer.current as NodeJS.Timeout)\n          setSellPanel(RAMP_SELL_PANEL.LIST)\n          break\n        case BanxaCheck.OrderShow:\n          if (props.data?.reason == 'transferDone') {\n            const {\n              _router_modalData: { offBanxaValue },\n            } = store.getState()\n            setSellPanel(RAMP_SELL_PANEL.LIST)\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.Transfer_BANXA_Confirm,\n              info: {\n                orderId: offBanxaValue?.id,\n                hash: `${BANXA_URLS[chainId]}/status/${offBanxaValue?.id}`,\n              },\n            })\n          }\n          break\n        default:\n          break\n      }\n    })\n    return () => {\n      clearTimeout(nodeTimer.current as NodeJS.Timeout)\n      subscription.unsubscribe()\n    }\n  }, [subject])\n\n  React.useEffect(() => {\n    if (\n      info?.transferBanxa === AccountStep.Transfer_BANXA_Failed &&\n      info?.trigger == 'checkFeeIsEnough'\n    ) {\n      checkFeeIsEnough()\n    }\n  }, [info?.transferBanxa])\n\n  const banxaViewProps = React.useMemo(() => {\n    const { address, memo, fee, __request__, ...tradeData } = transferBanxaValue\n\n    return {\n      type: TRADE_TYPE.TOKEN,\n      disabled: !(legalEnable === true),\n      addressDefault: address,\n      realAddr: address,\n      tradeData,\n      coinMap: totalCoinMap as CoinMap<T>,\n      transferBtnStatus: btnStatus,\n      isLoopringAddress: true,\n      isSameAddress: false,\n      isAddressCheckLoading: WALLET_TYPE.Loopring,\n      feeInfo,\n      handleFeeChange,\n      balanceNotEnough,\n      chargeFeeTokenList,\n      isFeeNotEnough,\n      handleSureItsLayer2: () => undefined,\n      sureItsLayer2: true,\n      onTransferClick,\n      handlePanelEvent: () => undefined,\n      addrStatus: AddressError.NoError,\n      memo,\n      walletMap,\n      handleOnMemoChange: () => undefined,\n      handleOnAddressChange: () => undefined,\n    } as any\n  }, [\n    balanceNotEnough,\n    btnStatus,\n    chargeFeeTokenList,\n    feeInfo,\n    handleFeeChange,\n    isFeeNotEnough,\n    legalEnable,\n    onTransferClick,\n    totalCoinMap,\n    transferBanxaValue,\n    walletMap,\n  ])\n\n  return { banxaViewProps, offBanxaValue }\n}\n\nexport const useBanxaTransPost = () => {\n  const { account } = useAccount()\n  const { chainId } = useSystem()\n  const { checkHWAddr, updateHW } = useWalletInfo()\n  const { setShowAccount } = useOpenModals()\n  const { offBanxaValue, updateTransferBanxaData } = useModalData()\n  const {\n    chargeFeeTokenList,\n    isFeeNotEnough,\n    handleFeeChange,\n    feeInfo,\n    checkFeeIsEnough,\n    // setIsFeeNotEnough,\n  } = useChargeFees({\n    requestType: sdk.OffchainFeeReqType.TRANSFER,\n    updateData: ({ fee }) => {\n      myLog('transferBanxaValue updateData', fee)\n      const { transferBanxaValue } = store.getState()._router_modalData\n      updateTransferBanxaData({ ...transferBanxaValue, fee })\n    },\n  })\n  const processRequestBanxaTransfer = React.useCallback(\n    async (request: sdk.OriginTransferRequestV3, isNotHardwareWallet: boolean) => {\n      const { apiKey, connectName, eddsaKey } = account\n      let response\n      try {\n        if (connectProvides.usedWeb3 && LoopringAPI.userAPI && isAccActivated()) {\n          let isHWAddr = checkHWAddr(account.accAddress)\n          if (!isHWAddr && !isNotHardwareWallet) {\n            isHWAddr = true\n          }\n\n          updateTransferBanxaData({ __request__: request })\n\n          response = await LoopringAPI.userAPI.submitInternalTransfer(\n            {\n              request: _.cloneDeep(request),\n              web3: connectProvides.usedWeb3 as any,\n              chainId: chainId === NETWORKEXTEND.NONETWORK ? sdk.ChainId.MAINNET : chainId,\n              walletType: (ConnectProviders[connectName] ??\n                connectName) as unknown as sdk.ConnectorNames,\n              eddsaKey: eddsaKey.sk,\n              apiKey,\n              isHWAddr,\n            },\n            {\n              accountId: account.accountId,\n              counterFactualInfo: eddsaKey.counterFactualInfo,\n            },\n          )\n\n          // myLog(\"Banxa submitInternalTransfer:\", response);\n\n          if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n            throw response\n          }\n          // setIsConfirmTransfer(false);\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.Transfer_BANXA_In_Progress,\n          })\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.Transfer_BANXA_Success,\n            info: {\n              hash: Explorer + `tx/${(response as sdk.TX_HASH_API)?.hash}-transfer`,\n            },\n          })\n          banxaService.TransferDone({ order: offBanxaValue as any })\n          walletLayer2Service.sendUserUpdate()\n\n          if (isHWAddr) {\n            myLog('Banxa ......try to set isHWAddr', isHWAddr)\n            updateHW({ wallet: account.accAddress, isHWAddr })\n          }\n          await sdk.sleep(TOAST_TIME)\n        }\n      } catch (e: any) {\n        const code = sdk.checkErrorInfo(e, isNotHardwareWallet)\n        switch (code) {\n          case sdk.ConnectorError.NOT_SUPPORT_ERROR:\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.Transfer_BANXA_First_Method_Denied,\n            })\n            break\n          case sdk.ConnectorError.USER_DENIED:\n          case sdk.ConnectorError.USER_DENIED_2:\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.Transfer_BANXA_User_Denied,\n            })\n            break\n          default:\n            if ([102024, 102025, 114001, 114002].includes((e as sdk.RESULT_INFO)?.code || 0)) {\n              checkFeeIsEnough({ isRequiredAPI: true })\n            }\n            myLog('Transfer BANXA error', e)\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.Transfer_BANXA_Failed,\n              error: {\n                code: UIERROR_CODE.UNKNOWN,\n                msg: e?.message,\n                ...(e instanceof Error\n                  ? {\n                      message: e?.message,\n                      stack: e?.stack,\n                    }\n                  : e ?? {}),\n              },\n            })\n\n            break\n        }\n      }\n      try {\n        if (\n          response &&\n          offBanxaValue &&\n          (response as sdk.TX_HASH_API)?.hash &&\n          offBanxaValue.wallet_address\n        ) {\n          banxaApiCall({\n            chainId: chainId as ChainId,\n            account,\n            method: sdk.ReqMethod.POST,\n            url: `/api/orders/${offBanxaValue.id}/confirm`,\n            query: '',\n            payload: {\n              tx_hash: (response as sdk.TX_HASH_API)?.hash,\n              source_address: account.accAddress,\n              destination_address: offBanxaValue.wallet_address,\n            },\n          })\n        }\n      } catch (error) {\n        console.error('Banxa confirm error', error)\n      }\n    },\n    [\n      account,\n      chainId,\n      checkHWAddr,\n      setShowAccount,\n      updateHW,\n      offBanxaValue,\n      updateTransferBanxaData,\n    ],\n  )\n  return {\n    processRequestBanxaTransfer,\n    chargeFeeTokenList,\n    isFeeNotEnough,\n    // setIsFeeNotEnough,\n    handleFeeChange,\n    feeInfo,\n    checkFeeIsEnough,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/useBtrade.ts",
    "content": "import * as sdk from '@loopring-web/loopring-sdk'\nimport React from 'react'\nimport {\n  DAYS,\n  dexSwapDependAsync,\n  getTimestampDaysLater,\n  LoopringAPI,\n  makeWalletLayer2,\n  MAPFEEBIPS,\n  marketInitCheck,\n  reCalcStoB,\n  store,\n  useAccount,\n  useBtradeMap,\n  usePairMatch,\n  useSocket,\n  useSubmitBtn,\n  useSystem,\n  useToast,\n  useTokenMap,\n  useTokenPrices,\n  useWalletLayer2,\n  useWalletLayer2Socket,\n  walletLayer2Service,\n} from '@loopring-web/core'\n\nimport {\n  AccountStatus,\n  BtradeTradeCalcData,\n  BtradeType,\n  CoinMap,\n  CustomErrorWithCode,\n  defaultBlockTradeSlipage,\n  EmptyValueTag,\n  getValuePrecisionThousand,\n  IBData,\n  MarketType,\n  myLog,\n  SagaStatus,\n  SDK_ERROR_MAP_TO_UI,\n  SUBMIT_PANEL_AUTO_CLOSE,\n  SUBMIT_PANEL_DOUBLE_QUICK_AUTO_CLOSE,\n  TradeBtnStatus,\n  UIERROR_CODE,\n  WalletMap,\n  RouterPath,\n  globalSetup,\n} from '@loopring-web/common-resources'\nimport {\n  AccountStep,\n  SwapData,\n  SwapTradeData,\n  SwapType,\n  ToastType,\n  useOpenModals,\n  useSettings,\n  useToggle,\n} from '@loopring-web/component-lib'\nimport { useTranslation } from 'react-i18next'\nimport { useHistory } from 'react-router-dom'\n\nimport { useTradeBtrade } from '../../stores/router/tradeBtrade'\nimport BigNumber from 'bignumber.js'\nimport { merge } from 'rxjs'\nimport { btradeOrderbookService } from '../../services'\nimport _ from 'lodash'\n\nconst useBtradeSocket = ({}: { updateAPICall: () => void }) => {\n  const { sendSocketTopic, socketEnd } = useSocket()\n  const { tradeBtrade, updateTradeBtrade } = useTradeBtrade()\n  const { marketMap } = useBtradeMap()\n\n  const subjectBtradeOrderbook = React.useMemo(() => btradeOrderbookService.onSocket(), [])\n  React.useEffect(() => {\n    if (tradeBtrade?.depth?.symbol) {\n      sendSocketTopic({\n        [sdk.WsTopicType.btradedepth]: {\n          showOverlap: false,\n          markets: [tradeBtrade?.depth?.symbol],\n          level: 0,\n          count: 50,\n          snapshot: false,\n        },\n      })\n    } else {\n      socketEnd()\n    }\n    return () => {\n      socketEnd()\n    }\n  }, [\n    // account.readyState,\n    tradeBtrade?.depth?.symbol,\n  ])\n  React.useEffect(() => {\n    const { tradeBtrade } = store.getState()._router_tradeBtrade\n    const subscription = merge(subjectBtradeOrderbook).subscribe(({ btradeOrderbookMap }) => {\n      // const { market } = store.getState()._router_tradeBtrade.tradeBtrade\n      const item = marketMap[tradeBtrade.market]\n      if (btradeOrderbookMap && item.btradeMarket && btradeOrderbookMap[item?.btradeMarket]) {\n        updateTradeBtrade({\n          // @ts-ignore\n          market: item.market,\n          depth: btradeOrderbookMap[item?.btradeMarket],\n          ...item,\n        })\n        myLog('useBtradeSwap: depth', btradeOrderbookMap[item?.btradeMarket])\n        // debonceCall()\n      }\n    })\n    return () => subscription.unsubscribe()\n  }, [tradeBtrade.market])\n}\n\nexport const useBtradeSwap = <\n  T extends SwapTradeData<IBData<C>>,\n  C extends { [key: string]: any },\n  CAD extends BtradeTradeCalcData<C>,\n>({\n  path,\n}: {\n  path: string\n}) => {\n  const { marketCoins, marketArray, marketMap, tradeMap, getBtradeMap } = useBtradeMap()\n  //High: No not Move!!!!!!\n  const { realMarket } = usePairMatch({\n    path,\n    coinA: 'ETH',\n    coinB: 'USDC',\n    marketArray,\n    tokenMap: tradeMap,\n  })\n  const { t } = useTranslation(['common', 'error'])\n  const history = useHistory()\n  const refreshRef = React.createRef()\n  const { toastOpen, setToastOpen, closeToast } = useToast()\n  const { isMobile } = useSettings()\n  const { setShowSupport, setShowTradeIsFrozen, setShowAccount } = useOpenModals()\n  const { account } = useAccount()\n  const {\n    toggle: { BTradeInvest },\n  } = useToggle()\n  /** loaded from loading **/\n  const { exchangeInfo, allowTrade } = useSystem()\n  const { coinMap, tokenMap } = useTokenMap()\n  /** init Ticker ready from ui-backend load**/\n  /** get store value **/\n  /** after unlock **/\n  const { status: walletLayer2Status } = useWalletLayer2()\n  const [tradeData, setTradeData] = React.useState<T | undefined>(undefined)\n  const [tradeCalcData, setTradeCalcData] = React.useState<Partial<CAD>>({\n    isBtrade: true,\n    lockedNotification: true,\n    coinInfoMap: marketCoins?.reduce((prev: any, item: string | number) => {\n      return { ...prev, [item]: coinMap ? coinMap[item] : {} }\n    }, {} as CoinMap<C>),\n  } as any)\n\n  /** redux storage **/\n  const {\n    tradeBtrade,\n    updateTradeBtrade,\n    __SUBMIT_LOCK_TIMER__,\n    __TOAST_AUTO_CLOSE_TIMER__,\n    __DAYS__,\n  } = useTradeBtrade()\n\n  const resetMarket = (_market: MarketType, type: 'sell' | 'buy') => {\n    const { tradePair } = marketInitCheck({\n      market: _market,\n      type,\n      defaultValue: 'ETH-USDC',\n      marketArray,\n      marketMap,\n      tokenMap: tradeMap,\n    })\n    // @ts-ignore\n    const [_, sellToken, buyToken] = (tradePair ?? '').match(/(\\w+)-(\\w+)/i)\n    let { market } = sdk.getExistedMarket(marketArray, sellToken, buyToken)\n    setIsMarketStatus((state) => {\n      return {\n        tradePair,\n        market,\n        isMarketInit: state.market !== market,\n      }\n    })\n    if (coinMap && tokenMap && tradeMap && marketMap && marketArray) {\n      // @ts-ignore\n      const [, coinA, coinB] = tradePair.match(/([\\w,#]+)-([\\w,#]+)/i)\n      let walletMap: WalletMap<any> | undefined\n      if (\n        account.readyState === AccountStatus.ACTIVATED &&\n        walletLayer2Status === SagaStatus.UNSET\n      ) {\n        if (!Object.keys(tradeCalcData?.walletMap ?? {}).length) {\n          walletMap = makeWalletLayer2({ needFilterZero: true }).walletMap as WalletMap<any>\n        }\n        walletMap = tradeCalcData?.walletMap as WalletMap<any>\n      }\n      const tradeDataTmp: any = {\n        sell: {\n          belong: coinA,\n          tradeValue: undefined,\n          balance: walletMap ? walletMap[coinA]?.count : 0,\n        },\n        buy: {\n          belong: coinB,\n          tradeValue: undefined,\n          balance: walletMap ? walletMap[coinB]?.count : 0,\n        },\n      }\n\n      const sellCoinInfoMap = tradeMap[coinB]?.tradePairs?.reduce(\n        (prev: any, item: string | number) => {\n          return { ...prev, [item]: coinMap[item] }\n        },\n        {} as CoinMap<C>,\n      )\n\n      const buyCoinInfoMap = tradeMap[coinA]?.tradePairs?.reduce(\n        (prev: any, item: string | number) => {\n          return { ...prev, [item]: coinMap[item] }\n        },\n        {} as CoinMap<C>,\n      )\n      const btradeType = BtradeType.Quantity\n      let _tradeCalcData = {}\n      setTradeCalcData((state) => {\n        _tradeCalcData = {\n          ...state,\n          walletMap,\n          coinSell: coinA,\n          coinBuy: coinB,\n          sellPrecision: tokenMap[coinA as string]?.precision,\n          buyPrecision: tokenMap[coinB as string]?.precision,\n          sellCoinInfoMap,\n          buyCoinInfoMap,\n          StoB: undefined,\n          BtoS: undefined,\n          fee: undefined,\n          tradeCost: undefined,\n          lockedNotification: true,\n          volumeSell: undefined,\n          volumeBuy: undefined,\n          sellMinAmtStr: undefined,\n          sellMaxL2AmtStr: undefined,\n          sellMaxAmtStr: undefined,\n          totalQuota: undefined,\n          l1Pool: undefined,\n          l2Pool: undefined,\n          btradeType,\n        }\n        return _tradeCalcData\n      })\n      setTradeData((state) => {\n        return {\n          ...state,\n          btradeType,\n          ...tradeDataTmp,\n        }\n      })\n      history.push(`${RouterPath.btrade}/${_market}`)\n      updateTradeBtrade({\n        market,\n        tradePair,\n        btradeType,\n        tradeCalcData: _tradeCalcData,\n      })\n    }\n  }\n  const [{ market, isMarketInit }, setIsMarketStatus] = React.useState<{\n    market: MarketType\n    tradePair?: MarketType\n    isMarketInit?: boolean\n  }>({} as any)\n  React.useEffect(() => {\n    resetMarket(realMarket ?? '#null-#null', 'sell')\n  }, [])\n  React.useEffect(() => {\n    if (marketArray?.[0]) {\n      resetMarket(marketArray[0] as MarketType, 'sell')\n    }\n  }, [marketArray?.[0]])\n  const [isBtradeLoading, setIsBtradeLoading] = React.useState(false)\n\n  const { tokenPrices } = useTokenPrices()\n\n  const clearData = () => {\n    let _tradeCalcData: any = {}\n    let btradeType: any\n    setTradeData((state) => {\n      btradeType = state?.btradeType ? state.btradeType : BtradeType.Quantity\n      return {\n        ...state,\n        btradeType: state?.btradeType ? state.btradeType : BtradeType.Quantity,\n        sell: { ...state?.sell, tradeValue: undefined },\n        buy: { ...state?.buy, tradeValue: undefined },\n      } as T\n    })\n\n    setTradeCalcData((state) => {\n      _tradeCalcData = {\n        ...(state ?? {}),\n        maxFeeBips: undefined,\n        lockedNotification: true,\n        volumeSell: undefined,\n        volumeBuy: undefined,\n        btradeType,\n      }\n      return _tradeCalcData\n    })\n    updateTradeBtrade({\n      market,\n      maxFeeBips: 0,\n      btradeType,\n      tradeCalcData: {\n        ..._tradeCalcData,\n      },\n    })\n  }\n\n  const availableTradeCheck = React.useCallback((): {\n    tradeBtnStatus: TradeBtnStatus\n    label: string | undefined\n  } => {\n    if (!tokenMap && !tokenPrices) {\n      // setSwapBtnStatus();\n      // return {tradeBtnStatus:TradeBtnStatus.DISABLED};\n      return {\n        label: undefined,\n        tradeBtnStatus: TradeBtnStatus.DISABLED,\n      }\n    }\n    // const account = store.getState().account;\n    const sellToken = tokenMap[tradeData?.sell.belong as string]\n    const buyToken = tokenMap[tradeData?.buy.belong as string]\n    const account = store.getState().account\n    const { tradeCalcData, sellMinAmtInfo, sellMaxAmtInfo } = tradeBtrade\n\n    if (!sellToken || !buyToken || !tradeCalcData) {\n      return {\n        label: undefined,\n        tradeBtnStatus: TradeBtnStatus.DISABLED,\n      }\n    }\n    const walletMap = makeWalletLayer2({ needFilterZero: true }).walletMap ?? {}\n    let validAmt = !!(\n      tradeCalcData?.volumeSell &&\n      sellMinAmtInfo &&\n      sdk\n        .toBig(tradeCalcData?.volumeSell)\n        .gte(sdk.toBig(sellMinAmtInfo).times('1e' + sellToken.decimals))\n    )\n    const sellExceed = sellMaxAmtInfo\n      ? sdk\n          .toBig(sellMaxAmtInfo)\n          .times('1e' + sellToken.decimals)\n          .lt(tradeCalcData.volumeSell ?? 0)\n      : false\n\n    if (sellExceed) {\n      validAmt = false\n    }\n\n    const notEnough = sdk\n      .toBig(walletMap[sellToken.symbol]?.count ?? 0)\n      .lt(tradeData?.sell?.tradeValue ?? 0)\n    if (isBtradeLoading || isMarketInit) {\n      return {\n        label: undefined,\n        tradeBtnStatus: TradeBtnStatus.LOADING,\n      }\n    } else {\n      if (account.readyState === AccountStatus.ACTIVATED) {\n        if (!tradeCalcData || !tradeCalcData.volumeSell || !tradeCalcData.volumeBuy) {\n          return {\n            label: 'labelEnterAmount',\n            tradeBtnStatus: TradeBtnStatus.DISABLED,\n          }\n        } else if (notEnough) {\n          const sellSymbol = tradeData?.sell.belong\n          return {\n            label: `labelArgNoEnough| ${sellSymbol}`,\n            tradeBtnStatus: TradeBtnStatus.DISABLED,\n          }\n        } else if (sellExceed) {\n          const maxOrderSize = tradeCalcData.sellMaxAmtStr + ' ' + tradeData?.sell.belong\n          return {\n            label: `labelLimitMax| ${maxOrderSize}`,\n            tradeBtnStatus: TradeBtnStatus.DISABLED,\n          }\n        } else if (!validAmt) {\n          const sellSymbol = tradeData?.sell.belong\n          if (sellMinAmtInfo === undefined || !sellSymbol || sellMinAmtInfo === 'NaN') {\n            return {\n              label: 'labelEnterAmount',\n              tradeBtnStatus: TradeBtnStatus.DISABLED,\n            }\n          } else {\n            const sellToken = tokenMap[sellSymbol]\n            const minOrderSize = getValuePrecisionThousand(\n              sdk.toBig(sellMinAmtInfo ?? 0), //.div(\"1e\" + sellToken.decimals),\n              sellToken.precision,\n              sellToken.precision,\n              sellToken.precision,\n              false,\n              { floor: false, isAbbreviate: true },\n            )\n            if (isNaN(Number(minOrderSize))) {\n              return {\n                label: `labelLimitMin| ${EmptyValueTag + ' ' + sellSymbol}`,\n                tradeBtnStatus: TradeBtnStatus.DISABLED,\n              }\n            } else {\n              return {\n                label: `labelLimitMin| ${minOrderSize + ' ' + sellSymbol}`,\n                tradeBtnStatus: TradeBtnStatus.DISABLED,\n              }\n            }\n          }\n        } else {\n          return {\n            label: undefined,\n            tradeBtnStatus: TradeBtnStatus.AVAILABLE,\n          }\n        }\n      } else {\n        return {\n          label: undefined,\n          tradeBtnStatus: TradeBtnStatus.AVAILABLE,\n        }\n      }\n    }\n  }, [\n    account,\n    tokenMap,\n    tradeData?.sell.belong,\n    tradeData?.buy.belong,\n    tradeBtrade.maxFeeBips,\n    tradeData?.sell.tradeValue,\n    tradeData?.buy.tradeValue,\n    isBtradeLoading,\n    isMarketInit,\n  ])\n  const sendRequest = React.useCallback(async () => {\n    setIsBtradeLoading(true)\n    const {\n      tradeBtrade: { tradeCalcData, sellToken: _sellToken, buyToken: _buyToken },\n    } = store.getState()._router_tradeBtrade\n    const account = store.getState().account\n\n    try {\n      if (\n        account.readyState == AccountStatus.ACTIVATED &&\n        _sellToken &&\n        _buyToken &&\n        tokenMap &&\n        exchangeInfo &&\n        tradeCalcData &&\n        tradeCalcData?.volumeSell &&\n        tradeCalcData?.volumeBuy &&\n        tradeCalcData.maxFeeBips &&\n        LoopringAPI.userAPI &&\n        LoopringAPI.defiAPI\n      ) {\n        const sellToken = tokenMap[_sellToken]\n        const buyToken = tokenMap[_buyToken]\n        const storageId = await LoopringAPI.userAPI.getNextStorageId(\n          {\n            accountId: account.accountId,\n            sellTokenId: sellToken?.tokenId ?? 0,\n          },\n          account.apiKey,\n        )\n        const request: sdk.OriginBTRADEV3OrderRequest = {\n          exchange: exchangeInfo.exchangeAddress,\n          storageId: storageId.orderId,\n          accountId: account.accountId,\n          sellToken: {\n            tokenId: sellToken?.tokenId ?? 0,\n            volume: sdk.toBig(tradeCalcData.volumeSell).toFixed(0),\n          },\n          buyToken: {\n            tokenId: buyToken?.tokenId ?? 0,\n            volume: sdk.toBig(tradeCalcData.volumeBuy).toFixed(0),\n          },\n          validUntil: getTimestampDaysLater(DAYS),\n          maxFeeBips: tradeCalcData.maxFeeBips,\n          fillAmountBOrS: false,\n          allOrNone: false,\n          eddsaSignature: '',\n          clientOrderId: '',\n          orderType: sdk.OrderTypeResp.TakerOnly,\n          fastMode: tradeCalcData.btradeType === BtradeType.Speed ? true : false,\n        }\n        myLog('useBtradeSwap: submitOrder request', request)\n        const response: { hash: string } | any = await LoopringAPI.defiAPI.sendBtradeOrder({\n          request,\n          privateKey: account.eddsaKey.sk,\n          apiKey: account.apiKey,\n        })\n        if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n          throw new CustomErrorWithCode({\n            code: (response as sdk.RESULT_INFO).code,\n            message: (response as sdk.RESULT_INFO).message,\n            ...SDK_ERROR_MAP_TO_UI[(response as sdk.RESULT_INFO)?.code ?? UIERROR_CODE.UNKNOWN],\n          })\n        } else {\n          clearData()\n        }\n\n        const item = {\n          fromSymbol: sellToken.symbol,\n          fromAmount: sdk.toBig(tradeCalcData.volumeSell).div('1e' + sellToken.decimals),\n          settledFromAmount: undefined,\n          toSymbol: buyToken.symbol,\n          feeAmount: tradeCalcData.fee,\n          settledToAmount: undefined,\n        }\n\n        let info: any = {\n          sellToken,\n          buyToken,\n          sellStr: getValuePrecisionThousand(\n            sdk.toBig(tradeCalcData.volumeSell).div('1e' + sellToken.decimals),\n            sellToken.precision,\n            sellToken.precision,\n            sellToken.precision,\n            false,\n            { floor: false },\n          ),\n          buyStr: getValuePrecisionThousand(\n            sdk.toBig(tradeCalcData.volumeBuy).div('1e' + buyToken.decimals),\n            buyToken.precision,\n            buyToken.precision,\n            buyToken.precision,\n            false,\n            { floor: false },\n          ),\n          sellFStr: undefined,\n          buyFStr: undefined,\n          convertStr:\n            marketMap[market].baseTokenId !== sellToken.tokenId\n              ? `1 ${buyToken.symbol} \\u2248 ${\n                sdk.toBig(tradeCalcData.volumeSell)\n                .multipliedBy('1e' + buyToken.decimals)\n                .div('1e' + sellToken.decimals)\n                .div(tradeCalcData.volumeBuy).toFixed(4) \n                } ${sellToken.symbol}`\n              : `1 ${sellToken.symbol} \\u2248 ${\n                sdk.toBig(tradeCalcData.volumeBuy)\n                .multipliedBy('1e' + sellToken.decimals)\n                .div('1e' + buyToken.decimals)\n                .div(tradeCalcData.volumeSell).toFixed(4) \n                } ${buyToken.symbol}`,\n          feeStr: tradeCalcData?.fee,\n          time: undefined,\n          placedAmount:\n            tokenMap && sellToken.symbol && item.fromAmount && sdk.toBig(item.fromAmount).gt(0)\n              ? `${getValuePrecisionThousand(\n                  sdk.toBig(item.fromAmount),\n                  undefined,\n                  undefined,\n                  tokenMap[item.fromSymbol].precision,\n                  false,\n                  { isAbbreviate: true },\n                )} ${item.fromSymbol}`\n              : EmptyValueTag,\n          executedAmount:\n            tokenMap &&\n            item.fromSymbol &&\n            item.settledFromAmount &&\n            sdk.toBig(item.settledFromAmount).gt(0)\n              ? `${getValuePrecisionThousand(\n                  sdk.toBig(item.settledFromAmount),\n                  undefined,\n                  undefined,\n                  tokenMap[item.fromSymbol].precision,\n                  false,\n                  { isAbbreviate: true },\n                )} ${item.fromSymbol}`\n              : EmptyValueTag,\n          executedRate:\n            tokenMap &&\n            item.fromSymbol &&\n            item.settledFromAmount &&\n            item.fromAmount &&\n            sdk.toBig(item.fromAmount).gt(0)\n              ? `${sdk\n                  .toBig(item.settledFromAmount)\n                  .div(item.fromAmount)\n                  .multipliedBy('100')\n                  .toFixed(2)}%`\n              : EmptyValueTag,\n          convertedAmount:\n            tokenMap &&\n            item.toSymbol &&\n            item.settledToAmount &&\n            sdk.toBig(item.settledToAmount).gt(0)\n              ? `${getValuePrecisionThousand(\n                  sdk.toBig(item.settledToAmount),\n                  undefined,\n                  undefined,\n                  tokenMap[item.toSymbol].precision,\n                  false,\n                  { isAbbreviate: true },\n                )} ${item.toSymbol}`\n              : EmptyValueTag,\n          settledAmount:\n            tokenMap &&\n            item.toSymbol &&\n            item.settledToAmount &&\n            item.feeAmount &&\n            sdk.toBig(item.settledToAmount).gt(0)\n              ? `${getValuePrecisionThousand(\n                  sdk.toBig(item.settledToAmount).minus(item.feeAmount),\n                  undefined,\n                  undefined,\n                  tokenMap[item.toSymbol].precision,\n                  false,\n                  { isAbbreviate: true },\n                )} ${item.toSymbol}`\n              : EmptyValueTag,\n        }\n        setShowAccount({\n          isShow: true,\n          step: AccountStep.BtradeSwap_Pending,\n          info,\n        })\n        walletLayer2Service.sendUserUpdate()\n        await sdk.sleep(SUBMIT_PANEL_DOUBLE_QUICK_AUTO_CLOSE)\n        if (refreshRef.current) {\n          // @ts-ignore\n          refreshRef.current.firstElementChild.click()\n        }\n        const orderConfirm: { hash: string } | any = await LoopringAPI.defiAPI.getBtradeOrders({\n          request: {\n            accountId: account.accountId,\n            // @ts-ignore\n            hash: response.hash,\n          },\n          apiKey: account.apiKey,\n        })\n        if ((orderConfirm as sdk.RESULT_INFO).code || (orderConfirm as sdk.RESULT_INFO).message) {\n        } else if (['failed', 'cancelled'].includes(orderConfirm.status)) {\n          throw 'orderConfirm failed'\n        } else if (store.getState().modals.isShowAccount.isShow) {\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.BtradeSwap_Pending,\n            info: {\n              ...info,\n            },\n          })\n        }\n\n        await sdk.sleep(SUBMIT_PANEL_AUTO_CLOSE)\n        if (store.getState().modals.isShowAccount.isShow) {\n          setShowAccount({ isShow: false })\n        }\n      } else {\n        throw new Error('api not ready')\n      }\n    } catch (error: any) {\n      let content: string = ''\n      if ([102024, 102025, 114001, 114002].includes(error?.code || 0)) {\n        content =\n          t('labelBtradeSwapFailed') +\n          ' error: ' +\n          (error && error.messageKey\n            ? t(error.messageKey, { ns: 'error' })\n            : (error as sdk.RESULT_INFO).message)\n      } else {\n        sdk.dumpError400(error)\n        content =\n          t('labelBtradeSwapFailed') +\n          ' error: ' +\n          (error && error.messageKey\n            ? t(error.messageKey, { ns: 'error' })\n            : (error as sdk.RESULT_INFO).message)\n      }\n      setShowAccount({\n        isShow: false,\n      })\n      setToastOpen({\n        open: true,\n        type: ToastType.error,\n        content,\n      })\n    }\n    setIsBtradeLoading(false)\n  }, [\n    tradeBtrade,\n    tradeData,\n    tokenMap,\n    exchangeInfo,\n    __SUBMIT_LOCK_TIMER__,\n    setToastOpen,\n    t,\n    __DAYS__,\n    market,\n    __TOAST_AUTO_CLOSE_TIMER__,\n    updateTradeBtrade,\n  ])\n\n  /*** Btn related function ***/\n  const btradeSwapSubmit = React.useCallback(async () => {\n    if (!allowTrade?.order?.enable) {\n      setShowSupport({ isShow: true })\n      setIsBtradeLoading(false)\n      return\n    } else if (!marketMap[market]?.enabled || !BTradeInvest.enable) {\n      setShowTradeIsFrozen({\n        isShow: true,\n        type: 'Btrade',\n      })\n      setIsBtradeLoading(false)\n      return\n    } else {\n      sendRequest()\n    }\n  }, [market, marketMap, BTradeInvest])\n\n  const {\n    btnStatus: swapBtnStatus,\n    onBtnClick: onSwapClick,\n    btnLabel: swapBtnI18nKey,\n  } = useSubmitBtn({\n    availableTradeCheck,\n    isLoading: isBtradeLoading || (isMarketInit ?? false),\n    submitCallback: btradeSwapSubmit,\n  })\n\n  const should15sRefresh = React.useCallback(() => {\n    myLog('useBtradeSwap: should15sRefresh', market)\n    if (market) {\n      getBtradeMap()\n      callPairDetailInfoAPIs()\n    }\n  }, [market])\n\n  React.useEffect(() => {\n    const { depth, market } = store.getState()._router_tradeBtrade.tradeBtrade\n    if (depth && new RegExp(market).test(depth?.symbol)) {\n      refreshWhenDepthUp()\n      setIsMarketStatus((state) => {\n        return {\n          ...state,\n          isMarketInit: false,\n        }\n      })\n    }\n  }, [tradeBtrade.depth, account.readyState, market])\n\n  const walletLayer2Callback = React.useCallback(async () => {\n    if (account.readyState === AccountStatus.ACTIVATED) {\n      refreshWhenDepthUp()\n    } else {\n      if (tradeCalcData.coinSell && tradeCalcData.coinBuy) {\n        setTradeData((state) => {\n          return {\n            ...state,\n            btradeType: state?.btradeType ? state.btradeType : BtradeType.Quantity,\n            sell: { belong: tradeCalcData.coinSell },\n            buy: { belong: tradeCalcData.coinBuy },\n          } as T\n        })\n      }\n      updateTradeBtrade({\n        market: market as MarketType,\n        maxFeeBips: 0,\n        totalFee: 0,\n        tradeCalcData: {},\n      })\n\n      setTradeCalcData((state) => {\n        return {\n          ...state,\n          walletMap: {},\n          minimumReceived: undefined,\n          priceImpact: undefined,\n          fee: undefined,\n        }\n      })\n    }\n  }, [tradeData, market, tradeCalcData, marketArray, account.readyState])\n  const callPairDetailInfoAPIs = React.useCallback(async () => {\n    if (market && LoopringAPI.defiAPI && marketMap && marketMap[market]) {\n      try {\n        const { depth } = await dexSwapDependAsync({\n          // @ts-ignore\n          market: marketMap[market]?.btradeMarket,\n          tokenMap,\n        })\n        updateTradeBtrade({\n          // @ts-ignore\n          market,\n          depth,\n          ...marketMap[market],\n        })\n        myLog('useBtradeSwap: depth', depth)\n      } catch (error: any) {\n        myLog('useBtradeSwap:', error, 'go to LRC-ETH')\n        setToastOpen({\n          open: true,\n          content: 'error: resetMarket',\n          type: ToastType.error,\n        })\n        // myLog(\"useBtradeSwap:\", error, \"go to LRC-USDT\");\n        resetMarket(market, 'sell')\n      }\n    }\n  }, [market, marketMap])\n\n  useBtradeSocket({ updateAPICall: callPairDetailInfoAPIs })\n  useWalletLayer2Socket({ walletLayer2Callback })\n\n  /*** user Action function ***/\n  //High: effect by wallet state update\n  const handleSwapPanelEvent = async (\n    swapData: SwapData<SwapTradeData<IBData<C>>>,\n    swapType: any,\n  ): Promise<void> => {\n    const { tradeData: _tradeData } = swapData\n    myLog('useBtradeSwap: resetSwap', swapType, _tradeData)\n    const depth = store.getState()._router_tradeBtrade.tradeBtrade?.depth\n    switch (swapType) {\n      case SwapType.SEll_CLICK:\n      case SwapType.BUY_CLICK:\n        return\n      case SwapType.SELL_SELECTED:\n        myLog(_tradeData)\n        if (_tradeData?.sell.belong !== tradeData?.sell.belong) {\n          resetMarket(\n            `${_tradeData?.sell?.belong ?? `#null`}-${_tradeData?.buy?.belong ?? `#null`}`,\n            'sell',\n          )\n        } else {\n          reCalculateDataWhenValueChange(\n            _tradeData,\n            `${_tradeData?.sell.belong}-${_tradeData?.buy.belong}`,\n            'sell',\n          )\n        }\n        break\n      case SwapType.BUY_SELECTED:\n        if (_tradeData?.buy.belong !== tradeData?.buy.belong) {\n          resetMarket(\n            `${_tradeData?.sell?.belong ?? `#null`}-${_tradeData?.buy?.belong ?? `#null`}`,\n            'buy',\n          )\n        } else {\n          reCalculateDataWhenValueChange(\n            _tradeData,\n            `${_tradeData?.sell.belong}-${_tradeData?.buy.belong}`,\n            'buy',\n          )\n        }\n        break\n      case SwapType.EXCHANGE_CLICK:\n        let StoB, BtoS\n        if (depth && depth.mid_price) {\n          const pr1 = sdk.toBig(1).div(depth.mid_price).toString()\n          const pr2 = depth.mid_price\n          ;[StoB, BtoS] =\n            market === `${tradeCalcData.coinBuy}-${tradeCalcData.coinSell}`\n              ? [pr1, pr2]\n              : [pr2, pr1]\n        }\n        const sellPrecision = tokenMap[tradeCalcData.coinBuy as string].precision\n        const buyPrecision = tokenMap[tradeCalcData.coinSell as string].precision\n        const reserveInfo = sdk.getReserveInfo(tradeCalcData.coinSell as string, tradeCalcData.coinBuy as string, marketArray, tokenMap, marketMap as any)\n        const _tradeCalcData = {\n          ...tradeCalcData,\n          coinSell: tradeCalcData.coinBuy,\n          coinBuy: tradeCalcData.coinSell,\n          sellPrecision,\n          buyPrecision,\n          sellCoinInfoMap: tradeCalcData.buyCoinInfoMap,\n          buyCoinInfoMap: tradeCalcData.sellCoinInfoMap,\n          StoB: getValuePrecisionThousand(\n            StoB,\n            undefined,\n            reserveInfo?.isReverse ? 6 : marketMap[market].precisionForPrice,\n            reserveInfo?.isReverse ? 6 : marketMap[market].precisionForPrice,\n            true,\n          ),\n          BtoS: getValuePrecisionThousand(\n            BtoS,\n            undefined,\n            !reserveInfo?.isReverse ? 6 : marketMap[market].precisionForPrice,\n            !reserveInfo?.isReverse ? 6 : marketMap[market].precisionForPrice,\n            true,\n          ),\n        }\n\n        myLog(\n          'useBtradeSwap:Exchange,tradeCalcData,_tradeCalcData',\n          tradeData,\n          tradeCalcData,\n          _tradeCalcData,\n        )\n        callPairDetailInfoAPIs()\n        updateTradeBtrade({\n          market,\n          tradePair: `${tradeCalcData.coinBuy}-${tradeCalcData.coinSell}`,\n          tradeCalcData: _tradeCalcData,\n        })\n        setTradeCalcData(_tradeCalcData)\n        // @ts-ignore\n        setTradeData((state) => {\n          const walletMap = makeWalletLayer2({ needFilterZero: true }).walletMap\n\n          return {\n            ...(state ?? {}),\n            sell: {\n              belong: _tradeCalcData.coinSell,\n              tradeValue: undefined,\n              balance: walletMap ? walletMap[_tradeCalcData.coinSell as string]?.count : 0,\n            },\n            buy: {\n              belong: _tradeCalcData.coinBuy,\n              tradeValue: undefined,\n              balance: walletMap ? walletMap[_tradeCalcData.coinBuy as string]?.count : 0,\n            },\n          }\n        })\n        break\n      default:\n        // myLog(\"useBtradeSwap:resetSwap default\");\n        // resetTradeCalcData(undefined, market);\n        break\n    }\n  }\n\n  React.useEffect(() => {\n    if (market) {\n      //@ts-ignore\n      if (refreshRef.current) {\n        // @ts-ignore\n        refreshRef.current.firstElementChild.click()\n        should15sRefresh()\n      }\n    }\n  }, [market])\n\n  const reCalculateDataWhenValueChange = React.useCallback(\n    (_tradeData, _tradePair?, type?) => {\n      const {\n        tradeBtrade: { depth, tradePair, btradeType: _btradeType },\n      } = store.getState()._router_tradeBtrade\n      const walletMap = makeWalletLayer2({ needFilterZero: true }).walletMap\n      myLog('useBtradeSwap:reCalculateDataWhenValueChange', tradeData, _tradePair, type)\n      if (\n        depth &&\n        marketMap[market] &&\n        marketMap[market]?.enabled !== 'isFormLocal' &&\n        market &&\n        _tradePair === tradePair &&\n        _tradeData?.sell\n      ) {\n        const btradeType = _tradeData.btradeType ? _tradeData.btradeType : _btradeType\n        const coinA = _tradeData?.sell.belong\n        const coinB = _tradeData?.buy.belong\n        _tradeData.sell.balance = walletMap ? walletMap[coinA]?.count : 0\n        const sellToken = tokenMap[coinA as string]\n        const buyToken = tokenMap[coinB as string]\n        const sellBuyStr = `${sellToken.symbol}-${buyToken.symbol}`\n        const isAtoB = type === 'sell'\n\n        let input: any = isAtoB ? _tradeData.sell.tradeValue : _tradeData.buy.tradeValue\n        input = input === undefined || isNaN(Number(input)) ? 0 : Number(input)\n        let totalFee: any = undefined\n        let stob: string | undefined = undefined\n        let btos: string | undefined = undefined\n        let minimumReceived: any\n        let minimumConverted: string | undefined = undefined\n        let sellMinAmtInfo: any = undefined\n        let sellMaxAmtInfo: any = undefined\n        let sellMaxL2AmtInfo: any = undefined\n        let totalFeeRaw: any = undefined\n        let totalQuote: any = undefined\n        let poolToVol: any = undefined\n        const info: sdk.BTRADE_MARKET = marketMap[market] as sdk.BTRADE_MARKET\n        let maxFeeBips = info.feeBips ?? MAPFEEBIPS\n\n        let slippage = sdk\n          .toBig(\n            _tradeData.slippage && !isNaN(_tradeData.slippage)\n              ? _tradeData.slippage\n              : defaultBlockTradeSlipage,\n          )\n          .times(100)\n          .toString()\n        const { btradeAmount, minAmount, l2Amount } = info\n        const calcDexOutput = sdk.calcDex({\n          info,\n          input: input.toString(),\n          sell: sellToken.symbol,\n          buy: buyToken.symbol,\n          isAtoB,\n          marketArr: marketArray,\n          tokenMap,\n          marketMap: marketMap as any,\n          depth,\n          feeBips: maxFeeBips.toString(),\n          slipBips: slippage,\n        })\n        if (\n          btradeAmount &&\n          l2Amount &&\n          (sellBuyStr == market ? btradeAmount.base !== '0' : btradeAmount.quote !== '0')\n        ) {\n          const btradeAmountVol = sellBuyStr == market ? btradeAmount.base : btradeAmount.quote\n          if (btradeAmountVol) {\n            poolToVol =\n              sdk\n                .toBig(btradeAmountVol)\n                .div('1e' + sellToken.decimals)\n                .toString() ?? '0'\n          }\n          const sellDeepStr =\n            sdk\n              .toBig(sellBuyStr == market ? depth.bids_amtTotal : depth.asks_volTotal)\n              .div('1e' + sellToken.decimals)\n              .times(0.99)\n              .toString() ?? '0'\n\n          if (btradeType === BtradeType.Speed) {\n            const calcDexL2Output = sdk.calcDex({\n              info,\n              input: (sellBuyStr == market\n                ? sdk.toBig(l2Amount.quote ?? 0)\n                : sdk.toBig(l2Amount.base ?? 0)\n              )\n                .div('1e' + buyToken.decimals)\n                .toString(), //input.toString(),\n              sell: sellToken.symbol,\n              buy: buyToken.symbol,\n              isAtoB: false,\n              marketArr: marketArray,\n              tokenMap,\n              marketMap: marketMap as any,\n              depth,\n              feeBips: maxFeeBips.toString(),\n              slipBips: slippage,\n            })\n            totalQuote = poolToVol\n              ? getValuePrecisionThousand(\n                  BigNumber.min(sellDeepStr, poolToVol, calcDexL2Output?.amountS ?? 0),\n                  sellToken.precision,\n                  sellToken.precision,\n                  undefined,\n                  false,\n                  { isAbbreviate: true },\n                )\n              : EmptyValueTag\n            sellMaxAmtInfo = poolToVol\n              ? BigNumber.min(sellDeepStr, poolToVol, calcDexL2Output?.amountS ?? 0)\n              : sellDeepStr\n          } else {\n            sellMaxAmtInfo = poolToVol ? BigNumber.min(sellDeepStr, poolToVol) : sellDeepStr\n            totalQuote = poolToVol\n              ? getValuePrecisionThousand(\n                  BigNumber.min(sellDeepStr, poolToVol),\n                  sellToken.precision,\n                  sellToken.precision,\n                  undefined,\n                  false,\n                  { isAbbreviate: true },\n                )\n              : (sellBuyStr == market ? btradeAmount.base == '0' : btradeAmount.quote == '0')\n              ? t('labelBtradeInsufficient')\n              : EmptyValueTag\n          }\n          sellMinAmtInfo = BigNumber.max(\n            sellToken.orderAmounts.dust,\n            sellBuyStr == market ? minAmount.base : minAmount.quote,\n          )\n            .div('1e' + sellToken.decimals)\n            .toString()\n        }\n\n        if (calcDexOutput) {\n          totalFeeRaw = sdk\n            .toBig(calcDexOutput?.amountBSlipped?.minReceived ?? 0)\n            .div(10000)\n            .times(maxFeeBips)\n          totalFee = totalFeeRaw.gt(0)\n            ? getValuePrecisionThousand(\n                sdk\n                  .toBig(totalFeeRaw)\n                  .div('1e' + buyToken.decimals)\n                  .toString(),\n                buyToken.precision,\n                buyToken.precision,\n                undefined,\n              )\n            : 0\n          minimumReceived = sdk.toBig(calcDexOutput?.amountBSlipped?.minReceived ?? 0).gt(0)\n            ? getValuePrecisionThousand(\n                sdk\n                  .toBig(calcDexOutput?.amountBSlipped?.minReceived ?? 0)\n                  .minus(totalFeeRaw ?? 0)\n                  .div('1e' + buyToken.decimals)\n                  .toString(),\n                buyToken.precision,\n                buyToken.precision,\n                undefined,\n              )\n            : 0\n          minimumConverted = calcDexOutput?.amountB\n            ? getValuePrecisionThousand(\n                sdk\n                  .toBig(calcDexOutput?.amountB)\n                  .times(sdk.toBig(1).minus(sdk.toBig(slippage).div('10000')))\n                  .toString(),\n                buyToken.precision,\n                buyToken.precision,\n                undefined,\n              )\n            : undefined\n          _tradeData[isAtoB ? 'buy' : 'sell'].tradeValue =\n            !_tradeData[isAtoB ? 'sell' : 'buy'].tradeValue &&\n            _tradeData[isAtoB ? 'sell' : 'buy'].tradeValue != '0'\n              ? (undefined as any)\n              : getValuePrecisionThousand(\n                  calcDexOutput[`amount${isAtoB ? 'B' : 'S'}`],\n                  isAtoB ? buyToken.precision : sellToken.precision,\n                  isAtoB ? buyToken.precision : sellToken.precision,\n                  isAtoB ? buyToken.precision : sellToken.precision,\n                ).replaceAll(sdk.SEP, '')\n          let result = reCalcStoB({\n            market,\n            tradeData: _tradeData as SwapTradeData<IBData<unknown>>,\n            tradePair: tradePair as any,\n            marketMap,\n            tokenMap: tradeMap,\n            noGetValuePrecisionThousand: true\n          })\n          stob = result?.stob\n          btos = result?.btos\n        } else {\n          minimumReceived = undefined\n        }\n\n        let _tradeCalcData: any = {\n          minimumReceived,\n          maxFeeBips,\n          btradeType,\n          volumeSell: calcDexOutput?.sellVol as any,\n          volumeBuy: calcDexOutput?.amountBSlipped?.minReceived,\n          fee: totalFee,\n          slippage: sdk.toBig(slippage).div(100).toString(),\n          isReverse: calcDexOutput?.isReverse,\n          lastStepAt: type,\n          sellMinAmtStr: getValuePrecisionThousand(\n            sdk.toBig(sellMinAmtInfo ?? 0),\n            sellToken.precision,\n            sellToken.precision,\n            sellToken.precision,\n            false,\n          ),\n          sellMaxL2AmtStr: getValuePrecisionThousand(\n            sdk.toBig(sellMaxL2AmtInfo ?? 0),\n            sellToken.precision,\n            sellToken.precision,\n            sellToken.precision,\n            false,\n            { isAbbreviate: true },\n          ),\n          sellMaxAmtStr:\n            sellMaxAmtInfo !== undefined\n              ? getValuePrecisionThousand(\n                  sdk.toBig(sellMaxAmtInfo ?? 0),\n                  sellToken.precision,\n                  sellToken.precision,\n                  undefined,\n                  false,\n                  { isAbbreviate: true },\n                )\n              : undefined,\n          totalQuota: totalQuote,\n          l1Pool: poolToVol,\n          l2Pool: getValuePrecisionThousand(\n            sdk\n              .toBig((sellBuyStr == market ? l2Amount.quote : l2Amount.base) ?? 0)\n              .div('1e' + buyToken.decimals),\n            buyToken.precision,\n            buyToken.precision,\n            undefined,\n            false,\n          ),\n          minimumConverted,\n        }\n\n        setTradeCalcData((state) => {\n          const [mid_price, _mid_price_convert] = calcDexOutput\n            ? [\n                depth.mid_price,\n                1 / depth.mid_price\n              ]\n            : [undefined, undefined]\n          stob = stob\n            ? stob\n            : calcDexOutput\n            ? calcDexOutput.isReverse\n              ? _mid_price_convert!.toString()\n              : mid_price!.toString()\n            : state.StoB ? state.StoB: undefined\n          btos = btos\n            ? btos\n            : calcDexOutput\n            ? calcDexOutput.isReverse\n              ? mid_price!.toString()\n              : _mid_price_convert!.toString()\n            : state?.BtoS\n            ? state?.BtoS\n            : undefined\n          _tradeCalcData = {\n            ...state,\n            ..._tradeCalcData,\n            StoB: getValuePrecisionThousand(\n              stob?.replaceAll(sdk.SEP, '') ?? 0,\n              undefined,\n              calcDexOutput?.isReverse ? 6 : marketMap[market].precisionForPrice,\n              calcDexOutput?.isReverse ? 6 : marketMap[market].precisionForPrice,\n              true\n            ),\n            BtoS: getValuePrecisionThousand(\n              btos?.replaceAll(sdk.SEP, '') ?? 0,\n              undefined,\n              !calcDexOutput?.isReverse ? 6 : marketMap[market].precisionForPrice,\n              !calcDexOutput?.isReverse ? 6 : marketMap[market].precisionForPrice,\n              true\n            ),\n            lastStepAt: type,\n          }\n          return _tradeCalcData\n        })\n\n        setTradeData((state) => ({\n          ...state,\n          ..._tradeData,\n          sell: {\n            ...state?.sell,\n            ..._tradeData?.sell,\n            balance: walletMap ? walletMap[_tradeData?.sell?.belong ?? '']?.count : 0,\n          },\n        }))\n\n        updateTradeBtrade({\n          info: info,\n          market: market as any,\n          totalFee: totalFee,\n          totalFeeRaw: totalFeeRaw?.toString(),\n          lastStepAt: type,\n          sellMinAmtInfo: sellMinAmtInfo as any,\n          sellMaxL2AmtInfo: sellMaxL2AmtInfo as any,\n          sellMaxAmtInfo: sellMaxAmtInfo as any,\n          tradeCalcData: _tradeCalcData,\n          maxFeeBips,\n          btradeType,\n        })\n      }\n    },\n    [account.readyState, tradeBtrade, tradeCalcData, tradeData, coinMap, tokenMap, marketArray],\n  )\n  const refreshWhenDepthUp = React.useCallback(() => {\n    const { depth, lastStepAt, tradePair, market } = tradeBtrade\n\n    if (\n      (depth && depth.symbol === market) ||\n      (tradeData &&\n        lastStepAt &&\n        tradeCalcData.coinSell === tradeData['sell'].belong &&\n        tradeCalcData.coinBuy === tradeData['buy'].belong &&\n        tradeData[lastStepAt].tradeValue &&\n        tradeData[lastStepAt].tradeValue !== 0)\n    ) {\n      reCalculateDataWhenValueChange(tradeData, tradePair, lastStepAt)\n    } else if (\n      depth &&\n      tradeCalcData.coinSell &&\n      tradeCalcData.coinBuy &&\n      (`${tradeCalcData.coinSell}-${tradeCalcData.coinBuy}` === market ||\n        `${tradeCalcData.coinBuy}-${tradeCalcData.coinSell}` === market)\n    ) {\n      const walletMap = makeWalletLayer2({ needFilterZero: true }).walletMap\n\n      const result = reCalcStoB({\n        market,\n        tradeData: tradeData as SwapTradeData<IBData<unknown>>,\n        tradePair: tradePair as any,\n\n        marketMap,\n        tokenMap: tradeMap,\n        noGetValuePrecisionThousand: true\n      })\n      const buyToken = tokenMap[tradeCalcData.coinBuy]\n      const sellToken = tokenMap[tradeCalcData.coinSell]\n\n      let _tradeCalcData: any = {}\n      setTradeCalcData((state) => {\n        const pr1 = sdk.toBig(1).div(depth.mid_price).toString()\n        const pr2 = depth.mid_price\n        const [StoB, BtoS] =\n          market === `${tradeCalcData.coinBuy}-${tradeCalcData.coinSell}` ? [pr1, pr2] : [pr2, pr1]\n        const reserveInfo = sdk.getReserveInfo(sellToken.symbol, buyToken.symbol, marketArray, tokenMap, marketMap as any)\n        _tradeCalcData = {\n          ...state,\n          ...tradeCalcData,\n          StoB: getValuePrecisionThousand(\n            (result ? result?.stob : StoB.toString())?.replaceAll(sdk.SEP, ''),\n            undefined,\n            reserveInfo?.isReverse ? 6 : marketMap[market].precisionForPrice,\n            reserveInfo?.isReverse ? 6 : marketMap[market].precisionForPrice,\n            true,\n          ),\n          BtoS: getValuePrecisionThousand(\n            (result ? result?.btos : BtoS.toString())?.replaceAll(sdk.SEP, ''),\n            undefined,\n            !reserveInfo?.isReverse ? 6 : marketMap[market].precisionForPrice,\n            !reserveInfo?.isReverse ? 6 : marketMap[market].precisionForPrice,\n            true,\n          ),\n        }\n        return {\n          ..._tradeCalcData,\n          walletMap,\n        }\n      })\n      reCalculateDataWhenValueChange(\n        {\n          sell: {\n            belong: tradeCalcData.coinSell,\n            balance: walletMap ? walletMap[tradeCalcData.coinSell]?.count : 0,\n          },\n          buy: { belong: tradeCalcData.coinBuy },\n        },\n        `${tradeCalcData.coinSell}-${tradeCalcData.coinBuy}`,\n        'sell',\n      )\n\n      updateTradeBtrade({ market, tradeCalcData: _tradeCalcData })\n    }\n  }, [market, tradeBtrade, tradeData, tradeCalcData, setTradeCalcData])\n\n  return {\n    isMarketInit,\n    toastOpen,\n    closeToast,\n    tradeCalcData,\n    tradeData,\n    onSwapClick,\n    swapBtnI18nKey,\n    swapBtnStatus,\n    handleSwapPanelEvent,\n    should15sRefresh,\n    refreshRef,\n    btradeSwapSubmit,\n    tradeBtrade,\n    isSwapLoading: isBtradeLoading,\n    market,\n    isMobile,\n    setToastOpen,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/useCheckAccStatus.tsx",
    "content": "import {\n  AccountStatus,\n  coinbaseSmartWalletChains,\n  FeeInfo,\n  MapChainId,\n  SagaStatus,\n  SPECIAL_ACTIVATION_NETWORKS,\n  UIERROR_CODE,\n  WalletMap,\n} from '@loopring-web/common-resources'\nimport { isCoinbaseSmartWallet, LoopringAPI, makeWalletLayer2, store, useAccount, useSystem, useWalletLayer2 } from '../../index'\nimport {\n  AccountStep,\n  CheckActiveStatusProps,\n  TOASTOPEN,\n  ToastType,\n  useOpenModals,\n  TransErrorHelp,\n  useSettings,\n} from '@loopring-web/component-lib'\nimport React from 'react'\nimport { connectProvides } from '@loopring-web/web3-provider'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nexport function isAccActivated() {\n  return store.getState().account.readyState === AccountStatus.ACTIVATED\n}\n\nexport const useCheckActiveStatus = <C extends FeeInfo>({\n  // isFeeNotEnough,\n  checkFeeIsEnough,\n  chargeFeeTokenList,\n  onDisconnect,\n  isDepositing,\n  setToastOpen,\n}: // isShow,\n{\n  // isShow: boolean;\n  isDepositing: boolean\n  onDisconnect: () => void\n  isFeeNotEnough: {\n    isFeeNotEnough: boolean\n    isOnLoading: boolean\n  }\n  setToastOpen: (state: TOASTOPEN) => void\n  chargeFeeTokenList: C[]\n  checkFeeIsEnough: (props?: { isRequiredAPI: true; intervalTime?: number }) => void\n}): { checkActiveStatusProps: CheckActiveStatusProps<C> } => {\n  const { account, updateAccount } = useAccount()\n  const { status: walletLayer2Status, updateWalletLayer2 } = useWalletLayer2()\n  // const { chainInfos } = onchainHashInfo.useOnChainInfo();\n  // const nodeTimer = React.useRef<NodeJS.Timeout | -1>(-1);\n\n  const {\n    setShowAccount,\n    setShowActiveAccount,\n    setShowDeposit,\n    modals: { isShowAccount },\n  } = useOpenModals()\n  const [know, setKnow] = React.useState(false)\n  const [knowDisable, setKnowDisable] = React.useState(true)\n  const [isAddressContract, setIsAddressContract] = React.useState<undefined | boolean>(undefined)\n  const [walletMap, setWalletMap] = React.useState(\n    makeWalletLayer2({ needFilterZero: true, isActive: true }).walletMap ?? ({} as WalletMap<any>),\n  )\n  const [isFeeNotEnough, setIsFeeNotEnough] = React.useState({\n    isFeeNotEnough: true,\n    isOnLoading: false,\n  })\n\n  const goUpdateAccount = () => {\n    setShowAccount({ isShow: false })\n    setShowActiveAccount({ isShow: true })\n  }\n  const onIKnowClick = async () => {\n    const { account } = store.getState()\n    const [walletType, coinbaseSW] = await Promise.all([\n      LoopringAPI?.walletAPI?.getWalletType({\n        wallet: account.accAddress,\n        network: MapChainId[defaultNetwork] as sdk.NetworkWallet\n      }),\n      isCoinbaseSmartWallet(account.accAddress, defaultNetwork as sdk.ChainId)\n    ])\n    \n    const isActivationSupported =\n      !walletType?.walletType?.isContract ||\n      (coinbaseSW && coinbaseSmartWalletChains.includes(defaultNetwork))\n    if (!isActivationSupported || isFeeNotEnough.isFeeNotEnough) {\n      setKnow(true)\n    } else {\n      goUpdateAccount()\n    }\n  }\n  const walletLayer2Callback = React.useCallback(() => {\n    const walletMap = makeWalletLayer2({ needFilterZero: true, isActive: true }).walletMap ?? {}\n    setWalletMap(walletMap)\n    setIsFeeNotEnough((state) => ({\n      ...state,\n      isFeeNotEnough: walletMap\n        ? chargeFeeTokenList.findIndex((item) => {\n            if (walletMap[item.belong] && walletMap[item.belong]?.count) {\n              return sdk\n                .toBig(walletMap[item.belong]?.count ?? 0)\n                .gte(sdk.toBig(item.fee.toString().replaceAll(sdk.SEP, '')))\n            } else {\n              return (\n                item?.feeRaw !== undefined &&\n                Number(item.fee.toString()) == 0 &&\n                sdk.toBig((item.feeRaw ?? '').toString().replaceAll(sdk.SEP, '')).eq(0)\n              )\n            }\n            return\n          }) === -1\n        : false,\n    }))\n    setKnowDisable(false)\n  }, [chargeFeeTokenList])\n\n  const checkFeeIsEnoughInterval = React.useRef<NodeJS.Timeout | -1>(-1)\n\n  React.useEffect(() => {\n    if (walletLayer2Callback && walletLayer2Status === SagaStatus.UNSET) {\n      walletLayer2Callback()\n      checkFeeIsEnough()\n    }\n    \n  }, [walletLayer2Status])\n\n\n  const init = React.useCallback(async () => {\n    setKnowDisable(true)\n    try {\n      const isContract = await sdk.isContract(connectProvides.usedWeb3 as any, account.accAddress)\n      setIsAddressContract(isContract)\n      updateWalletLayer2()\n    } catch (error: any) {\n      console.log('Web3 error', error)\n      setToastOpen({\n        open: true,\n        type: ToastType.error,\n        content: <TransErrorHelp error={{ code: UIERROR_CODE.TIME_OUT }} />,\n      })\n    }\n  }, [account.accAddress, updateWalletLayer2])\n\n  React.useEffect(() => {\n    if (isShowAccount.isShow && isShowAccount.step === AccountStep.CheckingActive) {\n      init()\n      setKnow(false)\n      checkFeeIsEnoughInterval.current = setInterval(() => {\n        updateWalletLayer2()\n        walletLayer2Callback()\n        checkFeeIsEnough()\n        updateAccount({})\n      }, 10 * 1000) \n    }\n    return () => {\n      if (checkFeeIsEnoughInterval.current !== -1) {\n        clearInterval(checkFeeIsEnoughInterval.current)\n      }\n    }\n  }, [isShowAccount.step, isShowAccount.isShow])\n\n  const { app } = useSystem()\n  const { defaultNetwork } = useSettings()\n  const isSpecialActivation = app === 'earn' && SPECIAL_ACTIVATION_NETWORKS.includes(defaultNetwork)\n\n  const checkActiveStatusProps: CheckActiveStatusProps<C> = {\n    know,\n    knowDisable,\n    onIKnowClick,\n    isDepositing,\n    goDisconnect: onDisconnect,\n    account: { ...account, isContract: isAddressContract },\n    chargeFeeTokenList,\n    goSend: () => {\n      if (isSpecialActivation) {\n        setShowAccount({ isShow: false })\n        setShowDeposit({ isShow: true })\n      } else {\n        setShowAccount({ isShow: true, step: AccountStep.AddAssetGateway })\n      }\n      \n    },\n    walletMap,\n    isFeeNotEnough,\n    depositNeeded: true\n    // account._accountIdNotActive !== -1\n  }\n  return { checkActiveStatusProps }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/useClaimConfirm.ts",
    "content": "import {\n  AccountStatus,\n  CLAIM_TYPE,\n  getValuePrecisionThousand,\n  IBData,\n  LIVE_FEE_TIMES,\n  myLog,\n  SUBMIT_PANEL_AUTO_CLOSE,\n  TRADE_TYPE,\n  UIERROR_CODE,\n} from '@loopring-web/common-resources'\nimport { store, useAccount, useModalData, useSystem, useTokenMap } from '../../stores'\nimport { useWalletInfo } from '../../stores/localStore/walletInfo'\nimport { AccountStep, ClaimProps, useOpenModals } from '@loopring-web/component-lib'\nimport { useBtnStatus } from '../common'\nimport React from 'react'\nimport { volumeToCount } from '../help'\nimport {\n  useChargeFees,\n  useWalletLayer2Socket,\n  walletLayer2Service,\n  claimServices,\n} from '../../services'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { ConnectProvidersSignMap, connectProvides } from '@loopring-web/web3-provider'\nimport { LoopringAPI } from '../../api_wrapper'\nimport { isAccActivated } from './useCheckAccStatus'\nimport { getTimestampDaysLater } from '../../utils'\nimport { DAYS } from '../../defs'\n\nexport const useClaimConfirm = <T extends IBData<I> & { tradeValueView: string }, I>() => {\n  const { exchangeInfo, chainId } = useSystem()\n  const { account } = useAccount()\n  const {\n    allowTrade: { raw_data },\n  } = useSystem()\n  const legalEnable = (raw_data as any)?.legal?.enable\n  const { tokenMap, idIndex } = useTokenMap()\n  const { checkHWAddr, updateHW } = useWalletInfo()\n\n  const {\n    setShowAccount,\n    setShowClaimWithdraw,\n    modals: {\n      isShowClaimWithdraw: { claimToken, isShow, claimType },\n      isShowAccount: { info },\n    },\n  } = useOpenModals()\n  const { claimValue, updateClaimData } = useModalData()\n  const { btnStatus, enableBtn, disableBtn, btnInfo } = useBtnStatus()\n  const feeProps =\n    claimValue.tradeType === TRADE_TYPE.TOKEN\n      ? claimType === CLAIM_TYPE.lrcStaking || claimType === CLAIM_TYPE.allToken\n        ? {\n            requestType: sdk.OffchainFeeReqType.EXTRA_TYPES,\n            extraType: 3,\n          }\n        : {\n            requestType: sdk.OffchainFeeReqType.EXTRA_TYPES,\n            extraType: 2,\n          }\n      : {\n          requestType: sdk.OffchainNFTFeeReqType.EXTRA_TYPES,\n          tokenAddress: claimValue?.tokenAddress,\n          extraType: 2,\n          isNFT: true,\n        }\n  const {\n    chargeFeeTokenList,\n    isFeeNotEnough,\n    handleFeeChange,\n    feeInfo,\n    checkFeeIsEnough,\n    resetIntervalTime,\n  } = useChargeFees({\n    ...feeProps,\n    intervalTime: undefined,\n    updateData: ({ fee }) => {\n      const claimValue = store.getState()._router_modalData.claimValue\n      if (\n        (claimValue.tradeType === TRADE_TYPE.TOKEN &&\n          (claimValue.claimType === CLAIM_TYPE.lrcStaking ||\n            claimValue.claimType === CLAIM_TYPE.allToken) &&\n          feeProps.extraType === 3) ||\n        (claimValue.tradeType === TRADE_TYPE.TOKEN &&\n          claimType === CLAIM_TYPE.redPacket &&\n          feeProps.extraType === 2 &&\n          !feeProps.isNFT) ||\n        (claimValue.tradeType === TRADE_TYPE.NFT &&\n          claimType === CLAIM_TYPE.redPacket &&\n          feeProps.extraType === 2 &&\n          feeProps.isNFT)\n      ) {\n        updateClaimData({ ...claimValue, fee: fee })\n      }\n    },\n  })\n\n  useWalletLayer2Socket({ walletLayer2Callback: undefined })\n  // calim\n  const resetDefault = React.useCallback(() => {\n    if (info?.isRetry) {\n      checkFeeIsEnough()\n      return\n    }\n    // claimToken\n    if (claimToken) {\n      if (claimToken?.isNft) {\n        updateClaimData({\n          ...claimToken.nftTokenInfo,\n          tradeType: TRADE_TYPE.NFT,\n          // nftData: claimToken.nftData,\n          tokenAddress: claimToken?.nftTokenInfo?.tokenAddress,\n          tokenId: claimToken.tokenId,\n          belong: claimToken.nftTokenInfo?.metadata?.base?.name ?? 'NFT',\n          tradeValue: Number(claimToken.total),\n          volume: claimToken.total,\n          balance: Number(claimToken.total),\n          claimType,\n          fee: feeInfo,\n          luckyTokenHash: claimToken.luckyTokenHash,\n        } as any)\n      } else {\n        const token = tokenMap[idIndex[claimToken.tokenId]]\n        updateClaimData({\n          belong: idIndex[claimToken.tokenId],\n          tradeType: TRADE_TYPE.TOKEN,\n          tradeValue: volumeToCount(token.symbol, claimToken.total),\n          volume: claimToken.total,\n          balance: volumeToCount(token.symbol, claimToken.total),\n          claimType,\n          fee: feeInfo,\n        })\n      }\n    } else {\n    }\n  }, [checkFeeIsEnough, updateClaimData, feeInfo, claimToken, info?.isRetry])\n\n  React.useEffect(() => {\n    if (isShow) {\n      resetDefault()\n      walletLayer2Service.sendUserUpdate()\n    }\n  }, [isShow])\n  React.useEffect(() => {\n    if (isShow) {\n      checkFeeIsEnough({ isRequiredAPI: true, intervalTime: LIVE_FEE_TIMES })\n    } else {\n      resetIntervalTime()\n    }\n    return () => {\n      resetIntervalTime()\n    }\n  }, [isShow, claimValue.claimType, claimValue.tradeType])\n  const processRequest = React.useCallback(\n    async (\n      request: sdk.OriginLuckTokenWithdrawsRequestV3 | sdk.OriginStakeClaimRequestV3,\n      isHardwareWallet: boolean = false,\n    ) => {\n      const { apiKey, connectName, eddsaKey } = account\n      const claimValue = store.getState()._router_modalData.claimValue\n      // const claimValue = store.getState()._router_modalData.c;\n\n      try {\n        if (connectProvides.usedWeb3 && LoopringAPI.luckTokenAPI && isAccActivated()) {\n          let isHWAddr = checkHWAddr(account.accAddress)\n\n          if (!isHWAddr && isHardwareWallet) {\n            isHWAddr = true\n          }\n\n          myLog('ClaimConfirm processRequest:', isHWAddr, isHardwareWallet)\n          let response\n          if (claimValue.claimType === CLAIM_TYPE.redPacket) {\n            response = await LoopringAPI.luckTokenAPI.sendLuckTokenWithdraws(\n              {\n                request: request as sdk.OriginLuckTokenWithdrawsRequestV3,\n                web3: connectProvides.usedWeb3 as any,\n                chainId: chainId === 'unknown' ? 1 : chainId,\n                walletType: (ConnectProvidersSignMap[connectName] ??\n                  connectName) as unknown as sdk.ConnectorNames,\n                eddsaKey: eddsaKey.sk,\n                apiKey,\n                isHWAddr,\n              },\n              {\n                accountId: account.accountId,\n                counterFactualInfo: eddsaKey.counterFactualInfo,\n              },\n            )\n          } else if (claimValue.claimType === CLAIM_TYPE.allToken) {\n            response = await LoopringAPI.userAPI?.sendTotalClaim(\n              {\n                request: request as sdk.OriginClaimRequestV3,\n                web3: connectProvides.usedWeb3 as any,\n                chainId: chainId === 'unknown' ? 1 : chainId,\n                walletType: (ConnectProvidersSignMap[connectName] ??\n                  connectName) as unknown as sdk.ConnectorNames,\n                eddsaKey: eddsaKey.sk,\n                apiKey,\n                isHWAddr,\n              },\n              {\n                accountId: account.accountId,\n                counterFactualInfo: eddsaKey.counterFactualInfo,\n              },\n            )\n          } else if (claimValue.claimType === CLAIM_TYPE.lrcStaking) {\n            response = await LoopringAPI.defiAPI?.sendStakeClaim(\n              {\n                request: request as sdk.OriginStakeClaimRequestV3,\n                web3: connectProvides.usedWeb3 as any,\n                chainId: chainId === 'unknown' ? 1 : chainId,\n                walletType: (ConnectProvidersSignMap[connectName] ??\n                  connectName) as unknown as sdk.ConnectorNames,\n                eddsaKey: eddsaKey.sk,\n                apiKey,\n                isHWAddr,\n              },\n              {\n                accountId: account.accountId,\n                counterFactualInfo: eddsaKey.counterFactualInfo,\n              },\n            )\n          }\n\n          myLog('claim submitted :', claimValue.claimType, response)\n\n          if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n            throw response\n          }\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.ClaimWithdraw_In_Progress,\n          })\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.ClaimWithdraw_Submit,\n            info: {\n              symbol: claimValue.belong,\n            },\n          })\n          claimServices.claimSuccess({ type: claimValue.claimType })\n          if (isHWAddr) {\n            myLog('......try to set isHWAddr', isHWAddr)\n            updateHW({ wallet: account.accAddress, isHWAddr })\n          }\n          walletLayer2Service.sendUserUpdate()\n          setShowClaimWithdraw({ isShow: false })\n          await sdk.sleep(SUBMIT_PANEL_AUTO_CLOSE)\n          if (\n            store.getState().modals.isShowAccount.isShow &&\n            store.getState().modals.isShowAccount.step == AccountStep.ClaimWithdraw_Submit\n          ) {\n            setShowAccount({ isShow: false })\n          }\n        }\n      } catch (e: any) {\n        const code = sdk.checkErrorInfo(e, isHardwareWallet)\n        claimServices.claimFailed({ type: claimValue.claimType, error: { ...e, code } })\n        switch (code) {\n          case sdk.ConnectorError.NOT_SUPPORT_ERROR:\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.ClaimWithdraw_First_Method_Denied,\n              info: {\n                symbol: claimValue.belong,\n              },\n            })\n            break\n          case sdk.ConnectorError.USER_DENIED:\n          case sdk.ConnectorError.USER_DENIED_2:\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.ClaimWithdraw_Denied,\n              info: {\n                symbol: claimValue.belong,\n              },\n            })\n            break\n          default:\n            if ([102024, 102025, 114001, 114002].includes((e as sdk.RESULT_INFO)?.code || 0)) {\n              checkFeeIsEnough({ isRequiredAPI: true })\n            }\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.ClaimWithdraw_Failed,\n              info: {\n                symbol: claimValue.belong,\n              },\n              error: {\n                code: UIERROR_CODE.UNKNOWN,\n                msg: e?.message,\n                ...(e instanceof Error\n                  ? {\n                      message: e?.message,\n                      stack: e?.stack,\n                    }\n                  : e ?? {}),\n              },\n            })\n            break\n        }\n      }\n    },\n    [account],\n  )\n\n  const onClaimClick = React.useCallback(\n    async (_data: Partial<T>, isHardwareRetry = false) => {\n      const { accountId, accAddress, readyState, apiKey, eddsaKey } = account\n      const claimValue = store.getState()._router_modalData.claimValue\n      if (\n        readyState === AccountStatus.ACTIVATED &&\n        tokenMap &&\n        LoopringAPI.userAPI &&\n        exchangeInfo &&\n        claimValue?.fee?.belong &&\n        claimValue.fee?.feeRaw &&\n        claimValue?.tradeValue &&\n        (claimValue?.belong || claimValue.nftData) &&\n        !isFeeNotEnough.isFeeNotEnough &&\n        eddsaKey?.sk\n      ) {\n        try {\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.ClaimWithdraw_WaitForAuth,\n          })\n          const feeToken = tokenMap[claimValue.fee.belong]\n          const feeRaw = claimValue.fee.feeRaw ?? claimValue.fee.__raw__?.feeRaw ?? 0\n          const fee = sdk.toBig(feeRaw)\n\n          let token: any\n          let amount: any = 0\n          if (claimValue?.nftData) {\n            token = {\n              tokenId: claimValue.tokenId,\n            }\n            amount = claimValue.volume\n          } else {\n            token = tokenMap[claimValue?.belong]\n            amount = claimValue.volume\n          }\n\n          const storageId = await LoopringAPI.userAPI?.getNextStorageId(\n            {\n              accountId,\n              sellTokenId: Number(feeToken.tokenId),\n            },\n            apiKey,\n          )\n          let brokerType: any = undefined\n          switch (claimValue.claimType) {\n            case CLAIM_TYPE.redPacket:\n              brokerType = 2\n              break\n            case CLAIM_TYPE.lrcStaking:\n            case CLAIM_TYPE.allToken:\n              brokerType = 0\n              break\n          }\n          const { broker } = await LoopringAPI.userAPI?.getAvailableBroker({\n            type: brokerType,\n          })\n          let request:\n            | (sdk.OriginLuckTokenWithdrawsRequestV3 & {\n                luckyTokenHash?: string\n              })\n            | sdk.OriginStakeClaimRequestV3 = {} as any\n\n          if (claimValue.claimType === CLAIM_TYPE.redPacket) {\n            request = {\n              tokenId: token.tokenId,\n              feeTokenId: feeToken.tokenId,\n              amount: amount.toString(),\n              nftData: claimToken?.isNft ? claimToken.nftTokenInfo?.nftData : undefined,\n              claimer: accAddress,\n              transfer: {\n                exchange: exchangeInfo.exchangeAddress,\n                payerAddr: accAddress,\n                payerId: accountId,\n                payeeAddr: broker,\n                storageId: storageId.offchainId,\n                maxFee: {\n                  tokenId: feeToken.tokenId,\n                  volume: '0',\n                },\n                token: {\n                  tokenId: feeToken.tokenId,\n                  volume: fee.toFixed(), // TEST: fee.toString(),\n                },\n                validUntil: getTimestampDaysLater(DAYS),\n              },\n              luckyTokenHash: claimToken?.isNft ? claimToken?.luckyTokenHash : undefined,\n            }\n          } else if (claimValue.claimType === CLAIM_TYPE.allToken) {\n            request = {\n              accountId: account.accountId,\n              token: {\n                tokenId: token.tokenId,\n                volume: amount.toString(),\n              },\n              transfer: {\n                exchange: exchangeInfo.exchangeAddress,\n                payerAddr: accAddress,\n                payerId: accountId,\n                payeeAddr: broker,\n                storageId: storageId.offchainId,\n                maxFee: {\n                  tokenId: feeToken.tokenId,\n                  volume: '0',\n                },\n                token: {\n                  tokenId: feeToken.tokenId,\n                  volume: fee.toFixed(), // TEST: fee.toString(),\n                },\n                validUntil: getTimestampDaysLater(DAYS),\n              },\n            }\n          } else if (claimValue.claimType === CLAIM_TYPE.lrcStaking) {\n            request = {\n              accountId: account.accountId,\n              token: {\n                tokenId: token.tokenId,\n                volume: amount.toString(),\n              },\n              transfer: {\n                exchange: exchangeInfo.exchangeAddress,\n                payerAddr: accAddress,\n                payeeId: 0,\n                payerId: accountId,\n                payeeAddr: broker,\n                storageId: storageId.offchainId,\n                maxFee: {\n                  tokenId: feeToken.tokenId,\n                  volume: '0',\n                },\n                token: {\n                  tokenId: feeToken.tokenId,\n                  volume: fee.toFixed(), // TEST: fee.toString(),\n                },\n                validUntil: getTimestampDaysLater(DAYS),\n              },\n            }\n          }\n\n          myLog('claimWithdrawals request:', request)\n          processRequest(request, isHardwareRetry)\n        } catch (e: any) {\n          // sdk.dumpError400(e);\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.ClaimWithdraw_Failed,\n            error: {\n              code: e?.code ?? UIERROR_CODE.UNKNOWN,\n              message: e.message,\n              ...(e instanceof Error\n                ? {\n                    message: e?.message,\n                    stack: e?.stack,\n                  }\n                : e ?? {}),\n            } as sdk.RESULT_INFO,\n          })\n        }\n\n        return true\n      } else {\n        return false\n      }\n    },\n    [\n      account,\n      tokenMap,\n      exchangeInfo,\n      isFeeNotEnough.isFeeNotEnough,\n      setShowAccount,\n      processRequest,\n    ],\n  )\n  const checkBtnStatus = React.useCallback(() => {\n    const claimValue = store.getState()._router_modalData.claimValue\n    if (\n      tokenMap &&\n      chargeFeeTokenList.length &&\n      isFeeNotEnough &&\n      !isFeeNotEnough.isFeeNotEnough &&\n      (claimValue.belong || claimValue.nftData) &&\n      claimValue.tradeValue &&\n      claimValue.fee &&\n      claimValue.fee.belong\n    ) {\n      enableBtn()\n      return\n    }\n    disableBtn()\n  }, [\n    chargeFeeTokenList.length,\n    disableBtn,\n    enableBtn,\n    isFeeNotEnough.isFeeNotEnough,\n    tokenMap,\n    claimValue?.balance,\n    claimValue?.belong,\n    claimValue?.fee?.feeRaw,\n    claimValue?.tradeValue,\n  ])\n\n  React.useEffect(() => {\n    checkBtnStatus()\n  }, [\n    chargeFeeTokenList,\n    claimValue?.tradeValue,\n    isFeeNotEnough?.isFeeNotEnough,\n    claimValue?.fee?.feeRaw,\n  ])\n\n  const retryBtn = React.useCallback(\n    (isHardwareRetry: boolean = false) => {\n      setShowAccount({\n        isShow: true,\n        step: AccountStep.ClaimWithdraw_WaitForAuth,\n      })\n      onClaimClick({}, isHardwareRetry)\n    },\n    [setShowAccount],\n  )\n  return {\n    retryBtn,\n    claimProps: {\n      btnStatus,\n      btnInfo,\n      disabled: !(legalEnable === true),\n      tradeData: {\n        tradeValue: claimValue?.tradeValue,\n        belong: claimValue?.belong,\n        balance: claimValue?.belong,\n        tradeValueView: getValuePrecisionThousand(\n          claimValue?.tradeValue,\n          tokenMap[claimValue?.belong?.toString() ?? '']?.precision,\n          tokenMap[claimValue?.belong?.toString() ?? '']?.precision,\n          tokenMap[claimValue?.belong?.toString() ?? '']?.precision,\n          false,\n        ),\n      },\n      chargeFeeTokenList,\n      isFeeNotEnough,\n      handleFeeChange,\n      feeInfo,\n      checkFeeIsEnough,\n      onClaimClick,\n      claimType,\n      isNFT: claimToken?.isNft ? true : false,\n      nftIMGURL: claimToken?.nftTokenInfo?.metadata?.imageSize.original,\n    } as any as ClaimProps<any, any>,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/useCoinbaseWalletPassword.ts",
    "content": "import { AccountStep, useOpenModals, useSettings } from '@loopring-web/component-lib'\nimport { useTranslation } from 'react-i18next'\nimport { useUpdateAccount } from './useUpdateAccount'\nimport { decryptAESMd5, isSameEVMAddress, offchainFeeInfoToFeeInfo } from '../../utils'\nimport { useCoinbaseSmartWalletPersist } from '../../stores/localStore/coinbaseSmartWalletPersist'\nimport { LoopringAPI } from '../../api_wrapper'\nimport { accountServices } from '../../services'\nimport { useAccount, useTokenMap, useWalletLayer2 } from '../../stores'\nimport { DUAL_RETRY_STATUS, LABEL_INVESTMENT_STATUS, OffchainFeeReqType, SETTLEMENT_STATUS, VaultAccountStatus } from '@loopring-web/loopring-sdk'\nimport { useEffect, useState } from 'react'\nimport { keys } from 'lodash'\nimport { BigNumber} from 'ethers'\n\n\nexport const useCoinbaseWalletPassword = () => {\n  const { t } = useTranslation('common')\n  const { modals: {isShowAccount, isShowActiveAccount}, setShowAccount, setShowResetAccount, setShowActiveAccount } = useOpenModals()\n  const { goUpdateAccountCoinbaseWallet } = useUpdateAccount()\n  const { data } = useCoinbaseSmartWalletPersist()\n  const { defaultNetwork } = useSettings()\n  const { account } = useAccount()\n  const {tokenMap} = useTokenMap()\n  const {walletLayer2} = useWalletLayer2()\n  const foundPersistData = data?.find(\n    (item) => item.chainId === defaultNetwork && isSameEVMAddress(item.wallet, account?.accAddress),\n  )\n  const [showPasswordMismatchError, setShowPasswordMismatchError] = useState(false)\n  useEffect(() => {\n    setShowPasswordMismatchError(false)\n  }, [isShowAccount.step, isShowAccount.isShow])\n  return {\n    introProps: {\n      t,\n      onClickConfirm: () => {\n        setShowAccount({\n          step: AccountStep.Coinbase_Smart_Wallet_Password_Set,\n          isShow: true,\n          info: isShowAccount?.info\n        })\n      },\n    },\n    setProps: {\n      t,\n      onClickConfirm: (password: string) => {\n        setShowAccount({\n          step: AccountStep.Coinbase_Smart_Wallet_Password_Set_Confirm,\n          isShow: true,\n          info: {\n            ...isShowAccount?.info,\n            password\n          }\n        })\n      },\n      onClickBack: () => {\n        setShowAccount({\n          step: AccountStep.Coinbase_Smart_Wallet_Password_Intro,\n          isShow: true,\n        })\n      },\n    },\n    setConfirmProps: {\n      t,\n      onClickProceed: () => {\n        goUpdateAccountCoinbaseWallet({\n          password: isShowAccount?.info?.password,\n          feeInfo: isShowAccount?.info?.feeInfo,\n          isReset: isShowAccount?.info?.isReset,\n        })\n      },\n    },\n    setProcessingProps: {\n      step: isShowAccount?.info?.step,\n      showResumeUpdateAccount: isShowAccount?.info?.showResumeUpdateAccount\n    },\n    setErrorProps: {\n      t,\n      onClickConfirm: () => {\n        setShowAccount({\n          isShow: false\n        })\n      },\n    },\n    getErrorProps: {\n      t,\n      onClickConfirm: () => {\n        setShowAccount({\n          isShow: false\n        })\n      },\n    },\n    inputProps: {\n      t,\n      inputDisabled: !(\n        foundPersistData &&\n        foundPersistData.eddsaKey.sk &&\n        foundPersistData.nonce === account?.nonce\n      ),\n      onClickConfirm: async (password: string) => {\n        if (!foundPersistData || !foundPersistData?.eddsaKey.sk) return\n        try {\n          const sk = decryptAESMd5(password, foundPersistData.eddsaKey.sk)\n          const accountInfoRealTime = await LoopringAPI.exchangeAPI?.getAccount({\n            owner: foundPersistData.wallet,\n          })\n          setShowPasswordMismatchError(false)\n          const res = await LoopringAPI.userAPI!\n            .getUserApiKey(\n              {\n                accountId: accountInfoRealTime!.accInfo.accountId,\n              },\n              sk,\n            )\n            \n          accountServices.sendAccountSigned({\n            apiKey: res.apiKey,\n            eddsaKey: { ...foundPersistData!.eddsaKey, sk },\n            isInCounterFactualStatus: false,\n            accountId: accountInfoRealTime!.accInfo.accountId,\n          })\n          setShowAccount({\n            isShow: false,\n          })\n        } catch (e) {\n          setShowPasswordMismatchError(true)\n          accountServices.sendCheckAccount(foundPersistData!.wallet)\n        }\n      },\n      onClickForgetPassword: async () => {\n        const [hasDualInvest, hasVault] = await Promise.all([\n          LoopringAPI.defiAPI?.getDualTransactions(\n            {\n              accountId: account.accountId,\n              settlementStatuses: SETTLEMENT_STATUS.UNSETTLED,\n              investmentStatuses: [\n                LABEL_INVESTMENT_STATUS.CANCELLED,\n                LABEL_INVESTMENT_STATUS.SUCCESS,\n                LABEL_INVESTMENT_STATUS.PROCESSED,\n                LABEL_INVESTMENT_STATUS.PROCESSING,\n              ].join(','),\n              retryStatuses: [DUAL_RETRY_STATUS.RETRYING],\n            } as any,\n             \"\",\n          ).then(res => res.totalNum && res.totalNum > 0),\n          LoopringAPI.vaultAPI?.getVaultInfoAndBalance(\n            {\n              accountId: account.accountId,\n              },\n             \"\",\n          ).then(res => {\n            return res.accountStatus === VaultAccountStatus.IN_STAKING\n          })\n        ])\n        const hasPortalOrDual = hasDualInvest || hasVault\n        if (hasPortalOrDual) {\n          setShowAccount({\n            step: AccountStep.Coinbase_Smart_Wallet_Password_Forget_Password_Confirm,\n            isShow: true,\n          })\n        } else {\n          setShowAccount({\n            step: AccountStep.Coinbase_Smart_Wallet_Password_Forget_Password,\n            isShow: true,\n          })\n        }\n      },\n      onInputPassword: () => {\n        setShowPasswordMismatchError(false)\n      },\n      showPasswordMismatchError\n    },\n    \n    forgetPasswordConfirmProps: {\n      t,\n      onClickConfirm: () => {\n        setShowAccount({\n          isShow: false,\n        })\n      },\n      onClickBack: () => {\n        setShowAccount({\n          step: AccountStep.Coinbase_Smart_Wallet_Password_Input,\n          isShow: true,\n        })\n      },\n    },\n    forgetPasswordProps: {\n      t,\n      onClickConfirm: async () => {\n        setShowAccount({\n          isShow: false,\n        })\n        \n\n        const feeInfoRes = await LoopringAPI.userAPI?.getOffchainFeeAmt({\n          accountId: account.accountId,\n          requestType: OffchainFeeReqType.UPDATE_ACCOUNT,\n        }, '')\n        \n        const foundFeeKey = keys(feeInfoRes?.fees).find((key) => {\n          const bal = BigNumber.from(walletLayer2?.[key].total || 0).sub(walletLayer2?.[key].locked || 0)\n          return feeInfoRes?.fees?.[key]?.fee && bal.gte(feeInfoRes?.fees?.[key]?.fee) \n        })\n        \n        if (foundFeeKey && walletLayer2) {\n          const foundFeeInfo = feeInfoRes?.fees[foundFeeKey]\n          const mapped = offchainFeeInfoToFeeInfo(foundFeeInfo!, tokenMap, walletLayer2)\n          setShowAccount({\n            step: AccountStep.Coinbase_Smart_Wallet_Password_Set,\n            isShow: true,\n            info: {\n              feeInfo: mapped,\n            }\n          })\n\n        }\n        \n      },\n    },\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/useCollectionAdvanceMeta.ts",
    "content": "import {\n  CollectionMeta,\n  CollectionMetaJSON,\n  myLog,\n  SDK_ERROR_MAP_TO_UI,\n  UIERROR_CODE,\n} from '@loopring-web/common-resources'\nimport { CollectionAdvanceProps, ToastType, useOpenModals } from '@loopring-web/component-lib'\nimport React from 'react'\nimport { useAccount, useModalData, useSystem, useWalletL2Collection } from '../../stores'\nimport { useBtnStatus } from '../index'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { LoopringAPI } from '../../api_wrapper'\nimport { useTranslation } from 'react-i18next'\n\nexport function useCollectionAdvanceMeta<T extends CollectionMeta>({\n  setCollectionToastOpen,\n}: {\n  setCollectionToastOpen: any\n}) {\n  const { allowTrade, chainId } = useSystem()\n  const { setShowCollectionAdvance } = useOpenModals()\n  const { updateWalletL2Collection } = useWalletL2Collection()\n  const { account } = useAccount()\n  const [metaData, setMetaData] = React.useState('')\n  const { t } = useTranslation('common')\n  const {\n    btnStatus,\n    setLabelAndParams,\n    resetBtnInfo,\n    enableBtn,\n    disableBtn,\n    btnInfo,\n    setLoadingBtn,\n  } = useBtnStatus()\n  const { collectionAdvanceValue, updateCollectionAdvanceData } = useModalData()\n  const [error, setError] = React.useState<undefined | { code: UIERROR_CODE; message: string }>(\n    undefined,\n  )\n  const onSubmitClick = React.useCallback(\n    async (_data: T) => {\n      if (\n        !error &&\n        collectionAdvanceValue.name?.trim() &&\n        collectionAdvanceValue.tileUri?.trim() &&\n        LoopringAPI.userAPI\n      ) {\n        setLoadingBtn()\n        try {\n          const response = await LoopringAPI.userAPI.submitNFTCollection(\n            {\n              ...collectionAdvanceValue,\n              name: collectionAdvanceValue.name?.trim(),\n              tileUri: collectionAdvanceValue.tileUri?.trim(),\n              owner: account.accAddress,\n              nftFactory: sdk.NFTFactory_Collection[chainId],\n            } as sdk.CollectionBasicMeta,\n            chainId as any,\n            account.apiKey,\n            account.eddsaKey.sk,\n          )\n          if (\n            response &&\n            ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message)\n          ) {\n            const _response: sdk.RESULT_INFO = response as sdk.RESULT_INFO\n            throw new Error(\n              t(\n                _response.code && SDK_ERROR_MAP_TO_UI[_response.code]\n                  ? SDK_ERROR_MAP_TO_UI[_response.code].messageKey\n                  : SDK_ERROR_MAP_TO_UI[UIERROR_CODE.UNKNOWN].messageKey,\n                { ns: 'error', name: collectionAdvanceValue.name?.trim() },\n              ),\n            )\n          } else {\n            setCollectionToastOpen({\n              open: true,\n              type: 'success',\n              content: t('labelCreateCollectionSuccess'),\n            })\n            updateWalletL2Collection({ page: 1 })\n          }\n        } catch (error) {\n          myLog('error', error)\n          setCollectionToastOpen({\n            open: true,\n            type: ToastType.error,\n            content:\n              t('labelCreateCollectionFailed') +\n              `: ${(error as any)?.message ? (error as any).message : t('errorUnknown')}`,\n          })\n        }\n\n        setShowCollectionAdvance({ isShow: false })\n      }\n      // resetBtnInfo();\n      // disableBtn();\n      setError(undefined)\n      setMetaData('')\n      updateCollectionAdvanceData({})\n    },\n    [collectionAdvanceValue, disableBtn, resetBtnInfo],\n  )\n\n  const updateBtnStatus = React.useCallback(() => {\n    resetBtnInfo()\n    if (!error && collectionAdvanceValue?.name) {\n      enableBtn()\n      return\n    }\n    if (collectionAdvanceValue === undefined || Object.keys(collectionAdvanceValue).length === 0) {\n      setLabelAndParams('labelEnterMeta', {})\n    } else if (error) {\n      setLabelAndParams(SDK_ERROR_MAP_TO_UI[error?.code ?? 700001]?.messageKey, {})\n    } else if (!collectionAdvanceValue?.name) {\n      setLabelAndParams(SDK_ERROR_MAP_TO_UI[700014].messageKey, {})\n    }\n    disableBtn()\n    myLog('try to disable collectionAdvance btn!')\n  }, [error, resetBtnInfo, enableBtn, setLabelAndParams, collectionAdvanceValue, disableBtn])\n\n  React.useEffect(() => {\n    updateBtnStatus()\n  }, [collectionAdvanceValue, error])\n\n  const collectionAdvanceProps: CollectionAdvanceProps<T> = {\n    handleDataChange: (_data) => {\n      setMetaData(_data)\n      try {\n        let _metaDataJSON: CollectionMetaJSON = JSON.parse(_data.replaceAll(/\\n|\\s/gi, ''))\n        const _metaData: sdk.CollectionBasicMeta = {\n          owner: account.accAddress,\n          tileUri: _metaDataJSON?.tile_uri.trim() ?? undefined,\n          name: _metaDataJSON?.name?.trim() ?? undefined,\n          description: _metaDataJSON?.description?.trim() ?? undefined,\n          avatar: _metaDataJSON?.avatar_uri?.trim() ?? undefined,\n          banner: _metaDataJSON?.banner_uri?.trim() ?? undefined,\n        }\n\n        if (!_metaData.tileUri) {\n          setError({\n            code: UIERROR_CODE.ERROR_COLLECTION_METADATA_NO_TILEURI,\n            message: 'empty tileUri',\n          })\n          updateCollectionAdvanceData({})\n          return\n        }\n        if (!_metaData.name) {\n          setError({\n            code: UIERROR_CODE.ERROR_COLLECTION_NO_NAME,\n            message: 'empty name',\n          })\n          updateCollectionAdvanceData({})\n          return\n        }\n        setError(undefined)\n        updateCollectionAdvanceData(_metaData)\n      } catch (_error) {\n        setError({\n          code: UIERROR_CODE.ERROR_JSON_STRINGIFY,\n          message: (_error as any)?.message,\n        })\n        return\n      }\n    },\n    onSubmitClick,\n    allowTrade,\n    disabled: false,\n    btnStatus,\n    btnInfo,\n    metaData,\n  } as CollectionAdvanceProps<T>\n\n  return {\n    collectionAdvanceProps,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/useContact.ts",
    "content": "import React from 'react'\nimport { Contact, NetworkMap, SDK_ERROR_MAP_TO_UI, ToastType } from '@loopring-web/common-resources'\nimport { store, useAccount, useContacts } from '../../stores'\nimport {\n  AccountStep,\n  RawDataTransactionItem,\n  TransactionStatus,\n  useOpenModals,\n  useSettings,\n} from '@loopring-web/component-lib'\nimport { useTranslation } from 'react-i18next'\nimport { connectProvides } from '@loopring-web/web3-provider'\nimport { useToast } from '../common'\nimport { LoopringAPI } from '../../api_wrapper'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { useLocation } from 'react-router-dom'\nimport { volumeToCount, volumeToCountAsBigNumber } from '../help'\n\nconst RowHeight = 78\n\nexport const useContact = ({ viewHeightRatio = 0.85, viewHeightOffset = 130 }) => {\n  // const [addOpen, setAddOpen] = React.useState(false)\n  const [deleteInfo, setDeleteInfo] = React.useState({\n    open: false,\n    selected: undefined as Contact | undefined,\n  })\n  const [sendInfo, setSendInfo] = React.useState({\n    open: false,\n    selected: undefined as Contact | undefined,\n  })\n  const [searchValue, setSearchValue] = React.useState('')\n  const { defaultNetwork } = useSettings()\n  const { setShowAccount, setShowEditContact } = useOpenModals()\n  const [btnLoading, setBtnLoading] = React.useState<{ index: number; loading: boolean }>({\n    loading: false,\n    index: 0,\n  })\n\n  // const cachedForAccountId = useSelector((state: RootState) => state.contacts.currentAccountId)\n  const { t } = useTranslation()\n  const [tableHeight] = React.useState(window.innerHeight * viewHeightRatio - viewHeightOffset)\n  const [page, setPage] = React.useState(1)\n  const pageSize = Math.floor(tableHeight / RowHeight)\n  const { contacts, errorMessage: contactsErrorMessage, updateContacts } = useContacts()\n  const total = contacts?.length\n  const pagination = total\n    ? {\n        page,\n        pageSize,\n        total,\n      }\n    : undefined\n\n  // When localInit when unlock account Failed update contact once?\n  React.useEffect(() => {\n    if (contactsErrorMessage) {\n      updateContacts()\n    }\n  }, [])\n  // const [selectAddress, setSelectAddress] = React.useState<ContactType | undefined>(undefined)\n\n  const onChangeSearch = React.useCallback((input: string) => {\n    setSearchValue(input)\n  }, [])\n  const onClearSearch = React.useCallback(() => {\n    setSearchValue('')\n  }, [])\n  const onClickDelete = React.useCallback((address: string, name: string) => {\n    setDeleteInfo({\n      open: true,\n      selected: {\n        address,\n        name,\n      },\n    })\n  }, [])\n  const onCloseDelete = React.useCallback(() => {\n    setDeleteInfo({\n      open: false,\n      selected: undefined,\n    })\n  }, [])\n\n  const onClickSend = React.useCallback(async (data: Contact, index: number) => {\n    setBtnLoading({ loading: true, index })\n    let isENSWrong = false\n    if (data.contactAddress && data.ens && connectProvides.usedWeb3) {\n      try {\n        const ensAddr = await connectProvides?.usedWeb3.eth?.ens?.getAddress(data.ens)\n        if (ensAddr?.toLowerCase() !== data?.contactAddress?.toLowerCase()) {\n          isENSWrong = true\n        }\n      } catch (e) {\n        console.log('error: ens->address ignore', e)\n      }\n    }\n    // geUpdateContact,\n\n    setShowAccount({\n      isShow: true,\n      step: AccountStep.SendAssetFromContact,\n      info: {\n        ...data,\n        isENSWrong,\n      },\n    })\n    setBtnLoading({ loading: false, index })\n  }, [])\n  const onCloseSend = React.useCallback(() => {\n    setSendInfo({\n      open: false,\n      selected: undefined,\n    })\n  }, [])\n  const { toastOpen, setToastOpen, closeToast } = useToast()\n\n  React.useEffect(() => {\n    if (contactsErrorMessage) {\n      updateContacts()\n    }\n  }, [])\n  const [deleteLoading, setDeleteLoading] = React.useState(false)\n\n  const onPageChange = React.useCallback((page: number) => {\n    setSearchValue('')\n    setPage(page)\n  }, [])\n  const showPagination = total !== undefined && searchValue === ''\n  const submitDeleteContact = React.useCallback(\n    async (address: string, _name: string) => {\n      setDeleteLoading(true)\n      const { accountId, apiKey, isContractAddress, isCFAddress } = store.getState().account\n      const response = await LoopringAPI.contactAPI?.deleteContact(\n        {\n          accountId,\n          isHebao: isContractAddress || isCFAddress ? true : false,\n          contactAddress: address,\n          // @ts-ignore\n          network: NetworkMap[defaultNetwork].walletType,\n        },\n        apiKey,\n      )\n\n      if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n        setToastOpen({\n          open: true,\n          type: ToastType.error,\n          content: t('labelContactsDeleteFailed'),\n        })\n        return\n      }\n      // setPage to page - 1 if there is only one contact on this page when page >= 1\n      if (\n        page > 1 && page === Math.ceil(contacts.length / pageSize) && contacts.length % pageSize === 1 \n      ) {\n        setPage(page - 1)\n      }\n      updateContacts()\n      setToastOpen({\n        open: true,\n        type: ToastType.success,\n        content: t('labelContactsDeleteSuccess'),\n      })\n      setDeleteLoading(false)\n      onCloseDelete()\n      // if(result as sdk.RESULT_INFO)\n    },\n    [contacts, page, pageSize],\n  )\n  return {\n    contacts:\n      contacts &&\n      (searchValue === ''\n        ? contacts.slice(\n            (page - 1) * pageSize,\n            page * pageSize >= contacts.length ? contacts.length : page * pageSize,\n          )\n        : contacts.filter((contact) => {\n            return (\n              contact.contactAddress.toLowerCase().includes(searchValue.toLowerCase()) ||\n              contact.contactName.toLowerCase().includes(searchValue.toLowerCase())\n            )\n          })),\n    // selectAddress,\n    // setSelectAddress,\n    onChangeSearch,\n    onClearSearch,\n    searchValue,\n    toastInfo: toastOpen,\n    setToast: setToastOpen,\n    closeToast,\n    onClickDelete,\n    deleteInfo,\n    onCloseDelete,\n    submitDeleteContact,\n    deleteLoading,\n    setShowEditContact,\n    onClickSend,\n    onCloseSend,\n    sendInfo,\n    pagination,\n    onPageChange,\n    showPagination,\n    btnLoading,\n  }\n}\n\ntype TxsFilterProps = {\n  // accountId: number;\n  tokenSymbol?: string\n  start?: number\n  end?: number\n  offset?: number\n  limit?: number\n  types?: sdk.UserTxTypes[] | string\n}\n\nexport function useContractRecord(setToastOpen: (state: any) => void) {\n  const {\n    account: { accountId, apiKey },\n  } = useAccount()\n  const { tokenMap } = store.getState().tokenMap\n  const { t } = useTranslation(['error'])\n  const [txs, setTxs] = React.useState<RawDataTransactionItem[]>([])\n  const [txsTotal, setTxsTotal] = React.useState(0)\n  const [showLoading, setShowLoading] = React.useState(false)\n  const { search } = useLocation()\n  const searchParams = new URLSearchParams(search)\n\n  const getTxnStatus = (status: string) => {\n    return status === ''\n      ? TransactionStatus.processing\n      : status === 'PROCESSED'\n      ? TransactionStatus.processed\n      : status === 'PROCESSING'\n      ? TransactionStatus.processing\n      : status === 'RECEIVED'\n      ? TransactionStatus.received\n      : TransactionStatus.failed\n  }\n\n  const getUserTxnList = React.useCallback(\n    async ({ tokenSymbol, start, end, limit, offset }: TxsFilterProps) => {\n      // const address = routeMatch.params[0];\n      const tokenId = tokenSymbol ? tokenMap[tokenSymbol!].tokenId : undefined\n      const response = await LoopringAPI.userAPI!.getUserBills(\n        {\n          accountId,\n          tokenSymbol,\n          tokenId,\n          fromAddress: searchParams?.get('contactAddress') ?? '',\n          transferAddress: searchParams?.get('contactAddress') ?? '',\n          start,\n          end,\n          limit,\n          offset,\n          // @ts-ignore\n          billType: '1,2,4',\n        },\n        apiKey,\n      )\n      if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n        const errorItem = SDK_ERROR_MAP_TO_UI[(response as sdk.RESULT_INFO)?.code ?? 700001]\n        setToastOpen({\n          open: true,\n          type: ToastType.error,\n          content:\n            'error : ' + errorItem\n              ? t(errorItem.messageKey)\n              : (response as sdk.RESULT_INFO).message,\n        })\n      } else {\n        const formattedList: RawDataTransactionItem[] = (response as any).raw_data.bills.map(\n          (o: any) => {\n            const feePrecision = tokenMap ? tokenMap[o.tokenF].precision : undefined\n            return {\n              ...o,\n              txType: o.billType,\n              side: o.billType as any,\n              amount: {\n                unit: o.token || '',\n                value: Number(volumeToCount(o.token, o.amount)),\n              },\n              fee: {\n                unit: o.tokenF || '',\n                value: Number(volumeToCountAsBigNumber(o.tokenF, o.amountF || 0)),\n              },\n              memo: o.memo || '',\n              time: o.timestamp,\n              txnHash: o.hash,\n              status: getTxnStatus(o.status),\n              feePrecision: feePrecision,\n              receiverAddress: o.to,\n              senderAddress: o.from,\n            } as RawDataTransactionItem\n          },\n        )\n        setTxs(formattedList)\n\n        setTxsTotal(response.totalNum)\n        setShowLoading(false)\n      }\n    },\n    [accountId, apiKey, t, tokenMap],\n  )\n\n  return {\n    txs,\n    txsTotal,\n    showLoading,\n    getUserTxnList,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/useContactAdd.tsx",
    "content": "import React from 'react'\nimport {\n  AddressError,\n  EXCHANGE_TYPE,\n  HEBAO_CONTRACT_MAP,\n  myLog,\n  NetworkMap,\n  SDK_ERROR_MAP_TO_UI,\n  TradeBtnStatus,\n  UIERROR_CODE,\n  WALLET_TYPE,\n  Contact,\n} from '@loopring-web/common-resources'\nimport { useTranslation } from 'react-i18next'\nimport {\n  addressToExWalletMapFn,\n  exWalletToAddressMapFn,\n  LoopringAPI,\n  store,\n  useAddressCheck,\n  useContacts,\n  useSubmitBtn,\n} from '@loopring-web/core'\nimport { ToastType, useSettings, useOpenModals } from '@loopring-web/component-lib'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nexport const useContactAdd = () => {\n  const { t } = useTranslation()\n  const [loading, setLoading] = React.useState(false)\n  const [isNameExit, setIsNameExit] = React.useState(false)\n  const [isContactExit, setIsContactExit] = React.useState(false)\n  const [isEdit, setIsEdit] = React.useState<{ item: Contact & { isENSWrong: boolean } } | false>(\n    false,\n  )\n  const {\n    modals: { isShowEditContact },\n    setShowOtherExchange,\n    setShowGlobalToast,\n    setShowEditContact,\n  } = useOpenModals()\n  const {\n    address,\n    realAddr,\n    setAddress,\n    addrStatus,\n    isCFAddress: addressTypeISCFAddress,\n    isContractAddress,\n    isAddressCheckLoading,\n    loopringSmartWalletVersion,\n    ens,\n    // isENSWrong,\n  } = useAddressCheck(false)\n  const { contacts, updateContacts } = useContacts()\n  const [addName, setAddName] = React.useState('')\n\n  const [selectedAddressType, setSelectedAddressType] = React.useState<\n    WALLET_TYPE | EXCHANGE_TYPE | undefined\n  >(undefined)\n  const allowToClickIsSure = React.useMemo(() => {\n    return isAddressCheckLoading || addrStatus === AddressError.InvalidAddr || !realAddr\n  }, [addrStatus, isAddressCheckLoading, realAddr])\n  const mapContactAddressType = React.useCallback(():\n    | (typeof sdk.AddressType)[sdk.AddressTypeKeys]\n    | undefined => {\n    if (addressTypeISCFAddress) {\n      return sdk.AddressType.LOOPRING_HEBAO_CF\n    } else if (loopringSmartWalletVersion?.isLoopringSmartWallet) {\n      const item = HEBAO_CONTRACT_MAP.find(\n        (item) => item[0] === loopringSmartWalletVersion?.version,\n      )\n      return (\n        item ? item[1] : /V2_/.test(loopringSmartWalletVersion?.version ?? '') ? 2002 : undefined\n      ) as any\n    } else if (isContractAddress) {\n      return sdk.AddressType.CONTRACT\n    } else if (selectedAddressType) {\n      return exWalletToAddressMapFn(selectedAddressType)\n    }\n  }, [\n    addressTypeISCFAddress,\n    isContractAddress,\n    loopringSmartWalletVersion?.isLoopringSmartWallet,\n    loopringSmartWalletVersion?.version,\n    selectedAddressType,\n  ])\n  const autoSetWalletType = () => {\n    if (realAddr && selectedAddressType == undefined) {\n      const addressType = mapContactAddressType()\n      if (addressType) {\n        const type = addressToExWalletMapFn(addressType)\n        myLog('onChangeAddressType before', type)\n        onChangeAddressType(type)\n      } else if (isEdit && isEdit.item.addressType) {\n        const type = addressToExWalletMapFn(isEdit.item.addressType)\n        myLog('onChangeAddressType before isEdit', type)\n        onChangeAddressType(type)\n      } else {\n        onChangeAddressType(undefined)\n      }\n    }\n  }\n  const onSubmit = React.useCallback(async () => {\n    setLoading(true)\n    const { accountId, apiKey, isContractAddress, isCFAddress } = store.getState().account\n\n    let createContact: sdk.CreateContactRequest | sdk.UpdateContactRequest = {\n      contactAddress: realAddr,\n      accountId,\n      contactName: addName,\n      isHebao: !!(isContractAddress || isCFAddress),\n      network: NetworkMap[defaultNetwork].walletType,\n      ens: isEdit?.item?.isENSWrong ? '' : isEdit ? isEdit?.item.ens : ens,\n    } as any\n    createContact = {\n      ...createContact,\n      addressType: mapContactAddressType(),\n    }\n    if (isEdit) {\n      try {\n        const response = await LoopringAPI.contactAPI?.updateContact(createContact, apiKey)\n        if (\n          response &&\n          ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message)\n        ) {\n          throw {\n            code: (response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message,\n          }\n        }\n        setShowGlobalToast({\n          isShow: true,\n          info: {\n            type: ToastType.success,\n            content: t('labelContactsEditSuccess'),\n          },\n        })\n        restData()\n        setShowEditContact({\n          isShow: false,\n        })\n      } catch (error) {\n        const _error = LoopringAPI?.globalAPI?.genErr(error as unknown as any) ?? {}\n        error = {\n          ...((error as any) ?? {}),\n          ..._error,\n        }\n        if ((error as any)?.code == sdk.LoopringErrorCode.HTTP_ERROR) {\n          setShowGlobalToast({\n            isShow: true,\n            info: {\n              type: ToastType.error,\n              content: t(SDK_ERROR_MAP_TO_UI[UIERROR_CODE.TIME_OUT].messageKey, { ns: 'error' }),\n            },\n          })\n        } else if ((error as any)?.code) {\n          setShowGlobalToast({\n            isShow: true,\n            info: {\n              type: ToastType.error,\n              content: t(\n                SDK_ERROR_MAP_TO_UI[(error as any)?.code]?.messageKey ?? 'labelContactsEditFailed',\n                { ns: 'error' },\n              ),\n            },\n          })\n        } else {\n          setShowGlobalToast({\n            isShow: true,\n            info: {\n              type: ToastType.error,\n              content: t('labelContactsEditFailed'),\n            },\n          })\n        }\n      }\n    } else {\n      try {\n        const response = await LoopringAPI.contactAPI?.createContact(createContact as any, apiKey)\n        if (\n          response &&\n          ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message)\n        ) {\n          throw {\n            code: (response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message,\n          }\n        }\n\n        setShowGlobalToast({\n          isShow: true,\n          info: {\n            type: ToastType.success,\n            content: t('labelContactsAddSuccess'),\n          },\n        })\n\n        restData()\n        setShowEditContact({\n          isShow: false,\n        })\n      } catch (error) {\n        const _error = LoopringAPI?.globalAPI?.genErr(error as unknown as any) ?? {}\n        error = {\n          ...((error as any) ?? {}),\n          ..._error,\n        }\n        if ((error as any)?.code == sdk.LoopringErrorCode.HTTP_ERROR) {\n          setShowGlobalToast({\n            isShow: true,\n            info: {\n              type: ToastType.error,\n              content: t(SDK_ERROR_MAP_TO_UI[UIERROR_CODE.TIME_OUT].messageKey, { ns: 'error' }),\n            },\n          })\n        } else if ((error as any)?.code) {\n          setShowGlobalToast({\n            isShow: true,\n            info: {\n              type: ToastType.error,\n              content: t(\n                SDK_ERROR_MAP_TO_UI[(error as any)?.code]?.messageKey ?? 'labelContactsAddFailed',\n                { ns: 'error' },\n              ),\n            },\n          })\n        } else {\n          setShowGlobalToast({\n            isShow: true,\n            info: {\n              type: ToastType.error,\n              content: t('labelContactsAddFailed'),\n            },\n          })\n        }\n      }\n      setLoading(false)\n    }\n  }, [realAddr, addName, mapContactAddressType, isEdit, t])\n  React.useEffect(() => {\n    if (realAddr && addName && realAddr !== '' && !isAddressCheckLoading) {\n      autoSetWalletType()\n    }\n    const list = contacts?.filter((item) => {\n      return isEdit\n        ? isEdit?.item?.contactAddress?.toLowerCase() !== item?.contactAddress?.toLowerCase()\n        : true\n    })\n\n    if (addName && list?.find((item) => item.contactName === addName)) {\n      setIsNameExit(true)\n    } else {\n      setIsNameExit(false)\n    }\n    if (list?.find((item) => item.contactAddress.toLowerCase() === realAddr.toLowerCase())) {\n      setIsContactExit(true)\n    } else {\n      setIsContactExit(false)\n    }\n  }, [realAddr, isAddressCheckLoading, addName])\n  const availableTradeCheck = React.useCallback((): {\n    tradeBtnStatus: TradeBtnStatus\n    label: string | undefined\n  } => {\n    if (realAddr && addName) {\n      if (isContactExit) {\n        return {\n          label: `labelContactAddressExisted`,\n          tradeBtnStatus: TradeBtnStatus.DISABLED,\n        }\n      } else if (isNameExit) {\n        return {\n          label: `labelContactNameExisted`,\n          tradeBtnStatus: TradeBtnStatus.DISABLED,\n        }\n      } else {\n        return {\n          label: undefined,\n          tradeBtnStatus: TradeBtnStatus.AVAILABLE,\n        }\n      }\n    }\n    return {\n      label: undefined,\n      tradeBtnStatus: TradeBtnStatus.DISABLED,\n    }\n  }, [realAddr, addName, isNameExit, isContactExit])\n\n  const { btnStatus, onBtnClick, btnLabel } = useSubmitBtn({\n    availableTradeCheck,\n    isLoading: isAddressCheckLoading || loading,\n    submitCallback: onSubmit,\n  })\n  React.useEffect(() => {\n    if (isShowEditContact.isShow) {\n      if (isShowEditContact?.info?.contactName) {\n        setIsEdit(() => {\n          return { item: isShowEditContact.info }\n        })\n        onChangeName(isShowEditContact.info.contactName)\n        onChangeAddressType(\n          addressToExWalletMapFn(isShowEditContact.info?.addressType ?? undefined),\n        )\n        onChangeAddress(isShowEditContact.info?.contactAddress)\n        // if (isShowEditContact?.info?.contactAddress ) {\n        //   onChangeAddress((isEdit as EditItem)?.item.contactAddress)\n        // }\n      } else {\n        setIsEdit(false)\n      }\n    } else {\n      restData()\n    }\n\n    setLoading(false)\n  }, [isShowEditContact.isShow])\n\n  const detectedWalletType = loopringSmartWalletVersion?.isLoopringSmartWallet\n    ? WALLET_TYPE.Loopring\n    : isContractAddress\n    ? WALLET_TYPE.OtherSmart\n    : WALLET_TYPE.EOA\n  const onChangeAddress = (input: string) => {\n    setAddress(input)\n    setSelectedAddressType(undefined)\n  }\n  const onChangeName = (input: string) => {\n    if (new TextEncoder().encode(input).length <= 48) {\n      setAddName(input)\n    }\n  }\n  const onChangeAddressType = (value: WALLET_TYPE | EXCHANGE_TYPE | undefined) => {\n    myLog('onChangeAddressType', value)\n    setSelectedAddressType(value)\n  }\n  const restData = () => {\n    onChangeAddress('')\n    onChangeName('')\n    onChangeAddressType(undefined)\n    setSelectedAddressType(undefined)\n    setLoading(false)\n    updateContacts()\n    setShowOtherExchange({ agree: false, isShow: false })\n  }\n\n  const { defaultNetwork } = useSettings()\n\n  return {\n    contactAddProps: {\n      isEdit,\n      contacts,\n      restData,\n      selectedAddressType,\n      detectedWalletType,\n      addressDefault: address,\n      isAddressCheckLoading,\n      onChangeAddress,\n      addName,\n      onChangeName,\n      realAddr,\n      addrStatus,\n      handleOnAddressChange: onChangeAddress,\n      allowToClickIsSure,\n      onChangeAddressType,\n      btnStatus,\n      isNameExit,\n      isContactExit,\n      btnLabel,\n      submitContact: onBtnClick,\n      isENSWrong: isEdit?.item?.isENSWrong,\n    },\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/useCreateRedPacket.ts",
    "content": "import {\n  AccountStatus,\n  AssetsRawDataItem,\n  Explorer,\n  FeeInfo,\n  getValuePrecisionThousand,\n  LIVE_FEE_TIMES,\n  myLog,\n  NFTWholeINFO,\n  REDPACKET_ORDER_LIMIT,\n  REDPACKET_ORDER_NFT_LIMIT,\n  RedPacketOrderData,\n  SUBMIT_PANEL_AUTO_CLOSE,\n  TOAST_TIME,\n  UIERROR_CODE,\n  WalletMap,\n  BLINDBOX_REDPACKET_LIMIT,\n  RedPacketOrderType,\n  EXCLUSIVE_REDPACKET_ORDER_LIMIT_WHITELIST,\n  EXCLUSIVE_REDPACKET_ORDER_LIMIT,\n  MapChainId,\n  isAddress,\n} from '@loopring-web/common-resources'\nimport { NETWORKEXTEND, store, useAccount, useModalData, useNotify, useSystem, useTokenMap } from '../../stores'\nimport {\n  AccountStep,\n  CreateRedPacketProps,\n  RedPacketViewStep,\n  SwitchData,\n  useOpenModals,\n  useSettings,\n  useToggle,\n} from '@loopring-web/component-lib'\nimport React, { useCallback } from 'react'\nimport { makeWalletLayer2 } from '../help'\nimport { useChargeFees, useWalletLayer2Socket, walletLayer2Service } from '../../services'\nimport { useBtnStatus } from '../common'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { LoopringAPI } from '../../api_wrapper'\nimport { ConnectProvidersSignMap, connectProvides } from '@loopring-web/web3-provider'\nimport { getTimestampDaysLater } from '../../utils'\nimport { DAYS } from '../../defs'\nimport Web3 from 'web3'\nimport { isAccActivated } from './useCheckAccStatus'\nimport { useWalletInfo } from '../../stores/localStore/walletInfo'\nimport { useRedPacketConfig } from '../../stores/redPacket'\nimport { useHistory, useLocation } from 'react-router-dom'\nimport moment from 'moment'\nconst checkPermission = (\n  dexToggle: any,\n  info: { network: string; functionName: string; accAddress: string },\n) => {\n  const whiteList = dexToggle.whiteList\n  const { functionName, network, accAddress } = info\n  const toogle = dexToggle[functionName]\n  if (toogle.enable) {\n    return true\n  } else if (!toogle.enable && toogle.reason === 'no view') {\n    const found =\n      whiteList &&\n      whiteList[network].find((item: any) => item.superUserFunction.includes('redpacket_exclusive'))\n    return (\n      found &&\n      found.superUserAddress.find(\n        (addr) => addr.toLocaleLowerCase() === accAddress.toLocaleLowerCase(),\n      )\n    )\n  } else {\n    return false\n  }\n}\nexport const useCreateRedPacket = <\n  T extends RedPacketOrderData<I>,\n  I,\n  F = FeeInfo,\n  NFT = NFTWholeINFO,\n>({\n  assetsRawData,\n  isShow = false,\n}: {\n  assetsRawData: AssetsRawDataItem[]\n  isShow?: boolean\n}): {\n  createRedPacketProps: CreateRedPacketProps<T, I, F, NFT>\n  retryBtn: (isHardware?: boolean) => void\n} => {\n  const { exchangeInfo, chainId } = useSystem()\n  const { tokenMap, totalCoinMap, idIndex } = useTokenMap()\n  const { notifyMap } = useNotify()\n  // const tradeType\n  const {\n    allowTrade: { transfer: transferEnabale },\n  } = useSystem()\n  const {\n    setShowAccount,\n    setShowRedPacket,\n    modals: {\n      isShowAccount: { info },\n    },\n  } = useOpenModals()\n  const [selectNFT, setSelectNFT] = React.useState<NFT | undefined>(undefined)\n\n  const { redPacketConfigs } = useRedPacketConfig()\n  const { redPacketOrder, updateRedPacketOrder } = useModalData()\n  const { account, status: accountStatus } = useAccount()\n  const { checkHWAddr, updateHW } = useWalletInfo()\n  const isToken =\n    redPacketOrder.tradeType === RedPacketOrderType.TOKEN ||\n    (redPacketOrder.tradeType === RedPacketOrderType.BlindBox && !redPacketOrder.nftData)\n  const feeProps = isToken\n    ? {\n        requestType: sdk.OffchainFeeReqType.EXTRA_TYPES,\n        extraType: 1,\n      }\n    : {\n        requestType: sdk.OffchainNFTFeeReqType.EXTRA_TYPES,\n        tokenAddress: redPacketOrder?.tokenAddress,\n        extraType: 1,\n        isNFT: true,\n      }\n\n  const {\n    chargeFeeTokenList,\n    isFeeNotEnough,\n    handleFeeChange,\n    feeInfo,\n    checkFeeIsEnough,\n    resetIntervalTime,\n  } = useChargeFees({\n    ...feeProps,\n    intervalTime: undefined,\n    updateData: ({ fee }) => {\n      const redPacketOrder = store.getState()._router_modalData.redPacketOrder\n      updateRedPacketOrder({ ...(redPacketOrder as any), fee: fee })\n      const isToken =\n        redPacketOrder.tradeType === RedPacketOrderType.TOKEN ||\n        (redPacketOrder.tradeType === RedPacketOrderType.BlindBox && !redPacketOrder.nftData)\n      if ((isToken && !feeProps.isNFT) || (!isToken && feeProps.isNFT)) {\n        updateRedPacketOrder({ ...(redPacketOrder as any), fee: fee })\n      }\n    },\n  })\n\n  const [walletMap, setWalletMap] = React.useState(\n    makeWalletLayer2({ needFilterZero: true }).walletMap ?? ({} as WalletMap<T>),\n  )\n  const walletLayer2Callback = React.useCallback(() => {\n    const walletMap = makeWalletLayer2({ needFilterZero: true }).walletMap ?? {}\n    setWalletMap(walletMap)\n    const redPacketOrder = store.getState()._router_modalData.redPacketOrder\n    if (\n      RedPacketOrderType.TOKEN === redPacketOrder.tradeType &&\n      !redPacketOrder.belong &&\n      walletMap\n    ) {\n      resetDefault(RedPacketOrderType.TOKEN)\n    } else if (\n      RedPacketOrderType.TOKEN === redPacketOrder.tradeType &&\n      walletMap &&\n      redPacketOrder.belong &&\n      walletMap[redPacketOrder.belong]\n    ) {\n      handleOnDataChange({\n        balance: walletMap[redPacketOrder.belong]?.count,\n      } as T)\n    }\n  }, [redPacketOrder, accountStatus])\n  const handleOnDataChange = React.useCallback(\n    (tradeData: Partial<T>) => {\n      const redPacketOrder = store.getState()._router_modalData.redPacketOrder\n      updateRedPacketOrder({ ...redPacketOrder, ...tradeData })\n    },\n    [updateRedPacketOrder],\n  )\n  const resetDefault = React.useCallback(\n    (value: RedPacketOrderType) => {\n      if (info?.isRetry) {\n        checkFeeIsEnough()\n        return\n      }\n      const walletMap = makeWalletLayer2({ needFilterZero: true }).walletMap ?? {}\n      const isToken =\n        value === RedPacketOrderType.TOKEN ||\n        (value === RedPacketOrderType.BlindBox && !redPacketOrder.isNFT)\n      if (isToken && !redPacketOrder.belong && walletMap) {\n        const keys = Reflect.ownKeys(walletMap)\n        for (let key in keys) {\n          const keyVal = keys[key]\n          const walletInfo = walletMap[keyVal.toString()]\n          if (sdk.toBig(walletInfo?.count ?? '0').gt(0)) {\n            updateRedPacketOrder({\n              belong: keyVal as any,\n              tradeValue: undefined,\n              fee: feeInfo,\n              balance: walletInfo?.count,\n              memo: '',\n              numbers: undefined,\n              giftNumbers: undefined,\n              validUntil: moment().add('days', 1).toDate().getTime(),\n              validSince: Date.now(),\n              tradeType: value,\n              isNFT: false,\n            } as unknown as T)\n            break\n          }\n        }\n      } else if (isToken && redPacketOrder.belong && walletMap) {\n        const walletInfo = walletMap[redPacketOrder.belong]\n        updateRedPacketOrder({\n          fee: feeInfo,\n          belong: redPacketOrder.belong as any,\n          tradeValue: undefined as any,\n          balance: walletInfo?.count,\n          memo: '',\n          numbers: undefined,\n          giftNumbers: undefined,\n          validSince: Date.now(),\n          validUntil: moment().add('days', 1).toDate().getTime(),\n          tradeType: value,\n          isNFT: false,\n        } as unknown as T)\n      } else if (!isToken) {\n        updateRedPacketOrder({\n          fee: feeInfo,\n          belong: undefined,\n          tradeValue: undefined,\n          balance: undefined,\n          giftNumbers: undefined,\n          memo: '',\n          numbers: undefined,\n          validSince: Date.now(),\n          validUntil: moment().add('days', 1).toDate().getTime(),\n          tradeType: value,\n          isNFT: true,\n        } as unknown as T)\n      } else {\n        updateRedPacketOrder({\n          fee: feeInfo,\n          belong: redPacketOrder.belong,\n          tradeValue: undefined,\n          balance: undefined,\n          giftNumbers: undefined,\n          memo: '',\n          numbers: undefined,\n          validSince: Date.now(),\n          validUntil: moment().add('days', 1).toDate().getTime(),\n          tradeType: 'TOKEN',\n          isNFT: false,\n        } as unknown as T)\n      }\n    },\n    [\n      checkFeeIsEnough,\n      walletMap,\n      handleOnDataChange,\n      feeInfo,\n      redPacketOrder.belong,\n      info?.isRetry,\n    ],\n  )\n  useWalletLayer2Socket({ walletLayer2Callback })\n\n  const { btnStatus, enableBtn, disableBtn, setLabelAndParams, resetBtnInfo, btnInfo } =\n    useBtnStatus()\n\n  const calcNumberAndAmount = React.useCallback(() => {\n    const redPacketOrder = store.getState()._router_modalData.redPacketOrder as T\n    if (redPacketOrder.type?.partition === sdk.LuckyTokenAmountType.RANDOM) {\n      const eachValue = sdk.toBig(redPacketOrder?.tradeValue ?? 0).div(redPacketOrder.numbers ?? 1)\n      const isToken =\n        redPacketOrder.tradeType === RedPacketOrderType.TOKEN ||\n        (redPacketOrder.tradeType === RedPacketOrderType.BlindBox && !redPacketOrder.nftData)\n      return {\n        tradeValue: redPacketOrder?.tradeValue,\n        eachValue: isToken ? eachValue.toString() : eachValue.toFixed(),\n      }\n    } else {\n      return {\n        tradeValue: sdk.toBig(redPacketOrder?.tradeValue ?? 0).times(redPacketOrder.numbers ?? 1),\n        eachValue: redPacketOrder?.tradeValue,\n      }\n    }\n  }, [])\n  const history = useHistory()\n\n  const checkBtnStatus = React.useCallback(() => {\n    const _tradeData = calcNumberAndAmount()\n    resetBtnInfo()\n    if (\n      tokenMap &&\n      chargeFeeTokenList.length &&\n      !isFeeNotEnough.isFeeNotEnough &&\n      redPacketOrder.fee &&\n      redPacketOrder.fee?.belong &&\n      redPacketOrder.numbers &&\n      redPacketOrder.numbers > 0 &&\n      redPacketOrder.validUntil &&\n      // redPacketOrder.numbers <= REDPACKET_ORDER_LIMIT &&\n      _tradeData.tradeValue\n      // &&\n      // redPacketOrder.memo &&\n      // redPacketOrder.memo?.trim().length > 0\n    ) {\n      let tradeToken: any = {},\n        balance,\n        tradeValue,\n        isExceedBalance,\n        tooSmall,\n        tooLarge\n      const feeToken = tokenMap[redPacketOrder.fee.belong]\n      const feeRaw = redPacketOrder.fee.feeRaw ?? redPacketOrder.fee.__raw__?.feeRaw ?? 0\n      const fee = sdk.toBig(feeRaw)\n      const blindBoxGiftsEqualsZero =\n        redPacketOrder.type?.mode === sdk.LuckyTokenClaimType.BLIND_BOX &&\n        sdk.toBig(redPacketOrder.giftNumbers ?? '0').isZero()\n      const blindBoxGiftsLargerThanPackets =\n        redPacketOrder.type?.mode === sdk.LuckyTokenClaimType.BLIND_BOX &&\n        sdk.toBig(redPacketOrder.giftNumbers ?? '0').isGreaterThan(redPacketOrder.numbers)\n      const blindBoxPacketsNumberTooLarge =\n        redPacketOrder.type?.mode === sdk.LuckyTokenClaimType.BLIND_BOX &&\n        sdk.toBig(redPacketOrder.numbers).isGreaterThan(BLINDBOX_REDPACKET_LIMIT)\n      // @ts-ignore\n      const isToken =\n        redPacketOrder.tradeType === RedPacketOrderType.TOKEN ||\n        (redPacketOrder.tradeType === RedPacketOrderType.BlindBox && !redPacketOrder.nftData)\n      if (isToken && redPacketOrder.belong && tokenMap[(redPacketOrder as T).belong as any]) {\n        tradeToken = tokenMap[(redPacketOrder as T).belong as any]\n        balance = sdk.toBig((redPacketOrder as T).balance ?? 0).times('1e' + tradeToken.decimals)\n        tradeValue = sdk.toBig(_tradeData.tradeValue ?? 0).times('1e' + tradeToken.decimals)\n        isExceedBalance = tradeValue\n          .plus(feeToken.tokenId === tradeToken.tokenId ? fee : '0')\n          .gt(balance)\n        const eachValue = sdk.toBig(_tradeData.eachValue ?? 0).times('1e' + tradeToken.decimals)\n        tooSmall = eachValue.lt(tradeToken.luckyTokenAmounts?.minimum ?? 0)\n        tooLarge = tradeValue.gt(tradeToken.luckyTokenAmounts.maximum)\n      } else {\n        balance = redPacketOrder.balance ?? 0\n        tradeValue = sdk.toBig(redPacketOrder.tradeValue ?? 0)\n        if (redPacketOrder.type?.partition === sdk.LuckyTokenAmountType.AVERAGE) {\n          // console.log('isExceedBalance = tradeValue.times(redPacketOrder.giftNumbers ?? 1).gt(balance)', redPacketOrder.numbers, balance, tradeValue.toString())\n          isExceedBalance = tradeValue.times(redPacketOrder.numbers ?? 1).gt(balance)\n        } else {\n          isExceedBalance = tradeValue.gt(balance)\n        }\n        const eachValue =\n          redPacketOrder.type?.mode === sdk.LuckyTokenClaimType.BLIND_BOX\n            ? sdk.toBig(redPacketOrder.tradeValue ?? 0).div(redPacketOrder.giftNumbers ?? 1)\n            : sdk.toBig(_tradeData.eachValue ?? 0)\n        tooSmall = eachValue.lt(1)\n        tooLarge = tradeValue\n          .div(\n            redPacketOrder.type?.partition === sdk.LuckyTokenAmountType.AVERAGE\n              ? 1\n              : redPacketOrder.type?.mode === sdk.LuckyTokenClaimType.BLIND_BOX\n              ? redPacketOrder.giftNumbers ?? 1\n              : redPacketOrder.numbers ?? 1,\n          )\n          .gt(REDPACKET_ORDER_NFT_LIMIT)\n      }\n\n      if (\n        tradeValue &&\n        !isExceedBalance &&\n        !tooSmall &&\n        !tooLarge &&\n        ((!isToken && redPacketOrder.nftData) ||\n          // @ts-ignore\n          isToken) &&\n        redPacketConfigs?.luckTokenAgents &&\n        !blindBoxGiftsEqualsZero &&\n        !blindBoxGiftsLargerThanPackets &&\n        !blindBoxPacketsNumberTooLarge &&\n        redPacketOrder.numbers <= redpacketNumberLimit\n      ) {\n        enableBtn()\n        return\n      } else {\n        disableBtn()\n        if (blindBoxGiftsEqualsZero) {\n          setLabelAndParams('labelRedPacketsGiftsEqualsZero', {})\n        } else if (!redPacketConfigs?.luckTokenAgents) {\n          setLabelAndParams('labelRedPacketWaitingBlock', {})\n        } else if (isExceedBalance) {\n          setLabelAndParams('labelRedPacketsInsufficient', {\n            symbol: isToken ? (tradeToken.symbol as string) : 'NFT',\n          })\n        } else if (\n          isExceedBalance &&\n          (redPacketOrder as T).tradeType === RedPacketOrderType.TOKEN &&\n          feeToken.tokenId === tradeToken.tokenId\n        ) {\n          setLabelAndParams('labelReserveFee', {\n            symbol: tradeToken.symbol as string,\n          })\n        } else if (isFeeNotEnough.isFeeNotEnough) {\n          setLabelAndParams('labelRedPacketFee', {})\n        } else if (tooSmall) {\n          setLabelAndParams(\n            'labelRedPacketsMin',\n            isToken\n              ? tradeToken &&\n                  tradeToken.decimals && {\n                    value: getValuePrecisionThousand(\n                      sdk\n                        .toBig(tradeToken.luckyTokenAmounts?.minimum ?? '0')\n                        .div('1e' + tradeToken.decimals),\n                      tradeToken.precision,\n                      tradeToken.precision,\n                      tradeToken.precision,\n                      false,\n                      { floor: false, isAbbreviate: true },\n                    ),\n                    symbol: tradeToken.symbol,\n                  }\n              : {\n                  value:\n                    redPacketOrder.type?.mode === sdk.LuckyTokenClaimType.BLIND_BOX\n                      ? redPacketOrder.giftNumbers\n                      : redPacketOrder.type?.partition === sdk.LuckyTokenAmountType.AVERAGE\n                      ? 1\n                      : redPacketOrder.numbers,\n                  symbol: 'NFT',\n                },\n          )\n        } else if (redPacketOrder.numbers > redpacketNumberLimit) {\n          setLabelAndParams('labelRedPacketsSplitNumber', {\n            value: redpacketNumberLimit.toString(),\n          })\n        } else if (tooLarge) {\n          setLabelAndParams(\n            'labelRedPacketsMax',\n            (redPacketOrder as T).tradeType === RedPacketOrderType.TOKEN && tradeToken\n              ? {\n                  value: getValuePrecisionThousand(\n                    sdk\n                      .toBig(tradeToken.luckyTokenAmounts.maximu ?? 0)\n                      .div('1e' + tradeToken.decimals),\n                    tradeToken.precision,\n                    tradeToken.precision,\n                    tradeToken.precision,\n                    false,\n                    { floor: true, isAbbreviate: true },\n                  ),\n                  symbol: tradeToken.symbol,\n                }\n              : {\n                  value: sdk\n                    .toBig(REDPACKET_ORDER_NFT_LIMIT)\n                    .times(\n                      redPacketOrder.type?.mode === sdk.LuckyTokenClaimType.BLIND_BOX\n                        ? redPacketOrder.giftNumbers ?? 1\n                        : redPacketOrder.type?.partition === sdk.LuckyTokenAmountType.AVERAGE\n                        ? 1\n                        : redPacketOrder.numbers ?? 1,\n                    ),\n                  symbol: 'NFT',\n                },\n          )\n        } else if (blindBoxGiftsLargerThanPackets) {\n          setLabelAndParams('labelRedPacketsGiftsLargerThanPackets', {})\n        } else if (blindBoxPacketsNumberTooLarge) {\n          setLabelAndParams('labelBlindBoxNumberOverMaximun', {})\n        }\n      }\n    }\n    disableBtn()\n  }, [\n    chargeFeeTokenList.length,\n    disableBtn,\n    enableBtn,\n    isFeeNotEnough.isFeeNotEnough,\n    tokenMap,\n    redPacketOrder.balance,\n    redPacketOrder.belong,\n    redPacketOrder.fee,\n    redPacketOrder.tradeValue,\n    redPacketOrder.numbers,\n    redPacketOrder.memo,\n    redPacketConfigs?.luckTokenAgents,\n    redPacketOrder.giftNumbers,\n    redPacketOrder.validSince,\n    redPacketOrder.validUntil,\n  ])\n\n  React.useEffect(() => {\n    checkBtnStatus()\n  }, [\n    chargeFeeTokenList,\n    isFeeNotEnough.isFeeNotEnough,\n    redPacketOrder?.numbers,\n    redPacketOrder.balance,\n    redPacketOrder.belong,\n    redPacketOrder.fee,\n    redPacketOrder.tradeValue,\n    redPacketOrder.memo,\n    redPacketConfigs?.luckTokenAgents,\n    redPacketOrder.validSince,\n    redPacketOrder.validUntil,\n    redPacketOrder?.giftNumbers,\n  ])\n  const processRequest = React.useCallback(\n    async (request: sdk.LuckyTokenItemForSendV3, isNotHardwareWallet: boolean) => {\n      const { apiKey, connectName, eddsaKey } = account\n      const redPacketOrder = store.getState()._router_modalData.redPacketOrder\n\n      try {\n        if (connectProvides.usedWeb3 && LoopringAPI.luckTokenAPI && isAccActivated()) {\n          let isHWAddr = checkHWAddr(account.accAddress)\n          if (!isHWAddr && !isNotHardwareWallet) {\n            isHWAddr = true\n          }\n          updateRedPacketOrder({\n            ...redPacketOrder,\n            __request__: request,\n          } as any)\n\n          const response = await LoopringAPI.luckTokenAPI.sendLuckTokenSend(\n            {\n              request,\n              web3: connectProvides.usedWeb3 as unknown as Web3,\n              chainId: chainId === NETWORKEXTEND.NONETWORK ? sdk.ChainId.MAINNET : chainId,\n              walletType: (ConnectProvidersSignMap[connectName] ??\n                connectName) as unknown as sdk.ConnectorNames,\n              eddsaKey: eddsaKey.sk,\n              apiKey,\n              isHWAddr,\n            },\n            {\n              accountId: account.accountId,\n              counterFactualInfo: eddsaKey.counterFactualInfo,\n            },\n          )\n\n          myLog('submit sendLuckTokenSend:', response)\n          if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n            throw response\n          }\n          // setIsConfirmTransfer(false);\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.RedPacketSend_In_Progress,\n          })\n          await sdk.sleep(TOAST_TIME)\n          if (redPacketOrder.type?.scope === sdk.LuckyTokenViewType.TARGET) {\n            setShowAccount({\n              isShow: false,\n            })\n            handleOnDataChange({\n              target: {\n                redpacketHash: (response as sdk.TX_HASH_API)?.hash,\n                maxSendCount: request.numbers,\n              },\n            } as any)\n            getTargetRedpackets()\n          } else {\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.RedPacketSend_Success,\n              info: {\n                scope: request.type.scope,\n                hash: Explorer + `tx/${(response as sdk.TX_HASH_API)?.hash}-transfer`,\n                shared:\n                  request.type.scope == sdk.LuckyTokenViewType.PUBLIC\n                    ? () => {\n                        LoopringAPI.luckTokenAPI\n                          ?.getLuckTokenDetail(\n                            {\n                              hash: (response as sdk.TX_HASH_API).hash!,\n                            },\n                            apiKey,\n                          )\n                          .then((response) => {\n                            setShowAccount({ isShow: false })\n                            setShowRedPacket({\n                              isShow: true,\n                              info: {\n                                ...response.detail.luckyToken,\n                              },\n                              step: RedPacketViewStep.QRCodePanel,\n                            })\n                          })\n                      }\n                    : undefined,\n              },\n            })\n\n            if (isHWAddr) {\n              myLog('......try to set isHWAddr', isHWAddr)\n              updateHW({ wallet: account.accAddress, isHWAddr })\n            }\n            walletLayer2Service.sendUserUpdate()\n            history.push(`/redpacket?redPacketHash=${(response as sdk.TX_HASH_API)?.hash}`)\n            resetDefault(RedPacketOrderType.TOKEN)\n            if (\n              request.type.scope == sdk.LuckyTokenViewType.PRIVATE &&\n              (response as sdk.TX_HASH_API)?.hash\n            ) {\n              setShowAccount({ isShow: false })\n              const blindBoxRepspnse = (await LoopringAPI.luckTokenAPI.getBlindBoxDetail(\n                {\n                  hash: (response as sdk.TX_HASH_API).hash!,\n                  showHelper: false,\n                },\n                apiKey,\n              )) as any\n              setShowRedPacket({\n                isShow: true,\n                info: {\n                  ...blindBoxRepspnse.raw_data.luckyToken,\n                  hash: (response as sdk.TX_HASH_API).hash,\n                },\n                step: RedPacketViewStep.QRCodePanel,\n              })\n            } else {\n              await sdk.sleep(SUBMIT_PANEL_AUTO_CLOSE)\n              if (\n                store.getState().modals.isShowAccount.isShow &&\n                store.getState().modals.isShowAccount.step == AccountStep.RedPacketSend_Success\n              ) {\n                setShowAccount({ isShow: false })\n              }\n            }\n          }\n        }\n      } catch (e: any) {\n        const code = sdk.checkErrorInfo(e, isNotHardwareWallet)\n        switch (code) {\n          case sdk.ConnectorError.NOT_SUPPORT_ERROR:\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.RedPacketSend_First_Method_Denied,\n            })\n            break\n          case sdk.ConnectorError.USER_DENIED:\n          case sdk.ConnectorError.USER_DENIED_2:\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.RedPacketSend_User_Denied,\n            })\n            break\n          default:\n            if ([102024, 102025, 114001, 114002].includes((e as sdk.RESULT_INFO)?.code || 0)) {\n              checkFeeIsEnough({ isRequiredAPI: true })\n            }\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.RedPacketSend_Failed,\n              error: {\n                code: UIERROR_CODE.UNKNOWN,\n                msg: e?.message,\n                ...(e instanceof Error\n                  ? {\n                      message: e?.message,\n                      stack: e?.stack,\n                    }\n                  : e ?? {}),\n              },\n            })\n\n            break\n        }\n      }\n    },\n    [\n      account,\n      checkHWAddr,\n      chainId,\n      setShowAccount,\n      redPacketOrder.belong,\n      checkFeeIsEnough,\n      resetDefault,\n      updateHW,\n    ],\n  )\n  React.useEffect(() => {\n    if (isShow) {\n      resetDefault(RedPacketOrderType.BlindBox)\n      walletLayer2Service.sendUserUpdate()\n    }\n  }, [isShow])\n  React.useEffect(() => {\n    ;(async () => {\n      if (redPacketOrder.target?.redpacketHash) {\n        const response = await LoopringAPI.luckTokenAPI?.getLuckTokenDetail(\n          {\n            hash: redPacketOrder.target?.redpacketHash,\n          },\n          account.apiKey,\n        )\n        const targets = (response?.detail as any).targets as string[]\n        handleOnDataChange({\n          target: {\n            ...redPacketOrder.target,\n            sentAddresses: targets,\n          },\n        } as any)\n      }\n    })()\n  }, [redPacketOrder.target?.redpacketHash])\n  React.useEffect(() => {\n    if (isShow) {\n      checkFeeIsEnough({ isRequiredAPI: true, intervalTime: LIVE_FEE_TIMES })\n    } else {\n      resetIntervalTime()\n    }\n    return () => {\n      resetIntervalTime()\n    }\n  }, [isShow, redPacketOrder.tradeType])\n\n  const onCreateRedPacketClick = React.useCallback(\n    async (_redPacketOrder, isHardwareRetry: boolean = false) => {\n      const { accountId, accAddress, readyState, apiKey, eddsaKey } = account\n      const redPacketOrder = store.getState()._router_modalData.redPacketOrder as T\n      const _tradeData = calcNumberAndAmount()\n      const isToken =\n        redPacketOrder.tradeType === RedPacketOrderType.TOKEN ||\n        (redPacketOrder.tradeType === RedPacketOrderType.BlindBox && !redPacketOrder.isNFT)\n\n      if (\n        readyState === AccountStatus.ACTIVATED &&\n        LoopringAPI.userAPI &&\n        tokenMap &&\n        exchangeInfo &&\n        chargeFeeTokenList.length &&\n        !isFeeNotEnough.isFeeNotEnough &&\n        redPacketOrder.belong &&\n        (!isToken ? redPacketOrder.nftData : tokenMap[redPacketOrder.belong]) &&\n        redPacketOrder.fee &&\n        redPacketOrder.fee.belong &&\n        redPacketOrder.fee?.__raw__ &&\n        redPacketOrder.numbers &&\n        redPacketOrder.numbers > 0 &&\n        _tradeData.tradeValue &&\n        redPacketOrder.type &&\n        // redPacketOrder.memo &&\n        redPacketOrder?.validUntil &&\n        redPacketConfigs?.luckTokenAgents &&\n        // redPacketOrder.memo?.trim().length > 0 &&\n        eddsaKey?.sk\n      ) {\n        try {\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.RedPacketSend_WaitForAuth,\n          })\n          let tradeToken, tradeValue\n          if (!isToken) {\n            tradeToken = {\n              tokenId: redPacketOrder.tokenId,\n              nftDta: redPacketOrder.nftData,\n            }\n            tradeValue = sdk.toBig(_tradeData.tradeValue)\n          } else {\n            //@ts-ignore\n            tradeToken = tokenMap[redPacketOrder.belong.toString()]\n            tradeValue = sdk.toBig(_tradeData.tradeValue ?? 0).times('1e' + tradeToken.decimals)\n          }\n          const feeToken = tokenMap[redPacketOrder.fee.belong]\n          const feeRaw = redPacketOrder.fee.feeRaw ?? redPacketOrder.fee.__raw__?.feeRaw ?? 0\n          const fee = sdk.toBig(feeRaw)\n\n          const storageId = await LoopringAPI.userAPI.getNextStorageId(\n            {\n              accountId,\n              sellTokenId: Number(tradeToken.tokenId),\n            },\n            apiKey,\n          )\n          // const { broker } = await LoopringAPI.userAPI.getAvailableBroker({\n          //   type: 1,\n          // });\n          myLog('memo', redPacketOrder.memo)\n\n          const req: sdk.LuckyTokenItemForSendV3 = {\n            type: {\n              ...redPacketOrder.type,\n              mode:\n                redPacketOrder.tradeType === RedPacketOrderType.BlindBox\n                  ? sdk.LuckyTokenClaimType.BLIND_BOX\n                  : redPacketOrder.tradeType === RedPacketOrderType.NFT\n                  ? sdk.LuckyTokenClaimType.COMMON\n                  : // @ts-ignore\n                    redPacketOrder.type?.mode ?? sdk.LuckyTokenClaimType.COMMON,\n            },\n            numbers: redPacketOrder.numbers,\n            giftNumbers: redPacketOrder.giftNumbers!,\n            memo: redPacketOrder.memo ? redPacketOrder.memo : 'Best wishes',\n            signerFlag: false as any,\n            nftData: isToken ? undefined : redPacketOrder.nftData,\n            // @ts-ignore\n            templateId: 0,\n            validSince: Math.round((redPacketOrder.validSince ?? Date.now()) / 1000),\n            validUntil: Math.round((redPacketOrder.validUntil ?? Date.now()) / 1000),\n            luckyToken: {\n              exchange: exchangeInfo.exchangeAddress,\n              payerAddr: accAddress,\n              payerId: accountId,\n              payeeAddr: Reflect.ownKeys(redPacketConfigs.luckTokenAgents ?? {})[0],\n              storageId: storageId?.offchainId,\n              token: tradeToken.tokenId,\n              amount: tradeValue.toFixed(),\n              feeToken: feeToken.tokenId,\n              maxFeeAmount: fee.toFixed(),\n              validUntil: getTimestampDaysLater(DAYS - 1),\n            } as any,\n          }\n\n          myLog('transfer req:', req)\n\n          processRequest(req, !isHardwareRetry)\n        } catch (e: any) {\n          // transfer failed\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.RedPacketSend_Failed,\n            error: {\n              code: UIERROR_CODE.UNKNOWN,\n              message: e.message,\n            } as sdk.RESULT_INFO,\n          })\n        }\n      } else {\n        return\n      }\n    },\n    [\n      account,\n      tokenMap,\n      exchangeInfo,\n      setShowAccount,\n      processRequest,\n      redPacketConfigs?.luckTokenAgents,\n    ],\n  )\n  const onSendTargetRedpacketClick = React.useCallback(async () => {\n    const { readyState } = account\n    const redPacketOrder = store.getState()._router_modalData.redPacketOrder as T\n\n    const getValidAddresses = (input: string) => {\n      return input\n        .split(';')\n        .map((str) => str.trim())\n        .filter((str) => {\n          return isAddress(str.trim())\n        })\n    }\n\n    if (\n      readyState === AccountStatus.ACTIVATED &&\n      LoopringAPI.luckTokenAPI &&\n      redPacketOrder.target?.redpacketHash &&\n      getValidAddresses(redPacketOrder.target?.addressListString).length > 0 &&\n      redPacketOrder.target?.addressListString\n    ) {\n      try {\n        setShowAccount({\n          isShow: true,\n          step: AccountStep.RedPacketSend_WaitForAuth,\n        })\n        const response = await LoopringAPI.luckTokenAPI.sendLuckTokenSubmitAddTarget(\n          {\n            claimer: getValidAddresses(redPacketOrder.target?.addressListString),\n            hash: redPacketOrder.target?.redpacketHash,\n            notifyType: isWhiteListed\n              ? redPacketOrder.target?.popupChecked === undefined ||\n                redPacketOrder.target?.popupChecked\n                ? 1\n                : 0\n              : 0,\n          },\n          account.eddsaKey.sk,\n          account.apiKey,\n        )\n        if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n          throw response\n        }\n        setShowAccount({\n          isShow: true,\n          step: AccountStep.RedPacketSend_Success,\n          info: {\n            scope: sdk.LuckyTokenViewType.TARGET,\n          },\n        })\n        getTargetRedpackets()\n      } catch (e: any) {\n        setShowAccount({\n          isShow: true,\n          step: AccountStep.RedPacketSend_Failed,\n          error: {\n            code: UIERROR_CODE.UNKNOWN,\n            message: e.message,\n          } as sdk.RESULT_INFO,\n        })\n      }\n    } else {\n      return\n    }\n  }, [\n    account.readyState,\n    redPacketOrder.target?.redpacketHash,\n    redPacketOrder.target?.addressListString,\n  ])\n\n  const handlePanelEvent = useCallback(\n    async (data: SwitchData<Partial<T>>) => {\n      return new Promise<void>((res: any) => {\n        if (data.to === 'button') {\n          if (walletMap && data?.tradeData?.belong) {\n            const walletInfo = walletMap[data?.tradeData?.belong as string]\n            handleOnDataChange({\n              belong: data.tradeData?.belong,\n              tradeValue: data.tradeData?.tradeValue,\n              balance: walletInfo ? walletInfo.count : 0,\n            } as T)\n          } else {\n            handleOnDataChange({\n              belong: undefined,\n              tradeValue: undefined,\n              balance: undefined,\n            } as unknown as T)\n          }\n        }\n        res()\n      })\n    },\n    [walletMap],\n  )\n  const [isWhiteListed, setIsWhiteListed] = React.useState(undefined as undefined | boolean)\n  const redpacketNumberLimit =\n    redPacketOrder.type?.scope === sdk.LuckyTokenViewType.TARGET\n      ? isWhiteListed\n        ? EXCLUSIVE_REDPACKET_ORDER_LIMIT_WHITELIST\n        : EXCLUSIVE_REDPACKET_ORDER_LIMIT\n      : isToken\n      ? REDPACKET_ORDER_LIMIT\n      : REDPACKET_ORDER_NFT_LIMIT\n\n  const [minimum, maximum] = React.useMemo(() => {\n    if (redPacketOrder.tradeType === RedPacketOrderType.NFT) {\n      const minimum = sdk\n        .toBig(redPacketOrder?.tradeValue ?? 0)\n        .div(REDPACKET_ORDER_NFT_LIMIT)\n        .toFixed(0, 1)\n\n      const maximum =\n        redPacketOrder?.balance &&\n        // @ts-ignore\n        sdk.toBig(redPacketOrder.balance ?? 0).lt(redpacketNumberLimit)\n          ? // @ts-ignore\n            redPacketOrder?.tradeValue ?? redPacketOrder.balance\n          : redpacketNumberLimit\n      return [minimum ? 1 : minimum, maximum]\n    } else {\n      if (redPacketOrder.belong && tokenMap[redPacketOrder.belong]) {\n        const { minimum, maximum } = tokenMap[redPacketOrder.belong].luckyTokenAmounts\n        const decimals = tokenMap[redPacketOrder.belong].decimals\n        return [\n          sdk\n            .toBig(minimum ?? 0)\n            .div('1e' + decimals)\n            .toString(),\n          sdk\n            .toBig(maximum ?? 0)\n            .div('1e' + decimals)\n            .toString(),\n        ]\n      } else {\n        return [undefined, undefined]\n      }\n    }\n  }, [redPacketOrder?.belong, tokenMap, redPacketOrder.tradeType])\n  const retryBtn = React.useCallback(\n    (isHardwareRetry: boolean = false) => {\n      setShowAccount({\n        isShow: true,\n        step: AccountStep.RedPacketSend_WaitForAuth,\n      })\n      onCreateRedPacketClick({}, isHardwareRetry)\n    },\n    [processRequest, setShowAccount],\n  )\n  const location = useLocation()\n  React.useEffect(() => {\n    ;(async () => {\n      const nftDatas = new URLSearchParams(location.search).get('nftDatas')\n      if (nftDatas) {\n        updateRedPacketOrder({\n          ...redPacketOrder,\n          tradeType: RedPacketOrderType.FromNFT,\n          isNFT: true,\n        })\n        const info = await LoopringAPI.nftAPI?.getInfoForNFTTokens({\n          nftDatas: [nftDatas],\n        })\n        if (info && info[nftDatas]) {\n          const balance = await LoopringAPI.userAPI?.getUserNFTBalances(\n            {\n              accountId: account.accountId,\n              nftDatas: nftDatas,\n              metadata: true,\n            },\n            account.apiKey,\n          )\n          const balanceInfo = balance!.userNFTBalances[0]\n          handleOnDataChange({\n            collectionInfo: balanceInfo.collectionInfo,\n            tokenId: balanceInfo.tokenId,\n            tradeValue: undefined,\n            balance: balanceInfo.total,\n            nftData: balanceInfo.nftData,\n            belong: balanceInfo.metadata?.base.name,\n            tokenAddress: balanceInfo.tokenAddress,\n            image: balanceInfo?.metadata?.imageSize && balanceInfo?.metadata?.imageSize['240-240'],\n          } as T)\n        }\n      }\n    })()\n  }, [location.search])\n\n  const [targetRedPackets, setTargetRedPackets] = React.useState(\n    [] as sdk.LuckyTokenItemForReceive[],\n  )\n  const [popRedPacket, setPopRedPacket] = React.useState(\n    undefined as sdk.LuckTokenClaimDetail | undefined,\n  )\n  const tokenInfo = popRedPacket && tokenMap[idIndex[popRedPacket.luckyToken.tokenId]]\n\n  const popRedPacketAmountStr = popRedPacket\n    ? popRedPacket.luckyToken.isNft\n      ? `${popRedPacket.luckyToken.tokenAmount.totalAmount} NFTs`\n      : tokenInfo &&\n        getValuePrecisionThousand(\n          sdk\n            .toBig(popRedPacket.luckyToken.tokenAmount.totalAmount)\n            .div('1e' + tokenInfo!.decimals),\n          tokenInfo!.precision,\n          tokenInfo!.precision,\n          tokenInfo!.precision,\n          false,\n        ) +\n          ' ' +\n          tokenInfo?.symbol\n    : undefined\n\n  const getTargetRedpackets = async () => {\n    const response = await LoopringAPI.luckTokenAPI?.getLuckTokenLuckyTokens(\n      {\n        senderId: account.accountId,\n        scopes: '2',\n        modes: '0,1,2',\n        partitions: '0,1',\n        statuses: '2',\n        official: false,\n        offset: 0,\n        limit: 100,\n        isEnough: true,\n      } as any,\n      account.apiKey,\n    )\n    setTargetRedPackets(response?.list ?? [])\n  }\n  React.useEffect(() => {\n    getTargetRedpackets()\n    ;(async () => {\n      const response = await LoopringAPI.luckTokenAPI?.getLuckTokenAuthorizedSigners()\n      const found = (response?.raw_data as any)?.find(\n        (item) => item.owner.toLocaleLowerCase() === account.accAddress.toLocaleLowerCase(),\n      )\n      setIsWhiteListed(found ? true : false)\n    })()\n  }, [])\n\n  const onClickViewTargetDetail = React.useCallback(async (hash: string) => {\n    const response = await LoopringAPI.luckTokenAPI?.getLuckTokenDetail(\n      {\n        hash: hash,\n      },\n      account.apiKey,\n    )\n    setPopRedPacket(response?.detail)\n  }, [])\n  const onCloseRedpacketPop = React.useCallback(async () => {\n    setPopRedPacket(undefined)\n  }, [])\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const { toggle } = useToggle()\n\n  const showExclusiveOption = checkPermission(toggle, {\n    accAddress: account.accAddress,\n    network,\n    functionName: 'redpacket_exclusive',\n  })\n\n  const createRedPacketProps: CreateRedPacketProps<T, I, F> = {\n    redPacketConfig: notifyMap?.redPacket ?? {},\n    tradeType: redPacketOrder.tradeType,\n    chargeFeeTokenList,\n    onCreateRedPacketClick,\n    btnStatus,\n    btnInfo,\n    disabled: transferEnabale?.enable == true,\n    assetsData: assetsRawData,\n    walletMap,\n    coinMap: totalCoinMap,\n    tokenMap,\n    idIndex,\n    minimum,\n    maximum,\n    feeInfo: redPacketOrder.fee ?? feeInfo,\n    handleFeeChange,\n    tradeData: redPacketOrder as T,\n    handleOnDataChange,\n    handlePanelEvent,\n    selectNFT,\n    handleOnChoose: (_value: NFT) => {\n      setSelectNFT(_value as NFT)\n      if (_value) {\n        const value = _value as any\n        handleOnDataChange({\n          collectionInfo: value.collectionInfo,\n          tokenId: value.tokenId,\n          tradeValue: undefined,\n          balance: value.nftBalance ?? value.total,\n          nftData: value.nftData,\n          belong: value.name,\n          tokenAddress: value.tokenAddress,\n          image: value?.metadata?.imageSize ? value?.metadata?.imageSize['240-240'] : value.image,\n        } as T)\n      }\n    },\n    selectNFTDisabled: redPacketOrder.tradeType === RedPacketOrderType.FromNFT,\n    onSendTargetRedpacketClick,\n    targetRedPackets,\n    popRedPacket,\n    popRedPacketAmountStr,\n    onClickViewTargetDetail,\n    onCloseRedpacketPop,\n    isWhiteListed,\n    showExclusiveOption,\n  } as unknown as CreateRedPacketProps<T, I, F, NFT>\n\n  return { createRedPacketProps, retryBtn }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/useDefiTrade.ts",
    "content": "import React from 'react'\nimport {\n  DeFiWrapProps,\n  ToastType,\n  useOpenModals,\n  useSettings,\n  useToggle,\n} from '@loopring-web/component-lib'\nimport {\n  AccountStatus,\n  CustomErrorWithCode,\n  DEFI_CONFIG,\n  LEVERAGE_ETH_CONFIG,\n  DeFiCalcData,\n  DeFiChgType,\n  getValuePrecisionThousand,\n  globalSetup,\n  IBData,\n  MapChainId,\n  MarketType,\n  myLog,\n  SDK_ERROR_MAP_TO_UI,\n  TradeBtnStatus,\n  TradeDefi,\n} from '@loopring-web/common-resources'\n\nimport _ from 'lodash'\n\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nimport {\n  DAYS,\n  getTimestampDaysLater,\n  LoopringAPI,\n  store,\n  useAccount,\n  useSystem,\n  useTokenMap,\n  walletLayer2Service,\n  makeWalletLayer2,\n  useSubmitBtn,\n  useWalletLayer2Socket,\n  useDefiMap,\n  useTradeDefi,\n} from '../../index'\nimport { useTranslation } from 'react-i18next'\n\nexport const useDefiTrade = <T extends IBData<I>, I, ACD extends DeFiCalcData<T>>({\n  isJoin = true,\n  isLeverageETH = false,\n  market,\n  setToastOpen,\n  setServerUpdate,\n  setConfirmShowNoBalance,\n  confirmShowLimitBalance,\n  setConfirmShowLimitBalance,\n}: {\n  market: string\n  isJoin: boolean\n  isLeverageETH: boolean\n  setServerUpdate: (state: any) => void\n  setConfirmShowLimitBalance: (state: boolean) => void\n  setConfirmShowNoBalance: (state: boolean) => void\n  confirmShowLimitBalance: boolean\n  setToastOpen: (props: { open: boolean; content: JSX.Element | string; type: ToastType }) => void\n}) => {\n  const { t } = useTranslation(['common'])\n  const refreshRef = React.createRef()\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const { marketMap, marketLeverageMap, updateDefiSyncMap } = useDefiMap()\n  const [isLoading, setIsLoading] = React.useState(false)\n  const [isStoB, setIsStoB] = React.useState(true)\n\n  const { tokenMap } = useTokenMap()\n  const { account } = useAccount()\n  // const { status: walletLayer2Status } = useWalletLayer2();\n  const { exchangeInfo, allowTrade } = useSystem()\n  const { updateTradeDefi, resetTradeDefi } = useTradeDefi()\n  const { setShowSupport, setShowTradeIsFrozen, setShowETHStakingApr } = useOpenModals()\n\n  const { toggle } = useToggle()\n  const [{ coinSellSymbol, coinBuySymbol }, setSymbol] = React.useState(() => {\n    if (isJoin) {\n      const [, coinBuySymbol, coinSellSymbol] = market.match(/(\\w+)-(\\w+)/i) ?? []\n      return { coinBuySymbol, coinSellSymbol }\n    } else {\n      const [, coinSellSymbol, coinBuySymbol] = market.match(/(\\w+)-(\\w+)/i) ?? []\n      return { coinBuySymbol, coinSellSymbol }\n    }\n  })\n\n  const getFee = React.useCallback(\n    async (\n      requestType: sdk.OffchainFeeReqType.DEFI_JOIN | sdk.OffchainFeeReqType.DEFI_EXIT,\n    ): Promise<{ fee: string; feeRaw: string } | undefined> => {\n      if (\n        LoopringAPI.userAPI &&\n        coinSellSymbol &&\n        account.readyState === AccountStatus.ACTIVATED &&\n        tokenMap\n      ) {\n        const feeToken: sdk.TokenInfo = tokenMap[coinBuySymbol]\n\n        const request: sdk.GetOffchainFeeAmtRequest = {\n          accountId: account.accountId,\n          requestType,\n          market,\n        }\n\n        const { fees } = await LoopringAPI.userAPI.getOffchainFeeAmt(request, account.apiKey)\n\n        const feeRaw = fees[coinBuySymbol] ? fees[coinBuySymbol].fee : '0'\n        const fee = sdk\n          .toBig(feeRaw)\n          .div('1e' + feeToken.decimals)\n          .toString()\n\n        myLog('new fee:', fee.toString())\n        return {\n          fee: fee,\n          feeRaw: feeRaw,\n          // fees,\n        }\n      }\n    },\n    [\n      coinSellSymbol,\n      account.readyState,\n      account.accountId,\n      account.apiKey,\n      tokenMap,\n      coinBuySymbol,\n      market,\n    ],\n  )\n\n  const handleOnchange = _.debounce(\n    ({\n      tradeData,\n      type,\n      _tradeDefi = {},\n    }: {\n      type: DeFiChgType\n      tradeData: T\n      _tradeDefi?: Partial<TradeDefi<T>>\n    }) => {\n      const marketInfo = (isLeverageETH ? marketLeverageMap : marketMap)[market]\n      let calcValue, feeRaw, fee\n      let newTradeDefi = {\n        ...store.getState()._router_tradeDefi.tradeDefi,\n        ..._tradeDefi,\n      }\n      let _deFiCalcData: DeFiCalcData<T> = newTradeDefi.deFiCalcData as unknown as DeFiCalcData<T>\n      if (\n        tradeData &&\n        newTradeDefi.defiBalances &&\n        coinBuySymbol &&\n        newTradeDefi?.defiBalances[coinBuySymbol]\n      ) {\n        const inputValue =\n          type === DeFiChgType.coinSell\n            ? {\n                sellAmount: tradeData?.tradeValue?.toString() ?? '0',\n              }\n            : {\n                buyAmount: tradeData?.tradeValue?.toString() ?? '0',\n              }\n        const buyTokenBalanceVol: string = newTradeDefi?.defiBalances[coinBuySymbol] ?? ''\n        calcValue = sdk.calcDefi({\n          isJoin,\n          isInputSell: type === DeFiChgType.coinSell,\n          ...inputValue,\n          maxFeeBips:\n            (isLeverageETH ? marketLeverageMap : marketMap)[market]?.extra?.maxFeeBips ?? 5,\n          defaultFee: newTradeDefi.defaultFee,\n          marketInfo,\n          tokenSell: tokenMap[coinSellSymbol],\n          tokenBuy: tokenMap[coinBuySymbol],\n          buyTokenBalanceVol,\n          withdrawFeeBips: (isLeverageETH ? marketLeverageMap : marketMap)[market]?.extra\n            ?.withdrawFeeBips,\n        })\n\n        const sellAmount =\n          tradeData?.tradeValue === undefined\n            ? undefined\n            : getValuePrecisionThousand(\n                sdk.toBig(calcValue?.sellVol ?? 0).div('1e' + tokenMap[coinSellSymbol]?.decimals),\n                tokenMap[coinSellSymbol].precision,\n                tokenMap[coinSellSymbol].precision,\n                tokenMap[coinSellSymbol].precision,\n                false,\n                { floor: false },\n              ).replaceAll(sdk.SEP, '')\n        const buyAmount =\n          tradeData?.tradeValue === undefined\n            ? undefined\n            : getValuePrecisionThousand(\n                sdk.toBig(calcValue?.buyVol ?? 0).div('1e' + tokenMap[coinBuySymbol]?.decimals),\n                tokenMap[coinBuySymbol].precision,\n                tokenMap[coinBuySymbol].precision,\n                tokenMap[coinBuySymbol].precision,\n                true,\n                { floor: true },\n              ).replaceAll(sdk.SEP, '')\n        if (sdk.toBig(newTradeDefi.defaultFee).gt(0)) {\n          feeRaw = isNaN(calcValue.feeVol) ? '0' : calcValue.feeVol\n          fee = sdk\n            .toBig(feeRaw)\n            .div('1e' + tokenMap[coinBuySymbol].decimals)\n            .toString()\n        } else {\n          feeRaw = '0'\n          fee = '0'\n        }\n\n        // @ts-ignore\n        _deFiCalcData = {\n          ..._deFiCalcData,\n          fee,\n          coinSell:\n            type === DeFiChgType.coinSell\n              ? tradeData\n              : { ..._deFiCalcData?.coinSell, tradeValue: sellAmount },\n          coinBuy:\n            type === DeFiChgType.coinBuy\n              ? tradeData\n              : { ..._deFiCalcData?.coinBuy, tradeValue: buyAmount },\n        }\n      }\n      updateTradeDefi({\n        market: newTradeDefi.market !== market ? (market as MarketType) : undefined,\n        ...newTradeDefi,\n        type: marketInfo.type,\n        ...calcValue,\n        feeRaw,\n        fee,\n        deFiCalcData: {\n          ..._deFiCalcData,\n        },\n        lastInput: type,\n      })\n    },\n    globalSetup.wait,\n  )\n  const availableTradeCheck = React.useCallback((): {\n    tradeBtnStatus: TradeBtnStatus\n    label: string\n  } => {\n    const account = store.getState().account\n    const tradeDefi = store.getState()._router_tradeDefi.tradeDefi\n\n    if (account.readyState === AccountStatus.ACTIVATED) {\n      const sellExceed = sdk\n        .toBig(tradeDefi.deFiCalcData?.coinSell?.tradeValue ?? 0)\n        .gt(tradeDefi.deFiCalcData?.coinSell?.balance ?? 0)\n      if (\n        tradeDefi?.sellVol === undefined ||\n        sdk.toBig(tradeDefi?.sellVol).lte(0) ||\n        tradeDefi?.buyVol === undefined ||\n        sdk.toBig(tradeDefi?.buyVol).lte(0) ||\n        tradeDefi?.maxFeeBips === undefined ||\n        tradeDefi?.maxFeeBips === 0\n      ) {\n        return {\n          tradeBtnStatus: TradeBtnStatus.DISABLED,\n          label: 'labelEnterAmount',\n        }\n      } else if (sdk.toBig(tradeDefi?.fee ?? 0).lte(0)) {\n        return {\n          tradeBtnStatus: TradeBtnStatus.DISABLED,\n          label: `labelFeeCalculating`,\n        }\n      } else if (\n        sdk\n          .toBig(tradeDefi?.sellVol)\n          .minus(tradeDefi?.miniSellVol ?? 0)\n          .lt(0)\n      ) {\n        return {\n          tradeBtnStatus: TradeBtnStatus.DISABLED,\n          label: `labelDefiMin| ${getValuePrecisionThousand(\n            sdk.toBig(tradeDefi?.miniSellVol ?? 0).div('1e' + tokenMap[coinSellSymbol]?.decimals),\n            tokenMap[coinSellSymbol].precision,\n            tokenMap[coinSellSymbol].precision,\n            tokenMap[coinSellSymbol].precision,\n            false,\n            { floor: false, isAbbreviate: true },\n          )} ${coinSellSymbol}`,\n        }\n      } else if (sellExceed) {\n        return {\n          tradeBtnStatus: TradeBtnStatus.DISABLED,\n          label: `labelDefiNoEnough| ${coinSellSymbol}`,\n        }\n      } else {\n        return { tradeBtnStatus: TradeBtnStatus.AVAILABLE, label: '' } // label: ''}\n      }\n    }\n    return { tradeBtnStatus: TradeBtnStatus.AVAILABLE, label: '' }\n  }, [market, tokenMap, coinSellSymbol])\n\n  const resetDefault = React.useCallback(\n    async (clearTrade: boolean = false, { defaultFee }: { defaultFee?: any }) => {\n      let walletMap: any = {}\n      const tradeDefi = store.getState()._router_tradeDefi.tradeDefi\n      const [, baseSymbol, quoteSymbol] = market.match(/(\\w+)-(\\w+)/i) ?? []\n      const { marketLeverageMap, marketMap } = store.getState().invest.defiMap\n      const marketInfo = isLeverageETH ? marketLeverageMap[market] : marketMap[market]\n      let deFiCalcDataInit: Partial<DeFiCalcData<any>> = {\n        ...tradeDefi.deFiCalcData,\n        coinSell: {\n          belong: coinSellSymbol,\n          balance: undefined,\n          tradeValue:\n            tradeDefi.deFiCalcData?.coinSell?.belong === coinSellSymbol\n              ? tradeDefi.deFiCalcData?.coinSell?.tradeValue\n              : undefined,\n        },\n        coinBuy: {\n          belong: coinBuySymbol,\n          balance: undefined,\n          tradeValue:\n            tradeDefi.deFiCalcData?.coinBuy?.belong === coinBuySymbol\n              ? tradeDefi.deFiCalcData?.coinBuy?.tradeValue\n              : undefined,\n        },\n      }\n\n      if (account.readyState === AccountStatus.ACTIVATED) {\n        if (clearTrade) {\n          walletLayer2Service.sendUserUpdate()\n        }\n        walletMap = makeWalletLayer2({ needFilterZero: true }).walletMap ?? {}\n\n        deFiCalcDataInit.coinSell.balance = walletMap[coinSellSymbol]?.count\n        deFiCalcDataInit.coinBuy.balance = walletMap[coinBuySymbol]?.count\n      }\n\n      myLog(\n        'resetDefault defi clearTrade',\n        deFiCalcDataInit.coinSell,\n        tradeDefi.deFiCalcData?.coinSell?.tradeValue,\n        clearTrade,\n        defaultFee,\n      )\n      if (\n        tradeDefi.market !== market ||\n        clearTrade ||\n        tradeDefi.deFiCalcData?.coinSell?.tradeValue === undefined\n      ) {\n        deFiCalcDataInit.coinSell.tradeValue = undefined\n        deFiCalcDataInit.coinBuy.tradeValue = undefined\n        const [AtoB, BtoA] = marketInfo\n          ? isJoin\n            ? [marketInfo.depositPrice, marketInfo.withdrawPrice]\n            : [marketInfo.withdrawPrice, marketInfo.depositPrice]\n          : ['0', '0']\n        updateTradeDefi({\n          market: tradeDefi.market !== market ? (market as MarketType) : undefined,\n          type: marketInfo.type,\n          isStoB,\n          sellVol: '0',\n          buyVol: '0',\n          sellToken: tokenMap[coinSellSymbol],\n          buyToken: tokenMap[coinBuySymbol],\n          deFiCalcData: {\n            ...deFiCalcDataInit,\n            AtoB,\n            BtoA,\n            fee: '',\n            // : undefined, //feeInfo?.fee?.toString() ?? '',\n          } as DeFiCalcData<T>,\n          defiBalances: {\n            [baseSymbol]: marketInfo?.baseVolume ?? '',\n            [quoteSymbol]: marketInfo?.quoteVolume ?? '',\n          } as any,\n          defaultFee: defaultFee?.feeRaw,\n          depositPrice: marketInfo?.depositPrice ?? '0',\n          withdrawPrice: marketInfo?.withdrawPrice ?? '0',\n          withdrawFeeBips: marketInfo?.extra?.withdrawFeeBips,\n        })\n        myLog('resetDefault defi clearTrade', deFiCalcDataInit, marketInfo)\n      } else {\n        const type = tradeDefi.lastInput ?? DeFiChgType.coinSell\n        const _tradeDefi = {\n          defiBalances: {\n            [baseSymbol]: marketInfo?.baseVolume ?? '',\n            [quoteSymbol]: marketInfo?.quoteVolume ?? '',\n          } as any,\n          defaultFee: defaultFee?.feeRaw,\n          depositPrice: marketInfo?.depositPrice ?? '0',\n          withdrawPrice: marketInfo?.withdrawPrice ?? '0',\n        }\n        const tradeData = {\n          ...deFiCalcDataInit[type],\n          tradeValue: tradeDefi.deFiCalcData[type]?.tradeValue ?? undefined,\n        }\n        handleOnchange({ tradeData, type, _tradeDefi })\n      }\n\n      setIsLoading(false)\n    },\n    [\n      account.readyState,\n      coinBuySymbol,\n      coinSellSymbol,\n      handleOnchange,\n      isJoin,\n      isStoB,\n      market,\n      tokenMap,\n      updateTradeDefi,\n    ],\n  )\n\n  const should15sRefresh = _.debounce(async (clearTrade: boolean = false) => {\n    myLog('should15sRefresh', market, clearTrade)\n    if (market && LoopringAPI.defiAPI) {\n      // updateDepth()\n      // getDefiMap();\n      if (clearTrade) {\n        setIsLoading(true)\n      }\n      Promise.all([\n        LoopringAPI.defiAPI?.getDefiMarkets({\n          defiType: (isLeverageETH ? LEVERAGE_ETH_CONFIG : DEFI_CONFIG).products[network].join(','),\n        }),\n        account.readyState === AccountStatus.ACTIVATED\n          ? getFee(isJoin ? sdk.OffchainFeeReqType.DEFI_JOIN : sdk.OffchainFeeReqType.DEFI_EXIT)\n          : Promise.resolve(undefined),\n      ]).then(([defiMapInfo, _feeInfo]) => {\n        if ((defiMapInfo as sdk.RESULT_INFO).code || (defiMapInfo as sdk.RESULT_INFO).message) {\n          setServerUpdate(true)\n        } else {\n          let status: any = defiMapInfo.markets[market]?.status ?? 0\n          status = ('00000000' + status.toString(2)).split('')\n          if ((status[status.length - 2] !== '1' && status[status.length - 4] !== '1')) {\n            setServerUpdate(true)\n          } else {\n            updateDefiSyncMap({\n              defiMap: {\n                marketMap: defiMapInfo.markets,\n                marketCoins: defiMapInfo.tokenArr,\n                marketArray: defiMapInfo.marketArr,\n              },\n            })\n          }\n        }\n        resetDefault(clearTrade, { defaultFee: _feeInfo })\n      })\n      // if (account.readyState === AccountStatus.ACTIVATED) {\n      //   resetDefault(clearTrade, {})\n      // }\n    }\n  }, globalSetup.wait)\n\n  const walletLayer2Callback = React.useCallback(async () => {\n    const tradeDefi = store.getState()._router_tradeDefi.tradeDefi\n    const type = tradeDefi.lastInput ?? DeFiChgType.coinSell\n    let tradeValue: any = undefined\n\n    let deFiCalcDataInit: Partial<DeFiCalcData<any>> = {\n      coinSell: {\n        belong: coinSellSymbol,\n        balance: undefined,\n      },\n      coinBuy: {\n        belong: coinBuySymbol,\n        balance: undefined,\n      },\n      ...(tradeDefi?.deFiCalcData ?? {}),\n    }\n    if (tradeDefi.deFiCalcData) {\n      tradeValue = tradeDefi?.deFiCalcData[type]?.tradeValue ?? undefined\n    }\n    if (deFiCalcDataInit[type]?.belong) {\n      let walletMap: any\n      if (account.readyState === AccountStatus.ACTIVATED) {\n        walletMap = makeWalletLayer2({ needFilterZero: true }).walletMap\n        deFiCalcDataInit.coinSell = {\n          belong: coinSellSymbol,\n          balance: walletMap[coinSellSymbol]?.count,\n        }\n        deFiCalcDataInit.coinBuy = {\n          belong: coinBuySymbol,\n          balance: walletMap[coinBuySymbol]?.count,\n        }\n      } else {\n        deFiCalcDataInit.coinSell = {\n          belong: coinSellSymbol,\n          balance: undefined,\n        }\n        deFiCalcDataInit.coinBuy = {\n          belong: coinBuySymbol,\n          balance: undefined,\n        }\n      }\n      const tradeData = {\n        ...deFiCalcDataInit[type],\n        tradeValue,\n      }\n      myLog('resetDefault Defi walletLayer2Callback', tradeData)\n      handleOnchange({ tradeData, type })\n    }\n  }, [account.readyState, coinBuySymbol, coinSellSymbol, handleOnchange])\n\n  useWalletLayer2Socket({ walletLayer2Callback })\n  const sendRequest = React.useCallback(async () => {\n    const tradeDefi = store.getState()._router_tradeDefi.tradeDefi\n    try {\n      setIsLoading(true)\n      if (\n        LoopringAPI.userAPI &&\n        LoopringAPI.defiAPI &&\n        tradeDefi.sellToken?.symbol &&\n        tradeDefi.maxFeeBips &&\n        exchangeInfo\n      ) {\n        const req: sdk.GetNextStorageIdRequest = {\n          accountId: account.accountId,\n          sellTokenId: tradeDefi.sellToken?.tokenId ?? 0,\n        }\n        const storageId = await LoopringAPI.userAPI.getNextStorageId(req, account.apiKey)\n        let fee = tradeDefi.feeRaw\n        let maxFeeBips = tradeDefi.maxFeeBips <= 5 ? 5 : tradeDefi.maxFeeBips\n        const request: sdk.DefiOrderRequest = {\n          exchange: exchangeInfo.exchangeAddress,\n          storageId: storageId.orderId,\n          accountId: account.accountId,\n          sellToken: {\n            tokenId: tradeDefi.sellToken?.tokenId ?? 0,\n            volume: tradeDefi.sellVol,\n          },\n          buyToken: {\n            tokenId: tradeDefi.buyToken?.tokenId ?? 0,\n            volume: tradeDefi.buyVol,\n          },\n          validUntil: getTimestampDaysLater(DAYS),\n          maxFeeBips: maxFeeBips,\n          fillAmountBOrS: false,\n          action: isJoin ? sdk.DefiAction.Deposit : sdk.DefiAction.Withdraw,\n          fee: fee,\n          type: tradeDefi.type,\n          taker: '',\n          eddsaSignature: '',\n          // taker:\n          // new BN(ethUtil.toBuffer(request.taker)).toString(),\n        }\n        myLog('DefiTrade request:', request)\n        const response = await LoopringAPI.defiAPI.orderDefi(\n          request,\n          account.eddsaKey.sk,\n          account.apiKey,\n        )\n        if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n          const errorItem = SDK_ERROR_MAP_TO_UI[(response as sdk.RESULT_INFO)?.code ?? 700001]\n          throw new CustomErrorWithCode(errorItem)\n        } else {\n          setToastOpen({\n            open: true,\n            type: ToastType.success,\n            content: t('labelInvestSuccess', {\n              type: isJoin ? t('labelInvestDefDeposit') : t('labelInvestDefWithdraw'),\n              symbol: coinBuySymbol,\n            }),\n          })\n        }\n      } else {\n        throw new Error('api not ready')\n      }\n    } catch (reason) {\n      setToastOpen({\n        open: true,\n        type: ToastType.error,\n        content:\n          t('labelInvestFailed') + (reason as CustomErrorWithCode)?.messageKey ??\n          ` error: ${t((reason as CustomErrorWithCode)?.messageKey)}`,\n      })\n    } finally {\n      setConfirmShowLimitBalance(false)\n      should15sRefresh(true)\n    }\n  }, [\n    account.accountId,\n    account.apiKey,\n    account.eddsaKey.sk,\n    coinBuySymbol,\n    exchangeInfo,\n    isJoin,\n    setToastOpen,\n    should15sRefresh,\n    t,\n  ])\n\n  const handleSubmit = React.useCallback(async () => {\n    const tradeDefi = store.getState()._router_tradeDefi.tradeDefi\n    // const marketInfo = defiMarketMap[market];\n\n    if (\n      (account.readyState === AccountStatus.ACTIVATED &&\n        tokenMap &&\n        exchangeInfo &&\n        account.eddsaKey?.sk,\n      tradeDefi.buyVol)\n    ) {\n      const [, tokenBase] = market.match(/(\\w+)-(\\w+)/i) ?? []\n\n      if (allowTrade && !allowTrade.defiInvest.enable) {\n        setShowSupport({ isShow: true })\n      } else if (toggle && !toggle[`${tokenBase}Invest`].enable) {\n        setShowTradeIsFrozen({ isShow: true, type: 'DefiInvest' })\n      } else {\n        sendRequest()\n      }\n    } else {\n      return false\n    }\n  }, [\n    market,\n    account.readyState,\n    account.eddsaKey?.sk,\n    tokenMap,\n    exchangeInfo,\n    sendRequest,\n    setToastOpen,\n    t,\n  ])\n  const onSubmitBtnClick = React.useCallback(async () => {\n    const tradeDefi = store.getState()._router_tradeDefi.tradeDefi\n    if (\n      tradeDefi?.maxSellVol &&\n      tradeDefi?.sellVol &&\n      sdk.toBig(tradeDefi.sellVol).gte(tradeDefi?.maxSellVol)\n    ) {\n      if (\n        sdk\n          .toBig(tradeDefi?.maxSellVol ?? 0)\n          .minus(tradeDefi.miniSellVol ?? 0)\n          .toString()\n          .startsWith('-')\n      ) {\n        setConfirmShowNoBalance(true)\n      } else {\n        setConfirmShowLimitBalance(true)\n        const type = DeFiChgType.coinSell\n        const tradeValue = getValuePrecisionThousand(\n          sdk.toBig(tradeDefi?.maxSellVol).div('1e' + tokenMap[coinSellSymbol]?.decimals),\n          tokenMap[coinSellSymbol].precision,\n          tokenMap[coinSellSymbol].precision,\n          tokenMap[coinSellSymbol].precision,\n          false,\n          { floor: true },\n        ).replaceAll(sdk.SEP, '')\n        // @ts-ignore\n        const oldTrade = (tradeDefi?.deFiCalcData[type] ?? {}) as unknown as T\n        handleOnchange({\n          tradeData: {\n            ...oldTrade,\n            tradeValue,\n          },\n          type,\n        })\n        // handleOnchange()\n      }\n    } else {\n      handleSubmit()\n    }\n  }, [tokenMap, coinSellSymbol, handleOnchange, handleSubmit])\n  const {\n    btnStatus,\n    onBtnClick,\n    btnLabel: tradeMarketI18nKey,\n  } = useSubmitBtn({\n    availableTradeCheck,\n    isLoading,\n    submitCallback: onSubmitBtnClick,\n  })\n  React.useEffect(() => {\n    if (\n      market &&\n      market !== '' &&\n      // walletLayer2Status === SagaStatus.UNSET &&\n      isJoin !== undefined\n    ) {\n      setSymbol(() => {\n        if (isJoin) {\n          const [, coinBuySymbol, coinSellSymbol] = market.match(/(\\w+)-(\\w+)/i) ?? []\n          return { coinBuySymbol, coinSellSymbol }\n        } else {\n          const [, coinSellSymbol, coinBuySymbol] = market.match(/(\\w+)-(\\w+)/i) ?? []\n          return { coinBuySymbol, coinSellSymbol }\n        }\n      })\n      if (refreshRef.current) {\n        // @ts-ignore\n        refreshRef.current.firstElementChild.click()\n        should15sRefresh(true)\n        myLog('should15sRefresh refreshRef.current click only', market)\n      } else {\n        should15sRefresh(true)\n      }\n    }\n    return () => {\n      myLog('should15sRefresh cancel', market)\n      resetTradeDefi()\n      should15sRefresh.cancel()\n      handleOnchange.cancel()\n    }\n  }, [isJoin, market])\n\n  const deFiWrapProps = React.useMemo(() => {\n    const tradeDefi = store.getState()._router_tradeDefi.tradeDefi\n    return {\n      isStoB,\n      refreshRef,\n      onConfirm: sendRequest,\n      disabled:\n        !tradeDefi.deFiCalcData?.AtoB ||\n        (account.readyState === AccountStatus.ACTIVATED && !tradeDefi?.feeRaw),\n      btnInfo: {\n        label: tradeMarketI18nKey,\n        params: {},\n      },\n      isLoading,\n      switchStobEvent: (_isStoB: boolean | ((prevState: boolean) => boolean)) => {\n        setIsStoB(_isStoB)\n      },\n      onRefreshData: should15sRefresh,\n      onSubmitClick: onBtnClick as () => void,\n      onChangeEvent: handleOnchange,\n      tokenAProps: {},\n      tokenBProps: {},\n      deFiCalcData: {\n        ...tradeDefi.deFiCalcData,\n      },\n      maxBuyVol: tradeDefi.defiBalances ? tradeDefi.defiBalances[coinBuySymbol] : undefined,\n      maxSellVol: tradeDefi.maxSellVol,\n      confirmShowLimitBalance,\n      tokenSell: tokenMap[coinSellSymbol],\n      tokenBuy: tokenMap[coinBuySymbol],\n      btnStatus,\n      accStatus: account.readyState,\n      withdrawFeeBips: tradeDefi.maxFeeBips,\n      apr: (isLeverageETH ? marketLeverageMap : marketMap)[market]?.apy,\n      onAprDetail: () => {\n        setShowETHStakingApr({\n          isShow: true,\n          symbol: market,\n          info: (isLeverageETH ? marketLeverageMap : marketMap)[market],\n        })\n      },\n    }\n  }, [\n    isStoB,\n    refreshRef,\n    sendRequest,\n    account.readyState,\n    tradeMarketI18nKey,\n    isLoading,\n    should15sRefresh,\n    onBtnClick,\n    handleOnchange,\n    confirmShowLimitBalance,\n    tokenMap,\n    coinSellSymbol,\n    coinBuySymbol,\n    btnStatus,\n  ]) // as ForceWithdrawProps<any, any>;\n  return {\n    deFiWrapProps: deFiWrapProps as unknown as DeFiWrapProps<T, I, ACD>,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/useDeposit.ts",
    "content": "import React from 'react'\n\nimport {\n  AccountStep,\n  DepositProps,\n  SwitchData,\n  useOpenModals,\n  useSettings,\n} from '@loopring-web/component-lib'\nimport {\n  AccountStatus,\n  AddressError,\n  coinbaseSmartWalletChains,\n  CoinMap,\n  IBData,\n  L1_UPDATE,\n  L1L2_NAME_DEFINED,\n  MapChainId,\n  myLog,\n  SagaStatus,\n  SUBMIT_PANEL_AUTO_CLOSE,\n  TRADE_TYPE,\n  UIERROR_CODE,\n  WalletMap,\n} from '@loopring-web/common-resources'\nimport { connectProvides } from '@loopring-web/web3-provider'\n\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport {\n  ActionResultCode,\n  BIGO,\n  callSwitchChain,\n  DepositCommands,\n  depositServices,\n  getContractTypeByNetwork,\n  LoopringAPI,\n  store,\n  useAccount,\n  useAddressCheck,\n  useAllowances,\n  useBtnStatus,\n  useModalData,\n  useSystem,\n  useTokenMap,\n  useWalletLayer1,\n  useWalletLayer2,\n} from '../../index'\nimport { useTranslation } from 'react-i18next'\nimport { useOnChainInfo } from '../../stores/localStore/onchainHashInfo'\nimport Web3 from 'web3'\nimport { omit } from 'lodash'\n\nexport const useDeposit = <\n  T extends {\n    toAddress?: string\n    addressError?: { error: boolean; message?: string }\n  } & IBData<I>,\n  I,\n>(\n  isAllowInputToAddress = false,\n  opts?: { token?: string | null; owner?: string | null },\n) => {\n  const subject = React.useMemo(() => depositServices.onSocket(), [])\n  const { tokenMap, totalCoinMap } = useTokenMap()\n  const { account, status: accountStatus, updateAccount } = useAccount()\n  const { walletLayer1, updateWalletLayer1, status: walletLayer1Status } = useWalletLayer1()\n  const { updateWalletLayer2 } = useWalletLayer2()\n  const { updateDepositHash } = useOnChainInfo()\n  const { t } = useTranslation('common')\n  const nodeTimer = React.useRef<NodeJS.Timeout | -1>(-1)\n  const [isToAddressEditable, setIsToAddressEditable] = React.useState(false)\n  const { exchangeInfo, chainId, gasPrice, allowTrade, baseURL, status: systemStatus, app } = useSystem()\n  const { defaultNetwork } = useSettings()\n\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const [toInputAddress, setToInputAddress] = React.useState<string>('')\n  const {\n    depositValue,\n    updateDepositData,\n    resetDepositData,\n    activeAccountValue: { chargeFeeList },\n  } = useModalData()\n  const {\n    // address: toAddress,\n    realAddr: realToAddress,\n    setAddress: setToAddress,\n    addrStatus: _toAddressStatus,\n    isAddressCheckLoading: toIsAddressCheckLoading,\n  } = useAddressCheck()\n\n  const toAddressStatus =\n    coinbaseSmartWalletChains.includes(defaultNetwork) &&\n    _toAddressStatus === AddressError.IsNotLoopringContract\n      ? AddressError.NoError\n      : _toAddressStatus\n\n  const [loopringSmartWalletCheck, setLoopringSmartWalletCheck] = React.useState(\n    {\n      isLoopringSmartWallet: undefined as boolean | undefined,\n      checkedAddress: undefined as string | undefined\n    }\n  )\n  \n  React.useEffect(() => {\n    if (realToAddress && realToAddress !== loopringSmartWalletCheck.checkedAddress) {\n      setLoopringSmartWalletCheck({\n        checkedAddress: realToAddress,\n        isLoopringSmartWallet: undefined\n      })\n      getContractTypeByNetwork(realToAddress, MapChainId[defaultNetwork]).then((contractType) => {\n        setLoopringSmartWalletCheck((state) => ({\n          ...state,\n          isLoopringSmartWallet: contractType ? contractType.contractVersion !== '' : false\n        }))\n      })\n    }\n  }, [realToAddress])\n  \n\n  React.useEffect(() => {\n    const depositValue = store.getState()._router_modalData.depositValue\n    handlePanelEvent(\n      {\n        to: 'button',\n        tradeData: depositValue as any,\n      },\n      'Tobutton',\n    )\n  }, [realToAddress])\n\n  const {\n    modals: {\n      isShowDeposit: { symbol, isShow },\n    },\n    setShowDeposit,\n    setShowAccount,\n  } = useOpenModals()\n\n  React.useEffect(() => {\n    if(!isShow) {\n      const oldValue = store.getState()._router_modalData.depositValue\n      let newValue = {\n        ...oldValue,\n        tradeValue: undefined\n      }\n      updateDepositData({ ...newValue })\n    }\n  }, [isShow])\n\n  const {\n    btnStatus,\n    btnInfo,\n    enableBtn,\n    // setLoadingBtn,\n    disableBtn,\n    setLabelAndParams,\n    resetBtnInfo,\n  } = useBtnStatus()\n\n  const { allowanceInfo } = useAllowances({\n    owner: account.accAddress,\n    symbol: depositValue.belong as string,\n  })\n  const isNewAccount = [AccountStatus.NO_ACCOUNT, AccountStatus.NOT_ACTIVE].includes(\n    account.readyState as any,\n  )\n  const updateBtnStatus = React.useCallback(() => {\n    resetBtnInfo()\n    if (\n      realToAddress &&\n      (toAddressStatus as AddressError) === AddressError.NoError &&\n      depositValue?.toAddress?.trim() !== '' &&\n      depositValue.toAddress == realToAddress &&\n      depositValue.belong === allowanceInfo?.tokenInfo.symbol &&\n      depositValue?.tradeValue &&\n      allowanceInfo &&\n      sdk.toBig(walletLayer1?.ETH?.count ?? 0).gt(BIGO) &&\n      sdk.toBig(depositValue?.tradeValue).gt(BIGO) &&\n      sdk.toBig(depositValue?.tradeValue).lte(sdk.toBig(depositValue?.balance ?? ''))\n    ) {\n      myLog('walletLayer1?.ETH?.count', walletLayer1?.ETH?.count)\n\n      const curValInWei = sdk\n        .toBig(depositValue?.tradeValue)\n        .times('1e' + allowanceInfo?.tokenInfo.decimals)\n      if (allowanceInfo.needCheck && curValInWei.gt(allowanceInfo.allowance)) {\n        myLog('!!---> set labelL1toL2NeedApprove!!!! belong:', depositValue.belong)\n        setLabelAndParams('labelL1toL2NeedApprove', {\n          symbol: depositValue.belong as string,\n        })\n      }\n\n      // NewAccountCheck\n      const index = chargeFeeList?.findIndex(({ belong }) => belong === depositValue.belong) ?? -1\n      if (\n        isAllowInputToAddress ||\n        (isNewAccount && (index !== -1 || /dev|uat/gi.test(baseURL))) ||\n        !isNewAccount\n      ) {\n        enableBtn()\n        return\n      }\n    }\n    myLog('try to disable deposit btn!')\n    if (sdk.toBig(walletLayer1?.ETH?.count ?? 0).eq(BIGO)) {\n      setLabelAndParams('labelNOETH', {})\n    }\n    disableBtn()\n  }, [\n    resetBtnInfo,\n    isAllowInputToAddress,\n    realToAddress,\n    toAddressStatus,\n    depositValue.toAddress,\n    depositValue.belong,\n    depositValue?.tradeValue,\n    depositValue?.balance,\n    allowanceInfo,\n    walletLayer1?.ETH?.count,\n    disableBtn,\n    chargeFeeList,\n    isNewAccount,\n    setLabelAndParams,\n    enableBtn,\n    // account?.readyState,\n    opts?.owner,\n  ])\n\n  React.useEffect(() => {\n    updateBtnStatus()\n  }, [\n    depositValue?.belong,\n    depositValue?.tradeValue,\n    depositValue?.balance,\n    depositValue.toAddress,\n    allowanceInfo?.tokenInfo.symbol,\n    toAddressStatus,\n    realToAddress,\n    toIsAddressCheckLoading,\n    walletLayer1?.ETH?.count,\n  ])\n\n  const handlePanelEvent = React.useCallback(\n    (data: SwitchData<Partial<T>>, _switchType: 'Tomenu' | 'Tobutton') => {\n      const oldValue = store.getState()._router_modalData.depositValue\n      let newValue = {\n        ...oldValue,\n      }\n      if (data.to === 'button') {\n        if (walletLayer1 && data?.tradeData?.belong) {\n          const walletInfo = walletLayer1[data.tradeData.belong]\n          newValue = {\n            ...newValue,\n            ...data.tradeData,\n            balance: walletInfo?.count,\n          }\n        }\n      }\n\n      // myLog('DepositData', {...newValue, toAddress: realToAddress})\n      updateDepositData({ ...newValue, toAddress: realToAddress })\n      return Promise.resolve()\n    },\n    [setToAddress, updateDepositData, realToAddress, isToAddressEditable, walletLayer1],\n  )\n  const handleAddressChange = (value?: string) => {\n    const toAddress = store.getState()._router_modalData.depositValue.toAddress\n    if (isToAddressEditable == false && opts?.owner && opts.owner !== '') {\n      value = opts.owner\n    }\n    const makeForceFresh = (state: string, value: string) => {\n      if (value === state) {\n        sdk.sleep(0).then(() => {\n          setToAddress(state)\n        })\n        return ''\n      } else {\n        return value\n      }\n    }\n    setToAddress((state) => {\n      // myLog('address update setToAddress', state, value, realToAddress, toAddressStatus)\n      if (\n        value &&\n        toIsAddressCheckLoading == false &&\n        realToAddress &&\n        realToAddress.startsWith('0x') &&\n        [value, toAddress].includes(realToAddress)\n      ) {\n        return makeForceFresh(state, value)\n      } else if (value !== undefined) {\n        setToInputAddress(value)\n        return makeForceFresh(state, value)\n      } else if (toInputAddress !== '') {\n        return makeForceFresh(state, toInputAddress)\n      } else if (toIsAddressCheckLoading == false) {\n        return makeForceFresh(state, state)\n      } else {\n        return state\n      }\n    })\n  }\n  const handleClear = React.useCallback(() => {\n    if (isAllowInputToAddress && !isToAddressEditable) {\n      return\n    }\n    handleAddressChange('')\n  }, [isAllowInputToAddress, isToAddressEditable])\n\n  const walletLayer1Callback = React.useCallback(() => {\n    // const {\n    //   _router_modalData: { depositValue },\n    // } = store.getState()\n    let updateData = {} // = { ...depositValue }\n    if (nodeTimer.current !== -1) {\n      clearTimeout(nodeTimer.current)\n    }\n    if (!depositValue.belong && walletLayer1) {\n      const keys = Reflect.ownKeys(walletLayer1)\n      updateData = {\n        belong: 'ETH',\n        tradeValue: undefined,\n        balance: 0,\n      }\n      for (var key in keys) {\n        const keyVal = keys[key] as any\n        const walletInfo = walletLayer1[keyVal]\n        if (sdk.toBig(walletInfo?.count ?? 0).gt(0)) {\n          updateData = {\n            // ...updateData,\n            belong: keyVal as any,\n            tradeValue: undefined,\n            balance: walletInfo?.count,\n          }\n          break\n        }\n      }\n    } else if (depositValue.belong && walletLayer1) {\n      updateData = {\n        // ...updateData,\n        belong: depositValue.belong,\n        balance: walletLayer1[depositValue.belong]?.count ?? 0,\n      }\n    }\n    if (isAllowInputToAddress && !(opts?.owner && opts?.owner?.startsWith('0x'))) {\n      setIsToAddressEditable(true)\n    }\n    handlePanelEvent(\n      {\n        to: 'button',\n        tradeData: updateData as any,\n      },\n      'Tobutton',\n    )\n    handleAddressChange()\n  }, [\n    depositValue.belong,\n    depositValue.tradeValue,\n    opts?.token,\n    opts?.owner,\n    symbol,\n    walletLayer1,\n    isAllowInputToAddress,\n    handlePanelEvent,\n    account.accAddress,\n    handleClear,\n  ])\n\n  React.useEffect(() => {\n    const { walletLayer1 } = store.getState()\n    if (walletLayer1Status == SagaStatus.UNSET) {\n      if (\n        walletLayer1.error\n        // &&\n        // ![AccountStatus.UN_CONNECT, AccountStatus.ERROR_NETWORK, 'unknown'].includes(\n        //   account.readyState,\n        // )\n      ) {\n        updateWalletLayer1()\n      } else {\n        walletLayer1Callback()\n      }\n    }\n  }, [walletLayer1Status])\n\n  const init = () => {\n    if (chainId === defaultNetwork && baseURL) {\n      let tradeData: any = {\n        belong: opts?.token?.toUpperCase() ?? symbol,\n        tradeValue: !isShow ? undefined : depositValue.tradeValue,\n      }\n      updateWalletLayer1()\n      handleAddressChange()\n\n      handlePanelEvent(\n        {\n          to: 'button',\n          tradeData: {\n            ...tradeData,\n          } as any,\n        },\n        'Tobutton',\n      )\n    }\n  }\n  React.useEffect(() => {\n    // myLog('accountStatus,LoopringAPI?.__chainId__', LoopringAPI?.__chainId__, accountStatus)\n    if (accountStatus === SagaStatus.UNSET && systemStatus === SagaStatus.UNSET) {\n      init()\n      if (isShow || isAllowInputToAddress) {\n        nodeTimer.current = setTimeout(() => {\n          updateWalletLayer1()\n        }, L1_UPDATE)\n      }\n    }\n    return () => {\n      if (nodeTimer.current !== -1) {\n        clearTimeout(nodeTimer.current)\n      }\n    }\n  }, [accountStatus, isShow, isToAddressEditable, systemStatus])\n\n  const handleDeposit = React.useCallback(\n    async (inputValue: any) => {\n      myLog('handleDeposit:', inputValue)\n      const { readyState, connectName } = account\n      let result = { code: ActionResultCode.NoError }\n      const { toAddress } = store.getState()._router_modalData.depositValue\n      try {\n        if (\n          readyState !== AccountStatus.UN_CONNECT &&\n          inputValue.tradeValue &&\n          tokenMap &&\n          exchangeInfo?.exchangeAddress &&\n          connectProvides.usedWeb3 &&\n          LoopringAPI.exchangeAPI &&\n          toAddress\n        ) {\n          const tokenInfo = tokenMap[inputValue.belong]\n          const gasLimit = '0x' + parseInt(tokenInfo.gasAmounts.deposit).toString(16)\n          const fee = 0\n          const isMetaMask = true\n\n          const realGasPrice = gasPrice ?? 30\n\n          const _chainId = await connectProvides?.usedWeb3?.eth?.getChainId()\n          //chainId === 'unknown' ? sdk.ChainId.MAINNET : chainId\n          await callSwitchChain(_chainId)\n\n          let nonce = 0\n\n          let nonceInit = false\n\n          if (allowanceInfo?.needCheck) {\n            const curValInWei = sdk.toBig(inputValue.tradeValue).times('1e' + tokenInfo.decimals)\n\n            if (curValInWei.gt(allowanceInfo.allowance)) {\n              myLog(curValInWei, allowanceInfo.allowance, ' need approveMax!')\n\n              setShowAccount({\n                isShow: true,\n                step: AccountStep.Deposit_Approve_WaitForAuth,\n                info: {\n                  isAllowInputToAddress,\n                },\n              })\n\n              nonce = await sdk.getNonce(\n                connectProvides.usedWeb3 as unknown as Web3,\n                account.accAddress,\n              )\n\n              nonceInit = true\n\n              try {\n                await sdk.approveMax(\n                  connectProvides.usedWeb3,\n                  account.accAddress,\n                  tokenInfo.address,\n                  exchangeInfo?.depositAddress,\n                  realGasPrice,\n                  gasLimit,\n                  _chainId,\n                  '0x' + nonce.toString(16),\n                  isMetaMask,\n                )\n                nonce += 1\n              } catch (error: any) {\n                if (error instanceof Error) {\n                  throw {\n                    // Pull all enumerable properties, supporting properties on custom Errors\n                    ...error,\n                    // Explicitly pull Error's non-enumerable properties\n                    message: error.message,\n                    stack: error.stack,\n                    type: 'ApproveToken',\n                  }\n                } else {\n                  throw {\n                    ...(error as any),\n                    type: 'ApproveToken',\n                  }\n                }\n              }\n            } else {\n              myLog(\"allowance is enough! don't need approveMax!\")\n            }\n          }\n\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.Deposit_WaitForAuth,\n            info: {\n              to: isAllowInputToAddress ? realToAddress : null,\n              isAllowInputToAddress,\n            },\n          })\n\n          if (!nonceInit) {\n            nonce = await sdk.getNonce(\n              connectProvides.usedWeb3 as unknown as Web3,\n              account.accAddress,\n            )\n          }\n\n          myLog('before deposit:', chainId, connectName, isMetaMask)\n\n          // const realChainId = chainId === 'unknown' ? 1 : chainId\n          let response\n          try {\n            const exchangeInfoResponse = await LoopringAPI.exchangeAPI.getExchangeInfo()\n            // if chaindId from response is not equal to the chainId from wallet, \n            // or exchangeAddress on redux is not same as from response, throw error\n            if (\n              exchangeInfoResponse.exchangeInfo.chainId !== _chainId ||\n              exchangeInfoResponse.exchangeInfo.exchangeAddress.toLowerCase() !==\n                exchangeInfo.exchangeAddress.toLowerCase()\n            ) {\n              throw {\n                message: 'data not matched',\n              } \n            }\n            response = await sdk.deposit(\n              connectProvides.usedWeb3,\n              account.accAddress,\n              exchangeInfo.exchangeAddress,\n              tokenInfo,\n              inputValue.tradeValue,\n              fee,\n              realGasPrice,\n              gasLimit,\n              _chainId,\n              '0x' + nonce.toString(16),\n              isMetaMask,\n              toAddress,\n            )\n          } catch (error) {\n            if (error instanceof Error) {\n              throw {\n                ...error,\n                message: error.message,\n                stack: error.stack,\n                type: 'Deposit',\n              }\n            } else {\n              throw {\n                ...(error as any),\n                type: 'Deposit',\n              }\n            }\n          }\n\n          myLog('response:', response)\n\n          if (response) {\n            // Close Deposit panel...\n            setShowDeposit({ isShow: false })\n            resetDepositData()\n            updateWalletLayer1()\n            setShowAccount({\n              isShow: true,\n              info: {\n                to: isAllowInputToAddress ? realToAddress : null,\n                symbol: tokenInfo.symbol,\n                value: inputValue.tradeValue,\n                hash: response.result,\n                isAllowInputToAddress,\n                isNewAccount,\n              },\n              step: AccountStep.Deposit_Submit,\n            })\n            updateDepositHash(response.result, account.accAddress, undefined, {\n              symbol: tokenInfo.symbol,\n              type: 'Deposit',\n              value: inputValue.tradeValue,\n            })\n            await sdk.sleep(SUBMIT_PANEL_AUTO_CLOSE)\n            if (\n              store.getState().modals.isShowAccount.isShow &&\n              store.getState().modals.isShowAccount.step == AccountStep.Deposit_Submit\n            ) {\n              setShowAccount({ isShow: false })\n            }\n            if (account.readyState === 'NO_ACCOUNT') {\n              const timer = setInterval(() => {\n                LoopringAPI.exchangeAPI?.getAccount({\n                  owner: account.accAddress,\n                }).then(acc => {\n                  if (acc.accInfo.accountId > 0) {\n                    updateAccount({ \n                      _accountIdNotActive : acc.accInfo.accountId,\n                      readyState: 'NOT_ACTIVE',\n                    })\n                    updateWalletLayer2()\n                    clearInterval(timer)\n                  }\n                })\n              }, 5 * 1000);\n            }\n            \n          } else {\n            throw { code: UIERROR_CODE.ERROR_NO_RESPONSE }\n          }\n        } else {\n          throw { code: UIERROR_CODE.DATA_NOT_READY }\n        }\n      } catch (e) {\n        const { type, ..._error } = (e as any)?.message ? (e as any) : { type: '' }\n        const error = LoopringAPI?.exchangeAPI?.genErr(_error as any) ?? {\n          code: UIERROR_CODE.DATA_NOT_READY,\n        }\n        const code = sdk.checkErrorInfo(error, true)\n        switch (code) {\n          case sdk.ConnectorError.USER_DENIED:\n          case sdk.ConnectorError.USER_DENIED_2:\n            if (type === 'ApproveToken') {\n              setShowAccount({\n                isShow: true,\n                step: AccountStep.Deposit_Approve_Denied,\n                info: {\n                  isAllowInputToAddress,\n                },\n              })\n            } else {\n              setShowAccount({\n                isShow: true,\n                step: AccountStep.Deposit_Denied,\n                info: {\n                  isAllowInputToAddress,\n                },\n              })\n            }\n            break\n          default:\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.Deposit_Failed,\n              info: {\n                isAllowInputToAddress,\n              },\n              error: {\n                ..._error,\n                ...error,\n                code: (e as any)?.code ?? UIERROR_CODE.UNKNOWN,\n              },\n            })\n            resetDepositData()\n            break\n        }\n        updateWalletLayer1()\n      }\n\n      return result\n    },\n    [\n      isNewAccount,\n      account,\n      tokenMap,\n      exchangeInfo?.exchangeAddress,\n      exchangeInfo?.depositAddress,\n      isAllowInputToAddress,\n      setShowAccount,\n      gasPrice,\n      chainId,\n      allowanceInfo?.needCheck,\n      allowanceInfo?.allowance,\n      realToAddress,\n      updateWalletLayer1,\n      resetDepositData,\n      updateDepositHash,\n    ],\n  )\n\n  const onDepositClick = React.useCallback(async () => {\n    // setLoadingBtn();\n    const depositValue = store.getState()._router_modalData.depositValue\n    myLog('onDepositClick depositValue:', depositValue)\n\n    if (depositValue && depositValue.belong) {\n      // enableBtn();\n      await handleDeposit(depositValue as T)\n    }\n  }, [depositValue, handleDeposit])\n\n  React.useEffect(() => {\n    const subscription = subject.subscribe((props) => {\n      myLog('subscription Deposit DepsitERC20')\n\n      switch (props.status) {\n        case DepositCommands.DepsitERC20:\n          onDepositClick()\n          break\n        default:\n          break\n      }\n    })\n    return () => {\n      subscription.unsubscribe()\n    }\n  }, [subject, accountStatus, systemStatus])\n\n  const title =\n    app === 'earn'\n      ? 'labelDeposit'\n      : account.readyState === AccountStatus.NO_ACCOUNT\n      ? t('labelDepositTitleAndActive', { l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol })\n      : t('labelDepositTitle', { l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol })\n\n  const isTaiko = [sdk.ChainId.TAIKO, sdk.ChainId.TAIKOHEKLA].includes(defaultNetwork)\n  const depositProps: DepositProps<T, I> = {\n    btnInfo,\n    isNewAccount,\n    title,\n    type: TRADE_TYPE.TOKEN,\n    handleClear,\n    allowTrade,\n    isAllowInputToAddress,\n    chargeFeeTokenList: chargeFeeList ?? [],\n    tradeData: depositValue as T,\n    coinMap: totalCoinMap as CoinMap<any>,\n    walletMap: (isTaiko ? omit(walletLayer1, ['TAIKO']) : walletLayer1) as WalletMap<any>,\n    depositBtnStatus: btnStatus,\n    handlePanelEvent,\n    handleAddressChange,\n    onDepositClick,\n    toAddressStatus,\n    toIsAddressCheckLoading,\n    toAddress: toInputAddress,\n    realToAddress: depositValue.toAddress,\n    isToAddressEditable,\n    isLoopringSmartWallet: loopringSmartWalletCheck.isLoopringSmartWallet,\n    onClose() {\n      setShowDeposit({ isShow: false })\n    },\n  }\n\n  return {\n    depositProps,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/useDualEdit.ts",
    "content": "import React from 'react'\nimport { DualDetailType, ToastType, useOpenModals, useSettings } from '@loopring-web/component-lib'\nimport {\n  AccountStatus,\n  CustomErrorWithCode,\n  myLog,\n  SDK_ERROR_MAP_TO_UI,\n  SUBMIT_PANEL_AUTO_CLOSE,\n  TradeBtnStatus,\n} from '@loopring-web/common-resources'\nimport BigNumber from 'bignumber.js'\n\nimport {\n  DAYS,\n  getTimestampDaysLater,\n  useSubmitBtn,\n  useToast,\n  useTokenMap,\n  useTradeDual,\n} from '@loopring-web/core'\n\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nimport { LoopringAPI, store, useSystem } from '../../index'\nimport { useTranslation } from 'react-i18next'\n\nexport const useDualEdit = <\n  T extends {\n    isRenew: boolean\n    renewTargetPrice?: string\n    renewDuration?: number\n  },\n  R extends DualDetailType,\n>({\n  refresh,\n}: {\n  refresh?: (item: R, dontCloseModal: boolean) => void\n}) => {\n  const { exchangeInfo } = useSystem()\n  const { setShowAccount } = useOpenModals()\n  const { t } = useTranslation()\n  const { setShowDual } = useOpenModals()\n  const {\n    editDual: { dualViewInfo },\n    updateEditDual,\n    resetEditDual,\n  } = useTradeDual()\n  const { dualAuto } = useSettings()\n\n  const { toastOpen, setToastOpen, closeToast } = useToast()\n  const [isLoading, setIsLoading] = React.useState(false)\n  const { tokenMap, idIndex } = useTokenMap()\n  const [tradeData, setTradeData] = React.useState<T>(() => {\n    // @ts-ignore\n    return {\n      isRenew: dualViewInfo?.__raw__?.order?.dualReinvestInfo?.isRecursive ?? false,\n      renewDuration:\n        dualViewInfo?.__raw__?.order?.dualReinvestInfo?.isRecursive || dualAuto.day === 'auto'\n          ? dualViewInfo?.__raw__?.order?.dualReinvestInfo?.maxDuration / 86400000\n          : dualAuto.day,\n      renewTargetPrice: dualViewInfo?.__raw__?.order.dualReinvestInfo.newStrike,\n    } as T\n  })\n  React.useEffect(() => {\n    const { dualViewInfo } = store.getState()._router_tradeDual.editDual\n    setTradeData({\n      // @ts-ignore\n      isRenew: dualViewInfo?.__raw__?.order?.dualReinvestInfo?.isRecursive ?? false,\n      renewDuration: dualViewInfo?.__raw__?.order?.dualReinvestInfo?.maxDuration / 86400000,\n      renewTargetPrice: dualViewInfo?.__raw__?.order.dualReinvestInfo.newStrike,\n    })\n  }, [dualViewInfo?.__raw__?.order?.hash])\n\n  const handleOnchange = ({ tradeData }: { tradeData: T }) => {\n    setTradeData(tradeData)\n    const editDual = store.getState()._router_tradeDual.editDual\n    updateEditDual({\n      ...editDual,\n      tradeData,\n    })\n  }\n\n  const availableTradeCheck = React.useCallback((): {\n    tradeBtnStatus: TradeBtnStatus\n    label: string\n  } => {\n    const account = store.getState().account\n    const { maxDuration, newStrike } = dualViewInfo?.__raw__?.order?.dualReinvestInfo ?? {}\n    if (account.readyState === AccountStatus.ACTIVATED && tradeData) {\n      if (!tradeData.isRenew) {\n        return {\n          tradeBtnStatus: TradeBtnStatus.AVAILABLE,\n          label: 'labelConfirm',\n        }\n      } else if (\n        tradeData.isRenew &&\n        tradeData.renewDuration &&\n        tradeData.renewTargetPrice &&\n        (tradeData.renewDuration !== (maxDuration ?? 0) / 86400000 ||\n          !sdk.toBig(tradeData.renewTargetPrice).eq(newStrike))\n      ) {\n        return {\n          tradeBtnStatus: TradeBtnStatus.AVAILABLE,\n          label: '',\n        }\n      } else {\n        return { tradeBtnStatus: TradeBtnStatus.DISABLED, label: '' } // label: ''}\n      }\n    }\n    return { tradeBtnStatus: TradeBtnStatus.AVAILABLE, label: '' }\n  }, [dualViewInfo, tradeData.isRenew, tradeData.renewDuration, tradeData.renewTargetPrice])\n  const onSubmitBtnClick = React.useCallback(\n    async (props?: any) => {\n      const editDual = store.getState()._router_tradeDual.editDual\n      const account = store.getState().account\n      let { tradeData: _tradeData } = editDual\n      _tradeData = { ...tradeData, ..._tradeData }\n      const tradeDual = editDual?.dualViewInfo?.__raw__?.order\n      const dualViewInfo = editDual?.dualViewInfo\n      try {\n        setIsLoading(true)\n        if (\n          LoopringAPI.userAPI &&\n          LoopringAPI.defiAPI &&\n          tradeDual &&\n          dualViewInfo &&\n          exchangeInfo\n        ) {\n          let request: any = {\n            currentDualHash: tradeDual.hash,\n            isRecursive: tradeDual.dualReinvestInfo.isRecursive,\n            maxDuration: tradeDual.dualReinvestInfo.maxDuration,\n            newStrike: tradeDual.dualReinvestInfo.newStrike,\n            accountId: account.accountId,\n          }\n          if (!_tradeData.isRenew) {\n            request.isRecursive = false\n          } else {\n            request.isRecursive = true\n            request.maxDuration = tradeDual.dualReinvestInfo.maxDuration && tradeDual.dualReinvestInfo.maxDuration !== 0 ? tradeDual.dualReinvestInfo.maxDuration : 60*60*1000*24\n            if (\n              _tradeData.renewDuration &&\n              _tradeData.renewDuration !== (request.maxDuration ?? 0) / 86400000\n            ) {\n              request.maxDuration = Number(_tradeData.renewDuration) * 86400000\n            }\n            if (\n              _tradeData.renewTargetPrice &&\n              tradeDual?.tokenInfoOrigin?.storageId !== undefined &&\n              !sdk.toBig(_tradeData.renewTargetPrice).eq(tradeDual.dualReinvestInfo.newStrike)\n            ) {\n              const req: sdk.GetNextStorageIdRequest = {\n                accountId: account.accountId,\n                sellTokenId: tradeDual.tokenInfoOrigin.tokenIn ?? 0,\n              }\n              const storageId = await LoopringAPI.userAPI.getNextStorageId(req, account.apiKey)\n              request.newStrike = _tradeData.renewTargetPrice\n              const [, , base, quote] =\n                (tradeDual.tokenInfoOrigin.market ?? 'dual-').match(/(dual-)?(\\w+)-(\\w+)/i) ?? []\n              const buyToken =\n                tradeDual.dualType === sdk.DUAL_TYPE.DUAL_BASE ? tokenMap[quote] : tokenMap[base] //tokenMap[idIndex[tradeDual.tokenInfoOrigin.tokenOut]]\n              const sellToken = tokenMap[idIndex[tradeDual.tokenInfoOrigin.tokenIn]]\n\n              request.newOrder = {\n                exchange: exchangeInfo.exchangeAddress,\n                storageId: storageId.orderId,\n                accountId: account.accountId,\n                sellToken: {\n                  tokenId: tradeDual.tokenInfoOrigin.tokenIn, //tradeDual.tokenInfoOrigin.tokenIn ?? 0,\n                  volume: tradeDual.tokenInfoOrigin.amountIn,\n                },\n                buyToken: {\n                  tokenId: buyToken.tokenId,\n                  //tradeDual.tokenInfoOrigin.tokenOut ?? 0,\n                  ...(tradeDual.dualType === sdk.DUAL_TYPE.DUAL_BASE\n                    ? {\n                        volume: sdk\n                          .toBig(\n                            sdk\n                              .toBig(tradeDual.tokenInfoOrigin.amountIn)\n                              .div('1e' + sellToken.decimals)\n                              .times(request.newStrike)\n                              .toFixed(buyToken.precision, BigNumber.ROUND_CEIL),\n                          )\n                          .times('1e' + buyToken.decimals)\n                          .toString(),\n                      }\n                    : {\n                        volume: sdk\n                          .toBig(\n                            sdk\n                              .toBig(\n                                sdk\n                                  .toBig(tradeDual.tokenInfoOrigin.amountIn)\n                                  .div('1e' + sellToken.decimals),\n                              )\n                              .div(request.newStrike)\n                              .toFixed(buyToken.precision, BigNumber.ROUND_CEIL),\n                          )\n                          .times('1e' + buyToken.decimals)\n                          .toFixed(0, BigNumber.ROUND_FLOOR),\n                      }),\n                },\n                validUntil: getTimestampDaysLater(DAYS * 12),\n                maxFeeBips: 5,\n                fillAmountBOrS: false,\n                fee: tradeDual.feeVol ?? '0',\n                baseProfit: tradeDual.dualReinvestInfo.profit,\n                settleRatio: tradeDual?.settleRatio?.toString()?.replaceAll(sdk.SEP, ''),\n                expireTime: tradeDual.expireTime,\n              }\n            }\n          }\n          myLog('DualTrade request:', request)\n          const response = await LoopringAPI.defiAPI.editDual(\n            request,\n            account.eddsaKey.sk,\n            account.apiKey,\n          )\n\n          if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n            const errorItem = /DUAL_PRODUCT_STOPPED/gi.test(\n              (response as sdk.RESULT_INFO).message ?? '',\n            )\n              ? SDK_ERROR_MAP_TO_UI[115003]\n              : SDK_ERROR_MAP_TO_UI[700001]\n            throw new CustomErrorWithCode({\n              ...response,\n              ...errorItem,\n            } as any)\n          } else {\n            setShowDual({ isShow: false, dualInfo: undefined })\n            setToastOpen({\n              open: true,\n              type: ToastType.success,\n              content: t('labelDualEditSuccess'),\n            })\n            // await sdk.sleep(SUBMIT_PANEL_AUTO_CLOSE)\n          }\n          refresh &&\n            refresh(\n              {\n                ...dualViewInfo,\n                ...dualViewInfo.__raw__.order,\n                __raw__: {\n                  order: {\n                    ...dualViewInfo.__raw__.order,\n                    dualReinvestInfo: {\n                      ...dualViewInfo?.__raw__?.dualReinvestInfo,\n                      newStrike: request.newStrike,\n                      maxDuration: request.maxDuration,\n                      isRecursive: request.isRecursive,\n                    },\n                  },\n                },\n              } as any,\n              props && props.dontCloseModal,\n            )\n        } else {\n          throw new Error('api not ready')\n        }\n      } catch (reason) {\n        if (!_tradeData.isRenew) {\n          resetEditDual()\n        }\n        setToastOpen({\n          open: true,\n          type: ToastType.error,\n          content: t('labelDualEditFailed'),\n        })\n      }\n      setIsLoading(false)\n    },\n    [\n      exchangeInfo,\n      setShowAccount,\n      setShowDual,\n      tradeData.isRenew,\n      tradeData.renewDuration,\n      tradeData.renewTargetPrice,\n    ],\n  )\n\n  const {\n    btnStatus,\n    onBtnClick,\n    btnLabel: tradeMarketI18nKey,\n  } = useSubmitBtn({\n    availableTradeCheck,\n    isLoading,\n    submitCallback: onSubmitBtnClick,\n  })\n\n  return {\n    editDualTrade: tradeData,\n    editDualBtnInfo: {\n      label: tradeMarketI18nKey,\n      params: {},\n    },\n    onEditDualClick: onBtnClick,\n    handleOnchange,\n    editDualBtnStatus: btnStatus,\n    dualToastOpen: toastOpen,\n    closeDualToast: closeToast,\n    setDualTradeData: setTradeData,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/useDualTrade.ts",
    "content": "import React from 'react'\nimport {\n  AccountStep,\n  DualChgData,\n  DualWrapProps,\n  useOpenModals,\n  useSettings,\n  useToggle,\n} from '@loopring-web/component-lib'\nimport {\n  AccountStatus,\n  CustomErrorWithCode,\n  DualCalcData,\n  DualTrade,\n  DualViewInfo,\n  getValuePrecisionThousand,\n  globalSetup,\n  myLog,\n  SagaStatus,\n  SDK_ERROR_MAP_TO_UI,\n  SUBMIT_PANEL_AUTO_CLOSE,\n  TradeBtnStatus,\n} from '@loopring-web/common-resources'\n\nimport {\n  DAYS,\n  getTimestampDaysLater,\n  makeDualViewItem,\n  makeWalletLayer2,\n  TradeDual,\n  useDualMap,\n  useSubmitBtn,\n  useToast,\n  useWalletLayer2Socket,\n  walletLayer2Service,\n} from '@loopring-web/core'\nimport _ from 'lodash'\n\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nimport { LoopringAPI, store, useAccount, useSystem, useTokenMap } from '../../index'\nimport { confirmation, useTradeDual } from '../../stores'\n\nexport const useDualTrade = <\n  T extends DualTrade<I>,\n  I,\n  ACD extends DualCalcData<R>,\n  R extends DualViewInfo,\n>() => {\n  const refreshRef = React.useRef()\n  const { dualAuto } = useSettings()\n  const { confirmation: { showAutoDefault }, setShowAutoDefault } = confirmation.useConfirmation()\n\n  const { exchangeInfo, allowTrade } = useSystem()\n  const { tokenMap, marketArray } = useTokenMap()\n  const { setShowAccount } = useOpenModals()\n  const { marketMap: dualMarketMap } = useDualMap()\n  const { account, status: accountStatus } = useAccount()\n  const { setShowDual } = useOpenModals()\n  const { toastOpen, closeToast } = useToast()\n  const {\n    modals: { isShowDual },\n    setShowSupport,\n    setShowTradeIsFrozen,\n  } = useOpenModals()\n  const { tradeDual, updateTradeDual, resetTradeDual } = useTradeDual()\n  const [serverUpdate, setServerUpdate] = React.useState(false)\n  const {\n    toggle: { dualInvest, dual_reinvest },\n  } = useToggle()\n\n  const [[coinSellSymbol, coinBuySymbol], setSellBuySymbol] = React.useState<\n    [string | undefined, string | undefined]\n  >([undefined, undefined])\n  // });\n  const [isLoading, setIsLoading] = React.useState(false)\n  const [productInfo, setProductInfo] = React.useState<R>(undefined as any)\n\n  const refreshDual = React.useCallback(\n    ({\n      dualInfo = productInfo,\n      tradeData,\n      balance,\n      index = productInfo?.__raw__.index,\n    }: {\n      dualInfo?: R\n      tradeData?: T\n      balance?: { [key: string]: sdk.DualBalance }\n      index?: sdk.DualIndex\n    }) => {\n      let walletMap: any = {}\n      let { sellSymbol, buySymbol } = isShowDual.dualInfo as R\n      // feeVol: string | undefined = undefined;\n      let { info } = dualInfo.__raw__\n      const {\n        tradeDual: { coinSell: _coinSell },\n      } = store.getState()._router_tradeDual\n      let _updateInfo: Partial<TradeDual<R>> = {\n        dualViewInfo: _.cloneDeep(dualInfo),\n      }\n      if (productInfo?.productId === dualInfo.productId) {\n        _updateInfo = {\n          ...(tradeDual as TradeDual<R>),\n          ..._updateInfo,\n        }\n      } else {\n        // resetTradeDual();\n        // info = _updateInfo.dualViewInfo.__raw__.info;\n      }\n      if (index && _updateInfo.dualViewInfo) {\n        _updateInfo.dualViewInfo.__raw__.index = index\n      } else if (!_updateInfo.dualViewInfo) {\n        return\n      }\n      if (balance) {\n        _updateInfo.balance = balance\n      }\n\n      const [baseSymbol, quoteSymbol] = [sellSymbol, buySymbol]\n\n      const dualMarket =\n        dualMarketMap[`DUAL-${sellSymbol}-${buySymbol}`] ??\n        dualMarketMap[`DUAL-${buySymbol}-${sellSymbol}`]\n\n      setSellBuySymbol([baseSymbol, quoteSymbol])\n      let coinSell: any = tradeData ?? {}\n      if (tradeData && tradeData.belong === baseSymbol) {\n        // coinSell= tradeData;\n      } else if (_coinSell?.belong === baseSymbol) {\n        coinSell = {\n          ..._coinSell,\n        } as unknown as T\n      } else {\n        const isRenew =\n          _updateInfo?.coinSell?.isRenew ?? (dual_reinvest?.enable && dualAuto.auto) ? true : false\n        let calc = (_updateInfo.dualViewInfo.expireTime - Date.now()) / 86400000\n        calc = calc < 1 ? Math.ceil(calc) : Math.floor(calc)\n        const renewDuration = Number(\n          tradeDual?.coinSell?.renewDuration ?? (dualAuto.day === 'auto' ? calc : dualAuto.day),\n        )\n        coinSell = {\n          balance: _updateInfo?.coinSell?.balance ?? 0,\n          tradeValue: _updateInfo?.coinSell?.tradeValue ?? undefined,\n          belong: baseSymbol,\n          isRenew,\n          renewDuration,\n        } as unknown as T\n      }\n      const existedMarket = sdk.getExistedMarket(marketArray, baseSymbol, quoteSymbol)\n      if (account.readyState == AccountStatus.ACTIVATED && existedMarket) {\n        walletMap = makeWalletLayer2({ needFilterZero: true }).walletMap\n        coinSell.balance = walletMap[baseSymbol]?.count\n      }\n\n      const dualViewInfo = makeDualViewItem(\n        info,\n        index ?? ({} as any),\n        dualInfo.__raw__.rule,\n        sellSymbol,\n        buySymbol,\n        dualMarket,\n      )\n      if (_updateInfo.balance) {\n        const calDualValue: sdk.CalDualResult = sdk.calcDual({\n          ...dualInfo.__raw__,\n          balance: _updateInfo.balance,\n          // feeVol,\n          sellToken: tokenMap[baseSymbol],\n          buyToken: tokenMap[quoteSymbol],\n          sellAmount: coinSell.tradeValue?.toString() ?? undefined,\n          dualMarket,\n        })\n        _updateInfo = {\n          ..._updateInfo,\n          ...(calDualValue as TradeDual<R>),\n        }\n      }\n\n      updateTradeDual({ ..._updateInfo, dualViewInfo, coinSell })\n    },\n    [\n      account.readyState,\n      dualMarketMap,\n      isShowDual.dualInfo,\n      marketArray,\n      productInfo,\n      tokenMap,\n      tradeDual,\n      updateTradeDual,\n      dualAuto,\n    ],\n  )\n\n  const handleOnchange = ({ tradeData }: DualChgData<T>) => {\n    refreshDual({ tradeData })\n  }\n\n  const availableTradeCheck = React.useCallback((): {\n    tradeBtnStatus: TradeBtnStatus\n    label: string\n  } => {\n    const account = store.getState().account\n    const tradeDual = store.getState()._router_tradeDual.tradeDual\n    if (account.readyState === AccountStatus.ACTIVATED && coinSellSymbol && tradeDual?.coinSell) {\n      const sellToken = tokenMap[tradeDual?.coinSell.belong]\n      const sellExceed = sdk\n        .toBig(tradeDual.coinSell?.tradeValue ?? 0)\n        .gt(tradeDual?.coinSell?.balance ?? 0)\n      // myLog(\"sellExceed\", sellExceed, tradeDual.sellVol, tradeDual);\n      if (\n        tradeDual?.sellVol === undefined ||\n        sdk.toBig(tradeDual?.sellVol).lte(0) ||\n        tradeDual?.maxFeeBips === undefined ||\n        tradeDual?.maxFeeBips === 0\n      ) {\n        return {\n          tradeBtnStatus: TradeBtnStatus.DISABLED,\n          label: 'labelEnterAmount',\n        }\n      } else if (\n        sdk\n          .toBig(tradeDual?.sellVol ?? 0)\n          .minus(tradeDual?.miniSellVol ?? 0)\n          .lt(0)\n      ) {\n        const sellMinVal = getValuePrecisionThousand(\n          sdk.toBig(tradeDual?.miniSellVol).div('1e' + sellToken?.decimals),\n          sellToken.precision,\n          sellToken.precision,\n          sellToken.precision,\n          false,\n          { floor: false, isAbbreviate: true },\n        )\n        const mimOrderSize = sellMinVal + ' ' + sellToken.symbol\n        return {\n          tradeBtnStatus: TradeBtnStatus.DISABLED,\n          label: `labelDualMin| ${mimOrderSize}`,\n        }\n      } else if (sellExceed) {\n        return {\n          tradeBtnStatus: TradeBtnStatus.DISABLED,\n          label: `labelDualNoEnough| ${coinSellSymbol}`,\n        }\n      } else if (\n        tradeDual?.maxSellAmount &&\n        tradeDual?.sellVol &&\n        sellToken &&\n        sdk.toBig(tradeDual?.coinSell?.tradeValue ?? 0).gte(tradeDual?.maxSellAmount)\n      ) {\n        const sellMaxVal = getValuePrecisionThousand(\n          tradeDual?.maxSellAmount,\n          sellToken.precision,\n          sellToken.precision,\n          sellToken.precision,\n          false,\n          { floor: false, isAbbreviate: true },\n        )\n        const maxOrderSize = sellMaxVal + ' ' + sellToken.symbol\n        return {\n          tradeBtnStatus: TradeBtnStatus.DISABLED,\n          label: `labelDualMax| ${maxOrderSize}`,\n        }\n      } else {\n        return { tradeBtnStatus: TradeBtnStatus.AVAILABLE, label: '' } // label: ''}\n      }\n    }\n    return { tradeBtnStatus: TradeBtnStatus.AVAILABLE, label: '' }\n  }, [coinSellSymbol, tokenMap])\n  const should15sRefresh = _.debounce(async (clearTrade: boolean = false) => {\n    if (productInfo && coinSellSymbol && coinBuySymbol && LoopringAPI.defiAPI) {\n      if (clearTrade) {\n        setIsLoading(true)\n      }\n      const dualMarket =\n        dualMarketMap[`DUAL-${coinSellSymbol}-${coinBuySymbol}`] ??\n        dualMarketMap[`DUAL-${coinBuySymbol}-${coinSellSymbol}`]\n      Promise.all([\n        LoopringAPI.defiAPI?.getDualIndex({\n          baseSymbol: productInfo.__raw__.info.base,\n          quoteSymbol: dualMarket.quoteAlias,\n        }),\n        LoopringAPI.defiAPI?.getDualPrices({\n          baseSymbol: productInfo.__raw__.info.base,\n          productIds: productInfo.productId,\n        }),\n        LoopringAPI.defiAPI?.getDualBalance(),\n      ])\n        .then(([dualIndexResponse, dualPriceResponse, dualBalanceResponse]) => {\n          const {\n            tradeDual: { dualViewInfo },\n          } = store.getState()._router_tradeDual\n          let dualInfo: R = _.cloneDeep(dualViewInfo) as R\n          let balance = undefined,\n            index = undefined\n          if (\n            (dualIndexResponse as sdk.RESULT_INFO).code ||\n            (dualIndexResponse as sdk.RESULT_INFO).message\n          ) {\n          } else {\n            index = dualIndexResponse.dualPrice\n          }\n          if (\n            (dualPriceResponse as sdk.RESULT_INFO).code ||\n            (dualPriceResponse as sdk.RESULT_INFO).message\n          ) {\n          }\n          if (dualInfo?.__raw__?.info && dualPriceResponse.infos) {\n            dualInfo.__raw__.info = {\n              ...dualInfo.__raw__.info,\n              ...dualPriceResponse.infos[0],\n            }\n          }\n          if (\n            (dualBalanceResponse as sdk.RESULT_INFO).code ||\n            (dualBalanceResponse as sdk.RESULT_INFO).message\n          ) {\n          } else {\n            balance = dualBalanceResponse.raw_data.reduce((prev: any, item: any) => {\n              prev[item.coin] = item\n              return prev\n            }, {} as any)\n          }\n          refreshDual({ dualInfo, balance, index })\n          setIsLoading(false)\n        })\n        .catch((error) => {\n          console.log(error)\n        })\n    }\n  }, globalSetup.wait)\n\n  const refreshClick = React.useCallback(() => {\n    if (refreshRef.current && tradeDual) {\n      //@ts-ignore\n      refreshRef.current.firstElementChild.click()\n      myLog('should15sRefresh refreshRef.current click only')\n      should15sRefresh(true)\n    }\n  }, [tradeDual])\n  React.useEffect(() => {\n    if (isShowDual?.isShow && isShowDual?.dualInfo?.__raw__) {\n      setProductInfo(isShowDual.dualInfo as R)\n      refreshDual({ dualInfo: isShowDual.dualInfo as R })\n    } else {\n      resetTradeDual()\n    }\n    refreshClick()\n    return () => {\n      myLog('should15sRefresh cancel')\n      resetTradeDual()\n      should15sRefresh.cancel()\n    }\n  }, [isShowDual, refreshRef.current])\n\n  const walletLayer2Callback = React.useCallback(async () => {\n    const {\n      tradeDual: { coinSell },\n    } = store.getState()._router_tradeDual\n    if (coinSell) {\n      if (account.readyState === AccountStatus.ACTIVATED) {\n        refreshDual({ tradeData: { ...coinSell } as T })\n      } else {\n        refreshDual({ tradeData: { ...coinSell, tradeValue: undefined } as T })\n      }\n    }\n  }, [account.readyState, refreshDual])\n\n  useWalletLayer2Socket({ walletLayer2Callback })\n  const sendRequest = React.useCallback(async () => {\n    const tradeDual = store.getState()._router_tradeDual.tradeDual\n    const account = store.getState().account\n\n    try {\n      setIsLoading(true)\n      if (\n        LoopringAPI.userAPI &&\n        LoopringAPI.defiAPI &&\n        tradeDual &&\n        tradeDual.coinSell?.belong &&\n        tradeDual.maxFeeBips &&\n        exchangeInfo\n      ) {\n        const sellToken = tokenMap[tradeDual.coinSell?.belong]\n        const req: sdk.GetNextStorageIdRequest = {\n          accountId: account.accountId,\n          sellTokenId: sellToken?.tokenId ?? 0,\n        }\n        const storageId = await LoopringAPI.userAPI.getNextStorageId(req, account.apiKey)\n        if ((storageId as sdk.RESULT_INFO).code || (storageId as sdk.RESULT_INFO).message) {\n          const errorItem = SDK_ERROR_MAP_TO_UI[700001]\n          throw new CustomErrorWithCode({\n            ...storageId,\n            ...errorItem,\n          } as any)\n        }\n        const {\n          dualType,\n          productId,\n          profit,\n          // dualPrice: { dualBid },\n        } = tradeDual.dualViewInfo.__raw__.info\n\n        const isRenew = tradeDual.coinSell?.isRenew\n          ? {\n              isRecursive: true,\n              maxRecurseProductDuration: Number(tradeDual?.coinSell?.renewDuration ?? 7) * 86400000,\n            }\n          : {}\n        // myLog(\"fee\", tradeDual.feeVol);\n        const request: sdk.DualOrderRequest = {\n          clientOrderId: '',\n          exchange: exchangeInfo.exchangeAddress,\n          storageId: storageId.orderId,\n          accountId: account.accountId,\n          sellToken: {\n            tokenId: sellToken?.tokenId ?? 0,\n            volume: tradeDual.sellVol,\n          },\n          buyToken:\n            dualType === sdk.DUAL_TYPE.DUAL_BASE\n              ? {\n                  tokenId: tokenMap[tradeDual.greaterEarnTokenSymbol]?.tokenId ?? 0,\n                  volume: tradeDual.greaterEarnVol,\n                }\n              : {\n                  tokenId: tokenMap[tradeDual.lessEarnTokenSymbol]?.tokenId ?? 0,\n                  volume: tradeDual.lessEarnVol,\n                },\n          validUntil: getTimestampDaysLater(DAYS * 12),\n          maxFeeBips: tradeDual.maxFeeBips,\n          fillAmountBOrS: false,\n          fee: tradeDual.feeVol ?? '0',\n          baseProfit: profit,\n          productId,\n          settleRatio: tradeDual.dualViewInfo.settleRatio.replaceAll(sdk.SEP, ''), //sdk.toBig(tradeDual.dualViewInfo.settleRatio).f,\n          expireTime: tradeDual.dualViewInfo.expireTime,\n          ...isRenew,\n        }\n        myLog('DualTrade request:', request)\n        const response = await LoopringAPI.defiAPI.orderDual(\n          request,\n          account.eddsaKey.sk,\n          account.apiKey,\n        )\n        if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n          const errorItem = /DUAL_PRODUCT_STOPPED/gi.test(\n            (response as sdk.RESULT_INFO).message ?? '',\n          )\n            ? SDK_ERROR_MAP_TO_UI[115003]\n            : SDK_ERROR_MAP_TO_UI[700001]\n          throw new CustomErrorWithCode({\n            ...response,\n            ...errorItem,\n          } as any)\n        } else {\n          setShowDual({ isShow: false, dualInfo: undefined })\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.Dual_Success,\n            info: {\n              symbol: sellToken.symbol,\n              value: tradeDual.coinSell.tradeValue,\n            },\n          })\n          await sdk.sleep(SUBMIT_PANEL_AUTO_CLOSE)\n          if (\n            store.getState().modals.isShowAccount.isShow &&\n            store.getState().modals.isShowAccount.step == AccountStep.Dual_Success\n          ) {\n            setShowAccount({ isShow: false })\n          }\n        }\n      } else {\n        throw new Error('api not ready')\n      }\n      walletLayer2Service.sendUserUpdate()\n    } catch (reason) {\n      setShowAccount({\n        isShow: true,\n        step: AccountStep.Dual_Failed,\n        error: reason as sdk.RESULT_INFO,\n        info: {\n          symbol: tradeDual?.coinSell?.belong,\n        },\n      })\n    } finally {\n      should15sRefresh(true)\n    }\n  }, [exchangeInfo, setShowAccount, setShowDual, tokenMap])\n\n  // const isNoBalance = ;\n  const onSubmitBtnClick = React.useCallback(async () => {\n    const { tradeDual } = store.getState()._router_tradeDual\n\n    if (\n      (account.readyState === AccountStatus.ACTIVATED &&\n        tokenMap &&\n        exchangeInfo &&\n        account.eddsaKey?.sk,\n      tradeDual.sellVol)\n    ) {\n      if (!allowTrade.defiInvest.enable) {\n        setShowSupport({ isShow: true })\n      } else if (!dualInvest.enable) {\n        setShowTradeIsFrozen({ isShow: true, type: 'DualInvest' })\n      } else {\n        sendRequest()\n      }\n    } else {\n      return false\n    }\n  }, [tokenMap, coinSellSymbol])\n\n  React.useEffect(() => {\n    if (accountStatus === SagaStatus.UNSET) {\n      walletLayer2Callback()\n    }\n  }, [accountStatus])\n\n  const {\n    btnStatus,\n    onBtnClick,\n    btnLabel: tradeMarketI18nKey,\n  } = useSubmitBtn({\n    availableTradeCheck,\n    isLoading,\n    submitCallback: onSubmitBtnClick,\n  })\n\n  const dualTradeProps: DualWrapProps<T, I, ACD> = {\n    refreshRef,\n    disabled: false,\n    btnInfo: {\n      label: tradeMarketI18nKey,\n      params: {},\n    },\n    toggle: dual_reinvest,\n    isLoading,\n    tokenMap: tokenMap as any,\n    onRefreshData: should15sRefresh,\n    onSubmitClick: onBtnClick as () => void,\n    onChangeEvent: handleOnchange,\n    tokenSellProps: {},\n    dualCalcData: tradeDual as ACD,\n    // maxSellVol: tradeDual.maxSellVol,\n    tokenSell: tokenMap[coinSellSymbol ?? ''],\n    btnStatus,\n    accStatus: account.readyState as AccountStatus,\n    showAutoDefault,\n    setShowAutoDefault,\n  } // as ForceWithdrawProps<any, any>;\n  return {\n    dualTradeProps,\n    serverUpdate,\n    setServerUpdate,\n    dualToastOpen: toastOpen,\n    closeDualToast: closeToast,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/useEditCollection.tsx",
    "content": "import {\n  CollectionMeta,\n  ErrorType,\n  IPFS_HEAD_URL,\n  myLog,\n  NFTSubRouter,\n  RouterPath,\n  SDK_ERROR_MAP_TO_UI,\n  UIERROR_CODE,\n} from '@loopring-web/common-resources'\n\nimport { BigNumber } from 'bignumber.js'\nimport React from 'react'\nimport {\n  getIPFSString,\n  ipfsService,\n  LoopringAPI,\n  store,\n  useAccount,\n  useBtnStatus,\n  useIPFS,\n  useModalData,\n  useSystem,\n  useToast,\n  useWalletL2Collection,\n} from '../../index'\nimport { IpfsFile, ToastType, useToggle } from '@loopring-web/component-lib'\nimport { useHistory, useRouteMatch } from 'react-router-dom'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { AddResult } from 'ipfs-core-types/src/root'\nimport { useTranslation } from 'react-i18next'\n\n// const enum MINT_VIEW_STEP {\n//   METADATA,\n//   MINT_CONFIRM,\n// }\n\nBigNumber.config({ EXPONENTIAL_AT: 100 })\nexport const useEditCollection = <T extends CollectionMeta>({\n  isEdit = false,\n  type,\n}: {\n  isEdit?: boolean\n  type: 'addCollection' | 'editCollection' | 'addLegacyCollection'\n}) => {\n  const {\n    toggle: { collectionNFT },\n  } = useToggle()\n  const {\n    toastOpen: collectionToastOpen,\n    setToastOpen: setCollectionToastOpen,\n    closeToast: collectionToastClose,\n  } = useToast()\n  let match: any = useRouteMatch('/nft/:type?/:tokenAddress?')\n  const { t } = useTranslation('common')\n  const [disabled, _setDisabled] = React.useState(!collectionNFT.enable)\n  const { collectionValue, updateCollectionData, resetCollectionData } = useModalData()\n  const [collectionOldValue] = React.useState<T | undefined>(\n    isEdit\n      ? ({\n          ...collectionValue,\n        } as T)\n      : undefined,\n  )\n\n  const { baseURL, chainId } = useSystem()\n  const { updateWalletL2Collection } = useWalletL2Collection()\n  const history = useHistory()\n  const keysEditInit = (collection: Partial<CollectionMeta> = {}) => {\n    // const req = Promise.all([\n    //   fetch(getIPFSString(collection.banner, baseURL), {\n    //     method: \"HEAD\",\n    //   }),\n    //   fetch(getIPFSString(collection.tileUri, baseURL), {\n    //     method: \"HEAD\",\n    //   }),\n    //   fetch(getIPFSString(collection.avatar, baseURL), {\n    //     method: \"HEAD\",\n    //   }),\n    // ]).then([]);\n    // tokenInfo.__mediaType__ = getMediaType(\n    //   req?.headers?.get(\"content-type\") ?? \"\"\n    // );\n    return {\n      banner: collection.banner\n        ? ({\n            error: undefined,\n            file: {\n              type: 'image/*',\n            },\n            fullSrc: getIPFSString(collection.banner, baseURL),\n            localSrc: getIPFSString(collection.banner, baseURL),\n            isProcessing: false,\n            isUpdateIPFS: false,\n            uniqueId: '',\n          } as unknown as IpfsFile)\n        : undefined,\n      tileUri: collection.tileUri\n        ? ({\n            error: undefined,\n            file: {\n              type: 'image/*',\n            },\n            fullSrc: getIPFSString(collection.tileUri, baseURL),\n            localSrc: getIPFSString(collection.tileUri, baseURL),\n            isProcessing: false,\n            isUpdateIPFS: false,\n            uniqueId: '',\n          } as unknown as IpfsFile)\n        : undefined,\n      avatar: collection.avatar\n        ? ({\n            error: undefined,\n            file: {\n              type: 'image/*',\n            },\n            fullSrc: getIPFSString(collection.avatar, baseURL),\n            localSrc: getIPFSString(collection.avatar, baseURL),\n            isProcessing: false,\n            isUpdateIPFS: false,\n            uniqueId: '',\n          } as unknown as IpfsFile)\n        : undefined,\n    }\n  }\n  const [keys, setKeys] = React.useState<{\n    [key: string]: undefined | IpfsFile\n  }>(() => {\n    return isEdit\n      ? keysEditInit(collectionOldValue)\n      : {\n          banner: undefined,\n          // name: undefined,\n          tileUri: undefined,\n          avatar: undefined,\n          // thumbnail: undefined,\n        }\n  })\n\n  const { account } = useAccount()\n\n  const {\n    btnStatus,\n    btnInfo,\n    enableBtn,\n    disableBtn,\n    setLabelAndParams,\n    resetBtnInfo,\n    setLoadingBtn,\n  } = useBtnStatus()\n  const updateBtnStatus = React.useCallback(\n    (error?: ErrorType & any) => {\n      resetBtnInfo()\n\n      const ipfsProcessing = Reflect.ownKeys(keys).find(\n        (key) => keys[key as string]?.isProcessing === true,\n      )\n\n      if (\n        !error &&\n        collectionValue &&\n        collectionValue.name &&\n        collectionValue.tileUri &&\n        ipfsProcessing === undefined\n      ) {\n        enableBtn()\n        return\n      }\n      if (!collectionValue?.name) {\n        setLabelAndParams('labelCollectionRequiredName', {})\n      }\n      if (!collectionValue?.tileUri) {\n        setLabelAndParams('labelCollectionRequiredTileUri', {})\n      }\n\n      if (ipfsProcessing) {\n        setLoadingBtn()\n        return\n      }\n\n      disableBtn()\n      myLog('try to disable nftMint btn!')\n    },\n    [resetBtnInfo, keys, collectionValue, disableBtn, enableBtn, setLabelAndParams, setLoadingBtn],\n  )\n\n  React.useEffect(() => {\n    updateBtnStatus()\n  }, [collectionValue, updateBtnStatus, keys])\n  React.useEffect(() => {\n    return () => {\n      resetCollectionData()\n    }\n  }, [])\n  const onSubmitClick = React.useCallback(async () => {\n    if (collectionValue.name?.trim() && collectionValue.tileUri?.trim() && LoopringAPI.userAPI) {\n      setLoadingBtn()\n      if (isEdit && type === 'editCollection' && collectionOldValue?.id) {\n        try {\n          const response = await LoopringAPI.userAPI.submitEditNFTCollection(\n            {\n              name: collectionValue.name?.trim(),\n              tileUri: collectionValue.tileUri?.trim(),\n              accountId: account.accountId,\n              banner: collectionValue.banner?.trim() ?? '',\n              avatar: collectionValue.avatar?.trim() ?? '',\n              description: collectionValue.description?.trim() ?? '',\n              collectionId: collectionOldValue.id ?? '',\n              // @ts-ignore\n              thumbnail: '',\n            },\n            chainId as any,\n            account.apiKey,\n            account.eddsaKey.sk,\n          )\n          if (\n            response &&\n            ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message)\n          ) {\n            const _response: sdk.RESULT_INFO = response as sdk.RESULT_INFO\n            throw new Error(\n              t(\n                _response.code && SDK_ERROR_MAP_TO_UI[_response.code]\n                  ? SDK_ERROR_MAP_TO_UI[_response.code].messageKey\n                  : SDK_ERROR_MAP_TO_UI[UIERROR_CODE.UNKNOWN].messageKey,\n                { ns: 'error', name: collectionValue.name?.trim() },\n              ),\n            )\n          } else {\n            setCollectionToastOpen({\n              open: true,\n              type: ToastType.success,\n              content: t('labelEditCollectionSuccess'),\n            })\n            updateWalletL2Collection({ page: 1 })\n            history.push(`${RouterPath.nft}/${NFTSubRouter.myCollection}`)\n          }\n          updateCollectionData({ ...collectionOldValue })\n          setKeys({\n            banner: undefined,\n            name: undefined,\n            tileUri: undefined,\n            avatar: undefined,\n            thumbnail: undefined,\n          })\n        } catch (error) {\n          setCollectionToastOpen({\n            open: true,\n            type: ToastType.error,\n            content:\n              t('labelEditCollectionFailed') +\n              `: ${(error as any)?.message ? (error as any).message : t('errorUnknown')}`,\n          })\n          resetBtnInfo()\n        }\n      } else if (type === 'addLegacyCollection' && account.accountId && match.params.tokenAddress) {\n        try {\n          const response = await LoopringAPI.userAPI.submitNFTLegacyCollection(\n            {\n              ...collectionValue,\n              tokenAddress: match.params.tokenAddress,\n              accountId: account.accountId,\n              name: collectionValue.name?.trim(),\n              tileUri: collectionValue.tileUri?.trim(),\n            },\n            chainId as any,\n            account.apiKey,\n            account.eddsaKey.sk,\n          )\n          if (\n            response &&\n            ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message)\n          ) {\n            const _response: sdk.RESULT_INFO = response as sdk.RESULT_INFO\n            throw new Error(\n              t(\n                _response.code && SDK_ERROR_MAP_TO_UI[_response.code]\n                  ? SDK_ERROR_MAP_TO_UI[_response.code].messageKey\n                  : SDK_ERROR_MAP_TO_UI[UIERROR_CODE.UNKNOWN].messageKey,\n                { ns: 'error', name: collectionValue.name?.trim() },\n              ),\n            )\n          } else {\n            setCollectionToastOpen({\n              open: true,\n              type: ToastType.success,\n              content: t('labelCreateCollectionSuccess'),\n            })\n            updateWalletL2Collection({ page: 1 })\n            history.push(\n              `${RouterPath.nft}/${NFTSubRouter.importLegacyCollection}/${match.params.tokenAddress}`,\n            )\n          }\n          updateCollectionData({})\n          setKeys({\n            banner: undefined,\n            name: undefined,\n            tileUri: undefined,\n            avatar: undefined,\n            thumbnail: undefined,\n          })\n        } catch (error) {\n          setCollectionToastOpen({\n            open: true,\n            type: ToastType.error,\n            content:\n              t('labelCreateCollectionFailed') +\n              `: ${(error as any)?.message ? (error as any).message : t('errorUnknown')}`,\n          })\n          resetBtnInfo()\n        }\n      } else {\n        try {\n          const response = await LoopringAPI.userAPI.submitNFTCollection(\n            {\n              ...collectionValue,\n              name: collectionValue.name?.trim(),\n              tileUri: collectionValue.tileUri?.trim(),\n              owner: account.accAddress,\n              nftFactory: sdk.NFTFactory_Collection[chainId],\n            } as sdk.CollectionMeta,\n            chainId as any,\n            account.apiKey,\n            account.eddsaKey.sk,\n          )\n          if (\n            response &&\n            ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message)\n          ) {\n            const _response: sdk.RESULT_INFO = response as sdk.RESULT_INFO\n            throw new Error(\n              t(\n                _response.code && SDK_ERROR_MAP_TO_UI[_response.code]\n                  ? SDK_ERROR_MAP_TO_UI[_response.code].messageKey\n                  : SDK_ERROR_MAP_TO_UI[UIERROR_CODE.UNKNOWN].messageKey,\n                { ns: 'error', name: collectionValue.name?.trim() },\n              ),\n            )\n          } else {\n            setCollectionToastOpen({\n              open: true,\n              type: ToastType.success,\n              content: t('labelCreateCollectionSuccess'),\n            })\n            updateWalletL2Collection({ page: 1 })\n            history.push(`${RouterPath.nft}/${NFTSubRouter.myCollection}`)\n          }\n          updateCollectionData({})\n          setKeys({\n            banner: undefined,\n            name: undefined,\n            tileUri: undefined,\n            avatar: undefined,\n            thumbnail: undefined,\n          })\n        } catch (error) {\n          setCollectionToastOpen({\n            open: true,\n            type: ToastType.error,\n            content:\n              t('labelCreateCollectionFailed') +\n              `: ${(error as any)?.message ? (error as any).message : t('errorUnknown')}`,\n          })\n          resetBtnInfo()\n        }\n      }\n    }\n  }, [\n    account,\n    chainId,\n    collectionOldValue,\n    collectionValue,\n    history,\n    isEdit,\n    resetBtnInfo,\n    setCollectionToastOpen,\n    setLoadingBtn,\n    t,\n    updateCollectionData,\n    updateWalletL2Collection,\n    match.params.tokenAddress,\n  ])\n\n  const handleOnDataChange = React.useCallback(\n    (key: string, value: any) => {\n      const collectionValue = store.getState()._router_modalData.collectionValue\n      myLog('collectionValue', collectionValue)\n      updateCollectionData({ ...collectionValue, [key]: value })\n    },\n    [updateCollectionData],\n  )\n\n  const onDelete = React.useCallback(\n    (key: string) => {\n      setKeys((state) => {\n        return {\n          ...state,\n          [key]: undefined,\n        }\n      })\n      handleOnDataChange(key, undefined)\n    },\n    [handleOnDataChange],\n  )\n\n  const handleFailedUpload = React.useCallback(\n    (data: { uniqueId: string; error: sdk.RESULT_INFO }) => {\n      setKeys((state) => {\n        const key: string = Reflect.ownKeys(state).find((key) => {\n          return state[key as any]?.uniqueId === data.uniqueId\n        }) as string\n        if (key) {\n          handleOnDataChange(key, undefined)\n          return {\n            ...state,\n            [key]: {\n              ...state[key],\n              isProcessing: false,\n              ...{\n                error: data.error\n                  ? data.error\n                  : {\n                      code: UIERROR_CODE.UNKNOWN,\n                      message: `Ipfs Error ${data}`,\n                    },\n              },\n            } as IpfsFile,\n          }\n        } else {\n          return state\n        }\n      })\n    },\n    [handleOnDataChange],\n  )\n  const handleSuccessUpload = React.useCallback(\n    (data: AddResult & { uniqueId: string }) => {\n      setKeys((state) => {\n        const key: string = Reflect.ownKeys(state).find((key) => {\n          return state[key as any]?.uniqueId === data.uniqueId\n        }) as string\n        if (key) {\n          const cid = data.cid.toString()\n          handleOnDataChange(key, `${IPFS_HEAD_URL}${data.path}`)\n          return {\n            ...state,\n            [key as any]: {\n              ...state[key as any],\n              ...{\n                cid,\n                fullSrc: getIPFSString(`${IPFS_HEAD_URL}${data.path}`, baseURL),\n                isProcessing: false,\n              },\n            },\n          }\n        } else {\n          return state\n        }\n      })\n    },\n    [baseURL, handleOnDataChange],\n  )\n\n  const { ipfsProvides } = useIPFS({\n    handleSuccessUpload,\n    handleFailedUpload,\n  })\n\n  const onFilesLoad = React.useCallback(\n    (key: string, value: IpfsFile) => {\n      let uniqueId = key + '|' + Date.now()\n      value.isUpdateIPFS = true\n      ipfsService.addFile({\n        ipfs: ipfsProvides.ipfs,\n        file: value.file,\n        uniqueId: uniqueId,\n      })\n      setKeys((state) => {\n        return {\n          ...state,\n          [key]: {\n            ...value,\n            file: value.file,\n            uniqueId: uniqueId,\n            cid: '',\n          },\n        }\n      })\n    },\n    [ipfsProvides.ipfs],\n  )\n\n  return {\n    keys,\n    isEdit,\n    collectionToastOpen,\n    collectionToastClose,\n    onFilesLoad,\n    onDelete,\n    btnStatus,\n    btnInfo,\n    disabled,\n    handleOnDataChange,\n    collectionValue,\n    resetEdit: isEdit\n      ? () => {\n          updateCollectionData({ ...collectionOldValue })\n          setKeys(keysEditInit(collectionOldValue))\n        }\n      : undefined,\n    onSubmitClick,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/useExportAccount.ts",
    "content": "import React from 'react'\n\nimport { AccountStatus } from '@loopring-web/common-resources'\nimport { useAccount } from '../../index'\nimport { useTranslation } from 'react-i18next'\n\nexport const useExportAccount = <_T>() => {\n  const { t } = useTranslation('common')\n  const { account } = useAccount()\n  const [accountInfo, setAccountInfo] = React.useState({\n    address: '',\n    accountId: 0,\n    level: '',\n    nonce: 0 as number | undefined,\n    apiKey: '',\n    publicX: '',\n    publicY: '',\n    privateKey: '',\n  })\n  const [exportAccountToastOpen, setExportAccountToastOpen] = React.useState(false)\n  const exportAccountAlertText = t('labelCopyClipBoard')\n\n  React.useEffect(() => {\n    if (account.readyState !== AccountStatus.ACTIVATED) {\n      return undefined\n    }\n\n    const accInfo = {\n      address: account.accAddress,\n      accountId: account.accountId,\n      level: account.level,\n      nonce: account.nonce,\n      apiKey: account.apiKey,\n      publicX: account.eddsaKey.formatedPx,\n      publicY: account.eddsaKey.formatedPy,\n      privateKey: account.eddsaKey.sk,\n    }\n    setAccountInfo(accInfo)\n  }, [account.readyState, account.nonce])\n\n  const exportAccountProps = {\n    accountInfo,\n  }\n\n  return {\n    exportAccountProps: exportAccountProps,\n    exportAccountAlertText,\n    exportAccountToastOpen,\n    setExportAccountToastOpen,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/useForceWithdraw.ts",
    "content": "import React from 'react'\nimport { ConnectProviders, connectProvides } from '@loopring-web/web3-provider'\nimport {\n  AccountStep,\n  ForceWithdrawProps,\n  SwitchData,\n  TransactionTradeViews,\n  useOpenModals,\n} from '@loopring-web/component-lib'\nimport {\n  AccountStatus,\n  CoinMap,\n  IBData,\n  myLog,\n  UIERROR_CODE,\n  WalletMap,\n  LIVE_FEE_TIMES,\n  SUBMIT_PANEL_AUTO_CLOSE,\n  TRADE_TYPE,\n  RecordTabIndex,\n} from '@loopring-web/common-resources'\nimport {\n  LAST_STEP,\n  updateForceWithdrawData as updateForceWithdrawDataStore,\n} from '@loopring-web/core'\n\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nimport {\n  useTokenMap,\n  useAccount,\n  BIGO,\n  DAYS,\n  getTimestampDaysLater,\n  LoopringAPI,\n  store,\n  useAddressCheck,\n  useBtnStatus,\n  walletLayer2Service,\n  useModalData,\n  isAccActivated,\n  useChargeFees,\n  useSystem,\n  WalletMapExtend,\n  WalletLayer2Map,\n} from '../../index'\nimport { useWalletInfo } from '../../stores/localStore/walletInfo'\nimport { useHistory, useRouteMatch } from 'react-router-dom'\nimport Web3 from 'web3'\n\nexport const useForceWithdraw = <R extends IBData<T>, T>() => {\n  const { tokenMap, totalCoinMap, idIndex } = useTokenMap()\n  const { account } = useAccount()\n  const { exchangeInfo, chainId } = useSystem()\n  const { setShowAccount } = useOpenModals()\n  const history = useHistory()\n  const match = useRouteMatch('/layer2/:forceWithdraw')\n  const { forceWithdrawValue, updateForceWithdrawData, resetForceWithdrawData } = useModalData()\n  const {\n    modals: { isShowAccount },\n  } = useOpenModals()\n  const {\n    chargeFeeTokenList,\n    isFeeNotEnough,\n    handleFeeChange,\n    feeInfo,\n    checkFeeIsEnough,\n    resetIntervalTime,\n  } = useChargeFees({\n    requestType: sdk.OffchainFeeReqType.FORCE_WITHDRAWAL,\n    updateData: ({ fee }) => {\n      const { forceWithdrawValue } = store.getState()._router_modalData\n      store.dispatch(updateForceWithdrawDataStore({ ...forceWithdrawValue, fee }))\n    },\n  })\n\n  const { checkHWAddr, updateHW } = useWalletInfo()\n  // const [forceWithDrawAccount, setForceWithDrawAccount] =\n  //   React.useState<by>();\n\n  const [walletItsMap, setWalletItsMap] = React.useState<WalletMap<T>>({})\n\n  const {\n    address,\n    realAddr,\n    setAddress,\n    checkAddAccountId,\n    addrStatus,\n    isLoopringAddress,\n    isActiveAccount,\n    isAddressCheckLoading,\n  } = useAddressCheck()\n\n  const { btnStatus, enableBtn, disableBtn } = useBtnStatus()\n\n  const checkBtnStatus = React.useCallback(() => {\n    if (\n      tokenMap &&\n      forceWithdrawValue?.fee?.belong &&\n      forceWithdrawValue.fee?.feeRaw &&\n      forceWithdrawValue.belong &&\n      forceWithdrawValue.balance &&\n      !!forceWithdrawValue?.withdrawAddress &&\n      !isFeeNotEnough.isFeeNotEnough\n    ) {\n      enableBtn()\n      myLog('enableBtn')\n      return\n    }\n    disableBtn()\n  }, [\n    tokenMap,\n    forceWithdrawValue.fee?.belong,\n    forceWithdrawValue.fee?.feeRaw,\n    forceWithdrawValue.belong,\n    forceWithdrawValue.balance,\n    forceWithdrawValue?.withdrawAddress,\n    isFeeNotEnough.isFeeNotEnough,\n    disableBtn,\n    enableBtn,\n  ])\n\n  React.useEffect(() => {\n    checkBtnStatus()\n  }, [\n    address,\n    addrStatus,\n    isFeeNotEnough.isFeeNotEnough,\n    forceWithdrawValue.fee?.belong,\n    forceWithdrawValue.fee?.feeRaw,\n    forceWithdrawValue.belong,\n    isLoopringAddress,\n    isActiveAccount,\n  ])\n\n  const walletLayer2Callback = React.useCallback(async () => {\n    if (\n      LoopringAPI.userAPI &&\n      realAddr &&\n      checkAddAccountId &&\n      isLoopringAddress &&\n      !isActiveAccount\n    ) {\n      const { userBalances } = await LoopringAPI.userAPI?.getUserBalances(\n        { accountId: checkAddAccountId, tokens: '' },\n        account.apiKey,\n      )\n      let walletMap: WalletMap<T> = {}\n      if (userBalances) {\n        const walletLayer2 = Reflect.ownKeys(userBalances).reduce((prev, item) => {\n          // @ts-ignore\n          return { ...prev, [idIndex[item]]: userBalances[Number(item)] }\n        }, {} as WalletLayer2Map<R>)\n        walletMap = Reflect.ownKeys(walletLayer2).reduce((prev, item) => {\n          const {\n            total,\n            locked,\n            // pending: { withdraw },\n          } = walletLayer2[item as string]\n          const countBig = sdk.toBig(total).minus(sdk.toBig(locked))\n\n          if (countBig.eq(BIGO)) {\n            return prev\n          }\n\n          return {\n            ...prev,\n            [item]: {\n              belong: item,\n              count: sdk.fromWEI(tokenMap, item, countBig.toString()),\n              detail: walletLayer2[item as string],\n            },\n          }\n        }, {} as WalletMapExtend<T>)\n      }\n      const key = Reflect.ownKeys(walletMap).length ? Reflect.ownKeys(walletMap)[0] : undefined\n      const _value = key ? walletMap[key] : undefined\n      updateForceWithdrawData({\n        withdrawAddress: realAddr,\n        belong: _value?.belong ?? '',\n        tradeValue: _value?.count,\n        balance: _value?.count,\n      })\n      setWalletItsMap({ ...walletMap })\n    } else {\n      setWalletItsMap({})\n    }\n  }, [\n    account.apiKey,\n    checkAddAccountId,\n    idIndex,\n    isActiveAccount,\n    isLoopringAddress,\n    realAddr,\n    tokenMap,\n    updateForceWithdrawData,\n  ])\n\n  React.useEffect(() => {\n    if (checkAddAccountId && isLoopringAddress && !isActiveAccount && !!realAddr) {\n      walletLayer2Callback()\n    } else {\n      setWalletItsMap({})\n      updateForceWithdrawData({\n        withdrawAddress: '',\n        belong: '',\n        tradeValue: undefined,\n        balance: undefined,\n      })\n    }\n  }, [isLoopringAddress, isActiveAccount, checkAddAccountId, realAddr])\n  // useWalletLayer2Socket({ walletLayer2Callback });\n  const resetDefault = React.useCallback(() => {\n    checkFeeIsEnough({ isRequiredAPI: true, intervalTime: LIVE_FEE_TIMES })\n    resetForceWithdrawData()\n    setWalletItsMap({})\n    setAddress('')\n  }, [checkFeeIsEnough, resetForceWithdrawData, setAddress])\n\n  React.useEffect(() => {\n    // @ts-ignore\n    if (match?.params?.forcewithdraw?.toLowerCase() === 'forcewithdraw') {\n      resetDefault()\n    } else {\n      resetIntervalTime()\n    }\n    return () => {\n      resetIntervalTime()\n    }\n  }, [match?.params])\n\n  const processRequest = React.useCallback(\n    async (request: sdk.OriginForcesWithdrawalsV3, isNotHardwareWallet: boolean) => {\n      const { apiKey, connectName, eddsaKey } = account\n\n      try {\n        if (connectProvides.usedWeb3 && LoopringAPI.userAPI && isAccActivated()) {\n          let isHWAddr = checkHWAddr(account.accAddress)\n\n          if (!isHWAddr && !isNotHardwareWallet) {\n            isHWAddr = true\n          }\n\n          myLog('force Withdraw processRequest:', isHWAddr, isNotHardwareWallet)\n          const response = await LoopringAPI.userAPI.submitForceWithdrawals(\n            {\n              request,\n              web3: connectProvides.usedWeb3 as unknown as Web3,\n              chainId: chainId === 'unknown' ? 1 : chainId,\n              walletType: (ConnectProviders[connectName] ??\n                connectName) as unknown as sdk.ConnectorNames,\n              eddsaKey: eddsaKey.sk,\n              apiKey,\n              isHWAddr,\n            },\n            {\n              accountId: account.accountId,\n              counterFactualInfo: eddsaKey.counterFactualInfo,\n            },\n          )\n          myLog('submitNFTWithdraw:', response)\n\n          if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n            throw response\n          }\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.ForceWithdraw_In_Progress,\n          })\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.ForceWithdraw_Submit,\n            info: {\n              symbol: forceWithdrawValue.belong,\n            },\n          })\n          if (isHWAddr) {\n            myLog('......try to set isHWAddr', isHWAddr)\n            updateHW({ wallet: account.accAddress, isHWAddr })\n          }\n          walletLayer2Service.sendUserUpdate()\n          resetDefault()\n          history.push(\n            `/l2assets/history/${RecordTabIndex.Transactions}?types=${TransactionTradeViews.forceWithdraw}`,\n          )\n          await sdk.sleep(SUBMIT_PANEL_AUTO_CLOSE)\n          if (\n            store.getState().modals.isShowAccount.isShow &&\n            store.getState().modals.isShowAccount.step == AccountStep.ForceWithdraw_Submit\n          ) {\n            setShowAccount({ isShow: false })\n          }\n        }\n      } catch (e: any) {\n        const code = sdk.checkErrorInfo(e, isNotHardwareWallet)\n        switch (code) {\n          case sdk.ConnectorError.NOT_SUPPORT_ERROR:\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.ForceWithdraw_First_Method_Denied,\n              info: {\n                symbol: forceWithdrawValue.belong,\n              },\n            })\n            break\n          case sdk.ConnectorError.USER_DENIED:\n          case sdk.ConnectorError.USER_DENIED_2:\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.ForceWithdraw_Denied,\n              info: {\n                symbol: forceWithdrawValue.belong,\n              },\n            })\n            break\n          default:\n            if ([102024, 102025, 114001, 114002].includes((e as sdk.RESULT_INFO)?.code || 0)) {\n              checkFeeIsEnough({ isRequiredAPI: true })\n            }\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.ForceWithdraw_Failed,\n              info: {\n                symbol: forceWithdrawValue.belong,\n              },\n              error: {\n                code: UIERROR_CODE.UNKNOWN,\n                msg: e?.message,\n                ...(e instanceof Error\n                  ? {\n                      message: e?.message,\n                      stack: e?.stack,\n                    }\n                  : e ?? {}),\n              },\n            })\n            break\n        }\n      }\n    },\n    [\n      account,\n      checkHWAddr,\n      chainId,\n      setShowAccount,\n      forceWithdrawValue.belong,\n      checkFeeIsEnough,\n      resetDefault,\n      updateHW,\n    ],\n  )\n\n  const handleForceWithdraw = React.useCallback(\n    async (_inputValue: R, isFirstTime: boolean = true) => {\n      const { accountId, accAddress, readyState, apiKey, eddsaKey } = account\n      const forceWithdrawValue = store.getState()._router_modalData.forceWithdrawValue\n\n      if (\n        readyState === AccountStatus.ACTIVATED &&\n        tokenMap &&\n        LoopringAPI.userAPI &&\n        exchangeInfo &&\n        forceWithdrawValue?.fee?.belong &&\n        forceWithdrawValue.fee?.feeRaw &&\n        forceWithdrawValue?.belong &&\n        forceWithdrawValue?.withdrawAddress &&\n        !isFeeNotEnough.isFeeNotEnough &&\n        eddsaKey?.sk\n      ) {\n        try {\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.ForceWithdraw_WaitForAuth,\n          })\n\n          const feeToken = tokenMap[forceWithdrawValue.fee.belong]\n          const feeRaw =\n            forceWithdrawValue.fee.feeRaw ?? forceWithdrawValue.fee.__raw__?.feeRaw ?? 0\n          const fee = sdk.toBig(feeRaw)\n          // const fee = sdk.toBig(forceWithdrawValue.fee.__raw__?.feeRaw ?? 0);\n\n          const storageId = await LoopringAPI.userAPI?.getNextStorageId(\n            {\n              accountId,\n              sellTokenId: Number(feeToken.tokenId),\n            },\n            apiKey,\n          )\n          const { broker } = await LoopringAPI.userAPI?.getAvailableBroker({\n            type: 1,\n          })\n\n          const request: sdk.OriginForcesWithdrawalsV3 = {\n            transfer: {\n              exchange: exchangeInfo.exchangeAddress,\n              payerAddr: accAddress,\n              payerId: accountId,\n              payeeAddr: broker,\n              storageId: storageId.offchainId,\n              token: {\n                tokenId: feeToken.tokenId,\n                volume: fee.toFixed(), // TEST: fee.toString(),\n              },\n              validUntil: getTimestampDaysLater(DAYS),\n            },\n            requesterAddress: accAddress,\n            tokenId: tokenMap[forceWithdrawValue.belong].tokenId,\n            withdrawAddress: forceWithdrawValue.withdrawAddress ?? realAddr,\n          }\n\n          myLog('ForcesWithdrawals request:', request)\n\n          processRequest(request, isFirstTime)\n        } catch (e: any) {\n          sdk.dumpError400(e)\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.ForceWithdraw_Failed,\n            error: {\n              code: UIERROR_CODE.UNKNOWN,\n              msg: e?.message,\n            },\n          })\n        }\n\n        return true\n      } else {\n        return false\n      }\n    },\n    [\n      account,\n      tokenMap,\n      exchangeInfo,\n      isFeeNotEnough.isFeeNotEnough,\n      setShowAccount,\n      realAddr,\n      processRequest,\n    ],\n  )\n\n  const retryBtn = React.useCallback(\n    (isHardwareRetry: boolean = false) => {\n      setShowAccount({\n        isShow: true,\n        step: AccountStep.ForceWithdraw_WaitForAuth,\n      })\n      handleForceWithdraw(\n        {\n          belong: forceWithdrawValue.belong,\n          balance: forceWithdrawValue.balance,\n          tradeValue: forceWithdrawValue.tradeValue,\n        } as R,\n        !isHardwareRetry,\n      )\n    },\n    [forceWithdrawValue, handleForceWithdraw, setShowAccount],\n  )\n  // myLog(\"walletItsMap\", walletItsMap);\n  // @ts-ignore\n  const forceWithdrawProps: ForceWithdrawProps<any, any> = React.useMemo(() => {\n    return {\n      disabled: false,\n      // onChangeEvent: undefined,\n      type: TRADE_TYPE.TOKEN,\n      addressDefault: address,\n      handleOnAddressChange: (value: any) => {\n        setAddress(value)\n        updateForceWithdrawData({\n          belong: '',\n          tradeValue: undefined,\n          balance: undefined,\n        })\n      },\n      lastFailed: isShowAccount?.info?.lastFailed === LAST_STEP.forceWithdraw,\n      isActiveAccount,\n      isNotAvailableAddress: !(isLoopringAddress && !isActiveAccount),\n      realAddr,\n      isAddressCheckLoading,\n      isLoopringAddress,\n      tradeData: forceWithdrawValue as any,\n      coinMap: totalCoinMap as CoinMap<T>,\n      walletMap: walletItsMap,\n      addrStatus,\n      withdrawBtnStatus: btnStatus,\n      onWithdrawClick: handleForceWithdraw,\n      handlePanelEvent: async (data: SwitchData<R>) => {\n        return new Promise((res: any) => {\n          if (data.to === 'button') {\n            if (data.tradeData.belong) {\n              const walletInfo = walletItsMap[data.tradeData.belong]\n\n              updateForceWithdrawData({\n                ...forceWithdrawValue,\n                belong: data.tradeData.belong,\n                tradeValue: walletInfo?.count, //data.tradeData?.tradeValue,\n                balance: walletInfo?.count,\n                // withdrawAddress: realAddr,\n              })\n            } else {\n              updateForceWithdrawData({\n                belong: '',\n                tradeValue: undefined,\n                balance: undefined,\n                // withdrawAddress: realAddr,\n              })\n            }\n          }\n          res()\n        })\n      },\n      handleFeeChange,\n      feeInfo,\n      chargeFeeTokenList,\n      isFeeNotEnough,\n    }\n  }, [\n    addrStatus,\n    address,\n    btnStatus,\n    isShowAccount,\n    chargeFeeTokenList,\n    feeInfo,\n    isShowAccount?.info?.lastFailed,\n    forceWithdrawValue,\n    handleFeeChange,\n    handleForceWithdraw,\n    isActiveAccount,\n    isAddressCheckLoading,\n    isFeeNotEnough,\n    isLoopringAddress,\n    realAddr,\n    setAddress,\n    totalCoinMap,\n    updateForceWithdrawData,\n    walletItsMap,\n  ]) // as ForceWithdrawProps<any, any>;\n\n  return {\n    forceWithdrawProps,\n    retryBtn,\n  }\n}\n\n// ErrorCode.ERR_REST_ACCOUNT_NOT_EXIST, //104003\n//   message =s\"payer hasn't completed opening an payerAccount, payerAccount id\n//\n// ErrorCode.ERR_ACCOUNT_FREEZED, //121001\n//   message = \"payer is freeze\"\n//\n//\n// ErrorCode.ERR_INVALID_ARGUMENT, //100001\n//   \"payer address and payer id is not match\"\n//\n// ErrorCode.ERR_INVALID_SIGNATURE, //100206\n//   \"inner transfer eddsa sig invalid\"\n//\n// ErrorCode.ERR_WALLET_BALANCE_NOT_ENOUGH, //109143\n//   s\"balance of ${transfer.tokenId} in payerAccount ${transfer.payerId} is not enough\"\n//\n// ErrorCode.ERR_NO_ACCOUNT, //113001\n//   s\"withdraw address payerAccount info not found ${targetAccount.error}\"\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/useNFTBurn.ts",
    "content": "import React from 'react'\n\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { ConnectProviders, connectProvides } from '@loopring-web/web3-provider'\nimport {\n  AccountStep,\n  SwitchData,\n  TransferProps,\n  useOpenModals,\n} from '@loopring-web/component-lib'\nimport {\n  AccountStatus,\n  CoinMap,\n  Explorer,\n  LIVE_FEE_TIMES,\n  myLog, SDK_ERROR_MAP_TO_UI,\n  SUBMIT_PANEL_AUTO_CLOSE,\n  TRADE_TYPE,\n  TradeNFT,\n  UIERROR_CODE,\n} from '@loopring-web/common-resources'\n\nimport {\n  BIGO,\n  DAYS,\n  getIPFSString,\n  getTimestampDaysLater,\n  isAccActivated,\n  LAST_STEP,\n  LoopringAPI,\n  store,\n  useAccount,\n  useBtnStatus,\n  useChargeFees,\n  useModalData,\n  useSystem,\n  useTokenMap,\n  useWalletLayer2,\n  useWalletLayer2WithNFTSocket,\n  walletLayer2Service,\n} from '../../index'\nimport { useWalletInfo } from '../../stores/localStore/walletInfo'\nimport { useHistory, useLocation } from 'react-router-dom'\nimport { NETWORKEXTEND, useContacts } from '../../stores'\nimport Web3 from 'web3'\nimport {useTranslation} from \"react-i18next\";\n\nexport const useNFTBurn = <R extends TradeNFT<T, any>, T>() => {\n  const {\n    setShowAccount,\n    setShowNFTTransfer,\n    setShowNFTDetail,\n    modals: {\n      isShowNFTDetail,\n      isShowNFTTransfer: {\n        isShow,\n        info,\n        address: contactAddress,\n        name: contactName,\n        addressType: contactAddressType,\n      },\n    },\n  } = useOpenModals()\n  const { t } = useTranslation()\n  const { tokenMap, totalCoinMap } = useTokenMap()\n  const { account } = useAccount()\n  const { exchangeInfo, chainId, baseURL } = useSystem()\n  const { updateWalletLayer2 } = useWalletLayer2()\n\n  const { nftTransferValue, updateNFTWithdrawData, updateNFTTransferData } =\n    useModalData()\n\n  const history = useHistory()\n  const { search, pathname } = useLocation()\n  const searchParams = new URLSearchParams(search)\n  const {\n    chargeFeeTokenList,\n    isFeeNotEnough,\n    handleFeeChange,\n    feeInfo,\n    resetIntervalTime,\n    checkFeeIsEnough,\n  } = useChargeFees({\n    tokenAddress: nftTransferValue.tokenAddress,\n    // requestType: sdk.OffchainNFTFeeReqType.NFT_TRANSFER,\n    requestType: sdk.OffchainNFTFeeReqType.NFT_TRANSFER,\n    updateData:\n      // React.useCallback(\n      ({ fee, requestType }) => {\n        let _requestType = sdk.OffchainNFTFeeReqType.NFT_TRANSFER\n        if (_requestType === requestType) {\n          const nftTransferValue = store.getState()._router_modalData.nftTransferValue\n          updateNFTTransferData({\n            ...nftTransferValue,\n            balance: sdk\n              .toBig(nftTransferValue.total ?? 0)\n              .minus(nftTransferValue.locked ?? 0)\n              .toNumber(),\n            fee,\n          })\n        }\n      },\n    //   [feeWithActive]\n    // ),\n  })\n  const { btnStatus, enableBtn, disableBtn } = useBtnStatus()\n  const checkBtnStatus = React.useCallback(() => {\n    if (\n      tokenMap &&\n      nftTransferValue.fee?.belong &&\n      nftTransferValue?.tradeValue &&\n      chargeFeeTokenList.length &&\n      !isFeeNotEnough.isFeeNotEnough &&\n      sdk.toBig(nftTransferValue.tradeValue).gt(BIGO) &&\n      sdk.toBig(nftTransferValue.tradeValue).lte(Number(nftTransferValue.balance) ?? 0)\n    ) {\n      enableBtn()\n      myLog('enableBtn')\n      return\n    }\n    disableBtn()\n  }, [\n    tokenMap,\n    nftTransferValue.fee?.belong,\n    nftTransferValue.tradeValue,\n    nftTransferValue.balance,\n    chargeFeeTokenList.length,\n    isFeeNotEnough?.isFeeNotEnough,\n\n    disableBtn,\n    enableBtn,\n  ])\n\n  React.useEffect(() => {\n    checkBtnStatus()\n  }, [\n    isFeeNotEnough.isFeeNotEnough,\n    nftTransferValue.tradeValue,\n    nftTransferValue.fee,\n  ])\n  const walletLayer2Callback = React.useCallback(() => {\n    checkFeeIsEnough()\n  }, [checkFeeIsEnough])\n  const { contacts, updateContacts, errorMessage: contactsErrorMessage } = useContacts()\n\n  useWalletLayer2WithNFTSocket({ walletLayer2Callback })\n\n  const resetDefault = React.useCallback(() => {\n    if (info?.isRetry) {\n      checkFeeIsEnough()\n      return\n    }\n    checkFeeIsEnough({ isRequiredAPI: true, intervalTime: LIVE_FEE_TIMES })\n    if (nftTransferValue.nftData) {\n      updateNFTTransferData({\n        balance: sdk\n          .toBig(nftTransferValue.total ?? 0)\n          .minus(nftTransferValue.locked ?? 0)\n          .toNumber(),\n        belong: nftTransferValue.name as any,\n        tradeValue: undefined,\n        fee: feeInfo,\n      })\n    } else {\n      updateNFTTransferData({\n        fee: feeInfo,\n        belong: '',\n        balance: 0,\n        tradeValue: 0,\n        address: '*',\n      })\n    }\n\n  }, [\n    info?.isRetry,\n    contactsErrorMessage,\n    checkFeeIsEnough,\n    nftTransferValue.nftData,\n    nftTransferValue.total,\n    nftTransferValue.locked,\n    nftTransferValue.name,\n    contactAddress,\n    updateContacts,\n    updateNFTTransferData,\n    feeInfo,\n  ])\n\n  React.useEffect(() => {\n    if (isShow || info?.isBurn) {\n      updateWalletLayer2()\n      resetDefault()\n    } else {\n      resetIntervalTime()\n    }\n    return () => {\n      resetIntervalTime()\n    }\n  }, [isShow, info?.isShowLocal])\n\n  const { checkHWAddr, updateHW } = useWalletInfo()\n\n  const [lastRequest, setLastRequest] = React.useState<any>({})\n\n  const processRequest = React.useCallback(\n    async (request: sdk.OriginNFTTransferRequestV3, isNotHardwareWallet: boolean) => {\n      const { apiKey, connectName, eddsaKey } = account\n      try {\n        if (connectProvides.usedWeb3 && LoopringAPI.userAPI && isAccActivated()) {\n          let isHWAddr = checkHWAddr(account.accAddress)\n\n          if (!isHWAddr && !isNotHardwareWallet) {\n            isHWAddr = true\n          }\n\n          setLastRequest({ request })\n\n          const response = await LoopringAPI.userAPI?.submitNFTInTransfer(\n            {\n              request,\n              web3: connectProvides.usedWeb3 as unknown as Web3,\n              chainId: chainId === NETWORKEXTEND.NONETWORK ? sdk.ChainId.MAINNET : chainId,\n              walletType: (ConnectProviders[ connectName ] ??\n                connectName) as unknown as sdk.ConnectorNames,\n              eddsaKey: eddsaKey.sk,\n              apiKey,\n              isHWAddr,\n            },\n            {\n              accountId: account.accountId,\n              counterFactualInfo: eddsaKey.counterFactualInfo,\n            },\n          )\n\n          myLog('submitInternalTransfer:', response)\n\n          if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n            throw response\n          }\n          setShowNFTTransfer({ isShow: false })\n          // setIsConfirmTransfer(false);\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.NFTBurn_In_Progress,\n          })\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.NFTBurn_Success,\n            info: {\n              symbol: nftTransferValue.name,\n              hash:\n                Explorer +\n                `tx/${(response as sdk.TX_HASH_API)?.hash}-nftTransfer-${account.accountId}-${\n                  request.token.tokenId\n                }-${request.storageId}`,\n            },\n          })\n          if (isHWAddr) {\n            myLog('......try to set isHWAddr', isHWAddr)\n            updateHW({ wallet: account.accAddress, isHWAddr })\n          }\n          setShowNFTDetail({\n            ...isShowNFTDetail,\n            locked: (\n              Number(isShowNFTDetail?.locked ?? 0) + Number(request?.token?.amount)\n            ).toString(),\n          })\n          updateNFTWithdrawData({\n            ...isShowNFTDetail,\n            locked: (\n              Number(isShowNFTDetail?.locked ?? 0) + Number(request?.token?.amount)\n            ).toString(),\n          })\n          updateNFTTransferData({\n            ...isShowNFTDetail,\n            locked: (\n              Number(isShowNFTDetail?.locked ?? 0) + Number(request?.token?.amount)\n            ).toString(),\n          })\n          walletLayer2Service.sendUserUpdate()\n          // resetNFTTransferData();\n          await sdk.sleep(SUBMIT_PANEL_AUTO_CLOSE)\n          if (\n            store.getState().modals.isShowAccount.isShow &&\n            store.getState().modals.isShowAccount.step == AccountStep.NFTBurn_Success\n          ) {\n            setShowAccount({ isShow: false })\n            searchParams.delete('detail')\n            history.push(pathname + '?' + searchParams.toString())\n          }\n        }\n      } catch (e: any) {\n        const code = sdk.checkErrorInfo(e, isNotHardwareWallet)\n        switch (code) {\n          case sdk.ConnectorError.NOT_SUPPORT_ERROR:\n            setLastRequest({ request })\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.NFTBurn_First_Method_Denied,\n              info: {\n                symbol: nftTransferValue.name,\n              },\n            })\n            break\n          case sdk.ConnectorError.USER_DENIED:\n          case sdk.ConnectorError.USER_DENIED_2:\n            setLastRequest({ request })\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.NFTBurn_User_Denied,\n            })\n            break\n          default:\n            if ([102024, 102025, 114001, 114002].includes((e as sdk.RESULT_INFO)?.code || 0)) {\n              checkFeeIsEnough({\n                isRequiredAPI: true,\n                requestType: sdk.OffchainNFTFeeReqType.NFT_TRANSFER,\n              })\n            }\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.NFTBurn_Failed,\n              info: {\n                symbol: nftTransferValue.name,\n              },\n              error: {\n                code: UIERROR_CODE.UNKNOWN,\n                msg: e?.message,\n                ...(e instanceof Error\n                  ? {\n                      message: e?.message,\n                      stack: e?.stack,\n                    }\n                  : e ?? {}),\n              },\n            })\n            break\n        }\n      }\n    },\n    [\n      account,\n      checkHWAddr,\n      chainId,\n      setShowNFTTransfer,\n      setShowAccount,\n      nftTransferValue.name,\n      setShowNFTDetail,\n      isShowNFTDetail,\n      updateNFTWithdrawData,\n      updateNFTTransferData,\n      updateHW,\n      searchParams,\n      history,\n      pathname,\n      checkFeeIsEnough,\n    ],\n  )\n\n  const onTransferClick = React.useCallback(\n    async (_nftTransferValue, isFirstTime: boolean = true) => {\n      const { accountId, accAddress, readyState, apiKey, eddsaKey } = account\n      const nftTransferValue = {\n        ...store.getState()._router_modalData.nftTransferValue,\n        // tradeValue: _nftTransferValue.tradeValue,\n        // balance: _nftTransferValue.balance,\n      }\n      if (\n        readyState === AccountStatus.ACTIVATED &&\n        tokenMap &&\n        LoopringAPI.userAPI &&\n        exchangeInfo &&\n        connectProvides.usedWeb3 &&\n        nftTransferValue?.nftData &&\n        nftTransferValue?.fee?.belong &&\n        nftTransferValue?.fee?.feeRaw &&\n        nftTransferValue.tradeValue &&\n        nftTransferValue.tokenId &&\n        eddsaKey?.sk\n      ) {\n        try {\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.NFTBurn_WaitForAuth,\n          })\n          const feeToken = tokenMap[nftTransferValue.fee.belong]\n          const feeRaw = nftTransferValue.fee.feeRaw ?? nftTransferValue.fee.__raw__?.feeRaw ?? 0\n          const fee = sdk.toBig(feeRaw)\n          const tradeValue = nftTransferValue.tradeValue ?? _nftTransferValue.tradeValue\n          const balance = nftTransferValue.balance ?? _nftTransferValue.balance\n          const isExceedBalance = sdk.toBig(tradeValue).gt(balance)\n\n          if (isExceedBalance) {\n            throw Error('overflow balance')\n          }\n\n          const storageId = await LoopringAPI.userAPI?.getNextStorageId(\n            {\n              accountId,\n              sellTokenId: nftTransferValue.tokenId,\n            },\n            apiKey,\n          )\n          const  {result:realAddr} = await LoopringAPI.nftAPI?.getUserNFTBurnAddress({accountId,tokenId:nftTransferValue.tokenId});\n          if(!realAddr){\n            throw {code:UIERROR_CODE.ERROR_ADDRESS_BURN_NFT}\n          }\n          const req: sdk.OriginNFTTransferRequestV3 = {\n            exchange: exchangeInfo.exchangeAddress,\n            fromAccountId: accountId,\n            fromAddress: accAddress,\n            toAccountId: 0,\n            toAddress: realAddr,\n            storageId: storageId?.offchainId,\n            token: {\n              tokenId: nftTransferValue.tokenId,\n              nftData: nftTransferValue.nftData,\n              amount: tradeValue.toString(),\n            },\n            payPayeeUpdateAccount: false,\n            maxFee: {\n              tokenId: feeToken.tokenId,\n              amount: fee.toString(), // TEST: fee.toString(),\n            },\n            validUntil: getTimestampDaysLater(DAYS),\n            memo: 'Burn',\n          }\n          myLog('nftBurn req:', req)\n          processRequest(req, isFirstTime)\n        } catch (e: any) {\n          const errorItem = SDK_ERROR_MAP_TO_UI[(e)?.code ?? UIERROR_CODE.UNKNOWN]??  SDK_ERROR_MAP_TO_UI[UIERROR_CODE.UNKNOWN]\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.NFTBurn_Failed,\n            info: {\n              symbol: nftTransferValue?.name,\n            },\n            error: {\n              code:(e)?.code ?? UIERROR_CODE.UNKNOWN,\n              message: t(errorItem.messageKey,{ ns: 'error' },),\n            },\n          })\n        }\n      } else {\n        return\n      }\n    },\n    [\n      account,\n      tokenMap,\n      exchangeInfo,\n      setShowAccount,\n      processRequest,\n    ],\n  )\n  // const activeFee = React.useMemo(() => {\n  //   // return activeAccountFeeList?.find(\n  //   //   (item: any) => item.belong == feeInfo.belong\n  //   // );\n  // }, [feeInfo, activeAccountFeeList]);\n  const handlePanelEvent = React.useCallback(\n    async (data: SwitchData<R>, _switchType: 'Tomenu' | 'Tobutton') => {\n      return new Promise<void>((res: any) => {\n        if (data.to === 'button') {\n          if (data.tradeData.belong) {\n            updateNFTTransferData({\n              belong: data.tradeData.belong,\n              tradeValue: data.tradeData?.tradeValue,\n              balance: data.tradeData.balance,\n              address: '*',\n            })\n          } else {\n            updateNFTTransferData({\n              belong: undefined,\n              tradeValue: undefined,\n              balance: undefined,\n              address: '*',\n            })\n          }\n        }\n\n        res()\n      })\n    },\n    [updateNFTTransferData],\n  )\n\n\n  const retryBtn = React.useCallback(\n    (isHardwareRetry: boolean = false) => {\n      setShowAccount({\n        isShow: true,\n        step: AccountStep.NFTBurn_WaitForAuth,\n      })\n      processRequest(lastRequest, !isHardwareRetry)\n    },\n    [lastRequest, processRequest, setShowAccount],\n  )\n\n  const nftBurnProps: TransferProps<R, T> = {\n    handleOnMemoChange:()=>{},\n    memo: nftTransferValue.memo ?? '',\n    type: TRADE_TYPE.NFT,\n    lastFailed: store.getState().modals.isShowAccount.info?.lastFailed === LAST_STEP.nftTransfer,\n    tradeData: { ...nftTransferValue } as unknown as R,\n    coinMap: totalCoinMap as CoinMap<T>,\n    walletMap: {},\n    transferBtnStatus: btnStatus,\n    transferI18nKey: t('labelL2NFTBurnBtn'),\n    onTransferClick,\n    handleFeeChange,\n    feeInfo,\n    chargeFeeTokenList,\n    isFeeNotEnough,\n    handlePanelEvent,\n    baseURL,\n    getIPFSString,\n    isFromContact: contactAddress ? true : false,\n    contact: contactAddress\n      ? {\n          address: contactAddress,\n          name: contactName!,\n          addressType: contactAddressType!,\n        }\n      : undefined,\n    contacts,\n  }  as unknown as TransferProps<R, T>\n\n  return {\n    nftBurnProps,\n    retryBtn,\n    // cancelNFTTransfer,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/useNFTDeploy.ts",
    "content": "import {\n  useAccount,\n  useTokenMap,\n  useModalData,\n  useWalletLayer2Socket,\n  walletLayer2Service,\n  DAYS,\n  getTimestampDaysLater,\n  LoopringAPI,\n  store,\n  useSystem,\n  isAccActivated,\n  useChargeFees,\n  useWalletLayer2NFT,\n  useWalletL2Collection,\n  NETWORKEXTEND,\n} from '../../index'\nimport { AccountStep, NFTDeployProps, useOpenModals } from '@loopring-web/component-lib'\nimport React from 'react'\n\nimport {\n  AccountStatus,\n  Layer1Action,\n  myLog,\n  TradeNFT,\n  UIERROR_CODE,\n  LIVE_FEE_TIMES,\n  SUBMIT_PANEL_QUICK_AUTO_CLOSE,\n} from '@loopring-web/common-resources'\nimport { useBtnStatus } from '../common/useBtnStatus'\n\nimport { ConnectProviders, connectProvides } from '@loopring-web/web3-provider'\n\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { useLayer1Store } from '../../stores/localStore/layer1Store'\nimport { useWalletInfo } from '../../stores/localStore/walletInfo'\nimport {\n  useHistory,\n  useLocation,\n  // useLocation\n} from 'react-router-dom'\nimport Web3 from 'web3'\n\nexport function useNFTDeploy<T extends TradeNFT<I, any> & { broker: string }, I>() {\n  const { btnStatus, enableBtn, disableBtn } = useBtnStatus()\n  const { tokenMap } = useTokenMap()\n  const { account } = useAccount()\n  const { exchangeInfo, chainId } = useSystem()\n  const { nftDeployValue, updateNFTDeployData, resetNFTDeployData } = useModalData()\n  const { page, updateWalletLayer2NFT } = useWalletLayer2NFT()\n  const { page: collectionPage, updateWalletL2Collection } = useWalletL2Collection()\n\n  const {\n    setShowAccount,\n    setShowNFTDetail,\n    setShowNFTDeploy,\n    modals: { isShowNFTDeploy, isShowNFTDetail },\n  } = useOpenModals()\n\n  const { setOneItem } = useLayer1Store()\n  const { checkHWAddr, updateHW } = useWalletInfo()\n  const history = useHistory()\n  const { search, pathname } = useLocation()\n  const searchParams = new URLSearchParams(search)\n\n  const {\n    chargeFeeTokenList,\n    isFeeNotEnough,\n    handleFeeChange,\n    feeInfo,\n    checkFeeIsEnough,\n    resetIntervalTime,\n  } = useChargeFees({\n    tokenAddress: nftDeployValue.tokenAddress,\n    requestType: sdk.OffchainNFTFeeReqType.NFT_DEPLOY,\n    updateData: ({ fee }) => {\n      updateNFTDeployData({ ...nftDeployValue, fee })\n    },\n  })\n  const processRequestNFT = React.useCallback(\n    async (\n      request: sdk.OriginDeployNFTRequestV3 | sdk.OriginDeployCollectionRequestV3,\n      isFirstTime: boolean,\n    ) => {\n      const { apiKey, connectName, eddsaKey } = account\n\n      try {\n        if (connectProvides.usedWeb3 && isAccActivated()) {\n          let isHWAddr = checkHWAddr(account.accAddress)\n          isHWAddr = !isFirstTime ? !isHWAddr : isHWAddr\n          let response\n          if (request.hasOwnProperty('nftData')) {\n            response = await LoopringAPI.userAPI?.submitDeployNFT(\n              {\n                request: request as sdk.OriginDeployNFTRequestV3,\n                web3: connectProvides.usedWeb3 as unknown as Web3,\n                chainId: chainId === NETWORKEXTEND.NONETWORK ? sdk.ChainId.MAINNET : chainId,\n                walletType: (ConnectProviders[connectName] ??\n                  connectName) as unknown as sdk.ConnectorNames,\n                eddsaKey: eddsaKey.sk,\n                apiKey,\n                isHWAddr,\n              },\n              {\n                accountId: account.accountId,\n                counterFactualInfo: eddsaKey.counterFactualInfo,\n              },\n            )\n          } else {\n            response = await LoopringAPI.userAPI?.submitDeployCollection(\n              {\n                request: request as sdk.OriginDeployCollectionRequestV3,\n                web3: connectProvides.usedWeb3 as unknown as Web3,\n                chainId: chainId === NETWORKEXTEND.NONETWORK ? sdk.ChainId.MAINNET : chainId,\n                walletType: (ConnectProviders[connectName] ??\n                  connectName) as unknown as sdk.ConnectorNames,\n                eddsaKey: eddsaKey.sk,\n                apiKey,\n                isHWAddr,\n              },\n              {\n                accountId: account.accountId,\n                counterFactualInfo: eddsaKey.counterFactualInfo,\n              },\n            )\n          }\n\n          if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n            throw response\n          }\n          setOneItem({\n            chainId: chainId as sdk.ChainId,\n            uniqueId: request.tokenAddress.toLowerCase(),\n            domain: Layer1Action.NFTDeploy,\n          })\n          // setShowAccount({\n          //   isShow: true,\n          //   step: AccountStep.NFTDeploy_In_Progress,\n          // });\n\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.NFTDeploy_Submit,\n            info: {\n              symbol: nftDeployValue?.tokenAddress,\n            },\n          })\n          if (isHWAddr) {\n            myLog('......try to set isHWAddr', isHWAddr)\n            updateHW({ wallet: account.accAddress, isHWAddr })\n          }\n          walletLayer2Service.sendUserUpdate()\n          setShowNFTDeploy({ isShow: false })\n          resetNFTDeployData()\n          // searchParams.delete(\"detail\");\n\n          if (nftDeployValue.nftData) {\n            updateWalletLayer2NFT({\n              page: Number(searchParams.get('collectionPage')) ?? 1,\n              collectionId: nftDeployValue?.collectionMeta?.id,\n              collectionContractAddress: nftDeployValue?.collectionMeta?.contractAddress,\n            })\n            setShowNFTDetail({\n              ...isShowNFTDetail,\n              deploymentStatus: sdk.DEPLOYMENT_STATUS.DEPLOYING,\n            })\n          } else {\n            updateWalletL2Collection({\n              page: collectionPage,\n            })\n            history.push(pathname + '?' + searchParams.toString())\n          }\n          await sdk.sleep(SUBMIT_PANEL_QUICK_AUTO_CLOSE)\n          if (store.getState().modals.isShowAccount.isShow) {\n            setShowAccount({ isShow: false })\n          }\n        }\n      } catch (e: any) {\n        const code = sdk.checkErrorInfo(e, isFirstTime)\n        switch (code) {\n          case sdk.ConnectorError.NOT_SUPPORT_ERROR:\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.NFTDeploy_First_Method_Denied,\n              info: {\n                symbol: nftDeployValue?.tokenAddress,\n              },\n            })\n            break\n          case sdk.ConnectorError.USER_DENIED:\n          case sdk.ConnectorError.USER_DENIED_2:\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.NFTDeploy_Denied,\n              info: {\n                symbol: nftDeployValue?.tokenAddress,\n              },\n            })\n            break\n          default:\n            if ([102024, 102025, 114001, 114002].includes((e as sdk.RESULT_INFO)?.code || 0)) {\n              checkFeeIsEnough({ isRequiredAPI: true })\n            }\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.NFTDeploy_Failed,\n              info: {\n                symbol: nftDeployValue?.tokenAddress,\n              },\n              error: {\n                code: UIERROR_CODE.UNKNOWN,\n                msg: e?.message,\n                ...(e instanceof Error\n                  ? {\n                      message: e?.message,\n                      stack: e?.stack,\n                    }\n                  : e ?? {}),\n              },\n            })\n\n            break\n        }\n      }\n    },\n    [\n      account,\n      checkHWAddr,\n      chainId,\n      setShowAccount,\n      nftDeployValue?.tokenAddress,\n      checkFeeIsEnough,\n      setOneItem,\n      updateWalletLayer2NFT,\n      page,\n      resetNFTDeployData,\n      updateHW,\n    ],\n  )\n  React.useEffect(() => {\n    if (isShowNFTDeploy.isShow) {\n      checkFeeIsEnough({ isRequiredAPI: true, intervalTime: LIVE_FEE_TIMES })\n    } else {\n      resetIntervalTime()\n    }\n    return () => {\n      resetIntervalTime()\n    }\n  }, [isShowNFTDeploy])\n\n  const checkBtnStatus = React.useCallback(() => {\n    if (tokenMap && !isFeeNotEnough.isFeeNotEnough) {\n      enableBtn()\n      return\n    }\n    disableBtn()\n  }, [disableBtn, enableBtn, isFeeNotEnough.isFeeNotEnough, tokenMap])\n\n  React.useEffect(() => {\n    checkBtnStatus()\n  }, [checkBtnStatus, nftDeployValue, isFeeNotEnough.isFeeNotEnough])\n\n  const onNFTDeployClick = async (_nftDeployValue: T, isFirsTime: boolean = true) => {\n    const { accountId, accAddress, readyState, apiKey, eddsaKey } = account\n    const nftDeployValue = store.getState()._router_modalData.nftDeployValue\n\n    if (\n      readyState === AccountStatus.ACTIVATED &&\n      tokenMap &&\n      LoopringAPI.userAPI &&\n      exchangeInfo &&\n      !isFeeNotEnough.isFeeNotEnough &&\n      nftDeployValue &&\n      nftDeployValue.broker &&\n      nftDeployValue.tokenAddress &&\n      connectProvides.usedWeb3 &&\n      (nftDeployValue?.nftData ||\n        nftDeployValue?.collectionMeta?.owner?.toLowerCase() ===\n          account.accAddress?.toLowerCase()) &&\n      nftDeployValue.fee &&\n      nftDeployValue?.fee.belong &&\n      nftDeployValue?.fee.fee &&\n      eddsaKey?.sk\n    ) {\n      try {\n        setShowAccount({\n          isShow: true,\n          step: AccountStep.NFTDeploy_WaitForAuth,\n        })\n        const feeToken = tokenMap[nftDeployValue.fee.belong]\n        const feeRaw = nftDeployValue.fee.feeRaw ?? nftDeployValue.fee.__raw__?.feeRaw ?? 0\n        const _fee = sdk.toBig(feeRaw)\n        // const _fee = sdk.toBig(nftDeployValue.fee.__raw__?.feeRaw ?? 0);\n        myLog('fee.__raw__', _fee)\n        const storageId = await LoopringAPI.userAPI?.getNextStorageId(\n          {\n            accountId,\n            sellTokenId: Number(feeToken.tokenId),\n          },\n          apiKey,\n        )\n        let req: sdk.OriginDeployNFTRequestV3 | sdk.OriginDeployCollectionRequestV3\n        if (\n          nftDeployValue.collectionMeta &&\n          nftDeployValue.collectionMeta.owner?.toLowerCase() === account.accAddress?.toLowerCase()\n        ) {\n          req = {\n            nftOwner: account.accAddress?.toLowerCase(),\n            nftBaseUri: nftDeployValue.collectionMeta.baseUri ?? '',\n            tokenAddress: nftDeployValue.tokenAddress,\n            nftFactory: nftDeployValue.collectionMeta?.nftFactory ?? '',\n            transfer: {\n              exchange: exchangeInfo.exchangeAddress,\n              payerAddr: accAddress,\n              payerId: accountId,\n              payeeAddr: nftDeployValue.broker,\n              storageId: storageId.offchainId,\n              token: {\n                tokenId: feeToken.tokenId,\n                volume: _fee.toFixed(), // TEST: fee.toString(),\n              },\n              validUntil: getTimestampDaysLater(DAYS),\n            },\n          }\n        } else {\n          req = {\n            nftData: nftDeployValue.nftData ?? '',\n            tokenAddress: nftDeployValue.tokenAddress,\n            transfer: {\n              exchange: exchangeInfo.exchangeAddress,\n              payerAddr: accAddress,\n              payerId: accountId,\n              payeeAddr: nftDeployValue.broker,\n              storageId: storageId.offchainId,\n              token: {\n                tokenId: feeToken.tokenId,\n                volume: _fee.toFixed(), // TEST: fee.toString(),\n              },\n              validUntil: getTimestampDaysLater(DAYS),\n            },\n          }\n        }\n\n        myLog('nftDeploy req:', req)\n\n        processRequestNFT(req, isFirsTime)\n      } catch (e: unknown) {\n        // nftTransfer failed\n        setShowAccount({\n          isShow: true,\n          step: AccountStep.NFTDeploy_Failed,\n          error: { code: UIERROR_CODE.UNKNOWN, msg: (e as any).message },\n        })\n      }\n    } else {\n      return false\n    }\n  }\n\n  useWalletLayer2Socket({})\n\n  const nftDeployProps = {\n    coinMap: {},\n    handleOnNFTDataChange<T>(_data: T): void {},\n    tradeData: nftDeployValue as T,\n    walletMap: {},\n    onNFTDeployClick: (trade: T) => {\n      onNFTDeployClick(trade)\n    },\n    nftDeployBtnStatus: btnStatus,\n    chargeFeeTokenList,\n    isFeeNotEnough,\n    handleFeeChange,\n    feeInfo,\n  } as NFTDeployProps<any, any>\n\n  return {\n    nftDeployProps,\n    updateNFTDeployData,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/useNFTDeposit.ts",
    "content": "import React from 'react'\n\nimport { AccountStep, NFTDepositProps, useOpenModals } from '@loopring-web/component-lib'\nimport {\n  AccountStatus,\n  CoinMap,\n  DEAULT_NFTID_STRING,\n  ErrorMap,\n  ErrorType,\n  globalSetup,\n  IPFS_LOOPRING_SITE,\n  myLog,\n  NFTSubRouter,\n  RouterPath,\n  SUBMIT_PANEL_AUTO_CLOSE,\n  TRADE_TYPE,\n  TradeNFT,\n  UIERROR_CODE,\n  WalletMap,\n} from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport {\n  useModalData,\n  useSystem,\n  useTokenMap,\n  useAccount,\n  useWalletLayer1,\n  ActionResultCode,\n  LoopringAPI,\n  store,\n  useBtnStatus,\n  getIPFSString,\n  depositServices,\n  DepositCommands,\n  BIGO,\n  waitForTx,\n} from '../../index'\n\nimport { connectProvides } from '@loopring-web/web3-provider'\n\nimport _ from 'lodash'\nimport { useOnChainInfo } from '../../stores/localStore/onchainHashInfo'\nimport { useHistory } from 'react-router-dom'\nimport Web3 from 'web3'\n\nexport const useNFTDeposit = <T extends TradeNFT<I, any>, I>(): {\n  nftDepositProps: NFTDepositProps<T, I>\n} => {\n  const subject = React.useMemo(() => depositServices.onSocket(), [])\n\n  const { tokenMap, totalCoinMap } = useTokenMap()\n  const { account } = useAccount()\n  const { exchangeInfo, chainId, gasPrice, baseURL } = useSystem()\n  const [isNFTCheckLoading, setIsNFTCheckLoading] = React.useState(false)\n  const { nftDepositValue, updateNFTDepositData, resetNFTDepositData } = useModalData()\n  const { walletLayer1, updateWalletLayer1 } = useWalletLayer1()\n  const { updateDepositHash } = useOnChainInfo()\n  const history = useHistory()\n\n  const {\n    btnStatus,\n    btnInfo,\n    enableBtn,\n    disableBtn,\n    setLoadingBtn,\n    setLabelAndParams,\n    resetBtnInfo,\n  } = useBtnStatus()\n\n  const { setShowAccount, setShowNFTDeposit } = useOpenModals()\n\n  const debounceCheck = _.debounce(\n    async (data) => {\n      const web3 = connectProvides.usedWeb3 as unknown as Web3\n      if (LoopringAPI.nftAPI && exchangeInfo && web3) {\n        setIsNFTCheckLoading(true)\n        let [balance, meta, isApproved] = await Promise.all([\n          LoopringAPI.nftAPI.getNFTBalance({\n            account: account.accAddress,\n            nftId: data.nftId,\n            nftType: data.nftType as unknown as sdk.NFTType,\n            web3,\n            tokenAddress: data.tokenAddress,\n          }),\n          LoopringAPI.nftAPI.getContractNFTMeta(\n            {\n              _id: data.nftId,\n              nftId: data.nftId,\n              nftType: data.nftType as unknown as sdk.NFTType,\n              web3,\n              tokenAddress: data.tokenAddress,\n            },\n            IPFS_LOOPRING_SITE as any,\n          ),\n          LoopringAPI.nftAPI.isApprovedForAll({\n            web3,\n            from: account.accAddress,\n            exchangeAddress: exchangeInfo.exchangeAddress,\n            tokenAddress: data.tokenAddress,\n            nftType: data.nftType as unknown as sdk.NFTType,\n          }),\n        ]).finally(() => {\n          setIsNFTCheckLoading(() => false)\n        })\n        myLog('setIsNFTCheckLoading done', balance, meta, isApproved)\n\n        const shouldUpdate = {\n          ...data,\n          nftId: data.nftId,\n          name: meta.name ?? 'unknown NFT',\n          image: meta?.image ?? '',\n          description: meta.description ?? '',\n          balance: Number(balance.count ?? 0),\n          isApproved,\n        }\n        myLog('debounceCheck', shouldUpdate)\n        updateNFTDepositData(shouldUpdate)\n      }\n    },\n    globalSetup.wait,\n    { trailing: true },\n  )\n  {\n  }\n  const handleOnNFTDataChange = async (data: T) => {\n    const web3 = connectProvides.usedWeb3\n    const nftDepositValue = store.getState()._router_modalData.nftDepositValue\n    let shouldUpdate: any = {\n      nftType: nftDepositValue.nftType ?? 0,\n    }\n    if (data.hasOwnProperty('tokenAddress')) {\n      shouldUpdate = {\n        ...shouldUpdate,\n        tokenAddress: data.tokenAddress,\n      }\n    }\n    if (data.hasOwnProperty('nftIdView') && web3) {\n      let _nftId = nftDepositValue.nftId\n      if (\n        (data.nftId !== '' && (!data.nftIdView || !data.nftIdView?.trim())) ||\n        (data.nftIdView && data.nftIdView.toLowerCase().startsWith('0x'))\n      ) {\n        _nftId = data.nftIdView ?? ''\n      } else if (data.nftIdView !== undefined) {\n        try {\n          if (data.nftIdView === '') {\n            _nftId = ''\n            shouldUpdate.balance = ''\n            shouldUpdate.tradeValue = undefined\n          } else {\n            _nftId = web3.utils.toHex(sdk.toBN(data.nftIdView) as any).replace('0x', '')\n            const prev = DEAULT_NFTID_STRING.substring(\n              0,\n              DEAULT_NFTID_STRING.length - _nftId.toString().length,\n            )\n            _nftId = prev + _nftId.toString()\n          }\n        } catch (error: any) {\n          const errorView: ErrorType = ErrorMap.NTF_ID_ENCODE_ERROR\n          updateBtnStatus({ errorView, ...(error as any) })\n          return\n        }\n      }\n      shouldUpdate = {\n        ...shouldUpdate,\n        nftIdView: data.nftIdView,\n        nftId: _nftId,\n      }\n    }\n    if (data.hasOwnProperty('nftType')) {\n      shouldUpdate = {\n        ...shouldUpdate,\n        nftType: data.nftType,\n      }\n    }\n    if (data.hasOwnProperty('tradeValue')) {\n      shouldUpdate = {\n        ...shouldUpdate,\n        tradeValue: data.tradeValue,\n      }\n    }\n    if (\n      (shouldUpdate.tokenAddress && shouldUpdate.tokenAddress !== nftDepositValue.tokenAddress) ||\n      (shouldUpdate.nftIdView && shouldUpdate.nftIdView != nftDepositValue.nftIdView) ||\n      (shouldUpdate.nftType !== undefined && shouldUpdate.nftType != nftDepositValue.nftType)\n    ) {\n      myLog('debounceCheck', debounceCheck)\n      const obj = { ...nftDepositValue, ...shouldUpdate }\n      if (\n        obj.tokenAddress &&\n        obj.nftId !== undefined &&\n        obj.nftId !== '' &&\n        obj.nftType !== undefined\n      ) {\n        debounceCheck(obj)\n      }\n    } else if (\n      nftDepositValue.balance !== 0 &&\n      (!nftDepositValue.tokenAddress ||\n        !nftDepositValue.nftIdView ||\n        nftDepositValue.nftType === undefined)\n    ) {\n      shouldUpdate = {\n        ...shouldUpdate,\n        description: '',\n        image: '',\n        name: '',\n        balance: 0,\n        isApproved: undefined,\n      }\n    }\n\n    myLog('nftDepositValue', nftDepositValue, shouldUpdate)\n\n    updateNFTDepositData({\n      ...nftDepositValue,\n      ...shouldUpdate,\n    })\n  }\n\n  const onNFTDepositClick = React.useCallback(async () => {\n    let result = { code: ActionResultCode.NoError }\n    const nftDepositValue = store.getState()._router_modalData.nftDepositValue\n    setLoadingBtn()\n\n    try {\n      if (\n        account.readyState !== AccountStatus.UN_CONNECT &&\n        nftDepositValue.tradeValue &&\n        nftDepositValue.tokenAddress &&\n        nftDepositValue.nftId &&\n        tokenMap &&\n        exchangeInfo?.exchangeAddress &&\n        connectProvides.usedWeb3 &&\n        LoopringAPI.nftAPI\n      ) {\n        const web3 = connectProvides.usedWeb3 as unknown as Web3\n        const gasLimit = undefined //parseInt(NFTGasAmounts.deposit) ?? undefined;\n        const realGasPrice = gasPrice ?? 30\n        enableBtn()\n        setShowAccount({\n          isShow: true,\n          step: AccountStep.NFTDeposit_WaitForAuth,\n        })\n        let nonce =\n          (await sdk.getNonce(connectProvides.usedWeb3 as unknown as Web3, account.accAddress)) ?? 0\n        if (!nftDepositValue.isApproved) {\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.NFTDeposit_Approve_WaitForAuth,\n          })\n          try {\n            const tx = await LoopringAPI.nftAPI.approveNFT({\n              web3,\n              from: account.accAddress,\n              depositAddress: exchangeInfo?.exchangeAddress,\n              tokenAddress: nftDepositValue.tokenAddress,\n              nftId: nftDepositValue.nftId,\n              gasPrice: realGasPrice,\n              gasLimit,\n              chainId: chainId as sdk.ChainId,\n              nonce,\n              nftType: nftDepositValue.nftType as unknown as sdk.NFTType,\n              sendByMetaMask: true,\n            })\n            \n            await waitForTx(web3, tx.result);\n          } catch (error: any) {\n            if (error instanceof Error) {\n              throw {\n                // Pull all enumerable properties, supporting properties on custom Errors\n                ...error,\n                // Explicitly pull Error's non-enumerable properties\n                message: error.message,\n                stack: error.stack,\n                type: 'ApproveToken',\n              }\n            } else {\n              throw {\n                ...(error as any),\n                type: 'ApproveToken',\n              }\n            }\n          }\n          nonce += 1\n        } else {\n          myLog('NFT is Approved ALL at History')\n        }\n        setShowAccount({\n          isShow: true,\n          step: AccountStep.NFTDeposit_WaitForAuth,\n        })\n\n        try {\n          const response = await LoopringAPI.nftAPI.depositNFT({\n            web3,\n            from: account.accAddress,\n            exchangeAddress: exchangeInfo?.exchangeAddress,\n            tokenAddress: nftDepositValue.tokenAddress,\n            nftId: nftDepositValue.nftId,\n            amount: nftDepositValue.tradeValue,\n            gasPrice: realGasPrice,\n            gasLimit,\n            chainId: chainId as sdk.ChainId,\n            nonce,\n            nftType: nftDepositValue.nftType as unknown as sdk.NFTType,\n            sendByMetaMask: true,\n          })\n          handleOnNFTDataChange({ nftIdView: '', tokenAddress: '' } as T)\n          updateWalletLayer1()\n          resetNFTDepositData()\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.NFTDeposit_Submit,\n            info: {\n              symbol: nftDepositValue?.name,\n              value: nftDepositValue.tradeValue,\n              hash: response.result,\n            },\n          })\n          updateDepositHash(response.result, account.accAddress, undefined, {\n            symbol: nftDepositValue.name,\n            type: 'Deposit NFT',\n            value: nftDepositValue.tradeValue,\n          })\n          myLog('response:', response)\n\n          await sdk.sleep(SUBMIT_PANEL_AUTO_CLOSE)\n          if (\n            store.getState().modals.isShowAccount.isShow &&\n            store.getState().modals.isShowAccount.step == AccountStep.NFTDeposit_Submit\n          ) {\n            setShowAccount({ isShow: false })\n            history.push(`${RouterPath.nft}/${NFTSubRouter.assetsNFT}`)\n          }\n        } catch (error) {\n          if (error instanceof Error) {\n            throw {\n              // Pull all enumerable properties, supporting properties on custom Errors\n              ...error,\n              // Explicitly pull Error's non-enumerable properties\n              message: error.message,\n              stack: error.stack,\n              type: 'Deposit',\n            }\n          } else {\n            throw {\n              ...(error as any),\n              type: 'Deposit',\n            }\n          }\n        }\n      } else {\n        throw { code: UIERROR_CODE.DATA_NOT_READY }\n      }\n    } catch (e) {\n      //deposit failed\n      enableBtn()\n      const { type, ..._error } = (e as any).message ? (e as any) : { type: '' }\n      const error = LoopringAPI?.exchangeAPI?.genErr(_error as any) ?? {\n        code: UIERROR_CODE.DATA_NOT_READY,\n      }\n      const code = sdk.checkErrorInfo(error, true)\n      setShowAccount({\n        isShow: true,\n        step: AccountStep.NFTDeposit_Approve_Denied,\n      })\n      myLog('---- deposit NFT ERROR reason:', _error?.message, code)\n\n      switch (code) {\n        case sdk.ConnectorError.USER_DENIED:\n        case sdk.ConnectorError.USER_DENIED_2:\n          if (type === 'ApproveToken') {\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.NFTDeposit_Approve_Denied,\n            })\n          } else {\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.NFTDeposit_Denied,\n              info: {\n                symbol: nftDepositValue?.name,\n              },\n            })\n          }\n          break\n        default:\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.NFTDeposit_Failed,\n            info: {\n              symbol: nftDepositValue?.name,\n            },\n            error: {\n              ..._error,\n              ...error,\n              code: (e as any)?.code ?? UIERROR_CODE.UNKNOWN,\n            },\n          })\n          break\n      }\n      updateWalletLayer1()\n    }\n\n    return result\n  }, [\n    account.accAddress,\n    account.readyState,\n    chainId,\n    exchangeInfo?.exchangeAddress,\n    gasPrice,\n    nftDepositValue.isApproved,\n    nftDepositValue.name,\n    nftDepositValue.nftId,\n    nftDepositValue.nftType,\n    nftDepositValue.tokenAddress,\n    nftDepositValue.tradeValue,\n    resetNFTDepositData,\n    setShowAccount,\n    setShowNFTDeposit,\n    tokenMap,\n    updateDepositHash,\n  ])\n\n  const nftDepositProps: NFTDepositProps<T, I> = {\n    type: TRADE_TYPE.NFT,\n    handleOnNFTDataChange,\n    getIPFSString,\n    onNFTDepositClick,\n    walletMap: walletLayer1 as WalletMap<any>,\n    coinMap: totalCoinMap as CoinMap<any>,\n    tradeData: nftDepositValue as T,\n    nftDepositBtnStatus: btnStatus,\n    isNFTCheckLoading,\n    baseURL,\n    btnInfo,\n  }\n\n  const updateBtnStatus = React.useCallback(\n    (error?: ErrorType & any) => {\n      resetBtnInfo()\n      myLog('updateBtnStatus', nftDepositValue)\n      if (\n        !error &&\n        walletLayer1 &&\n        nftDepositValue &&\n        nftDepositValue.balance &&\n        nftDepositValue.tradeValue &&\n        sdk.toBig(walletLayer1?.ETH?.count ?? 0).gt(BIGO) &&\n        sdk.toBig(nftDepositValue.tradeValue).gt(sdk.toBig(0)) &&\n        sdk.toBig(nftDepositValue.tradeValue).lte(sdk.toBig(nftDepositValue?.balance ?? ''))\n      ) {\n        myLog('try to enable nftDeposit btn!', walletLayer1?.ETH?.count)\n        enableBtn()\n        if (!nftDepositValue.isApproved) {\n          myLog('!!---> set labelNFTDepositNeedApprove!!!! belong:', nftDepositValue.tokenAddress)\n          setLabelAndParams('labelNFTDepositNeedApprove', {\n            symbol: nftDepositValue.name ?? 'unknown NFT',\n          })\n        }\n      } else {\n        if (sdk.toBig(walletLayer1?.ETH?.count ?? 0).eq(BIGO)) {\n          setLabelAndParams('labelNOETH', {})\n        }\n        myLog('try to disable nftDeposit btn!')\n        disableBtn()\n      }\n    },\n    [resetBtnInfo, nftDepositValue, walletLayer1, enableBtn, setLabelAndParams, disableBtn],\n  )\n  React.useEffect(() => {\n    updateBtnStatus()\n  }, [\n    nftDepositValue?.tokenAddress,\n    nftDepositValue?.nftId,\n    nftDepositValue?.nftType,\n    nftDepositValue?.tradeValue,\n    nftDepositValue?.balance,\n    walletLayer1?.ETH?.count,\n  ])\n  React.useEffect(() => {\n    updateWalletLayer1()\n    const subscription = subject.subscribe((props) => {\n      myLog('subscription Deposit DepsitNFT')\n      switch (props.status) {\n        case DepositCommands.DepsitNFT:\n          onNFTDepositClick()\n          break\n        default:\n          break\n      }\n    })\n    return () => {\n      subscription.unsubscribe()\n    }\n  }, [subject])\n  return {\n    nftDepositProps,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/useNFTMintAdvance.ts",
    "content": "import React from 'react'\n\nimport { AccountStep, NFTMintAdvanceProps, useOpenModals } from '@loopring-web/component-lib'\nimport {\n  AccountStatus,\n  CollectionMeta,\n  CustomError,\n  EmptyValueTag,\n  ErrorMap,\n  ErrorType,\n  Explorer,\n  IPFS_HEAD_URL,\n  LIVE_FEE_TIMES,\n  MINT_LIMIT,\n  myLog,\n  NFTSubRouter,\n  RouterPath,\n  SUBMIT_PANEL_QUICK_AUTO_CLOSE,\n  TradeNFT,\n  UIERROR_CODE,\n} from '@loopring-web/common-resources'\n\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { ConnectProviders, connectProvides } from '@loopring-web/web3-provider'\nimport {\n  LAST_STEP,\n  NETWORKEXTEND,\n  store,\n  useAccount,\n  useModalData,\n  useSystem,\n  useTokenMap,\n  useWalletLayer2NFT,\n} from '../../stores'\nimport { useBtnStatus, useMyCollection } from '../common'\nimport { LoopringAPI } from '../../api_wrapper'\nimport { useChargeFees, useWalletLayer2Socket, walletLayer2Service } from '../../services'\nimport { useWalletInfo } from '../../stores/localStore/walletInfo'\nimport { useTranslation } from 'react-i18next'\nimport { getIPFSString, getTimestampDaysLater, makeMeta } from '../../utils'\nimport { ActionResultCode, DAYS } from '../../defs'\nimport { useHistory } from 'react-router-dom'\nimport Web3 from 'web3'\nimport { isAccActivated } from './useCheckAccStatus'\n\nconst CID = require('cids')\n\nexport const useNFTMintAdvance = <T extends TradeNFT<I, Co>, Co extends CollectionMeta, I>() => {\n  const { tokenMap, totalCoinMap } = useTokenMap()\n  const { account } = useAccount()\n  const { exchangeInfo, chainId } = useSystem()\n  const collectionListProps = useMyCollection<Co>()\n  const { nftMintAdvanceValue, updateNFTMintAdvanceData, resetNFTMintAdvanceData } = useModalData()\n  const { btnStatus, btnInfo, enableBtn, disableBtn, setLabelAndParams, resetBtnInfo } =\n    useBtnStatus()\n  const { t } = useTranslation('common')\n  const { checkHWAddr, updateHW } = useWalletInfo()\n  const { page, updateWalletLayer2NFT } = useWalletLayer2NFT()\n  const [isNotAvailableCID, setIsNotAvailableCID] = React.useState<undefined | { reason: string }>(\n    undefined,\n  )\n  const [isNotAvailableTokenAddress, setIsNotAvailableTokenAddress] = React.useState<\n    undefined | { reason: string }\n  >(undefined)\n  const [isNFTCheckLoading, setIsNFTCheckLoading] = React.useState(false)\n  const { setShowAccount, setShowNFTMintAdvance } = useOpenModals()\n  const { baseURL, etherscanBaseUrl } = useSystem()\n  const history = useHistory()\n  const {\n    chargeFeeTokenList,\n    isFeeNotEnough,\n    resetIntervalTime,\n    checkFeeIsEnough,\n    handleFeeChange,\n    feeInfo,\n  } = useChargeFees({\n    tokenAddress: nftMintAdvanceValue?.collectionMeta?.contractAddress, //tokenAddress?.toLowerCase(),\n    requestType: sdk.OffchainNFTFeeReqType.NFT_MINT,\n    updateData: ({ fee }) => {\n      updateNFTMintAdvanceData({\n        ...nftMintAdvanceValue,\n        fee,\n      })\n    },\n  })\n  const checkAvailable = ({\n    nftMintAdvanceValue,\n    isFeeNotEnough,\n    isNotAvailableCID,\n  }: {\n    nftMintAdvanceValue: Partial<T>\n    isFeeNotEnough: any\n    isNotAvailableCID: undefined | { reason: string }\n  }) => {\n    return (\n      nftMintAdvanceValue &&\n      nftMintAdvanceValue.royaltyPercentage !== undefined &&\n      Number.isInteger(Number(nftMintAdvanceValue.royaltyPercentage)) &&\n      nftMintAdvanceValue.royaltyPercentage >= 0 &&\n      nftMintAdvanceValue.royaltyPercentage <= 10 &&\n      nftMintAdvanceValue.tradeValue &&\n      Number(nftMintAdvanceValue.tradeValue) > 0 &&\n      Number(nftMintAdvanceValue.tradeValue) <= MINT_LIMIT &&\n      (nftMintAdvanceValue.image !== undefined || nftMintAdvanceValue.name !== undefined) &&\n      nftMintAdvanceValue.nftId &&\n      nftMintAdvanceValue.fee &&\n      nftMintAdvanceValue.fee.belong &&\n      nftMintAdvanceValue.fee.feeRaw &&\n      !isFeeNotEnough.isFeeNotEnough &&\n      !isNotAvailableCID\n    )\n  }\n\n  const updateBtnStatus = React.useCallback(\n    (error?: ErrorType & any) => {\n      resetBtnInfo()\n      if (\n        !error &&\n        checkAvailable({\n          nftMintAdvanceValue: nftMintAdvanceValue as any,\n          isFeeNotEnough,\n          isNotAvailableCID,\n        })\n      ) {\n        enableBtn()\n        return\n      }\n      if (isNotAvailableCID) {\n        setLabelAndParams('labelNFTMintWrongCIDBtn', {})\n      } else if (\n        (!nftMintAdvanceValue.image && !nftMintAdvanceValue.name) ||\n        !(\n          nftMintAdvanceValue.royaltyPercentage !== undefined &&\n          Number.isInteger(nftMintAdvanceValue.royaltyPercentage / 1) &&\n          nftMintAdvanceValue.royaltyPercentage >= 0 &&\n          nftMintAdvanceValue.royaltyPercentage <= 10\n        )\n      ) {\n        setLabelAndParams('labelNFTMintNoMetaBtn', {})\n      }\n      disableBtn()\n      myLog('try to disable nftMintAdvance btn!')\n    },\n    [\n      isNotAvailableCID,\n      isFeeNotEnough,\n      resetBtnInfo,\n      nftMintAdvanceValue,\n      enableBtn,\n      setLabelAndParams,\n      disableBtn,\n    ],\n  )\n\n  useWalletLayer2Socket({})\n\n  React.useEffect(() => {\n    updateBtnStatus()\n  }, [isFeeNotEnough.isFeeNotEnough, isNotAvailableCID, nftMintAdvanceValue, feeInfo])\n\n  const resetDefault = React.useCallback(() => {\n    checkFeeIsEnough({ isRequiredAPI: true, intervalTime: LIVE_FEE_TIMES })\n    resetNFTMintAdvanceData()\n  }, [checkFeeIsEnough, updateNFTMintAdvanceData])\n  const processRequest = React.useCallback(\n    async (request: sdk.NFTMintRequestV3, isNotHardwareWallet: boolean) => {\n      const { apiKey, connectName, eddsaKey } = account\n\n      try {\n        if (connectProvides.usedWeb3 && LoopringAPI.userAPI && isAccActivated()) {\n          let isHWAddr = checkHWAddr(account.accAddress)\n\n          if (!isHWAddr && !isNotHardwareWallet) {\n            isHWAddr = true\n          }\n\n          const response = await LoopringAPI.userAPI?.submitNFTMint(\n            {\n              request,\n              web3: connectProvides.usedWeb3 as unknown as Web3,\n              chainId: chainId === NETWORKEXTEND.NONETWORK ? sdk.ChainId.MAINNET : chainId,\n              walletType: (ConnectProviders[connectName] ??\n                connectName) as unknown as sdk.ConnectorNames,\n              eddsaKey: eddsaKey.sk,\n              apiKey,\n              isHWAddr,\n            },\n            {\n              accountId: account.accountId,\n              counterFactualInfo: eddsaKey.counterFactualInfo,\n            } as any,\n          )\n\n          myLog('submitNFTMintAdvance:', response)\n\n          if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n            throw response\n          }\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.NFTMint_In_Progress,\n            info: {\n              symbol: nftMintAdvanceValue.name,\n              value: nftMintAdvanceValue.tradeValue,\n            },\n          })\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.NFTMint_Success,\n            info: {\n              symbol: nftMintAdvanceValue.name,\n              value: nftMintAdvanceValue.tradeValue,\n              lastStep: LAST_STEP.nftMintAdv,\n              hash: Explorer + `tx/${(response as sdk.TX_HASH_API)?.hash}-nftMintAdvance`,\n            },\n          })\n\n          if (isHWAddr) {\n            myLog('......try to set isHWAddr', isHWAddr)\n            updateHW({ wallet: account.accAddress, isHWAddr })\n          }\n          walletLayer2Service.sendUserUpdate()\n          history.push({\n            pathname: `${RouterPath.nft}/${NFTSubRouter.assetsNFT}/byCollection/${nftMintAdvanceValue?.collectionMeta?.contractAddress}--${nftMintAdvanceValue?.collectionMeta?.id}`,\n          })\n          resetDefault()\n          await sdk.sleep(SUBMIT_PANEL_QUICK_AUTO_CLOSE)\n          if (\n            store.getState().modals.isShowAccount.isShow &&\n            store.getState().modals.isShowAccount.step == AccountStep.NFTMint_Success\n          ) {\n            setShowAccount({ isShow: false })\n          }\n        }\n      } catch (e: any) {\n        myLog('useADNFTMint', e)\n        const code = sdk.checkErrorInfo(e, isNotHardwareWallet)\n        switch (code) {\n          case sdk.ConnectorError.NOT_SUPPORT_ERROR:\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.NFTMint_First_Method_Denied,\n              info: {\n                symbol: nftMintAdvanceValue.name,\n                value: nftMintAdvanceValue.tradeValue,\n                isAdvanceMint: true,\n              },\n            })\n            break\n          case sdk.ConnectorError.USER_DENIED:\n          case sdk.ConnectorError.USER_DENIED_2:\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.NFTMint_Denied,\n              info: {\n                symbol: nftMintAdvanceValue.name,\n                value: nftMintAdvanceValue.tradeValue,\n                isAdvanceMint: true,\n              },\n            })\n            break\n          default:\n            if ([102024, 102025, 114001, 114002].includes((e as sdk.RESULT_INFO)?.code || 0)) {\n              checkFeeIsEnough({ isRequiredAPI: true })\n            } else if ([102040].includes((e as sdk.RESULT_INFO)?.code || 0)) {\n              walletLayer2Service.sendUserUpdate()\n              history.push({\n                pathname: `${RouterPath.nft}/${NFTSubRouter.assetsNFT}/byCollection/${nftMintAdvanceValue?.collectionMeta?.contractAddress}--${nftMintAdvanceValue?.collectionMeta?.id}`,\n              })\n              resetDefault()\n            }\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.NFTMint_Failed,\n              info: {\n                symbol: nftMintAdvanceValue.name,\n                value: nftMintAdvanceValue.tradeValue,\n              },\n              error: {\n                code: UIERROR_CODE.UNKNOWN,\n                msg: e?.message,\n                ...(e instanceof Error\n                  ? {\n                      message: e?.message,\n                      stack: e?.stack,\n                    }\n                  : e ?? {}),\n              },\n            })\n            break\n        }\n      }\n    },\n    [\n      account,\n      checkHWAddr,\n      chainId,\n      setShowAccount,\n      nftMintAdvanceValue.name,\n      nftMintAdvanceValue.tradeValue,\n      resetDefault,\n      checkFeeIsEnough,\n      updateWalletLayer2NFT,\n      page,\n      updateHW,\n    ],\n  )\n\n  const handleOnNFTDataChange = React.useCallback(\n    async (data: Partial<T>) => {\n      let shouldUpdate: any = {\n        balance: MINT_LIMIT,\n      }\n\n      if (data.hasOwnProperty('tokenAddress')) {\n        let collectionMeta: any = undefined\n        setIsNFTCheckLoading(true)\n        setIsNotAvailableTokenAddress(undefined)\n        if (data.tokenAddress === '') {\n          shouldUpdate = {\n            tokenAddress: undefined,\n            collectionMeta: undefined,\n          }\n        } else {\n          try {\n            const response = await LoopringAPI.userAPI\n              ?.getUserOwenCollection(\n                {\n                  owner: account.accAddress,\n                  tokenAddress: data.tokenAddress,\n                  // @ts-ignore\n                  isMintable: true,\n                },\n                account.apiKey,\n              )\n              .catch((_error) => {\n                throw new CustomError(ErrorMap.TIME_OUT)\n              })\n            if (\n              (response &&\n                ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message)) ||\n              !response.collections.length\n            ) {\n              throw new CustomError(ErrorMap.ERROR_COLLECTION_INFO)\n            }\n\n            collectionMeta = (response as any).collections[0] as CollectionMeta\n            shouldUpdate = {\n              tokenAddress: collectionMeta?.contractAddress,\n              collectionMeta: collectionMeta,\n            }\n          } catch (error) {\n            shouldUpdate = {\n              tokenAddress: undefined,\n              collectionMeta: undefined,\n            }\n            setIsNotAvailableTokenAddress({\n              reason: ErrorMap.ERROR_COLLECTION_INFO.messageKey,\n            })\n          }\n        }\n        setIsNFTCheckLoading(false)\n      } else if (!nftMintAdvanceValue.tokenAddress) {\n        resetNFTMintAdvanceData()\n      } else if (\n        nftMintAdvanceValue.tokenAddress &&\n        data.hasOwnProperty('nftIdView') &&\n        LoopringAPI.nftAPI &&\n        nftMintAdvanceValue.nftIdView !== data.nftIdView\n      ) {\n        setIsNFTCheckLoading(true)\n\n        if (!data.nftIdView) {\n          shouldUpdate = {\n            nftIdView: undefined,\n            nftId: undefined,\n          }\n        } else {\n          let nftId: string = ''\n          try {\n            let cid: string\n            if (/^Qm[a-zA-Z0-9]{44}$/.test(data.nftIdView)) {\n              cid = data.nftIdView\n            } else {\n              cid = new CID(data.nftIdView).toV0()\n            }\n            nftId = LoopringAPI.nftAPI.ipfsCid0ToNftID(cid)\n            shouldUpdate = {\n              nftId,\n              ...shouldUpdate,\n            }\n          } catch (error: any) {\n            myLog('handleOnNFTDataChange -> data.nftId', error)\n            // setIsAvailableId(false);\n            setIsNotAvailableCID({\n              reason: ErrorMap.IPFS_CID_TO_NFTID_ERROR.messageKey,\n            })\n            shouldUpdate = {\n              nftId: undefined,\n              nftIdView: undefined,\n            }\n          }\n\n          if (nftId && nftId !== '') {\n            try {\n              const value = await fetch(getIPFSString(`${IPFS_HEAD_URL}${data.nftIdView}`, baseURL))\n                .then((response) => response.json())\n                .catch((_error) => {\n                  setIsNotAvailableCID({\n                    reason: ErrorMap.IPFS_TIME_OUT.messageKey,\n                  })\n                  throw ErrorMap.IPFS_TIME_OUT\n                })\n              if (value) {\n                shouldUpdate = {\n                  nftId: nftId,\n                  name: value.name ?? t('labelUnknown'),\n                  image: value.image,\n                  collection_metadata: value.collection_metadata,\n                  description: value.description ?? EmptyValueTag,\n                  royaltyPercentage: isNaN(value.royalty_percentage)\n                    ? undefined\n                    : Number(value.royalty_percentage),\n                  ...shouldUpdate,\n                }\n                setIsNotAvailableCID(undefined)\n              } else {\n                setIsNotAvailableCID({\n                  reason: ErrorMap.ERROR_COLLECTION_EMPTY.messageKey,\n                })\n                throw ErrorMap.ERROR_COLLECTION_EMPTY\n              }\n            } catch (error: any) {\n              console.log('Mint NFT read resource error:', error)\n              shouldUpdate = {\n                nftId: undefined,\n                nftIdView: undefined,\n                name: undefined,\n                image: undefined,\n                description: undefined,\n                balance: undefined,\n                ...shouldUpdate,\n              }\n              setIsNotAvailableCID({ reason: error.messageKey })\n            }\n          }\n        }\n      } else {\n        shouldUpdate = {\n          ...shouldUpdate,\n          ...data,\n        }\n      }\n      setIsNFTCheckLoading(false)\n      updateNFTMintAdvanceData({\n        ...shouldUpdate,\n      })\n    },\n    [nftMintAdvanceValue, t, updateNFTMintAdvanceData],\n  )\n\n  const onNFTMintAdvanceClick = React.useCallback(\n    async (_nftMintAdvanceValue, isHardwareRetry: boolean = false) => {\n      let result = { code: ActionResultCode.NoError }\n      // pattern=\"^Qm[a-zA-Z0-9]{44}$\"\n      if (\n        LoopringAPI.userAPI &&\n        LoopringAPI.nftAPI &&\n        exchangeInfo &&\n        account.readyState === AccountStatus.ACTIVATED &&\n        nftMintAdvanceValue &&\n        nftMintAdvanceValue.collectionMeta?.contractAddress &&\n        checkAvailable({\n          nftMintAdvanceValue: nftMintAdvanceValue as any,\n          isFeeNotEnough,\n          isNotAvailableCID,\n        })\n      ) {\n        setShowNFTMintAdvance({ isShow: false })\n        setShowAccount({\n          isShow: true,\n          step: AccountStep.NFTMint_WaitForAuth,\n          info: {\n            symbol: nftMintAdvanceValue.name,\n            value: nftMintAdvanceValue.tradeValue,\n          },\n        })\n        try {\n          const { accountId, accAddress, apiKey } = account\n          const fee = sdk.toBig(\n            nftMintAdvanceValue?.fee?.feeRaw ?? nftMintAdvanceValue?.fee?.__raw__?.feeRaw ?? 0,\n          )\n          const feeToken = tokenMap[nftMintAdvanceValue?.fee?.belong ?? '']\n          const storageId = await LoopringAPI.userAPI.getNextStorageId(\n            {\n              accountId,\n              sellTokenId: feeToken.tokenId,\n            },\n            apiKey,\n          )\n\n          const req: sdk.NFTMintRequestV3 = {\n            exchange: exchangeInfo.exchangeAddress,\n            minterId: accountId,\n            minterAddress: accAddress,\n            toAccountId: accountId,\n            toAddress: accAddress,\n            nftType: 0,\n            tokenAddress: nftMintAdvanceValue.collectionMeta.contractAddress,\n            nftId: nftMintAdvanceValue.nftId ?? '',\n            amount: nftMintAdvanceValue.tradeValue?.toString() ?? '',\n            validUntil: getTimestampDaysLater(DAYS),\n            storageId: storageId?.offchainId,\n            maxFee: {\n              tokenId: feeToken.tokenId,\n              amount: fee.toString(), // TEST: fee.toString(),\n            },\n            counterFactualNftInfo: {\n              nftOwner: account.accAddress,\n              nftFactory:\n                nftMintAdvanceValue.collectionMeta.nftFactory ?? sdk.NFTFactory_Collection[chainId],\n              nftBaseUri: nftMintAdvanceValue.collectionMeta?.baseUri ?? '',\n            },\n            royaltyPercentage: Math.floor(nftMintAdvanceValue?.royaltyPercentage ?? 0),\n            forceToMint: false,\n          }\n          myLog('onNFTMintAdvanceClick req:', req)\n\n          processRequest(req, !isHardwareRetry)\n        } catch (e: any) {\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.NFTMint_Failed,\n            info: {\n              symbol: nftMintAdvanceValue.name,\n              value: nftMintAdvanceValue.tradeValue,\n            },\n            error: {\n              code: UIERROR_CODE.UNKNOWN,\n              msg: e?.message,\n              ...(e instanceof Error\n                ? {\n                    message: e?.message,\n                    stack: e?.stack,\n                  }\n                : e ?? {}),\n            },\n          })\n        }\n        return\n      } else {\n        result.code = ActionResultCode.DataNotReady\n      }\n    },\n    [\n      account,\n      chainId,\n      checkAvailable,\n      exchangeInfo,\n      isNotAvailableCID,\n      isFeeNotEnough,\n      nftMintAdvanceValue,\n      processRequest,\n      setShowAccount,\n      setShowNFTMintAdvance,\n      tokenMap,\n    ],\n  )\n  const retryBtn = React.useCallback(\n    (isHardwareRetry: boolean = false) => {\n      setShowAccount({\n        isShow: true,\n        step: AccountStep.NFTMint_WaitForAuth,\n        info: {\n          symbol: nftMintAdvanceValue.name,\n          value: nftMintAdvanceValue.tradeValue,\n        },\n      })\n      onNFTMintAdvanceClick({}, isHardwareRetry)\n    },\n    [nftMintAdvanceValue.name, nftMintAdvanceValue.tradeValue, processRequest, setShowAccount],\n  )\n  const nftMintAdvanceProps: NFTMintAdvanceProps<T, Co, I> = {\n    chargeFeeTokenList,\n    isFeeNotEnough,\n    handleFeeChange,\n    feeInfo,\n    isNFTCheckLoading,\n    isNotAvailableTokenAddress,\n    isNotAvailableCID,\n    collectionInputProps: {\n      collectionListProps: {\n        ...collectionListProps,\n        size: 'small',\n      },\n      collection: nftMintAdvanceValue.collectionMeta as Co,\n      onSelected: (item) => {\n        handleOnNFTDataChange({ collectionMeta: item } as unknown as T)\n      },\n      domain: LoopringAPI.delegate?.getCollectionDomain() ?? '',\n      makeMeta,\n    },\n    etherscanBaseUrl,\n    baseURL,\n    getIPFSString,\n    handleOnNFTDataChange,\n    onNFTMintClick: onNFTMintAdvanceClick,\n    walletMap: {} as any,\n    coinMap: totalCoinMap as any,\n    tradeData: { ...nftMintAdvanceValue } as any,\n    nftMintBtnStatus: btnStatus,\n    btnInfo,\n  }\n\n  return {\n    nftMintAdvanceProps,\n    retryBtn,\n    resetIntervalTime,\n    resetDefault,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/useNFTTransfer.ts",
    "content": "import React from 'react'\n\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nimport { ConnectProviders, connectProvides } from '@loopring-web/web3-provider'\n\nimport {\n  AccountStep,\n  SwitchData,\n  TransferProps,\n  useOpenModals,\n  useSettings,\n} from '@loopring-web/component-lib'\nimport {\n  AccountStatus,\n  AddressError,\n  CoinMap,\n  CurrencyToTag,\n  EmptyValueTag,\n  EXCHANGE_TYPE,\n  Explorer,\n  FeeInfo,\n  getValuePrecisionThousand,\n  LIVE_FEE_TIMES,\n  myLog,\n  PriceTag,\n  SagaStatus,\n  SUBMIT_PANEL_AUTO_CLOSE,\n  TRADE_TYPE,\n  TradeNFT,\n  UIERROR_CODE,\n  WALLET_TYPE,\n} from '@loopring-web/common-resources'\n\nimport {\n  BIGO,\n  DAYS,\n  getIPFSString,\n  getTimestampDaysLater,\n  isAccActivated,\n  LAST_STEP,\n  LoopringAPI,\n  store,\n  useAccount,\n  useAddressCheck,\n  useBtnStatus,\n  useChargeFees,\n  useModalData,\n  useSystem,\n  useTokenMap,\n  useTokenPrices,\n  useWalletLayer2,\n  useWalletLayer2WithNFTSocket,\n  volumeToCountAsBigNumber,\n  walletLayer2Service,\n} from '../../index'\nimport { useWalletInfo } from '../../stores/localStore/walletInfo'\nimport { useHistory, useLocation } from 'react-router-dom'\nimport { addressToExWalletMapFn, exWalletToAddressMapFn } from '@loopring-web/core'\nimport { NETWORKEXTEND, useContacts } from '../../stores'\nimport Web3 from 'web3'\n\nexport const useNFTTransfer = <R extends TradeNFT<T, any>, T>() => {\n  const {\n    setShowAccount,\n    setShowNFTTransfer,\n    setShowNFTDetail,\n    setShowEditContact,\n    modals: {\n      isShowNFTDetail,\n      isShowNFTTransfer: {\n        isShow,\n        info,\n        address: contactAddress,\n        name: contactName,\n        addressType: contactAddressType,\n      },\n    },\n  } = useOpenModals()\n\n  const { tokenMap, totalCoinMap } = useTokenMap()\n  const { account, status: accountStatus } = useAccount()\n  const { exchangeInfo, chainId, baseURL, forexMap } = useSystem()\n  const { currency } = useSettings()\n  const { tokenPrices } = useTokenPrices()\n  const {\n    contacts,\n    updateContacts,\n    errorMessage: contactsErrorMessage,\n    status: contactStatus,\n  } = useContacts()\n  const { updateWalletLayer2 } = useWalletLayer2()\n\n  const { nftTransferValue, updateNFTWithdrawData, updateNFTTransferData } =\n    useModalData()\n\n\n  const history = useHistory()\n  const { search, pathname } = useLocation()\n  const searchParams = new URLSearchParams(search)\n\n  const [sureItsLayer2, setSureItsLayer2] = React.useState<WALLET_TYPE | EXCHANGE_TYPE | undefined>(\n    undefined,\n  )\n\n  const [feeWithActive, setFeeWithActive] = React.useState(false)\n  // const [chargeFeeTransferList, setChargeFeeTransferList] = React.useState([\n  //   false,\n  // ]);\n  const {\n    chargeFeeTokenList,\n    isFeeNotEnough,\n    handleFeeChange,\n    feeInfo,\n    resetIntervalTime,\n    checkFeeIsEnough,\n  } = useChargeFees({\n    tokenAddress: nftTransferValue.tokenAddress,\n    // requestType: sdk.OffchainNFTFeeReqType.NFT_TRANSFER,\n    requestType: feeWithActive\n      ? sdk.OffchainNFTFeeReqType.NFT_TRANSFER_AND_UPDATE_ACCOUNT\n      : sdk.OffchainNFTFeeReqType.NFT_TRANSFER,\n    updateData:\n      // React.useCallback(\n      ({ fee, requestType }) => {\n        let _requestType = feeWithActive\n          ? sdk.OffchainNFTFeeReqType.NFT_TRANSFER_AND_UPDATE_ACCOUNT\n          : sdk.OffchainNFTFeeReqType.NFT_TRANSFER\n        if (_requestType === requestType) {\n          const nftTransferValue = store.getState()._router_modalData.nftTransferValue\n          updateNFTTransferData({\n            ...nftTransferValue,\n            balance: sdk\n              .toBig(nftTransferValue.total ?? 0)\n              .minus(nftTransferValue.locked ?? 0)\n              .toNumber(),\n            fee,\n          })\n        }\n      },\n    //   [feeWithActive]\n    // ),\n  })\n\n  const {\n    chargeFeeTokenList: activeAccountFeeList,\n    checkFeeIsEnough: checkActiveFeeIsEnough,\n    // resetIntervalTime: resetActiveIntervalTime,\n  } = useChargeFees({\n    isActiveAccount: true,\n    requestType: undefined as any,\n  })\n  const {\n    address,\n    realAddr,\n    setAddress,\n    addrStatus,\n    isActiveAccount,\n    isActiveAccountFee,\n    isLoopringAddress,\n    isAddressCheckLoading,\n    isSameAddress,\n    isContractAddress,\n    loopringSmartWalletVersion,\n    reCheck,\n    isENSWrong,\n    ens,\n  } = useAddressCheck()\n\n  React.useEffect(() => {\n    if (loopringSmartWalletVersion?.isLoopringSmartWallet && sureItsLayer2 === undefined) {\n      setSureItsLayer2(WALLET_TYPE.Loopring)\n    }\n  }, [loopringSmartWalletVersion?.isLoopringSmartWallet])\n\n  const { btnStatus, enableBtn, disableBtn } = useBtnStatus()\n  const handleOnMemoChange = React.useCallback(\n    (e: React.ChangeEvent<HTMLInputElement>) => {\n      const nftTransferValue = store.getState()._router_modalData.nftTransferValue\n      updateNFTTransferData({\n        ...nftTransferValue,\n        memo: e.target.value,\n      })\n    },\n    [updateNFTTransferData],\n  )\n  const checkBtnStatus = React.useCallback(() => {\n    const contact = contacts?.find((x) => x.contactAddress === realAddr)\n    const ensHasCheck = (contact?.ens || ens) \n        ? !isENSWrong \n        : true\n    if (\n      tokenMap &&\n      nftTransferValue.fee?.belong &&\n      nftTransferValue?.tradeValue &&\n      chargeFeeTokenList.length &&\n      !isFeeNotEnough.isFeeNotEnough &&\n      !isSameAddress &&\n      ensHasCheck &&\n      sureItsLayer2 &&\n      sdk.toBig(nftTransferValue.tradeValue).gt(BIGO) &&\n      sdk.toBig(nftTransferValue.tradeValue).lte(Number(nftTransferValue.balance) ?? 0) &&\n      (addrStatus as AddressError) === AddressError.NoError &&\n      realAddr\n    ) {\n      enableBtn()\n      myLog('enableBtn')\n      return\n    }\n    disableBtn()\n  }, [\n    tokenMap,\n    nftTransferValue.fee?.belong,\n    nftTransferValue.tradeValue,\n    nftTransferValue.balance,\n    chargeFeeTokenList.length,\n    isFeeNotEnough?.isFeeNotEnough,\n    isSameAddress,\n    sureItsLayer2,\n    addrStatus,\n    realAddr,\n    disableBtn,\n    enableBtn,\n    contacts,\n  ])\n\n  React.useEffect(() => {\n    checkBtnStatus()\n  }, [\n    address,\n    addrStatus,\n    sureItsLayer2,\n    isFeeNotEnough.isFeeNotEnough,\n    isSameAddress,\n    nftTransferValue.tradeValue,\n    nftTransferValue.fee,\n  ])\n  const walletLayer2Callback = React.useCallback(() => {\n    checkFeeIsEnough()\n  }, [checkFeeIsEnough])\n\n  useWalletLayer2WithNFTSocket({ walletLayer2Callback })\n\n  const resetDefault = React.useCallback(() => {\n    if (info?.isRetry) {\n      checkFeeIsEnough()\n      return\n    }\n    if (contactsErrorMessage) {\n      updateContacts()\n    }\n    checkFeeIsEnough({ isRequiredAPI: true, intervalTime: LIVE_FEE_TIMES })\n    // checkActiveFeeIsEnough({\n    //   isRequiredAPI: true,\n    //   // intervalTime: LIVE_FEE_TIMES,\n    // });\n    if (nftTransferValue.nftData) {\n      updateNFTTransferData({\n        balance: sdk\n          .toBig(nftTransferValue.total ?? 0)\n          .minus(nftTransferValue.locked ?? 0)\n          .toNumber(),\n        belong: nftTransferValue.name as any,\n        tradeValue: undefined,\n        fee: feeInfo,\n        address: address ? address : '*',\n      })\n    } else {\n      updateNFTTransferData({\n        fee: feeInfo,\n        belong: '',\n        balance: 0,\n        tradeValue: 0,\n        address: '*',\n      })\n    }\n    if (contactAddress) {\n      setAddress(contactAddress)\n    } else {\n      setAddress('')\n    }\n  }, [\n    info?.isRetry,\n    contactsErrorMessage,\n    checkFeeIsEnough,\n    nftTransferValue.nftData,\n    nftTransferValue.total,\n    nftTransferValue.locked,\n    nftTransferValue.name,\n    contactAddress,\n    updateContacts,\n    updateNFTTransferData,\n    feeInfo,\n    address,\n    setAddress,\n  ])\n\n  React.useEffect(() => {\n    if (isShow || info?.isShowLocal) {\n      updateWalletLayer2()\n      resetDefault()\n    } else {\n      resetIntervalTime()\n      checkActiveFeeIsEnough({\n        isRequiredAPI: true,\n        requestType: undefined as any,\n      })\n    }\n    return () => {\n      resetIntervalTime()\n      setAddress('')\n      checkActiveFeeIsEnough({\n        isRequiredAPI: true,\n        requestType: undefined as any,\n      })\n    }\n  }, [isShow, info?.isShowLocal])\n\n  React.useEffect(() => {\n    if (accountStatus === SagaStatus.UNSET && account.readyState === AccountStatus.ACTIVATED) {\n      // myLog('useEffect nftTransferValue.address:', nftTransferValue.address)\n      setAddress(nftTransferValue.address ? nftTransferValue.address : '')\n    }\n  }, [setAddress, nftTransferValue.address, accountStatus, account.readyState])\n\n  const { checkHWAddr, updateHW } = useWalletInfo()\n\n  const [lastRequest, setLastRequest] = React.useState<any>({})\n\n  const processRequest = React.useCallback(\n    async (request: sdk.OriginNFTTransferRequestV3, isNotHardwareWallet: boolean) => {\n      const { apiKey, connectName, eddsaKey } = account\n      try {\n        if (connectProvides.usedWeb3 && LoopringAPI.userAPI && isAccActivated()) {\n          let isHWAddr = checkHWAddr(account.accAddress)\n\n          if (!isHWAddr && !isNotHardwareWallet) {\n            isHWAddr = true\n          }\n\n          setLastRequest({ request })\n\n          const response = await LoopringAPI.userAPI?.submitNFTInTransfer(\n            {\n              request,\n              web3: connectProvides.usedWeb3 as unknown as Web3,\n              chainId: chainId === NETWORKEXTEND.NONETWORK ? sdk.ChainId.MAINNET : chainId,\n              walletType: (ConnectProviders[connectName] ??\n                connectName) as unknown as sdk.ConnectorNames,\n              eddsaKey: eddsaKey.sk,\n              apiKey,\n              isHWAddr,\n            },\n            {\n              accountId: account.accountId,\n              counterFactualInfo: eddsaKey.counterFactualInfo,\n            },\n          )\n\n          myLog('submitInternalTransfer:', response)\n\n          if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n            throw response\n          }\n          setShowNFTTransfer({ isShow: false })\n          // setIsConfirmTransfer(false);\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.NFTTransfer_In_Progress,\n          })\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.NFTTransfer_Success,\n            info: {\n              symbol: nftTransferValue.name,\n              hash:\n                Explorer +\n                `tx/${(response as sdk.TX_HASH_API)?.hash}-nftTransfer-${account.accountId}-${\n                  request.token.tokenId\n                }-${request.storageId}`,\n            },\n          })\n          if (isHWAddr) {\n            myLog('......try to set isHWAddr', isHWAddr)\n            updateHW({ wallet: account.accAddress, isHWAddr })\n          }\n          setShowNFTDetail({\n            ...isShowNFTDetail,\n            locked: (\n              Number(isShowNFTDetail?.locked ?? 0) + Number(request?.token?.amount)\n            ).toString(),\n          })\n          updateNFTWithdrawData({\n            ...isShowNFTDetail,\n            locked: (\n              Number(isShowNFTDetail?.locked ?? 0) + Number(request?.token?.amount)\n            ).toString(),\n          })\n          updateNFTTransferData({\n            ...isShowNFTDetail,\n            locked: (\n              Number(isShowNFTDetail?.locked ?? 0) + Number(request?.token?.amount)\n            ).toString(),\n          })\n          walletLayer2Service.sendUserUpdate()\n          // resetNFTTransferData();\n          await sdk.sleep(SUBMIT_PANEL_AUTO_CLOSE)\n          if (\n            store.getState().modals.isShowAccount.isShow &&\n            store.getState().modals.isShowAccount.step == AccountStep.NFTTransfer_Success\n          ) {\n            setShowAccount({ isShow: false })\n            searchParams.delete('detail')\n            history.push(pathname + '?' + searchParams.toString())\n          }\n        }\n      } catch (e: any) {\n        const code = sdk.checkErrorInfo(e, isNotHardwareWallet)\n        switch (code) {\n          case sdk.ConnectorError.NOT_SUPPORT_ERROR:\n            setLastRequest({ request })\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.NFTTransfer_First_Method_Denied,\n              info: {\n                symbol: nftTransferValue.name,\n              },\n            })\n            break\n          case sdk.ConnectorError.USER_DENIED:\n          case sdk.ConnectorError.USER_DENIED_2:\n            setLastRequest({ request })\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.NFTTransfer_User_Denied,\n            })\n            break\n          default:\n            if ([102024, 102025, 114001, 114002].includes((e as sdk.RESULT_INFO)?.code || 0)) {\n              checkFeeIsEnough({\n                isRequiredAPI: true,\n                requestType: feeWithActive\n                  ? sdk.OffchainNFTFeeReqType.NFT_TRANSFER_AND_UPDATE_ACCOUNT\n                  : sdk.OffchainNFTFeeReqType.NFT_TRANSFER,\n              })\n            }\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.NFTTransfer_Failed,\n              info: {\n                symbol: nftTransferValue.name,\n              },\n              error: {\n                code: UIERROR_CODE.UNKNOWN,\n                msg: e?.message,\n                ...(e instanceof Error\n                  ? {\n                      message: e?.message,\n                      stack: e?.stack,\n                    }\n                  : e ?? {}),\n              },\n            })\n            break\n        }\n      }\n    },\n    [\n      account,\n      checkHWAddr,\n      chainId,\n      setShowNFTTransfer,\n      setShowAccount,\n      nftTransferValue.name,\n      setShowNFTDetail,\n      isShowNFTDetail,\n      updateNFTWithdrawData,\n      updateNFTTransferData,\n      updateHW,\n      searchParams,\n      history,\n      pathname,\n      checkFeeIsEnough,\n      feeWithActive,\n    ],\n  )\n\n  const onTransferClick = React.useCallback(\n    async (_nftTransferValue, isFirstTime: boolean = true) => {\n      const { accountId, accAddress, readyState, apiKey, eddsaKey } = account\n      const nftTransferValue = {\n        ...store.getState()._router_modalData.nftTransferValue,\n        // tradeValue: _nftTransferValue.tradeValue,\n        // balance: _nftTransferValue.balance,\n      }\n      if (\n        readyState === AccountStatus.ACTIVATED &&\n        tokenMap &&\n        LoopringAPI.userAPI &&\n        exchangeInfo &&\n        connectProvides.usedWeb3 &&\n        nftTransferValue?.nftData &&\n        nftTransferValue?.fee?.belong &&\n        nftTransferValue?.fee?.feeRaw &&\n        nftTransferValue.tradeValue &&\n        nftTransferValue.tokenId &&\n        eddsaKey?.sk\n      ) {\n        try {\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.NFTTransfer_WaitForAuth,\n          })\n          const feeToken = tokenMap[nftTransferValue.fee.belong]\n          const feeRaw = nftTransferValue.fee.feeRaw ?? nftTransferValue.fee.__raw__?.feeRaw ?? 0\n          const fee = sdk.toBig(feeRaw)\n          const tradeValue = nftTransferValue.tradeValue ?? _nftTransferValue.tradeValue\n          const balance = nftTransferValue.balance ?? _nftTransferValue.balance\n          const isExceedBalance = sdk.toBig(tradeValue).gt(balance)\n\n          if (isExceedBalance) {\n            throw Error('overflow balance')\n          }\n\n          const storageId = await LoopringAPI.userAPI?.getNextStorageId(\n            {\n              accountId,\n              sellTokenId: nftTransferValue.tokenId,\n            },\n            apiKey,\n          )\n\n          const req: sdk.OriginNFTTransferRequestV3 = {\n            exchange: exchangeInfo.exchangeAddress,\n            fromAccountId: accountId,\n            fromAddress: accAddress,\n            toAccountId: 0,\n            toAddress: realAddr ? realAddr : address,\n            storageId: storageId?.offchainId,\n            token: {\n              tokenId: nftTransferValue.tokenId,\n              nftData: nftTransferValue.nftData,\n              amount: tradeValue.toString(),\n            },\n            payPayeeUpdateAccount: !isActiveAccountFee && feeWithActive,\n            maxFee: {\n              tokenId: feeToken.tokenId,\n              amount: fee.toString(), // TEST: fee.toString(),\n            },\n            validUntil: getTimestampDaysLater(DAYS),\n            memo: nftTransferValue.memo,\n          }\n\n          myLog('nftTransfer req:', req)\n\n          processRequest(req, isFirstTime)\n        } catch (e: any) {\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.NFTTransfer_Failed,\n            info: {\n              symbol: nftTransferValue?.name,\n            },\n            error: {\n              code: UIERROR_CODE.UNKNOWN,\n              msg: e?.message,\n            },\n          })\n        }\n      } else {\n        return\n      }\n    },\n    [\n      account,\n      tokenMap,\n      exchangeInfo,\n      setShowAccount,\n      realAddr,\n      address,\n      processRequest,\n      isActiveAccountFee,\n      feeWithActive,\n    ],\n  )\n  // const activeFee = React.useMemo(() => {\n  //   // return activeAccountFeeList?.find(\n  //   //   (item: any) => item.belong == feeInfo.belong\n  //   // );\n  // }, [feeInfo, activeAccountFeeList]);\n  const activeAccountPrice = React.useMemo(() => {\n    if (\n      realAddr !== '' &&\n      !isActiveAccount &&\n      activeAccountFeeList.length &&\n      activeAccountFeeList[0] &&\n      tokenPrices &&\n      activeAccountFeeList[0].feeRaw\n    ) {\n      const feeInfo: FeeInfo = activeAccountFeeList[0]\n      const feeU: any =\n        volumeToCountAsBigNumber(feeInfo.belong, feeInfo.feeRaw ?? 0)?.times(\n          tokenPrices[feeInfo.belong],\n        ) ?? undefined\n      return feeU && currency && forexMap[currency]\n        ? '～' +\n            PriceTag[CurrencyToTag[currency]] +\n            getValuePrecisionThousand(\n              // @ts-ignore\n              feeU * forexMap[currency],\n              2,\n              2,\n              2,\n              true,\n              { floor: true },\n            )\n        : EmptyValueTag\n    } else {\n      return\n    }\n    // return activeAccountFeeList?.find(\n    //   (item: any) => item.belong == feeInfo.belong\n    // );\n  }, [realAddr, isActiveAccount, activeAccountFeeList, tokenPrices, currency, forexMap])\n  const handlePanelEvent = React.useCallback(\n    async (data: SwitchData<R>, _switchType: 'Tomenu' | 'Tobutton') => {\n      return new Promise<void>((res: any) => {\n        if (data.to === 'button') {\n          if (data.tradeData.belong) {\n            updateNFTTransferData({\n              belong: data.tradeData.belong,\n              tradeValue: data.tradeData?.tradeValue,\n              balance: data.tradeData.balance,\n              address: '*',\n            })\n          } else {\n            updateNFTTransferData({\n              belong: undefined,\n              tradeValue: undefined,\n              balance: undefined,\n              address: '*',\n            })\n          }\n        }\n\n        res()\n      })\n    },\n    [updateNFTTransferData],\n  )\n\n  React.useEffect(() => {\n    if (realAddr !== '' && isActiveAccount === false) {\n      checkActiveFeeIsEnough({\n        isRequiredAPI: true,\n        requestType: 'TRANSFER_ACTIVE',\n      })\n    }\n  }, [isActiveAccount, realAddr])\n\n  const retryBtn = React.useCallback(\n    (isHardwareRetry: boolean = false) => {\n      setShowAccount({\n        isShow: true,\n        step: AccountStep.NFTTransfer_WaitForAuth,\n      })\n      processRequest(lastRequest, !isHardwareRetry)\n    },\n    [lastRequest, processRequest, setShowAccount],\n  )\n  React.useEffect(() => {\n    const { contacts } = store.getState().contacts\n    const contact = contacts?.find(\n      (x) => x.contactAddress?.toLowerCase() === realAddr?.toLowerCase(),\n    )\n    if (isShow === false) {\n      setSureItsLayer2(undefined)\n    } else if (contact?.addressType !== undefined) {\n      const found = contact.addressType ? addressToExWalletMapFn(contact.addressType) : undefined\n      setSureItsLayer2(found)\n    }\n    if (\n      isShow &&\n      contactStatus == SagaStatus.UNSET &&\n      contact &&\n      realAddr?.toLowerCase() == contact?.contactAddress?.toLowerCase()\n    ) {\n      reCheck()\n    }\n  }, [realAddr, isShow, contactStatus])\n  const nftTransferProps: TransferProps<R, T> = {\n    handleOnMemoChange,\n    memo: nftTransferValue.memo ?? '',\n    type: TRADE_TYPE.NFT,\n    addressDefault: address,\n    realAddr,\n    lastFailed: store.getState().modals.isShowAccount.info?.lastFailed === LAST_STEP.nftTransfer,\n    handleSureItsLayer2: (sure: WALLET_TYPE | EXCHANGE_TYPE) => {\n      const found = exWalletToAddressMapFn(sure)!\n      const contact = contacts?.find((x) => x.contactAddress === realAddr)\n      if (!account.isContractAddress && contact) {\n        LoopringAPI.contactAPI?.updateContact(\n          {\n            ...contact,\n            isHebao: !!(account.isContractAddress || account.isCFAddress),\n            accountId: account.accountId,\n            addressType: found,\n          },\n          account.apiKey,\n        )\n        updateContacts()\n      }\n      setSureItsLayer2(sure)\n    },\n    // isConfirmTransfer,\n    sureItsLayer2,\n    tradeData: { ...nftTransferValue } as unknown as R,\n    coinMap: totalCoinMap as CoinMap<T>,\n    walletMap: {},\n    transferBtnStatus: btnStatus,\n    onTransferClick,\n    handleFeeChange,\n    addrStatus,\n    feeInfo,\n    chargeFeeTokenList,\n    activeAccountPrice,\n    // activeAccountFeeList,\n    // chargeFeeTransferList,\n    isFeeNotEnough,\n    handlePanelEvent,\n    isLoopringAddress,\n    baseURL,\n    getIPFSString,\n    isSameAddress,\n    isAddressCheckLoading,\n    handleOnAddressChange: (value: any) => {\n      checkActiveFeeIsEnough({\n        isRequiredAPI: true,\n        requestType: undefined as any,\n      })\n      setAddress((state) => {\n        if (state !== value || '') {\n          // flag = true;\n          setFeeWithActive((state) => {\n            if (state !== false) {\n              checkFeeIsEnough({\n                isRequiredAPI: true,\n                requestType: sdk.OffchainFeeReqType.TRANSFER,\n              })\n            }\n            return false\n          })\n        }\n        return value || ''\n      })\n    },\n    feeWithActive,\n    isActiveAccount,\n    isActiveAccountFee,\n    handleOnFeeWithActive: (value: boolean) => {\n      setFeeWithActive(value)\n      if (value && !isActiveAccountFee) {\n        checkFeeIsEnough({\n          isRequiredAPI: true,\n          requestType: sdk.OffchainNFTFeeReqType.NFT_TRANSFER_AND_UPDATE_ACCOUNT,\n        })\n      } else {\n        checkFeeIsEnough({\n          isRequiredAPI: true,\n          requestType: sdk.OffchainNFTFeeReqType.NFT_TRANSFER,\n        })\n      }\n    },\n    isSmartContractAddress: isContractAddress,\n    isFromContact: contactAddress ? true : false,\n    contact: contactAddress\n      ? {\n          address: contactAddress,\n          name: contactName!,\n          addressType: contactAddressType!,\n        }\n      : undefined,\n    loopringSmartWalletVersion,\n    contacts,\n    isENSWrong,\n    geUpdateContact: () => {\n      if (isENSWrong) {\n        const contact = contacts?.find((x) => x.contactAddress === realAddr)\n        setShowEditContact({\n          isShow: true,\n          info: {\n            ...contact,\n            isENSWrong,\n          },\n        })\n      }\n    },\n    ens,\n  }\n  // const cancelNFTTransfer = () => {\n  //   resetDefault();\n  // };\n  return {\n    nftTransferProps,\n    retryBtn,\n    // cancelNFTTransfer,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/useNFTWithdraw.ts",
    "content": "import React from 'react'\nimport { ConnectProviders, connectProvides } from '@loopring-web/web3-provider'\nimport { AccountStep, SwitchData, useOpenModals, useSettings, WithdrawProps } from '@loopring-web/component-lib'\nimport {\n  AccountStatus,\n  AddressError,\n  CoinMap,\n  EXCHANGE_TYPE,\n  Explorer,\n  LIVE_FEE_TIMES,\n  myLog,\n  SagaStatus,\n  SUBMIT_PANEL_AUTO_CLOSE,\n  TRADE_TYPE,\n  TradeNFT,\n  UIERROR_CODE,\n  WALLET_TYPE,\n} from '@loopring-web/common-resources'\n\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nimport {\n  BIGO,\n  DAYS,\n  fiatNumberDisplaySafe,\n  getIPFSString,\n  getTimestampDaysLater,\n  isAccActivated,\n  LAST_STEP,\n  LoopringAPI,\n  store,\n  tryFn,\n  useAccount,\n  useAddressCheck,\n  useBtnStatus,\n  useChargeFees,\n  useModalData,\n  useSystem,\n  useTokenMap,\n  useWalletLayer2NFT,\n  useWalletLayer2WithNFTSocket,\n  walletLayer2Service,\n} from '../../index'\nimport { useWalletInfo } from '../../stores/localStore/walletInfo'\nimport { useHistory, useLocation } from 'react-router-dom'\nimport { addressToExWalletMapFn, exWalletToAddressMapFn } from '@loopring-web/core'\nimport { useContacts, useTokenPrices } from '../../stores'\nimport Web3 from 'web3'\nimport Decimal from 'decimal.js'\nimport { ethers } from 'ethers'\n\nexport const useNFTWithdraw = <R extends TradeNFT<any, any>, T>() => {\n  const {\n    modals: {\n      isShowNFTDetail,\n      isShowNFTWithdraw: { isShow, info, address: contactAddress },\n    },\n    setShowNFTWithdraw,\n    setShowNFTDetail,\n    setShowAccount,\n    setShowEditContact,\n  } = useOpenModals()\n  const {\n    updateContacts,\n    contacts,\n    errorMessage: contactsErrorMessage,\n    status: contactStatus,\n  } = useContacts()\n\n  const { tokenMap, totalCoinMap, disableWithdrawList } = useTokenMap()\n  const { account } = useAccount()\n  const { exchangeInfo, chainId, baseURL } = useSystem()\n  const { page, updateWalletLayer2NFT } = useWalletLayer2NFT()\n  const history = useHistory()\n  const { search, pathname } = useLocation()\n  const searchParams = new URLSearchParams(search)\n\n  const { nftWithdrawValue, updateNFTTransferData, updateNFTWithdrawData, resetNFTWithdrawData } =\n    useModalData()\n  const {\n    chargeFeeTokenList,\n    isFeeNotEnough,\n    handleFeeChange,\n    feeInfo,\n    resetIntervalTime,\n    checkFeeIsEnough,\n  } = useChargeFees({\n    requestType: sdk.OffchainNFTFeeReqType.NFT_WITHDRAWAL,\n    tokenAddress: nftWithdrawValue.tokenAddress,\n    deployInWithdraw:\n      nftWithdrawValue.isCounterFactualNFT && nftWithdrawValue.deploymentStatus === 'NOT_DEPLOYED',\n    updateData: ({ fee }) => {\n      const nftWithdrawValue = store.getState()._router_modalData.nftWithdrawValue\n      updateNFTWithdrawData({\n        ...nftWithdrawValue,\n        balance: sdk\n          .toBig(nftWithdrawValue.total ?? 0)\n          .minus(nftWithdrawValue.locked ?? 0)\n          .toNumber(),\n        fee,\n      })\n    },\n  })\n\n  const { checkHWAddr, updateHW } = useWalletInfo()\n  const [sureIsAllowAddress, setSureIsAllowAddress] = React.useState<\n    EXCHANGE_TYPE | WALLET_TYPE | undefined\n  >(undefined)\n  const [lastRequest, setLastRequest] = React.useState<any>({})\n\n  const {\n    address,\n    realAddr,\n    setAddress,\n    addrStatus,\n    isCFAddress,\n    isContract1XAddress,\n    isAddressCheckLoading,\n    loopringSmartWalletVersion,\n    reCheck,\n    isENSWrong,\n    ens,\n  } = useAddressCheck()\n\n  React.useEffect(() => {\n    if (loopringSmartWalletVersion?.isLoopringSmartWallet && sureIsAllowAddress === undefined) {\n      setSureIsAllowAddress(WALLET_TYPE.Loopring)\n    }\n  }, [loopringSmartWalletVersion?.isLoopringSmartWallet])\n\n  const isNotAvailableAddress = isContract1XAddress ? 'isContract1XAddress' : undefined\n  const { btnStatus, enableBtn, disableBtn } = useBtnStatus()\n\n  const checkBtnStatus = React.useCallback(() => {\n    const contact = contacts?.find((x) => x.contactAddress === realAddr)\n    const ensHasCheck = (contact?.ens || ens) \n        ? !isENSWrong \n        : true\n    if (\n      tokenMap &&\n      nftWithdrawValue?.fee?.belong &&\n      nftWithdrawValue.fee?.feeRaw &&\n      nftWithdrawValue?.tradeValue &&\n      sdk.toBig(nftWithdrawValue.tradeValue).gt(BIGO) &&\n      sdk.toBig(nftWithdrawValue.tradeValue).lte(Number(nftWithdrawValue.balance) ?? 0) &&\n      (addrStatus as AddressError) === AddressError.NoError &&\n      !isFeeNotEnough.isFeeNotEnough &&\n      !isNotAvailableAddress &&\n      ensHasCheck &&\n      (info?.isToMyself || sureIsAllowAddress) &&\n      realAddr\n    ) {\n      enableBtn()\n      myLog('enableBtn')\n      return\n    }\n    disableBtn()\n  }, [\n    contacts,\n    tokenMap,\n    nftWithdrawValue.fee?.belong,\n    nftWithdrawValue.fee?.feeRaw,\n    nftWithdrawValue.tradeValue,\n    nftWithdrawValue.balance,\n    addrStatus,\n    isFeeNotEnough,\n    isNotAvailableAddress,\n    info?.isToMyself,\n    sureIsAllowAddress,\n    realAddr,\n    disableBtn,\n    enableBtn,\n  ])\n\n  React.useEffect(() => {\n    checkBtnStatus()\n  }, [\n    address,\n    addrStatus,\n    isFeeNotEnough.isFeeNotEnough,\n    nftWithdrawValue.fee,\n    nftWithdrawValue.tradeValue,\n    isNotAvailableAddress,\n    sureIsAllowAddress,\n  ])\n\n  const walletLayer2Callback = React.useCallback(() => {\n    checkFeeIsEnough()\n  }, [])\n  useWalletLayer2WithNFTSocket({ walletLayer2Callback })\n  const resetDefault = React.useCallback(() => {\n    if (info?.isRetry) {\n      checkFeeIsEnough()\n      return\n    }\n    if (contactsErrorMessage) {\n      updateContacts()\n    }\n    checkFeeIsEnough({ isRequiredAPI: true, intervalTime: LIVE_FEE_TIMES })\n    if (nftWithdrawValue.nftData) {\n      updateNFTWithdrawData({\n        // ...nftWithdrawValue,\n        balance: sdk\n          .toBig(nftWithdrawValue.total ?? 0)\n          .minus(nftWithdrawValue.locked ?? 0)\n          .toNumber(),\n        belong: nftWithdrawValue.name,\n        tradeValue: undefined,\n        fee: feeInfo,\n        address: info?.isToMyself ? account.accAddress : '*',\n      })\n    } else {\n      updateNFTWithdrawData({\n        fee: feeInfo,\n        belong: '',\n        balance: 0,\n        tradeValue: undefined,\n        address: info?.isToMyself ? account.accAddress : '*',\n      })\n    }\n    if (info?.isToMyself) {\n      setAddress(account.accAddress)\n    } else if (contactAddress) {\n      setAddress(contactAddress)\n    } else {\n      setAddress('')\n    }\n  }, [\n    checkFeeIsEnough,\n    nftWithdrawValue,\n    info?.isRetry,\n    info?.isToMyself,\n    updateNFTWithdrawData,\n    feeInfo,\n    account.accAddress,\n    setAddress,\n    contactAddress,\n    contactsErrorMessage,\n  ])\n\n  React.useEffect(() => {\n    if (isShow || info?.isShowLocal) {\n      resetDefault()\n    } else {\n      resetIntervalTime()\n    }\n    return () => {\n      resetIntervalTime()\n    }\n  }, [isShow, info?.isShowLocal])\n\n  const processRequest = React.useCallback(\n    async (request: sdk.NFTWithdrawRequestV3, isNotHardwareWallet: boolean) => {\n      const { apiKey, connectName, eddsaKey } = account\n\n      try {\n        if (connectProvides.usedWeb3 && LoopringAPI.userAPI && isAccActivated()) {\n          let isHWAddr = checkHWAddr(account.accAddress)\n\n          if (!isHWAddr && !isNotHardwareWallet) {\n            isHWAddr = true\n          }\n\n          myLog('nftWithdraw processRequest:', isHWAddr, isNotHardwareWallet)\n          const response = await LoopringAPI.userAPI.submitNFTWithdraw(\n            {\n              request,\n              web3: connectProvides.usedWeb3 as unknown as Web3,\n              chainId: chainId === 'unknown' ? 1 : chainId,\n              walletType: (ConnectProviders[connectName] ??\n                connectName) as unknown as sdk.ConnectorNames,\n              eddsaKey: eddsaKey.sk,\n              apiKey,\n              isHWAddr,\n            },\n            {\n              accountId: account.accountId,\n              counterFactualInfo: eddsaKey.counterFactualInfo,\n            },\n          )\n          myLog('submitNFTWithdraw:', response)\n\n          if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n            throw response\n          }\n          setShowNFTWithdraw({ isShow: false })\n\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.NFTWithdraw_In_Progress,\n          })\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.NFTWithdraw_Success,\n            info: {\n              symbol: nftWithdrawValue.name,\n              hash:\n                Explorer +\n                `tx/${(response as sdk.TX_HASH_API)?.hash}-nftWithdraw${account.accountId}-${\n                  request.token.tokenId\n                }-${request.storageId}`,\n            },\n          })\n          if (isHWAddr) {\n            myLog('......try to set isHWAddr', isHWAddr)\n            updateHW({ wallet: account.accAddress, isHWAddr })\n          }\n\n          setShowNFTDetail({\n            ...isShowNFTDetail,\n            deploymentStatus:\n              isShowNFTDetail.deploymentStatus === sdk.DEPLOYMENT_STATUS.NOT_DEPLOYED\n                ? sdk.DEPLOYMENT_STATUS.DEPLOYING\n                : isShowNFTDetail.deploymentStatus,\n            locked: (\n              Number(isShowNFTDetail?.locked ?? 0) + Number(request?.token?.amount)\n            ).toString(),\n          })\n          updateNFTWithdrawData({\n            ...isShowNFTDetail,\n            deploymentStatus:\n              isShowNFTDetail.deploymentStatus === sdk.DEPLOYMENT_STATUS.NOT_DEPLOYED\n                ? sdk.DEPLOYMENT_STATUS.DEPLOYING\n                : isShowNFTDetail.deploymentStatus,\n\n            locked: (\n              Number(isShowNFTDetail?.locked ?? 0) + Number(request?.token?.amount)\n            ).toString(),\n          })\n          updateNFTTransferData({\n            ...isShowNFTDetail,\n            deploymentStatus:\n              isShowNFTDetail.deploymentStatus === sdk.DEPLOYMENT_STATUS.NOT_DEPLOYED\n                ? sdk.DEPLOYMENT_STATUS.DEPLOYING\n                : isShowNFTDetail.deploymentStatus,\n            locked: (\n              Number(isShowNFTDetail?.locked ?? 0) + Number(request?.token?.amount)\n            ).toString(),\n          })\n          walletLayer2Service.sendUserUpdate()\n          await sdk.sleep(SUBMIT_PANEL_AUTO_CLOSE)\n          if (\n            store.getState().modals.isShowAccount.isShow &&\n            store.getState().modals.isShowAccount.step == AccountStep.NFTWithdraw_Success\n          ) {\n            setShowAccount({ isShow: false })\n            searchParams.delete('detail')\n            history.push(pathname + '?' + searchParams.toString())\n          }\n        }\n      } catch (e: any) {\n        const code = sdk.checkErrorInfo(e, isNotHardwareWallet)\n        switch (code) {\n          case sdk.ConnectorError.NOT_SUPPORT_ERROR:\n            setLastRequest({ request })\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.NFTWithdraw_First_Method_Denied,\n              info: {\n                symbol: nftWithdrawValue.name,\n              },\n            })\n            break\n          case sdk.ConnectorError.USER_DENIED:\n          case sdk.ConnectorError.USER_DENIED_2:\n            setLastRequest({ request })\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.NFTWithdraw_User_Denied,\n              info: {\n                symbol: nftWithdrawValue.name,\n              },\n            })\n            break\n          default:\n            if ([102024, 102025, 114001, 114002].includes((e as sdk.RESULT_INFO)?.code || 0)) {\n              checkFeeIsEnough({ isRequiredAPI: true })\n            }\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.NFTWithdraw_Failed,\n              info: {\n                symbol: nftWithdrawValue.name,\n              },\n              error: {\n                code: UIERROR_CODE.UNKNOWN,\n                msg: e?.message,\n                ...(e instanceof Error\n                  ? {\n                      message: e?.message,\n                      stack: e?.stack,\n                    }\n                  : e ?? {}),\n              },\n            })\n            break\n        }\n      }\n    },\n    [\n      account,\n      checkHWAddr,\n      chainId,\n      setShowAccount,\n      nftWithdrawValue.name,\n      checkFeeIsEnough,\n      updateWalletLayer2NFT,\n      page,\n      setShowNFTDetail,\n      resetNFTWithdrawData,\n      updateHW,\n    ],\n  )\n\n  const handleNFTWithdraw = React.useCallback(\n    async (_nftWithdrawToken: any, address, isFirstTime: boolean = true) => {\n      const { accountId, accAddress, readyState, apiKey, eddsaKey } = account\n      const nftWithdrawToken = {\n        ...store.getState()._router_modalData.nftWithdrawValue,\n        ..._nftWithdrawToken,\n      }\n      if (\n        readyState === AccountStatus.ACTIVATED &&\n        tokenMap &&\n        exchangeInfo &&\n        connectProvides.usedWeb3 &&\n        address &&\n        LoopringAPI.userAPI &&\n        nftWithdrawValue.fee?.belong &&\n        nftWithdrawValue?.fee?.feeRaw &&\n        eddsaKey?.sk\n      ) {\n        try {\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.NFTWithdraw_WaitForAuth,\n          })\n\n          const feeToken = tokenMap[nftWithdrawValue.fee.belong]\n          const feeRaw = nftWithdrawValue.fee.feeRaw ?? nftWithdrawValue.fee.__raw__?.feeRaw ?? 0\n          const fee = sdk.toBig(feeRaw)\n          // const fee = sdk.toBig(nftWithdrawValue.fee.__raw__?.feeRaw ?? 0);\n          const tradeValue = nftWithdrawToken.tradeValue\n\n          const storageId = await LoopringAPI.userAPI.getNextStorageId(\n            {\n              accountId: accountId,\n              sellTokenId: nftWithdrawToken.tokenId,\n            },\n            apiKey,\n          )\n\n          const request: sdk.NFTWithdrawRequestV3 = {\n            exchange: exchangeInfo.exchangeAddress,\n            owner: accAddress,\n            to: address,\n            accountId: account.accountId,\n            storageId: storageId?.offchainId,\n            token: {\n              tokenId: nftWithdrawToken.tokenId,\n              nftData: nftWithdrawToken.nftData,\n              amount: tradeValue.toString(),\n            },\n            maxFee: {\n              tokenId: feeToken.tokenId,\n              amount: fee.toString(), // TEST: fee.toString(),\n            },\n            // fastWithdrawalMode: nftWithdrawType2 === WithdrawType.Fast,\n            extraData: '',\n            minGas: 0,\n            validUntil: getTimestampDaysLater(DAYS),\n          }\n\n          myLog('submitNFTWithdraw:', request)\n\n          processRequest(request, isFirstTime)\n        } catch (e: any) {\n          sdk.dumpError400(e)\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.NFTWithdraw_Failed,\n            error: {\n              code: UIERROR_CODE.UNKNOWN,\n              msg: e?.message,\n            },\n          })\n        }\n\n        return true\n      } else {\n        return false\n      }\n    },\n    [\n      account,\n      tokenMap,\n      exchangeInfo,\n      nftWithdrawValue.fee?.belong,\n      nftWithdrawValue.fee?.__raw__,\n      nftWithdrawValue.fee?.feeRaw,\n      setShowAccount,\n      processRequest,\n    ],\n  )\n\n  const retryBtn = React.useCallback(\n    (isHardwareRetry: boolean = false) => {\n      setShowAccount({\n        isShow: true,\n        step: AccountStep.NFTWithdraw_WaitForAuth,\n      })\n      processRequest(lastRequest, !isHardwareRetry)\n    },\n    [lastRequest, processRequest, setShowAccount],\n  )\n  React.useEffect(() => {\n    const { contacts } = store.getState().contacts\n    const contact = contacts?.find(\n      (x) => x.contactAddress?.toLowerCase() === realAddr?.toLowerCase(),\n    )\n    if (!isShow) {\n      setSureIsAllowAddress(undefined)\n    } else if (contact?.addressType !== undefined) {\n      const found = contact.addressType ? addressToExWalletMapFn(contact.addressType) : undefined\n      setSureIsAllowAddress(found)\n    }\n    if (\n      isShow &&\n      contactStatus == SagaStatus.UNSET &&\n      contact &&\n      realAddr?.toLowerCase() == contact?.contactAddress?.toLowerCase()\n    ) {\n      reCheck()\n    }\n  }, [realAddr, isShow, contacts])\n  const { tokenPrices } = useTokenPrices()\n  const { getValueInCurrency } = useSystem()\n  const { currency } = useSettings()\n  const feeTokenInfo = tokenMap ? tokenMap[feeInfo.belong] : undefined\n  const feeNormalInCurrency = tryFn(() => {\n    return feeTokenInfo && feeInfo.feeRaw && tokenPrices && fiatNumberDisplaySafe(\n      getValueInCurrency(\n        new Decimal(ethers.utils.formatUnits(feeInfo.feeRaw, feeTokenInfo.decimals))\n          .mul(tokenPrices[feeTokenInfo.symbol])\n          .toFixed(2),\n      ),\n      currency,\n    )\n  }, () => undefined)\n\n  const nftWithdrawProps: WithdrawProps<any, any> = {\n    handleOnAddressChange: (value: any) => {\n      setAddress(value)\n    },\n    sureIsAllowAddress,\n    handleSureIsAllowAddress: (value) => {\n      const found = exWalletToAddressMapFn(value)\n      // const found = map.find(x => x[0] === value)![1]\n      const contact = contacts?.find((x) => x.contactAddress === realAddr)\n      if (!account?.isContractAddress && contact) {\n        LoopringAPI.contactAPI\n          ?.updateContact(\n            {\n              ...contact,\n              isHebao: !!(account.isContractAddress || account.isCFAddress),\n              accountId: account.accountId,\n              addressType: found,\n            },\n            account.apiKey,\n          )\n          .then(() => {\n            updateContacts()\n          })\n      }\n      setSureIsAllowAddress(value)\n    },\n    type: TRADE_TYPE.NFT,\n    addressDefault: address,\n    accAddr: account.accAddress,\n    isNotAvailableAddress,\n    realAddr,\n    isToMyself: info?.isToMyself,\n    disableWithdrawList,\n    tradeData: nftWithdrawValue as any,\n    coinMap: totalCoinMap as CoinMap<T>,\n    walletMap: {},\n    isCFAddress,\n    getIPFSString,\n    baseURL,\n    lastFailed: store.getState().modals.isShowAccount.info?.lastFailed === LAST_STEP.nftWithdraw,\n    isContractAddress: isContract1XAddress,\n    isAddressCheckLoading,\n    addrStatus,\n    withdrawBtnStatus: btnStatus,\n    withdrawType: sdk.OffchainNFTFeeReqType.NFT_WITHDRAWAL,\n    withdrawTypes: {\n      [sdk.OffchainNFTFeeReqType.NFT_WITHDRAWAL]: 'Standard',\n    } as any,\n    onWithdrawClick: (tradeData: R) => {\n      if (nftWithdrawValue && nftWithdrawValue.tradeValue) {\n        handleNFTWithdraw(tradeData, realAddr ? realAddr : address)\n      }\n    },\n    handleWithdrawTypeChange: () => {},\n    handlePanelEvent: async (data: SwitchData<R>) => {\n      return new Promise((res: any) => {\n        if (data.to === 'button') {\n          if (data.tradeData.belong) {\n            updateNFTWithdrawData({\n              belong: data.tradeData.belong,\n              tradeValue: data.tradeData?.tradeValue,\n              balance: data.tradeData.balance,\n              address: info?.isToMyself ? account.accAddress : '*',\n            })\n          } else {\n            updateNFTWithdrawData({\n              belong: undefined,\n              tradeValue: undefined,\n              balance: undefined,\n              address: info?.isToMyself ? account.accAddress : '*',\n            })\n          }\n        }\n\n        res()\n      })\n    },\n    handleFeeChange,\n    feeInfo,\n    chargeFeeTokenList,\n    isFeeNotEnough,\n    isLoopringAddress: true,\n    contacts,\n    loopringSmartWalletVersion,\n    isENSWrong,\n    geUpdateContact: () => {\n      if (isENSWrong) {\n        const contact = contacts?.find((x) => x.contactAddress === realAddr)\n        setShowEditContact({\n          isShow: true,\n          info: {\n            ...contact,\n            isENSWrong,\n          },\n        })\n      }\n    },\n    ens,\n    withdrawMode: {\n      mode: 'normal',\n      showFastMode: false,\n      fastMode: undefined,\n      fastMaxAlert: {\n        show: false,\n        message: '',\n      },\n      normalMode: {\n        fee: feeNormalInCurrency ? '~' + feeNormalInCurrency : '--',\n        time: '~25 minutes',\n      },\n      onChange: () => {},\n      showTrustUI: false\n    },\n  } as unknown as WithdrawProps<any, any>\n  return {\n    nftWithdrawProps,\n    retryBtn,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/useRampConfirm.ts",
    "content": "import {\n  AccountStatus,\n  AddressError,\n  CoinMap,\n  Explorer,\n  FeeInfo,\n  IBData,\n  myLog,\n  TOAST_TIME,\n  TRADE_TYPE,\n  UIERROR_CODE,\n  WALLET_TYPE,\n  WalletMap,\n} from '@loopring-web/common-resources'\nimport { NETWORKEXTEND, useAccount, useModalData, useSystem, useTokenMap } from '../../stores'\nimport { AccountStep, useOpenModals } from '@loopring-web/component-lib'\nimport React from 'react'\nimport { makeWalletLayer2 } from '../help'\nimport { useChargeFees, useWalletLayer2Socket, walletLayer2Service } from '../../services'\nimport { useBtnStatus } from '../common'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { LoopringAPI } from '../../api_wrapper'\nimport { ConnectProviders, connectProvides } from '@loopring-web/web3-provider'\nimport { getTimestampDaysLater } from '../../utils'\nimport { DAYS } from '../../defs'\nimport { RAMP_SELL_PANEL } from './useVendor'\nimport { useWalletInfo } from '../../stores/localStore/walletInfo'\nimport Web3 from 'web3'\nimport { isAccActivated } from './useCheckAccStatus'\n\nexport const useRampConfirm = <T extends IBData<I>, I, _C extends FeeInfo>({\n  sellPanel,\n  setSellPanel,\n}: {\n  sellPanel: RAMP_SELL_PANEL\n  setSellPanel: (value: RAMP_SELL_PANEL) => void\n}) => {\n  const { exchangeInfo } = useSystem()\n\n  const {\n    allowTrade: { raw_data },\n  } = useSystem()\n  const legalEnable = (raw_data as any)?.legal?.enable\n  const { tokenMap, totalCoinMap } = useTokenMap()\n  const {\n    setShowAccount,\n    modals: {\n      isShowAccount: { info },\n    },\n  } = useOpenModals()\n  const { account } = useAccount()\n  const [balanceNotEnough, setBalanceNotEnough] = React.useState(false)\n  const { offRampValue } = useModalData()\n  const {\n    processRequestRampTransfer: processRequest,\n    chargeFeeTokenList,\n    isFeeNotEnough,\n    handleFeeChange,\n    feeInfo,\n    checkFeeIsEnough,\n  } = useRampTransPost()\n  const [walletMap, setWalletMap] = React.useState(\n    makeWalletLayer2({ needFilterZero: true }).walletMap ?? ({} as WalletMap<T>),\n  )\n  const walletLayer2Callback = React.useCallback(() => {\n    const walletMap = makeWalletLayer2({ needFilterZero: true }).walletMap ?? {}\n    setWalletMap(walletMap)\n  }, [])\n\n  useWalletLayer2Socket({ walletLayer2Callback })\n\n  const { btnStatus, enableBtn, disableBtn } = useBtnStatus()\n  const { transferRampValue, updateTransferRampData, resetOffRampData } = useModalData()\n\n  React.useEffect(() => {\n    if (\n      info?.transferRamp === AccountStep.Transfer_RAMP_Failed &&\n      info?.trigger == 'checkFeeIsEnough'\n    ) {\n      checkFeeIsEnough()\n    }\n  }, [info?.transferRamp])\n\n  const checkBtnStatus = React.useCallback(() => {\n    if (\n      tokenMap &&\n      chargeFeeTokenList.length &&\n      !isFeeNotEnough.isFeeNotEnough &&\n      transferRampValue.belong &&\n      tokenMap[transferRampValue.belong] &&\n      transferRampValue.fee &&\n      transferRampValue.fee.belong &&\n      transferRampValue.address\n    ) {\n      const sellToken = tokenMap[transferRampValue.belong]\n      const feeToken = tokenMap[transferRampValue.fee.belong]\n      const feeRaw = transferRampValue.fee.feeRaw ?? transferRampValue.fee.__raw__?.feeRaw ?? 0\n      const fee = sdk.toBig(feeRaw)\n      const balance = sdk.toBig(transferRampValue.balance ?? 0).times('1e' + sellToken.decimals)\n      const tradeValue = sdk\n        .toBig(transferRampValue.tradeValue ?? 0)\n        .times('1e' + sellToken.decimals)\n      const isExceedBalance = tradeValue\n        .plus(feeToken.tokenId === sellToken.tokenId ? fee : '0')\n        .gt(balance)\n      myLog('isExceedBalance', isExceedBalance, fee.toString(), tradeValue.toString())\n      if (tradeValue && !isExceedBalance) {\n        enableBtn()\n        return\n      } else {\n        disableBtn()\n        // if (isExceedBalance && feeToken.tokenId === sellToken.tokenId) {\n        //   // setIsFeeEnough(isFeeNotEnoughtrue);\n        //   // setIsFeeNotEnough({\n        //   //   isFeeNotEnough: true,\n        //   //   isOnLoading: false,\n        //   // });\n        //   setBalanceNotEnough(true);\n        // } else\n        if (isExceedBalance) {\n          setBalanceNotEnough(true)\n        }\n        // else {\n        //\n        // }\n      }\n    }\n    disableBtn()\n  }, [\n    chargeFeeTokenList.length,\n    disableBtn,\n    enableBtn,\n    isFeeNotEnough.isFeeNotEnough,\n    tokenMap,\n    transferRampValue.address,\n    transferRampValue.balance,\n    transferRampValue.belong,\n    transferRampValue.fee,\n    transferRampValue.tradeValue,\n  ])\n\n  React.useEffect(() => {\n    checkBtnStatus()\n  }, [chargeFeeTokenList, isFeeNotEnough.isFeeNotEnough, transferRampValue])\n\n  const onTransferClick = React.useCallback(\n    async (transferRampValue, isFirstTime: boolean = true) => {\n      const { accountId, accAddress, readyState, apiKey, eddsaKey } = account\n\n      if (\n        readyState === AccountStatus.ACTIVATED &&\n        tokenMap &&\n        LoopringAPI.userAPI &&\n        exchangeInfo &&\n        connectProvides.usedWeb3 &&\n        transferRampValue.address !== '*' &&\n        transferRampValue?.fee &&\n        transferRampValue?.fee.belong &&\n        transferRampValue.fee?.__raw__ &&\n        eddsaKey?.sk\n      ) {\n        try {\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.Transfer_RAMP_WaitForAuth,\n          })\n\n          const sellToken = tokenMap[transferRampValue.belong as string]\n          const feeToken = tokenMap[transferRampValue.fee.belong]\n          const feeRaw = transferRampValue.fee.feeRaw ?? transferRampValue.fee.__raw__?.feeRaw ?? 0\n          const fee = sdk.toBig(feeRaw)\n          // const balance = sdk\n          //   .toBig(transferRampValue.balance ?? 0)\n          //   .times(\"1e\" + sellToken.decimals);\n          const tradeValue = sdk\n            .toBig(transferRampValue.tradeValue ?? 0)\n            .times('1e' + sellToken.decimals)\n          // const isExceedBalance =\n          //   feeToken.tokenId === sellToken.tokenId &&\n          //   tradeValue.plus(fee).gt(balance);\n          const finalVol = tradeValue\n          const transferVol = finalVol.toFixed(0, 0)\n\n          const storageId = await LoopringAPI.userAPI?.getNextStorageId(\n            {\n              accountId,\n              sellTokenId: sellToken.tokenId,\n            },\n            apiKey,\n          )\n          const req: sdk.OriginTransferRequestV3 = {\n            exchange: exchangeInfo.exchangeAddress,\n            payerAddr: accAddress,\n            payerId: accountId,\n            payeeAddr: transferRampValue.address,\n            payeeId: 0,\n            storageId: storageId?.offchainId,\n            token: {\n              tokenId: sellToken.tokenId,\n              volume: transferVol,\n            },\n            maxFee: {\n              tokenId: feeToken.tokenId,\n              volume: fee.toString(), // TEST: fee.toString(),\n            },\n            validUntil: getTimestampDaysLater(DAYS),\n            memo: transferRampValue.memo,\n          }\n\n          myLog('transfer req:', req)\n\n          processRequest(req, isFirstTime)\n        } catch (e: any) {\n          // transfer failed\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.Transfer_RAMP_Failed,\n            error: {\n              code: UIERROR_CODE.UNKNOWN,\n              message: e.message,\n            } as sdk.RESULT_INFO,\n          })\n        }\n      } else {\n        return\n      }\n    },\n    [account, tokenMap, exchangeInfo, setShowAccount, processRequest],\n  )\n\n  // const [rampViewProps, setRampViewProps] =\n  //   React.useState<RampViewProps<T, I, C> | undefined>(undefined);\n\n  const initRampViewProps = React.useCallback(() => {\n    if (offRampValue?.send && window.rampInstance) {\n      const { amount, assetSymbol, destinationAddress } = offRampValue?.send\n\n      const memo = 'OFF-RAMP Transfer'\n      updateTransferRampData({\n        belong: assetSymbol,\n        tradeValue: Number(amount),\n        balance: walletMap[assetSymbol]?.count,\n        fee: feeInfo,\n        memo,\n        address: destinationAddress as string,\n      })\n      return\n    }\n    if (window.rampInstance) {\n      window.rampInstance.close()\n    } else {\n      // setSellPanel(RAMP_SELL_PANEL.LIST);\n      resetOffRampData()\n    }\n  }, [\n    btnStatus,\n    chargeFeeTokenList,\n    feeInfo,\n    handleFeeChange,\n    isFeeNotEnough,\n    legalEnable,\n    onTransferClick,\n    setSellPanel,\n    totalCoinMap,\n    updateTransferRampData,\n  ])\n  React.useEffect(() => {\n    if (sellPanel === RAMP_SELL_PANEL.RAMP_CONFIRM) {\n      initRampViewProps()\n    } else {\n    }\n  }, [sellPanel])\n\n  const rampViewProps = React.useMemo(() => {\n    const { address, memo, fee, __request__, ...tradeData } = transferRampValue\n    return {\n      type: TRADE_TYPE.TOKEN,\n      disabled: !(legalEnable === true),\n      addressDefault: address,\n      realAddr: address,\n      tradeData,\n      coinMap: totalCoinMap as CoinMap<T>,\n      transferBtnStatus: btnStatus,\n      isLoopringAddress: true,\n      isSameAddress: false,\n      isAddressCheckLoading: WALLET_TYPE.Loopring,\n      feeInfo,\n      handleFeeChange,\n      balanceNotEnough,\n      chargeFeeTokenList,\n      isFeeNotEnough,\n      handleSureItsLayer2: () => undefined,\n      sureItsLayer2: true,\n      onTransferClick,\n      handlePanelEvent: () => undefined,\n      addrStatus: AddressError.NoError,\n      memo,\n      walletMap,\n      handleOnMemoChange: () => undefined,\n      handleOnAddressChange: () => undefined,\n    } as any\n  }, [\n    balanceNotEnough,\n    btnStatus,\n    chargeFeeTokenList,\n    feeInfo,\n    handleFeeChange,\n    isFeeNotEnough,\n    legalEnable,\n    onTransferClick,\n    totalCoinMap,\n    transferRampValue,\n    walletMap,\n  ])\n\n  return { rampViewProps }\n}\nexport const useRampTransPost = () => {\n  const { account } = useAccount()\n  const { chainId } = useSystem()\n  const { checkHWAddr, updateHW } = useWalletInfo()\n  const { setShowAccount } = useOpenModals()\n  const { updateTransferRampData, resetTransferRampData } = useModalData()\n  const {\n    chargeFeeTokenList,\n    isFeeNotEnough,\n    handleFeeChange,\n    feeInfo,\n    checkFeeIsEnough,\n    // setIsFeeNotEnough,\n  } = useChargeFees({\n    requestType: sdk.OffchainFeeReqType.TRANSFER,\n    // updateData: ({ fee }) => {},\n  })\n  const processRequestRampTransfer = React.useCallback(\n    async (request: sdk.OriginTransferRequestV3, isNotHardwareWallet: boolean) => {\n      const { apiKey, connectName, eddsaKey } = account\n\n      try {\n        if (\n          connectProvides.usedWeb3 &&\n          LoopringAPI.userAPI &&\n          window.rampInstance &&\n          isAccActivated()\n        ) {\n          let isHWAddr = checkHWAddr(account.accAddress)\n          if (!isHWAddr && !isNotHardwareWallet) {\n            isHWAddr = true\n          }\n          updateTransferRampData({ __request__: request })\n          const response = await LoopringAPI.userAPI.submitInternalTransfer(\n            {\n              request,\n              web3: connectProvides.usedWeb3 as unknown as Web3,\n              chainId: chainId === NETWORKEXTEND.NONETWORK ? sdk.ChainId.MAINNET : chainId,\n              walletType: (ConnectProviders[connectName] ??\n                connectName) as unknown as sdk.ConnectorNames,\n              eddsaKey: eddsaKey.sk,\n              apiKey,\n              isHWAddr,\n            },\n            {\n              accountId: account.accountId,\n              counterFactualInfo: eddsaKey.counterFactualInfo,\n            },\n          )\n\n          myLog('submitInternalTransfer:', response)\n          if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n            throw response\n          }\n          // setIsConfirmTransfer(false);\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.Transfer_RAMP_In_Progress,\n          })\n          await sdk.sleep(TOAST_TIME)\n\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.Transfer_RAMP_Success,\n            info: {\n              hash: Explorer + `tx/${(response as sdk.TX_HASH_API)?.hash}-transfer`,\n            },\n          })\n          if (window.rampInstance) {\n            try {\n              console.log('RAMP WEIGHT display on transfer done')\n              // @ts-ignore\n              window.rampInstance.domNodes.overlay.style.display = ''\n            } catch (e) {\n              console.log('RAMP WEIGHT hidden failed')\n            }\n          }\n          if (isHWAddr) {\n            myLog('......try to set isHWAddr', isHWAddr)\n            updateHW({ wallet: account.accAddress, isHWAddr })\n          }\n          walletLayer2Service.sendUserUpdate()\n          resetTransferRampData()\n        }\n      } catch (e: any) {\n        const code = sdk.checkErrorInfo(e, isNotHardwareWallet)\n        switch (code) {\n          case sdk.ConnectorError.NOT_SUPPORT_ERROR:\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.Transfer_RAMP_First_Method_Denied,\n            })\n            break\n          case sdk.ConnectorError.USER_DENIED:\n          case sdk.ConnectorError.USER_DENIED_2:\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.Transfer_RAMP_User_Denied,\n            })\n            break\n          default:\n            if ([102024, 102025, 114001, 114002].includes((e as sdk.RESULT_INFO)?.code || 0)) {\n              checkFeeIsEnough({ isRequiredAPI: true })\n            }\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.Transfer_RAMP_Failed,\n              error: {\n                code: UIERROR_CODE.UNKNOWN,\n                msg: e?.message,\n                ...(e instanceof Error\n                  ? {\n                      message: e?.message,\n                      stack: e?.stack,\n                    }\n                  : e ?? {}),\n              },\n            })\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.Transfer_Failed,\n            })\n\n            break\n        }\n      }\n    },\n    [\n      account,\n      chainId,\n      checkHWAddr,\n      resetTransferRampData,\n      setShowAccount,\n      updateHW,\n      updateTransferRampData,\n    ],\n  )\n  return {\n    processRequestRampTransfer,\n    chargeFeeTokenList,\n    isFeeNotEnough,\n    handleFeeChange,\n    feeInfo,\n    checkFeeIsEnough,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/useRedpacket.ts",
    "content": "import React from 'react'\nimport { LoopringAPI } from '../../api_wrapper'\nimport { AccountStep, RedPacketViewStep, useOpenModals } from '@loopring-web/component-lib'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { LuckyTokenItemStatus } from '@loopring-web/loopring-sdk'\nimport { store, useAccount, useSystem, useTargetRedPackets } from '../../stores'\nimport { CustomError, ErrorMap, UIERROR_CODE } from '@loopring-web/common-resources'\n\n\nexport function useOpenRedpacket() {\n  const { setShowRedPacket, setShowAccount } = useOpenModals()\n  const { chainId } = useSystem()\n  const { account } = useAccount()\n  const { getExclusiveRedpacket } = useTargetRedPackets()\n\n  const callOpen = React.useCallback(async () => {\n    // setShowAccount({\n    //   isShow: true,\n    //   step: AccountStep.RedPacketOpen_Claim_In_Progress,\n    // });\n    const _info = store.getState().modals.isShowRedPacket.info as sdk.LuckyTokenItemForReceive & {\n      referrer?: string\n      isShouldSharedRely: boolean\n    }\n    \n    // let difference = new Date(_info.validSince).getTime() - Date.now();\n    if (\n      _info.status == LuckyTokenItemStatus.COMPLETED ||\n      _info.status == LuckyTokenItemStatus.OVER_DUE ||\n      _info.tokenAmount.remainCount === 0\n    ) {\n      setShowRedPacket({\n        isShow: true,\n        step: RedPacketViewStep.TimeOutPanel,\n        info: {\n          ..._info,\n        },\n      })\n    } else {\n      try {\n        if (_info.type.mode === sdk.LuckyTokenClaimType.BLIND_BOX) {\n          let response = await LoopringAPI.luckTokenAPI?.sendLuckTokenClaimBlindBox({\n            request: {\n              hash: _info?.hash,\n              claimer: account.accAddress,\n              referrer: _info.isShouldSharedRely && _info?.referrer ? _info?.referrer : '',\n              serialNo: _info.serialNo\n            },\n            eddsaKey: account.eddsaKey.sk,\n            apiKey: account.apiKey,\n          } as any)\n          if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n            throw response\n          }\n          // setShowAccount({\n          //   isShow: false,\n          // });\n          setShowRedPacket({\n            isShow: true,\n            step: RedPacketViewStep.BlindBoxDetail,\n            info: {\n              ..._info,\n            },\n          })\n        } else {\n          \n          let response = await LoopringAPI.luckTokenAPI?.sendLuckTokenClaimLuckyToken({\n            request: {\n              hash: _info?.hash,\n              claimer: account.accAddress,\n              referrer: _info.isShouldSharedRely && _info?.referrer ? _info?.referrer : '',\n              serialNo: _info.serialNo\n            },\n            eddsaKey: account.eddsaKey.sk,\n            apiKey: account.apiKey,\n          } as any)\n          if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n            throw response\n          }\n\n          // setShowAccount({\n          //   isShow: false,\n          // });\n          setShowRedPacket({\n            isShow: true,\n            step: RedPacketViewStep.DetailPanel,\n            info: {\n              ..._info,\n              response,\n              claimAmount: (response as any).amount,\n            },\n          })\n        }\n        getExclusiveRedpacket()\n      } catch (error: any) {\n        if (error?.code === UIERROR_CODE.ERROR_REDPACKET_CLAIMED) {\n          // setShowAccount({\n          //   isShow: false,\n          // });\n          if (_info.type.mode === sdk.LuckyTokenClaimType.BLIND_BOX) {\n            setShowRedPacket({\n              isShow: true,\n              step: RedPacketViewStep.BlindBoxDetail,\n              info: {\n                ..._info,\n              },\n            })\n          } else {\n            setShowRedPacket({\n              isShow: true,\n              step: RedPacketViewStep.DetailPanel,\n              info: {\n                ..._info,\n              },\n            })\n          }\n        } else if (\n          [\n            UIERROR_CODE.ERROR_REDPACKET_CLAIM_TIMEOUT,\n            UIERROR_CODE.ERROR_REDPACKET_CLAIM_OUT,\n          ].includes(error?.code)\n        ) {\n          // setShowAccount({\n          //   isShow: false,\n          // });\n          setShowRedPacket({\n            isShow: true,\n            step: RedPacketViewStep.TimeOutPanel,\n            info: {\n              ..._info,\n            },\n          })\n        } else {\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.RedPacketOpen_Failed,\n            error: {\n              code: UIERROR_CODE.UNKNOWN,\n              msg: error?.message,\n              // @ts-ignore\n              ...(error instanceof Error\n                ? {\n                    message: error?.message,\n                    stack: error?.stack,\n                  }\n                : error ?? {}),\n            },\n          })\n          // await sdk.sleep(SUBMIT_PANEL_QUICK_AUTO_CLOSE);\n          // setShowAccount({\n          //   isShow: false,\n          // });\n        }\n      }\n    }\n  }, [chainId, account])\n\n  return {\n    callOpen,\n  }\n}\n\nexport const useRedPacketScanQrcodeSuccess = () => {\n  const {\n    setShowAccount,\n    setShowRedPacket,\n    // modals: { isShowAccount },\n  } = useOpenModals()\n  const {\n    account: { apiKey, accountId },\n  } = useAccount()\n\n  const [redPacketInfo, setRedPacketInfo] = React.useState<\n    { hash: string; referrer: string } | undefined\n  >(undefined)\n  const getLuckTokenDetail = React.useCallback(async () => {\n    if (LoopringAPI.luckTokenAPI && redPacketInfo) {\n      setShowAccount({\n        isShow: true,\n        step: AccountStep.RedPacketOpen_In_Progress,\n      })\n\n      const response = await LoopringAPI.luckTokenAPI.getLuckTokenDetail(\n        {\n          accountId: accountId,\n          hash: redPacketInfo.hash,\n          fromId: 0,\n          showHelper: true,\n        } as any,\n        apiKey,\n      )\n      if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n        setShowAccount({\n          isShow: true,\n          step: AccountStep.RedPacketOpen_Failed,\n          error: {\n            code: (response as sdk.RESULT_INFO)?.code,\n            msg: (response as sdk.RESULT_INFO)?.message,\n            ...(response instanceof Error\n              ? {\n                  message: response?.message,\n                  stack: response?.stack,\n                }\n              : response ?? {}),\n          },\n        })\n      } else {\n        const detail = (response as any).detail\n        const luckTokenInfo: sdk.LuckyTokenItemForReceive = detail.luckyToken\n        let difference = new Date(luckTokenInfo.validSince).getTime() - Date.now()\n\n        if (luckTokenInfo) {\n          setShowAccount({ isShow: false })\n          if (response.detail?.claimAmount.toString() !== '0') {\n            if (response.detail?.luckyToken.type.mode === sdk.LuckyTokenClaimType.BLIND_BOX) {\n              setShowRedPacket({\n                isShow: true,\n                step: RedPacketViewStep.BlindBoxDetail,\n                info: {\n                  ...luckTokenInfo,\n                },\n              })\n            } else {\n              setShowRedPacket({\n                isShow: true,\n                step: RedPacketViewStep.DetailPanel,\n                info: {\n                  ...luckTokenInfo,\n                },\n              })\n            }\n          } else if (difference > 0) {\n            // change here\n            if (luckTokenInfo.sender.accountId === accountId) {\n              if (luckTokenInfo.type.mode === sdk.LuckyTokenClaimType.BLIND_BOX) {\n                setShowRedPacket({\n                  isShow: true,\n                  info: {\n                    ...luckTokenInfo,\n                    referrer: redPacketInfo.referrer,\n                  },\n                  step: RedPacketViewStep.BlindBoxDetail,\n                })\n              } else {\n                setShowRedPacket({\n                  isShow: true,\n                  info: {\n                    ...luckTokenInfo,\n                    referrer: redPacketInfo.referrer,\n                  },\n                  step: RedPacketViewStep.DetailPanel,\n                })\n              }\n            } else {\n              setShowRedPacket({\n                isShow: true,\n                info: {\n                  ...luckTokenInfo,\n                  referrer: redPacketInfo.referrer,\n                },\n                step: RedPacketViewStep.RedPacketClock,\n              })\n            }\n          } else if (\n            luckTokenInfo.status == LuckyTokenItemStatus.COMPLETED ||\n            luckTokenInfo.status == LuckyTokenItemStatus.OVER_DUE ||\n            // difference + 86400000 < 0 ||\n            luckTokenInfo.tokenAmount.remainCount === 0\n          ) {\n            if (luckTokenInfo.type.mode === sdk.LuckyTokenClaimType.BLIND_BOX) {\n              setShowRedPacket({\n                isShow: true,\n                info: {\n                  ...luckTokenInfo,\n                },\n                step: RedPacketViewStep.BlindBoxDetail,\n              })\n            } else {\n              setShowRedPacket({\n                isShow: true,\n                info: {\n                  ...luckTokenInfo,\n                },\n                step: RedPacketViewStep.TimeOutPanel,\n              })\n            }\n          } else {\n            const canOpenBlindbox =\n              luckTokenInfo.type.mode === sdk.LuckyTokenClaimType.BLIND_BOX &&\n              luckTokenInfo.status === sdk.LuckyTokenItemStatus.PENDING &&\n              detail.blindBoxStatus === ''\n            const canOpenLuckyToken =\n              luckTokenInfo.type.mode !== sdk.LuckyTokenClaimType.BLIND_BOX &&\n              luckTokenInfo.status === sdk.LuckyTokenItemStatus.PENDING &&\n              !detail.claimStatus\n            if (canOpenBlindbox || canOpenLuckyToken) {\n              setShowRedPacket({\n                isShow: true,\n                info: {\n                  ...luckTokenInfo,\n                  referrer: redPacketInfo.referrer,\n                  hideViewDetail: accountId !== luckTokenInfo.sender.accountId,\n                },\n                step: RedPacketViewStep.OpenPanel,\n              })\n            } else {\n              if (luckTokenInfo.type.mode === sdk.LuckyTokenClaimType.BLIND_BOX) {\n                setShowRedPacket({\n                  isShow: true,\n                  info: {\n                    ...luckTokenInfo,\n                    referrer: redPacketInfo.referrer,\n                  },\n                  step: RedPacketViewStep.BlindBoxDetail,\n                })\n              } else {\n                setShowRedPacket({\n                  isShow: true,\n                  info: {\n                    ...luckTokenInfo,\n                    referrer: redPacketInfo.referrer,\n                  },\n                  step: RedPacketViewStep.DetailPanel,\n                })\n              }\n            }\n          }\n          setShowAccount({\n            isShow: false,\n          })\n        } else {\n          const error = new CustomError(ErrorMap.ERROR_REDPACKET_EMPTY)\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.RedPacketOpen_Failed,\n            error: {\n              code: UIERROR_CODE.ERROR_REDPACKET_EMPTY,\n              msg: error.message,\n            },\n          })\n        }\n        // const luckTokenInfo: sdk.LuckyTokenItemForReceive = (response as any)\n        //   .detail.luckyToken;\n        // if (luckTokenInfo) {\n        //   setShowAccount({ isShow: false });\n        //   setShowRedPacket({\n        //     isShow: true,\n        //     info: {\n        //       ...luckTokenInfo,\n        //       referrer: redPacketInfo.referrer,\n        //     },\n        //     step: RedPacketViewStep.OpenPanel,\n        //   });\n        // } else {\n        //   const error = new CustomError(ErrorMap.ERROR_REDPACKET_EMPTY);\n        //   setShowAccount({\n        //     isShow: true,\n        //     step: AccountStep.RedPacketOpen_Failed,\n        //     error: {\n        //       code: UIERROR_CODE.ERROR_REDPACKET_EMPTY,\n        //       msg: error.message,\n        //     },\n        //   });\n        // }\n      }\n    }\n  }, [redPacketInfo, accountId])\n  React.useEffect(() => {\n    if (redPacketInfo) {\n      getLuckTokenDetail()\n    }\n  }, [redPacketInfo])\n  const handleSuccess = React.useCallback(\n    async (data: string) => {\n      const url = new URL(data)\n      const searchParams = new URLSearchParams(url.hash.replace('#/wallet', ''))\n      if (searchParams.has('redpacket') && searchParams.get('id')) {\n        setRedPacketInfo({\n          hash: searchParams.get('id')?.toString() ?? '',\n          referrer: searchParams.get('referrer')?.toString() ?? '',\n        })\n      } else {\n        setRedPacketInfo({\n          hash: '',\n          referrer: '',\n        })\n        const error = new CustomError(ErrorMap.ERROR_REDPACKET_EMPTY)\n        setShowAccount({\n          isShow: true,\n          step: AccountStep.RedPacketOpen_Failed,\n          error: {\n            code: UIERROR_CODE.ERROR_REDPACKET_EMPTY,\n            msg: error.message,\n          },\n        })\n      }\n    },\n    [apiKey],\n  )\n  return {\n    handleSuccess,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/useReset.ts",
    "content": "import React from 'react'\n\nimport { ResetProps, useOpenModals } from '@loopring-web/component-lib'\nimport { FeeInfo, LIVE_FEE_TIMES } from '@loopring-web/common-resources'\nimport { useBtnStatus, useChargeFees } from '../../index'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { useUpdateAccount } from './useUpdateAccount'\n\nexport const useReset = <T extends FeeInfo>(): {\n  resetProps: ResetProps<T>\n} => {\n  const { btnStatus, enableBtn, disableBtn } = useBtnStatus()\n  const {\n    setShowResetAccount,\n    modals: {\n      isShowResetAccount: { isShow },\n    },\n  } = useOpenModals()\n\n  const {\n    chargeFeeTokenList,\n    isFeeNotEnough,\n    handleFeeChange,\n    feeInfo,\n    checkFeeIsEnough,\n    resetIntervalTime,\n  } = useChargeFees({\n    requestType: sdk.OffchainFeeReqType.UPDATE_ACCOUNT,\n    updateData: () => {},\n  })\n  React.useEffect(() => {\n    if (isFeeNotEnough.isFeeNotEnough) {\n      disableBtn()\n    } else {\n      enableBtn()\n    }\n  }, [isFeeNotEnough.isFeeNotEnough])\n\n  React.useEffect(() => {\n    if (isShow) {\n      checkFeeIsEnough({ isRequiredAPI: true, intervalTime: LIVE_FEE_TIMES })\n      return\n    } else {\n      resetIntervalTime()\n    }\n    return () => {\n      resetIntervalTime()\n    }\n  }, [isShow])\n\n  const { goUpdateAccount } = useUpdateAccount()\n\n  const onResetClick = React.useCallback(() => {\n    setShowResetAccount({ isShow: false })\n    goUpdateAccount({ isReset: true, feeInfo: feeInfo })\n  }, [goUpdateAccount, feeInfo])\n\n  const resetProps: ResetProps<any> = {\n    isFeeNotEnough,\n    onResetClick,\n    resetBtnStatus: btnStatus,\n    feeInfo,\n    chargeFeeTokenList,\n    handleFeeChange,\n  }\n\n  return {\n    resetProps: resetProps as ResetProps<T>,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/useStakeTrade.ts",
    "content": "import React from 'react'\nimport {\n  AccountStep,\n  DeFiSideWrapProps,\n  ToastType,\n  useOpenModals,\n  useToggle,\n} from '@loopring-web/component-lib'\nimport {\n  AccountStatus,\n  CustomErrorWithCode,\n  DeFiSideCalcData,\n  getValuePrecisionThousand,\n  globalSetup,\n  IBData,\n  myLog,\n  SagaStatus,\n  SDK_ERROR_MAP_TO_UI,\n  SUBMIT_PANEL_QUICK_AUTO_CLOSE,\n  TradeBtnStatus,\n  TradeStake,\n} from '@loopring-web/common-resources'\n\nimport {\n  calcSideStaking,\n  makeWalletLayer2,\n  useStakingMap,\n  useSubmitBtn,\n  useWalletLayer2Socket,\n} from '@loopring-web/core'\nimport _ from 'lodash'\n\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nimport {\n  LoopringAPI,\n  store,\n  useAccount,\n  useSystem,\n  useTokenMap,\n  walletLayer2Service,\n} from '../../index'\nimport { useTranslation } from 'react-i18next'\nimport { useTradeStake } from '../../stores'\n\nexport const useStakeTradeJOIN = <T extends IBData<I>, I, ACD extends DeFiSideCalcData<T>>({\n  setToastOpen,\n  symbol: coinSellSymbol,\n}: {\n  symbol: string\n  setToastOpen: (props: { open: boolean; content: JSX.Element | string; type: ToastType }) => void\n}) => {\n  const { t } = useTranslation(['common'])\n  const refreshRef = React.createRef()\n  const [isLoading, setIsLoading] = React.useState(false)\n  const { tokenMap } = useTokenMap()\n  const { account } = useAccount()\n  const { setShowAccount } = useOpenModals()\n  const { status: stakingMapStatus, marketMap: stakingMap, getStakingMap } = useStakingMap()\n\n  const { setShowSupport, setShowTradeIsFrozen } = useOpenModals()\n  const { tradeStake, updateTradeStake, resetTradeStake } = useTradeStake()\n  const { exchangeInfo, allowTrade } = useSystem()\n  const { toggle } = useToggle()\n\n  const handleOnchange = _.debounce(\n    ({ tradeData, _tradeStake = {} }: { tradeData: T; _tradeStake?: Partial<TradeStake<T>> }) => {\n      const tradeStake = store.getState()._router_tradeStake.tradeStake\n      let _deFiSideCalcData: DeFiSideCalcData<T> = {\n        ...tradeStake.deFiSideCalcData,\n      } as unknown as DeFiSideCalcData<T>\n      let _oldTradeStake = {\n        ...tradeStake,\n        ..._tradeStake,\n      }\n      //_.cloneDeep({ ...tradeStake, ..._tradeStake });\n      myLog('defi handleOnchange', _oldTradeStake)\n\n      if (tradeData && coinSellSymbol) {\n        const inputValue = tradeData?.tradeValue?.toString() ?? '0'\n        const tokenSell = tokenMap[coinSellSymbol]\n        const { sellVol, deFiSideCalcData } = calcSideStaking({\n          inputValue,\n          isJoin: true,\n          deFiSideCalcData: _deFiSideCalcData,\n          tokenSell,\n        })\n\n        // @ts-ignore\n        _deFiSideCalcData = {\n          ...deFiSideCalcData,\n          coinSell: {\n            ...tradeData,\n            tradeValue: tradeData?.tradeValue?.toString(),\n          },\n        }\n        updateTradeStake({\n          sellToken: tokenSell,\n          sellVol,\n          deFiSideCalcData: {\n            ..._deFiSideCalcData,\n          },\n        })\n      }\n    },\n    globalSetup.wait,\n  )\n\n  const resetDefault = React.useCallback(\n    async (clearTrade: boolean = false) => {\n      let walletMap: any = {}\n      let deFiSideCalcDataInit: Partial<DeFiSideCalcData<any>> = {\n        ...tradeStake.deFiSideCalcData,\n        coinSell: {\n          belong: coinSellSymbol,\n          balance: undefined,\n          tradeValue:\n            tradeStake.deFiSideCalcData?.coinSell?.belong === coinSellSymbol\n              ? tradeStake.deFiSideCalcData?.coinSell?.tradeValue\n              : undefined,\n        },\n      }\n      try {\n        let item = stakingMap[coinSellSymbol]\n        if (item && stakingMap) {\n          deFiSideCalcDataInit.stakeViewInfo = { ...item }\n        } else {\n          throw new Error('no product')\n        }\n\n        if (account.readyState === AccountStatus.ACTIVATED) {\n          if (clearTrade === true) {\n            walletLayer2Service.sendUserUpdate()\n          }\n          walletMap = makeWalletLayer2({ needFilterZero: true }).walletMap ?? {}\n\n          deFiSideCalcDataInit.coinSell.balance = walletMap[coinSellSymbol]?.count\n        }\n\n        if (clearTrade || tradeStake.deFiSideCalcData?.coinSell?.tradeValue === undefined) {\n          deFiSideCalcDataInit.coinSell.tradeValue = undefined\n          updateTradeStake({\n            sellVol: '0',\n            sellToken: tokenMap[coinSellSymbol],\n            deFiSideCalcData: {\n              ...deFiSideCalcDataInit,\n              coinSell: {\n                ...deFiSideCalcDataInit.coinSell,\n                tradeValue: undefined,\n              },\n            } as DeFiSideCalcData<T>,\n          })\n          myLog('resetDefault defi clearTrade', deFiSideCalcDataInit)\n        } else {\n          const tradeData = {\n            ...deFiSideCalcDataInit.coinSell,\n            tradeValue: tradeStake.deFiSideCalcData?.coinSell?.tradeValue ?? undefined,\n          }\n          handleOnchange({ tradeData })\n        }\n      } catch (error) {\n        setToastOpen({\n          open: true,\n          type: ToastType.error,\n          content: t(\n            SDK_ERROR_MAP_TO_UI[(error as sdk.RESULT_INFO).code ?? 700001]?.messageKey ??\n              (error as sdk.RESULT_INFO).message,\n          ),\n        })\n      }\n      setIsLoading(false)\n    },\n    [\n      account.readyState,\n      coinSellSymbol,\n      handleOnchange,\n      coinSellSymbol,\n      tokenMap,\n      tradeStake.deFiSideCalcData,\n      updateTradeStake,\n    ],\n  )\n\n  const walletLayer2Callback = React.useCallback(async () => {\n    let tradeValue: any = undefined\n    let deFiSideCalcDataInit: Partial<DeFiSideCalcData<any>> = {\n      coinSell: {\n        belong: coinSellSymbol,\n        balance: undefined,\n      },\n      ...(tradeStake?.deFiSideCalcData ?? {}),\n    }\n    if (tradeStake.deFiSideCalcData) {\n      tradeValue = tradeStake?.deFiSideCalcData?.coinSell?.tradeValue ?? undefined\n    }\n    if (deFiSideCalcDataInit?.coinSell?.belong) {\n      let walletMap: any\n      if (account.readyState === AccountStatus.ACTIVATED) {\n        walletMap = makeWalletLayer2({ needFilterZero: true }).walletMap\n        deFiSideCalcDataInit.coinSell = {\n          belong: coinSellSymbol,\n          balance: walletMap[coinSellSymbol]?.count,\n        }\n      } else {\n        deFiSideCalcDataInit.coinSell = {\n          belong: coinSellSymbol,\n          balance: undefined,\n        }\n      }\n      const tradeData = {\n        ...deFiSideCalcDataInit.coinSell,\n        tradeValue,\n      }\n      myLog('resetDefault Defi walletLayer2Callback', tradeData)\n      handleOnchange({ tradeData })\n    }\n  }, [account.readyState, coinSellSymbol, handleOnchange, tradeStake.deFiSideCalcData])\n\n  useWalletLayer2Socket({ walletLayer2Callback })\n  const sendRequest = React.useCallback(async () => {\n    const tradeStake = store.getState()._router_tradeStake.tradeStake\n    try {\n      setIsLoading(true)\n      if (\n        LoopringAPI.userAPI &&\n        LoopringAPI.defiAPI &&\n        tradeStake.deFiSideCalcData?.coinSell &&\n        tradeStake.sellToken?.tokenId !== undefined &&\n        exchangeInfo\n      ) {\n        const request = {\n          accountId: account.accountId,\n          timestamp: Date.now(),\n          token: {\n            tokenId: tradeStake.sellToken?.tokenId,\n            volume: tradeStake.sellVol,\n          },\n        }\n        myLog('Stake Trade request:', request)\n\n        const response = await LoopringAPI.defiAPI.sendStake(\n          request,\n          account.eddsaKey.sk,\n          account.apiKey,\n        )\n        if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n          const errorItem = SDK_ERROR_MAP_TO_UI[(response as sdk.RESULT_INFO)?.code ?? 700001]\n          throw new CustomErrorWithCode(errorItem)\n        } else {\n          const response1 = await LoopringAPI.defiAPI.getStakeSummary(\n            {\n              accountId: account.accountId,\n              hashes: response.hash,\n              tokenId: tradeStake.sellToken.tokenId,\n            },\n            account.apiKey,\n          )\n          let item: any\n          if ((response1 as sdk.RESULT_INFO).code || (response1 as sdk.RESULT_INFO).message) {\n          } else {\n            item = (response1 as any).list[0]\n          }\n\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.Staking_Success,\n            info: {\n              symbol: tradeStake.sellToken.symbol,\n              amount: tradeStake.deFiSideCalcData.coinSell.tradeValue,\n              daysDuration: Math.ceil(\n                Number(tradeStake?.deFiSideCalcData?.stakeViewInfo?.rewardPeriod ?? 0) / 86400000,\n              ),\n              ...item,\n            },\n          })\n          await sdk.sleep(SUBMIT_PANEL_QUICK_AUTO_CLOSE)\n          walletLayer2Service.sendUserUpdate()\n          if (\n            store.getState().modals.isShowAccount.isShow &&\n            store.getState().modals.isShowAccount.step == AccountStep.Staking_Success\n          ) {\n            setShowAccount({ isShow: false })\n          }\n        }\n      } else {\n        throw new Error('api not ready')\n      }\n    } catch (reason) {\n      setToastOpen({\n        open: true,\n        type: ToastType.error,\n        content:\n          t('labelInvestFailed') + ' ' + (reason as CustomErrorWithCode)?.messageKey ??\n          ` error: ${t((reason as CustomErrorWithCode)?.messageKey)}`,\n      })\n    } finally {\n      resetDefault(true)\n    }\n  }, [\n    account.accountId,\n    account.apiKey,\n    account.eddsaKey.sk,\n    exchangeInfo,\n    resetDefault,\n    setToastOpen,\n    t,\n  ])\n\n  const onSubmitBtnClick = React.useCallback(async () => {\n    // const tradeStake = store.getState().router_tradeStake.tradeStake;\n    if (\n      account.readyState === AccountStatus.ACTIVATED &&\n      tokenMap &&\n      exchangeInfo &&\n      account.eddsaKey?.sk\n    ) {\n      if (allowTrade && !allowTrade.defiInvest.enable) {\n        setShowSupport({ isShow: true })\n      } else if (toggle && !toggle[`${coinSellSymbol}StackInvest`].enable) {\n        setShowTradeIsFrozen({ isShow: true, type: 'StakingInvest' })\n      } else {\n        sendRequest()\n      }\n    } else {\n      return false\n    }\n  }, [\n    account.readyState,\n    account.eddsaKey?.sk,\n    tokenMap,\n    exchangeInfo,\n    sendRequest,\n    setToastOpen,\n    t,\n  ])\n  const availableTradeCheck = React.useCallback((): {\n    tradeBtnStatus: TradeBtnStatus\n    label: string\n  } => {\n    const account = store.getState().account\n    const tradeStake = store.getState()._router_tradeStake.tradeStake\n    myLog('tradeStake', tradeStake)\n    if (account.readyState === AccountStatus.ACTIVATED) {\n      if (tradeStake?.sellVol === undefined || sdk.toBig(tradeStake?.sellVol).lte(0)) {\n        return {\n          tradeBtnStatus: TradeBtnStatus.DISABLED,\n          label: 'labelEnterAmount',\n        }\n      } else if (\n        sdk\n          .toBig(tradeStake?.sellVol)\n          .minus(tradeStake?.deFiSideCalcData?.stakeViewInfo?.minSellVol ?? 0)\n          .lt(0)\n      ) {\n        return {\n          tradeBtnStatus: TradeBtnStatus.DISABLED,\n          label: `labelDefiMin| ${getValuePrecisionThousand(\n            sdk.toBig(tradeStake?.deFiSideCalcData?.stakeViewInfo?.minSellAmount ?? 0),\n            tokenMap[coinSellSymbol].precision,\n            tokenMap[coinSellSymbol].precision,\n            tokenMap[coinSellSymbol].precision,\n            false,\n            { floor: false, isAbbreviate: true },\n          )} ${coinSellSymbol}`,\n        }\n      } else if (\n        sdk\n          .toBig(tradeStake?.sellVol)\n          .gt(tradeStake?.deFiSideCalcData?.stakeViewInfo?.maxSellVol ?? 0)\n      ) {\n        return {\n          tradeBtnStatus: TradeBtnStatus.DISABLED,\n          label: `labelDefiMax| ${getValuePrecisionThousand(\n            sdk.toBig(tradeStake?.deFiSideCalcData?.stakeViewInfo?.maxSellAmount ?? 0),\n            tokenMap[coinSellSymbol].precision,\n            tokenMap[coinSellSymbol].precision,\n            tokenMap[coinSellSymbol].precision,\n            false,\n            { floor: false, isAbbreviate: true },\n          )} ${coinSellSymbol}`,\n        }\n        // return {\n        //   tradeBtnStatus: TradeBtnStatus.DISABLED,\n        //   label: `labelDefiNoEnough| ${coinSellSymbol}`,\n        // };\n      } else if (\n        tradeStake?.deFiSideCalcData?.coinSell?.tradeValue &&\n        sdk\n          .toBig(tradeStake.deFiSideCalcData.coinSell.tradeValue)\n          .gt(tradeStake.deFiSideCalcData?.coinSell.balance ?? 0)\n      ) {\n        return {\n          tradeBtnStatus: TradeBtnStatus.DISABLED,\n          label: `labelStakeNoEnough| ${coinSellSymbol}`,\n        }\n      } else {\n        return { tradeBtnStatus: TradeBtnStatus.AVAILABLE, label: '' } // label: ''}\n      }\n    }\n    return { tradeBtnStatus: TradeBtnStatus.AVAILABLE, label: '' }\n  }, [\n    tradeStake?.deFiSideCalcData?.stakeViewInfo?.minSellVol,\n    tradeStake.sellVol,\n    tradeStake.sellToken,\n    tradeStake.deFiSideCalcData,\n    tokenMap,\n    coinSellSymbol,\n  ])\n  const {\n    btnStatus,\n    onBtnClick,\n    btnLabel: tradeMarketI18nKey,\n  } = useSubmitBtn({\n    availableTradeCheck,\n    isLoading,\n    submitCallback: onSubmitBtnClick,\n  })\n  React.useEffect(() => {\n    getStakingMap()\n    walletLayer2Service.sendUserUpdate()\n  }, [])\n  React.useEffect(() => {\n    const {\n      _router_tradeStake: { tradeStake },\n      invest: {\n        stakingMap: { marketMap: stakingMap },\n      },\n    } = store.getState()\n\n    if (\n      stakingMapStatus === SagaStatus.UNSET &&\n      stakingMap &&\n      stakingMap[coinSellSymbol]?.symbol == coinSellSymbol &&\n      !(tradeStake?.deFiSideCalcData?.coinSell?.belong == coinSellSymbol)\n    ) {\n      resetDefault(true)\n    } else if (stakingMapStatus === SagaStatus.UNSET && stakingMap && !stakingMap[coinSellSymbol]) {\n      // setToastOpen({\n      //\n      // })\n    }\n    return () => {\n      resetTradeStake()\n      handleOnchange.cancel()\n    }\n  }, [stakingMapStatus])\n  const stakeWrapProps = React.useMemo(() => {\n    return {\n      disabled: false,\n      btnInfo: {\n        label: tradeMarketI18nKey,\n        params: {},\n      },\n      isJoin: true,\n      isLoading,\n      switchStobEvent: (_isStoB: boolean | ((prevState: boolean) => boolean)) => {},\n      onSubmitClick: onBtnClick as () => void,\n      onChangeEvent: handleOnchange,\n      deFiSideCalcData: {\n        ...tradeStake.deFiSideCalcData,\n      },\n      minSellAmount: tradeStake?.deFiSideCalcData?.stakeViewInfo?.minSellAmount,\n      maxSellAmount: tradeStake?.deFiSideCalcData?.stakeViewInfo?.maxSellAmount,\n      tokenSell: {\n        ...tokenMap[coinSellSymbol],\n        decimals: tradeStake?.deFiSideCalcData?.stakeViewInfo?.decimals,\n        precision: tradeStake?.deFiSideCalcData?.stakeViewInfo?.precision,\n      },\n      btnStatus,\n      accStatus: account.readyState,\n    }\n  }, [\n    refreshRef,\n    sendRequest,\n    tradeStake.deFiSideCalcData,\n    tradeStake?.deFiSideCalcData?.stakeViewInfo?.maxSellVol,\n    account.readyState,\n    tradeMarketI18nKey,\n    isLoading,\n    onBtnClick,\n    handleOnchange,\n    tokenMap,\n    coinSellSymbol,\n    btnStatus,\n  ]) // as ForceWithdrawProps<any, any>;\n  return {\n    stakeWrapProps: stakeWrapProps as unknown as DeFiSideWrapProps<T, I, ACD>,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/useStakeTradeExit.ts",
    "content": "import {\n  AccountStatus,\n  CustomErrorWithCode,\n  DeFiSideRedeemCalcData,\n  getValuePrecisionThousand,\n  globalSetup,\n  IBData,\n  myLog,\n  RedeemStake,\n  SDK_ERROR_MAP_TO_UI,\n  SUBMIT_PANEL_QUICK_AUTO_CLOSE,\n  TradeBtnStatus,\n} from '@loopring-web/common-resources'\nimport { useTranslation } from 'react-i18next'\nimport {\n  AccountStep,\n  DeFiStakeRedeemWrapProps,\n  RawDataDefiSideStakingItem,\n  ToastType,\n  useOpenModals,\n  useToggle,\n} from '@loopring-web/component-lib'\nimport { store, useAccount, useRedeemStake, useSystem, useTokenMap } from '../../stores'\nimport React from 'react'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport _ from 'lodash'\nimport { calcRedeemStaking } from '../help'\nimport { LoopringAPI } from '../../api_wrapper'\nimport { useSubmitBtn } from '../common'\nimport { useHistory } from 'react-router-dom'\nimport moment from 'moment'\nimport { walletLayer2Service } from '../../services'\n\nexport const useStakeRedeemClick = () => {\n  const { tokenMap, idIndex } = useTokenMap()\n  const { updateRedeemStake } = useRedeemStake()\n  const { setShowSideStakingRedeem } = useOpenModals()\n\n  const redeemItemClick = (item: RawDataDefiSideStakingItem) => {\n    const tokenInfo = tokenMap[idIndex[item.tokenId]]\n    updateRedeemStake({\n      sellToken: tokenInfo,\n      deFiSideRedeemCalcData: {\n        coinSell: {\n          belong: tokenInfo.symbol,\n          balance: sdk\n            .toBig(item.remainAmount)\n            .div('1e' + tokenInfo.decimals)\n            .toString(),\n          tradeValue: undefined,\n        },\n        stakeViewInfo: { ...item } as never,\n      },\n    })\n    setShowSideStakingRedeem({ isShow: true, symbol: tokenInfo.symbol })\n  }\n  return { redeemItemClick }\n}\n\nexport const useStakeTradeExit = <T extends IBData<I>, I, ACD extends DeFiSideRedeemCalcData<T>>({\n  setToastOpen,\n}: // symbol: coinSellSymbol,\n{\n  setToastOpen: (props: { open: boolean; content: JSX.Element | string; type: ToastType }) => void\n}) => {\n  const { t } = useTranslation()\n  const { setShowSupport, setShowTradeIsFrozen, setShowSideStakingRedeem } = useOpenModals()\n  const history = useHistory()\n  const { redeemStake, updateRedeemStake } = useRedeemStake()\n  const { tokenMap } = useTokenMap()\n  const { account } = useAccount()\n  const { exchangeInfo, allowTrade } = useSystem()\n  const { toggle } = useToggle()\n  const [isLoading, setIsLoading] = React.useState(false)\n  const { setShowAccount } = useOpenModals()\n\n  const coinSellSymbol = redeemStake?.sellToken?.symbol\n  const availableTradeCheck = React.useCallback((): {\n    tradeBtnStatus: TradeBtnStatus\n    label: string\n  } => {\n    const account = store.getState().account\n    const redeemStake = store.getState()._router_redeemStake.redeemStake\n    if (redeemStake?.sellToken && account.readyState === AccountStatus.ACTIVATED) {\n      if (redeemStake?.sellVol === undefined || sdk.toBig(redeemStake?.sellVol).lte(0)) {\n        return {\n          tradeBtnStatus: TradeBtnStatus.DISABLED,\n          label: 'labelEnterAmount',\n        }\n      } else if (\n        sdk\n          .toBig(redeemStake?.sellVol)\n          .minus((redeemStake?.deFiSideRedeemCalcData?.stakeViewInfo as any)?.minSellVol ?? 0)\n          .lt(0)\n      ) {\n        return {\n          tradeBtnStatus: TradeBtnStatus.DISABLED,\n          label: `labelDefiMin| ${getValuePrecisionThousand(\n            sdk.toBig(\n              (redeemStake?.deFiSideRedeemCalcData?.stakeViewInfo as any)?.minSellAmount ?? 0,\n            ),\n            tokenMap[coinSellSymbol].precision,\n            tokenMap[coinSellSymbol].precision,\n            tokenMap[coinSellSymbol].precision,\n            false,\n            { floor: false, isAbbreviate: true },\n          )} ${coinSellSymbol}`,\n        }\n      } else if (\n        sdk\n          .toBig(redeemStake?.sellVol)\n          .gt((redeemStake?.deFiSideRedeemCalcData?.stakeViewInfo as any)?.remainAmount)\n      ) {\n        return {\n          tradeBtnStatus: TradeBtnStatus.DISABLED,\n          label: `labelStakeNoEnough| ${redeemStake?.sellToken.symbol}`,\n        }\n      } else if (\n        !sdk\n          .toBig(redeemStake?.sellVol)\n          .eq((redeemStake?.deFiSideRedeemCalcData?.stakeViewInfo as any)?.remainAmount) &&\n        sdk\n          .toBig((redeemStake?.deFiSideRedeemCalcData?.stakeViewInfo as any)?.remainAmount ?? 0)\n          .minus(redeemStake?.sellVol)\n          .minus((redeemStake?.deFiSideRedeemCalcData?.stakeViewInfo as any)?.minSellVol ?? 0)\n          .lt(0)\n      ) {\n        return {\n          tradeBtnStatus: TradeBtnStatus.DISABLED,\n          label: 'labelRemainingBtnAmount',\n        }\n      } else {\n        return { tradeBtnStatus: TradeBtnStatus.AVAILABLE, label: '' } // label: ''}\n      }\n    }\n    return { tradeBtnStatus: TradeBtnStatus.AVAILABLE, label: '' }\n  }, [redeemStake?.deFiSideRedeemCalcData, tokenMap, coinSellSymbol])\n  const handleOnchange = _.debounce(\n    ({\n      tradeData,\n      _redeemStake = {},\n    }: {\n      tradeData: T\n      _redeemStake?: Partial<RedeemStake<T>>\n    }) => {\n      const redeemStake = store.getState()._router_redeemStake.redeemStake\n      let _deFiSideRedeemCalcData: DeFiSideRedeemCalcData<T> = {\n        ...redeemStake.deFiSideRedeemCalcData,\n      } as unknown as DeFiSideRedeemCalcData<T>\n      let _oldTradeStake = {\n        ...redeemStake,\n        ..._redeemStake,\n      }\n      //_.cloneDeep({ ...tradeStake, ..._tradeStake });\n      myLog('defi handleOnchange', _oldTradeStake)\n\n      if (tradeData && coinSellSymbol) {\n        const inputValue = tradeData?.tradeValue?.toString() ?? '0'\n        const tokenSell = tokenMap[coinSellSymbol]\n        const { sellVol, deFiSideRedeemCalcData } = calcRedeemStaking({\n          inputValue,\n          isJoin: false,\n          deFiSideRedeemCalcData: _deFiSideRedeemCalcData,\n          tokenSell,\n        })\n\n        // @ts-ignore\n        _deFiSideRedeemCalcData = {\n          ...deFiSideRedeemCalcData,\n          coinSell: {\n            ...tradeData,\n            tradeValue: tradeData?.tradeValue?.toString(),\n          },\n        }\n        updateRedeemStake({\n          sellToken: tokenSell,\n          sellVol,\n          deFiSideRedeemCalcData: {\n            ..._deFiSideRedeemCalcData,\n          },\n        })\n      }\n    },\n    globalSetup.wait,\n  )\n  const sendRequest = React.useCallback(async () => {\n    const redeemStake = store.getState()._router_redeemStake.redeemStake\n    try {\n      setIsLoading(true)\n      if (\n        LoopringAPI.userAPI &&\n        LoopringAPI.defiAPI &&\n        redeemStake.sellToken?.symbol &&\n        redeemStake.sellVol &&\n        exchangeInfo\n      ) {\n        const request = {\n          accountId: account.accountId,\n          token: {\n            tokenId: redeemStake.sellToken?.tokenId ?? 0,\n            volume: redeemStake.sellVol,\n          },\n          hash: (redeemStake.deFiSideRedeemCalcData.stakeViewInfo as any)?.hash,\n        }\n        myLog('DefiTrade request:', request)\n        const response = await LoopringAPI.defiAPI.sendStakeRedeem(\n          request,\n          account.eddsaKey.sk,\n          account.apiKey,\n        )\n        if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n          const errorItem = SDK_ERROR_MAP_TO_UI[(response as sdk.RESULT_INFO)?.code ?? 700001]\n          throw new CustomErrorWithCode(errorItem)\n        } else {\n          const searchParams = new URLSearchParams()\n          searchParams.set(\n            'refreshStake',\n            (redeemStake.deFiSideRedeemCalcData.stakeViewInfo as any).hash,\n          )\n          history.replace({ search: searchParams.toString() })\n          setShowSideStakingRedeem({ isShow: false })\n          const remainAmount = sdk\n            .toBig(redeemStake?.deFiSideRedeemCalcData?.coinSell?.balance)\n            .minus(redeemStake?.deFiSideRedeemCalcData?.coinSell?.tradeValue ?? 0)\n            .toString()\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.Staking_Redeem_Success,\n            info: {\n              productId: redeemStake?.deFiSideRedeemCalcData?.stakeViewInfo?.productId,\n              symbol: redeemStake.sellToken.symbol,\n              amount: redeemStake?.deFiSideRedeemCalcData?.coinSell?.tradeValue,\n              remainAmount,\n            },\n          })\n          await sdk.sleep(SUBMIT_PANEL_QUICK_AUTO_CLOSE)\n          walletLayer2Service.sendUserUpdate()\n          if (\n            store.getState().modals.isShowAccount.isShow &&\n            store.getState().modals.isShowAccount.step == AccountStep.Staking_Redeem_Success\n          ) {\n            setShowAccount({ isShow: false })\n          }\n        }\n      } else {\n        throw new Error('api not ready')\n      }\n    } catch (reason) {\n      setToastOpen({\n        open: true,\n        type: ToastType.error,\n        content:\n          t('labelInvestFailed') + (reason as CustomErrorWithCode)?.messageKey ??\n          ` error: ${t((reason as CustomErrorWithCode)?.messageKey)}`,\n      })\n    } finally {\n      setIsLoading(false)\n    }\n  }, [\n    account.accountId,\n    account.apiKey,\n    account.eddsaKey.sk,\n    exchangeInfo,\n    setToastOpen,\n    t,\n    redeemStake?.sellToken?.symbol,\n    redeemStake?.sellToken?.tokenId,\n    redeemStake?.sellVol,\n  ])\n\n  const handleSubmit = React.useCallback(async () => {\n    if (\n      account.readyState === AccountStatus.ACTIVATED &&\n      tokenMap &&\n      exchangeInfo &&\n      account.eddsaKey?.sk\n    ) {\n      if (allowTrade && !allowTrade.defiInvest.enable) {\n        setShowSupport({ isShow: true })\n      } else if (toggle && !toggle[`${coinSellSymbol}StackInvest`].enable) {\n        setShowTradeIsFrozen({\n          isShow: true,\n          type: coinSellSymbol + 'StakingRedeemInvest',\n        })\n      } else {\n        sendRequest()\n      }\n    } else {\n      return false\n    }\n  }, [\n    account.readyState,\n    account.eddsaKey?.sk,\n    tokenMap,\n    redeemStake?.sellToken?.symbol,\n    exchangeInfo,\n    sendRequest,\n    setToastOpen,\n    t,\n  ])\n  const onSubmitBtnClick = React.useCallback(async () => {\n    const tradeStake = store.getState()._router_tradeStake.tradeStake\n    if (\n      tradeStake?.deFiSideCalcData?.stakeViewInfo?.maxSellVol &&\n      tradeStake?.sellVol &&\n      sdk.toBig(tradeStake.sellVol).gte(tradeStake?.deFiSideCalcData?.stakeViewInfo?.maxSellVol)\n    ) {\n      if (\n        sdk\n          .toBig(tradeStake?.deFiSideCalcData?.stakeViewInfo?.maxSellVol ?? 0)\n          .minus(tradeStake?.deFiSideCalcData?.stakeViewInfo?.minSellVol ?? 0)\n          .toString()\n          .startsWith('-')\n      ) {\n      } else {\n        const tradeValue = getValuePrecisionThousand(\n          sdk\n            .toBig(tradeStake?.deFiSideCalcData?.stakeViewInfo?.maxSellVol)\n            .div('1e' + tokenMap[coinSellSymbol]?.decimals),\n          tokenMap[coinSellSymbol].precision,\n          tokenMap[coinSellSymbol].precision,\n          tokenMap[coinSellSymbol].precision,\n          false,\n          { floor: true },\n        ).replaceAll(sdk.SEP, '')\n        // @ts-ignore\n        const oldTrade = (tradeStake?.deFiSideCalcData ?? {}) as unknown as T\n        handleOnchange({\n          tradeData: {\n            ...oldTrade,\n            tradeValue,\n          },\n        })\n        // handleOnchange()\n      }\n    } else {\n      handleSubmit()\n    }\n  }, [tokenMap, coinSellSymbol, handleOnchange, handleSubmit])\n  const {\n    btnStatus,\n    onBtnClick,\n    btnLabel: tradeMarketI18nKey,\n  } = useSubmitBtn({\n    availableTradeCheck,\n    isLoading,\n    submitCallback: onSubmitBtnClick,\n  })\n  const stakeWrapProps = React.useMemo(() => {\n    const stakeViewInfo = redeemStake?.deFiSideRedeemCalcData?.stakeViewInfo\n    const requiredHoldDay = (stakeViewInfo?.claimableTime - stakeViewInfo?.stakeAt) / 86400000\n    const holdDay = moment(Date.now()).diff(\n      moment(new Date(stakeViewInfo?.stakeAt ?? ''))\n        .utc()\n        .startOf('days'),\n      'days',\n      false,\n    )\n    return {\n      isJoin: false,\n      isFullTime: holdDay >= requiredHoldDay,\n      disabled: account.readyState !== AccountStatus.ACTIVATED,\n      btnInfo: {\n        label: tradeMarketI18nKey,\n        params: {},\n      },\n      isLoading,\n      minSellAmount: (redeemStake?.deFiSideRedeemCalcData?.stakeViewInfo as any)?.minSellAmount,\n      maxSellAmount: (redeemStake?.deFiSideRedeemCalcData?.stakeViewInfo as any)?.maxSellAmount,\n      onSubmitClick: onBtnClick as () => void,\n      switchStobEvent: (_isStoB: boolean | ((prevState: boolean) => boolean)) => {},\n      onChangeEvent: handleOnchange,\n      deFiSideRedeemCalcData: redeemStake?.deFiSideRedeemCalcData as any,\n      tokenSell: tokenMap[coinSellSymbol],\n      btnStatus,\n      accStatus: account.readyState,\n    } as DeFiStakeRedeemWrapProps<T, I, ACD>\n  }, [\n    sendRequest,\n    redeemStake?.deFiSideRedeemCalcData,\n    (redeemStake?.deFiSideRedeemCalcData?.stakeViewInfo as any)?.claimableTime,\n    (redeemStake?.deFiSideRedeemCalcData?.stakeViewInfo as any)?.maxSellVol,\n    account.readyState,\n    tradeMarketI18nKey,\n    onBtnClick,\n    handleOnchange,\n    tokenMap,\n    coinSellSymbol,\n    btnStatus,\n  ]) // as ForceWithdrawProps<any, any>;\n  return {\n    stakeWrapProps: stakeWrapProps as unknown as DeFiStakeRedeemWrapProps<T, I, ACD>,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/useStakingAprTrend.ts",
    "content": "import React from 'react'\nimport { useOpenModals } from '@loopring-web/component-lib'\nimport { CustomErrorWithCode, myLog, SDK_ERROR_MAP_TO_UI } from '@loopring-web/common-resources'\nimport { useDefiMap } from '../../stores'\nimport { LoopringAPI } from '../../api_wrapper'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nexport const useStakingAprTrend = () => {\n  const { marketMap: defiMarketMap, marketLeverageMap } = useDefiMap()\n  const [isLoading, setLoading] = React.useState(false)\n  const [{ trends, defiInfo }, setTrends] = React.useState({\n    trends: [],\n    defiInfo: undefined,\n  })\n\n  const {\n    modals: { isShowETHStakingApr },\n  } = useOpenModals()\n  React.useEffect(() => {\n    if (isShowETHStakingApr.isShow && isShowETHStakingApr.symbol) {\n      setLoading(true)\n      // isShowETHStakingApr.info\n      LoopringAPI.defiAPI\n        .getDefiApys({\n          request: {\n            defiType: isShowETHStakingApr.info?.type,\n            product: isShowETHStakingApr.symbol,\n            limit: 90,\n          },\n        })\n        .then((response) => {\n          if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n            const errorItem = SDK_ERROR_MAP_TO_UI[(response as sdk.RESULT_INFO)?.code ?? 700001]\n            throw new CustomErrorWithCode(errorItem)\n          } else {\n            const _defiMarketMap = {\n              ...defiMarketMap,\n              ...marketLeverageMap,\n            }\n            setTrends({\n              defiInfo: _defiMarketMap[isShowETHStakingApr.symbol],\n              trends: response.apys,\n            })\n            setLoading(false)\n          }\n        })\n        .finally(() => {\n          setLoading(false)\n        })\n    }\n    return () => {}\n  }, [isShowETHStakingApr.isShow])\n\n  return {\n    isLoading,\n    trends,\n    defiInfo,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/useTaikoLock.ts",
    "content": "import React, { useEffect, useState } from 'react'\nimport {\n  AccountStep,\n  ToastType,\n  useOpenModals,\n  useSettings,\n  useToggle,\n} from '@loopring-web/component-lib'\nimport {\n  AccountStatus,\n  CustomErrorWithCode,\n  DeFiSideCalcData,\n  FeeInfo,\n  getValuePrecisionThousand,\n  globalSetup,\n  IBData,\n  L1L2_NAME_DEFINED,\n  MapChainId,\n  myLog,\n  SagaStatus,\n  SDK_ERROR_MAP_TO_UI,\n  SUBMIT_PANEL_QUICK_AUTO_CLOSE,\n  TradeBtnStatus,\n  TradeStake,\n} from '@loopring-web/common-resources'\n\nimport {\n  accountServices,\n  calcSideStaking,\n  DAYS,\n  erc20ABI,\n  fiatNumberDisplay,\n  getStateFnState,\n  getTimestampDaysLater,\n  hasLrTAIKODust,\n  isNumberStr,\n  numberFormat,\n  numberFormatThousandthPlace,\n  resetlrTAIKOIfNeeded,\n  strNumDecimalPlacesLessThan,\n  taikoDepositABI,\n  unlockAccount,\n  useChargeFees,\n  useStakingMap,\n  useUpdateAccount,\n  useWalletLayer2Socket,\n} from '@loopring-web/core'\nimport _, { last } from 'lodash'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport Web3 from 'web3'\nimport {\n  LoopringAPI,\n  store,\n  useAccount,\n  useSystem,\n  useTokenMap,\n  walletLayer2Service,\n} from '../../index'\nimport { useTranslation } from 'react-i18next'\nimport { useTokenPrices, useTradeStake, useVaultLayer2, useWalletLayer2, WalletLayer1Map } from '../../stores'\nimport Decimal from 'decimal.js'\nimport { BigNumber, Contract, ethers, providers, utils } from 'ethers'\nimport moment from 'moment'\nimport { useAppKitProvider } from '@reown/appkit/react'\nimport { useDispatch } from 'react-redux'\nimport { useWalletInfo } from '../../stores/localStore/walletInfo'\nimport { mapObject } from 'react-financial-charts'\n\nconst depositContractAddrTAIKOHEKLA = '0x40aCCf1a13f4960AC00800Dd6A4afE82509C2fD2'\nconst depositContractAddrTAIKO = '0xaD32A362645Ac9139CFb5Ba3A2A46fC4c378812B'\n\nconst depositTaikoWithDurationApprove = async (input: {\n  provider: providers.Web3Provider\n  amount: BigNumber\n  duration: BigNumber\n  taikoAddress: string\n  from: string\n  to: string\n  chainId: sdk.ChainId\n  approveToAddress: string\n}) => {\n  const { provider, amount, duration, taikoAddress, from, to, chainId, approveToAddress } = input\n  const signer = provider.getSigner()\n  const tokenContract = new Contract(taikoAddress, erc20ABI, signer)\n  const allowance = await tokenContract.allowance(from, approveToAddress)\n  if (allowance.lt(amount)) {\n    const approveTx = await tokenContract.approve(approveToAddress, amount)\n    await approveTx.wait()\n  }\n}\nconst depositTaikoWithDuration = async (input: {\n  provider: providers.Web3Provider\n  amount: BigNumber\n  duration: BigNumber\n  taikoAddress: string\n  from: string\n  to: string\n  chainId: sdk.ChainId\n  approveToAddress: string\n}) => {\n  const { provider, amount, duration, taikoAddress, from, to, chainId, approveToAddress } = input\n  const depositContractAddr =\n    chainId === sdk.ChainId.TAIKO ? depositContractAddrTAIKO : depositContractAddrTAIKOHEKLA\n  const signer = provider.getSigner()\n  const contract = new Contract(depositContractAddr, taikoDepositABI, signer)\n  const tx = await contract.deposit(from, to, taikoAddress, amount, duration, '0x')\n  return tx.wait()\n}\nconst depositTaikoWithDurationTx = async (input: {\n  provider: providers.Web3Provider\n  amount: BigNumber\n  duration: BigNumber\n  taikoAddress: string\n  from: string\n  to: string\n  chainId: sdk.ChainId\n  approveToAddress: string\n}) => {\n  const { provider, amount, duration, taikoAddress, from, to, chainId, approveToAddress } = input\n  const depositContractAddr =\n    chainId === sdk.ChainId.TAIKO ? depositContractAddrTAIKO : depositContractAddrTAIKOHEKLA\n  const signer = provider.getSigner()\n  const contract = new Contract(depositContractAddr, taikoDepositABI, signer)\n  return contract.functions['deposit'](from, to, taikoAddress, amount, duration, '0x') \n  // return tx.wait()\n}\n\nconst submitTaikoFarmingMint = async (info: {\n  amount: BigNumber\n  accountId: number\n  apiKey: string\n  exchangeAddress: string\n  tokenId: number\n  eddsaSk: string\n}) => {\n  const storageId = await LoopringAPI?.userAPI?.getNextStorageId(\n    {\n      accountId: info.accountId,\n      sellTokenId: info.tokenId,\n    },\n    info.apiKey,\n  )\n  const avaiableNFT = await LoopringAPI?.defiAPI?.getTaikoFarmingAvailableNft(\n    {\n      accountId: info.accountId,\n    },\n    info.apiKey,\n  )\n  const positionsInfo = await LoopringAPI?.defiAPI?.getTaikoFarmingPositionInfo(\n    {\n      accountId: info.accountId,\n    }\n  )\n  const positions = positionsInfo?.data\n  \n  const claimedTotal =\n    positions && positions[0] && positions[0].claimedTotal\n      ? BigNumber.from(positions[0].claimedTotal)\n      : BigNumber.from('0')\n  const preorderHash =\n    positions && positions?.length > 0 ? ((positions[0] as any).orderHash as string) : ''\n  const taikoFarmingSubmit: sdk.TaikoFarmingSubmitRequest = {\n    exchange: info.exchangeAddress,\n    accountId: info.accountId,\n    storageId: storageId!.orderId,\n    sellToken: {\n      tokenId: info.tokenId,\n      amount: claimedTotal.add(info.amount).toString(),\n    },\n    buyToken: {\n      tokenId: avaiableNFT!.tokenId,\n      nftData: avaiableNFT!.nftData,\n      amount: '1',\n    },\n    allOrNone: false,\n    fillAmountBOrS: true,\n    validUntil: getTimestampDaysLater(365 * 10),\n    maxFeeBips: 100,\n    preOrderHash: preorderHash,\n  }\n  return LoopringAPI?.defiAPI?.submitTaikoFarmingClaim({\n    request: taikoFarmingSubmit,\n    apiKey: info.apiKey,\n    eddsaKey: info.eddsaSk,\n  })\n}\n\nexport const useTaikoLock = <T extends IBData<I>, I>({\n  setToastOpen,\n  symbol: coinSellSymbol,\n}: {\n  symbol: string\n  setToastOpen: (props: { open: boolean; content: JSX.Element | string; type: ToastType }) => void\n}) => {\n  const { t } = useTranslation(['common'])\n  const refreshRef = React.createRef()\n  const [isLoading, setIsLoading] = React.useState(false)\n  const [taikoFarmingChecked, setTaikoFarmingChecked] = React.useState(false)\n  const onCheckBoxChange = React.useCallback(() => {\n    setTaikoFarmingChecked(!taikoFarmingChecked)\n  }, [taikoFarmingChecked])\n  const { tokenMap } = useTokenMap()\n  const { tokenPrices } = useTokenPrices()\n  const { account } = useAccount()\n  const dispatch = useDispatch()\n  const { setShowAccount } = useOpenModals()\n  const { status: stakingMapStatus, marketMap: stakingMap, getStakingMap } = useStakingMap()\n\n  const { setShowSupport, setShowTradeIsFrozen } = useOpenModals()\n  const { tradeStake, updateTradeStake, resetTradeStake } = useTradeStake()\n  const { exchangeInfo, allowTrade, getValueInCurrency } = useSystem()\n  const { toggle } = useToggle()\n  const { defaultNetwork, currency, coinJson } = useSettings()\n  const sellToken = tokenMap[coinSellSymbol] ? tokenMap[coinSellSymbol] : undefined\n  const taikoFarmingPrecision = 2\n  const { walletLayer2, updateWalletLayer2 } = useWalletLayer2()\n  const [mintedLRTAIKO, setMintedLRTAIKO] = useState(undefined as string | undefined)\n  const holdingTAIKO = walletLayer2 && walletLayer2['TAIKO'] \n    ? BigNumber.from(walletLayer2['TAIKO'].total).sub(walletLayer2['TAIKO'].locked).toString()\n    : undefined\n\n  \n  const holdingLRTAIKO =\n    walletLayer2 && walletLayer2['LRTAIKO']?.total && sellToken\n      ? utils.formatUnits(\n          BigNumber.from(walletLayer2['LRTAIKO'].total).sub(walletLayer2['LRTAIKO'].locked),\n          sellToken.decimals,\n        )\n      : undefined\n\n  \n\n  const handleOnchange = _.debounce(\n    ({ tradeData, _tradeStake = {} }: { tradeData: T; _tradeStake?: Partial<TradeStake<T>> }) => {\n      const tradeStake = store.getState()._router_tradeStake.tradeStake\n      let _deFiSideCalcData: DeFiSideCalcData<T> = {\n        ...tradeStake.deFiSideCalcData,\n      } as unknown as DeFiSideCalcData<T>\n      let _oldTradeStake = {\n        ...tradeStake,\n        ..._tradeStake,\n      }\n      myLog('defi handleOnchange', _oldTradeStake)\n\n      if (tradeData && coinSellSymbol) {\n        const inputValue = tradeData?.tradeValue?.toString() ?? ''\n\n        const tokenSell = tokenMap[coinSellSymbol]\n        const { sellVol, deFiSideCalcData } = calcSideStaking({\n          inputValue,\n          isJoin: true,\n          deFiSideCalcData: _deFiSideCalcData,\n          tokenSell,\n        })\n\n        // @ts-ignore\n        _deFiSideCalcData = {\n          ...deFiSideCalcData,\n          coinSell: {\n            ...tradeData,\n            tradeValue: inputValue,\n          },\n          stakeViewInfo: {\n            ...deFiSideCalcData.stakeViewInfo,\n          }\n        }\n        updateTradeStake({\n          sellToken: tokenSell,\n          sellVol,\n          deFiSideCalcData: {\n            ..._deFiSideCalcData,\n          },\n        })\n      }\n    },\n    globalSetup.wait,\n  )\n\n  const resetDefault = React.useCallback(\n    async (clearTrade: boolean = false) => {\n      let deFiSideCalcDataInit: Partial<DeFiSideCalcData<any>> = {\n        ...tradeStake.deFiSideCalcData,\n        coinSell: {\n          belong: coinSellSymbol,\n          balance: undefined,\n          tradeValue:\n            tradeStake.deFiSideCalcData?.coinSell?.belong === coinSellSymbol\n              ? tradeStake.deFiSideCalcData?.coinSell?.tradeValue\n              : undefined,\n        },\n      }\n      try {\n        let item = stakingMap[coinSellSymbol]\n        if (item && stakingMap) {\n          deFiSideCalcDataInit.stakeViewInfo = { \n            ...item,\n            // minSellAmount: '1',\n            // minSellVol: utils.parseEther('1').toString(),\n          }\n        } else {\n          throw new Error('no product')\n        }\n\n        // if (account.readyState === AccountStatus.ACTIVATED) {\n        if (clearTrade === true) {\n          walletLayer2Service.sendUserUpdate()\n        }\n        const walletLayer1 = store.getState().walletLayer1.walletLayer1 as WalletLayer1Map<any>\n\n        deFiSideCalcDataInit.coinSell.balance = walletLayer1[coinSellSymbol]?.count\n          ? numberFormat(walletLayer1[coinSellSymbol]?.count, {\n              fixed: taikoFarmingPrecision,\n              removeTrailingZero: true,\n            })\n          : undefined\n\n        if (clearTrade || tradeStake.deFiSideCalcData?.coinSell?.tradeValue === undefined) {\n          deFiSideCalcDataInit.coinSell.tradeValue = undefined\n          updateTradeStake({\n            sellVol: '0',\n            sellToken: tokenMap[coinSellSymbol],\n            deFiSideCalcData: {\n              ...deFiSideCalcDataInit,\n              coinSell: {\n                ...deFiSideCalcDataInit.coinSell,\n                tradeValue: undefined,\n              },\n            } as DeFiSideCalcData<T>,\n          })\n          myLog('resetDefault defi clearTrade', deFiSideCalcDataInit)\n        } else {\n          const tradeData = {\n            ...deFiSideCalcDataInit.coinSell,\n            tradeValue: tradeStake.deFiSideCalcData?.coinSell?.tradeValue ?? undefined,\n          }\n          handleOnchange({ tradeData })\n        }\n      } catch (error) {\n        setToastOpen({\n          open: true,\n          type: ToastType.error,\n          content: t(\n            SDK_ERROR_MAP_TO_UI[(error as sdk.RESULT_INFO).code ?? 700001]?.messageKey ??\n              (error as sdk.RESULT_INFO).message,\n          ),\n        })\n      }\n      setIsLoading(false)\n      setDaysInput('')\n    },\n    [\n      account.readyState,\n      coinSellSymbol,\n      handleOnchange,\n      coinSellSymbol,\n      tokenMap,\n      tradeStake.deFiSideCalcData,\n      updateTradeStake,\n    ],\n  )\n\n  const walletLayer1Callback = React.useCallback(async () => {\n    let tradeValue: any = undefined\n    let deFiSideCalcDataInit: Partial<DeFiSideCalcData<any>> = {\n      coinSell: {\n        belong: coinSellSymbol,\n        balance: undefined,\n      },\n      ...(tradeStake?.deFiSideCalcData ?? {}),\n    }\n    if (tradeStake.deFiSideCalcData) {\n      tradeValue = tradeStake?.deFiSideCalcData?.coinSell?.tradeValue ?? undefined\n    }\n    if (deFiSideCalcDataInit?.coinSell?.belong) {\n      const walletLayer1 = store.getState().walletLayer1.walletLayer1 as WalletLayer1Map<any>\n\n      deFiSideCalcDataInit.coinSell = {\n        belong: coinSellSymbol,\n        balance: numberFormat(walletLayer1[coinSellSymbol]?.count, {\n          fixed: taikoFarmingPrecision,\n          removeTrailingZero: true,\n        }),\n      }\n      const tradeData = {\n        ...deFiSideCalcDataInit.coinSell,\n        tradeValue,\n      }\n      myLog('resetDefault Defi walletLayer2Callback', tradeData)\n      handleOnchange({ tradeData })\n    }\n  }, [account.readyState, coinSellSymbol, handleOnchange, tradeStake.deFiSideCalcData])\n\n  useWalletLayer2Socket({ walletLayer1Callback })\n  // useWalletLayer({ walletLayer1Callback })\n  const sendRequest = React.useCallback(async () => {\n    const tradeStake = store.getState()._router_tradeStake.tradeStake\n    try {\n      setIsLoading(true)\n      if (\n        LoopringAPI.userAPI &&\n        LoopringAPI.defiAPI &&\n        tradeStake.deFiSideCalcData?.coinSell &&\n        tradeStake.sellToken?.tokenId !== undefined &&\n        exchangeInfo\n      ) {\n        const request = {\n          accountId: account.accountId,\n          timestamp: Date.now(),\n          token: {\n            tokenId: tradeStake.sellToken?.tokenId,\n            volume: tradeStake.sellVol,\n          },\n        }\n        myLog('Stake Trade request:', request)\n\n        const response = await LoopringAPI.defiAPI.sendStake(\n          request,\n          account.eddsaKey.sk,\n          account.apiKey,\n        )\n        if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n          const errorItem = SDK_ERROR_MAP_TO_UI[(response as sdk.RESULT_INFO)?.code ?? 700001]\n          throw new CustomErrorWithCode(errorItem)\n        } else {\n          const response1 = await LoopringAPI.defiAPI.getStakeSummary(\n            {\n              accountId: account.accountId,\n              hashes: response.hash,\n              tokenId: tradeStake.sellToken.tokenId,\n              \n            },\n            account.apiKey,\n          )\n          let item: any\n          if ((response1 as sdk.RESULT_INFO).code || (response1 as sdk.RESULT_INFO).message) {\n          } else {\n            item = (response1 as any).list[0]\n          }\n\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.Taiko_Farming_Lock_Success,\n            info: {\n              symbol: tradeStake.sellToken.symbol,\n              amount: tradeStake.deFiSideCalcData.coinSell.tradeValue,\n              daysDuration: Math.ceil(\n                Number(tradeStake?.deFiSideCalcData?.stakeViewInfo?.rewardPeriod ?? 0) / 86400000,\n              ),\n              ...item,\n            },\n          })\n          await sdk.sleep(SUBMIT_PANEL_QUICK_AUTO_CLOSE)\n          walletLayer2Service.sendUserUpdate()\n          refreshData()\n        }\n      } else {\n        throw new Error('api not ready')\n      }\n    } catch (reason) {\n      setToastOpen({\n        open: true,\n        type: ToastType.error,\n        content:\n          t('labelInvestFailed') + ' ' + (reason as CustomErrorWithCode)?.messageKey ??\n          ` error: ${t((reason as CustomErrorWithCode)?.messageKey)}`,\n      })\n    } finally {\n      resetDefault(true)\n    }\n  }, [\n    account.accountId,\n    account.apiKey,\n    account.eddsaKey.sk,\n    exchangeInfo,\n    resetDefault,\n    setToastOpen,\n    t,\n  ])\n  const provider = useAppKitProvider('eip155')\n  const [daysInput, setDaysInput] = React.useState('')\n  const [txSubmitModalState, setTxSubmitModalState] = React.useState({\n    open: false,\n    status: 'init' as 'init' | 'tokenApproving' |  'depositing' | 'depositCompleted',\n  })\n  const [pendingTxsModalOpen, setPendingTxsModalOpen] = React.useState(false)\n  const [localPendingTx, setLocalPendingTx] = useState<{\n    txHash: string\n    lockDuration: number\n    stakeAt: number\n    amount: string\n  } | undefined>(undefined)\n  \n\n  const daysInputValid =\n    Number.isInteger(Number(daysInput)) && Number(daysInput) >= 15 && Number(daysInput) <= 60\n  const [stakeInfo, setStakeInfo] = React.useState(\n    undefined as\n      | undefined\n      | {\n          totalStaked: string\n          stakingReceivedLocked: {\n            accountId: number\n            tokenId: number\n            stakeAt: number\n            initialAmount: string\n            remainAmount: string\n            totalRewards: string\n            productId: string\n            hash: string\n            status: string\n            createdAt: number\n            updatedAt: number\n            claimableTime: number\n            lastDayPendingRewards: string\n            apr: string\n          }[]\n        },\n  )\n  const [realizedAndUnrealized, setRealizedAndUnrealized] = React.useState(\n    undefined as\n      | undefined\n      | {\n          redeemAmount: string\n          realizedUSDT: string\n          unrealizedTaiko: string\n        },\n  )\n  \n  \n\n\n  \n\n  const [pendingDeposits, setPendingDeposits] = React.useState(\n    undefined as\n      | undefined\n      | {\n          accountId: number\n          tokenId: number\n          stakeAt: number\n          txHash: string\n          eventIndex: number\n          lockDuration: number\n          hash: string\n          status: string\n          createdAt: number\n          updatedAt: number\n        }[],\n  )\n\n  const pendingDepositsMergeLocal = [\n    ...(localPendingTx ? [\n      {...localPendingTx, isLocal: true}\n    ] : []),\n    ...(pendingDeposits ? pendingDeposits.map(tx => ({...tx, isLocal: false})) : []),\n  ]\n\n  const firstLockingPos: { claimableTime: number } | undefined =\n    stakeInfo?.stakingReceivedLocked && last(stakeInfo.stakingReceivedLocked)\n      ? { claimableTime: last(stakeInfo.stakingReceivedLocked)!.claimableTime }\n      : pendingDepositsMergeLocal.length > 0\n      ? {\n          claimableTime:\n            last(pendingDepositsMergeLocal)!.lockDuration + last(pendingDepositsMergeLocal)!.stakeAt,\n        }\n      : undefined\n\n\n  const hasNoLockingPos = !firstLockingPos\n  const [hasLockingTxNotOnChain, setHasLockingTxNotOnChain] = React.useState(false)\n\n\n  const onSubmitBtnClick = React.useCallback(async () => {\n    if (tokenMap && exchangeInfo) {\n      if (allowTrade && !allowTrade.defiInvest.enable) {\n        setShowSupport({ isShow: true })\n      } else if (toggle && !toggle['taikoFarming'].enable) {\n        setShowTradeIsFrozen({ isShow: true, type: 'StakingInvest' })\n      } else if (hasLrTAIKODust() && account.readyState === 'LOCKED') {\n        setShowLogInToCleanLrTaiko(true)\n      } else {\n        new Promise((res) => {\n          setIsLoading(true)\n          setTxSubmitModalState({\n            open: true,\n            status: 'tokenApproving',\n          })\n          res(null)\n        })\n          .then(() => {\n            if (account.accountId && account.accountId !== -1) {\n              return resetlrTAIKOIfNeeded(account, defaultNetwork, exchangeInfo, 5)\n            }\n          })\n          .then(() => {\n            const oneDay = BigNumber.from('60').mul('60').mul('24')\n            const duration =\n              stakeInfo && !firstLockingPos\n                ? BigNumber.from(daysInput).mul(oneDay)\n                : firstLockingPos\n                ? BigNumber.from(firstLockingPos.claimableTime)\n                    .sub(Date.now())\n                    .div('1000')\n                    .div(oneDay)\n                    .mul(oneDay)\n                : undefined\n            if (tradeStake && tradeStake.deFiSideCalcData && duration && sellToken) {\n              return depositTaikoWithDurationApprove({\n                provider: new providers.Web3Provider(provider.walletProvider!),\n                amount: BigNumber.from(tradeStake!.sellVol),\n                duration: duration,\n                taikoAddress: sellToken.address,\n                from: account.accAddress,\n                to: account.accAddress,\n                chainId: defaultNetwork,\n                approveToAddress: exchangeInfo!.depositAddress,\n              }).then(() => {\n                setTxSubmitModalState({\n                  open: true,\n                  status: 'depositing',\n                })\n                setHasLockingTxNotOnChain(true)\n                return depositTaikoWithDurationTx({\n                  provider: new providers.Web3Provider(provider.walletProvider!),\n                  amount: BigNumber.from(tradeStake!.sellVol),\n                  duration: duration,\n                  taikoAddress: sellToken.address,\n                  from: account.accAddress,\n                  to: account.accAddress,\n                  chainId: defaultNetwork,\n                  approveToAddress: exchangeInfo!.depositAddress,\n                })\n              })\n            } else {\n              throw new Error('depositTaikoWithDurationApprove error')\n            }\n          })\n          .then((tx) => {\n            setDaysInput('')\n            setIsLoading(false)\n            resetDefault(true)\n            setLocalPendingTx({\n              txHash: tx.hash,\n              amount: tradeStake!.sellVol,\n              stakeAt: Date.now(),\n              lockDuration: firstLockingPos\n                ? firstLockingPos.claimableTime - Date.now()\n                : Number(daysInput) * 24 * 60 * 60 * 1000,\n            })\n            return tx.wait()\n          })\n          .then((txReceipt) => {\n            setHasLockingTxNotOnChain(false)\n            const recursiveCheck = async (\n              hash: string,\n              env: { addr: string; chainId: sdk.ChainId },\n            ) => {\n              const account = store.getState().account\n              const defaultNetwork = store.getState().settings.defaultNetwork\n\n              if (\n                env.addr.toLowerCase() !== account.accAddress.toLowerCase() ||\n                defaultNetwork !== env.chainId\n              ) {\n                // stop if address, chain changed\n                return\n              }\n              const accountId =\n                account.accountId === -1 ? account._accountIdNotActive ?? -1 : account.accountId\n              if (!accountId || accountId === -1) {\n                accountServices.sendCheckAccount(account.accAddress)\n                await sdk.sleep(10 * 1000)\n                return recursiveCheck(hash, env)\n              } else {\n                const res = await LoopringAPI?.defiAPI?.getTaikoFarmingDepositDurationList({\n                  accountId,\n                  tokenId: sellToken!.tokenId,\n                  statuses: 'locked',\n                  // @ts-ignore\n                  txHashes: hash,\n                })\n                if (res?.data && res.data.length > 0) {\n                  setTxSubmitModalState((state) => ({\n                    ...state,\n                    status: 'depositCompleted',\n                  }))\n                  return\n                } else {\n                  await sdk.sleep(10 * 1000)\n                  return recursiveCheck(hash, env)\n                }\n              }\n            }\n            recursiveCheck(txReceipt.transactionHash, {\n              addr: account.accAddress,\n              chainId: defaultNetwork,\n            })\n          })\n          .catch((e) => {\n            setTxSubmitModalState({\n              open: false,\n              status: 'init',\n            })\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.Taiko_Farming_Lock_Failed,\n              info: {\n                error: {\n                  msg: e.toString(),\n                },\n              },\n            })\n          })\n          .finally(() => {\n            setHasLockingTxNotOnChain(false)\n            resetDefault(true)\n          })\n      }\n    } else {\n      return false\n    }\n  }, [\n    account.readyState,\n    account.eddsaKey?.sk,\n    tokenMap,\n    exchangeInfo,\n    sendRequest,\n    setToastOpen,\n    daysInput,\n    tradeStake,\n    tradeStake.deFiSideCalcData,\n    t,\n  ])\n  const [taikoFarmingAccountStatus, setTaikoFarmingAccountStatus] = useState(undefined as number | undefined)\n  \n  const chargeFee = useChargeFees({\n    requestType: sdk.OffchainFeeReqType.OFFCHAIN_WITHDRAWAL,\n\n    amount: holdingTAIKO ? Number(holdingTAIKO) : 0,\n    needAmountRefresh: true,\n    tokenSymbol: sellToken?.symbol,\n  })\n  const { idIndex }=useTokenMap()\n  useEffect(() => {\n    const feeTokenBalance = walletLayer2 && chargeFee.feeInfo.__raw__ ? walletLayer2[idIndex[chargeFee.feeInfo.__raw__.tokenId]] : undefined\n    const isFeeNotEnough = feeTokenBalance ? BigNumber.from(feeTokenBalance.total).sub(feeTokenBalance.locked).lt(chargeFee.feeInfo.__raw__.feeRaw) : false\n    if (isFeeNotEnough) {\n      const foundFee = chargeFee.chargeFeeTokenList.find((feeInfo) => {\n        const balance = walletLayer2 && walletLayer2[idIndex[feeInfo.__raw__.tokenId] ]\n        return balance && BigNumber.from(balance.total).sub(balance.locked).gte(feeInfo.__raw__.feeRaw)\n      })\n      foundFee && chargeFee.handleFeeChange(foundFee)\n    } \n  }, [chargeFee, walletLayer2])\n  \n  const taikoFee = chargeFee?.chargeFeeTokenList?.find(fee => fee.belong === 'TAIKO')\n  const taikoBalanceGreaterThanFee = holdingTAIKO && taikoFee\n    ? BigNumber.from(holdingTAIKO).gt(taikoFee.__raw__.feeRaw)\n    : undefined\n\n  const settlementStatus: 'init' | 'minting' | 'notSettled' | 'settled' | 'noPosition' =\n    taikoFarmingAccountStatus === undefined\n      ? 'init'\n      : (taikoFarmingAccountStatus === 1 || taikoFarmingAccountStatus === 2)\n      ? 'minting'\n      : taikoFarmingAccountStatus === 3\n      ? 'notSettled'\n      : taikoFarmingAccountStatus === 0 && taikoBalanceGreaterThanFee\n      ? 'settled'\n      : 'noPosition'\n\n  const availableTradeCheck = React.useCallback((): {\n    tradeBtnStatus: TradeBtnStatus\n    label: string\n  } => {\n    const account = store.getState().account\n    const tradeStake = store.getState()._router_tradeStake.tradeStake\n    myLog('tradeStake', tradeStake)\n\n    \n    if (tradeStake?.sellVol === undefined || sdk.toBig(tradeStake?.sellVol).lte(0)) {\n      return {\n        tradeBtnStatus: TradeBtnStatus.DISABLED,\n        label: 'labelEnterAmount',\n      }\n    } else if (\n      sdk\n        .toBig(tradeStake?.sellVol)\n        .minus(tradeStake?.deFiSideCalcData?.stakeViewInfo?.minSellVol ?? 0)\n        .lt(0)\n    ) {\n      return {\n        tradeBtnStatus: TradeBtnStatus.DISABLED,\n        label: `labelDefiMin| ${getValuePrecisionThousand(\n          sdk.toBig(tradeStake?.deFiSideCalcData?.stakeViewInfo?.minSellAmount ?? 0),\n          tokenMap[coinSellSymbol].precision,\n          tokenMap[coinSellSymbol].precision,\n          tokenMap[coinSellSymbol].precision,\n          false,\n          { floor: false, isAbbreviate: true },\n        )} ${coinSellSymbol}`,\n      }\n    } else if (\n      sdk\n        .toBig(tradeStake?.sellVol)\n        .gt(tradeStake?.deFiSideCalcData?.stakeViewInfo?.maxSellVol ?? 0)\n    ) {\n      return {\n        tradeBtnStatus: TradeBtnStatus.DISABLED,\n        label: `labelDefiMax| ${getValuePrecisionThousand(\n          sdk.toBig(tradeStake?.deFiSideCalcData?.stakeViewInfo?.maxSellAmount ?? 0),\n          tokenMap[coinSellSymbol].precision,\n          tokenMap[coinSellSymbol].precision,\n          tokenMap[coinSellSymbol].precision,\n          false,\n          { floor: false, isAbbreviate: true },\n        )} ${coinSellSymbol}`,\n      }\n    } else if (\n      tradeStake?.deFiSideCalcData?.coinSell?.tradeValue &&\n      sdk\n        .toBig(tradeStake.deFiSideCalcData.coinSell.tradeValue)\n        .gt(tradeStake.deFiSideCalcData?.coinSell.balance ?? 0)\n    ) {\n      return {\n        tradeBtnStatus: TradeBtnStatus.DISABLED,\n        label: `labelStakeNoEnough| ${coinSellSymbol}`,\n      }\n    } else if (stakeInfo && hasNoLockingPos && !daysInput) {\n      return {\n        tradeBtnStatus: TradeBtnStatus.DISABLED,\n        label: 'input days please',\n      }\n    } else if (stakeInfo && hasNoLockingPos && !daysInputValid) {\n      return {\n        tradeBtnStatus: TradeBtnStatus.DISABLED,\n        label: 'Days should be between 15 and 60',\n      }\n    } else if (\n      firstLockingPos && firstLockingPos.claimableTime < Date.now()\n    ) {\n      return {\n        tradeBtnStatus: TradeBtnStatus.DISABLED,\n        label: 'posiotions should be redeemed to lock again',\n      }\n    } else if (\n      firstLockingPos && moment(firstLockingPos.claimableTime).diff(moment(), 'days') < 1\n    ) {\n      return {\n        tradeBtnStatus: TradeBtnStatus.DISABLED,\n        label: 'Less than 1 day to unlcok, locking Disabled',\n      }\n    } else if (settlementStatus === 'notSettled') {\n      return {\n        tradeBtnStatus: TradeBtnStatus.DISABLED,\n        label: 'Settlement is in progress',\n      }\n    } else if (settlementStatus === 'settled') {\n      return {\n        tradeBtnStatus: TradeBtnStatus.DISABLED,\n        label: 'Plese reddem first',\n      }\n    } else if (hasLockingTxNotOnChain) {\n      return {\n        tradeBtnStatus: TradeBtnStatus.DISABLED,\n        label: 'There is a pending transaction, please wait',\n      }\n    } else {\n      return { tradeBtnStatus: TradeBtnStatus.AVAILABLE, label: '' } // label: ''}\n    }\n  }, [tokenMap, coinSellSymbol, daysInput, stakeInfo, hasNoLockingPos, daysInputValid, settlementStatus, firstLockingPos, hasLockingTxNotOnChain])\n  const checked = availableTradeCheck()\n  const btnStatus = isLoading ? TradeBtnStatus.LOADING : checked.tradeBtnStatus\n\n  const onBtnClick = onSubmitBtnClick\n  const [stakingTotal, setStakingTotal] = React.useState<string | undefined>(undefined)\n\n  const stakingAmountRaw =\n    stakeInfo && sellToken\n      ? utils.formatUnits(stakeInfo.totalStaked, sellToken.decimals)\n      : undefined\n  const stakingAmount =\n    stakingAmountRaw && sellToken\n      ? numberFormatThousandthPlace(stakingAmountRaw, {\n          tokenSymbol: sellToken.symbol,\n          fixed: sellToken.precision,\n          removeTrailingZero: true,\n        })\n      : undefined\n  const stakingAmountWithNoSymbol =\n    stakingAmountRaw && sellToken\n      ? numberFormatThousandthPlace(stakingAmountRaw, {\n          fixed: sellToken.precision,\n          removeTrailingZero: true,\n        })\n      : undefined\n\n  const stakingAmountInCurrency =\n    stakingAmountRaw &&\n    sellToken &&\n    tokenPrices[sellToken.symbol] &&\n    getValueInCurrency(new Decimal(stakingAmountRaw).mul(tokenPrices[sellToken.symbol]).toString())\n      ? fiatNumberDisplay(\n          getValueInCurrency(\n            new Decimal(stakingAmountRaw).mul(tokenPrices[sellToken.symbol]).toString(),\n          ),\n          currency,\n        )\n      : undefined\n  const [mintRedeemModalState, setMintRedeemModalState] = React.useState({\n    open: false,\n    mint: {\n      inputValue: '',\n      warningChecked: false,\n      availableToMint: '',\n      minInputAmount: undefined as Decimal | undefined,\n      maxInputAmount: undefined as Decimal | undefined,\n    },\n    redeemErrorMsg: undefined as string | undefined,\n    status: 'notSignedIn' as 'notSignedIn' | 'signingIn' | 'signedIn' | 'minting' | 'redeeming' | 'redeemError',\n  })\n\n\n  \n\n\n  useEffect(() => {\n    if (defaultNetwork && ![sdk.ChainId.TAIKO, sdk.ChainId.TAIKOHEKLA].includes(defaultNetwork)) {\n      new providers.Web3Provider(provider.walletProvider!).send('wallet_switchEthereumChain', [\n        { chainId: sdk.toHex(sdk.ChainId.TAIKO) },\n      ])\n    }\n  }, [defaultNetwork])\n\n  \n  const [previousLockRecord, setPreviousLockRecord] = useState({ status: 'init' } as\n    | { status: 'init' }\n    | { status: 'notFound' }\n    | {\n        TAIKOProfit: string \n        USDTProfit: string \n        redeemAmount: string \n        expirationTime: number\n        status: 'found'\n      })\n\n  \n  const { vaultAccountInfo, updateVaultLayer2 } = useVaultLayer2()\n  const refreshData = async () => {\n    \n    const account = store.getState().account\n    const accountId =\n      account.accountId === -1 ? account._accountIdNotActive ?? -1 : account.accountId\n    if (!accountId || accountId === -1) {\n      setStakeInfo({\n        totalStaked: '0',\n        stakingReceivedLocked: [],\n      })\n      // refresh account \n      accountServices.sendCheckAccount(account.accAddress)\n      return\n    }\n    \n    LoopringAPI?.defiAPI\n      ?.getTaikoFarmingDepositDurationList({\n        accountId,\n        tokenId: sellToken?.tokenId,\n        statuses: 'received',\n      })\n      .then((res) => {\n        getStateFnState(setLocalPendingTx).then(localPendingTx => {\n          const found = res.data.find((item) => {\n            return item.txHash === localPendingTx?.txHash\n          })\n          if (found) {\n            setLocalPendingTx(undefined)\n          }\n          setPendingDeposits(res.data)\n        })\n      })\n    LoopringAPI?.defiAPI\n      ?.getTaikoFarmingPositionInfo({\n        accountId: accountId,\n      })\n      .then((res) => {\n        const data = res.data\n        setTaikoFarmingAccountStatus(res.account.status)\n        const availableToMint = (data && data[0] && data[0].claimableTotal) ?? '0'\n        const minClaimAmount = (data[0] as any).minClaimAmount as string\n        const maxClaimAmount = (data[0] as any).maxClaimAmount as string\n        setMintRedeemModalState((mintModalState) => ({\n          ...mintModalState,\n          mint: {\n            ...mintModalState.mint,\n            availableToMint: availableToMint,\n            minInputAmount: new Decimal(utils.formatUnits(minClaimAmount, sellToken?.decimals)),\n            maxInputAmount: new Decimal(utils.formatUnits(maxClaimAmount, sellToken?.decimals)),\n          },\n        }))\n        \n        setMintedLRTAIKO(utils.formatUnits(data[0].claimedTotal, sellToken?.decimals))\n        setStakingTotal(data[0].stakedTotal)\n        \n      })\n    LoopringAPI?.defiAPI\n      ?.getTaikoFarmingUserSummary({\n        accountId: accountId,\n        tokenId: sellToken?.tokenId,\n        statuses: 'received,locked',\n      })\n      .then((res) => {\n        setStakeInfo({\n          stakingReceivedLocked: res.staking,\n          totalStaked: res.totalStaked,\n        })\n      })\n\n    account.apiKey && LoopringAPI.defiAPI?.getTaikoFarmingTransactions(\n      {\n        accountId,\n        tokenId: sellToken?.tokenId,\n        limit: 1,\n        types: 'redeem',\n      } as any,\n      account.apiKey,\n    ).then(res => {\n      if (res.transactions.length === 0) {\n        setPreviousLockRecord({ status: 'notFound' })\n      } else if (res.transactions.length > 0){\n        const record = res.transactions[0] as any\n        setPreviousLockRecord({\n          status: 'found',\n          TAIKOProfit: record.amount ? record.amount : '0',\n          USDTProfit: record.portalOfU ? record.portalOfU : '0',\n          redeemAmount: record.amountOut ? record.amountOut : '0',\n          expirationTime: record.lockDuration,\n        })\n      }\n    })\n\n    LoopringAPI?.defiAPI\n      ?.getTaikoFarmingGetRedeem({\n        accountId: accountId,\n        tokenId: sellToken?.tokenId,\n      }, '')\n      .then((res) => {\n        setRealizedAndUnrealized({\n          realizedUSDT: res.profitOfU,\n          unrealizedTaiko: res.profit,\n          redeemAmount: res.redeemAmount\n        })\n      })\n    updateWalletLayer2()\n\n    account.apiKey && updateVaultLayer2({})\n  }\n  const [showLogInToCleanLrTaiko, setShowLogInToCleanLrTaiko] = useState(false)\n\n  const clearState = () => {\n    setShowLogInToCleanLrTaiko(false)\n    setStakingTotal(undefined)\n    setStakeInfo(undefined)\n    setMintRedeemModalState({\n      open: false,\n      mint: {\n        inputValue: '',\n        warningChecked: false,\n        availableToMint: '',\n        minInputAmount: undefined,\n        maxInputAmount: undefined,\n      },\n      status: 'notSignedIn',\n      redeemErrorMsg: undefined,\n    })\n    setLocalPendingTx(undefined)\n    setPendingDeposits(undefined)\n    setRealizedAndUnrealized(undefined)\n    setPreviousLockRecord({ status: 'init' })\n    chargeFee.handleFeeChange({\n      belong: 'ETH',\n      fee: 0,\n      feeRaw: undefined,\n    } as FeeInfo)\n  }\n  React.useEffect(() => {\n    getStakingMap()\n    walletLayer2Service.sendUserUpdate()\n  }, [account.readyState])\n  React.useEffect(() => {\n    clearState()\n    const isTaiko = [sdk.ChainId.TAIKO, sdk.ChainId.TAIKOHEKLA].includes(defaultNetwork)\n    const timer = isTaiko\n      ? setInterval(() => {\n          refreshData()\n        }, 10 * 1000)\n      : undefined\n    isTaiko && refreshData()\n    return () => {\n      timer && clearInterval(timer)\n    }\n  }, [account.accAddress, defaultNetwork, sellToken])\n\n  React.useEffect(() => {\n    const {\n      _router_tradeStake: { tradeStake },\n      invest: {\n        stakingMap: { marketMap: stakingMap },\n      },\n    } = store.getState()\n\n    if (\n      stakingMapStatus === SagaStatus.UNSET &&\n      stakingMap &&\n      stakingMap[coinSellSymbol]?.symbol == coinSellSymbol &&\n      !(tradeStake?.deFiSideCalcData?.coinSell?.belong == coinSellSymbol)\n    ) {\n      resetDefault(true)\n    } else if (stakingMapStatus === SagaStatus.UNSET && stakingMap && !stakingMap[coinSellSymbol]) {\n    }\n    return () => {\n      resetTradeStake()\n      handleOnchange.cancel()\n    }\n  }, [stakingMapStatus])\n  // React.useEffect(() => {\n  //   // if (walletLayer2Status === SagaStatus.UNSET) {\n  //   //   chargeFee.\n  //   // }\n  //   // if (reddemAmount) {\n  //   //   chargeFee.checkFeeIsEnough({\n  //   //     isRequiredAPI: true,\n  //   //     intervalTime: LIVE_FEE_TIMES,\n  //   //     tokenSymbol: sellToken.symbol,\n  //   //     requestType: sdk.OffchainFeeReqType.OFFCHAIN_WITHDRAWAL,\n  //   //     needAmountRefresh: true,\n  //   //     amount: Number(reddemAmount),\n  //   //   })\n  //   // }\n  // }, [reddemAmount, sellToken.symbol])\n\n  \n\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const btnLabel =\n    checked.tradeBtnStatus === TradeBtnStatus.DISABLED\n      ? t(\n          checked.label.split('|')[0],\n          checked.label.split('|') && checked.label.split('|')[1]\n            ? {\n                arg: checked.label.split('|')[1],\n                layer2: L1L2_NAME_DEFINED[network].layer2,\n                l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n              }\n            : {\n                layer2: L1L2_NAME_DEFINED[network].layer2,\n                l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n              },\n        )\n      : t('labelLockTAIKO')\n  const availableToMintFormatted = mintRedeemModalState.mint.availableToMint && sellToken\n    ? utils.formatUnits(mintRedeemModalState.mint.availableToMint, sellToken.decimals)\n    : undefined\n  const isInputInvalid =\n    mintRedeemModalState.mint.inputValue && mintRedeemModalState.mint.maxInputAmount && mintRedeemModalState.mint.minInputAmount &&\n    (new Decimal(mintRedeemModalState.mint.inputValue).lessThan(mintRedeemModalState.mint.minInputAmount) ||\n      new Decimal(mintRedeemModalState.mint.inputValue).greaterThan(Decimal.min(availableToMintFormatted ?? '0', mintRedeemModalState.mint.maxInputAmount)))\n\n  const { goUpdateAccount } = useUpdateAccount()\n  const [feeModalState, setFeeModalState] = useState({\n    open: false,\n  })\n  // const expirationTime = stakeInfo && last(stakeInfo.stakingReceivedLocked) \n  //   ? last(stakeInfo.stakingReceivedLocked)?.claimableTime \n  //   : undefined\n  \n\n  \n  // const expireStatus: 'expired' | 'notExpired' | 'noPosition' =\n  //   taikoFarmingAccountStatus === 0 \n  //     ? walletLayer2 && walletLayer2['TAIKO'] && new Decimal(walletLayer2['TAIKO'].total).gt(0) \n  //       ? 'expired' : 'noPosition'\n  //     : 'notExpired'\n\n  \n      \n  const redeemAmount =\n    settlementStatus === 'settled' && previousLockRecord && previousLockRecord.status === 'found'\n      ? previousLockRecord.redeemAmount\n      : realizedAndUnrealized?.redeemAmount\n\n  \n  const unrealizedTAIKOBN =\n    settlementStatus === 'settled'\n      ? previousLockRecord.status === 'found'\n        ? BigNumber.from(previousLockRecord.TAIKOProfit)\n        : undefined\n      : realizedAndUnrealized && realizedAndUnrealized.unrealizedTaiko\n      ? BigNumber.from(realizedAndUnrealized.unrealizedTaiko)\n      : undefined\n\n  const realizedUSDTBN =\n    settlementStatus === 'settled'\n      ? previousLockRecord.status === 'found'\n        ? BigNumber.from(previousLockRecord.USDTProfit)\n        : undefined\n      : realizedAndUnrealized && realizedAndUnrealized.realizedUSDT\n      ? BigNumber.from(realizedAndUnrealized.realizedUSDT)\n      : undefined\n    // expirationTime !== undefined\n    //   ? expirationTime < Date.now()\n    //     ? 'expired'\n    //     : 'notExpired'\n    //   : 'noPosition'\n\n      // taikoFarmingAccountStatus\n  \n  const daysInputInfo = (stakeInfo && hasNoLockingPos) ? {\n    value: daysInput,\n    onInput: (input) => {\n      if (Number.isInteger(Number(input)) || input === '') {\n        setDaysInput(input)\n      }\n    },\n    disabled: false,\n    unlockTime: moment().add(Number(daysInput), 'days').format('YYYY-MM-DD')\n  } : {\n    value: firstLockingPos \n      ? Math.max(0, moment(firstLockingPos!.claimableTime).diff(moment(), 'days')).toString()\n      : '',\n    onInput: (input) => {\n      if (Number.isInteger(Number(input)) || input === '') {\n        setDaysInput(input)\n      }\n    },\n    disabled: true,\n    unlockTime: stakeInfo?.stakingReceivedLocked && last(stakeInfo!.stakingReceivedLocked)?.claimableTime\n    ? moment(last(stakeInfo!.stakingReceivedLocked)!.claimableTime).format('YYYY-MM-DD')\n    : ''\n    \n  }\n  const { walletProvider } = useAppKitProvider('eip155')\n  const { checkHWAddr} = useWalletInfo()\n  const accountReadyStateCheck = async (activatedCallBack: () => void) => {\n    if (account.readyState === AccountStatus.ACTIVATED) {\n      activatedCallBack()\n    } else if (account.readyState === AccountStatus.LOCKED) {\n      unlockAccount()\n    } else if (account.readyState === AccountStatus.NOT_ACTIVE) {\n      setMintRedeemModalState({\n        ...mintRedeemModalState,\n        open: true,\n        status: 'notSignedIn',\n      })\n    }\n  }\n  const expirationTime =\n    settlementStatus === 'settled'\n      ? previousLockRecord && previousLockRecord.status === 'found'\n        ? previousLockRecord.expirationTime\n        : 0\n      : stakeInfo\n      ? last(stakeInfo.stakingReceivedLocked)?.claimableTime\n      : 0\n  const lrTaikoInUse =\n    tokenMap &&\n    tokenMap['LRTAIKO'] &&\n    vaultAccountInfo?.collateralInfo?.collateralTokenId === tokenMap['LRTAIKO'].tokenId\n  const output = {\n    stakeWrapProps: {\n      disabled: false,\n      buttonDisabled: btnStatus !== TradeBtnStatus.AVAILABLE || !stakeInfo,\n      // || (stakeInfo && hasNoLockingPos && (!daysInputValid || !daysInput)),\n      isJoin: true,\n      isLoading,\n      switchStobEvent: (_isStoB: boolean | ((prevState: boolean) => boolean)) => {},\n      onSubmitClick: onBtnClick as () => void,\n      onChangeEvent: handleOnchange,\n      deFiSideCalcData: tradeStake.deFiSideCalcData,\n      minSellAmount: tradeStake?.deFiSideCalcData?.stakeViewInfo?.minSellAmount,\n      maxSellAmount: tradeStake?.deFiSideCalcData?.stakeViewInfo?.maxSellAmount,\n      tokenSell: {\n        ...tokenMap[coinSellSymbol],\n        decimals: tradeStake?.deFiSideCalcData?.stakeViewInfo?.decimals,\n        precision: tradeStake?.deFiSideCalcData?.stakeViewInfo?.precision,\n      },\n      btnStatus,\n      accStatus: account.readyState,\n      btnLabel: btnLabel,\n      lockedPosition:\n        stakingTotal && new Decimal(stakingTotal).gt(0)\n          ? {\n              amount: stakingAmount,\n              amountInCurrency: stakingAmountInCurrency,\n              trailblazerBooster: '60x',\n            }\n          : undefined,\n      taikoFarmingChecked,\n      showMultiplier: stakeInfo && hasNoLockingPos,\n      onCheckBoxChange,\n      lockTaikoPlaceholder: tradeStake?.deFiSideCalcData?.stakeViewInfo?.minSellAmount\n        ? `≥ ${tradeStake?.deFiSideCalcData?.stakeViewInfo?.minSellAmount}`\n        : '',\n      daysInput: daysInputInfo,\n      myPosition: {\n        totalAmount: (() => {\n          const amountBN =\n            settlementStatus === 'settled'\n              ? previousLockRecord &&\n                previousLockRecord.status === 'found' &&\n                previousLockRecord.redeemAmount\n              : stakingTotal\n          return amountBN && sellToken\n            ? numberFormatThousandthPlace(utils.formatUnits(amountBN, sellToken.decimals), {\n                fixed: sellToken.precision,\n                removeTrailingZero: true,\n                fixedRound: Decimal.ROUND_DOWN,\n              })\n            : '--'\n        })(),\n        totalAmountInCurrency: stakingAmountInCurrency,\n        positions:\n          stakeInfo &&\n          stakeInfo.stakingReceivedLocked.map((stake) => {\n            const tokenInfo = tokenMap[coinSellSymbol]\n            const lockingDays = Math.floor(\n              (stake.claimableTime - stake.stakeAt) / (1000 * 60 * 60 * 24),\n            )\n\n            return {\n              amount: numberFormatThousandthPlace(\n                utils.formatUnits(stake.initialAmount, tokenInfo.decimals),\n                {\n                  fixed: tokenInfo.precision,\n                  removeTrailingZero: true,\n                },\n              ),\n              unlocked: stake.status !== 'locked',\n              lockingDays,\n              unlockTime: stake.claimableTime\n                ? moment(stake.claimableTime).format('YYYY-MM-DD')\n                : '',\n              multiplier: lockingDays + 'x',\n            }\n          }),\n        expirationTime,\n        totalAmountWithNoSymbol: stakingAmountWithNoSymbol,\n        realizedUSDT: realizedUSDTBN\n          ? numberFormatThousandthPlace(utils.formatUnits(realizedUSDTBN, 6), {\n              fixed: 2,\n              removeTrailingZero: true,\n              fixedRound: Decimal.ROUND_DOWN,\n            }) + ' USDT'\n          : '--',\n        unrealizedTAIKO: unrealizedTAIKOBN && sellToken\n          ? numberFormatThousandthPlace(utils.formatUnits(unrealizedTAIKOBN, sellToken.decimals), {\n              fixed: sellToken.precision,\n              removeTrailingZero: true,\n              fixedRound: Decimal.ROUND_UP,\n            }) + ' TAIKO'\n          : '--',\n        settlementStatus,\n        showMyPosition: !(\n          (taikoFarmingAccountStatus === undefined || taikoFarmingAccountStatus === 0) &&\n          account.readyState !== AccountStatus.ACTIVATED\n        ),\n      },\n      mintButton: {\n        onClick: async () => {\n          accountReadyStateCheck(() => {\n            setMintRedeemModalState({\n              ...mintRedeemModalState,\n              open: true,\n              status: 'minting',\n            })\n          })\n        },\n        disabled: !(\n          settlementStatus === 'minting' &&\n          expirationTime &&\n          expirationTime > Date.now()\n        ),\n      },\n      redeemButton: {\n        onClick: () => {\n          accountReadyStateCheck(() => {\n            if (\n              previousLockRecord &&\n              previousLockRecord.status === 'found' &&\n              previousLockRecord.redeemAmount &&\n              ethers.BigNumber.from(previousLockRecord.redeemAmount).gt('0')\n            ) {\n              setMintRedeemModalState({\n                ...mintRedeemModalState,\n                open: true,\n                status: 'redeeming',\n              })\n            } else if (lrTaikoInUse) {\n              setMintRedeemModalState({\n                ...mintRedeemModalState,\n                open: true,\n                status: 'redeeming',\n              })\n            } else {\n              setMintRedeemModalState({\n                ...mintRedeemModalState,\n                open: true,\n                status: 'redeemError',\n                redeemErrorMsg: 'No TAIKO to Redeem',\n              })\n            }\n          })\n        },\n        disabled: !(\n          ['settled', 'notSettled', 'minting'].includes(settlementStatus) &&\n          expirationTime &&\n          expirationTime < Date.now()\n        ),\n      },\n      taikoCoinJSON: coinJson['TAIKO'],\n      mintRedeemModal: {\n        redeem: {\n          redeemAmount: holdingTAIKO && sellToken\n            ? numberFormatThousandthPlace(utils.formatUnits(holdingTAIKO, sellToken.decimals), {\n                fixed: sellToken.precision,\n                removeTrailingZero: true,\n              }) +\n              ' ' +\n              sellToken.symbol\n            : '--',\n          lrTaikoInUse,\n          lockedTaikoAmount:\n            previousLockRecord && previousLockRecord.status === 'found' && sellToken\n              ? numberFormatThousandthPlace(\n                  utils.formatUnits(\n                    ethers.BigNumber.from(previousLockRecord.redeemAmount).sub(\n                      previousLockRecord.TAIKOProfit,\n                    ),\n                    sellToken.decimals,\n                  ),\n                  {\n                    fixed: sellToken.precision,\n                    removeTrailingZero: true,\n                  },\n                ) + ' TAIKO'\n              : '--',\n          pnlAmount:\n            holdingLRTAIKO && mintedLRTAIKO && sellToken\n              ? `${\n                  new Decimal(holdingLRTAIKO).sub(mintedLRTAIKO).isPos() ? '+' : '-'\n                }${numberFormatThousandthPlace(\n                  new Decimal(holdingLRTAIKO).sub(mintedLRTAIKO).abs().toString(),\n                  { fixed: sellToken.precision, removeTrailingZero: true },\n                )}`\n              : '--',\n          onClickConfirm: async () => {\n            Promise.resolve('')\n              .then(async () => {\n                setShowAccount({\n                  isShow: true,\n                  step: AccountStep.Taiko_Farming_Redeem_In_Progress,\n                  info: {\n                    amount: numberFormatThousandthPlace(\n                      utils.formatUnits(holdingTAIKO!, sellToken!.decimals),\n                      {\n                        fixed: sellToken!.precision,\n                        removeTrailingZero: true,\n                      },\n                    ),\n                  },\n                })\n                if (!exchangeInfo) {\n                  throw new Error('No exchangeInfo')\n                }\n                const storageId = await LoopringAPI.userAPI?.getNextStorageId(\n                  {\n                    accountId: account.accountId,\n                    sellTokenId: sellToken!.tokenId,\n                  },\n                  account.apiKey,\n                )\n                if (!storageId) {\n                  throw new Error('No storageId')\n                }\n                let isHWAddr = checkHWAddr(account.accAddress)\n                const tokenVolume =\n                  chargeFee.feeInfo.__raw__.tokenId === sellToken!.tokenId\n                    ? ethers.BigNumber.from(holdingTAIKO!)\n                        .sub(chargeFee.feeInfo.__raw__.feeRaw)\n                        .toString()\n                    : holdingTAIKO!.toString()\n                const request: sdk.OffChainWithdrawalRequestV3 = {\n                  exchange: exchangeInfo.exchangeAddress,\n                  owner: account.accAddress,\n                  to: account.accAddress,\n                  accountId: account.accountId,\n                  storageId: storageId?.offchainId,\n                  token: {\n                    tokenId: sellToken!.tokenId,\n                    volume: tokenVolume,\n                  },\n                  maxFee: {\n                    tokenId: chargeFee.feeInfo.__raw__.tokenId,\n                    volume: chargeFee.feeInfo.__raw__.feeRaw,\n                  },\n                  fastWithdrawalMode: false,\n                  extraData: '',\n                  minGas: 0,\n                  validUntil: getTimestampDaysLater(DAYS),\n                }\n                return LoopringAPI.userAPI?.submitOffchainWithdraw(\n                  {\n                    request: {\n                      ...request,\n                    },\n                    web3: new Web3(walletProvider as any),\n                    chainId: defaultNetwork,\n                    walletType: sdk.ConnectorNames.Unknown,\n                    eddsaKey: account.eddsaKey.sk,\n                    apiKey: account.apiKey,\n                    isHWAddr,\n                  },\n                  {\n                    accountId: account.accountId,\n                    counterFactualInfo: account.eddsaKey.counterFactualInfo,\n                  },\n                )\n              })\n              .then((res) => {\n                if (res?.code) {\n                  throw new Error(res.message)\n                }\n                setShowAccount({\n                  isShow: true,\n                  step: AccountStep.Taiko_Farming_Redeem_Success,\n                  info: {\n                    amount: numberFormatThousandthPlace(\n                      utils.formatUnits(holdingTAIKO!, sellToken!.decimals),\n                      {\n                        fixed: sellToken!.precision,\n                        removeTrailingZero: true,\n                      },\n                    ),\n                    redeemAt: Date.now(),\n                  },\n                })\n                updateWalletLayer2()\n                setMintRedeemModalState((state) => ({\n                  ...state,\n                  open: false,\n                }))\n              })\n              .catch((e) => {\n                setShowAccount({\n                  isShow: true,\n                  step: AccountStep.Taiko_Farming_Redeem_Failed,\n                  error: e,\n                })\n              })\n          },\n          fee: chargeFee.feeInfo.fee + ' ' + chargeFee.feeInfo.belong,\n          onClickFee: () => {\n            setFeeModalState({\n              ...feeModalState,\n              open: true,\n            })\n          },\n          readlizedUSDT: realizedUSDTBN\n            ? numberFormatThousandthPlace(utils.formatUnits(realizedUSDTBN, 6), {\n                fixed: 2,\n                removeTrailingZero: true,\n              }) + ' USDT'\n            : '--',\n          unrealizedTAIKO: unrealizedTAIKOBN && sellToken\n            ? numberFormatThousandthPlace(\n                utils.formatUnits(unrealizedTAIKOBN, sellToken.decimals),\n                { fixed: sellToken!.precision, removeTrailingZero: true },\n              ) + ' TAIKO'\n            : '--',\n        },\n        onClickSignIn: async () => {\n          setMintRedeemModalState({\n            ...mintRedeemModalState,\n            status: 'signingIn',\n          })\n          const feeInfo = await LoopringAPI?.globalAPI?.getActiveFeeInfo({\n            accountId: account._accountIdNotActive,\n          })\n          const { userBalances } = await LoopringAPI?.globalAPI?.getUserBalanceForFee({\n            accountId: account._accountIdNotActive!,\n            tokens: '',\n          })\n          const found = Object.keys(feeInfo.fees).find((key) => {\n            const fee = feeInfo.fees[key].fee\n            const foundBalance = userBalances[feeInfo.fees[key].tokenId]\n            return (\n              (foundBalance && sdk.toBig(foundBalance.total).gte(fee)) || sdk.toBig(fee).eq('0')\n            )\n          })\n          await goUpdateAccount({\n            isFirstTime: true,\n            isReset: false,\n            // @ts-ignore\n            feeInfo: {\n              token: feeInfo.fees[found!].fee,\n              belong: found!,\n              fee: feeInfo.fees[found!].fee,\n              feeRaw: feeInfo.fees[found!].fee,\n            },\n          })\n            .then(() => {\n              setMintRedeemModalState({\n                ...mintRedeemModalState,\n                status: 'signedIn',\n              })\n            })\n            .catch(() => {\n              setMintRedeemModalState({\n                ...mintRedeemModalState,\n                status: 'notSignedIn',\n              })\n            })\n        },\n        onClickMint: () => {\n          setMintRedeemModalState({\n            ...mintRedeemModalState,\n            status: 'minting',\n          })\n        },\n        open: mintRedeemModalState.open,\n        onClose: () => {\n          setMintRedeemModalState({\n            ...mintRedeemModalState,\n            open: false,\n          })\n        },\n        onClickMax: () => {\n          setMintRedeemModalState({\n            ...mintRedeemModalState,\n            mint: {\n              ...mintRedeemModalState.mint,\n              inputValue: utils.formatUnits(\n                mintRedeemModalState.mint.availableToMint,\n                sellToken!.decimals,\n              ),\n            },\n          })\n        },\n        mintWarningChecked: mintRedeemModalState.mint.warningChecked,\n        // mintWarningText: t('labelTaikoFarmingMintWarningText'),\n        onWarningCheckBoxChange: () => {\n          setMintRedeemModalState({\n            ...mintRedeemModalState,\n            mint: {\n              ...mintRedeemModalState.mint,\n              warningChecked: !mintRedeemModalState.mint.warningChecked,\n            },\n          })\n        },\n        onConfirmBtnClicked: async () => {\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.Taiko_Farming_Mint_In_Progress,\n            info: {\n              symbol: 'lrTAIKO',\n              amount: numberFormatThousandthPlace(mintRedeemModalState.mint.inputValue, {\n                fixed: 18,\n                removeTrailingZero: true,\n              }),\n              mintAt: Date.now(),\n            },\n          })\n\n          const res = await submitTaikoFarmingMint({\n            amount: utils.parseUnits(mintRedeemModalState.mint.inputValue, sellToken!.decimals),\n            accountId: account.accountId,\n            apiKey: account.apiKey,\n            exchangeAddress: exchangeInfo!.exchangeAddress,\n            tokenId: sellToken!.tokenId,\n            eddsaSk: account.eddsaKey.sk,\n          })\n            .then((res) => {\n              const checkStatus = (hash: string) => {\n                return LoopringAPI.defiAPI\n                  ?.getTaikoFarmingTransactionByHash(\n                    {\n                      accountId: account.accountId,\n                      hash: res!.hash,\n                    },\n                    account.apiKey,\n                  )\n                  .then(async (res2) => {\n                    if (res2!.operation.status === 7) {\n                      throw {\n                        msg: 'error',\n                      }\n                    } else if (res2.operation.status < 7) {\n                      setShowAccount({\n                        isShow: true,\n                        step: AccountStep.Taiko_Farming_Mint_In_Progress,\n                        info: {\n                          symbol: sellToken!.symbol,\n                          amount: numberFormatThousandthPlace(\n                            mintRedeemModalState.mint.inputValue,\n                            {\n                              fixed: sellToken!.precision,\n                              removeTrailingZero: true,\n                            },\n                          ),\n                        },\n                      })\n                      await sdk.sleep(5 * 1000)\n                      if (\n                        store.getState().modals.isShowAccount.isShow &&\n                        store.getState().modals.isShowAccount.step ===\n                          AccountStep.Taiko_Farming_Mint_In_Progress\n                      ) {\n                        return checkStatus(hash)\n                      }\n                    } else {\n                      setShowAccount({\n                        isShow: true,\n                        step: AccountStep.Taiko_Farming_Mint_Success,\n                        info: {\n                          symbol: 'lrTAIKO',\n                          amount: numberFormatThousandthPlace(\n                            mintRedeemModalState.mint.inputValue,\n                            {\n                              fixed: 18,\n                              removeTrailingZero: true,\n                            },\n                          ),\n                          mintAt: Date.now(),\n                        },\n                      })\n                      setMintRedeemModalState({\n                        ...mintRedeemModalState,\n                        mint: {\n                          ...mintRedeemModalState.mint,\n                          inputValue: '',\n                          warningChecked: false,\n                        },\n                      })\n                    }\n                  })\n              }\n              return checkStatus(res!.hash)\n            })\n            .catch((e) => {\n              setShowAccount({\n                isShow: true,\n                step: AccountStep.Taiko_Farming_Mint_Failed,\n                info: {\n                  error: e,\n                },\n              })\n            })\n            .finally(() => {\n              refreshData()\n            })\n        },\n        onInput: (input: string) => {\n          if (\n            stakingMap && \n            stakingMap[coinSellSymbol] &&\n            (isNumberStr(input) && strNumDecimalPlacesLessThan(input, stakingMap[coinSellSymbol].precision + 1)) ||\n            input === ''\n          ) {\n            setMintRedeemModalState({\n              ...mintRedeemModalState,\n              mint: {\n                ...mintRedeemModalState.mint,\n                inputValue: input,\n              },\n            })\n          }\n        },\n        inputValue: mintRedeemModalState.mint.inputValue,\n        confirmBtnDisabled:\n          !isNumberStr(mintRedeemModalState.mint.inputValue) ||\n          !mintRedeemModalState.mint.warningChecked ||\n          !mintRedeemModalState.mint.availableToMint ||\n          new Decimal(availableToMintFormatted!).eq('0') ||\n          isInputInvalid\n            ? true\n            : false,\n        confirmBtnWording:\n          isInputInvalid || !mintRedeemModalState.mint.inputValue\n            ? availableToMintFormatted &&\n              mintRedeemModalState.mint.minInputAmount &&\n              mintRedeemModalState.mint.maxInputAmount &&\n              Decimal.min(mintRedeemModalState.mint.maxInputAmount, availableToMintFormatted).gte(\n                mintRedeemModalState.mint.minInputAmount,\n              )\n              ? `Please input between ${mintRedeemModalState.mint.minInputAmount.toString()} - ${Decimal.min(\n                  mintRedeemModalState.mint.maxInputAmount,\n                  availableToMintFormatted,\n                ).toString()}`\n              : 'Invalid amount'\n            : !mintRedeemModalState.mint.warningChecked\n            ? 'Please check checkbox'\n            : 'Confirm',\n        tokenAvailableAmount: availableToMintFormatted ? availableToMintFormatted : '--',\n        inputPlaceholder:\n          mintRedeemModalState.mint.minInputAmount && mintRedeemModalState.mint.maxInputAmount\n            ? availableToMintFormatted &&\n              Decimal.min(mintRedeemModalState.mint.maxInputAmount, availableToMintFormatted).gte(\n                mintRedeemModalState.mint.minInputAmount,\n              )\n              ? `${mintRedeemModalState.mint.minInputAmount.toString()} - ${Decimal.min(\n                  mintRedeemModalState.mint.maxInputAmount,\n                  availableToMintFormatted,\n                ).toString()}`\n              : `≥ ${mintRedeemModalState.mint.minInputAmount.toString()}`\n            : '',\n        status: mintRedeemModalState.status,\n        redeemErrorMsg: mintRedeemModalState.redeemErrorMsg,\n      },\n      feeModal: {\n        ...chargeFee,\n        isFeeNotEnough: chargeFee.isFeeNotEnough.isFeeNotEnough,\n        open: feeModalState.open,\n        onClose: () => {\n          setFeeModalState({\n            ...feeModalState,\n            open: false,\n          })\n        },\n        onClickFee: () => {\n          setFeeModalState({\n            ...feeModalState,\n            open: true,\n          })\n        },\n        handleToggleChange: (fee) => {\n          chargeFee.handleFeeChange(fee)\n        },\n        feeLoading: false,\n      },\n      txSubmitModal: {\n        open: txSubmitModalState.open,\n        onClose: () => {\n          setTxSubmitModalState({\n            open: false,\n            status: 'init',\n          })\n        },\n        status: txSubmitModalState.status,\n      },\n      hasPendingDeposits: pendingDepositsMergeLocal && pendingDepositsMergeLocal.length > 0,\n      onClickPendingDeposits: () => {\n        setPendingTxsModalOpen(true)\n      },\n      pendingTxsModal: {\n        open: pendingTxsModalOpen,\n        onClose: () => {\n          setPendingTxsModalOpen(false)\n        },\n        pendingTxs: pendingDepositsMergeLocal?.map((tx) => {\n          return {\n            hash: tx.txHash,\n            amount: numberFormatThousandthPlace(\n              utils.formatUnits((tx as any).amount as string, sellToken!.decimals),\n              {\n                fixed: sellToken!.precision,\n                removeTrailingZero: true,\n              },\n            ),\n            symbol: sellToken!.symbol,\n            isLocal: tx.isLocal,\n          }\n        }),\n        onClickLocking: () => {\n          setTxSubmitModalState({\n            open: true,\n            status: 'depositing',\n          })\n        },\n      },\n      lrTAIKOTradeEarnSummary: mintedLRTAIKO &&\n        holdingLRTAIKO && sellToken && {\n          holdingAmount: numberFormatThousandthPlace(holdingLRTAIKO, {\n            fixed: sellToken.precision,\n            removeTrailingZero: true,\n          }),\n          mintedAmount: numberFormatThousandthPlace(mintedLRTAIKO, {\n            fixed: sellToken.precision,\n            removeTrailingZero: true,\n          }),\n          pnl: `${\n            new Decimal(holdingLRTAIKO).sub(mintedLRTAIKO).isPos() ? '+' : '-'\n          }${numberFormatThousandthPlace(\n            new Decimal(holdingLRTAIKO).sub(mintedLRTAIKO).abs().toString(),\n            { fixed: sellToken.precision, removeTrailingZero: true },\n          )} TAIKO`,\n          // pnl: `--`,\n        },\n      logInToCleanLrTaikoModal: {\n        open: showLogInToCleanLrTaiko,\n        onClose: () => {\n          setShowLogInToCleanLrTaiko(false)\n        },\n        onClickSignIn: () => {\n          unlockAccount()\n          setShowLogInToCleanLrTaiko(false)\n        },\n      }\n      \n    },\n  }\n  return output\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/useTransfer.ts",
    "content": "import React from 'react'\n\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nimport { ConnectProviders, connectProvides } from '@loopring-web/web3-provider'\n\nimport {\n  AccountStep,\n  SwitchData,\n  TransferProps,\n  useOpenModals,\n  useSettings,\n} from '@loopring-web/component-lib'\nimport {\n  AccountStatus,\n  AddressError,\n  CoinMap,\n  CurrencyToTag,\n  EmptyValueTag,\n  EXCHANGE_TYPE,\n  Explorer,\n  FeeInfo,\n  getValuePrecisionThousand,\n  IBData,\n  LIVE_FEE_TIMES,\n  myLog,\n  PriceTag,\n  SagaStatus,\n  SUBMIT_PANEL_AUTO_CLOSE,\n  TRADE_TYPE,\n  UIERROR_CODE,\n  WALLET_TYPE,\n  WalletMap,\n} from '@loopring-web/common-resources'\n\nimport {\n  BIGO,\n  DAYS,\n  getTimestampDaysLater,\n  isAccActivated,\n  LAST_STEP,\n  LoopringAPI,\n  makeWalletLayer2,\n  store,\n  useAccount,\n  useAddressCheck,\n  useBtnStatus,\n  useChargeFees,\n  useModalData,\n  useSystem,\n  useTokenMap,\n  useTokenPrices,\n  useWalletLayer2Socket,\n  volumeToCountAsBigNumber,\n  walletLayer2Service,\n} from '../../index'\nimport { useWalletInfo } from '../../stores/localStore/walletInfo'\nimport { addressToExWalletMapFn, exWalletToAddressMapFn } from '@loopring-web/core'\nimport { NETWORKEXTEND, useContacts } from '../../stores'\n\nexport const useTransfer = <R extends IBData<T>, T>() => {\n  const { setShowAccount, setShowTransfer } = useOpenModals()\n\n  const {\n    setShowEditContact,\n    modals: {\n      isShowTransfer: {\n        symbol,\n        isShow,\n        info,\n        address: contactAddress,\n        name: contactName,\n        addressType: contactAddressType,\n      },\n    },\n  } = useOpenModals()\n  const { tokenMap, totalCoinMap } = useTokenMap()\n  const { account, status: accountStatus } = useAccount()\n  const { exchangeInfo, chainId, forexMap } = useSystem()\n  const { currency } = useSettings()\n  const { tokenPrices } = useTokenPrices()\n  const {\n    contacts,\n    status: contactStatus,\n    errorMessage: contactsErrorMessage,\n    updateContacts,\n  } = useContacts()\n\n  const { transferValue, updateTransferData, resetTransferData } = useModalData()\n\n  const [walletMap, setWalletMap] = React.useState(\n    makeWalletLayer2({ needFilterZero: true }).walletMap ?? ({} as WalletMap<R>),\n  )\n\n  const [sureItsLayer2, setSureItsLayer2] = React.useState<WALLET_TYPE | EXCHANGE_TYPE | undefined>(\n    undefined,\n  )\n\n  const { btnStatus, enableBtn, disableBtn } = useBtnStatus()\n  const [feeWithActive, setFeeWithActive] = React.useState(false)\n\n  const {\n    chargeFeeTokenList,\n    isFeeNotEnough,\n    handleFeeChange,\n    feeInfo,\n    checkFeeIsEnough,\n    resetIntervalTime,\n    resetFee,\n  } = useChargeFees({\n    requestType: feeWithActive\n      ? sdk.OffchainFeeReqType.TRANSFER_AND_UPDATE_ACCOUNT\n      : sdk.OffchainFeeReqType.TRANSFER,\n    updateData: ({ fee, requestType }) => {\n      let _requestType = feeWithActive\n        ? sdk.OffchainFeeReqType.TRANSFER_AND_UPDATE_ACCOUNT\n        : sdk.OffchainFeeReqType.TRANSFER\n      if (_requestType === requestType) {\n        const transferValue = store.getState()._router_modalData.transferValue\n        updateTransferData({ ...transferValue, fee })\n      }\n    },\n    //   [feeWithActive]\n    // ),\n  })\n  const {\n    chargeFeeTokenList: activeAccountFeeList,\n    checkFeeIsEnough: checkActiveFeeIsEnough,\n    // resetIntervalTime: resetActiveIntervalTime,\n  } = useChargeFees({\n    isActiveAccount: true,\n    requestType: undefined as any,\n  })\n  const handleOnMemoChange = React.useCallback(\n    (e: React.ChangeEvent<HTMLInputElement>) => {\n      const transferValue = store.getState()._router_modalData.transferValue\n      updateTransferData({\n        ...transferValue,\n        memo: e.target.value,\n      })\n    },\n    [updateTransferData],\n  )\n\n  const {\n    address,\n    realAddr,\n    setAddress,\n    addrStatus,\n    isLoopringAddress,\n    isActiveAccount,\n    isAddressCheckLoading,\n    isActiveAccountFee,\n    isSameAddress,\n    isContractAddress,\n    loopringSmartWalletVersion,\n    reCheck,\n    isENSWrong,\n    ens,\n  } = useAddressCheck(true)\n\n  React.useEffect(() => {\n    if (loopringSmartWalletVersion?.isLoopringSmartWallet && sureItsLayer2 === undefined) {\n      setSureItsLayer2(WALLET_TYPE.Loopring)\n    }\n  }, [loopringSmartWalletVersion?.isLoopringSmartWallet])\n\n  const checkBtnStatus = React.useCallback(() => {\n    if (tokenMap && transferValue.belong && tokenMap[transferValue.belong]) {\n      const sellToken = tokenMap[transferValue.belong]\n      const tradeValue = sdk.toBig(transferValue.tradeValue ?? 0).times('1e' + sellToken.decimals)\n      const isEnough = tradeValue.lte(\n        sdk.toBig(transferValue.balance ?? 0).times('1e' + sellToken.decimals),\n      )\n      const contact = contacts?.find((x) => x.contactAddress === realAddr)\n      const ensHasCheck = (contact?.ens || ens) \n        ? !isENSWrong \n        : true\n      if (\n        tradeValue &&\n        chargeFeeTokenList.length &&\n        !isFeeNotEnough.isFeeNotEnough &&\n        !isSameAddress &&\n        ensHasCheck &&\n        isEnough &&\n        sureItsLayer2 &&\n        transferValue.fee?.belong &&\n        tradeValue.gt(BIGO) &&\n        ((address && address.startsWith('0x')) || realAddr) &&\n        (addrStatus as AddressError) === AddressError.NoError\n      ) {\n        enableBtn()\n        return\n      }\n    }\n\n    disableBtn()\n  }, [\n    realAddr,\n    tokenMap,\n    transferValue,\n    disableBtn,\n    sureItsLayer2,\n    chargeFeeTokenList.length,\n    isFeeNotEnough,\n    isSameAddress,\n    address,\n    addrStatus,\n    enableBtn,\n    contacts,\n  ])\n\n  React.useEffect(() => {\n    checkBtnStatus()\n  }, [\n    realAddr,\n    chargeFeeTokenList,\n    address,\n    sureItsLayer2,\n    isFeeNotEnough.isFeeNotEnough,\n    isAddressCheckLoading,\n    transferValue,\n    addrStatus,\n  ])\n\n  const walletLayer2Callback = React.useCallback(() => {\n    const walletMap = makeWalletLayer2({ needFilterZero: true }).walletMap ?? {}\n    setWalletMap(walletMap)\n  }, [])\n\n  useWalletLayer2Socket({ walletLayer2Callback })\n\n  const resetDefault = React.useCallback(() => {\n    if (info?.isRetry) {\n      checkFeeIsEnough()\n      return\n    }\n    checkFeeIsEnough({ isRequiredAPI: true, intervalTime: LIVE_FEE_TIMES })\n    if (contactsErrorMessage) {\n      updateContacts()\n    }\n    if (symbol && walletMap) {\n      myLog('resetDefault symbol:', symbol)\n      updateTransferData({\n        fee: feeInfo,\n        belong: symbol as any,\n        balance: walletMap[symbol]?.count,\n        tradeValue: undefined,\n        address: '*',\n        memo: '',\n      })\n    } else {\n      if (!transferValue.belong && walletMap) {\n        const keys = Reflect.ownKeys(walletMap)\n        for (let key in keys) {\n          const keyVal = keys[key]\n          const walletInfo = walletMap[keyVal]\n          if (sdk.toBig(walletInfo.count).gt(0)) {\n            updateTransferData({\n              belong: keyVal as any,\n              tradeValue: undefined,\n              fee: feeInfo,\n              balance: walletInfo?.count,\n              address: '*',\n              memo: '',\n            })\n            break\n          }\n        }\n      } else if (transferValue.belong && walletMap) {\n        const walletInfo = walletMap[transferValue.belong]\n        updateTransferData({\n          fee: feeInfo,\n          belong: transferValue.belong,\n          tradeValue: undefined,\n          balance: walletInfo?.count,\n          address: info?.isToMyself ? account.accAddress : '*',\n          memo: '',\n        })\n      } else {\n        updateTransferData({\n          fee: feeInfo,\n          belong: transferValue.belong,\n          tradeValue: undefined,\n          balance: undefined,\n          address: info?.isToMyself ? account.accAddress : '*',\n          memo: '',\n        })\n      }\n    }\n\n    if (contactAddress) {\n      setAddress(contactAddress)\n    } else {\n      setAddress('')\n    }\n  }, [\n    info?.isRetry,\n    info?.isToMyself,\n    checkFeeIsEnough,\n    contactsErrorMessage,\n    symbol,\n    walletMap,\n    contactAddress,\n    updateContacts,\n    updateTransferData,\n    feeInfo,\n    transferValue.belong,\n    account.accAddress,\n    setAddress,\n  ])\n\n  React.useEffect(() => {\n    if (\n      isShow &&\n      accountStatus === SagaStatus.UNSET &&\n      account.readyState === AccountStatus.ACTIVATED\n    ) {\n      resetDefault()\n      resetFee()\n    } else {\n      resetIntervalTime()\n      checkActiveFeeIsEnough({\n        isRequiredAPI: true,\n        requestType: undefined as any,\n      })\n    }\n    return () => {\n      resetIntervalTime()\n      setAddress('')\n      checkActiveFeeIsEnough({\n        isRequiredAPI: true,\n        requestType: undefined as any,\n      })\n    }\n  }, [isShow])\n\n  const { checkHWAddr, updateHW } = useWalletInfo()\n\n  const [lastRequest, setLastRequest] = React.useState<any>({})\n\n  const processRequest = React.useCallback(\n    async (request: sdk.OriginTransferRequestV3, isNotHardwareWallet: boolean) => {\n      const { apiKey, connectName, eddsaKey } = account\n\n      try {\n        if (connectProvides.usedWeb3 && LoopringAPI.userAPI && isAccActivated()) {\n          let isHWAddr = checkHWAddr(account.accAddress)\n          if (!isHWAddr && !isNotHardwareWallet) {\n            isHWAddr = true\n          }\n          setLastRequest({ request })\n          const response = await LoopringAPI.userAPI.submitInternalTransfer(\n            {\n              request,\n              web3: connectProvides.usedWeb3 as any,\n              chainId: chainId === NETWORKEXTEND.NONETWORK ? sdk.ChainId.MAINNET : chainId,\n              walletType: (ConnectProviders[connectName] ??\n                connectName) as unknown as sdk.ConnectorNames,\n              eddsaKey: eddsaKey.sk,\n              apiKey,\n              isHWAddr,\n            },\n            {\n              accountId: account.accountId,\n              counterFactualInfo: eddsaKey.counterFactualInfo,\n            },\n          )\n\n          myLog('submitInternalTransfer:', response)\n          if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n            throw response\n          }\n          info?.onCloseCallBack && info?.onCloseCallBack()\n          setShowTransfer({ isShow: false })\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.Transfer_In_Progress,\n          })\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.Transfer_Success,\n            info: {\n              hash: Explorer + `tx/${(response as sdk.TX_HASH_API)?.hash}-transfer`,\n            },\n          })\n          if (isHWAddr) {\n            myLog('......try to set isHWAddr', isHWAddr)\n            updateHW({ wallet: account.accAddress, isHWAddr })\n          }\n          resetTransferData()\n          walletLayer2Service.sendUserUpdate()\n          await sdk.sleep(SUBMIT_PANEL_AUTO_CLOSE)\n          if (\n            store.getState().modals.isShowAccount.isShow &&\n            store.getState().modals.isShowAccount.step == AccountStep.Transfer_Success\n          ) {\n            setShowAccount({ isShow: false })\n          }\n        }\n      } catch (e: any) {\n        const code = sdk.checkErrorInfo(e, isNotHardwareWallet)\n        switch (code) {\n          case sdk.ConnectorError.NOT_SUPPORT_ERROR:\n            setLastRequest({ request })\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.Transfer_First_Method_Denied,\n            })\n            break\n          case sdk.ConnectorError.USER_DENIED:\n          case sdk.ConnectorError.USER_DENIED_2:\n            setLastRequest({ request })\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.Transfer_User_Denied,\n            })\n            break\n\n          default:\n            if ([102024, 102025, 114001, 114002].includes((e as sdk.RESULT_INFO)?.code || 0)) {\n              checkFeeIsEnough({\n                isRequiredAPI: true,\n                requestType: feeWithActive\n                  ? sdk.OffchainFeeReqType.TRANSFER_AND_UPDATE_ACCOUNT\n                  : sdk.OffchainFeeReqType.TRANSFER,\n              })\n            }\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.Transfer_Failed,\n              error: {\n                code: UIERROR_CODE.UNKNOWN,\n                msg: e?.message,\n                ...(e instanceof Error\n                  ? {\n                      message: e?.message,\n                      stack: e?.stack,\n                    }\n                  : e ?? {}),\n              },\n            })\n\n            break\n        }\n      }\n    },\n    [\n      account,\n      checkHWAddr,\n      chainId,\n      info,\n      setShowTransfer,\n      setShowAccount,\n      resetTransferData,\n      updateHW,\n      checkFeeIsEnough,\n      feeWithActive,\n    ],\n  )\n\n  const onTransferClick = React.useCallback(\n    async (_transferValue, isFirstTime: boolean = true) => {\n      const { accountId, accAddress, readyState, apiKey, eddsaKey } = account\n      const transferValue = store.getState()._router_modalData.transferValue\n      if (\n        readyState === AccountStatus.ACTIVATED &&\n        tokenMap &&\n        LoopringAPI.userAPI &&\n        exchangeInfo &&\n        connectProvides.usedWeb3 &&\n        transferValue.address !== '*' &&\n        transferValue?.fee &&\n        transferValue?.fee.belong &&\n        transferValue.fee?.__raw__ &&\n        eddsaKey?.sk\n      ) {\n        try {\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.Transfer_WaitForAuth,\n          })\n\n          const sellToken = tokenMap[transferValue.belong as string]\n          const feeToken = tokenMap[transferValue.fee.belong]\n          const feeRaw = transferValue.fee.feeRaw ?? transferValue.fee.__raw__?.feeRaw ?? 0\n          const fee = sdk.toBig(feeRaw)\n          const balance = sdk.toBig(transferValue.balance ?? 0).times('1e' + sellToken.decimals)\n          const tradeValue = sdk\n            .toBig(transferValue.tradeValue ?? 0)\n            .times('1e' + sellToken.decimals)\n          const isExceedBalance =\n            feeToken.tokenId === sellToken.tokenId && tradeValue.plus(fee).gt(balance)\n          const finalVol = isExceedBalance ? balance.minus(fee) : tradeValue\n          const transferVol = finalVol.toFixed(0, 0)\n\n          const storageId = await LoopringAPI.userAPI?.getNextStorageId(\n            {\n              accountId,\n              sellTokenId: sellToken.tokenId,\n            },\n            apiKey,\n          )\n          const req: sdk.OriginTransferRequestV3 = {\n            exchange: exchangeInfo.exchangeAddress,\n            payerAddr: accAddress,\n            payerId: accountId,\n            payeeAddr: realAddr ? realAddr : address,\n            payeeId: 0,\n            storageId: storageId?.offchainId,\n            payPayeeUpdateAccount: !isActiveAccountFee && feeWithActive,\n            token: {\n              tokenId: sellToken.tokenId,\n              volume: transferVol,\n            },\n            maxFee: {\n              tokenId: feeToken.tokenId,\n              volume: fee.toString(), // TEST: fee.toString(),\n            },\n            validUntil: getTimestampDaysLater(DAYS),\n            memo: transferValue.memo,\n          }\n\n          myLog('transfer req:', req)\n\n          processRequest(req, isFirstTime)\n        } catch (e: any) {\n          // transfer failed\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.Transfer_Failed,\n            error: {\n              code: UIERROR_CODE.UNKNOWN,\n              message: e.message,\n            } as sdk.RESULT_INFO,\n          })\n        }\n      } else {\n        return\n      }\n    },\n    [\n      account,\n      tokenMap,\n      exchangeInfo,\n      setShowAccount,\n      realAddr,\n      address,\n      processRequest,\n      isActiveAccountFee,\n      feeWithActive,\n    ],\n  )\n\n  const handlePanelEvent = React.useCallback(\n    async (data: SwitchData<R>) => {\n      return new Promise<void>((res: any) => {\n        if (data.to === 'button') {\n          if (walletMap && data?.tradeData?.belong) {\n            const walletInfo = walletMap[data?.tradeData?.belong as string]\n            updateTransferData({\n              belong: data.tradeData?.belong,\n              tradeValue: data.tradeData?.tradeValue,\n              balance: walletInfo ? walletInfo.count : 0,\n              address: '*',\n            })\n          } else {\n            updateTransferData({\n              belong: undefined,\n              tradeValue: undefined,\n              balance: undefined,\n              address: '*',\n            })\n          }\n        }\n        res()\n      })\n    },\n    [walletMap, updateTransferData],\n  )\n\n  const retryBtn = React.useCallback(\n    (isHardwareRetry: boolean = false) => {\n      setShowAccount({\n        isShow: true,\n        step: AccountStep.Transfer_WaitForAuth,\n      })\n\n      processRequest(lastRequest, !isHardwareRetry)\n    },\n    [lastRequest, processRequest, setShowAccount],\n  )\n  const activeAccountPrice = React.useMemo(() => {\n    if (\n      realAddr !== '' &&\n      isActiveAccount == false &&\n      activeAccountFeeList.length &&\n      activeAccountFeeList[0] &&\n      tokenPrices &&\n      activeAccountFeeList[0].feeRaw\n    ) {\n      const feeInfo: FeeInfo = activeAccountFeeList[0]\n      const feeU: any =\n        volumeToCountAsBigNumber(feeInfo.belong, feeInfo.feeRaw ?? 0)?.times(\n          tokenPrices[feeInfo.belong],\n        ) ?? undefined\n\n      return feeU && currency && forexMap[currency]\n        ? '～' +\n            PriceTag[CurrencyToTag[currency]] +\n            getValuePrecisionThousand(\n              // @ts-ignore\n              feeU * forexMap[currency],\n              2,\n              2,\n              2,\n              true,\n              { floor: true },\n            )\n        : EmptyValueTag\n    } else {\n      return\n    }\n  }, [realAddr, isActiveAccount, activeAccountFeeList, tokenPrices, currency, forexMap])\n\n  React.useEffect(() => {\n    if (realAddr !== '' && isActiveAccount === false) {\n      checkActiveFeeIsEnough({\n        isRequiredAPI: true,\n        requestType: 'TRANSFER_ACTIVE',\n      })\n    }\n  }, [isActiveAccount, realAddr])\n  const handleSureItsLayer2 = (sure) => {\n    const found = exWalletToAddressMapFn(sure)!\n    const contact = contacts?.find((x) => x.contactAddress === realAddr)\n    if (!account.isContractAddress && contact && contact.addressType !== sure) {\n      LoopringAPI.contactAPI\n        ?.updateContact(\n          {\n            ...contact,\n            isHebao: !!(account.isContractAddress || account.isCFAddress),\n            accountId: account.accountId,\n            addressType: found,\n          },\n          account.apiKey,\n        )\n        .then(() => {\n          updateContacts()\n          reCheck()\n        })\n    }\n    setSureItsLayer2(sure)\n  }\n  React.useEffect(() => {\n    const { contacts } = store.getState().contacts\n    const contact = contacts?.find(\n      (x) => x.contactAddress?.toLowerCase() === realAddr?.toLowerCase(),\n    )\n    if (isShow === false) {\n      setSureItsLayer2(undefined)\n    } else if (contact?.addressType !== undefined) {\n      const found = contact.addressType ? addressToExWalletMapFn(contact.addressType) : undefined\n      setSureItsLayer2((state) => {\n        if (state !== found) {\n          return found\n        } else {\n          return state\n        }\n      })\n    }\n    if (\n      isShow &&\n      contactStatus == SagaStatus.UNSET &&\n      contact &&\n      realAddr?.toLowerCase() == contact?.contactAddress?.toLowerCase()\n    ) {\n      reCheck()\n    }\n  }, [realAddr, isShow, contactStatus])\n\n  const transferProps: TransferProps<any, any> = {\n    contacts,\n    type: TRADE_TYPE.TOKEN,\n    addressDefault: address,\n    realAddr,\n    tradeData: transferValue as any,\n    coinMap: totalCoinMap as CoinMap<T>,\n    walletMap: walletMap as WalletMap<T>,\n    transferBtnStatus: btnStatus,\n    onTransferClick,\n    handlePanelEvent,\n    handleFeeChange,\n    feeInfo,\n    handleSureItsLayer2,\n    lastFailed: store.getState().modals.isShowAccount.info?.lastFailed === LAST_STEP.transfer,\n    // isConfirmTransfer,\n    sureItsLayer2,\n    chargeFeeTokenList,\n    activeAccountPrice,\n    isFeeNotEnough,\n    isLoopringAddress,\n    isSameAddress,\n    isAddressCheckLoading,\n    addrStatus,\n    memo: transferValue.memo ?? '',\n    handleOnMemoChange,\n    handleOnAddressChange: (value: any, isContactSelection?: boolean) => {\n      checkActiveFeeIsEnough({\n        isRequiredAPI: true,\n        requestType: undefined as any,\n      })\n      setAddress((state) => {\n        if (isContactSelection) {\n          const contact = contacts?.find((x) => x.contactAddress === value)\n          const v = contact && addressToExWalletMapFn(contact.addressType)\n          v && setSureItsLayer2(v)\n        } else {\n          setSureItsLayer2(undefined)\n        }\n        if (state !== value || '') {\n          // flag = true;\n          setFeeWithActive((state) => {\n            if (state !== false) {\n              checkFeeIsEnough({\n                isRequiredAPI: true,\n                requestType: sdk.OffchainFeeReqType.TRANSFER,\n              })\n            }\n            return false\n          })\n        }\n\n        return value || ''\n      })\n    },\n    isActiveAccount,\n    isActiveAccountFee,\n    feeWithActive,\n    handleOnFeeWithActive: (value: boolean) => {\n      setFeeWithActive(value)\n      if (value && !isActiveAccountFee) {\n        checkFeeIsEnough({\n          isRequiredAPI: true,\n\n          requestType: sdk.OffchainFeeReqType.TRANSFER_AND_UPDATE_ACCOUNT,\n        })\n      } else {\n        checkFeeIsEnough({\n          isRequiredAPI: true,\n          requestType: sdk.OffchainFeeReqType.TRANSFER,\n        })\n      }\n    },\n    isSmartContractAddress: isContractAddress,\n    isFromContact: contactAddress ? true : false,\n    contact: contactAddress\n      ? contacts?.find((x) => x.contactAddress === contactAddress)\n      : undefined,\n    loopringSmartWalletVersion,\n    isENSWrong,\n    geUpdateContact: () => {\n      if (isENSWrong) {\n        const contact = contacts?.find((x) => x.contactAddress === realAddr)\n        setShowEditContact({\n          isShow: true,\n          info: {\n            ...contact,\n            isENSWrong,\n          },\n        })\n      }\n    },\n    ens,\n    // contacts,\n  }\n\n  return {\n    retryBtn,\n    transferProps,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/useTransferToTaikoAccount.ts",
    "content": "import {\n  AccountStep,\n  TransferToTaikoAccountProps,\n  useOpenModals,\n  useSettings,\n} from '@loopring-web/component-lib'\nimport { store, TokenMap, useAccount, useConfig, useContacts, useSystem, useTokenMap, useWalletLayer2 } from '../../stores'\nimport { useEffect } from 'react'\nimport { useGetSet } from 'react-use'\nimport { LoopringAPI } from '../../api_wrapper'\nimport { Account, MapChainId, NetworkMap, UIERROR_CODE, WalletMap } from '@loopring-web/common-resources'\nimport { ChainId, checkErrorInfo, ConnectorError, ExchangeAPI, OffchainFeeInfo, OffchainFeeReqType, RabbitWithdrawRequest, RESULT_INFO, sleep, TokenInfo } from '@loopring-web/loopring-sdk'\nimport { ethers, utils } from 'ethers'\nimport { getTimestampDaysLater, isValidateNumberStr, numberFormat } from '../../utils'\nimport { makeWalletLayer2, parseRabbitConfig } from '../../hooks/help'\nimport Decimal from 'decimal.js'\nimport { DAYS } from '../../defs'\nimport { useAppKitProvider } from '@reown/appkit/react'\nimport { useDebouncedCallback } from '../../hooks/common'\nimport _ from 'lodash'\nimport { parseRabbitConfig2 } from '../../hooks/help/parseRabbitConfig'\n\nconst offchainFeeInfoToFeeInfo = (offchainFeeInfo: OffchainFeeInfo, tokenMap: TokenMap<{\n  [key: string]: any;\n}>, walletMap: WalletMap<string, any>) => {\n  return {\n    belong: offchainFeeInfo.token,\n    fee: tokenMap[offchainFeeInfo.token] ? ethers.utils.formatUnits(offchainFeeInfo.fee, tokenMap[offchainFeeInfo.token].decimals) : '',\n    feeRaw: offchainFeeInfo.fee,\n    token: offchainFeeInfo.token,\n    hasToken: !!offchainFeeInfo.token,\n    count: walletMap[offchainFeeInfo.token]?.count,\n    discount: offchainFeeInfo.discount ? offchainFeeInfo.discount : undefined,\n    __raw__: {\n      fastWithDraw: '',\n      tokenId: tokenMap[offchainFeeInfo.token]?.tokenId,\n      feeRaw: offchainFeeInfo.fee,\n    }\n  }\n}\n\nconst networkById = (id: ChainId) => {\n  return MapChainId[id] ? (167009 === id ? 'TAIKO' : MapChainId[id]) : undefined\n}\n\nconst transferToOtherNetwork = async ({\n  account,\n  transferToken,\n  feeToken,\n  state,\n  configJSON,\n  feeRaw,\n  walletProvider,\n  chainId: defaultNetwork,\n  balance\n}: {\n  account: Account\n  transferToken: TokenInfo\n  feeToken: TokenInfo\n  state: any\n  configJSON:  {\n    toOtherNetworks: {\n      network: string\n      supportedTokens: string[]\n    }[]\n    agentId?: number\n    agentAddr?: string\n    exchange?: string\n  }\n  feeRaw: string\n  walletProvider: any\n  chainId: number\n  balance: string\n}) => {\n  const network = networkById(defaultNetwork)!\n  const toNetwork = configJSON.toOtherNetworks[0]?.network\n  \n  // Get next storage Id for the transfer\n  const storageId = await LoopringAPI.userAPI?.getNextStorageId(\n    {\n      accountId: account.accountId,\n      sellTokenId: transferToken.tokenId,\n    },\n    account.apiKey,\n  )\n  // Get agent and exchange information from config\n  // Prepare the transfer request\n\n  if (\n    transferToken.tokenId === feeToken?.tokenId &&\n    utils\n      .parseUnits(state.amount, transferToken.decimals)\n      .add(feeRaw!)\n      .gt(utils.parseUnits(balance, transferToken.decimals))\n  ) {\n    var transferVolume = utils\n      .parseUnits(state.amount, transferToken.decimals)\n      .sub(ethers.BigNumber.from(feeRaw!))\n      .toString()\n  } else {\n    transferVolume = utils.parseUnits(state.amount, transferToken.decimals).toString()\n  }\n  const request: RabbitWithdrawRequest = {\n    fromNetwork: network,\n    toNetwork: toNetwork,\n    toAddress: state.receipt,\n    transfer: {\n      exchange: configJSON.exchange!,\n      payerId: account.accountId,\n      payerAddr: account.accAddress,\n      payeeId: configJSON.agentId!,\n      payeeAddr: configJSON.agentAddr!,\n      token: {\n        tokenId: transferToken.tokenId,\n        volume: transferVolume,\n      },\n      maxFee: {\n        // @ts-ignore\n        tokenId: feeToken.tokenId,\n        volume: ethers.BigNumber.from(feeRaw).toString(),\n      },\n      storageId: storageId!.offchainId,\n      validUntil: getTimestampDaysLater(DAYS),\n      counterFactualInfo: account.eddsaKey.counterFactualInfo,\n    },\n  }\n  // Setup provider for transaction signing\n  const provider = new ethers.providers.Web3Provider(walletProvider as any)\n\n  // Submit the withdraw request\n  return LoopringAPI.rabbitWithdrawAPI!.submitRabitWithdraw(request, {\n    exchangeAddr: configJSON.exchange!,\n    signer: provider.getSigner(),\n    eddsaSignKey: account.eddsaKey.sk,\n    chainId: defaultNetwork as number,\n  })\n}\n\nexport const useTransferToTaikoAccount = (): TransferToTaikoAccountProps => {\n  const { setShowAccount, setShowTransferToTaikoAccount, setShowBridge, modals } = useOpenModals()\n  const { coinJson, defaultNetwork, feeChargeOrder } = useSettings()\n  const { app } = useSystem()\n  const { tokenMap, idIndex } = useTokenMap()\n  const { updateWalletLayer2 } = useWalletLayer2()\n\n  const { fastWithdrawConfig } = useConfig()\n  const { account } = useAccount()\n\n  const initialState = {\n    transferToken: undefined as string | undefined,\n    feeList: undefined as OffchainFeeInfo[] | undefined,\n    feeToken: undefined as string | undefined,\n    panel: 'main' as 'main' | 'contacts' | 'tokenSelection' | 'confirm',\n    showFeeModal: false,\n    amount: '',\n    receipt: '',\n    tokenFilterInput: '',\n    maxTransferAmount: undefined as ethers.BigNumber | undefined,\n    feeLoading: false\n  }\n\n  const [getState, setState] = useGetSet(initialState)\n\n\n  const state = getState()\n  const transferTokenSymbol = state.transferToken \n    ? state.transferToken \n    : modals.isShowTransferToTaikoAccount.info?.initSymbol \n      ? modals.isShowTransferToTaikoAccount.info?.initSymbol \n      : 'ETH'\n  const transferToken = tokenMap[transferTokenSymbol]\n  const isOverMax =\n    state.amount &&\n    ethers.utils\n      .parseUnits(state.amount, transferToken.decimals)\n      .gt(state.maxTransferAmount ?? '0')\n  \n  \n  const { contacts, updateContacts } = useContacts()\n  \n  const fromNetwork = networkById(defaultNetwork)\n  const parsed = fastWithdrawConfig && idIndex && fromNetwork\n    ? parseRabbitConfig2(fastWithdrawConfig, fromNetwork, idIndex)\n    : undefined\n  \n  const transferTokenList = parsed?.toOtherNetworks[0]?.supportedTokens || []\n\n  // const toTaikoNetwork = parsed?.toOtherNetworks[0].network\n\n  const refreshData = async () => {\n    const globalState = store.getState()\n    const account = globalState.account\n    const idIndex = globalState.tokenMap.idIndex\n    const defaultNetwork = globalState.settings.defaultNetwork\n    const fastWithdrawConfig = globalState.config.fastWithdrawConfig\n\n    const fromNetwork = networkById(defaultNetwork)\n    const parsed = fastWithdrawConfig && idIndex && fromNetwork\n      ? parseRabbitConfig2(fastWithdrawConfig, fromNetwork, idIndex)\n      : undefined\n    const destinationNetwork = parsed?.toOtherNetworks[0]?.network\n\n    const state = getState()\n    const modals = globalState.modals\n    const transferTokenSymbol = state.transferToken\n      ? state.transferToken\n      : modals.isShowTransferToTaikoAccount.info?.initSymbol\n      ? modals.isShowTransferToTaikoAccount.info?.initSymbol\n      : 'ETH'\n    const transferToken = tokenMap[transferTokenSymbol]\n\n    setState((state) => ({\n      ...state,\n      feeLoading: true\n    }))\n    const feeRes = await LoopringAPI.rabbitWithdrawAPI\n      ?.getUserCrossChainFee(\n        {\n          receiveFeeNetwork: fromNetwork!,\n          requestType: OffchainFeeReqType.RABBIT_OFFCHAIN_WITHDRAWAL,\n          calFeeNetwork: destinationNetwork!,\n          tokenSymbol: transferTokenSymbol,\n          amount: state.amount ? utils.parseUnits(state.amount, transferToken.decimals).toString() : '0',\n        },\n        account.apiKey,\n      ).finally(() => {\n        setState(state => ({\n          ...state,\n          feeLoading: false\n        }))\n      })\n\n    const destinationNetworkId = _.toPairs(MapChainId).find(([_, v]) => v === destinationNetwork)?.[0]\n    const desExchangeAPI = new ExchangeAPI({baseUrl: `https://${process.env[`REACT_APP_API_URL_${destinationNetworkId}`]}`})\n    const desTokens = await desExchangeAPI.getTokens()\n    transferToken && LoopringAPI.rabbitWithdrawAPI?.getNetworkWithdrawalAgents({\n      tokenId: desTokens.tokensMap[transferToken.symbol].tokenId,\n      network: destinationNetwork!,\n      amount: '0'\n    }).then(res => {\n      const amounts = res.map(agent => {\n        return ethers.BigNumber.from(agent.totalAmount).sub(agent.freezeAmount).toString()\n      })\n      const sorted = amounts.concat('0').sort((a, b) => ethers.BigNumber.from(b).gte(a) ? 1 : -1)\n      const amount = sorted[0] ? sorted[0] : '0'\n      setState((state) => ({\n        ...state,\n        maxTransferAmount: ethers.BigNumber.from(amount),\n      }))\n    })\n\n    setState((state) => ({\n      ...state,\n      feeList: feeRes?.fees || [],\n    }))\n  }\n\n  useEffect(() => {\n    var timer: NodeJS.Timeout\n    if (modals.isShowTransferToTaikoAccount.isShow && fastWithdrawConfig) {\n      timer = setInterval(() => {\n        refreshData()\n      }, 10 * 1000)\n      refreshData()\n    }\n    return () => {\n      timer && clearInterval(timer)\n    }\n  }, [modals.isShowTransferToTaikoAccount.isShow, fastWithdrawConfig])\n  const { walletMap } = makeWalletLayer2({ needFilterZero: true })\n  const enoughFeeList = walletMap && tokenMap ? state.feeList?.filter(fee => {\n    \n    return ethers.utils.parseUnits(walletMap[fee.token]?.count.toString() ?? '0', tokenMap[fee.token].decimals).gte(fee.fee)\n    \n  }) : []\n  const _feeInfo = [state.feeToken, ...feeChargeOrder]\n    .map((order) => enoughFeeList?.find((fee) => fee.token === order))\n    .filter((fee) => fee)[0]\n  const feeInfo = _feeInfo\n    ? _feeInfo\n    : state.feeList?.find(feeInfo => feeInfo.token === 'ETH')\n  const feeTokenSymbol = feeInfo?.token\n  const feeToken = (tokenMap && feeTokenSymbol) ? tokenMap[feeTokenSymbol] : undefined\n  \n  const feeRaw = feeInfo?.fee\n  \n\n  const transferTokenWallet = walletMap ? walletMap[transferTokenSymbol] : undefined\n\n  const isInvalidAddress = state.receipt && !ethers.utils.isAddress(state.receipt)\n  const balance = \n      transferTokenWallet && transferToken\n        ? transferTokenWallet.count\n        : undefined;\n  const isOverBalance =\n    state.amount &&\n    new Decimal(state.amount)\n      .gt(balance ?? '0')\n  const isFeeNotEnough = (() => {\n    if (!tokenMap) return false\n    if (!feeInfo || !walletMap || !feeTokenSymbol || !walletMap[feeTokenSymbol]?.count || !feeToken)\n      return true\n    const count = walletMap[feeTokenSymbol]!.count\n    return new Decimal(count).lt(utils.formatUnits(feeInfo.fee, feeToken.decimals))\n  })()\n  const sendBtnDisabled =\n    state.feeLoading ||\n    !state.amount ||\n    new Decimal(state.amount).lessThanOrEqualTo('0') ||\n    !state.receipt ||\n    isOverMax ||\n    isOverBalance ||\n    isFeeNotEnough ||\n    isInvalidAddress\n  const {walletProvider} = useAppKitProvider('eip155')\n  \n\n  const sendBtn = {\n    \n    onClick: async () => {\n      setState({\n        ...state,\n        panel: 'confirm',\n      })\n    },\n    disabled: sendBtnDisabled,\n    text: 'Send'\n  }\n  const debouncedRefreshData = useDebouncedCallback(refreshData, 500)\n\n  const isToEthereum =\n    parsed?.toOtherNetworks[0]?.network &&\n    ['SEPOLIA', 'ETHEREUM'].includes(parsed?.toOtherNetworks[0]?.network)\n  const confirmSend = async () => {\n    setShowAccount({\n      step: AccountStep.Transfer_To_Taiko_In_Progress,\n      isShow: true,\n      info: {\n        isToEthereum\n      }\n    })\n    return transferToOtherNetwork({\n      account,\n      chainId: defaultNetwork,\n      transferToken,\n      feeToken: feeToken!,\n      state,\n      configJSON: parsed!,\n      feeRaw: feeRaw!,\n      walletProvider: walletProvider,\n      balance: balance?.toString() ?? '0',\n    }).then((response) => {\n      if ((response as any)?.resultInfo?.code || (response as any)?.resultInfo?.message) {\n        throw (response as any).resultInfo\n      } else if (response.status === 'failed') {\n        throw new Error('withdraw filed')\n      }\n      setShowTransferToTaikoAccount({\n        isShow: false\n      })\n      setState(initialState)\n      setShowAccount({\n        step: AccountStep.Transfer_To_Taiko_Success,\n        isShow: true,\n        info: {\n          isToEthereum\n        }\n      })\n      sleep(1000).then(() => {\n        updateWalletLayer2()\n      })\n    })\n    .catch(e => {\n      const msg = checkErrorInfo(e, false)\n      const userDenied = [ConnectorError.USER_DENIED, ConnectorError.USER_DENIED_2].includes(\n        msg as ConnectorError,\n      ) || 'User rejected the request.' === msg\n      if (userDenied) {\n        setShowAccount({\n          step: AccountStep.Transfer_To_Taiko_User_Denied,\n          isShow: true,\n          info: {\n            isToEthereum\n          }\n        })\n      } else {\n        setShowAccount({\n          step: AccountStep.Transfer_To_Taiko_Failed,\n          isShow: true,\n          error: {\n            code: UIERROR_CODE.UNKNOWN,\n            msg: e?.message,\n            ...(e instanceof Error\n              ? {\n                  message: e?.message,\n                  stack: e?.stack,\n                }\n              : e ?? {}),\n          },\n          info: {\n            isToEthereum\n          }\n        })\n      }\n    })\n    \n  }\n  \n  const output = {\n    onClickContact: () => {\n      setState({\n        ...state,\n        panel: 'contacts',\n      })\n    },\n    onClickFee: () => {\n      setState({\n        ...state,\n        showFeeModal: true,\n      })\n    },\n    onClickConfirm: confirmSend,\n    onInputAmount: (str) => {\n      if (isValidateNumberStr(str, transferToken.precision) || str === '') {\n        setState({\n          ...state,\n          amount: str,\n        })\n        debouncedRefreshData()\n      }\n    },\n    onInputAddress: (addr) => {\n      setState({\n        ...state,\n        receipt: addr,\n      })\n    },\n    onClickToken: () => {\n      setState({\n        ...state,\n        panel: 'tokenSelection',\n      })\n    },\n    onClickBalance: () => {\n      if (transferTokenWallet?.count.toString()) {\n        setState({\n          ...state,\n          amount: transferTokenWallet.count.toString(),\n        })\n      }\n    },\n    fee:\n      feeToken && feeRaw\n        ? numberFormat(ethers.utils.formatUnits(feeRaw, feeToken.decimals), {\n            fixed: feeToken.precision,\n            removeTrailingZero: true,\n          }) +\n          ' ' +\n          feeToken.symbol\n        : '--',\n    balance: balance\n      ? numberFormat(balance, {\n          fixed: transferToken.precision,\n          removeTrailingZero: true,\n        }) +\n        ' ' +\n        transferTokenSymbol\n      : '--',\n    token: {\n      coinJSON: coinJson[transferTokenSymbol],\n      symbol: transferTokenSymbol,\n    },\n    feeSelect: {\n      open: state.showFeeModal,\n      onClose: () => {\n        setState({\n          ...state,\n          showFeeModal: false,\n        })\n      },\n      feeInfo:\n        feeInfo && walletMap && tokenMap\n          ? offchainFeeInfoToFeeInfo(feeInfo, tokenMap, walletMap as any)\n          : undefined,\n      chargeFeeTokenList:\n        walletMap && tokenMap\n          ? state.feeList?.map((item) => offchainFeeInfoToFeeInfo(item, tokenMap, walletMap as any))\n          : [],\n      handleToggleChange: (feeInfo) => {\n        setState({\n          ...state,\n          feeToken: feeInfo.token!,\n        })\n      },\n      disableNoToken: false,\n      onClickFee: () => {},\n      feeLoading: state.feeLoading || state.feeList === undefined,\n      // isFeeNotEnough: true,\n      isFeeNotEnough,\n      isFastWithdrawAmountLimit: false,\n    },\n    panel: state.panel,\n    contacts: {\n      onSelect: (address) => {\n        setState({\n          ...state,\n          panel: 'main',\n          receipt: address,\n        })\n      },\n      scrollHeight: '200px',\n      contacts: contacts as any,\n    },\n    tokenSelection: {\n      filter: state.tokenFilterInput,\n      tokens: coinJson\n        ? transferTokenList\n            .filter((token) => {\n              if (state.tokenFilterInput) {\n                return token.toLowerCase().includes(state.tokenFilterInput.toLowerCase())\n              }\n              return true\n            })\n            .map((token) => ({\n              symbol: token,\n              coinJSON: [coinJson[token]],\n              amount: walletMap && walletMap[token] ? walletMap[token].count.toString() : '0',\n            }))\n        : [],\n      onChangeFilter: (inputValue: string) => {\n        setState({\n          ...state,\n          tokenFilterInput: inputValue,\n        })\n      },\n      onClickClearFilter: () => {\n        setState({\n          ...state,\n          tokenFilterInput: '',\n        })\n      },\n      onClickCancel: () => {\n        setState({\n          ...state,\n          panel: 'main',\n        })\n      },\n      onClickToken: (symbol) => {\n        setState({\n          ...state,\n          transferToken: symbol,\n          panel: 'main',\n          amount: '',\n        })\n        refreshData()\n      },\n    },\n    receiptInput: state.receipt,\n    amountInput: state.amount,\n    onClickBack() {\n      if (state.panel === 'main') {\n        if (modals.isShowTransferToTaikoAccount.from === 'bridge') {\n          setShowBridge({ isShow: true })\n        } else {\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.SendAssetGateway,\n            info: { symbol: modals.isShowTransferToTaikoAccount.info?.initSymbol },\n          })\n        }\n        setShowTransferToTaikoAccount({ isShow: false })\n        setState(initialState)\n      } else {\n        setState({\n          ...state,\n          panel: 'main',\n        })\n      }\n    },\n    onClickClose() {\n      setShowTransferToTaikoAccount({ isShow: false })\n      setState(initialState)\n    },\n    open: modals.isShowTransferToTaikoAccount.isShow,\n    supportedTokens: transferTokenList,\n    sendBtn: sendBtn,\n    maxAlert: {\n      show: isOverMax || isOverBalance,\n      message:\n        isOverMax && state.maxTransferAmount\n          ? `Quota: ${numberFormat(\n              utils.formatUnits(state.maxTransferAmount!, transferToken.decimals),\n              { fixed: transferToken.precision, removeTrailingZero: true },\n            )} ${transferToken.symbol}`\n          : isOverBalance\n          ? `Insufficient ${transferToken.symbol} balance`\n          : '',\n    },\n    receiptError: {\n      show: isInvalidAddress,\n      message: 'invalid address',\n    },\n    receiptClear: {\n      show: !!state.receipt,\n      onClick: () => {\n        setState({\n          ...state,\n          receipt: '',\n        })\n      },\n    },\n    showReceiptWarning: state.receipt && !isInvalidAddress,\n    retrySend: () => {\n      confirmSend()\n    },\n    title: isToEthereum\n      ? 'Send to Ethereum'\n      : 'Send to Taiko',\n    hideContactBtn: app === 'earn'\n  } as TransferToTaikoAccountProps\n  return output\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/useUpdateAccount.ts",
    "content": "import React from 'react'\n\nimport { FeeInfo, MapChainId, myLog, UIERROR_CODE } from '@loopring-web/common-resources'\nimport { AccountStep, setShowAccount as _setShowAccount, useOpenModals, useSettings } from '@loopring-web/component-lib'\n\nimport { activateAccount, useAccount, LoopringAPI, accountServices, activateAccountSmartWallet, updateAccountRecursively, isCoinbaseSmartWallet, encryptAESMd5, isSameEVMAddress, withRetry, getAndSaveEncryptedSKFromServer } from '../../index'\n\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { useWalletInfo } from '../../stores/localStore/walletInfo'\nimport { useLocation } from 'react-router-dom';\nimport { coinbaseSmartWalletPersist, store } from '../../stores'\nimport { persistStoreCoinbaseSmartWalletData } from 'stores/localStore/coinbaseSmartWalletPersist'\n\n\nconst handleError = (e: any, isReset: boolean) => {\n  const setShowAccount = (args: any) => store.dispatch(_setShowAccount(args))\n  if (e.message === 'submitEncryptedEcdsaKey failed') {\n    setShowAccount({\n      isShow: true,\n      step: AccountStep.Coinbase_Smart_Wallet_Password_Set_Error,\n    })\n    return\n  }\n  const error = LoopringAPI?.exchangeAPI?.genErr(e as any) ?? {\n    code: UIERROR_CODE.DATA_NOT_READY,\n  }\n  const code = sdk.checkErrorInfo(error, true)\n  myLog('unlock', error, e, code)\n  switch (code) {\n    case sdk.ConnectorError.NOT_SUPPORT_ERROR:\n      myLog('activateAccount UpdateAccount: NOT_SUPPORT_ERROR')\n      setShowAccount({\n        isShow: true,\n        step: isReset\n          ? AccountStep.ResetAccount_First_Method_Denied\n          : AccountStep.UpdateAccount_First_Method_Denied,\n      })\n      break\n    case sdk.ConnectorError.USER_DENIED:\n    case sdk.ConnectorError.USER_DENIED_2:\n      myLog('activateAccount: USER_DENIED')\n      setShowAccount({\n        isShow: true,\n        step: isReset\n          ? AccountStep.ResetAccount_User_Denied\n          : AccountStep.UpdateAccount_User_Denied,\n      })\n      break\n    default:\n      setShowAccount({\n        isShow: true,\n        step: isReset ? AccountStep.ResetAccount_Failed : AccountStep.UpdateAccount_Failed,\n        error: {\n          ...((e as any) ?? {}),\n          ...error,\n          code: (e as any)?.code ?? UIERROR_CODE.UNKNOWN,\n        },\n      })\n      break\n  }\n  throw error\n}\n\nexport const goUpdateAccountCoinbaseWalletBackupKeyOnlyFn = async ({\n  isReset = false,\n  backupKeyJSON,\n}: {\n  isFirstTime?: boolean\n  isReset?: boolean\n  feeInfo?: FeeInfo\n  backupKeyJSON: string\n}) => {\n  const {\n    settings: { defaultNetwork },\n    account: { accAddress },\n  } = store.getState()\n  const setShowAccount = (args: any) => store.dispatch(_setShowAccount(args))\n  const { eddsaKey, request } = JSON.parse(backupKeyJSON)\n  try {\n    setShowAccount({\n      isShow: true,\n      step: AccountStep.Coinbase_Smart_Wallet_Password_Set_Processing,\n      info: {\n        step: 'updatingAccount',\n        showResumeUpdateAccount: true,\n      },\n    })\n\n    const [{ apiKey }, { walletType }] = await Promise.all([\n      LoopringAPI?.userAPI?.getUserApiKey(\n        {\n          accountId: request.accountId,\n        },\n        eddsaKey.sk,\n      ),\n      LoopringAPI?.walletAPI?.getWalletType({\n        wallet: accAddress,\n        network: MapChainId[defaultNetwork] as sdk.NetworkWallet,\n      }),\n    ]).then((response) => {\n      if ((response[0] as sdk.RESULT_INFO)?.code) {\n        throw response[0]\n      }\n      return response as any\n    })\n\n    await withRetry(\n      () =>\n        LoopringAPI!.userAPI!.submitEncryptedEcdsaKey(request, eddsaKey.sk, apiKey).then((res) => {\n          if (res.code) {\n            throw res\n          }\n          return res\n        }),\n      3,\n      1000,\n    )()\n    .catch((e) => {\n      throw new Error('submitEncryptedEcdsaKey failed')\n    })\n    const foundData = store.getState().localStore.coinbaseSmartWalletPersist.data!.find((item) => item.chainId === defaultNetwork && isSameEVMAddress(item.wallet, accAddress))!\n    store.dispatch(\n      coinbaseSmartWalletPersist.persistStoreCoinbaseSmartWalletData({\n        ...foundData,\n        eddsaKeyBackup: {\n          backupNotFinished: false,\n          json: ''\n        }\n      })\n    )\n\n    accountServices.sendAccountSigned({\n      apiKey,\n      eddsaKey,\n      isInCounterFactualStatus: walletType?.isInCounterFactualStatus,\n      isContract: walletType?.isContract,\n    })\n\n    setShowAccount({\n      isShow: true,\n      step: AccountStep.Coinbase_Smart_Wallet_Password_Set_Processing,\n      info: {\n        step: 'completed',\n        showResumeUpdateAccount: true,\n      },\n    })\n\n    await sdk.sleep(2 * 1000)\n\n    setShowAccount({ isShow: false })\n  } catch (e) {\n    handleError(e, isReset)\n  }\n}\n\nexport const goUpdateAccountCoinbaseWalletUpdateAccountFn = async ({\n  isFirstTime = false,\n  isReset = false,\n  feeInfo,\n  updateAccountJSON,\n}: {\n  isFirstTime?: boolean\n  isReset?: boolean\n  feeInfo?: FeeInfo\n  updateAccountJSON: string\n}) => {\n  const {\n    settings: { defaultNetwork },\n  } = store.getState()\n  const setShowAccount = (args: any) => store.dispatch(_setShowAccount(args))\n  const { eddsaKey, request } = JSON.parse(updateAccountJSON)\n  try {\n    setShowAccount({\n        isShow: true,\n        step: AccountStep.Coinbase_Smart_Wallet_Password_Set_Processing,\n        info: {\n          step: 'updatingAccount',\n        showResumeUpdateAccount: true,\n      },\n    })\n\n    await updateAccountRecursively({\n      request,\n      eddsaKey: { eddsaKey },\n    })\n\n    const foundData = store.getState().localStore.coinbaseSmartWalletPersist.data!.find((item) => item.chainId === defaultNetwork && isSameEVMAddress(item.wallet, request.owner))!\n    const submitEncryptedEcdsaKeyReq = {\n      accountId: request.accountId,\n      eddsaEncryptedPrivateKey: foundData.eddsaKey.sk,\n      nonce: request.nonce + 1,\n    }\n    const backupKeyJSON = JSON.stringify({\n      request: submitEncryptedEcdsaKeyReq,\n      eddsaKey: eddsaKey\n    })\n    store.dispatch(\n      coinbaseSmartWalletPersist.persistStoreCoinbaseSmartWalletData({\n        ...foundData,\n        nonce: request.nonce + 1,\n        updateAccountData: {\n          updateAccountNotFinished: false,\n          json: '',\n        },\n        eddsaKeyBackup: {\n          backupNotFinished: true,\n          json: backupKeyJSON\n        }\n      }),\n    )\n\n    await goUpdateAccountCoinbaseWalletBackupKeyOnlyFn({\n      isReset,\n      backupKeyJSON,\n    })\n  } catch (e) {\n    handleError(e, isReset)\n  }\n}\n\n\nconst checkBeforeGoUpdateAccount = async (isReset: boolean, feeInfo?: FeeInfo) => {\n  const {\n    account: { accAddress, nonce, accountId },\n    settings: { defaultNetwork },\n    localStore: { coinbaseSmartWalletPersist },\n    system: { exchangeInfo },\n  } = store.getState()\n  if (!exchangeInfo) {\n    return false\n  }\n  if (await isCoinbaseSmartWallet(accAddress, defaultNetwork)) {\n    const foundPersistData = coinbaseSmartWalletPersist?.data.find(\n      (item) =>\n        item.chainId === defaultNetwork &&\n        isSameEVMAddress(item.wallet, accAddress) &&\n        item.nonce === nonce,\n    )\n    if (\n      foundPersistData &&\n      !!foundPersistData.eddsaKeyBackup?.backupNotFinished &&\n      foundPersistData.eddsaKeyBackup?.json\n    ) {\n      goUpdateAccountCoinbaseWalletBackupKeyOnlyFn({\n        isReset: false,\n        backupKeyJSON: foundPersistData.eddsaKeyBackup?.json!,\n      })\n    } else if (\n      foundPersistData &&\n      !!foundPersistData.updateAccountData?.updateAccountNotFinished &&\n      foundPersistData.updateAccountData?.json\n    ) {\n      goUpdateAccountCoinbaseWalletUpdateAccountFn({\n        isReset: false,\n        updateAccountJSON: foundPersistData.updateAccountData?.json!,\n      })\n    } else {\n      store.dispatch(\n        _setShowAccount({\n          isShow: true,\n          step: AccountStep.Coinbase_Smart_Wallet_Password_Set,\n          info: {\n            feeInfo,\n          }\n        }),\n      )\n    }\n    return false\n  }\n  return true\n}\n\nexport function useUpdateAccount() {\n  const { updateHW, checkHWAddr } = useWalletInfo()\n  const { setShowAccount } = useOpenModals()\n  const { account } = useAccount()\n  const { search } = useLocation()\n  const { referralCode, setReferralCode, defaultNetwork } = useSettings()\n  const { persistStoreCoinbaseSmartWalletData } = coinbaseSmartWalletPersist.useCoinbaseSmartWalletPersist()\n\n\n  const goUpdateAccount = React.useCallback(\n    async ({\n      isFirstTime = false,\n      isReset = false,\n      feeInfo,\n    }: {\n      isFirstTime?: boolean\n      isReset?: boolean\n      feeInfo?: FeeInfo\n    }) => {\n      const shouldContinue = await checkBeforeGoUpdateAccount(isReset, feeInfo)\n      if (!shouldContinue) {\n        return\n      }\n\n      setShowAccount({\n        isShow: true,\n        step: isReset\n          ? AccountStep.ResetAccount_Approve_WaitForAuth\n          : AccountStep.UpdateAccount_Approve_WaitForAuth,\n      })\n\n      const isHWAddr = !isFirstTime ? true : checkHWAddr(account.accAddress)\n\n      myLog(\n        'goUpdateAccount: isFirstTime:',\n        isFirstTime,\n        ' isReset:',\n        isReset,\n        ' isHWAddr:',\n        isHWAddr,\n      )\n      let walletType, apiKey\n      try {\n        const { eddsaKey, accInfo } = await activateAccount({\n          isHWAddr,\n          feeInfo,\n          isReset,\n          referral: referralCode,\n        })\n        if (!isFirstTime && isHWAddr) {\n          updateHW({ wallet: account.accAddress, isHWAddr })\n        }\n        if (LoopringAPI.userAPI && LoopringAPI.walletAPI && accInfo && accInfo?.accountId !== -1) {\n          ;[{ apiKey }, { walletType }] = await Promise.all([\n            LoopringAPI.userAPI.getUserApiKey(\n              {\n                accountId: accInfo.accountId,\n              },\n              eddsaKey.sk,\n            ),\n            LoopringAPI.walletAPI.getWalletType({\n              wallet: account.accAddress,\n              network: MapChainId[defaultNetwork] as sdk.NetworkWallet\n            }),\n          ])\n            .then((response) => {\n              if ((response[0] as sdk.RESULT_INFO)?.code) {\n                throw response[0]\n              }\n              return response as any\n            })\n            .catch((error) => {\n              throw error\n            })\n          accountServices.sendAccountSigned({\n            apiKey,\n            eddsaKey,\n            isInCounterFactualStatus: walletType?.isInCounterFactualStatus,\n            isContract: walletType?.isContract,\n          })\n          setShowAccount({\n            isShow: true,\n            step: isReset ? AccountStep.ResetAccount_Success : AccountStep.UpdateAccount_Success,\n          })\n          await sdk.sleep(1000)\n          setShowAccount({ isShow: false })\n        } else {\n          throw { code: UIERROR_CODE.DATA_NOT_READY }\n        }\n      } catch (e) {\n        handleError(e, isReset)\n      }\n      setReferralCode('')\n    },\n    [account.accAddress, search, checkHWAddr, setShowAccount, updateHW, referralCode],\n  )\n\n  const goUpdateAccountCoinbaseWallet = React.useCallback(\n    async ({\n      isFirstTime = false,\n      isReset = false,\n      feeInfo,\n      password,\n    }: {\n      password: string\n      isFirstTime?: boolean\n      isReset?: boolean\n      feeInfo?: FeeInfo\n    }) => {      \n      try {\n        \n        setShowAccount({\n          isShow: true,\n          step: AccountStep.Coinbase_Smart_Wallet_Password_Set_Processing,\n          info: {\n            step: 'keyGenerating',\n            showResumeUpdateAccount: false\n          }\n        })\n        \n        const { eddsaKey, request, approveFn } = await activateAccountSmartWallet({\n          feeInfo,\n          isReset,\n          referral: referralCode,\n        })\n        setShowAccount({\n          isShow: true,\n          step: AccountStep.Coinbase_Smart_Wallet_Password_Set_Processing,\n          info: {\n            step: 'blockConfirming',\n            showResumeUpdateAccount: false\n          }\n        })\n        await approveFn()\n        const encryptedSk = encryptAESMd5(password, eddsaKey.sk)\n        const updateAccountJSON = JSON.stringify({\n          request, \n          eddsaKey\n        })\n        persistStoreCoinbaseSmartWalletData({\n          eddsaKey: {\n            ...eddsaKey,\n            sk: encryptedSk\n          },\n          wallet: request.owner,\n          nonce: request.nonce,\n          chainId: defaultNetwork,\n          updateAccountData: {\n            updateAccountNotFinished: true,\n            json: updateAccountJSON\n          },\n          eddsaKeyBackup: {\n            backupNotFinished: true,\n            json: ''\n          }\n        })\n\n        await goUpdateAccountCoinbaseWalletUpdateAccountFn({\n          isFirstTime,\n          isReset,\n          feeInfo,\n          updateAccountJSON,\n        })\n      } catch (e) {\n        handleError(e, isReset)\n      }\n      setReferralCode('')\n    },\n    [account.accAddress, search, checkHWAddr, setShowAccount, updateHW, referralCode],\n  )\n\n  return {\n    goUpdateAccount,\n    goUpdateAccountCoinbaseWallet,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/useVendor.ts",
    "content": "import {\n  AccountStatus,\n  L1L2_NAME_DEFINED,\n  MapChainId,\n  myLog,\n  TradeBtnStatus,\n  VendorItem,\n  VendorList,\n} from '@loopring-web/common-resources'\nimport { store, useAccount, useModalData, useSystem } from '../../index'\nimport { RampInstantEventTypes, RampInstantSDK } from '@ramp-network/ramp-instant-sdk'\nimport { AccountStep, useOpenModals, useSettings } from '@loopring-web/component-lib'\nimport React from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { BanxaCheck, banxaService, OrderENDReason } from '../../services'\nimport _ from 'lodash'\nimport { useHistory, useRouteMatch } from 'react-router-dom'\nimport { useLocation } from 'react-use'\n\nexport enum RAMP_SELL_PANEL {\n  LIST,\n  RAMP_CONFIRM,\n  BANXA_CONFIRM,\n}\n\nexport const useVendor = () => {\n  const { account } = useAccount()\n  const { t } = useTranslation()\n  const { setShowTradeIsFrozen } = useOpenModals()\n  const match: any = useRouteMatch('/trade/fiat/:tab?')\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const banxaRef = React.useRef()\n  const subject = React.useMemo(() => banxaService.onSocket(), [])\n\n  const {\n    allowTrade: { raw_data },\n  } = useSystem()\n  const legalEnable = (raw_data as any)?.legal?.enable\n  const legalShow = (raw_data as any)?.legal?.show\n  const { setShowAccount } = useOpenModals()\n  const nodeTimer = React.useRef<NodeJS.Timeout | -1>(-1)\n  const history = useHistory()\n  const { href } = useLocation()\n  const search = href?.split('?')[1] ?? ''\n  const searchParams = new URLSearchParams(search)\n  const {\n    // updateOffRampData,\n    resetOffRampData,\n    resetOffBanxaData,\n  } = useModalData()\n\n  const [sellPanel, setSellPanel] = React.useState<RAMP_SELL_PANEL>(\n    RAMP_SELL_PANEL.LIST,\n    // RAMP_SELL_PANEL.BANXA_CONFIRM\n  )\n  const [banxaBtnStatus, setBanxaBtnStatus] = React.useState<TradeBtnStatus>(\n    TradeBtnStatus.AVAILABLE,\n  )\n  const _banxaClick = _.debounce(() => {\n    resetOffBanxaData()\n    banxaService.banxaStart()\n  }, 500)\n\n  const vendorListBuy: VendorItem[] = legalShow\n    ? [\n        {\n          // key: VendorProviders.Ramp,\n          // svgIcon: \"RampIcon\",\n          ...VendorList.Ramp,\n          handleSelect: () => {\n            setShowAccount({ isShow: false })\n            if (legalEnable) {\n              let config: any = {\n                hostAppName: 'Loopring',\n                hostLogoUrl: 'https://static.loopring.io/assets/svg/logo.svg',\n                userAddress: account.accAddress,\n                defaultFlow: 'ONRAMP',\n                enabledFlows: ['ONRAMP'],\n              }\n              if (account && account.accountId && account.accountId !== -1) {\n                config = {\n                  ...config,\n                  swapAsset: 'LOOPRING_*',\n                  // enabledFlows: [\"ONRAMP\"],\n                  hostApiKey: 'r6e232on45rt3ukdb7zbcvh3avdwbqpore5rbht7',\n                }\n              } else {\n                config = {\n                  ...config,\n                  swapAsset: 'LOOPRING_ETH,LOOPRING_USDC,LOOPRING_LRC',\n                  hostApiKey: 'xqh8ej6ye2rpoj528xd6rkghsgmyrk4hxb7kxarz',\n                }\n              }\n              window.rampInstance = new RampInstantSDK({\n                ...config,\n              }).show()\n              window.rampInstance.on(RampInstantEventTypes.WIDGET_CLOSE, () => {\n                resetOffRampData()\n                setSellPanel(RAMP_SELL_PANEL.LIST)\n                if (window.rampInstance) {\n                  window.rampInstance.unsubscribe('*', () => undefined)\n                  window.rampInstance = undefined\n                }\n                let dex = 'labelAddAssetTitleCardDes'\n                if (\n                  account.readyState &&\n                  [\n                    AccountStatus.DEPOSITING,\n                    AccountStatus.NOT_ACTIVE,\n                    AccountStatus.NO_ACCOUNT,\n                  ].includes(\n                    // @ts-ignore\n                    account?.readyState,\n                  )\n                ) {\n                  dex = 'labelAddAssetTitleCardDesActive'\n                }\n                setShowAccount({\n                  isShow: true,\n                  step: AccountStep.ThirdPanelReturn,\n                  info: {\n                    title: t('labelAddAssetTitleCard'),\n                    description: t(dex, {\n                      loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                      l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                      l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                      ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                      loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n                    }),\n                  },\n                })\n              })\n            }\n          },\n        },\n        {\n          ...VendorList.Banxa,\n          handleSelect: () => {\n            let dex = 'labelAddAssetTitleCardDes'\n            if (\n              account.readyState &&\n              [\n                AccountStatus.DEPOSITING,\n                AccountStatus.NOT_ACTIVE,\n                AccountStatus.NO_ACCOUNT,\n              ].includes(\n                // @ts-ignore\n                account?.readyState,\n              )\n            ) {\n              dex = 'labelAddAssetTitleCardDesActive'\n            }\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.ThirdPanelReturn,\n              info: {\n                title: t('labelAddAssetTitleCard'),\n                description: t(dex, {\n                  loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                  l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                  l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                  ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                  loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n                }),\n              },\n            })\n            if (legalEnable) {\n              window.open(\n                'https://loopring.banxa.com/?code=1fe263e17175561954c6&buyMode&walletAddress=' +\n                  account.accAddress,\n                '_blank',\n              )\n              window.opener = null\n            }\n          },\n        },\n      ]\n    : []\n\n  const vendorListSell: VendorItem[] = legalShow\n    ? [\n        // {\n        //   ...VendorList.Ramp,\n        //   handleSelect: () => {\n        //     setShowAccount({ isShow: false });\n        //     if (legalEnable) {\n        //       let config: any = {\n        //         hostAppName: \"Loopring\",\n        //         hostLogoUrl: \"https://static.loopring.io/assets/svg/logo.svg\",\n        //         userAddress: account.accAddress,\n        //         defaultFlow: \"OFFRAMP\",\n        //         enabledFlows: [\"OFFRAMP\"],\n        //         url: \"https://ramp.network/sell-beta\",\n        //       };\n        //       config = {\n        //         ...config,\n        //         hostApiKey: \"qjkymvqp2q7uvvrf7x6fb93pxn4aqc5tb7xheg8u\",\n        //       };\n        //       window.rampInstance = new RampInstantSDK({\n        //         ...config,\n        //       });\n        //       window.rampInstance.onSendCrypto(\n        //         (\n        //           assetSymbol: string,\n        //           amount: string,\n        //           destinationAddress: string\n        //         ) => {\n        //           if (window.rampInstance) {\n        //             try {\n        //               updateOffRampData({\n        //                 send: { assetSymbol, amount, destinationAddress },\n        //               });\n        //               setSellPanel(RAMP_SELL_PANEL.RAMP_CONFIRM);\n        //               console.log(\n        //                 \"onSendCrypto\",\n        //                 assetSymbol,\n        //                 destinationAddress\n        //               );\n        //               //@ts-ignore\n        //               window.rampInstance.domNodes.overlay.style.display =\n        //                 \"none\";\n        //               console.log(\"RAMP WEIGHT hidden on send Crypto\");\n        //             } catch (e) {\n        //               console.log(\"RAMP WEIGHT hidden failed\");\n        //             }\n        //           } else {\n        //             resetOffRampData();\n        //             setSellPanel(RAMP_SELL_PANEL.LIST);\n        //           }\n        //           return new Promise(() => {});\n        //         }\n        //       );\n        //       window.rampInstance.on(RampInstantEventTypes.WIDGET_CLOSE, () => {\n        //         console.log(\"RAMP WEIGHT close\");\n        //         resetOffRampData();\n        //         setSellPanel(RAMP_SELL_PANEL.LIST);\n        //         if (window.rampInstance) {\n        //           window.rampInstance.unsubscribe(\"*\", () => undefined);\n        //           window.rampInstance = undefined;\n        //         }\n        //       });\n        //       console.log(\"RAMP WEIGHT display on send user selected\");\n        //       window.rampInstance.show();\n        //     }\n        //   },\n        // },\n        {\n          ...VendorList.Banxa,\n          btnStatus: banxaBtnStatus,\n          handleSelect: async (_event) => {\n            setBanxaBtnStatus(TradeBtnStatus.LOADING)\n            setShowAccount({ isShow: false })\n            _banxaClick()\n            // @ts-ignore\n          },\n        },\n      ]\n    : []\n\n  const closeBanxa = () => {\n    // @ts-ignore\n    var parentsNode: undefined | HTMLElement = window.document.getElementById('iframeBanxaTarget')\n    if (parentsNode && parentsNode.style) {\n      // @ts-ignore\n      parentsNode.style.display = 'none'\n    }\n  }\n\n  const enterCheck = React.useCallback(async () => {\n    const data = await banxaService.banxaCheckHavePending()\n    if (data?.order?.status === 'waitingPayment') {\n      myLog('banxa Check Have waitingPayment', data.order)\n      banxaService.KYCDone()\n      searchParams.set('orderId', data?.order.id)\n      history.replace({\n        pathname: '/trade/fiat/sell',\n        search: searchParams.toString(),\n      })\n      store.dispatch(\n        setShowAccount({\n          isShow: true,\n          step: AccountStep.ContinuousBanxaOrder,\n          info: { orderId: data?.order.id },\n        }),\n      )\n      // closeBanxa()\n      return\n    }\n    setBanxaBtnStatus(TradeBtnStatus.AVAILABLE)\n  }, [])\n  React.useEffect(() => {\n    const offBanxaValue = store.getState()._router_modalData.offBanxaValue\n    if (\n      match?.params?.tab?.toLowerCase() === 'sell'.toLowerCase() &&\n      searchParams.get('orderId') &&\n      searchParams.get('orderId')?.toLowerCase() !== offBanxaValue?.id?.toLowerCase()\n    ) {\n      banxaService.banxaCheckHavePending()\n    } else if (\n      match?.params?.tab?.toLowerCase() === 'sell'.toLowerCase() &&\n      !searchParams.has('orderId')\n    ) {\n      setBanxaBtnStatus(TradeBtnStatus.LOADING)\n      setSellPanel(RAMP_SELL_PANEL.LIST)\n      enterCheck()\n    }\n  }, [match?.params?.tab, searchParams?.get('orderId')])\n  const clickEvent = () =>\n    banxaService.banxaEnd({\n      reason: OrderENDReason.UserCancel,\n      data: { resource: 'on close' },\n    })\n\n  React.useEffect(() => {\n    const close = window.document.querySelector('#iframeBanxaClose')\n    const parentsNode = window.document.querySelector('#iframeBanxaTarget')\n    if (close && parentsNode) {\n      parentsNode.addEventListener('click', clickEvent)\n    }\n    const subscription = subject.subscribe((props) => {\n      switch (props.status) {\n        // case BanxaCheck.CheckOrderStatus:\n        //   checkOrderStatus(props.data);\n        //   break;\n        case BanxaCheck.OrderHide:\n          setBanxaBtnStatus(TradeBtnStatus.AVAILABLE)\n          // hideBanxa();\n          closeBanxa()\n          break\n        case BanxaCheck.OrderShow:\n          setBanxaBtnStatus(TradeBtnStatus.AVAILABLE)\n          // showBanxa();\n          break\n        case BanxaCheck.OrderEnd:\n          // myLog(\"subscription Banxa\", props. status:t(status), props.data);\n          if (props?.data?.reason === OrderENDReason.BanxaNotReady) {\n            setShowTradeIsFrozen({\n              isShow: true,\n              messageKey: 'labelBanxaNotReady',\n            })\n          }\n          if (props?.data?.reason === OrderENDReason.CreateOrderFailed) {\n            setShowTradeIsFrozen({\n              isShow: true,\n              messageKey: 'labelBanxaFailedForAPI',\n            })\n          }\n          closeBanxa()\n          setBanxaBtnStatus(TradeBtnStatus.AVAILABLE)\n\n          // clearTimeout(nodeTimer.current as NodeJS.Timeout);\n          break\n        default:\n          break\n      }\n    })\n    return () => {\n      if (close && parentsNode) {\n        parentsNode?.removeEventListener('click', clickEvent)\n      }\n      clearTimeout(nodeTimer.current as NodeJS.Timeout)\n      subscription.unsubscribe()\n      closeBanxa()\n    }\n  }, [])\n  return {\n    banxaRef,\n    vendorListBuy,\n    vendorListSell,\n    vendorForce: undefined,\n    sellPanel,\n    setSellPanel,\n    // setSellPanel,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/useWithdraw.ts",
    "content": "import React from 'react'\nimport Web3 from 'web3'\nimport { ConnectProviders, connectProvides } from '@loopring-web/web3-provider'\nimport { AccountStep, SwitchData, useOpenModals, useSettings, useToggle, WithdrawProps } from '@loopring-web/component-lib'\nimport {\n  AccountStatus,\n  AddressError,\n  CoinMap,\n  EXCHANGE_TYPE,\n  Explorer,\n  FeeInfo,\n  getValuePrecisionThousand,\n  IBData,\n  MapChainId,\n  myLog,\n  SagaStatus,\n  SUBMIT_PANEL_AUTO_CLOSE,\n  TRADE_TYPE,\n  TradeBtnStatus,\n  UIERROR_CODE,\n  WALLET_TYPE,\n  WalletMap,\n  WITHDRAW_TOKEN_FILTER_LIST,\n  WithdrawType,\n  WithdrawTypes,\n} from '@loopring-web/common-resources'\n\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nimport {\n  BIGO,\n  DAYS,\n  getTimestampDaysLater,\n  isAccActivated,\n  LAST_STEP,\n  LoopringAPI,\n  makeWalletLayer2,\n  store,\n  TokenMap,\n  useAccount,\n  useAddressCheck,\n  useContacts,\n  useDebouncedCallback,\n  useModalData,\n  useSystem,\n  useTokenMap,\n  useTokenPrices,\n  useWalletLayer2Socket,\n  walletLayer2Service,\n  fiatNumberDisplaySafe,\n  parseRabbitConfig,\n  useConfig,\n  numberFormat,\n  tryFn,\n} from '../../index'\nimport { useWalletInfo } from '../../stores/localStore/walletInfo'\nimport _, { values, omit } from 'lodash'\nimport { addressToExWalletMapFn, exWalletToAddressMapFn } from '@loopring-web/core'\nimport { useGetSet } from 'react-use'\nimport { ethers } from 'ethers'\nimport Decimal from 'decimal.js'\nimport { useAppKitProvider } from '@reown/appkit/react'\n\nconst offchainFeeInfoToFeeInfo = (offchainFeeInfo: sdk.OffchainFeeInfo, tokenMap: TokenMap<{\n  [key: string]: any;\n}>, walletMap: WalletMap<string, any>) => {\n\n  return {\n    belong: offchainFeeInfo.token,\n    fee: tokenMap[offchainFeeInfo.token] ? ethers.utils.formatUnits(offchainFeeInfo.fee, tokenMap[offchainFeeInfo.token].decimals) : '',\n    feeRaw: offchainFeeInfo.fee,\n    token: offchainFeeInfo.token,\n    hasToken: !!offchainFeeInfo.token,\n    count: walletMap[offchainFeeInfo.token]?.count,\n    discount: offchainFeeInfo.discount,\n    __raw__: {\n      fastWithDraw: '',\n      tokenId: tokenMap[offchainFeeInfo.token]?.tokenId,\n      feeRaw: offchainFeeInfo.fee,\n    }\n  }\n}\n\nexport const useWithdraw = <R extends IBData<T>, T>() => {\n  const {\n    modals: {\n      isShowWithdraw: { symbol, isShow, info, address: contactAddress },\n    },\n    setShowAccount,\n    setShowWithdraw,\n    setShowEditContact,\n  } = useOpenModals()\n  const { tokenMap, totalCoinMap, disableWithdrawList, idIndex } = useTokenMap()\n  const { tokenPrices } = useTokenPrices()\n  const { currency, defaultNetwork, feeChargeOrder } = useSettings()\n  const { account, status: accountStatus } = useAccount()\n  const { exchangeInfo, chainId, getValueInCurrency, app } = useSystem()\n  \n  const {\n    contacts,\n    errorMessage: contactsErrorMessage,\n    updateContacts,\n    status: contactStatus,\n  } = useContacts()\n  const { withdrawValue, updateWithdrawData, resetWithdrawData } = useModalData()\n  const [walletMap2, setWalletMap2] = React.useState(\n    makeWalletLayer2({ needFilterZero: true, _isToL1: true }).walletMap ?? ({} as WalletMap<R>),\n  )\n\n  const [sureIsAllowAddress, setSureIsAllowAddress] = React.useState<\n    WALLET_TYPE | EXCHANGE_TYPE | undefined\n  >(undefined)\n\n  const initState = {\n    fee: {\n      chargeFeeTokenListNormal: [] as sdk.OffchainFeeInfo[],\n      chargeFeeTokenListFast: [] as sdk.OffchainFeeInfo[],\n      isOnLoading: false,\n      symbol: undefined as string | undefined, \n    },\n    withdrawMode: {\n      fastInfo: undefined as undefined | {\n        fee: string\n        time: string\n        \n      },\n      maxFastWithdrawAmountBN: undefined as undefined | string,\n      normalInfo: undefined as undefined | {\n        fee: string\n        time: string\n      },\n      mode: 'fast' as 'fast' | 'normal',\n    }\n  }\n  const {fastWithdrawConfig} = useConfig()\n  const parsed =\n    fastWithdrawConfig && idIndex && MapChainId[defaultNetwork]\n      ? parseRabbitConfig(fastWithdrawConfig, MapChainId[defaultNetwork], idIndex)\n      : undefined\n  const fastModeTokens = parsed?.toL1SupportedTokens\n  const [getState, setState] = useGetSet(initState)\n  const state = getState()\n  const { fee: { symbol: feeSymbol, chargeFeeTokenListFast, chargeFeeTokenListNormal }, withdrawMode } = state\n  const withdrawToken = tokenMap[withdrawValue.belong as string]\n  const {toggle} = useToggle()\n  const tradeValueBN = withdrawToken && withdrawValue.tradeValue\n    ? ethers.utils.parseUnits(withdrawValue.tradeValue.toString(), withdrawToken.decimals)\n    : ethers.BigNumber.from('0')\n  const fastWithdrawOverflow = state.withdrawMode.maxFastWithdrawAmountBN && tradeValueBN \n    ? tradeValueBN.gte(state.withdrawMode.maxFastWithdrawAmountBN)\n    : undefined\n  const fastModeSupportted = \n    toggle.rabbitWithdraw.enable &&\n    fastModeTokens?.includes(withdrawValue.belong as string)\n\n  const isFastMode =\n    fastWithdrawOverflow === false && fastModeSupportted ? withdrawMode.mode === 'fast' : false\n  const chargeFeeTokenList = isFastMode \n    ? chargeFeeTokenListFast \n    : chargeFeeTokenListNormal\n  const enoughFeeList = tryFn(() => {\n    return chargeFeeTokenList.filter(fee => {\n      return ethers.utils.parseUnits(walletMap2[fee.token]?.count ?? '0', tokenMap[fee.token].decimals).gte(fee.fee)\n    })\n  }, () => [])\n  \n  const _feeInfo = [feeSymbol, ...feeChargeOrder]\n    .map((order) => enoughFeeList?.find((fee) => fee.token === order))\n    .filter((fee) => fee)[0]\n  \n  const feeInfo = _feeInfo\n    ? _feeInfo\n    : chargeFeeTokenList?.find(feeInfo => feeInfo.token === 'ETH')\n    \n  const feeInfo2 = feeInfo && walletMap2 && tokenMap \n    ? offchainFeeInfoToFeeInfo(feeInfo, tokenMap, walletMap2 as any)\n    : undefined;\n  \n  const isFeeNotEnough = {\n    isFeeNotEnough:\n      feeInfo2 && feeInfo2.fee && feeInfo2.count\n        ? new Decimal(feeInfo2.fee).gt(feeInfo2.count)\n        : true,\n    isOnLoading: getState().fee.isOnLoading,\n  }\n  const handleFeeChange = (feeInfo: FeeInfo) => {\n    setState({\n      ...getState(),\n      fee: {\n        ...getState().fee,\n        symbol: feeInfo.token,\n      },\n    })\n  }\n\n  const { checkHWAddr, updateHW } = useWalletInfo()\n\n  const [lastRequest, setLastRequest] = React.useState<any>({})\n  \n\n  const {\n    address,\n    realAddr,\n    isCFAddress,\n    isContractAddress,\n    setAddress,\n    addrStatus,\n    isLoopringAddress,\n    isAddressCheckLoading,\n    loopringSmartWalletVersion,\n    reCheck,\n    isENSWrong,\n    ens,\n  } = useAddressCheck(false)\n\n  React.useEffect(() => {\n    if (loopringSmartWalletVersion?.isLoopringSmartWallet && sureIsAllowAddress === undefined) {\n      setSureIsAllowAddress(WALLET_TYPE.Loopring)\n    }\n  }, [loopringSmartWalletVersion?.isLoopringSmartWallet])\n\n  const isNotAvailableAddress =\n    // isCFAddress\n    // ? \"isCFAddress\"\n    // :\n    isContractAddress && disableWithdrawList.includes(withdrawValue?.belong ?? '')\n      ? `isContractAddress`\n      : undefined\n      \n  const checkBtnStatus = () => {\n    const withdrawValue = store.getState()._router_modalData.withdrawValue\n    if (tokenMap && withdrawValue.belong && tokenMap[withdrawValue.belong]) {\n      const withdrawT = tokenMap[withdrawValue.belong]\n      const tradeValue = sdk.toBig(withdrawValue.tradeValue ?? 0).times('1e' + withdrawT.decimals)\n      const exceedPoolLimit =\n        withdrawValue.withdrawType == sdk.OffchainFeeReqType.FAST_OFFCHAIN_WITHDRAWAL &&\n        tradeValue.gt(0) &&\n        withdrawT.fastWithdrawLimit &&\n        tradeValue.gte(withdrawT.fastWithdrawLimit)\n      const isEnough = tradeValue.lte(\n        sdk.toBig(withdrawValue.balance ?? 0).times('1e' + withdrawT.decimals),\n      )\n      \n      const contact = contacts?.find((x) => x.contactAddress === realAddr)\n      const ensHasCheck = (contact?.ens || ens) \n        ? !isENSWrong \n        : true\n\n      if (exceedPoolLimit) {\n        const amt = getValuePrecisionThousand(\n          sdk.toBig(withdrawT.fastWithdrawLimit ?? 0).div('1e' + withdrawT.decimals),\n          withdrawT.precision,\n          withdrawT.precision,\n          withdrawT.precision,\n          false,\n          { floor: true },\n        ).toString()\n        return {\n          label: `labelL2toL1BtnExceed|${amt}`,\n          enable: false,\n          isFastWithdrawAmountLimit: true,\n        }\n      } else if (!info?.isToMyself && realAddr && withdrawValue.tradeValue && sureIsAllowAddress === undefined) {\n        return {\n          label: 'Please input address type',\n          enable: false,\n          isFastWithdrawAmountLimit: false,\n        }\n      }\n      if (\n        tradeValue &&\n        !exceedPoolLimit &&\n        !isNotAvailableAddress &&\n        chargeFeeTokenList.length &&\n        !isFeeNotEnough.isFeeNotEnough &&\n        feeInfo2?.belong &&\n        feeInfo2?.feeRaw &&\n        tradeValue.gt(BIGO) &&\n        !isFeeNotEnough.isOnLoading &&\n        withdrawValue.tradeValue &&\n        realAddr &&\n        isEnough &&\n        ensHasCheck &&\n        (info?.isToMyself || sureIsAllowAddress) &&\n        [AddressError.NoError, AddressError.IsNotLoopringContract].includes(addrStatus)\n      ) {\n        return {\n          enable: true,\n          isFastWithdrawAmountLimit: false,\n          label: undefined\n        }\n      }\n      \n    } \n    return {\n      label: undefined,\n      enable: false,\n      isFastWithdrawAmountLimit: false\n    }\n  }\n  const checkResult = checkBtnStatus()\n  const btnStatus: TradeBtnStatus = checkResult.enable\n    ? TradeBtnStatus.AVAILABLE \n    : TradeBtnStatus.DISABLED\n  const withdrawI18nKey = checkResult.label\n  const isFastWithdrawAmountLimit=checkResult.isFastWithdrawAmountLimit\n\n\n  const walletLayer2Callback = () => {\n    const walletMap =\n      makeWalletLayer2({ needFilterZero: true, _isToL1: true }).walletMap ?? ({} as WalletMap<R>)\n    setWalletMap2(\n      WITHDRAW_TOKEN_FILTER_LIST.reduce((pre, cur) => {\n        return omit(pre, cur) as WalletMap<R>\n      }, walletMap),\n    )\n  }\n\n  const resetDefault = React.useCallback(() => {\n    if (info?.isRetry) {\n      return\n    }\n    if (contactsErrorMessage) {\n      updateContacts()\n    }\n    if (symbol) {\n      if (walletMap2) {\n        updateWithdrawData({\n          belong: symbol as any,\n          balance: walletMap2[symbol]?.count,\n          tradeValue: undefined,\n          address: info?.isToMyself ? account.accAddress : '*',\n          withdrawType: sdk.OffchainFeeReqType.OFFCHAIN_WITHDRAWAL,\n        })\n      }\n    } else {\n      if (!withdrawValue.belong && walletMap2) {\n        const keys = Reflect.ownKeys(walletMap2)\n        let objInit = {\n          belong: 'LRC',\n          tradeValue: undefined,\n          balance: 0,\n          address: info?.isToMyself ? account.accAddress : '*',\n          withdrawType: sdk.OffchainFeeReqType.OFFCHAIN_WITHDRAWAL as WithdrawType,\n        }\n        for (let key in keys) {\n          const keyVal = keys[key]\n          const walletInfo = walletMap2[keyVal]\n          if (sdk.toBig(walletInfo.count).gt(0)) {\n            objInit = {\n              belong: keyVal as any,\n              tradeValue: undefined,\n              balance: walletInfo?.count,\n              address: info?.isToMyself ? account.accAddress : '*',\n              withdrawType: sdk.OffchainFeeReqType.OFFCHAIN_WITHDRAWAL,\n            }\n            break\n          }\n        }\n        updateWithdrawData(objInit as any)\n      } else if (withdrawValue.belong && walletMap2) {\n        const walletInfo = walletMap2[withdrawValue.belong]\n        updateWithdrawData({\n          belong: withdrawValue.belong,\n          tradeValue: undefined,\n          balance: walletInfo?.count,\n          address: info?.isToMyself ? account.accAddress : '*',\n          withdrawType: sdk.OffchainFeeReqType.OFFCHAIN_WITHDRAWAL,\n        })\n      } else {\n        updateWithdrawData({\n          belong: withdrawValue.belong,\n          tradeValue: undefined,\n          balance: undefined,\n          address: info?.isToMyself ? account.accAddress : '*',\n          withdrawType: sdk.OffchainFeeReqType.OFFCHAIN_WITHDRAWAL,\n        })\n      }\n    }\n    if (info?.isToMyself) {\n      setAddress(account.accAddress)\n    } else if (contactAddress) {\n      setAddress(contactAddress)\n    } else {\n      setAddress('')\n    }\n  }, [\n    account.accAddress,\n    setAddress,\n    info?.isToMyself,\n    symbol,\n    walletMap2,\n    updateWithdrawData,\n    feeInfo,\n    withdrawValue.belong,\n    info?.isRetry,\n    contactAddress,\n  ])\n  \n\n\n  const refreshFee = async () => {\n    setState((state) => ({\n      ...state,\n      fee: {\n        ...state.fee,\n        isOnLoading: true,\n      },\n    }))\n    try {\n      const globalState = store.getState()\n      const account = globalState.account\n      const network = MapChainId[globalState.settings.defaultNetwork]\n      const symbol = globalState._router_modalData.withdrawValue.belong as string\n      const withdrawValue = globalState._router_modalData.withdrawValue.tradeValue\n        ? globalState._router_modalData.withdrawValue.tradeValue.toString()\n        : '0'\n      const withdrawToken = symbol\n        ? tokenMap[symbol]\n        : undefined\n\n      const feeResNormal = await LoopringAPI.userAPI?.getOffchainFeeAmt(\n        {\n          accountId: account.accountId,\n          requestType: sdk.OffchainFeeReqType.OFFCHAIN_WITHDRAWAL,\n          tokenSymbol: symbol,\n          amount: ethers.utils.parseUnits(withdrawValue ? withdrawValue : '0', withdrawToken?.decimals).toString(),\n        },\n        account.apiKey,\n      )\n      const feeResFast = await LoopringAPI.rabbitWithdrawAPI?.getUserCrossChainFee(\n        {\n          receiveFeeNetwork: network,\n          requestType: sdk.OffchainFeeReqType.RABBIT_OFFCHAIN_WITHDRAWAL,\n          calFeeNetwork: network,\n          tokenSymbol: symbol,\n          amount: ethers.utils.parseUnits(withdrawValue ? withdrawValue : '0', withdrawToken?.decimals).toString(),\n        },\n        account.apiKey,\n      )\n      .catch(e => {\n        return {fees: []}\n      })\n      withdrawToken && LoopringAPI.rabbitWithdrawAPI?.getNetworkWithdrawalAgents({\n        tokenId: withdrawToken.tokenId,\n        network: network,\n        amount: '0'\n      }).then(res => {\n        const amounts = res.map(agent => {\n\n          return ethers.BigNumber.from(agent.totalAmount).sub(agent.freezeAmount).toString()\n        })\n        const sorted = amounts.concat('0').sort((a, b) => ethers.BigNumber.from(b).gte(a) ? 1 : -1)\n        const amount = sorted[0] ? sorted[0] : '0'\n        setState((state) => ({\n          ...state,\n          withdrawMode: {\n            ...state.withdrawMode,\n            maxFastWithdrawAmountBN: amount,\n          }\n        }))\n      })\n      const chargeFeeTokenListNormal = feeResNormal?.fees ? values(feeResNormal.fees) : []\n      const chargeFeeTokenListFast = feeResFast?.fees ?? []\n      setState((state) => ({\n        ...state,\n        fee: {\n          ...state.fee,\n          chargeFeeTokenListNormal,\n          chargeFeeTokenListFast,\n        }\n      }))\n    } finally {\n      setState((state) => ({\n        ...state,\n        fee: {\n          ...state.fee,\n          isOnLoading: false,\n        },\n      }))\n    }\n  }\n\n  const debouncedRefresshFee = useDebouncedCallback(refreshFee, 100)\n\n  const onChangeWithdrawMode = (mode: 'fast' | 'normal') => {\n    setState((state) => ({\n      ...state,\n      withdrawMode: {\n        ...state.withdrawMode,\n        mode,\n      },\n    }))\n    refreshFee()\n  }\n\n  React.useEffect(() => {\n    const account = store.getState().account\n    var refreshTimer: NodeJS.Timeout | undefined = undefined\n    if (\n      isShow &&\n      accountStatus === SagaStatus.UNSET &&\n      account.readyState === AccountStatus.ACTIVATED\n    ) {\n      resetDefault()\n      refreshTimer = setInterval(() => {\n        refreshFee()\n      }, 20 * 1000)\n      refreshFee()\n    } \n    if (isShow) {\n      setState(initState)\n    }\n    return () => {\n      setAddress('')\n      refreshTimer && clearInterval(refreshTimer)\n    }\n  }, [isShow, accountStatus])\n\n\n  useWalletLayer2Socket({ walletLayer2Callback })\n\n  const processRequest = React.useCallback(\n    async (request: sdk.OffChainWithdrawalRequestV3, isNotHardwareWallet: boolean) => {\n      const { apiKey, connectName, eddsaKey } = account\n      const withdrawValue = store.getState()._router_modalData.withdrawValue\n\n      try {\n        if (\n          connectProvides.usedWeb3 &&\n          LoopringAPI.userAPI &&\n          isAccActivated() &&\n          feeInfo2?.belong\n        ) {\n          let isHWAddr = checkHWAddr(account.accAddress)\n          if (!isHWAddr && !isNotHardwareWallet) {\n            isHWAddr = true\n          }\n          myLog('withdraw processRequest:', isHWAddr, isNotHardwareWallet)\n          const feeToken = tokenMap[feeInfo2.belong]\n          const feeRaw = feeInfo2.feeRaw ?? 0\n          const fee = sdk.toBig(feeRaw)\n          const response = await LoopringAPI.userAPI.submitOffchainWithdraw(\n            {\n              request: {\n                ...request,\n                maxFee: {\n                  tokenId: feeToken?.tokenId ?? request.maxFee.tokenId,\n                  volume: fee?.toString() ?? request.maxFee.volume, // TEST: fee.toString(),\n                },\n              },\n              web3: connectProvides.usedWeb3 as unknown as Web3,\n              chainId: chainId === 'unknown' ? 1 : chainId,\n              walletType: (ConnectProviders[connectName] ??\n                connectName) as unknown as sdk.ConnectorNames,\n              eddsaKey: eddsaKey.sk,\n              apiKey,\n              isHWAddr,\n            },\n            {\n              accountId: account.accountId,\n              counterFactualInfo: eddsaKey.counterFactualInfo,\n            },\n          )\n\n          myLog('submitOffchainWithdraw:', response)\n\n          if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n            throw response\n          }\n          info?.onCloseCallBack && info?.onCloseCallBack()\n          setShowWithdraw({ isShow: false, info })\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.Withdraw_In_Progress,\n          })\n          let hash = Explorer + `tx/${(response as sdk.TX_HASH_API)?.hash}-withdraw`\n\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.Withdraw_Success,\n            info: {\n              symbol: withdrawValue.belong,\n              hash,\n              isToMyself: info?.isToMyself,\n            },\n          })\n\n          if (isHWAddr) {\n            myLog('......try to set isHWAddr', isHWAddr)\n            updateHW({ wallet: account.accAddress, isHWAddr })\n          }\n          resetWithdrawData()\n          walletLayer2Service.sendUserUpdate()\n          await sdk.sleep(SUBMIT_PANEL_AUTO_CLOSE)\n          if (\n            store.getState().modals.isShowAccount.isShow &&\n            store.getState().modals.isShowAccount.step == AccountStep.Withdraw_Success\n          ) {\n            setShowAccount({ isShow: false })\n          }\n        }\n      } catch (e: any) {\n        const code = sdk.checkErrorInfo(e, isNotHardwareWallet)\n        myLog('checkErrorInfo', code, e)\n        switch (code) {\n          case sdk.ConnectorError.NOT_SUPPORT_ERROR:\n            setLastRequest({ request })\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.Withdraw_First_Method_Denied,\n            })\n            break\n          case sdk.ConnectorError.USER_DENIED:\n          case sdk.ConnectorError.USER_DENIED_2:\n            setLastRequest({ request })\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.Withdraw_User_Denied,\n            })\n            break\n          default:\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.Withdraw_Failed,\n              info: {\n                symbol: withdrawValue.belong,\n              },\n              error: {\n                code: UIERROR_CODE.UNKNOWN,\n                msg: e?.message,\n                ...(e instanceof Error\n                  ? {\n                      message: e?.message,\n                      stack: e?.stack,\n                    }\n                  : e ?? {}),\n              },\n            })\n            break\n        }\n      }\n    },\n    [\n      account,\n      withdrawValue,\n      checkHWAddr,\n      chainId,\n      setShowAccount,\n      resetWithdrawData,\n      updateHW,\n    ],\n  )\n\n  const { walletProvider } = useAppKitProvider('eip155')\n\n  const handleWithdraw = React.useCallback(\n    async (inputValue: any, address, isFirstTime: boolean = true) => {\n      const { accountId, accAddress, readyState, apiKey, eddsaKey } = account\n\n      if (\n        readyState === AccountStatus.ACTIVATED &&\n        tokenMap &&\n        exchangeInfo &&\n        connectProvides.usedWeb3 &&\n        address &&\n        LoopringAPI.userAPI &&\n        feeInfo2?.belong &&\n        feeInfo2?.feeRaw &&\n        eddsaKey?.sk &&\n        (info?.isToMyself || sureIsAllowAddress)\n      ) {\n        try {\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.Withdraw_WaitForAuth,\n          })\n\n          const withdrawToken = tokenMap[withdrawValue.belong as string]\n          const feeToken = tokenMap[feeInfo2.belong]\n\n          // const fee = sdk.toBig(withdrawValue.fee?.feeRaw ?? 0);\n          const feeRaw = feeInfo2.feeRaw ?? 0\n          const fee = sdk.toBig(feeRaw)\n          const balance = sdk.toBig(inputValue.balance ?? 0).times('1e' + withdrawToken.decimals)\n          const tradeValue = sdk\n            .toBig(inputValue.tradeValue ?? 0)\n            .times('1e' + withdrawToken.decimals)\n          const isExceedBalance =\n            feeToken.tokenId === withdrawToken.tokenId && tradeValue.plus(fee).gt(balance)\n          const finalVol = isExceedBalance ? balance.minus(fee) : tradeValue\n          const withdrawVol = finalVol.toFixed(0, 0)\n\n          const storageId = await LoopringAPI.userAPI.getNextStorageId(\n            {\n              accountId: accountId,\n              sellTokenId: withdrawToken.tokenId,\n            },\n            apiKey,\n          )\n\n          const request: sdk.OffChainWithdrawalRequestV3 = {\n            exchange: exchangeInfo.exchangeAddress,\n            owner: accAddress,\n            to: address,\n            accountId: account.accountId,\n            storageId: storageId?.offchainId,\n            token: {\n              tokenId: withdrawToken.tokenId,\n              volume: withdrawVol,\n            },\n            maxFee: {\n              tokenId: feeToken.tokenId,\n              volume: fee.toString(), // TEST: fee.toString(),\n            },\n            fastWithdrawalMode:\n              withdrawValue.withdrawType == sdk.OffchainFeeReqType.FAST_OFFCHAIN_WITHDRAWAL, // WithdrawType.Fast,\n            extraData: '',\n            minGas: 0,\n            validUntil: getTimestampDaysLater(DAYS),\n          }\n\n          myLog('submitOffchainWithdraw:', request)\n\n          processRequest(request, isFirstTime)\n        } catch (e: any) {\n          sdk.dumpError400(e)\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.Withdraw_Failed,\n            error: {\n              code: UIERROR_CODE.UNKNOWN,\n              msg: e?.message,\n            },\n          })\n        }\n\n        return true\n      } else {\n        return false\n      }\n    },\n    [\n      account,\n      tokenMap,\n      exchangeInfo,\n      feeInfo2?.belong,\n      feeInfo2?.feeRaw,\n      info,\n      sureIsAllowAddress,\n      setShowAccount,\n      processRequest,\n    ],\n  )\n  \n  const handleRabbitWithdraw = async (inputValue: any, toAddress: string) => {\n    const { readyState, eddsaKey } = account\n    const ok =\n      readyState === AccountStatus.ACTIVATED &&\n      tokenMap &&\n      exchangeInfo &&\n      connectProvides.usedWeb3 &&\n      LoopringAPI.userAPI &&\n      feeInfo2?.belong &&\n      feeInfo2?.feeRaw &&\n      eddsaKey?.sk &&\n      (info?.isToMyself || sureIsAllowAddress) &&\n      toAddress\n    if (!ok) return false\n\n    try {\n      setShowAccount({\n        isShow: true,\n        step: AccountStep.Withdraw_WaitForAuth,\n      })\n      const withdrawToken = tokenMap[withdrawValue.belong as string]\n      const feeToken = tokenMap[feeInfo2.belong]\n      const feeRaw = feeInfo2!.feeRaw ?? 0\n      const fee = sdk.toBig(feeRaw)\n      const balance = sdk.toBig(inputValue.balance ?? 0).times('1e' + withdrawToken.decimals)\n      const tradeValue = sdk.toBig(inputValue.tradeValue ?? 0).times('1e' + withdrawToken.decimals)\n      const isExceedBalance =\n        feeToken.tokenId === withdrawToken.tokenId && tradeValue.plus(fee).gt(balance)\n      const finalVol = isExceedBalance ? balance.minus(fee) : tradeValue\n      const withdrawVol = finalVol.toFixed(0, 0)\n      const network = MapChainId[chainId]\n      const configiJSON = fastWithdrawConfig!\n      const storageId = await LoopringAPI.userAPI?.getNextStorageId(\n        {\n          accountId: account.accountId,\n          sellTokenId: withdrawToken.tokenId,\n        },\n        account.apiKey,\n      )\n      const agentId = configiJSON.networkL2AgentAccountIds[network]\n      const agentAddr = configiJSON.networkL2AgentAddresses[network]\n      const exchange = configiJSON.networkExchanges[network]\n\n      const request: sdk.RabbitWithdrawRequest = {\n        fromNetwork: network,\n        toNetwork: network,\n        toAddress: toAddress,\n        transfer: {\n          exchange: exchange,\n          payerId: account.accountId,\n          payerAddr: account.accAddress,\n          payeeId: agentId,\n          payeeAddr: agentAddr,\n          token: {\n            tokenId: withdrawToken.tokenId,\n            volume: withdrawVol,\n          },\n          maxFee: {\n            // @ts-ignore\n            tokenId: feeToken.tokenId,\n            volume: feeRaw\n          },\n          storageId: storageId!.offchainId,\n          validUntil: getTimestampDaysLater(DAYS),\n          counterFactualInfo: eddsaKey.counterFactualInfo\n        },\n      }\n\n      const provider = new ethers.providers.Web3Provider(walletProvider as any)\n\n      const response = await LoopringAPI.rabbitWithdrawAPI?.submitRabitWithdraw(request, {\n        exchangeAddr: exchange,\n        signer: provider.getSigner(),\n        eddsaSignKey: account.eddsaKey.sk,\n        chainId: chainId as number,\n      })\n      if ((response as any).resultInfo && (response as any).resultInfo.code > 0) {\n        throw (response as any).resultInfo\n      } else if (!response || response.status === 'failed') {\n        throw new Error('withdraw failed')\n      } else {\n        info?.onCloseCallBack && info?.onCloseCallBack()\n        setShowWithdraw({\n          isShow: false,\n          contactName: info?.contactName,\n        })\n        setShowAccount({\n          isShow: true,\n          step: AccountStep.Withdraw_In_Progress,\n        })\n\n        let hash = Explorer + `tx/${(response as sdk.TX_HASH_API)?.hash}-withdraw` // todo\n\n        setShowAccount({\n          isShow: true,\n          step: AccountStep.Withdraw_Success,\n          info: {\n            symbol: withdrawValue.belong,\n            hash,\n            isToMyself: info?.isToMyself,\n          },\n        })\n\n        resetWithdrawData()\n        walletLayer2Service.sendUserUpdate()\n        await sdk.sleep(SUBMIT_PANEL_AUTO_CLOSE)\n        if (\n          store.getState().modals.isShowAccount.isShow &&\n          store.getState().modals.isShowAccount.step === AccountStep.Withdraw_Success\n        ) {\n          setShowAccount({ isShow: false })\n        }\n      }\n    } catch (e: any) {\n      const code = sdk.checkErrorInfo(e, true)\n      myLog('checkErrorInfo', code, e)\n      switch (code) {\n        case sdk.ConnectorError.NOT_SUPPORT_ERROR:\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.Withdraw_First_Method_Denied,\n          })\n          break\n        case sdk.ConnectorError.USER_DENIED:\n        case sdk.ConnectorError.USER_DENIED_2:\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.Withdraw_User_Denied,\n          })\n          break\n        default:\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.Withdraw_Failed,\n            info: {\n              symbol: withdrawValue.belong,\n            },\n            error: {\n              code: UIERROR_CODE.UNKNOWN,\n              msg: e?.message,\n              ...(e instanceof Error\n                ? {\n                    message: e?.message,\n                    stack: e?.stack,\n                  }\n                : e ?? {}),\n            },\n          })\n          break\n      }\n      sdk.dumpError400(e)\n      setShowAccount({\n        isShow: true,\n        step: AccountStep.Withdraw_Failed,\n        error: {\n          code: UIERROR_CODE.UNKNOWN,\n          msg: e?.message,\n        },\n      })\n    }\n      \n  }\n  const retryBtn = React.useCallback(\n    (isHardwareRetry: boolean = false) => {\n      setShowAccount({\n        isShow: true,\n        step: AccountStep.NFTWithdraw_WaitForAuth,\n      })\n      if (isFastMode) {\n        return\n      } else {\n        processRequest(lastRequest, !isHardwareRetry)\n      }\n    },\n    [lastRequest, processRequest, setShowAccount, isFastMode],\n  )\n\n  React.useEffect(() => {\n    const { contacts } = store.getState().contacts\n    const contact = contacts?.find(\n      (x) => x.contactAddress?.toLowerCase() === realAddr?.toLowerCase(),\n    )\n    if (contact?.addressType !== undefined) {\n      const found = contact.addressType ? addressToExWalletMapFn(contact.addressType) : undefined\n      setSureIsAllowAddress(found)\n    } else {\n      setSureIsAllowAddress(undefined)\n    }\n    if (\n      isShow &&\n      contactStatus == SagaStatus.UNSET &&\n      contact &&\n      realAddr?.toLowerCase() == contact?.contactAddress?.toLowerCase()\n    ) {\n      reCheck()\n    }\n  }, [realAddr, isShow, contactStatus])\n  const isTaiko = [sdk.ChainId.TAIKO, sdk.ChainId.TAIKOHEKLA].includes(defaultNetwork)\n\n  const withdrawProps: WithdrawProps<any, any> = {\n    type: TRADE_TYPE.TOKEN,\n    isLoopringAddress,\n    isAddressCheckLoading,\n    isCFAddress,\n    isToMyself: info?.isToMyself,\n    isContractAddress,\n    withdrawI18nKey,\n    accAddr: account.accAddress,\n    isNotAvailableAddress,\n    addressDefault: address,\n    realAddr,\n    disableWithdrawList,\n    tradeData: withdrawValue as any,\n    coinMap: totalCoinMap as CoinMap<T>,\n    walletMap: walletMap2 as WalletMap<any>,\n    withdrawBtnStatus: btnStatus,\n    withdrawType: withdrawValue.withdrawType as any,\n    isFastWithdrawAmountLimit,\n    sureIsAllowAddress,\n    lastFailed: store.getState().modals.isShowAccount.info?.lastFailed === LAST_STEP.withdraw,\n    handleSureIsAllowAddress: (value: WALLET_TYPE | EXCHANGE_TYPE) => {\n      const found = exWalletToAddressMapFn(value)\n      // const found = map.find(x => x[0] === value)![1]\n      const contact = contacts?.find((x) => x.contactAddress === realAddr)\n      if (!account?.isContractAddress && contact) {\n        LoopringAPI.contactAPI\n          ?.updateContact(\n            {\n              ...contact,\n              isHebao: !!(account.isContractAddress || account.isCFAddress),\n              accountId: account.accountId,\n              addressType: found,\n            },\n            account.apiKey,\n          )\n          .then(() => {\n            updateContacts()\n          })\n      }\n      setSureIsAllowAddress(value)\n    },\n\n    onWithdrawClick: () => {\n      if (withdrawValue && withdrawValue.belong) {\n        return isFastMode\n          ? handleRabbitWithdraw(withdrawValue, realAddr ? realAddr : address)\n          : handleWithdraw(withdrawValue, realAddr ? realAddr : address)\n      }\n    },\n    handleWithdrawTypeChange: (value) => {\n      // setWithdrawType(value);\n      const _withdrawValue = store.getState()._router_modalData.withdrawValue\n      updateWithdrawData({\n        ..._withdrawValue,\n        withdrawType: value as any,\n      })\n    },\n    handlePanelEvent: async (data: SwitchData<R>, _switchType: 'Tomenu' | 'Tobutton') => {\n      if (data.to === 'button') {\n        if (walletMap2 && data?.tradeData?.belong) {\n          setState({\n            ...state,\n            withdrawMode: {\n              ...state.withdrawMode,\n              maxFastWithdrawAmountBN: undefined,\n            }\n          })\n          debouncedRefresshFee()\n          const walletInfo = walletMap2[data?.tradeData?.belong as string]\n          updateWithdrawData({\n            ...withdrawValue,\n            belong: data.tradeData?.belong,\n            tradeValue: data.tradeData?.tradeValue,\n            balance: walletInfo?.count,\n            address: '*',\n          })\n        } else {\n          updateWithdrawData({\n\n            withdrawType: sdk.OffchainFeeReqType.OFFCHAIN_WITHDRAWAL,\n            belong: undefined,\n            tradeValue: undefined,\n            balance: undefined,\n            address: '*',\n          })\n        }\n      }\n    },\n    handleFeeChange,\n    feeInfo: feeInfo2,\n    addrStatus,\n    chargeFeeTokenList: chargeFeeTokenList.map(feeInfo => {\n      return feeInfo && walletMap2 && tokenMap\n      ? offchainFeeInfoToFeeInfo(feeInfo, tokenMap, walletMap2 as any)\n      : undefined\n    }).filter(feeInfo => feeInfo !== undefined),\n    isFeeNotEnough,\n    handleOnAddressChange: (value: any) => {\n      setAddress(value)\n    },\n    isFromContact: contactAddress ? true : false,\n    contact: contactAddress\n      ? contacts?.find((x) => x.contactAddress === contactAddress)\n      : undefined,\n    loopringSmartWalletVersion,\n    contacts,\n    isENSWrong,\n    geUpdateContact: () => {\n      if (isENSWrong) {\n        const contact = contacts?.find((x) => x.contactAddress === realAddr)\n        setShowEditContact({\n          isShow: true,\n          info: {\n            ...contact,\n            isENSWrong,\n          },\n        })\n      }\n    },\n    ens,\n    withdrawMode: (() => {\n      const state = getState()\n      const feeSymbol = state.fee.symbol ?? 'ETH'\n      const feeFast = state.fee.chargeFeeTokenListFast.find((item) => item.token === feeSymbol)\n      const feeNormal = state.fee.chargeFeeTokenListNormal.find((item) => item.token === feeSymbol)\n      const feeTokenInfo = tokenMap[feeSymbol]\n\n      const feeFastInCurrency =\n        tryFn(\n          () => {\n            return feeFast && fiatNumberDisplaySafe(\n              getValueInCurrency(\n                new Decimal(ethers.utils.formatUnits(feeFast.fee, feeTokenInfo.decimals))\n                  .mul(tokenPrices[feeSymbol])\n                  .toFixed(2),\n              ),\n              currency,\n            )\n          },\n          () => undefined\n        )\n      const feeNormalInCurrency = tryFn(\n        () =>\n          fiatNumberDisplaySafe(\n            getValueInCurrency(\n              new Decimal(ethers.utils.formatUnits(feeNormal!.fee, feeTokenInfo.decimals))\n                .mul(tokenPrices[feeSymbol])\n                .toFixed(2),\n            ),\n            currency,\n          ),\n        () => undefined,\n      )\n      \n      return {\n        mode: isFastMode ? 'fast' : 'normal',\n        showTrustUI: !isTaiko,\n        showFastMode: fastModeSupportted,\n        fastMode: {\n          fee: feeFastInCurrency ? '~' + feeFastInCurrency : '--',\n          time: '~3 minutes',\n        },\n        fastMaxAlert: {\n          show: fastWithdrawOverflow === true,\n          message:\n            state.withdrawMode.maxFastWithdrawAmountBN && withdrawToken\n              ? `Max ${numberFormat(\n                  ethers.utils.formatUnits(\n                    state.withdrawMode.maxFastWithdrawAmountBN,\n                    withdrawToken.decimals,\n                  ),\n                  { fixed: withdrawToken.precision, removeTrailingZero: true },\n                )} ${withdrawToken?.symbol}`\n              : '--',\n        },\n        normalMode: {\n          fee: feeNormalInCurrency ? '~' + feeNormalInCurrency : '--',\n          time: '~25 minutes',\n        },\n        onChange: onChangeWithdrawMode,\n        fastModeSupportedTokens: parsed?.toL1SupportedTokens ? parsed.toL1SupportedTokens : []\n      }\n    })(),\n  }\n  myLog('withdrawProps', getState(), withdrawValue, withdrawProps)\n\n  return {\n    withdrawProps,\n    retryBtn,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/vault/index.ts",
    "content": "export * from './useVaultJoin'\nexport * from './useAccountInfo'\nexport * from './useVaultRedeem'\nexport * from './useVaultLoan'\nexport * from './useVaultRepay'\nexport * from './useVaultBorrow'\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/vault/useAccountInfo.ts",
    "content": "import {\n  store,\n  useAccount,\n  useSubmitBtn,\n  useTokenMap,\n  useVaultLayer2,\n  useVaultMap,\n  VaultLayer2States,\n} from '@loopring-web/core'\nimport React from 'react'\nimport {\n  L1L2_NAME_DEFINED,\n  MapChainId,\n  RouterPath,\n  SagaStatus,\n  TradeBtnStatus,\n  VaultKey,\n  VaultLoanType,\n} from '@loopring-web/common-resources'\nimport { useOpenModals, useSettings } from '@loopring-web/component-lib'\nimport { useTranslation } from 'react-i18next'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { useConfirmation } from '../../../stores/localStore/confirmation'\nimport { useHistory } from 'react-router'\n\nexport type VaultAccountInfoStatus = VaultLayer2States & {\n  joinBtnStatus: TradeBtnStatus\n  joinBtnLabel: string\n  onJoinPop: (props: any) => void\n  swapBtnStatus: TradeBtnStatus\n  swapBtnLabel: string\n  onSwapPop: (props: any & { symbol: string, isSell?: boolean }) => void\n  redeemBtnStatus: TradeBtnStatus\n  onRedeemPop: (props: any) => void\n  redeemBtnLabel: string\n  borrowBtnStatus: TradeBtnStatus\n  onBorrowPop: (props: any) => void\n  borrowBtnLabel: string\n  repayBtnStatus: TradeBtnStatus\n  onRepayPop: (props: any) => void\n  repayBtnLabel: string\n  vaultAccountInfoStatus: SagaStatus\n  onGoToSwap: ({ symbol, isSell }: { symbol?: string; isSell?: boolean }) => void\n  // isShowFeathure:  vaultAccountInfo?.accountStatus\n}\nexport const useVaultAccountInfo = () => {\n  const {\n    vaultAccountInfo,\n    status: vaultAccountInfoStatus,\n    updateVaultLayer2,\n    tokenFactors,\n    collateralTokens,\n    maxLeverage,\n    activeInfo,\n  } = useVaultLayer2()\n  const { erc20Map } = useVaultMap()\n  const { idIndex } = useTokenMap()\n\n  const {\n    setShowVaultJoin,\n    setShowVaultSwap,\n    setShowVaultExit,\n    setShowVaultLoan,\n    setShowConfirmedVault,\n  } = useOpenModals()\n\n  const { t } = useTranslation()\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const {\n    confirmation: { confirmedOpenVaultPosition },\n  } = useConfirmation()\n\n  const availableJoinCheck = React.useCallback((): {\n    tradeBtnStatus: TradeBtnStatus\n    label: string\n  } => {\n    const { vaultAccountInfo } = store.getState().vaultLayer2\n    switch (vaultAccountInfo?.accountStatus) {\n      // @ts-ignore\n      case sdk.VaultAccountStatus.IN_REDEEM: //sdk.VaultAccountStatus.IN_REDEEM:\n        return { tradeBtnStatus: TradeBtnStatus.DISABLED, label: `labelVaultREDEEMPendingBtn|` }\n      // @ts-ignore\n      case sdk.VaultAccountStatus.IN_STAKING: //sdk.VaultAccountStatus.IN_STAKING:\n        return { tradeBtnStatus: TradeBtnStatus.AVAILABLE, label: `labelVaultAddBtn|` }\n      case sdk.VaultAccountStatus.FREE: // sdk.VaultAccountStatus.FREE:\n      default:\n        if (activeInfo?.hash) {\n          return { tradeBtnStatus: TradeBtnStatus.AVAILABLE, label: `labelVaultJoinBtn|` }\n        }\n        return { tradeBtnStatus: TradeBtnStatus.AVAILABLE, label: `labelVaultJoinBtn|` }\n    }\n  }, [vaultAccountInfoStatus, activeInfo])\n  const {\n    btnStatus: joinBtnStatus,\n    onBtnClick: onJoinPop,\n    btnLabel: joinBtnLabel,\n  } = useSubmitBtn({\n    availableTradeCheck: availableJoinCheck,\n    isLoading: false,\n    submitCallback: async () => {\n      const { vaultAccountInfo } = store.getState().vaultLayer2\n      switch (vaultAccountInfo?.accountStatus) {\n        // @ts-ignore\n        case sdk.VaultAccountStatus.IN_REDEEM: // sdk.VaultAccountStatus.IN_REDEEM:\n          break\n        // @ts-ignore\n        case sdk.VaultAccountStatus.IN_STAKING: //sdk.VaultAccountStatus.IN_STAKING:\n          setShowVaultJoin({ isShow: true, info: { isActiveAccount: false } })\n          break\n        // @ts-ignore\n        case sdk.VaultAccountStatus.FREE: //sdk.VaultAccountStatus.FREE\n        default: {\n          if (!confirmedOpenVaultPosition) {\n            setShowConfirmedVault({ isShow: true })  \n          } else {\n            history.push(`${RouterPath.vault}/${VaultKey.VAULT_DASHBOARD}`)\n            setShowVaultJoin({ isShow: true, info: { isActiveAccount: true } })\n            setShowConfirmedVault({ isShow: false })  \n          }\n        }\n      }\n    },\n  })\n  const availableSwapCheck = React.useCallback((): {\n    tradeBtnStatus: TradeBtnStatus\n    label: string\n  } => {\n    const { vaultAccountInfo } = store.getState().vaultLayer2\n    if (vaultAccountInfoStatus === SagaStatus.UNSET && vaultAccountInfo) {\n      // setIsLoading(false)\n      switch (vaultAccountInfo?.accountStatus) {\n        case sdk.VaultAccountStatus.IN_STAKING: //sdk.VaultAccountStatus.IN_STAKING:\n          return { tradeBtnStatus: TradeBtnStatus.AVAILABLE, label: `labelVaultTradeBtn|` }\n\n        default:\n          return { tradeBtnStatus: TradeBtnStatus.DISABLED, label: `labelVaultTradeBtn|` }\n      }\n    } else {\n      // setIsLoading(true)\n      return { tradeBtnStatus: TradeBtnStatus.LOADING, label: `abelVaultTradeBtn|` }\n    }\n  }, [vaultAccountInfoStatus])\n  const {\n    btnStatus: swapBtnStatus,\n    onBtnClick: onSwapPop,\n    btnLabel: swapBtnLabel,\n  } = useSubmitBtn({\n    availableTradeCheck: availableSwapCheck,\n    isLoading: false,\n    submitCallback: async ({ symbol, isSell }: { symbol?: string, isSell?: boolean }) => {\n      \n      updateVaultLayer2({})\n      const { vaultAccountInfo } = store.getState().vaultLayer2\n      switch (vaultAccountInfo?.accountStatus) {\n        case sdk.VaultAccountStatus.IN_STAKING:\n          setShowVaultSwap({\n            isShow: true,\n            symbol: symbol ?? 'ETH',\n            isSell\n          })\n          break\n      }\n    },\n  })\n\n  const availableRedeemCheck = React.useCallback((): {\n    tradeBtnStatus: TradeBtnStatus\n    label: string\n  } => {\n    const { vaultAccountInfo } = store.getState().vaultLayer2\n    if (vaultAccountInfoStatus === SagaStatus.UNSET && vaultAccountInfo) {\n      // setIsLoading(false)\n      switch (vaultAccountInfo?.accountStatus) {\n        case sdk.VaultAccountStatus.IN_STAKING: //sdk.VaultAccountStatus.IN_STAKING:\n          return { tradeBtnStatus: TradeBtnStatus.AVAILABLE, label: `labelVaultRedeemBtn|` }\n\n        default:\n          return { tradeBtnStatus: TradeBtnStatus.DISABLED, label: `labelVaultRedeemBtn|` }\n      }\n    } else {\n      // setIsLoading(true)\n      return { tradeBtnStatus: TradeBtnStatus.LOADING, label: `abelVaultRedeemBtn|` }\n    }\n  }, [vaultAccountInfoStatus])\n\n  const {\n    btnStatus: redeemBtnStatus,\n    onBtnClick: onRedeemPop,\n    btnLabel: redeemBtnLabel,\n  } = useSubmitBtn({\n    availableTradeCheck: availableRedeemCheck,\n    isLoading: false,\n    submitCallback: async (key?: string) => {\n      const { vaultAccountInfo } = store.getState().vaultLayer2\n      switch (vaultAccountInfo?.accountStatus) {\n        case sdk.VaultAccountStatus.IN_STAKING: //sdk.VaultAccountStatus.IN_STAKING:\n          setShowVaultExit({ isShow: true, symbol: key ?? '' })\n          break\n      }\n    },\n  })\n\n  const availableBorrowCheck = React.useCallback((): {\n    tradeBtnStatus: TradeBtnStatus\n    label: string\n  } => {\n    const { vaultAccountInfo } = store.getState().vaultLayer2\n    if (vaultAccountInfoStatus === SagaStatus.UNSET && vaultAccountInfo) {\n      // setIsLoading(false)\n      switch (vaultAccountInfo?.accountStatus) {\n        case sdk.VaultAccountStatus.IN_STAKING: //sdk.VaultAccountStatus.IN_STAKING:\n          return { tradeBtnStatus: TradeBtnStatus.AVAILABLE, label: `labelVaultBorrowBtn|` }\n\n        default:\n          return { tradeBtnStatus: TradeBtnStatus.DISABLED, label: `labelVaultBorrowBtn|` }\n      }\n    } else {\n      // setIsLoading(true)\n      return { tradeBtnStatus: TradeBtnStatus.LOADING, label: `abelVaultBorrowBtn|` }\n    }\n  }, [vaultAccountInfoStatus])\n  const {\n    btnStatus: borrowBtnStatus,\n    onBtnClick: onBorrowPop,\n    btnLabel: borrowBtnLabel,\n  } = useSubmitBtn({\n    availableTradeCheck: availableBorrowCheck,\n    isLoading: false,\n    submitCallback: async ({symbol}: {isShow: boolean,symbol: string}) => {\n      const { vaultAccountInfo } = store.getState().vaultLayer2\n      switch (vaultAccountInfo?.accountStatus) {\n        case sdk.VaultAccountStatus.IN_STAKING: //sdk.VaultAccountStatus.IN_STAKING:\n          setShowVaultLoan({ isShow: true, info: {symbol: symbol ?? ''}, type: VaultLoanType.Borrow })\n          break\n      }\n    },\n  })\n\n  const availableRepayCheck = React.useCallback((): {\n    tradeBtnStatus: TradeBtnStatus\n    label: string\n  } => {\n    const { vaultAccountInfo } = store.getState().vaultLayer2\n    if (vaultAccountInfoStatus === SagaStatus.UNSET && vaultAccountInfo) {\n      // setIsLoading(false)\n      switch (vaultAccountInfo?.accountStatus) {\n        case sdk.VaultAccountStatus.IN_STAKING: //sdk.VaultAccountStatus.IN_STAKING:\n          return { tradeBtnStatus: TradeBtnStatus.AVAILABLE, label: `labelVaultRepayBtn|` }\n\n        default:\n          return { tradeBtnStatus: TradeBtnStatus.DISABLED, label: `labelVaultRepayBtn|` }\n      }\n    } else {\n      // setIsLoading(true)\n      return { tradeBtnStatus: TradeBtnStatus.LOADING, label: `abelVaultRepayBtn|` }\n    }\n  }, [vaultAccountInfoStatus])\n  const {\n    btnStatus: repayBtnStatus,\n    onBtnClick: onRepayPop,\n    btnLabel: repayBtnLabel,\n  } = useSubmitBtn({\n    availableTradeCheck: availableRepayCheck,\n    isLoading: false,\n    submitCallback: async (key?: string) => {\n      const { vaultAccountInfo } = store.getState().vaultLayer2\n      switch (vaultAccountInfo?.accountStatus) {\n        case sdk.VaultAccountStatus.IN_STAKING: //sdk.VaultAccountStatus.IN_STAKING:\n          setShowVaultLoan({ isShow: true, symbol: key ?? '', type: VaultLoanType.Repay })\n          break\n      }\n    },\n  })\n  const history = useHistory()\n\n  const onGoToSwap = ({ symbol, isSell }: { symbol?: string; isSell?: boolean }) => {\n    const searchParams = new URLSearchParams()\n    symbol !== undefined && searchParams.append('symbol', symbol)\n    isSell !== undefined && searchParams.append('isSell', isSell ? 'true' : 'false')\n    \n    history.push(RouterPath.vault + '/' + VaultKey.VAULT_TRADE + `?${searchParams.toString()}`)\n  }\n\n  const label = React.useCallback((btnLabel) => {\n    const key = btnLabel.split('|')\n    return t(key[0], {\n      arg: key[1],\n      // symbol: tradeCalcProData.coinBase,\n      layer2: L1L2_NAME_DEFINED[network].layer2,\n      loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n      loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n      l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n      l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n      ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n    })\n  }, [])\n  const { account } = useAccount()\n  React.useEffect(() => {\n    if (account.apiKey) updateVaultLayer2({})\n  }, [account.apiKey])\n\n  return {\n    joinBtnStatus,\n    joinBtnLabel: label(joinBtnLabel),\n    onJoinPop,\n    vaultAccountInfo,\n    swapBtnStatus,\n    swapBtnLabel: label(swapBtnLabel),\n    onSwapPop,\n    redeemBtnStatus,\n    onRedeemPop,\n    redeemBtnLabel: label(redeemBtnLabel),\n    borrowBtnStatus,\n    onBorrowPop,\n    borrowBtnLabel: label(borrowBtnLabel),\n    repayBtnStatus,\n    onRepayPop,\n    repayBtnLabel: label(repayBtnLabel),\n    vaultAccountInfoStatus,\n    tokenFactors,\n    maxLeverage,\n    collateralTokens,\n    onGoToSwap,\n  } as VaultAccountInfoStatus\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/vault/useVaultBorrow.ts",
    "content": "import {\n  CustomErrorWithCode,\n  EmptyValueTag,\n  getValuePrecisionThousand,\n  IBData,\n  myLog,\n  SDK_ERROR_MAP_TO_UI,\n  SUBMIT_PANEL_AUTO_CLOSE,\n  SUBMIT_PANEL_CHECK,\n  TradeBtnStatus,\n  UIERROR_CODE,\n  VaultBorrowData,\n} from '@loopring-web/common-resources'\nimport {\n  AccountStep,\n  SwitchData,\n  useOpenModals,\n  VaultBorrowProps,\n} from '@loopring-web/component-lib'\nimport { useTranslation } from 'react-i18next'\nimport {\n  onchainHashInfo,\n  store,\n  useAccount,\n  useSystem,\n  useTokenMap,\n  useTokenPrices,\n  useTradeVault,\n  useVaultLayer2,\n  useVaultMap,\n} from '../../../stores'\nimport React, { useRef } from 'react'\nimport { makeVaultAvaiable2 } from '../../help'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { LoopringAPI } from '../../../api_wrapper'\nimport { useSubmitBtn, useUserWallets } from '../../common'\nimport BigNumber from 'bignumber.js'\nimport { l2CommonService } from '../../../services'\nimport { keys } from 'lodash'\nimport Decimal from 'decimal.js'\nimport { calcMarinLevel, marginLevelType } from './utils'\nimport { numberFormat } from '../../../utils'\nimport { utils } from 'ethers'\n\nexport type VaultBorrowTradeData = IBData<any> & {\n  erc20Symbol: string\n  borrowed: string\n  count: string\n}\n\nexport const calcSupportBorrowData = <T extends VaultBorrowTradeData>(\n  tradeData: T, // Omit<T, 'balance'> & { count: string },\n) => {\n  const {\n    invest: {\n      vaultMap: { tokenMap: vaultTokenMap, coinMap: vaultCoinMap },\n    },\n  } = store.getState()\n  let supportData: any = {\n    maxBorrowAmount: undefined,\n    maxBorrowStr: undefined,\n    minBorrowAmount: undefined,\n    minBorrowStr: undefined,\n    maxBorrowVol: undefined,\n    minBorrowVol: undefined,\n    maxQuote: undefined,\n    borrowVol: undefined,\n    borrowAmt: undefined,\n    totalQuote: undefined,\n  }\n  if (tradeData?.belong && vaultTokenMap) {\n    const borrowToken = vaultTokenMap[tradeData.belong]\n    const orderAmounts = borrowToken.orderAmounts\n    const minBorrowVol = BigNumber.max(\n      // orderAmounts.dust,\n      //@ts-ignore\n      borrowToken?.vaultTokenAmounts?.minLoanAmount,\n    )\n    const minBorrowAmt = minBorrowVol.div('1e' + borrowToken.decimals)\n    const totalQuote = sdk.toBig(orderAmounts.maximum ?? 0).div('1e' + borrowToken.decimals)\n    const maxBorrowAmt = sdk\n      .toBig(BigNumber.min(totalQuote, tradeData.count))\n      .toFixed(borrowToken?.vaultTokenAmounts?.qtyStepScale, BigNumber.ROUND_DOWN)\n    const tradeValue = tradeData.tradeValue\n    supportData = {\n      minBorrowAmount: minBorrowAmt?.toString(),\n      minBorrowStr: getValuePrecisionThousand(\n        minBorrowAmt ?? 0,\n        borrowToken.precision,\n        borrowToken.precision,\n        undefined,\n      ),\n      minBorrowVol: minBorrowVol.toString(),\n      maxQuote: orderAmounts.maximum,\n      borrowVol: sdk\n        .toBig(tradeValue ?? 0)\n        .times('1e' + borrowToken.decimals)\n        .toString(),\n      borrowAmtStr: getValuePrecisionThousand(\n        tradeValue ?? 0,\n        borrowToken.precision,\n        borrowToken.precision,\n        undefined,\n      ),\n      borrowedStr: getValuePrecisionThousand(\n        tradeData.borrowed ?? 0,\n        borrowToken.precision,\n        borrowToken.precision,\n        undefined,\n      ),\n      balance: maxBorrowAmt,\n      borrowAmt: tradeValue ?? 0,\n      totalQuote: totalQuote.toString(),\n      coinInfoMap: vaultCoinMap,\n      hourlyRateInPercent: sdk.toFixed(sdk.toNumber(borrowToken.interestRate) * 100, 6, false),\n      yearlyRateInPercent: sdk.toFixed(sdk.toNumber(borrowToken.interestRate) * 100 * 24 * 365, 2, false)\n    }\n  }\n  return {\n    ...supportData,\n  }\n}\nexport const useVaultBorrow = <\n  T extends VaultBorrowTradeData,\n  V extends VaultBorrowData<T>,\n  I,\n>(): Partial<VaultBorrowProps<T, I, V>> => {\n  const { t } = useTranslation()\n  const {\n    modals: { isShowVaultLoan },\n    setShowAccount,\n    setShowVaultLoan,\n  } = useOpenModals()\n\n  const [isLoading, setIsLoading] = React.useState(false)\n\n  const { exchangeInfo, forexMap } = useSystem()\n  const { tokenMap: vaultTokenMap, coinMap: vaultCoinMap, marketCoins, getVaultMap, tokenPrices: vaultTokenPrices } = useVaultMap()\n  const [walletMap, setWalletMap] = React.useState(() => {\n    const { vaultAvaiable2Map } = makeVaultAvaiable2({})\n    return vaultAvaiable2Map\n  })\n\n  const { updateVaultBorrowHash } = onchainHashInfo.useOnChainInfo()\n  // chainInfos[defaultNetwork].vaultBorrowHashes\n\n  const { vaultAccountInfo, status: vaultAccountInfoStatus, updateVaultLayer2 } = useVaultLayer2()\n  const { vaultBorrowData, updateVaultBorrow, resetVaultBorrow } = useTradeVault()\n  const { account } = useAccount()\n\n  // const [tradeData, setTradeData] = React.useState<T | undefined>(undefined)\n  \n  const timerRef = useRef<NodeJS.Timeout | null>(null)\n  const updateVaultBorrowDataRepeatly = async () => {\n    if (timerRef.current) {\n      clearInterval(timerRef.current)\n    }\n    const fn = async () => {\n      getVaultMap()\n      const vaultBorrowData = store.getState()._router_tradeVault.vaultBorrowData\n      let symbol = vaultBorrowData.belong as string | undefined\n      if (!symbol) { return }\n      const maxBorrowable = await LoopringAPI.vaultAPI?.getMaxBorrowable(\n        {\n          accountId: account.accountId,\n          symbol: symbol.slice(2),\n        },\n        account.apiKey,\n        '1',\n      )\n      const vaultBorrowData2 = store.getState()._router_tradeVault.vaultBorrowData\n      let symbol2 = vaultBorrowData2.belong as string | undefined\n      if (symbol2 !== symbol) { return }\n      const tokenPrice = vaultTokenPrices[symbol]\n      const vToken = vaultTokenMap[symbol]\n      const balance = numberFormat(\n        new Decimal(maxBorrowable!.maxBorrowableOfUsdt).div(tokenPrice).toString(),\n        {\n          fixed: vToken.vaultTokenAmounts.qtyStepScale,\n          removeTrailingZero: true,\n        },\n      )\n      const maxBorrowVol = utils.parseUnits(balance, vToken.decimals).toString()\n      updateVaultBorrow({\n        ...vaultBorrowData2,\n        balance: Number(balance),\n        tradeData: { ...vaultBorrowData2.tradeData, balance: Number(balance) },\n        maxBorrowAmount: balance,\n        maxBorrowStr: balance,\n        maxBorrowVol: maxBorrowVol.toString(),\n      })\n    }\n    timerRef.current = setInterval(fn, 10 * 1000)\n    fn()\n  }\n\n  const initData = async () => {\n    let vaultBorrowData: any = {}\n    let initSymbol = marketCoins[0]\n    if (isShowVaultLoan.info?.symbol) {\n      initSymbol = isShowVaultLoan.info?.symbol\n    }\n    let { vaultAvaiable2Map } = makeVaultAvaiable2({})\n    setWalletMap(vaultAvaiable2Map)\n    vaultBorrowData = {\n      ...vaultBorrowData,\n      vaultAvaiable2Map,\n      coinMap: vaultCoinMap,\n      walletMap: vaultAvaiable2Map,\n    }\n    let walletInfo\n    walletInfo = {\n      belong: initSymbol,\n      ...((vaultAvaiable2Map && vaultAvaiable2Map[initSymbol.toString()]) ?? {}),\n      // balance: (vaultAvaiable2Map && vaultAvaiable2Map[initSymbol.toString()]?.count) ?? 0,\n      tradeValue: undefined,\n      erc20Symbol: initSymbol.slice(2)\n    }\n    const supportdata = calcSupportBorrowData(walletInfo)\n    walletInfo = {\n      ...walletInfo,\n      borrowedAmt: walletInfo.borrowed,\n    }\n    vaultBorrowData = {\n      ...vaultBorrowData,\n      ...walletInfo,\n      ...supportdata,\n      walletMap: vaultAvaiable2Map,\n      tradeData: walletInfo,\n    }\n    updateVaultBorrow({\n      ...walletInfo,\n      ...vaultBorrowData,\n      ...calcSupportBorrowData(walletInfo),\n    })\n  }\n\n  \n\n  const onRefreshData = React.useCallback(() => {\n    getVaultMap()\n  }, [])\n\n  React.useEffect(() => {\n    if (isShowVaultLoan.isShow) {\n      initData()\n    } else {\n      if (timerRef.current) {\n        clearInterval(timerRef.current)\n      }\n      resetVaultBorrow()\n    }\n    // @ts-ignore\n  }, [isShowVaultLoan.isShow])\n\n  React.useEffect(() => {\n    isShowVaultLoan.isShow && updateVaultBorrowDataRepeatly()\n  }, [isShowVaultLoan.isShow, vaultAccountInfo?.leverage, vaultBorrowData?.tradeData?.belong])\n\n  const handlePanelEvent = React.useCallback(\n    (data: SwitchData<T>) => {\n      if (data.to === 'button') {\n\n        let { vaultAvaiable2Map } = makeVaultAvaiable2({})\n        setWalletMap(vaultAvaiable2Map)\n        if (vaultAvaiable2Map && data?.tradeData?.belong) {\n          let walletInfo: any = vaultAvaiable2Map[data?.tradeData?.belong as string]\n          walletInfo = {\n            ...walletInfo,\n            tradeValue: data?.tradeData?.belong !== store.getState()._router_tradeVault.vaultBorrowData.tradeData.belong ? undefined : data.tradeData?.tradeValue,\n            borrowedAmt: walletInfo.borrowed,\n          }\n          const supportdata = calcSupportBorrowData(walletInfo)\n\n          updateVaultBorrow({\n            ...store.getState()._router_tradeVault.vaultBorrowData,\n            ...vaultBorrowData,\n            ...walletInfo,\n            ...supportdata,\n            walletMap: vaultAvaiable2Map,\n            tradeData: {\n              ...store.getState()._router_tradeVault.vaultBorrowData.tradeData,\n              ...walletInfo,\n            },\n          })\n        } else {\n          updateVaultBorrow({\n            belong: undefined,\n            tradeValue: undefined,\n            balance: undefined,\n          })\n        }\n      }\n    },\n    [account, updateVaultBorrow],\n  )\n\n  const availableTradeCheck = React.useCallback(() => {\n    const vaultBorrowData = store.getState()._router_tradeVault.vaultBorrowData\n    if (\n      !vaultBorrowData?.tradeValue ||\n      !vaultBorrowData?.belong ||\n      sdk.toBig(vaultBorrowData?.tradeValue ?? 0).lte(0)\n    ) {\n      return { tradeBtnStatus: TradeBtnStatus.DISABLED, label: '' }\n    } else if (sdk.toBig(vaultBorrowData?.tradeValue ?? 0).lt(vaultBorrowData.minBorrowAmount)) {\n      return {\n        tradeBtnStatus: TradeBtnStatus.DISABLED,\n        label: `labelVaultBorrowMini|${vaultBorrowData.minBorrowStr} ${vaultBorrowData.belong.slice(2)}`,\n      }\n    } else if (sdk.toBig(vaultBorrowData.tradeData.tradeValue ?? 0).gt(BigNumber.min(vaultBorrowData.totalQuote, vaultBorrowData.tradeData.balance))) {\n      return {\n        tradeBtnStatus: TradeBtnStatus.DISABLED,\n        label: `labelVaultBorrowNotEnough|${vaultBorrowData.belong}`,\n      }\n    } else {\n      return { tradeBtnStatus: TradeBtnStatus.AVAILABLE, label: '' }\n    }\n  }, [\n    vaultAccountInfoStatus,\n    vaultTokenMap,\n    vaultBorrowData,\n    vaultBorrowData.belong,\n    vaultBorrowData.tradeValue,\n    vaultBorrowData.balance,\n    vaultBorrowData.maxBorrowAmount,\n    vaultBorrowData.minBorrowAmount,\n    vaultBorrowData.tradeData\n  ])\n  const processRequest = async (request?: sdk.VaultBorrowRequest) => {\n    const vaultBorrowData = store.getState()._router_tradeVault.vaultBorrowData\n    const vaultToken = vaultTokenMap[vaultBorrowData.belong]\n    const {\n      account: { eddsaKey, apiKey, accountId, accAddress },\n    } = store.getState()\n    const erc20Symbol = vaultBorrowData.erc20Symbol\n\n    try {\n      if ((LoopringAPI.vaultAPI && request) || (vaultBorrowData.request && accountId)) {\n        let response = await LoopringAPI.vaultAPI.submitVaultBorrow({\n          request: request ?? vaultBorrowData.request,\n          privateKey: eddsaKey?.sk,\n          apiKey: apiKey,\n        }, '1')\n        if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n          throw response\n        }\n        setShowVaultLoan({\n          isShow: false,\n        })\n        setIsLoading(false)\n        l2CommonService.sendUserUpdate()\n        updateVaultBorrowHash((response as any).hash, accAddress)\n\n        await sdk.sleep(SUBMIT_PANEL_CHECK)\n        const response2 = await LoopringAPI?.vaultAPI.getVaultGetOperationByHash(\n          {\n            accountId: accountId?.toString(),\n            hash: (response as any).hash,\n          },\n          apiKey,\n          '1'\n        )\n        let status = ''\n        if (\n          response2?.raw_data?.operation?.status == sdk.VaultOperationStatus.VAULT_STATUS_FAILED\n        ) {\n          updateVaultBorrowHash((response as any).hash, accAddress, 'failed')\n          throw sdk.VaultOperationStatus.VAULT_STATUS_FAILED\n        } else if (\n          [sdk.VaultOperationStatus.VAULT_STATUS_SUCCEED].includes(\n            response2?.raw_data?.operation?.status,\n          )\n        ) {\n          updateVaultBorrowHash((response as any).hash, accAddress, 'success')\n          status = 'labelSuccessfully'\n        } else {\n          status = 'labelPending'\n        }\n        setShowAccount({\n          isShow: store.getState().modals.isShowAccount.isShow,\n          step:\n            status == 'labelSuccessfully'\n              ? AccountStep.VaultBorrow_Success\n              : AccountStep.VaultBorrow_In_Progress,\n          info: {\n            amount: sdk.VaultOperationStatus.VAULT_STATUS_SUCCEED\n              ? vaultBorrowData.borrowAmtStr\n              : 0,\n            sum: vaultBorrowData.borrowAmtStr,\n            status: t(status),\n            forexMap,\n            symbol: erc20Symbol,\n            vSymbol: vaultToken.symbol,\n            time: response2?.raw_data?.order?.createdAt,\n          },\n        })\n\n        await sdk.sleep(SUBMIT_PANEL_AUTO_CLOSE)\n        l2CommonService.sendUserUpdate()\n\n        if (\n          store.getState().modals.isShowAccount.isShow &&\n          [AccountStep.VaultBorrow_Success, AccountStep.VaultBorrow_In_Progress].includes(\n            store.getState().modals.isShowAccount.step,\n          )\n        ) {\n          setShowAccount({ isShow: false })\n        }\n      } else {\n        throw new Error('api not ready')\n      }\n    } catch (e) {\n      setIsLoading(false)\n      const code =\n        (e as any)?.message === sdk.VaultOperationStatus.VAULT_STATUS_FAILED\n          ? UIERROR_CODE.ERROR_ORDER_FAILED\n          : (e as sdk.RESULT_INFO)?.code ?? UIERROR_CODE.UNKNOWN\n      const error = new CustomErrorWithCode({\n        code,\n        message: (e as sdk.RESULT_INFO)?.message,\n        ...SDK_ERROR_MAP_TO_UI[code],\n      })\n      setShowAccount({\n        isShow: true,\n        step: AccountStep.VaultBorrow_Failed,\n        info: {\n          amount: EmptyValueTag,\n          sum: vaultBorrowData.borrowAmtStr,\n          status: t('labelFailed'),\n          forexMap,\n          symbol: erc20Symbol,\n          vSymbol: vaultBorrowData.belong,\n          time: Date.now(),\n          title: t('labelVaultBorrowTitle'),\n        },\n        error,\n      })\n    }\n  }\n\n  const submitCallback = async () => {\n    const vaultBorrowData = store.getState()._router_tradeVault.vaultBorrowData\n    const account = store.getState().account\n    const erc20Symbol = vaultBorrowData.erc20Symbol\n    setIsLoading(true)\n    try {\n      if (\n        vaultBorrowData &&\n        exchangeInfo &&\n        vaultBorrowData.belong &&\n        LoopringAPI.vaultAPI &&\n        LoopringAPI.userAPI &&\n        vaultAccountInfo &&\n        sdk.toBig(vaultBorrowData.borrowVol).gte(vaultBorrowData.minBorrowVol ?? 0) &&\n        sdk.toBig(vaultBorrowData.borrowVol).lte(vaultBorrowData.maxBorrowVol ?? 0)\n      ) {\n        setShowAccount({\n          isShow: true,\n          step: AccountStep.VaultBorrow_In_Progress,\n          info: {\n            amount: EmptyValueTag,\n            sum: vaultBorrowData.borrowAmtStr,\n            status: t('labelPending'),\n            forexMap,\n            symbol: erc20Symbol,\n            vSymbol: vaultBorrowData.belong,\n            time: Date.now(),\n            title: t('labelVaultBorrowTitle'),\n          },\n        })\n\n        const vaultBorrowRequest: sdk.VaultBorrowRequest = {\n          accountId: account.accountId,\n          token: {\n            tokenId: vaultTokenMap[vaultBorrowData.belong].vaultTokenId as unknown as number,\n            volume: vaultBorrowData.borrowVol,\n          },\n          timestamp: Date.now(),\n        }\n        updateVaultBorrow({\n          ...vaultBorrowData,\n          request: vaultBorrowRequest,\n        })\n        processRequest(vaultBorrowRequest)\n      }\n    } catch (e) {\n      setIsLoading(false)\n      setShowAccount({\n        isShow: true,\n        step: AccountStep.VaultBorrow_Failed,\n        info: {\n          amount: EmptyValueTag,\n          sum: vaultBorrowData.borrowAmtStr,\n          status: t('labelFailed'),\n          forexMap,\n          symbol: erc20Symbol,\n          vSymbol: vaultBorrowData.belong,\n          time: Date.now(),\n          title: t('labelVaultBorrowTitle'),\n        },\n        error: {\n          ...(e as any),\n        },\n      })\n    }\n  }\n\n  const {\n    btnStatus,\n    onBtnClick,\n    btnLabel,\n    // btnStyle: tradeLimitBtnStyle,\n  } = useSubmitBtn({\n    availableTradeCheck,\n    isLoading,\n    submitCallback,\n  })\n\n  \n  const moreToBorrowInUSD = (vaultBorrowData.tradeData && vaultTokenPrices[vaultBorrowData.tradeData.belong as string])\n    ? new Decimal(vaultBorrowData.tradeData.tradeValue ?? '0')\n        .mul(vaultTokenPrices[vaultBorrowData.tradeData.belong as string])\n        .toString()\n    : undefined\n  const nextMarginLevel =\n    vaultAccountInfo && moreToBorrowInUSD\n      ? calcMarinLevel(\n        vaultAccountInfo.totalCollateralOfUsdt,\n        vaultAccountInfo.totalDebtOfUsdt,\n        vaultAccountInfo.totalBalanceOfUsdt,\n        moreToBorrowInUSD,\n        '0'\n        )\n      : vaultAccountInfo?.marginLevel\n  \n\n  return {\n    handlePanelEvent,\n    vaultBorrowBtnStatus: btnStatus,\n    vaultBorrowBtnI18nKey: btnLabel,\n    onVaultBorrowClick: onBtnClick,\n    walletMap: walletMap as unknown as any,\n    coinMap: keys(walletMap ?? {}).reduce((prev, key) => {\n      return {\n        ...prev,\n        [key]: {\n          ...vaultCoinMap[key?.toString() ?? ''],\n          erc20Symbol: vaultCoinMap[key?.toString() ?? '']?.simpleName.slice(2),\n          belongAlice: vaultCoinMap[key?.toString() ?? '']?.simpleName.slice(2),\n        },\n      }\n    }, {}),\n    tradeData: vaultBorrowData.tradeData as any,\n    vaultBorrowData: vaultBorrowData as V,\n    onRefreshData,\n    tokenProps: {\n      decimalsLimit:\n        vaultTokenMap[vaultBorrowData?.tradeData?.belong]?.vaultTokenAmounts?.qtyStepScale,\n      allowDecimals: vaultTokenMap[vaultBorrowData?.tradeData?.belong]?.vaultTokenAmounts\n        ?.qtyStepScale\n        ? true\n        : false,\n    },\n    marginLevelChange: vaultAccountInfo?.marginLevel\n      ? nextMarginLevel && vaultBorrowData.tradeValue\n        ? {\n            from: {\n              marginLevel: vaultAccountInfo.marginLevel,\n              type: marginLevelType(vaultAccountInfo.marginLevel),\n            },\n            to: {\n              marginLevel: nextMarginLevel,\n              type: marginLevelType(nextMarginLevel),\n            },\n          }\n        : {\n            from: {\n              marginLevel: vaultAccountInfo.marginLevel,\n              type: marginLevelType(vaultAccountInfo.marginLevel),\n            },\n            to: {\n              marginLevel: vaultAccountInfo.marginLevel,\n              type: marginLevelType(vaultAccountInfo.marginLevel),\n            },\n          }\n      : undefined,\n    userLeverage: vaultAccountInfo?.leverage,\n    hideLeverage: (vaultAccountInfo as any)?.accountType === 0,\n  }\n}"
  },
  {
    "path": "packages/core/src/hooks/useractions/vault/useVaultJoin.ts",
    "content": "import { AccountStep, SwitchData, useOpenModals, VaultJoinProps } from '@loopring-web/component-lib'\nimport {\n  AccountStatus,\n  CoinInfo,\n  CoinMap,\n  EmptyValueTag,\n  getValuePrecisionThousand,\n  IBData,\n  SUBMIT_PANEL_AUTO_CLOSE,\n  SUBMIT_PANEL_CHECK,\n  TRADE_TYPE,\n  TradeBtnStatus,\n  WalletMap,\n  myLog,\n  mapSpecialTokenName,\n} from '@loopring-web/common-resources'\nimport React from 'react'\nimport {\n  DAYS,\n  getTimestampDaysLater,\n  LoopringAPI,\n  makeVaultLayer2,\n  makeWalletLayer2,\n  store,\n  useAccount,\n  useSubmitBtn,\n  useSystem,\n  useTokenMap,\n  useTradeVault,\n  useVaultLayer2,\n  useVaultMap,\n  useL2CommonSocket,\n  l2CommonService,\n  NETWORKEXTEND,\n  useTokenPrices,\n  numberFormat,\n  useUserWallets,\n} from '@loopring-web/core'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport {\n  ConnectProviders,\n  ConnectProvidersSignMap,\n  connectProvides,\n} from '@loopring-web/web3-provider'\nimport { useTranslation } from 'react-i18next'\nimport BigNumber from 'bignumber.js'\nimport { VaultAccountStatus } from '@loopring-web/loopring-sdk'\nimport { keys } from 'lodash'\nimport { calcMarinLevel, marginLevelType } from './utils'\nimport Decimal from 'decimal.js'\nimport { utils } from 'ethers'\nimport { useBasicTrade } from '@loopring-web/component-lib/src/components/tradePanel/components'\n\nconst DATE_IN_TEN_YEARS = 2027988026\n\nexport const useVaultJoin = <T extends IBData<I>, I>() => {\n  const { t } = useTranslation()\n  const { tokenMap: vaultTokenMap, joinTokenMap, erc20Map, getVaultMap } = useVaultMap()\n  const { tokenMap, coinMap, idIndex } = useTokenMap()\n  const { status: vaultAccountInfoStatus, vaultAccountInfo, updateVaultLayer2 } = useVaultLayer2()\n  const { updateUserWallets } = useUserWallets()\n\n  const { exchangeInfo, chainId, baseURL } = useSystem()\n  const { account } = useAccount()\n  const { updateVaultJoin, vaultJoinData, resetVaultJoin } = useTradeVault()\n  const [isLoading, setIsLoading] = React.useState(false)\n  const [isAddOrRedeem, setIsAddOrRedeem] = React.useState<'Add' | 'Redeem'>('Add')\n  const { tokenPrices } = useTokenPrices()\n\n  const isActiveAccount =\n    [sdk.VaultAccountStatus.FREE, sdk.VaultAccountStatus.UNDEFINED].includes(\n      vaultAccountInfo?.accountStatus ?? ('' as any),\n    ) ||\n    vaultAccountInfo == undefined ||\n    vaultAccountInfo?.accountStatus == undefined\n  const calcSupportData = (tradeData: T) => {\n    let supportData = {}\n\n    if (tradeData?.belong && walletAllowMap && walletAllowMap[tradeData.belong as any]) {\n      const vaultTokenSymbol = walletAllowMap[tradeData.belong as any]?.vaultToken\n      const vaultTokenInfo = vaultTokenMap[vaultTokenSymbol]\n      const ercToken = tokenMap[tradeData.belong]\n      const minAmount =\n        vaultAccountInfo?.accountStatus === VaultAccountStatus.IN_STAKING\n          ? sdk\n              .toBig('10')\n              .exponentiatedBy(-1 * vaultTokenInfo?.vaultTokenAmounts?.qtyStepScale)\n              .toString()\n          : sdk\n              .toBig(vaultTokenInfo?.vaultTokenAmounts?.minAmount)\n              .div('1e' + vaultTokenInfo.decimals)\n              .toString()\n      supportData = {\n        maxShowVal: getValuePrecisionThousand(\n          sdk\n            //@ts-ignore\n            .toBig(vaultTokenInfo?.vaultTokenAmounts?.maxAmount ?? 0)\n            .div('1e' + ercToken.decimals),\n          vaultTokenInfo?.vaultTokenAmounts?.qtyStepScale,\n          vaultTokenInfo?.vaultTokenAmounts?.qtyStepScale,\n          undefined,\n        ),\n\n        minShowVal: getValuePrecisionThousand(\n          minAmount,\n          vaultTokenInfo?.vaultTokenAmounts?.qtyStepScale,\n          vaultTokenInfo?.vaultTokenAmounts?.qtyStepScale,\n          undefined,\n        ),\n        maxAmount: vaultTokenInfo?.vaultTokenAmounts?.maxAmount,\n        minAmount: sdk.toBig(minAmount).times('1e' + vaultTokenInfo.decimals),\n        vaultSymbol: vaultTokenSymbol,\n        vaultTokenInfo,\n      }\n    }\n    return {\n      ...supportData,\n    }\n  }\n  const availableTradeCheck = React.useCallback(() => {\n    const vaultAccountInfoSymbol =\n      idIndex[vaultAccountInfo?.collateralInfo?.collateralTokenId ?? ''] ?? ''\n    const vaultJoinData = store.getState()._router_tradeVault.vaultJoinData\n    if (!vaultJoinData?.amount && sdk.toBig(vaultJoinData?.amount ?? 0).lte(0)) {\n      return { tradeBtnStatus: TradeBtnStatus.DISABLED, label: '' }\n    } else if (\n      !isActiveAccount &&\n      vaultAccountInfoSymbol &&\n      vaultJoinData.belong !== vaultAccountInfoSymbol\n    ) {\n      return {\n        tradeBtnStatus: TradeBtnStatus.DISABLED,\n        label: `labelVaultJoinSymbolNotSame|${vaultJoinData.belong}`,\n      }\n    } else if (sdk.toBig(vaultJoinData.amount).lt(vaultJoinData.minAmount)) {\n      return {\n        tradeBtnStatus: TradeBtnStatus.DISABLED,\n        label: `labelVaultJoinMini|${vaultJoinData.minShowVal} ${mapSpecialTokenName(vaultJoinData.belong as string)}`,\n      }\n    } else if (sdk.toBig(vaultJoinData.tradeValue ?? 0).gt(vaultJoinData.balance ?? 0)) {\n      return {\n        tradeBtnStatus: TradeBtnStatus.DISABLED,\n        label:\n          isAddOrRedeem === 'Add'\n            ? `labelVaultJoinNotEnough|${vaultJoinData.belong}`\n            : `labelVaultRedeemNotEnough|${vaultJoinData.belong}`,\n      }\n    } else if (sdk.toBig(vaultJoinData.amount ?? 0).gt(vaultJoinData.maxAmount ?? 0)) {\n      return {\n        tradeBtnStatus: TradeBtnStatus.DISABLED,\n        label: `labelVaultJoinMax|${vaultJoinData.maxShowVal} ${vaultJoinData.belong}`,\n      }\n    } else {\n      return { tradeBtnStatus: TradeBtnStatus.AVAILABLE, label: '' }\n    }\n  }, [\n    vaultAccountInfoStatus,\n    tokenMap,\n    vaultJoinData,\n    vaultJoinData.tradeValue,\n    vaultJoinData.balance,\n    vaultJoinData.amount,\n    vaultJoinData.maxAmount,\n    vaultJoinData.minAmount,\n    vaultJoinData.belong,\n    isAddOrRedeem,\n  ])\n  const processRequest = async (request?: sdk.VaultJoinRequest) => {\n\n    const vaultJoinData = store.getState()._router_tradeVault.vaultJoinData ?? {}\n    const ercToken = tokenMap[vaultJoinData?.belong?.toString() ?? '']\n    try {\n      if (LoopringAPI.vaultAPI && (request || vaultJoinData.request) && ercToken) {\n        let response = await LoopringAPI.vaultAPI.submitVaultJoin(\n          {\n            // @ts-ignore\n            request: request ?? vaultJoinData.request,\n            eddsaKey: account.eddsaKey.sk,\n            apiKey: account.apiKey,\n            web3: connectProvides.usedWeb3 as any,\n            chainId: chainId === 'unknown' ? 1 : chainId,\n            walletType: (ConnectProvidersSignMap[account.connectName] ??\n              account.connectName) as unknown as sdk.ConnectorNames,\n          },\n          '1',\n        )\n        if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n          throw response\n        }\n        if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n          throw response\n        } else {\n          updateUserWallets()\n          updateVaultLayer2(\n            isActiveAccount\n              ? {\n                  activeInfo: {\n                    hash: (response as any).hash,\n                    isInActive: true,\n                  },\n                }\n              : {},\n          )\n          setShowVaultJoin({ isShow: false })\n          setIsLoading(false)\n          await sdk.sleep(SUBMIT_PANEL_CHECK)\n          const response2 = await LoopringAPI.vaultAPI.getVaultGetOperationByHash(\n            {\n              accountId: account?.accountId?.toString(),\n              hash: (response as any).hash,\n            },\n            account.apiKey,\n            '1',\n          )\n          let status = ''\n          if (\n            response2?.raw_data?.operation?.status == sdk.VaultOperationStatus.VAULT_STATUS_FAILED\n          ) {\n            throw sdk.VaultOperationStatus.VAULT_STATUS_FAILED\n          } else if (\n            [\n              sdk.VaultOperationStatus.VAULT_STATUS_EARNING,\n              sdk.VaultOperationStatus.VAULT_STATUS_SUCCEED,\n            ].includes(response2?.raw_data?.operation?.status)\n          ) {\n            status = 'labelSuccessfully'\n          } else {\n            status = 'labelPending'\n          }\n\n          setShowAccount({\n            isShow: store.getState().modals.isShowAccount.isShow,\n            step:\n              status == 'labelSuccessfully'\n                ? AccountStep.VaultJoin_Success\n                : AccountStep.VaultJoin_In_Progress,\n            info: {\n              title: isActiveAccount\n                ? t('labelVaultJoinTitle')\n                : isAddOrRedeem === 'Add'\n                ? t('labelVaultJoinAdd')\n                : t('labelVaultRedeem'),\n              type: isActiveAccount\n                ? t('labelVaultJoin')\n                : isAddOrRedeem === 'Redeem'\n                ? t('labelVaultRedeem')\n                : t('labelVaultMarginCall'),\n              status: t(status),\n              amount: sdk.VaultOperationStatus.VAULT_STATUS_SUCCEED\n                ? getValuePrecisionThousand(\n                    vaultJoinData.tradeValue,\n                    ercToken.precision,\n                    ercToken.precision,\n                    undefined,\n                  )\n                : 0,\n              sum: getValuePrecisionThousand(\n                vaultJoinData.tradeValue,\n                ercToken.precision,\n                ercToken.precision,\n                undefined,\n              ),\n              symbol: ercToken.symbol,\n              vSymbol: vaultJoinData.vaultSymbol,\n              time: response2?.raw_data?.order?.createdAt,\n            },\n          })\n        }\n\n        await sdk.sleep(SUBMIT_PANEL_AUTO_CLOSE)\n        l2CommonService.sendUserUpdate()\n        if (\n          store.getState().modals.isShowAccount.isShow &&\n          [AccountStep.VaultJoin_Success, AccountStep.VaultJoin_In_Progress].includes(\n            store.getState().modals.isShowAccount.step,\n          )\n        ) {\n          setShowAccount({ isShow: false })\n        }\n      } else {\n        throw new Error('api not ready')\n      }\n    } catch (e) {\n      let error\n      setIsLoading(false)\n      setShowAccount({\n        isShow: true,\n        step: AccountStep.VaultJoin_Failed,\n        info: {\n          title: isActiveAccount\n            ? t('labelVaultJoinTitle')\n            : isAddOrRedeem === 'Add'\n            ? t('labelVaultJoinAdd')\n            : t('labelVaultRedeem'),\n          type: isActiveAccount\n            ? t('labelVaultJoin')\n            : isAddOrRedeem === 'Redeem'\n            ? t('labelVaultRedeem')\n            : t('labelVaultMarginCall'),\n          status: t('labelFailed'),\n          percentage: '0',\n          amount: EmptyValueTag,\n          sum: getValuePrecisionThousand(\n            vaultJoinData.tradeValue,\n            ercToken.precision,\n            ercToken.precision,\n            undefined,\n          ),\n          symbol: ercToken.symbol,\n          vSymbol: vaultJoinData.vaultSymbol,\n          time: Date.now(),\n        },\n        error,\n      })\n    }\n  }\n\n  const submitCallback = async () => {\n    const vaultJoinData = store.getState()._router_tradeVault.vaultJoinData\n    const ercToken = tokenMap[vaultJoinData?.belong ?? ''] ?? {}\n    try {\n      if (\n        vaultJoinData &&\n        exchangeInfo &&\n        vaultJoinData.belong &&\n        LoopringAPI.vaultAPI &&\n        LoopringAPI.userAPI &&\n        LoopringAPI.defiAPI &&\n        vaultAccountInfo &&\n        sdk.toBig(vaultJoinData.amount).gte(vaultJoinData.minAmount ?? 0) &&\n        sdk.toBig(vaultJoinData.amount).lte(vaultJoinData.maxAmount ?? 0)\n      ) {\n        setIsLoading(true)\n        const taikoFarmingPositionInfo = await LoopringAPI.defiAPI.getTaikoFarmingPositionInfo({accountId: account.accountId});\n        if (\n          [0, 3].includes(taikoFarmingPositionInfo.account.status) &&\n          vaultJoinData.tradeData.belong === 'LRTAIKO'\n        ) {\n          throw {\n            message: 'Cannot use lrTAIKO as collateral under the current conditions.',\n          }\n        }\n        setShowAccount({\n          isShow: true,\n          step: AccountStep.VaultJoin_In_Progress,\n          info: {\n            title: isActiveAccount\n              ? t('labelVaultJoinTitle')\n              : isAddOrRedeem === 'Add'\n              ? t('labelVaultJoinAdd')\n              : t('labelVaultRedeem'),\n            type: isActiveAccount\n              ? t('labelVaultJoin')\n              : isAddOrRedeem === 'Redeem'\n              ? t('labelVaultRedeem')\n              : t('labelVaultJoinAdd'),\n            status: t('labelPending'),\n            percentage: '0',\n            amount: EmptyValueTag,\n            sum: getValuePrecisionThousand(\n              vaultJoinData.tradeValue,\n              ercToken?.precision ?? 6,\n              ercToken?.precision ?? 6,\n              undefined,\n            ),\n            symbol: ercToken.symbol,\n            vSymbol: vaultJoinData.vaultSymbol,\n            time: Date.now(),\n          },\n        })\n        let number = 3\n        // Step 1: check rest balance (loop three times for dust)\n        while (number--) {\n          if (isActiveAccount) {\n            const response = await LoopringAPI.vaultAPI.getVaultBalance(\n              {\n                accountId: account.accountId,\n                tokens: '',\n              },\n              account.apiKey,\n              '1',\n            )\n\n            if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n              throw response\n            } else if (response.raw_data?.length) {\n              const tokenListIgnoreZero: any = []\n              const promiseAllStorageId =\n                response?.raw_data?.reduce((prev, item) => {\n                  if (sdk.toBig(item?.total).gt(0)) {\n                    tokenListIgnoreZero.push(item)\n                    prev.push(\n                      //@ts-ignore\n                      LoopringAPI.userAPI.getNextStorageId(\n                        {\n                          accountId: account.accountId,\n                          sellTokenId: item.tokenId,\n                        },\n                        account.apiKey,\n                      ),\n                    )\n                  }\n                  return prev\n                }, [] as Array<Promise<any>>) ?? []\n              if (tokenListIgnoreZero.length === 0) {\n                break\n              }\n              const { broker } = await LoopringAPI.userAPI?.getAvailableBroker({\n                type: 4,\n              })\n              await Promise.all([...promiseAllStorageId]).then((result) => {\n                return Promise.all(\n                  result.map((item, index) => {\n                    return (\n                      item &&\n                      LoopringAPI.vaultAPI?.sendVaultResetToken(\n                        {\n                          request: {\n                            exchange: exchangeInfo.exchangeAddress,\n                            payerAddr: account.accAddress,\n                            payerId: account.accountId,\n                            payeeId: 0,\n                            payeeAddr: broker,\n                            storageId: item.offchainId,\n                            token: {\n                              tokenId: tokenListIgnoreZero[index].tokenId,\n                              volume: tokenListIgnoreZero[index].total,\n                            },\n                            maxFee: {\n                              tokenId: tokenListIgnoreZero[index].tokenId,\n                              volume: '0',\n                            },\n                            validUntil: getTimestampDaysLater(DAYS),\n                            memo: '',\n                          } as any,\n                          web3: connectProvides.usedWeb3 as any,\n                          chainId:\n                            chainId === NETWORKEXTEND.NONETWORK ? sdk.ChainId.MAINNET : chainId,\n                          walletType: (ConnectProviders[account.connectName] ??\n                            account.connectName) as unknown as sdk.ConnectorNames,\n                          eddsaKey: account.eddsaKey.sk,\n                          apiKey: account.apiKey,\n                        },\n                        {\n                          accountId: account.accountId,\n                          counterFactualInfo: account.eddsaKey.counterFactualInfo,\n                        },\n                        '1',\n                      )\n                    )\n                  }),\n                )\n              })\n            }\n          }\n        }\n\n        // Step 2: get a NFT\n        const [avaiableNFT, storageId] = await Promise.all([\n          isActiveAccount\n            ? LoopringAPI.vaultAPI\n                .getVaultGetAvailableNFT(\n                  {\n                    accountId: account.accountId,\n                  },\n                  account.apiKey,\n                )\n                .then((avaiableNFT) => {\n                  if (\n                    avaiableNFT &&\n                    ((avaiableNFT as sdk.RESULT_INFO).code ||\n                      (avaiableNFT as sdk.RESULT_INFO).message)\n                  ) {\n                    throw avaiableNFT\n                  }\n                  return {\n                    ...avaiableNFT.raw_data,\n                  }\n                })\n            : Promise.resolve({\n                ...vaultAccountInfo.collateralInfo,\n                tokenId: vaultAccountInfo?.collateralInfo?.nftTokenId,\n              }),\n          LoopringAPI.userAPI.getNextStorageId(\n            {\n              accountId: account.accountId,\n              sellTokenId: tokenMap[vaultJoinData.belong].tokenId,\n            },\n            account.apiKey,\n          ),\n        ])\n\n        if (\n          storageId &&\n          ((storageId as sdk.RESULT_INFO).code || (storageId as sdk.RESULT_INFO).message)\n        ) {\n          throw storageId\n        }\n        const amount = isActiveAccount\n          ? sdk.toBig(vaultJoinData.amount)\n          : isAddOrRedeem === 'Add'\n          ? sdk\n              .toBig(vaultAccountInfo?.collateralInfo?.collateralTokenAmount)\n              .plus(vaultJoinData.amount)\n          : sdk\n              .toBig(vaultAccountInfo?.collateralInfo?.collateralTokenAmount)\n              .minus(vaultJoinData.amount)\n        const takerOrder: sdk.VaultJoinRequest = {\n          exchange: exchangeInfo.exchangeAddress,\n          accountId: account.accountId,\n          storageId: storageId.orderId,\n          sellToken: {\n            tokenId: tokenMap[vaultJoinData.belong].tokenId,\n            amount: amount.toString(),\n          },\n          buyToken: {\n            //@ts-ignore\n            tokenId: avaiableNFT.tokenId,\n            //@ts-ignore\n            nftData: avaiableNFT.nftData,\n            amount: '1',\n          },\n          allOrNone: false,\n          fillAmountBOrS: true,\n          validUntil: DATE_IN_TEN_YEARS,\n          maxFeeBips: 100,\n          joinHash: isActiveAccount ? '' : (avaiableNFT as any)?.orderHash,\n        }\n        updateVaultJoin({\n          ...vaultJoinData,\n          __request__: takerOrder,\n          request: takerOrder,\n        })\n        processRequest(takerOrder)\n      }\n    } catch (e) {\n      setIsLoading(false)\n      setShowAccount({\n        isShow: true,\n        step: AccountStep.VaultJoin_Failed,\n        info: {\n          title: isActiveAccount\n            ? t('labelVaultJoinTitle')\n            : isAddOrRedeem === 'Add'\n            ? t('labelVaultJoinAdd')\n            : t('labelVaultRedeem'),\n          type: isActiveAccount\n            ? t('labelVaultJoin')\n            : isAddOrRedeem === 'Redeem'\n            ? t('labelVaultRedeem')\n            : t('labelVaultMarginCall'),\n          status: t('labelFailed'),\n          percentage: '0',\n          amount: EmptyValueTag,\n          sum: EmptyValueTag,\n          symbol: ercToken.symbol,\n          vSymbol: vaultJoinData.vaultSymbol,\n          time: Date.now(),\n        },\n        error: {\n          ...(e as any),\n        },\n      })\n    }\n  }\n\n  const {\n    btnStatus,\n    onBtnClick,\n    btnLabel,\n\n  } = useSubmitBtn({\n    availableTradeCheck,\n    isLoading,\n    submitCallback,\n  })\n\n  const {\n    modals: {\n      isShowVaultJoin: { isShow, symbol },\n\n    },\n    setShowVaultJoin,\n    setShowAccount,\n  } = useOpenModals()\n  const makeWalletLayer2ForVault = () => {\n    let walletMap = makeWalletLayer2({ needFilterZero: true }).walletMap ?? {}\n    Reflect.ownKeys(walletMap ?? {}).forEach((symbol) => {\n      walletMap[symbol.toString()] = {\n        ...walletMap[symbol.toString()],\n        count: sdk\n          .toBig((walletMap && walletMap[symbol.toString()]?.count) ?? 0)\n          .toFixed(erc20Map[symbol]?.vaultTokenAmounts?.qtyStepScale, BigNumber.ROUND_DOWN),\n      } as any\n    })\n    return walletMap\n  }\n\n  const walletAllowMap =\n    joinTokenMap &&\n    (keys(joinTokenMap)\n      .filter((key) => {\n        return joinTokenMap[key].vaultTokenAmounts.status & 2\n      })\n      .reduce((pre, cur) => {\n        const value = joinTokenMap[cur]\n        const symbolWithLV = cur.slice(2)\n        return {\n          ...pre,\n          [symbolWithLV]: {\n            vaultToken: cur,\n            vaultId: value.vaultTokenId,\n            name: symbolWithLV,\n            simpleName: symbolWithLV,\n          },\n        }\n      }, {}) as { name: string; simpleName: string; vaultToken: string; vaultId: number })\n\n  const initData = () => {\n    let vaultJoinData: any = {}\n    let walletMap = makeWalletLayer2ForVault()\n    let vaultMap = makeVaultLayer2({ needFilterZero: true }).vaultLayer2Map ?? {}\n    vaultJoinData = {\n      ...vaultJoinData,\n      walletMap,\n      vaultMap,\n      coinMap: walletAllowMap,\n    }\n    let walletInfo,\n      isActiveAccount =\n        !vaultAccountInfo?.accountStatus ||\n        [VaultAccountStatus.FREE, VaultAccountStatus.UNDEFINED].includes(\n          vaultAccountInfo?.accountStatus,\n        )\n\n    const initSymbol = (() => {\n      const availableCollaterals = Object.keys(walletAllowMap).filter(key => \n        joinTokenMap[key]?.vaultTokenAmounts.status & 2\n      )    \n      if (symbol && availableCollaterals.includes(`LV${symbol}`)) {\n        return symbol\n      } else if (availableCollaterals.length > 0) {\n        return availableCollaterals[0]\n      }\n      if (\n        account &&\n        account.readyState === AccountStatus.ACTIVATED &&\n        !isActiveAccount &&\n        vaultAccountInfo?.collateralInfo?.collateralTokenId !== undefined\n      ) {\n        return idIndex[vaultAccountInfo?.collateralInfo.collateralTokenId]\n      } else if (account.readyState === AccountStatus.ACTIVATED && !symbol) {\n        const key = Reflect.ownKeys(joinTokenMap).find((keyVal) => {\n          if (!(joinTokenMap[keyVal.toString()]?.vaultTokenAmounts.status & 2)) {\n            return false;\n          }\n          const erc20Symbol = idIndex[joinTokenMap[keyVal.toString()]?.tokenId]\n          const walletInfo = walletMap[erc20Symbol] ?? { count: 0 }\n          return sdk.toBig(walletInfo?.count ?? 0).gt(0);\n        })\n        if (key) {\n          return idIndex[joinTokenMap[key.toString()]?.tokenId].toString()\n        }\n      }\n      return 'ETH'\n    })()\n    \n    const maxRedeemCollateral =\n      vaultAccountInfo && (vaultAccountInfo as any).maxRedeemCollateral\n        ? Decimal.max(\n            numberFormat(\n              utils.formatUnits(\n                (vaultAccountInfo as any).maxRedeemCollateral as string,\n                tokenMap[initSymbol].decimals,\n              ),\n              {\n                fixed: vaultTokenMap['LV' + initSymbol].vaultTokenAmounts.qtyStepScale,\n                removeTrailingZero: true,\n                fixedRound: Decimal.ROUND_FLOOR,\n              },\n            ),\n            '0',\n          ).toString()\n        : undefined\n    walletInfo = {\n      belong: initSymbol,\n      balance: isAddOrRedeem === 'Add' ? walletMap[initSymbol]?.count ?? 0 : maxRedeemCollateral,\n      tradeValue: undefined,\n    }\n    updateVaultJoin({\n      ...walletInfo,\n      ...vaultJoinData,\n      ...calcSupportData(walletInfo),\n      tradeData: walletInfo,\n    })\n  }\n  React.useEffect(() => {\n    if (isAddOrRedeem === 'Redeem') {\n      const symbol = vaultJoinData.belong as string\n      const maxRedeemCollateral =\n        vaultAccountInfo && (vaultAccountInfo as any).maxRedeemCollateral && tokenMap[symbol]\n          ? Decimal.max(\n              numberFormat(\n                utils.formatUnits(\n                  (vaultAccountInfo as any).maxRedeemCollateral as string,\n                  tokenMap[symbol].decimals,\n                ),\n                {\n                  fixed: vaultTokenMap['LV' + symbol].vaultTokenAmounts.qtyStepScale,\n                  removeTrailingZero: true,\n                  fixedRound: Decimal.ROUND_FLOOR,\n                },\n              ),\n              '0',\n            ).toString()\n          : undefined\n      updateVaultJoin({\n        ...vaultJoinData,\n        tradeData: {\n          ...vaultJoinData.tradeData,\n          // @ts-ignore\n          balance: maxRedeemCollateral,\n        },\n      })\n    }\n  }, [(vaultAccountInfo as any)?.maxRedeemCollateral, isAddOrRedeem])\n  const vaultLayer2Callback = React.useCallback(() => {\n    const vaultJoinData = store.getState()._router_tradeVault.vaultJoinData\n    let walletMap = makeWalletLayer2ForVault()\n    updateVaultJoin({\n      ...vaultJoinData,\n      walletMap,\n      vaultLayer2Map: makeVaultLayer2({ needFilterZero: true }).vaultLayer2Map,\n    })\n  }, [])\n\n  const walletLayer2Callback = React.useCallback(() => {\n    const vaultJoinData = store.getState()._router_tradeVault.vaultJoinData\n    updateVaultJoin({\n      ...vaultJoinData,\n      walletMap: makeWalletLayer2ForVault(),\n    })\n  }, [])\n  useL2CommonSocket({ walletLayer2Callback, vaultLayer2Callback })\n  React.useEffect(() => {\n    if (isShow) {\n      onRefreshData()\n      initData()\n    } else {\n      resetVaultJoin()\n    }\n  }, [isShow, isAddOrRedeem])\n  const onRefreshData = React.useCallback(() => {\n    getVaultMap()\n    updateUserWallets()\n  }, [])\n  const refreshRef = React.createRef()\n\n  const handlePanelEvent = async (data: SwitchData<T>, _switchType: 'Tomenu' | 'Tobutton') => {\n    const walletMap = makeWalletLayer2ForVault()\n    const tokenSymbol = data.tradeData.belong\n    const maxRedeemCollateral =\n      vaultAccountInfo &&\n      (vaultAccountInfo as any).maxRedeemCollateral &&\n      tokenMap[tokenSymbol as string]\n        ? Decimal.max(\n            numberFormat(\n              utils.formatUnits(\n                (vaultAccountInfo as any).maxRedeemCollateral as string,\n                tokenMap[tokenSymbol as string].decimals,\n              ),\n              {\n                fixed: vaultTokenMap['LV' + (tokenSymbol as string)].vaultTokenAmounts.qtyStepScale,\n                removeTrailingZero: true,\n                fixedRound: Decimal.ROUND_FLOOR,\n              },\n            ),\n            '0',\n          ).toString()\n        : undefined\n    let walletInfo: any = {\n      ...walletMap[tokenSymbol],\n      balance: isAddOrRedeem === 'Add' ? walletMap[tokenSymbol]?.count ?? 0 : maxRedeemCollateral,\n      tradeValue: data.tradeData?.tradeValue,\n      belong: tokenSymbol,\n    }\n    myLog('walletInfo', walletInfo)\n    if (tokenSymbol) {\n      updateVaultJoin({\n        ...vaultJoinData,\n        amount: sdk\n          .toBig(walletInfo.tradeValue ?? 0)\n          .times('1e' + tokenMap[tokenSymbol as string].decimals)\n          .toString(),\n        tradeData: walletInfo,\n        ...walletInfo,\n        ...calcSupportData(walletInfo),\n      })\n    }\n  }\n  const walletAllowCoin = React.useMemo(() => {\n    const vaultTokenSymbol = idIndex[vaultAccountInfo?.collateralInfo?.collateralTokenId ?? '']\n    return { [vaultTokenSymbol]: coinMap[vaultTokenSymbol] }\n  }, [vaultAccountInfo?.collateralInfo])\n\n\n  const moreToCollateralizeInUSD =\n    vaultJoinData.tradeData &&\n    vaultJoinData.tradeData.tradeValue &&\n    new Decimal(vaultJoinData.tradeData.tradeValue).gt(0) &&\n    tokenPrices[vaultJoinData.tradeData.belong as string]\n      ? new Decimal(vaultJoinData.tradeData.tradeValue ?? '0')\n          .mul(tokenPrices[vaultJoinData.tradeData.belong as string])\n          .mul(isAddOrRedeem === 'Add' ? 1 : -1)\n          .toString()\n      : undefined\n  const nextMarginLevel =\n    vaultAccountInfo && moreToCollateralizeInUSD\n      ? calcMarinLevel(\n          vaultAccountInfo.totalCollateralOfUsdt,\n          vaultAccountInfo.totalDebtOfUsdt,\n          vaultAccountInfo.totalBalanceOfUsdt,\n          '0',\n          moreToCollateralizeInUSD,\n        )\n      : undefined\n\n  const ercToken = vaultJoinData.tradeData && tokenMap[vaultJoinData.tradeData.belong as string]\n  const props = {\n    handleError: undefined,\n    type: TRADE_TYPE.TOKEN,\n    baseURL,\n    btnI18nKey: btnLabel,\n    btnStatus,\n    isActiveAccount,\n    disabled: false,\n    onSubmitClick: (_data: T) => onBtnClick(),\n    propsExtends: {},\n    tradeData: vaultJoinData.tradeData as unknown as T,\n    handlePanelEvent,\n    onRefreshData,\n    refreshRef,\n    walletMap: vaultJoinData.walletMap as WalletMap<any>,\n    vaultJoinData,\n    coinMap: isActiveAccount ? walletAllowMap : walletAllowCoin,\n    tokenProps: {\n      decimalsLimit:\n        erc20Map &&\n        erc20Map[vaultJoinData?.tradeData?.belong as string]?.vaultTokenAmounts?.qtyStepScale,\n      allowDecimals:\n        erc20Map &&\n        erc20Map[vaultJoinData?.tradeData?.belong as string]?.vaultTokenAmounts?.qtyStepScale\n          ? true\n          : false,\n    },\n    onToggleAddRedeem: (value: 'Add' | 'Redeem') => {\n      setIsAddOrRedeem(value)\n    },\n    isAddOrRedeem,\n    marginLevelChange: vaultAccountInfo?.marginLevel\n      ? nextMarginLevel\n        ? {\n            from: {\n              marginLevel: vaultAccountInfo.marginLevel,\n              type: marginLevelType(vaultAccountInfo.marginLevel),\n            },\n            to: {\n              marginLevel: nextMarginLevel,\n              type: marginLevelType(nextMarginLevel),\n            },\n          }\n        : {\n            from: {\n              marginLevel: vaultAccountInfo.marginLevel,\n              type: marginLevelType(vaultAccountInfo.marginLevel),\n            },\n            to: {\n              marginLevel: vaultAccountInfo.marginLevel,\n              type: marginLevelType(vaultAccountInfo.marginLevel),\n            },\n          }\n      : undefined,\n    holdingCollateral:\n      vaultAccountInfo && vaultAccountInfo?.collateralInfo && ercToken\n        ? numberFormat(\n            utils.formatUnits(\n              vaultAccountInfo?.collateralInfo.collateralTokenAmount,\n              ercToken.decimals,\n            ),\n            {\n              fixed: ercToken.precision,\n              removeTrailingZero: true,\n            },\n          )\n        : undefined,\n  }\n  const basicTrade = useBasicTrade(props as any)\n  const [panelIndex, setPanelIndex] = React.useState(basicTrade.index)\n  React.useEffect(() => {\n    setPanelIndex(basicTrade.index)\n  }, [basicTrade.index])\n  \n  const output= {\n    ...props,\n    basicTrade,\n    panelIndex,\n    handleConfirm: (index: number) => {\n      setPanelIndex(index)\n    },\n    modalOpen: isShow,\n    onCloseModal: () => {\n      setShowVaultJoin({ isShow: false })\n    }\n  } \n\n  return output\n\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/vault/useVaultLoan.ts",
    "content": "import { useOpenModals } from '@loopring-web/component-lib'\nimport { store } from '../../../stores'\nimport React from 'react'\nimport { VaultLoanType } from '@loopring-web/common-resources'\nimport { useVaultRepay } from './useVaultRepay'\nimport { useVaultBorrow } from './useVaultBorrow'\nimport { useL2CommonSocket } from '../../../services'\n\nexport const useVaultLoan = () => {\n  const {\n    modals: {\n      isShowVaultLoan: { type, isShow, info },\n    },\n  } = useOpenModals()\n\n  const [vaultLoanType, setVaultLoanType] = React.useState(type ?? VaultLoanType.Borrow)\n  const handleTabChange = (index: VaultLoanType) => {\n    setVaultLoanType(index)\n  }\n  React.useEffect(() => {\n    if (isShow) {\n      setVaultLoanType(() => {\n        return store.getState().modals?.isShowVaultLoan?.type ?? VaultLoanType.Borrow\n      })\n      // const withdrawValue =\n    }\n  }, [isShow])\n  useL2CommonSocket({})\n\n  return {\n    vaultRepayProps: useVaultRepay(info?.symbol),\n    vaultBorrowProps: useVaultBorrow(),\n    vaultLoanType,\n    handleTabChange,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/vault/useVaultRedeem.ts",
    "content": "import { AccountStep, useOpenModals, useSettings } from '@loopring-web/component-lib'\nimport {\n  CurrencyToTag,\n  CustomErrorWithCode,\n  EmptyValueTag,\n  getValuePrecisionThousand,\n  PriceTag,\n  SDK_ERROR_MAP_TO_UI,\n  SUBMIT_PANEL_AUTO_CLOSE,\n  SUBMIT_PANEL_CHECK,\n  TradeBtnStatus,\n  UIERROR_CODE,\n} from '@loopring-web/common-resources'\nimport React from 'react'\nimport {\n  l2CommonService,\n  LoopringAPI,\n  store,\n  useL2CommonSocket,\n  useSubmitBtn,\n  useSystem,\n  useVaultLayer2,\n} from '@loopring-web/core'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { useTranslation } from 'react-i18next'\n\nexport const useVaultRedeem = () => {\n  const { t } = useTranslation('common')\n  const { status: vaultAccountInfoStatus, vaultAccountInfo } = useVaultLayer2()\n  const [isLoading, setIsLoading] = React.useState(false)\n  const { setShowVaultExit, setShowAccount, setShowNoVaultAccount } = useOpenModals()\n  const { forexMap } = useSystem()\n  const { currency } = useSettings()\n  const [info, setInfo] = React.useState<\n    | {\n        profit: any\n        usdValue: any\n        usdDebt: any\n        usdEquity: any\n        forexMap: any\n        profitPercent: any\n      }\n    | undefined\n  >(undefined)\n\n  const vaultLayer2Callback = React.useCallback(() => {\n    const {\n      vaultLayer2: { vaultAccountInfo },\n    } = store.getState()\n    if (vaultAccountInfo?.accountStatus == sdk.VaultAccountStatus.IN_STAKING) {\n      setInfo(() => {\n        const profit =\n          (vaultAccountInfo as any)?.accountType === 0\n            ? vaultAccountInfo?.totalCollateralOfUsdt && vaultAccountInfo?.totalCollateralOfUsdt\n              ? sdk\n                  .toBig(vaultAccountInfo?.totalEquityOfUsdt ?? 0)\n                  .minus(vaultAccountInfo?.totalCollateralOfUsdt ?? 0)\n              : undefined\n            : vaultAccountInfo?.totalCollateralOfUsdt && vaultAccountInfo?.totalCollateralOfUsdt\n            ? sdk\n                .toBig(vaultAccountInfo?.totalBalanceOfUsdt ?? 0)\n                .minus(vaultAccountInfo?.totalDebtOfUsdt ?? 0)\n            : undefined\n        return {\n          profit: profit\n            ? PriceTag[CurrencyToTag[currency]] +\n              getValuePrecisionThousand(\n                sdk.toBig(profit).times(forexMap[currency] ?? 0),\n                2,\n                2,\n                2,\n                true,\n                { floor: true },\n              )\n            : EmptyValueTag,\n          profitPercent:\n            profit && Number(vaultAccountInfo?.totalCollateralOfUsdt ?? 0)\n              ? getValuePrecisionThousand(\n                  profit.div(vaultAccountInfo?.totalCollateralOfUsdt).times(100) ?? 0,\n                  2,\n                  2,\n                  undefined,\n                  false,\n                  {\n                    isFait: false,\n                    floor: true,\n                  },\n                ) + '%'\n              : EmptyValueTag,\n          usdValue: vaultAccountInfo?.totalBalanceOfUsdt\n            ? PriceTag[CurrencyToTag[currency]] +\n              getValuePrecisionThousand(\n                sdk.toBig(vaultAccountInfo?.totalBalanceOfUsdt ?? 0).times(forexMap[currency] ?? 0),\n                2,\n                2,\n                2,\n                true,\n                { floor: true },\n              )\n            : EmptyValueTag,\n          usdDebt: vaultAccountInfo?.totalDebtOfUsdt\n            ? PriceTag[CurrencyToTag[currency]] +\n              getValuePrecisionThousand(\n                sdk.toBig(vaultAccountInfo?.totalDebtOfUsdt ?? 0).times(forexMap[currency] ?? 0),\n                2,\n                2,\n                2,\n                true,\n                { floor: true },\n              )\n            : EmptyValueTag,\n          usdEquity: vaultAccountInfo?.totalEquityOfUsdt\n            ? PriceTag[CurrencyToTag[currency]] +\n              getValuePrecisionThousand(\n                sdk.toBig(vaultAccountInfo?.totalEquityOfUsdt ?? 0).times(forexMap[currency] ?? 0),\n                2,\n                2,\n                2,\n                true,\n                { floor: true },\n              )\n            : EmptyValueTag,\n          forexMap,\n        }\n      })\n    }\n  }, [currency])\n  React.useEffect(() => {\n    vaultLayer2Callback()\n  }, [currency])\n  useL2CommonSocket({ vaultLayer2Callback })\n\n  const availableTradeCheck = React.useCallback(() => {\n    if (\n      vaultAccountInfo?.accountStatus == sdk.VaultAccountStatus.IN_STAKING &&\n      vaultAccountInfo?.collateralInfo?.orderHash\n    ) {\n      return { tradeBtnStatus: TradeBtnStatus.AVAILABLE, label: 'labelVaultConfirm' }\n    } else {\n      return { tradeBtnStatus: TradeBtnStatus.DISABLED, label: 'labelVaultConfirm' }\n    }\n  }, [vaultAccountInfoStatus, vaultAccountInfo?.collateralInfo?.orderHash])\n  const processRequest = async (request: sdk.VaultExitRequest) => {\n    try {\n      const {\n        account: { apiKey, eddsaKey, accountId },\n      } = store.getState()\n      if (request && LoopringAPI.vaultAPI) {\n        let response = await LoopringAPI.vaultAPI.submitVaultExit({\n          // @ts-ignore\n          request: request,\n          privateKey: eddsaKey.sk,\n          apiKey,\n        }, '1')\n        if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n          throw response\n        }\n        // submit success\n        setShowVaultExit({ isShow: false })\n        await sdk.sleep(SUBMIT_PANEL_CHECK)\n        const response2 = await LoopringAPI.vaultAPI.getVaultGetOperationByHash(\n          {\n            accountId: accountId?.toString(),\n            hash: (response as any).hash,\n          },\n          apiKey,\n          '1'\n        )\n        let status = ''\n        if (\n          response2?.raw_data?.operation?.status == sdk.VaultOperationStatus.VAULT_STATUS_FAILED\n        ) {\n          throw sdk.VaultOperationStatus.VAULT_STATUS_FAILED\n        } else if (\n          [sdk.VaultOperationStatus.VAULT_STATUS_SUCCEED].includes(\n            response2?.raw_data?.operation?.status,\n          )\n        ) {\n          status = 'labelSuccessfully'\n        } else {\n          status = 'labelPending'\n        }\n        setShowAccount({\n          isShow: store.getState().modals.isShowAccount.isShow,\n          step:\n            status == 'labelSuccessfully'\n              ? AccountStep.VaultRedeem_Success\n              : AccountStep.VaultRedeem_In_Progress,\n          info: {\n            ...info,\n            status: t(status),\n          },\n        })\n        setIsLoading(false)\n        await sdk.sleep(SUBMIT_PANEL_AUTO_CLOSE)\n        l2CommonService.sendUserUpdate()\n        if (\n          store.getState().modals.isShowAccount.isShow &&\n          [AccountStep.VaultRedeem_Success, AccountStep.VaultRedeem_In_Progress].includes(\n            store.getState().modals.isShowAccount.step,\n          )\n        ) {\n          setShowAccount({ isShow: false })\n        }\n        var timer = setInterval(() => {\n          LoopringAPI.vaultAPI?.getVaultGetOperationByHash(\n            {\n              accountId: accountId?.toString(),\n              hash: (response as any).hash,\n            },\n            apiKey,\n            '1'\n          ).then(x => {\n            if (x.operation.status === sdk.VaultOperationStatus.VAULT_STATUS_SUCCEED) {\n              setShowNoVaultAccount({ isShow: false })\n              clearInterval(timer)\n            }\n          })\n        }, 2000)\n      } else {\n        throw new Error('api not ready')\n      }\n    } catch (e) {\n      const code =\n        (e as any)?.message === sdk.VaultOperationStatus.VAULT_STATUS_FAILED\n          ? UIERROR_CODE.ERROR_ORDER_FAILED\n          : (e as sdk.RESULT_INFO)?.code ?? UIERROR_CODE.UNKNOWN\n      const error = new CustomErrorWithCode({\n        code,\n        message: (e as sdk.RESULT_INFO)?.message,\n        ...SDK_ERROR_MAP_TO_UI[code],\n      })\n      setShowAccount({\n        isShow: true,\n        step: AccountStep.VaultRedeem_Failed,\n        info: {\n          ...info,\n          status: t('labelFailed'),\n        },\n        error,\n      })\n    }\n    setIsLoading(false)\n  }\n\n  const submitCallback = async () => {\n    try {\n      const { accountId } = store.getState().account\n      if (\n        vaultAccountInfo?.accountStatus == sdk.VaultAccountStatus.IN_STAKING &&\n        vaultAccountInfo?.collateralInfo?.orderHash\n      ) {\n        setIsLoading(true)\n        setShowAccount({\n          isShow: true,\n          step: AccountStep.VaultRedeem_In_Progress,\n        })\n        processRequest({\n          accountId,\n          joinHash: vaultAccountInfo?.collateralInfo?.orderHash,\n          timestamp: Date.now(),\n        })\n      } else {\n        throw 'accountStatus is not in staking'\n      }\n    } catch (e) {\n      if (e as any) {\n        setIsLoading(false)\n        setShowAccount({\n          isShow: true,\n          step: AccountStep.VaultRedeem_Failed,\n          info: {\n            ...info,\n            status: t('labelFailed'),\n          },\n          error: {\n            ...(e as any),\n          },\n        })\n      }\n    }\n  }\n\n  const {\n    btnStatus,\n    onBtnClick,\n    btnLabel,\n    // btnStyle: tradeLimitBtnStyle,\n  } = useSubmitBtn({\n    availableTradeCheck,\n    isLoading,\n    submitCallback,\n  })\n  return {\n    btnStatus,\n    onClose: () => {\n      setShowVaultExit({ isShow: false })\n    },\n    confirmLabel: btnLabel,\n    onSubmitClick: () => onBtnClick(),\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/vault/useVaultRepay.ts",
    "content": "import {\n  CustomErrorWithCode,\n  EmptyValueTag,\n  getValuePrecisionThousand,\n  IBData,\n  SDK_ERROR_MAP_TO_UI,\n  SUBMIT_PANEL_AUTO_CLOSE,\n  SUBMIT_PANEL_CHECK,\n  TradeBtnStatus,\n  UIERROR_CODE,\n  VaultRepayData,\n} from '@loopring-web/common-resources'\nimport { AccountStep, SwitchData, useOpenModals } from '@loopring-web/component-lib'\nimport {\n  NETWORKEXTEND,\n  store,\n  useAccount,\n  useSystem,\n  useTokenMap,\n  useTradeVault,\n  useVaultLayer2,\n  useVaultMap,\n} from '../../../stores'\nimport { useTranslation } from 'react-i18next'\nimport React from 'react'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { makeVaultRepay } from '../../help'\nimport { LoopringAPI } from '../../../api_wrapper'\nimport { useSubmitBtn } from '../../common'\nimport BigNumber from 'bignumber.js'\nimport { getTimestampDaysLater } from '../../../utils'\nimport { DAYS } from '../../../defs'\nimport { ConnectProviders, connectProvides } from '@loopring-web/web3-provider'\nimport { mapValues } from 'lodash'\nimport Decimal from 'decimal.js'\nimport { calcMarinLevel, marginLevelType } from './utils'\nexport const useVaultRepay = <\n  T extends IBData<I> & {\n    borrowed: string\n    max: string\n  },\n  V extends VaultRepayData<T>,\n  I,\n>(initialSymbol: string | undefined) => {\n  const {\n    modals: { isShowVaultLoan },\n    setShowAccount,\n    setShowVaultLoan,\n  } = useOpenModals()\n  const { vaultAccountInfo, status: vaultAccountInfoStatus, updateVaultLayer2 } = useVaultLayer2()\n  const { account } = useAccount()\n  const { idIndex: erc20IdIndex } = useTokenMap()\n  const { tokenMap: vaultTokenMap, idIndex: vaultIdIndex, coinMap: vaultCoinMap, tokenPrices } = useVaultMap()\n  const { t } = useTranslation()\n  const { vaultRepayData, updateVaultRepay, resetVaultRepay } = useTradeVault()\n  const { exchangeInfo, chainId } = useSystem()\n  const [isLoading, setIsLoading] = React.useState(false)\n  const [walletMap, setWalletMap] = React.useState(() => {\n    return makeVaultRepay({ needFilterZero: true }).vaultAvaiable2Map\n  })\n  const [tradeData, setTradeData] = React.useState<T | undefined>(undefined)\n\n  const calcSupportData = (tradeData: T) => {\n    let supportData = {}\n    if (tradeData?.belong) {\n      const vaultToken = vaultTokenMap[tradeData.belong as any]\n      if(!vaultToken) {\n        return {}\n      }\n      const borrowed = tradeData.borrowed\n      let minRepayVol = BigNumber.max(\n        // orderAmounts.dust,\n        //@ts-ignore\n        vaultToken?.vaultTokenAmounts?.minLoanAmount,\n      )\n      let minRepayAmt = minRepayVol.div('1e' + vaultToken.decimals)\n      const tradeValue = tradeData.tradeValue\n\n      if (sdk.toBig(tradeData.borrowed).minus(tradeData.tradeValue).lt(minRepayAmt)) {\n        minRepayVol = sdk\n          .toBig(tradeData.borrowed)\n          .times('1e' + vaultToken.decimals)\n          .toString()\n        minRepayAmt = sdk.toBig(tradeData.borrowed).toString()\n      }\n\n      supportData = {\n        maxRepayAmount: borrowed,\n        maxRepayStr: getValuePrecisionThousand(\n          borrowed,\n          // sdk.toBig(vaultToken.btradeAmount).div('1e' + vaultToken.decimals),\n          vaultToken?.vaultTokenAmounts?.qtyStepScale,\n          vaultToken?.vaultTokenAmounts?.qtyStepScale,\n          undefined,\n        ),\n        minRepayAmount: minRepayAmt,\n        minRepayStr: getValuePrecisionThousand(\n          minRepayAmt,\n          vaultToken?.vaultTokenAmounts?.qtyStepScale,\n          vaultToken?.vaultTokenAmounts?.qtyStepScale,\n          undefined,\n        ),\n        maxRepayVol: sdk\n          .toBig(borrowed)\n          .times('1e' + vaultToken.decimals)\n          .toString(),\n        minRepayVol: minRepayVol.toString(),\n        repayVol: sdk\n          .toBig(tradeValue ?? 0)\n          .times('1e' + vaultToken.decimals)\n          .toString(),\n        repayAmtStr: getValuePrecisionThousand(\n          tradeValue ?? 0,\n          vaultToken?.vaultTokenAmounts?.qtyStepScale,\n          vaultToken?.vaultTokenAmounts?.qtyStepScale,\n          undefined,\n        ),\n        repayAmt: tradeValue ?? 0,\n        coinInfoMap: vaultCoinMap,\n      }\n    }\n    return {\n      ...supportData,\n    }\n  }\n  // useVaultSocket()\n  const initData = () => {\n    let vaultRepayData: any = {}\n    let initSymbol = vaultIdIndex[vaultAccountInfo?.collateralInfo?.collateralTokenId ?? ''] ?? ''\n    const walletMap = makeVaultRepay({ needFilterZero: true }).vaultAvaiable2Map ?? {}\n    setWalletMap(walletMap)\n\n    let walletInfo: any = walletMap[initSymbol.toString()]\n    walletInfo = {\n      ...walletInfo,\n      belong: initSymbol.toString(),\n      balance: walletInfo?.count ?? 0,\n      tradeValue: undefined,\n      max: BigNumber.min(walletInfo?.borrowed, walletInfo?.count) ?? 0,\n    }\n    vaultRepayData = {\n      ...vaultRepayData,\n      walletMap,\n      coinMap: vaultCoinMap,\n    }\n\n    setTradeData({\n      ...walletInfo,\n    })\n\n    updateVaultRepay({\n      ...walletInfo,\n      ...vaultRepayData,\n      ...calcSupportData(walletInfo),\n    })\n  }\n  React.useEffect(() => {\n    if (isShowVaultLoan.isShow) {\n      initData()\n    } else {\n      resetVaultRepay()\n    }\n  }, [isShowVaultLoan.isShow])\n  const availableTradeCheck = React.useCallback(() => {\n    const vaultRepayData = store.getState()._router_tradeVault.vaultRepayData\n    if (\n      !vaultRepayData?.tradeValue ||\n      !vaultRepayData?.belong ||\n      sdk.toBig(vaultRepayData?.tradeValue ?? 0).lte(0)\n    ) {\n      return { tradeBtnStatus: TradeBtnStatus.DISABLED, label: '' }\n    } else if (sdk.toBig(vaultRepayData?.tradeValue ?? 0).lt(vaultRepayData.minRepayAmount)) {\n      return {\n        tradeBtnStatus: TradeBtnStatus.DISABLED,\n        label: `labelVaultRepayMini|${vaultRepayData.minRepayStr} ${vaultRepayData.belong.slice(2)}`,\n      }\n    } else if (sdk.toBig(vaultRepayData.tradeValue ?? 0).gt(vaultRepayData.balance ?? 0)) {\n      return {\n        tradeBtnStatus: TradeBtnStatus.DISABLED,\n        label: `labelVaultRepayNotEnough|${vaultRepayData.belong}`,\n      }\n    } else if (sdk.toBig(vaultRepayData.tradeValue ?? 0).gt(vaultRepayData.maxRepayAmount ?? 0)) {\n      return {\n        tradeBtnStatus: TradeBtnStatus.DISABLED,\n        label: `labelVaultRepayMax|${vaultRepayData.maxRepayStr} ${vaultRepayData.belong.slice(2)}`,\n      }\n    } else {\n      return { tradeBtnStatus: TradeBtnStatus.AVAILABLE, label: '' }\n    }\n  }, [\n    vaultAccountInfoStatus,\n    vaultTokenMap,\n    vaultRepayData,\n    vaultRepayData.belong,\n    vaultRepayData.tradeValue,\n    vaultRepayData.balance,\n    vaultRepayData.maxRepayAmount,\n    vaultRepayData.minRepayAmount,\n  ])\n  const handlePanelEvent = React.useCallback(\n    async (data: SwitchData<T>) => {\n      let vaultRepayData = store.getState()._router_tradeVault.vaultRepayData\n      return new Promise<void>((res: any) => {\n        if (data.to === 'button') {\n          const walletMap = makeVaultRepay({ needFilterZero: true }).vaultAvaiable2Map ?? {}\n          setWalletMap(walletMap)\n          if (walletMap && data?.tradeData?.belong) {\n            const vaultToken = vaultTokenMap[data.tradeData.belong]\n            let walletInfo: any = walletMap[data?.tradeData?.belong as string]\n            walletInfo = {\n              ...walletInfo,\n              balance: walletInfo ? walletInfo.count : 0,\n              tradeValue: data.tradeData?.tradeValue,\n              max: BigNumber.min(\n                walletInfo.borrowed, \n                sdk.toFixed(sdk.toBig(walletInfo.count), vaultToken.vaultTokenAmounts.qtyStepScale, false)\n              )\n            }\n            setTradeData(walletInfo)\n            vaultRepayData = {\n              ...vaultRepayData,\n              ...walletInfo,\n              ...calcSupportData(walletInfo),\n              walletMap,\n              tradeData: walletInfo,\n            }\n            updateVaultRepay({\n              ...vaultRepayData,\n            })\n          } else {\n            updateVaultRepay({\n              belong: undefined,\n              tradeValue: undefined,\n              balance: undefined,\n            })\n          }\n        }\n        res()\n      })\n    },\n    [tradeData, account.readyState],\n  )\n\n  const processRequest = async (request?: sdk.VaultRepayRequestV3WithPatch['request']) => {\n    const account = store.getState().account\n    const vaultRepayData = store.getState()._router_tradeVault.vaultRepayData\n    const vaultToken = vaultTokenMap[vaultRepayData.belong]\n    const erc20Symbol = vaultRepayData.belong.slice(2)\n\n    try {\n      if ((request || vaultRepayData.request) && LoopringAPI.vaultAPI) {\n        let response = await LoopringAPI.vaultAPI?.submitVaultRepay(\n          {\n            // @ts-ignore\n            request: request ?? vaultRepayData.request,\n            web3: connectProvides.usedWeb3 as any,\n            chainId: chainId === NETWORKEXTEND.NONETWORK ? sdk.ChainId.MAINNET : chainId,\n            walletType: (ConnectProviders[account.connectName] ??\n              account.connectName) as unknown as sdk.ConnectorNames,\n            eddsaKey: account.eddsaKey.sk,\n            apiKey: account.apiKey,\n          },\n          {\n            accountId: account.accountId,\n            counterFactualInfo: account.eddsaKey.counterFactualInfo,\n          },\n          '1'\n        )\n\n        if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n          throw response\n        } else {\n          setShowVaultLoan({ isShow: false })\n          setIsLoading(false)\n          updateVaultLayer2({})\n          await sdk.sleep(SUBMIT_PANEL_CHECK)\n          const response2 = await LoopringAPI.vaultAPI.getVaultGetOperationByHash(\n            {\n              accountId: account?.accountId?.toString(),\n              hash: (response as any).hash,\n            },\n            account.apiKey,\n            '1'\n          )\n          let status = ''\n          if (\n            response2?.raw_data?.operation?.status == sdk.VaultOperationStatus.VAULT_STATUS_FAILED\n          ) {\n            throw sdk.VaultOperationStatus.VAULT_STATUS_FAILED\n          } else if (\n            [sdk.VaultOperationStatus.VAULT_STATUS_SUCCEED].includes(\n              response2?.raw_data?.operation?.status,\n            )\n          ) {\n            status = 'labelSuccessfully'\n          } else {\n            status = 'labelPending'\n          }\n          setShowAccount({\n            isShow: store.getState().modals.isShowAccount.isShow,\n            step:\n              status == 'labelSuccessfully'\n                ? AccountStep.VaultRepay_Success\n                : AccountStep.VaultRepay_In_Progress,\n            info: {\n              status: t(status),\n              amount: sdk.VaultOperationStatus.VAULT_STATUS_SUCCEED\n                ? vaultRepayData.repayAmtStr\n                : 0,\n              sum: vaultRepayData.repayAmtStr,\n              symbol: erc20Symbol,\n              vSymbol: vaultToken.symbol,\n              time: response2?.raw_data?.order?.createdAt,\n            },\n          })\n          await sdk.sleep(SUBMIT_PANEL_AUTO_CLOSE)\n          updateVaultLayer2({})\n          if (\n            store.getState().modals.isShowAccount.isShow &&\n            [AccountStep.VaultRepay_Success, AccountStep.VaultRepay_In_Progress].includes(\n              store.getState().modals.isShowAccount.step,\n            )\n          ) {\n            setShowAccount({ isShow: false })\n          }\n        }\n      } else {\n        throw new Error('api not ready')\n      }\n      setIsLoading(false)\n    } catch (e) {\n      const code =\n        (e as any)?.message === sdk.VaultOperationStatus.VAULT_STATUS_FAILED\n          ? UIERROR_CODE.ERROR_ORDER_FAILED\n          : (e as sdk.RESULT_INFO)?.code ?? UIERROR_CODE.UNKNOWN\n      const error = new CustomErrorWithCode({\n        code,\n        message: (e as sdk.RESULT_INFO)?.message,\n        ...SDK_ERROR_MAP_TO_UI[code],\n      })\n      setIsLoading(false)\n      setShowAccount({\n        isShow: true,\n        step: AccountStep.VaultRepay_Failed,\n        info: {\n          status: t('labelFailed'),\n          amount: EmptyValueTag,\n          sum: vaultRepayData.repayAmtStr,\n          symbol: erc20Symbol,\n          vSymbol: vaultToken.symbol,\n          time: Date.now(),\n          error,\n        },\n      })\n    }\n  }\n\n  const submitCallback = async () => {\n    const vaultRepayData = store.getState()._router_tradeVault.vaultRepayData\n    const erc20Symbol = vaultRepayData.belong.slice(2)\n    try {\n      if (\n        vaultRepayData &&\n        exchangeInfo &&\n        vaultRepayData.belong &&\n        LoopringAPI.vaultAPI &&\n        LoopringAPI.userAPI &&\n        vaultAccountInfo &&\n        sdk.toBig(vaultRepayData?.repayVol).gte(vaultRepayData.minRepayVol ?? 0) &&\n        sdk.toBig(vaultRepayData?.maxRepayAmount).lte(vaultRepayData.maxRepayVol ?? 0)\n      ) {\n        setIsLoading(true)\n        setShowAccount({\n          isShow: true,\n          step: AccountStep.VaultRepay_In_Progress,\n          info: {\n            status: t('labelPending'),\n            amount: EmptyValueTag,\n            sum: vaultRepayData.repayAmtStr,\n            symbol: erc20Symbol,\n            vSymbol: vaultRepayData.belong,\n            time: Date.now(),\n          },\n        })\n        const tokenInfo = vaultTokenMap[vaultRepayData.belong]\n        const [{ broker }, { offchainId }] = await Promise.all([\n          LoopringAPI.userAPI?.getAvailableBroker({\n            type: 4,\n          }),\n          LoopringAPI.userAPI?.getNextStorageId(\n            {\n              accountId: account.accountId,\n              sellTokenId: tokenInfo.vaultTokenId,\n            },\n            account.apiKey,\n          ),\n        ])\n        const vaultRepayRequest = {\n          exchange: exchangeInfo.exchangeAddress,\n          payerAddr: account.accAddress,\n          payerId: account.accountId,\n          payeeId: 0,\n          payeeAddr: broker,\n          storageId: offchainId,\n          token: {\n            tokenId: tokenInfo.vaultTokenId,\n            volume: vaultRepayData?.repayVol,\n          },\n          maxFee: {\n            tokenId: tokenInfo.vaultTokenId,\n            volume: '0', // TEST: fee.toString(),\n          },\n          validUntil: getTimestampDaysLater(DAYS),\n          memo: '',\n        }\n\n        updateVaultRepay({\n          ...vaultRepayData,\n          request: vaultRepayRequest,\n        })\n        processRequest(vaultRepayRequest)\n      }\n    } catch (e) {\n      setIsLoading(false)\n      setShowAccount({\n        isShow: true,\n        step: AccountStep.VaultRepay_Failed,\n        error: {\n          ...(e as any),\n        },\n      })\n    }\n  }\n\n  const { btnStatus, onBtnClick, btnLabel } = useSubmitBtn({\n    availableTradeCheck,\n    isLoading,\n    submitCallback,\n  })\n\n  const moreToBorrowInUSD =\n    vaultRepayData.tradeData && tokenPrices[vaultRepayData.tradeData.belong as string]\n      ? new Decimal(vaultRepayData.tradeData.tradeValue?.toString() ?? '0')\n          .mul(tokenPrices[vaultRepayData.tradeData.belong as string])\n          .mul('-1')\n          .toString()\n      : undefined\n  \n\n  const nextMarginLevel =\n    vaultAccountInfo?.marginLevel && moreToBorrowInUSD\n      ? calcMarinLevel(\n          vaultAccountInfo.totalCollateralOfUsdt,\n          vaultAccountInfo.totalDebtOfUsdt,\n          vaultAccountInfo.totalBalanceOfUsdt,\n          moreToBorrowInUSD,\n          '0',\n        )\n      : vaultAccountInfo?.marginLevel\n      \n  return {\n    handlePanelEvent,\n    vaultRepayBtnStatus: btnStatus,\n    vaultRepayBtnI18nKey: btnLabel,\n    onVaultRepayClick: onBtnClick,\n    walletMap: mapValues(walletMap, (value, key) => {\n      return {\n        ...value,\n        erc20Symbol: key.slice(2),\n        belongAlice: key.slice(2),\n      }\n    }) as unknown as any,\n    coinMap: mapValues(vaultCoinMap, (value) => {\n      return {\n        ...value,\n        erc20Symbol: value?.simpleName.slice(2),\n        belongAlice: value?.simpleName.slice(2),\n      }\n    }),\n    tradeData: {\n      ...vaultRepayData.tradeData,\n      erc20Symbol: vaultRepayData.tradeData?.belong.slice(2),\n      belongAlice: vaultRepayData.tradeData?.belong.slice(2),\n    },\n    vaultRepayData: {\n      ...vaultRepayData,\n      erc20Symbol: vaultRepayData.tradeData?.belong.slice(2),\n      belongAlice: vaultRepayData.tradeData?.belong.slice(2),\n      tradeData: {\n        ...vaultRepayData?.tradeData,\n        erc20Symbol: vaultRepayData.tradeData?.belong.slice(2),\n        belongAlice: vaultRepayData.tradeData?.belong.slice(2),\n      },\n    } as unknown as V,\n    tokenInfo: vaultTokenMap[vaultRepayData?.belong],\n    tokenProps: {\n      decimalsLimit: vaultTokenMap[vaultRepayData?.belong]?.vaultTokenAmounts?.qtyStepScale,\n      allowDecimals: vaultTokenMap[vaultRepayData?.tradeData?.belong]?.vaultTokenAmounts\n        ?.qtyStepScale\n        ? true\n        : false,\n    },\n    marginLevelChange: vaultAccountInfo?.marginLevel\n      ? nextMarginLevel && vaultRepayData.tradeValue\n        ? {\n            from: {\n              marginLevel: vaultAccountInfo.marginLevel,\n              type: marginLevelType(vaultAccountInfo.marginLevel),\n            },\n            to: {\n              marginLevel: nextMarginLevel,\n              type: marginLevelType(nextMarginLevel),\n            },\n          }\n        : {\n            from: {\n              marginLevel: vaultAccountInfo.marginLevel,\n              type: marginLevelType(vaultAccountInfo.marginLevel),\n            },\n            to: {\n              marginLevel: vaultAccountInfo.marginLevel,\n              type: marginLevelType(vaultAccountInfo.marginLevel),\n            },\n          }\n      : undefined,\n    initialSymbol\n  }\n}\n"
  },
  {
    "path": "packages/core/src/hooks/useractions/vault/utils.ts",
    "content": "import Decimal from 'decimal.js'\n\nexport const calcMarinLevel = (\n  originMarginInUSD: string,\n  originDebtInUSD: string,\n  totalBalanceInUSD: string,\n  moreToBorrowInUSD: string,\n  moreToCollateralizeInUSD: string,\n) => {\n  const originMarginDecimal = new Decimal(originMarginInUSD)\n  const totalBalanceInUSDDecimal = new Decimal(totalBalanceInUSD)\n  const moreToBorrowDecimal = new Decimal(moreToBorrowInUSD ?? '0')\n  const moreToCollateralizeDecimal = new Decimal(moreToCollateralizeInUSD ?? '0')\n  const originDebtDecimal = new Decimal(originDebtInUSD ?? '0')\n  if (originDebtDecimal.add(moreToBorrowDecimal).eq('0')) {\n    return '999'\n  } else {\n    const calculated = originMarginDecimal\n    .add(moreToCollateralizeDecimal)\n    .add(totalBalanceInUSDDecimal)\n    .add(moreToBorrowDecimal)\n    .div(originDebtDecimal.add(moreToBorrowDecimal))\n    if (calculated.gte('999')) {\n      return '999'\n    } else if (calculated.lt('0')) {\n      return undefined\n    } else {\n      return calculated.toString()\n    }\n  } \n}\n\nexport const marginLevelType: (marginLevel: string) => 'danger' | 'safe' | 'warning' = (\n  marginLevel: string,\n) => {\n  const marginLevelDecimal = new Decimal(marginLevel)\n  if (marginLevelDecimal.gte('1.5')) {\n    return 'safe'\n  } else if (marginLevelDecimal.gte('1.15')) {\n    return 'warning'\n  } else {\n    return 'danger'\n  }\n}\n"
  },
  {
    "path": "packages/core/src/index.ts",
    "content": "export * from './component'\nexport * from './stores/index'\nexport * from './stores/rootSaga'\nexport * from './hookConnect'\nexport * from './TimeoutCheckProvider'\nexport * from './storage'\nexport * from './services'\nexport * from './defs'\nexport * from './api_wrapper'\nexport * from './utils'\nexport * from './hooks'\nexport * from './modal'\nexport { erc20ABI, taikoDepositABI } from './abi'\n"
  },
  {
    "path": "packages/core/src/modal/AccountL1Modal/hook.tsx",
    "content": "/* eslint-disable react/jsx-pascal-case */\nimport {\n  AccountStep,\n  Button,\n  Deposit_Approve_Denied,\n  Deposit_Approve_WaitForAuth,\n  Deposit_Denied,\n  Deposit_Failed,\n  Deposit_Sign_WaitForRefer,\n  Deposit_Submit,\n  Deposit_WaitForAuth,\n  DepositProps,\n  HadAccount,\n  NoAccount,\n  QRAddressPanel,\n  useOpenModals,\n  useSettings,\n} from '@loopring-web/component-lib'\nimport { ConnectProviders, walletServices } from '@loopring-web/web3-provider'\n\nimport React, { useState } from 'react'\nimport {\n  Account,\n  AccountStatus,\n  AssetsRawDataItem,\n  copyToClipBoard,\n  L1L2_NAME_DEFINED,\n  MapChainId,\n} from '@loopring-web/common-resources'\nimport {\n  depositServices,\n  goActiveAccount,\n  LAST_STEP,\n  lockAccount,\n  onchainHashInfo,\n  unlockAccount,\n  useAccount,\n  useNotify,\n  useRampTransPost,\n  useSystem,\n  useToast,\n} from '@loopring-web/core'\n\nexport function useAccountModalForL1UI({\n  t,\n  assetsRawData,\n  depositProps,\n  ...rest\n}: {\n  t: any\n  etherscanBaseUrl: string\n  depositProps: DepositProps<any, any>\n  account: Account\n  assetsRawData: AssetsRawDataItem[]\n  // onClose?: any;\n}) {\n  const { chainInfos, updateDepositHash } = onchainHashInfo.useOnChainInfo()\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const { processRequestRampTransfer } = useRampTransPost()\n  const { campaignTagConfig } = useNotify().notifyMap ?? {}\n  const {\n    modals: { isShowAccount },\n    setShowConnect,\n    setShowAccount,\n    setShowDeposit,\n  } = useOpenModals()\n  rest = { ...rest, ...isShowAccount.info }\n\n  const { allowTrade } = useSystem()\n\n  const { account, addressShort, shouldShow, setShouldShow } = useAccount()\n\n  const { toastOpen, setToastOpen, closeToast } = useToast()\n  // const { nftDepositProps } = useNFTDeposit();\n\n  const [openQRCode, setOpenQRCode] = useState(false)\n\n  const [copyToastOpen, setCopyToastOpen] = useState(false)\n\n  const onSwitch = React.useCallback(() => {\n    setShowAccount({ isShow: false })\n    setShouldShow(true)\n    setShowConnect({ isShow: shouldShow ?? false })\n  }, [setShowAccount, setShouldShow, setShowConnect, shouldShow])\n\n  const onCopy = React.useCallback(async () => {\n    copyToClipBoard(account.accAddress)\n    setCopyToastOpen(true)\n  }, [account, setCopyToastOpen])\n\n  const onViewQRCode = React.useCallback(() => {\n    setOpenQRCode(true)\n  }, [setOpenQRCode])\n\n  const onDisconnect = React.useCallback(async () => {\n    walletServices.sendDisconnect('', 'customer click disconnect')\n    setShowAccount({ isShow: false })\n  }, [setShowAccount])\n\n  const onQRClick = React.useCallback(() => {\n    setShowAccount({ isShow: true, step: AccountStep.QRCode })\n  }, [setShowAccount])\n\n  const unlockBtn = React.useMemo(() => {\n    return (\n      <Button\n        variant={'contained'}\n        fullWidth\n        size={'medium'}\n        onClick={() => {\n          setShouldShow(true)\n          unlockAccount()\n        }}\n      >\n        {t('labelUnLockLayer2')}\n      </Button>\n    )\n  }, [t, setShouldShow])\n\n  const lockBtn = React.useMemo(() => {\n    return (\n      <Button\n        variant={'contained'}\n        fullWidth\n        size={'medium'}\n        onClick={() => {\n          lockAccount()\n        }}\n      >\n        {t('labelLockLayer2')}\n      </Button>\n    )\n  }, [t])\n\n  const onQRBack = React.useCallback(() => {\n    if (Number.isInteger(isShowAccount.info?.backTo)) {\n      setShowAccount({ isShow: true, step: isShowAccount.info?.backTo })\n    } else {\n      switch (account.readyState) {\n        case AccountStatus.NO_ACCOUNT:\n        case AccountStatus.DEPOSITING:\n          setShowAccount({ isShow: true, step: AccountStep.NoAccount })\n          break\n        case AccountStatus.LOCKED:\n        case AccountStatus.ACTIVATED:\n          break\n        default:\n          setShowAccount({ isShow: false })\n      }\n    }\n  }, [account.readyState, isShowAccount, setShowAccount])\n\n  const closeBtnInfo = React.useCallback(\n    (props?: { closeExtend?: (e?: any) => void }) => {\n      return {\n        btnTxt: 'labelClose',\n        callback: (e: any) => {\n          setShouldShow(false)\n          setShowAccount({ isShow: false })\n          if (props?.closeExtend) {\n            props?.closeExtend(e)\n          }\n          // if (onClose) {\n          //   onClose(e);\n          // }\n        },\n      }\n    },\n    [setShouldShow, setShowAccount],\n  )\n\n  const accountList = React.useMemo(() => {\n    // const isShowAccount?.info.\n    return Object.values({\n      [AccountStep.NoAccount]: {\n        view: (\n          <NoAccount\n            {...{\n              goActiveAccount,\n              chainInfos,\n              // isSupport,\n              noButton: true,\n              onClose: (_e: any) => {\n                setShouldShow(false)\n                setShowAccount({ isShow: false })\n              },\n              clearDepositHash: () => undefined,\n              updateDepositHash,\n              ...account,\n              etherscanUrl: rest.etherscanBaseUrl,\n              onSwitch,\n              onCopy,\n              onViewQRCode,\n              onDisconnect,\n              addressShort,\n            }}\n          />\n        ),\n        onQRClick,\n        height: 'auto',\n      },\n      [AccountStep.QRCode]: {\n        view: (\n          <QRAddressPanel\n            {...{\n              ...rest,\n              account,\n              btnInfo: {\n                ...closeBtnInfo(),\n                btnTxt: isShowAccount?.info?.btnTxt ?? t('labelIKnow2'),\n              } as any,\n              ...account,\n              isNewAccount: depositProps.isNewAccount,\n              isForL2Send: isShowAccount.info?.backTo === AccountStep.AddAssetGateway,\n              etherscanUrl: rest.etherscanBaseUrl,\n              t,\n            }}\n          />\n        ),\n        onBack: onQRBack,\n        noClose: true,\n        height: 'auto',\n      },\n      [AccountStep.HadAccount]: {\n        view: (\n          <HadAccount\n            {...{\n              ...account,\n              clearDepositHash: () => undefined,\n              chainInfos,\n              noButton: true,\n              onSwitch,\n              onCopy,\n              onClose: (_e: any) => {\n                setShouldShow(false)\n                setShowAccount({ isShow: false })\n              },\n              etherscanUrl: rest.etherscanBaseUrl,\n              onViewQRCode,\n              onDisconnect,\n              addressShort,\n              etherscanLink: rest.etherscanBaseUrl + 'address/' + account.accAddress,\n              mainBtn: account.readyState === AccountStatus.ACTIVATED ? lockBtn : unlockBtn,\n            }}\n          />\n        ),\n        onQRClick,\n        height: 'auto',\n      },\n      [AccountStep.Deposit_Sign_WaitForRefer]: {\n        view: (\n          <Deposit_Sign_WaitForRefer\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.Deposit_Approve_WaitForAuth]: {\n        view: (\n          <Deposit_Approve_WaitForAuth\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.Deposit_Approve_Denied]: {\n        view: (\n          <Deposit_Approve_Denied\n            btnInfo={{\n              btnTxt: 'labelRetry',\n              callback: () => {\n                depositServices.depositERC20()\n              },\n            }}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n        onBack: () => {\n          setShowAccount({ isShow: false })\n        },\n      },\n      [AccountStep.Deposit_WaitForAuth]: {\n        view: (\n          <Deposit_WaitForAuth\n            symbol={depositProps.tradeData.belong}\n            value={depositProps.tradeData.tradeValue}\n            chainInfos={chainInfos}\n            updateDepositHash={updateDepositHash}\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n        onBack: () => {\n          setShowAccount({ isShow: false })\n        },\n      },\n      [AccountStep.Deposit_Denied]: {\n        view: (\n          <Deposit_Denied\n            btnInfo={{\n              btnTxt: 'labelRetry',\n              callback: () => {\n                depositServices.depositERC20()\n              },\n            }}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n        onBack: () => {\n          setShowAccount({ isShow: false })\n        },\n      },\n      [AccountStep.Deposit_Failed]: {\n        view: (\n          <Deposit_Failed\n            btnInfo={closeBtnInfo({\n              closeExtend: () => {\n                setShowAccount({\n                  ...isShowAccount,\n                  isShow: false,\n                  info: {\n                    ...isShowAccount.info,\n                    lastFailed: LAST_STEP.deposit,\n                  },\n                })\n              },\n            })}\n            {...{\n              ...rest,\n              account,\n              error: isShowAccount.error,\n              t,\n            }}\n          />\n        ),\n        onBack: !depositProps.isAllowInputToAddress\n          ? () => {\n              setShowAccount({ isShow: false })\n              setShowDeposit({ isShow: true })\n            }\n          : undefined,\n      },\n      [AccountStep.Deposit_Submit]: {\n        view: (\n          <Deposit_Submit\n            btnInfo={{\n              btnTxt: 'labelDoAgain',\n              param: {\n                method: t('labelDepositL1', {\n                  loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                  l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                  l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                  ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                }),\n              },\n              callback: () => {\n                setShowAccount({ isShow: false })\n                setShowDeposit({\n                  isShow: true,\n                  symbol: (rest as any)?.symbol ?? isShowAccount?.info?.symbol ?? 'LRC',\n                })\n              },\n            }}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n    })\n  }, [\n    network,\n    account,\n    isShowAccount.info,\n    isShowAccount.error,\n    allowTrade,\n    depositProps.isNewAccount,\n    depositProps.isAllowInputToAddress,\n    depositProps.tradeData.belong,\n    depositProps.tradeData.tradeValue,\n    campaignTagConfig,\n    chainInfos,\n    updateDepositHash,\n    rest,\n    onSwitch,\n    onCopy,\n    onViewQRCode,\n    onDisconnect,\n    addressShort,\n    onQRClick,\n    lockBtn,\n    unlockBtn,\n    t,\n    onQRBack,\n    closeBtnInfo,\n    setShowAccount,\n    setShowDeposit,\n\n    processRequestRampTransfer,\n  ])\n\n  const currentModal = accountList[isShowAccount.step]\n\n  return {\n    depositProps,\n    copyToastOpen,\n    setCopyToastOpen,\n    setToastOpen,\n    openQRCode,\n    setOpenQRCode,\n    isShowAccount,\n    account,\n    closeBtnInfo,\n    accountList,\n    currentModal,\n    toastOpen,\n    closeToast,\n    // checkActiveStatusProps,\n    // dualToastOpen,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/modal/AccountL1Modal/index.tsx",
    "content": "import { WithTranslation, withTranslation } from 'react-i18next'\nimport {\n  DepositProps,\n  ModalAccount,\n  ModalQRCode,\n  Toast,\n  ToastType,\n  useOpenModals,\n} from '@loopring-web/component-lib'\nimport { useAccountModalForL1UI } from './hook'\nimport { Account, AssetsRawDataItem, TOAST_TIME } from '@loopring-web/common-resources'\n\nexport const ModalAccountL1Info = withTranslation('common')(\n  ({\n    // onClose,\n    etherscanBaseUrl,\n    open,\n    assetsRawData,\n    depositProps,\n    t,\n    ...rest\n  }: {\n    open: boolean\n    account: Account\n    depositProps: DepositProps<any, any>\n    // onClose?: (e: MouseEvent) => void;\n    etherscanBaseUrl: string\n    assetsRawData: AssetsRawDataItem[]\n  } & WithTranslation) => {\n    // const { isMobile } = useSettings();\n    const {\n      modals: {\n        // isShowNFTDetail,\n        isShowAccount,\n      },\n      // setShowNFTDetail,\n      setShowAccount,\n      // setShowDeposit,\n      // setShowTransfer,\n      // setShowWithdraw,\n    } = useOpenModals()\n    const {\n      setCopyToastOpen,\n      setOpenQRCode,\n      account,\n      copyToastOpen,\n      openQRCode,\n      accountList,\n      currentModal,\n      toastOpen,\n      closeToast,\n    } = useAccountModalForL1UI({\n      t,\n      assetsRawData,\n      depositProps,\n      etherscanBaseUrl,\n      ...rest,\n    })\n    // myLog(\n    //   \"resetProps.chargeFeeTokenList\",\n    //   activeAccountProps.chargeFeeTokenList\n    // );\n    return (\n      <>\n        <Toast\n          alertText={toastOpen?.content ?? ''}\n          open={toastOpen?.open ?? false}\n          autoHideDuration={TOAST_TIME}\n          onClose={closeToast}\n        />\n        <Toast\n          alertText={toastOpen?.content ?? ''}\n          severity={toastOpen?.type ?? ToastType.success}\n          open={toastOpen?.open ?? false}\n          autoHideDuration={TOAST_TIME}\n          onClose={closeToast}\n        />\n        <Toast\n          alertText={t('labelCopyAddClip')}\n          open={copyToastOpen}\n          autoHideDuration={TOAST_TIME}\n          onClose={() => {\n            setCopyToastOpen(false)\n          }}\n          severity={ToastType.success}\n        />\n        <ModalQRCode\n          open={openQRCode}\n          onClose={() => setOpenQRCode(false)}\n          title={'ETH Address'}\n          description={account?.accAddress}\n          url={account?.accAddress}\n        />\n        <ModalAccount\n          open={isShowAccount.isShow}\n          onClose={() => {\n            setShowAccount({ isShow: false })\n            // currentModal?.onClose && currentModal?.onClose();\n          }}\n          panelList={accountList}\n          onBack={currentModal?.onBack}\n          onQRClick={currentModal?.onQRClick}\n          step={isShowAccount.step}\n          etherscanBaseUrl={etherscanBaseUrl}\n          isLayer2Only={true}\n          noClose={currentModal?.noClose}\n        />\n      </>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/core/src/modal/AccountModal/components/NFTDetail.tsx",
    "content": "import styled from '@emotion/styled'\nimport {\n  Avatar,\n  Box,\n  BoxProps,\n  Divider,\n  Grid,\n  IconButton,\n  Link,\n  Tab,\n  Tabs,\n  Tooltip,\n  Typography,\n} from '@mui/material'\nimport {\n  AssetsRawDataItem,\n  EmptyValueTag,\n  Explorer,\n  getShortAddr,\n  ImageIcon,\n  IPFS_LOOPRING_SITE,\n  LinkIcon,\n  myLog,\n  NFT_TYPE_STRING,\n  NFTWholeINFO,\n  RefreshIPFSIcon,\n  type,\n  ZoomIcon,\n  TOAST_TIME,\n  htmlDecode,\n  HideIcon,\n  ViewIcon,\n  SDK_ERROR_MAP_TO_UI,\n  UIERROR_CODE,\n  FavSolidIcon,\n  FavHollowIcon,\n  BurnIcon,\n  RedPacketIcon,\n  RouterPath,\n} from '@loopring-web/common-resources'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport {\n  Button,\n  TextareaAutosizeStyled,\n  useOpenModals,\n  useSettings,\n  useToggle,\n  NFTMedia,\n  ZoomMedia,\n  AccountStep,\n  EmptyDefault,\n  Toast,\n  ToastType,\n} from '@loopring-web/component-lib'\nimport { nftRefresh, store, useAccount, useSystem } from '../../../stores'\nimport React from 'react'\nimport { getIPFSString } from '../../../utils'\nimport { LoopringAPI } from '../../../api_wrapper'\nimport { useToast } from '../../../hooks'\nimport { sanitize } from 'dompurify'\nimport { StylePaper } from '../../../component'\nimport { DEPLOYMENT_STATUS, NFTType } from '@loopring-web/loopring-sdk'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { useHistory } from 'react-router-dom'\nimport { useTheme } from '@emotion/react'\n\nenum NFTDetailTab {\n  Detail = 'Detail',\n  Property = 'Property',\n}\n\nconst BoxNFT = styled(Box)`\n  background: var(--color-global-bg-opacity);\n\n  img {\n    object-fit: contain;\n  }\n` as typeof Box\n\nconst FavoriteBoxStyle = styled(Box)`\n  .favHollow {\n    &:hover {\n      color: var(--color-error);\n    }\n  }\n\n  .favSolid {\n    &:hover {\n      color: var(--color-text-secondary);\n    }\n  }\n`\nconst BoxStyle = styled(Box)<\n  { isMobile: boolean; baseURL: string } & BoxProps & Partial<NFTWholeINFO>\n>`\n  .objectFit {\n    img {\n      object-fit: contain;\n    }\n  }\n\n  .line-clamp {\n    display: -webkit-box;\n    -webkit-line-clamp: 2;\n    -webkit-box-orient: vertical;\n    overflow: hidden;\n  }\n` as (\n  props: { isMobile?: boolean; baseURL?: string } & BoxProps & Partial<NFTWholeINFO>,\n) => JSX.Element\nexport const NFTDetail = withTranslation('common')(\n  ({\n    popItem,\n    etherscanBaseUrl,\n    baseURL,\n    setNFTMetaNotReady,\n    t,\n  }: {\n    popItem: Partial<NFTWholeINFO>\n    etherscanBaseUrl: string\n    baseURL: string\n    setNFTMetaNotReady: (props: any) => void\n    assetsRawData: AssetsRawDataItem[]\n  } & WithTranslation) => {\n    const { isMobile } = useSettings()\n    const { chainId } = useSystem()\n    const theme = useTheme()\n\n    const { account } = useAccount()\n    const [iconLoading, setIconLoading] = React.useState(false)\n    const {\n      nftDataHashes: { nftDataHashes },\n      updateNFTRefreshHash,\n    } = nftRefresh.useNFTRefresh()\n\n    const nodeTimer = React.useRef<NodeJS.Timeout | -1>(-1)\n    const { toastOpen, setToastOpen, closeToast } = useToast()\n    const {\n      toggle: { deployNFT },\n    } = useToggle()\n    const {\n      setShowNFTDetail,\n      setShowAccount,\n      setShowNFTTransfer,\n      setShowNFTDeploy,\n      setShowTradeIsFrozen,\n      modals: { isShowNFTDetail },\n    } = useOpenModals()\n    const [zoom, setZoom] = React.useState(false)\n    const [tabValue, setTabValue] = React.useState(NFTDetailTab.Detail)\n    const [showFresh, setShowFresh] = React.useState(\n      popItem?.nftData && nftDataHashes[popItem.nftData?.toLowerCase()] ? 'loading' : 'click',\n    )\n    const history = useHistory()\n    myLog('showFresh', showFresh)\n    const onFavoriteClick = React.useCallback(async () => {\n      if (LoopringAPI.userAPI) {\n        try {\n          setIconLoading(true)\n          const response = await LoopringAPI.userAPI.submitUpdateNFTGroup(\n            {\n              accountId: account.accountId,\n              nftHashes: [popItem.nftData ?? ''],\n              preferenceType: sdk.NFT_PREFERENCE_TYPE.fav,\n              statusToUpdate: !popItem?.preference?.favourite,\n            },\n            chainId as any,\n            account.apiKey,\n            account.eddsaKey.sk,\n          )\n          setIconLoading(false)\n          if (\n            response &&\n            ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message)\n          ) {\n            const _response: sdk.RESULT_INFO = response as sdk.RESULT_INFO\n            throw new Error(\n              t(\n                _response.code && SDK_ERROR_MAP_TO_UI[_response.code]\n                  ? SDK_ERROR_MAP_TO_UI[_response.code].messageKey\n                  : SDK_ERROR_MAP_TO_UI[UIERROR_CODE.UNKNOWN].messageKey,\n                { ns: 'error', name: popItem.name?.trim() },\n              ),\n            )\n          } else {\n            setToastOpen({\n              open: true,\n              type: ToastType.success,\n              content: t(`labelFavouriteSuccess`, {\n                favorite: !popItem?.preference?.favourite\n                  ? t('labelfavourite')\n                  : t('labelunfavourite'),\n              }),\n            })\n            setShowNFTDetail({\n              ...isShowNFTDetail,\n              preference: {\n                ...isShowNFTDetail.preference,\n                favourite: !popItem?.preference?.favourite ?? false,\n              } as any,\n            })\n          }\n        } catch (error) {\n          setToastOpen({\n            open: true,\n            type: ToastType.error,\n            content:\n              t(`labelFavouriteFailed`, {\n                favorite: !popItem?.preference?.favourite\n                  ? t('labelfavourite')\n                  : t('labelunfavourite'),\n              }) + `: ${(error as any)?.message ? (error as any).message : t('errorUnknown')}`,\n          })\n        }\n      }\n    }, [popItem])\n    const onHideClick = React.useCallback(async () => {\n      if (LoopringAPI.userAPI) {\n        try {\n          setIconLoading(true)\n          const response = await LoopringAPI.userAPI.submitUpdateNFTGroup(\n            {\n              accountId: account.accountId,\n              nftHashes: [popItem.nftData ?? ''],\n              preferenceType: sdk.NFT_PREFERENCE_TYPE.hide,\n              statusToUpdate: !popItem?.preference?.hide,\n            },\n            chainId as any,\n            account.apiKey,\n            account.eddsaKey.sk,\n          )\n          setIconLoading(false)\n          if (\n            response &&\n            ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message)\n          ) {\n            const _response: sdk.RESULT_INFO = response as sdk.RESULT_INFO\n            throw new Error(\n              t(\n                _response.code && SDK_ERROR_MAP_TO_UI[_response.code]\n                  ? SDK_ERROR_MAP_TO_UI[_response.code].messageKey\n                  : SDK_ERROR_MAP_TO_UI[UIERROR_CODE.UNKNOWN].messageKey,\n                { ns: 'error', name: popItem.name?.trim() },\n              ),\n            )\n          } else {\n            setToastOpen({\n              open: true,\n              type: ToastType.success,\n              content: t(`labelHideSuccess`, {\n                hide: !popItem?.preference?.hide ? t('labelhide') : t('labelunhide'),\n              }),\n            })\n            setShowNFTDetail({\n              ...isShowNFTDetail,\n              preference: {\n                ...isShowNFTDetail.preference,\n                hide: !popItem?.preference?.hide ?? false,\n              } as any,\n            })\n          }\n        } catch (error) {\n          setToastOpen({\n            open: true,\n            type: ToastType.error,\n            content:\n              t(`labelHideFailed`, {\n                hide: !popItem?.preference?.hide ? t('labelhide') : t('labelunhide'),\n              }) + `: ${(error as any)?.message ? (error as any).message : t('errorUnknown')}`,\n          })\n        }\n      }\n    }, [popItem])\n\n    const handleRefresh = React.useCallback(async () => {\n      setShowFresh('loading')\n      setToastOpen({\n        open: true,\n        type: ToastType.success,\n        content: t('labelNFTServerRefreshSubmit'),\n      })\n      if (popItem && popItem.nftData) {\n        updateNFTRefreshHash(popItem.nftData)\n        await LoopringAPI.nftAPI?.callRefreshNFT({\n          network: 'ETHEREUM',\n          tokenAddress: popItem.tokenAddress ?? '',\n          nftId: popItem?.nftId?.toString() ?? '',\n          nftType: (popItem?.nftType?.toString() ?? '') as NFT_TYPE_STRING,\n        })\n        setToastOpen({\n          open: true,\n          type: ToastType.success,\n          content: t('labelNFTServerRefreshSubmit'),\n        })\n      }\n    }, [])\n    // const [showDialog, setShowDialog] =\n    //   React.useState<string | undefined>(undefined);\n    const [isKnowNFTNoMeta, setIsKnowNFTNoMeta] = React.useState<boolean>(\n      !!(popItem?.name !== '' && popItem.image && popItem.image !== ''),\n    )\n\n    let properties = popItem.properties\n      ? typeof popItem.properties === 'string'\n        ? JSON.parse(popItem.properties)\n        : popItem.properties\n      : undefined\n    React.useEffect(() => {\n      setIsKnowNFTNoMeta((_state) => {\n        return !!(popItem.name !== '' && popItem.image && popItem.image !== '')\n      })\n    }, [popItem.name, popItem.image])\n\n    const updateNFTStatus = React.useCallback(async () => {\n      const nftDataHashes = store.getState().localStore.nftHashInfos[chainId]?.nftDataHashes\n      clearTimeout(nodeTimer.current as NodeJS.Timeout)\n      if (popItem.nftData && nftDataHashes && nftDataHashes[popItem.nftData.toLowerCase()]) {\n        updateNFTRefreshHash(popItem.nftData)\n        nodeTimer.current = setTimeout(() => {\n          updateNFTStatus()\n          // updateNFTRefreshHash(popItem.nftData);\n        }, 180000)\n      } else {\n        setShowFresh('click')\n      }\n      return () => {\n        clearTimeout(nodeTimer.current as NodeJS.Timeout)\n      }\n    }, [nodeTimer])\n\n    React.useEffect(() => {\n      if (popItem?.nftData && nftDataHashes[popItem.nftData]) {\n        updateNFTStatus()\n      }\n    }, [nftDataHashes, popItem.nftData])\n    const compileString = (str: any) => {\n      const _type = type(str)\n      let _str\n      if (['string', 'number', 'symbol'].includes(_type)) {\n        _str = str\n      } else if (['array', 'object'].includes(_type)) {\n        _str = JSON.stringify(str, undefined, 2)\n      }\n      return sanitize(_str ?? EmptyValueTag)\n    }\n    const ref = React.useRef()\n    const cid = LoopringAPI?.nftAPI?.ipfsNftIDToCid(popItem?.nftId ?? '')\n    return (\n      <>\n        <StylePaper\n          display={'flex'}\n          flexDirection={'row'}\n          flex={1}\n          paddingX={3}\n          paddingTop={3}\n          paddingBottom={2}\n          marginTop={2}\n        >\n          <Grid container>\n            <Grid item xs={12} md={5} lg={5} display={'flex'} flexDirection={'column'}>\n              <BoxNFT flex={1} position={'relative'} paddingTop={'100%'}>\n                <Box\n                  position={'absolute'}\n                  top={0}\n                  right={0}\n                  bottom={0}\n                  left={0}\n                  display={'flex'}\n                  alignItems={'center'}\n                  justifyContent={'center'}\n                >\n                  <NFTMedia\n                    ref={ref}\n                    item={popItem as Partial<NFTWholeINFO>}\n                    shouldPlay={true}\n                    onNFTError={() => undefined}\n                    isOrigin={true}\n                    getIPFSString={getIPFSString}\n                    baseURL={baseURL}\n                  />\n                </Box>\n              </BoxNFT>\n              <FavoriteBoxStyle\n                marginTop={2}\n                display={'flex'}\n                alignItems={'center'}\n                justifyContent={'center'}\n              >\n                {popItem.preference && (\n                  <Tooltip\n                    title={t(\n                      `labelFavouriteMethodTooltip${\n                        popItem.preference.favourite ? 'unfavourite' : 'favourite'\n                      }`,\n                    ).toString()}\n                    placement={'top'}\n                  >\n                    <IconButton\n                      aria-label={t(\n                        `labelHideMethodTooltip${\n                          popItem.preference.favourite ? 'favourite' : 'unfavourite'\n                        }`,\n                      )}\n                      size={'large'}\n                      edge={'end'}\n                      disabled={iconLoading}\n                      color={'inherit'}\n                      onClick={(_event) => {\n                        onFavoriteClick()\n                      }}\n                      sx={{\n                        minWidth: 'initial',\n                        padding: '4px',\n                        marginRight: 1,\n                      }}\n                    >\n                      {popItem.preference.favourite ? (\n                        <FavSolidIcon className={'favSolid'} htmlColor={'var(--color-error)'} />\n                      ) : (\n                        <FavHollowIcon className={'favHollow'} />\n                      )}\n                    </IconButton>\n                  </Tooltip>\n                )}\n                <Tooltip title={t('labelNFTServerRefresh').toString()} placement={'top'}>\n                  <IconButton\n                    aria-label={t('labelRefresh')}\n                    disabled={showFresh !== 'click'}\n                    size={'large'}\n                    edge={'end'}\n                    color={'inherit'}\n                    onClick={(_event) => {\n                      handleRefresh()\n                    }}\n                    sx={{ minWidth: 'initial', padding: '4px', marginRight: 1 }}\n                  >\n                    <RefreshIPFSIcon color={showFresh !== 'click' ? 'disabled' : undefined} />\n                  </IconButton>\n                </Tooltip>\n                <Tooltip title={t('labelZoom').toString()} placement={'top'}>\n                  <IconButton\n                    aria-label={t('labelZoom')}\n                    size={'large'}\n                    edge={'end'}\n                    color={'inherit'}\n                    onClick={(_event) => {\n                      setZoom(true)\n                    }}\n                    sx={{ minWidth: 'initial', padding: '4px', marginRight: 1 }}\n                  >\n                    <ZoomIcon />\n                  </IconButton>\n                </Tooltip>\n                {popItem.preference && (\n                  <Tooltip\n                    title={t(\n                      `labelHideMethodTooltip${popItem.preference.hide ? 'unhide' : 'hide'}`,\n                    ).toString()}\n                    placement={'top'}\n                  >\n                    <IconButton\n                      aria-label={t(\n                        `labelHideMethodTooltip${popItem.preference.hide ? 'hide' : 'unhide'}`,\n                      )}\n                      size={'large'}\n                      edge={'end'}\n                      disabled={iconLoading}\n                      color={'inherit'}\n                      onClick={(_event) => {\n                        onHideClick()\n                      }}\n                      sx={{\n                        minWidth: 'initial',\n                        padding: '4px',\n                        marginRight: 1,\n                      }}\n                    >\n                      {popItem.preference.hide ? <HideIcon /> : <ViewIcon />}\n                    </IconButton>\n                  </Tooltip>\n                )}\n              </FavoriteBoxStyle>\n            </Grid>\n            <Grid\n              item\n              xs={12}\n              md={7}\n              lg={7}\n              display={'flex'}\n              flexDirection={'column'}\n              justifyContent={'space-between'}\n            >\n              <BoxStyle flexDirection={'column'} display={'flex'} paddingLeft={3} flex={1}>\n                {popItem?.collectionInfo && (\n                  <Box display={'flex'} flexDirection={'row'} alignItems={'center'} marginTop={2}>\n                    <>\n                      {(\n                        popItem?.collectionInfo?.cached?.tileUri ??\n                        getIPFSString(popItem?.collectionInfo?.tileUri ?? '', baseURL)\n                      ).startsWith('http') ? (\n                        <Avatar\n                          className={'objectFit'}\n                          sx={{\n                            bgcolor: 'var(--color-global-bg-opacity)',\n                            marginRight: 1,\n                            width: 'var(--svg-size-large)',\n                            height: 'var(--svg-size-large)',\n                          }}\n                          variant={'rounded'}\n                          src={\n                            popItem?.collectionInfo?.cached?.tileUri ??\n                            getIPFSString(popItem?.collectionInfo?.tileUri ?? '', baseURL)\n                          }\n                        />\n                      ) : (\n                        <Avatar\n                          sx={{\n                            bgcolor: 'var(--color-global-bg-opacity)',\n                            marginRight: 1,\n                            width: 'var(--svg-size-large)',\n                            height: 'var(--svg-size-large)',\n                            color: 'var(--color-text-third)',\n                          }}\n                          variant={'rounded'}\n                        >\n                          <ImageIcon />\n                        </Avatar>\n                      )}\n                      <Typography\n                        component={'h4'}\n                        whiteSpace={'pre-line'}\n                        sx={{ wordBreak: 'break-all' }}\n                        color={'textPrimary'}\n                        variant={'body1'}\n                      >\n                        {popItem?.collectionInfo\n                          ? popItem?.collectionInfo?.name\n                            ? htmlDecode(popItem.collectionInfo.name)\n                            : t('labelUnknown') +\n                              ' - ' +\n                              getShortAddr(popItem?.collectionInfo?.contractAddress ?? '')\n                          : EmptyValueTag}\n                      </Typography>\n                    </>\n                  </Box>\n                )}\n                <Box display={'flex'} alignItems={'center'} marginTop={2}>\n                  <Tooltip title={popItem?.name ?? EmptyValueTag} placement={'top'}>\n                    <Typography\n                      color={'textPrimary'}\n                      variant={'h1'}\n                      className={'line-clamp'}\n                      whiteSpace={'pre-line'}\n                      sx={{ wordBreak: 'break-all' }}\n                      dangerouslySetInnerHTML={{\n                        __html: sanitize(popItem?.name ?? EmptyValueTag) ?? '',\n                      }}\n                    />\n                  </Tooltip>\n                </Box>\n                <Box flex={1} marginTop={2} display={'flex'} marginBottom={2}>\n                  <TextareaAutosizeStyled\n                    aria-label='NFT Description'\n                    maxRows={5}\n                    disabled={true}\n                    style={{ padding: 0, height: 'auto' }}\n                    value={\n                      popItem?.description\n                        ? htmlDecode(popItem.description ?? '').toString()\n                        : EmptyValueTag\n                    }\n                  />\n                </Box>\n              </BoxStyle>\n              <Box\n                paddingLeft={3}\n                display={'flex'}\n                flexDirection={'row'}\n                justifyContent={'left'}\n                marginBottom={isMobile ? 2 : 5}\n                paddingRight={3}\n                alignItems={'center'}\n              >\n                <Box className={isMobile ? 'isMobile' : ''} width={'36%'}>\n                  <Button\n                    variant={'contained'}\n                    size={'medium'}\n                    fullWidth\n                    onClick={() =>\n                      isKnowNFTNoMeta\n                        ? setShowAccount({\n                            isShow: true,\n                            step: AccountStep.SendNFTGateway,\n                            info: { ...popItem },\n                          })\n                        : setNFTMetaNotReady({\n                            isShow: true,\n                            info: { method: 'Send' },\n                          })\n                    }\n                  >\n                    {t('labelNFTSendBtn')}\n                  </Button>\n                </Box>\n                {!!(\n                  popItem.isCounterFactualNFT &&\n                  popItem.deploymentStatus === DEPLOYMENT_STATUS.NOT_DEPLOYED &&\n                  popItem.minter?.toLowerCase() === account.accAddress.toLowerCase()\n                ) && (\n                  <Box marginLeft={1} className={isMobile ? 'isMobile' : ''} width={'36%'}>\n                    <Button\n                      variant={'contained'}\n                      size={'medium'}\n                      fullWidth\n                      onClick={() =>\n                        deployNFT.enable\n                          ? setShowNFTDeploy({\n                              isShow: true,\n                              info: { ...popItem },\n                            })\n                          : setShowTradeIsFrozen({\n                              isShow: true,\n                              type: t('nftDeployDescription'),\n                            })\n                      }\n                    >\n                      {t('labelNFTDeployContract')}\n                    </Button>\n                  </Box>\n                )}\n                {/* <Box marginLeft={2}>\n                  <IconButton\n                    size={'large'}\n                    onClick={() => {\n                      history.push(`${RouterPath.redPacket}/create?nftDatas=${popItem.nftData}`)\n                    }}\n                    style={{\n                      height: 40,\n                      width: 40,\n                      background: '#F26666',\n                      borderRadius: theme.unit,\n                    }}\n                  >\n                    <RedPacketIcon htmlColor={'var(--color-white)'} />\n                  </IconButton>\n                </Box> */}\n                <Box marginLeft={2}>\n                  <IconButton\n                    size={'large'}\n                    style={{\n                      height: 40,\n                      width: 40,\n                      background: 'var(--color-global-bg)',\n                      borderRadius: theme.unit,\n                    }}\n                    title={t('labelL2NFTBurnBtn')}\n                    onClick={() => {\n                      setShowNFTTransfer({ isShow: true, info: { isBurn: true, ...popItem } })\n                    }}\n                  >\n                    <BurnIcon htmlColor={theme.mode === 'dark' ? 'var(--color-white)' : 'var(--color-black)'} />\n                  </IconButton>\n                </Box>\n              </Box>\n            </Grid>\n          </Grid>\n        </StylePaper>\n        <StylePaper display={'flex'} flexDirection={'row'} flex={1}>\n          <Box\n            paddingLeft={1}\n            display={'flex'}\n            flexDirection={'row'}\n            justifyContent={'space-between'}\n            alignItems={'center'}\n          >\n            <Tabs\n              value={tabValue}\n              onChange={(_e, value) => setTabValue(value)}\n              aria-label='NFT Detail Tab'\n            >\n              <Tab label={t('labelNFTDetailTab')} value={NFTDetailTab.Detail} />\n              <Tab label={t('labelNFTPropertiesTab')} value={NFTDetailTab.Property} />\n            </Tabs>\n          </Box>\n          <Divider style={{ marginTop: '-1px' }} />\n          <Box\n            display={'flex'}\n            flexDirection={'column'}\n            justifyContent={'stretch'}\n            marginBottom={2}\n            paddingX={3}\n            flex={1}\n          >\n            {tabValue === NFTDetailTab.Detail && (\n              <>\n                <Typography\n                  display={'inline-flex'}\n                  flexDirection={'row'}\n                  variant={'body1'}\n                  marginTop={1}\n                  justifyContent={'space-between'}\n                >\n                  <Typography component={'span'} color={'var(--color-text-third)'} width={150}>\n                    {t('labelNFTTOTAL')}\n                  </Typography>\n                  <Typography\n                    component={'span'}\n                    color={'var(--color-text-secondary)'}\n                    title={popItem?.total}\n                  >\n                    {Number(popItem.total) - Number(popItem.locked ?? 0)}\n                  </Typography>\n                </Typography>\n                <Typography\n                  display={'inline-flex'}\n                  flexDirection={'row'}\n                  justifyContent={'space-between'}\n                  variant={'body1'}\n                  marginTop={1}\n                >\n                  <Typography component={'span'} color={'var(--color-text-third)'} width={150}>\n                    {t('labelNFTID')}\n                  </Typography>\n                  <Link\n                    fontSize={'inherit'}\n                    whiteSpace={'break-spaces'}\n                    display={'inline-flex'}\n                    alignItems={'center'}\n                    style={{ wordBreak: 'break-all' }}\n                    target='_blank'\n                    rel='noopener noreferrer'\n                    href={\n                      Explorer +\n                      `nft/${popItem.minter?.toLowerCase()}-${\n                        NFTType[popItem.nftType ?? 0]\n                      }-${popItem.tokenAddress?.toLowerCase()}-${popItem.nftId?.toLowerCase()}-${\n                        popItem.royaltyPercentage\n                      }`\n                    }\n                    title={popItem?.nftId}\n                    width={'fit-content'}\n                  >\n                    {'# ' +\n                      getShortAddr(popItem?.nftIdView ? popItem.nftIdView : popItem.nftId ?? '')}\n                    <LinkIcon fontSize={'medium'} />\n                  </Link>\n                </Typography>\n                <Typography\n                  display={'inline-flex'}\n                  flexDirection={'row'}\n                  justifyContent={'space-between'}\n                  variant={'body1'}\n                  marginTop={1}\n                >\n                  <Typography component={'span'} color={'var(--color-text-third)'} width={150}>\n                    {t('labelNFTContractAddress')}\n                  </Typography>\n                  <Link\n                    fontSize={'inherit'}\n                    whiteSpace={'break-spaces'}\n                    style={{ wordBreak: 'break-all' }}\n                    target='_blank'\n                    rel='noopener noreferrer'\n                    href={\n                      popItem.deploymentStatus === DEPLOYMENT_STATUS.NOT_DEPLOYED\n                        ? `${Explorer}collections/${popItem.tokenAddress}?a=${popItem.nftId}`\n                        : `${etherscanBaseUrl}token/${popItem.tokenAddress}?a=${popItem.nftId}`\n                    }\n                  >\n                    {popItem.tokenAddress}\n                  </Link>\n                </Typography>\n                <Typography\n                  display={'inline-flex'}\n                  flexDirection={'row'}\n                  justifyContent={'space-between'}\n                  variant={'body1'}\n                  marginTop={1}\n                >\n                  <Typography component={'span'} color={'var(--color-text-third)'} width={150}>\n                    {t('labelNFTRoyaltyPercentage')}\n                  </Typography>\n                  <Typography\n                    component={'span'}\n                    color={'var(--color-text-secondary)'}\n                    // title={popItem?.royaltyPercentage}\n                  >\n                    {popItem?.royaltyPercentage ?? EmptyValueTag + '%'}\n                  </Typography>\n                </Typography>\n                <Typography\n                  display={'inline-flex'}\n                  flexDirection={'row'}\n                  justifyContent={'space-between'}\n                  variant={'body1'}\n                  marginTop={1}\n                >\n                  <Typography component={'span'} color={'var(--color-text-third)'} width={150}>\n                    {t('labelNFTTYPE')}\n                  </Typography>\n                  <Typography\n                    component={'span'}\n                    color={'var(--color-text-secondary)'}\n                    title={popItem?.nftType}\n                  >\n                    {popItem?.nftType}\n                  </Typography>\n                </Typography>\n\n                <Typography\n                  display={'inline-flex'}\n                  flexDirection={'row'}\n                  justifyContent={'space-between'}\n                  variant={'body1'}\n                  marginTop={1}\n                >\n                  <Typography component={'span'} color={'var(--color-text-third)'} width={150}>\n                    {t('labelNFTMinter')}\n                  </Typography>\n\n                  <Link\n                    fontSize={'inherit'}\n                    whiteSpace={'break-spaces'}\n                    style={{ wordBreak: 'break-all' }}\n                    onClick={() => {\n                      window.open(`${etherscanBaseUrl}address/${popItem.minter}`, 'blank')\n                      window.opener = null\n                    }}\n                  >\n                    {popItem.minter}\n                  </Link>\n                </Typography>\n                <Typography\n                  display={'inline-flex'}\n                  flexDirection={'row'}\n                  justifyContent={'space-between'}\n                  variant={'body1'}\n                  marginTop={1}\n                >\n                  <Typography component={'span'} color={'var(--color-text-third)'} width={150}>\n                    {t('labelNFTMetadata')}\n                  </Typography>\n\n                  <Link\n                    fontSize={'inherit'}\n                    whiteSpace={'break-spaces'}\n                    style={{ wordBreak: 'break-all' }}\n                    onClick={() => {\n                      window.open(IPFS_LOOPRING_SITE + cid, 'blank')\n                      window.opener = null\n                    }}\n                  >\n                    {cid}\n                  </Link>\n                </Typography>\n              </>\n            )}\n            {tabValue === NFTDetailTab.Property &&\n              (!!properties ? (\n                typeof properties === 'string' ? (\n                  <Typography\n                    display={'inline-flex'}\n                    flexDirection={isMobile ? 'column' : 'row'}\n                    variant={'body1'}\n                    marginTop={1}\n                  >\n                    {properties.toString()}\n                  </Typography>\n                ) : (\n                  [...(Array.isArray(properties) ? properties : Object.keys(properties))].map(\n                    (key, index) => {\n                      // @ts-ignore\n                      return Array.isArray(properties) ? (\n                        <Typography\n                          component={'pre'}\n                          key={JSON.stringify(key) + index}\n                          marginTop={1}\n                          display={'inline-flex'}\n                          flexDirection={'row'}\n                          justifyContent={'space-between'}\n                          variant={'body1'}\n                          dangerouslySetInnerHTML={{\n                            __html: compileString(key) ?? '',\n                          }}\n                        />\n                      ) : (\n                        // JSON.stringify(key.toString())\n                        <Typography\n                          key={key.toString() + index}\n                          marginTop={1}\n                          display={'inline-flex'}\n                          flexDirection={'row'}\n                          justifyContent={'space-between'}\n                          variant={'body1'}\n                        >\n                          <Typography\n                            component={'pre'}\n                            color={'var(--color-text-third)'}\n                            width={150}\n                            dangerouslySetInnerHTML={{\n                              __html: sanitize(key.toString() ?? EmptyValueTag) ?? '',\n                            }}\n                          />\n                          <Typography\n                            component={'pre'}\n                            color={'var(--color-text-secondary)'}\n                            title={key.toString()}\n                            dangerouslySetInnerHTML={{\n                              __html: compileString(properties[key.toString()]) ?? '',\n                            }}\n                          />\n                        </Typography>\n                      )\n                    },\n                  )\n                )\n              ) : (\n                <Box flex={1} height={'100%'} width={'100%'}>\n                  <EmptyDefault\n                    style={{ alignSelf: 'center' }}\n                    height={'100%'}\n                    message={() => (\n                      <Box\n                        flex={1}\n                        display={'flex'}\n                        alignItems={'center'}\n                        justifyContent={'center'}\n                      >\n                        {t('labelNoContent')}\n                      </Box>\n                    )}\n                  />\n                </Box>\n              ))}\n          </Box>\n        </StylePaper>\n        <ZoomMedia\n          onClose={() => {\n            setZoom(false)\n          }}\n          getIPFSString={getIPFSString}\n          baseURL={baseURL}\n          open={zoom}\n          nftItem={popItem as Partial<NFTWholeINFO>}\n        />\n        <Toast\n          alertText={toastOpen?.content ?? ''}\n          severity={toastOpen?.type ?? ToastType.success}\n          open={toastOpen?.open ?? false}\n          autoHideDuration={TOAST_TIME}\n          onClose={closeToast}\n        />\n      </>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/core/src/modal/AccountModal/components/QRCodeScanner.tsx",
    "content": "import { ImportRedPacketWrap } from '@loopring-web/component-lib'\nimport { useQrcodeScan } from '../../../services'\nimport React from 'react'\nimport { myLog } from '@loopring-web/common-resources'\n// import { useLocation } from 'react-use';\n\nexport const ImportRedPacket = ({\n  handleSuccess,\n}: {\n  handleSuccess: (value: string) => Promise<void>\n}) => {\n  const ref = React.useRef()\n  // const { search } = useLocation();\n  const handleFailedUpload = React.useCallback((data: any) => {\n    myLog('handleFailedUpload', data)\n  }, [])\n  const handleSuccessUpload = React.useCallback((result: any) => {\n    myLog('handleSuccessUpload', result?.data?.decodedText)\n    if (result?.data?.decodedText) {\n      handleSuccess(result?.data?.decodedText)\n    }\n  }, [])\n\n  const { h5QrcodeScannerProvides } = useQrcodeScan({\n    handleFailedUpload,\n    handleSuccessUpload,\n  })\n  React.useEffect(() => {\n    if (ref.current) {\n      h5QrcodeScannerProvides.render()\n    } else {\n      h5QrcodeScannerProvides.clear()\n    }\n    return () => {\n      h5QrcodeScannerProvides.clear()\n    }\n  }, [ref.current])\n  return <ImportRedPacketWrap ref={ref} />\n}\n"
  },
  {
    "path": "packages/core/src/modal/AccountModal/hook.tsx",
    "content": "/* eslint-disable react/jsx-pascal-case */\nimport {\n  AccountStep,\n  AddAsset,\n  AddAssetItem,\n  Button,\n  CheckActiveStatus,\n  ClaimWithdraw_Denied,\n  ClaimWithdraw_Failed,\n  ClaimWithdraw_First_Method_Denied,\n  ClaimWithdraw_In_Progress,\n  ClaimWithdraw_Submit,\n  ClaimWithdraw_WaitForAuth,\n  ContinuousBanxaOrder,\n  CreateAccount_Approve_Denied,\n  CreateAccount_Approve_Submit,\n  CreateAccount_Approve_WaitForAuth,\n  CreateAccount_Denied,\n  CreateAccount_Failed,\n  CreateAccount_Submit,\n  CreateAccount_WaitForAuth,\n  Deposit_Approve_Denied,\n  Deposit_Approve_WaitForAuth,\n  Deposit_Denied,\n  Deposit_Failed,\n  Deposit_Sign_WaitForRefer,\n  Deposit_Submit,\n  Deposit_WaitForAuth,\n  DepositProps,\n  Dual_Failed,\n  Dual_Success,\n  Staking_Failed,\n  Staking_Success,\n  ExportAccount_Approve_WaitForAuth,\n  ExportAccount_Failed,\n  ExportAccount_Success,\n  ExportAccount_User_Denied,\n  ForceWithdraw_Denied,\n  ForceWithdraw_Failed,\n  ForceWithdraw_First_Method_Denied,\n  ForceWithdraw_In_Progress,\n  ForceWithdraw_Submit,\n  ForceWithdraw_WaitForAuth,\n  HadAccount,\n  NFTDeploy_Denied,\n  NFTDeploy_Failed,\n  NFTDeploy_First_Method_Denied,\n  NFTDeploy_In_Progress,\n  NFTDeploy_Submit,\n  NFTDeploy_WaitForAuth,\n  NFTDeposit_Approve_Denied,\n  NFTDeposit_Approve_WaitForAuth,\n  NFTDeposit_Denied,\n  NFTDeposit_Failed,\n  NFTDeposit_Submit,\n  NFTDeposit_WaitForAuth,\n  NFTMint_Denied,\n  NFTMint_Failed,\n  NFTMint_First_Method_Denied,\n  NFTMint_In_Progress,\n  NFTMint_Success,\n  NFTMint_WaitForAuth,\n  NFTTransfer_Failed,\n  NFTTransfer_First_Method_Denied,\n  NFTTransfer_In_Progress,\n  NFTTransfer_Success,\n  NFTTransfer_User_Denied,\n  NFTTransfer_WaitForAuth,\n  NFTWithdraw_Failed,\n  NFTWithdraw_First_Method_Denied,\n  NFTWithdraw_In_Progress,\n  NFTWithdraw_Success,\n  NFTWithdraw_User_Denied,\n  NFTWithdraw_WaitForAuth,\n  NoAccount,\n  QRAddressPanel,\n  RedPacketOpen_Claim_Failed,\n  RedPacketOpen_Claim_In_Progress,\n  RedPacketOpen_Failed,\n  RedPacketOpen_In_Progress,\n  RedPacketSend_Claim_Success,\n  RedPacketSend_Failed,\n  RedPacketSend_First_Method_Denied,\n  RedPacketSend_In_Progress,\n  RedPacketSend_Success,\n  RedPacketSend_User_Denied,\n  RedPacketSend_WaitForAuth,\n  SendAsset,\n  SendAssetItem,\n  SendNFTAsset,\n  ThirdPanelReturn,\n  Transfer_banxa_confirm,\n  Transfer_Failed,\n  Transfer_First_Method_Denied,\n  Transfer_In_Progress,\n  Transfer_Success,\n  Transfer_User_Denied,\n  Transfer_WaitForAuth,\n  UnlockAccount_Failed,\n  UnlockAccount_Success,\n  UnlockAccount_User_Denied,\n  UnlockAccount_WaitForAuth,\n  UpdateAccount,\n  UpdateAccount_Approve_WaitForAuth,\n  UpdateAccount_Failed,\n  UpdateAccount_First_Method_Denied,\n  UpdateAccount_Success,\n  UpdateAccount_User_Denied,\n  useOpenModals,\n  VendorMenu,\n  Withdraw_Failed,\n  Withdraw_First_Method_Denied,\n  Withdraw_In_Progress,\n  Withdraw_Success,\n  Withdraw_User_Denied,\n  Withdraw_WaitForAuth,\n  Staking_Redeem_Success,\n  Staking_Redeem_Failed,\n  BtradeSwap_Settled,\n  BtradeSwap_Delivering,\n  BtradeSwap_Failed,\n  BtradeSwap_Pending,\n  AMM_Pending,\n  useSettings,\n  TOASTOPEN,\n  setShowGlobalToast,\n  SendFromContact,\n  NFTBurn_Failed,\n  NFTBurn_First_Method_Denied,\n  NFTBurn_In_Progress,\n  NFTBurn_Success,\n  NFTBurn_User_Denied,\n  NFTBurn_WaitForAuth,\n\t// NFTBurn_Failed,\n\t// NFTBurn_First_Method_Denied,\n\t// NFTBurn_In_Progress,\n\t// NFTBurn_Success,\n\t// NFTBurn_User_Denied,\n\t// NFTBurn_WaitForAuth,\n  // SendFromContact,\n  VaultTrade_Success,\n  VaultTrade_Failed,\n  VaultTrade_In_Progress,\n  VaultJoin_Success,\n  VaultJoin_Failed,\n  VaultJoin_In_Progress,\n  VaultRedeem_Success,\n  VaultRedeem_Failed,\n  VaultRedeem_In_Progress,\n  VaultBorrow_Success,\n  VaultBorrow_Failed,\n  VaultBorrow_In_Progress,\n  VaultRepay_Success,\n  VaultRepay_Failed,\n  VaultRepay_In_Progress,\n  VaultDustCollector_Success,\n  VaultDustCollector_Failed,\n  VaultDustCollector_In_Progress,\n  General_Failed,\n  Taiko_Farming_Lock_Success,\n  Taiko_Farming_Redeem_Failed,\n  Taiko_Farming_Redeem_Success,\n  Taiko_Farming_Lock_Failed,\n  Taiko_Farming_Mint_Success,\n  Taiko_Farming_Mint_Failed,\n  Taiko_Farming_Mint_In_Progress,\n  Taiko_Farming_Redeem_In_Progress,\n  useToggle,\n  Transfer_To_TaikoUser_Denied,\n  Transfer_To_TaikoIn_Progress,\n  Transfer_To_Taiko_User_Denied,\n  Transfer_To_Taiko_In_Progress,\n  Transfer_To_Taiko_Success,\n  Transfer_To_Taiko_Failed,\n  UnlockAccount_Reset_Key_Confirm,\n  Coinbase_Smart_Wallet_Password_Intro,\n  Coinbase_Smart_Wallet_Password_Set,\n  Coinbase_Smart_Wallet_Password_Input,\n  Coinbase_Smart_Wallet_Password_Forget_Password_Confirm,\n  Coinbase_Smart_Wallet_Password_Forget_Password,\n  UpdateAccount_SmartWallet_NotSupported_Alert,\n  CreateAccount_EOA_Only_Alert,\n} from '@loopring-web/component-lib'\nimport { ConnectProviders, connectProvides, walletServices } from '@loopring-web/web3-provider'\n\nimport React, { useState } from 'react'\nimport {\n  Account,\n  AccountStatus,\n  AddAssetList,\n  AddAssetListMap,\n  AssetsRawDataItem,\n  Bridge,\n  copyToClipBoard,\n  FeeInfo,\n  InvestRouter,\n  InvestType,\n  L1L2_NAME_DEFINED,\n  MapChainId,\n  NFTSubRouter,\n  NFTWholeINFO,\n  RouterPath,\n  SendAssetList,\n  SendAssetListMap,\n  SendNFTAssetList,\n  SPECIAL_ACTIVATION_NETWORKS,\n  TradeTypes,\n  VendorProviders,\n} from '@loopring-web/common-resources'\nimport {\n  banxaService,\n  depositServices,\n  goActiveAccount,\n  LAST_STEP,\n  lockAccount,\n  mintService,\n  offFaitService,\n  onchainHashInfo,\n  OrderENDReason,\n  parseRabbitConfig,\n  store,\n  unlockAccount,\n  useAccount,\n  useActiveAccount,\n  useCheckActiveStatus,\n  useCoinbaseWalletPassword,\n  useCollectionAdvanceMeta,\n  useConfig,\n  useContacts,\n  useCreateRedPacket,\n  useExportAccount,\n  useForceWithdraw,\n\tuseModalData,\n\tuseNFTBurn,\n  useNFTDeploy,\n  useNFTMintAdvance,\n  useNFTTransfer,\n  useNFTWithdraw,\n  useNotify,\n  useRampTransPost,\n  useRedPacketScanQrcodeSuccess,\n  useReset,\n  useStakeTradeExit,\n  useSystem,\n  useTokenMap,\n  useTransfer,\n  useTransferToTaikoAccount,\n  useVendor,\n  useWalletLayer2,\n  useWithdraw,\n} from '@loopring-web/core'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { useHistory } from 'react-router-dom'\nimport { ImportRedPacket } from './components/QRCodeScanner'\nimport { useClaimConfirm } from '../../hooks/useractions/useClaimConfirm'\nimport { useContactAdd } from '../../hooks/useractions/useContactAdd'\nimport { Coinbase_Smart_Wallet_Password_Get_Error, Coinbase_Smart_Wallet_Password_Set_Confirm, Coinbase_Smart_Wallet_Password_Set_Error, Coinbase_Smart_Wallet_Password_Set_Processing } from '@loopring-web/component-lib/src/components/modal/ModalPanels/CoinbaseSmartWalletModal'\n\nexport function useAccountModalForUI({\n  t,\n  assetsRawData,\n  isLayer1Only = false,\n  depositProps,\n  isWebEarn,\n  ...rest\n}: {\n  t: any\n  etherscanBaseUrl: string\n  isLayer1Only?: boolean\n  depositProps: DepositProps<any, any>\n  account: Account\n  assetsRawData: AssetsRawDataItem[]\n  isWebEarn?: boolean\n  // onClose?: any;\n}) {\n  const { chainInfos, updateDepositHash, clearDepositHash } = onchainHashInfo.useOnChainInfo()\n\n  const { updateWalletLayer2 } = useWalletLayer2()\n  const { processRequestRampTransfer } = useRampTransPost()\n  const { campaignTagConfig } = useNotify().notifyMap ?? {}\n  const history = useHistory()\n  const {\n    modals: { isShowAccount },\n    setShowConnect,\n    setShowAccount,\n    setShowDeposit,\n    setShowTransfer,\n    setShowWithdraw,\n    setShowResetAccount,\n    setShowActiveAccount,\n    setShowNFTTransfer,\n    setShowNFTWithdraw,\n    setShowTransferToTaikoAccount\n  } = useOpenModals()\n  rest = { ...rest, ...isShowAccount.info }\n  const {\n    nftDepositValue,\n    nftTransferValue,\n    nftWithdrawValue,\n    nftDeployValue,\n    transferValue,\n    withdrawValue,\n    resetTransferData,\n    resetWithdrawData,\n    resetDepositData,\n    forceWithdrawValue,\n    claimValue,\n  } = useModalData()\n\n  const { chainId, allowTrade, app } = useSystem()\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const { account, addressShort, shouldShow, setShouldShow } = useAccount()\n  const redPacketScanQrcodeSuccessProps = useRedPacketScanQrcodeSuccess()\n\n  const { exportAccountAlertText, exportAccountToastOpen, setExportAccountToastOpen } =\n    useExportAccount()\n\n  const { retryBtn: nftMintAdvanceRetryBtn } = useNFTMintAdvance()\n  const { retryBtn: creatRedPacketRetryBtn } = useCreateRedPacket({\n    assetsRawData,\n    isShow: false,\n  })\n  // const [toastOpen, setToastOpen] = React.useState<TOASTOPEN>({\n  //   open: false,\n  //   content: '',\n  //   type: ToastType.info,\n  // })\n\n  const { collectionAdvanceProps } = useCollectionAdvanceMeta({\n    setCollectionToastOpen: (info: TOASTOPEN) => {\n      setShowGlobalToast({ isShow: info.open, info: { ...info } })\n    },\n  })\n  const { vendorListBuy, banxaRef } = useVendor()\n  // const { nftMintProps } = useNFTMint();\n  const { withdrawProps } = useWithdraw()\n  const transferToTaikoProps = useTransferToTaikoAccount()\n  const { transferProps } = useTransfer()\n  const { nftWithdrawProps } = useNFTWithdraw()\n  const { nftTransferProps } = useNFTTransfer()\n\tconst { nftBurnProps } = useNFTBurn()\n  const { nftDeployProps } = useNFTDeploy()\n  const { contactAddProps } = useContactAdd()\n  const { stakeWrapProps } = useStakeTradeExit({\n    setToastOpen: (info: TOASTOPEN) => setShowGlobalToast({ isShow: info.open, info: { ...info } }),\n  })\n  const { retryBtn: forceWithdrawRetry } = useForceWithdraw()\n  const { claimProps, retryBtn: claimRetryBtn } = useClaimConfirm()\n  const coinbaseWalletPassword = useCoinbaseWalletPassword()\n  const { resetProps } = useReset()\n  const { activeAccountProps, activeAccountCheckFeeIsEnough } = useActiveAccount()\n  const [tryCheckL2BalanceTimes, setTryCheckL2BalanceTimes] = React.useState(5)\n\n  // const { nftDepositProps } = useNFTDeposit();\n  const { exportAccountProps } = useExportAccount()\n\n  const [openQRCode, setOpenQRCode] = useState(false)\n\n  const [copyToastOpen, setCopyToastOpen] = useState(false)\n\n  const onSwitch = React.useCallback(() => {\n    setShowAccount({ isShow: false })\n    setShouldShow(true)\n    setShowConnect({ isShow: shouldShow ?? false })\n  }, [setShowAccount, setShouldShow, setShowConnect, shouldShow])\n\n  const onCopy = React.useCallback(async () => {\n    copyToClipBoard(account.accAddress)\n    setCopyToastOpen(true)\n  }, [account, setCopyToastOpen])\n\n  const onViewQRCode = React.useCallback(() => {\n    setOpenQRCode(true)\n  }, [setOpenQRCode])\n\n  const onDisconnect = React.useCallback(async () => {\n    walletServices.sendDisconnect('', 'customer click disconnect')\n    setShowAccount({ isShow: false })\n  }, [setShowAccount])\n\n  const onQRClick = React.useCallback(() => {\n    setShowAccount({ isShow: true, step: AccountStep.QRCode })\n  }, [setShowAccount])\n\n  const unlockBtn = React.useMemo(() => {\n    return (\n      <Button\n        variant={'contained'}\n        fullWidth\n        size={'medium'}\n        onClick={() => {\n          setShouldShow(true)\n          unlockAccount()\n        }}\n      >\n        {t('labelUnLockLayer2')}\n      </Button>\n    )\n  }, [t, setShouldShow])\n\n  const lockBtn = React.useMemo(() => {\n    return (\n      <Button\n        variant={'contained'}\n        fullWidth\n        size={'medium'}\n        onClick={() => {\n          lockAccount()\n        }}\n      >\n        {t('labelLockLayer2')}\n      </Button>\n    )\n  }, [t])\n\n  const onQRBack = React.useCallback(() => {\n    if (Number.isInteger(isShowAccount.info?.backTo)) {\n      setShowAccount({ isShow: true, step: isShowAccount.info?.backTo })\n    } else {\n      switch (account.readyState) {\n        case AccountStatus.NO_ACCOUNT:\n        case AccountStatus.DEPOSITING:\n          setShowAccount({ isShow: true, step: AccountStep.NoAccount })\n          break\n        case AccountStatus.LOCKED:\n        case AccountStatus.ACTIVATED:\n          // setShowAccount({ isShow: true, step: AccountStep.HadAccount })\n          break\n        default:\n          setShowAccount({ isShow: false })\n      }\n    }\n  }, [account.readyState, isShowAccount, setShowAccount])\n\n  const closeBtnInfo = React.useCallback(\n    (props?: { closeExtend?: (e?: any) => void }) => {\n      return {\n        btnTxt: 'labelClose',\n        callback: (e: any) => {\n          setShouldShow(false)\n          setShowAccount({ isShow: false })\n          if (props?.closeExtend) {\n            props?.closeExtend(e)\n          }\n        },\n      }\n    },\n    [setShouldShow, setShowAccount],\n  )\n  const nodeTimer = React.useRef<NodeJS.Timeout | -1>(-1)\n  const clearDeposit = React.useCallback(() => {\n    clearDepositHash(account.accAddress)\n  }, [clearDepositHash, account])\n\n  const updateDepositStatus = React.useCallback(async () => {\n    const chainInfos = store.getState().localStore.chainHashInfos[chainId]\n    const { accAddress } = account\n    clearTimeout(nodeTimer.current as NodeJS.Timeout)\n    if (\n      chainInfos &&\n      chainInfos.depositHashes &&\n      chainInfos.depositHashes[accAddress] &&\n      connectProvides\n    ) {\n      const depositList = chainInfos.depositHashes[accAddress]\n      let flag = false\n      depositList.forEach((txInfo) => {\n        if (txInfo.status === 'pending' && connectProvides?.usedWeb3?.eth?.getTransactionReceipt) {\n          connectProvides.usedWeb3.eth.getTransactionReceipt(txInfo.hash).then((result) => {\n            if (result) {\n              updateDepositHash(txInfo.hash, accAddress, result.status ? 'success' : 'failed')\n            }\n          })\n          flag = true\n        }\n      })\n      if (flag) {\n        setTryCheckL2BalanceTimes(20)\n        let wait = 60000\n        if (\n          account.readyState &&\n          [AccountStatus.DEPOSITING, AccountStatus.NOT_ACTIVE].includes(\n            // @ts-ignore\n            account?.readyState,\n          )\n        ) {\n          wait = 30000\n        }\n        nodeTimer.current = setTimeout(() => {\n          updateDepositStatus()\n        }, wait)\n        updateWalletLayer2()\n      } else {\n        setTryCheckL2BalanceTimes((state) => {\n          if (state > 0) {\n            updateWalletLayer2()\n            nodeTimer.current = setTimeout(() => {\n              updateDepositStatus()\n            }, 10000)\n          }\n          return state - 1\n        })\n      }\n    }\n  }, [account, chainId, updateDepositHash, updateWalletLayer2, nodeTimer, tryCheckL2BalanceTimes])\n  React.useEffect(() => {\n    if (chainInfos?.depositHashes && chainInfos?.depositHashes[account.accAddress]) {\n      updateDepositStatus()\n    }\n    return () => {\n      clearTimeout(nodeTimer.current as NodeJS.Timeout)\n    }\n  }, [account.accAddress, chainInfos?.depositHashes])\n  const { setShowLayerSwapNotice, setShowAnotherNetworkNotice } = useOpenModals()\n\n  const disbaleList = account.isInCounterFactualStatus ? [AddAssetList.FromMyL1.key] : undefined\n\n  const addAssetList: AddAssetItem[] = React.useMemo(\n    () =>\n      AddAssetListMap[network].map((item: string) => {\n        switch (item) {\n          case AddAssetList.BuyWithCard.key:\n            return {\n              ...AddAssetList.BuyWithCard,\n              handleSelect: () => {\n                setShowAccount({ isShow: true, step: AccountStep.PayWithCard })\n              },\n            }\n          case AddAssetList.FromMyL1.key:\n            return {\n              ...AddAssetList.FromMyL1,\n              handleSelect: () => {\n                setShowAccount({\n                  isShow: false,\n                  info: { lastFailed: undefined },\n                })\n                if (isShowAccount?.info?.symbol) {\n                  resetDepositData()\n                }\n                setShowDeposit({\n                  isShow: true,\n                  symbol: isShowAccount?.info?.symbol,\n                })\n              },\n            }\n          case AddAssetList.FromOtherL1.key:\n            return {\n              ...AddAssetList.FromOtherL1,\n              handleSelect: () => {\n                let dex = 'labelAddAssetTitleBridgeDes'\n                if (\n                  account.readyState &&\n                  [\n                    AccountStatus.DEPOSITING,\n                    AccountStatus.NOT_ACTIVE,\n                    AccountStatus.NO_ACCOUNT,\n                  ].includes(\n                    // @ts-ignore\n                    account?.readyState,\n                  )\n                ) {\n                  dex = 'labelAddAssetTitleBridgeDesActive'\n                }\n                setShowAccount({\n                  isShow: true,\n                  step: AccountStep.ThirdPanelReturn,\n                  info: {\n                    title: t('labelAddAssetTitleBridge', {\n                      loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                      l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                      l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                      ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                      loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n                    }),\n                    description: t(dex, {\n                      loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                      l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                      l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                      ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                      loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n                    }),\n                  },\n                })\n\n                window.open(\n                  Bridge +\n                    `?l2account=${account.accAddress}&token=${\n                      isShowAccount?.info?.symbol ?? ''\n                    }&__trace_isSharedBy=loopringExchange`,\n                )\n                window.opener = null\n              },\n            }\n          case AddAssetList.FromOtherL2.key:\n            return {\n              ...AddAssetList.FromOtherL2,\n              handleSelect: () => {\n                setShowAccount({\n                  isShow: true,\n                  step: AccountStep.QRCode,\n                  info: { backTo: AccountStep.AddAssetGateway },\n                })\n              },\n            }\n          case AddAssetList.FromExchange.key:\n            return {\n              ...AddAssetList.FromExchange,\n              handleSelect: () => {\n                let dex = 'labelAddAssetTitleExchangeDes'\n                if (\n                  account.readyState &&\n                  [\n                    AccountStatus.DEPOSITING,\n                    AccountStatus.NOT_ACTIVE,\n                    AccountStatus.NO_ACCOUNT,\n                  ].includes(\n                    // @ts-ignore\n                    account?.readyState,\n                  )\n                ) {\n                  dex = 'labelAddAssetTitleExchangeDesActive'\n                }\n                setShowAccount({\n                  isShow: true,\n                  step: AccountStep.ThirdPanelReturn,\n                  info: {\n                    title: t('labelAddAssetTitleExchange'),\n                    description: t(dex, {\n                      loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                      l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                      l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                      ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                      loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n                    }),\n                  },\n                })\n                setShowLayerSwapNotice({ isShow: true })\n              },\n            }\n          case AddAssetList.FromAnotherNet.key:\n            return {\n              ...AddAssetList.FromAnotherNet,\n              handleSelect: () => {\n                let dex = 'labelAddAssetTitleAnotherNetDes'\n                if (\n                  account.readyState &&\n                  [\n                    AccountStatus.DEPOSITING,\n                    AccountStatus.NOT_ACTIVE,\n                    AccountStatus.NO_ACCOUNT,\n                  ].includes(\n                    // @ts-ignore\n                    account?.readyState,\n                  )\n                ) {\n                  dex = 'labelAddAssetTitleAnotherNetDesActive'\n                }\n                setShowAccount({\n                  isShow: true,\n                  step: AccountStep.ThirdPanelReturn,\n                  info: {\n                    title: t('labelFromAnotherNet'),\n                    description: t(dex, {\n                      loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                      l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                      l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                      ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                      loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n                    }),\n                  },\n                })\n                setShowAnotherNetworkNotice({\n                  isShow: true,\n                  info: { url: 'https://www.orbiter.finance/?source=Ethereum&dest=Loopring' },\n                })\n              },\n            }\n        }\n\n        // .\n      }),\n    [\n      network,\n      account.accAddress,\n      isShowAccount?.info?.symbol,\n      setShowAccount,\n      setShowDeposit,\n      setShowLayerSwapNotice,\n    ],\n  )\n\n  const { toggle } = useToggle()\n  const { fastWithdrawConfig } = useConfig()\n  const { idIndex } = useTokenMap()\n\n  const sendAssetList: SendAssetItem[] = React.useMemo(\n    () =>\n      SendAssetListMap[network].filter(item => {\n        if (item === SendAssetList.SendAssetToTaikoAccount.key) {\n          // console.log('isShowAccount?.info', isShowAccount?)\n          const parsed = parseRabbitConfig(fastWithdrawConfig, network, idIndex)\n          return (\n            !isShowAccount?.info?.hideSendToTaiko &&\n            toggle.rabbitWithdraw.enable &&\n            parsed.toTaikoNetwork === 'TAIKO' &&\n            (isShowAccount?.info?.symbol\n              ? parsed.toTaikoNetworkSupportedTokens?.includes(isShowAccount.info.symbol)\n              : true)\n          )\n        } else {\n          return true\n        }\n      }).map((item: string) => {\n        switch (item) {\n          case SendAssetList.SendAssetToL2.key:\n            return {\n              ...SendAssetList.SendAssetToL2,\n              handleSelect: () => {\n                setShowAccount({\n                  isShow: false,\n                  info: { lastFailed: undefined },\n                })\n                if (isShowAccount?.info?.symbol) {\n                  resetTransferData()\n                }\n                setShowTransfer({\n                  isShow: true,\n                  symbol: isShowAccount?.info?.symbol,\n                })\n              },\n            }\n          case SendAssetList.SendAssetToMyL1.key:\n            return {\n              ...SendAssetList.SendAssetToMyL1,\n              handleSelect: () => {\n                setShowAccount({\n                  isShow: false,\n                  info: { lastFailed: undefined },\n                })\n                if (isShowAccount?.info?.symbol) {\n                  resetWithdrawData()\n                }\n                setShowWithdraw({\n                  isShow: true,\n                  info: { isToMyself: true },\n                  symbol: isShowAccount?.info?.symbol,\n                })\n              },\n            }\n          case SendAssetList.SendAssetToOtherL1.key:\n            return {\n              ...SendAssetList.SendAssetToOtherL1,\n              handleSelect: () => {\n                setShowAccount({\n                  isShow: false,\n                  info: { lastFailed: undefined },\n                })\n                if (isShowAccount?.info?.symbol) {\n                  resetWithdrawData()\n                }\n                setShowWithdraw({\n                  isShow: true,\n                  info: { isToMyself: false },\n                  symbol: isShowAccount?.info?.symbol,\n                })\n              },\n            }\n          case SendAssetList.SendAssetToAnotherNet.key:\n            return {\n              ...SendAssetList.SendAssetToAnotherNet,\n              handleSelect: () => {\n                setShowAccount({\n                  isShow: false,\n                })\n                setShowAnotherNetworkNotice({\n                  isShow: true,\n                  info: { url: 'https://www.orbiter.finance/?source=Loopring&dest=Ethereum' },\n                })\n                // window.open('https://www.orbiter.finance/?source=Loopring&dest=Ethereum')\n                // window.opener = null\n              },\n            }\n          case SendAssetList.SendAssetToTaikoAccount.key:\n            return {\n              ...SendAssetList.SendAssetToTaikoAccount,\n              handleSelect: () => {\n                setShowAccount({\n                  isShow: false,\n                  info: { lastFailed: undefined },\n                })\n                setShowTransferToTaikoAccount({\n                  isShow: true,\n                  from: 'send'\n                })\n              },\n            }\n        }\n      }),\n    [network, isShowAccount?.info?.symbol, setShowAccount, setShowTransfer, setShowWithdraw, toggle.rabbitWithdraw.enable, fastWithdrawConfig],\n  )\n  const sendNFTAssetList: SendAssetItem[] = React.useMemo(\n    () => [\n      {\n        ...SendNFTAssetList.SendAssetToL2,\n        handleSelect: (_e) => {\n          setShowAccount({ isShow: false })\n          setShowNFTTransfer({\n            isShow: true,\n          })\n        },\n      },\n      {\n        ...SendNFTAssetList.SendAssetToMyL1,\n        handleSelect: () => {\n          setShowAccount({ isShow: false })\n          setShowNFTWithdraw({\n            isShow: true,\n            info: { isToMyself: true, lastFailed: undefined },\n          })\n        },\n      },\n      {\n        ...SendNFTAssetList.SendAssetToOtherL1,\n        handleSelect: () => {\n          setShowAccount({\n            isShow: false,\n          })\n          setShowNFTWithdraw({\n            isShow: true,\n            info: { isToMyself: false, lastFailed: undefined },\n          })\n        },\n      },\n    ],\n    [setShowAccount, setShowNFTTransfer, setShowNFTWithdraw],\n  )\n  const onBackReceive = React.useCallback(() => {\n    setShowAccount({\n      isShow: true,\n      step: AccountStep.AddAssetGateway,\n      info: { ...isShowAccount?.info },\n    })\n  }, [isShowAccount?.info, setShowAccount])\n  const onBackSend = React.useCallback(() => {\n    setShowAccount({\n      isShow: true,\n      step: AccountStep.SendAssetGateway,\n      info: { ...isShowAccount?.info },\n    })\n  }, [isShowAccount?.info, setShowAccount])\n\n  const { checkActiveStatusProps } = useCheckActiveStatus<FeeInfo>({\n    setToastOpen: (info: TOASTOPEN) => setShowGlobalToast({ isShow: info.open, info: { ...info } }),\n    onDisconnect,\n    isDepositing: !!chainInfos?.depositHashes[account?.accAddress]?.length,\n    chargeFeeTokenList: activeAccountProps.chargeFeeTokenList as FeeInfo[],\n    checkFeeIsEnough: activeAccountCheckFeeIsEnough,\n    isFeeNotEnough: activeAccountProps.isFeeNotEnough,\n  })\n  const isEarn = app === 'earn'\n  const isTaiko = [sdk.ChainId.TAIKO, sdk.ChainId.TAIKOHEKLA].includes(defaultNetwork)\n\n  const accountList = React.useMemo(() => {\n    // const isShowAccount?.info.\n    return Object.values({\n      [AccountStep.ContinuousBanxaOrder]: {\n        view: (\n          <ContinuousBanxaOrder\n            title={t('labelBanxaTitleCreateAgain')}\n            btnInfo={{\n              isLoading: isShowAccount?.info?.isBanxaLaunchLoading,\n              callback: () => {\n                setShouldShow(false)\n                setShowAccount({ isShow: false })\n              },\n              btnTxt: t('labelBanxaContinuous'),\n            }}\n            orderId={isShowAccount?.info?.orderId}\n            chainId={chainId as any}\n            btnInfo2={{\n              isLoading: isShowAccount?.info?.isBanxaLaunchLoading,\n              callback: () => {\n                setShowAccount({ isShow: false })\n                offFaitService.offRampCancel({\n                  data: {\n                    product: VendorProviders.Banxa,\n                    orderId: isShowAccount?.info?.orderId,\n                  },\n                })\n                banxaService.banxaStart(true)\n              },\n              btnTxt: t('labelBanxaCreate'),\n            }}\n          />\n        ),\n        height: 'auto',\n        onClose: () => {\n          banxaService.banxaEnd({\n            reason: OrderENDReason.UserCancel,\n            data: { resource: 'on close' },\n          })\n        },\n      },\n      [AccountStep.ThirdPanelReturn]: {\n        view: (\n          <ThirdPanelReturn\n            title={isShowAccount?.info?.title ?? ''}\n            description={isShowAccount?.info?.description}\n            btnInfo={{\n              ...closeBtnInfo(),\n              btnTxt: isShowAccount?.info?.btnTxt ?? t('labelIKnow2'),\n            }}\n          />\n        ),\n        height: 'auto',\n      },\n      [AccountStep.CheckingActive]: {\n        view: (\n          <CheckActiveStatus\n            {...{\n              ...checkActiveStatusProps,\n              updateDepositHash,\n              chainInfos,\n              clearDepositHash: clearDeposit,\n              ...account,\n              etherscanUrl: rest.etherscanBaseUrl,\n            }}\n          />\n        ),\n        height: 'auto',\n      },\n      [AccountStep.AddAssetGateway]: {\n        height: 'auto',\n        view: (\n          <AddAsset\n            symbol={isShowAccount?.info?.symbol}\n            addAssetList={addAssetList}\n            allowTrade={allowTrade}\n            isNewAccount={depositProps.isNewAccount}\n            disbaleList={disbaleList}\n          />\n        ),\n      },\n      [AccountStep.SendAssetGateway]: {\n        view: (\n          <SendAsset\n            isToL1={isShowAccount?.info?.isToL1}\n            symbol={isShowAccount?.info?.symbol}\n            allowTrade={allowTrade}\n            sameLayerAssetList={sendAssetList.filter((item) => item.type === 'sameLayer')}\n            crossLayerAssetList={sendAssetList.filter((item) => item.type === 'crossLayer')}\n            crossChainAssetList={sendAssetList.filter((item) => item.type === 'crossChain')}\n            toL1Title={isTaiko ? 'To Taiko' : 'To Ethereum'}\n          />\n        ),\n        height: 'auto',\n      },\n      [AccountStep.SendAssetFromContact]: {\n        view: <SendFromContact {...(isShowAccount?.info as any)} />,\n      },\n      [AccountStep.SendNFTGateway]: {\n        view: (\n          <SendNFTAsset\n            nftData={{ ...isShowAccount?.info } as Partial<NFTWholeINFO>}\n            sendAssetList={sendNFTAssetList}\n            allowTrade={allowTrade}\n            isNotAllowToL1={account.isContract1XAddress}\n          />\n        ),\n      },\n      [AccountStep.PayWithCard]: {\n        view: (\n          <VendorMenu\n            vendorList={vendorListBuy}\n            banxaRef={banxaRef}\n            type={TradeTypes.Buy}\n            vendorForce={undefined}\n            campaignTagConfig={campaignTagConfig}\n          />\n        ),\n        onBack: onBackReceive,\n      },\n      [AccountStep.NoAccount]: {\n        view: (\n          <NoAccount\n            {...{\n              goActiveAccount,\n              chainInfos,\n              // isSupport,\n              noButton: isLayer1Only,\n              onClose: (_e: any) => {\n                setShouldShow(false)\n                setShowAccount({ isShow: false })\n              },\n              updateDepositHash,\n              clearDepositHash: clearDeposit,\n              ...account,\n              etherscanUrl: rest.etherscanBaseUrl,\n              onSwitch,\n              onCopy,\n              onViewQRCode,\n              onDisconnect,\n              addressShort,\n            }}\n          />\n        ),\n        onQRClick,\n        height: isLayer1Only ? 'auto' : null,\n      },\n      [AccountStep.HadAccount]: {\n        view: (\n          <HadAccount\n            {...{\n              ...account,\n              clearDepositHash: clearDeposit,\n              chainInfos,\n              noButton: isLayer1Only,\n              onSwitch,\n              onCopy,\n              onClose: (_e: any) => {\n                setShouldShow(false)\n                setShowAccount({ isShow: false })\n              },\n              etherscanUrl: rest.etherscanBaseUrl,\n              onViewQRCode,\n              onDisconnect,\n              addressShort,\n              etherscanLink: rest.etherscanBaseUrl + 'address/' + account.accAddress,\n              mainBtn: account.readyState === AccountStatus.ACTIVATED ? lockBtn : unlockBtn,\n              hideVIPlevel: isWebEarn ? true : false,\n            }}\n          />\n        ),\n        onQRClick,\n        height: isLayer1Only ? 'auto' : null,\n      },\n      [AccountStep.QRCodeScanner]: {\n        view: <ImportRedPacket {...redPacketScanQrcodeSuccessProps} />,\n        onBack: () => {\n          setShowAccount({ isShow: false })\n        },\n        height: 'auto',\n      },\n      [AccountStep.QRCode]: {\n        view: (\n          <QRAddressPanel\n            {...{\n              ...rest,\n              account,\n              btnInfo: {\n                ...closeBtnInfo(),\n                btnTxt: isShowAccount?.info?.btnTxt ?? t('labelIKnow2'),\n              } as any,\n              ...account,\n              isNewAccount: depositProps.isNewAccount,\n              isForL2Send: isShowAccount.info?.backTo === AccountStep.AddAssetGateway,\n              etherscanUrl: rest.etherscanBaseUrl,\n              t,\n            }}\n          />\n        ),\n        onBack: onQRBack,\n        noClose: true,\n        height: 'auto',\n      },\n      [AccountStep.Deposit_Sign_WaitForRefer]: {\n        view: (\n          <Deposit_Sign_WaitForRefer\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n            title={isEarn ? 'labelDeposit' : 'labelL1toL2'}\n          />\n        ),\n      },\n      [AccountStep.Deposit_Approve_WaitForAuth]: {\n        view: (\n          <Deposit_Approve_WaitForAuth\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n            title={isEarn ? 'labelDeposit' : 'labelL1toL2'}\n          />\n        ),\n      },\n      [AccountStep.Deposit_Approve_Denied]: {\n        view: (\n          <Deposit_Approve_Denied\n            btnInfo={{\n              btnTxt: 'labelRetry',\n              callback: () => {\n                depositServices.depositERC20()\n              },\n            }}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n            title={isEarn ? 'labelDeposit' : 'labelL1toL2'}\n          />\n        ),\n        onBack: () => {\n          setShowAccount({ isShow: false })\n        },\n      },\n      [AccountStep.Deposit_WaitForAuth]: {\n        view: (\n          <Deposit_WaitForAuth\n            symbol={depositProps.tradeData.belong}\n            value={depositProps.tradeData.tradeValue}\n            chainInfos={chainInfos}\n            updateDepositHash={updateDepositHash}\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n            title={isEarn ? 'labelDeposit' : 'labelL1toL2'}\n          />\n        ),\n        onBack: () => {\n          setShowAccount({ isShow: false })\n        },\n      },\n      [AccountStep.Deposit_Denied]: {\n        view: (\n          <Deposit_Denied\n            btnInfo={{\n              btnTxt: 'labelRetry',\n              callback: () => {\n                depositServices.depositERC20()\n              },\n            }}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n            title={isEarn ? 'labelDeposit' : 'labelL1toL2'}\n          />\n        ),\n        onBack: () => {\n          setShowAccount({ isShow: false })\n        },\n      },\n      [AccountStep.Deposit_Failed]: {\n        view: (\n          <Deposit_Failed\n            btnInfo={closeBtnInfo({\n              closeExtend: () => {\n                setShowAccount({\n                  ...isShowAccount,\n                  isShow: false,\n                  info: {\n                    ...isShowAccount.info,\n                    lastFailed: LAST_STEP.deposit,\n                  },\n                })\n              },\n            })}\n            {...{\n              ...rest,\n              account,\n              error: isShowAccount.error,\n              t,\n            }}\n            title={isEarn ? 'labelDeposit' : 'labelL1toL2'}\n          />\n        ),\n        onBack: !depositProps.isAllowInputToAddress\n          ? () => {\n              setShowAccount({ isShow: false })\n              setShowDeposit({ isShow: true })\n            }\n          : undefined,\n      },\n      [AccountStep.Deposit_Submit]: {\n        view: (\n          <Deposit_Submit\n            btnInfo={{\n              btnTxt: 'labelDoAgain',\n              param: {\n                method: t('labelDepositL1', {\n                  loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                  l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                  l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                  ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                  loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n                }),\n              },\n              callback: () => {\n                setShowAccount({ isShow: false })\n                setShowDeposit({\n                  isShow: true,\n                  symbol: (rest as any)?.symbol ?? isShowAccount?.info?.symbol ?? 'LRC',\n                })\n              },\n            }}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n            title={isEarn ? 'labelDeposit' : 'labelL1toL2'}\n          />\n        ),\n      },\n      [AccountStep.NFTDeposit_Approve_WaitForAuth]: {\n        view: (\n          <NFTDeposit_Approve_WaitForAuth\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              account,\n              ...nftDepositValue,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.NFTDeposit_Approve_Denied]: {\n        view: (\n          <NFTDeposit_Approve_Denied\n            btnInfo={{\n              btnTxt: 'labelRetry',\n              callback: () => {\n                depositServices.depositNFT()\n                // setShowAccount({ isShow: false });\n              },\n            }}\n            {...{\n              ...rest,\n              account,\n              ...nftDepositValue,\n              t,\n            }}\n          />\n        ),\n        onBack: () => {\n          setShowAccount({ isShow: false })\n        },\n      },\n\n      [AccountStep.NFTDeposit_WaitForAuth]: {\n        view: (\n          <NFTDeposit_WaitForAuth\n            symbol={nftDepositValue.name}\n            value={nftDepositValue.tradeValue}\n            chainInfos={chainInfos}\n            updateDepositHash={updateDepositHash}\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              account,\n              ...nftDepositValue,\n              t,\n            }}\n          />\n        ),\n        onBack: () => {\n          setShowAccount({ isShow: false })\n        },\n      },\n      [AccountStep.NFTDeposit_Denied]: {\n        view: (\n          <NFTDeposit_Denied\n            btnInfo={{\n              btnTxt: 'labelRetry',\n              callback: () => {\n                depositServices.depositNFT()\n              },\n            }}\n            {...{\n              ...rest,\n              account,\n              ...nftDepositValue,\n              t,\n            }}\n          />\n        ),\n        onBack: () => {\n          setShowAccount({ isShow: false })\n        },\n      },\n      [AccountStep.NFTDeposit_Failed]: {\n        view: (\n          <NFTDeposit_Failed\n            btnInfo={closeBtnInfo({\n              closeExtend: () => {\n                setShowAccount({\n                  ...isShowAccount,\n                  isShow: false,\n                  info: {\n                    ...isShowAccount.info,\n                    lastFailed: LAST_STEP.nftDeposit,\n                  },\n                })\n              },\n            })}\n            {...{\n              ...rest,\n              account,\n              ...nftDepositValue,\n              error: isShowAccount.error,\n              t,\n            }}\n          />\n        ),\n        onBack: () => {\n          setShowAccount({ isShow: false })\n        },\n      },\n      [AccountStep.NFTDeposit_Submit]: {\n        view: (\n          <NFTDeposit_Submit\n            btnInfo={{\n              btnTxt: 'labelDoAgain',\n              param: {\n                method: t('labelDepositNFTL1', {\n                  loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                  l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                  l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                  ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                  loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n                }),\n              },\n              callback: () => {\n                setShowAccount({ isShow: false })\n                history.push(`${RouterPath.nft}/${NFTSubRouter.depositNFT}`)\n              },\n            }}\n            {...{\n              ...rest,\n              account,\n              ...nftDepositValue,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.NFTMint_WaitForAuth]: {\n        view: (\n          <NFTMint_WaitForAuth\n            symbol={isShowAccount.info?.name}\n            value={isShowAccount.info?.value}\n            chainInfos={chainInfos}\n            updateDepositHash={updateDepositHash}\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n        onBack: () => {\n          setShowAccount({ isShow: false })\n        },\n      },\n      [AccountStep.NFTMint_Denied]: {\n        view: (\n          <NFTMint_Denied\n            symbol={isShowAccount.info?.name}\n            value={isShowAccount.info?.value}\n            btnInfo={{\n              btnTxt: 'labelRetry',\n              callback: () => {\n                if (isShowAccount.info?.isAdvanceMint) {\n                  nftMintAdvanceRetryBtn()\n                } else {\n                  mintService.goMintConfirm()\n                }\n              },\n            }}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n        onBack: () => {\n          setShowAccount({ isShow: false })\n        },\n      },\n      [AccountStep.NFTMint_First_Method_Denied]: {\n        view: (\n          <NFTMint_First_Method_Denied\n            btnInfo={{\n              btnTxt: 'labelTryAnother',\n              callback: () => {\n                if (isShowAccount.info?.isAdvanceMint) {\n                  nftMintAdvanceRetryBtn(true)\n                } else {\n                  mintService.goMintConfirm(true)\n                }\n              },\n            }}\n            symbol={isShowAccount.info?.name}\n            value={isShowAccount.info?.value}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.NFTMint_In_Progress]: {\n        view: (\n          <NFTMint_In_Progress\n            symbol={isShowAccount.info?.name}\n            value={isShowAccount.info?.value}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.NFTMint_Failed]: {\n        view: (\n          <NFTMint_Failed\n            btnInfo={closeBtnInfo()}\n            symbol={isShowAccount.info?.name}\n            value={isShowAccount.info?.value}\n            {...{\n              ...rest,\n              account,\n              error: isShowAccount.error,\n              t,\n            }}\n          />\n        ),\n        onBack: () => {\n          setShowAccount({ isShow: false })\n        },\n      },\n      [AccountStep.NFTMint_Success]: {\n        view: (\n          <NFTMint_Success\n            // btnInfo={closeBtnInfo}\n            btnInfo={{\n              btnTxt: 'labelDoAgain',\n              param: { method: t('labelMintNFT') },\n              callback: () => {\n                setShowAccount({ isShow: false })\n                if (isShowAccount.info?.lastStep === LAST_STEP.nftMint) {\n                  history.push(\n                    `${RouterPath.nft}/${NFTSubRouter.mintNFT}/${isShowAccount.info?.collection?.contractAddress}`,\n                  )\n                } else {\n                  history.push(`${RouterPath.nft}/${NFTSubRouter.mintNFTAdvance}`)\n                }\n              },\n            }}\n            symbol={isShowAccount.info?.name}\n            value={isShowAccount.info?.value}\n            {...{\n              t,\n              ...rest,\n              account,\n              link: isShowAccount?.info?.hash\n                ? {\n                    name: 'Txn Hash',\n                    url: isShowAccount?.info?.hash,\n                  }\n                : undefined,\n            }}\n          />\n        ),\n      },\n\n      [AccountStep.RedPacketSend_WaitForAuth]: {\n        view: (\n          <RedPacketSend_WaitForAuth\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n        onBack: () => {\n          setShowAccount({ isShow: false })\n        },\n      },\n\n      [AccountStep.RedPacketSend_First_Method_Denied]: {\n        view: (\n          <RedPacketSend_First_Method_Denied\n            btnInfo={{\n              btnTxt: 'labelRetry',\n              callback: () => {\n                creatRedPacketRetryBtn(true)\n              },\n            }}\n            {...{\n              ...rest,\n              account,\n              ...nftDeployValue,\n              t,\n            }}\n          />\n        ),\n        onBack: () => {\n          setShowAccount({ isShow: false })\n        },\n      },\n\n      [AccountStep.RedPacketSend_In_Progress]: {\n        view: (\n          <RedPacketSend_In_Progress\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n\n      [AccountStep.RedPacketSend_User_Denied]: {\n        view: (\n          <RedPacketSend_User_Denied\n            btnInfo={{\n              btnTxt: 'labelRetry',\n              callback: () => {\n                creatRedPacketRetryBtn()\n              },\n            }}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n\n      [AccountStep.RedPacketSend_Failed]: {\n        view: (\n          <RedPacketSend_Failed\n            btnInfo={closeBtnInfo()}\n            {...{\n              ...rest,\n              account,\n              error: isShowAccount.error,\n              info: {\n                ...isShowAccount.info,\n                lastFailed: LAST_STEP.redPacketSend,\n              },\n              t,\n            }}\n          />\n        ),\n        onBack: () => {\n          setShowAccount({ isShow: false })\n        },\n      },\n\n      [AccountStep.RedPacketSend_Success]: {\n        view: (\n          <RedPacketSend_Success\n            btnInfo={closeBtnInfo()}\n            {...{\n              ...rest,\n              account,\n              info: {\n                ...isShowAccount.info,\n              },\n              t,\n            }}\n          />\n        ),\n        onBack: () => {\n          setShowAccount({ isShow: false })\n        },\n      },\n\n      [AccountStep.RedPacketOpen_In_Progress]: {\n        view: (\n          <RedPacketOpen_In_Progress\n            btnInfo={undefined}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n\n      [AccountStep.RedPacketOpen_Failed]: {\n        view: (\n          <RedPacketOpen_Failed\n            btnInfo={closeBtnInfo()}\n            {...{\n              ...rest,\n              account,\n              error: isShowAccount.error,\n              t,\n            }}\n          />\n        ),\n        onBack: () => {\n          setShowAccount({ isShow: false })\n        },\n      },\n\n      [AccountStep.RedPacketOpen_Claim_In_Progress]: {\n        view: (\n          <RedPacketOpen_Claim_In_Progress\n            btnInfo={closeBtnInfo()}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n        onBack: () => {\n          setShowAccount({ isShow: false })\n        },\n      },\n\n      [AccountStep.RedPacketSend_Claim_Success]: {\n        view: (\n          <RedPacketSend_Claim_Success\n            btnInfo={closeBtnInfo()}\n            {...{\n              ...rest,\n              account,\n              error: isShowAccount.error,\n              t,\n            }}\n          />\n        ),\n        onBack: () => {\n          setShowAccount({ isShow: false })\n        },\n      },\n      [AccountStep.RedPacketOpen_Claim_Failed]: {\n        view: (\n          <RedPacketOpen_Claim_Failed\n            btnInfo={closeBtnInfo()}\n            {...{\n              ...rest,\n              account,\n              error: isShowAccount.error,\n              t,\n            }}\n          />\n        ),\n        onBack: () => {\n          setShowAccount({ isShow: false })\n        },\n      },\n\n      [AccountStep.NFTDeploy_WaitForAuth]: {\n        view: (\n          <NFTDeploy_WaitForAuth\n            symbol={nftDeployValue.name}\n            value={nftDeployValue.tradeValue}\n            chainInfos={chainInfos}\n            updateDepositHash={updateDepositHash}\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              account,\n              ...nftDeployValue,\n              t,\n            }}\n          />\n        ),\n        onBack: () => {\n          setShowAccount({ isShow: false })\n        },\n      },\n      [AccountStep.NFTDeploy_Denied]: {\n        view: (\n          <NFTDeploy_Denied\n            btnInfo={{\n              btnTxt: 'labelRetry',\n              callback: () => {\n                nftDeployProps.onNFTDeployClick(nftDeployValue as any)\n              },\n            }}\n            {...{\n              ...rest,\n              account,\n              ...nftDeployValue,\n              t,\n            }}\n          />\n        ),\n        onBack: () => {\n          setShowAccount({ isShow: false })\n        },\n      },\n      [AccountStep.NFTDeploy_First_Method_Denied]: {\n        view: (\n          <NFTDeploy_First_Method_Denied\n            btnInfo={{\n              btnTxt: 'labelTryAnother',\n              callback: () => {\n                nftDeployProps.onNFTDeployClick(nftDeployValue as any, false)\n              },\n            }}\n            {...{\n              ...rest,\n              account,\n              ...nftDeployValue,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.NFTDeploy_In_Progress]: {\n        view: (\n          <NFTDeploy_In_Progress\n            {...{\n              ...rest,\n              account,\n              ...nftDeployValue,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.NFTDeploy_Failed]: {\n        view: (\n          <NFTDeploy_Failed\n            btnInfo={closeBtnInfo()}\n            {...{\n              ...rest,\n              account,\n              ...nftDeployValue,\n              error: isShowAccount.error,\n              t,\n            }}\n          />\n        ),\n        onBack: () => {\n          setShowAccount({ isShow: false })\n        },\n      },\n      [AccountStep.NFTDeploy_Submit]: {\n        view: (\n          <NFTDeploy_Submit\n            btnInfo={closeBtnInfo()}\n            {...{\n              ...rest,\n              account,\n              ...nftDeployValue,\n              t,\n            }}\n          />\n        ),\n        onBack: () => {\n          setShowAccount({ isShow: false })\n        },\n      },\n\n      [AccountStep.ForceWithdraw_WaitForAuth]: {\n        view: (\n          <ForceWithdraw_WaitForAuth\n            symbol={forceWithdrawValue.belong}\n            value={forceWithdrawValue.tradeValue}\n            chainInfos={chainInfos}\n            updateDepositHash={updateDepositHash}\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              account,\n              ...forceWithdrawValue,\n              t,\n            }}\n          />\n        ),\n        // onBack: () => {\n        //   setShowAccount({ isShow: false });\n        // },\n      },\n      [AccountStep.ForceWithdraw_Denied]: {\n        view: (\n          <ForceWithdraw_Denied\n            btnInfo={{\n              btnTxt: 'labelRetry',\n              callback: () => {\n                forceWithdrawRetry()\n              },\n            }}\n            {...{\n              ...rest,\n              account,\n              ...forceWithdrawValue,\n              t,\n            }}\n          />\n        ),\n        // onBack: () => {\n        //   setShowAccount({ isShow: false });\n        // },\n      },\n      [AccountStep.ForceWithdraw_First_Method_Denied]: {\n        view: (\n          <ForceWithdraw_First_Method_Denied\n            btnInfo={{\n              btnTxt: 'labelTryAnother',\n              callback: () => {\n                // setShowAccount({ isShow: false });\n                forceWithdrawRetry(true)\n              },\n            }}\n            {...{\n              ...rest,\n              account,\n              ...forceWithdrawValue,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.ForceWithdraw_In_Progress]: {\n        view: (\n          <ForceWithdraw_In_Progress\n            {...{\n              ...rest,\n              account,\n              ...forceWithdrawValue,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.ForceWithdraw_Failed]: {\n        view: (\n          <ForceWithdraw_Failed\n            btnInfo={closeBtnInfo({\n              closeExtend: () => {\n                setShowAccount({\n                  ...isShowAccount,\n                  isShow: false,\n                  info: {\n                    ...isShowAccount.info,\n                    lastFailed: LAST_STEP.forceWithdraw,\n                  },\n                })\n              },\n            })}\n            {...{\n              ...rest,\n              account,\n              ...forceWithdrawValue,\n              error: isShowAccount.error,\n              t,\n            }}\n          />\n        ),\n        // onBack: () => {\n        //   setShowAccount({ isShow: false });\n        // },\n      },\n      [AccountStep.ForceWithdraw_Submit]: {\n        view: (\n          <ForceWithdraw_Submit\n            btnInfo={closeBtnInfo()}\n            {...{\n              ...rest,\n              account,\n              ...forceWithdrawValue,\n              t,\n            }}\n          />\n        ),\n      },\n\n      // ClaimWithdraw\n      [AccountStep.ClaimWithdraw_WaitForAuth]: {\n        view: (\n          <ClaimWithdraw_WaitForAuth\n            symbol={claimValue?.belong}\n            value={claimValue?.tradeValue}\n            chainInfos={chainInfos}\n            // updateDepositHash={updateDepositHash}\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              account,\n              ...claimValue,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.ClaimWithdraw_Denied]: {\n        view: (\n          <ClaimWithdraw_Denied\n            btnInfo={{\n              btnTxt: 'labelRetry',\n              callback: () => {\n                claimRetryBtn()\n              },\n            }}\n            {...{\n              ...rest,\n              account,\n              ...claimValue,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.ClaimWithdraw_First_Method_Denied]: {\n        view: (\n          <ClaimWithdraw_First_Method_Denied\n            btnInfo={{\n              btnTxt: 'labelTryAnother',\n              callback: () => {\n                claimRetryBtn(true)\n              },\n            }}\n            {...{\n              ...rest,\n              account,\n              ...claimValue,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.ClaimWithdraw_In_Progress]: {\n        view: (\n          <ClaimWithdraw_In_Progress\n            {...{\n              ...rest,\n              account,\n              ...claimValue,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.ClaimWithdraw_Failed]: {\n        view: (\n          <ClaimWithdraw_Failed\n            btnInfo={closeBtnInfo({\n              closeExtend: () => {\n                setShowAccount({\n                  ...isShowAccount,\n                  isShow: false,\n                  info: {\n                    ...isShowAccount.info,\n                    lastFailed: LAST_STEP.claim,\n                  },\n                })\n              },\n            })}\n            {...{\n              ...rest,\n              account,\n              ...claimValue,\n              error: isShowAccount.error,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.ClaimWithdraw_Submit]: {\n        view: (\n          <ClaimWithdraw_Submit\n            btnInfo={closeBtnInfo()}\n            {...{\n              ...rest,\n              account,\n              ...claimValue,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.General_Failed]: {\n        view: <General_Failed t={t} {...rest} />,\n      },\n      // transfer\n      [AccountStep.Transfer_WaitForAuth]: {\n        view: (\n          <Transfer_WaitForAuth\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.Transfer_First_Method_Denied]: {\n        view: (\n          <Transfer_First_Method_Denied\n            btnInfo={{\n              btnTxt: 'labelTryAnother',\n              callback: () => {\n                transferProps.onTransferClick(transferValue as any, false)\n              },\n            }}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.Transfer_User_Denied]: {\n        view: (\n          <Transfer_User_Denied\n            btnInfo={{\n              btnTxt: 'labelRetry',\n              callback: () => {\n                transferProps.onTransferClick(transferValue as any)\n              },\n            }}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.Transfer_In_Progress]: {\n        view: (\n          <Transfer_In_Progress\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.Transfer_Success]: {\n        view: (\n          <Transfer_Success\n            btnInfo={{\n              btnTxt: 'labelDoAgain',\n              param: {\n                method: t('labelL2ToL2Method', {\n                  loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                  l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                  l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                  symbol: isShowAccount?.info?.symbol,\n                }),\n              },\n              callback: () => {\n                setShowAccount({ isShow: false })\n                setShowTransfer({\n                  isShow: true,\n                  symbol: isShowAccount?.info?.symbol,\n                })\n              },\n            }}\n            {...{\n              ...rest,\n              account,\n              link: isShowAccount?.info?.hash\n                ? {\n                    name: 'Txn Hash',\n                    url: isShowAccount?.info?.hash,\n                  }\n                : undefined,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.Transfer_Failed]: {\n        view: (\n          <Transfer_Failed\n            btnInfo={closeBtnInfo({\n              closeExtend: () => {\n                setShowAccount({\n                  ...isShowAccount,\n                  isShow: false,\n                  info: {\n                    ...isShowAccount.info,\n                    lastFailed: LAST_STEP.transfer,\n                  },\n                })\n              },\n            })}\n            {...{\n              ...rest,\n              account,\n              error: isShowAccount.error,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.Transfer_RAMP_WaitForAuth]: {\n        view: (\n          <Transfer_WaitForAuth\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.Transfer_RAMP_First_Method_Denied]: {\n        view: (\n          <Transfer_First_Method_Denied\n            btnInfo={{\n              btnTxt: 'labelTryAnother',\n              callback: () => {\n                const { __request__ } = store.getState()._router_modalData.transferRampValue\n                if (__request__) {\n                  processRequestRampTransfer(__request__, false)\n                } else {\n                  setShowAccount({\n                    isShow: true,\n                    step: AccountStep.Transfer_RAMP_Failed,\n                  })\n                }\n              },\n            }}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.Transfer_RAMP_User_Denied]: {\n        view: (\n          <Transfer_User_Denied\n            btnInfo={{\n              btnTxt: 'labelRetry',\n              callback: () => {\n                const { __request__ } = store.getState()._router_modalData.transferRampValue\n                if (__request__) {\n                  processRequestRampTransfer(__request__, true)\n                } else {\n                  setShowAccount({\n                    isShow: true,\n                    step: AccountStep.Transfer_RAMP_Failed,\n                  })\n                }\n              },\n            }}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.Transfer_RAMP_In_Progress]: {\n        view: (\n          <Transfer_In_Progress\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.Transfer_RAMP_Success]: {\n        view: (\n          <Transfer_Success\n            btnInfo={closeBtnInfo()}\n            {...{\n              ...rest,\n              account,\n              link: isShowAccount?.info?.hash\n                ? {\n                    name: 'Txn Hash',\n                    url: isShowAccount?.info?.hash,\n                  }\n                : undefined,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.Transfer_RAMP_Failed]: {\n        view: (\n          <Transfer_Failed\n            btnInfo={closeBtnInfo()}\n            {...{\n              ...rest,\n              account,\n              error: isShowAccount.error,\n              t,\n            }}\n          />\n        ),\n      },\n\n      // transferBanxa\n      [AccountStep.Transfer_BANXA_WaitForAuth]: {\n        view: (\n          <Transfer_WaitForAuth\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.Transfer_BANXA_First_Method_Denied]: {\n        view: (\n          <Transfer_First_Method_Denied\n            btnInfo={{\n              btnTxt: 'labelTryAnother',\n              callback: () => {\n                const { __request__ } = store.getState()._router_modalData.transferBanxaValue\n                if (__request__) {\n                  processRequestRampTransfer(__request__, false)\n                } else {\n                  setShowAccount({\n                    isShow: true,\n                    step: AccountStep.Transfer_RAMP_Failed,\n                  })\n                }\n              },\n            }}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.Transfer_BANXA_User_Denied]: {\n        view: (\n          <Transfer_User_Denied\n            btnInfo={{\n              btnTxt: 'labelRetry',\n              callback: () => {\n                const { __request__ } = store.getState()._router_modalData.transferBanxaValue\n                if (__request__) {\n                  processRequestRampTransfer(__request__, true)\n                } else {\n                  setShowAccount({\n                    isShow: true,\n                    step: AccountStep.Transfer_RAMP_Failed,\n                  })\n                }\n              },\n            }}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.Transfer_BANXA_In_Progress]: {\n        view: (\n          <Transfer_In_Progress\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.Transfer_BANXA_Success]: {\n        view: (\n          <Transfer_Success\n            btnInfo={closeBtnInfo()}\n            {...{\n              ...rest,\n              account,\n              link: isShowAccount?.info?.hash\n                ? {\n                    name: 'Txn Hash',\n                    url: isShowAccount?.info?.hash,\n                  }\n                : undefined,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.Transfer_BANXA_Confirm]: {\n        view: (\n          <Transfer_banxa_confirm\n            btnInfo={closeBtnInfo()}\n            {...{\n              ...rest,\n              account,\n              info: { ...isShowAccount?.info },\n              link: isShowAccount?.info?.hash\n                ? {\n                    name: 'Banxa Status',\n                    url: isShowAccount?.info?.hash,\n                  }\n                : undefined,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.Transfer_BANXA_Failed]: {\n        view: (\n          <Transfer_Failed\n            btnInfo={closeBtnInfo()}\n            {...{\n              ...rest,\n              account,\n              error: isShowAccount.error,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.NFTBurn_WaitForAuth]: {\n        view: (\n          <NFTBurn_WaitForAuth\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.NFTBurn_First_Method_Denied]: {\n        view: (\n          <NFTBurn_First_Method_Denied\n            btnInfo={{\n              btnTxt: 'labelTryAnother',\n              callback: () => {\n                nftTransferProps.onTransferClick(nftTransferValue as any, false)\n              },\n            }}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.NFTBurn_User_Denied]: {\n        view: (\n          <NFTBurn_User_Denied\n            btnInfo={{\n              btnTxt: 'labelRetry',\n              callback: () => {\n                nftTransferProps.onTransferClick(nftTransferValue as any)\n              },\n            }}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.NFTBurn_In_Progress]: {\n        view: (\n          <NFTBurn_In_Progress\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.NFTBurn_Success]: {\n        view: (\n          <NFTBurn_Success\n            btnInfo={closeBtnInfo()}\n            {...{\n              ...rest,\n              account,\n              link: isShowAccount?.info?.hash\n                ? {\n                    name: 'Txn Hash',\n                    url: isShowAccount?.info?.hash,\n                  }\n                : undefined,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.NFTBurn_Failed]: {\n        view: (\n          <NFTBurn_Failed\n            btnInfo={closeBtnInfo({\n              closeExtend: () => {\n                setShowAccount({\n                  ...isShowAccount,\n                  isShow: false,\n                  info: {\n                    ...isShowAccount.info,\n                    lastFailed: LAST_STEP.nftTransfer,\n                  },\n                })\n              },\n            })}\n            {...{\n              ...rest,\n              account,\n              error: isShowAccount.error,\n              t,\n            }}\n          />\n        ),\n      },\n\n      // withdraw\n      [AccountStep.Withdraw_WaitForAuth]: {\n        view: (\n          <Withdraw_WaitForAuth\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.Withdraw_First_Method_Denied]: {\n        view: (\n          <Withdraw_First_Method_Denied\n            btnInfo={{\n              btnTxt: 'labelTryAnother',\n              callback: () => {\n                withdrawProps.onWithdrawClick(withdrawValue as any, false)\n              },\n            }}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.Withdraw_User_Denied]: {\n        view: (\n          <Withdraw_User_Denied\n            btnInfo={{\n              btnTxt: 'labelRetry',\n              callback: () => {\n                withdrawProps.onWithdrawClick(withdrawValue as any)\n              },\n            }}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.Withdraw_In_Progress]: {\n        view: (\n          <Withdraw_In_Progress\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.Withdraw_Success]: {\n        view: (\n          <Withdraw_Success\n            btnInfo={{\n              btnTxt: 'labelDoAgain',\n              param: {\n                method: t('labelL2ToL1Method', {\n                  symbol: isShowAccount?.info?.symbol,\n                  loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                  l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                  l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                  ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                  loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n                }),\n              },\n              callback: () => {\n                setShowAccount({ isShow: false })\n                setShowWithdraw({\n                  isShow: true,\n                  info: {\n                    isToMyself: isShowAccount?.info?.isToMyself ?? false,\n                    symbol: isShowAccount?.info?.symbol,\n                  },\n                  symbol: isShowAccount?.info?.symbol,\n                })\n              },\n            }}\n            {...{\n              ...rest,\n              account,\n              symbol: isShowAccount?.info?.symbol,\n              // value:isShowAccount?.info?.value,\n              link: isShowAccount?.info?.hash\n                ? {\n                    name: 'Txn Hash',\n                    url: isShowAccount?.info?.hash,\n                  }\n                : undefined,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.Withdraw_Failed]: {\n        view: (\n          <Withdraw_Failed\n            btnInfo={closeBtnInfo({\n              closeExtend: () => {\n                setShowAccount({\n                  ...isShowAccount,\n                  isShow: false,\n                  info: {\n                    ...isShowAccount.info,\n                    lastFailed: LAST_STEP.withdraw,\n                  },\n                })\n              },\n            })}\n            {...{\n              ...rest,\n              symbol: isShowAccount?.info?.symbol,\n              // value:isShowAccount?.info?.value,\n              account,\n              error: isShowAccount.error,\n              t,\n            }}\n          />\n        ),\n      },\n\n      // transfer\n      [AccountStep.NFTTransfer_WaitForAuth]: {\n        view: (\n          <NFTTransfer_WaitForAuth\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.NFTTransfer_First_Method_Denied]: {\n        view: (\n          <NFTTransfer_First_Method_Denied\n            btnInfo={{\n              btnTxt: 'labelTryAnother',\n              callback: () => {\n                nftTransferProps.onTransferClick(nftTransferValue as any, false)\n              },\n            }}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.NFTTransfer_User_Denied]: {\n        view: (\n          <NFTTransfer_User_Denied\n            btnInfo={{\n              btnTxt: 'labelRetry',\n              callback: () => {\n                nftTransferProps.onTransferClick(nftTransferValue as any)\n              },\n            }}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.NFTTransfer_In_Progress]: {\n        view: (\n          <NFTTransfer_In_Progress\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.NFTTransfer_Success]: {\n        view: (\n          <NFTTransfer_Success\n            btnInfo={closeBtnInfo()}\n            {...{\n              ...rest,\n              account,\n              link: isShowAccount?.info?.hash\n                ? {\n                    name: 'Txn Hash',\n                    url: isShowAccount?.info?.hash,\n                  }\n                : undefined,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.NFTTransfer_Failed]: {\n        view: (\n          <NFTTransfer_Failed\n            btnInfo={closeBtnInfo({\n              closeExtend: () => {\n                setShowAccount({\n                  ...isShowAccount,\n                  isShow: false,\n                  info: {\n                    ...isShowAccount.info,\n                    lastFailed: LAST_STEP.nftTransfer,\n                  },\n                })\n              },\n            })}\n            {...{\n              ...rest,\n              account,\n              error: isShowAccount.error,\n              t,\n            }}\n          />\n        ),\n      },\n      //Burn\n\n      // withdraw\n      [AccountStep.NFTWithdraw_WaitForAuth]: {\n        view: (\n          <NFTWithdraw_WaitForAuth\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.NFTWithdraw_First_Method_Denied]: {\n        view: (\n          <NFTWithdraw_First_Method_Denied\n            btnInfo={{\n              btnTxt: 'labelTryAnother',\n              callback: () => {\n                nftWithdrawProps.onWithdrawClick(nftWithdrawValue as any, false)\n              },\n            }}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.NFTWithdraw_User_Denied]: {\n        view: (\n          <NFTWithdraw_User_Denied\n            btnInfo={{\n              btnTxt: 'labelRetry',\n              callback: () => {\n                nftWithdrawProps.onWithdrawClick(nftWithdrawValue as any)\n              },\n            }}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.NFTWithdraw_In_Progress]: {\n        view: (\n          <NFTWithdraw_In_Progress\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.NFTWithdraw_Success]: {\n        view: (\n          <NFTWithdraw_Success\n            btnInfo={closeBtnInfo()}\n            {...{\n              ...rest,\n              account,\n              link: isShowAccount?.info?.hash\n                ? {\n                    name: 'Txn Hash',\n                    url: isShowAccount?.info?.hash,\n                  }\n                : undefined,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.NFTWithdraw_Failed]: {\n        view: (\n          <NFTWithdraw_Failed\n            btnInfo={closeBtnInfo({\n              closeExtend: () => {\n                setShowAccount({\n                  ...isShowAccount,\n                  isShow: false,\n                  info: {\n                    ...isShowAccount.info,\n                    lastFailed: LAST_STEP.nftWithdraw,\n                  },\n                })\n              },\n            })}\n            {...{\n              ...rest,\n              account,\n              error: isShowAccount.error,\n              t,\n            }}\n          />\n        ),\n      },\n\n      //create account\n\n      [AccountStep.CreateAccount_Approve_WaitForAuth]: {\n        view: (\n          <CreateAccount_Approve_WaitForAuth\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.CreateAccount_EOA_Only_Alert]: {\n        view: (\n          <CreateAccount_EOA_Only_Alert\n            onClose={() => setShowAccount({ isShow: false })}\n            onConfirm={() => {\n              setShowAccount({\n                isShow: true,\n                step: AccountStep.CheckingActive,\n              })\n            }}\n          />\n        ),\n        height: '450px',\n      },\n      [AccountStep.CreateAccount_Approve_Denied]: {\n        view: (\n          <CreateAccount_Approve_Denied\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.CreateAccount_Approve_Submit]: {\n        view: (\n          <CreateAccount_Approve_Submit\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.CreateAccount_WaitForAuth]: {\n        view: (\n          <CreateAccount_WaitForAuth\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.CreateAccount_Denied]: {\n        view: (\n          <CreateAccount_Denied\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.CreateAccount_Failed]: {\n        view: (\n          <CreateAccount_Failed\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              account,\n              error: isShowAccount.error,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.CreateAccount_Submit]: {\n        view: (\n          <CreateAccount_Submit\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n\n      [AccountStep.UnlockAccount_WaitForAuth]: {\n        view: (\n          <UnlockAccount_WaitForAuth\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.UnlockAccount_User_Denied]: {\n        view: (\n          <UnlockAccount_User_Denied\n            btnInfo={{\n              btnTxt: 'labelRetry',\n              callback: () => {\n                unlockAccount()\n              },\n            }}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.UnlockAccount_Success]: {\n        view: (\n          <UnlockAccount_Success\n            btnInfo={closeBtnInfo()}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.UnlockAccount_Failed]: {\n        view: (\n          <UnlockAccount_Failed\n            btnInfo={closeBtnInfo()}\n            onClickReset={() => {\n              setShowAccount({ isShow: true, step: AccountStep.UnlockAccount_Reset_Key_Confirm })\n            }}\n            {...{\n              ...rest,\n              account,\n              error: isShowAccount.error,\n              walletType: isShowAccount?.info?.walletType,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.UnlockAccount_Reset_Key_Confirm]: {\n        view: (\n          <UnlockAccount_Reset_Key_Confirm\n            t={t}\n            resetAccount={() => {\n              if (walletServices)\n                if (isShowAccount.info && isShowAccount.info.walletType) {\n                  const walletType = isShowAccount.info.walletType as sdk.WalletType\n                  if (walletType.isContract || walletType.isInCounterFactualStatus) {\n                    return\n                  }\n                }\n              setShowAccount({ isShow: false })\n              setShowActiveAccount({\n                isShow: true,\n                info: { isReset: true, confirmationType: undefined },\n              })\n            }}\n          />\n        ),\n        height: 510,\n      },\n\n      [AccountStep.ResetAccount_Approve_WaitForAuth]: {\n        view: (\n          <UpdateAccount_Approve_WaitForAuth\n            patch={{ isReset: true }}\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.ResetAccount_First_Method_Denied]: {\n        view: (\n          <UpdateAccount_First_Method_Denied\n            patch={{ isReset: true }}\n            btnInfo={{\n              btnTxt: t('labelTryAnother'),\n              callback: (_e?: any) => {\n                activeAccountProps.onResetClick({\n                  isReset: true,\n                  isNotFirstTime: false,\n                })\n              },\n            }}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n        onBack: () => {\n          setShowAccount({ isShow: false })\n          setShowResetAccount({ isShow: true })\n        },\n      },\n      [AccountStep.ResetAccount_User_Denied]: {\n        view: (\n          <UpdateAccount_User_Denied\n            patch={{ isReset: true }}\n            btnInfo={{\n              btnTxt: t('labelRetry'),\n              callback: (_e?: any) => {\n                activeAccountProps.onResetClick({\n                  isReset: true,\n                })\n              },\n            }}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.ResetAccount_Success]: {\n        view: (\n          <UpdateAccount_Success\n            patch={{ isReset: true }}\n            btnInfo={closeBtnInfo()}\n            {...{\n              ...rest,\n              account,\n              link: isShowAccount?.info?.hash\n                ? {\n                    name: 'Txn Hash',\n                    url: isShowAccount?.info?.hash,\n                  }\n                : undefined,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.ResetAccount_Failed]: {\n        view: (\n          <UpdateAccount_Failed\n            patch={{ isReset: true }}\n            btnInfo={{\n              btnTxt: 'labelClose',\n              callback: (e: any) => {\n                setShouldShow(false)\n                setShowAccount({ isShow: false })\n                setShowActiveAccount({ isShow: false })\n              },\n            }}\n            {...{\n              ...rest,\n              account,\n              error: isShowAccount.error,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.UpdateAccount_SmartWallet_NotSupported_Alert]: {\n        view: (\n          <UpdateAccount_SmartWallet_NotSupported_Alert\n            btnInfo={{\n              btnTxt: 'labelClose',\n              callback: (e: any) => {\n                setShowAccount({ isShow: false })\n                setShowActiveAccount({ isShow: false })\n              },\n            }}\n          />\n        ),\n      },\n\n      //update account\n      [AccountStep.UpdateAccount]: {\n        view: (\n          <UpdateAccount\n            {...{\n              ...account,\n              clearDepositHash: clearDeposit,\n              chainInfos,\n              etherscanUrl: rest.etherscanBaseUrl,\n              onSwitch,\n              onCopy,\n              onViewQRCode,\n              onDisconnect,\n              addressShort,\n            }}\n            goUpdateAccount={() => {\n              setShowAccount({ isShow: false })\n              setShowActiveAccount({ isShow: true })\n              // goUpdateAccount({});\n            }}\n            {...{ ...rest, account, t }}\n          />\n        ),\n        onQRClick,\n      },\n      [AccountStep.UpdateAccount_Approve_WaitForAuth]: {\n        view: (\n          <UpdateAccount_Approve_WaitForAuth\n            providerName={account.connectName as ConnectProviders}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.UpdateAccount_First_Method_Denied]: {\n        view: (\n          <UpdateAccount_First_Method_Denied\n            btnInfo={{\n              btnTxt: t('labelTryAnother'),\n              callback: (_e?: any) => {\n                activeAccountProps.onResetClick({ isNotFirstTime: true })\n                // goUpdateAccount({ isFirstTime: false });\n              },\n            }}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n        onBack: () => {\n          setShowAccount({ isShow: true, step: AccountStep.CreateAccount_EOA_Only_Alert })\n          // backToUpdateAccountBtnInfo.callback();\n        },\n      },\n      [AccountStep.UpdateAccount_User_Denied]: {\n        view: (\n          <UpdateAccount_User_Denied\n            btnInfo={{\n              btnTxt: t('labelRetry'),\n              callback: (_e?: any) => {\n                activeAccountProps.onResetClick({})\n              },\n            }}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.UpdateAccount_Success]: {\n        view: (\n          <UpdateAccount_Success\n            btnInfo={closeBtnInfo()}\n            {...{\n              ...rest,\n              account,\n              link: isShowAccount?.info?.hash\n                ? {\n                    name: 'Txn Hash',\n                    url: isShowAccount?.info?.hash,\n                  }\n                : undefined,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.UpdateAccount_Failed]: {\n        view: (\n          <UpdateAccount_Failed\n            btnInfo={{\n              btnTxt: 'labelClose',\n              callback: () => {\n                setShouldShow(false)\n                const isSpecialActivation =\n                  isEarn && SPECIAL_ACTIVATION_NETWORKS.includes(defaultNetwork)\n                if (isSpecialActivation) {\n                  setShowAccount({ isShow: false })\n                } else {\n                  setShowAccount({ isShow: false })\n                  setShowActiveAccount({ isShow: false })\n                }\n              },\n            }}\n            {...{\n              ...rest,\n              account,\n              error: isShowAccount.error,\n              t,\n            }}\n          />\n        ),\n      },\n\n      [AccountStep.ExportAccount_Approve_WaitForAuth]: {\n        view: (\n          <ExportAccount_Approve_WaitForAuth\n            patch={{ isReset: true }}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.ExportAccount_User_Denied]: {\n        view: (\n          <ExportAccount_User_Denied\n            patch={{ isReset: true }}\n            btnInfo={closeBtnInfo()}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.ExportAccount_Success]: {\n        view: (\n          <ExportAccount_Success\n            patch={{ isReset: true }}\n            btnInfo={closeBtnInfo()}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.ExportAccount_Failed]: {\n        view: (\n          <ExportAccount_Failed\n            patch={{ isReset: true }}\n            btnInfo={closeBtnInfo()}\n            {...{\n              ...rest,\n              account,\n              error: isShowAccount.error,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.Dual_Success]: {\n        view: (\n          <Dual_Success\n            btnInfo={{\n              btnTxt: 'labelDualPanelClose',\n              callback: (_e: any) => {\n                if (isWebEarn) {\n                  setShowAccount({ isShow: false })\n                  history.push('/l2assets/assets/Invests')\n                } else {\n                  setShowAccount({ isShow: false })\n                  history.push(`${RouterPath.invest}/${InvestRouter[InvestType.MyBalance]}`)\n                }\n              },\n            }}\n            {...{\n              ...rest,\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.Dual_Failed]: {\n        view: (\n          <Dual_Failed\n            btnInfo={closeBtnInfo()}\n            {...{\n              ...rest,\n              account,\n              error: isShowAccount.error,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.Staking_Redeem_Failed]: {\n        view: (\n          <Staking_Redeem_Failed\n            btnInfo={closeBtnInfo()}\n            {...{\n              ...rest,\n              account,\n              info: isShowAccount?.info,\n              error: isShowAccount.error,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.Staking_Redeem_Success]: {\n        view: (\n          <Staking_Redeem_Success\n            btnInfo={closeBtnInfo()}\n            {...{\n              ...rest,\n              info: isShowAccount?.info ?? {},\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.Staking_Success]: {\n        view: (\n          <Staking_Success\n            btnInfo={closeBtnInfo()}\n            {...{\n              ...rest,\n              info: isShowAccount?.info ?? {},\n              account,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.Staking_Failed]: {\n        view: (\n          <Staking_Failed\n            btnInfo={closeBtnInfo()}\n            {...{\n              ...rest,\n              account,\n              info: isShowAccount?.info,\n              error: isShowAccount.error,\n              t,\n            }}\n          />\n        ),\n      },\n      [AccountStep.BtradeSwap_Delivering]: {\n        view: (\n          <BtradeSwap_Delivering\n            btnInfo={undefined}\n            {...{\n              ...rest,\n              account,\n              info: isShowAccount?.info,\n              error: isShowAccount.error,\n              t,\n            }}\n          />\n        ),\n        height: 'auto',\n      },\n      [AccountStep.BtradeSwap_Pending]: {\n        view: (\n          <BtradeSwap_Pending\n            btnInfo={undefined}\n            {...{\n              ...rest,\n              account,\n              info: isShowAccount?.info,\n              error: isShowAccount.error,\n              t,\n            }}\n          />\n        ),\n        height: 'auto',\n      },\n\n      [AccountStep.BtradeSwap_Settled]: {\n        view: (\n          <BtradeSwap_Settled\n            btnInfo={undefined}\n            {...{\n              ...rest,\n              account,\n              info: isShowAccount?.info,\n              error: isShowAccount.error,\n              t,\n            }}\n          />\n        ),\n        height: 'auto',\n      },\n      [AccountStep.BtradeSwap_Failed]: {\n        view: (\n          <BtradeSwap_Failed\n            btnInfo={undefined}\n            {...{\n              ...rest,\n              account,\n              info: isShowAccount?.info,\n              error: isShowAccount.error,\n              t,\n            }}\n          />\n        ),\n        height: 'auto',\n      },\n      [AccountStep.AMM_Pending]: {\n        view: (\n          <AMM_Pending\n            btnInfo={undefined}\n            {...{\n              ...rest,\n              t,\n            }}\n          />\n        ),\n        height: 'auto',\n      },\n      [AccountStep.VaultTrade_Success]: {\n        view: (\n          <VaultTrade_Success btnInfo={undefined} {...{ info: isShowAccount?.info, t, ...rest }} />\n        ),\n      },\n      [AccountStep.VaultTrade_Failed]: {\n        view: (\n          <VaultTrade_Failed\n            btnInfo={undefined}\n            {...{\n              t,\n              info: isShowAccount?.info,\n              symbol: isShowAccount?.info?.symbol,\n              value: isShowAccount?.info?.value,\n              error: isShowAccount.error,\n              ...rest,\n            }}\n          />\n        ),\n      },\n      [AccountStep.VaultTrade_In_Progress]: {\n        view: (\n          <VaultTrade_In_Progress\n            btnInfo={undefined}\n            {...{ info: isShowAccount?.info, t, ...rest }}\n          />\n        ),\n      },\n      [AccountStep.VaultJoin_Success]: {\n        view: (\n          <VaultJoin_Success btnInfo={undefined} {...{ info: isShowAccount?.info, t, ...rest }} />\n        ),\n      },\n      [AccountStep.VaultJoin_Failed]: {\n        view: (\n          <VaultJoin_Failed\n            btnInfo={undefined}\n            {...{\n              info: isShowAccount?.info,\n              symbol: isShowAccount?.info?.symbol,\n              value: isShowAccount?.info?.value,\n              error: isShowAccount.error,\n              t,\n              ...rest,\n            }}\n          />\n        ),\n      },\n      [AccountStep.VaultJoin_In_Progress]: {\n        view: (\n          <VaultJoin_In_Progress\n            btnInfo={undefined}\n            {...{ info: isShowAccount?.info, t, ...rest }}\n          />\n        ),\n      },\n      [AccountStep.VaultRedeem_Success]: {\n        view: (\n          <VaultRedeem_Success btnInfo={undefined} {...{ info: isShowAccount?.info, t, ...rest }} />\n        ),\n      },\n      [AccountStep.VaultRedeem_Failed]: {\n        view: (\n          <VaultRedeem_Failed\n            btnInfo={undefined}\n            {...{\n              info: isShowAccount?.info,\n              symbol: isShowAccount?.info?.symbol,\n              value: isShowAccount?.info?.value,\n              error: isShowAccount.error,\n              t,\n              ...rest,\n            }}\n          />\n        ),\n      },\n      [AccountStep.VaultRedeem_In_Progress]: {\n        view: (\n          <VaultRedeem_In_Progress\n            btnInfo={undefined}\n            {...{ info: isShowAccount?.info, t, ...rest }}\n          />\n        ),\n      },\n      [AccountStep.VaultBorrow_Success]: {\n        view: (\n          <VaultBorrow_Success btnInfo={undefined} {...{ info: isShowAccount?.info, t, ...rest }} />\n        ),\n      },\n      [AccountStep.VaultBorrow_Failed]: {\n        view: (\n          <VaultBorrow_Failed btnInfo={undefined} {...{ info: isShowAccount?.info, t, ...rest }} />\n        ),\n      },\n      [AccountStep.VaultBorrow_In_Progress]: {\n        view: (\n          <VaultBorrow_In_Progress\n            btnInfo={undefined}\n            {...{ info: isShowAccount?.info, t, ...rest }}\n          />\n        ),\n      },\n      [AccountStep.VaultRepay_Success]: {\n        view: (\n          <VaultRepay_Success btnInfo={undefined} {...{ info: isShowAccount?.info, t, ...rest }} />\n        ),\n      },\n      [AccountStep.VaultRepay_Failed]: {\n        view: (\n          <VaultRepay_Failed btnInfo={undefined} {...{ info: isShowAccount?.info, t, ...rest }} />\n        ),\n      },\n      [AccountStep.VaultRepay_In_Progress]: {\n        view: (\n          <VaultRepay_In_Progress\n            btnInfo={undefined}\n            {...{ info: isShowAccount?.info, t, ...rest }}\n          />\n        ),\n      },\n      [AccountStep.VaultDustCollector_Success]: {\n        view: (\n          <VaultDustCollector_Success\n            btnInfo={undefined}\n            {...{ info: isShowAccount?.info, t, ...rest }}\n          />\n        ),\n      },\n      [AccountStep.VaultDustCollector_Failed]: {\n        view: (\n          <VaultDustCollector_Failed\n            btnInfo={undefined}\n            {...{ info: isShowAccount?.info, t, ...rest }}\n          />\n        ),\n      },\n      [AccountStep.VaultDustCollector_In_Progress]: {\n        view: (\n          <VaultDustCollector_In_Progress\n            btnInfo={undefined}\n            {...{ info: isShowAccount?.info, t, ...rest }}\n          />\n        ),\n      },\n      [AccountStep.Taiko_Farming_Lock_Success]: {\n        view: (\n          <Taiko_Farming_Lock_Success\n            btnInfo={undefined}\n            {...{ info: isShowAccount?.info, t, ...rest }}\n          />\n        ),\n      },\n      [AccountStep.Taiko_Farming_Lock_Failed]: {\n        view: (\n          <Taiko_Farming_Lock_Failed\n            btnInfo={undefined}\n            {...{ info: isShowAccount?.info, t, ...rest }}\n          />\n        ),\n      },\n      [AccountStep.Taiko_Farming_Redeem_In_Progress]: {\n        view: (\n          <Taiko_Farming_Redeem_In_Progress\n            btnInfo={undefined}\n            {...{ info: isShowAccount?.info, t, ...rest }}\n          />\n        ),\n      },\n      [AccountStep.Taiko_Farming_Redeem_Success]: {\n        view: (\n          <Taiko_Farming_Redeem_Success\n            btnInfo={undefined}\n            {...{ info: isShowAccount?.info, t, ...rest }}\n          />\n        ),\n      },\n      [AccountStep.Taiko_Farming_Redeem_Failed]: {\n        view: (\n          <Taiko_Farming_Redeem_Failed\n            btnInfo={undefined}\n            {...{ info: isShowAccount?.info, t, ...rest }}\n          />\n        ),\n      },\n      [AccountStep.Taiko_Farming_Mint_Success]: {\n        view: (\n          <Taiko_Farming_Mint_Success\n            btnInfo={undefined}\n            {...{ info: isShowAccount?.info, t, ...rest }}\n          />\n        ),\n      },\n      [AccountStep.Taiko_Farming_Mint_Failed]: {\n        view: (\n          <Taiko_Farming_Mint_Failed\n            btnInfo={undefined}\n            {...{ info: isShowAccount?.info, t, ...rest }}\n          />\n        ),\n      },\n      [AccountStep.Taiko_Farming_Mint_In_Progress]: {\n        view: (\n          <Taiko_Farming_Mint_In_Progress\n            btnInfo={undefined}\n            {...{ info: isShowAccount?.info, t, ...rest }}\n          />\n        ),\n      },\n\n      [AccountStep.Transfer_To_Taiko_User_Denied]: {\n        view: (\n          <Transfer_To_Taiko_User_Denied\n            btnInfo={{\n              btnTxt: 'labelRetry',\n              callback: () => {\n                transferToTaikoProps.retrySend()\n              },\n            }}\n            {...{\n              ...rest,\n              account,\n              t,\n              title: isShowAccount.info?.isToEthereum ? 'Send to Ethereum' : 'Send to Taiko',\n            }}\n          />\n        ),\n      },\n      [AccountStep.Transfer_To_Taiko_In_Progress]: {\n        view: (\n          <Transfer_To_Taiko_In_Progress\n            {...{\n              ...rest,\n              account,\n              t,\n              title: isShowAccount.info?.isToEthereum ? 'Send to Ethereum' : 'Send to Taiko',\n            }}\n          />\n        ),\n      },\n      [AccountStep.Transfer_To_Taiko_Success]: {\n        view: (\n          <Transfer_To_Taiko_Success\n            btnInfo={{\n              btnTxt: 'Send to Taiko Again',\n              callback: () => {\n                setShowAccount({ isShow: false })\n                setShowTransferToTaikoAccount({\n                  isShow: true,\n                  from: 'send',\n                })\n              },\n            }}\n            {...{\n              ...rest,\n              account,\n              link: isShowAccount?.info?.hash\n                ? {\n                    name: 'Txn Hash',\n                    url: isShowAccount?.info?.hash,\n                  }\n                : undefined,\n              t,\n              title: isShowAccount.info?.isToEthereum ? 'Send to Ethereum' : 'Send to Taiko',\n            }}\n          />\n        ),\n      },\n      [AccountStep.Transfer_To_Taiko_Failed]: {\n        view: (\n          <Transfer_To_Taiko_Failed\n            btnInfo={closeBtnInfo({\n              closeExtend: () => {\n                setShowAccount({\n                  ...isShowAccount,\n                  isShow: false,\n                  info: {\n                    ...isShowAccount.info,\n                    lastFailed: LAST_STEP.transfer,\n                  },\n                })\n              },\n            })}\n            {...{\n              ...rest,\n              account,\n              error: isShowAccount.error,\n              t,\n              title: isShowAccount.info?.isEthereum ? 'Send to Ethereum' : 'Send to Taiko',\n            }}\n          />\n        ),\n      },\n      [AccountStep.Coinbase_Smart_Wallet_Password_Intro]: {\n        view: <Coinbase_Smart_Wallet_Password_Intro {...coinbaseWalletPassword.introProps} />,\n      },\n      [AccountStep.Coinbase_Smart_Wallet_Password_Set]: {\n        view: <Coinbase_Smart_Wallet_Password_Set {...coinbaseWalletPassword.setProps} />,\n        height: '440px',\n      },\n      [AccountStep.Coinbase_Smart_Wallet_Password_Set_Confirm]: {\n        view: (\n          <Coinbase_Smart_Wallet_Password_Set_Confirm {...coinbaseWalletPassword.setConfirmProps} />\n        ),\n        noClose: true,\n      },\n      [AccountStep.Coinbase_Smart_Wallet_Password_Set_Processing]: {\n        view: (\n          <Coinbase_Smart_Wallet_Password_Set_Processing\n            {...coinbaseWalletPassword.setProcessingProps}\n          />\n        ),\n        height: '450px',\n      },\n      [AccountStep.Coinbase_Smart_Wallet_Password_Set_Error]: {\n        view: (\n          <Coinbase_Smart_Wallet_Password_Set_Error {...coinbaseWalletPassword.setErrorProps} />\n        ),\n      },\n      [AccountStep.Coinbase_Smart_Wallet_Password_Get_Error]: {\n        view: (\n          <Coinbase_Smart_Wallet_Password_Get_Error {...coinbaseWalletPassword.getErrorProps} />\n        ),\n      },\n      [AccountStep.Coinbase_Smart_Wallet_Password_Input]: {\n        view: <Coinbase_Smart_Wallet_Password_Input {...coinbaseWalletPassword.inputProps} />,\n      },\n      [AccountStep.Coinbase_Smart_Wallet_Password_Forget_Password_Confirm]: {\n        view: (\n          <Coinbase_Smart_Wallet_Password_Forget_Password_Confirm\n            {...coinbaseWalletPassword.forgetPasswordConfirmProps}\n          />\n        ),\n        height: '520px',\n      },\n      [AccountStep.Coinbase_Smart_Wallet_Password_Forget_Password]: {\n        view: (\n          <Coinbase_Smart_Wallet_Password_Forget_Password\n            {...coinbaseWalletPassword.forgetPasswordProps}\n          />\n        ),\n        height: '450px',\n      },\n    })\n  }, [\n    activeAccountProps,\n    resetProps,\n    checkActiveStatusProps,\n    account,\n    isShowAccount.info,\n    isShowAccount.error,\n    addAssetList,\n    allowTrade,\n    depositProps.isNewAccount,\n    depositProps.isAllowInputToAddress,\n    depositProps.tradeData.belong,\n    depositProps.tradeData.tradeValue,\n    sendAssetList,\n    sendNFTAssetList,\n    vendorListBuy,\n    campaignTagConfig,\n    onBackReceive,\n    chainInfos,\n    isLayer1Only,\n    updateDepositHash,\n    clearDeposit,\n    rest,\n    onSwitch,\n    onCopy,\n    onViewQRCode,\n    onDisconnect,\n    addressShort,\n    onQRClick,\n    lockBtn,\n    unlockBtn,\n    t,\n    onQRBack,\n    closeBtnInfo,\n    nftDepositValue,\n    nftDeployValue,\n    setShowAccount,\n    setShowDeposit,\n    creatRedPacketRetryBtn,\n    nftMintAdvanceRetryBtn,\n    nftDeployProps,\n    forceWithdrawRetry,\n    transferProps,\n    transferValue,\n    processRequestRampTransfer,\n    withdrawProps,\n    withdrawValue,\n    nftTransferProps,\n    nftTransferValue,\n    nftWithdrawProps,\n    nftWithdrawValue,\n    setShowActiveAccount,\n    disbaleList,\n  ])\n\n  const currentModal = accountList[isShowAccount.step]\n\n  return {\n    nftDeployProps,\n    nftTransferProps,\n    nftWithdrawProps,\n    transferProps,\n    withdrawProps,\n\t\tnftBurnProps,\n    claimProps,\n    depositProps,\n    resetProps,\n    collectionAdvanceProps,\n    sideStackRedeemProps: stakeWrapProps,\n    activeAccountProps,\n    exportAccountProps,\n    exportAccountAlertText,\n    exportAccountToastOpen,\n    setExportAccountToastOpen,\n    copyToastOpen,\n    setCopyToastOpen,\n    openQRCode,\n    setOpenQRCode,\n    isShowAccount,\n    account,\n    closeBtnInfo,\n    accountList,\n    currentModal,\n    onBackReceive,\n    onBackSend,\n    contactAddProps,\n    transferToTaikoProps\n\t}\n}\n"
  },
  {
    "path": "packages/core/src/modal/AccountModal/index.tsx",
    "content": "import { WithTranslation, withTranslation } from 'react-i18next'\nimport {\n  DepositProps,\n  Modal,\n  ModalAccount,\n  ModalPanel,\n  ModalQRCode,\n  Toast,\n  ToastType,\n  useOpenModals,\n  ETHStakingDetail,\n  AccountStep,\n} from '@loopring-web/component-lib'\nimport { useStakingAprTrend, useSystem } from '@loopring-web/core'\nimport { useAccountModalForUI } from './hook'\nimport {\n  Account,\n  AssetsRawDataItem,\n  SendAssetList,\n  TOAST_TIME,\n} from '@loopring-web/common-resources'\n\nexport const ModalAccountInfo = withTranslation('common')(\n  ({\n    // onClose,\n    etherscanBaseUrl,\n    open,\n    assetsRawData,\n    isLayer1Only,\n    depositProps,\n    hideDepositWithdrawBack,\n    isWebEarn,\n    t,\n    ...rest\n  }: {\n    open: boolean\n    isLayer1Only?: boolean\n    account: Account\n    depositProps: DepositProps<any, any>\n    etherscanBaseUrl: string\n    assetsRawData: AssetsRawDataItem[]\n    hideDepositWithdrawBack?: boolean\n    isWebEarn?: boolean\n  } & WithTranslation) => {\n    const { baseURL } = useSystem()\n    const {\n      modals: { isShowAccount, isShowGlobalToast, isShowETHStakingApr },\n      setShowAccount,\n      setShowDeposit,\n      setShowTransfer,\n      setShowWithdraw,\n      setShowGlobalToast,\n      setShowETHStakingApr,\n    } = useOpenModals()\n    const stakingAprProps = useStakingAprTrend()\n    const {\n      exportAccountAlertText,\n      exportAccountToastOpen,\n      setExportAccountToastOpen,\n      setCopyToastOpen,\n      setOpenQRCode,\n      account,\n      collectionAdvanceProps,\n      nftBurnProps,\n      transferProps,\n      withdrawProps,\n      nftTransferProps,\n      nftWithdrawProps,\n      nftDeployProps,\n      resetProps,\n      claimProps,\n      activeAccountProps,\n      exportAccountProps,\n      // dualTradeProps,\n      sideStackRedeemProps,\n      copyToastOpen,\n      openQRCode,\n      accountList,\n      currentModal,\n      onBackReceive,\n      onBackSend,\n      contactAddProps,\n      transferToTaikoProps,\n      // toastOpen,\n      // closeToast,\n    } = useAccountModalForUI({\n      t,\n      assetsRawData,\n      depositProps,\n      etherscanBaseUrl,\n      isLayer1Only,\n      isWebEarn,\n      ...rest,\n    })\n\n    return (\n      <>\n        <Toast\n          alertText={exportAccountAlertText as string}\n          open={exportAccountToastOpen}\n          autoHideDuration={TOAST_TIME}\n          onClose={() => {\n            setExportAccountToastOpen(false)\n          }}\n          severity={ToastType.success}\n        />\n        <Toast\n          alertText={\n            isShowGlobalToast?.info?.messageKey\n              ? t(isShowGlobalToast?.info?.messageKey, { ns: ['error', 'common'] })\n              : isShowGlobalToast?.info?.content ?? ''\n          }\n          severity={isShowGlobalToast?.info?.type ?? ToastType.success}\n          open={isShowGlobalToast?.isShow ?? false}\n          autoHideDuration={TOAST_TIME}\n          onClose={() =>\n            setShowGlobalToast({\n              isShow: false,\n              info: {\n                content: '',\n                messageKey: '',\n                type: ToastType.info,\n              },\n            })\n          }\n        />\n\n        <ModalPanel\n          baseURL={baseURL}\n          transferProps={{\n            ...transferProps,\n            onBack: () => {\n              if (transferProps.isFromContact) {\n                setShowTransfer({ isShow: false })\n                setShowAccount({\n                  isShow: true,\n                  step: AccountStep.SendAssetFromContact,\n                  info: {\n                    ...transferProps.contact,\n                    isENSWrong: false,\n                    select: SendAssetList.SendAssetToL2.key,\n                  },\n                })\n              } else {\n                setShowTransfer({ isShow: false })\n                onBackSend()\n              }\n            },\n          }}\n          contactAddProps={contactAddProps}\n          withdrawProps={{\n            ...withdrawProps,\n            onBack: hideDepositWithdrawBack\n              ? undefined\n              : () => {\n                  if (withdrawProps.isFromContact) {\n                    setShowWithdraw({ isShow: false })\n                    setShowAccount({\n                      isShow: true,\n                      step: AccountStep.SendAssetFromContact,\n                      info: {\n                        ...withdrawProps.contact,\n                        isENSWrong: false,\n                        select: SendAssetList.SendAssetToOtherL1.key,\n                      },\n                    })\n                  } else {\n                    setShowWithdraw({ isShow: false })\n                    onBackSend()\n                  }\n                },\n          }}\n          depositProps={{\n            ...depositProps,\n            onBack: hideDepositWithdrawBack\n              ? undefined\n              : () => {\n                  setShowDeposit({ isShow: false })\n                  onBackReceive()\n                },\n          }}\n          collectionAdvanceProps={collectionAdvanceProps as any}\n          nftTransferProps={\n            {\n              ...nftTransferProps,\n            } as any\n          }\n          nftBurnProps={nftBurnProps}\n          nftWithdrawProps={nftWithdrawProps as any}\n          nftDeployProps={nftDeployProps as any}\n          claimProps={claimProps as any}\n          resetProps={resetProps as any}\n          activeAccountProps={activeAccountProps as any}\n          exportAccountProps={exportAccountProps}\n          assetsData={assetsRawData}\n          setExportAccountToastOpen={setExportAccountToastOpen}\n          account={account}\n          sideStackRedeemProps={sideStackRedeemProps as any}\n          transferToTaikoProps={transferToTaikoProps}\n          {...{ _height: 'var(--modal-height)', _width: 'var(--modal-width)' }}\n        />\n        <Toast\n          alertText={t('labelCopyAddClip')}\n          open={copyToastOpen}\n          autoHideDuration={TOAST_TIME}\n          onClose={() => {\n            setCopyToastOpen(false)\n          }}\n          severity={ToastType.success}\n        />\n        <ModalQRCode\n          open={openQRCode}\n          onClose={() => setOpenQRCode(false)}\n          title={'ETH Address'}\n          description={account?.accAddress}\n          url={account?.accAddress}\n        />\n        <ModalAccount\n          open={isShowAccount.isShow}\n          onClose={() => {\n            setShowAccount({ isShow: false })\n            currentModal?.onClose && currentModal?.onClose()\n          }}\n          panelList={accountList}\n          onBack={currentModal?.onBack}\n          onQRClick={currentModal?.onQRClick}\n          step={isShowAccount.step}\n          etherscanBaseUrl={etherscanBaseUrl}\n          isLayer2Only={isLayer1Only}\n          noClose={currentModal?.noClose}\n        />\n        <Modal\n          open={isShowETHStakingApr.isShow}\n          onClose={() => setShowETHStakingApr({ ...isShowETHStakingApr, isShow: false })}\n          content={<ETHStakingDetail symbol={isShowETHStakingApr.symbol} {...stakingAprProps} />}\n        />\n      </>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/core/src/modal/AmmPoolModal/components/ammPanel.tsx",
    "content": "import React from 'react'\nimport { AmmPanel, ConfirmAmmExitMiniOrder, TOASTOPEN } from '@loopring-web/component-lib'\n\nimport { Grid } from '@mui/material'\nimport { useAccount, useAmmMap, usePageAmmPool, walletLayer2Service } from '../../../index'\nimport styled from '@emotion/styled'\nimport { useAmmJoin } from '../../../hooks/useractions/hookAmmJoin'\nimport { useAmmExit } from '../../../hooks/useractions/hookAmmExit'\nimport { SagaStatus, AmmPanelType } from '@loopring-web/common-resources'\n\nexport const BoxWrapperStyled = styled(Grid)`\n  background: var(--color-box);\n  border-radius: ${({ theme }) => theme.unit}px;\n\n  .divider-item {\n    border-right: 0;\n  }\n\n  @media only screen and (min-width: 900px) {\n    .divider-item {\n      height: 0;\n      padding-top: 42%;\n      margin-left: 8px;\n      border-right: 1px solid var(--color-divide);\n    }\n  }\n` as typeof Grid\n\nexport const AmmPanelView = ({\n  market,\n  ammType,\n  getRecentAmmPoolTxs,\n  updateAmmPoolSnapshot,\n  refreshRef,\n  setToastOpen,\n  // getFee,\n  updateExitFee,\n  updateJoinFee,\n  // ammExit,\n  // ammJoin,\n  ...rest\n}: {\n  market: string\n  refreshRef: React.Ref<any>\n  updateAmmPoolSnapshot: () => void\n  setToastOpen: (state: TOASTOPEN) => void\n  // getFee: () => void;\n  ammType?: keyof typeof AmmPanelType\n  getRecentAmmPoolTxs?: (props: { limit?: number; offset?: number }) => void\n  updateExitFee: () => Promise<void>\n  updateJoinFee: () => Promise<void>\n  // ammExit: any;\n  // ammJoin: any;\n} & any) => {\n  const [confirmExitSmallOrder, setConfirmExitSmallOrder] = React.useState<{\n    open: boolean\n    type: 'Disabled' | 'Mini'\n  }>({ open: false, type: 'Disabled' })\n  const { ammMap } = useAmmMap()\n\n  const [index, setIndex] = React.useState(ammType == 1 ? AmmPanelType.Exit : AmmPanelType.Join)\n  const handleTabChange = React.useCallback(\n    (newValue: any) => {\n      if (index !== newValue) {\n        setIndex(newValue)\n      }\n    },\n    [index],\n  )\n  const {\n    ammCalcData: ammCalcDataDeposit,\n    ammData: ammJoinData,\n    handleAmmPoolEvent: handleJoinAmmPoolEvent,\n    onAmmClick: onAmmAddClick,\n    btnStatus: addBtnStatus,\n    btnI18nKey: ammDepositBtnI18nKey,\n    propsAExtends,\n    propsBExtends,\n  } = useAmmJoin({\n    updateJoinFee,\n    setToastOpen,\n    market,\n    refreshRef,\n  })\n  const {\n    ammCalcData: ammCalcDataWithdraw,\n    ammData: ammExitData,\n    handleAmmPoolEvent: handleExitAmmPoolEvent,\n    onAmmClick: onAmmRemoveClick,\n    btnStatus: removeBtnStatus,\n    btnI18nKey: ammWithdrawBtnI18nKey,\n    exitSmallOrderCloseClick,\n    propsLPExtends,\n  } = useAmmExit({\n    updateExitFee,\n    setToastOpen,\n    market,\n    refreshRef,\n    // ammCalcDefault: ammExit.ammCalcData,\n    // ammDataDefault: ammExit.ammData,\n    setConfirmExitSmallOrder,\n  })\n  const { resetAmmPool } = usePageAmmPool()\n  const { status: accountStatus } = useAccount()\n\n  React.useEffect(() => {\n    if (refreshRef.current) {\n      // @ts-ignore\n      refreshRef.current.firstElementChild.click()\n    }\n    return () => {\n      resetAmmPool()\n    }\n  }, [])\n  React.useEffect(() => {\n    if (accountStatus === SagaStatus.UNSET) {\n      walletLayer2Service.sendUserUpdate()\n    }\n  }, [accountStatus])\n\n  return (\n    <>\n      <ConfirmAmmExitMiniOrder\n        type={confirmExitSmallOrder.type}\n        handleClose={(_e: any, isAgree = false) => {\n          setConfirmExitSmallOrder({ open: false, type: 'Disabled' })\n          exitSmallOrderCloseClick(isAgree)\n        }}\n        open={confirmExitSmallOrder.open}\n      />\n      <AmmPanel\n        {...{ ...rest }}\n        onRefreshData={() => {\n          updateAmmPoolSnapshot()\n        }}\n        tabSelected={ammType ? ammType : AmmPanelType.Join}\n        ammInfo={ammMap['AMM-' + market]}\n        refreshRef={refreshRef}\n        ammType={index}\n        handleTabChange={handleTabChange}\n        ammDepositData={ammJoinData}\n        ammCalcDataDeposit={ammCalcDataDeposit}\n        handleAmmAddChangeEvent={handleJoinAmmPoolEvent}\n        onAmmAddClick={onAmmAddClick}\n        ammDepositBtnI18nKey={ammDepositBtnI18nKey}\n        ammDepositBtnStatus={addBtnStatus}\n        propsAExtends={propsAExtends}\n        propsBExtends={propsBExtends}\n        ammWithdrawData={ammExitData}\n        ammCalcDataWithDraw={ammCalcDataWithdraw}\n        handleAmmRemoveChangeEvent={handleExitAmmPoolEvent}\n        onAmmRemoveClick={onAmmRemoveClick}\n        ammWithdrawBtnI18nKey={ammWithdrawBtnI18nKey}\n        ammWithdrawBtnStatus={removeBtnStatus}\n        propsLPExtends={propsLPExtends}\n      />\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/core/src/modal/AmmPoolModal/components/ammRecordPanel.tsx",
    "content": "import React from 'react'\nimport { StylePaper } from '../../../component'\nimport { BoxProps, Divider, Tab, Tabs } from '@mui/material'\nimport { AmmRecordTable, useSettings } from '@loopring-web/component-lib'\nimport { AccountStatus, RowConfig } from '@loopring-web/common-resources'\nimport styled from '@emotion/styled'\nimport { useTranslation } from 'react-i18next'\nimport { store, useSystem } from '../../../stores'\nimport { useAmmRecord } from '../hooks'\n\nconst TabsStyled = styled(Tabs)`\n  padding-left: ${({ theme }) => theme.unit}px;\n`\nconst AMMPanelStyled = styled(StylePaper)<BoxProps & { isMobile: boolean }>`\n  background: initial;\n  && {\n    margin-bottom: 0;\n  }\n  .amm-record-table {\n    .rdg {\n      ${({ isMobile }) =>\n        !isMobile\n          ? `--template-columns: 50% 30% 20% !important;`\n          : `--template-columns: 86% 14% !important;`}\n    }\n  }\n` as (props: BoxProps & { isMobile: boolean }) => JSX.Element\n\nconst applyProps = (index: number) => {\n  return {\n    id: `simple-tab-${index}`,\n    'aria-controls': `tabpanel-${index}`,\n  }\n}\nexport const AmmRecordPanel = ({ market }: { market: string }) => {\n  const {\n    isMyAmmLoading,\n    isRecentLoading,\n    ammMarketArray,\n    container,\n    myAmmMarketArray,\n    ammUserTotal,\n    getUserAmmPoolTxs,\n    getRecentAmmPoolTxs,\n    pageSize,\n  } = useAmmRecord({ market })\n  const [tabIndex, setTabIndex] = React.useState<0 | 1>(0)\n\n  const { t } = useTranslation('common')\n  const { currency, isMobile } = useSettings()\n  const { forexMap } = useSystem()\n  const tableHeight = RowConfig.rowHeaderHeight + (tabIndex === 0 ? 15 : 14) * RowConfig.rowHeight\n\n  const handleTabsChange = React.useCallback((_: any, value: 0 | 1) => {\n    setTabIndex(value)\n  }, [])\n  React.useEffect(() => {\n    if (container.current) {\n      if (tabIndex == 0) {\n        getRecentAmmPoolTxs({})\n      } else if (store.getState().account.readyState === AccountStatus.ACTIVATED && tabIndex == 1) {\n        getUserAmmPoolTxs({})\n      }\n    }\n  }, [tabIndex, container])\n  return (\n    <AMMPanelStyled\n      isMobile={isMobile}\n      // className={\"MuiPaper-elevation2\"}\n      // paddingBottom={1}\n      ref={container}\n      marginBottom={0}\n    >\n      <TabsStyled value={tabIndex} onChange={handleTabsChange} aria-label='tabs switch'>\n        <Tab label={t('labelAmmAllTransactions')} {...applyProps(0)} />\n        <Tab label={t('labelAmmMyTransactions')} {...applyProps(1)} />\n      </TabsStyled>\n      <Divider style={{ marginTop: '-1px' }} />\n      {/*ammRecordArray*/}\n      {tabIndex === 0 ? (\n        <AmmRecordTable\n          rawData={ammMarketArray}\n          rowHeight={RowConfig.rowHeight}\n          headerRowHeight={RowConfig.rowHeaderHeight}\n          currentheight={tableHeight}\n          showloading={isRecentLoading}\n          currency={currency}\n          forexMap={forexMap as any}\n          scroll={true}\n        />\n      ) : (\n        <AmmRecordTable\n          rawData={myAmmMarketArray}\n          handlePageChange={getUserAmmPoolTxs}\n          pagination={{\n            pageSize,\n            total: ammUserTotal,\n          }}\n          showloading={isMyAmmLoading}\n          rowHeight={RowConfig.rowHeight}\n          headerRowHeight={RowConfig.rowHeaderHeight}\n          forexMap={forexMap as any}\n          currency={currency}\n        />\n      )}\n    </AMMPanelStyled>\n  )\n}\n"
  },
  {
    "path": "packages/core/src/modal/AmmPoolModal/components/chartAndInfo.tsx",
    "content": "import { Box, BoxProps, Divider, Grid, Typography } from '@mui/material'\nimport {\n  ChartType,\n  floatTag,\n  PopoverPure,\n  ScaleAreaChart,\n  StyledProps,\n  useSettings,\n  AmmPairDetail,\n  CoinIcons,\n  LoadingBlock,\n  ToastType,\n  EmptyDefault,\n} from '@loopring-web/component-lib'\nimport {\n  AmmHistoryItem,\n  CurrencyToTag,\n  CustomError,\n  EmptyValueTag,\n  FloatTag,\n  getValuePrecisionThousand,\n  myLog,\n  PriceTag,\n  SDK_ERROR_MAP_TO_UI,\n  SoursURL,\n  TokenType,\n  UIERROR_CODE,\n  UpColor,\n} from '@loopring-web/common-resources'\nimport { useTranslation } from 'react-i18next'\nimport { useAmmMap, useSystem, useTicker, useTokenMap, useUserRewards } from '../../../stores'\nimport { BoxWrapperStyled } from './ammPanel'\nimport { bindHover, bindPopper } from 'material-ui-popup-state'\nimport { usePopupState } from 'material-ui-popup-state/hooks'\nimport styled from '@emotion/styled'\nimport React from 'react'\nimport { LoopringAPI } from '../../../api_wrapper'\nimport { TradingInterval } from '@loopring-web/loopring-sdk'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport moment from 'moment'\nimport _ from 'lodash'\n\nconst BoxStyle = styled(Box)<StyledProps & BoxProps>`\n  ${({ theme, custom }) => floatTag({ theme, custom })};\n` as (props: StyledProps & BoxProps) => JSX.Element\n\nexport const ChartAndInfoPanel = ({\n  setToastOpen,\n  market,\n}: // myAmm,\n{\n  market: string\n  setToastOpen: (props: { open: boolean; content: JSX.Element | string; type: ToastType }) => void\n}) => {\n  const { t } = useTranslation('common')\n  const { ammMap } = useAmmMap()\n  const { tokenMap } = useTokenMap()\n  const { tickerMap } = useTicker()\n  const ammInfo = ammMap['AMM-' + market]\n  const { myAmmLPMap } = useUserRewards()\n  const [pairHistory, setPairHistory] = React.useState<AmmHistoryItem[] | undefined>([])\n  const getPairList = React.useCallback(async () => {\n    if (LoopringAPI.exchangeAPI) {\n      try {\n        const response = await LoopringAPI.exchangeAPI.getMixCandlestick({\n          market,\n          interval: TradingInterval.d1,\n          limit: 30,\n        })\n        if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n          // myLog(\"getMixCandlestick\", response);\n          throw new CustomError(\n            // @ts-ignore\n            SDK_ERROR_MAP_TO_UI[(response as sdk.RESULT_INFO)?.code ?? UIERROR_CODE.UNKNOWN],\n          )\n        }\n        const formattedPairHistory = response.candlesticks\n          .map((o) => ({\n            ...o,\n            timeStamp: o.timestamp,\n            date: moment(o.timestamp).format('MMM DD'),\n          }))\n          .sort((a, b) => a.timeStamp - b.timeStamp)\n        setPairHistory(formattedPairHistory)\n      } catch (error: any) {\n        setPairHistory(undefined)\n        setToastOpen({\n          open: true,\n          type: ToastType.error,\n          content: t('labelAMMChartFailed') + error?.message,\n        })\n        myLog('getMixCandlestick', 'timeout', error)\n      }\n    }\n  }, [market])\n  const myAmm = myAmmLPMap && myAmmLPMap[market ?? '']\n\n  const popState = usePopupState({\n    variant: 'popover',\n    popupId: `popup-My-LP`,\n  })\n  const { upColor, coinJson, currency } = useSettings()\n  const { forexMap } = useSystem()\n  const precisionA = tokenMap[ammInfo?.coinA ?? '']?.precision\n  const precisionB = tokenMap[ammInfo?.coinB ?? '']?.precision\n  const ticker = tickerMap[market]\n  const { balanceAStr, balanceBStr, balanceU: myBalanceDollar } = myAmm ?? {}\n  const tradeFloatType =\n    ticker?.changeU === 0 || !ticker?.changeU\n      ? FloatTag.none\n      : ticker.changeU < 0\n      ? FloatTag.decrease\n      : FloatTag.increase\n  React.useEffect(() => {\n    const timer = _.delay(getPairList, 0)\n    return () => {\n      clearTimeout(timer)\n    }\n  }, [])\n\n  return (\n    <BoxStyle\n      custom={{ chg: upColor as UpColor }}\n      flex={1}\n      marginTop={3}\n      display={'flex'}\n      flexDirection={'column'}\n    >\n      {ammInfo.market ? (\n        <>\n          <Box\n            width={'100%'}\n            // height={\"60%\"}\n            height={'calc(var(--swap-box-height) - 262px)'}\n            maxHeight={420}\n          >\n            {pairHistory?.length ? (\n              <ScaleAreaChart\n                type={ChartType.Trend}\n                data={pairHistory}\n                quoteSymbol={ammInfo.coinB}\n                showXAxis\n              />\n            ) : pairHistory == undefined || pairHistory?.length == 0 ? (\n              <Box\n                flex={1}\n                display={'flex'}\n                alignItems={'center'}\n                justifyContent={'center'}\n                height={'90%'}\n              >\n                <EmptyDefault\n                  message={() => {\n                    return t('labelAMMChartFailed')\n                  }}\n                />\n              </Box>\n            ) : (\n              <Box\n                flex={1}\n                display={'flex'}\n                alignItems={'center'}\n                justifyContent={'center'}\n                height={'90%'}\n              >\n                <img\n                  className='loading-gif'\n                  alt={'loading'}\n                  width='36'\n                  src={`${SoursURL}images/loading-line.gif`}\n                />\n              </Box>\n            )}\n          </Box>\n          <BoxWrapperStyled\n            container\n            className={'MuiPaper-elevation2'}\n            display={'flex'}\n            alignItems={'center'}\n            margin={2}\n            width={'auto'}\n            spacing={2}\n          >\n            <Grid\n              item\n              // paddingLeft={2}\n              // paddingY={3}\n              xs={12}\n              md={6}\n              display={'flex'}\n              justifyContent={'space-between'}\n              alignItems={'center'}\n            >\n              <Box>\n                <Box\n                  display={'flex'}\n                  flexDirection={'column'}\n                  alignItems={'flex-start'}\n                  justifyContent={'center'}\n                  className={'float-chart float-group'}\n                >\n                  <Typography\n                    variant={'h5'}\n                    component={'span'}\n                    className={`float-tag float-${tradeFloatType}`}\n                  >\n                    {ticker?.change === 0 || typeof ticker?.change === 'undefined'\n                      ? EmptyValueTag\n                      : (tradeFloatType === FloatTag.increase ? '+' : '') +\n                        getValuePrecisionThousand(ticker?.change, 2, 2, 2, true) +\n                        '%'}\n                  </Typography>\n                </Box>\n                <Typography\n                  component={'span'}\n                  display={'flex'}\n                  flexDirection={'row'}\n                  justifyContent={'flex-start'}\n                  alignItems={'center'}\n                  style={{ textTransform: 'capitalize' }}\n                  color={'textPrimary'}\n                  marginTop={1}\n                >\n                  <Box\n                    component={'span'}\n                    className={'logo-icon'}\n                    display={'flex'}\n                    height={'var(--list-menu-coin-size)'}\n                    width={'var(--list-menu-coin-size)'}\n                    alignItems={'center'}\n                    justifyContent={'center'}\n                  >\n                    <CoinIcons type={TokenType.single} tokenIcon={[coinJson[ammInfo.coinA]]} />\n                  </Box>\n                  <Typography marginLeft={1 / 2} justifyContent={'center'} display={'flex'}>\n                    <Typography\n                      component={'span'}\n                      alignSelf={'right'}\n                      variant={'h5'}\n                      height={24}\n                      lineHeight={'24px'}\n                    >\n                      {getValuePrecisionThousand(ammInfo.totalA, precisionA, precisionA)}\n                    </Typography>\n                    <Typography\n                      component={'span'}\n                      variant={'h5'}\n                      marginLeft={1}\n                      alignSelf={'right'}\n                      height={24}\n                      lineHeight={'24px'}\n                    >\n                      {ammInfo.coinA}\n                    </Typography>\n                  </Typography>\n                </Typography>\n                <Typography\n                  component={'span'}\n                  display={'flex'}\n                  flexDirection={'row'}\n                  justifyContent={'flex-start'}\n                  alignItems={'center'}\n                  marginTop={1}\n                  style={{ textTransform: 'capitalize' }}\n                >\n                  <Box\n                    component={'span'}\n                    className={'logo-icon'}\n                    display={'flex'}\n                    height={'var(--list-menu-coin-size)'}\n                    width={'var(--list-menu-coin-size)'}\n                    alignItems={'center'}\n                    justifyContent={'center'}\n                  >\n                    <CoinIcons type={TokenType.single} tokenIcon={[coinJson[ammInfo.coinB]]} />\n                  </Box>\n                  <Typography marginLeft={1 / 2} justifyContent={'center'} display={'flex'}>\n                    <Typography\n                      variant={'h5'}\n                      component={'span'}\n                      alignSelf={'right'}\n                      height={24}\n                      lineHeight={'24px'}\n                    >\n                      {getValuePrecisionThousand(ammInfo.totalB, precisionB, precisionB)}\n                    </Typography>\n                    <Typography\n                      variant={'h5'}\n                      component={'span'}\n                      marginLeft={1}\n                      alignSelf={'right'}\n                      height={24}\n                      lineHeight={'24px'}\n                    >\n                      {ammInfo.coinB}\n                    </Typography>\n                  </Typography>\n                </Typography>\n              </Box>\n              <Divider className={'divider-item'} orientation={'vertical'} />\n            </Grid>\n\n            <Grid item paddingX={2} paddingY={3} xs={12} md={6}>\n              <Typography\n                display={'inline-flex'}\n                component={'p'}\n                marginTop={1}\n                justifyContent={'space-between'}\n                width={'100%'}\n              >\n                <Typography\n                  component={'span'}\n                  color={'var(--color-text-third)'}\n                  display={'flex'}\n                  title={'Total Volume Locked'}\n                >\n                  {t('labelTVL')}\n                </Typography>\n                <Typography variant={'body1'} component={'span'}>\n                  {typeof ammInfo.amountU === 'undefined'\n                    ? EmptyValueTag\n                    : PriceTag[CurrencyToTag[currency]] +\n                      getValuePrecisionThousand(\n                        sdk.toBig(ammInfo.amountU ?? 0).times(forexMap[currency] ?? 0),\n                        undefined,\n                        undefined,\n                        2,\n                        true,\n                        { isFait: true, floor: true, isAbbreviate: true },\n                      )}\n                </Typography>\n              </Typography>\n\n              <Typography\n                display={'inline-flex'}\n                component={'p'}\n                marginTop={1}\n                justifyContent={'space-between'}\n                width={'100%'}\n              >\n                <Typography component={'span'} color={'var(--color-text-third)'} display={'flex'}>\n                  {t('label24Volume')}\n                </Typography>\n                <Typography variant={'body1'} component={'span'}>\n                  {ticker?.priceU\n                    ? PriceTag[CurrencyToTag[currency]] +\n                      getValuePrecisionThousand(\n                        sdk.toBig(ticker?.priceU ?? 0).times(forexMap[currency] ?? 0),\n                        undefined,\n                        undefined,\n                        undefined,\n                        true,\n                        {\n                          isFait: true,\n                          floor: false,\n                          isAbbreviate: true,\n                          abbreviate: 6,\n                        },\n                      )\n                    : EmptyValueTag}\n                </Typography>\n              </Typography>\n\n              <Typography\n                display={'inline-flex'}\n                component={'p'}\n                marginTop={1}\n                justifyContent={'space-between'}\n                width={'100%'}\n              >\n                <Typography component={'span'} color={'var(--color-text-third)'} display={'flex'}>\n                  {t('labelAPR')}\n                </Typography>\n                <Typography variant={'body1'} component={'span'}>\n                  {ammInfo.APR\n                    ? getValuePrecisionThousand(ammInfo.APR, 2, 2, undefined, true) + '%'\n                    : EmptyValueTag}\n                </Typography>\n              </Typography>\n\n              <Typography\n                display={'inline-flex'}\n                component={'p'}\n                marginTop={1}\n                justifyContent={'space-between'}\n                width={'100%'}\n              >\n                <Typography component={'span'} color={'var(--color-text-third)'} display={'flex'}>\n                  {t('labelMe')}\n                </Typography>\n                {typeof myBalanceDollar === 'undefined' ? (\n                  <Typography component={'span'}>{EmptyValueTag}</Typography>\n                ) : (\n                  <Typography\n                    component={'span'}\n                    {...bindHover(popState)}\n                    style={{\n                      cursor: 'pointer',\n                      textDecoration: 'underline dotted',\n                    }}\n                  >\n                    {PriceTag[CurrencyToTag[currency]] +\n                      getValuePrecisionThousand(\n                        (myBalanceDollar || 0) * (forexMap[currency] ?? 0),\n                        undefined,\n                        undefined,\n                        2,\n                        true,\n                        { isFait: true, floor: true },\n                      )}\n                  </Typography>\n                )}\n                <PopoverPure\n                  className={'arrow-top-center'}\n                  {...bindPopper(popState)}\n                  anchorOrigin={{\n                    vertical: 'top',\n                    horizontal: 'center',\n                  }}\n                  transformOrigin={{\n                    vertical: 'bottom',\n                    horizontal: 'center',\n                  }}\n                >\n                  <AmmPairDetail\n                    coinA={ammInfo.coinA}\n                    coinB={ammInfo.coinB}\n                    balanceA={balanceAStr}\n                    balanceB={balanceBStr}\n                  />\n                </PopoverPure>\n              </Typography>\n            </Grid>\n          </BoxWrapperStyled>\n        </>\n      ) : (\n        <LoadingBlock />\n      )}\n    </BoxStyle>\n  )\n}\n"
  },
  {
    "path": "packages/core/src/modal/AmmPoolModal/hooks.ts",
    "content": "import React from 'react'\n\nimport {\n  useTokenPrices,\n  useAmmMap,\n  getRecentAmmTransaction,\n  makeMyAmmMarketArray,\n  volumeToCount,\n  getUserAmmTransaction,\n} from '../../index'\n\n// import _ from \"lodash\";\nimport {\n  AmmRecordRow,\n  // useOpenModals\n} from '@loopring-web/component-lib'\n// import * as sdk from \"@loopring-web/loopring-sdk\";\n// import { useAmmCommon } from \"../../hooks/useractions/hookAmmCommon\";\nimport { AmmPoolTx, UserAmmPoolTx } from '@loopring-web/loopring-sdk'\nimport { RowConfig } from '@loopring-web/common-resources'\n// import moment from \"moment\";\n\nexport type AwardItme = {\n  start: string\n  end: string\n  market: string\n  accountId: number\n  awardList: {\n    token?: string\n    volume?: number\n  }[]\n}\n\nexport const useAmmRecord = <R extends { [key: string]: any }>({ market }: { market: string }) => {\n  const { ammMap } = useAmmMap()\n  const container = React.useRef(null)\n\n  const [isMyAmmLoading, setIsMyAmmLoading] = React.useState(false)\n  const [isRecentLoading, setIsRecentLoading] = React.useState(false)\n  const [ammMarketArray, setAmmMarketArray] = React.useState<AmmRecordRow<R>[]>([])\n  const [ammTotal, setAmmTotal] = React.useState(0)\n  const [ammUserTotal, setAmmUserTotal] = React.useState(0)\n  const [pageSize, setPageSize] = React.useState(14)\n  const { tokenPrices } = useTokenPrices()\n  const [myAmmMarketArray, setMyAmmMarketArray] = React.useState<AmmRecordRow<R>[]>([])\n  React.useEffect(() => {\n    // @ts-ignore\n    let height = container?.current?.offsetHeight\n    if (height) {\n      // const pageSize =\n      setPageSize(Math.floor((height - RowConfig.rowHeight * 2) / RowConfig.rowHeight) - 1)\n      // getUserAmmPoolTxs()\n    }\n  }, [container])\n  const getUserAmmPoolTxs = React.useCallback(\n    ({ limit = pageSize, offset = 0 }) => {\n      // limit = pageSize;\n      if (ammMap) {\n        const addr = ammMap['AMM-' + market]?.address\n        if (addr) {\n          setIsMyAmmLoading(true)\n          getUserAmmTransaction({\n            address: addr,\n            limit: limit,\n            offset,\n            txStatus: 'processed',\n          })?.then(\n            (res: { userAmmPoolTxs: UserAmmPoolTx[]; totalNum: React.SetStateAction<number> }) => {\n              let _myTradeArray = makeMyAmmMarketArray(market, res.userAmmPoolTxs)\n\n              const formattedArray = _myTradeArray.map((o: any) => {\n                const market = `LP-${o.coinA.simpleName}-${o.coinB.simpleName}`\n                const formattedBalance = Number(volumeToCount(market, o.totalBalance))\n                const price = tokenPrices && tokenPrices[market]\n                const totalDollar = ((formattedBalance || 0) * (price || 0)) as any\n                return {\n                  ...o,\n                  totalDollar: totalDollar,\n                }\n              })\n              setMyAmmMarketArray(formattedArray || [])\n              setAmmUserTotal(res.totalNum)\n              setIsMyAmmLoading(false)\n            },\n          )\n        }\n      }\n    },\n    [ammMap, market, tokenPrices, pageSize],\n  )\n\n  const getRecentAmmPoolTxs = React.useCallback(\n    ({ limit = 15, offset = 0 }) => {\n      if (ammMap) {\n        // const market = list[list.length - 1];\n        const addr = ammMap['AMM-' + market]?.address\n\n        if (addr) {\n          setIsRecentLoading(true)\n          getRecentAmmTransaction({\n            address: addr,\n            limit: limit,\n            offset,\n          })?.then(\n            ({ ammPoolTrades, totalNum }: { ammPoolTrades: AmmPoolTx[]; totalNum: number }) => {\n              let _tradeArray = makeMyAmmMarketArray(market, ammPoolTrades)\n\n              const formattedArray = _tradeArray.map((o: any) => {\n                const market = `LP-${o.coinA.simpleName}-${o.coinB.simpleName}`\n                const formattedBalance = Number(volumeToCount(market, o.totalBalance))\n                const price = tokenPrices && tokenPrices[market]\n                const totalDollar = ((formattedBalance || 0) * (price || 0)) as any\n                return {\n                  ...o,\n                  totalDollar: totalDollar,\n                }\n              })\n              setAmmMarketArray(formattedArray || [])\n              setAmmTotal(totalNum)\n              setIsRecentLoading(false)\n            },\n          )\n        }\n      }\n    },\n    [ammMap, market, tokenPrices],\n  )\n  return {\n    container,\n    isMyAmmLoading,\n    isRecentLoading,\n    ammMarketArray,\n    ammTotal,\n    myAmmMarketArray,\n    ammUserTotal,\n    getUserAmmPoolTxs, //handle page change used\n    getRecentAmmPoolTxs,\n    pageSize,\n    setPageSize,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/modal/AmmPoolModal/index.tsx",
    "content": "import React from 'react'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport {\n  boxLiner,\n  ModalBackButton,\n  ModalCloseButton,\n  SwitchPanelStyled,\n  Toast,\n  ToastType,\n  useOpenModals,\n  useSettings,\n} from '@loopring-web/component-lib'\nimport { myLog, TOAST_TIME } from '@loopring-web/common-resources'\nimport { Box, Link, Modal as MuiModal } from '@mui/material'\nimport styled from '@emotion/styled'\nimport { store, useAmmMap } from '../../index'\nimport { AmmPanelView } from './components/ammPanel'\nimport { useTheme } from '@emotion/react'\nimport { useAmmCommon } from '../../hooks/useractions/hookAmmCommon'\nimport { ChartAndInfoPanel } from './components/chartAndInfo'\nimport { AmmRecordPanel } from './components/ammRecordPanel'\n\nconst BoxStyle = styled(Box)`\n  .rdg {\n    background: var(--color-box);\n    border-bottom-left-radius: ${({ theme }) => theme.unit}px;\n    border-bottom-right-radius: ${({ theme }) => theme.unit}px;\n  }\n`\nconst BoxLinear = styled(SwitchPanelStyled)`\n  && {\n    ${({ theme }) => boxLiner({ theme })};\n\n    .trade-panel {\n      background: initial;\n\n      .react-swipeable-view-container > div {\n        height: initial;\n      }\n    }\n\n    @media only screen and (max-height: 680px) {\n      height: 100vh;\n      overflow: scroll;\n    }\n    @media only screen and (max-width: 768px) {\n      height: 86%;\n      overflow: scroll;\n    }\n  }\n`\nconst Content = withTranslation('common')(\n  ({\n    t,\n    market,\n    setPanelIndex,\n    panelIndex,\n    ...rest\n  }: WithTranslation & { market: string } & any) => {\n    const {\n      modals: {\n        isShowAmm: { type },\n      },\n      setShowAmm,\n    } = useOpenModals()\n    const { isMobile } = useSettings()\n    const theme = useTheme()\n    const {\n      toastOpen,\n      setToastOpen,\n      closeToast,\n      refreshRef,\n      updateAmmPoolSnapshot,\n      updateExitFee,\n      updateJoinFee,\n    } = useAmmCommon({ market })\n    myLog('amm type', type)\n    return (\n      <>\n        <Box\n          display={'flex'}\n          width={'100%'}\n          flexDirection={'column'}\n          alignItems={!isMobile ? 'stretch' : 'center'}\n        >\n          {panelIndex === 1 ? (\n            <ModalBackButton\n              marginTop={'-27px'}\n              marginLeft={1}\n              onBack={() => {\n                setPanelIndex(0)\n              }}\n            />\n          ) : (\n            <>\n              {isMobile && (\n                <Link\n                  position={'absolute'}\n                  variant={'body1'}\n                  sx={{\n                    left: 2 * theme.unit,\n                    top: 2 * theme.unit,\n                    zIndex: 999,\n                  }}\n                  onClick={() => {\n                    setPanelIndex(1)\n                  }}\n                >\n                  {t('labelAMMTransactionsLink')}\n                </Link>\n              )}\n            </>\n          )}\n          <ModalCloseButton\n            onClose={() => {\n              setShowAmm({ isShow: false })\n            }}\n            t={t}\n            {...rest}\n          />\n        </Box>\n        {panelIndex === 0 && (\n          <Box\n            flex={1}\n            alignSelf={'center'}\n            flexDirection={!isMobile ? 'row' : 'column'}\n            alignItems={!isMobile ? 'stretch' : 'center'}\n            justifyContent={'stretch'}\n            position={'relative'}\n            display={'flex'}\n          >\n            {!isMobile && (\n              <Link\n                position={'absolute'}\n                variant={'body1'}\n                sx={{\n                  right: 2 * theme.unit,\n                  top: 2 * theme.unit,\n                  zIndex: 999,\n                }}\n                onClick={() => {\n                  setPanelIndex(1)\n                }}\n              >\n                {t('labelAMMTransactionsLink')}\n              </Link>\n            )}\n            <Box\n              marginBottom={2}\n              display={'flex'}\n              width={isMobile ? '100%' : 'initial'}\n              flexDirection={isMobile ? 'column' : 'row'}\n            >\n              <Toast\n                alertText={toastOpen?.content ?? ''}\n                severity={toastOpen?.type ?? ToastType.success}\n                open={toastOpen?.open ?? false}\n                autoHideDuration={TOAST_TIME}\n                onClose={closeToast}\n              />\n              <AmmPanelView\n                market={market}\n                updateExitFee={updateExitFee}\n                updateJoinFee={updateJoinFee}\n                ammType={type}\n                setToastOpen={setToastOpen}\n                refreshRef={refreshRef}\n                updateAmmPoolSnapshot={updateAmmPoolSnapshot}\n              />\n              <ChartAndInfoPanel market={market} setToastOpen={setToastOpen} />\n            </Box>\n          </Box>\n        )}\n        {panelIndex === 1 && (\n          <BoxStyle display={'flex'} overflow={'scroll'} flex={1} height={'100%'}>\n            {market && <AmmRecordPanel market={market} />}\n          </BoxStyle>\n        )}\n      </>\n    )\n  },\n)\n\nexport const ModalCoinPairPanel = () => {\n  const {\n    modals: {\n      isShowAmm: { isShow },\n    },\n    setShowAmm,\n  } = useOpenModals()\n  const [panelIndex, setPanelIndex] = React.useState<0 | 1>(0)\n  const { ammMap } = useAmmMap()\n  const [market, setMarket] = React.useState<string>('')\n  React.useEffect(() => {\n    if (isShow) {\n      const { symbol } = store.getState().modals.isShowAmm\n      setMarket((market) => {\n        if (symbol !== market) {\n          return ammMap[`AMM-${symbol}`] ? ammMap[`AMM-${symbol}`].market : 'LRC-ETH'\n        } else {\n          return market == '' ? 'LRC-ETH' : market\n        }\n      })\n    }\n    return () => {\n      setPanelIndex(0)\n      setMarket('')\n    }\n  }, [isShow])\n\n  const { isMobile } = useSettings()\n  return (\n    <MuiModal\n      open={isShow}\n      onClose={() => {\n        setShowAmm({ isShow: false })\n      }}\n      aria-labelledby='modal-modal-title'\n      aria-describedby='modal-modal-description'\n    >\n      <BoxLinear\n        width={'80%'}\n        minWidth={isMobile ? 'initial' : 720}\n        maxWidth={isMobile ? 'initial' : 1000}\n        position={'relative'}\n        style={{ alignItems: 'stretch' }}\n      >\n        {market && ammMap['AMM-' + market] ? (\n          <Content\n            market={market.replace('AMM-', '')}\n            panelIndex={panelIndex}\n            setPanelIndex={setPanelIndex}\n          />\n        ) : (\n          <></>\n        )}\n      </BoxLinear>\n    </MuiModal>\n  )\n}\n"
  },
  {
    "path": "packages/core/src/modal/DualModal/index.tsx",
    "content": "import { WithTranslation, withTranslation } from 'react-i18next'\nimport {\n  boxLiner,\n  CoinIcons,\n  ConfirmInvestDualAutoRisk,\n  ConfirmInvestDualDipRisk,\n  ConfirmInvestDualGainRisk,\n  ConfirmInvestDualRisk,\n  CountDownIcon,\n  DualWrap,\n  DualWrapProps,\n  ModalCloseButton,\n  SwitchPanelStyled,\n  Toast,\n  TOASTOPEN,\n  ToastType,\n  useOpenModals,\n  useSettings,\n} from '@loopring-web/component-lib'\nimport { useHistory, useLocation } from 'react-router-dom'\nimport { Box, Divider, Modal as MuiModal, Typography } from '@mui/material'\nimport styled from '@emotion/styled'\nimport {\n  DualInvestConfirmType,\n  DualViewType,\n  TOAST_TIME,\n  TokenType,\n} from '@loopring-web/common-resources'\nimport { DUAL_TYPE } from '@loopring-web/loopring-sdk'\nimport { confirmation } from '../../stores'\nimport React from 'react'\n\nconst BoxLinear = styled(SwitchPanelStyled)`\n  && {\n    ${({ theme }) => boxLiner({ theme })};\n\n    .trade-panel {\n      background: initial;\n\n      .react-swipeable-view-container > div {\n        height: initial;\n      }\n    }\n\n    @media only screen and (max-height: 680px) {\n      height: 100vh;\n      overflow: scroll;\n    }\n    @media only screen and (max-width: 768px) {\n      height: 86%;\n      overflow: scroll;\n    }\n  }\n`\n\nexport const ModalDualPanel = withTranslation('common')(\n  ({\n    t,\n    viewType,\n    dualTradeProps,\n    dualToastOpen,\n    closeDualToast,\n    isBeginnerMode,\n    confirmDualAutoInvest,\n    setConfirmDualAutoInvest,\n    ...rest\n  }: WithTranslation & {\n    viewType: DualViewType | undefined\n    dualTradeProps: DualWrapProps<any, any, any>\n    dualToastOpen?: TOASTOPEN\n    closeDualToast?: (state: boolean) => void\n    isBeginnerMode: boolean\n    confirmDualAutoInvest: boolean\n    setConfirmDualAutoInvest: (state: boolean) => void\n  }) => {\n    const history = useHistory()\n    const { search, pathname } = useLocation()\n    const searchParams = new URLSearchParams(search)\n    const {\n      modals: { isShowDual },\n      setShowDual,\n    } = useOpenModals()\n    const { isShow, dualInfo } = isShowDual ?? {}\n    const { isMobile, coinJson } = useSettings()\n    const [showDualAlert, setShowAlert] = React.useState(false)\n    React.useEffect(() => {\n      // @ts-ignore\n      if (viewType && viewType !== '') {\n        setShowAlert(true)\n      }\n    }, [viewType])\n    // const [confirmDualInvest, setConfirmDualInvest] = React.useState<undefined | string | false>(\n    //   undefined,\n    // )\n    //\n    const {\n      confirmation: {\n        confirmDualAutoInvest: _confirmDualAutoInvest,\n        confirmedDualInvestV2,\n        confirmDualDipInvest,\n        confirmDualGainInvest,\n        showAutoDefault\n      },\n      confirmDualAutoInvest: confirmDualAutoInvestFun,\n      confirmDualInvest: confirmDualInvestFun,\n      confirmDualDipInvest: confirmDualDipInvestFun,\n      confirmDualGainInvest: confirmDualGainInvestFun,\n      setShowAutoDefault,\n    } = confirmation.useConfirmation()\n\n    return (\n      <>\n        <MuiModal\n          // open={true}\n          open={isShow}\n          onClose={() => {\n            setShowDual({ isShow: false, dualInfo: undefined })\n          }}\n          aria-labelledby='modal-modal-title'\n          aria-describedby='modal-modal-description'\n        >\n          <BoxLinear\n            width={isMobile ? '90%' : 'var(--modal-width)'}\n            height={isMobile ? 'auto' : 'inherit'}\n            // width={\"80%\"}\n            // minWidth={isMobile ? \"initial\" : 720}\n            // maxWidth={isMobile ? \"initial\" : 1000}\n            position={'relative'}\n            style={{ alignItems: 'stretch' }}\n          >\n            <ModalCloseButton\n              onClose={() => {\n                setShowDual({ isShow: false, dualInfo: undefined })\n              }}\n              t={t}\n              {...rest}\n            />\n            <Box\n              width={'100%'}\n              display={'flex'}\n              position={'relative'}\n              marginTop={'var(--toolbar-row-padding-minus)'}\n              minHeight={'var(--toolbar-row-height)'}\n              paddingX={3}\n            >\n              <Box component={'h3'} display={'flex'} flexDirection={'row'} alignItems={'center'}>\n                {dualInfo?.productId && (\n                  <>\n                    <Typography component={'span'} display={'inline-flex'}>\n                      {/* eslint-disable-next-line react/jsx-no-undef */}\n                      <CoinIcons\n                        type={TokenType.dual}\n                        size={32}\n                        tokenIcon={[coinJson[dualInfo.sellSymbol], coinJson[dualInfo.buySymbol]]}\n                      />\n                    </Typography>\n                    <Typography component={'span'} flexDirection={'column'} display={'flex'}>\n                      <Typography component={'span'} display={'inline-flex'} color={'textPrimary'}>\n                        {t(\n                          dualInfo.__raw__.info.dualType === DUAL_TYPE.DUAL_BASE\n                            ? 'labelDualInvestBaseTitle'\n                            : 'labelDualInvestQuoteTitle',\n                          {\n                            symbolA: dualInfo.sellSymbol,\n                            symbolB: dualInfo.buySymbol,\n                          },\n                        )}\n                      </Typography>\n                    </Typography>\n                  </>\n                )}\n              </Box>\n              <Box alignSelf={'flex-end'} sx={{ display: 'none' }}>\n                {/*sx={{ display: \"none\" }}*/}\n                <CountDownIcon\n                  onRefreshData={dualTradeProps.onRefreshData}\n                  // viewType={viewType}\n                  ref={dualTradeProps.refreshRef}\n                />\n              </Box>\n            </Box>\n            <Divider sx={{ marginX: 0 }} />\n            <Box\n              flex={1}\n              // flexDirection={!isMobile ? \"row\" : \"column\"}\n              alignItems={!isMobile ? 'flex-start' : 'center'}\n              position={'relative'}\n              display={'flex'}\n              paddingTop={2}\n              paddingBottom={1}\n              sx={\n                isMobile\n                  ? {\n                      maxHeight: 'initial',\n                      overflowY: 'initial',\n                    }\n                  : { maxHeight: 'var(--lage-modal-height)', overflowY: 'scroll' }\n              }\n            >\n              <DualWrap\n                isBeginnerMode={isBeginnerMode}\n                {...{ ...rest, ...dualTradeProps }}\n              />\n            </Box>\n            <Toast\n              alertText={dualToastOpen?.content ?? ''}\n              severity={dualToastOpen?.type ?? ToastType.success}\n              open={dualToastOpen?.open ?? false}\n              autoHideDuration={TOAST_TIME}\n              onClose={() => {\n                if (closeDualToast) {\n                  closeDualToast(false)\n                }\n              }}\n            />\n          </BoxLinear>\n        </MuiModal>\n        <ConfirmInvestDualAutoRisk\n          open={confirmDualAutoInvest}\n          handleClose={(_e, isAgree) => {\n            if (!isAgree) {\n              dualTradeProps.onChangeEvent({\n                tradeData: {\n                  ...dualTradeProps.dualCalcData?.coinSell,\n                  isRenew: false,\n                } as any,\n              })\n            } else {\n              dualTradeProps.onChangeEvent({\n                tradeData: {\n                  ...dualTradeProps.dualCalcData?.coinSell,\n                  isRenew: true,\n                } as any,\n              })\n              confirmDualAutoInvestFun()\n            }\n            setConfirmDualAutoInvest(false)\n          }}\n        />\n\n        <ConfirmInvestDualRisk\n          open={\n            !confirmedDualInvestV2 &&\n            showDualAlert &&\n            [DualViewType.All, DualViewType.DualBegin, DualViewType.DualBTC].includes(\n              viewType as any,\n            )\n          }\n          USDCOnly={confirmedDualInvestV2 === 'USDCOnly'}\n          handleClose={(_e, isAgree: DualInvestConfirmType | undefined) => {\n            if (!isAgree) {\n              setShowAlert(false)\n              searchParams.set('viewType', '')\n              history.goBack()\n              history.push(pathname + '?' + searchParams.toString())\n            } else {\n              confirmDualInvestFun(isAgree)\n              setShowAlert(false)\n            }\n          }}\n        />\n        <ConfirmInvestDualGainRisk\n          open={\n            !confirmDualGainInvest &&\n            showDualAlert &&\n            [DualViewType.DualGain].includes(viewType as any)\n          }\n          handleClose={(_e, isAgree) => {\n            if (!isAgree) {\n              setShowAlert(false)\n              // history.goBack()\n              searchParams.set('viewType', '')\n              history.push(pathname + '?' + searchParams.toString())\n            } else {\n              confirmDualGainInvestFun()\n              setShowAlert(false)\n            }\n          }}\n        />\n        <ConfirmInvestDualDipRisk\n          open={\n            !confirmDualDipInvest &&\n            showDualAlert &&\n            [DualViewType.DualDip].includes(viewType as any)\n          }\n          handleClose={(_e, isAgree) => {\n            if (!isAgree) {\n              setShowAlert(false)\n              searchParams.set('viewType', '')\n              // history.goBack()\n              history.push(pathname + '?' + searchParams.toString())\n            } else {\n              confirmDualDipInvestFun()\n              setShowAlert(false)\n            }\n          }}\n        />\n      </>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/core/src/modal/RedPacketModal/hook.tsx",
    "content": "/* eslint-disable react/jsx-pascal-case */\nimport {\n  AccountStep,\n  RedPacketDetailProps,\n  RedPacketOpenedProps,\n  RedPacketOpenProps,\n  RedPacketQRCodeProps,\n  RedPacketTimeoutProps,\n  RedPacketClockProps,\n  RedPacketViewStep,\n  useOpenModals,\n  RedPacketDetailLimit,\n  NFTMedia,\n  BoxNFT,\n  RedPacketBlindBoxDetailProps,\n  RedPacketBlindBoxDetailTypes,\n  RedPacketNFTDetailLimit,\n  RedPacketBlindBoxLimit,\n} from '@loopring-web/component-lib'\nimport React, { useState } from 'react'\nimport {\n  AssetTabIndex,\n  CLAIM_TYPE,\n  CustomError,\n  EmptyValueTag,\n  ErrorMap,\n  Exchange,\n  getShortAddr,\n  getValuePrecisionThousand,\n  myLog,\n  NFTWholeINFO,\n  RouterPath,\n  UIERROR_CODE,\n  YEAR_DAY_MINUTE_FORMAT,\n} from '@loopring-web/common-resources'\nimport { store, useAccount, useSystem, useTokenMap } from '../../stores'\nimport {\n  amountStrCallback,\n  amountStrNFTCallback,\n  getUserNFTReceiveList,\n  getUserReceiveList,\n  useOpenRedpacket,\n  volumeToCountAsBigNumber,\n} from '../../hooks'\nimport { useTranslation } from 'react-i18next'\nimport moment from 'moment'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { LoopringAPI } from '../../api_wrapper'\nimport { useRedPacketHistory } from '../../stores/localStore/redPacket'\nimport { Box } from '@mui/material'\nimport { getIPFSString } from '../../utils'\nimport { NFT_IMAGE_SIZES, toBig } from '@loopring-web/loopring-sdk'\nimport { useHistory } from 'react-router-dom'\nimport { ClaimCommands, claimServices, redpacketService } from '../../services'\n\nexport function useRedPacketModal() {\n  const ref = React.createRef()\n\n  const {\n    modals: {\n      // isShowNFTDetail,\n      isShowRedPacket: { info, isShow, step },\n    },\n    setShowRedPacket,\n    setShowAccount,\n  } = useOpenModals()\n  const { account } = useAccount()\n  const { updateRedpacketHash } = useRedPacketHistory()\n  const { chainId, baseURL } = useSystem()\n  const { tokenMap, idIndex, coinMap } = useTokenMap()\n  const { t } = useTranslation('common')\n  const { callOpen } = useOpenRedpacket()\n  const subject = React.useMemo(() => claimServices.onSocket(), [])\n\n  const [detail, setDetail] = React.useState<undefined | sdk.LuckTokenClaimDetail>(undefined)\n  const [blinBoxDetail, setBlindBoxDetail] = React.useState<undefined | any>(undefined)\n  const [qrcode, setQrcode] = React.useState<undefined | sdk.LuckyTokenItemForReceive>(undefined)\n  const ImageEle = React.useMemo(() => {\n    const _info = info as sdk.LuckyTokenItemForReceive\n    if (isShow && _info && _info.isNft && _info.nftTokenInfo) {\n      return (\n        <BoxNFT flex={1} position={'relative'} className={'redPacketNFT'}>\n          <Box\n            position={'absolute'}\n            top={0}\n            right={0}\n            bottom={0}\n            left={0}\n            display={'flex'}\n            alignItems={'center'}\n            justifyContent={'center'}\n          >\n            <NFTMedia\n              ref={ref}\n              item={_info.nftTokenInfo as Partial<NFTWholeINFO>}\n              shouldPlay={true}\n              onNFTError={() => undefined}\n              isOrigin={true}\n              getIPFSString={getIPFSString}\n              baseURL={baseURL}\n            />\n          </Box>\n        </BoxNFT>\n      )\n    }\n  }, [info?.isNft, info?.nftDta, info])\n  const amountStr = React.useMemo(() => {\n    const _info = info as sdk.LuckyTokenItemForReceive\n    let symbol\n    if (\n      isShow &&\n      _info &&\n      _info.tokenAmount &&\n      _info.type.mode !== sdk.LuckyTokenClaimType.BLIND_BOX\n    ) {\n      if (_info.isNft) {\n        symbol = 'NFT'\n        // @ ts-ignore\n        // symbol = (_info.nftTokenInfo as any)?.metadata?.base?.name ?? \"NFT\";\n        const amount = getValuePrecisionThousand(\n          _info.tokenAmount.totalAmount,\n          0,\n          0,\n          undefined,\n          false,\n          {\n            floor: false,\n            // isTrade: true,\n          },\n        )\n        return amount + ' ' + symbol\n      } else {\n        const token = tokenMap[idIndex[_info?.tokenId] ?? '']\n        const symbol = token.symbol\n        const amount = getValuePrecisionThousand(\n          volumeToCountAsBigNumber(symbol, _info.tokenAmount.totalAmount as any),\n          token.precision,\n          token.precision,\n          undefined,\n          false,\n          {\n            floor: false,\n            // isTrade: true,\n          },\n        )\n        return amount + ' ' + symbol\n      }\n    }\n    return ''\n  }, [info?.tokenId, info?.tokenAmount, isShow, info])\n  const amountClaimStr = React.useMemo(() => {\n    const _info = info as sdk.LuckyTokenItemForReceive & {\n      claimAmount: string\n    }\n    let symbol\n    if (isShow && _info && _info.claimAmount) {\n      if (_info.isNft) {\n        symbol = 'NFT'\n        // (_info.nftTokenInfo as any)?.metadata?.base?.name ?? \"NFT\";\n        const amount = getValuePrecisionThousand(_info.claimAmount, 0, 0, undefined, false, {\n          floor: false,\n          // isTrade: true,\n        })\n        return amount + ' ' + symbol\n      } else {\n        const token = tokenMap[idIndex[_info?.tokenId] ?? '']\n        symbol = token.symbol\n        const amount = getValuePrecisionThousand(\n          volumeToCountAsBigNumber(symbol, _info.claimAmount as any),\n          token.precision,\n          token.precision,\n          undefined,\n          false,\n          {\n            floor: false,\n            // isTrade: true,\n          },\n        )\n        return amount + ' ' + symbol\n      }\n    }\n    return ''\n\n    // tokenMap[]\n  }, [info?.tokenId, info?.claimAmount])\n\n  const textSendBy = React.useMemo(() => {\n    const _info = info as sdk.LuckyTokenItemForReceive\n    if (isShow && _info && _info.validSince > Date.now()) {\n      const date = moment(new Date(_info.validSince)).format(YEAR_DAY_MINUTE_FORMAT)\n      return t('labelRedPacketStartWithTime', {\n        time: date,\n      })\n    } else {\n      if (_info && _info.type.mode === sdk.LuckyTokenClaimType.BLIND_BOX) {\n        return ''\n      } else {\n        return t('labelLuckyRedPacketStarted')\n      }\n    }\n  }, [info?.validSince, info?.createdAt])\n\n  const redPacketTimeoutProps: RedPacketTimeoutProps | undefined = React.useMemo(() => {\n    const _info = info as sdk.LuckyTokenItemForReceive\n    if (\n      isShow &&\n      info &&\n      step === RedPacketViewStep.TimeOutPanel\n      // &&\n      // (_info.status === sdk.LuckyTokenItemStatus.COMPLETED ||\n      //   _info.status === sdk.LuckyTokenItemStatus.OVER_DUE)\n    ) {\n      return {\n        ImageEle,\n        memo: _info.info.memo,\n        sender: _info.sender?.ens ? _info.sender?.ens : getShortAddr(_info.sender?.address),\n        viewDetail: () => {\n          if (_info.type.mode === sdk.LuckyTokenClaimType.BLIND_BOX) {\n            LoopringAPI.luckTokenAPI\n              ?.getLuckTokenDetail(\n                {\n                  hash: _info.hash,\n                  serialNo: _info.serialNo,\n                },\n                account.apiKey,\n              )\n              .then((response) => {\n                setShowRedPacket({\n                  isShow,\n                  step: RedPacketViewStep.BlindBoxDetail,\n                  info: {\n                    ...response.detail.luckyToken,\n                  },\n                })\n              })\n          } else {\n            LoopringAPI.luckTokenAPI\n              ?.getLuckTokenDetail(\n                {\n                  hash: _info.hash,\n                  serialNo: _info.serialNo,\n                },\n                account.apiKey,\n              )\n              .then((response) => {\n                setShowRedPacket({\n                  isShow,\n                  step: RedPacketViewStep.DetailPanel,\n                  info: {\n                    ...response.detail.luckyToken,\n                  },\n                })\n              })\n          }\n        },\n      }\n    }\n    return undefined\n  }, [info, account.accAddress, isShow, step])\n  const redPacketOpenProps: RedPacketOpenProps | undefined = React.useMemo(() => {\n    const _info = info as sdk.LuckyTokenItemForReceive & {\n      referrer?: string\n    }\n    if (isShow && info && step === RedPacketViewStep.OpenPanel) {\n      if (_info?.status == sdk.LuckyTokenItemStatus.COMPLETED) {\n      } else if (_info.status === sdk.LuckyTokenItemStatus.OVER_DUE) {\n        setShowRedPacket({\n          isShow,\n          step: RedPacketViewStep.TimeOutPanel,\n          info: _info,\n        })\n      } else if (_info?.hash) {\n        return {\n          ImageEle,\n          memo: _info.info.memo,\n          amountStr,\n          sender: _info.sender?.ens ? _info.sender?.ens : getShortAddr(_info.sender?.address),\n          viewDetail: info['hideViewDetail']\n            ? undefined\n            : () => {\n                if (_info.type.mode === sdk.LuckyTokenClaimType.BLIND_BOX) {\n                  setShowRedPacket({\n                    isShow,\n                    step: RedPacketViewStep.BlindBoxDetail,\n                    info: _info,\n                  })\n                } else {\n                  setShowRedPacket({\n                    isShow,\n                    step: RedPacketViewStep.DetailPanel,\n                    info: _info,\n                  })\n                }\n              },\n\n          onOpen: callOpen,\n        }\n      }\n    }\n    return undefined\n  }, [info, amountStr, account.accAddress, isShow, step])\n  const redPacketOpenedProps: RedPacketOpenedProps | undefined = React.useMemo(() => {\n    const _info = info as sdk.LuckyTokenItemForReceive & {\n      claimAmount?: string\n    }\n\n    if (isShow && info && step === RedPacketViewStep.OpenedPanel && _info?.hash) {\n      let myAmountStr: string | undefined = undefined\n      let symbol: string\n      if (_info?.claimAmount) {\n        if (_info.isNft) {\n          symbol = 'NFT'\n          // @ts-ignore\n          // symbol = _info.nftTokenInfo?.metadata?.base?.name ?? \"NFT\";\n          myAmountStr =\n            getValuePrecisionThousand(\n              volumeToCountAsBigNumber(symbol, _info.claimAmount as any),\n              0,\n              0,\n              undefined,\n              false,\n              {\n                floor: false,\n                // isTrade: true,\n              },\n            ) +\n            ' ' +\n            symbol\n        } else {\n          let tokenInfo = tokenMap[idIndex[_info?.tokenId] ?? '']\n          symbol = tokenInfo.symbol\n          myAmountStr =\n            getValuePrecisionThousand(\n              volumeToCountAsBigNumber(symbol, _info.claimAmount as any),\n              tokenInfo.precision,\n              tokenInfo.precision,\n              undefined,\n              false,\n              {\n                floor: false,\n                // isTrade: true,\n              },\n            ) +\n            ' ' +\n            symbol\n        }\n      }\n      return {\n        ImageEle,\n        memo: _info.info.memo,\n        amountStr,\n        myAmountStr,\n        sender: _info.sender?.ens ? _info.sender?.ens : getShortAddr(_info.sender?.address),\n        viewDetail: () => {\n          if (_info.type.mode === sdk.LuckyTokenClaimType.BLIND_BOX) {\n            setShowRedPacket({\n              isShow,\n              step: RedPacketViewStep.BlindBoxDetail,\n              info: _info,\n            })\n          } else {\n            setShowRedPacket({\n              isShow,\n              step: RedPacketViewStep.DetailPanel,\n              info: _info,\n            })\n          }\n        },\n        isBlindBox: _info.type.mode === sdk.LuckyTokenClaimType.BLIND_BOX,\n      }\n    }\n    return undefined\n  }, [info, amountClaimStr, amountStr, account.accAddress, isShow, step])\n  let redPacketClockProps: RedPacketClockProps | undefined = React.useMemo(() => {\n    const _info = info as sdk.LuckyTokenItemForReceive & {\n      claimAmount?: string\n    }\n    if (isShow && info && step === RedPacketViewStep.RedPacketClock && _info?.hash) {\n      return {\n        memo: _info.info.memo,\n        amountStr,\n        amountClaimStr,\n        sender: _info.sender?.ens ? _info.sender?.ens : getShortAddr(_info.sender?.address),\n        validSince: _info.validSince,\n        showRedPacket: () => {\n          setShowRedPacket({\n            isShow: true,\n            step: RedPacketViewStep.OpenPanel,\n            info: _info,\n          })\n        },\n        ImageEle,\n      }\n    }\n\n    return undefined\n  }, [info, amountClaimStr, amountStr, account.accAddress, isShow, step])\n\n  const [opendBlindBoxCount, setOpendBlindBoxCount] = React.useState(0)\n  React.useState<undefined | sdk.LuckTokenClaimDetail>(undefined)\n\n  const redPacketDetailCall = React.useCallback(\n    async ({\n      limit = detail?.luckyToken.isNft ? RedPacketNFTDetailLimit : RedPacketDetailLimit,\n      offset = 0,\n    }: {\n      limit?: number\n      offset?: number\n    }) => {\n      setDetail(undefined)\n      const _info = info as sdk.LuckyTokenItemForReceive & {\n        claimAmount?: string\n      }\n      if (_info?.hash && LoopringAPI.luckTokenAPI) {\n        try {\n          const response = await LoopringAPI.luckTokenAPI.getLuckTokenDetail(\n            {\n              accountId: account.accountId,\n              hash: _info.hash,\n              serialNo: _info.serialNo,\n              limit,\n              offset,\n              // fromId: 0,\n              showHelper: true,\n            } as any,\n            account.apiKey,\n          )\n\n          if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.RedPacketOpen_Failed,\n              error: {\n                code: (response as sdk.RESULT_INFO)?.code,\n                msg: (response as sdk.RESULT_INFO)?.message,\n                ...(response instanceof Error\n                  ? {\n                      message: response?.message,\n                      stack: response?.stack,\n                    }\n                  : response ?? {}),\n              },\n            })\n          } else {\n            if (\n              response.detail?.claimAmount?.toString() !== '0' &&\n              _info?.type.scope === sdk.LuckyTokenViewType.PUBLIC\n            ) {\n              updateRedpacketHash({\n                hash: _info?.hash,\n                chainId: chainId as any,\n                luckToken: _info,\n                claimAmount: response.detail.claimAmount.toString(),\n                address: account.accAddress,\n              })\n            }\n            const detail = (response as any).detail\n            const luckTokenInfo: sdk.LuckyTokenItemForReceive = detail.luckyToken\n            if (luckTokenInfo) {\n              setDetail(detail)\n              // setShowRedPacket({\n              //   isShow: true,\n              //   step: RedPacketViewStep.DetailPanel,\n              // });\n            } else {\n              const error = new CustomError(ErrorMap.ERROR_REDPACKET_EMPTY)\n              setShowAccount({\n                isShow: true,\n                step: AccountStep.RedPacketOpen_Failed,\n                error: {\n                  code: UIERROR_CODE.ERROR_REDPACKET_EMPTY,\n                  msg: error.message,\n                },\n              })\n            }\n          }\n        } catch (error: any) {\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.RedPacketOpen_Failed,\n            error: {\n              code: UIERROR_CODE.UNKNOWN,\n              msg: error?.message,\n              // @ts-ignore\n              ...(error instanceof Error\n                ? {\n                    message: error?.message,\n                    stack: error?.stack,\n                  }\n                : error ?? {}),\n            },\n          })\n          setShowRedPacket({ isShow: false })\n        }\n      }\n    },\n    [isShow, step, info],\n  )\n\n  const [blindBoxType, setBlindBoxType] = React.useState(\n    undefined as RedPacketBlindBoxDetailTypes | undefined,\n  )\n  const [viewDetailFrom, setViewDetailFrom] = React.useState(\n    undefined as RedPacketBlindBoxDetailTypes | undefined,\n  )\n  const [wonPrizeInfo, setWonPrizeInfo] = React.useState(\n    undefined as\n      | {\n          name: string\n          url: string\n          isNFT: true\n        }\n      | {\n          amountStr: string\n          tokenURL: string\n          tokenName: string\n          isNFT: false\n        }\n      | undefined,\n  )\n  const redPacketBlindBoxDetailCall = React.useCallback(\n    async ({ limit = RedPacketBlindBoxLimit, offset = 0 }: { limit?: number; offset?: number }) => {\n      setDetail(undefined)\n      setBlindBoxDetail(undefined)\n      setWonPrizeInfo(undefined)\n      const _info = info as sdk.LuckyTokenItemForReceive & {\n        claimAmount?: string\n      }\n      setShowAccount({\n        isShow: true,\n        step: AccountStep.RedPacketOpen_Claim_In_Progress,\n      })\n      if (_info?.hash && LoopringAPI.luckTokenAPI) {\n        try {\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.RedPacketOpen_In_Progress,\n          })\n          const responseTemp = await LoopringAPI.luckTokenAPI.getBlindBoxDetail(\n            {\n              accountId: account.accountId,\n              hash: _info.hash,\n              serialNo: _info.serialNo,\n              limit: 500,\n              offset: 0,\n              showHelper: true,\n            } as any,\n            account.apiKey,\n          )\n          setOpendBlindBoxCount((responseTemp.raw_data as any).claims.length)\n          let response = await LoopringAPI.luckTokenAPI.getLuckTokenDetail(\n            {\n              accountId: account.accountId,\n              hash: _info.hash,\n              serialNo: _info.serialNo,\n              limit: RedPacketNFTDetailLimit,\n              offset,\n              // fromId: 0,\n              showHelper: true,\n            } as any,\n            account.apiKey,\n          )\n          if ((response as any).detail.blindBoxStatus !== '') {\n            updateRedpacketHash({\n              hash: _info?.hash,\n              chainId: chainId as any,\n              luckToken: _info,\n              claimAmount: response.detail.claimAmount.toString(),\n              address: account.accAddress,\n              blindboxClaimed: true,\n            })\n          }\n          const response2 = await LoopringAPI.luckTokenAPI.getBlindBoxDetail(\n            {\n              accountId: account.accountId,\n              hash: _info.hash,\n              serialNo: _info.serialNo,\n              limit: RedPacketBlindBoxLimit,\n              offset,\n            } as any,\n            account.apiKey,\n          )\n\n          if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.RedPacketOpen_Failed,\n              error: {\n                code: (response as sdk.RESULT_INFO)?.code,\n                msg: (response as sdk.RESULT_INFO)?.message,\n                ...(response instanceof Error\n                  ? {\n                      message: response?.message,\n                      stack: response?.stack,\n                    }\n                  : response ?? {}),\n              },\n            })\n            setShowRedPacket({ isShow: false })\n          } else if (\n            (response2 as sdk.RESULT_INFO).code ||\n            (response2 as sdk.RESULT_INFO).message\n          ) {\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.RedPacketOpen_Failed,\n              error: {\n                code: (response2 as sdk.RESULT_INFO)?.code,\n                msg: (response2 as sdk.RESULT_INFO)?.message,\n                ...(response2 instanceof Error\n                  ? {\n                      message: response2?.message,\n                      stack: response2?.stack,\n                    }\n                  : response2 ?? {}),\n              },\n            })\n            setShowRedPacket({ isShow: false })\n          } else {\n            const now = new Date().getTime()\n            if (now < response.detail.luckyToken.validSince) {\n              setBlindBoxType('Not Started')\n            } else if (\n              now >= response.detail.luckyToken.validSince &&\n              now < response.detail.luckyToken.validUntil\n            ) {\n              setBlindBoxType('Blind Box Started')\n            } else if (\n              now > response.detail.luckyToken.validUntil ||\n              response.detail.luckyToken.status === sdk.LuckyTokenItemStatus.COMPLETED\n            ) {\n              if (\n                (response2.raw_data as any).blindBoxStatus === sdk.BlindBoxStatus.NOT_OPENED &&\n                Date.now() > (response2.raw_data as any).luckyToken.validUntil\n              ) {\n                const claimLuckyTokenResponse =\n                  await LoopringAPI.luckTokenAPI?.sendLuckTokenClaimLuckyToken({\n                    request: {\n                      hash: _info.hash,\n                      claimer: account.accAddress,\n                      referrer: '',\n                      serialNo: _info.serialNo\n                    },\n                    eddsaKey: account.eddsaKey.sk,\n                    apiKey: account.apiKey,\n                  } as any)\n                if (\n                  (claimLuckyTokenResponse as sdk.RESULT_INFO).code ||\n                  (claimLuckyTokenResponse as sdk.RESULT_INFO).message ||\n                  (claimLuckyTokenResponse as any).amount === '0'\n                ) {\n                  setBlindBoxType('Lottery Started and Not Win Lottery')\n                } else {\n                  setBlindBoxType('Lottery Started and Win Lottery')\n\n                  if (response.detail.luckyToken.isNft) {\n                    setWonPrizeInfo({\n                      name: response.detail.luckyToken.nftTokenInfo?.metadata?.base.name ?? '',\n                      url:\n                        response.detail.luckyToken.nftTokenInfo?.metadata?.imageSize.original ?? '',\n                      isNFT: true,\n                    })\n                  } else {\n                    const token = tokenMap[idIndex[response.detail.tokenId]]\n                    const coin = coinMap[idIndex[response.detail.tokenId]]\n                    const amount = getValuePrecisionThousand(\n                      sdk.toBig((claimLuckyTokenResponse as any).amount).div('1e' + token.decimals),\n                      token.precision,\n                      token.precision,\n                      undefined,\n                      false,\n                      {\n                        floor: false,\n                      },\n                    )\n                    setWonPrizeInfo({\n                      tokenURL: 'tokenIcon',\n                      tokenName: coin?.simpleName ?? '',\n                      amountStr: amount + ' ' + (coin?.simpleName ?? ''),\n                      isNFT: false,\n                    })\n                  }\n                }\n                // refetch\n                response = await LoopringAPI.luckTokenAPI.getLuckTokenDetail(\n                  {\n                    accountId: account.accountId,\n                    hash: _info.hash,\n                    serialNo: _info.serialNo,\n                    limit,\n                    offset,\n                    // fromId: 0,\n                    showHelper: true,\n                  } as any,\n                  account.apiKey,\n                )\n                redpacketService.refresh()\n              } else {\n                setBlindBoxType('Lottery Started')\n              }\n            }\n\n            if (\n              response.detail?.claimAmount?.toString() !== '0' &&\n              _info?.type.scope === sdk.LuckyTokenViewType.PUBLIC\n            ) {\n              updateRedpacketHash({\n                hash: _info?.hash,\n                chainId: chainId as any,\n                luckToken: _info,\n                claimAmount: response.detail.claimAmount.toString(),\n                address: account.accAddress,\n              })\n            }\n            const detail = (response as any).detail\n            const luckTokenInfo: sdk.LuckyTokenItemForReceive = detail.luckyToken\n\n            if (luckTokenInfo && response2.raw_data) {\n              setDetail(detail)\n              setBlindBoxDetail(response2.raw_data)\n              setShowAccount({\n                isShow: false,\n              })\n            } else {\n              const error = new CustomError(ErrorMap.ERROR_REDPACKET_EMPTY)\n              setShowAccount({\n                isShow: true,\n                step: AccountStep.RedPacketOpen_Failed,\n                error: {\n                  code: UIERROR_CODE.ERROR_REDPACKET_EMPTY,\n                  msg: error.message,\n                },\n              })\n            }\n          }\n        } catch (error: any) {\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.RedPacketOpen_Failed,\n            error: {\n              code: UIERROR_CODE.UNKNOWN,\n              msg: error?.message,\n              // @ts-ignore\n              ...(error instanceof Error\n                ? {\n                    message: error?.message,\n                    stack: error?.stack,\n                  }\n                : error ?? {}),\n            },\n          })\n          setShowRedPacket({ isShow: false })\n        }\n      }\n    },\n    [isShow, step, info],\n  )\n\n  const redPacketQrCodeCall = React.useCallback(async () => {\n    setQrcode(undefined)\n    if (info?.hash && LoopringAPI.luckTokenAPI) {\n      const response = await LoopringAPI.luckTokenAPI.getLuckTokenDetail(\n        {\n          account: account.accountId,\n          hash: info.hash,\n          serialNo: info.serialNo,\n          fromId: 0,\n          showHelper: true,\n        } as any,\n        account.apiKey,\n      )\n      const luckTokenInfo = response.detail.luckyToken as sdk.LuckyTokenItemForReceive\n      setQrcode(luckTokenInfo)\n    }\n  }, [isShow, step, info])\n  const [page, setPage] = useState(1)\n  const [pageForBlindbox, setPageForBlindbox] = useState(1)\n  const history = useHistory()\n  React.useEffect(() => {\n    if (isShow) {\n      const info = store.getState().modals.isShowRedPacket.info\n      if (step === RedPacketViewStep.DetailPanel) {\n        setPage(1)\n        redPacketDetailCall({})\n      } else if (step === RedPacketViewStep.BlindBoxDetail) {\n        setPage(1)\n        redPacketBlindBoxDetailCall({})\n      } else if (step === RedPacketViewStep.QRCodePanel && info?.hash) {\n        if (info?.id) {\n          setQrcode(info as any)\n        } else {\n          redPacketQrCodeCall()\n        }\n      }\n    }\n  }, [step, isShow])\n\n  const redPacketDetailProps = React.useMemo(() => {\n    const _info = info as sdk.LuckyTokenItemForReceive & {\n      claimAmount?: string\n    }\n    const redPacketType =\n      _info && _info.type\n        ? _info.type.mode === sdk.LuckyTokenClaimType.RELAY\n          ? 'relay'\n          : _info.type.partition === sdk.LuckyTokenAmountType.RANDOM\n          ? 'lucky'\n          : 'normal'\n        : 'normal'\n\n    // _info && _info.type && console.log('_info.type.partition', _info.type.partition)\n    if (\n      isShow &&\n      info &&\n      step === RedPacketViewStep.DetailPanel &&\n      _info?.hash &&\n      LoopringAPI.luckTokenAPI &&\n      detail &&\n      detail.luckyToken\n    ) {\n      const isShouldSharedRely =\n        detail.luckyToken.type.mode === sdk.LuckyTokenClaimType.RELAY &&\n        // detail.luckyToken.type.scope === sdk.LuckyTokenViewType.PRIVATE &&\n        ![\n          sdk.LuckyTokenItemStatus.OVER_DUE,\n          sdk.LuckyTokenItemStatus.FAILED,\n          sdk.LuckyTokenItemStatus.COMPLETED,\n        ].includes(detail.luckyToken.status)\n      const showRelayText =\n        detail.luckyToken.type.mode === sdk.LuckyTokenClaimType.RELAY &&\n        account.accountId !== _info.sender.accountId\n\n      let myAmountStr: string | undefined = undefined\n      const relyNumber = detail.helpers?.length\n      const value =\n        detail.helpers?.reduce((prev, item) => {\n          // @ts-ignore\n          return prev.plus(item.amount)\n        }, sdk.toBig(0)) ?? 0\n      let relyAmount: string | undefined = undefined\n      let symbol, list\n      // if (detail.claimAmount.toString() !== \"0\") {\n      if (_info.isNft) {\n        symbol = detail.claimAmount == 1 ? 'NFT' : 'NFTs'\n        // @ts-ignore\n        // const symbol = _info.nftTokenInfo?.metadata?.base?.name ?? \"NFT\";\n        myAmountStr = sdk.toBig(detail.claimAmount).isZero()\n          ? EmptyValueTag\n          : getValuePrecisionThousand(detail.claimAmount, 0, 0, undefined, false, {\n              floor: false,\n              // isTrade: true,\n            }) +\n            ' ' +\n            symbol\n        relyAmount = getValuePrecisionThousand(value, 0, 0, undefined, false, {\n          floor: false,\n          // isTrade: true,\n        })\n        list = getUserNFTReceiveList(\n          detail.claims as any,\n          _info.nftTokenInfo as any,\n          detail.champion,\n        ).list\n      } else {\n        let tokenInfo = tokenMap[idIndex[_info?.tokenId] ?? '']\n        symbol = tokenInfo.symbol\n        myAmountStr = myAmountStr = sdk.toBig(detail.claimAmount).isZero()\n          ? EmptyValueTag\n          : getValuePrecisionThousand(\n              volumeToCountAsBigNumber(symbol, detail.claimAmount as any),\n              tokenInfo.precision,\n              tokenInfo.precision,\n              undefined,\n              false,\n              {\n                floor: false,\n                // isTrade: true,\n              },\n            ) +\n            ' ' +\n            symbol\n        relyAmount = getValuePrecisionThousand(\n          volumeToCountAsBigNumber(symbol, value),\n          tokenInfo.precision,\n          tokenInfo.precision,\n          undefined,\n          false,\n          {\n            floor: false,\n            // isTrade: true,\n          },\n        )\n        list = getUserReceiveList(detail.claims as any, tokenInfo, detail.champion).list\n      }\n      // }\n\n      const claimButton: 'claimed' | 'claim' | 'claiming' | 'expired' | 'hidden' = detail.luckyToken\n        .isNft\n        ? detail.claimStatus === sdk.ClaimRecordStatus.WAITING_CLAIM\n          ? 'claim'\n          : detail.claimStatus === sdk.ClaimRecordStatus.CLAIMED\n          ? 'claimed'\n          : detail.claimStatus === sdk.ClaimRecordStatus.CLAIMING\n          ? 'claiming'\n          : detail.claimStatus === sdk.ClaimRecordStatus.EXPIRED\n          ? 'expired'\n          : 'hidden'\n        : 'hidden'\n      const bottomButton: 'ended' | 'share' | 'hidden' = [\n        sdk.LuckyTokenItemStatus.OVER_DUE,\n        sdk.LuckyTokenItemStatus.FAILED,\n        sdk.LuckyTokenItemStatus.COMPLETED,\n      ].includes(detail.luckyToken.status)\n        ? claimButton === 'hidden'\n          ? 'ended'\n          : 'hidden'\n        : detail.luckyToken.type.scope === sdk.LuckyTokenViewType.TARGET\n        ? 'hidden'\n        : 'share'\n\n      return {\n        redPacketType,\n        ImageEle,\n        totalCount: detail.luckyToken.tokenAmount.totalCount,\n        remainCount: detail.luckyToken.tokenAmount.remainCount,\n        memo: _info.info.memo,\n        amountStr,\n        amountClaimStr,\n        sender: _info.sender?.ens ? _info.sender?.ens : getShortAddr(_info.sender?.address),\n        claimList: list,\n        detail,\n        myAmountStr,\n        relyAmount: relyAmount ? relyAmount?.toString() : undefined,\n        relyNumber: relyNumber ? relyNumber?.toString() : undefined,\n        isShouldSharedRely,\n        handlePageChange: (page: number = 1) => {\n          setPage(page)\n          redPacketDetailCall({\n            offset:\n              (detail.luckyToken.isNft ? RedPacketNFTDetailLimit : RedPacketDetailLimit) *\n              (page - 1),\n          })\n        },\n        onShared: () => {\n          setShowRedPacket({\n            isShow: true,\n            step: RedPacketViewStep.QRCodePanel,\n            info: {\n              ...detail.luckyToken,\n              referrer: account.accountId,\n              isShouldSharedRely,\n            },\n          })\n        },\n        tokenSymbol: _info.isNft ? undefined : tokenMap[idIndex[_info?.tokenId] ?? ''].symbol,\n        showRelayText,\n        bottomButton,\n        page,\n        claimButton,\n        onClickClaim: () => {\n          LoopringAPI.luckTokenAPI\n            ?.getLuckTokenBalances(\n              {\n                accountId: account.accountId,\n                isNft: detail.luckyToken.isNft,\n                tokens: [detail.luckyToken.tokenId],\n              },\n              account.apiKey,\n            )\n            .then((response) => {\n              if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n              } else {\n                setShowClaimWithdraw({\n                  isShow: true,\n                  claimToken: {\n                    tokenId: detail.luckyToken.tokenId,\n                    // response!.tokenBalance[0].tokenId,\n                    total: detail.claimAmount.toString(),\n                    locked: response!.tokenBalance[0].locked,\n                    pending: response!.tokenBalance[0].pending,\n                    nftTokenInfo: detail.luckyToken.nftTokenInfo,\n                    isNft: detail.luckyToken.isNft,\n                    luckyTokenHash: detail.luckyToken.hash,\n                  },\n                  claimType: CLAIM_TYPE.redPacket,\n                })\n              }\n            })\n        },\n        totalNumber: (detail as any).totalNum,\n        showReceiptListBtn:\n          account.accountId === detail.luckyToken.sender.accountId &&\n          detail.luckyToken.type.scope === sdk.LuckyTokenViewType.TARGET,\n        showShareBtn: false,\n        ended: false\n      } as RedPacketDetailProps\n    } else {\n      return undefined\n    }\n  }, [info, detail, amountClaimStr, amountStr, account.accAddress, isShow, step])\n  const { setShowClaimWithdraw } = useOpenModals()\n  const successCallback = React.useCallback(async () => {\n    if (isShow) {\n      switch (step) {\n        case RedPacketViewStep.DetailPanel:\n          redPacketDetailCall({ offset: 0 })\n          redpacketService.refresh()\n          break\n        case RedPacketViewStep.BlindBoxDetail:\n          redPacketBlindBoxDetailCall({ offset: 0 })\n          redpacketService.refresh()\n          if (wonPrizeInfo && wonPrizeInfo.isNFT) {\n            setShowRedPacket({ isShow: false })\n          }\n          break\n      }\n    }\n  }, [step, isShow])\n  React.useEffect(() => {\n    const subscription = subject.subscribe((props) => {\n      switch (props.status) {\n        case ClaimCommands.Success:\n          if (props?.data?.type == CLAIM_TYPE.redPacket) {\n            successCallback()\n          }\n          break\n        default:\n          break\n      }\n    })\n    return () => {\n      subscription.unsubscribe()\n    }\n  }, [subject, successCallback])\n  const redPacketBlindBoxDetailProps = React.useMemo(() => {\n    const _info = info as sdk.LuckyTokenItemForReceive & {\n      claimAmount?: string\n    }\n\n    if (\n      isShow &&\n      info &&\n      step === RedPacketViewStep.BlindBoxDetail &&\n      _info?.hash &&\n      LoopringAPI.luckTokenAPI &&\n      detail &&\n      detail.luckyToken &&\n      blinBoxDetail &&\n      blindBoxType\n    ) {\n      const shareButton: 'hidden' | 'share' =\n        (blindBoxType === 'Not Started' || blindBoxType === 'Blind Box Started') &&\n        detail.luckyToken.status !== sdk.LuckyTokenItemStatus.COMPLETED &&\n        detail.luckyToken.type.scope !== sdk.LuckyTokenViewType.TARGET\n          ? 'share'\n          : 'hidden'\n\n      const claimButton: 'claimed' | 'claim' | 'claiming' | 'expired' | 'hidden' | 'ended' = detail\n        .luckyToken.isNft\n        ? Date.now() > detail.luckyToken.validUntil\n          ? detail.claimStatus === sdk.ClaimRecordStatus.WAITING_CLAIM\n            ? 'claim'\n            : detail.claimStatus === sdk.ClaimRecordStatus.CLAIMED\n            ? 'claimed'\n            : detail.claimStatus === sdk.ClaimRecordStatus.CLAIMING\n            ? 'claiming'\n            : detail.claimStatus === sdk.ClaimRecordStatus.EXPIRED\n            ? 'expired'\n            : detail.luckyToken.status !== sdk.LuckyTokenItemStatus.COMPLETED\n            ? 'ended'\n            : 'hidden'\n          : 'hidden'\n        : [\n            sdk.LuckyTokenItemStatus.COMPLETED,\n            sdk.LuckyTokenItemStatus.FAILED,\n            sdk.LuckyTokenItemStatus.OVER_DUE,\n          ].includes(detail.luckyToken.status)\n        ? 'ended'\n        : 'hidden'\n\n      const tokenInfo = !detail.luckyToken.isNft\n        ? tokenMap[idIndex[detail.luckyToken.tokenId]]\n        : undefined\n      return {\n        sender: _info.sender?.ens ? _info.sender?.ens : getShortAddr(_info.sender?.address),\n        memo: _info.info.memo,\n        type: blindBoxType,\n        blindBoxStartTime: detail!.luckyToken.validSince,\n        lotteryStartTime: detail!.luckyToken.validUntil,\n        lotteryEndTime: moment(detail!.luckyToken.nftExpireTime).toDate().getTime(),\n        opendBlindBoxAmount: detail!.luckyToken.tokenAmount.claimedBoxCount,\n        totalBlindBoxAmount: detail!.luckyToken.tokenAmount.totalCount,\n        deliverdGiftsAmount: (detail as any).totalNum,\n        totalGiftsAmount: Number(detail!.luckyToken.tokenAmount.giftCount),\n        // imageEle?: JSX.Element | undefined;\n        onShared: () => {\n          setShowRedPacket({\n            isShow: true,\n            step: RedPacketViewStep.QRCodePanel,\n            info: {\n              ...detail.luckyToken,\n              referrer: account.accountId,\n            },\n          })\n        },\n        onClickViewDetail: () => {\n          redPacketBlindBoxDetailCall({}).then(() => {\n            setViewDetailFrom(blindBoxType)\n            setBlindBoxType('BlindBox Claime Detail')\n          })\n        },\n        NFTClaimList: detail!.claims.map((claim) => {\n          return {\n            isMe: claim.claimer.accountId === account.accountId,\n            who: claim.claimer?.ens ? claim.claimer?.ens : getShortAddr(claim.claimer?.address),\n            when: claim.createdAt,\n            amount: detail.luckyToken.isNft\n              ? claim.amount\n              : getValuePrecisionThousand(\n                  sdk.toBig(claim.amount).div('1e' + tokenInfo!.decimals),\n                  tokenInfo!.precision,\n                  tokenInfo!.precision,\n                  tokenInfo!.precision,\n                ) +\n                ' ' +\n                tokenInfo!.symbol,\n            showMultiplier: detail.luckyToken.isNft,\n            showLuckiest:\n              detail.luckyToken.tokenAmount.remainAmount == '0' &&\n              detail.champion?.accountId === claim.claimer.accountId &&\n              detail.champion?.amount === claim.amount,\n          }\n        }),\n        // to change\n        BlindBoxClaimList: blinBoxDetail.claims.map((x: any) => {\n          return {\n            who: x.claimer?.ens ? x.claimer?.ens : getShortAddr(x.claimer?.address),\n            when: x.createdAt,\n            amount: x.amount ? x.amount : 0,\n            isMe: x.claimer.accountId === account.accountId,\n          }\n        }),\n        showOpenLottery:\n          blindBoxType === 'Lottery Started and Win Lottery' ||\n          blindBoxType === 'Lottery Started and Not Win Lottery',\n        wonPrizeInfo: wonPrizeInfo,\n        onCloseOpenModal: () => {\n          setShowRedPacket({ isShow: false })\n        },\n        onClickClaimDetailBack: () => {\n          setBlindBoxType(viewDetailFrom)\n        },\n        onClickClaim: async () => {\n          if (!detail.luckyToken.isNft) {\n            setShowRedPacket({\n              isShow: false,\n            })\n            history.push(`${RouterPath.l2assetsDetail}/${AssetTabIndex.RedPacket}`)\n            return\n          }\n          const response = await LoopringAPI.luckTokenAPI?.getLuckTokenBalances(\n            {\n              accountId: account.accountId,\n              isNft: detail.luckyToken.isNft,\n              tokens: [detail.luckyToken.tokenId],\n            },\n            account.apiKey,\n          )\n          if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n          } else {\n            setShowClaimWithdraw({\n              isShow: true,\n              claimToken: {\n                tokenId: detail.luckyToken.tokenId,\n                // response!.tokenBalance[0].tokenId,\n                total: detail.claimAmount.toString(),\n                locked: response!.tokenBalance[0].locked,\n                pending: response!.tokenBalance[0].pending,\n                nftTokenInfo: detail.luckyToken.nftTokenInfo,\n                isNft: detail.luckyToken.isNft,\n                luckyTokenHash: detail.luckyToken.hash,\n              },\n              claimType: CLAIM_TYPE.redPacket,\n            })\n          }\n        },\n        NFTURL:\n          Date.now() > detail!.luckyToken.validUntil\n            ? detail.luckyToken.nftTokenInfo?.metadata?.imageSize.original\n            : undefined,\n        description: '',\n        // Date.now() > detail!.luckyToken.validUntil\n        //   ? t(\"labelBlindBoxExplainationEnded\")\n        //   : t(\"labelBlindBoxExplainationNotEnded\"),\n        claimButton,\n        shareButton,\n        didClaimABlindBox:\n          blinBoxDetail.blindBoxStatus !== '' && blinBoxDetail.blindBoxStatus !== 'EXPIRED',\n        wonInfo: blinBoxDetail!.luckyToken.isNft\n          ? {\n              participated:\n                blinBoxDetail.blindBoxStatus !== '' && blinBoxDetail.blindBoxStatus !== 'EXPIRED',\n              won: blinBoxDetail.claimAmount && toBig(blinBoxDetail.claimAmount).isGreaterThan(0),\n              amount: detail.claimAmount,\n              isNFT: true,\n            }\n          : {\n              participated:\n                blinBoxDetail.blindBoxStatus !== '' && blinBoxDetail.blindBoxStatus !== 'EXPIRED',\n              won: blinBoxDetail.claimAmount && toBig(blinBoxDetail.claimAmount).isGreaterThan(0),\n              amount:\n                blinBoxDetail.claimAmount &&\n                tokenInfo &&\n                getValuePrecisionThousand(\n                  sdk.toBig(blinBoxDetail.claimAmount ?? '0').div('1e' + tokenInfo.decimals),\n                  tokenInfo.precision,\n                  tokenInfo.precision,\n                  tokenInfo.precision,\n                  false,\n                ),\n              total:\n                tokenInfo &&\n                getValuePrecisionThousand(\n                  sdk\n                    .toBig(blinBoxDetail.luckyToken.tokenAmount.totalAmount)\n                    .div('1e' + tokenInfo!.decimals),\n                  tokenInfo!.precision,\n                  tokenInfo!.precision,\n                  tokenInfo!.precision,\n                  false,\n                ),\n              symbol: tokenInfo?.symbol,\n              isNFT: false,\n            },\n        handlePageChange: (page: number = 1) => {\n          setPage(page)\n          // redPacketBlindBoxDetailCall({ offset: (detail.luckyToken.isNft ? RedPacketNFTDetailLimit : RedPacketDetailLimit) * (page - 1) });\n          redPacketBlindBoxDetailCall({\n            offset:\n              (detail.luckyToken.isNft ? RedPacketNFTDetailLimit : RedPacketDetailLimit) *\n              (page - 1),\n          })\n        },\n        totalCount: detail.luckyToken.tokenAmount.giftCount,\n        remainCount: detail.luckyToken.tokenAmount.remainCount,\n        page,\n        totalClaimedNFTsCount: (detail as any).totalNum,\n        totalBlindboxCount: opendBlindBoxCount,\n        handlePageChange_BlindBox: (page: number = 1) => {\n          setPageForBlindbox(page)\n          // setPage(page)\n          LoopringAPI.luckTokenAPI\n            ?.getBlindBoxDetail(\n              {\n                accountId: account.accountId,\n                hash: _info.hash,\n                serialNo: _info.serialNo,\n                limit: RedPacketBlindBoxLimit,\n                offset: (page - 1) * RedPacketBlindBoxLimit,\n              } as any,\n              account.apiKey,\n            )\n            .then((response2) => {\n              setBlindBoxDetail(response2.raw_data)\n            })\n        },\n        pageForBlindbox,\n        onClickClaimPopViewDetail: () => {\n          redPacketBlindBoxDetailCall({}).then(() => {\n            setBlindBoxType('Lottery Started')\n          })\n        },\n        expired: Date.now() > detail!.luckyToken.nftExpireTime,\n        isTokenBlindbox: detail!.luckyToken.isNft ? false : true,\n        remainGiftsAmount: detail!.luckyToken.isNft\n          ? detail!.luckyToken.tokenAmount.remainAmount\n          : getValuePrecisionThousand(\n              sdk\n                .toBig(detail!.luckyToken.tokenAmount.remainAmount)\n                .div('1e' + tokenInfo!.decimals),\n              tokenInfo?.precision,\n              undefined,\n              undefined,\n              false,\n            ) +\n            ' ' +\n            tokenInfo?.symbol,\n        showReceiptListBtn:\n          account.accountId === detail.luckyToken.sender.accountId &&\n          detail.luckyToken.type.scope === sdk.LuckyTokenViewType.TARGET,\n        targets: (detail as any).targets,\n      } as RedPacketBlindBoxDetailProps\n    } else {\n      return undefined\n    }\n  }, [\n    info,\n    detail,\n    amountClaimStr,\n    amountStr,\n    account.accAddress,\n    isShow,\n    step,\n    blinBoxDetail,\n    blindBoxType,\n    wonPrizeInfo,\n  ])\n  const redPacketQRCodeProps: RedPacketQRCodeProps | undefined = React.useMemo(() => {\n    if (isShow && info && step === RedPacketViewStep.QRCodePanel && qrcode && qrcode.hash) {\n      if (\n        qrcode.status === sdk.LuckyTokenItemStatus.COMPLETED ||\n        qrcode.status === sdk.LuckyTokenItemStatus.OVER_DUE\n      ) {\n        setShowRedPacket({\n          isShow,\n          step: RedPacketViewStep.TimeOutPanel,\n          info: qrcode,\n        })\n      } else if (qrcode?.hash) {\n        const url = `${Exchange}wallet?redpacket&id=${qrcode?.hash}&referrer=${account.accAddress}`\n        return {\n          url,\n          imageEleUrl: qrcode.nftTokenInfo?.metadata?.imageSize[NFT_IMAGE_SIZES.large] ?? undefined,\n          textAddress: qrcode.sender?.ens\n            ? qrcode.sender?.ens\n            : getShortAddr(qrcode.sender?.address),\n          textContent: qrcode.info.memo,\n          amountStr: qrcode.isNft\n            ? amountStrNFTCallback(qrcode.nftTokenInfo as any, qrcode.tokenAmount.totalAmount)\n                .amount === '1'\n              ? t('labelNFTs_one', {\n                  count: 1,\n                })\n              : t('labelNFTs_other', {\n                  count: amountStrNFTCallback(\n                    qrcode.nftTokenInfo as any,\n                    qrcode.tokenAmount.totalAmount,\n                  ).amount,\n                })\n            : amountStrCallback(tokenMap, idIndex, qrcode.tokenId, qrcode.tokenAmount.totalAmount)\n                .amountStr,\n          textSendBy,\n          textType:\n            info && info.type\n              ? info.type.mode === sdk.LuckyTokenClaimType.BLIND_BOX\n                ? t('labelLuckyBlindBox')\n                : info.type.mode === sdk.LuckyTokenClaimType.RELAY\n                ? t('labelRelayRedPacket')\n                : info.type.partition === sdk.LuckyTokenAmountType.RANDOM\n                ? t('labelLuckyRedPacket')\n                : t('labelNormalRedPacket')\n              : t('labelNormalRedPacket'),\n          textShared: t('labelShare'),\n          textDes: t('labelRedpacketScanDes'),\n          isShouldSharedRely: qrcode.type.mode == sdk.LuckyTokenClaimType.RELAY,\n          textNo: t('labelRedPacketNo', { value: qrcode?.hash.slice(-8) }),\n        } as RedPacketQRCodeProps\n      }\n    }\n    return undefined\n  }, [info, qrcode, account.accAddress, isShow, textSendBy, amountStr, step])\n  return {\n    redPacketQRCodeProps,\n    redPacketTimeoutProps,\n    redPacketOpenProps,\n    redPacketOpenedProps,\n    redPacketDetailProps,\n    redPacketClockProps,\n    redPacketBlindBoxDetailProps,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/modal/RedPacketModal/index.tsx",
    "content": "import { WithTranslation, withTranslation } from 'react-i18next'\nimport {\n  ModalRedPacket,\n  RedPacketBlindBoxDetail,\n  RedPacketClock,\n  RedPacketDetail,\n  RedPacketOpen,\n  RedPacketOpened,\n  RedPacketQRCode,\n  RedPacketSize,\n  RedPacketTimeout,\n  RedPacketViewStep,\n  useOpenModals,\n} from '@loopring-web/component-lib'\nimport React from 'react'\nimport { useRedPacketModal } from './hook'\nimport { myLog, SoursURL } from '@loopring-web/common-resources'\nimport { Box } from '@mui/material'\n\nexport const ModalRedPacketPanel = withTranslation('common')(\n  ({\n    etherscanBaseUrl,\n  }: WithTranslation & {\n    etherscanBaseUrl: string\n  }) => {\n    const {\n      modals: { isShowRedPacket },\n      setShowRedPacket,\n    } = useOpenModals()\n    const {\n      redPacketQRCodeProps,\n      redPacketTimeoutProps,\n      redPacketOpenProps,\n      redPacketOpenedProps,\n      redPacketDetailProps,\n      redPacketClockProps,\n      redPacketBlindBoxDetailProps,\n    } = useRedPacketModal()\n    // const { redPacketProps } = useRedPacketDetail();\n    // const theme = useTheme();\n    const redPacketList = React.useMemo(() => {\n      myLog(redPacketOpenProps)\n      return Object.values({\n        [RedPacketViewStep.QRCodePanel]: {\n          view: redPacketQRCodeProps ? (\n            <Box height={603} display={'flex'} justifyContent={'start'} alignItems={'start'}>\n              <Box flex={1}>\n                <RedPacketQRCode {...redPacketQRCodeProps} />\n              </Box>\n            </Box>\n          ) : (\n            <></>\n          ),\n        },\n        [RedPacketViewStep.OpenPanel]: {\n          view: redPacketOpenProps ? (\n            <Box\n              height={RedPacketSize.large.height}\n              width={RedPacketSize.large.width}\n              display={'flex'}\n              justifyContent={'center'}\n              alignItems={'center'}\n            >\n              <Box flex={1}>\n                <RedPacketOpen size={'large'} {...redPacketOpenProps} />\n              </Box>\n            </Box>\n          ) : (\n            <></>\n          ),\n        },\n        [RedPacketViewStep.RedPacketClock]: {\n          view: redPacketClockProps ? (\n            <Box\n              height={RedPacketSize.large.height}\n              width={RedPacketSize.large.width}\n              display={'flex'}\n              justifyContent={'center'}\n              alignItems={'center'}\n            >\n              <Box flex={1}>\n                <RedPacketClock size={'large'} {...redPacketClockProps} />\n              </Box>\n            </Box>\n          ) : (\n            <></>\n          ),\n        },\n        [RedPacketViewStep.OpenedPanel]: {\n          view: redPacketOpenedProps ? (\n            <Box\n              height={RedPacketSize.large.height}\n              width={RedPacketSize.large.width}\n              display={'flex'}\n              justifyContent={'center'}\n              alignItems={'center'}\n            >\n              <Box flex={1}>\n                <RedPacketOpened size={'large'} {...redPacketOpenedProps} />\n              </Box>\n            </Box>\n          ) : (\n            <></>\n          ),\n        },\n        [RedPacketViewStep.TimeOutPanel]: {\n          view: redPacketTimeoutProps ? (\n            <Box\n              height={RedPacketSize.large.height}\n              width={RedPacketSize.large.width}\n              display={'flex'}\n              justifyContent={'center'}\n              alignItems={'center'}\n            >\n              <Box flex={1}>\n                <RedPacketTimeout size={'large'} {...redPacketTimeoutProps} />\n              </Box>\n            </Box>\n          ) : (\n            <></>\n          ),\n        },\n        [RedPacketViewStep.DetailPanel]: {\n          view: redPacketDetailProps ? (\n            <Box\n              minHeight={RedPacketSize.large.height}\n              height={'80vh'}\n              width={RedPacketSize.large.width}\n              display={'flex'}\n              justifyContent={'center'}\n              alignItems={'start'}\n            >\n              <RedPacketDetail {...redPacketDetailProps} />\n            </Box>\n          ) : (\n            <></>\n          ),\n        },\n\n        [RedPacketViewStep.PreparePanel]: { view: <></> },\n        [RedPacketViewStep.BlindBoxDetail]: {\n          view: redPacketBlindBoxDetailProps ? (\n            <Box\n              minHeight={RedPacketSize.large.height}\n              height={'80vh'}\n              width={RedPacketSize.large.width}\n              display={'flex'}\n              justifyContent={'center'}\n              alignItems={'start'}\n            >\n              <RedPacketBlindBoxDetail {...redPacketBlindBoxDetailProps} />\n            </Box>\n          ) : (\n            <></>\n          ),\n        },\n        [RedPacketViewStep.Loading]: {\n          view: (\n            <Box\n              minHeight={RedPacketSize.large.height}\n              height={'80vh'}\n              width={RedPacketSize.large.width}\n              display={'flex'}\n              justifyContent={'center'}\n              alignItems={'center'}\n            >\n              <img\n                className='loading-gif'\n                alt={'loading'}\n                width='36'\n                src={`${SoursURL}images/loading-line.gif`}\n              />\n            </Box>\n          ),\n        },\n      })\n    }, [\n      redPacketQRCodeProps,\n      redPacketOpenProps,\n      redPacketDetailProps,\n      redPacketTimeoutProps,\n      redPacketOpenedProps,\n      redPacketClockProps,\n      redPacketBlindBoxDetailProps,\n    ])\n    return (\n      <ModalRedPacket\n        onClose={() => {\n          setShowRedPacket({ isShow: false })\n        }}\n        etherscanBaseUrl={etherscanBaseUrl}\n        step={isShowRedPacket.step}\n        open={isShowRedPacket.isShow}\n        panelList={redPacketList}\n      />\n    )\n  },\n)\n"
  },
  {
    "path": "packages/core/src/modal/WalletModal/index.tsx",
    "content": "// @ts-nocheck\nimport { useTranslation, WithTranslation, withTranslation } from 'react-i18next'\nimport {\n  AccountStep,\n  CommonConnectInProgress,\n  ConfirmLinkCopy,\n  ConnectFailed,\n  ConnectReject,\n  ConnectRejectSwitchNetwork,\n  ConnectSuccess,\n  InformationForCoinBase,\n  ModalWalletConnect,\n  ProviderMenu,\n  Toast,\n  ToastType,\n  useOpenModals,\n  useSettings,\n  WalletConnectConnectInProgress,\n  WalletConnectQRCode,\n  WalletConnectStep,\n  WrongNetworkGuide,\n} from '@loopring-web/component-lib'\nimport React from 'react'\nimport {\n  AccountStatus,\n  Bridge,\n  copyToClipBoard,\n  GatewayItem,\n  gatewayList as DefaultGatewayList,\n  globalSetup,\n  myLog,\n  NetworkMap,\n  SagaStatus,\n  SoursURL,\n  TOAST_TIME,\n} from '@loopring-web/common-resources'\nimport { walletServices } from '@loopring-web/web3-provider'\nimport {\n  CoinbaseCallback,\n  gameStopCallback,\n  metaMaskCallback,\n  RootState,\n  useAccount,\n  walletConnectCallback,\n} from '@loopring-web/core'\nimport { useSelector } from 'react-redux'\nimport { useLocation } from 'react-router-dom'\n\nexport const useGatewayList = ({\n  setIsOpenUnknownProvider,\n  setConnectProvider,\n  setIsConfirmLinkCopy,\n}: {\n  setIsOpenUnknownProvider?: any\n  setConnectProvider?: any\n  setIsConfirmLinkCopy: (boolean) => void\n}) => {\n  const { search } = useLocation()\n  const { t } = useTranslation()\n  const searchParams = new URLSearchParams(search)\n  const { isMobile } = useSettings()\n  const { setShowConnect } = useOpenModals()\n  const { account, status: accountStatus } = useAccount()\n\n  const [stateCheck, setStateCheck] = React.useState<boolean>(false)\n  const [processingCallback, setProcessingCallback] = React.useState<\n    { callback: () => Promise<void> } | undefined\n  >(undefined)\n  React.useEffect(() => {\n    if (stateCheck && [SagaStatus.UNSET].findIndex((ele: string) => ele === accountStatus) !== -1) {\n      myLog('clear cache connect done')\n      setStateCheck(false)\n      if (processingCallback !== undefined) {\n        processingCallback.callback()\n      }\n    }\n  }, [accountStatus, stateCheck])\n  const gatewayList: GatewayItem[] = !isMobile\n    ? [\n        {\n          ...DefaultGatewayList[0],\n          handleSelect: React.useCallback(\n            async (event, flag?) => {\n              if (!flag && account.connectName === DefaultGatewayList[0].key) {\n                setShowConnect({ isShow: false })\n              } else {\n                const isKnow = localStorage.getItem('useKnowCoinBaseWalletInstall')\n                if (\n                  !(isKnow === 'true') &&\n                  !(window?.ethereum?._metamask && window?.ethereum?._metamask.requestBatch)\n                ) {\n                  setIsOpenUnknownProvider && setIsOpenUnknownProvider(true)\n                }\n                walletServices.sendDisconnect('', 'should new provider')\n                setConnectProvider && setConnectProvider(DefaultGatewayList[0].key)\n                setShowConnect({\n                  isShow: true,\n                  step: WalletConnectStep.Provider,\n                  info: {\n                    status: 'processing',\n                  },\n                })\n                setProcessingCallback({ callback: metaMaskCallback })\n                setStateCheck(true)\n              }\n            },\n            [account.connectName, setShowConnect],\n          ),\n        },\n        {\n          ...DefaultGatewayList[1],\n          handleSelect: React.useCallback(\n            async (event, flag?) => {\n              if (!flag && account.connectName === DefaultGatewayList[1].key) {\n                setShowConnect({ isShow: false })\n              } else {\n                walletServices.sendDisconnect('', 'should new provider')\n                setConnectProvider(DefaultGatewayList[1].key)\n                setShowConnect({\n                  isShow: true,\n                  step: WalletConnectStep.Provider,\n                  info: {\n                    status: 'processing',\n                  },\n                })\n                setProcessingCallback({ callback: walletConnectCallback })\n                setStateCheck(true)\n              }\n            },\n            [account.connectName, setShowConnect],\n          ),\n        },\n        {\n          ...DefaultGatewayList[2],\n          handleSelect: React.useCallback(\n            async (event, flag?) => {\n              walletServices.sendDisconnect('', 'should new provider')\n              setConnectProvider(DefaultGatewayList[2].key)\n              setShowConnect({\n                isShow: true,\n                step: WalletConnectStep.Provider,\n                info: {\n                  status: 'processing',\n                },\n              })\n              setProcessingCallback({ callback: gameStopCallback })\n              setStateCheck(true)\n            },\n            [setShowConnect],\n          ),\n        },\n        {\n          ...DefaultGatewayList[3],\n          handleSelect: React.useCallback(\n            async (event, flag?) => {\n              walletServices.sendDisconnect('', 'should new provider')\n              setConnectProvider(DefaultGatewayList[3].key)\n              if (\n                window.ethereum &&\n                'isCoinbaseBrowser' in ethereum &&\n                ethereum.isCoinbaseBrowser\n              ) {\n                setShowConnect({\n                  isShow: true,\n                  step: WalletConnectStep.Provider,\n                  info: {\n                    status: 'processing',\n                  },\n                })\n              } else {\n                setShowConnect({\n                  isShow: false,\n                  step: WalletConnectStep.Provider,\n                  info: {\n                    status: 'processing',\n                  },\n                })\n              }\n              setProcessingCallback({ callback: CoinbaseCallback })\n              setStateCheck(true)\n            },\n            [setShowConnect],\n          ),\n        },\n      ]\n    : [\n        ...(window.ethereum\n          ? [\n              {\n                ...DefaultGatewayList[0],\n                key: t('labelConnectWithDapp'),\n                imgSrc: SoursURL + 'svg/loopring.svg',\n                handleSelect: React.useCallback(\n                  async (event, flag?) => {\n                    if (!flag && account.connectName === DefaultGatewayList[0].key) {\n                      setShowConnect({ isShow: false })\n                    } else {\n                      walletServices.sendDisconnect('', 'should new provider')\n                      setConnectProvider && setConnectProvider(DefaultGatewayList[0].key)\n                      setShowConnect({\n                        isShow: true,\n                        step: WalletConnectStep.Provider,\n                        info: {\n                          status: 'processing',\n                        },\n                      })\n                      setProcessingCallback({ callback: metaMaskCallback })\n                      setStateCheck(true)\n                    }\n                  },\n                  [account.connectName, setShowConnect],\n                ),\n              },\n            ]\n          : [\n              {\n                key: t('labelOpenInWalletApp'),\n                keyi18n: 'labelOpenInWalletApp',\n                imgSrc: SoursURL + 'svg/loopring.svg',\n                handleSelect: React.useCallback(\n                  async (event, flag?) => {\n                    // setShowConnect({ isShow: false });\n                    const token = searchParams.get('token')\n                    const l2account = searchParams.get('l2account') || searchParams.get('owner')\n                    copyToClipBoard(\n                      Bridge +\n                        `?${l2account ? `l2account=` + l2account : ''}&${\n                          token ? `token=` + token : ''\n                        }`,\n                    )\n                    setIsConfirmLinkCopy(true)\n                  },\n                  [searchParams],\n                ),\n              },\n            ]),\n        {\n          ...DefaultGatewayList[1],\n          handleSelect: React.useCallback(\n            async (event, flag?) => {\n              if (!flag && account.connectName === DefaultGatewayList[1].key) {\n                setShowConnect({ isShow: false })\n              } else {\n                walletServices.sendDisconnect('', 'should new provider')\n                setConnectProvider && setConnectProvider(DefaultGatewayList[1].key)\n                setShowConnect({\n                  isShow: true,\n                  step: WalletConnectStep.Provider,\n                  info: {\n                    status: 'processing',\n                  },\n                })\n                setProcessingCallback({ callback: walletConnectCallback })\n                setStateCheck(true)\n              }\n            },\n            [account.connectName, setShowConnect],\n          ),\n        },\n        {\n          ...DefaultGatewayList[3],\n          handleSelect: React.useCallback(\n            async (event, flag?) => {\n              walletServices.sendDisconnect('', 'should new provider')\n              setConnectProvider && setConnectProvider(DefaultGatewayList[3].key)\n              setShowConnect({\n                isShow: false,\n                step: WalletConnectStep.Provider,\n                info: {\n                  status: 'processing',\n                },\n              })\n              setProcessingCallback({ callback: CoinbaseCallback })\n              setStateCheck(true)\n            },\n            [setShowConnect],\n          ),\n        },\n      ]\n  return { gatewayList }\n}\nexport const ModalWalletConnectPanel = withTranslation('common')(\n  ({\n    onClose,\n    open,\n    wait = globalSetup.wait,\n    t,\n    ...rest\n  }: {\n    open: boolean\n    wait?: number\n    onClose?: (e: MouseEvent) => void\n  } & WithTranslation) => {\n    const { account, setShouldShow } = useAccount()\n    const { defaultNetwork } = useSettings()\n    const {\n      modals: { isShowConnect, isWrongNetworkGuide },\n      setShowConnect,\n      setShowAccount,\n      setShowWrongNetworkGuide,\n    } = useOpenModals()\n\n    const qrCodeUrl = useSelector((state: RootState) => state.account.qrCodeUrl)\n    const [connectProvider, setConnectProvider] = React.useState<boolean>(() => {\n      return account?.connectName ?? false\n    })\n    React.useEffect(() => {\n      if (account?.connectName !== connectProvider) {\n        setConnectProvider(account?.connectName)\n      }\n    }, [account?.connectName])\n\n    const _onClose = React.useCallback(\n      async (e: any) => {\n        setShouldShow(false)\n        setShowConnect({ isShow: false })\n        if (account.readyState === 'UN_CONNECT') {\n          walletServices.sendDisconnect('', 'should new provider')\n        }\n        if (onClose) {\n          onClose(e)\n        }\n      },\n      [account.readyState, onClose, setShouldShow, setShowConnect],\n    )\n    const [isOpenUnknownProvider, setIsOpenUnknownProvider] = React.useState(false)\n    const [isConfirmLinkCopy, setIsConfirmLinkCopy] = React.useState(false)\n    const { gatewayList } = useGatewayList({\n      setConnectProvider,\n      setIsOpenUnknownProvider,\n      setIsConfirmLinkCopy,\n    })\n    const handleCloseDialog = React.useCallback((_event: any, state?: boolean) => {\n      setIsOpenUnknownProvider(false)\n      localStorage.setItem('useKnowCoinBaseWalletInstall', String(!!state))\n    }, [])\n\n    const [copyToastOpen, setCopyToastOpen] = React.useState(false)\n    const onRetry = React.useCallback(async () => {\n      const index = gatewayList.findIndex((item) => {\n        return item.key === account.connectName\n      })\n      if (index !== -1 && gatewayList) {\n        //@ts-ignore\n        gatewayList[index].handleSelect(null, true)\n      } else {\n        walletServices.sendDisconnect('', 'should new provider')\n        setShowConnect({ isShow: true, step: WalletConnectStep.Provider })\n      }\n    }, [gatewayList, account.connectName, setShowConnect])\n    const providerBack = React.useMemo(() => {\n      return ['UN_CONNECT', 'ERROR_NETWORK'].includes(account.readyState)\n        ? undefined\n        : () => {\n            setShowConnect({ isShow: false })\n            switch (account.readyState) {\n              case AccountStatus.ACTIVATED:\n              case AccountStatus.LOCKED:\n                break\n              case AccountStatus.DEPOSITING:\n                setShowAccount({\n                  isShow: true,\n                  step: AccountStep.Deposit_Submit,\n                })\n                break\n              case AccountStatus.NO_ACCOUNT:\n                setShowAccount({ isShow: true, step: AccountStep.NoAccount })\n                break\n            }\n          }\n    }, [account.readyState, setShowAccount, setShowConnect])\n\n    const walletList = React.useMemo(() => {\n      return Object.values({\n        [WalletConnectStep.Provider]: {\n          view: (\n            <ProviderMenu\n              gatewayList={gatewayList}\n              providerName={connectProvider}\n              status={isShowConnect?.info?.status}\n              {...{ t, ...rest }}\n            />\n          ),\n          height: 'auto',\n          onBack: providerBack,\n        },\n        [WalletConnectStep.CommonProcessing]: {\n          view: (\n            <CommonConnectInProgress\n              {...{\n                t,\n                ...rest,\n                providerName: connectProvider,\n                network: NetworkMap[defaultNetwork]?.label,\n              }}\n            />\n          ),\n        },\n        [WalletConnectStep.WalletConnectProcessing]: {\n          view: <WalletConnectConnectInProgress {...{ t, ...rest }} />,\n        },\n        [WalletConnectStep.WalletConnectQRCode]: {\n          view: (\n            <WalletConnectQRCode\n              onCopy={() => {\n                copyToClipBoard(qrCodeUrl)\n                setCopyToastOpen(true)\n              }}\n              url={qrCodeUrl}\n              {...{ t, ...rest }}\n            />\n          ),\n          onBack: () => {\n            setShowConnect({ isShow: true, step: WalletConnectStep.Provider })\n          },\n        },\n        [WalletConnectStep.SuccessConnect]: {\n          view: <ConnectSuccess providerName={connectProvider} {...{ t, ...rest }} />,\n        },\n        [WalletConnectStep.RejectConnect]: {\n          view: (\n            <ConnectReject\n              {...{\n                t,\n                ...rest,\n              }}\n              providerName={connectProvider}\n              btnInfo={{ btnTxt: 'labelRetry', callback: onRetry }}\n            />\n          ),\n          onBack: () => {\n            walletServices.sendDisconnect('', 'should new provider')\n            setShowConnect({ isShow: true, step: WalletConnectStep.Provider })\n          },\n        },\n        [WalletConnectStep.RejectSwitchNetwork]: {\n          view: (\n            <ConnectRejectSwitchNetwork\n              {...{\n                t,\n                ...rest,\n              }}\n              providerName={connectProvider}\n              btnInfo={{ btnTxt: 'labelRetry', callback: onRetry }}\n            />\n          ),\n        },\n        [WalletConnectStep.FailedConnect]: {\n          view: (\n            <ConnectFailed\n              {...{\n                t,\n                error: isShowConnect.error,\n                errorOptions: { name: connectProvider },\n                ...rest,\n              }}\n              providerName={connectProvider}\n              // NetWorkItems={NetWorkItems}\n              btnInfo={{ btnTxt: 'labelRetry', callback: onRetry }}\n            />\n          ),\n          onBack: () => {\n            walletServices.sendDisconnect('', 'should new provider')\n            setShowConnect({ isShow: true, step: WalletConnectStep.Provider })\n          },\n        },\n      })\n    }, [\n      gatewayList,\n      account.connectName,\n      t,\n      rest,\n      providerBack,\n      connectProvider,\n      qrCodeUrl,\n      isShowConnect.error,\n      onRetry,\n      setShowConnect,\n    ])\n    return (\n      <>\n        <InformationForCoinBase open={isOpenUnknownProvider} handleClose={handleCloseDialog} />\n        <ConfirmLinkCopy\n          open={isConfirmLinkCopy}\n          setCopyToastOpen={setCopyToastOpen}\n          handleClose={() => setIsConfirmLinkCopy(false)}\n        />\n        <WrongNetworkGuide\n          open={isWrongNetworkGuide.isShow}\n          handleClose={() => {\n            setShowWrongNetworkGuide({ isShow: false })\n          }}\n        />\n        <ModalWalletConnect\n          open={isShowConnect.isShow}\n          onClose={_onClose}\n          panelList={walletList}\n          onBack={walletList[isShowConnect.step].onBack}\n          step={isShowConnect.step}\n        />\n        <Toast\n          alertText={t('labelCopyAddClip')}\n          open={copyToastOpen}\n          autoHideDuration={TOAST_TIME}\n          onClose={() => {\n            setCopyToastOpen(false)\n          }}\n          severity={ToastType.success}\n        />\n      </>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/core/src/modal/index.tsx",
    "content": "import {\n  AccountStep,\n  AlertNotSupport,\n  DepositProps,\n  InformationForNoMetaNFT,\n  ModalCloseButton,\n  ModalSettingFee,\n  OtherExchangeDialog,\n  SwitchPanelStyled,\n  useOpenModals,\n} from '@loopring-web/component-lib'\nimport { ClosureAnnouncementModal } from '@loopring-web/component-lib/src/components/modal/ClosureAnnouncementModal'\nimport { \n  isClosureAnnouncementDismissed, \n  setClosureAnnouncementDismissed \n} from '@loopring-web/component-lib/src/utils/closureAnnouncementUtils'\nimport { ModalWalletConnectPanel } from './WalletModal'\nimport { ModalAccountInfo } from './AccountModal'\nimport { withTranslation, WithTranslation } from 'react-i18next'\nimport { useSystem, useAccountModal, useAccount } from '@loopring-web/core'\nimport React from 'react'\nimport { AccountStatus, AssetsRawDataItem } from '@loopring-web/common-resources'\nimport { Box, Modal as MuiModal } from '@mui/material'\nimport { ModalAccountL1Info } from './AccountL1Modal'\n\nexport const ModalGroup = withTranslation('common')(\n  ({\n    isLayer1Only,\n    onWalletConnectPanelClose,\n    depositProps,\n    assetsRawData,\n    hideDepositWithdrawBack,\n    isWebEarn,\n    ...rest\n  }: WithTranslation & {\n    isLayer1Only?: boolean\n    depositProps: DepositProps<any, any>\n    assetsRawData: AssetsRawDataItem[]\n    onWalletConnectPanelClose?: (event: MouseEvent) => void\n    hideDepositWithdrawBack?: boolean\n    isWebEarn?: boolean\n  }) => {\n    const { etherscanBaseUrl } = useSystem()\n    const {\n      modals: { isShowFeeSetting, isShowIFrame, isShowClosureAnnouncement },\n      setShowFeeSetting,\n      setShowIFrame,\n      setShowOtherExchange,\n      setShowClosureAnnouncement,\n    } = useOpenModals()\n    useAccountModal()\n\n    const {\n      modals: {\n        isShowAccount,\n        isShowConnect,\n        isShowSupport,\n        isShowOtherExchange,\n        isShowNFTMetaNotReady,\n      },\n      setShowAccount,\n      setShowSupport,\n      setShowDeposit,\n      setShowTransfer,\n      setShowWithdraw,\n      setShowResetAccount,\n      setNFTMetaNotReady,\n    } = useOpenModals()\n    const { account } = useAccount()\n\n    React.useEffect(() => {\n      if (account.readyState !== AccountStatus.ACTIVATED) {\n        setShowDeposit({ isShow: false })\n        setShowTransfer({ isShow: false })\n        setShowWithdraw({ isShow: false })\n        setShowResetAccount({ isShow: false })\n      }\n    }, [account.readyState])\n\n    React.useEffect(() => {\n      if (!isClosureAnnouncementDismissed()) {\n        setShowClosureAnnouncement({ isShow: true })\n      }\n    }, [setShowClosureAnnouncement])\n\n    return (\n      <>\n        <ClosureAnnouncementModal\n          open={isShowClosureAnnouncement.isShow}\n          handleClose={() => {\n            setClosureAnnouncementDismissed()\n            setShowClosureAnnouncement({ isShow: false })\n          }}\n        />\n        <AlertNotSupport\n          open={isShowSupport.isShow}\n          handleClose={() => {\n            setShowSupport({ isShow: false })\n          }}\n        />\n        {/*<ModalRedPacketPanel etherscanBaseUrl={etherscanBaseUrl} />*/}\n        <ModalWalletConnectPanel\n          {...{\n            ...rest,\n            open: isShowConnect.isShow,\n            onClose: onWalletConnectPanelClose,\n          }}\n        />\n        <OtherExchangeDialog\n          open={isShowOtherExchange.isShow}\n          handleClose={(_e, agree) => {\n            setShowOtherExchange({ isShow: false, agree })\n          }}\n        />\n        <InformationForNoMetaNFT\n          open={!!isShowNFTMetaNotReady.isShow}\n          method={isShowNFTMetaNotReady?.info?.method}\n          handleClose={(_e, isAgree) => {\n            setNFTMetaNotReady({ isShow: false })\n            if (isAgree) {\n              setShowAccount({\n                isShow: true,\n                step: AccountStep.SendNFTGateway,\n              })\n            }\n          }}\n        />\n        <ModalAccountInfo\n          {...{\n            ...rest,\n            assetsRawData,\n            etherscanBaseUrl,\n            account,\n            open: isShowAccount.isShow,\n            depositProps,\n            isLayer1Only,\n            hideDepositWithdrawBack,\n            isWebEarn,\n          }}\n        />\n        <ModalSettingFee\n          open={isShowFeeSetting.isShow}\n          onClose={() => setShowFeeSetting({ isShow: false })}\n        />\n        <MuiModal\n          open={isShowIFrame.isShow}\n          onClose={() => setShowIFrame({ isShow: false, url: '' })}\n          aria-labelledby='modal-modal-title'\n          aria-describedby='modal-modal-description'\n        >\n          <SwitchPanelStyled width={'80%'} position={'relative'} style={{ alignItems: 'stretch' }}>\n            <Box display={'flex'} width={'100%'} flexDirection={'column'}>\n              <ModalCloseButton\n                onClose={() => setShowIFrame({ isShow: false, url: '' })}\n                {...rest}\n              />\n              {/*{onBack ? <ModalBackButton onBack={onBack}  {...rest}/> : <></>}*/}\n            </Box>\n            <iframe src={isShowIFrame.url} />\n          </SwitchPanelStyled>\n        </MuiModal>\n      </>\n    )\n  },\n)\nexport const ModalGroupL1 = withTranslation('common')(\n  ({\n    onWalletConnectPanelClose,\n    depositProps,\n    assetsRawData,\n    ...rest\n  }: WithTranslation & {\n    depositProps: DepositProps<any, any>\n    assetsRawData: AssetsRawDataItem[]\n    onWalletConnectPanelClose?: (event: MouseEvent) => void\n  }) => {\n    const { etherscanBaseUrl } = useSystem()\n\n    useAccountModal()\n\n    const {\n      modals: { isShowAccount, isShowConnect, isShowSupport },\n      setShowSupport,\n    } = useOpenModals()\n    const { account } = useAccount()\n\n    return (\n      <>\n        <AlertNotSupport\n          open={isShowSupport.isShow}\n          handleClose={() => {\n            setShowSupport({ isShow: false })\n          }}\n        />\n        {/*<ModalRedPacketPanel etherscanBaseUrl={etherscanBaseUrl} />*/}\n        <ModalWalletConnectPanel\n          {...{\n            ...rest,\n            open: isShowConnect.isShow,\n            onClose: onWalletConnectPanelClose,\n          }}\n        />\n\n        <ModalAccountL1Info\n          {...{\n            ...rest,\n            assetsRawData,\n            etherscanBaseUrl,\n            account,\n            open: isShowAccount.isShow,\n            depositProps,\n          }}\n        />\n      </>\n    )\n  },\n)\nexport * from './AmmPoolModal'\nexport * from './RedPacketModal'\nexport * from './DualModal'\nexport * from './AccountModal/components/NFTDetail'\n\nexport { ModalWalletConnectPanel }\n"
  },
  {
    "path": "packages/core/src/react-app-env.d.ts",
    "content": "/// <reference types=\"react-scripts\" />\n"
  },
  {
    "path": "packages/core/src/reportWebVitals.ts",
    "content": "import { ReportHandler } from 'web-vitals'\n\nconst reportWebVitals = (onPerfEntry?: ReportHandler) => {\n  if (onPerfEntry && onPerfEntry instanceof Function) {\n    import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {\n      getCLS(onPerfEntry)\n      getFID(onPerfEntry)\n      getFCP(onPerfEntry)\n      getLCP(onPerfEntry)\n      getTTFB(onPerfEntry)\n    })\n  }\n}\n\nexport default reportWebVitals\n"
  },
  {
    "path": "packages/core/src/services/account/accountServices.ts",
    "content": "import { AccountStatus, myLog, UIERROR_CODE } from '@loopring-web/common-resources'\n\nimport { Subject } from 'rxjs'\nimport { banxaService, LoopringAPI, OrderENDReason, store } from '../../index'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport _ from 'lodash'\nimport { resetLayer12Data, resetLayer2Data } from './resetAccount'\nimport { AccountCommands } from './command'\nimport { updateAccountStatus } from '../../stores/account/reducer'\nimport {\n  setShowDeposit,\n  setShowNFTDeploy,\n  setShowNFTDeposit,\n  setShowNFTMintAdvance,\n  setShowNFTTransfer,\n  setShowNFTWithdraw,\n  setShowTransfer,\n  setShowWithdraw,\n  setShowActiveAccount,\n  setShowExportAccount,\n  setShowResetAccount,\n  setShowRedPacket,\n  setShowClaimWithdraw,\n} from '@loopring-web/component-lib'\n\nconst subject = new Subject<{ status: AccountCommands; data: any }>()\n\nexport const accountServices = {\n  //INFO: for update Account and unlock account\n  sendSign: async () => {\n    subject.next({\n      status: AccountCommands.ProcessSign,\n      data: undefined,\n    })\n  },\n  sendSignDeniedByUser: () => {\n    subject.next({\n      status: AccountCommands.SignDeniedByUser,\n      data: undefined,\n    })\n  },\n  sendErrorUnlock: (error?: sdk.RESULT_INFO, walletType?: sdk.WalletType) => {\n    subject.next({\n      status: AccountCommands.ErrorSign,\n      data: {\n        walletType,\n        error:\n          error ??\n          ({\n            code: UIERROR_CODE.UNKNOWN,\n            msg: 'unknown error',\n          } as sdk.RESULT_INFO),\n      },\n    })\n  },\n\n  sendUpdateAccStatusAndReset: (readyState: AccountStatus, accountId: number = -1) => {\n    store.dispatch(\n      updateAccountStatus({\n        accountId,\n        readyState,\n        apiKey: '',\n        eddsaKey: '',\n        publicKey: '',\n        nonce: undefined,\n      }),\n    )\n\n    if (readyState === AccountStatus.ERROR_NETWORK) {\n      resetLayer12Data()\n      subject.next({\n        status: AccountCommands.ErrorNetwork,\n        data: undefined,\n      })\n    } else {\n      const { accAddress } = store.getState().account\n      accountServices.sendCheckAccount(accAddress)\n    }\n  },\n  sendAccountLock: async (accInfo?: sdk.AccountInfo) => {\n    const updateInfo = accInfo\n      ? {\n          readyState: AccountStatus.LOCKED,\n          accountId: accInfo.accountId,\n          nonce: accInfo.nonce,\n          level: accInfo.tags?.split(';').find((item) => /vip/gi.test(item)) ?? '',\n          keyNonce: accInfo.keyNonce,\n          keySeed: accInfo.keySeed,\n          accAddress: accInfo.owner,\n          hasUnknownCollection: undefined,\n        }\n      : {\n          readyState: AccountStatus.LOCKED,\n          apiKey: '',\n          eddsaKey: '',\n          publicKey: '',\n          nonce: undefined,\n          hasUnknownCollection: undefined,\n        }\n    store.dispatch(updateAccountStatus(updateInfo))\n    store.dispatch(setShowTransfer({ isShow: false }))\n    store.dispatch(setShowNFTTransfer({ isShow: false }))\n    store.dispatch(setShowWithdraw({ isShow: false }))\n    store.dispatch(setShowNFTWithdraw({ isShow: false }))\n    store.dispatch(setShowDeposit({ isShow: false }))\n    store.dispatch(setShowNFTDeposit({ isShow: false }))\n    store.dispatch(setShowNFTDeploy({ isShow: false }))\n    store.dispatch(setShowNFTMintAdvance({ isShow: false }))\n    store.dispatch(setShowActiveAccount({ isShow: false }))\n    store.dispatch(setShowResetAccount({ isShow: false }))\n    store.dispatch(setShowExportAccount({ isShow: false }))\n    store.dispatch(setShowRedPacket({ isShow: false }))\n    store.dispatch(setShowClaimWithdraw({ isShow: false }))\n    banxaService.banxaEnd({\n      reason: OrderENDReason.UserCancel,\n      data: { resource: 'Account Locked' },\n    })\n\n    resetLayer2Data()\n    // await sleep(50)\n\n    _.delay(() => {\n      subject.next({\n        status: AccountCommands.LockAccount,\n        data: undefined,\n      })\n    }, 10)\n  },\n  sendActiveAccountDeposit: () => {},\n  sendAccountSigned: ({\n    // accountId,\n    apiKey,\n    // frozen,\n    eddsaKey,\n    // isReset,\n    // keySeed,\n    // nonce,\n    isInCounterFactualStatus,\n    isContract,\n    accountId\n  }: {\n    apiKey?: string\n    eddsaKey?: any\n    isInCounterFactualStatus?: boolean\n    isContract?: boolean\n    accountId?: number\n  }) => {\n    const updateInfo =\n      apiKey && eddsaKey\n        ? {\n            // accountId,\n            apiKey,\n            eddsaKey,\n            // nonce,\n            // frozen,\n            // keySeed,\n            publicKey: {\n              x: sdk.toHex(sdk.toBig(eddsaKey.keyPair.publicKeyX)),\n              y: sdk.toHex(sdk.toBig(eddsaKey.keyPair.publicKeyY)),\n            },\n            readyState: AccountStatus.ACTIVATED,\n            _accountIdNotActive: -1,\n            isInCounterFactualStatus,\n            isContract,\n            accountId\n          }\n        : { readyState: AccountStatus.ACTIVATED }\n\n    store.dispatch(updateAccountStatus(updateInfo))\n    subject.next({\n      status: AccountCommands.AccountUnlocked,\n      data: undefined,\n    })\n  },\n  sendNoAccount: (ethAddress: string) => {\n    store.dispatch(\n      updateAccountStatus({\n        readyState: AccountStatus.NO_ACCOUNT,\n        accAddress: ethAddress,\n        hasUnknownCollection: undefined,\n        _accountIdNotActive: -1,\n      }),\n    )\n    subject.next({\n      status: AccountCommands.NoAccount,\n      data: undefined,\n    })\n  },\n  sendNeedUpdateAccount: async (accInfo: sdk.AccountInfo) => {\n    myLog('sendNeedUpdateAccount accInfo:', accInfo)\n    store.dispatch(\n      updateAccountStatus({\n        readyState: AccountStatus.NOT_ACTIVE,\n        accAddress: accInfo.owner,\n        _accountIdNotActive: accInfo.accountId,\n        tags: accInfo.tags,\n        nonce: accInfo.nonce,\n        keySeed: accInfo.keySeed,\n        hasUnknownCollection: undefined,\n      }),\n    )\n    subject.next({\n      status: AccountCommands.SignAccount,\n      data: accInfo,\n    })\n  },\n  sendCheckAccount: async (ethAddress: string, _chainId?: sdk.ChainId | undefined) => {\n    myLog('After connect >>,sendCheckAccount: step3 processAccountCheck', ethAddress)\n    const account = store.getState().account\n    subject.next({\n      status: AccountCommands.ProcessAccountCheck,\n      data: undefined,\n    })\n\n    if (\n      ethAddress &&\n      LoopringAPI.exchangeAPI &&\n      ((_chainId && LoopringAPI?.__chainId__?.toString() == _chainId.toString()) || !_chainId)\n    ) {\n      const { accInfo } = await LoopringAPI.exchangeAPI.getAccount({\n        owner: ethAddress,\n      })\n      if (accInfo === undefined) {\n        if (\n          account.readyState !== AccountStatus.NO_ACCOUNT ||\n          account.accountId !== -1 ||\n          account.accAddress.toLowerCase() !== ethAddress.toLowerCase()\n        ) {\n          myLog('-------sendCheckAccount sendNoAccount!')\n          accountServices.sendNoAccount(ethAddress)\n        }\n      } else {\n        if (account.accountId == accInfo.accountId && account.publicKey.x) {\n          myLog('-------sendCheckAccount already Unlock!')\n          accountServices.sendAccountSigned({\n            ...account,\n          })\n        } else if (accInfo.accountId) {\n          if (!accInfo.publicKey.x || !accInfo.publicKey.y) {\n            myLog('-------sendCheckAccount need update account!')\n            accountServices.sendNeedUpdateAccount({\n              ...accInfo,\n            })\n          } else {\n            myLog('-------sendCheckAccount need unlockAccount!', accInfo)\n            accountServices.sendAccountLock(accInfo)\n          }\n        } else {\n          myLog('-------sendCheckAccount  unexpected accInfo:', accInfo)\n          throw Error('unexpected accinfo:' + accInfo)\n        }\n      }\n    } else {\n      myLog('-------sendCheckAccount unexpected no ethAddress:' + ethAddress)\n      store.dispatch(\n        updateAccountStatus({\n          accAddress: ethAddress,\n          readyState: AccountStatus.UN_CONNECT,\n          hasUnknownCollection: undefined,\n          _accountIdNotActive: -1,\n        }),\n      )\n    }\n  },\n\n  onSocket: () => subject.asObservable(),\n}\n"
  },
  {
    "path": "packages/core/src/services/account/activateAccount.ts",
    "content": "import {\n  DAYS,\n  getTimestampDaysLater,\n  LoopringAPI,\n  store,\n  EddsaKey,\n  callSwitchChain,\n} from '../../index'\nimport { ChainIdExtends, FeeInfo, myLog, UIERROR_CODE } from '@loopring-web/common-resources'\nimport { ConnectProviders, connectProvides } from '@loopring-web/web3-provider'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { providers, utils, Contract } from 'ethers'\nimport { updateAccountStatus } from '../../stores/account/reducer'\n\nexport async function activateAccount({\n  isHWAddr,\n  referral,\n  feeInfo = {} as FeeInfo,\n}: {\n  isHWAddr: boolean\n  feeInfo?: FeeInfo\n  isReset?: boolean\n  referral?: string | null\n}): Promise<EddsaKey> {\n  // let result: ActionResult =;\n  const system = store.getState().system\n  let eddsaKey: any = undefined //isReset ?  //: account.eddsaKey;\n  const { tokenMap } = store.getState().tokenMap\n  // const {} = store.getState().account;\n  const {\n    accAddress,\n    connectName,\n    eddsaKey: { counterFactualInfo },\n  } = store.getState().account\n\n  if (\n    !system.exchangeInfo?.exchangeAddress ||\n    system.chainId === ChainIdExtends.NONETWORK ||\n    !LoopringAPI?.exchangeAPI ||\n    !accAddress\n  ) {\n    throw { code: UIERROR_CODE.DATA_NOT_READY }\n  }\n  let accInfo\n  try {\n    const accountResponse = await LoopringAPI.exchangeAPI.getAccount({\n      owner: accAddress,\n    })\n    if ((accountResponse as sdk.RESULT_INFO).code || (accountResponse as sdk.RESULT_INFO).message) {\n      throw accountResponse\n    } else {\n      accInfo = accountResponse.accInfo\n    }\n  } catch (error: any) {\n    throw error\n  }\n\n  let keySeed = sdk.GlobalAPI.KEY_MESSAGE.replace(\n    '${exchangeAddress}',\n    system.exchangeInfo.exchangeAddress,\n  ).replace('${nonce}', accInfo.nonce.toString())\n\n  if (feeInfo?.belong && feeInfo.feeRaw && connectProvides.usedWeb3) {\n    const feeToken = tokenMap[feeInfo.belong]\n    const tokenId = feeToken.tokenId\n    const fee = feeInfo.feeRaw\n    const _chainId = await connectProvides.usedWeb3.eth.getChainId()\n    try {\n      await callSwitchChain(_chainId)\n    } catch (error: any) {\n      throw error\n    }\n    myLog('switchChain Error')\n\n    try {\n      await callSwitchChain(_chainId)\n      eddsaKey = await sdk.generateKeyPair({\n        web3: connectProvides.usedWeb3 as any,\n        address: accInfo.owner,\n        keySeed,\n        walletType: (ConnectProviders[ connectName ] ?? connectName) as unknown as sdk.ConnectorNames,\n        chainId: system.chainId as any,\n        counterFactualInfo: counterFactualInfo ?? undefined,\n      })\n    } catch (error: any) {\n      throw error\n    }\n    myLog('generateKeyPair done')\n\n    // @ts-ignore\n    const request: sdk.UpdateAccountRequestV3 = {\n      // // @ts-ignore\n      // recommenderAccountId: \"\" as any,\n      exchange: system.exchangeInfo.exchangeAddress,\n      owner: accInfo.owner,\n      accountId: accInfo.accountId,\n      publicKey: { x: eddsaKey.formatedPx, y: eddsaKey.formatedPy },\n      maxFee: {\n        tokenId,\n        volume: fee.toString(),\n      },\n      validUntil: getTimestampDaysLater(DAYS),\n      keySeed,\n      // @ts-ignore\n      recommenderAccountId: referral ? referral : undefined,\n      nonce: accInfo.nonce as number,\n    }\n\n    myLog('updateAccountFromServer req:', request)\n    try {\n      const response = await LoopringAPI?.userAPI?.updateAccount(\n        {\n          request,\n          web3: connectProvides.usedWeb3,\n          chainId: system.chainId as any,\n          walletType: (ConnectProviders[connectName] ??\n            connectName) as unknown as sdk.ConnectorNames,\n          isHWAddr,\n          privateKey: eddsaKey.sk,\n        },\n        {\n          accountId: accInfo.accountId,\n          counterFactualInfo: eddsaKey.counterFactualInfo,\n        },\n      )\n      if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n        throw response\n      } else {\n        myLog('updateAccountResponse:', response)\n        return {\n          eddsaKey,\n          accInfo,\n          // code: ActionResultCode.NoError,\n          // data: { eddsaKey, accInfo },\n        }\n      }\n    } catch (error) {\n      throw error\n    }\n  } else {\n    throw { code: UIERROR_CODE.ERROR_ON_FEE_UI }\n  }\n}\n\nconst getSmartWalletUpdateAccount = async (\n  provider: providers.Web3Provider,\n  KEY_MESSAGE: string,\n  accInfo: sdk.AccountInfo,\n  exchangeAddr: string,\n  chainId: number,\n  feeInfo: FeeInfo\n) => {\n  const { tokenMap } = store.getState().tokenMap\n  const feeToken = tokenMap[feeInfo.belong]\n\n  const signer = await provider.getSigner()\n\n  const signature = await signer?.signMessage(KEY_MESSAGE)\n  const eddsaKeyInfo = sdk.generatePrivateKey({\n    sig: signature,\n    counterFactualInfo: undefined,\n    error: null,\n  })\n\n  const data = {\n    owner: accInfo.owner,\n    accountId: accInfo.accountId,\n    publicKey: {\n      x: eddsaKeyInfo.formatedPx,\n      y: eddsaKeyInfo.formatedPy,\n    },\n    exchange: exchangeAddr,\n    validUntil: getTimestampDaysLater(DAYS),\n    nonce: accInfo.nonce,\n    maxFee: {\n      tokenId: feeToken.tokenId,\n      volume: feeInfo.feeRaw!.toString(),\n    },\n  }\n\n  const typedData = sdk.getUpdateAccountEcdsaTypedData(\n    data,\n    chainId,\n  )\n  delete typedData.types['EIP712Domain']\n  const hash = utils._TypedDataEncoder.hash(typedData.domain, typedData.types, typedData.message)\n  const eip712Sig = await signer?._signTypedData(typedData.domain, typedData.types, typedData.message)\n  return {\n    hash,\n    eip712Sig,\n    eddsaKeyInfo,\n    updateAccountRequest: data as sdk.UpdateAccountRequestV3\n  }\n}\n\nconst approveHash = async (\n  provider: providers.Web3Provider,\n  hash: string,\n  exchangeAddress: string,\n  owner: string,\n) => {\n  const signer = await provider.getSigner()\n  const contract = new Contract(exchangeAddress, sdk.Contracts.exchange36Abi.exchange, signer)\n  return contract.approveTransaction(owner, hash)\n}\n\nexport async function activateAccountSmartWallet({\n  referral,\n  feeInfo = {} as FeeInfo,\n}: {\n  feeInfo?: FeeInfo\n  isReset?: boolean\n  referral?: string | null\n}) {\n  const system = store.getState().system\n  const { accAddress } = store.getState().account\n\n  if (\n    !system.exchangeInfo?.exchangeAddress ||\n    system.chainId === ChainIdExtends.NONETWORK ||\n    !LoopringAPI?.exchangeAPI ||\n    !accAddress\n  ) {\n    throw { code: UIERROR_CODE.DATA_NOT_READY }\n  }\n  const accInfo = await LoopringAPI.exchangeAPI\n    .getAccount({\n      owner: accAddress,\n    })\n    .then((res) => {\n      if ((res as sdk.RESULT_INFO).code || (res as sdk.RESULT_INFO).message) {\n        throw res\n      } else {\n        return res.accInfo\n      }\n    })\n\n  const keySeed = sdk.GlobalAPI.KEY_MESSAGE.replace(\n    '${exchangeAddress}',\n    system.exchangeInfo.exchangeAddress,\n  ).replace('${nonce}', accInfo.nonce.toString())\n\n  if (!feeInfo?.belong || !feeInfo.feeRaw || !connectProvides.usedWeb3) {\n    throw { code: UIERROR_CODE.ERROR_ON_FEE_UI }\n  }\n  const _chainId = await connectProvides.usedWeb3.eth.getChainId()\n  await callSwitchChain(_chainId)\n  const provider = new providers.Web3Provider(connectProvides.usedWeb3.currentProvider as any)\n  const { hash, eip712Sig, eddsaKeyInfo, updateAccountRequest } = await getSmartWalletUpdateAccount(\n    provider,\n    keySeed,\n    accInfo,\n    system.exchangeInfo.exchangeAddress,\n    _chainId,\n    feeInfo\n  )\n\n  return {\n    request: { ...updateAccountRequest, hashApproved: hash, ecdsaSignature: eip712Sig },\n    eddsaKey: eddsaKeyInfo,\n    approveFn: () => approveHash(provider, hash, system.exchangeInfo!.exchangeAddress, accInfo.owner)\n  }\n\n}\n\nexport async function updateAccountRecursively({\n  request,\n  eddsaKey,\n}: {\n  request?: sdk.UpdateAccountRequestV3\n  eddsaKey?: EddsaKey\n}) {\n  const system = store.getState().system\n  if (!request || !connectProvides.usedWeb3) {\n    throw { code: UIERROR_CODE.ERROR_ON_FEE_UI }\n  }\n  \n  const response = await LoopringAPI?.userAPI?.checkUpdateAccount({\n    request,\n    web3: connectProvides.usedWeb3,\n    chainId: system.chainId as any,\n    isHWAddr: false,\n    privateKey: eddsaKey?.eddsaKey.sk,\n  })\n  if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n    const isNonceNotFoundError = (response as sdk.RESULT_INFO).message === 'No confirmed approve hash '\n    if (isNonceNotFoundError) {\n      await sdk.sleep(15 * 1000)\n      return updateAccountRecursively({ request, eddsaKey })\n    } else {\n      throw response\n    }\n  } else {\n    store.dispatch(\n      updateAccountStatus({})\n    )\n    return response\n  }\n}\n"
  },
  {
    "path": "packages/core/src/services/account/checkAccount.ts",
    "content": "import { accountServices } from './accountServices'\nimport { isCoinbaseSmartWallet, LoopringAPI, store, toggleCheck } from '../../index'\nimport { coinbaseSmartWalletChains, myLog } from '@loopring-web/common-resources'\nimport { ChainId, generateKeyPair } from '@loopring-web/loopring-sdk'\nimport { cleanAccountStatus } from '../../stores/account/reducer'\n\nexport const checkAccount = async (\n  newAccAddress: string,\n  chainId: ChainId | undefined,\n) => {\n  const { account } = store.getState()\n  const accountInfoRealTime = await LoopringAPI.exchangeAPI?.getAccount({owner: newAccAddress})\n  if (\n    account.accAddress === '' ||\n    account.accAddress.toLowerCase() !== newAccAddress.toLowerCase()\n  ) {\n    store.dispatch(cleanAccountStatus(undefined))\n    accountServices.sendCheckAccount(newAccAddress, chainId)\n  } else if (newAccAddress && newAccAddress !== '') {\n    if (account.accountId === -1) {\n      accountServices.sendCheckAccount(newAccAddress)\n    } else if (accountInfoRealTime?.accInfo.accountId && account.apiKey && account.eddsaKey) {\n      accountServices.sendAccountSigned({\n        apiKey: account.apiKey,\n        eddsaKey: account.eddsaKey,\n        isInCounterFactualStatus: account.isInCounterFactualStatus,\n        isContract: account.isContract,\n      })\n    } else {\n      accountServices.sendAccountLock()\n    }\n  }\n}\n"
  },
  {
    "path": "packages/core/src/services/account/command.ts",
    "content": "export enum AccountCommands {\n  ErrorNetwork = 'ErrorNetwork',\n  LockAccount = 'LockAccount', // clear private data\n  NoAccount = 'NoAccount', //\n  DepositingAccount = 'DepositingAccount',\n  ErrorApproveToken = 'ErrorApproveToken',\n  ErrorDepositSign = 'ErrorDepositSign',\n  ProcessDeposit = 'ProcessDeposit', // two or one step\n  SignAccount = 'SignAccount', //unlock or update account  assgin\n  SignDeniedByUser = 'SignDeniedByUser',\n  ErrorSign = 'ErrorSign',\n  ProcessSign = 'ProcessSign',\n  ProcessAccountCheck = 'ProcessAccountCheck',\n  AccountUnlocked = 'AccountUnlocked',\n}\n"
  },
  {
    "path": "packages/core/src/services/account/index.ts",
    "content": "export * from './accountServices'\nexport * from './activateAccount'\nexport * from './checkAccount'\nexport * from './lockAccount'\nexport * from './networkUpdate'\nexport * from './resetAccount'\nexport * from './unlockAccount'\nexport * from './useAccountHook'\nexport * from './command'\n"
  },
  {
    "path": "packages/core/src/services/account/lockAccount.ts",
    "content": "import { AccountStatus } from '@loopring-web/common-resources'\nimport { accountServices } from './accountServices'\nimport { resetSystemData } from './resetAccount'\n\nexport function lockAccount() {\n  accountServices.sendAccountLock()\n}\n\nexport function goErrorNetWork() {\n  accountServices.sendUpdateAccStatusAndReset(AccountStatus.ERROR_NETWORK)\n}\n\n// Do something clear the session storage related to Network\nexport function cleanLayer2() {\n  accountServices.sendUpdateAccStatusAndReset(AccountStatus.UN_CONNECT)\n  resetSystemData()\n}\n"
  },
  {
    "path": "packages/core/src/services/account/networkUpdate.ts",
    "content": "import { accountServices, cleanLayer2, goErrorNetWork, store } from '../../index'\n\nimport { AccountStatus, myLog, SagaStatus, SUPPORTING_NETWORKS } from '@loopring-web/common-resources'\nimport { updateAccountStatus } from '../../stores/account/reducer'\nimport { updateSystem } from '../../stores/system/reducer'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { ChainId } from '@loopring-web/loopring-sdk'\nimport { setDefaultNetwork } from '@loopring-web/component-lib'\n\nexport const networkUpdate = async (chainId?: ChainId | string): Promise<boolean> => {\n  let { defaultNetwork } = store.getState().settings\n  const { status: systemStatus } = store.getState().system\n  myLog('chainId,defaultNetwork', chainId, defaultNetwork)\n  const { _chainId: accountChainId, accAddress, readyState } = store.getState().account\n  if (chainId && chainId !== defaultNetwork) {\n    let _chainId = Number(chainId)\n    if (SUPPORTING_NETWORKS.includes(_chainId.toString())) {\n      store.dispatch(setDefaultNetwork(_chainId))\n      if (systemStatus !== SagaStatus.UNSET) {\n        await sdk.sleep(10)\n      }\n      store.dispatch(updateSystem({ chainId: Number(_chainId) }))\n      if (readyState !== AccountStatus.UN_CONNECT && Number(accountChainId) !== chainId) {\n        store.dispatch(\n          updateAccountStatus({\n            wrongChain: false,\n          }),\n        )\n        cleanLayer2()\n        accountServices.sendCheckAccount(accAddress, accountChainId as any)\n      }\n      return true\n    } else {\n      store.dispatch(updateAccountStatus({ wrongChain: true }))\n      goErrorNetWork()\n      return false\n    }\n  } else {\n    if (SUPPORTING_NETWORKS.includes(defaultNetwork.toString())) {\n      if (systemStatus !== SagaStatus.UNSET) {\n        await sdk.sleep(10)\n      }\n      store.dispatch(updateSystem({ chainId: defaultNetwork }))\n      store.dispatch(\n        updateAccountStatus({\n          wrongChain: false,\n        }),\n      )\n      if (defaultNetwork !== accountChainId) {\n        myLog('chainId,defaultNetwork', accountChainId, defaultNetwork)\n        cleanLayer2()\n      }\n      return true\n    } else {\n      store.dispatch(updateAccountStatus({ wrongChain: true }))\n      goErrorNetWork()\n      return false\n    }\n  }\n}\n"
  },
  {
    "path": "packages/core/src/services/account/resetAccount.ts",
    "content": "import { resetUserRewards } from '../../stores/userRewards/reducer'\nimport { reset as resetWalletLayer1 } from '../../stores/walletLayer1/reducer'\nimport { reset as resetWalletLayer2 } from '../../stores/walletLayer2/reducer'\nimport { reset as resetwalletLayer2NFT } from '../../stores/walletLayer2NFT/reducer'\nimport { reset as resetContacts } from '../../stores/contacts/reducer'\nimport { reset as resetVaultLayer2 } from '../../stores/vaultLayer2/reducer'\n\nimport { resetAmount } from '../../stores/amount/reducer'\nimport { store } from '../../stores'\nimport { resetTokenPrices } from '../../stores/tokenPrices/reducer'\nimport { resetTicker } from '../../stores/ticker/reducer'\nimport { updateToggleStatus } from '@loopring-web/component-lib'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { myLog } from '@loopring-web/common-resources'\nimport { LoopringAPI } from '../../'\n\nexport async function resetLayer12Data() {\n  store.dispatch(resetAmount(undefined))\n  store.dispatch(resetUserRewards(undefined))\n  store.dispatch(resetWalletLayer1(undefined))\n  store.dispatch(resetWalletLayer2(undefined))\n  store.dispatch(resetVaultLayer2(undefined))\n  store.dispatch(resetContacts(undefined))\n  store.dispatch(resetwalletLayer2NFT(undefined))\n  let toggle = {}\n  if (\n    store.getState().system.chainId !== sdk.ChainId.SEPOLIA &&\n    store.getState().system.dexToggleUrl\n  ) {\n    toggle = await fetch(store.getState().system.dexToggleUrl)\n      .then((response) => {\n        if (response.ok) {\n          return response.json()\n        }\n      })\n      .catch(() => ({}))\n  }\n  store.dispatch(\n    updateToggleStatus({\n      chainId: store.getState().settings.defaultNetwork,\n      account: store.getState().account,\n      order: { enable: true, reason: undefined },\n      joinAmm: { enable: true, reason: undefined },\n      exitAmm: { enable: true, reason: undefined },\n      transfer: { enable: true, reason: undefined },\n      transferNFT: { enable: true, reason: undefined },\n      defi: { enable: true, reason: undefined },\n      deposit: { enable: true, reason: undefined },\n      depositNFT: { enable: true, reason: undefined },\n      withdraw: { enable: true, reason: undefined },\n      withdrawNFT: { enable: true, reason: undefined },\n      mintNFT: { enable: true, reason: undefined },\n      deployNFT: { enable: true, reason: undefined },\n      updateAccount: { enable: true, reason: undefined },\n      LRCStackInvest: { enable: true, reason: undefined },\n      redPacketNFTV1: { enable: true, reason: undefined },\n      claim: { enable: true, reason: undefined },\n      ...toggle,\n    }),\n  )\n}\n\nexport async function resetSystemData() {\n  store.dispatch(resetTokenPrices(undefined))\n  store.dispatch(resetTicker(undefined))\n}\n\nexport function resetLayer2Data() {\n  store.dispatch(resetAmount(undefined))\n  store.dispatch(resetUserRewards(undefined))\n  store.dispatch(resetWalletLayer2(undefined))\n  store.dispatch(resetVaultLayer2(undefined))\n  store.dispatch(resetwalletLayer2NFT(undefined))\n  store.dispatch(resetContacts(undefined))\n}\n\nconst LoopFrozenFlag = true\n\nexport async function toggleCheck(\n  chainId?: sdk.ChainId,\n  dexToggleUrl?: string,\n  whiteList?: string,\n) {\n  if (chainId === undefined) {\n    const system = store.getState().system\n    // chainId = (system.chainId ?? sdk.ChainId.MAINNET) as sdk.ChainId\n    dexToggleUrl = system.dexToggleUrl\n  }\n\n  const account = store.getState().account\n\n  const accountInfo = account.accAddress\n    ? await LoopringAPI?.exchangeAPI?.getAccount({\n        owner: account.accAddress,\n      })\n    : undefined\n  if (!accountInfo) return\n  if (accountInfo.accInfo?.frozen === LoopFrozenFlag) {\n    myLog('account.frozen ___timer___', account.accountId)\n    store.dispatch(\n      updateToggleStatus({\n        order: { enable: false, reason: 'account frozen' },\n        joinAmm: { enable: false, reason: 'account frozen' },\n        exitAmm: { enable: false, reason: 'account frozen' },\n        transfer: { enable: false, reason: 'account frozen' },\n        transferNFT: { enable: false, reason: 'account frozen' },\n        withdraw: { enable: false, reason: 'account frozen' },\n        withdrawNFT: { enable: false, reason: 'account frozen' },\n        mintNFT: { enable: true, reason: 'account frozen' },\n        deployNFT: { enable: false, reason: 'account frozen' },\n        defiInvest: { enable: false, reason: 'account frozen' },\n        WSTEHTInvest: { enable: false, reason: 'account frozen' },\n        RETHInvest: { enable: false, reason: 'account frozen' },\n        dualInvest: { enable: false, reason: 'account frozen' },\n        collectionNFT: { enable: false, reason: 'account frozen' },\n        claim: { enable: false, reason: 'account frozen' },\n        redPacketNFTV1: { enable: false, reason: 'account frozen' },\n        LRCStackInvest: { enable: false, reason: 'account frozen' },\n        BTradeInvest: { enable: false, reason: 'account frozen' },\n        StopLimit: { enable: false, reason: 'account frozen' },\n        transferToTaikoAccount: { enable: false, reason: 'account frozen' },\n      }),\n    )\n  } else if (dexToggleUrl) {\n    Promise.all([\n      dexToggleUrl\n        ? fetch(dexToggleUrl).then((response) => (response?.ok ? response.json() : {}))\n        : Promise.resolve(undefined),\n      whiteList\n        ? fetch(whiteList).then((response) => (response?.ok ? response.json() : {}))\n        : Promise.resolve(undefined),\n    ])\n      .then(([toggle, _whiteListRes]) => {\n        store.dispatch(\n          updateToggleStatus({\n            chainId: store.getState().settings.defaultNetwork,\n            account,\n            order: { enable: true, reason: undefined },\n            joinAmm: { enable: true, reason: undefined },\n            exitAmm: { enable: true, reason: undefined },\n            transfer: { enable: true, reason: undefined },\n            transferNFT: { enable: true, reason: undefined },\n            defi: { enable: true, reason: undefined },\n            deposit: { enable: true, reason: undefined },\n            depositNFT: { enable: true, reason: undefined },\n            withdraw: { enable: true, reason: undefined },\n            withdrawNFT: { enable: true, reason: undefined },\n            mintNFT: { enable: true, reason: undefined },\n            deployNFT: { enable: true, reason: undefined },\n            updateAccount: { enable: true, reason: undefined },\n            LRCStackInvest: { enable: true, reason: undefined },\n            redPacketNFTV1: { enable: true, reason: undefined },\n            claim: { enable: true, reason: undefined },\n            transferToTaikoAccount: { enable: true, reason: undefined },\n            ...toggle,\n            whiteList: _whiteListRes,\n          }),\n        )\n      })\n      .catch(() => [{}, {}])\n  }\n}\n"
  },
  {
    "path": "packages/core/src/services/account/unlockAccount.ts",
    "content": "import { ConnectProviders, connectProvides } from '@loopring-web/web3-provider'\nimport { callSwitchChain, DAYS, getTimestampDaysLater, goUpdateAccountCoinbaseWalletUpdateAccountFn, isCoinbaseSmartWallet, isSameEVMAddress, LoopringAPI, store, WalletLayer2Map, appKit, goUpdateAccountCoinbaseWalletBackupKeyOnlyFn, withRetry } from '../../index'\nimport { accountServices } from './accountServices'\nimport { Account, AccountStatus, coinbaseSmartWalletChains, MapChainId, myLog, UIERROR_CODE } from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport Web3 from 'web3'\nimport { nextAccountSyncStatus } from '../../stores/account/reducer'\nimport Decimal from 'decimal.js'\nimport { updateWalletLayer2 } from '../../stores/walletLayer2/reducer'\nimport { AccountStep, setShowAccount, setShowActiveAccount } from '@loopring-web/component-lib'\nimport { providers, BigNumber } from 'ethers'\nimport { persistStoreCoinbaseSmartWalletData } from '../../stores/localStore/coinbaseSmartWalletPersist'\nimport { CoinbaseSmartWalletPersistData } from '../../stores/localStore/coinbaseSmartWalletPersist/interface'\n\nexport const hasLrTAIKODust = () => {\n  const walletLayer2 = store.getState().walletLayer2.walletLayer2\n  return walletLayer2 && walletLayer2['LRTAIKO'] && new Decimal(walletLayer2['LRTAIKO'].total).gt(0)\n}\nexport const resetlrTAIKOIfNeeded = async (\n  account: Account,\n  defaultNetwork: sdk.ChainId,\n  exchangeInfo: sdk.ExchangeInfo,\n  retryTimes: number\n) => {\n  const taikoFarmingAccountStatus = await LoopringAPI?.defiAPI\n    ?.getTaikoFarmingPositionInfo({\n      accountId: account.accountId,\n    })\n    .then((res) => {\n      return res.account.status\n    })\n\n  const walletLayer2 = store.getState().walletLayer2.walletLayer2\n\n  if (\n    !(\n      taikoFarmingAccountStatus === 0 &&\n      hasLrTAIKODust() &&\n      account.apiKey\n    )\n  ) {\n    return\n  }\n  if (retryTimes === 0) {\n    throw new Error('retry_times_out')\n  }\n  const lrTAIKOBalanceInfo = walletLayer2!['LRTAIKO']\n  const { broker } = await LoopringAPI.userAPI!.getAvailableBroker({\n    type: 4,\n  })\n  const storageId = await LoopringAPI.userAPI!.getNextStorageId(\n    {\n      accountId: account.accountId,\n      sellTokenId: lrTAIKOBalanceInfo.tokenId,\n    },\n    account.apiKey,\n  )\n  return LoopringAPI.vaultAPI\n    ?.sendVaultResetToken(\n      {\n        request: {\n          exchange: exchangeInfo!.exchangeAddress,\n          payerAddr: account.accAddress,\n          payerId: account.accountId,\n          payeeId: 0,\n          payeeAddr: broker,\n          storageId: storageId.offchainId,\n          token: {\n            tokenId: lrTAIKOBalanceInfo.tokenId,\n            volume: lrTAIKOBalanceInfo.total,\n          },\n          maxFee: {\n            // @ts-ignore\n            tokenId: lrTAIKOBalanceInfo.tokenId,\n            volume: '0',\n          },\n          validUntil: getTimestampDaysLater(DAYS),\n          memo: '',\n        } as any,\n        web3: undefined as any,\n        chainId: defaultNetwork,\n        walletType: sdk.ConnectorNames.Unknown,\n        eddsaKey: account.eddsaKey.sk,\n        apiKey: account.apiKey,\n      },\n      {\n        accountId: account.accountId,\n        counterFactualInfo: account.eddsaKey.counterFactualInfo,\n      },\n      '1',\n    )\n    .then(() => {\n      store.dispatch(updateWalletLayer2({}))\n    })\n    .then(() => sdk.sleep(1000 * 2))\n    .then(() => resetlrTAIKOIfNeeded(account, defaultNetwork, exchangeInfo, retryTimes - 1))\n}\n\n\nexport const getAndSaveEncryptedSKFromServer = async (accAddress: string, defaultNetwork: sdk.ChainId) => {\n  store.dispatch(\n    setShowAccount({\n      isShow: true,\n      step: AccountStep.UpdateAccount_Approve_WaitForAuth,\n    }),\n  )\n\n  const validUntilInMs = Date.now() + 1000 * 60 * 30\n  const walletProvider = appKit.getProvider('eip155')\n  const messageToSign = `\n      |No EDDSA key file detected in your environment.\n      |Please sign the message to retrieve the encrypted EDDSA file from the Loopring server, allowing you to avoid resetting your account.\n      |Note: This request will expire after ${validUntilInMs}.`\n    .trim()\n    .replace(/^\\s*\\|/gm, '')\n  const provider = new providers.Web3Provider(walletProvider as any)\n\n  const ecdsaSig = await provider.getSigner().signMessage(messageToSign)\n  const res = await withRetry(\n    () =>\n      LoopringAPI!.userAPI!.getEncryptedEcdsaKey({\n        owner: accAddress,\n        validUntilInMs,\n        ecdsaSig: ecdsaSig,\n      }).then((res) => {\n        if (!res?.data) {\n          throw res\n        } else {\n          return res\n        }\n      }),\n    3,\n    1000,\n  )()\n  .catch((e) => {\n    throw new Error('getEncryptedEcdsaKey failed')\n  })\n  const accInfo = await LoopringAPI.exchangeAPI?.getAccount({\n    owner: accAddress,\n  })\n\n  const data: CoinbaseSmartWalletPersistData = {\n    eddsaKey: {\n      sk: res?.data.encryptedEddsaPrivateKey,\n      formatedPx: accInfo?.accInfo.publicKey.x!,\n      formatedPy: accInfo?.accInfo.publicKey.y!,\n      keyPair: {\n        publicKeyX: BigNumber.from(accInfo?.accInfo.publicKey.x).toString(),\n        publicKeyY: BigNumber.from(accInfo?.accInfo.publicKey.y).toString(),\n        secretKey: '',\n      },\n    },\n    wallet: accAddress,\n    nonce: res?.data.nonce,\n    chainId: defaultNetwork,\n    updateAccountData: {\n      updateAccountNotFinished: false,\n      json: ''\n    },\n    eddsaKeyBackup: {\n      backupNotFinished: false,\n      json: ''\n    }\n  }\n  store.dispatch(\n    persistStoreCoinbaseSmartWalletData(data)\n  )\n}\n\nconst checkBeforeUnlock = async () => {\n  const {\n    account: { accAddress, nonce, accountId },\n    settings: { defaultNetwork },\n    localStore: { coinbaseSmartWalletPersist },\n    system: { exchangeInfo },\n  } = store.getState()\n  if (!exchangeInfo) {\n    return false\n  }\n\n  if (coinbaseSmartWalletChains.includes(defaultNetwork) && await isCoinbaseSmartWallet(accAddress, defaultNetwork)) {\n    const foundPersistData = coinbaseSmartWalletPersist?.data.find(\n      (item) =>\n        item.chainId === defaultNetwork &&\n        isSameEVMAddress(item.wallet, accAddress) &&\n        item.nonce === nonce,\n    )\n    if (\n      foundPersistData &&\n      !!foundPersistData.eddsaKeyBackup?.backupNotFinished &&\n      foundPersistData.eddsaKeyBackup?.json\n    ) {\n      goUpdateAccountCoinbaseWalletBackupKeyOnlyFn({\n        isReset: false,\n        backupKeyJSON: foundPersistData.eddsaKeyBackup?.json!,\n      })\n    } else if (\n      foundPersistData &&\n      !!foundPersistData.updateAccountData?.updateAccountNotFinished &&\n      foundPersistData.updateAccountData?.json\n    ) {\n      goUpdateAccountCoinbaseWalletUpdateAccountFn({\n        isReset: false,\n        updateAccountJSON: foundPersistData.updateAccountData?.json!,\n      })\n    } else if (foundPersistData && !!foundPersistData.eddsaKey?.sk) {\n      store.dispatch(\n        setShowAccount({ isShow: true, step: AccountStep.Coinbase_Smart_Wallet_Password_Input }),\n      )\n    } else {\n      await getAndSaveEncryptedSKFromServer(accAddress, defaultNetwork)\n        .then(() => {\n          store.dispatch(\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.Coinbase_Smart_Wallet_Password_Input,\n            }),\n          )\n        })\n        .catch(async (e) => {\n          if (e.message === 'getEncryptedEcdsaKey failed') {\n            store.dispatch(\n              setShowAccount({\n                isShow: true,\n                step: AccountStep.Coinbase_Smart_Wallet_Password_Get_Error,\n              }),\n            )\n            return\n          }\n          if (e.code === 'ACTION_REJECTED' || e.code === 4001) {\n            store.dispatch(\n              setShowAccount({\n                isShow: true,\n                step: AccountStep.UnlockAccount_User_Denied,\n              }),\n            )\n            return\n          }\n          const [hasDualInvest, hasVault] = await Promise.all([\n            LoopringAPI.defiAPI\n              ?.getDualTransactions(\n                {\n                  accountId: accountId,\n                  settlementStatuses: sdk.SETTLEMENT_STATUS.UNSETTLED,\n                  investmentStatuses: [\n                    sdk.LABEL_INVESTMENT_STATUS.CANCELLED,\n                    sdk.LABEL_INVESTMENT_STATUS.SUCCESS,\n                    sdk.LABEL_INVESTMENT_STATUS.PROCESSED,\n                    sdk.LABEL_INVESTMENT_STATUS.PROCESSING,\n                  ].join(','),\n                  retryStatuses: [sdk.DUAL_RETRY_STATUS.RETRYING],\n                } as any,\n                '',\n              )\n              .then((res) => res.totalNum && res.totalNum > 0),\n            LoopringAPI.vaultAPI\n              ?.getVaultInfoAndBalance(\n                {\n                  accountId: accountId,\n                },\n                '',\n              )\n              .then((res) => {\n                return res.accountStatus === sdk.VaultAccountStatus.IN_STAKING\n              }),\n          ])\n          const hasPortalOrDual = hasDualInvest || hasVault\n          if (hasPortalOrDual) {\n            store.dispatch(\n              setShowAccount({\n                step: AccountStep.Coinbase_Smart_Wallet_Password_Forget_Password_Confirm,\n                isShow: true,\n              }),\n            )\n          } else {\n            store.dispatch(\n              setShowAccount({\n                step: AccountStep.Coinbase_Smart_Wallet_Password_Forget_Password,\n                isShow: true,\n              }),\n            )\n          }\n          return false\n        })\n    }\n    return false\n    \n  }\n\n  return true\n}\n\nexport async function unlockAccount() {\n  const shouldContinue = await checkBeforeUnlock()\n  if (!shouldContinue) {\n    return\n  }\n  store.dispatch(\n    setShowAccount({\n      isShow: true,\n      step: AccountStep.UpdateAccount_Approve_WaitForAuth,\n    }),\n  )\n  myLog('unlockAccount starts')\n  const accounStore = store.getState().account\n  const { exchangeInfo } = store.getState().system\n  const { isMobile, defaultNetwork } = store.getState().settings\n  myLog('unlockAccount account:', accounStore)\n  accountServices.sendSign()\n  if (\n    exchangeInfo &&\n    LoopringAPI.userAPI &&\n    LoopringAPI.exchangeAPI &&\n    LoopringAPI.walletAPI &&\n    accounStore.nonce !== undefined &&\n    connectProvides?.usedWeb3\n  ) {\n    let walletType, account: any, _chainId: any\n    try {\n      const connectName = (ConnectProviders[accounStore.connectName] ??\n        accounStore.connectName) as unknown as sdk.ConnectorNames\n      const walletTypePromise: Promise<{ walletType: any }> =\n        window.ethereum && connectName === sdk.ConnectorNames.MetaMask && isMobile\n          ? Promise.resolve({ walletType: undefined })\n          : LoopringAPI.walletAPI.getWalletType({\n              wallet: accounStore.accAddress,\n              network: MapChainId[defaultNetwork] as sdk.NetworkWallet\n            })\n      ;[{ accInfo: account }, { walletType }, _chainId] = await Promise.all([\n        LoopringAPI.exchangeAPI.getAccount({\n          owner: accounStore.accAddress,\n        }),\n        walletTypePromise,\n        connectProvides?.usedWeb3?.eth?.getChainId(),\n      ])\n        .then((response) => {\n          if ((response[0] as sdk.RESULT_INFO)?.code) {\n            throw response[0]\n          }\n          return response as any\n        })\n        .catch((error) => {\n          throw error\n        })\n\n      const nonce = account ? account.nonce : accounStore.nonce\n\n      const msg =\n        account.keySeed && account.keySeed !== ''\n          ? account.keySeed\n          : sdk.GlobalAPI.KEY_MESSAGE.replace(\n              '${exchangeAddress}',\n              exchangeInfo.exchangeAddress,\n            ).replace('${nonce}', (nonce - 1).toString())\n\n      await callSwitchChain(_chainId)\n      \n      const response = await LoopringAPI.userAPI.unLockAccount(\n        {\n          keyPair: {\n            web3: connectProvides.usedWeb3 as unknown as Web3,\n            address: account.owner,\n            keySeed: msg,\n            walletType: connectName,\n            chainId: Number(_chainId),\n            accountId: Number(account.accountId),\n            isMobile: isMobile,\n          },\n          request: {\n            accountId: account.accountId,\n          },\n        },\n        account.publicKey,\n      )\n      if (response.hasOwnProperty('apiKey') && response.hasOwnProperty('eddsaKey')) {\n        accountServices.sendAccountSigned({\n          apiKey: (response as any).apiKey,\n          eddsaKey: (response as any).eddsaKey,\n          isInCounterFactualStatus: walletType?.isInCounterFactualStatus,\n          isContract: walletType?.isContract,\n        })\n        \n        // send lrTAIKO back to operator\n        resetlrTAIKOIfNeeded({...accounStore, ...account, ...response}, defaultNetwork, exchangeInfo, 5)\n        .catch((error) => {\n          console.error(error)\n        })\n\n        if (account?.accountId) {\n          LoopringAPI.nftAPI\n            ?.getHadUnknownCollection({\n              accountId: account.accountId,\n            })\n            .then((_response) => {\n              if ((_response as unknown as sdk.RESULT_INFO)?.code) {\n                // console.error(_response)\n                return\n              }\n              if (account && account.accountId === store.getState().account.accountId) {\n                store.dispatch(\n                  nextAccountSyncStatus({\n                    ...store.getState().account,\n                    hasUnknownCollection: _response,\n                  }),\n                )\n              }\n            })\n            .catch((error) => {\n              console.error(error)\n            })\n        }\n      } else {\n        throw response\n      }\n    } catch (e: any) {\n      myLog('unlock', e)\n      if (e instanceof Error && e.message === 'sig is empty') {\n        accountServices.sendErrorUnlock(\n          {\n            msg: 'Signature is empty, please try again',\n            code: 1,\n            message: 'Signature is empty, please try again'\n          },\n          walletType,\n        )\n        return \n      }\n      const error = LoopringAPI.exchangeAPI.genErr(e)\n      const code = sdk.checkErrorInfo(error, true)\n      switch (code) {\n        case sdk.ConnectorError.USER_DENIED:\n        case sdk.ConnectorError.USER_DENIED_2: {          \n          store.dispatch(\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.UnlockAccount_User_Denied,\n            })\n          )\n          return\n        }\n        default:\n          break\n      }\n      accountServices.sendErrorUnlock(\n        {\n          msg: error.msg ?? error.message,\n          code: error.code ?? UIERROR_CODE.UNKNOWN,\n          ...error,\n        },\n        walletType,\n      )\n    }\n  }\n}\n"
  },
  {
    "path": "packages/core/src/services/account/useAccountHook.ts",
    "content": "import React from 'react'\nimport { AccountCommands } from './command'\nimport { accountServices } from './accountServices'\n\nexport function useAccountHook({\n  handleLockAccount, // clear private data\n  handleNoAccount, //\n  handleErrorAccount,\n  handleDepositingAccount,\n  handleErrorApproveToken,\n  handleErrorDepositSign,\n  handleProcessDeposit, // two or one step\n  handleSignAccount, //unlock or update account  assgin\n  handleProcessSign,\n  handleSignDeniedByUser,\n  handleSignError,\n  handleProcessAccountCheck,\n  handleAccountActive,\n}: any) {\n  const subject = React.useMemo(() => accountServices.onSocket(), [])\n  React.useEffect(() => {\n    const subscription = subject.subscribe(\n      ({ data, status }: { status: AccountCommands; data?: any }) => {\n        switch (status) {\n          case AccountCommands.ErrorNetwork:\n            handleErrorAccount(data)\n            break // clear private data\n          case AccountCommands.LockAccount:\n            handleLockAccount(data)\n            break // clear private data\n          case AccountCommands.NoAccount:\n            handleNoAccount(data)\n            break //\n          case AccountCommands.DepositingAccount:\n            handleDepositingAccount(data)\n            break\n          case AccountCommands.ErrorApproveToken:\n            handleErrorApproveToken(data)\n            break\n          case AccountCommands.ErrorDepositSign:\n            handleErrorDepositSign(data)\n            break\n          case AccountCommands.ProcessDeposit:\n            handleProcessDeposit(data)\n            break // two or one step\n          case AccountCommands.SignAccount:\n            handleSignAccount(data)\n            break //unlock or update account  assgin\n          case AccountCommands.ProcessSign:\n            handleProcessSign(data)\n            break\n          case AccountCommands.SignDeniedByUser:\n            handleSignDeniedByUser(data)\n            break\n          case AccountCommands.ErrorSign:\n            handleSignError(data)\n            break\n          case AccountCommands.AccountUnlocked:\n            handleAccountActive(data)\n            break\n        }\n      },\n    )\n    return () => subscription.unsubscribe()\n  }, [\n    subject,\n    handleLockAccount, // clear private data\n    handleErrorAccount,\n    handleNoAccount, //\n    handleDepositingAccount,\n    handleErrorApproveToken,\n    handleErrorDepositSign,\n    handleProcessDeposit, // two or one step\n    handleSignAccount, //unlock or update account  assgin\n    handleProcessSign,\n    handleSignDeniedByUser,\n    handleProcessAccountCheck,\n  ])\n}\n"
  },
  {
    "path": "packages/core/src/services/banxa/banxaService.ts",
    "content": "import * as sdk from '@loopring-web/loopring-sdk'\nimport { ChainId } from '@loopring-web/loopring-sdk'\nimport { LoopringAPI } from '../../api_wrapper'\nimport {\n  Account,\n  BANXA_URLS,\n  BanxaOrder,\n  myLog,\n  VendorProviders,\n} from '@loopring-web/common-resources'\nimport { resetTransferBanxaData, store } from '../../stores'\nimport { Subject } from 'rxjs'\nimport { offFaitService } from './offFaitService'\nimport {\n  // AccountStep,\n  setShowAccount,\n} from '@loopring-web/component-lib'\n\nexport enum BalanceReason {\n  Balance = 0,\n  FeeAndBalance = 1,\n}\n\nexport enum BanxaCheck {\n  CheckOrderStatus = 0,\n  OrderEnd = 1,\n  OrderHide = 2,\n  OrderShow = 3,\n}\n\nexport enum OrderENDReason {\n  UserCancel = 0,\n  Expired = 1,\n  Done = 2,\n  Waiting = 3,\n  BanxaNotReady,\n  CreateOrderFailed = 4,\n}\n\nexport const banxaApiCall = async ({\n  url,\n  query,\n  payload,\n  method,\n  chainId,\n  account,\n}: {\n  url: string\n  query: URLSearchParams | string | string[][]\n  payload: object | undefined\n  method: sdk.ReqMethod\n  chainId: ChainId\n  account: Account\n}): Promise<{ data: any }> => {\n  const querys = url + (query ? '?' + new URLSearchParams(query).toString() : '')\n  const { result } = (await LoopringAPI.globalAPI?.getBanxaAPI(\n    {\n      url: BANXA_URLS[chainId as number],\n      method,\n      query: querys,\n      accountId: account.accountId,\n      payload: JSON.stringify(payload),\n    },\n    account.eddsaKey.sk,\n    account.apiKey,\n  )) ?? { result: null }\n  let data: any\n  try {\n    // @ts-ignore\n    data = JSON.parse(result)?.data\n  } catch (e) {}\n  return { data }\n}\n\nconst subject = new Subject<{\n  status: BanxaCheck\n  data?: {\n    [key: string]: any\n  }\n}>()\nexport const banxaService = {\n  banxaCheckHavePending: async () => {\n    const {\n      account,\n      system: { chainId },\n      localStore: { offRampHistory },\n      // modals:{isShowAccount}\n    } = store.getState()\n    if (\n      offRampHistory[chainId][account.accAddress] &&\n      offRampHistory[chainId][account.accAddress][VendorProviders.Banxa] &&\n      offRampHistory[chainId][account.accAddress][VendorProviders.Banxa]['pending']\n    ) {\n      const _order = offRampHistory[chainId][account.accAddress][VendorProviders.Banxa]['pending']\n      const { data } = await banxaApiCall({\n        chainId: chainId as ChainId,\n        method: sdk.ReqMethod.GET,\n        url: `/api/orders/${_order.orderId}`,\n        query: '',\n        payload: {},\n        account,\n      })\n      if (data) {\n        myLog('banxa Check Have Pending', data.order)\n\n        offFaitService.banxaCheckStatus({\n          data: data.order,\n        })\n        return data\n      }\n    }\n  },\n  openOldOne: async () => {\n    const {\n      account,\n      system: { chainId },\n      localStore: { offRampHistory },\n      // modals:{isShowAccount}\n    } = store.getState()\n\n    store.dispatch(setShowAccount({ isShow: false, info: { isBanxaLaunchLoading: true } }))\n    if (\n      offRampHistory[chainId][account.accAddress] &&\n      offRampHistory[chainId][account.accAddress][VendorProviders.Banxa] &&\n      offRampHistory[chainId][account.accAddress][VendorProviders.Banxa]['pending'] &&\n      offRampHistory[chainId][account.accAddress][VendorProviders.Banxa]['pending'].checkout_iframe\n    ) {\n    } else {\n      banxaService.banxaStart(true)\n    }\n  },\n  banxaStart: async (_createNew = false) => {\n    const {\n      account,\n      system: { chainId },\n      // localStore: { offRampHistory },\n    } = store.getState()\n    let banxa: any = undefined\n    try {\n      // @ts-ignore\n      banxa = new window.Banxa('loopring', chainId == ChainId.SEPOLIA ? 'sandbox' : '')\n    } catch (e) {\n      banxaService.banxaEnd({\n        reason: OrderENDReason.BanxaNotReady,\n        data: 'Banxa SKD is not ready',\n      })\n      return\n    }\n    store.dispatch(setShowAccount({ isShow: false, info: { isBanxaLaunchLoading: true } }))\n    const anchor: any = window.document.querySelector('#iframeBanxaTarget')\n    // anchor.querySelector(\"anchor\");\n    if (anchor && banxa) {\n      anchor.style.display = 'flex'\n      try {\n        const { data } = await banxaApiCall({\n          chainId: chainId as ChainId,\n          account,\n          method: sdk.ReqMethod.POST,\n          url: '/api/orders',\n          query: '',\n          payload: {\n            blockchain: 'LRC',\n            iframe_domain: window.location.href.replace(/http(s)?:\\/\\//, ''), //: BANXA_URLS[chainId].replace(/http(s)?:\\/\\//, \"\"),\n            source: 'USDT',\n            target: 'AUD',\n            refund_address: account.accAddress,\n            return_url_on_success: 'https://loopring.io/#/trade/fiat/Sell',\n            account_reference: account.accAddress,\n          },\n        })\n\n        banxa.generateIframe(\n          '#iframeBanxaTarget',\n          data.order.checkout_iframe,\n          false,\n          // \"800px\", //Optional width parameter – Pass false if not needed.\n          // \"400px\" //Optional height parameter – Pass false if not needed.\n        )\n        offFaitService.banxaCheckStatus({\n          data: {\n            ...data.order,\n            status: data.order.status ?? 'create',\n            id: data.order.id,\n          },\n        })\n        subject.next({\n          status: BanxaCheck.CheckOrderStatus,\n          data: data,\n        })\n      } catch (e) {\n        banxaService.banxaEnd({\n          reason: OrderENDReason.CreateOrderFailed,\n          data: (e as any)?.message,\n        })\n      }\n    }\n\n    // @ts-ignore\n  },\n  KYCDone: () => {\n    subject.next({\n      status: BanxaCheck.OrderHide,\n      data: {\n        reason: 'KYCDone',\n      },\n    })\n  },\n  TransferDone: ({ order }: { order: Partial<BanxaOrder> }) => {\n    offFaitService.banxaCheckStatus({\n      data: {\n        status: 'paymentReceived',\n        id: order.id ?? '',\n        wallet_address: order.wallet_address,\n      },\n    })\n    subject.next({\n      status: BanxaCheck.OrderShow,\n      data: {\n        reason: 'transferDone',\n        id: order.id ?? '',\n      },\n    })\n  },\n  orderDone: () => {},\n  orderExpired: () => {\n    banxaService.banxaEnd({ reason: OrderENDReason.Expired, data: '' })\n  },\n  banxaEnd: ({ reason, data }: { reason: OrderENDReason; data: any }) => {\n    store.dispatch(resetTransferBanxaData(undefined))\n    const parentsNode: any = window.document.querySelector('#iframeBanxaTarget')\n    parentsNode.style = 'display: none'\n    const items = parentsNode?.getElementsByTagName('iframe')\n    for (let index = 0; index < items.length; index++) {\n      const item = items[index];\n      item && item.parentNode.removeChild(item)\n    }\n    subject.next({\n      status: BanxaCheck.OrderEnd,\n      data: {\n        reason,\n        data,\n      },\n    })\n  },\n  banxaConfirm: () => {},\n  onSocket: () => subject.asObservable(),\n}\n"
  },
  {
    "path": "packages/core/src/services/banxa/index.tsx",
    "content": "import React from 'react'\nimport { myLog, OffRampStatus, VendorProviders } from '@loopring-web/common-resources'\nimport { OffFaitCommon, offFaitService, OffOderUIItem } from './offFaitService'\nimport { Box } from '@mui/material'\nimport { Button } from '@loopring-web/component-lib'\nimport { useTranslation } from 'react-i18next'\nimport { useHistory } from 'react-router-dom'\nimport { store, useModalData } from '../../stores'\nimport { BanxaCheck, banxaService } from './banxaService'\n\nexport * from './banxaService'\nexport * from './offFaitService'\n\nexport function useOffFaitModal() {\n  const { t } = useTranslation('common')\n  const subject = React.useMemo(() => offFaitService.onSocket(), [])\n  const [open, setOpen] = React.useState(false)\n  const handleClose = () => {\n    setOpen(false)\n  }\n  const { offBanxaValue, updateOffBanxaData } = useModalData()\n  useOffRampHandler()\n  const actionEle = React.useMemo(() => {\n    return (\n      <Box display={'inline-flex'} justifyContent={'flex-end'} flexDirection={'row-reverse'}>\n        <Button\n          sx={{ marginLeft: 1 }}\n          variant={'contained'}\n          size={'small'}\n          color={'primary'}\n          onClick={() => {\n            banxaService.KYCDone()\n            handleClose()\n          }}\n        >\n          {t('labelOrderOpen')}\n        </Button>\n        <Button\n          sx={{ marginLeft: 1 }}\n          variant={'text'}\n          size={'medium'}\n          onClick={() => {\n            offFaitService.offRampCancel({\n              data: {\n                product: VendorProviders.Banxa,\n                orderId: offBanxaValue?.id,\n                ...offBanxaValue,\n              },\n            })\n            setOpen(false)\n            handleClose()\n          }}\n        >\n          {t('labelOrderCancel')}\n        </Button>\n      </Box>\n    )\n  }, [offBanxaValue])\n  const handleShowUI = React.useCallback((props: OffOderUIItem) => {\n    myLog('banxaService.KYCDone')\n    updateOffBanxaData({ order: props.order })\n    if (/trade\\/fiat\\/sell\\?orderId/gi.test(window.location.href ?? '')) {\n      banxaService.KYCDone()\n      handleClose()\n    } else if (!/trade\\/fiat\\/sell/gi.test(window.location.href ?? '')) {\n      setOpen(true)\n    }\n  }, [])\n\n  React.useEffect(() => {\n    const subscription = subject.subscribe(({ data, status }) => {\n      switch (status) {\n        case OffFaitCommon.ShowUI:\n          if (\n            (\n              data as {\n                order: any\n                orderStatus: OffRampStatus\n                product: VendorProviders\n              }\n            ).orderStatus == OffRampStatus.watingForCreateOrder\n          ) {\n            handleShowUI(data as OffOderUIItem)\n          }\n          break\n      }\n    })\n    return () => {\n      subscription.unsubscribe()\n    }\n  }, [subject])\n  return {\n    open,\n    actionEle,\n    handleClose,\n  }\n}\n\nexport const useOffRampHandler = () => {\n  const subject = React.useMemo(() => banxaService.onSocket(), [])\n  const history = useHistory()\n  const searchParams = new URLSearchParams('')\n\n  React.useEffect(() => {\n    const subscription = subject.subscribe((props) => {\n      myLog('Banxa subscription ', props)\n      switch (props.status) {\n        case BanxaCheck.OrderHide:\n          myLog('Banxa Order OrderHide')\n          const {\n            _router_modalData: { offBanxaValue },\n          } = store.getState()\n          if (props.data?.reason == 'KYCDone' && offBanxaValue) {\n            searchParams.set('orderId', offBanxaValue.id)\n            history.push({\n              pathname: '/trade/fiat/sell',\n              search: searchParams.toString(),\n            })\n          }\n          break\n        default:\n          break\n      }\n    })\n    return () => {\n      subscription.unsubscribe()\n    }\n  }, [subject])\n}\n"
  },
  {
    "path": "packages/core/src/services/banxa/offFaitService.ts",
    "content": "import { store } from '../../stores'\nimport {\n  myLog,\n  OffRampHashItem,\n  OffRampHashItemObj,\n  OffRampStatus,\n  VendorProviders,\n} from '@loopring-web/common-resources'\nimport { banxaApiCall, banxaService } from './banxaService'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { updateOffRampHash } from '../../stores/localStore/offRamp'\nimport { Subject } from 'rxjs'\n\nlet __timer__: -1 | NodeJS.Timeout = -1\n\nexport enum OffFaitCommon {\n  ShowUI = 'ShowUI',\n  OffFaitCancel = 'OffFaitCancel',\n}\n\nexport type OffOderUIItem = {\n  order: any\n  orderStatus: OffRampStatus\n  product: VendorProviders\n}\nconst subject = new Subject<{\n  status: OffFaitCommon\n  data?: {\n    [key: string]: any\n  }\n}>()\nexport const offFaitService = {\n  backendCheckStart: () => {\n    const {\n      localStore: { offRampHistory },\n      system: { chainId },\n      account,\n    } = store.getState()\n    if (__timer__ !== -1) {\n      clearTimeout(__timer__)\n    }\n    if (\n      account?.accAddress &&\n      offRampHistory[chainId] &&\n      offRampHistory[chainId][account?.accAddress]\n    ) {\n      const { pending, payments }: OffRampHashItemObj = offRampHistory[chainId][account.accAddress][\n        VendorProviders.Banxa\n      ] ?? { pending: undefined, payments: undefined }\n      let promise: any = [...payments]\n      if (pending) {\n        promise.push(pending)\n      }\n      if (promise.length) {\n        promise = promise.reduce((prev: any[], item: any) => {\n          const ajxa = banxaApiCall({\n            chainId: chainId as sdk.ChainId,\n            method: sdk.ReqMethod.GET,\n            url: `/api/orders/${item.orderId}`,\n            query: '',\n            payload: {},\n            account,\n          })\n          return [...prev, ajxa]\n        }, [])\n\n        Promise.all(promise as Promise<any>[])\n          .then((result) => {\n            result.forEach(({ data }: any) => {\n              if (data?.order) {\n                offFaitService.banxaCheckStatus({ data: data?.order })\n              }\n            })\n          })\n          .catch(() => {})\n\n        __timer__ = setTimeout(() => {\n          offFaitService.backendCheckStart()\n        }, 120000)\n      }\n    }\n  },\n  offRampCancel: ({ data: order }: { data: any }) => {\n    const {\n      system: { chainId },\n      account: { accAddress },\n    } = store.getState()\n    store.dispatch(\n      updateOffRampHash({\n        ...order,\n        address: accAddress,\n        chainId,\n        status: OffRampStatus.cancel,\n      } as OffRampHashItem),\n    )\n    subject.next({\n      status: OffFaitCommon.OffFaitCancel,\n      data: {\n        reason: 'offRampCancel',\n        id: order.id ?? '',\n      },\n    })\n  },\n  banxaCheckStatus: ({\n    data: order,\n  }: {\n    data: Omit<OffRampHashItem, 'status' | 'orderId'> & {\n      status: string\n      id: string\n    }\n  }) => {\n    const {\n      system: { chainId },\n      account,\n    } = store.getState()\n\n    if (order && order.status) {\n      if (order?.wallet_address && order.status === 'waitingPayment') {\n        offFaitService.notifyUI({\n          data: order,\n          product: VendorProviders.Banxa,\n          status: OffRampStatus.watingForCreateOrder,\n        })\n      } else if (order.status === 'refunded') {\n        offFaitService.notifyUI({\n          data: order,\n          product: VendorProviders.Banxa,\n          status: OffRampStatus.refund,\n        })\n      } else if (order.status === 'complete') {\n        offFaitService.notifyUI({\n          data: order,\n          product: VendorProviders.Banxa,\n          status: OffRampStatus.done,\n        })\n      }\n      const _order = {\n        orderId: order.id,\n        address: account.accAddress,\n        chainId,\n        product: VendorProviders.Banxa,\n        ...(order?.checkout_iframe ? { checkout_iframe: order?.checkout_iframe } : {}),\n        ...(order?.wallet_address\n          ? { wallet_address: order?.wallet_address?.toString() ?? undefined }\n          : {}),\n        ...(order?.account_reference ? { account_reference: order?.account_reference } : {}),\n      }\n      myLog('banxa orderId', order.id)\n      if (\n        order.status === 'waitingPayment' ||\n        order.status === 'pendingPayment' ||\n        order.status === 'create'\n      ) {\n        store.dispatch(\n          updateOffRampHash({\n            ..._order,\n            status: OffRampStatus.watingForCreateOrder,\n          } as OffRampHashItem),\n        )\n        myLog('watingForCreateOrder')\n      } else if (order.status === 'paymentReceived' || order.status === 'inProgress') {\n        store.dispatch(\n          updateOffRampHash({\n            ..._order,\n            status: OffRampStatus.waitingForWithdraw,\n          } as OffRampHashItem),\n        )\n      } else if (\n        order.status === 'cancelled' ||\n        order.status === 'expired' ||\n        order.status === 'declined'\n      ) {\n        store.dispatch(\n          updateOffRampHash({\n            ..._order,\n            status: OffRampStatus.expired,\n          } as OffRampHashItem),\n        )\n        banxaService.orderExpired()\n      } else if (order.status === 'refunded') {\n        store.dispatch(\n          updateOffRampHash({\n            ..._order,\n            status: OffRampStatus.refund,\n          } as OffRampHashItem),\n        )\n      } else if (order.status === 'complete') {\n        store.dispatch(\n          updateOffRampHash({\n            ..._order,\n            status: OffRampStatus.done,\n          } as OffRampHashItem),\n        )\n      }\n    }\n  },\n  notifyUI: ({\n    data: order,\n    status,\n    product,\n  }: {\n    data: Omit<OffRampHashItem, 'status' | 'orderId'> & {\n      status: string\n      id: string\n    }\n    status: OffRampStatus\n    product: VendorProviders\n  }) => {\n    subject.next({\n      status: OffFaitCommon.ShowUI,\n      data: { order, orderStatus: status, product },\n    })\n  },\n  banxaEnd: () => {\n    if (__timer__ !== -1) {\n      clearTimeout(__timer__)\n    }\n  },\n  onSocket: () => subject.asObservable(),\n}\n"
  },
  {
    "path": "packages/core/src/services/claimServices/claimServices.ts",
    "content": "import { Subject } from 'rxjs'\nimport { CLAIM_TYPE } from '@loopring-web/common-resources'\n\nexport enum ClaimCommands {\n  Success = 0,\n  Failed = 1,\n}\n\nconst subject = new Subject<{\n  status: ClaimCommands\n  data?: {\n    type: CLAIM_TYPE\n    error?: any\n  }\n}>()\nexport const claimServices = {\n  claimSuccess: ({ type }: { type: CLAIM_TYPE }) => {\n    subject.next({\n      status: ClaimCommands.Success,\n      data: {\n        type,\n      },\n    })\n  },\n  claimFailed: ({ type, error }: { type: CLAIM_TYPE; error: any }) => {\n    subject.next({\n      status: ClaimCommands.Failed,\n      data: {\n        type,\n        error,\n      },\n    })\n  },\n  onSocket: () => subject.asObservable(),\n}\n"
  },
  {
    "path": "packages/core/src/services/claimServices/index.ts",
    "content": "export * from './claimServices'\n"
  },
  {
    "path": "packages/core/src/services/collectionServices/collectionService.ts",
    "content": "import { Subject } from 'rxjs'\nimport { resetCollectionData, store } from '../../index'\n\nexport enum ContractCommands {\n  CreateTokenAddress,\n  CreateMetaData,\n  CreateTokenAddressFailed,\n  // MintConfirm,\n  // SignatureMint,\n}\n\nconst subject = new Subject<{\n  status: ContractCommands\n  data?: {\n    uniqueId?: string\n    [key: string]: any\n  }\n}>()\n\n// const socket =  ipfsService.onSocket();\n\nexport const collectionService = {\n  emptyData: async () => {\n    store.dispatch(resetCollectionData({}))\n    // const {\n    //   account,\n    //   // system: { chainId },\n    // } = store.getState();\n    // let tokenAddress = contractAddress, collection: undefined | CollectionMeta = undefined;\n    // if (tokenAddress && account.readyState === AccountStatus.ACTIVATED && account.accAddress) {\n    //   const response = await LoopringAPI.userAPI?.getUserOwenCollection({\n    //     owner: account.accAddress,\n    //     address: contractAddress\n    //   }, account.apiKey);\n    //   if (\n    //     response &&\n    //     ((response as sdk.RESULT_INFO).code ||\n    //       (response as sdk.RESULT_INFO).message)\n    //   ) {\n    //     throw new CustomError(ErrorMap.ERROR_UNKNOWN);\n    //   }\n    //   collection = (response as any).collections[ 0 ];\n    // }\n    // store.dispatch(resetNFTMintData({tokenAddress, collection}));\n    // subject.next({\n    //   status: MintCommands.MetaDataSetup,\n    //   data: {\n    //     emptyData: true,\n    //   },\n    // });\n  },\n  // generateCollectionTokenAddress: async ({cid}: { cid: CID }) => {\n  //    // const {\n  //    //   account,\n  //    //   system: {chainId},\n  //    // } = store.getState();\n  //    // if (account.readyState === AccountStatus.ACTIVATED && account.accAddress) {\n  //    //   if (account.accAddress && LoopringAPI.nftAPI) {\n  //    //     // return (\n  //    //     const tokenAddress = await LoopringAPI.nftAPI?.computeNFTAddress({\n  //    //       nftOwner: account.accAddress,\n  //    //       nftFactory: sdk.NFTFactory[ chainId ],\n  //    //       nftBaseUri: `ipfs://${cid}`,\n  //    //     }).tokenAddress || undefined\n  //    //     // );\n  //    //     subject.next({\n  //    //       status: ContractCommands.CreateMetaData,\n  //    //       data: {tokenAddress},\n  //    //     });\n  //    //\n  //    //   } else {\n  //    //     subject.next({\n  //    //       status: ContractCommands.CreateTokenAddressFailed,\n  //    //       data: undefined,\n  //    //     });\n  //    //\n  //    //     return Promise.resolve();\n  //    //     // return undefined;\n  //    //   }\n  //    // }\n  //  },\n  // backMetaDataSetup: () => {\n  // updateIpfsGetTokenAddress: (ipfsProvides: IpfsProvides, uniqueId: string) => {\n  //   // ipfsService.addJSON({\n  //   //   ipfs: ipfsProvides.ipfs,\n  //   //   json: JSON.stringify({name: name}),\n  //   //   uniqueId, //:),\n  //   // });\n  // },\n  //   subject.next({\n  //     status: MintCommands.MetaDataSetup,\n  //   });\n  //   const {\n  //     nftMintValue: { nftMETA, mintData },\n  //   } = store.getState()._router_modalData;\n  //   store.dispatch(\n  //     updateNFTMintData({\n  //       nftMETA: nftMETA,\n  //       mintData: {\n  //         ...mintData,\n  //         nftIdView: undefined,\n  //         nftId: undefined,\n  //       },\n  //     })\n  //   );\n  // },\n  // processingIPFS: ({\n  //   ipfsProvides,\n  //   uniqueId,\n  // }: {\n  //   ipfsProvides: IpfsProvides;\n  //   uniqueId: string;\n  // }) => {\n  //   const {\n  //     nftMintValue: { nftMETA },\n  //   } = store.getState()._router_modalData;\n  //   let _nftMETA: any = {\n  //     image: nftMETA.image,\n  //     animation_url: nftMETA.image,\n  //     name: nftMETA.name,\n  //     royalty_percentage: nftMETA.royaltyPercentage, // 0 - 10 for UI\n  //     description: nftMETA.description,\n  //     collection: nftMETA.collection,\n  //     mint_channel: \"Loopring\",\n  //   };\n  //   // const attributes = [];\n  //   const obj =\n  //     nftMETA.properties?.reduce(\n  //       (prev, item) => {\n  //         if (!!item.key?.trim() && !!item.value?.trim()) {\n  //           const obj = { trait_type: item.key, value: item.value };\n  //           prev.attributes = [...prev.attributes, obj];\n  //           prev.properties = { ...prev.properties, [item.key]: item.value };\n  //           return prev;\n  //         } else {\n  //           return prev;\n  //         }\n  //       },\n  //       {\n  //         properties: {} as MetaDataProperty,\n  //         attributes: [] as AttributesProperty[],\n  //       }\n  //     ) ?? {};\n  //\n  //   _nftMETA = {\n  //     ..._nftMETA,\n  //     ...obj,\n  //   };\n  //   myLog(\"_nftMETA\", _nftMETA);\n  //   ipfsService.addJSON({\n  //     ipfs: ipfsProvides.ipfs,\n  //     json: JSON.stringify(_nftMETA),\n  //     uniqueId, //:),\n  //   });\n  // },\n  // completedIPFSCallMint: ({ ipfsResult }: { ipfsResult: AddResult }) => {\n  //   const {\n  //     nftMintValue: { nftMETA, mintData },\n  //   } = store.getState()._router_modalData;\n  //   try {\n  //     const cid = ipfsResult.cid.toString();\n  //     let nftId: string = LoopringAPI?.nftAPI?.ipfsCid0ToNftID(cid) ?? \"\";\n  //     let nftIdView = new BigNumber(nftId ?? \"0\", 16).toString();\n  //     store.dispatch(\n  //       updateNFTMintData({\n  //         nftMETA: nftMETA,\n  //         mintData: {\n  //           ...mintData,\n  //           cid,\n  //           nftIdView,\n  //           nftId,\n  //         },\n  //       })\n  //     );\n  //     subject.next({\n  //       status: MintCommands.SignatureMint,\n  //     });\n  //   } catch (error: any) {\n  //     myLog(\"handleMintDataChange ->.cid\", error);\n  //     subject.next({\n  //       status: MintCommands.MetaDataSetup,\n  //       data: {\n  //         error: {\n  //           code: UIERROR_CODE.IPFS_CID_TO_NFTID_ERROR,\n  //           message: `error on decode ipfsResult: ${ipfsResult}`,\n  //         },\n  //       },\n  //     });\n  //   }\n  //   // }\n  // },\n  // goMintConfirm: () => {\n  //   subject.next({\n  //     status: MintCommands.MintConfirm,\n  //   });\n  // },\n  // signatureMint: (isHardware?: boolean) => {\n  //   subject.next({\n  //     status: MintCommands.SignatureMint,\n  //     data: {\n  //       isHardware: isHardware,\n  //     },\n  //   });\n  // },\n  // signatureHardware: () => {\n  //   subject.next({\n  //     status: MintCommands.SignatureHardware,\n  //     data: {\n  //       isHardware: true,\n  //     },\n  //   });\n  //   // subject.next({\n  //   //   status: MintCommands.HardwareSignature,\n  //   // });\n  // },\n  onSocket: () => subject.asObservable(),\n}\n"
  },
  {
    "path": "packages/core/src/services/collectionServices/index.ts",
    "content": "export * from './collectionService'\n// export * from \"./useCollectionContract\";\n// export * from \"./useCollectionMeta\";\n"
  },
  {
    "path": "packages/core/src/services/connect/index.ts",
    "content": "export * from './useConnectHook'\n"
  },
  {
    "path": "packages/core/src/services/connect/useConnectHook.ts",
    "content": "import React from 'react'\nimport { provider } from 'web3-core'\nimport { ChainId } from '@loopring-web/loopring-sdk'\nimport { Commands, ErrorType, ProcessingType, walletServices } from '@loopring-web/web3-provider'\n\nexport function useConnectHook({\n  // handleChainChanged,\n  handleConnect,\n  handleAccountDisconnect,\n  handleError,\n  handleProcessing,\n}: {\n  handleProcessing?: (props: { type: ProcessingType; opts: any }) => void\n  handleError?: (props: { type: keyof typeof ErrorType; errorObj: any }) => void\n  // handleChainChanged?: (chainId: string) => void,\n  handleConnect?: (prosp: {\n    accounts: string\n    provider: provider\n    chainId: ChainId | 'unknown'\n  }) => void\n  handleAccountDisconnect?: (props: { reason?: string; code?: number }) => void\n}) {\n  const subject = React.useMemo(() => walletServices.onSocket(), [])\n  React.useEffect(() => {\n    const subscription = subject.subscribe(\n      ({ data, status }: { status: keyof typeof Commands; data?: any }) => {\n        switch (status) {\n          case 'Error':\n            if (handleError) {\n              handleError(data)\n            }\n            break\n          case 'Processing':\n            if (handleProcessing) {\n              handleProcessing(data)\n            }\n            break\n          // case 'ChangeNetwork':\n          //     // {chainId} = data ? data : {chainId: undefined};\n          //     handleChainChanged ? handleChainChanged(data.chainId) : undefined;\n          //     break\n          case 'ConnectWallet': // provider, accounts, chainId, networkId\n            const { accounts, provider, chainId } = data\n              ? data\n              : {\n                  accounts: undefined,\n                  provider: undefined,\n                  chainId: 1,\n                }\n            if (handleConnect) {\n              handleConnect({ accounts, provider, chainId })\n            }\n            break\n          case 'DisConnect':\n            if (handleAccountDisconnect) {\n              handleAccountDisconnect(data)\n            }\n        }\n      },\n    )\n    return () => subscription.unsubscribe()\n  }, [subject])\n}\n"
  },
  {
    "path": "packages/core/src/services/depositServices/depositServices.ts",
    "content": "import { Subject } from 'rxjs'\n\nexport enum DepositCommands {\n  DepsitERC20 = 0,\n  DepsitNFT = 1,\n}\n\nconst subject = new Subject<{\n  status: DepositCommands\n  data?: {\n    uniqueId?: string\n    [key: string]: any\n  }\n}>()\nexport const depositServices = {\n  depositERC20: () => {\n    subject.next({\n      status: DepositCommands.DepsitERC20,\n      data: {\n        emptyData: false,\n      },\n    })\n  },\n  depositNFT: () => {\n    subject.next({\n      status: DepositCommands.DepsitNFT,\n      data: {\n        emptyData: false,\n      },\n    })\n  },\n  onSocket: () => subject.asObservable(),\n}\n"
  },
  {
    "path": "packages/core/src/services/depositServices/index.ts",
    "content": "export * from './depositServices'\n"
  },
  {
    "path": "packages/core/src/services/fee/index.ts",
    "content": "export * from './useChargeFees'\n"
  },
  {
    "path": "packages/core/src/services/fee/useChargeFees.ts",
    "content": "import * as sdk from '@loopring-web/loopring-sdk'\nimport { useSettings } from '@loopring-web/component-lib'\n\nimport React from 'react'\nimport * as _ from 'lodash'\nimport {\n  AccountStatus,\n  FeeChargeOrderDefaultMap,\n  FeeInfo,\n  globalSetup,\n  myLog,\n  WalletMap,\n} from '@loopring-web/common-resources'\nimport {\n  useTokenMap,\n  LoopringAPI,\n  useAccount,\n  useSystem,\n  makeWalletLayer2,\n  store,\n  useWalletLayer2,\n} from '../../index'\n\nconst INTERVAL_TIME = (() => 900000)()\nexport function useChargeFees({\n  tokenSymbol: _tokenSymbol,\n  requestType: _requestType,\n  amount,\n  extraType,\n  isNFT = false,\n  tokenAddress,\n  updateData,\n  needAmountRefresh,\n  isActiveAccount = false,\n  deployInWithdraw = undefined,\n  intervalTime = INTERVAL_TIME,\n}: {\n  tokenAddress?: string | undefined\n  tokenSymbol?: string | undefined\n  isNFT?: boolean\n  requestType:\n    | sdk.OffchainFeeReqType\n    | sdk.OffchainNFTFeeReqType\n    | 'UPDATE_ACCOUNT_BY_NEW'\n    | 'TRANSFER_ACTIVE'\n  extraType?: number\n  amount?: number\n  intervalTime?: number\n  updateData?:\n    | undefined\n    | ((props: {\n        fee: FeeInfo\n        chargeFeeTokenList?: FeeInfo[]\n        isFeeNotEnough?: {\n          isFeeNotEnough: boolean\n          isOnLoading: boolean\n        }\n        requestType:\n          | sdk.OffchainFeeReqType\n          | sdk.OffchainNFTFeeReqType\n          | 'UPDATE_ACCOUNT_BY_NEW'\n          | 'TRANSFER_ACTIVE'\n        [key: string]: any\n      }) => void)\n  isActiveAccount?: boolean\n  needAmountRefresh?: boolean\n  deployInWithdraw?: boolean\n}): {\n  chargeFeeTokenList: FeeInfo[]\n  isFeeNotEnough: {\n    isFeeNotEnough: boolean\n    isOnLoading: boolean\n  }\n  checkFeeIsEnough: (\n    props?: {\n      isRequiredAPI: true\n      intervalTime?: number\n      requestType?: sdk.OffchainFeeReqType | sdk.OffchainNFTFeeReqType\n    } & any,\n  ) => void\n  handleFeeChange: (value: FeeInfo) => void\n  feeInfo: FeeInfo\n  resetIntervalTime: () => void\n  resetFee: () => void\n} {\n  const [feeInfo, setFeeInfo] = React.useState<FeeInfo>({\n    belong: 'ETH',\n    fee: 0,\n    feeRaw: undefined,\n  } as FeeInfo)\n  const { chainId } = useSystem()\n  let { feeChargeOrder } = useSettings()\n  const nodeTimer = React.useRef<NodeJS.Timeout | -1>(-1)\n  const [chargeFeeTokenList, setChargeFeeTokenList] = React.useState<FeeInfo[]>([])\n  const [isFeeNotEnough, setIsFeeNotEnough] = React.useState<{\n    isFeeNotEnough: boolean\n    isOnLoading: boolean\n  }>({\n    isFeeNotEnough: false,\n    isOnLoading: false,\n  })\n  const { tokenMap } = useTokenMap()\n  const { account } = useAccount()\n  const [_amount, setAmount] = React.useState({ amount, needAmountRefresh })\n  const [_intervalTime, setIntervalTime] = React.useState<number>(intervalTime)\n  const { status: walletLayer2Status } = useWalletLayer2()\n  const [requestType, setRequestType] = React.useState(_requestType)\n  const [tokenSymbol, seTokenSymbol] = React.useState(_tokenSymbol)\n\n  const handleFeeChange = (_value: FeeInfo): void => {\n    const walletMap =\n      makeWalletLayer2({ needFilterZero: true, isActive: isActiveAccount }).walletMap ??\n      ({} as WalletMap<any>)\n    let isFeeNotEnough = {\n      isFeeNotEnough: true,\n      isOnLoading: false,\n    }\n    const value = chargeFeeTokenList.find((ele) => _value?.belong === ele.belong) ?? _value\n    if (\n      walletMap &&\n      value?.belong &&\n      walletMap[value.belong] &&\n      walletMap[value.belong]?.count &&\n      sdk\n        // @ts-ignore\n        .toBig(walletMap[value.belong].count)\n        .gte(sdk.toBig(value.fee.toString().replaceAll(sdk.SEP, '')))\n    ) {\n      isFeeNotEnough = {\n        isFeeNotEnough: false,\n        isOnLoading: false,\n      }\n      setIsFeeNotEnough(isFeeNotEnough)\n    } else {\n      setIsFeeNotEnough(isFeeNotEnough)\n    }\n    if (updateData && value) {\n      updateData({\n        fee: {\n          ...value,\n          __raw__: {\n            ...value.__raw__,\n            tokenId: tokenMap[value.belong.toString()].tokenId,\n          },\n        },\n        requestType,\n        isFeeNotEnough: isFeeNotEnough,\n        amount: _amount.needAmountRefresh ? _amount.amount : undefined,\n        tokenSymbol,\n      })\n    }\n    setFeeInfo(value)\n  }\n\n  const getFeeList = _.debounce(\n    async () => {\n      let isFeeNotEnough = {\n        isFeeNotEnough: true,\n        isOnLoading: false,\n      }\n      let _feeInfo: any = undefined,\n        isSame = true\n      let tokenInfo\n      setIsFeeNotEnough((state) => {\n        isFeeNotEnough = { ...state }\n        return { ...state, isOnLoading: true }\n      })\n      const reduxState = store.getState()\n      const { tokenMap } = reduxState.tokenMap\n      const { account } = reduxState\n      const walletMap =\n        makeWalletLayer2({ needFilterZero: true, isActive: isActiveAccount }).walletMap ??\n        ({} as WalletMap<any>)\n      if (nodeTimer.current !== -1) {\n        clearTimeout(nodeTimer.current as NodeJS.Timeout)\n      }\n\n      if (tokenSymbol && tokenMap) {\n        tokenInfo = tokenMap[tokenSymbol]\n      }\n      if (tokenMap && tokenMap.ETH && LoopringAPI.userAPI && LoopringAPI.globalAPI) {\n        // myLog(\"getFeeList\", requestType);\n\n        try {\n          const request: sdk.GetOffchainFeeAmtRequest | sdk.GetNFTOffchainFeeAmtRequest = {\n            accountId: account.accountId,\n            tokenSymbol,\n            tokenAddress,\n            extraType,\n            requestType: requestType as any,\n            amount:\n              tokenInfo && _amount.amount && _amount.needAmountRefresh\n                ? sdk\n                    .toBig(_amount.amount)\n                    .times('1e' + tokenInfo.decimals)\n                    .toFixed(0, 0)\n                : '0',\n            deployInWithdraw:\n              requestType === sdk.OffchainNFTFeeReqType.NFT_WITHDRAWAL\n                ? deployInWithdraw\n                : undefined,\n          }\n          let fees: any\n          if (isActiveAccount && requestType !== undefined) {\n            const response = await LoopringAPI.globalAPI.getActiveFeeInfo({\n              accountId:\n                account.accountId === -1 && account._accountIdNotActive !== -1\n                  ? account._accountIdNotActive\n                  : account.accountId > 10000\n                  ? account.accountId\n                  : -1,\n            })\n\n            if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n            } else {\n              fees = response.fees\n            }\n          } else if (\n            requestType !== undefined &&\n            ([\n              sdk.OffchainNFTFeeReqType.NFT_MINT,\n              sdk.OffchainNFTFeeReqType.NFT_WITHDRAWAL,\n              sdk.OffchainNFTFeeReqType.NFT_TRANSFER_AND_UPDATE_ACCOUNT,\n              sdk.OffchainNFTFeeReqType.NFT_TRANSFER,\n              sdk.OffchainNFTFeeReqType.NFT_DEPLOY,\n            ].includes(requestType as any) ||\n              (sdk.OffchainNFTFeeReqType.EXTRA_TYPES == requestType && isNFT)) &&\n            account.accountId &&\n            account.accountId !== -1 &&\n            account.apiKey\n          ) {\n            const response = await LoopringAPI.userAPI.getNFTOffchainFeeAmt(\n              request as sdk.GetNFTOffchainFeeAmtRequest,\n              account.apiKey,\n            )\n            if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n            } else {\n              fees = response.fees\n            }\n          } else if (\n            [\n              sdk.OffchainFeeReqType.OFFCHAIN_WITHDRAWAL,\n              sdk.OffchainFeeReqType.FAST_OFFCHAIN_WITHDRAWAL,\n            ].includes(Number(requestType)) &&\n            account.accountId &&\n            account.accountId !== -1\n          ) {\n            const response = await LoopringAPI.userAPI.getOffchainFeeAmt(\n              request as sdk.GetOffchainFeeAmtRequest,\n              account.apiKey,\n            )\n            if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n            } else {\n              fees = response.fees\n            }\n          } else if (\n            requestType !== undefined &&\n            account.accountId &&\n            account.accountId !== -1 &&\n            account.apiKey\n          ) {\n            const response = await LoopringAPI.userAPI.getOffchainFeeAmt(\n              request as sdk.GetOffchainFeeAmtRequest,\n              account.apiKey,\n            )\n            if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n            } else {\n              fees = response.fees\n            }\n          }\n\n          if (_amount?.needAmountRefresh) {\n            setAmount((state) => {\n              isSame = _amount.amount === state.amount\n              return state\n            })\n          }\n          if (isSame && fees && feeChargeOrder) {\n            const _chargeFeeTokenList = feeChargeOrder?.reduce((pre, item) => {\n              let { fee, token, discount } = fees[item] ?? {}\n              if (fee && token) {\n                const tokenInfo = tokenMap[token]\n                const tokenId = tokenInfo.tokenId\n                const fastWithDraw = tokenInfo.fastWithdrawLimit\n                const feeRaw = fee\n                fee = sdk\n                  .toBig(fee)\n                  .div('1e' + tokenInfo.decimals)\n                  .toString()\n                const feeInfoTemplate = {\n                  belong: token,\n                  fee,\n                  feeRaw,\n                  hasToken: !!(walletMap && walletMap[token]),\n                  discount: discount as number,\n                  __raw__: { fastWithDraw, feeRaw, tokenId },\n                }\n                pre.push(feeInfoTemplate)\n                if (_feeInfo === undefined && walletMap && walletMap[token]) {\n                  const { count } = walletMap[token] ?? { count: 0 }\n                  if (sdk.toBig(count).gte(sdk.toBig(fee.toString().replaceAll(sdk.SEP, '')))) {\n                    _feeInfo = _.cloneDeep(feeInfoTemplate)\n                  }\n                }\n              }\n              return pre\n            }, [] as Array<FeeInfo>)\n            let _isFeeNotEnough = {\n              isFeeNotEnough: true,\n              isOnLoading: false,\n            }\n            setFeeInfo((state) => {\n              if (_feeInfo === undefined) {\n                if (state?.feeRaw === '0' && isActiveAccount) {\n                  _isFeeNotEnough = {\n                    isFeeNotEnough: false,\n                    isOnLoading: false,\n                  }\n                }\n                setIsFeeNotEnough(_isFeeNotEnough)\n                _feeInfo =\n                  !state || state?.feeRaw === undefined\n                    ? _chargeFeeTokenList[0]\n                      ? _.cloneDeep(_chargeFeeTokenList[0])\n                      : {\n                          belong: 'ETH',\n                          fee: 0,\n                          feeRaw: undefined,\n                        }\n                    : _chargeFeeTokenList?.find((ele) => ele.belong === state.belong) ?? state\n\n                if (updateData && _feeInfo) {\n                  updateData({\n                    fee: {\n                      ..._feeInfo,\n                      __raw__: {\n                        ..._feeInfo.__raw__,\n                        tokenId: tokenMap[_feeInfo?.belong.toString()].tokenId,\n                      },\n                    },\n                    requestType,\n                    chargeFeeTokenList: _chargeFeeTokenList,\n                    isFeeNotEnough: _isFeeNotEnough,\n                    amount: _amount.needAmountRefresh ? _amount.amount : undefined,\n                    tokenSymbol,\n                  })\n                }\n                // myLog(\"_feeInfo\", _feeInfo);\n                return _feeInfo\n              } else {\n                if (isFeeNotEnough.isFeeNotEnough || !state || state?.feeRaw === undefined) {\n                  _isFeeNotEnough = {\n                    isFeeNotEnough: false,\n                    isOnLoading: false,\n                  }\n                  setIsFeeNotEnough(_isFeeNotEnough)\n                  if (updateData && _feeInfo) {\n                    updateData({\n                      fee: {\n                        ..._feeInfo,\n                        __raw__: {\n                          ...feeInfo?.__raw__,\n                          ..._feeInfo?.__raw__,\n                          tokenId: tokenMap[_feeInfo?.belong.toString()].tokenId,\n                        },\n                      },\n                      requestType,\n                      chargeFeeTokenList: _chargeFeeTokenList,\n                      isFeeNotEnough: _isFeeNotEnough,\n                      amount: _amount.needAmountRefresh ? _amount.amount : undefined,\n                      tokenSymbol,\n                    })\n                  }\n                  return _feeInfo\n                } else {\n                  const feeInfo = _chargeFeeTokenList?.find((ele) => ele.belong === state.belong)\n                  if (updateData && feeInfo) {\n                    _isFeeNotEnough = {\n                      isFeeNotEnough: sdk\n                        .toBig(walletMap[state.belong]?.count ?? 0)\n                        .lt(sdk.toBig(feeInfo.fee.toString().replaceAll(sdk.SEP, ''))),\n                      isOnLoading: false,\n                    }\n                    setIsFeeNotEnough(_isFeeNotEnough)\n                    updateData({\n                      fee: { ...feeInfo },\n                      requestType,\n                      chargeFeeTokenList: _chargeFeeTokenList,\n                      isFeeNotEnough: _isFeeNotEnough,\n                      amount: _amount.needAmountRefresh ? _amount.amount : undefined,\n                      tokenSymbol,\n                    })\n                  }\n                  return feeInfo ?? state\n                }\n              }\n            })\n            const _chargeFeeTokenListWithCount = _chargeFeeTokenList.map((feeInfo) => {\n              return {\n                ...feeInfo,\n                count: walletMap[feeInfo.belong]?.count\n                  ? walletMap[feeInfo.belong]?.count\n                  : undefined,\n              } as FeeInfo\n            })\n            setChargeFeeTokenList(_chargeFeeTokenListWithCount ?? [])\n          }\n        } catch (reason: any) {\n          // myLog(\"chargeFeeTokenList, error\", reason);\n          if ((reason as sdk.RESULT_INFO).code) {\n          }\n        }\n        if (isSame && Number.isFinite(_intervalTime) && !Number.isNaN(_intervalTime)) {\n          nodeTimer.current = setTimeout(() => {\n            getFeeList()\n          }, _intervalTime)\n        }\n        return\n      } else {\n        nodeTimer.current = setTimeout(() => {\n          getFeeList()\n        }, 1000)\n      }\n    },\n    globalSetup.wait,\n    { trailing: true },\n  )\n  const checkFeeIsEnough = async (\n    props:\n      | undefined\n      | ({\n          isRequiredAPI: true\n          intervalTime?: number\n          requestType?: sdk.OffchainFeeReqType\n        } & any),\n  ) => {\n    if (props?.isRequiredAPI) {\n      const intervalTime = props.intervalTime\n      setIntervalTime((state) => {\n        return intervalTime ? intervalTime : state\n      })\n      if (props?.tokenSymbol && props?.tokenSymbol !== tokenSymbol) {\n        seTokenSymbol(props.tokenSymbol)\n      }\n      if (props.amount && props.needAmountRefresh && props.requestType) {\n        myLog('checkFeeIsEnough needAmountRefresh', requestType)\n        if (props.requestType && props.requestType !== requestType) {\n          setRequestType(props.requestType)\n        }\n        setAmount(() => ({\n          amount: props.amount,\n          needAmountRefresh: props.needAmountRefresh,\n        }))\n        getFeeList.cancel()\n      } else if (props.requestType && props.requestType !== requestType) {\n        setRequestType(props.requestType)\n        myLog('checkFeeIsEnough', requestType)\n        getFeeList.cancel()\n      } else {\n        getFeeList.cancel()\n        getFeeList()\n      }\n    } else {\n      const walletMap =\n        makeWalletLayer2({ needFilterZero: true, isActive: isActiveAccount }).walletMap ??\n        ({} as WalletMap<any>)\n      if (chargeFeeTokenList && walletMap) {\n        chargeFeeTokenList.map((feeInfo) => {\n          return {\n            ...feeInfo,\n            hasToken: !!(walletMap && walletMap[feeInfo.belong]),\n          }\n        })\n      }\n\n      if (feeInfo && feeInfo.belong && feeInfo.feeRaw) {\n        const { count } = walletMap[feeInfo.belong] ?? { count: 0 }\n        if (sdk.toBig(count).gte(sdk.toBig(feeInfo.fee.toString().replaceAll(sdk.SEP, '')))) {\n          setIsFeeNotEnough({ isFeeNotEnough: false, isOnLoading: false })\n          return\n        }\n      }\n      setIsFeeNotEnough({ isFeeNotEnough: true, isOnLoading: false })\n    }\n  }\n\n  React.useEffect(() => {\n    if (nodeTimer.current !== -1) {\n      clearTimeout(nodeTimer.current as NodeJS.Timeout)\n      getFeeList.cancel()\n    }\n\n    if (\n      (isActiveAccount &&\n        ((requestType === 'UPDATE_ACCOUNT_BY_NEW' &&\n          [\n            AccountStatus.NO_ACCOUNT,\n            AccountStatus.DEPOSITING,\n            AccountStatus.NOT_ACTIVE,\n            AccountStatus.LOCKED,\n          ].includes(account.readyState as any)) ||\n          requestType === 'TRANSFER_ACTIVE')) ||\n      (!isActiveAccount &&\n        walletLayer2Status === 'UNSET' &&\n        AccountStatus.ACTIVATED === account.readyState &&\n        [\n          sdk.OffchainFeeReqType.UPDATE_ACCOUNT,\n          sdk.OffchainFeeReqType.UPDATE_ACCOUNT,\n          sdk.OffchainFeeReqType.TRANSFER,\n          sdk.OffchainFeeReqType.EXTRA_TYPES,\n          sdk.OffchainFeeReqType.TRANSFER_AND_UPDATE_ACCOUNT,\n          sdk.OffchainFeeReqType.FORCE_WITHDRAWAL,\n          sdk.OffchainNFTFeeReqType.NFT_TRANSFER,\n          sdk.OffchainNFTFeeReqType.EXTRA_TYPES,\n          sdk.OffchainNFTFeeReqType.NFT_TRANSFER_AND_UPDATE_ACCOUNT,\n          sdk.OffchainNFTFeeReqType.NFT_DEPLOY,\n        ].includes(Number(requestType))) ||\n      (!isActiveAccount &&\n        walletLayer2Status === 'UNSET' &&\n        sdk.OffchainNFTFeeReqType.NFT_WITHDRAWAL === requestType &&\n        tokenAddress) ||\n      (!isActiveAccount &&\n        tokenSymbol &&\n        [\n          sdk.OffchainFeeReqType.OFFCHAIN_WITHDRAWAL,\n          sdk.OffchainFeeReqType.FAST_OFFCHAIN_WITHDRAWAL,\n        ].includes(Number(requestType))) ||\n      //   [sdk.OffchainFeeReqType.OFFCHAIN_WITHDRAWAL].includes(\n      //     Number(requestType)\n      //   )) ||\n      // (!isActiveAccount &&\n      //   tokenSymbol &&\n      //   amount &&\n      //   AccountStatus.ACTIVATED === account.readyState &&\n      //   walletLayer2Status === \"UNSET\" &&\n      //   [sdk.OffchainFeeReqType.FAST_OFFCHAIN_WITHDRAWAL].includes(\n      //     Number(requestType)\n      //   )) ||\n      (!isActiveAccount &&\n        tokenAddress &&\n        AccountStatus.ACTIVATED === account.readyState &&\n        walletLayer2Status === 'UNSET' &&\n        [sdk.OffchainNFTFeeReqType.NFT_MINT].includes(Number(requestType)))\n    ) {\n      getFeeList()\n    }\n\n    return () => {\n      if (nodeTimer.current !== -1) {\n        clearTimeout(nodeTimer.current as NodeJS.Timeout)\n      }\n      getFeeList.cancel()\n    }\n  }, [\n    isActiveAccount,\n    tokenAddress,\n    tokenSymbol,\n    requestType,\n    _intervalTime,\n    _amount,\n    account.readyState,\n    walletLayer2Status,\n    feeChargeOrder\n  ])\n\n  const resetFee = () => {\n    setFeeInfo({\n      belong: 'ETH',\n      fee: 0,\n      feeRaw: undefined,\n    } as FeeInfo)\n    getFeeList()\n  }\n\n  return {\n    chargeFeeTokenList,\n    isFeeNotEnough,\n    resetIntervalTime: () => {\n      setIntervalTime(intervalTime)\n    },\n    checkFeeIsEnough,\n    handleFeeChange,\n    feeInfo,\n    resetFee\n  }\n}\n"
  },
  {
    "path": "packages/core/src/services/index.ts",
    "content": "export * from './account'\nexport * from './connect'\nexport * from './mintServices'\nexport * from './collectionServices'\nexport * from './depositServices'\nexport * from './qrcodeServices'\nexport * from './banxa'\nexport * from './socket'\nexport * from './ipfs'\nexport * from './fee'\nexport * from './claimServices'\nexport * from './redpacket'\n"
  },
  {
    "path": "packages/core/src/services/ipfs/index.ts",
    "content": "export * from './ipfsService'\nexport * from './useIpfs'\n"
  },
  {
    "path": "packages/core/src/services/ipfs/ipfsService.ts",
    "content": "import { Subject } from 'rxjs'\nimport { create, IPFSHTTPClient } from 'ipfs-http-client'\n\nimport {\n  CustomError,\n  ErrorMap,\n  IPFS_LOOPRING_URL,\n  UIERROR_CODE,\n} from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nexport enum IPFSCommands {\n  ErrorGetIpfs = 'ErrorGetIpfs',\n  IpfsResult = 'IpfsResult',\n}\nexport class IpfsProvides {\n  private _ipfs: IPFSHTTPClient | undefined = undefined\n\n  get ipfs(): IPFSHTTPClient | undefined {\n    return this._ipfs\n  }\n\n  async init() {\n    try {\n      this._ipfs = await create({\n        url: `${IPFS_LOOPRING_URL}`,\n      })\n    } catch (error) {\n      console.error('IPFSHTTPClient ERROR ON INIT::', error)\n      ipfsService.sendError(new CustomError(ErrorMap.CREATE_IPFS_ERROR))\n    }\n    return this._ipfs\n  }\n\n  stop() {\n    if (this._ipfs) {\n      try {\n        this._ipfs = undefined\n      } catch (err) {\n        console.error('IPFSHTTPClient ERROR ON STOP::', err as any)\n      }\n    }\n  }\n}\n\nconst subject = new Subject<{\n  status: IPFSCommands\n  data?: {\n    uniqueId?: string\n    [key: string]: any\n  }\n}>()\n\nexport const ipfsService = {\n  sendError: (error: CustomError) => {\n    subject.next({\n      status: IPFSCommands.ErrorGetIpfs,\n      data: {\n        error: error,\n      },\n    })\n  },\n  addJSONStringify: async ({\n    ipfs,\n    str,\n    uniqueId,\n  }: {\n    ipfs: IPFSHTTPClient\n    str: string\n    uniqueId: string\n  }) => {\n    if (ipfs) {\n      try {\n        const data = await ipfs.add(str) //callIpfs({ ipfs, cmd, opts });\n        subject.next({\n          status: IPFSCommands.IpfsResult,\n          data: { ...data, uniqueId },\n        })\n      } catch (error) {\n        subject.next({\n          status: IPFSCommands.ErrorGetIpfs,\n          data: {\n            uniqueId,\n            error: {\n              code: UIERROR_CODE.ADD_IPFS_ERROR,\n              ...(error as any),\n              uniqueId,\n            },\n          },\n        })\n      }\n    } else {\n      subject.next({\n        status: IPFSCommands.ErrorGetIpfs,\n        data: {\n          uniqueId,\n          error: {\n            code: UIERROR_CODE.NO_IPFS_INSTANCE,\n            message: 'IPFSHTTPClient is undefined',\n          } as sdk.RESULT_INFO,\n        },\n      })\n    }\n  },\n  addFile: async ({\n    ipfs,\n    file,\n    uniqueId,\n  }: {\n    ipfs: IPFSHTTPClient | undefined\n    file: File\n    uniqueId: string\n  }) => {\n    if (ipfs) {\n      try {\n        const data = await ipfs.add({ content: file.stream() }).catch((e) => {\n          throw e\n        })\n        subject.next({\n          status: IPFSCommands.IpfsResult,\n          data: { ...data, uniqueId, file },\n        })\n      } catch (error) {\n        subject.next({\n          status: IPFSCommands.ErrorGetIpfs,\n          data: {\n            error: {\n              code: UIERROR_CODE.ADD_IPFS_ERROR,\n              ...(error as any),\n            },\n            uniqueId,\n          },\n        })\n      }\n    } else {\n      subject.next({\n        status: IPFSCommands.ErrorGetIpfs,\n        data: {\n          uniqueId,\n          error: {\n            code: UIERROR_CODE.NO_IPFS_INSTANCE,\n            message: 'IPFSHTTPClient is undefined',\n          },\n        },\n      })\n    }\n  },\n  addJSON: async ({\n    ipfs,\n    json,\n    uniqueId,\n  }: {\n    ipfs: IPFSHTTPClient | undefined\n    json: string\n    uniqueId: string\n  }) => {\n    if (ipfs) {\n      try {\n        const data = await ipfs.add(json) //callIpfs({ ipfs, cmd, opts });\n        subject.next({\n          status: IPFSCommands.IpfsResult,\n          data: { ...data, uniqueId },\n        })\n      } catch (error) {\n        subject.next({\n          status: IPFSCommands.ErrorGetIpfs,\n          data: {\n            error: {\n              code: UIERROR_CODE.ADD_IPFS_ERROR,\n              ...(error as any),\n            },\n            uniqueId,\n          },\n        })\n      }\n    } else {\n      subject.next({\n        status: IPFSCommands.ErrorGetIpfs,\n        data: {\n          uniqueId,\n          error: {\n            code: UIERROR_CODE.NO_IPFS_INSTANCE,\n            message: 'IPFSHTTPClient is undefined',\n          },\n        },\n      })\n    }\n  },\n\n  // clearMessages: () => subject.next(),\n  onSocket: () => subject.asObservable(),\n}\n"
  },
  {
    "path": "packages/core/src/services/ipfs/useIpfs.ts",
    "content": "import React from 'react'\nimport { IPFSCommands, IpfsProvides, ipfsService } from './ipfsService'\nconst ipfsProvides = new IpfsProvides()\n\nexport function useIPFS({ handleSuccessUpload, handleFailedUpload }: any) {\n  const subject = React.useMemo(() => ipfsService.onSocket(), [])\n  const start = React.useCallback(async () => {\n    await ipfsProvides.init()\n  }, [])\n  React.useEffect(() => {\n    start()\n    const subscription = subject.subscribe(\n      ({ data, status }: { status: IPFSCommands; data?: any }) => {\n        switch (status) {\n          case IPFSCommands.IpfsResult:\n            handleSuccessUpload(data)\n            break\n          case IPFSCommands.ErrorGetIpfs:\n            handleFailedUpload(data)\n        }\n      },\n    )\n    return () => {\n      ipfsProvides.stop()\n      subscription.unsubscribe()\n    }\n  }, [])\n  return { ipfsProvides }\n}\n"
  },
  {
    "path": "packages/core/src/services/mintServices/index.ts",
    "content": "export * from './mintService'\nexport * from './useNFTMint'\nexport * from './useNFTMeta'\n"
  },
  {
    "path": "packages/core/src/services/mintServices/mintService.ts",
    "content": "import { Subject } from 'rxjs'\nimport { LoopringAPI, store, resetNFTMintData, updateNFTMintData, LAST_STEP } from '../../index'\nimport {\n  AccountStatus,\n  // AccountStatus,\n  AttributesProperty,\n  CollectionMeta,\n  CustomError,\n  ErrorMap,\n  MetaDataProperty,\n  myLog,\n  UIERROR_CODE,\n} from '@loopring-web/common-resources'\nimport { IpfsProvides, ipfsService } from '../ipfs'\nimport { BigNumber } from 'bignumber.js'\nimport { AddResult } from 'ipfs-core-types/types/src/root'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\n// import * as sdk from \"@loopring-web/loopring-sdk\";\n\nexport enum MintCommands {\n  MetaDataSetup,\n  MintConfirm,\n  SignatureMint,\n}\n\nconst subject = new Subject<{\n  status: MintCommands\n  data?: {\n    uniqueId?: string\n    [key: string]: any\n  }\n}>()\n\nexport const mintService = {\n  emptyData: async (\n    props:\n      | {\n          contractAddress?: string | undefined\n          lastStep?: LAST_STEP | undefined\n        }\n      | undefined,\n  ) => {\n    const {\n      account,\n      // system: { chainId },\n    } = store.getState()\n    let tokenAddress = props?.contractAddress,\n      collection: undefined | CollectionMeta = undefined\n    if (tokenAddress && account.readyState === AccountStatus.ACTIVATED && account.accAddress) {\n      const response = await LoopringAPI.userAPI?.getUserOwenCollection(\n        {\n          owner: account.accAddress,\n          tokenAddress: props?.contractAddress,\n        },\n        account.apiKey,\n      )\n      if (\n        response &&\n        ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message)\n      ) {\n        throw new CustomError(ErrorMap.ERROR_UNKNOWN)\n      }\n      collection = (response as any).collections[0]\n    }\n    store.dispatch(resetNFTMintData({ tokenAddress, collection, lastStep: props?.lastStep }))\n    subject.next({\n      status: MintCommands.MetaDataSetup,\n      data: {\n        emptyData: true,\n        collection,\n      },\n    })\n  },\n  processingIPFS: ({\n    ipfsProvides,\n    uniqueId,\n  }: {\n    ipfsProvides: IpfsProvides\n    uniqueId: string\n  }) => {\n    const {\n      nftMintValue: { nftMETA },\n    } = store.getState()._router_modalData\n    let _nftMETA: any = {\n      image: nftMETA.image,\n      animation_url: nftMETA.animationUrl ?? nftMETA.image,\n      name: nftMETA.name,\n      royalty_percentage: nftMETA.royaltyPercentage, // 0 - 10 for UI\n      description: nftMETA.description,\n      collection_metadata: nftMETA.collection_metadata,\n      mint_channel: 'Loopring',\n    }\n    // const attributes = [];\n    const obj =\n      nftMETA.properties?.reduce(\n        (prev, item) => {\n          if (!!item.key?.trim() && !!item.value?.trim()) {\n            const obj = { trait_type: item.key, value: item.value }\n            prev.attributes = [...prev.attributes, obj]\n            prev.properties = { ...prev.properties, [item.key]: item.value }\n            return prev\n          } else {\n            return prev\n          }\n        },\n        {\n          properties: {} as MetaDataProperty,\n          attributes: [] as AttributesProperty[],\n        },\n      ) ?? {}\n\n    _nftMETA = {\n      ..._nftMETA,\n      ...obj,\n    }\n    myLog('_nftMETA', _nftMETA)\n    ipfsService.addJSON({\n      ipfs: ipfsProvides.ipfs,\n      json: JSON.stringify(_nftMETA),\n      uniqueId, //:),\n    })\n  },\n  completedIPFSCallMint: ({ ipfsResult }: { ipfsResult: AddResult }) => {\n    const {\n      nftMintValue: { nftMETA, mintData, collection },\n    } = store.getState()._router_modalData\n    try {\n      const cid = ipfsResult.cid.toString()\n      let nftId: string = LoopringAPI?.nftAPI?.ipfsCid0ToNftID(cid) ?? ''\n      let nftIdView = new BigNumber(nftId ?? '0', 16).toString()\n      store.dispatch(\n        updateNFTMintData({\n          nftMETA: nftMETA,\n          mintData: {\n            ...mintData,\n            cid,\n            nftIdView,\n            nftId,\n          },\n          collection,\n        }),\n      )\n      subject.next({\n        status: MintCommands.SignatureMint,\n      })\n    } catch (error: any) {\n      myLog('handleMintDataChange ->.cid', error)\n      subject.next({\n        status: MintCommands.MetaDataSetup,\n        data: {\n          error: {\n            code: UIERROR_CODE.IPFS_CID_TO_NFTID_ERROR,\n            message: `error on decode ipfsResult: ${ipfsResult}`,\n          },\n        },\n      })\n    }\n    // }\n  },\n  goMintConfirm: (isHardware?: boolean) => {\n    subject.next({\n      status: MintCommands.MintConfirm,\n      data: {\n        isHardware: isHardware,\n      },\n    })\n  },\n  backMetaDataSetup: () => {\n    subject.next({\n      status: MintCommands.MetaDataSetup,\n      data: {\n        emptyData: false,\n      },\n    })\n  },\n  signatureMint: () => {\n    subject.next({\n      status: MintCommands.SignatureMint,\n    })\n  },\n  onSocket: () => subject.asObservable(),\n}\n"
  },
  {
    "path": "packages/core/src/services/mintServices/useNFTMeta.ts",
    "content": "import React from 'react'\nimport {\n  ErrorType,\n  IPFS_HEAD_URL,\n  MINT_LIMIT,\n  myLog,\n  NFTMETA,\n  UIERROR_CODE,\n  CollectionMeta,\n  LIVE_FEE_TIMES,\n} from '@loopring-web/common-resources'\nimport { IpfsFile, NFTMetaProps } from '@loopring-web/component-lib'\nimport {\n  store,\n  useBtnStatus,\n  useChargeFees,\n  NFT_MINT_VALUE,\n  useModalData,\n  MintCommands,\n  mintService,\n  LoopringAPI,\n  useSystem,\n  getIPFSString,\n} from '../../index'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { ipfsService, useIPFS } from '../ipfs'\nimport { AddResult } from 'ipfs-core-types/types/src/root'\n\nexport function useNFTMeta<T extends NFTMETA, Co extends CollectionMeta>({\n  handleTabChange,\n  nftMintValue,\n}: {\n  nftMintValue: NFT_MINT_VALUE<any>\n  handleTabChange: (value: 0 | 1) => void\n}) {\n  const subject = React.useMemo(() => mintService.onSocket(), [])\n  const { updateNFTMintData, resetNFTMintData } = useModalData()\n  const [errorOnMeta, setErrorOnMeta] = React.useState<sdk.RESULT_INFO | undefined>(undefined)\n  const [_, setCIDUniqueId] = React.useState<string | undefined>(undefined)\n  const [keys, setKeys] = React.useState<{\n    [key: string]: undefined | IpfsFile\n  }>(() => {\n    return {\n      image: undefined,\n      animationUrl: undefined,\n    }\n  })\n  const [userAgree, setUserAgree] = React.useState(false)\n  const { baseURL } = useSystem()\n  const domain = LoopringAPI.delegate?.getCollectionDomain() ?? ''\n\n  const handleOnMetaChange = React.useCallback(\n    (_newnftMeta: Partial<T> & { collection?: CollectionMeta }) => {\n      const { nftMETA, mintData, collection } = store.getState()._router_modalData.nftMintValue\n      const buildNFTMeta = { ...nftMETA }\n      const buildMint = { ...mintData }\n      let buildCollection = { ...collection }\n      Reflect.ownKeys(_newnftMeta).map((key) => {\n        switch (key) {\n          case 'image':\n            buildNFTMeta.image = _newnftMeta.image\n            break\n          case 'animationUrl':\n            buildNFTMeta.animationUrl = _newnftMeta.animationUrl\n            break\n          case 'name':\n            buildNFTMeta.name = _newnftMeta.name\n            break\n          case 'royaltyPercentage':\n            const value = Number(_newnftMeta.royaltyPercentage)\n            buildMint.royaltyPercentage = value\n            buildNFTMeta.royaltyPercentage = value\n            // if (\n            //   Number.isInteger(value) &&\n            //   [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].includes(value)\n            // ) {\n            //   buildNFTMeta.royaltyPercentage = value;\n            //   buildMint.royaltyPercentage = value;\n            // }\n            break\n          case 'description':\n            buildNFTMeta.description = _newnftMeta.description\n            break\n          case 'collection':\n            buildMint.tokenAddress = _newnftMeta.collection?.contractAddress\n            // @ts-ignore\n            buildNFTMeta.collection_metadata = `${domain}/${_newnftMeta.collection?.collectionAddress}`\n            buildCollection = _newnftMeta.collection ? _newnftMeta.collection : buildCollection\n            break\n          case 'properties':\n            buildNFTMeta.properties = _newnftMeta.properties\n            break\n        }\n      })\n      updateNFTMintData({\n        mintData: buildMint,\n        nftMETA: buildNFTMeta,\n        collection: buildCollection,\n      })\n      myLog('updateNFTMintData buildNFTMeta', buildNFTMeta)\n    },\n    [updateNFTMintData],\n  )\n  // const handleOnMetaChange = React.useCallback(\n  //   (key: string, value: any) => {\n  //     const collectionValue =\n  //       store.getState()._router_modalData.collectionValue;\n  //     myLog(\"collectionValue\", collectionValue);\n  //     updateCollectionData({ ...collectionValue, [key]: value });\n  //   },\n  //   [updateCollectionData]\n  // );\n\n  const handleFailedUpload = React.useCallback(\n    (data: { uniqueId: string; error: sdk.RESULT_INFO }) => {\n      setKeys((state) => {\n        const key: string = Reflect.ownKeys(state).find((key) => {\n          return state[key as any]?.uniqueId === data.uniqueId\n        }) as string\n        if (key) {\n          handleOnMetaChange({ [key]: undefined } as Partial<T>)\n          return {\n            ...state,\n            [key]: {\n              ...state[key],\n              isProcessing: false,\n              ...{\n                error: data.error\n                  ? data.error\n                  : {\n                      code: UIERROR_CODE.UNKNOWN,\n                      message: `Ipfs Error ${data}`,\n                    },\n              },\n            } as IpfsFile,\n          }\n        } else {\n          return state\n        }\n      })\n    },\n    [handleOnMetaChange],\n  )\n  const handleSuccessUpload = React.useCallback(\n    (data: AddResult & { uniqueId: string }) => {\n      setKeys((state) => {\n        const key: string = Reflect.ownKeys(state).find((key) => {\n          return state[key as any]?.uniqueId === data.uniqueId\n        }) as string\n        if (key) {\n          const cid = data.cid.toString()\n          handleOnMetaChange({\n            [key]: `${IPFS_HEAD_URL}${data.path}`,\n          } as unknown as Partial<T>)\n          return {\n            ...state,\n            [key as any]: {\n              ...state[key as any],\n              ...{\n                cid,\n                fullSrc: getIPFSString(`${IPFS_HEAD_URL}${data.path}`, baseURL),\n                isProcessing: false,\n              },\n            },\n          }\n        } else {\n          return state\n        }\n      })\n      setCIDUniqueId((cidUniqueID) => {\n        if (cidUniqueID && cidUniqueID === data.uniqueId) {\n          mintService.completedIPFSCallMint({ ipfsResult: data })\n        }\n        return cidUniqueID\n      })\n    },\n    [baseURL, handleOnMetaChange],\n  )\n\n  const { ipfsProvides } = useIPFS({\n    handleSuccessUpload,\n    handleFailedUpload,\n  })\n  const onFilesLoad = React.useCallback(\n    (key: string, value: IpfsFile) => {\n      let uniqueId = key + '|' + Date.now()\n      value.isUpdateIPFS = true\n      ipfsService.addFile({\n        ipfs: ipfsProvides.ipfs,\n        file: value.file,\n        uniqueId: uniqueId,\n      })\n      setKeys((state) => {\n        return {\n          ...state,\n          [key]: {\n            ...value,\n            file: value.file,\n            uniqueId: uniqueId,\n            cid: '',\n          },\n        }\n      })\n    },\n    [ipfsProvides.ipfs],\n  )\n\n  // const onFilesLoad = React.useCallback(\n  //   (value: IpfsFile) => {\n  //     value.isUpdateIPFS = true;\n  //     setIpfsMediaSources(value);\n  //     ipfsService.addFile({\n  //       ipfs: ipfsProvides.ipfs,\n  //       file: value.file,\n  //       uniqueId: value.uniqueId,\n  //     });\n  //   },\n  //   [ipfsProvides.ipfs]\n  // );\n  // const onDelete = React.useCallback(() => {\n  //   setIpfsMediaSources(undefined);\n  //   handleOnMetaChange({\n  //     image: undefined,\n  //   } as Partial<T>);\n  // }, [handleOnMetaChange]);\n\n  const onDelete = React.useCallback(\n    (keys: string[]) => {\n      setKeys((state) => {\n        keys.forEach((key: string) => {\n          handleOnMetaChange({ [key]: undefined } as Partial<T>)\n          state = {\n            ...state,\n            [key]: undefined,\n          }\n        })\n        return state\n      })\n    },\n    [handleOnMetaChange],\n  )\n\n  const {\n    chargeFeeTokenList,\n    isFeeNotEnough,\n    checkFeeIsEnough,\n    handleFeeChange,\n    feeInfo,\n    resetIntervalTime,\n  } = useChargeFees({\n    tokenAddress: nftMintValue?.mintData?.tokenAddress?.toLowerCase(),\n    requestType: sdk.OffchainNFTFeeReqType.NFT_MINT,\n    updateData: ({ fee }) => {\n      const { nftMETA, mintData, collection } = store.getState()._router_modalData.nftMintValue\n      if (mintData?.tokenAddress === collection?.contractAddress) {\n        // myLog(\"fee\", fee);\n        updateNFTMintData({\n          nftMETA: nftMETA,\n          mintData: { ...mintData, fee },\n          collection,\n        })\n      }\n    },\n  })\n  const { btnStatus, btnInfo, enableBtn, disableBtn, setLabelAndParams, resetBtnInfo } =\n    useBtnStatus()\n  const updateBtnStatus = React.useCallback(\n    (error?: ErrorType & any) => {\n      resetBtnInfo()\n      myLog(\n        'nftMetaBtnStatus nftMintValue:',\n        'mintData',\n        nftMintValue.mintData,\n        'nftMETA',\n        nftMintValue.nftMETA,\n        'userAgree',\n        userAgree,\n        'error',\n        error,\n      )\n      if (\n        !error &&\n        nftMintValue &&\n        nftMintValue.mintData &&\n        nftMintValue.nftMETA &&\n        userAgree &&\n        // tokenAddress &&\n        nftMintValue.nftMETA.royaltyPercentage !== undefined &&\n        Number.isInteger(nftMintValue.nftMETA.royaltyPercentage / 1) &&\n        nftMintValue.nftMETA.royaltyPercentage / 1 >= 0 &&\n        nftMintValue.nftMETA.royaltyPercentage / 1 <= 10 &&\n        nftMintValue.mintData.tradeValue &&\n        Number(nftMintValue.mintData.tradeValue) > 0 &&\n        Number(nftMintValue.mintData.tradeValue) <= MINT_LIMIT &&\n        !!nftMintValue.nftMETA.name &&\n        !!nftMintValue.nftMETA.image &&\n        nftMintValue.mintData.fee &&\n        nftMintValue.mintData.fee.belong &&\n        nftMintValue.mintData.fee.__raw__ &&\n        nftMintValue.collection\n        // && !isFeeNotEnough.isFeeNotEnough\n      ) {\n        enableBtn()\n        return\n      }\n      if (error) {\n        setLabelAndParams(error.messageKey ?? '', { ...error.options })\n      }\n      if (!userAgree) {\n        setLabelAndParams('labelMintUserAgree', {})\n      }\n      if (nftMintValue.collection) {\n        setLabelAndParams('labelMintNoCollectionBtn', {})\n      }\n\n      if (!nftMintValue.nftMETA.image || nftMintValue.nftMETA.image.trim() == '') {\n        setLabelAndParams('labelMintNoImageBtn', {})\n      }\n      if (!nftMintValue.collection) {\n        setLabelAndParams('labelCollectionSelect', {})\n      }\n      if (!nftMintValue.nftMETA.name || nftMintValue.nftMETA.name.trim() == '') {\n        setLabelAndParams('labelMintNoNameBtn', {})\n      }\n      if (\n        !(\n          nftMintValue.nftMETA.royaltyPercentage !== undefined &&\n          Number.isInteger(nftMintValue.nftMETA.royaltyPercentage / 1) &&\n          nftMintValue.nftMETA.royaltyPercentage / 1 >= 0 &&\n          nftMintValue.nftMETA.royaltyPercentage / 1 <= 10\n        )\n      ) {\n        setLabelAndParams('labelMintWrongRoyaltyBtn', {})\n      }\n\n      if (\n        !(\n          nftMintValue.mintData.tradeValue &&\n          Number(nftMintValue.mintData.tradeValue) > 0 &&\n          Number(nftMintValue.mintData.tradeValue) <= MINT_LIMIT\n        )\n      ) {\n        setLabelAndParams('labelMintTradeValueBtn', {})\n      }\n\n      disableBtn()\n      myLog('try to disable nftMint btn!')\n    },\n    [\n      resetBtnInfo,\n      nftMintValue,\n      userAgree,\n      // tokenAddress,\n      // isFeeNotEnough,\n      disableBtn,\n      enableBtn,\n      setLabelAndParams,\n    ],\n  )\n\n  React.useEffect(() => {\n    updateBtnStatus()\n  }, [nftMintValue.mintData, nftMintValue.nftMETA, userAgree, updateBtnStatus])\n\n  const resetMETADAT = (_nftMintValue?: NFT_MINT_VALUE<any>) => {\n    onDelete(['image', 'animationUrl'])\n    checkFeeIsEnough({ isRequiredAPI: true, intervalTime: LIVE_FEE_TIMES })\n  }\n  const onMetaClick = React.useCallback(() => {\n    const uniqueId = (nftMintValue.nftMETA as T).name + Date.now()\n    setCIDUniqueId(uniqueId)\n    mintService.processingIPFS({ ipfsProvides, uniqueId })\n  }, [ipfsProvides, nftMintValue.nftMETA])\n\n  const handleUserAgree = (value: boolean) => {\n    setUserAgree(value)\n  }\n  const nftMetaProps: Omit<NFTMetaProps<T, Co>, 'collectionInputProps'> = {\n    handleOnMetaChange,\n    isFeeNotEnough,\n    baseURL,\n    handleFeeChange,\n    userAgree,\n    handleUserAgree,\n    chargeFeeTokenList,\n    feeInfo,\n    nftMetaBtnStatus: btnStatus,\n    btnInfo,\n    onMetaClick,\n    domain,\n  }\n  const commonSwitch = React.useCallback(\n    async ({ data, status }: { status: MintCommands; data?: any }) => {\n      switch (status) {\n        case MintCommands.MetaDataSetup:\n          handleTabChange(0)\n          setErrorOnMeta(data?.error)\n          if (data?.emptyData) {\n            resetMETADAT()\n          }\n          break\n      }\n    },\n    [handleTabChange],\n  )\n  React.useEffect(() => {\n    const subscription = subject.subscribe((props) => {\n      commonSwitch(props)\n    })\n    return () => {\n      resetNFTMintData()\n      subscription.unsubscribe()\n    }\n  }, [subject])\n  return {\n    onFilesLoad,\n    onDelete,\n    keys,\n    ipfsProvides,\n    nftMetaProps,\n    chargeFeeTokenList,\n    isFeeNotEnough,\n    checkFeeIsEnough,\n    handleFeeChange,\n    feeInfo,\n    resetIntervalTime,\n    // tokenAddress,\n    // resetMETADAT,\n    errorOnMeta,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/services/mintServices/useNFTMint.ts",
    "content": "import React from 'react'\nimport { AccountStep, NFTMintProps, useOpenModals } from '@loopring-web/component-lib'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport {\n  MintCommands,\n  mintService,\n  NFT_MINT_VALUE,\n  useModalData,\n  useTokenMap,\n  useAccount,\n  DAYS,\n  getTimestampDaysLater,\n  LoopringAPI,\n  store,\n  useBtnStatus,\n  useWalletLayer2Socket,\n  walletLayer2Service,\n  useSystem,\n  useWalletLayer2NFT,\n  getIPFSString,\n  LAST_STEP,\n  NETWORKEXTEND,\n} from '../../index'\n\nimport {\n  AccountStatus,\n  ErrorType,\n  Explorer,\n  FeeInfo,\n  MINT_LIMIT,\n  MintReadTradeNFT,\n  MintTradeNFT,\n  myLog,\n  NFTMETA,\n  NFTSubRouter,\n  RouterPath,\n  SUBMIT_PANEL_QUICK_AUTO_CLOSE,\n  UIERROR_CODE,\n} from '@loopring-web/common-resources'\nimport { ConnectProviders, connectProvides } from '@loopring-web/web3-provider'\nimport { useHistory } from 'react-router-dom'\nimport { useWalletInfo } from '../../stores/localStore/walletInfo'\nimport Web3 from 'web3'\n\nexport function useNFTMint<Me extends NFTMETA, Mi extends MintTradeNFT<I>, I, _C extends FeeInfo>({\n  chargeFeeTokenList,\n  isFeeNotEnough,\n  checkFeeIsEnough,\n  handleFeeChange,\n  feeInfo,\n  handleTabChange,\n  nftMintValue,\n}: {\n  chargeFeeTokenList: FeeInfo[]\n  isFeeNotEnough: {\n    isFeeNotEnough: boolean\n    isOnLoading: boolean\n  }\n  // resetIntervalTime: () => void;\n  checkFeeIsEnough: (props?: { isRequiredAPI: true; intervalTime?: number }) => void\n  handleFeeChange: (value: FeeInfo) => void\n  feeInfo: FeeInfo\n  handleTabChange: (value: 0 | 1) => void\n  nftMintValue: NFT_MINT_VALUE<any>\n}) {\n  const subject = React.useMemo(() => mintService.onSocket(), [])\n  const history = useHistory()\n  const { tokenMap, totalCoinMap } = useTokenMap()\n  const { exchangeInfo, chainId, baseURL } = useSystem()\n  const { account } = useAccount()\n  const { updateNFTMintData } = useModalData()\n  const { btnStatus, btnInfo, enableBtn, disableBtn, setLabelAndParams, resetBtnInfo } =\n    useBtnStatus()\n  const { checkHWAddr, updateHW } = useWalletInfo()\n  const { page, updateWalletLayer2NFT } = useWalletLayer2NFT()\n  const { setShowAccount, setShowNFTMintAdvance } = useOpenModals()\n  const checkAvailable = ({\n    nftMintValue,\n    isFeeNotEnough,\n  }: {\n    nftMintValue: NFT_MINT_VALUE<any>\n    isFeeNotEnough: any\n  }) => {\n    return (\n      nftMintValue.nftMETA.royaltyPercentage !== undefined &&\n      Number.isInteger(nftMintValue.nftMETA.royaltyPercentage / 1) &&\n      nftMintValue.nftMETA.royaltyPercentage / 1 >= 0 &&\n      nftMintValue.nftMETA.royaltyPercentage / 1 <= 10 &&\n      nftMintValue.mintData.tokenAddress &&\n      nftMintValue.mintData.tradeValue &&\n      Number(nftMintValue.mintData.tradeValue) > 0 &&\n      Number(nftMintValue.mintData.tradeValue) <= MINT_LIMIT &&\n      nftMintValue.mintData.nftId &&\n      nftMintValue.mintData.fee &&\n      nftMintValue.mintData.fee.belong &&\n      nftMintValue.mintData.fee.__raw__ &&\n      !isFeeNotEnough.isFeeNotEnough\n    )\n  }\n  const updateBtnStatus = React.useCallback(\n    (error?: ErrorType & any) => {\n      resetBtnInfo()\n      if (!error && checkAvailable({ nftMintValue, isFeeNotEnough })) {\n        enableBtn()\n        return\n      }\n      if (\n        !(\n          nftMintValue.nftMETA.royaltyPercentage !== undefined &&\n          Number.isInteger(nftMintValue.nftMETA.royaltyPercentage / 1) &&\n          nftMintValue.nftMETA.royaltyPercentage >= 0 &&\n          nftMintValue.nftMETA.royaltyPercentage <= 10\n        )\n      ) {\n        setLabelAndParams('labelNFTMintNoMetaBtn', {})\n      }\n      disableBtn()\n      myLog('try to disable nftMint btn!')\n    },\n    [isFeeNotEnough, resetBtnInfo, nftMintValue, enableBtn, setLabelAndParams, disableBtn],\n  )\n\n  React.useEffect(() => {\n    updateBtnStatus()\n  }, [isFeeNotEnough.isFeeNotEnough, nftMintValue, feeInfo])\n  useWalletLayer2Socket({})\n\n  const handleMintDataChange = React.useCallback(\n    async (data: Partial<MintReadTradeNFT<I>>) => {\n      const { nftMETA, mintData, collection } = nftMintValue\n      // const {\n      //   nftMintValue: { nftMETA, mintData, collection },\n      // } = store.getState()._router_modalData;\n      const buildNFTMeta = { ...nftMETA }\n      const buildMint = { ...mintData }\n      Reflect.ownKeys(data).map((key) => {\n        switch (key) {\n          case 'tradeValue':\n            buildMint.tradeValue = data.tradeValue\n            break\n          case 'fee':\n            buildMint.fee = data.fee\n            break\n        }\n      })\n      updateNFTMintData({\n        mintData: buildMint,\n        nftMETA: buildNFTMeta,\n        collection,\n      })\n    },\n    [nftMintValue],\n  )\n  const resetNFTMINT = () => {\n    if (nftMintValue.mintData.tokenAddress) {\n      checkFeeIsEnough({ isRequiredAPI: true })\n      handleMintDataChange({\n        fee: feeInfo,\n      })\n    }\n  }\n  const processRequest = React.useCallback(\n    async (request: sdk.NFTMintRequestV3, isNotHardwareWallet: boolean) => {\n      const { apiKey, connectName, eddsaKey } = account\n      try {\n        const nftMintValue = store.getState()._router_modalData.nftMintValue\n        if (connectProvides.usedWeb3 && LoopringAPI.userAPI) {\n          let isHWAddr = checkHWAddr(account.accAddress)\n\n          if (!isHWAddr && !isNotHardwareWallet) {\n            isHWAddr = true\n          }\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.NFTMint_WaitForAuth,\n            info: {\n              symbol: nftMintValue.nftMETA?.name,\n              value: nftMintValue.mintData?.tradeValue,\n            },\n          })\n          const response = await LoopringAPI.userAPI\n            ?.submitNFTMint(\n              {\n                request,\n                web3: connectProvides.usedWeb3 as unknown as Web3,\n                chainId: chainId === NETWORKEXTEND.NONETWORK ? sdk.ChainId.MAINNET : chainId,\n                walletType: (ConnectProviders[connectName] ??\n                  connectName) as unknown as sdk.ConnectorNames,\n                eddsaKey: eddsaKey.sk,\n                apiKey,\n                isHWAddr,\n              },\n              {\n                accountId: account.accountId,\n                counterFactualInfo: eddsaKey.counterFactualInfo,\n              } as any,\n            )\n            .catch()\n\n          myLog('submitNFTMint:', response)\n\n          if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n            throw response\n          }\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.NFTMint_Success,\n            info: {\n              collection: nftMintValue.collection,\n              symbol: nftMintValue.nftMETA?.name,\n              value: nftMintValue.mintData?.tradeValue,\n              lastStep: LAST_STEP.nftMint,\n              hash:\n                Explorer +\n                `tx/${(response as sdk.TX_HASH_API)?.hash}-nftMint-${account.accountId}-${\n                  request.maxFee.tokenId\n                }-${request.storageId}`,\n            },\n          })\n          if (isHWAddr) {\n            myLog('......try to set isHWAddr', isHWAddr)\n            updateHW({ wallet: account.accAddress, isHWAddr })\n          }\n          myLog('nftMintValue', nftMintValue.collection)\n          history.push(\n            `${RouterPath.nft}/${NFTSubRouter.assetsNFT}/byCollection/${nftMintValue.collection?.contractAddress}--${nftMintValue.collection?.id}`,\n          )\n          walletLayer2Service.sendUserUpdate()\n          mintService.emptyData({\n            lastStep: LAST_STEP.nftMint,\n            contractAddress: nftMintValue.collection?.contractAddress,\n          })\n\n          await sdk.sleep(SUBMIT_PANEL_QUICK_AUTO_CLOSE)\n          if (store.getState().modals.isShowAccount.isShow) {\n            setShowAccount({ isShow: false })\n          }\n        }\n      } catch (e: any) {\n        myLog('useNFTMint', e)\n        const code = sdk.checkErrorInfo(e, isNotHardwareWallet)\n        switch (code) {\n          case sdk.ConnectorError.NOT_SUPPORT_ERROR:\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.NFTMint_First_Method_Denied,\n              info: {\n                symbol: nftMintValue.nftMETA?.name,\n                value: nftMintValue.mintData?.tradeValue,\n              },\n            })\n            break\n          case sdk.ConnectorError.USER_DENIED:\n          case sdk.ConnectorError.USER_DENIED_2:\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.NFTMint_Denied,\n              info: {\n                symbol: nftMintValue.nftMETA?.name,\n                value: nftMintValue.mintData?.tradeValue,\n              },\n            })\n            break\n          default:\n            if ([102024, 102025, 114001, 114002].includes((e as sdk.RESULT_INFO)?.code || 0)) {\n              checkFeeIsEnough({ isRequiredAPI: true })\n            } else if ([102040].includes((e as sdk.RESULT_INFO)?.code || 0)) {\n              walletLayer2Service.sendUserUpdate()\n              history.push(\n                `${RouterPath.nft}/${NFTSubRouter.assetsNFT}/byCollection/${nftMintValue.collection?.contractAddress}--${nftMintValue.collection?.id}`,\n              )\n              mintService.emptyData({\n                lastStep: LAST_STEP.nftMint,\n                contractAddress: nftMintValue.collection?.contractAddress,\n              })\n            }\n\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.NFTMint_Failed,\n              info: {\n                symbol: nftMintValue.nftMETA?.name,\n                value: nftMintValue.mintData?.tradeValue,\n              },\n              error: {\n                code: UIERROR_CODE.UNKNOWN,\n                msg: e?.message,\n                ...(e instanceof Error\n                  ? {\n                      message: e?.message,\n                      stack: e?.stack,\n                    }\n                  : e ?? {}),\n              },\n            })\n            break\n        }\n      }\n    },\n    [\n      account,\n      checkHWAddr,\n      setShowAccount,\n      chainId,\n      nftMintValue.nftMETA?.name,\n      updateWalletLayer2NFT,\n      page,\n      history,\n      updateHW,\n      checkFeeIsEnough,\n    ],\n  )\n\n  const onNFTMintClick = React.useCallback(async (isFirstTime: boolean = true) => {\n    const nftMintValue = store.getState()._router_modalData.nftMintValue\n    if (\n      account.readyState === AccountStatus.ACTIVATED &&\n      LoopringAPI.userAPI &&\n      LoopringAPI.nftAPI &&\n      exchangeInfo &&\n      nftMintValue.collection &&\n      nftMintValue.mintData &&\n      nftMintValue.mintData.fee &&\n      checkAvailable({ nftMintValue, isFeeNotEnough })\n    ) {\n      setShowNFTMintAdvance({ isShow: false })\n      setShowAccount({\n        isShow: true,\n        step: AccountStep.NFTMint_In_Progress,\n        info: {\n          symbol: nftMintValue.nftMETA?.name,\n          value: nftMintValue.mintData?.tradeValue,\n        },\n      })\n      try {\n        const { accountId, accAddress, apiKey } = account\n        const feeRaw =\n          nftMintValue.mintData.fee.feeRaw ?? nftMintValue.mintData.fee.__raw__?.feeRaw ?? 0\n        const fee = sdk.toBig(feeRaw)\n        const feeToken = tokenMap[nftMintValue.mintData.fee.belong]\n        const storageId = await LoopringAPI.userAPI.getNextStorageId(\n          {\n            accountId,\n            sellTokenId: feeToken.tokenId,\n          },\n          apiKey,\n        )\n        const req: sdk.NFTMintRequestV3 = {\n          exchange: exchangeInfo.exchangeAddress,\n          minterId: accountId,\n          minterAddress: accAddress,\n          toAccountId: accountId,\n          toAddress: accAddress,\n          nftType: 0,\n          tokenAddress: nftMintValue.mintData.tokenAddress ?? '',\n          nftId: nftMintValue.mintData.nftId ?? '',\n          amount: nftMintValue.mintData.tradeValue?.toString() ?? '',\n          maxFee: {\n            tokenId: feeToken.tokenId,\n            amount: fee.toString(), // TEST: fee.toString(),\n          },\n          counterFactualNftInfo: {\n            nftOwner: account.accAddress,\n            nftFactory: nftMintValue.collection.nftFactory ?? sdk.NFTFactory_Collection[chainId],\n            nftBaseUri: nftMintValue.collection.baseUri ?? '',\n          },\n          royaltyPercentage: nftMintValue.nftMETA.royaltyPercentage ?? 0,\n          forceToMint: false,\n          validUntil: getTimestampDaysLater(DAYS),\n          storageId: storageId?.offchainId,\n        }\n        myLog('onNFTMintClick req:', req)\n        processRequest(req, isFirstTime)\n      } catch (e: any) {\n        setShowAccount({\n          isShow: true,\n          step: AccountStep.NFTMint_Failed,\n          info: {\n            symbol: nftMintValue.nftMETA?.name,\n            value: nftMintValue.mintData?.tradeValue,\n          },\n\n          error: {\n            code: e?.code ?? UIERROR_CODE.UNKNOWN,\n            message: e.message,\n            ...(e instanceof Error\n              ? {\n                  message: e?.message,\n                  stack: e?.stack,\n                }\n              : e ?? {}),\n          } as sdk.RESULT_INFO,\n        })\n      }\n      return\n    }\n  }, [])\n  const retryBtn = React.useCallback(\n    (isHardwareRetry: boolean = false) => {\n      setShowAccount({\n        isShow: true,\n        step: AccountStep.NFTMint_WaitForAuth,\n        info: {\n          symbol: nftMintValue.nftMETA?.name,\n          value: nftMintValue.mintData?.tradeValue,\n        },\n      })\n      onNFTMintClick(!isHardwareRetry)\n      // processRequest(lastRequest, !isHardwareRetry);\n    },\n    [nftMintValue.mintData?.tradeValue, nftMintValue.nftMETA?.name, onNFTMintClick, setShowAccount],\n  )\n\n  const nftMintProps: NFTMintProps<Me, Mi, I> = {\n    chargeFeeTokenList,\n    isFeeNotEnough,\n    handleFeeChange,\n    feeInfo,\n    baseURL,\n    getIPFSString,\n    handleMintDataChange,\n    onNFTMintClick,\n    walletMap: {} as any,\n    coinMap: totalCoinMap as any,\n    tradeData: nftMintValue.mintData as Mi,\n    nftMintBtnStatus: btnStatus,\n    btnInfo,\n    mintService,\n  }\n\n  const commonSwitch = ({ data, status }: { status: MintCommands; data?: any }) => {\n    switch (status) {\n      case MintCommands.MetaDataSetup:\n        if (data?.emptyData) {\n          resetNFTMINT()\n        }\n        break\n      case MintCommands.SignatureMint:\n        handleTabChange(1)\n        break\n      case MintCommands.MintConfirm:\n        nftMintProps.onNFTMintClick(data?.isHardware)\n        handleTabChange(1)\n        break\n    }\n  }\n  React.useEffect(() => {\n    const subscription = subject.subscribe((props) => {\n      commonSwitch(props)\n    })\n    return () => {\n      subscription.unsubscribe()\n    }\n  }, [subject])\n\n  return {\n    nftMintProps,\n    retryBtn,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/services/qrcodeServices/index.ts",
    "content": "export * from './qrCodeService'\nexport * from './useQrcodeScan'\n"
  },
  {
    "path": "packages/core/src/services/qrcodeServices/qrCodeService.ts",
    "content": "import { Subject } from 'rxjs'\nimport { Html5QrcodeScanner, Html5QrcodeScanType, Html5QrcodeSupportedFormats } from 'html5-qrcode'\n\nimport { CustomError, ErrorMap, QRCODE_REGION_ID } from '@loopring-web/common-resources'\n\nfunction onScanSuccess(decodedText: any, decodedResult: any) {\n  // handle the scanned code as you like, for example:\n  // console.log(`Code matched = ${decodedText}`, decodedResult);\n  h5QrcodeScannerService.sendSuccess({\n    data: {\n      decodedText,\n      decodedResult,\n    },\n  })\n}\n\nfunction onScanFailure(error: any) {\n  // handle scan failure, usually better to ignore and keep scanning.\n  // for example:\n  // console.warn(`Code scan error = ${error}`);\n  h5QrcodeScannerService.sendError({ ...error })\n}\n\nexport class Html5QrcodeScannerProvides {\n  private _h5QrcodeScanner: Html5QrcodeScanner | undefined = undefined\n\n  get h5QrcodeScanner(): Html5QrcodeScanner | undefined {\n    return this._h5QrcodeScanner\n  }\n\n  constructor() {\n    this.init()\n    this.clear()\n  }\n\n  async init() {\n    try {\n      this._h5QrcodeScanner = new Html5QrcodeScanner(\n        QRCODE_REGION_ID,\n        {\n          fps: 10,\n          qrbox: { width: 260, height: 260 },\n          formatsToSupport: [Html5QrcodeSupportedFormats.QR_CODE],\n          supportedScanTypes: [\n            // Html5QrcodeScanType.SCAN_TYPE_CAMERA,\n            Html5QrcodeScanType.SCAN_TYPE_FILE,\n          ],\n        },\n        true,\n      )\n    } catch (error) {\n      console.error('IPFSHTTPClient ERROR ON INIT::', error)\n      h5QrcodeScannerService.sendError(new CustomError(ErrorMap.CREATE_IPFS_ERROR))\n    }\n    return this._h5QrcodeScanner\n  }\n\n  clear() {\n    if (this._h5QrcodeScanner) {\n      try {\n        this._h5QrcodeScanner.clear()\n      } catch (err) {\n        console.error('IPFSHTTPClient ERROR ON STOP::', err as any)\n      }\n    }\n  }\n\n  stop() {\n    if (this._h5QrcodeScanner) {\n      try {\n        this._h5QrcodeScanner.clear()\n        this._h5QrcodeScanner = undefined\n      } catch (err) {\n        console.error('IPFSHTTPClient ERROR ON STOP::', err as any)\n      }\n    }\n  }\n\n  render() {\n    if (this._h5QrcodeScanner) {\n      try {\n        this._h5QrcodeScanner.render(onScanSuccess, onScanFailure)\n        // this._h5QrcodeScanner = undefined;\n      } catch (err) {\n        // console.error(\"IPFSHTTPClient ERROR ON STOP::\", err as any);\n      }\n    }\n  }\n}\n\nexport enum H5QrcodeScannerCommands {\n  ErrorHtml5QrcodeScanner = 'ErrorHtml5QrcodeScanner',\n  SuccessH5QrcodeScanner = 'SuccessH5QrcodeScanner',\n}\n\nconst subject = new Subject<{\n  status: H5QrcodeScannerCommands\n  data?: {\n    uniqueId?: string\n    [key: string]: any\n  }\n}>()\n\nexport const h5QrcodeScannerService = {\n  sendError: (error: CustomError) => {\n    subject.next({\n      status: H5QrcodeScannerCommands.ErrorHtml5QrcodeScanner,\n      data: {\n        error: error,\n      },\n    })\n  },\n  // cleanQRScanner: () => {\n  //   h5QrcodeScannerProvides.clear();\n  // },\n  // renderQRScanner: () => {\n  //   h5QrcodeScannerProvides.render();\n  // },\n  sendSuccess: (data: any) => {\n    subject.next({\n      status: H5QrcodeScannerCommands.SuccessH5QrcodeScanner,\n      data,\n    })\n  },\n  // addJSONStringify: async ({\n  //   ipfs,\n  //   str,\n  //   uniqueId,\n  // }: {\n  //   ipfs: Html5QrcodeScanner;\n  //   str: string;\n  //   uniqueId: string;\n  // }) => {\n  //   if (ipfs) {\n  //     try {\n  //       const data = await ipfs.add(str); //callIpfs({ ipfs, cmd, opts });\n  //       subject.next({\n  //         status: IPFSCommands.IpfsResult,\n  //         data: { ...data, uniqueId },\n  //       });\n  //     } catch (error) {\n  //       subject.next({\n  //         status: IPFSCommands.ErrorGetIpfs,\n  //         data: {\n  //           uniqueId,\n  //           error: {\n  //             code: UIERROR_CODE.ADD_IPFS_ERROR,\n  //             ...(error as any),\n  //             uniqueId,\n  //           },\n  //         },\n  //       });\n  //     }\n  //   } else {\n  //     subject.next({\n  //       status: IPFSCommands.ErrorGetIpfs,\n  //       data: {\n  //         uniqueId,\n  //         error: {\n  //           code: UIERROR_CODE.NO_IPFS_INSTANCE,\n  //           message: \"IPFSHTTPClient is undefined\",\n  //         } as sdk.RESULT_INFO,\n  //       },\n  //     });\n  //   }\n  // },\n  // addFile: async ({\n  //   ipfs,\n  //   file,\n  //   uniqueId,\n  // }: {\n  //   ipfs: IPFSHTTPClient | undefined;\n  //   file: File;\n  //   uniqueId: string;\n  // }) => {\n  //   if (ipfs) {\n  //     try {\n  //       const data: AddResult = await ipfs\n  //         .add({ content: file.stream() })\n  //         .catch((e) => {\n  //           throw e;\n  //         });\n  //       subject.next({\n  //         status: IPFSCommands.IpfsResult,\n  //         data: { ...data, uniqueId, file },\n  //       });\n  //     } catch (error) {\n  //       subject.next({\n  //         status: IPFSCommands.ErrorGetIpfs,\n  //         data: {\n  //           error: {\n  //             code: UIERROR_CODE.ADD_IPFS_ERROR,\n  //             ...(error as any),\n  //           },\n  //           uniqueId,\n  //         },\n  //       });\n  //     }\n  //   } else {\n  //     subject.next({\n  //       status: IPFSCommands.ErrorGetIpfs,\n  //       data: {\n  //         uniqueId,\n  //         error: {\n  //           code: UIERROR_CODE.NO_IPFS_INSTANCE,\n  //           message: \"IPFSHTTPClient is undefined\",\n  //         },\n  //       },\n  //     });\n  //   }\n  // },\n  // addJSON: async ({\n  //   ipfs,\n  //   json,\n  //   uniqueId,\n  // }: {\n  //   ipfs: IPFSHTTPClient | undefined;\n  //   json: string;\n  //   uniqueId: string;\n  // }) => {\n  //   if (ipfs) {\n  //     try {\n  //       const data: AddResult = await ipfs.add(json); //callIpfs({ ipfs, cmd, opts });\n  //       subject.next({\n  //         status: IPFSCommands.IpfsResult,\n  //         data: { ...data, uniqueId },\n  //       });\n  //     } catch (error) {\n  //       subject.next({\n  //         status: IPFSCommands.ErrorGetIpfs,\n  //         data: {\n  //           error: {\n  //             code: UIERROR_CODE.ADD_IPFS_ERROR,\n  //             ...(error as any),\n  //           },\n  //           uniqueId,\n  //         },\n  //       });\n  //     }\n  //   } else {\n  //     subject.next({\n  //       status: IPFSCommands.ErrorGetIpfs,\n  //       data: {\n  //         uniqueId,\n  //         error: {\n  //           code: UIERROR_CODE.NO_IPFS_INSTANCE,\n  //           message: \"IPFSHTTPClient is undefined\",\n  //         },\n  //       },\n  //     });\n  //   }\n  // },\n\n  // clearMessages: () => subject.next(),\n  onSocket: () => subject.asObservable(),\n}\n"
  },
  {
    "path": "packages/core/src/services/qrcodeServices/useQrcodeScan.ts",
    "content": "import React from 'react'\nimport {\n  H5QrcodeScannerCommands,\n  h5QrcodeScannerService,\n  Html5QrcodeScannerProvides,\n} from './qrCodeService'\n\nexport const h5QrcodeScannerProvides = new Html5QrcodeScannerProvides()\n\nexport function useQrcodeScan({ handleFailedUpload, handleSuccessUpload }: any) {\n  const subject = React.useMemo(() => h5QrcodeScannerService.onSocket(), [])\n\n  const start = React.useCallback(async () => {\n    await h5QrcodeScannerProvides.init()\n  }, [])\n  React.useEffect(() => {\n    start()\n    h5QrcodeScannerProvides.init()\n    const subscription = subject.subscribe(\n      ({ data, status }: { status: H5QrcodeScannerCommands; data?: any }) => {\n        switch (status) {\n          case H5QrcodeScannerCommands.SuccessH5QrcodeScanner:\n            handleSuccessUpload(data)\n            break\n          case H5QrcodeScannerCommands.ErrorHtml5QrcodeScanner:\n            handleFailedUpload(data)\n            break\n        }\n      },\n    )\n    return () => {\n      h5QrcodeScannerProvides.stop()\n      subscription.unsubscribe()\n    }\n  }, [])\n\n  return {\n    h5QrcodeScannerProvides,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/services/redpacket/index.ts",
    "content": "import { Subject } from 'rxjs'\n\nconst subject = new Subject<void>()\nexport const redpacketService = {\n  refresh: () => {\n    subject.next()\n  },\n  onRefresh: () => subject.asObservable(),\n}\n"
  },
  {
    "path": "packages/core/src/services/socket/hook/useL2CommonSocket.ts",
    "content": "import React from 'react'\nimport * as _ from 'lodash'\nimport { globalSetup, SagaStatus } from '@loopring-web/common-resources'\nimport { useWalletLayer1, useWalletLayer2, store, useVaultLayer2 } from '../../../stores'\nimport { l2CommonService } from '../services/l2CommonService'\n\nexport const useL2CommonSocket = ({\n  throttleWait = globalSetup.throttleWait,\n  walletLayer2Callback,\n  walletLayer1Callback,\n  vaultLayer2Callback,\n}: {\n  throttleWait?: number\n  walletLayer2Callback?: () => void\n  walletLayer1Callback?: () => void\n  vaultLayer2Callback?: () => void\n}) => {\n  const { updateWalletLayer1, status: walletLayer1Status } = useWalletLayer1()\n  const { updateWalletLayer2, status: walletLayer2Status } = useWalletLayer2()\n  const { updateVaultLayer2, status: vaultLayer2Status } = useVaultLayer2()\n\n  const subject = React.useMemo(() => l2CommonService.onSocket(), [])\n\n  const socketUpdate = React.useCallback(\n    _.throttle(({ walletLayer1Status, walletLayer2Status, vaultLayer2Status }) => {\n      if (walletLayer1Status !== SagaStatus.PENDING) {\n        updateWalletLayer1()\n      }\n      if (walletLayer2Status !== SagaStatus.PENDING) {\n        updateWalletLayer2()\n      }\n      if (vaultLayer2Status !== SagaStatus.PENDING) {\n        updateVaultLayer2({})\n      }\n    }, throttleWait),\n    [],\n  )\n  const _socketUpdate = ({ walletLayer2Status, walletLayer1Status }: any) => {\n    socketUpdate({ walletLayer2Status, walletLayer1Status })\n  }\n\n  // const  _socketUpdate = React.useCallback(socketUpdate({updateWalletLayer1,updateWalletLayer2,walletLayer1Status,walletLayer2Status}),[]);\n  React.useEffect(() => {\n    const subscription = subject.subscribe(() => {\n      const walletLayer2Status = store.getState().walletLayer2.status\n      const walletLayer1Status = store.getState().walletLayer1.status\n      const vaultLayer2Status = store.getState().vaultLayer2.status\n      _socketUpdate({ walletLayer2Status, walletLayer1Status, vaultLayer2Status })\n    })\n    return () => subscription.unsubscribe()\n  }, [subject])\n  React.useEffect(() => {\n    if (walletLayer2Callback && walletLayer2Status === SagaStatus.UNSET) {\n      walletLayer2Callback()\n    }\n  }, [walletLayer2Status])\n  React.useEffect(() => {\n    if (walletLayer1Callback && walletLayer1Status === SagaStatus.UNSET) {\n      walletLayer1Callback()\n    }\n  }, [walletLayer1Status])\n  React.useEffect(() => {\n    if (vaultLayer2Callback && vaultLayer2Status === SagaStatus.UNSET) {\n      vaultLayer2Callback()\n    }\n  }, [vaultLayer2Status])\n  React.useEffect(() => {\n    walletLayer2Callback && walletLayer2Callback()\n    walletLayer1Callback && walletLayer1Callback()\n    vaultLayer2Callback && vaultLayer2Callback()\n  }, [])\n}\n"
  },
  {
    "path": "packages/core/src/services/socket/hook/useNotificationSocket.ts",
    "content": "import React from 'react'\nimport { notificationService } from '../../../index'\nimport { BasicListItem } from '@loopring-web/component-lib'\nimport * as _ from 'lodash'\nimport { globalSetup } from '@loopring-web/common-resources'\n\nexport const useNotificationSocket = ({\n  notificationCallback,\n  throttleWait = globalSetup.throttleWait,\n}: {\n  notificationCallback?: (notification: BasicListItem) => void\n  throttleWait?: number\n}) => {\n  const socketUpdate = _.throttle(({ notification }) => {\n    notificationCallback && notificationCallback(notification)\n  }, throttleWait)\n  const subject = React.useMemo(() => notificationService.onSocket(), [])\n  React.useEffect(() => {\n    const subscription = subject.subscribe(({ notification }: { notification: BasicListItem }) => {\n      socketUpdate({ notification })\n    })\n    return () => subscription.unsubscribe()\n  }, [subject])\n}\n"
  },
  {
    "path": "packages/core/src/services/socket/hook/useWalletLayer2Socket.ts",
    "content": "import React from 'react'\nimport * as _ from 'lodash'\nimport { globalSetup, SagaStatus } from '@loopring-web/common-resources'\nimport { useWalletLayer1 } from '../../../stores/walletLayer1'\nimport { useWalletLayer2 } from '../../../stores/walletLayer2'\nimport { store, walletLayer2Service } from '../../../index'\n\nexport const useWalletLayer2Socket = ({\n  throttleWait = globalSetup.throttleWait,\n  walletLayer2Callback,\n  walletLayer1Callback,\n}: {\n  throttleWait?: number\n  walletLayer2Callback?: () => void\n  walletLayer1Callback?: () => void\n}) => {\n  const { updateWalletLayer1, status: walletLayer1Status } = useWalletLayer1()\n  const { updateWalletLayer2, status: walletLayer2Status } = useWalletLayer2()\n  const subject = React.useMemo(() => walletLayer2Service.onSocket(), [])\n\n  const socketUpdate = React.useCallback(\n    _.throttle(({ walletLayer1Status, walletLayer2Status }) => {\n      if (walletLayer1Status !== SagaStatus.PENDING) {\n        updateWalletLayer1()\n      }\n      if (walletLayer2Status !== SagaStatus.PENDING) {\n        updateWalletLayer2()\n      }\n    }, throttleWait),\n    [],\n  )\n  const _socketUpdate = ({ walletLayer2Status, walletLayer1Status }: any) => {\n    socketUpdate({ walletLayer2Status, walletLayer1Status })\n  }\n\n  // const  _socketUpdate = React.useCallback(socketUpdate({updateWalletLayer1,updateWalletLayer2,walletLayer1Status,walletLayer2Status}),[]);\n  React.useEffect(() => {\n    const subscription = subject.subscribe(() => {\n      const walletLayer2Status = store.getState().walletLayer2.status\n      const walletLayer1Status = store.getState().walletLayer1.status\n      _socketUpdate({ walletLayer2Status, walletLayer1Status })\n    })\n    return () => subscription.unsubscribe()\n  }, [subject])\n  React.useEffect(() => {\n    if (walletLayer2Callback && walletLayer2Status === SagaStatus.UNSET) {\n      walletLayer2Callback()\n    }\n  }, [walletLayer2Status])\n  React.useEffect(() => {\n    if (walletLayer1Callback && walletLayer1Status === SagaStatus.UNSET) {\n      walletLayer1Callback()\n    }\n  }, [walletLayer1Status])\n  React.useEffect(() => {\n    walletLayer2Callback && walletLayer2Callback()\n    walletLayer1Callback && walletLayer1Callback()\n  }, [])\n}\n"
  },
  {
    "path": "packages/core/src/services/socket/hook/useWalletLayer2WithNFTSocket.ts",
    "content": "import React from 'react'\nimport * as _ from 'lodash'\nimport { globalSetup, SagaStatus } from '@loopring-web/common-resources'\nimport { useWalletLayer1 } from '../../../stores/walletLayer1'\nimport { useWalletLayer2 } from '../../../stores/walletLayer2'\nimport { useWalletLayer2NFT } from '../../../stores/walletLayer2NFT'\nimport { store, useModalData, useNFTListDeep, walletLayer2Service } from '../../../index'\nimport { useOpenModals } from '@loopring-web/component-lib'\n\nexport const useWalletLayer2WithNFTSocket = ({\n  throttleWait = globalSetup.throttleWait,\n  walletLayer2Callback,\n  walletLayer1Callback,\n}: {\n  throttleWait?: number\n  walletLayer2Callback?: () => void\n  walletLayer1Callback?: () => void\n}) => {\n  const {\n    setShowNFTDetail,\n    modals: {\n      isShowNFTDetail: { isShow: isShowDetail, ...restDetail },\n    },\n  } = useOpenModals()\n  const { nftListReduce } = useNFTListDeep()\n  const { updateNFTTransferData, updateNFTWithdrawData } = useModalData()\n  const { updateWalletLayer1, status: walletLayer1Status } = useWalletLayer1()\n  const { updateWalletLayer2, status: walletLayer2Status } = useWalletLayer2()\n  const {\n    walletLayer2NFT,\n    updateWalletLayer2NFT,\n    status: walletLayer2NFTStatus,\n  } = useWalletLayer2NFT()\n  const subject = React.useMemo(() => walletLayer2Service.onSocket(), [])\n\n  const socketUpdate = React.useCallback(\n    _.throttle(({ walletLayer1Status, walletLayer2Status, nftDatas }) => {\n      if (walletLayer1Status !== SagaStatus.PENDING) {\n        updateWalletLayer1()\n      }\n      if (walletLayer2Status !== SagaStatus.PENDING) {\n        updateWalletLayer2()\n      }\n      if (walletLayer2NFTStatus !== SagaStatus.PENDING && nftDatas) {\n        updateWalletLayer2NFT({\n          page: 1,\n          nftDatas: nftDatas?.join(','),\n          collectionContractAddress: undefined,\n          collectionId: undefined,\n        })\n      }\n    }, throttleWait),\n    [],\n  )\n  const _socketUpdate = ({ walletLayer2Status, walletLayer1Status, nftDatas }: any) => {\n    socketUpdate({ walletLayer2Status, walletLayer1Status, nftDatas })\n  }\n\n  // const  _socketUpdate = React.useCallback(socketUpdate({updateWalletLayer1,updateWalletLayer2,walletLayer1Status,walletLayer2Status}),[]);\n  React.useEffect(() => {\n    const subscription = subject.subscribe((props: { nftDatas: string[] } | undefined) => {\n      const walletLayer2Status = store.getState().walletLayer2.status\n      const walletLayer1Status = store.getState().walletLayer1.status\n      _socketUpdate({\n        walletLayer2Status,\n        walletLayer1Status,\n        nftDatas: props?.nftDatas,\n      })\n    })\n    return () => subscription.unsubscribe()\n  }, [subject])\n\n  const walletLayer2NFTCallback = React.useCallback(async () => {\n    if (isShowDetail) {\n      const _walletLayer2NFT = nftListReduce(walletLayer2NFT)\n      const item = _walletLayer2NFT.find((item: any) => {\n        return item.nftData === restDetail?.nftData\n      })\n      if (item) {\n        const nftEle = { ...restDetail, ...item }\n        setShowNFTDetail({\n          isShow: isShowDetail,\n          ...nftEle,\n        })\n        updateNFTWithdrawData({ ...nftEle })\n        updateNFTTransferData({ ...nftEle })\n      }\n    }\n  }, [])\n  React.useEffect(() => {\n    if (walletLayer2Status === SagaStatus.UNSET && walletLayer2NFTStatus === SagaStatus.UNSET) {\n      walletLayer2NFTCallback()\n      walletLayer2Callback && walletLayer2Callback()\n    }\n  }, [walletLayer2Status, walletLayer2NFTStatus])\n  React.useEffect(() => {\n    if (walletLayer1Callback && walletLayer1Status === SagaStatus.UNSET) {\n      walletLayer1Callback()\n    }\n  }, [walletLayer1Status])\n}\n"
  },
  {
    "path": "packages/core/src/services/socket/index.ts",
    "content": "export * from './socketUtil'\nexport * from './hook/useWalletLayer2Socket'\nexport * from './services/ammPoolService'\nexport * from './services/tickerService'\nexport * from './services/walletLayer2Service'\nexport * from './services/bookService'\nexport * from './services/mixorderService'\nexport * from './services/orderbookService'\nexport * from './services/tradeService'\nexport * from './services/mixtradeService'\nexport * from './hook/useWalletLayer2WithNFTSocket'\nexport * from './services/btradeOrderbookService'\nexport * from './services/notificationService'\nexport * from './hook/useNotificationSocket'\nexport * from './services/l2CommonService'\nexport * from './hook/useL2CommonSocket'\n"
  },
  {
    "path": "packages/core/src/services/socket/services/ammPoolService.ts",
    "content": "import { Subject } from 'rxjs'\n\nexport type AmmPoolMap<R> = {\n  [key in keyof R]: { pooled: [string, string]; lp: string }\n}\n// <R extends {[key:string]:any}>\nconst subject = new Subject<{\n  ammPoolMap: AmmPoolMap<{ [key: string]: any }>\n}>()\n\nexport const ammPoolService = {\n  sendAmmPool: (ammPoolMap: AmmPoolMap<{ [key: string]: any }>) => subject.next({ ammPoolMap }),\n  // clearMessages: () => subject.next(),\n  onSocket: () => subject.asObservable(),\n}\n"
  },
  {
    "path": "packages/core/src/services/socket/services/bookService.ts",
    "content": "import { OrderDetail } from '@loopring-web/loopring-sdk'\nimport { Subject } from 'rxjs'\n\nconst subject = new Subject<{ bookMap: BookMap<{ [key: string]: any }> }>()\n\nexport type BookMap<R> = {\n  [key in keyof R]: OrderDetail\n}\n// <R extends {[key:string]:any}>\n\nexport const bookService = {\n  sendBook: (bookMap: BookMap<{ [key: string]: any }>) => subject.next({ bookMap }),\n  // clearMessages: () => subject.next(),\n  onSocket: () => subject.asObservable(),\n}\n"
  },
  {
    "path": "packages/core/src/services/socket/services/btradeOrderbookService.ts",
    "content": "import { Subject } from 'rxjs'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nconst subject = new Subject<{\n  btradeOrderbookMap: BtradeOrderbookMap<{ [key: string]: any }>\n}>()\n\nexport type BtradeOrderbookMap<R> = {\n  [key in keyof R]: sdk.DepthData\n}\n// <R extends {[key:string]:any}>\n\nexport const btradeOrderbookService = {\n  sendBtradeOrderBook: (btradeOrderbookMap: BtradeOrderbookMap<{ [key: string]: any }>) => {\n    const _orderbookMap = Reflect.ownKeys(btradeOrderbookMap).reduce((pre, key) => {\n      const data = btradeOrderbookMap[key as string]\n      const { bids, asks, mid_price } = sdk.getMidPrice({\n        _asks: data['asks'],\n        _bids: data['bids'],\n      })\n\n      return {\n        ...pre,\n        [key]: {\n          ...data,\n          mid_price,\n          bids: bids.ab_arr,\n          bids_prices: bids.ab_prices,\n          bids_amtTotals: bids.ab_amtTotals,\n          bids_volTotals: bids.ab_volTotals,\n          bids_amtTotal: bids.amtTotal.toString(),\n          bids_volTotal: bids.volTotal.toString(),\n          asks: asks.ab_arr,\n          asks_prices: asks.ab_prices,\n          asks_amtTotals: asks.ab_amtTotals,\n          asks_volTotals: asks.ab_volTotals,\n          asks_amtTotal: asks.amtTotal.toString(),\n          asks_volTotal: asks.volTotal.toString(),\n        },\n      }\n    }, {})\n\n    subject.next({ btradeOrderbookMap: _orderbookMap })\n  },\n  // clearMessages: () => subject.next(),\n  onSocket: () => subject.asObservable(),\n}\n"
  },
  {
    "path": "packages/core/src/services/socket/services/l2CommonService.ts",
    "content": "import { Subject } from 'rxjs'\nimport { WsL2Common } from '@loopring-web/loopring-sdk/src/defs/ws_defs'\nconst subject = new Subject<{ nftDatas: string[] } | undefined>()\n\nexport const l2CommonService = {\n  sendUserUpdate: (props?: { data: WsL2Common } | undefined) => {\n    subject.next(props ?? undefined)\n  },\n  onSocket: () => subject.asObservable(),\n}\n"
  },
  {
    "path": "packages/core/src/services/socket/services/mixorderService.ts",
    "content": "import { Subject } from 'rxjs'\nimport { DepthData, getMidPrice } from '@loopring-web/loopring-sdk'\n\nconst subject = new Subject<{\n  mixorderMap: MixorderMap<{ [key: string]: any }>\n}>()\n\nexport type MixorderMap<R> = {\n  [key in keyof R]: DepthData\n}\n// <R extends {[key:string]:any}>\n\nexport const mixorderService = {\n  sendMixorder: (mixorderMap: MixorderMap<{ [key: string]: any }>) => {\n    const _mixorderMap = Reflect.ownKeys(mixorderMap).reduce((pre, key) => {\n      const data = mixorderMap[key as string]\n      const { bids, asks, mid_price } = getMidPrice({\n        _asks: data['asks'],\n        _bids: data['bids'],\n      })\n\n      return {\n        ...pre,\n        [key]: {\n          ...data,\n          mid_price,\n          bids: bids.ab_arr,\n          bids_prices: bids.ab_prices,\n          bids_amtTotals: bids.ab_amtTotals,\n          bids_volTotals: bids.ab_volTotals,\n          bids_amtTotal: bids.amtTotal.toString(),\n          bids_volTotal: bids.volTotal.toString(),\n          asks: asks.ab_arr,\n          asks_prices: asks.ab_prices,\n          asks_amtTotals: asks.ab_amtTotals,\n          asks_volTotals: asks.ab_volTotals,\n          asks_amtTotal: asks.amtTotal.toString(),\n          asks_volTotal: asks.volTotal.toString(),\n        },\n      }\n    }, {})\n\n    subject.next({ mixorderMap: _mixorderMap })\n  },\n  // clearMessages: () => subject.next(),\n  onSocket: () => subject.asObservable(),\n}\n"
  },
  {
    "path": "packages/core/src/services/socket/services/mixtradeService.ts",
    "content": "import { Subject } from 'rxjs'\nimport { MarketTradeInfo } from '@loopring-web/loopring-sdk'\n\nconst subject = new Subject<{ mixtrades: MarketTradeInfo[] }>()\n\nexport const mixtradeService = {\n  sendMixtrade: (mixtrades: MarketTradeInfo[]) => {\n    subject.next({ mixtrades: mixtrades })\n  },\n  // clearMessages: () => subject.next(),\n  onSocket: () => subject.asObservable(),\n}\n"
  },
  {
    "path": "packages/core/src/services/socket/services/notificationService.ts",
    "content": "import { Subject } from 'rxjs'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\n// import { BasicListItem } from '@loopring-web/component-lib'\n\n// export type NotificationMap<R> = {\n//   [key in keyof R]: { pooled: [string, string]; lp: string }\n// }\n// <R extends {[key:string]:any}>\nconst subject = new Subject<{\n  notification: sdk.UserNotification\n}>()\n\nexport const notificationService = {\n  sendNotification: (notification: sdk.UserNotification) => subject.next({ notification }),\n  // clearMessages: () => subject.next(),\n  onSocket: () => subject.asObservable(),\n}\n"
  },
  {
    "path": "packages/core/src/services/socket/services/orderbookService.ts",
    "content": "import { Subject } from 'rxjs'\nimport { DepthData, getMidPrice } from '@loopring-web/loopring-sdk'\n\nconst subject = new Subject<{\n  orderbookMap: OrderbookMap<{ [key: string]: any }>\n}>()\n\nexport type OrderbookMap<R> = {\n  [key in keyof R]: DepthData\n}\n// <R extends {[key:string]:any}>\n\nexport const orderbookService = {\n  sendOrderbook: (orderbookMap: OrderbookMap<{ [key: string]: any }>) => {\n    const _orderbookMap = Reflect.ownKeys(orderbookMap).reduce((pre, key) => {\n      const data = orderbookMap[key as string]\n      const { bids, asks, mid_price } = getMidPrice({\n        _asks: data['asks'],\n        _bids: data['bids'],\n      })\n\n      return {\n        ...pre,\n        [key]: {\n          ...data,\n          mid_price,\n          bids: bids.ab_arr,\n          bids_prices: bids.ab_prices,\n          bids_amtTotals: bids.ab_amtTotals,\n          bids_volTotals: bids.ab_volTotals,\n          bids_amtTotal: bids.amtTotal.toString(),\n          bids_volTotal: bids.volTotal.toString(),\n          asks: asks.ab_arr,\n          asks_prices: asks.ab_prices,\n          asks_amtTotals: asks.ab_amtTotals,\n          asks_volTotals: asks.ab_volTotals,\n          asks_amtTotal: asks.amtTotal.toString(),\n          asks_volTotal: asks.volTotal.toString(),\n        },\n      }\n    }, {})\n\n    subject.next({ orderbookMap: _orderbookMap })\n  },\n  // clearMessages: () => subject.next(),\n  onSocket: () => subject.asObservable(),\n}\n"
  },
  {
    "path": "packages/core/src/services/socket/services/tickerService.ts",
    "content": "import { Subject } from 'rxjs'\nimport { LoopringMap, TickerData } from '@loopring-web/loopring-sdk'\nimport { makeTickerMap } from '../../../hooks'\nimport { updateTicker } from '../../../stores/ticker/reducer'\nimport { store, TickerMap } from '../../../stores'\n\nconst subject = new Subject<{ tickerMap: TickerMap<{ [key: string]: any }> }>()\n\n// export type TickerMap<R> = {\n//     [key in keyof R]:TradeFloat\n// }\n// <R extends {[key:string]:any}>\n//<R>\nexport const tickerService = {\n  sendTicker: (_tickerMap: LoopringMap<TickerData>) => {\n    // dispatchEvent()\n    store.dispatch(updateTicker(_tickerMap))\n    const tickerMap: TickerMap<{ [key: string]: any }> = makeTickerMap({\n      tickerMap: _tickerMap,\n    })\n    subject.next({ tickerMap })\n  },\n  // clearMessages: () => subject.next(),\n  onSocket: () => subject.asObservable(),\n}\n"
  },
  {
    "path": "packages/core/src/services/socket/services/tradeService.ts",
    "content": "import { Subject } from 'rxjs'\nimport { MarketTradeInfo } from '@loopring-web/loopring-sdk'\n\nconst subject = new Subject<{ trades: MarketTradeInfo[] }>()\n\nexport const tradeService = {\n  sendTrade: (trades: MarketTradeInfo[]) => {\n    subject.next({ trades })\n  },\n  // clearMessages: () => subject.next(),\n  onSocket: () => subject.asObservable(),\n}\n"
  },
  {
    "path": "packages/core/src/services/socket/services/walletLayer2Service.ts",
    "content": "import { Subject } from 'rxjs'\nconst subject = new Subject<{ nftDatas: string[] } | undefined>()\n\nexport const walletLayer2Service = {\n  sendUserUpdate: (props?: { nftDatas: string[] } | undefined) => {\n    subject.next(props ?? undefined)\n  },\n  onSocket: () => subject.asObservable(),\n}\n"
  },
  {
    "path": "packages/core/src/services/socket/socketUtil.ts",
    "content": "import * as sdk from '@loopring-web/loopring-sdk'\nimport { walletLayer2Service } from './services/walletLayer2Service'\nimport { tickerService } from './services/tickerService'\nimport { ammPoolService } from './services/ammPoolService'\nimport { CustomError, ErrorMap, globalSetup, myLog } from '@loopring-web/common-resources'\nimport { LoopringAPI, notificationService, SocketMap, SocketUserMap } from '../../index'\nimport { bookService } from './services/bookService'\nimport { orderbookService } from './services/orderbookService'\nimport { tradeService } from './services/tradeService'\nimport { mixorderService } from './services/mixorderService'\nimport { mixtradeService } from './services/mixtradeService'\nimport { btradeOrderbookService } from './services/btradeOrderbookService'\nimport { l2CommonService } from './services/l2CommonService'\nimport * as _ from 'lodash'\n\nexport type SocketEvent = (e: any, ...props: any[]) => any\n\nexport enum PINGPONG {\n  pingpong = 'pingpong',\n}\n\nexport type SocketCallbackMap = {\n  // [sdk.WsTopicType.pingpong]:  { fn: SocketEvent, deps?: any[] },\n  [key in sdk.WsTopicType | PINGPONG]?: { fn: SocketEvent; deps: any[] }\n}\n//\nexport type SocketEventMap = {\n  [key in sdk.WsTopicType | PINGPONG]: SocketEvent\n}\n\nexport class LoopringSocket {\n  private static SocketEventMap: SocketEventMap = {\n    [sdk.WsTopicType.account]: (_data: { [key: string]: any }) => {\n      walletLayer2Service.sendUserUpdate()\n    },\n    [sdk.WsTopicType.notification]: (data: sdk.UserNotification, _topic: any) => {\n      notificationService.sendNotification(data)\n    },\n    [sdk.WsTopicType.l2Common]: (\n      { actionType }: { data: sdk.WsL2Common; actionType: string },\n      _topic: any,\n    ) => {\n      if (actionType == sdk.WS_ACTIONT_YPE.VAULT_ACCOUNT_UPDATE) {\n        l2CommonService.sendUserUpdate()\n      }\n    },\n    [sdk.WsTopicType.order]: (data: sdk.OrderDetail) => {\n      bookService.sendBook({\n        [data.market]: data as any,\n      })\n    },\n    [sdk.WsTopicType.orderbook]: (data: sdk.DepthData, topic: any) => {\n      const timestamp = Date.now()\n      orderbookService.sendOrderbook({\n        [topic.market]: {\n          ...data,\n          timestamp: timestamp,\n          symbol: topic.market,\n        } as any,\n      })\n    },\n    [sdk.WsTopicType.mixorder]: (data: sdk.DepthData, topic: any) => {\n      if (\n        (window as any)?.loopringSocket?.socketKeyMap &&\n        (window as any).loopringSocket?.socketKeyMap[sdk.WsTopicType.mixorder]?.level ===\n          topic.level\n      ) {\n        const timestamp = Date.now()\n        mixorderService.sendMixorder({\n          [topic.market]: {\n            ...data,\n            timestamp: timestamp,\n            symbol: topic.market,\n          } as any,\n        })\n      }\n    },\n    [sdk.WsTopicType.btradedepth]: (data: sdk.DepthData, topic: any) => {\n      if (\n        (window as any)?.loopringSocket?.socketKeyMap &&\n        (window as any).loopringSocket?.socketKeyMap[sdk.WsTopicType.btradedepth]?.level ===\n          topic.level\n      ) {\n        const timestamp = Date.now()\n        btradeOrderbookService.sendBtradeOrderBook({\n          [topic.market]: {\n            ...data,\n            timestamp: timestamp,\n            symbol: topic.market,\n          } as any,\n        })\n      }\n    },\n    [sdk.WsTopicType.btradedepth]: (data: sdk.DepthData, topic: any) => {\n      if (\n        (window as any)?.loopringSocket?.socketKeyMap &&\n        (window as any).loopringSocket?.socketKeyMap[sdk.WsTopicType.btradedepth]?.level ===\n          topic.level\n      ) {\n        const timestamp = Date.now()\n        btradeOrderbookService.sendBtradeOrderBook({\n          [topic.market]: {\n            ...data,\n            timestamp: timestamp,\n            symbol: topic.market,\n          } as any,\n        })\n      }\n    },\n    [sdk.WsTopicType.trade]: (datas: string[][]) => {\n      const marketTrades: sdk.MarketTradeInfo[] = datas.map((data) => {\n        const [market, tradeTime, tradeId, side, volume, price, fee] = data\n        return {\n          market,\n          tradeTime,\n          tradeId,\n          side,\n          volume,\n          price,\n          fee,\n        } as unknown as sdk.MarketTradeInfo\n      })\n      tradeService.sendTrade(marketTrades)\n    },\n    [sdk.WsTopicType.mixtrade]: (datas: string[][]) => {\n      const marketTrades: sdk.MarketTradeInfo[] = datas.map((data) => {\n        const [tradeTime, tradeId, side, volume, price, market, fee] = data\n        return {\n          market: market.replace('AMM-', ''),\n          tradeTime,\n          tradeId,\n          side,\n          volume,\n          price,\n          fee,\n        } as unknown as sdk.MarketTradeInfo\n      })\n      mixtradeService.sendMixtrade(marketTrades)\n    },\n    [sdk.WsTopicType.ticker]: (data: string[]) => {\n      const [symbol, timestamp, size, volume, open, high, low, close, count, bid, ask] = data\n      // @ts-ignore\n      const [, base, quote] = symbol.match(/(\\w+)-(\\w+)/i)\n      const base_token_volume = size\n      const quote_token_volume = volume\n      const change =\n        open === undefined || Number(open) === 0\n          ? undefined\n          : sdk.toBig(close).minus(open).div(open)\n      tickerService.sendTicker({\n        [symbol]: {\n          symbol,\n          base,\n          quote,\n          base_token_volume,\n          quote_token_volume,\n          timestamp: Number(timestamp),\n          change,\n          base_fee_amt: undefined,\n          quote_fee_amt: undefined,\n          open,\n          high,\n          low,\n          close,\n          count,\n          bid,\n          ask,\n        } as any,\n      })\n    },\n    //TODO\n    [sdk.WsTopicType.candlestick]: (_e: any) => {},\n    //TODO\n    [sdk.WsTopicType.crawlTokenPrices]: (_e: any) => {},\n\n    [sdk.WsTopicType.ammpool]: (data: [[string, string], string], topic: any) => {\n      if (data.length) {\n        ammPoolService.sendAmmPool({\n          [topic.poolAddress]: { pooled: data[0], lp: data[1] },\n        })\n      }\n    },\n    [PINGPONG.pingpong]: (data: string, socket: WebSocket) => {\n      if (data === 'ping' && socket && socket.send && socket.readyState === 1) {\n        socket.send('pong')\n      } else if ((window as any)?.loopringSocket?.isConnectSocket()) {\n        ;(window as any).loopringSocket.ws.send('pong')\n      }\n    },\n  }\n  private __wsTimer__: { timer: NodeJS.Timer | -1; count: number } = {\n    timer: -1,\n    count: 0,\n  }\n  private _baseUrl: string\n\n  constructor(url: string) {\n    // const url = sdk.ChainId.MAINNET === chainId ? process.env.REACT_APP_API_URL : process.env.REACT_APP_API_URL_UAT;\n    this._baseUrl = url // baseSocket: string = `wss://ws.${url}/v3/ws?wsApiKey=${wsKey}`;\n  }\n\n  private _socketKeyMap: object | undefined\n\n  get socketKeyMap(): object | undefined {\n    return this._socketKeyMap\n  }\n\n  private _topics: object | undefined\n\n  get topics(): object | undefined {\n    return this._topics\n  }\n\n  private _socketCallbackMap: SocketCallbackMap | undefined\n\n  get socketCallbackMap(): SocketCallbackMap | undefined {\n    return this._socketCallbackMap\n  }\n\n  private _ws: WebSocket | undefined\n\n  get ws(): WebSocket | undefined {\n    return this._ws\n  }\n  private sendMeassage = _.throttle(\n    ({ topics, apiKey }) => {\n      if (!this.isConnectSocket()) {\n        this.socketConnect({ topics, apiKey }).catch(() => {\n          throw new CustomError(ErrorMap.SOCKET_ERROR)\n        })\n      } else {\n        this._ws?.send(this.makeTopics(topics, apiKey))\n      }\n    },\n    globalSetup.wait,\n    { trailing: true },\n  )\n\n  public socketSendMessage = async ({\n    socket,\n    apiKey,\n  }: {\n    chainId: sdk.ChainId | 'unknown'\n    socket: { [key: string]: string[] }\n    apiKey?: string\n  }): Promise<boolean> => {\n    try {\n      if (socket && Reflect.ownKeys(socket).length) {\n        //register ping pong event\n        this.clearInitTimer(true)\n        this.resetSocketEvents()\n        this._socketKeyMap = socket\n        const { topics } = this.makeMessageArray({ socket })\n        myLog('makeMessageArray', socket, topics)\n        this.sendMeassage({ topics, apiKey })\n        return true\n      } else {\n        if (!this.isConnectSocket()) {\n          this.socketClose()\n        }\n        return false\n      }\n    } catch (error: any) {\n      throw new CustomError(ErrorMap.SOCKET_ERROR)\n    }\n  }\n  public socketClose = async () => {\n    let ws: WebSocket | undefined = this._ws\n    return new Promise((reolve) => {\n      if (ws) {\n        ws.onclose = function (e) {\n          reolve(`Socket is closed, ${e.reason}`)\n        }\n        ws.close()\n      } else {\n        reolve('no websocket')\n      }\n    })\n  }\n\n  public removeSocketEvents = (key: string) => {\n    // @ts-ignore\n    if (this._socketCallbackMap && this._socketCallbackMap[key]) {\n      // @ts-ignore\n      delete this._socketCallbackMap[key]\n    }\n  }\n\n  private makeMessageArray = ({\n    socket,\n  }: {\n    socket: SocketMap & SocketUserMap\n  }): {\n    topics: any[]\n  } => {\n    let topics: any[] = [],\n      list: any[] = [] // let registerDispatch = [];\n    Reflect.ownKeys(socket).forEach((eventType) => {\n      switch (eventType) {\n        case sdk.WsTopicType.ticker:\n          const tickerSocket = socket[sdk.WsTopicType.ticker]\n          if (tickerSocket) {\n            list = tickerSocket.map((key) => sdk.getTickerArg(key))\n            if (list && list.length) {\n              this.addSocketEvents(sdk.WsTopicType.ticker)\n              topics = [...topics, ...list]\n            }\n          }\n          break\n        case sdk.WsTopicType.ammpool:\n          const ammpoolSocket = socket[sdk.WsTopicType.ammpool]\n          if (ammpoolSocket) {\n            list = ammpoolSocket.map((key) => sdk.getAmmpoolArg(key))\n            if (list && list.length) {\n              this.addSocketEvents(sdk.WsTopicType.ammpool)\n              topics = [...topics, ...list]\n            }\n          }\n          break\n        case sdk.WsTopicType.account:\n          if (socket[sdk.WsTopicType.account]) {\n            list = [sdk.getAccountArg()]\n          }\n          if (list && list.length) {\n            this.addSocketEvents(sdk.WsTopicType.account)\n            topics = [...topics, ...list]\n          }\n          break\n        case sdk.WsTopicType.notification:\n          const params = socket[sdk.WsTopicType.notification]\n          if (params) {\n            this.addSocketEvents(sdk.WsTopicType.notification)\n            topics = [...topics, sdk.getNotificationArg(params)]\n          }\n\n          break\n        case sdk.WsTopicType.l2Common:\n          if (socket[sdk.WsTopicType.l2Common]) {\n            this.addSocketEvents(sdk.WsTopicType.l2Common)\n            topics = [...topics, sdk.getL2Common(socket[sdk.WsTopicType.l2Common])]\n          }\n          break\n        case sdk.WsTopicType.order:\n          const orderSocket = socket[sdk.WsTopicType.order]\n          if (orderSocket) {\n            list = orderSocket.map((key) => sdk.getOrderArg(key))\n            if (list && list.length) {\n              this.addSocketEvents(sdk.WsTopicType.order)\n              topics = [...topics, ...list]\n            }\n          }\n\n          break\n        case sdk.WsTopicType.orderbook:\n          const orderbookSocket = socket[sdk.WsTopicType.orderbook]\n          if (orderbookSocket) {\n            const level = orderbookSocket.level ?? 0\n            const snapshot = orderbookSocket.snapshot ?? true\n            const count = orderbookSocket.count ?? 50\n            list = orderbookSocket.markets.map((key) =>\n              sdk.getOrderBookArg({\n                market: key,\n                level,\n                count,\n                snapshot,\n              }),\n            )\n            if (list && list.length) {\n              this.addSocketEvents(sdk.WsTopicType.orderbook)\n              topics = [...topics, ...list]\n            }\n          }\n\n          break\n        case sdk.WsTopicType.mixorder:\n          const mixorderSocket = socket[sdk.WsTopicType.mixorder]\n          if (mixorderSocket) {\n            const level = mixorderSocket.level ?? 0\n            const snapshot = mixorderSocket.snapshot ?? true\n            const count = mixorderSocket.count ?? 50\n            list = mixorderSocket.markets.map((key) =>\n              sdk.getMixOrderArg({\n                market: key,\n                level,\n                count,\n                snapshot,\n                showOverlap: false,\n              }),\n            )\n            if (list && list.length) {\n              this.addSocketEvents(sdk.WsTopicType.mixorder)\n              topics = [...topics, ...list]\n            }\n          }\n          break\n\n        case sdk.WsTopicType.btradedepth:\n          const btradeOrderSocket = socket[sdk.WsTopicType.btradedepth]\n          if (btradeOrderSocket) {\n            const level = btradeOrderSocket.level ?? 0\n            const snapshot = btradeOrderSocket.snapshot ?? true\n            const count = btradeOrderSocket.count ?? 50\n            list = btradeOrderSocket.markets.map((key) => {\n              return sdk.getBtradeOrderBook({\n                market: key,\n                level,\n                count,\n                snapshot,\n                showOverlap: false,\n              })\n            })\n            if (list && list.length) {\n              this.addSocketEvents(sdk.WsTopicType.btradedepth)\n              topics = [...topics, ...list]\n            }\n          }\n          break\n        case sdk.WsTopicType.trade:\n          const tradeSocket = socket[sdk.WsTopicType.trade]\n          if (tradeSocket) {\n            list = tradeSocket.map((key) => sdk.getTradeArg(key))\n            if (list && list.length) {\n              this.addSocketEvents(sdk.WsTopicType.trade)\n              topics = [...topics, ...list]\n            }\n          }\n          break\n        case sdk.WsTopicType.mixtrade:\n          const mixtradeSocket = socket[sdk.WsTopicType.mixtrade]\n          if (mixtradeSocket) {\n            list = mixtradeSocket.map((key) => sdk.getMixTradeArg(key))\n            if (list && list.length) {\n              this.addSocketEvents(sdk.WsTopicType.mixtrade)\n              topics = [...topics, ...list]\n            }\n          }\n          break\n        case sdk.WsTopicType.candlestick:\n          const candlestickSocket = socket[sdk.WsTopicType.candlestick]\n          if (candlestickSocket) {\n            list = candlestickSocket.map((key) => sdk.getCandlestickArg(key))\n            if (list && list.length) {\n              this.addSocketEvents(sdk.WsTopicType.candlestick)\n              topics = [...topics, ...list]\n            }\n          }\n          break\n      }\n    })\n    return { topics }\n  }\n\n  private isConnectSocket = () => {\n    return !!(this._ws && this._ws.readyState === 1)\n  }\n\n  private makeTopics = (topics: any, apiKey?: string) => {\n    let data: any = {\n      op: 'sub',\n      unsubscribeAll: 'true',\n      topics: topics,\n    }\n\n    if (apiKey) {\n      data.apiKey = apiKey\n    }\n    this._topics = topics\n    return JSON.stringify(data)\n    // sendMessage(flat_txt)\n  }\n\n  private addSocketEvents = (type: keyof typeof sdk.WsTopicType | PINGPONG, deps?: any[]) => {\n    this._socketCallbackMap = {\n      ...this._socketCallbackMap,\n      [type]: {\n        fn: LoopringSocket.SocketEventMap[type],\n        deps: deps ? deps : [],\n      },\n    }\n  }\n\n  private socketConnect = async ({\n    topics,\n    apiKey,\n  }: {\n    // chainId: sdk.ChainId | 'unknown',\n    topics: any[]\n    apiKey?: string\n  }) => {\n    try {\n      const self = this\n      if (LoopringAPI.wsAPI && topics) {\n        const { wsKey } = await LoopringAPI.wsAPI.getWsKey()\n        this._ws = new WebSocket(`${this._baseUrl}?wsApiKey=${wsKey}`)\n\n        this._ws.onopen = function () {\n          console.warn('Socket>>Socket', 'WebSocket is open now.')\n          if (self._ws && self._ws.readyState === WebSocket.OPEN) {\n            self._ws.send(self.makeTopics(topics, apiKey))\n          }\n        }\n        this._ws.onmessage = function (e) {\n          const { data } = e\n          // data.topic.topic;\n          if (data === 'ping' && self._socketCallbackMap) {\n            self._socketCallbackMap?.pingpong?.fn.call(\n              self,\n              data,\n              ...self._socketCallbackMap.pingpong.deps,\n            )\n          } else {\n            const result = JSON.parse(data)\n            const { topics, topic } = result\n            if (topics) {\n              // myLog(\"Socket>>Socket topics first return\", topics);\n            }\n            if (topic && topic.topic && self._socketCallbackMap) {\n              const {\n                topic: { topic: _topic },\n                data,\n              } = result\n\n              self._socketCallbackMap[_topic]?.fn.call(\n                self,\n                data,\n                topic,\n                // @ts-ignore\n                ...self._socketCallbackMap[_topic]?.deps,\n              )\n            }\n          }\n          return false\n        }\n        this._ws.onclose = async function (e) {\n          // console.error('Socket>>Socket', e);\n          if (self._ws) {\n            self._ws = undefined\n          }\n          console.log(\n            'Socket>>Socket::',\n            'Socket is closed. Reconnect will be attempted in 1 second.',\n            e.reason,\n          )\n          self.clearInitTimer()\n          if (self.__wsTimer__.count < 5) {\n            self.__wsTimer__.timer = setTimeout(function () {\n              self.socketConnect.call(self, { topics, apiKey })\n            }, 1000 * self.__wsTimer__.count)\n          } else {\n          }\n        }\n        this._ws.onerror = function (err: Event) {\n          console.error('Socket>>Socket', 'Socket encountered error:', 'Closing socket', err)\n        }\n      }\n      return\n    } catch (error: any) {\n      console.error('Socket>>Socket', 'connect error, not from reconnect')\n      // @ts-ignore\n      if (this._ws) {\n        // @ts-ignore\n        this._ws.close()\n      }\n      return\n    }\n  }\n  private clearInitTimer = (init?: boolean) => {\n    if (this.__wsTimer__) {\n      if (this.__wsTimer__.timer !== -1) {\n        clearTimeout(this.__wsTimer__.timer)\n      }\n      this.__wsTimer__.timer = -1\n      this.__wsTimer__.count++\n    }\n    if (init) {\n      this.__wsTimer__ = {\n        timer: -1,\n        count: 0,\n      }\n    }\n  }\n  private resetSocketEvents = () => {\n    this._socketCallbackMap = undefined\n    this.addSocketEvents(PINGPONG.pingpong, [this.ws])\n  }\n}\n"
  },
  {
    "path": "packages/core/src/storage/index.ts",
    "content": "import { TxStatus } from '@loopring-web/loopring-sdk'\nimport { Account, myLog } from '@loopring-web/common-resources'\n\nexport enum CONSTANTS {\n  Handler = 'handler',\n  AccountId = 'account_id',\n  Account = 'account',\n  Apikey = 'apikey',\n  Eddsakey = 'eddsakey',\n  ActiveTime = 'active_time',\n  AmmOrder = 'amm_order',\n  HardwareAddresses = 'hardware_addresses',\n  ConnectorName = 'connector_name',\n\n  DepositHash = '__loopring__.depositsHash',\n\n  WalletConnect = 'walletconnect',\n}\n\nconst SESSION_TIMEOUT = 7 * 24 * 60 * 60 * 1000\n\nexport class UserStorage {\n  public static getLocalDepositHash(account: Account): { [key: string]: any } | undefined {\n    let depositsHash = window.localStorage.getItem(CONSTANTS.DepositHash)\n    if (depositsHash) {\n      depositsHash = JSON.parse(depositsHash)\n      if (depositsHash && account.accAddress && depositsHash[account.accAddress]) {\n        return depositsHash[account.accAddress]\n      }\n    }\n    return undefined\n  }\n\n  public static clearDepositHash(account: Account, value: string) {\n    // @ts-ignore\n    let depositsHash: { [key: string]: object } = window.localStorage.getItem(CONSTANTS.DepositHash)\n    depositsHash = depositsHash ? JSON.parse(depositsHash as any) : {}\n    if (depositsHash[account.accAddress] && depositsHash[account.accAddress][value]) {\n      delete depositsHash[account.accAddress][value]\n    }\n  }\n\n  public static setLocalDepositHash(account: Account, value: string, status: TxStatus): void {\n    // @ts-ignore\n    let depositsHash: { [key: string]: object } = window.localStorage.getItem(CONSTANTS.DepositHash)\n    depositsHash = depositsHash ? JSON.parse(depositsHash as any) : {}\n    depositsHash[account.accAddress] = {\n      ...depositsHash[account.accAddress],\n      [value]: status,\n    }\n  }\n\n  public static clearWalletConnect() {\n    myLog('try to clearWalletConnect....')\n    localStorage.removeItem(CONSTANTS.WalletConnect)\n  }\n\n  public static setConnectorName(connectionName: string) {\n    localStorage.setItem(CONSTANTS.ConnectorName, connectionName)\n  }\n\n  public static getConnectorName() {\n    return localStorage.getItem(CONSTANTS.ConnectorName)\n  }\n\n  public static clearConnectorName() {\n    myLog('try to clearConnectorName')\n    localStorage.removeItem(CONSTANTS.ConnectorName)\n  }\n\n  public static getHandler() {\n    const rawHandler = sessionStorage.getItem(CONSTANTS.Handler)\n    try {\n      if (rawHandler !== undefined && rawHandler !== null) return parseInt(rawHandler)\n    } catch (err) {}\n    return undefined\n  }\n\n  public static setHandler(handler: any) {\n    sessionStorage.setItem(CONSTANTS.Handler, handler)\n  }\n\n  public static clearHandler() {\n    sessionStorage.removeItem(CONSTANTS.Handler)\n  }\n\n  public static checkTimeout(reset: boolean = false): boolean {\n    let dateTimeStr = localStorage.getItem(CONSTANTS.ActiveTime)\n    let now = new Date().getTime()\n\n    if (dateTimeStr !== null && !reset) {\n      let tmpDt = new Date(parseInt(dateTimeStr))\n\n      if (now - tmpDt.getTime() > SESSION_TIMEOUT) {\n        myLog(`TIMEOUT! now:${now} dateTimeStr:${dateTimeStr} delta:${now - tmpDt.getTime()}`)\n        sessionStorage.clear()\n        localStorage.setItem(CONSTANTS.ActiveTime, now.toString())\n        return true\n      }\n    } else {\n      localStorage.setItem(CONSTANTS.ActiveTime, now.toString())\n    }\n\n    return false\n  }\n\n  public static getAccountId() {\n    const rawId = sessionStorage.getItem(CONSTANTS.AccountId)\n    try {\n      if (rawId) return parseInt(rawId)\n    } catch (err) {}\n    return undefined\n  }\n\n  public static setAccountId(accountId: number) {\n    sessionStorage.setItem(CONSTANTS.AccountId, accountId.toString())\n  }\n\n  public static getAccount() {\n    return sessionStorage.getItem(CONSTANTS.Account)\n  }\n\n  public static setAccount(account: string) {\n    sessionStorage.setItem(CONSTANTS.Account, account)\n  }\n\n  public static getApikey() {\n    return sessionStorage.getItem(CONSTANTS.Apikey)\n  }\n\n  public static setApikey(apikey: string) {\n    sessionStorage.setItem(CONSTANTS.Apikey, apikey)\n  }\n\n  public static getEddsakey() {\n    return sessionStorage.getItem(CONSTANTS.Eddsakey)\n  }\n\n  public static setEddsakey(eddsakey: string) {\n    sessionStorage.setItem(CONSTANTS.Eddsakey, eddsakey)\n  }\n\n  public static getAmmOrder(): string {\n    var orderHash = localStorage.getItem(CONSTANTS.AmmOrder)\n    return orderHash ? orderHash : ''\n  }\n\n  public static setAmmOrder(orderHash: string) {\n    localStorage.setItem(CONSTANTS.AmmOrder, orderHash)\n  }\n\n  public static clearAmmOrder() {\n    localStorage.removeItem(CONSTANTS.AmmOrder)\n  }\n\n  public static isHardwareAddress(address: string) {\n    let current = localStorage.getItem(CONSTANTS.HardwareAddresses)\n    if (current) {\n      if (current.includes(address.toLowerCase())) {\n        return true\n      }\n    }\n    return false\n  }\n\n  public static saveHardwareAddress(address: string) {\n    let current = localStorage.getItem(CONSTANTS.HardwareAddresses)\n    if (current) {\n      if (current.includes(address.toLowerCase()) !== true) {\n        let newValue = current + ',' + address.toLowerCase()\n        localStorage.setItem(CONSTANTS.HardwareAddresses, newValue)\n      }\n    } else {\n      localStorage.setItem(CONSTANTS.HardwareAddresses, address.toLowerCase())\n    }\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/Amm/AmmActivityMap/hook.ts",
    "content": "import { useDispatch, useSelector } from 'react-redux'\nimport { AmmActivityMapStates } from './interface'\nimport { getAmmActivityMap, statusUnset } from './reducer'\nimport React from 'react'\n\nexport function useAmmActivityMap(): AmmActivityMapStates & {\n  getAmmActivityMap: () => void\n  statusUnset: () => void\n} {\n  const ammActivityMap: AmmActivityMapStates = useSelector((state: any) => state.amm.ammActivityMap)\n  const dispatch = useDispatch()\n  return {\n    ...ammActivityMap,\n    statusUnset: React.useCallback(() => dispatch(statusUnset(undefined)), [dispatch]),\n    getAmmActivityMap: React.useCallback(() => dispatch(getAmmActivityMap(undefined)), [dispatch]),\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/Amm/AmmActivityMap/interface.ts",
    "content": "import {\n  AmmPoolActivityRule,\n  AmmPoolInProgressActivityRule,\n  LoopringMap,\n} from '@loopring-web/loopring-sdk'\nimport { StateBase } from '@loopring-web/common-resources'\n\nexport type ActivityMap = LoopringMap<LoopringMap<AmmPoolActivityRule[]>>\nexport type ActivityRulesMap = LoopringMap<AmmPoolInProgressActivityRule>\nexport type AmmActivityMapStates = {\n  activityInProgressRules: LoopringMap<AmmPoolInProgressActivityRule>\n  activityDateMap: {\n    [key: number]: {\n      AMM_MINING?: LoopringMap<AmmPoolActivityRule> | undefined\n      ORDERBOOK_MINING?: LoopringMap<AmmPoolActivityRule> | undefined\n      SWAP_VOLUME_RANKING?: LoopringMap<AmmPoolActivityRule> | undefined\n    }\n  }\n  ammActivityMap: LoopringMap<LoopringMap<AmmPoolActivityRule[]>>\n  groupByRuleType: LoopringMap<AmmPoolActivityRule[]>\n  groupByActivityStatus: LoopringMap<AmmPoolActivityRule[]>\n  groupByRuleTypeAndStatus: LoopringMap<LoopringMap<AmmPoolActivityRule[]>>\n} & StateBase\n"
  },
  {
    "path": "packages/core/src/stores/Amm/AmmActivityMap/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { AmmActivityMapStates } from './interface'\nimport { SagaStatus } from '@loopring-web/common-resources'\n\nconst initialState: Required<AmmActivityMapStates> = {\n  ammActivityMap: {},\n  activityInProgressRules: {},\n  activityDateMap: {},\n  groupByRuleType: {},\n  groupByActivityStatus: {},\n  groupByRuleTypeAndStatus: {},\n  status:SagaStatus.PENDING,\n  errorMessage: null,\n}\nconst ammActivityMapSlice: Slice = createSlice({\n  name: 'ammActivityMap',\n  initialState,\n  reducers: {\n    getAmmActivityMap(state, _action: PayloadAction<string | undefined>) {\n      state.status = SagaStatus.PENDING\n    },\n    getAmmActivityMapStatus(state, action: PayloadAction<AmmActivityMapStates>) {\n      // @ts-ignore\n      if (action.payload?.error) {\n        state.status = SagaStatus.ERROR\n        // @ts-ignore\n        state.errorMessage = action.payload.error\n      }\n      state.ammActivityMap = { ...action.payload.groupByRuleTypeAndStatus }\n      state.activityInProgressRules = {\n        ...action.payload.activityInProgressRules,\n      }\n      state.activityDateMap = { ...action.payload.activityDateMap }\n      state.groupByRuleType = { ...action.payload.groupByRuleType }\n      state.groupByActivityStatus = {\n        ...action.payload.groupByActivityStatus,\n      }\n      state.groupByRuleTypeAndStatus = {\n        ...action.payload.groupByRuleTypeAndStatus,\n      }\n      state.status = SagaStatus.DONE\n    },\n    statusUnset: (state) => {\n      state.status = SagaStatus.UNSET\n    },\n  },\n})\nexport { ammActivityMapSlice }\nexport const { getAmmActivityMap, getAmmActivityMapStatus, statusUnset } =\n  ammActivityMapSlice.actions\n"
  },
  {
    "path": "packages/core/src/stores/Amm/AmmActivityMap/saga.ts",
    "content": "import { all, call, put, takeLatest } from 'redux-saga/effects'\nimport { getAmmActivityMap, getAmmActivityMapStatus } from './reducer'\nimport { LoopringAPI } from '../../../api_wrapper'\n\nconst getAmmActivityMapApi = async () => {\n  if (LoopringAPI.ammpoolAPI) {\n    const {\n      activityInProgressRules,\n      activityDateMap,\n      groupByRuleType,\n      groupByActivityStatus,\n      groupByRuleTypeAndStatus,\n    } = await LoopringAPI.ammpoolAPI.getAmmPoolActivityRules()\n    return {\n      data: {\n        activityInProgressRules,\n        activityDateMap,\n        groupByRuleType,\n        groupByActivityStatus,\n        groupByRuleTypeAndStatus,\n      },\n    }\n  } else {\n    return { data: undefined }\n  }\n}\n\nexport function* getPostsSaga() {\n  try {\n    const { data } = yield call(getAmmActivityMapApi)\n    yield put(getAmmActivityMapStatus({ ...data }))\n  } catch (err) {\n    yield put(getAmmActivityMapStatus({ error: err }))\n  }\n}\n\nexport default function* ammActivityMapSaga() {\n  yield all([takeLatest(getAmmActivityMap, getPostsSaga)])\n}\n"
  },
  {
    "path": "packages/core/src/stores/Amm/AmmMap/hook.ts",
    "content": "import { useDispatch, useSelector } from 'react-redux'\nimport { AmmMapStates } from './interface'\nimport React from 'react'\nimport { getAmmMap, statusUnset, updateRealTimeAmmMap } from './reducer'\nimport { RootState } from '../../index'\nimport { LoopringMap, AmmPoolStat } from '@loopring-web/loopring-sdk'\n\nexport const useAmmMap = <\n  R extends { [key: string]: any },\n  I extends { [key: string]: any },\n>(): AmmMapStates<R, I> & {\n  getAmmMap: () => void\n  statusUnset: () => void\n  updateRealTimeAmmMap: (props: { ammPoolStats: LoopringMap<AmmPoolStat> }) => void\n} => {\n  const ammMap: AmmMapStates<R, I> = useSelector((state: RootState) => state.amm.ammMap)\n  const dispatch = useDispatch()\n  return {\n    ...ammMap,\n    updateRealTimeAmmMap: React.useCallback(\n      ({ ammPoolStats }: { ammPoolStats: LoopringMap<AmmPoolStat> }) => {\n        dispatch(updateRealTimeAmmMap({ ammPoolStats }))\n      },\n      [dispatch],\n    ),\n\n    statusUnset: React.useCallback(() => dispatch(statusUnset(undefined)), [dispatch]),\n    getAmmMap: React.useCallback(() => dispatch(getAmmMap(undefined)), [dispatch]),\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/Amm/AmmMap/interface.ts",
    "content": "import { AmmDetail, StateBase } from '@loopring-web/common-resources'\nimport { AmmPoolInfoV3, LoopringMap } from '@loopring-web/loopring-sdk'\n\nexport type GetAmmMapParams = { ammpools: LoopringMap<AmmPoolInfoV3> }\n\nexport type AmmDetailStore<T> = AmmDetail<T>\nexport type AmmMap<R extends { [key: string]: any }, I extends { [key: string]: any }> = {\n  [key in keyof R]: AmmDetailStore<I>\n}\nexport type AmmMapStates<R extends { [key: string]: any }, I extends { [key: string]: any }> = {\n  ammMap: AmmMap<R, I>\n  ammArrayEnable: AmmDetailStore<I>[]\n  __timer__?: number\n} & StateBase\n"
  },
  {
    "path": "packages/core/src/stores/Amm/AmmMap/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { AmmMapStates, GetAmmMapParams } from './interface'\nimport { SagaStatus } from '@loopring-web/common-resources'\nimport { AmmPoolInfoV3, ChainId, LoopringMap, AmmPoolStat } from '@loopring-web/loopring-sdk'\n\nconst initialState: Required<AmmMapStates<any, any>> = {\n  ammMap: {},\n  ammArrayEnable: [],\n  __timer__: -1,\n  status: SagaStatus.PENDING,\n  errorMessage: null,\n}\n// @ts-ignore\nconst ammMapSlice: Slice<AmmMapStates<any, any>> = createSlice({\n  name: 'ammMap',\n  initialState,\n  reducers: {\n    initAmmMap(\n      state,\n      action: PayloadAction<{\n        ammpools: LoopringMap<AmmPoolInfoV3>\n        // ammpoolsRaw?: any;\n        chainId: ChainId\n      }>,\n    ) {\n      const ammpools = action.payload.ammpools\n      const ammMap = Reflect.ownKeys(ammpools).reduce((prev, key) => {\n        let status: any = ammpools[key.toString()].status ?? 0\n        status = ('00000' + status.toString(2)).split('')\n        let exitDisable = status[status.length - 1] === '0'\n        let joinDisable = status[status.length - 2] === '0'\n        let swapDisable = status[status.length - 3] === '0'\n        let showDisable = status[status.length - 4] === '0'\n        let isRiskyMarket = status[status.length - 5] === '1'\n        return {\n          ...prev,\n          [key]: {\n            ...ammpools[key as string],\n            exitDisable,\n            joinDisable,\n            swapDisable,\n            showDisable,\n            isRiskyMarket,\n            __rawConfig__: ammpools[key as string],\n            market: key.toString().replace('AMM-', ''),\n          },\n        }\n      }, {})\n      state.ammMap = ammMap\n    },\n    getAmmMap(\n      state,\n      _action: PayloadAction<GetAmmMapParams & { ammpoolsRaw?: any; chainId?: ChainId }>,\n    ) {\n      state.status = SagaStatus.PENDING\n    },\n    getAmmMapStatus(state, action: PayloadAction<AmmMapStates<any, any>>) {\n      // @ts-ignore\n      if (action.error) {\n        state.status = SagaStatus.ERROR\n        // @ts-ignore\n        state.errorMessage = action.error\n      } else {\n        const { ammMap, ammArrayEnable, __timer__ } = action.payload\n        if (ammMap) {\n          // myLog(ammMap[\"AMM-LRC-USDT\"].tokens, \"ammMap\");\n          state.ammMap = ammMap\n        }\n        if (ammArrayEnable) {\n          state.ammArrayEnable = ammArrayEnable\n        }\n        if (__timer__) {\n          state.__timer__ = __timer__\n        }\n        state.status = SagaStatus.DONE\n      }\n    },\n    updateRealTimeAmmMap(\n      state,\n      _action: PayloadAction<{ ammPoolStats?: LoopringMap<AmmPoolStat> }>,\n    ) {\n      state.status = SagaStatus.PENDING\n    },\n    statusUnset: (state) => {\n      state.status = SagaStatus.UNSET\n    },\n  },\n})\nexport { ammMapSlice }\nexport const { getAmmMap, initAmmMap, getAmmMapStatus, statusUnset, updateRealTimeAmmMap } =\n  ammMapSlice.actions\n"
  },
  {
    "path": "packages/core/src/stores/Amm/AmmMap/saga.ts",
    "content": "import { all, call, fork, put, takeLatest } from 'redux-saga/effects'\nimport { getAmmMap, getAmmMapStatus, updateRealTimeAmmMap } from './reducer'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { AmmPoolInfoV3, AmmPoolStat, ChainId, toBig } from '@loopring-web/loopring-sdk'\n\nimport {\n  AmmDetail,\n  getValuePrecisionThousand,\n  LocalStorageConfigKey,\n  myLog,\n} from '@loopring-web/common-resources'\nimport { store } from '../../index'\nimport { LoopringAPI } from '../../../api_wrapper'\nimport { PayloadAction } from '@reduxjs/toolkit'\nimport { AmmDetailStore, GetAmmMapParams } from './interface'\nimport { volumeToCount, volumeToCountAsBigNumber } from '../../../hooks'\nimport _ from 'lodash'\n\nconst ammMapStoreLocal = (ammpoolsRaw: any, chainId?: any) => {\n  // const system = store.getState().system;\n  myLog('system', chainId)\n  const ammpoolsChain = JSON.parse(\n    window.localStorage.getItem(LocalStorageConfigKey.ammpools) ?? '{}',\n  )\n  localStorage.setItem(\n    'ammpools',\n    JSON.stringify({\n      ...ammpoolsChain,\n      [chainId ?? 1]: ammpoolsRaw,\n    }),\n  )\n}\n\ntype AmmMap<R extends { [key: string]: any }> = { [key: string]: AmmDetail<R> } | {} //key is AMM-XXX-XXX\nexport const setAmmState = ({\n  ammPoolState,\n  market,\n}: {\n  ammPoolState: AmmPoolStat & { apysBips?: string[] }\n  market: string\n}) => {\n  const { idIndex, tokenMap } = store.getState().tokenMap\n  const { chainId } = store.getState().system\n  const { tokenPrices } = store.getState().tokenPrices\n  const { tickerMap } = store.getState().tickerMap\n  // @ts-ignore\n  const [, coinA, coinB] = market.match(/(\\w+)-(\\w+)/i)\n  if (idIndex && coinA && coinB && tokenPrices) {\n    if (chainId === 5 && market == 'CLRC-USDT') {\n      ammPoolState.liquidity = ['0', '0']\n      ammPoolState.lpLiquidity = '0'\n    }\n    const totalA = volumeToCountAsBigNumber(coinA, ammPoolState.liquidity[0]) //parseInt(ammPoolState.liquidity[ 0 ]),\n    const totalB = volumeToCountAsBigNumber(coinB, ammPoolState.liquidity[1]) //parseInt(ammPoolState.liquidity[ 1 ]),\n    const totalAU = totalA?.times(tokenPrices[coinA]) ?? sdk.toBig(0)\n    const totalBU = totalB?.times(tokenPrices[coinB]) ?? sdk.toBig(0)\n    const rewardA = ammPoolState.rewards[0]\n      ? volumeToCountAsBigNumber(\n          idIndex[ammPoolState.rewards[0].tokenId as number],\n          ammPoolState.rewards[0].volume,\n        )\n      : undefined\n    const rewardB = ammPoolState.rewards[1]\n      ? volumeToCountAsBigNumber(\n          idIndex[ammPoolState.rewards[1].tokenId as number],\n          ammPoolState.rewards[1].volume,\n        )\n      : undefined\n    let result = {\n      totalA: totalA?.toString() ?? 0,\n      totalB: totalB?.toString() ?? 0,\n      totalAU: totalAU.toString(),\n      totalBU: totalBU.toString(),\n      amountU: totalAU.plus(totalBU).toString(),\n      totalLPToken: volumeToCount('LP-' + market, ammPoolState.lpLiquidity),\n      rewardA: rewardA?.toString(),\n      rewardToken: ammPoolState.rewards[0]\n        ? idIndex[ammPoolState.rewards[0].tokenId as number]\n        : undefined,\n      rewardAU: rewardA?.times(tokenPrices[coinA]).toString(),\n      rewardBU: rewardB?.times(tokenPrices[coinB]).toString(),\n      rewardB: rewardB?.toString(),\n      rewardToken2: ammPoolState.rewards[1]\n        ? idIndex[ammPoolState.rewards[1].tokenId as number]\n        : undefined,\n      tokens: {\n        pooled: ammPoolState.liquidity,\n        lp: ammPoolState.lpLiquidity,\n      },\n    }\n    const feeA = volumeToCountAsBigNumber(coinA, ammPoolState.fees[0])\n    const feeB = volumeToCountAsBigNumber(coinB, ammPoolState.fees[1])\n    const feeU =\n      tokenPrices[coinA] && tokenPrices[coinB]\n        ? toBig(feeA ?? 0)\n            .times(tokenPrices[coinA])\n            .plus(toBig(feeB ?? 0).times(tokenPrices[coinB]))\n        : undefined\n    const APRs = {\n      self: (parseInt(ammPoolState?.apysBips ? ammPoolState.apysBips[0] : '0') * 1.0) / 100,\n      event: (parseInt(ammPoolState?.apysBips ? ammPoolState?.apysBips[1] : '0') * 1.0) / 100,\n      fee: (parseInt(ammPoolState?.apysBips ? ammPoolState?.apysBips[2] : '0') * 1.0) / 100,\n    }\n\n    return {\n      ...result,\n      feeA: feeA?.toNumber(),\n      feeB: feeB?.toNumber(),\n      feeU: feeU ? feeU.toNumber() : undefined,\n      totalAStr: getValuePrecisionThousand(\n        result.totalA,\n        tokenMap[coinA].precision,\n        tokenMap[coinA].precision,\n        tokenMap[coinA].precision,\n        false,\n        { isFait: true },\n      ),\n      totalBStr: getValuePrecisionThousand(\n        result.totalB,\n        tokenMap[coinA].precision,\n        tokenMap[coinA].precision,\n        tokenMap[coinA].precision,\n        false,\n        { isFait: true },\n      ),\n      tradeFloat: {\n        change: undefined,\n        timeUnit: '24h',\n        ...(tickerMap[market] ? tickerMap[market] : {}),\n      },\n      // @ts-ignore\n      APR: ammPoolState?.apysBips\n        ? APRs.self + APRs.event + APRs.fee\n        : (parseInt(ammPoolState.apyBips) * 1.0) / 100,\n      APRs,\n      __ammPoolState__: ammPoolState,\n    }\n  }\n}\nconst getAmmMapApi = async <R extends { [key: string]: any }>({ ammpools }: GetAmmMapParams) => {\n  if (!LoopringAPI.ammpoolAPI) {\n    return undefined\n  }\n  let ammMap: AmmMap<R> = {} //\n  let ammArrayEnable: AmmDetailStore<R>[] = []\n  const { chainId } = store.getState().system\n  const { ammMap: _ammMap } = store.getState().amm.ammMap\n  myLog('loop get ammPoolStats')\n\n  const { idIndex, coinMap } = store.getState().tokenMap\n  let ammPoolStats: any = {}\n  try {\n    ammPoolStats = (await LoopringAPI.ammpoolAPI?.getAmmPoolStats())?.ammPoolStats ?? {}\n  } catch (e) {\n    // throw e;\n  }\n  Reflect.ownKeys(ammpools).forEach(async (key) => {\n    let item: AmmPoolInfoV3 = ammpools[key as string]\n    if (chainId === 5 && key == 'AMM-CLRC-USDT') {\n      item = {\n        ...ammpools[key as string],\n        tokens: {\n          pooled: ['0', '0'],\n          lp: '0' as any,\n        },\n      }\n    }\n    if (item.market === key && item.tokens.pooled && idIndex) {\n      const coinA = idIndex[item.tokens.pooled[0] as any]\n      const coinB = idIndex[item.tokens.pooled[1] as any]\n      let status: any = ammpools[key.toString()].status ?? 0\n      status = ('00000' + status.toString(2)).split('')\n      let exitDisable = status[status.length - 1] === '0'\n      let joinDisable = status[status.length - 2] === '0'\n      let swapDisable = status[status.length - 3] === '0'\n      let showDisable = status[status.length - 4] === '0'\n      let isRiskyMarket = status[status.length - 5] === '1'\n      const dataItem: AmmDetailStore<R> = {\n        ...item,\n        coinA: coinA,\n        coinB: coinB,\n        coinAInfo: coinMap[coinA],\n        coinBInfo: coinMap[coinB],\n        isNew: Date.now() - Number(item.createdAt) > 3 * 86400 * 1000 ? false : true, //3*24*60*60*1000,\n        isActivity: item.status === 7 ? true : false,\n        ...(ammPoolStats[key]\n          ? setAmmState({\n              ammPoolState: ammPoolStats[key],\n              market: item.market.replace('AMM-', ''),\n            })\n          : { ..._ammMap[key] }),\n        exitDisable,\n        joinDisable,\n        swapDisable,\n        showDisable,\n        isRiskyMarket,\n        __rawConfig__: item,\n        market: key.replace('AMM-', ''),\n      } as AmmDetailStore<R>\n      // @ts-ignore\n      ammMap[key] = dataItem\n      if (!dataItem.showDisable) {\n        // @ts-ignore\n        ammArrayEnable.push(dataItem)\n      }\n    }\n  })\n\n  let { __timer__ } = store.getState().amm.ammMap\n  // @ts-ignore\n  __timer__ = ((ammpools) => {\n    if (__timer__ && __timer__ !== -1) {\n      clearInterval(__timer__)\n    }\n    return setInterval(() => {\n      store.dispatch(getAmmMap({ ammpools }))\n    }, 900000) //15*60*1000 //900000\n  })(ammpools)\n\n  return { ammMap, ammArrayEnable, __timer__ }\n}\n\nexport function* getPostsSaga({\n  payload,\n}: PayloadAction<GetAmmMapParams & { ammpoolsRaw?: any; chainId?: ChainId }>) {\n  try {\n    const { ammpools } = payload\n    if (payload?.ammpoolsRaw && payload.chainId) {\n      ammMapStoreLocal(payload?.ammpoolsRaw, payload.chainId)\n    }\n    const { ammMap, ammArrayEnable, __timer__ } = yield call(getAmmMapApi, {\n      ammpools,\n    })\n    // const { readyState } = store.getState().account;\n    // if (readyState === AccountStatus.ACTIVATED) {\n    //   store.dispatch(getUserAMM(undefined));\n    // }\n    yield put(getAmmMapStatus({ ammMap, ammArrayEnable, __timer__ }))\n  } catch (err) {\n    yield put(getAmmMapStatus({ error: err }))\n  }\n}\n\nexport function* updateRealTimeSaga({ payload }: any) {\n  try {\n    const { ammPoolStats } = payload\n    let { ammMap: _ammMap, ammArrayEnable: _ammArrayEnable } = store.getState().amm.ammMap\n    let ammMap\n    let ammArrayEnable = _.cloneDeep(_ammArrayEnable)\n    if (ammPoolStats) {\n      ammMap = Reflect.ownKeys(ammPoolStats).reduce((_ammMap, key) => {\n        const market = (key as string).replace('AMM-', '')\n        const ammMarket = 'AMM-' + market\n        // myLog(\"ammPoolStats[ammMarket]\", ammPoolStats[ammMarket]);\n        const result = setAmmState({\n          ammPoolState: {\n            ..._ammMap[ammMarket]?.__ammPoolState__,\n            ...ammPoolStats[ammMarket],\n          },\n          market,\n        })\n        // @ts-ignore\n        _ammMap[ammMarket] = {\n          ..._ammMap[ammMarket],\n          ...result,\n          market,\n        }\n        if (!_ammMap[ammMarket].showDisable) {\n          const index = ammArrayEnable.findIndex(\n            (item) => _ammMap[ammMarket].market === item.market,\n          )\n          if (index != -1) {\n            ammArrayEnable[index] = _ammMap[ammMarket]\n          }\n        }\n        return _ammMap\n      }, _.cloneDeep(_ammMap))\n    }\n    yield put(getAmmMapStatus({ ammMap, ammArrayEnable }))\n  } catch (err) {\n    yield put(getAmmMapStatus({ error: err }))\n  }\n}\n\nexport function* ammMapInitSaga() {\n  // @ts-ignore\n  yield all([takeLatest(getAmmMap, getPostsSaga)])\n}\n\nexport function* ammMapRealTimeSaga() {\n  yield all([takeLatest(updateRealTimeAmmMap, updateRealTimeSaga)])\n}\n\nexport const ammMapSaga = [fork(ammMapInitSaga), fork(ammMapRealTimeSaga)]\n"
  },
  {
    "path": "packages/core/src/stores/Amm/index.ts",
    "content": "import { combineReducers } from '@reduxjs/toolkit'\n\nimport { ammMapSlice } from './AmmMap/reducer'\nimport { ammActivityMapSlice } from './AmmActivityMap/reducer'\nimport ammActivityMapSaga from './AmmActivityMap/saga'\nimport { ammMapSaga } from './AmmMap/saga'\nimport { fork } from 'redux-saga/effects'\n\nexport const ammReducer = combineReducers({\n  ammMap: ammMapSlice.reducer,\n  ammActivityMap: ammActivityMapSlice.reducer,\n})\nexport const ammForks = [\n  fork(ammActivityMapSaga),\n  ...ammMapSaga,\n  // fork(ammRecordSaga),\n  // fork(ammTradesSaga)\n]\n\nexport * from './AmmMap/interface'\nexport * from './AmmActivityMap/interface'\nexport * from './AmmMap/hook'\nexport * from './AmmActivityMap/hook'\nexport * as ammMapReducer from './AmmMap/reducer'\nexport * as ammActivityMapReducer from './AmmActivityMap/reducer'\n"
  },
  {
    "path": "packages/core/src/stores/account/hook.ts",
    "content": "import { useDispatch, useSelector } from 'react-redux'\nimport { changeShowModel, cleanAccountStatus, statusUnset, updateAccountStatus } from './reducer'\nimport React from 'react'\nimport { Account, AccountState, getShortAddr } from '@loopring-web/common-resources'\nimport { RootState } from '../index'\n\nexport function useAccount() {\n  const { status, errorMessage, ...account }: AccountState = useSelector(\n    (state: RootState) => state.account,\n  )\n  // const [shouldShow,setShouldShow] = React.useState(account._userOnModel)\n  const dispatch = useDispatch()\n\n  const resetAccount = React.useCallback(\n    (props?: { shouldUpdateProvider?: boolean | undefined }) => {\n      dispatch(cleanAccountStatus(props))\n    },\n    [dispatch],\n  )\n\n  const updateAccount = React.useCallback(\n    (account: Partial<Account>) => {\n      dispatch(updateAccountStatus(account))\n    },\n    [dispatch],\n  )\n\n  const shouldShow = React.useMemo(() => {\n    return account._userOnModel\n  }, [account])\n\n  const setShouldShow = React.useCallback(\n    (flag: boolean) => {\n      dispatch(changeShowModel({ _userOnModel: flag }))\n    },\n    [dispatch],\n  )\n\n  const addressShort = getShortAddr(account.accAddress)\n\n  return {\n    account,\n    addressShort,\n    resetAccount,\n    shouldShow,\n    setShouldShow,\n    updateAccount,\n    statusUnset: React.useCallback(() => {\n      dispatch(statusUnset(undefined))\n    }, [dispatch]),\n    status,\n    errorMessage,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/account/index.ts",
    "content": "export * from './hook'\nexport * as accountReducer from './reducer'\n\n// export * from './method'\n"
  },
  {
    "path": "packages/core/src/stores/account/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { SliceCaseReducers } from '@reduxjs/toolkit/src/createSlice'\nimport { Account, AccountState, AccountStatus, SagaStatus } from '@loopring-web/common-resources'\nimport { ConnectProviders } from '@loopring-web/web3-provider'\n\nconst initialState: AccountState = {\n  accAddress: '',\n  qrCodeUrl: '',\n  readyState: AccountStatus.UN_CONNECT,\n  accountId: -1,\n  apiKey: '',\n  eddsaKey: '',\n  publicKey: {},\n  level: '',\n  keySeed: '',\n  nonce: undefined,\n  keyNonce: undefined,\n  connectName: ConnectProviders.Unknown,\n  _chainId: 1,\n  status: SagaStatus.PENDING,\n  errorMessage: null,\n  frozen: false,\n  __timer__: -1,\n  hasUnknownCollection: undefined,\n}\n\nconst accountSlice: Slice<AccountState> = createSlice<\n  AccountState,\n  SliceCaseReducers<AccountState>\n>({\n  name: 'account',\n  initialState: initialState,\n  reducers: {\n    updateAccountStatus(state) {\n      state.status = SagaStatus.PENDING\n    },\n    nextAccountSyncStatus(state) {\n      state.status = SagaStatus.PENDING\n    },\n    changeShowModel(state, action: PayloadAction<{ _userOnModel: boolean | undefined }>) {\n      const { _userOnModel } = action.payload\n      state._userOnModel = _userOnModel\n    },\n\n    nextAccountStatus(state, action: PayloadAction<Partial<Account>>) {\n      // @ts-ignore\n      if (action.error) {\n        state.status = SagaStatus.ERROR\n        // @ts-ignore\n        state.errorMessage = action.error\n      } else {\n        const {\n          accAddress,\n          qrCodeUrl,\n          readyState,\n          accountId,\n          wrongChain,\n          level,\n          apiKey,\n          eddsaKey,\n          _chainId,\n          keySeed,\n          nonce,\n          frozen,\n          _accountIdNotActive,\n          connectName,\n          isInCounterFactualStatus,\n          isContract1XAddress,\n          isContractAddress,\n          isCFAddress,\n          isContract,\n          __timer__,\n          // hasUnknownCollection,\n        } = action.payload\n        if (_accountIdNotActive) {\n          state._accountIdNotActive = _accountIdNotActive\n        }\n        if (accAddress !== undefined) {\n          state.accAddress = accAddress\n        }\n\n        if (qrCodeUrl !== undefined) {\n          state.qrCodeUrl = qrCodeUrl\n        }\n\n        if (wrongChain !== undefined) {\n          state.wrongChain = wrongChain\n        }\n        if (readyState) {\n          state.readyState = readyState\n        }\n        if (accountId !== undefined) {\n          state.accountId = accountId\n        }\n        if (level !== undefined) {\n          state.level = level\n        }\n        if (apiKey !== undefined) {\n          state.apiKey = apiKey\n        }\n        if (eddsaKey !== undefined) {\n          state.eddsaKey = eddsaKey\n        }\n        if (connectName !== undefined) {\n          state.connectName = connectName\n        }\n        if (_chainId !== undefined) {\n          state._chainId = _chainId\n        }\n        if (nonce !== undefined) {\n          state.nonce = nonce\n        }\n        if (keySeed !== undefined) {\n          state.keySeed = keySeed\n        }\n        if (__timer__ !== undefined) {\n          state.__timer__ = __timer__\n        }\n        if (action.payload.hasOwnProperty('hasUnknownCollection')) {\n          state.hasUnknownCollection = action.payload.hasUnknownCollection\n        }\n        state.isInCounterFactualStatus = isInCounterFactualStatus\n        state.isContract1XAddress = isContract1XAddress\n        state.isContractAddress = isContractAddress\n        state.isCFAddress = isCFAddress\n        state.isContract = isContract\n        state.frozen = frozen\n        state.status = SagaStatus.DONE\n      }\n    },\n    cleanAccountStatus(\n      state,\n      _action: PayloadAction<{ shouldUpdateProvider?: boolean | undefined }>,\n    ) {\n      state.status = SagaStatus.PENDING\n    },\n    statusUnset: (state) => {\n      state.status = SagaStatus.UNSET\n    },\n  },\n})\nexport default accountSlice\nexport const {\n  updateAccountStatus,\n  changeShowModel,\n  cleanAccountStatus,\n  nextAccountStatus,\n  statusUnset,\n  nextAccountSyncStatus,\n} = accountSlice.actions\n"
  },
  {
    "path": "packages/core/src/stores/account/saga.ts",
    "content": "import { all, call, fork, put, takeLatest } from 'redux-saga/effects'\nimport {\n  cleanAccountStatus,\n  nextAccountStatus,\n  nextAccountSyncStatus,\n  statusUnset,\n  updateAccountStatus,\n} from './reducer'\nimport { PayloadAction } from '@reduxjs/toolkit'\nimport { Account, AccountStatus, MapChainId, myLog } from '@loopring-web/common-resources'\nimport { ConnectProviders, connectProvides } from '@loopring-web/web3-provider'\nimport { AccountInfo, NetworkWallet, WalletType } from '@loopring-web/loopring-sdk'\nimport { store } from '../index'\nimport { LoopringAPI } from '../../api_wrapper'\nimport { toggleCheck } from '../../services'\n\nconst LoopFrozenFlag = true\nconst getAccount = async (): Promise<{\n  account: AccountInfo\n  walletType: WalletType\n  __timer__: NodeJS.Timer | -1\n}> => {\n  let { accAddress, __timer__, frozen } = store.getState().account\n  let { defaultNetwork } = store.getState().settings\n  if (frozen === LoopFrozenFlag) {\n    __timer__ = ((__timer__) => {\n      if (__timer__ && __timer__ !== -1) {\n        clearTimeout(__timer__ as any)\n      }\n      return setTimeout(() => {\n        store.dispatch(updateAccountStatus({ frozen: account.frozen }))\n      }, 1000 * 60)\n    })(__timer__)\n  }\n  const [{ accInfo: account }, { walletType }] = await Promise.all([\n    LoopringAPI?.exchangeAPI?.getAccount({\n      owner: accAddress,\n    }) ?? Promise.resolve({ accInfo: {} } as any),\n    LoopringAPI?.walletAPI?.getWalletType({\n      wallet: accAddress, //realAddr != \"\" ? realAddr : address,\n      network: MapChainId[defaultNetwork] as NetworkWallet\n    }) ?? Promise.resolve({ walletType: {} } as any),\n  ])\n\n  if (__timer__ && __timer__ !== -1) {\n    clearTimeout(__timer__ as any)\n  }\n  return {\n    account: {\n      ...account,\n      isContractAddress: walletType?.loopringWalletContractVersion ? true : false,\n      isCFAddress: walletType?.isInCounterFactualStatus ? true : false\n    },\n    walletType: {\n      ...walletType,\n      isContract1XAddress: walletType?.loopringWalletContractVersion?.startsWith('V1_') ?? false,\n    },\n    __timer__: __timer__ ?? -1,\n  }\n}\n\nexport function* accountUpdateSaga({ payload }: PayloadAction<Partial<Account>>) {\n  try {\n    let data = { account: {}, walletType: {}, __timer__: -1 }\n    data = yield call(getAccount)\n    yield put(\n      nextAccountStatus({\n        ...payload,\n        ...data.account,\n        ...data.walletType,\n        __timer__: data.__timer__,\n      }),\n    )\n    toggleCheck()\n  } catch (err) {\n    yield put(nextAccountStatus({ error: err }))\n  }\n}\n\nexport function* cleanAccountSaga({\n  payload,\n}: PayloadAction<{ shouldUpdateProvider?: boolean | undefined }>) {\n  try {\n    let account: Partial<Account> = {\n      accAddress: '',\n      readyState: AccountStatus.UN_CONNECT,\n      accountId: -1,\n      apiKey: '',\n      eddsaKey: '',\n      publicKey: {},\n      level: '',\n      nonce: -1,\n      keyNonce: -1,\n      keySeed: '',\n      _accountIdNotActive: -1,\n      isInCounterFactualStatus: undefined,\n      isContract: undefined,\n      isContract1XAddress: undefined,\n    }\n\n    if (payload && payload.shouldUpdateProvider) {\n      yield call(async () => await connectProvides.clear())\n      account = {\n        ...account,\n        connectName: ConnectProviders.Unknown,\n      }\n    }\n    yield put(\n      nextAccountStatus({\n        ...account,\n      }),\n    )\n  } catch (err) {\n    yield put(nextAccountStatus({ error: err }))\n  }\n}\n\nexport function* accountUpdateSyncSaga(action: PayloadAction<Account>) {\n  try {\n    myLog('accountUpdateSyncSaga', action.payload, action)\n    yield put(\n      nextAccountStatus({\n        ...action?.payload,\n      }),\n    )\n    yield put(statusUnset({}))\n  } catch (err) {\n    yield put(nextAccountStatus({ error: err }))\n  }\n}\n\nfunction* accountSage() {\n  // @ts-ignore\n  yield all([takeLatest(updateAccountStatus, accountUpdateSaga)])\n}\nfunction* accountSyncSage() {\n  // @ts-ignore\n  yield all([takeLatest(nextAccountSyncStatus, accountUpdateSyncSaga)])\n}\n\nfunction* accountRestSage() {\n  // @ts-ignore\n  yield all([takeLatest(cleanAccountStatus, cleanAccountSaga)])\n}\n\nexport const accountFork = [fork(accountSage), fork(accountRestSage), fork(accountSyncSage)]\n"
  },
  {
    "path": "packages/core/src/stores/amount/hook.ts",
    "content": "import { useDispatch, useSelector } from 'react-redux'\nimport { getAmount, resetAmount, statusUnset } from './reducer'\nimport { AmountStates } from './interface'\nimport React from 'react'\n\nexport function useAmount(): AmountStates & {\n  getAmount: ({ market }: { market: string }) => void\n  statusUnset: () => void\n  resetAmount: () => void\n} {\n  const amountMap: AmountStates = useSelector((state: any) => state.amountMap)\n  const dispatch = useDispatch()\n  return {\n    ...amountMap,\n    resetAmount: React.useCallback(() => dispatch(resetAmount(undefined)), [dispatch]),\n    statusUnset: React.useCallback(() => dispatch(statusUnset(undefined)), [dispatch]),\n    getAmount: React.useCallback(({ market }) => dispatch(getAmount({ market })), [dispatch]),\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/amount/index.ts",
    "content": "export * from './hook'\nexport * from './interface'\nexport * as amountReducer from './reducer'\n"
  },
  {
    "path": "packages/core/src/stores/amount/interface.ts",
    "content": "import { StateBase } from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\n//key is market or AMM-${market}\nexport type Amount = {\n  [key: string]: sdk.LoopringMap<sdk.TokenAmount>\n}\nexport type TimerMap = { [key: string]: NodeJS.Timeout | -1 }\n/**\n * @amountMap is only update weh\n */\nexport type AmountStates = {\n  amountMap?: Amount | undefined\n  __timerMap__?: TimerMap\n} & StateBase\n"
  },
  {
    "path": "packages/core/src/stores/amount/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { AmountStates } from './interface'\nimport { SagaStatus } from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nconst initialState: AmountStates = {\n  amountMap: undefined,\n  __timerMap__: undefined,\n  status: SagaStatus.PENDING,\n  errorMessage: null,\n}\nexport type AmountMap = sdk.LoopringMap<sdk.TokenAmount>\n\nconst amountMapSlice: Slice<AmountStates> = createSlice({\n  name: 'amountMap',\n  initialState,\n  reducers: {\n    getAmount(state, _action: PayloadAction<{ market: string }>) {\n      state.status = SagaStatus.PENDING\n    },\n    resetAmount(state, _action: PayloadAction<undefined>) {\n      state.status = SagaStatus.PENDING\n    },\n    getAmountStatus(state, action: PayloadAction<AmountStates>) {\n      // @ts-ignore\n      if (action.error) {\n        state.status = SagaStatus.ERROR\n        // @ts-ignore\n        state.errorMessage = action.error\n      }\n      state.amountMap = action.payload.amountMap //{...state.amountMap, ...action.payload.amountMap};\n      state.__timerMap__ = action.payload.__timerMap__ //{...state.__timerMap__, ...action.payload.__timerMap__};\n      state.status = SagaStatus.DONE\n    },\n\n    statusUnset: (state) => {\n      state.status = SagaStatus.UNSET\n    },\n  },\n})\nexport { amountMapSlice }\nexport const { getAmount, resetAmount, getAmountStatus, statusUnset } = amountMapSlice.actions\n"
  },
  {
    "path": "packages/core/src/stores/amount/saga.ts",
    "content": "import { all, call, fork, put, takeLatest } from 'redux-saga/effects'\nimport { getAmount, getAmountStatus, resetAmount } from './reducer'\n\nimport { store } from '../index'\nimport { LoopringAPI } from '../../api_wrapper'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { myLog } from '@loopring-web/common-resources'\n\nconst getAmountApi = async <_R extends { [key: string]: any }>(\n  market: string,\n): Promise<{\n  newAmountMap: object | undefined\n  __timer__: NodeJS.Timer | -1\n}> => {\n  const { accountId, apiKey } = store.getState().account\n  let { __timerMap__ } = store.getState().amountMap\n  let __timer__ = __timerMap__ && __timerMap__[market] ? __timerMap__[market] : -1\n\n  if (LoopringAPI.userAPI && accountId && apiKey) {\n    if (__timer__ && __timer__ !== -1) {\n      clearInterval(__timer__)\n    }\n    __timer__ = setInterval(async () => {\n      store.dispatch(getAmount(market))\n    }, 1000 * 15 * 60) //   //\n\n    const req: sdk.GetMinimumTokenAmtRequest = {\n      accountId: accountId,\n      market: market,\n    }\n    myLog('loop get getMinimumTokenAmt')\n\n    const { amountMap: _pairMap } = await LoopringAPI.userAPI.getMinimumTokenAmt(req, apiKey)\n    const reqAmm: sdk.GetMinimumTokenAmtRequest = {\n      accountId: accountId,\n      market: 'AMM-' + market,\n    }\n    const { amountMap: _pairMapAmm } = await LoopringAPI.userAPI.getMinimumTokenAmt(reqAmm, apiKey)\n    return {\n      newAmountMap: { [market]: _pairMap, ['AMM-' + market]: _pairMapAmm },\n      __timer__,\n    }\n  } else {\n    if (__timer__ && __timer__ !== -1) {\n      clearInterval(__timer__)\n    }\n    return Promise.resolve({ newAmountMap: {}, __timer__: -1 })\n  }\n}\n\nexport function* getPostsSaga({ payload: { market } }: any) {\n  try {\n    const { amountMap, __timerMap__ } = store.getState().amountMap\n    if (market) {\n      const { newAmountMap, __timer__ } = yield call(getAmountApi, market)\n      yield put(\n        getAmountStatus({\n          amountMap: { ...amountMap, ...newAmountMap },\n          __timerMap__: { ...__timerMap__, [market]: __timer__ },\n        }),\n      )\n    } else {\n      yield put(getAmountStatus({ amountMap, __timerMap__ }))\n    }\n  } catch (err) {\n    yield put(getAmountStatus({ error: err }))\n  }\n}\n\nexport function* getResetsSaga() {\n  try {\n    let { __timerMap__ } = store.getState().amountMap\n    if (__timerMap__) {\n      Reflect.ownKeys(__timerMap__).map((market) => {\n        let __timer__ = __timerMap__ && __timerMap__[market as string]\n        if (__timer__ && __timer__ !== -1) {\n          clearInterval(__timer__)\n        }\n      })\n    }\n\n    yield put(getAmountStatus({ amountMap: undefined, __timerMap__: undefined }))\n  } catch (err) {\n    yield put(getAmountStatus({ error: err }))\n  }\n}\n\nfunction* amountSaga() {\n  yield all([takeLatest(getAmount, getPostsSaga)])\n}\n\nfunction* restAmountSaga() {\n  yield all([takeLatest(resetAmount, getResetsSaga)])\n}\n\nexport const amountForks = [\n  fork(amountSaga),\n  fork(restAmountSaga),\n  // fork(amountsSaga),\n]\n"
  },
  {
    "path": "packages/core/src/stores/config/hook.ts",
    "content": "import { useSelector } from 'react-redux'\nimport { Config } from './interface'\nimport { RootState } from '../index'\n\nexport const useConfig = (): Config => {\n  const contacts: Config = useSelector((state: RootState) => state.config)\n  return {\n    ...contacts\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/config/index.ts",
    "content": "export type { Config, FastWithdrawConfig } from './interface'\nexport * as configReducer from './reducer'\nexport {useConfig} from './hook'\n"
  },
  {
    "path": "packages/core/src/stores/config/interface.ts",
    "content": "import { ForexMap, StateBase } from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\n\nexport type FastWithdrawConfig = {\n  fromToNetworks: {\n    [key in string]: Array<string>\n  },\n  networkExchanges: {\n    [key in string]: string\n  },\n  networkProtocols: {\n    [key in string]: string\n  },\n  networkL1Tokens: {\n    [key in string]: {\n      [key in string]: string\n    }\n  },\n  networkL2TokenIds: {\n    [key in string]: Array<number>\n  },\n  networkL2AgentAddresses: {\n    [key in string]: string\n  },\n  networkL2AgentAccountIds: {\n    [key in string]: number\n  }\n}\n\nexport type Config = {\n  fastWithdrawConfig: FastWithdrawConfig | undefined\n}\n"
  },
  {
    "path": "packages/core/src/stores/config/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { Config, FastWithdrawConfig } from './interface'\n\nconst initialState: Config = {\n  fastWithdrawConfig: undefined\n}\nexport const configSlice: Slice<Config> = createSlice({\n  name: 'system',\n  initialState,\n  reducers: {\n    updateFastWithdrawConfig(state, action: PayloadAction<FastWithdrawConfig>) {\n      state.fastWithdrawConfig = action.payload\n    },\n  },\n})\nexport default configSlice\nexport const { updateFastWithdrawConfig } = configSlice.actions\n"
  },
  {
    "path": "packages/core/src/stores/contacts/hooks.ts",
    "content": "import { updateContacts, reset, statusUnset } from './reducer'\nimport { useDispatch, useSelector } from 'react-redux'\nimport React from 'react'\nimport { ContactsState } from './interface'\nimport { RootState } from '../index'\n\nexport const useContacts = (): ContactsState & {\n  updateContacts: () => void\n  reset: () => void\n  statusUnset: () => void\n} => {\n  const contacts: ContactsState = useSelector((state: RootState) => state.contacts)\n  const dispatch = useDispatch()\n  return {\n    ...contacts,\n    statusUnset: React.useCallback(() => dispatch(statusUnset(undefined)), [dispatch]),\n    updateContacts: React.useCallback(() => dispatch(updateContacts({})), [dispatch]),\n    reset: React.useCallback(() => dispatch(reset({})), [dispatch]),\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/contacts/index.ts",
    "content": "export * as contactsReducer from './reducer'\nexport * from './hooks'\nexport * from './interface'\nexport * from './saga'\n\n// export * from './method'\n"
  },
  {
    "path": "packages/core/src/stores/contacts/interface.ts",
    "content": "import { StateBase } from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nexport type ContactsState = Pick<sdk.GetContactsResponse, 'contacts'> & {\n  __timer__: NodeJS.Timeout | -1\n} & StateBase\n"
  },
  {
    "path": "packages/core/src/stores/contacts/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice, SliceCaseReducers } from '@reduxjs/toolkit'\nimport { SagaStatus } from '@loopring-web/common-resources'\nimport { ContactsState } from './interface'\n\nconst initialState: ContactsState = {\n  contacts: [],\n  status: SagaStatus.PENDING,\n  __timer__: -1,\n}\n\nexport const contactsSlice: Slice<ContactsState> = createSlice<\n  ContactsState,\n  SliceCaseReducers<ContactsState>\n>({\n  name: 'contacts',\n  initialState: initialState,\n  reducers: {\n    updateContacts(state) {\n      state.status = SagaStatus.PENDING\n    },\n    reset(state) {\n      state = {\n        ...initialState,\n      }\n      state.status = SagaStatus.UNSET\n    },\n    getContactsStatus(state, action: PayloadAction<ContactsState>) {\n      if ((action.payload as any).error) {\n        state.status = SagaStatus.ERROR\n        state.errorMessage = (action.payload as any).error\n        state.contacts = []\n        return\n      }\n      state.errorMessage = null\n      state.contacts = action.payload.contacts\n      if (action.payload.__timer__) {\n        state.__timer__ = action.payload.__timer__\n      }\n      state.status = SagaStatus.DONE\n    },\n    statusUnset: (state) => {\n      state.status = SagaStatus.UNSET\n    },\n  },\n})\nexport default contactsSlice\nexport const { updateContacts, getContactsStatus, statusUnset, reset } = contactsSlice.actions\n"
  },
  {
    "path": "packages/core/src/stores/contacts/saga.ts",
    "content": "import { all, call, fork, put, takeLatest } from 'redux-saga/effects'\nimport { updateContacts, getContactsStatus } from './reducer'\n\nimport { LoopringAPI, store } from '../../index'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { NetworkMap } from '@loopring-web/common-resources'\n\nconst getContractsApi = async ({ limit = 100 }: { limit?: number }) => {\n  const { isContractAddress, isCFAddress, accountId, apiKey } = store.getState().account\n  const { defaultNetwork } = store.getState().settings\n  let contacts: any[] = []\n  if (apiKey && LoopringAPI.contactAPI && accountId) {\n    const response = await LoopringAPI.contactAPI?.getContacts(\n      {\n        isHebao: !!(isContractAddress || isCFAddress),\n        accountId,\n        limit,\n        offset: 0,\n        // @ts-ignore\n        network: NetworkMap[defaultNetwork].walletType,\n      },\n      apiKey,\n    )\n    if (response && ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message)) {\n      throw new Error((response as sdk.RESULT_INFO).message)\n    }\n    if (store.getState().account.accountId !== accountId) {\n      return { contacts: [] }\n    }\n    contacts = response.contacts\n    if (response.total > limit) {\n      let more: Promise<any>[] = []\n      for (let i = 1; i <= response.total / limit; i++) {\n        more.push(\n          LoopringAPI.contactAPI\n            .getContacts(\n              {\n                isHebao: !!(isContractAddress || isCFAddress),\n                accountId,\n                limit,\n                offset: i * limit,\n              },\n              apiKey,\n            )\n            .then((res) => {\n              if (\n                response &&\n                ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message)\n              ) {\n                throw new Error((response as sdk.RESULT_INFO).message)\n              }\n              return res.contacts\n            }),\n        )\n      }\n      const res = await Promise.all(more)\n      contacts = contacts.concat(res.flat())\n    }\n  }\n  return { contacts }\n}\n\nexport function* getPostsSaga() {\n  try {\n    const { contacts } = yield call(getContractsApi, {})\n    yield put(getContactsStatus({ contacts }))\n  } catch (err) {\n    yield put(getContactsStatus({ error: err }))\n  }\n}\n\nfunction* contractsSaga() {\n  yield all([takeLatest(updateContacts, getPostsSaga)])\n}\n\nexport const contractsForks = [fork(contractsSaga)]\n"
  },
  {
    "path": "packages/core/src/stores/global/actions.ts",
    "content": "import { createAction } from '@reduxjs/toolkit'\n\n// fired once when the app reloads but before the app renders\n// allows any updates to be applied to store data loaded from localStorage\nexport const updateVersion = createAction<void>('global/updateVersion')\n"
  },
  {
    "path": "packages/core/src/stores/index.ts",
    "content": "import {\n  CombinedState,\n  combineReducers,\n  configureStore,\n  getDefaultMiddleware,\n} from '@reduxjs/toolkit'\n\nimport { useDispatch } from 'react-redux'\nimport { persistReducer } from 'redux-persist'\nimport storageSession from 'redux-persist/lib/storage/session'\nimport storage from 'redux-persist/lib/storage'\nimport persistStore from 'redux-persist/es/persistStore'\nimport mySaga from './rootSaga'\nimport { updateVersion } from './global/actions'\nimport createSagaMiddleware from 'redux-saga'\nimport { reduxBatch } from '@manaflair/redux-batch'\nimport accountSlice from './account/reducer'\nimport {\n  modalsSlice,\n  setCoinJson,\n  setLanguage,\n  settingsSlice,\n  SettingsState,\n  toggleSlice,\n} from '@loopring-web/component-lib'\nimport { ammReducer } from './Amm'\nimport { tokenMapSlice } from './token/reducer'\nimport { tickerMapSlice } from './ticker/reducer'\nimport { systemSlice } from './system/reducer'\nimport { walletLayer1Slice } from './walletLayer1/reducer'\nimport { walletLayer2Slice } from './walletLayer2/reducer'\nimport { vaultLayer2Slice } from './vaultLayer2/reducer'\nimport { socketSlice } from './socket'\nimport { userRewardsMapSlice } from './userRewards/reducer'\nimport { amountMapSlice } from './amount/reducer'\nimport { tokenPricesSlice } from './tokenPrices/reducer'\nimport { TradeProSettings } from './localStore/tradeProSettings'\nimport { notifyMapSlice } from './notify/reducer'\nimport { walletLayer2NFTSlice } from './walletLayer2NFT/reducer'\nimport { redPacketConfigsSlice } from './redPacket/reducer'\nimport { localStoreReducer } from './localStore'\nimport { getAnalytics } from 'firebase/analytics'\nimport {\n  ChainHashInfos,\n  firebaseBridgeConfig,\n  firebaseIOConfig,\n  LAYER1_ACTION_HISTORY,\n  myLog,\n  NFTHashInfos,\n  OffRampHashInfos,\n  RedPacketHashInfos,\n} from '@loopring-web/common-resources'\nimport { FavoriteMarketStates } from './localStore/favoriteMarket'\nimport { Confirmation } from './localStore/confirmation'\nimport { WalletInfo } from './localStore/walletInfo'\n\nimport {\n  modalDataSlice,\n  pageTradeLiteSlice,\n  redeemStakeSlice,\n  tradeStakeSlice,\n  tradeVaultSlice,\n  tradeDefiSlice,\n  tradeDualSlice,\n  pageTradeProSlice,\n  pageAmmPoolSlice,\n} from './router'\nimport { firebaseReducer, ReactReduxFirebaseProviderProps } from 'react-redux-firebase'\nimport firebase from 'firebase/compat/app'\nimport { investReducer } from './invest'\nimport { walletL2CollectionSlice } from './walletL2Collection/reducer'\nimport { walletL2NFTCollectionSlice } from './walletL2NFTCollection/reducer'\nimport { tradeBtradeSlice } from './router/tradeBtrade'\nimport { contactsSlice } from './contacts/reducer'\nimport { targetRedpacketSlice } from './targetRedpackt/reducer'\nimport { configSlice } from './config/reducer'\nimport autoMergeLevel2 from 'redux-persist/es/stateReconciler/autoMergeLevel2'\nimport { CoinbaseSmartWalletPersist } from './localStore/coinbaseSmartWalletPersist/interface'\n\n\nconst sagaMiddleware = createSagaMiddleware()\n\nconst DEFAULT_TIMEOUT = 1000 * 60 * 15\n\nmyLog('---store DEFAULT_TIMEOUT:', DEFAULT_TIMEOUT)\n\n//\nconst persistAccConfig = {\n  key: 'account',\n  storage: storage,\n  timeout: DEFAULT_TIMEOUT,\n}\n\nconst persistSettingConfig = {\n  key: 'settings',\n  storage: storage,\n}\n\nconst persistLocalStoreConfig = {\n  key: 'localStore',\n  storage: storage,\n  stateReconciler: autoMergeLevel2,\n}\nconst persistedAccountReducer = persistReducer(persistAccConfig, accountSlice.reducer)\nconst perisitTokenPricesSessionStoreConfig = persistReducer(\n  { key: 'tokenPrices', storage: storageSession, timeout: DEFAULT_TIMEOUT },\n  tokenPricesSlice.reducer,\n)\nconst perisitWalletLayer2SessionStoreConfig = persistReducer(\n  { key: 'walletLayer2', storage: storageSession, timeout: DEFAULT_TIMEOUT },\n  walletLayer2Slice.reducer,\n)\nconst perisitVaultLayer2SessionStoreConfig = persistReducer(\n  { key: 'vaultLayer2', storage: storageSession, timeout: DEFAULT_TIMEOUT },\n  vaultLayer2Slice.reducer,\n)\nconst perisitWalletLayer1SessionStoreConfig = persistReducer(\n  { key: 'walletLayer1', storage: storageSession, timeout: DEFAULT_TIMEOUT },\n  walletLayer1Slice.reducer,\n)\nconst perisitTickerMapSessionStoreConfig = persistReducer(\n  { key: 'tickerMap', storage: storageSession, timeout: DEFAULT_TIMEOUT },\n  tickerMapSlice.reducer,\n)\n\nconst persistedSettingReducer = persistReducer<SettingsState>(\n  persistSettingConfig,\n  settingsSlice.reducer,\n)\n\nconst persistedLocalStoreReducer = persistReducer<\n  CombinedState<{\n    favoriteMarket: FavoriteMarketStates\n    chainHashInfos: ChainHashInfos\n    confirmation: Confirmation\n    walletInfo: WalletInfo\n    tradeProSettings: TradeProSettings\n    layer1ActionHistory: LAYER1_ACTION_HISTORY\n    nftHashInfos: NFTHashInfos\n    redPacketHistory: RedPacketHashInfos\n    offRampHistory: OffRampHashInfos\n    favoriteVaultMarket: FavoriteMarketStates\n    coinbaseSmartWalletPersist: CoinbaseSmartWalletPersist\n  }>\n>(persistLocalStoreConfig , localStoreReducer)\n\nexport const initReduce = {\n  account: persistedAccountReducer,\n  socket: socketSlice.reducer,\n  settings: persistedSettingReducer,\n  system: systemSlice.reducer,\n  modals: modalsSlice.reducer,\n  userRewardsMap: userRewardsMapSlice.reducer,\n  amm: ammReducer,\n  invest: investReducer,\n  tokenMap: tokenMapSlice.reducer,\n  redPacketConfigs: redPacketConfigsSlice.reducer,\n  toggle: toggleSlice.reducer,\n  tokenPrices: perisitTokenPricesSessionStoreConfig,\n  walletLayer2: perisitWalletLayer2SessionStoreConfig,\n  walletLayer1: perisitWalletLayer1SessionStoreConfig,\n  vaultLayer2: perisitVaultLayer2SessionStoreConfig,\n  tickerMap: perisitTickerMapSessionStoreConfig,\n  walletLayer2NFT: walletLayer2NFTSlice.reducer,\n  walletL2Collection: walletL2CollectionSlice.reducer,\n  walletL2NFTCollection: walletL2NFTCollectionSlice.reducer,\n  localStore: persistedLocalStoreReducer,\n  amountMap: amountMapSlice.reducer,\n  notifyMap: notifyMapSlice.reducer,\n  firebase: firebaseReducer,\n  contacts: contactsSlice.reducer,\n  targetRedpacket: targetRedpacketSlice.reducer,\n  config: configSlice.reducer,\n  _router_tradeDefi: tradeDefiSlice.reducer,\n  _router_tradeDual: tradeDualSlice.reducer,\n  _router_tradeStake: tradeStakeSlice.reducer,\n  _router_tradeBtrade: tradeBtradeSlice.reducer,\n  _router_redeemStake: redeemStakeSlice.reducer,\n  _router_pageTradeLite: pageTradeLiteSlice.reducer,\n  _router_pageTradePro: pageTradeProSlice.reducer,\n  _router_pageAmmPool: pageAmmPoolSlice.reducer,\n  _router_modalData: modalDataSlice.reducer,\n  _router_tradeVault: tradeVaultSlice.reducer,\n}\n\nexport const store = configureStore({\n  reducer: combineReducers(initReduce),\n  // middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(logger),\n  middleware: [\n    ...getDefaultMiddleware({\n      thunk: false,\n      serializableCheck: false,\n    }),\n    sagaMiddleware,\n  ],\n  //middleware: [...getDefaultMiddleware({ thunk: true }), ],\n  devTools: process.env.NODE_ENV !== 'production',\n  enhancers: [reduxBatch],\n})\n\nexport const firebaseProps: ReactReduxFirebaseProviderProps = (() => {\n  let firebase_app\n  switch (process.env.REACT_APP_NAME) {\n    case 'guardian':\n    case 'bridge':\n      // getAnalytics(firebase);\n      firebase_app = firebase.initializeApp(firebaseBridgeConfig)\n      // myLog(firebase_app);\n      getAnalytics(firebase_app)\n      return {\n        firebase,\n        config: {\n          userProfile: 'users',\n\n          // useFirestoreForProfile: true // Firestore for Profile instead of Realtime DB\n        },\n        dispatch: store.dispatch,\n      }\n    case 'loopring.io':\n    default:\n      firebase_app = firebase.initializeApp(firebaseIOConfig)\n      // myLog(firebase_app);\n      getAnalytics(firebase_app)\n      return {\n        firebase,\n        config: {\n          userProfile: 'users',\n        },\n        dispatch: store.dispatch,\n      }\n  }\n})()\n\nstore.dispatch(updateVersion())\n\nstore.dispatch(setLanguage(store.getState().settings.language))\nfetch(`./static/coin/loopring.json`)\n  .then((results) => results.json())\n  .then((imgConfig) => {\n    store.dispatch(setCoinJson(imgConfig.frames))\n  })\n// async function imageConfig() {\n//     const imgConfig = (await .json();\n//\n//\n\n// imageConfig()\n\n// @ts-ignore\nsagaMiddleware.run(mySaga, store.dispatch)\n\n// The store has been created with these options:\n// - The slice reducers were automatically passed to combineReducers()\n// - redux-thunk and redux-logger were added as middleware\n// - The Redux DevTools Extension is disabled for production\n// - The middleware, batch, and devtools enhancers were composed together\n\nexport type AppDispatch = typeof store.dispatch\nexport const useAppDispatch = () => useDispatch<AppDispatch>()\n//@ts-ignore\nexport type RootState = ReturnType<typeof initReduce>\nexport const persistor = persistStore(store)\n\n// persistor.persist()\n\nexport * from './account'\nexport * from './Amm'\nexport * from './amount'\nexport * from './global/actions'\nexport * from './localStore'\nexport * from './notify'\nexport * from './router'\nexport * from './socket'\nexport * from './system'\nexport * from './ticker'\nexport * from './token'\nexport * from './tokenPrices'\nexport * from './userRewards'\nexport * from './walletLayer1'\nexport * from './walletLayer2'\nexport * from './walletLayer2NFT'\nexport * from './walletL2Collection'\nexport * from './walletL2NFTCollection'\nexport * from './vaultLayer2'\nexport * from './invest'\nexport * from './contacts'\nexport * from './targetRedpackt'\nexport type { Config, FastWithdrawConfig } from './config'\nexport { configReducer, useConfig } from './config'\n// export { useCoinbaseSmartWalletPersist, persistStoreCoinbaseSmartWalletData } from './localStore/coinbaseSmartWalletPersist'\n"
  },
  {
    "path": "packages/core/src/stores/invest/BtradeMap/hook.ts",
    "content": "import { useDispatch, useSelector } from 'react-redux'\nimport React from 'react'\nimport { RootState } from '../../index'\nimport { getBtradeMap, statusUnset } from './reducer'\nimport { BtradeMap, BtradeMapStates } from './interface'\n\nexport const useBtradeMap = (): BtradeMapStates & {\n  getBtradeMap: () => void\n  statusUnset: () => void\n  updateBtradeSyncMap: (props: { btradeMap: BtradeMap }) => void\n} => {\n  const btradeMap: BtradeMapStates = useSelector((state: RootState) => state.invest.btradeMap)\n  const dispatch = useDispatch()\n  return {\n    ...btradeMap,\n    statusUnset: React.useCallback(() => dispatch(statusUnset(undefined)), [dispatch]),\n    getBtradeMap: React.useCallback(() => dispatch(getBtradeMap(undefined)), [dispatch]),\n    updateBtradeSyncMap: React.useCallback(\n      ({ btradeMap }: { btradeMap: BtradeMap }) => dispatch(getBtradeMap(btradeMap)),\n      [dispatch],\n    ),\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/invest/BtradeMap/index.ts",
    "content": "export * from './hook'\nexport * as btradeReducer from './reducer'\nexport * from './interface'\n"
  },
  {
    "path": "packages/core/src/stores/invest/BtradeMap/interface.ts",
    "content": "import { StateBase } from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nexport type BtradeUIMap = { enabled: boolean | 'isFormLocal' } & Omit<sdk.BTRADE_MARKET, 'enabled'>\nexport type BtradeMap = {\n  marketArray: string[]\n  marketCoins: string[]\n  marketMap: sdk.LoopringMap<BtradeUIMap>\n  tradeMap: sdk.LoopringMap<{ tokenId: number; tradePairs: string[] }>\n}\n\nexport type BtradeMapStates = BtradeMap & {\n  __timer__?: number\n} & StateBase\n"
  },
  {
    "path": "packages/core/src/stores/invest/BtradeMap/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { BtradeMapStates } from './interface'\nimport { SagaStatus } from '@loopring-web/common-resources'\n\nconst initialState: Required<BtradeMapStates> = {\n  marketArray: [],\n  marketCoins: [],\n  marketMap: {},\n  tradeMap: {},\n  __timer__: -1,\n  status: SagaStatus.PENDING,\n  errorMessage: null,\n}\nconst btradeMapSlice: Slice = createSlice({\n  name: 'btradeMap',\n  initialState,\n  reducers: {\n    getBtradeMap(state, _action: PayloadAction<undefined>) {\n      state.status = SagaStatus.PENDING\n    },\n    getBtradeMapStatus(state, action: PayloadAction<BtradeMapStates>) {\n      // @ts-ignore\n      if (action.payload.error) {\n        state.status = SagaStatus.ERROR\n      } else {\n        const { ...btradeMap } = action.payload\n        if (btradeMap) {\n          state.marketArray = btradeMap.marketArray\n          state.marketCoins = btradeMap.marketCoins\n          state.marketMap = btradeMap.marketMap\n          state.tradeMap = btradeMap.tradeMap\n          // , marketCoins, marketMap\n          // state.marketArray = { ...state, ...BtradeMap };\n        }\n\n        state.status = SagaStatus.DONE\n      }\n      if (action.payload.__timer__) {\n        state.__timer__ = action.payload.__timer__\n      }\n    },\n    updateBtradeSyncMap(state, _action: PayloadAction<BtradeMapStates>) {\n      state.status = SagaStatus.PENDING\n    },\n    statusUnset: (state) => {\n      state.status = SagaStatus.UNSET\n    },\n  },\n})\nconst { getBtradeMap, updateBtradeSyncMap, getBtradeMapStatus, statusUnset } =\n  btradeMapSlice.actions\nexport { btradeMapSlice, getBtradeMap, getBtradeMapStatus, statusUnset, updateBtradeSyncMap }\n"
  },
  {
    "path": "packages/core/src/stores/invest/BtradeMap/saga.ts",
    "content": "import { all, call, fork, put, takeLatest } from 'redux-saga/effects'\nimport { getBtradeMap, getBtradeMapStatus, updateBtradeSyncMap } from './reducer'\nimport { BtradeMap, store } from '../../index'\nimport { LoopringAPI } from '../../../api_wrapper'\nimport { PayloadAction } from '@reduxjs/toolkit'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport {\n  BTRDE_PRE,\n  LocalStorageConfigKey,\n  myLog,\n  UIERROR_CODE,\n} from '@loopring-web/common-resources'\n\nconst getBtradeMapApi = async () => {\n  if (!LoopringAPI.defiAPI) {\n    return undefined\n  }\n  const { chainId } = store.getState().system\n  const btradeMapStorage = window.localStorage.getItem(LocalStorageConfigKey.btradeMarkets)\n  let { __timer__ } = store.getState().invest.btradeMap\n  __timer__ = (() => {\n    if (__timer__ && __timer__ !== -1) {\n      clearInterval(__timer__)\n    }\n    return setInterval(async () => {\n      if (!LoopringAPI.defiAPI) {\n        return undefined\n      }\n      // let { markets, pairs, tokenArr, tokenArrStr, marketArr, marketArrStr } =\n      //   await LoopringAPI.defiAPI.getDefiMarkets();\n      store.dispatch(getBtradeMap(undefined))\n    }, 900000) //15*60*1000 //900000\n  })()\n  let response,\n    marketCoins,\n    pairs: sdk.LoopringMap<sdk.TokenRelatedInfo>,\n    marketArray,\n    marketMap,\n    tradeMap\n  try {\n    try {\n      response = await LoopringAPI.defiAPI?.getBtradeMarkets()\n    } catch (error) {\n      throw { code: UIERROR_CODE.TIME_OUT, error: error }\n    }\n    if (!response || (response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n      throw (response as sdk.RESULT_INFO).message\n    }\n    let localStorageData: any[] = []\n\n    const reformat: any[] = (response.raw_data as sdk.BTRADE_MARKET[]).reduce((prev, ele) => {\n      if (/-/gi.test(ele.market) && ele.enabled) {\n        localStorageData.push({\n          ...ele,\n          btradeMarket: ele.market,\n          market: ele.market.replace(BTRDE_PRE, ''),\n          feeBips: undefined,\n          enabled: 'isFormLocal', //localStorageSetAs false\n          minAmount: {\n            base: undefined,\n            quote: undefined,\n          },\n          btradeAmount: {\n            base: undefined,\n            quote: undefined,\n          },\n          l2Amount: {\n            base: undefined,\n            quote: undefined,\n          },\n        })\n        return [\n          ...prev,\n          {\n            ...ele,\n            btradeMarket: ele.market,\n            market: ele.market.replace(BTRDE_PRE, ''),\n          } as sdk.BTRADE_MARKET,\n        ]\n      } else {\n        return prev\n      }\n    }, [] as sdk.BTRADE_MARKET[])\n    localStorage.setItem(\n      'btradeMarkets',\n      JSON.stringify({\n        ...(btradeMapStorage ? JSON.parse(btradeMapStorage) : {}),\n        [chainId]: localStorageData,\n      }),\n    )\n\n    const res = sdk.makeMarkets({ markets: reformat })\n    marketMap = res.markets\n    pairs = res.pairs\n    marketArray = res.marketArr\n    marketCoins = res.tokenArr\n\n    tradeMap = Reflect.ownKeys(pairs ?? {}).reduce((prev, key) => {\n      const tradePairs = pairs[key as string]?.tokenList?.sort()\n      prev[key] = {\n        ...pairs[key as string],\n        tradePairs,\n      }\n      return prev\n    }, {})\n\n    return {\n      btradeMap: {\n        marketArray,\n        marketCoins,\n        marketMap,\n        tradeMap,\n      },\n      __timer__,\n    }\n  } catch (e) {\n    throw { e, __timer__ }\n  }\n\n  // const resultTokenMap = sdk.makeMarket(_tokenMap);\n}\n\nexport function* getPostsSaga() {\n  try {\n    const { btradeMap, __timer__ } = yield call(getBtradeMapApi)\n    yield put(getBtradeMapStatus({ ...btradeMap, __timer__ }))\n  } catch (err) {\n    myLog('getBtradeMapStatus', err)\n    yield put(getBtradeMapStatus({ error: (err as any)?.e, __timer__: (err as any)?.__timer__ }))\n  }\n}\n\nexport function* getBtradeSyncSaga({ payload }: PayloadAction<{ btradeMap: BtradeMap }>) {\n  try {\n    if (payload.btradeMap) {\n      yield put(getBtradeMapStatus({ ...payload.btradeMap }))\n    }\n  } catch (err) {\n    yield put(getBtradeMapStatus({ error: err }))\n  }\n}\n\nexport function* BtradeMapInitSaga() {\n  yield all([takeLatest(getBtradeMap, getPostsSaga)])\n}\n\nexport function* BtradeMapSyncSaga() {\n  // @ts-ignore\n  yield all([takeLatest(updateBtradeSyncMap, getBtradeSyncSaga)])\n}\n\nexport const btradeMapFork = [fork(BtradeMapInitSaga), fork(BtradeMapSyncSaga)]\n"
  },
  {
    "path": "packages/core/src/stores/invest/DefiMap/hook.ts",
    "content": "import { useDispatch, useSelector } from 'react-redux'\nimport React from 'react'\nimport { DefiMap, RootState } from '../../index'\nimport { getDefiMap, statusUnset } from './reducer'\nimport { DefiMapStates } from './interface'\n\nexport const useDefiMap = (): DefiMapStates & {\n  getDefiMap: () => void\n  statusUnset: () => void\n  updateDefiSyncMap: (props: { defiMap: Partial<DefiMap> }) => void\n} => {\n  const defiMap: DefiMapStates = useSelector((state: RootState) => state.invest.defiMap)\n  const dispatch = useDispatch()\n  return {\n    ...defiMap,\n    statusUnset: React.useCallback(() => dispatch(statusUnset(undefined)), [dispatch]),\n    getDefiMap: React.useCallback(() => dispatch(getDefiMap(undefined)), [dispatch]),\n    updateDefiSyncMap: React.useCallback(\n      ({ defiMap }: { defiMap: Partial<DefiMap> }) => dispatch(getDefiMap(defiMap)),\n      [dispatch],\n    ),\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/invest/DefiMap/index.ts",
    "content": "export * from './hook'\nexport * as defiReducer from './reducer'\nexport * from './interface'\n"
  },
  {
    "path": "packages/core/src/stores/invest/DefiMap/interface.ts",
    "content": "import { StateBase } from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nexport type DefiMap = {\n  marketArray: string[]\n  marketCoins: string[]\n  marketMap: sdk.LoopringMap<sdk.DefiMarketInfo>\n  marketLeverageArray: string[]\n  marketLeverageCoins: string[]\n  marketLeverageMap: sdk.LoopringMap<sdk.DefiMarketInfo>\n}\n\nexport type DefiMapStates = DefiMap & {\n  __timer__?: number\n} & StateBase\n"
  },
  {
    "path": "packages/core/src/stores/invest/DefiMap/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { DefiMapStates } from './interface'\nimport { SagaStatus } from '@loopring-web/common-resources'\n\nconst initialState: Required<DefiMapStates> = {\n  marketArray: [],\n  marketCoins: [],\n  marketMap: {},\n  marketLeverageMap: {},\n  marketLeverageCoins: [],\n  marketLeverageArray: [],\n  __timer__: -1,\n  status: SagaStatus.PENDING,\n  errorMessage: null,\n}\nconst defiMapSlice: Slice = createSlice({\n  name: 'defiMap',\n  initialState,\n  reducers: {\n    getDefiMap(state, _action: PayloadAction<undefined>) {\n      state.status = SagaStatus.PENDING\n    },\n    getDefiMapStatus(state, action: PayloadAction<DefiMapStates>) {\n      if ((action.payload as any).error) {\n        state.status = SagaStatus.ERROR\n        state.errorMessage = (action.payload as any).error\n        return\n      }\n      state.errorMessage = null\n      const { __timer__, ...defiMap } = action.payload\n      if (defiMap) {\n        state.marketArray = defiMap.marketArray\n        state.marketCoins = defiMap.marketCoins\n        state.marketMap = defiMap.marketMap\n        state.marketLeverageMap = defiMap.marketLeverageMap\n        state.marketLeverageCoins = defiMap.marketLeverageCoins\n        state.marketLeverageArray = defiMap.marketLeverageArray\n        // , marketCoins, marketMap\n        // state.marketArray = { ...state, ...defiMap };\n      }\n      if (__timer__) {\n        state.__timer__ = __timer__\n      }\n      state.status = SagaStatus.DONE\n    },\n    updateDefiSyncMap(state, _action: PayloadAction<DefiMapStates>) {\n      state.status = SagaStatus.PENDING\n    },\n    statusUnset: (state) => {\n      state.status = SagaStatus.UNSET\n    },\n  },\n})\nconst { getDefiMap, updateDefiSyncMap, getDefiMapStatus, statusUnset } = defiMapSlice.actions\nexport { defiMapSlice, getDefiMap, getDefiMapStatus, statusUnset, updateDefiSyncMap }\n"
  },
  {
    "path": "packages/core/src/stores/invest/DefiMap/saga.ts",
    "content": "import { all, call, fork, put, takeLatest } from 'redux-saga/effects'\nimport { getDefiMap, getDefiMapStatus, updateDefiSyncMap } from './reducer'\nimport { DefiMap, store } from '../../index'\nimport { LoopringAPI } from '../../../api_wrapper'\nimport { PayloadAction } from '@reduxjs/toolkit'\nimport { DEFI_CONFIG, LEVERAGE_ETH_CONFIG, MapChainId } from '@loopring-web/common-resources'\n\nconst getDefiMapApi = async () => {\n  if (!LoopringAPI.defiAPI) {\n    return undefined\n  }\n  const { defaultNetwork } = store.getState().settings\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n\n  // const [normal, leverage] = chainId === 1 ? ['LIDO,ROCKETPOOL', 'CIAN'] : ['ROCKETPOOL', 'LIDO']\n  const [\n    { markets: marketMap, tokenArr: marketCoins, marketArr: marketArray },\n    { markets: marketLeverageMap, tokenArr: marketLeverageCoins, marketArr: marketLeverageArray },\n  ] = await Promise.all([\n    LoopringAPI.defiAPI?.getDefiMarkets({\n      defiType: DEFI_CONFIG.products[network].join(','),\n    }),\n    LoopringAPI.defiAPI?.getDefiMarkets({\n      defiType: LEVERAGE_ETH_CONFIG.products[network].join(','),\n    }),\n  ])\n  let { __timer__ } = store.getState().invest.defiMap\n  __timer__ = (() => {\n    if (__timer__ && __timer__ !== -1) {\n      clearInterval(__timer__)\n    }\n    return setInterval(async () => {\n      if (!LoopringAPI.defiAPI) {\n        return undefined\n      }\n\n      // let { markets, pairs, tokenArr, tokenArrStr, marketArr, marketArrStr } =\n      //   await LoopringAPI.defiAPI.getDefiMarkets();\n      store.dispatch(getDefiMap(undefined))\n    }, 900000) //15*60*1000 //900000\n  })()\n\n  return {\n    defiMap: {\n      marketArray,\n      marketCoins,\n      marketMap,\n      marketLeverageMap,\n      marketLeverageCoins,\n      marketLeverageArray,\n    },\n    __timer__,\n  }\n}\n\nexport function* getPostsSaga() {\n  try {\n    const { defiMap, __timer__ } = yield call(getDefiMapApi)\n    yield put(getDefiMapStatus({ ...defiMap, __timer__ }))\n  } catch (err) {\n    yield put(getDefiMapStatus({ error: err }))\n  }\n}\n\nexport function* getDefiSyncSaga({ payload }: PayloadAction<{ defiMap: DefiMap }>) {\n  try {\n    if (payload.defiMap) {\n      yield put(getDefiMapStatus({ ...payload.defiMap }))\n    }\n  } catch (err) {\n    yield put(getDefiMapStatus({ error: err }))\n  }\n}\n\nexport function* defiMapInitSaga() {\n  yield all([takeLatest(getDefiMap, getPostsSaga)])\n}\n\nexport function* defiMapSyncSaga() {\n  // @ts-ignore\n  yield all([takeLatest(updateDefiSyncMap, getDefiSyncSaga)])\n}\n\nexport const defiMapFork = [fork(defiMapInitSaga), fork(defiMapSyncSaga)]\n"
  },
  {
    "path": "packages/core/src/stores/invest/DualMap/hook.ts",
    "content": "import { useDispatch, useSelector } from 'react-redux'\nimport React from 'react'\nimport { RootState } from '../../index'\nimport { getDualMap, statusUnset } from './reducer'\nimport { DualMapStates } from './interface'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nexport const useDualMap = (): DualMapStates & {\n  getDualMap: () => void\n  statusUnset: () => void\n  updateDualSyncMap: (props: {\n    dualMap: Partial<{\n      markets: sdk.LoopringMap<sdk.DefiMarketInfo>\n      pairs: sdk.LoopringMap<sdk.TokenRelatedInfo>\n      tokenArr: string[]\n      tokenArrStr: string\n      marketArr: string[]\n      marketArrStr: string\n    }>\n  }) => void\n} => {\n  const dualMap: DualMapStates = useSelector((state: RootState) => state.invest.dualMap)\n  const dispatch = useDispatch()\n  return {\n    ...dualMap,\n    statusUnset: React.useCallback(() => dispatch(statusUnset(undefined)), [dispatch]),\n    getDualMap: React.useCallback(() => dispatch(getDualMap(undefined)), [dispatch]),\n    updateDualSyncMap: React.useCallback(\n      ({ dualMap }) => dispatch(getDualMap(dualMap)),\n      [dispatch],\n    ),\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/invest/DualMap/index.ts",
    "content": "export * from './hook'\nexport * as dualReducer from './reducer'\nexport * from './interface'\n"
  },
  {
    "path": "packages/core/src/stores/invest/DualMap/interface.ts",
    "content": "import { StateBase } from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nexport type DualMap = {\n  marketArray: string[]\n  marketCoins: string[]\n  marketMap: sdk.LoopringMap<sdk.DefiMarketInfo>\n  tradeMap: sdk.LoopringMap<{ tokenId: number; tokenList: string[]; quoteList }>\n}\n\nexport type DualMapStates = DualMap & {\n  __timer__?: number\n} & StateBase\n"
  },
  {
    "path": "packages/core/src/stores/invest/DualMap/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { DualMapStates } from './interface'\nimport { SagaStatus } from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nconst initialState: Required<DualMapStates> = {\n  marketArray: [],\n  marketCoins: [],\n  tradeMap: {},\n  marketMap: {},\n  __timer__: -1,\n  status: SagaStatus.PENDING,\n  errorMessage: null,\n}\nconst dualMapSlice: Slice = createSlice({\n  name: 'dualMap',\n  initialState,\n  reducers: {\n    getDualMap(state, _action: PayloadAction<undefined>) {\n      state.status = SagaStatus.PENDING\n    },\n    getDualMapStatus(state, action: PayloadAction<DualMapStates>) {\n      // @ts-ignore\n      if (action.error) {\n        state.status = SagaStatus.ERROR\n        // @ts-ignore\n        state.errorMessage = action.error\n      }\n      const { __timer__, ...dualMap } = action.payload\n\n      if (dualMap) {\n        state.marketArray = dualMap.marketArray\n        state.marketCoins = dualMap.marketCoins\n        state.marketMap = dualMap.marketMap\n        state.tradeMap = dualMap.tradeMap\n        // , marketCoins, marketMap\n        // state.marketArray = { ...state, ...dualMap };\n      }\n      if (__timer__) {\n        state.__timer__ = __timer__\n      }\n      state.status = SagaStatus.DONE\n    },\n    updateDualSyncMap(\n      state,\n      _action: PayloadAction<\n        Partial<{\n          markets: sdk.LoopringMap<sdk.DefiMarketInfo>\n          pairs: sdk.LoopringMap<sdk.TokenRelatedInfo>\n          tokenArr: string[]\n          tokenArrStr: string\n          marketArr: string[]\n          marketArrStr: string\n        }>\n      >,\n    ) {\n      state.status = SagaStatus.PENDING\n    },\n    statusUnset: (state) => {\n      state.status = SagaStatus.UNSET\n    },\n  },\n})\nconst { getDualMap, updateDualSyncMap, getDualMapStatus, statusUnset } = dualMapSlice.actions\nexport { dualMapSlice, getDualMap, getDualMapStatus, statusUnset, updateDualSyncMap }\n"
  },
  {
    "path": "packages/core/src/stores/invest/DualMap/saga.ts",
    "content": "import { all, call, fork, put, takeLatest } from 'redux-saga/effects'\nimport { getDualMap, getDualMapStatus, updateDualSyncMap } from './reducer'\nimport { store } from '../../index'\nimport { LoopringAPI } from '../../../api_wrapper'\nimport { PayloadAction } from '@reduxjs/toolkit'\nimport { DUAL_CONFIG, MapChainId } from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nconst getDualMapApi = async () => {\n  if (!LoopringAPI.defiAPI) {\n    return undefined\n  }\n  const { baseURL } = store.getState().system\n  const { defaultNetwork } = store.getState().settings\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const url =\n    sdk.LOOPRING_URLs.GET_DEFI_MARKETS + (/https:\\/\\/dev\\./.test(baseURL) ? `?defiType=DUAL` : '')\n  const {\n    markets: marketMap,\n    tokenArr: marketCoins,\n    marketArr,\n    pairs,\n  } = await LoopringAPI.defiAPI?.getDefiMarkets(\n    {\n      defiType: DUAL_CONFIG.products[network].join(','),\n    },\n    url,\n  )\n  const marketArray = marketArr?.sort((b, a) => a.localeCompare(b))\n  const tradeMap = Reflect.ownKeys(pairs ?? {}).reduce((prev, key) => {\n    const tokenList = pairs[key as string]?.tokenList?.sort()\n    const quoteList = pairs[key as string]?.tokenList?.filter((item) => {\n      return marketMap[`DUAL-${key as string}-${item}`] !== undefined\n    })\n    prev[key] = {\n      ...pairs[key as string],\n      tokenList,\n      quoteList,\n    }\n    return prev\n  }, {})\n  let { __timer__ } = store.getState().invest.dualMap\n  __timer__ = (() => {\n    if (__timer__ && __timer__ !== -1) {\n      clearInterval(__timer__)\n    }\n    return setInterval(async () => {\n      if (!LoopringAPI.defiAPI) {\n        return undefined\n      }\n      store.dispatch(getDualMap(undefined))\n    }, 900000) //15*60*1000 //900000\n  })()\n\n  return {\n    dualMap: {\n      marketArray,\n      marketCoins,\n      marketMap,\n      tradeMap,\n    },\n    __timer__,\n  }\n}\n\nexport function* getPostsSaga() {\n  try {\n    const { dualMap, __timer__ } = yield call(getDualMapApi)\n    yield put(getDualMapStatus({ ...dualMap, __timer__ }))\n  } catch (err) {\n    yield put(getDualMapStatus({ error: err }))\n  }\n}\n\nexport function* getDualSyncSaga({\n  payload,\n}: PayloadAction<{\n  dualMap: {\n    markets: sdk.LoopringMap<sdk.DefiMarketInfo>\n    pairs: sdk.LoopringMap<sdk.TokenRelatedInfo>\n    tokenArr: string[]\n    tokenArrStr: string\n    marketArr: string[]\n    marketArrStr: string\n  }\n}>) {\n  try {\n    if (payload.dualMap) {\n      const { markets: marketMap, tokenArr: marketCoins, marketArr, pairs } = payload.dualMap\n      const marketArray = marketArr?.sort((b, a) => a.localeCompare(b))\n      const tradeMap = Reflect.ownKeys(pairs ?? {}).reduce((prev, key) => {\n        const tokenList = pairs[key as string]?.tokenList?.sort()\n        const quoteList = pairs[key as string]?.tokenList?.filter((item) => {\n          return marketMap[`DUAL-${key as string}-${item}`] !== undefined\n        })\n        prev[key] = {\n          ...pairs[key as string],\n          tokenList,\n          quoteList,\n        }\n        return prev\n      }, {})\n      let { __timer__ } = store.getState().invest.dualMap\n      __timer__ = (() => {\n        if (__timer__ && __timer__ !== -1) {\n          clearInterval(__timer__)\n        }\n        return setInterval(async () => {\n          if (!LoopringAPI.defiAPI) {\n            return undefined\n          }\n          store.dispatch(getDualMap(undefined))\n        }, 900000) //15*60*1000 //900000\n      })()\n      yield put(\n        getDualMapStatus({\n          marketArray,\n          marketCoins,\n          marketMap,\n          tradeMap,\n          __timer__,\n        }),\n      )\n    }\n  } catch (err) {\n    yield put(getDualMapStatus({ error: err }))\n  }\n}\n\nexport function* dualMapInitSaga() {\n  yield all([takeLatest(getDualMap, getPostsSaga)])\n}\n\nexport function* dualMapSyncSaga() {\n  // @ts-ignore\n  yield all([takeLatest(updateDualSyncMap, getDualSyncSaga)])\n}\n\nexport const dualMapFork = [fork(dualMapInitSaga), fork(dualMapSyncSaga)]\n"
  },
  {
    "path": "packages/core/src/stores/invest/InvestTokenTypeMap/hook.ts",
    "content": "import { InvestTokenTypeMapStates } from './interface'\nimport { useDispatch, useSelector } from 'react-redux'\nimport { RootState } from '../../index'\nimport React from 'react'\nimport { getInvestTokenTypeMap, statusUnset } from './reducer'\n\nexport const useInvestTokenTypeMap = (): InvestTokenTypeMapStates & {\n  getInvestTokenTypeMap: () => void\n  statusUnset: () => void\n} => {\n  const investTokenTypeMap: InvestTokenTypeMapStates = useSelector(\n    (state: RootState) => state.invest.investTokenTypeMap,\n  )\n  const dispatch = useDispatch()\n  return {\n    ...investTokenTypeMap,\n    statusUnset: React.useCallback(() => dispatch(statusUnset(undefined)), [dispatch]),\n    getInvestTokenTypeMap: React.useCallback(\n      () => dispatch(getInvestTokenTypeMap(undefined)),\n      [dispatch],\n    ),\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/invest/InvestTokenTypeMap/index.ts",
    "content": "export * from './hook'\nexport * as investTokenTypeMapReducer from './reducer'\nexport * from './interface'\n"
  },
  {
    "path": "packages/core/src/stores/invest/InvestTokenTypeMap/interface.ts",
    "content": "import { InvestDetail, InvestItem, InvestMapType, StateBase } from '@loopring-web/common-resources'\n\n//labelInvestType\nexport const labelI18n = 'labelInvestType_'\n\nexport type InvestTokenTypeMap = {\n  [key: string]: {\n    [key in InvestMapType]?: InvestItem\n  } & { detail: InvestDetail }\n}\n\nexport type InvestTokenTypeMapStates = {\n  investTokenTypeMap: InvestTokenTypeMap\n} & StateBase\n"
  },
  {
    "path": "packages/core/src/stores/invest/InvestTokenTypeMap/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { InvestTokenTypeMapStates } from './interface'\nimport { SagaStatus } from '@loopring-web/common-resources'\n\nconst initialState: Required<InvestTokenTypeMapStates> = {\n  investTokenTypeMap: {},\n  status: SagaStatus.PENDING,\n  errorMessage: null,\n}\nconst investTokenTypeMapSlice: Slice = createSlice({\n  name: 'investTokenTypeMap',\n  initialState,\n  reducers: {\n    getInvestTokenTypeMap(state, _action: PayloadAction<undefined>) {\n      state.status = SagaStatus.PENDING\n    },\n    getInvestTokenTypeMapStatus(state, action: PayloadAction<InvestTokenTypeMapStates>) {\n      // @ts-ignore\n      if (action.error) {\n        state.status = SagaStatus.ERROR\n        // @ts-ignore\n        state.errorMessage = action.error\n      }\n      state.investTokenTypeMap = action.payload.investTokenTypeMap\n      state.status = SagaStatus.DONE\n    },\n    statusUnset: (state) => {\n      state.status = SagaStatus.UNSET\n    },\n  },\n})\nconst { getInvestTokenTypeMapStatus, getInvestTokenTypeMap, statusUnset } =\n  investTokenTypeMapSlice.actions\nexport { statusUnset, investTokenTypeMapSlice, getInvestTokenTypeMapStatus, getInvestTokenTypeMap }\n"
  },
  {
    "path": "packages/core/src/stores/invest/InvestTokenTypeMap/saga.ts",
    "content": "import { all, call, fork, put, takeLatest } from 'redux-saga/effects'\nimport { getInvestTokenTypeMap, getInvestTokenTypeMapStatus } from './reducer'\nimport { AmmDetailStore, InvestTokenTypeMap, store } from '../../index'\nimport { InvestDuration, InvestItem, InvestMapType } from '@loopring-web/common-resources'\n\nfunction calcApr(\n  ammInfo: AmmDetailStore<any>,\n  investItem: InvestItem,\n): [start: number, end: number] {\n  let [start, end] = investItem.apr\n  const apr = ammInfo.APR\n  if ((!start && apr) || (apr && apr < start)) {\n    start = apr\n  }\n  if (apr && apr > end) {\n    end = apr\n  }\n  return [start, end]\n}\nfunction calcDefiApr(\n  defiinfo: { apy: string } | any,\n  investItem: InvestItem,\n): [start: number, end: number] {\n  let [start, end] = investItem.apr\n  const apr = Number(defiinfo.apy)\n  if (start === 0 && apr !== 0) {\n    start = apr\n  } else if (apr !== 0 && apr < start) {\n    start = apr\n  }\n  if (end === 0 && apr !== 0) {\n    end = apr\n  } else if (apr !== 0 && apr > end) {\n    end = apr\n  }\n  return [start, end]\n}\n\nfunction calcDualApr(apr: [number, number], investItem: InvestItem): [start: number, end: number] {\n  let [start, end] = investItem.apr\n  let [_start, _end] = apr\n  // const apr = Number(defiinfo.apy);\n  if (start === 0 && _start !== 0) {\n    start = _start\n  } else if (_start !== 0 && _start < start) {\n    start = _start\n  }\n  if (end === 0 && _end !== 0) {\n    end = _end\n  } else if (_end !== 0 && _end > end) {\n    end = _end\n  }\n  return [start, end]\n}\n\nconst getInvestMapApi = async () => {\n  const { ammMap } = store.getState().amm.ammMap\n  const { marketMap: defiMarketMap, marketLeverageMap } = store.getState().invest.defiMap\n  const { marketMap: dualMarketMap } = store.getState().invest.dualMap\n  const { marketMap: stakingMarketMap } = store.getState().invest.stakingMap\n\n  const { tokenMap } = store.getState().tokenMap\n  let investTokenTypeMap: InvestTokenTypeMap = Object.keys(ammMap).reduce((prev, key) => {\n    // @ts-ignore\n    const [, coinA, coinB] = key.match(/AMM-(\\w+)-(\\w+)/i)\n    const ammInfo = ammMap[key]\n    if (prev[coinA] && prev[coinA]) {\n      let investItem = prev[coinA][InvestMapType.AMM]\n      if (investItem) {\n        investItem.apr = calcApr(ammInfo, investItem)\n      } else {\n        prev[coinA][InvestMapType.AMM] = {\n          // token: tokenMap[coinA],\n          type: InvestMapType.AMM,\n          i18nKey: `labelInvestType_${InvestMapType.AMM}`,\n          apr: [ammInfo.APR ?? 0, ammInfo.APR ?? 0],\n          durationType: InvestDuration.Flexible,\n          duration: '',\n        }\n      }\n    } else {\n      prev[coinA] = {\n        detail: {\n          token: tokenMap[coinA],\n          apr: [ammInfo.APR ?? 0, ammInfo.APR ?? 0],\n          durationType: InvestDuration.All,\n          duration: '',\n        },\n        [InvestMapType.AMM]: {\n          type: InvestMapType.AMM,\n          // token: tokenMap[coinA],\n          i18nKey: `labelInvestType_${InvestMapType.AMM}`,\n          apr: [ammInfo.APR ?? 0, ammInfo.APR ?? 0],\n          durationType: InvestDuration.Flexible,\n          duration: '',\n        },\n      }\n    }\n\n    if (prev[coinB] && prev[coinB]) {\n      let investItem = prev[coinB][InvestMapType.AMM]\n      if (investItem) {\n        investItem.apr = calcApr(ammInfo, investItem)\n      } else {\n        prev[coinB][InvestMapType.AMM] = {\n          type: InvestMapType.AMM,\n          // token: tokenMap[coinB],\n          i18nKey: `labelInvestType_${InvestMapType.AMM}`,\n          apr: [ammInfo.APR ?? 0, ammInfo.APR ?? 0],\n          durationType: InvestDuration.Flexible,\n          duration: '',\n        }\n      }\n    } else {\n      prev[coinB] = {\n        detail: {\n          token: tokenMap[coinB],\n          apr: [ammInfo.APR ?? 0, ammInfo.APR ?? 0],\n          durationType: InvestDuration.All,\n          duration: '',\n        },\n        [InvestMapType.AMM]: {\n          type: InvestMapType.AMM,\n          // token: tokenMap[coinB],\n          i18nKey: `labelInvestType_${InvestMapType.AMM}`,\n          apr: [ammInfo.APR ?? 0, ammInfo.APR ?? 0],\n          durationType: InvestDuration.Flexible,\n          duration: '',\n        },\n      }\n    }\n\n    if (prev[coinA]?.detail && ammInfo.APR) {\n      prev[coinA].detail.apr = [\n        prev[coinA]?.detail?.apr[0] === 0\n          ? ammInfo.APR\n          : Math.min(ammInfo.APR, prev[coinA]?.detail?.apr[0]),\n        Math.max(ammInfo.APR, prev[coinA]?.detail?.apr[1]),\n      ]\n    }\n\n    if (prev[coinB]?.detail && ammInfo.APR) {\n      prev[coinB].detail.apr = [\n        prev[coinB]?.detail?.apr[0] === 0\n          ? ammInfo.APR\n          : Math.min(ammInfo.APR, prev[coinB]?.detail?.apr[0]),\n        Math.max(ammInfo.APR, prev[coinB]?.detail?.apr[1]),\n      ]\n    }\n\n    return prev\n  }, {} as InvestTokenTypeMap)\n  if (defiMarketMap) {\n    investTokenTypeMap = Object.keys(defiMarketMap).reduce((prev, key) => {\n      const [, _coinA, coinB] = key.match(/(\\w+)-(\\w+)/i)\n      const defiInfo = defiMarketMap[key]\n      if (prev[coinB] && prev[coinB]) {\n        let investItem = prev[coinB][InvestMapType.STAKE]\n        if (investItem) {\n          investItem.apr = calcDefiApr(defiInfo, investItem)\n        } else {\n          prev[coinB][InvestMapType.STAKE] = {\n            type: InvestMapType.STAKE,\n            // token: tokenMap[coinB],\n            i18nKey: `labelInvestType_${InvestMapType.STAKE}`,\n            apr: [defiInfo.apy ?? 0, defiInfo.apy ?? 0],\n            durationType: InvestDuration.Flexible,\n            duration: '',\n          }\n        }\n      } else {\n        prev[coinB] = {\n          detail: {\n            token: tokenMap[coinB],\n            apr: [defiInfo.apy ?? 0, defiInfo.apy ?? 0],\n            durationType: InvestDuration.All,\n            duration: '',\n          },\n          [InvestMapType.STAKE]: {\n            type: InvestMapType.STAKE,\n            // token: tokenMap[coinB],\n            i18nKey: `labelInvestType_${InvestMapType.STAKE}`,\n            apr: [defiInfo.apy ?? 0, defiInfo.apy ?? 0],\n            durationType: InvestDuration.Flexible,\n            duration: '',\n          },\n        }\n      }\n      if (prev[coinB]?.detail && defiInfo.apy) {\n        prev[coinB].detail.apr = [\n          prev[coinB]?.detail?.apr[0] === 0\n            ? defiInfo.apy\n            : Math.min(defiInfo.apy, prev[coinB]?.detail?.apr[0]),\n          Math.max(defiInfo.apy, prev[coinB]?.detail?.apr[1]),\n        ]\n      }\n      return prev\n    }, investTokenTypeMap)\n  }\n  if (marketLeverageMap) {\n    investTokenTypeMap = Object.keys(marketLeverageMap).reduce((prev, key) => {\n      const [, _coinA, coinB] = key.match(/(\\w+)-(\\w+)/i)\n      const defiInfo = marketLeverageMap[key]\n      if (prev[coinB] && prev[coinB]) {\n        let investItem = prev[coinB][InvestMapType.LEVERAGEETH]\n        if (investItem) {\n          investItem.apr = calcDefiApr(defiInfo, investItem)\n        } else {\n          prev[coinB][InvestMapType.LEVERAGEETH] = {\n            type: InvestMapType.LEVERAGEETH,\n            // token: tokenMap[coinB],\n            i18nKey: `labelInvestType_${InvestMapType.LEVERAGEETH}`,\n            apr: [defiInfo.apy ?? 0, defiInfo.apy ?? 0],\n            durationType: InvestDuration.Flexible,\n            duration: '',\n          }\n        }\n      } else {\n        prev[coinB] = {\n          detail: {\n            token: tokenMap[coinB],\n            apr: [defiInfo.apy ?? 0, defiInfo.apy ?? 0],\n            durationType: InvestDuration.All,\n            duration: '',\n          },\n          [InvestMapType.LEVERAGEETH]: {\n            type: InvestMapType.LEVERAGEETH,\n            // token: tokenMap[coinB],\n            i18nKey: `labelInvestType_${InvestMapType.LEVERAGEETH}`,\n            apr: [defiInfo.apy ?? 0, defiInfo.apy ?? 0],\n            durationType: InvestDuration.Flexible,\n            duration: '',\n          },\n        }\n      }\n      if (prev[coinB]?.detail && defiInfo.apy) {\n        prev[coinB].detail.apr = [\n          prev[coinB]?.detail?.apr[0] === 0\n            ? defiInfo.apy\n            : Math.min(defiInfo.apy, prev[coinB]?.detail?.apr[0]),\n          Math.max(defiInfo.apy, prev[coinB]?.detail?.apr[1]),\n        ]\n      }\n      return prev\n    }, investTokenTypeMap)\n  }\n\n  if (dualMarketMap) {\n    investTokenTypeMap = Object.keys(dualMarketMap).reduce((prev, key) => {\n      // const [, _, coinB] = key.match(/(\\w+)-(\\w+)/i);\n      // @ts-ignore\n      const [_markets, type, coinA, coinB] = key.match(/^(\\w+-)?(\\w+)-(\\w+)$/i)\n\n      const dualInfo = dualMarketMap[key]\n      if (prev[coinA] && prev[coinA]) {\n        let investItem = prev[coinA][InvestMapType.DUAL]\n        prev[coinA].detail.durationType = InvestDuration.All\n        if (investItem) {\n          investItem.apr = calcDualApr(\n            [(dualInfo?.baseTokenApy?.min ?? 0) * 100, (dualInfo?.baseTokenApy?.max ?? 0) * 100],\n            investItem,\n          )\n        } else {\n          prev[coinA][InvestMapType.DUAL] = {\n            // token: tokenMap[coinA],\n            type: InvestMapType.DUAL,\n            i18nKey: `labelInvestType_${InvestMapType.DUAL}`,\n            //@ts-ignore\n            apr: [\n              (dualInfo?.baseTokenApy?.min ?? 0) * 100,\n              (dualInfo?.baseTokenApy?.max ?? 0) * 100,\n            ], // [dualInfo.apy ?? 0, dualInfo.apy ?? 0],\n            durationType: InvestDuration.Duration,\n            duration: `labelInvestRangeDay|1 - 10`,\n          }\n        }\n      } else {\n        prev[coinA] = {\n          detail: {\n            token: tokenMap[coinA],\n            // apr: [dualInfo.apy ?? 0, dualInfo.apy ?? 0],\n            //@ts-ignore\n            apr: [\n              (dualInfo?.baseTokenApy?.min ?? 0) * 100,\n              (dualInfo?.baseTokenApy?.max ?? 0) * 100,\n            ],\n            durationType: InvestDuration.All,\n            duration: '',\n          },\n          [InvestMapType.DUAL]: {\n            type: InvestMapType.DUAL,\n            // token: tokenMap[coinA],\n            i18nKey: `labelInvestType_${InvestMapType.DUAL}`,\n            apr: [\n              (dualInfo?.baseTokenApy?.min ?? 0) * 100,\n              (dualInfo?.baseTokenApy?.max ?? 0) * 100,\n            ],\n            durationType: InvestDuration.Duration,\n            duration: `labelInvestRangeDay|1 - 10`,\n          },\n        }\n      }\n      if (prev[coinB] && prev[coinB]) {\n        let investItem = prev[coinB][InvestMapType.DUAL]\n        // prev[coinB].detail.durationType = InvestDuration.All;\n        if (investItem) {\n          investItem.apr = calcDualApr(\n            [(dualInfo?.quoteTokenApy?.min ?? 0) * 100, (dualInfo?.quoteTokenApy?.max ?? 0) * 100],\n            investItem,\n          )\n        } else {\n          prev[coinB][InvestMapType.DUAL] = {\n            type: InvestMapType.DUAL,\n            i18nKey: `labelInvestType_${InvestMapType.DUAL}`,\n            //@ts-ignore\n            apr: [\n              (dualInfo?.quoteTokenApy?.min ?? 0) * 100,\n              (dualInfo?.quoteTokenApy?.max ?? 0) * 100,\n            ],\n            durationType: InvestDuration.Duration,\n            duration: `labelInvestRangeDay|1 - 10`,\n          }\n        }\n      } else {\n        prev[coinB] = {\n          detail: {\n            token: tokenMap[coinB],\n            apr: [\n              (dualInfo?.quoteTokenApy?.min ?? 0) * 100,\n              (dualInfo?.quoteTokenApy?.max ?? 0) * 100,\n            ],\n            durationType: InvestDuration.All,\n            duration: '',\n          },\n          [InvestMapType.DUAL]: {\n            type: InvestMapType.DUAL,\n            // token: tokenMap[coinB],\n            i18nKey: `labelInvestType_${InvestMapType.DUAL}`,\n            apr: [\n              (dualInfo?.quoteTokenApy?.min ?? 0) * 100,\n              (dualInfo?.quoteTokenApy?.max ?? 0) * 100,\n            ],\n            durationType: InvestDuration.Duration,\n            duration: `labelInvestRangeDay|1 - 10`,\n          },\n        }\n      }\n\n      if (prev[coinA]?.detail && dualInfo.baseTokenApy) {\n        prev[coinA].detail.apr = [\n          prev[coinA]?.detail?.apr[0] === 0\n            ? (dualInfo?.baseTokenApy?.min ?? 0) * 100\n            : Math.min((dualInfo?.baseTokenApy?.min ?? 0) * 100, prev[coinA]?.detail?.apr[0]),\n          Math.max((dualInfo?.baseTokenApy?.max ?? 0) * 100, prev[coinA]?.detail?.apr[1]),\n        ]\n      }\n\n      if (prev[coinB]?.detail && dualInfo.quoteTokenApy) {\n        prev[coinB].detail.apr = [\n          prev[coinB]?.detail?.apr[0] === 0\n            ? (dualInfo?.quoteTokenApy?.min ?? 0) * 100\n            : Math.min((dualInfo?.quoteTokenApy?.min ?? 0) * 100, prev[coinB]?.detail?.apr[0]),\n          Math.max((dualInfo?.quoteTokenApy?.max ?? 0) * 100, prev[coinB]?.detail?.apr[1]),\n        ]\n      }\n\n      return prev\n    }, investTokenTypeMap)\n  }\n\n  if (stakingMarketMap) {\n    investTokenTypeMap = Object.keys(stakingMarketMap).reduce((prev, key) => {\n      const coin = key\n      if (prev[coin] && prev[coin]) {\n        let investItem = prev[coin][InvestMapType.STAKELRC]\n        if (investItem) {\n          investItem.apr = calcDefiApr({ apy: stakingMarketMap[key].apr }, investItem)\n        } else {\n          prev[coin][InvestMapType.STAKELRC] = {\n            type: InvestMapType.STAKELRC,\n            // token: tokenMap[coinB],\n            i18nKey: `labelInvestType_${InvestMapType.STAKELRC}`,\n            apr: [stakingMarketMap[key]?.apr ?? 0, stakingMarketMap[key]?.apr ?? 0],\n            durationType: InvestDuration.Flexible,\n            duration: '',\n          }\n        }\n      } else {\n        prev[coin] = {\n          detail: {\n            token: tokenMap[coin],\n            apr: [stakingMarketMap[key]?.apr ?? 0, stakingMarketMap[key]?.apr ?? 0],\n            durationType: InvestDuration.All,\n            duration: '',\n          },\n          [InvestMapType.STAKE]: {\n            type: InvestMapType.STAKE,\n            // token: tokenMap[coinB],\n            i18nKey: `labelInvestType_${InvestMapType.STAKE}`,\n            apr: [stakingMarketMap[key]?.apr ?? 0, stakingMarketMap[key]?.apr ?? 0],\n            durationType: InvestDuration.Flexible,\n            duration: '',\n          },\n        }\n      }\n      if (prev[coin]?.detail && stakingMarketMap[key].apr) {\n        prev[coin].detail.apr = [\n          prev[coin]?.detail?.apr[0] === 0\n            ? stakingMarketMap[key].apy\n            : Math.min(stakingMarketMap[key].apr, prev[coin]?.detail?.apr[0]),\n          Math.max(stakingMarketMap[key].apr, prev[coin]?.detail?.apr[1]),\n        ]\n      }\n      return prev\n    }, investTokenTypeMap)\n  }\n\n  return {\n    investTokenTypeMap,\n  }\n}\n\nexport function* getPostsSaga() {\n  try {\n    const { investTokenTypeMap } = yield call(getInvestMapApi)\n    yield put(getInvestTokenTypeMapStatus({ investTokenTypeMap }))\n  } catch (err) {\n    yield put(getInvestTokenTypeMapStatus({ error: err }))\n  }\n}\n\nexport function* investTokenTypeSaga() {\n  yield all([takeLatest(getInvestTokenTypeMap, getPostsSaga)])\n}\n\nexport const investTokenTypeForks = [fork(investTokenTypeSaga)]\n"
  },
  {
    "path": "packages/core/src/stores/invest/StakingMap/hook.ts",
    "content": "import { useDispatch, useSelector } from 'react-redux'\nimport React from 'react'\nimport { RootState } from '../../index'\nimport { getStakingMap, statusUnset } from './reducer'\nimport { StakingMap, StakingMapStates } from './interface'\n\nexport const useStakingMap = (): StakingMapStates & {\n  getStakingMap: () => void\n  statusUnset: () => void\n  updateStakingSyncMap: (props: { stakingMap: StakingMap }) => void\n} => {\n  const stakingMap: StakingMapStates = useSelector((state: RootState) => state.invest.stakingMap)\n  const dispatch = useDispatch()\n  return {\n    ...stakingMap,\n    statusUnset: React.useCallback(() => dispatch(statusUnset(undefined)), [dispatch]),\n    getStakingMap: React.useCallback(() => dispatch(getStakingMap(undefined)), [dispatch]),\n    updateStakingSyncMap: React.useCallback(\n      ({ stakingMap }: { stakingMap: StakingMap }) => dispatch(getStakingMap(stakingMap)),\n      [dispatch],\n    ),\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/invest/StakingMap/index.ts",
    "content": "export * from './hook'\nexport * as stakingReducer from './reducer'\nexport * from './interface'\n"
  },
  {
    "path": "packages/core/src/stores/invest/StakingMap/interface.ts",
    "content": "import { StateBase } from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nexport type StakingMap = {\n  marketArray: string[]\n  marketCoins: string[]\n  marketMap: sdk.LoopringMap<sdk.STACKING_PRODUCT>\n}\n\nexport type StakingMapStates = StakingMap & {\n  __timer__?: number\n} & StateBase\n"
  },
  {
    "path": "packages/core/src/stores/invest/StakingMap/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { StakingMapStates } from './interface'\nimport { SagaStatus } from '@loopring-web/common-resources'\n\nconst initialState: Required<StakingMapStates> = {\n  marketArray: [],\n  marketCoins: [],\n  marketMap: {},\n  __timer__: -1,\n  status: SagaStatus.PENDING,\n  errorMessage: null,\n}\nconst stakingMapSlice: Slice = createSlice({\n  name: 'stakingMap',\n  initialState,\n  reducers: {\n    getStakingMap(state, _action: PayloadAction<undefined>) {\n      state.status = SagaStatus.PENDING\n    },\n    getStakingMapStatus(state, action: PayloadAction<StakingMapStates>) {\n      // @ts-ignore\n      if (action.error) {\n        state.status = SagaStatus.ERROR\n        // @ts-ignore\n        state.errorMessage = action.error\n      }\n      const { __timer__, ...stakingMap } = action.payload\n      if (stakingMap) {\n        state.marketArray = stakingMap.marketArray\n        state.marketCoins = stakingMap.marketCoins\n        state.marketMap = stakingMap.marketMap\n        // , marketCoins, marketMap\n        // state.marketArray = { ...state, ...stakingMap };\n      }\n      if (__timer__) {\n        state.__timer__ = __timer__\n      }\n      state.status = SagaStatus.DONE\n    },\n    updateStakingSyncMap(state, _action: PayloadAction<StakingMapStates>) {\n      state.status = SagaStatus.PENDING\n    },\n    statusUnset: (state) => {\n      state.status = SagaStatus.UNSET\n    },\n  },\n})\nconst { getStakingMap, updateStakingSyncMap, getStakingMapStatus, statusUnset } =\n  stakingMapSlice.actions\nexport { stakingMapSlice, getStakingMap, getStakingMapStatus, statusUnset, updateStakingSyncMap }\n"
  },
  {
    "path": "packages/core/src/stores/invest/StakingMap/saga.ts",
    "content": "import { all, call, fork, put, takeLatest } from 'redux-saga/effects'\nimport { getStakingMap, getStakingMapStatus, updateStakingSyncMap } from './reducer'\nimport { store } from '../../index'\nimport { LoopringAPI } from '../../../api_wrapper'\nimport { PayloadAction } from '@reduxjs/toolkit'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { StakingMap } from './interface'\n\nconst getStakingMapApi = async () => {\n  if (!LoopringAPI.defiAPI) {\n    return undefined\n  }\n\n  const responseProduct = await LoopringAPI.defiAPI.getStakeProducts()\n\n  let result: any = undefined\n  if ((responseProduct as sdk.RESULT_INFO).code || (responseProduct as sdk.RESULT_INFO).message) {\n    result = {\n      marketArray: [],\n      marketCoins: [],\n      marketMap: {},\n    }\n  } else {\n    result = (responseProduct as any)?.products?.markets?.reduce(\n      (prev: any, item: sdk.STACKING_PRODUCT) => {\n        prev.marketArray.push([item.symbol.toUpperCase()])\n        prev.marketCoins.push([item.symbol.toUpperCase()])\n        prev.marketMap = {\n          ...prev.marketMap,\n          [item.symbol.toUpperCase()]: item,\n        }\n        // (ele:) =>\n        // ele.symbol?.toLowerCase() === coinSellSymbol?.toLowerCase()\n        return prev\n      },\n      { marketArray: [], marketCoins: [], marketMap: {} } as any,\n    )\n  }\n\n  let { __timer__ } = store.getState().invest.stakingMap\n  __timer__ = (() => {\n    if (__timer__ && __timer__ !== -1) {\n      clearInterval(__timer__)\n    }\n    return setInterval(async () => {\n      if (!LoopringAPI.defiAPI) {\n        return undefined\n      }\n      store.dispatch(getStakingMap(undefined))\n    }, 900000) //15*60*1000 //900000\n  })()\n\n  return {\n    stakingMap: {\n      ...result,\n    },\n    __timer__,\n  }\n}\n\nexport function* getPostsSaga() {\n  try {\n    const { stakingMap, __timer__ } = yield call(getStakingMapApi)\n    yield put(getStakingMapStatus({ ...stakingMap, __timer__ }))\n  } catch (err) {\n    yield put(getStakingMapStatus({ error: err }))\n  }\n}\n\nexport function* getDefiSyncSaga({ payload }: PayloadAction<{ stakingMap: StakingMap }>) {\n  try {\n    if (payload.stakingMap) {\n      yield put(getStakingMapStatus({ ...payload.stakingMap }))\n    }\n  } catch (err) {\n    yield put(getStakingMapStatus({ error: err }))\n  }\n}\n\nexport function* stakingMapInitSaga() {\n  yield all([takeLatest(getStakingMap, getPostsSaga)])\n}\n\nexport function* stakingMapSyncSaga() {\n  // @ts-ignore\n  yield all([takeLatest(updateStakingSyncMap, getDefiSyncSaga)])\n}\n\nexport const stakingMapFork = [fork(stakingMapInitSaga), fork(stakingMapSyncSaga)]\n"
  },
  {
    "path": "packages/core/src/stores/invest/VaultMap/hook.ts",
    "content": "import { useDispatch } from 'react-redux'\nimport React from 'react'\nimport { store } from '../../index'\nimport { getVaultMap, statusUnset } from './reducer'\nimport { VaultMap, VaultMapStates } from './interface'\n\nexport const useVaultMap = (): VaultMapStates & {\n  getVaultMap: () => void\n  statusUnset: () => void\n  updateVaultSyncMap: (props: { vaultMap: VaultMap }) => void\n} => {\n  const vaultMap: VaultMapStates = store.getState().invest.vaultMap\n  //useSelector((state: RootState) => state.invest.vaultMap)\n  const dispatch = useDispatch()\n  return {\n    ...vaultMap,\n    statusUnset: React.useCallback(() => dispatch(statusUnset(undefined)), [dispatch]),\n    getVaultMap: React.useCallback(() => {\n      return dispatch(getVaultMap(undefined))\n    }, [dispatch]),\n    updateVaultSyncMap: React.useCallback(\n      ({ vaultMap }: { vaultMap: VaultMap }) => dispatch(getVaultMap(vaultMap)),\n      [dispatch],\n    ),\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/invest/VaultMap/index.ts",
    "content": "export * from './hook'\nexport * as vaultReducer from './reducer'\nexport * from './interface'\n"
  },
  {
    "path": "packages/core/src/stores/invest/VaultMap/interface.ts",
    "content": "import { CoinKey, CoinMap, StateBase, VaultMarketExtends } from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { LoopringMap, TokenAddress } from '@loopring-web/loopring-sdk'\n\nexport type VaultUIMap = VaultMarketExtends\nexport type VaultMap<\n  R = {\n    [key: string]: any\n  },\n> = {\n  erc20Array: string[]\n  marketArray: string[]\n  marketCoins: string[]\n  tokenPrices: sdk.LoopringMap<string>\n  marketMap: sdk.LoopringMap<VaultUIMap & { wsMarket: string }>\n  tradeMap: sdk.LoopringMap<{ tokenId: number; tradePairs: string[] }>\n  coinMap: CoinMap<any>\n  // pairs: sdk.LoopringMap<sdk.TokenRelatedInfo>\n  joinTokenMap: sdk.LoopringMap<sdk.VaultToken>\n  idIndex: LoopringMap<number>\n  addressIndex: sdk.LoopringMap<TokenAddress>\n  tokenMap: sdk.LoopringMap<\n    sdk.VaultToken & {\n      tradePairs: Array<CoinKey<R>>\n    }\n  >\n  erc20Map: sdk.LoopringMap<sdk.VaultToken>\n}\n\nexport type VaultMapStates = VaultMap & {\n  __timer__?: number\n} & StateBase\n"
  },
  {
    "path": "packages/core/src/stores/invest/VaultMap/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { VaultMapStates } from './interface'\nimport { SagaStatus } from '@loopring-web/common-resources'\n\nconst initialState: Required<VaultMapStates> = {\n  marketArray: [],\n  marketCoins: [],\n  erc20Array: [],\n  erc20Map: {},\n  marketMap: {},\n  tradeMap: {},\n  tokenMap: {},\n  coinMap: {},\n  idIndex: {},\n  tokenPrices: {},\n  joinTokenMap: {},\n  addressIndex: {},\n  __timer__: -1,\n  status: SagaStatus.PENDING,\n  errorMessage: null,\n}\nconst vaultMapSlice: Slice = createSlice({\n  name: 'vaultMap',\n  initialState,\n  reducers: {\n    getVaultMap(state, _action: PayloadAction<undefined>) {\n      state.status = SagaStatus.PENDING\n    },\n    getVaultMapStatus(state, action: PayloadAction<VaultMapStates & { raw_data?: any }>) {\n      // @ts-ignore\n      if (action.payload.error) {\n        state.status = SagaStatus.ERROR\n      } else {\n        const vaultMap = action.payload\n        if (vaultMap) {\n          state.marketArray = vaultMap.marketArray\n          state.marketCoins = vaultMap.marketCoins\n          state.marketMap = vaultMap.marketMap\n          state.tradeMap = vaultMap.tradeMap\n          state.coinMap = vaultMap.coinMap\n          state.idIndex = vaultMap.idIndex\n          state.addressIndex = vaultMap.addressIndex\n          state.tokenMap = vaultMap.tokenMap\n          state.joinTokenMap = vaultMap.joinTokenMap\n          state.erc20Array = vaultMap.erc20Array\n          state.erc20Map = vaultMap.erc20Map\n          state.tokenPrices = vaultMap?.tokenPrices ?? {}\n          state.raw_data = vaultMap?.raw_data ?? undefined\n        }\n\n        state.status = SagaStatus.DONE\n      }\n      if (action.payload.__timer__) {\n        state.__timer__ = action.payload.__timer__\n      }\n    },\n    updateVaultSyncMap(state, _action: PayloadAction<VaultMapStates>) {\n      state.status = SagaStatus.PENDING\n    },\n    statusUnset: (state) => {\n      state.status = SagaStatus.UNSET\n    },\n  },\n})\nconst { getVaultMap, updateVaultSyncMap, getVaultMapStatus, statusUnset } = vaultMapSlice.actions\nexport { vaultMapSlice, getVaultMap, getVaultMapStatus, statusUnset, updateVaultSyncMap }\n"
  },
  {
    "path": "packages/core/src/stores/invest/VaultMap/saga.ts",
    "content": "import { all, call, fork, put, takeLatest } from 'redux-saga/effects'\nimport { getVaultMap, getVaultMapStatus, updateVaultSyncMap } from './reducer'\nimport { store } from '../../index'\nimport { LoopringAPI } from '../../../api_wrapper'\nimport { PayloadAction } from '@reduxjs/toolkit'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { LocalStorageConfigKey, myLog } from '@loopring-web/common-resources'\nimport { makeVault } from '../../../hooks'\nimport { VaultMap } from './interface'\nconst getVaultMapApi = async () => {\n  if (!LoopringAPI.vaultAPI) {\n    return undefined\n  }\n  const { chainId } = store.getState().system\n  const vaultMapStorage = window.localStorage.getItem(LocalStorageConfigKey.vaultMarkets)\n  const vaultTokenMapStorage = window.localStorage.getItem(LocalStorageConfigKey.vaultTokenMap)\n  let { __timer__ } = store.getState().invest.vaultMap\n\n  if (__timer__) {\n    clearTimeout(__timer__)\n  }\n  __timer__ = setTimeout(async () => {\n    if (!LoopringAPI.defiAPI) {\n      return undefined\n    }\n    store.dispatch(getVaultMap(undefined))\n  }, 30 * 1000)\n\n  try {\n    const [tokenMapRaw, marketRaw] = await Promise.all([\n      LoopringAPI.vaultAPI.getVaultTokens('1').then((response) => {\n        if (\n          !response ||\n          (response as sdk.RESULT_INFO).code ||\n          (response as sdk.RESULT_INFO).message\n        ) {\n          throw (response as sdk.RESULT_INFO).message\n        } else {\n          let tokenListRaw = response.tokens\n          if (tokenListRaw) {\n            localStorage.setItem(\n              LocalStorageConfigKey.vaultTokenMap,\n              JSON.stringify({\n                ...(vaultTokenMapStorage ? JSON.parse(vaultTokenMapStorage) : {}),\n                [chainId]: tokenListRaw,\n              }),\n            )\n          }\n          return tokenListRaw.map(token => ({\n            ...token,\n            type: 'Vault'\n          }))\n          \n        }\n      }),\n      LoopringAPI.vaultAPI.getVaultMarkets('1').then((response) => {\n        if (\n          !response ||\n          (response as sdk.RESULT_INFO).code ||\n          (response as sdk.RESULT_INFO).message\n        ) {\n          throw (response as sdk.RESULT_INFO).message\n        } else {\n          let marketsRaw: any[] = response.markets\n          localStorage.setItem(\n            LocalStorageConfigKey.vaultMarkets,\n            JSON.stringify({\n              ...(vaultMapStorage ? JSON.parse(vaultMapStorage) : {}),\n              [chainId]: marketsRaw,\n            }),\n          )\n          // @ts-ignore\n          return response.markets as sdk.VaultMarket[]\n        }\n      }),\n    ])\n\n    const result = makeVault(tokenMapRaw as sdk.VaultToken[], marketRaw)\n    const tokenPrices = await LoopringAPI.vaultAPI\n      .getVaultPrice({ tokenIds: Reflect.ownKeys(result.idIndex) })\n      .then((response: any) => {\n        if (\n          !response ||\n          (response as sdk.RESULT_INFO).code ||\n          (response as sdk.RESULT_INFO).message\n        ) {\n          throw (response as sdk.RESULT_INFO).message\n        } else {\n          return response?.list?.reduce((prev, item) => {\n            return { ...prev, [item.symbol]: item.price }\n          }, {})\n        }\n      })\n    return {\n      ...result,\n      tokenPrices,\n      raw_data: {\n        tokenMapRaw,\n        marketRaw,\n      },\n      __timer__\n    }\n  } catch (error) {\n    throw error\n  }\n}\n\nexport function* getPostsSaga() {\n  try {\n    const { __timer__, ...vaultMap } = yield call(getVaultMapApi)\n    yield put(getVaultMapStatus({ ...vaultMap, __timer__ }))\n  } catch (err) {\n    myLog('getVaultMapStatus', err)\n    yield put(getVaultMapStatus({ error: (err as any)?.e, __timer__: (err as any)?.__timer__ }))\n  }\n}\n\nexport function* getVaultSyncSaga({ payload }: PayloadAction<{ vaultMap: VaultMap }>) {\n  try {\n    if (payload.vaultMap) {\n      yield put(getVaultMapStatus({ ...payload.vaultMap }))\n    }\n  } catch (err) {\n    yield put(getVaultMapStatus({ error: err }))\n  }\n}\n\nexport function* VaultMapInitSaga() {\n  yield all([takeLatest(getVaultMap, getPostsSaga)])\n}\n\nexport function* VaultMapSyncSaga() {\n  // @ts-ignore\n  yield all([takeLatest(updateVaultSyncMap, getVaultSyncSaga)])\n}\n\nexport const vaultMapFork = [fork(VaultMapInitSaga), fork(VaultMapSyncSaga)]\n"
  },
  {
    "path": "packages/core/src/stores/invest/VaultTicker/hook.ts",
    "content": "import { useDispatch, useSelector } from 'react-redux'\nimport { getVaultTickers, statusUnset, updateVaultTicker } from './reducer'\nimport { VaultTickerStates } from './interface'\nimport React from 'react'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nexport function useVaultTicker(): VaultTickerStates & {\n  updateVaultTickers: () => void\n  updateVaultTickerSync: (item: sdk.DatacenterTokenQuote) => void\n  statusUnset: () => void\n} {\n  const vaultTickerMap: VaultTickerStates = useSelector((state: any) => state.invest.vaultTickerMap)\n  const dispatch = useDispatch()\n  return {\n    ...vaultTickerMap,\n    statusUnset: React.useCallback(() => dispatch(statusUnset(undefined)), [dispatch]),\n    updateVaultTickers: React.useCallback(() => dispatch(getVaultTickers({})), [dispatch]),\n    updateVaultTickerSync: React.useCallback(\n      (item: sdk.DatacenterTokenQuote) => dispatch(updateVaultTicker(item)),\n      [dispatch],\n    ),\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/invest/VaultTicker/index.ts",
    "content": "export * from './hook'\nexport * from './interface'\nexport * as vaultTickerReducer from './reducer'\n"
  },
  {
    "path": "packages/core/src/stores/invest/VaultTicker/interface.ts",
    "content": "import { StateBase, TickerNew } from '@loopring-web/common-resources'\n\nexport type VaultTickerMap<R = { [key: string]: any }> = {\n  [key in keyof R]: TickerNew\n}\nexport type VaultTickerStates<C = { [key: string]: any }> = {\n  vaultTickerMap: VaultTickerMap<C>\n  __timer__?: number\n} & StateBase\n"
  },
  {
    "path": "packages/core/src/stores/invest/VaultTicker/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { VaultTickerStates } from './interface'\nimport { SagaStatus } from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nconst initialState: Required<VaultTickerStates> = {\n  vaultTickerMap: {},\n  __timer__: -1,\n  status: SagaStatus.PENDING,\n  errorMessage: null,\n}\nconst vaultTickerMapSlice: Slice = createSlice({\n  name: 'vaultTickerMap',\n  initialState,\n  reducers: {\n    resetVaultTicker(state) {\n      if (state.__timer__ !== -1) {\n        clearTimeout(state.__timer__)\n        state.__timer__ = -1\n      }\n      state.vaultTickerMap = {}\n      state.status = SagaStatus.UNSET\n    },\n    updateVaultTicker(\n      state,\n      _action: PayloadAction<sdk.LoopringMap<sdk.DatacenterTokenInfoSimple>>,\n    ) {\n      state.status = SagaStatus.PENDING\n    },\n    getVaultTickers(state) {\n      state.status = SagaStatus.PENDING\n    },\n    getVaultTickerStatus(state, action: PayloadAction<VaultTickerStates>) {\n      // @ts-ignore\n      if (action.error) {\n        state.status = SagaStatus.ERROR\n        // @ts-ignore\n        state.errorMessage = action.error\n      }\n      const { vaultTickerMap, __timer__ } = action.payload\n      if (vaultTickerMap) {\n        state.vaultTickerMap = vaultTickerMap\n      }\n      if (__timer__) {\n        state.__timer__ = __timer__\n      }\n      state.status = SagaStatus.DONE\n    },\n    statusUnset: (state) => {\n      state.status = SagaStatus.UNSET\n    },\n  },\n})\nexport { vaultTickerMapSlice }\nexport const { updateVaultTicker, getVaultTickers, getVaultTickerStatus, statusUnset } =\n  vaultTickerMapSlice.actions\n"
  },
  {
    "path": "packages/core/src/stores/invest/VaultTicker/saga.ts",
    "content": "import { all, call, fork, put, takeLatest } from 'redux-saga/effects'\nimport { getVaultTickers, getVaultTickerStatus, updateVaultTicker } from './reducer'\nimport { myLog } from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { PayloadAction } from '@reduxjs/toolkit'\nimport { store } from '../../index'\nimport { LoopringAPI } from '../../../api_wrapper'\nimport { makeTokenTickerMap, makeTokenTickerView } from '../../../hooks'\nimport { values } from 'lodash'\n\nconst getVaultTickersApi = async (): Promise<{\n  data: object | undefined\n  __timer__: NodeJS.Timer | -1\n}> => {\n  const {\n    invest,\n  } = store.getState()\n  let {\n    vaultTickerMap,\n    vaultMap: { tokenMap: vaultTokenMap },\n  } = invest\n  let { __timer__ } = vaultTickerMap\n  if (LoopringAPI.exchangeAPI) {\n    __timer__ = ((__timer__) => {\n      if (__timer__ && __timer__ !== -1) {\n        clearTimeout(__timer__)\n      }\n      return setTimeout(() => {\n        store.dispatch(getVaultTickers({}))\n      }, 1000 * 60 * 5)\n    })(__timer__)\n    const vaultTickers = await LoopringAPI.exchangeAPI.getSupportTokens({\n      cmcTokenIds: values(vaultTokenMap).map(token => token.cmcTokenId),\n      currency: 'USD',\n    })\n    //@ts-ignore\n    const data = makeTokenTickerMap({ rawData: vaultTickers.list, isVault: true })\n    return { data, __timer__ }\n  } else {\n    if (__timer__ && __timer__ !== -1) {\n      clearTimeout(__timer__)\n    }\n    return { data: {}, __timer__: -1 }\n  }\n}\n\nfunction* getPostsSaga() {\n  try {\n    const { data, __timer__ } = yield call(getVaultTickersApi)\n    yield put(getVaultTickerStatus({ vaultTickerMap: data, __timer__ }))\n  } catch (err) {\n    yield put(getVaultTickerStatus({ error: err }))\n  }\n}\n\nfunction* vaultTickerMakeMap({ payload }: PayloadAction<sdk.DatacenterTokenInfoSimple>) {\n  try {\n    const { invest } = store.getState()\n    let { vaultTickerMap } = invest\n    const data = makeTokenTickerView({ item: payload, isVault: true })\n    yield put(\n      getVaultTickerStatus({\n        vaultTickerMap: { ...vaultTickerMap, ...{ [payload?.symbol as any]: data } },\n      }),\n    )\n  } catch (err) {\n    myLog('err', err)\n    yield put(getVaultTickerStatus(err))\n  }\n}\n\nfunction* vaultTickersSaga() {\n  yield all([takeLatest(getVaultTickers, getPostsSaga)])\n}\n\nfunction* vaultTickerSyncSaga() {\n  // @ts-ignore\n  yield all([takeLatest(updateVaultTicker, vaultTickerMakeMap)])\n}\n\nexport const vaultTickerForks = [fork(vaultTickerSyncSaga), fork(vaultTickersSaga)]\n"
  },
  {
    "path": "packages/core/src/stores/invest/index.ts",
    "content": "import { combineReducers } from '@reduxjs/toolkit'\n\nimport { defiMapFork } from './DefiMap/saga'\nimport { btradeMapFork } from './BtradeMap/saga'\n\nimport * as defiReducer from './DefiMap/reducer'\nimport * as stakingSlice from './StakingMap/reducer'\nimport * as btradeSlice from './BtradeMap/reducer'\nimport * as vaultSlice from './VaultMap/reducer'\nimport * as vaultTickerMapSlice from './VaultTicker/reducer'\nimport * as investTokenTypeMapReducer from './InvestTokenTypeMap/reducer'\nimport { investTokenTypeForks } from './InvestTokenTypeMap/saga'\nimport { dualReducer } from './DualMap'\nimport { dualMapFork } from './DualMap/saga'\nimport { stakingMapFork } from './StakingMap/saga'\nimport { vaultMapFork } from './VaultMap/saga'\nimport { vaultTickerForks } from './VaultTicker/saga'\n\nexport const investReducer = combineReducers({\n  defiMap: defiReducer.defiMapSlice.reducer,\n  dualMap: dualReducer.dualMapSlice.reducer,\n  stakingMap: stakingSlice.stakingMapSlice.reducer,\n  investTokenTypeMap: investTokenTypeMapReducer.investTokenTypeMapSlice.reducer,\n  btradeMap: btradeSlice.btradeMapSlice.reducer,\n  vaultMap: vaultSlice.vaultMapSlice.reducer,\n  vaultTickerMap: vaultTickerMapSlice.vaultTickerMapSlice.reducer,\n})\nexport const investForks = [\n  ...defiMapFork,\n  ...investTokenTypeForks,\n  ...dualMapFork,\n  ...stakingMapFork,\n  ...btradeMapFork,\n  ...vaultMapFork,\n  ...vaultTickerForks,\n]\n\nexport * from './DefiMap'\nexport * from './DualMap'\nexport * from './InvestTokenTypeMap'\nexport * from './StakingMap'\nexport * from './BtradeMap'\nexport * from './VaultMap'\nexport * from './VaultTicker'\n"
  },
  {
    "path": "packages/core/src/stores/localStore/coinbaseSmartWalletPersist/hook.ts",
    "content": "import { useDispatch, useSelector } from 'react-redux'\nimport { persistStoreCoinbaseSmartWalletData } from './reducer'\nimport React from 'react'\nimport { RootState } from '../../index'\nimport { CoinbaseSmartWalletPersist, CoinbaseSmartWalletPersistData } from './interface'\n\nexport function useCoinbaseSmartWalletPersist() {\n  const state: CoinbaseSmartWalletPersist = useSelector(\n    (state: RootState) => state.localStore.coinbaseSmartWalletPersist,\n  )\n  // const [shouldShow,setShouldShow] = React.useState(account._userOnModel)\n  const dispatch = useDispatch()\n\n  return {\n    ...state,\n    persistStoreCoinbaseSmartWalletData: React.useCallback(\n      (data: CoinbaseSmartWalletPersistData) => {\n        dispatch(persistStoreCoinbaseSmartWalletData(data))\n      },\n      [dispatch],\n    ),\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/localStore/coinbaseSmartWalletPersist/index.ts",
    "content": "import coinbaseSmartWalletPersistSlice from './reducer'\nexport { persistStoreCoinbaseSmartWalletData } from './reducer'\nexport { useCoinbaseSmartWalletPersist } from './hook'\nexport { coinbaseSmartWalletPersistSlice }\n"
  },
  {
    "path": "packages/core/src/stores/localStore/coinbaseSmartWalletPersist/interface.ts",
    "content": "import { ChainId } from \"@loopring-web/loopring-sdk\";\n\nexport interface CoinbaseSmartWalletPersist {\n  data: CoinbaseSmartWalletPersistData[]\n}\n\nexport interface CoinbaseSmartWalletPersistData {\n  wallet: string;\n  eddsaKey: {\n    sk: string;\n    formatedPx: string;\n    formatedPy: string;\n    keyPair: {\n      publicKeyX: string;\n      publicKeyY: string;\n      secretKey: string;\n    };\n  };\n  nonce: number\n  chainId: ChainId\n  updateAccountData: {\n    updateAccountNotFinished: boolean\n    json: string\n  }\n  eddsaKeyBackup: {\n    backupNotFinished: boolean\n    json: string\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/localStore/coinbaseSmartWalletPersist/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { SliceCaseReducers } from '@reduxjs/toolkit/src/createSlice'\nimport { CoinbaseSmartWalletPersist, CoinbaseSmartWalletPersistData } from './interface'\n\nconst initialState: CoinbaseSmartWalletPersist = {\n  data: []\n} \n\nconst coinbaseSmartWalletPersistSlice: Slice<CoinbaseSmartWalletPersist> = createSlice<\n  CoinbaseSmartWalletPersist,\n  SliceCaseReducers<CoinbaseSmartWalletPersist>\n>({\n  name: 'coinbaseSmartWalletPersist',\n  initialState: initialState,\n  reducers: {\n    persistStoreCoinbaseSmartWalletData(state, action: PayloadAction<CoinbaseSmartWalletPersistData>) {\n      const filtered = state.data.filter((item) => !(item.chainId === action.payload.chainId && item.wallet === action.payload.wallet))\n      state.data = [...filtered, action.payload]\n    },\n  },\n})\nexport default coinbaseSmartWalletPersistSlice\nexport const {\n  persistStoreCoinbaseSmartWalletData,\n} = coinbaseSmartWalletPersistSlice.actions\n"
  },
  {
    "path": "packages/core/src/stores/localStore/confirmation/hook.ts",
    "content": "import React from 'react'\nimport { useDispatch, useSelector } from 'react-redux'\nimport { RootState } from '../../index'\nimport { Confirmation } from './interface'\n\nimport {\n  confirm,\n  confirmedRETHDefiInvest,\n  confirmedWSETHDefiInvest,\n  showDualBeginnerHelp,\n  hidDualBeginnerHelp,\n  confirmedLRCStakeInvest,\n  confirmedBtradeSwap,\n  confirmDualInvestV2,\n  confirmDualAutoInvest,\n  confirmedLeverageETHInvest,\n  confirmDualDipInvest,\n  confirmDualGainInvest,\n  setShowRETHStakePopup,\n  setShowWSTETHStakePopup,\n  setShowLRCStakePopup,\n  setShowLeverageETHPopup,\n  setShowAutoDefault,\n  setConfirmedOpenVaultPosition,\n  setShowTaikoLaunchBanner,\n  setShowTaikoLockDescription,\n  setShowTaikoLaunchBanner2,\n  setShowVaultTradeHint,\n} from './reducer'\nimport { DualInvestConfirmType } from '@loopring-web/common-resources'\n\nexport const useConfirmation = (): {\n  confirmation: Confirmation\n  confirmWrapper: () => void\n  confirmedRETHDefiInvest: () => void\n  confirmedWSETHDefiInvest: () => void\n  confirmedLRCStakeInvest: () => void\n  confirmDualInvest: (level: DualInvestConfirmType | undefined) => void\n  confirmDualAutoInvest: () => void\n  confirmedBtradeSwap: () => void\n  confirmedLeverageETHInvest: () => void\n  confirmDualDipInvest: () => void\n  confirmDualGainInvest: () => void\n  setShowRETHStakePopup: (data: { isShow: boolean; confirmationNeeded: boolean }) => void\n  setShowWSTETHStakePopup: (data: { isShow: boolean; confirmationNeeded: boolean }) => void\n  setShowLRCStakePopup: (data: { isShow: boolean; confirmationNeeded: boolean }) => void\n  setShowLeverageETHPopup: (data: { isShow: boolean; confirmationNeeded: boolean }) => void\n  setShowAutoDefault: (show: boolean) => void\n  setConfirmedOpenVaultPosition: () => void\n  setShowTaikoLaunchBanner: (show: boolean) => void\n  setShowTaikoLockDescription: (show: boolean) => void\n  setShowTaikoLaunchBanner2: (show: boolean) => void\n  setShowVaultTradeHint: (show: boolean) => void\n} => {\n  const confirmation: Confirmation = useSelector(\n    (state: RootState) => state.localStore.confirmation,\n  )\n  const dispatch = useDispatch()\n\n  return {\n    confirmation,\n    confirmWrapper: React.useCallback(() => {\n      dispatch(confirm(undefined))\n    }, [dispatch]),\n    confirmDualInvest: React.useCallback(\n      (level: DualInvestConfirmType | undefined) => {\n        dispatch(confirmDualInvestV2({ level }))\n        dispatch(showDualBeginnerHelp(undefined))\n        setTimeout(() => {\n          dispatch(hidDualBeginnerHelp(undefined))\n        }, 5 * 1000)\n      },\n      [dispatch],\n    ),\n    confirmedRETHDefiInvest: React.useCallback(() => {\n      dispatch(confirmedRETHDefiInvest(undefined))\n    }, [dispatch]),\n    confirmedWSETHDefiInvest: React.useCallback(() => {\n      dispatch(confirmedWSETHDefiInvest(undefined))\n    }, [dispatch]),\n    confirmedLRCStakeInvest: React.useCallback(() => {\n      dispatch(confirmedLRCStakeInvest(undefined))\n    }, [dispatch]),\n    confirmedBtradeSwap: React.useCallback(() => {\n      dispatch(confirmedBtradeSwap(undefined))\n    }, [dispatch]),\n    confirmedLeverageETHInvest: React.useCallback(() => {\n      dispatch(confirmedLeverageETHInvest(undefined))\n    }, [dispatch]),\n    confirmDualAutoInvest: React.useCallback(() => {\n      dispatch(confirmDualAutoInvest(undefined))\n    }, [dispatch]),\n    confirmDualDipInvest: React.useCallback(() => {\n      dispatch(confirmDualDipInvest(undefined))\n    }, [dispatch]),\n    confirmDualGainInvest: React.useCallback(() => {\n      dispatch(confirmDualGainInvest(undefined))\n    }, [dispatch]),\n    setShowRETHStakePopup: React.useCallback(\n      (data: { isShow: boolean; confirmationNeeded: boolean }) =>\n        dispatch(setShowRETHStakePopup(data)),\n      [dispatch],\n    ),\n    setShowWSTETHStakePopup: React.useCallback(\n      (data: { isShow: boolean; confirmationNeeded: boolean }) =>\n        dispatch(setShowWSTETHStakePopup(data)),\n      [dispatch],\n    ),\n    setShowLRCStakePopup: React.useCallback(\n      (data: { isShow: boolean; confirmationNeeded: boolean }) =>\n        dispatch(setShowLRCStakePopup(data)),\n      [dispatch],\n    ),\n    setShowLeverageETHPopup: React.useCallback(\n      (data: { isShow: boolean; confirmationNeeded: boolean }) =>\n        dispatch(setShowLeverageETHPopup(data)),\n      [dispatch],\n    ),\n    setShowAutoDefault: React.useCallback(\n      (show: boolean) => dispatch(setShowAutoDefault({ show })),\n      [dispatch],\n    ),\n    setConfirmedOpenVaultPosition: React.useCallback(() => {\n      dispatch(setConfirmedOpenVaultPosition(undefined))\n    }, [dispatch]),\n    setShowTaikoLaunchBanner: React.useCallback((show: boolean) => {\n      dispatch(setShowTaikoLaunchBanner({show}))\n    }, [dispatch]),\n    setShowTaikoLockDescription: React.useCallback((show: boolean) => {\n      dispatch(setShowTaikoLockDescription({show}))\n    }, [dispatch]),\n    setShowTaikoLaunchBanner2: React.useCallback((show: boolean) => {\n      dispatch(setShowTaikoLaunchBanner2({show}))\n    }, [dispatch]),\n    setShowVaultTradeHint: React.useCallback((show: boolean) => {\n      dispatch(setShowVaultTradeHint({show}))\n    }, [dispatch]),\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/localStore/confirmation/index.ts",
    "content": "export * from './hook'\nexport * from './reducer'\nexport * from './interface'\n"
  },
  {
    "path": "packages/core/src/stores/localStore/confirmation/interface.ts",
    "content": "import { DualInvestConfirmType } from '@loopring-web/common-resources'\n\nexport interface Confirmation {\n  confirmed: boolean\n  confirmedRETHDefiInvest: boolean\n  confirmedWSETHDefiInvest: boolean\n  // confirmedDualInvest: boolean\n  confirmedDualInvestV2: DualInvestConfirmType | undefined\n  confirmDualAutoInvest: boolean\n  showDualBeginnerHelp: boolean\n  confirmedLRCStakeInvest: boolean\n  confirmedBtradeSwap: boolean\n  confirmedLeverageETHInvest: boolean\n  confirmDualDipInvest: boolean\n  confirmDualGainInvest: boolean\n  showWSTETHStakePopup: boolean\n  showRETHStakePopup: boolean\n  showLRCStakePopup: boolean\n  showLeverageETHPopup: boolean\n  showAutoDefault: boolean\n  confirmationNeeded: boolean\n  confirmedOpenVaultPosition: boolean\n  showTaikoLaunchBanner: boolean\n  showTaikoLockDescription: boolean\n  showTaikoLaunchBanner2: boolean\n  showVaultTradeHint: boolean\n}\n"
  },
  {
    "path": "packages/core/src/stores/localStore/confirmation/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { SliceCaseReducers } from '@reduxjs/toolkit/src/createSlice'\nimport { Confirmation } from './interface'\nimport { DualInvestConfirmType } from '@loopring-web/common-resources'\n\nconst initialState: Confirmation = {\n  confirmed: false,\n  confirmedRETHDefiInvest: false,\n  confirmedWSETHDefiInvest: false,\n  confirmedDualInvestV2: undefined,\n  confirmDualAutoInvest: false,\n  confirmDualDipInvest: false,\n  confirmDualGainInvest: false,\n  confirmedLRCStakeInvest: false,\n  confirmedBtradeSwap: false,\n  confirmedLeverageETHInvest: false,\n  showDualBeginnerHelp: false,\n  showRETHStakePopup: false,\n  showWSTETHStakePopup: false,\n  showLRCStakePopup: false,\n  showLeverageETHPopup: false,\n  confirmationNeeded: true,\n  showAutoDefault: false,\n  confirmedOpenVaultPosition: false,\n  showTaikoLaunchBanner: true,\n  showTaikoLockDescription: true,\n  showTaikoLaunchBanner2: true,\n  showVaultTradeHint: true,\n}\n\nconst confirmationSlice: Slice<Confirmation> = createSlice<\n  Confirmation,\n  SliceCaseReducers<Confirmation>,\n  'confirmation'\n>({\n  name: 'confirmation',\n  initialState,\n  reducers: {\n    confirm(state: Confirmation, _action: PayloadAction<string>) {\n      state.confirmed = true\n    },\n    confirmedRETHDefiInvest(state: Confirmation, _action: PayloadAction<string>) {\n      state.confirmedRETHDefiInvest = true\n    },\n    confirmedWSETHDefiInvest(state: Confirmation, _action: PayloadAction<string>) {\n      state.confirmedWSETHDefiInvest = true\n    },\n    confirmedLRCStakeInvest(state: Confirmation, _action: PayloadAction<string>) {\n      state.confirmedLRCStakeInvest = true\n    },\n    confirmDualAutoInvest(state: Confirmation, _action: PayloadAction<undefined>) {\n      state.confirmDualAutoInvest = true\n    },\n    confirmDualDipInvest(state: Confirmation, _action: PayloadAction<undefined>) {\n      state.confirmDualDipInvest = true\n    },\n    confirmDualGainInvest(state: Confirmation, _action: PayloadAction<undefined>) {\n      state.confirmDualGainInvest = true\n    },\n    confirmDualInvestV2(\n      state: Confirmation,\n      _action: PayloadAction<{ level: DualInvestConfirmType | undefined }>,\n    ) {\n      state.confirmedDualInvestV2 = _action.payload?.level\n    },\n    confirmedBtradeSwap(state: Confirmation, _action: PayloadAction<string>) {\n      state.confirmedBtradeSwap = true\n    },\n    showDualBeginnerHelp(state: Confirmation, _action: PayloadAction<string>) {\n      state.showDualBeginnerHelp = true\n    },\n    hidDualBeginnerHelp(state: Confirmation, _action: PayloadAction<string>) {\n      state.showDualBeginnerHelp = false\n    },\n    confirmedLeverageETHInvest(state: Confirmation, _action: PayloadAction<string>) {\n      state.confirmedLeverageETHInvest = true\n    },\n    setShowRETHStakePopup(\n      state: Confirmation,\n      action: PayloadAction<{ isShow: boolean; confirmationNeeded: boolean }>,\n    ) {\n      state.showRETHStakePopup = action.payload.isShow\n      state.confirmationNeeded = action.payload.confirmationNeeded\n    },\n    setShowWSTETHStakePopup(\n      state: Confirmation,\n      action: PayloadAction<{ isShow: boolean; confirmationNeeded: boolean }>,\n    ) {\n      state.showWSTETHStakePopup = action.payload.isShow\n      state.confirmationNeeded = action.payload.confirmationNeeded\n    },\n    setShowLRCStakePopup(\n      state: Confirmation,\n      action: PayloadAction<{ isShow: boolean; confirmationNeeded: boolean }>,\n    ) {\n      state.showLRCStakePopup = action.payload.isShow\n      state.confirmationNeeded = action.payload.confirmationNeeded\n    },\n    setShowLeverageETHPopup(\n      state: Confirmation,\n      action: PayloadAction<{ isShow: boolean; confirmationNeeded: boolean }>,\n    ) {\n      state.showLeverageETHPopup = action.payload.isShow\n      state.confirmationNeeded = action.payload.confirmationNeeded\n    },\n    setShowAutoDefault(state: Confirmation, action: PayloadAction<{ show: boolean }>) {\n      state.showAutoDefault = action.payload.show\n    },\n    setConfirmedOpenVaultPosition(state: Confirmation, _: PayloadAction) {\n      state.confirmedOpenVaultPosition = true\n    },\n    setShowTaikoLaunchBanner(state: Confirmation, action: PayloadAction<{show: boolean}>) {\n      state.showTaikoLaunchBanner = action.payload.show\n    },\n    setShowTaikoLockDescription(state: Confirmation, action: PayloadAction<{show: boolean}>) {\n      state.showTaikoLockDescription = action.payload.show\n    },\n    setShowTaikoLaunchBanner2(state: Confirmation, action: PayloadAction<{show: boolean}>) {\n      state.showTaikoLaunchBanner2 = action.payload.show\n    },\n    setShowVaultTradeHint(state: Confirmation, action: PayloadAction<{show: boolean}>) {\n      state.showVaultTradeHint = action.payload.show\n    },\n  },\n})\n\nexport { confirmationSlice }\nexport const {\n  confirm,\n  confirmedRETHDefiInvest,\n  confirmedWSETHDefiInvest,\n  confirmedLRCStakeInvest,\n  confirmDualDipInvest,\n  confirmDualGainInvest,\n  confirmDualAutoInvest,\n  confirmDualInvestV2,\n  confirmedBtradeSwap,\n  showDualBeginnerHelp,\n  hidDualBeginnerHelp,\n  confirmedLeverageETHInvest,\n  setShowRETHStakePopup,\n  setShowWSTETHStakePopup,\n  setShowLRCStakePopup,\n  setShowLeverageETHPopup,\n  setShowAutoDefault,\n  setConfirmedOpenVaultPosition,\n  setShowTaikoLaunchBanner,\n  setShowTaikoLockDescription,\n  setShowTaikoLaunchBanner2,\n  setShowVaultTradeHint,\n} = confirmationSlice.actions\n"
  },
  {
    "path": "packages/core/src/stores/localStore/favoriteMarket/hook.ts",
    "content": "import { useDispatch, useSelector } from 'react-redux'\nimport { FavoriteMarketStates } from './interface'\nimport { addMarket, addMarkets, clearAll, removeMarket } from './reducer'\nimport React from 'react'\n\nexport const useFavoriteMarket = (): {\n  favoriteMarket: FavoriteMarketStates\n  clearAll: () => void\n  removeMarket: (pair: string) => void\n  addMarket: (pair: string) => void\n  addMarkets: (pair: string[]) => void\n} => {\n  const favoriteMarket: FavoriteMarketStates = useSelector(\n    (state: any) => state.localStore.favoriteMarket,\n  )\n  const dispatch = useDispatch()\n  return {\n    favoriteMarket: favoriteMarket,\n    clearAll: React.useCallback(() => dispatch(clearAll(undefined)), [dispatch]),\n    removeMarket: React.useCallback((pair) => dispatch(removeMarket(pair)), [dispatch]),\n    addMarket: React.useCallback((pair) => dispatch(addMarket(pair)), [dispatch]),\n    addMarkets: React.useCallback((pairs) => dispatch(addMarkets(pairs)), [dispatch]),\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/localStore/favoriteMarket/index.ts",
    "content": "export * from './hook'\nexport * from './interface'\nexport * from './reducer'\n"
  },
  {
    "path": "packages/core/src/stores/localStore/favoriteMarket/interface.ts",
    "content": "export type FavoriteMarketStates = string[]\n"
  },
  {
    "path": "packages/core/src/stores/localStore/favoriteMarket/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { FavoriteMarketStates } from './interface'\nimport { SliceCaseReducers } from '@reduxjs/toolkit/src/createSlice'\n\nconst favoriteMarketSlice: Slice<FavoriteMarketStates> = createSlice<\n  FavoriteMarketStates,\n  SliceCaseReducers<FavoriteMarketStates>,\n  'favoriteMarket'\n>({\n  name: 'favoriteMarket',\n  initialState: [],\n  reducers: {\n    clearAll(state: FavoriteMarketStates, _action: PayloadAction<undefined>) {\n      state.length = 0\n    },\n    removeMarket(state: FavoriteMarketStates, action: PayloadAction<string>) {\n      const pair = action.payload\n      if (pair && state.includes(pair)) {\n        const index = state.findIndex((_pair) => _pair === pair)\n        state.splice(index, 1)\n      }\n    },\n    addMarket(state: FavoriteMarketStates, action: PayloadAction<string>) {\n      const pair = action.payload\n      if (pair && state.findIndex((_pair: string) => _pair === pair) === -1) {\n        state.push(pair)\n      }\n    },\n    addMarkets(state: FavoriteMarketStates, action: PayloadAction<string[]>) {\n      const pairs = action.payload\n      if (pairs.length) {\n        pairs.forEach((pair) => {\n          if (pair && state.findIndex((_pair: string) => _pair === pair) === -1) {\n            state.push(pair)\n          }\n        })\n      }\n    },\n  },\n})\nexport { favoriteMarketSlice }\nexport const { clearAll, removeMarket, addMarket, addMarkets } = favoriteMarketSlice.actions\n"
  },
  {
    "path": "packages/core/src/stores/localStore/favoriteVaultMarket/hook.ts",
    "content": "import { useDispatch, useSelector } from 'react-redux'\nimport { addMarket, addMarkets, clearAll, removeMarket } from './reducer'\nimport React from 'react'\nimport { FavoriteMarketStates } from '../favoriteMarket'\n\nexport const useFavoriteVaultMarket = (): {\n  favoriteMarket: FavoriteMarketStates\n  clearAll: () => void\n  removeMarket: (pair: string) => void\n  addMarket: (pair: string) => void\n  addMarkets: (pair: string[]) => void\n} => {\n  const favoriteMarket: FavoriteMarketStates = useSelector(\n    (state: any) => state.localStore.favoriteVaultMarket,\n  )\n  const dispatch = useDispatch()\n  return {\n    favoriteMarket: favoriteMarket,\n    clearAll: React.useCallback(() => dispatch(clearAll(undefined)), [dispatch]),\n    removeMarket: React.useCallback((pair) => dispatch(removeMarket(pair)), [dispatch]),\n    addMarket: React.useCallback((pair) => dispatch(addMarket(pair)), [dispatch]),\n    addMarkets: React.useCallback((pairs) => dispatch(addMarkets(pairs)), [dispatch]),\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/localStore/favoriteVaultMarket/index.ts",
    "content": "export * from './hook'\nexport * from './reducer'\n"
  },
  {
    "path": "packages/core/src/stores/localStore/favoriteVaultMarket/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice, SliceCaseReducers } from '@reduxjs/toolkit'\nimport { FavoriteMarketStates } from '../favoriteMarket'\n\nconst favoriteVaultMarketSlice: Slice<FavoriteMarketStates> = createSlice<\n  FavoriteMarketStates,\n  SliceCaseReducers<FavoriteMarketStates>,\n  'favoriteVaultMarket'\n>({\n  name: 'favoriteVaultMarket',\n  initialState: [],\n  reducers: {\n    clearAll(state: FavoriteMarketStates, _action: PayloadAction<undefined>) {\n      state.length = 0\n    },\n    removeMarket(state: FavoriteMarketStates, action: PayloadAction<string>) {\n      const pair = action.payload\n      if (pair && state.includes(pair)) {\n        const index = state.findIndex((_pair) => _pair === pair)\n        state.splice(index, 1)\n      }\n    },\n    addMarket(state: FavoriteMarketStates, action: PayloadAction<string>) {\n      const pair = action.payload\n      if (pair && state.findIndex((_pair: string) => _pair === pair) === -1) {\n        state.push(pair)\n      }\n    },\n    addMarkets(state: FavoriteMarketStates, action: PayloadAction<string[]>) {\n      const pairs = action.payload\n      if (pairs.length) {\n        pairs.forEach((pair) => {\n          if (pair && state.findIndex((_pair: string) => _pair === pair) === -1) {\n            state.push(pair)\n          }\n        })\n      }\n    },\n  },\n})\nexport { favoriteVaultMarketSlice }\nexport const { clearAll, removeMarket, addMarket, addMarkets } = favoriteVaultMarketSlice.actions\n"
  },
  {
    "path": "packages/core/src/stores/localStore/index.ts",
    "content": "import { combineReducers } from '@reduxjs/toolkit'\nimport { confirmationSlice } from './confirmation'\nimport { favoriteMarketSlice } from './favoriteMarket'\nimport { OnChainHashInfoSlice } from './onchainHashInfo'\nimport { walletInfoSlice } from './walletInfo'\nimport { tradeProSettingsSlice } from './tradeProSettings'\nimport { layer1ActionHistorySlice } from './layer1Store'\nimport { NFTHashInfoSlice } from './nftRefresh'\nimport { redPacketHistorySlice } from './redPacket'\nimport { offRampHistorySlice } from './offRamp'\nimport { favoriteVaultMarketSlice } from './favoriteVaultMarket'\nimport { coinbaseSmartWalletPersistSlice } from './coinbaseSmartWalletPersist'\n\nexport const localStoreReducer = combineReducers({\n  favoriteMarket: favoriteMarketSlice.reducer,\n  chainHashInfos: OnChainHashInfoSlice.reducer,\n  confirmation: confirmationSlice.reducer,\n  walletInfo: walletInfoSlice.reducer,\n  tradeProSettings: tradeProSettingsSlice.reducer,\n  layer1ActionHistory: layer1ActionHistorySlice.reducer,\n  nftHashInfos: NFTHashInfoSlice.reducer,\n  redPacketHistory: redPacketHistorySlice.reducer,\n  offRampHistory: offRampHistorySlice.reducer,\n  favoriteVaultMarket: favoriteVaultMarketSlice.reducer,\n  coinbaseSmartWalletPersist: coinbaseSmartWalletPersistSlice.reducer,\n})\n\nexport * as confirmation from './confirmation'\nexport * as favoriteMarket from './favoriteMarket'\nexport * as favoriteVaultMarket from './favoriteVaultMarket'\nexport * as layer1Store from './layer1Store'\nexport * as onchainHashInfo from './onchainHashInfo'\nexport * as nftRefresh from './nftRefresh'\nexport * as tradeProSettings from './tradeProSettings'\nexport * as walletInfo from './walletInfo'\nexport * as redPacketHistory from './redPacket'\nexport * as offRampHistory from './offRamp'\nexport * as coinbaseSmartWalletPersist from './coinbaseSmartWalletPersist'\n"
  },
  {
    "path": "packages/core/src/stores/localStore/layer1Store/hook.ts",
    "content": "import { useDispatch, useSelector } from 'react-redux'\nimport { Layer1ActionHistory } from '@loopring-web/common-resources'\nimport { ChainId } from '@loopring-web/loopring-sdk'\nimport { circleUpdateLayer1ActionHistory, clearOneItem, setOneItem } from './reducer'\n\nexport const useLayer1Store = (): {\n  layer1ActionHistory: {\n    [ChainId.MAINNET]: Layer1ActionHistory\n    [ChainId.GOERLI]: Layer1ActionHistory\n    [ChainId.SEPOLIA]: Layer1ActionHistory\n    [ChainId.TAIKOHEKLA]: Layer1ActionHistory\n    [ChainId.TAIKO]: Layer1ActionHistory\n    [ChainId.BASE]: Layer1ActionHistory\n    [ChainId.BASESEPOLIA]: Layer1ActionHistory\n  }\n  setOneItem: (props: { domain: string; uniqueId: string; chainId?: ChainId }) => void\n  clearOneItem: (props: { domain: string; uniqueId: string; chainId?: ChainId }) => void\n  circleUpdateLayer1ActionHistory: (props: { chainId?: ChainId }) => void\n} => {\n  const { chainId } = useSelector((state: any) => state.system)\n\n  const layer1ActionHistory = useSelector((state: any) => state.localStore.layer1ActionHistory)\n\n  const dispatch = useDispatch()\n\n  return {\n    layer1ActionHistory,\n    setOneItem: (props: { domain: string; uniqueId: string; chainId?: ChainId }) =>\n      dispatch(setOneItem({ ...props, chainId: props.chainId ?? chainId })),\n    clearOneItem: (props: { domain: string; uniqueId: string; chainId?: ChainId }) =>\n      dispatch(clearOneItem({ ...props, chainId: props.chainId ?? chainId })),\n    circleUpdateLayer1ActionHistory: (props: { chainId?: ChainId }) =>\n      dispatch(circleUpdateLayer1ActionHistory({ chainId: props.chainId ?? chainId })),\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/localStore/layer1Store/index.ts",
    "content": "export * from './hook'\nexport * from './reducer'\n"
  },
  {
    "path": "packages/core/src/stores/localStore/layer1Store/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { SliceCaseReducers } from '@reduxjs/toolkit/src/createSlice'\nimport { LAYER1_ACTION_HISTORY, Layer1ActionHistory } from '@loopring-web/common-resources'\nimport { ChainId } from '@loopring-web/loopring-sdk'\n\n// @ts-ignore\nconst initialState: LAYER1_ACTION_HISTORY = {\n  [ChainId.GOERLI]: {},\n  [ChainId.MAINNET]: {},\n  [ChainId.SEPOLIA]: {},\n  [ChainId.TAIKOHEKLA]: {},\n  [ChainId.TAIKO]: {},\n  [ChainId.BASE]: {},\n  [ChainId.BASESEPOLIA]: {},\n  __timer__: -1,\n}\n\nconst layer1ActionHistorySlice: Slice<LAYER1_ACTION_HISTORY> = createSlice<\n  LAYER1_ACTION_HISTORY,\n  SliceCaseReducers<LAYER1_ACTION_HISTORY>,\n  'layer1ActionHistory'\n>({\n  name: 'layer1ActionHistory',\n  initialState,\n  reducers: {\n    circleUpdateLayer1ActionHistory(\n      // @ts-ignore\n      state,\n      // @ts-ignore\n      action: PayloadAction<{ chainId: string }>,\n    ) {},\n    layer1ActionHistoryStatus(\n      state,\n      action: PayloadAction<\n        {\n          chainId: string\n          __timer__: NodeJS.Timeout\n        } & Layer1ActionHistory\n      >,\n    ) {\n      const { chainId, __timer__, layer1ActionHistory } = action.payload\n      // @ts-ignore\n      if (action.error) {\n        // @ts-ignore\n        state.errorMessage = action.error\n      }\n      state.__timer__ = __timer__\n\n      state[chainId] = { ...layer1ActionHistory } //{...state.amountMap, ...action.payload.amountMap};\n    },\n    clearOneItem(\n      state,\n      action: PayloadAction<{\n        domain: string\n        uniqueId: string\n        chainId: ChainId\n      }>,\n    ) {\n      const { domain, uniqueId, chainId } = action.payload\n      try {\n        if (state[chainId] && state[chainId][domain] && state[chainId][domain][uniqueId]) {\n          // Reflect.ownKeys(state[chainId][domain]).findIndex()\n          delete state[chainId][domain][uniqueId]\n        }\n      } catch (e) {}\n    },\n    setOneItem(\n      state,\n      action: PayloadAction<{\n        domain: string\n        uniqueId: string\n        chainId: ChainId\n      }>,\n    ) {\n      const { domain, uniqueId, chainId } = action.payload\n      if (state[chainId]) {\n        state[chainId][domain] = {\n          ...state[chainId][domain],\n          [uniqueId]: Date.now(),\n        }\n      } \n    },\n  },\n})\n\nexport { layer1ActionHistorySlice }\nexport const {\n  clearOneItem,\n  circleUpdateLayer1ActionHistory,\n  layer1ActionHistoryStatus,\n  setOneItem,\n} = layer1ActionHistorySlice.actions\n"
  },
  {
    "path": "packages/core/src/stores/localStore/layer1Store/saga.ts",
    "content": "import { all, call, fork, put, takeLatest } from 'redux-saga/effects'\nimport { circleUpdateLayer1ActionHistory, layer1ActionHistoryStatus } from './reducer'\nimport { PayloadAction } from '@reduxjs/toolkit'\nimport { store } from '../../index'\nimport { ChainId } from '@loopring-web/loopring-sdk'\n\nconst updateLayer1ActionHistory = async <_R extends { [key: string]: any }>({\n  chainId,\n}: {\n  chainId: ChainId\n}) => {\n  let { __timer__, ...layer1ActionHistory } = store.getState().localStore.layer1ActionHistory\n  const now = Date.now()\n  let _layer1ActionHistory = {}\n  if (layer1ActionHistory[chainId]) {\n    Reflect.ownKeys(layer1ActionHistory[chainId]).map((item) => {\n      if (layer1ActionHistory[chainId][item as string]) {\n        // _layer1ActionHistory = _.cloneDeep(layer1ActionHistory[chainId][item]);\n        _layer1ActionHistory[item] = Reflect.ownKeys(\n          layer1ActionHistory[chainId][item as string],\n        ).reduce((prev, unit) => {\n          if (\n            unit &&\n            now - 1800000 < layer1ActionHistory[chainId][item as string][unit] //1800000\n          ) {\n            prev[unit] = layer1ActionHistory[chainId][item as string][unit]\n            return prev\n          }\n          return prev\n        }, {})\n      }\n    })\n  }\n  __timer__ = (() => {\n    if (__timer__ && __timer__ !== -1) {\n      clearInterval(__timer__)\n    }\n    return setInterval(() => {\n      const chainId = store.getState().system.chainId\n      store.dispatch(circleUpdateLayer1ActionHistory({ chainId }))\n    }, 300000) //5*60*1000 //300000\n  })()\n  return { layer1ActionHistory: _layer1ActionHistory, __timer__, chainId }\n}\n\nexport function* getPostsSaga({ payload }: PayloadAction<{ chainId: ChainId }>) {\n  try {\n    const { __timer__, chainId, layer1ActionHistory } = yield call(updateLayer1ActionHistory, {\n      chainId: payload.chainId,\n    })\n    yield put(layer1ActionHistoryStatus({ layer1ActionHistory, __timer__, chainId }))\n  } catch (err) {\n    yield put(layer1ActionHistoryStatus({ error: err }))\n  }\n}\n\nfunction* Layer1Saga() {\n  // @ts-ignore\n  yield all([takeLatest(circleUpdateLayer1ActionHistory, getPostsSaga)])\n}\n\nexport const layer1ActionHistoryForks = [fork(Layer1Saga)]\n"
  },
  {
    "path": "packages/core/src/stores/localStore/nftRefresh/hook.ts",
    "content": "import { useDispatch, useSelector } from 'react-redux'\nimport { NFTHashInfo, NFTHashInfos } from '@loopring-web/common-resources'\nimport { clearNFTRefreshHash, updateNFTRefreshHash } from './reducer'\n\nexport const useNFTRefresh = (): {\n  nftDataHashes: NFTHashInfo\n  clearNFTRefreshHash: (nftData: string) => void\n  updateNFTRefreshHash: (nftData: string) => void\n} => {\n  const { chainId } = useSelector((state: any) => state.system)\n\n  const nftDataHashes: NFTHashInfos = useSelector((state: any) => state.localStore.nftHashInfos)\n\n  const dispatch = useDispatch()\n\n  return {\n    nftDataHashes: nftDataHashes[chainId],\n    clearNFTRefreshHash: (nftData: string) => {\n      dispatch(clearNFTRefreshHash({ chainId, nftData }))\n    },\n    updateNFTRefreshHash: (nftData: string) => {\n      dispatch(updateNFTRefreshHash({ chainId, nftData }))\n    },\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/localStore/nftRefresh/index.ts",
    "content": "export * from './hook'\nexport * from './reducer'\n"
  },
  {
    "path": "packages/core/src/stores/localStore/nftRefresh/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { SliceCaseReducers } from '@reduxjs/toolkit/src/createSlice'\nimport { NFTHashInfos, TxInfo } from '@loopring-web/common-resources'\nimport { ChainId } from '@loopring-web/loopring-sdk'\n\nconst initialState: NFTHashInfos = {\n  [ChainId.GOERLI]: { nftDataHashes: {} },\n  [ChainId.MAINNET]: { nftDataHashes: {} },\n  [ChainId.SEPOLIA]: { nftDataHashes: {} },\n  [ChainId.TAIKOHEKLA]: { nftDataHashes: {} },\n  [ChainId.TAIKO]: { nftDataHashes: {} },\n  [ChainId.BASE]: { nftDataHashes: {} },\n  [ChainId.BASESEPOLIA]: { nftDataHashes: {} },\n  // withdrawHashes:{},\n}\n\nconst NFTHashInfoSlice: Slice<NFTHashInfos> = createSlice<\n  NFTHashInfos,\n  SliceCaseReducers<NFTHashInfos>,\n  'nftHashInfos'\n>({\n  name: 'nftHashInfos',\n  initialState,\n  reducers: {\n    // @ts-ignore\n    clearAll(state: NFTHashInfos, _action: PayloadAction<undefined>) {\n      state = { ...initialState }\n    },\n    clearNFTRefreshHash(\n      state: NFTHashInfos,\n      action: PayloadAction<{ nftData: string; chainId: ChainId }>,\n    ) {\n      const { nftData, chainId } = action.payload\n      if (nftData && state[chainId].nftDataHashes[nftData]) {\n        delete state[chainId].nftDataHashes[nftData]\n      } else {\n        state[chainId].nftDataHashes = {}\n      }\n    },\n    updateNFTRefreshHash(\n      state: NFTHashInfos,\n      action: PayloadAction<{\n        nftData: string\n        chainId: ChainId\n      }>,\n    ) {\n      const { nftData, chainId } = action.payload\n      if (!state[chainId] || !state[chainId].nftDataHashes) {\n        state[chainId] = { ...state[chainId], nftDataHashes: {} }\n      }\n      if (state[chainId].nftDataHashes[nftData.toLowerCase()]) {\n        const _timestamp = Date.now()\n        const _txInfo: Required<TxInfo> = state[chainId].nftDataHashes[nftData.toLowerCase()]\n        if (_timestamp >= _txInfo.timestamp + 30 * 60 * 1000) {\n          delete state[chainId].nftDataHashes[nftData.toLowerCase()]\n        }\n      } else {\n        const txInfo: Required<TxInfo> = {\n          status: 'pending',\n          timestamp: Date.now(),\n          hash: nftData,\n        }\n\n        state[chainId].nftDataHashes = {\n          ...state[chainId].nftDataHashes,\n          [nftData.toLowerCase()]: txInfo,\n        }\n      }\n    },\n  },\n})\n\nexport { NFTHashInfoSlice }\nexport const { clearAll, clearNFTRefreshHash, updateNFTRefreshHash } = NFTHashInfoSlice.actions\n"
  },
  {
    "path": "packages/core/src/stores/localStore/offRamp/hook.ts",
    "content": "import { useDispatch, useSelector } from 'react-redux'\nimport { clearAll, clearOffRampHash, updateOffRampHash } from './reducer'\nimport React from 'react'\nimport { OffRampHashInfos, OffRampHashItem } from '@loopring-web/common-resources'\n\nexport const useRedPacketHistory = (): {\n  redPacketHistory: OffRampHashInfos\n  clearAll: () => void\n  clearOffRampHash: () => void\n  updateOffRampHash: (props: OffRampHashItem) => void\n} => {\n  const redPacketHistory: OffRampHashInfos = useSelector(\n    (state: any) => state.localStore.redPacketHistory,\n  )\n  const dispatch = useDispatch()\n  return {\n    redPacketHistory: redPacketHistory,\n    clearAll: React.useCallback(() => dispatch(clearAll(undefined)), [dispatch]),\n    clearOffRampHash: React.useCallback(() => dispatch(clearOffRampHash(undefined)), [dispatch]),\n    updateOffRampHash: React.useCallback(\n      (prosp: OffRampHashItem) => dispatch(updateOffRampHash(prosp)),\n      [dispatch],\n    ),\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/localStore/offRamp/index.ts",
    "content": "export * from './hook'\nexport * from './reducer'\n"
  },
  {
    "path": "packages/core/src/stores/localStore/offRamp/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { SliceCaseReducers } from '@reduxjs/toolkit/src/createSlice'\nimport {\n  ChainHashInfos,\n  OffRampHashInfos,\n  OffRampHashItem,\n  OffRampStatus,\n} from '@loopring-web/common-resources'\nimport { ChainId } from '@loopring-web/loopring-sdk'\n\nconst initialState: OffRampHashInfos = {\n  [ChainId.GOERLI]: {},\n  [ChainId.SEPOLIA]: {},\n  [ChainId.MAINNET]: {},\n  [ChainId.TAIKOHEKLA]: {},\n  [ChainId.TAIKO]: {},\n  [ChainId.BASE]: {},\n  [ChainId.BASESEPOLIA]: {},\n  // withdrawHashes:{},\n}\nconst offRampHistorySlice: Slice<OffRampHashInfos> = createSlice<\n  OffRampHashInfos,\n  SliceCaseReducers<any>,\n  'offRampHistory'\n>({\n  name: 'offRampHistory',\n  initialState,\n  reducers: {\n    // @ts-ignore\n    clearAll(state: OffRampHashInfos, _action: PayloadAction<undefined>) {\n      state = { ...initialState }\n    },\n    // clearOffRampHash(\n    //   state: OffRampHashInfos,\n    //   _action: PayloadAction<undefined>\n    // ) {\n    //   function make(state: OffRampHashInfos, chainId: string) {\n    //     return Reflect.ownKeys(state[chainId]).reduce(\n    //       (prev, address) => {\n    //         if (state[chainId][address.toString()]) {\n    //         }\n    //         return prev;\n    //       },\n    //\n    //       {} as OffRampHashInfo\n    //     );\n    //   }\n    //\n    //   state = {\n    //     [ChainId.GOERLI]: make(state, ChainId.GOERLI.toString()),\n    //     [ChainId.MAINNET]: make(state, ChainId.MAINNET.toString()),\n    //   };\n    // },\n    updateOffRampHash(state: ChainHashInfos, action: PayloadAction<OffRampHashItem>) {\n      const { orderId, product, status, address, chainId } = action.payload\n      if (!state[chainId] || !state[chainId][address]) {\n        state[chainId] = { ...state[chainId], [address]: {} }\n      }\n      let productObj: any = { pending: undefined, payments: [] }\n      switch (status) {\n        case OffRampStatus.cancel:\n        case OffRampStatus.done:\n        case OffRampStatus.expired:\n        case OffRampStatus.refund:\n          if (state[chainId][address][product]) {\n            if (\n              state[chainId][address][product].pending?.orderId.toString() == orderId.toString()\n            ) {\n              state[chainId][address][product].pending = undefined\n            } else {\n              state[chainId][address][product].payments?.filter(\n                (_item: OffRampHashInfos) => _item?.orderId.toString() == orderId.toString(),\n              )\n            }\n          }\n          break\n        case OffRampStatus.waitingForWithdraw:\n          if (state[chainId][address][product]) {\n            let pending,\n              prev: any = undefined\n            if (\n              state[chainId][address][product]?.pending?.orderId.toString() !== orderId.toString()\n            ) {\n              pending = state[chainId][address][product]?.pending\n            } else {\n              pending = undefined\n              prev = state[chainId][address][product]?.pending\n            }\n\n            productObj = {\n              pending,\n              payments: [\n                ...(state[chainId][address][product]?.payments ?? undefined),\n                { ...prev, ...action.payload },\n              ],\n            }\n          } else {\n            productObj = {\n              pending: undefined,\n              payments: [{ ...action.payload }],\n            }\n          }\n          state[chainId] = {\n            ...state[chainId],\n            [address]: {\n              ...state[chainId][address],\n              [product]: productObj,\n            },\n          }\n          break\n        case OffRampStatus.watingForCreateOrder:\n          if (\n            state[chainId][address][product]?.payments &&\n            state[chainId][address][product]?.payments.find(\n              (_item: OffRampHashInfos) => _item?.orderId.toString() == orderId.toString(),\n            )\n          ) {\n            productObj = state[chainId][address][product]\n          } else {\n            let pending\n            if (\n              state[chainId][address][product]?.pending?.orderId.toString() == orderId.toString()\n            ) {\n              pending = state[chainId][address][product]?.pending\n            }\n            productObj = {\n              pending: { ...pending, ...action.payload },\n              payments: [...(state[chainId][address][product]?.payments ?? [])],\n            }\n          }\n          state[chainId] = {\n            ...state[chainId],\n            [address]: {\n              ...state[chainId][address],\n              [product]: productObj,\n            },\n          }\n          break\n      }\n    },\n  },\n})\nexport { offRampHistorySlice }\nexport const { clearAll, clearOffRampHash, updateOffRampHash } = offRampHistorySlice.actions\n"
  },
  {
    "path": "packages/core/src/stores/localStore/onchainHashInfo/hook.ts",
    "content": "import React from 'react'\nimport { useDispatch, useSelector } from 'react-redux'\nimport { ChainHashInfos, SagaStatus, TxInfo } from '@loopring-web/common-resources'\nimport {\n  clearAll,\n  clearDepositHash,\n  clearVaultBorrowHash,\n  updateDepositHash,\n  updateHadUnknownCollection,\n  updateVaultBorrowHash,\n} from './reducer'\nimport { updateWalletLayer1 } from '../../walletLayer1/reducer'\nimport { updateWalletLayer2 } from '../../walletLayer2/reducer'\nimport { WalletLayer1States } from '../../walletLayer1'\nimport { updateVaultLayer2 } from '../../vaultLayer2/reducer'\n\nexport const useOnChainInfo = () => {\n  const { chainId } = useSelector((state: any) => state.system)\n\n  const chainInfos: ChainHashInfos = useSelector((state: any) => state.localStore.chainHashInfos)\n\n  const walletLayer1: WalletLayer1States = useSelector((state: any) => state.walletLayer1)\n\n  const dispatch = useDispatch()\n\n  const clearAllWrapper = React.useCallback(() => {\n    dispatch(clearAll(undefined))\n  }, [dispatch])\n\n  return {\n    chainInfos: chainInfos[chainId],\n    clearAllWrapper,\n    clearDepositHash: React.useCallback(\n      (accountAddress?: string) => {\n        dispatch(clearDepositHash({ chainId, accountAddress }))\n      },\n      [dispatch, chainId],\n    ),\n    updateDepositHash: React.useCallback(\n      (\n        depositHash: string,\n        accountAddress: string,\n        status?: 'success' | 'failed',\n        args?: { [key: string]: any },\n      ) => {\n        // accountAddress\n        const props: { txInfo: TxInfo; accountAddress: string } = {\n          txInfo: {\n            hash: depositHash,\n            status,\n            ...args,\n            // reason:'activeAccount'|'regular'|'reset'\n          },\n          accountAddress,\n        }\n        if (\n          status === 'success' &&\n          walletLayer1.status !== SagaStatus.PENDING\n          // && chainInfos.depositHashes[ accountAddress ].find(ele => ele.hash === depositHash && ele.status == 'pending')\n        ) {\n          dispatch(updateWalletLayer1(undefined))\n          dispatch(updateWalletLayer2(undefined))\n        }\n        dispatch(updateDepositHash({ ...props, chainId }))\n      },\n      [dispatch, walletLayer1.status],\n    ),\n    updateHadUnknownCollection: React.useCallback(\n      (props: { accountAddress: string }) => {\n        dispatch(updateHadUnknownCollection({ ...props, chainId }))\n      },\n      [dispatch, walletLayer1.status],\n    ),\n    updateVaultBorrowHash: React.useCallback(\n      (\n        vaultBorrowHash: string,\n        accountAddress: string,\n        status?: 'success' | 'failed',\n        args?: { [key: string]: any },\n      ) => {\n        // accountAddress\n        const props: { txInfo: TxInfo; accountAddress: string } = {\n          txInfo: {\n            hash: vaultBorrowHash,\n            status,\n            ...args,\n            // reason:'activeAccount'|'regular'|'reset'\n          },\n          accountAddress,\n        }\n        if (\n          status === 'success' &&\n          walletLayer1.status !== SagaStatus.PENDING\n          // && chainInfos.depositHashes[ accountAddress ].find(ele => ele.hash === depositHash && ele.status == 'pending')\n        ) {\n          dispatch(updateVaultLayer2(undefined))\n        }\n        dispatch(updateVaultBorrowHash({ ...props, chainId }))\n      },\n      [dispatch, walletLayer1.status],\n    ),\n    clearVaultBorrowHash: React.useCallback(\n      (accountAddress?: string) => {\n        dispatch(clearVaultBorrowHash({ chainId, accountAddress }))\n      },\n      [dispatch, chainId],\n    ),\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/localStore/onchainHashInfo/index.ts",
    "content": "export * from './hook'\nexport * from './reducer'\n"
  },
  {
    "path": "packages/core/src/stores/localStore/onchainHashInfo/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { SliceCaseReducers } from '@reduxjs/toolkit/src/createSlice'\nimport { ChainHashInfos, NetworkMap, TxInfo } from '@loopring-web/common-resources'\nimport { ChainId } from '@loopring-web/loopring-sdk'\n\nconst OnChainHashInfoSlice: Slice<ChainHashInfos> = createSlice<\n  ChainHashInfos,\n  SliceCaseReducers<ChainHashInfos>,\n  'chainHashInfos'\n>({\n  name: 'chainHashInfos',\n  initialState: Reflect.ownKeys(NetworkMap).reduce((prev, item) => {\n    prev[NetworkMap[item]?.chainId] = {\n      depositHashes: {},\n      vaultBorrowHashes: {},\n      showHadUnknownCollection: {},\n    }\n    return prev\n  }, {}),\n  reducers: {\n    // @ts-ignore\n    clearAll(state: ChainHashInfos, _action: PayloadAction<undefined>) {\n      state = {\n        ...Reflect.ownKeys(NetworkMap).reduce((prev, item) => {\n          prev[NetworkMap[item]?.chainId] = {\n            depositHashes: {},\n            vaultBorrowHashes: {},\n            showHadUnknownCollection: {},\n          }\n          return prev\n        }, {}),\n      }\n    },\n    clearDepositHash(\n      state: ChainHashInfos,\n      action: PayloadAction<{ accountAddress?: string; chainId: ChainId }>,\n    ) {\n      const { accountAddress, chainId } = action.payload\n      if (accountAddress && state[chainId].depositHashes) {\n        state[chainId].depositHashes[accountAddress] = []\n      } else {\n        state[chainId].depositHashes = {}\n      }\n    },\n    clearWithdrawHash(_state: ChainHashInfos) {\n      // state[chainId].withdrawHashes = {}\n    },\n    updateHadUnknownCollection(\n      state: ChainHashInfos,\n      action: PayloadAction<{\n        accountAddress: string\n        chainId: ChainId\n      }>,\n    ) {\n      const { accountAddress, chainId } = action.payload\n      if (!state[chainId] || !state[chainId].showHadUnknownCollection) {\n        state[chainId] = {\n          ...state[chainId],\n          showHadUnknownCollection: {},\n        }\n      }\n      if (accountAddress) {\n        state[chainId].showHadUnknownCollection = {\n          ...state[chainId].showHadUnknownCollection,\n          [accountAddress]: true,\n        }\n      }\n    },\n\n    updateDepositHash(\n      state: ChainHashInfos,\n      action: PayloadAction<{\n        txInfo: TxInfo\n        accountAddress: string\n        chainId: ChainId\n      }>,\n    ) {\n      const { txInfo, accountAddress, chainId } = action.payload\n      if (!state[chainId] || !state[chainId].depositHashes) {\n        state[chainId] = {\n          ...state[chainId],\n          depositHashes: {},\n        }\n      }\n      if (accountAddress && txInfo) {\n        if (!txInfo.status) {\n          txInfo.status = 'pending'\n          txInfo.timestamp = Date.now()\n          state[chainId].depositHashes = {\n            [accountAddress]: state[chainId].depositHashes[accountAddress]\n              ? [...[txInfo], ...state[chainId].depositHashes[accountAddress]]\n              : [txInfo],\n          }\n        } else if (state[chainId].depositHashes[accountAddress]) {\n          const index = state[chainId].depositHashes[accountAddress].findIndex(\n            (item) => item.hash === txInfo.hash,\n          )\n          if (index !== -1) {\n            state[chainId].depositHashes[accountAddress][index] = {\n              ...state[chainId].depositHashes[accountAddress][index],\n              status: txInfo.status,\n            }\n          }\n        }\n\n        if (\n          state[chainId].depositHashes[accountAddress] &&\n          state[chainId].depositHashes[accountAddress].length > 5\n        ) {\n          state[chainId].depositHashes[accountAddress].length = 5\n        }\n      }\n    },\n    updateVaultBorrowHash(\n      state: ChainHashInfos,\n      action: PayloadAction<{\n        txInfo: TxInfo\n        accountAddress: string\n        chainId: ChainId\n      }>,\n    ) {\n      const { txInfo, accountAddress, chainId } = action.payload\n      if (!state[chainId] || !state[chainId]?.vaultBorrowHashes) {\n        state[chainId] = {\n          ...state[chainId],\n          vaultBorrowHashes: {},\n        }\n      }\n      if (accountAddress && txInfo) {\n        if (!txInfo.status) {\n          txInfo.status = 'pending'\n          txInfo.timestamp = Date.now()\n          state[chainId].vaultBorrowHashes = {\n            [accountAddress]: state[chainId].vaultBorrowHashes[accountAddress]\n              ? [...[txInfo], ...state[chainId].vaultBorrowHashes[accountAddress]]\n              : [txInfo],\n          }\n        }\n        if (\n          ['success', 'failed'].includes(txInfo.status) &&\n          state[chainId].vaultBorrowHashes[accountAddress]\n        ) {\n          state[chainId].vaultBorrowHashes[accountAddress] = state[chainId].vaultBorrowHashes[\n            accountAddress\n          ].filter((item) => item.hash !== txInfo.hash)\n        }\n      }\n    },\n    clearVaultBorrowHash(\n      state: ChainHashInfos,\n      action: PayloadAction<{ accountAddress?: string; chainId: ChainId }>,\n    ) {\n      const { accountAddress, chainId } = action.payload\n      if (accountAddress && state[chainId].vaultBorrowHashes) {\n        state[chainId].vaultBorrowHashes[accountAddress] = []\n      } else {\n        state[chainId].vaultBorrowHashes = {}\n      }\n    },\n  },\n})\n\nexport { OnChainHashInfoSlice }\nexport const {\n  clearAll,\n  clearDepositHash,\n  updateDepositHash,\n  clearWithdrawHash,\n  updateWithdrawHash,\n  updateHadUnknownCollection,\n  updateVaultBorrowHash,\n  clearVaultBorrowHash,\n} = OnChainHashInfoSlice.actions\n"
  },
  {
    "path": "packages/core/src/stores/localStore/redPacket/hook.ts",
    "content": "import { useDispatch, useSelector } from 'react-redux'\nimport {\n  clearAll,\n  clearRedPacketHash,\n  updateRedpacketHash,\n  updateRedpacketHashProps,\n} from './reducer'\nimport React from 'react'\nimport { RedPacketHashInfos } from '@loopring-web/common-resources'\n\nexport const useRedPacketHistory = (): {\n  redPacketHistory: RedPacketHashInfos\n  clearAll: () => void\n  clearRedPacketHash: () => void\n  updateRedpacketHash: (props: updateRedpacketHashProps) => void\n} => {\n  const redPacketHistory: RedPacketHashInfos = useSelector(\n    (state: any) => state.localStore.redPacketHistory,\n  )\n  const dispatch = useDispatch()\n  return {\n    redPacketHistory: redPacketHistory,\n    clearAll: React.useCallback(() => dispatch(clearAll(undefined)), [dispatch]),\n    clearRedPacketHash: React.useCallback(\n      () => dispatch(clearRedPacketHash(undefined)),\n      [dispatch],\n    ),\n    updateRedpacketHash: React.useCallback(\n      (prosp: updateRedpacketHashProps) => dispatch(updateRedpacketHash(prosp)),\n      [dispatch],\n    ),\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/localStore/redPacket/index.ts",
    "content": "export * from './hook'\nexport * from './reducer'\n"
  },
  {
    "path": "packages/core/src/stores/localStore/redPacket/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { SliceCaseReducers } from '@reduxjs/toolkit/src/createSlice'\nimport {\n  ChainHashInfos,\n  RedPacketHashInfo,\n  RedPacketHashInfos,\n  RedPacketHashItems,\n  TX_HASH,\n} from '@loopring-web/common-resources'\nimport { ChainId } from '@loopring-web/loopring-sdk'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nexport type updateRedpacketHashProps = {\n  hash: TX_HASH\n  luckToken: { validSince: number; hash: string }\n  chainId: sdk.ChainId\n  address: string\n  claimAmount: string\n  blindboxClaimed?: boolean\n}\nconst initialState: RedPacketHashInfos = {\n  [ChainId.GOERLI]: {},\n  [ChainId.SEPOLIA]: {},\n  [ChainId.MAINNET]: {},\n  [ChainId.TAIKOHEKLA]: {},\n  [ChainId.TAIKO]: {},\n  [ChainId.BASE]: {},\n  [ChainId.BASESEPOLIA]: {},\n  // withdrawHashes:{},\n}\nconst redPacketHistorySlice: Slice<RedPacketHashInfos> = createSlice<\n  RedPacketHashInfos,\n  SliceCaseReducers<any>,\n  'redPacketHistory'\n>({\n  name: 'redPacketHistory',\n  initialState,\n  reducers: {\n    // @ts-ignore\n    // clearAll(state: RedPacketHashInfos, _action: PayloadAction<undefined>) {\n    //   state = { ...initialState };\n    // },\n    clearRedPacketHash(state: RedPacketHashInfos, _action: PayloadAction<undefined>) {\n      function make(state: RedPacketHashInfos, chainId: string) {\n        return Reflect.ownKeys(state[chainId]).reduce(\n          (prev, address) => {\n            if (state[chainId][address.toString()]) {\n              let obj = state[chainId][address.toString()]\n              obj = Reflect.ownKeys(obj).reduce((_prev, hash) => {\n                const item = obj[hash.toString()]\n                if (\n                  item &&\n                  new Date(item.luckToken.validSince + 30 * 86400000).getTime() - Date.now() > 0\n                ) {\n                  _prev = { ..._prev, [hash]: item }\n                }\n                return _prev\n              }, {} as RedPacketHashItems)\n              if (Reflect.ownKeys(obj).length) {\n                prev = { ...prev, [address.toString()]: obj }\n              }\n            }\n            return prev\n          },\n\n          {} as RedPacketHashInfo,\n        )\n      }\n\n      state = {\n        [ChainId.GOERLI]: make(state, ChainId.GOERLI.toString()),\n        [ChainId.SEPOLIA]: make(state, ChainId.SEPOLIA.toString()),\n        [ChainId.MAINNET]: make(state, ChainId.MAINNET.toString()),\n        [ChainId.TAIKOHEKLA]: make(state, ChainId.TAIKOHEKLA.toString()),\n        [ChainId.TAIKO]: make(state, ChainId.TAIKO.toString()),\n        [ChainId.BASE]: make(state, ChainId.BASE.toString()),\n        [ChainId.BASESEPOLIA]: make(state, ChainId.BASESEPOLIA.toString()),\n      }\n    },\n    updateRedpacketHash(state: ChainHashInfos, action: PayloadAction<updateRedpacketHashProps>) {\n      const { hash, luckToken, claimAmount, address, chainId, blindboxClaimed } = action.payload\n      if (!state[chainId] || !state[chainId][address]) {\n        state[chainId] = { ...state[chainId], [address]: {} }\n      }\n      if (luckToken && hash) {\n        state[chainId] = {\n          ...state[chainId],\n          [address]: {\n            ...state[chainId][address],\n            [hash]: {\n              luckToken: {\n                validSince: luckToken.validSince,\n                hash: luckToken.hash,\n              },\n              claim: claimAmount,\n              blindboxClaimed: blindboxClaimed,\n            },\n          },\n        }\n      }\n    },\n  },\n})\nexport { redPacketHistorySlice }\nexport const { clearAll, clearRedPacketHash, updateRedpacketHash } = redPacketHistorySlice.actions\n"
  },
  {
    "path": "packages/core/src/stores/localStore/tradeProSettings/hook.ts",
    "content": "import React from 'react'\nimport { useDispatch, useSelector } from 'react-redux'\nimport { TradeProSettings } from './interface'\nimport { updateHideOtherPairs } from './reducer'\nimport { RootState } from '../../index'\n\nexport const useTradeProSettings = () => {\n  const tradeProSettings: TradeProSettings = useSelector(\n    (state: RootState) => state.localStore.tradeProSettings,\n  )\n  const dispatch = useDispatch()\n\n  const updateIsHideOtherPairs = React.useCallback(\n    ({ isHide }: { isHide: boolean }) => {\n      dispatch(updateHideOtherPairs({ isHide }))\n    },\n    [dispatch],\n  )\n\n  return {\n    tradeProSettings,\n    updateIsHideOtherPairs,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/localStore/tradeProSettings/index.ts",
    "content": "export * from './hook'\nexport * from './interface'\nexport * from './reducer'\n"
  },
  {
    "path": "packages/core/src/stores/localStore/tradeProSettings/interface.ts",
    "content": "export interface TradeProSettings {\n  hideOtherTradingPairs: boolean\n}\n"
  },
  {
    "path": "packages/core/src/stores/localStore/tradeProSettings/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { SliceCaseReducers } from '@reduxjs/toolkit/src/createSlice'\nimport { TradeProSettings } from './interface'\n\nconst initialState: TradeProSettings = {\n  hideOtherTradingPairs: false,\n}\n\nconst tradeProSettingsSlice: Slice<TradeProSettings> = createSlice<\n  TradeProSettings,\n  SliceCaseReducers<TradeProSettings>,\n  'tradeProSettings'\n>({\n  name: 'tradeProSettings',\n  initialState,\n  reducers: {\n    updateHideOtherPairs(state: TradeProSettings, action: PayloadAction<{ isHide: boolean }>) {\n      const tradeProSettings = action.payload\n      state.hideOtherTradingPairs = tradeProSettings.isHide\n    },\n  },\n})\n\nexport { tradeProSettingsSlice }\nexport const { updateHideOtherPairs } = tradeProSettingsSlice.actions\n"
  },
  {
    "path": "packages/core/src/stores/localStore/walletInfo/hook.ts",
    "content": "import React from 'react'\nimport { useDispatch, useSelector } from 'react-redux'\nimport { RootState } from '../../index'\nimport { WalletInfo } from './interface'\nimport { clearAll, updateWallet } from './reducer'\n\nexport const useWalletInfo = () => {\n  const walletInfo: WalletInfo = useSelector((state: RootState) => state.localStore.walletInfo)\n  const dispatch = useDispatch()\n\n  const clearAllWrapper = React.useCallback(() => {\n    dispatch(clearAll(undefined))\n  }, [dispatch])\n\n  const updateHW = React.useCallback(\n    ({ wallet, isHWAddr }: { wallet: string; isHWAddr: boolean }) => {\n      dispatch(updateWallet({ address: wallet, isHW: isHWAddr }))\n    },\n    [dispatch],\n  )\n\n  const checkHWAddr = React.useCallback(\n    (address: string) => {\n      if (!address) {\n        return false\n      }\n      const wInfo = walletInfo.walletTypeMap[address]\n      return !!wInfo\n    },\n    [walletInfo],\n  )\n\n  return {\n    checkHWAddr,\n    walletInfo,\n    clearAllWrapper,\n    updateHW,\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/localStore/walletInfo/index.ts",
    "content": "export * from './hook'\nexport * from './reducer'\nexport * from './interface'\n"
  },
  {
    "path": "packages/core/src/stores/localStore/walletInfo/interface.ts",
    "content": "export interface WalletInfo {\n  walletTypeMap: { [key: string]: boolean }\n}\n"
  },
  {
    "path": "packages/core/src/stores/localStore/walletInfo/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { SliceCaseReducers } from '@reduxjs/toolkit/src/createSlice'\nimport { WalletInfo } from './interface'\n\nconst initialState: WalletInfo = {\n  walletTypeMap: {},\n}\n\nconst walletInfoSlice: Slice<WalletInfo> = createSlice<\n  WalletInfo,\n  SliceCaseReducers<WalletInfo>,\n  'walletInfo'\n>({\n  name: 'walletInfo',\n  initialState,\n  reducers: {\n    clearAll(state: WalletInfo) {\n      state = initialState\n    },\n    updateWallet(_state: WalletInfo, _action: PayloadAction<{ address: string; isHW: boolean }>) {\n      // const walletInfo = action.payload\n      // state.walletTypeMap[walletInfo.address] = walletInfo.isHW\n    },\n  },\n})\n\nexport { walletInfoSlice }\nexport const { clearAll, updateWallet } = walletInfoSlice.actions\n"
  },
  {
    "path": "packages/core/src/stores/notify/hook.ts",
    "content": "import { useDispatch, useSelector } from 'react-redux'\nimport { getNotify, statusUnset, getUserNotify, restUerNotify } from './reducer'\nimport { NotifyStates } from './interface'\nimport React from 'react'\n\nexport function useNotify() {\n  const notifyMap: NotifyStates = useSelector((state: any) => state.notifyMap)\n  const dispatch = useDispatch()\n  return {\n    ...notifyMap,\n    restUserNotify: React.useCallback(() => dispatch(restUerNotify(undefined)), [dispatch]),\n    statusUnset: React.useCallback(() => dispatch(statusUnset(undefined)), [dispatch]),\n    getNotify: React.useCallback(() => dispatch(getNotify(undefined)), [dispatch]),\n    getUserNotify: React.useCallback(() => dispatch(getUserNotify(undefined)), [dispatch]),\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/notify/index.ts",
    "content": "export * from './hook'\nexport * from './interface'\nexport * as notifyReducer from './reducer'\n"
  },
  {
    "path": "packages/core/src/stores/notify/interface.ts",
    "content": "import { Notify, StateBase } from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\n/**\n * @notifyMap is only update\n */\nexport type NotifyStates = {\n  notifyMap: Notify | undefined\n  myNotifyMap: {\n    items: sdk.UserNotification[]\n    total: number | undefined\n    unReads: number | undefined\n  }\n} & StateBase\n"
  },
  {
    "path": "packages/core/src/stores/notify/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { NotifyStates } from './interface'\nimport { SagaStatus } from '@loopring-web/common-resources'\n\nconst initialState: NotifyStates = {\n  notifyMap: undefined,\n  myNotifyMap: {\n    items: [],\n    total: undefined,\n    unReads: undefined,\n  },\n  status: SagaStatus.PENDING,\n  errorMessage: null,\n}\n\nconst notifyMapSlice: Slice<NotifyStates> = createSlice({\n  name: 'notifyMap',\n  initialState,\n  reducers: {\n    restUerNotify(state) {\n      state.status = SagaStatus.DONE\n      state.myNotifyMap = initialState.myNotifyMap\n    },\n    getNotify(state, _action: PayloadAction<undefined>) {\n      state.status = SagaStatus.PENDING\n    },\n    getUserNotify(state, _action: PayloadAction<undefined>) {\n      state.status = SagaStatus.PENDING\n    },\n    getNotifyStatus(state, action: PayloadAction<NotifyStates>) {\n      // @ts-ignore\n      if (action.error) {\n        state.status = SagaStatus.ERROR\n        // @ts-ignoreis                                                  i\n        state.errorMessage = action.error\n      }\n      if (action.payload.notifyMap) {\n        state.notifyMap = action.payload.notifyMap\n      }\n      if (action.payload.myNotifyMap) {\n        state.myNotifyMap = action.payload.myNotifyMap\n      }\n      state.status = SagaStatus.DONE\n    },\n\n    statusUnset: (state) => {\n      state.status = SagaStatus.UNSET\n    },\n  },\n})\nexport { notifyMapSlice }\nexport const { restUerNotify, getNotify, getUserNotify, getNotifyStatus, statusUnset } =\n  notifyMapSlice.actions\n"
  },
  {
    "path": "packages/core/src/stores/notify/saga.ts",
    "content": "import { all, call, fork, put, takeLatest } from 'redux-saga/effects'\nimport { getNotify, getNotifyStatus, getUserNotify } from './reducer'\n\nimport { Lang, MapChainId, Notify, url_path, url_test_path } from '@loopring-web/common-resources'\nimport { store } from '../index'\nimport { LoopringAPI } from '../../api_wrapper'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nconst getNotifyApi = async <_R extends { [key: string]: any }>(): Promise<{\n  notifyMap: Notify\n}> => {\n  const lng = store.getState().settings.language\n  const baseURL = store.getState().system.baseURL\n  let notifyMap = {\n    activities: [],\n    notifications: [],\n    invest: [],\n  }\n\n  const path = `${/uat/gi.test(baseURL) ? url_test_path : url_path}`\n  const notify = await fetch(`${path}/notification.json`).then((response) => {\n    if (response.ok) {\n      return response.json()\n    } else {\n      return { prev: null }\n    }\n  })\n  return {\n    notifyMap: {\n      ...notifyMap,\n      ...notify['en'],\n      ...notify[Lang[lng]],\n      invest: notify.invest,\n      prev: { ...notify?.prev },\n    },\n  }\n}\n\nconst getNotifyUserApi = async () => {\n  const { accountId, apiKey } = store.getState().account\n  const { defaultNetwork } = store.getState().settings\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const networkWallet: sdk.NetworkWallet = [\n    sdk.NetworkWallet.ETHEREUM,\n    sdk.NetworkWallet.GOERLI,\n    sdk.NetworkWallet.SEPOLIA,\n  ].includes(network as sdk.NetworkWallet)\n    ? sdk.NetworkWallet.ETHEREUM\n    : sdk.NetworkWallet[network]\n  if (accountId && accountId !== -1 && apiKey && LoopringAPI.userAPI) {\n    const response = await LoopringAPI.userAPI?.getNotificationAll(\n      {\n        accountId: accountId,\n        offset: 0,\n        limit: 5,\n        network: networkWallet,\n        notRead: true,\n      },\n      apiKey,\n    )\n    if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n    } else {\n      //@ts-ignore\n      const { totalNum, notRead, notifications } = response\n      return {\n        myNotifyMap: {\n          items: notifications,\n          total: totalNum,\n          unReads: notRead,\n        },\n      }\n    }\n  }\n}\n\nexport function* getPostsSaga() {\n  try {\n    const { notifyMap } = yield call(getNotifyApi)\n    yield put(getNotifyStatus({ notifyMap }))\n  } catch (err) {\n    yield put(getNotifyStatus({ error: err }))\n  }\n}\n\nexport function* getPostsUserSaga() {\n  try {\n    const { myNotifyMap } = yield call(getNotifyUserApi)\n    yield put(getNotifyStatus({ myNotifyMap }))\n  } catch (err) {\n    yield put(getNotifyStatus({ error: err }))\n  }\n}\n\nfunction* notifyUserSaga() {\n  yield all([takeLatest(getNotify, getPostsSaga)])\n}\n\nfunction* notifySaga() {\n  yield all([takeLatest(getUserNotify, getPostsUserSaga)])\n}\n\nexport const notifyForks = [fork(notifySaga), fork(notifyUserSaga)]\n"
  },
  {
    "path": "packages/core/src/stores/redPacket/hook.ts",
    "content": "import { useDispatch, useSelector } from 'react-redux'\nimport { getRedPacketConfigs, statusUnset } from './reducer'\nimport { RedPacketConfigStates } from './interface'\nimport { CoinKey } from '@loopring-web/common-resources'\nimport React from 'react'\n\nexport function useRedPacketConfig(): RedPacketConfigStates & {\n  updateRedPacketConfigs: (tickerKeys: Array<CoinKey<any>>) => void\n  statusUnset: () => void\n} {\n  const redPacketConfigs = useSelector((state: any) => state.redPacketConfigs)\n  const dispatch = useDispatch()\n  return {\n    ...redPacketConfigs,\n    statusUnset: React.useCallback(() => dispatch(statusUnset(undefined)), [dispatch]),\n    updateRedPacketConfigs: React.useCallback(() => dispatch(getRedPacketConfigs({})), [dispatch]),\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/redPacket/index.ts",
    "content": "export * from './hook'\nexport * from './interface'\nexport * as tickerReducer from './reducer'\n"
  },
  {
    "path": "packages/core/src/stores/redPacket/interface.ts",
    "content": "import { StateBase } from '@loopring-web/common-resources'\n\nexport type RedPacketConfig = any\nexport type RedPacketConfigStates = {\n  redPacketConfigs: RedPacketConfig\n  __timer__?: number\n} & StateBase\n"
  },
  {
    "path": "packages/core/src/stores/redPacket/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { RedPacketConfigStates } from './interface'\nimport { CoinKey, SagaStatus } from '@loopring-web/common-resources'\n\nconst initialState: Required<RedPacketConfigStates> = {\n  redPacketConfigs: {},\n  __timer__: -1,\n  status: SagaStatus.PENDING,\n  errorMessage: null,\n}\nconst redPacketConfigsSlice: Slice = createSlice({\n  name: 'redPacketConfigs',\n  initialState,\n  reducers: {\n    getRedPacketConfigs(state, _action: PayloadAction<Array<CoinKey<any>>>) {\n      state.status = SagaStatus.PENDING\n    },\n    getRedPacketConfigsStatus(state, action: PayloadAction<RedPacketConfigStates>) {\n      // @ts-ignore\n      if (action.error) {\n        state.status = SagaStatus.ERROR\n        // @ts-ignore\n        state.errorMessage = action.error\n      }\n      const { redPacketConfigs, __timer__ } = action.payload\n      if (redPacketConfigs) {\n        state.redPacketConfigs = redPacketConfigs\n      }\n      if (__timer__) {\n        state.__timer__ = __timer__\n      }\n      state.status = SagaStatus.DONE\n    },\n    statusUnset: (state) => {\n      state.status = SagaStatus.UNSET\n    },\n  },\n})\nexport { redPacketConfigsSlice }\nexport const { getRedPacketConfigs, getRedPacketConfigsStatus, statusUnset } =\n  redPacketConfigsSlice.actions\n"
  },
  {
    "path": "packages/core/src/stores/redPacket/saga.ts",
    "content": "import { all, call, fork, put, takeLatest } from 'redux-saga/effects'\nimport { getRedPacketConfigs, getRedPacketConfigsStatus } from './reducer'\n\nimport { store, LoopringAPI } from '../../index'\n\nconst getRedPacketConfigsApi = async (): Promise<{\n  data: object | undefined\n  __timer__: NodeJS.Timer | -1\n}> => {\n  let { __timer__ } = store.getState().redPacketConfigs.__timer__\n  // let { redPacketConfigs } = store.getState().redpacketConfigs;\n\n  if (LoopringAPI.luckTokenAPI) {\n    __timer__ = ((__timer__) => {\n      if (__timer__ && __timer__ !== -1) {\n        clearTimeout(__timer__)\n      }\n      return setTimeout(() => {\n        store.dispatch(getRedPacketConfigs({}))\n      }, 1000 * 60 * 30)\n    })(__timer__)\n    const [resLuckTokenAgents, resLuckTokenAgentsAuth] = await Promise.all([\n      LoopringAPI.luckTokenAPI.getLuckTokenAgents(),\n      LoopringAPI.luckTokenAPI.getLuckTokenAuthorizedSigners(),\n    ])\n    const luckTokenAgents = resLuckTokenAgents?.luckTokenAgents\n    const luckTokenAgentsAuth = resLuckTokenAgentsAuth?.luckTokenAgents\n\n    return {\n      data: {\n        luckTokenAgents,\n        luckTokenAgentsAuth,\n      },\n      __timer__,\n    }\n  } else {\n    if (__timer__ && __timer__ !== -1) {\n      clearTimeout(__timer__)\n    }\n    return { data: {}, __timer__: -1 }\n  }\n}\n\nfunction* getPostsSaga() {\n  try {\n    const { data, __timer__ } = yield call(getRedPacketConfigsApi)\n    yield put(getRedPacketConfigsStatus({ redPacketConfigs: data, __timer__ }))\n  } catch (err) {\n    yield put(getRedPacketConfigsStatus({ error: err }))\n  }\n}\n\nfunction* redPacketConfigsInitSaga() {\n  yield all([takeLatest(getRedPacketConfigs, getPostsSaga)])\n}\n\nexport const redPacketConfigsSaga = [\n  fork(redPacketConfigsInitSaga),\n  // fork(tokenPairsSaga),\n]\n"
  },
  {
    "path": "packages/core/src/stores/rootSaga.ts",
    "content": "import { all } from 'redux-saga/effects'\nimport { tokenSaga } from './token/saga'\nimport { ammForks } from './Amm'\nimport { tickerForks } from './ticker/saga'\nimport { systemForks } from './system/saga'\nimport { walletLayer1Fork } from './walletLayer1/saga'\nimport { walletLayer2Fork } from './walletLayer2/saga'\nimport { userRewardsForks } from './userRewards/saga'\nimport { socketForks } from './socket/saga'\nimport { accountFork } from './account/saga'\nimport { amountForks } from './amount/saga'\nimport { tokenPricesSaga } from './tokenPrices/saga'\nimport { notifyForks } from './notify/saga'\nimport { walletLayer2NFTFork } from './walletLayer2NFT/saga'\nimport { layer1ActionHistoryForks } from './localStore/layer1Store/saga'\nimport { investForks } from './invest'\nimport { walletL2CollectionFork } from './walletL2Collection/saga'\nimport { walletL2NFTCollectionFork } from './walletL2NFTCollection/saga'\nimport { redPacketConfigsSaga } from './redPacket/saga'\nimport { exclusiveRedPacketSaga } from './targetRedpackt/saga'\nimport { contractsForks } from './contacts/saga'\nimport { vaultLayer2Fork } from './vaultLayer2/saga'\n\nfunction* mySaga() {\n  yield all([\n    ...tokenSaga,\n    ...tokenPricesSaga,\n    ...redPacketConfigsSaga,\n    ...walletLayer1Fork,\n    ...walletLayer2Fork,\n    ...walletLayer2NFTFork,\n    ...walletL2CollectionFork,\n    ...walletL2NFTCollectionFork,\n    ...systemForks,\n    ...ammForks,\n    ...investForks,\n    ...tickerForks,\n    ...userRewardsForks,\n    ...socketForks,\n    ...accountFork,\n    ...amountForks,\n    ...notifyForks,\n    ...layer1ActionHistoryForks,\n    ...exclusiveRedPacketSaga,\n    ...contractsForks,\n    ...exclusiveRedPacketSaga,\n    ...vaultLayer2Fork,\n  ])\n}\n\nexport default mySaga\n"
  },
  {
    "path": "packages/core/src/stores/router/amm/hook.ts",
    "content": "import { useDispatch, useSelector } from 'react-redux'\nimport {\n  resetAmmPool,\n  // updatePageAmmCommon,\n  updatePageAmmExit,\n  updatePageAmmExitBtn,\n  updatePageAmmJoin,\n  updatePageAmmJoinBtn,\n} from './reducer'\nimport {\n  // PageAmmCommon,\n  PageAmmExit,\n  PageAmmJoin,\n  PageAmmPoolStatus,\n} from './interface'\nimport React from 'react'\nimport { RequireOne } from '@loopring-web/common-resources'\nimport { RootState } from '../../index'\n\nexport function usePageAmmPool(): PageAmmPoolStatus & {\n  // updatePageAmmCommon: (pageAmmPool: RequireOne<PageAmmCommon, never>) => void;\n  updatePageAmmJoin: (pageAmmPool: RequireOne<PageAmmJoin, never>) => void\n  updatePageAmmJoinBtn: (pageAmmPool: RequireOne<PageAmmJoin, never>) => void\n  updatePageAmmExit: (pageAmmPool: RequireOne<PageAmmExit, never>) => void\n  updatePageAmmExitBtn: (pageAmmPool: RequireOne<PageAmmExit, never>) => void\n  resetAmmPool: () => void\n} {\n  const pageAmmPoolStatus: PageAmmPoolStatus = useSelector(\n    (state: RootState) => state._router_pageAmmPool,\n  )\n  const dispatch = useDispatch()\n  return {\n    ...pageAmmPoolStatus,\n    resetAmmPool: React.useCallback(() => {\n      dispatch(resetAmmPool({}))\n    }, [dispatch]),\n\n    updatePageAmmJoin: React.useCallback(\n      (pageAmmJoin: RequireOne<PageAmmJoin, never>) => {\n        dispatch(updatePageAmmJoin(pageAmmJoin))\n      },\n      [dispatch],\n    ),\n    updatePageAmmJoinBtn: React.useCallback(\n      (pageAmmJoin: RequireOne<PageAmmJoin, never>) => {\n        dispatch(updatePageAmmJoinBtn(pageAmmJoin))\n      },\n      [dispatch],\n    ),\n    updatePageAmmExit: React.useCallback(\n      (pageAmmJoin: RequireOne<PageAmmExit, never>) => {\n        dispatch(updatePageAmmExit(pageAmmJoin))\n      },\n      [dispatch],\n    ),\n    updatePageAmmExitBtn: React.useCallback(\n      (pageAmmJoin: RequireOne<PageAmmExit, never>) => {\n        dispatch(updatePageAmmExitBtn(pageAmmJoin))\n      },\n      [dispatch],\n    ),\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/router/amm/index.ts",
    "content": "export * from './hook'\nexport * from './interface'\nexport * from './reducer'\n"
  },
  {
    "path": "packages/core/src/stores/router/amm/interface.ts",
    "content": "import * as sdk from '@loopring-web/loopring-sdk'\nimport {\n  AmmExitData,\n  AmmInData,\n  AmmJoinData,\n  IBData,\n  TradeBtnStatus,\n} from '@loopring-web/common-resources'\n// import { AmmDetailStore } from \"../../Amm\";\n\n// export type PageAmmCommon = {\n//   // ammPoolSnapshot: sdk.AmmPoolSnapshot | undefined;\n//   ammInfo: AmmDetailStore<any> | undefined;\n// };\n\ntype PageAmmBase = {\n  btnStatus: TradeBtnStatus\n  btnI18nKey: string | undefined\n  ammCalcData: AmmInData<any> | undefined\n}\n\nexport type PageAmmJoin = {\n  fees: sdk.LoopringMap<sdk.OffchainFeeInfo>\n  fee: number\n  request: sdk.JoinAmmPoolRequest | undefined\n  ammData: AmmJoinData<IBData<string>, string>\n} & PageAmmBase\n\nexport type PageAmmExit = {\n  volA_show: number | undefined\n  volB_show: number | undefined\n  volA: number | undefined\n  volB: number | undefined\n  fees: sdk.LoopringMap<sdk.OffchainFeeInfo>\n  fee: number\n  request: sdk.ExitAmmPoolRequest | undefined\n  ammData: AmmExitData<IBData<string>, string>\n} & PageAmmBase\n\nexport type PageAmmPoolStatus = {\n  ammJoin: PageAmmJoin\n  ammExit: PageAmmExit\n  // common: PageAmmCommon;\n  __SUBMIT_LOCK_TIMER__: 1000\n  __TOAST_AUTO_CLOSE_TIMER__: 3000\n}\n"
  },
  {
    "path": "packages/core/src/stores/router/amm/reducer.ts",
    "content": "import {\n  AmmExitData,\n  AmmJoinData,\n  defaultSlipage,\n  IBData,\n  TradeBtnStatus,\n} from '@loopring-web/common-resources'\nimport { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\n// import { PageAmmCommon } from \"./index\";\nimport { PageAmmExit, PageAmmJoin, PageAmmPoolStatus } from './interface'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { BIGO } from '../../../defs'\n\nexport const initSlippage = defaultSlipage\n\nconst initJoinState: PageAmmJoin = {\n  fees: {},\n  fee: 0,\n  request: undefined,\n  btnI18nKey: undefined,\n  btnStatus: TradeBtnStatus.AVAILABLE,\n  ammCalcData: undefined,\n  ammData: {\n    coinLP: { belong: undefined } as unknown as IBData<string>,\n    coinA: { belong: undefined } as unknown as IBData<string>,\n    coinB: { belong: undefined } as unknown as IBData<string>,\n    slippage: initSlippage,\n  } as AmmJoinData<IBData<string>, string>,\n}\n\nconst initExitState: PageAmmExit = {\n  volA_show: undefined,\n  volB_show: undefined,\n  volA: undefined,\n  volB: undefined,\n  fees: {},\n  fee: 0,\n  request: undefined,\n  btnI18nKey: undefined,\n  btnStatus: TradeBtnStatus.AVAILABLE,\n  ammCalcData: undefined,\n  ammData: {\n    coinLP: { belong: undefined } as unknown as IBData<string>,\n    coinA: { belong: undefined } as unknown as IBData<string>,\n    coinB: { belong: undefined } as unknown as IBData<string>,\n    slippage: initSlippage,\n  } as AmmExitData<IBData<string>, string>,\n}\n\n// const initCommonState: PageAmmCommon = {\n//   ammInfo: undefined,\n//   ammPoolSnapshot: undefined,\n// };\n\nconst initialState: PageAmmPoolStatus = {\n  ammJoin: initJoinState,\n  ammExit: initExitState,\n  // common: initCommonState,\n  __SUBMIT_LOCK_TIMER__: 1000,\n  __TOAST_AUTO_CLOSE_TIMER__: 3000,\n}\n\nconst pageAmmPoolSlice: Slice<PageAmmPoolStatus> = createSlice({\n  name: '_router_pageAmmPool',\n  initialState,\n  reducers: {\n    resetAmmPool(state) {\n      state.ammJoin = initJoinState\n      state.ammExit = initExitState\n      // state.common = initCommonState;\n    },\n\n    // updatePageAmmCommon(state, action: PayloadAction<Partial<PageAmmCommon>>) {\n    //   const { ammInfo } = action.payload;\n    //\n    //   if (ammInfo) {\n    //     state.common.ammInfo = ammInfo;\n    //   }\n    //\n    //   // if (ammPoolSnapshot) {\n    //   //   state.common.ammPoolSnapshot = ammPoolSnapshot;\n    //   // }\n    // },\n\n    updatePageAmmJoinBtn(state, action: PayloadAction<Partial<PageAmmJoin>>) {\n      const { btnI18nKey, btnStatus } = action.payload\n\n      state.ammJoin.btnI18nKey = btnI18nKey\n\n      if (btnStatus) {\n        state.ammJoin.btnStatus = btnStatus\n      }\n    },\n\n    updatePageAmmJoin(state, action: PayloadAction<Partial<PageAmmJoin>>) {\n      const { fee, fees, request, ammCalcData, ammData } = action.payload\n\n      if (typeof fee !== 'undefined') {\n        state.ammJoin.fee = fee\n        state.ammJoin.ammCalcData = {\n          ...state.ammJoin.ammCalcData,\n          fee: fee + ' ' + state.ammJoin?.ammCalcData?.lpCoinB?.belong,\n        } as any\n      }\n\n      if (fees) {\n        state.ammJoin.fees = fees\n      }\n      // if (fee) {\n      //   state.ammJoin.fee = fee;\n      // }\n      //\n      // if (fees) {\n      //   state.ammJoin.fees = fees;\n      // }\n\n      if (request) {\n        state.ammJoin.request = request\n      }\n\n      if (ammCalcData) {\n        state.ammJoin.ammCalcData = ammCalcData\n      }\n\n      if (ammData) {\n        state.ammJoin.ammData = ammData\n      }\n    },\n\n    updatePageAmmExitBtn(state, action: PayloadAction<Partial<PageAmmExit>>) {\n      const { btnI18nKey, btnStatus } = action.payload\n\n      state.ammExit.btnI18nKey = btnI18nKey\n\n      if (btnStatus) {\n        state.ammExit.btnStatus = btnStatus\n      }\n    },\n\n    updatePageAmmExit(state, action: PayloadAction<Partial<PageAmmExit>>) {\n      const {\n        fee,\n        fees,\n        request,\n        ammCalcData,\n        ammData,\n\n        volA_show,\n        volB_show,\n      } = action.payload\n\n      if (typeof fee !== 'undefined') {\n        state.ammExit.fee = fee\n        state.ammExit.ammCalcData = {\n          ...state.ammExit.ammCalcData,\n          fee: fee + ' ' + state.ammExit?.ammCalcData?.lpCoinB?.belong,\n        } as any\n      }\n\n      if (fees) {\n        state.ammExit.fees = fees\n      }\n\n      if (request) {\n        state.ammExit.request = request\n      }\n\n      if (ammCalcData) {\n        state.ammExit.ammCalcData = ammCalcData\n      }\n\n      if (ammData) {\n        state.ammExit.ammData = ammData\n      }\n\n      if (volA_show !== undefined && sdk.toBig(volA_show).gte(BIGO)) {\n        state.ammExit.volA_show = volA_show\n      }\n\n      if (volB_show !== undefined && sdk.toBig(volB_show).gte(BIGO)) {\n        state.ammExit.volB_show = volB_show\n      }\n    },\n  },\n})\n\nexport { pageAmmPoolSlice }\n\nexport const {\n  updatePageAmmJoin,\n  updatePageAmmJoinBtn,\n  updatePageAmmExit,\n  updatePageAmmExitBtn,\n  // updatePageAmmCommon,\n  resetAmmPool,\n} = pageAmmPoolSlice.actions\n"
  },
  {
    "path": "packages/core/src/stores/router/index.ts",
    "content": "export * from './tradeLite'\nexport * from './amm'\nexport * from './modals'\nexport * from './tradePro'\nexport * from './tradeDefi'\nexport * from './tradeDual'\nexport * from './tradeStake'\nexport * from './tradeVault'\n"
  },
  {
    "path": "packages/core/src/stores/router/modals/hook.ts",
    "content": "import { useDispatch, useSelector } from 'react-redux'\nimport {\n  resetActiveAccountData,\n  resetDepositData,\n  resetNFTDeployData,\n  resetNFTDepositData,\n  resetNFTMintAdvanceData,\n  resetCollectionAdvanceData,\n  resetCollectionData,\n  resetNFTMintData,\n  resetNFTTransferData,\n  resetNFTWithdrawData,\n  resetOffRampData,\n  resetTransferData,\n  resetWithdrawData,\n  resetForceWithdrawData,\n  updateActiveAccountData,\n  updateOffRampData,\n  updateDepositData,\n  updateNFTDeployData,\n  updateNFTDepositData,\n  updateNFTMintAdvanceData,\n  updateCollectionAdvanceData,\n  updateCollectionData,\n  updateNFTMintData,\n  updateNFTTransferData,\n  updateNFTWithdrawData,\n  updateTransferData,\n  updateWithdrawData,\n  updateForceWithdrawData,\n  updateTransferRampData,\n  resetTransferRampData,\n  updateTransferBanxaData,\n  resetTransferBanxaData,\n  updateOffBanxaData,\n  resetOffBanxaData,\n  resetRedPacketOrder,\n  updateRedPacketOrder,\n  updateClaimData,\n  resetClaimData,\n} from './reducer'\nimport {\n  ActiveAccountData,\n  ClaimData,\n  DepositData,\n  ForceWithdrawData,\n  LAST_STEP,\n  ModalDataStatus,\n  NFT_MINT_VALUE,\n  TransferData,\n  WithdrawData,\n} from './interface'\nimport React from 'react'\nimport {\n  BanxaOrder,\n  CollectionMeta,\n  NFTWholeINFO,\n  RequireOne,\n  TradeNFT,\n  RedPacketOrderData,\n  RedPacketOrderType,\n} from '@loopring-web/common-resources'\nimport { RootState } from '../../index'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nexport function useModalData(): {\n  lastStep: LAST_STEP\n  updateWithdrawData: (withdrawData: RequireOne<WithdrawData, never>) => void\n  updateNFTTransferData: (\n    nftTransferData: RequireOne<\n      TransferData & Partial<sdk.NFTTokenInfo & sdk.UserNFTBalanceInfo & NFTWholeINFO>,\n      never\n    >,\n  ) => void\n  resetTransferData: () => void\n  nftWithdrawValue: WithdrawData & Partial<sdk.NFTTokenInfo & sdk.UserNFTBalanceInfo & NFTWholeINFO>\n  collectionAdvanceValue: Partial<CollectionMeta>\n  resetNFTMintData: (tokenAddress?: string) => void\n  resetCollectionAdvanceData: () => void\n  resetNFTDeployData: () => void\n  nftTransferValue: TransferData & Partial<sdk.NFTTokenInfo & sdk.UserNFTBalanceInfo & NFTWholeINFO>\n  nftDeployValue: TradeNFT<any, any> & { broker: string }\n  updateNFTMintAdvanceData: (nftMintData: TradeNFT<any, any>) => void\n  updateDepositData: (depositData: RequireOne<DepositData, never>) => void\n  resetNFTMintAdvanceData: () => void\n  updateCollectionAdvanceData: (collectionAdvanceDate: Partial<CollectionMeta>) => void\n  updateTransferData: (transferData: RequireOne<TransferData, never>) => void\n  resetWithdrawData: () => void\n  updateForceWithdrawData: (forceWithdrawData: Partial<ForceWithdrawData>) => void\n  resetDepositData: () => void\n  updateNFTWithdrawData: (\n    nftWithdrawData: RequireOne<\n      WithdrawData & Partial<sdk.NFTTokenInfo & sdk.UserNFTBalanceInfo & NFTWholeINFO>,\n      never\n    >,\n  ) => void\n  resetActiveAccountData: () => void\n  updateCollectionData: (collectionDate: Partial<CollectionMeta>) => void\n  collectionValue: Partial<CollectionMeta>\n  nftDepositValue: TradeNFT<any, any>\n  updateActiveAccountData: (activeAccountData: RequireOne<ActiveAccountData, never>) => void\n  updateNFTDeployData: (nftDeployData: Partial<TradeNFT<any, any> & { broker: string }>) => void\n  activeAccountValue: ActiveAccountData\n  nftMintValue: NFT_MINT_VALUE<any>\n  transferValue: TransferData\n  resetForceWithdrawData: () => void\n  resetCollectionData: () => void\n  updateNFTDepositData: (nftDepositData: TradeNFT<any, any>) => void\n  depositValue: DepositData\n  resetNFTTransferData: () => void\n  nftMintAdvanceValue: TradeNFT<any, any>\n  withdrawValue: WithdrawData\n  resetNFTDepositData: () => void\n  forceWithdrawValue: ForceWithdrawData\n  resetNFTWithdrawData: () => void\n  updateNFTMintData: (nftMintData: NFT_MINT_VALUE<any>) => void\n  offRampValue:\n    | Partial<{\n        offRampPurchase?: undefined\n        send?: {\n          assetSymbol: string\n          amount: string\n          destinationAddress: string\n        }\n      }>\n    | undefined\n  updateOffRampData: (\n    offRamp: Partial<{\n      offRampPurchase?: undefined\n      send?: {\n        assetSymbol: string\n        amount: string\n        destinationAddress: string\n      }\n    }>,\n  ) => void\n  resetOffRampData: () => void\n  offBanxaValue: Partial<BanxaOrder> | undefined\n  updateOffBanxaData: (\n    offBanxa: Partial<{\n      order: BanxaOrder\n    }>,\n  ) => void\n  resetOffBanxaData: () => void\n  transferRampValue: TransferData\n  resetTransferRampData: () => void\n  updateTransferRampData: (transferData: RequireOne<TransferData, never>) => void\n  transferBanxaValue: TransferData\n  resetTransferBanxaData: () => void\n  updateTransferBanxaData: (transferData: RequireOne<TransferData, never>) => void\n\n  redPacketOrder: RedPacketOrderData<any>\n  updateRedPacketOrder: (redPacketOrder: RedPacketOrderData<any>) => void\n  resetRedPacketOrder: (type?: RedPacketOrderType) => void\n\n  claimValue: Partial<ClaimData>\n  updateClaimData: (value: Partial<ClaimData>) => void\n  resetClaimData: () => void\n} {\n  const modalDataStatus: ModalDataStatus = useSelector(\n    (state: RootState) => state._router_modalData,\n  )\n  const dispatch = useDispatch()\n\n  return {\n    ...modalDataStatus,\n    updateActiveAccountData: React.useCallback(\n      (activeAccountData: RequireOne<ActiveAccountData, never>) => {\n        dispatch(updateActiveAccountData(activeAccountData))\n      },\n      [dispatch],\n    ),\n    updateWithdrawData: React.useCallback(\n      (withdrawData: RequireOne<WithdrawData, never>) => {\n        dispatch(updateWithdrawData(withdrawData))\n      },\n      [dispatch],\n    ),\n    updateTransferData: React.useCallback(\n      (transferData: RequireOne<TransferData, never>) => {\n        dispatch(updateTransferData(transferData))\n      },\n      [dispatch],\n    ),\n    updateTransferRampData: React.useCallback(\n      (transferData: RequireOne<TransferData, never>) => {\n        dispatch(updateTransferRampData(transferData))\n      },\n      [dispatch],\n    ),\n    updateTransferBanxaData: React.useCallback(\n      (transferData: RequireOne<TransferData, never>) => {\n        dispatch(updateTransferBanxaData(transferData))\n      },\n      [dispatch],\n    ),\n    updateDepositData: React.useCallback(\n      (depositData: RequireOne<DepositData, never>) => {\n        dispatch(updateDepositData(depositData))\n      },\n      [dispatch],\n    ),\n    updateNFTWithdrawData: React.useCallback(\n      (\n        nftWithdrawData: RequireOne<\n          WithdrawData &\n            sdk.NFTTokenInfo & {\n              image: string\n              name: string\n              description: string\n            },\n          never\n        >,\n      ) => {\n        dispatch(updateNFTWithdrawData(nftWithdrawData))\n      },\n      [dispatch],\n    ),\n    updateNFTTransferData: React.useCallback(\n      (\n        nftTransferData: RequireOne<\n          TransferData &\n            sdk.NFTTokenInfo & {\n              image: string\n              name: string\n              description: string\n            },\n          never\n        >,\n      ) => {\n        dispatch(updateNFTTransferData(nftTransferData))\n      },\n      [dispatch],\n    ),\n    updateNFTDepositData: React.useCallback(\n      (nftDepositData: TradeNFT<any, any>) => {\n        dispatch(updateNFTDepositData(nftDepositData))\n      },\n      [dispatch],\n    ),\n    updateNFTDeployData: React.useCallback(\n      (nftDeployData: Partial<TradeNFT<any, any> & { broker: string }>) => {\n        dispatch(updateNFTDeployData(nftDeployData))\n      },\n      [dispatch],\n    ),\n    updateNFTMintData: React.useCallback(\n      (nftMintData: NFT_MINT_VALUE<any>) => {\n        dispatch(updateNFTMintData(nftMintData))\n      },\n      [dispatch],\n    ),\n    updateCollectionAdvanceData: React.useCallback(\n      (collectionAdvanceDate: Partial<CollectionMeta>) => {\n        dispatch(updateCollectionAdvanceData(collectionAdvanceDate))\n      },\n      [dispatch],\n    ),\n    updateCollectionData: React.useCallback(\n      (collectionDate: Partial<CollectionMeta>) => {\n        dispatch(updateCollectionData(collectionDate))\n      },\n      [dispatch],\n    ),\n    updateNFTMintAdvanceData: React.useCallback(\n      (nftMintData: TradeNFT<any, any>) => {\n        dispatch(updateNFTMintAdvanceData(nftMintData))\n      },\n      [dispatch],\n    ),\n    updateForceWithdrawData: React.useCallback(\n      (forceWithdrawData: Partial<ForceWithdrawData>) => {\n        dispatch(updateForceWithdrawData(forceWithdrawData))\n      },\n      [dispatch],\n    ),\n    updateOffRampData: React.useCallback(\n      (\n        offRamp: Partial<{\n          offRampPurchase?: undefined\n          send?: {\n            assetSymbol: string\n            amount: string\n            destinationAddress: string\n          }\n        }>,\n      ) => {\n        dispatch(updateOffRampData(offRamp))\n      },\n      [dispatch],\n    ),\n    updateOffBanxaData: React.useCallback(\n      (\n        offBanxa: Partial<{\n          order: BanxaOrder\n        }>,\n      ) => {\n        dispatch(updateOffBanxaData(offBanxa))\n      },\n      [dispatch],\n    ),\n    updateRedPacketOrder: (redPacketOrder: RedPacketOrderData<any>) => {\n      dispatch(updateRedPacketOrder(redPacketOrder))\n    },\n    updateClaimData: (data: Partial<ClaimData>) => {\n      dispatch(updateClaimData(data))\n    },\n    resetForceWithdrawData: React.useCallback(() => {\n      dispatch(resetForceWithdrawData(undefined))\n    }, [dispatch]),\n    resetWithdrawData: React.useCallback(() => {\n      dispatch(resetWithdrawData(undefined))\n    }, [dispatch]),\n    resetTransferData: React.useCallback(() => {\n      dispatch(resetTransferData(undefined))\n    }, [dispatch]),\n    resetTransferRampData: React.useCallback(() => {\n      dispatch(resetTransferRampData(undefined))\n    }, [dispatch]),\n    resetTransferBanxaData: React.useCallback(() => {\n      dispatch(resetTransferBanxaData(undefined))\n    }, [dispatch]),\n    resetDepositData: React.useCallback(() => {\n      dispatch(resetDepositData(undefined))\n    }, [dispatch]),\n    resetNFTWithdrawData: React.useCallback(() => {\n      dispatch(resetNFTWithdrawData(undefined))\n    }, [dispatch]),\n    resetNFTTransferData: React.useCallback(() => {\n      dispatch(resetNFTTransferData(undefined))\n    }, [dispatch]),\n    resetNFTDepositData: React.useCallback(() => {\n      dispatch(resetNFTDepositData(undefined))\n    }, [dispatch]),\n    resetActiveAccountData: React.useCallback(() => {\n      dispatch(resetActiveAccountData(undefined))\n    }, [dispatch]),\n    resetNFTMintAdvanceData: React.useCallback(() => {\n      dispatch(resetNFTMintAdvanceData(undefined))\n    }, [dispatch]),\n    resetCollectionAdvanceData: React.useCallback(() => {\n      dispatch(resetCollectionAdvanceData(undefined))\n    }, [dispatch]),\n    resetCollectionData: React.useCallback(() => {\n      dispatch(resetCollectionData(undefined))\n    }, [dispatch]),\n    resetNFTMintData: React.useCallback(\n      (tokenAddress?: string) => {\n        dispatch(resetNFTMintData(tokenAddress ? { tokenAddress } : undefined))\n      },\n      [dispatch],\n    ),\n    resetNFTDeployData: React.useCallback(() => {\n      dispatch(resetNFTDeployData(undefined))\n    }, [dispatch]),\n    resetOffRampData: React.useCallback(() => {\n      dispatch(resetOffRampData(undefined))\n    }, [dispatch]),\n    resetOffBanxaData: React.useCallback(() => {\n      dispatch(resetOffBanxaData(undefined))\n    }, [dispatch]),\n    resetRedPacketOrder: React.useCallback(\n      (type?: RedPacketOrderType) => {\n        dispatch(resetRedPacketOrder({ type }))\n      },\n      [dispatch],\n    ),\n    resetClaimData: React.useCallback(() => {\n      dispatch(resetClaimData(undefined))\n    }, [dispatch]),\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/router/modals/index.ts",
    "content": "export * from './hook'\nexport * from './interface'\nexport * from './reducer'\n"
  },
  {
    "path": "packages/core/src/stores/router/modals/interface.ts",
    "content": "import * as sdk from '@loopring-web/loopring-sdk'\nimport { NFTTokenInfo, UserNFTBalanceInfo, XOR } from '@loopring-web/loopring-sdk'\nimport {\n  BanxaOrder,\n  CLAIM_TYPE,\n  CollectionMeta,\n  FeeInfo,\n  IBData,\n  MintTradeNFT,\n  NFTMETA,\n  NFTWholeINFO,\n  RedPacketOrderData,\n  TRADE_TYPE,\n  TradeNFT,\n  // VaultJoinData,\n} from '@loopring-web/common-resources'\nimport { WalletLayer2Map } from '../../walletLayer2'\n\nexport type WithdrawData<T = any> = IBData<T> & {\n  // belong: string | undefined;\n  // tradeValue: number | undefined;\n  // balance: number | undefined;\n  address: string | undefined\n  withdrawType: sdk.OffchainFeeReqType\n}\nexport type ForceWithdrawData = {\n  belong: string | undefined\n  tradeValue: number | undefined\n  balance: number | undefined\n  // requesterAddress: string | undefined;\n  withdrawAddress: string | undefined\n  fee: FeeInfo | undefined\n}\n\nexport type TransferData = {\n  belong: string | undefined\n  tradeValue: number | undefined\n  balance: number | undefined\n  address: string | undefined\n  memo: string | undefined\n  fee: FeeInfo | undefined\n  __request__: sdk.OriginTransferRequestV3 | undefined\n}\n\nexport type ClaimData = {\n  belong: string | undefined\n  tradeValue: string | number | undefined\n  balance: string | number | undefined\n  fee: FeeInfo | undefined\n  address: string | undefined\n  volume: string | undefined\n  tradeType: TRADE_TYPE\n  claimType: CLAIM_TYPE\n  __request__: sdk.OriginLuckTokenWithdrawsRequestV3 | undefined\n} & XOR<\n  {\n    tradeType: TRADE_TYPE.TOKEN\n  },\n  {\n    tradeType: TRADE_TYPE.NFT\n    tokenId: number\n    nftData: string\n    tokenAddress: string\n  }\n>\n\nexport type DepositData = {\n  belong: string | undefined\n  tradeValue: number | undefined\n  balance: number | undefined\n  toAddress?: string\n  addressError?: { error: boolean; message?: string | undefined }\n}\nexport type MintData = {\n  tokenAddress: string | undefined\n  tradeValue: number | undefined\n  memo: string | undefined\n  fee: FeeInfo | undefined\n}\n\nexport type ActiveAccountData = {\n  chargeFeeList: FeeInfo[]\n  fee?: FeeInfo\n  isFeeNotEnough?: {\n    isFeeNotEnough: boolean\n    isOnLoading: boolean\n  }\n  walletLayer2: WalletLayer2Map<any> | undefined\n  referral: string | number | undefined\n}\nexport type NFT_MINT_VALUE<I> = {\n  mintData: Partial<MintTradeNFT<I>>\n  nftMETA: Partial<NFTMETA>\n  collection?: Partial<CollectionMeta>\n  error?: undefined | sdk.RESULT_INFO\n}\n\nexport type ModalDataStatus = {\n  lastStep: LAST_STEP\n  withdrawValue: WithdrawData\n  transferValue: TransferData\n  transferRampValue: TransferData\n  transferBanxaValue: TransferData\n  depositValue: DepositData\n  activeAccountValue: ActiveAccountData\n  forceWithdrawValue: ForceWithdrawData\n  nftWithdrawValue: WithdrawData & Partial<NFTTokenInfo & UserNFTBalanceInfo & NFTWholeINFO>\n  nftTransferValue: TransferData & Partial<NFTTokenInfo & UserNFTBalanceInfo & NFTWholeINFO>\n  nftDepositValue: TradeNFT<any, any>\n  nftMintAdvanceValue: TradeNFT<any, any>\n  collectionAdvanceValue: Partial<CollectionMeta>\n  collectionValue: Partial<CollectionMeta>\n  nftMintValue: NFT_MINT_VALUE<any>\n  nftDeployValue: TradeNFT<any, any> & { broker: string }\n  offBanxaValue: BanxaOrder | undefined\n  offRampValue:\n    | Partial<{\n        offRampPurchase?: undefined\n        send?: {\n          assetSymbol: string\n          amount: string\n          destinationAddress: string\n        }\n      }>\n    | undefined\n  redPacketOrder: RedPacketOrderData<any>\n  claimValue: ClaimData\n}\n\nexport enum LAST_STEP {\n  withdraw = 'withdraw',\n  transfer = 'transfer',\n  deposit = 'deposit',\n  nftWithdraw = 'nftWithdraw',\n  nftTransfer = 'nftTransfer',\n  nftDeposit = 'nftDeposit',\n  nftDeploy = 'nftDeploy',\n  nftMint = 'nftMint',\n  nftMintAdv = 'nftMintAdv',\n  forceWithdraw = 'forceWithdraw',\n  collectionAdv = 'collectionAdv',\n  offRamp = 'offRamp',\n  offBanxa = 'offBanxa',\n  offRampTrans = 'offRampTrans',\n  redPacketSend = 'redPacketSend',\n  claim = 'claim',\n  default = 'default',\n}\n"
  },
  {
    "path": "packages/core/src/stores/router/modals/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport {\n  ActiveAccountData,\n  ClaimData,\n  DepositData,\n  ForceWithdrawData,\n  LAST_STEP,\n  ModalDataStatus,\n  NFT_MINT_VALUE,\n  TransferData,\n  WithdrawData,\n} from './interface'\nimport {\n  BanxaOrder,\n  CollectionMeta,\n  MINT_LIMIT,\n  MintTradeNFT,\n  NFTMETA,\n  NFTWholeINFO,\n  RedPacketOrderData,\n  RedPacketOrderType,\n  TRADE_TYPE,\n  TradeNFT,\n  // VaultJoinData,\n} from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { LoopringAPI } from '../../../api_wrapper'\nimport moment from 'moment'\n\nconst initialWithdrawState: WithdrawData = {\n  belong: undefined as any,\n  tradeValue: 0,\n  balance: 0,\n  address: undefined,\n  fee: undefined,\n  withdrawType: sdk.OffchainFeeReqType.OFFCHAIN_WITHDRAWAL,\n}\nconst initialForceWithdrawState: ForceWithdrawData = {\n  belong: undefined,\n  tradeValue: 0,\n  balance: 0,\n  // requesterAddress: string | undefined;\n  withdrawAddress: undefined,\n  fee: undefined,\n}\n\nconst initialTransferState: TransferData = {\n  belong: undefined,\n  tradeValue: 0,\n  balance: 0,\n  address: undefined,\n  memo: undefined,\n  fee: undefined,\n  __request__: undefined,\n}\n\nconst initialRedPacketState: RedPacketOrderData<any> = {\n  belong: undefined as any,\n  tradeValue: 0,\n  balance: 0,\n  fee: undefined,\n  validSince: Date.now(),\n  validUntil: moment().add('days', 1).toDate().getTime(),\n  type: {\n    partition: sdk.LuckyTokenAmountType.AVERAGE,\n    mode: sdk.LuckyTokenClaimType.COMMON,\n    scope: sdk.LuckyTokenViewType.PRIVATE,\n  },\n  tradeType: RedPacketOrderType.TOKEN,\n  __request__: undefined,\n  isNFT: false,\n}\nconst initialRedPacketNFTState: RedPacketOrderData<any> = {\n  belong: undefined as any,\n  tradeValue: 0,\n  fee: undefined,\n  validSince: Date.now(),\n  validUntil: moment().add('days', 1).toDate().getTime(),\n  type: {\n    partition: sdk.LuckyTokenAmountType.AVERAGE,\n    mode: sdk.LuckyTokenClaimType.RELAY,\n    scope: sdk.LuckyTokenViewType.PRIVATE,\n  },\n  tradeType: RedPacketOrderType.NFT,\n  __request__: undefined,\n  isNFT: true,\n}\nconst initialBlindBoxState: RedPacketOrderData<any> = {\n  belong: undefined as any,\n  tradeValue: 0,\n  fee: undefined,\n  validSince: Date.now(),\n  validUntil: moment().add('days', 1).toDate().getTime(),\n  type: {\n    partition: sdk.LuckyTokenAmountType.AVERAGE,\n    mode: sdk.LuckyTokenClaimType.BLIND_BOX,\n    scope: sdk.LuckyTokenViewType.PRIVATE,\n  },\n  tradeType: RedPacketOrderType.BlindBox,\n  __request__: undefined,\n  isNFT: false,\n}\n\nconst initialClaimState: ClaimData = {\n  belong: undefined as any,\n  tradeValue: 0,\n  balance: 0,\n  fee: undefined,\n  address: undefined,\n  tradeType: TRADE_TYPE.TOKEN,\n  __request__: undefined,\n} as any\n\n// const initialJoinVault: VaultJoinData = {\n//   belong: undefined as any,\n//   tradeValue: 0,\n//   balance: 0,\n//   __request__: undefined,\n// } as any\n\nconst initialDepositState: DepositData = {\n  belong: undefined,\n  tradeValue: 0,\n  balance: 0,\n  toAddress: undefined,\n}\n\nexport const initialTradeNFT = {\n  belong: undefined,\n  tradeValue: 0,\n  // balance: MINT_LIMIT,\n  nftBalance: 0,\n}\nexport const initialMintNFT: Partial<MintTradeNFT<any>> = {\n  belong: undefined,\n  tradeValue: 0,\n  nftBalance: MINT_LIMIT,\n}\n\nexport const initialNFTMETA: Partial<NFTMETA> = {\n  image: undefined,\n  name: undefined,\n  royaltyPercentage: 10,\n  description: undefined,\n  collection_metadata: undefined,\n  properties: undefined,\n}\nconst initialActiveAccountState: ActiveAccountData = {\n  chargeFeeList: [],\n  walletLayer2: undefined,\n  referral: undefined,\n}\n\nconst initialState: ModalDataStatus = {\n  lastStep: LAST_STEP.default,\n  offRampValue: undefined,\n  offBanxaValue: undefined,\n  withdrawValue: initialWithdrawState,\n  transferValue: initialTransferState,\n  transferRampValue: initialTransferState,\n  transferBanxaValue: initialTransferState,\n  depositValue: initialDepositState,\n  nftWithdrawValue: initialWithdrawState,\n  nftTransferValue: initialTransferState,\n  nftDepositValue: { ...initialTradeNFT },\n  nftMintValue: {\n    mintData: { ...initialMintNFT },\n    nftMETA: { ...initialNFTMETA },\n  },\n  nftMintAdvanceValue: { ...initialTradeNFT },\n  collectionAdvanceValue: {},\n  collectionValue: {},\n  nftDeployValue: { ...initialTradeNFT, broker: '' },\n  activeAccountValue: initialActiveAccountState,\n  forceWithdrawValue: { ...initialForceWithdrawState },\n  redPacketOrder: { ...initialRedPacketState },\n  claimValue: { ...initialClaimState },\n  // joinVault: { ...initialJoinVault },\n}\n\nconst modalDataSlice: Slice<ModalDataStatus> = createSlice({\n  name: '_router_modalData',\n  initialState,\n  reducers: {\n    resetAll(state) {\n      this.resetWithdrawData(state)\n      this.resetTransferData(state)\n      this.resetTransferRampData(state)\n      this.resetTransferBanxaData(state)\n      this.resetDepositData(state)\n      this.resetNFTWithdrawData(state)\n      this.resetNFTTransferData(state)\n      this.resetNFTDepositData(state)\n      this.resetActiveAccountData(state)\n      this.resetNFTMintData(state)\n      this.resetNFTDeployData(state)\n      this.resetForceWithdrawData(state)\n      this.resetRedPacketOrder(state)\n      this.resetClaimData(state)\n    },\n    resetForceWithdrawData(state) {\n      state.lastStep = LAST_STEP.default\n      state.forceWithdrawValue = initialForceWithdrawState\n    },\n\n    resetWithdrawData(state) {\n      state.lastStep = LAST_STEP.default\n      state.withdrawValue = initialWithdrawState\n    },\n    resetActiveAccountData(state) {\n      state.lastStep = LAST_STEP.default\n      state.activeAccountValue = initialActiveAccountState\n    },\n    resetTransferData(state) {\n      state.lastStep = LAST_STEP.default\n      state.transferValue = initialTransferState\n    },\n    resetTransferRampData(state) {\n      state.lastStep = LAST_STEP.default\n      state.transferRampValue = initialTransferState\n    },\n    resetTransferBanxaData(state) {\n      state.lastStep = LAST_STEP.default\n      state.transferBanxaValue = initialTransferState\n    },\n    resetDepositData(state) {\n      state.lastStep = LAST_STEP.default\n      state.depositValue = initialDepositState\n    },\n    resetNFTWithdrawData(state) {\n      state.lastStep = LAST_STEP.default\n      state.nftWithdrawValue = initialWithdrawState\n    },\n    resetNFTTransferData(state) {\n      state.lastStep = LAST_STEP.default\n      state.nftTransferValue = initialTransferState\n    },\n    resetNFTDepositData(state) {\n      state.lastStep = LAST_STEP.default\n      state.nftDepositValue = initialDepositState\n    },\n    resetNFTMintData(\n      state,\n      _action?: PayloadAction<{\n        lastStep?: LAST_STEP\n        tokenAddress?: string\n        collection?: CollectionMeta\n      }>,\n    ) {\n      state.lastStep = _action?.payload?.lastStep ?? LAST_STEP.default\n      state.nftMintValue = {\n        mintData: {\n          ...initialMintNFT,\n          tokenAddress: _action?.payload?.tokenAddress ? _action?.payload?.tokenAddress : undefined,\n        },\n        nftMETA: {\n          ...initialNFTMETA,\n          collection_metadata: _action?.payload?.collection?.contractAddress\n            ? `${LoopringAPI.delegate?.getCollectionDomain()}/${\n                _action?.payload.collection?.contractAddress\n              }`\n            : undefined,\n        },\n        collection: _action?.payload?.collection ? _action?.payload?.collection : undefined,\n      }\n    },\n    resetNFTMintAdvanceData(\n      state,\n      _action?: PayloadAction<{\n        lastStep?: LAST_STEP\n        tokenAddress?: string\n        collection?: CollectionMeta\n      }>,\n    ) {\n      state.lastStep = _action?.payload?.lastStep ?? LAST_STEP.default\n      state.nftMintAdvanceValue = initialTradeNFT\n    },\n    resetCollectionAdvanceData(state) {\n      state.lastStep = LAST_STEP.default\n      state.collectionAdvanceValue = {}\n    },\n    resetCollectionData(state) {\n      state.lastStep = LAST_STEP.default\n      state.collectionValue = {}\n    },\n    resetNFTDeployData(state) {\n      state.lastStep = LAST_STEP.default\n      state.nftDeployValue = { ...initialTradeNFT, broker: '' }\n    },\n    resetOffRampData(state) {\n      state.lastStep = LAST_STEP.default\n      state.offRampValue = undefined\n    },\n    resetOffBanxaData(state) {\n      state.lastStep = LAST_STEP.default\n      state.offBanxaValue = undefined\n    },\n    resetRedPacketOrder(\n      state,\n      _action?: PayloadAction<{\n        type?: RedPacketOrderType\n        isNFT?: boolean\n      }>,\n    ) {\n      state.lastStep = LAST_STEP.default\n      state.redPacketOrder = {\n        ...(_action?.payload?.type === RedPacketOrderType.NFT\n          ? initialRedPacketNFTState\n          : _action?.payload?.type === RedPacketOrderType.BlindBox\n          ? initialBlindBoxState\n          : initialRedPacketState),\n      } as RedPacketOrderData<any>\n    },\n    resetClaimData(state) {\n      state.lastStep = LAST_STEP.default\n      state.claimValue = { ...initialClaimState }\n    },\n    // resetJoinVault(state) {\n    //   state.lastStep = LAST_STEP.default\n    //   state.joinVault = { ...initialJoinVault }\n    // },\n    updateActiveAccountData(state, action: PayloadAction<Partial<ActiveAccountData>>) {\n      const { chargeFeeList, walletLayer2, isFeeNotEnough, referral, ...rest } = action.payload\n      state.lastStep = LAST_STEP.default\n      if (chargeFeeList) {\n        state.activeAccountValue.chargeFeeList = chargeFeeList\n        state.activeAccountValue.walletLayer2 = walletLayer2\n        state.activeAccountValue.isFeeNotEnough = isFeeNotEnough\n      }\n      if (referral !== undefined) {\n        state.activeAccountValue.referral = referral\n      }\n      state.activeAccountValue = {\n        ...state.activeAccountValue,\n        ...rest,\n      }\n    },\n    updateWithdrawData(state, action: PayloadAction<Partial<WithdrawData>>) {\n      const { belong, balance, tradeValue, address, withdrawType, ...rest } = action.payload\n      state.lastStep = LAST_STEP.withdraw\n      state.withdrawValue = {\n        ...state.withdrawValue,\n        withdrawType: withdrawType ? withdrawType : state.withdrawValue.withdrawType,\n        balance: balance as any,\n        belong: belong as any,\n        tradeValue,\n        address: address !== '*' ? address : undefined,\n        ...rest,\n      }\n    },\n    updateForceWithdrawData(state, action: PayloadAction<Partial<ForceWithdrawData>>) {\n      const {\n        belong,\n        balance,\n        tradeValue,\n        withdrawAddress,\n        // requesterAddress,\n        ...rest\n      } = action.payload\n      state.lastStep = LAST_STEP.withdraw\n      state.forceWithdrawValue = {\n        ...state.forceWithdrawValue,\n        balance: balance === undefined || balance >= 0 ? balance : state.forceWithdrawValue.balance,\n        belong,\n        tradeValue,\n        // requesterAddress: requesterAddress !== \"*\" ? requesterAddress : undefined,\n        withdrawAddress: withdrawAddress !== '*' ? withdrawAddress : undefined,\n        ...rest,\n      }\n    },\n    updateTransferData(state, action: PayloadAction<Partial<TransferData>>) {\n      const { belong, balance, tradeValue, address, ...rest } = action.payload\n      state.lastStep = LAST_STEP.transfer\n\n      state.transferValue = {\n        ...state.transferValue,\n        balance: balance === undefined || balance >= 0 ? balance : state.transferValue.balance,\n        belong,\n        tradeValue,\n        address: address !== '*' ? address : undefined,\n        ...rest,\n      }\n    },\n    updateTransferRampData(state, action: PayloadAction<Partial<TransferData>>) {\n      const { belong, balance, tradeValue, address, __request__, ...rest } = action.payload\n      state.lastStep = LAST_STEP.offRampTrans\n      if (__request__) {\n        state.transferRampValue.__request__ = __request__\n        return state\n      }\n      state.transferRampValue = {\n        ...state.transferRampValue,\n        balance: balance === undefined || balance >= 0 ? balance : state.transferValue.balance,\n        belong,\n        tradeValue,\n        address: address !== '*' ? address : undefined,\n        ...rest,\n      }\n    },\n    updateTransferBanxaData(state, action: PayloadAction<Partial<TransferData>>) {\n      const { belong, balance, tradeValue, address, __request__, ...rest } = action.payload\n      state.lastStep = LAST_STEP.offRampTrans\n      if (__request__) {\n        state.transferBanxaValue.__request__ = __request__\n        return state\n      }\n      state.transferBanxaValue = {\n        ...state.transferBanxaValue,\n        balance: balance === undefined || balance >= 0 ? balance : state.transferValue.balance,\n        belong,\n        tradeValue,\n        address: address !== '*' ? address : undefined,\n        ...rest,\n      }\n    },\n    updateDepositData(state, action: PayloadAction<Partial<DepositData>>) {\n      const { belong, balance, tradeValue, toAddress, addressError } = action.payload\n      state.lastStep = LAST_STEP.nftDeposit\n      if (belong) {\n        state.depositValue.belong = belong\n      }\n\n      if (balance && balance >= 0) {\n        state.depositValue.balance = balance\n      }\n      state.depositValue.tradeValue = tradeValue\n      state.depositValue.toAddress = toAddress\n      state.depositValue.addressError = addressError\n    },\n    updateNFTWithdrawData(\n      state,\n      action: PayloadAction<Partial<WithdrawData & sdk.UserNFTBalanceInfo & NFTWholeINFO>>,\n    ) {\n      const { belong, tradeValue, address, ...rest } = action.payload\n      state.lastStep = LAST_STEP.nftWithdraw\n      state.nftWithdrawValue = {\n        ...state.nftWithdrawValue,\n        belong: belong as any,\n        tradeValue: tradeValue === undefined || tradeValue >= 0 ? tradeValue : undefined,\n        address: address !== '*' ? address : undefined,\n\n        ...rest,\n      }\n    },\n    updateNFTTransferData(\n      state,\n      action: PayloadAction<Partial<TransferData & sdk.UserNFTBalanceInfo & NFTWholeINFO>>,\n    ) {\n      const { belong, tradeValue, address, ...rest } = action.payload\n      state.lastStep = LAST_STEP.nftTransfer\n      state.nftTransferValue = {\n        ...state.nftTransferValue,\n        belong,\n        // balance: balance\n        //   ? balance\n        //   : rest.total !== undefined\n        //   ? sdk\n        //       .toBig(rest.total ?? 0)\n        //       .minus(rest.locked ?? 0)\n        //       .toNumber()\n        //   : state.nftTransferValue.balance,\n        tradeValue: tradeValue === undefined || tradeValue >= 0 ? tradeValue : undefined,\n        address: address !== '*' ? address : undefined,\n\n        ...rest,\n      }\n    },\n    updateNFTDepositData(state, action: PayloadAction<Partial<TradeNFT<any, any>>>) {\n      const { balance, tradeValue, ...rest } = action.payload\n      state.lastStep = LAST_STEP.nftDeposit\n\n      if (balance === undefined || balance >= 0) {\n        state.nftDepositValue.balance = balance\n      }\n\n      if (tradeValue === undefined || tradeValue >= 0) {\n        state.nftDepositValue.tradeValue = tradeValue\n      }\n\n      state.nftDepositValue = {\n        ...state.nftDepositValue,\n        ...rest,\n      }\n    },\n    updateNFTMintAdvanceData(state, action: PayloadAction<Partial<TradeNFT<any, any>>>) {\n      const { balance, tradeValue, ...rest } = action.payload\n      state.lastStep = LAST_STEP.nftMintAdv\n\n      if (balance && balance >= 0) {\n        state.nftMintAdvanceValue.balance = balance\n      }\n\n      if (tradeValue === undefined || tradeValue >= 0) {\n        state.nftMintAdvanceValue.tradeValue = tradeValue\n      }\n\n      state.nftMintAdvanceValue = {\n        ...state.nftMintAdvanceValue,\n        ...rest,\n      }\n    },\n    updateCollectionAdvanceData(state, action: PayloadAction<any>) {\n      state.lastStep = LAST_STEP.collectionAdv\n      const _collectionAdvanceValue = action.payload\n      state.collectionAdvanceValue = { ..._collectionAdvanceValue }\n    },\n    updateCollectionData(state, action: PayloadAction<any>) {\n      state.lastStep = LAST_STEP.collectionAdv\n      const _collectionValue = action.payload\n      state.collectionValue = { ..._collectionValue }\n    },\n    updateNFTMintData(state, action: PayloadAction<NFT_MINT_VALUE<any>>) {\n      const mintData = action.payload.mintData\n      const nftMETA = action.payload.nftMETA\n      const collection = action.payload.collection\n      const error = action.payload.error\n      const { balance, tradeValue, tokenAddress, ...rest } = mintData\n\n      state.lastStep = LAST_STEP.nftMint\n\n      if (balance === undefined || balance >= 0) {\n        state.nftMintValue.mintData.balance = balance\n      }\n\n      if (tradeValue === undefined || tradeValue >= 0) {\n        state.nftMintValue.mintData.tradeValue = tradeValue\n      }\n\n      state.nftMintValue.mintData = {\n        ...state.nftMintValue.mintData,\n        tokenAddress,\n        ...rest,\n      }\n      state.nftMintValue.nftMETA = {\n        ...state.nftMintValue.nftMETA,\n        ...nftMETA,\n      }\n      if (collection) {\n        state.nftMintValue.collection = collection\n      }\n      state.nftMintValue.error = error\n    },\n    updateNFTDeployData(\n      state,\n      action: PayloadAction<Partial<TradeNFT<any, any> & { broker: string }>>,\n    ) {\n      const { balance, tradeValue, broker, ...rest } = action.payload\n      state.lastStep = LAST_STEP.nftDeploy\n\n      // if (balance === undefined || balance >= 0) {\n      //   state.nftDeployValue.balance = balance;\n      // }\n      if (broker) {\n        state.nftDeployValue.broker = broker\n      }\n\n      // if (tradeValue === undefined || tradeValue >= 0) {\n      //   state.nftDeployValue.tradeValue = tradeValue;\n      // }\n\n      state.nftDeployValue = {\n        ...state.nftDeployValue,\n        ...rest,\n      }\n    },\n    updateOffRampData(\n      state,\n      action: PayloadAction<\n        Partial<{\n          offRampPurchase?: undefined\n          send?: {\n            assetSymbol: string\n            amount: string\n            destinationAddress: string\n          }\n        }>\n      >,\n    ) {\n      state.lastStep = LAST_STEP.offRamp\n      const { send } = action.payload\n      if (send) {\n        state.offRampValue = {\n          ...state.offRampValue,\n          send,\n        }\n      }\n      // if()\n      // state.offRampValue = {\n      //   ...state.offRampValue,\n      //   ...action.payload,\n      // };\n    },\n    updateOffBanxaData(state, action: PayloadAction<{ order: BanxaOrder }>) {\n      state.lastStep = LAST_STEP.offBanxa\n      const { order } = action.payload\n      if (order) {\n        state.offBanxaValue = {\n          ...order,\n        }\n      }\n    },\n    updateRedPacketOrder(state, action: PayloadAction<RedPacketOrderData<any>>) {\n      state.lastStep = LAST_STEP.redPacketSend\n      const { balance, tradeValue, belong, target, ...rest } = action.payload\n      state.redPacketOrder = {\n        ...state.redPacketOrder,\n        balance: balance === undefined || balance >= 0 ? balance : state.redPacketOrder.balance,\n        belong,\n        tradeValue,\n        target,\n        ...rest,\n      } as RedPacketOrderData<any>\n    },\n    updateClaimData(state, action: PayloadAction<ClaimData>) {\n      state.lastStep = LAST_STEP.claim\n      const { balance, tradeValue, belong, ...rest } = action.payload\n      state.claimValue = {\n        ...state.redPacketOrder,\n        balance: balance === undefined || balance >= 0 ? balance : state.redPacketOrder.balance,\n        belong,\n        tradeValue,\n        ...rest,\n      } as ClaimData\n    },\n\n    // updateJoinVault(state, action: PayloadAction<VaultJoinData>) {\n    //   state.lastStep = LAST_STEP.claim\n    //   const { balance, tradeValue, belong, ...rest } = action.payload\n    //   state.joinVault = {\n    //     ...state.joinVault,\n    //     balance: balance === undefined || balance >= 0 ? balance : state.redPacketOrder.balance,\n    //     belong,\n    //     tradeValue,\n    //     ...rest,\n    //   } as VaultJoinData\n    // },\n  },\n})\n\nexport { modalDataSlice }\n\nexport const {\n  // joinVault,\n  // updateJoinVault,\n  // resetJoinVault,\n  // exitVault,\n  // updateExitVault,\n  // reseExitVault,\n  updateForceWithdrawData,\n  updateActiveAccountData,\n  updateWithdrawData,\n  updateTransferData,\n  updateTransferRampData,\n  updateTransferBanxaData,\n  updateDepositData,\n  updateNFTWithdrawData,\n  updateNFTTransferData,\n  updateNFTDepositData,\n  updateNFTMintData,\n  updateNFTDeployData,\n  updateNFTMintAdvanceData,\n  updateCollectionAdvanceData,\n  updateCollectionData,\n  updateOffRampData,\n  updateOffBanxaData,\n  updateRedPacketOrder,\n  updateClaimData,\n  resetClaimData,\n  resetForceWithdrawData,\n  resetNFTWithdrawData,\n  resetNFTTransferData,\n  resetNFTDepositData,\n  resetNFTMintData,\n  resetWithdrawData,\n  resetTransferData,\n  resetTransferRampData,\n  resetDepositData,\n  resetActiveAccountData,\n  resetNFTDeployData,\n  resetNFTMintAdvanceData,\n  resetCollectionAdvanceData,\n  resetCollectionData,\n  resetOffRampData,\n  resetOffBanxaData,\n  resetRedPacketOrder,\n  resetTransferBanxaData,\n  resetAll,\n} = modalDataSlice.actions\n"
  },
  {
    "path": "packages/core/src/stores/router/tradeBtrade/hook.ts",
    "content": "import { useDispatch, useSelector } from 'react-redux'\nimport { resetBtradeSwap, updateBtradeTrade } from './reducer'\nimport { TradeBtrade, TradeBtradeStatus } from './interface'\nimport React from 'react'\n\nexport function useTradeBtrade(): TradeBtradeStatus & {\n  updateTradeBtrade: (tradeBtrade: Partial<TradeBtrade>) => void\n  resetTradeBtrade: () => void\n} {\n  const tradeBtradeStatus: TradeBtradeStatus = useSelector(\n    (state: any) => state._router_tradeBtrade,\n  )\n  const dispatch = useDispatch()\n  return {\n    ...tradeBtradeStatus,\n    updateTradeBtrade: React.useCallback(\n      (tradeBtrade: Partial<TradeBtrade>) => {\n        dispatch(updateBtradeTrade(tradeBtrade))\n      },\n      [dispatch],\n    ),\n    resetTradeBtrade: React.useCallback(() => {\n      dispatch(resetBtradeSwap(undefined))\n    }, [dispatch]),\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/router/tradeBtrade/index.ts",
    "content": "export * from './hook'\nexport * from './interface'\nexport * from './reducer'\n"
  },
  {
    "path": "packages/core/src/stores/router/tradeBtrade/interface.ts",
    "content": "import { BtradeTradeCalcData, BtradeType, MarketType } from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { OrderInfoPatch } from '../tradePro'\n\nexport type TradeBtrade = {\n  market: MarketType\n  tradePair?: MarketType //eg: ETH-LRC or LRC-ETH  ${sell}-${buy}\n  request?: sdk.OriginBTRADEV3OrderRequest | null | undefined\n  tradeCalcData: Partial<BtradeTradeCalcData<any>>\n  depth?: sdk.DepthData | undefined\n  sellToken: string\n  buyToken: string\n  totalFeeRaw?: number | string\n  totalFee?: number | string\n  maxFeeBips?: number\n  sellMinAmtInfo?: string\n  sellMaxL2AmtInfo?: string\n  sellMaxAmtInfo?: string\n  lastStepAt: 'sell' | 'buy' | undefined\n  sellUserOrderInfo?: undefined | null | sdk.OrderInfo\n  buyUserOrderInfo?: undefined | null | sdk.OrderInfo\n  minOrderInfo?: undefined | null | Partial<sdk.OrderInfo & OrderInfoPatch>\n  info: sdk.BTRADE_MARKET\n  btradeType: undefined | BtradeType\n}\n\nexport type TradeBtradeStatus = {\n  tradeBtrade: TradeBtrade\n  __DAYS__: 30\n  __SUBMIT_LOCK_TIMER__: 1000\n  __TOAST_AUTO_CLOSE_TIMER__: 3000\n}\n"
  },
  {
    "path": "packages/core/src/stores/router/tradeBtrade/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { TradeBtrade, TradeBtradeStatus } from './interface'\nimport { MAPFEEBIPS } from '../../../defs'\n\nconst initState: TradeBtrade = {\n  market: undefined,\n  tradePair: undefined,\n  tradeCalcData: {\n    isBtrade: true,\n  },\n  maxFeeBips: MAPFEEBIPS,\n} as unknown as TradeBtrade\nconst initialState: TradeBtradeStatus = {\n  // pageTradePro: initState,\n  tradeBtrade: initState,\n  __DAYS__: 30,\n  __SUBMIT_LOCK_TIMER__: 1000,\n  __TOAST_AUTO_CLOSE_TIMER__: 3000,\n}\nconst tradeBtradeSlice: Slice<TradeBtradeStatus> = createSlice({\n  name: '_router_tradeBtrade',\n  initialState,\n  reducers: {\n    resetBtradeSwap(state) {\n      state.tradeBtrade = initState\n    },\n    updateBtradeTrade(state, action: PayloadAction<Partial<TradeBtrade>>) {\n      const {\n        market,\n        tradePair,\n        request,\n        tradeCalcData,\n        depth,\n        sellUserOrderInfo,\n        buyUserOrderInfo,\n        minOrderInfo,\n        lastStepAt,\n        totalFee,\n        sellMinAmtInfo,\n        sellMaxL2AmtInfo,\n        sellMaxAmtInfo,\n        // btradeMarket,\n        maxFeeBips,\n        btradeType,\n        ...rest\n      } = action.payload\n      if (market !== state.tradeBtrade.market && market && tradePair) {\n        // @ts-ignore\n        const [_, sellToken, buyToken] = (tradePair ?? '').match(/(\\w+)-(\\w+)/i)\n        // @ts-ignore\n        state.tradeBtrade = {\n          market,\n          tradePair, //eg: ETH-LRC or LRC-ETH  ${sell}-${buy}\n          request,\n          depth,\n          totalFee,\n          minOrderInfo,\n          sellToken,\n          buyToken,\n          tradeCalcData: tradeCalcData as any,\n          sellUserOrderInfo,\n          buyUserOrderInfo,\n          sellMinAmtInfo,\n          sellMaxL2AmtInfo,\n          sellMaxAmtInfo,\n          lastStepAt: undefined,\n          // btradeMarket,\n          btradeType,\n          maxFeeBips,\n          ...rest,\n        }\n      } else {\n        if (lastStepAt) {\n          state.tradeBtrade.lastStepAt = lastStepAt\n        }\n        if (btradeType) {\n          state.tradeBtrade.btradeType = btradeType\n        }\n\n        if (tradePair && tradePair) {\n          const [_, sellToken, buyToken] = tradePair.match(/(\\w+)-(\\w+)/i)\n          state.tradeBtrade.tradePair = tradePair\n          state.tradeBtrade.sellToken = sellToken\n          state.tradeBtrade.buyToken = buyToken\n          state.tradeBtrade.lastStepAt = undefined\n        }\n        if (depth) {\n          state.tradeBtrade.depth = depth\n        }\n\n        if (totalFee) {\n          state.tradeBtrade.totalFee = totalFee\n        }\n        // if (takerRate) {\n        //   state.tradeBtrade.takerRate = takerRate;\n        // }\n        if (minOrderInfo) {\n          state.tradeBtrade.minOrderInfo = minOrderInfo\n        }\n        if (maxFeeBips !== undefined) {\n          state.tradeBtrade.maxFeeBips = maxFeeBips\n        }\n        if (tradeCalcData) {\n          state.tradeBtrade.tradeCalcData = tradeCalcData\n        }\n        if (sellUserOrderInfo !== undefined) {\n          state.tradeBtrade.sellUserOrderInfo = sellUserOrderInfo\n        }\n        if (buyUserOrderInfo !== undefined) {\n          state.tradeBtrade.buyUserOrderInfo = buyUserOrderInfo\n        }\n\n        if (sellMinAmtInfo !== undefined) {\n          state.tradeBtrade.sellMinAmtInfo = sellMinAmtInfo\n        }\n        if (sellMaxL2AmtInfo !== undefined) {\n          state.tradeBtrade.sellMaxL2AmtInfo = sellMaxL2AmtInfo\n        }\n        if (sellMaxAmtInfo !== undefined) {\n          state.tradeBtrade.sellMaxAmtInfo = sellMaxAmtInfo\n        }\n      }\n    },\n  },\n})\n\nexport { tradeBtradeSlice }\nexport const { resetBtradeSwap, updateBtradeTrade } = tradeBtradeSlice.actions\n"
  },
  {
    "path": "packages/core/src/stores/router/tradeDefi/hook.ts",
    "content": "import { useDispatch, useSelector } from 'react-redux'\nimport { updateTradeDefi, resetTradeDefi } from './reducer'\nimport { TradeDefiStatus } from './interface'\nimport React from 'react'\nimport { TradeDefi } from '@loopring-web/common-resources'\n\nexport function useTradeDefi<C extends { [key: string]: any }>(): TradeDefiStatus<C> & {\n  updateTradeDefi: (tradeDefi: Partial<TradeDefi<C>>) => void\n  resetTradeDefi: () => void\n} {\n  const tradeDefiStatus: TradeDefiStatus<C> = useSelector((state: any) => state._router_tradeDefi)\n  const dispatch = useDispatch()\n  return {\n    ...tradeDefiStatus,\n    updateTradeDefi: React.useCallback(\n      (tradeDefi: Partial<TradeDefi<C>>) => {\n        dispatch(updateTradeDefi(tradeDefi))\n      },\n      [dispatch],\n    ),\n    resetTradeDefi: React.useCallback(() => {\n      dispatch(resetTradeDefi(undefined))\n    }, [dispatch]),\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/router/tradeDefi/index.ts",
    "content": "export * from './hook'\nexport * from './interface'\nexport * from './reducer'\n"
  },
  {
    "path": "packages/core/src/stores/router/tradeDefi/interface.ts",
    "content": "import { TradeDefi } from '@loopring-web/common-resources'\n\nexport type TradeDefiStatus<C> = {\n  tradeDefi: TradeDefi<C>\n  __DAYS__: 30\n  __SUBMIT_LOCK_TIMER__: 1000\n  __TOAST_AUTO_CLOSE_TIMER__: 3000\n}\n"
  },
  {
    "path": "packages/core/src/stores/router/tradeDefi/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { TradeDefiStatus } from './interface'\nimport { IBData, TradeDefi, RequireOne } from '@loopring-web/common-resources'\nimport { TokenInfo } from '@loopring-web/loopring-sdk'\n\nconst initState: TradeDefi<any> = {\n  type: 'LIDO',\n  isStoB: true,\n  sellToken: {} as any,\n  buyToken: {} as any,\n  depositPrice: '0',\n  withdrawPrice: '0',\n  sellVol: '0',\n  buyVol: '0',\n  deFiCalcData: {\n    coinSell: {},\n    coinBuy: {},\n    AtoB: undefined as any,\n    BtoA: undefined as any,\n    fee: undefined as any,\n  },\n  fee: '0',\n  feeRaw: '0',\n  defaultFee: '0',\n}\ntype R = { [key: string]: any }\nconst initialState: TradeDefiStatus<IBData<R>> = {\n  tradeDefi: initState,\n  __DAYS__: 30,\n  // __API_REFRESH__: 15000,\n  __SUBMIT_LOCK_TIMER__: 1000,\n  __TOAST_AUTO_CLOSE_TIMER__: 3000,\n}\nconst tradeDefiSlice: Slice<TradeDefiStatus<IBData<R>>> = createSlice({\n  name: '_router_tradeDefi',\n  initialState,\n  reducers: {\n    resetTradeDefi(state) {\n      state.tradeDefi = initState\n    },\n    updateTradeDefi(state, action: PayloadAction<RequireOne<TradeDefi<IBData<any>>, 'market'>>) {\n      const {\n        type,\n        market,\n        isStoB,\n        sellToken,\n        buyToken,\n        sellVol,\n        buyVol,\n        deFiCalcData,\n        fee,\n        defiBalances,\n        depositPrice,\n        withdrawPrice,\n        request,\n        feeRaw,\n        maxSellVol,\n        maxFeeBips,\n        miniSellVol,\n        lastInput,\n        defaultFee,\n      } = action.payload\n      if (market !== undefined && market !== state.tradeDefi.market && type) {\n        // @ts-ignore\n        state.tradeDefi = {\n          ...initState,\n          type,\n          market,\n          sellToken: sellToken as TokenInfo,\n          buyToken: buyToken as TokenInfo,\n        }\n      }\n      if (lastInput) {\n        state.tradeDefi.lastInput = lastInput\n      }\n      if (request) {\n        state.tradeDefi.request = request\n      }\n\n      if (deFiCalcData) {\n        // let _deFiCalcData = { ...deFiCalcData };\n        state.tradeDefi.deFiCalcData = deFiCalcData\n        // if (_deFiCalcData.AtoB === undefined) {\n        //   _deFiCalcData.AtoB = state.tradeDefi.deFiCalcData.AtoB;\n        //   _deFiCalcData.BtoA = state.tradeDefi.deFiCalcData.BtoA;\n        // }\n      }\n      if (defaultFee) {\n        state.tradeDefi.defaultFee = defaultFee\n      }\n      if (isStoB) {\n        state.tradeDefi.isStoB = isStoB\n      }\n      if (defiBalances) {\n        state.tradeDefi.defiBalances = defiBalances\n      }\n      if (maxSellVol) {\n        state.tradeDefi.maxSellVol = maxSellVol\n      }\n      if (maxFeeBips) {\n        state.tradeDefi.maxFeeBips = maxFeeBips\n      }\n      if (miniSellVol) {\n        state.tradeDefi.miniSellVol = miniSellVol\n      }\n      if (sellVol !== undefined) {\n        state.tradeDefi.sellVol = sellVol\n      }\n      if (buyVol !== undefined) {\n        state.tradeDefi.buyVol = buyVol\n      }\n      if (fee) {\n        state.tradeDefi.fee = fee\n      }\n      if (feeRaw) {\n        state.tradeDefi.feeRaw = feeRaw\n      }\n      if (depositPrice) {\n        state.tradeDefi.depositPrice = depositPrice\n      }\n      if (withdrawPrice) {\n        state.tradeDefi.withdrawPrice = withdrawPrice\n      }\n    },\n  },\n})\nexport { tradeDefiSlice }\nexport const { updateTradeDefi, resetTradeDefi } = tradeDefiSlice.actions\n"
  },
  {
    "path": "packages/core/src/stores/router/tradeDual/hook.ts",
    "content": "import { useDispatch, useSelector } from 'react-redux'\nimport { updateTradeDual, resetTradeDual, updateEditDual, resetEditDual } from './reducer'\nimport { EditDual, TradeDual, TradeDualStatus } from './interface'\nimport React from 'react'\nimport { DualViewInfo, DualViewOrder } from '@loopring-web/common-resources'\n\nexport function useTradeDual<R = DualViewInfo>(): TradeDualStatus<R> & {\n  updateTradeDual: (tradeDual: Partial<TradeDual<R>>) => void\n  resetTradeDual: () => void\n  updateEditDual: (tradeDual: EditDual<any> & DualViewOrder) => void\n  resetEditDual: () => void\n} {\n  const tradeDualStatus: TradeDualStatus<R> = useSelector((state: any) => state._router_tradeDual)\n  const dispatch = useDispatch()\n  return {\n    ...tradeDualStatus,\n    updateTradeDual: React.useCallback(\n      (tradeDual: Partial<TradeDual<R>>) => {\n        dispatch(updateTradeDual(tradeDual))\n      },\n      [dispatch],\n    ),\n    resetTradeDual: React.useCallback(() => {\n      dispatch(resetTradeDual(undefined))\n    }, [dispatch]),\n    updateEditDual: React.useCallback(\n      (tradeDual: EditDual<any> & DualViewOrder) => {\n        dispatch(updateEditDual(tradeDual))\n      },\n      [dispatch],\n    ),\n    resetEditDual: React.useCallback(() => {\n      dispatch(resetEditDual(undefined))\n    }, [dispatch]),\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/router/tradeDual/index.ts",
    "content": "export * from './hook'\nexport * from './interface'\nexport * from './reducer'\n"
  },
  {
    "path": "packages/core/src/stores/router/tradeDual/interface.ts",
    "content": "import { DualCalcData, DualViewOrder } from '@loopring-web/common-resources'\n\nexport type TradeDual<R> = DualCalcData<R>\nexport type EditDual<I> = {\n  dualViewInfo: I\n  tradeData: {\n    isRenew: boolean\n    renewTargetPrice?: string\n    renewDuration?: number\n  }\n} & I\n\nexport type TradeDualStatus<R, I = DualViewOrder> = {\n  tradeDual: TradeDual<R>\n  editDual: EditDual<I>\n  __DAYS__: 30\n  __SUBMIT_LOCK_TIMER__: 1000\n  __TOAST_AUTO_CLOSE_TIMER__: 3000\n}\n"
  },
  {
    "path": "packages/core/src/stores/router/tradeDual/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { EditDual, TradeDual, TradeDualStatus } from './interface'\nimport { DualViewInfo, DualViewOrder } from '@loopring-web/common-resources'\n\nconst initialState: TradeDualStatus<DualViewInfo> = {\n  tradeDual: {} as any,\n  editDual: {} as any,\n  __DAYS__: 30,\n  // __API_REFRESH__: 15000,\n  __SUBMIT_LOCK_TIMER__: 1000,\n  __TOAST_AUTO_CLOSE_TIMER__: 3000,\n}\nconst tradeDualSlice: Slice<TradeDualStatus<DualViewInfo>> = createSlice({\n  name: '_router_tradeDual',\n  initialState,\n  reducers: {\n    resetTradeDual(state) {\n      state.tradeDual = {} as any\n    },\n    resetEditDual(state) {\n      state.editDual = {} as any\n    },\n    updateTradeDual(state, action: PayloadAction<Partial<TradeDual<DualViewInfo>>>) {\n      const {\n        quota,\n        lessEarnVol,\n        lessEarnTokenSymbol,\n        greaterEarnVol,\n        greaterEarnTokenSymbol,\n        maxSellAmount,\n        miniSellVol,\n        dualViewInfo,\n        feeVol,\n        feeTokenSymbol,\n        maxFeeBips,\n        sellToken,\n        buyToken,\n        balance,\n        request,\n        coinSell,\n        sellVol,\n      } = action.payload\n      if (dualViewInfo !== undefined) {\n        state.tradeDual.dualViewInfo = dualViewInfo\n      }\n      if (sellToken !== undefined) {\n        state.tradeDual.sellToken = sellToken\n      }\n      if (quota !== undefined) {\n        state.tradeDual.quota = quota\n      }\n      if (coinSell) {\n        state.tradeDual.coinSell = coinSell\n      }\n      if (buyToken !== undefined) {\n        state.tradeDual.buyToken = buyToken\n      }\n\n      if (request) {\n        state.tradeDual.request = request\n      }\n\n      if (maxSellAmount) {\n        state.tradeDual.maxSellAmount = maxSellAmount\n      }\n\n      if (miniSellVol) {\n        state.tradeDual.miniSellVol = miniSellVol\n      }\n      if (maxFeeBips !== undefined) {\n        state.tradeDual.maxFeeBips = maxFeeBips\n      }\n      if (lessEarnVol) {\n        state.tradeDual.lessEarnVol = lessEarnVol\n      }\n      if (lessEarnTokenSymbol) {\n        state.tradeDual.lessEarnTokenSymbol = lessEarnTokenSymbol\n      }\n      if (greaterEarnVol) {\n        state.tradeDual.greaterEarnVol = greaterEarnVol\n      }\n      if (greaterEarnTokenSymbol) {\n        state.tradeDual.greaterEarnTokenSymbol = greaterEarnTokenSymbol\n      }\n      if (feeVol) {\n        state.tradeDual.feeVol = feeVol\n      }\n      if (feeTokenSymbol) {\n        state.tradeDual.feeTokenSymbol = feeTokenSymbol\n      }\n      if (balance) {\n        state.tradeDual.balance = balance\n      }\n      if (sellVol) {\n        state.tradeDual.sellVol = sellVol\n      }\n    },\n    updateEditDual(state, action: PayloadAction<EditDual<any> & DualViewOrder>) {\n      state.editDual = { ...action.payload }\n    },\n  },\n})\nexport { tradeDualSlice }\nexport const { updateTradeDual, resetTradeDual, updateEditDual, resetEditDual } =\n  tradeDualSlice.actions\n"
  },
  {
    "path": "packages/core/src/stores/router/tradeLite/hook.ts",
    "content": "import { useDispatch, useSelector } from 'react-redux'\nimport { updatePageTradeLite } from './reducer'\nimport { PageTradeLite, PageTradeLiteStatus } from './interface'\nimport React from 'react'\nimport { RequireOne } from '@loopring-web/common-resources'\n\nexport function usePageTradeLite(): PageTradeLiteStatus & {\n  updatePageTradeLite: (pageTradeLite: RequireOne<PageTradeLite, 'market'>) => void\n} {\n  const pageTradeLiteStatus: PageTradeLiteStatus = useSelector(\n    (state: any) => state._router_pageTradeLite,\n  )\n  const dispatch = useDispatch()\n  return {\n    ...pageTradeLiteStatus,\n    updatePageTradeLite: React.useCallback(\n      (pageTradeLite: RequireOne<PageTradeLite, 'market'>) => {\n        dispatch(updatePageTradeLite(pageTradeLite))\n      },\n      [dispatch],\n    ),\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/router/tradeLite/index.ts",
    "content": "export * from './hook'\nexport * from './interface'\nexport * from './reducer'\n"
  },
  {
    "path": "packages/core/src/stores/router/tradeLite/interface.ts",
    "content": "import * as sdk from '@loopring-web/loopring-sdk'\nimport { MarketType, Ticker } from '@loopring-web/common-resources'\nimport { MarketCalcParams, OrderInfoPatch } from '../tradePro'\n\nexport type PageTradeLite = {\n  market?: MarketType // eg: ETH-LRC, Pair from loopring market\n  tradePair?: MarketType //eg: ETH-LRC or LRC-ETH  ${sell}-${buy}\n  request?: sdk.SubmitOrderRequestV3 | null | undefined\n  minOrderInfo?: (sdk.OrderInfo & OrderInfoPatch) | undefined | null\n  calcTradeParams?: Partial<MarketCalcParams> | null | undefined\n  priceImpactObj?:\n    | {\n        // account has activated or undefined\n        value: number | string\n        priceImpactColor: string\n        priceLevel: number | string\n      }\n    | null\n    | undefined\n  depth?: sdk.DepthData | undefined\n  ticker?: Ticker | undefined\n  ammPoolSnapshot?: sdk.AmmPoolSnapshot | undefined\n  tradeChannel?: undefined | sdk.TradeChannel\n  orderType?: undefined | sdk.OrderType\n  feeBips?: number | string\n  takerRate?: number | string\n  quoteMinAmtInfo?: number | string\n  buyMinAmtInfo?: undefined | sdk.OrderInfo\n  sellMinAmtInfo?: undefined | sdk.OrderInfo\n  lastStepAt?: 'sell' | 'buy' | undefined\n  close?: string\n  totalFee?: number | string\n  maxFeeBips?: number\n  feeTakerRate?: number\n  tradeCost?: string\n}\n\nexport type PageTradeLiteStatus = {\n  pageTradeLite: PageTradeLite\n  __DAYS__: 30\n  __SUBMIT_LOCK_TIMER__: 1000\n  __TOAST_AUTO_CLOSE_TIMER__: 3000\n}\n"
  },
  {
    "path": "packages/core/src/stores/router/tradeLite/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { PageTradeLite, PageTradeLiteStatus } from './interface'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { MAPFEEBIPS } from '../../../defs'\n\nconst initState = {\n  market: undefined,\n  tradePair: undefined,\n  calcTradeParams: undefined,\n  priceImpactObj: undefined,\n  maxFeeBips: MAPFEEBIPS,\n}\n\nconst initialState: PageTradeLiteStatus = {\n  pageTradeLite: initState,\n  __DAYS__: 30,\n  __SUBMIT_LOCK_TIMER__: 1000,\n  __TOAST_AUTO_CLOSE_TIMER__: 3000,\n}\nconst pageTradeLiteSlice: Slice<PageTradeLiteStatus> = createSlice({\n  name: '_router_pageTradeLite',\n  initialState,\n  reducers: {\n    resetSwap(state) {\n      state.pageTradeLite = initState\n    },\n    updatePageTradeLite(state, action: PayloadAction<Partial<PageTradeLite>>) {\n      const {\n        market,\n        depth,\n        ticker,\n        ammPoolSnapshot,\n        tradePair,\n        quoteMinAmtInfo,\n        minOrderInfo,\n        request,\n        calcTradeParams,\n        priceImpactObj,\n        feeBips,\n        totalFee,\n        takerRate,\n        buyMinAmtInfo,\n        sellMinAmtInfo,\n        lastStepAt,\n        close,\n        maxFeeBips,\n        feeTakerRate,\n        tradeCost,\n      } = action.payload\n      if (market !== state.pageTradeLite.market) {\n        state.pageTradeLite = {\n          market,\n          tradePair, //eg: ETH-LRC or LRC-ETH  ${sell}-${buy}\n          request,\n          calcTradeParams,\n          depth,\n          ticker,\n          ammPoolSnapshot,\n          priceImpactObj,\n          tradeChannel: calcTradeParams\n            ? calcTradeParams.exceedDepth\n              ? sdk.TradeChannel.BLANK\n              : sdk.TradeChannel.MIXED\n            : undefined,\n          orderType: calcTradeParams\n            ? calcTradeParams.exceedDepth\n              ? sdk.OrderType.ClassAmm\n              : sdk.OrderType.TakerOnly\n            : undefined,\n          feeBips,\n          totalFee,\n          takerRate,\n          quoteMinAmtInfo,\n          buyMinAmtInfo,\n          sellMinAmtInfo,\n          minOrderInfo,\n          lastStepAt: undefined,\n          close,\n          maxFeeBips: MAPFEEBIPS,\n          tradeCost: tradeCost,\n          feeTakerRate: feeTakerRate,\n        }\n      } else {\n        if (lastStepAt) {\n          state.pageTradeLite.lastStepAt = lastStepAt\n        }\n        if (tradePair && tradePair) {\n          state.pageTradeLite.tradePair = tradePair\n          state.pageTradeLite.lastStepAt = undefined\n        }\n        if (depth) {\n          state.pageTradeLite.depth = depth\n        }\n        if (close) {\n          state.pageTradeLite.close = close\n        }\n        if (ticker) {\n          state.pageTradeLite.ticker = ticker\n        }\n        if (ammPoolSnapshot) {\n          state.pageTradeLite.ammPoolSnapshot = ammPoolSnapshot\n        }\n        if (request !== undefined) {\n          state.pageTradeLite.request = request\n        }\n        if (calcTradeParams !== undefined) {\n          state.pageTradeLite.calcTradeParams = calcTradeParams\n          state.pageTradeLite.orderType = calcTradeParams?.exceedDepth\n            ? sdk.OrderType.ClassAmm\n            : sdk.OrderType.TakerOnly\n          state.pageTradeLite.tradeChannel = calcTradeParams?.exceedDepth\n            ? sdk.TradeChannel.BLANK\n            : sdk.TradeChannel.MIXED\n        }\n\n        if (priceImpactObj) {\n          state.pageTradeLite.priceImpactObj = priceImpactObj\n        }\n        if (feeBips) {\n          state.pageTradeLite.feeBips = feeBips\n        }\n        if (totalFee) {\n          state.pageTradeLite.totalFee = totalFee\n        }\n        if (takerRate) {\n          state.pageTradeLite.takerRate = takerRate\n        }\n        if (sellMinAmtInfo) {\n          state.pageTradeLite.sellMinAmtInfo = sellMinAmtInfo\n        }\n        if (buyMinAmtInfo) {\n          state.pageTradeLite.buyMinAmtInfo = buyMinAmtInfo\n        }\n        if (minOrderInfo) {\n          state.pageTradeLite.minOrderInfo = minOrderInfo\n        }\n        if (maxFeeBips) {\n          state.pageTradeLite.maxFeeBips = maxFeeBips\n        }\n        state.pageTradeLite.tradeCost = tradeCost\n        state.pageTradeLite.feeTakerRate = feeTakerRate\n      }\n    },\n  },\n})\nexport { pageTradeLiteSlice }\nexport const { updatePageTradeLite, resetSwap } = pageTradeLiteSlice.actions\n"
  },
  {
    "path": "packages/core/src/stores/router/tradePro/hook.ts",
    "content": "import { useDispatch, useSelector } from 'react-redux'\nimport { updatePageTradePro } from './reducer'\nimport { PageTradePro, PageTradeProStatus } from './interface'\nimport React from 'react'\nimport { RequireOne } from '@loopring-web/common-resources'\n\nexport function usePageTradePro<C extends { [key: string]: any }>(): PageTradeProStatus<C> & {\n  updatePageTradePro: (pageTradePro: RequireOne<PageTradePro<C>, 'market'>) => void\n} {\n  const pageTradeProStatus: PageTradeProStatus<C> = useSelector(\n    (state: any) => state._router_pageTradePro,\n  )\n  const dispatch = useDispatch()\n  return {\n    ...pageTradeProStatus,\n    updatePageTradePro: React.useCallback(\n      (pageTradePro: RequireOne<PageTradePro<C>, 'market'>) => {\n        dispatch(updatePageTradePro(pageTradePro))\n      },\n      [dispatch],\n    ),\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/router/tradePro/index.ts",
    "content": "export * from './hook'\nexport * from './interface'\nexport * from './reducer'\n"
  },
  {
    "path": "packages/core/src/stores/router/tradePro/interface.ts",
    "content": "import * as sdk from '@loopring-web/loopring-sdk'\nimport {\n  DepthViewData,\n  MarketType,\n  TradeCalcProData,\n  TradeProType,\n  Ticker,\n} from '@loopring-web/common-resources'\nimport { DepthType, RawDataTradeItem } from '@loopring-web/component-lib'\n\nexport type MarketCalcParams = {\n  exceedDepth: boolean\n  isReverse: boolean\n  isAtoB: boolean\n  slipBips: string\n  takerRate: string | number\n  feeBips: string | number\n  output: string\n  sellAmt: string\n  buyAmt: string\n  amountS: string\n  amountBOut: string\n  amountBOutWithoutFee: string\n  amountBOutSlip: {\n    minReceived: string\n    minReceivedVal: string\n  }\n  priceImpact: string\n}\n\nexport type limitCalcParams = {\n  isBuy: boolean\n  priceImpact: number\n  baseVol: string\n  baseVolShow: string | number\n  amountBOut: string\n  quoteVol: string\n  quoteVolShow: string | number\n}\nexport type stopLimitCalcParams = limitCalcParams & {\n  stopPrice: string\n}\n\nexport type OrderInfoPatch = {\n  minAmtShow?: number | string\n  symbol?: string\n  minAmtCheck?: boolean\n}\n\nexport type PageTradePro<C> = {\n  market: MarketType // eg: ETH-LRC, Pair from loopring market\n  // tradePair?: MarketType  //eg: ETH-LRC or LRC-ETH  ${sell}-${buy}\n  request?: sdk.SubmitOrderRequestV3 | null | undefined\n  tradeCalcProData: Partial<TradeCalcProData<keyof C>>\n  calcTradeParams?: Partial<MarketCalcParams> | null | undefined\n  limitCalcTradeParams?: Partial<limitCalcParams> | null | undefined\n  stopLimitCalcTradeParams?: Partial<stopLimitCalcParams> | null | undefined\n  priceImpactObj?:\n    | {\n        // account has activated or undefined\n        value: number | string\n        priceImpactColor: string\n        priceLevel: number | string\n      }\n    | null\n    | undefined\n  tradeType: TradeProType\n  chooseDepth?: (DepthViewData & { type: DepthType | 'close' }) | null\n  precisionLevels?: { value: number; label: string }[]\n  depth?: sdk.DepthData | undefined\n  depthForCalc?: sdk.DepthData | undefined\n  depthLevel?: number\n  ticker?: Ticker | undefined\n  ammPoolSnapshot?: sdk.AmmPoolSnapshot | undefined\n  feeBips?: number | string\n  takerRate?: number | string\n  sellUserOrderInfo?: undefined | null | sdk.OrderInfo\n  buyUserOrderInfo?: undefined | null | sdk.OrderInfo\n  minOrderInfo?: undefined | null | Partial<sdk.OrderInfo & OrderInfoPatch>\n  lastStepAt?: 'base' | 'quote' | undefined\n  tradeArray?: RawDataTradeItem[]\n  tradeMapByTimeStamp?: {\n    [key: string]: RawDataTradeItem\n  }\n  totalFee?: number | string\n  maxFeeBips?: number\n  feeTakerRate?: number\n  tradeCost?: string\n}\n\nexport type PageTradeProStatus<C extends { [key: string]: any }> = {\n  pageTradePro: PageTradePro<C>\n  __DAYS__: 30\n  __API_REFRESH__: 15000\n  __SUBMIT_LOCK_TIMER__: 1000\n  __TOAST_AUTO_CLOSE_TIMER__: 3000\n  __AUTO_RE_CALC__: 3000\n}\n"
  },
  {
    "path": "packages/core/src/stores/router/tradePro/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { PageTradePro, PageTradeProStatus } from './interface'\nimport { RequireOne, TradeProType } from '@loopring-web/common-resources'\nimport { MAPFEEBIPS } from '../../../defs'\n\nconst initState = {\n  market: '' as any,\n  tradePair: undefined,\n  request: undefined,\n  calcTradeParams: undefined,\n  priceImpactObj: undefined,\n  tradeCalcProData: {},\n  tradeArray: [],\n  tradeType: TradeProType.buy,\n}\n\nconst initialState: PageTradeProStatus<{ [key: string]: any }> = {\n  pageTradePro: initState,\n  __DAYS__: 30,\n  __API_REFRESH__: 15000,\n  __SUBMIT_LOCK_TIMER__: 1000,\n  __TOAST_AUTO_CLOSE_TIMER__: 3000,\n  __AUTO_RE_CALC__: 3000,\n}\nconst pageTradeProSlice: Slice<PageTradeProStatus<{ [key: string]: any }>> = createSlice({\n  name: '_router_pageTradePro',\n  initialState,\n  reducers: {\n    resetOrderPge(state) {\n      state.pageTradePro = initState\n    },\n    updatePageTradePro(\n      state,\n      action: PayloadAction<RequireOne<PageTradePro<{ [key: string]: any }>, 'market'>>,\n    ) {\n      const {\n        market,\n        depth,\n        depthForCalc,\n        tradeType,\n        precisionLevels,\n        depthLevel,\n        ticker,\n        request,\n        tradeCalcProData,\n        ammPoolSnapshot,\n        calcTradeParams,\n        limitCalcTradeParams,\n        stopLimitCalcTradeParams,\n        priceImpactObj,\n        feeBips,\n        tradeArray,\n        tradeMapByTimeStamp,\n        totalFee,\n        takerRate,\n        chooseDepth,\n        sellUserOrderInfo,\n        buyUserOrderInfo,\n        minOrderInfo,\n        lastStepAt,\n        maxFeeBips,\n        feeTakerRate,\n        tradeCost,\n      } = action.payload\n      if (market !== state.pageTradePro.market) {\n        state.pageTradePro = {\n          ...initState,\n          tradeType: state.pageTradePro.tradeType ?? tradeType ?? initState.tradeType,\n          market,\n          tradeCalcProData: tradeCalcProData ? tradeCalcProData : {},\n          request,\n          calcTradeParams,\n          limitCalcTradeParams,\n          stopLimitCalcTradeParams,\n          depth,\n          depthForCalc,\n          ticker,\n          ammPoolSnapshot,\n          priceImpactObj,\n          feeBips,\n          totalFee,\n          takerRate,\n          tradeArray,\n          chooseDepth,\n          precisionLevels,\n          depthLevel,\n          sellUserOrderInfo,\n          buyUserOrderInfo,\n          minOrderInfo,\n          lastStepAt: undefined,\n          maxFeeBips: MAPFEEBIPS,\n          tradeCost: tradeCost,\n          feeTakerRate: feeTakerRate,\n        }\n      } else {\n        if (tradeType) {\n          state.pageTradePro.tradeType = tradeType\n        }\n        if (precisionLevels) {\n          state.pageTradePro.precisionLevels = precisionLevels\n        }\n        if (chooseDepth !== undefined) {\n          state.pageTradePro.chooseDepth = chooseDepth\n        }\n        if (depthLevel) {\n          state.pageTradePro.depthLevel = depthLevel\n        }\n\n        if (lastStepAt) {\n          state.pageTradePro.lastStepAt = lastStepAt\n        }\n        if (tradeCalcProData) {\n          state.pageTradePro.tradeCalcProData = tradeCalcProData\n        }\n        if (depth) {\n          state.pageTradePro.depth = depth\n        }\n        if (depthForCalc) {\n          state.pageTradePro.depthForCalc = depthForCalc\n        }\n        if (ticker) {\n          state.pageTradePro.ticker = ticker\n        }\n\n        if (ammPoolSnapshot) {\n          state.pageTradePro.ammPoolSnapshot = ammPoolSnapshot\n        }\n\n        if (request !== undefined) {\n          state.pageTradePro.request = request\n        }\n\n        if (calcTradeParams !== undefined) {\n          state.pageTradePro.calcTradeParams = calcTradeParams\n        }\n\n        if (limitCalcTradeParams !== undefined) {\n          state.pageTradePro.limitCalcTradeParams = limitCalcTradeParams\n        }\n        if (stopLimitCalcTradeParams !== undefined) {\n          state.pageTradePro.stopLimitCalcTradeParams = stopLimitCalcTradeParams\n        }\n\n        if (tradeArray) {\n          state.pageTradePro.tradeArray = tradeArray\n        }\n        if (tradeMapByTimeStamp) {\n          state.pageTradePro.tradeMapByTimeStamp = tradeMapByTimeStamp\n        }\n        if (priceImpactObj) {\n          state.pageTradePro.priceImpactObj = priceImpactObj\n        }\n        if (feeBips) {\n          state.pageTradePro.feeBips = feeBips\n        }\n        if (totalFee) {\n          state.pageTradePro.totalFee = totalFee\n        }\n        if (takerRate) {\n          state.pageTradePro.takerRate = takerRate\n        }\n        if (sellUserOrderInfo !== undefined) {\n          state.pageTradePro.sellUserOrderInfo = sellUserOrderInfo\n        }\n        if (buyUserOrderInfo !== undefined) {\n          state.pageTradePro.buyUserOrderInfo = buyUserOrderInfo\n        }\n        if (minOrderInfo !== undefined) {\n          state.pageTradePro.minOrderInfo = minOrderInfo\n        }\n        if (maxFeeBips) {\n          state.pageTradePro.maxFeeBips = maxFeeBips\n        }\n\n        state.pageTradePro.tradeCost = tradeCost\n        state.pageTradePro.feeTakerRate = feeTakerRate\n      }\n    },\n  },\n})\nexport { pageTradeProSlice }\nexport const { updatePageTradePro } = pageTradeProSlice.actions\n"
  },
  {
    "path": "packages/core/src/stores/router/tradeStake/hook.ts",
    "content": "import { useDispatch, useSelector } from 'react-redux'\nimport { updateTradeStake, resetTradeStake, updateRedeemStake, resetRedeemStake } from './reducer'\nimport { RedeemStakeStatus, TradeStakeStatus } from './interface'\nimport React from 'react'\nimport { RedeemStake, TradeStake } from '@loopring-web/common-resources'\n\nexport function useTradeStake<C extends { [key: string]: any }>(): TradeStakeStatus<C> & {\n  updateTradeStake: (tradeStake: Partial<TradeStake<C>>) => void\n  resetTradeStake: () => void\n} {\n  const tradeStakeStatus: TradeStakeStatus<C> = useSelector(\n    (state: any) => state._router_tradeStake,\n  )\n  const dispatch = useDispatch()\n  return {\n    ...tradeStakeStatus,\n    updateTradeStake: React.useCallback(\n      (tradeStake: Partial<TradeStake<C>>) => {\n        dispatch(updateTradeStake(tradeStake))\n      },\n      [dispatch],\n    ),\n    resetTradeStake: React.useCallback(() => {\n      dispatch(resetTradeStake(undefined))\n    }, [dispatch]),\n  }\n}\n\nexport function useRedeemStake<C extends { [key: string]: any }>(): RedeemStakeStatus<C> & {\n  updateRedeemStake: (RedeemStake: Partial<RedeemStake<C>>) => void\n  resetRedeemStake: () => void\n} {\n  const redeemStakeStatus: RedeemStakeStatus<C> = useSelector(\n    (state: any) => state._router_redeemStake,\n  )\n  const dispatch = useDispatch()\n  return {\n    ...redeemStakeStatus,\n    updateRedeemStake: React.useCallback(\n      (redeemStake: Partial<RedeemStake<C>>) => {\n        dispatch(updateRedeemStake(redeemStake))\n      },\n      [dispatch],\n    ),\n    resetRedeemStake: React.useCallback(() => {\n      dispatch(resetRedeemStake(undefined))\n    }, [dispatch]),\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/router/tradeStake/index.ts",
    "content": "export * from './hook'\nexport * from './interface'\nexport * from './reducer'\n"
  },
  {
    "path": "packages/core/src/stores/router/tradeStake/interface.ts",
    "content": "import { RedeemStake, TradeStake } from '@loopring-web/common-resources'\n\nexport type TradeStakeStatus<C> = {\n  tradeStake: TradeStake<C>\n  __DAYS__: 30\n  __SUBMIT_LOCK_TIMER__: 1000\n  __TOAST_AUTO_CLOSE_TIMER__: 3000\n}\n\nexport type RedeemStakeStatus<C> = {\n  redeemStake: RedeemStake<C>\n  __DAYS__: 30\n  __SUBMIT_LOCK_TIMER__: 1000\n  __TOAST_AUTO_CLOSE_TIMER__: 3000\n}\n"
  },
  {
    "path": "packages/core/src/stores/router/tradeStake/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { RedeemStakeStatus, TradeStakeStatus } from './interface'\nimport { IBData, RedeemStake, TradeStake } from '@loopring-web/common-resources'\nimport { TokenInfo } from '@loopring-web/loopring-sdk'\n\nconst initState: TradeStake<any> = {\n  sellToken: {} as any,\n  sellVol: '0',\n  deFiSideCalcData: {\n    coinSell: {},\n    stakeViewInfo: {} as any,\n  },\n}\ntype R = { [key: string]: any }\nconst initialState: TradeStakeStatus<IBData<R>> = {\n  tradeStake: initState,\n  __DAYS__: 30,\n  // __API_REFRESH__: 15000,\n  __SUBMIT_LOCK_TIMER__: 1000,\n  __TOAST_AUTO_CLOSE_TIMER__: 3000,\n}\nconst tradeStakeSlice: Slice<TradeStakeStatus<IBData<R>>> = createSlice({\n  name: 'router_tradeStake',\n  initialState,\n  reducers: {\n    resetTradeStake(state) {\n      state.tradeStake = initState\n    },\n    updateTradeStake(state, action: PayloadAction<TradeStake<IBData<any>>>) {\n      const { sellToken, sellVol, deFiSideCalcData, request } = action.payload\n      state.tradeStake = {\n        ...initState,\n        sellToken: sellToken as TokenInfo,\n      }\n\n      if (request) {\n        state.tradeStake.request = request\n      }\n\n      if (deFiSideCalcData) {\n        // let _deFiCalcData = { ...deFiCalcData };\n        state.tradeStake.deFiSideCalcData = deFiSideCalcData\n        // if (_deFiCalcData.AtoB === undefined) {\n        //   _deFiCalcData.AtoB = state.tradeStake.deFiCalcData.AtoB;\n        //   _deFiCalcData.BtoA = state.tradeStake.deFiCalcData.BtoA;\n        // }\n      }\n\n      if (sellVol !== undefined) {\n        state.tradeStake.sellVol = sellVol\n      }\n    },\n  },\n})\n\nconst initRedeemState: RedeemStake<any> = {\n  sellToken: {} as any,\n  sellVol: '0',\n  deFiSideRedeemCalcData: {\n    coinSell: {},\n  } as any,\n}\nconst initialRedeemState: RedeemStakeStatus<any> = {\n  redeemStake: initRedeemState,\n  __DAYS__: 30,\n  // __API_REFRESH__: 15000,\n  __SUBMIT_LOCK_TIMER__: 1000,\n  __TOAST_AUTO_CLOSE_TIMER__: 3000,\n}\nconst redeemStakeSlice: Slice<RedeemStakeStatus<IBData<R>>> = createSlice({\n  name: '_router_redeemStake',\n  initialState: initialRedeemState,\n  reducers: {\n    resetRedeemStake(state) {\n      state.redeemStake = initRedeemState\n    },\n    updateRedeemStake(state, action: PayloadAction<RedeemStake<IBData<any>>>) {\n      const { sellToken, sellVol, deFiSideRedeemCalcData, request } = action.payload\n      state.redeemStake = {\n        ...initRedeemState,\n        sellToken: sellToken as TokenInfo,\n      }\n\n      if (request) {\n        state.redeemStake.request = request\n      }\n\n      if (deFiSideRedeemCalcData) {\n        // let _deFiCalcData = { ...deFiCalcData };\n        state.redeemStake.deFiSideRedeemCalcData = deFiSideRedeemCalcData\n        // if (_deFiCalcData.AtoB === undefined) {\n        //   _deFiCalcData.AtoB = state.redeemStake.deFiCalcData.AtoB;\n        //   _deFiCalcData.BtoA = state.redeemStake.deFiCalcData.BtoA;\n        // }\n      }\n\n      if (sellVol !== undefined) {\n        state.redeemStake.sellVol = sellVol\n      }\n    },\n  },\n})\nexport { tradeStakeSlice, redeemStakeSlice }\nexport const { updateTradeStake, resetTradeStake } = tradeStakeSlice.actions\nexport const { updateRedeemStake, resetRedeemStake } = redeemStakeSlice.actions\n"
  },
  {
    "path": "packages/core/src/stores/router/tradeVault/hook.ts",
    "content": "import { useDispatch, useSelector } from 'react-redux'\nimport {\n  resetVaultBorrow,\n  resetVaultExit,\n  resetVaultJoin,\n  resetVaultRepay,\n  resetVaultSwap,\n  updateVaultBorrow,\n  updateVaultExit,\n  updateVaultJoin,\n  updateVaultRepay,\n  updateVaultTrade,\n} from './reducer'\nimport { TradeVault, TradeVaultStatus } from './interface'\nimport React from 'react'\nimport {\n  IBData,\n  VaultBorrowData,\n  VaultExitData,\n  VaultJoinData,\n  VaultRepayData,\n} from '@loopring-web/common-resources'\n\nexport function useTradeVault() {\n  const tradeVaultStatus: TradeVaultStatus = useSelector((state: any) => state._router_tradeVault)\n  const dispatch = useDispatch()\n  return {\n    ...tradeVaultStatus,\n    updateTradeVault: React.useCallback(\n      (tradeVault: Partial<TradeVault>) => {\n        dispatch(updateVaultTrade(tradeVault))\n      },\n      [dispatch],\n    ),\n    resetTradeVault: React.useCallback(() => {\n      dispatch(resetVaultSwap(undefined))\n    }, [dispatch]),\n    updateVaultJoin: React.useCallback(\n      (tradeVault: Partial<VaultJoinData>) => {\n        dispatch(updateVaultJoin(tradeVault))\n      },\n      [dispatch],\n    ),\n    updateVaultExit: React.useCallback(\n      (tradeVault: Partial<VaultExitData>) => {\n        dispatch(updateVaultExit(tradeVault))\n      },\n      [dispatch],\n    ),\n    updateVaultBorrow: React.useCallback(\n      (tradeVault: Partial<VaultBorrowData<IBData<any> & { erc20Symbol: string }>>) => {\n        dispatch(updateVaultBorrow(tradeVault))\n      },\n      [dispatch],\n    ),\n    updateVaultRepay: React.useCallback(\n      (tradeVault: Partial<VaultRepayData<IBData<any> & { erc20Symbol: string }>>) => {\n        dispatch(updateVaultRepay(tradeVault))\n      },\n      [dispatch],\n    ),\n    resetVaultJoin: React.useCallback(() => {\n      dispatch(resetVaultJoin(undefined))\n    }, [dispatch]),\n    resetVaultExit: React.useCallback(() => {\n      dispatch(resetVaultExit(undefined))\n    }, [dispatch]),\n    resetVaultBorrow: React.useCallback(() => {\n      dispatch(resetVaultBorrow(undefined))\n    }, [dispatch]),\n    resetVaultRepay: React.useCallback(() => {\n      dispatch(resetVaultRepay(undefined))\n    }, [dispatch]),\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/router/tradeVault/index.ts",
    "content": "export * from './hook'\nexport * from './interface'\nexport * from './reducer'\n"
  },
  {
    "path": "packages/core/src/stores/router/tradeVault/interface.ts",
    "content": "import {\n  VaultTradeCalcData,\n  MarketType,\n  VaultJoinData,\n  VaultExitData,\n  IBData,\n  VaultBorrowData,\n  VaultRepayData,\n} from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { OrderInfoPatch } from '../tradePro'\n\nexport type TradeVault = {\n  market: MarketType\n  tradePair?: MarketType //eg: ETH-LRC or LRC-ETH  ${sell}-${buy}\n  request?: sdk.VaultOrderRequest | null | undefined\n  tradeCalcData: Partial<VaultTradeCalcData<any>>\n  depth?: sdk.DepthData | undefined\n  sellToken: string\n  buyToken: string\n  totalFeeRaw?: number | string\n  totalFee?: number | string\n  maxFeeBips?: number\n  sellMinAmtInfo?: string\n  sellMaxL2AmtInfo?: string\n  sellMaxAmtInfo?: string\n  lastStepAt: 'sell' | 'buy' | undefined\n  isRequiredBorrow: boolean\n  sellUserOrderInfo?: undefined | null | sdk.OrderInfo\n  buyUserOrderInfo?: undefined | null | sdk.OrderInfo\n  minOrderInfo?: undefined | null | Partial<sdk.OrderInfo & OrderInfoPatch>\n  info: sdk.VaultMarket\n  smallTradePromptAmt?: string\n  upSlippageFeeBips?: string\n}\n\nexport type TradeVaultStatus = {\n  tradeVault: TradeVault\n  vaultJoinData: VaultJoinData\n  vaultExitData: VaultExitData\n  vaultBorrowData: VaultBorrowData<IBData<any> & { erc20Symbol: string }>\n  vaultRepayData: VaultRepayData<IBData<any> & { erc20Symbol: string }>\n  __DAYS__: 30\n  __SUBMIT_LOCK_TIMER__: 1000\n  __TOAST_AUTO_CLOSE_TIMER__: 3000\n}\n"
  },
  {
    "path": "packages/core/src/stores/router/tradeVault/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { TradeVault, TradeVaultStatus } from './interface'\nimport { MAPFEEBIPS } from '../../../defs'\nimport {\n  IBData,\n  VaultBorrowData,\n  VaultExitData,\n  VaultJoinData,\n  VaultRepayData,\n} from '@loopring-web/common-resources'\n\nconst initState: TradeVault = {\n  market: undefined,\n  tradePair: undefined,\n  tradeCalcData: {\n    isVault: true,\n  },\n  maxFeeBips: MAPFEEBIPS,\n} as unknown as TradeVault\nconst initJoinState: VaultJoinData = {} as unknown as VaultJoinData\nconst initExitState: VaultExitData = {} as unknown as VaultExitData\nconst initBorrowState: VaultBorrowData<IBData<any> & { erc20Symbol: string }> =\n  {} as unknown as VaultBorrowData<IBData<any> & { erc20Symbol: string }>\nconst initRepayState: VaultRepayData<IBData<any> & { erc20Symbol: string }> =\n  {} as unknown as VaultRepayData<IBData<any> & { erc20Symbol: string }>\n\nconst initialState: TradeVaultStatus = {\n  // pageTradePro: initState,\n  tradeVault: initState,\n  vaultJoinData: initJoinState,\n  vaultExitData: initExitState,\n  vaultBorrowData: initBorrowState,\n  vaultRepayData: initRepayState,\n  __DAYS__: 30,\n  __SUBMIT_LOCK_TIMER__: 1000,\n  __TOAST_AUTO_CLOSE_TIMER__: 3000,\n}\nconst tradeVaultSlice: Slice<TradeVaultStatus> = createSlice({\n  name: '_router_tradeVault',\n  initialState,\n  reducers: {\n    resetVaultSwap(state) {\n      state.tradeVault = initState\n    },\n    resetVaultJoin(state) {\n      state.vaultJoinData = initJoinState\n    },\n    resetVaultExit(state) {\n      state.vaultExitData = initExitState\n    },\n    resetVaultBorrow(state) {\n      state.vaultBorrowData = initBorrowState\n    },\n    resetVaultRepay(state) {\n      state.vaultRepayData = initRepayState\n    },\n    updateVaultTrade(state, action: PayloadAction<Partial<TradeVault>>) {\n      const {\n        market,\n        tradePair,\n        request,\n        tradeCalcData,\n        depth,\n        sellUserOrderInfo,\n        buyUserOrderInfo,\n        minOrderInfo,\n        lastStepAt,\n        totalFee,\n        sellMinAmtInfo,\n        sellMaxL2AmtInfo,\n        sellMaxAmtInfo,\n        isRequiredBorrow,\n        // VaultMarket,\n        maxFeeBips,\n        smallTradePromptAmt,\n        upSlippageFeeBips,\n        ...rest\n      } = action.payload\n      if (market !== state.tradeVault.market && market && tradePair) {\n        // @ts-ignore\n        const [_, sellToken, buyToken] = (tradePair ?? '').match(/(\\w+)-(\\w+)/i)\n        // @ts-ignore\n        state.tradeVault = {\n          market,\n          tradePair, //eg: ETH-LRC or LRC-ETH  ${sell}-${buy}\n          request,\n          depth,\n          totalFee,\n          minOrderInfo,\n          sellToken,\n          buyToken,\n          tradeCalcData: tradeCalcData as any,\n          sellUserOrderInfo,\n          buyUserOrderInfo,\n          sellMinAmtInfo,\n          sellMaxL2AmtInfo,\n          sellMaxAmtInfo,\n          lastStepAt: undefined,\n          maxFeeBips,\n          ...rest,\n        }\n      } else {\n        if (lastStepAt) {\n          state.tradeVault.lastStepAt = lastStepAt\n        }\n\n        if (tradePair && tradePair) {\n          const [_, sellToken, buyToken] = tradePair.match(/(\\w+)-(\\w+)/i)\n          state.tradeVault.tradePair = tradePair\n          state.tradeVault.sellToken = sellToken\n          state.tradeVault.buyToken = buyToken\n          state.tradeVault.lastStepAt = undefined\n        }\n        if (depth) {\n          state.tradeVault.depth = depth\n        }\n\n        if (totalFee) {\n          state.tradeVault.totalFee = totalFee\n        }\n        // if (takerRate) {\n        //   state.tradeVault.takerRate = takerRate;\n        // }\n        if (minOrderInfo) {\n          state.tradeVault.minOrderInfo = minOrderInfo\n        }\n        if (maxFeeBips !== undefined) {\n          state.tradeVault.maxFeeBips = maxFeeBips\n        }\n        if (tradeCalcData) {\n          state.tradeVault.tradeCalcData = tradeCalcData\n        }\n        if (sellUserOrderInfo !== undefined) {\n          state.tradeVault.sellUserOrderInfo = sellUserOrderInfo\n        }\n        if (buyUserOrderInfo !== undefined) {\n          state.tradeVault.buyUserOrderInfo = buyUserOrderInfo\n        }\n\n        if (sellMinAmtInfo !== undefined) {\n          state.tradeVault.sellMinAmtInfo = sellMinAmtInfo\n        }\n        if (smallTradePromptAmt !== undefined) {\n          state.tradeVault.smallTradePromptAmt = smallTradePromptAmt\n        }\n        if (upSlippageFeeBips !== undefined) {\n          state.tradeVault.upSlippageFeeBips = upSlippageFeeBips\n        }\n        if (sellMaxL2AmtInfo !== undefined) {\n          state.tradeVault.sellMaxL2AmtInfo = sellMaxL2AmtInfo\n        }\n        if (sellMaxAmtInfo !== undefined) {\n          state.tradeVault.sellMaxAmtInfo = sellMaxAmtInfo\n        }\n        if (isRequiredBorrow !== undefined) {\n          state.tradeVault.isRequiredBorrow = isRequiredBorrow\n        }\n      }\n    },\n    updateVaultJoin(state, action: PayloadAction<Partial<VaultJoinData>>) {\n      state.vaultJoinData = { ...action.payload }\n    },\n    updateVaultExit(state, action: PayloadAction<Partial<VaultExitData>>) {\n      state.vaultExitData = { ...action.payload }\n    },\n    updateVaultBorrow(\n      state,\n      action: PayloadAction<Partial<VaultBorrowData<IBData<any> & { erc20Symbol: string }>>>,\n    ) {\n      state.vaultBorrowData = { ...action.payload }\n    },\n    updateVaultRepay(\n      state,\n      action: PayloadAction<Partial<VaultRepayData<IBData<any> & { erc20Symbol: string }>>>,\n    ) {\n      state.vaultRepayData = { ...action.payload }\n    },\n  },\n})\n\nexport { tradeVaultSlice }\nexport const {\n  resetVaultJoin,\n  updateVaultJoin,\n  resetVaultExit,\n  resetVaultSwap,\n  updateVaultTrade,\n  updateVaultExit,\n  updateVaultBorrow,\n  updateVaultRepay,\n  resetVaultBorrow,\n  resetVaultRepay,\n} = tradeVaultSlice.actions\n"
  },
  {
    "path": "packages/core/src/stores/socket/hook.ts",
    "content": "import { useDispatch, useSelector } from 'react-redux'\nimport { sendSocketTopic, socketEnd, statusUnset, socketUserEnd } from './reducer'\nimport { SocketMap, SocketUserMap } from './interface'\nimport React from 'react'\nimport { StateBase } from '@loopring-web/common-resources'\n\nexport function useSocket() {\n  const socket: StateBase & { socket: SocketMap } = useSelector((state: any) => state.socket)\n  const dispatch = useDispatch()\n  return {\n    ...socket,\n    statusUnset: React.useCallback(() => dispatch(statusUnset(undefined)), [dispatch]),\n    sendSocketTopic: React.useCallback(\n      (socket: SocketMap | SocketUserMap) => dispatch(sendSocketTopic({ socket })),\n      [dispatch],\n    ),\n    socketUserEnd: React.useCallback(() => dispatch(socketUserEnd(undefined)), [dispatch]),\n    socketEnd: React.useCallback(() => dispatch(socketEnd(undefined)), [dispatch]),\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/socket/index.ts",
    "content": "export * from './hook'\nexport * from './interface'\nexport * from './reducer'\n"
  },
  {
    "path": "packages/core/src/stores/socket/interface.ts",
    "content": "/* eslint-disable  @typescript-eslint/ban-types */\n/* tslint:disable  @typescript-eslint/ban-types */\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nexport type TickerSocket = string\nexport type SocketUserMap = {\n  [sdk.WsTopicType.account]?: boolean\n  [sdk.WsTopicType.notification]?: {\n    address: string\n    network: sdk.NetworkWallet\n  }\n  // @ts-ignore\n  [sdk.WsTopicType.l2Common]?: {\n    address: string\n    network: sdk.NetworkWallet\n  }\n}\n//sdk.WsTopicType.\nexport type SocketMap = {\n  [sdk.WsTopicType.ticker]?: TickerSocket[]\n  [sdk.WsTopicType.order]?: any[]\n  [sdk.WsTopicType.trade]?: any[]\n  [sdk.WsTopicType.mixtrade]?: any[]\n  [sdk.WsTopicType.candlestick]?: any[]\n  [sdk.WsTopicType.ammpool]?: any[]\n  [sdk.WsTopicType.orderbook]?: {\n    markets: any[]\n    level?: number\n    count?: number\n    snapshot?: boolean\n  }\n  [sdk.WsTopicType.mixorder]?: {\n    showOverlap?: boolean\n    markets: any[]\n    level?: number\n    count?: number\n    snapshot?: boolean\n  }\n  [sdk.WsTopicType.btradedepth]?: {\n    showOverlap?: boolean\n    markets: any[]\n    level?: number\n    count?: number\n    snapshot?: boolean\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/socket/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { SagaStatus, StateBase } from '@loopring-web/common-resources'\nimport { SocketMap, SocketUserMap } from './interface'\n\nconst initialState: StateBase & { socket: SocketMap & SocketUserMap } = {\n  socket: {},\n  status: SagaStatus.UNSET,\n  errorMessage: null,\n}\nconst socketSlice: Slice<StateBase & { socket: SocketMap }> = createSlice({\n  name: 'socket',\n  initialState,\n  reducers: {\n    socketEnd(state, _action: PayloadAction<undefined>) {\n      state.socket = {}\n      state.status = SagaStatus.PENDING\n    },\n    socketUserEnd(state, _action: PayloadAction<undefined>) {\n      state.status = SagaStatus.PENDING\n    },\n    // socketNotSupport(state,action: PayloadAction<undefined>) {\n    //\n    // },\n    sendSocketTopic(state, _action: PayloadAction<{ socket: SocketMap }>) {\n      state.status = SagaStatus.PENDING\n    },\n    getSocketStatus(state, action: PayloadAction<{ socket: SocketMap } | Error>) {\n      // @ts-ignore\n      if ((action.payload as any).error) {\n        state.status = SagaStatus.ERROR\n        state.errorMessage = (action.payload as any).error\n        state.socket = {}\n        return\n      }\n      state.socket = (action.payload as { socket: SocketMap })?.socket ?? {}\n      state.status = SagaStatus.DONE\n    },\n\n    statusUnset: (state) => {\n      state.status = SagaStatus.UNSET\n    },\n  },\n})\nexport { socketSlice }\nexport const { getSocketStatus, socketUserEnd, sendSocketTopic, socketEnd, statusUnset } =\n  socketSlice.actions\n"
  },
  {
    "path": "packages/core/src/stores/socket/saga.ts",
    "content": "import { all, fork, put, takeLatest } from 'redux-saga/effects'\nimport { getSocketStatus, sendSocketTopic, socketEnd, socketUserEnd } from './reducer'\nimport { SocketMap, SocketUserMap, store } from '../index'\nimport { AccountStatus, MapChainId, myLog } from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nconst getSocket = async ({ socket, apiKey }: { socket: any; apiKey?: string }) => {\n  await (window as any).loopringSocket.socketSendMessage({ socket, apiKey })\n  myLog('socketStatus get', socket)\n  return\n}\n\nexport function* closeSocket() {\n  try {\n    const {\n      settings: { defaultNetwork },\n      account,\n    } = store.getState()\n    if ((window as any).loopringSocket) {\n      const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n      const networkWallet: sdk.NetworkWallet = [\n        sdk.NetworkWallet.ETHEREUM,\n        sdk.NetworkWallet.GOERLI,\n        sdk.NetworkWallet.SEPOLIA,\n      ].includes(network as sdk.NetworkWallet)\n        ? sdk.NetworkWallet.ETHEREUM\n        : sdk.NetworkWallet[network]\n      let socket = {}\n      if (account.readyState !== AccountStatus.ACTIVATED) {\n        yield (window as any).loopringSocket.socketClose()\n        myLog('socketStatus end')\n      } else {\n        socket = {\n          [sdk.WsTopicType.account]: true,\n          [sdk.WsTopicType.notification]: {\n            address: account.accAddress,\n            network: networkWallet,\n          },\n        }\n        // SocketUserMap\n        yield getSocket({\n          socket,\n          apiKey: account.apiKey,\n        })\n      }\n      yield put(getSocketStatus({ socket }))\n    } else {\n      yield put(getSocketStatus(undefined))\n    }\n  } catch (err) {\n    yield put(getSocketStatus({ error: err }))\n  }\n}\n\nexport function* closeUserSocket() {\n  let { socket } = store.getState().socket\n  try {\n    if ((window as any).loopringSocket) {\n      delete socket[sdk.WsTopicType.account]\n      delete socket[sdk.WsTopicType.notification]\n      yield getSocket({\n        socket,\n      })\n      yield put(getSocketStatus({ socket }))\n    } else {\n      yield put(getSocketStatus(undefined))\n    }\n  } catch (err) {\n    yield put(getSocketStatus({ error: err }))\n  }\n}\nvar firstTimeSubscribe = false\nexport function* sendMessage({ payload }: { payload: { socket: SocketMap } }) {\n  try {\n    const {\n      settings: { defaultNetwork },\n      account,\n    } = store.getState()\n    const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n    const networkWallet: sdk.NetworkWallet = [\n      sdk.NetworkWallet.ETHEREUM,\n      sdk.NetworkWallet.GOERLI,\n      sdk.NetworkWallet.SEPOLIA,\n    ].includes(network as sdk.NetworkWallet)\n      ? sdk.NetworkWallet.ETHEREUM\n      : sdk.NetworkWallet[network]\n    const { socket } = payload\n    if ((window as any).loopringSocket) {\n      let userSocket: SocketMap & SocketUserMap = { ...socket }\n      if (account.readyState == AccountStatus.ACTIVATED && account.accAddress) {\n        if (!firstTimeSubscribe) {\n          userSocket = socket\n        } else {\n          firstTimeSubscribe = false\n          userSocket = {\n            ...userSocket,\n            [sdk.WsTopicType.account]: true,\n            [sdk.WsTopicType.notification]: {\n              address: account.accAddress,\n              network: networkWallet,\n            },\n          }\n        }\n      }\n      yield getSocket({\n        socket: userSocket,\n        apiKey: account.apiKey,\n      })\n      yield put(getSocketStatus({ socket: userSocket }))\n    } else {\n      yield put(getSocketStatus(undefined))\n    }\n  } catch (err) {\n    yield put(getSocketStatus({ error: err }))\n  }\n}\n\nfunction* socketEndSaga() {\n  yield all([takeLatest(socketEnd, closeSocket)])\n}\nfunction* socketUserEndSaga() {\n  yield all([takeLatest(socketUserEnd, closeUserSocket)])\n}\n\nfunction* socketSendMessageSaga() {\n  yield all([takeLatest<any>(sendSocketTopic, sendMessage)])\n}\n\nexport const socketForks = [\n  // fork(socketSaga),\n  fork(socketEndSaga),\n  fork(socketSendMessageSaga),\n  fork(socketUserEndSaga),\n  //   fork(initConfig),\n]\n"
  },
  {
    "path": "packages/core/src/stores/system/hook.ts",
    "content": "import { useDispatch, useSelector } from 'react-redux'\nimport { updateSystem, statusUnset, clearSystem } from './reducer'\nimport { System, SystemStatus } from './interface'\nimport React from 'react'\nimport Decimal from 'decimal.js'\nimport { useSettings } from '@loopring-web/component-lib'\n\nexport function useSystem(): SystemStatus & {\n  updateSystem: (system: Partial<System>) => void\n  clearSystem: () => void\n  statusUnset: () => void\n  getValueInCurrency: (valueInUSD: string) => string\n} {\n  const system: SystemStatus = useSelector((state: any) => state.system)\n  const { currency } = useSettings()\n  const dispatch = useDispatch()\n  return {\n    ...system,\n    statusUnset: React.useCallback(() => dispatch(statusUnset(undefined)), [dispatch]),\n    updateSystem: React.useCallback(\n      (system: Partial<System>) => dispatch(updateSystem(system)),\n      [dispatch],\n    ),\n    getValueInCurrency: (valueInUSD: string) => {\n      return system.forexMap && system.forexMap[currency] &&\n        new Decimal(valueInUSD).mul(system.forexMap[currency]).toString()\n    },\n    clearSystem: React.useCallback(\n      () => dispatch(clearSystem(undefined)),\n      [dispatch],\n    ),\n  }\n}\n\n"
  },
  {
    "path": "packages/core/src/stores/system/index.ts",
    "content": "export * from './hook'\nexport * from './interface'\nexport * as systemReducer from './reducer'\n"
  },
  {
    "path": "packages/core/src/stores/system/interface.ts",
    "content": "import { ForexMap, StateBase } from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nexport enum ENV {\n  DEV = 'DEV',\n  UAT = 'UAT',\n  PROD = 'PROD',\n}\n\nexport enum NETWORKEXTEND {\n  NONETWORK = 'unknown',\n}\n\nexport type NETWORK = NETWORKEXTEND | sdk.ChainId\nexport type System = {\n  env: keyof typeof ENV\n  chainId: NETWORK\n  dexToggleUrl: string\n  // network: keyof typeof NETWORK,\n  etherscanBaseUrl: string\n  socketURL: string\n  baseURL: string\n  gasPrice: number\n  forexMap: ForexMap\n  exchangeInfo: sdk.ExchangeInfo | undefined\n  app: 'main' | 'earn' | 'guardian' | 'bridge' | undefined\n  allowTrade: {\n    register: { enable: boolean; reason?: string }\n    order: { enable: boolean; reason?: string }\n    joinAmm: { enable: boolean; reason?: string }\n    defi: { enable: boolean; reason?: string }\n    dAppTrade: { enable: boolean; reason?: string }\n    defiInvest: { enable: boolean; reason?: string }\n    legal: { enable: boolean; reason?: string; show?: boolean }\n    raw_data?: any\n    exitAmm?: { enable: boolean; reason?: string }\n    transfer?: { enable: boolean; reason?: string }\n    transferNFT?: { enable: boolean; reason?: string }\n    deposit?: { enable: boolean; reason?: string }\n    depositNFT?: { enable: boolean; reason?: string }\n    withdraw?: { enable: boolean; reason?: string }\n    withdrawNFT?: { enable: boolean; reason?: string }\n    mintNFT?: { enable: boolean; reason?: string }\n    deployNFT?: { enable: boolean; reason?: string }\n    forceWithdraw?: { enable: boolean; reason?: string }\n  }\n}\n\nexport type SystemStatus = System & {\n  // system:System | {}\n  __timer__: NodeJS.Timeout | -1\n  topics: any[]\n} & StateBase\n"
  },
  {
    "path": "packages/core/src/stores/system/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { ENV, NETWORKEXTEND, System, SystemStatus } from './interface'\nimport { ForexMap, SagaStatus } from '@loopring-web/common-resources'\n\nconst initialState: SystemStatus = {\n  env: ENV.PROD,\n  chainId: NETWORKEXTEND.NONETWORK,\n  baseURL: '',\n  socketURL: '',\n  dexToggleUrl: '',\n  etherscanBaseUrl: '',\n  gasPrice: -1,\n  forexMap: {} as ForexMap<any>,\n  __timer__: -1,\n  status: SagaStatus.PENDING,\n  errorMessage: null,\n  allowTrade: {\n    defiInvest: { enable: false },\n    defi: { enable: false },\n    legal: { enable: false },\n    register: { enable: false },\n    order: { enable: false },\n    joinAmm: { enable: false },\n    dAppTrade: { enable: false },\n  },\n  exchangeInfo: undefined,\n  app:\n    process.env.REACT_APP_NAME === 'loopring.io'\n      ? 'main'\n      : process.env.REACT_APP_NAME === 'loopring defi'\n      ? 'earn'\n      : process.env.REACT_APP_NAME === 'loopring guardian'\n      ? 'guardian'\n      : process.env.REACT_APP_NAME === 'loopring bridge'\n      ? 'bridge'\n      : undefined,\n  topics: [],\n}\nconst systemSlice: Slice<SystemStatus> = createSlice({\n  name: 'system',\n  initialState,\n  reducers: {\n    updateSystem(state, action: PayloadAction<System>) {\n      state.chainId = action.payload.chainId\n      state.status = SagaStatus.PENDING\n    },\n\n    updateRealTimeObj(state, action: PayloadAction<Partial<{ forexMap: any; gasPrice: number }>>) {\n      const { forexMap, gasPrice } = action.payload\n      if (forexMap) {\n        state.forexMap = forexMap\n      }\n      if (gasPrice) {\n        state.gasPrice = gasPrice\n      }\n    },\n    getSystemStatus(state, action: PayloadAction<Partial<SystemStatus>>) {\n      // @ts-ignore\n      if (action.error) {\n        state.status = SagaStatus.ERROR\n        // @ts-ignore\n        state.errorMessage = action.error\n      }\n      const {\n        env,\n        baseURL,\n        socketURL,\n        gasPrice,\n        forexMap,\n        allowTrade,\n        exchangeInfo,\n        dexToggleUrl,\n        __timer__,\n        // isMobile,\n        etherscanBaseUrl,\n      } = action.payload\n\n      if (env) {\n        state.env = env\n      }\n\n      if (allowTrade) {\n        state.allowTrade = allowTrade\n      }\n      if (socketURL) {\n        state.socketURL = socketURL\n      }\n      if (baseURL) {\n        state.baseURL = baseURL\n      }\n\n      if (dexToggleUrl) {\n        state.dexToggleUrl = dexToggleUrl\n      }\n      if (gasPrice) {\n        state.gasPrice = gasPrice\n      }\n      if (forexMap) {\n        state.forexMap = forexMap\n      }\n\n      if (exchangeInfo) {\n        state.exchangeInfo = exchangeInfo\n      }\n      if (etherscanBaseUrl) {\n        state.etherscanBaseUrl = etherscanBaseUrl\n      }\n\n      if (__timer__) {\n        state.__timer__ = __timer__\n      }\n      state.status = SagaStatus.DONE\n    },\n    clearSystem(state, _: PayloadAction<undefined>) {\n      Object.keys(state).forEach(key => {\n        state[key] = initialState[key]\n      })\n    },\n    statusUnset: (state) => {\n      state.status = SagaStatus.UNSET\n    },\n  },\n})\nconst { updateSystem, clearSystem, setTopics, getSystemStatus, statusUnset, updateRealTimeObj } =\n  systemSlice.actions\nexport { systemSlice, updateSystem, clearSystem, setTopics, getSystemStatus, statusUnset, updateRealTimeObj }\n"
  },
  {
    "path": "packages/core/src/stores/system/saga.ts",
    "content": "import { all, call, fork, put, take, takeLatest, delay } from 'redux-saga/effects'\nimport { getSystemStatus, updateRealTimeObj, updateSystem } from './reducer'\nimport { ENV } from './interface'\nimport { store, LoopringSocket, LoopringAPI, toggleCheck, makeVault, configReducer } from '../../index'\nimport {\n  ChainIdExtends,\n  CustomError,\n  DEFI_CONFIG,\n  DUAL_CONFIG,\n  ErrorMap,\n  ForexMap,\n  LocalStorageConfigKey,\n  LEVERAGE_ETH_CONFIG,\n  MapChainId,\n  myLog,\n  TokenPriceBase,\n  CurrencyToTag,\n  SUPPORTING_NETWORKS,\n} from '@loopring-web/common-resources'\nimport { statusUnset as accountStatusUnset } from '../account/reducer'\nimport { getAmmMap, initAmmMap } from '../Amm/AmmMap/reducer'\nimport { getTickers } from '../ticker/reducer'\nimport { getAmmActivityMap } from '../Amm/AmmActivityMap/reducer'\nimport { updateWalletLayer1 } from '../walletLayer1/reducer'\nimport { getTokenMap } from '../token/reducer'\nimport { getNotify } from '../notify/reducer'\nimport { getTokenPrices } from '../tokenPrices/reducer'\nimport { getInvestTokenTypeMap } from '../invest/InvestTokenTypeMap/reducer'\nimport { getDualMap } from '../invest/DualMap/reducer'\nimport { getStakingMap } from '../invest/StakingMap/reducer'\nimport { clearAll as clearWalletInfoAll } from '../localStore/walletInfo'\n\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { getRedPacketConfigs } from '../redPacket/reducer'\nimport { getBtradeMap, getBtradeMapStatus } from '../invest/BtradeMap/reducer'\nimport { setShowGlobalToast } from '@loopring-web/component-lib'\nimport { updateDualSyncMap } from '../invest/DualMap/reducer'\nimport { updateDefiSyncMap } from '../invest/DefiMap/reducer'\nimport { getVaultMap, updateVaultSyncMap } from '../invest/VaultMap/reducer'\nimport { getVaultTickers } from '../invest/VaultTicker/reducer'\nimport { getExclusiveRedpacket } from '../targetRedpackt/reducer'\nimport { promiseAllSequently } from '../../utils/promise'\n\nenum ENV_KEY {\n  Bridge = 'bridge',\n  LoopringIo = 'loopring.io',\n  Earn = 'earn',\n  Guardian = 'guardian',\n}\nexport const defiAllAsync = async () => {\n  if (LoopringAPI.defiAPI) {\n    let { raw_data } = await LoopringAPI.defiAPI?.getDefiMarkets({})\n    // const { baseURL } = store.getState().system\n    const { defaultNetwork } = store.getState().settings\n    const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n    const [\n      dualMap,\n      { markets: marketMap, tokenArr: marketCoins, marketArr: marketArray },\n      { markets: marketLeverageMap, tokenArr: marketLeverageCoins, marketArr: marketLeverageArray },\n    ] = [\n      sdk.makeInvestMarkets(raw_data, DUAL_CONFIG.products[network].join(',')),\n      sdk.makeInvestMarkets(raw_data, DEFI_CONFIG.products[network].join(',')),\n      sdk.makeInvestMarkets(raw_data, LEVERAGE_ETH_CONFIG.products[network].join(',')),\n    ]\n    store.dispatch(updateDualSyncMap({ dualMap }))\n    // store.dispatch(updateDefiSyncMap({ dualMap }))\n    store.dispatch(\n      updateDefiSyncMap({\n        defiMap: {\n          marketArray,\n          marketCoins,\n          marketMap,\n          marketLeverageMap,\n          marketLeverageCoins,\n          marketLeverageArray,\n        },\n      }),\n    )\n  }\n}\n\nconst initConfig = function* <_R extends { [key: string]: any }>(\n  _chainId: sdk.ChainId | 'unknown',\n) {\n  const APP_NAME = process.env?.REACT_APP_NAME ?? 'loopring.io'\n  const { chainId } = store.getState().system\n  const _tokenMap = JSON.parse(window.localStorage.getItem('tokenMap') ?? '{}')[chainId]\n  const _ammpools = JSON.parse(window.localStorage.getItem('ammpools') ?? '{}')[chainId]\n  const _markets = JSON.parse(window.localStorage.getItem('markets') ?? '{}')[chainId]\n  const _btradeMarkets = JSON.parse(window.localStorage.getItem('btradeMarkets') ?? '{}')[chainId]\n  const _vaultMarkets = JSON.parse(\n    window.localStorage.getItem(LocalStorageConfigKey.vaultMarkets) ?? '{}',\n  )[chainId]\n  const _vaultTokenMap = JSON.parse(\n    window.localStorage.getItem(LocalStorageConfigKey.vaultTokenMap) ?? '{}',\n  )[chainId]\n  const _disableWithdrawTokenList = JSON.parse(\n    window.localStorage.getItem(LocalStorageConfigKey.disableWithdrawTokenList) ?? '{}',\n  )[chainId]\n  let tokensMap,\n    coinMap,\n    totalCoinMap,\n    idIndex,\n    addressIndex,\n    tokenListRaw,\n    markets,\n    ammpools,\n    pairs,\n    marketArr,\n    tokenArr,\n    disableWithdrawTokenList,\n    ammpoolsRaw,\n    disableWithdrawTokenListRaw,\n    marketRaw\n  // const { checkHWAddr, updateHW } = useWalletInfo()\n  store.dispatch(clearWalletInfoAll(undefined))\n  if (_tokenMap && _ammpools && _markets && _disableWithdrawTokenList) {\n    myLog('tokenConfig, ammpoolConfig, markets, disableWithdrawTokenList from local storge')\n    const resultTokenMap = sdk.makeMarket(_tokenMap)\n    tokensMap = resultTokenMap.tokensMap\n    coinMap = resultTokenMap.coinMap\n    totalCoinMap = resultTokenMap.totalCoinMap\n    idIndex = resultTokenMap.idIndex\n    addressIndex = resultTokenMap.addressIndex\n\n    const resultMarket = sdk.makeMarkets(_markets)\n    markets = resultMarket.markets\n    pairs = resultMarket.pairs\n    marketArr = resultMarket.marketArr\n    tokenArr = resultMarket.tokenArr\n    ammpools = sdk.makeAmmPool(_ammpools)?.ammpools\n\n    store.dispatch(\n      getTokenMap({\n        tokensMap,\n        coinMap,\n        totalCoinMap,\n        idIndex,\n        addressIndex,\n        marketMap: markets,\n        pairs,\n        marketArr,\n        tokenArr,\n        disableWithdrawTokenList: [..._disableWithdrawTokenList],\n      }),\n    )\n    store.dispatch(initAmmMap({ ammpools, chainId }))\n    try {\n      store.dispatch(updateVaultSyncMap(makeVault(_vaultTokenMap, _vaultMarkets, 'isFormLocal')))\n    } catch (e) {}\n    ;(function (btradeMarkets) {\n      if (btradeMarkets) {\n        const {\n          markets: marketMap,\n          pairs,\n          marketArr: marketArray,\n          tokenArr: marketCoins,\n        } = sdk.makeMarkets({ markets: btradeMarkets })\n        const tradeMap = Reflect.ownKeys(pairs ?? {}).reduce((prev, key) => {\n          const tradePairs = pairs[key as string]?.tokenList?.sort()\n          prev[key] = {\n            ...pairs[key as string],\n            tradePairs,\n          }\n          return prev\n        }, {})\n        if (!marketArray?.length) {\n          store.dispatch(\n            getBtradeMapStatus({\n              marketArray,\n              marketCoins,\n              marketMap,\n              tradeMap,\n            }),\n          )\n        }\n      }\n    })(_btradeMarkets)\n\n    yield delay(1)\n    store.dispatch(getTokenPrices(undefined))\n    if (!Object.keys(store.getState().tokenPrices).length) {\n      yield take('tokenPrices/getTokenPricesStatus')\n    }\n    store.dispatch(getTickers({ tickerKeys: marketArr }))\n    yield take('tickerMap/getTickerStatus')\n    store.dispatch(getAmmMap({ ammpools }))\n    yield take('ammMap/getAmmMapStatus')\n    store.dispatch(getAmmActivityMap({ ammpools }))\n    myLog('getTokenPricesStatus update')\n    Promise.all([\n      LoopringAPI.exchangeAPI?.getTokens(),\n      LoopringAPI.ammpoolAPI?.getAmmPoolConf(),\n      LoopringAPI.exchangeAPI?.getMixMarkets(),\n      LoopringAPI.exchangeAPI?.disableWithdrawTokenList() ?? {\n        disableWithdrawTokenList: [],\n        raw_data: undefined,\n      },\n      \n    ]).then(\n      ([\n        { tokensMap, coinMap, totalCoinMap, idIndex, addressIndex, raw_data: tokenListRaw },\n        { ammpools, raw_data: ammpoolsRaw },\n        { pairs, marketArr, tokenArr, markets, raw_data: marketRaw },\n        { disableWithdrawTokenList, raw_data: disableWithdrawTokenListRaw },\n      ]: any) => {\n        store.dispatch(\n          getTokenMap({\n            tokensMap,\n            coinMap,\n            totalCoinMap,\n            idIndex,\n            addressIndex,\n            marketMap: markets,\n            pairs,\n            marketArr,\n            tokenArr,\n            disableWithdrawTokenList,\n            tokenListRaw,\n            disableWithdrawTokenListRaw,\n            marketRaw,\n          }),\n        )\n        store.dispatch(\n          getTokenMap({\n            tokensMap,\n            coinMap,\n            totalCoinMap,\n            idIndex,\n            addressIndex,\n            marketMap: markets,\n            pairs,\n            marketArr,\n            tokenArr,\n            disableWithdrawTokenList,\n            tokenListRaw,\n            disableWithdrawTokenListRaw,\n            marketRaw,\n          }),\n        )\n        // myLog(\n        //   \"tokenConfig, ammpoolConfig, markets, disableWithdrawTokenList update from server-side update\"\n        // );\n        store.dispatch(getAmmMap({ ammpools, ammpoolsRaw, chainId }))\n        store.dispatch(getAmmActivityMap({ ammpools }))\n        \n      },\n    )\n  } else {\n    ;[\n      { tokensMap, coinMap, totalCoinMap, idIndex, addressIndex, raw_data: tokenListRaw },\n      { ammpools, raw_data: ammpoolsRaw },\n      { pairs, marketArr, tokenArr, markets, raw_data: marketRaw },\n      { disableWithdrawTokenList, raw_data: disableWithdrawTokenListRaw },\n    ] = yield all([\n      call(async () => LoopringAPI.exchangeAPI?.getTokens()),\n      call(async () => LoopringAPI.ammpoolAPI?.getAmmPoolConf()),\n      call(async () => LoopringAPI.exchangeAPI?.getMixMarkets()),\n      call(async () => {\n        try {\n          return await LoopringAPI.exchangeAPI?.disableWithdrawTokenList()\n        } catch (e: any) {\n          return {\n            disableWithdrawTokenList: [],\n            raw_data: undefined,\n          }\n        }\n      }),\n    ])\n    myLog(\n      'tokenConfig, ammpoolConfig, markets, disableWithdrawTokenList update from server-side init',\n    )\n    store.dispatch(\n      getTokenMap({\n        tokensMap,\n        coinMap,\n        totalCoinMap,\n        idIndex,\n        addressIndex,\n        marketMap: markets,\n        pairs,\n        marketArr,\n        tokenArr,\n        disableWithdrawTokenList,\n        tokenListRaw,\n        disableWithdrawTokenListRaw,\n        marketRaw,\n      }),\n    )\n    store.dispatch(initAmmMap({ ammpools }))\n    yield take('tokenMap/getTokenMapStatus')\n    store.dispatch(getTokenPrices(undefined))\n    yield take('tokenPrices/getTokenPricesStatus')\n    store.dispatch(getTickers({ tickerKeys: marketArr }))\n    yield take('tickerMap/getTickerStatus')\n    store.dispatch(getAmmMap({ ammpools, ammpoolsRaw, chainId }))\n    yield take('ammMap/getAmmMapStatus')\n    store.dispatch(getAmmActivityMap({ ammpools }))\n    if (store.getState().tokenMap.status === 'ERROR') {\n      throw new CustomError({ ...ErrorMap.NO_SDK, message: 'tokenMap Error' })\n    }\n  }\n  LoopringAPI.rabbitWithdrawAPI?.getConfig().then((res) => {\n    store.dispatch(configReducer.updateFastWithdrawConfig(JSON.parse(res.config)))\n  })\n\n  //APP_NAME\n  switch (APP_NAME.toLowerCase()) {\n    case ENV_KEY.Bridge.toLowerCase():\n    case ENV_KEY.Guardian.toLowerCase():\n      break\n    case ENV_KEY.Earn.toLowerCase():\n      store.dispatch(getDualMap(undefined))\n      defiAllAsync()\n      yield all([take('dualMap/getDualMapStatus')])\n      store.dispatch(getInvestTokenTypeMap(undefined))\n      break\n    case ENV_KEY.LoopringIo.toLowerCase():\n    default:\n      store.dispatch(getRedPacketConfigs(undefined))\n      store.dispatch(getNotify(undefined))\n      store.dispatch(getStakingMap(undefined))\n      store.dispatch(getBtradeMap(undefined))\n      store.dispatch(getVaultMap(undefined))\n      defiAllAsync()\n      yield take('vaultMap/getVaultMapStatus')\n      store.dispatch(getVaultTickers(undefined))\n      yield all([\n        take('defiMap/getDefiMapStatus'),\n        take('dualMap/getDualMapStatus'),\n        take('stakingMap/getStakingMapStatus'),\n      ])\n      store.dispatch(getInvestTokenTypeMap(undefined))\n\n      break\n  }\n\n  yield delay(5)\n  const { account, walletLayer1 } = store.getState()\n  if (account.accAddress && walletLayer1.walletLayer1 === undefined) {\n    store.dispatch(updateWalletLayer1(undefined))\n  }\n  store.dispatch(accountStatusUnset(undefined))\n}\nconst getForexMapGasPrice = async (\n  chainId: sdk.ChainId\n): Promise<{\n  gasPrice: number\n  forexMapLight: ForexMap\n  forexMapAllPromise: Promise<ForexMap>\n} | undefined> => {\n  const network = MapChainId[chainId] ?? MapChainId[1]\n  if (LoopringAPI.exchangeAPI && TokenPriceBase[network]) {\n    let { currency } = store.getState().settings\n    let indexUSD = 0\n    const tokenAddress = TokenPriceBase[network] //addressIndex[TokenPriceBase[network]];\n    \n    const promiseArrayAll = Object.keys(CurrencyToTag).map((key, index) => {\n      if (key.toString().toUpperCase() === sdk.Currency.usd.toUpperCase()) {\n        indexUSD = index\n      }\n      \n      return async () => {\n        await sdk.sleep(300)\n        return (LoopringAPI?.exchangeAPI?.getLatestTokenPrices({\n          currency: CurrencyToTag[key].toString(),\n          tokens: tokenAddress,\n        }) ?? Promise.resolve({ tokenPrices: null }))\n      }\n    })\n    const forexMapAllPromise = promiseAllSequently(promiseArrayAll).then(async (restForexs) => { \n      const baseUsd = restForexs[indexUSD].tokenPrices[tokenAddress] ?? 1\n      return Object.keys(CurrencyToTag).reduce<ForexMap>((prev, key, index) => {\n        if (restForexs[index] && key && restForexs[index].tokenPrices) {\n          // @ts-ignore\n          prev[CurrencyToTag[key]] = Number(restForexs[index].tokenPrices[tokenAddress] / baseUsd)\n        }\n        return prev\n      }, {} as ForexMap)\n    })\n    const promiseArrayLight = [currency].map((key, index) => {\n      if (key.toString().toUpperCase() === sdk.Currency.usd.toUpperCase()) {\n        indexUSD = index\n      }\n      return (\n        LoopringAPI?.exchangeAPI?.getLatestTokenPrices({\n          currency: CurrencyToTag[key].toString(),\n          tokens: tokenAddress,\n        }) ?? Promise.resolve({ tokenPrices: null })\n      )\n    })\n    const forexMapLight: ForexMap = await Promise.all(promiseArrayLight).then((restForexs) => {\n      return [currency].reduce<ForexMap>((prev, key, index) => {\n        if (restForexs[index] && key && restForexs[index].tokenPrices) {\n          // @ts-ignore\n          prev[CurrencyToTag[key]] = Number(restForexs[index].tokenPrices[tokenAddress])\n        }\n        return prev\n      }, {} as ForexMap)\n    })\n    const { gasPrice } = await LoopringAPI.exchangeAPI.getGasPrice();\n\n    return {\n      gasPrice,\n      forexMapLight,\n      forexMapAllPromise,\n    }\n  }\n  return undefined\n}\nconst should15MinutesUpdateDataGroup = async (\n  chainId: sdk.ChainId,\n): Promise<{\n  gasPrice: number | undefined\n  forexMap: ForexMap\n}> => {\n  const network = MapChainId[chainId] ?? MapChainId[1]\n  if (LoopringAPI.exchangeAPI && TokenPriceBase[network]) {\n    let indexUSD = 0\n    const tokenAddress = TokenPriceBase[network] //addressIndex[TokenPriceBase[network]];\n    // const tokenId =\n    //   chainId === sdk.ChainId.GOERLI\n    //     ? '0xd4e71c4bb48850f5971ce40aa428b09f242d3e8a'\n    //     : '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48'\n    \n    const promiseArray = Object.keys(CurrencyToTag).map((key, index) => {\n      if (key.toString().toUpperCase() === sdk.Currency.usd.toUpperCase()) {\n        indexUSD = index\n      }\n      return () => (\n        LoopringAPI?.exchangeAPI?.getLatestTokenPrices({\n          currency: CurrencyToTag[key].toString(),\n          tokens: tokenAddress,\n        }) ?? Promise.resolve({ tokenPrices: null })\n      )\n    })\n    const restForexs = await promiseAllSequently(promiseArray)\n\n    const { gasPrice } = await LoopringAPI.exchangeAPI.getGasPrice();\n    const baseUsd = restForexs[indexUSD].tokenPrices[tokenAddress] ?? 1\n    const forexMap: ForexMap = Object.keys(CurrencyToTag).reduce<ForexMap>((prev, key, index) => {\n      if (restForexs[index] && key && restForexs[index].tokenPrices) {\n        // @ts-ignore\n        prev[CurrencyToTag[key]] = Number(restForexs[index].tokenPrices[tokenAddress] / baseUsd)\n      }\n      return prev\n    }, {} as ForexMap)\n\n    return {\n      gasPrice,\n      forexMap,\n    }\n  }\n  return {\n    forexMap: {} as ForexMap,\n    gasPrice: undefined,\n  }\n}\n\nconst getSystemsApi = async <_R extends { [key: string]: any }>(_chainId: any) => {\n  const extendsChain: string[] = (SUPPORTING_NETWORKS ?? []) \n  .filter(\n    (item) => ![1, 5, 11155111].includes(Number(item)),\n  )\n  const env =\n    window.location.hostname === 'localhost'\n      ? ENV.DEV\n      : sdk.ChainId.SEPOLIA === Number(_chainId)\n      ? ENV.UAT\n      : ENV.PROD\n  const chainId: sdk.ChainId = (\n    SUPPORTING_NETWORKS.includes(_chainId.toString()) ? Number(_chainId) : ChainIdExtends.NONETWORK\n  ) as sdk.ChainId\n  if (_chainId === ChainIdExtends.NONETWORK) {\n    throw new CustomError(ErrorMap.NO_NETWORK_ERROR)\n  } else {\n    LoopringAPI.InitApi(chainId as sdk.ChainId)\n    if (LoopringAPI.exchangeAPI && LoopringAPI.walletAPI) {\n      let baseURL, socketURL\n      if (extendsChain.includes(chainId.toString())) {\n        const socketPrefix = 'ws.' // process.env['REACT_APP_API_WS_' + chainId.toString() + '_PREFIX'] ?? ''\n        baseURL = `https://${process.env['REACT_APP_API_URL_' + chainId.toString()]}`\n        socketURL = `wss://${socketPrefix}${\n          process.env['REACT_APP_API_URL_' + chainId.toString()]\n        }/v3/ws`\n      } else {\n        if (sdk.ChainId.MAINNET === chainId) {\n          baseURL = `https://${process.env.REACT_APP_API_URL_1}`\n          socketURL = `wss://ws.${process.env.REACT_APP_API_URL_1}/v3/ws`\n        } else {\n          \n          let socketPrefix = 'ws.' // process.env['REACT_APP_API_WS_' + chainId.toString() + '_PREFIX'] ?? ''\n          baseURL = `https://${process.env.REACT_APP_API_URL_11155111}`\n          socketURL = `wss://${socketPrefix}${process.env.REACT_APP_API_URL_11155111}/v3/ws`\n          // @ts-ignore\n          sdk.NFTFactory_Collection[sdk.ChainId.SEPOLIA] =\n            process.env[\n              `REACT_APP_SEPOLIA_${\n                /dev\\.loopring\\.io/.test(process.env?.REACT_APP_API_URL_11155111 ?? '') ? 'DEV' : 'UAT'\n              }_NFT_FACTORY_COLLECTION`\n            ]\n        }\n      }\n      \n      LoopringAPI.setBaseURL(baseURL, {\n        walletAPIURL: process.env?.[`REACT_APP_WALLET_API_URL_${chainId}`] ? 'https://' + process.env?.[`REACT_APP_WALLET_API_URL_${chainId}`] : undefined,\n        rabbitWithdrawAPIURL: process.env?.[`REACT_APP_RABBIT_API_URL_${chainId}`] ? 'https://' + process.env?.[`REACT_APP_RABBIT_API_URL_${chainId}`] : undefined\n      })\n      const etherscanBaseUrl =\n        sdk.ChainId.MAINNET === chainId\n          ? `https://etherscan.io/`\n          : sdk.ChainId.SEPOLIA === chainId\n          ? `https://sepolia.etherscan.io/`\n          : process.env[`REACT_APP_EXPLORER_URL_${chainId}`]\n      \n      \n      let allowTrade, exchangeInfo, forexMapGas,forexMap, gasPrice, forexMapAllPromise\n      try {\n        const _exchangeInfo = JSON.parse(\n          window.localStorage.getItem(LocalStorageConfigKey.exchangeInfo) ?? '{}',\n        )\n        ;[{ exchangeInfo }, forexMapGas, allowTrade] = await Promise.all([\n          _exchangeInfo[chainId]\n            ? Promise.resolve({ exchangeInfo: _exchangeInfo[chainId] })\n            : LoopringAPI.exchangeAPI.getExchangeInfo().then(({ exchangeInfo }) => {\n                myLog('exchangeInfo from service because no localstorage ')\n                window.localStorage.setItem(\n                  LocalStorageConfigKey.exchangeInfo,\n                  JSON.stringify({\n                    ..._exchangeInfo,\n                    [exchangeInfo.chainId]: exchangeInfo,\n                  }),\n                )\n                return { exchangeInfo }\n              }),\n          getForexMapGasPrice(chainId),\n          LoopringAPI.walletAPI.getAccountServices({}).then((result) => {\n            return {\n              ...result,\n              legal: (result as any)?.raw_data?.legal ?? { enable: false },\n            }\n          }).catch(() => {\n            return {\n              defiInvest: { enable: false },\n              register: { enable: false },\n              order: { enable: false },\n              joinAmm: { enable: false },\n              dAppTrade: { enable: false },\n              raw_data: { enable: false },\n              legal: { enable: false },\n            }\n          }),\n        ])\n        ;({forexMapLight: forexMap, gasPrice, forexMapAllPromise} = forexMapGas!)\n        if (_exchangeInfo[chainId]) {\n          LoopringAPI.exchangeAPI.getExchangeInfo().then(async ({ exchangeInfo }: any) => {\n            window.localStorage.setItem(\n              LocalStorageConfigKey.exchangeInfo,\n              JSON.stringify({\n                ..._exchangeInfo,\n                [exchangeInfo.chainId]: exchangeInfo,\n              }),\n            )\n            if (\n              _exchangeInfo[exchangeInfo.chainId]?.exchangeAddress?.toLowerCase() !==\n              exchangeInfo?.exchangeAddress?.toLowerCase()\n            ) {\n              await sdk.sleep(500)\n              window.location.reload()\n            }\n\n            myLog('exchangeInfo from service')\n          })\n        }\n        // get complete forex map async\n        forexMapAllPromise.then((forexMapAll) => {\n          if (chainId !== store.getState().system.chainId) return\n          store.dispatch(\n            getSystemStatus({\n              forexMap: forexMapAll\n            })\n          )\n        })\n      } catch (e: any) {\n        allowTrade = {\n          defiInvest: { enable: false },\n          register: { enable: false },\n          order: { enable: false },\n          joinAmm: { enable: false },\n          dAppTrade: { enable: false },\n          raw_data: { enable: false },\n          legal: { enable: false },\n        }\n        setShowGlobalToast({\n          isShow: true,\n          info: {\n            content: ErrorMap.NO_SDK,\n          },\n        })\n      }\n\n      // @ts-ignore\n      ;(window as any).loopringSocket = new LoopringSocket(socketURL)\n\n      let { __timer__ } = store.getState().system\n      __timer__ = ((__timer__) => {\n        if (__timer__ && __timer__ !== -1) {\n          clearInterval(__timer__ as NodeJS.Timeout)\n        }\n        return setInterval(async () => {\n          if (!LoopringAPI.exchangeAPI || chainId !== store.getState().system.chainId) return\n          should15MinutesUpdateDataGroup(chainId).then(({ forexMap, gasPrice }) => {\n            store.dispatch(updateRealTimeObj({ forexMap, gasPrice }))\n          })\n        }, 300000) //\n      })(__timer__)\n      return {\n        allowTrade,\n        chainId,\n        etherscanBaseUrl,\n        env,\n        baseURL,\n        socketURL,\n        exchangeInfo,\n        forexMap, \n        gasPrice,\n        __timer__,\n      }\n    }\n  }\n}\n\nexport function* getUpdateSystem({ payload }: any) {\n  try {\n    const { chainId } = payload\n    \n    const {\n      env,\n      baseURL,\n      allowTrade,\n      fiatPrices,\n      exchangeInfo,\n      gasPrice,\n      forexMap,\n      etherscanBaseUrl,\n      __timer__,\n    } = yield call(getSystemsApi, chainId)\n\n    yield put(\n      getSystemStatus({\n        env,\n        dexToggleUrl: process.env.REACT_APP_DEX_TOGGLE,\n        baseURL,\n        allowTrade,\n        fiatPrices,\n        gasPrice,\n        forexMap,\n        exchangeInfo,\n        etherscanBaseUrl,\n        __timer__,\n      }),\n    )\n    yield call(initConfig, chainId)\n  } catch (err) {\n    yield put(getSystemStatus({ error: err }))\n  }\n}\n\nfunction* systemSaga() {\n  yield all([takeLatest(updateSystem, getUpdateSystem)])\n}\n\nexport const systemForks = [fork(systemSaga)]\n"
  },
  {
    "path": "packages/core/src/stores/targetRedpackt/hook.ts",
    "content": "import { useDispatch, useSelector } from 'react-redux'\nimport { statusUnset, setShowRedPacketsPopup, getExclusiveRedpacket } from './reducer'\nimport { TargetRedPacketStates } from './interface'\nimport React from 'react'\n\nexport function useTargetRedPackets(): TargetRedPacketStates & {\n  statusUnset: () => void\n  setShowRedPacketsPopup: (show: boolean) => void\n  getExclusiveRedpacket: () => void\n} {\n  const targetRedpacket: TargetRedPacketStates = useSelector((state: any) => state.targetRedpacket)\n  const dispatch = useDispatch()\n  return {\n    ...targetRedpacket,\n    statusUnset: React.useCallback(() => dispatch(statusUnset(undefined)), [dispatch]),\n    setShowRedPacketsPopup: React.useCallback(\n      (show: boolean) => dispatch(setShowRedPacketsPopup(show)),\n      [dispatch],\n    ),\n    getExclusiveRedpacket() {\n      dispatch(getExclusiveRedpacket(undefined))\n    },\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/targetRedpackt/index.ts",
    "content": "export * from './hook'\nexport * from './interface'\nexport * as targetRedpacketReducer from './reducer'\n"
  },
  {
    "path": "packages/core/src/stores/targetRedpackt/interface.ts",
    "content": "import { StateBase } from '@loopring-web/common-resources'\nimport { LuckyTokenItemForReceive } from '@loopring-web/loopring-sdk'\n\nexport type RedPacketConfig = any\nexport type TargetRedPacketStates = {\n  redPackets: LuckyTokenItemForReceive[] | undefined\n  openedRedPackets: boolean\n  showPopup: boolean\n  __timer__?: number\n} & StateBase\n"
  },
  {
    "path": "packages/core/src/stores/targetRedpackt/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { TargetRedPacketStates } from './interface'\nimport { CoinKey, SagaStatus } from '@loopring-web/common-resources'\nimport { LuckyTokenItemForReceive } from '@loopring-web/loopring-sdk'\n\nconst initialState: Required<TargetRedPacketStates> = {\n  redPackets: undefined,\n  __timer__: -1,\n  status: SagaStatus.PENDING,\n  errorMessage: null,\n  openedRedPackets: false,\n  showPopup: false,\n}\nconst targetRedpacketSlice: Slice = createSlice({\n  name: 'targetRedpacket',\n  initialState,\n  reducers: {\n    getExclusiveRedpacket(state, _action: PayloadAction<undefined>) {\n      state.status = SagaStatus.PENDING\n    },\n    getExclusiveRedpacketStatus(state, action: PayloadAction<TargetRedPacketStates>) {\n      // @ts-ignore\n      if (action.error) {\n        state.status = SagaStatus.ERROR\n        // @ts-ignore\n        state.errorMessage = action.error\n      }\n      const { redPackets, __timer__ } = action.payload\n      if (redPackets) {\n        state.redPackets = redPackets\n      }\n      if (__timer__) {\n        state.__timer__ = __timer__\n      }\n      state.status = SagaStatus.DONE\n    },\n    statusUnset: (state) => {\n      state.status = SagaStatus.UNSET\n    },\n    setShowRedPacketsPopup: (state: TargetRedPacketStates, action: PayloadAction<boolean>) => {\n      state.showPopup = action.payload\n    },\n  },\n})\nexport { targetRedpacketSlice }\nexport const {\n  getExclusiveRedpacket,\n  getExclusiveRedpacketStatus,\n  statusUnset,\n  setShowRedPacketsPopup,\n} = targetRedpacketSlice.actions\n"
  },
  {
    "path": "packages/core/src/stores/targetRedpackt/saga.ts",
    "content": "import { all, call, fork, put, takeEvery } from 'redux-saga/effects'\nimport { getExclusiveRedpacket, getExclusiveRedpacketStatus } from './reducer'\n\nimport { store, LoopringAPI } from '../../index'\nimport { LuckyTokenItemForReceive } from '@loopring-web/loopring-sdk'\nimport { TargetRedPacketStates } from './interface'\nvar getExclusiveRedPacketAPIInterval: any\nconst getExclusiveRedPacketAPI = async (): Promise<{\n  data: object | undefined\n  __timer__: NodeJS.Timer | -1\n}> => {\n  let { __timer__ } = store.getState().targetRedpacket.__timer__\n  if (LoopringAPI.luckTokenAPI) {\n    if (getExclusiveRedPacketAPIInterval) {\n      clearInterval(getExclusiveRedPacketAPIInterval)\n    }\n    getExclusiveRedPacketAPIInterval = setInterval(() => {\n      store.dispatch(getExclusiveRedpacket({}))\n    }, 1000 * 60 * 5)\n\n    const account = store.getState().account\n    const response = await LoopringAPI.luckTokenAPI?.getLuckTokenUserLuckyTokenTargets(\n      {\n        statuses: [0],\n        offset: 0,\n        limit: 100,\n        isAll: 1,\n      },\n      account.apiKey,\n    )\n    const list = (response.raw_data as any).list as LuckyTokenItemForReceive[]\n\n    return {\n      data: list,\n      __timer__,\n    }\n  } else {\n    throw 'err'\n    // return { data: undefined,, __timer__: -1 }\n  }\n}\nfunction* getPostsSaga() {\n  try {\n    const { data, __timer__ } = yield call(getExclusiveRedPacketAPI)\n    yield put(getExclusiveRedpacketStatus({ redPackets: data, __timer__ } as TargetRedPacketStates))\n  } catch (err) {\n    yield put(getExclusiveRedpacketStatus({ error: err }))\n  }\n}\n\nfunction* exclusiveRedPacketInitSaga() {\n  yield all([takeEvery(getExclusiveRedpacket, getPostsSaga)])\n}\n\nexport const exclusiveRedPacketSaga = [fork(exclusiveRedPacketInitSaga)]\n"
  },
  {
    "path": "packages/core/src/stores/ticker/hook.ts",
    "content": "import { useDispatch, useSelector } from 'react-redux'\nimport { getTickers, statusUnset, updateTicker } from './reducer'\nimport { TickerStates } from './interface'\nimport { CoinKey } from '@loopring-web/common-resources'\nimport React from 'react'\nimport { LoopringMap, TickerData } from '@loopring-web/loopring-sdk'\n\nexport function useTicker(): TickerStates & {\n  updateTickers: (tickerKeys: Array<CoinKey<any>>) => void\n  updateTickerSync: (tickerMap: LoopringMap<TickerData>) => void\n  statusUnset: () => void\n} {\n  const tickerMap: TickerStates = useSelector((state: any) => state.tickerMap)\n  const dispatch = useDispatch()\n  return {\n    ...tickerMap,\n    statusUnset: React.useCallback(() => dispatch(statusUnset(undefined)), [dispatch]),\n    updateTickers: React.useCallback(\n      (tickerKeys: Array<CoinKey<any>>) => dispatch(getTickers({ tickerKeys })),\n      [dispatch],\n    ),\n    updateTickerSync: React.useCallback(\n      (tickMap: LoopringMap<TickerData>) => dispatch(updateTicker(tickMap)),\n      [dispatch],\n    ),\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/ticker/index.ts",
    "content": "export * from './hook'\nexport * from './interface'\nexport * as tickerReducer from './reducer'\n"
  },
  {
    "path": "packages/core/src/stores/ticker/interface.ts",
    "content": "import { StateBase, Ticker } from '@loopring-web/common-resources'\n\nexport type TickerMap<R = { [key: string]: any }> = {\n  [key in keyof R]: Ticker\n}\nexport type TickerStates<C = { [key: string]: any }> = {\n  tickerMap: TickerMap<C>\n  __timer__?: number\n} & StateBase\n"
  },
  {
    "path": "packages/core/src/stores/ticker/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { TickerStates } from './interface'\nimport { CoinKey, SagaStatus } from '@loopring-web/common-resources'\nimport { LoopringMap, TickerData } from '@loopring-web/loopring-sdk'\n\nconst initialState: Required<TickerStates> = {\n  tickerMap: {},\n  __timer__: -1,\n  status: SagaStatus.PENDING,\n  errorMessage: null,\n}\nconst tickerMapSlice: Slice = createSlice({\n  name: 'tickerMap',\n  initialState,\n  reducers: {\n    resetTicker(state) {\n      if (state.__timer__ !== -1) {\n        clearTimeout(state.__timer__)\n        state.__timer__ = -1\n      }\n      state.tickerMap = {}\n      state.status = SagaStatus.UNSET\n    },\n    updateTicker(state, _action: PayloadAction<LoopringMap<TickerData>>) {\n      state.status = SagaStatus.PENDING\n    },\n    getTickers(state, _action: PayloadAction<Array<CoinKey<any>>>) {\n      state.status = SagaStatus.PENDING\n    },\n    getTickerStatus(state, action: PayloadAction<TickerStates>) {\n      // @ts-ignore\n      if (action.error) {\n        state.status = SagaStatus.ERROR\n        // @ts-ignore\n        state.errorMessage = action.error\n      }\n      const { tickerMap, __timer__ } = action.payload\n      if (tickerMap) {\n        state.tickerMap = tickerMap\n      }\n      if (__timer__) {\n        state.__timer__ = __timer__\n      }\n      state.status = SagaStatus.DONE\n    },\n    statusUnset: (state) => {\n      state.status = SagaStatus.UNSET\n    },\n  },\n})\nexport { tickerMapSlice }\nexport const { updateTicker, resetTicker, getTickers, getTickerStatus, statusUnset } =\n  tickerMapSlice.actions\n"
  },
  {
    "path": "packages/core/src/stores/ticker/saga.ts",
    "content": "import { all, call, fork, put, takeLatest } from 'redux-saga/effects'\nimport { getTickers, getTickerStatus, updateTicker } from './reducer'\nimport { CustomError, ErrorMap, myLog } from '@loopring-web/common-resources'\nimport { LoopringAPI, makeTickerMap, store } from '../../index'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { PayloadAction } from '@reduxjs/toolkit'\n\nconst getTickersApi = async <R extends { [key: string]: any }>(\n  list: Array<keyof R>,\n): Promise<{\n  data: object | undefined\n  __timer__: NodeJS.Timer | -1\n}> => {\n  let { __timer__ } = store.getState().tickerMap.__timer__\n  let { marketArray } = store.getState().tokenMap\n\n  if (LoopringAPI.exchangeAPI) {\n    __timer__ = ((__timer__) => {\n      if (__timer__ && __timer__ !== -1) {\n        clearTimeout(__timer__)\n      }\n      return setTimeout(() => {\n        store.dispatch(getTickers({ tickerKey: marketArray }))\n      }, 1000 * 60 * 5)\n    })(__timer__)\n    const tickers = await LoopringAPI.exchangeAPI.getMixTicker({\n      market: list.join(','),\n    })\n    const data = makeTickerMap({ tickerMap: tickers.tickMap })\n\n    return { data, __timer__ }\n  } else {\n    if (__timer__ && __timer__ !== -1) {\n      clearTimeout(__timer__)\n    }\n    return { data: {}, __timer__: -1 }\n  }\n}\n\nfunction* getPostsSaga({ payload }: any) {\n  try {\n    // @ts-ignore\n    const { tickerKey, tickerKeys } = payload\n    if (tickerKey || (tickerKeys && tickerKeys.length)) {\n      const { data, __timer__ } = yield call(getTickersApi, tickerKey ? [tickerKey] : tickerKeys)\n      yield put(getTickerStatus({ tickerMap: data, __timer__ }))\n      // store.dispatch(updateRealTimeAmmMap({}));\n    } else {\n      throw new CustomError(ErrorMap.NO_TOKEN_KEY_LIST)\n    }\n  } catch (err) {\n    yield put(getTickerStatus({ error: err }))\n  }\n}\n\nfunction* tickerMakeMap({ payload }: PayloadAction<sdk.LoopringMap<sdk.TickerData>>) {\n  try {\n    let { tickerMap } = store.getState().tickerMap\n    const data = makeTickerMap({ tickerMap: payload })\n    yield put(getTickerStatus({ tickerMap: { ...tickerMap, ...data } }))\n  } catch (err) {\n    myLog('err', err)\n    yield put(getTickerStatus(err))\n  }\n}\n\nfunction* tickersSaga() {\n  yield all([takeLatest(getTickers, getPostsSaga)])\n}\n\nfunction* tickerSyncSaga() {\n  // @ts-ignore\n  yield all([takeLatest(updateTicker, tickerMakeMap)])\n}\n\nexport const tickerForks = [fork(tickerSyncSaga), fork(tickersSaga)]\n"
  },
  {
    "path": "packages/core/src/stores/token/hook.ts",
    "content": "import { useDispatch, useSelector } from 'react-redux'\nimport { getTokenMap, statusUnset } from './reducer'\nimport { GetTokenMapParams, TokenMapStates } from './interface'\nimport React from 'react'\nimport { PayloadAction } from '@reduxjs/toolkit'\n\nexport function useTokenMap<R extends { [key: string]: any }>(): TokenMapStates<R> & {\n  getTokenMap: (props: PayloadAction<GetTokenMapParams<any>>) => void\n  statusUnset: () => void\n} {\n  const tokenMap: TokenMapStates<R> = useSelector((state: any) => state.tokenMap)\n  const dispatch = useDispatch()\n\n  return {\n    ...tokenMap,\n    statusUnset: React.useCallback(() => dispatch(statusUnset(undefined)), [dispatch]),\n    getTokenMap: React.useCallback(\n      (props: PayloadAction<GetTokenMapParams<R>>) => dispatch(getTokenMap(props)),\n      [dispatch],\n    ),\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/token/index.ts",
    "content": "export * from './hook'\nexport * from './interface'\nexport * as tokenReducer from './reducer'\n"
  },
  {
    "path": "packages/core/src/stores/token/interface.ts",
    "content": "import { CoinKey, CoinMap, StateBase } from '@loopring-web/common-resources'\nimport {\n  LoopringMap,\n  MarketInfo,\n  TokenAddress,\n  TokenInfo,\n  TokenRelatedInfo,\n} from '@loopring-web/loopring-sdk'\n\nexport type TokenMap<R extends { [key: string]: any }> = LoopringMap<\n  TokenInfo & { tradePairs: Array<CoinKey<R>> }\n>\nexport type GetTokenMapParams<_R extends { [key: string]: any }> = {\n  tokensMap: LoopringMap<TokenInfo>\n  coinMap: LoopringMap<{\n    icon?: string\n    name: string\n    simpleName: string\n    description?: string\n    company: string\n  }>\n  totalCoinMap: LoopringMap<{\n    icon?: string\n    name: string\n    simpleName: string\n    description?: string\n    company: string\n  }>\n  idIndex: LoopringMap<number>\n  addressIndex: LoopringMap<TokenAddress>\n  marketMap: LoopringMap<MarketInfo>\n  pairs: LoopringMap<TokenRelatedInfo>\n  marketArr: string[]\n  tokenArr: string[]\n  disableWithdrawTokenList: any[]\n  tokenListRaw?: any\n  disableWithdrawTokenListRaw?: any\n  marketRaw: any\n  // ammpoolsRaw?: any;\n  // marketRaw?: any;\n  //\n}\n\nexport type AddressMap = {\n  [key: string]: string\n}\n\nexport type IdMap = {\n  [key: number]: string\n}\n\nexport type TokenMapStates<R extends { [key: string]: any }> = {\n  coinMap: CoinMap<R>\n  totalCoinMap?: CoinMap<R> | undefined\n  marketArray: string[]\n  marketCoins: string[]\n  disableWithdrawList: string[]\n  tokenMap: TokenMap<R>\n  marketMap: LoopringMap<MarketInfo>\n  addressIndex: AddressMap\n  idIndex: IdMap\n} & StateBase\n"
  },
  {
    "path": "packages/core/src/stores/token/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { GetTokenMapParams, TokenMapStates } from './interface'\nimport { SagaStatus } from '@loopring-web/common-resources'\n\nconst initialState: TokenMapStates<object> = {\n  marketArray: [],\n  marketCoins: [],\n  disableWithdrawList: [],\n  coinMap: {},\n  totalCoinMap: {},\n  addressIndex: {},\n  tokenMap: {},\n  marketMap: {},\n  idIndex: {},\n  status: SagaStatus.PENDING,\n  errorMessage: null,\n}\nconst tokenMapSlice: Slice<TokenMapStates<object>> = createSlice({\n  name: 'tokenMap',\n  initialState,\n  reducers: {\n    getTokenMap(state, _action: PayloadAction<GetTokenMapParams<any>>) {\n      state.status = SagaStatus.PENDING\n    },\n    getTokenMapStatus(state, action: PayloadAction<TokenMapStates<object>>) {\n      // @ts-ignore\n      if (action.error) {\n        state.status = SagaStatus.ERROR\n        // @ts-ignore\n        state.errorMessage = action.error\n      }\n\n      const {\n        tokenMap,\n        totalCoinMap,\n        marketMap,\n        addressIndex,\n        idIndex,\n        coinMap,\n        marketArray,\n        marketCoins,\n        disableWithdrawList,\n      } = action.payload\n      if (tokenMap) {\n        state.tokenMap = tokenMap\n      }\n      if (marketMap) {\n        state.marketMap = marketMap\n      }\n      if (addressIndex) {\n        state.addressIndex = addressIndex\n      }\n      if (idIndex) {\n        state.idIndex = idIndex\n      }\n      if (coinMap) {\n        state.coinMap = coinMap\n      }\n      if (totalCoinMap) {\n        state.totalCoinMap = totalCoinMap\n      }\n      if (marketArray) {\n        state.marketArray = marketArray\n      }\n      if (marketCoins) {\n        state.marketCoins = marketCoins\n      }\n      if (disableWithdrawList) {\n        state.disableWithdrawList = disableWithdrawList\n      }\n      // if (tokenPairsMap) {state.tokenPairsMap = tokenPairsMap }\n      state.status = SagaStatus.DONE\n    },\n\n    statusUnset: (state) => {\n      state.status = SagaStatus.UNSET\n    },\n  },\n})\nexport { tokenMapSlice }\nexport const { getTokenMap, getTokenMapStatus, statusUnset } = tokenMapSlice.actions\n"
  },
  {
    "path": "packages/core/src/stores/token/saga.ts",
    "content": "import { all, call, fork, put, takeLatest } from 'redux-saga/effects'\nimport { getTokenMap, getTokenMapStatus } from './reducer'\nimport { GetTokenMapParams } from './interface'\nimport { PayloadAction } from '@reduxjs/toolkit'\nimport { store } from '../index'\n\nconst getTokenMapApi = async <R extends { [key: string]: any }>({\n  tokensMap,\n  coinMap,\n  totalCoinMap,\n  idIndex,\n  addressIndex,\n  pairs,\n  marketArr,\n  tokenArr,\n  disableWithdrawTokenList,\n  tokenListRaw,\n  disableWithdrawTokenListRaw,\n  marketRaw,\n}: GetTokenMapParams<R>) => {\n  const { chainId } = store.getState().system\n  const tokenChainMap = window.localStorage.getItem('tokenMap')\n  const disableWithdrawTokenListChain = window.localStorage.getItem('disableWithdrawTokenList')\n  const marketChain = window.localStorage.getItem('markets')\n  // let coinMap: CoinMap<any, CoinInfo<any>> = {};\n  // let totalCoinMap: CoinMap<any, CoinInfo<any>> = {};\n  let tokenMap: any = tokensMap\n  // let addressIndex: AddressMap = {};\n  // let idIndex: IdMap = {};\n  let disableWithdrawList: string[] = disableWithdrawTokenList\n    ? disableWithdrawTokenList.map((item) => {\n        return item.symbol\n      })\n    : []\n\n  Reflect.ownKeys(tokensMap).forEach((key) => {\n    if (pairs[key as string] && pairs[key as string].tokenList) {\n      // @ts-ignore\n      tokensMap[key].tradePairs = pairs[key as string].tokenList\n    }\n  })\n  if (disableWithdrawTokenListRaw) {\n    localStorage.setItem(\n      'disableWithdrawTokenList',\n      JSON.stringify({\n        ...(disableWithdrawTokenListChain ? JSON.parse(disableWithdrawTokenListChain) : {}),\n        [chainId]: disableWithdrawTokenListRaw,\n      }),\n    )\n  }\n  if (tokenListRaw) {\n    localStorage.setItem(\n      'tokenMap',\n      JSON.stringify({\n        ...(tokenChainMap ? JSON.parse(tokenChainMap) : {}),\n        [chainId]: tokenListRaw,\n      }),\n    )\n  }\n  if (marketRaw) {\n    localStorage.setItem(\n      'markets',\n      JSON.stringify({\n        ...(marketChain ? JSON.parse(marketChain) : {}),\n        [chainId]: marketRaw,\n      }),\n    )\n  }\n\n  return {\n    data: {\n      coinMap,\n      totalCoinMap,\n      addressIndex,\n      idIndex,\n      tokenMap,\n      disableWithdrawList,\n      marketArray: marketArr,\n      marketCoins: tokenArr,\n    },\n  }\n}\n\nexport function* getPostsSaga<R extends { [key: string]: any }>({\n  payload,\n}: PayloadAction<GetTokenMapParams<R>>) {\n  try {\n    const {\n      tokensMap,\n      coinMap,\n      totalCoinMap,\n      idIndex,\n      addressIndex,\n      marketMap,\n      pairs,\n      marketArr,\n      tokenArr,\n      disableWithdrawTokenList,\n      tokenListRaw,\n      marketRaw,\n      disableWithdrawTokenListRaw,\n    } = payload\n\n    // @ts-ignore\n    const { data } = yield call(getTokenMapApi, {\n      tokensMap,\n      coinMap,\n      totalCoinMap,\n      idIndex,\n      addressIndex,\n      pairs,\n      marketArr,\n      tokenArr,\n      disableWithdrawTokenList,\n      tokenListRaw,\n      marketRaw,\n      disableWithdrawTokenListRaw,\n    })\n\n    yield put(getTokenMapStatus({ ...data, marketMap }))\n  } catch (err) {\n    yield put(getTokenMapStatus({ error: err }))\n  }\n}\n\nexport function* tokenInitSaga() {\n  yield all([takeLatest(getTokenMap, getPostsSaga)])\n}\n\nexport const tokenSaga = [\n  fork(tokenInitSaga),\n  // fork(tokenPairsSaga),\n]\n"
  },
  {
    "path": "packages/core/src/stores/tokenPrices/hook.ts",
    "content": "import { useDispatch, useSelector } from 'react-redux'\nimport React from 'react'\nimport { TokenPricesStates } from './interface'\nimport { getTokenPrices, statusUnset } from './reducer'\n\nexport const useTokenPrices = <R extends { [key: string]: any }>(): TokenPricesStates<R> & {\n  getTokenPrices: () => void\n  statusUnset: () => void\n} => {\n  const tokenPrices: TokenPricesStates<R> = useSelector((state: any) => state.tokenPrices)\n  const dispatch = useDispatch()\n  return {\n    ...tokenPrices,\n    statusUnset: React.useCallback(() => dispatch(statusUnset(undefined)), [dispatch]),\n    getTokenPrices: React.useCallback(() => dispatch(getTokenPrices(undefined)), [dispatch]),\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/tokenPrices/index.ts",
    "content": "export * from './hook'\nexport * from './interface'\nexport * as tokenPriceReducer from './reducer'\n"
  },
  {
    "path": "packages/core/src/stores/tokenPrices/interface.ts",
    "content": "import { StateBase } from '@loopring-web/common-resources'\n\nexport type TokenPrices<R extends { [key: string]: any }> = {\n  [key in keyof R]: number\n}\n\nexport type TokenPricesStates<R extends { [key: string]: any }> = {\n  tokenPrices: TokenPrices<R>\n  __timer__?: number\n  __rawConfig__: any\n} & StateBase\n"
  },
  {
    "path": "packages/core/src/stores/tokenPrices/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { TokenPricesStates } from './interface'\nimport { SagaStatus } from '@loopring-web/common-resources'\n\nconst initialState: Required<TokenPricesStates<object>> = {\n  tokenPrices: {},\n  __rawConfig__: undefined,\n  __timer__: -1,\n  status: SagaStatus.PENDING,\n  errorMessage: null,\n}\nconst tokenPricesSlice: Slice = createSlice({\n  name: 'tokenPrices',\n  initialState,\n  reducers: {\n    resetTokenPrices(state) {\n      if (state.__timer__ !== -1) {\n        clearInterval(state.__timer__)\n        state.__timer__ = -1\n      }\n      state.tokenPrices = {}\n      state.status = SagaStatus.UNSET\n    },\n    getTokenPrices(state, _action: PayloadAction<undefined>) {\n      state.status = SagaStatus.PENDING\n    },\n    getTokenPricesStatus(state, action: PayloadAction<TokenPricesStates<any>>) {\n      // @ts-ignore\n      if (action.payload.error) {\n        state.status = SagaStatus.ERROR\n        // @ts-ignore\n        state.errorMessage = action.payload.error\n        return\n      } else {\n        const { tokenPrices, __timer__, __rawConfig__ } = action.payload\n        if (tokenPrices) {\n          state.tokenPrices = tokenPrices\n          state.__rawConfig__ = __rawConfig__\n        }\n        if (__timer__) {\n          state.__timer__ = __timer__\n        }\n        state.status = SagaStatus.DONE\n      }\n    },\n\n    statusUnset: (state) => {\n      state.status = SagaStatus.UNSET\n    },\n  },\n})\nexport { tokenPricesSlice }\nexport const { resetTokenPrices, getTokenPrices, getTokenPricesStatus, statusUnset } =\n  tokenPricesSlice.actions\n"
  },
  {
    "path": "packages/core/src/stores/tokenPrices/saga.ts",
    "content": "import { all, call, fork, put, takeLatest } from 'redux-saga/effects'\nimport { getTokenPrices, getTokenPricesStatus } from './reducer'\nimport { store, LoopringAPI } from '../../index'\nimport { myLog } from '@loopring-web/common-resources'\n\nexport const getTokenPricesApi = async <R extends { [key: string]: any }>() => {\n  const { addressIndex } = store.getState().tokenMap\n  if (LoopringAPI?.exchangeAPI && addressIndex) {\n    myLog('loop get getLatestTokenPrices')\n    \n    const { tokenPrices: _tokenPrices, raw_data } =\n      await LoopringAPI?.exchangeAPI.getLatestTokenPrices()\n    let { __timer__ } = store.getState().tokenPrices\n    const tokenPrices: { [key in keyof R]: number } = Reflect.ownKeys(_tokenPrices).reduce(\n      (prev, address) => {\n        const symbol = addressIndex[address.toString().toLowerCase()]\n        if (symbol === 'TAIKO') {\n          return { \n            ...prev, \n            [symbol]: _tokenPrices[address as keyof R],\n            ['LRTAIKO']: 0\n          }\n        } else {\n          return { ...prev, [symbol]: _tokenPrices[address as keyof R] }\n        }\n      },\n      {} as { [key in keyof R]: number },\n    )\n    __timer__ = ((__timer__) => {\n      if (__timer__ && __timer__ !== -1) {\n        clearInterval(__timer__)\n      }\n      return setInterval(() => {\n        store.dispatch(getTokenPrices({}))\n      }, 900000) //15*60*1000 //900000\n    })(__timer__)\n    return { tokenPrices, __timer__, __rawConfig__: raw_data }\n  }\n}\n\nexport function* getPostsSaga() {\n  try {\n    const { tokenPrices, __timer__, __rawConfig__ } = yield call(getTokenPricesApi)\n    yield put(getTokenPricesStatus({ tokenPrices, __timer__, __rawConfig__ }))\n  } catch (err) {\n    yield put(getTokenPricesStatus({ error: err }))\n  }\n}\n\nexport function* tokenPricesInitSaga() {\n  yield all([takeLatest(getTokenPrices, getPostsSaga)])\n}\n\nexport const tokenPricesSaga = [fork(tokenPricesInitSaga)]\n"
  },
  {
    "path": "packages/core/src/stores/userRewards/hook.ts",
    "content": "import { useDispatch, useSelector } from 'react-redux'\nimport { getUserRewards, resetUserRewards, statusUnset } from './reducer'\nimport { UserRewardsStates } from './interface'\nimport React from 'react'\n\nexport function useUserRewards(): UserRewardsStates<UserRewardsStates<any>> & {\n  getUserRewards: () => void\n  statusUnset: () => void\n  resetUserRewards: () => void\n} {\n  const userRewardsMap: UserRewardsStates<UserRewardsStates<any>> = useSelector(\n    (state: any) => state.userRewardsMap,\n  )\n  const dispatch = useDispatch()\n  return {\n    ...userRewardsMap,\n    resetUserRewards: React.useCallback(() => dispatch(resetUserRewards(undefined)), [dispatch]),\n    statusUnset: React.useCallback(() => dispatch(statusUnset(undefined)), [dispatch]),\n    getUserRewards: React.useCallback(() => dispatch(getUserRewards(undefined)), [dispatch]),\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/userRewards/index.ts",
    "content": "export * from './hook'\nexport * from './interface'\nexport * as useRewardReducer from './reducer'\n"
  },
  {
    "path": "packages/core/src/stores/userRewards/interface.ts",
    "content": "import { MyAmmLP, StateBase } from '@loopring-web/common-resources'\nimport { EarningsRow } from '@loopring-web/component-lib'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nexport type UserRewards = sdk.AmmUserRewardMap\nexport type MyAmmLPMap<R extends { [key: string]: any }> = {\n  [key in keyof R]: MyAmmLP<R>\n}\nexport type UserRewardsStates<R extends { [key: string]: any }, E = EarningsRow> = {\n  userRewardsMap?: UserRewards | undefined\n  defiAverageMap:\n    | {\n        [key in keyof R]: {\n          list: Array<{\n            sellToken: sdk.TokenVolumeV3\n            buyToken: sdk.TokenVolumeV3\n            price: string\n          }>\n          average: string\n          priceTotal: string\n        }\n      }\n    | undefined\n  myAmmLPMap: MyAmmLPMap<R> | undefined\n  totalClaims: { [key in keyof R]: E }\n  rewardU: string\n  feeU: string\n  __timer__: NodeJS.Timeout | -1\n} & StateBase\n"
  },
  {
    "path": "packages/core/src/stores/userRewards/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { UserRewardsStates } from './interface'\nimport { SagaStatus } from '@loopring-web/common-resources'\nimport { makeSummaryMyAmm } from '../../hooks'\n\nconst initialState: UserRewardsStates<{ [key: string]: any }> = {\n  userRewardsMap: undefined,\n  myAmmLPMap: undefined,\n  totalClaims: {},\n  rewardU: '',\n  feeU: '',\n  defiAverageMap: undefined,\n  status: SagaStatus.PENDING,\n  errorMessage: null,\n  __timer__: -1,\n}\nconst userRewardsMapSlice: Slice<UserRewardsStates<any>> = createSlice({\n  name: 'userRewardsMap',\n  initialState,\n  reducers: {\n    getUserRewards(state, _action: PayloadAction<undefined>) {\n      state.status = SagaStatus.PENDING\n    },\n    resetUserRewards(state, _action: PayloadAction<undefined>) {\n      state = {\n        ...initialState,\n        status: SagaStatus.UNSET,\n      }\n    },\n    getUserAMM(state, _action: PayloadAction<undefined>) {\n      const { myAmmLPMap, rewardU, feeU } = makeSummaryMyAmm({\n        userRewardsMap: state.userRewardsMap,\n      })\n      state.rewardU = rewardU\n      state.feeU = feeU\n      state.myAmmLPMap = myAmmLPMap\n    },\n    getUserRewardsStatus(state, action: PayloadAction<UserRewardsStates<any>>) {\n      if ((action.payload as any).error) {\n        state.status = SagaStatus.ERROR\n        state.errorMessage = (action.payload as any).error\n        return\n      }\n      state.errorMessage = null\n      state.userRewardsMap = action.payload.userRewardsMap\n      state.rewardU = action.payload.rewardU\n      state.feeU = action.payload.feeU\n      state.myAmmLPMap = action.payload.myAmmLPMap\n      state.totalClaims = action.payload.totalClaims\n      if (action.payload.__timer__) {\n        state.__timer__ = action.payload.__timer__\n      }\n      state.status = SagaStatus.DONE\n    },\n    statusUnset: (state) => {\n      state.status = SagaStatus.UNSET\n    },\n    setDefiAverageMap(state, action: PayloadAction<{ defiAverageMap: any }>) {\n      state.defiAverageMap = action.payload.defiAverageMap\n    },\n  },\n})\nexport { userRewardsMapSlice }\nexport const {\n  getUserRewards,\n  setDefiAverageMap,\n  resetUserRewards,\n  getUserRewardsStatus,\n  statusUnset,\n} = userRewardsMapSlice.actions\n"
  },
  {
    "path": "packages/core/src/stores/userRewards/saga.ts",
    "content": "import { all, call, fork, put, takeLatest } from 'redux-saga/effects'\nimport {\n  getUserRewards,\n  getUserRewardsStatus,\n  resetUserRewards,\n  setDefiAverageMap,\n} from './reducer'\n\nimport { LoopringAPI, makeClaimRewards, makeSummaryMyAmm, store } from '../../index'\nimport {\n  AccountStatus,\n  DEFI_CONFIG,\n  LEVERAGE_ETH_CONFIG,\n  MapChainId,\n} from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nconst defiNum = 10\nconst getUserRewardsApi = async () => {\n  const { accountId, apiKey, readyState } = store.getState().account\n\n  if (LoopringAPI.ammpoolAPI && LoopringAPI.userAPI && accountId) {\n    let ammUserRewardMap = {},\n      _totalClaims = [],\n      result: any = {}\n    try {\n      ;[ammUserRewardMap, _totalClaims] = await Promise.all([\n        LoopringAPI.ammpoolAPI\n          .getAmmPoolUserRewards({\n            owner: accountId,\n          })\n          .then((response) => {\n            if (\n              response &&\n              ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message)\n            ) {\n              return {}\n            }\n            return response.ammUserRewardMap\n          }),\n        LoopringAPI.userAPI\n          .getUserTotalClaim(\n            {\n              accountId: accountId,\n            },\n            apiKey,\n          )\n          .then((response) => {\n            if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n              return []\n            }\n            // @ts-ignore\n            return response?.raw_data?.items ?? []\n          })\n          .catch((error) => {\n            throw error\n          }),\n      ])\n      if (readyState === AccountStatus.ACTIVATED) {\n        result = makeSummaryMyAmm({\n          userRewardsMap: ammUserRewardMap,\n        })\n        const { marketArray, marketLeverageArray } = store.getState().invest.defiMap\n        const { defaultNetwork } = store.getState().settings\n        const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n\n        LoopringAPI.defiAPI\n          .getDefiDepositList(\n            // .getDefiTransaction(\n            {\n              accountId,\n              number: defiNum,\n              markets: [...marketArray, ...marketLeverageArray],\n              types: [...DEFI_CONFIG.products[network], ...LEVERAGE_ETH_CONFIG.products[network]],\n            } as any,\n            apiKey,\n          )\n          .then((response) => {\n            if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n              return {}\n            }\n            const defiAverageMap = [...marketArray, ...marketLeverageArray].reduce((prev, item) => {\n              let priceTotal = sdk.toBig(0)\n              const _value = (response as any).transactions\n                ?.filter(\n                  (_history) =>\n                    item === _history.market &&\n                    _history.action == sdk?.DefiAction?.Deposit.toUpperCase(),\n                )\n                .slice(0, defiNum)\n                .reduce(\n                  (prev, _history) => {\n                    return {\n                      sellTokenVol: prev.sellTokenVol.plus(_history.sellToken.volume),\n                      buyTokenVol: prev.buyTokenVol.plus(_history.buyToken.volume),\n                      feeVol: prev.feeVol.plus(_history.fee.volume),\n                    }\n                  },\n                  {\n                    sellTokenVol: sdk.toBig(0),\n                    buyTokenVol: sdk.toBig(0),\n                    feeVol: sdk.toBig(0),\n                  },\n                )\n              const price = sdk\n                .toBig(_value.sellTokenVol)\n                .div(sdk.toBig(_value.buyTokenVol).minus(_value.feeVol))\n              prev[item] = {\n                list: _value,\n                average: price.toString(),\n                priceTotal: priceTotal.toString(),\n              }\n              return prev\n            }, {})\n            store.dispatch(setDefiAverageMap({ defiAverageMap }))\n          })\n          .catch((error) => {\n            throw error\n          })\n      }\n      const totalClaims = makeClaimRewards(_totalClaims ?? [])\n      let __timer__ = (() => {\n        return setTimeout(() => {\n          let { __timer__ } = store.getState().userRewardsMap\n          if (__timer__ && __timer__ !== -1) {\n            clearTimeout(__timer__)\n          }\n          store.dispatch(getUserRewards(undefined))\n        }, 60000 * 4)\n      })()\n      return {\n        data: { userRewardsMap: ammUserRewardMap, totalClaims, ...result },\n        __timer__,\n      }\n    } catch (error) {\n      throw error\n    }\n  } else {\n    let { __timer__ } = store.getState().userRewardsMap\n    if (__timer__ && __timer__ !== -1) {\n      clearTimeout(__timer__)\n    }\n    return Promise.resolve({ data: {}, __timer__: -1 })\n  }\n}\n\nexport function* getPostsSaga() {\n  try {\n    const { data, __timer__ } = yield call(getUserRewardsApi)\n    yield put(getUserRewardsStatus({ ...data, __timer__ }))\n  } catch (err) {\n    yield put(getUserRewardsStatus({ error: err }))\n  }\n}\n\nexport function* getResetsSaga() {\n  try {\n    // @ts-ignore\n    let { __timer__ } = store.getState().userRewardsMap\n    if (__timer__ && __timer__ !== -1) {\n      clearTimeout(__timer__)\n    }\n    yield put(getUserRewardsStatus({ userRewardsMap: [], __timer__: -1 }))\n  } catch (err) {\n    yield put(getUserRewardsStatus({ error: err }))\n  }\n}\n\nfunction* userRewardsSaga() {\n  yield all([takeLatest(getUserRewards, getPostsSaga)])\n}\n\nfunction* resetUserRewardsSaga() {\n  yield all([takeLatest(resetUserRewards, getResetsSaga)])\n}\n\nexport const userRewardsForks = [\n  fork(userRewardsSaga),\n  fork(resetUserRewardsSaga),\n  // fork(uerRewardssSaga),\n]\n"
  },
  {
    "path": "packages/core/src/stores/vaultLayer2/hook.ts",
    "content": "import { useDispatch, useSelector } from 'react-redux'\nimport {\n  reset,\n  // socketUpdateBalance,\n  statusUnset,\n  updateVaultLayer2,\n} from './reducer'\nimport { VaultLayer2States } from './interface'\nimport React from 'react'\n\n// import * as sdk from '@loopring-web/loopring-sdk'\n\nexport function useVaultLayer2(): VaultLayer2States & {\n  updateVaultLayer2: (props: {\n    activeInfo?: { hash: string; isInActive: boolean } | undefined\n  }) => void\n  // socketUpdateBalance: (balance: { [key: string]: loopring_defs.UserBalanceInfo }) => void\n  statusUnset: () => void\n  resetLayer2: () => void\n} {\n  const vaultLayer2: VaultLayer2States = useSelector((state: any) => state.vaultLayer2)\n  const dispatch = useDispatch()\n  return {\n    ...vaultLayer2,\n    resetLayer2: React.useCallback(() => {\n      dispatch(reset(undefined))\n    }, [dispatch]),\n    statusUnset: React.useCallback(() => dispatch(statusUnset(undefined)), [dispatch]),\n    updateVaultLayer2: React.useCallback(\n      (props: { activeInfo?: { hash: string; isInActive: boolean } | undefined }) =>\n        dispatch(updateVaultLayer2(props)),\n      [dispatch],\n    ),\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/vaultLayer2/index.ts",
    "content": "export * from './hook'\nexport * from './interface'\nexport * as vaultLayer2Reducer from './reducer'\n"
  },
  {
    "path": "packages/core/src/stores/vaultLayer2/interface.ts",
    "content": "import { StateBase } from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nexport type VaultLayer2Map<R extends { [key: string]: any }> = {\n  [key in keyof R]: sdk.VaultBalance\n}\n\nexport type VaultLayer2States = {\n  vaultLayer2?: VaultLayer2Map<any> | undefined\n  vaultAccountInfo?: sdk.VaultAccountInfo | undefined\n  activeInfo?: {\n    hash: string\n    isInActive: boolean\n  }\n  tokenFactors: {\n    symbol: string\n    factor: string\n  }[]\n  maxLeverage: string | undefined\n  collateralTokens: {\n    orderHash: string\n    collateralTokenId: number\n    collateralTokenAmount: string\n    nftTokenId: number\n    nftData: string\n  }[]\n  __timer__?: NodeJS.Timeout | -1\n} & StateBase\n"
  },
  {
    "path": "packages/core/src/stores/vaultLayer2/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { VaultLayer2States } from './interface'\nimport { SagaStatus } from '@loopring-web/common-resources'\n\nconst initialState: VaultLayer2States = {\n  vaultLayer2: undefined,\n  status: SagaStatus.DONE,\n  errorMessage: null,\n  vaultAccountInfo: undefined,\n  tokenFactors: [],\n  maxLeverage: undefined,\n  collateralTokens: []\n}\nconst vaultLayer2Slice: Slice<VaultLayer2States> = createSlice({\n  name: 'vaultLayer2',\n  initialState,\n  reducers: {\n    updateVaultLayer2(\n      state,\n      _action: PayloadAction<{ activeInfo?: { hash: string; isInActive: boolean } | undefined }>,\n    ) {\n      state.status = SagaStatus.PENDING\n    },\n    reset(state) {\n      state.vaultLayer2 = undefined\n      state.vaultAccountInfo = undefined\n      if (state?.__timer__ && state.__timer__ !== -1) {\n        clearTimeout(state.__timer__ as any)\n        state.__timer__ = -1\n      }\n      state.status = SagaStatus.DONE\n    },\n    socketUpdateBalance(state) {\n      state.status = SagaStatus.PENDING\n    },\n    getVaultLayer2Status(state, action: PayloadAction<VaultLayer2States>) {\n      // @ts-ignore\n      if (action.payload.error) {\n        state.status = SagaStatus.ERROR\n        // @ts-ignore\n        state.errorMessage = action.payload.error\n        return\n      }\n\n      state.__timer__ = action.payload?.__timer__ ?? -1\n      state.activeInfo = action.payload.activeInfo ? action.payload.activeInfo : undefined\n      state.vaultLayer2 = { ...action.payload.vaultLayer2 }\n      state.vaultAccountInfo = { ...action.payload.vaultAccountInfo } as any\n      state.tokenFactors = action.payload.tokenFactors\n      state.maxLeverage = action.payload.maxLeverage\n      state.collateralTokens = action.payload.collateralTokens\n      state.status = SagaStatus.DONE\n    },\n    statusUnset: (state) => {\n      state.status = SagaStatus.UNSET\n    },\n  },\n})\nexport { vaultLayer2Slice }\nexport const { updateVaultLayer2, socketUpdateBalance, getVaultLayer2Status, statusUnset, reset } =\n  vaultLayer2Slice.actions\n"
  },
  {
    "path": "packages/core/src/stores/vaultLayer2/saga.ts",
    "content": "import { all, call, fork, put, takeLatest } from 'redux-saga/effects'\nimport { getVaultLayer2Status, socketUpdateBalance, updateVaultLayer2 } from './reducer'\nimport { CoinKey, PairKey, WalletCoin } from '@loopring-web/common-resources'\nimport { store, LoopringAPI } from '../../index'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { throttle } from 'lodash'\n\ntype VaultLayer2Map<R extends { [key: string]: any }> = {\n  [key in CoinKey<R> | PairKey<R>]?: WalletCoin<R>\n}\n\nconst getVaultLayer2Balance = async <R extends { [key: string]: any }>(activeInfo?: {\n  hash: string\n  isInActive: boolean\n}) => {\n  let {\n    // tokenMap: { idIndex,coinMap },\n    account: { accountId, apiKey },\n    invest: {\n      vaultMap: { idIndex: vaultIdIndex },\n    }\n  } = store.getState()\n  let __timer__ : -1 | NodeJS.Timeout | undefined\n  // const { idIndex: vaultIdIndex } = store.getState().vaultMap\n  let _activeInfo: any = undefined,\n    vaultLayer2,\n    vaultAccountInfo,\n    userBalances,\n    history,\n    wait,\n    tokenFactors, \n    maxLeverage,\n    collateralTokens\n\n  if (apiKey && accountId && accountId >= 10000 && LoopringAPI.vaultAPI) {\n    let promise: any[] = [\n      LoopringAPI.vaultAPI.getVaultInfoAndBalance({ accountId }, apiKey, '1'),\n      LoopringAPI.vaultAPI.getVaultBalance({ accountId, tokens: '' }, apiKey, '1'),\n      LoopringAPI.vaultAPI.getCredit({ accountId }, apiKey, '1'),\n      LoopringAPI.vaultAPI.getCollaterals({ accountId }, apiKey, '1'),\n    ]\n    try {\n      if (activeInfo && activeInfo.hash && activeInfo.isInActive) {\n        promise.push(\n          LoopringAPI.vaultAPI.getVaultGetOperationByHash(\n            {\n              accountId: accountId as any,\n              hash: activeInfo.hash,\n            },\n            apiKey,\n            '1'\n          ),\n        )\n      }\n      ;[vaultAccountInfo, { userBalances }, {tokenFactors, maxLeverage }, {collateralTokens},history] = await Promise.all(promise)\n      if (\n        (vaultAccountInfo as sdk.RESULT_INFO).code ||\n        (vaultAccountInfo as sdk.RESULT_INFO).message\n      ) {\n        throw vaultAccountInfo\n      }\n      if (\n        (history &&\n          history?.raw_data?.operation?.status &&\n          [\n            sdk.VaultOperationStatus.VAULT_STATUS_EARNING,\n            sdk.VaultOperationStatus.VAULT_STATUS_FAILED,\n          ].includes(history?.operation?.status?.toUpperCase() ?? '')) ||\n        [sdk.VaultAccountStatus.IN_STAKING, sdk.VaultAccountStatus.IN_REDEEM].includes(\n          vaultAccountInfo.accountStatus,\n        )\n      ) {\n        _activeInfo = undefined\n        wait = 1000 * 10\n      } else if (\n        activeInfo &&\n        [sdk.VaultAccountStatus.FREE, sdk.VaultAccountStatus.UNDEFINED, ''].includes(\n          vaultAccountInfo.accountStatus,\n        )\n      ) {\n        _activeInfo = activeInfo\n        wait = 1000 * 10\n      } else {\n        wait = Infinity\n      }\n\n      __timer__ = store.getState().vaultLayer2.__timer__\n\n      if (__timer__) {\n        clearTimeout(__timer__)\n      }\n      if (wait !== Infinity) {\n        __timer__ = setTimeout(() => {\n          store.dispatch(updateVaultLayer2({ activeInfo }))\n        }, wait)\n      }\n\n      // if(vaultAccountInfo.userAssets)\n      if (vaultAccountInfo.userAssets) {\n        vaultLayer2 = vaultAccountInfo.userAssets.reduce((prev, item) => {\n          prev[vaultIdIndex[item.tokenId]] = {\n            ...item,\n            locked: userBalances[item.tokenId]?.locked,\n            l2balance: userBalances[item.tokenId]?.total,\n          }\n          return prev\n        }, {} as VaultLayer2Map<R>)\n      }\n    } catch (error) {\n      throw error\n    }\n  }\n  return { vaultLayer2, vaultAccountInfo, activeInfo: _activeInfo, tokenFactors, maxLeverage, collateralTokens, __timer__ }\n}\n\nconst getVaultLayer2BalanceThrottle = throttle(getVaultLayer2Balance, 200)\n\nexport function* getPostsSaga({\n  payload,\n}: {\n  payload: { activeInfo?: { hash: string; isInActive: boolean } | undefined }\n}) {\n  try {\n    let { vaultLayer2, vaultAccountInfo, activeInfo, tokenFactors, maxLeverage, collateralTokens, __timer__ } = yield call(\n      getVaultLayer2BalanceThrottle,\n      payload.activeInfo,\n    )\n\n    yield put(getVaultLayer2Status({ vaultLayer2, vaultAccountInfo, activeInfo, tokenFactors, maxLeverage, collateralTokens, __timer__ }))\n  } catch (err) {\n    yield put(getVaultLayer2Status({ error: err }))\n  }\n}\n\nexport function* vaultLayer2Saga() {\n  // @ts-ignore\n  yield all([takeLatest(updateVaultLayer2, getPostsSaga)])\n}\n\nexport function* getSocketSaga({ payload }: any) {\n  try {\n    let { vaultLayer2 } = store.getState().vaultLayer2\n    vaultLayer2 = { ...vaultLayer2, ...payload }\n    yield put(getVaultLayer2Status({ vaultLayer2 }))\n  } catch (err) {\n    yield put(getVaultLayer2Status({ error: err }))\n  }\n}\n\nexport function* vaultLayer2SocketSaga() {\n  yield all([takeLatest(socketUpdateBalance, getSocketSaga)])\n}\n\nexport const vaultLayer2Fork = [fork(vaultLayer2Saga), fork(vaultLayer2SocketSaga)]\n"
  },
  {
    "path": "packages/core/src/stores/walletL2Collection/hook.ts",
    "content": "import { useDispatch, useSelector } from 'react-redux'\nimport {\n  reset,\n  socketUpdateBalance,\n  statusUnset,\n  updateLegacyContracts,\n  updateWalletL2Collection,\n} from './reducer'\nimport { WalletL2CollectionStates } from './interface'\nimport React from 'react'\nimport * as loopring_defs from '@loopring-web/loopring-sdk'\nimport { CollectionMeta, L2CollectionFilter } from '@loopring-web/common-resources'\nimport { LoopringAPI } from '../../api_wrapper'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { store } from '../index'\n\nexport function useWalletL2Collection<C extends CollectionMeta>(): WalletL2CollectionStates<C> & {\n  updateLegacyContracts: () => void\n  updateWalletL2Collection: (props: {\n    page?: number\n    filter?: L2CollectionFilter | undefined\n  }) => void\n  socketUpdateBalance: (balance: { [key: string]: loopring_defs.UserBalanceInfo }) => void\n  statusUnset: () => void\n  resetL2Collection: () => void\n} {\n  const walletL2Collection: WalletL2CollectionStates<C> = useSelector(\n    (state: any) => state.walletL2Collection,\n  )\n\n  const dispatch = useDispatch()\n\n  return {\n    ...walletL2Collection,\n    resetL2Collection: React.useCallback(() => {\n      dispatch(reset(undefined))\n    }, [dispatch]),\n    statusUnset: React.useCallback(() => dispatch(statusUnset(undefined)), [dispatch]),\n    updateLegacyContracts: React.useCallback(async () => {\n      const account = store.getState().account\n      // const { chainId } = store.getState().system;\n\n      if (account.accountId && LoopringAPI.userAPI) {\n        const response = await LoopringAPI.userAPI.getUserNFTLegacyTokenAddress(\n          {\n            accountId: account.accountId,\n          },\n          account.apiKey,\n        )\n        if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n          dispatch(updateLegacyContracts({ legacyContract: [] }))\n        }\n        dispatch(\n          updateLegacyContracts({\n            legacyContract: [...response?.raw_data?.addresses],\n          }),\n        )\n      }\n    }, [dispatch]),\n\n    updateWalletL2Collection: React.useCallback(\n      ({ page, filter }: { page?: number; filter?: L2CollectionFilter | undefined }) =>\n        dispatch(updateWalletL2Collection({ page, filter })),\n      [dispatch],\n    ),\n    socketUpdateBalance: React.useCallback(\n      (balance: { [key: string]: loopring_defs.UserBalanceInfo }) =>\n        dispatch(socketUpdateBalance(balance)),\n      [dispatch],\n    ),\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/walletL2Collection/index.ts",
    "content": "export * from './hook'\nexport * from './interface'\nexport * as walletL2CollectionReducer from './reducer'\n"
  },
  {
    "path": "packages/core/src/stores/walletL2Collection/interface.ts",
    "content": "import { StateBase, CollectionMeta } from '@loopring-web/common-resources'\n\nexport type WalletL2CollectionStates<C extends CollectionMeta> = {\n  walletL2Collection: C[]\n  legacyContract: string[]\n  total: number\n  page: number\n} & StateBase\n"
  },
  {
    "path": "packages/core/src/stores/walletL2Collection/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { WalletL2CollectionStates } from './interface'\nimport { CollectionMeta, SagaStatus, L2CollectionFilter } from '@loopring-web/common-resources'\n\nconst initialState: WalletL2CollectionStates<CollectionMeta> = {\n  walletL2Collection: [],\n  total: 0,\n  legacyContract: [],\n  status: SagaStatus.DONE,\n  errorMessage: null,\n  page: -1,\n}\nconst walletL2CollectionSlice: Slice<WalletL2CollectionStates<CollectionMeta>> = createSlice({\n  name: 'walletL2Collection',\n  initialState,\n  reducers: {\n    reset(state) {\n      state = {\n        ...initialState,\n      }\n      state.status = SagaStatus.UNSET\n    },\n    updateLegacyContracts(state, action: PayloadAction<{ legacyContract: string[] }>) {\n      state.legacyContract = action.payload?.legacyContract ?? []\n    },\n    updateWalletL2LegacyContract(state, action: PayloadAction<{ legacyContract: string[] }>) {\n      state.legacyContract = action.payload?.legacyContract ?? []\n    },\n    updateWalletL2Collection(\n      state,\n      _action: PayloadAction<{ page?: number; filter?: L2CollectionFilter }>,\n    ) {\n      state.status = SagaStatus.PENDING\n    },\n    socketUpdateBalance(state) {\n      state.status = SagaStatus.PENDING\n    },\n    getWalletL2CollectionStatus(\n      state,\n      action: PayloadAction<WalletL2CollectionStates<CollectionMeta>>,\n    ) {\n      // @ts-ignore\n      if (action.error) {\n        state.status = SagaStatus.ERROR\n        // @ts-ignore\n        state.errorMessage = action.error\n      }\n      state.walletL2Collection = [...(action.payload?.walletL2Collection ?? [])]\n      state.total = action.payload.total ?? 0\n      state.status = SagaStatus.DONE\n      state.page = action.payload.page ?? 1\n    },\n    statusUnset: (state) => {\n      state.status = SagaStatus.UNSET\n    },\n  },\n})\nexport { walletL2CollectionSlice }\nexport const {\n  updateLegacyContracts,\n  updateWalletL2Collection,\n  socketUpdateBalance,\n  getWalletL2CollectionStatus,\n  statusUnset,\n  reset,\n} = walletL2CollectionSlice.actions\n"
  },
  {
    "path": "packages/core/src/stores/walletL2Collection/saga.ts",
    "content": "import { all, call, fork, put, takeLatest } from 'redux-saga/effects'\nimport { getWalletL2CollectionStatus, updateWalletL2Collection } from './reducer'\nimport { store, LoopringAPI } from '../../index'\nimport {\n  CustomError,\n  ErrorMap,\n  CollectionLimit,\n  L2CollectionFilter,\n} from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nconst getWalletL2CollectionBalance = async <_R extends { [key: string]: any }>({\n  page,\n  filter,\n}: {\n  page: number\n  filter?: L2CollectionFilter\n}) => {\n  const offset = (page - 1) * CollectionLimit\n  const { accountId, apiKey, accAddress } = store.getState().account\n  let response\n  if (filter?.isLegacy && apiKey && accountId && LoopringAPI.userAPI && filter?.tokenAddress) {\n    response = await LoopringAPI.userAPI\n      .getUserLegacyCollection(\n        {\n          accountId: accountId.toString(),\n          tokenAddress: filter.tokenAddress,\n          limit: CollectionLimit,\n          offset,\n          ...filter,\n        },\n        apiKey,\n      )\n      .catch((_error) => {\n        throw new CustomError(ErrorMap.TIME_OUT)\n      })\n  } else if (!filter?.isLegacy && apiKey && accountId && LoopringAPI.userAPI) {\n    response = await LoopringAPI.userAPI\n      .getUserOwenCollection(\n        {\n          // @ts-ignore\n          owner: accAddress,\n          limit: CollectionLimit,\n          offset,\n          ...filter,\n        },\n        apiKey,\n      )\n      .catch((_error) => {\n        throw new CustomError(ErrorMap.TIME_OUT)\n      })\n  }\n  let collections: sdk.CollectionMeta[] = [],\n    totalNum = 0\n  if (response && ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message)) {\n    throw new CustomError(ErrorMap.ERROR_UNKNOWN)\n  }\n  collections = (response as any)?.collections\n  totalNum = (response as any).totalNum\n  return {\n    walletL2Collection: collections ?? [],\n    total: totalNum,\n    page,\n  }\n}\n\nexport function* getPostsSaga({ payload: { page = 1, filter } }: any) {\n  try {\n    // @ts-ignore\n    const walletL2Collection: any = yield call(getWalletL2CollectionBalance, {\n      page,\n      filter,\n    })\n    yield put(getWalletL2CollectionStatus({ ...walletL2Collection }))\n  } catch (err) {\n    yield put(getWalletL2CollectionStatus({ error: err }))\n  }\n}\n\nexport function* walletL2CollectionSaga() {\n  yield all([takeLatest(updateWalletL2Collection, getPostsSaga)])\n}\n\nexport const walletL2CollectionFork = [fork(walletL2CollectionSaga)]\n"
  },
  {
    "path": "packages/core/src/stores/walletL2NFTCollection/hook.ts",
    "content": "import { useDispatch, useSelector } from 'react-redux'\nimport { reset, socketUpdateBalance, statusUnset, updateWalletL2NFTCollection } from './reducer'\nimport { WalletL2NFTCollectionStates } from './interface'\nimport React from 'react'\nimport * as loopring_defs from '@loopring-web/loopring-sdk'\nimport { CollectionMeta } from '@loopring-web/common-resources'\n\nexport function useWalletL2NFTCollection<\n  C extends CollectionMeta,\n>(): WalletL2NFTCollectionStates<C> & {\n  updateWalletL2NFTCollection: (props: { page?: number }) => void\n  socketUpdateBalance: (balance: { [key: string]: loopring_defs.UserBalanceInfo }) => void\n  statusUnset: () => void\n  resetL2NFTCollection: () => void\n} {\n  const walletL2NFTCollection: WalletL2NFTCollectionStates<C> = useSelector(\n    (state: any) => state.walletL2NFTCollection,\n  )\n  const dispatch = useDispatch()\n\n  return {\n    ...walletL2NFTCollection,\n    resetL2NFTCollection: React.useCallback(() => {\n      dispatch(reset(undefined))\n    }, [dispatch]),\n    statusUnset: React.useCallback(() => dispatch(statusUnset(undefined)), [dispatch]),\n    updateWalletL2NFTCollection: React.useCallback(\n      ({ page }: { page?: number }) => dispatch(updateWalletL2NFTCollection({ page })),\n      [dispatch],\n    ),\n    socketUpdateBalance: React.useCallback(\n      (balance: { [key: string]: loopring_defs.UserBalanceInfo }) =>\n        dispatch(socketUpdateBalance(balance)),\n      [dispatch],\n    ),\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/walletL2NFTCollection/index.ts",
    "content": "export * from './hook'\nexport * from './interface'\nexport * as walletL2NFTCollectionReducer from './reducer'\n"
  },
  {
    "path": "packages/core/src/stores/walletL2NFTCollection/interface.ts",
    "content": "import { StateBase, CollectionMeta } from '@loopring-web/common-resources'\n\nexport type WalletL2NFTCollectionStates<C extends CollectionMeta> = {\n  walletL2NFTCollection: C[]\n  total: number\n  page: number\n} & StateBase\n"
  },
  {
    "path": "packages/core/src/stores/walletL2NFTCollection/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { WalletL2NFTCollectionStates } from './interface'\nimport { CollectionMeta, SagaStatus } from '@loopring-web/common-resources'\n\nconst initialState: WalletL2NFTCollectionStates<CollectionMeta> = {\n  walletL2NFTCollection: [],\n  total: 0,\n  status: SagaStatus.DONE,\n  errorMessage: null,\n  page: -1,\n}\nconst walletL2NFTCollectionSlice: Slice<WalletL2NFTCollectionStates<CollectionMeta>> = createSlice({\n  name: 'walletL2NFTCollection',\n  initialState,\n  reducers: {\n    updateWalletL2NFTCollection(state, _action: PayloadAction<{ page?: number }>) {\n      state.status = SagaStatus.PENDING\n    },\n    reset(state) {\n      state = {\n        ...initialState,\n      }\n      state.status = SagaStatus.UNSET\n    },\n    socketUpdateBalance(state) {\n      state.status = SagaStatus.PENDING\n    },\n    getWalletL2NFTCollectionStatus(\n      state,\n      action: PayloadAction<WalletL2NFTCollectionStates<CollectionMeta>>,\n    ) {\n      // @ts-ignore\n      if (action.error) {\n        state.status = SagaStatus.ERROR\n        // @ts-ignore\n        state.errorMessage = action.error\n      }\n      state.walletL2NFTCollection = [...(action.payload?.walletL2NFTCollection ?? [])]\n      state.total = action.payload.total ?? 0\n      state.status = SagaStatus.DONE\n      state.page = action.payload.page ?? 1\n    },\n    statusUnset: (state) => {\n      state.status = SagaStatus.UNSET\n    },\n  },\n})\nexport { walletL2NFTCollectionSlice }\nexport const {\n  updateWalletL2NFTCollection,\n  socketUpdateBalance,\n  getWalletL2NFTCollectionStatus,\n  statusUnset,\n  reset,\n} = walletL2NFTCollectionSlice.actions\n"
  },
  {
    "path": "packages/core/src/stores/walletL2NFTCollection/saga.ts",
    "content": "import { all, call, fork, put, takeLatest } from 'redux-saga/effects'\nimport { getWalletL2NFTCollectionStatus, updateWalletL2NFTCollection } from './reducer'\nimport { store, LoopringAPI } from '../../index'\nimport { CustomError, ErrorMap, CollectionLimit } from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nconst getWalletL2NFTCollectionBalance = async <_R extends { [key: string]: any }>({\n  page,\n}: {\n  page: number\n}) => {\n  const offset = (page - 1) * CollectionLimit\n  const { accountId, apiKey } = store.getState().account\n  if (apiKey && accountId && LoopringAPI.userAPI) {\n    const response = await LoopringAPI.userAPI\n      .getUserNFTCollection(\n        {\n          accountId: accountId.toString(),\n          limit: CollectionLimit,\n          offset,\n        },\n        apiKey,\n      )\n      .catch((_error) => {\n        throw new CustomError(ErrorMap.TIME_OUT)\n      })\n\n    let collections: sdk.CollectionMeta[] = [],\n      totalNum = 0\n    if (response && ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message)) {\n      throw new CustomError(ErrorMap.ERROR_UNKNOWN)\n    }\n    collections = (response as any).collections\n    totalNum = (response as any).totalNum\n    return {\n      walletL2NFTCollection: collections ?? [],\n\n      total: totalNum,\n      page,\n    }\n  }\n  return {}\n}\n\nexport function* getPostsSaga({ payload: { page = 1 } }: any) {\n  try {\n    // @ts-ignore\n    const walletL2NFTCollection: any = yield call(getWalletL2NFTCollectionBalance, {\n      page,\n    })\n    yield put(getWalletL2NFTCollectionStatus({ ...walletL2NFTCollection }))\n  } catch (err) {\n    yield put(getWalletL2NFTCollectionStatus({ error: err }))\n  }\n}\n\nexport function* walletL2NFTCollectionSaga() {\n  yield all([takeLatest(updateWalletL2NFTCollection, getPostsSaga)])\n}\n\nexport const walletL2NFTCollectionFork = [fork(walletL2NFTCollectionSaga)]\n"
  },
  {
    "path": "packages/core/src/stores/walletLayer1/hook.ts",
    "content": "import { useDispatch, useSelector } from 'react-redux'\nimport { reset, statusUnset, updateWalletLayer1 } from './reducer'\nimport { WalletLayer1States } from './interface'\nimport React from 'react'\n\nexport function useWalletLayer1(): WalletLayer1States & {\n  updateWalletLayer1: () => void\n  statusUnset: () => void\n  resetLayer1: () => void\n} {\n  const walletLayer1: WalletLayer1States = useSelector((state: any) => state.walletLayer1)\n  const dispatch = useDispatch()\n\n  return {\n    ...walletLayer1,\n    resetLayer1: React.useCallback(() => {\n      dispatch(reset(undefined))\n    }, [dispatch]),\n    statusUnset: React.useCallback(() => dispatch(statusUnset(undefined)), [dispatch]),\n    updateWalletLayer1: React.useCallback(\n      () => dispatch(updateWalletLayer1(undefined)),\n      [dispatch],\n    ),\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/walletLayer1/index.ts",
    "content": "export * from './hook'\nexport * from './interface'\nexport * as walletLayer1Reducer from './reducer'\n"
  },
  {
    "path": "packages/core/src/stores/walletLayer1/interface.ts",
    "content": "import { StateBase, WalletCoin } from '@loopring-web/common-resources'\n\nexport type WalletLayer1Map<R extends { [key: string]: any }> = {\n  [key in keyof R]: WalletCoin<R>\n}\nexport type WalletLayer1States = {\n  walletLayer1?: WalletLayer1Map<any> | undefined\n} & StateBase\n"
  },
  {
    "path": "packages/core/src/stores/walletLayer1/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { WalletLayer1Map, WalletLayer1States } from './interface'\nimport { SagaStatus } from '@loopring-web/common-resources'\n\nconst initialState: WalletLayer1States = {\n  walletLayer1: undefined,\n  status: SagaStatus.DONE,\n  errorMessage: null,\n}\nconst walletLayer1Slice: Slice = createSlice({\n  name: 'walletLayer1',\n  initialState,\n  reducers: {\n    updateWalletLayer1(state, _action: PayloadAction<string | undefined>) {\n      state.status = SagaStatus.PENDING\n    },\n    reset(state, _action: PayloadAction<string | undefined>) {\n      state.walletLayer1 = undefined\n      state.status = SagaStatus.DONE\n    },\n    getWalletLayer1Status(state, action: PayloadAction<{ walletLayer1: WalletLayer1Map<object> }>) {\n      // @ts-ignore\n      if (action.payload.error) {\n        state.status = SagaStatus.ERROR\n        // @ts-ignore\n        state.errorMessage = action.payload.error\n        return\n      }\n      state.errorMessage = undefined\n      state.walletLayer1 = { ...action.payload.walletLayer1 }\n      state.status = SagaStatus.DONE\n    },\n    statusUnset: (state) => {\n      state.status = SagaStatus.UNSET\n    },\n  },\n})\nexport { walletLayer1Slice }\nexport const { updateWalletLayer1, getWalletLayer1Status, statusUnset, reset } =\n  walletLayer1Slice.actions\n"
  },
  {
    "path": "packages/core/src/stores/walletLayer1/saga.ts",
    "content": "import { all, call, fork, put, takeLatest } from 'redux-saga/effects'\nimport { getWalletLayer1Status, updateWalletLayer1 } from './reducer'\nimport { CoinKey, PairKey, WalletCoin } from '@loopring-web/common-resources'\nimport { store, LoopringAPI } from '../../index'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\ntype WalletLayer1Map<R extends { [key: string]: any }> = {\n  [key in CoinKey<R> | PairKey<R>]?: WalletCoin<R>\n}\n\nconst getWalletLayer1Balance = async <R extends { [key: string]: any }>() => {\n  const { accAddress } = store.getState().account\n  const { tokenMap, addressIndex } = store.getState().tokenMap\n\n  if (tokenMap && LoopringAPI.exchangeAPI && accAddress) {\n    const [{ tokenBalances: tokenBalancesObj }, { ethBalance }] = await Promise.all([\n      // @ts-ignore\n      LoopringAPI.exchangeAPI.getAllTokenBalances({\n        owner: accAddress,\n      }),\n      LoopringAPI.exchangeAPI.getEthBalances({\n        owner: accAddress,\n      }),\n      ,\n    ])\n    const tokenBalances = new Map()\n    // @ts-ignore\n    tokenBalancesObj.forEach((item, index) => {\n      // @ts-ignore\n      tokenBalances.set(item.address.toLowerCase(), item.value)\n    })\n    // const tokenBalances = new Map(Object.entries(tokenBalancesObj));\n    tokenBalances.set(tokenMap['ETH']?.address as unknown as sdk.TokenAddress, ethBalance)\n    let walletLayer1\n    if (tokenBalances.size) {\n      walletLayer1 = Array.from(tokenBalances.keys()).reduce((prev, item) => {\n        return {\n          ...prev,\n          [addressIndex[item]]: {\n            belong: addressIndex[item],\n            count: sdk.fromWEI(tokenMap, addressIndex[item], tokenBalances.get(item)),\n          },\n        }\n      }, {} as WalletLayer1Map<R>)\n    }\n    return { walletLayer1 }\n  } else {\n    return { walletLayer1: {} }\n  }\n}\n\nexport function* getPostsSaga() {\n  try {\n    //\n    const { walletLayer1 } = yield call(getWalletLayer1Balance)\n    yield put(getWalletLayer1Status({ walletLayer1 }))\n  } catch (err) {\n    yield put(getWalletLayer1Status({ error: err }))\n  }\n}\n\nexport function* walletLayer1Saga() {\n  yield all([takeLatest(updateWalletLayer1, getPostsSaga)])\n}\n\nexport const walletLayer1Fork = [\n  fork(walletLayer1Saga),\n  // fork(tokenPairsSaga),\n]\n"
  },
  {
    "path": "packages/core/src/stores/walletLayer2/hook.ts",
    "content": "import { useDispatch, useSelector } from 'react-redux'\nimport { reset, socketUpdateBalance, statusUnset, updateWalletLayer2 } from './reducer'\nimport { WalletLayer2States } from './interface'\nimport React from 'react'\nimport * as loopring_defs from '@loopring-web/loopring-sdk'\n\nexport function useWalletLayer2(): WalletLayer2States & {\n  updateWalletLayer2: () => void\n  socketUpdateBalance: (balance: { [key: string]: loopring_defs.UserBalanceInfo }) => void\n  statusUnset: () => void\n  resetLayer2: () => void\n} {\n  const walletLayer2: WalletLayer2States = useSelector((state: any) => state.walletLayer2)\n  const dispatch = useDispatch()\n\n  return {\n    ...walletLayer2,\n    resetLayer2: React.useCallback(() => {\n      dispatch(reset(undefined))\n    }, [dispatch]),\n    statusUnset: React.useCallback(() => dispatch(statusUnset(undefined)), [dispatch]),\n    updateWalletLayer2: React.useCallback(\n      () => dispatch(updateWalletLayer2(undefined)),\n      [dispatch],\n    ),\n    socketUpdateBalance: React.useCallback(\n      (balance: { [key: string]: loopring_defs.UserBalanceInfo }) =>\n        dispatch(socketUpdateBalance(balance)),\n      [dispatch],\n    ),\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/walletLayer2/index.ts",
    "content": "export * from './hook'\nexport * from './interface'\nexport * as walletLayer2Reducer from './reducer'\n"
  },
  {
    "path": "packages/core/src/stores/walletLayer2/interface.ts",
    "content": "import { StateBase } from '@loopring-web/common-resources'\nimport * as loopring_defs from '@loopring-web/loopring-sdk'\n\nexport type WalletLayer2Map<R extends { [key: string]: any }> = {\n  [key in keyof R]: loopring_defs.UserBalanceInfo\n}\n\nexport type WalletLayer2States = {\n  walletLayer2?: WalletLayer2Map<any> | undefined\n} & StateBase\n"
  },
  {
    "path": "packages/core/src/stores/walletLayer2/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { WalletLayer2Map, WalletLayer2States } from './interface'\nimport { SagaStatus } from '@loopring-web/common-resources'\n\nconst initialState: WalletLayer2States = {\n  walletLayer2: undefined,\n  status: SagaStatus.DONE,\n  errorMessage: null,\n}\nconst walletLayer2Slice: Slice<WalletLayer2States> = createSlice({\n  name: 'walletLayer2',\n  initialState,\n  reducers: {\n    updateWalletLayer2(state) {\n      state.status = SagaStatus.PENDING\n    },\n    reset(state) {\n      state.walletLayer2 = undefined\n      state.status = SagaStatus.UNSET\n    },\n    socketUpdateBalance(state) {\n      state.status = SagaStatus.PENDING\n    },\n    getWalletLayer2Status(\n      state,\n      action: PayloadAction<{\n        walletLayer2: WalletLayer2Map<object>\n      }>,\n    ) {\n      // @ts-ignore\n      if (action.error) {\n        state.status = SagaStatus.ERROR\n        // @ts-ignore\n        state.errorMessage = action.error\n      }\n      state.walletLayer2 = { ...action.payload.walletLayer2 }\n      state.status = SagaStatus.DONE\n    },\n    statusUnset: (state) => {\n      state.status = SagaStatus.UNSET\n    },\n  },\n})\nexport { walletLayer2Slice }\nexport const {\n  updateWalletLayer2,\n  socketUpdateBalance,\n  getWalletLayer2Status,\n  statusUnset,\n  reset,\n} = walletLayer2Slice.actions\n"
  },
  {
    "path": "packages/core/src/stores/walletLayer2/saga.ts",
    "content": "import { all, call, fork, put, takeLatest } from 'redux-saga/effects'\nimport { getWalletLayer2Status, socketUpdateBalance, updateWalletLayer2 } from './reducer'\nimport { CoinKey, PairKey, WalletCoin } from '@loopring-web/common-resources'\nimport { store, LoopringAPI } from '../../index'\n\ntype WalletLayer2Map<R extends { [key: string]: any }> = {\n  [key in CoinKey<R> | PairKey<R>]?: WalletCoin<R>\n}\n\nconst getWalletLayer2Balance = async <R extends { [key: string]: any }>() => {\n  const { accountId, apiKey, readyState, _accountIdNotActive, accAddress } =\n    store.getState().account\n  const { idIndex } = store.getState().tokenMap\n  let walletLayer2\n\n  if (apiKey && accountId && accountId >= 10000 && LoopringAPI.userAPI) {\n    // @ts-ignore\n    try {\n      const { userBalances } = await LoopringAPI.userAPI.getUserBalances(\n        { accountId, tokens: '' },\n        apiKey,\n      )\n      if (userBalances) {\n        walletLayer2 = Reflect.ownKeys(userBalances).reduce((prev, item) => {\n          // @ts-ignore\n          return { ...prev, [idIndex[item]]: userBalances[Number(item)] }\n        }, {} as WalletLayer2Map<R>)\n      }\n    } catch (error) {\n      throw error\n    }\n  } else if (\n    !apiKey &&\n    ['DEPOSITING', 'NOT_ACTIVE', 'LOCKED', 'NO_ACCOUNT'].includes(readyState) &&\n    accAddress &&\n    LoopringAPI.exchangeAPI &&\n    LoopringAPI.globalAPI\n  ) {\n    let _accountId =\n      _accountIdNotActive && _accountIdNotActive !== -1 ? _accountIdNotActive : accountId\n    if (['NO_ACCOUNT'].includes(readyState) || _accountIdNotActive == -1) {\n      const { accInfo } = await LoopringAPI.exchangeAPI.getAccount({\n        owner: accAddress,\n      })\n      _accountId = accInfo.accountId\n    }\n    if (_accountId && _accountId !== -1) {\n      const { userBalances } =\n        (await LoopringAPI.globalAPI.getUserBalanceForFee({\n          accountId: _accountId,\n          tokens: '',\n          // tokens,\n        })) ?? {}\n      if (userBalances) {\n        // @ts-ignore\n        walletLayer2 = Reflect.ownKeys(userBalances).reduce((prev, item) => {\n          return { ...prev, [idIndex[item]]: userBalances[Number(item)] }\n        }, {} as WalletLayer2Map<R>)\n      }\n    }\n  }\n  return { walletLayer2 }\n}\n\nexport function* getPostsSaga() {\n  try {\n    const { walletLayer2 } = yield call(getWalletLayer2Balance)\n    yield put(getWalletLayer2Status({ walletLayer2 }))\n  } catch (err) {\n    yield put(getWalletLayer2Status({ error: err }))\n  }\n}\n\nexport function* walletLayer2Saga() {\n  yield all([takeLatest(updateWalletLayer2, getPostsSaga)])\n}\n\nexport function* getSocketSaga({ payload }: any) {\n  try {\n    let { walletLayer2 } = store.getState().walletLayer2\n    walletLayer2 = { ...walletLayer2, ...payload }\n    yield put(getWalletLayer2Status({ walletLayer2 }))\n  } catch (err) {\n    yield put(getWalletLayer2Status({ error: err }))\n  }\n}\n\nexport function* walletLayer2SocketSaga() {\n  yield all([takeLatest(socketUpdateBalance, getSocketSaga)])\n}\n\nexport const walletLayer2Fork = [fork(walletLayer2Saga), fork(walletLayer2SocketSaga)]\n"
  },
  {
    "path": "packages/core/src/stores/walletLayer2NFT/hook.ts",
    "content": "import { useDispatch, useSelector } from 'react-redux'\nimport { reset, socketUpdateBalance, statusUnset, updateWalletLayer2NFT } from './reducer'\nimport { MyNFTFilter } from '@loopring-web/common-resources'\nimport { WalletLayer2NFTStates } from './interface'\nimport React from 'react'\nimport * as loopring_defs from '@loopring-web/loopring-sdk'\n\nexport function useWalletLayer2NFT(): WalletLayer2NFTStates & {\n  updateWalletLayer2NFT: (props: {\n    page?: number\n    nftDatas?: string\n    collectionId: string | undefined\n    collectionContractAddress: string | undefined\n    filter?: MyNFTFilter | undefined\n  }) => void\n  socketUpdateBalance: (balance: { [key: string]: loopring_defs.UserBalanceInfo }) => void\n  statusUnset: () => void\n  resetLayer2NFT: () => void\n} {\n  const walletLayer2NFT: WalletLayer2NFTStates = useSelector((state: any) => state.walletLayer2NFT)\n  const dispatch = useDispatch()\n\n  return {\n    ...walletLayer2NFT,\n    resetLayer2NFT: React.useCallback(() => {\n      dispatch(reset(undefined))\n    }, [dispatch]),\n    statusUnset: React.useCallback(() => dispatch(statusUnset(undefined)), [dispatch]),\n    updateWalletLayer2NFT: React.useCallback(\n      ({\n        page,\n        collectionId,\n        collectionContractAddress,\n        nftDatas,\n        filter,\n      }: {\n        page?: number\n        nftDatas?: string\n        collectionId: string | undefined\n        collectionContractAddress: string | undefined\n        filter?: MyNFTFilter | undefined\n      }) =>\n        dispatch(\n          updateWalletLayer2NFT({\n            page,\n            collectionId,\n            collectionContractAddress,\n            nftDatas,\n            filter,\n          }),\n        ),\n      [dispatch],\n    ),\n    socketUpdateBalance: React.useCallback(\n      (balance: { [key: string]: loopring_defs.UserBalanceInfo }) =>\n        dispatch(socketUpdateBalance(balance)),\n      [dispatch],\n    ),\n  }\n}\n"
  },
  {
    "path": "packages/core/src/stores/walletLayer2NFT/index.ts",
    "content": "export * from './hook'\nexport * from './interface'\nexport * as walletLayer2NFTReducer from './reducer'\n"
  },
  {
    "path": "packages/core/src/stores/walletLayer2NFT/interface.ts",
    "content": "import { CollectionMeta, MyNFTFilter, StateBase } from '@loopring-web/common-resources'\nimport * as loopring_defs from '@loopring-web/loopring-sdk'\n\nexport type WalletLayer2NFTMap<R extends { [key: string]: any }> = {\n  [key in keyof R]: loopring_defs.UserBalanceInfo\n}\n\nexport type WalletLayer2NFTStates = {\n  collection: CollectionMeta | undefined\n  walletLayer2NFT: loopring_defs.UserNFTBalanceInfo[]\n  total: number\n  page: number\n  filter?: MyNFTFilter | undefined\n} & StateBase\n"
  },
  {
    "path": "packages/core/src/stores/walletLayer2NFT/reducer.ts",
    "content": "import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'\nimport { WalletLayer2NFTStates } from './interface'\nimport { CollectionMeta, MyNFTFilter, SagaStatus } from '@loopring-web/common-resources'\n\nconst initialState: WalletLayer2NFTStates = {\n  walletLayer2NFT: [],\n  collection: undefined,\n  total: 0,\n  status: SagaStatus.DONE,\n  errorMessage: null,\n  page: -1,\n}\nconst walletLayer2NFTSlice: Slice<WalletLayer2NFTStates> = createSlice({\n  name: 'walletLayer2NFT',\n  initialState,\n  reducers: {\n    updateWalletLayer2NFT(\n      state,\n      _action: PayloadAction<{\n        page?: number\n        nftDatas?: string\n        collection: CollectionMeta | undefined\n        filter?: MyNFTFilter | undefined\n      }>,\n    ) {\n      state.status = SagaStatus.PENDING\n    },\n    reset(state) {\n      state = {\n        ...initialState,\n      }\n      state.status = SagaStatus.UNSET\n    },\n    socketUpdateBalance(state) {\n      state.status = SagaStatus.PENDING\n    },\n    getWalletLayer2NFTStatus(state, action: PayloadAction<WalletLayer2NFTStates>) {\n      // @ts-ignore\n      if (action.error) {\n        state.status = SagaStatus.ERROR\n        // @ts-ignore\n        state.errorMessage = action.error\n      }\n      state.walletLayer2NFT = [...(action.payload?.walletLayer2NFT ?? [])]\n      state.collection = action.payload.collection\n      state.total = action.payload.total ?? 0\n      state.filter = action.payload.filter\n      state.status = SagaStatus.DONE\n      state.page = action.payload.page ?? 1\n    },\n    statusUnset: (state) => {\n      state.status = SagaStatus.UNSET\n    },\n  },\n})\nexport { walletLayer2NFTSlice }\nexport const {\n  updateWalletLayer2NFT,\n  socketUpdateBalance,\n  getWalletLayer2NFTStatus,\n  statusUnset,\n  reset,\n} = walletLayer2NFTSlice.actions\n"
  },
  {
    "path": "packages/core/src/stores/walletLayer2NFT/saga.ts",
    "content": "import { all, call, fork, put, takeLatest } from 'redux-saga/effects'\nimport { getWalletLayer2NFTStatus, updateWalletLayer2NFT } from './reducer'\nimport { store, LoopringAPI } from '../../index'\nimport { CustomError, ErrorMap, MyNFTFilter, NFTLimit } from '@loopring-web/common-resources'\nimport { PayloadAction } from '@reduxjs/toolkit'\n\nconst getWalletLayer2NFTBalance = async <_R extends { [key: string]: any }>({\n  page,\n  nftDatas,\n  collectionId,\n  collectionContractAddress,\n  filter,\n}: {\n  page: number\n  nftDatas?: string\n  collectionId: string | undefined\n  collectionContractAddress: string | undefined\n  filter?: MyNFTFilter | undefined\n}) => {\n  const offset = (page - 1) * NFTLimit\n  const { accountId, apiKey } = store.getState().account\n  if (apiKey && accountId && LoopringAPI.userAPI) {\n    let userNFTBalances, totalNum\n    if (collectionId) {\n      ;({ userNFTBalances, totalNum } = await LoopringAPI.userAPI\n        .getUserNFTBalancesByCollection(\n          {\n            accountId,\n            tokenAddress: collectionContractAddress!,\n            collectionId: Number(collectionId),\n            limit: NFTLimit,\n            offset,\n            nonZero: true,\n            metadata: true, // close metadata\n            ...(nftDatas ? { nftDatas } : {}),\n            ...(filter ?? {}),\n          },\n          apiKey,\n        )\n        .catch((_error) => {\n          throw new CustomError(ErrorMap.TIME_OUT)\n        }))\n    } else {\n      ;({ userNFTBalances, totalNum } = await LoopringAPI.userAPI\n        .getUserNFTBalances(\n          {\n            accountId,\n            // @ts-ignore\n            tokenAddress: collectionContractAddress ?? undefined,\n            limit: NFTLimit,\n            offset,\n            nonZero: true,\n            metadata: true, // close metadata\n            ...(nftDatas ? { nftDatas } : {}),\n            ...(filter ?? {}),\n          },\n          apiKey,\n        )\n        .catch((_error) => {\n          throw new CustomError(ErrorMap.TIME_OUT)\n        }))\n    }\n\n    return {\n      walletLayer2NFT: userNFTBalances ?? [],\n      total: totalNum,\n      collection: {\n        contractAddress: collectionContractAddress,\n        id: collectionId,\n      },\n      filter,\n      page,\n    }\n  }\n  return {}\n}\n\nexport function* getPostsSaga({\n  payload: { page = 1, collectionId, collectionContractAddress, nftDatas, filter },\n}: PayloadAction<{\n  page?: number\n  nftDatas?: string\n  // collection: CollectionMeta | undefined;\n  collectionId: string | undefined\n  collectionContractAddress: string | undefined\n  filter?: MyNFTFilter | undefined\n}>) {\n  try {\n    // @ts-ignore\n    const walletLayer2NFT: any = yield call(getWalletLayer2NFTBalance, {\n      page,\n      nftDatas,\n      collectionId,\n      collectionContractAddress,\n      filter,\n    })\n    yield put(getWalletLayer2NFTStatus({ ...walletLayer2NFT }))\n  } catch (err) {\n    yield put(getWalletLayer2NFTStatus({ error: err }))\n  }\n}\n\nexport function* walletLayer2NFTSaga() {\n  // @ts-ignore\n  yield all([takeLatest(updateWalletLayer2NFT, getPostsSaga)])\n}\n\nexport const walletLayer2NFTFork = [fork(walletLayer2NFTSaga)]\n"
  },
  {
    "path": "packages/core/src/types.d.ts",
    "content": "import { LoopringSocket } from '@loopring-web/core'\nimport { RampInstantSDK } from '@ramp-network/ramp-instant-sdk'\n\ndeclare global {\n  interface Window {\n    loopringSocket: InstanceType<LoopringSocket>\n    __renderReportCall__: () => void\n    Banxa: any\n    rampInstance: RampInstantSDK | undefined\n    rampTransPromise: Promise<{ txHash: string }> | undefined\n  }\n}\n"
  },
  {
    "path": "packages/core/src/utils/.gitignore",
    "content": "*.java\n"
  },
  {
    "path": "packages/core/src/utils/AESMd5.ts",
    "content": "import { AES, enc, MD5 } from \"crypto-js\"\n\nexport const encryptAESMd5 = (password: string, data: string) => {\n  const md5Password = MD5(password).toString()\n  return AES.encrypt(data, md5Password).toString()\n}\n\nexport const decryptAESMd5 = (password: string, encryptedData: string) => {\n  const md5Password = MD5(password).toString()\n  return AES.decrypt(encryptedData, md5Password).toString(enc.Utf8)\n}"
  },
  {
    "path": "packages/core/src/utils/address.ts",
    "content": "export const isSameEVMAddress = (address1: string, address2: string) => {\n  return address1.toLowerCase() === address2.toLowerCase()\n}"
  },
  {
    "path": "packages/core/src/utils/addressTypeMap.ts",
    "content": "import { EXCHANGE_TYPE, WALLET_TYPE } from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nconst addressToExWalletMap: [\n  (typeof sdk.AddressType)[sdk.AddressTypeKeys],\n  EXCHANGE_TYPE | WALLET_TYPE,\n][] = [\n  [sdk.AddressType.EXCHANGE_COINBASE, EXCHANGE_TYPE.Coinbase],\n  [sdk.AddressType.EXCHANGE_BINANCE, EXCHANGE_TYPE.Binance],\n  [sdk.AddressType.EXCHANGE_HUOBI, EXCHANGE_TYPE.Huobi],\n  [sdk.AddressType.EXCHANGE_OTHER, EXCHANGE_TYPE.Others],\n  [sdk.AddressType.EOA, WALLET_TYPE.EOA],\n  [sdk.AddressType.LOOPRING_DEX_EOA, WALLET_TYPE.EOA],\n  [sdk.AddressType.LOOPRING_HEBAO_CF, WALLET_TYPE.Loopring],\n  [sdk.AddressType.LOOPRING_HEBAO_CONTRACT_1_1_6, WALLET_TYPE.Loopring],\n  [sdk.AddressType.LOOPRING_HEBAO_CONTRACT_1_2_0, WALLET_TYPE.Loopring],\n  [sdk.AddressType.LOOPRING_HEBAO_CONTRACT_2_0_0, WALLET_TYPE.Loopring],\n  [sdk.AddressType.LOOPRING_HEBAO_CONTRACT_2_1_0, WALLET_TYPE.Loopring],\n  [sdk.AddressType.LOOPRING_HEBAO_CONTRACT_2_2_0, WALLET_TYPE.Loopring],\n  [sdk.AddressType.LOOPRING_HEBAO_CONTRACT_3_0_0, WALLET_TYPE.Loopring],\n  [sdk.AddressType.CONTRACT, WALLET_TYPE.OtherSmart],\n]\nexport const addressToExWalletMapFn = (a: (typeof sdk.AddressType)[sdk.AddressTypeKeys]) => {\n  const found = addressToExWalletMap.find((x) => x[0] === a)\n  return found ? found[1] : undefined\n}\n\nconst exWalletToAddressMap: [\n  WALLET_TYPE | EXCHANGE_TYPE,\n  (typeof sdk.AddressType)[sdk.AddressTypeKeys],\n][] = [\n  [WALLET_TYPE.EOA, sdk.AddressType.EOA],\n  [EXCHANGE_TYPE.Binance, sdk.AddressType.EXCHANGE_BINANCE],\n  [EXCHANGE_TYPE.Huobi, sdk.AddressType.EXCHANGE_HUOBI],\n  [EXCHANGE_TYPE.Others, sdk.AddressType.EXCHANGE_OTHER],\n  [WALLET_TYPE.Loopring, sdk.AddressType.LOOPRING_HEBAO_CF], // to do: is here sdk.AddressType.LOOPRING_HEBAO_CF?\n  [WALLET_TYPE.OtherSmart, sdk.AddressType.CONTRACT], // to do: is here AddressType.LOOPRING_HEBAO_CF?\n]\n\nexport const exWalletToAddressMapFn = (a: WALLET_TYPE | EXCHANGE_TYPE) => {\n  const found = exWalletToAddressMap.find((x) => x[0] === a)\n  return found ? found[1] : undefined\n}\n"
  },
  {
    "path": "packages/core/src/utils/calculation.ts",
    "content": "import Decimal from \"decimal.js\";\n\nexport const numberStringListSum = (list: string[]) => \n  list.reduce((pre, cur) => pre.add(cur), new Decimal(0)).toFixed()\n"
  },
  {
    "path": "packages/core/src/utils/coinbaseSmartWallet.ts",
    "content": "import { ChainId } from \"@loopring-web/loopring-sdk\"\nimport type { UserOperation } from 'permissionless';\nimport {  createPublicClient } from 'viem';\nimport { CHAIN_ID_TO_VIEW_CHAIN } from \"@loopring-web/common-resources\";\nimport { http } from 'viem';\nimport { isWalletACoinbaseSmartWallet } from '@coinbase/onchainkit/wallet';\n\nexport const isCoinbaseSmartWallet = async (accAddress: string | undefined, chainId: ChainId) => {   \n  if (!accAddress) return false;\n  const rpcURL = process.env[`REACT_APP_RPC_URL_${chainId}`]\n  const res = await isWalletACoinbaseSmartWallet({ client:createPublicClient({\n    chain: CHAIN_ID_TO_VIEW_CHAIN.get(chainId),\n    transport: http(rpcURL),\n  }), userOp: { sender: accAddress } as UserOperation<'v0.6'> })\n  return res.isCoinbaseSmartWallet\n}\n"
  },
  {
    "path": "packages/core/src/utils/decimal.ts",
    "content": "import Decimal from \"decimal.js\"\n\nexport const getOptionalDecimal = (value: any) => {\n  try {\n    return new Decimal(value)\n  } catch (e) {\n    return undefined\n  }\n}"
  },
  {
    "path": "packages/core/src/utils/dt_tools.ts",
    "content": "// import { i18nInstance as i18n  } from \"@loopring-web/common-resources\"\nimport i18n from 'i18next'\n\nconst covertLocale = (rawLocale: string = i18n.language) => {\n  return rawLocale.replace('_', '-')\n}\n\nexport function getLocaleDtFromTs(ts: number | string, locale: string = i18n.language) {\n  if (typeof ts === 'string') {\n    ts = parseInt(ts)\n  }\n  const dt = new Date(ts).toLocaleString(covertLocale(locale))\n  return dt\n}\n\nexport function getLocaleDt(dt?: Date, locale: string = i18n.language) {\n  if (dt) {\n    return dt.toLocaleString(covertLocale(locale))\n  }\n  return ''\n}\n\nexport function getTimestampDaysLater(days: number, date: Date = new Date()) {\n  const ts = Math.round(date.getTime() / 1000) + days * 86400\n  return ts\n}\n\nexport function getContactInfo(\n  _subject: string = 'report to loopring website',\n  _body: string = 'Body Content',\n) {\n  // const email = process.env.CONTACT_US_EMAIL ?? 'contact@loopring.io'\n  return `https://loopring.zohodesk.com/portal/en/newticket`\n}\n"
  },
  {
    "path": "packages/core/src/utils/feeInfo.ts",
    "content": "import { WalletMap } from \"@loopring-web/common-resources\";\nimport { OffchainFeeInfo } from \"@loopring-web/loopring-sdk\";\nimport { ethers } from \"ethers\";\nimport { TokenMap } from \"stores\";\n\nexport const offchainFeeInfoToFeeInfo = (offchainFeeInfo: OffchainFeeInfo, tokenMap: TokenMap<{\n  [key: string]: any;\n}>, walletMap: WalletMap<string, any>) => {\n  return {\n    belong: offchainFeeInfo.token,\n    fee: tokenMap[offchainFeeInfo.token] ? ethers.utils.formatUnits(offchainFeeInfo.fee, tokenMap[offchainFeeInfo.token].decimals) : '',\n    feeRaw: offchainFeeInfo.fee,\n    token: offchainFeeInfo.token,\n    hasToken: !!offchainFeeInfo.token,\n    count: walletMap[offchainFeeInfo.token]?.count,\n    discount: offchainFeeInfo.discount ? offchainFeeInfo.discount : undefined,\n    __raw__: {\n      fastWithDraw: '',\n      tokenId: tokenMap[offchainFeeInfo.token]?.tokenId,\n      feeRaw: offchainFeeInfo.fee,\n    }\n  }\n}"
  },
  {
    "path": "packages/core/src/utils/formatter_tool.ts",
    "content": "import { store } from '../index'\n\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport {\n  GET_IPFS_STRING,\n  getValuePrecisionThousand,\n  IPFS_HEAD_URL,\n  IPFS_HEAD_URL_REG,\n  IPFS_LOOPRING_SITE,\n  TradeTypes,\n} from '@loopring-web/common-resources'\nimport { volumeToCountAsBigNumber } from '../hooks/help'\n\nconst getTokenInfo = (symbol: string) => {\n  const tokenMap = store.getState().tokenMap.tokenMap\n\n  if (!tokenMap || !tokenMap[symbol]) {\n    return undefined\n  }\n\n  return tokenMap[symbol]\n}\n\nconst getMarketInfo = (symbol: string) => {\n  const marketMap = store.getState().tokenMap.marketMap\n\n  if (!marketMap || !marketMap[symbol]) {\n    return undefined\n  }\n\n  return marketMap[symbol]\n}\n\nexport function StringToNumberWithPrecision(rawVal: string, symbol: string) {\n  if (rawVal === undefined || rawVal === null || rawVal.trim() === '') return 0\n\n  const tokenInfo = getTokenInfo(symbol)\n\n  if (!tokenInfo) {\n    return undefined\n  }\n\n  return parseFloat(sdk.toBig(rawVal).toFixed(tokenInfo.precision, 0))\n}\n\n/*\n * format volume to real number\n */\nexport function VolToNumberWithPrecision(rawVal: string | number, symbol: string) {\n  const tokenInfo = getTokenInfo(symbol)\n\n  if (!tokenInfo) {\n    return undefined\n  }\n\n  if (rawVal === undefined || rawVal === null || isNaN(Number(rawVal))) return 0\n\n  return sdk\n    .toBig(rawVal)\n    .div('1e' + tokenInfo.decimals)\n    .toFixed(tokenInfo.precision, 0)\n}\n\n/*\n * format raw val with precision\n */\nexport function FormatValWithPrecision(rawVal: string, symbol: string) {\n  const tokenInfo = getTokenInfo(symbol)\n\n  if (!tokenInfo) {\n    return undefined\n  }\n\n  if (rawVal === undefined || rawVal === null || rawVal.trim() === '') return 0\n\n  return sdk.toBig(rawVal).toFixed(tokenInfo.precision, 0)\n}\n\n/*\n * format order price with precision\n */\nexport function formatPriceWithPrecision(rawVal: string, symbol: string) {\n  const marketInfo = getMarketInfo(symbol)\n  if (!rawVal || !marketInfo || !symbol) {\n    return '0'\n  }\n\n  return sdk.toBig(rawVal).toFixed(marketInfo.precisionForPrice)\n}\n\nexport function tradeItemToTableDataItem(tradeItem: any) {\n  const { tokenMap } = store.getState().tokenMap\n  const marketList = tradeItem.market.split('-')\n  // due to AMM case, we cannot use first index\n  const side = tradeItem.side === sdk.Side.Buy ? TradeTypes.Buy : TradeTypes.Sell\n  const isBuy = side === TradeTypes.Buy\n\n  const base = marketList[marketList.length - 2]\n  const quote = marketList[marketList.length - 1]\n  const baseValue = volumeToCountAsBigNumber(base, tradeItem.volume)\n  //\n  const quoteValue = baseValue?.times(tradeItem.price)\n  const sellToken = isBuy ? quote : base\n  const buyToken = isBuy ? base : quote\n  const sellValue = (isBuy ? quoteValue : baseValue)?.toNumber()\n  const buyValue = (isBuy ? baseValue : quoteValue)?.toNumber()\n\n  const feeKey = isBuy ? base : quote\n  const feeKeyPrecision = tokenMap ? tokenMap[feeKey].precision : undefined\n\n  const feeValue = getValuePrecisionThousand(\n    volumeToCountAsBigNumber(feeKey, tradeItem.fee),\n    feeKeyPrecision,\n    feeKeyPrecision,\n    undefined,\n    false,\n    {\n      floor: false,\n      // isTrade: true,\n    },\n  ) as any\n  const counterparty = marketList.length === 3 ? 'Orderbook' : 'Pool'\n  // myLog ('....',tokenMap[base].precision)\n  return {\n    side,\n    role: tradeItem.type,\n    counterparty: counterparty,\n    price: {\n      key: sellToken,\n      value: sdk.toBig(tradeItem.price).toNumber(),\n    },\n    fee: {\n      key: feeKey,\n      value: feeKey && feeValue ? feeValue : undefined,\n    },\n    time: Number(tradeItem.tradeTime),\n    amount: {\n      from: {\n        key: sellToken,\n        value: sellToken ? sellValue : undefined,\n      },\n      to: {\n        key: buyToken,\n        value: buyValue ? buyValue : undefined,\n      },\n\n      volume: getValuePrecisionThousand(\n        baseValue,\n        //@ts-ignore\n        tokenMap[base].precisionForOrder,\n        tokenMap[base].precisionForOrder,\n        tokenMap[base].precisionForOrder,\n        true,\n      ),\n    },\n    __raw__: tradeItem,\n  }\n}\n\nexport function getFloatValue(rawVal: any) {\n  if (rawVal === undefined || rawVal === null) {\n    return 0\n  }\n\n  const isStr = typeof rawVal === 'string'\n  return isStr ? parseFloat(rawVal.trim()) : rawVal\n}\n\nexport function isIntNum(val: any) {\n  var regPos = /^\\d+$/\n  var regNeg = /^-[1-9][0-9]*$/\n  return regPos.test(val) && regNeg.test(val)\n}\n\nexport function isPosIntNum(val: any) {\n  var regPos = /^\\d+$/\n  return regPos.test(val)\n}\n\nexport const getIPFSString: GET_IPFS_STRING = (url: string | undefined, _baseURL: string) => {\n  if (url === undefined) {\n    return ''\n  } else if (url.startsWith('http')) {\n    return url\n  } else if (url.startsWith(IPFS_HEAD_URL)) {\n    const _url = url.replace(IPFS_HEAD_URL_REG, IPFS_LOOPRING_SITE)\n    return _url\n    // myLog(_url, url);\n    // return baseURL + \"/api/v3/delegator/ipfs\" + `?path=` + _url;\n  } else {\n    return url\n  }\n}\n"
  },
  {
    "path": "packages/core/src/utils/genAvatar.ts",
    "content": "export const getRandomColor = () => {\n  var letters = '0123456789ABCDEF'\n  var color = '#'\n  for (var i = 0; i < 6; i++) {\n    color += letters[Math.floor(Math.random() * 16)]\n  }\n  return color\n}\n\nconst getInitials = (name: string) => {\n  let initials\n  const nameSplit = name.split(' ')\n  const nameLength = nameSplit.length\n  if (nameLength > 1) {\n    initials = nameSplit[0].substring(0, 1) + nameSplit[nameLength - 1].substring(0, 1)\n  } else if (nameLength === 1) {\n    initials = nameSplit[0].substring(0, 1)\n  } else return\n\n  return initials.toUpperCase()\n}\n\nexport const createImageFromInitials = (size: number, _name: string, color: string) => {\n  if (_name == null) return\n  const name = getInitials(_name)!\n\n  const canvas = document.createElement('canvas')\n  const context = canvas.getContext('2d')!\n  canvas.width = canvas.height = size\n\n  context.fillStyle = '#ffffff'\n  context.fillRect(0, 0, size, size)\n\n  context.fillStyle = `${color}50`\n  context.fillRect(0, 0, size, size)\n\n  context.fillStyle = color\n  context.textBaseline = 'middle'\n  context.textAlign = 'center'\n  context.font = `${size / 2}px Roboto`\n  context.fillText(name, size / 2, size / 1.9)\n\n  return canvas.toDataURL()\n}\n"
  },
  {
    "path": "packages/core/src/utils/getStateFnState.ts",
    "content": "\nexport const getStateFnState = <T>(setStateFn: React.Dispatch<React.SetStateAction<T>>) => {\n  return new Promise<T>(res => {\n    return setStateFn(state => {\n      res(state)\n      return state\n    })\n  })\n}"
  },
  {
    "path": "packages/core/src/utils/index.ts",
    "content": "export * from './web3_tools'\nexport * from './swap_utils'\nexport * from './dt_tools'\nexport * from './formatter_tool'\nexport * from './makeMeta'\nexport * from './genAvatar'\nexport * from './addressTypeMap'\nexport * from './waitForTx'\nexport {readFileQrCode} from './readFileQrcode'\nexport {\n  numberFormat,\n  numberFormatShowInPercent,\n  numberFormatThousandthPlace,\n  bigNumberFormat,\n  fiatNumberDisplay,\n  toPercent,\n  bipsToPercent,\n  fiatNumberDisplaySafe,\n  bignumberFix\n} from './numberFormat'\nexport {\n  numberStringListSum\n} from './calculation'\nexport {getOptionalDecimal} from './decimal'\nexport {\n  isValid6DigitPasscode,\n  validatePassword,\n  containsRegularCharOnly,\n  isValidateNumberStr,\n} from './validation'\nexport {isNumberStr,strNumDecimalPlacesLessThan} from './validation'\n\nexport {getStateFnState} from './getStateFnState'\nexport { tryFn } from './tryFn'\nexport { isCoinbaseSmartWallet } from './coinbaseSmartWallet'\nexport { encryptAESMd5, decryptAESMd5 } from './AESMd5'\nexport { isSameEVMAddress } from './address'\n\nexport { withRetry } from './retry'\nexport { offchainFeeInfoToFeeInfo } from './feeInfo'\n\n"
  },
  {
    "path": "packages/core/src/utils/makeMeta.ts",
    "content": "import { CollectionMeta, MakeMeta } from '@loopring-web/common-resources'\n\nexport const makeMeta: MakeMeta = ({\n  collection,\n  domain,\n}: {\n  collection: CollectionMeta\n  domain: string\n}) => {\n  const metaDemo = {\n    name: '`${NFT_NAME}`',\n    description: '`${NFT_DESCRIPTION}`',\n    image: 'ipfs://`${CID}`',\n    animation_url: 'ipfs://`${CID}`',\n    collection_metadata: `${domain}/${collection.contractAddress}`,\n    royalty_percentage: '`[0..10] (int 0-10)`',\n    attributes: [\n      {\n        trait_type: '`${PROPERTIES_KEY}`',\n        value: '`${VALUE}`',\n      },\n    ],\n    properties: {\n      '`${PROPERTIES_KEY}`': '`${VALUE}`',\n    },\n  }\n  return { metaDemo }\n}\n"
  },
  {
    "path": "packages/core/src/utils/numberFormat.ts",
    "content": "import Decimal from \"decimal.js\"\n\nimport { BigNumber, utils } from \"ethers\"\nimport { CurrencyToTag, PriceTag } from \"@loopring-web/common-resources\"\n\nexport const numberFormat = (number: string | number, format?: {\n  fixed?: number,\n  fixedRound?: Decimal.Rounding\n  thousandthPlace?: boolean,\n  showInPercent?: boolean,\n  currency?: CurrencyToTag,\n  locale?: Intl.LocalesArgument\n  tokenSymbol?: string\n  removeTrailingZero?: boolean\n}) => {\n  const numberStr1 = typeof number === 'number' ? new Decimal(number).toString() : number\n  const numberStr2 =\n    format?.fixed !== undefined\n      ? format.fixedRound\n        ? new Decimal(numberStr1).toFixed(format?.fixed, format.fixedRound)\n        : new Decimal(numberStr1).toFixed(format?.fixed)\n      : numberStr1\n  const numberStr4 = format?.removeTrailingZero\n    ? new Decimal(numberStr2).toFixed()\n    : numberStr2\n  const numberStr5 = format?.thousandthPlace\n    ? numberStr4.replace(/(?<!\\..*)(\\d)(?=(?:\\d{3})+(?:\\.|$))/g, '$1,')\n    : numberStr4\n  const suffix = format?.showInPercent ? '%' : format?.tokenSymbol ? ' ' + format.tokenSymbol : ''\n  const currencySymbol = format?.currency ? PriceTag[CurrencyToTag[format.currency]] : ''\n\n  if (numberStr5.startsWith('-')) {\n    return `-${currencySymbol}${numberStr5.substring(1)}${suffix}`\n  } else {\n    return `${currencySymbol}${numberStr5}${suffix}`\n  }\n}\n\nexport const numberFormatThousandthPlace = (number: string | number, format?: {\n  fixed?: number,\n  showInPercent?: boolean,\n  currency?: CurrencyToTag,\n  locale?: Intl.LocalesArgument\n  tokenSymbol?: string\n  removeTrailingZero?: boolean,\n  fixedRound?: Decimal.Rounding\n}) => {\n  return numberFormat(number, {thousandthPlace: true, ...format})\n}\n\nexport const numberFormatShowInPercent = (number: string | number, format?: {\n  fixed?: number,\n  thousandthPlace?: boolean,\n  currency?: CurrencyToTag,\n  locale?: Intl.LocalesArgument\n  tokenSymbol?: string\n  removeTrailingZero?: boolean,\n  fixedRound?: Decimal.Rounding\n}) => {\n  return numberFormat(number, {showInPercent: true, fixed: 2, ...format})\n}\n\nexport const fiatNumberDisplay = (number: string | number, currency: CurrencyToTag) => {\n  const numberStr = typeof number === 'number' ? number.toString() : number\n  const fixed = new Decimal(numberStr).lessThan('1') && new Decimal(numberStr).greaterThan('0') ? 6 : 2\n  return numberFormatThousandthPlace(number, {\n    fixed,\n    currency\n  })\n}\n\nexport const fiatNumberDisplaySafe = (number: string | number, currency: CurrencyToTag) => {\n  if (number === undefined || number === null) return undefined\n  const numberStr = typeof number === 'number' ? number.toString() : number\n  const fixed = new Decimal(numberStr).lessThan('1') && new Decimal(numberStr).greaterThan('0') ? 6 : 2\n  return numberFormatThousandthPlace(number, {\n    fixed,\n    currency\n  })\n}\n\nexport const bigNumberFormat = (number: BigNumber | string, decimals: number, format?: {\n  fixed?: number,\n  thousandthPlace?: boolean,\n  showInPercent?: boolean,\n  currency?: CurrencyToTag,\n  locale?: Intl.LocalesArgument\n  tokenSymbol?: string\n  removeTrailingZero?: boolean\n}) => {\n  const bn = typeof number === 'string' ? BigNumber.from(number) : number\n  return numberFormat(utils.formatUnits(bn, decimals), format)\n}\n\nexport const toPercent = (number: string | number, fixed: number) => {\n  return numberFormat(number, {showInPercent: true, fixed: fixed})\n}\n\nexport const bipsToPercent = (bips: number, fixed: number) => {\n  return toPercent(new Decimal(bips).div(10000).toString(), fixed)\n}\n\nexport const bignumberFix = (number: BigNumber, decimals: number, fix: number, fixRound?: 'FLOOR' | 'CEIL') => {\n  const oneUnit = utils.parseUnits('1', decimals - fix)\n  const floor = number\n    .div(oneUnit)\n    .mul(oneUnit)\n  const ceil = floor.add(oneUnit)\n  const nearCeil = ceil.sub(number).gte(number.sub(floor))\n  return fixRound === 'CEIL' ? ceil : fixRound === 'FLOOR' ? floor : nearCeil ? ceil : floor\n}"
  },
  {
    "path": "packages/core/src/utils/promise.ts",
    "content": "\nexport const promiseAllSequently = async (promiseFns: (() => Promise<any>)[]) => {\n  let list = [] as any[]\n  for (let index = 0; index < promiseFns.length; index++) {\n    const fn = promiseFns[index];\n    const res = await fn().catch(e => {\n      throw e\n    })\n    list = list.concat(res)\n  }\n  return list\n}"
  },
  {
    "path": "packages/core/src/utils/readFileQrcode.ts",
    "content": "import jsQR from 'jsqr'\nexport const readFileQrCode = () => {\n  return new Promise<string>((res, rej) => {\n    var input = document.createElement('input')\n    input.onchange = (e: any) => {\n      var file = e.currentTarget.files && e.currentTarget.files[0]\n      var reader = new FileReader()\n\n      reader.onload = (readerEvent: any) => {\n        const img = new Image()\n        img.onload = () => {\n          const canvas = document.createElement('canvas')\n          canvas.width = img.width\n          canvas.height = img.height\n          const ctx = canvas.getContext('2d')\n          ctx!.drawImage(img, 0, 0)\n          const imageData = ctx!.getImageData(0, 0, canvas.width, canvas.height)\n          const code = jsQR(imageData.data, imageData.width, imageData.height)\n          if (code) {\n            res(code.data)\n          } else {\n            rej('no code read')\n          }\n        }\n        img.src = readerEvent.target.result\n      }\n      reader.readAsDataURL(file)\n    }\n    input.type = 'file'\n    input.accept = '.jpg, .png, .jpeg'\n    input.click()\n  })\n}\n"
  },
  {
    "path": "packages/core/src/utils/retry.ts",
    "content": "export const withRetry = <T, Args extends any[]>(\n  fn: (...args: Args) => Promise<T>,\n  maxRetries: number,\n  delayMs?: number\n): ((...args: Args) => Promise<T>) => {\n  const retryFn = async (\n    args: Args,\n    retriesLeft: number,\n    lastError?: Error | unknown\n  ): Promise<T> => {\n    if (retriesLeft < 0 && lastError) {\n      throw lastError;\n    }\n\n    try {\n      return await fn(...args);\n    } catch (err) {\n      if (retriesLeft > 0) {\n        if (delayMs) {\n          await new Promise(resolve => setTimeout(resolve, delayMs));\n        }\n        \n        return retryFn(args, retriesLeft - 1, err);\n      }\n      \n      throw err;\n    }\n  };\n\n  return async (...args: Args): Promise<T> => {\n    return retryFn(args, maxRetries);\n  };\n};\n"
  },
  {
    "path": "packages/core/src/utils/swap_utils.ts",
    "content": "import { utils } from 'ethers'\n\nimport { TokenInfo } from '@loopring-web/loopring-sdk'\n\nimport { CoinInfo, SoursURL } from '@loopring-web/common-resources'\n\nexport function getIcon(symbol: string, tokens: any) {\n  const token: any = tokens[symbol]\n  return getIconByTokenInfo(token)\n}\n\nexport function getIconByTokenInfo(token: TokenInfo) {\n  if (token) {\n    const addr = utils.getAddress(token.address)\n    const path = SoursURL + `ethereum/assets/${addr}/logo.png`\n    return path\n  }\n  return ''\n}\n\nexport function makeCoinInfo(token: TokenInfo) {\n  if (token) {\n    const info: CoinInfo<any> = {\n      icon: getIconByTokenInfo(token),\n      name: token.symbol,\n      simpleName: token.symbol,\n      description: token.name,\n      company: token.name,\n    }\n    return info\n  }\n  return undefined\n}\n"
  },
  {
    "path": "packages/core/src/utils/tryFn.ts",
    "content": "export const tryFn = <T>(tryCall: () => T, catchCall?: (e: any) => T, finallyCall?: () => void) => {\n  try {\n    return tryCall()\n  } catch (e) {\n    if (catchCall) {\n      return catchCall(e)\n    } else {\n      throw e\n    }\n  } finally {\n    if (finallyCall) {\n      finallyCall()\n    }\n  }\n  \n}\n"
  },
  {
    "path": "packages/core/src/utils/validation.ts",
    "content": "import Decimal from 'decimal.js'\nimport { BigNumber } from 'ethers'\nimport { formatUnits, parseUnits } from 'ethers/lib/utils'\nimport { range } from 'lodash'\nconst containsLowercase = (str: string) => /^(?=.*[a-z]).*$/.test(str)\nconst containsLowercaseOnly = (str: string) => /^[a-z]+$/.test(str)\nconst containsUppercase = (str: string) => /^(?=.*[A-Z]).*$/.test(str)\nconst containsUppercaseOnly = (str: string) => /^[A-Z]+$/.test(str)\nconst isValidPasswordLength = (str: string) => /^.{6,20}$/.test(str)\nconst containsSymbol = (str: string) => /^(?=.*[~`!@#$%^&*()--+={}]).*$/.test(str)\nconst containsSymbolOnly = (str: string) => /^[~`!@#$%^&*()--+={}]+$/.test(str)\nconst containsNumber = (str: string) => /^(?=.*[0-9]).*$/.test(str)\nconst containsNumberOnly = (str: string) => /^[0-9]+$/.test(str)\n\nexport const containsRegularCharOnly = (str: string) => {\n  return range(str.length).every((index) => {\n    const char = str.charAt(index)\n    return (\n      containsNumberOnly(char) ||\n      containsSymbolOnly(char) ||\n      containsUppercaseOnly(char) ||\n      containsLowercaseOnly(char)\n    )\n  })\n} \n\nexport enum ValidatePasswordErrEnum {\n  PASSWORD_LENGTH_ERR = 0,\n  NO_LOWERCASE,\n  NO_NUMBER,\n  CONTAINS_IRREGULAR_CHAR,\n}\nexport const isValid6DigitPasscode = (str: string) => containsNumberOnly(str) && str.length === 6\n\nexport const validatePassword = (\n  str: string,\n): { securityLevel: 'invalid' | 'weak' | 'normal' | 'strong'; err?: ValidatePasswordErrEnum } => {\n  if (!isValidPasswordLength(str)) {\n    return {\n      securityLevel: 'invalid',\n      err: ValidatePasswordErrEnum.PASSWORD_LENGTH_ERR,\n    }\n  }\n  if (!containsLowercase(str)) {\n    return {\n      securityLevel: 'invalid',\n      err: ValidatePasswordErrEnum.NO_LOWERCASE,\n    }\n  }\n  if (!containsNumber(str)) {\n    return {\n      securityLevel: 'invalid',\n      err: ValidatePasswordErrEnum.NO_NUMBER,\n    }\n  }\n  if (!containsRegularCharOnly(str)) {\n    return {\n      securityLevel: 'invalid',\n      err: ValidatePasswordErrEnum.CONTAINS_IRREGULAR_CHAR,\n    }\n  }\n  if (!containsUppercase(str) && !containsSymbol(str)) {\n    return {\n      securityLevel: 'weak',\n    }\n  } else if (containsUppercase(str) && containsSymbol(str)) {\n    return {\n      securityLevel: 'strong',\n    }\n  } else {\n    return {\n      securityLevel: 'normal',\n    }\n  }\n}\n\nexport const isValidateNumberStr = (str:string, decimals: number) => {\n  try {\n    parseUnits(str, decimals)\n    return true\n  } catch{\n    return false\n  }\n}\n\nexport const isNumberStr = (str: string): boolean => {\n  return !isNaN(Number(str)) && !isNaN(parseFloat(str));\n}\n\nexport const strNumDecimalPlacesLessThan = (str: string, length: number): boolean => {\n  if (!isNumberStr(str)) return false;\n  const parts = str.split('.');\n  const decimalPlaces = parts.length > 1 ? parts[1].length : 0;\n  return decimalPlaces < length;\n}\n"
  },
  {
    "path": "packages/core/src/utils/waitForTx.ts",
    "content": "import Web3 from 'web3'\nexport const waitForTx = (web3: Web3, hash: string) => {\n  return new Promise((res, rej) => {\n    let subscription = web3.eth.subscribe('newBlockHeaders', async (error, event) => {\n      if (error) {\n        subscription.unsubscribe()\n        rej(error)\n      }\n      const blockTxHashes = (await web3.eth.getBlock(event.hash)).transactions\n      if (blockTxHashes.includes(hash)) {\n        res(await web3.eth.getTransactionReceipt(hash))\n        subscription.unsubscribe()\n      }\n    })\n  })\n}\n"
  },
  {
    "path": "packages/core/src/utils/web3_tools.ts",
    "content": "import { Contract } from '@ethersproject/contracts'\nimport { AddressZero } from '@ethersproject/constants'\nimport { BigNumber } from '@ethersproject/bignumber'\n\nimport { JsonRpcSigner, Web3Provider } from '@ethersproject/providers'\n\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nimport { utils, providers } from 'ethers'\nimport { connectProvides } from '@loopring-web/web3-provider'\nimport { AddressError, myLog, isAddress } from '@loopring-web/common-resources'\nimport { LoopringAPI } from '../api_wrapper'\n\nexport function getLibrary(provider: any): Web3Provider {\n  const library = new Web3Provider(\n    provider,\n    typeof provider.chainId === 'number'\n      ? provider.chainId\n      : typeof provider.chainId === 'string'\n      ? parseInt(provider.chainId)\n      : 'any',\n  )\n  library.pollingInterval = 15000\n\n  return library\n}\n\nexport function transactionChecker(web3: any, address: string) {\n  const account = address.toLowerCase()\n\n  const subscription = web3.eth.subscribe('pendingTransactions', (err: any, _res: any) => {\n    if (err) {\n      console.error(err)\n    }\n  })\n\n  return function watchTransactions() {\n    console.log('Watch Transactions...')\n    subscription.on('data', (txHash: any) => {\n      setTimeout(async () => {\n        try {\n          let tx = await web3.eth.getTransaction(txHash)\n          if (tx.to && tx.to.toLowerCase() === account) {\n            const value = web3.utils.fromWei(tx.value, 'ether')\n            if (value > 0) {\n              console.log('watchTransactions value:', value)\n            }\n          }\n        } catch (err) {\n          console.error(err)\n        }\n      }, 60 * 1000)\n    })\n  }\n}\n\n// returns the checksummed address if the address is valid, otherwise returns false\n\nconst ETHERSCAN_PREFIXES: { [key: number]: string } = {\n  1: '',\n  5: 'goerli.',\n  11155111: 'sepolia.',\n}\n\nexport function getEtherscanLink(\n  chainId: sdk.ChainId,\n  data: string,\n  type: 'transaction' | 'token' | 'address' | 'block',\n): string {\n  const prefix = `https://${ETHERSCAN_PREFIXES[chainId] || ETHERSCAN_PREFIXES[1]}etherscan.io`\n\n  switch (type) {\n    case 'transaction': {\n      return `${prefix}/tx/${data}`\n    }\n    case 'token': {\n      return `${prefix}/token/${data}`\n    }\n    case 'block': {\n      return `${prefix}/block/${data}`\n    }\n    case 'address':\n    default: {\n      return `${prefix}/address/${data}`\n    }\n  }\n}\n\n// shorten the checksummed version of the input address to have 0x + 4 characters at start and end\nexport function shortenAddress(address: string, chars = 4): string {\n  const parsed = isAddress(address)\n  if (!parsed) {\n    throw Error(`Invalid 'address' parameter '${address}'.`)\n  }\n  return `${parsed.substring(0, chars + 2)}...${parsed.substring(42 - chars)}`\n}\n\n// add 10%\nexport function calculateGasMargin(value: BigNumber): BigNumber {\n  return value.mul(BigNumber.from(10000).add(BigNumber.from(1000))).div(BigNumber.from(10000))\n}\n\n// account is not optional\nexport function getSigner(library: Web3Provider, account: string): JsonRpcSigner {\n  return library.getSigner(account).connectUnchecked()\n}\n\n// account is optional\nexport function getProviderOrSigner(\n  library: Web3Provider,\n  account?: string,\n): Web3Provider | JsonRpcSigner {\n  return account ? getSigner(library, account) : library\n}\n\n// account is optional\nexport function getContract(\n  address: string,\n  ABI: any,\n  library: Web3Provider,\n  account?: string,\n): Contract {\n  if (!isAddress(address) || address === AddressZero) {\n    throw Error(`Invalid 'address' parameter '${address}'.`)\n  }\n\n  return new Contract(address, ABI, getProviderOrSigner(library, account) as any)\n}\n\nexport function escapeRegExp(string: string): string {\n  return string.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&') // $& means the whole matched string\n}\n\nexport async function isContract(web3: any, address: string) {\n  try {\n    const code = await web3.eth.getCode(address)\n    return code && code.length > 2\n  } catch (error: any) {\n    myLog(error)\n  }\n}\n\nexport interface AddrCheckResult {\n  realAddr: string\n  addressErr: AddressError\n  isContract?: boolean\n  ens: string\n}\n\nexport async function checkAddr(address: any, web3?: any): Promise<AddrCheckResult> {\n  if (!web3) {\n    web3 = connectProvides.usedWeb3\n  }\n\n  let realAddr = ''\n\n  let addressErr: AddressError = AddressError.NoError\n  let isContract: undefined | boolean,\n    response: any,\n    ens: any = ''\n  if (address) {\n    try {\n      if (/^\\d{5,8}$/g.test(address) && Number(address) > 10000 && LoopringAPI.exchangeAPI) {\n        const {\n          accInfo: { owner },\n        } = await LoopringAPI.exchangeAPI.getAccount({\n          //@ts-ignore\n          accountId: address,\n        })\n        realAddr = owner\n      } else {\n        utils.getAddress(address)\n        realAddr = address\n      }\n      addressErr = AddressError.NoError\n    } catch (reason: any) {\n      if (web3) {\n        addressErr = AddressError.NoError\n        realAddr = await web3?.eth?.ens?.getAddress(address)\n          .then((addr) => {\n            if (addr) {\n              return addr\n            } else {\n              throw 'no result'\n            }\n          })\n          .catch((_e: any) => {\n            addressErr = AddressError.InvalidAddr\n            return ''\n          })\n\n        \n        if (realAddr && addressErr == AddressError.NoError) {\n          ens = address\n        }\n      } else {\n        realAddr = ''\n        addressErr = AddressError.ENSResolveFailed\n      }\n    }\n    if (realAddr && web3) {\n      ;[isContract, response] = await Promise.all([\n        sdk.isContract(web3, realAddr),\n        LoopringAPI.exchangeAPI.getAccount({\n          owner: realAddr,\n        }),\n      ])\n      if (\n        isContract &&\n        ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message)\n      ) {\n        addressErr = AddressError.IsNotLoopringContract\n      }\n    }\n  } else {\n    addressErr = AddressError.EmptyAddr\n  }\n  return {\n    realAddr,\n    addressErr,\n    isContract,\n    ens,\n  }\n}\n"
  },
  {
    "path": "packages/core/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.build.json\",\n  \"compilerOptions\": {\n    \"jsx\": \"react-jsx\",\n    \"noUnusedLocals\": true,\n    \"noUnusedParameters\": true,\n    \"resolveJsonModule\": true,\n    \"allowSyntheticDefaultImports\": true,\n    \"baseUrl\": \"./src\",\n    \"rootDir\": \"./src\"\n  },\n  \"include\": [\n    \"src\",\n    \"src/**/*.json\",\n    \"src/*\"\n  ],\n  \"exclude\": [\n    \"node_modules\",\n    \"build\",\n    \"dist\",\n    \"example\",\n    \"rollup.config.js\"\n  ]\n}\n"
  },
  {
    "path": "packages/core/tsconfig.test.json",
    "content": "{\n  \"extends\": \"./tsconfig.json\",\n  \"compilerOptions\": {\n    \"module\": \"commonjs\"\n  },\n  \"include\": [\n    \"src\",\n    \"src/**/*.json\",\n    \"src/*\"\n  ]\n}\n"
  },
  {
    "path": "packages/web-bridge/.babelrc",
    "content": "{\n  \"presets\": [\n    [\n      \"@babel/preset-env\",\n      {\n        \"targets\": {\n          \"node\": \"current\"\n        },\n        \"loose\": true\n      }\n    ],\n    [\n      \"@babel/preset-react\",\n      {\n        \"runtime\": \"automatic\"\n      }\n    ]\n  ],\n  \"plugins\": [\n    \"@babel/plugin-transform-typescript\",\n    \"@babel/plugin-proposal-nullish-coalescing-operator\",\n    \"@babel/plugin-proposal-optional-chaining\"\n  ]\n}\n"
  },
  {
    "path": "packages/web-bridge/.eslintrc.json",
    "content": "{\n  \"plugins\": [\n    \"react-hooks\"\n  ],\n  \"extends\": [\n    \"react-app\"\n  ],\n  \"overrides\": [\n    {\n      \"files\": [\n        \"**/*.tsx\",\n        \"**/*.ts\"\n      ],\n      \"rules\": {\n        \"import/no-anonymous-default-export\": \"off\",\n        \"@typescript-eslint/no-unused-vars\": \"warn\",\n        \"react-hooks/rules-of-hooks\": \"error\",\n        // 检查 Hook 的规则\n        \"react-hooks/exhaustive-deps\": \"warn\"\n        // 检查 effect 的依赖\n      }\n    }\n  ]\n}\n"
  },
  {
    "path": "packages/web-bridge/.gitignore",
    "content": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n# Runtime data\npids\n*.pid\n*.seed\n*.pid.lock\n\n# Directory for instrumented libs generated by jscoverage/JSCover\nlib-cov\n\n# Coverage directory used by tools like istanbul\ncoverage\n\n# nyc test coverage\n.nyc_output\n\n# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)\n.grunt\n\n# Bower dependency directory (https://bower.io/)\nbower_components\n\n# node-waf configuration\n.lock-wscript\n\n# Compiled binary addons (https://nodejs.org/api/addons.html)\nbuild/Release\n\n# Dependency directories\nnode_modules/\njspm_packages/\n\n# TypeScript v1 declaration files\ntypings/\n\n# Optional npm cache directory\n.npm\n\n# Optional eslint cache\n.eslintcache\n\n# Optional REPL history\n.node_repl_history\n\n# Output of 'npm pack'\n*.tgz\n\n# Yarn Integrity file\n.yarn-integrity\n\n# dotenv environment variables file\n.env\n\n# parcel-bundler cache (https://parceljs.org/)\n.cache\n\n# next.js build output\n.next\n\n# nuxt.js build output\n.nuxt\n\n# vuepress build output\n.vuepress/dist\n\n# Serverless directories\n.serverless/\n\n# FuseBox cache\n.fusebox/\n\n# DynamoDB Local files\n.dynamodb/\n# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\n/node_modules\n/.pnp\n.pnp.js\n\n# testing\n/coverage\n\n# production\n**/build\n/out\n/dist\n\n# misc\n.DS_Store\n.env.local\n.env.development\n.env.development.local\n# .env.prod_for_dev\n\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n*.code-workspace\n.vscode\nopenapitools.json\n*.tgz\n.idea/\ntestkey.txt\n\ntest_datadir\n\nipfs_deploy.txt\n.env.deploy*\n.testfile*\n.DS_Store\n"
  },
  {
    "path": "packages/web-bridge/README.md",
    "content": "<p align=\"center\">\n  <a href=\"https://github.com/Loopring/loopring-web-v2\" rel=\"noopener\" target=\"_blank\"><img width=\"150\" src=\"https://loopring.org/images/logo.svg\" alt=\"Loopring-website\"></a>\n</p>\n\n<h1 align=\"center\">Loopring Application</h1>\n<div align=\"center\">\n<h2>Ethereum’s First zkRollup Layer2</h2>\n<p>Fast, Secure, and 100x Lower Fees</p>\n\n[![license](https://img.shields.io/badge/license-MIT-blue)](https://github.com/Loopring/loopring-web-v2/master/LICENSE)\n\n[![type-badge](https://img.shields.io/npm/types/react-data-grid)](https://www.npmjs.com/package/react-data-grid)\n\n<!-- [![Materi-UI](https://img.shields.io/npm/types/react-data-grid)](https://www.npmjs.com/package/react-data-grid) -->\n\n</div>\n\n## 🚀 Quick Start\n\n```bash\n// with yarn\nyarn install\nyarn up\ncd ./packages/webapp\nnpm run dev\n\n\n```\n\n## 📚 Loopring UI component StoryBook\n\n```bash\n\ncd ./packages/component-lib\nnpm run storybook\n```\n\n## 🏗 Framework Design\n\n![](https://static.loopring.io/Loopring%20framwork.png)\n\n## 👉 [What is Loopring?](https://loopring.org/#/)\n\n## 🫂 Community\n\n- [Loopring Website](https://loopring.org/)\n- [Loopring Exchange](https://loopring.io/#/layer2)\n- [Loopring Reddit](https://www.reddit.com/r/loopringorg/)\n- [Loopring Medium](https://medium.com/loopring-protocol)\n- [Loopring Twitter](https://twitter.com/loopringorg)\n- [Loopring Telegram](https://t.me/loopring_en)\n\n## 👺 For Developer\n\n- We appreciate any improvements or initiatives for Loopring Layer2 website, please view the source code\n  in `./packages/component-lib`.\n- The project contains a separate lib \"web3-provider\", which is a third-party ETH web3 wallet provider service (\n  wallectConnect & metamask),\n- You are welcome to reuse it or integrate your provider service with our website.\n- Feel free to leave suggestions or ideas.\n\n### 📒 API & Dependency\n\n- [Web3-Provider](https://www.npmjs.com/package/@loopring-web/web3-provider)\n- [Loopring-sdk](https://www.npmjs.com/package/@loopring-web/loopring-sdk)\n- [Python](https://github.com/Loopring/hello_loopring)\n- [APIs](https://docs.loopring.io)\n\n## 🙋 Protocol & Architecture\n\n- [Whitepaper](https://loopring.org/resources/en_whitepaper.pdf)\n- [Design Docs](https://github.com/LoopringSecondary/docs/wiki/Loopring3_Design)\n\n## ❓[Help](https://desk.zoho.com/portal/loopring/en/home)\n\n## 🔑 Security\n\n- [Wallet](https://security.loopring.io/)\n- [Protocol Audit](https://loopring.org/resources/loopring1.0_audit.pdf)\n\n## Release Process\n\nalpha.loopring.io, beta.loopring.io, static.loopring.io, and loopring.io are now auto deployed using Vercel.\n"
  },
  {
    "path": "packages/web-bridge/craco.config.js",
    "content": "module.exports = require(\"../../craco.config.cjs\")"
  },
  {
    "path": "packages/web-bridge/electron-builder.env",
    "content": "ELECTRON_BUILDER_ALLOW_UNRESOLVED_DEPENDENCIES=true\n"
  },
  {
    "path": "packages/web-bridge/generate-react-cli.json",
    "content": "{\n  \"usesTypeScript\": true,\n  \"usesCssModule\": true,\n  \"cssPreprocessor\": \"scss\",\n  \"testLibrary\": \"Testing Library\",\n  \"component\": {\n    \"default\": {\n      \"path\": \"src/components\",\n      \"withLazy\": false,\n      \"withStory\": true,\n      \"withStyle\": true,\n      \"withTest\": true\n    },\n    \"page\": {\n      \"path\": \"src/pages\",\n      \"withLazy\": true,\n      \"withStory\": false,\n      \"withStyle\": true,\n      \"withTest\": true\n    },\n    \"layout\": {\n      \"path\": \"src/layout\",\n      \"withLazy\": false,\n      \"withStory\": false,\n      \"withStyle\": false,\n      \"withTest\": true\n    }\n  }\n}\n"
  },
  {
    "path": "packages/web-bridge/jest.config.js",
    "content": "module.exports = {\n  testEnvironment: 'node',\n\n  setupFilesAfterEnv: ['./jest.setup.js'],\n}\n"
  },
  {
    "path": "packages/web-bridge/jest.setup.js",
    "content": "process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0\n\njest.setTimeout(30000)\n"
  },
  {
    "path": "packages/web-bridge/package.json",
    "content": "{\n  \"name\": \"@loopring-web/web-bridge\",\n  \"version\": \"1.0.0\",\n  \"author\": \"Loopring L2 App Frontend Team\",\n  \"description\": \"dexwebapp new version\",\n  \"private\": true,\n  \"dependencies\": {\n    \"@loopring-web/common-resources\": \"1.0.0\",\n    \"@loopring-web/component-lib\": \"1.0.0\",\n    \"@loopring-web/core\": \"1.0.0\",\n    \"react-scripts\": \"5.0.1\",\n    \"cross-env\": \"^7.0.3\"\n  },\n  \"resolutions\": {\n    \"@types/react\": \"^18.2.19\",\n    \"@types/react-dom\": \"^18.2.7\"\n  },\n  \"build\": {\n    \"files\": [\n      \"build/**/*\",\n      \"node_modules/**/*\"\n    ],\n    \"publish\": {\n      \"provider\": \"custom\",\n      \"repo\": \"https://github.com/Loopring/loopring-web-v2\",\n      \"owner\": \"Loopring Dex Frontend Team\"\n    }\n  },\n  \"main\": \"./public/electron.js\",\n  \"homepage\": \".\",\n  \"scripts\": {\n    \"build\": \"git rev-parse --short HEAD; cross-env REACT_APP_VER=`git rev-parse --short HEAD`_prod dotenv -e .env.production craco build\",\n    \"dev\": \"export SET NODE_OPTIONS=--openssl-legacy-provider && cross-env REACT_APP_VER=\\\"git rev-parse --short HEAD\\\"_dev dotenv -e .env.development craco start\",\n    \"build_dev\": \"REACT_APP_VER=`git rev-parse --short HEAD`_dev dotenv -e .env.development craco build\"\n  },\n  \"browserslist\": {\n    \"production\": [\n      \"last 2 chrome version\",\n      \"last 2 firefox version\",\n      \"last 2 safari version\"\n    ],\n    \"development\": [\n      \"last 1 chrome version\",\n      \"last 1 firefox version\",\n      \"last 1 safari version\"\n    ]\n  }\n}\n"
  },
  {
    "path": "packages/web-bridge/public/electron.js",
    "content": "const path = require('path')\n\nconst { app, BrowserWindow } = require('electron')\nconst isDev = require('electron-is-dev')\n\nconsole.log('BROWSER:', process.env.BROWSER)\nconsole.log('NODE_ENV:', process.env.NODE_ENV)\n\nfunction createWindow() {\n  // Create the browser window.\n  const win = new BrowserWindow({\n    width: 1024,\n    height: 768,\n    frame: true,\n    webPreferences: {\n      nodeIntegration: true,\n    },\n  })\n\n  // and load the index.html of the app.\n  // win.loadFile(\"index.html\");\n  win.loadURL(\n    isDev ? 'http://localhost:3000' : `file://${path.join(__dirname, '../build/index.html')}`,\n  )\n\n  // Open the DevTools.\n  if (isDev) {\n    win.webContents.openDevTools({ mode: 'detach' })\n  }\n}\n\n// This method will be called when Electron has finished\n// initialization and is ready to create browser windows.\n// Some APIs can only be used after this event occurs.\napp.whenReady().then(createWindow)\n\n// Quit when all windows are closed, except on macOS. There, it's common\n// for applications and their menu bar to stay active until the user quits\n// explicitly with Cmd + Q.\napp.on('window-all-closed', () => {\n  if (process.platform !== 'darwin') {\n    app.quit()\n  }\n})\n\napp.on('activate', () => {\n  // On macOS it's common to re-create a window in the app when the\n  // dock icon is clicked and there are no other windows open.\n  if (BrowserWindow.getAllWindows().length === 0) {\n    createWindow()\n  }\n})\n"
  },
  {
    "path": "packages/web-bridge/public/index.html",
    "content": "<!DOCTYPE html>\n<html lang='en'>\n<head>\n  <meta charset='utf-8' />\n  <link rel='icon' href='%PUBLIC_URL%/favicon.ico' />\n  <meta name='description' content='Ethereum zkRollup Exchange and Payment Protocol' />\n  <meta\n    name='viewport'\n    content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0'\n  />\n  <meta name='theme-color' content='#000000' />\n  <meta\n    name='description'\n    content='Loopring Layer 2, Ethereum zkRollup Exchange and Payment Protocol'\n  />\n\n  <link\n    rel='stylesheet'\n    href='https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap'\n  />\n  <link rel='apple-touch-icon' href='%PUBLIC_URL%/logo192.png' />\n  <!--\n    manifest.json provides metadata used when your web app is installed on a\n    user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/\n  -->\n  <link rel='manifest' href='%PUBLIC_URL%/manifest.json' />\n  <!--\n    Notice the use of %PUBLIC_URL% in the tags above.\n    It will be replaced with the URL of the `public` folder during the build.\n    Only files inside the `public` folder can be referenced from the HTML.\n\n    Unlike \"/favicon.ico\" or \"favicon.ico\", \"%PUBLIC_URL%/favicon.ico\" will\n    work correctly both with client-side routing and a non-root public URL.\n    Learn how to configure a non-root public URL by running `npm run build`.\n  -->\n  <style type='text/css'>\n      body {\n          height: 100vh;\n          background: linear-gradient(194.79deg, #000000 17.96%, #434343 44.29%, #BFBFBF 96.93%);\n          color: #fff;\n          flex-direction: column;\n      }\n\n      .iubenda-pure {\n          height: 0 !important;\n          width: 0 !important;\n          line-height: 0 !important;\n          overflow: hidden !important;\n          padding: 0;\n          margin: 0;\n          display: none !important;\n      }\n\n      #iubenda-pp iframe {\n          display: block;\n      }\n  </style>\n  <script async src='https://www.googletagmanager.com/gtag/js?id=UA-224502206-1'></script>\n  <script\n    type='module'\n    src='https://unpkg.com/@google/model-viewer/dist/model-viewer.min.js'\n  ></script>\n  <script>\n    window.dataLayer = window.dataLayer || []\n\n    function gtag() {\n      dataLayer.push(arguments)\n    }\n\n    gtag('js', new Date())\n    gtag('config', 'UA-224502206-1')\n  </script>\n  <title>Loopring - Ethereum Layer2</title>\n  <!-- Global site tag (gtag.js) - Google Analytics -->\n</head>\n\n<body ondragstart='return false;' ondrop='return false;' draggable='false'>\n<noscript>You need to enable JavaScript to run this app.</noscript>\n<div id='root' style='width: 100%; height: 100vh; display: flex; flex-direction: column'></div>\n<!--\n  This HTML file is a template.\n  If you open it directly in the browser, you will see an empty page.\n\n  You can add webfonts, meta tags, or analytics to this file.\n  The build step will place the bundled scripts into the <body> tag.\n\n  To begin the development, run `npm start` or `yarn start`.\n  To create a production bundle, use `npm run build` or `yarn build`.\n-->\n<div hidden>\n  <a\n    href='https://www.iubenda.com/terms-and-conditions/74969935'\n    data-index='0'\n    class='iubenda-white iubenda-embed iubenda-pure iubenda-noiframe'\n  ></a>\n  <!--      <a href=\"https://www.iubenda.com/terms-and-conditions/74969935\"-->\n  <!--         class=\"iubenda-black iubenda-embed iubenda-pure iubenda-noiframe\"></a>-->\n</div>\n<script type='text/javascript'>\n  ;(function(w, d) {\n    var loader = function() {\n      var s = d.createElement('script'),\n        tag = d.getElementsByTagName('script')[0]\n      s.src = 'https://cdn.iubenda.com/iubenda.js'\n      tag.parentNode.insertBefore(s, tag)\n    }\n    if (w.addEventListener) {\n      w.addEventListener('load', loader, false)\n    } else if (w.attachEvent) {\n      w.attachEvent('onload', loader)\n    } else {\n      w.onload = loader\n    }\n  })(window, document)\n</script>\n<script src='https://d17nz991552y2g.cloudfront.net/app/js/jqueryandencoder.ffa5afd5124fbedceea9.js'></script>\n</body>\n</html>\n"
  },
  {
    "path": "packages/web-bridge/public/manifest.json",
    "content": "{\n  \"short_name\": \"Loopring L2\",\n  \"name\": \"Loopring - Ethereum Layer2\",\n  \"icons\": [\n    {\n      \"src\": \"favicon.ico\",\n      \"sizes\": \"64x64 32x32 24x24 16x16\",\n      \"type\": \"image/x-icon\"\n    }\n  ],\n  \"start_url\": \".\",\n  \"display\": \"standalone\",\n  \"theme_color\": \"#000000\",\n  \"background_color\": \"#ffffff\"\n}\n"
  },
  {
    "path": "packages/web-bridge/public/robots.txt",
    "content": "# https://www.robotstxt.org/robotstxt.html\nUser-agent: *\nDisallow:\n"
  },
  {
    "path": "packages/web-bridge/src/App.tsx",
    "content": "// import { ModalProvider } from 'styled-react-modal'\nimport RouterView from './routers'\nimport { GlobalStyles } from '@mui/material'\nimport { css, Theme, useTheme } from '@emotion/react'\nimport { globalCss, SagaStatus } from '@loopring-web/common-resources'\nimport { setLanguage } from '@loopring-web/component-lib'\nimport { useInit } from './hook'\nimport React from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { HashRouter as Router, useLocation } from 'react-router-dom'\nimport { store } from '@loopring-web/core'\n\nconst ScrollToTop = () => {\n  const { pathname } = useLocation()\n\n  React.useEffect(() => {\n    window.scrollTo(0, 0)\n  }, [pathname])\n\n  return null\n}\nconst App = () => {\n  const theme: Theme = useTheme()\n  const {\n    i18n: { language },\n  } = useTranslation()\n  const storeLan = store.getState().settings.language\n\n  React.useEffect(() => {\n    if (storeLan !== language) {\n      store.dispatch(setLanguage(language))\n    }\n  }, [storeLan, language])\n\n  React.useEffect(() => {\n    if (window.location.protocol !== 'https:') {\n      console.log('Current PROTOCOL::', window.location.protocol)\n      window.location.replace(\n        `https:${window.location.href.substring(window.location.protocol.length)}`,\n      )\n    }\n  }, [])\n\n  const { state } = useInit()\n\n  return (\n    <>\n      <GlobalStyles\n        styles={css`\n      ${globalCss({ theme })};\n\n      body {\n        ${\n          theme.mode === 'dark'\n            ? `\n            color: ${theme.colorBase.textPrimary};\n          `\n            : ``\n        }\n\n\n      }\n\n          body:before {\n            ${\n              theme.mode === 'dark'\n                ? `\n            background: var(--color-global-bg);\n       `\n                : ''\n            }\n      }\n    }`}\n      />\n\n      <Router>\n        <ScrollToTop />\n        <RouterView state={state as SagaStatus} />\n      </Router>\n    </>\n  )\n}\n\nexport default App\n\n"
  },
  {
    "path": "packages/web-bridge/src/hook.ts",
    "content": "import React from 'react'\nimport {\n  layer1Store,\n  useAccount,\n  useInjectWeb3Modal,\n  useSocket,\n  useSystem,\n  useTokenMap,\n  useTokenPrices,\n} from '@loopring-web/core'\nimport { ChainId } from '@loopring-web/loopring-sdk'\nimport { myLog, SagaStatus, ThemeType } from '@loopring-web/common-resources'\nimport {\n  ConnectProviders,\n  ConnectProvides,\n  connectProvides,\n  walletServices,\n} from '@loopring-web/web3-provider'\nimport { useAccountInit } from './hookAccountInit'\nimport { useSettings } from '@loopring-web/component-lib'\nimport { useTheme } from '@emotion/react'\n\n/**\n * @description\n * @step1 subscribe Connect hook\n * @step2 check the session storage ? choose the provider : none provider\n * @step3 decide china ID by step2\n * @step4 prepare the static date (tokenMap, ammMap, faitPrice, gasPrice, Activities ...)\n * @step5 launch the page\n */\n\nexport function useInit() {\n  const [, search] = window.location?.hash.split('?') ?? []\n  const query = new URLSearchParams(search)\n  const [, pathname1] = window.location.hash.match(/#\\/([\\w\\d\\-]+)\\??/) ?? []\n  const isNoServer: boolean =\n    query.has('noheader') && ['notification', 'document'].includes(pathname1)\n  const [state, setState] = React.useState<keyof typeof SagaStatus>(() => {\n    if (isNoServer) {\n      return SagaStatus.DONE\n    } else {\n      return SagaStatus.PENDING\n    }\n  })\n  const { isMobile, defaultNetwork } = useSettings()\n  const theme = useTheme()\n\n  const {\n    account,\n    updateAccount,\n    resetAccount,\n    status: accountStatus,\n    statusUnset: accountStatusUnset,\n  } = useAccount()\n  const { status: tokenMapStatus, statusUnset: tokenMapStatusUnset } = useTokenMap()\n  const { status: tokenPricesStatus, statusUnset: tokenPricesUnset } = useTokenPrices()\n\n  const { updateSystem, status: systemStatus, statusUnset: systemStatusUnset } = useSystem()\n\n  const { status: socketStatus, statusUnset: socketUnset } = useSocket()\n  const { circleUpdateLayer1ActionHistory } = layer1Store.useLayer1Store()\n\n  React.useEffect(() => {\n    ConnectProvides.walletConnectClientMeta = {\n      ...ConnectProvides.walletConnectClientMeta,\n      url:\n        process?.env?.REACT_APP_WALLETCONNECTCLIENTMETA_URL ??\n        ConnectProvides.walletConnectClientMeta.url,\n      name:\n        process?.env?.REACT_APP_WALLETCONNECTCLIENTMETA_NAME ??\n        ConnectProvides.walletConnectClientMeta.name,\n      description:\n        process?.env?.REACT_APP_WALLETCONNECTCLIENTMETA_DESCRIPTION ??\n        ConnectProvides.walletConnectClientMeta.description,\n    }\n    ;(async (account) => {\n      if (\n        account.accAddress !== ''\n      ) {\n        try {\n          ConnectProvides.IsMobile = isMobile\n          await connectProvides[account.connectName]({\n            account: account.accAddress,\n            darkMode: theme.mode === ThemeType.dark,\n            chainId: defaultNetwork.toString(),\n          })\n          updateAccount({})\n          if (connectProvides.usedProvide && connectProvides.usedWeb3) {\n            let chainId =\n              // @ts-ignore\n              Number(connectProvides.usedProvide?.connection?.chainId) ??\n              Number(await connectProvides.usedWeb3.eth.getChainId())\n            if (ChainId[chainId] === undefined) {\n              chainId =\n                account._chainId && account._chainId !== 'unknown'\n                  ? account._chainId\n                  : ChainId.MAINNET\n            }\n            circleUpdateLayer1ActionHistory({ chainId })\n\n            if (!isNoServer) {\n              updateSystem({ chainId: chainId as any })\n            }\n            return\n          }\n        } catch (error: any) {\n          walletServices.sendDisconnect('', `error at init loading  ${error}, disconnect`)\n          const chainId =\n            account._chainId && account._chainId !== 'unknown' ? account._chainId : ChainId.MAINNET\n          if (!isNoServer) {\n            updateSystem({ chainId })\n          }\n        }\n      } else {\n        if (account.accAddress === '') {\n          resetAccount()\n        }\n        const chainId =\n          account._chainId && account._chainId !== 'unknown' ? account._chainId : ChainId.MAINNET\n        if (!isNoServer) {\n          updateSystem({ chainId })\n        }\n      }\n    })(account)\n  }, [])\n  React.useEffect(() => {\n    switch (accountStatus) {\n      case SagaStatus.ERROR:\n        accountStatusUnset()\n        setState('ERROR')\n        break\n      case SagaStatus.DONE:\n        accountStatusUnset()\n        break\n      default:\n        break\n    }\n  }, [accountStatus])\n  React.useEffect(() => {\n    switch (systemStatus) {\n      case SagaStatus.PENDING:\n        if (!query.has('noheader') && state !== SagaStatus.PENDING) {\n          setState(SagaStatus.PENDING)\n        }\n        break\n      case SagaStatus.ERROR:\n        systemStatusUnset()\n        setState('ERROR')\n        break\n      case SagaStatus.DONE:\n        systemStatusUnset()\n        break\n      default:\n        break\n    }\n  }, [systemStatus])\n\n  React.useEffect(() => {\n    switch (tokenMapStatus) {\n      case SagaStatus.ERROR:\n        tokenMapStatusUnset()\n        setState('ERROR')\n        break\n      case SagaStatus.DONE:\n        tokenMapStatusUnset()\n        break\n      default:\n        break\n    }\n  }, [tokenMapStatus])\n\n  React.useEffect(() => {\n    switch (tokenPricesStatus) {\n      case SagaStatus.ERROR:\n        tokenPricesUnset()\n        setState('ERROR')\n        break\n      case SagaStatus.DONE:\n        tokenPricesUnset()\n        break\n      default:\n        break\n    }\n  }, [tokenPricesStatus])\n  React.useEffect(() => {\n    switch (socketStatus) {\n      case 'ERROR':\n        socketUnset()\n        break\n      case 'DONE':\n        socketUnset()\n        break\n      default:\n        break\n    }\n  }, [socketStatus])\n\n  useAccountInit({ state })\n  useInjectWeb3Modal('BRIDGE')\n  return {\n    state,\n  }\n}\n"
  },
  {
    "path": "packages/web-bridge/src/hookAccountInit.ts",
    "content": "import React from 'react'\nimport { AccountStatus, myLog, SagaStatus } from '@loopring-web/common-resources'\nimport { useAccount, useConnect, useWalletLayer1 } from '@loopring-web/core'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nexport function useAccountInit({ state }: { state: keyof typeof SagaStatus }) {\n  useConnect({ state })\n  const {\n    updateWalletLayer1,\n    status: walletLayer1Status,\n    statusUnset: wallet1statusUnset,\n  } = useWalletLayer1()\n  const { account, status: accountStatus, updateAccount } = useAccount()\n\n  const callBack = React.useCallback(async () => {\n    switch (account.readyState) {\n      case AccountStatus.DEPOSITING:\n      case AccountStatus.NOT_ACTIVE:\n      case AccountStatus.LOCKED:\n      case AccountStatus.NO_ACCOUNT:\n      case AccountStatus.ACTIVATED:\n        if (walletLayer1Status !== SagaStatus.PENDING) {\n          updateWalletLayer1()\n          myLog('updateWalletLayer1')\n        } else {\n          wallet1statusUnset()\n          sdk.sleep(10)\n          updateWalletLayer1()\n        }\n        break\n      case AccountStatus.UN_CONNECT:\n      case AccountStatus.ERROR_NETWORK:\n        break\n    }\n  }, [account.readyState, accountStatus, updateAccount, updateWalletLayer1, walletLayer1Status])\n  React.useEffect(() => {\n    if (accountStatus === SagaStatus.UNSET && state === SagaStatus.DONE) {\n      callBack()\n    }\n  }, [accountStatus, state])\n  React.useEffect(() => {\n    switch (walletLayer1Status) {\n      case SagaStatus.ERROR:\n        wallet1statusUnset()\n        break\n      case SagaStatus.DONE:\n        wallet1statusUnset()\n        break\n      default:\n        break\n    }\n  }, [walletLayer1Status])\n}\n"
  },
  {
    "path": "packages/web-bridge/src/index.tsx",
    "content": "import { Provider } from 'react-redux'\nimport App from './App'\nimport reportWebVitals from './reportWebVitals'\nimport { firebaseProps, persistor, store, TimeoutCheckProvider } from '@loopring-web/core'\nimport { getTheme, i18n } from '@loopring-web/common-resources'\nimport { ThemeProvider as MuThemeProvider } from '@mui/material'\nimport { LocalizationProvider } from '@mui/lab'\nimport MomentUtils from '@mui/lab/AdapterMoment'\n\nimport { ThemeProvider } from '@emotion/react'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { I18nextProvider } from 'react-i18next'\nimport { PersistGate } from 'redux-persist/integration/react'\nimport { provider, ProviderComposer, useSettings } from '@loopring-web/component-lib'\nimport React, { Provider as TProvider } from 'react'\nimport { ReactReduxFirebaseProvider } from 'react-redux-firebase'\nimport { createRoot } from 'react-dom/client'\n\nif (process.env.REACT_APP_VER) {\n  console.log('VER:', process.env.REACT_APP_VER)\n}\n// @ts-ignore\nwindow.global = window;\nconst ProviderApp = React.memo(({ children }: { children: JSX.Element }) => {\n  const providers: Array<[TProvider<any>, any]> = [\n    provider(Provider as any, { store }),\n    provider(LocalizationProvider as any, { dateAdapter: MomentUtils }),\n    provider(I18nextProvider as any, { i18n: i18n }),\n  ] as any\n  return <ProviderComposer providers={providers}>{children}</ProviderComposer>\n})\nconst ProviderThen = React.memo(({ children }: { children: JSX.Element }) => {\n  const { themeMode, setIsMobile } = useSettings()\n  const isMobile = sdk.IsMobile.any() ? true : false\n  setIsMobile(isMobile)\n  const providers: Array<[TProvider<any>, any]> = [\n    provider(MuThemeProvider as any, { theme: getTheme(themeMode, isMobile) }),\n    provider(ThemeProvider as any, { theme: getTheme(themeMode, isMobile) }),\n    provider(PersistGate as any, { persistor, loading: null }),\n    provider(TimeoutCheckProvider as any),\n  ] as any\n  return <ProviderComposer providers={providers}>{children}</ProviderComposer>\n})\n\nconst root = createRoot(document.getElementById('root') as HTMLElement)\nroot.render(\n  <ProviderApp>\n    <ReactReduxFirebaseProvider {...firebaseProps}>\n      <ProviderThen>\n        <App />\n      </ProviderThen>\n    </ReactReduxFirebaseProvider>\n  </ProviderApp>,\n)\n\n// If you want to start measuring performance in your app, pass a function\n// to log results (for example: reportWebVitals(console.log))\n// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals\n\nif (process.env.NODE_ENV !== 'production') {\n  reportWebVitals(console.log)\n}\n"
  },
  {
    "path": "packages/web-bridge/src/layouts/footer/index.tsx",
    "content": "import React from 'react'\nimport { FOOTER_LIST_MAP, MEDIA_LIST } from '@loopring-web/common-resources'\nimport { Footer as FooterUI } from '@loopring-web/component-lib'\nimport _ from 'lodash'\n\nconst linkListMap = _.cloneDeep(FOOTER_LIST_MAP)\nconst mediaList = _.cloneDeep(MEDIA_LIST)\nexport const Footer = () => {\n  return (\n    <FooterUI\n      isBeta={false}\n      isLandingPage={false}\n      linkListMap={linkListMap}\n      mediaList={mediaList}\n    />\n  )\n}\n"
  },
  {
    "path": "packages/web-bridge/src/layouts/header/hook.tsx",
    "content": "import React from 'react'\n\nimport {\n  ButtonComponentsMap,\n  fnType,\n  headerMenuLandingData,\n  headerToolBarData as _initHeaderToolBarData,\n  myLog,\n} from '@loopring-web/common-resources'\n\nimport {\n  accountReducer,\n  accountStaticCallBack,\n  btnClickMap,\n  store,\n  useAccount,\n  useNotify,\n  useSelectNetwork,\n} from '@loopring-web/core'\n\nimport { AccountStep, useOpenModals } from '@loopring-web/component-lib'\n\nimport _ from 'lodash'\n\nexport const useHeader = () => {\n  const accountTotal = useAccount()\n  const { account, setShouldShow, status: accountStatus } = accountTotal\n  const { setShowAccount } = useOpenModals()\n  const accountState = React.useMemo(() => {\n    return { account }\n  }, [account])\n  const { NetWorkItems } = useSelectNetwork({ className: 'header' })\n\n  const [headerToolBarData, setHeaderToolBarData] =\n    React.useState<typeof _initHeaderToolBarData>(_initHeaderToolBarData)\n  const _btnClickMap = Object.assign(_.cloneDeep(btnClickMap), {\n    [fnType.ACTIVATED]: [\n      function () {\n        store.dispatch(accountReducer.changeShowModel({ _userOnModel: true }))\n        store.dispatch(setShowAccount({ isShow: true, step: AccountStep.HadAccount }))\n      },\n    ],\n    [fnType.LOCKED]: [\n      function () {\n        store.dispatch(accountReducer.changeShowModel({ _userOnModel: true }))\n        store.dispatch(setShowAccount({ isShow: true, step: AccountStep.HadAccount }))\n      },\n    ],\n  })\n\n  const onWalletBtnConnect = React.useCallback(async () => {\n    myLog(`onWalletBtnConnect click: ${account.readyState}`)\n    accountStaticCallBack(_btnClickMap, [])\n  }, [account, setShouldShow, _btnClickMap])\n  React.useEffect(() => {\n    setHeaderToolBarData((headerToolBarData) => {\n      headerToolBarData[ButtonComponentsMap.WalletConnect] = {\n        ...headerToolBarData[ButtonComponentsMap.WalletConnect],\n        handleClick: onWalletBtnConnect,\n        NetWorkItems,\n        accountState: { account },\n      }\n      headerToolBarData[ButtonComponentsMap.WalletConnect] = {\n        ...headerToolBarData[ButtonComponentsMap.WalletConnect],\n        accountState,\n        handleClick: onWalletBtnConnect,\n      }\n      return headerToolBarData\n      // return {\n      //   ...headerToolBarData,\n      //   // [ButtonComponentsMap.Notification]: {\n      //   //   ...headerToolBarData[ButtonComponentsMap.Notification],\n      //   // },\n      //   [ButtonComponentsMap.WalletConnect]: {\n      //     ...headerToolBarData[ButtonComponentsMap.WalletConnect],\n      //     accountState,\n      //     handleClick: onWalletBtnConnect,\n      //   },\n      // } as HeaderToolBarInterface[];\n    })\n  }, [])\n\n  React.useEffect(() => {\n    if (accountStatus && accountStatus === 'UNSET') {\n      setHeaderToolBarData((headerToolBarData) => {\n        headerToolBarData[ButtonComponentsMap.WalletConnect] = {\n          ...headerToolBarData[ButtonComponentsMap.WalletConnect],\n          accountState,\n          NetWorkItems,\n          handleClick: onWalletBtnConnect,\n        }\n        return headerToolBarData\n      })\n    }\n    // forceUpdate()\n  }, [accountStatus, account.readyState])\n  const { notifyMap } = useNotify()\n\n  return {\n    headerToolBarData,\n    headerMenuLandingData,\n    account,\n    notifyMap,\n  }\n}\n"
  },
  {
    "path": "packages/web-bridge/src/layouts/header/index.tsx",
    "content": "import { headerRoot } from '@loopring-web/common-resources'\n\nimport { Toolbar } from '@mui/material'\n\nimport { useHeader } from './hook'\nimport { confirmation, useAccount, useSystem } from '@loopring-web/core'\nimport { withTranslation } from 'react-i18next'\n\nimport {\n  BottomRule,\n  Header as HeaderUI,\n  HideOnScroll,\n  useSettings,\n} from '@loopring-web/component-lib'\nimport { useLocation, withRouter } from 'react-router-dom'\nimport { RouteComponentProps } from 'react-router'\nimport React from 'react'\n\nconst Header = withTranslation('common')(\n  withRouter(({ t, location, ...rest }: any & RouteComponentProps) => {\n    const { headerToolBarData, notifyMap, headerMenuLandingData } = useHeader()\n    const { isMobile } = useSettings()\n    const { pathname } = useLocation()\n    const { confirmWrapper } = confirmation.useConfirmation()\n    const { allowTrade, chainId } = useSystem()\n    const { account } = useAccount()\n    return (\n      <>\n        <HideOnScroll window={undefined}>\n          <HeaderUI\n            account={account}\n            isWrap={false}\n            {...rest}\n            chainId={chainId}\n            isLandPage={true}\n            isMobile={isMobile}\n            allowTrade={allowTrade}\n            headerMenuData={headerMenuLandingData}\n            headerToolBarData={{}}\n            notification={notifyMap}\n            selected={location.pathname === '/' ? headerRoot : location.pathname}\n            application={'web-bridge'}\n          />\n        </HideOnScroll>\n        <Toolbar id='back-to-top-anchor' />\n        {/* <BottomRule isShow={!confirmation?.confirmed} */}\n        <BottomRule\n          isShow={false}\n          content={t('labelAgreeLoopringTxt')}\n          btnTxt={t('labelCookiesAgree')}\n          clickToConfirm={() => confirmWrapper()}\n        />\n      </>\n    )\n  }),\n)\n\nexport default Header\n"
  },
  {
    "path": "packages/web-bridge/src/pages/DepositPage/index.tsx",
    "content": "import { WithTranslation, withTranslation } from 'react-i18next'\nimport React from 'react'\nimport {\n  AccountStatus,\n  Exchange,\n  fnType,\n  L1L2_NAME_DEFINED,\n  LoopringIcon,\n  MapChainId,\n  myLog,\n  SagaStatus,\n  TradeBtnStatus,\n} from '@loopring-web/common-resources'\nimport {\n  boxLiner,\n  BtnInfo,\n  DepositPanel,\n  DepositProps,\n  SwitchPanelStyled,\n  useSettings,\n  WalletConnectL1Btn,\n} from '@loopring-web/component-lib'\nimport {\n  accountStaticCallBack,\n  btnClickMap,\n  btnConnectL1kMap,\n  useAccount,\n  useSelectNetwork,\n} from '@loopring-web/core'\nimport { Box, Link, Typography } from '@mui/material'\nimport styled from '@emotion/styled'\nimport _ from 'lodash'\n\nconst BoxStyle = styled(Box)`\n  max-height: var(--swap-box-height);\n  width: var(--modal-width);\n\n  & > div > div {\n    width: 100%;\n  }\n\n  &.mobile {\n    width: calc(var(--modal-width) + 20px);\n  }\n\n  .MuiToolbar-root {\n    margin-top: -24px !important;\n  }\n\n  min-height: 320px;\n  ${({ theme }) => boxLiner({ theme })};\n\n  .depositTitle {\n    font-size: ${({ theme }) => theme.fontDefault.h4};\n  }\n` as typeof SwitchPanelStyled\nconst BoxWrap = styled(Box)`\n  .MuiOutlinedInput-root.header {\n    background: none;\n  }\n`\nexport const DepositToPage = withTranslation(['common'])(\n  ({ t, depositProps }: { depositProps: DepositProps<any, any> } & WithTranslation) => {\n    const { isMobile, defaultNetwork } = useSettings()\n    const { NetWorkItems } = useSelectNetwork({ className: 'header' })\n\n    const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n    const [_depositBtnI18nKey, setDepositBtnI18nKey] = React.useState<BtnInfo | undefined>(\n      undefined,\n    )\n    const [_depositBtnStatus, setDepositBtnStatus] = React.useState(TradeBtnStatus.AVAILABLE)\n    const { account, status: accountStatus } = useAccount()\n    const { onDepositClick, btnInfo, depositBtnStatus, ...restProps } = depositProps\n    const depositBtnCallback = () => {\n      setDepositBtnStatus(depositBtnStatus as TradeBtnStatus)\n      return btnInfo\n    }\n    const onWalletBtnConnectClick = React.useCallback(async () => {\n      // myLog(`onWalletBtnConnect click: ${account.readyState}`)\n      accountStaticCallBack(btnConnectL1kMap)\n    }, [])\n    React.useEffect(() => {\n      if (accountStatus === SagaStatus.UNSET) {\n        setDepositBtnI18nKey(\n          accountStaticCallBack({\n            [fnType.ACTIVATED]: [depositBtnCallback],\n            [fnType.LOCKED]: [depositBtnCallback],\n            [fnType.NO_ACCOUNT]: [depositBtnCallback],\n            [fnType.NOT_ACTIVE]: [depositBtnCallback],\n            [fnType.DEPOSITING]: [depositBtnCallback],\n            [fnType.UN_CONNECT]: [\n              function () {\n                setDepositBtnStatus(TradeBtnStatus.AVAILABLE)\n                return { label: `labelConnectWallet` }\n              },\n            ],\n            [fnType.ERROR_NETWORK]: [\n              function () {\n                setDepositBtnStatus(TradeBtnStatus.DISABLED)\n                return { label: `labelWrongNetwork` }\n              },\n            ],\n          } as any),\n        )\n      }\n    }, [accountStatus, btnInfo, depositBtnStatus])\n    const _onDepositClick = React.useCallback(\n      (data: any) => {\n        accountStaticCallBack(\n          Object.assign(_.cloneDeep(btnClickMap), {\n            [fnType.ACTIVATED]: [onDepositClick],\n            [fnType.LOCKED]: [onDepositClick],\n            [fnType.NO_ACCOUNT]: [onDepositClick],\n            [fnType.NOT_ACTIVE]: [onDepositClick],\n            [fnType.DEPOSITING]: [onDepositClick],\n          }),\n          [data],\n        )\n      },\n      [onDepositClick],\n    )\n    return (\n      <Box\n        flex={1}\n        display={'flex'}\n        justifyContent={'center'}\n        flexDirection={'column'}\n        alignItems={'center'}\n      >\n        <Box\n          display={'flex'}\n          marginBottom={5 / 2}\n          width={`calc(var(--modal-width) + ${isMobile ? 20 : 0}px)`}\n          justifyContent={'space-between'}\n          alignItems={'center'}\n        >\n          <Link href={Exchange?.toString() ?? ''}>\n            <LoopringIcon\n              htmlColor={'var(--color-primary)'}\n              style={{ height: '40px', width: '120px', marginTop: -10 }}\n            />\n          </Link>\n\n          <Box\n            display={'flex'}\n            alignItems={'flex-end'}\n            flexDirection={'column'}\n            justifyContent={'center'}\n          >\n            {account.readyState !== AccountStatus.UN_CONNECT && (\n              <Typography color={'var(--color-text-secondary)'} marginBottom={1 / 4}>\n                {t('labelPayer')}\n              </Typography>\n            )}\n            <BoxWrap display={'flex'} alignItems={'center'}>\n              <WalletConnectL1Btn\n                NetWorkItems={NetWorkItems}\n                accountState={{ account } as any}\n                handleClick={onWalletBtnConnectClick}\n                isShowOnUnConnect={false}\n              />\n            </BoxWrap>\n          </Box>\n        </Box>\n        <BoxStyle\n          display={'flex'}\n          flexDirection={'column'}\n          paddingY={isMobile ? 2 : undefined}\n          paddingTop={5 / 2}\n          className={isMobile ? 'mobile' : ''}\n        >\n          <Box marginTop={-3} display={'flex'} flex={1} flexDirection={'column'}>\n            <DepositPanel\n              {...restProps}\n              isHideDes={account.readyState === AccountStatus.UN_CONNECT}\n              title={t(\n                account.readyState === AccountStatus.UN_CONNECT\n                  ? 'labelL1toL2TitleBridgeNoConnect'\n                  : 'labelL1toL2TitleBridge',\n                {\n                  loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                  l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                  l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                  ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                  loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n                },\n              )}\n              accountReady={account?.readyState as any}\n              btnInfo={_depositBtnI18nKey}\n              depositBtnStatus={_depositBtnStatus}\n              onDepositClick={_onDepositClick}\n              isNewAccount={false}\n            />\n          </Box>\n        </BoxStyle>\n      </Box>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/web-bridge/src/pages/ErrorPage/index.tsx",
    "content": "import { Trans, useTranslation } from 'react-i18next'\nimport { Box, Container, Link, Typography } from '@mui/material'\nimport styled from '@emotion/styled'\nimport { ErrorObject, SoursURL } from '@loopring-web/common-resources'\nimport { getContactInfo } from '@loopring-web/core'\n\nconst StyleBox = styled(Box)`\n  background-image: url('${SoursURL}/images/error_bg.png');\n  background-repeat: no-repeat;\n  background-size: contain;\n  background-position: bottom;\n  white-space: pre-wrap;\n` as typeof Box\n\nexport const ErrorPage = ({ messageKey }: ErrorObject) => {\n  const { t } = useTranslation('error')\n  const message = `labelConnectUs`\n  return (\n    <>\n      <Container style={{ flex: 1, display: 'flex' }}>\n        {/*style={{height: '100%' }}*/}\n        <StyleBox\n          flex={1}\n          display={'flex'}\n          alignItems={'flex-start'}\n          justifyContent={'center'}\n          flexDirection={'column'}\n          marginTop={4}\n          height={680}\n          maxWidth={1200}\n        >\n          {/*<StyleBox>*/}\n          <Box textAlign={'center'} position={'relative'} left={128} top={-64}>\n            <Typography component={'h2'} variant={'h3'} whiteSpace={'pre-line'}>\n              {t(messageKey)}\n            </Typography>\n            <Typography\n              marginY={2}\n              component={'p'}\n              variant={'body1'}\n              color={'textSecondary'}\n              whiteSpace={'pre-line'}\n            >\n              <Trans i18nKey={message} ns={'error'}>\n                If you believe this is indeed a bug, please\n                <Link\n                  component={'a'}\n                  sx={{\n                    display: 'inline-flex',\n                  }}\n                  onClick={(e) => {\n                    window.open(getContactInfo(), '_blank')\n                    window.opener = null\n                    e.preventDefault()\n                  }}\n                >\n                  &nbsp; contact us\n                </Link>\n                <br /> We would appreciate your feedback\n              </Trans>\n            </Typography>\n          </Box>\n        </StyleBox>\n      </Container>\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/web-bridge/src/pages/LoadingPage/index.tsx",
    "content": "import { useTranslation } from 'react-i18next'\nimport { Box } from '@mui/material'\nimport styled from '@emotion/styled'\n// import { ErrorObject } from '@loopring-web/common-resources';\n// import { getContactInfo } from '../../utils/dt_tools';\nimport { boxLiner } from '@loopring-web/component-lib'\nimport { SoursURL } from '@loopring-web/common-resources'\nimport React from 'react'\n// ${({theme}) => boxLiner({theme})}\nconst StyleBox = styled(Box)`\n  ${({ theme }) => boxLiner({ theme })}\n\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  left: 0;\n  right: 0;\n  width: 0;\n  z-index: 500;\n  height: 100%;\n  width: 100%;\n  svg path,\n  svg rect {\n    fill: var(--color-primary);\n  }\n` as typeof Box\nconst StyleBlock = styled(Box)`\n  background: var(--color-global-bg);\n  svg path,\n  svg rect {\n    fill: var(--color-primary);\n  }\n` as typeof Box\n\nexport const LoadingPage = () => {\n  const { t } = useTranslation('layout')\n  return (\n    <>\n      {/*<Container>*/}\n      {/*style={{height: '100%' }}*/}\n      <StyleBox\n        flex={1}\n        display={'flex'}\n        alignItems={'center'}\n        justifyContent={'center'}\n        flexDirection={'column'}\n        height={'100%'}\n        width={'100%'}\n      >\n        <div className='loader loader--style3' title='2'>\n          <img\n            className='loading-gif'\n            alt={'loading'}\n            width='36'\n            src={`${SoursURL}images/loading-line.gif`}\n          />\n        </div>\n      </StyleBox>\n    </>\n  )\n}\nexport const LoadingBlock = () => {\n  const { t } = useTranslation('layout')\n  return (\n    <>\n      {/*<Container>*/}\n      {/*style={{height: '100%' }}*/}\n      <StyleBlock\n        flex={1}\n        display={'flex'}\n        alignItems={'center'}\n        justifyContent={'center'}\n        flexDirection={'column'}\n        height={'100%'}\n        width={'100%'}\n      >\n        <div className='loader loader--style3' title='2'>\n          <img\n            className='loading-gif'\n            alt={'loading'}\n            width='36'\n            src={`${SoursURL}images/loading-line.gif`}\n          />\n        </div>\n      </StyleBlock>\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/web-bridge/src/react-app-env.d.ts",
    "content": "/// <reference types=\"react-scripts\" />\n// window.__loopringEnv__ = process.env;\n"
  },
  {
    "path": "packages/web-bridge/src/reportWebVitals.ts",
    "content": "import { ReportHandler } from 'web-vitals'\n\nconst reportWebVitals = (onPerfEntry?: ReportHandler) => {\n  if (onPerfEntry && onPerfEntry instanceof Function) {\n    import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {\n      getCLS(onPerfEntry)\n      getFID(onPerfEntry)\n      getFCP(onPerfEntry)\n      getLCP(onPerfEntry)\n      getTTFB(onPerfEntry)\n    })\n  }\n}\n\nexport default reportWebVitals\n"
  },
  {
    "path": "packages/web-bridge/src/routers/index.tsx",
    "content": "import { Route, Switch, useLocation } from 'react-router-dom'\nimport React from 'react'\nimport { Box, Container } from '@mui/material'\nimport { ModalGroup, useDeposit } from '@loopring-web/core'\nimport { LoadingPage } from '../pages/LoadingPage'\nimport { SagaStatus, setMyLog, ThemeType } from '@loopring-web/common-resources'\nimport { ErrorPage } from '../pages/ErrorPage'\nimport { useSettings } from '@loopring-web/component-lib'\nimport { DepositToPage } from '../pages/DepositPage'\nimport { Footer } from '../layouts/footer'\n\nexport const useWrapModal = () => {\n  const { search } = useLocation()\n  const searchParams = new URLSearchParams(search)\n  const token = searchParams.get('token')\n  const l2account = searchParams.get('l2account') || searchParams.get('owner')\n  const { depositProps } = useDeposit(true, { token, owner: l2account })\n  return {\n    depositProps,\n    view: <ModalGroup assetsRawData={[]} depositProps={depositProps} isLayer1Only={true} />,\n  }\n}\nconst RouterView = ({ state }: { state: SagaStatus }) => {\n  const location = useLocation()\n  const { setTheme } = useSettings()\n  const { depositProps, view: modalView } = useWrapModal()\n  // const { depositProps } = useDeposit(true, { token, owner });\n  const searchParams = new URLSearchParams(location.search)\n  React.useEffect(() => {\n    if (searchParams.has('theme')) {\n      searchParams.get('theme') === ThemeType.dark ? setTheme('dark') : setTheme('light')\n    }\n  }, [location.search])\n  React.useEffect(() => {\n    if (state === SagaStatus.ERROR) {\n      window.location.replace(`${window.location.origin}/error`)\n    }\n  }, [state])\n  if (searchParams.has('___OhTrustDebugger___')) {\n    // @ts-ignore\n    setMyLog(true)\n  }\n  return (\n    <>\n      <Switch>\n        <Route exact path='/loading'>\n          <LoadingPage />\n        </Route>\n        <Route exact path={['/', '/depositto', '/depositto/*']}>\n          {/*{searchParams && searchParams.has(\"noheader\") ? <></> : <Header />}*/}\n          <Container\n            maxWidth='lg'\n            style={{\n              display: 'flex',\n              flexDirection: 'column',\n              flex: 1,\n            }}\n          >\n            <Box\n              display={'flex'}\n              flex={1}\n              alignItems={'stretch'}\n              flexDirection={'row'}\n              marginTop={3}\n            >\n              <DepositToPage depositProps={depositProps} />\n            </Box>\n          </Container>\n        </Route>\n        <Route\n          component={() => (\n            <>\n              <ErrorPage messageKey={'error404'} />\n            </>\n          )}\n        />\n      </Switch>\n      {modalView}\n      {searchParams && searchParams.has('nofooter') ? <></> : <Footer />}\n    </>\n  )\n}\n\nexport default RouterView\n"
  },
  {
    "path": "packages/web-bridge/src/setupTests.ts",
    "content": "// jest-dom adds custom jest matchers for asserting on DOM nodes.\n// allows you to do things like:\n// expect(element).toHaveTextContent(/react/i)\n// learn more: https://github.com/testing-library/jest-dom\nimport '@testing-library/jest-dom'\n"
  },
  {
    "path": "packages/web-bridge/src/types.d.ts",
    "content": "import { RampInstantSDK } from '@ramp-network/ramp-instant-sdk'\nimport '@google/model-viewer'\nimport { ModelViewerElement } from '@google/model-viewer'\n\ndeclare module '*.html' {\n  const value: string\n  export default value\n}\n\ndeclare global {\n  interface Window {\n    loopringSocket: InstanceType<LoopringSocket>\n    __renderReportCall__: () => void\n    rampInstance: RampInstantSDK | undefined\n  }\n\n  namespace JSX {\n    interface IntrinsicElements {\n      'model-viewer': MyElementAttributes\n    }\n\n    interface MyElementAttributes {\n      src: string\n      'auto-rotate': any\n      'camera-controls': any\n      'ar-modes': any\n      'touch-action': any\n      'shadow-intensity': any\n      poster?: string\n\n      [key: string]: any\n    }\n  }\n}\n"
  },
  {
    "path": "packages/web-bridge/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.build.json\",\n  \"compilerOptions\": {\n    \"baseUrl\": \"src/\",\n    \"rootDir\": \".\"\n  },\n  \"include\": [\n    \"src\",\n    \"src/*\",\n    \"src/**/*.json\"\n  ]\n}\n"
  },
  {
    "path": "packages/web-developer/public/badge.xml",
    "content": "<FrameLayout xmlns:android=\"https://download.loopring.io/LoopringWallet.apk\"\n             xmlns:app=\"https://download.loopring.io/\"\n             android:layout_width=\"match_parent\"\n             android:layout_height=\"match_parent\">\n\n    <TextView\n            android:id=\"@+id/notifications.badge\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"top|center_horizontal\"\n            android:layout_marginLeft=\"10dp\"\n            android:layout_marginStart=\"10dp\"\n            android:background=\"@drawable/notification_badge\"\n            android:gravity=\"center\"\n            android:padding=\"3dp\"\n            android:text=\"9+\"\n            android:textColor=\"@color/white\"\n            android:textSize=\"11sp\"/>\n</FrameLayout>"
  },
  {
    "path": "packages/web-developer/public/browserconfig.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<browserconfig>\n    <msapplication>\n        <tile>\n            <!--            <square70x70logo src=\"small.png\"/>-->\n            <!--            <square150x150logo src=\"medium.png\"/>-->\n            <!--            <wide310x150logo src=\"wide.png\"/>-->\n            <!--            <square310x310logo src=\"large.png\"/>-->\n            <square129x129logo src=\"loopring129.png\"/>\n            <TileColor>#3B5AF4</TileColor>\n        </tile>\n        <badge>\n            <polling-uri src=\"badge.xml\"/>\n            <frequency>30</frequency>\n        </badge>\n        <!--        <notification>-->\n        <!--            <polling-uri  src=\"1.xml\"/>-->\n        <!--            <polling-uri2 src=\"2.xml\"/>-->\n        <!--            <polling-uri3 src=\"3.xml\"/>-->\n        <!--            <polling-uri4 src=\"4.xml\"/>-->\n        <!--            <polling-uri5 src=\"5.xml\"/>-->\n        <!--            <frequency>30</frequency>-->\n        <!--            <cycle>1</cycle>-->\n        <!--        </notification>-->\n    </msapplication>\n</browserconfig>"
  },
  {
    "path": "packages/web-developer/public/dark.css",
    "content": "@import 'reset.css';\n\nhtml {\n    --color-global-Bg: var(--dark);\n    --color-primary: #446eff;\n    --color-primary-hover: var(--light900);\n    --color-primary-pressed: #2d49b2;\n    --color-disable: #343754;\n    --color-text-primary: var(--light);\n    --color-border: var(--light900);\n    --color-divide: var(--dark800);\n    --color-border-hover: var(--color-primary);\n    --color-text-Secondary: var(--light500);\n    --color-text-third: var(--dark400);\n    --color-text-Button: var(--light);\n    --color-text-ButtonSelect: var(--light);\n    --color-text-Disable: var(--light) 45;\n    --color-box: var(--dark900);\n    --color-logo: var(--light);\n}\n"
  },
  {
    "path": "packages/web-developer/public/developer.css",
    "content": "@charset \"UTF-8\";\nbody {\n  background: var(--color-global-Bg);\n  font-family: Roboto, Helvetica, Arial, \"华文细黑\", \"Microsoft YaHei\", \"微软雅黑\", SimSun, \"宋体\", Heiti, \"黑体\", sans-serif;\n  user-drag: none;\n  user-select: none;\n}\n\nsvg {\n  fill: var(--color-text-primary);\n}\n\nbutton {\n  border: 1px solid var(--color-border);\n  border-radius: 2px;\n  box-sizing: border-box;\n}\nbutton:hover {\n  border: 1px solid var(--color-border-hover);\n}\n\n.Typography-root {\n  font-size: 14px;\n  color: var(--color-text-primary);\n}\n\n.Typography-h4 {\n  font-size: var(--h4);\n}\n\n.Typography-subtitle {\n  font-size: var(--subtitle);\n}\n\n.Typography-h1 {\n  font-size: var(--h1);\n}\n\n.Typography-h2 {\n  font-size: var(--h2);\n}\n\nheader .headerGg {\n  width: 100vw;\n}\nheader .Toolbar-root {\n  height: var(--header-height);\n  display: flex;\n  flex-direction: row;\n  justify-content: space-between;\n  align-items: center;\n}\nheader nav {\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n}\nheader nav ul {\n  margin-left: 24px;\n}\nheader nav ul li {\n  display: inline-block;\n  height: var(--header-height);\n  line-height: var(--header-height);\n  padding: 0 8px;\n}\n\n.flexBox {\n  display: flex;\n}\n\n.flex-column {\n  flex-direction: column;\n}\n\n.flex-row {\n  flex-direction: row;\n}\n\n.align-center {\n  align-items: center;\n}\n\n.stretch {\n  justify-content: stretch;\n}\n\n/* Rectangle 1662 */\n#labelNavLanuch {\n  /*width: 112px;*/\n  padding: 0 16px;\n  line-height: 36px;\n  height: 36px;\n  border-radius: 2px;\n  border: 0;\n  /*border: 1px solid;*/\n  /*border-image: linear-gradient(90deg, #D7B2FF 0%, #77AAFF 53.24%) 1;*/\n  color: var(--color-text-primary);\n  border-image-repeat: round;\n  position: relative;\n  z-index: 99;\n  box-sizing: border-box;\n}\n\n#labelNavLanuch:after {\n  top: 0;\n  left: 0;\n  right: 0;\n  bottom: 0;\n  position: absolute;\n  content: \"\";\n  border-radius: 2px;\n  z-index: -1;\n  border: 2px solid;\n  border-image: linear-gradient(224.95deg, #79FAAC -5.39%, #4F5AE4 96.95%) 1;\n}\n\n#logo {\n  min-width: auto;\n  border-radius: 0px;\n  text-indent: -999999em;\n  background: var(--color-logo);\n  -webkit-mask: url(https://static.loopring.io/assets/svg/logo.svg) center center/contain space;\n  width: 105px;\n  height: 40px;\n  padding: 8px;\n  color: transparent;\n  display: inline-flex;\n  align-items: center;\n  justify-content: center;\n  position: relative;\n  box-sizing: border-box;\n  outline: 0px;\n  border: 0px;\n  margin: -10px 0px 0px -12px;\n  cursor: pointer;\n}\n#logo::after {\n  content: \"beta\";\n  position: absolute;\n  color: var(--color-logo);\n  display: block;\n  font-size: 1rem;\n  line-height: 0.8rem;\n  right: -24px;\n  top: 14px;\n  font-weight: 200;\n  opacity: 0;\n  box-shadow: 0 0 1px 0 var(--color-logo);\n  border-radius: 2px;\n  padding: 3px 2px;\n}\n#logo svg {\n  fill: var(--color-text-Secondary);\n}\n\n/* identical to box height, or 129% */\n.Container-root,\n.wrap {\n  max-width: 1168px;\n  padding: 0 16px;\n  margin: 0 auto;\n}\n\na.Typography-root,\na.Typography-root:active,\na.Typography-root:visited,\n.Link-root,\n.Link-root:active,\n.Link-root:visited,\n.MenuItem-root a.Typography-root,\n.MenuItem-root a.Typography-root:active,\n.MenuItem-root a.Typography-root:visited,\n.Link-root {\n  color: var(--color-text-Secondary);\n}\n\na.Typography-root:hover,\n.MenuItem-root a.Typography-root:hover,\n.Link-root:hover {\n  color: var(--color-text-primary);\n}\n\n.Link-underlineAlways:hover {\n  text-decoration: underline;\n}\n\nbody {\n  display: flex;\n  flex-direction: column;\n  justify-content: flex-start;\n  height: 100%;\n}\n\n.sectionFull {\n  width: 100vw;\n  margin: 80px 0;\n}\n.sectionFull a {\n  display: inline-flex;\n  align-items: center;\n  color: var(--color-text-primary);\n}\n.sectionFull a:hover {\n  color: var(--color-primary);\n}\n.sectionFull a:hover svg {\n  fill: var(--color-primary);\n}\n.sectionFull button:hover {\n  border: 1px solid var(--color-border-hover);\n}\n.sectionFull button:hover svg {\n  fill: var(--color-border-hover);\n}\n.sectionFull .wrap:nth-child(even) {\n  flex-direction: row-reverse;\n}\n.sectionFull:nth-child(odd) .img-container {\n  display: flex;\n  justify-content: flex-end;\n}\n.sectionFull .wrap {\n  justify-content: space-between;\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n}\n\nh3.Typography-root {\n  font-size: var(--h1);\n}\n\nh3 ~ p.Typography-root {\n  color: var(--color-text-third);\n  font-size: var(--h5);\n}\n\n.cardBtnGroup {\n  justify-content: stretch;\n  margin-top: 80px;\n}\n.cardBtnGroup .wrap-svg {\n  padding: 16px;\n  border-radius: 50%;\n  background: var(--dark900);\n  margin-bottom: 24px;\n}\n.cardBtnGroup .wrap-svg svg {\n  height: 48px;\n  width: 48px;\n  fill: var(--color-text-Button);\n}\n.cardBtnGroup .des {\n  margin-top: 8px;\n  color: var(--color-text-third);\n}\n.cardBtnGroup button {\n  box-sizing: border-box;\n  width: 388px;\n  height: 285px;\n  background: var(--dark);\n  border: 1px solid var(--dark600);\n  border-radius: 8px;\n  margin: 0 12px;\n  padding: 0 24px;\n  justify-content: center;\n  align-items: center;\n}\n.cardBtnGroup button:hover {\n  border: 1px solid var(--color-border-hover);\n}\n.cardBtnGroup button:hover .wrap-svg {\n  background: var(--dark800);\n}\n\n.banner .right-part {\n  margin-left: 120px;\n  align-self: flex-end;\n}\n\n/* Ethereum Unleashed */\n#LoopringDeveloperBox {\n  height: 72px;\n  font-size: 64px;\n  line-height: 72px;\n  font-weight: 700;\n  margin-top: 184px;\n  margin-bottom: 16px;\n  display: inline-flex;\n  width: 50%;\n  align-items: flex-end;\n}\n\n#labelLoopring {\n  height: 72px;\n  width: fit-content;\n  background: linear-gradient(224.95deg, #79FAAC -5.39%, #4F5AE4 96.95%), linear-gradient(231.69deg, #79FAAC 39.53%, #4F5AE4 89.75%);\n  -webkit-background-clip: text;\n  -webkit-text-fill-color: transparent;\n  /*background-clip: text;*/\n  border-radius: 2px;\n  text-fill-color: transparent;\n  text-align: center;\n}\n\n#labelTitleDes {\n  line-height: 1.5em;\n  font-size: var(--h5);\n  text-align: left;\n  color: var(--dark400);\n}\n\nfooter {\n  flex: 1;\n  display: flex;\n  flex-direction: column;\n  justify-content: flex-end;\n}\nfooter .Container-root {\n  display: flex;\n  flex-direction: column;\n}\nfooter .content {\n  margin-top: 24px;\n}\nfooter .followUs {\n  width: 100%;\n  background: url(https://static.loopring.io/assets/images/landPage/docFooter.webp) no-repeat 50% 50%;\n  height: 367px;\n  background-size: cover;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  flex-direction: column;\n}\nfooter .followUs .footerContentList {\n  justify-content: center;\n}\nfooter .followUs .footerContentList ul {\n  width: 376px;\n  display: flex;\n  flex-direction: row;\n  justify-content: space-between;\n}\nfooter .followUs .footerContentList ul .icon svg {\n  font-size: var(--h5);\n  fill: var(--color-text-Secondary);\n  width: 40px;\n  height: 40px;\n}\nfooter .followUs .footerContentList ul a.icon:hover svg {\n  fill: var(--color-text-primary);\n}\nfooter .group {\n  padding-top: 16px;\n}\nfooter .group h6 {\n  font-size: var(--body2);\n  color: var(--color-text-third);\n  line-height: 4em;\n  padding-bottom: 8px;\n}\nfooter .group .Typography-root {\n  font-size: var(--body2);\n  line-height: 2em;\n}\nfooter .group #labelFollowus {\n  font-size: var(--h1);\n  color: var(--color-text-primary);\n}\n\n.Button-root {\n  cursor: pointer;\n}\n\n#labelCopyRight {\n  color: var(--color-text-third);\n  text-align: center;\n  height: 40px;\n  line-height: 40px;\n}\n\n.logoDex {\n  display: flex;\n  flex-direction: column;\n  justify-content: space-evenly;\n}\n\n.logoDex p:first-child {\n  color: var(--color-text-primary);\n  font-size: var(--h5);\n}\n\n.logoDex p:last-child {\n  color: var(--color-text-third);\n}\n\n.carousel-container {\n  --height: 596px;\n  --width: 280px;\n  --size-image: 0.8;\n  display: flex;\n  margin-top: 120px;\n  overflow: hidden;\n  width: 800px;\n  height: calc(var(--height) + 32px);\n  transform-style: preserve-3d;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  overflow: hidden;\n}\n.carousel-container .container {\n  height: 100%;\n  width: 100%;\n}\n.carousel-container #slider {\n  width: 100vw;\n  height: 100%;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n}\n.carousel-container input[type=radio] {\n  display: none;\n}\n.carousel-container .cards {\n  position: relative;\n  width: 100%;\n  height: 100%;\n}\n.carousel-container .card {\n  position: absolute;\n  top: 50%;\n  left: 50%;\n  margin-left: calc(var(--width) / -2);\n  margin-top: calc(var(--height) / -2);\n  cursor: pointer;\n  transition: transform 0.4s cubic-bezier(0.165, 0.84, 0.44, 1);\n}\n.carousel-container img {\n  width: var(--width);\n  object-fit: cover;\n}\n\n.sectionDetail {\n  width: 580px;\n  height: 492px;\n  min-width: 340px;\n  background: var(--dark);\n  border-radius: 8px;\n  display: flex;\n  flex-direction: column;\n  justify-content: center;\n}\n.sectionDetail h3 svg {\n  width: 36px;\n  height: 36px;\n}\n.sectionDetail .labelDocDes {\n  margin-top: 8px;\n  margin-bottom: 32px;\n  line-height: 1.2em;\n}\n.sectionDetail .learnMore {\n  margin-top: 32px;\n  line-height: 1.2em;\n  color: var(--color-text-primary);\n  align-items: center;\n  display: inline-flex;\n  flex-direction: row;\n}\n.sectionDetail ul {\n  width: 500px;\n}\n.sectionDetail ul li {\n  margin: 16px 0;\n  width: 100%;\n}\n.sectionDetail ul li button {\n  width: 100%;\n  height: 56px;\n  line-height: 1.8rem;\n  display: flex;\n  flex-direction: row;\n  color: var(--color-text-primary);\n  border: 1px solid var(--dark600);\n  border-radius: 8px;\n  padding: 0px 16px;\n  justify-content: space-between;\n  align-items: center;\n}\n.sectionDetail ul li button span {\n  display: inline-flex;\n  flex-direction: row;\n  align-items: center;\n  text-align: left;\n  line-height: 1.2em;\n}\n\n.img-container {\n  width: 50%;\n  min-width: 50%;\n  display: flex;\n  margin-top: 24px;\n  justify-content: center !important;\n}\n\n#bgContent {\n  position: absolute;\n  z-index: 1;\n  top: 0;\n  right: 0;\n  left: 0;\n  width: 100%;\n  height: 100vh;\n  overflow: hidden;\n  pointer-events: none;\n}\n#bgContent #bgAlphaBg {\n  position: absolute;\n  pointer-events: none;\n  transform: translate(0, -300px) rotate(0);\n  top: 0;\n  left: 0;\n  width: 100%;\n}\n#bgContent #bgAlpha {\n  position: absolute;\n  pointer-events: none;\n  transform: translate(12%, -40%) rotate(-13deg);\n}\n\n@media only screen and (max-width: 1024px) {\n  .Container-root,\n  .wrap {\n    width: 100vw;\n    padding: 0 16px;\n    margin: 0 auto;\n  }\n\n  .cardBtnGroup {\n    margin-top: 32px;\n  }\n\n  .carousel-container {\n    display: flex;\n    overflow: hidden;\n    align-items: center;\n    width: 100%;\n    align-items: center;\n    justify-content: center;\n    margin-top: 40px;\n  }\n\n  #logo {\n    min-width: auto;\n    /*border-radius: 0px;*/\n    /*text-indent: -999999em;*/\n    background: var(--color-logo);\n    -webkit-mask: url(https://static.loopring.io/assets/svg/loopring.svg) center center/contain space;\n    width: 40px;\n    height: 40px;\n    margin-left: 8px;\n  }\n\n  h3.Typography-root {\n    font-size: var(--h4);\n    text-align: center;\n  }\n\n  h3 ~ p.Typography-root {\n    font-size: var(--body);\n    white-space: initial;\n  }\n\n  header ul li:first-child {\n    display: none;\n  }\n\n  .downLoadBtnGroup {\n    flex-direction: column;\n    justify-content: space-between;\n    height: 192px;\n    margin-left: 0;\n  }\n\n  .downLoadBtnGroup button {\n    margin-left: 0;\n  }\n\n  footer .footerWallet .wrap {\n    flex-direction: column;\n    align-items: center;\n    justify-content: space-between;\n  }\n\n  footer .downLoadBtnGroup {\n    margin-top: 24px;\n  }\n\n  footer .content {\n    flex-direction: column;\n  }\n\n  footer .followUs .footerContentList ul {\n    width: 320px;\n  }\n\n  #LoopringDeveloperBox {\n    font-size: 36px;\n    margin-top: 32px;\n    width: 100%;\n  }\n\n  #logSvg {\n    display: none;\n  }\n\n  .sectionFull {\n    align-items: flex-start;\n    justify-content: center;\n    height: initial;\n    margin: 80px 0;\n  }\n\n  .sectionFull .wrap {\n    flex-direction: column-reverse !important;\n  }\n\n  .carousel-container {\n    --size-image: 0.5;\n  }\n\n  #bgContent #bgAlphaBg {\n    display: none;\n  }\n\n  #bgContent #bgAlpha {\n    position: absolute;\n    pointer-events: none;\n    transform: translate(-30%, -20%) rotate(13deg) scale(0.5);\n  }\n\n  .sectionDetail {\n    min-width: 340px;\n    height: 492px;\n    width: 100%;\n    max-width: 480px;\n  }\n\n  .sectionDetail ul {\n    min-width: 340px;\n    width: 100%;\n    max-width: 480px;\n  }\n\n  .banner {\n    flex-direction: column;\n    align-items: center;\n  }\n\n  .banner .right-part {\n    margin-left: 0px;\n    margin-top: 24px;\n    align-self: initial;\n  }\n\n  .cardBtnGroup {\n    margin-top: 32px;\n    flex-direction: column;\n    align-items: center;\n  }\n\n  .cardBtnGroup button {\n    margin: 8px;\n    max-width: 388px;\n    width: 100%;\n  }\n}\n.labelDocumentation {\n  --borderWidth: 3px;\n  background: var(--color-global-Bg);\n  position: relative;\n  display: inline-flex;\n  align-items: center;\n  padding: 8px;\n}\n.labelDocumentation:hover {\n  border: 0;\n  box-shadow: 0 5px 15px rgba(247, 149, 51, 0.0156862745), 0 10px 30px rgba(243, 112, 85, 0.0078431373);\n  animation: boxShow 3s ease alternate infinite;\n}\n.labelDocumentation:hover:after {\n  content: \"\";\n  position: absolute;\n  top: calc(-1 * var(--borderWidth));\n  left: calc(-1 * var(--borderWidth));\n  right: calc(-1 * var(--borderWidth));\n  bottom: calc(-1 * var(--borderWidth));\n  background: linear-gradient(60deg, #f79533, #f37055, #ef4e7b, #a166ab, #5073b8, #1098ad, #07b39b, #6fba82);\n  border-radius: calc(2 * var(--borderWidth));\n  z-index: -1;\n  animation: animatedgradient 3s ease alternate infinite;\n  background-size: 300% 300%;\n}\n\n@media only screen and (min-width: 768px) and (max-width: 1024px) {\n  #LoopringDeveloperBox {\n    width: 522px;\n    font-size: 56px;\n  }\n\n  .carousel-container {\n    --size-image: 0.7;\n    margin-top: 40px;\n  }\n\n  .cardBtnGroup {\n    margin-top: 32px;\n    flex-direction: column;\n    align-items: center;\n  }\n\n  .cardBtnGroup button {\n    margin: 8px;\n    width: 100%;\n  }\n\n  .banner {\n    flex-direction: column;\n    align-items: center;\n  }\n\n  .banner .right-part {\n    margin-left: 0px;\n    align-self: initial;\n  }\n\n  #labelTitleDes {\n    font-size: var(--h5);\n    text-align: center;\n  }\n\n  h3.Typography-root {\n    font-size: var(--h1);\n    margin: 80px 0 40px 0;\n  }\n\n  h3 ~ p.Typography-root {\n    color: var(--color-text-third);\n    font-size: var(--h5);\n  }\n\n  .banner {\n    flex-direction: column;\n    align-items: center;\n  }\n\n  .banner .right-part {\n    margin-left: 0px;\n    align-self: initial;\n  }\n}\n\n@keyframes boxShow {\n  0% {\n    box-shadow: 0 5px 15px rgba(247, 149, 51, 0.4), 0 10px 30px rgba(243, 112, 85, 0.2);\n  }\n  25% {\n    box-shadow: 0 5px 15px rgba(239, 78, 123, 0.4), 0 10px 30px rgba(161, 102, 171, 0.2);\n  }\n  50% {\n    box-shadow: 0 5px 15px rgba(80, 115, 184, 0.4), 0 10px 30px rgba(16, 152, 173, 0.2);\n  }\n  75% {\n    box-shadow: 0 5px 15px rgba(7, 179, 155, 0.4), 0 10px 30px rgba(111, 186, 130, 0.2);\n  }\n}\n\n@keyframes animatedgradient {\n  0% {\n    background-position: 0% 50%;\n  }\n  25% {\n    background-position: 25% 50%;\n  }\n  50% {\n    background-position: 50% 50%;\n  }\n  75% {\n    background-position: 75% 50%;\n  }\n}\n#changeColor {\n  margin-right: 24px;\n  border: 0;\n}\n\n.carousel-container #item-1:checked ~ .cards #selector-1,\n.carousel-container #item-2:checked ~ .cards #selector-2,\n.carousel-container #item-3:checked ~ .cards #selector-3 {\n  transform: translateX(0%) scale(1);\n  z-index: 80;\n}\n.carousel-container #item-1:checked ~ .cards #selector-3,\n.carousel-container #item-2:checked ~ .cards #selector-1,\n.carousel-container #item-3:checked ~ .cards #selector-2 {\n  transform: translateX(100%) scale(var(--size-image));\n  z-index: 70;\n}\n.carousel-container #item-1:checked ~ .cards #selector-2,\n.carousel-container #item-2:checked ~ .cards #selector-3,\n.carousel-container #item-3:checked ~ .cards #selector-1 {\n  transform: translateX(-100%) scale(var(--size-image));\n  z-index: 70;\n}\n\n/*# sourceMappingURL=developer.css.map */\n"
  },
  {
    "path": "packages/web-developer/public/developer.js",
    "content": "const svgGroup = {\n  LightIcon: `<svg width='24' height='24' viewBox='0 0 24 24' fill='black'>\n    <path d='M12 18C10.4087 18 8.88258 17.3679 7.75736 16.2426C6.63214 15.1174 6 13.5913 6 12C6 10.4087 6.63214 8.88258 7.75736 7.75736C8.88258 6.63214 10.4087 6 12 6C13.5913 6 15.1174 6.63214 16.2426 7.75736C17.3679 8.88258 18 10.4087 18 12C18 13.5913 17.3679 15.1174 16.2426 16.2426C15.1174 17.3679 13.5913 18 12 18ZM12 16C13.0609 16 14.0783 15.5786 14.8284 14.8284C15.5786 14.0783 16 13.0609 16 12C16 10.9391 15.5786 9.92172 14.8284 9.17157C14.0783 8.42143 13.0609 8 12 8C10.9391 8 9.92172 8.42143 9.17157 9.17157C8.42143 9.92172 8 10.9391 8 12C8 13.0609 8.42143 14.0783 9.17157 14.8284C9.92172 15.5786 10.9391 16 12 16V16ZM11 1H13V4H11V1ZM11 20H13V23H11V20ZM3.515 4.929L4.929 3.515L7.05 5.636L5.636 7.05L3.515 4.93V4.929ZM16.95 18.364L18.364 16.95L20.485 19.071L19.071 20.485L16.95 18.364ZM19.071 3.514L20.485 4.929L18.364 7.05L16.95 5.636L19.071 3.515V3.514ZM5.636 16.95L7.05 18.364L4.929 20.485L3.515 19.071L5.636 16.95V16.95ZM23 11V13H20V11H23ZM4 11V13H1V11H4Z' />\n  </svg>`,\n  DarkIcon: `<svg width='24' height='24' viewBox='0 0 24 24' fill='white'>\n    <path d='M11.38 2.01953C10.6431 2.70615 10.0521 3.53416 9.64219 4.45415C9.23227 5.37414 9.01185 6.36728 8.99408 7.37431C8.97632 8.38133 9.16156 9.38163 9.53877 10.3155C9.91598 11.2494 10.4774 12.0977 11.1896 12.8099C11.9018 13.5221 12.7501 14.0835 13.684 14.4608C14.6179 14.838 15.6182 15.0232 16.6252 15.0054C17.6323 14.9877 18.6254 14.7673 19.5454 14.3573C20.4654 13.9474 21.2934 13.3564 21.98 12.6195C21.662 17.8545 17.316 22.0005 12.001 22.0005C6.477 22.0005 2 17.5235 2 12.0005C2 6.68553 6.146 2.33953 11.38 2.01953Z' />\n  </SvgIcon>`,\n  logSvg: `<svg\n      aria-hidden='true'\n      className='SvgIcon-root SvgIcon-fontSizeMedium '\n      color='var(--color-text-third)'\n      fill='none'\n      focusable='false'\n      height='27'\n      style='height: 40px; width: 120px;'\n      viewBox='0 0 89 27'\n      width='89'\n    >\n      <path\n        clip-rule='evenodd'\n        d='M33.2461 13.1402H19.2495L22.2249 17.7118L11.3922 26.0863L33.2461 13.2211V13.1402ZM11.0988 26.2683V0.740234L0.0356445 17.732L11.0988 26.2683ZM35.2363 26.1875V13.1807H37.4154V24.4074H40.3908V26.1875H35.2363ZM88.6455 15.6486V17.7928H86.5293V15.6283C86.5921 14.6372 84.5387 14.5967 84.6854 15.6283V23.659C84.6854 24.1647 84.9578 24.4277 85.5654 24.4277C86.1311 24.4277 86.5293 24.1647 86.5293 23.659V21.4541H85.6073V19.674H88.6455V23.6792C88.6455 25.257 87.556 26.2887 85.5654 26.2887C83.5749 26.2887 82.4853 25.2368 82.4853 23.6792V15.6486C82.4853 14.091 83.5749 13.0391 85.5654 13.0391C87.556 13.0391 88.6455 14.0708 88.6455 15.6486ZM79.1119 20.2809C79.07 19.0874 79.049 17.9951 79.049 16.9836H79.0281V13.1605H81.0186V26.1875H78.7138L76.6604 18.9256C76.7023 20.1393 76.7233 21.2923 76.7233 22.3441V26.1875H74.7327V13.1605H77.1004L79.1119 20.2809ZM73.1403 26.1673H70.9612V13.1403H73.1403V26.1673ZM66.582 19.411C67.1058 19.411 67.3782 19.1481 67.3782 18.6424V15.7093C67.3782 15.2036 67.1058 14.9406 66.582 14.9406H65.5972V19.411H66.582ZM69.5573 15.7093V18.6424C69.5573 19.6335 69.1383 20.4022 68.3421 20.827L69.8297 26.1875H67.6506L66.2677 21.2114H65.5972V26.1875H63.4181V13.1605H66.582C68.5306 13.1605 69.5573 14.1315 69.5573 15.7093ZM59.3532 19.411C59.8771 19.411 60.1494 19.1481 60.1494 18.6424H60.1704V15.7093C60.1704 15.2036 59.898 14.9406 59.3742 14.9406H58.3894V19.411H59.3532ZM56.2103 13.1605H59.3742C61.3228 13.1605 62.3285 14.1112 62.3495 15.7295V18.6626C62.3495 20.2404 61.3228 21.2114 59.3742 21.2114H58.3894V26.1875H56.2103V13.1605ZM50.7834 23.6792C50.6577 24.6906 52.7111 24.6906 52.5854 23.6792V15.6486C52.6902 14.6372 50.6577 14.6372 50.7834 15.6486V23.6792ZM48.6043 15.6486C48.6043 14.0708 49.6939 13.0391 51.6844 13.0391C53.654 13.0391 54.7645 14.0708 54.7645 15.6486V23.6792C54.7645 25.257 53.675 26.2887 51.6844 26.2887C49.6939 26.2887 48.6043 25.2368 48.6043 23.6792V15.6486ZM43.3242 23.6792C43.1985 24.6906 45.2519 24.6906 45.1261 23.6792V15.6486C45.2309 14.6372 43.1985 14.6372 43.3242 15.6486V23.6792ZM41.1451 15.6486C41.1451 14.0708 42.2346 13.0391 44.2252 13.0391C46.2157 13.0391 47.3053 14.0708 47.3053 15.6486V23.6792C47.3053 25.257 46.2157 26.2887 44.2252 26.2887C42.2346 26.2887 41.1451 25.2368 41.1451 23.6792V15.6486Z'\n        fill-rule='evenodd'\n      />\n    </svg>`,\n  ios: `<svg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'>\n<path d='M11.6236 7.22161C10.7476 7.22161 9.39157 6.22561 7.96357 6.26161C6.07957 6.28561 4.35157 7.35361 3.37957 9.04561C1.42357 12.4416 2.87557 17.4576 4.78357 20.2176C5.71957 21.5616 6.82357 23.0736 8.28757 23.0256C9.69157 22.9656 10.2196 22.1136 11.9236 22.1136C13.6156 22.1136 14.0956 23.0256 15.5836 22.9896C17.0956 22.9656 18.0556 21.6216 18.9796 20.2656C20.0476 18.7056 20.4916 17.1936 20.5156 17.1096C20.4796 17.0976 17.5756 15.9816 17.5396 12.6216C17.5156 9.81361 19.8316 8.46961 19.9396 8.40961C18.6196 6.47761 16.5916 6.26161 15.8836 6.21361C14.0356 6.06961 12.4876 7.22161 11.6236 7.22161ZM14.7436 4.38961C15.5236 3.45361 16.0396 2.14561 15.8956 0.849609C14.7796 0.897609 13.4356 1.59361 12.6316 2.52961C11.9116 3.35761 11.2876 4.68961 11.4556 5.96161C12.6916 6.05761 13.9636 5.32561 14.7436 4.38961Z' />\n</svg>\n`,\n  android: `<svg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'>\n<path d='M6.382 3.968C7.97574 2.69106 9.9578 1.99674 12 2C14.125 2 16.078 2.736 17.618 3.968L19.071 2.515L20.485 3.929L19.032 5.382C20.3089 6.97574 21.0033 8.9578 21 11V12H3V11C3 8.875 3.736 6.922 4.968 5.382L3.515 3.93L4.929 2.516L6.382 3.969V3.968ZM3 14H21V21C21 21.2652 20.8946 21.5196 20.7071 21.7071C20.5196 21.8946 20.2652 22 20 22H4C3.73478 22 3.48043 21.8946 3.29289 21.7071C3.10536 21.5196 3 21.2652 3 21V14ZM9 9C9.26522 9 9.51957 8.89464 9.70711 8.7071C9.89464 8.51957 10 8.26521 10 8C10 7.73478 9.89464 7.48043 9.70711 7.29289C9.51957 7.10535 9.26522 7 9 7C8.73478 7 8.48043 7.10535 8.29289 7.29289C8.10536 7.48043 8 7.73478 8 8C8 8.26521 8.10536 8.51957 8.29289 8.7071C8.48043 8.89464 8.73478 9 9 9ZM15 9C15.2652 9 15.5196 8.89464 15.7071 8.7071C15.8946 8.51957 16 8.26521 16 8C16 7.73478 15.8946 7.48043 15.7071 7.29289C15.5196 7.10535 15.2652 7 15 7C14.7348 7 14.4804 7.10535 14.2929 7.29289C14.1054 7.48043 14 7.73478 14 8C14 8.26521 14.1054 8.51957 14.2929 8.7071C14.4804 8.89464 14.7348 9 15 9Z' />\n</svg> `,\n  googlePlay: `<svg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'>\n  <path d='M3.60972 1.81445L13.793 12.0005L3.61082 22.1869C3.41776 22.1053 3.24866 21.9625 3.13555 21.7672C3.0474 21.6149 3.00098 21.4421 3.00098 21.2661V2.73502C3.00098 2.32158 3.25188 1.96674 3.60972 1.81445ZM14.5 12.7075L16.802 15.0095L5.86498 21.3425L14.5 12.7075ZM17.699 9.50945L20.5061 11.1352C20.9841 11.4119 21.1473 12.0237 20.8705 12.5016C20.783 12.6528 20.6574 12.7785 20.5061 12.866L17.698 14.4915L15.207 12.0005L17.699 9.50945ZM5.86498 2.65845L16.803 8.99045L14.5 11.2935L5.86498 2.65845Z' />\n  </svg>`,\n  youtubeIcon: ` <svg width='24'\n        height='24'\n        viewBox='0 0 24 24'\n        fill='none'\n      >\n        <path\n          fill-rule ='evenodd'\n          clip-rule='evenodd'\n          d='M22.5417 12C22.5417 17.822 17.822 22.5417 12 22.5417C6.178 22.5417 1.45833 17.822 1.45833 12C1.45833 6.178 6.178 1.45833 12 1.45833C17.822 1.45833 22.5417 6.178 22.5417 12ZM23 12C23 18.0751 18.0751 23 12 23C5.92487 23 1 18.0751 1 12C1 5.92487 5.92487 1 12 1C18.0751 1 23 5.92487 23 12ZM18.1111 12C18.1111 12 18.1111 9.72667 17.8318 8.63767C17.6784 8.03756 17.225 7.56456 16.6475 7.402C15.6031 7.11111 12 7.11111 12 7.11111C12 7.11111 8.39872 7.11111 7.3525 7.402C6.77744 7.56211 6.32339 8.03572 6.16817 8.63767C5.88889 9.72667 5.88889 12 5.88889 12C5.88889 12 5.88889 14.2733 6.16817 15.3623C6.32156 15.9624 6.775 16.4354 7.3525 16.598C8.39872 16.8889 12 16.8889 12 16.8889C12 16.8889 15.6031 16.8889 16.6475 16.598C17.2226 16.4379 17.6766 15.9643 17.8318 15.3623C18.1111 14.2733 18.1111 12 18.1111 12ZM14.4444 12L10.7778 14.1389V9.86111L14.4444 12Z'\n        />\n     </svg>`,\n  twitterIcon: `\n    <svg width='24'\n        height='24'\n        viewBox='0 0 24 24'\n        fill='none'\n      >\n        <path\n          fill-rule ='evenodd'\n          clip-rule='evenodd'\n          d='M22.5417 12C22.5417 17.822 17.822 22.5417 12 22.5417C6.178 22.5417 1.45833 17.822 1.45833 12C1.45833 6.178 6.178 1.45833 12 1.45833C17.822 1.45833 22.5417 6.178 22.5417 12ZM23 12C23 18.0751 18.0751 23 12 23C5.92487 23 1 18.0751 1 12C1 5.92487 5.92487 1 12 1C18.0751 1 23 5.92487 23 12ZM16.7095 9.93043C16.7145 10.0394 16.7165 10.1494 16.7165 10.2604C16.7165 13.6354 14.2725 17.5254 9.80347 17.5244C8.43047 17.5244 7.15347 17.0944 6.07747 16.3564C6.26747 16.3804 6.46147 16.3934 6.65747 16.3934C7.79547 16.3964 8.84347 15.9844 9.67547 15.2944C8.61247 15.2694 7.71447 14.5164 7.40547 13.4854C7.55347 13.5174 7.70547 13.5344 7.86247 13.5354C8.08347 13.5364 8.29847 13.5064 8.50247 13.4484C7.39047 13.2024 6.55247 12.1484 6.55247 10.8904V10.8574C6.88047 11.0554 7.25447 11.1764 7.65347 11.1944C7.00147 10.7224 6.57247 9.92243 6.57247 9.02243C6.57247 8.54643 6.69247 8.10243 6.90147 7.72243C8.09947 9.30843 9.89047 10.3604 11.9115 10.4904C11.8695 10.3014 11.8485 10.1054 11.8485 9.90343C11.8485 8.48243 12.9365 7.34843 14.2785 7.37043C14.9775 7.38243 15.6095 7.70343 16.0525 8.20743C16.6055 8.10143 17.1255 7.89743 17.5955 7.61243C17.4135 8.20543 17.0285 8.69943 16.5265 9.00843C17.0185 8.95343 17.4865 8.82243 17.9225 8.62643C17.5965 9.13343 17.1845 9.57643 16.7095 9.93043Z'\n        />\n     </svg>`,\n  mediumIcon: `\n    <svg width='24'\n        height='24'\n        viewBox='0 0 24 24'\n        fill='none'\n      >\n        <path\n          fill-rule ='evenodd'\n          clip-rule='evenodd'\n          d='M22.5417 12C22.5417 17.822 17.822 22.5417 12 22.5417C6.178 22.5417 1.45833 17.822 1.45833 12C1.45833 6.178 6.178 1.45833 12 1.45833C17.822 1.45833 22.5417 6.178 22.5417 12ZM23 12C23 18.0751 18.0751 23 12 23C5.92487 23 1 18.0751 1 12C1 5.92487 5.92487 1 12 1C18.0751 1 23 5.92487 23 12ZM17.7337 16.4862L16.8583 15.6117H16.8593C16.7676 15.5658 16.7217 15.4274 16.7217 15.3358V8.33883C16.7217 8.24717 16.7676 8.10875 16.8593 8.01708L17.7337 7.00417V6.95833H14.6033L12.2548 12.8965L9.5855 6.95833H6.36342V7.00417L7.193 8.15642C7.37633 8.33975 7.42217 8.61658 7.42217 8.84667V13.9085C7.468 14.1853 7.42217 14.508 7.28467 14.783L6.04167 16.4862V16.532H9.35633V16.4862L8.11333 14.8298C7.97583 14.5529 7.92908 14.277 7.97583 13.9543V9.35267C7.99111 9.38322 8.00639 9.40359 8.02167 9.42396C8.05222 9.4647 8.08278 9.50544 8.11333 9.62767L11.2438 16.6246H11.2896L14.3274 9.03C14.2807 9.30592 14.2807 9.62767 14.2807 9.85867V15.2899C14.2807 15.4283 14.2348 15.52 14.1432 15.6117L13.2228 16.4862V16.532H17.7337V16.4862Z'\n        />\n     </svg>`,\n  discordIcon: ` <svg width='24'\n        height='24'\n        viewBox='0 0 24 24'\n        fill='none'\n      >\n        <path\n          fill-rule ='evenodd'\n          clip-rule='evenodd'\n          d='M22.5417 12C22.5417 17.822 17.822 22.5417 12 22.5417C6.178 22.5417 1.45833 17.822 1.45833 12C1.45833 6.178 6.178 1.45833 12 1.45833C17.822 1.45833 22.5417 6.178 22.5417 12ZM23 12C23 18.0751 18.0751 23 12 23C5.92487 23 1 18.0751 1 12C1 5.92487 5.92487 1 12 1C18.0751 1 23 5.92487 23 12ZM10.7503 15.4042C10.6021 15.3766 10.4546 15.3449 10.3081 15.3092V15.3083L9.3882 16.3442C7.31174 16.2766 6.5124 14.8862 6.5124 14.8862C6.5124 11.7976 7.86626 9.29449 7.86626 9.29449C9.21828 8.25854 10.5064 8.28686 10.5064 8.28686L10.9101 8.76647C11.6111 8.66738 12.3223 8.66431 13.0241 8.75733C13.0583 8.75866 13.0924 8.76171 13.1264 8.76647L13.4945 8.28686C13.4945 8.28686 14.7817 8.25854 16.1346 9.29357C16.1346 9.29357 17.4876 11.7976 17.4876 14.8862C17.4876 14.8862 16.6983 16.2775 14.6218 16.3442L13.7805 15.2507C13.5238 15.3192 13.3246 15.3677 13.1839 15.3951C12.3806 15.5525 11.5547 15.5556 10.7503 15.4042ZM14.7972 12.9523C14.7972 12.4498 14.3633 12.0387 13.8143 12.0387C13.2652 12.0387 12.8231 12.4498 12.8322 12.9523C12.8322 13.4547 13.2661 13.8658 13.8143 13.8658C14.3542 13.8658 14.7972 13.4547 14.7972 12.9523ZM11.281 12.9523C11.281 12.4498 10.8471 12.0387 10.299 12.0387C9.74996 12.0387 9.31603 12.4498 9.31603 12.9523C9.31603 13.4547 9.74996 13.8658 10.299 13.8658C10.838 13.8658 11.281 13.4547 11.281 12.9523Z'\n        />\n     </svg>`,\n  blackSvg: `<svg id='bgAlpha' width='3958' height='1453' viewBox='0 0 3958 1453' fill='none' xmlns='http://www.w3.org/2000/svg'>\n<path d='M2135.57 466.105C2094 466.105 2052.43 474.805 2009.89 492.203C1925.78 526.034 1840.71 588.861 1754.67 671.988C1711.17 714.517 1670.56 758.98 1633.83 804.409C1622.23 818.908 1610.63 833.407 1599.02 847.906C1593.22 855.638 1588.39 862.404 1585.49 865.304L1569.05 888.502L1552.62 865.304C1549.72 861.438 1545.85 855.638 1539.09 847.906C1527.48 833.407 1515.88 818.908 1504.28 804.409C1467.55 758.98 1426.94 714.517 1383.44 671.988C1297.4 587.895 1212.33 525.067 1128.22 492.203C1085.68 475.771 1044.11 466.105 1002.54 466.105C739.586 466.105 524.001 664.255 524.001 912.667C524.001 1161.08 739.586 1359.23 1002.54 1359.23C1044.11 1359.23 1085.68 1350.53 1128.22 1333.13C1212.33 1299.3 1297.4 1236.47 1383.44 1153.35C1426.94 1110.82 1467.55 1066.35 1504.28 1020.92C1515.88 1006.43 1527.48 991.926 1539.09 977.428C1544.89 969.695 1549.72 962.929 1552.62 960.029L1569.05 936.831L1585.49 960.029C1588.39 963.895 1592.26 969.695 1599.02 977.428C1610.63 991.926 1622.23 1006.43 1633.83 1020.92C1670.56 1066.35 1711.17 1110.82 1754.67 1153.35C1840.71 1237.44 1925.78 1300.27 2009.89 1333.13C2052.43 1349.56 2094 1359.23 2135.57 1359.23C2398.52 1359.23 2614.11 1161.08 2614.11 912.667C2614.11 664.255 2398.52 466.105 2135.57 466.105Z' stroke='url(#paint0_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M2637.31 906.87C2640.21 1150.45 2442.02 1365.03 2160.7 1359.23C2119.13 1359.23 2076.59 1349.56 2033.09 1333.13C1947.05 1299.3 1860.04 1236.47 1773.04 1153.35C1728.57 1110.82 1686.99 1066.36 1649.29 1020.93C1636.72 1006.43 1625.12 991.93 1613.52 977.431C1606.76 969.698 1602.89 962.932 1599.99 960.032L1582.59 936.834L1565.18 959.066C1562.28 961.965 1558.42 967.765 1551.65 975.498C1540.05 989.996 1528.45 1003.53 1515.88 1017.06C1478.18 1059.59 1436.61 1103.09 1393.1 1143.68C1306.1 1223.91 1220.06 1282.87 1134.98 1313.8C1092.45 1329.27 1049.91 1337.97 1008.34 1337C742.483 1334.1 521.098 1143.68 518.198 905.904C517.231 864.341 523.999 825.677 536.566 787.981C595.538 605.297 776.319 488.34 999.638 484.474C1041.21 484.474 1083.74 492.206 1126.28 507.672C1137.88 511.538 1149.48 516.371 1161.08 522.17C1234.56 555.034 1309 609.163 1384.4 677.79C1427.91 718.387 1469.48 760.916 1507.18 803.446C1518.78 816.978 1531.35 830.51 1542.95 845.009C1549.72 852.742 1553.58 858.541 1556.48 861.441L1573.89 883.672L1591.29 860.474C1594.19 856.608 1598.05 850.808 1604.82 843.076C1616.42 828.577 1628.02 813.112 1640.59 798.613C1678.29 753.184 1719.86 707.754 1763.37 665.225C1850.38 580.165 1936.42 517.338 2022.46 483.507C2065.96 466.109 2107.53 457.409 2149.1 456.443C2413.02 456.443 2633.44 652.659 2637.31 906.87Z' stroke='url(#paint1_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M2660.51 901.063C2666.31 1138.84 2485.53 1370.82 2185.84 1360.19C2143.3 1359.22 2100.77 1350.52 2057.26 1333.13C1969.29 1299.29 1881.31 1235.5 1792.37 1152.37C1746.94 1109.84 1704.4 1064.42 1665.73 1019.95C1653.16 1005.45 1640.59 990.955 1628.99 976.456C1622.23 968.723 1618.36 961.957 1615.46 959.058C1614.49 959.058 1598.06 935.86 1598.06 935.86C1597.09 935.86 1580.66 958.091 1580.66 957.124C1577.76 960.024 1572.92 965.824 1567.12 973.556C1555.52 987.088 1542.95 1000.62 1530.39 1013.19C1491.72 1053.78 1449.18 1095.35 1404.71 1133.04C1315.77 1209.4 1228.76 1264.5 1142.72 1293.5C1099.22 1307.99 1056.68 1315.73 1015.11 1314.76C746.354 1307.99 519.168 1126.28 512.401 899.129C511.434 860.466 517.235 822.769 529.802 787.972C588.774 610.121 766.655 509.597 996.741 502.831C1038.31 501.864 1081.81 509.597 1125.32 524.095C1136.92 527.962 1148.52 532.795 1161.09 537.628C1236.49 568.558 1311.9 619.787 1387.31 684.548C1431.78 723.211 1474.31 763.808 1512.98 804.404C1525.55 816.97 1537.15 830.502 1548.75 844.034C1555.52 851.767 1559.39 856.6 1562.29 859.5C1563.25 859.5 1579.69 880.764 1579.69 880.764C1580.66 880.764 1597.09 857.566 1597.09 856.6C1599.99 852.734 1604.83 846.934 1610.63 839.201C1622.23 823.736 1634.79 809.237 1646.4 794.739C1685.07 749.309 1727.6 702.913 1772.07 660.384C1861.01 575.324 1948.02 510.563 2035.03 475.766C2078.53 458.368 2121.07 448.702 2163.6 447.735C2428.49 445.802 2653.75 642.019 2660.51 901.063Z' stroke='url(#paint2_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M2683.71 896.235C2692.41 1129.18 2528.07 1377.59 2210.01 1362.13C2166.5 1361.16 2123 1351.5 2079.5 1334.1C1989.59 1299.3 1899.68 1236.47 1809.77 1153.35C1763.37 1110.82 1719.87 1065.39 1680.23 1020.92C1667.66 1006.43 1655.09 991.927 1642.53 976.461C1635.76 968.729 1630.93 962.929 1628.03 959.063C1627.06 958.096 1610.62 935.865 1609.66 935.865C1608.69 934.898 1592.26 957.13 1591.29 956.163C1588.39 959.063 1583.56 963.896 1576.79 971.629C1565.19 985.161 1552.62 996.76 1539.08 1009.33C1499.45 1047.99 1455.94 1086.65 1411.47 1123.38C1321.57 1194.91 1233.59 1247.1 1146.59 1274.17C1103.08 1287.7 1059.58 1294.47 1017.04 1292.53C745.386 1282.87 512.4 1108.88 502.732 892.369C500.799 855.639 507.566 820.842 519.167 787.011C579.105 613.027 754.086 529.9 989.006 520.235C1031.54 519.268 1075.05 526.034 1118.55 539.566C1130.15 543.433 1142.72 547.299 1154.32 552.132C1230.69 581.129 1307.07 628.492 1383.44 690.353C1428.88 727.083 1471.41 764.78 1511.05 803.443C1523.62 816.009 1536.18 828.574 1547.79 841.14C1554.55 847.906 1559.39 853.706 1562.29 856.605C1563.25 855.639 1579.69 877.87 1580.65 876.903C1581.62 875.937 1598.06 853.705 1599.02 852.739C1601.92 848.873 1606.76 843.073 1613.52 835.34C1625.13 819.875 1637.69 805.376 1650.26 790.878C1689.9 744.482 1732.43 698.086 1777.87 655.556C1867.78 569.53 1956.72 504.769 2044.69 469.006C2089.16 451.607 2132.67 440.975 2175.2 440.008C2442.99 435.175 2674.05 630.425 2683.71 896.235Z' stroke='url(#paint3_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M2707.87 890.438C2719.47 1118.55 2572.53 1384.36 2236.1 1363.1C2192.6 1362.13 2148.13 1352.46 2103.66 1335.07C2011.82 1300.27 1919.98 1236.47 1829.1 1154.31C1781.73 1111.79 1737.26 1066.36 1696.66 1020.93C1683.12 1006.43 1670.55 991.929 1657.99 976.464C1651.22 968.731 1646.39 962.931 1643.49 959.065C1642.52 958.099 1626.08 935.867 1625.12 935.867C1624.15 934.901 1607.72 956.165 1606.75 955.199C1603.85 958.099 1599.02 962.931 1592.25 969.698C1579.68 982.263 1567.11 993.862 1554.55 1005.46C1513.94 1042.19 1469.47 1078.92 1424.03 1112.75C1333.16 1180.41 1243.25 1229.71 1155.28 1253.87C1110.81 1266.44 1067.3 1272.24 1024.77 1270.3C750.212 1256.77 511.425 1091.49 497.891 885.605C495.957 850.808 501.758 818.911 513.359 787.014C574.264 617.862 745.378 551.167 987.065 538.602C1029.6 536.669 1073.11 542.468 1118.54 555.034C1130.14 557.934 1142.71 562.766 1155.28 566.633C1232.62 592.731 1309.96 638.16 1388.26 696.155C1433.7 730.952 1478.17 766.715 1517.81 803.445C1530.38 815.044 1543.91 826.643 1555.51 839.209C1562.28 845.975 1567.11 850.808 1570.01 853.708C1570.98 852.741 1587.41 874.006 1588.38 873.039C1589.35 872.073 1605.78 849.841 1606.75 848.875C1609.65 845.008 1614.48 839.209 1621.25 830.51C1633.82 815.044 1646.39 800.546 1658.95 785.08C1699.56 738.684 1743.06 692.288 1789.46 648.792C1881.31 561.8 1971.21 496.072 2060.15 460.309C2104.62 441.944 2149.09 432.278 2191.63 430.345C2457.49 424.545 2694.34 618.828 2707.87 890.438Z' stroke='url(#paint4_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M2731.08 884.632C2744.62 1107.91 2616.04 1390.15 2261.24 1364.06C2216.77 1362.12 2172.3 1352.46 2126.86 1335.06C2033.09 1299.3 1940.28 1236.47 1847.47 1154.31C1799.14 1111.78 1753.7 1066.35 1712.13 1020.92C1698.6 1006.42 1685.06 991.923 1672.49 976.457C1665.73 968.725 1660.89 962.925 1657.99 959.059C1657.03 958.092 1639.62 935.861 1638.66 934.894C1637.69 933.928 1620.29 954.226 1619.32 953.259C1616.42 956.159 1611.59 960.992 1604.82 966.792C1592.25 978.391 1578.72 989.99 1566.15 1000.62C1524.58 1035.42 1480.11 1070.22 1432.74 1102.11C1339.93 1165.91 1249.06 1211.34 1160.12 1233.57C1115.65 1245.17 1072.14 1250 1028.64 1247.1C751.184 1230.67 506.597 1073.12 489.195 877.866C486.295 845.002 492.095 815.038 503.696 786.041C565.568 620.755 732.815 572.426 981.269 555.994C1023.81 554.061 1068.28 558.894 1113.71 570.493C1126.28 573.393 1137.88 577.259 1150.45 581.125C1228.76 605.29 1307.06 646.853 1386.34 701.948C1432.74 734.812 1478.18 768.642 1518.78 802.473C1532.31 813.105 1544.88 824.704 1557.45 836.303C1564.22 843.069 1569.05 847.902 1571.95 849.835C1572.92 848.869 1589.35 869.167 1591.29 868.2C1592.25 867.234 1608.69 845.002 1610.62 844.036C1613.52 840.169 1618.36 834.37 1625.12 825.671C1637.69 810.205 1650.26 795.707 1663.79 780.241C1705.36 732.879 1749.83 686.483 1796.24 642.02C1889.04 555.028 1980.89 488.333 2070.79 451.603C2116.23 433.238 2160.7 422.606 2204.2 421.639C2471.99 414.873 2713.68 607.223 2731.08 884.632Z' stroke='url(#paint5_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M2754.28 878.833C2769.75 1097.28 2659.54 1395.95 2285.41 1365.02C2240.94 1363.09 2195.51 1352.46 2150.07 1336.03C2054.36 1300.26 1959.62 1236.47 1865.84 1155.28C1816.54 1112.75 1770.14 1067.32 1727.6 1021.89C1714.07 1007.39 1700.53 992.89 1687 977.425C1680.23 969.692 1675.4 963.893 1671.53 960.026C1669.59 959.06 1653.16 936.828 1652.19 935.862C1650.26 934.895 1633.83 954.227 1632.86 953.26C1628.99 955.193 1624.16 960.026 1617.39 965.826C1604.82 977.425 1591.29 988.057 1577.75 997.723C1535.22 1030.59 1489.78 1062.48 1442.41 1093.41C1348.63 1153.34 1256.79 1194.91 1166.89 1215.2C1121.45 1224.87 1077.95 1229.7 1034.44 1226.8C754.085 1207.47 503.698 1056.68 483.396 873.034C480.496 843.07 486.297 815.039 496.931 787.975C560.736 627.522 723.15 595.625 978.371 576.293C1021.87 574.36 1066.34 578.226 1112.75 587.892C1125.32 590.792 1136.92 593.692 1149.48 597.558C1228.76 618.823 1308.03 658.453 1388.27 709.681C1435.64 740.612 1481.08 771.543 1522.65 804.406C1536.18 815.039 1549.72 824.705 1562.29 836.304C1569.05 842.103 1573.89 846.936 1576.79 848.869C1578.72 847.903 1595.16 867.234 1596.12 866.268C1598.06 865.301 1614.49 843.07 1615.46 842.103C1618.36 838.237 1624.16 831.471 1629.96 823.738C1642.53 808.273 1656.06 792.808 1669.59 778.309C1712.13 730.946 1757.57 683.584 1803.97 639.121C1898.71 551.162 1990.55 483.501 2082.4 446.771C2127.83 428.406 2173.27 416.807 2217.74 415.84C2487.46 404.241 2733.98 595.625 2754.28 878.833Z' stroke='url(#paint6_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M2777.48 873.034C2794.89 1086.65 2702.08 1402.72 2310.55 1365.02C2265.11 1363.09 2218.7 1352.46 2173.27 1335.06C2075.63 1298.33 1979.92 1235.5 1884.21 1154.31C1833.94 1111.78 1786.57 1066.35 1743.06 1020.92C1728.56 1006.42 1715.03 991.924 1701.49 976.458C1694.73 968.726 1689.89 962.926 1686.03 959.06C1684.09 958.093 1667.66 936.828 1665.73 934.895C1663.79 933.929 1647.36 952.294 1645.42 951.327C1641.56 953.26 1636.72 958.093 1629.96 963.893C1617.39 974.525 1602.89 984.191 1589.35 993.857C1545.85 1024.79 1499.44 1054.75 1451.11 1082.78C1355.4 1138.84 1262.59 1176.54 1171.72 1194.91C1126.28 1203.61 1081.81 1207.47 1037.34 1203.61C754.083 1182.34 497.895 1040.25 474.693 866.268C470.826 838.237 476.627 813.106 487.261 787.975C552.033 632.355 711.546 616.89 971.601 594.658C1015.1 591.759 1060.54 595.625 1106.95 604.324C1119.51 606.257 1132.08 610.124 1144.65 613.023C1225.86 632.355 1305.13 668.119 1386.34 716.448C1434.67 745.445 1481.08 774.443 1523.61 804.407C1537.15 814.072 1550.68 823.738 1563.25 833.404C1570.02 839.204 1574.85 843.07 1578.72 845.003C1580.65 844.037 1597.09 862.402 1598.05 861.435C1599.99 860.468 1616.42 838.237 1618.35 837.27C1622.22 833.404 1627.06 826.638 1633.82 818.905C1647.36 803.44 1659.92 787.975 1673.46 772.51C1716.96 724.18 1762.4 676.818 1810.74 632.355C1906.45 543.43 2000.22 475.769 2093.03 438.072C2139.43 418.74 2184.87 408.108 2229.34 406.175C2501.96 393.609 2753.32 583.059 2777.48 873.034Z' stroke='url(#paint7_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M2800.69 868.203C2820.03 1076.02 2745.59 1409.49 2335.69 1366.96C2289.28 1364.06 2242.88 1353.43 2196.47 1337C2096.9 1300.26 1999.26 1237.44 1902.58 1156.24C1851.34 1112.75 1803.01 1068.29 1758.54 1022.86C1744.04 1008.36 1729.53 993.858 1716 978.393C1709.23 970.66 1703.43 964.861 1699.57 960.995C1697.63 960.028 1681.2 938.763 1679.26 936.83C1677.33 935.863 1660.9 954.228 1658.96 952.295C1655.1 954.228 1650.26 958.095 1643.49 963.894C1629.96 974.527 1616.43 983.226 1601.92 991.925C1557.45 1020.92 1510.08 1048.95 1461.75 1075.05C1365.07 1127.25 1271.3 1162.04 1179.46 1177.51C1134.02 1185.24 1088.58 1188.14 1044.11 1184.28C757.954 1158.18 495.966 1023.82 468.897 860.47C464.063 834.372 469.864 812.141 480.498 787.976C547.204 637.189 701.883 638.156 968.705 612.058C1013.18 609.159 1058.61 612.058 1105.98 618.824C1118.55 620.758 1131.12 623.657 1143.69 626.557C1225.86 642.989 1307.07 676.819 1388.27 721.282C1436.61 747.38 1483.98 775.411 1527.48 803.442C1541.02 812.141 1555.52 820.84 1568.09 830.506C1574.86 836.305 1579.69 840.172 1583.56 841.138C1585.49 839.205 1601.92 857.57 1603.86 855.637C1605.79 853.704 1622.23 832.439 1624.16 830.506C1628.03 826.64 1632.86 819.874 1639.63 812.141C1653.16 796.676 1666.7 781.21 1680.23 765.745C1724.7 717.416 1771.11 669.087 1819.44 624.624C1917.08 534.732 2011.82 466.104 2105.6 428.408C2152 409.076 2198.41 397.477 2243.84 395.544C2516.47 382.978 2773.62 571.462 2800.69 868.203Z' stroke='url(#paint8_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M2823.89 862.405C2844.19 1065.39 2789.09 1415.29 2359.85 1367.93C2313.45 1365.03 2266.08 1354.4 2218.71 1337C2117.2 1300.27 2017.63 1236.47 1919.98 1156.25C1867.78 1112.75 1818.48 1068.29 1773.04 1022.86C1758.54 1008.36 1744.04 993.86 1729.54 978.395C1722.77 970.662 1716.97 964.862 1713.1 960.03C1710.2 958.096 1694.73 937.798 1691.83 935.865C1688.93 933.932 1673.46 952.297 1670.56 950.364C1666.7 952.297 1661.86 956.163 1654.13 960.996C1640.59 970.662 1626.09 979.361 1611.59 987.094C1566.16 1014.16 1517.82 1040.26 1468.51 1064.42C1369.91 1112.75 1275.16 1143.68 1182.36 1157.21C1135.95 1163.98 1090.52 1165.91 1046.05 1161.08C756.988 1131.11 489.199 1005.46 458.263 852.739C453.429 828.574 458.263 808.276 468.897 787.011C537.536 642.024 687.382 659.422 960.971 629.458C1005.44 626.559 1051.85 627.525 1099.22 634.291C1111.78 636.224 1124.35 638.158 1137.89 641.057C1221.03 655.556 1303.2 685.52 1386.34 727.083C1435.64 751.248 1483.98 776.379 1528.45 802.477C1542.95 811.176 1556.49 818.909 1570.02 827.608C1576.79 832.441 1582.59 836.307 1585.49 838.24C1587.42 836.307 1603.86 853.705 1605.79 851.772C1607.73 849.839 1624.16 828.574 1626.09 826.641C1629.96 822.775 1634.79 816.009 1641.56 808.276C1655.1 792.811 1669.6 777.345 1683.13 761.88C1728.57 712.584 1775.94 665.222 1825.24 619.793C1923.85 529.9 2020.53 460.306 2115.27 420.677C2162.64 401.345 2209.04 388.779 2255.45 386.846C2530.97 373.314 2792.96 558.898 2823.89 862.405Z' stroke='url(#paint9_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M2847.09 856.608C2868.36 1054.76 2832.59 1421.09 2384.98 1368.9C2337.61 1366 2290.24 1354.4 2241.91 1337C2137.5 1299.3 2037.92 1236.48 1938.35 1156.25C1885.18 1112.75 1833.94 1068.29 1788.5 1021.89C1773.03 1007.4 1758.53 992.897 1744.03 977.431C1737.26 969.699 1731.46 963.899 1727.6 959.066C1724.7 957.133 1708.26 936.835 1706.33 934.902C1703.43 932.968 1686.99 950.367 1685.06 948.434C1681.19 949.4 1675.39 953.267 1668.62 958.1C1655.09 966.799 1639.62 974.532 1625.12 982.264C1578.72 1007.4 1529.41 1030.59 1480.11 1052.82C1380.53 1097.29 1284.83 1124.35 1190.08 1135.95C1143.68 1141.75 1097.28 1142.72 1052.81 1137.88C760.849 1105.02 488.226 986.131 452.457 845.01C446.656 822.778 452.457 805.38 462.124 786.048C533.664 645.893 677.709 679.724 958.066 646.86C1002.54 642.994 1049.91 643.96 1097.28 649.76C1109.84 650.726 1123.38 653.626 1135.95 655.559C1220.05 667.158 1303.19 695.189 1387.3 732.886C1437.57 755.117 1485.91 778.315 1531.35 801.513C1545.85 809.246 1560.35 816.012 1573.88 824.711C1580.65 829.544 1586.45 833.41 1590.32 834.377C1593.22 832.444 1608.69 848.876 1611.59 846.943C1614.49 845.009 1629.95 823.745 1632.86 821.812C1636.72 817.945 1642.52 811.179 1649.29 803.446C1662.82 787.015 1677.33 771.549 1691.83 757.05C1738.23 707.755 1786.57 659.426 1835.87 613.996C1936.41 523.138 2034.05 453.544 2129.76 412.947C2178.1 392.649 2224.5 381.05 2270.91 378.15C2545.46 362.685 2813.25 547.302 2847.09 856.608Z' stroke='url(#paint10_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M2870.29 850.81C2892.52 1044.13 2875.12 1427.86 2410.12 1369.87C2361.78 1366 2313.44 1355.37 2266.07 1337.97C2159.73 1300.27 2058.22 1236.48 1957.68 1156.25C1903.54 1112.75 1851.34 1068.29 1803.97 1021.9C1788.5 1007.4 1773.03 992.898 1759.5 977.433C1751.76 969.7 1746.93 963.901 1742.1 959.068C1739.2 957.134 1722.76 936.836 1719.86 934.903C1716.96 932.97 1700.53 949.402 1697.63 947.469C1693.76 948.435 1687.96 952.302 1680.22 957.134C1665.72 965.834 1651.22 972.6 1635.75 979.366C1588.38 1002.56 1538.11 1023.83 1487.84 1044.13C1387.3 1084.72 1289.66 1107.92 1194.92 1117.59C1147.55 1122.42 1102.11 1122.42 1055.71 1116.62C760.848 1080.86 482.425 968.733 443.755 839.211C437.955 818.913 438.921 802.481 452.456 787.016C497.893 641.062 666.107 701.957 952.264 666.193C997.701 662.327 1045.07 662.327 1093.41 666.193C1105.98 667.16 1119.51 669.093 1132.08 671.026C1218.12 680.692 1301.26 705.823 1386.33 739.653C1437.57 759.952 1486.87 780.25 1532.31 802.481C1546.81 809.247 1562.28 816.013 1575.82 823.746C1582.58 827.612 1588.38 831.479 1592.25 832.445C1595.15 830.512 1610.62 845.977 1613.52 844.044C1616.42 842.111 1631.89 820.846 1634.79 818.913C1638.65 814.08 1644.45 808.281 1651.22 800.548C1665.72 784.116 1680.22 768.651 1694.73 753.186C1741.13 703.89 1790.43 654.594 1841.67 609.165C1943.18 517.34 2042.75 446.779 2139.43 406.183C2187.77 385.884 2235.14 373.319 2282.51 370.419C2559.96 352.054 2832.59 534.738 2870.29 850.81Z' stroke='url(#paint11_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M2892.53 845.007C2915.73 1033.49 2917.67 1433.66 2433.33 1370.83C2384.99 1366.96 2335.68 1355.36 2287.35 1337.96C2179.07 1299.3 2075.63 1236.47 1974.12 1156.25C1919.02 1112.75 1865.85 1068.29 1817.51 1021.89C1802.04 1007.39 1786.57 991.928 1772.07 977.429C1764.34 969.696 1758.54 963.897 1754.67 959.064C1751.77 957.131 1735.33 936.833 1732.43 934.899C1729.53 932.966 1713.1 948.432 1709.23 946.498C1704.4 947.465 1699.56 951.331 1691.83 955.198C1677.33 962.93 1661.86 969.696 1646.39 975.496C1598.06 996.761 1547.79 1016.09 1496.55 1034.46C1394.07 1071.19 1296.43 1091.49 1199.76 1097.29C1152.39 1100.18 1105.98 1100.18 1059.58 1094.39C761.82 1054.76 478.564 951.331 435.06 832.442C428.293 815.043 429.259 799.578 442.794 787.012C487.264 643.958 653.545 723.218 945.502 684.555C990.939 679.722 1038.31 679.722 1087.61 682.621C1100.18 683.588 1113.72 684.555 1127.25 685.521C1214.26 692.287 1299.33 714.519 1384.41 745.449C1436.61 763.814 1486.88 782.179 1533.28 801.511C1547.79 807.311 1563.25 813.11 1576.79 820.843C1584.52 824.709 1589.36 827.609 1593.22 828.575C1596.12 825.676 1612.56 842.107 1615.46 839.208C1618.36 836.308 1634.79 816.01 1637.69 814.077C1641.56 809.244 1647.36 803.444 1654.13 794.745C1668.63 778.313 1683.13 762.848 1697.63 747.382C1745 697.12 1795.27 647.824 1846.51 601.429C1949.95 509.603 2049.53 438.076 2148.14 396.513C2197.44 376.215 2245.78 362.683 2293.15 359.783C2574.47 342.385 2851.93 522.169 2892.53 845.007Z' stroke='url(#paint12_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M2915.73 839.209C2939.89 1021.89 2961.16 1439.46 2458.45 1370.83C2409.15 1366.96 2359.85 1355.36 2310.54 1337.97C2200.33 1299.3 2095.92 1235.51 1992.48 1156.25C1936.41 1112.75 1882.27 1067.32 1832.97 1021.89C1817.5 1007.39 1801.07 991.929 1786.56 977.43C1778.83 969.698 1773.03 963.898 1769.16 959.065C1765.3 957.132 1749.83 936.834 1745.96 934.901C1742.09 932.968 1726.63 947.466 1722.76 945.533C1717.93 946.5 1712.13 949.4 1705.36 953.266C1690.86 960.999 1674.42 965.832 1659.92 971.631C1610.62 989.996 1559.38 1007.39 1507.18 1023.83C1403.73 1055.72 1304.16 1073.12 1207.48 1076.99C1160.11 1078.92 1112.74 1077.96 1066.34 1071.19C765.68 1028.66 476.623 931.035 430.219 824.71C423.452 809.245 423.452 796.68 436.986 785.081C480.49 645.893 644.837 743.518 943.562 700.988C989.965 696.155 1037.34 694.222 1087.61 696.155C1101.14 696.155 1113.71 698.088 1127.24 698.088C1215.22 702.921 1301.26 722.253 1388.27 749.317C1441.44 765.749 1491.71 782.181 1539.08 799.579C1554.55 805.379 1570.01 810.212 1583.55 816.978C1591.28 820.844 1596.12 823.744 1600.95 823.744C1603.85 820.844 1620.28 836.309 1623.18 833.41C1626.08 830.51 1642.52 810.212 1645.42 808.279C1649.29 803.446 1655.09 797.646 1662.82 788.947C1677.32 772.515 1692.79 757.05 1707.29 741.584C1755.63 691.322 1806.87 641.06 1859.07 594.664C1963.48 501.872 2064.99 429.378 2164.56 387.815C2213.87 366.551 2263.17 353.985 2310.54 350.119C2588 331.754 2871.25 509.605 2915.73 839.209Z' stroke='url(#paint13_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M2937.97 834.374C2963.1 1012.23 3003.71 1447.19 2482.63 1372.76C2432.36 1367.93 2383.06 1356.33 2332.78 1338.93C2220.64 1299.3 2114.3 1236.47 2009.89 1157.21C1952.85 1113.72 1897.75 1068.29 1847.48 1022.86C1831.04 1008.36 1815.58 992.894 1800.11 977.429C1792.37 969.696 1786.57 963.896 1781.74 959.064C1777.87 957.13 1761.44 936.832 1758.54 934.899C1754.67 931.999 1738.24 947.465 1734.37 944.565C1729.53 945.531 1723.73 948.431 1716 951.331C1700.53 958.097 1685.06 962.93 1669.6 968.729C1619.33 985.161 1567.12 1000.63 1514.92 1015.13C1409.54 1043.16 1309.97 1056.69 1211.36 1058.62C1163.02 1059.59 1115.65 1057.65 1068.28 1050.89C764.721 1005.46 470.83 914.601 419.593 819.876C411.859 806.344 411.859 795.711 425.393 787.012C466.963 651.69 630.344 766.714 935.835 721.284C982.239 716.451 1030.58 712.585 1080.85 714.518C1094.38 714.518 1107.92 715.485 1121.45 715.485C1210.39 717.418 1297.4 733.85 1385.37 758.015C1438.54 772.513 1490.75 786.045 1539.09 801.511C1554.55 806.344 1570.02 810.21 1584.52 816.976C1592.26 819.876 1597.09 822.775 1601.92 822.775C1605.79 819.876 1621.26 834.374 1624.16 831.475C1628.03 828.575 1643.49 808.277 1647.36 806.344C1652.19 801.511 1658 794.745 1664.76 787.012C1679.26 770.58 1694.73 755.115 1710.2 738.683C1759.5 687.454 1811.71 637.192 1863.91 590.796C1970.25 497.037 2072.73 424.544 2173.27 382.014C2223.54 360.749 2272.85 347.217 2321.18 343.351C2602.51 321.119 2890.6 497.037 2937.97 834.374Z' stroke='url(#paint14_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M2960.2 828.576C2986.3 1001.59 3045.28 1452.99 2505.83 1373.73C2455.56 1368.9 2404.32 1357.3 2355.02 1339.9C2240.94 1300.27 2132.67 1236.47 2027.29 1158.18C1968.32 1114.68 1913.21 1069.25 1861.98 1023.83C1845.54 1009.33 1829.11 993.861 1813.64 978.396C1805.91 970.663 1800.11 964.864 1795.27 960.031C1791.4 957.131 1774.97 938.766 1771.1 935.866C1767.24 932.966 1750.8 947.465 1746.93 944.565C1742.1 944.565 1736.3 947.465 1728.57 951.332C1713.1 958.098 1696.66 961.964 1681.2 966.797C1629.96 981.296 1576.79 994.828 1523.62 1006.43C1417.27 1030.59 1315.76 1040.26 1216.19 1040.26C1167.85 1040.26 1119.52 1037.36 1072.14 1029.62C765.686 980.329 465.994 896.236 410.89 813.11C403.156 800.545 402.189 793.779 415.723 787.013C456.327 655.557 618.74 787.979 930.033 739.65C976.437 733.851 1025.74 730.951 1076.98 729.984C1090.51 729.984 1104.05 730.951 1117.58 729.984C1207.49 726.118 1296.43 743.516 1384.4 763.815C1438.54 776.38 1490.75 787.979 1540.05 801.511C1555.52 805.378 1571.95 809.244 1586.45 815.043C1594.19 817.943 1599.99 820.843 1603.86 820.843C1607.72 817.943 1623.19 831.475 1627.06 828.576C1630.92 825.676 1646.39 806.344 1650.26 802.478C1655.09 797.645 1660.89 790.879 1667.66 783.146C1683.13 766.714 1698.6 750.282 1714.06 734.817C1764.34 683.588 1816.54 633.326 1869.71 585.963C1977.02 491.238 2081.43 417.778 2182.94 375.249C2233.21 353.984 2283.48 339.485 2332.78 335.619C2616.04 311.454 2908.96 484.472 2960.2 828.576Z' stroke='url(#paint15_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M2982.43 822.776C3008.54 990.961 3087.81 1458.79 2530 1374.69C2478.76 1369.86 2427.52 1357.3 2377.25 1339.9C2261.24 1300.27 2151.03 1236.47 2044.69 1158.18C1984.75 1114.68 1928.68 1069.25 1876.47 1023.82C1860.04 1009.33 1842.64 993.861 1827.17 978.395C1819.44 970.663 1813.64 964.863 1807.84 960.03C1803 957.13 1787.53 938.765 1783.67 935.866C1778.83 932.966 1763.37 946.498 1758.53 943.598C1753.7 943.598 1747.9 946.498 1740.16 949.398C1724.7 955.197 1708.26 959.064 1691.83 962.93C1639.62 975.496 1585.48 987.095 1531.35 996.76C1423.07 1017.06 1321.56 1023.82 1221.02 1020.92C1171.72 1019.96 1124.35 1016.09 1076.01 1008.36C766.649 956.164 447.623 887.537 403.152 807.31C392.518 798.611 393.485 792.812 407.019 787.979C446.656 660.39 607.136 810.21 924.229 758.981C971.599 753.182 1020.9 749.315 1072.14 747.382C1085.68 746.416 1099.21 747.382 1112.74 746.416C1204.59 743.516 1293.53 754.148 1382.47 771.547C1437.57 782.179 1490.74 791.845 1540.05 802.477C1555.51 806.344 1571.95 808.277 1587.42 814.076C1595.15 816.976 1600.95 818.909 1605.79 818.909C1609.65 816.009 1625.12 828.575 1628.99 825.675C1632.85 822.776 1648.32 803.444 1653.16 799.578C1657.99 794.745 1663.79 787.979 1671.52 780.246C1686.99 763.814 1702.46 747.382 1718.89 731.917C1770.13 679.721 1823.3 629.459 1877.44 582.097C1986.68 487.372 2092.06 412.945 2194.53 369.449C2245.77 348.184 2296.04 333.685 2345.35 328.852C2629.57 300.821 2928.3 471.906 2982.43 822.776Z' stroke='url(#paint16_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3003.71 816.97C3029.81 980.323 3129.38 1464.58 2553.2 1375.65C2501 1369.86 2449.76 1358.26 2398.52 1340.86C2280.58 1300.26 2169.4 1236.47 2061.13 1159.14C2000.22 1115.64 1943.18 1070.21 1890.01 1023.82C1872.61 1009.32 1856.18 993.855 1839.74 978.389C1832.01 970.657 1825.24 964.857 1820.41 960.024C1815.57 957.125 1800.11 938.76 1795.27 935.86C1790.44 932.96 1774.97 945.526 1770.14 942.626C1765.3 942.626 1758.53 944.559 1750.8 947.459C1734.37 952.292 1717.93 955.191 1701.5 959.058C1647.36 969.69 1593.22 978.389 1539.08 987.089C1429.84 1003.52 1326.4 1006.42 1224.89 1001.59C1175.59 999.654 1127.25 994.821 1078.91 986.122C766.653 930.06 440.859 870.132 393.488 800.538C382.854 793.772 382.854 789.906 397.355 787.973C436.025 663.284 594.572 832.436 918.432 776.374C965.803 770.574 1016.07 765.741 1068.28 762.842C1081.81 761.875 1095.35 761.875 1109.85 760.908C1202.66 756.076 1293.53 762.842 1382.47 777.34C1438.54 786.04 1492.68 792.806 1542.95 802.472C1559.39 805.371 1575.82 807.304 1591.29 811.171C1599.02 813.104 1604.82 815.037 1609.66 815.037C1613.52 811.171 1628.99 823.736 1633.82 820.837C1637.69 816.97 1654.13 798.605 1657.99 794.739C1662.83 789.906 1668.63 783.14 1676.36 775.407C1691.83 758.975 1708.26 742.543 1723.73 726.112C1775.94 673.916 1830.07 622.687 1884.21 575.325C1994.42 479.633 2100.76 404.24 2205.17 359.777C2257.38 337.545 2307.65 323.047 2357.92 318.214C2643.11 290.183 2946.67 459.335 3003.71 816.97Z' stroke='url(#paint17_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3025.94 811.175C3052.04 969.695 3171.92 1471.35 2576.4 1376.63C2524.2 1370.83 2471.99 1358.26 2419.79 1340.86C2299.91 1300.27 2186.8 1236.47 2077.56 1159.14C2015.69 1115.65 1957.69 1070.22 1903.55 1023.82C1886.15 1009.32 1868.74 993.859 1852.31 978.394C1844.58 970.661 1837.81 964.862 1832.97 960.029C1828.14 957.129 1812.67 938.764 1807.84 935.864C1803.01 932.965 1786.57 944.564 1781.74 941.664C1776.9 941.664 1770.14 943.597 1762.4 945.53C1745.97 950.363 1728.57 952.296 1712.13 955.196C1657.03 963.895 1601.92 970.661 1546.82 976.461C1435.64 989.026 1332.2 988.06 1229.72 981.294C1180.42 977.427 1131.12 972.595 1081.81 963.895C766.653 904.934 435.059 852.738 384.788 793.777C373.187 789.911 373.187 787.977 387.688 787.011C425.391 666.188 582.004 852.738 912.632 793.777C960.969 787.011 1011.24 781.211 1063.44 777.345C1076.98 776.378 1091.48 775.412 1105.01 774.445C1198.79 766.713 1290.63 771.545 1381.5 782.178C1438.54 788.944 1492.68 793.777 1543.92 800.543C1560.35 802.476 1576.79 803.443 1592.25 807.309C1599.99 809.242 1605.79 811.175 1610.62 810.209C1615.46 806.342 1630.92 817.941 1634.79 814.075C1639.63 810.209 1655.09 791.844 1658.96 787.977C1663.79 783.144 1670.56 776.378 1677.33 768.646C1692.8 752.214 1709.23 735.782 1725.67 719.35C1778.84 666.188 1832.97 614.959 1889.05 567.597C2001.19 470.938 2108.5 395.545 2213.87 350.116C2266.08 327.884 2317.31 313.385 2368.55 307.586C2655.68 280.522 2964.07 446.774 3025.94 811.175Z' stroke='url(#paint18_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3047.21 805.376C3074.28 959.063 3212.52 1477.15 2599.6 1376.63C2546.43 1370.83 2493.26 1358.26 2441.06 1339.9C2319.25 1298.33 2204.2 1235.51 2093.99 1158.18C2031.16 1114.68 1972.18 1069.25 1917.08 1022.86C1899.68 1007.39 1881.31 992.893 1864.88 977.428C1857.14 969.695 1850.37 963.896 1844.57 959.063C1839.74 956.163 1823.31 937.798 1818.47 934.898C1813.64 931.998 1797.2 942.631 1792.37 939.731C1786.57 939.731 1780.77 940.698 1772.07 942.631C1755.63 946.497 1738.23 948.43 1720.83 950.363C1664.76 957.129 1609.65 961.962 1553.58 965.829C1441.44 974.528 1336.06 970.662 1232.62 960.996C1182.35 956.163 1133.05 950.363 1083.74 940.698C765.684 878.836 427.322 833.407 374.151 786.044C361.583 784.111 361.583 784.111 376.085 786.044C412.821 669.088 568.467 873.037 904.895 811.176C953.233 804.41 1003.5 797.644 1057.64 792.811C1071.18 791.844 1085.68 790.877 1100.18 788.944C1194.92 779.278 1287.73 781.212 1378.6 788.944C1436.61 793.777 1491.71 796.677 1543.92 801.51C1560.35 803.443 1577.75 803.443 1593.22 806.343C1600.95 808.276 1606.75 809.242 1612.55 808.276C1617.39 804.41 1632.86 815.042 1637.69 811.176C1642.52 807.309 1657.99 788.944 1662.83 785.078C1667.66 780.245 1674.43 773.479 1682.16 765.746C1698.59 748.348 1715.03 731.916 1731.46 716.451C1785.6 663.289 1840.71 611.093 1896.78 562.764C2009.89 465.139 2119.13 388.779 2225.47 343.35C2278.64 321.119 2329.88 305.653 2381.12 299.854C2668.24 269.89 2982.44 434.209 3047.21 805.376Z' stroke='url(#paint19_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3074.28 799.575C3074.28 950.362 3259.89 1482.95 2627.64 1377.59C2573.5 1370.82 2520.33 1358.26 2468.13 1340.86C2344.38 1299.3 2228.37 1235.5 2116.23 1159.14C2052.43 1115.65 1992.49 1070.22 1936.42 1023.82C1918.05 1008.36 1900.65 993.858 1883.25 978.393C1875.51 970.66 1868.74 964.86 1862.94 960.027C1857.14 956.161 1841.68 938.763 1836.84 935.863C1831.04 931.997 1815.57 942.629 1809.77 939.729C1803.97 938.763 1797.2 940.696 1789.47 942.629C1772.07 946.495 1754.67 946.495 1737.27 948.429C1680.23 953.261 1624.16 955.195 1567.12 958.094C1453.04 962.927 1347.67 955.195 1242.29 943.596C1192.02 937.796 1141.75 931.03 1092.45 921.364C771.487 853.703 427.325 816.973 371.253 779.277C358.686 779.277 357.719 782.176 372.22 786.043C407.023 672.953 561.703 894.3 903.931 829.539C952.268 821.806 1003.51 815.04 1057.64 808.274C1071.18 806.341 1085.68 805.374 1100.18 803.441C1196.86 790.876 1290.63 789.909 1382.47 793.775C1441.44 796.675 1496.55 796.675 1549.72 799.575C1567.12 800.541 1583.55 799.575 1599.99 802.475C1607.72 803.441 1614.49 804.408 1619.32 803.441C1624.16 799.575 1639.63 809.241 1644.46 805.374C1649.29 801.508 1664.76 783.143 1669.59 779.277C1674.43 774.444 1681.2 767.678 1688.93 758.978C1705.36 741.58 1721.8 725.148 1739.2 708.716C1794.3 655.554 1850.38 603.359 1907.41 554.063C2022.46 458.371 2132.67 381.045 2239.97 334.649C2293.15 311.451 2345.35 295.986 2397.55 290.186C2687.58 259.255 2939.9 439.04 3074.28 799.575Z' stroke='url(#paint20_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3095.54 793.782C3095.54 939.736 3301.46 1488.75 2650.84 1378.56C2596.7 1371.8 2542.56 1359.23 2489.39 1340.87C2363.72 1299.3 2245.77 1235.51 2132.66 1158.18C2067.89 1114.69 2006.02 1069.26 1949.95 1022.86C1931.58 1007.4 1913.21 992.898 1895.81 977.432C1888.08 969.7 1880.34 963.9 1874.54 959.067C1868.74 955.201 1853.27 937.803 1847.47 934.903C1841.67 931.036 1826.21 941.669 1820.41 937.803C1814.6 936.836 1807.84 938.769 1800.1 939.736C1782.7 942.635 1764.33 942.635 1746.93 943.602C1688.93 945.535 1631.89 946.502 1574.85 946.502C1459.81 946.502 1352.5 935.869 1247.12 922.337C1195.89 915.571 1145.62 907.839 1096.31 897.206C771.485 827.612 420.555 799.581 361.584 772.517C348.049 774.45 347.083 779.283 361.584 786.049C395.42 675.859 548.166 916.538 897.162 847.91C946.466 840.178 997.703 832.445 1052.81 824.712C1067.31 822.779 1080.84 820.846 1095.34 818.913C1192.99 803.448 1287.73 806.347 1380.54 800.548C1439.51 796.682 1496.54 799.581 1549.72 799.581C1567.12 799.581 1584.52 798.615 1600.95 800.548C1608.69 801.514 1615.45 802.481 1620.29 801.515C1625.12 797.648 1640.59 806.347 1645.42 802.481C1651.22 798.615 1665.73 780.25 1671.53 775.417C1677.33 770.584 1683.13 762.851 1690.86 755.119C1707.3 737.72 1724.7 721.288 1742.1 704.856C1798.17 650.728 1855.21 598.532 1912.25 549.237C2028.26 450.645 2140.4 372.352 2248.67 325.956C2302.81 302.758 2355.98 287.293 2408.19 281.493C2699.18 249.596 2954.4 428.414 3095.54 793.782Z' stroke='url(#paint21_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3115.85 788.949C3115.85 930.07 3342.07 1496.49 2673.08 1380.5C2617.97 1373.73 2563.84 1360.2 2509.7 1342.8C2382.09 1300.27 2262.21 1236.48 2148.13 1160.12C2082.4 1116.62 2019.56 1071.19 1962.52 1024.79C1944.15 1009.33 1924.82 994.831 1907.41 979.365C1898.71 971.633 1891.95 965.833 1886.15 961C1880.35 957.134 1864.88 939.735 1859.08 936.836C1853.28 932.969 1837.81 942.635 1831.04 938.769C1825.24 937.802 1818.47 938.769 1809.77 939.735C1792.37 941.669 1774 941.669 1755.64 941.669C1696.66 941.669 1638.66 940.702 1580.65 938.769C1463.68 934.902 1355.4 921.37 1249.06 904.938C1197.82 897.206 1147.55 888.506 1096.31 877.874C769.554 805.38 411.857 785.082 349.986 769.617C335.484 774.45 334.518 781.216 349.019 789.915C381.888 683.591 532.701 941.669 888.464 870.141C937.768 862.409 989.972 853.71 1045.08 844.044C1059.58 842.111 1074.08 840.177 1088.58 837.278C1187.19 819.879 1283.86 818.913 1377.64 810.213C1437.58 804.414 1495.58 804.414 1549.72 803.447C1567.12 802.481 1584.52 798.614 1601.92 802.481C1609.66 804.414 1616.42 803.447 1622.22 802.481C1628.02 797.648 1642.53 807.314 1648.33 802.481C1654.13 797.648 1668.63 780.249 1674.43 775.416C1680.23 769.617 1687 762.851 1694.73 755.118C1712.13 737.72 1729.53 721.288 1745.97 704.856C1803.01 650.727 1860.04 597.565 1919.02 548.27C2036.96 448.712 2149.1 370.418 2259.31 323.056C2313.45 299.858 2367.59 283.426 2419.79 277.627C2711.75 238.963 2968.9 416.814 3115.85 788.949Z' stroke='url(#paint22_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3137.11 783.142C3137.11 919.43 3383.63 1502.28 2695.31 1381.46C2639.24 1373.72 2584.13 1361.16 2530 1342.79C2400.45 1300.26 2279.61 1236.47 2163.6 1160.11C2096.89 1115.65 2033.09 1071.18 1975.08 1023.82C1955.75 1008.36 1937.38 993.856 1919.01 978.391C1910.31 970.658 1903.55 964.859 1897.74 960.026C1890.98 956.16 1875.51 939.728 1869.71 935.862C1862.94 931.995 1847.47 940.694 1841.67 936.828C1835.87 935.862 1828.14 936.828 1820.4 936.828C1802.04 938.761 1783.67 936.828 1766.27 936.828C1706.33 934.895 1647.36 931.029 1589.35 928.129C1471.41 920.396 1362.17 902.998 1254.86 884.633C1203.62 875.933 1152.38 866.268 1101.15 854.669C771.485 779.275 407.021 766.71 343.216 760.91C327.748 767.676 326.781 776.375 341.282 787.008C373.185 684.55 523.031 960.026 884.594 885.599C934.865 876.9 987.069 868.201 1043.14 857.568C1057.64 854.669 1072.14 852.735 1086.64 849.836C1187.19 829.537 1283.86 819.872 1378.6 814.072C1439.51 810.206 1497.51 804.406 1552.62 800.54C1570.02 799.573 1588.39 793.774 1604.82 797.64C1612.55 799.573 1619.32 798.607 1625.12 796.674C1630.92 791.841 1645.42 800.54 1651.22 795.707C1657.02 790.874 1672.49 773.476 1678.29 768.643C1684.09 762.843 1690.86 756.077 1698.59 748.345C1716 730.946 1733.4 714.514 1750.8 697.116C1808.8 642.02 1866.81 588.858 1925.78 539.563C2044.69 440.005 2158.77 360.745 2269.94 312.416C2325.05 288.251 2379.18 271.819 2432.36 266.02C2724.31 228.323 2982.43 405.208 3137.11 783.142Z' stroke='url(#paint23_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3157.42 777.342C3157.42 908.797 3423.27 1508.08 2717.55 1382.42C2661.47 1374.69 2605.4 1361.16 2551.26 1343.76C2419.79 1300.26 2297.01 1237.44 2180.03 1161.08C2112.36 1116.61 2047.59 1072.15 1988.62 1024.79C1969.28 1009.32 1949.95 994.823 1931.58 978.391C1922.88 971.625 1916.11 964.859 1909.34 960.026C1902.58 956.16 1887.11 939.728 1881.31 934.895C1874.54 931.028 1859.07 938.761 1852.31 934.895C1846.51 933.928 1838.77 933.928 1831.04 934.895C1812.67 935.861 1794.3 933.928 1775.93 932.962C1715.03 929.095 1655.09 923.296 1596.12 917.496C1476.24 905.897 1366.03 884.633 1257.76 864.334C1205.55 854.669 1154.32 844.036 1103.08 832.437C770.517 754.144 400.253 749.311 332.581 754.144C317.113 762.843 315.179 774.442 329.681 787.008C360.616 688.416 508.529 981.291 876.859 903.964C927.13 895.265 980.301 884.633 1036.37 874C1050.87 871.1 1065.37 868.201 1079.88 865.301C1181.38 842.103 1279.03 829.537 1374.73 820.838C1436.61 815.039 1495.58 807.306 1551.65 801.506C1570.02 799.573 1587.42 793.774 1604.82 796.674C1612.55 797.64 1619.32 796.674 1625.12 794.74C1630.92 789.907 1646.39 797.64 1652.19 792.807C1657.99 787.974 1673.46 770.576 1679.26 765.743C1685.06 759.943 1691.83 753.177 1699.56 745.445C1716.96 728.046 1735.33 710.648 1752.73 694.216C1811.7 639.121 1870.68 584.992 1929.65 535.696C2049.52 435.172 2165.53 354.945 2277.68 306.616C2332.78 282.452 2387.88 266.02 2442.02 259.254C2735.91 218.657 2996.94 394.575 3157.42 777.342Z' stroke='url(#paint24_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3177.72 771.543C3177.72 898.165 3463.88 1514.84 2739.78 1382.42C2682.74 1374.69 2626.67 1360.19 2571.57 1342.79C2438.16 1299.3 2313.45 1235.5 2195.5 1160.11C2126.86 1115.65 2061.13 1070.22 2001.19 1023.82C1981.85 1008.36 1961.55 993.857 1943.18 977.425C1934.48 970.659 1927.71 963.892 1920.95 959.06C1914.18 955.193 1898.71 938.761 1891.95 933.928C1885.18 929.096 1869.71 936.828 1862.94 932.962C1856.18 931.029 1849.41 931.995 1840.71 931.995C1821.37 931.995 1803 930.062 1784.64 928.129C1722.76 922.329 1661.86 914.597 1602.89 906.864C1482.04 891.399 1370.87 867.234 1260.66 844.036C1208.46 833.404 1156.25 821.805 1104.05 809.239C768.585 727.08 391.554 730.946 320.981 746.411C304.547 757.044 302.613 771.543 317.114 786.041C347.084 691.316 493.062 1002.56 867.193 921.363C917.464 912.664 971.602 901.065 1028.64 888.499C1043.14 885.599 1057.64 882.7 1073.11 878.833C1175.59 853.702 1275.16 837.27 1370.87 825.671C1433.71 817.939 1492.68 807.306 1549.72 799.574C1568.08 796.674 1586.45 789.908 1603.85 792.807C1611.59 793.774 1618.36 791.841 1625.12 789.908C1630.92 785.075 1646.39 791.841 1652.19 787.008C1658.96 782.175 1673.46 764.777 1679.26 759.944C1685.06 754.144 1691.83 747.378 1700.53 739.645C1717.93 722.247 1736.3 704.848 1754.67 688.417C1814.61 632.355 1874.54 579.193 1934.48 528.931C2056.29 427.439 2173.27 347.213 2286.38 296.951C2342.45 272.786 2397.55 255.388 2451.69 248.622C2748.48 208.025 3010.47 382.977 3177.72 771.543Z' stroke='url(#paint25_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3198.99 765.751C3198.99 887.54 3505.45 1520.65 2762.02 1383.4C2704.01 1374.7 2647.94 1361.17 2591.87 1342.8C2456.53 1299.3 2329.88 1235.51 2210.97 1160.12C2141.37 1115.65 2074.66 1070.22 2013.76 1023.83C1993.46 1008.36 1974.12 993.865 1954.79 977.433C1946.08 970.667 1938.35 963.9 1932.55 959.068C1925.78 954.235 1910.31 938.769 1903.55 933.936C1896.78 929.103 1881.31 935.87 1873.58 932.003C1866.81 930.07 1860.04 930.07 1851.34 930.07C1832.01 930.07 1812.67 926.204 1794.31 924.271C1731.47 916.538 1669.59 906.872 1609.66 896.24C1486.88 876.908 1374.74 848.877 1264.53 822.779C1211.36 810.214 1159.15 798.615 1106.95 786.049C768.587 700.99 379.955 701.957 312.282 738.687C293.914 749.319 292.947 767.684 307.449 785.083C335.484 693.257 480.496 1022.86 861.395 937.803C912.632 928.137 965.803 916.538 1023.81 903.006C1038.31 899.139 1053.78 896.24 1068.28 892.373C1171.72 864.342 1272.26 845.011 1368.94 830.512C1432.74 820.846 1492.68 808.281 1549.72 798.615C1568.09 795.715 1586.45 790.882 1604.82 788.949C1612.56 787.982 1620.29 787.982 1626.09 785.083C1632.86 780.25 1647.36 786.049 1654.13 781.216C1660.89 775.417 1675.4 758.985 1682.16 754.152C1687.96 748.353 1695.7 741.587 1703.43 733.854C1721.8 716.455 1740.17 699.057 1758.54 681.658C1818.47 625.597 1879.38 571.468 1940.28 520.239C2063.06 417.781 2181.97 336.588 2296.05 286.326C2353.08 261.195 2408.19 243.797 2463.29 237.03C2760.09 198.367 3024.01 371.385 3198.99 765.751Z' stroke='url(#paint26_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3219.29 759.947C3219.29 876.903 3546.05 1526.45 2784.26 1384.36C2726.25 1375.66 2668.25 1361.16 2612.17 1343.76C2473.93 1299.3 2347.29 1235.51 2226.44 1161.08C2154.9 1116.62 2088.2 1071.19 2025.36 1024.79C2005.06 1009.33 1984.76 994.826 1965.42 978.394C1956.72 971.628 1948.99 964.862 1942.22 960.029C1934.48 955.196 1919.98 939.731 1912.25 934.898C1904.52 930.065 1889.05 936.831 1882.28 931.999C1875.51 930.065 1867.78 930.065 1860.05 929.099C1840.71 928.132 1821.38 924.266 1802.04 921.366C1738.24 910.734 1676.36 899.135 1614.49 887.536C1490.75 863.371 1377.64 832.44 1265.5 804.41C1212.32 790.877 1159.15 778.312 1106.95 764.78C765.688 675.854 370.288 686.487 299.716 732.882C280.381 745.448 279.414 766.713 293.915 786.045C320.984 698.086 465.029 1045.09 851.728 957.13C902.966 947.464 957.103 934.898 1015.11 919.433C1029.61 915.567 1045.08 911.7 1060.55 907.834C1165.92 877.87 1266.46 855.638 1365.07 837.273C1429.84 824.708 1490.75 811.176 1548.75 798.61C1567.12 794.744 1585.49 789.911 1604.82 787.011C1612.56 786.045 1620.29 785.078 1626.09 783.145C1632.86 777.345 1647.36 783.145 1654.13 777.345C1660.9 771.546 1675.4 755.114 1682.16 749.314C1688.93 743.515 1695.7 736.749 1703.43 729.016C1721.8 711.618 1740.17 694.219 1758.54 676.821C1819.44 620.759 1881.31 565.664 1943.19 514.435C2067.9 411.977 2186.81 329.818 2302.82 278.589C2359.85 253.458 2415.92 236.059 2472 228.327C2771.69 187.73 3037.54 360.748 3219.29 759.947Z' stroke='url(#paint27_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3239.59 755.112C3239.59 867.236 3585.68 1533.21 2806.49 1386.29C2747.51 1377.59 2689.51 1363.09 2632.47 1344.73C2492.29 1300.26 2363.72 1236.47 2241.91 1162.04C2169.4 1117.58 2101.73 1072.15 2037.92 1025.76C2017.62 1010.29 1996.35 994.824 1977.02 979.359C1968.32 972.593 1960.58 965.827 1953.81 960.994C1946.08 956.161 1930.61 940.696 1923.85 935.863C1916.11 931.03 1900.64 936.83 1892.91 931.997C1886.14 930.063 1878.41 929.097 1869.71 928.13C1849.41 926.197 1830.07 922.331 1810.74 918.464C1745.96 905.899 1683.13 892.367 1621.25 878.835C1495.58 850.804 1381.5 816.973 1269.36 786.043C1216.19 771.544 1163.02 758.012 1109.84 744.48C765.683 652.654 363.516 672.953 291.01 728.048C270.708 743.513 269.742 765.744 284.243 787.009C310.345 702.917 452.457 1067.32 845.923 976.459C897.16 965.827 952.265 953.261 1011.24 936.83C1025.74 932.963 1041.21 929.097 1056.67 924.264C1163.02 891.4 1265.49 866.269 1364.1 845.004C1428.87 830.505 1490.74 814.074 1549.71 800.541C1569.05 795.708 1587.42 789.909 1605.79 787.009C1613.52 786.043 1621.25 785.076 1628.02 782.176C1634.79 776.377 1649.29 781.21 1656.06 775.41C1662.82 769.611 1678.29 753.179 1685.06 747.379C1691.83 741.58 1698.59 734.814 1707.29 726.115C1725.66 707.75 1745 691.318 1763.37 673.919C1825.24 616.891 1888.08 561.796 1949.95 510.567C2075.62 407.143 2196.47 324.016 2313.44 272.788C2371.45 247.657 2427.52 229.291 2483.59 221.559C2783.28 178.063 3051.07 349.148 3239.59 755.112Z' stroke='url(#paint28_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3258.92 749.316C3258.92 856.606 3625.32 1539.98 2826.79 1387.26C2766.85 1377.59 2708.85 1363.1 2651.81 1345.7C2509.7 1301.23 2379.18 1237.44 2256.41 1163.01C2182.94 1118.55 2114.3 1073.12 2049.52 1025.76C2028.26 1010.29 2007.95 994.828 1987.65 979.362C1978.95 972.596 1971.22 965.83 1963.48 960.997C1955.75 956.164 1940.28 940.699 1932.55 935.866C1924.81 931.033 1909.35 935.866 1901.61 931.033C1894.84 928.133 1887.11 928.133 1878.41 927.167C1858.11 925.234 1838.77 919.434 1818.47 915.568C1752.73 901.069 1688.93 885.604 1626.09 869.172C1499.45 837.275 1384.4 799.578 1270.33 766.714C1216.19 751.249 1163.02 736.75 1108.88 722.251C761.817 627.526 352.883 656.524 277.477 721.285C257.175 738.683 255.241 763.814 269.743 787.012C294.878 706.786 435.056 1089.55 834.323 994.828C886.527 984.195 941.632 970.663 1000.6 952.298C1016.07 947.465 1031.54 943.599 1046.04 938.766C1153.35 903.002 1256.79 874.971 1356.37 850.807C1422.11 834.375 1484.94 816.01 1544.88 799.578C1564.22 794.745 1582.59 787.979 1601.92 784.113C1609.65 782.18 1617.39 781.213 1624.16 778.313C1630.92 772.514 1645.42 776.38 1653.16 770.581C1660.89 764.781 1675.39 748.349 1682.16 742.55C1688.93 736.75 1695.69 729.018 1704.4 721.285C1723.73 702.92 1742.1 685.521 1761.43 668.123C1824.27 611.094 1888.08 555.033 1950.92 503.804C2078.53 399.413 2200.34 316.287 2318.28 264.092C2376.28 237.994 2433.32 220.595 2490.36 211.896C2794.89 167.433 3064.61 337.552 3258.92 749.316Z' stroke='url(#paint29_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3279.23 743.512C3279.23 845.97 3665.93 1545.77 2849.02 1387.26C2789.09 1377.59 2730.11 1363.09 2672.11 1344.73C2528.06 1299.3 2396.59 1235.5 2271.88 1161.08C2197.44 1116.61 2127.83 1071.18 2062.09 1023.82C2040.82 1008.36 2019.56 992.89 1999.25 977.425C1990.55 970.659 1982.82 963.893 1975.09 959.06C1967.35 954.227 1951.88 938.761 1944.15 933.928C1935.45 929.096 1920.95 932.962 1912.25 928.129C1905.48 925.229 1896.78 924.263 1888.08 923.296C1867.78 920.396 1847.47 914.597 1827.17 909.764C1760.47 893.332 1695.7 874.967 1632.86 857.568C1504.28 821.805 1388.27 780.242 1273.23 745.445C1219.09 729.013 1164.95 713.548 1110.81 698.082C760.851 599.491 345.15 638.154 266.844 712.581C245.575 732.879 243.642 758.977 258.143 785.075C282.312 708.715 420.557 1108.88 826.59 1011.26C878.795 1000.62 934.866 985.157 994.804 966.792C1010.27 961.959 1025.74 957.126 1041.21 952.294C1149.48 914.597 1253.89 882.7 1354.43 855.635C1421.14 837.27 1483.98 816.006 1544.88 797.64C1564.22 791.841 1583.55 785.075 1602.89 780.242C1610.62 778.309 1618.36 776.376 1625.12 773.476C1632.86 767.676 1647.36 770.576 1654.13 764.777C1661.86 758.977 1676.36 742.545 1684.09 736.746C1690.86 730.946 1698.6 723.214 1706.33 715.481C1725.66 697.116 1745 679.717 1764.33 662.319C1828.14 604.324 1891.95 549.229 1955.75 497.033C2084.33 392.642 2208.07 307.583 2326.98 255.388C2385.95 229.29 2443.96 210.925 2501 202.226C2806.49 156.796 3078.14 326.915 3279.23 743.512Z' stroke='url(#paint30_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3299.53 737.72C3299.53 835.345 3706.53 1551.58 2871.26 1388.23C2810.36 1378.56 2750.42 1363.1 2692.41 1345.7C2546.43 1300.27 2413.02 1236.48 2287.35 1162.05C2211.94 1117.59 2140.4 1072.16 2074.66 1024.8C2053.39 1009.33 2031.16 993.865 2010.86 978.399C2002.16 971.633 1993.45 964.867 1986.69 960.034C1977.99 955.201 1963.49 940.703 1954.79 934.903C1946.08 929.104 1931.58 932.97 1922.88 928.137C1915.15 925.237 1907.41 924.271 1898.71 922.338C1877.45 918.471 1857.14 912.672 1836.84 906.872C1769.17 888.507 1703.43 868.209 1639.63 848.877C1510.08 809.247 1393.11 764.785 1277.1 727.088C1221.99 709.689 1167.85 693.258 1113.72 677.792C760.853 576.301 339.351 622.697 258.144 706.79C235.909 729.021 233.976 758.019 248.477 786.049C271.679 712.589 408.957 1131.12 820.791 1030.59C873.962 1019 930.033 1003.53 989.972 984.199C1005.44 979.366 1020.91 974.533 1036.38 968.734C1146.58 928.137 1251.96 894.307 1353.47 863.376C1421.14 843.078 1484.95 819.88 1546.82 799.582C1567.12 792.816 1585.49 785.083 1605.79 780.25C1613.52 778.317 1621.26 776.384 1628.99 772.517C1636.73 765.751 1651.23 769.618 1658.96 762.852C1666.69 756.085 1681.2 740.62 1688.93 734.821C1695.7 729.021 1703.43 721.288 1712.13 713.556C1731.47 695.191 1750.8 677.792 1771.1 660.394C1835.88 602.399 1900.65 546.337 1965.42 494.142C2094 385.884 2218.71 301.792 2338.58 247.663C2397.56 221.565 2456.53 202.234 2513.56 193.535C2818.09 147.139 3091.68 315.324 3299.53 737.72Z' stroke='url(#paint31_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3319.83 731.909C3319.83 824.701 3746.16 1558.34 2892.53 1389.18C2830.66 1378.55 2770.72 1364.05 2711.75 1345.69C2563.83 1299.29 2428.49 1235.5 2301.84 1162.04C2225.47 1117.58 2152.97 1072.15 2086.26 1024.78C2064.02 1009.32 2042.76 993.853 2021.49 978.387C2012.79 971.621 2004.09 964.855 1996.35 960.022C1987.65 954.223 1972.18 940.691 1964.45 934.891C1955.75 929.092 1940.28 931.991 1931.58 927.158C1923.85 924.259 1916.11 922.326 1907.41 920.392C1886.14 915.559 1865.84 908.793 1845.54 902.994C1776.9 881.729 1710.2 860.464 1646.39 838.233C1514.91 794.737 1396.97 746.408 1279.99 706.778C1224.89 688.413 1169.78 671.014 1115.65 654.582C758.917 550.191 331.615 605.287 247.508 700.012C225.272 725.143 222.372 755.107 236.873 786.037C258.142 716.443 394.453 1152.37 813.054 1048.95C866.226 1037.35 923.264 1020.92 984.169 999.652C999.637 993.853 1015.1 989.02 1031.54 983.22C1142.72 939.724 1249.06 902.994 1351.53 868.197C1420.17 844.999 1484.94 820.834 1546.82 797.636C1567.12 789.904 1586.45 782.171 1606.75 776.372C1615.45 774.438 1623.19 771.539 1629.96 767.672C1637.69 760.906 1652.19 763.806 1659.92 757.04C1667.66 750.274 1682.16 734.809 1690.86 729.009C1697.63 723.21 1705.36 715.477 1714.06 707.744C1733.4 689.379 1753.7 671.981 1773.03 653.616C1838.77 594.654 1904.51 538.592 1969.28 486.397C2100.76 380.073 2226.44 294.047 2348.25 240.885C2408.19 214.787 2467.16 195.456 2525.16 185.79C2829.69 136.494 3105.21 304.679 3319.83 731.909Z' stroke='url(#paint32_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3339.16 726.117C3339.16 814.076 3785.8 1564.14 2913.8 1390.16C2851.92 1379.53 2791.02 1364.06 2732.05 1345.7C2582.2 1299.3 2444.92 1235.51 2317.31 1162.05C2239.97 1117.58 2166.5 1072.15 2098.83 1024.79C2076.59 1009.33 2054.36 993.86 2033.09 978.395C2023.42 971.629 2015.69 964.863 2007.95 960.03C1999.25 954.23 1983.79 940.698 1975.08 934.899C1966.38 929.099 1950.92 931.999 1942.22 926.199C1934.48 923.3 1925.78 921.366 1917.08 919.433C1895.81 914.6 1874.54 906.868 1854.24 900.102C1784.64 876.904 1716.96 852.739 1652.19 829.541C1519.75 781.212 1400.84 729.983 1282.89 688.42C1227.79 669.088 1172.68 650.723 1116.61 634.291C757.95 526.034 323.881 590.795 236.874 694.22C213.672 721.284 210.771 754.148 226.239 786.045C246.541 720.317 380.919 1174.61 805.321 1067.32C858.492 1055.72 916.497 1038.32 977.402 1016.09C992.87 1010.29 1009.3 1004.49 1024.77 998.693C1136.92 953.264 1244.22 912.667 1347.67 874.97C1417.27 849.839 1482.04 822.775 1544.88 798.61C1565.18 790.878 1584.52 781.212 1604.82 775.412C1613.52 772.513 1621.26 770.58 1628.02 766.713C1636.72 759.947 1650.26 761.88 1658.96 755.114C1667.66 748.348 1681.19 732.883 1689.89 726.117C1696.66 719.351 1704.4 712.585 1713.1 704.852C1733.4 686.487 1753.7 668.122 1773.03 650.723C1839.74 591.762 1906.45 534.733 1971.22 482.538C2104.63 375.247 2231.27 289.222 2354.05 234.126C2414.95 207.062 2473.93 187.73 2532.9 178.065C2841.29 126.836 3117.78 293.088 3339.16 726.117Z' stroke='url(#paint33_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3359.46 721.284C3359.46 804.41 3826.4 1570.91 2936.03 1392.09C2873.19 1381.46 2812.28 1365.99 2752.35 1347.63C2600.57 1301.23 2462.32 1237.44 2332.78 1163.98C2254.47 1119.52 2180.03 1074.09 2111.39 1026.72C2089.16 1011.26 2066.92 995.793 2044.69 979.361C2035.02 972.595 2027.29 965.829 2019.55 960.03C2009.88 954.23 1995.38 940.698 1986.68 934.899C1977.01 929.099 1962.51 931.032 1952.85 924.266C1945.11 920.4 1936.41 918.467 1927.71 916.534C1905.48 910.734 1884.21 903.001 1863.91 895.269C1792.37 870.138 1725.66 844.04 1659.92 818.909C1526.51 766.713 1405.67 712.585 1286.76 668.122C1230.69 646.857 1175.58 628.492 1119.51 611.094C757.947 499.937 318.077 572.43 227.203 686.487C204.001 716.451 199.168 750.281 215.602 785.078C234.937 723.217 367.381 1194.91 798.551 1084.72C852.688 1072.15 909.726 1054.75 972.565 1030.59C988.033 1024.79 1004.47 1018.99 1019.94 1012.23C1133.04 963.896 1242.29 920.4 1345.73 879.803C1415.34 852.739 1482.04 823.742 1545.85 796.677C1566.15 787.978 1586.45 778.312 1606.75 771.546C1615.45 768.647 1623.19 765.747 1629.95 761.88C1638.65 755.114 1652.19 756.081 1660.89 749.315C1669.59 742.549 1684.09 727.084 1691.82 720.317C1699.56 713.551 1707.29 706.785 1715.99 699.053C1736.29 680.688 1756.6 662.322 1776.9 644.924C1844.57 584.996 1911.28 527.968 1977.98 474.806C2112.36 367.515 2240.94 280.523 2364.68 224.461C2425.59 197.396 2485.52 178.065 2544.5 167.432C2851.92 116.204 3131.31 281.489 3359.46 721.284Z' stroke='url(#paint34_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3378.8 715.484C3378.8 792.811 3866.04 1576.71 2956.33 1393.06C2892.53 1381.46 2830.66 1365.99 2770.72 1347.63C2617 1300.27 2476.83 1236.47 2346.32 1163.98C2267.04 1119.52 2191.64 1074.09 2122.03 1026.72C2098.83 1011.26 2076.59 995.793 2054.36 979.361C2044.69 972.595 2035.99 965.829 2028.26 960.03C2018.59 954.23 2004.09 940.698 1994.42 934.899C1984.75 929.099 1970.25 930.066 1960.58 923.3C1952.85 919.433 1944.15 917.5 1935.45 914.6C1913.21 907.834 1891.94 899.135 1870.68 891.402C1798.17 864.338 1730.5 836.307 1663.79 808.276C1528.45 752.215 1406.64 694.22 1286.76 647.824C1230.69 625.592 1174.62 606.261 1118.55 588.862C754.083 473.839 307.446 555.998 214.639 679.721C190.47 711.618 185.636 748.348 202.071 785.078C220.439 726.117 351.917 1216.17 788.886 1102.12C843.024 1089.55 901.029 1071.19 963.867 1046.06C979.335 1040.26 995.77 1033.49 1012.2 1026.72C1126.28 975.495 1236.49 929.099 1340.9 885.603C1411.47 856.606 1478.18 824.708 1542.95 796.677C1564.22 787.012 1583.55 777.346 1604.82 768.647C1613.52 765.747 1621.26 761.88 1628.99 758.014C1637.69 751.248 1652.19 751.248 1659.93 744.482C1668.63 737.716 1683.13 723.217 1691.83 715.484C1699.56 708.718 1707.3 701.952 1716 694.22C1736.3 675.855 1757.57 657.49 1777.87 639.124C1846.51 579.196 1914.18 521.201 1980.89 468.039C2117.2 359.782 2246.74 271.823 2371.45 215.761C2433.32 188.697 2493.26 168.399 2553.2 157.766C2863.52 106.538 3143.88 270.857 3378.8 715.484Z' stroke='url(#paint35_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3399.1 709.682C3399.1 782.176 3905.68 1583.47 2978.57 1393.06C2914.76 1381.46 2851.92 1365.99 2791.02 1347.63C2635.37 1300.26 2493.26 1236.47 2361.78 1163.98C2281.54 1119.51 2205.17 1073.12 2134.6 1025.75C2111.4 1010.29 2088.19 994.824 2065.96 978.392C2056.29 971.626 2047.59 964.86 2039.86 959.061C2030.19 953.261 2015.69 939.729 2006.02 933.93C1996.35 927.163 1980.89 928.13 1971.22 921.364C1963.48 917.498 1954.78 914.598 1945.12 911.698C1922.88 903.965 1900.65 895.266 1879.38 886.567C1805.9 857.57 1737.26 826.639 1670.56 797.641C1534.25 737.713 1411.47 675.852 1290.63 627.523C1233.59 604.325 1177.52 584.027 1120.48 565.662C753.117 447.739 300.679 537.631 204.005 671.986C179.836 705.816 174.035 745.446 190.47 784.109C207.872 729.014 337.416 1236.47 781.152 1119.51C836.257 1105.98 894.262 1086.65 958.067 1060.55C973.535 1053.79 989.97 1047.02 1006.4 1040.25C1122.41 987.092 1232.62 937.796 1338.97 890.433C1410.5 858.536 1478.18 825.672 1543.92 794.742C1565.18 785.076 1585.49 773.477 1606.75 764.778C1615.45 760.911 1623.19 758.012 1630.92 753.179C1639.62 745.446 1654.12 745.446 1662.83 738.68C1671.53 730.947 1686.03 717.415 1694.73 709.682C1702.46 702.916 1710.2 696.15 1718.9 687.451C1739.2 669.086 1760.47 650.721 1781.74 632.356C1851.34 572.428 1919.98 514.433 1987.65 460.304C2123 353.98 2254.47 265.055 2380.15 208.993C2442.02 180.962 2502.93 160.664 2562.87 150.031C2875.13 95.9026 3157.42 259.255 3399.1 709.682Z' stroke='url(#paint36_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3418.44 703.886C3418.44 771.547 3945.31 1589.28 2999.84 1394.03C2935.06 1382.43 2872.22 1366 2810.35 1347.63C2652.77 1299.3 2508.73 1236.47 2376.28 1163.98C2294.11 1119.52 2217.74 1073.12 2146.2 1025.76C2123 1010.29 2099.79 994.828 2076.59 978.396C2066.92 971.63 2058.22 964.864 2049.52 959.064C2039.86 952.298 2024.39 939.732 2014.72 933.933C2004.09 927.167 1989.58 927.167 1979.92 920.401C1971.22 916.534 1962.52 913.635 1953.81 909.768C1930.61 902.036 1909.34 892.37 1887.11 882.704C1812.67 850.807 1743.06 818.91 1675.39 787.012C1537.15 723.218 1413.4 658.457 1291.59 607.228C1234.56 583.064 1177.52 561.799 1120.48 543.434C750.215 421.644 291.01 520.236 191.435 665.223C166.3 701.953 160.499 742.55 176.934 784.113C192.402 732.884 320.979 1258.7 771.483 1137.88C826.588 1124.35 885.559 1104.05 949.365 1076.99C965.799 1070.22 982.234 1063.45 998.669 1054.76C1115.65 998.694 1227.79 946.499 1334.13 896.236C1406.64 862.406 1474.31 827.609 1541.01 794.745C1562.28 784.113 1583.55 772.514 1604.82 762.848C1613.52 758.982 1622.22 755.115 1628.99 750.282C1638.66 742.55 1652.19 741.583 1660.89 733.851C1670.56 726.118 1684.09 712.586 1693.76 704.853C1701.49 698.087 1709.23 690.354 1717.93 682.622C1739.2 664.257 1760.47 645.892 1780.77 627.526C1851.34 566.632 1919.98 508.637 1988.62 454.508C2127.83 344.318 2259.31 255.392 2386.92 198.364C2449.76 170.333 2510.66 150.035 2571.57 139.402C2885.76 86.2404 3169.98 247.66 3418.44 703.886Z' stroke='url(#paint37_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3438.74 698.086C3438.74 760.914 3985.92 1595.07 3021.11 1394.99C2955.37 1382.43 2892.53 1366.96 2830.66 1348.6C2671.15 1300.27 2526.13 1236.47 2391.76 1164.95C2308.62 1120.48 2231.28 1074.09 2158.77 1026.72C2134.6 1011.26 2111.4 995.793 2088.2 979.361C2078.53 972.595 2069.83 965.829 2061.13 960.03C2050.49 953.264 2035.99 940.698 2026.33 934.899C2015.69 928.133 2001.19 927.166 1990.56 920.4C1981.86 916.534 1973.15 912.667 1964.45 909.768C1941.25 901.068 1919.02 890.436 1896.78 880.77C1821.38 846.94 1750.8 813.109 1683.13 779.279C1543.92 711.618 1419.21 642.991 1296.43 589.829C1239.39 564.698 1181.39 542.466 1124.35 523.135C750.219 398.445 286.181 505.736 183.706 660.389C157.604 699.053 151.803 742.549 168.238 785.078C182.739 737.716 309.383 1280.94 765.687 1157.21C820.792 1143.68 880.73 1122.42 945.502 1094.38C961.937 1087.62 978.372 1079.89 994.807 1071.19C1112.75 1012.23 1225.86 957.13 1333.17 903.968C1406.64 868.205 1475.28 830.508 1541.99 795.711C1563.25 784.112 1584.52 772.513 1605.79 761.88C1614.49 758.014 1623.19 754.148 1630.93 748.348C1640.59 740.616 1654.13 738.682 1663.8 730.95C1673.46 723.217 1687 709.685 1696.66 701.952C1704.4 695.186 1713.1 687.454 1721.8 679.721C1743.07 660.389 1764.34 642.024 1785.61 623.659C1857.14 562.764 1926.75 503.803 1996.36 449.674C2136.53 339.484 2269.95 249.592 2399.49 191.597C2462.33 163.566 2524.2 142.301 2586.07 131.669C2897.36 75.6069 3183.52 237.026 3438.74 698.086Z' stroke='url(#paint38_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3458.08 693.253C3458.08 751.248 4025.56 1601.84 3042.38 1396.92C2976.64 1384.36 2911.86 1367.93 2849.99 1349.56C2688.55 1301.23 2541.6 1237.44 2406.26 1165.91C2322.15 1121.45 2243.84 1075.05 2170.37 1027.69C2146.2 1012.23 2122.03 996.76 2099.8 980.328C2090.13 973.562 2081.43 966.796 2072.73 960.996C2062.09 954.23 2047.59 942.631 2036.96 935.865C2026.32 929.099 2011.82 928.132 2001.19 920.4C1992.49 915.567 1983.79 912.667 1974.12 908.801C1950.92 899.135 1927.72 888.503 1905.48 877.87C1829.11 842.107 1757.57 805.376 1688.93 770.579C1547.78 698.086 1422.11 626.559 1298.36 571.464C1240.36 545.366 1183.32 522.168 1125.32 502.836C747.319 373.314 276.513 488.337 171.138 653.623C145.035 694.22 138.268 739.649 154.703 785.078C168.237 741.582 293.914 1302.2 756.019 1175.58C812.091 1161.08 872.029 1139.81 936.801 1109.85C953.236 1102.12 969.67 1094.38 986.105 1085.69C1105.01 1024.79 1219.09 965.829 1327.37 909.767C1400.84 872.071 1471.41 832.441 1539.08 795.711C1561.32 784.112 1582.59 770.58 1603.86 759.947C1612.56 755.114 1621.26 751.248 1628.99 746.415C1638.66 738.682 1652.19 735.783 1661.86 728.05C1671.53 720.317 1685.06 706.785 1695.7 699.052C1703.43 692.286 1712.13 684.554 1720.83 676.821C1742.1 657.489 1764.34 639.124 1785.6 620.759C1858.11 558.898 1928.68 499.936 1998.29 445.808C2140.4 334.651 2274.78 243.792 2405.29 185.797C2469.09 156.8 2531.93 135.535 2592.84 124.903C2908 65.941 3196.09 225.427 3458.08 693.253Z' stroke='url(#paint39_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3477.41 687.459C3477.41 740.622 4064.22 1608.61 3063.64 1397.9C2996.93 1385.33 2932.16 1368.9 2869.32 1349.57C2705.94 1301.24 2557.06 1237.44 2420.75 1164.95C2335.68 1120.49 2256.41 1074.09 2181.97 1026.73C2157.8 1011.26 2133.63 995.799 2110.43 979.367C2100.76 972.601 2091.09 965.835 2082.39 960.036C2071.76 953.27 2057.26 941.671 2046.62 934.905C2035.99 928.138 2021.49 926.205 2009.89 918.473C2001.19 913.64 1991.52 909.773 1982.82 905.907C1958.65 896.241 1936.41 884.642 1913.21 873.043C1835.87 835.347 1763.37 796.683 1693.76 758.987C1551.65 682.627 1425 608.2 1299.33 549.238C1241.32 522.174 1183.32 498.009 1124.35 477.711C744.414 346.256 267.808 469.978 159.532 644.93C132.463 688.426 125.696 735.789 142.131 783.151C154.699 742.555 278.442 1321.54 747.314 1192.02C803.386 1177.52 864.291 1155.29 930.03 1124.35C946.464 1116.62 962.899 1108.89 980.301 1099.22C1100.18 1035.43 1215.22 973.568 1324.46 914.606C1398.9 874.01 1469.47 833.413 1538.11 793.784C1560.35 781.218 1581.62 767.686 1603.85 756.087C1612.55 751.254 1621.25 746.421 1628.99 741.588C1638.66 733.855 1652.19 729.989 1662.82 722.256C1672.49 713.557 1686.99 700.992 1696.66 692.292C1704.39 685.526 1713.09 677.794 1721.8 670.061C1744.03 650.729 1765.3 632.364 1787.53 613.999C1861.01 552.138 1932.55 492.21 2003.12 438.081C2146.2 325.958 2282.51 235.099 2413.99 176.137C2477.79 147.14 2541.6 125.875 2603.47 114.276C2919.6 55.3147 3209.62 214.801 3477.41 687.459Z' stroke='url(#paint40_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3497.71 681.656C3497.71 729.985 4104.83 1614.41 3084.91 1398.86C3017.24 1385.33 2952.47 1368.9 2888.66 1350.53C2722.38 1301.24 2572.53 1237.44 2435.26 1165.91C2349.22 1121.45 2268.98 1075.05 2193.57 1027.69C2168.43 1012.23 2144.26 996.762 2121.06 980.33C2111.4 973.564 2101.73 966.798 2093.03 960.998C2081.43 954.232 2066.93 942.633 2056.29 935.867C2044.69 929.101 2030.19 926.201 2019.55 918.469C2010.85 913.636 2001.19 909.769 1991.52 904.937C1967.35 894.304 1944.15 881.739 1920.95 870.14C1842.64 829.543 1769.17 788.947 1699.56 750.283C1555.52 670.057 1427.91 591.764 1302.23 530.869C1243.26 502.838 1185.25 477.707 1126.28 457.409C743.448 323.054 261.042 454.509 148.899 640.093C121.83 685.522 114.096 734.818 130.531 785.08C142.132 748.35 263.942 1345.7 739.581 1212.31C796.619 1197.81 857.525 1174.61 923.263 1141.75C939.698 1134.02 957.099 1125.32 973.534 1115.65C1095.34 1048.96 1211.35 985.163 1321.56 922.335C1396.97 879.805 1468.51 836.309 1538.11 794.746C1560.35 781.214 1582.58 767.682 1604.82 755.116C1613.52 750.283 1622.22 745.45 1630.92 739.651C1641.56 730.952 1655.09 728.052 1664.76 719.353C1675.39 710.653 1688.93 698.088 1698.59 689.389C1707.3 682.623 1715.03 674.89 1724.7 667.157C1746.93 647.826 1769.17 629.461 1791.4 610.129C1865.84 547.301 1937.38 488.34 2008.92 432.278C2153.93 320.154 2291.21 227.362 2423.65 167.434C2488.43 138.437 2552.23 116.205 2615.07 104.606C2930.23 45.6448 3222.19 203.198 3497.71 681.656Z' stroke='url(#paint41_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3517.04 675.857C3517.04 719.353 4144.46 1620.21 3106.18 1398.86C3038.5 1385.33 2971.8 1368.9 2908.96 1349.56C2740.75 1300.27 2589.93 1236.47 2450.72 1164.95C2363.72 1120.48 2281.54 1074.09 2206.14 1025.76C2181 1010.29 2155.86 993.862 2132.66 978.397C2123 971.631 2113.33 964.865 2104.63 959.065C2093.03 952.299 2078.52 940.7 2067.89 932.968C2056.29 925.235 2041.79 922.335 2030.19 914.602C2021.49 909.77 2011.82 904.937 2002.15 901.07C1977.98 889.471 1954.78 876.906 1931.58 864.34C1852.31 821.811 1778.83 779.281 1707.29 738.684C1562.28 653.625 1433.7 573.399 1306.09 509.604C1247.12 480.607 1188.15 454.509 1129.18 433.245C741.514 297.923 252.34 438.077 137.297 633.327C109.261 680.69 101.527 732.885 117.962 785.08C128.596 752.217 248.473 1366.96 729.913 1230.67C786.951 1215.21 848.823 1192.01 915.528 1158.18C931.963 1149.48 949.365 1140.78 966.766 1131.12C1089.54 1062.49 1206.52 994.829 1317.7 929.101C1394.07 884.638 1465.61 839.209 1536.18 795.713C1558.42 781.214 1580.65 766.715 1603.85 754.15C1612.55 749.317 1621.25 743.517 1629.95 737.718C1640.59 729.019 1654.12 725.152 1663.79 716.453C1674.42 707.754 1687.96 695.188 1698.59 686.489C1707.29 679.723 1715.99 671.99 1724.7 664.258C1746.93 644.926 1769.17 625.594 1791.4 607.229C1865.84 544.401 1939.31 484.473 2010.85 428.412C2156.83 315.321 2296.04 222.53 2429.45 161.635C2495.19 131.671 2559 110.406 2621.84 97.8405C2941.83 35.9792 3234.75 191.599 3517.04 675.857Z' stroke='url(#paint42_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3536.38 670.05C3536.38 708.714 4184.1 1626.97 3127.44 1399.82C3058.81 1386.29 2992.1 1368.89 2928.29 1350.52C2758.15 1300.26 2605.4 1237.43 2465.22 1165.91C2377.25 1121.44 2294.11 1075.05 2216.77 1026.72C2191.63 1011.25 2166.5 994.822 2142.33 979.357C2132.66 972.591 2122.99 965.825 2113.33 960.025C2101.73 952.292 2087.23 941.66 2075.62 933.927C2064.02 926.195 2049.52 922.328 2037.92 914.596C2028.25 909.763 2019.55 904.93 2009.89 900.097C1984.75 887.531 1961.55 874.966 1938.35 861.434C1858.11 816.971 1783.67 772.508 1712.13 729.012C1566.15 640.086 1435.64 555.994 1308.03 490.266C1248.09 460.302 1189.12 433.238 1130.15 411.973C739.58 272.785 244.605 420.672 126.662 626.554C97.6599 675.85 89.926 729.979 106.361 784.107C115.061 755.11 234.938 1387.25 722.178 1247.1C779.216 1231.63 841.088 1206.5 908.761 1171.71C925.195 1163.01 942.597 1154.31 959.998 1143.68C1083.74 1072.15 1201.68 1001.59 1313.83 932.961C1390.2 886.565 1463.67 839.202 1534.25 792.806C1557.45 778.308 1579.68 762.842 1601.92 749.31C1610.62 743.511 1620.29 738.678 1628.02 731.912C1638.65 723.212 1652.19 718.38 1662.82 709.68C1673.46 700.981 1686.99 688.415 1697.63 679.716C1706.33 672.95 1715.03 665.218 1723.73 657.485C1745.96 638.153 1769.17 618.822 1791.4 600.456C1866.81 537.629 1941.25 476.734 2013.75 420.672C2161.66 306.616 2300.88 212.857 2436.22 151.962C2501.96 121.998 2566.73 99.7669 2630.54 87.2014C2952.46 25.3401 3248.29 180.96 3536.38 670.05Z' stroke='url(#paint43_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3555.72 665.219C3555.72 699.05 4222.77 1633.73 3147.75 1401.75C3078.15 1387.26 3011.44 1370.82 2946.67 1351.49C2774.59 1301.23 2619.91 1237.44 2478.76 1166.88C2389.82 1122.41 2305.71 1076.02 2227.41 1027.69C2201.31 1012.22 2176.17 995.79 2152 979.358C2142.33 972.592 2131.7 965.826 2123 960.027C2111.4 952.294 2096.9 941.662 2085.3 933.929C2072.73 926.196 2059.19 921.364 2046.63 913.631C2036.96 907.831 2027.29 902.998 2017.62 898.166C1992.49 885.6 1968.32 871.101 1945.12 857.569C1863.91 811.173 1788.5 764.777 1716 719.348C1568.09 626.556 1436.61 538.597 1308.03 470.936C1248.09 439.039 1188.15 411.975 1128.22 389.743C737.651 246.689 236.876 404.242 115.066 620.756C86.0633 672.952 77.3626 729.014 93.7973 785.075C101.531 759.944 219.474 1409.49 713.482 1266.43C771.487 1250 833.359 1224.87 901.031 1189.11C917.466 1180.41 934.867 1170.74 952.269 1160.11C1076.98 1085.68 1195.89 1012.22 1309 940.695C1386.34 891.399 1460.78 842.104 1532.32 794.741C1555.52 779.276 1577.75 763.811 1600.96 749.312C1609.66 743.512 1619.32 737.713 1628.02 731.913C1638.66 723.214 1652.19 717.415 1662.83 708.715C1674.43 700.016 1687 687.451 1698.6 678.751C1707.3 671.019 1716 664.253 1725.67 656.52C1748.87 637.188 1771.1 617.857 1794.31 598.525C1870.68 534.731 1946.08 473.836 2018.59 417.774C2167.47 302.751 2308.61 208.992 2444.93 147.131C2511.63 117.167 2576.4 93.9691 2641.18 81.4035C2964.07 15.6759 3260.86 169.362 3555.72 665.219Z' stroke='url(#paint44_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3576.02 659.422C3576.02 688.419 4263.37 1639.54 3169.98 1402.72C3100.38 1388.22 3032.71 1370.83 2966.97 1352.46C2792.95 1302.2 2636.34 1238.4 2494.23 1167.84C2404.32 1123.38 2319.25 1076.99 2239.97 1028.66C2213.87 1013.19 2188.74 996.759 2163.6 980.327C2152.97 973.561 2143.3 966.795 2133.63 960.995C2121.06 953.263 2107.53 942.63 2094.96 934.898C2082.39 927.165 2067.89 921.366 2056.29 913.633C2046.62 907.833 2036.96 903 2027.29 897.201C2002.15 883.669 1977.99 869.17 1953.82 854.671C1871.64 806.342 1795.27 757.047 1722.76 710.651C1573.89 613.992 1441.44 523.134 1310.93 452.573C1250.99 419.709 1191.05 391.678 1130.15 369.447C735.716 221.56 228.174 386.845 103.463 613.992C73.4942 668.121 64.7934 726.116 81.2281 785.077C87.9954 762.846 204.005 1431.72 704.78 1284.8C762.785 1268.37 825.623 1242.27 894.262 1205.54C911.664 1195.87 929.065 1186.21 946.467 1175.58C1072.14 1099.22 1192.02 1021.89 1307.06 947.463C1385.37 896.234 1459.81 845.005 1532.32 794.743C1555.52 778.311 1578.72 761.879 1601.92 746.414C1611.59 740.615 1620.29 733.849 1628.99 728.049C1640.59 719.35 1653.16 712.584 1664.76 703.884C1676.36 694.219 1689.89 682.62 1700.53 673.92C1709.23 666.188 1718.9 658.455 1727.6 650.722C1750.8 631.391 1774 612.059 1797.2 592.728C1874.54 528.933 1949.95 467.072 2024.39 411.01C2174.24 295.987 2316.35 200.295 2453.62 138.434C2520.33 107.503 2586.07 85.2718 2650.84 71.7396C2974.7 5.04545 3273.43 158.732 3576.02 659.422Z' stroke='url(#paint45_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3595.36 653.623C3595.36 677.787 4303.01 1645.34 3191.26 1403.69C3120.68 1389.19 3052.04 1371.79 2986.3 1352.46C2810.36 1301.23 2652.78 1238.41 2508.73 1167.84C2416.89 1123.38 2331.82 1076.99 2251.58 1028.66C2225.48 1013.19 2199.37 996.76 2174.24 980.328C2163.6 973.562 2153.94 966.796 2144.27 960.996C2131.7 953.264 2117.2 942.631 2105.6 934.898C2093.03 927.166 2078.53 921.366 2065.96 912.667C2056.29 906.868 2046.63 901.068 2036.96 896.235C2011.82 881.736 1986.69 867.238 1962.52 851.772C1879.38 801.51 1802.04 750.281 1728.57 700.986C1577.75 600.461 1444.34 505.736 1313.83 433.242C1252.93 399.412 1192.99 370.414 1132.08 347.216C733.785 196.429 220.442 369.448 92.8314 607.227C61.8955 663.289 53.1948 724.183 69.6295 785.078C75.4299 766.713 190.473 1452.99 696.082 1303.17C755.053 1286.73 817.892 1259.67 886.531 1221.01C903.932 1211.34 921.334 1201.68 938.735 1190.08C1065.38 1110.82 1187.19 1031.56 1302.23 953.264C1381.51 900.101 1456.91 845.973 1530.38 794.744C1554.55 778.312 1577.75 760.914 1600.96 744.482C1610.62 737.716 1619.32 731.916 1628.03 725.15C1639.63 715.484 1652.19 708.718 1663.8 700.019C1675.4 690.353 1688.93 678.754 1700.53 669.088C1709.23 661.356 1718.9 653.623 1727.6 645.89C1750.8 626.559 1774.97 607.227 1798.17 587.895C1876.48 523.134 1952.85 462.24 2027.29 405.211C2179.07 289.221 2323.12 193.53 2461.36 130.702C2529.03 99.7712 2594.77 76.5732 2660.51 63.0411C2985.34 -4.6197 3286.96 147.134 3595.36 653.623Z' stroke='url(#paint46_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3614.69 647.825C3614.69 667.156 4342.65 1652.1 3211.55 1404.66C3140.01 1389.19 3071.38 1371.79 3005.64 1352.46C2827.75 1301.23 2668.24 1237.44 2523.23 1167.85C2430.42 1123.38 2344.38 1076.02 2263.17 1028.66C2236.11 1013.19 2210 996.761 2184.87 980.329C2174.23 973.563 2164.57 966.797 2154.9 960.997C2142.33 953.265 2127.83 943.599 2115.26 934.899C2102.69 926.2 2088.19 920.401 2075.63 911.702C2065.96 905.902 2055.32 900.103 2045.66 894.303C2019.55 878.838 1995.39 863.372 1970.25 847.907C1886.14 794.745 1807.84 742.55 1734.36 691.321C1581.62 585.963 1447.24 488.339 1314.8 413.912C1253.89 379.115 1192.99 349.151 1132.08 325.953C731.848 171.3 211.738 353.017 81.227 601.429C50.2911 660.39 40.6236 723.218 57.0583 786.046C61.892 771.547 175.001 1475.22 687.377 1322.5C746.349 1305.1 810.154 1278.04 879.76 1238.41C897.161 1228.74 914.563 1218.11 932.931 1206.51C1061.51 1124.35 1183.32 1042.19 1299.33 960.997C1378.6 905.902 1454.97 849.84 1529.41 795.712C1553.58 778.313 1576.78 760.915 1600.95 743.516C1610.62 736.75 1619.32 729.984 1628.99 723.218C1640.59 713.552 1654.12 705.82 1665.73 696.154C1677.33 686.488 1690.86 674.889 1702.46 665.223C1711.16 657.49 1720.83 649.758 1730.5 642.025C1754.67 622.693 1777.87 602.395 1801.07 584.03C1880.34 519.269 1957.68 457.408 2033.09 400.38C2186.8 283.423 2331.81 187.731 2471.03 123.937C2538.7 93.0064 2606.37 69.8085 2672.11 55.3097C2996.94 -14.2842 3299.53 135.536 3614.69 647.825Z' stroke='url(#paint47_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3634.03 642.024C3634.03 656.523 4381.32 1657.9 3232.83 1404.66C3161.29 1389.19 3091.68 1371.79 3024.98 1352.46C2845.16 1300.27 2683.72 1237.44 2537.74 1167.84C2443.96 1123.38 2356.95 1076.02 2274.78 1027.69C2247.71 1012.23 2221.61 995.793 2195.51 979.361C2184.87 972.595 2175.21 965.829 2164.57 960.03C2151.04 952.297 2137.5 942.631 2124.94 933.932C2111.4 925.233 2097.87 918.467 2084.33 909.767C2074.66 903.968 2064.03 897.202 2054.36 891.402C2028.26 875.937 2003.13 859.505 1977.99 843.073C1892.92 787.978 1814.61 732.883 1739.2 679.721C1585.49 571.463 1450.15 469.972 1317.7 392.646C1255.83 356.882 1194.93 325.952 1133.05 301.787C729.92 144.234 204.01 333.684 70.5985 591.762C38.6958 652.656 29.0284 717.417 45.4631 782.178C49.33 773.479 160.506 1495.52 679.649 1339.9C738.621 1322.5 803.393 1294.47 872.998 1252.9C890.4 1243.24 907.801 1231.64 926.169 1220.04C1055.71 1134.98 1178.49 1049.92 1295.47 965.829C1375.71 907.834 1453.05 850.806 1528.45 794.744C1552.62 776.379 1576.79 758.014 1599.99 740.615C1609.66 733.849 1618.36 727.083 1628.03 719.351C1639.63 709.685 1653.16 700.986 1664.76 691.32C1677.33 681.654 1689.9 670.055 1702.47 660.389C1712.13 652.656 1720.84 644.924 1730.5 637.191C1754.67 616.893 1778.84 597.561 1802.04 578.23C1882.28 512.502 1960.59 450.641 2035.99 392.646C2190.67 274.723 2336.65 178.064 2477.8 114.27C2546.44 82.3728 2614.11 59.1749 2679.85 44.6761C3007.58 -24.9178 3312.1 124.902 3634.03 642.024Z' stroke='url(#paint48_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3653.36 637.195C3653.36 646.861 4420.96 1664.67 3253.13 1406.59C3180.62 1391.13 3111.01 1372.76 3043.34 1353.43C2861.59 1301.24 2698.21 1238.41 2551.27 1167.85C2456.53 1123.39 2368.55 1076.02 2285.41 1027.69C2258.34 1011.26 2231.27 995.797 2205.17 979.365C2194.54 972.599 2183.9 965.833 2174.24 960.033C2160.7 951.334 2147.17 942.635 2133.63 933.935C2120.1 925.236 2106.56 917.504 2093.03 908.804C2082.4 902.038 2072.73 896.239 2062.09 889.473C2035.99 873.041 2009.89 856.609 1984.75 839.21C1898.71 782.182 1819.44 725.154 1744.03 670.059C1589.35 556.968 1452.08 452.578 1318.67 373.318C1256.79 336.588 1194.92 304.69 1133.05 280.526C727.016 120.073 195.305 318.223 58.0271 585.966C26.1244 648.794 15.4902 716.455 31.9249 783.149C33.8584 775.416 144.067 1515.82 669.978 1356.33C730.883 1339.9 795.655 1310.9 866.228 1268.37C883.629 1257.74 901.997 1247.11 919.399 1234.54C1049.91 1147.55 1173.65 1058.62 1291.6 971.632C1372.8 911.704 1451.11 851.776 1526.52 793.781C1550.68 774.449 1574.85 756.084 1599.02 737.719C1608.69 729.987 1618.36 723.221 1627.06 715.488C1639.63 705.822 1652.19 696.156 1663.79 686.49C1676.36 676.825 1688.93 665.226 1701.5 655.56C1711.16 647.827 1720.83 640.094 1729.53 632.362C1753.7 612.064 1777.87 592.732 1802.04 573.4C1883.25 507.673 1961.55 444.845 2038.89 386.85C2195.5 268.927 2342.45 171.302 2484.56 105.574C2554.17 73.6773 2621.84 49.5127 2688.55 35.014C3018.21 -34.5799 3324.67 113.307 3653.36 637.195Z' stroke='url(#paint49_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3673.66 631.391C3673.66 636.224 4461.56 1671.43 3275.36 1407.56C3201.89 1391.12 3131.32 1373.73 3063.64 1354.39C2879.96 1302.2 2715.61 1238.4 2566.74 1168.81C2471.03 1124.35 2382.09 1076.99 2297.98 1028.66C2269.94 1012.22 2242.88 996.759 2216.77 980.327C2206.14 973.561 2195.5 967.761 2184.87 960.995C2171.34 952.296 2156.83 943.597 2144.27 934.897C2130.73 926.198 2116.23 917.499 2102.7 908.8C2092.06 902.034 2082.4 895.268 2071.76 888.502C2045.66 871.103 2019.56 853.705 1993.45 836.306C1906.45 777.345 1826.21 718.383 1749.83 661.355C1593.22 544.398 1455.94 437.108 1320.6 354.948C1257.76 317.251 1196.86 284.388 1134.02 259.257C725.083 94.9376 186.605 301.786 47.3932 580.162C15.4906 645.889 3.88959 715.483 21.291 785.077C22.2578 781.211 131.5 1539.01 663.211 1376.63C723.149 1358.26 788.888 1328.3 859.461 1284.8C876.862 1274.17 895.23 1262.57 913.598 1250C1045.08 1160.11 1169.79 1068.29 1289.66 978.394C1371.84 916.532 1450.14 854.671 1526.52 794.743C1551.65 775.411 1575.82 756.08 1599.99 736.748C1609.66 729.015 1619.32 721.283 1628.99 714.517C1641.56 704.851 1654.13 695.185 1666.69 684.553C1679.26 673.92 1691.83 663.288 1704.4 653.622C1714.06 645.889 1723.73 638.157 1733.4 630.424C1757.57 610.126 1782.7 590.794 1806.87 571.463C1889.05 504.768 1968.32 441.941 2045.66 383.946C2203.24 265.056 2352.12 166.465 2495.2 100.737C2564.8 68.8398 2633.44 44.6753 2701.11 29.21C3029.81 -45.2168 3338.2 102.67 3673.66 631.391Z' stroke='url(#paint50_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M8.72248 785.078C8.72248 785.078 147.934 1792.26 905.864 1264.5C2184.87 374.281 2839.36 -707.324 3692.03 625.592C3692.03 625.592 4500.23 1677.23 3295.66 1408.52C2091.09 1139.81 1643.49 443.875 1135.95 237.993C628.407 32.1109 -82.1517 406.178 8.72248 785.078Z' stroke='url(#paint51_linear_14299_3629)' stroke-miterlimit='10'/>\n<defs>\n<linearGradient id='paint0_linear_14299_3629' x1='1569.05' y1='466.105' x2='1569.05' y2='1359.23' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint1_linear_14299_3629' x1='1577.72' y1='456.443' x2='1577.72' y2='1359.35' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint2_linear_14299_3629' x1='1586.47' y1='447.721' x2='1586.47' y2='1360.54' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint3_linear_14299_3629' x1='1593.22' y1='439.921' x2='1593.22' y2='1362.81' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint4_linear_14299_3629' x1='1603.02' y1='430.218' x2='1603.02' y2='1364.29' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint5_linear_14299_3629' x1='1610.25' y1='421.466' x2='1610.25' y2='1365.74' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint6_linear_14299_3629' x1='1619.17' y1='415.341' x2='1619.17' y2='1367.25' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint7_linear_14299_3629' x1='1626.48' y1='405.586' x2='1626.48' y2='1368.11' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint8_linear_14299_3629' x1='1635.32' y1='394.952' x2='1635.32' y2='1370.66' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint9_linear_14299_3629' x1='1641.92' y1='386.153' x2='1641.92' y2='1372.29' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint10_linear_14299_3629' x1='1650.93' y1='377.249' x2='1650.93' y2='1373.93' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint11_linear_14299_3629' x1='1658.32' y1='369.154' x2='1658.32' y2='1375.77' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint12_linear_14299_3629' x1='1665.62' y1='358.627' x2='1665.62' y2='1377.45' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint13_linear_14299_3629' x1='1675.76' y1='348.825' x2='1675.76' y2='1378.37' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint14_linear_14299_3629' x1='1682.56' y1='341.474' x2='1682.56' y2='1381.24' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint15_linear_14299_3629' x1='1690.7' y1='333.392' x2='1690.7' y2='1382.98' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint16_linear_14299_3629' x1='1698.83' y1='325.886' x2='1698.83' y2='1384.72' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint17_linear_14299_3629' x1='1706.39' y1='315.222' x2='1706.39' y2='1386.46' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint18_linear_14299_3629' x1='1714.88' y1='304.746' x2='1714.88' y2='1388.43' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint19_linear_14299_3629' x1='1722.24' y1='296.393' x2='1722.24' y2='1389.46' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint20_linear_14299_3629' x1='1730.63' y1='286.769' x2='1730.63' y2='1391.28' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint21_linear_14299_3629' x1='1738.78' y1='277.861' x2='1738.78' y2='1393.07' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint22_linear_14299_3629' x1='1745.64' y1='272.432' x2='1745.64' y2='1396.04' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint23_linear_14299_3629' x1='1755.52' y1='261.044' x2='1755.52' y2='1397.83' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint24_linear_14299_3629' x1='1763.16' y1='253.537' x2='1763.16' y2='1399.63' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint25_linear_14299_3629' x1='1770.42' y1='242.886' x2='1770.42' y2='1400.95' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint26_linear_14299_3629' x1='1779.51' y1='231.741' x2='1779.51' y2='1402.76' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint27_linear_14299_3629' x1='1786.48' y1='222.551' x2='1786.48' y2='1404.57' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint28_linear_14299_3629' x1='1795.3' y1='214.967' x2='1795.3' y2='1407.35' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint29_linear_14299_3629' x1='1801.57' y1='205.016' x2='1801.57' y2='1409.41' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint30_linear_14299_3629' x1='1809.73' y1='195.08' x2='1809.73' y2='1410.52' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint31_linear_14299_3629' x1='1818.93' y1='186.06' x2='1818.93' y2='1412.35' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint32_linear_14299_3629' x1='1827.12' y1='177.469' x2='1827.12' y2='1414.41' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint33_linear_14299_3629' x1='1835.07' y1='169.093' x2='1835.07' y2='1416.24' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint34_linear_14299_3629' x1='1843.87' y1='158.435' x2='1843.87' y2='1419.04' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint35_linear_14299_3629' x1='1850.78' y1='148.741' x2='1850.78' y2='1420.85' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint36_linear_14299_3629' x1='1859.19' y1='140.057' x2='1859.19' y2='1422.23' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint37_linear_14299_3629' x1='1866.24' y1='129.672' x2='1866.24' y2='1424.07' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint38_linear_14299_3629' x1='1876.16' y1='121' x2='1876.16' y2='1425.91' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint39_linear_14299_3629' x1='1883.4' y1='113.179' x2='1883.4' y2='1428.71' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint40_linear_14299_3629' x1='1890.83' y1='102.564' x2='1890.83' y2='1430.81' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint41_linear_14299_3629' x1='1899.49' y1='92.8153' x2='1899.49' y2='1432.65' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint42_linear_14299_3629' x1='1907.17' y1='84.9469' x2='1907.17' y2='1433.81' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint43_linear_14299_3629' x1='1915.36' y1='74.3203' x2='1915.36' y2='1435.9' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint44_linear_14299_3629' x1='1922.92' y1='67.025' x2='1922.92' y2='1438.71' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint45_linear_14299_3629' x1='1931.15' y1='57.0142' x2='1931.15' y2='1440.56' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint46_linear_14299_3629' x1='1939.4' y1='47.8563' x2='1939.4' y2='1442.41' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint47_linear_14299_3629' x1='1947.19' y1='39.2848' x2='1947.19' y2='1444.51' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint48_linear_14299_3629' x1='1955.28' y1='28.6678' x2='1955.28' y2='1445.68' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint49_linear_14299_3629' x1='1962.62' y1='18.9098' x2='1962.62' y2='1448.5' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint50_linear_14299_3629' x1='1971.67' y1='11.2063' x2='1971.67' y2='1450.61' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint51_linear_14299_3629' x1='1979.09' y1='0.921875' x2='1979.09' y2='1452.46' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n</defs>\n</svg>\n`,\n  lightSvg: `<svg id='bgAlpha' width='3958' height='1453' viewBox='0 0 3958 1453' fill='none' xmlns='http://www.w3.org/2000/svg'>\n<path d='M2135.57 466.105C2094 466.105 2052.43 474.805 2009.89 492.203C1925.78 526.034 1840.71 588.861 1754.67 671.988C1711.17 714.517 1670.56 758.98 1633.83 804.409C1622.23 818.908 1610.62 833.407 1599.02 847.906C1593.22 855.638 1588.39 862.404 1585.49 865.304L1569.05 888.502L1552.62 865.304C1549.72 861.438 1545.85 855.638 1539.09 847.906C1527.48 833.407 1515.88 818.908 1504.28 804.409C1467.55 758.98 1426.94 714.517 1383.44 671.988C1297.4 587.895 1212.32 525.067 1128.22 492.203C1085.68 475.771 1044.11 466.105 1002.54 466.105C739.586 466.105 524.001 664.255 524.001 912.667C524.001 1161.08 739.586 1359.23 1002.54 1359.23C1044.11 1359.23 1085.68 1350.53 1128.22 1333.13C1212.32 1299.3 1297.4 1236.47 1383.44 1153.35C1426.94 1110.82 1467.55 1066.35 1504.28 1020.92C1515.88 1006.43 1527.48 991.926 1539.09 977.428C1544.89 969.695 1549.72 962.929 1552.62 960.029L1569.05 936.831L1585.49 960.029C1588.39 963.895 1592.26 969.695 1599.02 977.428C1610.62 991.926 1622.23 1006.43 1633.83 1020.92C1670.56 1066.35 1711.17 1110.82 1754.67 1153.35C1840.71 1237.44 1925.78 1300.27 2009.89 1333.13C2052.43 1349.56 2094 1359.23 2135.57 1359.23C2398.52 1359.23 2614.11 1161.08 2614.11 912.667C2614.11 664.255 2398.52 466.105 2135.57 466.105Z' stroke='url(#paint0_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M2637.31 906.87C2640.21 1150.45 2442.02 1365.03 2160.7 1359.23C2119.13 1359.23 2076.59 1349.56 2033.09 1333.13C1947.05 1299.3 1860.04 1236.47 1773.04 1153.35C1728.57 1110.82 1687 1066.36 1649.29 1020.93C1636.72 1006.43 1625.12 991.93 1613.52 977.431C1606.76 969.698 1602.89 962.932 1599.99 960.032L1582.59 936.834L1565.19 959.066C1562.29 961.965 1558.42 967.765 1551.65 975.498C1540.05 989.996 1528.45 1003.53 1515.88 1017.06C1478.18 1059.59 1436.61 1103.09 1393.1 1143.68C1306.1 1223.91 1220.06 1282.87 1134.98 1313.8C1092.45 1329.27 1049.91 1337.97 1008.34 1337C742.484 1334.1 521.099 1143.68 518.199 905.904C517.232 864.341 523.999 825.677 536.567 787.981C595.538 605.297 776.32 488.34 999.639 484.474C1041.21 484.474 1083.75 492.206 1126.28 507.672C1137.88 511.538 1149.48 516.371 1161.09 522.17C1234.56 555.034 1309 609.163 1384.4 677.79C1427.91 718.387 1469.48 760.916 1507.18 803.446C1518.78 816.978 1531.35 830.51 1542.95 845.009C1549.72 852.742 1553.58 858.541 1556.48 861.441L1573.89 883.672L1591.29 860.474C1594.19 856.608 1598.05 850.808 1604.82 843.076C1616.42 828.577 1628.02 813.112 1640.59 798.613C1678.29 753.184 1719.86 707.754 1763.37 665.225C1850.38 580.165 1936.42 517.338 2022.46 483.507C2065.96 466.109 2107.53 457.409 2149.1 456.443C2413.02 456.443 2633.44 652.659 2637.31 906.87Z' stroke='url(#paint1_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M2660.51 901.062C2666.31 1138.84 2485.53 1370.82 2185.84 1360.19C2143.3 1359.22 2100.77 1350.52 2057.26 1333.12C1969.29 1299.29 1881.32 1235.5 1792.37 1152.37C1746.94 1109.84 1704.4 1064.41 1665.73 1019.95C1653.16 1005.45 1640.6 990.955 1628.99 976.456C1622.23 968.723 1618.36 961.957 1615.46 959.057C1614.49 959.057 1598.06 935.859 1598.06 935.859C1597.09 935.859 1580.66 958.091 1580.66 957.124C1577.76 960.024 1572.92 965.824 1567.12 973.556C1555.52 987.088 1542.95 1000.62 1530.39 1013.19C1491.72 1053.78 1449.18 1095.35 1404.71 1133.04C1315.77 1209.4 1228.76 1264.5 1142.72 1293.49C1099.22 1307.99 1056.68 1315.73 1015.11 1314.76C746.354 1307.99 519.169 1126.28 512.401 899.129C511.435 860.466 517.235 822.769 529.803 787.972C588.774 610.121 766.656 509.597 996.742 502.831C1038.31 501.864 1081.82 509.597 1125.32 524.095C1136.92 527.962 1148.52 532.795 1161.09 537.628C1236.49 568.558 1311.9 619.787 1387.31 684.548C1431.78 723.211 1474.31 763.808 1512.98 804.404C1525.55 816.97 1537.15 830.502 1548.75 844.034C1555.52 851.767 1559.39 856.6 1562.29 859.499C1563.26 859.499 1579.69 880.764 1579.69 880.764C1580.66 880.764 1597.09 857.566 1597.09 856.6C1599.99 852.733 1604.83 846.934 1610.63 839.201C1622.23 823.736 1634.79 809.237 1646.4 794.738C1685.07 749.309 1727.6 702.913 1772.07 660.383C1861.01 575.324 1948.02 510.563 2035.03 475.766C2078.53 458.368 2121.07 448.702 2163.61 447.735C2428.49 445.802 2653.75 642.018 2660.51 901.062Z' stroke='url(#paint2_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M2683.71 896.235C2692.41 1129.18 2528.07 1377.59 2210.01 1362.13C2166.5 1361.16 2123 1351.5 2079.5 1334.1C1989.59 1299.3 1899.68 1236.47 1809.77 1153.35C1763.37 1110.82 1719.87 1065.39 1680.23 1020.92C1667.66 1006.43 1655.09 991.927 1642.53 976.461C1635.76 968.729 1630.93 962.929 1628.03 959.063C1627.06 958.096 1610.62 935.865 1609.66 935.865C1608.69 934.898 1592.26 957.13 1591.29 956.163C1588.39 959.063 1583.56 963.896 1576.79 971.628C1565.19 985.161 1552.62 996.76 1539.08 1009.33C1499.45 1047.99 1455.94 1086.65 1411.47 1123.38C1321.57 1194.91 1233.59 1247.1 1146.59 1274.17C1103.08 1287.7 1059.58 1294.47 1017.04 1292.53C745.386 1282.87 512.4 1108.88 502.732 892.369C500.799 855.639 507.566 820.842 519.167 787.011C579.105 613.026 754.086 529.9 989.006 520.235C1031.54 519.268 1075.05 526.034 1118.55 539.566C1130.15 543.432 1142.72 547.299 1154.32 552.132C1230.69 581.129 1307.07 628.492 1383.44 690.353C1428.88 727.083 1471.41 764.78 1511.05 803.443C1523.62 816.009 1536.18 828.574 1547.79 841.14C1554.55 847.906 1559.39 853.705 1562.29 856.605C1563.25 855.639 1579.69 877.87 1580.65 876.903C1581.62 875.937 1598.06 853.705 1599.02 852.739C1601.92 848.872 1606.76 843.073 1613.52 835.34C1625.13 819.875 1637.69 805.376 1650.26 790.878C1689.9 744.482 1732.43 698.086 1777.87 655.556C1867.78 569.53 1956.72 504.769 2044.69 469.006C2089.16 451.607 2132.67 440.975 2175.2 440.008C2442.99 435.175 2674.05 630.425 2683.71 896.235Z' stroke='url(#paint3_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M2707.87 890.438C2719.47 1118.55 2572.53 1384.36 2236.1 1363.1C2192.6 1362.13 2148.13 1352.46 2103.66 1335.07C2011.82 1300.27 1919.98 1236.47 1829.1 1154.31C1781.73 1111.79 1737.26 1066.36 1696.66 1020.93C1683.12 1006.43 1670.55 991.929 1657.99 976.464C1651.22 968.731 1646.39 962.931 1643.49 959.065C1642.52 958.099 1626.08 935.867 1625.12 935.867C1624.15 934.901 1607.72 956.165 1606.75 955.199C1603.85 958.099 1599.02 962.931 1592.25 969.698C1579.68 982.263 1567.11 993.862 1554.55 1005.46C1513.94 1042.19 1469.47 1078.92 1424.03 1112.75C1333.16 1180.41 1243.25 1229.71 1155.28 1253.87C1110.81 1266.44 1067.3 1272.24 1024.77 1270.3C750.212 1256.77 511.425 1091.49 497.891 885.605C495.957 850.808 501.758 818.911 513.359 787.014C574.264 617.862 745.378 551.167 987.065 538.602C1029.6 536.669 1073.11 542.468 1118.54 555.034C1130.14 557.934 1142.71 562.766 1155.28 566.633C1232.62 592.731 1309.96 638.16 1388.26 696.155C1433.7 730.952 1478.17 766.715 1517.81 803.445C1530.38 815.044 1543.91 826.643 1555.51 839.209C1562.28 845.975 1567.11 850.808 1570.01 853.708C1570.98 852.741 1587.41 874.006 1588.38 873.039C1589.35 872.073 1605.78 849.841 1606.75 848.875C1609.65 845.008 1614.48 839.209 1621.25 830.51C1633.82 815.044 1646.39 800.546 1658.95 785.08C1699.56 738.684 1743.06 692.288 1789.46 648.792C1881.31 561.8 1971.21 496.072 2060.15 460.309C2104.62 441.944 2149.09 432.278 2191.63 430.345C2457.49 424.545 2694.34 618.828 2707.87 890.438Z' stroke='url(#paint4_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M2731.08 884.632C2744.62 1107.91 2616.04 1390.15 2261.24 1364.06C2216.77 1362.12 2172.3 1352.46 2126.86 1335.06C2033.09 1299.3 1940.28 1236.47 1847.47 1154.31C1799.14 1111.78 1753.7 1066.35 1712.13 1020.92C1698.6 1006.42 1685.06 991.923 1672.49 976.458C1665.73 968.725 1660.89 962.925 1657.99 959.059C1657.03 958.092 1639.62 935.861 1638.66 934.894C1637.69 933.928 1620.29 954.226 1619.32 953.26C1616.42 956.159 1611.59 960.992 1604.82 966.792C1592.25 978.391 1578.72 989.99 1566.15 1000.62C1524.58 1035.42 1480.11 1070.22 1432.74 1102.11C1339.93 1165.91 1249.06 1211.34 1160.12 1233.57C1115.65 1245.17 1072.14 1250 1028.64 1247.1C751.184 1230.67 506.597 1073.12 489.195 877.866C486.295 845.002 492.095 815.038 503.696 786.041C565.568 620.755 732.815 572.426 981.269 555.994C1023.81 554.061 1068.28 558.894 1113.71 570.493C1126.28 573.393 1137.88 577.259 1150.45 581.125C1228.76 605.29 1307.06 646.853 1386.34 701.948C1432.74 734.812 1478.18 768.642 1518.78 802.473C1532.31 813.105 1544.88 824.704 1557.45 836.303C1564.22 843.069 1569.05 847.902 1571.95 849.835C1572.92 848.869 1589.35 869.167 1591.29 868.2C1592.25 867.234 1608.69 845.002 1610.62 844.036C1613.52 840.169 1618.36 834.37 1625.12 825.671C1637.69 810.205 1650.26 795.707 1663.79 780.241C1705.36 732.879 1749.83 686.483 1796.24 642.02C1889.04 555.028 1980.89 488.333 2070.79 451.603C2116.23 433.238 2160.7 422.606 2204.2 421.639C2471.99 414.873 2713.68 607.223 2731.08 884.632Z' stroke='url(#paint5_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M2754.28 878.833C2769.75 1097.28 2659.54 1395.95 2285.41 1365.02C2240.94 1363.09 2195.51 1352.46 2150.07 1336.03C2054.36 1300.26 1959.62 1236.47 1865.84 1155.28C1816.54 1112.75 1770.14 1067.32 1727.6 1021.89C1714.07 1007.39 1700.53 992.89 1687 977.425C1680.23 969.692 1675.4 963.893 1671.53 960.026C1669.59 959.06 1653.16 936.828 1652.19 935.862C1650.26 934.895 1633.83 954.227 1632.86 953.26C1628.99 955.193 1624.16 960.026 1617.39 965.826C1604.82 977.425 1591.29 988.057 1577.75 997.723C1535.22 1030.59 1489.78 1062.48 1442.41 1093.41C1348.63 1153.34 1256.79 1194.91 1166.89 1215.2C1121.45 1224.87 1077.95 1229.7 1034.44 1226.8C754.085 1207.47 503.698 1056.68 483.396 873.034C480.496 843.07 486.297 815.039 496.931 787.975C560.736 627.522 723.15 595.625 978.371 576.293C1021.87 574.36 1066.34 578.226 1112.75 587.892C1125.32 590.792 1136.92 593.692 1149.48 597.558C1228.76 618.823 1308.03 658.453 1388.27 709.682C1435.64 740.612 1481.08 771.543 1522.65 804.407C1536.18 815.039 1549.72 824.705 1562.29 836.304C1569.05 842.103 1573.89 846.936 1576.79 848.869C1578.72 847.903 1595.16 867.234 1596.12 866.268C1598.06 865.301 1614.49 843.07 1615.46 842.103C1618.36 838.237 1624.16 831.471 1629.96 823.738C1642.53 808.273 1656.06 792.808 1669.59 778.309C1712.13 730.946 1757.57 683.584 1803.97 639.121C1898.71 551.162 1990.55 483.501 2082.4 446.771C2127.83 428.406 2173.27 416.807 2217.74 415.841C2487.46 404.242 2733.98 595.625 2754.28 878.833Z' stroke='url(#paint6_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M2777.48 873.034C2794.89 1086.65 2702.08 1402.72 2310.55 1365.02C2265.11 1363.09 2218.7 1352.46 2173.27 1335.06C2075.63 1298.33 1979.92 1235.5 1884.21 1154.31C1833.94 1111.78 1786.57 1066.35 1743.06 1020.92C1728.56 1006.42 1715.03 991.924 1701.49 976.458C1694.73 968.726 1689.89 962.926 1686.03 959.06C1684.09 958.093 1667.66 936.828 1665.73 934.895C1663.79 933.929 1647.36 952.294 1645.42 951.327C1641.56 953.26 1636.72 958.093 1629.96 963.893C1617.39 974.525 1602.89 984.191 1589.35 993.857C1545.85 1024.79 1499.44 1054.75 1451.11 1082.78C1355.4 1138.84 1262.59 1176.54 1171.72 1194.91C1126.28 1203.6 1081.81 1207.47 1037.34 1203.61C754.083 1182.34 497.895 1040.25 474.693 866.268C470.826 838.237 476.627 813.106 487.261 787.975C552.033 632.355 711.546 616.89 971.601 594.658C1015.1 591.759 1060.54 595.625 1106.95 604.324C1119.51 606.257 1132.08 610.124 1144.65 613.023C1225.86 632.355 1305.13 668.118 1386.34 716.448C1434.67 745.445 1481.08 774.443 1523.61 804.407C1537.15 814.072 1550.68 823.738 1563.25 833.404C1570.02 839.204 1574.85 843.07 1578.72 845.003C1580.65 844.036 1597.09 862.401 1598.05 861.435C1599.99 860.468 1616.42 838.237 1618.35 837.27C1622.22 833.404 1627.06 826.638 1633.82 818.905C1647.36 803.44 1659.92 787.975 1673.46 772.509C1716.96 724.18 1762.4 676.818 1810.74 632.355C1906.45 543.429 2000.22 475.769 2093.03 438.072C2139.43 418.74 2184.87 408.108 2229.34 406.175C2501.96 393.609 2753.32 583.059 2777.48 873.034Z' stroke='url(#paint7_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M2800.69 868.203C2820.03 1076.02 2745.59 1409.49 2335.69 1366.96C2289.28 1364.06 2242.88 1353.43 2196.47 1337C2096.9 1300.27 1999.26 1237.44 1902.58 1156.24C1851.34 1112.75 1803.01 1068.29 1758.54 1022.86C1744.04 1008.36 1729.53 993.858 1716 978.393C1709.23 970.66 1703.43 964.861 1699.57 960.995C1697.63 960.028 1681.2 938.763 1679.26 936.83C1677.33 935.864 1660.9 954.229 1658.96 952.295C1655.1 954.229 1650.26 958.095 1643.49 963.894C1629.96 974.527 1616.43 983.226 1601.92 991.925C1557.45 1020.92 1510.08 1048.95 1461.75 1075.05C1365.07 1127.25 1271.3 1162.04 1179.46 1177.51C1134.02 1185.24 1088.58 1188.14 1044.11 1184.28C757.954 1158.18 495.966 1023.82 468.897 860.47C464.063 834.372 469.864 812.141 480.498 787.976C547.204 637.19 701.883 638.156 968.705 612.058C1013.18 609.159 1058.61 612.058 1105.98 618.825C1118.55 620.758 1131.12 623.657 1143.69 626.557C1225.86 642.989 1307.07 676.819 1388.27 721.282C1436.61 747.38 1483.98 775.411 1527.48 803.442C1541.02 812.141 1555.52 820.84 1568.09 830.506C1574.86 836.306 1579.69 840.172 1583.56 841.138C1585.49 839.205 1601.92 857.57 1603.86 855.637C1605.79 853.704 1622.23 832.439 1624.16 830.506C1628.03 826.64 1632.86 819.874 1639.63 812.141C1653.16 796.676 1666.7 781.21 1680.23 765.745C1724.7 717.416 1771.11 669.087 1819.44 624.624C1917.08 534.732 2011.82 466.105 2105.6 428.408C2152 409.076 2198.41 397.477 2243.84 395.544C2516.47 382.978 2773.62 571.462 2800.69 868.203Z' stroke='url(#paint8_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M2823.89 862.405C2844.19 1065.39 2789.09 1415.29 2359.85 1367.93C2313.45 1365.03 2266.08 1354.4 2218.71 1337C2117.2 1300.27 2017.63 1236.47 1919.98 1156.25C1867.78 1112.75 1818.48 1068.29 1773.04 1022.86C1758.54 1008.36 1744.04 993.86 1729.54 978.395C1722.77 970.662 1716.97 964.863 1713.1 960.03C1710.2 958.096 1694.73 937.798 1691.83 935.865C1688.93 933.932 1673.46 952.297 1670.56 950.364C1666.7 952.297 1661.86 956.163 1654.13 960.996C1640.59 970.662 1626.09 979.361 1611.59 987.094C1566.16 1014.16 1517.82 1040.26 1468.51 1064.42C1369.91 1112.75 1275.16 1143.68 1182.36 1157.21C1135.95 1163.98 1090.52 1165.91 1046.05 1161.08C756.988 1131.11 489.199 1005.46 458.263 852.739C453.429 828.574 458.263 808.276 468.897 787.011C537.536 642.024 687.382 659.423 960.971 629.458C1005.44 626.559 1051.85 627.525 1099.22 634.291C1111.78 636.225 1124.35 638.158 1137.89 641.057C1221.03 655.556 1303.2 685.52 1386.34 727.083C1435.64 751.248 1483.98 776.379 1528.45 802.477C1542.95 811.176 1556.49 818.909 1570.02 827.608C1576.79 832.441 1582.59 836.307 1585.49 838.24C1587.42 836.307 1603.86 853.706 1605.79 851.772C1607.73 849.839 1624.16 828.574 1626.09 826.641C1629.96 822.775 1634.79 816.009 1641.56 808.276C1655.1 792.811 1669.6 777.346 1683.13 761.88C1728.57 712.585 1775.94 665.222 1825.24 619.793C1923.85 529.9 2020.53 460.307 2115.27 420.677C2162.64 401.345 2209.04 388.779 2255.45 386.846C2530.97 373.314 2792.96 558.898 2823.89 862.405Z' stroke='url(#paint9_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M2847.09 856.608C2868.36 1054.76 2832.59 1421.09 2384.98 1368.9C2337.61 1366 2290.24 1354.4 2241.91 1337C2137.5 1299.3 2037.92 1236.48 1938.35 1156.25C1885.18 1112.75 1833.94 1068.29 1788.5 1021.89C1773.03 1007.4 1758.53 992.896 1744.03 977.431C1737.26 969.698 1731.46 963.899 1727.6 959.066C1724.7 957.133 1708.26 936.835 1706.33 934.901C1703.43 932.968 1686.99 950.367 1685.06 948.434C1681.19 949.4 1675.39 953.266 1668.62 958.099C1655.09 966.799 1639.62 974.531 1625.12 982.264C1578.72 1007.4 1529.41 1030.59 1480.11 1052.82C1380.53 1097.29 1284.83 1124.35 1190.08 1135.95C1143.68 1141.75 1097.28 1142.72 1052.81 1137.88C760.849 1105.02 488.226 986.13 452.457 845.009C446.656 822.778 452.457 805.379 462.124 786.048C533.664 645.893 677.709 679.724 958.066 646.86C1002.54 642.994 1049.91 643.96 1097.28 649.76C1109.84 650.726 1123.38 653.626 1135.95 655.559C1220.05 667.158 1303.19 695.189 1387.3 732.886C1437.57 755.117 1485.91 778.315 1531.35 801.513C1545.85 809.246 1560.35 816.012 1573.88 824.711C1580.65 829.544 1586.45 833.41 1590.32 834.377C1593.22 832.444 1608.69 848.876 1611.59 846.942C1614.49 845.009 1629.95 823.744 1632.86 821.811C1636.72 817.945 1642.52 811.179 1649.29 803.446C1662.82 787.014 1677.33 771.549 1691.83 757.05C1738.23 707.755 1786.57 659.425 1835.87 613.996C1936.41 523.137 2034.05 453.543 2129.76 412.947C2178.1 392.649 2224.5 381.05 2270.91 378.15C2545.46 362.685 2813.25 547.302 2847.09 856.608Z' stroke='url(#paint10_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M2870.29 850.81C2892.52 1044.13 2875.12 1427.86 2410.12 1369.87C2361.78 1366 2313.44 1355.37 2266.07 1337.97C2159.73 1300.27 2058.22 1236.48 1957.68 1156.25C1903.54 1112.75 1851.34 1068.29 1803.97 1021.9C1788.5 1007.4 1773.03 992.898 1759.5 977.433C1751.76 969.7 1746.93 963.901 1742.1 959.068C1739.2 957.134 1722.76 936.836 1719.86 934.903C1716.96 932.97 1700.53 949.402 1697.63 947.469C1693.76 948.435 1687.96 952.302 1680.22 957.134C1665.72 965.834 1651.22 972.6 1635.75 979.366C1588.38 1002.56 1538.11 1023.83 1487.84 1044.13C1387.3 1084.72 1289.66 1107.92 1194.92 1117.59C1147.55 1122.42 1102.11 1122.42 1055.71 1116.62C760.848 1080.86 482.425 968.733 443.755 839.211C437.955 818.913 438.921 802.481 452.456 787.016C497.893 641.062 666.107 701.957 952.264 666.193C997.701 662.327 1045.07 662.327 1093.41 666.193C1105.98 667.16 1119.51 669.093 1132.08 671.026C1218.12 680.692 1301.26 705.823 1386.33 739.653C1437.57 759.952 1486.87 780.25 1532.31 802.481C1546.81 809.247 1562.28 816.013 1575.82 823.746C1582.58 827.612 1588.38 831.479 1592.25 832.445C1595.15 830.512 1610.62 845.977 1613.52 844.044C1616.42 842.111 1631.89 820.846 1634.79 818.913C1638.65 814.08 1644.45 808.281 1651.22 800.548C1665.72 784.116 1680.22 768.651 1694.73 753.186C1741.13 703.89 1790.43 654.594 1841.67 609.165C1943.18 517.34 2042.75 446.779 2139.43 406.183C2187.77 385.884 2235.14 373.319 2282.51 370.419C2559.96 352.054 2832.59 534.738 2870.29 850.81Z' stroke='url(#paint11_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M2892.53 845.007C2915.73 1033.49 2917.67 1433.66 2433.33 1370.83C2384.99 1366.96 2335.68 1355.36 2287.35 1337.96C2179.07 1299.3 2075.63 1236.47 1974.12 1156.25C1919.02 1112.75 1865.85 1068.29 1817.51 1021.89C1802.04 1007.39 1786.57 991.928 1772.07 977.429C1764.34 969.696 1758.54 963.897 1754.67 959.064C1751.77 957.131 1735.33 936.833 1732.43 934.899C1729.53 932.966 1713.1 948.432 1709.23 946.498C1704.4 947.465 1699.56 951.331 1691.83 955.198C1677.33 962.93 1661.86 969.696 1646.39 975.496C1598.06 996.761 1547.79 1016.09 1496.55 1034.46C1394.07 1071.19 1296.43 1091.49 1199.76 1097.29C1152.39 1100.18 1105.98 1100.18 1059.58 1094.39C761.82 1054.76 478.564 951.331 435.06 832.442C428.293 815.043 429.259 799.578 442.794 787.012C487.264 643.958 653.545 723.218 945.502 684.555C990.939 679.722 1038.31 679.722 1087.61 682.621C1100.18 683.588 1113.72 684.555 1127.25 685.521C1214.26 692.287 1299.33 714.519 1384.41 745.449C1436.61 763.814 1486.88 782.179 1533.28 801.511C1547.79 807.311 1563.25 813.11 1576.79 820.843C1584.52 824.709 1589.36 827.609 1593.22 828.575C1596.12 825.676 1612.56 842.107 1615.46 839.208C1618.36 836.308 1634.79 816.01 1637.69 814.077C1641.56 809.244 1647.36 803.444 1654.13 794.745C1668.63 778.313 1683.13 762.848 1697.63 747.382C1745 697.12 1795.27 647.824 1846.51 601.429C1949.95 509.603 2049.53 438.076 2148.14 396.513C2197.44 376.215 2245.78 362.683 2293.15 359.783C2574.47 342.385 2851.93 522.169 2892.53 845.007Z' stroke='url(#paint12_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M2915.72 839.209C2939.89 1021.89 2961.16 1439.46 2458.45 1370.83C2409.15 1366.96 2359.85 1355.36 2310.54 1337.97C2200.33 1299.3 2095.92 1235.51 1992.48 1156.25C1936.41 1112.75 1882.27 1067.32 1832.97 1021.89C1817.5 1007.39 1801.07 991.929 1786.56 977.43C1778.83 969.698 1773.03 963.898 1769.16 959.065C1765.3 957.132 1749.83 936.834 1745.96 934.901C1742.09 932.968 1726.63 947.466 1722.76 945.533C1717.93 946.5 1712.12 949.399 1705.36 953.266C1690.86 960.998 1674.42 965.831 1659.92 971.631C1610.62 989.996 1559.38 1007.39 1507.17 1023.83C1403.73 1055.72 1304.16 1073.12 1207.48 1076.99C1160.11 1078.92 1112.74 1077.95 1066.34 1071.19C765.68 1028.66 476.622 931.034 430.219 824.71C423.451 809.245 423.451 796.679 436.986 785.08C480.489 645.893 644.836 743.517 943.561 700.988C989.965 696.155 1037.34 694.222 1087.61 696.155C1101.14 696.155 1113.71 698.088 1127.24 698.088C1215.22 702.921 1301.26 722.253 1388.26 749.317C1441.44 765.749 1491.71 782.181 1539.08 799.579C1554.55 805.379 1570.01 810.212 1583.55 816.978C1591.28 820.844 1596.12 823.744 1600.95 823.744C1603.85 820.844 1620.28 836.309 1623.18 833.41C1626.08 830.51 1642.52 810.212 1645.42 808.278C1649.29 803.446 1655.09 797.646 1662.82 788.947C1677.32 772.515 1692.79 757.05 1707.29 741.584C1755.63 691.322 1806.87 641.06 1859.07 594.664C1963.48 501.872 2064.99 429.378 2164.56 387.815C2213.87 366.55 2263.17 353.985 2310.54 350.118C2588 331.753 2871.25 509.605 2915.72 839.209Z' stroke='url(#paint13_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M2937.97 834.375C2963.1 1012.23 3003.71 1447.19 2482.63 1372.76C2432.36 1367.93 2383.06 1356.33 2332.78 1338.93C2220.64 1299.3 2114.3 1236.47 2009.89 1157.21C1952.85 1113.72 1897.75 1068.29 1847.48 1022.86C1831.04 1008.36 1815.58 992.894 1800.11 977.429C1792.37 969.696 1786.57 963.897 1781.74 959.064C1777.87 957.131 1761.44 936.832 1758.54 934.899C1754.67 931.999 1738.24 947.465 1734.37 944.565C1729.53 945.532 1723.73 948.431 1716 951.331C1700.53 958.097 1685.06 962.93 1669.6 968.729C1619.33 985.161 1567.12 1000.63 1514.92 1015.13C1409.54 1043.16 1309.97 1056.69 1211.36 1058.62C1163.02 1059.59 1115.65 1057.66 1068.28 1050.89C764.721 1005.46 470.83 914.601 419.593 819.876C411.859 806.344 411.859 795.711 425.393 787.012C466.963 651.691 630.344 766.714 935.835 721.284C982.239 716.452 1030.58 712.585 1080.85 714.518C1094.38 714.518 1107.92 715.485 1121.45 715.485C1210.39 717.418 1297.4 733.85 1385.37 758.015C1438.54 772.513 1490.75 786.046 1539.09 801.511C1554.55 806.344 1570.02 810.21 1584.52 816.976C1592.26 819.876 1597.09 822.776 1601.92 822.776C1605.79 819.876 1621.26 834.375 1624.16 831.475C1628.03 828.575 1643.49 808.277 1647.36 806.344C1652.19 801.511 1658 794.745 1664.76 787.012C1679.26 770.58 1694.73 755.115 1710.2 738.683C1759.5 687.454 1811.71 637.192 1863.91 590.796C1970.25 497.037 2072.73 424.544 2173.27 382.014C2223.54 360.749 2272.85 347.217 2321.18 343.351C2602.51 321.119 2890.6 497.037 2937.97 834.375Z' stroke='url(#paint14_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M2960.2 828.576C2986.3 1001.59 3045.27 1452.99 2505.83 1373.73C2455.56 1368.9 2404.32 1357.3 2355.02 1339.9C2240.94 1300.27 2132.67 1236.47 2027.29 1158.18C1968.32 1114.68 1913.21 1069.25 1861.98 1023.83C1845.54 1009.33 1829.11 993.861 1813.64 978.396C1805.91 970.663 1800.1 964.864 1795.27 960.031C1791.4 957.131 1774.97 938.766 1771.1 935.866C1767.24 932.966 1750.8 947.465 1746.93 944.565C1742.1 944.565 1736.3 947.465 1728.57 951.332C1713.1 958.098 1696.66 961.964 1681.19 966.797C1629.96 981.296 1576.79 994.828 1523.61 1006.43C1417.27 1030.59 1315.76 1040.26 1216.19 1040.26C1167.85 1040.26 1119.51 1037.36 1072.14 1029.62C765.685 980.329 465.994 896.236 410.889 813.11C403.155 800.545 402.188 793.779 415.723 787.013C456.326 655.557 618.74 787.979 930.032 739.65C976.436 733.851 1025.74 730.951 1076.98 729.984C1090.51 729.984 1104.05 730.951 1117.58 729.984C1207.49 726.118 1296.43 743.516 1384.4 763.815C1438.54 776.38 1490.75 787.979 1540.05 801.511C1555.52 805.378 1571.95 809.244 1586.45 815.043C1594.19 817.943 1599.99 820.843 1603.85 820.843C1607.72 817.943 1623.19 831.475 1627.06 828.576C1630.92 825.676 1646.39 806.344 1650.26 802.478C1655.09 797.645 1660.89 790.879 1667.66 783.146C1683.13 766.714 1698.6 750.282 1714.06 734.817C1764.33 683.588 1816.54 633.326 1869.71 585.963C1977.02 491.238 2081.43 417.778 2182.94 375.249C2233.21 353.984 2283.48 339.485 2332.78 335.619C2616.04 311.454 2908.96 484.472 2960.2 828.576Z' stroke='url(#paint15_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M2982.43 822.776C3008.54 990.961 3087.81 1458.79 2530 1374.69C2478.76 1369.86 2427.52 1357.3 2377.25 1339.9C2261.24 1300.27 2151.03 1236.47 2044.69 1158.18C1984.75 1114.68 1928.68 1069.25 1876.47 1023.82C1860.04 1009.33 1842.64 993.861 1827.17 978.395C1819.44 970.663 1813.64 964.863 1807.84 960.03C1803 957.13 1787.53 938.765 1783.67 935.866C1778.83 932.966 1763.37 946.498 1758.53 943.598C1753.7 943.598 1747.9 946.498 1740.16 949.398C1724.7 955.197 1708.26 959.064 1691.83 962.93C1639.62 975.496 1585.48 987.095 1531.35 996.76C1423.07 1017.06 1321.56 1023.82 1221.02 1020.92C1171.72 1019.96 1124.35 1016.09 1076.01 1008.36C766.649 956.164 447.623 887.537 403.152 807.31C392.518 798.611 393.485 792.812 407.019 787.979C446.656 660.39 607.136 810.21 924.229 758.981C971.599 753.182 1020.9 749.315 1072.14 747.382C1085.68 746.416 1099.21 747.382 1112.74 746.416C1204.59 743.516 1293.53 754.148 1382.47 771.547C1437.57 782.179 1490.74 791.845 1540.05 802.477C1555.51 806.344 1571.95 808.277 1587.42 814.076C1595.15 816.976 1600.95 818.909 1605.79 818.909C1609.65 816.009 1625.12 828.575 1628.99 825.675C1632.85 822.776 1648.32 803.444 1653.16 799.578C1657.99 794.745 1663.79 787.979 1671.52 780.246C1686.99 763.814 1702.46 747.382 1718.89 731.917C1770.13 679.721 1823.3 629.459 1877.44 582.097C1986.68 487.372 2092.06 412.945 2194.53 369.449C2245.77 348.184 2296.04 333.685 2345.35 328.852C2629.57 300.821 2928.3 471.906 2982.43 822.776Z' stroke='url(#paint16_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3003.7 816.97C3029.81 980.323 3129.38 1464.58 2553.2 1375.65C2501 1369.86 2449.76 1358.26 2398.52 1340.86C2280.58 1300.26 2169.4 1236.47 2061.13 1159.14C2000.22 1115.64 1943.18 1070.21 1890.01 1023.82C1872.61 1009.32 1856.18 993.855 1839.74 978.39C1832.01 970.657 1825.24 964.857 1820.41 960.025C1815.57 957.125 1800.1 938.76 1795.27 935.86C1790.44 932.96 1774.97 945.526 1770.14 942.626C1765.3 942.626 1758.53 944.559 1750.8 947.459C1734.37 952.292 1717.93 955.192 1701.5 959.058C1647.36 969.69 1593.22 978.39 1539.08 987.089C1429.84 1003.52 1326.4 1006.42 1224.89 1001.59C1175.59 999.654 1127.25 994.822 1078.91 986.122C766.652 930.061 440.858 870.132 393.488 800.538C382.854 793.772 382.854 789.906 397.355 787.973C436.025 663.284 594.571 832.436 918.431 776.374C965.802 770.574 1016.07 765.742 1068.28 762.842C1081.81 761.875 1095.35 761.875 1109.85 760.909C1202.65 756.076 1293.53 762.842 1382.47 777.341C1438.54 786.04 1492.68 792.806 1542.95 802.472C1559.38 805.371 1575.82 807.305 1591.29 811.171C1599.02 813.104 1604.82 815.037 1609.66 815.037C1613.52 811.171 1628.99 823.737 1633.82 820.837C1637.69 816.97 1654.13 798.605 1657.99 794.739C1662.83 789.906 1668.63 783.14 1676.36 775.407C1691.83 758.975 1708.26 742.544 1723.73 726.112C1775.94 673.916 1830.07 622.687 1884.21 575.325C1994.42 479.633 2100.76 404.24 2205.17 359.777C2257.38 337.546 2307.65 323.047 2357.92 318.214C2643.11 290.183 2946.67 459.335 3003.7 816.97Z' stroke='url(#paint17_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3025.94 811.175C3052.04 969.695 3171.92 1471.35 2576.4 1376.63C2524.2 1370.83 2472 1358.26 2419.79 1340.86C2299.91 1300.27 2186.8 1236.47 2077.56 1159.14C2015.69 1115.65 1957.69 1070.22 1903.55 1023.82C1886.15 1009.32 1868.74 993.859 1852.31 978.394C1844.58 970.661 1837.81 964.862 1832.98 960.029C1828.14 957.129 1812.67 938.764 1807.84 935.864C1803.01 932.964 1786.57 944.563 1781.74 941.664C1776.9 941.664 1770.14 943.597 1762.4 945.53C1745.97 950.363 1728.57 952.296 1712.13 955.196C1657.03 963.895 1601.92 970.661 1546.82 976.461C1435.64 989.026 1332.2 988.06 1229.73 981.294C1180.42 977.427 1131.12 972.594 1081.81 963.895C766.653 904.934 435.059 852.738 384.788 793.777C373.187 789.91 373.187 787.977 387.689 787.011C425.392 666.188 582.005 852.738 912.632 793.777C960.97 787.011 1011.24 781.211 1063.44 777.345C1076.98 776.378 1091.48 775.412 1105.01 774.445C1198.79 766.712 1290.63 771.545 1381.5 782.178C1438.54 788.944 1492.68 793.777 1543.92 800.543C1560.35 802.476 1576.79 803.442 1592.26 807.309C1599.99 809.242 1605.79 811.175 1610.62 810.208C1615.46 806.342 1630.93 817.941 1634.79 814.075C1639.63 810.208 1655.09 791.843 1658.96 787.977C1663.79 783.144 1670.56 776.378 1677.33 768.645C1692.8 752.214 1709.23 735.782 1725.67 719.35C1778.84 666.188 1832.98 614.959 1889.05 567.596C2001.19 470.938 2108.5 395.545 2213.87 350.115C2266.08 327.884 2317.32 313.385 2368.55 307.586C2655.68 280.521 2964.07 446.774 3025.94 811.175Z' stroke='url(#paint18_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3047.21 805.376C3074.28 959.063 3212.52 1477.15 2599.6 1376.63C2546.43 1370.83 2493.26 1358.26 2441.06 1339.9C2319.25 1298.33 2204.2 1235.51 2093.99 1158.18C2031.16 1114.68 1972.18 1069.25 1917.08 1022.86C1899.68 1007.39 1881.31 992.893 1864.88 977.428C1857.14 969.695 1850.37 963.896 1844.57 959.063C1839.74 956.163 1823.31 937.798 1818.47 934.898C1813.64 931.998 1797.2 942.631 1792.37 939.731C1786.57 939.731 1780.77 940.698 1772.07 942.631C1755.63 946.497 1738.23 948.43 1720.83 950.364C1664.76 957.13 1609.65 961.963 1553.58 965.829C1441.44 974.528 1336.06 970.662 1232.62 960.996C1182.35 956.163 1133.05 950.364 1083.74 940.698C765.684 878.836 427.322 833.407 374.151 786.045C361.583 784.111 361.583 784.111 376.085 786.045C412.821 669.088 568.467 873.037 904.895 811.176C953.233 804.41 1003.5 797.644 1057.64 792.811C1071.18 791.844 1085.68 790.878 1100.18 788.944C1194.92 779.279 1287.73 781.212 1378.6 788.944C1436.61 793.777 1491.71 796.677 1543.92 801.51C1560.35 803.443 1577.75 803.443 1593.22 806.343C1600.95 808.276 1606.75 809.243 1612.55 808.276C1617.39 804.41 1632.86 815.042 1637.69 811.176C1642.52 807.309 1657.99 788.944 1662.83 785.078C1667.66 780.245 1674.43 773.479 1682.16 765.746C1698.59 748.348 1715.03 731.916 1731.46 716.451C1785.6 663.289 1840.71 611.093 1896.78 562.764C2009.89 465.139 2119.13 388.779 2225.47 343.35C2278.64 321.119 2329.88 305.653 2381.12 299.854C2668.24 269.89 2982.44 434.209 3047.21 805.376Z' stroke='url(#paint19_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3074.28 799.575C3074.28 950.362 3259.89 1482.95 2627.64 1377.59C2573.5 1370.82 2520.33 1358.26 2468.13 1340.86C2344.38 1299.3 2228.37 1235.5 2116.23 1159.14C2052.43 1115.65 1992.49 1070.22 1936.42 1023.82C1918.05 1008.36 1900.65 993.858 1883.25 978.393C1875.51 970.66 1868.74 964.861 1862.94 960.028C1857.14 956.161 1841.68 938.763 1836.84 935.863C1831.04 931.997 1815.57 942.629 1809.77 939.729C1803.97 938.763 1797.2 940.696 1789.47 942.629C1772.07 946.495 1754.67 946.495 1737.27 948.429C1680.23 953.262 1624.16 955.195 1567.12 958.094C1453.04 962.927 1347.67 955.195 1242.29 943.596C1192.02 937.796 1141.75 931.03 1092.45 921.364C771.487 853.704 427.325 816.973 371.253 779.277C358.686 779.277 357.719 782.176 372.22 786.043C407.023 672.953 561.703 894.3 903.931 829.539C952.268 821.806 1003.51 815.04 1057.64 808.274C1071.18 806.341 1085.68 805.374 1100.18 803.441C1196.86 790.876 1290.63 789.909 1382.47 793.775C1441.44 796.675 1496.55 796.675 1549.72 799.575C1567.12 800.542 1583.55 799.575 1599.99 802.475C1607.72 803.441 1614.49 804.408 1619.32 803.441C1624.16 799.575 1639.63 809.241 1644.46 805.374C1649.29 801.508 1664.76 783.143 1669.59 779.277C1674.43 774.444 1681.2 767.678 1688.93 758.979C1705.36 741.58 1721.8 725.148 1739.2 708.716C1794.3 655.554 1850.38 603.359 1907.41 554.063C2022.46 458.371 2132.67 381.045 2239.97 334.649C2293.15 311.451 2345.35 295.986 2397.55 290.186C2687.58 259.256 2939.9 439.04 3074.28 799.575Z' stroke='url(#paint20_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3095.54 793.782C3095.54 939.736 3301.46 1488.75 2650.84 1378.56C2596.7 1371.8 2542.56 1359.23 2489.39 1340.87C2363.72 1299.3 2245.77 1235.51 2132.66 1158.18C2067.89 1114.69 2006.02 1069.26 1949.95 1022.86C1931.58 1007.4 1913.21 992.898 1895.81 977.432C1888.08 969.7 1880.34 963.9 1874.54 959.067C1868.74 955.201 1853.27 937.803 1847.47 934.903C1841.67 931.036 1826.21 941.669 1820.41 937.803C1814.6 936.836 1807.84 938.769 1800.1 939.736C1782.7 942.635 1764.33 942.635 1746.93 943.602C1688.93 945.535 1631.89 946.502 1574.85 946.502C1459.81 946.502 1352.5 935.869 1247.12 922.337C1195.89 915.571 1145.62 907.839 1096.31 897.206C771.485 827.612 420.555 799.581 361.584 772.517C348.049 774.45 347.083 779.283 361.584 786.049C395.42 675.859 548.166 916.538 897.162 847.91C946.466 840.178 997.703 832.445 1052.81 824.712C1067.31 822.779 1080.84 820.846 1095.34 818.913C1192.99 803.448 1287.73 806.347 1380.54 800.548C1439.51 796.682 1496.54 799.581 1549.72 799.581C1567.12 799.581 1584.52 798.615 1600.95 800.548C1608.69 801.514 1615.45 802.481 1620.29 801.515C1625.12 797.648 1640.59 806.347 1645.42 802.481C1651.22 798.615 1665.73 780.25 1671.53 775.417C1677.33 770.584 1683.13 762.851 1690.86 755.119C1707.3 737.72 1724.7 721.288 1742.1 704.856C1798.17 650.728 1855.21 598.532 1912.25 549.237C2028.26 450.645 2140.4 372.352 2248.67 325.956C2302.81 302.758 2355.98 287.293 2408.19 281.493C2699.18 249.596 2954.4 428.414 3095.54 793.782Z' stroke='url(#paint21_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3115.85 788.949C3115.85 930.07 3342.07 1496.49 2673.08 1380.5C2617.97 1373.73 2563.84 1360.2 2509.7 1342.8C2382.09 1300.27 2262.21 1236.48 2148.13 1160.12C2082.4 1116.62 2019.56 1071.19 1962.52 1024.79C1944.15 1009.33 1924.82 994.831 1907.41 979.365C1898.71 971.633 1891.95 965.833 1886.15 961C1880.35 957.134 1864.88 939.736 1859.08 936.836C1853.28 932.969 1837.81 942.635 1831.04 938.769C1825.24 937.802 1818.47 938.769 1809.77 939.735C1792.37 941.669 1774 941.669 1755.64 941.669C1696.66 941.669 1638.66 940.702 1580.65 938.769C1463.68 934.903 1355.4 921.37 1249.06 904.939C1197.82 897.206 1147.55 888.507 1096.31 877.874C769.554 805.381 411.857 785.082 349.986 769.617C335.484 774.45 334.518 781.216 349.019 789.915C381.888 683.591 532.701 941.669 888.464 870.142C937.768 862.409 989.972 853.71 1045.08 844.044C1059.58 842.111 1074.08 840.178 1088.58 837.278C1187.19 819.879 1283.86 818.913 1377.64 810.213C1437.58 804.414 1495.58 804.414 1549.72 803.447C1567.12 802.481 1584.52 798.615 1601.92 802.481C1609.66 804.414 1616.42 803.447 1622.22 802.481C1628.02 797.648 1642.53 807.314 1648.33 802.481C1654.13 797.648 1668.63 780.249 1674.43 775.417C1680.23 769.617 1687 762.851 1694.73 755.118C1712.13 737.72 1729.53 721.288 1745.97 704.856C1803.01 650.727 1860.04 597.565 1919.02 548.27C2036.96 448.712 2149.1 370.419 2259.31 323.056C2313.45 299.858 2367.59 283.426 2419.79 277.627C2711.75 238.963 2968.9 416.815 3115.85 788.949Z' stroke='url(#paint22_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3137.11 783.142C3137.11 919.43 3383.63 1502.28 2695.31 1381.46C2639.24 1373.72 2584.13 1361.16 2530 1342.79C2400.45 1300.26 2279.61 1236.47 2163.6 1160.11C2096.89 1115.65 2033.09 1071.18 1975.08 1023.82C1955.75 1008.36 1937.38 993.856 1919.01 978.391C1910.31 970.658 1903.55 964.859 1897.74 960.026C1890.98 956.16 1875.51 939.728 1869.71 935.862C1862.94 931.995 1847.47 940.694 1841.67 936.828C1835.87 935.862 1828.14 936.828 1820.4 936.828C1802.04 938.761 1783.67 936.828 1766.27 936.828C1706.33 934.895 1647.36 931.029 1589.35 928.129C1471.41 920.396 1362.17 902.998 1254.86 884.633C1203.62 875.933 1152.38 866.268 1101.15 854.669C771.485 779.275 407.021 766.71 343.216 760.91C327.748 767.676 326.781 776.375 341.282 787.008C373.185 684.55 523.031 960.026 884.594 885.599C934.865 876.9 987.069 868.201 1043.14 857.568C1057.64 854.669 1072.14 852.735 1086.64 849.836C1187.19 829.537 1283.86 819.872 1378.6 814.072C1439.51 810.206 1497.51 804.406 1552.62 800.54C1570.02 799.573 1588.39 793.774 1604.82 797.64C1612.55 799.573 1619.32 798.607 1625.12 796.674C1630.92 791.841 1645.42 800.54 1651.22 795.707C1657.02 790.874 1672.49 773.476 1678.29 768.643C1684.09 762.843 1690.86 756.077 1698.59 748.345C1716 730.946 1733.4 714.514 1750.8 697.116C1808.8 642.02 1866.81 588.858 1925.78 539.563C2044.69 440.005 2158.77 360.745 2269.94 312.416C2325.05 288.251 2379.18 271.819 2432.36 266.02C2724.31 228.323 2982.43 405.208 3137.11 783.142Z' stroke='url(#paint23_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3157.42 777.342C3157.42 908.797 3423.27 1508.08 2717.55 1382.42C2661.47 1374.69 2605.4 1361.16 2551.26 1343.76C2419.79 1300.26 2297.01 1237.44 2180.03 1161.08C2112.36 1116.61 2047.59 1072.15 1988.62 1024.79C1969.28 1009.32 1949.95 994.823 1931.58 978.391C1922.88 971.625 1916.11 964.859 1909.34 960.026C1902.58 956.16 1887.11 939.728 1881.31 934.895C1874.54 931.029 1859.07 938.761 1852.31 934.895C1846.51 933.928 1838.77 933.928 1831.04 934.895C1812.67 935.862 1794.3 933.928 1775.93 932.962C1715.03 929.095 1655.09 923.296 1596.12 917.496C1476.24 905.897 1366.03 884.633 1257.76 864.334C1205.55 854.669 1154.32 844.036 1103.08 832.437C770.517 754.144 400.253 749.311 332.581 754.144C317.113 762.843 315.179 774.442 329.681 787.008C360.616 688.416 508.529 981.291 876.859 903.964C927.13 895.265 980.301 884.633 1036.37 874C1050.87 871.101 1065.37 868.201 1079.88 865.301C1181.38 842.103 1279.03 829.538 1374.73 820.838C1436.61 815.039 1495.58 807.306 1551.65 801.507C1570.02 799.573 1587.42 793.774 1604.82 796.674C1612.55 797.64 1619.32 796.674 1625.12 794.74C1630.92 789.908 1646.39 797.64 1652.19 792.807C1657.99 787.974 1673.46 770.576 1679.26 765.743C1685.06 759.944 1691.83 753.177 1699.56 745.445C1716.96 728.046 1735.33 710.648 1752.73 694.216C1811.7 639.121 1870.68 584.992 1929.65 535.696C2049.52 435.172 2165.53 354.946 2277.68 306.616C2332.78 282.452 2387.88 266.02 2442.02 259.254C2735.91 218.658 2996.94 394.576 3157.42 777.342Z' stroke='url(#paint24_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3177.72 771.543C3177.72 898.165 3463.87 1514.84 2739.78 1382.42C2682.74 1374.69 2626.67 1360.19 2571.57 1342.79C2438.16 1299.3 2313.45 1235.5 2195.5 1160.11C2126.86 1115.65 2061.13 1070.22 2001.19 1023.82C1981.85 1008.36 1961.55 993.857 1943.18 977.425C1934.48 970.659 1927.71 963.893 1920.95 959.06C1914.18 955.193 1898.71 938.761 1891.94 933.929C1885.18 929.096 1869.71 936.828 1862.94 932.962C1856.18 931.029 1849.41 931.995 1840.71 931.995C1821.37 931.995 1803 930.062 1784.64 928.129C1722.76 922.33 1661.86 914.597 1602.89 906.864C1482.04 891.399 1370.87 867.234 1260.66 844.036C1208.45 833.404 1156.25 821.805 1104.05 809.239C768.585 727.08 391.553 730.946 320.981 746.412C304.546 757.044 302.613 771.543 317.114 786.041C347.083 691.316 493.062 1002.56 867.193 921.363C917.464 912.664 971.602 901.065 1028.64 888.499C1043.14 885.599 1057.64 882.7 1073.11 878.833C1175.59 853.702 1275.16 837.27 1370.87 825.671C1433.71 817.939 1492.68 807.306 1549.72 799.574C1568.08 796.674 1586.45 789.908 1603.85 792.808C1611.59 793.774 1618.36 791.841 1625.12 789.908C1630.92 785.075 1646.39 791.841 1652.19 787.008C1658.96 782.175 1673.46 764.777 1679.26 759.944C1685.06 754.144 1691.83 747.378 1700.53 739.646C1717.93 722.247 1736.3 704.849 1754.67 688.417C1814.6 632.355 1874.54 579.193 1934.48 528.931C2056.29 427.44 2173.27 347.213 2286.38 296.951C2342.45 272.786 2397.55 255.388 2451.69 248.622C2748.48 208.025 3010.47 382.977 3177.72 771.543Z' stroke='url(#paint25_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3198.99 765.751C3198.99 887.541 3505.45 1520.65 2762.02 1383.4C2704.01 1374.7 2647.94 1361.17 2591.87 1342.8C2456.53 1299.3 2329.88 1235.51 2210.97 1160.12C2141.37 1115.65 2074.66 1070.22 2013.76 1023.83C1993.46 1008.36 1974.12 993.865 1954.79 977.433C1946.08 970.667 1938.35 963.901 1932.55 959.068C1925.78 954.235 1910.31 938.77 1903.55 933.937C1896.78 929.104 1881.31 935.87 1873.58 932.004C1866.81 930.07 1860.04 930.07 1851.34 930.07C1832.01 930.07 1812.67 926.204 1794.31 924.271C1731.47 916.538 1669.59 906.872 1609.66 896.24C1486.88 876.908 1374.74 848.877 1264.53 822.78C1211.36 810.214 1159.15 798.615 1106.95 786.049C768.587 700.99 379.955 701.957 312.282 738.687C293.914 749.319 292.947 767.684 307.449 785.083C335.484 693.258 480.496 1022.86 861.395 937.803C912.632 928.137 965.803 916.538 1023.81 903.006C1038.31 899.14 1053.78 896.24 1068.28 892.374C1171.72 864.343 1272.26 845.011 1368.94 830.512C1432.74 820.847 1492.68 808.281 1549.72 798.615C1568.09 795.715 1586.45 790.882 1604.82 788.949C1612.56 787.983 1620.29 787.983 1626.09 785.083C1632.86 780.25 1647.36 786.049 1654.13 781.217C1660.89 775.417 1675.4 758.985 1682.16 754.152C1687.96 748.353 1695.7 741.587 1703.43 733.854C1721.8 716.456 1740.17 699.057 1758.54 681.659C1818.47 625.597 1879.38 571.468 1940.28 520.239C2063.06 417.782 2181.97 336.589 2296.05 286.326C2353.08 261.195 2408.19 243.797 2463.29 237.031C2760.09 198.367 3024.01 371.386 3198.99 765.751Z' stroke='url(#paint26_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3219.29 759.947C3219.29 876.903 3546.05 1526.45 2784.25 1384.36C2726.25 1375.66 2668.25 1361.16 2612.17 1343.76C2473.93 1299.3 2347.29 1235.51 2226.44 1161.08C2154.9 1116.62 2088.2 1071.19 2025.36 1024.79C2005.06 1009.32 1984.75 994.826 1965.42 978.394C1956.72 971.628 1948.99 964.862 1942.22 960.029C1934.48 955.196 1919.98 939.731 1912.25 934.898C1904.51 930.065 1889.05 936.831 1882.28 931.998C1875.51 930.065 1867.78 930.065 1860.04 929.098C1840.71 928.132 1821.37 924.266 1802.04 921.366C1738.23 910.733 1676.36 899.134 1614.49 887.535C1490.75 863.371 1377.64 832.44 1265.5 804.409C1212.32 790.877 1159.15 778.312 1106.95 764.779C765.687 675.854 370.288 686.486 299.715 732.882C280.38 745.448 279.413 766.713 293.915 786.044C320.983 698.085 465.029 1045.09 851.728 957.129C902.965 947.464 957.103 934.898 1015.11 919.433C1029.61 915.566 1045.08 911.7 1060.54 907.834C1165.92 877.87 1266.46 855.638 1365.07 837.273C1429.84 824.708 1490.75 811.175 1548.75 798.61C1567.12 794.744 1585.49 789.911 1604.82 787.011C1612.56 786.044 1620.29 785.078 1626.09 783.145C1632.86 777.345 1647.36 783.145 1654.13 777.345C1660.89 771.546 1675.4 755.114 1682.16 749.314C1688.93 743.515 1695.7 736.749 1703.43 729.016C1721.8 711.618 1740.17 694.219 1758.54 676.821C1819.44 620.759 1881.31 565.664 1943.18 514.435C2067.9 411.977 2186.81 329.818 2302.81 278.589C2359.85 253.458 2415.92 236.059 2472 228.326C2771.69 187.73 3037.54 360.748 3219.29 759.947Z' stroke='url(#paint27_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3239.59 755.112C3239.59 867.236 3585.68 1533.21 2806.49 1386.29C2747.51 1377.59 2689.51 1363.09 2632.47 1344.73C2492.29 1300.26 2363.72 1236.47 2241.91 1162.04C2169.4 1117.58 2101.73 1072.15 2037.92 1025.76C2017.62 1010.29 1996.35 994.825 1977.02 979.359C1968.32 972.593 1960.58 965.827 1953.82 960.994C1946.08 956.161 1930.61 940.696 1923.85 935.863C1916.11 931.03 1900.64 936.83 1892.91 931.997C1886.14 930.064 1878.41 929.097 1869.71 928.13C1849.41 926.197 1830.07 922.331 1810.74 918.465C1745.96 905.899 1683.13 892.367 1621.25 878.835C1495.58 850.804 1381.5 816.973 1269.36 786.043C1216.19 771.544 1163.02 758.012 1109.85 744.48C765.683 652.655 363.517 672.953 291.011 728.048C270.709 743.513 269.742 765.745 284.243 787.009C310.345 702.917 452.457 1067.32 845.923 976.459C897.161 965.827 952.265 953.262 1011.24 936.83C1025.74 932.963 1041.21 929.097 1056.67 924.264C1163.02 891.4 1265.49 866.269 1364.1 845.004C1428.87 830.506 1490.74 814.074 1549.71 800.542C1569.05 795.709 1587.42 789.909 1605.79 787.009C1613.52 786.043 1621.25 785.076 1628.02 782.177C1634.79 776.377 1649.29 781.21 1656.06 775.41C1662.82 769.611 1678.29 753.179 1685.06 747.38C1691.83 741.58 1698.59 734.814 1707.29 726.115C1725.66 707.75 1745 691.318 1763.37 673.919C1825.24 616.891 1888.08 561.796 1949.95 510.567C2075.63 407.143 2196.47 324.017 2313.44 272.788C2371.45 247.657 2427.52 229.292 2483.59 221.559C2783.28 178.063 3051.07 349.148 3239.59 755.112Z' stroke='url(#paint28_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3258.93 749.316C3258.93 856.606 3625.32 1539.98 2826.79 1387.26C2766.85 1377.59 2708.85 1363.1 2651.81 1345.7C2509.7 1301.23 2379.19 1237.44 2256.41 1163.01C2182.94 1118.55 2114.3 1073.12 2049.52 1025.76C2028.26 1010.29 2007.95 994.828 1987.65 979.362C1978.95 972.596 1971.22 965.83 1963.48 960.997C1955.75 956.164 1940.28 940.699 1932.55 935.866C1924.81 931.033 1909.35 935.866 1901.61 931.033C1894.85 928.133 1887.11 928.133 1878.41 927.167C1858.11 925.234 1838.77 919.434 1818.47 915.568C1752.73 901.069 1688.93 885.604 1626.09 869.172C1499.45 837.275 1384.4 799.578 1270.33 766.714C1216.19 751.249 1163.02 736.75 1108.88 722.251C761.817 627.526 352.883 656.524 277.477 721.285C257.175 738.683 255.242 763.814 269.743 787.012C294.879 706.786 435.057 1089.55 834.323 994.828C886.528 984.195 941.632 970.663 1000.6 952.298C1016.07 947.465 1031.54 943.599 1046.04 938.766C1153.35 903.002 1256.79 874.971 1356.37 850.807C1422.11 834.375 1484.94 816.01 1544.88 799.578C1564.22 794.745 1582.59 787.979 1601.92 784.113C1609.65 782.18 1617.39 781.213 1624.16 778.313C1630.92 772.514 1645.42 776.38 1653.16 770.581C1660.89 764.781 1675.39 748.349 1682.16 742.55C1688.93 736.75 1695.7 729.018 1704.4 721.285C1723.73 702.92 1742.1 685.521 1761.43 668.123C1824.27 611.094 1888.08 555.033 1950.92 503.804C2078.53 399.413 2200.34 316.287 2318.28 264.092C2376.28 237.994 2433.32 220.595 2490.36 211.896C2794.89 167.433 3064.61 337.552 3258.93 749.316Z' stroke='url(#paint29_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3279.23 743.512C3279.23 845.97 3665.93 1545.78 2849.02 1387.26C2789.09 1377.59 2730.11 1363.09 2672.11 1344.73C2528.06 1299.3 2396.59 1235.5 2271.88 1161.08C2197.44 1116.61 2127.83 1071.18 2062.09 1023.82C2040.82 1008.36 2019.56 992.89 1999.25 977.425C1990.55 970.659 1982.82 963.893 1975.09 959.06C1967.35 954.227 1951.88 938.762 1944.15 933.929C1935.45 929.096 1920.95 932.962 1912.25 928.129C1905.48 925.229 1896.78 924.263 1888.08 923.296C1867.78 920.396 1847.47 914.597 1827.17 909.764C1760.47 893.332 1695.7 874.967 1632.86 857.569C1504.28 821.805 1388.27 780.242 1273.23 745.445C1219.09 729.013 1164.95 713.548 1110.81 698.083C760.851 599.491 345.15 638.154 266.844 712.581C245.575 732.88 243.642 758.977 258.143 785.075C282.312 708.715 420.557 1108.88 826.59 1011.26C878.795 1000.62 934.866 985.157 994.804 966.792C1010.27 961.96 1025.74 957.127 1041.21 952.294C1149.48 914.597 1253.89 882.7 1354.43 855.635C1421.14 837.27 1483.98 816.006 1544.88 797.641C1564.22 791.841 1583.55 785.075 1602.89 780.242C1610.62 778.309 1618.36 776.376 1625.12 773.476C1632.86 767.677 1647.36 770.576 1654.13 764.777C1661.86 758.977 1676.36 742.545 1684.09 736.746C1690.86 730.946 1698.6 723.214 1706.33 715.481C1725.66 697.116 1745 679.718 1764.33 662.319C1828.14 604.324 1891.95 549.229 1955.75 497.033C2084.33 392.643 2208.07 307.583 2326.98 255.388C2385.95 229.29 2443.96 210.925 2501 202.226C2806.49 156.797 3078.14 326.915 3279.23 743.512Z' stroke='url(#paint30_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3299.53 737.72C3299.53 835.345 3706.53 1551.58 2871.26 1388.23C2810.36 1378.56 2750.42 1363.1 2692.41 1345.7C2546.43 1300.27 2413.02 1236.48 2287.35 1162.05C2211.94 1117.59 2140.4 1072.16 2074.66 1024.8C2053.39 1009.33 2031.16 993.865 2010.86 978.399C2002.16 971.633 1993.45 964.867 1986.69 960.034C1977.99 955.201 1963.49 940.703 1954.78 934.903C1946.08 929.104 1931.58 932.97 1922.88 928.137C1915.15 925.237 1907.41 924.271 1898.71 922.338C1877.44 918.471 1857.14 912.672 1836.84 906.872C1769.17 888.507 1703.43 868.209 1639.63 848.877C1510.08 809.247 1393.1 764.785 1277.1 727.088C1221.99 709.689 1167.85 693.257 1113.71 677.792C760.852 576.301 339.35 622.697 258.144 706.79C235.909 729.021 233.975 758.018 248.476 786.049C271.678 712.589 408.956 1131.12 820.79 1030.59C873.962 1019 930.033 1003.53 989.971 984.199C1005.44 979.366 1020.91 974.533 1036.38 968.733C1146.58 928.137 1251.96 894.307 1353.47 863.376C1421.14 843.078 1484.95 819.88 1546.82 799.582C1567.12 792.815 1585.49 785.083 1605.79 780.25C1613.52 778.317 1621.26 776.384 1628.99 772.517C1636.72 765.751 1651.23 769.618 1658.96 762.851C1666.69 756.085 1681.2 740.62 1688.93 734.821C1695.7 729.021 1703.43 721.288 1712.13 713.556C1731.47 695.191 1750.8 677.792 1771.1 660.394C1835.87 602.399 1900.65 546.337 1965.42 494.141C2094 385.884 2218.71 301.792 2338.58 247.663C2397.55 221.565 2456.53 202.234 2513.56 193.534C2818.09 147.138 3091.68 315.324 3299.53 737.72Z' stroke='url(#paint31_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3319.83 731.909C3319.83 824.701 3746.16 1558.34 2892.53 1389.18C2830.66 1378.55 2770.72 1364.05 2711.75 1345.69C2563.83 1299.29 2428.49 1235.5 2301.84 1162.04C2225.47 1117.58 2152.97 1072.15 2086.26 1024.78C2064.02 1009.32 2042.76 993.853 2021.49 978.387C2012.79 971.621 2004.09 964.855 1996.35 960.022C1987.65 954.223 1972.18 940.691 1964.45 934.891C1955.75 929.092 1940.28 931.991 1931.58 927.159C1923.85 924.259 1916.11 922.326 1907.41 920.392C1886.14 915.56 1865.84 908.794 1845.54 902.994C1776.9 881.729 1710.2 860.464 1646.39 838.233C1514.91 794.737 1396.97 746.408 1279.99 706.778C1224.89 688.413 1169.78 671.014 1115.65 654.582C758.917 550.191 331.615 605.287 247.508 700.012C225.272 725.143 222.372 755.107 236.873 786.038C258.142 716.444 394.453 1152.37 813.054 1048.95C866.226 1037.35 923.264 1020.92 984.169 999.652C999.637 993.853 1015.1 989.02 1031.54 983.22C1142.72 939.724 1249.06 902.994 1351.53 868.197C1420.17 844.999 1484.94 820.835 1546.82 797.637C1567.12 789.904 1586.45 782.171 1606.75 776.372C1615.45 774.439 1623.19 771.539 1629.96 767.673C1637.69 760.906 1652.19 763.806 1659.92 757.04C1667.66 750.274 1682.16 734.809 1690.86 729.009C1697.63 723.21 1705.36 715.477 1714.06 707.744C1733.4 689.379 1753.7 671.981 1773.03 653.616C1838.77 594.654 1904.51 538.592 1969.28 486.397C2100.76 380.073 2226.44 294.047 2348.25 240.885C2408.19 214.787 2467.16 195.456 2525.16 185.79C2829.69 136.494 3105.21 304.68 3319.83 731.909Z' stroke='url(#paint32_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3339.16 726.117C3339.16 814.076 3785.8 1564.14 2913.8 1390.16C2851.92 1379.53 2791.02 1364.06 2732.05 1345.7C2582.2 1299.3 2444.92 1235.51 2317.31 1162.05C2239.97 1117.58 2166.5 1072.15 2098.83 1024.79C2076.59 1009.33 2054.36 993.86 2033.09 978.395C2023.42 971.629 2015.69 964.863 2007.95 960.03C1999.25 954.23 1983.78 940.698 1975.08 934.899C1966.38 929.099 1950.92 931.999 1942.21 926.199C1934.48 923.3 1925.78 921.366 1917.08 919.433C1895.81 914.6 1874.54 906.868 1854.24 900.102C1784.63 876.904 1716.96 852.739 1652.19 829.541C1519.75 781.212 1400.84 729.983 1282.89 688.42C1227.79 669.089 1172.68 650.723 1116.61 634.292C757.95 526.034 323.88 590.795 236.873 694.22C213.671 721.284 210.771 754.148 226.239 786.045C246.541 720.317 380.918 1174.61 805.32 1067.32C858.491 1055.72 916.496 1038.32 977.401 1016.09C992.869 1010.29 1009.3 1004.49 1024.77 998.693C1136.91 953.264 1244.22 912.667 1347.67 874.971C1417.27 849.839 1482.04 822.775 1544.88 798.611C1565.18 790.878 1584.52 781.212 1604.82 775.413C1613.52 772.513 1621.25 770.58 1628.02 766.713C1636.72 759.947 1650.26 761.88 1658.96 755.114C1667.66 748.348 1681.19 732.883 1689.89 726.117C1696.66 719.351 1704.4 712.585 1713.1 704.852C1733.4 686.487 1753.7 668.122 1773.03 650.723C1839.74 591.762 1906.45 534.734 1971.22 482.538C2104.63 375.248 2231.27 289.222 2354.05 234.127C2414.95 207.062 2473.93 187.731 2532.9 178.065C2841.29 126.836 3117.78 293.088 3339.16 726.117Z' stroke='url(#paint33_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3359.46 721.284C3359.46 804.41 3826.4 1570.91 2936.03 1392.09C2873.19 1381.46 2812.28 1365.99 2752.35 1347.63C2600.57 1301.23 2462.32 1237.44 2332.78 1163.98C2254.47 1119.52 2180.03 1074.09 2111.39 1026.72C2089.16 1011.26 2066.92 995.793 2044.69 979.362C2035.02 972.595 2027.29 965.829 2019.55 960.03C2009.88 954.23 1995.38 940.698 1986.68 934.899C1977.01 929.099 1962.51 931.032 1952.85 924.266C1945.11 920.4 1936.41 918.467 1927.71 916.534C1905.48 910.734 1884.21 903.002 1863.91 895.269C1792.37 870.138 1725.66 844.04 1659.92 818.909C1526.51 766.713 1405.67 712.585 1286.76 668.122C1230.69 646.857 1175.58 628.492 1119.51 611.094C757.947 499.937 318.077 572.431 227.203 686.487C204.001 716.451 199.168 750.282 215.602 785.079C234.937 723.217 367.381 1194.91 798.551 1084.72C852.688 1072.15 909.726 1054.75 972.565 1030.59C988.033 1024.79 1004.47 1018.99 1019.94 1012.23C1133.04 963.896 1242.29 920.4 1345.73 879.804C1415.34 852.739 1482.04 823.742 1545.85 796.678C1566.15 787.978 1586.45 778.312 1606.75 771.546C1615.45 768.647 1623.19 765.747 1629.95 761.881C1638.65 755.114 1652.19 756.081 1660.89 749.315C1669.59 742.549 1684.09 727.084 1691.82 720.318C1699.56 713.552 1707.29 706.785 1715.99 699.053C1736.29 680.688 1756.6 662.323 1776.9 644.924C1844.57 584.996 1911.28 527.968 1977.98 474.806C2112.36 367.515 2240.94 280.523 2364.68 224.461C2425.59 197.397 2485.52 178.065 2544.5 167.433C2851.92 116.204 3131.31 281.489 3359.46 721.284Z' stroke='url(#paint34_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3378.8 715.484C3378.8 792.811 3866.04 1576.71 2956.33 1393.06C2892.53 1381.46 2830.66 1365.99 2770.72 1347.63C2617 1300.27 2476.83 1236.47 2346.32 1163.98C2267.04 1119.52 2191.64 1074.09 2122.03 1026.72C2098.83 1011.26 2076.59 995.793 2054.36 979.361C2044.69 972.595 2035.99 965.829 2028.26 960.03C2018.59 954.23 2004.09 940.698 1994.42 934.899C1984.75 929.099 1970.25 930.066 1960.58 923.3C1952.85 919.433 1944.15 917.5 1935.45 914.6C1913.21 907.834 1891.94 899.135 1870.68 891.402C1798.17 864.338 1730.5 836.307 1663.79 808.276C1528.45 752.215 1406.64 694.22 1286.76 647.824C1230.69 625.592 1174.62 606.261 1118.55 588.862C754.083 473.839 307.446 555.998 214.639 679.721C190.47 711.618 185.636 748.348 202.071 785.078C220.439 726.117 351.917 1216.17 788.886 1102.12C843.024 1089.55 901.029 1071.19 963.867 1046.06C979.335 1040.26 995.77 1033.49 1012.2 1026.72C1126.28 975.495 1236.49 929.099 1340.9 885.603C1411.47 856.606 1478.18 824.708 1542.95 796.677C1564.22 787.012 1583.55 777.346 1604.82 768.647C1613.52 765.747 1621.26 761.88 1628.99 758.014C1637.69 751.248 1652.19 751.248 1659.93 744.482C1668.63 737.716 1683.13 723.217 1691.83 715.484C1699.56 708.718 1707.3 701.952 1716 694.22C1736.3 675.855 1757.57 657.49 1777.87 639.124C1846.51 579.196 1914.18 521.201 1980.89 468.039C2117.2 359.782 2246.74 271.823 2371.45 215.761C2433.32 188.697 2493.26 168.399 2553.2 157.766C2863.52 106.538 3143.88 270.857 3378.8 715.484Z' stroke='url(#paint35_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3399.1 709.683C3399.1 782.176 3905.68 1583.47 2978.57 1393.06C2914.76 1381.46 2851.92 1365.99 2791.02 1347.63C2635.37 1300.26 2493.26 1236.47 2361.78 1163.98C2281.54 1119.51 2205.17 1073.12 2134.6 1025.75C2111.4 1010.29 2088.19 994.824 2065.96 978.392C2056.29 971.626 2047.59 964.86 2039.86 959.061C2030.19 953.261 2015.69 939.729 2006.02 933.93C1996.35 927.164 1980.89 928.13 1971.22 921.364C1963.48 917.498 1954.78 914.598 1945.12 911.698C1922.88 903.966 1900.65 895.266 1879.38 886.567C1805.9 857.57 1737.26 826.639 1670.56 797.642C1534.25 737.713 1411.47 675.852 1290.63 627.523C1233.59 604.325 1177.52 584.027 1120.48 565.662C753.117 447.739 300.679 537.631 204.005 671.986C179.836 705.816 174.035 745.446 190.47 784.109C207.872 729.014 337.416 1236.47 781.152 1119.51C836.257 1105.98 894.262 1086.65 958.067 1060.55C973.535 1053.79 989.97 1047.02 1006.4 1040.25C1122.41 987.092 1232.62 937.796 1338.97 890.433C1410.5 858.536 1478.18 825.672 1543.92 794.742C1565.18 785.076 1585.49 773.477 1606.75 764.778C1615.45 760.911 1623.19 758.012 1630.92 753.179C1639.62 745.446 1654.12 745.446 1662.83 738.68C1671.53 730.947 1686.03 717.415 1694.73 709.683C1702.46 702.916 1710.2 696.15 1718.9 687.451C1739.2 669.086 1760.47 650.721 1781.74 632.356C1851.34 572.428 1919.98 514.433 1987.65 460.304C2123 353.98 2254.47 265.055 2380.15 208.993C2442.02 180.962 2502.93 160.664 2562.87 150.031C2875.13 95.9027 3157.42 259.255 3399.1 709.683Z' stroke='url(#paint36_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3418.44 703.887C3418.44 771.547 3945.31 1589.28 2999.84 1394.03C2935.06 1382.43 2872.22 1366 2810.35 1347.63C2652.77 1299.3 2508.73 1236.47 2376.28 1163.98C2294.11 1119.52 2217.74 1073.12 2146.2 1025.76C2123 1010.29 2099.79 994.828 2076.59 978.396C2066.92 971.63 2058.22 964.864 2049.52 959.064C2039.86 952.298 2024.39 939.733 2014.72 933.933C2004.09 927.167 1989.58 927.167 1979.92 920.401C1971.22 916.535 1962.52 913.635 1953.82 909.769C1930.61 902.036 1909.34 892.37 1887.11 882.704C1812.67 850.807 1743.06 818.91 1675.39 787.013C1537.15 723.218 1413.4 658.457 1291.59 607.228C1234.56 583.064 1177.52 561.799 1120.48 543.434C750.215 421.645 291.011 520.236 191.436 665.223C166.3 701.953 160.5 742.55 176.934 784.113C192.402 732.884 320.98 1258.7 771.484 1137.88C826.588 1124.35 885.56 1104.05 949.365 1076.99C965.8 1070.22 982.235 1063.46 998.669 1054.76C1115.65 998.694 1227.79 946.499 1334.13 896.236C1406.64 862.406 1474.31 827.609 1541.01 794.745C1562.28 784.113 1583.55 772.514 1604.82 762.848C1613.52 758.982 1622.22 755.115 1628.99 750.282C1638.66 742.55 1652.19 741.583 1660.89 733.851C1670.56 726.118 1684.09 712.586 1693.76 704.853C1701.49 698.087 1709.23 690.354 1717.93 682.622C1739.2 664.257 1760.47 645.892 1780.77 627.527C1851.34 566.632 1919.98 508.637 1988.62 454.508C2127.83 344.318 2259.31 255.392 2386.92 198.364C2449.76 170.333 2510.66 150.035 2571.57 139.403C2885.76 86.2405 3169.98 247.66 3418.44 703.887Z' stroke='url(#paint37_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3438.74 698.086C3438.74 760.914 3985.92 1595.07 3021.11 1394.99C2955.37 1382.43 2892.53 1366.96 2830.66 1348.6C2671.15 1300.27 2526.13 1236.47 2391.76 1164.95C2308.62 1120.48 2231.28 1074.09 2158.77 1026.72C2134.6 1011.26 2111.4 995.793 2088.2 979.362C2078.53 972.596 2069.83 965.829 2061.13 960.03C2050.49 953.264 2035.99 940.698 2026.33 934.899C2015.69 928.133 2001.19 927.166 1990.56 920.4C1981.86 916.534 1973.15 912.667 1964.45 909.768C1941.25 901.068 1919.02 890.436 1896.78 880.77C1821.38 846.94 1750.8 813.109 1683.13 779.279C1543.92 711.618 1419.21 642.991 1296.43 589.829C1239.39 564.698 1181.39 542.466 1124.35 523.135C750.219 398.446 286.181 505.736 183.706 660.389C157.604 699.053 151.803 742.549 168.238 785.079C182.739 737.716 309.383 1280.94 765.687 1157.21C820.792 1143.68 880.73 1122.42 945.502 1094.38C961.937 1087.62 978.372 1079.89 994.807 1071.19C1112.75 1012.23 1225.86 957.13 1333.17 903.968C1406.64 868.205 1475.28 830.508 1541.99 795.711C1563.25 784.112 1584.52 772.513 1605.79 761.881C1614.49 758.014 1623.19 754.148 1630.93 748.348C1640.59 740.616 1654.13 738.683 1663.8 730.95C1673.46 723.217 1687 709.685 1696.66 701.952C1704.4 695.186 1713.1 687.454 1721.8 679.721C1743.07 660.389 1764.34 642.024 1785.61 623.659C1857.14 562.765 1926.75 503.803 1996.36 449.674C2136.53 339.484 2269.95 249.592 2399.49 191.597C2462.33 163.566 2524.2 142.301 2586.07 131.669C2897.36 75.607 3183.52 237.026 3438.74 698.086Z' stroke='url(#paint38_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3458.08 693.253C3458.08 751.248 4025.56 1601.84 3042.38 1396.93C2976.64 1384.36 2911.86 1367.93 2849.99 1349.56C2688.55 1301.23 2541.6 1237.44 2406.26 1165.91C2322.15 1121.45 2243.84 1075.05 2170.37 1027.69C2146.2 1012.23 2122.03 996.76 2099.8 980.328C2090.13 973.562 2081.43 966.796 2072.73 960.997C2062.09 954.23 2047.59 942.631 2036.96 935.865C2026.32 929.099 2011.82 928.133 2001.19 920.4C1992.49 915.567 1983.79 912.667 1974.12 908.801C1950.92 899.135 1927.72 888.503 1905.48 877.87C1829.11 842.107 1757.57 805.377 1688.93 770.58C1547.78 698.086 1422.11 626.559 1298.36 571.464C1240.36 545.366 1183.32 522.168 1125.32 502.836C747.319 373.314 276.513 488.338 171.138 653.623C145.035 694.22 138.268 739.649 154.703 785.078C168.237 741.582 293.914 1302.2 756.019 1175.58C812.091 1161.08 872.029 1139.81 936.801 1109.85C953.236 1102.12 969.67 1094.38 986.105 1085.69C1105.01 1024.79 1219.09 965.829 1327.37 909.768C1400.84 872.071 1471.41 832.441 1539.08 795.711C1561.32 784.112 1582.59 770.58 1603.86 759.947C1612.56 755.114 1621.26 751.248 1628.99 746.415C1638.66 738.683 1652.19 735.783 1661.86 728.05C1671.53 720.317 1685.06 706.785 1695.7 699.053C1703.43 692.287 1712.13 684.554 1720.83 676.821C1742.1 657.49 1764.34 639.125 1785.6 620.759C1858.11 558.898 1928.68 499.937 1998.29 445.808C2140.4 334.651 2274.78 243.792 2405.29 185.797C2469.09 156.8 2531.93 135.535 2592.84 124.903C2908 65.9412 3196.09 225.427 3458.08 693.253Z' stroke='url(#paint39_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3477.41 687.459C3477.41 740.621 4064.22 1608.61 3063.64 1397.9C2996.93 1385.33 2932.16 1368.9 2869.32 1349.57C2705.94 1301.24 2557.06 1237.44 2420.75 1164.95C2335.68 1120.49 2256.41 1074.09 2181.97 1026.73C2157.8 1011.26 2133.63 995.799 2110.43 979.367C2100.76 972.601 2091.09 965.835 2082.39 960.036C2071.76 953.269 2057.26 941.67 2046.62 934.904C2035.99 928.138 2021.49 926.205 2009.89 918.473C2001.19 913.64 1991.52 909.773 1982.82 905.907C1958.65 896.241 1936.41 884.642 1913.21 873.043C1835.87 835.346 1763.37 796.683 1693.76 758.986C1551.65 682.626 1425 608.2 1299.33 549.238C1241.32 522.174 1183.32 498.009 1124.35 477.711C744.414 346.256 267.808 469.978 159.532 644.93C132.463 688.426 125.696 735.788 142.131 783.151C154.699 742.555 278.442 1321.54 747.314 1192.02C803.386 1177.52 864.291 1155.29 930.03 1124.35C946.464 1116.62 962.899 1108.89 980.301 1099.22C1100.18 1035.43 1215.22 973.568 1324.46 914.606C1398.9 874.01 1469.47 833.413 1538.11 793.783C1560.35 781.218 1581.62 767.686 1603.85 756.087C1612.55 751.254 1621.25 746.421 1628.99 741.588C1638.66 733.855 1652.19 729.989 1662.82 722.256C1672.49 713.557 1686.99 700.992 1696.66 692.292C1704.39 685.526 1713.09 677.794 1721.8 670.061C1744.03 650.729 1765.3 632.364 1787.53 613.999C1861.01 552.138 1932.55 492.21 2003.12 438.081C2146.2 325.958 2282.51 235.099 2413.99 176.137C2477.79 147.14 2541.6 125.875 2603.47 114.276C2919.6 55.3146 3209.62 214.801 3477.41 687.459Z' stroke='url(#paint40_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3497.71 681.656C3497.71 729.985 4104.83 1614.41 3084.91 1398.86C3017.24 1385.33 2952.47 1368.9 2888.66 1350.53C2722.38 1301.24 2572.53 1237.44 2435.26 1165.91C2349.22 1121.45 2268.98 1075.06 2193.57 1027.69C2168.43 1012.23 2144.27 996.762 2121.06 980.33C2111.4 973.564 2101.73 966.798 2093.03 960.998C2081.43 954.232 2066.93 942.633 2056.29 935.867C2044.69 929.101 2030.19 926.201 2019.55 918.469C2010.85 913.636 2001.19 909.77 1991.52 904.937C1967.35 894.304 1944.15 881.739 1920.95 870.14C1842.64 829.543 1769.17 788.947 1699.56 750.283C1555.52 670.057 1427.91 591.764 1302.23 530.869C1243.26 502.838 1185.25 477.707 1126.28 457.409C743.449 323.054 261.042 454.509 148.9 640.093C121.831 685.522 114.097 734.818 130.531 785.08C142.132 748.35 263.942 1345.7 739.582 1212.31C796.62 1197.81 857.525 1174.61 923.264 1141.75C939.699 1134.02 957.1 1125.32 973.535 1115.65C1095.34 1048.96 1211.35 985.163 1321.56 922.335C1396.97 879.806 1468.51 836.309 1538.11 794.746C1560.35 781.214 1582.59 767.682 1604.82 755.116C1613.52 750.283 1622.22 745.451 1630.92 739.651C1641.56 730.952 1655.09 728.052 1664.76 719.353C1675.39 710.654 1688.93 698.088 1698.59 689.389C1707.3 682.623 1715.03 674.89 1724.7 667.157C1746.93 647.826 1769.17 629.461 1791.4 610.129C1865.84 547.301 1937.38 488.34 2008.92 432.278C2153.93 320.154 2291.21 227.362 2423.66 167.434C2488.43 138.437 2552.23 116.205 2615.07 104.606C2930.23 45.6449 3222.19 203.198 3497.71 681.656Z' stroke='url(#paint41_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3517.04 675.857C3517.04 719.353 4144.46 1620.21 3106.18 1398.86C3038.5 1385.33 2971.8 1368.9 2908.96 1349.56C2740.75 1300.27 2589.93 1236.47 2450.72 1164.95C2363.72 1120.48 2281.54 1074.09 2206.14 1025.76C2181 1010.29 2155.86 993.862 2132.66 978.397C2123 971.631 2113.33 964.865 2104.63 959.065C2093.03 952.299 2078.52 940.7 2067.89 932.967C2056.29 925.235 2041.79 922.335 2030.19 914.602C2021.49 909.769 2011.82 904.936 2002.15 901.07C1977.98 889.471 1954.78 876.906 1931.58 864.34C1852.31 821.81 1778.83 779.281 1707.29 738.684C1562.28 653.625 1433.7 573.399 1306.09 509.604C1247.12 480.607 1188.15 454.509 1129.18 433.244C741.514 297.923 252.34 438.077 137.297 633.327C109.261 680.689 101.527 732.885 117.962 785.08C128.596 752.216 248.473 1366.96 729.913 1230.67C786.951 1215.21 848.823 1192.01 915.528 1158.18C931.963 1149.48 949.365 1140.78 966.766 1131.12C1089.54 1062.49 1206.52 994.829 1317.7 929.101C1394.07 884.638 1465.61 839.209 1536.18 795.713C1558.42 781.214 1580.65 766.715 1603.85 754.15C1612.55 749.317 1621.25 743.517 1629.95 737.718C1640.59 729.018 1654.12 725.152 1663.79 716.453C1674.42 707.754 1687.96 695.188 1698.59 686.489C1707.29 679.723 1715.99 671.99 1724.7 664.258C1746.93 644.926 1769.17 625.594 1791.4 607.229C1865.84 544.401 1939.31 484.473 2010.85 428.411C2156.83 315.321 2296.04 222.529 2429.45 161.635C2495.19 131.671 2559 110.406 2621.84 97.8403C2941.83 35.9791 3234.75 191.599 3517.04 675.857Z' stroke='url(#paint42_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3536.38 670.05C3536.38 708.714 4184.1 1626.97 3127.44 1399.82C3058.81 1386.29 2992.1 1368.89 2928.29 1350.52C2758.15 1300.26 2605.4 1237.43 2465.22 1165.91C2377.25 1121.44 2294.11 1075.05 2216.77 1026.72C2191.63 1011.25 2166.5 994.822 2142.33 979.357C2132.66 972.591 2122.99 965.825 2113.33 960.025C2101.73 952.292 2087.23 941.66 2075.62 933.927C2064.02 926.195 2049.52 922.328 2037.92 914.596C2028.25 909.763 2019.55 904.93 2009.89 900.097C1984.75 887.531 1961.55 874.966 1938.35 861.434C1858.11 816.971 1783.67 772.508 1712.13 729.012C1566.15 640.086 1435.64 555.994 1308.03 490.266C1248.09 460.302 1189.12 433.238 1130.15 411.973C739.58 272.785 244.605 420.672 126.662 626.554C97.6599 675.85 89.926 729.979 106.361 784.107C115.061 755.11 234.938 1387.25 722.178 1247.1C779.216 1231.63 841.088 1206.5 908.761 1171.71C925.195 1163.01 942.597 1154.31 959.998 1143.68C1083.74 1072.15 1201.68 1001.59 1313.83 932.961C1390.2 886.565 1463.67 839.202 1534.25 792.806C1557.45 778.308 1579.68 762.842 1601.92 749.31C1610.62 743.511 1620.29 738.678 1628.02 731.912C1638.65 723.212 1652.19 718.38 1662.82 709.68C1673.46 700.981 1686.99 688.415 1697.63 679.716C1706.33 672.95 1715.03 665.218 1723.73 657.485C1745.96 638.153 1769.17 618.822 1791.4 600.456C1866.81 537.629 1941.25 476.734 2013.75 420.672C2161.66 306.616 2300.88 212.857 2436.22 151.962C2501.96 121.998 2566.73 99.7669 2630.54 87.2014C2952.46 25.3401 3248.29 180.96 3536.38 670.05Z' stroke='url(#paint43_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3555.72 665.219C3555.72 699.049 4222.77 1633.73 3147.75 1401.75C3078.15 1387.26 3011.44 1370.82 2946.67 1351.49C2774.59 1301.23 2619.91 1237.44 2478.76 1166.88C2389.82 1122.41 2305.71 1076.02 2227.41 1027.69C2201.31 1012.22 2176.17 995.79 2152 979.358C2142.33 972.592 2131.7 965.826 2123 960.027C2111.4 952.294 2096.9 941.662 2085.3 933.929C2072.73 926.196 2059.19 921.363 2046.63 913.631C2036.96 907.831 2027.29 902.998 2017.62 898.165C1992.49 885.6 1968.32 871.101 1945.12 857.569C1863.91 811.173 1788.5 764.777 1716 719.348C1568.09 626.556 1436.61 538.597 1308.03 470.936C1248.09 439.039 1188.15 411.975 1128.22 389.743C737.651 246.689 236.876 404.242 115.066 620.756C86.0633 672.952 77.3626 729.013 93.7973 785.075C101.531 759.944 219.474 1409.49 713.482 1266.43C771.487 1250 833.359 1224.87 901.031 1189.11C917.466 1180.41 934.867 1170.74 952.269 1160.11C1076.98 1085.68 1195.89 1012.22 1309 940.695C1386.34 891.399 1460.78 842.104 1532.32 794.741C1555.52 779.276 1577.75 763.81 1600.96 749.312C1609.66 743.512 1619.32 737.713 1628.02 731.913C1638.66 723.214 1652.19 717.414 1662.83 708.715C1674.43 700.016 1687 687.45 1698.6 678.751C1707.3 671.019 1716 664.253 1725.67 656.52C1748.87 637.188 1771.1 617.857 1794.31 598.525C1870.68 534.73 1946.08 473.836 2018.59 417.774C2167.47 302.751 2308.61 208.992 2444.93 147.131C2511.63 117.167 2576.4 93.9689 2641.18 81.4034C2964.07 15.6758 3260.86 169.362 3555.72 665.219Z' stroke='url(#paint44_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3576.02 659.422C3576.02 688.419 4263.37 1639.54 3169.98 1402.72C3100.38 1388.22 3032.71 1370.83 2966.97 1352.46C2792.95 1302.2 2636.34 1238.4 2494.23 1167.84C2404.32 1123.38 2319.25 1076.99 2239.97 1028.66C2213.87 1013.19 2188.74 996.759 2163.6 980.327C2152.97 973.561 2143.3 966.795 2133.63 960.995C2121.06 953.263 2107.53 942.63 2094.96 934.898C2082.39 927.165 2067.89 921.366 2056.29 913.633C2046.62 907.833 2036.96 903 2027.29 897.201C2002.15 883.669 1977.99 869.17 1953.82 854.671C1871.64 806.342 1795.27 757.047 1722.76 710.651C1573.89 613.992 1441.44 523.134 1310.93 452.573C1250.99 419.709 1191.05 391.678 1130.15 369.447C735.716 221.56 228.174 386.845 103.463 613.992C73.4942 668.121 64.7934 726.116 81.2281 785.077C87.9954 762.846 204.005 1431.72 704.78 1284.8C762.785 1268.37 825.623 1242.27 894.262 1205.54C911.664 1195.87 929.065 1186.21 946.467 1175.58C1072.14 1099.22 1192.02 1021.89 1307.06 947.463C1385.37 896.234 1459.81 845.005 1532.32 794.743C1555.52 778.311 1578.72 761.879 1601.92 746.414C1611.59 740.615 1620.29 733.849 1628.99 728.049C1640.59 719.35 1653.16 712.584 1664.76 703.884C1676.36 694.219 1689.89 682.62 1700.53 673.92C1709.23 666.188 1718.9 658.455 1727.6 650.722C1750.8 631.391 1774 612.059 1797.2 592.728C1874.54 528.933 1949.95 467.072 2024.39 411.01C2174.24 295.987 2316.35 200.295 2453.62 138.434C2520.33 107.503 2586.07 85.2718 2650.84 71.7396C2974.7 5.04545 3273.43 158.732 3576.02 659.422Z' stroke='url(#paint45_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3595.36 653.623C3595.36 677.788 4303.01 1645.34 3191.26 1403.69C3120.68 1389.19 3052.04 1371.79 2986.3 1352.46C2810.36 1301.23 2652.78 1238.41 2508.73 1167.84C2416.89 1123.38 2331.82 1076.99 2251.58 1028.66C2225.48 1013.19 2199.37 996.76 2174.24 980.328C2163.6 973.562 2153.94 966.796 2144.27 960.996C2131.7 953.264 2117.2 942.631 2105.6 934.899C2093.03 927.166 2078.53 921.366 2065.96 912.667C2056.29 906.868 2046.63 901.068 2036.96 896.235C2011.82 881.737 1986.69 867.238 1962.52 851.772C1879.38 801.51 1802.04 750.281 1728.57 700.986C1577.75 600.461 1444.34 505.736 1313.83 433.242C1252.93 399.412 1192.99 370.414 1132.08 347.216C733.785 196.43 220.442 369.448 92.8314 607.227C61.8955 663.289 53.1948 724.184 69.6295 785.078C75.4299 766.713 190.473 1452.99 696.082 1303.17C755.053 1286.73 817.892 1259.67 886.531 1221.01C903.932 1211.34 921.334 1201.68 938.735 1190.08C1065.38 1110.82 1187.19 1031.56 1302.23 953.264C1381.51 900.102 1456.91 845.973 1530.38 794.744C1554.55 778.312 1577.75 760.914 1600.96 744.482C1610.62 737.716 1619.32 731.916 1628.03 725.15C1639.63 715.484 1652.19 708.718 1663.8 700.019C1675.4 690.353 1688.93 678.754 1700.53 669.088C1709.23 661.356 1718.9 653.623 1727.6 645.89C1750.8 626.559 1774.97 607.227 1798.17 587.895C1876.48 523.134 1952.85 462.24 2027.29 405.211C2179.07 289.221 2323.12 193.53 2461.36 130.702C2529.03 99.7713 2594.77 76.5733 2660.51 63.0412C2985.34 -4.61958 3286.96 147.134 3595.36 653.623Z' stroke='url(#paint46_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3614.69 647.824C3614.69 667.156 4342.65 1652.1 3211.55 1404.66C3140.01 1389.19 3071.38 1371.79 3005.64 1352.46C2827.75 1301.23 2668.24 1237.44 2523.23 1167.85C2430.42 1123.38 2344.38 1076.02 2263.17 1028.66C2236.11 1013.19 2210 996.761 2184.87 980.329C2174.23 973.563 2164.57 966.797 2154.9 960.997C2142.33 953.264 2127.83 943.599 2115.26 934.899C2102.69 926.2 2088.19 920.401 2075.63 911.701C2065.96 905.902 2055.32 900.102 2045.66 894.303C2019.55 878.838 1995.39 863.372 1970.25 847.907C1886.14 794.745 1807.84 742.55 1734.36 691.321C1581.62 585.963 1447.24 488.338 1314.8 413.912C1253.89 379.115 1192.99 349.151 1132.08 325.953C731.848 171.299 211.738 353.017 81.227 601.429C50.2911 660.39 40.6236 723.218 57.0583 786.046C61.892 771.547 175.001 1475.22 687.377 1322.5C746.349 1305.1 810.154 1278.04 879.76 1238.41C897.161 1228.74 914.563 1218.11 932.931 1206.51C1061.51 1124.35 1183.32 1042.19 1299.33 960.997C1378.6 905.902 1454.97 849.84 1529.41 795.712C1553.58 778.313 1576.78 760.915 1600.95 743.516C1610.62 736.75 1619.32 729.984 1628.99 723.218C1640.59 713.552 1654.12 705.819 1665.73 696.154C1677.33 686.488 1690.86 674.889 1702.46 665.223C1711.16 657.49 1720.83 649.758 1730.5 642.025C1754.67 622.693 1777.87 602.395 1801.07 584.03C1880.34 519.269 1957.68 457.408 2033.09 400.379C2186.8 283.423 2331.81 187.731 2471.03 123.937C2538.7 93.0063 2606.37 69.8083 2672.11 55.3096C2996.94 -14.2843 3299.53 135.536 3614.69 647.824Z' stroke='url(#paint47_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3634.03 642.024C3634.03 656.523 4381.32 1657.9 3232.83 1404.66C3161.29 1389.19 3091.68 1371.79 3024.98 1352.46C2845.16 1300.27 2683.72 1237.44 2537.74 1167.84C2443.96 1123.38 2356.95 1076.02 2274.78 1027.69C2247.71 1012.23 2221.61 995.793 2195.51 979.361C2184.87 972.595 2175.21 965.829 2164.57 960.03C2151.04 952.297 2137.5 942.631 2124.94 933.932C2111.4 925.233 2097.87 918.467 2084.33 909.767C2074.66 903.968 2064.03 897.202 2054.36 891.402C2028.26 875.937 2003.13 859.505 1977.99 843.073C1892.92 787.978 1814.61 732.883 1739.2 679.721C1585.49 571.464 1450.15 469.972 1317.7 392.646C1255.83 356.882 1194.93 325.952 1133.05 301.787C729.92 144.234 204.01 333.684 70.5985 591.762C38.6958 652.657 29.0284 717.418 45.4631 782.179C49.33 773.479 160.506 1495.52 679.649 1339.9C738.621 1322.5 803.393 1294.47 872.998 1252.9C890.4 1243.24 907.801 1231.64 926.169 1220.04C1055.71 1134.98 1178.49 1049.92 1295.47 965.829C1375.71 907.834 1453.05 850.806 1528.45 794.744C1552.62 776.379 1576.79 758.014 1599.99 740.616C1609.66 733.849 1618.36 727.083 1628.03 719.351C1639.63 709.685 1653.16 700.986 1664.76 691.32C1677.33 681.654 1689.9 670.055 1702.47 660.389C1712.13 652.657 1720.84 644.924 1730.5 637.191C1754.67 616.893 1778.84 597.561 1802.04 578.23C1882.28 512.502 1960.59 450.641 2035.99 392.646C2190.67 274.723 2336.65 178.065 2477.8 114.27C2546.44 82.373 2614.11 59.175 2679.85 44.6763C3007.58 -24.9177 3312.1 124.903 3634.03 642.024Z' stroke='url(#paint48_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3653.36 637.195C3653.36 646.86 4420.96 1664.67 3253.13 1406.59C3180.62 1391.13 3111.01 1372.76 3043.34 1353.43C2861.59 1301.24 2698.21 1238.41 2551.27 1167.85C2456.53 1123.39 2368.55 1076.02 2285.41 1027.69C2258.34 1011.26 2231.27 995.797 2205.17 979.365C2194.54 972.599 2183.9 965.833 2174.24 960.033C2160.7 951.334 2147.17 942.635 2133.63 933.935C2120.1 925.236 2106.56 917.503 2093.03 908.804C2082.4 902.038 2072.73 896.239 2062.09 889.473C2035.99 873.041 2009.89 856.609 1984.75 839.21C1898.71 782.182 1819.44 725.154 1744.03 670.058C1589.35 556.968 1452.08 452.577 1318.67 373.318C1256.79 336.588 1194.92 304.69 1133.05 280.526C727.016 120.073 195.305 318.222 58.0271 585.966C26.1244 648.794 15.4902 716.454 31.9249 783.149C33.8584 775.416 144.067 1515.82 669.978 1356.33C730.883 1339.9 795.655 1310.9 866.228 1268.37C883.629 1257.74 901.997 1247.11 919.399 1234.54C1049.91 1147.55 1173.65 1058.62 1291.6 971.632C1372.8 911.704 1451.11 851.776 1526.52 793.781C1550.68 774.449 1574.85 756.084 1599.02 737.719C1608.69 729.986 1618.36 723.22 1627.06 715.488C1639.63 705.822 1652.19 696.156 1663.79 686.49C1676.36 676.825 1688.93 665.225 1701.5 655.56C1711.16 647.827 1720.83 640.094 1729.53 632.362C1753.7 612.063 1777.87 592.732 1802.04 573.4C1883.25 507.673 1961.55 444.845 2038.89 386.85C2195.5 268.927 2342.45 171.302 2484.56 105.574C2554.17 73.6772 2621.84 49.5126 2688.55 35.0139C3018.21 -34.5801 3324.67 113.307 3653.36 637.195Z' stroke='url(#paint49_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3673.66 631.39C3673.66 636.223 4461.56 1671.43 3275.36 1407.56C3201.89 1391.12 3131.32 1373.73 3063.64 1354.39C2879.96 1302.2 2715.61 1238.4 2566.74 1168.81C2471.03 1124.35 2382.09 1076.98 2297.98 1028.66C2269.94 1012.22 2242.88 996.759 2216.77 980.327C2206.14 973.561 2195.5 967.761 2184.87 960.995C2171.34 952.296 2156.83 943.596 2144.27 934.897C2130.73 926.198 2116.23 917.499 2102.7 908.8C2092.06 902.033 2082.4 895.267 2071.76 888.501C2045.66 871.103 2019.56 853.704 1993.45 836.306C1906.45 777.344 1826.21 718.383 1749.83 661.355C1593.22 544.398 1455.94 437.107 1320.6 354.948C1257.76 317.251 1196.86 284.387 1134.02 259.256C725.083 94.9373 186.605 301.786 47.3932 580.162C15.4906 645.889 3.88959 715.483 21.291 785.077C22.2578 781.211 131.5 1539.01 663.211 1376.63C723.149 1358.26 788.888 1328.3 859.461 1284.8C876.862 1274.17 895.23 1262.57 913.598 1250C1045.08 1160.11 1169.79 1068.29 1289.66 978.393C1371.84 916.532 1450.14 854.671 1526.52 794.743C1551.65 775.411 1575.82 756.08 1599.99 736.748C1609.66 729.015 1619.32 721.283 1628.99 714.517C1641.56 704.851 1654.13 695.185 1666.69 684.552C1679.26 673.92 1691.83 663.288 1704.4 653.622C1714.06 645.889 1723.73 638.157 1733.4 630.424C1757.57 610.126 1782.7 590.794 1806.87 571.462C1889.05 504.768 1968.32 441.94 2045.66 383.945C2203.24 265.056 2352.12 166.464 2495.2 100.737C2564.8 68.8396 2633.44 44.675 2701.11 29.2097C3029.81 -45.2171 3338.2 102.67 3673.66 631.39Z' stroke='url(#paint50_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M8.72248 785.078C8.72248 785.078 147.934 1792.26 905.864 1264.5C2184.87 374.281 2839.36 -707.324 3692.03 625.592C3692.03 625.592 4500.23 1677.23 3295.66 1408.52C2091.09 1139.81 1643.49 443.875 1135.95 237.993C628.407 32.1109 -82.1517 406.178 8.72248 785.078Z' stroke='url(#paint51_linear_14300_3682)' stroke-miterlimit='10'/>\n<defs>\n<linearGradient id='paint0_linear_14300_3682' x1='1569.05' y1='466.105' x2='1569.05' y2='1359.23' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint1_linear_14300_3682' x1='1577.72' y1='456.443' x2='1577.72' y2='1359.35' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint2_linear_14300_3682' x1='1586.47' y1='447.721' x2='1586.47' y2='1360.54' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint3_linear_14300_3682' x1='1593.22' y1='439.92' x2='1593.22' y2='1362.81' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint4_linear_14300_3682' x1='1603.02' y1='430.218' x2='1603.02' y2='1364.29' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint5_linear_14300_3682' x1='1610.25' y1='421.466' x2='1610.25' y2='1365.74' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint6_linear_14300_3682' x1='1619.17' y1='415.341' x2='1619.17' y2='1367.25' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint7_linear_14300_3682' x1='1626.48' y1='405.585' x2='1626.48' y2='1368.11' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint8_linear_14300_3682' x1='1635.32' y1='394.952' x2='1635.32' y2='1370.66' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint9_linear_14300_3682' x1='1641.92' y1='386.153' x2='1641.92' y2='1372.29' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint10_linear_14300_3682' x1='1650.93' y1='377.249' x2='1650.93' y2='1373.93' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint11_linear_14300_3682' x1='1658.32' y1='369.154' x2='1658.32' y2='1375.77' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint12_linear_14300_3682' x1='1665.62' y1='358.627' x2='1665.62' y2='1377.45' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint13_linear_14300_3682' x1='1675.76' y1='348.825' x2='1675.76' y2='1378.37' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint14_linear_14300_3682' x1='1682.56' y1='341.474' x2='1682.56' y2='1381.24' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint15_linear_14300_3682' x1='1690.7' y1='333.392' x2='1690.7' y2='1382.98' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint16_linear_14300_3682' x1='1698.83' y1='325.886' x2='1698.83' y2='1384.72' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint17_linear_14300_3682' x1='1706.39' y1='315.222' x2='1706.39' y2='1386.46' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint18_linear_14300_3682' x1='1714.88' y1='304.746' x2='1714.88' y2='1388.43' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint19_linear_14300_3682' x1='1722.24' y1='296.394' x2='1722.24' y2='1389.46' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint20_linear_14300_3682' x1='1730.63' y1='286.769' x2='1730.63' y2='1391.28' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint21_linear_14300_3682' x1='1738.78' y1='277.861' x2='1738.78' y2='1393.07' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint22_linear_14300_3682' x1='1745.64' y1='272.433' x2='1745.64' y2='1396.05' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint23_linear_14300_3682' x1='1755.52' y1='261.044' x2='1755.52' y2='1397.83' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint24_linear_14300_3682' x1='1763.16' y1='253.537' x2='1763.16' y2='1399.63' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint25_linear_14300_3682' x1='1770.42' y1='242.886' x2='1770.42' y2='1400.95' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint26_linear_14300_3682' x1='1779.51' y1='231.742' x2='1779.51' y2='1402.76' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint27_linear_14300_3682' x1='1786.48' y1='222.551' x2='1786.48' y2='1404.57' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint28_linear_14300_3682' x1='1795.3' y1='214.967' x2='1795.3' y2='1407.35' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint29_linear_14300_3682' x1='1801.57' y1='205.016' x2='1801.57' y2='1409.41' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint30_linear_14300_3682' x1='1809.73' y1='195.081' x2='1809.73' y2='1410.52' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint31_linear_14300_3682' x1='1818.93' y1='186.06' x2='1818.93' y2='1412.35' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint32_linear_14300_3682' x1='1827.12' y1='177.469' x2='1827.12' y2='1414.41' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint33_linear_14300_3682' x1='1835.07' y1='169.093' x2='1835.07' y2='1416.24' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint34_linear_14300_3682' x1='1843.87' y1='158.436' x2='1843.87' y2='1419.04' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint35_linear_14300_3682' x1='1850.78' y1='148.741' x2='1850.78' y2='1420.85' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint36_linear_14300_3682' x1='1859.19' y1='140.058' x2='1859.19' y2='1422.23' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint37_linear_14300_3682' x1='1866.24' y1='129.672' x2='1866.24' y2='1424.07' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint38_linear_14300_3682' x1='1876.16' y1='121' x2='1876.16' y2='1425.91' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint39_linear_14300_3682' x1='1883.4' y1='113.179' x2='1883.4' y2='1428.71' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint40_linear_14300_3682' x1='1890.83' y1='102.563' x2='1890.83' y2='1430.81' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint41_linear_14300_3682' x1='1899.49' y1='92.8154' x2='1899.49' y2='1432.65' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint42_linear_14300_3682' x1='1907.17' y1='84.9468' x2='1907.17' y2='1433.81' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint43_linear_14300_3682' x1='1915.36' y1='74.3203' x2='1915.36' y2='1435.9' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint44_linear_14300_3682' x1='1922.92' y1='67.0249' x2='1922.92' y2='1438.71' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint45_linear_14300_3682' x1='1931.15' y1='57.0142' x2='1931.15' y2='1440.56' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint46_linear_14300_3682' x1='1939.4' y1='47.8564' x2='1939.4' y2='1442.41' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint47_linear_14300_3682' x1='1947.19' y1='39.2847' x2='1947.19' y2='1444.51' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint48_linear_14300_3682' x1='1955.28' y1='28.668' x2='1955.28' y2='1445.68' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint49_linear_14300_3682' x1='1962.62' y1='18.9097' x2='1962.62' y2='1448.5' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint50_linear_14300_3682' x1='1971.67' y1='11.2061' x2='1971.67' y2='1450.61' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint51_linear_14300_3682' x1='1979.09' y1='0.921875' x2='1979.09' y2='1452.46' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n</defs>\n</svg>\n`,\n  darkSvgBG: `<svg id='bgAlphaBg' width='1920' height='1626' viewBox='0 0 1920 1626' fill='none' xmlns='http://www.w3.org/2000/svg'>\n<path opacity='0.1' d='M0 64L1046.69 1110.69H0V64Z' fill='url(#paint0_radial_0_1)'/>\n<path opacity='0.1' d='M0 266L814 1080H0V266Z' fill='url(#paint1_radial_0_1)'/>\n<path opacity='0.1' d='M2161 -461L540 1160H2161V-461Z' fill='url(#paint2_radial_0_1)'/>\n<path d='M5 -461H1915V1626H5V-461Z' fill='url(#paint3_radial_0_1)'/>\n<defs>\n<radialGradient id='paint0_radial_0_1' cx='0' cy='0' r='1' gradientUnits='userSpaceOnUse' gradientTransform='translate(523.344 587.344) rotate(134.7) scale(312.545)'>\n<stop stop-color='#67698E'/>\n<stop offset='1' stop-color='#50516F' stop-opacity='0'/>\n</radialGradient>\n<radialGradient id='paint1_radial_0_1' cx='0' cy='0' r='1' gradientUnits='userSpaceOnUse' gradientTransform='translate(407 673) rotate(134.7) scale(243.064)'>\n<stop stop-color='#67698E'/>\n<stop offset='1' stop-color='#50516F' stop-opacity='0'/>\n</radialGradient>\n<radialGradient id='paint2_radial_0_1' cx='0' cy='0' r='1' gradientUnits='userSpaceOnUse' gradientTransform='translate(1350.5 349.5) rotate(45.2997) scale(484.037)'>\n<stop stop-color='#67698E'/>\n<stop offset='1' stop-color='#50516F' stop-opacity='0'/>\n</radialGradient>\n<radialGradient id='paint3_radial_0_1' cx='0' cy='0' r='1' gradientUnits='userSpaceOnUse' gradientTransform='translate(578.497 110.606) rotate(58.751) scale(1070.04 1040.14)'>\n<stop stop-color='#4868A7' stop-opacity='0.44'/>\n<stop offset='1' stop-color='#1F2034' stop-opacity='0'/>\n</radialGradient>\n</defs>\n</svg>\n`,\n  lightSvgBG: `<svg id='bgAlphaBg' width='1920' height='1626' viewBox='0 0 1920 1626' fill='none' xmlns='http://www.w3.org/2000/svg'>\n<path opacity='0.1' d='M0 64L1046.69 1110.69H0V64Z' fill='url(#paint0_radial_14267_4338)'/>\n<path opacity='0.1' d='M0 266L814 1080H0V266Z' fill='url(#paint1_radial_14267_4338)'/>\n<path opacity='0.1' d='M2161 -461L540 1160H2161V-461Z'  fill='url(#paint2_radial_14267_4338)'/>\n<path d='M5 -461H1915V1626H5V-461Z' fill=''/>\n<defs>\n<radialGradient id='paint0_radial_14267_4338' cx='0' cy='0' r='1' gradientUnits='userSpaceOnUse' gradientTransform='translate(523.344 587.344) rotate(134.7) scale(312.545)'>\n<stop stop-color='#67698E'/>\n<stop offset='1' stop-color='#50516F' stop-opacity='0'/>\n</radialGradient>\n<radialGradient id='paint1_radial_14267_4338' cx='0' cy='0' r='1' gradientUnits='userSpaceOnUse' gradientTransform='translate(407 673) rotate(134.7) scale(243.064)'>\n<stop stop-color='#67698E'/>\n<stop offset='1' stop-color='#50516F' stop-opacity='0'/>\n</radialGradient>\n<radialGradient id='paint2_radial_14267_4338' cx='0' cy='0' r='1' gradientUnits='userSpaceOnUse' gradientTransform='translate(1350.5 349.5) rotate(45.2997) scale(484.037)'>\n<stop stop-color='#ACAED9'/>\n<stop offset='1' stop-color='#8C8EB7' stop-opacity='0'/>\n</radialGradient>\n</defs>\n</svg>`,\n}\n\nconst resources = {\n  en_US: {\n    common: {\n      labelNavZkRollupLayer2: 'zkRollup Layer 2',\n      labelNavWallet: 'Wallet',\n      labelNavLanuch: 'Launch App',\n      labelAbout: 'About',\n      labelLoopringOrg: 'Loopring.org',\n      labelLoopringTerms: 'Terms of Service',\n      labelPrivacyPolicy: 'Privacy Policy',\n      labelRiskDisclosure: 'Risk Disclosure',\n      labelSupport: 'Support',\n      labelSubmitARequest: '❤️ Submit a Request',\n      labelCreatorGrants: 'Creator Grants',\n      labelListAToken: 'List a Token',\n      labelWalletGuardian: 'Wallet Guardian',\n      labelPlatform: 'Platform',\n      labelFees: 'Fees',\n      labelVIPProgram: 'VIP Program',\n      labelReferrals: 'Referrals',\n      labelDevelopers: 'Developers',\n      labelDeveloper: 'Developer',\n      labelSmartContracts: 'Smart Contracts',\n      labelAPIs: 'APIs',\n      labelLayer2Explorer: 'Layer 2 Explorer',\n      labelBugBounty: 'Bug Bounty',\n      labelSubgraph: 'Subgraph',\n      labelFollowus: 'Follow us',\n      labelDocumentation: 'Documentation',\n      labelLoopring: 'Loopring',\n      labelDeveloper1: 'Developer',\n      labelTitleDes:\n        'Our API, SDK, and step-by-step references to building, minting, and trading on Loopring',\n      labelCopyRight: '© 2017 Loopring Technology Limited. All rights reserved.',\n      labelLearnMore: 'Learn More',\n      labelLoopringWalletDes: 'Your gateway to Ethereum, DeFi, NFTs, and Financial Freedom.',\n      labelDappDes:\n        'Explore the Loopring DEX, Earn, and NFT Management. Powered by zkRollups, experience instant transactions with 100x lower fees than Ethereum without sacrificing any of its security.',\n      labelGuardians: 'Set up Guardians for social recovery',\n      labelCloudbackup: 'Cloud backup',\n      label2FA: 'Two-Factor Authentication (2FA)',\n      labelActivate: 'How to connect a wallet and activate your Loopring account',\n      labelMintNFT: 'How to mint an NFT',\n      labelLoopringEarn: 'How to participate in \"Loopring Earn\"',\n    },\n  },\n  // zh_CN: {...zhCN},\n}\n\n// const initLng = JSON.parse(localStorage.getItem('persist:settings') as string)?.language === `\"${LanguageType.zh_CN}\"` ? LanguageType.zh_CN : LanguageType.en_US\nconst initLng = 'en_US'\nconsole.log('en_US')\nconst settingPersist = 'persist:settings'\nconst basicUrl = 'https://static.loopring.io/assets/images/landPage/'\n;(function init() {\n  let themeMode = 'dark'\n  let settingPersistJson = localStorage.getItem(settingPersist)\n  let settings = JSON.parse(settingPersistJson ? settingPersistJson : '{}')\n  if (settings.themeMode && JSON.parse(settings.themeMode)) {\n    themeMode = JSON.parse(settings.themeMode)\n  }\n  const onColorChange = (value = 'dark', _this) => {\n    settings.themeMode = JSON.stringify(value)\n    window.localStorage.setItem(settingPersist, JSON.stringify(settings))\n    let link = document.getElementById('themeModeCss')\n    link.setAttribute('href', value !== 'light' ? './dark.css' : './light.css')\n    if (_this) {\n      _this.setAttribute('value', value)\n    }\n  }\n  const onColorChangeLoaded = (value = 'dark') => {\n    const imageEnd = value !== 'light' ? '.png' : '_light' + '.png'\n\n    document.getElementById('bgContent').style = `\n    background:url(${basicUrl}api_bg.webp) center 104px no-repeat;\n     background-size:50%;\n    `\n    // value !== 'light'\n    //   ? svgGroup.blackSvg + svgGroup.darkSvgBG\n    //   : svgGroup.lightSvg + svgGroup.lightSvgBG\n    // document.getElementById('changeColor').innerHTML =\n    //   value !== 'light' ? svgGroup.DarkIcon : svgGroup.LightIcon\n    // document.getElementById('changeColor').setAttribute('data-theme', themeMode)\n  }\n\n  onColorChange(themeMode !== 'dark' ? 'light' : 'dark')\n  window.onGlobalChange = () => {\n    themeMode = themeMode !== 'dark' ? 'dark' : 'light'\n    onColorChange(themeMode)\n    onColorChangeLoaded(themeMode)\n  }\n  // Language now english only\n  const onlanguagechange = (value) => {\n    let settingPersistJson = localStorage.getItem(settingPersist)\n    let settings = JSON.parse(settingPersistJson ? settingPersistJson : '{}')\n    settings.language = value\n    window.localStorage.setItem(settingPersist, JSON.stringify(settings))\n    i18next.changeLanguage('en_US')\n  }\n  const updateI18n = () => {\n    // document.getElementById('labelNavZkRollupLayer2').innerHTML =\n    //   i18next.t('labelNavZkRollupLayer2')\n    // document.getElementById('labelDeveloper').innerHTML = i18next.t('labelDeveloper')\n    document.getElementById('labelNavWallet').innerHTML = i18next.t('labelNavWallet')\n    document.getElementById('labelNavLanuch').innerHTML = i18next.t('labelNavLanuch')\n    document.getElementById('labelAbout').innerHTML = i18next.t('labelAbout')\n    document.getElementById('labelLoopringOrg').innerHTML = i18next.t('labelLoopringOrg')\n    document.getElementById('labelLoopringTerms').innerHTML = i18next.t('labelLoopringTerms')\n    document.getElementById('labelPrivacyPolicy').innerHTML = i18next.t('labelPrivacyPolicy')\n    document.getElementById('labelRiskDisclosure').innerHTML = i18next.t('labelRiskDisclosure')\n    document.getElementById('labelSupport').innerHTML = i18next.t('labelSupport')\n    document.getElementById('labelSubmitARequest').innerHTML = i18next.t('labelSubmitARequest')\n    document.getElementById('labelCreatorGrants').innerHTML = i18next.t('labelCreatorGrants')\n    document.getElementById('labelListAToken').innerHTML = i18next.t('labelListAToken')\n    document.getElementById('labelWalletGuardian').innerHTML = i18next.t('labelWalletGuardian')\n    document.getElementById('labelPlatform').innerHTML = i18next.t('labelPlatform')\n    document.getElementById('labelFees').innerHTML = i18next.t('labelFees')\n    document.getElementById('labelVIPProgram').innerHTML = i18next.t('labelVIPProgram')\n    document.getElementById('labelReferrals').innerHTML = i18next.t('labelReferrals')\n    document.getElementById('labelDevelopers').innerHTML = i18next.t('labelDevelopers')\n    document.getElementById('labelSmartContracts').innerHTML = i18next.t('labelSmartContracts')\n    document.getElementById('labelAPIs').innerHTML = i18next.t('labelAPIs')\n    document.getElementById('labelLayer2Explorer').innerHTML = i18next.t('labelLayer2Explorer')\n    document.getElementById('labelBugBounty').innerHTML = i18next.t('labelBugBounty')\n    document.getElementById('labelSubgraph').innerHTML = i18next.t('labelSubgraph')\n    document.getElementById('labelFollowus').innerHTML = i18next.t('labelFollowus')\n    document.getElementById('labelLoopring').innerHTML = i18next.t('labelLoopring')\n    document.getElementById('labelDeveloper1').innerHTML = i18next.t('labelDeveloper1')\n    document.getElementById('labelTitleDes').innerHTML = i18next.t('labelTitleDes')\n    document.getElementById('labelDocumentation').innerHTML = i18next.t('labelDocumentation')\n    document.getElementById('labelCopyRight').innerHTML = i18next.t('labelCopyRight')\n    document.getElementById('labelLearnMore').innerHTML = i18next.t('labelLearnMore')\n    document.getElementById('labelLearnMore2').innerHTML = i18next.t('labelLearnMore')\n    document.getElementById('labelLoopringWalletDes').innerHTML =\n      i18next.t('labelLoopringWalletDes')\n    document.getElementById('labelDappDes').innerHTML = i18next.t('labelDappDes')\n    document.getElementById('labelGuardians').innerHTML = i18next.t('labelGuardians')\n    document.getElementById('labelCloudbackup').innerHTML = i18next.t('labelCloudbackup')\n    document.getElementById('label2FA').innerHTML = i18next.t('label2FA')\n    document.getElementById('labelActivate').innerHTML = i18next.t('labelActivate')\n    document.getElementById('labelMintNFT').innerHTML = i18next.t('labelMintNFT')\n    document.getElementById('labelLoopringEarn').innerHTML = i18next.t('labelLoopringEarn')\n  }\n\n  const upLoadSvg = () => {\n    document.getElementById('logSvg').innerHTML = svgGroup.logSvg\n    // document.getElementById('iconIos').innerHTML = svgGroup.ios\n    // document.getElementById('iconAndroid').innerHTML = svgGroup.android\n    // document.getElementById('iconGooglePlay').innerHTML = svgGroup.googlePlay\n    // document.getElementById('iconIos2').innerHTML = svgGroup.ios\n    // document.getElementById('iconAndroid2').innerHTML = svgGroup.android\n    // document.getElementById('iconGooglePlay2').innerHTML = svgGroup.googlePlay\n    document.getElementById('youtubeIcon').innerHTML = svgGroup.youtubeIcon\n    document.getElementById('twitterIcon').innerHTML = svgGroup.twitterIcon\n    document.getElementById('mediumIcon').innerHTML = svgGroup.mediumIcon\n    document.getElementById('discordIcon').innerHTML = svgGroup.discordIcon\n  }\n\n  window.onload = () => {\n    i18next\n      // .use(i18nextHttpBackend)\n      .use(i18nextBrowserLanguageDetector)\n      .init(\n        {\n          resources,\n          debug: false,\n          ns: ['common'],\n          defaultNS: 'common',\n          lng: initLng,\n          fallbackLng: initLng,\n          keySeparator: '.', // we do not use keys in form messages.welcome\n          interpolation: {\n            escapeValue: true, // react already safes from xss\n            formatSeparator: `, `,\n          },\n        },\n        function (err, t) {\n          // init set content\n          updateI18n()\n        },\n      )\n    var i18nLng = window.localStorage.getItem('lng')\n    if (!i18nLng) {\n      i18nLng = 'en'\n    }\n    upLoadSvg()\n    onlanguagechange(i18nLng)\n    onColorChangeLoaded(themeMode)\n\n    // const handleScroll = () => {\n    //   const imgs = document.getElementsByClassName(\"scroll-up-img\");\n    //   for (let index = 0; index < imgs.length; index++) {\n    //     const img = imgs.item(index);\n    //     if (img.getBoundingClientRect().top < window.innerHeight) {\n    //       img.style.opacity = 1;\n    //       img.style.transform = \"translateY(0)\";\n    //     }\n    //   }\n    // };\n    // setTimeout(() => {\n    //   handleScroll();\n    // }, 50);\n    //\n    // window.addEventListener(\"scroll\", handleScroll);\n    // let clear = -1;\n    // var options = document.getElementsByName(\"slider\"); //.options;\n\n    // function loopScroll() {\n    //   if (clear !== -1) {\n    //     clearTimeout(clear)\n    //   }\n    //   let i = [].slice.call(options).findIndex((item) => item.checked == true)\n    //   let next = i + 1\n    //   options[options.length - next > 0 ? next : 0].checked = true\n    //   clear = setTimeout(() => {\n    //     if (window.innerWidth < 768) {\n    //       loopScroll()\n    //     }\n    //   }, 3000)\n    // }\n\n    // loopScroll()\n  }\n})()\n"
  },
  {
    "path": "packages/web-developer/public/developer.scss",
    "content": "body {\n  background: var(--color-global-Bg);\n  font-family: Roboto, Helvetica, Arial, '华文细黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体',\n  Heiti, '黑体', sans-serif;\n  user-drag: none;\n  user-select: none;\n}\n\nsvg {\n  fill: var(--color-text-primary);\n}\n\nbutton {\n  border: 1px solid var(--color-border);\n  border-radius: 2px;\n  box-sizing: border-box;\n\n  &:hover {\n    border: 1px solid var(--color-border-hover);\n  }\n}\n\n.Typography-root {\n  font-size: 14px;\n  color: var(--color-text-primary);\n}\n\n.Typography-h4 {\n  font-size: var(--h4);\n}\n\n.Typography-subtitle {\n  font-size: var(--subtitle);\n}\n\n.Typography-h1 {\n  font-size: var(--h1);\n}\n\n.Typography-h2 {\n  font-size: var(--h2);\n}\n\nheader {\n  .headerGg {\n    width: 100vw;\n    //background-color: var(--color-box);\n  }\n\n  .Toolbar-root {\n    height: var(--header-height);\n    //background-color: var(--color-box);\n    display: flex;\n    flex-direction: row;\n    justify-content: space-between;\n    align-items: center;\n  }\n\n  nav {\n    display: flex;\n    flex-direction: row;\n    align-items: center;\n\n    ul {\n      margin-left: 24px;\n\n      li {\n        display: inline-block;\n        height: var(--header-height);\n        line-height: var(--header-height);\n        padding: 0 8px;\n      }\n    }\n  }\n}\n\n.flexBox {\n  display: flex;\n}\n\n.flex-column {\n  flex-direction: column;\n}\n\n.flex-row {\n  flex-direction: row;\n}\n\n.align-center {\n  align-items: center;\n}\n\n.stretch {\n  justify-content: stretch;\n}\n\n/* Rectangle 1662 */\n\n#labelNavLanuch {\n  /*width: 112px;*/\n  padding: 0 16px;\n  line-height: 36px;\n  height: 36px;\n  border-radius: 2px;\n  border: 0;\n  /*border: 1px solid;*/\n  /*border-image: linear-gradient(90deg, #D7B2FF 0%, #77AAFF 53.24%) 1;*/\n  color: var(--color-text-primary);\n  border-image-repeat: round;\n  position: relative;\n  z-index: 99;\n  box-sizing: border-box;\n}\n\n#labelNavLanuch:after {\n  top: 0;\n  left: 0;\n  right: 0;\n  bottom: 0;\n  position: absolute;\n  content: '';\n  border-radius: 2px;\n  z-index: -1;\n  border: 2px solid;\n  border-image: linear-gradient(224.95deg, #79FAAC -5.39%, #4F5AE4 96.95%) 1;\n}\n\n#logo {\n  min-width: auto;\n  border-radius: 0px;\n  text-indent: -999999em;\n  background: var(--color-logo);\n  -webkit-mask: url(https://static.loopring.io/assets/svg/logo.svg) center center / contain space;\n  width: 105px;\n  height: 40px;\n  padding: 8px;\n  color: transparent;\n  display: inline-flex;\n  align-items: center;\n  justify-content: center;\n  position: relative;\n  box-sizing: border-box;\n  outline: 0px;\n  border: 0px;\n  margin: -10px 0px 0px -12px;\n  cursor: pointer;\n\n  &::after {\n    content: 'beta';\n    position: absolute;\n    color: var(--color-logo);\n    display: block;\n    font-size: 1rem;\n    line-height: 0.8rem;\n    right: -24px;\n    top: 14px;\n    font-weight: 200;\n    opacity: 0;\n    box-shadow: 0 0 1px 0 var(--color-logo);\n    border-radius: 2px;\n    padding: 3px 2px;\n  }\n\n  svg {\n    fill: var(--color-text-Secondary);\n  }\n}\n\n/* identical to box height, or 129% */\n\n.Container-root,\n.wrap {\n  max-width: calc(1200px - 32px);\n  padding: 0 16px;\n  margin: 0 auto;\n}\n\na.Typography-root,\na.Typography-root:active,\na.Typography-root:visited,\n.Link-root,\n.Link-root:active,\n.Link-root:visited,\n.MenuItem-root a.Typography-root,\n.MenuItem-root a.Typography-root:active,\n.MenuItem-root a.Typography-root:visited,\n.Link-root {\n  color: var(--color-text-Secondary);\n}\n\na.Typography-root:hover,\n.MenuItem-root a.Typography-root:hover,\n.Link-root:hover {\n  color: var(--color-text-primary);\n}\n\n.Link-underlineAlways:hover {\n  text-decoration: underline;\n}\n\nbody {\n  display: flex;\n  flex-direction: column;\n  justify-content: flex-start;\n  height: 100%;\n}\n\n.sectionFull {\n  width: 100vw;\n  margin: 80px 0;\n\n  a {\n    display: inline-flex;\n    align-items: center;\n    color: var(--color-text-primary);\n\n    &:hover {\n      color: var(--color-primary);\n\n      svg {\n        fill: var(--color-primary);\n      }\n    }\n  }\n\n  button {\n    &:hover {\n      border: 1px solid var(--color-border-hover);\n\n      svg {\n        fill: var(--color-border-hover);\n      }\n    }\n  }\n\n  .wrap:nth-child(even) {\n    flex-direction: row-reverse;\n  }\n\n  &:nth-child(odd) .img-container {\n    display: flex;\n    justify-content: flex-end;\n  }\n\n  .wrap {\n    justify-content: space-between;\n    display: flex;\n    flex-direction: row;\n    align-items: center;\n  }\n}\n\nh3.Typography-root {\n  font-size: var(--h1);\n}\n\nh3 ~ p.Typography-root {\n  color: var(--color-text-third);\n  font-size: var(--h5);\n}\n\n.cardBtnGroup {\n  justify-content: stretch;\n  margin-top: 80px;\n\n  .wrap-svg {\n    padding: 16px;\n    border-radius: 50%;\n    background: var(--dark900);\n    margin-bottom: 24px;\n\n    svg {\n      height: 48px;\n      width: 48px;\n      fill: var(--color-text-Button);\n    }\n  }\n\n  .des {\n    margin-top: 8px;\n    color: var(--color-text-third);\n  }\n\n  button {\n    box-sizing: border-box;\n    width: 388px;\n    height: 285px;\n    background: var(--dark);\n    border: 1px solid var(--dark600);\n    border-radius: 8px;\n    margin: 0 12px;\n    padding: 0 24px;\n    justify-content: center;\n    align-items: center;\n\n    &:hover {\n      border: 1px solid var(--color-border-hover);\n\n      .wrap-svg {\n        background: var(--dark800);\n      }\n    }\n  }\n\n}\n\n.banner {\n  .right-part {\n    margin-left: 120px;\n    align-self: flex-end;\n  }\n}\n\n/* Ethereum Unleashed */\n\n#LoopringDeveloperBox {\n  height: 72px;\n  font-size: 64px;\n  line-height: 72px;\n  font-weight: 700;\n  margin-top: 184px;\n  margin-bottom: 16px;\n  display: inline-flex;\n  width: 50%;\n  align-items: flex-end;\n}\n\n#labelLoopring {\n  height: 72px;\n  width: fit-content;\n  background: linear-gradient(224.95deg, #79FAAC -5.39%, #4F5AE4 96.95%),\n  linear-gradient(231.69deg, #79FAAC 39.53%, #4F5AE4 89.75%);\n  -webkit-background-clip: text;\n  -webkit-text-fill-color: transparent;\n  /*background-clip: text;*/\n  border-radius: 2px;\n  text-fill-color: transparent;\n  text-align: center;\n\n}\n\n#labelTitleDes {\n  line-height: 1.5em;\n  font-size: var(--h5);\n  text-align: left;\n  color: var(--dark400);\n\n}\n\nfooter {\n  flex: 1;\n  display: flex;\n  flex-direction: column;\n  justify-content: flex-end;\n\n  .Container-root {\n    display: flex;\n    flex-direction: column;\n  }\n\n\n  .content {\n    margin-top: 24px;\n    //margin-bottom: 24px;\n  }\n\n  .followUs {\n    width: 100%;\n    background: url(https://static.loopring.io/assets/images/landPage/docFooter.webp) no-repeat 50% 50%;\n    height: 367px;\n    background-size: cover;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    flex-direction: column;\n\n    .footerContentList {\n      justify-content: center;\n\n      ul {\n        width: 376px;\n        display: flex;\n        flex-direction: row;\n        justify-content: space-between;\n\n        .icon svg {\n          font-size: var(--h5);\n          fill: var(--color-text-Secondary);\n          width: 40px;\n          height: 40px;\n        }\n\n        a.icon:hover svg {\n          fill: var(--color-text-primary);\n        }\n      }\n    }\n  }\n\n\n  .group {\n    padding-top: 16px;\n\n    h6 {\n      font-size: var(--body2);\n      color: var(--color-text-third);\n      line-height: 4em;\n      padding-bottom: 8px;\n    }\n\n    .Typography-root {\n      font-size: var(--body2);\n      line-height: 2em;\n    }\n\n    #labelFollowus {\n      font-size: var(--h1);\n      color: var(--color-text-primary);\n    }\n  }\n}\n\n.Button-root {\n  cursor: pointer;\n}\n\n\n#labelCopyRight {\n  color: var(--color-text-third);\n  text-align: center;\n  height: 40px;\n  line-height: 40px;\n}\n\n.logoDex {\n  display: flex;\n  flex-direction: column;\n  justify-content: space-evenly;\n}\n\n.logoDex p:first-child {\n  color: var(--color-text-primary);\n  font-size: var(--h5);\n}\n\n.logoDex p:last-child {\n  color: var(--color-text-third);\n}\n\n.carousel-container {\n  --height: 596px;\n  --width: 280px;\n  --size-image: 0.8;\n  display: flex;\n  margin-top: 120px;\n  overflow: hidden;\n  width: 800px;\n  height: calc(var(--height) + 32px);\n  transform-style: preserve-3d;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  overflow: hidden;\n\n  .container {\n    height: 100%;\n    width: 100%;\n  }\n\n  #slider {\n    width: 100vw;\n    height: 100%;\n    display: flex;\n    justify-content: center;\n    align-items: center;\n  }\n\n  input[type='radio'] {\n    display: none;\n  }\n\n  .cards {\n    position: relative;\n    width: 100%;\n    height: 100%;\n  }\n\n  .card {\n    position: absolute;\n    top: 50%;\n    left: 50%;\n    margin-left: calc(var(--width) / -2);\n    margin-top: calc(var(--height) / -2);\n    cursor: pointer;\n    transition: transform 0.4s cubic-bezier(0.165, 0.84, 0.44, 1);\n  }\n\n  img {\n    width: var(--width);\n    object-fit: cover;\n    //border-radius: 32px;\n    //width: 100%;\n    //height: 100%;\n    //object-fit: cover;\n  }\n}\n\n.sectionDetail {\n  width: 580px;\n  height: 492px;\n  min-width: 340px;\n  background: var(--dark);\n  border-radius: 8px;\n  display: flex;\n  flex-direction: column;\n  justify-content: center;\n\n  h3 {\n    svg {\n      width: 36px;\n      height: 36px;\n    }\n  }\n\n  .labelDocDes {\n    margin-top: 8px;\n    margin-bottom: 32px;\n    line-height: 1.2em;\n  }\n\n  .learnMore {\n    margin-top: 32px;\n    line-height: 1.2em;\n    color: var(--color-text-primary);\n    align-items: center;\n    display: inline-flex;\n    flex-direction: row;\n  }\n\n  ul {\n    width: 500px;\n\n    li {\n      margin: 16px 0;\n      width: 100%;\n\n      button {\n        width: 100%;\n        height: 56px;\n        line-height: 1.8rem;\n        display: flex;\n        flex-direction: row;\n        color: var(--color-text-primary);\n        border: 1px solid var(--dark600);\n        border-radius: 8px;\n        padding: 0px 16px;\n        justify-content: space-between;\n        align-items: center;\n\n        span {\n          display: inline-flex;\n          flex-direction: row;\n          align-items: center;\n          text-align: left;\n          line-height: 1.2em;\n        }\n      }\n    }\n  }\n}\n\n.img-container {\n  width: 50%;\n  min-width: 50%;\n  display: flex;\n  margin-top: 24px;\n  justify-content: center !important;\n}\n\n#bgContent {\n  position: absolute;\n  z-index: 1;\n  top: 0;\n  right: 0;\n  left: 0;\n  width: 100%;\n  height: 100vh;\n  overflow: hidden;\n  pointer-events: none;\n\n  #bgAlphaBg {\n    position: absolute;\n    pointer-events: none;\n    transform: translate(0, -300px) rotate(0);\n    top: 0;\n    left: 0;\n    width: 100%;\n  }\n\n  #bgAlpha {\n    position: absolute;\n    pointer-events: none;\n    transform: translate(12%, -40%) rotate(-13deg);\n  }\n}\n\n@media only screen and (max-width: 1024px) {\n  .Container-root,\n  .wrap {\n    width: 100vw;\n    padding: 0 16px;\n    margin: 0 auto;\n  }\n  .cardBtnGroup {\n    margin-top: 32px;\n  }\n  .carousel-container {\n    display: flex;\n    overflow: hidden;\n    align-items: center;\n    width: 100%;\n    align-items: center;\n    justify-content: center;\n    margin-top: 40px;\n  }\n\n  #logo {\n    min-width: auto;\n    /*border-radius: 0px;*/\n    /*text-indent: -999999em;*/\n    background: var(--color-logo);\n    -webkit-mask: url(https://static.loopring.io/assets/svg/loopring.svg) center center / contain space;\n    width: 40px;\n    height: 40px;\n    margin-left: 8px;\n  }\n\n  h3.Typography-root {\n    font-size: var(--h4);\n    text-align: center;\n  }\n\n  h3 ~ p.Typography-root {\n    font-size: var(--body);\n    white-space: initial;\n  }\n\n  header ul li:first-child {\n    display: none;\n  }\n\n  .downLoadBtnGroup {\n    flex-direction: column;\n    justify-content: space-between;\n    height: calc(48px * 3 + 16px * 3);\n    margin-left: 0;\n  }\n\n  .downLoadBtnGroup button {\n    margin-left: 0;\n  }\n\n  footer {\n    .footerWallet .wrap {\n      flex-direction: column;\n      align-items: center;\n      justify-content: space-between;\n    }\n\n    .downLoadBtnGroup {\n      margin-top: 24px;\n    }\n\n    .content {\n      flex-direction: column;\n    }\n\n    .followUs {\n      .footerContentList {\n        ul {\n          width: 320px;\n        }\n      }\n    }\n  }\n  #LoopringDeveloperBox {\n    font-size: 36px;\n    margin-top: 32px;\n    width: 100%;\n  }\n\n\n  #logSvg {\n    display: none;\n  }\n\n  .sectionFull {\n    align-items: flex-start;\n    justify-content: center;\n    height: initial;\n    margin: 80px 0;\n  }\n\n  .sectionFull .wrap {\n    //flex-direction: column !important;\n    flex-direction: column-reverse !important;\n  }\n\n  .carousel-container {\n    --size-image: 0.5;\n  }\n  #bgContent {\n    #bgAlphaBg {\n      display: none;\n    }\n\n    #bgAlpha {\n      position: absolute;\n      pointer-events: none;\n      transform: translate(-30%, -20%) rotate(13deg) scale(0.5);\n    }\n  }\n  .sectionDetail {\n    min-width: 340px;\n    height: 492px;\n    width: 100%;\n    max-width: 480px;\n  }\n  .sectionDetail ul {\n    min-width: 340px;\n    width: 100%;\n    max-width: 480px;\n  }\n  .banner {\n    flex-direction: column;\n    align-items: center;\n\n    .right-part {\n      margin-left: 0px;\n      margin-top: 24px;\n      align-self: initial;\n    }\n  }\n  .cardBtnGroup {\n    margin-top: 32px;\n    flex-direction: column;\n    align-items: center;\n\n    button {\n      margin: 8px;\n      max-width: 388px;\n      width: 100%;\n    }\n  }\n\n\n}\n\n.labelDocumentation {\n  --borderWidth: 3px;\n  background: var(--color-global-Bg);\n  position: relative;\n  display: inline-flex;\n  align-items: center;\n  padding: 8px;\n\n  &:hover {\n    border: 0;\n    box-shadow: 0 5px 15px #f7953304, 0 10px 30px #f3705502;\n    animation: boxShow 3s ease alternate infinite;\n\n    &:after {\n      content: '';\n      position: absolute;\n      top: calc(-1 * var(--borderWidth));\n      left: calc(-1 * var(--borderWidth));\n      right: calc(-1 * var(--borderWidth));\n      bottom: calc(-1 * var(--borderWidth));\n      background: linear-gradient(\n                      60deg,\n                      #f79533,\n                      #f37055,\n                      #ef4e7b,\n                      #a166ab,\n                      #5073b8,\n                      #1098ad,\n                      #07b39b,\n                      #6fba82\n      );\n      border-radius: calc(2 * var(--borderWidth));\n      z-index: -1;\n      animation: animatedgradient 3s ease alternate infinite;\n      background-size: 300% 300%;\n    }\n  }\n\n  //border-radius: var(--borderWidth);\n}\n\n@media only screen and (min-width: 768px) and (max-width: 1024px) {\n  #LoopringDeveloperBox {\n    width: 522px;\n    font-size: 56px;\n  }\n  .carousel-container {\n    --size-image: 0.7;\n    margin-top: 40px;\n  }\n  .cardBtnGroup {\n    margin-top: 32px;\n    flex-direction: column;\n    align-items: center;\n\n    button {\n      margin: 8px;\n      width: 100%;\n    }\n  }\n  .banner {\n    flex-direction: column;\n    align-items: center;\n\n    .right-part {\n      margin-left: 0px;\n      align-self: initial;\n    }\n  }\n\n\n  #labelTitleDes {\n    font-size: var(--h5);\n    text-align: center;\n  }\n  h3.Typography-root {\n    font-size: var(--h1);\n    margin: 80px 0 40px 0;\n  }\n\n  h3 ~ p.Typography-root {\n    color: var(--color-text-third);\n    font-size: var(--h5);\n  }\n  .banner {\n    flex-direction: column;\n    align-items: center;\n\n    .right-part {\n      margin-left: 0px;\n      align-self: initial;\n    }\n  }\n}\n\n@keyframes boxShow {\n  0% {\n    //background-position: 0% 50%;\n    box-shadow: 0 5px 15px rgba(247, 149, 51, 0.4), 0 10px 30px rgba(243, 112, 85, 0.2);\n  }\n  25% {\n    //background-position: 25% 50%;\n    box-shadow: 0 5px 15px rgba(239, 78, 123, 0.4), 0 10px 30px rgba(161, 102, 171, 0.2);\n  }\n  50% {\n    //background-position: 50% 50%;\n    box-shadow: 0 5px 15px rgba(80, 115, 184, 0.4), 0 10px 30px rgba(16, 152, 173, 0.2);\n  }\n  75% {\n    //background-position: 75% 50%;\n    box-shadow: 0 5px 15px rgba(7, 179, 155, 0.4), 0 10px 30px rgba(111, 186, 130, 0.2);\n  }\n}\n\n@keyframes animatedgradient {\n  0% {\n    background-position: 0% 50%;\n    //box-shadow: 0 5px 15px #f7953304, 0 10px 30px #f3705502\n  }\n  25% {\n    background-position: 25% 50%;\n    //box-shadow: 0 5px 15px #ef4e7b04, 0 10px 30px #a166ab02\n  }\n  50% {\n    background-position: 50% 50%;\n    //box-shadow: 0 5px 15px #5073b804, 0 10px 30px #1098ad02\n  }\n  75% {\n    background-position: 75% 50%;\n    //box-shadow: 0 5px 15px #07b39b04, 0 10px 30px #6fba8202\n  }\n}\n\n#changeColor {\n  margin-right: 24px;\n  border: 0;\n}\n\n//0%,\n// to {\n//   border: 2px solid #00f8ff;\n// }\n//\n//20% {\n//    border: 2px solid #a4ff00;\n//    box-shadow: 0 5px 15px rgba(164, 255, 0, .4), 0 10px 30px rgba(37, 41, 46, .2);\n//  }\n//\n//40% {\n//    border: 2px solid #f7275e;\n//    box-shadow: 0 5px 15px rgba(247, 39, 94, .4), 0 10px 30px rgba(37, 41, 46, .2);\n//  }\n//\n//60% {\n//    border: 2px solid #ffd300;\n//    box-shadow: 0 5px 15px rgba(255, 211, 0, .4), 0 10px 30px rgba(37, 41, 46, .2);\n//  }\n//\n//80% {\n//    border: 2px solid #ff8a00;\n//    box-shadow: 0 5px 15px rgba(255, 138, 0, .4), 0 10px 30px rgba(37, 41, 46, .2);\n//  }\n//\n//\n\n.carousel-container {\n  #item-1:checked ~ .cards #selector-1,\n  #item-2:checked ~ .cards #selector-2,\n  #item-3:checked ~ .cards #selector-3,\n    //#item-4:checked ~ .cards #selector-4,\n    //#item-5:checked ~ .cards #selector-5,\n    //#item-6:checked ~ .cards #selector-6,\n    //#item-7:checked ~ .cards #selector-7\n  {\n    //transform: translateX(-120%) scale(0.4);\n    transform: translateX(0%) scale(1);\n    z-index: 80;\n  }\n\n  #item-1:checked ~ .cards #selector-3,\n  #item-2:checked ~ .cards #selector-1,\n  #item-3:checked ~ .cards #selector-2 {\n    transform: translateX(100%) scale(var(--size-image));\n    z-index: 70;\n  }\n\n  #item-1:checked ~ .cards #selector-2,\n  #item-2:checked ~ .cards #selector-3,\n  #item-3:checked ~ .cards #selector-1 {\n    transform: translateX(-100%) scale(var(--size-image));\n    z-index: 70;\n  }\n\n  //#item-2:checked ~ .cards #selector-1,\n  //#item-3:checked ~ .cards #selector-2,\n  //#item-4:checked ~ .cards #selector-3,\n  ////#item-5:checked ~ .cards #selector-4,\n  ////#item-6:checked ~ .cards #selector-5,\n  ////#item-7:checked ~ .cards #selector-6,\n  ////#item-1:checked ~ .cards #selector-7\n  //{\n  //  transform: translateX(-80%) scale(0.6);\n  //  z-index: 20;\n  //}\n\n  //#item-3:checked ~ .cards #selector-1,\n  //#item-4:checked ~ .cards #selector-2,\n  //#item-5:checked ~ .cards #selector-3,\n  //#item-6:checked ~ .cards #selector-4,\n  //#item-7:checked ~ .cards #selector-5,\n  //#item-1:checked ~ .cards #selector-6,\n  //#item-2:checked ~ .cards #selector-7\n  //{\n  //  transform: translateX(-40%) scale(0.8);\n  //  z-index: 30;\n  //}\n  //\n  //#item-4:checked ~ .cards #selector-1,\n  //#item-5:checked ~ .cards #selector-2,\n  //#item-6:checked ~ .cards #selector-3,\n  //#item-7:checked ~ .cards #selector-4,\n  //#item-1:checked ~ .cards #selector-5,\n  //#item-2:checked ~ .cards #selector-6,\n  //#item-3:checked ~ .cards #selector-7{\n  //  transform: translateX(0) scale(1);\n  //  z-index: 40;\n  //}\n  //\n  //#item-5:checked ~ .cards #selector-1,\n  //#item-6:checked ~ .cards #selector-2,\n  //#item-7:checked ~ .cards #selector-3,\n  //#item-1:checked ~ .cards #selector-4,\n  //#item-2:checked ~ .cards #selector-5,\n  //#item-3:checked ~ .cards #selector-6,\n  //#item-4:checked ~ .cards #selector-7{\n  //  transform: translateX(40%) scale(0.8);\n  //  z-index: 30;\n  //}\n  //\n  //#item-6:checked ~ .cards #selector-1,\n  //#item-7:checked ~ .cards #selector-2,\n  //#item-1:checked ~ .cards #selector-3,\n  //#item-2:checked ~ .cards #selector-4,\n  //#item-3:checked ~ .cards #selector-5,\n  //#item-4:checked ~ .cards #selector-6,\n  //#item-5:checked ~ .cards #selector-7{\n  //  transform: translateX(80%) scale(0.6);\n  //  z-index: 20;\n  //}\n  //\n  //#item-7:checked ~ .cards #selector-1,\n  //#item-1:checked ~ .cards #selector-2,\n  //#item-2:checked ~ .cards #selector-3,\n  //#item-3:checked ~ .cards #selector-4,\n  //#item-4:checked ~ .cards #selector-5,\n  //#item-5:checked ~ .cards #selector-6,\n  //#item-6:checked ~ .cards #selector-7{\n  //  transform: translateX(120%) scale(0.4);\n  //  z-index: 10;\n  //}\n}\n"
  },
  {
    "path": "packages/web-developer/public/footer.jsx",
    "content": "import { FOOTER_LIST_MAP, MEDIA_LIST } from '@loopring-web/common-resources'\n\nconst linkListMap = FOOTER_LIST_MAP\nconst mediaList = MEDIA_LIST\nexport const Footer = () => {\n  return (\n    <div className='footerContent'>\n      <div className='wrap Container-maxWidthLg'>\n        <div className='Box-root content'>\n          <div className='Box-root' id='logSvg'></div>\n\n          {\n            // @ts-ignore\n            Reflect.ownKeys(linkListMap).map((key) => {\n              return (\n                <section className='Box-root group'>\n                  <h6\n                    aria-label={key}\n                    className='Typography-root Typography-body2'\n                    id={`label${key.charAt(0).toUpperCase() + key.slice(1)}`}\n                  ></h6>\n                  <ul className='Ul-root'>\n                    {linkListMap[key.toString()].map((item) => {\n                      return (\n                        <li>\n                          <a\n                            aria-label={item.linkName}\n                            className={`Typography-root Typography-inherit ${item.linkName} Link-underlineAlways`}\n                            href={item.linkHref}\n                            id={`label${item.charAt(0).toUpperCase() + item.slice(1)}`}\n                            rel='noopener noreferrer'\n                            target='_blank'\n                          >\n                            {item.linkName}\n                          </a>\n                        </li>\n                      )\n                    })}\n                  </ul>\n                </section>\n              )\n            })\n          }\n        </div>\n\n        <section className='Box-root group groupIcon'>\n          <h6\n            aria-label='Follow us'\n            className='Typography-root Typography-body2'\n            id='labelFollowus'\n          >\n            Follow us\n          </h6>\n          <div className='Box-root footerContentList'>\n            <ul\n              className='List-root List-padding'\n              style={{ display: 'flex', alignItems: 'flex-start', paddingTop: 0, paddingBottom: 0 }}\n            >\n              {mediaList.map((o, index) => (\n                <li className='List-root Typography-body1'>\n                  <a\n                    className='Typography-root Typography-inherit Link-root Link-underlineAlways icon'\n                    id={`${o.linkName}Icon`}\n                    href={o.linkHref}\n                    rel='noopener noreferrer'\n                    target='_blank'\n                  >\n                    {o.linkName}\n                  </a>\n                </li>\n              ))}\n            </ul>\n          </div>\n        </section>\n      </div>\n      <p\n        aria-label='@2017 Loopring Technology Limited. All rights reserved.'\n        className='Typography-root Typography-body1'\n        id='labelCopyRight'\n      ></p>\n    </div>\n  )\n}\n"
  },
  {
    "path": "packages/web-developer/public/index.html",
    "content": "<!DOCTYPE HTML>\n<html lang='en' xmlns='http://www.w3.org/1999/html'>\n<head>\n  <meta charset='utf-8'>\n  <link href='./favicon.ico' rel='icon'>\n  <link rel='mask-icon' href='./loopring.svg' color='#3B5AF4'>\n  <link rel='icon' type='image/png' sizes='16x16' href='./favicon-16x16.png'>\n  <link rel='icon' type='image/png' sizes='32x32' href='./favicon-32x32.png'>\n  <link rel='icon' type='image/png' sizes='48x48' href='./favicon-48x48.png'>\n  <link rel='apple-touch-icon' href='./apple-touch-icon.png' sizes='129x129'>\n  <meta content='text/html; charset=utf-8' http-equiv='Content-Type'>\n  <meta content='Ethereum zkRollup Exchange and Payment Protocol' name='description'>\n  <meta name='generator' content='GitBook 3.2.3'>\n  <meta content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0' name='viewport'>\n  <meta content='#000000' name='theme-color'>\n  <meta content='Loopring Layer 2, Ethereum zkRollup Exchange and Payment Protocol' name='description'>\n  <link href='https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&amp;display=swap' rel='stylesheet'>\n  <link href='./manifest.json' rel='manifest'>\n  <meta content='summary_large_image' name='twitter:card'>\n  <meta content='Loopring Wallet' name='twitter:title'>\n  <meta content='Your gateway to Ethereum, DeFi, and NFTs' name='twitter:description'>\n  <meta name='HandheldFriendly' content='true' />\n  <meta content='https://static.loopring.io/assets/images/giftReward.png' name='twitter:image'>\n  <link id='themeModeCss' rel='stylesheet' type='text/css' />\n  <link href='developer.css' rel='stylesheet' type='text/css' />\n  <script src='https://unpkg.com/i18next-browser-languagedetector/i18nextBrowserLanguageDetector.min.js'\n          type='application/javascript'></script>\n  <script src='https://unpkg.com/i18next@22.5.0/dist/umd/i18next.min.js' type='application/javascript' />\n  </script>\n  <script src='developer.js' type='application/javascript'></script>\n  <title>Developer · Loopring API</title>\n  <style></style>\n</head>\n<body ondragstart='return false;' ondrop='return false;' draggable='false' onmousedown='return false'>\n<div style='z-index: 2'>\n  <header>\n    <div class='headerGg'>\n      <div class='Toolbar-root wrap' style='padding: 0px 8px;'>\n        <nav>\n          <h1 class='Typography-root Typography-h6'>\n            <a rel='noopener' aria-label='menu' id='logo' class='ButtonBase-root' href='https://loopring.io/#/'\n               tabindex='0'>Loopring\n              路印\n              loopring protocol\n              3.6\n              The first Layer2 Decentralized trading Platform</a>\n          </h1>\n          <ul class='Ul-root'>\n            <li class='MenuItem-root MenuItem-gutters ButtonBase-root layer-1' role='menuitem' tabindex='-1'>\n              <a rel='noopener' target='_blank' class='Typography-root Typography-body1'\n                 href='https://wallet.loopring.io'\n                 id='labelNavWallet'>Wallet</a>\n            </li>\n          </ul>\n        </nav>\n        <div class='Box-root flexBox flex-row'>\n          <button\n            class='Button-root Button-contained Button-containedPrimary Button-sizeSmall Button-containedSizeSmall ButtonBase-root'\n            id='labelNavLanuch'\n            onclick=\"window.open('https://loopring.io/#/','_blank')\"\n            href='https://loopring.io/#/'\n            type='button'>Launch App\n          </button>\n        </div>\n      </div>\n\n    </div>\n    <div\n      class='Box-root '>\n      <section class='wrap flex-row flexBox stretch banner'>\n        <div class=' flex-column flexBox '>\n          <h2 class='Typography-root Typography-body1 title' id='LoopringDeveloperBox'>\n            <span aria-label='Loopring' id='labelLoopring'>Loopring</span>\n            <span aria-label='Developer' id='labelDeveloper1' style='text-indent: .5em'>Developer</span>\n          </h2>\n          <p aria-label='Our API, SDK, and step-by-step references to building, minting, and trading on Loopring'\n             class='Typography-root Typography-body1 subtitle' id='labelTitleDes'>\n            Our API, SDK, and step-by-step references to building, minting, and trading on Loopring\n          </p>\n        </div>\n        <span class='right-part'>\n\t\t\t\t\t<button class='labelDocumentation gradient-border'\n                  rel='noopener'\n                  target='_blank'\n                  href='https://docs-protocol.loopring.io/'\n                  alt='https://docs-protocol.loopring.io/'\n                  title='https://docs-protocol.loopring.io/'\n                  onclick=\"window.open('https://docs-protocol.loopring.io/','_blank')\"\n          >\n\t\t\t\t\t\t\t\t\t\t<span aria-label='Documentation' class='Typography-root Typography-body1' id='labelDocumentation'>\n\t\t\t\t\t\t\t\t\t\t\tDocumentation\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t<span id='iconGo'>\n\t\t\t\t\t\t\t<svg width='24' height='24' viewBox='0 0 24 24'>\n\t\t\t\t\t\t\t\t<path\n                  d='M16.0037 9.41421L7.39712 18.0208L5.98291 16.6066L14.5895 8H7.00373V6H18.0037V17H16.0037V9.41421Z' />\n\t\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t</span>\n\t\t\t\t</button>\n\n\t\t\t\t</span>\n      </section>\n      <section class='wrap Box-root flex-row flexBox buttons cardBtnGroup'>\n        <button class='Box-root flexBox flex-column'\n                alt='https://docs-protocol.loopring.io/'\n                title='https://docs-protocol.loopring.io/'\n                onclick=\"window.open('https://docs-protocol.loopring.io/','_blank')\"\n        >\n          <div class='wrap-svg'>\n            <svg width='24' height='24' viewBox='0 0 24 24' fill='none'>\n              <path\n                d='M20 2C21.6569 2 23 3.34315 23 5V7H21V19C21 20.6569 19.6569 22 18 22H4C2.34315 22 1 20.6569 1 19V17H17V19C17 19.5128 17.386 19.9355 17.8834 19.9933L18 20C18.5128 20 18.9355 19.614 18.9933 19.1166L19 19V4H6C5.48716 4 5.06449 4.38604 5.00673 4.88338L5 5V15H3V5C3 3.34315 4.34315 2 6 2H20Z' />\n            </svg>\n          </div>\n          <span class='title Typography-root Typography-h4'>\n\t\t\t\t\t\t\t\t\t\tLoopring Protocol\n\n\t\t\t\t\t</span>\n          <span class='des Typography-root Typography-subtitle'>\n\t\t\t\t\t \t\t\t\t\tLoopring is the first scalable DEX protocol built with zkRollup for Ethereum\n\n\t\t\t\t\t</span>\n\n\n        </button>\n        <button class='Box-root flexBox flex-column'\n                alt='https://docs-protocol.loopring.io/counterfactual-nft/api-references/nft-collection'\n                title='https://docs-protocol.loopring.io/counterfactual-nft/api-references/nft-collection'\n                onclick=\"window.open('https://docs-protocol.loopring.io/counterfactual-nft/api-references/nft-collection','_blank')\"\n        >\n          <div class='wrap-svg'>\n            <svg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'>\n              <path\n                d='M4.5 7.65311V16.3469L12 20.689L19.5 16.3469V7.65311L12 3.311L4.5 7.65311ZM12 1L21.5 6.5V17.5L12 23L2.5 17.5V6.5L12 1ZM6.49896 9.97065L11 12.5765V17.625H13V12.5765L17.501 9.97066L16.499 8.2398L12 10.8445L7.50104 8.2398L6.49896 9.97065Z' />\n            </svg>\n          </div>\n          <span class='title Typography-root Typography-h4'>\n\t\t\t\t\t\tNFT SDK Guides\n\t\t\t\t\t</span>\n          <span class='des Typography-root Typography-subtitle'>\n\t\t\t\t\t Create Collections, Mint NFTs, Transfer - all with zero gas fees\n\t\t\t\t\t</span>\n\n        </button>\n        <button class='Box-root flexBox flex-column'\n                alt='https://docs-protocol.loopring.io/erc20-tokens/sdk-guides'\n                title='https://docs-protocol.loopring.io/erc20-tokens/sdk-guides'\n                onclick=\"window.open('https://docs-protocol.loopring.io/erc20-tokens/sdk-guides','_blank')\"\n\n        >\n          <div class='wrap-svg'>\n            <svg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'>\n              <path\n                d='M9 12.5L6.5 15L9 17.5L11.5 15L9 12.5ZM15 2.5C11.5724 2.5 8.76444 5.15304 8.51763 8.51763C5.15304 8.76445 2.5 11.5724 2.5 15C2.5 18.5899 5.41015 21.5 9 21.5C12.4276 21.5 15.2356 18.847 15.4824 15.4824C18.847 15.2356 21.5 12.4276 21.5 9C21.5 5.41015 18.5899 2.5 15 2.5ZM15.3234 13.4886C14.7575 11.1126 12.8874 9.24245 10.5114 8.67665C10.6772 6.34229 12.6234 4.5 15 4.5C17.4853 4.5 19.5 6.51472 19.5 9C19.5 11.3766 17.6577 13.3228 15.3234 13.4886ZM13.5 15C13.5 17.4853 11.4853 19.5 9 19.5C6.51472 19.5 4.5 17.4853 4.5 15C4.5 12.5147 6.51472 10.5 9 10.5C11.4853 10.5 13.5 12.5147 13.5 15ZM3 7C3 4.79086 4.79086 3 7 3H8.5V5H7C5.89543 5 5 5.89543 5 7V8.5H3V7ZM19 17V15.5H21V17C21 19.2091 19.2091 21 17 21H15.5V19H17C18.1046 19 19 18.1046 19 17Z' />\n            </svg>\n          </div>\n          <span class='title Typography-root Typography-h4'>\n\t\t\t\t\t\t\t\t\t\tTrade or Swap\n\n\t\t\t\t\t</span>\n          <span class='des Typography-root Typography-subtitle'>\n\t\t\t\t\t \t\t\t\t\t\t\t\tTrade programatically using the API\n\n\t\t\t\t\t</span>\n\n\n        </button>\n      </section>\n    </div>\n  </header>\n  <section class='Box-root' style='flex: 1; margin-top: 112px'>\n    <div class='Box-root flex-column flexBox stretch'>\n      <h4 class='Box-root Typography-root Typography-h1' style='text-align: center'>User Guides</h4>\n      <div class='Box-root sectionFull'>\n        <section class='wrap flex-row flexBox'>\n          <div class='Box-root sectionDetail'>\n            <h3 class='Typography-root Typography-h2'>\n              <a rel='noopener' target='_blank' href='https://wallet.loopring.io'>\n\t\t\t\t\t\t\t\t<span aria-label='Loopring Wallet' id='labelLoopringWallet'>\n\t\t\t\t\t\t\t\t  Loopring Wallet\n\t\t\t\t\t\t\t  </span>\n                <span class='iconGo'>\n\t\t\t\t\t\t\t\t<svg width='24' height='24' viewBox='0 0 24 24'>\n\t\t\t\t\t\t\t\t\t<path\n                    d='M16.0037 9.41421L7.39712 18.0208L5.98291 16.6066L14.5895 8H7.00373V6H18.0037V17H16.0037V9.41421Z' />\n\t\t\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t\t</span>\n              </a>\n            </h3>\n            <p class='Typography-root Typography-h5 labelDocDes'\n\n               aria-label='Your gateway to Ethereum, DeFi, NFTs, and Financial Freedom.' id='labelLoopringWalletDes'>\n              Your gateway to Ethereum, DeFi, NFTs, and Financial Freedom.\n            </p>\n            <ul>\n              <li>\n                <button\n                  rel='noopener'\n                  target='_blank'\n                  alt='https://docs-wallet.loopring.io/security/guardians'\n                  title='https://docs-wallet.loopring.io/security/guardians'\n                  onclick=\"window.open('https://docs-wallet.loopring.io/security/guardians','_blank')\"\n                  href='https://docs-wallet.loopring.io/security/guardians'>\n\t\t\t\t\t\t\t\t <span aria-label='Set up Guardians for social recovery'\n                       id='labelGuardians'>\tSet up Guardians for social recovery</span>\n                  <span class='iconGo'>\n\t\t\t\t\t\t\t<svg width='24' height='24' viewBox='0 0 24 24'>\n\t\t\t\t\t\t\t\t<path\n                  d='M16.0037 9.41421L7.39712 18.0208L5.98291 16.6066L14.5895 8H7.00373V6H18.0037V17H16.0037V9.41421Z' />\n\t\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t\t</span>\n                </button>\n              </li>\n\n              <li>\n                <button\n                  rel='noopener'\n                  target='_blank'\n                  alt='https://docs-wallet.loopring.io/security/cloud-back-up'\n                  title='https://docs-wallet.loopring.io/security/cloud-back-up'\n                  onclick=\"window.open('https://docs-wallet.loopring.io/security/cloud-back-up','_blank')\"\n                  href='https://docs-wallet.loopring.io/security/cloud-back-up'>\n\t\t\t\t\t\t\t\t\t <span aria-label='Set up Guardians for social recovery'\n                         id='labelCloudbackup'>\tCloud backup</span>\n\n                  <span class='iconGo'>\n\t\t\t\t\t\t\t<svg width='24' height='24' viewBox='0 0 24 24'>\n\t\t\t\t\t\t\t\t<path\n                  d='M16.0037 9.41421L7.39712 18.0208L5.98291 16.6066L14.5895 8H7.00373V6H18.0037V17H16.0037V9.41421Z' />\n\t\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t\t</span>\n                </button>\n              </li>\n              <li>\n                <button rel='noopener'\n                        target='_blank'\n                        alt='https://docs-wallet.loopring.io/security/two-factor-authentication-2fa'\n                        title='https://docs-wallet.loopring.io/security/two-factor-authentication-2fa'\n                        onclick=\"window.open('https://docs-wallet.loopring.io/security/two-factor-authentication-2fa','_blank')\"\n                        href='https://docs-wallet.loopring.io/security/two-factor-authentication-2fa'>\n\t\t\t\t\t\t\t\t\t<span aria-label='Two-Factor Authentication (2FA)'\n                        id='label2FA'>Two-Factor Authentication (2FA)</span>\n                  <span class='iconGo'>\n\t\t\t\t\t\t\t<svg width='24' height='24' viewBox='0 0 24 24'>\n\t\t\t\t\t\t\t\t<path\n                  d='M16.0037 9.41421L7.39712 18.0208L5.98291 16.6066L14.5895 8H7.00373V6H18.0037V17H16.0037V9.41421Z' />\n\t\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t\t</span>\n                </button>\n              </li>\n            </ul>\n            <a rel='noopener' target='_blank' class='learnMore' href='https://docs-wallet.loopring.io/'>\n              <span id='labelLearnMore'>Learn More</span>\n              <span class='iconGo'>\n\t\t\t\t\t\t\t<svg width='24' height='24' viewBox='0 0 24 24'>\n\t\t\t\t\t\t\t\t<path\n                  d='M16.0037 9.41421L7.39712 18.0208L5.98291 16.6066L14.5895 8H7.00373V6H18.0037V17H16.0037V9.41421Z' />\n\t\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t\t</span>\n            </a>\n          </div>\n          <div class='Box-root img-container img-container-odd'>\n            <img alt=\"Scroll-up Image' class='scroll-up-img\" title=\"Scroll-up Image' class='scroll-up-img\"\n                 src='https://static.loopring.io/assets/images/landPage/doc1.webp' id='imageSection1'\n                 style='width: 80%;' />\n            <!--\t\t\t\t\t\t\t\t style=\"opacity: 0; transform: translateY(100%); transition: opacity 1s ease 0s, transform 1s ease 0s; width: 80%;\"-->\n\n          </div>\n        </section>\n        <section class='wrap flex-row flexBox'>\n          <div class='Box-root sectionDetail'>\n            <h3 class='Typography-root Typography-h2'>\n              <a rel='noopener' target='_blank' href='https://loopring.io/#/l2assets'>\n\t\t\t\t\t\t\t <span aria-label='Dapp' id='labelDapp'>\n\t\t\t\t\t\t\t\t\t Dapp\n\t\t\t\t\t\t\t </span>\n                <span class='iconGo'>\n\t\t\t\t\t\t\t\t\t<svg width='24' height='24' viewBox='0 0 24 24'>\n\t\t\t\t\t\t\t\t\t\t<path\n                      d='M16.0037 9.41421L7.39712 18.0208L5.98291 16.6066L14.5895 8H7.00373V6H18.0037V17H16.0037V9.41421Z' />\n\t\t\t\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t\t  </span>\n              </a>\n            </h3>\n\n            <p class='Typography-root Typography-h5 labelDocDes' id='labelDappDes'\n               aria-label='Explore the Loopring DEX, Earn, and NFT Management. Powered by zkRollups, experience instant transactions with 100x lower fees than Ethereum without sacrificing any of its security.'>\n              Explore the Loopring DEX, Earn, and NFT Management. Powered by zkRollups, experience instant transactions\n              with 100x lower fees than Ethereum without sacrificing any of its security.\n            </p>\n            <ul>\n              <li>\n\n                <button\n                  rel='noopener'\n                  target='_blank'\n                  alt='https://docs-dapp.loopring.io/connect-to-loopring-l2'\n                  title='https://docs-dapp.loopring.io/connect-to-loopring-l2'\n                  onclick=\"window.open('https://docs-dapp.loopring.io/connect-to-loopring-l2','_blank')\"\n                  href='https://docs-dapp.loopring.io/connect-to-loopring-l2'>\n\t\t\t\t\t\t\t\t\t<span aria-label='How to connect a wallet and activate your Loopring account'\n                        id='labelActivate'>How to connect a wallet and activate your Loopring account</span>\n                  <span class='iconGo'>\n\n\t\t\t\t\t\t\t<svg width='24' height='24' viewBox='0 0 24 24'>\n\t\t\t\t\t\t\t\t<path\n                  d='M16.0037 9.41421L7.39712 18.0208L5.98291 16.6066L14.5895 8H7.00373V6H18.0037V17H16.0037V9.41421Z' />\n\t\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t\t</span>\n                </button>\n              </li>\n              <li>\n                <button\n                  rel='noopener'\n                  target='_blank'\n                  alt='https://docs-dapp.loopring.io/mint-nft-in-1-2-3'\n                  title='https://docs-dapp.loopring.io/mint-nft-in-1-2-3'\n                  onclick=\"window.open('https://docs-dapp.loopring.io/mint-nft-in-1-2-3','_blank')\"\n                  href='https://docs-dapp.loopring.io/mint-nft-in-1-2-3'>\n\t\t\t\t\t\t\t\t\t<span aria-label='How to mint an NFT'\n                        id='labelMintNFT'>How to mint an NFT</span>\n                  <span class='iconGo'>\n\t\t\t\t\t\t\t<svg width='24' height='24' viewBox='0 0 24 24'>\n\t\t\t\t\t\t\t\t<path\n                  d='M16.0037 9.41421L7.39712 18.0208L5.98291 16.6066L14.5895 8H7.00373V6H18.0037V17H16.0037V9.41421Z' />\n\t\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t\t</span>\n                </button>\n              </li>\n              <li>\n\n                <button rel='noopener'\n                        target='_blank'\n                        alt='https://docs-dapp.loopring.io/earn/overview'\n                        title='https://docs-dapp.loopring.io/earn/overview'\n                        onclick=\"window.open('https://docs-dapp.loopring.io/earn/overview','_blank')\"\n                        href='https://docs-dapp.loopring.io/earn/overview'>\n\t\t\t\t\t\t\t\t\t<span aria-label=\"How to participate in 'Loopring Earn' \"\n                        id='labelLoopringEarn'>How to participate in \"Loopring Earn\"</span>\n\n                  <span class='iconGo'>\n\t\t\t\t\t\t\t<svg width='24' height='24' viewBox='0 0 24 24'>\n\t\t\t\t\t\t\t\t<path\n                  d='M16.0037 9.41421L7.39712 18.0208L5.98291 16.6066L14.5895 8H7.00373V6H18.0037V17H16.0037V9.41421Z' />\n\t\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t\t</span>\n                </button>\n              </li>\n            </ul>\n            <a rel='noopener' target='_blank' class='learnMore' href='https://docs-dapp.loopring.io/'>\n              <span id='labelLearnMore2'>Learn More</span>\n              <span class='iconGo'>\n\t\t\t\t\t\t\t<svg width='24' height='24' viewBox='0 0 24 24'>\n\t\t\t\t\t\t\t\t<path\n                  d='M16.0037 9.41421L7.39712 18.0208L5.98291 16.6066L14.5895 8H7.00373V6H18.0037V17H16.0037V9.41421Z' />\n\t\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t\t</span>\n            </a>\n          </div>\n          <div class='Box-root img-container img-container-odd'>\n            <img alt=\"Scroll-up Image' class='scroll-up-img\" title=\"Scroll-up Image' class='scroll-up-img\"\n                 src='https://static.loopring.io/assets/images/landPage/doc2.webp' id='imageSection2'\n                 style='width: 80%;'\n            />\n            <!--\t\t\t\t\t\t\t\t style=\"opacity: 0; transform: translateY(100%); transition: opacity 1s ease 0s, transform 1s ease 0s; width: 80%;\">-->\n          </div>\n        </section>\n      </div>\n    </div>\n  </section>\n  <footer class='Box-root'>\n    <div class='footerContent'>\n      <div class=' Container-maxWidthLg wrap flex-column flexBox'>\n        <div class='Box-root content' style='display: none'>\n          <div class='Box-root' id='logSvg'></div>\n          <section class='Box-root group'>\n            <h6 aria-label='About' class='Typography-root Typography-body2' id='labelAbout'></h6>\n            <ul class='Ul-root'>\n              <li>\n                <a aria-label='blog Loopring.org'\n                   rel='noopener' target='_blank'\n                   class='Typography-root Typography-inherit Link-root Link-underlineAlways' href='https://loopring.org'\n                   id='labelLoopringOrg' rel='noopener noreferrer' target='_blank' />blog Loopring.org</a>\n              </li>\n              <li>\n                <a rel='noopener' target='_blank' aria-label='Loopring Terms'\n                   class='Typography-root Typography-inherit Link-root Link-underlineAlways'\n                   href='https://www.iubenda.com/terms-and-conditions/74969935' id='labelLoopringTerms'\n                   rel='noopener noreferrer' target='_blank'>Loopring Terms</a>\n              </li>\n              <li>\n                <a rel='noopener' target='_blank' aria-label='Privacy Policy'\n                   class='Typography-root Typography-inherit Link-root Link-underlineAlways'\n                   href='https://loopring.io/#/document/privacy_en.md' id='labelPrivacyPolicy' rel='noopener noreferrer'\n                   target='_blank'>Privacy Policy</a>\n              </li>\n              <li>\n                <a rel='noopener' target='_blank' aria-label='Risk Disclosure'\n                   class='Typography-root Typography-inherit Link-root Link-underlineAlways'\n                   href='https://loopring.io/#/document/risks_en.md' id='labelRiskDisclosure' rel='noopener noreferrer'\n                   target='_blank'>Risk Disclosure</a>\n              </li>\n            </ul>\n          </section>\n          <section class='Box-root group'>\n            <h6 aria-label='Platform' class='Typography-root Typography-body2' id='labelPlatform'></h6>\n            <ul class='Ul-root'>\n              <li>\n                <a aria-label='Fees' class='Typography-root Typography-inherit Link-root Link-underlineAlways'\n                   href='https://loopring.io/#/document/dex_fees_en.md' id='labelFees' rel='noopener noreferrer'\n                   target='_blank'>Box-root group</a>\n              </li>\n              <li>\n                <a aria-label='VIP Program' class='Typography-root Typography-inherit Link-root Link-underlineAlways'\n                   href='https://medium.loopring.io/introducing-loopring-vip-tiers-c6f73d753bac' id='labelVIPProgram'\n                   rel='noopener noreferrer' target='_blank'>VIP Program</a>\n              </li>\n              <li>\n                <a aria-label='Referrals' class='Typography-root Typography-inherit Link-root Link-underlineAlways'\n                   href='https://medium.loopring.io/loopring-exchange-launches-referral-program-c61777f072d1'\n                   id='labelReferrals' rel='noopener noreferrer' target='_blank'>Referrals</a>\n              </li>\n            </ul>\n          </section>\n          <section class='Box-root group'>\n            <h6 aria-label='Support' class='Typography-root Typography-body2' id='labelSupport'>Support</h6>\n            <ul class='Ul-root'>\n              <li>\n                <a aria-label='Submit A Request'\n                   class='Typography-root Typography-inherit Link-root Link-underlineAlways'\n                   href='https://desk.zoho.com/portal/loopring/en/home' id='labelSubmitARequest'\n                   rel='noopener noreferrer'\n                   target='_blank'>Submit A Request</a>\n              </li>\n              <li>\n                <a aria-label='Creator Grants' class='Typography-root Typography-inherit Link-root Link-underlineAlways'\n                   href='https://www.loopringgrants.org/' id='labelCreatorGrants' rel='noopener noreferrer'\n                   target='_blank'>Creator Grants</a>\n              </li>\n              <li>\n                <a aria-label='List a Token' class='Typography-root Typography-inherit Link-root Link-underlineAlways'\n                   href='https://loopringexchange.typeform.com/to/T0bgsodw?typeform-source=medium.com'\n                   id='labelListAToken' rel='noopener noreferrer' target='_blank'>List a Token</a>\n              </li>\n              <li>\n                <a aria-label='Wallet Guardian'\n                   class='Typography-root Typography-inherit Link-root Link-underlineAlways'\n                   href='https://guardian.loopring.io' id='labelWalletGuardian' rel='noopener noreferrer'\n                   target='_blank'></a>\n              </li>\n            </ul>\n          </section>\n          <section class='Box-root group'>\n            <h6 aria-label='Developers' class='Typography-root Typography-body2' id='labelDevelopers'></h6>\n            <ul class='Ul-root'>\n              <li>\n                <a aria-label='Smart Contracts'\n                   class='Typography-root Typography-inherit Link-root Link-underlineAlways'\n                   href='https://loopring.io/#/document/contracts_en.md' id='labelSmartContracts'\n                   rel='noopener noreferrer' target='_blank'>Smart Contracts</a>\n              </li>\n              <li>\n                <a aria-label='APIs' class='Typography-root Typography-inherit Link-root Link-underlineAlways'\n                   href='https://docs.loopring.io' id='labelAPIs' rel='noopener noreferrer' target='_blank'>APIs</a>\n              </li>\n              <li>\n                <a aria-label='Layer 2 Explorer'\n                   class='Typography-root Typography-inherit Link-root Link-underlineAlways'\n                   href='https://explorer.loopring.io' id='labelLayer2Explorer' rel='noopener noreferrer'\n                   target='_blank'>Layer 2 Explorer</a>\n              </li>\n              <li>\n                <a aria-label='Bug Bounty' class='Typography-root Typography-inherit Link-root Link-underlineAlways'\n                   href='https://loopring.io/#/document/bug_bounty_en.md' id='labelBugBounty' rel='noopener noreferrer'\n                   target='_blank'>Bug Bounty</a>\n              </li>\n              <li>\n                <a aria-label='Subgraph' class='Typography-root Typography-inherit Link-root Link-underlineAlways'\n                   href='https://thegraph.com/explorer/subgraph?id=HgnaENC2oG5hJFsWoHvULBbj7djTJ7TZnqa58iTWA3Rd'\n                   id='labelSubgraph' rel='noopener noreferrer' target='_blank'>Subgraph</a>\n              </li>\n            </ul>\n          </section>\n        </div>\n        <!--\t\t\t\t</div>-->\n        <!--\t\t\t</div>-->\n        <div class='Box-root content flex-column flexBox  stretch'>\n          <section class='Box-root group groupIcon followUs'>\n            <h6 aria-label='Follow us' class='Typography-root Typography-h1' id='labelFollowus'\n                style='text-align: center'>Follow us</h6>\n            <div class='Box-root flex-row flexBox footerContentList'>\n              <ul class='List-root List-padding'>\n                <li class='List-root Typography-body1'>\n                  <a class='Typography-root Typography-inherit Link-root Link-underlineAlways icon' id='discordIcon'\n                     href='https://discord.com/invite/KkYccYp' rel='noopener noreferrer' target='_blank'></a>\n                </li>\n                <li class='List-root Typography-body1'>\n                  <a class='Typography-root Typography-inherit Link-root Link-underlineAlways icon' id='twitterIcon'\n                     href='https://twitter.com/loopringorg' rel='noopener noreferrer' target='_blank'></a>\n                </li>\n                <li class='List-root Typography-body1'>\n                  <a class='Typography-root Typography-inherit Link-root Link-underlineAlways icon'\n                     href='https://www.youtube.com/c/Loopring' rel='noopener noreferrer' target='_blank'\n                     id='youtubeIcon'></a>\n                </li>\n                <li class='List-root Typography-body1'>\n                  <a class='Typography-root Typography-inherit Link-root Link-underlineAlways icon' id='mediumIcon'\n                     href='https://medium.com/loopring-protocol' rel='noopener noreferrer' target='_blank'></a>\n                </li>\n              </ul>\n            </div>\n          </section>\n          <p aria-label='@2017 Loopring Technology Limited. All rights reserved.'\n             class='Typography-root Typography-body1'\n             id='labelCopyRight'>\n            @2017 Loopring Technology Limited. All rights reserved.\n          </p>\n        </div>\n      </div>\n    </div>\n  </footer>\n</div>\n<div id='bgContent'>\n</div>\n</body>\n</html>\n"
  },
  {
    "path": "packages/web-developer/public/light.css",
    "content": "@import 'reset.css';\n\nhtml {\n    --color-global-Bg: var(--light900);\n    --color-primary: #446eff;\n    --color-primary-hover: var(--light900) 20;\n    --color-primary-pressed: #2d49b2;\n    --color-disable: #343754;\n    --color-text-primary: var(--dark);\n    --color-border: var(--dark900);\n    --color-divide: var(--light500);\n    --color-border-hover: var(--color-primary);\n    --color-text-Secondary: var(--dark500);\n    --color-text-third: var(--light400);\n    --color-text-Button: var(--dark);\n    --color-text-ButtonSelect: var(--dark);\n    --color-text-Disable: var(--dark) 25;\n    --color-box: var(--light);\n    --color-logo: #446eff;\n}\n"
  },
  {
    "path": "packages/web-developer/public/manifest.json",
    "content": "{\n  \"short_name\": \"Loopring L2\",\n  \"name\": \"Loopring - Ethereum Layer2\",\n  \"icons\": [\n    {\n      \"src\": \"favicon.ico\",\n      \"sizes\": \"64x64 32x32 24x24 16x16\",\n      \"type\": \"image/x-icon\"\n    }\n  ],\n  \"start_url\": \".\",\n  \"display\": \"standalone\",\n  \"theme_color\": \"#000000\",\n  \"background_color\": \"#ffffff\"\n}\n"
  },
  {
    "path": "packages/web-developer/public/reset.css",
    "content": "html,\nbody,\ndiv,\nspan,\napplet,\nobject,\niframe,\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\np,\nblockquote,\npre,\na,\nabbr,\nacronym,\naddress,\nbig,\ncite,\ncode,\ndel,\ndfn,\nem,\nimg,\nins,\nkbd,\nq,\ns,\nsamp,\nsmall,\nstrike,\nstrong,\nsub,\nsup,\ntt,\nvar,\nb,\nu,\ni,\ncenter,\ndl,\ndt,\ndd,\nol,\nul,\nli,\nfieldset,\nform,\nlabel,\nlegend,\ntable,\ncaption,\ntbody,\ntfoot,\nthead,\ntr,\nth,\ntd,\narticle,\naside,\ncanvas,\ndetails,\nembed,\nfigure,\nfigcaption,\nfooter,\nheader,\nhgroup,\nmenu,\nnav,\noutput,\nruby,\nsection,\nsummary,\ntime,\nmark,\naudio,\nvideo {\n    margin: 0;\n    padding: 0;\n    border: 0;\n    font-size: 100%;\n    font: inherit;\n    vertical-align: baseline;\n    box-sizing: border-box;\n}\n\naddress,\ncaption,\ncite,\ncode,\ndfn,\nem,\nstrong,\nth,\nvar,\nb {\n    font-weight: normal;\n    font-style: normal;\n}\n\nabbr,\nacronym {\n    border: 0;\n}\n\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmenu,\nnav,\nsection {\n    display: block;\n}\n\n*,\n*::after,\n*::before {\n    margin: 0;\n    padding: 0;\n    box-sizing: inherit;\n}\n\n*:focus-visible {\n    outline: rgba(0, 0, 0, 0);\n}\n\nhtml {\n    text-size-adjust: 100%;\n    box-sizing: border-box;\n    scroll-behavior: smooth;\n}\n\nbody {\n    line-height: 1;\n}\n\nol,\nul {\n    list-style: none;\n}\n\nblockquote,\nq {\n    quotes: none;\n}\n\ntable {\n    border-collapse: collapse;\n    border-spacing: 0;\n}\n\ncaption,\nth {\n    text-align: left;\n}\n\ntextarea {\n    resize: none;\n}\n\na {\n    text-decoration: none;\n    cursor: pointer;\n}\n\nbutton {\n    padding: 0;\n    border: none;\n    background: none;\n}\n\nhtml {\n    overscroll-behavior-x: none;\n    overscroll-behavior-y: none;\n    text-underline-offset: 3px;\n}\n\niframe {\n    display: none;\n}\n\nhtml {\n    --dark: #000000;\n    --dark900: #141414;\n    --dark800: #1f1f1f;\n    --dark700: #262626;\n    --dark600: #434343;\n    --dark500: #595959;\n    --dark400: #8c8c8c;\n    --light400: #bfbfbf;\n    --light500: #d9d9d9;\n    --light600: #ebebeb;\n    --light700: #f0f0f0;\n    --light800: #f5f5f5;\n    --light900: #fafafa;\n    --light: #ffffff;\n    --color-success: #00bba8;\n    --color-warning: #fba95c;\n    --color-error: #ff5677;\n    /**** config pex ****/\n    --h1: 48px;\n    --h4: 24px;\n    --h5: 20px;\n    --body: 14px;\n    --body2: 12px;\n    --header-row-height: 44px;\n    --header-height: 64px;\n\n    --header-submenu-item-height: 52px;\n    --header-submenu-item-width: 250px;\n}\n"
  },
  {
    "path": "packages/web-developer/public/robots.txt",
    "content": "# https://www.robotstxt.org/robotstxt.html\nUser-agent: *\nDisallow:\n"
  },
  {
    "path": "packages/web-developer/public/vercel.json",
    "content": "{\n  \"redirects\": [\n    { \"source\": \"/en\", \"destination\": \"https://docs.loopring.io\", \"permanent\": false }\n  ]\n}"
  },
  {
    "path": "packages/web-earn/.babelrc",
    "content": "{\n  \"presets\": [\n    [\n      \"@babel/react\",\n      {\n        \"runtime\": \"automatic\",\n        \"loose\": true\n      }\n    ],\n    [\n      \"@babel/preset-react\",\n      {\n        \"runtime\": \"automatic\"\n      }\n    ]\n  ]\n}\n"
  },
  {
    "path": "packages/web-earn/.eslintrc.json",
    "content": "{\n  \"plugins\": [\n    \"react-hooks\"\n  ],\n  \"extends\": [\n    \"react-app\"\n  ],\n  \"overrides\": [\n    {\n      \"files\": [\n        \"**/*.tsx\",\n        \"**/*.ts\"\n      ],\n      \"rules\": {\n        \"import/no-anonymous-default-export\": \"off\",\n        \"@typescript-eslint/no-unused-vars\": \"warn\",\n        \"react-hooks/rules-of-hooks\": \"warn\",\n        // 检查 Hook 的规则\n        \"react-hooks/exhaustive-deps\": \"warn\"\n        // 检查 effect 的依赖\n      }\n    }\n  ]\n}\n"
  },
  {
    "path": "packages/web-earn/.gitignore",
    "content": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n# Runtime data\npids\n*.pid\n*.seed\n*.pid.lock\n\n# Directory for instrumented libs generated by jscoverage/JSCover\nlib-cov\n\n# Coverage directory used by tools like istanbul\ncoverage\n\n# nyc test coverage\n.nyc_output\n\n# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)\n.grunt\n\n# Bower dependency directory (https://bower.io/)\nbower_components\n\n# node-waf configuration\n.lock-wscript\n\n# Compiled binary addons (https://nodejs.org/api/addons.html)\nbuild/Release\n\n# Dependency directories\nnode_modules/\njspm_packages/\n\n# TypeScript v1 declaration files\ntypings/\n\n# Optional npm cache directory\n.npm\n\n# Optional eslint cache\n.eslintcache\n\n# Optional REPL history\n.node_repl_history\n\n# Output of 'npm pack'\n*.tgz\n\n# Yarn Integrity file\n.yarn-integrity\n\n# dotenv environment variables file\n.env\n\n# parcel-bundler cache (https://parceljs.org/)\n.cache\n\n# next.js build output\n.next\n\n# nuxt.js build output\n.nuxt\n\n# vuepress build output\n.vuepress/dist\n\n# Serverless directories\n.serverless/\n\n# FuseBox cache\n.fusebox/\n\n# DynamoDB Local files\n.dynamodb/\n# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\n/node_modules\n/.pnp\n.pnp.js\n\n# testing\n/coverage\n\n# production\n**/build\n/out\n/dist\n\n# misc\n.DS_Store\n.env.local\n.env.development.local\n.env.development\n# .env.prod_for_dev\n\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n*.code-workspace\n.vscode\nopenapitools.json\n*.tgz\n.idea/\ntestkey.txt\n\ntest_datadir\n\nipfs_deploy.txt\n.env.deploy*\n.testfile*\n.DS_Store\n"
  },
  {
    "path": "packages/web-earn/ADD_NEW_CHAIN.md",
    "content": "# Way to add a new Chain\n\n### step1:\n\n.env.production\n\n```.env\n## part1 for connection\n# support chainId list eg:REACT_APP_RPC_OTHERS=167005,12345\nREACT_APP_RPC_OTHERS=167005\n# RPC URL for support chain eg:REACT_APP_RPC_URL_167005=https://rpc.test.taiko.xyz/\nREACT_APP_RPC_URL_167005=https://rpc.test.taiko.xyz/\n# Chian Name for show(if test use `|` split) eg:REACT_APP_RPC_CHAINNAME_167005=Taiko|test\nREACT_APP_RPC_CHAINNAME_167005=Taiko|test\n\n## part2 for Dex & API\n# DEX API URL for chain eg: REACT_APP_API_URL_167005=taikodev.loopring.io\nREACT_APP_API_URL_167005=taikodev.loopring.io\n```\n\n### step2: UI/View config\n\npackages/common-resources/static-resources/src/constant/router.ts\n\n#### navigation\n\n```ts\nexport const headerMenuDataMap: { [ key: string ]: HeaderMenuItemInterface[] } = {\n  TAIKO: [\n    {\n      label: {\n        id: 'L2Assets',\n        i18nKey: 'labelAssets',\n      },\n      router: { path: '/l2assets' },\n      status: HeaderMenuTabStatus.default,\n    },\n    {\n      label: {\n        id: 'Markets',\n        i18nKey: 'labelMarkets',\n      },\n      router: { path: '/markets' },\n      status: HeaderMenuTabStatus.default,\n    },\n    {\n      label: {\n        id: 'Trade',\n        i18nKey: 'labelTrade',\n      },\n      status: HeaderMenuTabStatus.default,\n      child: [\n        {\n          label: {\n            id: 'lite',\n            i18nKey: 'labelClassic',\n            description: 'labelClassicDescription',\n          },\n          router: { path: RouterPath.lite + '/${pair}' },\n        },\n        {\n          label: {\n            id: 'pro',\n            i18nKey: 'labelAdvanced',\n            description: 'labelAdvancedDescription',\n          },\n          router: { path: RouterPath.pro + '/${pair}' },\n        },\n      ],\n    },\n  ],\n}\n```\n\n#### avaiable land page\n\n```ts\nexport const RouterAllowIndex = {\n  TAIKO: [\n    RouterMainKey.lite,\n    RouterMainKey.pro,\n    RouterMainKey.markets,\n    RouterMainKey.l2assets,\n    RouterMainKey.layer2,\n  ],\n  ETHEREUM: [\n    RouterMainKey.lite,\n    RouterMainKey.pro,\n    RouterMainKey.stoplimit,\n    RouterMainKey.btrade,\n    RouterMainKey.fiat,\n    RouterMainKey.markets,\n    RouterMainKey.mining,\n    RouterMainKey.redPacket,\n    RouterMainKey.l2assets,\n    RouterMainKey.layer2,\n    RouterMainKey.nft,\n    RouterMainKey.invest,\n  ],\n  GOERLI: [\n    RouterMainKey.lite,\n    RouterMainKey.pro,\n    RouterMainKey.stoplimit,\n    RouterMainKey.btrade,\n    RouterMainKey.fiat,\n    RouterMainKey.markets,\n    RouterMainKey.mining,\n    RouterMainKey.redPacket,\n    RouterMainKey.l2assets,\n    RouterMainKey.layer2,\n    RouterMainKey.nft,\n    RouterMainKey.invest,\n  ],\n}\n```\n\n#### support send/receive assets way\n\n```ts\nexport const AddAssetListMap = {\n  TAIKO: [\n    AddAssetList.FromMyL1.key,\n    AddAssetList.FromOtherL2.key,\n    // AddAssetList.FromExchange.key,\n  ],\n  ETHEREUM: [\n    AddAssetList.FromMyL1.key,\n    AddAssetList.BuyWithCard.key,\n    AddAssetList.FromOtherL2.key,\n    AddAssetList.FromOtherL1.key,\n    AddAssetList.FromExchange.key,\n    AddAssetList.FromAnotherNet.key,\n  ],\n  GOERLI: [\n    AddAssetList.FromMyL1.key,\n    AddAssetList.BuyWithCard.key,\n    AddAssetList.FromOtherL2.key,\n    AddAssetList.FromOtherL1.key,\n    AddAssetList.FromExchange.key,\n    AddAssetList.FromAnotherNet.key,\n  ],\n}\nexport const SendAssetListMap = {\n  TAIKO: [\n    SendAssetList.SendAssetToMyL1.key,\n    SendAssetList.SendAssetToL2.key,\n    SendAssetList.SendAssetToOtherL1.key,\n  ],\n  ETHEREUM: [\n    SendAssetList.SendAssetToMyL1.key,\n    SendAssetList.SendAssetToL2.key,\n    SendAssetList.SendAssetToOtherL1.key,\n    SendAssetList.SendAssetToAnotherNet.key,\n  ],\n  GOERLI: [\n    SendAssetList.SendAssetToMyL1.key,\n    SendAssetList.SendAssetToL2.key,\n    SendAssetList.SendAssetToOtherL1.key,\n    SendAssetList.SendAssetToAnotherNet.key,\n  ],\n}\n```\n\n#### support AssetL2 assets tab\n\n```ts\nexport const AssetL2TabIndex = {\n  TAIKO: [AssetTabIndex.Tokens],\n  ETHEREUM: [AssetTabIndex.Tokens, AssetTabIndex.Invests, AssetTabIndex.RedPacket],\n  GOERLI: [AssetTabIndex.Tokens, AssetTabIndex.Invests, AssetTabIndex.RedPacket],\n}\n```\n\n#### support user Profile\n\n```ts\nexport const ProfileIndex = {\n  TAIKO: [Layer2RouterID.security, Layer2RouterID.referralrewards],\n  ETHEREUM: [Layer2RouterID.security, Layer2RouterID.vip, Layer2RouterID.contact, Layer2RouterID.referralrewards],\n  GOERLI: [Layer2RouterID.security, Layer2RouterID.vip, Layer2RouterID.contact, Layer2RouterID.referralrewards],\n}\n```\n\n#### 118n key name\n\n```ts\nexport const L1L2_NAME_DEFINED = {\n  TAIKO: {\n    layer2: 'Layer 3',\n    l1ChainName: 'TAIKO',\n    loopringL2: 'Loopring L3',\n    l2Symbol: 'L3',\n    l1Symbol: 'TAIKO',\n    ethereumL1: 'TAIKO',\n    loopringLayer2: 'Loopring Layer 3',\n  },\n  ETHEREUM: {\n    layer2: 'Layer 2',\n    l1ChainName: 'Ethereum',\n    loopringL2: 'Loopring L2',\n    l2Symbol: 'L2',\n    l1Symbol: 'L1',\n    ethereumL1: 'Ethereum L1',\n    loopringLayer2: 'Loopring Layer 2',\n  },\n  GOERLI: {\n    layer2: 'Layer 2',\n    l1ChainName: 'Ethereum',\n    loopringL2: 'Loopring L2',\n    l2Symbol: 'L2',\n    l1Symbol: 'L1',\n    ethereumL1: 'Ethereum L1',\n    loopringLayer2: 'Loopring Layer 2',\n  },\n}\n```\n\n### U base token address\n\n```ts\nexport const TokenPriceBase = {\n  TAIKO: '0x0000000000000000000000000000000000000000',\n  ETHEREUM: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',\n  GOERLI: '0xd4e71c4bb48850f5971ce40aa428b09f242d3e8a',\n}\n```\n\n### Record history\n\n```ts\nexport const RecordMap: { [ key: string ]: RecordTabIndex[] } = {\n  TAIKO: [RecordTabIndex.Transactions, RecordTabIndex.Trades, RecordTabIndex.Orders],\n  ETHEREUM: [\n    RecordTabIndex.Transactions,\n    RecordTabIndex.Trades,\n    RecordTabIndex.Orders,\n    RecordTabIndex.StopLimitRecords,\n    RecordTabIndex.AmmRecords,\n    RecordTabIndex.DefiRecords,\n    RecordTabIndex.DualRecords,\n    RecordTabIndex.SideStakingRecords,\n    RecordTabIndex.BtradeSwapRecords,\n  ],\n  GOERLI: [\n    RecordTabIndex.Transactions,\n    RecordTabIndex.Trades,\n    RecordTabIndex.Orders,\n    RecordTabIndex.StopLimitRecords,\n    RecordTabIndex.AmmRecords,\n    RecordTabIndex.DefiRecords,\n    RecordTabIndex.DualRecords,\n    RecordTabIndex.SideStakingRecords,\n    RecordTabIndex.BtradeSwapRecords,\n  ],\n}\n\n```\n"
  },
  {
    "path": "packages/web-earn/README.md",
    "content": "<p align=\"center\">\n  <a href=\"https://github.com/Loopring/loopring-web-v2\" rel=\"noopener\" target=\"_blank\"><img width=\"150\" src=\"https://loopring.org/images/logo.svg\" alt=\"Loopring-website\"></a>\n</p>\n\n<h1 align=\"center\">Loopring Application</h1>\n<div align=\"center\">\n<h2>Ethereum’s First zkRollup Layer2</h2>\n<p>Fast, Secure, and 100x Lower Fees</p>\n\n[![license](https://img.shields.io/badge/license-MIT-blue)](https://github.com/Loopring/loopring-web-v2/master/LICENSE)\n\n[![type-badge](https://img.shields.io/npm/types/react-data-grid)](https://www.npmjs.com/package/react-data-grid)\n\n<!-- [![Materi-UI](https://img.shields.io/npm/types/react-data-grid)](https://www.npmjs.com/package/react-data-grid) -->\n\n</div>\n\n## 🚀 Quick Start\n\n```bash\n// with yarn\nyarn install\nyarn up\ncd ./packages/web-earn\nnpm run dev\n\n\n```\n\n## 📚 Loopring UI component StoryBook\n\n```bash\n\ncd ./packages/component-lib\nnpm run storybook\n```\n\n## 🏗 Framework Design\n\n![](https://static.loopring.io/Loopring%20framwork.png)\n\n## 👉 [What is Loopring?](https://loopring.org/#/)\n\n## 🫂 Community\n\n- [Loopring Website](https://loopring.org/)\n- [Loopring Exchange](https://loopring.io/#/layer2)\n- [Loopring Reddit](https://www.reddit.com/r/loopringorg/)\n- [Loopring Medium](https://medium.com/loopring-protocol)\n- [Loopring Twitter](https://twitter.com/loopringorg)\n- [Loopring Telegram](https://t.me/loopring_en)\n\n## 👺 For Developer\n\n- We appreciate any improvements or initiatives for Loopring Layer2 website, please view the source code\n  in `./packages/component-lib`.\n- The project contains a separate lib \"web3-provider\", which is a third-party ETH web3 wallet provider service (\n  wallectConnect & metamask),\n- You are welcome to reuse it or integrate your provider service with our website.\n- Feel free to leave suggestions or ideas.\n\n### 📒 API & Dependency\n\n- [Web3-Provider](https://www.npmjs.com/package/@loopring-web/web3-provider)\n- [Loopring-sdk](https://www.npmjs.com/package/@loopring-web/loopring-sdk)\n- [Python](https://github.com/Loopring/hello_loopring)\n- [APIs](https://docs.loopring.io/)\n\n## 🙋 Protocol & Architecture\n\n- [Whitepaper](https://loopring.org/resources/en_whitepaper.pdf)\n- [Design Docs](https://github.com/LoopringSecondary/docs/wiki/Loopring3_Design)\n\n## ❓[Help](https://desk.zoho.com/portal/loopring/en/home)\n\n## 🔑 Security\n\n- [Wallet](https://security.loopring.io/)\n- [Protocol Audit](https://loopring.org/resources/loopring1.0_audit.pdf)\n\n## Release Process\n\nalpha.loopring.io, beta.loopring.io, static.loopring.io, and loopring.io are now auto deployed using Vercel.\n"
  },
  {
    "path": "packages/web-earn/craco.config.js",
    "content": "module.exports = require(\"../../craco.config.cjs\")"
  },
  {
    "path": "packages/web-earn/electron-builder.env",
    "content": "ELECTRON_BUILDER_ALLOW_UNRESOLVED_DEPENDENCIES=true\n"
  },
  {
    "path": "packages/web-earn/generate-react-cli.json",
    "content": "{\n  \"usesTypeScript\": true,\n  \"usesCssModule\": true,\n  \"cssPreprocessor\": \"scss\",\n  \"testLibrary\": \"Testing Library\",\n  \"component\": {\n    \"default\": {\n      \"path\": \"src/components\",\n      \"withLazy\": false,\n      \"withStory\": true,\n      \"withStyle\": true,\n      \"withTest\": true\n    },\n    \"page\": {\n      \"path\": \"src/pages\",\n      \"withLazy\": true,\n      \"withStory\": false,\n      \"withStyle\": true,\n      \"withTest\": true\n    },\n    \"layout\": {\n      \"path\": \"src/layout\",\n      \"withLazy\": false,\n      \"withStory\": false,\n      \"withStyle\": false,\n      \"withTest\": true\n    }\n  }\n}\n"
  },
  {
    "path": "packages/web-earn/jest.config.js",
    "content": "module.exports = {\n  testEnvironment: 'node',\n\n  setupFilesAfterEnv: ['./jest.setup.js'],\n}\n"
  },
  {
    "path": "packages/web-earn/jest.setup.js",
    "content": "process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0\n\njest.setTimeout(30000)\n"
  },
  {
    "path": "packages/web-earn/package.json",
    "content": "{\n  \"name\": \"@loopring-web/web-earn\",\n  \"version\": \"1.0.0\",\n  \"author\": \"Loopring L2 App Frontend Team\",\n  \"description\": \"dexwebapp new version\",\n  \"private\": true,\n  \"dependencies\": {\n    \"@loopring-web/common-resources\": \"1.0.0\",\n    \"@loopring-web/component-lib\": \"1.0.0\",\n    \"@loopring-web/core\": \"1.0.0\",\n    \"@manaflair/redux-batch\": \"^1.0.0\",\n    \"clipboard\": \"^2.0.8\",\n    \"export-from-json\": \"^1.4.0\",\n    \"lodash\": \"^4.17.20\",\n    \"ms.macro\": \"^2.0.0\",\n    \"react-device-detect\": \"^1.17.0\",\n    \"react-router-dom\": \"^5.2.0\",\n    \"redux-logger\": \"^3.0.6\",\n    \"redux-saga\": \"^1.1.3\",\n    \"snarkjs\": \"0.1.20\",\n    \"web-vitals\": \"^0.2.4\"\n  },\n  \"dependencies\": {\n    \"@loopring-web/common-resources\": \"1.0.0\",\n    \"@loopring-web/component-lib\": \"1.0.0\",\n    \"@loopring-web/core\": \"1.0.0\",\n    \"react-scripts\": \"5.0.1\",\n    \"cross-env\": \"^7.0.3\"\n  },\n  \"resolutions\": {\n    \"@types/react\": \"^18.2.19\",\n    \"@types/react-dom\": \"^18.2.7\"\n  },\n  \"build\": {\n    \"files\": [\n      \"build/**/*\",\n      \"node_modules/**/*\"\n    ],\n    \"publish\": {\n      \"provider\": \"custom\",\n      \"repo\": \"https://github.com/Loopring/loopring-web-v2\",\n      \"owner\": \"Loopring Dex Frontend Team\"\n    }\n  },\n  \"main\": \"./public/electron.js\",\n  \"homepage\": \".\",\n  \"scripts\": {\n    \"prettier\": \"prettier . --write\",\n    \"build\": \"git rev-parse --short HEAD; cross-env REACT_APP_VER=`git rev-parse --short HEAD`_prod dotenv -e .env.production  craco build\",\n    \"dev\": \"cross-env REACT_APP_VER=\\\"git rev-parse --short HEAD\\\"_dev dotenv -e .env.development craco start\",\n    \"build_dev\": \"REACT_APP_VER=`git rev-parse --short HEAD`_dev dotenv -e .env.development craco build\"\n  },\n  \"browserslist\": {\n    \"production\": [\n      \"last 2 chrome version\",\n      \"last 2 firefox version\",\n      \"last 2 safari version\"\n    ],\n    \"development\": [\n      \"last 1 chrome version\",\n      \"last 1 firefox version\",\n      \"last 1 safari version\"\n    ]\n  }\n}\n"
  },
  {
    "path": "packages/web-earn/public/badge.xml",
    "content": "<FrameLayout xmlns:android=\"https://download.loopring.io/LoopringWallet.apk\"\n             xmlns:app=\"https://download.loopring.io/\"\n             android:layout_width=\"match_parent\"\n             android:layout_height=\"match_parent\">\n\n    <TextView\n            android:id=\"@+id/notifications.badge\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"top|center_horizontal\"\n            android:layout_marginLeft=\"10dp\"\n            android:layout_marginStart=\"10dp\"\n            android:background=\"@drawable/notification_badge\"\n            android:gravity=\"center\"\n            android:padding=\"3dp\"\n            android:text=\"9+\"\n            android:textColor=\"@color/white\"\n            android:textSize=\"11sp\"/>\n</FrameLayout>"
  },
  {
    "path": "packages/web-earn/public/browserconfig.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<browserconfig>\n    <msapplication>\n        <tile>\n            <!--            <square70x70logo src=\"small.png\"/>-->\n            <!--            <square150x150logo src=\"medium.png\"/>-->\n            <!--            <wide310x150logo src=\"wide.png\"/>-->\n            <!--            <square310x310logo src=\"large.png\"/>-->\n            <square129x129logo src=\"loopring129.png\"/>\n            <TileColor>#3B5AF4</TileColor>\n        </tile>\n        <badge>\n            <polling-uri src=\"badge.xml\"/>\n            <frequency>30</frequency>\n        </badge>\n        <!--        <notification>-->\n        <!--            <polling-uri  src=\"1.xml\"/>-->\n        <!--            <polling-uri2 src=\"2.xml\"/>-->\n        <!--            <polling-uri3 src=\"3.xml\"/>-->\n        <!--            <polling-uri4 src=\"4.xml\"/>-->\n        <!--            <polling-uri5 src=\"5.xml\"/>-->\n        <!--            <frequency>30</frequency>-->\n        <!--            <cycle>1</cycle>-->\n        <!--        </notification>-->\n    </msapplication>\n</browserconfig>"
  },
  {
    "path": "packages/web-earn/public/electron.js",
    "content": "const path = require('path')\n\nconst { app, BrowserWindow } = require('electron')\nconst isDev = require('electron-is-dev')\n\nconsole.log('BROWSER:', process.env.BROWSER)\nconsole.log('NODE_ENV:', process.env.NODE_ENV)\n\nfunction createWindow() {\n  // Create the browser window.\n  const win = new BrowserWindow({\n    width: 1024,\n    height: 768,\n    frame: true,\n    webPreferences: {\n      nodeIntegration: true,\n    },\n  })\n\n  // and load the index.html of the app.\n  // win.loadFile(\"index.html\");\n  win.loadURL(\n    isDev ? 'http://localhost:3000' : `file://${path.join(__dirname, '../build/index.html')}`,\n  )\n\n  // Open the DevTools.\n  if (isDev) {\n    win.webContents.openDevTools({ mode: 'detach' })\n  }\n}\n\n// This method will be called when Electron has finished\n// initialization and is ready to create browser windows.\n// Some APIs can only be used after this event occurs.\napp.whenReady().then(createWindow)\n\n// Quit when all windows are closed, except on macOS. There, it's common\n// for applications and their menu bar to stay active until the user quits\n// explicitly with Cmd + Q.\napp.on('window-all-closed', () => {\n  if (process.platform !== 'darwin') {\n    app.quit()\n  }\n})\n\napp.on('activate', () => {\n  // On macOS it's common to re-create a window in the app when the\n  // dock icon is clicked and there are no other windows open.\n  if (BrowserWindow.getAllWindows().length === 0) {\n    createWindow()\n  }\n})\n"
  },
  {
    "path": "packages/web-earn/public/index.html",
    "content": "<!DOCTYPE html>\n<html lang='en'>\n<head>\n  <meta charset='utf-8' />\n  <link rel='icon' href='%PUBLIC_URL%/favicon.ico' />\n  <link rel='mask-icon' href='%PUBLIC_URL%/loopring.svg' color='#3B5AF4' />\n  <link rel='icon' type='image/png' href='%PUBLIC_URL%/favicon.png' />\n  <link rel='icon' type='image/png' sizes='16x16' href='%PUBLIC_URL%/favicon-16x16.png' />\n  <link rel='icon' type='image/png' sizes='32x32' href='%PUBLIC_URL%/favicon-32x32.png' />\n  <link rel='icon' type='image/png' sizes='48x48' href='%PUBLIC_URL%/favicon-48x48.png' />\n  <link\n    rel='apple-touch-icon'\n    type='image/png'\n    sizes='180x180'\n    href='%PUBLIC_URL%/apple-touch-icon.png'\n  />\n  <meta\n    name='viewport'\n    content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0'\n  />\n  <meta name='theme-color' content='#000000' />\n  <meta\n    name='description'\n    content='Bring the most innovative structural products to DeFi world'\n  />\n  <link\n    rel='stylesheet'\n    href='https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap'\n  />\n  <link href='/apple-touch-icon.png' rel='/apple-touch-icon' />\n  <!--\n    manifest.json provides metadata used when your web app is installed on a\n    user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/\n  -->\n  <link rel='manifest' href='%PUBLIC_URL%/manifest.json' />\n  <!--\n    Notice the use of %PUBLIC_URL% in the tags above.\n    It will be replaced with the URL of the `public` folder during the build.\n    Only files inside the `public` folder can be referenced from the HTML.\n\n    Unlike \"/favicon.ico\" or \"favicon.ico\", \"%PUBLIC_URL%/favicon.ico\" will\n    work correctly both with client-side routing and a non-root public URL.\n    Learn how to configure a non-root public URL by running `npm run build`.\n  -->\n  <style type='text/css'>\n      body {\n          height: 100vh;\n          background: linear-gradient(194.79deg, #141414 17.96%, #141414 44.29%, #1F1F1F 96.93%);\n          color: #fff;\n          flex-direction: column;\n      }\n\n      .iubenda-pure {\n          height: 0;\n      !important;\n          width: 0;\n      !important;\n          line-height: 0;\n      !important;\n          overflow: hidden;\n      !important;\n          padding: 0;\n          margin: 0;\n          display: none;\n      !important;\n\n      }\n\n      #iubenda-pp iframe {\n          display: block;\n      }\n  </style>\n  <script async src='https://www.googletagmanager.com/gtag/js?id=UA-224502206-1'></script>\n  <script>\n    window.dataLayer = window.dataLayer || []\n\n    function gtag() {\n      dataLayer.push(arguments)\n    }\n\n    gtag('js', new Date())\n    gtag('config', 'UA-224502206-1')\n  </script>\n  <title>Loopring DeFi</title>\n  <!-- Global site tag (gtag.js) - Google Analytics -->\n</head>\n\n<body ondragstart='return false;' ondrop='return false;' draggable='false'>\n<noscript>You need to enable JavaScript to run this app.</noscript>\n<div id='root' style='width: 100%; height: 100vh; display: flex; flex-direction: column'></div>\n<!--\n  This HTML file is a template.\n  If you open it directly in the browser, you will see an empty page.\n\n  You can add webfonts, meta tags, or analytics to this file.\n  The build step will place the bundled scripts into the <body> tag.\n\n  To begin the development, run `npm start` or `yarn start`.\n  To create a production bundle, use `npm run build` or `yarn build`.\n-->\n<div hidden>\n  <a\n    href='https://www.iubenda.com/terms-and-conditions/74969935'\n    data-index='0'\n    class='iubenda-white iubenda-embed iubenda-pure iubenda-noiframe'\n  ></a>\n  <!--      <a href=\"https://www.iubenda.com/terms-and-conditions/74969935\"-->\n  <!--         class=\"iubenda-black iubenda-embed iubenda-pure iubenda-noiframe\"></a>-->\n</div>\n\n<!--<button id=\"iframeButton\">Launch iframe</button>-->\n<div id='iframeBanxaTarget'>\n  <div id='iframeBanxaClose'>\n    <svg fill='#00C8C0' height='24' viewBox='0 0 24 24' width='24'>\n      <path\n        d='M17.59 5L12 10.59L6.41 5L5 6.41L10.59 12L5 17.59L6.41 19L12 13.41L17.59 19L19 17.59L13.41 12L19 6.41L17.59 5Z'\n      />\n    </svg>\n  </div>\n  <!-- Where the iframe will be loaded  -->\n</div>\n<script type='text/javascript'>\n  ;(function(w, d) {\n    var loader = function() {\n      var s = d.createElement('script'),\n        tag = d.getElementsByTagName('script')[0]\n      s.src = 'https://cdn.iubenda.com/iubenda.js'\n      tag.parentNode.insertBefore(s, tag)\n\n      var b = d.createElement('script')\n      ;(b.type = 'text/javascript'),\n        (b.async = !0),\n        (b.src = 'https://sdk.banxa.com/js/banxa-sdk-latest.js')\n      tag.parentNode.insertBefore(b, tag)\n    }\n    if (w.addEventListener) {\n      w.addEventListener('load', loader, false)\n    } else if (w.attachEvent) {\n      w.attachEvent('onload', loader)\n    } else {\n      w.onload = loader\n    }\n  })(window, document)\n</script>\n<script\n  src='https://ajax.googleapis.com/ajax/libs/model-viewer/3.0.1/model-viewer.min.js'\n  type='module'\n></script>\n</body>\n</html>\n"
  },
  {
    "path": "packages/web-earn/public/manifest.json",
    "content": "{\n  \"short_name\": \"Loopring L2\",\n  \"name\": \"Loopring - Ethereum Layer2\",\n  \"icons\": [\n    {\n      \"src\": \"favicon.ico\",\n      \"sizes\": \"64x64 32x32 24x24 16x16\",\n      \"type\": \"image/x-icon\"\n    }\n  ],\n  \"start_url\": \".\",\n  \"display\": \"standalone\",\n  \"theme_color\": \"#000000\",\n  \"background_color\": \"#ffffff\"\n}\n"
  },
  {
    "path": "packages/web-earn/public/robots.txt",
    "content": "# https://www.robotstxt.org/robotstxt.html\nUser-agent: *\nDisallow:\n"
  },
  {
    "path": "packages/web-earn/src/App.tsx",
    "content": "import RouterView from './routers'\nimport { GlobalStyles } from '@mui/material'\nimport { css, Theme, useTheme } from '@emotion/react'\nimport { globalCss } from '@loopring-web/common-resources'\nimport { setLanguage } from '@loopring-web/component-lib'\nimport { useInit } from './hook'\nimport React from 'react'\nimport { useTranslation } from 'react-i18next'\n\nimport { HashRouter as Router, useLocation } from 'react-router-dom'\nimport { store } from '@loopring-web/core'\n\nconst ScrollToTop = () => {\n  const { pathname } = useLocation()\n\n  React.useEffect(() => {\n    window.scrollTo(0, 0)\n  }, [pathname])\n\n  return null\n}\nconst App = () => {\n  const theme: Theme = useTheme()\n  const {\n    i18n: { language },\n  } = useTranslation()\n  const storeLan = store.getState().settings.language\n\n  React.useEffect(() => {\n    if (storeLan !== language) {\n      store.dispatch(setLanguage(language))\n    }\n  }, [storeLan, language])\n\n  React.useEffect(() => {\n    if (window.location.protocol !== 'https:') {\n      console.log('Current PROTOCOL::', window.location.protocol)\n      window.location.replace(\n        `https:${window.location.href.substring(window.location.protocol.length)}`,\n      )\n    }\n  }, [])\n\n  const { state } = useInit()\n\n  return (\n    <>\n      <GlobalStyles\n        styles={css`\n          ${globalCss({ theme })};\n\n          body {\n            ${\n              theme.mode === 'dark'\n                ? `\n            color: ${theme.colorBase.textPrimary};\n          `\n                : ``\n            }\n\n\n          }\n\n          body:before {\n            ${\n              theme.mode === 'dark'\n                ? `\n            background: var(--color-global-bg);\n       `\n                : ''\n            }\n          }\n        }`}\n      />\n\n      <Router>\n        <ScrollToTop />\n        <RouterView state={state} />\n      </Router>\n    </>\n  )\n}\nconst h = new Headers()\nexport default App\n"
  },
  {
    "path": "packages/web-earn/src/constant/index.ts",
    "content": "export * from 'routers'\n"
  },
  {
    "path": "packages/web-earn/src/constant/router.ts",
    "content": "import {\n  HeaderMenuItemInterface,\n  HeaderMenuTabStatus,\n  RecordTabIndex,\n  WalletSite,\n  ButtonComponentsMap,\n  SecurityIcon,\n} from '@loopring-web/common-resources'\nimport { ChainId, SoursURL } from '@loopring-web/loopring-sdk'\n\nexport const toolBarAvailableEarnItem: number[] = [\n  ButtonComponentsMap.Download,\n  ButtonComponentsMap.Notification,\n  ButtonComponentsMap.Setting,\n  ButtonComponentsMap.WalletConnect,\n  ButtonComponentsMap.TestNet,\n]\n\nexport enum RouterPath {\n  // lite = '/trade/lite',\n  // pro = '/trade/pro',\n  // stoplimit = '/trade/stoplimit',\n  btrade = '/trade/btrade',\n  // fiat = '/trade/fiat',\n  // markets = '/markets',\n  // mining = '/mining',\n  // redPacket = '/redPacket',\n  l2assets = '/l2assets',\n  layer2 = '/layer2',\n  // nft = '/nft',\n  invest = '/invest',\n  dualIntro = '/dual-intro',\n  intro = '/intro',\n  portal = '/portal',\n  taikoFarming = '/taiko-farming',\n}\n\nexport enum RouterMainKey {\n  l2assets = 'l2assets',\n  dualIntro = 'dualIntro',\n  invest = 'invest',\n  layer2 = 'layer2',\n  portal = 'portal',\n  btrade = 'btrade',\n  taikoFarming = 'taikoFarming',\n\n}\n\nexport const headerMenuEartData: Array<HeaderMenuItemInterface> = [\n  {\n    label: {\n      id: 'L2Assets',\n      i18nKey: 'labelVault2',\n      description: 'labelAssetsDes',\n    },\n    router: { path: '/l2assets' },\n    status: HeaderMenuTabStatus.default,\n    logo: {\n      dark: SoursURL + 'images/earn_nav_assets_dark.png',\n      light: SoursURL + 'images/earn_nav_assets_light.png',\n    }\n  },\n  {\n    label: {\n      id: 'dual',\n      i18nKey: 'labelDualInvest',\n      description: 'labelDualInvestDes',\n    },\n    router: { path: '/invest/dual' },\n    status: HeaderMenuTabStatus.default,\n    logo: {\n      dark: SoursURL + 'images/earn_nav_dual_dark.png',\n      light: SoursURL + 'images/earn_nav_dual_light.png',\n    }\n  },\n  {\n    label: {\n      id: 'portal',\n      i18nKey: 'labelVault',\n      description: 'labelVaultDes',\n    },\n    router: { path: '/portal' },\n    status: HeaderMenuTabStatus.default,\n    logo: {\n      dark: SoursURL + 'images/earn_nav_portal_dark.png',\n      light: SoursURL + 'images/earn_nav_portal_light.png',\n    }\n  },\n  {\n    label: {\n      id: 'btrade',\n      i18nKey: 'labelBtradeTrade',\n      description: 'labelBtradeTradeDes',\n    },\n    router: { path: '/trade/btrade' },\n    status: HeaderMenuTabStatus.default,\n    logo: {\n      dark: SoursURL + 'images/earn_nav_btrade_dark.png',\n      light: SoursURL + 'images/earn_nav_btrade_light.png',\n    }\n  },\n  {\n    label: {\n      id: 'taikoFarming',\n      i18nKey: 'labelTaikoFarming',\n    },\n    router: { path: '/taiko-farming' },\n    status: HeaderMenuTabStatus.default,\n  }\n]\n\nexport const RouterAllowIndex = {\n  TAIKOHEKLA: [\n    RouterMainKey.l2assets,\n    RouterMainKey.dualIntro,\n    RouterMainKey.layer2,\n    RouterMainKey.invest,\n    RouterMainKey.portal,\n    RouterMainKey.btrade,\n    RouterMainKey.taikoFarming,\n  ],\n  ETHEREUM: [\n    RouterMainKey.l2assets,\n    RouterMainKey.dualIntro,\n    RouterMainKey.layer2,\n    RouterMainKey.invest,\n    RouterMainKey.portal,\n    RouterMainKey.btrade,\n    RouterMainKey.taikoFarming,\n  ],\n  GOERLI: [],\n  SEPOLIA: [\n    RouterMainKey.l2assets,\n    RouterMainKey.dualIntro,\n    RouterMainKey.layer2,\n    RouterMainKey.invest,\n    RouterMainKey.portal,\n    RouterMainKey.btrade,\n    RouterMainKey.taikoFarming,\n  ],\n  ARBGOERLI: [\n    RouterMainKey.l2assets,\n    RouterMainKey.dualIntro,\n    RouterMainKey.invest,\n  ],\n  TAIKO: [\n    RouterMainKey.l2assets,\n    RouterMainKey.dualIntro,\n    RouterMainKey.layer2,\n    RouterMainKey.invest,\n    RouterMainKey.portal,\n    RouterMainKey.btrade,\n    RouterMainKey.taikoFarming,\n  ],\n  BASE: [\n    RouterMainKey.l2assets,\n    RouterMainKey.dualIntro,\n    RouterMainKey.layer2,\n    RouterMainKey.invest,\n    RouterMainKey.portal,\n    RouterMainKey.btrade,\n    RouterMainKey.taikoFarming,\n  ],\n  BASESEPOLIA: [\n    RouterMainKey.l2assets,\n    RouterMainKey.dualIntro,\n    RouterMainKey.layer2,\n    RouterMainKey.invest,\n    RouterMainKey.portal,\n    RouterMainKey.btrade,\n    RouterMainKey.taikoFarming,\n  ],\n}\n\nexport const headerMenuDataEarnMap: { [key: string]: HeaderMenuItemInterface[] } = {\n  TAIKOHEKLA: headerMenuEartData,\n  TAIKO: headerMenuEartData,\n  ETHEREUM: headerMenuEartData,\n  GOERLI: headerMenuEartData,\n  SEPOLIA: headerMenuEartData,\n  ARBGOERLI: headerMenuEartData,\n  BASE: headerMenuEartData,\n  BASESEPOLIA: headerMenuEartData,\n}\n\nexport const RecordEarnMap: { [key: string]: RecordTabIndex[] } = {\n  TAIKO: [RecordTabIndex.Transactions, RecordTabIndex.DualRecords, RecordTabIndex.VaultRecords, RecordTabIndex.BtradeSwapRecords, RecordTabIndex.TaikoLockRecords],\n  ETHEREUM: [RecordTabIndex.Transactions, RecordTabIndex.DualRecords, RecordTabIndex.VaultRecords, RecordTabIndex.BtradeSwapRecords],\n  GOERLI: [RecordTabIndex.Transactions, RecordTabIndex.DualRecords, RecordTabIndex.VaultRecords, RecordTabIndex.BtradeSwapRecords],\n  SEPOLIA: [RecordTabIndex.Transactions, RecordTabIndex.DualRecords, RecordTabIndex.VaultRecords, RecordTabIndex.BtradeSwapRecords],\n  ARBGOERLI: [RecordTabIndex.Transactions, RecordTabIndex.DualRecords, RecordTabIndex.VaultRecords, RecordTabIndex.BtradeSwapRecords],\n  TAIKOHEKLA: [RecordTabIndex.Transactions, RecordTabIndex.DualRecords, RecordTabIndex.VaultRecords, RecordTabIndex.BtradeSwapRecords, RecordTabIndex.TaikoLockRecords],\n  BASE: [RecordTabIndex.Transactions, RecordTabIndex.DualRecords, RecordTabIndex.VaultRecords, RecordTabIndex.BtradeSwapRecords],\n  BASESEPOLIA: [RecordTabIndex.Transactions, RecordTabIndex.DualRecords, RecordTabIndex.VaultRecords, RecordTabIndex.BtradeSwapRecords],\n}\nexport enum AssetTabIndex {\n  Tokens = 'Tokens',\n  DefiPortfolio = 'DefiPortfolio',\n}\nexport const AssetL2TabEarnIndex = {\n  TAIKO: [AssetTabIndex.Tokens, AssetTabIndex.DefiPortfolio],\n  ETHEREUM: [AssetTabIndex.Tokens, AssetTabIndex.DefiPortfolio],\n  GOERLI: [AssetTabIndex.Tokens, AssetTabIndex.DefiPortfolio],\n  SEPOLIA: [AssetTabIndex.Tokens, AssetTabIndex.DefiPortfolio],\n  ARBGOERLI: [AssetTabIndex.Tokens, AssetTabIndex.DefiPortfolio],\n  Arbitrum: [AssetTabIndex.Tokens, AssetTabIndex.DefiPortfolio],\n  TAIKOHEKLA: [AssetTabIndex.Tokens, AssetTabIndex.DefiPortfolio],\n  BASE: [AssetTabIndex.Tokens, AssetTabIndex.DefiPortfolio],\n  BASESEPOLIA: [AssetTabIndex.Tokens, AssetTabIndex.DefiPortfolio],\n}\nexport const RouterAllowEarnIndex = {\n  TAIKOHEKLA: [RouterMainKey.l2assets, RouterMainKey.invest],\n  TAIKO: [RouterMainKey.l2assets, RouterMainKey.invest],\n  ETHEREUM: [RouterMainKey.l2assets, RouterMainKey.invest],\n  GOERLI: [RouterMainKey.l2assets, RouterMainKey.invest],\n  SEPOLIA: [RouterMainKey.l2assets, RouterMainKey.invest],\n  ARBGOERLI: [RouterMainKey.l2assets, RouterMainKey.invest],\n  BASE: [RouterMainKey.l2assets, RouterMainKey.invest],\n  BASESEPOLIA: [RouterMainKey.l2assets, RouterMainKey.invest],\n}\n\nexport const earnHeaderToolBarData: {\n  [key in ButtonComponentsMap]?: {\n    buttonComponent: ButtonComponentsMap\n    handleClick?: (props: any) => void\n    [key: string]: any\n  }\n} = {\n  [ButtonComponentsMap.Download]: {\n    buttonComponent: ButtonComponentsMap.Download,\n    url: WalletSite,\n  },\n  [ButtonComponentsMap.Setting]: {\n    buttonComponent: ButtonComponentsMap.Setting,\n    label: 'labelSetting',\n  },\n  [ButtonComponentsMap.ProfileMenu]: {\n    buttonComponent: ButtonComponentsMap.ProfileMenu,\n    i18nDescription: 'labelProfile',\n    readyState: undefined,\n  },\n  [ButtonComponentsMap.WalletConnect]: {\n    buttonComponent: ButtonComponentsMap.WalletConnect,\n    label: 'labelConnectWallet',\n    accountState: undefined,\n    handleClick: undefined,\n  },\n}\n\nexport const earnHeaderToolBarDataMobile: {\n  [key in ButtonComponentsMap]?: {\n    buttonComponent: ButtonComponentsMap\n    handleClick?: (props: any) => void\n    [key: string]: any\n  }\n} = {\n  [ButtonComponentsMap.ProfileMenu]: {\n    buttonComponent: ButtonComponentsMap.ProfileMenu,\n    i18nDescription: 'labelProfile',\n    readyState: undefined,\n  },\n  [ButtonComponentsMap.WalletConnect]: {\n    buttonComponent: ButtonComponentsMap.WalletConnect,\n    label: 'labelConnectWallet',\n    accountState: undefined,\n    handleClick: undefined,\n  },\n}\nexport enum EarnLayer2RouterID {\n  security = 'security',\n}\n\nexport const EarnProfile = {\n  security: [\n    {\n      icon: SecurityIcon,\n      router: { path: `${RouterPath.layer2}/${EarnLayer2RouterID.security}` },\n      label: {\n        id: 'security',\n        i18nKey: 'labelSecurity',\n      },\n    },\n  ],\n}\n"
  },
  {
    "path": "packages/web-earn/src/constant/setting.ts",
    "content": "import { IsMobile } from \"@loopring-web/common-resources\"\n\n\nexport const RowEarnConfig = {\n  rowHeight: IsMobile.any() ? 48 : 72,\n  rowHeaderHeight: IsMobile.any() ? 48 : 44,\n  minHeight: 350\n}"
  },
  {
    "path": "packages/web-earn/src/hook.ts",
    "content": "import React from 'react'\nimport {\n  useSystem,\n  useAmmMap,\n  useTokenMap,\n  useAccount,\n  useTicker,\n  useAmmActivityMap,\n  useTokenPrices,\n  useAmount,\n  useSocket,\n  useNotify,\n  layer1Store,\n  useDefiMap,\n  useInvestTokenTypeMap,\n  useDualMap,\n  useStakingMap,\n  useBtradeMap,\n  useInjectWeb3Modal,\n} from '@loopring-web/core'\nimport { ChainId } from '@loopring-web/loopring-sdk'\nimport { myLog, SagaStatus, SUPPORTING_NETWORKS, ThemeType } from '@loopring-web/common-resources'\nimport {\n  ConnectProviders,\n  ConnectProvides,\n  connectProvides,\n  walletServices,\n} from '@loopring-web/web3-provider'\nimport { useAccountInit } from './hookAccountInit'\nimport { useSettings } from '@loopring-web/component-lib'\nimport { useTheme } from '@emotion/react'\nimport { useAppKitNetwork } from '@reown/appkit/react'\n\n/**\n * @description\n * @step1 subscribe Connect hook\n * @step2 check the session storage ? choose the provider : none provider\n * @step3 decide china ID by step2\n * @step4 prepare the static date (tokenMap, ammMap, faitPrice, gasPrice, Activities ...)\n * @step5 launch the page\n */\nexport function useInit() {\n  const [, search] = window.location?.hash.split('?') ?? []\n  const searchParams = new URLSearchParams(search)\n  const [, pathname1] = window.location.hash.match(/#\\/([\\w\\d\\-]+)\\??/) ?? []\n  const isNoServer: boolean =\n    searchParams.has('noheader') && ['notification', 'document'].includes(pathname1)\n  const [state, setState] = React.useState<keyof typeof SagaStatus>(() => {\n    if (isNoServer) {\n      return SagaStatus.DONE\n    } else {\n      return SagaStatus.PENDING\n    }\n  })\n  const { isMobile, defaultNetwork } = useSettings()\n  const theme = useTheme()\n\n  const {\n    account,\n    updateAccount,\n    resetAccount,\n    status: accountStatus,\n    statusUnset: accountStatusUnset,\n  } = useAccount()\n  const { status: tokenMapStatus, statusUnset: tokenMapStatusUnset } = useTokenMap()\n  const { status: ammMapStatus, statusUnset: ammMapStatusUnset } = useAmmMap()\n  const { status: tokenPricesStatus, statusUnset: tokenPricesUnset } = useTokenPrices()\n  const { status: defiMapStatus, statusUnset: defiMapStatusUnset } = useDefiMap()\n  const { status: dualMapStatus, statusUnset: dualMapStatusUnset } = useDualMap()\n  const { status: stakingMapStatus, statusUnset: stakingMapStatusUnset } = useStakingMap()\n  const { status: btradeMapStatus, statusUnset: btradeMapStatusUnset } = useBtradeMap()\n  const { status: investTokenTypeMapStatus, statusUnset: investTokenTypeMapStatusUnset } =\n    useInvestTokenTypeMap()\n\n  const { updateSystem, status: systemStatus, statusUnset: systemStatusUnset } = useSystem()\n  const { status: ammActivityMapStatus, statusUnset: ammActivityMapStatusUnset } =\n    useAmmActivityMap()\n  const { status: tickerStatus, statusUnset: tickerStatusUnset } = useTicker()\n  const { status: amountStatus, statusUnset: amountStatusUnset } = useAmount()\n  const { status: socketStatus, statusUnset: socketUnset } = useSocket()\n  const { circleUpdateLayer1ActionHistory } = layer1Store.useLayer1Store()\n  const { status: notifyStatus, statusUnset: notifyStatusUnset } = useNotify()\n  const { chainId: _chainId } =  useAppKitNetwork()\n  const chainId = Number(_chainId)\n  \n\n  React.useEffect(() => {\n    ConnectProvides.walletConnectClientMeta = {\n      ...ConnectProvides.walletConnectClientMeta,\n      url:\n        process?.env?.REACT_APP_WALLETCONNECTCLIENTMETA_URL ??\n        ConnectProvides.walletConnectClientMeta.url,\n      name:\n        process?.env?.REACT_APP_WALLETCONNECTCLIENTMETA_NAME ??\n        ConnectProvides.walletConnectClientMeta.name,\n      description:\n        process?.env?.REACT_APP_WALLETCONNECTCLIENTMETA_DESCRIPTION ??\n        ConnectProvides.walletConnectClientMeta.description,\n    }\n    ;(async (account) => {\n      if (\n        account.accAddress !== ''\n      ) {\n        try {\n          ConnectProvides.IsMobile = isMobile\n          if (chainId) {\n            updateAccount({})\n            const _chainId = !SUPPORTING_NETWORKS\n            .includes(chainId.toString())\n              ? account._chainId && account._chainId !== 'unknown'\n                ? account._chainId\n                : ChainId.MAINNET\n              : chainId\n            circleUpdateLayer1ActionHistory({ chainId: _chainId })\n\n            if (!isNoServer) {\n              updateSystem({ chainId: _chainId as any })\n            }\n            return\n          }\n        } catch (error: any) {\n          walletServices.sendDisconnect('', `error at init loading  ${error}, disconnect`)\n          const chainId =\n            account._chainId && account._chainId !== 'unknown' ? account._chainId : ChainId.MAINNET\n          if (!isNoServer) {\n            updateSystem({ chainId })\n          }\n        }\n      } else {\n        if (account.accAddress === '') {\n          resetAccount()\n        }\n        const chainId =\n          account._chainId && account._chainId !== 'unknown' ? account._chainId : ChainId.MAINNET\n        if (!isNoServer) {\n          updateSystem({ chainId })\n        }\n      }\n    })(account)\n  }, [chainId])\n  React.useEffect(() => {\n    switch (accountStatus) {\n      case SagaStatus.ERROR:\n        accountStatusUnset()\n        setState('ERROR')\n        break\n      case SagaStatus.DONE:\n        accountStatusUnset()\n        break\n      default:\n        break\n    }\n  }, [accountStatus])\n  React.useEffect(() => {\n    switch (systemStatus) {\n      case SagaStatus.PENDING:\n        if (!searchParams.has('noheader') && state !== SagaStatus.PENDING) {\n          setState(SagaStatus.PENDING)\n        }\n        break\n      case SagaStatus.ERROR:\n        systemStatusUnset()\n        setState('ERROR')\n        break\n      case SagaStatus.DONE:\n        systemStatusUnset()\n        break\n      default:\n        break\n    }\n  }, [systemStatus])\n  React.useEffect(() => {\n    if (\n      tokenMapStatus === SagaStatus.UNSET &&\n      ammMapStatus === SagaStatus.UNSET &&\n      tokenPricesStatus === SagaStatus.UNSET\n    ) {\n      setState('DONE')\n    }\n  }, [tokenMapStatus, ammMapStatus, tokenPricesStatus])\n  React.useEffect(() => {\n    switch (tokenMapStatus) {\n      case SagaStatus.ERROR:\n        tokenMapStatusUnset()\n        setState('ERROR')\n        break\n      case SagaStatus.DONE:\n        tokenMapStatusUnset()\n        break\n      default:\n        break\n    }\n  }, [tokenMapStatus])\n  React.useEffect(() => {\n    switch (ammMapStatus) {\n      case SagaStatus.ERROR:\n        ammMapStatusUnset()\n        setState('ERROR')\n        break\n      case SagaStatus.DONE:\n        ammMapStatusUnset()\n        break\n      default:\n        break\n    }\n  }, [ammMapStatus])\n\n  React.useEffect(() => {\n    switch (tokenPricesStatus) {\n      case SagaStatus.ERROR:\n        tokenPricesUnset()\n        setState('ERROR')\n        break\n      case SagaStatus.DONE:\n        tokenPricesUnset()\n        break\n      default:\n        break\n    }\n  }, [tokenPricesStatus])\n  React.useEffect(() => {\n    switch (ammActivityMapStatus) {\n      case SagaStatus.ERROR:\n        console.log('Network ERROR::', 'getAmmPoolActivityRules')\n        ammActivityMapStatusUnset()\n        break\n      case SagaStatus.DONE:\n        ammActivityMapStatusUnset()\n        break\n      default:\n        break\n    }\n  }, [ammActivityMapStatus])\n  React.useEffect(() => {\n    switch (tickerStatus) {\n      case SagaStatus.ERROR:\n        console.log('Network ERROR::', 'getMixTicker')\n        tickerStatusUnset()\n        break\n      case SagaStatus.DONE:\n        tickerStatusUnset()\n        break\n      default:\n        break\n    }\n  }, [tickerStatus])\n  React.useEffect(() => {\n    switch (amountStatus) {\n      case SagaStatus.ERROR:\n        console.log('Network ERROR::', 'userAPI getMinimumTokenAmt')\n        amountStatusUnset()\n        break\n      case SagaStatus.DONE:\n        amountStatusUnset()\n        break\n      default:\n        break\n    }\n  }, [amountStatus])\n  React.useEffect(() => {\n    switch (socketStatus) {\n      case SagaStatus.ERROR:\n        socketUnset()\n        break\n      case SagaStatus.DONE:\n        socketUnset()\n        break\n      default:\n        break\n    }\n  }, [socketStatus])\n  React.useEffect(() => {\n    switch (notifyStatus) {\n      case SagaStatus.ERROR:\n        notifyStatusUnset()\n        break\n      case SagaStatus.DONE:\n        notifyStatusUnset()\n        break\n      default:\n        break\n    }\n  }, [notifyStatus])\n\n  React.useEffect(() => {\n    switch (defiMapStatus) {\n      case SagaStatus.ERROR:\n        defiMapStatusUnset()\n        // setState(\"ERROR\");\n        break\n      case SagaStatus.DONE:\n        defiMapStatusUnset()\n        break\n      default:\n        break\n    }\n  }, [defiMapStatus])\n\n  React.useEffect(() => {\n    switch (dualMapStatus) {\n      case SagaStatus.ERROR:\n        dualMapStatusUnset()\n        // setState(\"ERROR\");\n        break\n      case SagaStatus.DONE:\n        dualMapStatusUnset()\n        break\n      default:\n        break\n    }\n  }, [dualMapStatus])\n  React.useEffect(() => {\n    switch (stakingMapStatus) {\n      case SagaStatus.ERROR:\n        stakingMapStatusUnset()\n        // setState(\"ERROR\");\n        break\n      case SagaStatus.DONE:\n        stakingMapStatusUnset()\n        break\n      default:\n        break\n    }\n  }, [stakingMapStatus])\n  React.useEffect(() => {\n    switch (btradeMapStatus) {\n      case SagaStatus.ERROR:\n        btradeMapStatusUnset()\n        // setState(\"ERROR\");\n        break\n      case SagaStatus.DONE:\n        btradeMapStatusUnset()\n        break\n      default:\n        break\n    }\n  }, [btradeMapStatus])\n\n  React.useEffect(() => {\n    switch (investTokenTypeMapStatus) {\n      case SagaStatus.ERROR:\n        investTokenTypeMapStatusUnset()\n        // setState(\"ERROR\");\n        break\n      case SagaStatus.DONE:\n        investTokenTypeMapStatusUnset()\n        break\n      default:\n        break\n    }\n  }, [investTokenTypeMapStatus])\n\n  useAccountInit({ state })\n  useInjectWeb3Modal('EARN')\n  return {\n    state,\n  }\n}\n"
  },
  {
    "path": "packages/web-earn/src/hookAccountInit.ts",
    "content": "import React from 'react'\nimport { AccountStatus, SagaStatus } from '@loopring-web/common-resources'\nimport {\n  useWalletLayer1,\n  useWalletLayer2,\n  useAccount,\n  useUserRewards,\n  useConnect,\n  useWalletLayer2NFT,\n  useWalletL2NFTCollection,\n  useWalletL2Collection,\n  redPacketHistory,\n  offFaitService,\n  store,\n  useContacts,\n  useSocket,\n  useVaultTicker,\n  useVaultLayer2,\n} from '@loopring-web/core'\n\nexport function useAccountInit({ state }: { state: keyof typeof SagaStatus }) {\n  useConnect({ state })\n  const {\n    updateWalletLayer1,\n    status: walletLayer1Status,\n    statusUnset: wallet1statusUnset,\n  } = useWalletLayer1()\n  const {\n    resetLayer2NFT,\n    status: wallet2statusNFTStatus,\n    statusUnset: wallet2statusNFTUnset,\n  } = useWalletLayer2NFT()\n  const {\n    getUserRewards,\n    status: userRewardsStatus,\n    statusUnset: userRewardsUnset,\n  } = useUserRewards()\n  const {\n    updateWalletLayer2,\n    status: walletLayer2Status,\n    statusUnset: wallet2statusUnset,\n  } = useWalletLayer2()\n  const { updateContacts, status: contactsStatus, statusUnset: contactsUnset } = useContacts()\n\n  const {\n    updateWalletL2Collection,\n    updateLegacyContracts,\n    resetL2Collection,\n    status: walletL2CollectionStatus,\n    statusUnset: walletL2CollectionstatusUnset,\n  } = useWalletL2Collection()\n\n  const {\n    updateWalletL2NFTCollection,\n    resetL2NFTCollection,\n    status: walletL2NFTCollectionStatus,\n    statusUnset: walletL2NFTCollectionstatusUnset,\n  } = useWalletL2NFTCollection()\n  const { clearRedPacketHash } = redPacketHistory.useRedPacketHistory()\n  const { account, status: accountStatus } = useAccount()\n  const { sendSocketTopic, socketUserEnd } = useSocket()\n  \n  const {\n    updateVaultLayer2,\n    status: vaultLayer2Status,\n    statusUnset: vaultsLayer2Unset,\n  } = useVaultLayer2()\n  const { status: vaultTickerStatus, statusUnset: vaultTickerUnset } = useVaultTicker()\n\n\n  React.useEffect(() => {\n    if (state === SagaStatus.DONE) {\n      offFaitService.banxaEnd()\n      const account = store.getState().account\n      switch (account.readyState) {\n        case AccountStatus.UN_CONNECT:\n        case AccountStatus.ERROR_NETWORK:\n          socketUserEnd()\n          break\n        case AccountStatus.DEPOSITING:\n        case AccountStatus.NOT_ACTIVE:\n        case AccountStatus.LOCKED:\n        case AccountStatus.NO_ACCOUNT:\n          updateWalletLayer1()\n          if (walletLayer2Status !== SagaStatus.PENDING) {\n            updateWalletLayer2()\n            resetLayer2NFT()\n            resetL2NFTCollection()\n            resetL2Collection()\n          }\n          break\n        case AccountStatus.ACTIVATED:\n          getUserRewards()\n          clearRedPacketHash()\n          offFaitService.backendCheckStart()\n          if (walletLayer1Status !== SagaStatus.PENDING) {\n            updateWalletLayer1()\n          }\n          if (walletLayer2Status !== SagaStatus.PENDING) {\n            updateWalletLayer2()\n            updateWalletL2NFTCollection({ page: 1 })\n            updateWalletL2Collection({ page: 1 })\n          }\n          sendSocketTopic({})\n          updateLegacyContracts()\n          updateContacts()\n          break\n      }\n    }\n  }, [accountStatus, state, account.readyState])\n  React.useEffect(() => {\n    switch (walletLayer1Status) {\n      case SagaStatus.ERROR:\n        wallet1statusUnset()\n        break\n      case SagaStatus.DONE:\n        wallet1statusUnset()\n        break\n      default:\n        break\n    }\n  }, [walletLayer1Status])\n  React.useEffect(() => {\n    switch (walletLayer2Status) {\n      case SagaStatus.ERROR:\n        wallet2statusUnset()\n        break\n      case SagaStatus.DONE:\n        wallet2statusUnset()\n        break\n      default:\n        break\n    }\n  }, [walletLayer2Status])\n\n  React.useEffect(() => {\n    switch (walletL2CollectionStatus) {\n      case SagaStatus.ERROR:\n        walletL2CollectionstatusUnset()\n        break\n      case SagaStatus.DONE:\n        walletL2CollectionstatusUnset()\n        break\n      default:\n        break\n    }\n  }, [walletL2CollectionStatus])\n  React.useEffect(() => {\n    switch (walletL2NFTCollectionStatus) {\n      case SagaStatus.ERROR:\n        walletL2NFTCollectionstatusUnset()\n        break\n      case SagaStatus.DONE:\n        walletL2NFTCollectionstatusUnset()\n        break\n      default:\n        break\n    }\n  }, [walletL2NFTCollectionStatus])\n  React.useEffect(() => {\n    switch (wallet2statusNFTStatus) {\n      case SagaStatus.ERROR:\n        wallet2statusNFTUnset()\n        break\n      case SagaStatus.DONE:\n        wallet2statusNFTUnset()\n        break\n      default:\n        break\n    }\n  }, [wallet2statusNFTStatus])\n  React.useEffect(() => {\n    switch (userRewardsStatus) {\n      case SagaStatus.ERROR:\n        console.log('Network ERROR::', 'ammpoolAPI getAmmPoolUserRewards')\n        userRewardsUnset()\n        break\n      case SagaStatus.DONE:\n        userRewardsUnset()\n        break\n      default:\n        break\n    }\n  }, [userRewardsStatus])\n  React.useEffect(() => {\n    switch (contactsStatus) {\n      case SagaStatus.ERROR:\n        contactsUnset()\n        break\n      case SagaStatus.DONE:\n        contactsUnset()\n        break\n      default:\n        break\n    }\n  }, [contactsStatus])\n  React.useEffect(() => {\n    switch (vaultLayer2Status) {\n      case SagaStatus.ERROR:\n        vaultsLayer2Unset()\n        break\n      case SagaStatus.DONE:\n        vaultsLayer2Unset()\n        break\n      default:\n        break\n    }\n  }, [vaultLayer2Status])\n  React.useEffect(() => {\n    switch (vaultTickerStatus) {\n      case SagaStatus.ERROR:\n        vaultTickerUnset()\n        break\n      case SagaStatus.DONE:\n        vaultTickerUnset()\n        break\n      default:\n        break\n    }\n  }, [vaultTickerStatus])\n}\n"
  },
  {
    "path": "packages/web-earn/src/index.tsx",
    "content": "import { Provider } from 'react-redux'\nimport { createRoot } from 'react-dom/client'\nimport App from './App'\nimport reportWebVitals from './reportWebVitals'\nimport { store, persistor, TimeoutCheckProvider, firebaseProps } from '@loopring-web/core'\nimport { getTheme, i18n } from '@loopring-web/common-resources'\nimport { ThemeProvider as MuThemeProvider } from '@mui/material'\nimport { LocalizationProvider } from '@mui/lab'\nimport MomentUtils from '@mui/lab/AdapterMoment'\n\nimport { ThemeProvider } from '@emotion/react'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { I18nextProvider } from 'react-i18next'\nimport { PersistGate } from 'redux-persist/integration/react'\nimport { provider, ProviderComposer, useSettings } from '@loopring-web/component-lib'\nimport React, { Provider as TProvider } from 'react'\nimport { ReactReduxFirebaseProvider } from 'react-redux-firebase'\nimport VConsole from 'vconsole'\n\nif (process.env.REACT_APP_VER) {\n  console.log('VER:', process.env.REACT_APP_VER)\n}\nwindow.global = window;\n\nfunction onLongPress(element: any, callback: () => void) {\n  let timer: NodeJS.Timeout | -1 = -1\n\n  element.addEventListener('touchstart', () => {\n    timer = setTimeout(() => {\n      timer = -1\n      callback()\n    }, 3000)\n  })\n\n  function cancel() {\n    if (timer !== -1) {\n      clearTimeout(timer)\n    }\n  }\n\n  element.addEventListener('touchend', cancel)\n  element.addEventListener('touchmove', cancel)\n}\n\nconst ProviderApp = React.memo(({ children }: { children: JSX.Element }) => {\n  const providers: Array<[TProvider<any>, any]> = [\n    provider(Provider as any, { store }),\n    provider(LocalizationProvider as any, { dateAdapter: MomentUtils }),\n    provider(I18nextProvider as any, { i18n: i18n }),\n  ] as any\n  return <ProviderComposer providers={providers}>{children}</ProviderComposer>\n})\nconst isLaunch = { isLaunch: false }\nconst ProviderThen = React.memo(({ children }: { children: JSX.Element }) => {\n  const { themeMode, setIsMobile } = useSettings()\n  const isMobile = sdk.IsMobile.any() ? true : false\n  setIsMobile(isMobile)\n  if (isMobile) {\n    onLongPress(window.document.body, () => {\n      if (!isLaunch.isLaunch) {\n        isLaunch.isLaunch = true\n        const vConsole = new VConsole({})\n      }\n    })\n  }\n  const providers: Array<[TProvider<any>, any]> = [\n    provider(MuThemeProvider as any, { theme: getTheme(themeMode, isMobile) }),\n    provider(ThemeProvider as any, { theme: getTheme(themeMode, isMobile) }),\n    provider(PersistGate as any, { persistor, loading: null }),\n    provider(TimeoutCheckProvider as any),\n  ] as any\n  return <ProviderComposer providers={providers}>{children}</ProviderComposer>\n})\n\nconst root = createRoot(document.getElementById('root') as HTMLElement)\nroot.render(\n  <ProviderApp>\n    <ReactReduxFirebaseProvider {...firebaseProps}>\n      <ProviderThen>\n        <App />\n      </ProviderThen>\n    </ReactReduxFirebaseProvider>\n  </ProviderApp>,\n)\n\n// If you want to start measuring performance in your app, pass a function\n// to log results (for example: reportWebVitals(console.log))\n// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals\n\nif (process.env.NODE_ENV !== 'production') {\n  reportWebVitals(console.log)\n}\n"
  },
  {
    "path": "packages/web-earn/src/layouts/footer/index.tsx",
    "content": "import React from 'react'\nimport { FOOTER_LIST_MAP, MEDIA_LIST, TOAST_TIME } from '@loopring-web/common-resources'\nimport { useLocation } from 'react-router-dom'\nimport { Footer as FooterUI, Toast, ToastType } from '@loopring-web/component-lib'\nimport _ from 'lodash'\nimport { useTranslation } from 'react-i18next'\n\nconst linkListMap = _.cloneDeep(FOOTER_LIST_MAP)\nconst mediaList = _.cloneDeep(MEDIA_LIST)\nexport const Footer = () => {\n  const location = useLocation()\n  const { t } = useTranslation()\n  const isLandingPage = location.pathname === '/' || location.pathname === '/wallet'\n  const [showBeta, setShowBeta] = React.useState(\n    process.env?.REACT_APP_TEST_ENV == 'true' ? true : false,\n  )\n  // const isWallet = location.pathname === '/wallet'\n  React.useLayoutEffect(() => {\n    function updateSize() {\n      // setSize([1200, window.innerHeight - HeightConfig.headerHeight - HeightConfig.whiteHeight]);\n    }\n\n    window.addEventListener('resize', updateSize)\n    updateSize()\n    return () => window.removeEventListener('resize', updateSize)\n  }, [])\n  return (\n    <>\n      <Toast\n        alertText={t('errorBetaEnv', { ns: 'error' })}\n        open={showBeta}\n        autoHideDuration={TOAST_TIME}\n        onClose={() => {\n          setShowBeta(false)\n        }}\n        severity={ToastType.warning}\n      />\n      <FooterUI\n        isBeta={process.env?.REACT_APP_TEST_ENV == 'true'}\n        isLandingPage={isLandingPage}\n        linkListMap={linkListMap}\n        mediaList={mediaList}\n      />\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/web-earn/src/layouts/header/hook.tsx",
    "content": "import React, { useMemo } from 'react'\n\nimport {\n  ButtonComponentsMap,\n  fnType,\n  headerMenuLandingData,\n  MapChainId,\n  Profile,\n  ProfileIndex,\n  SagaStatus,\n  SPECIAL_ACTIVATION_NETWORKS,\n} from '@loopring-web/common-resources'\n\nimport {\n  accountReducer,\n  useAccount,\n  store,\n  useNotify,\n  accountStaticCallBack,\n  btnClickMap,\n  useSelectNetwork,\n  unlockAccount,\n  useUpdateAccount,\n  LoopringAPI,\n  isCoinbaseSmartWallet,\n} from '@loopring-web/core'\n\nimport { AccountStep, useOpenModals, useSettings, useToggle } from '@loopring-web/component-lib'\nimport { myLog } from '@loopring-web/common-resources'\n\nimport _ from 'lodash'\nimport { earnHeaderToolBarData, earnHeaderToolBarDataMobile, headerMenuDataEarnMap } from '../../constant/router'\nimport { useAppKit } from '@reown/appkit/react'\nimport { useCoinbaseSmartWalletPersist } from '@loopring-web/core/src/stores/localStore/coinbaseSmartWalletPersist'\nimport { toBig } from '@loopring-web/loopring-sdk'\n\nexport const useHeader = () => {\n  const accountTotal = useAccount()\n  const { defaultNetwork, isMobile } = useSettings()\n  const { account, setShouldShow, status: accountStatus } = accountTotal\n  const { setShowAccount } = useOpenModals()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const profile = ProfileIndex[network]\n  const modal = useAppKit()\n\n  const _btnClickMap = Object.assign(_.cloneDeep(btnClickMap), {\n    [fnType.NO_ACCOUNT]: [\n      function () {\n        modal.open()\n      },\n    ],\n    [fnType.DEPOSITING]: [\n      function () {\n        modal.open()\n      },\n    ],\n    [fnType.NOT_ACTIVE]: [\n      function () {\n        modal.open()\n      },\n    ],\n    [fnType.ACTIVATED]: [\n      function () {\n        modal.open()\n      },\n    ],\n\n    [fnType.LOCKED]: [\n      function () {\n        modal.open()\n      },\n    ],\n  })\n\n  const onWalletBtnConnect = React.useCallback(async () => {\n    myLog(`onWalletBtnConnect click: ${account.readyState}`)\n    accountStaticCallBack(_btnClickMap, [])\n  }, [account, setShouldShow, _btnClickMap])\n\n  const { NetWorkItems } = useSelectNetwork({ className: 'header' })\n  const { goUpdateAccount } = useUpdateAccount() \n  \n  const headerToolBarData = React.useMemo(() => {\n    const toolBarData = isMobile ? earnHeaderToolBarDataMobile : earnHeaderToolBarData\n    return [SagaStatus.UNSET, SagaStatus.DONE].includes(accountStatus)\n      ? {\n          ...toolBarData,\n          [ButtonComponentsMap.WalletConnect]: {\n            ...toolBarData[ButtonComponentsMap.WalletConnect],\n            handleClick: onWalletBtnConnect,\n            handleClickUnlock: async () => {              \n\n              unlockAccount()\n            },\n            NetWorkItems,\n            accountState: { account },\n            handleClickSignIn: async () => {\n              if (SPECIAL_ACTIVATION_NETWORKS.includes(defaultNetwork)) {\n                setShowAccount({\n                  isShow: true,\n                  step: AccountStep.UpdateAccount_Approve_WaitForAuth,\n                })\n                const { account } = store.getState()\n                const feeInfo = await LoopringAPI?.globalAPI?.getActiveFeeInfo({\n                  accountId: account._accountIdNotActive,\n                })\n                const { userBalances } = await LoopringAPI?.globalAPI?.getUserBalanceForFee({\n                  accountId: account._accountIdNotActive!,\n                })\n                const found = Object.keys(feeInfo.fees).find((key) => {\n                  const fee = feeInfo.fees[key].fee\n                  const foundBalance = userBalances[feeInfo.fees[key].tokenId]\n                  return (foundBalance && toBig(foundBalance.total).gte(fee)) || toBig(fee).eq('0')\n                })\n                await goUpdateAccount({\n                  isFirstTime: true,\n                  isReset: false,\n                  // @ts-ignore\n                  feeInfo: {\n                    token: feeInfo.fees[found!].fee,\n                    belong: found!,\n                    fee: feeInfo.fees[found!].fee,\n                    feeRaw: feeInfo.fees[found!].fee,\n                  },\n                })\n\n              } else {\n                setShowAccount({ isShow: true, step: AccountStep.CheckingActive })\n              }\n            },\n          },\n          [ButtonComponentsMap.ProfileMenu]: {\n            ...toolBarData[ButtonComponentsMap.ProfileMenu],\n            subMenu: profile.map((item: string) => Profile[item]),\n            readyState: account.readyState,\n          },\n        }\n      : toolBarData\n  }, [accountStatus, account?.readyState, account, isMobile])\n  \n  const { notifyMap } = useNotify()\n  const { toggle: {\n    taikoFarming\n  } } = useToggle()\n  // const taikoFarming={enable: true}\n\n  return {\n    headerToolBarData,\n    headerMenuData: headerMenuDataEarnMap[network].filter(data => {\n      return data.label.id === 'taikoFarming' \n        ? taikoFarming.enable\n        : true\n    }),\n    headerMenuLandingData,\n    account,\n    notifyMap,\n  }\n}\n"
  },
  {
    "path": "packages/web-earn/src/layouts/header/index.tsx",
    "content": "import {\n  ButtonComponentsMap,\n  CloseIcon,\n  headerRoot,\n  hexToRGB,\n} from '@loopring-web/common-resources'\n\nimport { Box, IconButton, Toolbar, Typography } from '@mui/material'\n\nimport { useHeader } from './hook'\nimport { confirmation, useSystem, useAccount, useTargetRedPackets } from '@loopring-web/core'\nimport { withTranslation } from 'react-i18next'\n\nimport {\n  BottomRule,\n  Header as HeaderUI,\n  HideOnScroll,\n  RedPacketViewStep,\n  useOpenModals,\n  useSettings,\n} from '@loopring-web/component-lib'\nimport { withRouter, useLocation } from 'react-router-dom'\nimport { RouteComponentProps } from 'react-router'\nimport React from 'react'\n\nconst Header = withTranslation('common')(\n  withRouter(\n    ({\n      t,\n      location,\n      isHideOnScroll = false,\n      isLandPage = false,\n      isWrap = false,\n      application = 'webapp',\n      ...rest\n    }: any & RouteComponentProps) => {\n      const { headerToolBarData, headerMenuData, notifyMap, headerMenuLandingData } = useHeader()\n      const { isMobile } = useSettings()\n      const { pathname } = useLocation()\n      const { confirmWrapper } = confirmation.useConfirmation()\n      const { allowTrade, chainId } = useSystem()\n      const { account } = useAccount()\n      const [view, setView] = React.useState(false)\n      const { redPackets, setShowRedPacketsPopup } = useTargetRedPackets()\n      const popUpRedpackets = redPackets\n        ? redPackets.filter((redpacket) => (redpacket as any).notifyType === 'NOTIFY_WINDOW')\n        : []\n      const showExclusiveRedpacket = popUpRedpackets.length > 0\n      const exclusiveRedpacketCount = popUpRedpackets.length\n      const { setShowRedPacket } = useOpenModals()\n      const onClickExclusiveredPacket = () => {\n        if (exclusiveRedpacketCount > 1) {\n          setShowRedPacketsPopup(true)\n        } else {\n          setShowRedPacket({\n            isShow: true,\n            info: {\n              ...popUpRedpackets[0],\n            },\n            step: RedPacketViewStep.OpenPanel,\n          })\n        }\n      }\n\n      return (\n        <>\n          {isHideOnScroll ? (\n            <HideOnScroll window={undefined}>\n              <HeaderUI\n                account={account}\n                isWrap={isLandPage || isWrap}\n                chainId={chainId}\n                {...rest}\n                isLandPage={isLandPage}\n                isMobile={isMobile}\n                allowTrade={allowTrade}\n                headerMenuData={\n                  /(guardian)|(depositto)/gi.test(pathname) ? headerMenuLandingData : headerMenuData\n                }\n                toolBarMap={ButtonComponentsMap}\n                headerToolBarData={\n                  isLandPage\n                    ? { buttonComponent: ButtonComponentsMap.ColorSwitch, label: 'labelColors' }\n                    : headerToolBarData\n                }\n                notification={notifyMap}\n                selected={location.pathname === '/' ? headerRoot : location.pathname}\n                onClickExclusiveredPacket={onClickExclusiveredPacket}\n                showExclusiveRedpacket={showExclusiveRedpacket}\n                exclusiveRedpacketCount={exclusiveRedpacketCount}\n                application={'web-earn'}\n              />\n            </HideOnScroll>\n          ) : (\n            <HeaderUI\n              {...rest}\n              account={account}\n              allowTrade={allowTrade}\n              isMobile={isMobile}\n              chainId={chainId}\n              headerMenuData={\n                /(guardian)|(depositto)/gi.test(pathname) ? headerMenuLandingData : headerMenuData\n              }\n              toolBarMap={ButtonComponentsMap}\n              headerToolBarData={headerToolBarData}\n              notification={notifyMap}\n              selected={location.pathname === '/' ? headerRoot : location.pathname}\n              onClickExclusiveredPacket={onClickExclusiveredPacket}\n              showExclusiveRedpacket={showExclusiveRedpacket}\n              exclusiveRedpacketCount={exclusiveRedpacketCount}\n              transparent\n              application={'web-earn'}\n            />\n          )}\n          <Toolbar id='back-to-top-anchor' />\n          {/* <BottomRule isShow={!confirmation?.confirmed} */}\n          <BottomRule\n            isShow={false}\n            content={t('labelAgreeLoopringTxt')}\n            btnTxt={t('labelCookiesAgree')}\n            clickToConfirm={() => confirmWrapper()}\n          />\n\n          <Box\n            display={view ? 'flex' : 'none'}\n            alignItems={'center'}\n            justifyContent={'center'}\n            position={'fixed'}\n            top={58}\n            right={0}\n            left={0}\n            sx={{ background: hexToRGB('#FBA95C', '0.8') }}\n            width={'100%'}\n          >\n            <Typography color={'white'} padding={2}></Typography>\n            <IconButton\n              size={'large'}\n              aria-label={t('labelClose')}\n              color={'inherit'}\n              onClick={(event) => {\n                setView(false)\n              }}\n            >\n              <CloseIcon htmlColor={'white'} />\n            </IconButton>\n          </Box>\n        </>\n      )\n    },\n  ),\n)\n\nexport default Header\n"
  },
  {
    "path": "packages/web-earn/src/pages/AssetPage/AssetPanel/hook.ts",
    "content": "import React from 'react'\nimport {\n  fiatNumberDisplay,\n  LoopringAPI,\n  makeWalletLayer2,\n  makeWalletLayer2NoStatus,\n  networkById,\n  numberStringListSum,\n  store,\n  useAccount,\n  useBtnStatus,\n  useConfig,\n  useDefiMap,\n  useModalData,\n  useSystem,\n  useTokenMap,\n  useTokenPrices,\n  useWalletLayer2,\n  useWalletLayer2Socket,\n  volumeToCountAsBigNumber,\n} from '@loopring-web/core'\nimport {\n  AssetTitleProps,\n  TransactionTradeViews,\n  useOpenModals,\n  useSettings,\n} from '@loopring-web/component-lib'\nimport {\n  AssetsRawDataItem,\n  CurrencyToTag,\n  EmptyValueTag,\n  getValuePrecisionThousand,\n  globalSetup,\n  InvestAssetRouter,\n  PriceTag,\n  RecordTabIndex,\n  RouterPath,\n  SagaStatus,\n  TabOrderIndex,\n  TokenType,\n  TradeBtnStatus,\n  VaultKey,\n} from '@loopring-web/common-resources'\n\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { omitBy } from 'lodash'\nimport Decimal from 'decimal.js'\n\nimport _ from 'lodash'\nimport { parseRabbitConfig2 } from '@loopring-web/core/src/hooks/help/parseRabbitConfig'\n\nexport type AssetPanelProps<R = AssetsRawDataItem> = {\n  assetsRawData: R[]\n  hideL2Assets: any\n  onSend: any\n  onReceive: any\n  marketArray: any\n  hideInvestToken: any\n  allowTrade: any\n  setHideL2Assets: (value: boolean) => void\n  setHideLpToken: any\n  setHideSmallBalances: any\n  themeMode: any\n  getTokenRelatedMarketArray: any\n  hideSmallBalances: any\n  assetBtnStatus: TradeBtnStatus\n  totalAvailableInCurrency: string\n  totalFrozenInCurrency: string\n}\nexport const useGetAssets = (): AssetPanelProps & {\n  assetTitleProps: any\n  assetTitleMobileExtendProps: any\n} => {\n  // const [assetsMap, setAssetsMap] = React.useState<{ [key: string]: any }>({})\n  const [assetsRawData, setAssetsRawData] = React.useState<AssetsRawDataItem[]>([])\n  const [totalAsset, setTotalAsset] = React.useState<string>('0')\n  const { account } = useAccount()\n  const { allowTrade, forexMap, chainId } = useSystem()\n  const { status: tokenPriceStatus } = useTokenPrices()\n  const { btnStatus: assetBtnStatus, enableBtn } = useBtnStatus()\n  const {\n    setShowAccount,\n    setShowDeposit,\n    setShowWithdraw,\n    setShowBridge,\n    modals: { isShowAccount },\n  } = useOpenModals()\n  const { resetDepositData, resetWithdrawData } = useModalData()\n  const {\n    themeMode,\n    currency,\n    hideL2Assets,\n    hideInvestToken,\n    hideSmallBalances,\n    setHideLpToken,\n    setHideSmallBalances,\n    setHideL2Assets,\n  } = useSettings()\n  const { status: walletL2Status } = useWalletLayer2()\n\n  const { marketArray } = useTokenMap()\n  const { marketCoins: defiCoinArray } = useDefiMap()\n  const getAssetsRawData = () => {\n    const {\n      tokenPrices: { tokenPrices },\n      tokenMap: { tokenMap: tokenMapRaw },\n      amm: {\n        ammMap: { ammMap },\n      },\n    } = store.getState()\n    const tokenPriceList = tokenPrices\n      ? Object.entries(tokenPrices).map((o) => ({\n          token: o[0],\n          detail: o[1],\n        }))\n      : []\n    const { walletMap } = makeWalletLayer2NoStatus({ needFilterZero: false })\n    const tokenMap = omitBy(tokenMapRaw, (token) => token.isLpToken)\n    if (\n      tokenMap &&\n      !!Object.keys(tokenMap).length &&\n      !!Object.keys(walletMap ?? {}).length &&\n      !!tokenPriceList.length\n    ) {\n      let totalAssets = sdk.toBig(0)\n      let data: Array<any> = Object.keys(tokenMap ?? {}).reduce((pre, key, _index) => {\n        let item: any = undefined\n        const isDefi = [...(defiCoinArray ? defiCoinArray : [])].includes(key)\n        // tokenInfo\n        if (walletMap && walletMap[key]) {\n          let tokenInfo = {\n            token: key,\n            detail: walletMap[key],\n          }\n          let tokenValueDollar = sdk.toBig(0)\n          const withdrawAmount = volumeToCountAsBigNumber(\n            tokenInfo.token,\n            tokenInfo.detail?.detail?.pending?.withdraw ?? 0,\n          )\n          const depositAmount = volumeToCountAsBigNumber(\n            tokenInfo.token,\n            tokenInfo.detail?.detail?.pending?.deposit ?? 0,\n          )\n\n          const totalAmount = volumeToCountAsBigNumber(\n            tokenInfo.token,\n            tokenInfo.detail?.detail?.total ?? 0,\n          )\n            ?.plus(depositAmount || 0)\n            .plus(withdrawAmount || 0)\n          // ?.plus(depositAmount || 0)\n          // .plus(withdrawAmount || 0)\n          const price = tokenPrices?.[tokenInfo.token] || 0\n          if (totalAmount && price) {\n            tokenValueDollar = totalAmount?.times(price)\n          }\n          const isSmallBalance = tokenValueDollar.lt(1)\n          const lockedAmount = volumeToCountAsBigNumber(\n            tokenInfo.token,\n            tokenInfo.detail?.detail?.locked ?? 0,\n          )\n          const frozenAmount = lockedAmount?.plus(withdrawAmount || 0).plus(depositAmount || 0)\n          item = {\n            token: {\n              type: isDefi\n                ? TokenType.defi\n                : tokenInfo.token.split('-')[0] === 'LP'\n                ? TokenType.lp\n                : TokenType.single,\n              value: tokenInfo.token,\n            },\n            // amount: getThousandFormattedNumbers(volumeToCount(tokenInfo.token, tokenInfo.detail?.detail.total as string)) || EmptyValueTag,\n            amount: totalAmount?.toString() || EmptyValueTag,\n            // available: getThousandFormattedNumbers(Number(tokenInfo.detail?.count)) || EmptyValueTag,\n            available: Number(tokenInfo.detail?.count) || EmptyValueTag,\n            // locked: String(volumeToCountAsBigNumber(tokenInfo.token, tokenInfo.detail?.detail.locked)) || EmptyValueTag,\n            locked: frozenAmount?.toString() || EmptyValueTag,\n            smallBalance: isSmallBalance,\n            tokenValueDollar: tokenValueDollar.toString(),\n            name: tokenInfo.token,\n            withdrawAmount: withdrawAmount?.toString(),\n            depositAmount: depositAmount?.toString(),\n          }\n        } else {\n          item = {\n            token: {\n              type: isDefi\n                ? TokenType.defi\n                : key.split('-')[0] === 'LP'\n                ? TokenType.lp\n                : TokenType.single,\n              value: key,\n            },\n            amount: EmptyValueTag,\n            available: EmptyValueTag,\n            locked: 0,\n            smallBalance: true,\n            tokenValueDollar: 0,\n            name: key,\n            tokenValueYuan: 0,\n            withdrawAmount: 0,\n            depositAmount: 0,\n          }\n        }\n        if (item) {\n          const token = item.token.value\n          let precision = 0\n          if (token.split('-').length === 3 && ammMap) {\n            const rawList = token.split('-')\n            rawList.splice(0, 1, 'AMM')\n            const ammToken = rawList.join('-')\n            precision =\n              ammMap[ammToken]?.precisions?.amount ?? tokenMap[item.token.value]?.precision ?? 0\n          } else {\n            precision = tokenMap[item.token.value].precision\n          }\n          pre.push({\n            ...item,\n            precision: precision,\n          })\n          totalAssets = totalAssets.plus(\n            sdk.toBig(item.tokenValueDollar)\n            // .times(forexMap[currency] ?? 0),\n          )\n          // totalAssets = totalAssets.plus(sdk.toBig(item.tokenValueDollar).times(forexMap[currency] ?? 0))\n        }\n        pre?.sort((a, b) => {\n          const deltaDollar = b.tokenValueDollar - a.tokenValueDollar\n          const deltaAmount = sdk.toBig(b.amount).minus(a.amount).toNumber()\n          const deltaName = b.token.value < a.token.value ? 1 : -1\n          return deltaDollar !== 0 ? deltaDollar : deltaAmount !== 0 ? deltaAmount : deltaName\n        })\n        return pre\n      }, [] as Array<any>)\n      setAssetsRawData(data)\n      setTotalAsset(totalAssets.toString())\n    }\n  }\n  const startWorker = _.debounce(getAssetsRawData, globalSetup.wait)\n\n  React.useEffect(() => {\n    if (\n      tokenPriceStatus === SagaStatus.UNSET &&\n      walletL2Status === SagaStatus.UNSET &&\n      assetsRawData.length &&\n      assetBtnStatus !== TradeBtnStatus.AVAILABLE\n    ) {\n      enableBtn()\n    }\n  }, [walletL2Status, assetsRawData, tokenPriceStatus, assetBtnStatus])\n  React.useEffect(() => {\n    setTotalAsset('0')\n  }, [account.accAddress, chainId])\n  const walletLayer2Callback = React.useCallback(() => {\n    startWorker()\n  }, [])\n  useWalletLayer2Socket({ walletLayer2Callback })\n  const getTokenRelatedMarketArray = React.useCallback((token: string) => {\n    const { marketArray, marketMap } = store.getState().tokenMap\n    if (!marketArray) return []\n    return marketArray.filter((market) => {\n      const marketInfo = marketMap?.[market]\n      if (!marketInfo?.enabled) return false\n      const [coinA, coinB] = market.split('-')\n      return token === coinA || token === coinB\n    })\n  }, [])\n\n  const onReceive = React.useCallback(\n    (token?: any) => {\n      setShowAccount({\n        isShow: false,\n        info: { lastFailed: undefined },\n      })\n      if (isShowAccount?.info?.symbol) {\n        resetDepositData()\n      }\n      setShowDeposit({\n        isShow: true,\n        symbol: token,\n      })\n    },\n    [setShowAccount],\n  )\n  const onSend = React.useCallback(\n    (token?: any) => {\n      setShowAccount({\n        isShow: false,\n        info: { lastFailed: undefined },\n      })\n      if (isShowAccount?.info?.symbol) {\n        resetWithdrawData()\n      }\n      setShowWithdraw({\n        isShow: true,\n        symbol: token,\n        info: { isToMyself: true },\n      })\n    },\n    [setShowAccount],\n  )\n\n  const onClickBridge = React.useCallback(\n    (token?: any) => {\n      setShowAccount({\n        isShow: false,\n        info: { lastFailed: undefined },\n      });\n      setShowBridge({\n        isShow: true,\n        info: undefined\n      });\n    },\n    [setShowAccount, setShowBridge],\n  );\n  const { tokenPrices } = useTokenPrices()\n  const {defaultNetwork} = useSettings()\n  const {fastWithdrawConfig} = useConfig()\n  const {idIndex}=useTokenMap()\n  const fromNetwork = networkById(defaultNetwork)\n  const parsedConfig = fromNetwork \n    ? parseRabbitConfig2(fastWithdrawConfig, fromNetwork, idIndex)\n    : undefined\n  const hasToOtherNetwork = parsedConfig?.toOtherNetworks?.find(item => item.network !== fromNetwork)\n  const isTaiko = [sdk.ChainId.TAIKO, sdk.ChainId.TAIKOHEKLA].includes(defaultNetwork )\n  \n  const assetTitleProps: AssetTitleProps = {\n    setHideL2Assets,\n    assetInfo: {\n      totalAsset,\n      priceTag: PriceTag[CurrencyToTag[currency]],\n    },\n    accountId: account.accountId,\n    hideL2Assets,\n    onShowReceive: onReceive,\n    onShowSend: onSend,\n    onClickBridge,\n    showBridgeBtn: isTaiko && hasToOtherNetwork,\n  } as any\n  const assetTitleMobileExtendProps = {\n    btnShowNFTDepositStatus: TradeBtnStatus.AVAILABLE,\n    btnShowNFTMINTStatus: TradeBtnStatus.AVAILABLE,\n  }\n  \n  \n  return {\n    assetTitleProps,\n    assetTitleMobileExtendProps,\n    assetsRawData: assetsRawData.map((asset) => {\n      return isTaiko && asset.name === 'TAIKO'\n        ? { ...asset, hideDepositButton: true }\n        : isTaiko && asset.name === 'LRTAIKO'\n        ? { ...asset, hideDepositButton: true, hideWithdrawButton: true }\n        : asset\n    }),\n    assetBtnStatus,\n    hideL2Assets,\n    onSend,\n    onReceive,\n    marketArray,\n    hideInvestToken,\n    allowTrade,\n    setHideL2Assets,\n    setHideLpToken,\n    setHideSmallBalances,\n    themeMode,\n    getTokenRelatedMarketArray,\n    hideSmallBalances,\n    totalAvailableInCurrency:\n      forexMap[currency] &&\n      fiatNumberDisplay(\n        new Decimal(forexMap[currency])\n          .mul(\n            numberStringListSum(\n              assetsRawData.map((asset) => {\n                try {\n                  return new Decimal(asset.available.toString())\n                    .mul(tokenPrices[asset.name])\n                    .toString()\n                } catch {\n                  return '0'\n                }\n              }),\n            ),\n          )\n          .toString(),\n        currency,\n      ),\n    totalFrozenInCurrency:\n      forexMap[currency] &&\n      fiatNumberDisplay(\n        new Decimal(forexMap[currency])\n          .mul(\n            numberStringListSum(\n              assetsRawData.map((asset) => {\n                try {\n                  return new Decimal(asset.locked).mul(tokenPrices[asset.name]).toString()\n                } catch {\n                  return '0'\n                }\n              }),\n            ),\n          )\n          .toString(),\n        currency,\n      ),\n  }\n}\nexport const useAssetAction = () => {\n  const [tokenLockDetail, setTokenLockDetail] = React.useState<\n    | undefined\n    | {\n        list: any[]\n        row: any\n      }\n  >(undefined)\n  const onTokenLockHold = async (_item) => {\n    setTokenLockDetail(undefined)\n    const {\n      account,\n      tokenMap: { tokenMap },\n    } = store.getState()\n    if (LoopringAPI.userAPI && account.accountId) {\n      const response = await LoopringAPI.userAPI.getUserLockSummary(\n        {\n          accountId: account.accountId,\n          tokenId: tokenMap[_item.name].tokenId,\n          // @ts-ignore\n          lockTags: [\n            sdk.LOCK_TYPE.DUAL_CURRENCY,\n            sdk.LOCK_TYPE.DUAL_BASE,\n            sdk.LOCK_TYPE.BTRADE,\n            sdk.LOCK_TYPE.L2STAKING,\n            sdk.LOCK_TYPE.STOP_LIMIT,\n            sdk.LOCK_TYPE.VAULT_COLLATERAL,\n            sdk.LOCK_TYPE.TAIKO_FARMING\n          ].join(','),\n        } as any,\n        account.apiKey,\n      )\n\n      if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n      } else {\n        setTokenLockDetail(() => {\n\n          // merge l2Staking and taikoFarming to single record\n          const isL2StakingTaiko = (record) => record.lockTag === sdk.LOCK_TYPE.L2STAKING && tokenMap[_item.name].symbol === 'TAIKO'\n          const isTaikoFarming = (record) => record.lockTag === sdk.LOCK_TYPE.TAIKO_FARMING\n          const l2Staking = response.lockRecord.find(isL2StakingTaiko)\n          const taikoFarming = response.lockRecord.find(isTaikoFarming)\n          const taikoFarmingMerge = taikoFarming ? {\n            ...taikoFarming,\n            amount: sdk.toBig(taikoFarming.amount).plus(l2Staking ? l2Staking.amount : '0').toString()\n          } : l2Staking ? {\n            ...l2Staking,\n            lockTag: sdk.LOCK_TYPE.TAIKO_FARMING\n          } : undefined\n          const lockRecord = response.lockRecord\n            .filter((record) => !isL2StakingTaiko(record) && !isTaikoFarming(record))\n            .concat(taikoFarmingMerge ? [taikoFarmingMerge] : [])\n\n          const sum: { key: string; value: string; link: string }[] = lockRecord.reduce(\n            // @ts-ignore\n            (prev, record) => {\n              const amount = sdk\n                .toBig(record.amount)\n                .div('1e' + tokenMap[_item.name].decimals)\n                .toString()\n              prev[0] = {\n                ...prev[0],\n                value: sdk.toBig(prev[0].value?.replaceAll(sdk.SEP, '')).minus(amount).toString(),\n              }\n              let link = ''\n              switch (record.lockTag) {\n                case sdk.LOCK_TYPE.DUAL_CURRENCY:\n                  link = `/#${RouterPath.investBalance}/${InvestAssetRouter.DUAL}`\n                  break\n                case sdk.LOCK_TYPE.DUAL_BASE:\n                  link = `/#${RouterPath.investBalance}/${InvestAssetRouter.DUAL}`\n                  break\n                case sdk.LOCK_TYPE.L2STAKING: {\n                  if (tokenMap[_item.name].symbol === 'TAIKO') {\n                    link = `/#/taiko-farming`\n                  } else {\n                    link = `/#${RouterPath.investBalance}/${InvestAssetRouter.STAKELRC}`\n                  }\n                  break\n                }\n                case sdk.LOCK_TYPE.BTRADE:\n                  link = `/#${RouterPath.l2records}/${RecordTabIndex.BtradeSwapRecords}`\n                  break\n                case sdk.LOCK_TYPE.STOP_LIMIT:\n                  link = `/#${RouterPath.l2records}/${RecordTabIndex.Orders}/${TabOrderIndex.orderOpenTable}`\n                  break\n                case sdk.LOCK_TYPE.VAULT_COLLATERAL:\n                  link = `/#${RouterPath.vault}/${VaultKey.VAULT_DASHBOARD}`\n                  break\n                case sdk.LOCK_TYPE.TAIKO_FARMING:\n                  link = `/#/taiko-farming`\n                  break\n              }\n              const key = record.lockTag === 'L2STAKING' && _item.name === 'TAIKO'\n                ? 'labelL2TaikoFarming'\n                : `label${record.lockTag}`\n              prev.push({\n                key: key,\n                value: getValuePrecisionThousand(\n                  amount,\n                  tokenMap[_item.name].precision,\n                  tokenMap[_item.name].precision,\n                  undefined,\n                ),\n                link,\n              })\n              return prev\n            },\n            [\n              {\n                key: `labelMarketOrderUnfilled`,\n                value: sdk\n                  .toBig(_item.locked ?? '0')\n                  .minus(_item?.withdrawAmount ?? 0)\n                  .minus(_item?.depositAmount ?? 0)\n                  .toString(),\n                link: `/#${RouterPath.l2records}/${RecordTabIndex.Orders}/${TabOrderIndex.orderOpenTable}`,\n              },\n              ...(sdk.toBig(_item?.depositAmount ?? 0).gt(0)\n                ? [\n                    {\n                      key: `labelDepositPending`,\n                      value: sdk.toBig(_item?.depositAmount ?? '0').toString(),\n                      link: `/#${RouterPath.l2records}/${RecordTabIndex.Transactions}/?types=${TransactionTradeViews.receive}&searchValue=${_item.name}`,\n                    },\n                  ]\n                : []),\n              ...(sdk.toBig(_item?.withdrawAmount ?? 0).gt(0)\n                ? [\n                    {\n                      key: `labelWithDrawPending`,\n                      value: sdk.toBig(_item?.withdrawAmount ?? '0').toString(),\n                      link: `/#${RouterPath.l2records}/${RecordTabIndex.Transactions}/?types=${TransactionTradeViews.send}&searchValue=${_item.name}`,\n                    },\n                  ]\n                : []),\n            ] as { key: string; value: string; link: string }[],\n          )\n          if (_item.locked && sdk.toBig(sum[0].value).gt(0)) {\n            sum[0] = {\n              ...sum[0],\n              value: getValuePrecisionThousand(\n                sum[0].value,\n                tokenMap[_item.name].precision,\n                tokenMap[_item.name].precision,\n                undefined,\n              ),\n            }\n          } else {\n            sum.shift()\n          }\n\n          return {\n            list: sum,\n            row: _item,\n          }\n        })\n      }\n    }\n  }\n  return {\n    tokenLockDetail,\n    onTokenLockHold,\n  }\n}\n"
  },
  {
    "path": "packages/web-earn/src/pages/AssetPage/AssetPanel/index.tsx",
    "content": "import { WithTranslation, withTranslation } from 'react-i18next'\nimport { Tab, Typography, Box } from '@mui/material'\nimport {\n  AssetsTable,\n  AssetTitle,\n  AssetTitleProps,\n  Tabs,\n  useSettings,\n} from '@loopring-web/component-lib'\n\nimport { numberStringListSum, StylePaper, useSystem, useTokenMap } from '@loopring-web/core'\nimport { AssetPanelProps, useAssetAction } from './hook'\nimport React from 'react'\nimport { useHistory, useRouteMatch } from 'react-router-dom'\nimport MyLiquidity from '../../InvestPage/MyLiquidityPanel'\nimport { MapChainId, SoursURL, TradeBtnStatus } from '@loopring-web/common-resources'\nimport { AssetL2TabEarnIndex, AssetTabIndex } from '../../../constant/router'\nimport { containerColors } from 'pages/InvestPage'\nimport { RowEarnConfig } from 'constant/setting'\nimport { useTheme } from '@emotion/react'\nimport Decimal from 'decimal.js'\n\nexport const AssetPanel = withTranslation('common')(\n  ({\n    t,\n    assetTitleProps,\n    assetPanelProps: {\n      assetsRawData,\n      getTokenRelatedMarketArray,\n      onSend,\n      assetBtnStatus,\n      onReceive,\n      hideInvestToken,\n      hideSmallBalances,\n      allowTrade,\n      setHideLpToken,\n      setHideSmallBalances,\n      totalAvailableInCurrency,\n      totalFrozenInCurrency,\n      // onTokenLockHold,\n      // tokenLockDetail,\n    },\n    showRedpacketReddot,\n    ...rest\n  }: {\n    showRedpacketReddot: boolean\n    assetTitleProps: AssetTitleProps\n    assetPanelProps: AssetPanelProps\n  } & WithTranslation) => {\n    const { disableWithdrawList } = useTokenMap()\n    const { forexMap } = useSystem()\n    const { isMobile, defaultNetwork } = useSettings()\n    const match: any = useRouteMatch('/l2assets/:assets?/:item?')\n    const [currentTab, setCurrentTab] = React.useState<AssetTabIndex>(AssetTabIndex.Tokens)\n    const history = useHistory()\n    const theme = useTheme()\n    const { onTokenLockHold, tokenLockDetail } = useAssetAction()\n\n    const handleTabChange = (value: AssetTabIndex) => {\n      if (AssetL2TabEarnIndex[MapChainId[defaultNetwork]]?.includes(value)) {\n        switch (value) {\n          case AssetTabIndex.DefiPortfolio:\n            history.replace('/l2assets/assets/Invests')\n            setCurrentTab(AssetTabIndex.DefiPortfolio)\n            break\n          case AssetTabIndex.Tokens:\n          default:\n            history.replace('/l2assets/assets/Tokens')\n            setCurrentTab(AssetTabIndex.Tokens)\n            break\n        }\n      } else {\n        history.replace('/l2assets/assets/Tokens')\n        setCurrentTab(AssetTabIndex.Tokens)\n      }\n    }\n    React.useEffect(() => {\n      if (match.params.item === 'Invests') {\n        setCurrentTab(AssetTabIndex.DefiPortfolio)\n      }\n    }, [])\n    const hideAssets = assetTitleProps.hideL2Assets\n\n    return (\n      <Box bgcolor={'var(--color-box)'} borderRadius={'24px'} px={3.5} py={5}>\n        {!isMobile && (\n          <Box\n            sx={{\n              background: 'transparent',\n              paddingY: 5,\n              position: 'relative',\n            }}\n          >\n            <Box\n              sx={{\n                position: 'absolute',\n                zIndex: -1,\n                top: 'calc(var(--header-height) * -1)',\n                bottom: 0,\n                left: 0,\n                right: 0,\n                backgroundImage:\n                  theme.mode === 'light'\n                    ? `url(${SoursURL + 'images/asset_page_bg_light.png'})`\n                    : `url(${SoursURL + 'images/asset_page_bg_dark.png'})`,\n                backgroundPosition: 'center',\n                backgroundSize: 'cover',\n                backgroundRepeat: 'no-repeat',\n              }}\n            />\n            <AssetTitle\n              {...{\n                t,\n                ...rest,\n                ...assetTitleProps,\n                assetBtnStatus,\n                forexMap,\n                isWebEarn: true,\n              }}\n            />\n          </Box>\n        )}\n        <Box\n          sx={{\n            paddingTop: 2.5,\n            borderBottom: '1px solid var(--color-border)',\n          }}\n        >\n          <Tabs\n            sx={{ ml: -2 }}\n            value={currentTab}\n            onChange={(_event, value) => handleTabChange(value)}\n            aria-label='l2-history-tabs'\n            variant='scrollable'\n          >\n            {AssetL2TabEarnIndex[MapChainId[defaultNetwork]]?.map((item: string) => {\n              return <Tab key={item.toString()} label={t(`labelEarnAsset${item}`)} value={item} />\n            })}\n          </Tabs>\n        </Box>\n\n        <Box\n          sx={{\n            // overflowY: 'scroll',\n            // height: isMobile ? '300px' : '450px',\n          }}\n        >\n          {currentTab === AssetTabIndex.Tokens && (\n            <Box>\n              <Box marginBottom={3} marginTop={2} display={'flex'} justifyContent={'start'}>\n                <Typography marginRight={4} color={'var(--color-text-secondary)'}>\n                  {t('labelLocked')}:{' '}\n                  {hideAssets ? (\n                    <>\n                      <>&#10033;&#10033;&#10033;&#10033;&#10033;&#10033;</>\n                    </>\n                  ) : (\n                    totalFrozenInCurrency\n                  )}\n                </Typography>\n                <Typography color={'var(--color-text-secondary)'}>\n                  {t('labelAvailable')}{' '}\n                  {hideAssets ? (\n                    <>&#10033;&#10033;&#10033;&#10033;&#10033;&#10033;</>\n                  ) : (\n                    totalAvailableInCurrency\n                  )}\n                </Typography>\n              </Box>\n              <Box>\n                <AssetsTable\n                  {...{\n                    rawData: assetsRawData,\n                    disableWithdrawList,\n                    showFilter: true,\n                    allowTrade,\n                    onSend,\n                    onTokenLockHold: onTokenLockHold as any,\n                    tokenLockDetail,\n                    onReceive,\n                    isLoading: assetBtnStatus === TradeBtnStatus.LOADING,\n                    getMarketArrayListCallback: getTokenRelatedMarketArray,\n                    hideInvestToken,\n                    forexMap: forexMap as any,\n                    hideSmallBalances,\n                    setHideLpToken,\n                    setHideSmallBalances,\n                    hideAssets,\n                    isWebEarn: true,\n                    rowConfig: RowEarnConfig,\n                    ...rest,\n                  }}\n                />\n              </Box>\n            </Box>\n          )}\n\n          {currentTab === AssetTabIndex.DefiPortfolio && (\n            <MyLiquidity hideAssets={hideAssets} isPortfolio />\n          )}\n        </Box>\n      </Box>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/web-earn/src/pages/AssetPage/HistoryPanel/hooks.ts",
    "content": "import React from 'react'\nimport {\n  LoopringAPI,\n  makeDualOrderedItem,\n  store,\n  tradeItemToTableDataItem,\n  useAccount,\n  useDefiMap,\n  useDualMap,\n  useSystem,\n  useTokenMap,\n  useWalletLayer2,\n  volumeToCount,\n  volumeToCountAsBigNumber,\n  useVaultMap,\n  numberFormat,\n  numberStringListSum,\n  fiatNumberDisplay,\n  useTokenPrices,\n} from '@loopring-web/core'\nimport {\n  AccountStep,\n  AmmSideTypes,\n  BtradeSwapsType,\n  OrderHistoryRawDataItem,\n  OrderHistoryTableDetailItem,\n  RawDataAmmItem,\n  RawDataBtradeSwapsItem,\n  RawDataDualAssetItem,\n  RawDataDualTxsItem,\n  RawDataTradeItem,\n  RawDataTransactionItem,\n  RawDataVaultTxItem,\n  ToastType,\n  TransactionStatus,\n  useOpenModals,\n  useSettings,\n  VaultRecordType,\n} from '@loopring-web/component-lib'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { DUAL_TYPE, GetOrdersRequest, Side } from '@loopring-web/loopring-sdk'\nimport {\n  AccountStatus,\n  BTRDE_PRE,\n  DEFI_CONFIG,\n  getValuePrecisionThousand,\n  LEVERAGE_ETH_CONFIG,\n  MapChainId,\n  SDK_ERROR_MAP_TO_UI,\n  TradeStatus,\n  TradeTypes,\n  EmptyValueTag,\n  DirectionTag,\n  PriceTag,\n  CurrencyToTag,\n  mapSpecialTokenName,\n} from '@loopring-web/common-resources'\nimport { TFunction, useTranslation } from 'react-i18next'\nimport BigNumber from 'bignumber.js'\nimport { useLocation } from 'react-router-dom'\nimport { isEmpty } from 'lodash'\nimport { number } from 'prop-types'\nimport { utils } from 'ethers'\nimport Decimal from 'decimal.js'\n\nexport type TxsFilterProps = {\n  // accountId: number;\n  tokenSymbol?: string\n  start?: number\n  end?: number\n  offset?: number\n  limit?: number\n  types?: sdk.UserTxTypes[] | string\n}\n\nenum TxTypeAMM {\n  Add = 'join_pool',\n  Remove = 'exit_pool',\n}\n\nexport function useGetTxs(setToastOpen: (state: any) => void) {\n  const {\n    account: { accountId, apiKey },\n  } = useAccount()\n  const { search } = useLocation()\n  const searchParams = new URLSearchParams(search)\n  const { tokenMap } = store.getState().tokenMap\n  const { t } = useTranslation(['error'])\n  const [txs, setTxs] = React.useState<RawDataTransactionItem[]>([])\n  const [txsTotal, setTxsTotal] = React.useState(0)\n  const [showLoading, setShowLoading] = React.useState(false)\n\n  const getTxnStatus = (status: string) =>\n    status === ''\n      ? TransactionStatus.processing\n      : status === 'processed'\n      ? TransactionStatus.processed\n      : status === 'processing'\n      ? TransactionStatus.processing\n      : status === 'received'\n      ? TransactionStatus.received\n      : TransactionStatus.failed\n\n  const getUserTxnList = React.useCallback(\n    async ({ tokenSymbol, start, end, limit, offset, types }: TxsFilterProps) => {\n      if (LoopringAPI && LoopringAPI.userAPI && accountId && apiKey) {\n        setShowLoading(true)\n        const response = await LoopringAPI.userAPI.getUserTxs(\n          {\n            accountId,\n            limit,\n            tokenSymbol,\n            start,\n            end,\n            offset,\n            types,\n          },\n          apiKey,\n        )\n        if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n          const errorItem = SDK_ERROR_MAP_TO_UI[(response as sdk.RESULT_INFO)?.code ?? 700001]\n          setToastOpen({\n            open: true,\n            type: ToastType.error,\n            content:\n              'error : ' + errorItem\n                ? t(errorItem.messageKey)\n                : (response as sdk.RESULT_INFO).message,\n          })\n        } else {\n          const formattedList: RawDataTransactionItem[] = response.userTxs.map((order) => {\n            const feePrecision = tokenMap ? tokenMap[order.feeTokenSymbol]?.precision : undefined\n            return {\n              ...order,\n              side: order.txType as any,\n              amount: {\n                unit: order.symbol || '',\n                value: Number(volumeToCount(order.symbol, order.amount)),\n              },\n              fee: {\n                unit: order.feeTokenSymbol || '',\n                value: Number(volumeToCountAsBigNumber(order.feeTokenSymbol, order.feeAmount || 0)),\n              },\n              memo: order.memo || '',\n              time: order.timestamp,\n              txnHash: order.hash,\n              status: getTxnStatus(order.status),\n              feePrecision: feePrecision,\n            } as RawDataTransactionItem\n          })\n          setTxs(formattedList)\n          setTxsTotal(response.totalNum)\n          setShowLoading(false)\n        }\n      }\n    },\n    [accountId, apiKey, setToastOpen, t, tokenMap],\n  )\n\n  return {\n    txs,\n    txsTotal,\n    searchValue: searchParams?.get('searchValue'),\n    showLoading,\n    getUserTxnList,\n  }\n}\n\nexport function useGetTrades(setToastOpen: (state: any) => void) {\n  const [userTrades, setUserTrades] = React.useState<RawDataTradeItem[]>([])\n  const [userTradesTotal, setUserTradesTotal] = React.useState(0)\n  const [showLoading, setShowLoading] = React.useState(true)\n  const [page, setPage] = React.useState(1)\n  const {\n    account: { accountId, apiKey },\n  } = useAccount()\n\n  const tokenMap = store.getState().tokenMap.tokenMap\n  const { t } = useTranslation(['error'])\n\n  const getUserTradeList = React.useCallback(\n    async ({\n      market,\n      orderHash,\n      page = 1,\n      pageSize,\n      fromId,\n      fillTypes,\n    }: {\n      market?: string\n      page?: number\n      total?: number\n      pageSize: number\n      // offset: (page - 1) * pageSize,\n      // limit: pageSize,\n      fromId?: any\n      orderHash?: any\n      fillTypes?: any\n    }) => {\n      if (LoopringAPI && LoopringAPI.userAPI && accountId && apiKey && tokenMap) {\n        setShowLoading(true)\n        setPage(page)\n        const response = await LoopringAPI.userAPI.getUserTrades(\n          {\n            accountId,\n            market,\n            orderHash,\n            offset: (page - 1) * pageSize,\n            limit: pageSize,\n            fromId,\n            fillTypes,\n          },\n          apiKey,\n        )\n        if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n          const errorItem = SDK_ERROR_MAP_TO_UI[(response as sdk.RESULT_INFO)?.code ?? 700001]\n          setToastOpen({\n            open: true,\n            type: ToastType.error,\n            content:\n              'error : ' + errorItem\n                ? t(errorItem.messageKey)\n                : (response as sdk.RESULT_INFO).message,\n          })\n        } else {\n          setUserTrades(\n            response.userTrades.map((o) => {\n              return tradeItemToTableDataItem(o) as RawDataTradeItem\n            }),\n          )\n          setUserTradesTotal(response.totalNum)\n        }\n        setShowLoading(false)\n      }\n    },\n    [accountId, apiKey, setToastOpen, t, tokenMap],\n  )\n\n  return {\n    userTrades,\n    userTradesTotal,\n    getUserTradeList,\n    showLoading,\n    page,\n  }\n}\n\nexport function useGetAmmRecord(setToastOpen: (props: any) => void) {\n  const [ammRecordList, setAmmRecordList] = React.useState<RawDataAmmItem[]>([])\n  const { t } = useTranslation(['error'])\n  const [ammRecordTotal, setAmmRecordTotal] = React.useState(0)\n  const [showLoading, setShowLoading] = React.useState(true)\n  const { accountId, apiKey } = store.getState().account\n  const { tokenMap } = useTokenMap()\n\n  const getTokenName = React.useCallback(\n    (tokenId?: number) => {\n      if (tokenMap) {\n        const keys = Object.keys(tokenMap)\n        const values = Object.values(tokenMap)\n        const index = values.findIndex((token) => token.tokenId === tokenId)\n        if (index > -1) {\n          return keys[index]\n        }\n        return ''\n      }\n      return ''\n    },\n    [tokenMap],\n  )\n\n  const getAmmpoolList = React.useCallback(\n    async ({ tokenSymbol, start, end, txTypes, offset, limit }: any) => {\n      const ammPoolAddress = tokenMap[tokenSymbol]?.address\n      setShowLoading(true)\n      if (LoopringAPI.ammpoolAPI && accountId && apiKey) {\n        const response = await LoopringAPI.ammpoolAPI.getUserAmmPoolTxs(\n          {\n            accountId,\n            txTypes: txTypes ? TxTypeAMM[txTypes] : '',\n            offset,\n            start,\n            end,\n            limit,\n            ammPoolAddress,\n          },\n          apiKey,\n        )\n        if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n          const errorItem = SDK_ERROR_MAP_TO_UI[(response as sdk.RESULT_INFO)?.code ?? 700001]\n          setToastOpen({\n            open: true,\n            type: ToastType.error,\n            content:\n              'error : ' + errorItem\n                ? t(errorItem.messageKey)\n                : (response as sdk.RESULT_INFO).message,\n          })\n        } else {\n          const result = response.userAmmPoolTxs.map((order) => ({\n            side: order.txType === sdk.AmmTxType.JOIN ? AmmSideTypes.Join : AmmSideTypes.Exit,\n            amount: {\n              from: {\n                key: getTokenName(order.poolTokens[0]?.tokenId),\n                value: String(\n                  volumeToCount(\n                    getTokenName(order.poolTokens[0]?.tokenId),\n                    order.poolTokens[0]?.actualAmount,\n                  ),\n                ),\n              },\n              to: {\n                key: getTokenName(order.poolTokens[1]?.tokenId),\n                value: String(\n                  volumeToCount(\n                    getTokenName(order.poolTokens[1]?.tokenId),\n                    order.poolTokens[1]?.actualAmount,\n                  ),\n                ),\n              },\n            },\n            lpTokenAmount: String(\n              volumeToCount(getTokenName(order.lpToken?.tokenId), order.lpToken?.actualAmount),\n            ),\n            fee: {\n              key: getTokenName(order.poolTokens[1]?.tokenId),\n              value: volumeToCount(\n                getTokenName(order.poolTokens[1]?.tokenId),\n                order.poolTokens[1]?.feeAmount,\n              )?.toFixed(6),\n            },\n            time: order.updatedAt,\n          }))\n          setAmmRecordList(result)\n          setShowLoading(false)\n          setAmmRecordTotal(response.totalNum)\n        }\n      }\n      setShowLoading(false)\n    },\n    [accountId, apiKey, getTokenName, setToastOpen, t, tokenMap],\n  )\n\n  return {\n    ammRecordList,\n    showLoading,\n    getAmmpoolList,\n    ammRecordTotal,\n  }\n}\n\nexport function useGetDefiRecord(setToastOpen: (props: any) => void) {\n  const { t } = useTranslation(['error'])\n  const [defiList, setDefiRecordList] = React.useState<sdk.UserDefiTxsHistory[]>([])\n  const [defiTotal, setDefiTotal] = React.useState(0)\n  const [showLoading, setShowLoading] = React.useState(true)\n  const { accountId, apiKey } = store.getState().account\n\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n\n  const getDefiTxList = React.useCallback(\n    async ({ start, end, offset, limit }: any) => {\n      setShowLoading(true)\n      if (LoopringAPI.defiAPI && accountId && apiKey) {\n        const markets = DEFI_CONFIG.MARKETS[network]\n        const response = await LoopringAPI.defiAPI.getDefiTransaction(\n          {\n            accountId,\n            offset,\n            start,\n            end,\n            limit,\n            markets: markets.join(','),\n          } as any,\n          apiKey,\n        )\n        if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n          const errorItem = SDK_ERROR_MAP_TO_UI[(response as sdk.RESULT_INFO)?.code ?? 700001]\n          setToastOpen({\n            open: true,\n            type: ToastType.error,\n            content:\n              'error : ' + errorItem\n                ? t(errorItem.messageKey)\n                : (response as sdk.RESULT_INFO).message,\n          })\n        } else {\n          // @ts-ignore\n          const result = (response as any).userDefiTxs\n          setDefiRecordList(result)\n          setShowLoading(false)\n          setDefiTotal((response as any).totalNum)\n        }\n      }\n      setShowLoading(false)\n    },\n    [accountId, apiKey, setToastOpen, t],\n  )\n\n  return {\n    defiList,\n    showLoading,\n    getDefiTxList,\n    defiTotal,\n  }\n}\n\nexport function useTaikoFarmingRecord(setToastOpen: (props: any) => void) {\n  const { t } = useTranslation(['error'])\n  const { tokenMap } = useTokenMap()\n  const [sideStakingList, setSideStakingRecordList] = React.useState<{\n    accountId: number;\n    tokenId: number;\n    amount: string;\n    productId: string;\n    hash: string;\n    stakingType: \"subscribe\" | \"unsubscribe\" | \"redeem\";\n    createdAt: number;\n    updatedAt: number;\n}[]>(\n    [],\n  )\n  const [sideStakingTotal, setSideStakingTotal] = React.useState(0)\n  const [showLoading, setShowLoading] = React.useState(true)\n  const { accountId, apiKey } = store.getState().account\n  const tokenInfo = tokenMap['TAIKO']\n  const getSideStakingTxList = React.useCallback(\n    async ({ start, end, offset, limit }: any) => {\n      setShowLoading(true)\n      if (LoopringAPI.defiAPI && accountId && apiKey) {\n        const response = await LoopringAPI.defiAPI.getTaikoFarmingTransactions(\n          {\n            accountId,\n            tokenId: tokenInfo.tokenId,\n            start,\n            end,\n            limit,\n            offset,\n          } as any,\n          apiKey,\n        )\n        if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n          const errorItem = SDK_ERROR_MAP_TO_UI[(response as sdk.RESULT_INFO)?.code ?? 700001]\n          setToastOpen({\n            open: true,\n            type: ToastType.error,\n            content:\n              'error : ' + errorItem\n                ? t(errorItem.messageKey)\n                : (response as sdk.RESULT_INFO).message,\n          })\n        } else {\n\n          const result = response.transactions\n\n          setSideStakingRecordList(result)\n          setShowLoading(false)\n          setSideStakingTotal(response.totalNum)\n          // }\n        }\n      }\n      setShowLoading(false)\n    },\n    [accountId, apiKey, setToastOpen, t],\n  )\n\n  return {\n    sideStakingList: sideStakingList.filter(\n      (item) =>\n        !(item.stakingType === 'redeem' && (item.amount === '' || new Decimal(item.amount).eq(0))),\n    ),\n    showLoading,\n    getSideStakingTxList,\n    sideStakingTotal,\n  }\n}\n\nexport const useOrderList = ({\n  setToastOpen,\n  isStopLimit = false,\n  isOrderBookScroll = false,\n}: {\n  isStopLimit?: boolean\n  setToastOpen?: (props: any) => void\n  isOrderBookScroll?: boolean\n}) => {\n  const { t } = useTranslation(['error'])\n  const [orderOriginalData, setOrderOriginalData] = React.useState<OrderHistoryRawDataItem[]>([])\n  const [orderDetailList, setOrderDetailList] = React.useState<OrderHistoryTableDetailItem[]>([])\n  const [totalNum, setTotalNum] = React.useState(0)\n  const [showLoading, setShowLoading] = React.useState(false)\n  const [showDetailLoading, setShowDetailLoading] = React.useState(false)\n  const {\n    account: { accountId, apiKey, readyState },\n  } = useAccount()\n  const {\n    tokenMap: { marketArray, tokenMap, marketMap },\n  } = store.getState()\n  const {\n    ammMap: { ammMap },\n  } = store.getState().amm\n  const { sk: privateKey } = store.getState().account.eddsaKey\n\n  const { status, updateWalletLayer2 } = useWalletLayer2()\n\n  const ammPairList = ammMap ? Object.keys(ammMap) : []\n  const jointPairs = (marketArray || []).concat(ammPairList)\n\n  const getOrderList = React.useCallback(\n    async ({\n      isScroll,\n      ...props\n    }: Omit<GetOrdersRequest, 'accountId'> & { isScroll?: boolean; extraOrderTypes?: string }) => {\n      setShowLoading(true)\n      if (LoopringAPI && LoopringAPI.userAPI && accountId && apiKey) {\n        const userOrders = await LoopringAPI.userAPI.getOrders(\n          {\n            ...props,\n            accountId,\n            extraOrderTypes: isStopLimit ? 'STOP_LIMIT' : 'TRADITIONAL_ORDER',\n          },\n          apiKey,\n        )\n        if ((userOrders as sdk.RESULT_INFO).code || (userOrders as sdk.RESULT_INFO).message) {\n          const errorItem = SDK_ERROR_MAP_TO_UI[(userOrders as sdk.RESULT_INFO)?.code ?? 700001]\n          if (setToastOpen) {\n            setToastOpen({\n              open: true,\n              type: ToastType.error,\n              content:\n                'error : ' + errorItem\n                  ? t(errorItem.messageKey)\n                  : (userOrders as sdk.RESULT_INFO).message,\n            })\n          }\n        } else {\n          if (userOrders && Array.isArray(userOrders.orders)) {\n            setTotalNum(userOrders.totalNum)\n            const data = userOrders.orders.map((order) => {\n              const { baseAmount, quoteAmount, baseFilled, quoteFilled } = order.volumes\n              const marketList = order.market.split('-')\n              if (marketList.length === 3) {\n                marketList.shift()\n              }\n              // due to AMM case, we cannot use first index\n              const side = order.side === Side.Buy ? TradeTypes.Buy : TradeTypes.Sell\n              const isBuy = side === TradeTypes.Buy\n              const [tokenFirst, tokenLast] = marketList\n              const baseToken = isBuy ? tokenLast : tokenFirst\n              const quoteToken = isBuy ? tokenFirst : tokenLast\n              const actualBaseFilled = (isBuy ? quoteFilled : baseFilled) as any\n              const actualQuoteFilled = (isBuy ? baseFilled : quoteFilled) as any\n              const baseValue = isBuy\n                ? volumeToCount(baseToken, quoteAmount)\n                : volumeToCount(baseToken, baseAmount)\n              const quoteValue = isBuy\n                ? volumeToCount(quoteToken, baseAmount)\n                : (volumeToCount(baseToken, baseAmount) || 0) * Number(order.price || 0)\n              const baseVolume = volumeToCountAsBigNumber(baseToken, actualBaseFilled)\n              const quoteVolume = volumeToCountAsBigNumber(quoteToken, actualQuoteFilled)\n              const quotefilledValue = volumeToCount(quoteToken, actualQuoteFilled)\n\n              const average = isBuy\n                ? baseVolume?.div(quoteVolume || new BigNumber(1)).toNumber() || 0\n                : quoteVolume?.div(baseVolume || new BigNumber(1)).toNumber() || 0\n              const completion = (quotefilledValue || 0) / (quoteValue || 1)\n\n              const precisionFrom = tokenMap\n                ? (tokenMap as any)[baseToken]?.precisionForOrder\n                : undefined\n              const precisionTo = tokenMap\n                ? (tokenMap as any)[quoteToken]?.precisionForOrder\n                : undefined\n              const precisionMarket = marketMap\n                ? marketMap[order.market]?.precisionForPrice\n                : undefined\n\n              return {\n                market: order.market,\n                side: order.side === 'BUY' ? TradeTypes.Buy : TradeTypes.Sell,\n                orderType: order.orderType,\n                amount: {\n                  from: {\n                    key: baseToken,\n                    value: baseValue as any,\n                    precision: precisionFrom,\n                  },\n                  to: {\n                    key: quoteToken,\n                    value: quoteValue as any,\n                    precision: precisionTo,\n                  },\n                },\n                average: average,\n                price: {\n                  key: quoteToken,\n                  value: Number(order.price),\n                },\n                time: order.validity.start * 1000,\n                status: order.status as unknown as TradeStatus,\n                hash: order.hash,\n                orderId: order.clientOrderId,\n                tradeChannel: order.tradeChannel,\n                completion: completion,\n                precisionMarket: precisionMarket,\n                // @ts-ignore\n                extraOrderInfo: order.extraOrderInfo,\n                __raw__: order,\n              }\n            })\n            if (isScroll) {\n              setOrderOriginalData((_data) => {\n                return [..._data, ...data]\n              })\n            } else {\n              setOrderOriginalData(data)\n            }\n          }\n        }\n      }\n      setShowLoading(false)\n    },\n    [accountId, apiKey, marketMap, tokenMap, isStopLimit],\n  )\n\n  React.useEffect(() => {\n    ;(async () => {\n      if (status === 'UNSET' && isOrderBookScroll === true) {\n        getOrderList({\n          limit: 50,\n          status: ['processing'],\n        })\n      }\n    })()\n  }, [isOrderBookScroll, getOrderList, status])\n\n  const clearOrderDetail = React.useCallback(() => {\n    setOrderDetailList([])\n  }, [])\n\n  const isAtBottom = React.useCallback(\n    ({ currentTarget }: React.UIEvent<HTMLDivElement>): boolean => {\n      return currentTarget.scrollTop + 10 >= currentTarget.scrollHeight - currentTarget.clientHeight\n    },\n    [],\n  )\n\n  const handleScroll = React.useCallback(\n    async (event: React.UIEvent<HTMLDivElement>, isOpen: boolean = false) => {\n      if (!isAtBottom(event) || (event.target as any)?.scrollTop === 0) return\n      getOrderList({\n        isScroll: true,\n        offset: orderOriginalData.length,\n        status: isOpen\n          ? ['processing']\n          : ['processed', 'failed', 'cancelled', 'cancelling', 'expired'],\n        extraOrderTypes: isStopLimit ? 'STOP_LIMIT' : 'TRADITIONAL_ORDER',\n      })\n    },\n    [getOrderList, isAtBottom, orderOriginalData, isStopLimit],\n  )\n\n  const cancelOrder = React.useCallback(\n    async ({ orderHash, clientOrderId }: any) => {\n      if (LoopringAPI && LoopringAPI.userAPI && accountId && privateKey && apiKey) {\n        await LoopringAPI.userAPI.cancelOrder(\n          {\n            accountId,\n            orderHash,\n            clientOrderId,\n          },\n          privateKey,\n          apiKey,\n        )\n        updateWalletLayer2()\n      }\n    },\n    [accountId, apiKey, privateKey, updateWalletLayer2],\n  )\n\n  const cancelOrderByHashList = React.useCallback(\n    async (orderHashList: string) => {\n      if (LoopringAPI && LoopringAPI.userAPI && accountId && privateKey && apiKey) {\n        await LoopringAPI.userAPI.cancelMultiOrdersByHash(\n          {\n            accountId,\n            orderHash: orderHashList,\n          },\n          privateKey,\n          apiKey,\n        )\n        updateWalletLayer2()\n      }\n    },\n    [accountId, apiKey, privateKey, updateWalletLayer2],\n  )\n\n  const getOrderDetail = React.useCallback(\n    async (orderHash: string, t: TFunction) => {\n      if (LoopringAPI && LoopringAPI.userAPI && accountId && apiKey) {\n        setShowDetailLoading(true)\n        const response = await LoopringAPI.userAPI.getOrderDetails(\n          {\n            accountId,\n            orderHash,\n          },\n          apiKey,\n        )\n        const formattedData = [response.orderDetail].map((order: any) => {\n          const { baseAmount, quoteAmount, baseFilled, quoteFilled, fee } = order.volumes\n          const marketList = order.market.split('-')\n          if (marketList.length === 3) {\n            marketList.shift()\n          }\n          // due to AMM case, we cannot use first index\n          const side = order.side === Side.Buy ? TradeTypes.Buy : TradeTypes.Sell\n          const isBuy = side === TradeTypes.Buy\n          const role = isBuy ? t('labelOrderDetailMaker') : t('labelOrderDetailTaker')\n          const [tokenFirst, tokenLast] = marketList\n          const baseToken = isBuy ? tokenLast : tokenFirst\n          const quoteToken = isBuy ? tokenFirst : tokenLast\n          const baseValue = isBuy\n            ? volumeToCount(baseToken, quoteAmount)\n            : volumeToCount(baseToken, baseAmount)\n          const quoteValue = isBuy\n            ? volumeToCount(quoteToken, baseAmount)\n            : (volumeToCount(baseToken, baseAmount) || 0) * Number(order.price || 0)\n          const actualBaseFilled = isBuy ? quoteFilled : baseFilled\n          const actualQuoteFilled = isBuy ? baseFilled : quoteFilled\n          const baseVolume = volumeToCountAsBigNumber(baseToken, actualBaseFilled)\n          const quoteVolume = volumeToCountAsBigNumber(quoteToken, actualQuoteFilled)\n          const filledPrice = baseVolume?.div(quoteVolume || new BigNumber(1)).toNumber() || 0\n          const feeValue = volumeToCountAsBigNumber(quoteToken, fee)?.toNumber() || 0\n\n          const precisionFrom = tokenMap\n            ? (tokenMap as any)[baseToken]?.precisionForOrder\n            : undefined\n          const precisionTo = tokenMap\n            ? (tokenMap as any)[quoteToken]?.precisionForOrder\n            : undefined\n          const precisionMarket = marketMap ? marketMap[order.market]?.precisionForPrice : undefined\n          const precisionFee = tokenMap\n            ? (tokenMap as any)[quoteToken]?.precisionForOrder\n            : undefined\n\n          return {\n            amount: {\n              from: {\n                key: baseToken,\n                value: baseValue as any,\n                precision: precisionFrom,\n              },\n              to: {\n                key: quoteToken,\n                value: quoteValue as any,\n                precision: precisionTo,\n              },\n            },\n            filledPrice: {\n              value: filledPrice,\n              precision: precisionMarket,\n            },\n            fee: {\n              key: quoteToken,\n              value: feeValue,\n              precision: precisionFee,\n            },\n            role: role,\n            time: order.validity.start * 1000,\n            volume: quoteVolume?.toNumber(),\n            orderId: order.clientOrderId,\n            extraOrderInfo: order.extraOrderInfo,\n            __raw__: order,\n          }\n        })\n        setOrderDetailList(formattedData)\n        setShowDetailLoading(false)\n      }\n    },\n    [accountId, apiKey, marketMap, tokenMap],\n  )\n\n  const clearData = React.useCallback(() => {\n    setOrderOriginalData([])\n  }, [])\n\n  React.useEffect(() => {\n    if (readyState !== AccountStatus.ACTIVATED) {\n      clearData()\n    }\n  }, [status, readyState, clearData])\n\n  return {\n    marketArray: jointPairs,\n    getOrderList,\n    setOrderOriginalData,\n    rawData: orderOriginalData,\n    clearRawData: clearData,\n    totalNum,\n    showLoading,\n    showDetailLoading,\n    getOrderDetail,\n    orderDetailList,\n    cancelOrder,\n    handleScroll,\n    clearOrderDetail,\n    cancelOrderByHashList,\n  }\n}\n\nexport const useDualTransaction = <R extends RawDataDualTxsItem>(\n  setToastOpen: (props: any) => void,\n) => {\n  const { t } = useTranslation(['error'])\n\n  const {\n    account: { accountId, apiKey },\n  } = useAccount()\n\n  const [dualList, setDualList] = React.useState<R[]>([])\n  const { idIndex } = useTokenMap()\n  const [dualTotal, setDualTotal] = React.useState(0)\n  const { marketMap: dualMarketMap } = useDualMap()\n  // const [pagination, setDualPagination] = React.useState<{\n  //   pageSize: number;\n  //   total: number;\n  // }>({\n  //   pageSize: Limit,\n  //   total: 0,\n  // });\n  const [showLoading, setShowLoading] = React.useState(true)\n\n  const getDualTxList = React.useCallback(\n    async ({ start, end, offset, settlementStatus, investmentStatus, dualTypes, limit }: any) => {\n      setShowLoading(true)\n      if (LoopringAPI.defiAPI && accountId && apiKey) {\n        const response = await LoopringAPI.defiAPI.getDualTransactions(\n          {\n            dualTypes,\n            accountId,\n            settlementStatus,\n            investmentStatus,\n            offset,\n            limit,\n            start,\n            end,\n          } as any,\n          apiKey,\n        )\n        if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n          const errorItem = SDK_ERROR_MAP_TO_UI[(response as sdk.RESULT_INFO)?.code ?? 700001]\n          if (setToastOpen) {\n            setToastOpen({\n              open: true,\n              type: ToastType.error,\n              content:\n                'error : ' + errorItem\n                  ? t(errorItem.messageKey)\n                  : (response as sdk.RESULT_INFO).message,\n            })\n          }\n        } else {\n          // @ts-ignore\n          let result = (response as any)?.userDualTxs.reduce(\n            (prev: RawDataDualAssetItem[], item: sdk.UserDualTxsHistory) => {\n              const [, , coinA, coinB] =\n                (item.tokenInfoOrigin.market ?? 'dual-').match(/(dual-)?(\\w+)-(\\w+)/i) ?? []\n\n              let [sellTokenSymbol, buyTokenSymbol] =\n                item.dualType == DUAL_TYPE.DUAL_BASE\n                  ? [\n                      coinA ?? idIndex[item.tokenInfoOrigin.tokenIn],\n                      coinB ?? idIndex[item.tokenInfoOrigin.tokenOut],\n                    ]\n                  : [\n                      coinB ?? idIndex[item.tokenInfoOrigin.tokenIn],\n                      coinA ?? idIndex[item.tokenInfoOrigin.tokenOut],\n                    ]\n              prev.push({\n                ...makeDualOrderedItem(\n                  item,\n                  sellTokenSymbol,\n                  buyTokenSymbol,\n                  0,\n                  dualMarketMap[item.tokenInfoOrigin.market],\n                ),\n                amount: item.tokenInfoOrigin.amountIn,\n              })\n              return prev\n            },\n            [] as RawDataDualAssetItem[],\n          )\n\n          setDualList(result)\n          setShowLoading(false)\n          setDualTotal((response as any).totalNum)\n          // setDualPagination({\n          //   pageSize: limit,\n          //   total: (response as any).totalNum,\n          // });\n        }\n      }\n      setShowLoading(false)\n    },\n    [accountId, apiKey, setToastOpen, t, idIndex, dualMarketMap],\n  )\n\n  return {\n    // page,\n    dualList,\n    showLoading,\n    getDualTxList,\n    dualTotal,\n    dualMarketMap,\n  }\n}\n\nexport const useBtradeTransaction = <R extends RawDataBtradeSwapsItem>(\n  setToastOpen: (props: any) => void,\n) => {\n  const { t } = useTranslation(['error'])\n  const [btradeOrderData, setBtradeOrderData] = React.useState<R[]>([])\n  const [totalNum, setTotalNum] = React.useState(0)\n  const [showLoading, setShowLoading] = React.useState(false)\n  const {\n    account: { accountId, apiKey },\n  } = useAccount()\n  const { tokenMap } = useTokenMap()\n  const { setShowAccount } = useOpenModals()\n  const { chainId, baseURL} = useSystem()\n\n  const getBtradeOrderList = React.useCallback(\n    async (props: Omit<sdk.GetOrdersRequest, 'accountId'>) => {\n      \n      if (chainId && baseURL && accountId && apiKey) {\n        const defiAPI = new sdk.DefiAPI({\n          chainId: chainId as sdk.ChainId,\n          baseUrl: baseURL\n        })\n        setShowLoading(true)\n        const userOrders = await defiAPI.getBtradeOrders({\n          request: { accountId, limit: props.limit, offset: props.offset },\n          apiKey,\n        })\n        if ((userOrders as sdk.RESULT_INFO).code || (userOrders as sdk.RESULT_INFO).message) {\n          const errorItem = SDK_ERROR_MAP_TO_UI[(userOrders as sdk.RESULT_INFO)?.code ?? 700001]\n          if (setToastOpen) {\n            setToastOpen({\n              open: true,\n              type: ToastType.error,\n              content:\n                'error : ' + errorItem\n                  ? t(errorItem.messageKey)\n                  : (userOrders as sdk.RESULT_INFO).message,\n            })\n          }\n        } else {\n          if (userOrders && Array.isArray(userOrders.list)) {\n            setTotalNum(userOrders.totalNum)\n            const data = userOrders.list.map((item: any) => {\n              const {\n                status,\n                market,\n                price,\n                // btradeExtraInfo: tokenInfos,\n                volumes: { fee, baseAmount, baseFilled, quoteAmount, quoteFilled },\n                validity: { start },\n                side,\n                baseSettled,\n                quoteSettled,\n              } = item\n              //@ts-ignore\n              const [, baseTokenSymbol, quoteTokenSymbol] = market\n                .replace(BTRDE_PRE, '')\n                .match(/(\\w+)-(\\w+)/i)\n              let amountIn,\n                amountOut,\n                fromSymbol,\n                toSymbol,\n                amountFOut,\n                _price,\n                amountFIn,\n                settledIn,\n                settledOut\n\n              if (side === sdk.Side.Sell) {\n                fromSymbol = baseTokenSymbol\n                toSymbol = quoteTokenSymbol\n                amountFIn = baseFilled\n                amountFOut = quoteFilled\n                amountIn = baseAmount\n                amountOut = quoteAmount\n                settledIn = baseSettled\n                settledOut = quoteSettled\n                _price = {\n                  from: baseTokenSymbol,\n                  key: quoteTokenSymbol,\n                  value: getValuePrecisionThousand(\n                    price,\n                    tokenMap[quoteTokenSymbol].precision,\n                    tokenMap[quoteTokenSymbol].precision,\n                    undefined,\n                  ),\n                }\n              } else {\n                toSymbol = baseTokenSymbol\n                fromSymbol = quoteTokenSymbol\n                amountFOut = baseFilled\n                amountFIn = quoteFilled\n                amountOut = baseAmount\n                amountIn = quoteAmount\n                settledOut = baseSettled\n                settledIn = quoteSettled\n                _price = {\n                  from: baseTokenSymbol,\n                  key: quoteTokenSymbol,\n                  value: getValuePrecisionThousand(\n                    price,\n                    tokenMap[quoteTokenSymbol].precision,\n                    tokenMap[quoteTokenSymbol].precision,\n                    undefined,\n                  ),\n                }\n              }\n\n              const fromToken = tokenMap[fromSymbol]\n              const toToken = tokenMap[toSymbol]\n\n              const fromAmount = sdk.toBig(amountIn).div('1e' + fromToken.decimals)\n              const fromFAmount = sdk.toBig(amountFIn).div('1e' + fromToken.decimals)\n              const settledFromAmount = sdk.toBig(settledIn).div('1e' + fromToken.decimals)\n              const toAmount = sdk.toBig(amountOut).div('1e' + toToken.decimals)\n              const toFAmount = sdk.toBig(amountFOut).div('1e' + toToken.decimals)\n              const settledToAmount = sdk.toBig(settledOut).div('1e' + toToken.decimals)\n              const fromAmountDisplay = getValuePrecisionThousand(\n                sdk.toBig(amountIn).div('1e' + fromToken.decimals),\n                undefined,\n                fromToken.precision,\n                fromToken.precision,\n                false,\n              )\n\n              const toAmountDisplay = getValuePrecisionThousand(\n                sdk.toBig(amountOut).div('1e' + toToken.decimals),\n                undefined,\n                toToken.precision,\n                toToken.precision,\n                false,\n              )\n\n              const feeAmount =\n                fee && fee != 0\n                  ? getValuePrecisionThousand(\n                      sdk.toBig(fee ?? 0).div('1e' + toToken.decimals),\n                      toToken.precision,\n                      toToken.precision,\n                      undefined,\n                    )\n                  : undefined\n              const feeSymbol = toSymbol\n\n              let type\n              switch (status) {\n                case 'processed':\n                  type = BtradeSwapsType.Settled\n                  break\n                case 'failed':\n                case 'cancelled':\n                  type = BtradeSwapsType.Failed\n                  break\n                case 'filled':\n                  type = BtradeSwapsType.Delivering\n                  break\n                case 'processing':\n                default:\n                  type = BtradeSwapsType.Pending\n                  break\n              }\n              return {\n                type,\n                price: _price,\n                fromAmount,\n                fromSymbol,\n                toAmount,\n                fromFAmount,\n                toFAmount,\n                settledFromAmount,\n                settledToAmount,\n                fromAmountDisplay,\n                toAmountDisplay,\n                toSymbol,\n                time: Number(start + '000'),\n                rawData: item,\n                feeSymbol,\n                feeAmount,\n                filledPercent: sdk.toBig(amountFIn).div(amountIn).times(100).toFormat(2),\n              }\n            }, [])\n            setBtradeOrderData(data)\n          }\n        }\n        setShowLoading(false)\n      }\n    },\n    [accountId, apiKey, setToastOpen, t, tokenMap, baseURL, chainId],\n  )\n\n  return {\n    getBtradeOrderList,\n    btradeOrderData,\n    onDetail: (item: R) => {\n      const info = {\n        sellToken: tokenMap[item.fromSymbol],\n        buyToken: tokenMap[item.toSymbol],\n        sellFStr: item.fromFAmount && item.fromFAmount !== '0' ? item.fromFAmount : undefined,\n        sellStr: item.fromAmount,\n        buyFStr: item.toFAmount && item.toFAmount !== '0' ? item.toFAmount : undefined,\n        buyStr: item.toAmount,\n        convertStr: `1 ${item.price.from} \\u2248 ${item.price.value} ${item.price.key}`,\n        // @ts-ignore\n        feeStr: item?.feeAmount == 0 ? undefined : item?.feeAmount,\n        settledToAmount: item.settledToAmount,\n        settledFromAmount: item.settledFromAmount,\n        time: item?.time ?? undefined,\n        placedAmount:\n          tokenMap && item.fromSymbol && item.fromAmount && sdk.toBig(item.fromAmount).gt(0)\n            ? `${getValuePrecisionThousand(\n                sdk.toBig(item.fromAmount),\n                undefined,\n                undefined,\n                tokenMap[item.fromSymbol].precision,\n                false,\n                { isAbbreviate: true },\n              )} ${item.fromSymbol}`\n            : EmptyValueTag,\n        executedAmount:\n          tokenMap && item.fromSymbol && item.settledFromAmount && sdk.toBig(item.settledFromAmount).gt(0)\n            ? `${getValuePrecisionThousand(\n                sdk.toBig(item.settledFromAmount),\n                undefined,\n                undefined,\n                tokenMap[item.fromSymbol].precision,\n                false,\n                { isAbbreviate: true },\n              )} ${item.fromSymbol}`\n            : EmptyValueTag,\n        executedRate:\n          tokenMap && item.fromSymbol && item.settledFromAmount && item.fromAmount && sdk.toBig(item.fromAmount).gt(0)\n            ? `${sdk\n                .toBig(item.settledFromAmount)\n                .div(item.fromAmount)\n                .multipliedBy('100')\n                .toFixed(2)}%`\n            : EmptyValueTag,\n        convertedAmount:\n          tokenMap && item.toSymbol && item.settledToAmount && sdk.toBig(item.settledToAmount).gt(0)\n            ? `${getValuePrecisionThousand(\n                sdk.toBig(item.settledToAmount),\n                undefined,\n                undefined,\n                tokenMap[item.toSymbol].precision,\n                false,\n                { isAbbreviate: true },\n              )} ${item.toSymbol}`\n            : EmptyValueTag,\n        settledAmount:\n          tokenMap && item.toSymbol && item.settledToAmount && item.feeAmount && sdk.toBig(item.settledToAmount).gt(0)\n            ? `${getValuePrecisionThousand(\n                sdk.toBig(item.settledToAmount).minus(item.feeAmount),\n                undefined,\n                undefined,\n                tokenMap[item.toSymbol].precision,\n                false,\n                { isAbbreviate: true },\n              )} ${item.toSymbol}`\n            : EmptyValueTag,\n      }\n      switch (item.type) {\n        case BtradeSwapsType.Delivering:\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.BtradeSwap_Delivering,\n            info: {\n              ...info,\n              isDelivering: true,\n            },\n          })\n          break\n\n        case BtradeSwapsType.Settled:\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.BtradeSwap_Settled,\n            info,\n          })\n          break\n        case BtradeSwapsType.Cancelled:\n        case BtradeSwapsType.Failed:\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.BtradeSwap_Failed,\n            info,\n          })\n          break\n        case BtradeSwapsType.Pending:\n        default:\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.BtradeSwap_Pending,\n            info,\n          })\n          break\n      }\n    },\n    totalNum,\n    showLoading,\n  }\n}\n\n\nexport function useGetLeverageETHRecord(setToastOpen: (props: any) => void) {\n  const { t } = useTranslation(['error'])\n  const [leverageETHList, setLeverageETHRecordList] = React.useState<sdk.UserDefiTxsHistory[]>([])\n  const [leverageETHTotal, setLeverageETHTotal] = React.useState(0)\n  const [showLoading, setShowLoading] = React.useState(true)\n  const { marketLeverageArray } = useDefiMap()\n  const { accountId, apiKey } = store.getState().account\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const getLeverageETHTxList = React.useCallback(\n    async ({ start, end, offset, limit }: any) => {\n      setShowLoading(true)\n      if (LoopringAPI.defiAPI && accountId && apiKey) {\n        const types = LEVERAGE_ETH_CONFIG.types[network]\n        const response = await LoopringAPI.defiAPI.getDefiTransaction(\n          {\n            accountId,\n            offset,\n            start,\n            end,\n            limit,\n            types: types.join(','),\n          } as any,\n          apiKey,\n        )\n        if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n          const errorItem = SDK_ERROR_MAP_TO_UI[(response as sdk.RESULT_INFO)?.code ?? 700001]\n          setToastOpen({\n            open: true,\n            type: ToastType.error,\n            content:\n              'error : ' + errorItem\n                ? t(errorItem.messageKey)\n                : (response as sdk.RESULT_INFO).message,\n          })\n        } else {\n          // @ts-ignore\n          const result = (response as any).userDefiTxs\n          setLeverageETHRecordList(result)\n          setShowLoading(false)\n          setLeverageETHTotal((response as any).totalNum)\n        }\n      }\n      setShowLoading(false)\n    },\n    [accountId, apiKey, setToastOpen, t],\n  )\n\n  return {\n    leverageETHList,\n    showLoading,\n    getLeverageETHTxList,\n    leverageETHTotal,\n  }\n}\n\nexport const useVaultTransaction = <R extends RawDataVaultTxItem>(\n  setToastOpen: (props: any) => void,\n) => {\n  const { t } = useTranslation(['common', 'error'])\n  const { t: t2 } = useTranslation(['tables'])\n  const [vaultOrderData, setVaultOrderData] = React.useState<R[]>([])\n  const [totalNum, setTotalNum] = React.useState(0)\n  const [showLoading, setShowLoading] = React.useState(false)\n  const {\n    account: { accountId, apiKey },\n  } = useAccount()\n  const { currency, coinJson } = useSettings()\n  const { forexMap, getValueInCurrency } = useSystem()\n  const { tokenMap: vaultTokenMap, idIndex: vaultIdIndex, erc20Map, tokenPrices: vaultTokenPrices } = useVaultMap()\n  const { tokenMap, idIndex } = useTokenMap()\n  const { setShowAccount } = useOpenModals()\n  const getVaultOrderList = React.useCallback(\n    async (\n      props: Omit<\n        {\n          operateTypes: string\n          offset: number\n          start?: number\n          end?: number\n          limit: number\n        },\n        'accountId'\n      >,\n    ) => {\n      if (LoopringAPI && LoopringAPI.vaultAPI && accountId && apiKey) {\n        setShowLoading(true)\n        const response = await LoopringAPI.vaultAPI.getVaultGetOperationHistory(\n          {\n            accountId,\n            limit: props.limit ?? 20,\n            offset: props.offset ?? 0,\n            operateTypes:\n              props?.operateTypes ??\n              [\n                0, 1, 2, 3, 4, 5, 6, 7, 8\n              ].join(','),\n          },\n          apiKey,\n          '1'\n        )\n        if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n          const errorItem = SDK_ERROR_MAP_TO_UI[(response as sdk.RESULT_INFO)?.code ?? 700001]\n          if (setToastOpen) {\n            setToastOpen({\n              open: true,\n              type: ToastType.error,\n              content:\n                'error : ' + errorItem\n                  ? t(errorItem.messageKey)\n                  : (response as sdk.RESULT_INFO).message,\n            })\n          }\n        } else {\n          const { list, totalNum } = response as any\n          if (list && Array.isArray(list) && vaultIdIndex && !isEmpty(vaultIdIndex)) {\n            setTotalNum(totalNum)\n            const data = list.map(\n              ({ operation, order }: { operation: sdk.VaultOperation; order: sdk.VaultOrder }) => {\n                const {\n                  operateSubType,\n                  operateType,\n                  status,\n                  amountIn: amountS,\n                  tokenIn: tokenS,\n                  tokenOut: tokenB,\n                  amountOut: amountB,\n                } = operation\n                let fillAmountB, fillAmountS\n                const { fee, price } = order ?? {}\n                // const { fillAmountS, amountS, tokenS, tokenB, amountB, fillAmountB, price } = order\n                let type,\n                  mainContentRender,\n                  erc20Symbol,\n                  erc20SymbolB,\n                  vSymbol,\n                  precision,\n                  precisionB,\n                  vToken,\n                  fillAmount,\n                  amount,\n                  vTokenB,\n                  tokenBSymbol,\n                  vSymbolB,\n                  symbolB,\n                  percentage,\n                  fillAmountSStr,\n                  fillAmountBStr,\n                  feeStr,\n                  feeToken\n                switch (operateType) {\n                  case sdk.VaultOperationType.VAULT_OPEN_POSITION:\n                  case sdk.VaultOperationType.VAULT_MARGIN_CALL:\n                  case sdk.VaultOperationType.VAULT_JOIN_REDEEM:\n                    type =\n                      sdk.VaultOperationType.VAULT_OPEN_POSITION == operateType\n                        ? VaultRecordType.open\n                        : sdk.VaultOperationType.VAULT_JOIN_REDEEM == operateType\n                        ? VaultRecordType.redeem\n                        : VaultRecordType.margin\n                    //@ts-ignore\n                    const erc20Token = tokenMap[idIndex[tokenS ?? '']]\n                    //@ts-ignore\n                    vToken = vaultTokenMap[vaultIdIndex[erc20Map[erc20Token.symbol]?.vaultTokenId]]\n                    precision = vToken?.precision\n                    vSymbol = vToken.symbol\n                    erc20Symbol = vToken.symbol.slice(2)\n                    amount = sdk.toBig(amountS ?? 0).div('1e' + vToken.decimals).abs()\n                    fillAmountS =\n                      status == sdk.VaultOperationStatus.VAULT_STATUS_SUCCEED ? amountS : 0\n                    fillAmount = sdk.toBig(fillAmountS).div('1e' + vToken.decimals)\n                    percentage = sdk.VaultOperationStatus.VAULT_STATUS_SUCCEED ? 100 : 0\n                    const amountStr = !amount.eq(0)\n                      ? getValuePrecisionThousand(amount, precision, precision)\n                      : EmptyValueTag\n                    mainContentRender = `${amountStr.toString()} ${mapSpecialTokenName(erc20Symbol)}`\n                    break\n                  case sdk.VaultOperationType.VAULT_BORROW:\n                    type = VaultRecordType.borrow\n                    //@ts-ignore\n                    vToken = vaultTokenMap[vaultIdIndex[tokenB ?? '']] ?? {}\n                    erc20Symbol = vToken?.symbol.slice(2)\n                    precision = vToken.precision\n                    vSymbol = vToken?.symbol\n                    amount = sdk.toBig(amountB ?? 0).div('1e' + vToken.decimals)\n                    fillAmountB =\n                      status == sdk.VaultOperationStatus.VAULT_STATUS_SUCCEED ? amountB : 0\n                    fillAmount = sdk.toBig(fillAmountB).div('1e' + vToken.decimals)\n                    percentage = sdk\n                      .toBig(fillAmountB ?? 0)\n                      .div(amountB ?? 1)\n                      .times(100)\n                      .toFixed(2)\n\n                    mainContentRender = `${\n                      amount.gte(0)\n                        ? getValuePrecisionThousand(amount, precision, precision)\n                        : EmptyValueTag\n                    } ${mapSpecialTokenName(erc20Symbol)}`\n                    break\n                  case sdk.VaultOperationType.VAULT_REPAY:\n                    type = VaultRecordType.repay\n                    //@ts-ignore\n                    vToken = vaultTokenMap[vaultIdIndex[tokenS ?? '']] ?? {}\n                    erc20Symbol = vToken?.symbol.slice(2)\n                    precision = vToken?.precision\n                    vSymbol = vToken?.symbol\n                    amount = sdk.toBig(amountS ?? 0).div('1e' + vToken.decimals)\n                    fillAmountS =\n                      status == sdk.VaultOperationStatus.VAULT_STATUS_SUCCEED ? amountS : 0\n                    fillAmount = sdk.toBig(fillAmountS).div('1e' + vToken.decimals)\n                    percentage = sdk.VaultOperationStatus.VAULT_STATUS_SUCCEED ? 100 : 0\n                    // percentage = sdk\n                    //   .toBig(fillAmountS ?? 0)\n                    //   .div(amountS ?? 1)\n                    //   .times(100)\n                    //   .toFixed(2)\n\n                    mainContentRender = `${\n                      amount.gte(0)\n                        ? getValuePrecisionThousand(amount, precision, precision)\n                        : EmptyValueTag\n                    } ${mapSpecialTokenName(erc20Symbol)}`\n                    break\n                  case sdk.VaultOperationType.VAULT_TRADE:\n                    type = VaultRecordType.trade\n                    //@ts-ignore\n                    vToken = vaultTokenMap[vaultIdIndex[tokenS ?? '']]\n                    //@ts-ignore\n                    vTokenB = vaultTokenMap[vaultIdIndex[tokenB ?? '']]\n                    feeToken = vTokenB\n                    erc20Symbol = vToken.symbol.slice(2)\n                    erc20SymbolB = vTokenB.symbol.slice(2)\n                    precision = vToken.precision\n                    precisionB = vTokenB.precision\n                    vSymbol = vToken.symbol\n                    vSymbolB = vTokenB.symbol\n\n                    fillAmountS = sdk.toBig(order.fillAmountS ?? 0).div('1e' + vToken.decimals)\n                    fillAmountB = sdk.toBig(order.fillAmountB ?? 0).div('1e' + vTokenB.decimals)\n                    fillAmountSStr = getValuePrecisionThousand(fillAmountS, precision, precision)\n                    fillAmountBStr = getValuePrecisionThousand(fillAmountB, precisionB, precisionB)\n                    const _amountS = sdk.toBig(order.amountS ?? 0).div('1e' + vToken.decimals)\n                    const _amountB = sdk.toBig(order.amountB ?? 0).div('1e' + vTokenB.decimals)\n                    const _amountSStr = getValuePrecisionThousand(_amountS, precision, precision)\n                    const _amountBStr = getValuePrecisionThousand(_amountB, precisionB, precisionB)\n\n                    percentage = sdk\n                      .toBig(order?.fillAmountS ?? 0)\n                      .div(order?.amountS ?? 1)\n                      .times(100)\n                      .toFixed(2)\n                    feeStr = getValuePrecisionThousand(\n                      sdk.toBig(fee ?? 0).div('1e' + feeToken.decimals),\n                      precisionB,\n                      precisionB,\n                    )\n                    mainContentRender = `${fillAmountS.gte(0) ? fillAmountSStr : EmptyValueTag}  ${mapSpecialTokenName(erc20Symbol)} ${DirectionTag} ${\n                      fillAmountB.gte(0) ? fillAmountBStr : EmptyValueTag\n                    } ${mapSpecialTokenName(erc20SymbolB)}`\n                    break\n                  case sdk.VaultOperationType.VAULT_CLOSE_OUT:\n                    type = VaultRecordType.closeout\n                    let erc20B = tokenMap[idIndex[tokenB ?? '']]\n                    tokenBSymbol = erc20B.symbol\n                    //@ts-ignore\n                    // vTokenB = vaultTokenMap[vaultIdIndex[tokenB ?? '']]\n                    amount = sdk.toBig(amountB ?? 0).div('1e' + erc20B?.decimals ?? 0)\n                    //@ts-ignore\n                    precision = erc20B.precision\n                    fillAmountB =\n                      status == sdk.VaultOperationStatus.VAULT_STATUS_SUCCEED ? amountB : 0\n                    fillAmount = sdk.toBig(fillAmountB).div('1e' + erc20B.decimals)\n                    percentage = sdk.VaultOperationStatus.VAULT_STATUS_SUCCEED ? 100 : 0\n                    // percentage = sdk\n                    //   .toBig(amountB ?? 0)\n                    //   .div(fillAmountB ?? 1)\n                    //   .times(100)\n                    //   .toFixed(2)\n                    mainContentRender = `${\n                      amount.gte(0)\n                        ? getValuePrecisionThousand(amount, precision, precision)\n                        : EmptyValueTag\n                    } ${mapSpecialTokenName(tokenBSymbol)}`\n                    break\n                  case sdk.VaultOperationType.VAULT_CONVERT:\n                      type = VaultRecordType.convert\n                      const buyAmountList : string[] = (operation as any).executionHistory.map((item: string) => {\n                        const itemObj = JSON.parse(item)\n                        const {\n                          amountOut,\n                          tokenOut,\n                        } = itemObj\n                        const vTokenBuyInfo = vaultTokenMap[vaultIdIndex[tokenOut]]\n                        const buyAmount = numberFormat(utils.formatUnits(amountOut, vTokenBuyInfo.decimals), {fixed: vTokenBuyInfo.precision})\n                        return buyAmount\n                      })\n                      const repaymentInUSDT = numberFormat(numberStringListSum(buyAmountList), {fixed: 2});\n                      mainContentRender = repaymentInUSDT + ' USDT'\n                      break\n                      case sdk.VaultOperationType.VAULT_CLOSE_SHORT:\n                        vToken = vaultTokenMap[vaultIdIndex[tokenS ?? '']] ?? {}\n                        erc20Symbol = vToken?.symbol.slice(2)\n                        precision = vToken?.precision\n                        amount = sdk.toBig(amountS ?? 0).div('1e' + vToken.decimals)\n                        mainContentRender = `${\n                          amount.gte(0)\n                            ? getValuePrecisionThousand(amount, precision, precision)\n                            : EmptyValueTag\n                        } ${erc20Symbol}`\n                        type = VaultRecordType.closeShort\n                        break\n                }\n\n                let item = {\n                  status,\n                  type,\n                  vSymbol,\n                  vTokenB,\n                  operateSubType,\n                  operateType,\n                  symbolB,\n                  vSymbolB,\n                  feeStr,\n                  feeTokenSymbol: feeToken?.symbol,\n                  feeErc20Symbol: erc20SymbolB,\n                  erc20SymbolB,\n                  erc20Symbol,\n                  mainContentRender,\n                  fillAmount: fillAmount?.toString(),\n                  percentage,\n                  raw_data: {\n                    order,\n                    operation,\n                  },\n                } as unknown as R\n                return item\n              },\n            )\n            setVaultOrderData(data)\n          }\n        }\n        setShowLoading(false)\n      }\n    },\n    [accountId, apiKey, setToastOpen, t, tokenMap, vaultIdIndex],\n  )\n  const [detail, setShowDetail] = React.useState<\n    | {\n        isShow: true\n        detail:\n          | {\n              type:\n                | 'VAULT_OPEN_POSITION'\n                | 'VAULT_MARGIN_CALL'\n                | 'VAULT_BORROW'\n                | 'VAULT_REPAY'\n                | 'VAULT_JOIN_REDEEM'\n                | 'VAULT_CLOSE_SHORT'\n              statusColor: string\n              statusLabel: string\n              statusType: 'success' | 'processing' | 'failed'\n              // collateralSymbol?: string\n              // collateralAmount?: string\n              time: number\n              amount: string\n              amountSymbol: string\n            }\n          | {\n              type: 'VAULT_TRADE'\n              statusColor: string\n              statusLabel: string\n              statusType: 'success' | 'processing' | 'failed'\n              fromSymbol: string\n              toSymbol: string\n              placedAmount: string\n              executedAmount: string\n              executedRate: string\n              convertedAmount: string\n              price: string\n              feeSymbol: string\n              feeAmount: string\n              time: number\n            }\n          | {\n              type: 'VAULT_CLOSE_OUT'\n              vaultCloseDetail: any\n            }\n          | {\n              type: 'VAULT_CONVERT'\n              status: 'success' | 'processing' | 'failed'\n              totalValueInCurrency: string\n              convertedInUSDT: string\n              repaymentInUSDT: string\n              time: number\n              dusts: Array<{\n                symbol: string\n                coinJSON: any\n                amount: string\n                valueInCurrency: string\n              }>\n            }\n      }\n    | { isShow: false }\n  >({\n    isShow: false,\n  })\n\n  const onItemClick = (item: R) => {\n\n    setShowDetail((_state: any) => {\n      const {\n        raw_data: { operation, order },\n      } = item\n      const statusColor = [\n        sdk.VaultOperationStatus.VAULT_STATUS_SUCCEED,\n        'VAULT_STATUS_EARNING',\n      ].includes(operation.status)\n        ? 'var(--color-success)'\n        : [\n            sdk.VaultOperationStatus.VAULT_STATUS_PENDING,\n            sdk.VaultOperationStatus.VAULT_STATUS_PROCESSING,\n          ].includes(operation.status)\n        ? 'var(--color-primary)'\n        : operation.status === sdk.VaultOperationStatus.VAULT_STATUS_FAILED\n        ? 'var(--color-error)'\n        : 'var(--color-text-primary)'\n      const statusType = [\n        sdk.VaultOperationStatus.VAULT_STATUS_SUCCEED,\n        'VAULT_STATUS_EARNING',\n      ].includes(operation.status)\n        ? 'success'\n        : [\n            sdk.VaultOperationStatus.VAULT_STATUS_PENDING,\n            sdk.VaultOperationStatus.VAULT_STATUS_PROCESSING,\n          ].includes(operation.status)\n        ? 'processing'\n        : operation.status === sdk.VaultOperationStatus.VAULT_STATUS_FAILED\n        ? 'failed'\n        : 'processing'\n      const statusLabel = t2(`labelVault${operation.status}`)\n      switch (operation.operateType) {\n        case 'VAULT_BORROW':\n        case 'VAULT_MARGIN_CALL':\n        case 'VAULT_JOIN_REDEEM':\n        case 'VAULT_REPAY':\n        case 'VAULT_CLOSE_SHORT':\n        case 'VAULT_OPEN_POSITION': {\n          const collateralToken = tokenMap[idIndex[operation.tokenIn]]\n          let amount, amountSymbol: string \n          if (operation.operateType === 'VAULT_BORROW' ) {\n            const vAmountToken = vaultTokenMap[vaultIdIndex[operation.tokenOut]]\n            amount = getValuePrecisionThousand(\n              sdk.toBig(operation.amountOut ?? 0).div('1e' + vAmountToken.decimals),\n              vAmountToken.precision,\n              vAmountToken.precision,\n              undefined,\n              false,\n              {\n                floor: false,\n              },\n            )\n            amountSymbol = vAmountToken && vAmountToken.symbol.slice(2)\n          } else if (operation.operateType === 'VAULT_REPAY' || operation.operateType === 'VAULT_CLOSE_SHORT') {\n            const vAmountToken = vaultTokenMap[vaultIdIndex[operation.tokenIn]]\n            amount = getValuePrecisionThousand(\n              sdk.toBig(operation.amountIn ?? 0).div('1e' + vAmountToken.decimals).abs(),\n              vAmountToken.precision,\n              vAmountToken.precision,\n              undefined,\n              false,\n              {\n                floor: false,\n              },\n            )\n            amountSymbol = vAmountToken && vAmountToken.symbol.slice(2)\n          } else {\n            const amountToken = tokenMap[idIndex[operation.tokenIn]]\n            amount = getValuePrecisionThousand(\n              sdk.toBig(operation.amountIn ?? 0).div('1e' + amountToken.decimals).abs(),\n              amountToken.precision,\n              amountToken.precision,\n              undefined,\n              false,\n              {\n                floor: false,\n              },\n            )\n            amountSymbol = amountToken && amountToken.symbol\n          }\n          return {\n            isShow: true,\n            detail: {\n              type: operation.operateType,\n              time: operation && operation.createdAt,\n              statusColor,\n              statusLabel,\n              statusType,\n              amount: amount,\n              amountSymbol: amountSymbol\n            },\n          }\n        }\n        case 'VAULT_CLOSE_OUT': {\n          const profit =\n            (operation as any).accountType === 0 \n            ? (operation?.totalEquity && operation?.Collateral\n              ? sdk.toBig(operation?.totalEquity ?? 0).minus(operation?.Collateral ?? 0)\n              : undefined)\n            : (operation as any)?.profit as string\n          const outTokenInfo = tokenMap[idIndex[operation.tokenOut]]\n          const amount = sdk.toBig(operation.amountOut).div('1e' + outTokenInfo.decimals)\n\n          return {\n            isShow: true,\n            detail: {\n              ...item,\n              type: 'VAULT_CLOSE_OUT',\n              vaultCloseDetail: {\n                statusType,\n                statusLabel,\n                status: t(`labelVault${operation.status}`),\n                amount: amount.gte(0)\n                  ? getValuePrecisionThousand(\n                      amount,\n                      outTokenInfo.precision,\n                      outTokenInfo.precision,\n                      outTokenInfo.precision,\n                      true,\n                      { floor: true },\n                    ) +\n                    ' ' +\n                    mapSpecialTokenName(outTokenInfo.symbol)\n                  : EmptyValueTag,\n                executionHistory: operation?.executionHistory,\n                profit: profit\n                  ? PriceTag[CurrencyToTag[currency]] +\n                    getValuePrecisionThousand(\n                      sdk.toBig(profit).times(forexMap[currency] ?? 0),\n                      2,\n                      2,\n                      2,\n                      true,\n                      { floor: true },\n                    )\n                  : EmptyValueTag,\n                profitPercent:\n                  profit && Number(operation?.Collateral ?? 0)\n                    ? numberFormat(new Decimal(profit.toString()).div(operation?.Collateral).times(100).toString(), {fixed: 2}) + '%'\n                    : EmptyValueTag,\n                usdValue: operation?.totalBalance\n                  ? PriceTag[CurrencyToTag[currency]] +\n                    getValuePrecisionThousand(\n                      sdk.toBig(operation?.totalBalance ?? 0).times(forexMap[currency] ?? 0),\n                      2,\n                      2,\n                      2,\n                      true,\n                      { floor: true },\n                    )\n                  : EmptyValueTag,\n                usdDebt: operation?.totalDebt\n                  ? PriceTag[CurrencyToTag[currency]] +\n                    getValuePrecisionThousand(\n                      sdk.toBig(operation?.totalDebt ?? 0).times(forexMap[currency] ?? 0),\n                      2,\n                      2,\n                      2,\n                      true,\n                      { floor: true },\n                    )\n                  : EmptyValueTag,\n                usdEquity: operation?.totalEquity\n                  ? PriceTag[CurrencyToTag[currency]] +\n                    getValuePrecisionThousand(\n                      sdk.toBig(operation?.totalEquity ?? 0).times(forexMap[currency] ?? 0),\n                      2,\n                      2,\n                      2,\n                      true,\n                      { floor: true },\n                    )\n                  : EmptyValueTag,\n                forexMap,\n                tokenSymbol: outTokenInfo.symbol,\n                isForcedLiqudation:\n                  (item.raw_data.operation.operateSubType as string) === 'VAULT_FORCE_SETTLEMENT' ||\n                  (item.raw_data.operation.operateSubType as string) === 'VAULT_FORCE_WITHDRAW',\n              },\n            },\n          }\n        }\n        case 'VAULT_TRADE': {\n          const vTokenSellInfo = (vaultTokenMap && vaultIdIndex) ? vaultTokenMap[vaultIdIndex[order.tokenS]] : undefined\n          const vTokenBuyInfo = (vaultTokenMap && vaultIdIndex) ? vaultTokenMap[vaultIdIndex[order.tokenB]] : undefined\n\n          return {\n            isShow: true,\n            detail: {\n              type: 'VAULT_TRADE',\n              statusColor,\n              statusLabel,\n              statusType,\n              fromSymbol: vTokenSellInfo && vTokenSellInfo.symbol.slice(2),\n              toSymbol: vTokenBuyInfo && vTokenBuyInfo.symbol.slice(2),\n              placedAmount: vTokenSellInfo && getValuePrecisionThousand(\n                sdk.toBig(order.amountS).div('1e' + vTokenSellInfo.decimals),\n                vTokenSellInfo.precision,\n                vTokenSellInfo.precision,\n                undefined,\n                false,\n                {\n                  floor: false,\n                },\n              ),\n              executedAmount: vTokenSellInfo && getValuePrecisionThousand(\n                sdk.toBig(order.fillAmountS).div('1e' + vTokenSellInfo.decimals),\n                vTokenSellInfo.precision,\n                vTokenSellInfo.precision,\n                undefined,\n                false,\n                {\n                  floor: false,\n                },\n              ),\n              executedRate:\n                sdk.toBig(order.fillAmountS).div(order.amountS).multipliedBy('100').toFixed(2) +\n                '%',\n              convertedAmount: vTokenBuyInfo && getValuePrecisionThousand(\n                sdk.toBig(order.fillAmountB).div('1e' + vTokenBuyInfo.decimals),\n                vTokenBuyInfo.precision,\n                vTokenBuyInfo.precision,\n                undefined,\n                false,\n                {\n                  floor: false,\n                },\n              ),\n              price: order.price,\n              feeSymbol: vTokenBuyInfo && vTokenBuyInfo.symbol.slice(2),\n              feeAmount: vTokenBuyInfo && getValuePrecisionThousand(\n                sdk.toBig(order.fee).div('1e' + vTokenBuyInfo.decimals),\n                vTokenBuyInfo.precision,\n                vTokenBuyInfo.precision,\n                undefined,\n                false,\n                {\n                  floor: false,\n                },\n              ),\n              time: order.createdAt,\n            },\n          }\n        }\n        case 'VAULT_CONVERT': {\n          const executionHistory = (operation as any).executionHistory as string[]\n          const dustList : {\n            symbol: string;\n            coinJSON: any;\n            amount: string;\n            amountRaw: string;\n            valueInCurrency: string | undefined;\n            valueInCurrencyRaw: string | undefined;\n            buyAmount: string | undefined;\n          }[] = executionHistory.map(item => {\n            const itemObj = JSON.parse(item)\n            const {\n              tokenIn,\n              amountIn,\n              amountOut,\n              tokenOut,\n            } = itemObj\n            const vTokenSellInfo = vaultTokenMap[vaultIdIndex[tokenIn]]\n            const vTokenBuyInfo = vaultTokenMap[vaultIdIndex[tokenOut]]\n            const amount = numberFormat(utils.formatUnits(amountIn, vTokenSellInfo.decimals), {fixed: vTokenSellInfo.precision, removeTrailingZero: true})\n            const buyAmount = numberFormat(utils.formatUnits(amountOut, vTokenBuyInfo.decimals), {fixed: vTokenBuyInfo.precision, removeTrailingZero: true})\n            const sellTokenPrice = vaultTokenPrices[vTokenSellInfo.symbol]\n            return {\n              symbol: vTokenSellInfo.symbol.slice(2),\n              coinJSON: coinJson[vTokenSellInfo.symbol.slice(2)],\n              amount,\n              amountRaw: amountIn,\n              valueInCurrency: fiatNumberDisplay(\n                getValueInCurrency(new Decimal(amount).times(sellTokenPrice).toString()),\n                currency\n              ),\n              valueInCurrencyRaw: getValueInCurrency(new Decimal(amount).times(sellTokenPrice).toString()),\n              buyAmount,\n            }\n          })\n\n          return {\n            isShow: true,\n            detail: {\n              type: 'VAULT_CONVERT',\n              statusColor,\n              statusLabel,\n              statusType,\n              status: operation.status === sdk.VaultOperationStatus.VAULT_STATUS_SUCCEED ? 'success' : operation.status === sdk.VaultOperationStatus.VAULT_STATUS_FAILED ? 'failed' : 'processing',\n              totalValueInCurrency: fiatNumberDisplay(numberStringListSum(dustList.map(dust => dust.valueInCurrencyRaw ?? '0')), currency),\n              convertedInUSDT: numberFormat(numberStringListSum(dustList.map(dust => dust.valueInCurrencyRaw ?? '0')), {fixed: 2}),\n              repaymentInUSDT: numberFormat(numberStringListSum(dustList.map(dust => dust.buyAmount ?? '0')), {fixed: 2}), \n              time: operation.createdAt,\n              dusts: dustList,\n            },\n          }\n        }\n\n        default: {\n          throw 'err'\n        }\n      }\n    })\n  }\n  return {\n    getVaultOrderList,\n    vaultOrderData,\n    totalNum,\n    showLoading,\n    onItemClick,\n    vaultOperationDetail: detail.isShow ? detail.detail : undefined,\n    openVaultDetail: detail.isShow,\n    onVaultDetailClose: () =>\n      setShowDetail({\n        isShow: false,\n      }),\n  }\n}"
  },
  {
    "path": "packages/web-earn/src/pages/AssetPage/HistoryPanel/index.tsx",
    "content": "import React from 'react'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport { Box, Divider, Tab, Tabs, Typography } from '@mui/material'\nimport {\n  AmmTable,\n  BtradeSwapTable,\n  Button,\n  DefiTxsTable,\n  DualTxsTable,\n  ModalCloseButton,\n  OrderHistoryTable,\n  SwitchPanelStyled,\n  TaikoTarmingTxRecordsTable,\n  Toast,\n  ToastType,\n  TradeTable,\n  TransactionTable,\n  VaultTxTable,\n  useSettings,\n  useToggle,\n} from '@loopring-web/component-lib'\nimport {\n  StylePaper,\n  useAccount,\n  useAmmMap,\n  useGetOrderHistorys,\n  useSystem,\n  useToast,\n  useTokenMap,\n} from '@loopring-web/core'\nimport {\n  useBtradeTransaction,\n  useTaikoFarmingRecord,\n  useDualTransaction,\n  useGetAmmRecord,\n  useGetDefiRecord,\n  useGetLeverageETHRecord,\n  useGetTrades,\n  useGetTxs,\n  useOrderList,\n  useVaultTransaction,\n} from './hooks'\nimport {\n  BackIcon,\n  MapChainId,\n  RecordTabIndex,\n  RowConfig,\n  TOAST_TIME,\n  TabOrderIndex,\n} from '@loopring-web/common-resources'\nimport { useHistory, useLocation, useRouteMatch } from 'react-router-dom'\nimport { RecordEarnMap } from '../../../constant/router'\nimport { Modal } from '@mui/material'\nimport { VaultCloseDetail, VaultConvertDetail, VaultOperationDetail, VaultTradeDetail } from '@loopring-web/component-lib/src/components/tableList/vaultTable/VaultTxTable'\nimport Decimal from 'decimal.js'\n\n\n\nconst HistoryPanel = withTranslation('common')((rest: WithTranslation<'common'>) => {\n  const history = useHistory()\n  const { search } = useLocation()\n  const { isMobile, defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const {\n    toggle: { StopLimit, taikoFarming },\n  } = useToggle()\n  const match: any = useRouteMatch('/l2assets/:history/:tab/:orderTab?')\n  const [pageSize, setPageSize] = React.useState(0)\n  const [currentTab, setCurrentTab] = React.useState<RecordTabIndex>(() => {\n    let item = match?.params?.tab ?? RecordTabIndex.Transactions\n    return RecordEarnMap[network]?.includes(item) ? item : RecordTabIndex.Transactions\n  })\n  const [currentOrderTab, setCurrentOrderTab] = React.useState(() => {\n    return match?.params?.orderTab ?? TabOrderIndex.orderOpenTable\n  })\n\n  const { toastOpen, setToastOpen, closeToast } = useToast()\n  const { totalCoinMap, tokenMap, idIndex, marketArray } = useTokenMap()\n  const { ammMap } = useAmmMap()\n\n  const {\n    txs: txTableData,\n    txsTotal,\n    showLoading: showTxsLoading,\n    getUserTxnList,\n    searchValue,\n  } = useGetTxs(setToastOpen)\n  const {\n    userTrades,\n    getUserTradeList,\n    userTradesTotal,\n    page: tradePage,\n    showLoading: showTradeLoading,\n  } = useGetTrades(setToastOpen)\n  const {\n    defiList,\n    showLoading: showDefiLoading,\n    getDefiTxList,\n    defiTotal,\n  } = useGetDefiRecord(setToastOpen)\n  const {\n    ammRecordList,\n    showLoading: showAmmloading,\n    ammRecordTotal,\n    getAmmpoolList,\n  } = useGetAmmRecord(setToastOpen)\n  const {\n    rawData,\n    getOrderList,\n    totalNum,\n    showLoading,\n    marketArray: orderRaw,\n    cancelOrder,\n  } = useOrderList({ setToastOpen })\n  const {\n    rawData: stopLimitRawData,\n    getOrderList: getStopLimitOrderList,\n    totalNum: totalNumStopLimit,\n    showLoading: showLoadingStopLimit,\n    cancelOrder: cancelOrderStopLimit,\n  } = useOrderList({ setToastOpen, isStopLimit: true })\n\n  const {\n    dualList,\n    showLoading: showDualLoading,\n    getDualTxList,\n    dualMarketMap,\n    dualTotal,\n  } = useDualTransaction(setToastOpen)\n  const {\n    sideStakingList,\n    showLoading: showDefiSideStakingLoading,\n    getSideStakingTxList,\n    sideStakingTotal,\n  } = useTaikoFarmingRecord(setToastOpen)\n  const {\n    leverageETHList,\n    showLoading: showLeverageETHLoading,\n    getLeverageETHTxList,\n    leverageETHTotal,\n  } = useGetLeverageETHRecord(setToastOpen)\n\n  const { userOrderDetailList, getUserOrderDetailTradeList } = useGetOrderHistorys()\n  const { etherscanBaseUrl } = useSystem()\n  const {\n    getVaultOrderList,\n    vaultOrderData,\n    totalNum: vaultTotal,\n    showLoading: showVaultLoaning,\n    onItemClick: onVaultDetail,\n    vaultOperationDetail,\n    openVaultDetail,\n    onVaultDetailClose,\n  } = useVaultTransaction(setToastOpen)\n\n  const {\n    getBtradeOrderList,\n    btradeOrderData,\n    onDetail,\n    totalNum: btradeTotalNum,\n    showLoading: showBtradeLoading,\n  } = useBtradeTransaction(setToastOpen)\n\n  const {\n    account: { accAddress, accountId },\n  } = useAccount()\n\n  const { t } = rest\n  const container = React.useRef<HTMLDivElement>(null)\n\n  const handleTabChange = React.useCallback(\n    (value: RecordTabIndex, _pageSize?: number) => {\n      setCurrentTab(value)\n      history.replace(`/l2assets/history/${value}?${search.replace('?', '')}`)\n    },\n    [history, search],\n  )\n  React.useEffect(() => {\n    let height = container?.current?.offsetHeight\n    if (height) {\n      const pageSize = Math.floor((height - 120) / RowConfig.rowHeight) - 3\n      setPageSize(Math.floor((height - 120) / RowConfig.rowHeight) - 3)\n      handleTabChange(currentTab, pageSize)\n    }\n  }, [container?.current?.offsetHeight])\n  // React.useEffect(()=>{},[])\n  return (\n    <Box flex={1} display={'flex'} flexDirection={'column'}>\n      <Box marginBottom={2}>\n        <Button\n          startIcon={<BackIcon fontSize={'small'} />}\n          variant={'text'}\n          size={'medium'}\n          sx={{ color: 'var(--color-text-secondary)' }}\n          color={'inherit'}\n          onClick={history.goBack}\n        >\n          {t('labelTransactions')}\n          {/*<Typography color={\"textPrimary\"}></Typography>*/}\n        </Button>\n      </Box>\n      {/*<IconButton*/}\n      {/*  className={\"back-btn\"}*/}\n      {/*  size={\"large\"}*/}\n      {/*  color={\"inherit\"}*/}\n      {/*  aria-label={t && t(\"labelBack\")}*/}\n      {/*  onClick={() => {*/}\n      {/*    onBack && onBack();*/}\n      {/*  }}*/}\n      {/*>*/}\n      {/*  <BackIcon />*/}\n      {/*</IconButton>*/}\n      <StylePaper ref={container} flex={1}>\n        <Toast\n          alertText={toastOpen?.content ?? ''}\n          severity={toastOpen?.type ?? ToastType.success}\n          open={toastOpen?.open ?? false}\n          autoHideDuration={TOAST_TIME}\n          onClose={closeToast}\n        />\n        <Box\n          marginTop={2}\n          display={'flex'}\n          sx={isMobile ? { maxWidth: 'calc(100vw - 32px)' } : {}}\n        >\n          <Tabs\n            value={currentTab}\n            onChange={(_event, value) => handleTabChange(value)}\n            aria-label='l2-history-tabs'\n            variant='scrollable'\n          >\n            {RecordEarnMap[network].filter((item) => {\n              if (item === RecordTabIndex.TaikoLockRecords) {\n                return taikoFarming.enable\n              } else {\n                return true\n              }\n            })?.map((item) => {\n              return <Tab key={item} label={t(`labelLayer2History${item}`)} value={item} />\n            })}\n          </Tabs>\n        </Box>\n        <Box\n          className='tableWrapper table-divide-short'\n          display={'flex'}\n          flex={1}\n          overflow={'auto'}\n        >\n          {currentTab === RecordTabIndex.Transactions ? (\n            <TransactionTable\n              {...{\n                etherscanBaseUrl,\n                rawData: txTableData,\n                searchValue,\n                pagination: {\n                  pageSize: pageSize,\n                  total: txsTotal,\n                },\n                filterTokens: totalCoinMap ? (Reflect.ownKeys(totalCoinMap) as string[]) : [],\n                showFilter: true,\n                showloading: showTxsLoading,\n                getTxnList: getUserTxnList,\n                accAddress,\n                accountId,\n                ...rest,\n              }}\n            />\n          ) : currentTab === RecordTabIndex.Trades ? (\n            <TradeTable\n              getUserTradeList={getUserTradeList}\n              {...{\n                rawData: userTrades,\n                showFilter: true,\n                filterPairs: marketArray,\n                showloading: showTradeLoading,\n                tokenMap: tokenMap,\n                isL2Trade: true,\n                pagination: {\n                  page: tradePage,\n                  pageSize: pageSize,\n                  total: userTradesTotal,\n                },\n                accAddress,\n                accountId,\n                ...rest,\n              }}\n            />\n          ) : currentTab === RecordTabIndex.AmmRecords ? (\n            <AmmTable\n              {...{\n                rawData: ammRecordList,\n                pagination: {\n                  pageSize: pageSize,\n                  total: ammRecordTotal,\n                },\n                getAmmpoolList,\n                showFilter: true,\n                filterPairs: Reflect.ownKeys(ammMap ?? {}).map((item) =>\n                  item.toString().replace('AMM', 'LP'),\n                ),\n                showloading: showAmmloading,\n                ...rest,\n              }}\n            />\n          ) : currentTab === RecordTabIndex.DefiRecords ? (\n            <DefiTxsTable\n              key={'defi'}\n              {...{\n                rawData: defiList,\n                pagination: {\n                  pageSize: pageSize,\n                  total: defiTotal,\n                },\n                getDefiTxList,\n                showloading: showDefiLoading,\n                ...rest,\n              }}\n              tokenMap={tokenMap}\n              idIndex={idIndex}\n            />\n          ) : currentTab === RecordTabIndex.SideStakingRecords ? (\n            <></>\n          ) : currentTab === RecordTabIndex.DualRecords ? (\n            <DualTxsTable\n              rawData={dualList}\n              getDualTxList={getDualTxList}\n              pagination={{\n                pageSize: pageSize + 2,\n                total: dualTotal,\n              }}\n              dualMarketMap={dualMarketMap}\n              showloading={showDualLoading}\n              tokenMap={tokenMap}\n              idIndex={idIndex}\n              {...{\n                ...rest,\n              }}\n            />\n          ) : currentTab === RecordTabIndex.Orders ? (\n            <Box flex={1} display={'flex'} flexDirection={'column'} marginTop={-2}>\n              <Box marginBottom={2} marginLeft={3}>\n                <Tabs\n                  value={currentOrderTab}\n                  onChange={(_event, value) => {\n                    setCurrentOrderTab(value)\n                    history.replace(\n                      `/l2assets/history/${RecordTabIndex.Orders}/${value}?${search.replace(\n                        '?',\n                        '',\n                      )}`,\n                    )\n                  }}\n                  aria-label='l2-history-tabs'\n                  variant='scrollable'\n                >\n                  <Tab label={t('labelOrderTableOpenOrder')} value={TabOrderIndex.orderOpenTable} />\n                  <Tab\n                    label={t('labelOrderTableOrderHistory')}\n                    value={TabOrderIndex.orderHistoryTable}\n                  />\n                </Tabs>\n              </Box>\n\n              <OrderHistoryTable\n                {...{\n                  pagination:\n                    currentOrderTab === TabOrderIndex.orderOpenTable\n                      ? undefined\n                      : {\n                          pageSize: pageSize - 1,\n                          total: totalNum,\n                        },\n                  rawData,\n                  showFilter: true,\n                  getOrderList,\n                  marketArray: orderRaw,\n                  showDetailLoading: false,\n                  userOrderDetailList,\n                  getUserOrderDetailTradeList,\n                  ...rest,\n                  showLoading,\n                  isOpenOrder: currentOrderTab === TabOrderIndex.orderOpenTable,\n                  cancelOrder,\n                }}\n              />\n            </Box>\n          ) : currentTab === RecordTabIndex.StopLimitRecords ? (\n            <Box flex={1} display={'flex'} flexDirection={'column'} marginTop={-2}>\n              <>\n                <Box marginBottom={2} marginLeft={3}>\n                  <Tabs\n                    value={currentOrderTab}\n                    onChange={(_event, value) => {\n                      setCurrentOrderTab(value)\n                      history.replace(\n                        `/l2assets/history/${\n                          RecordTabIndex.StopLimitRecords\n                        }/${value}?${search.replace('?', '')}`,\n                      )\n                    }}\n                    aria-label='l2-history-tabs'\n                    variant='scrollable'\n                  >\n                    <Tab\n                      label={t('labelOrderTableOpenOrder')}\n                      value={TabOrderIndex.orderOpenTable}\n                    />\n                    <Tab\n                      label={t('labelOrderTableOrderHistory')}\n                      value={TabOrderIndex.orderHistoryTable}\n                    />\n                  </Tabs>\n                </Box>\n\n                <OrderHistoryTable\n                  {...{\n                    pagination:\n                      currentOrderTab === TabOrderIndex.orderOpenTable\n                        ? undefined\n                        : {\n                            pageSize: pageSize - 1,\n                            total: totalNumStopLimit,\n                          },\n                    isStopLimit: true,\n                    rawData: stopLimitRawData,\n                    showFilter: true,\n                    getOrderList: getStopLimitOrderList,\n                    marketArray: orderRaw,\n                    showDetailLoading: false,\n                    userOrderDetailList,\n                    getUserOrderDetailTradeList,\n                    ...rest,\n                    showLoading: showLoadingStopLimit,\n                    isOpenOrder: currentOrderTab === TabOrderIndex.orderOpenTable,\n                    cancelOrder: cancelOrderStopLimit,\n                  }}\n                />\n              </>\n            </Box>\n          ) : currentTab === RecordTabIndex.BtradeSwapRecords ? (\n            <Box flex={1} display={'flex'} flexDirection={'column'} marginTop={-2}>\n              <BtradeSwapTable\n                {...{\n                  showloading: showBtradeLoading,\n                  getBtradeOrderList,\n                  rawData: btradeOrderData,\n                }}\n                pagination={{\n                  pageSize: pageSize,\n                  total: btradeTotalNum,\n                }}\n                onItemClick={onDetail}\n              />\n            </Box>\n          ) : currentTab === RecordTabIndex.leverageETHRecords ? (\n            <DefiTxsTable\n              key={'leverage'}\n              {...{\n                rawData: leverageETHList,\n                pagination: {\n                  pageSize: pageSize,\n                  total: leverageETHTotal,\n                },\n                getDefiTxList: getLeverageETHTxList,\n                showloading: showLeverageETHLoading,\n                ...rest,\n              }}\n              tokenMap={tokenMap}\n              idIndex={idIndex}\n            />\n          ) : currentTab === RecordTabIndex.VaultRecords ? (\n            <>\n              <Modal\n                open={openVaultDetail}\n                onClose={onVaultDetailClose}\n                aria-labelledby='modal-modal-title'\n                aria-describedby='modal-modal-description'\n              >\n                <SwitchPanelStyled width={'var(--modal-width)'}>\n                  <ModalCloseButton onClose={onVaultDetailClose} t={t} />\n                  <Box\n                    display={'flex'}\n                    flexDirection={'column'}\n                    alignItems={'flex-start'}\n                    alignSelf={'stretch'}\n                    marginTop={-4}\n                    justifyContent={'stretch'}\n                  >\n                    <Typography\n                      display={'flex'}\n                      flexDirection={'row'}\n                      component={'header'}\n                      alignItems={'center'}\n                      height={'var(--toolbar-row-height)'}\n                      paddingX={3}\n                    >\n                      <Typography component={'span'} display={'inline-flex'}>\n                        {vaultOperationDetail &&\n                          (vaultOperationDetail.type === 'VAULT_BORROW'\n                            ? t('labelBorrowDetail')\n                            : vaultOperationDetail.type === 'VAULT_MARGIN_CALL'\n                            ? t('labelMarginCallDetail')\n                            : vaultOperationDetail.type === 'VAULT_OPEN_POSITION'\n                            ? t('labelVaultJoin')\n                            : vaultOperationDetail.type === 'VAULT_REPAY'\n                            ? t('labelRepayDetail')\n                            : vaultOperationDetail.type === 'VAULT_TRADE'\n                            ? t('labelTradeDetail')\n                            : vaultOperationDetail.type === 'VAULT_CONVERT'\n                            ? t('labelDustCollectorDetail')\n                            : vaultOperationDetail.type === 'VAULT_JOIN_REDEEM'\n                            ? t('labelVaultJoinRedeem')\n                            : vaultOperationDetail.type === 'VAULT_CLOSE_SHORT' \n                            ? 'Close Short'\n                            : t('labelCloseOutDetail'))\n                            }\n                      </Typography>\n                    </Typography>\n                    <Divider style={{ marginTop: '-1px', width: '100%' }} />\n                  </Box>\n                  <Box\n                    sx={{\n                      flex: 1,\n                      paddingY: 2,\n                      width: '100%',\n                      display: 'flex',\n                      flexDirection: 'column',\n                      maxHeight: isMobile ? 'initial' : '75vh',\n                      overflowY: isMobile ? 'initial' : 'auto',\n                    }}\n                  >\n                    {vaultOperationDetail &&\n                      (vaultOperationDetail.type === 'VAULT_BORROW' ||\n                        vaultOperationDetail.type === 'VAULT_MARGIN_CALL' ||\n                        vaultOperationDetail.type === 'VAULT_OPEN_POSITION' ||\n                        vaultOperationDetail.type === 'VAULT_JOIN_REDEEM' ||\n                        vaultOperationDetail.type === 'VAULT_REPAY' ||\n                        vaultOperationDetail.type === 'VAULT_CLOSE_SHORT') && (\n                        <VaultOperationDetail\n                          statusColor={vaultOperationDetail.statusColor}\n                          statusLabel={vaultOperationDetail.statusLabel}\n                          time={vaultOperationDetail.time}\n                          type={vaultOperationDetail.type}\n                          statusType={vaultOperationDetail.statusType}\n                          amount={vaultOperationDetail.amount ? vaultOperationDetail.amount : ''}\n                          amountSymbol={vaultOperationDetail.amountSymbol}\n                        />\n                      )}\n                    {vaultOperationDetail && vaultOperationDetail.type === 'VAULT_CLOSE_OUT' && (\n                      <VaultCloseDetail\n                        vaultCloseDetail={vaultOperationDetail.vaultCloseDetail}\n                      />\n                    )}\n                    {vaultOperationDetail && vaultOperationDetail.type === 'VAULT_TRADE' && (\n                      <VaultTradeDetail\n                        statusColor={vaultOperationDetail.statusColor}\n                        statusLabel={vaultOperationDetail.statusLabel}\n                        fromSymbol={vaultOperationDetail.fromSymbol}\n                        toSymbol={vaultOperationDetail.toSymbol}\n                        placedAmount={vaultOperationDetail.placedAmount}\n                        executedAmount={vaultOperationDetail.executedAmount}\n                        executedRate={vaultOperationDetail.executedRate}\n                        convertedAmount={vaultOperationDetail.convertedAmount}\n                        price={vaultOperationDetail.price}\n                        feeSymbol={vaultOperationDetail.feeSymbol}\n                        feeAmount={vaultOperationDetail.feeAmount}\n                        time={vaultOperationDetail.time}\n                        statusType={vaultOperationDetail.statusType}\n                      />\n                    )}\n                    {vaultOperationDetail && vaultOperationDetail.type === 'VAULT_CONVERT' && (\n                      <VaultConvertDetail\n                        totalValueInCurrency={vaultOperationDetail.totalValueInCurrency}\n                        convertedInUSDT={vaultOperationDetail.convertedInUSDT}\n                        repaymentInUSDT={vaultOperationDetail.repaymentInUSDT}\n                        time={vaultOperationDetail.time}\n                        dusts={vaultOperationDetail.dusts}\n                        status={vaultOperationDetail.status}\n                      />\n                    )}\n                  </Box>\n                </SwitchPanelStyled>\n              </Modal>\n              <Box flex={1} display={'flex'} flexDirection={'column'} marginTop={-2}>\n                <VaultTxTable\n                  {...{\n                    showloading: showVaultLoaning,\n                    getOrderList: getVaultOrderList,\n                    rawData: vaultOrderData,\n                    onItemClick: onVaultDetail,\n                  }}\n                  pagination={{\n                    pageSize: pageSize,\n                    total: vaultTotal,\n                  }}\n                />\n              </Box>\n            </>\n          ) : currentTab === RecordTabIndex.TaikoLockRecords ? (\n            <TaikoTarmingTxRecordsTable\n              {...{\n                rawData: sideStakingList as any[],\n                pagination: {\n                  pageSize: pageSize,\n                  total: sideStakingTotal,\n                },\n                getSideStakingTxList,\n                showloading: showDefiSideStakingLoading,\n                ...rest,\n              }}\n              tokenMap={tokenMap}\n              idIndex={idIndex}\n            />\n          ) : (\n            <></>\n          )}\n        </Box>\n      </StylePaper>\n    </Box>\n  )\n})\n\nexport default HistoryPanel\n"
  },
  {
    "path": "packages/web-earn/src/pages/AssetPage/HistoryPanel/useDualAsset.tsx",
    "content": "import {\n  LoopringAPI,\n  makeDualOrderedItem,\n  makeDualViewItem,\n  store,\n  useAccount,\n  useDualEdit,\n  useDualMap,\n  useTokenMap,\n  useTradeDual,\n} from '@loopring-web/core'\nimport React from 'react'\nimport {\n  CompleteIcon,\n  DualViewInfo,\n  EmptyValueTag,\n  getValuePrecisionThousand,\n  myLog,\n  SDK_ERROR_MAP_TO_UI,\n  WaitingIcon,\n  WarningIcon,\n} from '@loopring-web/common-resources'\nimport {\n  DualDetailType,\n  LABEL_INVESTMENT_STATUS_MAP,\n  RawDataDualAssetItem,\n  ToastType,\n} from '@loopring-web/component-lib'\nimport { useTranslation } from 'react-i18next'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { DUAL_TYPE, LABEL_INVESTMENT_STATUS } from '@loopring-web/loopring-sdk'\nimport BigNumber from 'bignumber.js'\nimport _ from 'lodash'\nimport { Tooltip, Typography } from '@mui/material'\n\nexport const Limit = 15\n\nexport const useDualAsset = <R extends RawDataDualAssetItem>(\n  setToastOpen?: (props: any) => void,\n) => {\n  const { t } = useTranslation(['common', 'error'])\n  const {\n    account: { accountId, apiKey },\n  } = useAccount()\n  const { updateEditDual } = useTradeDual()\n  const { tokenMap, idIndex } = useTokenMap()\n  const { marketMap: dualMarketMap } = useDualMap()\n  const [dualList, setDualList] = React.useState<R[]>([])\n  const [dualOnInvestAsset, setDualOnInvestAsset] = React.useState<any>(undefined)\n  const [pagination, setDualPagination] = React.useState<{\n    pageSize: number\n    total: number\n  }>({\n    pageSize: Limit,\n    total: 0,\n  })\n  const [showLoading, setShowLoading] = React.useState(true)\n  const [open, setOpen] = React.useState<boolean>(false)\n  const [detail, setDetail] = React.useState<DualDetailType | undefined>(undefined)\n  const [showRefreshError, setShowRefreshError] = React.useState<boolean>(false)\n  const [refreshErrorInfo, setRefreshErrorInfo] = React.useState<[string, string]>(['', ''])\n\n  const getDetail = (item: R, index?: number) => {\n    let {\n      sellSymbol,\n      buySymbol,\n      settleRatio,\n      __raw__: {\n        order: {\n          strike,\n          settlementStatus,\n          tokenInfoOrigin: { amountIn, tokenOut, amountOut, tokenIn },\n          dualReinvestInfo,\n          timeOrigin: { expireTime },\n          investmentStatus,\n          dualType,\n          deliveryPrice,\n        },\n      },\n    } = item\n    let icon: any = undefined,\n      status = ''\n    let content = ''\n    const currentPrice = _.cloneDeep(item.currentPrice)\n    if (index) {\n      currentPrice.currentPrice = index\n    }\n    let lessEarnTokenSymbol, greaterEarnTokenSymbol, lessEarnVol, greaterEarnVol\n    const sellAmount = sdk.toBig(amountIn ? amountIn : 0).div('1e' + tokenMap[sellSymbol].decimals)\n    const side =\n      settlementStatus === sdk.SETTLEMENT_STATUS.PAID\n        ? t(LABEL_INVESTMENT_STATUS_MAP.INVESTMENT_RECEIVED)\n        : Date.now() - expireTime >= 0 &&\n          investmentStatus !== LABEL_INVESTMENT_STATUS.CANCELLED &&\n          investmentStatus !== LABEL_INVESTMENT_STATUS.FAILED\n        ? t(LABEL_INVESTMENT_STATUS_MAP.DELIVERING)\n        : t(LABEL_INVESTMENT_STATUS_MAP.INVESTMENT_SUBSCRIBE)\n    const statusColor =\n      settlementStatus === sdk.SETTLEMENT_STATUS.PAID\n        ? 'var(--color-tag)'\n        : Date.now() - expireTime >= 0 &&\n          investmentStatus !== LABEL_INVESTMENT_STATUS.CANCELLED &&\n          investmentStatus !== LABEL_INVESTMENT_STATUS.FAILED\n        ? 'var(--color-warning)'\n        : 'var(--color-text-primary)'\n    let outSymbol: string | undefined = undefined,\n      outAmount\n\n    if (\n      (settlementStatus === sdk.SETTLEMENT_STATUS.PAID ||\n        (Date.now() - expireTime >= 0 &&\n          investmentStatus !== LABEL_INVESTMENT_STATUS.CANCELLED &&\n          investmentStatus !== LABEL_INVESTMENT_STATUS.FAILED)) &&\n      tokenOut !== undefined &&\n      tokenOut &&\n      tokenOut != 0\n    ) {\n      outSymbol = tokenMap[idIndex[tokenOut]].symbol\n      outAmount = getValuePrecisionThousand(\n        sdk.toBig(amountOut ? amountOut : 0).div('1e' + tokenMap[outSymbol].decimals),\n        tokenMap[outSymbol].precision,\n        tokenMap[outSymbol].precision,\n        tokenMap[outSymbol].precision,\n        false,\n      )\n    }\n    if (dualType === sdk.DUAL_TYPE.DUAL_BASE) {\n      lessEarnTokenSymbol = sellSymbol\n      greaterEarnTokenSymbol = buySymbol\n      lessEarnVol = sdk.toBig(settleRatio).plus(1).times(amountIn) //dualViewInfo.strike);\n      greaterEarnVol = sdk\n        .toBig(\n          sdk\n            .toBig(sellAmount ? sellAmount : 0)\n            .times(strike)\n            .toFixed(tokenMap[buySymbol].precision, BigNumber.ROUND_CEIL),\n        )\n        .times('1e' + tokenMap[buySymbol].decimals)\n    } else {\n      lessEarnTokenSymbol = buySymbol\n      greaterEarnTokenSymbol = sellSymbol\n      lessEarnVol = sdk\n        .toBig(\n          sdk\n            .toBig(sellAmount ? sellAmount : 0)\n            // .times(1 + info.ratio)\n            .div(strike)\n            .toFixed(tokenMap[buySymbol].precision, BigNumber.ROUND_CEIL),\n        )\n        .times('1e' + tokenMap[buySymbol].decimals)\n\n      // sellVol.times(1 + info.ratio).div(dualViewInfo.strike); //.times(1 + dualViewInfo.settleRatio);\n      greaterEarnVol = sdk.toBig(settleRatio).plus(1).times(amountIn)\n    }\n    const lessEarnView = amountIn\n      ? getValuePrecisionThousand(\n          sdk.toBig(lessEarnVol).div('1e' + tokenMap[lessEarnTokenSymbol].decimals),\n          tokenMap[lessEarnTokenSymbol].precision,\n          tokenMap[lessEarnTokenSymbol].precision,\n          tokenMap[lessEarnTokenSymbol].precision,\n          false,\n          { floor: true },\n        )\n      : EmptyValueTag\n    const greaterEarnView = amountIn\n      ? getValuePrecisionThousand(\n          sdk.toBig(greaterEarnVol).div('1e' + tokenMap[greaterEarnTokenSymbol].decimals),\n          tokenMap[greaterEarnTokenSymbol].precision,\n          tokenMap[greaterEarnTokenSymbol].precision,\n          tokenMap[greaterEarnTokenSymbol].precision,\n          false,\n          { floor: true },\n        )\n      : EmptyValueTag\n\n    const amount = getValuePrecisionThousand(\n      sellAmount,\n      tokenMap[sellSymbol].precision,\n      tokenMap[sellSymbol].precision,\n      tokenMap[sellSymbol].precision,\n      false,\n    )\n    switch (dualReinvestInfo.retryStatus) {\n      case sdk.DUAL_RETRY_STATUS.RETRY_SUCCESS:\n        icon = <CompleteIcon color={'success'} sx={{ paddingLeft: 1 / 2 }} />\n        status = 'labelDualRetryStatusSuccess'\n        content = 'labelDualRetrySuccess'\n        break\n      case sdk.DUAL_RETRY_STATUS.RETRY_FAILED:\n        icon = <WarningIcon color={'error'} sx={{ paddingLeft: 1 / 2 }} />\n        status = 'labelDualRetryStatusError'\n        content = 'labelDualRetryFailed'\n        break\n      case sdk.DUAL_RETRY_STATUS.NO_RETRY:\n        if (dualReinvestInfo?.isRecursive) {\n          content = 'labelDualAssetReInvestEnable'\n        } else if (\n          dualReinvestInfo.onceRecursive &&\n          settlementStatus === sdk.SETTLEMENT_STATUS.PAID &&\n          tokenIn !== tokenOut\n        ) {\n          icon = <WaitingIcon color={'primary'} sx={{ paddingLeft: 1 / 2 }} />\n          status = 'labelDualRetryStatusTerminated'\n          content = 'labelDualRetryTerminated'\n        } else {\n          content = 'labelDualAssetReInvestDisable'\n        }\n        break\n      case sdk.DUAL_RETRY_STATUS.RETRYING:\n        icon = <WaitingIcon color={'primary'} sx={{ paddingLeft: 1 / 2 }} />\n        status = 'labelDualRetryStatusRetrying'\n        content = 'labelDualRetryPending'\n        break\n      default:\n        content = dualReinvestInfo?.isRecursive\n          ? 'labelDualAssetReInvestEnable'\n          : 'labelDualAssetReInvestDisable'\n    }\n    return {\n      dualViewInfo: {\n        ...item?.__raw__?.order,\n        ...item,\n        quote: item?.__raw__?.order?.tokenInfoOrigin?.quote,\n        amount: amount + ' ' + sellSymbol,\n        currentPrice,\n        __raw__: item.__raw__,\n        outSymbol,\n        outAmount,\n        side,\n        status: settlementStatus,\n        statusColor,\n        maxDuration: dualReinvestInfo.maxDuration,\n        autoIcon: icon,\n        autoStatus: status,\n        autoContent: t(content),\n        newStrike: dualReinvestInfo.newStrike,\n        deliveryPrice:\n          Date.now() - expireTime >= 0\n            ? deliveryPrice\n              ? getValuePrecisionThousand(\n                  deliveryPrice,\n                  tokenMap[currentPrice.quote]?.precision,\n                  tokenMap[currentPrice.quote]?.precision,\n                  tokenMap[currentPrice.quote]?.precision,\n                  true,\n                  { isFait: true },\n                )\n              : EmptyValueTag\n            : undefined,\n      },\n\n      lessEarnTokenSymbol,\n      greaterEarnTokenSymbol,\n      lessEarnView,\n      greaterEarnView,\n      currentPrice,\n      __raw__: item.__raw__,\n    } as DualDetailType\n  }\n\n  const refresh = async (item: R) => {\n    const hash = item.__raw__.order.hash\n    const currentPrice = item.currentPrice\n    setShowLoading(true)\n    const { marketArray, marketMap: dualMarketMap } = store.getState().invest.dualMap\n    if (LoopringAPI.defiAPI && accountId && apiKey && marketArray?.length) {\n      const [response, responseTotal] = await Promise.all([\n        LoopringAPI.defiAPI.getDualTransactions(\n          {\n            accountId,\n            hashes: hash,\n          } as any,\n          apiKey,\n        ),\n        LoopringAPI.defiAPI.getDualUserLocked(\n          {\n            accountId: accountId,\n            lockTag: [DUAL_TYPE.DUAL_BASE, DUAL_TYPE.DUAL_CURRENCY],\n            //@ts-ignore\n            status: 'LOCKED',\n          },\n          apiKey,\n        ),\n      ])\n      if ((responseTotal as sdk.RESULT_INFO).code || (responseTotal as sdk.RESULT_INFO).message) {\n        setDualOnInvestAsset(undefined)\n      } else {\n        setDualOnInvestAsset(responseTotal.lockRecord)\n      }\n      if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n        const errorItem = SDK_ERROR_MAP_TO_UI[(response as sdk.RESULT_INFO)?.code ?? 700001]\n        if (setToastOpen) {\n          setToastOpen({\n            open: true,\n            type: ToastType.error,\n            content:\n              'error : ' + errorItem\n                ? t(errorItem.messageKey)\n                : (response as sdk.RESULT_INFO).message,\n          })\n        }\n      } else {\n        // @ts-ignore\n        let item = (response as any)?.userDualTxs[0] as sdk.UserDualTxsHistory\n        const [, , coinA, coinB] =\n          (item.tokenInfoOrigin.market ?? 'dual-').match(/(dual-)?(\\w+)-(\\w+)/i) ?? []\n\n        let [sellTokenSymbol, buyTokenSymbol] =\n          item.dualType === DUAL_TYPE.DUAL_BASE\n            ? [\n                coinA ?? idIndex[item.tokenInfoOrigin.tokenIn],\n                coinB ?? idIndex[item.tokenInfoOrigin.tokenOut],\n              ]\n            : [\n                coinB ?? idIndex[item.tokenInfoOrigin.tokenIn],\n                coinA ?? idIndex[item.tokenInfoOrigin.tokenOut],\n              ]\n        const format = makeDualOrderedItem(\n          item,\n          sellTokenSymbol,\n          buyTokenSymbol,\n          currentPrice?.currentPrice ?? 0,\n          dualMarketMap[item.tokenInfoOrigin.market],\n        )\n\n        const amount = getValuePrecisionThousand(\n          sdk.toBig(item.tokenInfoOrigin.amountIn).div('1e' + tokenMap[sellTokenSymbol].decimals),\n          tokenMap[sellTokenSymbol].precision,\n          tokenMap[sellTokenSymbol].precision,\n          tokenMap[sellTokenSymbol].precision,\n          true,\n        )\n        const refreshedRecord = {\n          ...format,\n          amount,\n        } as R\n        if (refreshedRecord.__raw__.order.id === detail?.__raw__.order.id) {\n          setDetail(getDetail(refreshedRecord))\n        }\n        if (\n          refreshedRecord.__raw__.order.investmentStatus === sdk.LABEL_INVESTMENT_STATUS.CANCELLED\n        ) {\n          setDualList((state) => {\n            return state?.filter((x) => {\n              return x.__raw__.order.id !== refreshedRecord.__raw__.order.id\n            })\n          })\n          setRefreshErrorInfo([refreshedRecord.buySymbol, refreshedRecord.sellSymbol])\n          setShowRefreshError(true)\n          setShowLoading(false)\n        } else if (\n          refreshedRecord.__raw__.order.settlementStatus === sdk.SETTLEMENT_STATUS.SETTLED &&\n          !refreshedRecord.__raw__.order.dualReinvestInfo.isRecursive\n        ) {\n          setDualList((state) => {\n            return state?.filter((x) => {\n              return x.__raw__.order.id !== refreshedRecord.__raw__.order.id\n            })\n          })\n          setShowLoading(false)\n        } else {\n          setDualList((state) => {\n            return state.map((x) => {\n              return x.__raw__.order.id === refreshedRecord.__raw__.order.id\n                ? {\n                    ...refreshedRecord,\n                    __raw__: {\n                      ...x.__raw__,\n                      ...refreshedRecord.__raw__,\n                    },\n                  }\n                : x\n            })\n          })\n          setShowLoading(false)\n        }\n      }\n    }\n    setShowLoading(false)\n  }\n\n  const {\n    editDualTrade,\n    editDualBtnInfo,\n    editDualBtnStatus,\n    dualToastOpen,\n    closeDualToast,\n    // setDualTradeData,\n    handleOnchange,\n    onEditDualClick,\n  } = useDualEdit({\n    refresh: (item, dontCloseModal?: boolean) => {\n      refresh(item as any)\n      !dontCloseModal && setOpen(false)\n    },\n  })\n  const showDetail = async (item: R) => {\n    const {\n      __raw__: { index },\n    } = item\n    if (index) {\n      const _item = getDetail(item, index?.index)\n      setDetail(_item)\n      const tradeData = {\n        isRenew: _item?.__raw__?.order?.dualReinvestInfo?.isRecursive,\n        renewDuration: _item?.__raw__?.order?.dualReinvestInfo?.maxDuration / 86400000,\n        renewTargetPrice: _item?.__raw__?.order.dualReinvestInfo.newStrike,\n      }\n      updateEditDual({\n        ...(_item as any),\n        tradeData,\n      })\n      if (_item?.__raw__?.order?.dualReinvestInfo?.isRecursive) {\n        getProduct(_item)\n      }\n      handleOnchange({\n        tradeData,\n      })\n      setOpen(true)\n    }\n  }\n\n  const getDualTxList = React.useCallback(\n    async ({ start, end, offset, limit = Limit }: any) => {\n      setShowLoading(true)\n      const { marketArray, marketMap: dualMarketMap } = store.getState().invest.dualMap\n      if (LoopringAPI.defiAPI && accountId && apiKey && marketArray?.length) {\n        const [response, responseTotal] = await Promise.all([\n          LoopringAPI.defiAPI.getDualTransactions(\n            {\n              accountId,\n              settlementStatuses: [sdk.SETTLEMENT_STATUS.UNSETTLED, sdk.SETTLEMENT_STATUS.SETTLED],\n              offset,\n              limit,\n              start,\n              end,\n              investmentStatuses: [\n                // sdk.LABEL_INVESTMENT_STATUS.FAILED,\n                sdk.LABEL_INVESTMENT_STATUS.CANCELLED,\n                sdk.LABEL_INVESTMENT_STATUS.SUCCESS,\n                sdk.LABEL_INVESTMENT_STATUS.PROCESSED,\n                sdk.LABEL_INVESTMENT_STATUS.PROCESSING,\n              ].join(','),\n              retryStatuses: [sdk.DUAL_RETRY_STATUS.RETRYING],\n            } as any,\n            apiKey,\n          ),\n          LoopringAPI.defiAPI.getDualUserLocked(\n            {\n              accountId: accountId,\n              lockTag: [DUAL_TYPE.DUAL_BASE, DUAL_TYPE.DUAL_CURRENCY],\n              //@ts-ignore\n              status: 'LOCKED',\n            },\n            apiKey,\n          ),\n        ])\n        if ((responseTotal as sdk.RESULT_INFO).code || (responseTotal as sdk.RESULT_INFO).message) {\n          setDualOnInvestAsset(undefined)\n        } else {\n          setDualOnInvestAsset(responseTotal.lockRecord)\n        }\n        if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n          const errorItem = SDK_ERROR_MAP_TO_UI[(response as sdk.RESULT_INFO)?.code ?? 700001]\n          if (setToastOpen) {\n            setToastOpen({\n              open: true,\n              type: ToastType.error,\n              content:\n                'error : ' + errorItem\n                  ? t(errorItem.messageKey)\n                  : (response as sdk.RESULT_INFO).message,\n            })\n          }\n        } else {\n          const indexes = response.indexes\n          let result = (response as any)?.userDualTxs.reduce(\n            (prev: RawDataDualAssetItem[], item: sdk.UserDualTxsHistory) => {\n              const [, , coinA, coinB] =\n                (item.tokenInfoOrigin.market ?? 'dual-').match(/(dual-)?(\\w+)-(\\w+)/i) ?? []\n              // [] =  item.tokenInfoOrigin.market\n              const findIndex = indexes?.find((_item) => {\n                return (\n                  _item.base === item.tokenInfoOrigin.base &&\n                  _item.quote === item.tokenInfoOrigin.quote\n                )\n              })\n              let [sellTokenSymbol, buyTokenSymbol] =\n                item.dualType === DUAL_TYPE.DUAL_BASE\n                  ? [\n                      coinA ?? idIndex[item.tokenInfoOrigin.tokenIn],\n                      coinB ?? idIndex[item.tokenInfoOrigin.tokenOut],\n                    ]\n                  : [\n                      coinB ?? idIndex[item.tokenInfoOrigin.tokenIn],\n                      coinA ?? idIndex[item.tokenInfoOrigin.tokenOut],\n                    ]\n              const format = makeDualOrderedItem(\n                item,\n                sellTokenSymbol,\n                buyTokenSymbol,\n                findIndex?.index ?? 0,\n                dualMarketMap[item.tokenInfoOrigin.market],\n              )\n\n              const amount = getValuePrecisionThousand(\n                sdk\n                  .toBig(item.tokenInfoOrigin.amountIn)\n                  .div('1e' + tokenMap[sellTokenSymbol].decimals),\n                tokenMap[sellTokenSymbol].precision,\n                tokenMap[sellTokenSymbol].precision,\n                tokenMap[sellTokenSymbol].precision,\n                true,\n              )\n              const market = dualMarketMap[item.tokenInfoOrigin.market] as sdk.DefiMarketInfo\n              const currentPrice = {\n                base: idIndex[market.baseTokenId],\n                quote: idIndex[market.quoteTokenId],\n                currentPrice: findIndex?.index,\n                precisionForPrice: market.precisionForPrice,\n                quoteUnit: idIndex[market.quoteTokenId],\n              }\n              prev.push({\n                ...format,\n                amount,\n                currentPrice,\n                __raw__: {\n                  ...format.__raw__,\n                  currentPrice,\n                  index: findIndex,\n                },\n              })\n              return prev\n            },\n            [] as RawDataDualAssetItem[],\n          )\n          const filteredResult = (result as R[]).filter(\n            (x) => x.__raw__.order.investmentStatus !== sdk.LABEL_INVESTMENT_STATUS.CANCELLED,\n          )\n          setDualList(filteredResult)\n          setShowLoading(false)\n          setDualPagination({\n            pageSize: limit,\n            total: (response as any).totalNum,\n          })\n        }\n      }\n      setShowLoading(false)\n    },\n    [accountId, apiKey, setToastOpen, t, dualMarketMap, idIndex, tokenMap],\n  )\n  const [dualProducts, setDualProducts] = React.useState<DualViewInfo[]>([])\n  const getProduct = async (detail) => {\n    if (detail && detail.dualViewInfo) {\n      const { marketMap: dualMarketMap } = store.getState().invest.dualMap\n      const market =\n        detail.dualViewInfo.dualType === sdk.DUAL_TYPE.DUAL_BASE\n          ? detail.dualViewInfo.sellSymbol + '-' + detail.dualViewInfo.buySymbol\n          : detail.dualViewInfo.buySymbol + '-' + detail.dualViewInfo.sellSymbol\n      const dualMarket = dualMarketMap[`DUAL-${market}`]\n      const { dualType } = detail.dualViewInfo\n      const currency = dualMarket.currency\n      const baseSymbol = idIndex[dualMarket.baseTokenId]\n      const quoteSymbol = dualMarket.quoteAlias ?? idIndex[dualMarket.quoteTokenId]\n      const response = await LoopringAPI.defiAPI?.getDualInfos({\n        baseSymbol,\n        quoteSymbol,\n        currency: currency ?? '',\n        dualType,\n        startTime: Date.now() + 1000 * 60 * 60,\n        timeSpan: 1000 * 60 * 60 * 24 * 9,\n        limit: 50,\n      })\n\n      if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n        setDualProducts([])\n      } else {\n        const {\n          dualInfo: { infos, index },\n          raw_data: { rules },\n        } = response as any\n        const rule = rules[0]\n        const rawData = infos.map((item: sdk.DualProductAndPrice) => {\n          return makeDualViewItem(item, index, rule, baseSymbol, quoteSymbol, dualMarket)\n        })\n        myLog('setDualProducts', rawData)\n        setDualProducts(rawData)\n      }\n    } else {\n      setDualProducts([])\n    }\n  }\n  const cancelReInvest = React.useCallback((item) => {\n    updateEditDual({\n      ...item,\n      dualViewInfo: item,\n      tradeData: {\n        isRenew: false,\n      },\n    })\n    sdk.sleep(0).then(() => {\n      onEditDualClick()\n    })\n  }, [])\n  return {\n    getDetail,\n    showDetail,\n    dualList,\n    showLoading,\n    getDualTxList,\n    pagination,\n    open,\n    detail,\n    setOpen,\n    dualOnInvestAsset,\n    refresh,\n    setShowRefreshError,\n    showRefreshError,\n    refreshErrorInfo,\n    cancelReInvest,\n    dualProducts,\n    getProduct,\n    // onEdit,\n    dualToastOpen,\n    closeDualToast,\n    editDualTrade,\n    editDualBtnInfo,\n    editDualBtnStatus,\n    handleOnchange,\n    onEditDualClick,\n  }\n}\n"
  },
  {
    "path": "packages/web-earn/src/pages/AssetPage/RewardsPanel/hook.ts",
    "content": "import { ToastType } from '@loopring-web/component-lib'\nimport { ClaimCommands, claimServices, useAccount, useUserRewards } from '@loopring-web/core'\nimport { useTranslation } from 'react-i18next'\nimport React from 'react'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { CLAIM_TYPE, myLog, SagaStatus, SDK_ERROR_MAP_TO_UI } from '@loopring-web/common-resources'\n\nexport function useRewardsTable(setToastOpen: (state: any) => void) {\n  const {\n    account: { accountId, apiKey },\n  } = useAccount()\n  const { totalClaims, errorMessage, status: userRewardsStatus, getUserRewards } = useUserRewards()\n  const subject = React.useMemo(() => claimServices.onSocket(), [])\n\n  const { t } = useTranslation(['error'])\n  const [claimList, setClaimList] = React.useState(\n    Reflect.ownKeys(totalClaims ?? {}).map((key) => totalClaims[key]) ?? [],\n  )\n  const [showLoading, setShowLoading] = React.useState(false)\n  const getRewardsTableList = React.useCallback(async () => {\n    setShowLoading(true)\n    try {\n      myLog('totalClaims', totalClaims)\n      if (errorMessage) {\n      } else {\n        setClaimList(Reflect.ownKeys(totalClaims).map((key) => totalClaims[key]))\n      }\n    } catch (error) {\n      let errorItem\n      if (typeof (error as sdk.RESULT_INFO)?.code === 'number') {\n        errorItem = SDK_ERROR_MAP_TO_UI[(error as sdk.RESULT_INFO)?.code ?? 700001]\n      } else {\n        errorItem = SDK_ERROR_MAP_TO_UI[700012]\n      }\n      setToastOpen({\n        open: true,\n        type: ToastType.error,\n        content: 'error : ' + errorItem ? t(errorItem.messageKey) : (error as any)?.message,\n      })\n    }\n    setShowLoading(false)\n  }, [accountId, totalClaims, apiKey, setToastOpen, t])\n  React.useEffect(() => {\n    const subscription = subject.subscribe((props) => {\n      switch (props.status) {\n        case ClaimCommands.Success:\n          if (props?.data?.type == CLAIM_TYPE.allToken) {\n            getUserRewards()\n          }\n          break\n        default:\n          break\n      }\n    })\n    return () => {\n      subscription.unsubscribe()\n    }\n  }, [subject])\n  React.useEffect(() => {\n    if (userRewardsStatus === SagaStatus.UNSET) {\n      getRewardsTableList()\n    }\n  }, [userRewardsStatus])\n  return {\n    claimList,\n    showLoading,\n    errorMessage,\n    getRewardsTableList,\n    getUserRewards,\n  }\n}\n"
  },
  {
    "path": "packages/web-earn/src/pages/AssetPage/RewardsPanel/index.tsx",
    "content": "import { useTranslation, WithTranslation, withTranslation } from 'react-i18next'\nimport {\n  Button,\n  EarningsRow,\n  RewardsTable,\n  Toast,\n  ToastType,\n  useOpenModals,\n} from '@loopring-web/component-lib'\nimport React from 'react'\nimport { CLAIM_TYPE, TOAST_TIME, TRADE_TYPE } from '@loopring-web/common-resources'\n\nimport { StylePaper, useModalData, useSystem, useToast } from '@loopring-web/core'\n\nimport { useRewardsTable } from './hook'\nimport { Box } from '@mui/material'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nconst RewardsPanel = withTranslation('common')(\n  ({\n    hideAssets,\n  }: WithTranslation<'common'> & {\n    hideAssets?: boolean\n  }) => {\n    const { forexMap } = useSystem()\n    const { t } = useTranslation('common')\n    const { toastOpen, setToastOpen, closeToast } = useToast()\n    const { updateClaimData } = useModalData()\n    const { setShowClaimWithdraw } = useOpenModals()\n    const { claimList, showLoading, errorMessage, getUserRewards } = useRewardsTable(setToastOpen)\n    const container = React.useRef<HTMLDivElement>(null)\n\n    return (\n      <StylePaper ref={container} flex={1} marginTop={2}>\n        <Toast\n          alertText={toastOpen?.content ?? ''}\n          severity={toastOpen?.type ?? ToastType.success}\n          open={toastOpen?.open ?? false}\n          autoHideDuration={TOAST_TIME}\n          onClose={closeToast}\n        />\n\n        <Box className='tableWrapper table-divide-short'>\n          {errorMessage ? (\n            <Box\n              key={'empty'}\n              flexDirection={'column'}\n              display={'flex'}\n              justifyContent={'center'}\n              height={'100%'}\n              width={'100%'}\n              alignItems={'center'}\n            >\n              <Button\n                onClick={() => {\n                  getUserRewards()\n                }}\n                variant={'contained'}\n              >\n                {t('labelRewardRefresh')}\n              </Button>\n            </Box>\n          ) : (\n            <RewardsTable\n              forexMap={forexMap}\n              rawData={claimList}\n              hideAssets={hideAssets}\n              onItemClick={(item: EarningsRow) => {\n                // getUserRewards()\n                updateClaimData({\n                  belong: item.token.value,\n                  tradeValue: item.amountStr?.replaceAll(sdk.SEP, ''),\n                  balance: item.amountStr?.replaceAll(sdk.SEP, ''),\n                  volume: item.amount,\n                  tradeType: TRADE_TYPE.TOKEN,\n                  claimType: CLAIM_TYPE.allToken,\n                })\n                setShowClaimWithdraw({\n                  isShow: true,\n                  claimType: CLAIM_TYPE.allToken,\n                })\n              }}\n              onDetail={(item) => {}}\n              showloading={showLoading}\n            />\n          )}\n        </Box>\n      </StylePaper>\n    )\n  },\n)\n\nexport default RewardsPanel\n"
  },
  {
    "path": "packages/web-earn/src/pages/AssetPage/index.tsx",
    "content": "import { useRouteMatch } from 'react-router-dom'\n\nimport { Box, BoxProps, Button, Typography } from '@mui/material'\nimport { AssetTitleMobile, AssetTitleMobileEarn, useSettings, useToggle } from '@loopring-web/component-lib'\nimport { CloseIcon, hexToRGB, HiddenTag, SoursURL, subMenuLayer2 } from '@loopring-web/common-resources'\n\nimport HistoryPanel from './HistoryPanel'\nimport React from 'react'\nimport {\n  fiatNumberDisplay,\n  numberFormatShowInPercent,\n  useAccount,\n  useDualMap,\n  useSocket,\n  useSubmitBtn,\n  useSystem,\n  useTargetRedPackets,\n  ViewAccountTemplate,\n  WalletConnectL2Btn,\n} from '@loopring-web/core'\nimport { useGetAssets } from './AssetPanel/hook'\nimport { AssetPanel } from './AssetPanel'\nimport { MaxWidthContainer } from '../InvestPage'\nimport { WsTopicType } from '@loopring-web/loopring-sdk'\nimport { useTheme } from '@emotion/react'\nimport { useConfirmation } from '@loopring-web/core/src/stores/localStore/confirmation/hook'\nimport { concat, max } from 'lodash'\nimport Decimal from 'decimal.js'\nimport { t } from 'i18next'\nimport ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos'\n\nexport * from './HistoryPanel/hooks'\nexport const subMenu = subMenuLayer2\n\ninterface BottomSectionProps {\n  title: string\n  subTitle?: React.ReactNode\n  des: string\n  imgSrc: string\n  link: string\n  isMobile: boolean\n}\n\nconst BottomSection = ({\n  title,\n  subTitle,\n  des,\n  imgSrc,\n  link,\n  isMobile,\n  ...rest\n}: BottomSectionProps & BoxProps) => {\n  const theme = useTheme()\n  return (\n    <Box\n      borderRadius={'24px'}\n      px={4}\n      py={8}\n      minHeight={'100%'}\n      bgcolor={hexToRGB(theme.colorBase.boxSecondary, 0.6)}\n      display={'flex'}\n      flexDirection={'column'}\n      minWidth={isMobile ? '100%' : '400px'}\n      justifyContent={'space-between'}\n      {...rest}\n    >\n      <Box>\n        <Box display={'flex'} justifyContent={'space-between'}>\n          <Typography mt={1.5} variant={isMobile ? 'h3' : 'h2'}>\n            {title}\n          </Typography>\n          <Box\n            component={'img'}\n            src={`${SoursURL}${\n              theme.mode === 'dark' ? 'earn/nav_button_dark.png' : 'earn/nav_button_light.png'\n            }`}\n            sx={{ cursor: 'pointer' }}\n            height={isMobile ? '32px' : '44px'}\n            width={isMobile ? '32px' : '44px'}\n            onClick={() => {\n              window.open(link, '_blank')\n            }}\n          />\n        </Box>\n        {subTitle && <Box mt={2}>{subTitle}</Box>}\n        <Typography\n          variant={isMobile ? 'body2' : 'body1'}\n          color={'var(--color-text-secondary)'}\n          mt={2}\n          mb={8}\n        >\n          {des}\n        </Typography>\n      </Box>\n\n      <Box width={'100%'} display={'flex'} justifyContent={'center'}>\n        <Box component={'img'} src={imgSrc} mt={'auto'} height={isMobile ? '120px' : '160px'} />\n      </Box>\n    </Box>\n  )\n}\n\nconst RightButton = ({ size, sx, ...rest }: { size: number } & BoxProps) => {\n  return (\n    <Box\n      sx={{\n        width: size + 'px',\n        height: size + 'px',\n        borderRadius: '50%',\n        display: 'flex',\n        justifyContent: 'center',\n        alignItems: 'center',\n        bgcolor: 'var(--color-border)',\n        cursor: 'pointer',\n        ...sx,\n      }}\n      {...rest}\n    >\n      <ArrowForwardIosIcon className='custome-size' sx={{ fontSize: '16px' }} />\n    </Box>\n  )\n}\n\nconst LeftButton = ({ size, sx, ...rest }: { size: number } & BoxProps) => {\n  return (\n    <Box\n      sx={{\n        width: size + 'px',\n        height: size + 'px',\n        borderRadius: '50%',\n        display: 'flex',\n        justifyContent: 'center',\n        alignItems: 'center',\n        bgcolor: 'var(--color-border)',\n        cursor: 'pointer',\n        ...sx,\n      }}\n      {...rest}\n    >\n      <ArrowForwardIosIcon className='custome-size' sx={{ transform: 'rotate(180deg)' ,fontSize: '16px' }} />\n    </Box>\n  )\n}\n\nexport const AssetPage = () => {\n  let match: any = useRouteMatch('/l2assets/:item')\n  const { forexMap, getValueInCurrency } = useSystem()\n\n  const selected = match?.params.item ?? 'assets'\n  const { assetTitleProps, assetTitleMobileExtendProps, assetBtnStatus, ...assetPanelProps } =\n    useGetAssets()\n  const { redPackets } = useTargetRedPackets()\n\n  const { sendSocketTopic } = useSocket()\n\n  React.useEffect(() => {\n    sendSocketTopic({\n      [WsTopicType.account]: true,\n    })\n  }, [])\n  const theme = useTheme()\n  const isUnlocked = useAccount().account.readyState === 'ACTIVATED'\n  const { setShowTaikoLaunchBanner2, confirmation } = useConfirmation()\n  const { isMobile, currency } = useSettings()\n  const { marketMap: dualMarketMap } = useDualMap()\n  const { account } = useAccount()\n\n  const keys = dualMarketMap ? Object.keys(dualMarketMap) : []\n  const dualAPRUpToRaw = max(\n    concat(\n      keys.map((key) => (dualMarketMap[key] as any).baseTokenApy?.max),\n      keys.map((key) => (dualMarketMap[key] as any).quoteTokenApy?.max),\n    ),\n  )\n  const dualAPRUpTo = dualAPRUpToRaw\n    ? numberFormatShowInPercent(new Decimal(dualAPRUpToRaw).mul('100').toString())\n    : '--'\n\n  const scrollDivRef = React.useRef<HTMLDivElement>(null)\n  const [reachedRight, setReachedRight] = React.useState(false)\n  const [reachedLeft, setReachedLeft] = React.useState(true)\n  const div = scrollDivRef.current\n  React.useEffect(() => {\n    if (scrollDivRef.current) {\n      const div = scrollDivRef.current\n      const handleScroll = () => {\n        setReachedRight(div.scrollLeft + div.clientWidth >= div.scrollWidth)\n        setReachedLeft(div.scrollLeft === 0)\n      }\n      div.addEventListener('scroll', handleScroll)\n      return () => {\n        div.removeEventListener('scroll', handleScroll)\n      }\n    }\n  }, [div])\n  const {\n    toggle: { taikoFarming },\n  } = useToggle()\n  if (selected.toLowerCase() === 'history') {\n    return (\n      <Box display={'flex'} alignItems={'stretch'} flexDirection={'column'} marginTop={0} flex={1}>\n        <ViewAccountTemplate\n          activeViewTemplate={\n            <MaxWidthContainer marginTop={5}>\n              <HistoryPanel />\n            </MaxWidthContainer>\n          }\n        ></ViewAccountTemplate>\n      </Box>\n    )\n  }\n\n\n  return (\n    <Box\n      sx={{\n        backgroundImage:\n          theme.mode === 'light'\n            ? `url(${SoursURL + 'images/asset_page_bg_light.png'})`\n            : `url(${SoursURL + 'images/asset_page_bg_dark.png'})`,\n        backgroundSize: 'cover',\n        backgroundPosition: 'center',\n        backgroundRepeat: 'no-repeat',\n        height: '100%',\n        overflow: 'auto',\n      }}\n    >\n      {confirmation.showTaikoLaunchBanner2 && (\n        <MaxWidthContainer>\n          <Box\n            sx={{\n              backgroundImage: `url(${SoursURL}earn/assets_banner_title2_${theme.mode === 'dark' ? 'dark' : 'light'}${isMobile ? '_mobile' : ''}.png)`,\n              backgroundSize: 'cover',\n              backgroundPosition: 'center',\n              backgroundRepeat: 'no-repeat',\n              height: '140px',\n              width: '100%',\n              display: 'flex',\n              justifyContent: 'center',\n              alignItems: 'center',\n              flexDirection: 'column',\n              position: 'relative',\n              mt: isMobile ? 6 : 4,\n              borderRadius: '12px',\n            }}\n          >\n            <CloseIcon\n              className='custom-size'\n              sx={{\n                color: 'var(--color-text-primary)',\n                position: 'absolute',\n                top: 8,\n                right: 8,\n                cursor: 'pointer',\n              }}\n              style={{ height: 24, width: 24 }}\n              onClick={() => {\n                setShowTaikoLaunchBanner2(false)\n              }}\n            />\n            {/* <Box\n              height={isMobile ? '28px' : '32px'}\n              component={'img'}\n              src={`${SoursURL}earn/assets_banner_title2_${theme.mode === 'dark' ? 'dark' : 'light'}.png`}\n            /> */}\n            {/* {isMobile ? (\n              <Typography\n                mt={1.5}\n                textAlign={'center'}\n                variant='body2'\n                color={'var(--color-white)'}\n              >\n                {t('labelLoopringDeFiIs')}\n              </Typography>\n            ) : (\n              <Typography\n                mt={1.5}\n                textAlign={'center'}\n                fontSize={'16px'}\n                color={'var(--color-white)'}\n              >\n                {t('labelLoopringDeFiIs21')}\n                <br />\n                {t('labelLoopringDeFiIs22')}\n              </Typography>\n            )} */}\n          </Box>\n        </MaxWidthContainer>\n      )}\n      <MaxWidthContainer mt={confirmation.showTaikoLaunchBanner2 ? 3 : 4}>\n        {isUnlocked ? (\n          <>\n            {isMobile && (\n              <AssetTitleMobileEarn\n                forexMap={forexMap}\n                assetBtnStatus={assetBtnStatus}\n                {...{ ...assetTitleProps, ...assetTitleMobileExtendProps }}\n              />\n            )}\n            <AssetPanel\n              showRedpacketReddot={redPackets ? redPackets?.length > 0 : false}\n              assetTitleProps={assetTitleProps}\n              assetPanelProps={{ ...assetPanelProps, assetBtnStatus }}\n            />\n          </>\n        ) : (\n          <Box\n            borderRadius={'24px'}\n            px={3}\n            py={5}\n            width={'100%'}\n            bgcolor={'var(--color-box)'}\n            display={'flex'}\n            justifyContent={'space-between'}\n            alignItems={'center'}\n            flexDirection={isMobile ? 'column' : 'row'}\n          >\n            <Box width={'30%'} alignSelf={'flex-start'}>\n              <Typography\n                fontSize={isMobile ? '14px' : '16px'}\n                color={'var(--color-text-secondary)'}\n              >\n                {t('labelLoopringDeFiAssets')}\n              </Typography>\n              <Typography variant={isMobile ? 'h4' : 'h2'} mt={2}>\n                {!assetTitleProps.hideL2Assets\n                  ? assetTitleProps.assetInfo.totalAsset &&\n                    new Decimal(assetTitleProps.assetInfo.totalAsset).gt(0) &&\n                    currency &&\n                    account.readyState !== 'UN_CONNECT' &&\n                    forexMap &&\n                    forexMap[currency]\n                    ? fiatNumberDisplay(\n                        getValueInCurrency(assetTitleProps.assetInfo.totalAsset),\n                        currency,\n                      )\n                    : '--'\n                  : HiddenTag}\n              </Typography>\n            </Box>\n            {isMobile ? (\n              <Box mt={1}>{<WalletConnectL2Btn width='120px' size={'medium'} />}</Box>\n            ) : (\n              <Box>{<WalletConnectL2Btn width='250px' size={'large'} />}</Box>\n            )}\n            {!isMobile && <Box width={'30%'} />}\n          </Box>\n        )}\n      </MaxWidthContainer>\n      <MaxWidthContainer mt={3} position={'relative'} mb={8}>\n        <Box\n          ref={scrollDivRef}\n          width={'100%'}\n          display={'flex'}\n          sx={{ overflowX: 'scroll', scrollbarWidth: 'none' }}\n          flexDirection={isMobile ? 'column' : 'row'}\n        >\n          {taikoFarming.enable && <BottomSection\n            title='Taiko Farming'\n            subTitle={\n              <Box\n                component={'img'}\n                src={`${SoursURL}${\n                  theme.mode === 'dark'\n                    ? 'earn/defi_assets_taiko_farming_subtitle_dark.png'\n                    : 'earn/defi_assets_taiko_farming_subtitle_light.png'\n                }`}\n                height={isMobile ? '18px' : '24px'}\n              />\n            }\n            des='Farm Trailblazers points at 60X while unlocking the value of your locked TAIKO to keep trading or earning.'\n            imgSrc={`${SoursURL}${\n              theme.mode === 'dark'\n                ? 'earn/defi_assets_taiko_farming_dark.png'\n                : 'earn/defi_assets_taiko_farming_light.png'\n            }`}\n            link='/#/taiko-farming'\n            mr={isMobile ? 0 : 2}\n            mb={isMobile ? 4 : 0}\n            width={isMobile ? '100%' : undefined}\n            isMobile={isMobile}\n          />}\n          <BottomSection\n            title='Dual Investment'\n            subTitle={\n              <Typography\n                color={'var(--color-text-secondary)'}\n                fontSize={isMobile ? '9px' : '12px'}\n              >\n                APR Up To{' '}\n                <Typography\n                  component={'span'}\n                  color={'var(--color-success)'}\n                  fontSize={isMobile ? '17px' : '24px'}\n                >\n                  {dualAPRUpTo}\n                </Typography>{' '}\n              </Typography>\n            }\n            des='Bring structured finance from CeFi to DeFi in a trustless manner. Place orders at your preferred price and earn high yields!'\n            imgSrc={`${SoursURL}${\n              theme.mode === 'dark'\n                ? 'earn/defi_assets_dual_dark.png'\n                : 'earn/defi_assets_dual_light.png'\n            }`}\n            link='/#/invest/dual'\n            mr={isMobile ? 0 : 2}\n            mb={isMobile ? 4 : 0}\n            width={isMobile ? '100%' : undefined}\n            isMobile={isMobile}\n          />\n          <BottomSection\n            title='Portal'\n            des='Trade popular tokens beyond the Ethereum chain, with leverage!'\n            imgSrc={`${SoursURL}${\n              theme.mode === 'dark'\n                ? 'earn/defi_assets_portal_dark.png'\n                : 'earn/defi_assets_portal_light.png'\n            }`}\n            link='/#/portal'\n            mr={isMobile ? 0 : 2}\n            mb={isMobile ? 4 : 0}\n            width={isMobile ? '100%' : undefined}\n            isMobile={isMobile}\n          />\n          <BottomSection\n            title='Block Trade'\n            des='Swap tokens securely and trustlessly, tapping into CEX liquidity.'\n            imgSrc={`${SoursURL}${\n              theme.mode === 'dark'\n                ? 'earn/defi_assets_btrade_dark.png'\n                : 'earn/defi_assets_btrade_light.png'\n            }`}\n            link='/#/trade/btrade'\n            mr={isMobile ? 0 : 2}\n            mb={isMobile ? 4 : 0}\n            width={isMobile ? '100%' : undefined}\n            isMobile={isMobile}\n          />\n        </Box>\n        {!isMobile && !reachedLeft && (\n          <LeftButton\n            onClick={() => {\n              const element = scrollDivRef.current\n              if (element) {\n                element.scrollTo({ behavior: 'smooth', left: 0 })\n              }\n            }}\n            size={64}\n            top={'45%'}\n            left={'32px'}\n            position={'absolute'}\n          />\n        )}\n        {!isMobile && !reachedRight && (\n          <RightButton\n            onClick={() => {\n              const element = scrollDivRef.current\n              if (element) {\n                element.scrollTo({ behavior: 'smooth', left: element.scrollLeft + 1000 })\n              }\n            }}\n            size={64}\n            top={'45%'}\n            right={'32px'}\n            position={'absolute'}\n          />\n        )}\n      </MaxWidthContainer>\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/web-earn/src/pages/BtradeSwapPage/index.tsx",
    "content": "import { Box, Typography } from '@mui/material'\nimport { useTranslation, WithTranslation, withTranslation } from 'react-i18next'\nimport {\n  Button,\n  ConfirmBtradeSwapRisk,\n  EmptyDefault,\n  SwapPanel,\n  Toast,\n  ToastType,\n  useSettings,\n} from '@loopring-web/component-lib'\nimport {\n  myLog,\n  HelpIcon,\n  LOOPRING_DOCUMENT,\n  TOAST_TIME,\n  SoursURL,\n  ImageIcon,\n} from '@loopring-web/common-resources'\nimport { confirmation, useBtradeMap, useBtradeSwap, useNotify, useSystem } from '@loopring-web/core'\nimport React from 'react'\nimport { useHistory } from 'react-router-dom'\nimport styled from '@emotion/styled'\nimport { Link } from '@mui/material'\n\nconst BoxStyle = styled(Box)`\n  &.btradePage {\n    .input-wrap {\n      input::placeholder {\n        font-size: 0.65em;\n      }\n    }\n  }\n`\nconst Content = withTranslation('common')(({ ...rest }: WithTranslation) => {\n  const { campaignTagConfig } = useNotify().notifyMap ?? {}\n  const { t } = useTranslation()\n  const {\n    toastOpen,\n    closeToast,\n    setToastOpen,\n    refreshRef,\n    tradeData,\n    tradeCalcData,\n    onSwapClick,\n    swapBtnStatus,\n    swapBtnI18nKey,\n    handleSwapPanelEvent,\n    isSwapLoading,\n    market,\n    should15sRefresh,\n    isMarketInit,\n  } = useBtradeSwap({ path: '/trade/btrade' })\n  const { isMobile, bTradeShowTutorial, setBTradeShowTutorial } = useSettings()\n  return (\n    <Box display={'flex'} justifyContent={'space-evenly'} alignItems={isMobile ? 'center' : 'start'} flexDirection={isMobile ? 'column-reverse' : 'row'} >\n      {bTradeShowTutorial && (\n        <Box\n          width={isMobile ? '100%' : '30%'}\n          borderRadius={'8px'}\n          bgcolor={'var(--color-pop-bg)'}\n          paddingX={4}\n          paddingTop={3}\n          paddingBottom={2}\n          marginTop={isMobile ? -20 : 0}\n        >\n          <Typography fontSize={'16px'}>{t(\"labelBtradeSwapTitle\")}</Typography>\n          <Typography marginTop={1} color={'var(--color-text-secondary)'} fontSize={'14px'}>\n            {t(\"labelBTradeTutorial\")}\n          </Typography>\n          <br />\n          <Link\n            marginTop={1}\n            fontSize={'14px'}\n            href='https://loopring.io/#/document/Block_Trade_tutorial_en.md'\n            target=\"_blank\"\n          >\n            {t(\"labelLearnMore\")}\n          </Link>\n        </Box>\n      )}\n      <Box>\n        {tradeData ? (\n          <SwapPanel\n            titleI8nKey={'labelBtradeSwapTitle'}\n            tokenBuyProps={{\n              disableInputValue: isMarketInit,\n              disabled: isSwapLoading || isMarketInit,\n              decimalsLimit: tradeCalcData.buyPrecision,\n            }}\n            tokenSellProps={{\n              disableInputValue: isMarketInit,\n              disabled: isSwapLoading || isMarketInit,\n              placeholderText:\n                tradeCalcData.sellMaxAmtStr && tradeCalcData.sellMaxAmtStr !== ''\n                  ? t('labelBtradeSwapMiniMax', {\n                      minValue: tradeCalcData.sellMinAmtStr,\n                      maxValue: tradeCalcData.sellMaxAmtStr,\n                    })\n                  : t('labelBtradeSwapMini', {\n                      minValue: tradeCalcData.sellMinAmtStr,\n                    }),\n            }}\n            campaignTagConfig={campaignTagConfig ?? ({} as any)}\n            market={market}\n            onRefreshData={should15sRefresh}\n            refreshRef={refreshRef}\n            tradeData={tradeData as any}\n            tradeCalcData={tradeCalcData as any}\n            onSwapClick={onSwapClick}\n            swapBtnI18nKey={swapBtnI18nKey}\n            swapBtnStatus={swapBtnStatus}\n            setToastOpen={setToastOpen}\n            hideSecondConfirmation\n            handleSwapPanelEvent={handleSwapPanelEvent}\n            bTradeTutorial={{\n              show: true,\n              checked: bTradeShowTutorial,\n              onToggle() {\n                setBTradeShowTutorial(!bTradeShowTutorial)\n              },\n            }}\n            {...rest}\n          />\n        ) : (\n          <Box\n            flex={1}\n            height={'100%'}\n            display={'flex'}\n            alignItems={'center'}\n            justifyContent={'center'}\n          >\n            <img className='loading-gif' width='36' src={`${SoursURL}images/loading-line.gif`} />\n          </Box>\n        )}\n      </Box>\n\n      {bTradeShowTutorial && <Box width={'30%'} />}\n\n      <Toast\n        alertText={toastOpen?.content ?? ''}\n        severity={toastOpen?.type ?? ToastType.success}\n        open={toastOpen?.open ?? false}\n        autoHideDuration={TOAST_TIME}\n        onClose={closeToast}\n      />\n    </Box>\n  )\n})\nexport const BtradeSwapPage = withTranslation('common')(({ t, ...rest }: WithTranslation) => {\n  const { marketMap, getBtradeMap } = useBtradeMap()\n\n  const {\n    confirmation: { confirmedBtradeSwap: confirmedBtradeSwapStore },\n    confirmedBtradeSwap: confirmedBtradeSwapFunc,\n  } = confirmation.useConfirmation()\n  const [_confirmedBtradeSwap, setConfirmedBtradeSwap] = React.useState<boolean>(\n    !confirmedBtradeSwapStore,\n  )\n\n  const { isMobile } = useSettings()\n  const { app } = useSystem()\n  const { marketArray } = useBtradeMap()\n  const history = useHistory()\n\n  const styles = isMobile ? { flex: 1 } : { width: 'var(--swap-box-width)' }\n  myLog('marketArray', marketArray?.length)\n  return (\n    <BoxStyle\n      className={'btradePage'}\n      display={'flex'}\n      flexDirection={'column'}\n      justifyContent={'center'}\n      alignItems={'center'}\n      flex={1}\n    >\n      <Box\n        paddingBottom={isMobile ? 2 : 'initial'}\n      >\n        {!marketArray?.length ||\n        !marketMap[marketArray[0]] ||\n        marketMap[marketArray[0]].enabled === 'isFormLocal' ? (\n          <Box\n            key={'empty'}\n            flexDirection={'column'}\n            display={'flex'}\n            justifyContent={'center'}\n            flex={1}\n            alignItems={'center'}\n          >\n            <EmptyDefault\n              emptyPic={\n                <img\n                  className='loading-gif'\n                  width='36'\n                  src={`${SoursURL}images/loading-line.gif`}\n                />\n              }\n              message={() => {\n                return (\n                  <Button onClick={getBtradeMap} variant={'contained'}>\n                    {t('labelBtradeRefresh')}\n                  </Button>\n                )\n              }}\n            />\n          </Box>\n        ) : (\n          <Content />\n        )}\n      </Box>\n\n      <ConfirmBtradeSwapRisk\n        open={_confirmedBtradeSwap}\n        handleClose={(_e, isAgree) => {\n          setConfirmedBtradeSwap(false)\n          if (!isAgree) {\n            if (app === 'earn') {\n              history.goBack()\n            } else {\n              history.replace('/markets')\n            }\n          } else {\n            confirmedBtradeSwapFunc()\n          }\n        }}\n      />\n    </BoxStyle>\n  )\n})\n"
  },
  {
    "path": "packages/web-earn/src/pages/EarnPage/index.tsx",
    "content": "import styled from '@emotion/styled'\nimport { CoinIcon, useSettings } from '@loopring-web/component-lib'\nimport { Box, Button, Typography } from '@mui/material'\n\nimport { withTranslation } from 'react-i18next'\nimport {\n  BackIcon,\n  EmptyValueTag,\n  SoursURL,\n  getValuePrecisionThousand,\n  hexToRGB,\n} from '@loopring-web/common-resources'\nimport { useTheme } from '@emotion/react'\nimport { useDualHook } from 'pages/InvestPage/DualPanel/hook'\nimport { btnClickMap, useAccount, useDualMap, useTokenPrices } from '@loopring-web/core'\nimport { cloneDeep, difference, max } from 'lodash'\nimport { toBig } from '@loopring-web/loopring-sdk'\nimport { useHistory, useLocation } from 'react-router'\nimport { useGetAssets } from 'pages/AssetPage/AssetPanel/hook'\nimport React from 'react'\n\nconst EarnCard = styled(Box)<{ isMobile: boolean }>`\n  background-color: var(--color-box-third);\n  padding: ${({ theme }) => theme.unit * 6}px ${({ theme }) => theme.unit * 4}px\n    ${({ theme }) => theme.unit * 4}px ${({ theme }) => theme.unit * 4}px;\n  width: ${({ isMobile }) => (isMobile ? '100%' : '32%')};\n  margin-bottom: ${({ theme }) => theme.unit * 2}px;\n  border-radius: ${({ theme }) => theme.unit * 1.5}px;\n  border: 0.5px solid var(--color-border);\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  position: relative;\n  overflow: hidden;\n  :hover {\n    border: 1px solid var(--color-primary);\n  }\n`\n\nconst FAQ = styled(Box)<{ opend: boolean }>`\n  background: ${({ opend }) => opend && 'var(--color-box-third)'};\n  padding: ${({ theme }) => theme.unit * 3}px;\n  border-radius: ${({ theme }) => theme.unit * 1.5}px;\n  border: ${({ opend }) => opend && '0.5px solid var(--color-border)'};\n  margin-bottom: ${({ theme }) => theme.unit * 2}px;\n`\n\nconst TextTag = styled(Box)<{ isMobile: boolean }>`\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  height: 32px;\n  border-radius: 16px;\n  background: ${({ theme }) => hexToRGB(theme.colorBase.primary, 0.2)};\n  padding: 0px ${({ theme }) => theme.unit * 2}px;\n  margin: 0px ${({ theme }) => theme.unit * 1}px;\n  color: var(--color-text-primary);\n  width: ${({ isMobile }) => (isMobile ? '50%' : 'auto')};\n  margin-bottom: ${({ isMobile, theme }) => (isMobile ? `${theme.unit}px` : 'auto')};\n`\nconst ConnectBtn = styled(Button)`\n  height: 80px;\n  padding: 0px 80px;\n  border-radius: 40px;\n  color: var(--color-text-primary);\n  &:hover {\n    &:before {\n      border-radius: 40px;\n    }\n  }\n`\nconst AnimationCard = styled(Box)<{ highlighted: boolean; isMobile: boolean }>`\n  display: flex;\n  flex-direction: column;\n  background-color: var(--color-box-third);\n  border-radius: 12px;\n  padding-top: ${({ theme }) => theme.unit * 8}px;\n  padding-left: ${({ theme }) => theme.unit * 5}px;\n  padding-right: ${({ theme }) => theme.unit * 4}px;\n  padding-bottom: ${({ theme }) => theme.unit * 2.5}px;\n  height: 390px;\n  height: ${({ isMobile }) => (isMobile ? '290px' : '390px')};\n  width: ${({ highlighted, isMobile }) => (isMobile ? '100%' : highlighted ? '55.08%' : '20.4%')};\n  transition: all 0.5s ease;\n  border: ${({ highlighted, isMobile }) =>\n    !isMobile && highlighted\n      ? '1px solid var(--color-primary)'\n      : '0.5px solid var(--color-border)'};\n  overflow: hidden;\n  .title {\n    margin-bottom: ${({ theme }) => theme.unit * 3}px;\n  }\n  .sub-title {\n    color: var(--color-text-secondary);\n    display: ${({ highlighted, isMobile }) => (isMobile || highlighted ? '' : 'none')};\n    max-height: 30px;\n  }\n  img {\n    height: 134px;\n    width: 134px;\n    align-self: end;\n    margin-right: ${({ highlighted, isMobile }) => (isMobile || highlighted ? '0px' : '-60px')};\n    opacity: ${({ highlighted, isMobile }) => (isMobile || highlighted ? '1' : '0.5')};\n    transition: all 0.5s ease;\n  }\n  margin-bottom: ${({ isMobile, theme }) => (isMobile ? `${theme.unit * 2.5}px` : 'auto')};\n`\n\nexport const EarnPage = withTranslation('webEarn', { withRef: true })(({ t }) => {\n  const { baseTokenList } = useDualHook()\n  const { marketMap } = useDualMap()\n  const tokenList: any[] = Object.values(baseTokenList ?? {})\n  const { tokenPrices } = useTokenPrices()\n\n  const account = useAccount()\n\n  const sellCoverTokens: {\n    symbol: string\n    apy: string\n    price: string\n    tag: 'sellCover' | 'buyDip'\n    apyRaw: number\n  }[] = (tokenList ?? [])?.map((token) => {\n    const keys = Object.keys(marketMap).filter((key) => key.includes(token.tokenName))\n    const maxApy = max(keys.map((key) => (marketMap[key] as any).baseTokenApy?.max as number))\n    return {\n      symbol: token.tokenName,\n      apy:\n        toBig(maxApy ?? 0)\n          .times('100')\n          .toString() + '%',\n      price: '$' + getValuePrecisionThousand(tokenPrices[token.tokenName], 2, 2),\n      tag: 'sellCover',\n      apyRaw: maxApy ?? 0,\n    }\n  })\n  const buyDipTokens: {\n    symbol: string\n    apy: string\n    price: string\n    tag: 'sellCover' | 'buyDip'\n    apyRaw: number\n  }[] =\n    tokenList?.map((token) => {\n      const keys = Object.keys(marketMap).filter((key) => key.includes(token.tokenName))\n      const maxApy = max(keys.map((key) => (marketMap[key] as any).quoteTokenApy?.max as number))\n      return {\n        symbol: token.tokenName,\n        apy:\n          toBig(maxApy ?? 0)\n            .times('100')\n            .toString() + '%',\n        price: '$' + getValuePrecisionThousand(tokenPrices[token.tokenName], 2, 2),\n        tag: 'buyDip',\n        apyRaw: maxApy ?? 0,\n      }\n    }) ?? []\n\n  const dualTokenList = [...sellCoverTokens, ...buyDipTokens]\n  const maxApyForAll = max(dualTokenList.map((token) => token.apyRaw))\n  const upTo = maxApyForAll ? toBig(maxApyForAll).times('100').toString() + '%' : EmptyValueTag\n  const history = useHistory()\n  const { assetTitleProps } = useGetAssets()\n  const myBalance =\n    assetTitleProps.assetInfo.totalAsset && assetTitleProps.assetInfo.priceTag\n      ? assetTitleProps.assetInfo.priceTag +\n        getValuePrecisionThousand(assetTitleProps.assetInfo.totalAsset, 2, 2, 2, true, {\n          floor: true,\n        })\n      : '$0.00'\n  const { isMobile } = useSettings()\n\n  const [openedFaqs, setOpenedFaqs] = React.useState([0])\n  const faqs: {\n    question: string\n    answer: React.ReactNode\n  }[] = [\n    {\n      question: t('labelFAQ1Question'),\n      answer: <Typography>{t('labelFAQ1Answer')}</Typography>,\n    },\n    {\n      question: t('labelFAQ2Question'),\n      answer: (\n        <Box>\n          <Typography>{t('labelFAQ2AnswerLine1')}</Typography>\n          <br />\n          <Typography>{t('labelFAQ2AnswerLine2')}</Typography>\n          <br />\n          <Typography>{t('labelFAQ2AnswerLine3')}</Typography>\n          <br />\n          <Typography component={'li'}>{t('labelFAQ2AnswerLine4')}</Typography>\n          <Typography component={'li'}>{t('labelFAQ2AnswerLine5')}</Typography>\n          <br />\n          <Typography>{t('labelFAQ2AnswerLine6')}</Typography>\n          <br />\n          <Typography component={'li'}>{t('labelFAQ2AnswerLine7')}</Typography>\n          <Typography component={'li'}>{t('labelFAQ2AnswerLine8')}</Typography>\n          <br />\n          <Typography>{t('labelFAQ2AnswerLine9')}</Typography>\n          <br />\n          <Typography>{t('labelFAQ2AnswerLine10')}</Typography>\n          <Typography component={'q'}>{t('labelFAQ2AnswerLine11')}</Typography>\n        </Box>\n      ),\n      // opened: openedFaq === 1,\n      // onClick: () => setOpenedFaq(1)\n    },\n    {\n      question: `What is the Dual Investment Sell covered gain ?`,\n      answer: (\n        <Box>\n          <Typography>{t('labelFAQ3AnswerLine1')}</Typography>\n          <br />\n          <Typography>{t('labelFAQ3AnswerLine2')}</Typography>\n\n          <Typography component={'li'}>{t('labelFAQ3AnswerLine3')}</Typography>\n          <Typography component={'li'}>{t('labelFAQ3AnswerLine4')}</Typography>\n          <br />\n\n          <Typography>{t('labelFAQ3AnswerLine5')}</Typography>\n          <Typography>{t('labelFAQ3AnswerLine6')}</Typography>\n          <br />\n          <Typography>{t('labelFAQ3AnswerLine7')}</Typography>\n          <br />\n          <Typography>{t('labelFAQ3AnswerLine8')}</Typography>\n          <Typography>{t('labelFAQ3AnswerLine9')}</Typography>\n          <br />\n          <Typography>{t('labelFAQ3AnswerLine10')}</Typography>\n          <br />\n          <Typography>{t('labelFAQ3AnswerLine11')}</Typography>\n          <Typography>{t('labelFAQ3AnswerLine12')}</Typography>\n          <br />\n          <Typography>{t('labelFAQ3AnswerLine13')}</Typography>\n          <br />\n          <Typography>{t('labelFAQ3AnswerLine14')}</Typography>\n        </Box>\n      ),\n      // opened: openedFaq === 1,\n      // onClick: () => setOpenedFaq(1)\n    },\n    {\n      question: `What is the Dual Investment Buy the dip ?`,\n      answer: (\n        <Box>\n          <Typography>{t('labelFAQ4AnswerLine1')}</Typography>\n          <br />\n          <Typography>{t('labelFAQ4AnswerLine2')}</Typography>\n\n          <Typography component={'li'}>{t('labelFAQ4AnswerLine3')}</Typography>\n          <Typography component={'li'}>{t('labelFAQ4AnswerLine4')}</Typography>\n          <br />\n\n          <Typography>{t('labelFAQ4AnswerLine5')}</Typography>\n          <Typography>{t('labelFAQ4AnswerLine6')}</Typography>\n          <br />\n          <Typography>{t('labelFAQ4AnswerLine7')}</Typography>\n          <br />\n          <Typography>{t('labelFAQ4AnswerLine8')}</Typography>\n          <Typography>{t('labelFAQ4AnswerLine9')}</Typography>\n          <br />\n          <Typography>{t('labelFAQ4AnswerLine10')}</Typography>\n          <br />\n          <Typography>{t('labelFAQ4AnswerLine11')}</Typography>\n          <Typography>{t('labelFAQ4AnswerLine12')}</Typography>\n          <br />\n          <Typography>{t('labelFAQ4AnswerLine13')}</Typography>\n          <br />\n          <Typography>{t('labelFAQ4AnswerLine14')}</Typography>\n        </Box>\n      ),\n    },\n  ]\n  const connectStatus: 'connected' | 'locked' | 'notConnected' =\n    account.account.readyState === 'ACTIVATED'\n      ? 'connected'\n      : account.account.readyState === 'LOCKED'\n      ? 'locked'\n      : 'notConnected'\n\n  const theme = useTheme()\n  const _btnClickMap = Object.assign(cloneDeep(btnClickMap), {})\n  const [highlightedAnimationCard, setHighlightedAnimationCard] = React.useState(0)\n\n  // const highlightedAnimationCard=0\n  const productsRef = React.useRef<HTMLDivElement>()\n  const location = useLocation()\n\n  React.useEffect(() => {\n    if (new URLSearchParams(location.search).get('scrollToProducts') === 'true') {\n      setTimeout(() => {\n        productsRef.current?.scrollIntoView({\n          behavior: 'smooth',\n          block: 'center',\n          inline: 'nearest',\n        })\n      }, 500)\n    }\n  }, [productsRef])\n\n  return (\n    <Box display={'flex'} justifyContent={'center'} width={'100%'}>\n      <Box\n        display={'flex'}\n        flexDirection={'column'}\n        width={'100%'}\n        marginBottom={2}\n        maxWidth={'964px'}\n        justifyContent={'center'}\n      >\n        <Box\n          marginTop={12}\n          display={'flex'}\n          justifyContent={'center'}\n          flexDirection={'column'}\n          width={'100%'}\n        >\n          <Typography variant={'h1'} textAlign={'center'}>\n            {t('labelDualEarnTitle')}\n          </Typography>\n          <Typography\n            marginTop={2}\n            variant={'h5'}\n            color={'var(--color-text-secondary)'}\n            textAlign={'center'}\n          >\n            {t('labelDualEarnSubTitle')}\n          </Typography>\n        </Box>\n\n        <Box\n          marginTop={3}\n          display={'flex'}\n          flexDirection={isMobile ? 'column' : 'row'}\n          alignItems={isMobile ? 'center' : 'auto'}\n          justifyContent={'center'}\n        >\n          <TextTag isMobile={isMobile}>\n            <Typography>{t('labelDualEarnTag1')}</Typography>\n          </TextTag>\n          <TextTag isMobile={isMobile}>\n            <Typography>{t('labelDualEarnTag2')}</Typography>\n          </TextTag>\n          <TextTag isMobile={isMobile}>\n            <Typography>{t('labelDualEarnTag3')}</Typography>\n          </TextTag>\n        </Box>\n\n        <Box ref={productsRef} component={'div'} id={'products'} marginTop={15}>\n          {dualTokenList && dualTokenList.length !== 0 ? (\n            <Box display={'flex'} flexDirection={isMobile ? 'column' : 'row'} flexWrap={'wrap'}>\n              {dualTokenList.map((info, index) => {\n                return (\n                  <EarnCard\n                    isMobile={isMobile}\n                    key={info.symbol}\n                    marginRight={index % 3 === 2 ? '0' : '2%'}\n                  >\n                    <Box\n                      sx={{\n                        height: 64,\n                        display: 'flex',\n                        justifyContent: 'center',\n                        alignItems: 'center',\n                      }}\n                    >\n                      <CoinIcon size={64} symbol={info.symbol} />\n                    </Box>\n\n                    {/* <Box width={64} height={64} src={info.imgSrc} component={'img'} /> */}\n                    <Typography variant={'h3'} marginTop={2}>\n                      {info.tag === 'sellCover'\n                        ? t('labelInvestSymbolSellHigh', {\n                            symbol: info.symbol,\n                          })\n                        : t('labelInvestSymbolBuyLow', {\n                            symbol: info.symbol,\n                          })}\n                    </Typography>\n                    <Box\n                      marginBottom={4}\n                      justifyContent={'center'}\n                      alignItems={'center'}\n                      marginTop={7}\n                      display={'flex'}\n                    >\n                      <Box>\n                        <Typography color={'var(--color-success)'} textAlign={'center'}>\n                          {t('labelApy')}\n                        </Typography>\n                        <Typography\n                          variant={'h4'}\n                          color={'var(--color-success)'}\n                          textAlign={'center'}\n                        >\n                          {info.apy}\n                        </Typography>\n                      </Box>\n                      <Box\n                        width={'1px'}\n                        height={24}\n                        marginX={1.5}\n                        bgcolor={'var(--color-border)'}\n                      />\n                      <Box>\n                        <Typography textAlign={'center'}>{t('labelCurrentPrice')}</Typography>\n                        <Typography variant={'h4'} textAlign={'center'}>\n                          {info.price}\n                        </Typography>\n                      </Box>\n                    </Box>\n\n                    <Button\n                      onClick={() => {\n                        history.push(\n                          `/invest/dual?viewType=${\n                            info.tag === 'buyDip' ? 'DualDip' : 'DualGain'\n                          }&autoChose=${info.symbol}`,\n                        )\n                      }}\n                      variant={'contained'}\n                      fullWidth\n                    >\n                      {t('labelViewDetails')}\n                    </Button>\n                  </EarnCard>\n                )\n              })}\n            </Box>\n          ) : (\n            <Box\n              display={'flex'}\n              justifyContent={'center'}\n              alignItems={'center'}\n              height={'150px'}\n              width={'100%'}\n            >\n              <img width={60} src={SoursURL + 'images/loading-line.gif'} />\n            </Box>\n          )}\n        </Box>\n        <Box\n          marginTop={12.5}\n          paddingTop={7}\n          paddingBottom={10}\n          justifyContent={'center'}\n          borderRadius={3}\n          bgcolor={'var(--color-primary)'}\n        >\n          <Typography\n            color={'var(--color-text-button)'}\n            textAlign={'center'}\n            marginBottom={3}\n            variant={'h2'}\n          >\n            {t('labelLoopringEarn')}\n          </Typography>\n          <Typography\n            paddingX={14}\n            color={'var(--color-text-button)'}\n            textAlign={'center'}\n            variant={'h5'}\n          >\n            {t('labelLoopringEarnDes')}{' '}\n          </Typography>\n        </Box>\n        <Box marginTop={12.5}>\n          <Typography textAlign={'center'} variant={'h2'}>\n            {t('labelLoopringProtocol')}\n          </Typography>\n          <Typography\n            textAlign={'center'}\n            variant={'h5'}\n            color={'var(--color-text-secondary)'}\n            marginTop={2}\n          >\n            {t('labelLoopringProtocolDes')}\n          </Typography>\n        </Box>\n        <Box marginTop={5} display={'flex'} flexDirection={isMobile ? 'column' : 'row'}>\n          <AnimationCard\n            justifyContent={'space-between'}\n            highlighted={highlightedAnimationCard === 0}\n            onMouseOver={() => setHighlightedAnimationCard(0)}\n            marginRight={'2.06%'}\n            isMobile={isMobile}\n          >\n            <Box>\n              <Typography variant={'h3'} className={'title'}>\n                {t('labelUltimateSecurity')}\n              </Typography>\n              <Typography className={'sub-title'}>{t('labelUltimateSecurityDes')}</Typography>\n            </Box>\n\n            <img\n              src={\n                SoursURL +\n                (theme.mode === 'dark'\n                  ? 'images/web-earn/animation_card_d1.svg'\n                  : 'images/web-earn/animation_card_l1.svg')\n              }\n            />\n          </AnimationCard>\n          <AnimationCard\n            justifyContent={'space-between'}\n            highlighted={highlightedAnimationCard === 1}\n            onMouseOver={() => setHighlightedAnimationCard(1)}\n            marginRight={'2.06%'}\n            isMobile={isMobile}\n          >\n            <Box>\n              <Typography variant={'h3'} className={'title'}>\n                {t('labelLowTransactionFees')}\n              </Typography>\n              <Typography className={'sub-title'}>{t('labelLowTransactionFeesDes')}</Typography>\n            </Box>\n            <img\n              src={\n                SoursURL +\n                (theme.mode === 'dark'\n                  ? 'images/web-earn/animation_card_d2.svg'\n                  : 'images/web-earn/animation_card_l2.svg')\n              }\n            />\n          </AnimationCard>\n          <AnimationCard\n            justifyContent={'space-between'}\n            highlighted={highlightedAnimationCard === 2}\n            onMouseOver={() => setHighlightedAnimationCard(2)}\n            isMobile={isMobile}\n          >\n            <Box>\n              <Typography variant={'h3'} className={'title'}>\n                {t('labelHighThroughput')}\n              </Typography>\n              <Typography variant={'h5'} className={'sub-title'}>\n                {t('labelHighThroughputDes')}\n              </Typography>\n            </Box>\n            <img\n              src={\n                SoursURL +\n                (theme.mode === 'dark'\n                  ? 'images/web-earn/animation_card_d3.svg'\n                  : 'images/web-earn/animation_card_l3.svg')\n              }\n            />\n          </AnimationCard>\n        </Box>\n\n        <Typography textAlign={'center'} marginTop={12.5} variant={'h2'}>\n          {t('labelFAQs')}\n        </Typography>\n        <Box marginTop={5} marginBottom={12.5}>\n          {faqs.map((faq, index) => {\n            const opened = openedFaqs.includes(index)\n            return (\n              <FAQ opend={openedFaqs.includes(index)} key={faq.question}>\n                <Box\n                  onClick={() => {\n                    if (opened) {\n                      setOpenedFaqs(difference(openedFaqs, [index]))\n                    } else {\n                      setOpenedFaqs(openedFaqs.concat(index))\n                    }\n                  }}\n                  sx={{ cursor: 'pointer' }}\n                  display={'flex'}\n                  justifyContent={'space-between'}\n                >\n                  <Typography marginBottom={2} variant={'h3'}>\n                    {faq.question}\n                  </Typography>\n                  <BackIcon\n                    sx={{\n                      transform: opened ? 'rotate(90deg)' : 'rotate(270deg)',\n                      cursor: 'pointer',\n                    }}\n                    htmlColor={'var(--color-text-secondary)'}\n                  />\n                </Box>\n                {opened && (\n                  <Box sx={{ '& .MuiTypography-root': { color: 'var(--color-text-secondary)' } }}>\n                    {faq.answer}\n                  </Box>\n                )}\n              </FAQ>\n            )\n          })}\n        </Box>\n      </Box>\n    </Box>\n  )\n})\n"
  },
  {
    "path": "packages/web-earn/src/pages/ErrorPage/index.tsx",
    "content": "import { Trans, useTranslation } from 'react-i18next'\nimport { Box, Container, Link, Typography } from '@mui/material'\nimport styled from '@emotion/styled'\nimport { ErrorObject, SoursURL } from '@loopring-web/common-resources'\nimport { getContactInfo } from '@loopring-web/core'\n\nconst StyleBox = styled(Box)`\n  background-image: url('${SoursURL}error_bg.png');\n  background-repeat: no-repeat;\n  background-size: contain;\n  background-position: bottom;\n  white-space: pre-wrap;\n  //h2{\n  //  position: relative;\n  //}\n` as typeof Box\n\nexport const ErrorPage = ({ messageKey, arg, components }: ErrorObject) => {\n  const message = `labelConnectUs`\n  return (\n    <>\n      <Container style={{ flex: 1 }}>\n        {/*style={{height: '100%' }}*/}\n        <StyleBox\n          flex={1}\n          display={'flex'}\n          alignItems={'flex-start'}\n          justifyContent={'center'}\n          flexDirection={'column'}\n          marginTop={4}\n          height={680}\n          maxWidth={1200}\n        >\n          {/*<StyleBox>*/}\n          <Box textAlign={'center'} position={'relative'} left={128} top={-64}>\n            <Typography component={'h2'} variant={'h3'} whiteSpace={'pre-line'}>\n              <Trans\n                i18nKey={messageKey}\n                tOptions={arg ? { ...arg } : undefined}\n                ns={['error', 'common']}\n                components={components ? { ...components } : undefined}\n              />\n            </Typography>\n            <Typography\n              marginY={2}\n              component={'p'}\n              variant={'body1'}\n              color={'textSecondary'}\n              whiteSpace={'pre-line'}\n            >\n              <Trans i18nKey={message}>\n                If you believe this is indeed a bug, please\n                <Link\n                  component={'a'}\n                  sx={{\n                    display: 'inline-flex',\n                  }}\n                  onClick={(e) => {\n                    window.open(getContactInfo(), '_blank')\n                    window.opener = null\n                    e.preventDefault()\n                  }}\n                >\n                  &nbsp; contact us\n                </Link>\n                <br /> We would appreciate your feedback\n              </Trans>\n            </Typography>\n          </Box>\n          {/*</StyleBox>*/}\n        </StyleBox>\n      </Container>\n\n      {/*<Footer></Footer>*/}\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/web-earn/src/pages/IntroPage/index.tsx",
    "content": "import { useTheme } from '@emotion/react';\nimport styled from '@emotion/styled';\nimport { CloseIcon, ToRightTopArrow, hexToRGB } from '@loopring-web/common-resources';\nimport { useSettings, useToggle } from '@loopring-web/component-lib';\nimport { SoursURL } from '@loopring-web/loopring-sdk';\nimport { Box, BoxProps, Button, ContainerProps, useMediaQuery } from '@mui/material';\n// import { styled } from '@mui/material';\nimport { Container, Typography, IconButton, Card, CardMedia, CardContent, Grid } from '@mui/material';\nimport React, { useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { useHistory } from 'react-router';\nimport { useConfirmation } from '@loopring-web/core/src/stores/localStore/confirmation';\n// import { confirmation } from '@loopring-web/core';\n\nconst LoopringDeFiLaunchPopup = ({ onClose }) => {\n  const theme =useTheme()\n  return (\n    <Box\n      sx={{\n        position: 'absolute',\n        maxWidth: '95%',\n        width: '428px',\n        backgroundColor: theme.mode === 'dark' ? 'var(--color-global-bg)' : '#F9F9FE',\n        padding: 4,\n        boxShadow: 3,\n        borderRadius: '24px',\n        textAlign: 'center',\n        zIndex: 10,\n        left: 90,\n        top: 200,\n      }}\n    >\n      <CloseIcon\n        className='tag'\n        sx={{\n          position: 'absolute',\n          right: 16,\n          top: 20,\n          color: 'var(--color-text-primary)',\n          cursor: 'pointer',\n        }}\n        style={{ width: 20, height: 20 }}\n        onClick={onClose}\n        component={'svg'}\n      />\n      <Typography variant='h3' sx={{ marginBottom: 2 }} mt={3}>\n        Loopring DeFi Launches on Taiko!\n      </Typography>\n      <Box display='flex' justifyContent='center' mb={3} width={'100%'}>\n        <Box\n          src={`${SoursURL}earn/taiko_up.png`}\n          alt='Loopring DeFi Launch'\n          style={{ width: '95%' }}\n          component={'img'}\n        />\n      </Box>\n      <Typography variant='body1'>\n        Loopring DeFi is expanding to various EVM-compatible networks using its trustless, time-tested ZK-Rollup protocol. The first deployment will be on Taiko. Join us for an exciting journey ahead!\n\n      </Typography>\n    </Box>\n  )\n};\n\nconst AnimationCard = styled(Box)<{ highlighted: boolean; isMobile: boolean }>`\n  display: flex;\n  flex-direction: column;\n  background-color: ${({ theme }) => theme.mode === 'dark' ? hexToRGB('#393E47', 0.3) : '#FFFFFF'};\n  border-radius: 12px;\n  padding-top: ${({ theme }) => theme.unit * 8}px;\n  padding-left: ${({ theme }) => theme.unit * 5}px;\n  padding-right: ${({ theme }) => theme.unit * 4}px;\n  padding-bottom: ${({ theme }) => theme.unit * 2.5}px;\n  height: 390px;\n  height: ${({ isMobile }) => (isMobile ? '290px' : '390px')};\n  width: ${({ highlighted, isMobile }) => (isMobile ? '100%' : highlighted ? '55.08%' : '20.4%')};\n  transition: all 0.5s ease;\n  border: ${({ highlighted, isMobile }) =>\n    !isMobile && highlighted\n      ? '1px solid var(--color-primary)'\n      : '0.5px solid var(--color-border)'};\n  overflow: hidden;\n  .title {\n    margin-bottom: ${({ theme }) => theme.unit * 3}px;\n  }\n  .sub-title {\n    color: var(--color-text-secondary);\n    display: ${({ highlighted, isMobile }) => (isMobile || highlighted ? '' : 'none')};\n    max-height: 30px;\n  }\n  img {\n    height: 134px;\n    width: 134px;\n    align-self: end;\n    margin-right: ${({ highlighted, isMobile }) => (isMobile || highlighted ? '0px' : '-60px')};\n    opacity: ${({ highlighted, isMobile }) => (isMobile || highlighted ? '1' : '0.5')};\n    transition: all 0.5s ease;\n  }\n  margin-bottom: ${({ isMobile, theme }) => (isMobile ? `${theme.unit * 2.5}px` : 'auto')};\n`\n\ntype SectionProps = {\n  title:string\n  des1:string\n  des2:string\n  viewMoreLink:string\n  imgURL?:string\n} & BoxProps\n\n\n\nconst Section: React.FC<SectionProps> = (props) => {\n  const { title, des1, des2, viewMoreLink, imgURL, sx, ref,...rest } = props\n  const theme = useTheme()\n  const isCompact = useMediaQuery('(max-width:720px)')\n  const history = useHistory()\n  const { t } = useTranslation('common')\n  return (\n    <Box\n      sx={{\n        display: 'flex',\n        justifyContent: 'center',\n        backgroundColor: theme.mode === 'dark' ? '#061021' : '#FFFFFF',\n        color: 'var(--color-text-primary)',\n        flexDirection: 'column',\n        paddingX: 7.25,\n        paddingY: 8,\n        width:'1152px',\n        maxWidth:'90%',\n        borderRadius: '12px',\n        ...sx,\n      }}\n      ref={ref}\n      {...rest}\n    >\n      <Typography\n        gutterBottom\n        sx={{\n          fontSize: '30px',\n          marginBottom: 9,\n          fontWeight: 500,\n        }}\n        color={'var(--color-text-primary)'}\n        textAlign={'center'}\n      >\n        {title}\n      </Typography>\n      <Box width={'100%'} display={'flex'} justifyContent={'space-between'} alignItems={'center'}>\n        <Box width={isCompact ? '100%' : '45%'}>\n          <Typography\n            paragraph\n            sx={{\n              fontSize: '24px',\n              marginBottom: 3,\n              fontWeight: 500,\n            }}\n            color={'var(--color-text-primary)'}\n          >\n            {des1}\n          </Typography>\n          <Typography\n            paragraph\n            sx={{\n              fontSize: '20px',\n              marginBottom: 5,\n              fontWeight: 300,\n            }}\n            color={'var(--color-text-primary)'}\n          >\n            {des2}\n          </Typography>\n          <Button\n            variant='contained'\n            sx={{\n              fontSize: '16px',\n              fontWeight: 400,\n            }}\n            onClick={() => history.push(viewMoreLink)}\n          >\n            {t('labelLaunch')}{' '}\n            <ToRightTopArrow\n              sx={{ marginLeft: 1, fontSize: '24px', fill: 'var(--color-text-button)' }}\n            />{' '}\n          </Button>\n        </Box>\n        <Box width={'45%'} display={isCompact ? 'none' : 'block'}>\n          <CardMedia\n            component='img'\n            image={imgURL}\n            alt='Dual Investment Info'\n            sx={{\n              \n              height: 'auto',\n              zIndex: 1,\n            }}\n          />\n        </Box>\n      </Box>\n    </Box>\n  )\n}\n\ninterface IntroProps {\n  \n}\n\nconst Intro: React.FC<IntroProps> = ({  }) => {\n  const { isMobile } = useSettings()\n  \n  const [state, setState] = useState({\n    highlightedAnimationCard: 0\n  })\n  const theme = useTheme()\n  const {t} = useTranslation('webEarn')\n  const isCompact = useMediaQuery('(max-width:720px)');\n  const history = useHistory()\n  const dual = React.useRef(null)\n  const {setShowTaikoLaunchBanner, confirmation} = useConfirmation()\n  const {\n    toggle: { taikoFarming },\n  } = useToggle()\n  return (\n    <Box\n      marginTop={'calc(var(--header-height) * -1)'}\n      position={'relative'}\n      sx={{ bgcolor: theme.mode === 'light' ? '#F5F7FC' : '#25282E' }}\n    >\n      {confirmation.showTaikoLaunchBanner && <LoopringDeFiLaunchPopup onClose={() => {\n        setShowTaikoLaunchBanner(false)\n      }}/>} \n      <Box\n        component={'img'}\n        src={`${SoursURL}earn/intro_bg_2.png`}\n        position={'absolute'}\n        left={'50%'}\n        top={-26}\n        sx={{\n          transform: 'translateX(-50%)',\n        }}\n        zIndex={2}\n      />\n      <Box\n        component={'img'}\n        src={`${SoursURL}earn/intro_bg_1.png`}\n        position={'absolute'}\n        left={0}\n        right={0}\n        top={0}\n        width={'100%'}\n        zIndex={1}\n      />\n      \n      <Box\n        width={'100%'}\n        zIndex={3}\n        sx={{\n          marginTop: 17,\n          display: 'flex',\n          justifyContent: 'center',\n          flexDirection: 'column',\n          alignItems: 'center',\n          position: 'relative',\n        }}\n      >\n        <Typography\n          width={'1152px'}\n          maxWidth={'90%'}\n          fontWeight={700}\n          fontSize={'64px'}\n          textAlign={'center'}\n          marginBottom={3}\n        >\n          {t('labelLoopringDeFi')}\n        </Typography>\n        <Typography\n          width={'1152px'}\n          maxWidth={'90%'}\n          marginBottom={4}\n          fontSize={'40px'}\n          textAlign={'center'}\n        >\n          {' '}\n          {t('labelIntroDes1')}\n          <br />\n          {t('labelIntroDes2')}\n        </Typography>\n        <Typography\n          width={'1152px'}\n          maxWidth={'90%'}\n          marginBottom={15}\n          fontSize={'20px'}\n          textAlign={'center'}\n        >\n          {t('labelIntroDes3')}\n        </Typography>\n        {taikoFarming.enable && (\n          <Section\n            title={t('labelInvestTaikoFarmingTitle')}\n            des1={t('labelInvestTaikoFarmingDes1')}\n            des2={t('labelInvestTaikoFarmingDes2')}\n            viewMoreLink='/taiko-farming'\n            imgURL={\n              SoursURL +\n              (theme.mode === 'dark'\n                ? 'earn/intro_screenshot_0.png'\n                : 'earn/intro_screenshot_0_light.png')\n            }\n            marginBottom={6}\n            sx={{\n              bgcolor: theme.mode === 'dark' ? hexToRGB('#303339', 0.8) : '#FFFFFF',\n            }}\n          />\n        )}\n        <Section\n          title={t('labelInvestDualTitle')}\n          des1={t('labelInvestDualDes1')}\n          des2={t('labelInvestDualDes2')}\n          viewMoreLink='/invest/dual'\n          imgURL={\n            SoursURL +\n            (theme.mode === 'dark'\n              ? 'earn/intro_screenshot_1.png'\n              : 'earn/intro_screenshot_1_light.png')\n          }\n          marginBottom={6}\n          sx={{\n            bgcolor: theme.mode === 'dark' ? hexToRGB('#393E47', 0.8) : '#FFFFFF',\n          }}\n          // ref={dual}\n        />\n        <Section\n          title={t('labelVault')}\n          des1={t('labelPortalDes1')}\n          des2={t('labelPortalDes2')}\n          viewMoreLink='/portal'\n          imgURL={\n            SoursURL +\n            (theme.mode === 'dark'\n              ? 'earn/intro_screenshot_2.png'\n              : 'earn/intro_screenshot_2_light.png')\n          }\n          marginBottom={6}\n          sx={{\n            bgcolor: theme.mode === 'dark' ? '#2A3A41' : '#E2F7F7',\n          }}\n        />\n        <Section\n          title={t('labelBtradeSwapTitle')}\n          des1={t('labelBtradeDes1')}\n          des2={t('labelBtradeDes2')}\n          viewMoreLink='/trade/btrade'\n          imgURL={\n            SoursURL +\n            (theme.mode === 'dark'\n              ? 'earn/intro_screenshot_3.png'\n              : 'earn/intro_screenshot_3_light.png')\n          }\n          sx={{\n            bgcolor: theme.mode === 'dark' ? '#2D3449' : '#E5F3FF',\n          }}\n        />\n      </Box>\n      <Box paddingTop={20}>\n        <Typography textAlign={'center'} fontSize={'45px'} fontWeight={800}>\n          {t('labelLoopringProtocol')}\n        </Typography>\n        <Typography\n          textAlign={'center'}\n          color={'var(--color-text-secondary)'}\n          marginTop={3}\n          fontSize={'24px'}\n          fontWeight={300}\n        >\n          {t('labelLoopringProtocolDes')}\n        </Typography>\n      </Box>\n      <Box display={'flex'} justifyContent={'center'}>\n        <Box\n          display={'flex'}\n          flexDirection={isMobile ? 'column' : 'row'}\n          paddingY={10}\n          width={'70%'}\n        >\n          <AnimationCard\n            justifyContent={'space-between'}\n            highlighted={state.highlightedAnimationCard === 0}\n            onMouseOver={() => setState({ ...state, highlightedAnimationCard: 0 })}\n            marginRight={'2.06%'}\n            isMobile={isMobile}\n          >\n            <Box>\n              <Typography variant={'h3'} className={'title'}>\n                {t('labelUltimateSecurity')}\n              </Typography>\n              <Typography className={'sub-title'}>{t('labelUltimateSecurityDes')}</Typography>\n            </Box>\n\n            <img\n              src={\n                SoursURL +\n                (theme.mode === 'dark'\n                  ? 'images/web-earn/animation_card_d1.svg'\n                  : 'images/web-earn/animation_card_l1.svg')\n              }\n            />\n          </AnimationCard>\n          <AnimationCard\n            justifyContent={'space-between'}\n            highlighted={state.highlightedAnimationCard === 1}\n            onMouseOver={() => setState({ ...state, highlightedAnimationCard: 1 })}\n            marginRight={'2.06%'}\n            isMobile={isMobile}\n          >\n            <Box>\n              <Typography variant={'h3'} className={'title'}>\n                {t('labelLowTransactionFees')}\n              </Typography>\n              <Typography className={'sub-title'}>{t('labelLowTransactionFeesDes')}</Typography>\n            </Box>\n            <img\n              src={\n                SoursURL +\n                (theme.mode === 'dark'\n                  ? 'images/web-earn/animation_card_d2.svg'\n                  : 'images/web-earn/animation_card_l2.svg')\n              }\n            />\n          </AnimationCard>\n          <AnimationCard\n            justifyContent={'space-between'}\n            highlighted={state.highlightedAnimationCard === 2}\n            onMouseOver={() => setState({ ...state, highlightedAnimationCard: 2 })}\n            isMobile={isMobile}\n          >\n            <Box>\n              <Typography variant={'h3'} className={'title'}>\n                {t('labelHighThroughput')}\n              </Typography>\n              <Typography variant={'h5'} className={'sub-title'}>\n                {t('labelHighThroughputDes')}\n              </Typography>\n            </Box>\n            <img\n              src={\n                SoursURL +\n                (theme.mode === 'dark'\n                  ? 'images/web-earn/animation_card_d3.svg'\n                  : 'images/web-earn/animation_card_l3.svg')\n              }\n            />\n          </AnimationCard>\n        </Box>\n      </Box>\n      <Box display={'flex'} justifyContent={'center'}>\n        <Box\n          sx={{\n            display: 'flex',\n            // justifyContent: 'center',\n            color: 'var(--color-text-primary)',\n            flexDirection: 'column',\n            paddingX: 5,\n            paddingY: 8,\n            borderRadius: '12px',\n            bgcolor: theme.mode === 'dark' ? hexToRGB('#393E47', 0.3) : '#FFFFFF',\n            width: '1152px',\n            maxWidth: '90%',\n          }}\n          marginTop={8}\n          marginBottom={15}\n        >\n          \n            <Typography\n              paragraph\n              sx={{\n                fontSize: '24px',\n                marginBottom: 6,\n                fontWeight: 500,\n              }}\n              color={'var(--color-text-primary)'}\n            >\n              {t(\"labelReadyForDevelopers\")}\n            </Typography>\n            <Typography\n              paragraph\n              sx={{\n                fontSize: '20px',\n                marginBottom: 6,\n                fontWeight: 300,\n              }}\n              color={'var(--color-text-primary)'}\n            >\n              {t(\"labelReadyForDevelopersDes\")}\n              \n            </Typography>\n            <Button\n              variant='contained'\n              sx={{\n                fontSize: '16px',\n                fontWeight: 400,\n                width: '120px',\n              }}\n              onClick={() => \n                window.open('https://docs.loopring.io/', '_blank')}\n            >\n              {t('labelLaunch')}{' '}\n              <ToRightTopArrow\n                sx={{ marginLeft: 1, fontSize: '24px', fill: 'var(--color-text-button)' }}\n              />{' '}\n            </Button>\n        </Box>\n      </Box>\n    </Box>\n  )\n};\n\nexport default Intro;"
  },
  {
    "path": "packages/web-earn/src/pages/InvestPage/DeFiPanel/DeFiTradePanel.tsx",
    "content": "import { useDefiMap, useDefiTrade, confirmation } from '@loopring-web/core'\nimport { DEFI_ADVICE_MAP, MarketType } from '@loopring-web/common-resources'\nimport {\n  ConfirmDefiNOBalance,\n  DeFiWrap,\n  LoadingBlock,\n  useSettings,\n} from '@loopring-web/component-lib'\nimport { Box } from '@mui/material'\nimport React from 'react'\nimport { useTranslation } from 'react-i18next'\n\nexport const DeFiTradePanel = ({\n  isJoin,\n  market,\n  setServerUpdate,\n  setToastOpen,\n}: {\n  market: MarketType\n  isJoin: boolean\n  setServerUpdate: (state: any) => void\n  setToastOpen: (state: any) => void\n}) => {\n  const { marketArray } = useDefiMap()\n  const [confirmShowLimitBalance, setConfirmShowLimitBalance] = React.useState<boolean>(false)\n  const [confirmShowNoBalance, setConfirmShowNoBalance] = React.useState<boolean>(false)\n  const { deFiWrapProps } = useDefiTrade({\n    isJoin,\n    setToastOpen: setToastOpen as any,\n    market: market ? market : marketArray[0],\n    setServerUpdate,\n    setConfirmShowNoBalance,\n    confirmShowLimitBalance,\n    setConfirmShowLimitBalance,\n    isLeverageETH: false,\n  })\n  const { isMobile } = useSettings()\n  const [, tokenBase] = market.match(/(\\w+)-(\\w+)/i) ?? []\n  const styles = isMobile\n    ? { flex: 1, background: 'var(--color-box-third)' }\n    : { width: 'var(--swap-box-width)', background: 'var(--color-box-third)' }\n  const { t } = useTranslation()\n  const { setShowRETHStakePopup, setShowWSTETHStakePopup } = confirmation.useConfirmation()\n  return (\n    <>\n      {deFiWrapProps.deFiCalcData ? (\n        <Box\n          className={'hasLinerBg'}\n          display={'flex'}\n          style={styles}\n          justifyContent={'center'}\n          padding={5 / 2}\n          bgcolor={'var(--color-box-third)'}\n        >\n          <DeFiWrap\n            market={market}\n            isJoin={isJoin}\n            setShowRETHStakePopup={setShowRETHStakePopup}\n            setShowWSTETHStakePopup={setShowWSTETHStakePopup}\n            // setShowLeverageETHPopup={setShowLeverageETHPopup}\n            type={DEFI_ADVICE_MAP[tokenBase].project}\n            title={DEFI_ADVICE_MAP[tokenBase].project}\n            {...(deFiWrapProps as any)}\n          />\n        </Box>\n      ) : (\n        <LoadingBlock />\n      )}\n      <ConfirmDefiNOBalance\n        isJoin={isJoin}\n        market={market}\n        type={DEFI_ADVICE_MAP[tokenBase].project}\n        handleClose={(_e) => {\n          setConfirmShowNoBalance(false)\n          if (deFiWrapProps?.onRefreshData) {\n            deFiWrapProps?.onRefreshData(true, true)\n          }\n        }}\n        isLeverage={false}\n        open={confirmShowNoBalance}\n      />\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/web-earn/src/pages/InvestPage/DeFiPanel/index.tsx",
    "content": "import React from 'react'\nimport styled from '@emotion/styled'\nimport { Avatar, Box, Card, CardContent, Grid, Tooltip, Typography } from '@mui/material'\nimport { useTranslation, WithTranslation, withTranslation } from 'react-i18next'\nimport { DeFiTradePanel } from './DeFiTradePanel'\nimport {\n  boxLiner,\n  Button,\n  ConfirmInvestDefiServiceUpdate,\n  Toast,\n  useSettings,\n  LoadingBlock,\n  ConfirmInvestDefiRisk,\n  ToastType,\n} from '@loopring-web/component-lib'\nimport { confirmation, useDefiMap, useNotify, useToast } from '@loopring-web/core'\nimport { useHistory, useRouteMatch } from 'react-router-dom'\nimport {\n  BackIcon,\n  defiRETHAdvice,\n  defiWSTETHAdvice,\n  hexToRGB,\n  Info2Icon,\n  MarketType,\n  SatkingLogo,\n  TOAST_TIME,\n  UpColor,\n} from '@loopring-web/common-resources'\nimport { MaxWidthContainer, containerColors } from '..'\nimport { useTheme } from '@emotion/react'\n\nexport const StyleWrapper = styled(Box)`\n  position: relative;\n  border-radius: ${({ theme }) => theme.unit}px;\n\n  .loading-block {\n    background: initial;\n  }\n\n  .hasLinerBg {\n    ${({ theme }) => boxLiner({ theme })}\n  }\n\n  border-radius: ${({ theme }) => theme.unit}px;\n` as typeof Grid\nexport const StyleCardContent = styled(CardContent)`\n  display: flex;\n\n  &.tableLap {\n    display: block;\n    width: 100%;\n    cursor: pointer;\n\n    .content {\n      flex-direction: column;\n      align-items: center;\n      padding-top: ${({ theme }) => 4 * theme.unit}px;\n\n      .des {\n        align-items: center;\n        margin: ${({ theme }) => 3 * theme.unit}px 0;\n      }\n      .backIcon {\n        display: none;\n      }\n    }\n  }\n\n  padding: 0;\n  &:last-child {\n    padding: 0;\n  }\n\n  &.isMobile {\n    flex: 1;\n\n    .content {\n      flex-direction: row;\n      width: 100%;\n\n      .des {\n        margin-left: ${({ theme }) => 2 * theme.unit}px;\n        align-items: flex-start;\n      }\n    }\n  }\n` as typeof CardContent\n\nconst LandDefiInvest = ({\n  setConfirmedDefiInvest,\n}: {\n  setConfirmedDefiInvest: (props: { isShow: boolean; type: 'RETH' | 'WSETH' }) => void\n}) => {\n  const history = useHistory()\n  const { notifyMap } = useNotify()\n  const { marketMap: defiMarketMap } = useDefiMap()\n  const { t } = useTranslation('common')\n  const { isMobile, upColor } = useSettings()\n  const {\n    confirmation: { confirmedRETHDefiInvest, confirmedWSETHDefiInvest },\n  } = confirmation.useConfirmation()\n  // const {\n  //   confirmedRETHDefiInvest: confirmedRETHDefiInvestFun,\n  //   confirmedWSETHDefiInvest: confirmedWSETHDefiInvestFun,\n  // } = confirmation.useConfirmation();\n\n  const investAdviceList = [\n    {\n      ...defiWSTETHAdvice,\n      ...(notifyMap?.invest?.STAKE ? notifyMap?.invest?.STAKE[0] : {}),\n      click: () => {\n        if (!confirmedWSETHDefiInvest) {\n          setConfirmedDefiInvest({ isShow: true, type: 'WSETH' })\n        } else {\n          history.push(defiWSTETHAdvice.router)\n        }\n      },\n      apy: defiMarketMap[defiWSTETHAdvice?.market ?? '']?.apy,\n    },\n    {\n      ...defiRETHAdvice,\n      ...(notifyMap?.invest?.STAKE ? notifyMap?.invest?.STAKE[1] : {}),\n      click: () => {\n        if (!confirmedRETHDefiInvest) {\n          setConfirmedDefiInvest({ isShow: true, type: 'RETH' })\n        } else {\n          history.push(defiRETHAdvice.router)\n        }\n      },\n      apy: defiMarketMap[defiRETHAdvice?.market ?? '']?.apy,\n    },\n  ]\n\n  return (\n    <Box flex={1} display={'flex'} alignItems={'center'} alignSelf={'stretch'}>\n      <Grid container spacing={isMobile ? 2 : 4} padding={3} flex={1} justifyContent={'center'}>\n        {investAdviceList.map((item, index) => {\n          return (\n            <React.Fragment key={item.type + index}>\n              {item.enable ? (\n                <Grid item xs={12} md={4} lg={3}>\n                  <Card\n                    sx={{ display: 'flex', bgcolor: 'var(--color-box-third)' }}\n                    onClick={item.click}\n                  >\n                    <StyleCardContent className={isMobile ? 'isMobile' : 'tableLap'}>\n                      <Box\n                        className={'content'}\n                        display={'flex'}\n                        flexDirection={'row'}\n                        alignItems={'center'}\n                      >\n                        <Avatar\n                          variant='circular'\n                          style={{\n                            height: 'var(--svg-size-huge)',\n                            width: 'var(--svg-size-huge)',\n                          }}\n                          src={item.banner}\n                        />\n                        <Box\n                          flex={1}\n                          display={'flex'}\n                          flexDirection={'column'}\n                          paddingLeft={1}\n                          className={'des'}\n                        >\n                          <Typography variant={'h4'}>\n                            {t(item.titleI18n, { ns: 'layout' })}\n                          </Typography>\n                          <Typography\n                            variant={'body2'}\n                            textOverflow={'ellipsis'}\n                            whiteSpace={'pre'}\n                            overflow={'hidden'}\n                            color={'textSecondary'}\n                          >\n                            {t(item.desI18n, { ns: 'layout' })}\n                          </Typography>\n                          {isMobile ? (\n                            <Typography\n                              variant={'body1'}\n                              textOverflow={'ellipsis'}\n                              whiteSpace={'pre'}\n                              overflow={'hidden'}\n                              paddingTop={1}\n                              color={\n                                upColor === UpColor.green\n                                  ? 'var(--color-success)'\n                                  : 'var(--color-error)'\n                              }\n                            >\n                              {'APR: ' + item.apy + '%'}\n                            </Typography>\n                          ) : (\n                            <Typography\n                              display={'flex'}\n                              flexDirection={'column'}\n                              alignItems={'center'}\n                              marginTop={2}\n                              component={'span'}\n                            >\n                              <Typography\n                                variant={'h3'}\n                                component={'span'}\n                                color={\n                                  upColor === UpColor.green\n                                    ? 'var(--color-success)'\n                                    : 'var(--color-error)'\n                                }\n                              >\n                                {item.apy + '%'}\n                              </Typography>\n                              <Tooltip title={t('labelEstRateAprDes').toString()}>\n                                <Typography\n                                  variant={'body2'}\n                                  component={'span'}\n                                  display={'inline-flex'}\n                                  alignItems={'center'}\n                                  color={'var(--color-text-third)'}\n                                >\n                                  {t('labelEstRateApr')}\n                                  <Info2Icon color={'inherit'} sx={{ marginLeft: 1 / 2 }} />\n                                </Typography>\n                              </Tooltip>\n                            </Typography>\n                          )}\n                        </Box>\n                        {isMobile ? (\n                          <BackIcon\n                            className={'backIcon'}\n                            fontSize={'small'}\n                            htmlColor={'var(--color-text-third)'}\n                            sx={{\n                              transform: 'rotate(180deg)',\n                            }}\n                          />\n                        ) : (\n                          <Button variant={'contained'} fullWidth={true} size={'medium'}>\n                            {t('labelInvestBtn')}\n                          </Button>\n                        )}\n                      </Box>\n                    </StyleCardContent>\n                  </Card>\n                </Grid>\n              ) : (\n                ''\n              )}\n            </React.Fragment>\n          )\n        })}\n      </Grid>\n    </Box>\n  )\n}\n\nconst ButtonStyled = styled(Button)`\n  background-color: var(--color-button-outlined);\n  color: var(--color-text-primary);\n  :hover {\n    background-color: var(--color-button-outlined);\n    ::before {\n      border-radius: 4px;\n    }\n  }\n`\n\nexport const DeFiPanel: any = withTranslation('common')(({ t }: WithTranslation & {}) => {\n  const { marketArray } = useDefiMap()\n  const {\n    confirmation: { confirmationNeeded, showRETHStakePopup, showWSTETHStakePopup },\n    setShowRETHStakePopup,\n    setShowWSTETHStakePopup,\n    confirmedRETHDefiInvest: confirmedRETHDefiInvestFun,\n    confirmedWSETHDefiInvest: confirmedWSETHDefiInvestFun,\n  } = confirmation.useConfirmation()\n  const _confirmedDefiInvest = {\n    isShow: showRETHStakePopup || showWSTETHStakePopup,\n    type: showRETHStakePopup ? 'RETH' : showWSTETHStakePopup ? 'WSETH' : undefined,\n    confirmationNeeded,\n  }\n  const setConfirmedDefiInvest = ({\n    isShow,\n    type,\n  }: {\n    isShow: boolean\n    type?: 'RETH' | 'WSETH' | undefined\n  }) => {\n    if (isShow) {\n      if (type === 'RETH') {\n        setShowRETHStakePopup({ isShow: true, confirmationNeeded: true })\n      } else {\n        setShowWSTETHStakePopup({ isShow: true, confirmationNeeded: true })\n      }\n    } else {\n      setShowRETHStakePopup({ isShow: false, confirmationNeeded: true })\n      setShowWSTETHStakePopup({ isShow: false, confirmationNeeded: true })\n    }\n  }\n\n  const match: any = useRouteMatch('/invest/defi/:market?/:isJoin?')\n  const [serverUpdate, setServerUpdate] = React.useState(false)\n  const { toastOpen, setToastOpen, closeToast } = useToast()\n  const history = useHistory()\n\n  const _market: MarketType = [...(marketArray ? marketArray : [])].find((_item) => {\n    if (match?.params?.market) {\n      //@ts-ignore\n      const [, , base] = _item.match(/(defi-)?(\\w+)(-\\w+)?/i)\n      //@ts-ignore\n      const [_base] = match?.params?.market?.split('-')\n      return base.toUpperCase() == _base.toUpperCase()\n    }\n  }) as MarketType\n  const isJoin = match?.params?.isJoin?.toUpperCase() !== 'Redeem'.toUpperCase()\n  const theme = useTheme()\n  const { isMobile } = useSettings()\n  const isMainView = !(match?.params?.market && _market)\n  const height = isMainView ? (isMobile ? 34 * theme.unit : 30 * theme.unit) : 6 * theme.unit\n\n  return (\n    <Box display={'flex'} flexDirection={'column'} flex={1}>\n      <MaxWidthContainer\n        display={'flex'}\n        justifyContent={'space-between'}\n        background={containerColors[0]}\n        height={height}\n        alignItems={'center'}\n        containerProps={{\n          borderBottom: isMainView ? '' : `1px solid ${hexToRGB(theme.colorBase.border, 0.5)}`,\n        }}\n      >\n        {isMainView ? (\n          <Box\n            display={'flex'}\n            justifyContent={'space-between'}\n            alignItems={'center'}\n            width={'100%'}\n          >\n            <Box>\n              <Typography marginBottom={2} fontSize={'38px'} variant={'h1'}>\n                {t('labelInvestDefiTitle')}\n              </Typography>\n              <Box display={'flex'} alignItems={'center'}>\n                <Button\n                  onClick={() => history.push('/invest/balance')}\n                  sx={{ width: isMobile ? 36 * theme.unit : 18 * theme.unit }}\n                  variant={'contained'}\n                >\n                  {t('labelInvestMyAmm')}\n                </Button>\n              </Box>\n            </Box>\n            {!isMobile && <SatkingLogo />}\n          </Box>\n        ) : (\n          <Box\n            width={'100%'}\n            display={'flex'}\n            alignItems={'center'}\n            justifyContent={'space-between'}\n          >\n            <Button\n              startIcon={<BackIcon htmlColor={'var(--color-text-primary)'} fontSize={'small'} />}\n              variant={'text'}\n              size={'medium'}\n              sx={{ color: 'var(--color-text-primary)' }}\n              color={'inherit'}\n              onClick={() => history.push(`/invest/defi`)}\n            >\n              {t('labelInvestDefiTitle')}\n            </Button>\n          </Box>\n        )}\n      </MaxWidthContainer>\n\n      <MaxWidthContainer\n        height={isMainView ? 'calc(100vh - 360px)' : 'calc(100vh - 180px)'}\n        background={isMainView ? containerColors[1] : 'transparent'}\n      >\n        <StyleWrapper\n          display={'flex'}\n          flexDirection={'column'}\n          justifyContent={'center'}\n          alignItems={'center'}\n          flex={1}\n          paddingTop={4}\n          paddingBottom={4}\n        >\n          {marketArray?.length ? (\n            match?.params?.market && _market ? (\n              <DeFiTradePanel\n                market={_market}\n                isJoin={isJoin}\n                setServerUpdate={setServerUpdate}\n                setToastOpen={setToastOpen}\n              />\n            ) : (\n              <LandDefiInvest setConfirmedDefiInvest={setConfirmedDefiInvest} />\n            )\n          ) : (\n            <LoadingBlock />\n          )}\n          <Toast\n            alertText={toastOpen?.content ?? ''}\n            severity={toastOpen?.type ?? ToastType.success}\n            open={toastOpen?.open ?? false}\n            autoHideDuration={TOAST_TIME}\n            onClose={closeToast}\n          />\n\n          <ConfirmInvestDefiServiceUpdate\n            open={serverUpdate}\n            handleClose={() => setServerUpdate(false)}\n          />\n          <ConfirmInvestDefiRisk\n            open={_confirmedDefiInvest.isShow}\n            type={_confirmedDefiInvest.type as any}\n            confirmationNeeded={confirmationNeeded}\n            handleClose={(_e, isAgree) => {\n              if (!isAgree) {\n                setConfirmedDefiInvest({ isShow: false })\n              } else {\n                if (_confirmedDefiInvest.type === 'RETH') {\n                  confirmedRETHDefiInvestFun()\n                  history.push(defiRETHAdvice.router)\n                }\n                if (_confirmedDefiInvest.type === 'WSETH') {\n                  confirmedWSETHDefiInvestFun()\n                  history.push(defiWSTETHAdvice.router)\n                }\n              }\n              setConfirmedDefiInvest({ isShow: false })\n            }}\n          />\n        </StyleWrapper>\n      </MaxWidthContainer>\n    </Box>\n  )\n})\n"
  },
  {
    "path": "packages/web-earn/src/pages/InvestPage/DualPanel/BeginnerMode.tsx",
    "content": "import styled from '@emotion/styled'\nimport { Avatar, Box, CardContent, Typography } from '@mui/material'\nimport { Trans, WithTranslation, withTranslation } from 'react-i18next'\nimport {\n  CoinIcon,\n  CoinIcons,\n  DualTable,\n  useOpenModals,\n  useSettings,\n  TickCardStyleItem,\n} from '@loopring-web/component-lib'\nimport { useDualMap, useSystem, useTokenMap } from '@loopring-web/core'\nimport {\n  DualGain,\n  DualDip,\n  DualBegin,\n  DualViewType,\n  getValuePrecisionThousand,\n  SoursURL,\n  TokenType,\n} from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { DUAL_TYPE } from '@loopring-web/loopring-sdk'\nimport { useTheme } from '@emotion/react'\nimport React, { useEffect } from 'react'\nimport { useHistory, useLocation } from 'react-router'\n\nconst WrapperStyled = styled(Box)`\n  flex: 1;\n  display: flex;\n  flex-direction: column;\n  background: var(--color-box);\n  border-radius: ${({ theme }) => theme.unit}px;\n`\nexport const ViewStepType = {\n  [DualViewType.DualGain]: DualGain,\n  [DualViewType.DualDip]: DualDip,\n  [DualViewType.DualBegin]: DualBegin,\n}\n\nexport const BeginnerMode: any = withTranslation('common')(\n  ({\n    t,\n    dualListProps,\n    viewType,\n  }: // setConfirmDualInvest,\n  WithTranslation & {\n    dualListProps: any\n    viewType: DualViewType\n    // setConfirmDualInvest: (state: any) => void\n  }) => {\n    // const viewType ===\n    const viewStepType = ViewStepType[viewType]\n\n    const theme = useTheme()\n    const { tradeMap, status } = useDualMap()\n    const { coinJson } = useSettings()\n    const { forexMap } = useSystem()\n    const { tokenMap } = useTokenMap()\n    const { setShowDual } = useOpenModals()\n    const {\n      pairASymbol,\n      pairBSymbol,\n      isLoading,\n      dualProducts,\n      currentPrice,\n      market,\n      baseTokenList,\n      step1SelectedToken,\n      step2BuyOrSell,\n      step3Token,\n      onSelectStep1Token,\n      onSelectStep2BuyOrSell,\n      onSelectStep3Token,\n      isDualBalanceSufficient,\n    } = dualListProps\n    const { isMobile } = useSettings()\n    const tokenList: any[] = Object.values(baseTokenList ?? {})?.sort((a: any, b: any) =>\n      a?.tokenName?.toString().localeCompare(b?.tokenName?.toString()),\n    )\n    const dualType =\n      step2BuyOrSell === 'Sell' ? sdk.DUAL_TYPE.DUAL_BASE : sdk.DUAL_TYPE.DUAL_CURRENCY\n    const step3Ref = React.useRef(null)\n    const tableRef = React.useRef(null)\n    const scroolStep3ToMiddle = () => {\n      setTimeout(() => {\n        const element = step3Ref.current as any\n        const elementRect = element.getBoundingClientRect()\n        const absoluteElementTop = elementRect.top + window.pageYOffset\n        const middle = absoluteElementTop - window.innerHeight / 2\n        window.scrollTo(0, middle)\n      }, 100)\n    }\n    const scroolTableToMiddle = () => {\n      setTimeout(() => {\n        const element = tableRef.current as any\n        const elementRect = element.getBoundingClientRect()\n        const absoluteElementTop = elementRect.top + window.pageYOffset\n        const middle = absoluteElementTop - window.innerHeight / 2\n        window.scrollTo(0, middle)\n      }, 100)\n    }\n    const { search } = useLocation()\n    const history = useHistory()\n    const autoChose = new URLSearchParams(search).get('autoChose')\n    useEffect(() => {\n      if (tokenList && status !== 'PENDING' && autoChose) {\n        onSelectStep1Token(autoChose)\n        const _search = new URLSearchParams(search)\n        _search.delete('autoChose')\n        \n        history.replace({\n          search: _search.toString()\n        })\n      }\n    }, [status, tokenList])\n\n    return (\n      <Box display={'flex'} flexDirection={'column'} flex={1} marginBottom={2}>\n        <Box marginBottom={5}>\n          <Typography marginBottom={2} display={'flex'} variant={'h4'}>\n            {t(viewStepType[0].labelKey)}\n          </Typography>\n          <Box display={'flex'} flexDirection={'row'}>\n            {tokenList?.map(({ tokenName, minAPY, maxAPY }: any) => {\n              const selected = step1SelectedToken === tokenName\n              return (\n                <Box marginRight={2} key={tokenName?.toString()}>\n                  <TickCardStyleItem\n                    className={\n                      selected ? 'btnCard dualInvestCard selected' : 'btnCard dualInvestCard '\n                    }\n                    selected={selected}\n                    onClick={() => onSelectStep1Token(tokenName?.toString())}\n                    width={'280px'}\n                  >\n                    <CardContent\n                    // sx={{\n                    //   alignItems: 'center',\n                    //   // paddingX: 3,\n                    //   // paddingY: 2,\n                    //   '&:last-child': { paddingY: 2 },\n                    // }}\n                    >\n                      <Typography component={'span'} display={'inline-flex'}>\n                        <CoinIcon\n                          size={32}\n                          symbol={typeof tokenName === 'string' ? tokenName : ''}\n                        />\n                      </Typography>\n                      <Typography paddingLeft={1}>\n                        <Typography\n                          color={\n                            selected ? theme.colorBase.textPrimary : theme.colorBase.textPrimary\n                          }\n                          variant={'subtitle1'}\n                        >\n                          {tokenName?.toString()}\n                        </Typography>\n                        <Typography variant={'body2'} color={theme.colorBase.textSecondary}>\n                          {t('labelDualBeginnerAPR', {\n                            APR:\n                              !minAPY && !maxAPY\n                                ? '--'\n                                : minAPY === maxAPY || !minAPY || !maxAPY\n                                ? `${getValuePrecisionThousand(\n                                    Number(minAPY) * 100,\n                                    2,\n                                    2,\n                                    2,\n                                    true,\n                                  )}%`\n                                : `${getValuePrecisionThousand(\n                                    Number(minAPY) * 100,\n                                    2,\n                                    2,\n                                    2,\n                                    true,\n                                  )}% - ${getValuePrecisionThousand(\n                                    Number(maxAPY) * 100,\n                                    2,\n                                    2,\n                                    2,\n                                    true,\n                                  )}%`,\n                          })}\n                        </Typography>\n                      </Typography>\n                    </CardContent>\n                  </TickCardStyleItem>\n                </Box>\n              )\n            })}\n          </Box>\n        </Box>\n\n        {step1SelectedToken !== undefined && viewType === DualViewType.DualBegin && (\n          <Box marginBottom={5}>\n            <Typography marginBottom={2} display={'flex'} variant={'h4'}>\n              {t('labelDualBeginnerStep2Title')}\n            </Typography>\n            <Box display={'flex'} flexDirection={'row'}>\n              <Box marginRight={2}>\n                <TickCardStyleItem\n                  className={\n                    step2BuyOrSell === 'Sell'\n                      ? 'btnCard dualInvestCard selected'\n                      : 'btnCard dualInvestCard '\n                  }\n                  selected={step2BuyOrSell === 'Sell'}\n                  onClick={() => {\n                    onSelectStep2BuyOrSell('Sell')\n                    scroolStep3ToMiddle()\n                  }}\n                  width={'310px'}\n                >\n                  <CardContent\n                  // sx={{\n                  //   alignItems: 'center',\n                  //   // paddingX: 3,\n                  //   // paddingY: 2,\n                  //   // '&:last-child': { paddingY: 2 },\n                  // }}\n                  >\n                    <Typography component={'span'} display={'inline-flex'}>\n                      <Avatar alt={'sell-high'} src={SoursURL + '/svg/sell-high.svg'} />\n                    </Typography>\n                    <Typography paddingLeft={1}>\n                      <Typography color={theme.colorBase.textPrimary} variant={'subtitle1'}>\n                        {t('labelDualBeginnerSellHigh', {\n                          token: step1SelectedToken,\n                        })}\n                      </Typography>\n                      <Typography variant={'body2'} color={theme.colorBase.textSecondary}>\n                        {t('labelDualBeginnerReceiveStable')}\n                      </Typography>\n                    </Typography>\n                  </CardContent>\n                </TickCardStyleItem>\n              </Box>\n              <Box marginLeft={2}>\n                <TickCardStyleItem\n                  className={\n                    step2BuyOrSell === 'Buy'\n                      ? 'btnCard dualInvestCard selected'\n                      : 'btnCard dualInvestCard '\n                  }\n                  selected={step2BuyOrSell === 'Buy'}\n                  onClick={() => {\n                    onSelectStep2BuyOrSell('Buy')\n                    scroolStep3ToMiddle()\n                  }}\n                  width={'310px'}\n                >\n                  <CardContent\n                  // sx={{\n                  //   alignItems: 'center',\n                  //   // paddingX: 3,\n                  //   // paddingY: 2,\n                  //   // '&:last-child': { paddingY: 2 },\n                  // }}\n                  >\n                    <Typography component={'span'} display={'inline-flex'}>\n                      <Avatar alt={'buy-low'} src={SoursURL + '/svg/buy-low.svg'} />\n                    </Typography>\n                    <Typography paddingLeft={1}>\n                      <Typography color={theme.colorBase.textPrimary} variant={'subtitle1'}>\n                        {t('labelDualBeginnerBuyLow', {\n                          token: step1SelectedToken,\n                        })}\n                      </Typography>\n                      <Typography variant={'body2'} color={theme.colorBase.textSecondary}>\n                        {t('labelDualBeginnerInvestStable')}\n                      </Typography>\n                    </Typography>\n                  </CardContent>\n                </TickCardStyleItem>\n              </Box>\n            </Box>\n          </Box>\n        )}\n\n        {step1SelectedToken !== undefined && step2BuyOrSell !== undefined && tokenList && tokenList.length > 0 && (\n          <Box ref={step3Ref} marginBottom={2}>\n            <Typography marginBottom={2} display={'flex'} variant={'h4'}>\n              {t(viewStepType[2].labelKey)}\n            </Typography>\n            <Box display={'flex'} flexDirection={'row'}>\n              {tradeMap[step1SelectedToken ?? '']?.quoteList?.map((token) => {\n                return (\n                  <Box marginRight={2} key={token}>\n                    <TickCardStyleItem\n                      className={\n                        step3Token === token\n                          ? 'btnCard dualInvestCard selected'\n                          : 'btnCard dualInvestCard '\n                      }\n                      selected={step3Token === token}\n                      onClick={() => {\n                        if (isLoading) return\n                        onSelectStep3Token(token)\n                        scroolTableToMiddle()\n                      }}\n                      width={'280px'}\n                    >\n                      <CardContent\n                        sx={{\n                          alignItems: 'center',\n                          paddingX: 3,\n                          paddingY: 2,\n                          '&:last-child': { paddingY: 2 },\n                        }}\n                      >\n                        <Typography component={'span'} display={'inline-flex'}>\n                          <CoinIcon size={32} symbol={token} />\n                        </Typography>\n                        <Typography\n                          color={theme.colorBase.textPrimary}\n                          variant={'subtitle1'}\n                          paddingLeft={1}\n                        >\n                          {step2BuyOrSell === 'Buy'\n                            ? t('labelDualBeginnerBuyLowWith', { token: token })\n                            : t('labelDualBeginnerSellHighFor', {\n                                token: token,\n                              })}\n                        </Typography>\n                      </CardContent>\n                    </TickCardStyleItem>\n                  </Box>\n                )\n              })}\n            </Box>\n          </Box>\n        )}\n        {step3Token !== undefined && step1SelectedToken !== undefined && (\n          <WrapperStyled ref={tableRef} marginTop={1} flex={1} flexDirection={'column'}>\n            {pairASymbol && pairBSymbol && market && (\n              <Box\n                display={'flex'}\n                flexDirection={'row'}\n                paddingTop={3}\n                paddingX={3}\n                justifyContent={'space-between'}\n                alignItems={'center'}\n              >\n                <Box component={'h3'} display={'flex'} flexDirection={'row'} alignItems={'center'}>\n                  <Typography component={'span'} display={'inline-flex'}>\n                    {/* eslint-disable-next-line react/jsx-no-undef */}\n                    <CoinIcons\n                      type={TokenType.dual}\n                      size={32}\n                      tokenIcon={[coinJson[pairASymbol], coinJson[pairBSymbol]]}\n                    />\n                  </Typography>\n                  <Typography component={'span'} flexDirection={'column'} display={'flex'}>\n                    <Typography component={'span'} display={'inline-flex'} color={'textPrimary'}>\n                      {t(\n                        dualType === DUAL_TYPE.DUAL_BASE\n                          ? 'labelDualInvestBaseTitle'\n                          : 'labelDualInvestQuoteTitle',\n                        {\n                          symbolA: pairASymbol,\n                          symbolB: pairBSymbol,\n                        },\n                      )}\n                    </Typography>\n                    {isDualBalanceSufficient === undefined ? (\n                      <Typography\n                        component={'span'}\n                        display={'inline-flex'}\n                        color={'textSecondary'}\n                        variant={'body2'}\n                      >\n                        &nbsp;\n                      </Typography>\n                    ) : isDualBalanceSufficient === true ? (\n                      <Typography\n                        component={'span'}\n                        display={'inline-flex'}\n                        color={'textSecondary'}\n                        variant={'body2'}\n                      >\n                        {t('labelDualInvestDes', {\n                          symbolA: pairASymbol,\n                          symbolB: pairBSymbol,\n                        })}\n                      </Typography>\n                    ) : (\n                      <Typography\n                        component={'span'}\n                        display={'inline-flex'}\n                        color={'var(--color-warning)'}\n                        variant={'body2'}\n                      >\n                        {t('labelDualInvestDesInsufficient')}\n                      </Typography>\n                    )}\n                  </Typography>\n                </Box>\n                <Typography\n                  component={'span'}\n                  display={isMobile ? 'flex' : 'inline-flex'}\n                  color={'textSecondary'}\n                  variant={'body2'}\n                  flexDirection={isMobile ? 'column' : 'row'}\n                  alignItems={'center'}\n                  whiteSpace={'pre-wrap'}\n                >\n                  {currentPrice &&\n                    (!isMobile ? (\n                      <Trans\n                        i18nKey={'labelDualCurrentPrice'}\n                        tOptions={{\n                          price:\n                            // PriceTag[CurrencyToTag[currency]] +\n                            getValuePrecisionThousand(\n                              currentPrice.currentPrice,\n                              currentPrice.precisionForPrice\n                                ? currentPrice.precisionForPrice\n                                : tokenMap[currentPrice.quote].precisionForOrder,\n                              currentPrice.precisionForPrice\n                                ? currentPrice.precisionForPrice\n                                : tokenMap[currentPrice.quote].precisionForOrder,\n                              currentPrice.precisionForPrice\n                                ? currentPrice.precisionForPrice\n                                : tokenMap[currentPrice.quote].precisionForOrder,\n                              true,\n                              { floor: true },\n                            ),\n                          symbol: currentPrice.base,\n                          baseSymbol: /USD/gi.test(currentPrice.quote ?? '')\n                            ? 'USDT'\n                            : currentPrice.quote,\n                        }}\n                      >\n                        LRC Current price:\n                        <Typography\n                          component={'span'}\n                          display={'inline-flex'}\n                          color={'textPrimary'}\n                          paddingLeft={1}\n                        >\n                          price\n                        </Typography>\n                        :\n                      </Trans>\n                    ) : (\n                      <>\n                        <Typography\n                          component={'span'}\n                          color={'textSecondary'}\n                          variant={'body2'}\n                          textAlign={'right'}\n                        >\n                          {t('labelDualMobilePrice', {\n                            symbol: currentPrice.base,\n                          })}\n                        </Typography>\n                        <Typography\n                          textAlign={'right'}\n                          component={'span'}\n                          display={'inline-flex'}\n                          color={'textPrimary'}\n                          paddingLeft={1}\n                        >\n                          {getValuePrecisionThousand(\n                            currentPrice.currentPrice,\n                            currentPrice.precisionForPrice\n                              ? currentPrice.precisionForPrice\n                              : tokenMap[currentPrice.quote].precisionForOrder,\n                            currentPrice.precisionForPrice\n                              ? currentPrice.precisionForPrice\n                              : tokenMap[currentPrice.quote].precisionForOrder,\n                            currentPrice.precisionForPrice\n                              ? currentPrice.precisionForPrice\n                              : tokenMap[currentPrice.quote].precisionForOrder,\n                            true,\n                            { floor: true },\n                          )}\n                        </Typography>\n                      </>\n                    ))}\n                </Typography>\n              </Box>\n            )}\n            <Box flex={1}>\n              <DualTable\n                rawData={dualProducts ?? []}\n                showloading={isLoading}\n                forexMap={forexMap as any}\n                onItemClick={(item) => {\n                  setShowDual({\n                    isShow: true,\n                    dualInfo: {\n                      ...item,\n                      sellSymbol: pairASymbol!,\n                      buySymbol: pairBSymbol!,\n                    },\n                  })\n                }}\n              />\n            </Box>\n          </WrapperStyled>\n        )}\n      </Box>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/web-earn/src/pages/InvestPage/DualPanel/ChooseDualType.tsx",
    "content": "import { Box, Grid, Typography } from '@mui/material'\nimport {\n  DualDownIcon,\n  DualConvertIcon,\n  DualUpIcon,\n  DualViewType,\n  LOOPRING_DOCUMENT,\n  DualInvestmentLogo,\n  SoursURL,\n} from '@loopring-web/common-resources'\nimport { Button, CoinIcon, MenuBtnStyled, useSettings } from '@loopring-web/component-lib'\nimport React from 'react'\nimport { useTranslation } from 'react-i18next'\nimport styled from '@emotion/styled'\nimport { containerColors, MaxWidthContainer } from '../index'\nimport { useHistory } from 'react-router-dom'\nimport { useTheme } from '@emotion/react'\nimport { groupBy, keys } from 'lodash'\n\nconst EarnCard = styled(Box)<{ isMobile: boolean }>`\n  background-color: var(--color-box-third);\n  padding: ${({ theme }) => theme.unit * 6}px ${({ theme }) => theme.unit * 4}px\n    ${({ theme }) => theme.unit * 4}px ${({ theme }) => theme.unit * 4}px;\n  width: ${({ isMobile }) => (isMobile ? '100%' : '32%')};\n  margin-bottom: ${({ theme }) => theme.unit * 2}px;\n  border-radius: ${({ theme }) => theme.unit * 1.5}px;\n  border: 0.5px solid var(--color-border);\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  position: relative;\n  overflow: hidden;\n  :hover {\n    border: 1px solid var(--color-primary);\n  }\n`\n\nexport const ChooseDualTypeContent = [\n  {\n    icon: (\n      <DualUpIcon\n        style={{\n          width: 156,\n          height: 156,\n        }}\n      />\n    ),\n    type: DualViewType.DualGain,\n    titleKey: 'labelCoverGain',\n    desKey: 'labelCoverGainDes',\n  },\n  {\n    icon: (\n      <DualDownIcon\n        style={{\n          width: 156,\n          height: 156,\n        }}\n      />\n    ),\n    type: DualViewType.DualDip,\n    titleKey: 'labelDip',\n    desKey: 'labelDipDes',\n  },\n\n  {\n    icon: (\n      <DualConvertIcon\n        style={{\n          width: 156,\n          height: 156,\n        }}\n      />\n    ),\n    type: DualViewType.All,\n    titleKey: 'labelDualMerge',\n    desKey: 'labelDualMergeDes',\n  },\n]\nexport const TypographyStyle = styled(Typography)`\n  svg {\n    fill: ${({ theme }) => theme.colorBase.textSecondary};\n  }\n` as typeof Typography\nexport const ChooseDualType = ({ \n  onSelect,\n  dualTokenList,\n  productsRef\n}: { \n  onSelect: (props: DualViewType) => void,\n  dualTokenList: {\n    symbol: string;\n    apy: string;\n    price: string;\n    tag: \"sellCover\" | \"buyDip\";\n    apyRaw: number;\n  }[]\n  productsRef: React.MutableRefObject<HTMLDivElement | undefined>\n}) => {\n  const { isMobile } = useSettings()\n  const theme = useTheme()\n  const history = useHistory()\n  const { t } = useTranslation()\n  const tEarn = useTranslation('webEarn').t\n\n  const widths = ['25%', '25%','25%','25%']\n  const group = groupBy(dualTokenList, token => token.symbol)\n  const tableData = dualTokenList.length > 0 ? keys(group).map(symbol => {\n    const list = group[symbol]\n    return {\n      token: symbol,\n      list: list.map(type => {\n        return {\n          apy: type.apy,\n          type: type.tag === 'buyDip' ? 'Buy Low' : 'Sell High',\n          viewDetail: () => {\n            history.push(\n              `/invest/dual?viewType=${\n                type.tag === 'buyDip' ? 'DualDip' : 'DualGain'\n              }&autoChose=${type.symbol}`,\n            )\n          },\n        }\n      })\n    }\n  }) : undefined\n  return (\n    <>\n      <MaxWidthContainer\n        display={'flex'}\n        justifyContent={'space-between'}\n        background={containerColors[0]}\n        height={isMobile ? 60 * theme.unit : 30 * theme.unit}\n        alignItems={'center'}\n      >\n        <Box paddingY={7}>\n          <Typography marginBottom={2} fontSize={'38px'} variant={'h1'}>\n            {t('labelInvestDualTitle')}\n          </Typography>\n          <Box display={'flex'} alignItems={'center'}>\n            <Button\n              onClick={() => history.push('/l2assets/assets/Invests')}\n              sx={{ width: isMobile ? 36 * theme.unit : 18 * theme.unit }}\n              variant={'contained'}\n            >\n              {t('labelInvestMyDual')}\n            </Button>\n\n            <Button\n              onClick={() => {\n                window.open(`${LOOPRING_DOCUMENT}dual_investment_tutorial_en.md`, '_blank')\n                window.opener = null\n              }}\n              sx={{ marginLeft: 1.5, height: 40 }}\n              variant={'outlined'}\n              color={'inherit'}\n            >\n              {t('labelInvestDualTutorial')}\n            </Button>\n          </Box>\n        </Box>\n        {!isMobile && <DualInvestmentLogo />}\n      </MaxWidthContainer>\n      <MaxWidthContainer background={containerColors[1]} minHeight={'70vh'} paddingY={3}>\n        <Grid\n          container\n          flex={1}\n          display={'flex'}\n          spacing={2}\n          flexDirection={isMobile ? 'column' : 'row'}\n        >\n          {ChooseDualTypeContent.map((item) => {\n            return (\n              <Grid item xs={6} md={4} key={item.type} display={'flex'} justifyContent={'center'}>\n                <MenuBtnStyled\n                  variant={'outlined'}\n                  sx={{\n                    width: 'var(--dual-type-width)',\n                    height: '320px',\n                    flexDirection: 'column',\n                    justifyContent: 'space-around',\n                  }}\n                  onClick={() => onSelect(item.type)}\n                >\n                  <Box display={'flex'} flexDirection={'column'} alignItems={'left'} marginTop={3}>\n                    <Typography\n                      variant={'h5'}\n                      component={'span'}\n                      display={'inline-flex'}\n                      color={'textPrimary'}\n                      textAlign={'left'}\n                      sx={{ textIndent: 0 }}\n                    >\n                      {t(item.titleKey)}\n                    </Typography>\n                    <Typography\n                      sx={{ textIndent: 0 }}\n                      variant={'body1'}\n                      component={'span'}\n                      display={'inline-flex'}\n                      color={'textSecondary'}\n                      textAlign={'left'}\n                    >\n                      {t(item.desKey)}\n                    </Typography>\n                  </Box>\n                  <TypographyStyle component={'span'} display={'inline-flex'}>\n                    {item.icon}\n                  </TypographyStyle>\n                  <Button\n                    sx={{ marginBottom: 3 }}\n                    variant={'contained'}\n                    fullWidth\n                    color={'primary'}\n                    size={'medium'}\n                  >\n                    {t('labelDualInvestGuid')}\n                  </Button>\n                </MenuBtnStyled>\n              </Grid>\n            )\n          })}\n        </Grid>\n\n        <Box ref={productsRef} component={'div'} id={'products'} marginTop={8}>\n          {tableData ? (\n            <>\n              <Typography marginBottom={5} variant='h2'>{t(\"labelTitleOverviewAllPrd\")}</Typography>\n              <Box paddingX={1.5} paddingY={1.5} display={'flex'}>\n                <Typography\n                  fontSize={'14px'}\n                  color={'var(--color-text-secondary)'}\n                  width={widths[0]}\n                >\n                  {t(\"labelToken\")}\n                </Typography>\n                <Typography\n                  fontSize={'14px'}\n                  color={'var(--color-text-secondary)'}\n                  width={widths[1]}\n                >\n                  {t(\"labelAPY\")}\n                </Typography>\n                <Typography\n                  fontSize={'14px'}\n                  color={'var(--color-text-secondary)'}\n                  width={widths[2]}\n                >\n                  {t(\"labelType\")}\n                </Typography>\n                <Typography\n                  fontSize={'14px'}\n                  color={'var(--color-text-secondary)'}\n                  width={widths[3]}\n                  textAlign={'right'}\n                >\n                  {t(\"labelAction2\")}\n                </Typography>\n              </Box>\n\n              <Box>\n                {tableData.map((ele) => {\n                  return (\n                    <Box key={ele.token} marginBottom={2.5}>\n                      <Box\n                        component={'hr'}\n                        sx={{\n                          background: 'var(--color-border)',\n                          border: 'none',\n                          height: '1px',\n                        }}\n                      />\n                      {ele.list.map((type, index) => {\n                        return (\n                          <Box\n                            paddingX={1.5}\n                            key={type.type}\n                            paddingY={3.5}\n                            display={'flex'}\n                            alignItems={'center'}\n                          >\n                            <Box width={widths[0]} display={'flex'} alignItems={'center'}>\n                              {index === 0 && (\n                                <>\n                                  <CoinIcon symbol={ele.token} />\n                                  <Typography marginLeft={1.5}>{ele.token}</Typography>\n                                </>\n                              )}\n                            </Box>\n                            <Box width={widths[1]} display={'flex'} alignItems={'center'}>\n                              <Typography>{type.apy}</Typography>\n                            </Box>\n                            <Box width={widths[2]} display={'flex'} alignItems={'center'}>\n                              <Typography>{type.type}</Typography>\n                            </Box>\n                            <Box width={widths[3]} display={'flex'} flexDirection={'row-reverse'}>\n                              <Button\n                                sx={{\n                                  color: 'var(--color-primary)',\n                                  borderColor: 'var(--color-primary)',\n                                  ':hover': {\n                                    color: 'var(--color-primary)',\n                                    borderColor: 'var(--color-primary)',\n                                  },\n                                }}\n                                variant={'outlined'}\n                                onClick={type.viewDetail}\n                              >\n                                {t(\"labelMiningViewDetails\")}\n                              </Button>\n                            </Box>\n                          </Box>\n                        )\n                      })}\n                    </Box>\n                  )\n                })}\n              </Box>\n            </>\n          ) : (\n            <Box\n              display={'flex'}\n              justifyContent={'center'}\n              alignItems={'center'}\n              height={'150px'}\n              width={'100%'}\n            >\n              <img width={60} src={SoursURL + 'images/loading-line.gif'} />\n            </Box>\n          )}\n        </Box>\n      </MaxWidthContainer>\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/web-earn/src/pages/InvestPage/DualPanel/DualListPanel.tsx",
    "content": "import React, { useEffect } from 'react'\nimport styled from '@emotion/styled'\nimport {\n  Box,\n  CardContent,\n  Divider,\n  FormControlLabel,\n  Grid,\n  Switch,\n  Tabs,\n  Tooltip,\n  Typography,\n} from '@mui/material'\nimport { Trans, WithTranslation, withTranslation } from 'react-i18next'\nimport { useDualHook } from './hook'\nimport {\n  Button,\n  CardStyleItem,\n  CoinIcon,\n  DualTable,\n  EmptyDefault,\n  useOpenModals,\n  useSettings,\n} from '@loopring-web/component-lib'\nimport {\n  ModalDualPanel,\n  useDualMap,\n  useDualTrade,\n  useSystem,\n  useTokenMap,\n  useTokenPrices,\n} from '@loopring-web/core'\nimport { useHistory, useLocation } from 'react-router-dom'\nimport {\n  BackIcon,\n  DualViewType,\n  getValuePrecisionThousand,\n  Info2Icon,\n  LOOPRING_DOCUMENT,\n  SagaStatus,\n  SoursURL,\n} from '@loopring-web/common-resources'\nimport { BeginnerMode } from './BeginnerMode'\nimport { containerColors, MaxWidthContainer } from '..'\nimport { ChooseDualType } from './ChooseDualType'\nimport { max } from 'lodash'\nimport { toBig } from '@loopring-web/loopring-sdk'\nconst StyleDual = styled(Box)`\n  position: relative;\n` as typeof Box\nconst WrapperStyled = styled(Box)`\n  flex: 1;\n  display: flex;\n  flex-direction: column;\n  border-radius: ${({ theme }) => theme.unit}px;\n`\n\nconst MainTabCardStyleItem = styled(CardStyleItem)`\n  &&,\n  &&.selected,\n  &&:hover {\n    border-radius: ${({ theme }) => theme.unit}px;\n    padding-left: ${({ theme }) => 3 * theme.unit}px;\n    padding-right: ${({ theme }) => 3 * theme.unit}px;\n    background: transparent;\n  }\n`\n\nconst SubTabCardStyleItem = styled(CardStyleItem)`\n  &&,\n  &&.selected,\n  &&:hover {\n    padding: ${({ theme }) => theme.unit}px ${({ theme }) => 2.5 * theme.unit}px;\n    width: auto;\n    border-radius: ${({ theme }) => theme.unit}px;\n  }\n`\n\nexport const DualListPanel: any = withTranslation('common')(({ t }: WithTranslation) => {\n  const { search, pathname } = useLocation()\n  const searchParams = new URLSearchParams(search)\n  const viewType = new URLSearchParams(search).get('viewType')\n  const autoChose = new URLSearchParams(search).get('autoChose')\n  const { forexMap } = useSystem()\n  const history = useHistory()\n  const { isMobile } = useSettings()\n  const { tradeMap, marketArray, status, getDualMap, marketMap } = useDualMap()\n  const { tokenMap } = useTokenMap()\n  const { setShowDual } = useOpenModals()\n  const [confirmDualAutoInvest, setConfirmDualAutoInvest] = React.useState(false)\n  const dualListProps = useDualHook()\n  const { dualTradeProps, dualToastOpen, closeDualToast } = useDualTrade()\n  const {\n    pairASymbol,\n    pairBSymbol,\n    isLoading,\n    dualProducts,\n    currentPrice,\n    market,\n    handleOnPairChange,\n    onSelectStep1Token,\n    baseTokenList\n  } = dualListProps\n  const marketsIsLoading = status === 'PENDING'\n  \n  const tokenList: any[] = Object.values(baseTokenList ?? {})\n  const { tokenPrices } = useTokenPrices()\n  const sellCoverTokens: {\n    symbol: string\n    apy: string\n    price: string\n    tag: 'sellCover' | 'buyDip'\n    apyRaw: number\n  }[] = (tokenList ?? [])?.map((token) => {\n    const keys = Object.keys(marketMap).filter((key) => key.includes(token.tokenName))\n    const maxApy = max(keys.map((key) => (marketMap[key] as any).baseTokenApy?.max as number))\n    return {\n      symbol: token.tokenName,\n      apy:\n        toBig(maxApy ?? 0)\n          .times('100')\n          .toString() + '%',\n      price: '$' + getValuePrecisionThousand(tokenPrices[token.tokenName], 2, 2),\n      tag: 'sellCover',\n      apyRaw: maxApy ?? 0,\n    }\n  })\n  const buyDipTokens: {\n    symbol: string\n    apy: string\n    price: string\n    tag: 'sellCover' | 'buyDip'\n    apyRaw: number\n  }[] =\n    tokenList?.map((token) => {\n      const keys = Object.keys(marketMap).filter((key) => key.includes(token.tokenName))\n      const maxApy = max(keys.map((key) => (marketMap[key] as any).quoteTokenApy?.max as number))\n      return {\n        symbol: token.tokenName,\n        apy:\n          toBig(maxApy ?? 0)\n            .times('100')\n            .toString() + '%',\n        price: '$' + getValuePrecisionThousand(tokenPrices[token.tokenName], 2, 2),\n        tag: 'buyDip',\n        apyRaw: maxApy ?? 0,\n      }\n    }) ?? []\n\n  const dualTokenList = [...sellCoverTokens, ...buyDipTokens]\n  const productsRef = React.useRef<HTMLDivElement>()\n  return (\n    <Box display={'flex'} flexDirection={'column'} flex={1} width={'100%'}>\n      {viewType ? (\n        <>\n          <MaxWidthContainer\n            background={containerColors[1]}\n            display={'flex'}\n            justifyContent={'space-between'}\n            paddingY={2}\n          >\n            <Button\n              startIcon={<BackIcon fontSize={'small'} />}\n              variant={'text'}\n              sx={{ color: 'var(--color-text-primary)' }}\n              color={'inherit'}\n              onClick={() => {\n                history.push('/invest/dual')\n              }}\n            >\n              {t('labelBack')}\n            </Button>\n            <Button\n              variant={'text'}\n              sx={{ color: 'var(--color-text-primary)' }}\n              color={'inherit'}\n              endIcon={<BackIcon fontSize={'small'} sx={{ transform: 'rotate(180deg)' }} />}\n              onClick={() => history.push('/l2assets/assets/Invests')}\n            >\n              {t('labelInvestMyDual')}\n            </Button>\n          </MaxWidthContainer>\n          <Divider />\n          <MaxWidthContainer\n            containerProps={{\n              sx: {\n                background: containerColors[1],\n                display: 'flex',\n                flex: 1,\n                flexDirection: 'column',\n                justifyContent: 'flex-start',\n                alignItems: 'center',\n              },\n            }}\n            sx={{\n              flex: 1,\n              display: 'flex',\n              flexDirection: 'column',\n            }}\n          >\n            <Box display={'flex'} justifyContent={'space-between'} alignItems={'center'}>\n              <Box display={'flex'} alignItems={'center'} marginY={3}>\n                <Typography component={'h4'} variant={'h4'}>\n                  {t(`labelDualType${viewType}`)}\n                </Typography>\n                <Button\n                  onClick={() => {\n                    window.open(`${LOOPRING_DOCUMENT}dual_investment_tutorial_en.md`, '_blank')\n                    window.opener = null\n                  }}\n                  size={'small'}\n                  sx={{ marginLeft: 1.5 }}\n                  variant={'outlined'}\n                >\n                  {t('labelInvestDualTutorial')}\n                </Button>\n              </Box>\n              {[DualViewType.All, DualViewType.DualBegin].includes(viewType as any) && (\n                <FormControlLabel\n                  labelPlacement={'start'}\n                  control={\n                    <Switch\n                      checked={viewType === DualViewType.DualBegin}\n                      onChange={(_event, _checked) => {\n                        searchParams.set(\n                          'viewType',\n                          _checked ? DualViewType.DualBegin : DualViewType.All,\n                        )\n                        history.push(pathname + '?' + searchParams.toString())\n                      }}\n                    />\n                  }\n                  label={\n                    <Typography marginLeft={1.5} variant={'h5'}>\n                      {t('labelInvestDualBeginerMode')}\n                    </Typography>\n                  }\n                />\n              )}\n            </Box>\n            <>\n              {viewType !== DualViewType.All ? (\n                <BeginnerMode dualListProps={dualListProps} viewType={viewType} />\n              ) : marketsIsLoading ? (\n                <Box\n                  key={'loading'}\n                  flexDirection={'column'}\n                  display={'flex'}\n                  justifyContent={'center'}\n                  height={'100%'}\n                  alignItems={'center'}\n                  flex={1}\n                >\n                  <img alt={'loading'} width='36' src={`${SoursURL}images/loading-line.gif`} />\n                </Box>\n              ) : !!marketArray?.length ? (\n                <StyleDual flexDirection={'column'} display={'flex'} flex={1}>\n                  <Tabs\n                    value={pairASymbol}\n                    onChange={(_event, value) => handleOnPairChange({ pairA: value.toString() })}\n                    aria-label='l2-history-tabs'\n                    variant='scrollable'\n                    sx={{\n                      display: 'flex',\n                      flexWrap: 'wrap',\n                    }}\n                  >\n                    {tradeMap &&\n                      Reflect.ownKeys(tradeMap)\n                        .sort((a, b) => a.toString().localeCompare(b.toString()))\n                        .map((item, index) => {\n                          return (\n                            <Grid\n                              marginBottom={2}\n                              marginLeft={2}\n                              item\n                              xs={6}\n                              md={3}\n                              lg={2}\n                              key={item.toString() + index.toString()}\n                            >\n                              <MainTabCardStyleItem\n                                className={\n                                  item.toString().toLowerCase() === pairASymbol.toLowerCase()\n                                    ? 'btnCard dualInvestCard selected'\n                                    : 'btnCard dualInvestCard '\n                                }\n                                sx={{ height: '100%' }}\n                                onClick={() => handleOnPairChange({ pairA: item.toString() })}\n                              >\n                                <CardContent sx={{ alignItems: 'center' }}>\n                                  <Typography component={'span'} display={'inline-flex'}>\n                                    <CoinIcon symbol={item.toString()} size={28} />\n                                  </Typography>\n                                  <Typography variant={'h5'} paddingLeft={1}>\n                                    {t('labelDualInvest', {\n                                      symbol: item.toString(),\n                                    })}\n                                  </Typography>\n                                </CardContent>\n                              </MainTabCardStyleItem>\n                            </Grid>\n                          )\n                        })}\n                  </Tabs>\n\n                  <WrapperStyled\n                    display={'flex'}\n                    marginTop={1}\n                    flex={1}\n                    flexDirection={'column'}\n                    className={'dualList'}\n                  >\n                    {pairASymbol && pairBSymbol && market && (\n                      <>\n                        <Box\n                          display={'flex'}\n                          flexDirection={'row'}\n                          paddingTop={1}\n                          paddingX={2}\n                          justifyContent={'space-between'}\n                          alignItems={'center'}\n                        >\n                          <Box display={'flex'} flexWrap={'wrap'}>\n                            {pairASymbol &&\n                              tradeMap[pairASymbol]?.tokenList?.map((item, index) => {\n                                const _index = marketArray.findIndex((_item) =>\n                                  new RegExp(pairASymbol + '-' + item.toString(), 'ig').test(_item),\n                                )\n                                return (\n                                  <SubTabCardStyleItem\n                                    className={\n                                      item.toString().toLowerCase() === pairBSymbol.toLowerCase()\n                                        ? 'btnCard dualInvestCard selected'\n                                        : 'btnCard dualInvestCard '\n                                    }\n                                    sx={{\n                                      marginRight: 2,\n                                      marginBottom: isMobile ? 2 : 0,\n                                    }}\n                                    onClick={() => {\n                                      handleOnPairChange({ pairB: item })\n                                    }}\n                                    key={item.toString() + index.toString()}\n                                  >\n                                    <Typography variant={isMobile ? 'body1' : 'h5'} padding={2}>\n                                      {_index !== -1\n                                        ? t('labelDualBase', {\n                                            symbol: item.toString(),\n                                          })\n                                        : t('labelDualQuote', {\n                                            symbol: item.toString(),\n                                          })}\n                                    </Typography>\n                                  </SubTabCardStyleItem>\n                                )\n                              })}\n                          </Box>\n                          <Typography\n                            component={'span'}\n                            display={isMobile ? 'flex' : 'inline-flex'}\n                            color={'textSecondary'}\n                            variant={'body2'}\n                            flexDirection={isMobile ? 'column' : 'row'}\n                            alignItems={'center'}\n                            whiteSpace={'pre-wrap'}\n                          >\n                            {currentPrice &&\n                              (!isMobile ? (\n                                <>\n                                  <Tooltip\n                                    title={<>{t('labelDualCurrentPriceTip')}</>}\n                                    placement={'top'}\n                                  >\n                                    <Typography\n                                      component={'p'}\n                                      variant='body2'\n                                      color={'textSecondary'}\n                                      display={'inline-flex'}\n                                      alignItems={'center'}\n                                    >\n                                      <Info2Icon\n                                        fontSize={'small'}\n                                        color={'inherit'}\n                                        sx={{ marginX: 1 / 2 }}\n                                      />\n                                    </Typography>\n                                  </Tooltip>\n                                  <Trans\n                                    i18nKey={'labelDualCurrentPrice'}\n                                    tOptions={{\n                                      price:\n                                        // PriceTag[CurrencyToTag[currency]] +\n                                        getValuePrecisionThousand(\n                                          currentPrice.currentPrice,\n                                          currentPrice.precisionForPrice\n                                            ? currentPrice.precisionForPrice\n                                            : tokenMap[currentPrice.quote].precisionForOrder,\n                                          currentPrice.precisionForPrice\n                                            ? currentPrice.precisionForPrice\n                                            : tokenMap[currentPrice.quote].precisionForOrder,\n                                          currentPrice.precisionForPrice\n                                            ? currentPrice.precisionForPrice\n                                            : tokenMap[currentPrice.quote].precisionForOrder,\n                                          true,\n                                          { floor: true },\n                                        ),\n                                      symbol: currentPrice.base,\n                                      baseSymbol: /USD/gi.test(currentPrice.quote ?? '')\n                                        ? 'USDT'\n                                        : currentPrice.quote, //currentPrice.quote,\n                                    }}\n                                  >\n                                    LRC Current price:\n                                    <Typography\n                                      component={'span'}\n                                      display={'inline-flex'}\n                                      color={'textPrimary'}\n                                      paddingLeft={1}\n                                    >\n                                      price\n                                    </Typography>\n                                    :\n                                  </Trans>\n                                </>\n                              ) : (\n                                <>\n                                  <Typography\n                                    component={'span'}\n                                    color={'textSecondary'}\n                                    variant={'body2'}\n                                    textAlign={'right'}\n                                  >\n                                    {t('labelDualMobilePrice', {\n                                      symbol: currentPrice.base,\n                                    })}\n                                  </Typography>\n                                  <Typography\n                                    textAlign={'right'}\n                                    component={'span'}\n                                    display={'inline-flex'}\n                                    color={'textPrimary'}\n                                    paddingLeft={1}\n                                  >\n                                    {getValuePrecisionThousand(\n                                      currentPrice.currentPrice,\n                                      currentPrice.precisionForPrice\n                                        ? currentPrice.precisionForPrice\n                                        : tokenMap[currentPrice.quote].precisionForOrder,\n                                      currentPrice.precisionForPrice\n                                        ? currentPrice.precisionForPrice\n                                        : tokenMap[currentPrice.quote].precisionForOrder,\n                                      currentPrice.precisionForPrice\n                                        ? currentPrice.precisionForPrice\n                                        : tokenMap[currentPrice.quote].precisionForOrder,\n                                      true,\n                                      { floor: true },\n                                    )}\n                                  </Typography>\n                                </>\n                              ))}\n                          </Typography>\n                        </Box>\n                        <Box flex={1} display={'flex'}>\n                          <DualTable\n                            rawData={dualProducts ?? []}\n                            showloading={isLoading}\n                            forexMap={forexMap as any}\n                            onItemClick={(item) => {\n                              setShowDual({\n                                isShow: true,\n                                dualInfo: {\n                                  ...item,\n                                  sellSymbol: pairASymbol,\n                                  buySymbol: pairBSymbol,\n                                },\n                              })\n                            }}\n                          />\n                        </Box>\n                      </>\n                    )}\n                  </WrapperStyled>\n                </StyleDual>\n              ) : (\n                <Box\n                  key={'empty'}\n                  flexDirection={'column'}\n                  display={'flex'}\n                  justifyContent={'center'}\n                  height={'100%'}\n                  flex={1}\n                  alignItems={'center'}\n                >\n                  <EmptyDefault\n                    height={'calc(100% - 35px)'}\n                    message={() => {\n                      return (\n                        <Trans i18nKey='labelNoContent'>\n                          <Button onClick={getDualMap} variant={'contained'}>\n                            {t('labelDualRefresh')}\n                          </Button>\n                        </Trans>\n                      )\n                    }}\n                  />\n                </Box>\n              )}\n            </>\n          </MaxWidthContainer>\n        </>\n      ) : (\n        <ChooseDualType\n          onSelect={(item) => {\n            searchParams.set('viewType', item)\n            history.push(pathname + '?' + searchParams.toString())\n          }}\n          productsRef={productsRef}\n          dualTokenList={dualTokenList}\n        />\n      )}\n\n      <ModalDualPanel\n        confirmDualAutoInvest={confirmDualAutoInvest}\n        setConfirmDualAutoInvest={setConfirmDualAutoInvest}\n        viewType={viewType as any}\n        dualTradeProps={{ ...dualTradeProps }}\n        dualToastOpen={dualToastOpen}\n        closeDualToast={closeDualToast}\n        isBeginnerMode={viewType === DualViewType.DualBegin}\n      />\n    </Box>\n  )\n})\n"
  },
  {
    "path": "packages/web-earn/src/pages/InvestPage/DualPanel/hook.ts",
    "content": "import { useHistory, useLocation, useRouteMatch } from 'react-router-dom'\nimport {\n  confirmation,\n  findDualMarket,\n  LoopringAPI,\n  makeDualViewItem,\n  store,\n  useDualMap,\n  useTokenMap,\n} from '@loopring-web/core'\nimport React from 'react'\nimport _ from 'lodash'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport {\n  DualCurrentPrice,\n  DualViewInfo,\n  DualViewType,\n  myLog,\n  SagaStatus,\n} from '@loopring-web/common-resources'\n\nconst DUALLimit = 20\nexport const useDualHook = () => {\n  const match: any = useRouteMatch('/invest/dual/:market?')\n  const { search } = useLocation()\n  const searchParams = new URLSearchParams(search)\n  const viewType = searchParams.get('viewType')\n  const { tokenMap, idIndex } = useTokenMap()\n  const { marketArray, marketMap, tradeMap, status: dualStatus, getDualMap } = useDualMap()\n  const {\n    confirmation: { confirmedDualInvestV2 },\n  } = confirmation.useConfirmation()\n  const history = useHistory()\n  const nodeTimer = React.useRef<NodeJS.Timeout | -1>(-1)\n\n  const [isLoading, setIsLoading] = React.useState(false)\n  const [currentPrice, setCurrentPrice] = React.useState<DualCurrentPrice | undefined>(undefined)\n  const [, , coinA, coinB] =\n    (match?.params?.market ? match.params.market : 'ETH-USDC').match(/(dual-)?(\\w+)-(\\w+)/i) ?? []\n\n  const [pairASymbol, setPairASymbol] = React.useState(() =>\n    tradeMap && tradeMap[coinA] ? coinA : 'ETH',\n  )\n  const [pairBSymbol, setPairBSymbol] = React.useState(\n    coinB && tradeMap && tradeMap[pairASymbol]?.tokenList\n      ? tradeMap[pairASymbol].tokenList.includes(coinB)\n        ? coinB\n        : tradeMap[pairASymbol].tokenList[0]\n      : 'USDC',\n  )\n  const [pair, setPair] = React.useState(`${pairASymbol}-${pairBSymbol}`)\n  const [market, setMarket] = React.useState(() =>\n    marketArray?.length ? findDualMarket(marketArray, pairASymbol, pairBSymbol) : '',\n  )\n  const [[marketBase, marketQuote], setMarketPair] = React.useState(() => {\n    // @ts-ignore\n    const [, , coinA, coinB] = market ? market : 'ETH-USDC'.match(/(dual-)?(\\w+)-(\\w+)/i) ?? []\n    return [coinA, coinB]\n  })\n\n  const handleOnPairChange = React.useCallback(\n    (\n      prosp:\n        | {\n            pairA: string\n          }\n        | { pairB: string },\n    ) => {\n      let market: any\n      let _pairBSymbol: string = ''\n      let _pairASymbol = pairASymbol\n      if (prosp.hasOwnProperty('pairA')) {\n        _pairASymbol = (prosp as any).pairA\n        _pairBSymbol = tradeMap[_pairASymbol]?.tokenList[0]\n        setPairASymbol(_pairASymbol)\n        setPairBSymbol(_pairBSymbol)\n        market = findDualMarket(marketArray, _pairASymbol, _pairBSymbol)\n      } else if (prosp.hasOwnProperty('pairB')) {\n        _pairBSymbol = (prosp as any).pairB\n        setPairBSymbol(_pairBSymbol)\n        market = findDualMarket(marketArray, _pairASymbol, _pairBSymbol)\n      }\n      if (market) {\n        history.push(`/invest/dual/${_pairASymbol}-${_pairBSymbol}${search}`)\n        const [, , coinA, coinB] = market.match(/(dual-)?(\\w+)-(\\w+)/i)\n        setMarket(market)\n        setPair(`${_pairASymbol}-${_pairBSymbol}`)\n        setMarketPair([coinA, coinB])\n      }\n    },\n    [marketArray, pairASymbol, tradeMap],\n  )\n\n  const [dualProducts, setDualProducts] = React.useState<DualViewInfo[]>([])\n  const [isDualBalanceSufficient, setIsDualBalanceSufficient] = React.useState<boolean | undefined>(\n    undefined,\n  )\n  // const [productRawData,setProductRawData] = React.useState([])\n  const getProduct = _.debounce(async () => {\n    setIsLoading(true)\n    try {\n      setIsDualBalanceSufficient(undefined)\n      const market = marketArray && findDualMarket(marketArray, pairASymbol, pairBSymbol)\n      if (nodeTimer.current !== -1) {\n        clearTimeout(nodeTimer.current as NodeJS.Timeout)\n      }\n      // @ts-ignore\n      const currency = market ? marketMap[market]?.currency : undefined\n      if (pairASymbol && pairBSymbol && market) {\n        // @ts-ignore\n        const [, , marketSymbolA, marketSymbolB] = (market ?? '').match(/(dual-)?(\\w+)-(\\w+)/i)\n        const dualType =\n          marketSymbolA === pairASymbol ? sdk.DUAL_TYPE.DUAL_BASE : sdk.DUAL_TYPE.DUAL_CURRENCY\n        const { quoteAlias } = marketMap[market]\n\n        const response = await LoopringAPI.defiAPI?.getDualInfos({\n          baseSymbol: marketSymbolA,\n          quoteSymbol: quoteAlias ?? marketSymbolB,\n          currency: currency ?? '',\n          dualType,\n          startTime: Date.now() + 1000 * 60 * 60,\n          timeSpan: 1000 * 60 * 60 * 24 * 9,\n          limit: DUALLimit,\n        })\n\n        if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n          setDualProducts([])\n        } else {\n          const {\n            // totalNum,\n            dualInfo: { infos, index, balance, rules },\n          } = response as any\n          const balanceCoin = pairASymbol === 'USDC' ? 'USDT' : pairASymbol\n          const found = balance.find((_balance: any) => _balance.coin === balanceCoin)\n          const sellToken = tokenMap[balanceCoin]\n          if (dualType === sdk.DUAL_TYPE.DUAL_BASE) {\n            var minSellVol = marketMap[market].baseLimitAmount\n          } else {\n            minSellVol = marketMap[market].quoteLimitAmount\n          }\n          setIsDualBalanceSufficient(\n            found && sellToken\n              ? sdk\n                  .toBig(found.free)\n                  .times('1e' + sellToken.decimals)\n                  .isGreaterThanOrEqualTo(minSellVol)\n              : undefined,\n          )\n          setCurrentPrice({\n            quoteUnit: marketSymbolB,\n            base: marketSymbolA,\n            quote: marketSymbolB,\n            currentPrice: index.index,\n            precisionForPrice: marketMap[market].precisionForPrice,\n          })\n\n          const rule = rules[0]\n          const rawData = infos.map((item: sdk.DualProductAndPrice) => {\n            return makeDualViewItem(item, index, rule, pairASymbol, pairBSymbol, marketMap[market])\n          })\n          myLog('setDualProducts', rawData)\n          setDualProducts(rawData)\n          // setIsLoading(false)\n        }\n        // }\n      }\n\n      nodeTimer.current = setTimeout(() => {\n        getProduct()\n      }, 60000)\n    } catch {\n      setDualProducts([])\n    } finally {\n      setIsLoading(false)\n    }\n  }, 100)\n  React.useEffect(() => {\n    if (dualStatus === SagaStatus.UNSET && pair) {\n      getProduct.cancel()\n      const [_, _pairASymbol, _pairBSymbol] = pair.match(/(\\w+)-(\\w+)/i)\n      if (marketArray !== undefined && marketArray.length) {\n        const market = findDualMarket(marketArray, _pairASymbol, _pairBSymbol)\n        if (market) {\n          setPairASymbol(_pairASymbol)\n          setPairBSymbol(_pairBSymbol)\n          getProduct()\n          return\n        } else {\n          handleOnPairChange({ pairB: _pairBSymbol })\n        }\n        return\n      }\n      history.push(`/invest/dual/${search}`)\n      myLog('update pair', pair)\n    }\n    return () => {\n      if (nodeTimer.current !== -1) {\n        clearTimeout(nodeTimer.current as NodeJS.Timeout)\n      }\n      getProduct.cancel()\n    }\n  }, [pair, dualStatus])\n  React.useEffect(() => {\n    switch (viewType) {\n      case DualViewType.DualGain:\n        setStep2BuyOrSell('Sell')\n        break\n      case DualViewType.DualDip:\n        setStep2BuyOrSell('Buy')\n        break\n      case DualViewType.DualBegin:\n        // setBeginnerMode(true)\n        setStep2BuyOrSell(undefined)\n        break\n      case DualViewType.All:\n      default:\n        setStep2BuyOrSell(undefined)\n        break\n    }\n    getDualMap()\n  }, [viewType])\n  const [step1SelectedToken, setStep1SelectedToken] = React.useState<string | undefined>(undefined)\n  const [step2BuyOrSell, setStep2BuyOrSell] = React.useState<'Buy' | 'Sell' | undefined>(undefined)\n  const [step3Token, setStep3Token] = React.useState<string | undefined>(undefined)\n  const onSelectStep1Token = React.useCallback(\n    (token?: string) => {\n      setStep1SelectedToken(token)\n      //@ts-ignore\n      if (![DualViewType.DualGain, DualViewType.DualDip].includes(viewType)) {\n        setStep2BuyOrSell(undefined)\n      }\n      setStep3Token(undefined)\n    },\n    [viewType],\n  )\n\n  const onSelectStep2BuyOrSell = React.useCallback((which: 'Buy' | 'Sell') => {\n    setStep2BuyOrSell(which)\n    setStep3Token(undefined)\n  }, [])\n  const onSelectStep3Token = React.useCallback(\n    (which: string) => {\n      setStep3Token(which)\n      if (step2BuyOrSell! === 'Sell') {\n        var pairA = step1SelectedToken!\n        var pairB = which\n      } else {\n        pairA = which\n        pairB = step1SelectedToken!\n      }\n      setPairASymbol(pairA)\n      setPairBSymbol(pairB)\n      const market = findDualMarket(marketArray, pairA, pairB)\n      history.push(`/invest/dual/${pairA}-${pairB}${search}`)\n      if (market) {\n        const [, , coinA, coinB] = market ?? ''.match(/(dual-)?(\\w+)-(\\w+)/i)\n        setMarket(market)\n        setPair(`${pairA}-${pairB}`)\n        setMarketPair([coinA, coinB])\n      }\n    },\n    [step1SelectedToken, step2BuyOrSell, marketArray, tradeMap],\n  )\n  const baseTokenList = React.useMemo(() => {\n    if (dualStatus === SagaStatus.UNSET) {\n      const object = Reflect.ownKeys(marketMap ?? {}).reduce((prev, key) => {\n        if (!marketMap[key.toString()].enabled) {\n          return prev\n        }\n        const baseSymbol = idIndex[marketMap[key.toString()].baseTokenId]\n        prev[baseSymbol] = {\n          tokenName: baseSymbol,\n          tokenList: tradeMap[baseSymbol]?.tokenList,\n        }\n        if (viewType === DualViewType.DualGain) {\n          prev[baseSymbol] = {\n            ...prev[baseSymbol],\n          }\n        } else if (viewType === DualViewType.DualDip) {\n          prev[baseSymbol] = {\n            ...prev[baseSymbol],\n          }\n        } else {\n          prev[baseSymbol] = {\n            ...prev[baseSymbol],\n          }\n        }\n\n        return prev\n      }, {} as any)\n      myLog('asdhksjahdjs')\n      return _.mapValues(object, (token) => {\n        const keys = Object.keys(marketMap).filter((key) => key.includes(token.tokenName))\n        if (viewType === DualViewType.DualGain) {\n          var maxAPY = _.max(keys.map((key) => (marketMap[key] as any).baseTokenApy?.max as number))\n          var minAPY = _.max(keys.map((key) => (marketMap[key] as any).baseTokenApy?.min as number))\n        } else if (viewType === DualViewType.DualDip) {\n          maxAPY = _.max(keys.map((key) => (marketMap[key] as any).quoteTokenApy?.max as number))\n          minAPY = _.max(keys.map((key) => (marketMap[key] as any).quoteTokenApy?.min as number))\n        } else {\n          maxAPY = _.max([\n            ...keys.map((key) => (marketMap[key] as any).quoteTokenApy?.max as number),\n            ...keys.map((key) => (marketMap[key] as any).baseTokenApy?.max as number),\n          ])\n          minAPY = _.max([\n            ...keys.map((key) => (marketMap[key] as any).quoteTokenApy?.min as number),\n            ...keys.map((key) => (marketMap[key] as any).baseTokenApy?.min as number),\n          ])\n        }\n        return {\n          ...token,\n          maxAPY,\n          minAPY,\n        }\n      })\n    } else {\n      return {}\n    }\n  }, [viewType, dualStatus])\n\n  return {\n    currentPrice,\n    pairASymbol,\n    pairBSymbol,\n    market,\n    isLoading,\n    dualProducts,\n    handleOnPairChange,\n    marketBase,\n    marketQuote,\n    // priceObj,\n    pair,\n    step1SelectedToken,\n    step2BuyOrSell,\n    step3Token,\n    onSelectStep1Token,\n    onSelectStep2BuyOrSell,\n    onSelectStep3Token,\n    isDualBalanceSufficient,\n    baseTokenList,\n    // baseSymbol: priceObj.symbol,\n  }\n}\n"
  },
  {
    "path": "packages/web-earn/src/pages/InvestPage/LeverageETHPanel/TradePanel.tsx",
    "content": "import { confirmation, useDefiTrade } from '@loopring-web/core'\nimport { MarketType, leverageETHAdvice, myLog } from '@loopring-web/common-resources'\nimport {\n  ConfirmDefiNOBalance,\n  DeFiWrap,\n  LoadingBlock,\n  useSettings,\n} from '@loopring-web/component-lib'\nimport { Box } from '@mui/material'\nimport React from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { useDefiMap } from '@loopring-web/core'\n\nexport const TradePanel = ({\n  isJoin,\n  setServerUpdate,\n  setToastOpen,\n}: {\n  isJoin: boolean\n  setServerUpdate: (state: any) => void\n  setToastOpen: (state: any) => void\n}) => {\n  const { marketLeverageArray: marketArray } = useDefiMap()\n  // @ts-ignore\n  const market: MarketType = marketArray[0]\n  myLog('isJoin', isJoin, 'market', market)\n  const [confirmShowLimitBalance, setConfirmShowLimitBalance] = React.useState<boolean>(false)\n  const [confirmShowNoBalance, setConfirmShowNoBalance] = React.useState<boolean>(false)\n\n  const { deFiWrapProps } = useDefiTrade({\n    isJoin,\n    setToastOpen: setToastOpen as any,\n    market: market,\n    setServerUpdate,\n    setConfirmShowNoBalance,\n    confirmShowLimitBalance,\n    setConfirmShowLimitBalance,\n    isLeverageETH: true,\n  })\n  const { t } = useTranslation()\n\n  const { isMobile } = useSettings()\n  const [, tokenBase] = market.match(/(\\w+)-(\\w+)/i) ?? []\n\n  const styles = isMobile\n    ? { flex: 1, background: 'var(--color-box-third)' }\n    : { width: 'var(--swap-box-width)', background: 'var(--color-box-third)' }\n  const { setShowLeverageETHPopup } = confirmation.useConfirmation()\n\n  return (\n    <>\n      {deFiWrapProps.deFiCalcData ? (\n        <Box\n          className={'hasLinerBg'}\n          display={'flex'}\n          style={styles}\n          justifyContent={'center'}\n          padding={5 / 2}\n        >\n          <DeFiWrap\n            isLeverageETH\n            market={market}\n            isJoin={isJoin}\n            setShowLeverageETHPopup={setShowLeverageETHPopup}\n            type={leverageETHAdvice.project}\n            title={t('labelLeverageETHStaking')}\n            {...(deFiWrapProps as any)}\n          />\n        </Box>\n      ) : (\n        <LoadingBlock />\n      )}\n      <ConfirmDefiNOBalance\n        isJoin={isJoin}\n        market={market}\n        type={leverageETHAdvice.project as any}\n        handleClose={(_e) => {\n          setConfirmShowNoBalance(false)\n          if (deFiWrapProps?.onRefreshData) {\n            deFiWrapProps?.onRefreshData(true, true)\n          }\n        }}\n        open={confirmShowNoBalance}\n        isLeverage\n      />\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/web-earn/src/pages/InvestPage/LeverageETHPanel/index.tsx",
    "content": "import React from 'react'\nimport styled from '@emotion/styled'\nimport { Box, CardContent, Grid, Typography } from '@mui/material'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport { TradePanel } from './TradePanel'\nimport {\n  boxLiner,\n  Button,\n  ConfirmInvestDefiServiceUpdate,\n  Toast,\n  LoadingBlock,\n  ConfirmInvestDefiRisk,\n  ToastType,\n  useToggle,\n  useSettings,\n} from '@loopring-web/component-lib'\nimport { confirmation, useDefiMap, useToast } from '@loopring-web/core'\nimport { useHistory, useRouteMatch } from 'react-router-dom'\nimport { BackIcon, TOAST_TIME } from '@loopring-web/common-resources'\nimport { MaxWidthContainer, containerColors } from '..'\nimport { useTheme } from '@emotion/react'\n\nexport const StyleWrapper = styled(Box)`\n  position: relative;\n  border-radius: ${({ theme }) => theme.unit}px;\n\n  .loading-block {\n    background: initial;\n  }\n\n  .hasLinerBg {\n    ${({ theme }) => boxLiner({ theme })}\n  }\n\n  border-radius: ${({ theme }) => theme.unit}px;\n` as typeof Grid\nexport const StyleCardContent = styled(CardContent)`\n  display: flex;\n\n  &.tableLap {\n    display: block;\n    width: 100%;\n    cursor: pointer;\n\n    .content {\n      flex-direction: column;\n      align-items: center;\n      padding-top: ${({ theme }) => 4 * theme.unit}px;\n\n      .des {\n        align-items: center;\n        margin: ${({ theme }) => 3 * theme.unit}px 0;\n      }\n\n      .backIcon {\n        display: none;\n      }\n    }\n  }\n\n  padding: 0;\n\n  &:last-child {\n    padding: 0;\n  }\n\n  &.isMobile {\n    flex: 1;\n\n    .content {\n      flex-direction: row;\n      width: 100%;\n\n      .des {\n        margin-left: ${({ theme }) => 2 * theme.unit}px;\n        align-items: flex-start;\n      }\n    }\n  }\n` as typeof CardContent\n\nconst ButtonStyled = styled(Button)`\n  background-color: var(--color-button-outlined);\n  color: var(--color-text-primary);\n  :hover {\n    background-color: var(--color-button-outlined);\n    ::before {\n      border-radius: 4px;\n    }\n  }\n`\n\nconst LeverageETHPanel: any = withTranslation('common')(({ t }: WithTranslation & {}) => {\n  const { marketLeverageArray: marketArray } = useDefiMap()\n  const {\n    confirmedLeverageETHInvest,\n    confirmation: {\n      confirmedLeverageETHInvest: confirmed,\n      confirmationNeeded,\n      showLeverageETHPopup,\n    },\n    setShowLeverageETHPopup,\n  } = confirmation.useConfirmation()\n  const {\n    toggle: {\n      CIETHInvest: { enable },\n    },\n  } = useToggle()\n\n  const _confirmedDefiInvest = {\n    isShow: showLeverageETHPopup,\n    type: 'CiETH',\n    confirmationNeeded,\n  }\n  const setConfirmedDefiInvest = ({ isShow }: { isShow: boolean }) => {\n    if (isShow) {\n      setShowLeverageETHPopup({ isShow: true, confirmationNeeded: true })\n    } else {\n      setShowLeverageETHPopup({ isShow: false, confirmationNeeded: true })\n    }\n  }\n  const match: any = useRouteMatch('/invest/leverageETH/:isJoin?')\n  const [serverUpdate, setServerUpdate] = React.useState(false)\n  const { toastOpen, setToastOpen, closeToast } = useToast()\n  const history = useHistory()\n  const isJoin = match?.params?.isJoin?.toUpperCase() !== 'Redeem'.toUpperCase()\n  React.useEffect(() => {\n    setConfirmedDefiInvest({\n      isShow: enable ? !confirmed : false,\n    })\n  }, [confirmed, enable])\n  const theme = useTheme()\n  const { isMobile } = useSettings()\n  return (\n    <Box display={'flex'} flexDirection={'column'} flex={1}>\n      <MaxWidthContainer minHeight={'70vh'} paddingY={5}>\n        <StyleWrapper\n          display={'flex'}\n          flexDirection={'column'}\n          justifyContent={'center'}\n          alignItems={'center'}\n          flex={1}\n          marginTop={6}\n        >\n          {marketArray?.length ? (\n            // match?.params?.market && _market ? (\n            <TradePanel\n              isJoin={isJoin}\n              setServerUpdate={setServerUpdate}\n              setToastOpen={setToastOpen}\n            />\n          ) : (\n            // )\n            // : (\n            //   <LandDefiInvest setConfirmedDefiInvest={setConfirmedDefiInvest} />\n            // )\n            <LoadingBlock />\n          )}\n          <Toast\n            alertText={toastOpen?.content ?? ''}\n            severity={toastOpen?.type ?? ToastType.success}\n            open={toastOpen?.open ?? false}\n            autoHideDuration={TOAST_TIME}\n            onClose={closeToast}\n          />\n\n          <ConfirmInvestDefiServiceUpdate\n            open={serverUpdate}\n            handleClose={() => setServerUpdate(false)}\n          />\n          <ConfirmInvestDefiRisk\n            confirmationNeeded={confirmationNeeded}\n            open={_confirmedDefiInvest.isShow}\n            type={_confirmedDefiInvest.type as any}\n            handleClose={(_e, isAgree) => {\n              if (!isAgree) {\n                setConfirmedDefiInvest({ isShow: false })\n                history.push('/invest/overview')\n              } else {\n                confirmedLeverageETHInvest()\n                setConfirmedDefiInvest({ isShow: false })\n              }\n            }}\n          />\n        </StyleWrapper>\n      </MaxWidthContainer>\n    </Box>\n  )\n})\n\nexport default LeverageETHPanel\n"
  },
  {
    "path": "packages/web-earn/src/pages/InvestPage/MyLiquidityPanel/hook.ts",
    "content": "import React from 'react'\nimport { AmmRecordRow, MyPoolRow, RawDataDefiSideStakingItem } from '@loopring-web/component-lib'\nimport {\n  LoopringAPI,\n  makeDefiInvestReward,\n  makeWalletLayer2,\n  store,\n  SummaryMyInvest,\n  useAccount,\n  useAmmMap,\n  useDefiMap,\n  useStakingMap,\n  useTokenMap,\n  useTokenPrices,\n  useUserRewards,\n  useWalletLayer2Socket,\n  walletLayer2Service,\n} from '@loopring-web/core'\nimport {\n  AccountStatus,\n  CustomError,\n  ErrorMap,\n  myLog,\n  RowInvestConfig,\n  SagaStatus,\n  STAKING_INVEST_LIMIT,\n} from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { pickBy, toArray } from 'lodash'\n// import { walletServices } from \"@loopring-web/web3-provider\";\n\nexport const useOverview = <R extends { [key: string]: any }, I extends { [key: string]: any }>({\n  dualOnInvestAsset,\n  rowConfig = RowInvestConfig,\n  hideSmallBalances,\n}: {\n  ammActivityMap: sdk.LoopringMap<sdk.LoopringMap<sdk.AmmPoolActivityRule[]>> | undefined\n  dualOnInvestAsset: any //RawDataDualAssetItem[];\n  rowConfig?: any\n  hideSmallBalances: boolean\n}): {\n  myAmmMarketArray: AmmRecordRow<R>[]\n  summaryMyInvest: Partial<SummaryMyInvest>\n  myPoolRow: MyPoolRow<R>[]\n  showLoading: boolean\n  filter: { searchValue: string }\n  tableHeight: number\n  handleFilterChange: (props: { searchValue: string }) => void\n  stakingList: RawDataDefiSideStakingItem[]\n  getStakingList: (props: { limit?: number; offset?: number }) => Promise<void>\n  stakeShowLoading: boolean\n  stakingTotal: number\n  totalStaked: string\n  totalStakedRewards: string\n  totalLastDayPendingRewards: string\n  totalClaimableRewards: string\n  stakedSymbol: string\n} => {\n  const { account, status: accountStatus } = useAccount()\n  const { status: userRewardsStatus, userRewardsMap, myAmmLPMap } = useUserRewards()\n  const { tokenMap } = useTokenMap()\n  const { marketCoins: defiCoinArray, marketLeverageCoins: leverageETHCoinArray } = useDefiMap()\n\n  const { status: ammMapStatus, ammMap } = useAmmMap()\n  const { tokenPrices } = useTokenPrices()\n  const { marketMap: stakingMap } = useStakingMap()\n\n  const [summaryMyInvest, setSummaryMyInvest] = React.useState<Partial<SummaryMyInvest>>({})\n  const [filter, setFilter] = React.useState({\n    searchValue: '',\n  })\n  const [stakeShowLoading, setStakeShowLoading] = React.useState(false)\n  const [\n    {\n      stakingList,\n      total: stakingTotal,\n      totalStaked,\n      totalLastDayPendingRewards,\n      totalStakedRewards,\n      totalClaimableRewards,\n      stakedSymbol,\n    },\n    setStakingProps,\n  ] = React.useState<{\n    stakingList: RawDataDefiSideStakingItem[]\n    totalStaked: string\n    totalLastDayPendingRewards: string\n    totalStakedRewards: string\n    totalClaimableRewards: string\n    total: number\n    stakedSymbol: string\n  }>({\n    stakingList: [],\n    total: 0,\n    totalStaked: '0',\n    totalLastDayPendingRewards: '0',\n    totalStakedRewards: '0',\n    totalClaimableRewards: '0',\n    stakedSymbol: 'LRC',\n  })\n\n  // const [totalData, setTotalData] = React.useState<MyPoolRow<R>[]>([]);\n  const [summaryDefiReward, setSummaryDefiReward] = React.useState('')\n  const [myPoolRow, setMyPoolRow] = React.useState<MyPoolRow<R>[]>([])\n  const [tableHeight, setTableHeight] = React.useState(0)\n  const resetTableData = React.useCallback(\n    (viewData) => {\n      setMyPoolRow(viewData)\n      setTableHeight(\n        viewData.length > 0\n          ? rowConfig.rowHeaderHeight + viewData.length * rowConfig.rowHeight\n          : 350,\n      )\n    },\n    [rowConfig.rowHeaderHeight, rowConfig.rowHeight],\n  )\n  const updateData = React.useCallback(() => {\n    if (myAmmLPMap) {\n      let resultData: MyPoolRow<R>[] = Object.keys(myAmmLPMap).map((key) => ({\n        ...myAmmLPMap[key],\n        ammDetail: ammMap['AMM-' + key],\n      }))\n\n      if (hideSmallBalances) {\n        // myLog('hideSmallBalances', hideSmallBalances, resultData)\n        resultData = resultData.filter((o) => sdk.toBig(o?.balanceU ?? 0).gt(0))\n      }\n      if (filter.searchValue) {\n        resultData = resultData.filter(\n          (o) =>\n            o.ammDetail.coinAInfo.simpleName\n              .toLowerCase()\n              .includes(filter.searchValue.toLowerCase()) ||\n            o.ammDetail.coinBInfo.simpleName\n              .toLowerCase()\n              .includes(filter.searchValue.toLowerCase()),\n        )\n      }\n      resetTableData(resultData)\n    }\n  }, [myAmmLPMap, filter, hideSmallBalances, resetTableData, defiCoinArray])\n  const handleFilterChange = React.useCallback(\n    (filter) => {\n      setFilter(filter)\n    },\n    [setFilter],\n  )\n  React.useEffect(() => {\n    updateData()\n  }, [filter, hideSmallBalances])\n\n  const [myAmmMarketArray, setMyAmmMarketArray] = React.useState<AmmRecordRow<R>[]>([])\n  const [showLoading, setShowLoading] = React.useState(false)\n  const mountedRef = React.useRef(false)\n\n\n  React.useEffect(() => {\n    if (ammMapStatus === SagaStatus.UNSET && accountStatus === SagaStatus.UNSET) {\n      walletLayer2Service.sendUserUpdate()\n      const account = store.getState().account\n      if (account.readyState == AccountStatus.ACTIVATED) {\n        getStakingList({})\n        makeDefiInvestReward().then((summaryDefiReward) => {\n          if (mountedRef.current) {\n            setSummaryDefiReward(summaryDefiReward.toString())\n          }\n        })\n      }\n    }\n  }, [ammMapStatus, accountStatus])\n\n\n  React.useEffect(() => {\n    mountedRef.current = true\n    setShowLoading(true)\n    return () => {\n      mountedRef.current = false\n    }\n  }, [])\n\n  const getStakingList = React.useCallback(\n    async ({ limit = STAKING_INVEST_LIMIT, offset = 0 }: { limit?: number; offset?: number }) => {\n      setStakeShowLoading(true)\n      const stakingSymbol = 'TAIKO'\n      if (LoopringAPI.defiAPI && account.readyState === AccountStatus.ACTIVATED) {\n        const [response] = await Promise.all([\n          LoopringAPI.defiAPI.getStakeSummary(\n            {\n              accountId: account.accountId,\n              limit,\n              offset,\n              statuses: 'locked,partial_unlocked',\n              tokenId: tokenMap[stakingSymbol].tokenId,\n            },\n            account.apiKey,\n          ),\n        ])\n        if (\n          (response &&\n            ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message)) ||\n          !stakingMap[stakingSymbol]\n        ) {\n          throw new CustomError(ErrorMap.ERROR_UNKNOWN)\n        } else {\n          let {\n            totalNum,\n            totalStaked,\n            totalStakedRewards,\n            totalLastDayPendingRewards,\n            totalClaimableRewards,\n            list,\n          } = response as any\n\n          list = list.map((item: sdk.StakeInfoOrigin) => {\n            return {\n              ...stakingMap[stakingSymbol],\n              ...item,\n              status_product: stakingMap[stakingSymbol].status,\n            }\n          })\n\n          setStakingProps({\n            total: totalNum,\n            stakingList: list,\n            totalStaked,\n            totalStakedRewards,\n            totalLastDayPendingRewards,\n            totalClaimableRewards,\n            stakedSymbol: stakingSymbol,\n          })\n\n          const totalDollar = sdk\n            .toBig(totalStaked)\n            .div('1e' + tokenMap[stakingSymbol].decimals)\n            .times(tokenPrices[stakingSymbol])\n\n          setSummaryMyInvest((state) => {\n            return {\n              ...state,\n              taikoFarmingDollar: totalDollar.toString(),\n              investDollar: sdk\n                .toBig(state.ammPoolDollar ?? 0)\n                .plus(state.dualStakeDollar ?? 0)\n                .plus(state.leverageETHDollar ?? 0)\n                .plus(state.taikoFarmingDollar ?? 0)\n                .plus(totalDollar ?? 0)\n                .toString(),\n            }\n          })\n        }\n      }\n      setStakeShowLoading(false)\n    },\n    [account, tokenPrices],\n  )\n\n  return {\n    myAmmMarketArray,\n    summaryMyInvest,\n    myPoolRow,\n    showLoading,\n    filter,\n    tableHeight,\n    handleFilterChange,\n    stakingList,\n    getStakingList,\n    stakeShowLoading,\n    stakingTotal,\n    totalStaked,\n    totalStakedRewards,\n    totalLastDayPendingRewards,\n    totalClaimableRewards,\n    stakedSymbol,\n  }\n}\n"
  },
  {
    "path": "packages/web-earn/src/pages/InvestPage/MyLiquidityPanel/index.tsx",
    "content": "import { Box, Button, Grid, Modal, Tab, Typography } from '@mui/material'\nimport { Trans, WithTranslation, withTranslation } from 'react-i18next'\nimport { useHistory, useLocation, useRouteMatch } from 'react-router-dom'\nimport {\n  ButtonStyle,\n  CancelDualAlert,\n  DualAssetTable,\n  DualDetail,\n  EarningsDetail,\n  EmptyDefault,\n  ModalCloseButton,\n  SwitchPanelStyled,\n  Toast,\n  ToastType,\n  VaultAssetsTable,\n  useSettings,\n  useGetVaultAssets, \n  useVaultMarket\n} from '@loopring-web/component-lib'\nimport {\n  AccountStatus,\n  CurrencyToTag,\n  DualViewBase,\n  EmptyValueTag,\n  FailedIcon,\n  getValuePrecisionThousand,\n  HiddenTag,\n  INVEST_TABS,\n  InvestAssetRouter,\n  // InvestTab,\n  // investTabs,\n  L1L2_NAME_DEFINED,\n  MapChainId,\n  myLog,\n  PriceTag,\n  SagaStatus,\n  SoursURL,\n  STAKING_INVEST_LIMIT,\n  TOAST_TIME,\n  TokenType,\n  TradeBtnStatus,\n} from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { AmmPoolActivityRule, LoopringMap } from '@loopring-web/loopring-sdk'\nimport { useOverview } from './hook'\nimport {\n  confirmation,\n  fiatNumberDisplay,\n  numberFormatShowInPercent,\n  numberFormatThousandthPlace,\n  TableWrapStyled,\n  useAccount,\n  useAmmActivityMap,\n  useDefiMap,\n  useDualMap,\n  useStakeRedeemClick,\n  useSystem,\n  useTokenMap,\n  useTokenPrices,\n  useUserRewards,\n  useVaultAccountInfo,\n  useVaultMap,\n  useVaultTicker,\n} from '@loopring-web/core'\nimport { useTheme } from '@emotion/react'\nimport { useGetAssets } from '../../AssetPage/AssetPanel/hook'\nimport { useDualAsset } from '../../AssetPage/HistoryPanel/useDualAsset'\nimport React from 'react'\nimport { containerColors, MaxWidthContainer } from '..'\nimport _ from 'lodash'\nimport { RowEarnConfig } from '../../../constant/setting'\n// import { useVaultMarket } from 'pages/VaultPage/HomePanel/hook'\n// usevau\nimport Decimal from 'decimal.js'\nimport { TaikoFarmingPortfolioTable } from '@loopring-web/component-lib/src/components/tableList/taikoFarmingTable'\nimport { utils } from 'ethers'\n// import { useGetVaultAssets } from 'pages/VaultPage/hooks/useVaultDashBoard'\n\nconst MyLiquidity = withTranslation('common')(\n  ({\n    t,\n    hideAssets,\n    className,\n    isPortfolio\n  }: WithTranslation & {\n    className?: string\n    hideAssets?: boolean\n    isPortfolio?: boolean\n  }) => {\n    let match: any = useRouteMatch('/invest/balance/:type')\n\n    const { search } = useLocation()\n    const searchParams = new URLSearchParams(search)\n    const { totalClaims, getUserRewards, errorMessage: rewardsAPIError } = useUserRewards()\n\n    const dualRef = React.useRef(null)\n    const { ammActivityMap } = useAmmActivityMap()\n    const { forexMap, getValueInCurrency } = useSystem()\n    const { tokenMap, idIndex } = useTokenMap()\n\n    const { tokenPrices } = useTokenPrices()\n    const { redeemItemClick } = useStakeRedeemClick()\n    const { marketMap: dualMarketMap, status: dualMarketMapStatus } = useDualMap()\n    const { assetsRawData, onSend, onReceive, allowTrade, getTokenRelatedMarketArray } =\n      useGetAssets()\n    const { account } = useAccount()\n    const { currency, hideSmallBalances, defaultNetwork, coinJson } = useSettings()\n    const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n    const { setShowAutoDefault, confirmation: { showAutoDefault } } = confirmation.useConfirmation()\n    const [showCancelOneAlert, setShowCancelOndAlert] = React.useState<{\n      open: boolean\n      row?: any\n    }>({\n      open: false,\n      row: undefined,\n    })\n    const {\n      dualList,\n      dualOnInvestAsset,\n      getDualTxList,\n      pagination,\n      showDetail,\n      showLoading: dualLoading,\n      open: dualOpen,\n      detail: dualDetail,\n      setOpen: setDualOpen,\n      getDetail,\n      refresh,\n      setShowRefreshError,\n      showRefreshError,\n      refreshErrorInfo,\n      dualProducts,\n      getProduct,\n      cancelReInvest,\n      dualToastOpen,\n      closeDualToast,\n      editDualTrade,\n      editDualBtnInfo,\n      editDualBtnStatus,\n      handleOnchange,\n      onEditDualClick,\n    } = useDualAsset()\n\n    const {\n      summaryMyInvest,\n      getStakingList,\n      stakedSymbol,\n      stakeShowLoading,\n      totalStaked,\n    } = useOverview({\n      ammActivityMap,\n      dualOnInvestAsset,\n      hideSmallBalances,\n      // dualList,\n    })\n    myLog('summaryMyInvest', summaryMyInvest, forexMap[currency])\n\n    React.useEffect(() => {\n      if (\n        account.readyState === AccountStatus.ACTIVATED &&\n        dualMarketMapStatus === SagaStatus.UNSET\n      ) {\n        getDualTxList({})\n      }\n    }, [account.readyState, dualMarketMapStatus])\n\n    const theme = useTheme()\n    const { isMobile } = useSettings()\n    const dualStakeDollar = React.useMemo(() => {\n      return dualOnInvestAsset\n        ? dualOnInvestAsset.reduce((pre: string, cur: any) => {\n            const price = tokenPrices[idIndex[cur.tokenId]]\n            return sdk\n              .toBig(cur?.amount ?? 0)\n              .div('1e' + tokenMap[idIndex[cur.tokenId]].decimals)\n              .times(price ?? 0)\n              .plus(pre)\n              .toString()\n          }, '0')\n        : undefined\n    }, [dualOnInvestAsset, tokenPrices])\n\n    const [tab, setTab] = React.useState(match?.params?.type ?? InvestAssetRouter.DUAL)\n    React.useEffect(() => {\n      setTab(\n        InvestAssetRouter[\n          // @ts-ignore\n          match?.params?.type?.toUpperCase() ?? InvestAssetRouter.DUAL\n        ] ?? InvestAssetRouter.DUAL,\n      )\n      if (searchParams?.get('refreshStake')) {\n        getStakingList({})\n      }\n    }, [match?.params?.type, searchParams?.get('refreshStake')])\n\n    const label = React.useMemo(() => {\n      if (editDualBtnInfo.label) {\n        const key = editDualBtnInfo.label.split('|')\n        return t(\n          key[0],\n          key && key[1]\n            ? {\n                arg: key[1].toString(),\n                l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n              }\n            : {\n                l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n              },\n        )\n      } else {\n        return t(`labelDualModifyBtn`, {\n          l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n          loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n          l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n          l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n          ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n        })\n      }\n    }, [editDualBtnInfo.label])\n\n    const _cancelReInvest = (item) => {\n      setShowCancelOndAlert({ open: true, row: item })\n    }\n    const nanToEmptyTag = (value: any, prefix: string) => {\n      return value === 'NaN' ? EmptyValueTag : prefix + value\n    }\n    const vaultAccountInfo = useVaultAccountInfo()\n    const {\n      onActionBtnClick,\n      dialogBtn,\n      showNoVaultAccount,\n      setShowNoVaultAccount,\n      whichBtn,\n      btnProps,\n      onBtnClose,\n      positionOpend,\n      onClcikOpenPosition,\n      totalAsset: totalAssetVault,\n      ...assetPanelProps\n    } = useGetVaultAssets({ vaultAccountInfo: vaultAccountInfo })\n    const { tokenMap: vaultTokenMap } = useVaultMap()\n    const priceTag = PriceTag[CurrencyToTag[currency]]\n    const { vaultTickerMap } = useVaultTicker()\n    const showTaikoFarming = new Decimal(totalStaked).greaterThan('0') ? true : false\n    const taikoFarmingTotalStakedRaw = utils.formatUnits(\n      totalStaked,\n      tokenMap[stakedSymbol].decimals,\n    )\n    const taikoFarmingTotalStaked = numberFormatThousandthPlace(taikoFarmingTotalStakedRaw, {\n      fixed: tokenMap[stakedSymbol].precision,\n    })\n    const taikoFarmingTotalStakedDollarRaw = \n      new Decimal(taikoFarmingTotalStakedRaw).times(tokenPrices[stakedSymbol] ?? 0).toString()\n    const taikoFarmingTotalStakedDollar = fiatNumberDisplay(\n      taikoFarmingTotalStakedDollarRaw,\n      currency,\n    )\n    const taikoFarmingInfo = new Decimal(taikoFarmingTotalStakedRaw).greaterThan('0')\n      ? {\n          amount: taikoFarmingTotalStaked,\n          value: taikoFarmingTotalStakedDollar,\n        }\n      : undefined\n    const defiTotalInUSD = sdk\n      .toBig(dualStakeDollar ?? 0)\n      .plus(totalAssetVault ?? 0)\n      .plus(taikoFarmingTotalStakedDollarRaw ?? 0)\n      .toString()\n    // @ts-ignore\n    const { marketProps } = useVaultMarket({ tableRef: undefined })\n    const showDual = dualList.length > 0\n    const showPortal = assetPanelProps.rawData.find((ele) => {\n      try {\n        return new Decimal(ele.amount).greaterThan('0')\n      } catch {\n        return false\n      }\n    })\n      ? true\n      : false\n    \n\n    const showEmptyHint =\n      !assetPanelProps.isLoading && !showDual && !showPortal && !dualLoading && !showTaikoFarming\n\n    return (\n      <Box display={'flex'} flex={1} position={'relative'} flexDirection={'column'}>\n        <MaxWidthContainer\n          marginBottom={3}\n          // minHeight={'80vh'}\n          background={isPortfolio ? undefined : containerColors[1]}\n          containerProps={{\n            borderRadius: isPortfolio ? `${theme.unit}px` : 0,\n            marginTop: 0,\n          }}\n          px={isPortfolio ? 0 : undefined}\n        >\n          <Typography marginY={3.5} color={'var(--color-text-third)'}>\n            {t('labelTotalBalance')}:{' '}\n            {hideAssets\n              ? HiddenTag\n              : nanToEmptyTag(\n                  sdk\n                    .toBig(defiTotalInUSD)\n                    .times(forexMap[currency] ?? 0)\n                    .toFixed(2, 1),\n                  PriceTag[CurrencyToTag[currency]],\n                )}\n          </Typography>\n          {showDual && (\n            <Box\n              sx={{\n                borderRadius: '8px',\n                border: '1px solid var(--color-border)',\n                padding: 4.5,\n              }}\n            >\n              <Box display={'flex'}>\n                <Box>\n                  <Typography variant='h4'>{t('labelInvestDualTitle')}</Typography>\n                  <Typography color={'var(--color-text-third)'}>\n                    {t('labelBalance')}:{' '}\n                    {hideAssets\n                      ? HiddenTag\n                      : dualStakeDollar && !Number.isNaN(dualStakeDollar)\n                      ? nanToEmptyTag(\n                          sdk\n                            .toBig(dualStakeDollar?.replaceAll(sdk.SEP))\n                            .times(forexMap[currency] ?? 0)\n                            .toFixed(2, 1),\n                          PriceTag[CurrencyToTag[currency]],\n                        )\n                      : EmptyValueTag}\n                  </Typography>\n                </Box>\n              </Box>\n              <TableWrapStyled\n                ref={dualRef}\n                className={`min-height`}\n                marginBottom={2}\n                paddingTop={1}\n                paddingX={0}\n                flex={1}\n                marginLeft={-3}\n              >\n                <Grid item xs={12} display={'flex'} flexDirection={'column'} flex={1} margin={0}>\n                  <DualAssetTable\n                    rawData={dualList}\n                    getDetail={getDetail}\n                    idIndex={idIndex}\n                    dualMarketMap={dualMarketMap}\n                    tokenMap={tokenMap}\n                    showloading={dualLoading}\n                    pagination={pagination}\n                    getDualAssetList={getDualTxList}\n                    showDetail={showDetail}\n                    refresh={refresh}\n                    hideAssets={hideAssets}\n                    cancelReInvest={_cancelReInvest as any}\n                    getProduct={getProduct}\n                    rowConfig={RowEarnConfig}\n                    noMinHeight\n                  />\n                  <Modal\n                    open={dualOpen}\n                    onClose={(_e: any) => setDualOpen(false)}\n                    aria-labelledby='modal-modal-title'\n                    aria-describedby='modal-modal-description'\n                  >\n                    <SwitchPanelStyled width={'var(--modal-width)'}>\n                      <ModalCloseButton onClose={(_e: any) => setDualOpen(false)} t={t} />\n                      {dualDetail && dualDetail.dualViewInfo && (\n                        <Box\n                          flex={1}\n                          paddingY={2}\n                          width={'100%'}\n                          display={'flex'}\n                          flexDirection={'column'}\n                        >\n                          <DualDetail\n                            setShowAutoDefault={setShowAutoDefault}\n                            showAutoDefault={showAutoDefault}\n                            isOrder={true}\n                            btnConfirm={\n                              dualDetail.__raw__?.order?.dualReinvestInfo?.isRecursive && (\n                                <ButtonStyle\n                                  fullWidth\n                                  variant={'contained'}\n                                  size={'medium'}\n                                  color={'primary'}\n                                  onClick={() => {\n                                    onEditDualClick()\n                                  }}\n                                  loading={\n                                    editDualBtnStatus === TradeBtnStatus.LOADING ? 'true' : 'false'\n                                  }\n                                  disabled={\n                                    editDualBtnStatus === TradeBtnStatus.LOADING ||\n                                    editDualBtnStatus === TradeBtnStatus.DISABLED\n                                  }\n                                >\n                                  {label}\n                                </ButtonStyle>\n                              )\n                            }\n                            dualProducts={dualProducts}\n                            dualViewInfo={dualDetail.dualViewInfo as DualViewBase}\n                            currentPrice={dualDetail.dualViewInfo.currentPrice}\n                            isPriceEditable={true}\n                            toggle={{ enable: true }}\n                            lessEarnTokenSymbol={dualDetail.lessEarnTokenSymbol}\n                            greaterEarnTokenSymbol={dualDetail.greaterEarnTokenSymbol}\n                            lessEarnView={dualDetail.lessEarnView}\n                            greaterEarnView={dualDetail.greaterEarnView}\n                            onChange={(item) => {\n                              handleOnchange({ tradeData: item })\n                            }}\n                            onChangeOrderReinvest={(info, item) => {\n                              if (info.on) {\n                                handleOnchange({\n                                  tradeData: {\n                                    ...item,\n                                    isRenew: info.on,\n                                    renewTargetPrice: info.renewTargetPrice,\n                                    renewDuration: info.renewDuration,\n                                  } as any,\n                                })\n                                onEditDualClick({ dontCloseModal: false })\n                              } else {\n                                handleOnchange({\n                                  tradeData: {\n                                    ...item,\n                                    isRenew: false,\n                                  } as any,\n                                })\n                                onEditDualClick({ dontCloseModal: false })\n                              }\n                            }}\n                            coinSell={{\n                              ...editDualTrade,\n                            }}\n                          />\n                        </Box>\n                      )}\n                    </SwitchPanelStyled>\n                  </Modal>\n                </Grid>\n              </TableWrapStyled>\n            </Box>\n          )}\n          {showPortal && (\n            <Box\n              sx={{\n                borderRadius: '8px',\n                border: '1px solid var(--color-border)',\n                padding: 4.5,\n                marginTop: 4,\n              }}\n            >\n              <Box marginBottom={2} display={'flex'}>\n                <Box>\n                  <Typography variant='h4'>Portal</Typography>\n                  <Typography color={'var(--color-text-third)'}>\n                    Balance:{' '}\n                    {totalAssetVault && !sdk.toBig(totalAssetVault ?? 0).eq('0')\n                      ? `${nanToEmptyTag(\n                          getValuePrecisionThousand(\n                            sdk.toBig(totalAssetVault ?? 0).times(forexMap[currency] ?? 0),\n                            2,\n                            2,\n                            2,\n                            true,\n                            { floor: true },\n                          ),\n                          priceTag,\n                        )}`\n                      : EmptyValueTag}{' '}\n                  </Typography>\n                </Box>\n              </Box>\n              <Box marginLeft={-2.5}>\n                <VaultAssetsTable\n                  {...assetPanelProps}\n                  onRowClick={(index, row) => {\n                    // @ts-ignore\n                    marketProps.onRowClick(index, {\n                      // @ts-ignore\n                      ...vaultTokenMap[row.name],\n                      // @ts-ignore\n                      cmcTokenId: vaultTickerMap[row.erc20Symbol].tokenId,\n                      ...vaultTickerMap[row.erc20Symbol],\n                    })\n                  }}\n                  showFilter\n                  hideActions\n                  noMinHeight\n                  hideDustCollector\n                />\n              </Box>\n            </Box>\n          )}\n          {showTaikoFarming && (\n            <Box\n              sx={{\n                borderRadius: '8px',\n                border: '1px solid var(--color-border)',\n                padding: 4.5,\n                marginTop: 4,\n              }}\n            >\n              <Box>\n                <Typography variant={'h4'}>{t('labelInvestType_TAIKOFarming')}</Typography>\n                <Typography color={'var(--color-text-third)'}>\n                  {t(\"labelBalance\")}:{' '}\n                  {hideAssets\n                    ? HiddenTag\n                    : taikoFarmingInfo\n                    ? taikoFarmingInfo.value\n                    : EmptyValueTag}\n                </Typography>\n              </Box>\n              <Box ml={-3}>\n                <TaikoFarmingPortfolioTable\n                  rawData={\n                    taikoFarmingInfo\n                      ? [\n                          {\n                            tokenSymbol: stakedSymbol,\n                            amount: taikoFarmingInfo.amount,\n                            value: taikoFarmingInfo.value,\n                            coinJSON: coinJson[stakedSymbol],\n                          },\n                        ]\n                      : []\n                  }\n                  idIndex={idIndex}\n                  tokenMap={tokenMap}\n                  getStakingList={getStakingList}\n                  isLoading={stakeShowLoading}\n                  hideAssets={hideAssets}\n                  noMinHeight\n                  hideDustCollector\n                />\n              </Box>\n            </Box>\n          )}\n          {showEmptyHint && (\n            <Box\n              flex={1}\n              display={'flex'}\n              alignItems={'center'}\n              justifyContent={'center'}\n              flexDirection={'column'}\n            >\n              <EmptyDefault\n                height={'calc(100% - 35px)'}\n                marginTop={10}\n                display={'flex'}\n                flexWrap={'nowrap'}\n                alignItems={'center'}\n                justifyContent={'center'}\n                flexDirection={'column'}\n                message={() => {\n                  return <Trans i18nKey='labelEmptyDefault'>Content is Empty</Trans>\n                }}\n              />\n            </Box>\n          )}\n        </MaxWidthContainer>\n        <Modal\n          open={showRefreshError}\n          onClose={(_e: any) => setShowRefreshError(false)}\n          aria-labelledby='modal-modal-title'\n          aria-describedby='modal-modal-description'\n        >\n          <SwitchPanelStyled width={'var(--modal-width)'}>\n            <ModalCloseButton onClose={(_e: any) => setShowRefreshError(false)} t={t} />\n            <Box marginTop={9}>\n              <FailedIcon color={'error'} style={{ width: 60, height: 60 }} />\n            </Box>\n\n            <Typography marginTop={1} variant={'h5'}>\n              {t('labelInvestDualRefreshErrorTitle')}\n            </Typography>\n            <Typography marginTop={5} marginBottom={22}>\n              {t('labelInvestDualRefreshError', {\n                token1: refreshErrorInfo[0],\n                token2: refreshErrorInfo[1],\n              })}\n            </Typography>\n          </SwitchPanelStyled>\n        </Modal>\n        <CancelDualAlert\n          open={showCancelOneAlert.open}\n          row={showCancelOneAlert.row}\n          handleCancelOne={async () => await cancelReInvest(showCancelOneAlert.row)}\n          handleClose={() => setShowCancelOndAlert({ open: false, row: undefined })}\n        />\n        <Toast\n          alertText={dualToastOpen?.content ?? ''}\n          severity={dualToastOpen?.type ?? ToastType.success}\n          open={dualToastOpen?.open ?? false}\n          autoHideDuration={TOAST_TIME}\n          onClose={() => {\n            if (closeDualToast) {\n              closeDualToast()\n            }\n          }}\n        />\n      </Box>\n    )\n  },\n)\n\nexport default MyLiquidity\n"
  },
  {
    "path": "packages/web-earn/src/pages/InvestPage/MyLiquidityPanel/interface.ts",
    "content": ""
  },
  {
    "path": "packages/web-earn/src/pages/InvestPage/OverviewPanel/hook.ts",
    "content": "import { makeInvestRow, useInvestTokenTypeMap, useWalletLayer2 } from '@loopring-web/core'\nimport { RowInvest } from '@loopring-web/component-lib'\nimport { SagaStatus } from '@loopring-web/common-resources'\nimport React from 'react'\n\nexport function useOverview<R extends RowInvest>() {\n  const { investTokenTypeMap, status: investTokenTypeMapStatus } = useInvestTokenTypeMap()\n\n  const { status: walletLayer2Status, walletLayer2 } = useWalletLayer2()\n  const [filterValue, setFilterValue] = React.useState<string>('')\n  const [rawData, setRawData] = React.useState<R[]>([])\n  const [filteredData, setFilteredData] = React.useState<R[]>(rawData)\n  const [myMapLoading, setMyMapLoading] = React.useState(false)\n\n  const [myRawData, setMyRawData] = React.useState<R[]>([])\n  const filterData = (rawData: R[], value: string) => {\n    return rawData.filter((item) => {\n      const regx = new RegExp(value.toLowerCase(), 'ig')\n      return regx.test(item?.token?.symbol ?? '')\n    })\n  }\n  const getFilteredData = React.useCallback(\n    (value: string) => {\n      setFilterValue(value)\n      if (value) {\n        const _rawData = [...filterData(rawData, value)]\n        setFilteredData(_rawData)\n      } else {\n        setFilteredData(rawData)\n      }\n    },\n    [filterData, myRawData, rawData, walletLayer2],\n  )\n\n  React.useEffect(() => {\n    if (investTokenTypeMapStatus === SagaStatus.UNSET) {\n      const _rawData = investTokenTypeMap\n        ? Object.keys(investTokenTypeMap)\n            .reduce((prev, key) => {\n              prev.push(makeInvestRow(investTokenTypeMap, key) as R)\n              return prev\n            }, [] as R[])\n            .sort((a, b) => {\n              return b.apr[1] - a.apr[1]\n            })\n        : []\n      setRawData(_rawData)\n      setFilteredData(\n        _rawData.filter((a) => {\n          return !!a.apr[1]\n        }),\n      )\n    }\n  }, [investTokenTypeMapStatus, investTokenTypeMap])\n  const getMyInvestTokenMap = React.useCallback(() => {\n    if (walletLayer2 && Reflect.ownKeys(walletLayer2 ?? {}).length > 0) {\n      const _rawData = Object.keys(walletLayer2)\n        .reduce((prev, key) => {\n          if (investTokenTypeMap && investTokenTypeMap[key]) {\n            prev.push(makeInvestRow(investTokenTypeMap, key) as R)\n          }\n          return prev\n        }, [] as R[])\n        .sort((a, b) => {\n          return b.apr[1] - a.apr[1]\n        })\n      setMyRawData(_rawData)\n    } else {\n      setMyRawData([])\n    }\n    setMyMapLoading(false)\n  }, [walletLayer2, investTokenTypeMap])\n  React.useEffect(() => {\n    if (walletLayer2Status === 'UNSET' && investTokenTypeMapStatus === 'UNSET') {\n      setMyMapLoading(true)\n      getMyInvestTokenMap()\n    }\n  }, [walletLayer2Status, investTokenTypeMapStatus])\n  return {\n    filteredData,\n    filterValue,\n    getFilteredData,\n    myRawData,\n    // myFilteredData,\n    myMapLoading,\n    rawData,\n  }\n}\n"
  },
  {
    "path": "packages/web-earn/src/pages/InvestPage/OverviewPanel/index.tsx",
    "content": "import { WithTranslation, withTranslation } from 'react-i18next'\nimport { Avatar, Box, Card, CardContent, IconButton, Link, Typography } from '@mui/material'\nimport styled from '@emotion/styled'\n\nimport React from 'react'\nimport { useOverview } from './hook'\n\nimport { Button, useSettings, InvestOverviewTable, useToggle } from '@loopring-web/component-lib'\nimport { useHistory } from 'react-router-dom'\nimport {\n  BackIcon,\n  ammAdvice,\n  defiAdvice,\n  RowInvestConfig,\n  dualAdvice,\n  stakeAdvice,\n  leverageETHAdvice,\n  Overview,\n  getValuePrecisionThousand,\n  EmptyValueTag,\n} from '@loopring-web/common-resources'\nimport {\n  useAccount,\n  useAmmMap,\n  useDefiMap,\n  useDualMap,\n  useNotify,\n  useStakingMap,\n} from '@loopring-web/core'\nimport { useTheme } from '@emotion/react'\nimport { MaxWidthContainer, containerColors } from '..'\nimport _ from 'lodash'\n\nconst WrapperStyled = styled(Box)`\n  flex: 1;\n  display: flex;\n  flex-direction: column;\n  /* background: var(--dark700); */\n  border-radius: ${({ theme }) => theme.unit}px;\n  width: 100%;\n  overflow: hidden;\n  .MuiCard-root {\n    padding: ${({ theme }) => 4 * theme.unit}px;\n    padding-top: ${({ theme }) => 6 * theme.unit}px;\n    cursor: pointer;\n    background: var(--dark700);\n    border: 1px solid;\n    border-color: var(--color-border);\n    width: ${({ theme }) => 34 * theme.unit}px;\n    .MuiCardContent-root {\n      padding: 0;\n    }\n    box-shadow: none;\n    .hover-button {\n      background: var(--color-button-inactive);\n      color: var(--color-text-primary);\n    }\n    :hover {\n      /* background: var(--color-box-hover); */\n      box-shadow: var(--color-shadow);\n      .hover-button {\n        color: var(--color-text-button);\n        background: var(--color-primary);\n      }\n    }\n  }\n\n  .scroll-view::-webkit-scrollbar {\n    display: none;\n  }\n  @media only screen and (max-width: 768px) {\n    .MuiCard-root {\n      width: 100%;\n      margin-bottom: 12px;\n    }\n  }\n`\n\nconst getAprRange = (list: number[]) => {\n  const aprs = list.sort((a, b) => a - b)\n  return (\n    aprs.length > 0 && {\n      from: aprs[0],\n      to: aprs[aprs.length - 1],\n    }\n  )\n}\n\nexport const OverviewPanel = withTranslation('common')(({ t }: WithTranslation & {}) => {\n  const { filteredData, filterValue, getFilteredData, rawData, myMapLoading, myRawData } =\n    useOverview()\n  const { coinJson, isMobile } = useSettings()\n  const { account } = useAccount()\n  const { notifyMap } = useNotify()\n  const { ammMap } = useAmmMap()\n  const { marketMap, marketLeverageMap } = useDefiMap()\n  const { marketMap: dualMarketMap } = useDualMap()\n  const { marketMap: LRCMarketMap } = useStakingMap()\n\n  const ammApr = React.useMemo(() => {\n    return getAprRange(\n      _.values(ammMap)\n        .filter((amm) => amm && amm.APR)\n        .map((amm) => amm.APR!),\n    )\n  }, [ammMap])\n  const defiApr = React.useMemo(() => {\n    return getAprRange(\n      _.values(marketMap)\n        .filter((defi) => defi && defi.apy)\n        .map((defi) => Number(defi.apy)),\n    )\n  }, [marketMap])\n  const dualApr = React.useMemo(() => {\n    return getAprRange(\n      _.values(dualMarketMap)\n        .flatMap((dual: any) => [\n          dual.baseTokenApy?.max as string,\n          dual.baseTokenApy?.min as string,\n        ])\n        .filter((apy) => apy)\n        .map((apy) => Number(apy) * 100),\n    )\n  }, [dualMarketMap])\n  const lrcApr = React.useMemo(() => {\n    return getAprRange(\n      _.values(LRCMarketMap)\n        .filter((lrc) => lrc.apr)\n        .map((lrc) => Number(lrc.apr)),\n    )\n  }, [LRCMarketMap])\n  const leverageApr = React.useMemo(() => {\n    return getAprRange(\n      _.values(marketLeverageMap)\n        .filter((leverage) => leverage.apy)\n        .map((leverage) => Number(leverage.apy)),\n    )\n  }, [marketLeverageMap])\n\n  const showLoading = filteredData && !filteredData.length\n  const history = useHistory()\n  const {\n    toggle: { CIETHInvest },\n  } = useToggle()\n  const investAdviceList = [\n    { ...dualAdvice, ...notifyMap?.invest?.investAdvice[2], apyRange: dualApr },\n    { ...defiAdvice, ...notifyMap?.invest?.investAdvice[1], apyRange: defiApr },\n    { ...leverageETHAdvice, ...notifyMap?.invest?.investAdvice[4], apyRange: leverageApr },\n    { ...ammAdvice, ...notifyMap?.invest?.investAdvice[0], apyRange: ammApr },\n    { ...stakeAdvice, ...notifyMap?.invest?.investAdvice[3], apyRange: lrcApr },\n  ]\n  const theme = useTheme()\n  const scrollViewRef = React.useRef()\n  const [showArrow, setShowArrow] = React.useState({ left: false, right: true })\n\n  return (\n    <>\n      <WrapperStyled>\n        <MaxWidthContainer\n          display={'flex'}\n          justifyContent={'space-between'}\n          background={containerColors[0]}\n          height={isMobile ? 60 * theme.unit : 30 * theme.unit}\n          alignItems={'center'}\n        >\n          <Box paddingY={7}>\n            <Typography\n              color={'var(--color-text-primary)'}\n              marginBottom={2}\n              fontSize={'38px'}\n              variant={'h1'}\n            >\n              {t('labelInvestLoopringEarn')}\n            </Typography>\n            <Typography marginBottom={3} color={'var(--color-text-secondary)'} variant={'h4'}>\n              {t('labelInvestLoopringEarnDes')}\n            </Typography>\n            <Button\n              onClick={() => history.push('/invest/balance')}\n              sx={{ width: isMobile ? 36 * theme.unit : 18 * theme.unit }}\n              variant={'contained'}\n            >\n              {t('labelAssetInvests')}\n            </Button>\n          </Box>\n          <Box marginRight={5}>{!isMobile && <Overview />}</Box>\n        </MaxWidthContainer>\n        <MaxWidthContainer marginTop={5} minHeight={'80vh'} background={containerColors[1]}>\n          <Box position={'relative'}>\n            <Box\n              component='div'\n              onScroll={(event) => {\n                if (\n                  event.currentTarget.scrollLeft + event.currentTarget.offsetWidth ===\n                  event.currentTarget.scrollWidth\n                ) {\n                  setShowArrow({\n                    left: true,\n                    right: false,\n                  })\n                } else if (event.currentTarget.scrollLeft === 0) {\n                  setShowArrow({\n                    left: false,\n                    right: true,\n                  })\n                } else {\n                  setShowArrow({\n                    left: true,\n                    right: true,\n                  })\n                }\n              }}\n              sx={{\n                width: '100%',\n                overflowX: 'scroll',\n                maxWidth: 'lg',\n                paddingY: 3,\n                scrollBehavior: 'smooth',\n              }}\n              className={'scroll-view'}\n              ref={scrollViewRef}\n            >\n              <Box\n                sx={{\n                  display: 'flex',\n                  width: isMobile ? '100%' : 'fit-content',\n                  flexDirection: isMobile ? 'column' : 'row',\n                }}\n              >\n                {investAdviceList.map((item, index) => {\n                  return (\n                    <Card\n                      key={item.type}\n                      onClick={() => history.push(item.router)}\n                      sx={{ marginRight: 2.5 }}\n                    >\n                      <CardContent>\n                        <Box display={'flex'} flexDirection={'column'} alignItems={'center'}>\n                          <Avatar\n                            variant='circular'\n                            style={{\n                              height: 'var(--svg-size-huge)',\n                              width: 'var(--svg-size-huge)',\n                            }}\n                            src={item.banner}\n                          />\n                          <Typography marginTop={0.5} variant={'h5'}>\n                            {t(item.titleI18n, { ns: 'layout' })}\n                          </Typography>\n\n                          <Typography variant={'h3'} marginTop={5}>\n                            {item.apyRange\n                              ? item.apyRange.from === item.apyRange.to\n                                ? `${getValuePrecisionThousand(\n                                    item.apyRange.from,\n                                    undefined,\n                                    2,\n                                    2,\n                                  )}%`\n                                : `${getValuePrecisionThousand(\n                                    item.apyRange.from,\n                                    undefined,\n                                    2,\n                                    2,\n                                  )}%-${getValuePrecisionThousand(\n                                    item.apyRange.to,\n                                    undefined,\n                                    2,\n                                    2,\n                                  )}%`\n                              : EmptyValueTag}\n                          </Typography>\n                          <Typography>{t('labelAPR')}</Typography>\n                          <Button\n                            className={'hover-button'}\n                            sx={{ marginTop: 2 }}\n                            fullWidth\n                            variant={'contained'}\n                          >\n                            {t('labelLiquidityDeposit')}\n                          </Button>\n                        </Box>\n                      </CardContent>\n                    </Card>\n                  )\n                })}\n              </Box>\n            </Box>\n            {showArrow.left && (\n              <IconButton\n                size={'large'}\n                sx={{\n                  position: 'absolute',\n                  transform: 'translateY(-50%)',\n                  top: '50%',\n                  left: -30,\n                }}\n                onClick={() => {\n                  ;(scrollViewRef.current as any).scrollTo(0, 0)\n                }}\n              >\n                <BackIcon />\n              </IconButton>\n            )}\n            {showArrow.right && (\n              <IconButton\n                size={'large'}\n                sx={{\n                  position: 'absolute',\n                  transform: 'rotate(180deg) translateY(50%)',\n                  top: '50%',\n                  right: -30,\n                }}\n                onClick={() => {\n                  ;(scrollViewRef.current as any).scrollTo(1000, 0)\n                }}\n              >\n                <BackIcon />\n              </IconButton>\n            )}\n          </Box>\n\n          <Box marginTop={5} display={'flex'} flex={1} marginBottom={1} flexDirection={'column'}>\n            <InvestOverviewTable\n              showLoading={showLoading}\n              showFilter={true}\n              filterValue={filterValue}\n              getFilteredData={getFilteredData}\n              coinJson={coinJson}\n              rawData={filteredData}\n              rowConfig={RowInvestConfig}\n            />\n            {rawData.length !== filteredData.length && (\n              <Link\n                variant={'body1'}\n                marginY={1}\n                textAlign={'center'}\n                display={'inline-flex'}\n                justifyContent={'center'}\n                onClick={() => {\n                  getFilteredData('')\n                }}\n              >\n                {t('labelViewMore')}\n              </Link>\n            )}\n          </Box>\n        </MaxWidthContainer>\n      </WrapperStyled>\n    </>\n  )\n})\n"
  },
  {
    "path": "packages/web-earn/src/pages/InvestPage/PoolsPanel/hook.ts",
    "content": "import React from 'react'\nimport { SagaStatus, AmmPanelType } from '@loopring-web/common-resources'\n\nimport { store, useAmmMap, useSystem } from '@loopring-web/core'\n\nimport { useLocation } from 'react-router-dom'\nimport { AccountStep, PoolRow, useOpenModals } from '@loopring-web/component-lib'\nimport { useTranslation } from 'react-i18next'\nimport _ from 'lodash'\n\n// type Row<R> = AmmDetail<R> & { tradeFloat: TradeFloat };\n\nexport function useAmmMapUI<R extends PoolRow<any>, I extends { [key: string]: any }>() {\n  const location = useLocation()\n  const { t } = useTranslation()\n  const {\n    setShowAmm,\n    setShowTradeIsFrozen,\n    setShowAccount,\n    // modals: { isShowAmm, isShowTradeIsFrozen },\n  } = useOpenModals()\n  const searchParams = new URLSearchParams(location.search)\n  const [showLoading, setShowLoading] = React.useState(true)\n  const [filteredData, setFilteredData] = React.useState<R[]>([])\n  // const { status: tokenMapStatus } = useTokenMap();\n  const { status: ammStatus } = useAmmMap()\n  const { allowTrade } = useSystem()\n  const nodeTimer = React.useRef<NodeJS.Timeout | -1>(-1)\n  const nodePopTimer = React.useRef<NodeJS.Timeout | -1>(-1)\n\n  const getFilteredData = (_value?: string) => {\n    const value = _value ? _value : searchParams.get('search')\n    if (nodeTimer.current !== -1) {\n      clearTimeout(nodeTimer.current as NodeJS.Timeout)\n    }\n    setShowLoading(false)\n    const { ammArrayEnable } = store.getState().amm.ammMap\n    let rawData = _.cloneDeep(ammArrayEnable) as unknown as R[]\n    if (value && value.trim() !== '') {\n      rawData = ammArrayEnable.reduce((prev, ammInfo) => {\n        if (\n          value &&\n          ([ammInfo.coinA].includes(value.toUpperCase()) ||\n            [ammInfo.coinB].includes(value.toUpperCase()))\n        ) {\n          prev.push({\n            ...ammInfo,\n          } as unknown as R)\n        }\n        return prev\n      }, [] as R[])\n    }\n\n    setFilteredData(rawData)\n\n    nodeTimer.current = setTimeout(() => {\n      getFilteredData()\n    }, 60000)\n  }\n\n  const handleWithdraw = React.useCallback((row: R) => {\n    setShowAccount({ isShow: true, step: AccountStep.AMM_Pending })\n    if (nodePopTimer.current !== -1) {\n      clearTimeout(nodePopTimer.current as NodeJS.Timeout)\n    }\n    nodePopTimer.current = _.delay(() => {\n      setShowAmm({\n        isShow: true,\n        type: AmmPanelType.Exit,\n        symbol: row.market,\n      })\n    }, 10) as any\n  }, [])\n  const handleDeposit = React.useCallback((row: R) => {\n    if (allowTrade.joinAmm) {\n      setShowAccount({ isShow: true, step: AccountStep.AMM_Pending })\n\n      nodePopTimer.current = _.delay(() => {\n        setShowAmm({\n          isShow: true,\n          type: AmmPanelType.Join,\n          symbol: row.market,\n        })\n      }, 10) as any\n    } else {\n      setShowTradeIsFrozen({\n        isShow: true,\n        type: t('labelAmmJoin') + ` ${row?.market}`,\n      })\n    }\n  }, [])\n  React.useEffect(() => {\n    if (ammStatus === SagaStatus.UNSET) {\n      getFilteredData()\n    }\n    return () => {\n      clearTimeout(nodeTimer.current as NodeJS.Timeout)\n      clearTimeout(nodePopTimer.current as NodeJS.Timeout)\n    }\n  }, [ammStatus])\n\n  return {\n    rawData: filteredData,\n    filterValue: searchParams.get('search') ?? '',\n    showLoading,\n    getFilteredData,\n    handleWithdraw,\n    handleDeposit,\n  }\n}\n"
  },
  {
    "path": "packages/web-earn/src/pages/InvestPage/PoolsPanel/index.tsx",
    "content": "import { WithTranslation, withTranslation } from 'react-i18next'\nimport { Box, Typography } from '@mui/material'\nimport styled from '@emotion/styled'\n\nimport React from 'react'\nimport { useAmmMapUI } from './hook'\n\nimport { Button, PoolsTable, useSettings } from '@loopring-web/component-lib'\n\nimport { useNotify, useSystem } from '@loopring-web/core'\nimport { AmmLogo, BackIcon, RowInvestConfig } from '@loopring-web/common-resources'\nimport { useHistory } from 'react-router-dom'\nimport { MaxWidthContainer, containerColors } from '..'\nimport { useTheme } from '@emotion/react'\nimport { SoursURL } from '@loopring-web/loopring-sdk'\n\nconst WrapperStyled = styled(Box)`\n  flex: 1;\n  display: flex;\n  flex-direction: column;\n  background: var(--color-box);\n  border-radius: ${({ theme }) => theme.unit}px;\n`\n\nconst StylePaper = styled(Box)`\n  width: 100%;\n  //height: 100%;\n  flex: 1;\n  padding-bottom: ${({ theme }) => theme.unit}px;\n\n  .rdg {\n    flex: 1;\n  }\n` as typeof Box\n\nexport const PoolsPanel = withTranslation('common')(\n  <R extends { [key: string]: any }, I extends { [key: string]: any }>({\n    t,\n  }: WithTranslation & {}) => {\n    const container = React.useRef(null)\n    const history = useHistory()\n    const { forexMap } = useSystem()\n    const { currency, isMobile } = useSettings()\n    const poolTableProps = useAmmMapUI()\n    const { campaignTagConfig } = useNotify().notifyMap ?? {}\n    const theme = useTheme()\n    return (\n      <Box display={'flex'} flexDirection={'column'} flex={1}>\n        <MaxWidthContainer\n          display={'flex'}\n          justifyContent={'space-between'}\n          background={containerColors[0]}\n          height={isMobile ? 50 * theme.unit : 30 * theme.unit}\n          alignItems={'center'}\n        >\n          <Box paddingY={7}>\n            <Typography fontSize={'38px'} variant={'h1'}>\n              {t(\"labelLiquidityPageTitle\")}\n            </Typography>\n          </Box>\n          {!isMobile && <AmmLogo />}\n        </MaxWidthContainer>\n        <MaxWidthContainer minHeight={'70vh'} background={containerColors[1]}>\n          <PoolsTable\n            {...{\n              ...poolTableProps,\n              campaignTagConfig,\n              rowConfig: RowInvestConfig,\n              forexValue: forexMap[currency],\n            }}\n          />\n        </MaxWidthContainer>\n      </Box>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/web-earn/src/pages/InvestPage/index.tsx",
    "content": "import { useRouteMatch } from 'react-router-dom'\n\nimport { Box, BoxProps, Modal, Typography } from '@mui/material'\n\nimport { useTranslation, withTranslation } from 'react-i18next'\nimport {\n  ComingSoonPanel,\n  ConfirmInvestLRCStakeRisk,\n  ModalCloseButton,\n  ModifySetting,\n  SwitchPanelStyled,\n  useToggle,\n} from '@loopring-web/component-lib'\nimport React from 'react'\nimport { confirmation, ViewAccountTemplate } from '@loopring-web/core'\nimport MyLiquidityPanel from './MyLiquidityPanel'\nimport { PoolsPanel } from './PoolsPanel'\nimport { DeFiPanel } from './DeFiPanel'\nimport { OverviewPanel } from './OverviewPanel'\nimport { DualListPanel } from './DualPanel/DualListPanel'\nimport LeverageETHPanel from './LeverageETHPanel'\nimport styled from '@emotion/styled'\nimport { TaikoLockPage } from 'pages/TaikoLockPage'\n\nexport enum InvestType {\n  MyBalance = 0,\n  AmmPool = 1,\n  DeFi = 2,\n  Overview = 3,\n  Dual = 4,\n  Stack = 5,\n  LeverageETH = 6,\n}\nexport const containerColors = ['var(--color-global-bg)', 'var(--color-pop-bg)']\nconst BoxStyled = styled(Box)`\n  display: flex;\n  justify-content: center;\n  @media only screen and (max-width: 1200px) {\n    .inner-box {\n      width: 100%;\n    }\n  }\n`\nexport const MaxWidthContainer = (\n  props: {\n    children: React.ReactNode\n    background?: string\n    containerProps?: BoxProps\n  } & BoxProps,\n) => {\n  const { containerProps, children, background, sx, ...otherProps } = props\n  return (\n    <BoxStyled sx={{ background, ...containerProps?.sx }} {...containerProps}>\n      <Box\n        sx={{\n          width: '1200px',\n          maxWidth: '100%',\n          ...sx,\n        }}\n        className={'inner-box'}\n        paddingX={3}\n        {...otherProps}\n      >\n        {children}\n      </Box>\n    </BoxStyled>\n  )\n}\nexport const InvestRouter = [\n  'balance',\n  'ammpool',\n  'defi',\n  'overview',\n  'dual',\n  'stakelrc',\n  'leverageETH',\n]\nexport const BalanceTitle = () => {\n  const { t } = useTranslation()\n  return (\n    <Typography display={'inline-flex'} alignItems={'center'}>\n      <Typography\n        component={'span'}\n        variant={'h5'}\n        whiteSpace={'pre'}\n        marginRight={1}\n        className={'invest-Balance-Title'}\n      >\n        {t('labelInvestBalanceTitle')}\n      </Typography>\n    </Typography>\n  )\n}\nexport const OverviewTitle = () => {\n  const { t } = useTranslation()\n  return (\n    <Typography display={'inline-flex'} alignItems={'center'}>\n      <Typography\n        component={'span'}\n        variant={'h5'}\n        whiteSpace={'pre'}\n        marginRight={1}\n        className={'invest-Overview-Title'}\n      >\n        {t('labelInvestOverviewTitle')}\n      </Typography>\n    </Typography>\n  )\n}\nexport const AmmTitle = () => {\n  const { t } = useTranslation()\n  return (\n    <Typography display={'inline-flex'} alignItems={'center'}>\n      <Typography\n        component={'span'}\n        variant={'h5'}\n        whiteSpace={'pre'}\n        marginRight={1}\n        className={'invest-Amm-Title'}\n      >\n        {t('labelInvestAmmTitle')}\n      </Typography>\n    </Typography>\n  )\n}\n\nexport const DefiTitle = () => {\n  const { t } = useTranslation()\n\n  return (\n    <Typography display={'inline-flex'} alignItems={'center'}>\n      <Typography\n        component={'span'}\n        variant={'h5'}\n        whiteSpace={'pre'}\n        marginRight={1}\n        className={'invest-defi-Title'}\n      >\n        {t('labelInvestDefiTitle')}\n      </Typography>\n    </Typography>\n  )\n}\n\nexport const InvestPage = withTranslation('common', { withRef: true })(() => {\n  let match: any = useRouteMatch('/invest/:item?')\n  const {\n    confirmation: {\n      confirmationNeeded,\n      showLRCStakePopup: confirmedLRCStakeInvest,\n      showAutoDefault,\n    },\n    confirmedLRCStakeInvest: confirmedLRCInvestFun,\n    setShowAutoDefault,\n    setShowLRCStakePopup: setConfirmedLRCStakeInvestInvest,\n  } = confirmation.useConfirmation()\n  const {\n    toggle: { CIETHInvest },\n  } = useToggle()\n  const { t } = useTranslation()\n  const [tabIndex, setTabIndex] = React.useState<InvestType>(\n    (InvestRouter.includes(match?.params?.item)\n      ? InvestType[match?.params?.item]\n      : InvestType.Overview) as any,\n    // InvestType.Overview\n  )\n  const [isShowTab, setIsShowTab] = React.useState<Boolean>(false)\n  React.useEffect(() => {\n    switch (match?.params.item) {\n      case InvestRouter[InvestType.MyBalance]:\n        setTabIndex(InvestType.MyBalance)\n        setIsShowTab(true)\n        return\n      // return ;\n      case InvestRouter[InvestType.AmmPool]:\n        setTabIndex(InvestType.AmmPool)\n        setIsShowTab(false)\n        return\n      case InvestRouter[InvestType.DeFi]:\n        setTabIndex(InvestType.DeFi)\n        setIsShowTab(false)\n        return\n      case InvestRouter[InvestType.Dual]:\n        setTabIndex(InvestType.Dual)\n        setIsShowTab(false)\n        return\n      case InvestRouter[InvestType.Stack]:\n        setTabIndex(InvestType.Stack)\n        setIsShowTab(false)\n        return\n      case InvestRouter[InvestType.LeverageETH]:\n        setTabIndex(InvestType.LeverageETH)\n        setIsShowTab(false)\n        return\n      case InvestRouter[InvestType.Overview]:\n      default:\n        setTabIndex(InvestType.Overview)\n        setIsShowTab(true)\n        return\n    }\n  }, [match?.params?.item])\n\n  return (\n    <Box flex={1} flexDirection={'column'} display={'flex'}>\n      <Box flex={1} component={'section'} display={'flex'}>\n        {tabIndex === InvestType.Overview && <OverviewPanel />}\n        {tabIndex === InvestType.AmmPool && <PoolsPanel />}\n        {tabIndex === InvestType.DeFi && <DeFiPanel />}\n        {tabIndex === InvestType.Dual && <DualListPanel />}\n        {tabIndex === InvestType.MyBalance && (\n          <Box flex={1} alignItems={'stretch'} display={'flex'} flexDirection={'column'}>\n            <ViewAccountTemplate activeViewTemplate={<MyLiquidityPanel />} />\n          </Box>\n        )}\n        {tabIndex === InvestType.Stack && (\n          <TaikoLockPage symbol='TAIKO' setConfirmedLRCStakeInvestInvest={setConfirmedLRCStakeInvestInvest} />\n        )}\n        {tabIndex === InvestType.LeverageETH &&\n          (!CIETHInvest.enable && CIETHInvest.reason === 'no view' ? (\n            <ComingSoonPanel />\n          ) : (\n            <LeverageETHPanel />\n          ))}\n      </Box>\n      <ConfirmInvestLRCStakeRisk\n        open={confirmedLRCStakeInvest}\n        confirmationNeeded={confirmationNeeded}\n        handleClose={(_e, isAgree) => {\n          setConfirmedLRCStakeInvestInvest({ isShow: false, confirmationNeeded: false })\n          if (!isAgree) {\n            // history.goBack()\n          } else {\n            confirmedLRCInvestFun()\n          }\n        }}\n      />\n    </Box>\n  )\n})\n"
  },
  {
    "path": "packages/web-earn/src/pages/Layer2Page/ContactPanel/delete.tsx",
    "content": "import React from 'react'\nimport {\n  Box,\n  Button,\n  Dialog,\n  DialogActions,\n  DialogContent,\n  DialogTitle,\n  IconButton,\n  Typography,\n} from '@mui/material'\nimport { CloseIcon, LoadingIcon, Contact } from '@loopring-web/common-resources'\nimport { TextField } from '@loopring-web/component-lib'\nimport { useTheme } from '@emotion/react'\nimport { useTranslation } from 'react-i18next'\n\ninterface DeleteDialogProps {\n  deleteInfo: {\n    open: boolean\n    selected: Contact | undefined\n  }\n  onCloseDelete: () => void\n  submitDeleteContact: (address: string, name: string) => void\n  loading: boolean\n}\n\nexport const Delete: React.FC<DeleteDialogProps> = (props) => {\n  const { deleteInfo, onCloseDelete, submitDeleteContact, loading } = props\n\n  const theme = useTheme()\n  const { t } = useTranslation()\n\n  return (\n    <div>\n      <Dialog\n        open={deleteInfo.open}\n        onClose={() => {\n          onCloseDelete()\n        }}\n      >\n        <DialogTitle>\n          <Typography variant={'h3'} textAlign={'center'}>\n            {t('labelContactsDeleteContact')}\n          </Typography>\n          <IconButton\n            size={'medium'}\n            sx={{\n              position: 'absolute',\n              right: 8,\n              top: 8,\n            }}\n            color={'inherit'}\n            onClick={() => {\n              onCloseDelete()\n            }}\n          >\n            <CloseIcon />\n          </IconButton>\n        </DialogTitle>\n        <DialogContent style={{ width: 'var(--modal-width)' }}>\n          <Box marginBottom={12} marginTop={6}>\n            <TextField\n              label={t('labelDeleteContactInfo')}\n              style={{\n                backgroundColor: 'var(--box-card-decorate)',\n              }}\n              color={'primary'}\n              InputProps={{\n                style: {\n                  background: 'var(--field-opacity)',\n                  height: `${theme.unit * 6}px`,\n                },\n              }}\n              fullWidth\n              value={`${deleteInfo.selected?.name}\\/${deleteInfo.selected?.address}`}\n            />\n          </Box>\n        </DialogContent>\n        <DialogActions>\n          <Box width={'100%'} flexDirection={'column'} display={'flex'}>\n            <Button\n              variant='contained'\n              onClick={() => {\n                submitDeleteContact!(deleteInfo.selected!.address, deleteInfo.selected!.name)\n              }}\n              fullWidth\n            >\n              {loading ? <LoadingIcon></LoadingIcon> : t('labelContactsDeleteContactBtn')}\n            </Button>\n            <Box></Box>\n            <Button\n              variant={'outlined'}\n              style={{\n                border: 'none',\n                marginTop: `${theme.unit}px`,\n              }}\n              color={'info'}\n              onClick={() => {\n                onCloseDelete()\n              }}\n            >\n              {t('labelCancel')}\n            </Button>\n          </Box>\n        </DialogActions>\n      </Dialog>\n    </div>\n  )\n}\n"
  },
  {
    "path": "packages/web-earn/src/pages/Layer2Page/ContactPanel/history.tsx",
    "content": "import React from 'react'\nimport { Box } from '@mui/material'\nimport { Button, Toast, ToastType, TransactionTable } from '@loopring-web/component-lib'\nimport {\n  StylePaper,\n  useAccount,\n  useSystem,\n  useToast,\n  useTokenMap,\n  useContractRecord,\n} from '@loopring-web/core'\nimport { BackIcon, RowConfig, TOAST_TIME } from '@loopring-web/common-resources'\nimport { useHistory } from 'react-router-dom'\nimport { WithTranslation, withTranslation } from 'react-i18next'\n\nexport const ContactTransactionsPage = withTranslation('common')(\n  (rest: WithTranslation<'common'>) => {\n    const history = useHistory()\n\n    const [pageSize, setPageSize] = React.useState(0)\n\n    const { toastOpen, setToastOpen, closeToast } = useToast()\n    const { totalCoinMap } = useTokenMap()\n    const { etherscanBaseUrl } = useSystem()\n\n    const {\n      account: { accAddress, accountId },\n    } = useAccount()\n\n    const container = React.useRef<HTMLDivElement>(null)\n\n    React.useEffect(() => {\n      let height = container?.current?.offsetHeight\n      if (height) {\n        // const pageSize = Math.floor((height - 120) / RowConfig.rowHeight) - 3;\n        setPageSize(Math.floor((height - 120) / RowConfig.rowHeight) - 3)\n        // handleTabChange(currentTab, pageSize);\n      }\n    }, [container?.current?.offsetHeight])\n    const {\n      txs: txTableData,\n      txsTotal,\n      showLoading: showTxsLoading,\n      getUserTxnList,\n    } = useContractRecord(setToastOpen)\n\n    return (\n      <Box flex={1} display={'flex'} flexDirection={'column'}>\n        <Box marginBottom={2}>\n          <Button\n            startIcon={<BackIcon fontSize={'small'} />}\n            variant={'text'}\n            size={'medium'}\n            sx={{ color: 'var(--color-text-secondary)' }}\n            color={'inherit'}\n            onClick={history.goBack}\n          >\n            {rest.t('labelContacts')}\n          </Button>\n        </Box>\n        <StylePaper ref={container} flex={1}>\n          <Toast\n            alertText={toastOpen?.content ?? ''}\n            severity={toastOpen?.type ?? ToastType.success}\n            open={toastOpen?.open ?? false}\n            autoHideDuration={TOAST_TIME}\n            onClose={closeToast}\n          />\n          <Box\n            className='tableWrapper table-divide-short'\n            display={'flex'}\n            flex={1}\n            overflow={'scroll'}\n          >\n            <TransactionTable\n              {...{\n                etherscanBaseUrl,\n                rawData: txTableData,\n                pagination: {\n                  pageSize: pageSize,\n                  total: txsTotal,\n                },\n                filterTokens: totalCoinMap ? (Reflect.ownKeys(totalCoinMap) as string[]) : [],\n                showFilter: true,\n                showloading: showTxsLoading,\n                getTxnList: getUserTxnList,\n                accAddress,\n                accountId,\n                ...rest,\n              }}\n            />\n          </Box>\n        </StylePaper>\n      </Box>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/web-earn/src/pages/Layer2Page/ContactPanel/index.tsx",
    "content": "import { Box, Grid, IconButton, MenuItem, Popover, Typography } from '@mui/material'\nimport styled from '@emotion/styled'\nimport {\n  AddressTypeTag,\n  InputSearch,\n  TablePagination,\n  Toast,\n  ToastType,\n  useSettings,\n  InitialNameAvatar,\n  Button,\n} from '@loopring-web/component-lib'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { useContact } from '@loopring-web/core'\n\nimport {\n  CopyIcon,\n  EditIcon,\n  getShortAddr,\n  MoreIcon,\n  TOAST_TIME,\n  ContactType,\n  Contact,\n} from '@loopring-web/common-resources'\nimport { Delete } from './delete'\nimport { useHistory } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport React from 'react'\nimport { useRouteMatch } from 'react-router-dom'\nimport { ContactTransactionsPage } from './history'\nimport { bindMenu, bindTrigger, usePopupState } from 'material-ui-popup-state/hooks'\n\nconst ContactPageStyle = styled(Box)`\n  background: var(--color-box-third);\n  display: flex;\n  flex-direction: column;\n  align-items: stretch;\n  height: 85vh;\n  /* padding-bottom: 5%  */\n  width: 100%;\n  border-radius: ${({ theme }) => theme.unit}px;\n`\n\nconst Line = styled('div')`\n  border-radius: ${({ theme }) => theme.unit / 2}px;\n  height: 1px;\n  margin-top: ${({ theme }) => theme.unit * 2}px;\n  background: var(--color-divide);\n`\n\nexport enum ContactL3Router {\n  list = 'list',\n  transactions = 'transactions',\n}\n\nexport const ContactPage = () => {\n  let match: any = useRouteMatch('/layer2/contact/:item')\n  const view = React.useMemo(() => {\n    return match?.params?.item == 'transactions' ? <ContactTransactionsPage /> : <ContractPanel />\n  }, [match?.params?.item])\n  return <>{view}</>\n}\nconst ActionMemo = React.memo(\n  <N = ContactType,>({\n    data,\n    onClickSend,\n    onClickDelete,\n    index,\n    btnLoading,\n  }: {\n    data: ContactType\n    index: number\n    onClickSend: (data: Contact, index: number) => void\n    onClickDelete: (contactAddress: string, contactName: string) => void\n    btnLoading: { index: number; loading: boolean }\n  }) => {\n    const history = useHistory()\n    const { isMobile } = useSettings()\n    const { t } = useTranslation('common')\n    const popupState = usePopupState({\n      variant: 'popover',\n      popupId: 'contact-action',\n    })\n    const bindContent = bindMenu(popupState)\n    const bindAction = bindTrigger(popupState)\n    return (\n      <Grid item marginTop={1}>\n        {isMobile ? (\n          <>\n            <IconButton size={'large'} edge={'end'} {...{ ...bindAction }}>\n              <MoreIcon cursor={'pointer'} />\n            </IconButton>\n            <Popover\n              {...bindContent}\n              anchorReference='anchorEl'\n              anchorOrigin={{\n                vertical: 'bottom',\n                horizontal: 'right',\n              }}\n              transformOrigin={{\n                vertical: 'top',\n                horizontal: 'right',\n              }}\n            >\n              <Box borderRadius={'inherit'} minWidth={110}>\n                <MenuItem onClick={() => onClickSend(data, index)}>\n                  {t('labelContactsSend')}\n                </MenuItem>\n                <MenuItem\n                  onClick={() => {\n                    history.push(\n                      '/layer2/contact/transactions?contactAddress=' + data.contactAddress,\n                    )\n                  }}\n                >\n                  {t('labelContactsTransactions')}\n                </MenuItem>\n                <MenuItem\n                  onClick={() => {\n                    onClickDelete(data.contactAddress, data.contactName)\n                  }}\n                >\n                  {t('labelContactsDeleteContactBtn')}\n                </MenuItem>\n              </Box>\n            </Popover>\n          </>\n        ) : (\n          <>\n            <Button\n              onClick={() => onClickSend(data, index)}\n              variant={'contained'}\n              size={'small'}\n              sx={{ marginLeft: 1 }}\n              loading={btnLoading.index == index && btnLoading.loading ? 'true' : 'false'}\n            >\n              {t('labelContactsSend')}\n            </Button>\n            <Button\n              variant={'outlined'}\n              size={'medium'}\n              onClick={() => {\n                history.push('/layer2/contact/transactions?contactAddress=' + data.contactAddress)\n              }}\n              sx={{ marginLeft: 1 }}\n            >\n              {t('labelContactsTransactions')}\n            </Button>\n            <Button\n              variant={'outlined'}\n              size={'medium'}\n              onClick={() => {\n                onClickDelete(data.contactAddress, data.contactName)\n              }}\n              sx={{ marginLeft: 1 }}\n            >\n              {t('labelContactsDeleteContactBtn')}\n            </Button>\n          </>\n        )}\n      </Grid>\n    )\n  },\n)\nexport const ContractPanel = ({ viewHeightRatio = 0.85, viewHeightOffset = 130 }) => {\n  const {\n    contacts,\n    searchValue,\n    onChangeSearch,\n    onClickDelete,\n    setShowEditContact,\n    toastInfo,\n    deleteInfo,\n    onCloseDelete,\n    submitDeleteContact,\n    deleteLoading,\n    onClickSend,\n    btnLoading,\n    closeToast,\n    setToast,\n    pagination,\n    onPageChange,\n    showPagination,\n  } = useContact({\n    viewHeightRatio,\n    viewHeightOffset,\n  })\n  const { t } = useTranslation()\n\n  const noContact = (\n    <Box height={'80vh'} display={'flex'} justifyContent={'center'} alignItems={'center'}>\n      <Typography component={'span'} variant={'body1'} color={'var(--color-text-third)'}>\n        {t('labelContactsNoContact')}\n      </Typography>\n    </Box>\n  )\n\n  const { isMobile } = useSettings()\n\n  return (\n    <ContactPageStyle className={'MuiPaper-elevation2'} paddingX={4} paddingY={3}>\n      <Toast\n        alertText={toastInfo.content ?? ''}\n        severity={toastInfo?.type}\n        open={toastInfo.open}\n        autoHideDuration={TOAST_TIME}\n        onClose={closeToast}\n        // onClose={closeToastL}\n      />\n      <Delete\n        deleteInfo={deleteInfo}\n        onCloseDelete={onCloseDelete}\n        submitDeleteContact={submitDeleteContact}\n        loading={deleteLoading}\n      />\n      <Box display={'flex'} justifyContent={'space-between'}>\n        <Typography variant={'h2'} paddingRight={2}>\n          {t('labelContacts')}\n        </Typography>\n        <Box display={'flex'} alignItems={'center'}>\n          <InputSearch\n            value={searchValue}\n            onChange={(e) => {\n              onChangeSearch(e as unknown as string)\n            }}\n          />\n          <Box marginLeft={2}>\n            <Button\n              variant={'contained'}\n              size={'small'}\n              onClick={() => {\n                setShowEditContact({ isShow: true })\n              }}\n            >\n              {t('labelContactsAddContactBtn')}\n            </Button>\n          </Box>\n        </Box>\n      </Box>\n      <Box className='table-divide'>\n        <Line />\n        <Box>\n          {!contacts || contacts.length === 0 ? (\n            noContact\n          ) : (\n            <>\n              <Box\n                height={`calc(${viewHeightRatio * 100}vh - ${viewHeightOffset}px)`}\n                overflow={'scroll'}\n              >\n                {contacts &&\n                  contacts.map((data, index) => {\n                    return (\n                      <Box\n                        key={data.contactAddress}\n                        paddingY={2}\n                        display={data.addressType === sdk.AddressType.OFFICIAL ? 'none' : 'flex'}\n                        justifyContent={'space-between'}\n                      >\n                        <Box display={'flex'}>\n                          <InitialNameAvatar name={data.contactName} />\n                          <Typography\n                            component={'p'}\n                            marginLeft={1}\n                            display={'flex'}\n                            flexDirection={'column'}\n                          >\n                            <Typography\n                              display={'inline-flex'}\n                              alignItems={'center'}\n                              component={'span'}\n                              paddingRight={1}\n                            >\n                              <Typography\n                                display={'inline-flex'}\n                                paddingRight={1}\n                                component={'span'}\n                              >\n                                {data.contactName}\n                              </Typography>\n                              <AddressTypeTag addressType={data.addressType} />\n                              <EditIcon\n                                sx={{\n                                  paddingLeft: 1,\n                                }}\n                                fontSize={'large'}\n                                onClick={() => {\n                                  setShowEditContact({\n                                    isShow: true,\n                                    info: {\n                                      ...data,\n                                    },\n                                  })\n                                }}\n                              />\n                            </Typography>\n                            <Typography component={'span'} title={data.contactAddress}>\n                              {isMobile\n                                ? getShortAddr(data.contactAddress ?? '')\n                                : data.contactAddress}\n                              <IconButton\n                                onClick={() => {\n                                  navigator.clipboard.writeText(data.contactAddress)\n                                  setToast({\n                                    open: true,\n                                    type: ToastType.success,\n                                    content: t('labelContactsCopySuccess'),\n                                  })\n                                }}\n                              >\n                                <CopyIcon />\n                              </IconButton>\n                            </Typography>\n                          </Typography>\n                        </Box>\n                        <Box display={'flex'}>\n                          <ActionMemo\n                            data={data}\n                            btnLoading={btnLoading}\n                            index={index}\n                            onClickSend={onClickSend}\n                            onClickDelete={onClickDelete}\n                          />\n                        </Box>\n                      </Box>\n                    )\n                  })}\n              </Box>\n              {showPagination && pagination && (\n                <TablePagination\n                  page={pagination.page}\n                  pageSize={pagination.pageSize}\n                  total={pagination.total}\n                  onPageChange={onPageChange}\n                />\n              )}\n            </>\n          )}\n        </Box>\n      </Box>\n    </ContactPageStyle>\n  )\n}\n"
  },
  {
    "path": "packages/web-earn/src/pages/Layer2Page/ForcewithdrawPanel/index.tsx",
    "content": "import styled from '@emotion/styled'\nimport { Box, Link } from '@mui/material'\nimport React from 'react'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport {\n  Button,\n  ForceWithdrawPanel,\n  TransactionTradeViews,\n  useSettings,\n} from '@loopring-web/component-lib'\nimport { useForceWithdraw } from '@loopring-web/core'\nimport { useTheme } from '@emotion/react'\nimport { useHistory } from 'react-router-dom'\nimport { BackIcon, RecordTabIndex } from '@loopring-web/common-resources'\n\nconst StylePaper = styled(Box)`\n  background: var(--color-box);\n  border-radius: ${({ theme }) => theme.unit}px;\n\n  .content {\n    width: 420px;\n  }\n\n  &.isMobile {\n    .content {\n      flex: 1;\n      width: var(--swap-box-width);\n    }\n  }\n`\n\nexport const ForcewithdrawPanel = withTranslation(['common', 'layout'])(\n  ({ t }: WithTranslation) => {\n    const { isMobile } = useSettings()\n    const history = useHistory()\n    const { forceWithdrawProps } = useForceWithdraw()\n    const theme = useTheme()\n    const extendsProps = isMobile ? { _width: 420 } : { _width: 'auto' }\n    return (\n      <Box flex={1} display={'flex'} flexDirection={'column'}>\n        <Box marginBottom={2}>\n          <Button\n            startIcon={<BackIcon fontSize={'small'} />}\n            variant={'text'}\n            size={'medium'}\n            sx={{ color: 'var(--color-text-secondary)' }}\n            color={'inherit'}\n            onClick={history.goBack}\n          >\n            {t('labelForceWithdrawTitle')}\n          </Button>\n        </Box>\n        <StylePaper\n          flex={1}\n          display={'flex'}\n          alignItems={'center'}\n          justifyContent={'center'}\n          className={isMobile ? 'isMobile' : 'MuiPaper-elevation2'}\n          marginBottom={2}\n          position={'relative'}\n        >\n          <Link\n            position={'absolute'}\n            variant={'body1'}\n            sx={{\n              right: 2 * theme.unit,\n              top: 2 * theme.unit,\n              zIndex: 999,\n            }}\n            target='_self'\n            rel='noopener noreferrer'\n            onClick={() =>\n              history.push(\n                `/l2assets/history/${RecordTabIndex.Transactions}?types=${TransactionTradeViews.forceWithdraw}`,\n              )\n            }\n          >\n            {t('labelTransactionsLink')}\n          </Link>\n          <Box\n            display={'flex'}\n            alignItems={'center'}\n            justifyContent={'center'}\n            className={'content'}\n          >\n            <ForceWithdrawPanel {...{ ...forceWithdrawProps, ...extendsProps }} />\n          </Box>\n        </StylePaper>\n      </Box>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/web-earn/src/pages/Layer2Page/ReferralRewardsPanel/hook.ts",
    "content": "import { LoopringAPI, store, useAccount } from '@loopring-web/core'\nimport { useTranslation } from 'react-i18next'\nimport React from 'react'\nimport { ReferralsRow, ToastType, RefundRow } from '@loopring-web/component-lib'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport {\n  AccountStatus,\n  getValuePrecisionThousand,\n  SagaStatus,\n  SDK_ERROR_MAP_TO_UI,\n} from '@loopring-web/common-resources'\nexport function useRefundTable<R = RefundRow>(setToastOpen: (state: any) => void) {\n  const {\n    account: { accountId, apiKey },\n    status: accountStatus,\n  } = useAccount()\n  const { tokenMap } = store.getState().tokenMap\n  const { t } = useTranslation(['error'])\n  const [summary, setSummary] = React.useState<undefined | any>(undefined)\n  const [record, setRecord] = React.useState<R[]>([])\n  const [recordTotal, setRecordTotal] = React.useState(0)\n  const [showLoading, setShowLoading] = React.useState(false)\n  const getRefundTableList = React.useCallback(\n    async ({ start, end, limit, offset }: Partial<sdk.GetReferSelf>) => {\n      if (LoopringAPI && LoopringAPI.userAPI && accountId && apiKey) {\n        setShowLoading(true)\n        try {\n          const response = await LoopringAPI.userAPI.getReferSelf(\n            {\n              accountId: accountId.toString(),\n              limit,\n              start,\n              end,\n              offset,\n            },\n            apiKey,\n          )\n          if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n            throw response as sdk.RESULT_INFO\n          } else {\n            const list = response?.records.map(({ lrcAmount, ...item }) => {\n              return {\n                ...item,\n                amount: {\n                  unit: 'LRC',\n                  value: getValuePrecisionThousand(\n                    sdk.toBig(lrcAmount).div('1e' + tokenMap['LRC'].decimals),\n                    tokenMap['LRC'].precision,\n                    tokenMap['LRC'].precision,\n                    tokenMap['LRC'].precision,\n                    false,\n                  ),\n                },\n              } as unknown as R\n            })\n            setRecord(list)\n            setRecordTotal(response.totalNum)\n          }\n        } catch (error) {\n          let errorItem\n          if (typeof (error as sdk.RESULT_INFO)?.code === 'number') {\n            errorItem = SDK_ERROR_MAP_TO_UI[(error as sdk.RESULT_INFO)?.code ?? 700001]\n          } else {\n            errorItem = SDK_ERROR_MAP_TO_UI[700012]\n          }\n          setToastOpen({\n            open: true,\n            type: ToastType.error,\n            content: 'error : ' + errorItem ? t(errorItem.messageKey) : (error as any)?.message,\n          })\n        }\n\n        setShowLoading(false)\n      }\n    },\n    [accountId, apiKey, setToastOpen, t, tokenMap],\n  )\n  React.useEffect(() => {\n    const account = store.getState().account\n    if (accountStatus === SagaStatus.UNSET && account.readyState == AccountStatus.ACTIVATED) {\n      LoopringAPI.userAPI\n        ?.geReferStatistic<sdk.ReferStatistic>(\n          {\n            accountId: accountId.toString(),\n            reason: sdk.GetReferStatisticReason.Recommender,\n          },\n          apiKey,\n        )\n        .then((response) => {\n          if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n            const errorItem = SDK_ERROR_MAP_TO_UI[(response as sdk.RESULT_INFO)?.code ?? 700001]\n            setToastOpen({\n              open: true,\n              type: ToastType.error,\n              content:\n                'error : ' + errorItem\n                  ? t(errorItem.messageKey)\n                  : (response as sdk.RESULT_INFO).message,\n            })\n          } else {\n            // ;\n            // ;\n\n            setSummary({\n              ...response,\n              totalValue:\n                response.totalProfit == '' || response.totalProfit == '0'\n                  ? undefined\n                  : getValuePrecisionThousand(\n                      sdk.toBig(response.totalProfit).div('1e' + tokenMap['LRC'].decimals),\n                      tokenMap['LRC'].precision,\n                      tokenMap['LRC'].precision,\n                      tokenMap['LRC'].precision,\n                      false,\n                    ),\n              claimableValue:\n                response.claimableProfit == '' || response.claimableProfit == '0'\n                  ? undefined\n                  : getValuePrecisionThousand(\n                      sdk.toBig(response.claimableProfit).div('1e' + tokenMap['LRC'].decimals),\n                      tokenMap['LRC'].precision,\n                      tokenMap['LRC'].precision,\n                      tokenMap['LRC'].precision,\n                      false,\n                    ),\n            })\n          }\n        })\n    }\n  }, [accountStatus])\n\n  return {\n    summary,\n    record,\n    recordTotal,\n    showLoading,\n    getRefundTableList,\n  }\n}\n\nexport function useReferralsTable<R = ReferralsRow>(setToastOpen: (state: any) => void) {\n  const {\n    account: { accountId, apiKey },\n    status: accountStatus,\n  } = useAccount()\n  const { tokenMap } = store.getState().tokenMap\n  const { t } = useTranslation(['error'])\n  const [summary, setSummary] = React.useState<undefined | any>(undefined)\n  const [record, setRecord] = React.useState<R[]>([])\n  const [recordTotal, setRecordTotal] = React.useState(0)\n  const [showLoading, setShowLoading] = React.useState(false)\n  const getReferralsTableList = React.useCallback(\n    async ({ start, end, limit, offset }: Partial<sdk.GetReferDownsides>) => {\n      if (LoopringAPI && LoopringAPI.userAPI && accountId && apiKey) {\n        setShowLoading(true)\n        try {\n          const response = await LoopringAPI.userAPI.getReferDownsides(\n            {\n              accountId: accountId.toString(),\n              limit,\n              start,\n              end,\n              offset,\n            },\n            apiKey,\n          )\n          if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n            throw response\n          } else {\n            const list = response?.records.map(({ lrcAmount, ...item }) => {\n              return {\n                ...item,\n                amount: {\n                  unit: 'LRC',\n                  value: getValuePrecisionThousand(\n                    sdk.toBig(lrcAmount).div('1e' + tokenMap['LRC'].decimals),\n                    tokenMap['LRC'].precision,\n                    tokenMap['LRC'].precision,\n                    tokenMap['LRC'].precision,\n                    false,\n                  ),\n                },\n              } as unknown as R\n            })\n            setRecord(list)\n            setRecordTotal(response.totalNum)\n          }\n        } catch (error) {\n          let errorItem\n          if (typeof (error as sdk.RESULT_INFO)?.code === 'number') {\n            errorItem = SDK_ERROR_MAP_TO_UI[(error as sdk.RESULT_INFO)?.code ?? 700001]\n          } else {\n            errorItem = SDK_ERROR_MAP_TO_UI[700012]\n          }\n          setToastOpen({\n            open: true,\n            type: ToastType.error,\n            content: 'error : ' + errorItem ? t(errorItem.messageKey) : (error as any)?.message,\n          })\n        }\n\n        setShowLoading(false)\n      }\n    },\n    [accountId, apiKey, setToastOpen, t, tokenMap],\n  )\n  React.useEffect(() => {\n    const account = store.getState().account\n    if (accountStatus === SagaStatus.UNSET && account.readyState == AccountStatus.ACTIVATED) {\n      LoopringAPI.userAPI\n        ?.geReferStatistic<sdk.ReferStatistic>(\n          {\n            accountId: accountId.toString(),\n            reason: sdk.GetReferStatisticReason.Invited,\n          },\n          apiKey,\n        )\n        .then((response) => {\n          if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n            const errorItem = SDK_ERROR_MAP_TO_UI[(response as sdk.RESULT_INFO)?.code ?? 700001]\n            setToastOpen({\n              open: true,\n              type: ToastType.error,\n              content:\n                'error : ' + errorItem\n                  ? t(errorItem.messageKey)\n                  : (response as sdk.RESULT_INFO).message,\n            })\n          } else {\n            setSummary({\n              ...response,\n              totalValue:\n                response.totalProfit == '' || response.totalProfit == '0'\n                  ? undefined\n                  : getValuePrecisionThousand(\n                      sdk.toBig(response.totalProfit).div('1e' + tokenMap['LRC'].decimals),\n                      tokenMap['LRC'].precision,\n                      tokenMap['LRC'].precision,\n                      tokenMap['LRC'].precision,\n                      false,\n                    ),\n              claimableValue:\n                response.claimableProfit == '' || response.claimableProfit == '0'\n                  ? undefined\n                  : getValuePrecisionThousand(\n                      sdk.toBig(response.claimableProfit).div('1e' + tokenMap['LRC'].decimals),\n                      tokenMap['LRC'].precision,\n                      tokenMap['LRC'].precision,\n                      tokenMap['LRC'].precision,\n                      false,\n                    ),\n            })\n          }\n        })\n    }\n  }, [accountStatus])\n\n  return {\n    summary,\n    record,\n    recordTotal,\n    showLoading,\n    getReferralsTableList,\n  }\n}\n\n// export function useReferralRewardSumInfo() {\n//   const {\n//     account: { accountId, apiKey },\n//   } = useAccount();\n//   const [summary, setSummary] = React.useState();\n//\n//\n//   return {};\n// }\n"
  },
  {
    "path": "packages/web-earn/src/pages/Layer2Page/ReferralRewardsPanel/index.tsx",
    "content": "import styled from '@emotion/styled'\nimport {\n  Box,\n  BoxProps,\n  Container,\n  Grid,\n  InputAdornment,\n  Link,\n  Tab,\n  Tabs,\n  Typography,\n} from '@mui/material'\nimport React from 'react'\nimport { Trans, useTranslation } from 'react-i18next'\nimport { useAccount, useIPFS, useSubmitBtn, useToast } from '@loopring-web/core'\nimport {\n  AccountStatus,\n  AssetTabIndex,\n  copyToClipBoard,\n  EmptyValueTag,\n  Exchange,\n  ExchangeIO,\n  L1L2_NAME_DEFINED,\n  LinkSharedIcon,\n  MapChainId,\n  myLog,\n  ProfileIndex,\n  Layer2RouterID,\n  SoursURL,\n  TOAST_TIME,\n  TradeBtnStatus,\n  url_path,\n  WalletSite,\n} from '@loopring-web/common-resources'\nimport {\n  Button,\n  CarouselItem,\n  ReferralsTable,\n  RefundTable,\n  ShareModal,\n  Toast,\n  ToastType,\n  useSettings,\n  OutlinedInput,\n} from '@loopring-web/component-lib'\nimport { useReferralsTable, useRefundTable } from './hook'\nimport { useHistory } from 'react-router-dom'\nimport { ErrorPage } from '../../ErrorPage'\n\nconst BoxStyled = styled(Box)`\n  ol {\n    list-style: decimal inside;\n\n    li {\n      //list-item;\n      color: var(--color-text-third);\n      display: list-item;\n      font-size: ${({ theme }) => theme.fontDefault.body1};\n      // padding: ${({ theme }) => `0 ${theme.unit}`}px;\n      line-height: 2em;\n    }\n  }\n`\nexport const BoxBannerStyle = styled(Box)<\n  BoxProps & { backGroundUrl?: string | number; direction?: 'left' | 'right' }\n>`\n  background-color: var(--color-box);\n\n  .bg:after {\n    display: block;\n    content: '';\n    float: ${({ direction }) => direction};\n    width: 35%;\n    background-repeat: no-repeat;\n    background-position: center;\n    background-size: contain;\n    background-image: url('${({ backGroundUrl }) => backGroundUrl}');\n  }\n\n  &.mobile .bg {\n    position: relative;\n    display: flex;\n    flex-direction: column;\n\n    &:after {\n      opacity: 0.08;\n      z-index: 1;\n      position: absolute;\n      top: 0;\n      width: 100%;\n      height: 100%;\n      pointer-events: none;\n    }\n  }\n` as (\n  props: BoxProps & {\n    backGroundUrl?: string | number\n    direction?: 'left' | 'right'\n  },\n) => JSX.Element\n\nenum ReferStep {\n  method1 = 0,\n  method2 = 1,\n}\n\nexport type ImageReferralBanner = {\n  referralBanners: { en: string[] }\n  lng: string[]\n  position: {\n    code: { default: any[]; [key: number]: any[] }\n    [key: string]: any\n  }\n}\n\nconst ReferHeader = <R extends ImageReferralBanner>({\n  isActive = true,\n  handleCopy,\n  link,\n}: {\n  link: string\n  isActive?: boolean\n  handleCopy: (selected: 'id' | 'link') => void\n}) => {\n  const { account } = useAccount()\n  const { t } = useTranslation(['common', 'layout'])\n  const { defaultNetwork, isMobile } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const [open, setOpen] = React.useState(false)\n  const [images, setImages] = React.useState<CarouselItem[]>([])\n  const [loading, setLoading] = React.useState(true)\n  const [imageList, setImageList] = React.useState<R>({\n    // @ts-ignore\n    referralBanners: {\n      en: [],\n    },\n    lng: ['en'],\n    position: {\n      code: { default: [48, 30, 230, 64, '#000000', 630, 880] },\n    },\n  })\n  const { btnStatus, onBtnClick, btnLabel } = useSubmitBtn({\n    availableTradeCheck: () => {\n      return { tradeBtnStatus: TradeBtnStatus.AVAILABLE, label: '' }\n    },\n    isLoading: loading,\n    submitCallback: async () => {\n      setOpen(true)\n      // Carousel\n      // onDownloadImage();\n    },\n  })\n  // const [images, setImages] = React.useState<JSX.Element[]>([]);\n  React.useEffect(() => {\n    fetch(`${url_path}/referral/information.json`)\n      .then((response) => response.json())\n      .then((result) => {\n        if (result.referralBanners) {\n          try {\n            setImageList(result)\n            renderImage(result)\n          } catch (error) {\n            setLoading(false)\n          }\n        }\n      })\n      .catch(() => {\n        setLoading(false)\n      })\n  }, [])\n  const renderImage = React.useCallback(\n    (imageList: R) => {\n      let images: any[] = []\n      imageList?.referralBanners?.en.forEach((item, index) => {\n        const canvas: HTMLCanvasElement = document.createElement('canvas')\n        let _default: any = undefined\n        if (imageList?.position?.code[index]) {\n          _default = imageList?.position?.code[index]\n        } else {\n          _default = imageList?.position?.code?.default\n        }\n        let [left, bottom, , , color, width, height] = _default ?? [\n          48,\n          30,\n          230,\n          64,\n          '#000000',\n          630,\n          880,\n        ]\n        const lebelY = height - bottom - 100 + 20\n        const lebelX = left\n        const lebelCodeY = lebelY + 64\n        const lebelCodeX = left\n        const labelCode = t('labelReferralImageCode', {\n          code: account.accountId,\n        })\n        const label = t('labelReferralImageDes')\n\n        canvas.width = width\n        canvas.height = height\n        // @ts-ignore\n        const context: CanvasRenderingContext2D = canvas.getContext('2d')\n        const image = new Image()\n        image.crossOrigin = 'true'\n        image.src = item\n\n        image.onload = function () {\n          context.clearRect(0, 0, width, width)\n          context.drawImage(image, 0, 0, width, height)\n          context.font = '28px Roboto'\n          context.fillStyle = color\n          context.textAlign = 'left'\n          context.fillText(label, lebelX, lebelY)\n          context.font = '44px Roboto'\n          context.fillText(labelCode, lebelCodeX, lebelCodeY)\n\n          // myLog('imageUrl createObjectURL', canvas.toDataURL())\n          images.push({\n            imageUrl: canvas.toDataURL(),\n            size: [width / 2, height / 2],\n            name: (item ?? '/').split('/')?.pop(),\n          })\n          if (index + 1 == imageList?.referralBanners?.en?.length) {\n            myLog('imageList', images)\n          }\n        }\n      })\n      setLoading(false)\n    },\n    [imageList, account],\n  )\n  const onDownloadImage = () => {\n    imageList?.referralBanners?.en.map((item, index) => {\n      const canvas: HTMLCanvasElement = document.createElement('canvas')\n      let _default: any = undefined\n      if (imageList?.position?.code[index]) {\n        _default = imageList?.position?.code[index]\n      } else {\n        _default = imageList?.position?.code?.default\n      }\n      let [left, bottom, , , color, width, height] = _default ?? [\n        48,\n        30,\n        230,\n        64,\n        '#000000',\n        630,\n        880,\n      ]\n      const lebelY = height - bottom - 100 + 20\n      const lebelX = left\n      const lebelCodeY = lebelY + 64\n      const lebelCodeX = left\n      const labelCode = t('labelReferralImageCode', {\n        code: account.accountId,\n      })\n      const label = t('labelReferralImageDes')\n\n      canvas.width = width\n      canvas.height = height\n      // @ts-ignore\n      const context: CanvasRenderingContext2D = canvas.getContext('2d')\n      const image = new Image()\n      image.crossOrigin = 'true'\n      image.src = item\n      image.onload = function () {\n        context.clearRect(0, 0, width, width)\n        context.drawImage(image, 0, 0, width, height)\n        context.font = '28px Roboto'\n        context.fillStyle = color\n        context.textAlign = 'left'\n        context.fillText(label, lebelX, lebelY)\n        context.font = '44px Roboto'\n        context.fillText(labelCode, lebelCodeX, lebelCodeY)\n\n        canvas.toBlob((blob) => {\n          const a = document.createElement('a')\n          // @ts-ignore\n          a.download = (item ?? '/').split('/')?.pop()\n          a.style.display = 'none'\n          // @ts-ignore\n          a.href = URL.createObjectURL(blob)\n          document.body.appendChild(a)\n          a.click()\n          document.body.removeChild(a)\n        }, 'image/jpeg')\n      }\n    })\n  }\n\n  const { ipfsProvides } = useIPFS({\n    handleSuccessUpload: () => undefined,\n    handleFailedUpload: () => undefined,\n  })\n\n  const label = React.useMemo(() => {\n    if (btnLabel) {\n      const key = btnLabel.split('|')\n      if (key) {\n        return t(\n          key[0],\n          key && key[1]\n            ? {\n                arg: key[1],\n                l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n              }\n            : {\n                l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n              },\n        )\n      } else {\n        return t(btnLabel, {\n          l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n          loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n          l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n          l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n          ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n        })\n      }\n    } else {\n      return t(`labelInvite`)\n    }\n  }, [t, btnLabel])\n\n  return (\n    <BoxBannerStyle\n      className={isMobile ? 'mobile' : ''}\n      backGroundUrl={SoursURL + '/images/giftReward.webp'}\n      direction={'right'}\n    >\n      <Container>\n        <ShareModal\n          onClick={() => onDownloadImage()}\n          open={open}\n          message={t('labelShareMessage', { code: account?.accountId })}\n          loading={btnStatus === TradeBtnStatus.LOADING}\n          onClose={() => setOpen(false)}\n          imageList={images}\n          ipfsProvides={ipfsProvides}\n          link={ExchangeIO + `?referralcode=${account?.accountId}`}\n        />\n        <Box className={'bg'} marginY={3} display={'flex'}>\n          <Box width={isMobile ? '100%' : '65%'}>\n            <Typography\n              component={'h1'}\n              variant={isMobile ? 'h4' : 'h2'}\n              sx={{ whiteSpace: 'pre-line', wordBreak: 'break-all' }}\n            >\n              {t('labelReferTitle')}\n            </Typography>\n            <Typography\n              paddingY={1}\n              component={'h2'}\n              variant={'body1'}\n              color={'textSecondary'}\n              sx={{ whiteSpace: 'pre-line', wordBreak: 'break-all' }}\n            >\n              {t('labelReferTitleDes')}\n            </Typography>\n            {account.readyState == AccountStatus.ACTIVATED && (\n              <>\n                <Box paddingTop={1} width={isMobile ? '100%' : '70%'}>\n                  <OutlinedInput\n                    size={'large'}\n                    className={'copy'}\n                    placeholder={'copy'}\n                    value={link}\n                    disabled={true}\n                    fullWidth={true}\n                    // onChange={(event: any) => {}}\n                    startAdornment={\n                      <InputAdornment position='start'>\n                        <LinkSharedIcon color={'inherit'} />\n                      </InputAdornment>\n                    }\n                    endAdornment={\n                      <Button size={'small'} variant={'text'} onClick={() => handleCopy('link')}>\n                        {t('labelCopy')}\n                      </Button>\n                    }\n                  />\n                </Box>\n                <Box paddingTop={1} width={isMobile ? '100%' : '70%'}>\n                  <OutlinedInput\n                    size={'large'}\n                    className={'copy'}\n                    placeholder={'copy'}\n                    value={account.accountId}\n                    disabled={true}\n                    fullWidth={true}\n                    // onChange={(event: any) => {}}\n                    startAdornment={\n                      <InputAdornment position='start'>\n                        <Typography\n                          color={'var(--color-text-third)'}\n                          variant={'h2'}\n                          display={'inline-flex'}\n                          width={36}\n                          textAlign={'center'}\n                          component={'span'}\n                          paddingX={1 / 2}\n                        >\n                          #\n                        </Typography>\n                        {/*<LinkIcon color={\"inherit\"} />*/}\n                      </InputAdornment>\n                    }\n                    endAdornment={\n                      <Button size={'small'} variant={'text'} onClick={() => handleCopy('id')}>\n                        {t('labelCopy')}\n                      </Button>\n                    }\n                  />\n                </Box>\n              </>\n            )}\n            <Box marginY={2}>\n              <Button\n                size={'medium'}\n                onClick={onBtnClick}\n                loading={'false'}\n                variant={'contained'}\n                sx={{ minWidth: 'var(--walletconnect-width)' }}\n                disabled={\n                  btnStatus === TradeBtnStatus.DISABLED || btnStatus === TradeBtnStatus.LOADING\n                }\n              >\n                {label}\n              </Button>\n              {/*{image.map((item, index) => (*/}\n              {/*  <React.Fragment key={index}>{item}</React.Fragment>*/}\n              {/*))}*/}\n              <Box sx={{ display: 'block' }} height={0} width={0} overflow={'hidden'}>\n                <canvas className={'canvas'} />\n                {/*{images.map((item, index) => (*/}\n                {/*  <React.Fragment key={index}>{item}</React.Fragment>*/}\n                {/*))}*/}\n              </Box>\n            </Box>\n          </Box>\n        </Box>\n      </Container>\n    </BoxBannerStyle>\n  )\n}\n\nconst ReferView = () => {\n  const { account } = useAccount()\n  const { t } = useTranslation()\n  const { defaultNetwork, isMobile } = useSettings()\n  const { toastOpen, setToastOpen, closeToast } = useToast()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const refundData = useRefundTable(setToastOpen)\n  const referralsData = useReferralsTable(setToastOpen)\n  const [currentTab, setCurrentTab] = React.useState(ReferStep.method1)\n  const link = `${WalletSite}?referralcode=${account.accountId}`\n  const linkExchange = `${Exchange}?referralcode=${account.accountId}`\n  const history = useHistory()\n\n  const handleCopy = (selected: 'id' | 'link') => {\n    switch (selected) {\n      case 'id':\n        copyToClipBoard(account?.accountId?.toString())\n        setToastOpen({\n          open: true,\n          type: ToastType.success,\n          content: t('labelCopyCodeClip'),\n        })\n        break\n      case 'link':\n        copyToClipBoard(link)\n        setToastOpen({\n          open: true,\n          type: ToastType.success,\n          content: t('labelCopyAddClip'),\n        })\n        break\n    }\n  }\n  myLog('refundData', refundData, referralsData)\n  return (\n    <>\n      {ProfileIndex[network]?.includes(Layer2RouterID.referralrewards) ? (\n        <>\n          <Toast\n            alertText={toastOpen?.content ?? ''}\n            open={toastOpen?.open ?? false}\n            autoHideDuration={TOAST_TIME}\n            onClose={closeToast}\n            severity={toastOpen.type}\n          />\n          <ReferHeader handleCopy={handleCopy} link={link} />\n          <Container>\n            <BoxStyled marginTop={2} paddingY={2} paddingX={0} flex={1}>\n              <Typography component={'h3'} variant={'h4'} marginY={2}>\n                {t('labelReferralRules')}\n              </Typography>\n              <Tabs\n                sx={{ marginLeft: -1 }}\n                value={currentTab}\n                className={'MuiTabs-small'}\n                onChange={(_event, value) => {\n                  setCurrentTab(value)\n                }}\n                aria-label='reward-rule-tabs'\n                variant='scrollable'\n              >\n                <Tab label={t('labelReferralMethod1')} value={ReferStep.method1} />\n                <Tab label={t('labelReferralMethod2')} value={ReferStep.method2} />\n              </Tabs>\n              <Box>\n                {currentTab === ReferStep.method1 && (\n                  <ol>\n                    <li>{t('labelReferralMethod1Step1')}</li>\n                    <li>{t('labelReferralMethod1Step2')}</li>\n                    <li>\n                      {t('labelReferralMethod1Step3', {\n                        loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                        l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                        l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                        ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                        loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n                      })}\n                    </li>\n                    <li>{t('labelReferralMethod1Step4')}</li>\n                  </ol>\n                )}\n                {currentTab === ReferStep.method2 && (\n                  <ol>\n                    <li>\n                      {' '}\n                      <Trans i18nKey={'labelReferralMethod2Step1'}>\n                        Access the website\n                        <Link href={linkExchange} target={'_blank'}>\n                          {ExchangeIO}\n                        </Link>\n                      </Trans>\n                    </li>\n                    <li>{t('labelReferralMethod2Step2')}</li>\n                    <li>\n                      {t('labelReferralMethod2Step3', {\n                        loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                        l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                        l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                        ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                        loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n                      })}\n                    </li>\n                    <li>{t('labelReferralMethod2Step4')}</li>\n                  </ol>\n                )}\n              </Box>\n\n              {account.readyState === AccountStatus.ACTIVATED && (\n                <>\n                  <BoxStyled marginTop={2} paddingY={2} paddingX={0} flex={1}>\n                    <Typography component={'h3'} variant={'h4'} marginY={2}>\n                      {t('labelReferralMyReferrals')}\n                    </Typography>\n\n                    <Box display={'flex'} flexDirection={'column'}>\n                      <Grid container marginY={2}>\n                        <Grid item md={4} xs={6}>\n                          <Typography\n                            component={'span'}\n                            color={'var(--color-text-third)'}\n                            variant={'body1'}\n                            paddingRight={isMobile ? '' : 2}\n                          >\n                            {t('labelReferralsTotalReferrals')}\n                            {referralsData.summary?.downsidesNum &&\n                            referralsData.summary?.downsidesNum != '0' ? (\n                              <Typography\n                                variant={'inherit'}\n                                component={'span'}\n                                color={'textPrimary'}\n                                paddingLeft={1}\n                              >\n                                {referralsData.summary?.downsidesNum}\n                              </Typography>\n                            ) : (\n                              EmptyValueTag\n                            )}\n                          </Typography>\n                        </Grid>\n                        <Grid\n                          item\n                          md={4}\n                          xs={6}\n                          justifyContent={'space-evenly'}\n                          flexDirection={'column'}\n                          alignItems={'flex-end'}\n                          display={'flex '}\n                        >\n                          <Typography\n                            component={'span'}\n                            color={'var(--color-text-third)'}\n                            variant={'body1'}\n                            paddingRight={isMobile ? '' : 2}\n                          >\n                            {t('labelReferralsTotalEarning')}\n                            {referralsData.summary?.totalValue ? (\n                              <Typography\n                                variant={'inherit'}\n                                component={'span'}\n                                color={'textPrimary'}\n                                paddingLeft={1}\n                              >\n                                {referralsData.summary?.totalValue + ' LRC'}\n                              </Typography>\n                            ) : (\n                              EmptyValueTag\n                            )}\n                          </Typography>\n                        </Grid>\n\n                        <Grid\n                          item\n                          md={4}\n                          xs={12}\n                          flexDirection={'row'}\n                          alignItems={'center'}\n                          display={'flex'}\n                          paddingTop={isMobile ? 1 : ''}\n                          justifyContent={isMobile ? 'space-between' : 'flex-end'}\n                        >\n                          <Typography\n                            component={'span'}\n                            color={'var(--color-text-third)'}\n                            variant={'body1'}\n                            paddingRight={isMobile ? '' : 2}\n                          >\n                            {t('labelReferralsClaimEarning')}\n                            {referralsData.summary?.claimableValue ? (\n                              <Typography\n                                paddingLeft={1}\n                                variant={'inherit'}\n                                component={'span'}\n                                color={'textPrimary'}\n                              >\n                                {referralsData.summary?.claimableValue + ' LRC'}\n                              </Typography>\n                            ) : (\n                              <Typography\n                                variant={'inherit'}\n                                component={'span'}\n                                color={'var(--color-text-third)'}\n                              >\n                                {EmptyValueTag}\n                              </Typography>\n                            )}\n                          </Typography>\n                          {referralsData.summary?.claimableValue ? (\n                            <Button\n                              variant={'contained'}\n                              size={'small'}\n                              sx={{ marginLeft: 2 }}\n                              onClick={() => {\n                                history.push(`/l2assets/assets/${AssetTabIndex.Rewards}`)\n                              }}\n                            >\n                              {t('labelClaimBtn')}\n                            </Button>\n                          ) : (\n                            <></>\n                          )}\n                        </Grid>\n                      </Grid>\n                      <ReferralsTable\n                        {...{\n                          rawData: referralsData.record,\n                          pagination: {\n                            pageSize: 8,\n                            total: referralsData.recordTotal,\n                          },\n                          getList: referralsData.getReferralsTableList,\n                          showloading: referralsData.showLoading,\n                        }}\n                      />\n                    </Box>\n                  </BoxStyled>\n                  <BoxStyled marginTop={2} paddingY={2} paddingX={0} flex={1}>\n                    <Typography component={'h3'} variant={'h4'} marginY={2}>\n                      {t('labelReferralReferralsRefunds')}\n                    </Typography>\n                    <Grid container marginY={2}>\n                      <Grid item md={4} xs={6}>\n                        <Typography\n                          component={'span'}\n                          color={'var(--color-text-third)'}\n                          variant={'body1'}\n                          paddingRight={isMobile ? '' : 2}\n                        >\n                          {t('labelReferralsTotalTradeNumber')}\n                          {refundData.summary?.tradeNum && refundData.summary?.tradeNum != '0' ? (\n                            <Typography\n                              variant={'inherit'}\n                              component={'span'}\n                              color={'textPrimary'}\n                              paddingLeft={1}\n                            >\n                              {refundData.summary?.tradeNum}\n                            </Typography>\n                          ) : (\n                            EmptyValueTag\n                          )}\n                        </Typography>\n                      </Grid>\n                      <Grid\n                        item\n                        md={4}\n                        xs={6}\n                        justifyContent={'space-evenly'}\n                        flexDirection={'column'}\n                        alignItems={'flex-end'}\n                        display={'flex '}\n                      >\n                        <Typography\n                          component={'span'}\n                          color={'var(--color-text-third)'}\n                          variant={'body1'}\n                          paddingRight={isMobile ? '' : 2}\n                        >\n                          {t('labelReferralsTotalRefund')}\n                          {refundData.summary?.totalValue ? (\n                            <Typography\n                              variant={'inherit'}\n                              component={'span'}\n                              color={'textPrimary'}\n                              paddingLeft={1}\n                            >\n                              {refundData.summary?.totalValue + ' LRC'}\n                            </Typography>\n                          ) : (\n                            EmptyValueTag\n                          )}\n                        </Typography>\n                      </Grid>\n\n                      <Grid\n                        item\n                        md={4}\n                        xs={12}\n                        flexDirection={'row'}\n                        alignItems={'center'}\n                        display={'flex'}\n                        paddingTop={isMobile ? 1 : ''}\n                        justifyContent={isMobile ? 'space-between' : 'flex-end'}\n                      >\n                        <Typography\n                          component={'span'}\n                          color={'var(--color-text-third)'}\n                          variant={'body1'}\n                          paddingRight={isMobile ? '' : 2}\n                        >\n                          {t('labelReferralsClaimRefund')}\n\n                          {refundData.summary?.claimableValue ? (\n                            <Typography\n                              variant={'inherit'}\n                              component={'span'}\n                              color={'textPrimary'}\n                              paddingLeft={1}\n                            >\n                              {refundData.summary?.claimableValue + ' LRC'}\n                            </Typography>\n                          ) : (\n                            <Typography\n                              variant={'inherit'}\n                              component={'span'}\n                              color={'var(--color-text-third)'}\n                            >\n                              {EmptyValueTag}\n                            </Typography>\n                          )}\n                        </Typography>\n                        {refundData.summary?.claimableValue ? (\n                          <Button\n                            variant={'contained'}\n                            size={'small'}\n                            sx={{ marginLeft: 2 }}\n                            onClick={() => {\n                              history.push(`/l2assets/assets/${AssetTabIndex.Rewards}`)\n                            }}\n                          >\n                            {t('labelClaimBtn')}\n                          </Button>\n                        ) : (\n                          <></>\n                        )}\n                      </Grid>\n                    </Grid>\n                    <Box display={'flex'} flexDirection={'column'}>\n                      <RefundTable\n                        {...{\n                          rawData: refundData.record,\n                          pagination: {\n                            pageSize: 8,\n                            total: refundData.recordTotal,\n                          },\n                          getList: refundData.getRefundTableList,\n                          showloading: refundData.showLoading,\n                        }}\n                      />\n                    </Box>\n                  </BoxStyled>\n                </>\n              )}\n            </BoxStyled>\n          </Container>\n        </>\n      ) : (\n        <ErrorPage messageKey={'error404'} />\n      )}\n    </>\n  )\n}\nexport const ReferralRewardsPanel = () => {\n  return <ReferView />\n}\n"
  },
  {
    "path": "packages/web-earn/src/pages/Layer2Page/SecurityPanel/hook.ts",
    "content": "import { AccountStatus, MapChainId, myLog, UIERROR_CODE } from '@loopring-web/common-resources'\nimport { LoopringAPI, store, useAccount } from '@loopring-web/core'\nimport React from 'react'\n\nimport { AccountStep, useOpenModals } from '@loopring-web/component-lib'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nimport { ConnectProviders, connectProvides } from '@loopring-web/web3-provider'\n\nimport Web3 from 'web3'\n\nexport function useResetAccount() {\n  const { setShowResetAccount } = useOpenModals()\n\n  const resetKeypair = React.useCallback(() => {\n    setShowResetAccount({ isShow: true })\n  }, [setShowResetAccount])\n\n  return {\n    resetKeypair,\n  }\n}\n\nexport function useExportAccountInfo() {\n  const { account } = useAccount()\n\n  const { setShowExportAccount, setShowAccount } = useOpenModals()\n\n  const exportAccInfo = React.useCallback(() => {\n    if (account.readyState !== AccountStatus.ACTIVATED) {\n      return undefined\n    }\n\n    return {\n      address: account.accAddress,\n      accountId: account.accountId,\n      level: account.level,\n      nonce: account.nonce,\n      apiKey: account.apiKey,\n      publicX: account.eddsaKey.formatedPx,\n      publicY: account.eddsaKey.formatedPy,\n      privateKey: account.eddsaKey.sk,\n    }\n  }, [account])\n\n  const exportAccount = React.useCallback(async () => {\n    const _account = store.getState().account\n    const connectName = (ConnectProviders[_account.connectName] ??\n      _account.connectName) as unknown as sdk.ConnectorNames\n    const { exchangeInfo, chainId } = store.getState().system\n    const { isMobile, defaultNetwork } = store.getState().settings\n    let walletType, account\n    if (exchangeInfo && LoopringAPI.userAPI && LoopringAPI.walletAPI && LoopringAPI.exchangeAPI) {\n      try {\n        setShowAccount({\n          isShow: true,\n          step: AccountStep.ExportAccount_Approve_WaitForAuth,\n        })\n        const walletTypePromise: Promise<{ walletType: any }> =\n          window.ethereum &&\n          (_account.connectName as unknown as sdk.ConnectorNames) === sdk.ConnectorNames.MetaMask &&\n          isMobile\n            ? Promise.resolve({ walletType: undefined })\n            : LoopringAPI.walletAPI.getWalletType({\n                wallet: _account.accAddress,\n                network: MapChainId[defaultNetwork] as sdk.NetworkWallet\n              })\n        ;[{ accInfo: account }, { walletType }] = await Promise.all([\n          LoopringAPI.exchangeAPI.getAccount({\n            owner: _account.accAddress,\n          }),\n          walletTypePromise,\n        ])\n          .then((response) => {\n            if ((response[0] as sdk.RESULT_INFO)?.code) {\n              throw response[0]\n            }\n            return response\n          })\n          .catch((error) => {\n            throw error\n          })\n\n        myLog('exportAccount account:', account)\n\n        try {\n          const eddsaKey = await sdk.generateKeyPair({\n            web3: connectProvides.usedWeb3 as unknown as Web3,\n            address: account.owner,\n            chainId: chainId as any,\n            keySeed:\n              account.keySeed && _account.keySeed !== ''\n                ? _account.keySeed\n                : sdk.GlobalAPI.KEY_MESSAGE.replace(\n                    '${exchangeAddress}',\n                    exchangeInfo.exchangeAddress,\n                  ).replace('${nonce}', (account.nonce - 1).toString()),\n            walletType: connectName,\n            accountId: account.accountId,\n          })\n          if (eddsaKey.sk === _account.eddsaKey.sk) {\n            myLog('try to sendAccountSigned....')\n            setShowAccount({ isShow: false })\n            setShowExportAccount({ isShow: true })\n          } else {\n            throw {\n              code: UIERROR_CODE.ERROR_PRIVATE_KEY,\n              msg: 'Wrong private key',\n              message: 'Wrong private key',\n            }\n          }\n        } catch (error) {\n          throw error\n        }\n      } catch (e: any) {\n        myLog('ExportAccount e:', e)\n        const error = LoopringAPI.exchangeAPI.genErr(e)\n        const errType = sdk.checkErrorInfo(error, true)\n        switch (errType) {\n          case sdk.ConnectorError.USER_DENIED:\n          case sdk.ConnectorError.USER_DENIED_2:\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.ExportAccount_User_Denied,\n            })\n            return\n          default:\n            break\n        }\n        setShowAccount({\n          isShow: true,\n          step: AccountStep.ExportAccount_Failed,\n          error: {\n            code: UIERROR_CODE.UNKNOWN,\n            msg: e?.message,\n            ...e,\n          },\n        })\n      }\n    }\n  }, [setShowAccount, setShowExportAccount])\n\n  return {\n    exportAccInfo,\n    exportAccount,\n  }\n}\n"
  },
  {
    "path": "packages/web-earn/src/pages/Layer2Page/SecurityPanel/index.tsx",
    "content": "import styled from '@emotion/styled'\nimport { Box, Button, Grid, Typography } from '@mui/material'\nimport React from 'react'\nimport { Trans, WithTranslation, withTranslation } from 'react-i18next'\nimport { useResetAccount } from './hook'\nimport { useSettings } from '@loopring-web/component-lib'\nimport { useAccount } from '@loopring-web/core'\nimport {\n  MapChainId,\n  L1L2_NAME_DEFINED,\n} from '@loopring-web/common-resources'\n\nconst StyledPaper = styled(Grid)`\n  width: 100%;\n  background: var(--color-box);\n  border-radius: ${({ theme }) => theme.unit}px;\n`\n\nexport const SecurityPanel = withTranslation(['common', 'layout'])(({ t }: WithTranslation) => {\n  const { account } = useAccount()\n  const { resetKeypair } = useResetAccount()\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n\n  return (\n    <StyledPaper height={'auto'} container className={'MuiPaper-elevation2'} marginBottom={2}>\n      <Grid item xs={12} display={'flex'} flexDirection={'row'} alignItems={'center'}>\n        <Typography\n          component={'h3'}\n          variant={'h4'}\n          paddingX={5 / 2}\n          paddingTop={5 / 2}\n          paddingBottom={2}\n        >\n          {t('labelSecurity')}\n        </Typography>\n      </Grid>\n      <Grid item xs={12} display={'flex'} flexDirection={'column'} paddingY={1}>\n        {!account.isContract && !account.isInCounterFactualStatus && (\n          <Box component={'section'} display={'flex'} flexDirection={'column'} padding={5 / 2}>\n            <Grid container display={'flex'}>\n              <Grid item xs={7}>\n                <Typography variant={'h4'} color={'text.primary'} component={'h4'} marginBottom={1}>\n                  {t('labelTitleResetL2Keypair', {\n                    loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                  })}\n                </Typography>\n                <Typography variant={'body1'} color={'text.secondary'} component={'p'}>\n                  <Trans\n                    i18nKey='labelResetDescription'\n                    tOptions={{\n                      layer2: L1L2_NAME_DEFINED[network].layer2,\n                      loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                    }}\n                  >\n                    Create a new signing key for layer-2 authentication (no backup needed). This\n                    will\n                    <Typography component={'span'}>cancel all your pending orders</Typography>.\n                  </Trans>\n                </Typography>\n              </Grid>\n\n              <Grid\n                item\n                xs={5}\n                display={'flex'}\n                justifyContent={'flex-start'}\n                alignItems={'flex-end'}\n                flexDirection={'column'}\n              >\n                <Button\n                  variant={'outlined'}\n                  size={'medium'}\n                  color={'primary'}\n                  onClick={() => {\n                    resetKeypair()\n                  }}\n                  disabled={false}\n                >\n                  {t('labelBtnReset')}\n                </Button>\n              </Grid>\n            </Grid>\n          </Box>\n        )}\n      </Grid>\n    </StyledPaper>\n  )\n})\n"
  },
  {
    "path": "packages/web-earn/src/pages/Layer2Page/VipPanel/hooks.ts",
    "content": "import React from 'react'\nimport { LoopringAPI, useAccount, useTokenMap } from '@loopring-web/core'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { myLog } from '@loopring-web/common-resources'\n\nexport function useGetVIPInfo() {\n  const {\n    account: { accountId, accAddress, apiKey },\n  } = useAccount()\n  const [tradeAmountInfo, setTraeAmountInfo] = React.useState<any>(null)\n  const [userVIPInfo, setUserVIPInfo] = React.useState<any>(null)\n  const [userAssets, setUserAssets] = React.useState<any[]>([])\n\n  const { tokenMap } = useTokenMap()\n\n  const getUserTradeAmount = React.useCallback(\n    async (markets: string = '', limit: number = 30) => {\n      if (LoopringAPI && LoopringAPI.exchangeAPI && accountId) {\n        const data = await LoopringAPI.exchangeAPI.getUserTradeAmount({\n          accountId,\n          markets,\n          limit,\n        })\n        setTraeAmountInfo(data)\n      }\n    },\n    [accountId],\n  )\n\n  const getUserVIPInfo = React.useCallback(async () => {\n    if (LoopringAPI && LoopringAPI.userAPI && accountId) {\n      const data = await LoopringAPI.userAPI.getUserVIPInfo(\n        {\n          userAddress: accAddress,\n        },\n        apiKey,\n      )\n      setUserVIPInfo(data)\n    }\n  }, [accAddress, accountId, apiKey])\n\n  const getUserAssets = React.useCallback(async () => {\n    if (LoopringAPI && LoopringAPI.userAPI && tokenMap) {\n      const lrcAddress = tokenMap['LRC'].address\n      const response = await LoopringAPI.userAPI.getUserVIPAssets({\n        address: accAddress,\n        assetTypes: 'DEX',\n        token: lrcAddress,\n      })\n      if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n        myLog((response as sdk.RESULT_INFO).message)\n      } else {\n        setUserAssets(response.vipAsset as any[])\n      }\n    }\n    setUserAssets([])\n  }, [accAddress, tokenMap])\n\n  return {\n    tradeAmountInfo,\n    getUserTradeAmount,\n    userVIPInfo,\n    getUserVIPInfo,\n    userAssets,\n    getUserAssets,\n  }\n}\n"
  },
  {
    "path": "packages/web-earn/src/pages/Layer2Page/VipPanel/index.tsx",
    "content": "import styled from '@emotion/styled'\nimport { Box, Grid, LinearProgress, Link, Typography } from '@mui/material'\nimport React from 'react'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport { useHistory } from 'react-router-dom'\nimport { LoopringAPI, useAccount, useTokenMap, useWalletLayer2 } from '@loopring-web/core'\nimport { getValuePrecisionThousand, SoursURL } from '@loopring-web/common-resources'\nimport { useSettings, VipPanel as VipView } from '@loopring-web/component-lib'\nimport { useGetVIPInfo } from './hooks'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nconst StyledPaper = styled(Grid)`\n  width: 100%;\n  height: 100%;\n  background: var(--color-box);\n  border-radius: ${({ theme }) => theme.unit}px;\n`\n\nconst feeRate = {\n  vip1: {\n    eth: 75,\n    lrc: 25000,\n  },\n  vip2: {\n    eth: 750,\n    lrc: 50000,\n  },\n  vip3: {\n    eth: 3750,\n    lrc: 125000,\n  },\n  vip4: {\n    eth: 7500,\n    lrc: 250000,\n  },\n}\n\nconst rawData = [\n  {\n    level: 'VIP 0',\n    tradeVolume: '< 75 ETH',\n    rule: 'or',\n    balance: '>= 0 LRC',\n    maker: '-0.02%',\n    taker: '0.3%',\n  },\n  {\n    level: 'VIP 1',\n    tradeVolume: '>= 75 ETH',\n    rule: 'or',\n    balance: '>= 25,000 LRC',\n    maker: '-0.02%',\n    taker: '0.25%',\n  },\n  {\n    level: 'VIP 2',\n    tradeVolume: '>= 750 ETH',\n    rule: 'and',\n    balance: '>= 50,000 LRC',\n    maker: '-0.02%',\n    taker: '0.2%',\n  },\n  {\n    level: 'VIP 3',\n    tradeVolume: '>= 3750 ETH',\n    rule: 'and',\n    balance: '>= 125,000 LRC',\n    maker: '-0.02%',\n    taker: '0.15%',\n  },\n  {\n    level: 'VIP 4',\n    tradeVolume: '>= 7500 ETH',\n    rule: 'and',\n    balance: '>= 250,000 LRC',\n    maker: '-0.02%',\n    taker: '0.1%',\n  },\n]\n\nexport const VipPanel = withTranslation(['common', 'layout'])(({ t }: WithTranslation) => {\n  const {\n    account: { level },\n  } = useAccount()\n  const history = useHistory()\n  const { isMobile } = useSettings()\n  const { tokenMap } = useTokenMap()\n  const { walletLayer2 } = useWalletLayer2()\n  const currentBalanceLRC = sdk\n    .toBig(walletLayer2?.LRC?.total ?? 0)\n    .div('1e' + tokenMap?.LRC?.decimals ?? 0)\n    .toNumber()\n  const { getUserTradeAmount, tradeAmountInfo, userVIPInfo, getUserVIPInfo, getUserAssets } =\n    useGetVIPInfo()\n\n  const getVIPLevel = React.useCallback(() => {\n    if (userVIPInfo && userVIPInfo?.vipInfo?.vipTag) {\n      if (userVIPInfo.vipInfo.vipTag === 'spam') {\n        return 'vip_0'\n      }\n      return userVIPInfo.vipInfo.vipTag\n    }\n    return 'vip_0'\n  }, [userVIPInfo])\n\n  const getNextVIPlevel = React.useCallback(() => {\n    const level = getVIPLevel()\n    if (level === 'super_vip' || level === 'vip_4') {\n      return level\n    }\n    let [_, number] = getVIPLevel().toUpperCase().replace('_', ',').split(',')\n    return `${++number}`\n  }, [getVIPLevel])\n\n  const getViewTableLevel = React.useCallback(() => {\n    if (!getVIPLevel()) {\n      return 0\n    }\n    if (getVIPLevel() === 'super_vip' || getVIPLevel() === 'vip_4') {\n      return 4\n    }\n    let [_, number] = getVIPLevel().toUpperCase().replace('_', ',').split(',')\n    return number\n  }, [getVIPLevel])\n\n  const getCurrentETHTradeAmount = React.useCallback(() => {\n    if (tradeAmountInfo && !!tradeAmountInfo.raw_data.data.length) {\n      const sum: number[] = tradeAmountInfo.raw_data.data.map((o: any) => Number(o.ethValue))\n      return sum.reduce((prev, next) => prev + next, 0).toFixed(7)\n    }\n    return 0\n  }, [tradeAmountInfo])\n\n  // const [vipTable, setVipTable] = React.useState<string[][]>(vipDefault);\n  const [userFee, setUserFee] = React.useState<{\n    maker: string\n    taker: string\n  }>({\n    maker: '0',\n    taker: '0.0025%',\n  })\n\n  const isVIP4 = getVIPLevel() === 'vip_4'\n  const isSVIP = getVIPLevel() === 'super_vip'\n\n  const getNextLevelAmount = React.useCallback(\n    (type: 'lrc' | 'eth', currLevel: number) => {\n      const isLrc = type === 'lrc'\n      const amount = Math.round(\n        feeRate[`vip${currLevel}`][type] -\n          (isLrc ? currentBalanceLRC : Number(getCurrentETHTradeAmount())),\n      )\n      return amount < 0 ? 0 : amount\n    },\n    [currentBalanceLRC, getCurrentETHTradeAmount],\n  )\n\n  const getImagePath = React.useMemo(() => {\n    const path = SoursURL + `images/vips/${level.toUpperCase().replace('_', '')}`\n    return (\n      <img\n        alt='VIP'\n        style={{\n          verticalAlign: 'text-bottom',\n          width: '32px',\n          height: '16px',\n        }}\n        src={`${path}.webp`}\n        // srcSet={`${path}.webp 1x, ${path}.png 1x`}\n      />\n    )\n  }, [level])\n  const result = React.useCallback(async () => {\n    if (LoopringAPI.exchangeAPI) {\n      const {\n        // orderbookTradingFeesStablecoin,\n        orderbookTradingFees,\n        // ammTradingFees,\n        // otherFees,\n      } = await LoopringAPI.exchangeAPI.getExchangeFeeInfo()\n      const _level = level === 'super_vip' ? 'vip_4' : level === '' ? 'default' : level\n      if (orderbookTradingFees[_level]) {\n        setUserFee({\n          maker: (orderbookTradingFees[_level].makerRate / 10000).toString() + '%',\n          taker: (orderbookTradingFees[_level].takerRate / 10000).toString() + '%',\n        })\n      }\n    }\n  }, [level])\n\n  React.useEffect(() => {\n    getUserTradeAmount()\n    getUserVIPInfo()\n    getUserAssets()\n    result()\n  }, [])\n\n  const handleTradeLinkClick = React.useCallback(() => {\n    if (history) {\n      history.push('/trade/lite/LRC-ETH')\n    }\n  }, [history])\n\n  const getTradeVolETHLinear = React.useMemo(() => {\n    if (isSVIP) {\n      return 0\n    }\n    if (isVIP4) {\n      return 100\n    }\n    const rate =\n      (Number(getCurrentETHTradeAmount()) / feeRate[`vip${getNextVIPlevel()}`]['eth']) * 100\n    return rate > 100 ? 100 : rate\n  }, [isVIP4, isSVIP, getCurrentETHTradeAmount, getNextVIPlevel])\n\n  const balanceLinearLRC = React.useMemo(() => {\n    if (isSVIP) {\n      return 0\n    }\n    if (isVIP4) {\n      return 100\n    }\n    const rate = (currentBalanceLRC / feeRate[`vip${getNextVIPlevel()}`]['lrc']) * 100\n    return rate > 100 ? 100 : rate\n  }, [currentBalanceLRC, getNextVIPlevel, isSVIP, isVIP4])\n\n  const getCurrVIPLevel = React.useCallback(\n    (direction: 'left' | 'right') => {\n      const isLeft = direction === 'left'\n      const isRight = direction === 'right'\n      if (getVIPLevel() !== 'super_vip' && getVIPLevel() !== 'vip_4' && isLeft) {\n        return getVIPLevel().toUpperCase().replace('_', ' ')\n      }\n      if (getVIPLevel() !== 'super_vip' && getVIPLevel() !== 'vip_4' && isRight) {\n        let [vip, number] = getVIPLevel().toUpperCase().replace('_', ',').split(',')\n        return `${vip} ${++number}`\n      }\n      if (isSVIP && direction === 'left') {\n        return 'Super VIP'\n      }\n      if (isSVIP && direction === 'right') {\n        return ''\n      }\n      if (isVIP4) {\n        return direction === 'left' ? 'VIP 3' : 'VIP 4'\n      }\n      return ''\n    },\n    [isSVIP, isVIP4, getVIPLevel],\n  )\n\n  return (\n    <>\n      <StyledPaper\n        container\n        className={'MuiPaper-elevation2'}\n        margin={0}\n        marginBottom={2}\n        paddingBottom={5 / 2}\n        spacing={3}\n      >\n        <Grid item xs={12}>\n          <Typography component={'h3'} variant={'h4'}>\n            {t('labelVipTitle')}\n          </Typography>\n        </Grid>\n        <Grid item xs={12}>\n          <Typography\n            variant={isMobile ? 'body1' : 'h5'}\n            component={'h2'}\n            marginY={1}\n            display={'flex'}\n            flexDirection={'column'}\n          >\n            <Typography\n              component={'div'}\n              flexDirection={'row'}\n              display={'flex'}\n              alignSelf={'flex-start'}\n            >\n              <Typography\n                component={'p'}\n                variant={isMobile ? 'h5' : 'h4'}\n                color={'text.primary'}\n                paddingRight={1}\n              >\n                {t('labelTradeFeeLevel')}\n              </Typography>\n              <Typography\n                variant={'body1'}\n                component={'span'}\n                display={'flex'}\n                flexDirection={'row'}\n                alignItems={'center'}\n              >\n                <Typography component={'span'} variant={'body1'}>\n                  {level && userVIPInfo?.vipInfo?.vipTag ? getImagePath : ''}\n                </Typography>\n              </Typography>\n            </Typography>\n            <Typography\n              variant={isMobile ? 'body1' : 'h5'}\n              component={'p'}\n              color={'var(--color-text-secondary)'}\n              marginTop={2}\n            >\n              {isVIP4\n                ? 'Congratulations you have reached the highest level'\n                : isSVIP\n                ? 'Congratulations! You are already a super VIP, enjoying the highest discount privileges, and will not be affected by balance and trading volume.'\n                : `Upgrade to VIP ${getNextVIPlevel()} by either trading ${getValuePrecisionThousand(\n                    getNextLevelAmount('eth', getNextVIPlevel()),\n                  )} ETH on our spot exchange and/or increase your LRC holdings by ${getValuePrecisionThousand(\n                    getNextLevelAmount('lrc', getNextVIPlevel()),\n                  )} LRC`}\n            </Typography>\n          </Typography>\n        </Grid>\n        <Grid item xs={12} md={6}>\n          <Typography fontWeight={400} variant={'h6'} color={'var(--color-text-secondary)'}>\n            {t('labelSpotTrading')}\n          </Typography>\n          <Typography\n            display={'inline-flex'}\n            justifyContent={'space-between'}\n            alignItems={'center'}\n            width={'100%'}\n            paddingRight={2}\n          >\n            <Typography variant={isMobile ? 'h5' : 'h4'} marginTop={0.5}>\n              {t('labelCurrentlyLevel', {\n                value: getValuePrecisionThousand(getCurrentETHTradeAmount()),\n                token: 'ETH',\n              })}\n            </Typography>\n            {isMobile && (\n              <Link\n                variant={'body1'}\n                onClick={handleTradeLinkClick}\n                style={{\n                  textDecoration: 'underline',\n                  color: 'var(--color-text-secondary)',\n                }}\n              >\n                {t('labelTradeSpot')}\n              </Link>\n            )}\n          </Typography>\n          <Box width={'100%'} paddingRight={2} marginY={1.5}>\n            <LinearProgress variant='determinate' value={getTradeVolETHLinear} />\n            <Box marginTop={1} display={'flex'} justifyContent={'space-between'}>\n              <Typography\n                fontWeight={400}\n                color={isVIP4 ? 'var(--color-text-secondary)' : 'var(--color-star)'}\n              >\n                {getCurrVIPLevel('left')}\n              </Typography>\n              <Typography\n                fontWeight={400}\n                color={isSVIP || isVIP4 ? 'var(--color-star)' : 'var(--color-text-secondary)'}\n              >\n                {getCurrVIPLevel('right')}\n              </Typography>\n            </Box>\n          </Box>\n          {!isMobile && (\n            <Link\n              variant={'body1'}\n              onClick={handleTradeLinkClick}\n              style={{\n                textDecoration: 'underline',\n                color: 'var(--color-text-secondary)',\n              }}\n            >\n              {t('labelTradeSpot')}\n            </Link>\n          )}\n        </Grid>\n        <Grid item xs={12} md={6}>\n          <Typography fontWeight={400} variant={'h6'} color={'var(--color-text-secondary)'}>\n            {t('labelLRCBalance')}\n          </Typography>\n          <Typography\n            display={'inline-flex'}\n            justifyContent={'space-between'}\n            alignItems={'center'}\n            width={'100%'}\n            paddingRight={2}\n          >\n            <Typography variant={isMobile ? 'h5' : 'h4'} marginTop={0.5}>\n              {t('labelCurrentlyLevel', {\n                value: getValuePrecisionThousand(\n                  currentBalanceLRC,\n                  tokenMap?.LRC.precision,\n                  tokenMap?.LRC.precision,\n                  tokenMap?.LRC.precision,\n                  false,\n                  { floor: true },\n                ),\n                token: 'LRC',\n              })}\n            </Typography>\n            {isMobile && (\n              <Link\n                variant={'body1'}\n                onClick={handleTradeLinkClick}\n                style={{\n                  textDecoration: 'underline',\n                  color: 'var(--color-text-secondary)',\n                }}\n              >\n                {t('labelBuyToken', { token: 'LRC' })}\n              </Link>\n            )}\n          </Typography>\n          <Box width={'100%'} paddingRight={2} marginY={1.5}>\n            <LinearProgress variant='determinate' value={balanceLinearLRC} />\n            <Box marginTop={1} display={'flex'} justifyContent={'space-between'}>\n              <Typography\n                fontWeight={400}\n                color={isVIP4 ? 'var(--color-text-secondary)' : 'var(--color-star)'}\n              >\n                {getCurrVIPLevel('left')}\n              </Typography>\n              <Typography\n                fontWeight={400}\n                color={isSVIP || isVIP4 ? 'var(--color-star)' : 'var(--color-text-secondary)'}\n              >\n                {getCurrVIPLevel('right')}\n              </Typography>\n            </Box>\n          </Box>\n          {!isMobile && (\n            <Link\n              variant={'body1'}\n              onClick={handleTradeLinkClick}\n              style={{\n                textDecoration: 'underline',\n                color: 'var(--color-text-secondary)',\n              }}\n            >\n              {t('labelBuyToken', { token: 'LRC' })}\n            </Link>\n          )}\n        </Grid>\n        <Grid item xs={12}>\n          <Typography\n            variant={'h6'}\n            component={'p'}\n            fontWeight={400}\n            color={'var(--color-text-secondary)'}\n          >\n            The cumulative 30-day trading volume ( in ETH ) and 24-hour LRC balance are updated at\n            0:00 (UTC+0) each day. After the update, you can access the corresponding fee discount\n            in the table below.\n          </Typography>\n        </Grid>\n      </StyledPaper>\n      {isMobile ? (\n        <Typography variant={'body1'} paddingY={2} textAlign={'center'}>\n          For details, please view on desktop.\n        </Typography>\n      ) : (\n        <StyledPaper\n          container\n          className={'MuiPaper-elevation2'}\n          margin={0}\n          marginBottom={2}\n          spacing={3}\n        >\n          <Grid item xs={12}>\n            <Typography component={'h4'} variant={isMobile ? 'h6' : 'h5'} color={'text.secondary'}>\n              {t('labelFeeTitleList')}\n            </Typography>\n          </Grid>\n          <Grid item xs={12} paddingRight={2}>\n            <VipView rawData={rawData} currentLevel={getViewTableLevel()} />\n          </Grid>\n        </StyledPaper>\n      )}\n    </>\n  )\n})\n"
  },
  {
    "path": "packages/web-earn/src/pages/Layer2Page/index.tsx",
    "content": "import { useRouteMatch } from 'react-router-dom'\n\nimport { Box, Container } from '@mui/material'\n\nimport React from 'react'\nimport { ViewAccountTemplate } from '@loopring-web/core'\nimport { SecurityPanel } from './SecurityPanel'\nimport { VipPanel } from './VipPanel'\nimport { ForcewithdrawPanel } from './ForcewithdrawPanel'\nimport { ReferralRewardsPanel } from './ReferralRewardsPanel'\nimport { ContactPage } from './ContactPanel'\nimport { Layer2RouterID, ProfileIndex, MapChainId } from '@loopring-web/common-resources'\nimport { useSettings } from '@loopring-web/component-lib'\n\nexport const Layer2Page = () => {\n  let match: any = useRouteMatch('/layer2/:item')\n  const selected = match?.params.item ?? 'assets'\n  const { defaultNetwork } = useSettings()\n\n  const layer2Router = React.useMemo(() => {\n    let _selected\n    const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n    if (ProfileIndex[network]?.includes(selected)) {\n      _selected = selected\n    } else {\n      _selected = ''\n    }\n    switch (_selected) {\n      case Layer2RouterID.forcewithdraw:\n        return <ForcewithdrawPanel />\n      case Layer2RouterID.security:\n        return <SecurityPanel />\n      case Layer2RouterID.vip:\n        return <VipPanel />\n      case Layer2RouterID.contact:\n        return <ContactPage />\n      default:\n        return <SecurityPanel />\n    }\n  }, [selected])\n\n  return selected === Layer2RouterID.referralrewards ? (\n    <Box flex={1} display={'flex'} flexDirection={'column'}>\n      <ReferralRewardsPanel />\n    </Box>\n  ) : (\n    <Container\n      maxWidth='lg'\n      style={{\n        display: 'flex',\n        flexDirection: 'column',\n        flex: 1,\n      }}\n    >\n      <Box display={'flex'} flex={1} alignItems={'stretch'} flexDirection={'column'} marginTop={3}>\n        <ViewAccountTemplate activeViewTemplate={layer2Router} />\n      </Box>\n    </Container>\n  )\n  // <>{viewTemplate}</>;\n}\n"
  },
  {
    "path": "packages/web-earn/src/pages/LoadingPage/index.tsx",
    "content": "import { useTranslation } from 'react-i18next'\nimport { Box } from '@mui/material'\nimport styled from '@emotion/styled'\n// import { ErrorObject } from '@loopring-web/common-resources';\n// import { getContactInfo } from '../../utils/dt_tools';\nimport { boxLiner } from '@loopring-web/component-lib'\nimport { SoursURL } from '@loopring-web/common-resources'\nimport React from 'react'\n// ${({theme}) => boxLiner({theme})}\nconst StyleBox = styled(Box)`\n  //background: var(--color-mask);\n  ${({ theme }) => boxLiner({ theme })}\n\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  left: 0;\n  right: 0;\n  width: 0;\n  z-index: 500;\n  height: 100%;\n  width: 100%;\n  svg path,\n  svg rect {\n    fill: var(--color-primary);\n  }\n` as typeof Box\n\nexport const LoadingPage = () => {\n  const { t } = useTranslation('layout')\n  return (\n    <>\n      {/*<Container>*/}\n      {/*style={{height: '100%' }}*/}\n      <StyleBox\n        flex={1}\n        display={'flex'}\n        alignItems={'center'}\n        justifyContent={'center'}\n        flexDirection={'column'}\n        height={'100%'}\n        width={'100%'}\n      >\n        <div className='loader loader--style3' title='2'>\n          <img\n            className='loading-gif'\n            alt={'loading'}\n            width='36'\n            src={`${SoursURL}images/loading-line.gif`}\n          />\n        </div>\n      </StyleBox>\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/web-earn/src/pages/MarkdownPage/index.tsx",
    "content": "import { Box, Grid } from '@mui/material'\nimport { useRouteMatch, useLocation } from 'react-router-dom'\nimport React from 'react'\nimport { EmptyDefault, LoadingBlock } from '@loopring-web/component-lib'\nimport Template from 'easy-template-string'\nimport gfm from 'remark-gfm'\nimport ReactMarkdown from 'react-markdown'\nimport { useTheme } from '@emotion/react'\n\nimport { useTranslation } from 'react-i18next'\nimport { MarkdownStyle } from '@loopring-web/common-resources'\n\nconst url_path = 'https://static.loopring.io/documents'\n\nconst formatInput = async (textContent: string): Promise<string> => {\n  // let [data, content] = args;\n  const data = await fetch('https://api3.loopring.io/api/v2/exchange/feeInfo')\n    .then((res) => res.json())\n    .then((data) => data.data)\n  let { ORDERBOOK_TRADING_FEES_STABLECOIN, ORDERBOOK_TRADING_FEES, AMM_TRADING_FEES } = data\n  ORDERBOOK_TRADING_FEES_STABLECOIN = Object.keys(ORDERBOOK_TRADING_FEES_STABLECOIN).reduce(\n    (pre, key) => {\n      pre['ORDERBOOK_TRADING_FEES_STABLECOIN.' + key] = (\n        ORDERBOOK_TRADING_FEES_STABLECOIN[key].takerRate / 100\n      ).toFixed(2)\n      return pre\n    },\n    {},\n  )\n  ORDERBOOK_TRADING_FEES = Object.keys(ORDERBOOK_TRADING_FEES).reduce((pre, key) => {\n    pre['ORDERBOOK_TRADING_FEES.' + key] = (ORDERBOOK_TRADING_FEES[key].takerRate / 100).toFixed(2)\n    return pre\n  }, {})\n  AMM_TRADING_FEES = Object.keys(AMM_TRADING_FEES).reduce((pre, key) => {\n    pre['AMM_TRADING_FEES.' + key] = (AMM_TRADING_FEES[key].takerRate / 100).toFixed(2)\n    return pre\n  }, {})\n  const template1 = new Template(textContent)\n  return template1.interpolate({\n    ...ORDERBOOK_TRADING_FEES_STABLECOIN,\n    ...ORDERBOOK_TRADING_FEES,\n    ...AMM_TRADING_FEES,\n  })\n}\nconst list = ['wallet_fees_zh.md', 'wallet_fees_en.md', 'dex_fees_en.md', 'dex_fees_zh.md']\nexport const MarkdownPage = () => {\n  const location = useLocation()\n  const path = location.pathname.split('/').slice(2).join('/')\n  const [input, setInput] = React.useState<string>('')\n  const { t } = useTranslation('common')\n  React.useEffect(() => {\n    if (path) {\n      try {\n        const _path = `markdown/${path}`\n        fetch(url_path + '/' + _path)\n          .then((response) => response.text())\n          .then((input) => {\n            if (list.findIndex((f) => f === path) !== -1) {\n              return formatInput(input)\n            } else {\n              return input\n            }\n          })\n          .then((input) => {\n            setInput(input)\n          })\n          .catch(() => {})\n      } catch (e: any) {}\n    }\n  }, [path])\n  const theme = useTheme()\n\n  return (\n    <MarkdownStyle\n      container\n      minHeight={'calc(100% - 260px)'}\n      flex={1}\n      marginTop={3}\n      marginBottom={2}\n    >\n      <Grid item xs={12}>\n        {path ? (\n          input ? (\n            <Box\n              flex={1}\n              padding={3}\n              boxSizing={'border-box'}\n              className={`${theme.mode}  ${theme.mode}-scheme markdown-body MuiPaper-elevation2`}\n            >\n              <ReactMarkdown remarkPlugins={[gfm]} children={input} />\n            </Box>\n          ) : (\n            <LoadingBlock />\n          )\n        ) : (\n          <EmptyDefault\n            height={'100%'}\n            message={() => (\n              <Box flex={1} display={'flex'} alignItems={'center'} justifyContent={'center'}>\n                {t('labelNoContent')}\n              </Box>\n            )}\n          />\n        )}\n      </Grid>\n    </MarkdownStyle>\n  )\n}\n\nexport * from './notifyMarkdown'\nexport * from './investMarkdown'\n"
  },
  {
    "path": "packages/web-earn/src/pages/MarkdownPage/investMarkdown.tsx",
    "content": "import { Box, Grid } from '@mui/material'\nimport { useLocation, useRouteMatch } from 'react-router-dom'\nimport React from 'react'\nimport { EmptyDefault, LoadingBlock } from '@loopring-web/component-lib'\nimport gfm from 'remark-gfm'\nimport ReactMarkdown from 'react-markdown'\nimport { useTheme } from '@emotion/react'\n\nimport { MarkdownStyle, url_test_path } from '@loopring-web/common-resources'\nimport { useTranslation } from 'react-i18next'\nimport { useNotify, useSystem } from '@loopring-web/core'\n\nconst url_path = 'https://static.loopring.io/documents/notification'\nexport const InvestMarkdownPage = () => {\n  let match: any = useRouteMatch('/invest/:path')\n  const { i18n, t } = useTranslation()\n  const { search } = useLocation()\n  const { notifyMap } = useNotify()\n  const searchParams = new URLSearchParams(search)\n  const { baseURL } = useSystem()\n  // const history = useHistory();\n\n  const [input, setInput] = React.useState<string>('')\n  //\n  const [path, setPath] = React.useState<null | string>(match?.params.path)\n  React.useEffect(() => {\n    if (baseURL) {\n      try {\n        // follow /2021/01/2021-01-01.en.json\n        const [year, month] = match?.params.path.split('-')\n        const type = searchParams.get('type')\n        const index =\n          notifyMap?.invest.investAdvice.findIndex((invest) => invest.type === type) ?? -1\n        let filePath = ''\n        if (notifyMap?.invest && index >= 0) {\n          filePath = notifyMap.invest[index].linkRule\n        } else {\n          const path = `${/uat/gi.test(baseURL) ? url_test_path : url_path}/${year}/${month}/`\n          filePath = `${path}/invest/${type}_rule.en.md`\n        }\n        if (year && month && filePath !== '') {\n          fetch(filePath)\n            .then((response) => response.text())\n            .then((input) => {\n              setInput(input)\n            })\n            .catch((e) => {\n              setPath(null)\n            })\n        } else {\n          throw 'url format wrong'\n        }\n      } catch (e: any) {\n        setPath(null)\n      }\n    }\n  }, [baseURL, i18n.language])\n\n  const theme = useTheme()\n\n  return (\n    <MarkdownStyle\n      container\n      minHeight={'calc(100% - 260px)'}\n      flex={1}\n      marginTop={3}\n      marginBottom={2}\n    >\n      <Grid item xs={12}>\n        {path ? (\n          input ? (\n            <Box\n              flex={1}\n              padding={3}\n              boxSizing={'border-box'}\n              className={`${theme.mode}  ${theme.mode}-scheme markdown-body MuiPaper-elevation2`}\n            >\n              <ReactMarkdown remarkPlugins={[gfm]} children={input} />\n            </Box>\n          ) : (\n            <LoadingBlock />\n          )\n        ) : (\n          <EmptyDefault\n            height={'100%'}\n            message={() => (\n              <Box flex={1} display={'flex'} alignItems={'center'} justifyContent={'center'}>\n                {t('labelNoContent')}\n              </Box>\n            )}\n          />\n        )}\n      </Grid>\n    </MarkdownStyle>\n  )\n}\n"
  },
  {
    "path": "packages/web-earn/src/pages/MarkdownPage/notifyMarkdown.tsx",
    "content": "import { Box, Grid } from '@mui/material'\nimport { useRouteMatch } from 'react-router-dom'\nimport React from 'react'\nimport { EmptyDefault, LoadingBlock } from '@loopring-web/component-lib'\nimport gfm from 'remark-gfm'\nimport ReactMarkdown from 'react-markdown'\nimport { useTheme } from '@emotion/react'\n\nimport { languageMap, MarkdownStyle } from '@loopring-web/common-resources'\nimport { useTranslation } from 'react-i18next'\n\nconst url_path = 'https://static.loopring.io/documents/notification'\nexport const NotifyMarkdownPage = () => {\n  let match: any = useRouteMatch('/notification/:path')\n  const { i18n, t } = useTranslation()\n  const [input, setInput] = React.useState<string>('')\n\n  const [path, setPath] = React.useState<null | string>(match?.params.path)\n  React.useEffect(() => {\n    if (path) {\n      try {\n        const _path =\n          path.split('/').length > 1 ? path : `${path.replace('{lng}', languageMap[i18n.language])}`\n\n        fetch(url_path + '/' + _path)\n          .then((response) => response.text())\n          .then((input) => {\n            setInput(input)\n          })\n          .catch(() => {\n            setPath(null)\n          })\n      } catch (e: any) {\n        setPath(null)\n      }\n    }\n  }, [path])\n  const theme = useTheme()\n\n  return (\n    <MarkdownStyle\n      container\n      minHeight={'calc(100% - 260px)'}\n      flex={1}\n      marginTop={3}\n      marginBottom={2}\n    >\n      <Grid item xs={12}>\n        {path ? (\n          input ? (\n            <Box\n              flex={1}\n              padding={3}\n              boxSizing={'border-box'}\n              className={`${theme.mode}  ${theme.mode}-scheme markdown-body MuiPaper-elevation2`}\n            >\n              <ReactMarkdown\n                remarkPlugins={[gfm]}\n                children={input}\n                // escapeHtml={false}\n              />\n            </Box>\n          ) : (\n            <LoadingBlock />\n          )\n        ) : (\n          <EmptyDefault\n            height={'100%'}\n            message={() => (\n              <Box flex={1} display={'flex'} alignItems={'center'} justifyContent={'center'}>\n                {t('labelNoContent')}\n              </Box>\n            )}\n          />\n        )}\n      </Grid>\n    </MarkdownStyle>\n  )\n}\n"
  },
  {
    "path": "packages/web-earn/src/pages/QuotePage/hook.ts",
    "content": "import React, { useCallback } from 'react'\n\nimport { QuoteTableRawDataItem } from '@loopring-web/component-lib'\nimport { WsTopicType } from '@loopring-web/loopring-sdk'\n\nimport { RowConfig, SagaStatus, TableFilterParams } from '@loopring-web/common-resources'\nimport _ from 'lodash'\nimport {\n  favoriteMarket as favoriteMarketReducer,\n  LAYOUT,\n  LoopringAPI,\n  store,\n  tickerService,\n  useNotify,\n  useSocket,\n  useSystem,\n  useTicker,\n  useTokenMap,\n  useTokenPrices,\n} from '@loopring-web/core'\nimport { useHistory } from 'react-router-dom'\n\nexport function useTickList<C extends { [key: string]: string }>() {\n  const [tickList, setTickList] = React.useState<any>([])\n  const { marketArray, coinMap, marketMap, tokenMap, status: tokenMapStatus } = useTokenMap()\n\n  const { forexMap } = useSystem()\n  const { tickerMap, status: tickerStatus } = useTicker()\n  const { tokenPrices } = useTokenPrices()\n  const updateRawData = React.useCallback(async () => {\n    let _recommendationsFloat: QuoteTableRawDataItem[] = []\n    let defaultRecommendationsFloat: QuoteTableRawDataItem[] = []\n    const _tickList =\n      tickerMap && Object.keys(tickerMap)\n        ? Reflect.ownKeys(tickerMap).reduce((prev, key) => {\n            // @ts-ignore\n            const [, coinA, coinB] = key.match(/(\\w+)-(\\w+)/i)\n            const ticker = tickerMap[key as string]\n            const coinApriceU = ticker.close * (tokenPrices[coinB] ?? 0) ?? tokenPrices[coinB] ?? 0\n            let _item: QuoteTableRawDataItem = {\n              ...ticker,\n              pair: {\n                coinA,\n                coinB,\n              },\n              coinApriceU,\n            } as QuoteTableRawDataItem\n\n            if (marketArray && marketArray.findIndex((m) => m === key) !== -1) {\n              defaultRecommendationsFloat.push(_.cloneDeep(_item))\n            }\n            prev.push(_item)\n            return prev\n          }, [] as QuoteTableRawDataItem[])\n        : []\n\n    const newTickListWithPrecision = _tickList\n      .filter((o: any) => {\n        const pair = o.__rawTicker__.symbol\n        return marketMap ? marketMap[pair]?.enabled : undefined\n      })\n      .map((o: any) => {\n        const pair = o.__rawTicker__.symbol\n        const precision = marketMap ? marketMap[pair]?.precisionForPrice : undefined\n        return {\n          ...o,\n          precision,\n        }\n      })\n\n    setTickList(newTickListWithPrecision)\n    while (_recommendationsFloat.length < 4) {\n      _recommendationsFloat.push(_.cloneDeep(_recommendationsFloat[0]))\n    }\n  }, [coinMap, forexMap, marketArray, marketMap, tokenMap, tokenPrices, tickerMap])\n\n  React.useEffect(() => {\n    if (tickerStatus === SagaStatus.UNSET && tokenMapStatus === SagaStatus.UNSET) {\n      updateRawData()\n    }\n  }, [tickerStatus, tokenMapStatus])\n  return {\n    tickList,\n    tickerMap,\n    updateRawData,\n  }\n}\n\nexport function useQuote<C extends { [key: string]: string }>() {\n  const { sendSocketTopic, socketEnd } = useSocket()\n  const { marketArray } = store.getState().tokenMap\n  const { tickList } = useTickList()\n  const subject = React.useMemo(() => tickerService.onSocket(), [])\n\n  React.useEffect(() => {\n    const subscription = subject.subscribe(({ tickerMap }) => {})\n    return () => subscription.unsubscribe()\n  }, [subject])\n\n  const socketSendTicker = React.useCallback(() => {\n    sendSocketTopic({ [WsTopicType.ticker]: marketArray })\n  }, [marketArray])\n\n  React.useEffect(() => {\n    socketSendTicker()\n    return () => {\n      socketEnd()\n    }\n  }, [])\n\n  return {\n    tickList,\n  }\n}\n\nexport const useQuotePage = ({ tableRef }: { tableRef: React.Ref<any> }) => {\n  const { status: tickerStatus } = useTicker()\n  const { marketMap } = useTokenMap()\n  const [ammPoolBalances, setAmmPoolBalances] = React.useState<any[]>([])\n  const [tableTabValue, setTableTabValue] = React.useState(TableFilterParams.all)\n  const { campaignTagConfig } = useNotify().notifyMap ?? {}\n  const [searchValue, setSearchValue] = React.useState<string>('')\n\n  const [filteredData, setFilteredData] = React.useState<QuoteTableRawDataItem[]>([])\n  const [tableHeight, setTableHeight] = React.useState(0)\n\n  const { favoriteMarket, removeMarket, addMarket } = favoriteMarketReducer.useFavoriteMarket()\n\n  const { tickList } = useQuote()\n  const handleCurrentScroll = React.useCallback((currentTarget, tableRef) => {\n    if (currentTarget && tableRef.current) {\n      const calcHeight = tableRef.current?.offsetTop - LAYOUT.HEADER_HEIGHT - currentTarget.scrollY\n      if (calcHeight < 2) {\n        tableRef.current.classList.add('fixed')\n      } else {\n        tableRef.current.classList.remove('fixed')\n      }\n    }\n  }, [])\n  const currentScroll = React.useCallback(\n    (event) => {\n      handleCurrentScroll(event.currentTarget, tableRef)\n    },\n    [handleCurrentScroll, tableRef],\n  )\n  const resetTableData = React.useCallback(\n    (tableData) => {\n      setFilteredData(tableData)\n      setTableHeight(RowConfig.rowHeaderHeight + tableData.length * RowConfig.rowHeight)\n    },\n    [setFilteredData, setTableHeight],\n  )\n  React.useEffect(() => {\n    window.addEventListener('scroll', currentScroll)\n    return () => {\n      window.removeEventListener('scroll', currentScroll)\n    }\n  }, [currentScroll])\n\n  const getAmmPoolBalances = React.useCallback(async () => {\n    if (LoopringAPI.ammpoolAPI) {\n      const ammRes = await LoopringAPI.ammpoolAPI?.getAmmPoolBalances<any[]>()\n      const fomattedRes = ammRes?.raw_data.map((o: any) => ({\n        ...o,\n        poolName: o.poolName.replace('AMM-', ''),\n      }))\n      setAmmPoolBalances(fomattedRes)\n    }\n  }, [])\n\n  React.useEffect(() => {\n    getAmmPoolBalances()\n  }, [])\n\n  let history = useHistory()\n\n  // prevent amm risky pair\n  const getFilteredTickList = React.useCallback(() => {\n    if (tickList && !!tickList.length) {\n      return tickList.filter((o: any) => {\n        const pair = `${o.pair.coinA}-${o.pair.coinB}`\n        const status = ('00' + marketMap[pair]?.status?.toString(2)).split('')\n        if (status[status.length - 2] === '1') {\n          return true\n        } else if (\n          status[status.length - 1] === '1' &&\n          ammPoolBalances.find((o) => o.poolName === pair)\n        ) {\n          return !ammPoolBalances.find((o) => o.poolName === pair).risky\n        }\n      })\n    }\n    return []\n  }, [tickList, ammPoolBalances, marketMap])\n\n  React.useEffect(() => {\n    if (tickerStatus === SagaStatus.UNSET && tickList.length) {\n      // const data = getFilteredTickList();\n      handleTableFilterChange({})\n    }\n  }, [ammPoolBalances, tickerStatus, tickList])\n\n  const handleTableFilterChange = React.useCallback(\n    ({\n      type = tableTabValue,\n      keyword = searchValue,\n    }: {\n      type?: TableFilterParams\n      keyword?: string\n    }) => {\n      let data = _.cloneDeep(tickList)\n      // myLog(\"tickList\", data);\n      if (type === TableFilterParams.favourite) {\n        data = data.filter((o: any) => {\n          const pair = `${o.pair.coinA}-${o.pair.coinB}`\n          return favoriteMarket?.includes(pair)\n        })\n      }\n      data = data.filter((o: any) => {\n        const formattedKeyword = keyword?.toLocaleLowerCase()\n        const coinA = o.pair.coinA.toLowerCase()\n        const coinB = o.pair.coinB.toLowerCase()\n        if (keyword === '') {\n          return true\n        }\n        return coinA?.includes(formattedKeyword) || coinB?.includes(formattedKeyword)\n      })\n      if (type === TableFilterParams.all && !keyword) {\n        data = getFilteredTickList()\n      }\n      resetTableData(data)\n    },\n    [\n      tickList,\n      tableTabValue,\n      resetTableData,\n      favoriteMarket,\n      // swapRankingList,\n      getFilteredTickList,\n    ],\n  )\n\n  const handleRowClick = useCallback(\n    (row: QuoteTableRawDataItem) => {\n      const { coinA, coinB } = row.pair\n      const tradePair = `${coinA}-${coinB}`\n      history &&\n        history.push({\n          pathname: `/trade/lite/${tradePair}`,\n        })\n    },\n    [history],\n  )\n\n  const handleTabChange = useCallback(\n    (_event: any, newValue: TableFilterParams) => {\n      // if (tickList?.length) {\n      setTableTabValue(newValue)\n      handleTableFilterChange({\n        keyword: searchValue,\n        type: newValue,\n      })\n      // }\n    },\n    [handleTableFilterChange, searchValue],\n  )\n\n  const handleSearchChange = React.useCallback(\n    (value) => {\n      setSearchValue(value)\n      handleTableFilterChange({ keyword: value, type: tableTabValue })\n    },\n    [handleTableFilterChange, tableTabValue],\n  )\n\n  return {\n    campaignTagConfig,\n    tableTabValue,\n    handleTabChange,\n    searchValue,\n    removeMarket,\n    favoriteMarket,\n    handleSearchChange,\n    addMarket,\n    showLoading: !tickList?.length,\n    tickList,\n    filteredData,\n    tableHeight,\n    handleRowClick,\n  }\n}\n"
  },
  {
    "path": "packages/web-earn/src/pages/QuotePage/index.tsx",
    "content": "import React from 'react'\nimport { InputSearch, QuoteTable } from '@loopring-web/component-lib'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport { RowConfig } from '@loopring-web/common-resources'\nimport { Box, Container, Divider, Tab, Tabs } from '@mui/material'\nimport { useQuotePage } from './hook'\nimport { TableWrapStyled, useAccount, useSystem } from '@loopring-web/core'\nexport const QuotePage = withTranslation('common')(({ t, ...rest }: WithTranslation) => {\n  const tableRef = React.useRef<HTMLDivElement>()\n  const { account } = useAccount()\n  const { forexMap } = useSystem()\n  const {\n    tableTabValue,\n    handleTabChange,\n    searchValue,\n    removeMarket,\n    favoriteMarket,\n    handleSearchChange,\n    addMarket,\n    tableHeight,\n    filteredData,\n    showLoading,\n    campaignTagConfig,\n    handleRowClick,\n  } = useQuotePage({ tableRef })\n  return (\n    <Box\n      display={'flex'}\n      flexDirection={'column'}\n      flex={1}\n      bgcolor={'var(--color-box-third)'}\n      borderRadius={2}\n    >\n      <TableWrapStyled\n        ref={tableRef as any}\n        paddingBottom={1}\n        flex={1}\n        bgcolor={'var(--color-box)'}\n        className={'MuiPaper-elevation2'}\n      >\n        <Box display={'flex'} flexDirection={'column'}>\n          <Container className={'toolbar'}>\n            <Box\n              paddingLeft={1}\n              paddingRight={2}\n              display={'flex'}\n              flexDirection={'row'}\n              justifyContent={'space-between'}\n              alignItems={'center'}\n            >\n              <Tabs\n                value={tableTabValue}\n                onChange={handleTabChange}\n                disabled={showLoading}\n                aria-label='Market Switch'\n              >\n                <Tab label={t('labelQuotePageFavourite')} value='favourite' />\n                <Tab label={t('labelAll')} value='all' />\n              </Tabs>\n              <InputSearch value={searchValue} onChange={handleSearchChange} />\n            </Box>\n            <Divider style={{ marginTop: '-1px' }} />\n          </Container>\n\n          <QuoteTable /* onVisibleRowsChange={onVisibleRowsChange} */\n            onRowClick={(index: any, row: any, col: any) => handleRowClick(row)}\n            campaignTagConfig={campaignTagConfig ?? ({} as any)}\n            forexMap={forexMap as any}\n            account={account}\n            rawData={filteredData}\n            favoriteMarket={favoriteMarket}\n            addFavoriteMarket={addMarket}\n            removeFavoriteMarket={removeMarket}\n            currentheight={tableHeight}\n            rowHeight={RowConfig.rowHeight}\n            headerRowHeight={RowConfig.rowHeaderHeight}\n            showLoading={showLoading}\n            {...{ ...rest }}\n          />\n        </Box>\n      </TableWrapStyled>\n    </Box>\n  )\n})\n"
  },
  {
    "path": "packages/web-earn/src/pages/QuotePage/useMaket.ts",
    "content": "import {\n  RowConfig,\n  RowConfigType,\n  TableFilterParams,\n  TickerNew,\n} from '@loopring-web/common-resources'\nimport React, { useCallback } from 'react'\nimport {\n  favoriteVaultMarket as favoriteMarketReducer,\n  LAYOUT,\n  store,\n  TokenMap,\n  useAccount,\n  useSystem,\n} from '@loopring-web/core'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nexport const useMarket = <\n  R extends TickerNew & { cmcTokenId: number; isFavorite: boolean },\n  T = sdk.TokenInfo,\n>({\n  tableRef,\n  rowConfig = RowConfig,\n  tickerMap,\n  handleRowClick,\n  handleItemClick,\n  tokenMap = store.getState()?.tokenMap?.tokenMap,\n}: {\n  tickerMap: { [key: string]: R }\n  tableRef: React.Ref<any>\n  rowConfig?: RowConfigType\n  handleRowClick?: (index: number, props: T & R) => void\n  handleItemClick?: (index: number, props: T & R) => void\n  tokenMap: TokenMap<any>\n}) => {\n  const { account } = useAccount()\n  // const { marketMap, tokenMap } = useTokenMap()\n  const [tableTabValue, setTableTabValue] = React.useState(TableFilterParams.all)\n  const [searchValue, setSearchValue] = React.useState<string>('')\n  const [filteredData, setFilteredData] = React.useState<(sdk.TokenInfo & R)[]>([])\n  const [tableHeight, setTableHeight] = React.useState(0)\n  const { favoriteMarket, removeMarket, addMarket } = favoriteMarketReducer.useFavoriteVaultMarket()\n\n  // const { tickList } = useQuote()\n  const handleCurrentScroll = React.useCallback((currentTarget, tableRef) => {\n    if (currentTarget && tableRef.current) {\n      const calcHeight = tableRef.current?.offsetTop - LAYOUT.HEADER_HEIGHT - currentTarget.scrollY\n      if (calcHeight < 2) {\n        tableRef.current.classList.add('fixed')\n      } else {\n        tableRef.current.classList.remove('fixed')\n      }\n    }\n  }, [])\n  const currentScroll = React.useCallback(\n    (event) => {\n      handleCurrentScroll(event.currentTarget, tableRef)\n    },\n    [handleCurrentScroll, tableRef],\n  )\n\n  const handleTableFilterChange = React.useCallback(\n    ({\n      type = tableTabValue,\n      // keyword,\n      ...rest\n    }: {\n      type?: TableFilterParams\n      keyword?: string\n    }) => {\n      let filter = ''\n      const favoriteMarket = store.getState().localStore.favoriteVaultMarket\n      setSearchValue((state) => {\n        filter = state\n        if (rest.hasOwnProperty('keyword')) {\n          filter = rest.keyword ?? ''\n        }\n        return filter\n      })\n      let data: Array<R & sdk.TokenInfo> = Object.values(tickerMap) ?? []\n      data = data\n      .filter((item) => {\n        if (!(item as any).vaultTokenAmounts) {\n          return false\n        }\n        const status = (item as any).vaultTokenAmounts.status as number\n        return item.enabled && status & 1\n      })\n      .map((item) => {\n        return {\n          ...tokenMap[item.symbol],\n          ...item,\n          isFavorite: favoriteMarket?.includes(item.symbol),\n        }\n      })\n      if (type === TableFilterParams.favourite) {\n        // myLog(\"tickList\", data);\n        data = data.filter((item) => {\n          return favoriteMarket?.includes(item.symbol)\n        })\n      }\n      if (filter) {\n        data = data.filter((o: any) => {\n          return new RegExp(filter, 'ig').test(o.symbol)\n        })\n      }\n      setFilteredData(data)\n      setTableHeight(\n        (rowConfig.rowHeaderHeight ?? RowConfig.rowHeaderHeight) +\n          data.length * (rowConfig?.rowHeight ?? RowConfig.rowHeaderHeight),\n      )\n    },\n    [\n      tickerMap,\n      tableTabValue,\n\n      searchValue,\n\n      // swapRankingList,\n      // getFilteredTickList,\n    ],\n  )\n\n  const handleTabChange = useCallback(\n    (_event: any, newValue: TableFilterParams) => {\n      // if (tickList?.length) {\n      setTableTabValue(newValue)\n      handleTableFilterChange({\n        keyword: searchValue,\n        type: newValue,\n      })\n      // }\n    },\n    [handleTableFilterChange, searchValue],\n  )\n\n  const handleSearchChange = React.useCallback(\n    (value) => {\n      handleTableFilterChange({ keyword: value, type: tableTabValue })\n    },\n    [tableTabValue],\n  )\n  const { forexMap } = useSystem()\n\n  return {\n    campaignTagConfig: {} as any,\n    tableTabValue,\n    handleTabChange,\n    searchValue,\n    handleStartClick: (symbol: string, rowIdx) => {\n      if (favoriteMarket.includes(symbol)) {\n        removeMarket(symbol)\n      } else {\n        addMarket(symbol)\n      }\n      handleTableFilterChange({})\n    },\n    favoriteMarket,\n    handleSearchChange,\n    addFavoriteMarket: addMarket,\n    showLoading: !Object.keys(tickerMap ?? {})?.length,\n    // tickList,\n    rawData: filteredData,\n    currentheight: tableHeight,\n    onRowClick: handleRowClick,\n    account,\n    forexMap,\n    rowConfig,\n    handleTableFilterChange,\n    onItemClick: handleItemClick,\n  }\n}\n"
  },
  {
    "path": "packages/web-earn/src/pages/TaikoLockPage/BannerPage.tsx",
    "content": "import React from 'react'\nimport { Box, Typography, Link } from '@mui/material'\nimport { MaxWidthContainer } from '@loopring-web/component-lib'\nimport { useTheme } from '@emotion/react'\nimport { SoursURL } from '@loopring-web/common-resources'\nimport { useTranslation } from 'react-i18next'\n\nconst BannerPage: React.FC = () => {\n  const theme = useTheme()\n  const { t } = useTranslation('common')\n\n  return (\n    <MaxWidthContainer>\n      <Typography mt={10} variant='h3'>\n        {t(\"labelTaikoLockEarn\")}\n      </Typography>\n      <Typography mt={3} variant='h4'>\n        {t(\"labelTaikoLockEarnDes\")}\n      </Typography>\n\n      <Box\n        sx={{\n          backgroundColor: 'var(--color-box-third)',\n          borderRadius: '48px',\n          justifyContent: 'center',\n          px: '12%',\n          py: 12.75,\n          mt: 7,\n          mb: 15,\n        }}\n      >\n        <Box display={'flex'} flexDirection={'column'}>\n          <Box\n            mb={16}\n            display={'flex'}\n            flexDirection={'row'}\n            alignItems={'center'}\n            justifyContent={'space-between'}\n          >\n            <Box width={'45%'} display={'flex'} justifyContent={'center'}>\n              <Box\n                component={'img'}\n                width={'70%'}\n                src={`${SoursURL}images/web-earn/taiko_farming_intro1_${theme.mode}.png`}\n              />\n            </Box>\n            <Typography width={'45%'} variant='h4'>\n              {t('labelTaikoFarmingQuestion')}\n            </Typography>\n          </Box>\n          <Box\n            mb={16}\n            display={'flex'}\n            flexDirection={'row-reverse'}\n            alignItems={'center'}\n            justifyContent={'space-between'}\n          >\n            <Box width={'45%'} display={'flex'} justifyContent={'center'}>\n              <Box\n                component={'img'}\n                width={'90%'}\n                src={`${SoursURL}images/web-earn/taiko_farming_intro2_${theme.mode}.png`}\n              />\n            </Box>\n            <Typography width={'45%'} variant='h4'>\n              {t('labelTaikoFarmingExplanation')}\n            </Typography>\n          </Box>\n          <Box\n            display={'flex'}\n            flexDirection={'row'}\n            alignItems={'center'}\n            justifyContent={'space-between'}\n          >\n            <Box width={'45%'} display={'flex'} justifyContent={'center'}>\n              <Box\n                component={'img'}\n                width={'90%'}\n                src={`${SoursURL}images/web-earn/taiko_farming_intro3_${theme.mode}.png`}\n              />\n            </Box>\n            <Typography width={'45%'} variant='h4'>\n              {t('labelTaikoFarmingPortalIntegration')}\n            </Typography>\n          </Box>\n        </Box>\n        <Box mt={12.5}>\n          <Typography variant='h4'>{t('labelTaikoFarmingStayTuned')}</Typography>\n          <Typography mt={2} variant='h4'>\n            {t('labelTaikoFarmingExploreUseCase')}\n            <Link href='/#/portal' color='secondary'>\n              {t('labelTaikoFarmingHereLink')}\n            </Link>\n            {t('labelTaikoFarmingDepositAnytime')}\n          </Typography>\n        </Box>\n      </Box>\n    </MaxWidthContainer>\n  )\n}\n\nexport default BannerPage\n"
  },
  {
    "path": "packages/web-earn/src/pages/TaikoLockPage/LogInToCleanLrTaiko.tsx",
    "content": "import { Box, Typography, Modal } from '@mui/material'\nimport { CloseIcon } from '@loopring-web/common-resources'\nimport _ from 'lodash'\nimport { Button } from '@loopring-web/component-lib'\n\ntype LogInToCleanLrTaikoModalModalProps = {\n  open: boolean\n  onClose: () => void\n  onClickSignIn: () => void\n}\n\nexport const LogInToCleanLrTaikoModalModal = (props: LogInToCleanLrTaikoModalModalProps) => {\n  const { open, onClose, onClickSignIn } = props\n\n  return (\n    <Modal open={open} onClose={onClose}>\n      <Box height={'100%'} display={'flex'} justifyContent={'center'} alignItems={'center'}>\n        <Box\n          bgcolor={'var(--color-box)'}\n          width={'var(--modal-width)'}\n          borderRadius={1}\n          display={'flex'}\n          flexDirection={'column'}\n          position={'relative'}\n          p={4}\n          pt={5}\n          minHeight={'428px'}\n          alignItems={'center'}\n          justifyContent={'space-between'}\n        >\n          <CloseIcon\n            className='custom-size'\n            style={{\n              color: 'var(--color-text-secondary)',\n              width: '20px',\n              height: '20px',\n              cursor: 'pointer',\n              position: 'absolute',\n              right: 16,\n              top: 16,\n            }}\n            onClick={onClose}\n          />\n          <Typography color={'var(--color-text-primary)'} variant='h4' textAlign={'center'}>\n            Clean Up lrTAIKO Dust\n          </Typography>\n          <Typography color={'var(--color-text-secondary)'} my={5}>\n            You have remaining lrTAIKO dust in your account from previous Taiko Farming activities.\n            To deposit TAIKO into the Loopring Protocol again, you must first transfer these dust\n            tokens to the Loopring operator.\n          </Typography>\n          <Button fullWidth variant='contained' onClick={onClickSignIn}>Sign In to Proceed</Button>\n        </Box>\n      </Box>\n    </Modal>\n  )\n}\n"
  },
  {
    "path": "packages/web-earn/src/pages/TaikoLockPage/MintRedeemModal.tsx",
    "content": "import { Box, Typography, Modal, Input, CircularProgress, Tooltip } from '@mui/material'\nimport { Button, ButtonStyle, CoinIcons, FeeSelect, FeeSelectProps, SpaceBetweenBox } from '@loopring-web/component-lib'\nimport { BackIcon, CloseIcon, Info2Icon, TokenType } from '@loopring-web/common-resources'\nimport _ from 'lodash'\nimport { useTranslation } from 'react-i18next'\n// import RadioButtonUncheckedIcon from '@mui/icons-material/RadioButtonUnchecked'\nimport RadioButtonCheckedIcon from '@mui/icons-material/RadioButtonChecked'\nimport CheckBoxOutlineBlankRoundedIcon from '@mui/icons-material/CheckBoxOutlineBlankRounded';\nimport CheckBoxRoundedIcon from '@mui/icons-material/CheckBoxRounded';\nimport { useTheme } from '@emotion/react'\nimport styled from '@emotion/styled'\nimport CheckCircleRoundedIcon from '@mui/icons-material/CheckCircleRounded'\nimport CheckRoundedIcon from '@mui/icons-material/CheckRounded'\nimport ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos';\n\ntype MintModalProps = {\n  open: boolean\n  onClose: () => void\n  mintWarningChecked: boolean\n  onWarningCheckBoxChange: () => void\n  onConfirmBtnClicked: () => void\n  onClickMax: () => void\n  confirmBtnDisabled: boolean\n  onInput: (str: string) => void\n  inputValue: string\n  inputPlaceholder: string\n  tokenAvailableAmount: string\n  confirmBtnWording: string\n  logoCoinJSON: any\n  status: 'notSignedIn' | 'signingIn' | 'signedIn' | 'minting' | 'redeeming' | 'redeemError'\n  onClickSignIn: () => void\n  onClickMint: () => void\n\n  redeem: {\n    redeemAmount: string\n    lrTaikoInUse: boolean\n    lockedTaikoAmount: string,\n    pnlAmount: string,\n    onClickConfirm: () => void\n    onClickFee: () => void\n    fee: string\n    readlizedUSDT: string\n    unrealizedTAIKO: string\n  }\n  feeSelectProps: FeeSelectProps\n  redeemErrorMsg: string | undefined\n}\n\nconst StyledInput = styled(Input)`\n  input::placeholder {\n    color: var(--color-text-secondary);\n  }\n`\n\nexport const MintRedeemModal = (props: MintModalProps) => {\n  const {\n    open,\n    onClose,\n    mintWarningChecked,\n    onWarningCheckBoxChange,\n    confirmBtnDisabled,\n    onConfirmBtnClicked,\n    onInput,\n    inputValue,\n    tokenAvailableAmount,\n    onClickMax,\n    logoCoinJSON,\n    confirmBtnWording,\n    inputPlaceholder,\n    status,\n    onClickSignIn,\n    onClickMint,\n    redeem,\n    feeSelectProps,\n    redeemErrorMsg\n  } = props\n  const { t } = useTranslation(\"common\")\n  const theme = useTheme()\n\n  const mintingUI = (\n    <Box pt={5} px={4} pb={4}>\n      <Box display={'flex'} justifyContent={'space-between'}>\n        <Typography color={'var(--color-text-secondary)'} mb={0.5}>\n          {t(\"labelAmount\")}\n        </Typography>\n        <Typography color={'var(--color-text-secondary)'} mb={0.5}>\n          {t(\"labelAvailable\")} {tokenAvailableAmount}\n        </Typography>\n      </Box>\n\n      <StyledInput\n        sx={{\n          textAlign: 'right',\n          paddingX: 1.5,\n          height: '48px',\n          width: '100%',\n        }}\n        inputProps={{\n          style: {\n            textAlign: 'right',\n            fontSize: '20px',\n            fontFamily: 'Arial',\n          },\n        }}\n        disableUnderline\n        startAdornment={\n          <Box display={'flex'} alignItems={'center'}>\n            <CoinIcons type={TokenType.single} tokenIcon={[logoCoinJSON]} />\n            <Typography ml={1} color={'var(--color-text-primary)'}>\n              lrTAIKO\n            </Typography>\n          </Box>\n        }\n        endAdornment={\n          <Typography\n            component={'span'}\n            onClick={onClickMax}\n            sx={{ cursor: 'pointer' }}\n            ml={1}\n            color={'var(--color-primary)'}\n          >\n            {t(\"labelInputMax\")}\n          </Typography>\n        }\n        placeholder={inputPlaceholder}\n        onInput={(e) => {\n          onInput((e.target as any).value)\n        }}\n        value={inputValue}\n      />\n      <Box display={'flex'} justifyContent={'space-between'} mt={3} alignItems={'center'}>\n        <Typography color={'var(--color-text-secondary)'}>{t(\"labelDefiRate\")}</Typography>\n        <Typography color={'var(--color-text-secondary)'}>1 lrTAIKO = 1 TAIKO</Typography>\n      </Box>\n      <Box mt={5} display={'flex'} alignItems={'center'}>\n        <Box>\n          {mintWarningChecked ? (\n            <CheckBoxRoundedIcon\n              onClick={onWarningCheckBoxChange}\n              className='custom-size'\n              sx={{\n                color: theme.colorBase.warning,\n                fontSize: '20px',\n                cursor: 'pointer',\n              }}\n            />\n          ) : (\n            <CheckBoxOutlineBlankRoundedIcon\n              onClick={onWarningCheckBoxChange}\n              className='custom-size'\n              sx={{ color: theme.colorBase.warning, fontSize: '20px', cursor: 'pointer' }}\n            />\n          )}\n        </Box>\n        <Box ml={1}>\n          <Typography color={'var(--color-warning)'}>\n            {t('I acknowledge and would like to proceed.')}\n          </Typography>\n        </Box>\n      </Box>\n      <Typography color={'var(--color-text-secondary)'} mt={4}>\n        {t(\"labelTaikoFarmingMintRiskReminder\")}\n      </Typography>\n      <ButtonStyle\n        sx={{\n          mt: 4,\n          textTransform: 'none',\n        }}\n        fullWidth\n        variant={'contained'}\n        size={'large'}\n        color={'primary'}\n        onClick={() => {\n          onConfirmBtnClicked()\n        }}\n        disabled={confirmBtnDisabled}\n      >\n        {confirmBtnWording}\n      </ButtonStyle>\n    </Box>\n  )\n\n  const redeemingUI = (\n    <Box pt={5} px={4} pb={4}>\n      {redeem.lrTaikoInUse ? (\n        <>\n          <Typography mb={8} mt={4} color={'var(--color-text-secondary)'} textAlign={'center'}>\n            You still have active DeFi positions using lrTAIKO as collateral. Please close these\n            positions first; otherwise, you won’t be able to redeem your TAIKO from the Loopring\n            protocol.\n          </Typography>\n          <Button onClick={() => onClose()} fullWidth variant={'contained'}>\n            I Know\n          </Button>\n        </>\n      ) : (\n        <Box display={'flex'} flexDirection={'column'} justifyContent={'center'}>\n          <Typography mt={3} mb={6} variant='h2' textAlign={'center'}>\n            {redeem.redeemAmount}\n          </Typography>\n          <SpaceBetweenBox\n            leftNode={\n              <Typography color={'var(--color-text-secondary)'}>Deposited Taiko Amount</Typography>\n            }\n            rightNode={\n              <Typography color={'var(--color-text-primary)'}>\n                {redeem.lockedTaikoAmount}\n              </Typography>\n            }\n            mb={1.5}\n          />\n          <SpaceBetweenBox\n            alignItems={'center'}\n            leftNode={\n              <Box>\n                <Typography color={'var(--color-text-secondary)'} mb={0.25}>\n                  Profit\n                </Typography>\n                <Typography color={'var(--color-text-third)'} variant={'body2'}>\n                  The profit has been credited to your Loopring account in USDT\n                </Typography>\n              </Box>\n            }\n            rightNode={\n              <Typography color={'var(--color-text-primary)'}>{redeem.readlizedUSDT}</Typography>\n            }\n            mb={1.5}\n          />\n          <SpaceBetweenBox\n            alignItems={'center'}\n            leftNode={\n              <Box>\n                <Typography color={'var(--color-text-secondary)'} mb={0.25}>\n                  Loss\n                </Typography>\n                <Typography color={'var(--color-text-third)'} variant={'body2'}>\n                  The loss has been deducted from your locked TAIKO balance\n                </Typography>\n              </Box>\n            }\n            rightNode={\n              <Typography color={'var(--color-text-primary)'}>{redeem.unrealizedTAIKO}</Typography>\n            }\n            mb={4}\n          />\n          <FeeSelect {...feeSelectProps}/>\n          <Button sx={{ mt: 1 }} onClick={() => redeem.onClickConfirm()} fullWidth variant={'contained'}>\n            Confirm\n          </Button>\n          <Typography mt={4} color={'var(--color-text-third)'} variant={'body2'}>\n            If the claimable amount is less than your initially deposited amount, it’s because your\n            lrTAIKO-related DeFi investment incurred a loss. This loss was covered by deducting a\n            portion of your deposited TAIKO.\n          </Typography>\n        </Box>\n      )}\n    </Box>\n  )\n  const redeemErrorUI = (\n    <Box pt={5} px={4} pb={4}>\n      <>\n        <Typography mb={8} mt={4} color={'var(--color-error)'} textAlign={'center'}>\n          {redeemErrorMsg}\n        </Typography>\n        <Button onClick={() => onClose()} fullWidth variant={'contained'}>\n          Close\n        </Button>\n      </>\n    </Box>\n  )\n  const signInUI = (\n    <Box pt={5} px={4} pb={4}>\n      <Box display={'flex'} justifyContent={'space-between'}>\n        <Box width={'75%'} display={'flex'} alignItems={'start'}>\n          {status === 'signedIn' ? (\n            <CheckCircleRoundedIcon\n              sx={{\n                color: theme.colorBase.success,\n                mr: 1,\n                fontSize: '24px',\n                mt: 0.4,\n              }}\n              className='custom-size'\n            />\n          ) : (\n            <RadioButtonCheckedIcon\n              sx={{\n                color: theme.colorBase.textSecondary,\n                mr: 1,\n                fontSize: '24px',\n                mt: 0.4,\n              }}\n              className='custom-size'\n            />\n          )}\n\n          <Box>\n            <Typography color={'var(--color-text-primary)'} variant='h4' mb={0.5}>\n              {t(\"labelCompleteSignIn\")}\n            </Typography>\n            <Typography color={'var(--color-text-secondary)'} fontSize={'12px'}>\n              {t(\"labelCompleteSignInDes\")}\n            </Typography>\n          </Box>\n        </Box>\n        <Box>\n          {status === 'notSignedIn' ? (\n            <Button variant='contained' onClick={onClickSignIn}>\n              {t(\"labelSignIn\")}\n            </Button>\n          ) : status === 'signingIn' ? (\n            <Typography\n              display={'flex'}\n              alignItems={'center'}\n              color={'var(--color-primary)'}\n              fontSize='16px'\n            >\n              <CircularProgress size={16} sx={{ mr: 1, color: 'var(--color-primary)' }} /> Signing\n            </Typography>\n          ) : (\n            <Typography\n              display={'flex'}\n              alignItems={'center'}\n              color={'var(--color-success)'}\n              fontSize='16px'\n            >\n              <CheckRoundedIcon\n                sx={{\n                  fontSize: '18px',\n                  mr: 1,\n                  color: 'var(--color-success)',\n                }}\n                className='custom-size'\n              />{' '}\n              {t(\"Complete\")}\n            </Typography>\n          )}\n        </Box>\n      </Box>\n      <Box mt={5} display={'flex'} justifyContent={'space-between'}>\n        <Box width={'75%'} display={'flex'}>\n          <RadioButtonCheckedIcon\n            sx={{\n              color: theme.colorBase.textSecondary,\n              mr: 1,\n              fontSize: '24px',\n              mt: 0.4,\n            }}\n            className='custom-size'\n          />\n          <Box>\n            <Typography color={'var(--color-text-primary)'} variant='h4' mb={0.5}>\n              {t(\"labelMint\")}\n            </Typography>\n            <Typography color={'var(--color-text-secondary)'} fontSize={'12px'}>{t(\"labelStartMintlrTAIKO\")}</Typography>\n          </Box>\n        </Box>\n        <Button disabled={status !== 'signedIn'} variant='contained' onClick={onClickMint}>\n        {t(\"labelMint\")}\n        </Button>\n      </Box>\n    </Box>\n  )\n  return (\n    <Modal open={open} onClose={onClose}>\n      <Box height={'100%'} display={'flex'} justifyContent={'center'} alignItems={'center'}>\n        <Box\n          bgcolor={'var(--color-box)'}\n          width={'var(--modal-width)'}\n          borderRadius={1}\n          display={'flex'}\n          flexDirection={'column'}\n        >\n          <Box\n            display={'flex'}\n            justifyContent={'space-between'}\n            px={4}\n            py={2}\n            borderBottom={'1px solid var(--color-border)'}\n            alignItems={'center'}\n          >\n            <Typography color={'var(--color-text-primary)'} variant='h5'>\n              {status === 'redeeming' || status === 'redeemError' ? 'Redeem TAIKO' : t('labelMint')}\n            </Typography>\n            <CloseIcon\n              className='custom-size'\n              style={{\n                color: 'var(--color-text-secondary)',\n                width: '20px',\n                height: '20px',\n                cursor: 'pointer',\n              }}\n              onClick={onClose}\n            />\n          </Box>\n          {status === 'redeemError'\n            ? redeemErrorUI\n            : status === 'redeeming'\n            ? redeemingUI\n            : status === 'minting'\n            ? mintingUI\n            : signInUI}\n        </Box>\n      </Box>\n    </Modal>\n  )\n}\n"
  },
  {
    "path": "packages/web-earn/src/pages/TaikoLockPage/PendingTxsModal.tsx",
    "content": "import { Box, Typography, Modal, Input, CircularProgress } from '@mui/material'\nimport { CloseIcon } from '@loopring-web/common-resources'\nimport { useSystem } from '@loopring-web/core'\nimport _ from 'lodash'\nimport { useTranslation } from 'react-i18next'\nimport { useTheme } from '@emotion/react'\nimport styled from '@emotion/styled'\nimport OpenInNewIcon from '@mui/icons-material/OpenInNew'\nimport ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos'\ntype PendingTxsModalProps = {\n  open: boolean\n  onClose: () => void\n  pendingTxs: {\n    amount: string\n    hash: string\n    symbol: string\n    isLocal: boolean\n  }[]\n  onClickLocking: () => void\n}\n\nconst StyledInput = styled(Input)`\n  input::placeholder {\n    color: var(--color-text-secondary);\n  }\n`\n\nexport const PendingTxsModal = (props: PendingTxsModalProps) => {\n  const { open, onClose, pendingTxs, onClickLocking } = props\n  const { t } = useTranslation()\n  const theme = useTheme()\n  const { etherscanBaseUrl } = useSystem()\n\n  return (\n    <Modal open={open} onClose={onClose}>\n      <Box height={'100%'} display={'flex'} justifyContent={'center'} alignItems={'center'}>\n        <Box\n          bgcolor={'var(--color-box)'}\n          width={'var(--modal-width)'}\n          borderRadius={1}\n          display={'flex'}\n          flexDirection={'column'}\n          position={'relative'}\n          px={3.5}\n          pt={5}\n          minHeight={'428px'}\n          alignItems={'center'}\n        >\n          <CloseIcon\n            className='custom-size'\n            style={{\n              color: 'var(--color-text-secondary)',\n              width: '20px',\n              height: '20px',\n              cursor: 'pointer',\n              position: 'absolute',\n              right: 16,\n              top: 16,\n            }}\n            onClick={onClose}\n          />\n          <Typography color={'var(--color-text-primary)'} variant='h4' textAlign={'center'}>\n            Pending Transaction\n          </Typography>\n          <Box width={'100%'} mt={6}>\n            {pendingTxs.map((tx) => {\n              return (\n                <Box\n                  key={tx.hash}\n                  display={'flex'}\n                  justifyContent={'space-between'}\n                  alignItems={'center'}\n                >\n                  <Typography display={'flex'} alignItems={'center'} fontSize={'16px'}>\n                    Lock {tx.amount} {tx.symbol}{' '}\n                    {!tx.isLocal && (\n                      <OpenInNewIcon\n                        sx={{\n                          ml: 1,\n                          cursor: 'pointer',\n                          fontSize: '16px',\n                          color: 'var(--color-text-primary)',\n                        }}\n                        onClick={() => window.open(`${etherscanBaseUrl}tx/${tx.hash}`)}\n                      />\n                    )}\n                  </Typography>\n                  {tx.isLocal ? (\n                    <Typography\n                      color={'var(--color-primary)'}\n                      display={'flex'}\n                      alignItems={'center'}\n                      component={'p'}\n                      onClick={onClickLocking}\n                      sx={{ cursor: 'pointer' }}\n                    >\n                      Locking{' '}\n                      <ArrowForwardIosIcon\n                        sx={{ color: 'var(--color-primary)', fontSize: '14px' }}\n                      ></ArrowForwardIosIcon>{' '}\n                    </Typography>\n                  ) : (\n                    <CircularProgress size={18} sx={{ color: 'var(--color-primary)' }} />\n                  )}\n                </Box>\n              )\n            })}\n          </Box>\n        </Box>\n      </Box>\n    </Modal>\n  )\n}\n"
  },
  {
    "path": "packages/web-earn/src/pages/TaikoLockPage/TaikoLockInput.tsx",
    "content": "import {\n  AccountStatus,\n  CoinInfo,\n  EmptyValueTag,\n  getValuePrecisionThousand,\n  hexToRGB,\n  IBData,\n  Info2Icon,\n  myLog,\n  OrderListIcon,\n  TradeBtnStatus,\n} from '@loopring-web/common-resources'\nimport { useTranslation } from 'react-i18next'\nimport React, { useCallback, useEffect, useRef, useState } from 'react'\nimport { Box, CircularProgress, Grid, Input, Tooltip, Typography } from '@mui/material'\nimport {\n  InputCoin,\n  ButtonStyle,\n  InputButtonProps,\n  BtnInfo,\n  useSettings,\n  SpaceBetweenBox,\n} from '@loopring-web/component-lib'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport styled from '@emotion/styled'\nimport { useHistory } from 'react-router'\nimport { useTheme } from '@emotion/react'\nimport moment from 'moment'\nimport KeyboardDoubleArrowUpIcon from '@mui/icons-material/KeyboardDoubleArrowUp';\n\nconst GridStyle = styled(Grid)`\n  input::placeholder {\n    font-size: ${({ theme }) => theme.fontDefault.h5};\n  }\n  .coinInput-wrap {\n    background-color: var(--color-global-bg);\n    border: 1px solid var(--color-border);\n  }\n`\n\ntype TaikoLockInputProps<T, I, ACD> = {\n  isJoin: true\n  disabled?: boolean\n  btnInfo?: BtnInfo\n  isLoading: boolean\n  minSellAmount: string\n  maxSellAmount: string\n  onSubmitClick: () => void\n  switchStobEvent?: (_isStoB: boolean) => void\n  onChangeEvent: (data: { tradeData?: undefined | T }) => void\n  handleError?: (data: T) => void\n  tokenSellProps?: Partial<InputButtonProps<T, I, CoinInfo<I>>>\n  deFiSideCalcData: ACD\n  tokenSell: sdk.TokenInfo\n  btnStatus?: keyof typeof TradeBtnStatus | undefined\n  accStatus?: AccountStatus\n  btnLabel: string\n  lockedPosition?: {\n    amount: string\n    amountInCurrency: string\n    trailblazerBooster: string\n  }\n  taikoFarmingChecked: boolean\n  onCheckBoxChange: () => void\n  buttonDisabled: boolean\n  daysInput: {\n    value: string\n    onInput: (value: string) => void\n    disabled: boolean\n    unlockTime: string\n  }\n  myPosition: {\n    totalAmount: string\n    totalAmountInCurrency: string\n    positions: {\n      amount: string\n      unlocked: boolean\n      lockingDays: number\n      unlockTime: string\n      multiplier: string\n    }[]\n    expirationTime: number\n    totalAmountWithNoSymbol: string\n    realizedUSDT: string\n    unrealizedTAIKO: string\n    settlementStatus: 'settled' | 'notSettled' | 'noPosition' | 'init' | 'minting',\n    showMyPosition: boolean\n  }\n  mintButton: {\n    onClick: () => void\n    disabled: boolean\n  }\n  redeemButton: {\n    onClick: () => void\n    disabled: boolean\n  }\n  hasPendingDeposits: boolean\n  onClickPendingDeposits: () => void\n  lockTaikoPlaceholder: string\n  lrTAIKOTradeEarnSummary?: {\n    holdingAmount: string\n    mintedAmount: string\n    pnl: string\n  }\n  showMultiplier: boolean\n}\n\nconst StyledInput = styled(Input)`\n  input::placeholder {\n    color: var(--color-text-secondary);\n  }\n`\n\nexport const TaikoLockInput = <T extends IBData<I>, I, ACD extends TaikoLockInputProps<T, I, ACD>>({\n  disabled,\n  isJoin,\n  btnInfo,\n  onSubmitClick,\n  switchStobEvent,\n  onChangeEvent,\n  handleError,\n  deFiSideCalcData,\n  accStatus,\n  tokenSell,\n  isLoading,\n  btnStatus,\n  tokenSellProps,\n  minSellAmount,\n  maxSellAmount,\n  btnLabel,\n  lockedPosition,\n  taikoFarmingChecked,\n  onCheckBoxChange,\n  buttonDisabled,\n  daysInput,\n  myPosition,\n  mintButton,\n  hasPendingDeposits,\n  onClickPendingDeposits,\n  lockTaikoPlaceholder,\n  lrTAIKOTradeEarnSummary,\n  showMultiplier,\n  redeemButton,\n  ...rest\n}: TaikoLockInputProps<T, I, ACD>) => {\n  // @ts-ignore\n  const coinSellRef = React.useRef()\n\n  const { t } = useTranslation('common')\n  const history = useHistory()\n  const getDisabled = React.useMemo(() => {\n    return disabled || deFiSideCalcData === undefined\n  }, [btnStatus, deFiSideCalcData, disabled])\n\n  const handleCountChange = React.useCallback(\n    (ibData: T, _name: string, _ref: any) => {\n      if (deFiSideCalcData.coinSell.tradeValue !== ibData.tradeValue) {\n        myLog('defi handleCountChange', _name, ibData)\n        onChangeEvent({\n          tradeData: { ...ibData },\n        })\n      }\n    },\n    [deFiSideCalcData, onChangeEvent],\n  )\n  const propsSell = {\n    label: t('tokenEnterPaymentToken'),\n    subLabel: t('tokenMax'),\n    emptyText: t('tokenSelectToken'),\n    placeholderText:\n      minSellAmount && maxSellAmount\n        ? t('labelInvestMaxDefi', {\n            minValue: getValuePrecisionThousand(\n              minSellAmount,\n              tokenSell.precision,\n              tokenSell.precision,\n              tokenSell.precision,\n              false,\n              { floor: false, isAbbreviate: true },\n            ),\n            maxValue: getValuePrecisionThousand(\n              maxSellAmount,\n              tokenSell.precision,\n              tokenSell.precision,\n              tokenSell.precision,\n              false,\n              { floor: false, isAbbreviate: true },\n            ),\n          })\n        : '0.00',\n    isShowCoinInfo: true,\n    isShowCoinIcon: true,\n    maxAllow: true,\n    ...tokenSellProps,\n    handleError: (data: any) => {\n      if (\n        data.tradeValue &&\n        (data.tradeValue > data.balance ||\n          sdk.toBig(data.tradeValue).gt(maxSellAmount) ||\n          sdk.toBig(data.tradeValue).lt(minSellAmount))\n      ) {\n        return {\n          error: true,\n        }\n      }\n      return {\n        error: false,\n      }\n    },\n    handleCountChange: handleCountChange as any,\n    ...rest,\n  } as any\n\n  // const daysDuration = Math.ceil(\n  //   Number(deFiSideCalcData?.stakeViewInfo?.rewardPeriod ?? 0) / 86400000,\n  // )\n  let dalyEarn = deFiSideCalcData?.stakeViewInfo?.dalyEarn\n    ? getValuePrecisionThousand(\n        sdk\n          .toBig(deFiSideCalcData.stakeViewInfo.dalyEarn)\n          .div('1e' + tokenSell.decimals)\n          .div(100),\n        tokenSell.precision,\n        tokenSell.precision,\n        tokenSell.precision,\n        false,\n      )\n    : undefined\n  dalyEarn = dalyEarn && dalyEarn !== '0' ? dalyEarn + ' ' + tokenSell.symbol : EmptyValueTag\n  myLog('deFiSideCalcData.stakeViewInfo', deFiSideCalcData.stakeViewInfo)\n  const theme = useTheme()\n  const { isMobile } = useSettings()\n  const [showPositionList, setShowPositionList] = useState<boolean>(false)\n  const realized = false\n\n  return (\n    <Box>\n      <Box\n        display={'flex'}\n        style={isMobile ? { flex: 1 } : { width: '450px' }}\n        justifyContent={'center'}\n        paddingX={3}\n        paddingTop={3}\n        paddingBottom={2}\n        bgcolor={'var(--color-box-third)'}\n        border={'1px solid var(--color-border)'}\n        borderRadius={2}\n      >\n        <GridStyle\n          className={deFiSideCalcData ? '' : 'loading'}\n          container\n          direction={'column'}\n          justifyContent={'space-between'}\n          alignItems={'center'}\n          flex={1}\n        >\n          <Grid\n            item\n            display={'flex'}\n            justifyContent={'space-between'}\n            alignItems={'center'}\n            flexDirection={'row'}\n            width={'100%'}\n            className={'MuiToolbar-root'}\n          >\n            <Typography\n              height={'100%'}\n              display={'inline-flex'}\n              variant={'h5'}\n              alignItems={'center'}\n              alignSelf={'self-start'}\n            >\n              Lock & Earn\n            </Typography>\n            <OrderListIcon\n              sx={{ cursor: 'pointer' }}\n              onClick={() => {\n                history.push(`/l2assets/history/TaikoLockRecords`)\n              }}\n              fontSize={'large'}\n            />\n          </Grid>\n          <Grid\n            item\n            marginTop={2}\n            paddingTop={2}\n            paddingBottom={3}\n            flexDirection={'column'}\n            display={'flex'}\n            alignSelf={'stretch'}\n            alignItems={'stretch'}\n          >\n            <InputCoin<T, I, any>\n              ref={coinSellRef}\n              disabled={getDisabled}\n              name='coinSell'\n              isHideError={true}\n              order='right'\n              inputData={deFiSideCalcData ? deFiSideCalcData.coinSell : {}}\n              coinMap={{}}\n              coinPrecision={tokenSell.precision}\n              {...propsSell}\n              decimalsLimit={2}\n              label={\n                <Typography color={'var(--color-text-secondary)'}>{t('labelAmount')}</Typography>\n              }\n              placeholderText={lockTaikoPlaceholder}\n            />\n          </Grid>\n          <Grid\n            item\n            flexDirection={'column'}\n            display={'flex'}\n            alignSelf={'stretch'}\n            alignItems={'stretch'}\n          >\n            <Typography color={'var(--color-text-secondary)'} mb={0.5}>\n              Lock Duration\n            </Typography>\n            <StyledInput\n              sx={{\n                textAlign: 'right',\n                paddingX: 1.5,\n                height: '48px',\n              }}\n              inputProps={{\n                style: {\n                  textAlign: 'right',\n                  fontSize: '20px',\n                  fontFamily: 'Arial',\n                },\n              }}\n              disableUnderline\n              startAdornment={\n                <Typography variant='h4' color={'var(--color-text-primary)'} mb={0.5}>\n                  Days\n                </Typography>\n              }\n              placeholder='15 ≤ Lock Duration ≤ 60'\n              onInput={(e) => {\n                daysInput.onInput((e.target as any).value)\n              }}\n              value={daysInput.value}\n              disabled={daysInput.disabled}\n            />\n          </Grid>\n\n          {showMultiplier && (\n            <Typography\n              sx={{ opacity: daysInput.value ? 1 : 0 }}\n              width={'100%'}\n              variant='body2'\n              textAlign={'left'}\n              mt={1.5}\n            >\n              * x{Number(daysInput.value)} Multiplier\n            </Typography>\n          )}\n          <Typography\n            sx={{ opacity: daysInput.value ? 1 : 0 }}\n            width={'100%'}\n            variant='body2'\n            textAlign={'left'}\n            mt={1}\n          >\n            * Your TAIKO token will be unlocked on {daysInput.unlockTime}\n          </Typography>\n\n          <Grid item alignSelf={'stretch'} marginTop={8} pb={1}>\n            <Grid container direction={'column'} spacing={1} alignItems={'stretch'}>\n              <Grid item>\n                <ButtonStyle\n                  fullWidth\n                  variant={'contained'}\n                  size={'large'}\n                  color={'primary'}\n                  onClick={() => {\n                    onSubmitClick()\n                  }}\n                  loading={!getDisabled && btnStatus === TradeBtnStatus.LOADING ? 'true' : 'false'}\n                  disabled={buttonDisabled}\n                >\n                  {btnLabel}\n                </ButtonStyle>\n              </Grid>\n              <Box mt={2} width={'100%'} display={'flex'} justifyContent={'center'}>\n                <Typography\n                  display={'flex'}\n                  alignItems={'center'}\n                  textAlign={'center'}\n                  variant={'body2'}\n                  color={'var(--color-text-secondary)'}\n                >\n                  Points tracked in Taiko Trailblazers Dashboard\n                </Typography>\n              </Box>\n              {hasPendingDeposits && (\n                <Box\n                  sx={{ cursor: 'pointer' }}\n                  onClick={onClickPendingDeposits}\n                  display={'flex'}\n                  alignItems={'center'}\n                  justifyContent={'center'}\n                  mt={4}\n                >\n                  <CircularProgress size={18} sx={{ color: 'var(--color-primary)', mr: 1 }} />\n                  <Typography color={'var(--color-primary)'}>Pending Transaction</Typography>\n                </Box>\n              )}\n            </Grid>\n          </Grid>\n        </GridStyle>\n      </Box>\n\n      {myPosition.showMyPosition && (\n        <Box\n          display={'flex'}\n          style={isMobile ? { flex: 1 } : { width: '450px' }}\n          justifyContent={'center'}\n          bgcolor={'var(--color-box-third)'}\n          border={'1px solid var(--color-border)'}\n          borderRadius={2}\n          width={'100%'}\n          flexDirection={'column'}\n          p={3}\n          my={5}\n        >\n          <Typography\n            display={'flex'}\n            alignItems={'center'}\n            variant={'h5'}\n            color={'var(--color-text-primary)'}\n          >\n            My Position\n          </Typography>\n          <Typography mt={0.5} variant='body2' color={'var(--color-text-secondary)'}>\n            Expiration date:{' '}\n            {myPosition.expirationTime\n              ? moment(myPosition.expirationTime).format('YYYY-MM-DD')\n              : '--'}\n          </Typography>\n          <Box mt={2}>\n            <Box mb={1} display={'flex'} alignItems={'center'}>\n              <Typography width={'40%'} variant='body2' color={'var(--color-text-secondary)'}>\n                Item\n              </Typography>\n              <Typography width={'30%'} variant='body2' color={'var(--color-text-secondary)'}>\n                Status\n              </Typography>\n              <Typography\n                width={'30%'}\n                textAlign={'right'}\n                variant='body2'\n                color={'var(--color-text-secondary)'}\n              >\n                Amount\n              </Typography>\n            </Box>\n            <Box mb={1} display={'flex'} alignItems={'center'}>\n              <Typography width={'40%'}>Taiko</Typography>\n              <Typography width={'30%'}>\n                {myPosition.settlementStatus === 'settled' ? 'Available' : 'Locked'}\n              </Typography>\n              <Typography width={'30%'} textAlign={'right'}>\n                {myPosition?.totalAmount ?? '--'}\n              </Typography>\n            </Box>\n            {myPosition.settlementStatus === 'settled' ? (\n              <>\n                <Box mb={1} display={'flex'} alignItems={'center'}>\n                  <Tooltip\n                    title={\n                      <Typography variant='body2'>\n                        The profit has been credited to your Loopring account in USDT\n                      </Typography>\n                    }\n                  >\n                    <Typography width={'40%'} display={'flex'} alignItems={'center'}>\n                      Profit <Info2Icon sx={{ ml: 0.5 }} />\n                    </Typography>\n                  </Tooltip>\n\n                  <Tooltip\n                    title={\n                      <Typography variant='body2'>\n                        Your P&L has been finalized. If your current TAIKO holdings are less than\n                        the initially locked amount, it indicates that losses incurred during your\n                        DeFi activities have been deducted from your balance.\n                      </Typography>\n                    }\n                  >\n                    <Typography width={'30%'} display={'flex'} alignItems={'center'}>\n                      Realized <Info2Icon sx={{ ml: 0.5 }} />\n                    </Typography>\n                  </Tooltip>\n\n                  <Typography width={'30%'} textAlign={'right'}>\n                    {myPosition.realizedUSDT}\n                  </Typography>\n                </Box>\n                <Box mb={1} display={'flex'} alignItems={'center'}>\n                  <Tooltip\n                    title={\n                      <Typography variant='body2'>\n                        The loss has been deducted from your locked TAIKO balance\n                      </Typography>\n                    }\n                  >\n                    <Typography width={'40%'} display={'flex'} alignItems={'center'}>\n                      Loss <Info2Icon sx={{ ml: 0.5 }} />\n                    </Typography>\n                  </Tooltip>\n\n                  <Tooltip\n                    title={\n                      <Typography variant='body2'>\n                        Your P&L has been finalized. If your current TAIKO holdings are less than\n                        the initially locked amount, it indicates that losses incurred during your\n                        DeFi activities have been deducted from your balance.\n                      </Typography>\n                    }\n                  >\n                    <Typography width={'30%'} display={'flex'} alignItems={'center'}>\n                      Realized <Info2Icon sx={{ ml: 0.5 }} />\n                    </Typography>\n                  </Tooltip>\n\n                  <Typography width={'30%'} textAlign={'right'}>\n                    {myPosition.unrealizedTAIKO}\n                  </Typography>\n                </Box>\n              </>\n            ) : (\n              <>\n                <Box mb={1} display={'flex'} alignItems={'center'}>\n                  <Tooltip\n                    title={\n                      <Typography variant='body2'>\n                        {`The amount shown reflects the total profit (positive) or loss (negative) accrued from using lrTAIKO as collateral in Loopring DeFi.`}\n                        <br />\n                        <br />\n                        {`If the investment hasn’t been settled, the P&L will not be displayed here. To view an investment’s unrealized P&L, please visit the dashboard of the DeFi product where the asset was invested.`}\n                      </Typography>\n                    }\n                  >\n                    <Typography width={'40%'} display={'flex'} alignItems={'center'}>\n                      Profit & Loss <Info2Icon sx={{ ml: 0.5 }} />\n                    </Typography>\n                  </Tooltip>\n\n                  <Tooltip\n                    title={\n                      <Typography variant='body2'>\n                        Your P&L is still pending. Once your lock duration expires, any unrealized\n                        losses will result in a portion of your locked TAIKO being transferred to\n                        Loopring.\n                      </Typography>\n                    }\n                  >\n                    <Typography width={'30%'} display={'flex'} alignItems={'center'}>\n                      Unrealized <Info2Icon sx={{ ml: 0.5 }} />\n                    </Typography>\n                  </Tooltip>\n\n                  <Typography width={'30%'} textAlign={'right'}>\n                    {myPosition.unrealizedTAIKO}\n                  </Typography>\n                </Box>\n              </>\n            )}\n\n            <Box\n              pb={1.5}\n              display={'flex'}\n              justifyContent={'center'}\n              borderBottom={'1px solid var(--color-border)'}\n              mt={2}\n            >\n              <KeyboardDoubleArrowUpIcon\n                className='custom-size'\n                style={{\n                  width: '24px',\n                  height: '24px',\n                  cursor: 'pointer',\n                  transform: showPositionList ? 'rotate(0deg)' : 'rotate(180deg)',\n                }}\n                onClick={() => {\n                  setShowPositionList(!showPositionList)\n                }}\n              />\n            </Box>\n          </Box>\n          <Box mt={2.5}>\n            <></>\n            {showPositionList && (\n              <>\n                <Box mb={0.5} display={'flex'} justifyContent={'space-between'}>\n                  <Typography color={'var(--color-text-secondary)'}>Amount (TAIKO)</Typography>\n                  <Typography color={'var(--color-text-secondary)'}>Lock Duration</Typography>\n                </Box>\n                <Box>\n                  {myPosition.positions?.map((item, index) => {\n                    return (\n                      <Box\n                        py={2}\n                        display={'flex'}\n                        justifyContent={'space-between'}\n                        alignItems={'center'}\n                      >\n                        <Box>\n                          <Box display={'flex'} alignItems={'center'}>\n                            <Typography\n                              component={'span'}\n                              fontSize={'16px'}\n                              color={'var(--color-text-primary)'}\n                            >\n                              {item.amount}\n                            </Typography>\n                            <Tooltip title={'Trailblazers Points Multiplier'}>\n                              <Box\n                                ml={1}\n                                bgcolor={hexToRGB('#EA29B6', 0.2)}\n                                color={'#EA29B6'}\n                                borderRadius={'4px'}\n                                // py={1}\n                                p={0.5}\n                                fontSize={'11px'}\n                              >\n                                {item.multiplier}\n                              </Box>\n                            </Tooltip>\n                          </Box>\n\n                          {/* <Typography\n                      color={item.unlocked ? 'var(--color-success)' : 'var(--color-text-secondary)'}\n                    >\n                      {item.unlocked ? 'Unlocked' : 'locked'}\n                    </Typography> */}\n                        </Box>\n                        <Box>\n                          <Typography\n                            textAlign={'right'}\n                            fontSize={'16px'}\n                            color={'var(--color-text-primary)'}\n                          >\n                            {item.lockingDays} Days\n                          </Typography>\n                          {/* <Typography textAlign={'right'} color={'var(--color-text-secondary)'}>\n                      {item.unlockTime}{' '}\n                    </Typography> */}\n                        </Box>\n                      </Box>\n                    )\n                  })}\n                </Box>\n              </>\n            )}\n            <Box display={'flex'} justifyContent={'space-between'}>\n              <ButtonStyle\n                sx={{ mt: 4, mb: 4, textTransform: 'none', width: '48%' }}\n                fullWidth\n                variant={'contained'}\n                size={'large'}\n                color={'primary'}\n                onClick={() => {\n                  redeemButton.onClick()\n                }}\n                disabled={redeemButton.disabled}\n              >\n                Redeem\n              </ButtonStyle>\n              <ButtonStyle\n                sx={{ mt: 4, mb: 4, textTransform: 'none', width: '48%' }}\n                fullWidth\n                variant={'contained'}\n                size={'large'}\n                color={'primary'}\n                onClick={() => {\n                  mintButton.onClick()\n                }}\n                disabled={mintButton.disabled}\n              >\n                Mint lrTAIKO\n              </ButtonStyle>\n            </Box>\n          </Box>\n        </Box>\n      )}\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/web-earn/src/pages/TaikoLockPage/TxSubmitModal.tsx",
    "content": "import { Box, Typography, Modal, Input, CircularProgress } from '@mui/material'\nimport { CloseIcon } from '@loopring-web/common-resources'\nimport _ from 'lodash'\nimport { useTranslation } from 'react-i18next'\nimport RadioButtonCheckedIcon from '@mui/icons-material/RadioButtonChecked'\nimport { useTheme } from '@emotion/react'\nimport styled from '@emotion/styled'\nimport CheckCircleRoundedIcon from '@mui/icons-material/CheckCircleRounded'\n\ntype TxSubmitModalProps = {\n  open: boolean\n  onClose: () => void\n  status: 'init' | 'tokenApproving' |  'depositing' | 'depositCompleted'\n}\n\nconst StyledInput = styled(Input)`\n  input::placeholder {\n    color: var(--color-text-secondary);\n  }\n`\n\nexport const TxSubmitModal = (props: TxSubmitModalProps) => {\n  const { open, onClose, status } = props\n  const { t } = useTranslation()\n  const theme = useTheme()\n\n  return (\n    <Modal open={open} onClose={onClose}>\n      <Box height={'100%'} display={'flex'} justifyContent={'center'} alignItems={'center'}>\n        <Box\n          bgcolor={'var(--color-box)'}\n          width={'var(--modal-width)'}\n          borderRadius={1}\n          display={'flex'}\n          flexDirection={'column'}\n        >\n          <Box\n            display={'flex'}\n            justifyContent={'space-between'}\n            px={4}\n            py={2}\n            borderBottom={'1px solid var(--color-border)'}\n            alignItems={'center'}\n          >\n            <Typography color={'var(--color-text-primary)'} variant='h5'>\n              Lock & Earn Progress\n            </Typography>\n            <CloseIcon\n              className='custom-size'\n              style={{\n                color: 'var(--color-text-secondary)',\n                width: '20px',\n                height: '20px',\n                cursor: 'pointer',\n              }}\n              onClick={onClose}\n            />\n          </Box>\n\n          <Box pt={5} px={4} pb={4}>\n            <Box display={'flex'} justifyContent={'space-between'}>\n              <Box display={'flex'} alignItems={'start'}>\n                {status === 'init' ? (\n                  <RadioButtonCheckedIcon\n                    sx={{\n                      color: theme.colorBase.textSecondary,\n                      mr: 1,\n                      fontSize: '20px',\n                      mt: 0.3,\n                    }}\n                    className='custom-size'\n                  />\n                ) : status === 'tokenApproving' ? (\n                  <CircularProgress\n                    size={18}\n                    sx={{\n                      color: theme.colorBase.primary,\n                      mr: 1.2,\n                      mt: 0.5,\n                    }}\n                  />\n                ) : (\n                  <CheckCircleRoundedIcon\n                    sx={{\n                      color: theme.colorBase.success,\n                      mr: 1,\n                      fontSize: '20px',\n                      mt: 0.3,\n                    }}\n                    className='custom-size'\n                  />\n                )}\n\n                <Box>\n                  <Typography\n                    color={\n                      status === 'init'\n                        ? 'var(--color-text-secondary)'\n                        : 'var(--color-text-primary)'\n                    }\n                    fontSize={'16px'}\n                    mb={0.5}\n                  >\n                    Token Approve\n                  </Typography>\n                </Box>\n              </Box>\n            </Box>\n            <Box mt={5} display={'flex'} justifyContent={'space-between'}>\n              <Box display={'flex'}>\n                {status === 'init' || status === 'tokenApproving' ? (\n                  <RadioButtonCheckedIcon\n                    sx={{\n                      color: theme.colorBase.textSecondary,\n                      mr: 1,\n                      fontSize: '20px',\n                      mt: 0.3,\n                    }}\n                    className='custom-size'\n                  />\n                ) : status === 'depositing' ? (\n                  <Box>\n                    <CircularProgress\n                      size={18}\n                      sx={{\n                        color: theme.colorBase.primary,\n                        mr: 1.2,\n                        mt: 0.5,\n                      }}\n                    />\n                  </Box>\n                ) : (\n                  <CheckCircleRoundedIcon\n                    sx={{\n                      color: theme.colorBase.success,\n                      mr: 1,\n                      fontSize: '20px',\n                      mt: 0.3,\n                    }}\n                    className='custom-size'\n                  />\n                )}\n                <Box>\n                  <Typography\n                    color={\n                      status === 'init' || status === 'tokenApproving'\n                        ? 'var(--color-text-secondary)'\n                        : 'var(--color-text-primary)'\n                    }\n                    fontSize={'16px'}\n                    mb={0.5}\n                  >\n                    Deposit Token\n                  </Typography>\n                  <Typography color={'var(--color-text-secondary)'} fontSize={'12px'}>\n                  Settlement on Loopring, an app-specific ZK-Rollup, may take around 10 blocks, while on the Taiko network, it might take a few minutes.\n                  </Typography>\n                  <Typography color={'var(--color-text-secondary)'} fontSize={'12px'} mt={1}>\n                  You can monitor the status here or close this prompt and return to check it later.\n                  </Typography>\n                </Box>\n              </Box>\n            </Box>\n          </Box>\n        </Box>\n      </Box>\n    </Modal>\n  )\n}\n"
  },
  {
    "path": "packages/web-earn/src/pages/TaikoLockPage/index.tsx",
    "content": "import { confirmation, useTaikoLock, useToast } from '@loopring-web/core'\nimport { useTranslation } from 'react-i18next'\n\nimport {\n  boxLiner,\n  Button,\n  FeeSelect,\n  LoadingBlock,\n  MaxWidthContainer,\n  Toast,\n  ToastType,\n  useSettings,\n  useToggle,\n} from '@loopring-web/component-lib'\nimport { Box, Grid, Typography } from '@mui/material'\nimport React from 'react'\nimport { CloseIcon, hexToRGB, SoursURL, TOAST_TIME } from '@loopring-web/common-resources'\n\nimport { useHistory } from 'react-router-dom'\nimport { TaikoLockInput } from './TaikoLockInput'\nimport styled from '@emotion/styled'\nimport { ErrorPage } from '../../pages/ErrorPage'\nimport BannerPage from './BannerPage'\nimport { useTheme } from '@emotion/react'\nimport { MintRedeemModal } from './MintRedeemModal'\nimport { TxSubmitModal } from './TxSubmitModal'\nimport { PendingTxsModal } from './PendingTxsModal'\nimport { LogInToCleanLrTaikoModalModal } from './LogInToCleanLrTaiko'\n\nconst containerColors = ['var(--color-global-bg)', 'var(--color-pop-bg)']\nconst StyleWrapper = styled(Box)`\n  position: relative;\n  border-radius: ${({ theme }) => theme.unit}px;\n\n  .loading-block {\n    background: initial;\n  }\n\n  .hasLinerBg {\n    ${({ theme }) => boxLiner({ theme })}\n  }\n\n  border-radius: ${({ theme }) => theme.unit}px;\n` as typeof Grid\n\nexport const TaikoLockPage = ({\n  setConfirmedLRCStakeInvestInvest,\n  isJoin = true,\n  symbol,\n}: {\n  symbol: string\n  setConfirmedLRCStakeInvestInvest: (state: {\n    isShow: boolean\n    confirmationNeeded: boolean\n  }) => void\n  isJoin?: boolean\n}) => {\n  const { t } = useTranslation('common')\n  const {\n    confirmation: { confirmedLRCStakeInvest},\n  } = confirmation.useConfirmation()\n  const { toggle } = useToggle()\n\n  const { toastOpen, setToastOpen, closeToast } = useToast()\n  const { stakeWrapProps } = useTaikoLock({ setToastOpen, symbol })\n\n  const { isMobile } = useSettings()\n\n  const styles = isMobile ? { flex: 1 } : { width: '450px' }\n  React.useEffect(() => {\n    setConfirmedLRCStakeInvestInvest({ show: !confirmedLRCStakeInvest, confirmationNeeded: true })\n  }, [])\n  const theme = useTheme()\n  return (\n    <>\n      <Toast\n        alertText={toastOpen?.content ?? ''}\n        severity={toastOpen?.type ?? ToastType.success}\n        open={toastOpen?.open ?? false}\n        autoHideDuration={TOAST_TIME}\n        onClose={closeToast}\n      />\n\n        <Box display={'flex'} flexDirection={'column'} flex={1} marginBottom={2}>\n          <Box\n            width={'100%'}\n            height={'48px'}\n            bgcolor={hexToRGB('#EB2FAC', 0.15)}\n            justifyContent={'center'}\n            alignItems={'center'}\n            display={'flex'}\n            mt={4}\n          >\n            <Box\n              component={'img'}\n              height={'28px'}\n              src={\n                SoursURL +\n                (theme.mode === 'dark'\n                  ? 'earn/taiko_farming_banner_wording.png'\n                  : 'earn/taiko_farming_banner_wording_light.png')\n              }\n              mb={'2px'}\n            />\n          </Box>\n          <MaxWidthContainer\n            mt={4}\n            background={containerColors[0]}\n            sx={{\n              display: 'flex',\n              flexDirection: 'row',\n              alignItems: 'flex-start',\n            }}\n          >\n            <Box width={'26%'} />\n            <StyleWrapper\n              display={'flex'}\n              flexDirection={'column'}\n              justifyContent={'center'}\n              alignItems={'center'}\n              flex={1}\n            >\n              {stakeWrapProps.deFiSideCalcData ? (\n                <TaikoLockInput isJoin={isJoin} symbol={symbol} {...(stakeWrapProps as any)} />\n              ) : (\n                <LoadingBlock />\n              )}\n            </StyleWrapper>\n            <Box width={'26%'}>\n              <Box\n                p={2}\n                borderRadius={'8px'}\n                bgcolor={'var(--color-box-third)'}\n                display={'flex'}\n                flexDirection={'column'}\n                justifyContent={'space-between'}\n                position={'relative'}\n                mb={6}\n                sx={{\n                  backgroundImage: `url('${SoursURL}earn/taiko_farming_des_bg${\n                    theme.mode === 'light' ? '_light' : ''\n                  }.png')`,\n                  backgroundRepeat: 'no-repeat',\n                  backgroundPosition: 'center',\n                  backgroundSize: 'cover',\n                }}\n              >\n                <Typography color={'var(--color-white)'}>\n                  {t(\"labelTaikoLockEnjoyComplete\")}\n                </Typography>\n              </Box>\n\n              <Box\n                p={2}\n                borderRadius={'8px'}\n                sx={{\n                  backgroundImage: `url(${\n                    SoursURL +\n                    (theme.mode === 'dark'\n                      ? 'earn/taiko_farming_banner_bg.png'\n                      : 'earn/taiko_farming_banner_bg_light.png')\n                  })`,\n                  backgroundSize: 'cover',\n                  backgroundPosition: 'center',\n                  backgroundRepeat: 'no-repeat',\n                }}\n                display={'flex'}\n                flexDirection={'column'}\n                justifyContent={'space-between'}\n              >\n                <Typography variant={'h5'} color={theme.colorBase.white}>\n                  {t('labelTaikoFarmingUnlockValue')}\n                </Typography>\n                <Box\n                  mt={2}\n                  height={'32px'}\n                  width={'115.2px'}\n                  component={'img'}\n                  sx={{\n                    cursor: 'pointer',\n                  }}\n                  src={SoursURL + 'earn/taiko_farming_banner_button.png'}\n                  alignSelf={'end'}\n                  onClick={() => {\n                    window.open('/#/taiko-farming/banner', '_blank')\n                  }}\n                />\n              </Box>\n            </Box>\n          </MaxWidthContainer>\n        </Box>\n      <MintRedeemModal \n        {...stakeWrapProps.mintRedeemModal} \n        redeem={{\n          ...stakeWrapProps.mintRedeemModal.redeem,\n          readlizedUSDT: stakeWrapProps.myPosition?.realizedUSDT ?? '',\n          unreadlizedTAIKO: stakeWrapProps.myPosition?.unrealizedTAIKO ?? '',\n        }}\n        logoCoinJSON={stakeWrapProps.taikoCoinJSON} \n        feeSelectProps={stakeWrapProps.feeModal}\n        />\n        {/* <FeeSelect\n          {...stakeWrapProps.feeModal}\n        /> */}\n        \n      <TxSubmitModal {...stakeWrapProps.txSubmitModal} />\n      <PendingTxsModal {...stakeWrapProps.pendingTxsModal} />\n      <LogInToCleanLrTaikoModalModal {...stakeWrapProps.logInToCleanLrTaikoModal} />\n    </>\n  )\n}\n\nexport { BannerPage as TaikoLockBannerPage }\n"
  },
  {
    "path": "packages/web-earn/src/pages/TradeRacePage/hook.ts",
    "content": "import React from 'react'\nimport { languageMap, myLog, url_path, url_test_path } from '@loopring-web/common-resources'\nimport { useHistory, useLocation, useRouteMatch } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport { Config_INFO_URL, EventData } from './interface'\nimport { useSystem } from '@loopring-web/core'\nimport moment from 'moment'\n\nexport enum EVENT_STATUS {\n  EVENT_START = 'labelTradeRaceStart',\n  EVENT_READY = 'labelTradeRaceReady',\n  EVENT_END = 'labelTradeRaceEnd',\n}\n\nexport const useTradeRace = () => {\n  const match: any = useRouteMatch('/race-event/:path')\n  const nodeTimer = React.useRef<NodeJS.Timeout | -1>(-1)\n  const { i18n } = useTranslation()\n  const { baseURL } = useSystem()\n  const { search } = useLocation()\n  const searchParams = new URLSearchParams(search)\n  const history = useHistory()\n\n  const [eventData, setEventData] = React.useState<EventData>()\n  const [eventsList, setEventsList] = React.useState<Array<EventData & { type: string }>>([])\n  const [eventStatus, setEventStatus] = React.useState<EVENT_STATUS | undefined>()\n\n  const [countDown, setCountDown] = React.useState<{\n    days: undefined | string\n    hours: undefined | string\n    seconds: undefined | string\n    minutes: undefined | string\n  }>()\n\n  React.useEffect(() => {\n    if (baseURL) {\n      try {\n        // follow /2021/01/2021-01-01.en.json\n        const [year, month] = match?.params.path.split('-')\n        const type = searchParams.get('type')\n        const path = `${/uat/gi.test(baseURL) ? url_test_path : url_path}/${year}/${month}/`\n        if (year && month && type) {\n          fetch(`${path}activities.${languageMap[i18n.language]}.json`)\n            .then((response) => {\n              if (response.ok) {\n                return response.json()\n              } else {\n                history.replace(`/race-event?${searchParams.toString()}`)\n              }\n            })\n            .then((input: { [key: string]: EventData }) => input[type])\n            .then(async (eventData: EventData) => {\n              myLog('useTradeRace eventData', eventData)\n              if (eventData) {\n                // https://uat2.loopring.io/api/v3/activity/getFilterInfo?version=1\n                const configUrl = `${baseURL}/${Config_INFO_URL}?version=${eventData.api?.version}`\n                myLog('baseURL', configUrl)\n                const config: [{ [key: string]: any }, string] = await Promise.all([\n                  fetch(configUrl).then((response) => {\n                    if (response.ok) {\n                      return response.json()\n                    } else {\n                      return {}\n                    }\n                  }),\n                  fetch(`${path}activities/${eventData.rule?.split('/').pop()}`)\n                    .then((response) => response.text())\n                    .then((input) => {\n                      return input\n                    })\n                    .catch(() => {\n                      return ''\n                    }),\n                ])\n                const startUnix =\n                  config[0].start ??\n                  moment.utc(eventData.duration.startDate, 'MM/DD/YYYY HH:mm:ss').valueOf()\n                const endUnix =\n                  config[0].end ??\n                  moment.utc(eventData.duration.endDate, 'MM/DD/YYYY HH:mm:ss').valueOf()\n\n                setEventData({\n                  ...eventData,\n                  banner: {\n                    pad: eventData.banner?.pad\n                      ? /uat/gi.test(baseURL)\n                        ? `${path}activities/${eventData.banner?.pad?.split('/').pop()}`\n                        : eventData.banner.pad //`${path}/`\n                      : undefined,\n                    laptop: eventData.banner?.laptop\n                      ? /uat/gi.test(baseURL)\n                        ? `${path}activities/${eventData.banner?.laptop?.split('/').pop()}`\n                        : eventData.banner.laptop //`${path}/`\n                      : undefined,\n                    mobile: eventData.banner?.mobile\n                      ? /uat/gi.test(baseURL)\n                        ? `${path}activities/${eventData.banner?.mobile?.split('/').pop()}`\n                        : eventData.banner.mobile\n                      : undefined,\n                  },\n                  duration: {\n                    ...eventData.duration,\n                    startDate: startUnix,\n                    endDate: endUnix,\n                  },\n                  ruleMarkdown: config[1],\n                  api: {\n                    ...eventData.api,\n                    ...config[0],\n                  },\n                })\n\n                if (startUnix > Date.now()) {\n                  setEventStatus(EVENT_STATUS.EVENT_READY)\n                } else if (endUnix > Date.now()) {\n                  setEventStatus(EVENT_STATUS.EVENT_START)\n                } else {\n                  setEventStatus(EVENT_STATUS.EVENT_END)\n                }\n              } else {\n                throw 'no EventData'\n              }\n            })\n            .catch((e) => {\n              searchParams.set('type', '')\n              // history.push(match.url + \"?\" + searchParams.toString());\n              window.open(`./#${match.url}?` + searchParams.toString(), '_self')\n              window.opener = null\n              window.location.reload()\n            })\n        } else if (year && month && !type) {\n          fetch(`${path}activities.${languageMap[i18n.language]}.json`)\n            .then((response) => {\n              if (response.ok) {\n                return response.json()\n              } else {\n                history.replace(`/race-event?${searchParams.toString()}`)\n              }\n            })\n            .then((input) => {\n              const eventsList = Reflect.ownKeys(input).map((key) => {\n                // input[key]\n                const startUnix = moment\n                  .utc(input[key].duration?.startDate ?? '', 'MM/DD/YYYY HH:mm:ss')\n                  .valueOf()\n                const endUnix = moment\n                  .utc(input[key].duration?.endDate ?? '', 'MM/DD/YYYY HH:mm:ss')\n                  .valueOf()\n                return {\n                  ...input[key],\n                  type: key,\n                  duration: {\n                    ...input[key].duration,\n                    startDate: startUnix,\n                    endDate: endUnix,\n                  },\n                }\n              })\n              setEventsList(eventsList)\n            })\n        } else {\n          throw 'url format wrong'\n        }\n      } catch (e: any) {\n        myLog(e?.message)\n        history.push('/race-event')\n      }\n    }\n  }, [baseURL, i18n.language])\n\n  const scrollToRule = (event: React.MouseEvent<HTMLElement>) => {\n    const anchor = ((event.target as HTMLElement).ownerDocument || document).querySelector(\n      '#event-rule',\n    )\n\n    if (anchor) {\n      anchor.scrollIntoView({ behavior: 'smooth', block: 'center' })\n    }\n  }\n\n  const calculateTimeLeft = React.useCallback(() => {\n    if (eventData && eventStatus) {\n      if (eventStatus === EVENT_STATUS.EVENT_READY) {\n        let difference = +new Date(eventData.duration.startDate) - Date.now()\n\n        setCountDown({\n          days: Math.floor(difference / (1000 * 60 * 60 * 24)).toString(),\n          hours: ('0' + Math.floor((difference / (1000 * 60 * 60)) % 24).toString()).slice(-2),\n          minutes: ('0' + Math.floor((difference / 1000 / 60) % 60).toString()).slice(-2),\n          seconds: ('0' + Math.floor((difference / 1000) % 60).toString()).slice(-2),\n        })\n      } else if (eventStatus === EVENT_STATUS.EVENT_START) {\n        let difference = +new Date(eventData.duration.endDate) - Date.now()\n        setCountDown({\n          days: Math.floor(difference / (1000 * 60 * 60 * 24)).toString(),\n          hours: ('0' + Math.floor((difference / (1000 * 60 * 60)) % 24).toString()).slice(-2),\n          minutes: ('0' + Math.floor((difference / 1000 / 60) % 60).toString()).slice(-2),\n          seconds: ('0' + Math.floor((difference / 1000) % 60).toString()).slice(-2),\n        })\n      }\n      if (nodeTimer.current !== -1) {\n        clearTimeout(nodeTimer.current as NodeJS.Timeout)\n      }\n      nodeTimer.current = setTimeout(calculateTimeLeft, 1000)\n    }\n  }, [eventData, eventStatus])\n  React.useEffect(() => {\n    if (eventStatus) {\n      if (nodeTimer.current !== -1) {\n        clearTimeout(nodeTimer.current as NodeJS.Timeout)\n      }\n      calculateTimeLeft()\n    }\n    return () => {\n      if (nodeTimer.current !== -1) {\n        clearTimeout(nodeTimer.current as NodeJS.Timeout)\n      }\n    }\n  }, [eventStatus])\n\n  return {\n    eventData,\n    match,\n    // selected,\n    // currMarketPair,\n    filteredAmmViewMap: [],\n    countDown,\n    eventsList,\n    // handleFilterChange,\n    searchParams,\n    // onChange,\n    // duration,\n    scrollToRule,\n    // activityRule,\n    eventStatus,\n  }\n}\n"
  },
  {
    "path": "packages/web-earn/src/pages/TradeRacePage/index.tsx",
    "content": "import React from 'react'\nimport { withTranslation, WithTranslation } from 'react-i18next'\nimport {\n  Box,\n  BoxProps,\n  Card,\n  CardContent,\n  Container,\n  Fab,\n  Grid,\n  Link,\n  Typography,\n} from '@mui/material'\nimport styled from '@emotion/styled'\nimport { LoadingBlock, ScrollTop } from '@loopring-web/component-lib'\nimport { EVENT_STATUS, useTradeRace } from './hook'\nimport {\n  EmptyValueTag,\n  GoTopIcon,\n  MarkdownStyle,\n  YEAR_DAY_SECOND_FORMAT,\n} from '@loopring-web/common-resources'\n\nimport { RankRaw } from './rank'\nimport moment from 'moment'\nimport ReactMarkdown from 'react-markdown'\nimport gfm from 'remark-gfm'\nimport rehypeRaw from 'rehype-raw'\nimport { useTheme } from '@emotion/react'\nimport { EventData } from './interface'\n\nconst CardStyled = styled(Card)`\n  // min-height: ${({ theme }) => theme.unit * 61.5}px;\n  display: flex;\n  flex-direction: column;\n  justify-content: space-between;\n  position: relative;\n`\nconst LayoutStyled = styled(Box)<BoxProps & { eventData: EventData }>`\n  width: 100%;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n\n  ${({ eventData: { showBannerOrTitle, banner } }) => {\n    if (showBannerOrTitle == '1' && banner.laptop) {\n      return `\n          margin-top:0;\n          .title-banner {        \n            h1,\n            h2 {\n             overflow: hidden;\n             text-indent:-999999em; \n            }\n            width:100%;\n            min-height: 65.6vw; \n            background-position:50%;\n            background-size: cover;\n            background-repeat: no-repeat;\n            background-image: url(${banner.pad});\n            @media only screen and (max-width: 600px) {\n                background-image: url(${banner.mobile});\n            }\n            @media only screen and (max-width: 992px) {\n              background-image: url(${banner.pad});\n            };\n            @media only screen and (min-width: 1200px) {\n              background-image: url(${banner.laptop});\n              min-height: 280px;\n            }\n          }`\n    }\n  }}\n  ol,\n  ul {\n    list-style: dismal;\n    font-size: ${({ theme }) => theme.fontDefault.body1};\n    margin-left: ${({ theme }) => theme.unit * 2}px;\n\n    li {\n      color: var(--color-text-secondary);\n    }\n\n    li ::marker {\n      content: '  ' counter(list-item) ')  ';\n      display: inline-flex;\n      color: var(--color-text-secondary);\n    }\n  }\n\n  .hours,\n  .minutes {\n    position: relative;\n\n    span:after {\n      display: block;\n      content: ':';\n      position: absolute;\n      right: -8px;\n      top: 0;\n    }\n  }\n` as (props: BoxProps & { eventData: EventData }) => JSX.Element\n// ${cssStyle}\n\nexport const TradeRacePage = withTranslation('common')(({ t }: WithTranslation) => {\n  const { eventData, countDown, scrollToRule, eventStatus, eventsList, searchParams, match } =\n    useTradeRace()\n  const theme = useTheme()\n  const anchorRef = React.useRef()\n  const anchorTopRef = React.createRef()\n\n  // const history = useHistory();\n\n  // myLog(\"activityRule\", eventStatus, activityRule);\n  /*remove: holiday only end\n      const flakes = 160;\n      const flake = React.useMemo(() => {\n        return <div className={\"flake\"} />;\n      }, []);\n      const snows = new Array(flakes).fill(flake, 0, flakes);\n    */\n  return (\n    <>\n      {eventData ? (\n        <>\n          <LayoutStyled\n            ref={anchorTopRef}\n            marginY={4}\n            eventData={eventData}\n            flex={1}\n            id={'tradeRaceTop'}\n          >\n            <ScrollTop>\n              <Fab color='primary' size={'large'} aria-label='scroll back to top'>\n                <GoTopIcon htmlColor={'var(--color-text-button)'} />\n              </Fab>\n            </ScrollTop>\n            <Box className={'title-banner'} marginBottom={4}>\n              <Typography\n                marginY={1}\n                component={'h1'}\n                variant={'h1'}\n                whiteSpace={'pre-line'}\n                textAlign={'center'}\n                dangerouslySetInnerHTML={{ __html: eventData.eventTitle }}\n              />\n\n              <Typography\n                component={'h2'}\n                variant={'h2'}\n                whiteSpace={'pre-line'}\n                textAlign={'center'}\n                dangerouslySetInnerHTML={{ __html: eventData.subTitle }}\n              />\n            </Box>\n\n            {eventStatus && (\n              <Box component={'section'} paddingX={3} marginBottom={4} textAlign={'center'}>\n                <Typography\n                  component={'h2'}\n                  variant={'h4'}\n                  marginBottom={2}\n                  color={'var(--color-text-secondary)'}\n                >\n                  {t(eventStatus)}\n                </Typography>\n                {eventStatus !== EVENT_STATUS.EVENT_END && (\n                  <Box display={'flex'} flexDirection={'row'} alignItems={'center'}>\n                    <Box\n                      className={'day'}\n                      display={'flex'}\n                      flexDirection={'column'}\n                      minWidth={86}\n                      alignItems={'center'}\n                      marginRight={2}\n                    >\n                      <Typography\n                        variant={'h2'}\n                        component={'span'}\n                        color={'var(--color-text-primary)'}\n                      >\n                        {Number(countDown?.days) >= 0 ? countDown?.days : EmptyValueTag}\n                      </Typography>\n                      <Typography\n                        variant={'h4'}\n                        color={'var(--color-text-secondary)'}\n                        marginTop={1}\n                        style={{ textTransform: 'uppercase' }}\n                      >\n                        {t('labelDay')}\n                      </Typography>\n                    </Box>\n                    <Box\n                      className={'hours'}\n                      display={'flex'}\n                      minWidth={86}\n                      flexDirection={'column'}\n                      alignItems={'center'}\n                      marginRight={2}\n                    >\n                      <Typography\n                        variant={'h2'}\n                        component={'span'}\n                        color={'var(--color-text-primary)'}\n                      >\n                        {Number(countDown?.hours) >= 0 ? countDown?.hours : EmptyValueTag}\n                      </Typography>\n                      <Typography\n                        variant={'h4'}\n                        color={'var(--color-text-secondary)'}\n                        marginTop={1}\n                        style={{ textTransform: 'uppercase' }}\n                      >\n                        {t('labelHours')}\n                      </Typography>\n                    </Box>\n                    <Box\n                      className={'minutes'}\n                      display={'flex'}\n                      minWidth={86}\n                      flexDirection={'column'}\n                      alignItems={'center'}\n                      marginRight={2}\n                    >\n                      <Typography\n                        variant={'h2'}\n                        component={'span'}\n                        color={'var(--color-text-primary)'}\n                      >\n                        {Number(countDown?.minutes) >= 0 ? countDown?.minutes : EmptyValueTag}\n                      </Typography>\n                      <Typography\n                        variant={'h4'}\n                        color={'var(--color-text-secondary)'}\n                        marginTop={1}\n                        style={{ textTransform: 'uppercase' }}\n                      >\n                        {t('labelMinutes')}\n                      </Typography>\n                    </Box>\n                    <Box\n                      className={'secondary'}\n                      display={'flex'}\n                      minWidth={86}\n                      flexDirection={'column'}\n                      alignItems={'center'}\n                      marginRight={2}\n                    >\n                      <Typography\n                        variant={'h2'}\n                        component={'span'}\n                        color={'var(--color-text-primary)'}\n                      >\n                        {Number(countDown?.seconds) >= 0 ? countDown?.seconds : EmptyValueTag}\n                      </Typography>\n                      <Typography\n                        variant={'h4'}\n                        color={'var(--color-text-secondary)'}\n                        marginTop={1}\n                        style={{ textTransform: 'uppercase' }}\n                      >\n                        {t('labelSeconds')}\n                      </Typography>\n                    </Box>\n                  </Box>\n                )}\n              </Box>\n            )}\n            {eventData.duration && (\n              <Typography marginBottom={2} paddingX={3} variant={'body1'}>\n                {eventData?.duration?.prev}\n                <Typography\n                  component={'time'}\n                  paddingX={1}\n                  variant={'h5'}\n                  dateTime={eventData.duration.startDate.toFixed()}\n                >\n                  {moment(eventData.duration.startDate).utc().format(YEAR_DAY_SECOND_FORMAT)}\n                </Typography>\n                <Typography component={'span'} variant={'h5'}>\n                  {eventData?.duration?.middle}\n                </Typography>\n                <Typography\n                  component={'time'}\n                  paddingX={1}\n                  variant={'h5'}\n                  dateTime={eventData.duration.endDate.toFixed()}\n                >\n                  {moment(eventData.duration.endDate).utc().format(YEAR_DAY_SECOND_FORMAT)}\n                </Typography>\n                {eventData?.duration?.timeZone && `(${eventData?.duration?.timeZone})`}{' '}\n                {eventData?.duration?.end}\n                <Typography marginLeft={1} component={'span'}>\n                  <Link onClick={(e) => scrollToRule(e)}>{t('labelTradeReadRule')}</Link>\n                </Typography>\n              </Typography>\n            )}\n            {!!(\n              !searchParams.has('rule') &&\n              eventData.api &&\n              eventData.api.version &&\n              eventStatus !== EVENT_STATUS.EVENT_READY\n            ) && <RankRaw {...eventData.api} />}\n\n            <Box\n              ref={anchorRef}\n              maxWidth={1200}\n              width={'100%'}\n              paddingX={3}\n              marginTop={3}\n              id={'event-rule'}\n            >\n              {eventData.ruleMarkdown ? (\n                <MarkdownStyle\n                  container\n                  minHeight={'calc(100% - 260px)'}\n                  flex={1}\n                  marginTop={3}\n                  marginBottom={2}\n                >\n                  <Box\n                    flex={1}\n                    padding={3}\n                    boxSizing={'border-box'}\n                    className={`${theme.mode}  ${theme.mode}-scheme markdown-body MuiPaper-elevation2 no-bg`}\n                  >\n                    <ReactMarkdown\n                      remarkPlugins={[gfm, ...(eventData.rehypeRaw == '1' ? [rehypeRaw] : [])]}\n                      children={eventData.ruleMarkdown}\n                    />\n                  </Box>\n                </MarkdownStyle>\n              ) : (\n                <LoadingBlock />\n              )}\n            </Box>\n          </LayoutStyled>\n        </>\n      ) : eventsList.length ? (\n        <Container\n          maxWidth='lg'\n          style={{\n            display: 'flex',\n            flexDirection: 'column',\n            flex: 1,\n          }}\n        >\n          <Grid container spacing={2} flex={1} marginTop={2}>\n            {eventsList.map((item, index) => (\n              <Grid item sm={12} md={6} lg={4} key={item.type}>\n                <Link\n                  onClick={() => {\n                    searchParams.set('type', item.type)\n                    // window.opene\n                    window.open(`./#${match.url}?` + searchParams.toString(), '_self')\n                    window.opener = null\n                    window.location.reload()\n                    // history.push(match.url + \"?\" );\n                  }}\n                >\n                  <CardStyled>\n                    <CardContent style={{ paddingBottom: 0 }}>\n                      <Box\n                        display={'flex'}\n                        flexDirection={'column'}\n                        justifyContent={'space-between'}\n                        alignItems={'flex-start'}\n                      >\n                        <Typography\n                          variant={'h3'}\n                          component={'p'}\n                          color={'textPrimary'}\n                          fontFamily={'Roboto'}\n                          textAlign={'center'}\n                          width={'100%'}\n                          dangerouslySetInnerHTML={{\n                            __html: item.eventTitle,\n                          }}\n                        />\n                        <Typography\n                          component={'h2'}\n                          variant={'body1'}\n                          whiteSpace={'pre-line'}\n                          textAlign={'left'}\n                          marginTop={2}\n                          paddingX={3}\n                          dangerouslySetInnerHTML={{ __html: item.subTitle }}\n                        />\n                        {item.duration && (\n                          <Typography\n                            marginBottom={2}\n                            paddingX={3}\n                            variant={'body1'}\n                            marginTop={1}\n                            textAlign={'left'}\n                          >\n                            {item?.duration?.prev}\n                            <Typography\n                              component={'time'}\n                              paddingX={1}\n                              variant={'inherit'}\n                              dateTime={item.duration.startDate.toFixed()}\n                            >\n                              {moment(item.duration.startDate).utc().format(YEAR_DAY_SECOND_FORMAT)}\n                            </Typography>\n                            <Typography component={'span'} variant={'inherit'}>\n                              {item?.duration?.middle}\n                            </Typography>\n                            <Typography\n                              component={'time'}\n                              paddingX={1}\n                              variant={'inherit'}\n                              dateTime={item.duration.endDate.toFixed()}\n                            >\n                              {moment(item.duration.endDate).utc().format(YEAR_DAY_SECOND_FORMAT)}\n                            </Typography>\n                            {item?.duration?.timeZone && `(${item?.duration?.timeZone})`}{' '}\n                            {item?.duration?.end}\n                          </Typography>\n                        )}\n                      </Box>\n                    </CardContent>\n                  </CardStyled>\n                </Link>\n              </Grid>\n            ))}\n          </Grid>\n        </Container>\n      ) : (\n        <LoadingBlock />\n      )}\n    </>\n  )\n})\n"
  },
  {
    "path": "packages/web-earn/src/pages/TradeRacePage/interface.ts",
    "content": "export type EventAPI = {\n  version: string\n  column: { key: string; label: string }[]\n  start: number\n  end: number\n}\nexport type EventAPIExtender = {\n  tableColumn: string[]\n  filters: string[]\n}\nexport type EventData = {\n  eventTitle: string\n  subTitle: string\n  local: 'en-US'\n  banner: {\n    laptop?: string\n    mobile?: string\n    pad?: string\n  }\n  showBannerOrTitle: '0' | '1'\n  rule: string\n  ruleMarkdown?: string\n  rehypeRaw: '0' | '1'\n  duration: {\n    prev?: string\n    startDate: number\n    middle?: 'to'\n    endDate: number\n    end?: string\n    timeZone?: string\n  }\n  api: EventAPI & Partial<EventAPIExtender>\n}\n\nexport type API_DATA<R extends object> = {\n  version: number\n  selected: string\n  owner: {\n    rank: string\n    accountId: string\n    address: string\n    usdtValue: string\n  }\n  data: R[]\n}\n\nexport const Config_INFO_URL = 'api/v3/activity/getFilterInfo'\nexport const Activity_URL = '/api/v3/activity/getActivityList'\n"
  },
  {
    "path": "packages/web-earn/src/pages/TradeRacePage/rank.tsx",
    "content": "import React from 'react'\nimport {\n  DropDownIcon,\n  EmptyValueTag,\n  getShortAddr,\n  RowConfig,\n  SoursURL,\n} from '@loopring-web/common-resources'\nimport { Box, MenuItem, Typography } from '@mui/material'\nimport {\n  InputSearch,\n  TablePaddingX,\n  TextField,\n  TradeRaceTable,\n  useSettings,\n} from '@loopring-web/component-lib'\nimport styled from '@emotion/styled'\nimport { useHistory, useLocation } from 'react-router-dom'\nimport { useSystem } from '@loopring-web/core'\nimport { Activity_URL, API_DATA, EventAPI, EventAPIExtender } from './interface'\nimport { useTranslation } from 'react-i18next'\n\nconst WrapperStyled = styled(Box)`\n  background-color: var(--color-box);\n  border-radius: ${({ theme }) => theme.unit}px;\n`\nconst StyledTextFiled = styled(TextField)`\n  &.MuiTextField-root {\n    max-width: initial;\n  }\n\n  .MuiInputBase-root {\n    width: initial;\n    max-width: initial;\n  }\n`\n\nconst TableStyled = styled(Box)<{ height: number | undefined | string }>`\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n\n  .rdg {\n    height: ${({ height }) => height}px;\n    height: auto;\n\n    .rdgCellCenter {\n      height: 100%;\n      //   display: flex;\n      justify-content: center;\n      align-items: center;\n    }\n\n    .textAlignRight {\n      text-align: right;\n    }\n\n    .textAlignCenter {\n      text-align: center;\n    }\n\n    .textAlignLeft {\n      text-align: left;\n    }\n  }\n\n  ${({ theme }) => TablePaddingX({ pLeft: theme.unit * 3, pRight: theme.unit * 3 })}\n` as typeof Box\n\nexport const RankRaw = <R extends object>({\n  column,\n  version,\n  filters = [],\n}: EventAPI & Partial<EventAPIExtender>) => {\n  const history = useHistory()\n  const { t } = useTranslation()\n  const { isMobile } = useSettings()\n  const { chainId, baseURL } = useSystem()\n  const { search, pathname } = useLocation()\n  const searchParams = new URLSearchParams(search)\n  const [rank, setRank] = React.useState<API_DATA<R> | undefined>(undefined)\n  const [rankTableData, setRankTableData] = React.useState<R[]>([])\n  const [searchValue, setSearchValue] = React.useState<string>('')\n  const [showLoading, setShowLoading] = React.useState(true)\n  const [selected, setSelected] = React.useState<string>(searchParams.get('selected') ?? filters[0])\n  const onChange = (event: React.ChangeEvent<{ value: string }>) => {\n    if (event.target.value) {\n      // setFilter((state) => ({ ...state, value: event.target.value } as any));\n      setSelected(event.target.value)\n      searchParams.set('selected', event.target.value)\n      history.push(pathname + '?' + searchParams.toString())\n    }\n  }\n\n  React.useEffect(() => {\n    if (searchValue !== '' && rank?.data?.length) {\n      setRankTableData((state) =>\n        rank?.data?.filter((item: any) => {\n          if (searchValue.startsWith('0x')) {\n            const regx = new RegExp(searchValue.toLowerCase(), 'ig')\n            return regx.test(item?.address)\n          } else {\n            const regx = new RegExp(searchValue.toLowerCase(), 'ig')\n            return regx.test(item?.address) || regx.test(item?.accountId)\n          }\n        }),\n      )\n    } else if (rank?.data?.length) {\n      setRankTableData([...rank?.data])\n    } else {\n      setRankTableData([])\n    }\n  }, [rank?.data, searchValue])\n\n  React.useEffect(() => {\n    getTableValues()\n  }, [selected])\n  const getTableValues = React.useCallback(async () => {\n    const l2account = searchParams.get('l2account') || searchParams.get('owner')\n    const _selected = filters?.find((item) => selected === item)\n    const url = `${baseURL}/${Activity_URL}?${_selected ? `&selected=${_selected}` : ''}${\n      l2account && l2account !== 'undefined' && l2account !== 'null' ? `&owner=${l2account}` : ''\n    }&version=${version}`\n    fetch(url)\n      .then((response) => response.json())\n      .then((json) => {\n        setRank(() => {\n          return { ...json } as API_DATA<R>\n        })\n        setShowLoading(false)\n      })\n      .catch(() => {\n        return []\n      })\n  }, [chainId, selected])\n\n  return (\n    <Box\n      flex={1}\n      display={'flex'}\n      flexDirection={'column'}\n      maxWidth={1200}\n      width={'100%'}\n      paddingX={isMobile ? 1 : 3}\n    >\n      <WrapperStyled flex={1} padding={isMobile ? 1 : 3}>\n        <Box\n          alignSelf={'flex-end'}\n          marginY={2}\n          display={'flex'}\n          justifyContent={'space-between'}\n          width={'100%'}\n        >\n          {!!filters?.length && (\n            <StyledTextFiled\n              id={'trading-race-filter'}\n              select\n              style={{ width: 150, textAlign: 'left' }}\n              value={selected}\n              onChange={onChange}\n              inputProps={{ IconComponent: DropDownIcon }}\n            >\n              {filters.map((item, index) => (\n                <MenuItem key={item + index} value={item}>\n                  {item}\n                </MenuItem>\n              ))}\n            </StyledTextFiled>\n          )}\n          <InputSearch\n            value={searchValue}\n            onChange={(value: any) => {\n              // setSearchValue(value)\n              setSearchValue(value)\n            }}\n          />\n        </Box>\n        <Box\n          display={'flex'}\n          justifyContent={'center'}\n          alignItems={'center'}\n          flexDirection={isMobile ? 'column' : 'row'}\n        >\n          <Typography\n            variant={'h5'}\n            display={'inline-flex'}\n            alignItems={'center'}\n            paddingRight={3}\n            component={'p'}\n          >\n            {t('labelTradeRaceYourRanking')}\n          </Typography>\n          {column.map((item, index) => (\n            <Typography\n              variant={'body1'}\n              key={item.key}\n              component={'span'}\n              display={'inline-flex'}\n              alignItems={'center'}\n              color={'textSecondary'}\n              whiteSpace={'pre-line'}\n              sx={{ wordBreak: 'break-all' }}\n              paddingRight={2}\n            >\n              {`${item.label}: `}\n              <Typography paddingLeft={1} component={'span'} color={'textPrimary'}>\n                {rank?.owner && rank?.owner[item.key] && rank?.owner[item.key] != '0'\n                  ? /address/gi.test(item.key.toLowerCase())\n                    ? getShortAddr(rank?.owner[item.key])\n                    : rank?.owner[item.key]\n                  : EmptyValueTag}\n              </Typography>\n              {index + 1 !== column.length ? ', ' : ''}\n            </Typography>\n          ))}\n        </Box>\n        <TableStyled\n          minHeight={120}\n          height={(((rankTableData && rankTableData?.length) ?? 0) + 1) * RowConfig.rowHeight}\n        >\n          {rank?.data?.length ? (\n            <TradeRaceTable\n              scrollable={true}\n              column={column}\n              rawData={rankTableData}\n              showloading={showLoading}\n            />\n          ) : (\n            <Box\n              flex={1}\n              height={'100%'}\n              display={'flex'}\n              alignItems={'center'}\n              justifyContent={'center'}\n            >\n              <img\n                className='loading-gif'\n                alt={'loading'}\n                width='60'\n                src={`${SoursURL}images/loading-line.gif`}\n              />\n            </Box>\n          )}\n        </TableStyled>\n      </WrapperStyled>\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/web-earn/src/pages/TradeRacePage/snow.css",
    "content": "@import url(https://fonts.googleapis.com/css?family=Varela+Round);\n\n.snow {\n    position: relative;\n    width: 100%;\n    height: 100%;\n    pointer-events: none;\n    opacity: 0.6;\n}\n\n.flake {\n    position: absolute;\n    border-radius: 50%;\n    transform: translateY(0) rotateX(0) rotateY(0);\n    background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuNSIgeTE9IjAuMCIgeDI9IjAuNSIgeTI9IjEuMCI+PHN0b3Agb2Zmc2V0PSIzMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiIHN0b3Atb3BhY2l0eT0iMC4wIi8+PHN0b3Agb2Zmc2V0PSI1MCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48c3RvcCBvZmZzZXQ9IjYwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIvPjxzdG9wIG9mZnNldD0iNjAlIiBzdG9wLWNvbG9yPSIjZmZmZmZmIiBzdG9wLW9wYWNpdHk9IjAuMCIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA=='),\n    url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIzMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiIHN0b3Atb3BhY2l0eT0iMC4wIi8+PHN0b3Agb2Zmc2V0PSI1MCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48c3RvcCBvZmZzZXQ9IjYwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIvPjxzdG9wIG9mZnNldD0iNjAlIiBzdG9wLWNvbG9yPSIjZmZmZmZmIiBzdG9wLW9wYWNpdHk9IjAuMCIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA=='),\n    url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjEuMCIgeDI9IjEuMCIgeTI9IjAuMCI+PHN0b3Agb2Zmc2V0PSIzMyUiIHN0b3AtY29sb3I9IiNmZmZmZmYiIHN0b3Atb3BhY2l0eT0iMC4wIi8+PHN0b3Agb2Zmc2V0PSI1MyUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48c3RvcCBvZmZzZXQ9IjU3JSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIvPjxzdG9wIG9mZnNldD0iNjUlIiBzdG9wLWNvbG9yPSIjZmZmZmZmIiBzdG9wLW9wYWNpdHk9IjAuMCIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA=='),\n    url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuMCIgeDI9IjEuMCIgeTI9IjEuMCI+PHN0b3Agb2Zmc2V0PSIzMyUiIHN0b3AtY29sb3I9IiNmZmZmZmYiIHN0b3Atb3BhY2l0eT0iMC4wIi8+PHN0b3Agb2Zmc2V0PSI1MyUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48c3RvcCBvZmZzZXQ9IjU3JSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIvPjxzdG9wIG9mZnNldD0iNjUlIiBzdG9wLWNvbG9yPSIjZmZmZmZmIiBzdG9wLW9wYWNpdHk9IjAuMCIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');\n    background-size: 100%;\n    background-image: linear-gradient(\n            180deg,\n            rgba(255, 255, 255, 0) 30%,\n            #ffffff 50%,\n            #ffffff 60%,\n            rgba(255, 255, 255, 0) 60%\n    ),\n    linear-gradient(\n            90deg,\n            rgba(255, 255, 255, 0) 30%,\n            #ffffff 50%,\n            #ffffff 60%,\n            rgba(255, 255, 255, 0) 60%\n    ),\n    linear-gradient(\n            45deg,\n            rgba(255, 255, 255, 0) 33%,\n            #ffffff 53%,\n            #ffffff 57%,\n            rgba(255, 255, 255, 0) 65%\n    ),\n    linear-gradient(\n            135deg,\n            rgba(255, 255, 255, 0) 33%,\n            #ffffff 53%,\n            #ffffff 57%,\n            rgba(255, 255, 255, 0) 65%\n    );\n}\n\n.flake:nth-child(1) {\n    width: 7px;\n    height: 7px;\n    top: -35px;\n    left: 55%;\n    opacity: 0.79;\n    filter: blur(3px);\n    -webkit-animation: 36s flakes linear infinite;\n    animation: 36s flakes linear infinite;\n}\n\n.flake:nth-child(2) {\n    width: 19px;\n    height: 19px;\n    top: -51px;\n    left: 25%;\n    opacity: 0.94;\n    filter: blur(3px);\n    -webkit-animation: 19s flakes linear infinite;\n    animation: 19s flakes linear infinite;\n}\n\n.flake:nth-child(3) {\n    width: 9px;\n    height: 9px;\n    top: -457px;\n    left: 33%;\n    opacity: 0.68;\n    filter: blur(3px);\n    -webkit-animation: 26s flakes linear infinite;\n    animation: 26s flakes linear infinite;\n}\n\n.flake:nth-child(4) {\n    width: 16px;\n    height: 16px;\n    top: -626px;\n    left: 72%;\n    opacity: 0.59;\n    filter: blur(4px);\n    -webkit-animation: 16s flakes linear infinite;\n    animation: 16s flakes linear infinite;\n}\n\n.flake:nth-child(5) {\n    width: 9px;\n    height: 9px;\n    top: -487px;\n    left: 3%;\n    opacity: 0.93;\n    filter: blur(3px);\n    -webkit-animation: 18s flakes linear infinite;\n    animation: 18s flakes linear infinite;\n}\n\n.flake:nth-child(6) {\n    width: 14px;\n    height: 14px;\n    top: -591px;\n    left: 85%;\n    opacity: 0.61;\n    filter: blur(4px);\n    -webkit-animation: 18s flakes linear infinite;\n    animation: 18s flakes linear infinite;\n}\n\n.flake:nth-child(7) {\n    width: 16px;\n    height: 16px;\n    top: -229px;\n    left: 83%;\n    opacity: 0.72;\n    filter: blur(3px);\n    -webkit-animation: 57s flakes linear infinite;\n    animation: 57s flakes linear infinite;\n}\n\n.flake:nth-child(8) {\n    width: 18px;\n    height: 18px;\n    top: -289px;\n    left: 29%;\n    opacity: 0.84;\n    filter: blur(4px);\n    -webkit-animation: 28s flakes linear infinite;\n    animation: 28s flakes linear infinite;\n}\n\n.flake:nth-child(9) {\n    width: 18px;\n    height: 18px;\n    top: -159px;\n    left: 71%;\n    opacity: 0.7;\n    filter: blur(3px);\n    -webkit-animation: 59s flakes linear infinite;\n    animation: 59s flakes linear infinite;\n}\n\n.flake:nth-child(10) {\n    width: 11px;\n    height: 11px;\n    top: -591px;\n    left: 8%;\n    opacity: 0.9;\n    filter: blur(3px);\n    -webkit-animation: 66s flakes linear infinite;\n    animation: 66s flakes linear infinite;\n}\n\n.flake:nth-child(11) {\n    width: 11px;\n    height: 11px;\n    top: -234px;\n    left: 86%;\n    opacity: 0.88;\n    filter: blur(4px);\n    -webkit-animation: 26s flakes linear infinite;\n    animation: 26s flakes linear infinite;\n}\n\n.flake:nth-child(12) {\n    width: 18px;\n    height: 18px;\n    top: -568px;\n    left: 26%;\n    opacity: 0.82;\n    filter: blur(4px);\n    -webkit-animation: 54s flakes linear infinite;\n    animation: 54s flakes linear infinite;\n}\n\n.flake:nth-child(13) {\n    width: 19px;\n    height: 19px;\n    top: -229px;\n    left: 14%;\n    opacity: 0.77;\n    filter: blur(3px);\n    -webkit-animation: 33s flakes linear infinite;\n    animation: 33s flakes linear infinite;\n}\n\n.flake:nth-child(14) {\n    width: 8px;\n    height: 8px;\n    top: -15px;\n    left: 5%;\n    opacity: 0.65;\n    filter: blur(4px);\n    -webkit-animation: 45s flakes linear infinite;\n    animation: 45s flakes linear infinite;\n}\n\n.flake:nth-child(15) {\n    width: 17px;\n    height: 17px;\n    top: -192px;\n    left: 96%;\n    opacity: 0.67;\n    filter: blur(3px);\n    -webkit-animation: 65s flakes linear infinite;\n    animation: 65s flakes linear infinite;\n}\n\n.flake:nth-child(16) {\n    width: 12px;\n    height: 12px;\n    top: -486px;\n    left: 66%;\n    opacity: 0.83;\n    filter: blur(3px);\n    -webkit-animation: 34s flakes linear infinite;\n    animation: 34s flakes linear infinite;\n}\n\n.flake:nth-child(17) {\n    width: 20px;\n    height: 20px;\n    top: -659px;\n    left: 85%;\n    opacity: 0.95;\n    filter: blur(3px);\n    -webkit-animation: 62s flakes linear infinite;\n    animation: 62s flakes linear infinite;\n}\n\n.flake:nth-child(18) {\n    width: 6px;\n    height: 6px;\n    top: -62px;\n    left: 29%;\n    opacity: 0.67;\n    filter: blur(3px);\n    -webkit-animation: 30s flakes linear infinite;\n    animation: 30s flakes linear infinite;\n}\n\n.flake:nth-child(19) {\n    width: 11px;\n    height: 11px;\n    top: -380px;\n    left: 21%;\n    opacity: 0.97;\n    filter: blur(4px);\n    -webkit-animation: 16s flakes linear infinite;\n    animation: 16s flakes linear infinite;\n}\n\n.flake:nth-child(20) {\n    width: 10px;\n    height: 10px;\n    top: -340px;\n    left: 10%;\n    opacity: 0.69;\n    filter: blur(3px);\n    -webkit-animation: 32s flakes linear infinite;\n    animation: 32s flakes linear infinite;\n}\n\n.flake:nth-child(21) {\n    width: 14px;\n    height: 14px;\n    top: -390px;\n    left: 28%;\n    opacity: 0.84;\n    filter: blur(3px);\n    -webkit-animation: 70s flakes linear infinite;\n    animation: 70s flakes linear infinite;\n}\n\n.flake:nth-child(22) {\n    width: 10px;\n    height: 10px;\n    top: -630px;\n    left: 45%;\n    opacity: 0.87;\n    filter: blur(3px);\n    -webkit-animation: 38s flakes linear infinite;\n    animation: 38s flakes linear infinite;\n}\n\n.flake:nth-child(23) {\n    width: 11px;\n    height: 11px;\n    top: -402px;\n    left: 82%;\n    opacity: 0.95;\n    filter: blur(4px);\n    -webkit-animation: 26s flakes linear infinite;\n    animation: 26s flakes linear infinite;\n}\n\n.flake:nth-child(24) {\n    width: 11px;\n    height: 11px;\n    top: -403px;\n    left: 61%;\n    opacity: 0.87;\n    filter: blur(3px);\n    -webkit-animation: 55s flakes linear infinite;\n    animation: 55s flakes linear infinite;\n}\n\n.flake:nth-child(25) {\n    width: 9px;\n    height: 9px;\n    top: -294px;\n    left: 57%;\n    opacity: 0.93;\n    filter: blur(4px);\n    -webkit-animation: 37s flakes linear infinite;\n    animation: 37s flakes linear infinite;\n}\n\n.flake:nth-child(26) {\n    width: 7px;\n    height: 7px;\n    top: -175px;\n    left: 45%;\n    opacity: 0.56;\n    filter: blur(4px);\n    -webkit-animation: 18s flakes linear infinite;\n    animation: 18s flakes linear infinite;\n}\n\n.flake:nth-child(27) {\n    width: 9px;\n    height: 9px;\n    top: -113px;\n    left: 2%;\n    opacity: 0.77;\n    filter: blur(3px);\n    -webkit-animation: 39s flakes linear infinite;\n    animation: 39s flakes linear infinite;\n}\n\n.flake:nth-child(28) {\n    width: 10px;\n    height: 10px;\n    top: -167px;\n    left: 50%;\n    opacity: 0.63;\n    filter: blur(3px);\n    -webkit-animation: 26s flakes linear infinite;\n    animation: 26s flakes linear infinite;\n}\n\n.flake:nth-child(29) {\n    width: 13px;\n    height: 13px;\n    top: -27px;\n    left: 59%;\n    opacity: 0.99;\n    filter: blur(3px);\n    -webkit-animation: 57s flakes linear infinite;\n    animation: 57s flakes linear infinite;\n}\n\n.flake:nth-child(30) {\n    width: 19px;\n    height: 19px;\n    top: -331px;\n    left: 94%;\n    opacity: 0.55;\n    filter: blur(4px);\n    -webkit-animation: 25s flakes linear infinite;\n    animation: 25s flakes linear infinite;\n}\n\n.flake:nth-child(31) {\n    width: 10px;\n    height: 10px;\n    top: -464px;\n    left: 73%;\n    opacity: 0.89;\n    filter: blur(4px);\n    -webkit-animation: 16s flakes linear infinite;\n    animation: 16s flakes linear infinite;\n}\n\n.flake:nth-child(32) {\n    width: 18px;\n    height: 18px;\n    top: -92px;\n    left: 66%;\n    opacity: 0.88;\n    filter: blur(3px);\n    -webkit-animation: 31s flakes linear infinite;\n    animation: 31s flakes linear infinite;\n}\n\n.flake:nth-child(33) {\n    width: 11px;\n    height: 11px;\n    top: -183px;\n    left: 76%;\n    opacity: 0.57;\n    filter: blur(4px);\n    -webkit-animation: 26s flakes linear infinite;\n    animation: 26s flakes linear infinite;\n}\n\n.flake:nth-child(34) {\n    width: 9px;\n    height: 9px;\n    top: -183px;\n    left: 15%;\n    opacity: 0.87;\n    filter: blur(3px);\n    -webkit-animation: 54s flakes linear infinite;\n    animation: 54s flakes linear infinite;\n}\n\n.flake:nth-child(35) {\n    width: 9px;\n    height: 9px;\n    top: -425px;\n    left: 10%;\n    opacity: 0.74;\n    filter: blur(3px);\n    -webkit-animation: 17s flakes linear infinite;\n    animation: 17s flakes linear infinite;\n}\n\n.flake:nth-child(36) {\n    width: 20px;\n    height: 20px;\n    top: -72px;\n    left: 23%;\n    opacity: 0.53;\n    filter: blur(3px);\n    -webkit-animation: 19s flakes linear infinite;\n    animation: 19s flakes linear infinite;\n}\n\n.flake:nth-child(37) {\n    width: 7px;\n    height: 7px;\n    top: -308px;\n    left: 56%;\n    opacity: 0.87;\n    filter: blur(4px);\n    -webkit-animation: 17s flakes linear infinite;\n    animation: 17s flakes linear infinite;\n}\n\n.flake:nth-child(38) {\n    width: 18px;\n    height: 18px;\n    top: -199px;\n    left: 15%;\n    opacity: 0.64;\n    filter: blur(4px);\n    -webkit-animation: 56s flakes linear infinite;\n    animation: 56s flakes linear infinite;\n}\n\n.flake:nth-child(39) {\n    width: 13px;\n    height: 13px;\n    top: -262px;\n    left: 59%;\n    opacity: 0.64;\n    filter: blur(4px);\n    -webkit-animation: 49s flakes linear infinite;\n    animation: 49s flakes linear infinite;\n}\n\n.flake:nth-child(40) {\n    width: 7px;\n    height: 7px;\n    top: -26px;\n    left: 83%;\n    opacity: 0.71;\n    filter: blur(4px);\n    -webkit-animation: 42s flakes linear infinite;\n    animation: 42s flakes linear infinite;\n}\n\n.flake:nth-child(41) {\n    width: 9px;\n    height: 9px;\n    top: -250px;\n    left: 67%;\n    opacity: 0.63;\n    filter: blur(4px);\n    -webkit-animation: 63s flakes linear infinite;\n    animation: 63s flakes linear infinite;\n}\n\n.flake:nth-child(42) {\n    width: 20px;\n    height: 20px;\n    top: -178px;\n    left: 86%;\n    opacity: 0.96;\n    filter: blur(4px);\n    -webkit-animation: 29s flakes linear infinite;\n    animation: 29s flakes linear infinite;\n}\n\n.flake:nth-child(43) {\n    width: 6px;\n    height: 6px;\n    top: -586px;\n    left: 73%;\n    opacity: 0.53;\n    filter: blur(4px);\n    -webkit-animation: 48s flakes linear infinite;\n    animation: 48s flakes linear infinite;\n}\n\n.flake:nth-child(44) {\n    width: 14px;\n    height: 14px;\n    top: -660px;\n    left: 47%;\n    opacity: 0.67;\n    filter: blur(4px);\n    -webkit-animation: 39s flakes linear infinite;\n    animation: 39s flakes linear infinite;\n}\n\n.flake:nth-child(45) {\n    width: 19px;\n    height: 19px;\n    top: -201px;\n    left: 95%;\n    opacity: 0.85;\n    filter: blur(3px);\n    -webkit-animation: 18s flakes linear infinite;\n    animation: 18s flakes linear infinite;\n}\n\n.flake:nth-child(46) {\n    width: 9px;\n    height: 9px;\n    top: -511px;\n    left: 90%;\n    opacity: 0.64;\n    filter: blur(3px);\n    -webkit-animation: 63s flakes linear infinite;\n    animation: 63s flakes linear infinite;\n}\n\n.flake:nth-child(47) {\n    width: 18px;\n    height: 18px;\n    top: -665px;\n    left: 62%;\n    opacity: 0.8;\n    filter: blur(3px);\n    -webkit-animation: 18s flakes linear infinite;\n    animation: 18s flakes linear infinite;\n}\n\n.flake:nth-child(48) {\n    width: 14px;\n    height: 14px;\n    top: -199px;\n    left: 93%;\n    opacity: 0.61;\n    filter: blur(4px);\n    -webkit-animation: 18s flakes linear infinite;\n    animation: 18s flakes linear infinite;\n}\n\n.flake:nth-child(49) {\n    width: 11px;\n    height: 11px;\n    top: -239px;\n    left: 34%;\n    opacity: 0.63;\n    filter: blur(4px);\n    -webkit-animation: 61s flakes linear infinite;\n    animation: 61s flakes linear infinite;\n}\n\n.flake:nth-child(50) {\n    width: 9px;\n    height: 9px;\n    top: -255px;\n    left: 98%;\n    opacity: 0.92;\n    filter: blur(3px);\n    -webkit-animation: 43s flakes linear infinite;\n    animation: 43s flakes linear infinite;\n}\n\n.flake:nth-child(51) {\n    width: 13px;\n    height: 13px;\n    top: -638px;\n    left: 1%;\n    opacity: 0.67;\n    filter: blur(3px);\n    -webkit-animation: 59s flakes linear infinite;\n    animation: 59s flakes linear infinite;\n}\n\n.flake:nth-child(52) {\n    width: 14px;\n    height: 14px;\n    top: -51px;\n    left: 99%;\n    opacity: 0.94;\n    filter: blur(3px);\n    -webkit-animation: 44s flakes linear infinite;\n    animation: 44s flakes linear infinite;\n}\n\n.flake:nth-child(53) {\n    width: 15px;\n    height: 15px;\n    top: -660px;\n    left: 76%;\n    opacity: 0.95;\n    filter: blur(3px);\n    -webkit-animation: 48s flakes linear infinite;\n    animation: 48s flakes linear infinite;\n}\n\n.flake:nth-child(54) {\n    width: 7px;\n    height: 7px;\n    top: -367px;\n    left: 10%;\n    opacity: 0.91;\n    filter: blur(4px);\n    -webkit-animation: 69s flakes linear infinite;\n    animation: 69s flakes linear infinite;\n}\n\n.flake:nth-child(55) {\n    width: 10px;\n    height: 10px;\n    top: -226px;\n    left: 16%;\n    opacity: 0.58;\n    filter: blur(4px);\n    -webkit-animation: 23s flakes linear infinite;\n    animation: 23s flakes linear infinite;\n}\n\n.flake:nth-child(56) {\n    width: 19px;\n    height: 19px;\n    top: -253px;\n    left: 51%;\n    opacity: 0.52;\n    filter: blur(3px);\n    -webkit-animation: 26s flakes linear infinite;\n    animation: 26s flakes linear infinite;\n}\n\n.flake:nth-child(57) {\n    width: 14px;\n    height: 14px;\n    top: -608px;\n    left: 87%;\n    opacity: 0.66;\n    filter: blur(3px);\n    -webkit-animation: 43s flakes linear infinite;\n    animation: 43s flakes linear infinite;\n}\n\n.flake:nth-child(58) {\n    width: 14px;\n    height: 14px;\n    top: -96px;\n    left: 64%;\n    opacity: 0.89;\n    filter: blur(4px);\n    -webkit-animation: 22s flakes linear infinite;\n    animation: 22s flakes linear infinite;\n}\n\n.flake:nth-child(59) {\n    width: 15px;\n    height: 15px;\n    top: -289px;\n    left: 61%;\n    opacity: 0.67;\n    filter: blur(3px);\n    -webkit-animation: 67s flakes linear infinite;\n    animation: 67s flakes linear infinite;\n}\n\n.flake:nth-child(60) {\n    width: 8px;\n    height: 8px;\n    top: -12px;\n    left: 75%;\n    opacity: 0.63;\n    filter: blur(4px);\n    -webkit-animation: 40s flakes linear infinite;\n    animation: 40s flakes linear infinite;\n}\n\n.flake:nth-child(61) {\n    width: 19px;\n    height: 19px;\n    top: -577px;\n    left: 85%;\n    opacity: 0.64;\n    filter: blur(4px);\n    -webkit-animation: 61s flakes linear infinite;\n    animation: 61s flakes linear infinite;\n}\n\n.flake:nth-child(62) {\n    width: 17px;\n    height: 17px;\n    top: -460px;\n    left: 17%;\n    opacity: 0.98;\n    filter: blur(3px);\n    -webkit-animation: 62s flakes linear infinite;\n    animation: 62s flakes linear infinite;\n}\n\n.flake:nth-child(63) {\n    width: 9px;\n    height: 9px;\n    top: -185px;\n    left: 20%;\n    opacity: 0.86;\n    filter: blur(3px);\n    -webkit-animation: 40s flakes linear infinite;\n    animation: 40s flakes linear infinite;\n}\n\n.flake:nth-child(64) {\n    width: 14px;\n    height: 14px;\n    top: -513px;\n    left: 14%;\n    opacity: 0.65;\n    filter: blur(3px);\n    -webkit-animation: 67s flakes linear infinite;\n    animation: 67s flakes linear infinite;\n}\n\n.flake:nth-child(65) {\n    width: 9px;\n    height: 9px;\n    top: -626px;\n    left: 8%;\n    opacity: 0.61;\n    filter: blur(3px);\n    -webkit-animation: 70s flakes linear infinite;\n    animation: 70s flakes linear infinite;\n}\n\n.flake:nth-child(66) {\n    width: 14px;\n    height: 14px;\n    top: -433px;\n    left: 68%;\n    opacity: 0.95;\n    filter: blur(3px);\n    -webkit-animation: 20s flakes linear infinite;\n    animation: 20s flakes linear infinite;\n}\n\n.flake:nth-child(67) {\n    width: 16px;\n    height: 16px;\n    top: -283px;\n    left: 41%;\n    opacity: 0.58;\n    filter: blur(4px);\n    -webkit-animation: 68s flakes linear infinite;\n    animation: 68s flakes linear infinite;\n}\n\n.flake:nth-child(68) {\n    width: 15px;\n    height: 15px;\n    top: -242px;\n    left: 57%;\n    opacity: 0.95;\n    filter: blur(4px);\n    -webkit-animation: 38s flakes linear infinite;\n    animation: 38s flakes linear infinite;\n}\n\n.flake:nth-child(69) {\n    width: 8px;\n    height: 8px;\n    top: -505px;\n    left: 90%;\n    opacity: 0.66;\n    filter: blur(3px);\n    -webkit-animation: 51s flakes linear infinite;\n    animation: 51s flakes linear infinite;\n}\n\n.flake:nth-child(70) {\n    width: 16px;\n    height: 16px;\n    top: -15px;\n    left: 34%;\n    opacity: 0.96;\n    filter: blur(3px);\n    -webkit-animation: 53s flakes linear infinite;\n    animation: 53s flakes linear infinite;\n}\n\n.flake:nth-child(71) {\n    width: 17px;\n    height: 17px;\n    top: -386px;\n    left: 34%;\n    opacity: 0.62;\n    filter: blur(4px);\n    -webkit-animation: 28s flakes linear infinite;\n    animation: 28s flakes linear infinite;\n}\n\n.flake:nth-child(72) {\n    width: 16px;\n    height: 16px;\n    top: -42px;\n    left: 47%;\n    opacity: 0.96;\n    filter: blur(4px);\n    -webkit-animation: 18s flakes linear infinite;\n    animation: 18s flakes linear infinite;\n}\n\n.flake:nth-child(73) {\n    width: 15px;\n    height: 15px;\n    top: -559px;\n    left: 17%;\n    opacity: 0.93;\n    filter: blur(4px);\n    -webkit-animation: 47s flakes linear infinite;\n    animation: 47s flakes linear infinite;\n}\n\n.flake:nth-child(74) {\n    width: 15px;\n    height: 15px;\n    top: -570px;\n    left: 2%;\n    opacity: 0.9;\n    filter: blur(3px);\n    -webkit-animation: 30s flakes linear infinite;\n    animation: 30s flakes linear infinite;\n}\n\n.flake:nth-child(75) {\n    width: 10px;\n    height: 10px;\n    top: -612px;\n    left: 53%;\n    opacity: 0.92;\n    filter: blur(4px);\n    -webkit-animation: 40s flakes linear infinite;\n    animation: 40s flakes linear infinite;\n}\n\n.flake:nth-child(76) {\n    width: 19px;\n    height: 19px;\n    top: -185px;\n    left: 84%;\n    opacity: 0.91;\n    filter: blur(3px);\n    -webkit-animation: 37s flakes linear infinite;\n    animation: 37s flakes linear infinite;\n}\n\n.flake:nth-child(77) {\n    width: 9px;\n    height: 9px;\n    top: -605px;\n    left: 1%;\n    opacity: 0.83;\n    filter: blur(4px);\n    -webkit-animation: 62s flakes linear infinite;\n    animation: 62s flakes linear infinite;\n}\n\n.flake:nth-child(78) {\n    width: 19px;\n    height: 19px;\n    top: -95px;\n    left: 43%;\n    opacity: 0.69;\n    filter: blur(3px);\n    -webkit-animation: 23s flakes linear infinite;\n    animation: 23s flakes linear infinite;\n}\n\n.flake:nth-child(79) {\n    width: 8px;\n    height: 8px;\n    top: -547px;\n    left: 53%;\n    opacity: 0.76;\n    filter: blur(4px);\n    -webkit-animation: 46s flakes linear infinite;\n    animation: 46s flakes linear infinite;\n}\n\n.flake:nth-child(80) {\n    width: 17px;\n    height: 17px;\n    top: -118px;\n    left: 88%;\n    opacity: 0.68;\n    filter: blur(3px);\n    -webkit-animation: 37s flakes linear infinite;\n    animation: 37s flakes linear infinite;\n}\n\n.flake:nth-child(81) {\n    width: 17px;\n    height: 17px;\n    top: -466px;\n    left: 38%;\n    opacity: 0.67;\n    filter: blur(3px);\n    -webkit-animation: 26s flakes linear infinite;\n    animation: 26s flakes linear infinite;\n}\n\n.flake:nth-child(82) {\n    width: 11px;\n    height: 11px;\n    top: -670px;\n    left: 24%;\n    opacity: 0.74;\n    filter: blur(4px);\n    -webkit-animation: 37s flakes linear infinite;\n    animation: 37s flakes linear infinite;\n}\n\n.flake:nth-child(83) {\n    width: 9px;\n    height: 9px;\n    top: -188px;\n    left: 37%;\n    opacity: 0.89;\n    filter: blur(4px);\n    -webkit-animation: 40s flakes linear infinite;\n    animation: 40s flakes linear infinite;\n}\n\n.flake:nth-child(84) {\n    width: 13px;\n    height: 13px;\n    top: -273px;\n    left: 44%;\n    opacity: 0.53;\n    filter: blur(3px);\n    -webkit-animation: 58s flakes linear infinite;\n    animation: 58s flakes linear infinite;\n}\n\n.flake:nth-child(85) {\n    width: 14px;\n    height: 14px;\n    top: -579px;\n    left: 6%;\n    opacity: 0.82;\n    filter: blur(4px);\n    -webkit-animation: 29s flakes linear infinite;\n    animation: 29s flakes linear infinite;\n}\n\n.flake:nth-child(86) {\n    width: 13px;\n    height: 13px;\n    top: -699px;\n    left: 88%;\n    opacity: 0.91;\n    filter: blur(4px);\n    -webkit-animation: 51s flakes linear infinite;\n    animation: 51s flakes linear infinite;\n}\n\n.flake:nth-child(87) {\n    width: 14px;\n    height: 14px;\n    top: -265px;\n    left: 64%;\n    opacity: 0.92;\n    filter: blur(3px);\n    -webkit-animation: 67s flakes linear infinite;\n    animation: 67s flakes linear infinite;\n}\n\n.flake:nth-child(88) {\n    width: 10px;\n    height: 10px;\n    top: -113px;\n    left: 76%;\n    opacity: 0.87;\n    filter: blur(3px);\n    -webkit-animation: 61s flakes linear infinite;\n    animation: 61s flakes linear infinite;\n}\n\n.flake:nth-child(89) {\n    width: 7px;\n    height: 7px;\n    top: -146px;\n    left: 78%;\n    opacity: 0.97;\n    filter: blur(4px);\n    -webkit-animation: 38s flakes linear infinite;\n    animation: 38s flakes linear infinite;\n}\n\n.flake:nth-child(90) {\n    width: 19px;\n    height: 19px;\n    top: -105px;\n    left: 82%;\n    opacity: 0.85;\n    filter: blur(4px);\n    -webkit-animation: 61s flakes linear infinite;\n    animation: 61s flakes linear infinite;\n}\n\n.flake:nth-child(91) {\n    width: 10px;\n    height: 10px;\n    top: -287px;\n    left: 94%;\n    opacity: 0.9;\n    filter: blur(4px);\n    -webkit-animation: 38s flakes linear infinite;\n    animation: 38s flakes linear infinite;\n}\n\n.flake:nth-child(92) {\n    width: 10px;\n    height: 10px;\n    top: -140px;\n    left: 28%;\n    opacity: 0.96;\n    filter: blur(4px);\n    -webkit-animation: 27s flakes linear infinite;\n    animation: 27s flakes linear infinite;\n}\n\n.flake:nth-child(93) {\n    width: 16px;\n    height: 16px;\n    top: -494px;\n    left: 3%;\n    opacity: 0.54;\n    filter: blur(3px);\n    -webkit-animation: 32s flakes linear infinite;\n    animation: 32s flakes linear infinite;\n}\n\n.flake:nth-child(94) {\n    width: 7px;\n    height: 7px;\n    top: -482px;\n    left: 91%;\n    opacity: 0.76;\n    filter: blur(4px);\n    -webkit-animation: 58s flakes linear infinite;\n    animation: 58s flakes linear infinite;\n}\n\n.flake:nth-child(95) {\n    width: 7px;\n    height: 7px;\n    top: -334px;\n    left: 48%;\n    opacity: 0.87;\n    filter: blur(3px);\n    -webkit-animation: 21s flakes linear infinite;\n    animation: 21s flakes linear infinite;\n}\n\n.flake:nth-child(96) {\n    width: 9px;\n    height: 9px;\n    top: -147px;\n    left: 65%;\n    opacity: 0.85;\n    filter: blur(4px);\n    -webkit-animation: 33s flakes linear infinite;\n    animation: 33s flakes linear infinite;\n}\n\n.flake:nth-child(97) {\n    width: 20px;\n    height: 20px;\n    top: -33px;\n    left: 52%;\n    opacity: 0.67;\n    filter: blur(3px);\n    -webkit-animation: 49s flakes linear infinite;\n    animation: 49s flakes linear infinite;\n}\n\n.flake:nth-child(98) {\n    width: 7px;\n    height: 7px;\n    top: -260px;\n    left: 65%;\n    opacity: 0.69;\n    filter: blur(4px);\n    -webkit-animation: 27s flakes linear infinite;\n    animation: 27s flakes linear infinite;\n}\n\n.flake:nth-child(99) {\n    width: 15px;\n    height: 15px;\n    top: -249px;\n    left: 47%;\n    opacity: 0.66;\n    filter: blur(4px);\n    -webkit-animation: 26s flakes linear infinite;\n    animation: 26s flakes linear infinite;\n}\n\n.flake:nth-child(100) {\n    width: 16px;\n    height: 16px;\n    top: -490px;\n    left: 86%;\n    opacity: 0.63;\n    filter: blur(3px);\n    -webkit-animation: 26s flakes linear infinite;\n    animation: 26s flakes linear infinite;\n}\n\n.flake:nth-child(101) {\n    width: 9px;\n    height: 9px;\n    top: -363px;\n    left: 49%;\n    opacity: 0.89;\n    filter: blur(3px);\n    -webkit-animation: 67s flakes linear infinite;\n    animation: 67s flakes linear infinite;\n}\n\n.flake:nth-child(102) {\n    width: 19px;\n    height: 19px;\n    top: -103px;\n    left: 1%;\n    opacity: 0.77;\n    filter: blur(4px);\n    -webkit-animation: 31s flakes linear infinite;\n    animation: 31s flakes linear infinite;\n}\n\n.flake:nth-child(103) {\n    width: 7px;\n    height: 7px;\n    top: -660px;\n    left: 17%;\n    opacity: 0.93;\n    filter: blur(4px);\n    -webkit-animation: 68s flakes linear infinite;\n    animation: 68s flakes linear infinite;\n}\n\n.flake:nth-child(104) {\n    width: 15px;\n    height: 15px;\n    top: -679px;\n    left: 46%;\n    opacity: 0.53;\n    filter: blur(3px);\n    -webkit-animation: 48s flakes linear infinite;\n    animation: 48s flakes linear infinite;\n}\n\n.flake:nth-child(105) {\n    width: 11px;\n    height: 11px;\n    top: -217px;\n    left: 92%;\n    opacity: 0.78;\n    filter: blur(4px);\n    -webkit-animation: 69s flakes linear infinite;\n    animation: 69s flakes linear infinite;\n}\n\n.flake:nth-child(106) {\n    width: 7px;\n    height: 7px;\n    top: -239px;\n    left: 32%;\n    opacity: 0.62;\n    filter: blur(4px);\n    -webkit-animation: 51s flakes linear infinite;\n    animation: 51s flakes linear infinite;\n}\n\n.flake:nth-child(107) {\n    width: 19px;\n    height: 19px;\n    top: -373px;\n    left: 56%;\n    opacity: 0.82;\n    filter: blur(4px);\n    -webkit-animation: 53s flakes linear infinite;\n    animation: 53s flakes linear infinite;\n}\n\n.flake:nth-child(108) {\n    width: 16px;\n    height: 16px;\n    top: -625px;\n    left: 90%;\n    opacity: 0.77;\n    filter: blur(3px);\n    -webkit-animation: 42s flakes linear infinite;\n    animation: 42s flakes linear infinite;\n}\n\n.flake:nth-child(109) {\n    width: 14px;\n    height: 14px;\n    top: -551px;\n    left: 90%;\n    opacity: 0.78;\n    filter: blur(3px);\n    -webkit-animation: 60s flakes linear infinite;\n    animation: 60s flakes linear infinite;\n}\n\n.flake:nth-child(110) {\n    width: 8px;\n    height: 8px;\n    top: -662px;\n    left: 12%;\n    opacity: 0.82;\n    filter: blur(4px);\n    -webkit-animation: 57s flakes linear infinite;\n    animation: 57s flakes linear infinite;\n}\n\n.flake:nth-child(111) {\n    width: 14px;\n    height: 14px;\n    top: -308px;\n    left: 43%;\n    opacity: 0.97;\n    filter: blur(4px);\n    -webkit-animation: 65s flakes linear infinite;\n    animation: 65s flakes linear infinite;\n}\n\n.flake:nth-child(112) {\n    width: 6px;\n    height: 6px;\n    top: -677px;\n    left: 24%;\n    opacity: 0.58;\n    filter: blur(3px);\n    -webkit-animation: 55s flakes linear infinite;\n    animation: 55s flakes linear infinite;\n}\n\n.flake:nth-child(113) {\n    width: 12px;\n    height: 12px;\n    top: -650px;\n    left: 11%;\n    opacity: 0.99;\n    filter: blur(4px);\n    -webkit-animation: 46s flakes linear infinite;\n    animation: 46s flakes linear infinite;\n}\n\n.flake:nth-child(114) {\n    width: 14px;\n    height: 14px;\n    top: -460px;\n    left: 72%;\n    opacity: 0.96;\n    filter: blur(4px);\n    -webkit-animation: 58s flakes linear infinite;\n    animation: 58s flakes linear infinite;\n}\n\n.flake:nth-child(115) {\n    width: 19px;\n    height: 19px;\n    top: -187px;\n    left: 8%;\n    opacity: 0.73;\n    filter: blur(3px);\n    -webkit-animation: 27s flakes linear infinite;\n    animation: 27s flakes linear infinite;\n}\n\n.flake:nth-child(116) {\n    width: 13px;\n    height: 13px;\n    top: -54px;\n    left: 70%;\n    opacity: 0.64;\n    filter: blur(3px);\n    -webkit-animation: 26s flakes linear infinite;\n    animation: 26s flakes linear infinite;\n}\n\n.flake:nth-child(117) {\n    width: 15px;\n    height: 15px;\n    top: -231px;\n    left: 2%;\n    opacity: 0.93;\n    filter: blur(3px);\n    -webkit-animation: 51s flakes linear infinite;\n    animation: 51s flakes linear infinite;\n}\n\n.flake:nth-child(118) {\n    width: 10px;\n    height: 10px;\n    top: -439px;\n    left: 6%;\n    opacity: 0.94;\n    filter: blur(4px);\n    -webkit-animation: 40s flakes linear infinite;\n    animation: 40s flakes linear infinite;\n}\n\n.flake:nth-child(119) {\n    width: 12px;\n    height: 12px;\n    top: -371px;\n    left: 69%;\n    opacity: 0.93;\n    filter: blur(4px);\n    -webkit-animation: 41s flakes linear infinite;\n    animation: 41s flakes linear infinite;\n}\n\n.flake:nth-child(120) {\n    width: 16px;\n    height: 16px;\n    top: -295px;\n    left: 68%;\n    opacity: 0.72;\n    filter: blur(4px);\n    -webkit-animation: 39s flakes linear infinite;\n    animation: 39s flakes linear infinite;\n}\n\n.flake:nth-child(121) {\n    width: 19px;\n    height: 19px;\n    top: -610px;\n    left: 35%;\n    opacity: 0.8;\n    filter: blur(3px);\n    -webkit-animation: 33s flakes linear infinite;\n    animation: 33s flakes linear infinite;\n}\n\n.flake:nth-child(122) {\n    width: 12px;\n    height: 12px;\n    top: -405px;\n    left: 27%;\n    opacity: 0.68;\n    filter: blur(3px);\n    -webkit-animation: 43s flakes linear infinite;\n    animation: 43s flakes linear infinite;\n}\n\n.flake:nth-child(123) {\n    width: 19px;\n    height: 19px;\n    top: -166px;\n    left: 30%;\n    opacity: 0.61;\n    filter: blur(3px);\n    -webkit-animation: 33s flakes linear infinite;\n    animation: 33s flakes linear infinite;\n}\n\n.flake:nth-child(124) {\n    width: 7px;\n    height: 7px;\n    top: -69px;\n    left: 33%;\n    opacity: 0.66;\n    filter: blur(4px);\n    -webkit-animation: 57s flakes linear infinite;\n    animation: 57s flakes linear infinite;\n}\n\n.flake:nth-child(125) {\n    width: 16px;\n    height: 16px;\n    top: -196px;\n    left: 95%;\n    opacity: 0.51;\n    filter: blur(4px);\n    -webkit-animation: 23s flakes linear infinite;\n    animation: 23s flakes linear infinite;\n}\n\n.flake:nth-child(126) {\n    width: 7px;\n    height: 7px;\n    top: -470px;\n    left: 31%;\n    opacity: 0.52;\n    filter: blur(4px);\n    -webkit-animation: 52s flakes linear infinite;\n    animation: 52s flakes linear infinite;\n}\n\n.flake:nth-child(127) {\n    width: 11px;\n    height: 11px;\n    top: -233px;\n    left: 67%;\n    opacity: 0.98;\n    filter: blur(4px);\n    -webkit-animation: 70s flakes linear infinite;\n    animation: 70s flakes linear infinite;\n}\n\n.flake:nth-child(128) {\n    width: 9px;\n    height: 9px;\n    top: -489px;\n    left: 96%;\n    opacity: 0.62;\n    filter: blur(4px);\n    -webkit-animation: 18s flakes linear infinite;\n    animation: 18s flakes linear infinite;\n}\n\n.flake:nth-child(129) {\n    width: 10px;\n    height: 10px;\n    top: -285px;\n    left: 94%;\n    opacity: 0.73;\n    filter: blur(4px);\n    -webkit-animation: 49s flakes linear infinite;\n    animation: 49s flakes linear infinite;\n}\n\n.flake:nth-child(130) {\n    width: 18px;\n    height: 18px;\n    top: -619px;\n    left: 44%;\n    opacity: 0.64;\n    filter: blur(3px);\n    -webkit-animation: 38s flakes linear infinite;\n    animation: 38s flakes linear infinite;\n}\n\n.flake:nth-child(131) {\n    width: 18px;\n    height: 18px;\n    top: -50px;\n    left: 100%;\n    opacity: 0.71;\n    filter: blur(3px);\n    -webkit-animation: 39s flakes linear infinite;\n    animation: 39s flakes linear infinite;\n}\n\n.flake:nth-child(132) {\n    width: 16px;\n    height: 16px;\n    top: -423px;\n    left: 56%;\n    opacity: 0.68;\n    filter: blur(3px);\n    -webkit-animation: 50s flakes linear infinite;\n    animation: 50s flakes linear infinite;\n}\n\n.flake:nth-child(133) {\n    width: 18px;\n    height: 18px;\n    top: -616px;\n    left: 93%;\n    opacity: 0.79;\n    filter: blur(3px);\n    -webkit-animation: 29s flakes linear infinite;\n    animation: 29s flakes linear infinite;\n}\n\n.flake:nth-child(134) {\n    width: 13px;\n    height: 13px;\n    top: -618px;\n    left: 73%;\n    opacity: 0.71;\n    filter: blur(4px);\n    -webkit-animation: 18s flakes linear infinite;\n    animation: 18s flakes linear infinite;\n}\n\n.flake:nth-child(135) {\n    width: 17px;\n    height: 17px;\n    top: -239px;\n    left: 31%;\n    opacity: 0.64;\n    filter: blur(4px);\n    -webkit-animation: 48s flakes linear infinite;\n    animation: 48s flakes linear infinite;\n}\n\n.flake:nth-child(136) {\n    width: 11px;\n    height: 11px;\n    top: -522px;\n    left: 57%;\n    opacity: 0.95;\n    filter: blur(3px);\n    -webkit-animation: 21s flakes linear infinite;\n    animation: 21s flakes linear infinite;\n}\n\n.flake:nth-child(137) {\n    width: 17px;\n    height: 17px;\n    top: -78px;\n    left: 73%;\n    opacity: 0.52;\n    filter: blur(4px);\n    -webkit-animation: 30s flakes linear infinite;\n    animation: 30s flakes linear infinite;\n}\n\n.flake:nth-child(138) {\n    width: 10px;\n    height: 10px;\n    top: -108px;\n    left: 100%;\n    opacity: 0.96;\n    filter: blur(4px);\n    -webkit-animation: 29s flakes linear infinite;\n    animation: 29s flakes linear infinite;\n}\n\n.flake:nth-child(139) {\n    width: 18px;\n    height: 18px;\n    top: -441px;\n    left: 58%;\n    opacity: 0.81;\n    filter: blur(4px);\n    -webkit-animation: 67s flakes linear infinite;\n    animation: 67s flakes linear infinite;\n}\n\n.flake:nth-child(140) {\n    width: 9px;\n    height: 9px;\n    top: -144px;\n    left: 30%;\n    opacity: 0.96;\n    filter: blur(4px);\n    -webkit-animation: 45s flakes linear infinite;\n    animation: 45s flakes linear infinite;\n}\n\n.flake:nth-child(141) {\n    width: 20px;\n    height: 20px;\n    top: -176px;\n    left: 67%;\n    opacity: 0.71;\n    filter: blur(4px);\n    -webkit-animation: 46s flakes linear infinite;\n    animation: 46s flakes linear infinite;\n}\n\n.flake:nth-child(142) {\n    width: 6px;\n    height: 6px;\n    top: -583px;\n    left: 60%;\n    opacity: 0.92;\n    filter: blur(4px);\n    -webkit-animation: 29s flakes linear infinite;\n    animation: 29s flakes linear infinite;\n}\n\n.flake:nth-child(143) {\n    width: 10px;\n    height: 10px;\n    top: -570px;\n    left: 31%;\n    opacity: 0.64;\n    filter: blur(4px);\n    -webkit-animation: 18s flakes linear infinite;\n    animation: 18s flakes linear infinite;\n}\n\n.flake:nth-child(144) {\n    width: 13px;\n    height: 13px;\n    top: -313px;\n    left: 78%;\n    opacity: 0.51;\n    filter: blur(3px);\n    -webkit-animation: 58s flakes linear infinite;\n    animation: 58s flakes linear infinite;\n}\n\n.flake:nth-child(145) {\n    width: 20px;\n    height: 20px;\n    top: -663px;\n    left: 28%;\n    opacity: 0.97;\n    filter: blur(3px);\n    -webkit-animation: 68s flakes linear infinite;\n    animation: 68s flakes linear infinite;\n}\n\n.flake:nth-child(146) {\n    width: 6px;\n    height: 6px;\n    top: -445px;\n    left: 18%;\n    opacity: 0.76;\n    filter: blur(3px);\n    -webkit-animation: 27s flakes linear infinite;\n    animation: 27s flakes linear infinite;\n}\n\n.flake:nth-child(147) {\n    width: 6px;\n    height: 6px;\n    top: -464px;\n    left: 2%;\n    opacity: 0.56;\n    filter: blur(4px);\n    -webkit-animation: 23s flakes linear infinite;\n    animation: 23s flakes linear infinite;\n}\n\n.flake:nth-child(148) {\n    width: 18px;\n    height: 18px;\n    top: -523px;\n    left: 82%;\n    opacity: 0.56;\n    filter: blur(4px);\n    -webkit-animation: 66s flakes linear infinite;\n    animation: 66s flakes linear infinite;\n}\n\n.flake:nth-child(149) {\n    width: 20px;\n    height: 20px;\n    top: -400px;\n    left: 62%;\n    opacity: 0.6;\n    filter: blur(4px);\n    -webkit-animation: 48s flakes linear infinite;\n    animation: 48s flakes linear infinite;\n}\n\n.flake:nth-child(150) {\n    width: 20px;\n    height: 20px;\n    top: -399px;\n    left: 36%;\n    opacity: 0.72;\n    filter: blur(3px);\n    -webkit-animation: 69s flakes linear infinite;\n    animation: 69s flakes linear infinite;\n}\n\n@-webkit-keyframes flakes {\n    100% {\n        transform: translateY(1000px) rotateX(35deg) rotateY(27deg);\n        opacity: 0;\n    }\n}\n\n@keyframes flakes {\n    100% {\n        transform: translateY(1000px) rotateX(35deg) rotateY(27deg);\n        opacity: 0;\n    }\n}\n"
  },
  {
    "path": "packages/web-earn/src/react-app-env.d.ts",
    "content": "/// <reference types=\"react-scripts\" />\n// window.__loopringEnv__ = process.env;\n"
  },
  {
    "path": "packages/web-earn/src/reportWebVitals.ts",
    "content": "import { ReportHandler } from 'web-vitals'\n\nconst reportWebVitals = (onPerfEntry?: ReportHandler) => {\n  if (onPerfEntry && onPerfEntry instanceof Function) {\n    import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {\n      getCLS(onPerfEntry)\n      getFID(onPerfEntry)\n      getFCP(onPerfEntry)\n      getLCP(onPerfEntry)\n      getTTFB(onPerfEntry)\n    })\n  }\n}\n\nexport default reportWebVitals\n"
  },
  {
    "path": "packages/web-earn/src/routers/index.tsx",
    "content": "import { Redirect, Route, Switch, useLocation } from 'react-router-dom'\nimport React from 'react'\nimport { Box, Container, Link } from '@mui/material'\nimport Header from 'layouts/header'\nimport {\n  ModalCoinPairPanel,\n  ModalGroup,\n  ModalRedPacketPanel,\n  store,\n  useDeposit,\n  useOffFaitModal,\n  useSystem,\n  useTicker,\n  useTokenMap,\n} from '@loopring-web/core'\nimport { LoadingPage } from '../pages/LoadingPage'\nimport {\n  ErrorMap,\n  GUARDIAN_URL,\n  MapChainId,\n  // RouterAllowIndex,\n  // RouterMainKey,\n  // RouterPath,\n  SagaStatus,\n  setMyLog,\n  ThemeType,\n  VendorProviders,\n  WalletSite,\n} from '@loopring-web/common-resources'\nimport { ErrorPage } from '../pages/ErrorPage'\nimport {\n  LoadingBlock,\n  NoticePanelSnackBar,\n  NoticeSnack,\n  useSettings,\n  useToggle,\n  VaultPage,\n} from '@loopring-web/component-lib'\nimport { InvestMarkdownPage, MarkdownPage, NotifyMarkdownPage } from '../pages/MarkdownPage'\nimport { TradeRacePage } from '../pages/TradeRacePage'\nimport { useGetAssets } from '../pages/AssetPage/AssetPanel/hook'\nimport { Footer } from '../layouts/footer'\nimport { InvestPage } from '../pages/InvestPage'\nimport { getAnalytics, logEvent } from 'firebase/analytics'\nimport { AssetPage } from '../pages/AssetPage'\nimport { useTranslation } from 'react-i18next'\nimport { EarnPage } from '../pages/EarnPage'\nimport { RouterAllowIndex, RouterMainKey, RouterPath } from '../constant/router'\nimport { Layer2Page } from '../pages/Layer2Page'\nimport { BtradeSwapPage } from '../pages/BtradeSwapPage'\nimport { TaikoLockBannerPage, TaikoLockPage } from 'pages/TaikoLockPage'\n\n// RouterAllowIndex\nconst ContentWrap = ({\n  children,\n  state,\n  noContainer = false,\n  value,\n  noPending\n}: React.PropsWithChildren<any> & {\n  state: keyof typeof SagaStatus\n  noContainer: boolean\n  noPending?: boolean\n  value: string\n}) => {\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  return (\n    <>\n      <Header isHideOnScroll={false} />\n      {state === 'PENDING' && !noPending ? (\n        <LoadingBlock />\n      ) : state === 'ERROR' || !RouterAllowIndex[network]?.includes(value) ? (\n        <ErrorPage\n          {...(!RouterAllowIndex[network]?.includes(value)\n            ? ErrorMap.TRADE_404\n            : ErrorMap.NO_NETWORK_ERROR)}\n        />\n      ) : noContainer ? (\n        <>{children}</>\n      ) : (\n        <Container\n          maxWidth='lg'\n          style={{\n            display: 'flex',\n            flexDirection: 'column',\n            flex: 1,\n          }}\n        >\n          <Box display={'flex'} flex={1} alignItems={'stretch'} flexDirection={'row'} marginTop={3}>\n            {children}\n          </Box>\n        </Container>\n      )}\n    </>\n  )\n}\n\nconst WrapModal = () => {\n  const { assetsRawData } = useGetAssets()\n  const location = useLocation()\n  const { etherscanBaseUrl } = useSystem()\n  const { t } = useTranslation()\n  const { depositProps } = useDeposit(false, { owner: store.getState()?.account?.accAddress })\n\n  const { open, actionEle, handleClose } = useOffFaitModal()\n\n  const noticeSnacksElEs = React.useMemo(() => {\n    return [\n      <NoticeSnack\n        actionEle={actionEle}\n        open={open}\n        handleClose={handleClose}\n        messageInfo={{\n          svgIcon: 'BanxaIcon',\n          key: VendorProviders.Banxa,\n          message: t('labelOrderBanxaIsReadyToPay'),\n        }}\n      />,\n    ] as any\n  }, [open, actionEle])\n  return (\n    <>\n      <ModalCoinPairPanel />\n      <ModalRedPacketPanel etherscanBaseUrl={etherscanBaseUrl} />\n      <ModalGroup\n        assetsRawData={assetsRawData}\n        depositProps={depositProps}\n        isLayer1Only={/(guardian)|(depositto)/gi.test(location.pathname ?? '')}\n        hideDepositWithdrawBack\n        isWebEarn\n      />\n      <NoticePanelSnackBar noticeSnacksElEs={noticeSnacksElEs} />\n    </>\n  )\n}\n\nconst RouterView = ({ state }: { state: keyof typeof SagaStatus }) => {\n  const location = useLocation()\n  const searchParams = new URLSearchParams(location.search)\n  const { tickerMap } = useTicker()\n  const { marketArray } = useTokenMap()\n  const { setTheme, defaultNetwork, setReferralCode } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n\n  const {\n    toggle: { BTradeInvest, StopLimit },\n  } = useToggle()\n\n  React.useEffect(() => {\n    if (searchParams.has('theme')) {\n      searchParams.get('theme') === ThemeType.dark ? setTheme('dark') : setTheme('light')\n    }\n    if (searchParams.has('referralcode')) {\n      const value = searchParams.get('referralcode')\n      setReferralCode(value ? value : '')\n    }\n  }, [location.search])\n\n  React.useEffect(() => {\n    if (state === SagaStatus.ERROR) {\n      window.location.replace(`${window.location.origin}/error`)\n    }\n  }, [state])\n  if (searchParams.has('___OhTrustDebugger___')) {\n    // @ts-ignore\n    setMyLog(true)\n  }\n  const analytics = getAnalytics()\n\n  logEvent(analytics, 'Route', {\n    protocol: window.location.protocol,\n    pathname: window.location.pathname,\n    query: searchParams,\n  })\n  React.useEffect(() => {\n    if (/^\\/?wallet/.test(location.pathname)) {\n      window.open(WalletSite, '_self')\n      window.opener = null\n    }\n  }, [location.pathname])\n  return (\n    <>\n      <Switch>\n        <Route exact path='/loading'>\n          <LoadingPage />\n        </Route>\n        \n        <Route path='/document'>\n          {searchParams && searchParams.has('noheader') ? (\n            <></>\n          ) : (\n            <Header isHideOnScroll={true} isLandPage />\n          )}\n          <Container\n            maxWidth='lg'\n            style={{\n              display: 'flex',\n              flexDirection: 'column',\n              flex: 1,\n            }}\n          >\n            <MarkdownPage />\n          </Container>\n        </Route>\n        <Route exact path={'/'} children={ <Redirect to={RouterPath.l2assets} /> }/>\n        <Route exact path='/notification/:path'>\n          {searchParams && searchParams.has('noheader') ? (\n            <></>\n          ) : (\n            <Header isHideOnScroll={true} isLandPage />\n          )}\n          <Container\n            maxWidth='lg'\n            style={{\n              display: 'flex',\n              flexDirection: 'column',\n              flex: 1,\n            }}\n          >\n            <NotifyMarkdownPage />\n          </Container>\n        </Route>\n        <Route exact path='/investrule/:path'>\n          {searchParams && searchParams.has('noheader') ? (\n            <></>\n          ) : (\n            <Header isHideOnScroll={true} isLandPage />\n          )}\n          <Container\n            maxWidth='lg'\n            style={{\n              display: 'flex',\n              flexDirection: 'column',\n              flex: 1,\n            }}\n          >\n            <InvestMarkdownPage />\n          </Container>\n        </Route>\n        <Route exact path={['/document', '/race-event', '/notification', '/investrule']}>\n          {searchParams && searchParams.has('noheader') ? <></> : <Header isHideOnScroll={true} />}\n          <ErrorPage messageKey={'error404'} />\n        </Route>\n        <Route exact path={['/race-event/:path']}>\n          {searchParams && searchParams.has('noheader') ? <></> : <Header isHideOnScroll={true} />}\n          <TradeRacePage />\n        </Route>\n\n        <Route path={RouterPath.btrade}>\n          <ContentWrap state={state} value={RouterMainKey.btrade}>\n            <BtradeSwapPage />\n          </ContentWrap>\n        </Route>\n\n        {/* <Route path={RouterPath.pro}>\n          {searchParams && searchParams.has('noheader') ? <></> : <Header isHideOnScroll={true} />}\n\n          {state === 'PENDING' && tickerMap ? (\n            <LoadingBlock />\n          ) : RouterAllowIndex[network]?.includes(RouterMainKey.pro) ? (\n            <OrderbookPage />\n          ) : (\n            <ErrorPage {...ErrorMap.TRADE_404} />\n          )}\n        </Route>\n        <Route path={RouterPath.stoplimit}>\n          {searchParams && searchParams.has('noheader') ? <></> : <Header isHideOnScroll={true} />}\n\n          {state === 'PENDING' || !marketArray.length || !Object.keys(tickerMap ?? {}).length ? (\n            <LoadingBlock />\n          ) : RouterAllowIndex[network]?.includes(RouterMainKey.stoplimit) ? (\n            <StopLimitPage />\n          ) : (\n            <ErrorPage {...ErrorMap.TRADE_404} />\n          )}\n        </Route>\n        <Route path={RouterPath.lite}>\n          <ContentWrap state={state} value={RouterMainKey.lite}>\n            <SwapPage />\n          </ContentWrap>\n        </Route>\n        <Route path={RouterPath.btrade}>\n          <ContentWrap state={state} value={RouterMainKey.btrade}>\n            <BtradeSwapPage />\n          </ContentWrap>\n        </Route>\n        <Route exact path={[RouterPath.fiat, RouterPath.fiat + '/*']}>\n          <ContentWrap state={state} value={RouterMainKey.fiat}>\n            <FiatPage />\n          </ContentWrap>\n        </Route> */}\n        {/* <Redirect */}\n        {/* <Redirect to={RouterPath.dualIntro} exact path={'/'} /> */}\n          {/* <ContentWrap state={state} value={RouterMainKey.dualIntro}>\n            <EarnPage />\n          </ContentWrap>\n        </Redirect> */}\n        \n\n        <Route exact path={RouterPath.dualIntro}>\n          <ContentWrap state={state} value={RouterMainKey.dualIntro}>\n            <EarnPage />\n          </ContentWrap>\n        </Route>\n        <Route exact path={[RouterPath.portal, RouterPath.portal + '/*']}>\n          <ContentWrap state={state} noContainer value={RouterMainKey.portal}>\n            <VaultPage />\n          </ContentWrap>\n        </Route>\n        \n        <Route path={[RouterPath.layer2, RouterPath.layer2 + '/*']}>\n          <ContentWrap state={state} noContainer={true} value={RouterMainKey.layer2}>\n            <Layer2Page />\n          </ContentWrap>\n        </Route>\n        <Route exact path={[RouterPath.l2assets, RouterPath.l2assets + '/*']}>\n          <ContentWrap noContainer state={state} value={RouterMainKey.l2assets}>\n            <AssetPage />\n          </ContentWrap>\n        </Route>\n        <Route exact path={[RouterPath.invest, RouterPath.invest + '/*']}>\n          <ContentWrap noContainer state={state} value={RouterMainKey.invest}>\n            <InvestPage />\n          </ContentWrap>\n        </Route>\n        <Route exact path={[RouterPath.taikoFarming ]}>\n          <ContentWrap noContainer state={state} value={RouterMainKey.taikoFarming}>\n            <TaikoLockPage symbol='TAIKO' setConfirmedLRCStakeInvestInvest={() => {}} />\n          </ContentWrap>\n        </Route>\n        <Route exact path={`${RouterPath.taikoFarming}/banner`}>\n          <ContentWrap noContainer state={state} value={RouterMainKey.taikoFarming}>\n            <TaikoLockBannerPage />\n          </ContentWrap>\n        </Route>\n\n        <Route\n          path={['/guardian', '/guardian/*']}\n          component={() => (\n            <>\n              <Header isHideOnScroll={true} isLandPage />\n              <ErrorPage\n                {...ErrorMap.GUARDIAN_ROUTER_ERROR}\n                components={{\n                  a: <Link target='_blank' rel='noopener noreferrer' href={GUARDIAN_URL} />,\n                }}\n              />\n            </>\n          )}\n        />\n        <Route\n          path={['/error/:messageKey', '/error']}\n          component={() => (\n            <>\n              <Header isHideOnScroll={true} isLandPage />\n              <ErrorPage {...ErrorMap.NO_NETWORK_ERROR} />\n            </>\n          )}\n        />\n        <Route\n          component={() => (\n            <>\n              <Header isHideOnScroll={true} isLandPage />\n              <ErrorPage messageKey={'error404'} />\n            </>\n          )}\n        />\n      </Switch>\n      {state === SagaStatus.DONE && <WrapModal />}\n      {searchParams && searchParams.has('nofooter') ? <></> : <Footer />}\n    </>\n  )\n}\n\nexport default RouterView\n"
  },
  {
    "path": "packages/web-earn/src/setupTests.ts",
    "content": "// jest-dom adds custom jest matchers for asserting on DOM nodes.\n// allows you to do things like:\n// expect(element).toHaveTextContent(/react/i)\n// learn more: https://github.com/testing-library/jest-dom\nimport '@testing-library/jest-dom'\n"
  },
  {
    "path": "packages/web-earn/src/types.d.ts",
    "content": "import { LoopringSocket } from '@loopring-web/core'\nimport { RampInstantSDK } from '@ramp-network/ramp-instant-sdk'\n\ndeclare module '*.html' {\n  const value: string\n  export default value\n}\n/// <reference types=\"@google/model-viewer\" />\n\ndeclare global {\n  interface Window {\n    loopringSocket: InstanceType<LoopringSocket>\n    __renderReportCall__: () => void\n    rampInstance: RampInstantSDK | undefined\n    __ChainIdExtends: any\n    __MapChainId: any\n  }\n\n  namespace JSX {\n    interface IntrinsicElements {\n      'model-viewer': MyElementAttributes\n    }\n\n    interface MyElementAttributes {\n      src: string\n      'auto-rotate': any\n      'camera-controls': any\n      'ar-modes': any\n      'touch-action': any\n      'shadow-intensity': any\n      poster?: string\n\n      [key: string]: any\n    }\n  }\n}\n"
  },
  {
    "path": "packages/web-earn/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.build.json\",\n  \"compilerOptions\": {\n    \"baseUrl\": \"src/\",\n    \"rootDir\": \".\",\n    \"noEmit\": true\n  },\n  \"include\": [\n    \"src\",\n    \"src/*\",\n    \"src/**/*.json\",\n    \"src/types.d.ts\"\n  ],\n  \"awesomeTypescriptLoaderOptions\": {\n    \"useCache\": true,\n    \"transpileOnly\": true\n  }\n}\n"
  },
  {
    "path": "packages/web-guardian/.babelrc",
    "content": "{\n  \"presets\": [\n    [\n      \"@babel/preset-env\",\n      {\n        \"targets\": {\n          \"node\": \"current\"\n        },\n        \"loose\": true\n      }\n    ],\n    [\n      \"@babel/preset-react\",\n      {\n        \"runtime\": \"automatic\"\n      }\n    ]\n  ],\n  \"plugins\": [\n    \"@babel/plugin-transform-typescript\",\n    \"@babel/plugin-proposal-nullish-coalescing-operator\",\n    \"@babel/plugin-proposal-optional-chaining\"\n  ]\n}\n"
  },
  {
    "path": "packages/web-guardian/.eslintrc.json",
    "content": "{\n  \"parser\": \"@typescript-eslint/parser\",\n  \"plugins\": [\n    \"react-hooks\",\n    \"@typescript-eslint\"\n  ],\n  \"extends\": [\n    \"react-app\"\n  ],\n  \"overrides\": [\n    {\n      \"files\": [\n        \"**/*.tsx\",\n        \"**/*.ts\"\n      ],\n      \"rules\": {\n        \"import/no-anonymous-default-export\": \"off\",\n        \"@typescript-eslint/no-unused-vars\": \"warn\",\n        \"react-hooks/rules-of-hooks\": \"error\",\n        // 检查 Hook 的规则\n        \"react-hooks/exhaustive-deps\": \"warn\"\n        // 检查 effect 的依赖\n      }\n    }\n  ]\n}\n"
  },
  {
    "path": "packages/web-guardian/.gitignore",
    "content": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n# Runtime data\npids\n*.pid\n*.seed\n*.pid.lock\n\n# Directory for instrumented libs generated by jscoverage/JSCover\nlib-cov\n\n# Coverage directory used by tools like istanbul\ncoverage\n\n# nyc test coverage\n.nyc_output\n\n# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)\n.grunt\n\n# Bower dependency directory (https://bower.io/)\nbower_components\n\n# node-waf configuration\n.lock-wscript\n\n# Compiled binary addons (https://nodejs.org/api/addons.html)\nbuild/Release\n\n# Dependency directories\nnode_modules/\njspm_packages/\n\n# TypeScript v1 declaration files\ntypings/\n\n# Optional npm cache directory\n.npm\n\n# Optional eslint cache\n.eslintcache\n\n# Optional REPL history\n.node_repl_history\n\n# Output of 'npm pack'\n*.tgz\n\n# Yarn Integrity file\n.yarn-integrity\n\n# dotenv environment variables file\n.env\n\n# parcel-bundler cache (https://parceljs.org/)\n.cache\n\n# next.js build output\n.next\n\n# nuxt.js build output\n.nuxt\n\n# vuepress build output\n.vuepress/dist\n\n# Serverless directories\n.serverless/\n\n# FuseBox cache\n.fusebox/\n\n# DynamoDB Local files\n.dynamodb/\n# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\n/node_modules\n/.pnp\n.pnp.js\n\n# testing\n/coverage\n\n# production\n**/build\n/out\n/dist\n\n# misc\n.DS_Store\n.env.local\n.env.development.local\n# .env.prod_for_dev\n\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n*.code-workspace\n.vscode\nopenapitools.json\n*.tgz\n.idea/\ntestkey.txt\n\ntest_datadir\n\nipfs_deploy.txt\n.env.deploy*\n.testfile*\n.DS_Store\n"
  },
  {
    "path": "packages/web-guardian/README.md",
    "content": "<p align=\"center\">\n  <a href=\"https://github.com/Loopring/loopring-web-v2\" rel=\"noopener\" target=\"_blank\"><img width=\"150\" src=\"https://loopring.org/images/logo.svg\" alt=\"Loopring-website\"></a>\n</p>\n\n<h1 align=\"center\">Loopring Application</h1>\n<div align=\"center\">\n<h2>Ethereum’s First zkRollup Layer2</h2>\n<p>Fast, Secure, and 100x Lower Fees</p>\n\n[![license](https://img.shields.io/badge/license-MIT-blue)](https://github.com/Loopring/loopring-web-v2/master/LICENSE)\n\n[![type-badge](https://img.shields.io/npm/types/react-data-grid)](https://www.npmjs.com/package/react-data-grid)\n\n<!-- [![Materi-UI](https://img.shields.io/npm/types/react-data-grid)](https://www.npmjs.com/package/react-data-grid) -->\n\n</div>\n\n## 🚀 Quick Start\n\n```bash\n// with yarn\nyarn install\nyarn up\ncd ./packages/webapp\nnpm run dev\n\n\n```\n\n## 📚 Loopring UI component StoryBook\n\n```bash\n\ncd ./packages/component-lib\nnpm run storybook\n```\n\n## 🏗 Framework Design\n\n![](https://static.loopring.io/Loopring%20framwork.png)\n\n## 👉 [What is Loopring?](https://loopring.org/#/)\n\n## 🫂 Community\n\n- [Loopring Website](https://loopring.org/)\n- [Loopring Exchange](https://loopring.io/#/layer2)\n- [Loopring Reddit](https://www.reddit.com/r/loopringorg/)\n- [Loopring Medium](https://medium.com/loopring-protocol)\n- [Loopring Twitter](https://twitter.com/loopringorg)\n- [Loopring Telegram](https://t.me/loopring_en)\n\n## 👺 For Developer\n\n- We appreciate any improvements or initiatives for Loopring Layer2 website, please view the source code\n  in `./packages/component-lib`.\n- The project contains a separate lib \"web3-provider\", which is a third-party ETH web3 wallet provider service (\n  wallectConnect & metamask),\n- You are welcome to reuse it or integrate your provider service with our website.\n- Feel free to leave suggestions or ideas.\n\n### 📒 API & Dependency\n\n- [Web3-Provider](https://www.npmjs.com/package/@loopring-web/web3-provider)\n- [Loopring-sdk](https://www.npmjs.com/package/@loopring-web/loopring-sdk)\n- [Python](https://github.com/Loopring/hello_loopring)\n- [APIs](https://docs.loopring.io)\n\n## 🙋 Protocol & Architecture\n\n- [Whitepaper](https://loopring.org/resources/en_whitepaper.pdf)\n- [Design Docs](https://github.com/LoopringSecondary/docs/wiki/Loopring3_Design)\n\n## ❓[Help](https://desk.zoho.com/portal/loopring/en/home)\n\n## 🔑 Security\n\n- [Wallet](https://security.loopring.io/)\n- [Protocol Audit](https://loopring.org/resources/loopring1.0_audit.pdf)\n\n## Release Process\n\nalpha.loopring.io, beta.loopring.io, static.loopring.io, and loopring.io are now auto deployed using Vercel.\n"
  },
  {
    "path": "packages/web-guardian/craco.config.js",
    "content": "module.exports = require(\"../../craco.config.cjs\")"
  },
  {
    "path": "packages/web-guardian/electron-builder.env",
    "content": "ELECTRON_BUILDER_ALLOW_UNRESOLVED_DEPENDENCIES=true\n"
  },
  {
    "path": "packages/web-guardian/generate-react-cli.json",
    "content": "{\n  \"usesTypeScript\": true,\n  \"usesCssModule\": true,\n  \"cssPreprocessor\": \"scss\",\n  \"testLibrary\": \"Testing Library\",\n  \"component\": {\n    \"default\": {\n      \"path\": \"src/components\",\n      \"withLazy\": false,\n      \"withStory\": true,\n      \"withStyle\": true,\n      \"withTest\": true\n    },\n    \"page\": {\n      \"path\": \"src/pages\",\n      \"withLazy\": true,\n      \"withStory\": false,\n      \"withStyle\": true,\n      \"withTest\": true\n    },\n    \"layout\": {\n      \"path\": \"src/layout\",\n      \"withLazy\": false,\n      \"withStory\": false,\n      \"withStyle\": false,\n      \"withTest\": true\n    }\n  }\n}\n"
  },
  {
    "path": "packages/web-guardian/jest.config.js",
    "content": "module.exports = {\n  testEnvironment: 'node',\n\n  setupFilesAfterEnv: ['./jest.setup.js'],\n}\n"
  },
  {
    "path": "packages/web-guardian/jest.setup.js",
    "content": "process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0\n\njest.setTimeout(30000)\n"
  },
  {
    "path": "packages/web-guardian/package.json",
    "content": "{\n  \"name\": \"@loopring-web/web-guardian\",\n  \"version\": \"1.0.0\",\n  \"author\": \"Loopring L2 App Frontend Team\",\n  \"description\": \"Guardian new version\",\n  \"private\": true,\n  \"dependencies\": {\n    \"@loopring-web/common-resources\": \"1.0.0\",\n    \"@loopring-web/component-lib\": \"1.0.0\",\n    \"@loopring-web/core\": \"1.0.0\",\n    \"react-scripts\": \"5.0.1\",\n    \"cross-env\": \"^7.0.3\"\n  },\n  \"resolutions\": {\n    \"@types/react\": \"^18.2.19\",\n    \"@types/react-dom\": \"^18.2.7\"\n  },\n  \"build\": {\n    \"files\": [\n      \"build/**/*\",\n      \"node_modules/**/*\"\n    ],\n    \"publish\": {\n      \"provider\": \"custom\",\n      \"repo\": \"https://github.com/Loopring/loopring-web-v2\",\n      \"owner\": \"Loopring Dex Frontend Team\"\n    }\n  },\n  \"main\": \"./public/electron.js\",\n  \"homepage\": \".\",\n  \"scripts\": {\n    \"build\": \"git rev-parse --short HEAD; cross-env REACT_APP_VER=`git rev-parse --short HEAD`_prod dotenv -e .env.production craco build\",\n    \"build-fast\": \"export SET NODE_OPTIONS=--openssl-legacy-provider && git rev-parse --short HEAD; REACT_APP_VER=`git rev-parse --short HEAD`_prod dotenv -e .env.production craco build\",\n    \"dev\": \"export SET NODE_OPTIONS=--openssl-legacy-provider && cross-env REACT_APP_VER=\\\"git rev-parse --short HEAD\\\"_dev dotenv -e .env.development craco start\",\n    \"build_dev\": \"REACT_APP_VER=`git rev-parse --short HEAD`_dev dotenv -e .env.development craco build\"\n  },\n  \"browserslist\": {\n    \"production\": [\n      \"last 2 chrome version\",\n      \"last 2 firefox version\",\n      \"last 2 safari version\"\n    ],\n    \"development\": [\n      \"last 1 chrome version\",\n      \"last 1 firefox version\",\n      \"last 1 safari version\"\n    ]\n  }\n}\n"
  },
  {
    "path": "packages/web-guardian/public/electron.js",
    "content": "const path = require('path')\n\nconst { app, BrowserWindow } = require('electron')\nconst isDev = require('electron-is-dev')\n\nconsole.log('BROWSER:', process.env.BROWSER)\nconsole.log('NODE_ENV:', process.env.NODE_ENV)\n\nfunction createWindow() {\n  // Create the browser window.\n  const win = new BrowserWindow({\n    width: 1024,\n    height: 768,\n    frame: true,\n    webPreferences: {\n      nodeIntegration: true,\n    },\n  })\n\n  // and load the index.html of the app.\n  // win.loadFile(\"index.html\");\n  win.loadURL(\n    isDev ? 'http://localhost:3000' : `file://${path.join(__dirname, '../build/index.html')}`,\n  )\n\n  // Open the DevTools.\n  if (isDev) {\n    win.webContents.openDevTools({ mode: 'detach' })\n  }\n}\n\n// This method will be called when Electron has finished\n// initialization and is ready to create browser windows.\n// Some APIs can only be used after this event occurs.\napp.whenReady().then(createWindow)\n\n// Quit when all windows are closed, except on macOS. There, it's common\n// for applications and their menu bar to stay active until the user quits\n// explicitly with Cmd + Q.\napp.on('window-all-closed', () => {\n  if (process.platform !== 'darwin') {\n    app.quit()\n  }\n})\n\napp.on('activate', () => {\n  // On macOS it's common to re-create a window in the app when the\n  // dock icon is clicked and there are no other windows open.\n  if (BrowserWindow.getAllWindows().length === 0) {\n    createWindow()\n  }\n})\n"
  },
  {
    "path": "packages/web-guardian/public/index.html",
    "content": "<!DOCTYPE html>\n<html lang='en'>\n<head>\n  <meta charset='utf-8' />\n  <link rel='icon' href='%PUBLIC_URL%/favicon.ico' />\n  <meta name='description' content='Ethereum zkRollup Exchange and Payment Protocol' />\n  <meta\n    name='viewport'\n    content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0'\n  />\n  <meta name='theme-color' content='#000000' />\n  <meta\n    name='description'\n    content='Loopring Layer 2, Ethereum zkRollup Exchange and Payment Protocol'\n  />\n  <link\n    rel='stylesheet'\n    href='https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap'\n  />\n  <link rel='apple-touch-icon' href='%PUBLIC_URL%/logo192.png' />\n  <!--\n  manifest.json provides metadata used when your web app is installed on a\n  user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/\n-->\n  <link rel='manifest' href='%PUBLIC_URL%/manifest.json' />\n  <!--\n  Notice the use of %PUBLIC_URL% in the tags above.\n  It will be replaced with the URL of the `public` folder during the build.\n  Only files inside the `public` folder can be referenced from the HTML.\n\n  Unlike \"/favicon.ico\" or \"favicon.ico\", \"%PUBLIC_URL%/favicon.ico\" will\n  work correctly both with client-side routing and a non-root public URL.\n  Learn how to configure a non-root public URL by running `npm run build`.\n-->\n  <style type='text/css'>\n      body {\n          height: 100vh;\n          background: linear-gradient(194.79deg, #000000 17.96%, #434343 44.29%, #BFBFBF 96.93%);\n          color: #fff;\n          flex-direction: column;\n      }\n\n      .iubenda-pure {\n          height: 0 !important;\n          width: 0 !important;\n          line-height: 0 !important;\n          overflow: hidden !important;\n          padding: 0;\n          margin: 0;\n          display: none !important;\n      }\n\n      #iubenda-pp iframe {\n          display: block;\n      }\n  </style>\n  <script async src='https://www.googletagmanager.com/gtag/js?id=UA-224502206-1'></script>\n  <script>\n    window.dataLayer = window.dataLayer || []\n\n    function gtag() {\n      dataLayer.push(arguments)\n    }\n\n    gtag('js', new Date())\n    gtag('config', 'UA-224502206-1')\n  </script>\n  <title>Loopring - Ethereum Layer2</title>\n  <!-- Global site tag (gtag.js) - Google Analytics -->\n</head>\n\n<body ondragstart='return false;' ondrop='return false;' draggable='false'>\n<noscript>You need to enable JavaScript to run this app.</noscript>\n<div id='root' style='width: 100%; height: 100vh; display: flex; flex-direction: column'></div>\n<!--\nThis HTML file is a template.\nIf you open it directly in the browser, you will see an empty page.\n\nYou can add webfonts, meta tags, or analytics to this file.\nThe build step will place the bundled scripts into the <body> tag.\n\nTo begin the development, run `npm start` or `yarn start`.\nTo create a production bundle, use `npm run build` or `yarn build`.\n-->\n<div hidden>\n  <a\n    href='https://www.iubenda.com/terms-and-conditions/74969935'\n    data-index='0'\n    class='iubenda-white iubenda-embed iubenda-pure iubenda-noiframe'\n  ></a>\n  <!--      <a href=\"https://www.iubenda.com/terms-and-conditions/74969935\"-->\n  <!--         class=\"iubenda-black iubenda-embed iubenda-pure iubenda-noiframe\"></a>-->\n</div>\n<script type='text/javascript'>\n  ;(function(w, d) {\n    var loader = function() {\n      var s = d.createElement('script'),\n        tag = d.getElementsByTagName('script')[0]\n      s.src = 'https://cdn.iubenda.com/iubenda.js'\n      tag.parentNode.insertBefore(s, tag)\n    }\n    if (w.addEventListener) {\n      w.addEventListener('load', loader, false)\n    } else if (w.attachEvent) {\n      w.attachEvent('onload', loader)\n    } else {\n      w.onload = loader\n    }\n  })(window, document)\n</script>\n<script src='https://d17nz991552y2g.cloudfront.net/app/js/jqueryandencoder.ffa5afd5124fbedceea9.js'></script>\n</body>\n</html>\n"
  },
  {
    "path": "packages/web-guardian/public/manifest.json",
    "content": "{\n  \"short_name\": \"Loopring L2\",\n  \"name\": \"Loopring - Ethereum Layer2\",\n  \"icons\": [\n    {\n      \"src\": \"favicon.ico\",\n      \"sizes\": \"64x64 32x32 24x24 16x16\",\n      \"type\": \"image/x-icon\"\n    }\n  ],\n  \"start_url\": \".\",\n  \"display\": \"standalone\",\n  \"theme_color\": \"#000000\",\n  \"background_color\": \"#ffffff\"\n}\n"
  },
  {
    "path": "packages/web-guardian/public/robots.txt",
    "content": "# https://www.robotstxt.org/robotstxt.html\nUser-agent: *\nDisallow:\n"
  },
  {
    "path": "packages/web-guardian/src/App.tsx",
    "content": "// import { ModalProvider } from 'styled-react-modal'\nimport RouterView from './routers'\nimport { GlobalStyles } from '@mui/material'\nimport { css, Theme, useTheme } from '@emotion/react'\nimport { globalCss, SagaStatus } from '@loopring-web/common-resources'\nimport { setLanguage } from '@loopring-web/component-lib'\nimport { useInit } from './hook'\nimport React from 'react'\nimport { useTranslation } from 'react-i18next'\n\nimport { HashRouter as Router, useLocation } from 'react-router-dom'\nimport { store } from '@loopring-web/core'\n\nconst ScrollToTop = () => {\n  const { pathname } = useLocation()\n\n  React.useEffect(() => {\n    window.scrollTo(0, 0)\n  }, [pathname])\n\n  return null\n}\nconst App = () => {\n  const theme: Theme = useTheme()\n  const {\n    i18n: { language },\n  } = useTranslation()\n  const storeLan = store.getState().settings.language\n\n  React.useEffect(() => {\n    if (storeLan !== language) {\n      store.dispatch(setLanguage(language))\n    }\n  }, [storeLan, language])\n\n  React.useEffect(() => {\n    if (window.location.protocol !== 'https:') {\n      console.log('Current PROTOCOL::', window.location.protocol)\n      window.location.replace(\n        `https:${window.location.href.substring(window.location.protocol.length)}`,\n      )\n    }\n  }, [])\n\n  const { state } = useInit()\n\n\n  return (\n    <>\n      <GlobalStyles\n        styles={css`\n          ${globalCss({ theme })};\n\n          body {\n            ${\n              theme.mode === 'dark'\n                ? `\n            color: ${theme.colorBase.textPrimary};\n          `\n                : ``\n            }\n\n\n          }\n\n          body:before {\n            ${\n              theme.mode === 'dark'\n                ? `\n            background: var(--color-global-bg);\n       `\n                : ''\n            }\n          }\n        }`}\n      />\n\n      <Router>\n        <ScrollToTop />\n        <RouterView state={state as SagaStatus} />\n      </Router>\n    </>\n  )\n}\n\nexport default App\n"
  },
  {
    "path": "packages/web-guardian/src/common.ts",
    "content": "import * as sdk from '@loopring-web/loopring-sdk'\nexport type ChainId = number | sdk.ChainId\n"
  },
  {
    "path": "packages/web-guardian/src/hook.ts",
    "content": "import React from 'react'\nimport {\n  layer1Store,\n  useAccount,\n  useInjectWeb3Modal,\n  useSocket,\n  useSystem,\n  useTokenMap,\n  useTokenPrices,\n} from '@loopring-web/core'\nimport { ChainId } from '@loopring-web/loopring-sdk'\nimport { myLog, SagaStatus, SUPPORTING_NETWORKS, ThemeType } from '@loopring-web/common-resources'\nimport {\n  ConnectProviders,\n  ConnectProvides,\n  connectProvides,\n  walletServices,\n} from '@loopring-web/web3-provider'\nimport { useAccountInit } from './hookAccountInit'\nimport { useSettings } from '@loopring-web/component-lib'\nimport { useTheme } from '@emotion/react'\n\n/**\n * @description\n * @step1 subscribe Connect hook\n * @step2 check the session storage ? choose the provider : none provider\n * @step3 decide china ID by step2\n * @step4 prepare the static date (tokenMap, ammMap, faitPrice, gasPrice, Activities ...)\n * @step5 launch the page\n */\n\nexport function useInit() {\n  const [, search] = window.location?.hash.split('?') ?? []\n  const query = new URLSearchParams(search)\n  const [, pathname1] = window.location.hash.match(/#\\/([\\w\\d\\-]+)\\??/) ?? []\n  const isNoServer: boolean =\n    query.has('noheader') && ['notification', 'document'].includes(pathname1)\n  const [state, setState] = React.useState<keyof typeof SagaStatus>(() => {\n    if (isNoServer) {\n      return SagaStatus.DONE\n    } else {\n      return SagaStatus.PENDING\n    }\n  })\n  const { isMobile, defaultNetwork } = useSettings()\n  const theme = useTheme()\n\n  const {\n    account,\n    updateAccount,\n    resetAccount,\n    status: accountStatus,\n    statusUnset: accountStatusUnset,\n  } = useAccount()\n  const { status: tokenMapStatus, statusUnset: tokenMapStatusUnset } = useTokenMap()\n  const { status: tokenPricesStatus, statusUnset: tokenPricesUnset } = useTokenPrices()\n\n  const { updateSystem, status: systemStatus, statusUnset: systemStatusUnset } = useSystem()\n\n  const { status: socketStatus, statusUnset: socketUnset } = useSocket()\n  const { circleUpdateLayer1ActionHistory } = layer1Store.useLayer1Store()\n\n  React.useEffect(() => {\n    ConnectProvides.walletConnectClientMeta = {\n      ...ConnectProvides.walletConnectClientMeta,\n      url:\n        process?.env?.REACT_APP_WALLETCONNECTCLIENTMETA_URL ??\n        ConnectProvides.walletConnectClientMeta.url,\n      name:\n        process?.env?.REACT_APP_WALLETCONNECTCLIENTMETA_NAME ??\n        ConnectProvides.walletConnectClientMeta.name,\n      description:\n        process?.env?.REACT_APP_WALLETCONNECTCLIENTMETA_DESCRIPTION ??\n        ConnectProvides.walletConnectClientMeta.description,\n    }\n    ;(async (account) => {\n      if (\n        account.accAddress !== ''\n      ) {\n        try {\n          ConnectProvides.IsMobile = isMobile\n          await connectProvides[account.connectName]({\n            account: account.accAddress,\n            darkMode: theme.mode === ThemeType.dark,\n            chainId: defaultNetwork.toString(),\n          })\n          updateAccount({})\n          if (connectProvides.usedProvide && connectProvides.usedWeb3) {\n            let chainId = Number(\n              // @ts-ignore\n              connectProvides.usedProvide?.connection?.chainId ??\n                (await connectProvides.usedWeb3.eth.getChainId()),\n            )\n            if (!SUPPORTING_NETWORKS.includes(chainId.toString())) {\n              chainId =\n                account._chainId && account._chainId !== 'unknown'\n                  ? account._chainId\n                  : ChainId.MAINNET\n            }\n            circleUpdateLayer1ActionHistory({ chainId })\n\n            if (!isNoServer) {\n              updateSystem({ chainId: chainId as any })\n            }\n            return\n          }\n        } catch (error: any) {\n          walletServices.sendDisconnect('', `error at init loading  ${error}, disconnect`)\n          const chainId =\n            account._chainId && account._chainId !== 'unknown' ? account._chainId : ChainId.MAINNET\n          if (!isNoServer) {\n            updateSystem({ chainId })\n          }\n        }\n      } else {\n        if (account.accAddress === '') {\n          resetAccount()\n        }\n        const chainId =\n          account._chainId && account._chainId !== 'unknown' ? account._chainId : ChainId.MAINNET\n        if (!isNoServer) {\n          updateSystem({ chainId })\n        }\n      }\n    })(account)\n  }, [])\n  React.useEffect(() => {\n    switch (accountStatus) {\n      case SagaStatus.ERROR:\n        accountStatusUnset()\n        setState('ERROR')\n        break\n      case SagaStatus.DONE:\n        accountStatusUnset()\n        break\n      default:\n        break\n    }\n  }, [accountStatus])\n  React.useEffect(() => {\n    switch (systemStatus) {\n      case SagaStatus.PENDING:\n        if (!query.has('noheader') && state !== SagaStatus.PENDING) {\n          setState(SagaStatus.PENDING)\n        }\n        break\n      case SagaStatus.ERROR:\n        systemStatusUnset()\n        setState('ERROR')\n        break\n      case SagaStatus.DONE:\n        systemStatusUnset()\n        break\n      default:\n        break\n    }\n  }, [systemStatus])\n\n  React.useEffect(() => {\n    switch (tokenMapStatus) {\n      case SagaStatus.ERROR:\n        tokenMapStatusUnset()\n        setState('ERROR')\n        break\n      case SagaStatus.DONE:\n        tokenMapStatusUnset()\n        break\n      default:\n        break\n    }\n  }, [tokenMapStatus])\n\n  React.useEffect(() => {\n    switch (tokenPricesStatus) {\n      case SagaStatus.ERROR:\n        tokenPricesUnset()\n        setState('ERROR')\n        break\n      case SagaStatus.DONE:\n        tokenPricesUnset()\n        break\n      default:\n        break\n    }\n  }, [tokenPricesStatus])\n  React.useEffect(() => {\n    switch (socketStatus) {\n      case 'ERROR':\n        socketUnset()\n        break\n      case 'DONE':\n        socketUnset()\n        break\n      default:\n        break\n    }\n  }, [socketStatus])\n\n  useAccountInit({ state })\n  useInjectWeb3Modal('GUARDIAN')\n  return {\n    state,\n  }\n}\n"
  },
  {
    "path": "packages/web-guardian/src/hookAccountInit.ts",
    "content": "import React from 'react'\nimport { AccountStatus, myLog, SagaStatus } from '@loopring-web/common-resources'\nimport { useAccount, useConnect, useWalletLayer1 } from '@loopring-web/core'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nexport function useAccountInit({ state }: { state: keyof typeof SagaStatus }) {\n  useConnect({ state })\n  const {\n    updateWalletLayer1,\n    status: walletLayer1Status,\n    statusUnset: wallet1statusUnset,\n  } = useWalletLayer1()\n  const { account, status: accountStatus, statusUnset: accountUnset, updateAccount } = useAccount()\n\n  const callBack = React.useCallback(async () => {\n    switch (account.readyState) {\n      case AccountStatus.DEPOSITING:\n      case AccountStatus.NOT_ACTIVE:\n      case AccountStatus.LOCKED:\n      case AccountStatus.NO_ACCOUNT:\n      case AccountStatus.ACTIVATED:\n        if (walletLayer1Status !== SagaStatus.PENDING) {\n          updateWalletLayer1()\n          myLog('updateWalletLayer1')\n        } else {\n          wallet1statusUnset()\n          sdk.sleep(10)\n          updateWalletLayer1()\n        }\n        break\n      case AccountStatus.UN_CONNECT:\n      case AccountStatus.ERROR_NETWORK:\n        break\n    }\n  }, [account.readyState, accountStatus, updateAccount, updateWalletLayer1, walletLayer1Status])\n  React.useEffect(() => {\n    if (accountStatus === SagaStatus.UNSET && state === SagaStatus.DONE) {\n      callBack()\n    }\n  }, [accountStatus, state])\n  React.useEffect(() => {\n    switch (walletLayer1Status) {\n      case SagaStatus.ERROR:\n        wallet1statusUnset()\n        break\n      case SagaStatus.DONE:\n        wallet1statusUnset()\n        break\n      default:\n        break\n    }\n  }, [walletLayer1Status])\n}\n"
  },
  {
    "path": "packages/web-guardian/src/index.tsx",
    "content": "import { Provider } from 'react-redux'\nimport App from './App'\nimport reportWebVitals from './reportWebVitals'\nimport { firebaseProps, persistor, store, TimeoutCheckProvider } from '@loopring-web/core'\nimport { getTheme, i18n } from '@loopring-web/common-resources'\nimport { ThemeProvider as MuThemeProvider } from '@mui/material'\n\nimport { ThemeProvider } from '@emotion/react'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { PersistGate } from 'redux-persist/integration/react'\nimport { provider, ProviderComposer, useSettings } from '@loopring-web/component-lib'\nimport React, { Provider as TProvider } from 'react'\nimport { ReactReduxFirebaseProvider } from 'react-redux-firebase'\nimport { LocalizationProvider } from '@mui/lab'\nimport MomentUtils from '@mui/lab/AdapterMoment'\nimport { I18nextProvider } from 'react-i18next'\nimport { createRoot } from 'react-dom/client'\n\nif (process.env.REACT_APP_VER) {\n  console.log('VER:', process.env.REACT_APP_VER)\n}\nwindow.global = window;\nconst ProviderApp = React.memo(({ children }: { children: JSX.Element }) => {\n  const providers: Array<[TProvider<any>, any]> = [\n    provider(Provider as any, { store }),\n    provider(LocalizationProvider as any, { dateAdapter: MomentUtils }),\n    provider(I18nextProvider as any, { i18n: i18n }),\n  ] as any\n  return <ProviderComposer providers={providers}>{children}</ProviderComposer>\n})\nconst ProviderThen = React.memo(({ children }: { children: JSX.Element }) => {\n  const { themeMode, setIsMobile } = useSettings()\n  const isMobile = sdk.IsMobile.any() ? true : false\n  setIsMobile(isMobile)\n  const providers: Array<[TProvider<any>, any]> = [\n    provider(MuThemeProvider as any, { theme: getTheme(themeMode, isMobile) }),\n    provider(ThemeProvider as any, { theme: getTheme(themeMode, isMobile) }),\n    provider(PersistGate as any, { persistor, loading: null }),\n    provider(TimeoutCheckProvider as any),\n  ] as any\n  return <ProviderComposer providers={providers}>{children}</ProviderComposer>\n})\n\nconst root = createRoot(document.getElementById('root') as HTMLElement)\nroot.render(\n  <ProviderApp>\n    <ReactReduxFirebaseProvider {...firebaseProps}>\n      <ProviderThen>\n        <App />\n      </ProviderThen>\n    </ReactReduxFirebaseProvider>\n  </ProviderApp>,\n)\n\n// If you want to start measuring performance in your app, pass a function\n// to log results (for example: reportWebVitals(console.log))\n// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals\n\nif (process.env.NODE_ENV !== 'production') {\n  reportWebVitals(console.log)\n}\n"
  },
  {
    "path": "packages/web-guardian/src/layouts/footer/index.tsx",
    "content": "import React from 'react'\nimport { FOOTER_LIST_MAP, MEDIA_LIST } from '@loopring-web/common-resources'\nimport { Footer as FooterUI } from '@loopring-web/component-lib'\nimport _ from 'lodash'\n\nconst linkListMap = _.cloneDeep(FOOTER_LIST_MAP)\nconst mediaList = _.cloneDeep(MEDIA_LIST)\nexport const Footer = () => {\n  return (\n    <FooterUI\n      isLandingPage={false}\n      linkListMap={linkListMap}\n      mediaList={mediaList}\n      isBeta={false}\n    />\n  )\n}\n"
  },
  {
    "path": "packages/web-guardian/src/layouts/header/hook.tsx",
    "content": "import React from 'react'\n\nimport {\n  ButtonComponentsMap,\n  headerGuardianToolBarData,\n  headerMenuLandingData,\n  myLog,\n} from '@loopring-web/common-resources'\n\nimport {\n  accountStaticCallBack,\n  btnConnectL1kMap,\n  useAccount,\n  useNotify,\n  useSelectNetwork,\n  useSystem,\n} from '@loopring-web/core'\n\nimport { useOpenModals } from '@loopring-web/component-lib'\n\nexport const useHeader = () => {\n  const accountTotal = useAccount()\n  const { account, setShouldShow, status: accountStatus } = accountTotal\n  const { chainId } = useSystem()\n  const accountState = { account } \n\n  const onkeypress = (e: KeyboardEvent) => {\n    if (e.altKey && e.shiftKey && e.code == 'KeyX') {\n      console.log(e.altKey && e.shiftKey && e.code && e.timeStamp)\n    }\n  }\n  const onWalletBtnConnect = React.useCallback(async () => {\n    myLog(`onWalletBtnConnect click: ${account.readyState}`)\n    accountStaticCallBack(btnConnectL1kMap, [])\n  }, [account, setShouldShow, btnConnectL1kMap])\n  const { NetWorkItems } = useSelectNetwork({ className: 'header' })\n\n  \n  const headerToolBarData = {\n    [ButtonComponentsMap.Notification]: headerGuardianToolBarData[ButtonComponentsMap.Notification],\n    [ButtonComponentsMap.WalletConnect]: {\n      ...headerGuardianToolBarData[ButtonComponentsMap.WalletConnect],\n      accountState,\n      isLayer1Only: true,\n      NetWorkItems,\n      handleClick: onWalletBtnConnect,\n    }\n\n  }\n  const { notifyMap } = useNotify()\n\n  return {\n    headerToolBarData,\n    headerMenuLandingData,\n    account,\n    notifyMap,\n    onkeypress,\n  }\n}\n"
  },
  {
    "path": "packages/web-guardian/src/layouts/header/index.tsx",
    "content": "import {\n  ButtonComponentsMap,\n  GuardianToolBarAvailableItem,\n  headerRoot,\n} from '@loopring-web/common-resources'\n\nimport { Toolbar } from '@mui/material'\n\nimport { useHeader } from './hook'\nimport { confirmation, useAccount, useSystem } from '@loopring-web/core'\nimport { withTranslation } from 'react-i18next'\n\nimport {\n  BottomRule,\n  Header as HeaderUI,\n  HideOnScroll,\n  useSettings,\n} from '@loopring-web/component-lib'\nimport { withRouter } from 'react-router-dom'\nimport { RouteComponentProps } from 'react-router'\nimport React from 'react'\n\nconst Header = withTranslation('common')(\n  withRouter(({ t, location, isLandPage = false, ...rest }: any & RouteComponentProps) => {\n    const { headerToolBarData, notifyMap, headerMenuLandingData, onkeypress } = useHeader()\n    const { isMobile } = useSettings()\n    const { confirmWrapper } = confirmation.useConfirmation()\n    const { allowTrade, chainId } = useSystem()\n    const { account } = useAccount()\n    return (\n      <>\n        <HideOnScroll window={undefined} onkeypress={onkeypress}>\n          <HeaderUI\n            {...rest}\n            account={account}\n            allowTrade={allowTrade}\n            isMobile={isMobile}\n            chainId={chainId}\n            // isLandPage={true}\n            // isWrap={false}\n            toolBarMap={ButtonComponentsMap}\n            headerMenuData={headerMenuLandingData}\n            headerToolBarData={headerToolBarData}\n            notification={notifyMap}\n            selected={location.pathname === '/' ? headerRoot : location.pathname}\n            application={'web-guardian'}\n          />\n        </HideOnScroll>\n        <Toolbar id='back-to-top-anchor' />\n        {/* <BottomRule isShow={!confirmation?.confirmed} */}\n        <BottomRule\n          isShow={false}\n          content={t('labelAgreeLoopringTxt')}\n          btnTxt={t('labelCookiesAgree')}\n          clickToConfirm={() => confirmWrapper()}\n        />\n      </>\n    )\n  }),\n)\n\nexport default Header\n"
  },
  {
    "path": "packages/web-guardian/src/pages/ErrorPage/index.tsx",
    "content": "import { Trans, useTranslation } from 'react-i18next'\nimport { Box, Container, Link, Typography } from '@mui/material'\nimport styled from '@emotion/styled'\nimport { ErrorObject } from '@loopring-web/common-resources'\nimport { getContactInfo } from '@loopring-web/core'\n\nconst StyleBox = styled(Box)`\n  background-image: url('https://static.loopring.io/assets/images/error_bg.png');\n  background-repeat: no-repeat;\n  background-size: contain;\n  background-position: bottom;\n  white-space: pre-wrap;\n  //h2{\n  //  position: relative;\n  //}\n` as typeof Box\n\nexport const ErrorPage = ({ messageKey }: ErrorObject) => {\n  const { t } = useTranslation('error')\n  const message = `labelConnectUs`\n  return (\n    <>\n      <Container style={{ flex: 1 }}>\n        {/*style={{height: '100%' }}*/}\n        <StyleBox\n          flex={1}\n          display={'flex'}\n          alignItems={'flex-start'}\n          justifyContent={'center'}\n          flexDirection={'column'}\n          marginTop={4}\n          height={680}\n          maxWidth={1200}\n        >\n          {/*<StyleBox>*/}\n          <Box textAlign={'center'} position={'relative'} left={128} top={-64}>\n            <Typography component={'h2'} variant={'h3'} whiteSpace={'pre-line'}>\n              {t(messageKey)}\n            </Typography>\n            <Typography\n              marginY={2}\n              component={'p'}\n              variant={'body1'}\n              color={'textSecondary'}\n              whiteSpace={'pre-line'}\n            >\n              <Trans i18nKey={message} ns={'error'}>\n                If you believe this is indeed a bug, please\n                <Link\n                  component={'a'}\n                  sx={{\n                    display: 'inline-flex',\n                  }}\n                  onClick={(e) => {\n                    window.open(getContactInfo(), '_blank')\n                    window.opener = null\n                    e.preventDefault()\n                  }}\n                >\n                  &nbsp; contact us\n                </Link>\n                <br /> We would appreciate your feedback\n              </Trans>\n            </Typography>\n          </Box>\n        </StyleBox>\n      </Container>\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/web-guardian/src/pages/LoadingPage/index.tsx",
    "content": "import { useTranslation } from 'react-i18next'\nimport { Box } from '@mui/material'\nimport styled from '@emotion/styled'\n// import { ErrorObject } from '@loopring-web/common-resources';\n// import { getContactInfo } from '../../utils/dt_tools';\nimport { boxLiner } from '@loopring-web/component-lib'\nimport { SoursURL } from '@loopring-web/common-resources'\nimport React from 'react'\n// ${({theme}) => boxLiner({theme})}\nconst StyleBox = styled(Box)`\n  //background: var(--color-mask);\n  ${({ theme }) => boxLiner({ theme })}\n\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  left: 0;\n  right: 0;\n  width: 0;\n  z-index: 500;\n  height: 100%;\n  width: 100%;\n\n  svg path,\n  svg rect {\n    fill: var(--color-primary);\n  }\n` as typeof Box\nconst StyleBlock = styled(Box)`\n  background: var(--color-global-bg);\n\n  svg path,\n  svg rect {\n    fill: var(--color-primary);\n  }\n` as typeof Box\n\nexport const LoadingPage = () => {\n  const { t } = useTranslation('layout')\n  return (\n    <>\n      {/*<Container>*/}\n      {/*style={{height: '100%' }}*/}\n      <StyleBox\n        flex={1}\n        display={'flex'}\n        alignItems={'center'}\n        justifyContent={'center'}\n        flexDirection={'column'}\n        height={'100%'}\n        width={'100%'}\n      >\n        <div className='loader loader--style3' title='2'>\n          <img\n            className='loading-gif'\n            alt={'loading'}\n            width='36'\n            src={`${SoursURL}images/loading-line.gif`}\n          />\n        </div>\n      </StyleBox>\n    </>\n  )\n}\nexport const LoadingBlock = () => {\n  const { t } = useTranslation('layout')\n  return (\n    <>\n      {/*<Container>*/}\n      {/*style={{height: '100%' }}*/}\n      <StyleBlock\n        flex={1}\n        display={'flex'}\n        alignItems={'center'}\n        justifyContent={'center'}\n        flexDirection={'column'}\n        height={'100%'}\n        width={'100%'}\n      >\n        <div className='loader loader--style3' title='2'>\n          <img\n            className='loading-gif'\n            alt={'loading'}\n            width='36'\n            src={`${SoursURL}images/loading-line.gif`}\n          />\n        </div>\n      </StyleBlock>\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/web-guardian/src/pages/WalletPage/GuardianModal.tsx",
    "content": "import { WithTranslation, withTranslation } from 'react-i18next'\nimport styled from '@emotion/styled'\nimport { Box, Modal, Typography } from '@mui/material'\nimport { ReactNode } from 'react'\nimport { ModalBackButton, ModalCloseButton, useSettings } from '@loopring-web/component-lib'\n\ntype GuardianModalProps = {\n  open: boolean\n  onClose: {\n    bivarianceHack(event: {}, reason: 'backdropClick' | 'escapeKeyDown'): void\n  }['bivarianceHack']\n  title: ReactNode\n  body: ReactNode\n  onBack?: () => void\n  showBackButton?: boolean\n  background?: string \n}\n\nconst GuardianModalContentStyled = styled(Box)<{ isMobile?: boolean }>`\n  & > div {\n    background: var(--color-box);\n    position: absolute;\n    top: 50%;\n    left: 50%;\n    transform: translate(-50%, -50%);\n    width: ${({ isMobile }) => (isMobile ? '92%' : '60%')};\n    min-width: ${({ isMobile }) => (isMobile ? 'auto' : '600px')};\n    margin: ${({ isMobile }) => (isMobile ? 'auto 2%' : 'auto')};\n  }\n\n  &.guardianPop .content {\n    padding-top: 40px;\n    border-radius: ${({ theme }) => theme.unit}px;\n  }\n`\n\nexport const GuardianModal = withTranslation('common')(\n  ({\n    onClose,\n    open,\n    body,\n    title,\n    onBack,\n    showBackButton,\n    background,\n    t,\n  }: GuardianModalProps & WithTranslation) => {\n    const { isMobile } = useSettings()\n    return (\n      <Modal\n        open={open}\n        onClose={onClose}\n        aria-labelledby='modal-modal-title'\n        aria-describedby='modal-modal-description'\n      >\n        <GuardianModalContentStyled\n          isMobile={isMobile}\n          display={'flex'}\n          alignItems={'center'}\n          justifyContent={'center'}\n          className={'guardianPop'}\n        >\n          <Box\n            className={'content'}\n            paddingTop={3}\n            paddingBottom={3}\n            display={'flex'}\n            flexDirection={'column'}\n            // width={isMobile ? \"100%\" : \"auto\"}\n            width={'100%'}\n            style={{background: background}}\n          >\n            {showBackButton && <ModalBackButton onBack={onBack} />}\n            <ModalCloseButton onClose={onClose} t={t} />\n            <Box\n              display={'flex'}\n              justifyContent={'space-between'}\n              alignItems={'center'}\n              flexDirection={'column'}\n            >\n              {title && (\n                <Typography variant={'h4'} component='h3' className='modalTitle' marginBottom={3}>\n                  {title}\n                </Typography>\n              )}\n            </Box>\n            <Box paddingX={5}>{body}</Box>\n          </Box>\n        </GuardianModalContentStyled>\n      </Modal>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/web-guardian/src/pages/WalletPage/WalletHistory.tsx",
    "content": "import { Box, Typography } from '@mui/material'\nimport { EmptyDefault } from '@loopring-web/component-lib'\nimport React from 'react'\nimport { useTranslation } from 'react-i18next'\n\nimport { HebaoOperationLog } from '@loopring-web/loopring-sdk'\nimport moment from 'moment'\nimport { TxGuardianHistoryType, TxHebaoAction } from './hook'\n\nexport const WalletHistory = ({ operationLogList }: { operationLogList: HebaoOperationLog[] }) => {\n  // operationLogList = [\n  //   {status: 1, createdAt: 0, ens: 'ens', from: '111',hebaoTxType: 1, to: '111', id: 1},\n  //   {status: 1, createdAt: 0, ens: 'ens', from: '111',hebaoTxType: 1, to: '111', id: 1},\n  // ]\n  const { t } = useTranslation()\n  return operationLogList.length !== 0 ? (\n    <Box height={'340px'} overflow='scroll'>\n      {operationLogList.map((log, index) => {\n        return (\n          <Box\n            key={log.id}\n            display={'flex'}\n            alignItems={'center'}\n            justifyContent={'space-between'}\n            marginBottom={2}\n          >\n            <Box display={'flex'} justifyContent={'space-between'} width={'100%'}>\n              <Typography>\n                {log.ens ? `${log.ens} /` : ''}\n                <Typography component={'span'} color={log.ens ? 'var(--color-text-third)' : ''}>\n                  {log.to && `${log.to.slice(0, 6)}...${log.to.slice(log.to.length - 4)} `}\n                </Typography>\n                <Typography>\n                  {`${t('labelTxGuardian' + TxHebaoAction[log.status])\n                    .slice(0, 1)\n                    .toUpperCase()}${t('labelTxGuardian' + TxHebaoAction[log.status])\n                    .slice(1)\n                    .toLowerCase()} `}\n                  {TxGuardianHistoryType[log.hebaoTxType] === undefined\n                    ? t('labelUnknown')\n                    : t('labelTxGuardian' + TxGuardianHistoryType[log.hebaoTxType]).toLowerCase()}\n                </Typography>\n              </Typography>\n              <Typography color={'var(--color-text-third)'} variant={'body1'}>\n                {moment(new Date(log.createdAt), 'YYYYMMDDHHMM').fromNow()}\n              </Typography>\n            </Box>\n          </Box>\n        )\n      })}\n    </Box>\n  ) : (\n    <Box flex={1} height={'100%'} width={'100%'}>\n      <EmptyDefault\n        style={{ alignSelf: 'center' }}\n        height={'100%'}\n        message={() => (\n          <Box flex={1} display={'flex'} alignItems={'center'} justifyContent={'center'}>\n            {t('labelNoContent')}\n          </Box>\n        )}\n      />\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/web-guardian/src/pages/WalletPage/WalletProtector.tsx",
    "content": "import { Box, Typography } from '@mui/material'\nimport { Button, EmptyDefault, GuardianStep, useSettings } from '@loopring-web/component-lib'\nimport React from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { LoadingIcon, LockIcon } from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { useHebaoProtector } from './hook'\n\nexport const WalletProtector = ({\n  protectorList,\n  handleOpenModal,\n  loadData,\n  guardianConfig,\n}: {\n  protectorList: sdk.Protector[]\n  handleOpenModal: (info: { step: GuardianStep; options?: any }) => void\n  loadData: () => Promise<void>\n  guardianConfig: any\n}) => {\n  const { t } = useTranslation()\n  const { onLock } = useHebaoProtector({\n    guardianConfig,\n    handleOpenModal,\n    loadData,\n  })\n  const { isMobile } = useSettings()\n  if (protectorList.length === 0) {\n    return (\n      <Box flex={1} height={'100%'} width={'100%'}>\n        <EmptyDefault\n          style={{ alignSelf: 'center' }}\n          height={'100%'}\n          message={() => (\n            <Box flex={1} display={'flex'} alignItems={'center'} justifyContent={'center'}>\n              {t('labelNoContent')}\n            </Box>\n          )}\n        />\n      </Box>\n    )\n  } else {\n    const StatusView = ({\n      status,\n      onClickLock,\n    }: {\n      status: sdk.HEBAO_LOCK_STATUS\n      onClickLock: () => void\n    }) => {\n      switch (status) {\n        case 'UNLOCK_FAILED':\n        case 'LOCKED':\n          return (\n            <Box display={'flex'} alignItems={'center'}>\n              <LockIcon htmlColor={'var(--color-text-third)'} fontSize={'medium'} />\n              <Typography\n                color={'var(--color-text-third)'}\n                paddingLeft={1}\n                variant={'body1'}\n                component={'span'}\n                alignItems={'center'}\n                display={'inline-flex'}\n                lineHeight={'inherit'}\n              >\n                {'LOCKED'}\n              </Typography>\n            </Box>\n          )\n        case 'UNLOCK_WAITING':\n          return (\n            <Box display={'flex'} alignItems={'center'}>\n              <LoadingIcon htmlColor={'var(--color-text-third)'} fontSize={'medium'} />\n              <Typography\n                color={'var(--color-text-third)'}\n                paddingLeft={1}\n                variant={'body1'}\n                component={'span'}\n                alignItems={'center'}\n                display={'inline-flex'}\n                lineHeight={'inherit'}\n              >\n                {'UNLOCKING'}\n              </Typography>\n            </Box>\n          )\n        case 'LOCK_WAITING':\n          return (\n            <Box display={'flex'} alignItems={'center'}>\n              <LockIcon htmlColor={'var(--color-text-third)'} fontSize={'medium'} />\n              <Typography\n                color={'var(--color-text-third)'}\n                paddingLeft={1}\n                height={32}\n                variant={'body1'}\n                component={'span'}\n                alignItems={'center'}\n                display={'inline-flex'}\n                lineHeight={'inherit'}\n              >\n                {'LOCKING'}\n              </Typography>\n            </Box>\n          )\n        case 'LOCK_FAILED':\n        case 'CREATED':\n          return (\n            <Button\n              variant={'contained'}\n              size={'small'}\n              color={'primary'}\n              startIcon={<LockIcon htmlColor={'var(--color-text-button)'} />}\n              onClick={() => onClickLock()}\n            >\n              {t('labelLock')}\n            </Button>\n          )\n        default:\n          return <></>\n      }\n    }\n\n    return (\n      <Box height={'320px'} overflow='scroll'>\n        {protectorList.map((x) => {\n          const { lockStatus } = x\n          return (\n            <Box\n              key={x.address}\n              display={'flex'}\n              alignItems={'center'}\n              justifyContent={'space-between'}\n              marginBottom={2}\n            >\n              <Box>\n                <Typography variant={'body1'}>{x.ens ? x.ens : t('labelUnknown')}</Typography>\n                <Typography color={'var(--color-text-third)'} title={x.address}>\n                  {isMobile\n                    ? x.address &&\n                      `${x.address.slice(0, 6)}...${x.address.slice(x.address.length - 4)}`\n                    : x.address}\n                </Typography>\n              </Box>\n              <StatusView\n                status={lockStatus}\n                onClickLock={() => {\n                  onLock(x)\n                }}\n              />\n            </Box>\n          )\n        })}\n      </Box>\n    )\n  }\n}\n"
  },
  {
    "path": "packages/web-guardian/src/pages/WalletPage/WalletValidationInfo.tsx",
    "content": "import { Box, IconButton, Input, Modal, Typography } from '@mui/material'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { Trans, useTranslation } from 'react-i18next'\nimport React, { useMemo } from 'react'\nimport {\n  Button,\n  EmptyDefault,\n  GuardianStep,\n  InputCode,\n  ModalCloseButton,\n  QRCodeV2,\n  SwitchPanelStyled,\n} from '@loopring-web/component-lib'\nimport { useAction } from './hook'\nimport { useTheme } from '@emotion/react'\nimport { CopyIcon, ScanQRIcon, SoursURL } from '@loopring-web/common-resources'\nimport { createImageFromInitials, shortenAddress } from '@loopring-web/core'\nimport QRCodeStyling from 'qr-code-styling'\nimport { decodeData, encodeData } from './utils'\n\nconst VCODE_UNIT = 6\nexport const WalletValidationInfo = ({\n  guardiansList,\n  loadData,\n  guardianConfig,\n  isContractAddress,\n  handleOpenModal,\n  onClickScan,\n  codeText,\n  onInputCode,\n  onClickNext,\n  onClickCodeApprovalApprove,\n  onClickCodeApprovalReject,\n  approvalCodeStatus,\n  guardianSign,\n  approveHash,\n  codeInputError,\n  nextBtnDisabled,\n  guardian\n}: {\n  guardiansList: sdk.Guardian[]\n  guardianConfig: any\n  isContractAddress: boolean\n  loadData: () => Promise<void>\n  handleOpenModal: (props: { step: GuardianStep; options?: any }) => void\n  onClickScan: () => void\n  codeText: string\n  onInputCode: (str: string) => void\n  onClickNext: () => void\n  onClickCodeApprovalApprove: () => void\n  onClickCodeApprovalReject: () => void\n  approvalCodeStatus: 'init' | 'confirmation' | 'sharing'\n  guardianSign?: string\n  approveHash?: string\n  guardian: string\n  codeInputError?: string\n  nextBtnDisabled: boolean\n}) => {\n  const { t } = useTranslation()\n  const [selected, setSelected] = React.useState<sdk.Guardian | undefined>()\n  const [openCode, setOpenCode] = React.useState(false)\n  const { submitApprove, handleReject, handleOpenApprove } = useAction({\n    setSelected,\n    setOpenCode,\n    loadData,\n    guardianConfig,\n    isContractAddress,\n    handleOpenModal,\n  })\n  const theme = useTheme()\n  const sharingStr = useMemo(() => {\n    return approvalCodeStatus === 'sharing' && guardianSign && approveHash\n      ? encodeData({ ...decodeData(codeText), guardian, guardianSign, approveHash })\n      : undefined\n  }, [approvalCodeStatus === 'sharing', guardianSign, codeText, approveHash])\n\n  if (approvalCodeStatus === 'confirmation') {\n    const jsonObj = decodeData(codeText)\n\n    return (\n      <Box>\n        <Typography variant={'body2'}>{t('labelGuardianCodeRequestedWallet')}</Typography>\n        <Box marginTop={1.5} display={'flex'} alignItems={'center'}>\n          <Box\n            marginRight={1.5}\n            borderRadius={'14px'}\n            src={createImageFromInitials(28, 'O', theme.colorBase.success)}\n            component={'img'}\n          />\n          <Box>\n            <Typography>{t('labelGuardianCodeOwner')}</Typography>\n            <Typography variant={'body2'} color={theme.colorBase.textSecondary}>\n              {jsonObj?.sender}\n            </Typography>\n          </Box>\n        </Box>\n        <Box marginTop={1.5} display={'flex'} justifyContent={'space-between'}>\n          <Typography variant={'body2'}>{t('labelGuardianCodeRequestType')}</Typography>\n          <Typography variant={'body2'} color={theme.colorBase.textPrimary}>\n            {jsonObj.metaTxType === 16\n              ? 'Recover Wallet'\n              : jsonObj.metaTxType === 34\n              ? 'Add Guardian'\n              : jsonObj.metaTxType === 35\n              ? 'Remove Guardian'\n              : jsonObj.metaTxType === 37\n              ? 'Unlock Wallet'\n              : jsonObj.metaTxType === 18\n              ? 'Exceed Daily Quota Transfer'\n              : jsonObj.metaTxType === 23\n              ? 'Token Approval'\n              : jsonObj.metaTxType === 201\n              ? 'Upgrade Wallet Contract'\n              : jsonObj.metaTxType === 202\n              ? 'Call Contract'\n              : 'Unknown'}\n          </Typography>\n        </Box>\n        <Box marginTop={1.5} display={'flex'} justifyContent={'space-between'}>\n          <Typography variant={'body2'}>{t('labelGuardianCodeNetwork')}</Typography>\n          <Typography variant={'body2'} color={theme.colorBase.textPrimary}>\n            {jsonObj?.network.toUpperCase()}\n          </Typography>\n        </Box>\n        <Typography variant={'body2'} marginTop={3}>\n          {t('labelGuardianCodeConfirmationDes')}\n        </Typography>\n        <Box marginTop={8} display={'flex'} justifyContent={'center'} paddingX={8}>\n          <Button\n            onClick={onClickCodeApprovalReject}\n            variant={'contained'}\n            sx={{ width: '150px', height: '52px', marginRight: 8 }}\n          >\n            {t('labelGuardianCodeReject')}\n          </Button>\n          <Button\n            onClick={onClickCodeApprovalApprove}\n            variant={'contained'}\n            sx={{ width: '150px', height: '52px' }}\n          >\n            {t('labelGuardianCodeApprove')}\n          </Button>\n        </Box>\n      </Box>\n    )\n  } else if (approvalCodeStatus === 'sharing') {\n    const jsonObj = decodeData(codeText)\n    // const guardianSign = '0xaa' // todo\n    return (\n      <Box display={'flex'} alignItems={'center'} flexDirection={'column'}>\n        <Typography marginBottom={1} variant={'h3'} textAlign={'center'}>\n          Share Approval Code\n        </Typography>\n        <Box\n          borderRadius={'12px'}\n          paddingX={2}\n          paddingTop={4}\n          paddingBottom={2}\n          width={'312px'}\n          bgcolor={theme.colorBase.box}\n          display={'flex'}\n          alignItems={'center'}\n          flexDirection={'column'}\n        >\n          <Typography textAlign={'center'}>{t('labelGuardianCodeSharingDes')}</Typography>\n          <Box width={200} marginTop={1.5} height={200}>\n            {sharingStr && (\n              <QRCodeV2\n                options={{\n                  data: sharingStr,\n                  width: 200,\n                  height: 200,\n                  imageOptions: {\n                    imageSize: 0.1,\n                  },\n                  image: `${SoursURL + 'svg/loopring.svg'}`,\n                }}\n              />\n            )}{' '}\n          </Box>\n          <Typography marginTop={1.5} textAlign={'center'}>\n            {t('labelGuardianCodeSharingApprovalRequest')}\n          </Typography>\n          <Typography\n            variant={'body2'}\n            marginTop={0.5}\n            textAlign={'center'}\n            color={theme.colorBase.textSecondary}\n            display={'flex'}\n            alignItems={'center'}\n          >\n            {sharingStr ? sharingStr.slice(0, 15) + '...' + sharingStr.slice(-15) : ''}\n            {sharingStr && (\n              <CopyIcon\n                sx={{ marginLeft: 0.5, cursor: 'pointer' }}\n                onClick={() => {\n                  navigator.clipboard.writeText(sharingStr)\n                }}\n              />\n            )}\n          </Typography>\n          <Box width={'100%'} marginTop={2.5} display={'flex'} justifyContent={'space-between'}>\n            <Typography variant={'body2'}>{t('labelGuardianCodeRequestType')}</Typography>\n            <Typography variant={'body2'} color={theme.colorBase.textPrimary}>\n              {jsonObj.metaTxType === 16\n                ? 'Recover Wallet'\n                : jsonObj.metaTxType === 34\n                ? 'Add Guardian'\n                : jsonObj.metaTxType === 35\n                ? 'Remove Guardian'\n                : jsonObj.metaTxType === 37\n                ? 'Unlock Wallet'\n                : jsonObj.metaTxType === 18\n                ? 'Exceed Daily Quota Transfer'\n                : jsonObj.metaTxType === 23\n                ? 'Token Approval'\n                : jsonObj.metaTxType === 201\n                ? 'Upgrade Wallet Contract'\n                : jsonObj.metaTxType === 202\n                ? 'Call Contract'\n                : 'Unknown'}\n            </Typography>\n          </Box>\n          <Box width={'100%'} marginTop={2} display={'flex'} justifyContent={'space-between'}>\n            <Typography variant={'body2'}>{t('labelGuardianCodeNetwork')}</Typography>\n            <Typography variant={'body2'} color={theme.colorBase.textPrimary}>\n              {jsonObj?.network.toUpperCase()}\n            </Typography>\n          </Box>\n          <Box width={'100%'} marginTop={2} display={'flex'} justifyContent={'space-between'}>\n            <Typography variant={'body2'}>{t('labelGuardianCodeRequester')}</Typography>\n            <Typography width={'55%'} variant={'body2'} sx={{wordBreak: 'break-all'}} color={theme.colorBase.textPrimary}>\n              {jsonObj?.sender}\n            </Typography>\n          </Box>\n          <Box width={'100%'} marginTop={2} display={'flex'} justifyContent={'space-between'}>\n            <Typography variant={'body2'}>{t('Authorization Result')}</Typography>\n            <Typography variant={'body2'} color={theme.colorBase.textPrimary}>\n              {t('Approved')}\n            </Typography>\n          </Box>\n          {/* <Typography marginTop={1.5}>Please send the QR code to the requester.</Typography> */}\n        </Box>\n        <Button\n          variant={'contained'}\n          sx={{\n            marginTop: 2,\n            marginBottom: 2,\n            width: '312px',\n          }}\n          onClick={() => {\n            new QRCodeStyling({\n              data: sharingStr,\n              width: 200,\n              height: 200,\n              imageOptions: {\n                imageSize: 0.1,\n              },\n              image: `${SoursURL + 'svg/loopring.svg'}`,\n            }).download()\n          }}\n        >\n          {t('labelGuardianCodeShare')}\n        </Button>\n      </Box>\n    )\n  }\n  return (\n    <>\n      <Modal open={openCode} onClose={() => setOpenCode(false)}>\n        <SwitchPanelStyled>\n          <Box display={'flex'} flexDirection={'column'}>\n            <ModalCloseButton onClose={() => setOpenCode(false)} t={t as any} />\n            <Typography component={'p'} textAlign={'center'} marginBottom={2} paddingX={2}>\n              <Typography\n                color={'var(--color-text-primary)'}\n                component={'p'}\n                variant={'h4'}\n                marginBottom={2}\n              >\n                {t('labelWalletInputGuardianCode')}\n              </Typography>\n              <Typography\n                color={'var(--color-text-secondary)'}\n                component={'p'}\n                variant={'body1'}\n                marginBottom={2}\n              >\n                {t('labelWalletInputGuardianCodeDes')}\n              </Typography>\n            </Typography>\n            <Box paddingBottom={3}>\n              <Box display={'flex'} alignItems={'center'} justifyContent={'center'}>\n                <InputCode\n                  length={VCODE_UNIT}\n                  onComplete={(code) => submitApprove(code, selected!)}\n                  loading={false}\n                />\n              </Box>\n              <Box display={'flex'} marginTop={4} marginX={2} justifyContent={'center'}>\n                <Button\n                  fullWidth\n                  variant={'contained'}\n                  size={'small'}\n                  color={'primary'}\n                  onClick={() => setOpenCode(false)}\n                >\n                  <Typography paddingX={2}> {t('labelCancel')}</Typography>\n                </Button>\n              </Box>\n            </Box>\n          </Box>\n        </SwitchPanelStyled>\n      </Modal>\n      <Box marginTop={5} marginBottom={10}>\n        <Typography variant='h4'>{t('labelGuardianCodeEnterApprovalCode')}</Typography>\n        <Box display={'flex'} marginTop={1.5}>\n          <Input\n            placeholder={t('labelGuardianCodeEnterApprovalCodeHint')}\n            sx={{\n              bgcolor: theme.colorBase.white,\n              flex: '1 1 auto',\n              height: '52px',\n              borderRadius: '8px',\n              paddingX: 2,\n              color: theme.colorBase.black,\n            }}\n            endAdornment={\n              <IconButton onClick={onClickScan} size={'large'}>\n                <ScanQRIcon />\n              </IconButton>\n            }\n            value={codeText}\n            onChange={(e) => onInputCode(e.target.value)}\n          />\n        </Box>\n        <Typography\n          marginTop={0.5}\n          visibility={codeInputError ? 'visible' : 'hidden'}\n          variant={'body2'}\n          color={theme.colorBase.error}\n        >\n          {codeInputError ?? '-'}\n        </Typography>\n        <Box width={'100%'} display={'flex'} justifyContent={'center'}>\n          <Button\n            sx={{\n              width: '30%',\n              height: '48px',\n              minWidth: '312px',\n              marginTop: 3,\n            }}\n            variant={'contained'}\n            onClick={onClickNext}\n            disabled={nextBtnDisabled}\n          >\n            {t('labelGuardianCodeNext')}\n          </Button>\n        </Box>\n      </Box>\n      {guardiansList.length !== 0 ? (\n        <Box height={'320px'} overflow='scroll'>\n          {guardiansList.map((guardian, index) => {\n            return (\n              <Box\n                key={guardian.address + index}\n                display={'flex'}\n                alignItems={'center'}\n                justifyContent={'space-between'}\n                marginBottom={2}\n              >\n                <Box>\n                  <Typography variant={'body1'}>\n                    <Trans\n                      i18nKey={'labelWalletSignType'}\n                      tOptions={{ type: t('labelTxGuardian_' + guardian.type) }}\n                    >\n                      Request for {guardian?.type?.replace('_', ' ').toUpperCase() ?? 'Unknown'}\n                    </Trans>\n                  </Typography>\n                  <Typography variant={'body1'}>\n                    {guardian.ens ? `${guardian.ens} /` : ''}\n                    <Typography\n                      title={guardian.address}\n                      component={'span'}\n                      color={'var(--color-text-third)'}\n                    >\n                      {guardian.address &&\n                        `${guardian.address.slice(0, 6)}...${guardian.address.slice(\n                          guardian.address.length - 4,\n                        )}`}\n                    </Typography>\n                  </Typography>\n                </Box>\n                <Box>\n                  <Box display={'inline-block'} marginRight={2}>\n                    <Button\n                      variant={'outlined'}\n                      size={'medium'}\n                      onClick={() => {\n                        handleOpenApprove(guardian)\n                      }}\n                    >\n                      {t('labelApprove')}\n                    </Button>\n                  </Box>\n                  <Button\n                    onClick={() => handleReject(guardian)}\n                    variant={'outlined'}\n                    size={'medium'}\n                  >\n                    Reject\n                  </Button>\n                </Box>\n              </Box>\n            )\n          })}\n        </Box>\n      ) : (\n        <></>\n      )}\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/web-guardian/src/pages/WalletPage/hook.ts",
    "content": "import React from 'react'\nimport {\n  callSwitchChain,\n  layer1Store,\n  LoopringAPI,\n  store,\n  useAccount,\n  useSystem,\n} from '@loopring-web/core'\n\nimport {\n  Layer1Action,\n  MapChainId,\n  myLog,\n  SagaStatus,\n  SDK_ERROR_MAP_TO_UI,\n} from '@loopring-web/common-resources'\n\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nimport { GuardianStep, useSettings } from '@loopring-web/component-lib'\nimport { connectProvides } from '@loopring-web/web3-provider'\nimport { useTranslation } from 'react-i18next'\n\nexport enum TxGuardianHistoryType {\n  ADD_GUARDIAN = 51,\n  GUARDIAN_CONFIRM_ADDITION = 52,\n  GUARDIAN_REJECT_ADDITION = 53,\n  GUARDIAN_APPROVE = 54,\n  APPROVE_RECOVER = 55, // RECOVER  16\n  APPROVE_TRANSFER = 56, // APPROVE TRANSFER 18\n  APPROVE_TOKEN_APPROVE = 57, // 23\n  ADD_GUARDIAN_WA = 58, // 34\n  REMOVE_GUARDIAN_WA = 59, // 35\n  UNLOCK_WALLET_WA = 60, // 37\n  RESET_GUARDIANS_WA = 61, // 200\n  CALL_CONTRACT_WA = 62, //201\n}\n\nexport enum TxHebaoAction {\n  Approve,\n  Reject,\n}\n\nexport const useHebaoMain = <\n  T extends sdk.Protector,\n  G extends sdk.Guardian,\n  H extends sdk.HebaoOperationLog,\n>() => {\n  const { account, status: accountStatus } = useAccount()\n  const [loopringSmartContractWallet, setLoopringSmartContractWallet] = React.useState<\n    boolean | undefined\n  >(undefined)\n  const [nonLoopringSmartContractWallet, setNonLoopringSmartContractWallet] = React.useState<\n    boolean | undefined\n  >(undefined)\n\n  const [{ guardianConfig, protectList, guardiansList, operationLogList }, setList] =\n    React.useState<{\n      guardianConfig: any\n      protectList: T[]\n      guardiansList: G[]\n      operationLogList: H[]\n    }>({\n      protectList: [],\n      guardiansList: [],\n      operationLogList: [],\n      guardianConfig: {},\n    })\n\n  const { clearOneItem } = layer1Store.useLayer1Store()\n  const [isLoading, setIsLoading] = React.useState(false)\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const networkName: sdk.NetworkWallet = sdk.NetworkWallet[network]\n  // sdk.NetworkWallet[MapChainId[AvaiableNetwork.includes(chainId.toString()) ? chainId : 1]]\n  const loadData = React.useCallback(async () => {\n    const layer1ActionHistory = store.getState().localStore.layer1ActionHistory\n    if (LoopringAPI.walletAPI && account.accAddress) {\n      setIsLoading(true)\n      const [{ raw_data: guardianConfig }, protector, guardian, guardianoperationlog]: any =\n        await Promise.all([\n          LoopringAPI.walletAPI.getHebaoConfig({ network: networkName }),\n          LoopringAPI.walletAPI\n            .getProtectors(\n              {\n                guardian: account.accAddress,\n                network: networkName,\n              },\n              account.apiKey,\n            )\n            .then((protector) => {\n              if ((protector as sdk.RESULT_INFO)?.code) {\n                throw protector\n              }\n              try {\n                protector?.protectorArray?.map((props) => {\n                  if (\n                    layer1ActionHistory &&\n                    layer1ActionHistory[defaultNetwork] &&\n                    layer1ActionHistory[defaultNetwork][Layer1Action.GuardianLock] &&\n                    layer1ActionHistory[defaultNetwork][Layer1Action.GuardianLock][\n                      props.address\n                    ] &&\n                    props.lockStatus === sdk.HEBAO_LOCK_STATUS.CREATED\n                  ) {\n                    props.lockStatus = sdk.HEBAO_LOCK_STATUS.LOCK_WAITING\n                  } else {\n                    clearOneItem({\n                      chainId: defaultNetwork as sdk.ChainId,\n                      uniqueId: props.address,\n                      domain: Layer1Action.GuardianLock,\n                    })\n                  }\n\n                  return props\n                })\n              } catch (error) {\n                throw error\n              }\n\n              return protector\n            }),\n          // api/wallet/v3/operationLogs\n          LoopringAPI.walletAPI\n            .getGuardianApproveList({\n              guardian: account.accAddress,\n              network: networkName,\n            })\n            .then((guardian) => {\n              if ((guardian as sdk.RESULT_INFO)?.code) {\n                throw protector\n              }\n              try {\n                guardian?.guardiansArray?.map((ele) => {\n                  ele.businessDataJson = JSON.parse(ele.businessDataJson ?? '')\n                  return ele\n                })\n              } catch (error) {\n                throw error\n              }\n              return guardian\n            }),\n          LoopringAPI.walletAPI.getHebaoOperationLogs({\n            from: account.accAddress,\n            fromTime: 0,\n            offset: 0,\n            limit: 50,\n            network: networkName,\n          }),\n        ])\n          .catch((error) => {\n            myLog('guardianConfig error', error)\n            setIsLoading(false)\n          })\n          .finally(() => {\n            setIsLoading(false)\n          })\n\n      const _guardiansList: G[] = guardian?.guardiansArray\n        ? guardian.guardiansArray.reduce((prev: G[], approve: G) => {\n            const _protector = protector.protectorArray?.find(\n              ({ address: pAddress }: any) =>\n                pAddress?.toLowerCase() === approve?.address?.toLowerCase(),\n            )\n            if (_protector) {\n              // @ts-ignore\n              approve.ens = _protector.ens\n              return [...prev, approve] as G[]\n            }\n            return prev\n          }, [] as G[])\n        : []\n\n      setList({\n        protectList: protector.protectorArray ?? [],\n        guardiansList: _guardiansList,\n        operationLogList: guardianoperationlog?.operationArray ?? [],\n        guardianConfig,\n      })\n    }\n  }, [account.accAddress, account.apiKey, defaultNetwork, clearOneItem])\n\n  React.useEffect(() => {\n    if (account.accAddress && accountStatus === SagaStatus.UNSET) {\n      loadData()\n      LoopringAPI.walletAPI\n        ?.getWalletType({\n          wallet: account.accAddress,\n          network: networkName,\n        })\n        .then(({ walletType }) => {\n          setLoopringSmartContractWallet(\n            walletType?.isInCounterFactualStatus ||\n              (walletType?.isContract && walletType?.loopringWalletContractVersion !== ''),\n          )\n          setNonLoopringSmartContractWallet(\n            walletType?.isContract && walletType?.loopringWalletContractVersion === '',\n          )\n        })\n        .catch(() => {\n          setNonLoopringSmartContractWallet(true)\n        })\n    }\n  }, [accountStatus])\n  return {\n    loopringSmartContractWallet,\n    nonLoopringSmartContractWallet,\n    protectList,\n    guardiansList,\n    guardianConfig,\n    // openHebao,\n    operationLogList,\n    // setOpenHebao,\n    isLoading,\n    setIsLoading,\n    loadData,\n  }\n}\n\nexport const useAction = ({\n  setSelected,\n  setOpenCode,\n  guardianConfig,\n  isContractAddress,\n  loadData,\n  handleOpenModal,\n}: {\n  setSelected: (state: sdk.Guardian | undefined) => void\n  setOpenCode: (state: boolean) => void\n  guardianConfig: any\n  isContractAddress: boolean\n  loadData: () => Promise<void>\n  handleOpenModal: (props: { step: GuardianStep; options?: any }) => void\n}) => {\n  const { t } = useTranslation()\n  const { account } = useAccount()\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const [isFirstTime, setIsFirstTime] = React.useState<boolean>(true)\n\n  const networkName: sdk.NetworkWallet = sdk.NetworkWallet[network]\n  const submitApprove = async (code: string, selected: sdk.Guardian) => {\n    setOpenCode(false)\n    handleOpenModal({\n      step: GuardianStep.Approve_WaitForAuth,\n      options: {\n        lockRetry: () => {\n          submitApprove(code, selected)\n        },\n      },\n    })\n    if (LoopringAPI.walletAPI && selected && connectProvides.usedWeb3) {\n      try {\n        const [\n          {\n            // @ts-ignore\n            raw_data: { data: contractTypes },\n          },\n          _chainId,\n        ] = await Promise.all([\n          LoopringAPI.walletAPI.getContractType({\n            wallet: selected.address,\n            network: networkName,\n          }),\n          connectProvides.usedWeb3.eth.getChainId(),\n        ])\n\n        await callSwitchChain(_chainId)\n        let isContract1XAddress: any = undefined,\n          guardianModuleAddress: any = undefined\n        // guardians: any = undefined\n        let walletModule: any,\n          type = sdk.HEBAO_META_TYPE[selected.type] as unknown as sdk.HEBAO_META_TYPE\n        const contractType = contractTypes?.find(\n          (item) => item?.network.toUpperCase() === networkName,\n        )\n        if (contractType && contractType.contractVersion?.startsWith('V1_')) {\n          switch (type) {\n            case sdk.HEBAO_META_TYPE.transfer:\n            case sdk.HEBAO_META_TYPE.deposit_wallet:\n            case sdk.HEBAO_META_TYPE.approve_token:\n              walletModule = guardianConfig?.supportContracts?.find((item: any) => {\n                return item.contractName === 'TRANSFER_MODULE'\n              })\n              break\n            default:\n              walletModule = guardianConfig?.supportContracts?.find((item: any) => {\n                return item.contractName === 'GUARDIAN_MODULE'\n              })\n          }\n          isContract1XAddress = true\n          guardianModuleAddress = walletModule?.contractAddress\n        }\n        const request: sdk.ApproveSignatureRequest = {\n          approveRecordId: selected.id,\n          txAwareHash: selected.messageHash,\n          securityNumber: code,\n          signer: account.accAddress,\n          signature: '',\n          network: networkName,\n        }\n        const _selected = selected.signedRequest.wallet\n          ? selected\n          : {\n              ...selected,\n              signedRequest: {\n                ...selected.signedRequest,\n                wallet: selected.wallet,\n              },\n            }\n        const response = await LoopringAPI.walletAPI.submitApproveSignature(\n          {\n            request: request,\n            guardian: { ..._selected, type: sdk.HEBAO_META_TYPE[_selected.type] as any },\n            web3: connectProvides.usedWeb3 as any,\n            chainId: _chainId,\n            eddsaKey: '',\n            apiKey: '',\n            isHWAddr: false, // !isFirstTime,\n            walletType: account.connectName as any,\n          },\n          [],\n          isContract1XAddress,\n          contractType?.masterCopy ?? undefined,\n          guardianModuleAddress ?? undefined,\n        )\n        // .then((response) => {\n        if ((response as sdk.RESULT_INFO).code !== 0) {\n          handleOpenModal({\n            step: GuardianStep.Approve_Failed,\n            options: {\n              error: response,\n              lockRetry: () => {\n                submitApprove(code, selected)\n              },\n            },\n          })\n        } else {\n          handleOpenModal({\n            step: GuardianStep.Approve_Success,\n          })\n          loadData()\n        }\n      } catch (error: any) {\n        setIsFirstTime((state) => !state)\n        const errorItem = SDK_ERROR_MAP_TO_UI[error?.code ?? 700001]\n        handleOpenModal({\n          step: GuardianStep.Approve_Failed,\n          options: {\n            error: errorItem ? t(errorItem.messageKey, { ns: 'error' }) : error.message,\n            lockRetry: () => {\n              submitApprove(code, selected)\n            },\n          },\n        })\n      }\n      // })\n      // .catch((error: any) => {\n\n      // })\n    }\n  }\n  const handleReject = async (guardian: sdk.Guardian) => {\n    handleOpenModal({\n      step: GuardianStep.Reject_WaitForAuth,\n      options: {\n        lockRetry: () => {\n          handleReject(guardian)\n        },\n      },\n    })\n    if (LoopringAPI.walletAPI && guardian && connectProvides.usedWeb3) {\n      try {\n        const _chainId = await connectProvides.usedWeb3.eth.getChainId()\n        await callSwitchChain(_chainId)\n        const request = {\n          approveRecordId: guardian.id,\n          signer: account.accAddress,\n          network: networkName,\n        }\n        const response = await LoopringAPI.walletAPI.rejectHebao({\n          request,\n          web3: connectProvides.usedWeb3 as any,\n          address: account.accAddress,\n          chainId: _chainId as any,\n          guardiaContractAddress: guardian.address,\n          walletType: account.connectName as any,\n        })\n        // .then((response) => {\n        if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n          handleOpenModal({\n            step: GuardianStep.Reject_Failed,\n            options: {\n              error: response,\n              lockRetry: () => {\n                handleReject(guardian)\n              },\n            },\n          })\n        } else {\n          handleOpenModal({\n            step: GuardianStep.Approve_Success,\n          })\n          loadData()\n        }\n        // })\n      } catch (error: any) {\n        const errorItem = SDK_ERROR_MAP_TO_UI[error?.code ?? 700001]\n        handleOpenModal({\n          step: GuardianStep.Approve_Failed,\n          options: {\n            error: errorItem ? t(errorItem.messageKey, { ns: 'error' }) : error.message,\n            lockRetry: () => {\n              handleReject(guardian)\n            },\n          },\n        })\n      }\n    }\n  }\n  const handleOpenApprove = (guardian: sdk.Guardian) => {\n    if (isContractAddress) {\n      // setNotSupportOpen(true)\n      return\n    }\n    setOpenCode(true)\n    setSelected(guardian)\n  }\n  return {\n    submitApprove,\n    handleReject,\n    handleOpenApprove,\n  }\n}\n\nexport const useHebaoProtector = <T extends sdk.Protector>({\n  guardianConfig,\n  handleOpenModal,\n  loadData,\n}: {\n  guardianConfig: any\n  // isContractAddress: boolean;\n  handleOpenModal: (props: { step: GuardianStep; options?: any }) => void\n  loadData: () => Promise<void>\n}) => {\n  const { account } = useAccount()\n  const { chainId, gasPrice } = useSystem()\n  const { t } = useTranslation(['error'])\n  const { setOneItem } = layer1Store.useLayer1Store()\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const networkName: sdk.NetworkWallet = sdk.NetworkWallet[network]\n  const onLock = React.useCallback(\n    async (item: T) => {\n      handleOpenModal({\n        step: GuardianStep.LockAccount_WaitForAuth,\n        options: {\n          lockRetry: () => {\n            onLock(item)\n          },\n          lockRetryParams: item,\n        },\n      })\n      const config = guardianConfig.actionGasSettings.find(\n        (item: any) => item.action === 'META_TX_LOCK_WALLET_WA',\n      )\n      const guardianModule = guardianConfig.supportContracts.find(\n        (ele: any) => ele.contractName.toUpperCase() === 'GUARDIAN_MODULE',\n      ).contractAddress\n\n      if (LoopringAPI?.walletAPI && connectProvides.usedWeb3) {\n        try {\n          const [isVersion1, nonce, _chainId] = await Promise.all([\n            LoopringAPI.walletAPI\n              .getWalletType({\n                wallet: item.address, //account.accAddress,\n                network: networkName,\n              })\n              .then(({ walletType }) => {\n                if (walletType && walletType.loopringWalletContractVersion?.startsWith('V1_')) {\n                  return true\n                } else {\n                  return false\n                }\n              }),\n            sdk.getNonce(connectProvides.usedWeb3 as any, account.accAddress),\n            await connectProvides.usedWeb3.eth.getChainId(),\n          ])\n          await callSwitchChain(_chainId)\n          const params: sdk.LockHebaoHebaoParam = {\n            web3: connectProvides.usedWeb3 as any,\n            from: account.accAddress,\n            contractAddress: isVersion1 ? guardianModule : item.address,\n            wallet: item.address,\n            gasPrice: '0x' + Number(gasPrice).toString(16),\n            gasLimit: '0x' + Number(config.gasLimit).toString(16),\n            chainId: chainId as any,\n            isVersion1,\n            nonce,\n            sendByMetaMask: true,\n          }\n          myLog('LockHebaoHebaoParam params', params)\n          const { error } = await LoopringAPI.walletAPI.lockHebaoWallet(params)\n          const errorItem = SDK_ERROR_MAP_TO_UI[error?.code ?? 700001]\n          if (error) {\n            handleOpenModal({\n              step: GuardianStep.LockAccount_Failed,\n              options: {\n                error: errorItem ? t(errorItem.messageKey) : error.message,\n                lockRetry: () => {\n                  onLock(item)\n                },\n                lockRetryParams: item,\n              },\n            })\n          } else {\n            setOneItem({\n              chainId: chainId as sdk.ChainId,\n              uniqueId: item.address,\n              domain: Layer1Action.GuardianLock,\n            })\n            handleOpenModal({\n              step: GuardianStep.LockAccount_Success,\n            })\n            loadData()\n          }\n        } catch (reason: any) {\n          // result.code = ActionResultCode.ApproveFailed;\n          // result.data = reason;\n          sdk.dumpError400(reason)\n          handleOpenModal({\n            step: GuardianStep.LockAccount_User_Denied,\n            options: {\n              error: reason.message,\n              lockRetry: () => {\n                onLock(item)\n              },\n              lockRetryParams: item,\n            },\n          })\n        }\n      }\n    },\n    [\n      guardianConfig.actionGasSettings,\n      guardianConfig.supportContracts,\n      account.accAddress,\n      gasPrice,\n      chainId,\n      handleOpenModal,\n      t,\n      setOneItem,\n      loadData,\n    ],\n  )\n  return {\n    onLock,\n  }\n}\n"
  },
  {
    "path": "packages/web-guardian/src/pages/WalletPage/index.tsx",
    "content": "import { useTranslation, WithTranslation, withTranslation } from 'react-i18next'\nimport React, { MouseEventHandler, ReactNode, useCallback } from 'react'\nimport {\n  AccountStatus,\n  ApprovalIcon,\n  BackIcon,\n  CopyIcon,\n  copyToClipBoard,\n  ExitIcon,\n  FailedIcon,\n  HelpIcon,\n  L1L2_NAME_DEFINED,\n  LockGuardianIcon,\n  LOOPRING_DOCUMENT,\n  MapChainId,\n  myLog,\n  RefuseIcon,\n  RoundAddIcon,\n  ViewHistoryIcon,\n} from '@loopring-web/common-resources'\nimport { Box, Button, Link, Tooltip, Typography } from '@mui/material'\nimport { GuardianStep, QRCodePanel, useSettings } from '@loopring-web/component-lib'\nimport { BtnConnectL1, callSwitchChain, LoopringAPI, readFileQrCode, useAccount } from '@loopring-web/core'\nimport { useHebaoMain } from './hook'\nimport { ModalLock } from './modal'\nimport { WalletHistory } from './WalletHistory'\nimport { WalletValidationInfo } from './WalletValidationInfo'\nimport { WalletProtector } from './WalletProtector'\nimport styled from '@emotion/styled'\nimport { connectProvides, walletServices } from '@loopring-web/web3-provider'\nimport { GuardianModal } from './GuardianModal'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nimport { useWalletInfo } from '@loopring-web/core/src/stores/localStore/walletInfo'\nimport { decodeData, getSignature } from './utils'\n\n\nconst WrongStatusStyled = styled(Box)`\n  display: flex;\n  justify-content: center;\n  flex-direction: column;\n  width: 100%;\n  align-items: center;\n  padding: ${({ theme }) => theme.unit * 10}px auto;\n  background-color: ${({ theme }) => theme.colorBase.box};\n\n  .logo {\n    margin-bottom: ${({ theme }) => theme.unit * 8}px;\n  }\n\n  .content {\n    text-align: center;\n    color: ${({ theme }) => theme.colorBase.textSecondary};\n    width: ${({ theme }) => theme.unit * 50}px;\n    margin-bottom: ${({ theme }) => theme.unit * 8}px;\n  }\n\n  .button {\n    color: ${({ theme }) => theme.colorBase.textSecondary};\n  }\n`\n\nconst WrongStatus = ({\n  logo,\n  content,\n  onClickDisconnect,\n}: {\n  logo: ReactNode\n  content: string\n  onClickDisconnect: MouseEventHandler\n}) => {\n  const { t } = useTranslation()\n  return (\n    <WrongStatusStyled>\n      <Box className='logo'>{logo}</Box>\n      <Typography className={'content'}>{content}</Typography>\n      <Button className={'button'} onClick={onClickDisconnect}>\n        <ExitIcon />\n        <Typography marginLeft={0.5}>{t('labelDisconnect')}</Typography>\n      </Button>\n    </WrongStatusStyled>\n  )\n}\n\nconst SectionStyled = styled(Box)<{ isMobile?: boolean }>`\n  padding: ${({ theme }) => theme.unit * 4}px;\n  padding-top: initial;\n  padding-bottom: initial;\n  background: ${({ theme }) => theme.colorBase.box};\n  margin-bottom: ${({ theme }) => theme.unit * 2}px;\n  width: ${({ theme, isMobile }) => (isMobile ? '100%' : `${theme.unit * 60}px`)};\n  height: 96px;\n  cursor: pointer;\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  border: 1px solid var(--color-border);\n  border-radius: ${({ theme }) => theme.unit}px;\n`\n\nconst Section = ({\n  logo,\n  title,\n  description,\n  onClick,\n}: {\n  logo: JSX.Element\n  title: string\n  description?: string\n  onClick: MouseEventHandler\n}) => {\n  const { isMobile } = useSettings()\n  return (\n    <>\n      <SectionStyled isMobile={isMobile} onClick={onClick}>\n        <Box display={'flex'} alignItems={'center'}>\n          {logo}\n          <Box paddingLeft={3}>\n            <Typography variant={'h4'}>{title}</Typography>\n            {description && (\n              <Typography color={'var(--color-text-third) '}>{description}</Typography>\n            )}\n          </Box>\n        </Box>\n        <BackIcon sx={{ transform: 'rotate(180deg)' }} />\n      </SectionStyled>\n    </>\n  )\n}\n\nconst ContainerStyled = styled(Box)`\n  display: flex;\n  flex-direction: column;\n  width: 100%;\n  align-items: center;\n  padding: ${({ theme }) => theme.unit * 10}px auto;\n`\n\nexport const GuardianPage = withTranslation(['common'])(({ t, ..._rest }: WithTranslation) => {\n  const { account } = useAccount()\n  const { defaultNetwork, isMobile } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const networkName: sdk.NetworkWallet = sdk.NetworkWallet[network]\n  const [openQRCode, setOpenQRCode] = React.useState(false)\n  const onOpenAdd = React.useCallback((open: boolean) => {\n    setOpenQRCode(open)\n  }, [])\n  const [showHistory, setShowHistory] = React.useState(false)\n  const onOpenHistory = React.useCallback((open: boolean) => {\n    setShowHistory(open)\n  }, [])\n  const [approvalRequests, setApprovalRequests] = React.useState<{\n    show: boolean,\n    codeApprovalStatus: 'init' | 'confirmation' | 'sharing'\n    codeInput: string,\n    guardianSign?: string\n    approveHash?: string\n  } >({\n    show: false,\n    codeApprovalStatus: 'init',\n    codeInput: '',\n    guardianSign: undefined,\n    approveHash: undefined\n  })\n  const onOpenApprovalRequests = React.useCallback((open: boolean) => {\n    setApprovalRequests({\n      show: open,\n      codeApprovalStatus: 'init',\n      codeInput: '',\n      guardianSign: '' \n    })\n  }, [approvalRequests])\n\n  const [showLockWallet, setShowLockWallet] = React.useState(false)\n  const onOpenLockWallet = React.useCallback((open: boolean) => {\n    setShowLockWallet(open)\n  }, [])\n\n  const {\n    protectList,\n    guardiansList,\n    guardianConfig,\n    // openHebao,\n    operationLogList,\n    // setOpenHebao,\n    loadData,\n    loopringSmartContractWallet,\n    nonLoopringSmartContractWallet,\n  } = useHebaoMain()\n  const [openHebao, setOpenHebao] = React.useState<{\n    isShow: boolean\n    step: GuardianStep\n    options?: any\n  }>({\n    isShow: false,\n    step: GuardianStep.LockAccount_WaitForAuth,\n    options: undefined,\n  })\n  const handleOpenModal = ({ step, options }: { step: GuardianStep; options?: any }) => {\n    setOpenHebao((state) => {\n      state.isShow = true\n      state.step = step\n      state.options = {\n        ...state.options,\n        ...options,\n      }\n      return { ...state }\n    })\n  }\n  const isContractAddress =\n    loopringSmartContractWallet === true || nonLoopringSmartContractWallet === true\n  const onClickCopy = useCallback((str: string) => {\n    copyToClipBoard(str)\n  }, [])\n  \n  const { checkHWAddr }= useWalletInfo()\n\n  switch (account.readyState) {\n    case AccountStatus.UN_CONNECT:\n      return (\n        <Box\n          flex={1}\n          display={'flex'}\n          justifyContent={'center'}\n          flexDirection={'column'}\n          alignItems={'center'}\n        >\n          <Typography marginTop={3} variant={isMobile ? 'h4' : 'h1'} textAlign={'center'}>\n            {t('describeTitleConnectToWalletAsGuardian', {\n              layer2: L1L2_NAME_DEFINED[network].layer2,\n              l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n            })}\n          </Typography>\n          <Link\n            marginY={2}\n            variant={'body1'}\n            textAlign={'center'}\n            color={'textSecondary'}\n            target='_blank'\n            rel='noopener noreferrer'\n            href={LOOPRING_DOCUMENT + 'walletdesign_en.md'}\n          >\n            {t('describeWhatIsGuardian')}\n          </Link>\n          <BtnConnectL1 />\n        </Box>\n      )\n    case AccountStatus.LOCKED:\n    case AccountStatus.NO_ACCOUNT:\n    case AccountStatus.NOT_ACTIVE:\n    case AccountStatus.DEPOSITING:\n    case AccountStatus.ACTIVATED:\n      if (nonLoopringSmartContractWallet) {\n        return (\n          <WrongStatus\n            logo={<FailedIcon htmlColor='var(--color-error)' style={{ width: 60, height: 60 }} />}\n            content={t('labelWalletNonLoopringSmartWallet')}\n            onClickDisconnect={() => {\n              walletServices.sendDisconnect('', 'customer click disconnect')\n            }}\n          />\n        )\n      }\n      break\n    default:\n      break\n  }\n  myLog(\n    'HebaoAddGuardian URL',\n    `${networkName?.toLowerCase()}:${account?.accAddress}?type=${\n      account?.connectName\n    }&action=HebaoAddGuardian`,\n  )\n\n  \n  \n  const codeInputValidation = () => {\n    if (approvalRequests.codeInput) {\n      try {\n        const jsonObj = decodeData(approvalRequests.codeInput)\n        if (!jsonObj) return t('labelGuardianCodeFormatError')\n        const found = protectList.find(protect => {\n          return protect.address.toLowerCase() === jsonObj.sender.toLowerCase()\n        })\n        if (!found) return t('labelGuardianNotWhoIProtect')\n        if (network.toLowerCase() !== jsonObj.network.toLowerCase()) {\n          return t('labelGuardianCodeNetworkError') \n        }\n      } catch {\n        return t('labelGuardianCodeFormatError')\n      }\n    } else {\n      return undefined\n    }\n  }\n  // const { isMobile } = useSettings();\n  return (\n    <>\n      <GuardianModal\n        open={openQRCode}\n        onClose={() => onOpenAdd(false)}\n        title={\n          <Typography component={'span'} textAlign={'center'} marginBottom={1}>\n            <Typography\n              color={'var(--color-text-primary)'}\n              component={'span'}\n              variant={'h4'}\n              marginBottom={2}\n              display={'flex'}\n              alignItems={'center'}\n              justifyContent={'center'}\n            >\n              {t('labelWalletAddAsGuardian')}\n              <Tooltip title={<>{t('labelWalletGuardianHint')}</>}>\n                <Box marginLeft={1} display={'flex'} alignItems={'center'}>\n                  <HelpIcon fontSize='large' />\n                </Box>\n              </Tooltip>\n            </Typography>\n            <Typography\n              color={'var(--color-text-secondary)'}\n              component={'span'}\n              variant={'body1'}\n              marginBottom={2}\n            >\n              {t('labelWalletScanQRCode')}\n            </Typography>\n          </Typography>\n        }\n        body={\n          <QRCodePanel\n            description={\n              <Button onClick={() => account?.accAddress && onClickCopy(account?.accAddress)}>\n                <Typography\n                  marginTop={2}\n                  component={'div'}\n                  variant={'body2'}\n                  display={'flex'}\n                  justifyContent={'center'}\n                  alignItems={'center'}\n                >\n                  <Typography\n                    color={'var(--color-text-secondary)'}\n                    component={'p'}\n                    variant={'inherit'}\n                    display={'flex'}\n                    alignItems={'center'}\n                  >\n                    <Typography marginRight={0.5}>{account?.accAddress}</Typography>\n                    <CopyIcon />\n                  </Typography>\n                </Typography>\n              </Button>\n            }\n            size={260}\n            url={`${networkName?.toLowerCase()}:${account?.accAddress}?type=${\n              account?.connectName\n            }&action=HebaoAddGuardian`}\n          />\n        }\n      />\n      <GuardianModal\n        open={showLockWallet}\n        onClose={() => onOpenLockWallet(false)}\n        title={\n          <Typography component={'p'} textAlign={'center'} marginBottom={1}>\n            <Typography\n              color={'var(--color-text-primary)'}\n              component={'p'}\n              variant={'h4'}\n              marginBottom={2}\n            >\n              {t('labelWalletLockTitle')}\n            </Typography>\n            <Typography\n              color={'var(--color-text-secondary)'}\n              component={'p'}\n              variant={'body1'}\n              marginBottom={2}\n            >\n              {t('labelWalletLockDes')}\n            </Typography>\n          </Typography>\n        }\n        body={\n          <WalletProtector\n            guardianConfig={guardianConfig}\n            loadData={loadData}\n            handleOpenModal={handleOpenModal}\n            protectorList={protectList}\n          />\n        }\n      />\n      <GuardianModal\n        open={approvalRequests.show}\n        onClose={() => onOpenApprovalRequests(false)}\n        background={approvalRequests.codeApprovalStatus === 'sharing' ? 'var(--color-pop-bg)' : undefined}\n        title={\n          approvalRequests.codeApprovalStatus !== 'sharing' && (\n            <Typography component={'p'} textAlign={'center'} marginBottom={1}>\n              <Typography\n                color={'var(--color-text-primary)'}\n                component={'p'}\n                variant={'h4'}\n                marginBottom={2}\n              >\n                {t('labelWalletValidationTitle')}\n              </Typography>\n              <Typography\n                color={'var(--color-text-secondary)'}\n                component={'p'}\n                variant={'body1'}\n                marginBottom={2}\n              >\n                {t('labelWalletValidationDes')}\n              </Typography>\n            </Typography>\n          )\n        }\n        \n        body={\n          <WalletValidationInfo\n            isContractAddress={isContractAddress}\n            loadData={loadData}\n            guardianConfig={guardianConfig}\n            handleOpenModal={handleOpenModal}\n            guardiansList={guardiansList}\n            guardianSign={approvalRequests.guardianSign}\n            approveHash={approvalRequests.approveHash}\n            approvalCodeStatus={approvalRequests.codeApprovalStatus}\n            onClickCodeApprovalApprove={async () => {\n              const jsonObj = decodeData(approvalRequests.codeInput)\n              const metaTxData =\n                jsonObj.metaTxType === sdk.HEBAO_META_TYPE.recovery\n                  ? {\n                      newGuardians: jsonObj.extra.newGuardians,\n                      newOwner: jsonObj.extra.newOwner,\n                    }\n                  : jsonObj.metaTxType === sdk.HEBAO_META_TYPE.transfer\n                  ? {\n                      ...jsonObj.extra,\n                      amount: jsonObj.extra.value,\n                      logdata: '0x',\n                    }\n                  : jsonObj.metaTxType === sdk.HEBAO_META_TYPE.approve_token\n                  ? {\n                      ...jsonObj.extra,\n                      amount: jsonObj.extra.value,\n                    }\n                  : jsonObj.extra\n              const data = await getSignature({\n                web3: connectProvides.usedWeb3,\n                guardianAddr: account.accAddress,\n                senderAddr: jsonObj.sender,\n                metaTxType: jsonObj.metaTxType,\n                networkName: (jsonObj.network as string).toUpperCase() as sdk.NetworkWallet,\n                validUntil: jsonObj.validUntil,\n                moduleAddress: jsonObj.extra.masterCopy,\n                metaTxData: metaTxData,\n                isHWAddr: checkHWAddr(account.accAddress),\n              })\n              setApprovalRequests({\n                ...approvalRequests,\n                codeApprovalStatus: 'sharing',\n                guardianSign: data!.signature,\n                approveHash: data!.hash\n              })\n            }}\n            onClickCodeApprovalReject={() => {\n              setApprovalRequests({\n                ...approvalRequests,\n                codeApprovalStatus: 'init',\n              })\n            }}\n            onClickNext={async () => {\n              const jsonObj = decodeData(approvalRequests.codeInput)\n              const metaTxData =\n                jsonObj.metaTxType === sdk.HEBAO_META_TYPE.recovery\n                  ? {\n                      newGuardians: jsonObj.extra.newGuardians,\n                      newOwner: jsonObj.extra.newOwner,\n                    }\n                  : jsonObj.metaTxType === sdk.HEBAO_META_TYPE.transfer\n                  ? {\n                      ...jsonObj.extra,\n                      amount: jsonObj.extra.value,\n                      logdata: '0x',\n                    }\n                  : jsonObj.metaTxType === sdk.HEBAO_META_TYPE.approve_token\n                  ? {\n                      ...jsonObj.extra,\n                      amount: jsonObj.extra.value,\n                    }\n                  : jsonObj.extra\n              \n              const data = await getSignature({\n                web3: connectProvides.usedWeb3,\n                guardianAddr: account.accAddress,\n                senderAddr: jsonObj.sender,\n                metaTxType: jsonObj.metaTxType,\n                networkName: (jsonObj.network as string).toUpperCase() as sdk.NetworkWallet,\n                validUntil: jsonObj.validUntil,\n                moduleAddress: jsonObj.extra.masterCopy,\n                metaTxData: metaTxData,\n                isHWAddr: checkHWAddr(account.accAddress),\n              })\n              setApprovalRequests({\n                ...approvalRequests,\n                codeApprovalStatus: 'sharing',\n                guardianSign: data!.signature,\n                approveHash: data!.hash\n              })\n            }}\n            onClickScan={() => {\n              readFileQrCode().then((value) => {\n                setApprovalRequests({\n                  ...approvalRequests,\n                  codeInput: value,\n                })\n              })\n            }}\n            onInputCode={(str) => {\n              setApprovalRequests({\n                ...approvalRequests,\n                codeInput: str,\n              })\n            }}\n            codeText={approvalRequests.codeInput}\n            codeInputError={codeInputValidation()}\n            nextBtnDisabled={(!approvalRequests.codeInput || codeInputValidation()) ? true : false}\n            guardian={account.accAddress}\n          />\n        }\n      />\n      <GuardianModal\n        open={showHistory}\n        onClose={() => onOpenHistory(false)}\n        title={\n          <Typography component={'p'} textAlign={'center'} marginBottom={1}>\n            <Typography\n              color={'var(--color-text-primary)'}\n              component={'p'}\n              variant={'h4'}\n              marginBottom={2}\n            >\n              {t('labelWalletHistoryTitle')}\n            </Typography>\n          </Typography>\n        }\n        body={<WalletHistory operationLogList={operationLogList} />}\n      />\n      <ModalLock\n        options={openHebao.options ?? {}}\n        open={openHebao.isShow}\n        step={openHebao.step}\n        setOpenHebao={setOpenHebao}\n        handleOpenModal={handleOpenModal}\n        onClose={() => {\n          setOpenHebao({\n            isShow: false,\n            step: GuardianStep.LockAccount_WaitForAuth,\n          })\n        }}\n      />\n      <ContainerStyled marginTop={2}>\n        <Section\n          onClick={() => {\n            loadData()\n            onOpenAdd(true)\n          }}\n          title={'Set as Guardian'}\n          logo={\n            <RoundAddIcon\n              htmlColor='var(--color-text-primary)'\n              style={{\n                width: 'var(--svg-size-huge)',\n                height: 'var(--svg-size-huge)',\n              }}\n            />\n          }\n        />\n        <Section\n          description={'Who I Protect'}\n          onClick={() => {\n            loadData()\n            onOpenLockWallet(true)\n          }}\n          title={'Lock/unlock Wallet'}\n          logo={\n            <LockGuardianIcon\n              htmlColor='var(--color-text-primary)'\n              style={{\n                width: 'var(--svg-size-huge)',\n                height: 'var(--svg-size-huge)',\n              }}\n            />\n          }\n        />\n        <Section\n          description={'Guardian Request Handling'}\n          onClick={() => {\n            loadData()\n            onOpenApprovalRequests(true)\n          }}\n          title={'Approve Requests'}\n          logo={\n            <ApprovalIcon\n              htmlColor='var(--color-text-primary)'\n              style={{\n                width: 'var(--svg-size-huge)',\n                height: 'var(--svg-size-huge)',\n              }}\n            />\n          }\n        />\n        <Section\n          description={'Guardian Handling Records'}\n          onClick={() => {\n            loadData()\n            onOpenHistory(true)\n          }}\n          title={'View History'}\n          logo={\n            <ViewHistoryIcon\n              htmlColor='var(--color-text-primary)'\n              style={{\n                width: 'var(--svg-size-huge)',\n                height: 'var(--svg-size-huge)',\n              }}\n            />\n          }\n        />\n      </ContainerStyled>\n    </>\n  )\n})\n"
  },
  {
    "path": "packages/web-guardian/src/pages/WalletPage/modal/index.tsx",
    "content": "import { WithTranslation, withTranslation } from 'react-i18next'\nimport {\n  Approve_Failed,\n  Approve_Success,\n  Approve_User_Denied,\n  Approve_WaitForAuth,\n  GuardianStep,\n  LockAccount_Failed,\n  LockAccount_Success,\n  LockAccount_User_Denied,\n  LockAccount_WaitForAuth,\n  ModalWallet,\n  Reject_Failed,\n  Reject_Success,\n  Reject_User_Denied,\n  Reject_WaitForAuth,\n} from '@loopring-web/component-lib'\nimport React from 'react'\nimport { useSystem } from '@loopring-web/core'\n\nexport const ModalLock = withTranslation('common')(\n  ({\n    onClose,\n    onBack,\n    open,\n    step,\n    t,\n    options,\n    handleOpenModal,\n    setOpenHebao,\n    ...rest\n  }: {\n    open: boolean\n    step: GuardianStep\n    handleOpenModal: (props: { step: GuardianStep; options?: any }) => void\n    onBack?: () => void\n    options: any\n    setOpenHebao: (state: any) => void\n    onClose: {\n      bivarianceHack(event: {}, reason: 'backdropClick' | 'escapeKeyDown'): void\n    }['bivarianceHack']\n  } & WithTranslation) => {\n    const { etherscanBaseUrl } = useSystem()\n    const backToLockAccountBtnInfo = React.useMemo(() => {\n      return {\n        btnTxt: 'labelRetry',\n        callback: () => {\n          setOpenHebao(({ options, ...rest }) => {\n            if (options && options.lockRetry && options.lockRetryParams) {\n              options.lockRetry(options.lockRetryParams)\n            }\n            return { ...rest, step: GuardianStep.LockAccount_WaitForAuth, options }\n          })\n        },\n      }\n    }, [])\n    const backToRejectBtnInfo = React.useMemo(() => {\n      return {\n        btnTxt: 'labelRetry',\n        callback: () => {\n          setOpenHebao(({ options, ...rest }) => {\n            if (options && options.lockRetry && options.lockRetryParams) {\n              options.lockRetry(options.lockRetryParams)\n            }\n            return { ...rest, step: GuardianStep.Reject_WaitForAuth, options }\n          })\n        },\n      }\n    }, [])\n    const backToApproveBtnInfo = React.useMemo(() => {\n      return {\n        btnTxt: 'labelRetry',\n        callback: () => {\n          setOpenHebao(({ options, ...rest }) => {\n            if (options && options.lockRetry && options.lockRetryParams) {\n              options.lockRetry(options.lockRetryParams)\n            }\n            return { ...rest, step: GuardianStep.Approve_WaitForAuth, isShow: true, options }\n          })\n        },\n      }\n    }, [])\n\n    const closeBtnInfo = React.useMemo(() => {\n      return {\n        btnTxt: 'labelClose',\n        callback: (e: any) => {\n          if (onClose) {\n            onClose(e, 'escapeKeyDown')\n          }\n        },\n      }\n    }, [onClose])\n\n    const accountList = React.useMemo(() => {\n      return Object.values({\n        [GuardianStep.LockAccount_WaitForAuth]: {\n          view: (\n            <LockAccount_WaitForAuth\n              {...{\n                ...rest,\n                t,\n              }}\n            />\n          ),\n        },\n        [GuardianStep.LockAccount_User_Denied]: {\n          view: (\n            <LockAccount_User_Denied\n              btnInfo={backToLockAccountBtnInfo as any}\n              {...{\n                ...rest,\n                t,\n              }}\n            />\n          ),\n        },\n        [GuardianStep.LockAccount_Success]: {\n          view: (\n            <LockAccount_Success\n              btnInfo={closeBtnInfo}\n              {...{\n                ...rest,\n                t,\n              }}\n            />\n          ),\n        },\n        [GuardianStep.LockAccount_Failed]: {\n          view: (\n            <LockAccount_Failed\n              btnInfo={closeBtnInfo}\n              {...{\n                ...rest,\n                ...options,\n                t,\n              }}\n            />\n          ),\n        },\n        [GuardianStep.Approve_WaitForAuth]: {\n          view: (\n            <Approve_WaitForAuth\n              {...{\n                ...rest,\n                t,\n              }}\n            />\n          ),\n        },\n        [GuardianStep.Approve_User_Denied]: {\n          view: (\n            <Approve_User_Denied\n              btnInfo={backToApproveBtnInfo as any}\n              {...{\n                ...rest,\n                t,\n              }}\n            />\n          ),\n        },\n        [GuardianStep.Approve_Success]: {\n          view: (\n            <Approve_Success\n              btnInfo={closeBtnInfo}\n              {...{\n                ...rest,\n                t,\n              }}\n            />\n          ),\n        },\n        [GuardianStep.Approve_Failed]: {\n          view: (\n            <Approve_Failed\n              btnInfo={closeBtnInfo}\n              {...{\n                ...rest,\n                ...options,\n                t,\n              }}\n            />\n          ),\n        },\n\n        [GuardianStep.Reject_WaitForAuth]: {\n          view: (\n            <Reject_WaitForAuth\n              {...{\n                ...rest,\n                t,\n              }}\n            />\n          ),\n        },\n        [GuardianStep.Reject_User_Denied]: {\n          view: (\n            <Reject_User_Denied\n              btnInfo={backToRejectBtnInfo as any}\n              {...{\n                ...rest,\n                t,\n              }}\n            />\n          ),\n        },\n        [GuardianStep.Reject_Success]: {\n          view: (\n            <Reject_Success\n              btnInfo={closeBtnInfo}\n              {...{\n                ...rest,\n                t,\n              }}\n            />\n          ),\n        },\n        [GuardianStep.Reject_Failed]: {\n          view: (\n            <Reject_Failed\n              btnInfo={closeBtnInfo}\n              {...{\n                ...rest,\n                ...options,\n                t,\n              }}\n            />\n          ),\n        },\n      })\n    }, [])\n\n    return (\n      <>\n        <ModalWallet\n          open={open}\n          onClose={onClose}\n          panelList={accountList}\n          onBack={onBack}\n          step={step ?? GuardianStep.LockAccount_WaitForAuth}\n          etherscanBaseUrl={etherscanBaseUrl}\n        />\n      </>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/web-guardian/src/pages/WalletPage/utils.ts",
    "content": "import { callSwitchChain, LoopringAPI } from '@loopring-web/core'\nimport { connectProvides } from '@loopring-web/web3-provider'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { mapKeys } from 'lodash'\n\nconst keyMap = [\n  { short: 'n', long: 'network' },\n  { short: 's', long: 'sender' },\n  { short: 'a', long: 'approveHash' },\n  { short: 'tx', long: 'metaTxType' },\n  { short: 'vu', long: 'validUntil' },\n  { short: 'cv', long: 'contractVersion' },\n  { short: 'gs', long: 'guardianSign' },\n  { short: 'g', long: 'guardian' },\n  { short: 'e', long: 'extra' },\n]\nconst extraKeyMap = [\n  { short: 'g', long: 'guardianAddress' },\n  { short: 't', long: 'token' },\n  { short: 'to', long: 'to' },\n  { short: 'nm', long: 'newMasterCopy' },\n  { short: 'm', long: 'masterCopy' },\n  { short: 'c', long: 'data' },\n  { short: 'gs', long: 'newGuardians' },\n  { short: 'no', long: 'newOwner' },\n  { short: 'a', long: 'value' },\n]\n\nconst compressCallData = (hexString: String) => {\n  const hex = hexString.startsWith(\"0x\") ? hexString.slice(2) : hexString;\n  const length = hex.length;\n  var compressedData = '';\n  var zeroCount = 0;\n  for (var i = 0; i < length; i += 2) {\n      const byteStr = hex.slice(i, i + 2);\n      const byteValue = parseInt(byteStr, 16)\n      if (byteValue === 0) {\n          zeroCount++;\n      } else {\n          if (zeroCount > 0) {\n              compressedData += \"00\";\n              compressedData += zeroCount.toString(16).padStart(2, '0');;\n              zeroCount = 0;\n          }\n          compressedData += byteValue.toString(16).padStart(2, '0');\n      }\n  }\n  \n  if (zeroCount > 0) {\n      compressedData += \"00\"\n      compressedData += zeroCount.toString(16).padStart(2, '0');\n  }\n  return compressedData\n}\n\n\nfunction decompressCallData(compressedHexString: string) {\n  let decompressedData = [] as number[];\n  let length = compressedHexString.length;\n\n  for (let i = 0; i < length; i += 2) {\n      let byteStr = compressedHexString.substring(i, i + 2);\n      if (byteStr === \"00\") {\n          if (i + 2 < length) {\n              let zeroCount = parseInt(compressedHexString.substring(i + 2, i + 4), 16);\n              for (let j = 0; j < zeroCount; j++) {\n                  decompressedData.push(0);\n              }\n              i += 2;\n          }\n      } else {\n          decompressedData.push(parseInt(byteStr, 16));\n      }\n  }\n\n  let result = '';\n  for (let b of decompressedData) {\n      result += b.toString(16).padStart(2, '0');\n  }\n\n  return '0x' + result;\n}\n\nconst JSONKeyMapShortToLong = (json: any) => {\n  const mapped = mapKeys(json, (_, key) => {\n    return keyMap.find((k) => k.short === key)!.long\n  }) as any\n  return {\n    ...mapped,\n    extra: mapKeys(mapped.extra, (_, key) => {\n      return extraKeyMap.find((k) => k.short === key)!.long\n    }),\n  }\n}\n\nconst JSONKeyMapLongToShort = (json: any) => {\n  const mapped = mapKeys(json, (_, key) => {\n    return keyMap.find((k) => k.long === key)!.short\n  }) as any\n  return {\n    ...mapped,\n    e: mapKeys(mapped.e, (_, key) => {\n      return extraKeyMap.find((k) => k.long === key)!.short\n    }),\n  }\n}\n\nexport const getHash = async (args: {\n  web3: any\n  guardianAddr: string\n  senderAddr: string\n  metaTxType: number\n  networkName: sdk.NetworkWallet\n  validUntil: number\n  metaTxData: any\n  moduleAddress: string\n  isHWAddr: boolean\n}) => {\n  const {\n    web3,\n    guardianAddr,\n    senderAddr,\n    metaTxType,\n    networkName,\n    validUntil,\n    moduleAddress,\n    metaTxData,\n    isHWAddr,\n  } = args\n  \n  if (LoopringAPI.walletAPI && connectProvides.usedWeb3) {\n    const [\n      {\n        // @ts-ignore\n        raw_data: { data: contractTypes },\n      },\n      _chainId,\n    ] = await Promise.all([\n      LoopringAPI.walletAPI.getContractType({\n        wallet: senderAddr,\n        network: networkName,\n      }),\n      connectProvides.usedWeb3.eth.getChainId(),\n    ])\n\n    const contractType = contractTypes?.find((item) => item?.network.toUpperCase() === networkName)\n    const isContract1XAddress =\n      contractType && contractType.contractVersion?.startsWith('V1_') ? true : false\n    return sdk.signHebaoApproveWrap({\n      web3: web3,\n      chainId: _chainId,\n      owner: guardianAddr,\n      isHWAddr: isHWAddr,\n      type: metaTxType,\n      // newGuardians?: any\n      masterCopy: isContract1XAddress ? undefined : moduleAddress,\n      wallet: senderAddr,\n      validUntil: validUntil,\n      forwarderModuleAddress: isContract1XAddress ? moduleAddress : undefined,\n      messageData: metaTxData,\n      guardian: undefined,\n      walletVersion: isContract1XAddress ? 1 : 2,\n    })\n  }\n}\n\nexport const getSignature = async (args: {\n  web3: any\n  guardianAddr: string\n  senderAddr: string\n  metaTxType: number\n  networkName: sdk.NetworkWallet\n  validUntil: number\n  metaTxData: any\n  moduleAddress: string\n  isHWAddr: boolean\n}) => {\n  const {\n    web3,\n    guardianAddr,\n    senderAddr,\n    metaTxType,\n    networkName,\n    validUntil,\n    moduleAddress,\n    metaTxData,\n    isHWAddr,\n  } = args\n  \n  if (LoopringAPI.walletAPI && connectProvides.usedWeb3) {\n    const [\n      {\n        // @ts-ignore\n        raw_data: { data: contractTypes },\n      },\n      _chainId,\n    ] = await Promise.all([\n      LoopringAPI.walletAPI.getContractType({\n        wallet: senderAddr,\n        network: networkName,\n      }),\n      connectProvides.usedWeb3.eth.getChainId(),\n    ])\n\n    await callSwitchChain(_chainId)\n    const contractType = contractTypes?.find((item) => item?.network.toUpperCase() === networkName)\n    const isContract1XAddress =\n      contractType && contractType.contractVersion?.startsWith('V1_') ? true : false\n    return sdk.signHebaoApproveWrap({\n      web3: web3,\n      chainId: _chainId,\n      owner: guardianAddr,\n      isHWAddr: isHWAddr,\n      type: metaTxType,\n      // newGuardians?: any\n      masterCopy: isContract1XAddress ? undefined : moduleAddress,\n      wallet: senderAddr,\n      validUntil: validUntil,\n      forwarderModuleAddress: isContract1XAddress ? moduleAddress : undefined,\n      messageData: metaTxData,\n      guardian: undefined,\n      walletVersion: isContract1XAddress ? 1 : 2,\n    })\n  }\n}\n\nexport const encodeData = (data: any) => {\n  const {e,...rest} = JSONKeyMapLongToShort(data)\n  return 'MetaTxWa:' + JSON.stringify(rest)\n} \n\nexport const decodeData = (str: string) => {\n  if (str.startsWith('MetaTxWa:')) {\n    const obj = JSONKeyMapShortToLong(JSON.parse(str.slice(9)))\n    if (obj.extra.data) {\n      return {\n        ...obj,\n        extra: {\n          ...obj.extra,\n          data: decompressCallData(obj.extra.data) \n        }\n      }\n    } else {\n      return obj\n    }\n  } else {\n    return undefined\n  }\n}\n"
  },
  {
    "path": "packages/web-guardian/src/react-app-env.d.ts",
    "content": "/// <reference types=\"react-scripts\" />\n// window.__loopringEnv__ = process.env;\n"
  },
  {
    "path": "packages/web-guardian/src/reportWebVitals.ts",
    "content": "import { ReportHandler } from 'web-vitals'\n\nconst reportWebVitals = (onPerfEntry?: ReportHandler) => {\n  if (onPerfEntry && onPerfEntry instanceof Function) {\n    import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {\n      getCLS(onPerfEntry)\n      getFID(onPerfEntry)\n      getFCP(onPerfEntry)\n      getLCP(onPerfEntry)\n      getTTFB(onPerfEntry)\n    })\n  }\n}\n\nexport default reportWebVitals\n"
  },
  {
    "path": "packages/web-guardian/src/routers/index.tsx",
    "content": "import { Route, Switch, useLocation } from 'react-router-dom'\nimport React from 'react'\nimport { Box, Container } from '@mui/material'\nimport { ModalGroup, ModalGroupL1, useDeposit } from '@loopring-web/core'\nimport { LoadingPage } from '../pages/LoadingPage'\nimport { SagaStatus, setMyLog, ThemeType } from '@loopring-web/common-resources'\nimport { ErrorPage } from '../pages/ErrorPage'\nimport { useSettings } from '@loopring-web/component-lib'\nimport { Footer } from '../layouts/footer'\nimport Header from 'layouts/header'\nimport { GuardianPage } from '../pages/WalletPage'\n\nexport const useWrapModal = () => {\n  const { search } = useLocation()\n  const searchParams = new URLSearchParams(search)\n  const token = searchParams.get('token')\n  const l2account = searchParams.get('l2account') || searchParams.get('owner')\n  const { depositProps } = useDeposit(true, { token, owner: l2account })\n  return {\n    depositProps,\n    view: <ModalGroupL1 assetsRawData={[]} depositProps={depositProps} />,\n  }\n}\nconst RouterView = ({ state }: { state: SagaStatus }) => {\n  const location = useLocation()\n  const { setTheme } = useSettings()\n  const { view: modalView } = useWrapModal()\n  const query = new URLSearchParams(location.search)\n  const searchParams = new URLSearchParams(location.search)\n  React.useEffect(() => {\n    if (query.has('theme')) {\n      query.get('theme') === ThemeType.dark ? setTheme('dark') : setTheme('light')\n    }\n  }, [location.search])\n\n  React.useEffect(() => {\n    if (state === SagaStatus.ERROR) {\n      window.location.replace(`${window.location.origin}/error`)\n    }\n  }, [state])\n  if (query.has('___OhTrustDebugger___')) {\n    // @ts-ignore\n    setMyLog(true)\n  }\n  return (\n    <>\n      <Switch>\n        <Route exact path='/loading'>\n          <LoadingPage />\n        </Route>\n        <Route path={['/', '/*']}>\n          {searchParams && searchParams.has('noheader') ? <></> : <Header />}\n          <Container\n            maxWidth='lg'\n            style={{\n              display: 'flex',\n              flexDirection: 'column',\n              flex: 1,\n            }}\n          >\n            <Box\n              display={'flex'}\n              flex={1}\n              alignItems={'stretch'}\n              flexDirection={'row'}\n              justifyContent={'center'}\n              marginTop={3}\n            >\n              <GuardianPage />\n            </Box>\n          </Container>\n        </Route>\n        <Route\n          component={() => (\n            <>\n              <ErrorPage messageKey={'error404'} />\n            </>\n          )}\n        />\n      </Switch>\n      {modalView}\n      {query && query.has('nofooter') ? <></> : <Footer />}\n    </>\n  )\n}\n\nexport default RouterView\n"
  },
  {
    "path": "packages/web-guardian/src/setupTests.ts",
    "content": "// jest-dom adds custom jest matchers for asserting on DOM nodes.\n// allows you to do things like:\n// expect(element).toHaveTextContent(/react/i)\n// learn more: https://github.com/testing-library/jest-dom\nimport '@testing-library/jest-dom'\n"
  },
  {
    "path": "packages/web-guardian/src/types.d.ts",
    "content": "import { RampInstantSDK } from '@ramp-network/ramp-instant-sdk'\nimport { LoopringSocket } from '@loopring-web/core'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\ndeclare module '*.html' {\n  const value: string\n  export default value\n}\n\ndeclare global {\n  interface Window {\n    loopringSocket: InstanceType<LoopringSocket>\n    __renderReportCall__: () => void\n    rampInstance: RampInstantSDK | undefined\n  }\n\n  namespace JSX {\n    interface IntrinsicElements {\n      'model-viewer': MyElementAttributes\n    }\n\n    interface MyElementAttributes {\n      src: string\n      'auto-rotate': any\n      'camera-controls': any\n      'ar-modes': any\n      'touch-action': any\n      'shadow-intensity': any\n      poster?: string\n\n      [key: string]: any\n    }\n  }\n\n  type ChainId = ChainIdExtends | sdk.ChainId\n\n  namespace JSX {\n    interface IntrinsicElements {\n      'model-viewer': MyElementAttributes\n    }\n\n    interface MyElementAttributes {\n      src: string\n      'auto-rotate': any\n      'camera-controls': any\n      'ar-modes': any\n      'touch-action': any\n      'shadow-intensity': any\n      poster?: string\n\n      [key: string]: any\n    }\n  }\n}\n"
  },
  {
    "path": "packages/web-guardian/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.build.json\",\n  \"compilerOptions\": {\n    \"baseUrl\": \"src/\",\n    \"rootDir\": \".\"\n  },\n  \"include\": [\n    \"src\",\n    \"src/*\",\n    \"src/**/*.json\"\n  ]\n}\n"
  },
  {
    "path": "packages/web-wallet/public/badge.xml",
    "content": "<FrameLayout xmlns:android=\"https://download.loopring.io/LoopringWallet.apk\"\n             xmlns:app=\"https://download.loopring.io/\"\n             android:layout_width=\"match_parent\"\n             android:layout_height=\"match_parent\">\n\n    <TextView\n            android:id=\"@+id/notifications.badge\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"top|center_horizontal\"\n            android:layout_marginLeft=\"10dp\"\n            android:layout_marginStart=\"10dp\"\n            android:background=\"@drawable/notification_badge\"\n            android:gravity=\"center\"\n            android:padding=\"3dp\"\n            android:text=\"9+\"\n            android:textColor=\"@color/white\"\n            android:textSize=\"11sp\"/>\n</FrameLayout>"
  },
  {
    "path": "packages/web-wallet/public/browserconfig.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<browserconfig>\n    <msapplication>\n        <tile>\n            <!--            <square70x70logo src=\"small.png\"/>-->\n            <!--            <square150x150logo src=\"medium.png\"/>-->\n            <!--            <wide310x150logo src=\"wide.png\"/>-->\n            <!--            <square310x310logo src=\"large.png\"/>-->\n            <square129x129logo src=\"loopring129.png\"/>\n            <TileColor>#3B5AF4</TileColor>\n        </tile>\n        <badge>\n            <polling-uri src=\"badge.xml\"/>\n            <frequency>30</frequency>\n        </badge>\n        <!--        <notification>-->\n        <!--            <polling-uri  src=\"1.xml\"/>-->\n        <!--            <polling-uri2 src=\"2.xml\"/>-->\n        <!--            <polling-uri3 src=\"3.xml\"/>-->\n        <!--            <polling-uri4 src=\"4.xml\"/>-->\n        <!--            <polling-uri5 src=\"5.xml\"/>-->\n        <!--            <frequency>30</frequency>-->\n        <!--            <cycle>1</cycle>-->\n        <!--        </notification>-->\n    </msapplication>\n</browserconfig>"
  },
  {
    "path": "packages/web-wallet/public/electron.js",
    "content": "const path = require('path')\n\nconst { app, BrowserWindow } = require('electron')\nconst isDev = require('electron-is-dev')\n\nconsole.log('BROWSER:', process.env.BROWSER)\nconsole.log('NODE_ENV:', process.env.NODE_ENV)\n\nfunction createWindow() {\n  // Create the browser window.\n  const win = new BrowserWindow({\n    width: 1024,\n    height: 768,\n    frame: true,\n    webPreferences: {\n      nodeIntegration: true,\n    },\n  })\n\n  // and load the index.html of the app.\n  // win.loadFile(\"index.html\");\n  win.loadURL(\n    isDev ? 'http://localhost:3000' : `file://${path.join(__dirname, '../build/index.html')}`,\n  )\n\n  // Open the DevTools.\n  if (isDev) {\n    win.webContents.openDevTools({ mode: 'detach' })\n  }\n}\n\n// This method will be called when Electron has finished\n// initialization and is ready to create browser windows.\n// Some APIs can only be used after this event occurs.\napp.whenReady().then(createWindow)\n\n// Quit when all windows are closed, except on macOS. There, it's common\n// for applications and their menu bar to stay active until the user quits\n// explicitly with Cmd + Q.\napp.on('window-all-closed', () => {\n  if (process.platform !== 'darwin') {\n    app.quit()\n  }\n})\n\napp.on('activate', () => {\n  // On macOS it's common to re-create a window in the app when the\n  // dock icon is clicked and there are no other windows open.\n  if (BrowserWindow.getAllWindows().length === 0) {\n    createWindow()\n  }\n})\n"
  },
  {
    "path": "packages/web-wallet/public/footer.jsx",
    "content": "import { FOOTER_LIST_MAP, MEDIA_LIST } from '@loopring-web/common-resources'\n\nconst linkListMap = FOOTER_LIST_MAP\nconst mediaList = MEDIA_LIST\nexport const Footer = () => {\n  return (\n    <div className='footerContent'>\n      <div className='wrap Container-maxWidthLg'>\n        <div className='Box-root content'>\n          <div className='Box-root' id='logSvg'></div>\n\n          {\n            // @ts-ignore\n            Reflect.ownKeys(linkListMap).map((key) => {\n              return (\n                <section className='Box-root group'>\n                  <h6\n                    aria-label={key}\n                    className='Typography-root Typography-body2'\n                    id={`label${key.charAt(0).toUpperCase() + key.slice(1)}`}\n                  ></h6>\n                  <ul className='Ul-root'>\n                    {linkListMap[key.toString()].map((item) => {\n                      return (\n                        <li>\n                          <a\n                            aria-label={item.linkName}\n                            className={`Typography-root Typography-inherit ${item.linkName} Link-underlineAlways`}\n                            href={item.linkHref}\n                            id={`label${item.charAt(0).toUpperCase() + item.slice(1)}`}\n                            rel='noopener noreferrer'\n                            target='_blank'\n                          >\n                            {item.linkName}\n                          </a>\n                        </li>\n                      )\n                    })}\n                  </ul>\n                </section>\n              )\n            })\n          }\n        </div>\n\n        <section className='Box-root group groupIcon'>\n          <h6\n            aria-label='Follow us'\n            className='Typography-root Typography-body2'\n            id='labelFollowus'\n          >\n            Follow us\n          </h6>\n          <div className='Box-root footerContentList'>\n            <ul\n              className='List-root List-padding'\n              style={{ display: 'flex', alignItems: 'flex-start', paddingTop: 0, paddingBottom: 0 }}\n            >\n              {mediaList.map((o, index) => (\n                <li className='List-root Typography-body1'>\n                  <a\n                    className='Typography-root Typography-inherit Link-root Link-underlineAlways icon'\n                    id={`${o.linkName}Icon`}\n                    href={o.linkHref}\n                    rel='noopener noreferrer'\n                    target='_blank'\n                  >\n                    {o.linkName}\n                  </a>\n                </li>\n              ))}\n            </ul>\n          </div>\n        </section>\n      </div>\n      <p\n        aria-label='@2017 Loopring Technology Limited. All rights reserved.'\n        className='Typography-root Typography-body1'\n        id='labelCopyRight'\n      ></p>\n    </div>\n  )\n}\n"
  },
  {
    "path": "packages/web-wallet/public/index.html",
    "content": "<html lang=\"en\" xmlns=\"http://www.w3.org/1999/html\">\n<head>\n\t<meta charset=\"utf-8\">\n\t<link href=\"/favicon.ico\" rel=\"icon\">\n\t<link rel=\"mask-icon\" href=\"/loopring.svg\" color=\"#3B5AF4\">\n\t<link rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/favicon-16x16.png\">\n\t<link rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/favicon-32x32.png\">\n\t<link rel=\"icon\" type=\"image/png\" sizes=\"48x48\" href=\"/favicon-48x48.png\">\n\t<link rel=\"apple-touch-icon\" href=\"/apple-touch-icon.png\" sizes=\"129x129\">\n\t<meta content=\"Ethereum zkRollup Exchange and Payment Protocol\" name=\"description\">\n\t<meta content=\"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0\" name=\"viewport\">\n\t<meta content=\"#000000\" name=\"theme-color\">\n\t<meta content=\"Loopring Layer 2, Ethereum zkRollup Exchange and Payment Protocol\" name=\"description\">\n\t<link href=\"https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&amp;display=swap\" rel=\"stylesheet\">\n\t<link href=\"/manifest.json\" rel=\"manifest\">\n\t<meta content=\"summary_large_image\" name=\"twitter:card\">\n\t<meta content=\"Loopring Wallet\" name=\"twitter:title\">\n\t<meta content=\"Your gateway to Ethereum, DeFi, and NFTs\" name=\"twitter:description\">\n\t<meta content=\"https://static.loopring.io/assets/images/giftReward.png\" name=\"twitter:image\">\n\t<link id=\"themeModeCss\" rel=\"stylesheet\" type=\"text/css\"/>\n\t<link href=\"./wallet.css\" rel=\"stylesheet\" type=\"text/css\"/>\n\t<script src=\"https://unpkg.com/i18next-browser-languagedetector/i18nextBrowserLanguageDetector.min.js\"\n\t\t\t\t\ttype=\"application/javascript\"></script>\n\t<script src=\"https://unpkg.com/i18next@22.5.0/dist/umd/i18next.min.js\" type=\"application/javascript\"/>\n\t</script>\n\t<script src=\"./wallet.js\" type=\"application/javascript\"></script>\n\t<title>Loopring</title>\n\t<style>\n\t\t@media (max-width: 768px) {\n\t\t\t.wallet-discontinue-banner {\n\t\t\t\tbackground-image: url('https://static.loopring.io/assets/images/wallet_discontinue_mobile.png') !important;\n\t\t\t\theight: 160px !important;\n\t\t\t}\n\t\t}\n\t</style>\n</head>\n<body ondragstart=\"return false;\" ondrop=\"return false;\" draggable=\"false\" onmousedown=\"return false\">\n<div style=\"z-index: 2\">\n\t<header>\n\t\t<div class=\"headerGg\">\n\t\t\t<div class=\"Toolbar-root wrap\" style=\"padding: 0px 8px;\">\n\t\t\t\t<nav>\n\t\t\t\t\t<h1 class='Typography-root Typography-h6'>\n\t\t\t\t\t\t<a aria-label='menu' id='logo' class='ButtonBase-root'\n\t\t\t\t\t\t\t href='https://loopring.io/#/' tabindex='0'>Loopring\n\t\t\t\t\t\t\t路印\n\t\t\t\t\t\t\tloopring protocol\n\t\t\t\t\t\t\t3.6\n\t\t\t\t\t\t\tThe first Layer2 Decentralized trading Platform</a>\n\t\t\t\t\t</h1>\n\t\t\t\t\t<ul class=\"Ul-root\">\n\t\t\t\t\t\t<li class=\"MenuItem-root MenuItem-gutters ButtonBase-root layer-0\" role=\"menuitem\" tabindex=\"-1\">\n\t\t\t\t\t\t\t<a class=\"Typography-root Typography-body1\" target=\"_parent\" href=\"https://loopring.io/#/\"\n\t\t\t\t\t\t\t\t id=\"labelNavZkRollupLayer2\"></a>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t\t<li class=\"MenuItem-root MenuItem-gutters ButtonBase-root layer-0\" role=\"menuitem\" tabindex=\"-1\">\n\t\t\t\t\t\t\t<a class='Typography-root Typography-body1 selected' href='https://guardian.loopring.io'\n\t\t\t\t\t\t\t\t id='labelNavWallet'>\n\t\t\t\t\t\t\t\t<!--\t\t\t\t\t\t\t<script type=\"application/javascript\">t(window.i18n.labelNavWallet) </script>-->\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t</ul>\n\t\t\t\t</nav>\n\t\t\t\t<div class=\"Box-root flexBox flex-row\">\n\n\t\t\t\t\t<button id=\"changeColor\" class=\"Button-root\" onClick=\"onGlobalChange()\"></button>\n\n\t\t\t\t\t<a\n\t\t\t\t\t\tclass='Button-root Button-contained Button-containedPrimary Button-sizeSmall Button-containedSizeSmall ButtonBase-root'\n\t\t\t\t\t\tid='labelNavLanuch'\n\t\t\t\t\t\tonclick=\"window.open('https://loopring.io/#/','_parent')\"\n\t\t\t\t\t\thref='https://loopring.io/#/'\n\t\t\t\t\t\ttype='button'></a>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t</div>\n\t\t<div\n\t\t\t\t\t\tclass=\"Box-root \">\n\n\t\t\t\t\t\t<div class=\"wallet-discontinue-banner\" style=\"height: 110px; width: 100%; background-image: url('https://static.loopring.io/assets/images/wallet_discontinue.png');background-size: cover;background-position: center;\" ></div>\n\t\t\t\t\t\t<section class=\"wrap flex-column flexBox align-center\">\n\t\t\t\t<p aria-label=\"Ethereum Unleashed\" class=\"Typography-root Typography-body1 title\" id=\"labelEthereumUnleashed\"/>\n\t\t\t\t<p aria-label=\"Your Gateway to Ethereum, DeFi, NFTs, and Financial Freedom\"\n\t\t\t\t\t class=\"Typography-root Typography-body1 subtitle\" id=\"labelGatewayToEthereum\"/>\n\t\t\t\t<div class=\"Box-root buttons downLoadBtnGroup\">\n\t\t\t\t\t<button class=\"ios gradient-border\"\n\t\t\t\t\t\t\t\t\thref=\"https://apps.apple.com/us/app/loopring-smart-wallet/id1550921126\"\n\t\t\t\t\t\t\t\t\tonClick=\"window.open('https://apps.apple.com/us/app/loopring-smart-wallet/id1550921126','_parent');\"\n\t\t\t\t\t\t\t\t\trel=\"noopener\"\n\t\t\t\t\t\t\t\t\ttarget=\"_blank\">\n\t\t\t\t\t\t<div id=\"iconIos\"></div>\n\t\t\t\t\t\t<!--\t\t\t\t\t<img alt=\"download-btn\" height=\"18\"-->\n\t\t\t\t\t\t<!--\t\t\t\t\t\t\t src=\"https://static.loopring.io/assets/images/landPage/wallet_ios.svg\" width=\"18\">-->\n\t\t\t\t\t\t<span aria-label=\"IOS\" class=\"Typography-root Typography-body1\" id=\"labelIOS\"></span>\n\t\t\t\t\t</button>\n\t\t\t\t\t<button class=\"android gradient-border\"\n\t\t\t\t\t\t\t\t\thref=\"https://download.loopring.io/LoopringWallet.apk\"\n\t\t\t\t\t\t\t\t\tonClick=\"window.open('https://download.loopring.io/LoopringWallet.apk','_parent');\"\n\t\t\t\t\t\t\t\t\trel=\"noopener\" target=\"_blank\">\n\t\t\t\t\t\t<div id=\"iconAndroid\"></div>\n\t\t\t\t\t\t<span aria-label=\"Android\" class=\"Typography-root Typography-body1\" id=\"labelAndroid\"></span>\n\t\t\t\t\t</button>\n\t\t\t\t\t<button class=\"google-play gradient-border\"\n\t\t\t\t\t\t\t\t\thref=\"https://play.google.com/store/apps/details?id=loopring.defi.wallet\"\n\t\t\t\t\t\t\t\t\tonClick=\"window.open('https://play.google.com/store/apps/details?id=loopring.defi.wallet','_parent');\"\n\t\t\t\t\t\t\t\t\trel=\"noopener\" target=\"_blank\">\n\t\t\t\t\t\t<div id=\"iconGooglePlay\"></div>\n\t\t\t\t\t\t<span aria-label=\"Google Play\" class=\"Typography-root Typography-body1\" id=\"labelGooglePlay\"></span>\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\n\t\t\t\t<section class=\"carousel-container\">\n\t\t\t\t\t<div id=\"slider\">\n\t\t\t\t\t\t<div class=\"container\" id=\"carousel\">\n\t\t\t\t\t\t\t<input type=\"radio\" name=\"slider\" class=\"select\" id=\"item-1\" checked/>\n\t\t\t\t\t\t\t<input type=\"radio\" name=\"slider\" class=\"select\" id=\"item-2\"/>\n\t\t\t\t\t\t\t<input type=\"radio\" name=\"slider\" class=\"select\" id=\"item-3\"/>\n\t\t\t\t\t\t\t<!--\t\t\t\t\t\t\t<input type=\"radio\" name=\"slider\" id=\"item-4\"/>-->\n\t\t\t\t\t\t\t<!--\t\t\t\t\t\t\t<input type=\"radio\" name=\"slider\" id=\"item-5\"/>-->\n\t\t\t\t\t\t\t<!--\t\t\t\t\t\t\t<input type=\"radio\" name=\"slider\" id=\"item-6\"/>-->\n\t\t\t\t\t\t\t<!--\t\t\t\t\t\t\t<input type=\"radio\" name=\"slider\" id=\"item-7\"/>-->\n\n\t\t\t\t\t\t\t<div class=\"cards\">\n\t\t\t\t\t\t\t\t<label class=\"card\" for=\"item-1\" id=\"selector-1\">\n\t\t\t\t\t\t\t\t\t<img alt=\"Earn Investment Uer Interface\"\n\t\t\t\t\t\t\t\t\t\t\t src=\"https://static.loopring.io/assets/images/landPage/wallet_banner1.png\" id=\"imageChang1\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t</label>\n\t\t\t\t\t\t\t\t<label class=\"card\" for=\"item-2\" id=\"selector-2\">\n\t\t\t\t\t\t\t\t\t<img alt=\"Assets & market\"\n\t\t\t\t\t\t\t\t\t\t\t src=\"https://static.loopring.io/assets/images/landPage/wallet_banner2.png\"\n\t\t\t\t\t\t\t\t\t\t\t id=\"imageChang2\"\n\t\t\t\t\t\t\t\t\t></label>\n\t\t\t\t\t\t\t\t<label class=\"card\" for=\"item-3\" id=\"selector-3\">\n\t\t\t\t\t\t\t\t\t<img alt=\"Loopring L2 orderbook\"\n\t\t\t\t\t\t\t\t\t\t\t src=\"https://static.loopring.io/assets/images/landPage/wallet_banner3.png\"\n\t\t\t\t\t\t\t\t\t\t\t id=\"imageChang3\"\n\t\t\t\t\t\t\t\t\t></label>\n\t\t\t\t\t\t\t\t<!--\t\t\t\t\t\t\t\t<label class=\"card\" for=\"item-4\" id=\"selector-4\">-->\n\t\t\t\t\t\t\t\t<!--\t\t\t\t\t\t\t\t\t<img alt=\"Loopring L2 orderbook\"-->\n\t\t\t\t\t\t\t\t<!--\t\t\t\t\t\t\t\t\t\t\t src=\"https://static.loopring.io/assets/images/landPage/wallet_banner4.png\"-->\n\t\t\t\t\t\t\t\t<!--\t\t\t\t\t\t\t\t\t\t\t id=\"imageChang4\"-->\n\t\t\t\t\t\t\t\t<!--\t\t\t\t\t\t\t\t\t\t\t style=\"width: 224px; object-fit: contain; border-radius: 32px;\">-->\n\t\t\t\t\t\t\t\t<!--\t\t\t\t\t\t\t\t</label>-->\n\t\t\t\t\t\t\t\t<!--\t\t\t\t\t\t\t\t\t<label class=\"card\" for=\"item-5\" id=\"selector-5\"><img src=\"assets/2 7.png\" alt=\"\"></label>-->\n\t\t\t\t\t\t\t\t<!--\t\t\t\t\t\t\t\t\t<label class=\"card\" for=\"item-6\" id=\"selector-6\"><img src=\"assets/2 8.png\" alt=\"\"></label>-->\n\t\t\t\t\t\t\t\t<!--\t\t\t\t\t\t\t\t\t<label class=\"card\" for=\"item-7\" id=\"selector-7\"><img src=\"assets/2 9.png\" alt=\"\"></label>-->\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t\t<!--\t\t\t\t\t<div class=\"carousel-item first\"-->\n\t\t\t\t\t<!--\t\t\t\t\t\t\t style=\"width: 224px; margin-left: 0%; margin-right: 4%; transition: all 1s ease-in-out 0s; transform: scale(1); cursor: pointer; display: flex; align-items: center;\">-->\n\t\t\t\t\t<!--\t\t\t\t\t\t<img alt=\"Earn Investment Uer Interface\"-->\n\t\t\t\t\t<!--\t\t\t\t\t\t\t\t src=\"https://static.loopring.io/assets/images/landPage/wallet_banner1.png\" id=\"imageChang1\"-->\n\t\t\t\t\t<!--\t\t\t\t\t\t\t\t style=\"width: 224px; object-fit: contain; border-radius: 32px;\">-->\n\t\t\t\t\t<!--\t\t\t\t\t</div>-->\n\t\t\t\t\t<!--\t\t\t\t\t<div class=\"carousel-item\"-->\n\t\t\t\t\t<!--\t\t\t\t\t\t\t style=\"width: 224px; margin-left: 4%; margin-right: 4%; transition: all 1s ease-in-out 0s; transform: scale(1.3); cursor: pointer; display: flex; align-items: center;\">-->\n\t\t\t\t\t<!--\t\t\t\t\t\t<img alt=\"Assets & market\" src=\"https://static.loopring.io/assets/images/landPage/wallet_banner2.png\"-->\n\t\t\t\t\t<!--\t\t\t\t\t\t\t\t id=\"imageChang2\"-->\n\t\t\t\t\t<!--\t\t\t\t\t\t\t\t style=\"width: 224px; object-fit: contain; border-radius: 32px;\">-->\n\t\t\t\t\t<!--\t\t\t\t\t</div>-->\n\t\t\t\t\t<!--\t\t\t\t\t<div class=\"carousel-item\"-->\n\t\t\t\t\t<!--\t\t\t\t\t\t\t style=\"width: 224px; margin-left: 4%; margin-right: 4%; transition: all 1s ease-in-out 0s; transform: scale(1); cursor: pointer; display: flex; align-items: center;\">-->\n\t\t\t\t\t<!--\t\t\t\t\t\t<img alt=\"Loopring L2 orderbook\" src=\"https://static.loopring.io/assets/images/landPage/wallet_banner3.png\"-->\n\t\t\t\t\t<!--\t\t\t\t\t\t\t\t id=\"imageChang3\"-->\n\t\t\t\t\t<!--\t\t\t\t\t\t\t\t style=\"width: 224px; object-fit: contain; border-radius: 32px;\">-->\n\t\t\t\t\t<!--\t\t\t\t\t</div>-->\n\t\t\t\t</section>\n\t\t\t</section>\n\t\t</div>\n\t</header>\n\t<section class=\"Box-root\" style=\"flex: 1\">\n\t\t<div class=\"Box-root\">\n\t\t\t<div class=\"Box-root sectionFull \">\n\t\t\t\t<section class=\"wrap flex-row flexBox\">\n\t\t\t\t\t<div class=\"Box-root sectionDetail\">\n\t\t\t\t\t\t<h3 aria-label=\"Fast, Secure, and 100x Lower Fees\" class=\"Typography-root Typography-h1\"\n\t\t\t\t\t\t\t\tid=\"labelFeature1\">\n\t\t\t\t\t\t\tFast, Secure, and 100x Lower Fees\n\t\t\t\t\t\t</h3>\n\t\t\t\t\t\t<p aria-label=\"Experience DeFi as it should be - fast and affordable. Built with zkRollups, Loopring provides instant transactions at 100x lower fees than Ethereum without sacrificing any of its security.\"\n\t\t\t\t\t\t\t class=\"Typography-root Typography-body1\" id=\"labelFeatureDes1\">\n\t\t\t\t\t\t\tExperience DeFi as it should be - fast and affordable. Built with zkRollups, Loopring provides instant\n\t\t\t\t\t\t\ttransactions at 100x lower fees than Ethereum without sacrificing any of its security.\n\t\t\t\t\t\t</p>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"Box-root img-container img-container-odd\">\n\t\t\t\t\t\t<img alt=\"Scroll-up Image\" class=\"scroll-up-img\"\n\t\t\t\t\t\t\t\t src=\"https://static.loopring.io/assets/images/landPage/wallet_section1.png\" id=\"imageSection1\"\n\t\t\t\t\t\t\t\t style=\"opacity: 0; transform: translateY(100%); transition: opacity 1s ease 0s, transform 1s ease 0s; width: 80%;\">\n\t\t\t\t\t</div>\n\t\t\t\t</section>\n\t\t\t</div>\n\t\t\t<div class=\"Box-root sectionFull \">\n\t\t\t\t<section class=\"wrap flex-row flexBox\">\n\t\t\t\t\t<div class=\"Box-root sectionDetail\">\n\t\t\t\t\t\t<h3 aria-label=\"Invest, Stake, and Earn\" class=\"Typography-root Typography-h1\" id=\"labelFeature2\"></h3>\n\t\t\t\t\t\t<p aria-label=\"Easily earn yield on your \\n crypto. Your funds never leave your wallet and can be accessed at any time.\"\n\t\t\t\t\t\t\t class=\"Typography-root Typography-body1\" id=\"labelFeatureDes2\"/>\n\t\t\t\t\t\tEasily earn yield on your crypto. Your funds never leave your wallet and can be accessed at any time.\n\t\t\t\t\t\t</p>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"Box-root img-container img-container-even\">\n\t\t\t\t\t\t<img alt=\"Scroll-up Image\" class=\"scroll-up-img\"\n\t\t\t\t\t\t\t\t src=\"https://static.loopring.io/assets/images/landPage/wallet_section2.png\" id=\"imageSection2\"\n\t\t\t\t\t\t\t\t style=\"opacity: 0; transform: translateY(100%); transition: opacity 1s ease 0s, transform 1s ease 0s; width: 80%;\">\n\t\t\t\t\t</div>\n\t\t\t\t</section>\n\t\t\t</div>\n\t\t\t<div style=\"display:none;\" class=\"Box-root sectionFull \">\n\t\t\t\t<section class=\"wrap flex-row flexBox\">\n\t\t\t\t\t<div class=\"Box-root sectionDetail\">\n\t\t\t\t\t\t<h3 Id=\"labelFeature3\" aria-label=\"Dual Investment\" class=\"Typography-root Typography-h1\"></h3>\n\t\t\t\t\t\t<p aria-label=\"Buy Low or Sell High. Get rewarded no matter which direction the market moves.\"\n\t\t\t\t\t\t\t class=\"Typography-root Typography-body1\" id=\"labelFeatureDes3\"></p>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"Box-root img-container img-container-odd\">\n\t\t\t\t\t\t<img alt=\"Scroll-up Image\" class=\"scroll-up-img\"\n\t\t\t\t\t\t\t\t src=\"https://static.loopring.io/assets/images/landPage/wallet_section3.png\" id=\"imageSection3\"\n\t\t\t\t\t\t\t\t style=\"opacity: 0; transform: translateY(100%); transition: opacity 1s ease 0s, transform 1s ease 0s; width: 80%;\">\n\t\t\t\t\t</div>\n\t\t\t\t</section>\n\t\t\t</div>\n\t\t\t<div class=\"Box-root sectionFull \">\n\t\t\t\t<section class=\"wrap flex-row flexBox\">\n\t\t\t\t\t<div class=\"Box-root sectionDetail\">\n\t\t\t\t\t\t<h3 Id=\"labelFeature4\" aria-label=\"Buy Crypto on L2\" class=\"Typography-root Typography-h1\">Buy Crypto on\n\t\t\t\t\t\t\tL2</h3>\n\t\t\t\t\t\t<p aria-label=\"Use card, bank transfer, or Apple Pay without ever having to leave your wallet.\"\n\t\t\t\t\t\t\t class=\"Typography-root Typography-body1\" id=\"labelFeatureDes4\">\n\t\t\t\t\t\t\tUse card, bank transfer, or Apple Pay without ever having to leave your wallet.\n\t\t\t\t\t\t</p>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"Box-root img-container img-container-even\">\n\t\t\t\t\t\t<img alt=\"Scroll-up Image\" class=\"scroll-up-img\"\n\t\t\t\t\t\t\t\t src=\"https://static.loopring.io/assets/images/landPage/wallet_section4.png\" id=\"imageSection4\"\n\t\t\t\t\t\t\t\t style=\"opacity: 0; transform: translateY(100%); transition: opacity 1s ease 0s, transform 1s ease 0s; width: 80%;\">\n\t\t\t\t\t</div>\n\t\t\t\t</section>\n\t\t\t</div>\n\t\t\t<div class=\"Box-root sectionFull \">\n\t\t\t\t<section class=\"wrap flex-row flexBox\">\n\t\t\t\t\t<div class=\"Box-root sectionDetail\">\n\t\t\t\t\t\t<h3 Id=\"labelFeature5\" aria-label=\"Your Personal Vault\" class=\"Typography-root Typography-h1\"></h3>\n\t\t\t\t\t\t<p aria-label=\"Forget seed phrases. Choose people, institutions, and hardware you trust to be your Guardians. Set limits on daily transfers or even lock your wallet if needed. You’re always in control.\"\n\t\t\t\t\t\t\t class=\"Typography-root Typography-body1\" id=\"labelFeatureDes5\">\n\t\t\t\t\t\t\tForget seed phrases. Choose people, institutions, and hardware you trust to be your Guardians. Set limits\n\t\t\t\t\t\t\ton daily transfers or even lock your wallet if needed. You’re always in control.\n\t\t\t\t\t\t</p>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"Box-root img-container img-container-odd\">\n\t\t\t\t\t\t<img alt=\"Scroll-up Image\" class=\"scroll-up-img\"\n\t\t\t\t\t\t\t\t src=\"https://static.loopring.io/assets/images/landPage/wallet_section5.png\" id=\"imageSection5\"\n\t\t\t\t\t\t\t\t style=\"opacity: 0; transform: translateY(100%); transition: opacity 1s ease 0s, transform 1s ease 0s; width: 80%;\">\n\t\t\t\t\t</div>\n\t\t\t\t</section>\n\t\t\t</div>\n\t\t\t<div class=\"Box-root sectionFull \">\n\t\t\t\t<section class=\"wrap flex-row flexBox\">\n\t\t\t\t\t<div class=\"Box-root sectionDetail\">\n\t\t\t\t\t\t<h3 Id=\"labelFeature6\" aria-label=\"Manage and Display Your NFT\n\t\t\t\t\t\t\t\t\t\tCollection\" class=\"Typography-root Typography-h1\"></h3>\n\t\t\t\t\t\t<p aria-label=\"Immerse yourself in the\n\t\t\t\t\t\t\t\t\t\tworld of unique digital assets. Safeguard your growing collection, all while enjoying easy access to\n\t\t\t\t\t\t\t\t\t\tyour favorite marketplaces.\" class=\"Typography-root Typography-body1\" id=\"labelFeatureDes6\">\n\t\t\t\t\t\t\tImmerse yourself in the\n\t\t\t\t\t\t\tworld of unique digital assets. Safeguard your growing collection, all while enjoying easy access to\n\t\t\t\t\t\t\tyour favorite marketplaces.\n\t\t\t\t\t\t</p>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"Box-root img-container img-container-even\">\n\t\t\t\t\t\t<img alt=\"Scroll-up Image\" class=\"scroll-up-img\"\n\t\t\t\t\t\t\t\t src=\"https://static.loopring.io/assets/images/landPage/wallet_section6.png\" id=\"imageSection6\"\n\t\t\t\t\t\t\t\t style=\"opacity: 0; transform: translateY(100%); transition: opacity 1s ease 0s, transform 1s ease 0s; width: 80%;\">\n\t\t\t\t\t</div>\n\t\t\t\t</section>\n\t\t\t</div>\n\t\t\t<div class=\"Box-root sectionFull \">\n\t\t\t\t<section class=\"wrap flex-row flexBox\">\n\t\t\t\t\t<div class=\"Box-root sectionDetail\">\n\t\t\t\t\t\t<h3 Id=\"labelFeature7\" aria-label=\"Digital Red Packets\" class=\"Typography-root Typography-h1\"></h3>\n\t\t\t\t\t\t<p aria-label=\"Create memorable\n\t\t\t\t\t\t\t\t\t\texperiences for friends, family, and your community. Red Packets are perfect for gifts, social events,\n\t\t\t\t\t\t\t\t\t\tgaming rewards, airdrops, and more!\" class=\"Typography-root Typography-body1\"\n\t\t\t\t\t\t\t id=\"labelFeatureDes7\">\n\t\t\t\t\t\t\tCreate memorable\n\t\t\t\t\t\t\texperiences for friends, family, and your community. Red Packets are perfect for gifts, social events,\n\t\t\t\t\t\t\tgaming rewards, airdrops, and more!\n\t\t\t\t\t\t</p>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"Box-root img-container img-container-odd\">\n\t\t\t\t\t\t<img alt=\"Scroll-up Image\" class=\"scroll-up-img\"\n\t\t\t\t\t\t\t\t src=\"https://static.loopring.io/assets/images/landPage/wallet_section7.png\" id=\"imageSection7\"\n\t\t\t\t\t\t\t\t style=\"opacity: 0; transform: translateY(100%); transition: opacity 1s ease 0s, transform 1s ease 0s; width: 80%;\">\n\t\t\t\t\t</div>\n\t\t\t\t</section>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n\t<footer class=\"Box-root\">\n\t\t<div class=\"footerWallet\">\n\t\t\t<div class=\"wrap flexBox center \">\n\t\t\t\t<div class=\"Box-root\" style=\"display: flex; align-items: center\">\n\t\t\t\t\t<img height=\"48\" src=\"https://static.loopring.io/assets/images/landPage/wallet_appicon.png\"\n\t\t\t\t\t\t\t style=\"object-fit: fill;\" width=\"48\">\n\t\t\t\t\t<div class=\"Box-root logoDex\" style=\"margin-left: 20px; height: 48px\">\n\t\t\t\t\t\t<p aria-label=\"Loopring Wallet\" class=\"Typography-root Typography-body1\" id=\"labelFeatureDes8\"></p>\n\t\t\t\t\t\t<p aria-label=\"Crypto exchange on the go\" class=\"Typography-root Typography-body1\"\n\t\t\t\t\t\t\t id=\"labelFeatureDes8_2\"></p>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"Box-root buttons downLoadBtnGroup\">\n\t\t\t\t\t<button class=\"ios gradient-border\"\n\t\t\t\t\t\t\t\t\thref=\"https://apps.apple.com/us/app/loopring-smart-wallet/id1550921126\"\n\t\t\t\t\t\t\t\t\tonClick=\"window.open('https://apps.apple.com/us/app/loopring-smart-wallet/id1550921126','_parent');\"\n\t\t\t\t\t\t\t\t\trel=\"noopener\"\n\t\t\t\t\t\t\t\t\ttarget=\"_blank\">\n\t\t\t\t\t\t<div id=\"iconIos2\"></div>\n\t\t\t\t\t\t<!--\t\t\t\t\t<img alt=\"download-btn\" height=\"18\"-->\n\t\t\t\t\t\t<!--\t\t\t\t\t\t\t src=\"https://static.loopring.io/assets/images/landPage/wallet_ios.svg\" width=\"18\">-->\n\t\t\t\t\t\t<span aria-label=\"IOS\" class=\"Typography-root Typography-body1\" id=\"labelIOS2\"></span>\n\t\t\t\t\t</button>\n\t\t\t\t\t<button class=\"android gradient-border\"\n\t\t\t\t\t\t\t\t\thref=\"https://download.loopring.io/LoopringWallet.apk\"\n\t\t\t\t\t\t\t\t\tonClick=\"window.open('https://download.loopring.io/LoopringWallet.apk','_parent');\"\n\t\t\t\t\t\t\t\t\trel=\"noopener\" target=\"_blank\">\n\t\t\t\t\t\t<div id=\"iconAndroid2\"></div>\n\t\t\t\t\t\t<span aria-label=\"Android\" class=\"Typography-root Typography-body1\" id=\"labelAndroid2\"></span>\n\t\t\t\t\t</button>\n\t\t\t\t\t<button class=\"google-play gradient-border\"\n\t\t\t\t\t\t\t\t\thref=\"https://play.google.com/store/apps/details?id=loopring.defi.wallet\"\n\t\t\t\t\t\t\t\t\tonClick=\"window.open('https://play.google.com/store/apps/details?id=loopring.defi.wallet','_parent');\"\n\t\t\t\t\t\t\t\t\trel=\"noopener\" target=\"_blank\">\n\t\t\t\t\t\t<div id=\"iconGooglePlay2\"></div>\n\t\t\t\t\t\t<span aria-label=\"Google Play\" class=\"Typography-root Typography-body1\" id=\"labelGooglePlay2\"></span>\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t\t<div class=\"footerContent\">\n\t\t\t<div class=\"wrap Container-maxWidthLg\">\n\t\t\t\t<div class=\"Box-root content\">\n\t\t\t\t\t<div class=\"Box-root\" id=\"logSvg\"></div>\n\t\t\t\t\t<section class=\"Box-root group\">\n\t\t\t\t\t\t<h6 aria-label=\"About\" class=\"Typography-root Typography-body2\" id=\"labelAbout\"></h6>\n\t\t\t\t\t\t<ul class=\"Ul-root\">\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<a aria-label=\"blog Loopring.org\"\n\t\t\t\t\t\t\t\t\t class=\"Typography-root Typography-inherit Link-root Link-underlineAlways\" href=\"https://loopring.org\"\n\t\t\t\t\t\t\t\t\t id=\"labelLoopringOrg\" rel=\"noopener noreferrer\" target=\"_blank\"/>blog Loopring.org</a>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<a aria-label=\"Loopring Terms\" class=\"Typography-root Typography-inherit Link-root Link-underlineAlways\"\n\t\t\t\t\t\t\t\t\t href=\"https://www.iubenda.com/terms-and-conditions/74969935\" id=\"labelLoopringTerms\"\n\t\t\t\t\t\t\t\t\t rel=\"noopener noreferrer\" target=\"_blank\">Loopring Terms</a>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<a aria-label=\"Privacy Policy\" class=\"Typography-root Typography-inherit Link-root Link-underlineAlways\"\n\t\t\t\t\t\t\t\t\t href=\"https://loopring.io/#/document/privacy_en.md\" id=\"labelPrivacyPolicy\" rel=\"noopener noreferrer\"\n\t\t\t\t\t\t\t\t\t target=\"_blank\">Privacy Policy</a>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<a aria-label=\"Risk Disclosure\"\n\t\t\t\t\t\t\t\t\t class=\"Typography-root Typography-inherit Link-root Link-underlineAlways\"\n\t\t\t\t\t\t\t\t\t href=\"https://loopring.io/#/document/risks_en.md\" id=\"labelRiskDisclosure\" rel=\"noopener noreferrer\"\n\t\t\t\t\t\t\t\t\t target=\"_blank\">Risk Disclosure</a>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</section>\n\t\t\t\t\t<section class=\"Box-root group\">\n\t\t\t\t\t\t<h6 aria-label=\"Platform\" class=\"Typography-root Typography-body2\" id=\"labelPlatform\"></h6>\n\t\t\t\t\t\t<ul class=\"Ul-root\">\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<a aria-label=\"Fees\" class=\"Typography-root Typography-inherit Link-root Link-underlineAlways\"\n\t\t\t\t\t\t\t\t\t href=\"https://loopring.io/#/document/dex_fees_en.md\" id=\"labelFees\" rel=\"noopener noreferrer\"\n\t\t\t\t\t\t\t\t\t target=\"_blank\">Box-root group</a>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<a aria-label=\"VIP Program\" class=\"Typography-root Typography-inherit Link-root Link-underlineAlways\"\n\t\t\t\t\t\t\t\t\t href=\"https://medium.loopring.io/introducing-loopring-vip-tiers-c6f73d753bac\" id=\"labelVIPProgram\"\n\t\t\t\t\t\t\t\t\t rel=\"noopener noreferrer\" target=\"_blank\">VIP Program</a>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<a aria-label=\"Referrals\" class=\"Typography-root Typography-inherit Link-root Link-underlineAlways\"\n\t\t\t\t\t\t\t\t\t href=\"https://medium.loopring.io/loopring-exchange-launches-referral-program-c61777f072d1\"\n\t\t\t\t\t\t\t\t\t id=\"labelReferrals\" rel=\"noopener noreferrer\" target=\"_blank\">Referrals</a>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</section>\n\t\t\t\t\t<section class=\"Box-root group\">\n\t\t\t\t\t\t<h6 aria-label=\"Support\" class=\"Typography-root Typography-body2\" id=\"labelSupport\">Support</h6>\n\t\t\t\t\t\t<ul class=\"Ul-root\">\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<a aria-label=\"Submit A Request\"\n\t\t\t\t\t\t\t\t\t class=\"Typography-root Typography-inherit Link-root Link-underlineAlways\"\n\t\t\t\t\t\t\t\t\t href=\"https://desk.zoho.com/portal/loopring/en/home\" id=\"labelSubmitARequest\"\n\t\t\t\t\t\t\t\t\t rel=\"noopener noreferrer\"\n\t\t\t\t\t\t\t\t\t target=\"_blank\">Submit A Request</a>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<a aria-label=\"Creator Grants\" class=\"Typography-root Typography-inherit Link-root Link-underlineAlways\"\n\t\t\t\t\t\t\t\t\t href=\"https://www.loopringgrants.org/\" id=\"labelCreatorGrants\" rel=\"noopener noreferrer\"\n\t\t\t\t\t\t\t\t\t target=\"_blank\">Creator Grants</a>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<a aria-label=\"List a Token\" class=\"Typography-root Typography-inherit Link-root Link-underlineAlways\"\n\t\t\t\t\t\t\t\t\t href=\"https://loopringexchange.typeform.com/to/T0bgsodw?typeform-source=medium.com\"\n\t\t\t\t\t\t\t\t\t id=\"labelListAToken\" rel=\"noopener noreferrer\" target=\"_blank\">List a Token</a>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<a aria-label='Wallet Guardian'\n\t\t\t\t\t\t\t\t\t class='Typography-root Typography-inherit Link-root Link-underlineAlways'\n\t\t\t\t\t\t\t\t\t href='https://guardian.loopring.io' id='labelWalletGuardian' rel='noopener noreferrer'\n\t\t\t\t\t\t\t\t\t target='_blank'></a>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</section>\n\t\t\t\t\t<section class=\"Box-root group\">\n\t\t\t\t\t\t<h6 aria-label=\"Developers\" class=\"Typography-root Typography-body2\" id=\"labelDevelopers\"></h6>\n\t\t\t\t\t\t<ul class=\"Ul-root\">\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<a aria-label=\"Smart Contracts\"\n\t\t\t\t\t\t\t\t\t class=\"Typography-root Typography-inherit Link-root Link-underlineAlways\"\n\t\t\t\t\t\t\t\t\t href=\"https://loopring.io/#/document/contracts_en.md\" id=\"labelSmartContracts\"\n\t\t\t\t\t\t\t\t\t rel=\"noopener noreferrer\" target=\"_blank\">Smart Contracts</a>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<a aria-label=\"APIs\" class=\"Typography-root Typography-inherit Link-root Link-underlineAlways\"\n\t\t\t\t\t\t\t\t\t href=\"https://docs.loopring.io\" id=\"labelAPIs\" rel=\"noopener noreferrer\" target=\"_blank\">APIs</a>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<a aria-label=\"Layer 2 Explorer\"\n\t\t\t\t\t\t\t\t\t class=\"Typography-root Typography-inherit Link-root Link-underlineAlways\"\n\t\t\t\t\t\t\t\t\t href=\"https://explorer.loopring.io\" id=\"labelLayer2Explorer\" rel=\"noopener noreferrer\"\n\t\t\t\t\t\t\t\t\t target=\"_blank\">Layer 2 Explorer</a>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<a aria-label=\"Bug Bounty\" class=\"Typography-root Typography-inherit Link-root Link-underlineAlways\"\n\t\t\t\t\t\t\t\t\t href=\"https://loopring.io/#/document/bug_bounty_en.md\" id=\"labelBugBounty\" rel=\"noopener noreferrer\"\n\t\t\t\t\t\t\t\t\t target=\"_blank\">Bug Bounty</a>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<a aria-label=\"Subgraph\" class=\"Typography-root Typography-inherit Link-root Link-underlineAlways\"\n\t\t\t\t\t\t\t\t\t href=\"https://thegraph.com/explorer/subgraph?id=HgnaENC2oG5hJFsWoHvULBbj7djTJ7TZnqa58iTWA3Rd\"\n\t\t\t\t\t\t\t\t\t id=\"labelSubgraph\" rel=\"noopener noreferrer\" target=\"_blank\">Subgraph</a>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</section>\n\t\t\t\t\t<section class=\"Box-root group groupIcon\">\n\t\t\t\t\t\t<h6 aria-label=\"Follow us\" class=\"Typography-root Typography-body2\" id=\"labelFollowus\">Follow us</h6>\n\t\t\t\t\t\t<div class=\"Box-root footerContentList\">\n\t\t\t\t\t\t\t<ul class=\"List-root List-padding\"\n\t\t\t\t\t\t\t\t\tstyle=\"display: flex; align-items: flex-start; padding-top: 0px; padding-bottom: 0px;\">\n\t\t\t\t\t\t\t\t<li class=\"List-root Typography-body1\">\n\t\t\t\t\t\t\t\t\t<a class=\"Typography-root Typography-inherit Link-root Link-underlineAlways icon\" id=\"discordIcon\"\n\t\t\t\t\t\t\t\t\t\t href=\"https://discord.com/invite/KkYccYp\" rel=\"noopener noreferrer\" target=\"_blank\"></a>\n\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t<li class=\"List-root Typography-body1\">\n\t\t\t\t\t\t\t\t\t<a class=\"Typography-root Typography-inherit Link-root Link-underlineAlways icon\" id=\"twitterIcon\"\n\t\t\t\t\t\t\t\t\t\t href=\"https://twitter.com/loopringorg\" rel=\"noopener noreferrer\" target=\"_blank\"></a>\n\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t<li class=\"List-root Typography-body1\">\n\t\t\t\t\t\t\t\t\t<a class=\"Typography-root Typography-inherit Link-root Link-underlineAlways icon\"\n\t\t\t\t\t\t\t\t\t\t href=\"https://www.youtube.com/c/Loopring\" rel=\"noopener noreferrer\" target=\"_blank\"\n\t\t\t\t\t\t\t\t\t\t id=\"youtubeIcon\"></a>\n\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t<li class=\"List-root Typography-body1\">\n\t\t\t\t\t\t\t\t\t<a class=\"Typography-root Typography-inherit Link-root Link-underlineAlways icon\" id=\"mediumIcon\"\n\t\t\t\t\t\t\t\t\t\t href=\"https://medium.com/loopring-protocol\" rel=\"noopener noreferrer\" target=\"_blank\"></a>\n\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t</ul>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</section>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<p aria-label=\"@2017 Loopring Technology Limited. All rights reserved.\" class=\"Typography-root Typography-body1\"\n\t\t\t\t id=\"labelCopyRight\"></p>\n\t\t</div>\n\t</footer>\n</div>\n<div id=\"bgContent\">\n</div>\n</body>\n</html>\n\n"
  },
  {
    "path": "packages/web-wallet/public/manifest.json",
    "content": "{\n  \"short_name\": \"Loopring L2\",\n  \"name\": \"Loopring - Ethereum Layer2\",\n  \"icons\": [\n    {\n      \"src\": \"favicon.ico\",\n      \"sizes\": \"64x64 32x32 24x24 16x16\",\n      \"type\": \"image/x-icon\"\n    }\n  ],\n  \"start_url\": \".\",\n  \"display\": \"standalone\",\n  \"theme_color\": \"#000000\",\n  \"background_color\": \"#ffffff\"\n}\n"
  },
  {
    "path": "packages/web-wallet/public/reset.css",
    "content": "html,\nbody,\ndiv,\nspan,\napplet,\nobject,\niframe,\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\np,\nblockquote,\npre,\na,\nabbr,\nacronym,\naddress,\nbig,\ncite,\ncode,\ndel,\ndfn,\nem,\nimg,\nins,\nkbd,\nq,\ns,\nsamp,\nsmall,\nstrike,\nstrong,\nsub,\nsup,\ntt,\nvar,\nb,\nu,\ni,\ncenter,\ndl,\ndt,\ndd,\nol,\nul,\nli,\nfieldset,\nform,\nlabel,\nlegend,\ntable,\ncaption,\ntbody,\ntfoot,\nthead,\ntr,\nth,\ntd,\narticle,\naside,\ncanvas,\ndetails,\nembed,\nfigure,\nfigcaption,\nfooter,\nheader,\nhgroup,\nmenu,\nnav,\noutput,\nruby,\nsection,\nsummary,\ntime,\nmark,\naudio,\nvideo {\n    margin: 0;\n    padding: 0;\n    border: 0;\n    font-size: 100%;\n    font: inherit;\n    vertical-align: baseline;\n    box-sizing: border-box;\n}\n\naddress,\ncaption,\ncite,\ncode,\ndfn,\nem,\nstrong,\nth,\nvar,\nb {\n    font-weight: normal;\n    font-style: normal;\n}\n\nabbr,\nacronym {\n    border: 0;\n}\n\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmenu,\nnav,\nsection {\n    display: block;\n}\n\n*,\n*::after,\n*::before {\n    margin: 0;\n    padding: 0;\n    box-sizing: inherit;\n}\n\n*:focus-visible {\n    outline: rgba(0, 0, 0, 0);\n}\n\nhtml {\n    text-size-adjust: 100%;\n    box-sizing: border-box;\n    scroll-behavior: smooth;\n}\n\nbody {\n    line-height: 1;\n}\n\nol,\nul {\n    list-style: none;\n}\n\nblockquote,\nq {\n    quotes: none;\n}\n\ntable {\n    border-collapse: collapse;\n    border-spacing: 0;\n}\n\ncaption,\nth {\n    text-align: left;\n}\n\ntextarea {\n    resize: none;\n}\n\na {\n    text-decoration: none;\n    cursor: pointer;\n}\n\nbutton {\n    padding: 0;\n    border: none;\n    background: none;\n}\n\nhtml {\n    overscroll-behavior-x: none;\n    overscroll-behavior-y: none;\n    text-underline-offset: 3px;\n}\n\niframe {\n    display: none;\n}\n\nhtml {\n    --dark: #000000;\n    --dark1000: #31353D;\n    --dark900: #141414;\n    --dark800: #1f1f1f;\n    --dark700: #262626;\n    --dark600: #434343;\n    --dark500: #595959;\n    --dark400: #8c8c8c;\n    --light400: #bfbfbf;\n    --light500: #d9d9d9;\n    --light600: #ebebeb;\n    --light700: #f0f0f0;\n    --light800: #f5f5f5;\n    --light900: #fafafa;\n    --light1000: #ffffff;\n    --light: #ffffff;\n    --color-success: #00bba8;\n    --color-warning: #fba95c;\n    --color-error: #ff5677;\n    /**** config pex ****/\n    --h1: 48px;\n    --h4: 24px;\n    --h5: 20px;\n    --body: 14px;\n    --body2: 12px;\n    --header-row-height: 44px;\n    --header-height: 64px;\n\n    --header-submenu-item-height: 52px;\n    --header-submenu-item-width: 250px;\n}\n"
  },
  {
    "path": "packages/web-wallet/public/robots.txt",
    "content": "# https://www.robotstxt.org/robotstxt.html\nUser-agent: *\nDisallow:\n"
  },
  {
    "path": "packages/web-wallet/public/wallet.css",
    "content": "@charset \"UTF-8\";\nbody {\n  background: var(--color-global-Bg);\n  font-family: Roboto, Helvetica, Arial, '华文细黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体',\n  Heiti, '黑体', sans-serif;\n  user-drag: none;\n  user-select: none;\n}\n\nbutton {\n  border: 1px solid var(--color-border);\n  border-radius: 2px;\n  box-sizing: border-box;\n}\n\nbutton:hover {\n  border: 1px solid var(--color-border-hover);\n}\n\n.Typography-root {\n  font-size: 14px;\n  color: var(--color-text-primary);\n}\n\nheader .headerGg {\n  width: 100vw;\n}\n\nheader .Toolbar-root {\n  height: var(--header-height);\n  display: flex;\n  flex-direction: row;\n  justify-content: space-between;\n  align-items: center;\n}\n\nheader nav {\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n}\n\nheader nav ul {\n  margin-left: 24px;\n}\n\nheader nav ul li {\n  display: inline-block;\n  height: var(--header-height);\n  line-height: var(--header-height);\n  padding: 0 8px;\n}\n\nfooter .Container-root {\n  display: flex;\n  flex-direction: column;\n}\n\nfooter .content {\n  display: flex;\n  flex-direction: row;\n  justify-content: space-between;\n}\n\n.flexBox {\n  display: flex;\n}\n\n.flex-column {\n  flex-direction: column;\n}\n\n.flex-row {\n  flex-direction: row;\n}\n\n.align-center {\n  align-items: center;\n}\n\n/* Rectangle 1662 */\n#labelNavLanuch {\n  /*width: 112px;*/\n  padding: 0 16px;\n  line-height: 36px;\n  height: 36px;\n  border-radius: 2px;\n  border: 0;\n  /*border: 1px solid;*/\n  /*border-image: linear-gradient(90deg, #D7B2FF 0%, #77AAFF 53.24%) 1;*/\n  color: var(--color-text-primary);\n  border-image-repeat: round;\n  position: relative;\n  z-index: 99;\n  box-sizing: border-box;\n}\n\n#labelNavLanuch:after {\n  top: 0;\n  left: 0;\n  right: 0;\n  bottom: 0;\n  position: absolute;\n  content: '';\n  border-radius: 2px;\n  z-index: -1;\n  border: 2px solid;\n  border-image: linear-gradient(90deg, #d7b2ff 0%, #77aaff 53.24%) 1;\n  /*background-image: linear-gradient(90deg, #D7B2FF 0%, #77AAFF 53.24%);*/\n  /*mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAABeSURBVHgB7dZBDYAwDIXhtgomAWdowAE4wF5PTMIMNOUtWFgv5P1Jk5329Vh1911V78xssraOORXAg8cmNQ0r/HzWTIojQIAAAQIEfgLgohhSV7eIOOQ7MZY2F8dcL/hCFFUPCYXoAAAAAElFTkSuQmCC);*/\n  /*-webkit-mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAABeSURBVHgB7dZBDYAwDIXhtgomAWdowAE4wF5PTMIMNOUtWFgv5P1Jk5329Vh1911V78xssraOORXAg8cmNQ0r/HzWTIojQIAAAQIEfgLgohhSV7eIOOQ7MZY2F8dcL/hCFFUPCYXoAAAAAElFTkSuQmCC);*/\n  /*mask-size:99%;*/\n  /*-webkit-mask-size:99%;*/\n}\n\n#logo {\n  min-width: auto;\n  border-radius: 0px;\n  text-indent: -999999em;\n  background: var(--color-logo);\n  -webkit-mask: url(https://static.loopring.io/assets/svg/logo.svg) center center/contain space;\n  width: 105px;\n  height: 40px;\n  padding: 8px;\n  color: transparent;\n  display: inline-flex;\n  align-items: center;\n  justify-content: center;\n  position: relative;\n  box-sizing: border-box;\n  outline: 0px;\n  border: 0px;\n  margin: -10px 0px 0px -12px;\n  cursor: pointer;\n}\n\n#logo::after {\n  content: 'beta';\n  position: absolute;\n  color: var(--color-logo);\n  display: block;\n  font-size: 1rem;\n  line-height: 0.8rem;\n  right: -24px;\n  top: 14px;\n  font-weight: 200;\n  opacity: 0;\n  box-shadow: 0 0 1px 0 var(--color-logo);\n  border-radius: 2px;\n  padding: 3px 2px;\n}\n\n#logo svg {\n  fill: var(--color-text-Secondary);\n}\n\n/* identical to box height, or 129% */\n.Container-root,\n.wrap {\n  max-width: calc(1200px - 32px);\n  padding: 0 16px;\n  margin: 0 auto;\n}\n\na.Typography-root,\na.Typography-root:active,\na.Typography-root:visited,\n.Link-root,\n.Link-root:active,\n.Link-root:visited,\n.MenuItem-root a.Typography-root,\n.MenuItem-root a.Typography-root:active,\n.MenuItem-root a.Typography-root:visited,\n.Link-root {\n  color: var(--color-text-Secondary);\n}\n\na.Typography-root:hover,\n.MenuItem-root a.Typography-root:hover,\n.Link-root:hover {\n  color: var(--color-text-primary);\n}\n\n.Link-underlineAlways:hover {\n  text-decoration: underline;\n}\n\nbody {\n  display: flex;\n  flex-direction: column;\n  justify-content: flex-start;\n  height: 100%;\n}\n\n.sectionDetail {\n  display: flex;\n  flex-direction: column;\n  width: 50%;\n  min-width: 50%;\n}\n\n.sectionDetail h3 {\n  word-break: break-word;\n  white-space: pre-line;\n  line-height: 1.2em;\n  margin: 24px 0;\n}\n\n.sectionDetail p {\n  line-height: 1.2em;\n  word-break: break-word;\n  white-space: pre-line;\n}\n\n.sectionFull {\n  align-items: center;\n  justify-content: center;\n  width: 100vw;\n  margin: 160px 0;\n}\n\n.sectionFull:nth-child(even) .wrap {\n  flex-direction: row-reverse;\n}\n\n.sectionFull:nth-child(odd) .img-container {\n  display: flex;\n  justify-content: flex-end;\n}\n\n.sectionFull .wrap {\n  justify-content: space-between;\n  display: flex;\n  align-items: center;\n}\n\nh3.Typography-root {\n  font-size: var(--h1);\n}\n\nh3 ~ p.Typography-root {\n  color: var(--color-text-third);\n  font-size: var(--h5);\n}\n\n.downLoadBtnGroup .Typography-roo {\n  display: inline-block;\n  margin-left: 8px;\n}\n\n.downLoadBtnGroup svg {\n  fill: var(--color-text-Button);\n}\n\n.downLoadBtnGroup {\n  display: flex;\n  flex-direction: row;\n  justify-content: space-evenly;\n}\n\n.downLoadBtnGroup button {\n  margin: 0 12px;\n  width: 180px;\n  height: 48px;\n  display: flex;\n  flex-direction: row;\n  justify-content: space-evenly;\n  align-items: center;\n  padding: 0 24px;\n}\n\n/* Ethereum Unleashed */\n#labelEthereumUnleashed {\n  width: 522px;\n  height: 72px;\n  font-weight: 700;\n  font-size: 56px;\n  line-height: 72px;\n  background: linear-gradient(90deg, #d7b2ff 0%, #77aaff 53.24%);\n  -webkit-background-clip: text;\n  -webkit-text-fill-color: transparent;\n  /*background-clip: text;*/\n  border-radius: 2px;\n  text-fill-color: transparent;\n  margin-top: 120px;\n  margin-bottom: 16px;\n  text-align: center;\n}\n\n#labelGatewayToEthereum {\n  margin-bottom: 32px;\n  line-height: 1.5em;\n  font-size: var(--h4);\n  text-align: center;\n}\n\nfooter {\n  flex: 1;\n  display: flex;\n  flex-direction: column;\n  justify-content: flex-end;\n}\n\nfooter .content {\n  margin-top: 24px;\n  margin-bottom: 24px;\n}\n\nfooter .footerWallet {\n  z-index: 99;\n  background: var(--color-box);\n  padding-top: 16px;\n  padding-bottom: 16px;\n}\n\nfooter .footerWallet .wrap {\n  flex-direction: row;\n  align-items: center;\n  justify-content: space-between;\n}\n\nfooter .group {\n  padding-top: 16px;\n}\n\nfooter .group h6 {\n  font-size: var(--body2);\n  color: var(--color-text-third);\n  line-height: 4em;\n  padding-bottom: 8px;\n}\n\nfooter .group .Typography-root {\n  font-size: var(--body2);\n  line-height: 2em;\n}\n\n.Button-root {\n  cursor: pointer;\n}\n\n.groupIcon li {\n  padding-right: 8px;\n}\n\n.groupIcon .icon svg {\n  font-size: var(--h5);\n  fill: var(--color-text-Secondary);\n  width: 36px;\n  height: 36px;\n}\n\n.groupIcon a.icon:hover svg {\n  fill: var(--color-text-primary);\n}\n\n#labelCopyRight {\n  color: var(--color-text-third);\n  text-align: center;\n  height: 40px;\n  line-height: 40px;\n  border-top: 1px solid var(--color-divide);\n}\n\n.logoDex {\n  display: flex;\n  flex-direction: column;\n  justify-content: space-evenly;\n}\n\n.logoDex p:first-child {\n  color: var(--color-text-primary);\n  font-size: var(--h5);\n}\n\n.logoDex p:last-child {\n  color: var(--color-text-third);\n}\n\n.carousel-container {\n  --height: 596px;\n  --width: 280px;\n  --size-image: 0.8;\n  display: flex;\n  margin-top: 120px;\n  overflow: hidden;\n  width: 800px;\n  height: calc(var(--height) + 32px);\n  transform-style: preserve-3d;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  overflow: hidden;\n}\n\n.carousel-container .container {\n  height: 100%;\n  width: 100%;\n}\n\n.carousel-container #slider {\n  width: 100vw;\n  height: 100%;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n}\n\n.carousel-container input[type='radio'] {\n  display: none;\n}\n\n.carousel-container .cards {\n  position: relative;\n  width: 100%;\n  height: 100%;\n}\n\n.carousel-container .card {\n  position: absolute;\n  top: 50%;\n  left: 50%;\n  margin-left: calc(var(--width) / -2);\n  margin-top: calc(var(--height) / -2);\n  cursor: pointer;\n  transition: transform 0.4s cubic-bezier(0.165, 0.84, 0.44, 1);\n}\n\n.carousel-container img {\n  width: var(--width);\n  object-fit: cover;\n}\n\n#bgContent {\n  position: absolute;\n  z-index: 1;\n  top: 0;\n  right: 0;\n  left: 0;\n  height: 100vh;\n  overflow: hidden;\n  pointer-events: none;\n}\n\n#bgContent #bgAlphaBg {\n  position: absolute;\n  pointer-events: none;\n  transform: translate(0, -300px) rotate(0);\n  top: 0;\n  left: 0;\n  width: 100%;\n}\n\n#bgContent #bgAlpha {\n  position: absolute;\n  pointer-events: none;\n  transform: translate(20%, -40%) rotate(-13deg);\n}\n\n@media only screen and (max-width: 1024px) {\n  .Container-root,\n  .wrap {\n    width: 100vw;\n    padding: 0 16px;\n    margin: 0 auto;\n  }\n\n  .carousel-container {\n    display: flex;\n    overflow: hidden;\n    align-items: center;\n    width: 100%;\n    align-items: center;\n    justify-content: center;\n    margin-top: 40px;\n  }\n\n  #logo {\n    min-width: auto;\n    /*border-radius: 0px;*/\n    /*text-indent: -999999em;*/\n    background: var(--color-logo);\n    -webkit-mask: url(https://static.loopring.io/assets/svg/loopring.svg) center center/contain space;\n    width: 40px;\n    height: 40px;\n    margin-left: 8px;\n  }\n\n  h3.Typography-root {\n    font-size: var(--h4);\n    text-align: center;\n  }\n\n  h3 ~ p.Typography-root {\n    font-size: var(--body);\n    white-space: initial;\n  }\n\n  header ul li:first-child {\n    display: none;\n  }\n\n  .downLoadBtnGroup {\n    flex-direction: column;\n    justify-content: space-between;\n    height: calc(48px * 3 + 16px * 3);\n    margin-left: 0;\n  }\n\n  .downLoadBtnGroup button {\n    margin-left: 0;\n  }\n\n  footer .footerWallet .wrap {\n    flex-direction: column;\n    align-items: center;\n    justify-content: space-between;\n  }\n\n  footer .downLoadBtnGroup {\n    margin-top: 24px;\n  }\n\n  footer .content {\n    flex-direction: column;\n  }\n\n  #labelEthereumUnleashed {\n    width: 100%;\n    font-size: 36px;\n    margin-top: 32px;\n  }\n\n  #logSvg {\n    display: none;\n  }\n\n  .sectionFull {\n    align-items: flex-start;\n    justify-content: center;\n    height: initial;\n    margin: 80px 0;\n  }\n\n  .sectionFull .wrap {\n    flex-direction: column-reverse !important;\n  }\n\n  .sectionFull .wrap .sectionDetail {\n    width: auto;\n    min-width: auto;\n  }\n\n  .sectionFull .wrap .sectionDetail h3,\n  .sectionFull .wrap .sectionDetail p {\n    text-align: center;\n  }\n\n  .sectionFull .img-container {\n    display: flex;\n    margin-top: 24px;\n    justify-content: center !important;\n  }\n\n  .carousel-container {\n    --size-image: 0.5;\n  }\n\n  #bgContent #bgAlphaBg {\n    display: none;\n  }\n\n  #bgContent #bgAlpha {\n    position: absolute;\n    pointer-events: none;\n    transform: translate(-30%, -20%) rotate(13deg) scale(0.5);\n  }\n}\n\n.gradient-border {\n  --borderWidth: 3px;\n  background: var(--color-global-Bg);\n  position: relative;\n}\n\n.gradient-border:hover {\n  border: 0;\n  box-shadow: 0 5px 15px #f7953304, 0 10px 30px #f3705502;\n  animation: boxShow 3s ease alternate infinite;\n}\n\n.gradient-border:hover:after {\n  content: '';\n  position: absolute;\n  top: calc(-1 * var(--borderWidth));\n  left: calc(-1 * var(--borderWidth));\n  right: calc(-1 * var(--borderWidth));\n  bottom: calc(-1 * var(--borderWidth));\n  background: linear-gradient(\n          60deg,\n          #f79533,\n          #f37055,\n          #ef4e7b,\n          #a166ab,\n          #5073b8,\n          #1098ad,\n          #07b39b,\n          #6fba82\n  );\n  border-radius: calc(2 * var(--borderWidth));\n  z-index: -1;\n  animation: animatedgradient 3s ease alternate infinite;\n  background-size: 300% 300%;\n}\n\n@media only screen and (min-width: 768px) and (max-width: 1024px) {\n  #labelEthereumUnleashed {\n    width: 522px;\n    font-size: 56px;\n  }\n\n  .carousel-container {\n    --size-image: 0.7;\n    margin-top: 40px;\n  }\n\n  #labelGatewayToEthereum {\n    margin-bottom: 32px;\n    font-size: var(--h4);\n    text-align: center;\n  }\n\n  h3.Typography-root {\n    font-size: var(--h1);\n    margin: 80px 0 40px 0;\n  }\n\n  h3 ~ p.Typography-root {\n    color: var(--color-text-third);\n    font-size: var(--h5);\n  }\n}\n\n@keyframes boxShow {\n  0% {\n    box-shadow: 0 5px 15px rgba(247, 149, 51, 0.4), 0 10px 30px rgba(243, 112, 85, 0.2);\n  }\n  25% {\n    box-shadow: 0 5px 15px rgba(239, 78, 123, 0.4), 0 10px 30px rgba(161, 102, 171, 0.2);\n  }\n  50% {\n    box-shadow: 0 5px 15px rgba(80, 115, 184, 0.4), 0 10px 30px rgba(16, 152, 173, 0.2);\n  }\n  75% {\n    box-shadow: 0 5px 15px rgba(7, 179, 155, 0.4), 0 10px 30px rgba(111, 186, 130, 0.2);\n  }\n}\n\n@keyframes animatedgradient {\n  0% {\n    background-position: 0% 50%;\n  }\n  25% {\n    background-position: 25% 50%;\n  }\n  50% {\n    background-position: 50% 50%;\n  }\n  75% {\n    background-position: 75% 50%;\n  }\n}\n\n#changeColor {\n  margin-right: 24px;\n  border: 0;\n}\n\n.carousel-container #item-1:checked ~ .cards #selector-1,\n.carousel-container #item-2:checked ~ .cards #selector-2,\n.carousel-container #item-3:checked ~ .cards #selector-3 {\n  transform: translateX(0%) scale(1);\n  z-index: 80;\n}\n\n.carousel-container #item-1:checked ~ .cards #selector-3,\n.carousel-container #item-2:checked ~ .cards #selector-1,\n.carousel-container #item-3:checked ~ .cards #selector-2 {\n  transform: translateX(100%) scale(var(--size-image));\n  z-index: 70;\n}\n\n.carousel-container #item-1:checked ~ .cards #selector-2,\n.carousel-container #item-2:checked ~ .cards #selector-3,\n.carousel-container #item-3:checked ~ .cards #selector-1 {\n  transform: translateX(-100%) scale(var(--size-image));\n  z-index: 70;\n}\n"
  },
  {
    "path": "packages/web-wallet/public/wallet.js",
    "content": "const svgGroup = {\n  LightIcon: `<svg width='24' height='24' viewBox='0 0 24 24' fill='black'>\n    <path d='M12 18C10.4087 18 8.88258 17.3679 7.75736 16.2426C6.63214 15.1174 6 13.5913 6 12C6 10.4087 6.63214 8.88258 7.75736 7.75736C8.88258 6.63214 10.4087 6 12 6C13.5913 6 15.1174 6.63214 16.2426 7.75736C17.3679 8.88258 18 10.4087 18 12C18 13.5913 17.3679 15.1174 16.2426 16.2426C15.1174 17.3679 13.5913 18 12 18ZM12 16C13.0609 16 14.0783 15.5786 14.8284 14.8284C15.5786 14.0783 16 13.0609 16 12C16 10.9391 15.5786 9.92172 14.8284 9.17157C14.0783 8.42143 13.0609 8 12 8C10.9391 8 9.92172 8.42143 9.17157 9.17157C8.42143 9.92172 8 10.9391 8 12C8 13.0609 8.42143 14.0783 9.17157 14.8284C9.92172 15.5786 10.9391 16 12 16V16ZM11 1H13V4H11V1ZM11 20H13V23H11V20ZM3.515 4.929L4.929 3.515L7.05 5.636L5.636 7.05L3.515 4.93V4.929ZM16.95 18.364L18.364 16.95L20.485 19.071L19.071 20.485L16.95 18.364ZM19.071 3.514L20.485 4.929L18.364 7.05L16.95 5.636L19.071 3.515V3.514ZM5.636 16.95L7.05 18.364L4.929 20.485L3.515 19.071L5.636 16.95V16.95ZM23 11V13H20V11H23ZM4 11V13H1V11H4Z' />\n  </svg>`,\n  DarkIcon: `<svg width='24' height='24' viewBox='0 0 24 24' fill='white'>\n    <path d='M11.38 2.01953C10.6431 2.70615 10.0521 3.53416 9.64219 4.45415C9.23227 5.37414 9.01185 6.36728 8.99408 7.37431C8.97632 8.38133 9.16156 9.38163 9.53877 10.3155C9.91598 11.2494 10.4774 12.0977 11.1896 12.8099C11.9018 13.5221 12.7501 14.0835 13.684 14.4608C14.6179 14.838 15.6182 15.0232 16.6252 15.0054C17.6323 14.9877 18.6254 14.7673 19.5454 14.3573C20.4654 13.9474 21.2934 13.3564 21.98 12.6195C21.662 17.8545 17.316 22.0005 12.001 22.0005C6.477 22.0005 2 17.5235 2 12.0005C2 6.68553 6.146 2.33953 11.38 2.01953Z' />\n  </SvgIcon>`,\n  logSvg: `<svg\n      aria-hidden='true'\n      className='SvgIcon-root SvgIcon-fontSizeMedium '\n      color='var(--color-text-third)'\n      fill='none'\n      focusable='false'\n      height='27'\n      style='height: 40px; width: 120px;'\n      viewBox='0 0 89 27'\n      width='89'\n    >\n      <path\n        clip-rule='evenodd'\n        d='M33.2461 13.1402H19.2495L22.2249 17.7118L11.3922 26.0863L33.2461 13.2211V13.1402ZM11.0988 26.2683V0.740234L0.0356445 17.732L11.0988 26.2683ZM35.2363 26.1875V13.1807H37.4154V24.4074H40.3908V26.1875H35.2363ZM88.6455 15.6486V17.7928H86.5293V15.6283C86.5921 14.6372 84.5387 14.5967 84.6854 15.6283V23.659C84.6854 24.1647 84.9578 24.4277 85.5654 24.4277C86.1311 24.4277 86.5293 24.1647 86.5293 23.659V21.4541H85.6073V19.674H88.6455V23.6792C88.6455 25.257 87.556 26.2887 85.5654 26.2887C83.5749 26.2887 82.4853 25.2368 82.4853 23.6792V15.6486C82.4853 14.091 83.5749 13.0391 85.5654 13.0391C87.556 13.0391 88.6455 14.0708 88.6455 15.6486ZM79.1119 20.2809C79.07 19.0874 79.049 17.9951 79.049 16.9836H79.0281V13.1605H81.0186V26.1875H78.7138L76.6604 18.9256C76.7023 20.1393 76.7233 21.2923 76.7233 22.3441V26.1875H74.7327V13.1605H77.1004L79.1119 20.2809ZM73.1403 26.1673H70.9612V13.1403H73.1403V26.1673ZM66.582 19.411C67.1058 19.411 67.3782 19.1481 67.3782 18.6424V15.7093C67.3782 15.2036 67.1058 14.9406 66.582 14.9406H65.5972V19.411H66.582ZM69.5573 15.7093V18.6424C69.5573 19.6335 69.1383 20.4022 68.3421 20.827L69.8297 26.1875H67.6506L66.2677 21.2114H65.5972V26.1875H63.4181V13.1605H66.582C68.5306 13.1605 69.5573 14.1315 69.5573 15.7093ZM59.3532 19.411C59.8771 19.411 60.1494 19.1481 60.1494 18.6424H60.1704V15.7093C60.1704 15.2036 59.898 14.9406 59.3742 14.9406H58.3894V19.411H59.3532ZM56.2103 13.1605H59.3742C61.3228 13.1605 62.3285 14.1112 62.3495 15.7295V18.6626C62.3495 20.2404 61.3228 21.2114 59.3742 21.2114H58.3894V26.1875H56.2103V13.1605ZM50.7834 23.6792C50.6577 24.6906 52.7111 24.6906 52.5854 23.6792V15.6486C52.6902 14.6372 50.6577 14.6372 50.7834 15.6486V23.6792ZM48.6043 15.6486C48.6043 14.0708 49.6939 13.0391 51.6844 13.0391C53.654 13.0391 54.7645 14.0708 54.7645 15.6486V23.6792C54.7645 25.257 53.675 26.2887 51.6844 26.2887C49.6939 26.2887 48.6043 25.2368 48.6043 23.6792V15.6486ZM43.3242 23.6792C43.1985 24.6906 45.2519 24.6906 45.1261 23.6792V15.6486C45.2309 14.6372 43.1985 14.6372 43.3242 15.6486V23.6792ZM41.1451 15.6486C41.1451 14.0708 42.2346 13.0391 44.2252 13.0391C46.2157 13.0391 47.3053 14.0708 47.3053 15.6486V23.6792C47.3053 25.257 46.2157 26.2887 44.2252 26.2887C42.2346 26.2887 41.1451 25.2368 41.1451 23.6792V15.6486Z'\n        fill-rule='evenodd'\n      />\n    </svg>`,\n  ios: `<svg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'>\n<path d='M11.6236 7.22161C10.7476 7.22161 9.39157 6.22561 7.96357 6.26161C6.07957 6.28561 4.35157 7.35361 3.37957 9.04561C1.42357 12.4416 2.87557 17.4576 4.78357 20.2176C5.71957 21.5616 6.82357 23.0736 8.28757 23.0256C9.69157 22.9656 10.2196 22.1136 11.9236 22.1136C13.6156 22.1136 14.0956 23.0256 15.5836 22.9896C17.0956 22.9656 18.0556 21.6216 18.9796 20.2656C20.0476 18.7056 20.4916 17.1936 20.5156 17.1096C20.4796 17.0976 17.5756 15.9816 17.5396 12.6216C17.5156 9.81361 19.8316 8.46961 19.9396 8.40961C18.6196 6.47761 16.5916 6.26161 15.8836 6.21361C14.0356 6.06961 12.4876 7.22161 11.6236 7.22161ZM14.7436 4.38961C15.5236 3.45361 16.0396 2.14561 15.8956 0.849609C14.7796 0.897609 13.4356 1.59361 12.6316 2.52961C11.9116 3.35761 11.2876 4.68961 11.4556 5.96161C12.6916 6.05761 13.9636 5.32561 14.7436 4.38961Z' />\n</svg>\n`,\n  android: `<svg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'>\n<path d='M6.382 3.968C7.97574 2.69106 9.9578 1.99674 12 2C14.125 2 16.078 2.736 17.618 3.968L19.071 2.515L20.485 3.929L19.032 5.382C20.3089 6.97574 21.0033 8.9578 21 11V12H3V11C3 8.875 3.736 6.922 4.968 5.382L3.515 3.93L4.929 2.516L6.382 3.969V3.968ZM3 14H21V21C21 21.2652 20.8946 21.5196 20.7071 21.7071C20.5196 21.8946 20.2652 22 20 22H4C3.73478 22 3.48043 21.8946 3.29289 21.7071C3.10536 21.5196 3 21.2652 3 21V14ZM9 9C9.26522 9 9.51957 8.89464 9.70711 8.7071C9.89464 8.51957 10 8.26521 10 8C10 7.73478 9.89464 7.48043 9.70711 7.29289C9.51957 7.10535 9.26522 7 9 7C8.73478 7 8.48043 7.10535 8.29289 7.29289C8.10536 7.48043 8 7.73478 8 8C8 8.26521 8.10536 8.51957 8.29289 8.7071C8.48043 8.89464 8.73478 9 9 9ZM15 9C15.2652 9 15.5196 8.89464 15.7071 8.7071C15.8946 8.51957 16 8.26521 16 8C16 7.73478 15.8946 7.48043 15.7071 7.29289C15.5196 7.10535 15.2652 7 15 7C14.7348 7 14.4804 7.10535 14.2929 7.29289C14.1054 7.48043 14 7.73478 14 8C14 8.26521 14.1054 8.51957 14.2929 8.7071C14.4804 8.89464 14.7348 9 15 9Z' />\n</svg> `,\n  googlePlay: `<svg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'>\n  <path d='M3.60972 1.81445L13.793 12.0005L3.61082 22.1869C3.41776 22.1053 3.24866 21.9625 3.13555 21.7672C3.0474 21.6149 3.00098 21.4421 3.00098 21.2661V2.73502C3.00098 2.32158 3.25188 1.96674 3.60972 1.81445ZM14.5 12.7075L16.802 15.0095L5.86498 21.3425L14.5 12.7075ZM17.699 9.50945L20.5061 11.1352C20.9841 11.4119 21.1473 12.0237 20.8705 12.5016C20.783 12.6528 20.6574 12.7785 20.5061 12.866L17.698 14.4915L15.207 12.0005L17.699 9.50945ZM5.86498 2.65845L16.803 8.99045L14.5 11.2935L5.86498 2.65845Z' />\n  </svg>`,\n  youtubeIcon: ` <svg width='24'\n        height='24'\n        viewBox='0 0 24 24'\n        fill='none'\n      >\n        <path\n          fill-rule ='evenodd'\n          clip-rule='evenodd'\n          d='M22.5417 12C22.5417 17.822 17.822 22.5417 12 22.5417C6.178 22.5417 1.45833 17.822 1.45833 12C1.45833 6.178 6.178 1.45833 12 1.45833C17.822 1.45833 22.5417 6.178 22.5417 12ZM23 12C23 18.0751 18.0751 23 12 23C5.92487 23 1 18.0751 1 12C1 5.92487 5.92487 1 12 1C18.0751 1 23 5.92487 23 12ZM18.1111 12C18.1111 12 18.1111 9.72667 17.8318 8.63767C17.6784 8.03756 17.225 7.56456 16.6475 7.402C15.6031 7.11111 12 7.11111 12 7.11111C12 7.11111 8.39872 7.11111 7.3525 7.402C6.77744 7.56211 6.32339 8.03572 6.16817 8.63767C5.88889 9.72667 5.88889 12 5.88889 12C5.88889 12 5.88889 14.2733 6.16817 15.3623C6.32156 15.9624 6.775 16.4354 7.3525 16.598C8.39872 16.8889 12 16.8889 12 16.8889C12 16.8889 15.6031 16.8889 16.6475 16.598C17.2226 16.4379 17.6766 15.9643 17.8318 15.3623C18.1111 14.2733 18.1111 12 18.1111 12ZM14.4444 12L10.7778 14.1389V9.86111L14.4444 12Z'\n        />\n     </svg>`,\n  twitterIcon: `\n    <svg width='24'\n        height='24'\n        viewBox='0 0 24 24'\n        fill='none'\n      >\n        <path\n          fill-rule ='evenodd'\n          clip-rule='evenodd'\n          d='M22.5417 12C22.5417 17.822 17.822 22.5417 12 22.5417C6.178 22.5417 1.45833 17.822 1.45833 12C1.45833 6.178 6.178 1.45833 12 1.45833C17.822 1.45833 22.5417 6.178 22.5417 12ZM23 12C23 18.0751 18.0751 23 12 23C5.92487 23 1 18.0751 1 12C1 5.92487 5.92487 1 12 1C18.0751 1 23 5.92487 23 12ZM16.7095 9.93043C16.7145 10.0394 16.7165 10.1494 16.7165 10.2604C16.7165 13.6354 14.2725 17.5254 9.80347 17.5244C8.43047 17.5244 7.15347 17.0944 6.07747 16.3564C6.26747 16.3804 6.46147 16.3934 6.65747 16.3934C7.79547 16.3964 8.84347 15.9844 9.67547 15.2944C8.61247 15.2694 7.71447 14.5164 7.40547 13.4854C7.55347 13.5174 7.70547 13.5344 7.86247 13.5354C8.08347 13.5364 8.29847 13.5064 8.50247 13.4484C7.39047 13.2024 6.55247 12.1484 6.55247 10.8904V10.8574C6.88047 11.0554 7.25447 11.1764 7.65347 11.1944C7.00147 10.7224 6.57247 9.92243 6.57247 9.02243C6.57247 8.54643 6.69247 8.10243 6.90147 7.72243C8.09947 9.30843 9.89047 10.3604 11.9115 10.4904C11.8695 10.3014 11.8485 10.1054 11.8485 9.90343C11.8485 8.48243 12.9365 7.34843 14.2785 7.37043C14.9775 7.38243 15.6095 7.70343 16.0525 8.20743C16.6055 8.10143 17.1255 7.89743 17.5955 7.61243C17.4135 8.20543 17.0285 8.69943 16.5265 9.00843C17.0185 8.95343 17.4865 8.82243 17.9225 8.62643C17.5965 9.13343 17.1845 9.57643 16.7095 9.93043Z'\n        />\n     </svg>`,\n  mediumIcon: `\n    <svg width='24'\n        height='24'\n        viewBox='0 0 24 24'\n        fill='none'\n      >\n        <path\n          fill-rule ='evenodd'\n          clip-rule='evenodd'\n          d='M22.5417 12C22.5417 17.822 17.822 22.5417 12 22.5417C6.178 22.5417 1.45833 17.822 1.45833 12C1.45833 6.178 6.178 1.45833 12 1.45833C17.822 1.45833 22.5417 6.178 22.5417 12ZM23 12C23 18.0751 18.0751 23 12 23C5.92487 23 1 18.0751 1 12C1 5.92487 5.92487 1 12 1C18.0751 1 23 5.92487 23 12ZM17.7337 16.4862L16.8583 15.6117H16.8593C16.7676 15.5658 16.7217 15.4274 16.7217 15.3358V8.33883C16.7217 8.24717 16.7676 8.10875 16.8593 8.01708L17.7337 7.00417V6.95833H14.6033L12.2548 12.8965L9.5855 6.95833H6.36342V7.00417L7.193 8.15642C7.37633 8.33975 7.42217 8.61658 7.42217 8.84667V13.9085C7.468 14.1853 7.42217 14.508 7.28467 14.783L6.04167 16.4862V16.532H9.35633V16.4862L8.11333 14.8298C7.97583 14.5529 7.92908 14.277 7.97583 13.9543V9.35267C7.99111 9.38322 8.00639 9.40359 8.02167 9.42396C8.05222 9.4647 8.08278 9.50544 8.11333 9.62767L11.2438 16.6246H11.2896L14.3274 9.03C14.2807 9.30592 14.2807 9.62767 14.2807 9.85867V15.2899C14.2807 15.4283 14.2348 15.52 14.1432 15.6117L13.2228 16.4862V16.532H17.7337V16.4862Z'\n        />\n     </svg>`,\n  discordIcon: ` <svg width='24'\n        height='24'\n        viewBox='0 0 24 24'\n        fill='none'\n      >\n        <path\n          fill-rule ='evenodd'\n          clip-rule='evenodd'\n          d='M22.5417 12C22.5417 17.822 17.822 22.5417 12 22.5417C6.178 22.5417 1.45833 17.822 1.45833 12C1.45833 6.178 6.178 1.45833 12 1.45833C17.822 1.45833 22.5417 6.178 22.5417 12ZM23 12C23 18.0751 18.0751 23 12 23C5.92487 23 1 18.0751 1 12C1 5.92487 5.92487 1 12 1C18.0751 1 23 5.92487 23 12ZM10.7503 15.4042C10.6021 15.3766 10.4546 15.3449 10.3081 15.3092V15.3083L9.3882 16.3442C7.31174 16.2766 6.5124 14.8862 6.5124 14.8862C6.5124 11.7976 7.86626 9.29449 7.86626 9.29449C9.21828 8.25854 10.5064 8.28686 10.5064 8.28686L10.9101 8.76647C11.6111 8.66738 12.3223 8.66431 13.0241 8.75733C13.0583 8.75866 13.0924 8.76171 13.1264 8.76647L13.4945 8.28686C13.4945 8.28686 14.7817 8.25854 16.1346 9.29357C16.1346 9.29357 17.4876 11.7976 17.4876 14.8862C17.4876 14.8862 16.6983 16.2775 14.6218 16.3442L13.7805 15.2507C13.5238 15.3192 13.3246 15.3677 13.1839 15.3951C12.3806 15.5525 11.5547 15.5556 10.7503 15.4042ZM14.7972 12.9523C14.7972 12.4498 14.3633 12.0387 13.8143 12.0387C13.2652 12.0387 12.8231 12.4498 12.8322 12.9523C12.8322 13.4547 13.2661 13.8658 13.8143 13.8658C14.3542 13.8658 14.7972 13.4547 14.7972 12.9523ZM11.281 12.9523C11.281 12.4498 10.8471 12.0387 10.299 12.0387C9.74996 12.0387 9.31603 12.4498 9.31603 12.9523C9.31603 13.4547 9.74996 13.8658 10.299 13.8658C10.838 13.8658 11.281 13.4547 11.281 12.9523Z'\n        />\n     </svg>`,\n  blackSvg: `<svg id='bgAlpha' width='3958' height='1453' viewBox='0 0 3958 1453' fill='none' xmlns='http://www.w3.org/2000/svg'>\n<path d='M2135.57 466.105C2094 466.105 2052.43 474.805 2009.89 492.203C1925.78 526.034 1840.71 588.861 1754.67 671.988C1711.17 714.517 1670.56 758.98 1633.83 804.409C1622.23 818.908 1610.63 833.407 1599.02 847.906C1593.22 855.638 1588.39 862.404 1585.49 865.304L1569.05 888.502L1552.62 865.304C1549.72 861.438 1545.85 855.638 1539.09 847.906C1527.48 833.407 1515.88 818.908 1504.28 804.409C1467.55 758.98 1426.94 714.517 1383.44 671.988C1297.4 587.895 1212.33 525.067 1128.22 492.203C1085.68 475.771 1044.11 466.105 1002.54 466.105C739.586 466.105 524.001 664.255 524.001 912.667C524.001 1161.08 739.586 1359.23 1002.54 1359.23C1044.11 1359.23 1085.68 1350.53 1128.22 1333.13C1212.33 1299.3 1297.4 1236.47 1383.44 1153.35C1426.94 1110.82 1467.55 1066.35 1504.28 1020.92C1515.88 1006.43 1527.48 991.926 1539.09 977.428C1544.89 969.695 1549.72 962.929 1552.62 960.029L1569.05 936.831L1585.49 960.029C1588.39 963.895 1592.26 969.695 1599.02 977.428C1610.63 991.926 1622.23 1006.43 1633.83 1020.92C1670.56 1066.35 1711.17 1110.82 1754.67 1153.35C1840.71 1237.44 1925.78 1300.27 2009.89 1333.13C2052.43 1349.56 2094 1359.23 2135.57 1359.23C2398.52 1359.23 2614.11 1161.08 2614.11 912.667C2614.11 664.255 2398.52 466.105 2135.57 466.105Z' stroke='url(#paint0_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M2637.31 906.87C2640.21 1150.45 2442.02 1365.03 2160.7 1359.23C2119.13 1359.23 2076.59 1349.56 2033.09 1333.13C1947.05 1299.3 1860.04 1236.47 1773.04 1153.35C1728.57 1110.82 1686.99 1066.36 1649.29 1020.93C1636.72 1006.43 1625.12 991.93 1613.52 977.431C1606.76 969.698 1602.89 962.932 1599.99 960.032L1582.59 936.834L1565.18 959.066C1562.28 961.965 1558.42 967.765 1551.65 975.498C1540.05 989.996 1528.45 1003.53 1515.88 1017.06C1478.18 1059.59 1436.61 1103.09 1393.1 1143.68C1306.1 1223.91 1220.06 1282.87 1134.98 1313.8C1092.45 1329.27 1049.91 1337.97 1008.34 1337C742.483 1334.1 521.098 1143.68 518.198 905.904C517.231 864.341 523.999 825.677 536.566 787.981C595.538 605.297 776.319 488.34 999.638 484.474C1041.21 484.474 1083.74 492.206 1126.28 507.672C1137.88 511.538 1149.48 516.371 1161.08 522.17C1234.56 555.034 1309 609.163 1384.4 677.79C1427.91 718.387 1469.48 760.916 1507.18 803.446C1518.78 816.978 1531.35 830.51 1542.95 845.009C1549.72 852.742 1553.58 858.541 1556.48 861.441L1573.89 883.672L1591.29 860.474C1594.19 856.608 1598.05 850.808 1604.82 843.076C1616.42 828.577 1628.02 813.112 1640.59 798.613C1678.29 753.184 1719.86 707.754 1763.37 665.225C1850.38 580.165 1936.42 517.338 2022.46 483.507C2065.96 466.109 2107.53 457.409 2149.1 456.443C2413.02 456.443 2633.44 652.659 2637.31 906.87Z' stroke='url(#paint1_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M2660.51 901.063C2666.31 1138.84 2485.53 1370.82 2185.84 1360.19C2143.3 1359.22 2100.77 1350.52 2057.26 1333.13C1969.29 1299.29 1881.31 1235.5 1792.37 1152.37C1746.94 1109.84 1704.4 1064.42 1665.73 1019.95C1653.16 1005.45 1640.59 990.955 1628.99 976.456C1622.23 968.723 1618.36 961.957 1615.46 959.058C1614.49 959.058 1598.06 935.86 1598.06 935.86C1597.09 935.86 1580.66 958.091 1580.66 957.124C1577.76 960.024 1572.92 965.824 1567.12 973.556C1555.52 987.088 1542.95 1000.62 1530.39 1013.19C1491.72 1053.78 1449.18 1095.35 1404.71 1133.04C1315.77 1209.4 1228.76 1264.5 1142.72 1293.5C1099.22 1307.99 1056.68 1315.73 1015.11 1314.76C746.354 1307.99 519.168 1126.28 512.401 899.129C511.434 860.466 517.235 822.769 529.802 787.972C588.774 610.121 766.655 509.597 996.741 502.831C1038.31 501.864 1081.81 509.597 1125.32 524.095C1136.92 527.962 1148.52 532.795 1161.09 537.628C1236.49 568.558 1311.9 619.787 1387.31 684.548C1431.78 723.211 1474.31 763.808 1512.98 804.404C1525.55 816.97 1537.15 830.502 1548.75 844.034C1555.52 851.767 1559.39 856.6 1562.29 859.5C1563.25 859.5 1579.69 880.764 1579.69 880.764C1580.66 880.764 1597.09 857.566 1597.09 856.6C1599.99 852.734 1604.83 846.934 1610.63 839.201C1622.23 823.736 1634.79 809.237 1646.4 794.739C1685.07 749.309 1727.6 702.913 1772.07 660.384C1861.01 575.324 1948.02 510.563 2035.03 475.766C2078.53 458.368 2121.07 448.702 2163.6 447.735C2428.49 445.802 2653.75 642.019 2660.51 901.063Z' stroke='url(#paint2_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M2683.71 896.235C2692.41 1129.18 2528.07 1377.59 2210.01 1362.13C2166.5 1361.16 2123 1351.5 2079.5 1334.1C1989.59 1299.3 1899.68 1236.47 1809.77 1153.35C1763.37 1110.82 1719.87 1065.39 1680.23 1020.92C1667.66 1006.43 1655.09 991.927 1642.53 976.461C1635.76 968.729 1630.93 962.929 1628.03 959.063C1627.06 958.096 1610.62 935.865 1609.66 935.865C1608.69 934.898 1592.26 957.13 1591.29 956.163C1588.39 959.063 1583.56 963.896 1576.79 971.629C1565.19 985.161 1552.62 996.76 1539.08 1009.33C1499.45 1047.99 1455.94 1086.65 1411.47 1123.38C1321.57 1194.91 1233.59 1247.1 1146.59 1274.17C1103.08 1287.7 1059.58 1294.47 1017.04 1292.53C745.386 1282.87 512.4 1108.88 502.732 892.369C500.799 855.639 507.566 820.842 519.167 787.011C579.105 613.027 754.086 529.9 989.006 520.235C1031.54 519.268 1075.05 526.034 1118.55 539.566C1130.15 543.433 1142.72 547.299 1154.32 552.132C1230.69 581.129 1307.07 628.492 1383.44 690.353C1428.88 727.083 1471.41 764.78 1511.05 803.443C1523.62 816.009 1536.18 828.574 1547.79 841.14C1554.55 847.906 1559.39 853.706 1562.29 856.605C1563.25 855.639 1579.69 877.87 1580.65 876.903C1581.62 875.937 1598.06 853.705 1599.02 852.739C1601.92 848.873 1606.76 843.073 1613.52 835.34C1625.13 819.875 1637.69 805.376 1650.26 790.878C1689.9 744.482 1732.43 698.086 1777.87 655.556C1867.78 569.53 1956.72 504.769 2044.69 469.006C2089.16 451.607 2132.67 440.975 2175.2 440.008C2442.99 435.175 2674.05 630.425 2683.71 896.235Z' stroke='url(#paint3_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M2707.87 890.438C2719.47 1118.55 2572.53 1384.36 2236.1 1363.1C2192.6 1362.13 2148.13 1352.46 2103.66 1335.07C2011.82 1300.27 1919.98 1236.47 1829.1 1154.31C1781.73 1111.79 1737.26 1066.36 1696.66 1020.93C1683.12 1006.43 1670.55 991.929 1657.99 976.464C1651.22 968.731 1646.39 962.931 1643.49 959.065C1642.52 958.099 1626.08 935.867 1625.12 935.867C1624.15 934.901 1607.72 956.165 1606.75 955.199C1603.85 958.099 1599.02 962.931 1592.25 969.698C1579.68 982.263 1567.11 993.862 1554.55 1005.46C1513.94 1042.19 1469.47 1078.92 1424.03 1112.75C1333.16 1180.41 1243.25 1229.71 1155.28 1253.87C1110.81 1266.44 1067.3 1272.24 1024.77 1270.3C750.212 1256.77 511.425 1091.49 497.891 885.605C495.957 850.808 501.758 818.911 513.359 787.014C574.264 617.862 745.378 551.167 987.065 538.602C1029.6 536.669 1073.11 542.468 1118.54 555.034C1130.14 557.934 1142.71 562.766 1155.28 566.633C1232.62 592.731 1309.96 638.16 1388.26 696.155C1433.7 730.952 1478.17 766.715 1517.81 803.445C1530.38 815.044 1543.91 826.643 1555.51 839.209C1562.28 845.975 1567.11 850.808 1570.01 853.708C1570.98 852.741 1587.41 874.006 1588.38 873.039C1589.35 872.073 1605.78 849.841 1606.75 848.875C1609.65 845.008 1614.48 839.209 1621.25 830.51C1633.82 815.044 1646.39 800.546 1658.95 785.08C1699.56 738.684 1743.06 692.288 1789.46 648.792C1881.31 561.8 1971.21 496.072 2060.15 460.309C2104.62 441.944 2149.09 432.278 2191.63 430.345C2457.49 424.545 2694.34 618.828 2707.87 890.438Z' stroke='url(#paint4_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M2731.08 884.632C2744.62 1107.91 2616.04 1390.15 2261.24 1364.06C2216.77 1362.12 2172.3 1352.46 2126.86 1335.06C2033.09 1299.3 1940.28 1236.47 1847.47 1154.31C1799.14 1111.78 1753.7 1066.35 1712.13 1020.92C1698.6 1006.42 1685.06 991.923 1672.49 976.457C1665.73 968.725 1660.89 962.925 1657.99 959.059C1657.03 958.092 1639.62 935.861 1638.66 934.894C1637.69 933.928 1620.29 954.226 1619.32 953.259C1616.42 956.159 1611.59 960.992 1604.82 966.792C1592.25 978.391 1578.72 989.99 1566.15 1000.62C1524.58 1035.42 1480.11 1070.22 1432.74 1102.11C1339.93 1165.91 1249.06 1211.34 1160.12 1233.57C1115.65 1245.17 1072.14 1250 1028.64 1247.1C751.184 1230.67 506.597 1073.12 489.195 877.866C486.295 845.002 492.095 815.038 503.696 786.041C565.568 620.755 732.815 572.426 981.269 555.994C1023.81 554.061 1068.28 558.894 1113.71 570.493C1126.28 573.393 1137.88 577.259 1150.45 581.125C1228.76 605.29 1307.06 646.853 1386.34 701.948C1432.74 734.812 1478.18 768.642 1518.78 802.473C1532.31 813.105 1544.88 824.704 1557.45 836.303C1564.22 843.069 1569.05 847.902 1571.95 849.835C1572.92 848.869 1589.35 869.167 1591.29 868.2C1592.25 867.234 1608.69 845.002 1610.62 844.036C1613.52 840.169 1618.36 834.37 1625.12 825.671C1637.69 810.205 1650.26 795.707 1663.79 780.241C1705.36 732.879 1749.83 686.483 1796.24 642.02C1889.04 555.028 1980.89 488.333 2070.79 451.603C2116.23 433.238 2160.7 422.606 2204.2 421.639C2471.99 414.873 2713.68 607.223 2731.08 884.632Z' stroke='url(#paint5_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M2754.28 878.833C2769.75 1097.28 2659.54 1395.95 2285.41 1365.02C2240.94 1363.09 2195.51 1352.46 2150.07 1336.03C2054.36 1300.26 1959.62 1236.47 1865.84 1155.28C1816.54 1112.75 1770.14 1067.32 1727.6 1021.89C1714.07 1007.39 1700.53 992.89 1687 977.425C1680.23 969.692 1675.4 963.893 1671.53 960.026C1669.59 959.06 1653.16 936.828 1652.19 935.862C1650.26 934.895 1633.83 954.227 1632.86 953.26C1628.99 955.193 1624.16 960.026 1617.39 965.826C1604.82 977.425 1591.29 988.057 1577.75 997.723C1535.22 1030.59 1489.78 1062.48 1442.41 1093.41C1348.63 1153.34 1256.79 1194.91 1166.89 1215.2C1121.45 1224.87 1077.95 1229.7 1034.44 1226.8C754.085 1207.47 503.698 1056.68 483.396 873.034C480.496 843.07 486.297 815.039 496.931 787.975C560.736 627.522 723.15 595.625 978.371 576.293C1021.87 574.36 1066.34 578.226 1112.75 587.892C1125.32 590.792 1136.92 593.692 1149.48 597.558C1228.76 618.823 1308.03 658.453 1388.27 709.681C1435.64 740.612 1481.08 771.543 1522.65 804.406C1536.18 815.039 1549.72 824.705 1562.29 836.304C1569.05 842.103 1573.89 846.936 1576.79 848.869C1578.72 847.903 1595.16 867.234 1596.12 866.268C1598.06 865.301 1614.49 843.07 1615.46 842.103C1618.36 838.237 1624.16 831.471 1629.96 823.738C1642.53 808.273 1656.06 792.808 1669.59 778.309C1712.13 730.946 1757.57 683.584 1803.97 639.121C1898.71 551.162 1990.55 483.501 2082.4 446.771C2127.83 428.406 2173.27 416.807 2217.74 415.84C2487.46 404.241 2733.98 595.625 2754.28 878.833Z' stroke='url(#paint6_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M2777.48 873.034C2794.89 1086.65 2702.08 1402.72 2310.55 1365.02C2265.11 1363.09 2218.7 1352.46 2173.27 1335.06C2075.63 1298.33 1979.92 1235.5 1884.21 1154.31C1833.94 1111.78 1786.57 1066.35 1743.06 1020.92C1728.56 1006.42 1715.03 991.924 1701.49 976.458C1694.73 968.726 1689.89 962.926 1686.03 959.06C1684.09 958.093 1667.66 936.828 1665.73 934.895C1663.79 933.929 1647.36 952.294 1645.42 951.327C1641.56 953.26 1636.72 958.093 1629.96 963.893C1617.39 974.525 1602.89 984.191 1589.35 993.857C1545.85 1024.79 1499.44 1054.75 1451.11 1082.78C1355.4 1138.84 1262.59 1176.54 1171.72 1194.91C1126.28 1203.61 1081.81 1207.47 1037.34 1203.61C754.083 1182.34 497.895 1040.25 474.693 866.268C470.826 838.237 476.627 813.106 487.261 787.975C552.033 632.355 711.546 616.89 971.601 594.658C1015.1 591.759 1060.54 595.625 1106.95 604.324C1119.51 606.257 1132.08 610.124 1144.65 613.023C1225.86 632.355 1305.13 668.119 1386.34 716.448C1434.67 745.445 1481.08 774.443 1523.61 804.407C1537.15 814.072 1550.68 823.738 1563.25 833.404C1570.02 839.204 1574.85 843.07 1578.72 845.003C1580.65 844.037 1597.09 862.402 1598.05 861.435C1599.99 860.468 1616.42 838.237 1618.35 837.27C1622.22 833.404 1627.06 826.638 1633.82 818.905C1647.36 803.44 1659.92 787.975 1673.46 772.51C1716.96 724.18 1762.4 676.818 1810.74 632.355C1906.45 543.43 2000.22 475.769 2093.03 438.072C2139.43 418.74 2184.87 408.108 2229.34 406.175C2501.96 393.609 2753.32 583.059 2777.48 873.034Z' stroke='url(#paint7_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M2800.69 868.203C2820.03 1076.02 2745.59 1409.49 2335.69 1366.96C2289.28 1364.06 2242.88 1353.43 2196.47 1337C2096.9 1300.26 1999.26 1237.44 1902.58 1156.24C1851.34 1112.75 1803.01 1068.29 1758.54 1022.86C1744.04 1008.36 1729.53 993.858 1716 978.393C1709.23 970.66 1703.43 964.861 1699.57 960.995C1697.63 960.028 1681.2 938.763 1679.26 936.83C1677.33 935.863 1660.9 954.228 1658.96 952.295C1655.1 954.228 1650.26 958.095 1643.49 963.894C1629.96 974.527 1616.43 983.226 1601.92 991.925C1557.45 1020.92 1510.08 1048.95 1461.75 1075.05C1365.07 1127.25 1271.3 1162.04 1179.46 1177.51C1134.02 1185.24 1088.58 1188.14 1044.11 1184.28C757.954 1158.18 495.966 1023.82 468.897 860.47C464.063 834.372 469.864 812.141 480.498 787.976C547.204 637.189 701.883 638.156 968.705 612.058C1013.18 609.159 1058.61 612.058 1105.98 618.824C1118.55 620.758 1131.12 623.657 1143.69 626.557C1225.86 642.989 1307.07 676.819 1388.27 721.282C1436.61 747.38 1483.98 775.411 1527.48 803.442C1541.02 812.141 1555.52 820.84 1568.09 830.506C1574.86 836.305 1579.69 840.172 1583.56 841.138C1585.49 839.205 1601.92 857.57 1603.86 855.637C1605.79 853.704 1622.23 832.439 1624.16 830.506C1628.03 826.64 1632.86 819.874 1639.63 812.141C1653.16 796.676 1666.7 781.21 1680.23 765.745C1724.7 717.416 1771.11 669.087 1819.44 624.624C1917.08 534.732 2011.82 466.104 2105.6 428.408C2152 409.076 2198.41 397.477 2243.84 395.544C2516.47 382.978 2773.62 571.462 2800.69 868.203Z' stroke='url(#paint8_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M2823.89 862.405C2844.19 1065.39 2789.09 1415.29 2359.85 1367.93C2313.45 1365.03 2266.08 1354.4 2218.71 1337C2117.2 1300.27 2017.63 1236.47 1919.98 1156.25C1867.78 1112.75 1818.48 1068.29 1773.04 1022.86C1758.54 1008.36 1744.04 993.86 1729.54 978.395C1722.77 970.662 1716.97 964.862 1713.1 960.03C1710.2 958.096 1694.73 937.798 1691.83 935.865C1688.93 933.932 1673.46 952.297 1670.56 950.364C1666.7 952.297 1661.86 956.163 1654.13 960.996C1640.59 970.662 1626.09 979.361 1611.59 987.094C1566.16 1014.16 1517.82 1040.26 1468.51 1064.42C1369.91 1112.75 1275.16 1143.68 1182.36 1157.21C1135.95 1163.98 1090.52 1165.91 1046.05 1161.08C756.988 1131.11 489.199 1005.46 458.263 852.739C453.429 828.574 458.263 808.276 468.897 787.011C537.536 642.024 687.382 659.422 960.971 629.458C1005.44 626.559 1051.85 627.525 1099.22 634.291C1111.78 636.224 1124.35 638.158 1137.89 641.057C1221.03 655.556 1303.2 685.52 1386.34 727.083C1435.64 751.248 1483.98 776.379 1528.45 802.477C1542.95 811.176 1556.49 818.909 1570.02 827.608C1576.79 832.441 1582.59 836.307 1585.49 838.24C1587.42 836.307 1603.86 853.705 1605.79 851.772C1607.73 849.839 1624.16 828.574 1626.09 826.641C1629.96 822.775 1634.79 816.009 1641.56 808.276C1655.1 792.811 1669.6 777.345 1683.13 761.88C1728.57 712.584 1775.94 665.222 1825.24 619.793C1923.85 529.9 2020.53 460.306 2115.27 420.677C2162.64 401.345 2209.04 388.779 2255.45 386.846C2530.97 373.314 2792.96 558.898 2823.89 862.405Z' stroke='url(#paint9_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M2847.09 856.608C2868.36 1054.76 2832.59 1421.09 2384.98 1368.9C2337.61 1366 2290.24 1354.4 2241.91 1337C2137.5 1299.3 2037.92 1236.48 1938.35 1156.25C1885.18 1112.75 1833.94 1068.29 1788.5 1021.89C1773.03 1007.4 1758.53 992.897 1744.03 977.431C1737.26 969.699 1731.46 963.899 1727.6 959.066C1724.7 957.133 1708.26 936.835 1706.33 934.902C1703.43 932.968 1686.99 950.367 1685.06 948.434C1681.19 949.4 1675.39 953.267 1668.62 958.1C1655.09 966.799 1639.62 974.532 1625.12 982.264C1578.72 1007.4 1529.41 1030.59 1480.11 1052.82C1380.53 1097.29 1284.83 1124.35 1190.08 1135.95C1143.68 1141.75 1097.28 1142.72 1052.81 1137.88C760.849 1105.02 488.226 986.131 452.457 845.01C446.656 822.778 452.457 805.38 462.124 786.048C533.664 645.893 677.709 679.724 958.066 646.86C1002.54 642.994 1049.91 643.96 1097.28 649.76C1109.84 650.726 1123.38 653.626 1135.95 655.559C1220.05 667.158 1303.19 695.189 1387.3 732.886C1437.57 755.117 1485.91 778.315 1531.35 801.513C1545.85 809.246 1560.35 816.012 1573.88 824.711C1580.65 829.544 1586.45 833.41 1590.32 834.377C1593.22 832.444 1608.69 848.876 1611.59 846.943C1614.49 845.009 1629.95 823.745 1632.86 821.812C1636.72 817.945 1642.52 811.179 1649.29 803.446C1662.82 787.015 1677.33 771.549 1691.83 757.05C1738.23 707.755 1786.57 659.426 1835.87 613.996C1936.41 523.138 2034.05 453.544 2129.76 412.947C2178.1 392.649 2224.5 381.05 2270.91 378.15C2545.46 362.685 2813.25 547.302 2847.09 856.608Z' stroke='url(#paint10_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M2870.29 850.81C2892.52 1044.13 2875.12 1427.86 2410.12 1369.87C2361.78 1366 2313.44 1355.37 2266.07 1337.97C2159.73 1300.27 2058.22 1236.48 1957.68 1156.25C1903.54 1112.75 1851.34 1068.29 1803.97 1021.9C1788.5 1007.4 1773.03 992.898 1759.5 977.433C1751.76 969.7 1746.93 963.901 1742.1 959.068C1739.2 957.134 1722.76 936.836 1719.86 934.903C1716.96 932.97 1700.53 949.402 1697.63 947.469C1693.76 948.435 1687.96 952.302 1680.22 957.134C1665.72 965.834 1651.22 972.6 1635.75 979.366C1588.38 1002.56 1538.11 1023.83 1487.84 1044.13C1387.3 1084.72 1289.66 1107.92 1194.92 1117.59C1147.55 1122.42 1102.11 1122.42 1055.71 1116.62C760.848 1080.86 482.425 968.733 443.755 839.211C437.955 818.913 438.921 802.481 452.456 787.016C497.893 641.062 666.107 701.957 952.264 666.193C997.701 662.327 1045.07 662.327 1093.41 666.193C1105.98 667.16 1119.51 669.093 1132.08 671.026C1218.12 680.692 1301.26 705.823 1386.33 739.653C1437.57 759.952 1486.87 780.25 1532.31 802.481C1546.81 809.247 1562.28 816.013 1575.82 823.746C1582.58 827.612 1588.38 831.479 1592.25 832.445C1595.15 830.512 1610.62 845.977 1613.52 844.044C1616.42 842.111 1631.89 820.846 1634.79 818.913C1638.65 814.08 1644.45 808.281 1651.22 800.548C1665.72 784.116 1680.22 768.651 1694.73 753.186C1741.13 703.89 1790.43 654.594 1841.67 609.165C1943.18 517.34 2042.75 446.779 2139.43 406.183C2187.77 385.884 2235.14 373.319 2282.51 370.419C2559.96 352.054 2832.59 534.738 2870.29 850.81Z' stroke='url(#paint11_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M2892.53 845.007C2915.73 1033.49 2917.67 1433.66 2433.33 1370.83C2384.99 1366.96 2335.68 1355.36 2287.35 1337.96C2179.07 1299.3 2075.63 1236.47 1974.12 1156.25C1919.02 1112.75 1865.85 1068.29 1817.51 1021.89C1802.04 1007.39 1786.57 991.928 1772.07 977.429C1764.34 969.696 1758.54 963.897 1754.67 959.064C1751.77 957.131 1735.33 936.833 1732.43 934.899C1729.53 932.966 1713.1 948.432 1709.23 946.498C1704.4 947.465 1699.56 951.331 1691.83 955.198C1677.33 962.93 1661.86 969.696 1646.39 975.496C1598.06 996.761 1547.79 1016.09 1496.55 1034.46C1394.07 1071.19 1296.43 1091.49 1199.76 1097.29C1152.39 1100.18 1105.98 1100.18 1059.58 1094.39C761.82 1054.76 478.564 951.331 435.06 832.442C428.293 815.043 429.259 799.578 442.794 787.012C487.264 643.958 653.545 723.218 945.502 684.555C990.939 679.722 1038.31 679.722 1087.61 682.621C1100.18 683.588 1113.72 684.555 1127.25 685.521C1214.26 692.287 1299.33 714.519 1384.41 745.449C1436.61 763.814 1486.88 782.179 1533.28 801.511C1547.79 807.311 1563.25 813.11 1576.79 820.843C1584.52 824.709 1589.36 827.609 1593.22 828.575C1596.12 825.676 1612.56 842.107 1615.46 839.208C1618.36 836.308 1634.79 816.01 1637.69 814.077C1641.56 809.244 1647.36 803.444 1654.13 794.745C1668.63 778.313 1683.13 762.848 1697.63 747.382C1745 697.12 1795.27 647.824 1846.51 601.429C1949.95 509.603 2049.53 438.076 2148.14 396.513C2197.44 376.215 2245.78 362.683 2293.15 359.783C2574.47 342.385 2851.93 522.169 2892.53 845.007Z' stroke='url(#paint12_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M2915.73 839.209C2939.89 1021.89 2961.16 1439.46 2458.45 1370.83C2409.15 1366.96 2359.85 1355.36 2310.54 1337.97C2200.33 1299.3 2095.92 1235.51 1992.48 1156.25C1936.41 1112.75 1882.27 1067.32 1832.97 1021.89C1817.5 1007.39 1801.07 991.929 1786.56 977.43C1778.83 969.698 1773.03 963.898 1769.16 959.065C1765.3 957.132 1749.83 936.834 1745.96 934.901C1742.09 932.968 1726.63 947.466 1722.76 945.533C1717.93 946.5 1712.13 949.4 1705.36 953.266C1690.86 960.999 1674.42 965.832 1659.92 971.631C1610.62 989.996 1559.38 1007.39 1507.18 1023.83C1403.73 1055.72 1304.16 1073.12 1207.48 1076.99C1160.11 1078.92 1112.74 1077.96 1066.34 1071.19C765.68 1028.66 476.623 931.035 430.219 824.71C423.452 809.245 423.452 796.68 436.986 785.081C480.49 645.893 644.837 743.518 943.562 700.988C989.965 696.155 1037.34 694.222 1087.61 696.155C1101.14 696.155 1113.71 698.088 1127.24 698.088C1215.22 702.921 1301.26 722.253 1388.27 749.317C1441.44 765.749 1491.71 782.181 1539.08 799.579C1554.55 805.379 1570.01 810.212 1583.55 816.978C1591.28 820.844 1596.12 823.744 1600.95 823.744C1603.85 820.844 1620.28 836.309 1623.18 833.41C1626.08 830.51 1642.52 810.212 1645.42 808.279C1649.29 803.446 1655.09 797.646 1662.82 788.947C1677.32 772.515 1692.79 757.05 1707.29 741.584C1755.63 691.322 1806.87 641.06 1859.07 594.664C1963.48 501.872 2064.99 429.378 2164.56 387.815C2213.87 366.551 2263.17 353.985 2310.54 350.119C2588 331.754 2871.25 509.605 2915.73 839.209Z' stroke='url(#paint13_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M2937.97 834.374C2963.1 1012.23 3003.71 1447.19 2482.63 1372.76C2432.36 1367.93 2383.06 1356.33 2332.78 1338.93C2220.64 1299.3 2114.3 1236.47 2009.89 1157.21C1952.85 1113.72 1897.75 1068.29 1847.48 1022.86C1831.04 1008.36 1815.58 992.894 1800.11 977.429C1792.37 969.696 1786.57 963.896 1781.74 959.064C1777.87 957.13 1761.44 936.832 1758.54 934.899C1754.67 931.999 1738.24 947.465 1734.37 944.565C1729.53 945.531 1723.73 948.431 1716 951.331C1700.53 958.097 1685.06 962.93 1669.6 968.729C1619.33 985.161 1567.12 1000.63 1514.92 1015.13C1409.54 1043.16 1309.97 1056.69 1211.36 1058.62C1163.02 1059.59 1115.65 1057.65 1068.28 1050.89C764.721 1005.46 470.83 914.601 419.593 819.876C411.859 806.344 411.859 795.711 425.393 787.012C466.963 651.69 630.344 766.714 935.835 721.284C982.239 716.451 1030.58 712.585 1080.85 714.518C1094.38 714.518 1107.92 715.485 1121.45 715.485C1210.39 717.418 1297.4 733.85 1385.37 758.015C1438.54 772.513 1490.75 786.045 1539.09 801.511C1554.55 806.344 1570.02 810.21 1584.52 816.976C1592.26 819.876 1597.09 822.775 1601.92 822.775C1605.79 819.876 1621.26 834.374 1624.16 831.475C1628.03 828.575 1643.49 808.277 1647.36 806.344C1652.19 801.511 1658 794.745 1664.76 787.012C1679.26 770.58 1694.73 755.115 1710.2 738.683C1759.5 687.454 1811.71 637.192 1863.91 590.796C1970.25 497.037 2072.73 424.544 2173.27 382.014C2223.54 360.749 2272.85 347.217 2321.18 343.351C2602.51 321.119 2890.6 497.037 2937.97 834.374Z' stroke='url(#paint14_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M2960.2 828.576C2986.3 1001.59 3045.28 1452.99 2505.83 1373.73C2455.56 1368.9 2404.32 1357.3 2355.02 1339.9C2240.94 1300.27 2132.67 1236.47 2027.29 1158.18C1968.32 1114.68 1913.21 1069.25 1861.98 1023.83C1845.54 1009.33 1829.11 993.861 1813.64 978.396C1805.91 970.663 1800.11 964.864 1795.27 960.031C1791.4 957.131 1774.97 938.766 1771.1 935.866C1767.24 932.966 1750.8 947.465 1746.93 944.565C1742.1 944.565 1736.3 947.465 1728.57 951.332C1713.1 958.098 1696.66 961.964 1681.2 966.797C1629.96 981.296 1576.79 994.828 1523.62 1006.43C1417.27 1030.59 1315.76 1040.26 1216.19 1040.26C1167.85 1040.26 1119.52 1037.36 1072.14 1029.62C765.686 980.329 465.994 896.236 410.89 813.11C403.156 800.545 402.189 793.779 415.723 787.013C456.327 655.557 618.74 787.979 930.033 739.65C976.437 733.851 1025.74 730.951 1076.98 729.984C1090.51 729.984 1104.05 730.951 1117.58 729.984C1207.49 726.118 1296.43 743.516 1384.4 763.815C1438.54 776.38 1490.75 787.979 1540.05 801.511C1555.52 805.378 1571.95 809.244 1586.45 815.043C1594.19 817.943 1599.99 820.843 1603.86 820.843C1607.72 817.943 1623.19 831.475 1627.06 828.576C1630.92 825.676 1646.39 806.344 1650.26 802.478C1655.09 797.645 1660.89 790.879 1667.66 783.146C1683.13 766.714 1698.6 750.282 1714.06 734.817C1764.34 683.588 1816.54 633.326 1869.71 585.963C1977.02 491.238 2081.43 417.778 2182.94 375.249C2233.21 353.984 2283.48 339.485 2332.78 335.619C2616.04 311.454 2908.96 484.472 2960.2 828.576Z' stroke='url(#paint15_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M2982.43 822.776C3008.54 990.961 3087.81 1458.79 2530 1374.69C2478.76 1369.86 2427.52 1357.3 2377.25 1339.9C2261.24 1300.27 2151.03 1236.47 2044.69 1158.18C1984.75 1114.68 1928.68 1069.25 1876.47 1023.82C1860.04 1009.33 1842.64 993.861 1827.17 978.395C1819.44 970.663 1813.64 964.863 1807.84 960.03C1803 957.13 1787.53 938.765 1783.67 935.866C1778.83 932.966 1763.37 946.498 1758.53 943.598C1753.7 943.598 1747.9 946.498 1740.16 949.398C1724.7 955.197 1708.26 959.064 1691.83 962.93C1639.62 975.496 1585.48 987.095 1531.35 996.76C1423.07 1017.06 1321.56 1023.82 1221.02 1020.92C1171.72 1019.96 1124.35 1016.09 1076.01 1008.36C766.649 956.164 447.623 887.537 403.152 807.31C392.518 798.611 393.485 792.812 407.019 787.979C446.656 660.39 607.136 810.21 924.229 758.981C971.599 753.182 1020.9 749.315 1072.14 747.382C1085.68 746.416 1099.21 747.382 1112.74 746.416C1204.59 743.516 1293.53 754.148 1382.47 771.547C1437.57 782.179 1490.74 791.845 1540.05 802.477C1555.51 806.344 1571.95 808.277 1587.42 814.076C1595.15 816.976 1600.95 818.909 1605.79 818.909C1609.65 816.009 1625.12 828.575 1628.99 825.675C1632.85 822.776 1648.32 803.444 1653.16 799.578C1657.99 794.745 1663.79 787.979 1671.52 780.246C1686.99 763.814 1702.46 747.382 1718.89 731.917C1770.13 679.721 1823.3 629.459 1877.44 582.097C1986.68 487.372 2092.06 412.945 2194.53 369.449C2245.77 348.184 2296.04 333.685 2345.35 328.852C2629.57 300.821 2928.3 471.906 2982.43 822.776Z' stroke='url(#paint16_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3003.71 816.97C3029.81 980.323 3129.38 1464.58 2553.2 1375.65C2501 1369.86 2449.76 1358.26 2398.52 1340.86C2280.58 1300.26 2169.4 1236.47 2061.13 1159.14C2000.22 1115.64 1943.18 1070.21 1890.01 1023.82C1872.61 1009.32 1856.18 993.855 1839.74 978.389C1832.01 970.657 1825.24 964.857 1820.41 960.024C1815.57 957.125 1800.11 938.76 1795.27 935.86C1790.44 932.96 1774.97 945.526 1770.14 942.626C1765.3 942.626 1758.53 944.559 1750.8 947.459C1734.37 952.292 1717.93 955.191 1701.5 959.058C1647.36 969.69 1593.22 978.389 1539.08 987.089C1429.84 1003.52 1326.4 1006.42 1224.89 1001.59C1175.59 999.654 1127.25 994.821 1078.91 986.122C766.653 930.06 440.859 870.132 393.488 800.538C382.854 793.772 382.854 789.906 397.355 787.973C436.025 663.284 594.572 832.436 918.432 776.374C965.803 770.574 1016.07 765.741 1068.28 762.842C1081.81 761.875 1095.35 761.875 1109.85 760.908C1202.66 756.076 1293.53 762.842 1382.47 777.34C1438.54 786.04 1492.68 792.806 1542.95 802.472C1559.39 805.371 1575.82 807.304 1591.29 811.171C1599.02 813.104 1604.82 815.037 1609.66 815.037C1613.52 811.171 1628.99 823.736 1633.82 820.837C1637.69 816.97 1654.13 798.605 1657.99 794.739C1662.83 789.906 1668.63 783.14 1676.36 775.407C1691.83 758.975 1708.26 742.543 1723.73 726.112C1775.94 673.916 1830.07 622.687 1884.21 575.325C1994.42 479.633 2100.76 404.24 2205.17 359.777C2257.38 337.545 2307.65 323.047 2357.92 318.214C2643.11 290.183 2946.67 459.335 3003.71 816.97Z' stroke='url(#paint17_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3025.94 811.175C3052.04 969.695 3171.92 1471.35 2576.4 1376.63C2524.2 1370.83 2471.99 1358.26 2419.79 1340.86C2299.91 1300.27 2186.8 1236.47 2077.56 1159.14C2015.69 1115.65 1957.69 1070.22 1903.55 1023.82C1886.15 1009.32 1868.74 993.859 1852.31 978.394C1844.58 970.661 1837.81 964.862 1832.97 960.029C1828.14 957.129 1812.67 938.764 1807.84 935.864C1803.01 932.965 1786.57 944.564 1781.74 941.664C1776.9 941.664 1770.14 943.597 1762.4 945.53C1745.97 950.363 1728.57 952.296 1712.13 955.196C1657.03 963.895 1601.92 970.661 1546.82 976.461C1435.64 989.026 1332.2 988.06 1229.72 981.294C1180.42 977.427 1131.12 972.595 1081.81 963.895C766.653 904.934 435.059 852.738 384.788 793.777C373.187 789.911 373.187 787.977 387.688 787.011C425.391 666.188 582.004 852.738 912.632 793.777C960.969 787.011 1011.24 781.211 1063.44 777.345C1076.98 776.378 1091.48 775.412 1105.01 774.445C1198.79 766.713 1290.63 771.545 1381.5 782.178C1438.54 788.944 1492.68 793.777 1543.92 800.543C1560.35 802.476 1576.79 803.443 1592.25 807.309C1599.99 809.242 1605.79 811.175 1610.62 810.209C1615.46 806.342 1630.92 817.941 1634.79 814.075C1639.63 810.209 1655.09 791.844 1658.96 787.977C1663.79 783.144 1670.56 776.378 1677.33 768.646C1692.8 752.214 1709.23 735.782 1725.67 719.35C1778.84 666.188 1832.97 614.959 1889.05 567.597C2001.19 470.938 2108.5 395.545 2213.87 350.116C2266.08 327.884 2317.31 313.385 2368.55 307.586C2655.68 280.522 2964.07 446.774 3025.94 811.175Z' stroke='url(#paint18_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3047.21 805.376C3074.28 959.063 3212.52 1477.15 2599.6 1376.63C2546.43 1370.83 2493.26 1358.26 2441.06 1339.9C2319.25 1298.33 2204.2 1235.51 2093.99 1158.18C2031.16 1114.68 1972.18 1069.25 1917.08 1022.86C1899.68 1007.39 1881.31 992.893 1864.88 977.428C1857.14 969.695 1850.37 963.896 1844.57 959.063C1839.74 956.163 1823.31 937.798 1818.47 934.898C1813.64 931.998 1797.2 942.631 1792.37 939.731C1786.57 939.731 1780.77 940.698 1772.07 942.631C1755.63 946.497 1738.23 948.43 1720.83 950.363C1664.76 957.129 1609.65 961.962 1553.58 965.829C1441.44 974.528 1336.06 970.662 1232.62 960.996C1182.35 956.163 1133.05 950.363 1083.74 940.698C765.684 878.836 427.322 833.407 374.151 786.044C361.583 784.111 361.583 784.111 376.085 786.044C412.821 669.088 568.467 873.037 904.895 811.176C953.233 804.41 1003.5 797.644 1057.64 792.811C1071.18 791.844 1085.68 790.877 1100.18 788.944C1194.92 779.278 1287.73 781.212 1378.6 788.944C1436.61 793.777 1491.71 796.677 1543.92 801.51C1560.35 803.443 1577.75 803.443 1593.22 806.343C1600.95 808.276 1606.75 809.242 1612.55 808.276C1617.39 804.41 1632.86 815.042 1637.69 811.176C1642.52 807.309 1657.99 788.944 1662.83 785.078C1667.66 780.245 1674.43 773.479 1682.16 765.746C1698.59 748.348 1715.03 731.916 1731.46 716.451C1785.6 663.289 1840.71 611.093 1896.78 562.764C2009.89 465.139 2119.13 388.779 2225.47 343.35C2278.64 321.119 2329.88 305.653 2381.12 299.854C2668.24 269.89 2982.44 434.209 3047.21 805.376Z' stroke='url(#paint19_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3074.28 799.575C3074.28 950.362 3259.89 1482.95 2627.64 1377.59C2573.5 1370.82 2520.33 1358.26 2468.13 1340.86C2344.38 1299.3 2228.37 1235.5 2116.23 1159.14C2052.43 1115.65 1992.49 1070.22 1936.42 1023.82C1918.05 1008.36 1900.65 993.858 1883.25 978.393C1875.51 970.66 1868.74 964.86 1862.94 960.027C1857.14 956.161 1841.68 938.763 1836.84 935.863C1831.04 931.997 1815.57 942.629 1809.77 939.729C1803.97 938.763 1797.2 940.696 1789.47 942.629C1772.07 946.495 1754.67 946.495 1737.27 948.429C1680.23 953.261 1624.16 955.195 1567.12 958.094C1453.04 962.927 1347.67 955.195 1242.29 943.596C1192.02 937.796 1141.75 931.03 1092.45 921.364C771.487 853.703 427.325 816.973 371.253 779.277C358.686 779.277 357.719 782.176 372.22 786.043C407.023 672.953 561.703 894.3 903.931 829.539C952.268 821.806 1003.51 815.04 1057.64 808.274C1071.18 806.341 1085.68 805.374 1100.18 803.441C1196.86 790.876 1290.63 789.909 1382.47 793.775C1441.44 796.675 1496.55 796.675 1549.72 799.575C1567.12 800.541 1583.55 799.575 1599.99 802.475C1607.72 803.441 1614.49 804.408 1619.32 803.441C1624.16 799.575 1639.63 809.241 1644.46 805.374C1649.29 801.508 1664.76 783.143 1669.59 779.277C1674.43 774.444 1681.2 767.678 1688.93 758.978C1705.36 741.58 1721.8 725.148 1739.2 708.716C1794.3 655.554 1850.38 603.359 1907.41 554.063C2022.46 458.371 2132.67 381.045 2239.97 334.649C2293.15 311.451 2345.35 295.986 2397.55 290.186C2687.58 259.255 2939.9 439.04 3074.28 799.575Z' stroke='url(#paint20_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3095.54 793.782C3095.54 939.736 3301.46 1488.75 2650.84 1378.56C2596.7 1371.8 2542.56 1359.23 2489.39 1340.87C2363.72 1299.3 2245.77 1235.51 2132.66 1158.18C2067.89 1114.69 2006.02 1069.26 1949.95 1022.86C1931.58 1007.4 1913.21 992.898 1895.81 977.432C1888.08 969.7 1880.34 963.9 1874.54 959.067C1868.74 955.201 1853.27 937.803 1847.47 934.903C1841.67 931.036 1826.21 941.669 1820.41 937.803C1814.6 936.836 1807.84 938.769 1800.1 939.736C1782.7 942.635 1764.33 942.635 1746.93 943.602C1688.93 945.535 1631.89 946.502 1574.85 946.502C1459.81 946.502 1352.5 935.869 1247.12 922.337C1195.89 915.571 1145.62 907.839 1096.31 897.206C771.485 827.612 420.555 799.581 361.584 772.517C348.049 774.45 347.083 779.283 361.584 786.049C395.42 675.859 548.166 916.538 897.162 847.91C946.466 840.178 997.703 832.445 1052.81 824.712C1067.31 822.779 1080.84 820.846 1095.34 818.913C1192.99 803.448 1287.73 806.347 1380.54 800.548C1439.51 796.682 1496.54 799.581 1549.72 799.581C1567.12 799.581 1584.52 798.615 1600.95 800.548C1608.69 801.514 1615.45 802.481 1620.29 801.515C1625.12 797.648 1640.59 806.347 1645.42 802.481C1651.22 798.615 1665.73 780.25 1671.53 775.417C1677.33 770.584 1683.13 762.851 1690.86 755.119C1707.3 737.72 1724.7 721.288 1742.1 704.856C1798.17 650.728 1855.21 598.532 1912.25 549.237C2028.26 450.645 2140.4 372.352 2248.67 325.956C2302.81 302.758 2355.98 287.293 2408.19 281.493C2699.18 249.596 2954.4 428.414 3095.54 793.782Z' stroke='url(#paint21_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3115.85 788.949C3115.85 930.07 3342.07 1496.49 2673.08 1380.5C2617.97 1373.73 2563.84 1360.2 2509.7 1342.8C2382.09 1300.27 2262.21 1236.48 2148.13 1160.12C2082.4 1116.62 2019.56 1071.19 1962.52 1024.79C1944.15 1009.33 1924.82 994.831 1907.41 979.365C1898.71 971.633 1891.95 965.833 1886.15 961C1880.35 957.134 1864.88 939.735 1859.08 936.836C1853.28 932.969 1837.81 942.635 1831.04 938.769C1825.24 937.802 1818.47 938.769 1809.77 939.735C1792.37 941.669 1774 941.669 1755.64 941.669C1696.66 941.669 1638.66 940.702 1580.65 938.769C1463.68 934.902 1355.4 921.37 1249.06 904.938C1197.82 897.206 1147.55 888.506 1096.31 877.874C769.554 805.38 411.857 785.082 349.986 769.617C335.484 774.45 334.518 781.216 349.019 789.915C381.888 683.591 532.701 941.669 888.464 870.141C937.768 862.409 989.972 853.71 1045.08 844.044C1059.58 842.111 1074.08 840.177 1088.58 837.278C1187.19 819.879 1283.86 818.913 1377.64 810.213C1437.58 804.414 1495.58 804.414 1549.72 803.447C1567.12 802.481 1584.52 798.614 1601.92 802.481C1609.66 804.414 1616.42 803.447 1622.22 802.481C1628.02 797.648 1642.53 807.314 1648.33 802.481C1654.13 797.648 1668.63 780.249 1674.43 775.416C1680.23 769.617 1687 762.851 1694.73 755.118C1712.13 737.72 1729.53 721.288 1745.97 704.856C1803.01 650.727 1860.04 597.565 1919.02 548.27C2036.96 448.712 2149.1 370.418 2259.31 323.056C2313.45 299.858 2367.59 283.426 2419.79 277.627C2711.75 238.963 2968.9 416.814 3115.85 788.949Z' stroke='url(#paint22_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3137.11 783.142C3137.11 919.43 3383.63 1502.28 2695.31 1381.46C2639.24 1373.72 2584.13 1361.16 2530 1342.79C2400.45 1300.26 2279.61 1236.47 2163.6 1160.11C2096.89 1115.65 2033.09 1071.18 1975.08 1023.82C1955.75 1008.36 1937.38 993.856 1919.01 978.391C1910.31 970.658 1903.55 964.859 1897.74 960.026C1890.98 956.16 1875.51 939.728 1869.71 935.862C1862.94 931.995 1847.47 940.694 1841.67 936.828C1835.87 935.862 1828.14 936.828 1820.4 936.828C1802.04 938.761 1783.67 936.828 1766.27 936.828C1706.33 934.895 1647.36 931.029 1589.35 928.129C1471.41 920.396 1362.17 902.998 1254.86 884.633C1203.62 875.933 1152.38 866.268 1101.15 854.669C771.485 779.275 407.021 766.71 343.216 760.91C327.748 767.676 326.781 776.375 341.282 787.008C373.185 684.55 523.031 960.026 884.594 885.599C934.865 876.9 987.069 868.201 1043.14 857.568C1057.64 854.669 1072.14 852.735 1086.64 849.836C1187.19 829.537 1283.86 819.872 1378.6 814.072C1439.51 810.206 1497.51 804.406 1552.62 800.54C1570.02 799.573 1588.39 793.774 1604.82 797.64C1612.55 799.573 1619.32 798.607 1625.12 796.674C1630.92 791.841 1645.42 800.54 1651.22 795.707C1657.02 790.874 1672.49 773.476 1678.29 768.643C1684.09 762.843 1690.86 756.077 1698.59 748.345C1716 730.946 1733.4 714.514 1750.8 697.116C1808.8 642.02 1866.81 588.858 1925.78 539.563C2044.69 440.005 2158.77 360.745 2269.94 312.416C2325.05 288.251 2379.18 271.819 2432.36 266.02C2724.31 228.323 2982.43 405.208 3137.11 783.142Z' stroke='url(#paint23_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3157.42 777.342C3157.42 908.797 3423.27 1508.08 2717.55 1382.42C2661.47 1374.69 2605.4 1361.16 2551.26 1343.76C2419.79 1300.26 2297.01 1237.44 2180.03 1161.08C2112.36 1116.61 2047.59 1072.15 1988.62 1024.79C1969.28 1009.32 1949.95 994.823 1931.58 978.391C1922.88 971.625 1916.11 964.859 1909.34 960.026C1902.58 956.16 1887.11 939.728 1881.31 934.895C1874.54 931.028 1859.07 938.761 1852.31 934.895C1846.51 933.928 1838.77 933.928 1831.04 934.895C1812.67 935.861 1794.3 933.928 1775.93 932.962C1715.03 929.095 1655.09 923.296 1596.12 917.496C1476.24 905.897 1366.03 884.633 1257.76 864.334C1205.55 854.669 1154.32 844.036 1103.08 832.437C770.517 754.144 400.253 749.311 332.581 754.144C317.113 762.843 315.179 774.442 329.681 787.008C360.616 688.416 508.529 981.291 876.859 903.964C927.13 895.265 980.301 884.633 1036.37 874C1050.87 871.1 1065.37 868.201 1079.88 865.301C1181.38 842.103 1279.03 829.537 1374.73 820.838C1436.61 815.039 1495.58 807.306 1551.65 801.506C1570.02 799.573 1587.42 793.774 1604.82 796.674C1612.55 797.64 1619.32 796.674 1625.12 794.74C1630.92 789.907 1646.39 797.64 1652.19 792.807C1657.99 787.974 1673.46 770.576 1679.26 765.743C1685.06 759.943 1691.83 753.177 1699.56 745.445C1716.96 728.046 1735.33 710.648 1752.73 694.216C1811.7 639.121 1870.68 584.992 1929.65 535.696C2049.52 435.172 2165.53 354.945 2277.68 306.616C2332.78 282.452 2387.88 266.02 2442.02 259.254C2735.91 218.657 2996.94 394.575 3157.42 777.342Z' stroke='url(#paint24_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3177.72 771.543C3177.72 898.165 3463.88 1514.84 2739.78 1382.42C2682.74 1374.69 2626.67 1360.19 2571.57 1342.79C2438.16 1299.3 2313.45 1235.5 2195.5 1160.11C2126.86 1115.65 2061.13 1070.22 2001.19 1023.82C1981.85 1008.36 1961.55 993.857 1943.18 977.425C1934.48 970.659 1927.71 963.892 1920.95 959.06C1914.18 955.193 1898.71 938.761 1891.95 933.928C1885.18 929.096 1869.71 936.828 1862.94 932.962C1856.18 931.029 1849.41 931.995 1840.71 931.995C1821.37 931.995 1803 930.062 1784.64 928.129C1722.76 922.329 1661.86 914.597 1602.89 906.864C1482.04 891.399 1370.87 867.234 1260.66 844.036C1208.46 833.404 1156.25 821.805 1104.05 809.239C768.585 727.08 391.554 730.946 320.981 746.411C304.547 757.044 302.613 771.543 317.114 786.041C347.084 691.316 493.062 1002.56 867.193 921.363C917.464 912.664 971.602 901.065 1028.64 888.499C1043.14 885.599 1057.64 882.7 1073.11 878.833C1175.59 853.702 1275.16 837.27 1370.87 825.671C1433.71 817.939 1492.68 807.306 1549.72 799.574C1568.08 796.674 1586.45 789.908 1603.85 792.807C1611.59 793.774 1618.36 791.841 1625.12 789.908C1630.92 785.075 1646.39 791.841 1652.19 787.008C1658.96 782.175 1673.46 764.777 1679.26 759.944C1685.06 754.144 1691.83 747.378 1700.53 739.645C1717.93 722.247 1736.3 704.848 1754.67 688.417C1814.61 632.355 1874.54 579.193 1934.48 528.931C2056.29 427.439 2173.27 347.213 2286.38 296.951C2342.45 272.786 2397.55 255.388 2451.69 248.622C2748.48 208.025 3010.47 382.977 3177.72 771.543Z' stroke='url(#paint25_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3198.99 765.751C3198.99 887.54 3505.45 1520.65 2762.02 1383.4C2704.01 1374.7 2647.94 1361.17 2591.87 1342.8C2456.53 1299.3 2329.88 1235.51 2210.97 1160.12C2141.37 1115.65 2074.66 1070.22 2013.76 1023.83C1993.46 1008.36 1974.12 993.865 1954.79 977.433C1946.08 970.667 1938.35 963.9 1932.55 959.068C1925.78 954.235 1910.31 938.769 1903.55 933.936C1896.78 929.103 1881.31 935.87 1873.58 932.003C1866.81 930.07 1860.04 930.07 1851.34 930.07C1832.01 930.07 1812.67 926.204 1794.31 924.271C1731.47 916.538 1669.59 906.872 1609.66 896.24C1486.88 876.908 1374.74 848.877 1264.53 822.779C1211.36 810.214 1159.15 798.615 1106.95 786.049C768.587 700.99 379.955 701.957 312.282 738.687C293.914 749.319 292.947 767.684 307.449 785.083C335.484 693.257 480.496 1022.86 861.395 937.803C912.632 928.137 965.803 916.538 1023.81 903.006C1038.31 899.139 1053.78 896.24 1068.28 892.373C1171.72 864.342 1272.26 845.011 1368.94 830.512C1432.74 820.846 1492.68 808.281 1549.72 798.615C1568.09 795.715 1586.45 790.882 1604.82 788.949C1612.56 787.982 1620.29 787.982 1626.09 785.083C1632.86 780.25 1647.36 786.049 1654.13 781.216C1660.89 775.417 1675.4 758.985 1682.16 754.152C1687.96 748.353 1695.7 741.587 1703.43 733.854C1721.8 716.455 1740.17 699.057 1758.54 681.658C1818.47 625.597 1879.38 571.468 1940.28 520.239C2063.06 417.781 2181.97 336.588 2296.05 286.326C2353.08 261.195 2408.19 243.797 2463.29 237.03C2760.09 198.367 3024.01 371.385 3198.99 765.751Z' stroke='url(#paint26_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3219.29 759.947C3219.29 876.903 3546.05 1526.45 2784.26 1384.36C2726.25 1375.66 2668.25 1361.16 2612.17 1343.76C2473.93 1299.3 2347.29 1235.51 2226.44 1161.08C2154.9 1116.62 2088.2 1071.19 2025.36 1024.79C2005.06 1009.33 1984.76 994.826 1965.42 978.394C1956.72 971.628 1948.99 964.862 1942.22 960.029C1934.48 955.196 1919.98 939.731 1912.25 934.898C1904.52 930.065 1889.05 936.831 1882.28 931.999C1875.51 930.065 1867.78 930.065 1860.05 929.099C1840.71 928.132 1821.38 924.266 1802.04 921.366C1738.24 910.734 1676.36 899.135 1614.49 887.536C1490.75 863.371 1377.64 832.44 1265.5 804.41C1212.32 790.877 1159.15 778.312 1106.95 764.78C765.688 675.854 370.288 686.487 299.716 732.882C280.381 745.448 279.414 766.713 293.915 786.045C320.984 698.086 465.029 1045.09 851.728 957.13C902.966 947.464 957.103 934.898 1015.11 919.433C1029.61 915.567 1045.08 911.7 1060.55 907.834C1165.92 877.87 1266.46 855.638 1365.07 837.273C1429.84 824.708 1490.75 811.176 1548.75 798.61C1567.12 794.744 1585.49 789.911 1604.82 787.011C1612.56 786.045 1620.29 785.078 1626.09 783.145C1632.86 777.345 1647.36 783.145 1654.13 777.345C1660.9 771.546 1675.4 755.114 1682.16 749.314C1688.93 743.515 1695.7 736.749 1703.43 729.016C1721.8 711.618 1740.17 694.219 1758.54 676.821C1819.44 620.759 1881.31 565.664 1943.19 514.435C2067.9 411.977 2186.81 329.818 2302.82 278.589C2359.85 253.458 2415.92 236.059 2472 228.327C2771.69 187.73 3037.54 360.748 3219.29 759.947Z' stroke='url(#paint27_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3239.59 755.112C3239.59 867.236 3585.68 1533.21 2806.49 1386.29C2747.51 1377.59 2689.51 1363.09 2632.47 1344.73C2492.29 1300.26 2363.72 1236.47 2241.91 1162.04C2169.4 1117.58 2101.73 1072.15 2037.92 1025.76C2017.62 1010.29 1996.35 994.824 1977.02 979.359C1968.32 972.593 1960.58 965.827 1953.81 960.994C1946.08 956.161 1930.61 940.696 1923.85 935.863C1916.11 931.03 1900.64 936.83 1892.91 931.997C1886.14 930.063 1878.41 929.097 1869.71 928.13C1849.41 926.197 1830.07 922.331 1810.74 918.464C1745.96 905.899 1683.13 892.367 1621.25 878.835C1495.58 850.804 1381.5 816.973 1269.36 786.043C1216.19 771.544 1163.02 758.012 1109.84 744.48C765.683 652.654 363.516 672.953 291.01 728.048C270.708 743.513 269.742 765.744 284.243 787.009C310.345 702.917 452.457 1067.32 845.923 976.459C897.16 965.827 952.265 953.261 1011.24 936.83C1025.74 932.963 1041.21 929.097 1056.67 924.264C1163.02 891.4 1265.49 866.269 1364.1 845.004C1428.87 830.505 1490.74 814.074 1549.71 800.541C1569.05 795.708 1587.42 789.909 1605.79 787.009C1613.52 786.043 1621.25 785.076 1628.02 782.176C1634.79 776.377 1649.29 781.21 1656.06 775.41C1662.82 769.611 1678.29 753.179 1685.06 747.379C1691.83 741.58 1698.59 734.814 1707.29 726.115C1725.66 707.75 1745 691.318 1763.37 673.919C1825.24 616.891 1888.08 561.796 1949.95 510.567C2075.62 407.143 2196.47 324.016 2313.44 272.788C2371.45 247.657 2427.52 229.291 2483.59 221.559C2783.28 178.063 3051.07 349.148 3239.59 755.112Z' stroke='url(#paint28_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3258.92 749.316C3258.92 856.606 3625.32 1539.98 2826.79 1387.26C2766.85 1377.59 2708.85 1363.1 2651.81 1345.7C2509.7 1301.23 2379.18 1237.44 2256.41 1163.01C2182.94 1118.55 2114.3 1073.12 2049.52 1025.76C2028.26 1010.29 2007.95 994.828 1987.65 979.362C1978.95 972.596 1971.22 965.83 1963.48 960.997C1955.75 956.164 1940.28 940.699 1932.55 935.866C1924.81 931.033 1909.35 935.866 1901.61 931.033C1894.84 928.133 1887.11 928.133 1878.41 927.167C1858.11 925.234 1838.77 919.434 1818.47 915.568C1752.73 901.069 1688.93 885.604 1626.09 869.172C1499.45 837.275 1384.4 799.578 1270.33 766.714C1216.19 751.249 1163.02 736.75 1108.88 722.251C761.817 627.526 352.883 656.524 277.477 721.285C257.175 738.683 255.241 763.814 269.743 787.012C294.878 706.786 435.056 1089.55 834.323 994.828C886.527 984.195 941.632 970.663 1000.6 952.298C1016.07 947.465 1031.54 943.599 1046.04 938.766C1153.35 903.002 1256.79 874.971 1356.37 850.807C1422.11 834.375 1484.94 816.01 1544.88 799.578C1564.22 794.745 1582.59 787.979 1601.92 784.113C1609.65 782.18 1617.39 781.213 1624.16 778.313C1630.92 772.514 1645.42 776.38 1653.16 770.581C1660.89 764.781 1675.39 748.349 1682.16 742.55C1688.93 736.75 1695.69 729.018 1704.4 721.285C1723.73 702.92 1742.1 685.521 1761.43 668.123C1824.27 611.094 1888.08 555.033 1950.92 503.804C2078.53 399.413 2200.34 316.287 2318.28 264.092C2376.28 237.994 2433.32 220.595 2490.36 211.896C2794.89 167.433 3064.61 337.552 3258.92 749.316Z' stroke='url(#paint29_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3279.23 743.512C3279.23 845.97 3665.93 1545.77 2849.02 1387.26C2789.09 1377.59 2730.11 1363.09 2672.11 1344.73C2528.06 1299.3 2396.59 1235.5 2271.88 1161.08C2197.44 1116.61 2127.83 1071.18 2062.09 1023.82C2040.82 1008.36 2019.56 992.89 1999.25 977.425C1990.55 970.659 1982.82 963.893 1975.09 959.06C1967.35 954.227 1951.88 938.761 1944.15 933.928C1935.45 929.096 1920.95 932.962 1912.25 928.129C1905.48 925.229 1896.78 924.263 1888.08 923.296C1867.78 920.396 1847.47 914.597 1827.17 909.764C1760.47 893.332 1695.7 874.967 1632.86 857.568C1504.28 821.805 1388.27 780.242 1273.23 745.445C1219.09 729.013 1164.95 713.548 1110.81 698.082C760.851 599.491 345.15 638.154 266.844 712.581C245.575 732.879 243.642 758.977 258.143 785.075C282.312 708.715 420.557 1108.88 826.59 1011.26C878.795 1000.62 934.866 985.157 994.804 966.792C1010.27 961.959 1025.74 957.126 1041.21 952.294C1149.48 914.597 1253.89 882.7 1354.43 855.635C1421.14 837.27 1483.98 816.006 1544.88 797.64C1564.22 791.841 1583.55 785.075 1602.89 780.242C1610.62 778.309 1618.36 776.376 1625.12 773.476C1632.86 767.676 1647.36 770.576 1654.13 764.777C1661.86 758.977 1676.36 742.545 1684.09 736.746C1690.86 730.946 1698.6 723.214 1706.33 715.481C1725.66 697.116 1745 679.717 1764.33 662.319C1828.14 604.324 1891.95 549.229 1955.75 497.033C2084.33 392.642 2208.07 307.583 2326.98 255.388C2385.95 229.29 2443.96 210.925 2501 202.226C2806.49 156.796 3078.14 326.915 3279.23 743.512Z' stroke='url(#paint30_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3299.53 737.72C3299.53 835.345 3706.53 1551.58 2871.26 1388.23C2810.36 1378.56 2750.42 1363.1 2692.41 1345.7C2546.43 1300.27 2413.02 1236.48 2287.35 1162.05C2211.94 1117.59 2140.4 1072.16 2074.66 1024.8C2053.39 1009.33 2031.16 993.865 2010.86 978.399C2002.16 971.633 1993.45 964.867 1986.69 960.034C1977.99 955.201 1963.49 940.703 1954.79 934.903C1946.08 929.104 1931.58 932.97 1922.88 928.137C1915.15 925.237 1907.41 924.271 1898.71 922.338C1877.45 918.471 1857.14 912.672 1836.84 906.872C1769.17 888.507 1703.43 868.209 1639.63 848.877C1510.08 809.247 1393.11 764.785 1277.1 727.088C1221.99 709.689 1167.85 693.258 1113.72 677.792C760.853 576.301 339.351 622.697 258.144 706.79C235.909 729.021 233.976 758.019 248.477 786.049C271.679 712.589 408.957 1131.12 820.791 1030.59C873.962 1019 930.033 1003.53 989.972 984.199C1005.44 979.366 1020.91 974.533 1036.38 968.734C1146.58 928.137 1251.96 894.307 1353.47 863.376C1421.14 843.078 1484.95 819.88 1546.82 799.582C1567.12 792.816 1585.49 785.083 1605.79 780.25C1613.52 778.317 1621.26 776.384 1628.99 772.517C1636.73 765.751 1651.23 769.618 1658.96 762.852C1666.69 756.085 1681.2 740.62 1688.93 734.821C1695.7 729.021 1703.43 721.288 1712.13 713.556C1731.47 695.191 1750.8 677.792 1771.1 660.394C1835.88 602.399 1900.65 546.337 1965.42 494.142C2094 385.884 2218.71 301.792 2338.58 247.663C2397.56 221.565 2456.53 202.234 2513.56 193.535C2818.09 147.139 3091.68 315.324 3299.53 737.72Z' stroke='url(#paint31_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3319.83 731.909C3319.83 824.701 3746.16 1558.34 2892.53 1389.18C2830.66 1378.55 2770.72 1364.05 2711.75 1345.69C2563.83 1299.29 2428.49 1235.5 2301.84 1162.04C2225.47 1117.58 2152.97 1072.15 2086.26 1024.78C2064.02 1009.32 2042.76 993.853 2021.49 978.387C2012.79 971.621 2004.09 964.855 1996.35 960.022C1987.65 954.223 1972.18 940.691 1964.45 934.891C1955.75 929.092 1940.28 931.991 1931.58 927.158C1923.85 924.259 1916.11 922.326 1907.41 920.392C1886.14 915.559 1865.84 908.793 1845.54 902.994C1776.9 881.729 1710.2 860.464 1646.39 838.233C1514.91 794.737 1396.97 746.408 1279.99 706.778C1224.89 688.413 1169.78 671.014 1115.65 654.582C758.917 550.191 331.615 605.287 247.508 700.012C225.272 725.143 222.372 755.107 236.873 786.037C258.142 716.443 394.453 1152.37 813.054 1048.95C866.226 1037.35 923.264 1020.92 984.169 999.652C999.637 993.853 1015.1 989.02 1031.54 983.22C1142.72 939.724 1249.06 902.994 1351.53 868.197C1420.17 844.999 1484.94 820.834 1546.82 797.636C1567.12 789.904 1586.45 782.171 1606.75 776.372C1615.45 774.438 1623.19 771.539 1629.96 767.672C1637.69 760.906 1652.19 763.806 1659.92 757.04C1667.66 750.274 1682.16 734.809 1690.86 729.009C1697.63 723.21 1705.36 715.477 1714.06 707.744C1733.4 689.379 1753.7 671.981 1773.03 653.616C1838.77 594.654 1904.51 538.592 1969.28 486.397C2100.76 380.073 2226.44 294.047 2348.25 240.885C2408.19 214.787 2467.16 195.456 2525.16 185.79C2829.69 136.494 3105.21 304.679 3319.83 731.909Z' stroke='url(#paint32_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3339.16 726.117C3339.16 814.076 3785.8 1564.14 2913.8 1390.16C2851.92 1379.53 2791.02 1364.06 2732.05 1345.7C2582.2 1299.3 2444.92 1235.51 2317.31 1162.05C2239.97 1117.58 2166.5 1072.15 2098.83 1024.79C2076.59 1009.33 2054.36 993.86 2033.09 978.395C2023.42 971.629 2015.69 964.863 2007.95 960.03C1999.25 954.23 1983.79 940.698 1975.08 934.899C1966.38 929.099 1950.92 931.999 1942.22 926.199C1934.48 923.3 1925.78 921.366 1917.08 919.433C1895.81 914.6 1874.54 906.868 1854.24 900.102C1784.64 876.904 1716.96 852.739 1652.19 829.541C1519.75 781.212 1400.84 729.983 1282.89 688.42C1227.79 669.088 1172.68 650.723 1116.61 634.291C757.95 526.034 323.881 590.795 236.874 694.22C213.672 721.284 210.771 754.148 226.239 786.045C246.541 720.317 380.919 1174.61 805.321 1067.32C858.492 1055.72 916.497 1038.32 977.402 1016.09C992.87 1010.29 1009.3 1004.49 1024.77 998.693C1136.92 953.264 1244.22 912.667 1347.67 874.97C1417.27 849.839 1482.04 822.775 1544.88 798.61C1565.18 790.878 1584.52 781.212 1604.82 775.412C1613.52 772.513 1621.26 770.58 1628.02 766.713C1636.72 759.947 1650.26 761.88 1658.96 755.114C1667.66 748.348 1681.19 732.883 1689.89 726.117C1696.66 719.351 1704.4 712.585 1713.1 704.852C1733.4 686.487 1753.7 668.122 1773.03 650.723C1839.74 591.762 1906.45 534.733 1971.22 482.538C2104.63 375.247 2231.27 289.222 2354.05 234.126C2414.95 207.062 2473.93 187.73 2532.9 178.065C2841.29 126.836 3117.78 293.088 3339.16 726.117Z' stroke='url(#paint33_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3359.46 721.284C3359.46 804.41 3826.4 1570.91 2936.03 1392.09C2873.19 1381.46 2812.28 1365.99 2752.35 1347.63C2600.57 1301.23 2462.32 1237.44 2332.78 1163.98C2254.47 1119.52 2180.03 1074.09 2111.39 1026.72C2089.16 1011.26 2066.92 995.793 2044.69 979.361C2035.02 972.595 2027.29 965.829 2019.55 960.03C2009.88 954.23 1995.38 940.698 1986.68 934.899C1977.01 929.099 1962.51 931.032 1952.85 924.266C1945.11 920.4 1936.41 918.467 1927.71 916.534C1905.48 910.734 1884.21 903.001 1863.91 895.269C1792.37 870.138 1725.66 844.04 1659.92 818.909C1526.51 766.713 1405.67 712.585 1286.76 668.122C1230.69 646.857 1175.58 628.492 1119.51 611.094C757.947 499.937 318.077 572.43 227.203 686.487C204.001 716.451 199.168 750.281 215.602 785.078C234.937 723.217 367.381 1194.91 798.551 1084.72C852.688 1072.15 909.726 1054.75 972.565 1030.59C988.033 1024.79 1004.47 1018.99 1019.94 1012.23C1133.04 963.896 1242.29 920.4 1345.73 879.803C1415.34 852.739 1482.04 823.742 1545.85 796.677C1566.15 787.978 1586.45 778.312 1606.75 771.546C1615.45 768.647 1623.19 765.747 1629.95 761.88C1638.65 755.114 1652.19 756.081 1660.89 749.315C1669.59 742.549 1684.09 727.084 1691.82 720.317C1699.56 713.551 1707.29 706.785 1715.99 699.053C1736.29 680.688 1756.6 662.322 1776.9 644.924C1844.57 584.996 1911.28 527.968 1977.98 474.806C2112.36 367.515 2240.94 280.523 2364.68 224.461C2425.59 197.396 2485.52 178.065 2544.5 167.432C2851.92 116.204 3131.31 281.489 3359.46 721.284Z' stroke='url(#paint34_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3378.8 715.484C3378.8 792.811 3866.04 1576.71 2956.33 1393.06C2892.53 1381.46 2830.66 1365.99 2770.72 1347.63C2617 1300.27 2476.83 1236.47 2346.32 1163.98C2267.04 1119.52 2191.64 1074.09 2122.03 1026.72C2098.83 1011.26 2076.59 995.793 2054.36 979.361C2044.69 972.595 2035.99 965.829 2028.26 960.03C2018.59 954.23 2004.09 940.698 1994.42 934.899C1984.75 929.099 1970.25 930.066 1960.58 923.3C1952.85 919.433 1944.15 917.5 1935.45 914.6C1913.21 907.834 1891.94 899.135 1870.68 891.402C1798.17 864.338 1730.5 836.307 1663.79 808.276C1528.45 752.215 1406.64 694.22 1286.76 647.824C1230.69 625.592 1174.62 606.261 1118.55 588.862C754.083 473.839 307.446 555.998 214.639 679.721C190.47 711.618 185.636 748.348 202.071 785.078C220.439 726.117 351.917 1216.17 788.886 1102.12C843.024 1089.55 901.029 1071.19 963.867 1046.06C979.335 1040.26 995.77 1033.49 1012.2 1026.72C1126.28 975.495 1236.49 929.099 1340.9 885.603C1411.47 856.606 1478.18 824.708 1542.95 796.677C1564.22 787.012 1583.55 777.346 1604.82 768.647C1613.52 765.747 1621.26 761.88 1628.99 758.014C1637.69 751.248 1652.19 751.248 1659.93 744.482C1668.63 737.716 1683.13 723.217 1691.83 715.484C1699.56 708.718 1707.3 701.952 1716 694.22C1736.3 675.855 1757.57 657.49 1777.87 639.124C1846.51 579.196 1914.18 521.201 1980.89 468.039C2117.2 359.782 2246.74 271.823 2371.45 215.761C2433.32 188.697 2493.26 168.399 2553.2 157.766C2863.52 106.538 3143.88 270.857 3378.8 715.484Z' stroke='url(#paint35_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3399.1 709.682C3399.1 782.176 3905.68 1583.47 2978.57 1393.06C2914.76 1381.46 2851.92 1365.99 2791.02 1347.63C2635.37 1300.26 2493.26 1236.47 2361.78 1163.98C2281.54 1119.51 2205.17 1073.12 2134.6 1025.75C2111.4 1010.29 2088.19 994.824 2065.96 978.392C2056.29 971.626 2047.59 964.86 2039.86 959.061C2030.19 953.261 2015.69 939.729 2006.02 933.93C1996.35 927.163 1980.89 928.13 1971.22 921.364C1963.48 917.498 1954.78 914.598 1945.12 911.698C1922.88 903.965 1900.65 895.266 1879.38 886.567C1805.9 857.57 1737.26 826.639 1670.56 797.641C1534.25 737.713 1411.47 675.852 1290.63 627.523C1233.59 604.325 1177.52 584.027 1120.48 565.662C753.117 447.739 300.679 537.631 204.005 671.986C179.836 705.816 174.035 745.446 190.47 784.109C207.872 729.014 337.416 1236.47 781.152 1119.51C836.257 1105.98 894.262 1086.65 958.067 1060.55C973.535 1053.79 989.97 1047.02 1006.4 1040.25C1122.41 987.092 1232.62 937.796 1338.97 890.433C1410.5 858.536 1478.18 825.672 1543.92 794.742C1565.18 785.076 1585.49 773.477 1606.75 764.778C1615.45 760.911 1623.19 758.012 1630.92 753.179C1639.62 745.446 1654.12 745.446 1662.83 738.68C1671.53 730.947 1686.03 717.415 1694.73 709.682C1702.46 702.916 1710.2 696.15 1718.9 687.451C1739.2 669.086 1760.47 650.721 1781.74 632.356C1851.34 572.428 1919.98 514.433 1987.65 460.304C2123 353.98 2254.47 265.055 2380.15 208.993C2442.02 180.962 2502.93 160.664 2562.87 150.031C2875.13 95.9026 3157.42 259.255 3399.1 709.682Z' stroke='url(#paint36_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3418.44 703.886C3418.44 771.547 3945.31 1589.28 2999.84 1394.03C2935.06 1382.43 2872.22 1366 2810.35 1347.63C2652.77 1299.3 2508.73 1236.47 2376.28 1163.98C2294.11 1119.52 2217.74 1073.12 2146.2 1025.76C2123 1010.29 2099.79 994.828 2076.59 978.396C2066.92 971.63 2058.22 964.864 2049.52 959.064C2039.86 952.298 2024.39 939.732 2014.72 933.933C2004.09 927.167 1989.58 927.167 1979.92 920.401C1971.22 916.534 1962.52 913.635 1953.81 909.768C1930.61 902.036 1909.34 892.37 1887.11 882.704C1812.67 850.807 1743.06 818.91 1675.39 787.012C1537.15 723.218 1413.4 658.457 1291.59 607.228C1234.56 583.064 1177.52 561.799 1120.48 543.434C750.215 421.644 291.01 520.236 191.435 665.223C166.3 701.953 160.499 742.55 176.934 784.113C192.402 732.884 320.979 1258.7 771.483 1137.88C826.588 1124.35 885.559 1104.05 949.365 1076.99C965.799 1070.22 982.234 1063.45 998.669 1054.76C1115.65 998.694 1227.79 946.499 1334.13 896.236C1406.64 862.406 1474.31 827.609 1541.01 794.745C1562.28 784.113 1583.55 772.514 1604.82 762.848C1613.52 758.982 1622.22 755.115 1628.99 750.282C1638.66 742.55 1652.19 741.583 1660.89 733.851C1670.56 726.118 1684.09 712.586 1693.76 704.853C1701.49 698.087 1709.23 690.354 1717.93 682.622C1739.2 664.257 1760.47 645.892 1780.77 627.526C1851.34 566.632 1919.98 508.637 1988.62 454.508C2127.83 344.318 2259.31 255.392 2386.92 198.364C2449.76 170.333 2510.66 150.035 2571.57 139.402C2885.76 86.2404 3169.98 247.66 3418.44 703.886Z' stroke='url(#paint37_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3438.74 698.086C3438.74 760.914 3985.92 1595.07 3021.11 1394.99C2955.37 1382.43 2892.53 1366.96 2830.66 1348.6C2671.15 1300.27 2526.13 1236.47 2391.76 1164.95C2308.62 1120.48 2231.28 1074.09 2158.77 1026.72C2134.6 1011.26 2111.4 995.793 2088.2 979.361C2078.53 972.595 2069.83 965.829 2061.13 960.03C2050.49 953.264 2035.99 940.698 2026.33 934.899C2015.69 928.133 2001.19 927.166 1990.56 920.4C1981.86 916.534 1973.15 912.667 1964.45 909.768C1941.25 901.068 1919.02 890.436 1896.78 880.77C1821.38 846.94 1750.8 813.109 1683.13 779.279C1543.92 711.618 1419.21 642.991 1296.43 589.829C1239.39 564.698 1181.39 542.466 1124.35 523.135C750.219 398.445 286.181 505.736 183.706 660.389C157.604 699.053 151.803 742.549 168.238 785.078C182.739 737.716 309.383 1280.94 765.687 1157.21C820.792 1143.68 880.73 1122.42 945.502 1094.38C961.937 1087.62 978.372 1079.89 994.807 1071.19C1112.75 1012.23 1225.86 957.13 1333.17 903.968C1406.64 868.205 1475.28 830.508 1541.99 795.711C1563.25 784.112 1584.52 772.513 1605.79 761.88C1614.49 758.014 1623.19 754.148 1630.93 748.348C1640.59 740.616 1654.13 738.682 1663.8 730.95C1673.46 723.217 1687 709.685 1696.66 701.952C1704.4 695.186 1713.1 687.454 1721.8 679.721C1743.07 660.389 1764.34 642.024 1785.61 623.659C1857.14 562.764 1926.75 503.803 1996.36 449.674C2136.53 339.484 2269.95 249.592 2399.49 191.597C2462.33 163.566 2524.2 142.301 2586.07 131.669C2897.36 75.6069 3183.52 237.026 3438.74 698.086Z' stroke='url(#paint38_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3458.08 693.253C3458.08 751.248 4025.56 1601.84 3042.38 1396.92C2976.64 1384.36 2911.86 1367.93 2849.99 1349.56C2688.55 1301.23 2541.6 1237.44 2406.26 1165.91C2322.15 1121.45 2243.84 1075.05 2170.37 1027.69C2146.2 1012.23 2122.03 996.76 2099.8 980.328C2090.13 973.562 2081.43 966.796 2072.73 960.996C2062.09 954.23 2047.59 942.631 2036.96 935.865C2026.32 929.099 2011.82 928.132 2001.19 920.4C1992.49 915.567 1983.79 912.667 1974.12 908.801C1950.92 899.135 1927.72 888.503 1905.48 877.87C1829.11 842.107 1757.57 805.376 1688.93 770.579C1547.78 698.086 1422.11 626.559 1298.36 571.464C1240.36 545.366 1183.32 522.168 1125.32 502.836C747.319 373.314 276.513 488.337 171.138 653.623C145.035 694.22 138.268 739.649 154.703 785.078C168.237 741.582 293.914 1302.2 756.019 1175.58C812.091 1161.08 872.029 1139.81 936.801 1109.85C953.236 1102.12 969.67 1094.38 986.105 1085.69C1105.01 1024.79 1219.09 965.829 1327.37 909.767C1400.84 872.071 1471.41 832.441 1539.08 795.711C1561.32 784.112 1582.59 770.58 1603.86 759.947C1612.56 755.114 1621.26 751.248 1628.99 746.415C1638.66 738.682 1652.19 735.783 1661.86 728.05C1671.53 720.317 1685.06 706.785 1695.7 699.052C1703.43 692.286 1712.13 684.554 1720.83 676.821C1742.1 657.489 1764.34 639.124 1785.6 620.759C1858.11 558.898 1928.68 499.936 1998.29 445.808C2140.4 334.651 2274.78 243.792 2405.29 185.797C2469.09 156.8 2531.93 135.535 2592.84 124.903C2908 65.941 3196.09 225.427 3458.08 693.253Z' stroke='url(#paint39_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3477.41 687.459C3477.41 740.622 4064.22 1608.61 3063.64 1397.9C2996.93 1385.33 2932.16 1368.9 2869.32 1349.57C2705.94 1301.24 2557.06 1237.44 2420.75 1164.95C2335.68 1120.49 2256.41 1074.09 2181.97 1026.73C2157.8 1011.26 2133.63 995.799 2110.43 979.367C2100.76 972.601 2091.09 965.835 2082.39 960.036C2071.76 953.27 2057.26 941.671 2046.62 934.905C2035.99 928.138 2021.49 926.205 2009.89 918.473C2001.19 913.64 1991.52 909.773 1982.82 905.907C1958.65 896.241 1936.41 884.642 1913.21 873.043C1835.87 835.347 1763.37 796.683 1693.76 758.987C1551.65 682.627 1425 608.2 1299.33 549.238C1241.32 522.174 1183.32 498.009 1124.35 477.711C744.414 346.256 267.808 469.978 159.532 644.93C132.463 688.426 125.696 735.789 142.131 783.151C154.699 742.555 278.442 1321.54 747.314 1192.02C803.386 1177.52 864.291 1155.29 930.03 1124.35C946.464 1116.62 962.899 1108.89 980.301 1099.22C1100.18 1035.43 1215.22 973.568 1324.46 914.606C1398.9 874.01 1469.47 833.413 1538.11 793.784C1560.35 781.218 1581.62 767.686 1603.85 756.087C1612.55 751.254 1621.25 746.421 1628.99 741.588C1638.66 733.855 1652.19 729.989 1662.82 722.256C1672.49 713.557 1686.99 700.992 1696.66 692.292C1704.39 685.526 1713.09 677.794 1721.8 670.061C1744.03 650.729 1765.3 632.364 1787.53 613.999C1861.01 552.138 1932.55 492.21 2003.12 438.081C2146.2 325.958 2282.51 235.099 2413.99 176.137C2477.79 147.14 2541.6 125.875 2603.47 114.276C2919.6 55.3147 3209.62 214.801 3477.41 687.459Z' stroke='url(#paint40_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3497.71 681.656C3497.71 729.985 4104.83 1614.41 3084.91 1398.86C3017.24 1385.33 2952.47 1368.9 2888.66 1350.53C2722.38 1301.24 2572.53 1237.44 2435.26 1165.91C2349.22 1121.45 2268.98 1075.05 2193.57 1027.69C2168.43 1012.23 2144.26 996.762 2121.06 980.33C2111.4 973.564 2101.73 966.798 2093.03 960.998C2081.43 954.232 2066.93 942.633 2056.29 935.867C2044.69 929.101 2030.19 926.201 2019.55 918.469C2010.85 913.636 2001.19 909.769 1991.52 904.937C1967.35 894.304 1944.15 881.739 1920.95 870.14C1842.64 829.543 1769.17 788.947 1699.56 750.283C1555.52 670.057 1427.91 591.764 1302.23 530.869C1243.26 502.838 1185.25 477.707 1126.28 457.409C743.448 323.054 261.042 454.509 148.899 640.093C121.83 685.522 114.096 734.818 130.531 785.08C142.132 748.35 263.942 1345.7 739.581 1212.31C796.619 1197.81 857.525 1174.61 923.263 1141.75C939.698 1134.02 957.099 1125.32 973.534 1115.65C1095.34 1048.96 1211.35 985.163 1321.56 922.335C1396.97 879.805 1468.51 836.309 1538.11 794.746C1560.35 781.214 1582.58 767.682 1604.82 755.116C1613.52 750.283 1622.22 745.45 1630.92 739.651C1641.56 730.952 1655.09 728.052 1664.76 719.353C1675.39 710.653 1688.93 698.088 1698.59 689.389C1707.3 682.623 1715.03 674.89 1724.7 667.157C1746.93 647.826 1769.17 629.461 1791.4 610.129C1865.84 547.301 1937.38 488.34 2008.92 432.278C2153.93 320.154 2291.21 227.362 2423.65 167.434C2488.43 138.437 2552.23 116.205 2615.07 104.606C2930.23 45.6448 3222.19 203.198 3497.71 681.656Z' stroke='url(#paint41_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3517.04 675.857C3517.04 719.353 4144.46 1620.21 3106.18 1398.86C3038.5 1385.33 2971.8 1368.9 2908.96 1349.56C2740.75 1300.27 2589.93 1236.47 2450.72 1164.95C2363.72 1120.48 2281.54 1074.09 2206.14 1025.76C2181 1010.29 2155.86 993.862 2132.66 978.397C2123 971.631 2113.33 964.865 2104.63 959.065C2093.03 952.299 2078.52 940.7 2067.89 932.968C2056.29 925.235 2041.79 922.335 2030.19 914.602C2021.49 909.77 2011.82 904.937 2002.15 901.07C1977.98 889.471 1954.78 876.906 1931.58 864.34C1852.31 821.811 1778.83 779.281 1707.29 738.684C1562.28 653.625 1433.7 573.399 1306.09 509.604C1247.12 480.607 1188.15 454.509 1129.18 433.245C741.514 297.923 252.34 438.077 137.297 633.327C109.261 680.69 101.527 732.885 117.962 785.08C128.596 752.217 248.473 1366.96 729.913 1230.67C786.951 1215.21 848.823 1192.01 915.528 1158.18C931.963 1149.48 949.365 1140.78 966.766 1131.12C1089.54 1062.49 1206.52 994.829 1317.7 929.101C1394.07 884.638 1465.61 839.209 1536.18 795.713C1558.42 781.214 1580.65 766.715 1603.85 754.15C1612.55 749.317 1621.25 743.517 1629.95 737.718C1640.59 729.019 1654.12 725.152 1663.79 716.453C1674.42 707.754 1687.96 695.188 1698.59 686.489C1707.29 679.723 1715.99 671.99 1724.7 664.258C1746.93 644.926 1769.17 625.594 1791.4 607.229C1865.84 544.401 1939.31 484.473 2010.85 428.412C2156.83 315.321 2296.04 222.53 2429.45 161.635C2495.19 131.671 2559 110.406 2621.84 97.8405C2941.83 35.9792 3234.75 191.599 3517.04 675.857Z' stroke='url(#paint42_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3536.38 670.05C3536.38 708.714 4184.1 1626.97 3127.44 1399.82C3058.81 1386.29 2992.1 1368.89 2928.29 1350.52C2758.15 1300.26 2605.4 1237.43 2465.22 1165.91C2377.25 1121.44 2294.11 1075.05 2216.77 1026.72C2191.63 1011.25 2166.5 994.822 2142.33 979.357C2132.66 972.591 2122.99 965.825 2113.33 960.025C2101.73 952.292 2087.23 941.66 2075.62 933.927C2064.02 926.195 2049.52 922.328 2037.92 914.596C2028.25 909.763 2019.55 904.93 2009.89 900.097C1984.75 887.531 1961.55 874.966 1938.35 861.434C1858.11 816.971 1783.67 772.508 1712.13 729.012C1566.15 640.086 1435.64 555.994 1308.03 490.266C1248.09 460.302 1189.12 433.238 1130.15 411.973C739.58 272.785 244.605 420.672 126.662 626.554C97.6599 675.85 89.926 729.979 106.361 784.107C115.061 755.11 234.938 1387.25 722.178 1247.1C779.216 1231.63 841.088 1206.5 908.761 1171.71C925.195 1163.01 942.597 1154.31 959.998 1143.68C1083.74 1072.15 1201.68 1001.59 1313.83 932.961C1390.2 886.565 1463.67 839.202 1534.25 792.806C1557.45 778.308 1579.68 762.842 1601.92 749.31C1610.62 743.511 1620.29 738.678 1628.02 731.912C1638.65 723.212 1652.19 718.38 1662.82 709.68C1673.46 700.981 1686.99 688.415 1697.63 679.716C1706.33 672.95 1715.03 665.218 1723.73 657.485C1745.96 638.153 1769.17 618.822 1791.4 600.456C1866.81 537.629 1941.25 476.734 2013.75 420.672C2161.66 306.616 2300.88 212.857 2436.22 151.962C2501.96 121.998 2566.73 99.7669 2630.54 87.2014C2952.46 25.3401 3248.29 180.96 3536.38 670.05Z' stroke='url(#paint43_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3555.72 665.219C3555.72 699.05 4222.77 1633.73 3147.75 1401.75C3078.15 1387.26 3011.44 1370.82 2946.67 1351.49C2774.59 1301.23 2619.91 1237.44 2478.76 1166.88C2389.82 1122.41 2305.71 1076.02 2227.41 1027.69C2201.31 1012.22 2176.17 995.79 2152 979.358C2142.33 972.592 2131.7 965.826 2123 960.027C2111.4 952.294 2096.9 941.662 2085.3 933.929C2072.73 926.196 2059.19 921.364 2046.63 913.631C2036.96 907.831 2027.29 902.998 2017.62 898.166C1992.49 885.6 1968.32 871.101 1945.12 857.569C1863.91 811.173 1788.5 764.777 1716 719.348C1568.09 626.556 1436.61 538.597 1308.03 470.936C1248.09 439.039 1188.15 411.975 1128.22 389.743C737.651 246.689 236.876 404.242 115.066 620.756C86.0633 672.952 77.3626 729.014 93.7973 785.075C101.531 759.944 219.474 1409.49 713.482 1266.43C771.487 1250 833.359 1224.87 901.031 1189.11C917.466 1180.41 934.867 1170.74 952.269 1160.11C1076.98 1085.68 1195.89 1012.22 1309 940.695C1386.34 891.399 1460.78 842.104 1532.32 794.741C1555.52 779.276 1577.75 763.811 1600.96 749.312C1609.66 743.512 1619.32 737.713 1628.02 731.913C1638.66 723.214 1652.19 717.415 1662.83 708.715C1674.43 700.016 1687 687.451 1698.6 678.751C1707.3 671.019 1716 664.253 1725.67 656.52C1748.87 637.188 1771.1 617.857 1794.31 598.525C1870.68 534.731 1946.08 473.836 2018.59 417.774C2167.47 302.751 2308.61 208.992 2444.93 147.131C2511.63 117.167 2576.4 93.9691 2641.18 81.4035C2964.07 15.6759 3260.86 169.362 3555.72 665.219Z' stroke='url(#paint44_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3576.02 659.422C3576.02 688.419 4263.37 1639.54 3169.98 1402.72C3100.38 1388.22 3032.71 1370.83 2966.97 1352.46C2792.95 1302.2 2636.34 1238.4 2494.23 1167.84C2404.32 1123.38 2319.25 1076.99 2239.97 1028.66C2213.87 1013.19 2188.74 996.759 2163.6 980.327C2152.97 973.561 2143.3 966.795 2133.63 960.995C2121.06 953.263 2107.53 942.63 2094.96 934.898C2082.39 927.165 2067.89 921.366 2056.29 913.633C2046.62 907.833 2036.96 903 2027.29 897.201C2002.15 883.669 1977.99 869.17 1953.82 854.671C1871.64 806.342 1795.27 757.047 1722.76 710.651C1573.89 613.992 1441.44 523.134 1310.93 452.573C1250.99 419.709 1191.05 391.678 1130.15 369.447C735.716 221.56 228.174 386.845 103.463 613.992C73.4942 668.121 64.7934 726.116 81.2281 785.077C87.9954 762.846 204.005 1431.72 704.78 1284.8C762.785 1268.37 825.623 1242.27 894.262 1205.54C911.664 1195.87 929.065 1186.21 946.467 1175.58C1072.14 1099.22 1192.02 1021.89 1307.06 947.463C1385.37 896.234 1459.81 845.005 1532.32 794.743C1555.52 778.311 1578.72 761.879 1601.92 746.414C1611.59 740.615 1620.29 733.849 1628.99 728.049C1640.59 719.35 1653.16 712.584 1664.76 703.884C1676.36 694.219 1689.89 682.62 1700.53 673.92C1709.23 666.188 1718.9 658.455 1727.6 650.722C1750.8 631.391 1774 612.059 1797.2 592.728C1874.54 528.933 1949.95 467.072 2024.39 411.01C2174.24 295.987 2316.35 200.295 2453.62 138.434C2520.33 107.503 2586.07 85.2718 2650.84 71.7396C2974.7 5.04545 3273.43 158.732 3576.02 659.422Z' stroke='url(#paint45_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3595.36 653.623C3595.36 677.787 4303.01 1645.34 3191.26 1403.69C3120.68 1389.19 3052.04 1371.79 2986.3 1352.46C2810.36 1301.23 2652.78 1238.41 2508.73 1167.84C2416.89 1123.38 2331.82 1076.99 2251.58 1028.66C2225.48 1013.19 2199.37 996.76 2174.24 980.328C2163.6 973.562 2153.94 966.796 2144.27 960.996C2131.7 953.264 2117.2 942.631 2105.6 934.898C2093.03 927.166 2078.53 921.366 2065.96 912.667C2056.29 906.868 2046.63 901.068 2036.96 896.235C2011.82 881.736 1986.69 867.238 1962.52 851.772C1879.38 801.51 1802.04 750.281 1728.57 700.986C1577.75 600.461 1444.34 505.736 1313.83 433.242C1252.93 399.412 1192.99 370.414 1132.08 347.216C733.785 196.429 220.442 369.448 92.8314 607.227C61.8955 663.289 53.1948 724.183 69.6295 785.078C75.4299 766.713 190.473 1452.99 696.082 1303.17C755.053 1286.73 817.892 1259.67 886.531 1221.01C903.932 1211.34 921.334 1201.68 938.735 1190.08C1065.38 1110.82 1187.19 1031.56 1302.23 953.264C1381.51 900.101 1456.91 845.973 1530.38 794.744C1554.55 778.312 1577.75 760.914 1600.96 744.482C1610.62 737.716 1619.32 731.916 1628.03 725.15C1639.63 715.484 1652.19 708.718 1663.8 700.019C1675.4 690.353 1688.93 678.754 1700.53 669.088C1709.23 661.356 1718.9 653.623 1727.6 645.89C1750.8 626.559 1774.97 607.227 1798.17 587.895C1876.48 523.134 1952.85 462.24 2027.29 405.211C2179.07 289.221 2323.12 193.53 2461.36 130.702C2529.03 99.7712 2594.77 76.5732 2660.51 63.0411C2985.34 -4.6197 3286.96 147.134 3595.36 653.623Z' stroke='url(#paint46_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3614.69 647.825C3614.69 667.156 4342.65 1652.1 3211.55 1404.66C3140.01 1389.19 3071.38 1371.79 3005.64 1352.46C2827.75 1301.23 2668.24 1237.44 2523.23 1167.85C2430.42 1123.38 2344.38 1076.02 2263.17 1028.66C2236.11 1013.19 2210 996.761 2184.87 980.329C2174.23 973.563 2164.57 966.797 2154.9 960.997C2142.33 953.265 2127.83 943.599 2115.26 934.899C2102.69 926.2 2088.19 920.401 2075.63 911.702C2065.96 905.902 2055.32 900.103 2045.66 894.303C2019.55 878.838 1995.39 863.372 1970.25 847.907C1886.14 794.745 1807.84 742.55 1734.36 691.321C1581.62 585.963 1447.24 488.339 1314.8 413.912C1253.89 379.115 1192.99 349.151 1132.08 325.953C731.848 171.3 211.738 353.017 81.227 601.429C50.2911 660.39 40.6236 723.218 57.0583 786.046C61.892 771.547 175.001 1475.22 687.377 1322.5C746.349 1305.1 810.154 1278.04 879.76 1238.41C897.161 1228.74 914.563 1218.11 932.931 1206.51C1061.51 1124.35 1183.32 1042.19 1299.33 960.997C1378.6 905.902 1454.97 849.84 1529.41 795.712C1553.58 778.313 1576.78 760.915 1600.95 743.516C1610.62 736.75 1619.32 729.984 1628.99 723.218C1640.59 713.552 1654.12 705.82 1665.73 696.154C1677.33 686.488 1690.86 674.889 1702.46 665.223C1711.16 657.49 1720.83 649.758 1730.5 642.025C1754.67 622.693 1777.87 602.395 1801.07 584.03C1880.34 519.269 1957.68 457.408 2033.09 400.38C2186.8 283.423 2331.81 187.731 2471.03 123.937C2538.7 93.0064 2606.37 69.8085 2672.11 55.3097C2996.94 -14.2842 3299.53 135.536 3614.69 647.825Z' stroke='url(#paint47_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3634.03 642.024C3634.03 656.523 4381.32 1657.9 3232.83 1404.66C3161.29 1389.19 3091.68 1371.79 3024.98 1352.46C2845.16 1300.27 2683.72 1237.44 2537.74 1167.84C2443.96 1123.38 2356.95 1076.02 2274.78 1027.69C2247.71 1012.23 2221.61 995.793 2195.51 979.361C2184.87 972.595 2175.21 965.829 2164.57 960.03C2151.04 952.297 2137.5 942.631 2124.94 933.932C2111.4 925.233 2097.87 918.467 2084.33 909.767C2074.66 903.968 2064.03 897.202 2054.36 891.402C2028.26 875.937 2003.13 859.505 1977.99 843.073C1892.92 787.978 1814.61 732.883 1739.2 679.721C1585.49 571.463 1450.15 469.972 1317.7 392.646C1255.83 356.882 1194.93 325.952 1133.05 301.787C729.92 144.234 204.01 333.684 70.5985 591.762C38.6958 652.656 29.0284 717.417 45.4631 782.178C49.33 773.479 160.506 1495.52 679.649 1339.9C738.621 1322.5 803.393 1294.47 872.998 1252.9C890.4 1243.24 907.801 1231.64 926.169 1220.04C1055.71 1134.98 1178.49 1049.92 1295.47 965.829C1375.71 907.834 1453.05 850.806 1528.45 794.744C1552.62 776.379 1576.79 758.014 1599.99 740.615C1609.66 733.849 1618.36 727.083 1628.03 719.351C1639.63 709.685 1653.16 700.986 1664.76 691.32C1677.33 681.654 1689.9 670.055 1702.47 660.389C1712.13 652.656 1720.84 644.924 1730.5 637.191C1754.67 616.893 1778.84 597.561 1802.04 578.23C1882.28 512.502 1960.59 450.641 2035.99 392.646C2190.67 274.723 2336.65 178.064 2477.8 114.27C2546.44 82.3728 2614.11 59.1749 2679.85 44.6761C3007.58 -24.9178 3312.1 124.902 3634.03 642.024Z' stroke='url(#paint48_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3653.36 637.195C3653.36 646.861 4420.96 1664.67 3253.13 1406.59C3180.62 1391.13 3111.01 1372.76 3043.34 1353.43C2861.59 1301.24 2698.21 1238.41 2551.27 1167.85C2456.53 1123.39 2368.55 1076.02 2285.41 1027.69C2258.34 1011.26 2231.27 995.797 2205.17 979.365C2194.54 972.599 2183.9 965.833 2174.24 960.033C2160.7 951.334 2147.17 942.635 2133.63 933.935C2120.1 925.236 2106.56 917.504 2093.03 908.804C2082.4 902.038 2072.73 896.239 2062.09 889.473C2035.99 873.041 2009.89 856.609 1984.75 839.21C1898.71 782.182 1819.44 725.154 1744.03 670.059C1589.35 556.968 1452.08 452.578 1318.67 373.318C1256.79 336.588 1194.92 304.69 1133.05 280.526C727.016 120.073 195.305 318.223 58.0271 585.966C26.1244 648.794 15.4902 716.455 31.9249 783.149C33.8584 775.416 144.067 1515.82 669.978 1356.33C730.883 1339.9 795.655 1310.9 866.228 1268.37C883.629 1257.74 901.997 1247.11 919.399 1234.54C1049.91 1147.55 1173.65 1058.62 1291.6 971.632C1372.8 911.704 1451.11 851.776 1526.52 793.781C1550.68 774.449 1574.85 756.084 1599.02 737.719C1608.69 729.987 1618.36 723.221 1627.06 715.488C1639.63 705.822 1652.19 696.156 1663.79 686.49C1676.36 676.825 1688.93 665.226 1701.5 655.56C1711.16 647.827 1720.83 640.094 1729.53 632.362C1753.7 612.064 1777.87 592.732 1802.04 573.4C1883.25 507.673 1961.55 444.845 2038.89 386.85C2195.5 268.927 2342.45 171.302 2484.56 105.574C2554.17 73.6773 2621.84 49.5127 2688.55 35.014C3018.21 -34.5799 3324.67 113.307 3653.36 637.195Z' stroke='url(#paint49_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M3673.66 631.391C3673.66 636.224 4461.56 1671.43 3275.36 1407.56C3201.89 1391.12 3131.32 1373.73 3063.64 1354.39C2879.96 1302.2 2715.61 1238.4 2566.74 1168.81C2471.03 1124.35 2382.09 1076.99 2297.98 1028.66C2269.94 1012.22 2242.88 996.759 2216.77 980.327C2206.14 973.561 2195.5 967.761 2184.87 960.995C2171.34 952.296 2156.83 943.597 2144.27 934.897C2130.73 926.198 2116.23 917.499 2102.7 908.8C2092.06 902.034 2082.4 895.268 2071.76 888.502C2045.66 871.103 2019.56 853.705 1993.45 836.306C1906.45 777.345 1826.21 718.383 1749.83 661.355C1593.22 544.398 1455.94 437.108 1320.6 354.948C1257.76 317.251 1196.86 284.388 1134.02 259.257C725.083 94.9376 186.605 301.786 47.3932 580.162C15.4906 645.889 3.88959 715.483 21.291 785.077C22.2578 781.211 131.5 1539.01 663.211 1376.63C723.149 1358.26 788.888 1328.3 859.461 1284.8C876.862 1274.17 895.23 1262.57 913.598 1250C1045.08 1160.11 1169.79 1068.29 1289.66 978.394C1371.84 916.532 1450.14 854.671 1526.52 794.743C1551.65 775.411 1575.82 756.08 1599.99 736.748C1609.66 729.015 1619.32 721.283 1628.99 714.517C1641.56 704.851 1654.13 695.185 1666.69 684.553C1679.26 673.92 1691.83 663.288 1704.4 653.622C1714.06 645.889 1723.73 638.157 1733.4 630.424C1757.57 610.126 1782.7 590.794 1806.87 571.463C1889.05 504.768 1968.32 441.941 2045.66 383.946C2203.24 265.056 2352.12 166.465 2495.2 100.737C2564.8 68.8398 2633.44 44.6753 2701.11 29.21C3029.81 -45.2168 3338.2 102.67 3673.66 631.391Z' stroke='url(#paint50_linear_14299_3629)' stroke-miterlimit='10'/>\n<path d='M8.72248 785.078C8.72248 785.078 147.934 1792.26 905.864 1264.5C2184.87 374.281 2839.36 -707.324 3692.03 625.592C3692.03 625.592 4500.23 1677.23 3295.66 1408.52C2091.09 1139.81 1643.49 443.875 1135.95 237.993C628.407 32.1109 -82.1517 406.178 8.72248 785.078Z' stroke='url(#paint51_linear_14299_3629)' stroke-miterlimit='10'/>\n<defs>\n<linearGradient id='paint0_linear_14299_3629' x1='1569.05' y1='466.105' x2='1569.05' y2='1359.23' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint1_linear_14299_3629' x1='1577.72' y1='456.443' x2='1577.72' y2='1359.35' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint2_linear_14299_3629' x1='1586.47' y1='447.721' x2='1586.47' y2='1360.54' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint3_linear_14299_3629' x1='1593.22' y1='439.921' x2='1593.22' y2='1362.81' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint4_linear_14299_3629' x1='1603.02' y1='430.218' x2='1603.02' y2='1364.29' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint5_linear_14299_3629' x1='1610.25' y1='421.466' x2='1610.25' y2='1365.74' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint6_linear_14299_3629' x1='1619.17' y1='415.341' x2='1619.17' y2='1367.25' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint7_linear_14299_3629' x1='1626.48' y1='405.586' x2='1626.48' y2='1368.11' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint8_linear_14299_3629' x1='1635.32' y1='394.952' x2='1635.32' y2='1370.66' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint9_linear_14299_3629' x1='1641.92' y1='386.153' x2='1641.92' y2='1372.29' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint10_linear_14299_3629' x1='1650.93' y1='377.249' x2='1650.93' y2='1373.93' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint11_linear_14299_3629' x1='1658.32' y1='369.154' x2='1658.32' y2='1375.77' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint12_linear_14299_3629' x1='1665.62' y1='358.627' x2='1665.62' y2='1377.45' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint13_linear_14299_3629' x1='1675.76' y1='348.825' x2='1675.76' y2='1378.37' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint14_linear_14299_3629' x1='1682.56' y1='341.474' x2='1682.56' y2='1381.24' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint15_linear_14299_3629' x1='1690.7' y1='333.392' x2='1690.7' y2='1382.98' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint16_linear_14299_3629' x1='1698.83' y1='325.886' x2='1698.83' y2='1384.72' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint17_linear_14299_3629' x1='1706.39' y1='315.222' x2='1706.39' y2='1386.46' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint18_linear_14299_3629' x1='1714.88' y1='304.746' x2='1714.88' y2='1388.43' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint19_linear_14299_3629' x1='1722.24' y1='296.393' x2='1722.24' y2='1389.46' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint20_linear_14299_3629' x1='1730.63' y1='286.769' x2='1730.63' y2='1391.28' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint21_linear_14299_3629' x1='1738.78' y1='277.861' x2='1738.78' y2='1393.07' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint22_linear_14299_3629' x1='1745.64' y1='272.432' x2='1745.64' y2='1396.04' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint23_linear_14299_3629' x1='1755.52' y1='261.044' x2='1755.52' y2='1397.83' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint24_linear_14299_3629' x1='1763.16' y1='253.537' x2='1763.16' y2='1399.63' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint25_linear_14299_3629' x1='1770.42' y1='242.886' x2='1770.42' y2='1400.95' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint26_linear_14299_3629' x1='1779.51' y1='231.741' x2='1779.51' y2='1402.76' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint27_linear_14299_3629' x1='1786.48' y1='222.551' x2='1786.48' y2='1404.57' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint28_linear_14299_3629' x1='1795.3' y1='214.967' x2='1795.3' y2='1407.35' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint29_linear_14299_3629' x1='1801.57' y1='205.016' x2='1801.57' y2='1409.41' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint30_linear_14299_3629' x1='1809.73' y1='195.08' x2='1809.73' y2='1410.52' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint31_linear_14299_3629' x1='1818.93' y1='186.06' x2='1818.93' y2='1412.35' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint32_linear_14299_3629' x1='1827.12' y1='177.469' x2='1827.12' y2='1414.41' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint33_linear_14299_3629' x1='1835.07' y1='169.093' x2='1835.07' y2='1416.24' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint34_linear_14299_3629' x1='1843.87' y1='158.435' x2='1843.87' y2='1419.04' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint35_linear_14299_3629' x1='1850.78' y1='148.741' x2='1850.78' y2='1420.85' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint36_linear_14299_3629' x1='1859.19' y1='140.057' x2='1859.19' y2='1422.23' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint37_linear_14299_3629' x1='1866.24' y1='129.672' x2='1866.24' y2='1424.07' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint38_linear_14299_3629' x1='1876.16' y1='121' x2='1876.16' y2='1425.91' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint39_linear_14299_3629' x1='1883.4' y1='113.179' x2='1883.4' y2='1428.71' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint40_linear_14299_3629' x1='1890.83' y1='102.564' x2='1890.83' y2='1430.81' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint41_linear_14299_3629' x1='1899.49' y1='92.8153' x2='1899.49' y2='1432.65' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint42_linear_14299_3629' x1='1907.17' y1='84.9469' x2='1907.17' y2='1433.81' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint43_linear_14299_3629' x1='1915.36' y1='74.3203' x2='1915.36' y2='1435.9' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint44_linear_14299_3629' x1='1922.92' y1='67.025' x2='1922.92' y2='1438.71' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint45_linear_14299_3629' x1='1931.15' y1='57.0142' x2='1931.15' y2='1440.56' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint46_linear_14299_3629' x1='1939.4' y1='47.8563' x2='1939.4' y2='1442.41' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint47_linear_14299_3629' x1='1947.19' y1='39.2848' x2='1947.19' y2='1444.51' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint48_linear_14299_3629' x1='1955.28' y1='28.6678' x2='1955.28' y2='1445.68' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint49_linear_14299_3629' x1='1962.62' y1='18.9098' x2='1962.62' y2='1448.5' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint50_linear_14299_3629' x1='1971.67' y1='11.2063' x2='1971.67' y2='1450.61' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint51_linear_14299_3629' x1='1979.09' y1='0.921875' x2='1979.09' y2='1452.46' gradientUnits='userSpaceOnUse'>\n<stop stop-color='white' stop-opacity='0.34'/>\n<stop offset='0.453125' stop-color='#A3FFF6' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n</defs>\n</svg>\n`,\n  lightSvg: `<svg id='bgAlpha' width='3958' height='1453' viewBox='0 0 3958 1453' fill='none' xmlns='http://www.w3.org/2000/svg'>\n<path d='M2135.57 466.105C2094 466.105 2052.43 474.805 2009.89 492.203C1925.78 526.034 1840.71 588.861 1754.67 671.988C1711.17 714.517 1670.56 758.98 1633.83 804.409C1622.23 818.908 1610.62 833.407 1599.02 847.906C1593.22 855.638 1588.39 862.404 1585.49 865.304L1569.05 888.502L1552.62 865.304C1549.72 861.438 1545.85 855.638 1539.09 847.906C1527.48 833.407 1515.88 818.908 1504.28 804.409C1467.55 758.98 1426.94 714.517 1383.44 671.988C1297.4 587.895 1212.32 525.067 1128.22 492.203C1085.68 475.771 1044.11 466.105 1002.54 466.105C739.586 466.105 524.001 664.255 524.001 912.667C524.001 1161.08 739.586 1359.23 1002.54 1359.23C1044.11 1359.23 1085.68 1350.53 1128.22 1333.13C1212.32 1299.3 1297.4 1236.47 1383.44 1153.35C1426.94 1110.82 1467.55 1066.35 1504.28 1020.92C1515.88 1006.43 1527.48 991.926 1539.09 977.428C1544.89 969.695 1549.72 962.929 1552.62 960.029L1569.05 936.831L1585.49 960.029C1588.39 963.895 1592.26 969.695 1599.02 977.428C1610.62 991.926 1622.23 1006.43 1633.83 1020.92C1670.56 1066.35 1711.17 1110.82 1754.67 1153.35C1840.71 1237.44 1925.78 1300.27 2009.89 1333.13C2052.43 1349.56 2094 1359.23 2135.57 1359.23C2398.52 1359.23 2614.11 1161.08 2614.11 912.667C2614.11 664.255 2398.52 466.105 2135.57 466.105Z' stroke='url(#paint0_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M2637.31 906.87C2640.21 1150.45 2442.02 1365.03 2160.7 1359.23C2119.13 1359.23 2076.59 1349.56 2033.09 1333.13C1947.05 1299.3 1860.04 1236.47 1773.04 1153.35C1728.57 1110.82 1687 1066.36 1649.29 1020.93C1636.72 1006.43 1625.12 991.93 1613.52 977.431C1606.76 969.698 1602.89 962.932 1599.99 960.032L1582.59 936.834L1565.19 959.066C1562.29 961.965 1558.42 967.765 1551.65 975.498C1540.05 989.996 1528.45 1003.53 1515.88 1017.06C1478.18 1059.59 1436.61 1103.09 1393.1 1143.68C1306.1 1223.91 1220.06 1282.87 1134.98 1313.8C1092.45 1329.27 1049.91 1337.97 1008.34 1337C742.484 1334.1 521.099 1143.68 518.199 905.904C517.232 864.341 523.999 825.677 536.567 787.981C595.538 605.297 776.32 488.34 999.639 484.474C1041.21 484.474 1083.75 492.206 1126.28 507.672C1137.88 511.538 1149.48 516.371 1161.09 522.17C1234.56 555.034 1309 609.163 1384.4 677.79C1427.91 718.387 1469.48 760.916 1507.18 803.446C1518.78 816.978 1531.35 830.51 1542.95 845.009C1549.72 852.742 1553.58 858.541 1556.48 861.441L1573.89 883.672L1591.29 860.474C1594.19 856.608 1598.05 850.808 1604.82 843.076C1616.42 828.577 1628.02 813.112 1640.59 798.613C1678.29 753.184 1719.86 707.754 1763.37 665.225C1850.38 580.165 1936.42 517.338 2022.46 483.507C2065.96 466.109 2107.53 457.409 2149.1 456.443C2413.02 456.443 2633.44 652.659 2637.31 906.87Z' stroke='url(#paint1_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M2660.51 901.062C2666.31 1138.84 2485.53 1370.82 2185.84 1360.19C2143.3 1359.22 2100.77 1350.52 2057.26 1333.12C1969.29 1299.29 1881.32 1235.5 1792.37 1152.37C1746.94 1109.84 1704.4 1064.41 1665.73 1019.95C1653.16 1005.45 1640.6 990.955 1628.99 976.456C1622.23 968.723 1618.36 961.957 1615.46 959.057C1614.49 959.057 1598.06 935.859 1598.06 935.859C1597.09 935.859 1580.66 958.091 1580.66 957.124C1577.76 960.024 1572.92 965.824 1567.12 973.556C1555.52 987.088 1542.95 1000.62 1530.39 1013.19C1491.72 1053.78 1449.18 1095.35 1404.71 1133.04C1315.77 1209.4 1228.76 1264.5 1142.72 1293.49C1099.22 1307.99 1056.68 1315.73 1015.11 1314.76C746.354 1307.99 519.169 1126.28 512.401 899.129C511.435 860.466 517.235 822.769 529.803 787.972C588.774 610.121 766.656 509.597 996.742 502.831C1038.31 501.864 1081.82 509.597 1125.32 524.095C1136.92 527.962 1148.52 532.795 1161.09 537.628C1236.49 568.558 1311.9 619.787 1387.31 684.548C1431.78 723.211 1474.31 763.808 1512.98 804.404C1525.55 816.97 1537.15 830.502 1548.75 844.034C1555.52 851.767 1559.39 856.6 1562.29 859.499C1563.26 859.499 1579.69 880.764 1579.69 880.764C1580.66 880.764 1597.09 857.566 1597.09 856.6C1599.99 852.733 1604.83 846.934 1610.63 839.201C1622.23 823.736 1634.79 809.237 1646.4 794.738C1685.07 749.309 1727.6 702.913 1772.07 660.383C1861.01 575.324 1948.02 510.563 2035.03 475.766C2078.53 458.368 2121.07 448.702 2163.61 447.735C2428.49 445.802 2653.75 642.018 2660.51 901.062Z' stroke='url(#paint2_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M2683.71 896.235C2692.41 1129.18 2528.07 1377.59 2210.01 1362.13C2166.5 1361.16 2123 1351.5 2079.5 1334.1C1989.59 1299.3 1899.68 1236.47 1809.77 1153.35C1763.37 1110.82 1719.87 1065.39 1680.23 1020.92C1667.66 1006.43 1655.09 991.927 1642.53 976.461C1635.76 968.729 1630.93 962.929 1628.03 959.063C1627.06 958.096 1610.62 935.865 1609.66 935.865C1608.69 934.898 1592.26 957.13 1591.29 956.163C1588.39 959.063 1583.56 963.896 1576.79 971.628C1565.19 985.161 1552.62 996.76 1539.08 1009.33C1499.45 1047.99 1455.94 1086.65 1411.47 1123.38C1321.57 1194.91 1233.59 1247.1 1146.59 1274.17C1103.08 1287.7 1059.58 1294.47 1017.04 1292.53C745.386 1282.87 512.4 1108.88 502.732 892.369C500.799 855.639 507.566 820.842 519.167 787.011C579.105 613.026 754.086 529.9 989.006 520.235C1031.54 519.268 1075.05 526.034 1118.55 539.566C1130.15 543.432 1142.72 547.299 1154.32 552.132C1230.69 581.129 1307.07 628.492 1383.44 690.353C1428.88 727.083 1471.41 764.78 1511.05 803.443C1523.62 816.009 1536.18 828.574 1547.79 841.14C1554.55 847.906 1559.39 853.705 1562.29 856.605C1563.25 855.639 1579.69 877.87 1580.65 876.903C1581.62 875.937 1598.06 853.705 1599.02 852.739C1601.92 848.872 1606.76 843.073 1613.52 835.34C1625.13 819.875 1637.69 805.376 1650.26 790.878C1689.9 744.482 1732.43 698.086 1777.87 655.556C1867.78 569.53 1956.72 504.769 2044.69 469.006C2089.16 451.607 2132.67 440.975 2175.2 440.008C2442.99 435.175 2674.05 630.425 2683.71 896.235Z' stroke='url(#paint3_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M2707.87 890.438C2719.47 1118.55 2572.53 1384.36 2236.1 1363.1C2192.6 1362.13 2148.13 1352.46 2103.66 1335.07C2011.82 1300.27 1919.98 1236.47 1829.1 1154.31C1781.73 1111.79 1737.26 1066.36 1696.66 1020.93C1683.12 1006.43 1670.55 991.929 1657.99 976.464C1651.22 968.731 1646.39 962.931 1643.49 959.065C1642.52 958.099 1626.08 935.867 1625.12 935.867C1624.15 934.901 1607.72 956.165 1606.75 955.199C1603.85 958.099 1599.02 962.931 1592.25 969.698C1579.68 982.263 1567.11 993.862 1554.55 1005.46C1513.94 1042.19 1469.47 1078.92 1424.03 1112.75C1333.16 1180.41 1243.25 1229.71 1155.28 1253.87C1110.81 1266.44 1067.3 1272.24 1024.77 1270.3C750.212 1256.77 511.425 1091.49 497.891 885.605C495.957 850.808 501.758 818.911 513.359 787.014C574.264 617.862 745.378 551.167 987.065 538.602C1029.6 536.669 1073.11 542.468 1118.54 555.034C1130.14 557.934 1142.71 562.766 1155.28 566.633C1232.62 592.731 1309.96 638.16 1388.26 696.155C1433.7 730.952 1478.17 766.715 1517.81 803.445C1530.38 815.044 1543.91 826.643 1555.51 839.209C1562.28 845.975 1567.11 850.808 1570.01 853.708C1570.98 852.741 1587.41 874.006 1588.38 873.039C1589.35 872.073 1605.78 849.841 1606.75 848.875C1609.65 845.008 1614.48 839.209 1621.25 830.51C1633.82 815.044 1646.39 800.546 1658.95 785.08C1699.56 738.684 1743.06 692.288 1789.46 648.792C1881.31 561.8 1971.21 496.072 2060.15 460.309C2104.62 441.944 2149.09 432.278 2191.63 430.345C2457.49 424.545 2694.34 618.828 2707.87 890.438Z' stroke='url(#paint4_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M2731.08 884.632C2744.62 1107.91 2616.04 1390.15 2261.24 1364.06C2216.77 1362.12 2172.3 1352.46 2126.86 1335.06C2033.09 1299.3 1940.28 1236.47 1847.47 1154.31C1799.14 1111.78 1753.7 1066.35 1712.13 1020.92C1698.6 1006.42 1685.06 991.923 1672.49 976.458C1665.73 968.725 1660.89 962.925 1657.99 959.059C1657.03 958.092 1639.62 935.861 1638.66 934.894C1637.69 933.928 1620.29 954.226 1619.32 953.26C1616.42 956.159 1611.59 960.992 1604.82 966.792C1592.25 978.391 1578.72 989.99 1566.15 1000.62C1524.58 1035.42 1480.11 1070.22 1432.74 1102.11C1339.93 1165.91 1249.06 1211.34 1160.12 1233.57C1115.65 1245.17 1072.14 1250 1028.64 1247.1C751.184 1230.67 506.597 1073.12 489.195 877.866C486.295 845.002 492.095 815.038 503.696 786.041C565.568 620.755 732.815 572.426 981.269 555.994C1023.81 554.061 1068.28 558.894 1113.71 570.493C1126.28 573.393 1137.88 577.259 1150.45 581.125C1228.76 605.29 1307.06 646.853 1386.34 701.948C1432.74 734.812 1478.18 768.642 1518.78 802.473C1532.31 813.105 1544.88 824.704 1557.45 836.303C1564.22 843.069 1569.05 847.902 1571.95 849.835C1572.92 848.869 1589.35 869.167 1591.29 868.2C1592.25 867.234 1608.69 845.002 1610.62 844.036C1613.52 840.169 1618.36 834.37 1625.12 825.671C1637.69 810.205 1650.26 795.707 1663.79 780.241C1705.36 732.879 1749.83 686.483 1796.24 642.02C1889.04 555.028 1980.89 488.333 2070.79 451.603C2116.23 433.238 2160.7 422.606 2204.2 421.639C2471.99 414.873 2713.68 607.223 2731.08 884.632Z' stroke='url(#paint5_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M2754.28 878.833C2769.75 1097.28 2659.54 1395.95 2285.41 1365.02C2240.94 1363.09 2195.51 1352.46 2150.07 1336.03C2054.36 1300.26 1959.62 1236.47 1865.84 1155.28C1816.54 1112.75 1770.14 1067.32 1727.6 1021.89C1714.07 1007.39 1700.53 992.89 1687 977.425C1680.23 969.692 1675.4 963.893 1671.53 960.026C1669.59 959.06 1653.16 936.828 1652.19 935.862C1650.26 934.895 1633.83 954.227 1632.86 953.26C1628.99 955.193 1624.16 960.026 1617.39 965.826C1604.82 977.425 1591.29 988.057 1577.75 997.723C1535.22 1030.59 1489.78 1062.48 1442.41 1093.41C1348.63 1153.34 1256.79 1194.91 1166.89 1215.2C1121.45 1224.87 1077.95 1229.7 1034.44 1226.8C754.085 1207.47 503.698 1056.68 483.396 873.034C480.496 843.07 486.297 815.039 496.931 787.975C560.736 627.522 723.15 595.625 978.371 576.293C1021.87 574.36 1066.34 578.226 1112.75 587.892C1125.32 590.792 1136.92 593.692 1149.48 597.558C1228.76 618.823 1308.03 658.453 1388.27 709.682C1435.64 740.612 1481.08 771.543 1522.65 804.407C1536.18 815.039 1549.72 824.705 1562.29 836.304C1569.05 842.103 1573.89 846.936 1576.79 848.869C1578.72 847.903 1595.16 867.234 1596.12 866.268C1598.06 865.301 1614.49 843.07 1615.46 842.103C1618.36 838.237 1624.16 831.471 1629.96 823.738C1642.53 808.273 1656.06 792.808 1669.59 778.309C1712.13 730.946 1757.57 683.584 1803.97 639.121C1898.71 551.162 1990.55 483.501 2082.4 446.771C2127.83 428.406 2173.27 416.807 2217.74 415.841C2487.46 404.242 2733.98 595.625 2754.28 878.833Z' stroke='url(#paint6_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M2777.48 873.034C2794.89 1086.65 2702.08 1402.72 2310.55 1365.02C2265.11 1363.09 2218.7 1352.46 2173.27 1335.06C2075.63 1298.33 1979.92 1235.5 1884.21 1154.31C1833.94 1111.78 1786.57 1066.35 1743.06 1020.92C1728.56 1006.42 1715.03 991.924 1701.49 976.458C1694.73 968.726 1689.89 962.926 1686.03 959.06C1684.09 958.093 1667.66 936.828 1665.73 934.895C1663.79 933.929 1647.36 952.294 1645.42 951.327C1641.56 953.26 1636.72 958.093 1629.96 963.893C1617.39 974.525 1602.89 984.191 1589.35 993.857C1545.85 1024.79 1499.44 1054.75 1451.11 1082.78C1355.4 1138.84 1262.59 1176.54 1171.72 1194.91C1126.28 1203.6 1081.81 1207.47 1037.34 1203.61C754.083 1182.34 497.895 1040.25 474.693 866.268C470.826 838.237 476.627 813.106 487.261 787.975C552.033 632.355 711.546 616.89 971.601 594.658C1015.1 591.759 1060.54 595.625 1106.95 604.324C1119.51 606.257 1132.08 610.124 1144.65 613.023C1225.86 632.355 1305.13 668.118 1386.34 716.448C1434.67 745.445 1481.08 774.443 1523.61 804.407C1537.15 814.072 1550.68 823.738 1563.25 833.404C1570.02 839.204 1574.85 843.07 1578.72 845.003C1580.65 844.036 1597.09 862.401 1598.05 861.435C1599.99 860.468 1616.42 838.237 1618.35 837.27C1622.22 833.404 1627.06 826.638 1633.82 818.905C1647.36 803.44 1659.92 787.975 1673.46 772.509C1716.96 724.18 1762.4 676.818 1810.74 632.355C1906.45 543.429 2000.22 475.769 2093.03 438.072C2139.43 418.74 2184.87 408.108 2229.34 406.175C2501.96 393.609 2753.32 583.059 2777.48 873.034Z' stroke='url(#paint7_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M2800.69 868.203C2820.03 1076.02 2745.59 1409.49 2335.69 1366.96C2289.28 1364.06 2242.88 1353.43 2196.47 1337C2096.9 1300.27 1999.26 1237.44 1902.58 1156.24C1851.34 1112.75 1803.01 1068.29 1758.54 1022.86C1744.04 1008.36 1729.53 993.858 1716 978.393C1709.23 970.66 1703.43 964.861 1699.57 960.995C1697.63 960.028 1681.2 938.763 1679.26 936.83C1677.33 935.864 1660.9 954.229 1658.96 952.295C1655.1 954.229 1650.26 958.095 1643.49 963.894C1629.96 974.527 1616.43 983.226 1601.92 991.925C1557.45 1020.92 1510.08 1048.95 1461.75 1075.05C1365.07 1127.25 1271.3 1162.04 1179.46 1177.51C1134.02 1185.24 1088.58 1188.14 1044.11 1184.28C757.954 1158.18 495.966 1023.82 468.897 860.47C464.063 834.372 469.864 812.141 480.498 787.976C547.204 637.19 701.883 638.156 968.705 612.058C1013.18 609.159 1058.61 612.058 1105.98 618.825C1118.55 620.758 1131.12 623.657 1143.69 626.557C1225.86 642.989 1307.07 676.819 1388.27 721.282C1436.61 747.38 1483.98 775.411 1527.48 803.442C1541.02 812.141 1555.52 820.84 1568.09 830.506C1574.86 836.306 1579.69 840.172 1583.56 841.138C1585.49 839.205 1601.92 857.57 1603.86 855.637C1605.79 853.704 1622.23 832.439 1624.16 830.506C1628.03 826.64 1632.86 819.874 1639.63 812.141C1653.16 796.676 1666.7 781.21 1680.23 765.745C1724.7 717.416 1771.11 669.087 1819.44 624.624C1917.08 534.732 2011.82 466.105 2105.6 428.408C2152 409.076 2198.41 397.477 2243.84 395.544C2516.47 382.978 2773.62 571.462 2800.69 868.203Z' stroke='url(#paint8_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M2823.89 862.405C2844.19 1065.39 2789.09 1415.29 2359.85 1367.93C2313.45 1365.03 2266.08 1354.4 2218.71 1337C2117.2 1300.27 2017.63 1236.47 1919.98 1156.25C1867.78 1112.75 1818.48 1068.29 1773.04 1022.86C1758.54 1008.36 1744.04 993.86 1729.54 978.395C1722.77 970.662 1716.97 964.863 1713.1 960.03C1710.2 958.096 1694.73 937.798 1691.83 935.865C1688.93 933.932 1673.46 952.297 1670.56 950.364C1666.7 952.297 1661.86 956.163 1654.13 960.996C1640.59 970.662 1626.09 979.361 1611.59 987.094C1566.16 1014.16 1517.82 1040.26 1468.51 1064.42C1369.91 1112.75 1275.16 1143.68 1182.36 1157.21C1135.95 1163.98 1090.52 1165.91 1046.05 1161.08C756.988 1131.11 489.199 1005.46 458.263 852.739C453.429 828.574 458.263 808.276 468.897 787.011C537.536 642.024 687.382 659.423 960.971 629.458C1005.44 626.559 1051.85 627.525 1099.22 634.291C1111.78 636.225 1124.35 638.158 1137.89 641.057C1221.03 655.556 1303.2 685.52 1386.34 727.083C1435.64 751.248 1483.98 776.379 1528.45 802.477C1542.95 811.176 1556.49 818.909 1570.02 827.608C1576.79 832.441 1582.59 836.307 1585.49 838.24C1587.42 836.307 1603.86 853.706 1605.79 851.772C1607.73 849.839 1624.16 828.574 1626.09 826.641C1629.96 822.775 1634.79 816.009 1641.56 808.276C1655.1 792.811 1669.6 777.346 1683.13 761.88C1728.57 712.585 1775.94 665.222 1825.24 619.793C1923.85 529.9 2020.53 460.307 2115.27 420.677C2162.64 401.345 2209.04 388.779 2255.45 386.846C2530.97 373.314 2792.96 558.898 2823.89 862.405Z' stroke='url(#paint9_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M2847.09 856.608C2868.36 1054.76 2832.59 1421.09 2384.98 1368.9C2337.61 1366 2290.24 1354.4 2241.91 1337C2137.5 1299.3 2037.92 1236.48 1938.35 1156.25C1885.18 1112.75 1833.94 1068.29 1788.5 1021.89C1773.03 1007.4 1758.53 992.896 1744.03 977.431C1737.26 969.698 1731.46 963.899 1727.6 959.066C1724.7 957.133 1708.26 936.835 1706.33 934.901C1703.43 932.968 1686.99 950.367 1685.06 948.434C1681.19 949.4 1675.39 953.266 1668.62 958.099C1655.09 966.799 1639.62 974.531 1625.12 982.264C1578.72 1007.4 1529.41 1030.59 1480.11 1052.82C1380.53 1097.29 1284.83 1124.35 1190.08 1135.95C1143.68 1141.75 1097.28 1142.72 1052.81 1137.88C760.849 1105.02 488.226 986.13 452.457 845.009C446.656 822.778 452.457 805.379 462.124 786.048C533.664 645.893 677.709 679.724 958.066 646.86C1002.54 642.994 1049.91 643.96 1097.28 649.76C1109.84 650.726 1123.38 653.626 1135.95 655.559C1220.05 667.158 1303.19 695.189 1387.3 732.886C1437.57 755.117 1485.91 778.315 1531.35 801.513C1545.85 809.246 1560.35 816.012 1573.88 824.711C1580.65 829.544 1586.45 833.41 1590.32 834.377C1593.22 832.444 1608.69 848.876 1611.59 846.942C1614.49 845.009 1629.95 823.744 1632.86 821.811C1636.72 817.945 1642.52 811.179 1649.29 803.446C1662.82 787.014 1677.33 771.549 1691.83 757.05C1738.23 707.755 1786.57 659.425 1835.87 613.996C1936.41 523.137 2034.05 453.543 2129.76 412.947C2178.1 392.649 2224.5 381.05 2270.91 378.15C2545.46 362.685 2813.25 547.302 2847.09 856.608Z' stroke='url(#paint10_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M2870.29 850.81C2892.52 1044.13 2875.12 1427.86 2410.12 1369.87C2361.78 1366 2313.44 1355.37 2266.07 1337.97C2159.73 1300.27 2058.22 1236.48 1957.68 1156.25C1903.54 1112.75 1851.34 1068.29 1803.97 1021.9C1788.5 1007.4 1773.03 992.898 1759.5 977.433C1751.76 969.7 1746.93 963.901 1742.1 959.068C1739.2 957.134 1722.76 936.836 1719.86 934.903C1716.96 932.97 1700.53 949.402 1697.63 947.469C1693.76 948.435 1687.96 952.302 1680.22 957.134C1665.72 965.834 1651.22 972.6 1635.75 979.366C1588.38 1002.56 1538.11 1023.83 1487.84 1044.13C1387.3 1084.72 1289.66 1107.92 1194.92 1117.59C1147.55 1122.42 1102.11 1122.42 1055.71 1116.62C760.848 1080.86 482.425 968.733 443.755 839.211C437.955 818.913 438.921 802.481 452.456 787.016C497.893 641.062 666.107 701.957 952.264 666.193C997.701 662.327 1045.07 662.327 1093.41 666.193C1105.98 667.16 1119.51 669.093 1132.08 671.026C1218.12 680.692 1301.26 705.823 1386.33 739.653C1437.57 759.952 1486.87 780.25 1532.31 802.481C1546.81 809.247 1562.28 816.013 1575.82 823.746C1582.58 827.612 1588.38 831.479 1592.25 832.445C1595.15 830.512 1610.62 845.977 1613.52 844.044C1616.42 842.111 1631.89 820.846 1634.79 818.913C1638.65 814.08 1644.45 808.281 1651.22 800.548C1665.72 784.116 1680.22 768.651 1694.73 753.186C1741.13 703.89 1790.43 654.594 1841.67 609.165C1943.18 517.34 2042.75 446.779 2139.43 406.183C2187.77 385.884 2235.14 373.319 2282.51 370.419C2559.96 352.054 2832.59 534.738 2870.29 850.81Z' stroke='url(#paint11_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M2892.53 845.007C2915.73 1033.49 2917.67 1433.66 2433.33 1370.83C2384.99 1366.96 2335.68 1355.36 2287.35 1337.96C2179.07 1299.3 2075.63 1236.47 1974.12 1156.25C1919.02 1112.75 1865.85 1068.29 1817.51 1021.89C1802.04 1007.39 1786.57 991.928 1772.07 977.429C1764.34 969.696 1758.54 963.897 1754.67 959.064C1751.77 957.131 1735.33 936.833 1732.43 934.899C1729.53 932.966 1713.1 948.432 1709.23 946.498C1704.4 947.465 1699.56 951.331 1691.83 955.198C1677.33 962.93 1661.86 969.696 1646.39 975.496C1598.06 996.761 1547.79 1016.09 1496.55 1034.46C1394.07 1071.19 1296.43 1091.49 1199.76 1097.29C1152.39 1100.18 1105.98 1100.18 1059.58 1094.39C761.82 1054.76 478.564 951.331 435.06 832.442C428.293 815.043 429.259 799.578 442.794 787.012C487.264 643.958 653.545 723.218 945.502 684.555C990.939 679.722 1038.31 679.722 1087.61 682.621C1100.18 683.588 1113.72 684.555 1127.25 685.521C1214.26 692.287 1299.33 714.519 1384.41 745.449C1436.61 763.814 1486.88 782.179 1533.28 801.511C1547.79 807.311 1563.25 813.11 1576.79 820.843C1584.52 824.709 1589.36 827.609 1593.22 828.575C1596.12 825.676 1612.56 842.107 1615.46 839.208C1618.36 836.308 1634.79 816.01 1637.69 814.077C1641.56 809.244 1647.36 803.444 1654.13 794.745C1668.63 778.313 1683.13 762.848 1697.63 747.382C1745 697.12 1795.27 647.824 1846.51 601.429C1949.95 509.603 2049.53 438.076 2148.14 396.513C2197.44 376.215 2245.78 362.683 2293.15 359.783C2574.47 342.385 2851.93 522.169 2892.53 845.007Z' stroke='url(#paint12_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M2915.72 839.209C2939.89 1021.89 2961.16 1439.46 2458.45 1370.83C2409.15 1366.96 2359.85 1355.36 2310.54 1337.97C2200.33 1299.3 2095.92 1235.51 1992.48 1156.25C1936.41 1112.75 1882.27 1067.32 1832.97 1021.89C1817.5 1007.39 1801.07 991.929 1786.56 977.43C1778.83 969.698 1773.03 963.898 1769.16 959.065C1765.3 957.132 1749.83 936.834 1745.96 934.901C1742.09 932.968 1726.63 947.466 1722.76 945.533C1717.93 946.5 1712.12 949.399 1705.36 953.266C1690.86 960.998 1674.42 965.831 1659.92 971.631C1610.62 989.996 1559.38 1007.39 1507.17 1023.83C1403.73 1055.72 1304.16 1073.12 1207.48 1076.99C1160.11 1078.92 1112.74 1077.95 1066.34 1071.19C765.68 1028.66 476.622 931.034 430.219 824.71C423.451 809.245 423.451 796.679 436.986 785.08C480.489 645.893 644.836 743.517 943.561 700.988C989.965 696.155 1037.34 694.222 1087.61 696.155C1101.14 696.155 1113.71 698.088 1127.24 698.088C1215.22 702.921 1301.26 722.253 1388.26 749.317C1441.44 765.749 1491.71 782.181 1539.08 799.579C1554.55 805.379 1570.01 810.212 1583.55 816.978C1591.28 820.844 1596.12 823.744 1600.95 823.744C1603.85 820.844 1620.28 836.309 1623.18 833.41C1626.08 830.51 1642.52 810.212 1645.42 808.278C1649.29 803.446 1655.09 797.646 1662.82 788.947C1677.32 772.515 1692.79 757.05 1707.29 741.584C1755.63 691.322 1806.87 641.06 1859.07 594.664C1963.48 501.872 2064.99 429.378 2164.56 387.815C2213.87 366.55 2263.17 353.985 2310.54 350.118C2588 331.753 2871.25 509.605 2915.72 839.209Z' stroke='url(#paint13_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M2937.97 834.375C2963.1 1012.23 3003.71 1447.19 2482.63 1372.76C2432.36 1367.93 2383.06 1356.33 2332.78 1338.93C2220.64 1299.3 2114.3 1236.47 2009.89 1157.21C1952.85 1113.72 1897.75 1068.29 1847.48 1022.86C1831.04 1008.36 1815.58 992.894 1800.11 977.429C1792.37 969.696 1786.57 963.897 1781.74 959.064C1777.87 957.131 1761.44 936.832 1758.54 934.899C1754.67 931.999 1738.24 947.465 1734.37 944.565C1729.53 945.532 1723.73 948.431 1716 951.331C1700.53 958.097 1685.06 962.93 1669.6 968.729C1619.33 985.161 1567.12 1000.63 1514.92 1015.13C1409.54 1043.16 1309.97 1056.69 1211.36 1058.62C1163.02 1059.59 1115.65 1057.66 1068.28 1050.89C764.721 1005.46 470.83 914.601 419.593 819.876C411.859 806.344 411.859 795.711 425.393 787.012C466.963 651.691 630.344 766.714 935.835 721.284C982.239 716.452 1030.58 712.585 1080.85 714.518C1094.38 714.518 1107.92 715.485 1121.45 715.485C1210.39 717.418 1297.4 733.85 1385.37 758.015C1438.54 772.513 1490.75 786.046 1539.09 801.511C1554.55 806.344 1570.02 810.21 1584.52 816.976C1592.26 819.876 1597.09 822.776 1601.92 822.776C1605.79 819.876 1621.26 834.375 1624.16 831.475C1628.03 828.575 1643.49 808.277 1647.36 806.344C1652.19 801.511 1658 794.745 1664.76 787.012C1679.26 770.58 1694.73 755.115 1710.2 738.683C1759.5 687.454 1811.71 637.192 1863.91 590.796C1970.25 497.037 2072.73 424.544 2173.27 382.014C2223.54 360.749 2272.85 347.217 2321.18 343.351C2602.51 321.119 2890.6 497.037 2937.97 834.375Z' stroke='url(#paint14_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M2960.2 828.576C2986.3 1001.59 3045.27 1452.99 2505.83 1373.73C2455.56 1368.9 2404.32 1357.3 2355.02 1339.9C2240.94 1300.27 2132.67 1236.47 2027.29 1158.18C1968.32 1114.68 1913.21 1069.25 1861.98 1023.83C1845.54 1009.33 1829.11 993.861 1813.64 978.396C1805.91 970.663 1800.1 964.864 1795.27 960.031C1791.4 957.131 1774.97 938.766 1771.1 935.866C1767.24 932.966 1750.8 947.465 1746.93 944.565C1742.1 944.565 1736.3 947.465 1728.57 951.332C1713.1 958.098 1696.66 961.964 1681.19 966.797C1629.96 981.296 1576.79 994.828 1523.61 1006.43C1417.27 1030.59 1315.76 1040.26 1216.19 1040.26C1167.85 1040.26 1119.51 1037.36 1072.14 1029.62C765.685 980.329 465.994 896.236 410.889 813.11C403.155 800.545 402.188 793.779 415.723 787.013C456.326 655.557 618.74 787.979 930.032 739.65C976.436 733.851 1025.74 730.951 1076.98 729.984C1090.51 729.984 1104.05 730.951 1117.58 729.984C1207.49 726.118 1296.43 743.516 1384.4 763.815C1438.54 776.38 1490.75 787.979 1540.05 801.511C1555.52 805.378 1571.95 809.244 1586.45 815.043C1594.19 817.943 1599.99 820.843 1603.85 820.843C1607.72 817.943 1623.19 831.475 1627.06 828.576C1630.92 825.676 1646.39 806.344 1650.26 802.478C1655.09 797.645 1660.89 790.879 1667.66 783.146C1683.13 766.714 1698.6 750.282 1714.06 734.817C1764.33 683.588 1816.54 633.326 1869.71 585.963C1977.02 491.238 2081.43 417.778 2182.94 375.249C2233.21 353.984 2283.48 339.485 2332.78 335.619C2616.04 311.454 2908.96 484.472 2960.2 828.576Z' stroke='url(#paint15_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M2982.43 822.776C3008.54 990.961 3087.81 1458.79 2530 1374.69C2478.76 1369.86 2427.52 1357.3 2377.25 1339.9C2261.24 1300.27 2151.03 1236.47 2044.69 1158.18C1984.75 1114.68 1928.68 1069.25 1876.47 1023.82C1860.04 1009.33 1842.64 993.861 1827.17 978.395C1819.44 970.663 1813.64 964.863 1807.84 960.03C1803 957.13 1787.53 938.765 1783.67 935.866C1778.83 932.966 1763.37 946.498 1758.53 943.598C1753.7 943.598 1747.9 946.498 1740.16 949.398C1724.7 955.197 1708.26 959.064 1691.83 962.93C1639.62 975.496 1585.48 987.095 1531.35 996.76C1423.07 1017.06 1321.56 1023.82 1221.02 1020.92C1171.72 1019.96 1124.35 1016.09 1076.01 1008.36C766.649 956.164 447.623 887.537 403.152 807.31C392.518 798.611 393.485 792.812 407.019 787.979C446.656 660.39 607.136 810.21 924.229 758.981C971.599 753.182 1020.9 749.315 1072.14 747.382C1085.68 746.416 1099.21 747.382 1112.74 746.416C1204.59 743.516 1293.53 754.148 1382.47 771.547C1437.57 782.179 1490.74 791.845 1540.05 802.477C1555.51 806.344 1571.95 808.277 1587.42 814.076C1595.15 816.976 1600.95 818.909 1605.79 818.909C1609.65 816.009 1625.12 828.575 1628.99 825.675C1632.85 822.776 1648.32 803.444 1653.16 799.578C1657.99 794.745 1663.79 787.979 1671.52 780.246C1686.99 763.814 1702.46 747.382 1718.89 731.917C1770.13 679.721 1823.3 629.459 1877.44 582.097C1986.68 487.372 2092.06 412.945 2194.53 369.449C2245.77 348.184 2296.04 333.685 2345.35 328.852C2629.57 300.821 2928.3 471.906 2982.43 822.776Z' stroke='url(#paint16_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3003.7 816.97C3029.81 980.323 3129.38 1464.58 2553.2 1375.65C2501 1369.86 2449.76 1358.26 2398.52 1340.86C2280.58 1300.26 2169.4 1236.47 2061.13 1159.14C2000.22 1115.64 1943.18 1070.21 1890.01 1023.82C1872.61 1009.32 1856.18 993.855 1839.74 978.39C1832.01 970.657 1825.24 964.857 1820.41 960.025C1815.57 957.125 1800.1 938.76 1795.27 935.86C1790.44 932.96 1774.97 945.526 1770.14 942.626C1765.3 942.626 1758.53 944.559 1750.8 947.459C1734.37 952.292 1717.93 955.192 1701.5 959.058C1647.36 969.69 1593.22 978.39 1539.08 987.089C1429.84 1003.52 1326.4 1006.42 1224.89 1001.59C1175.59 999.654 1127.25 994.822 1078.91 986.122C766.652 930.061 440.858 870.132 393.488 800.538C382.854 793.772 382.854 789.906 397.355 787.973C436.025 663.284 594.571 832.436 918.431 776.374C965.802 770.574 1016.07 765.742 1068.28 762.842C1081.81 761.875 1095.35 761.875 1109.85 760.909C1202.65 756.076 1293.53 762.842 1382.47 777.341C1438.54 786.04 1492.68 792.806 1542.95 802.472C1559.38 805.371 1575.82 807.305 1591.29 811.171C1599.02 813.104 1604.82 815.037 1609.66 815.037C1613.52 811.171 1628.99 823.737 1633.82 820.837C1637.69 816.97 1654.13 798.605 1657.99 794.739C1662.83 789.906 1668.63 783.14 1676.36 775.407C1691.83 758.975 1708.26 742.544 1723.73 726.112C1775.94 673.916 1830.07 622.687 1884.21 575.325C1994.42 479.633 2100.76 404.24 2205.17 359.777C2257.38 337.546 2307.65 323.047 2357.92 318.214C2643.11 290.183 2946.67 459.335 3003.7 816.97Z' stroke='url(#paint17_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3025.94 811.175C3052.04 969.695 3171.92 1471.35 2576.4 1376.63C2524.2 1370.83 2472 1358.26 2419.79 1340.86C2299.91 1300.27 2186.8 1236.47 2077.56 1159.14C2015.69 1115.65 1957.69 1070.22 1903.55 1023.82C1886.15 1009.32 1868.74 993.859 1852.31 978.394C1844.58 970.661 1837.81 964.862 1832.98 960.029C1828.14 957.129 1812.67 938.764 1807.84 935.864C1803.01 932.964 1786.57 944.563 1781.74 941.664C1776.9 941.664 1770.14 943.597 1762.4 945.53C1745.97 950.363 1728.57 952.296 1712.13 955.196C1657.03 963.895 1601.92 970.661 1546.82 976.461C1435.64 989.026 1332.2 988.06 1229.73 981.294C1180.42 977.427 1131.12 972.594 1081.81 963.895C766.653 904.934 435.059 852.738 384.788 793.777C373.187 789.91 373.187 787.977 387.689 787.011C425.392 666.188 582.005 852.738 912.632 793.777C960.97 787.011 1011.24 781.211 1063.44 777.345C1076.98 776.378 1091.48 775.412 1105.01 774.445C1198.79 766.712 1290.63 771.545 1381.5 782.178C1438.54 788.944 1492.68 793.777 1543.92 800.543C1560.35 802.476 1576.79 803.442 1592.26 807.309C1599.99 809.242 1605.79 811.175 1610.62 810.208C1615.46 806.342 1630.93 817.941 1634.79 814.075C1639.63 810.208 1655.09 791.843 1658.96 787.977C1663.79 783.144 1670.56 776.378 1677.33 768.645C1692.8 752.214 1709.23 735.782 1725.67 719.35C1778.84 666.188 1832.98 614.959 1889.05 567.596C2001.19 470.938 2108.5 395.545 2213.87 350.115C2266.08 327.884 2317.32 313.385 2368.55 307.586C2655.68 280.521 2964.07 446.774 3025.94 811.175Z' stroke='url(#paint18_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3047.21 805.376C3074.28 959.063 3212.52 1477.15 2599.6 1376.63C2546.43 1370.83 2493.26 1358.26 2441.06 1339.9C2319.25 1298.33 2204.2 1235.51 2093.99 1158.18C2031.16 1114.68 1972.18 1069.25 1917.08 1022.86C1899.68 1007.39 1881.31 992.893 1864.88 977.428C1857.14 969.695 1850.37 963.896 1844.57 959.063C1839.74 956.163 1823.31 937.798 1818.47 934.898C1813.64 931.998 1797.2 942.631 1792.37 939.731C1786.57 939.731 1780.77 940.698 1772.07 942.631C1755.63 946.497 1738.23 948.43 1720.83 950.364C1664.76 957.13 1609.65 961.963 1553.58 965.829C1441.44 974.528 1336.06 970.662 1232.62 960.996C1182.35 956.163 1133.05 950.364 1083.74 940.698C765.684 878.836 427.322 833.407 374.151 786.045C361.583 784.111 361.583 784.111 376.085 786.045C412.821 669.088 568.467 873.037 904.895 811.176C953.233 804.41 1003.5 797.644 1057.64 792.811C1071.18 791.844 1085.68 790.878 1100.18 788.944C1194.92 779.279 1287.73 781.212 1378.6 788.944C1436.61 793.777 1491.71 796.677 1543.92 801.51C1560.35 803.443 1577.75 803.443 1593.22 806.343C1600.95 808.276 1606.75 809.243 1612.55 808.276C1617.39 804.41 1632.86 815.042 1637.69 811.176C1642.52 807.309 1657.99 788.944 1662.83 785.078C1667.66 780.245 1674.43 773.479 1682.16 765.746C1698.59 748.348 1715.03 731.916 1731.46 716.451C1785.6 663.289 1840.71 611.093 1896.78 562.764C2009.89 465.139 2119.13 388.779 2225.47 343.35C2278.64 321.119 2329.88 305.653 2381.12 299.854C2668.24 269.89 2982.44 434.209 3047.21 805.376Z' stroke='url(#paint19_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3074.28 799.575C3074.28 950.362 3259.89 1482.95 2627.64 1377.59C2573.5 1370.82 2520.33 1358.26 2468.13 1340.86C2344.38 1299.3 2228.37 1235.5 2116.23 1159.14C2052.43 1115.65 1992.49 1070.22 1936.42 1023.82C1918.05 1008.36 1900.65 993.858 1883.25 978.393C1875.51 970.66 1868.74 964.861 1862.94 960.028C1857.14 956.161 1841.68 938.763 1836.84 935.863C1831.04 931.997 1815.57 942.629 1809.77 939.729C1803.97 938.763 1797.2 940.696 1789.47 942.629C1772.07 946.495 1754.67 946.495 1737.27 948.429C1680.23 953.262 1624.16 955.195 1567.12 958.094C1453.04 962.927 1347.67 955.195 1242.29 943.596C1192.02 937.796 1141.75 931.03 1092.45 921.364C771.487 853.704 427.325 816.973 371.253 779.277C358.686 779.277 357.719 782.176 372.22 786.043C407.023 672.953 561.703 894.3 903.931 829.539C952.268 821.806 1003.51 815.04 1057.64 808.274C1071.18 806.341 1085.68 805.374 1100.18 803.441C1196.86 790.876 1290.63 789.909 1382.47 793.775C1441.44 796.675 1496.55 796.675 1549.72 799.575C1567.12 800.542 1583.55 799.575 1599.99 802.475C1607.72 803.441 1614.49 804.408 1619.32 803.441C1624.16 799.575 1639.63 809.241 1644.46 805.374C1649.29 801.508 1664.76 783.143 1669.59 779.277C1674.43 774.444 1681.2 767.678 1688.93 758.979C1705.36 741.58 1721.8 725.148 1739.2 708.716C1794.3 655.554 1850.38 603.359 1907.41 554.063C2022.46 458.371 2132.67 381.045 2239.97 334.649C2293.15 311.451 2345.35 295.986 2397.55 290.186C2687.58 259.256 2939.9 439.04 3074.28 799.575Z' stroke='url(#paint20_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3095.54 793.782C3095.54 939.736 3301.46 1488.75 2650.84 1378.56C2596.7 1371.8 2542.56 1359.23 2489.39 1340.87C2363.72 1299.3 2245.77 1235.51 2132.66 1158.18C2067.89 1114.69 2006.02 1069.26 1949.95 1022.86C1931.58 1007.4 1913.21 992.898 1895.81 977.432C1888.08 969.7 1880.34 963.9 1874.54 959.067C1868.74 955.201 1853.27 937.803 1847.47 934.903C1841.67 931.036 1826.21 941.669 1820.41 937.803C1814.6 936.836 1807.84 938.769 1800.1 939.736C1782.7 942.635 1764.33 942.635 1746.93 943.602C1688.93 945.535 1631.89 946.502 1574.85 946.502C1459.81 946.502 1352.5 935.869 1247.12 922.337C1195.89 915.571 1145.62 907.839 1096.31 897.206C771.485 827.612 420.555 799.581 361.584 772.517C348.049 774.45 347.083 779.283 361.584 786.049C395.42 675.859 548.166 916.538 897.162 847.91C946.466 840.178 997.703 832.445 1052.81 824.712C1067.31 822.779 1080.84 820.846 1095.34 818.913C1192.99 803.448 1287.73 806.347 1380.54 800.548C1439.51 796.682 1496.54 799.581 1549.72 799.581C1567.12 799.581 1584.52 798.615 1600.95 800.548C1608.69 801.514 1615.45 802.481 1620.29 801.515C1625.12 797.648 1640.59 806.347 1645.42 802.481C1651.22 798.615 1665.73 780.25 1671.53 775.417C1677.33 770.584 1683.13 762.851 1690.86 755.119C1707.3 737.72 1724.7 721.288 1742.1 704.856C1798.17 650.728 1855.21 598.532 1912.25 549.237C2028.26 450.645 2140.4 372.352 2248.67 325.956C2302.81 302.758 2355.98 287.293 2408.19 281.493C2699.18 249.596 2954.4 428.414 3095.54 793.782Z' stroke='url(#paint21_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3115.85 788.949C3115.85 930.07 3342.07 1496.49 2673.08 1380.5C2617.97 1373.73 2563.84 1360.2 2509.7 1342.8C2382.09 1300.27 2262.21 1236.48 2148.13 1160.12C2082.4 1116.62 2019.56 1071.19 1962.52 1024.79C1944.15 1009.33 1924.82 994.831 1907.41 979.365C1898.71 971.633 1891.95 965.833 1886.15 961C1880.35 957.134 1864.88 939.736 1859.08 936.836C1853.28 932.969 1837.81 942.635 1831.04 938.769C1825.24 937.802 1818.47 938.769 1809.77 939.735C1792.37 941.669 1774 941.669 1755.64 941.669C1696.66 941.669 1638.66 940.702 1580.65 938.769C1463.68 934.903 1355.4 921.37 1249.06 904.939C1197.82 897.206 1147.55 888.507 1096.31 877.874C769.554 805.381 411.857 785.082 349.986 769.617C335.484 774.45 334.518 781.216 349.019 789.915C381.888 683.591 532.701 941.669 888.464 870.142C937.768 862.409 989.972 853.71 1045.08 844.044C1059.58 842.111 1074.08 840.178 1088.58 837.278C1187.19 819.879 1283.86 818.913 1377.64 810.213C1437.58 804.414 1495.58 804.414 1549.72 803.447C1567.12 802.481 1584.52 798.615 1601.92 802.481C1609.66 804.414 1616.42 803.447 1622.22 802.481C1628.02 797.648 1642.53 807.314 1648.33 802.481C1654.13 797.648 1668.63 780.249 1674.43 775.417C1680.23 769.617 1687 762.851 1694.73 755.118C1712.13 737.72 1729.53 721.288 1745.97 704.856C1803.01 650.727 1860.04 597.565 1919.02 548.27C2036.96 448.712 2149.1 370.419 2259.31 323.056C2313.45 299.858 2367.59 283.426 2419.79 277.627C2711.75 238.963 2968.9 416.815 3115.85 788.949Z' stroke='url(#paint22_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3137.11 783.142C3137.11 919.43 3383.63 1502.28 2695.31 1381.46C2639.24 1373.72 2584.13 1361.16 2530 1342.79C2400.45 1300.26 2279.61 1236.47 2163.6 1160.11C2096.89 1115.65 2033.09 1071.18 1975.08 1023.82C1955.75 1008.36 1937.38 993.856 1919.01 978.391C1910.31 970.658 1903.55 964.859 1897.74 960.026C1890.98 956.16 1875.51 939.728 1869.71 935.862C1862.94 931.995 1847.47 940.694 1841.67 936.828C1835.87 935.862 1828.14 936.828 1820.4 936.828C1802.04 938.761 1783.67 936.828 1766.27 936.828C1706.33 934.895 1647.36 931.029 1589.35 928.129C1471.41 920.396 1362.17 902.998 1254.86 884.633C1203.62 875.933 1152.38 866.268 1101.15 854.669C771.485 779.275 407.021 766.71 343.216 760.91C327.748 767.676 326.781 776.375 341.282 787.008C373.185 684.55 523.031 960.026 884.594 885.599C934.865 876.9 987.069 868.201 1043.14 857.568C1057.64 854.669 1072.14 852.735 1086.64 849.836C1187.19 829.537 1283.86 819.872 1378.6 814.072C1439.51 810.206 1497.51 804.406 1552.62 800.54C1570.02 799.573 1588.39 793.774 1604.82 797.64C1612.55 799.573 1619.32 798.607 1625.12 796.674C1630.92 791.841 1645.42 800.54 1651.22 795.707C1657.02 790.874 1672.49 773.476 1678.29 768.643C1684.09 762.843 1690.86 756.077 1698.59 748.345C1716 730.946 1733.4 714.514 1750.8 697.116C1808.8 642.02 1866.81 588.858 1925.78 539.563C2044.69 440.005 2158.77 360.745 2269.94 312.416C2325.05 288.251 2379.18 271.819 2432.36 266.02C2724.31 228.323 2982.43 405.208 3137.11 783.142Z' stroke='url(#paint23_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3157.42 777.342C3157.42 908.797 3423.27 1508.08 2717.55 1382.42C2661.47 1374.69 2605.4 1361.16 2551.26 1343.76C2419.79 1300.26 2297.01 1237.44 2180.03 1161.08C2112.36 1116.61 2047.59 1072.15 1988.62 1024.79C1969.28 1009.32 1949.95 994.823 1931.58 978.391C1922.88 971.625 1916.11 964.859 1909.34 960.026C1902.58 956.16 1887.11 939.728 1881.31 934.895C1874.54 931.029 1859.07 938.761 1852.31 934.895C1846.51 933.928 1838.77 933.928 1831.04 934.895C1812.67 935.862 1794.3 933.928 1775.93 932.962C1715.03 929.095 1655.09 923.296 1596.12 917.496C1476.24 905.897 1366.03 884.633 1257.76 864.334C1205.55 854.669 1154.32 844.036 1103.08 832.437C770.517 754.144 400.253 749.311 332.581 754.144C317.113 762.843 315.179 774.442 329.681 787.008C360.616 688.416 508.529 981.291 876.859 903.964C927.13 895.265 980.301 884.633 1036.37 874C1050.87 871.101 1065.37 868.201 1079.88 865.301C1181.38 842.103 1279.03 829.538 1374.73 820.838C1436.61 815.039 1495.58 807.306 1551.65 801.507C1570.02 799.573 1587.42 793.774 1604.82 796.674C1612.55 797.64 1619.32 796.674 1625.12 794.74C1630.92 789.908 1646.39 797.64 1652.19 792.807C1657.99 787.974 1673.46 770.576 1679.26 765.743C1685.06 759.944 1691.83 753.177 1699.56 745.445C1716.96 728.046 1735.33 710.648 1752.73 694.216C1811.7 639.121 1870.68 584.992 1929.65 535.696C2049.52 435.172 2165.53 354.946 2277.68 306.616C2332.78 282.452 2387.88 266.02 2442.02 259.254C2735.91 218.658 2996.94 394.576 3157.42 777.342Z' stroke='url(#paint24_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3177.72 771.543C3177.72 898.165 3463.87 1514.84 2739.78 1382.42C2682.74 1374.69 2626.67 1360.19 2571.57 1342.79C2438.16 1299.3 2313.45 1235.5 2195.5 1160.11C2126.86 1115.65 2061.13 1070.22 2001.19 1023.82C1981.85 1008.36 1961.55 993.857 1943.18 977.425C1934.48 970.659 1927.71 963.893 1920.95 959.06C1914.18 955.193 1898.71 938.761 1891.94 933.929C1885.18 929.096 1869.71 936.828 1862.94 932.962C1856.18 931.029 1849.41 931.995 1840.71 931.995C1821.37 931.995 1803 930.062 1784.64 928.129C1722.76 922.33 1661.86 914.597 1602.89 906.864C1482.04 891.399 1370.87 867.234 1260.66 844.036C1208.45 833.404 1156.25 821.805 1104.05 809.239C768.585 727.08 391.553 730.946 320.981 746.412C304.546 757.044 302.613 771.543 317.114 786.041C347.083 691.316 493.062 1002.56 867.193 921.363C917.464 912.664 971.602 901.065 1028.64 888.499C1043.14 885.599 1057.64 882.7 1073.11 878.833C1175.59 853.702 1275.16 837.27 1370.87 825.671C1433.71 817.939 1492.68 807.306 1549.72 799.574C1568.08 796.674 1586.45 789.908 1603.85 792.808C1611.59 793.774 1618.36 791.841 1625.12 789.908C1630.92 785.075 1646.39 791.841 1652.19 787.008C1658.96 782.175 1673.46 764.777 1679.26 759.944C1685.06 754.144 1691.83 747.378 1700.53 739.646C1717.93 722.247 1736.3 704.849 1754.67 688.417C1814.6 632.355 1874.54 579.193 1934.48 528.931C2056.29 427.44 2173.27 347.213 2286.38 296.951C2342.45 272.786 2397.55 255.388 2451.69 248.622C2748.48 208.025 3010.47 382.977 3177.72 771.543Z' stroke='url(#paint25_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3198.99 765.751C3198.99 887.541 3505.45 1520.65 2762.02 1383.4C2704.01 1374.7 2647.94 1361.17 2591.87 1342.8C2456.53 1299.3 2329.88 1235.51 2210.97 1160.12C2141.37 1115.65 2074.66 1070.22 2013.76 1023.83C1993.46 1008.36 1974.12 993.865 1954.79 977.433C1946.08 970.667 1938.35 963.901 1932.55 959.068C1925.78 954.235 1910.31 938.77 1903.55 933.937C1896.78 929.104 1881.31 935.87 1873.58 932.004C1866.81 930.07 1860.04 930.07 1851.34 930.07C1832.01 930.07 1812.67 926.204 1794.31 924.271C1731.47 916.538 1669.59 906.872 1609.66 896.24C1486.88 876.908 1374.74 848.877 1264.53 822.78C1211.36 810.214 1159.15 798.615 1106.95 786.049C768.587 700.99 379.955 701.957 312.282 738.687C293.914 749.319 292.947 767.684 307.449 785.083C335.484 693.258 480.496 1022.86 861.395 937.803C912.632 928.137 965.803 916.538 1023.81 903.006C1038.31 899.14 1053.78 896.24 1068.28 892.374C1171.72 864.343 1272.26 845.011 1368.94 830.512C1432.74 820.847 1492.68 808.281 1549.72 798.615C1568.09 795.715 1586.45 790.882 1604.82 788.949C1612.56 787.983 1620.29 787.983 1626.09 785.083C1632.86 780.25 1647.36 786.049 1654.13 781.217C1660.89 775.417 1675.4 758.985 1682.16 754.152C1687.96 748.353 1695.7 741.587 1703.43 733.854C1721.8 716.456 1740.17 699.057 1758.54 681.659C1818.47 625.597 1879.38 571.468 1940.28 520.239C2063.06 417.782 2181.97 336.589 2296.05 286.326C2353.08 261.195 2408.19 243.797 2463.29 237.031C2760.09 198.367 3024.01 371.386 3198.99 765.751Z' stroke='url(#paint26_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3219.29 759.947C3219.29 876.903 3546.05 1526.45 2784.25 1384.36C2726.25 1375.66 2668.25 1361.16 2612.17 1343.76C2473.93 1299.3 2347.29 1235.51 2226.44 1161.08C2154.9 1116.62 2088.2 1071.19 2025.36 1024.79C2005.06 1009.32 1984.75 994.826 1965.42 978.394C1956.72 971.628 1948.99 964.862 1942.22 960.029C1934.48 955.196 1919.98 939.731 1912.25 934.898C1904.51 930.065 1889.05 936.831 1882.28 931.998C1875.51 930.065 1867.78 930.065 1860.04 929.098C1840.71 928.132 1821.37 924.266 1802.04 921.366C1738.23 910.733 1676.36 899.134 1614.49 887.535C1490.75 863.371 1377.64 832.44 1265.5 804.409C1212.32 790.877 1159.15 778.312 1106.95 764.779C765.687 675.854 370.288 686.486 299.715 732.882C280.38 745.448 279.413 766.713 293.915 786.044C320.983 698.085 465.029 1045.09 851.728 957.129C902.965 947.464 957.103 934.898 1015.11 919.433C1029.61 915.566 1045.08 911.7 1060.54 907.834C1165.92 877.87 1266.46 855.638 1365.07 837.273C1429.84 824.708 1490.75 811.175 1548.75 798.61C1567.12 794.744 1585.49 789.911 1604.82 787.011C1612.56 786.044 1620.29 785.078 1626.09 783.145C1632.86 777.345 1647.36 783.145 1654.13 777.345C1660.89 771.546 1675.4 755.114 1682.16 749.314C1688.93 743.515 1695.7 736.749 1703.43 729.016C1721.8 711.618 1740.17 694.219 1758.54 676.821C1819.44 620.759 1881.31 565.664 1943.18 514.435C2067.9 411.977 2186.81 329.818 2302.81 278.589C2359.85 253.458 2415.92 236.059 2472 228.326C2771.69 187.73 3037.54 360.748 3219.29 759.947Z' stroke='url(#paint27_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3239.59 755.112C3239.59 867.236 3585.68 1533.21 2806.49 1386.29C2747.51 1377.59 2689.51 1363.09 2632.47 1344.73C2492.29 1300.26 2363.72 1236.47 2241.91 1162.04C2169.4 1117.58 2101.73 1072.15 2037.92 1025.76C2017.62 1010.29 1996.35 994.825 1977.02 979.359C1968.32 972.593 1960.58 965.827 1953.82 960.994C1946.08 956.161 1930.61 940.696 1923.85 935.863C1916.11 931.03 1900.64 936.83 1892.91 931.997C1886.14 930.064 1878.41 929.097 1869.71 928.13C1849.41 926.197 1830.07 922.331 1810.74 918.465C1745.96 905.899 1683.13 892.367 1621.25 878.835C1495.58 850.804 1381.5 816.973 1269.36 786.043C1216.19 771.544 1163.02 758.012 1109.85 744.48C765.683 652.655 363.517 672.953 291.011 728.048C270.709 743.513 269.742 765.745 284.243 787.009C310.345 702.917 452.457 1067.32 845.923 976.459C897.161 965.827 952.265 953.262 1011.24 936.83C1025.74 932.963 1041.21 929.097 1056.67 924.264C1163.02 891.4 1265.49 866.269 1364.1 845.004C1428.87 830.506 1490.74 814.074 1549.71 800.542C1569.05 795.709 1587.42 789.909 1605.79 787.009C1613.52 786.043 1621.25 785.076 1628.02 782.177C1634.79 776.377 1649.29 781.21 1656.06 775.41C1662.82 769.611 1678.29 753.179 1685.06 747.38C1691.83 741.58 1698.59 734.814 1707.29 726.115C1725.66 707.75 1745 691.318 1763.37 673.919C1825.24 616.891 1888.08 561.796 1949.95 510.567C2075.63 407.143 2196.47 324.017 2313.44 272.788C2371.45 247.657 2427.52 229.292 2483.59 221.559C2783.28 178.063 3051.07 349.148 3239.59 755.112Z' stroke='url(#paint28_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3258.93 749.316C3258.93 856.606 3625.32 1539.98 2826.79 1387.26C2766.85 1377.59 2708.85 1363.1 2651.81 1345.7C2509.7 1301.23 2379.19 1237.44 2256.41 1163.01C2182.94 1118.55 2114.3 1073.12 2049.52 1025.76C2028.26 1010.29 2007.95 994.828 1987.65 979.362C1978.95 972.596 1971.22 965.83 1963.48 960.997C1955.75 956.164 1940.28 940.699 1932.55 935.866C1924.81 931.033 1909.35 935.866 1901.61 931.033C1894.85 928.133 1887.11 928.133 1878.41 927.167C1858.11 925.234 1838.77 919.434 1818.47 915.568C1752.73 901.069 1688.93 885.604 1626.09 869.172C1499.45 837.275 1384.4 799.578 1270.33 766.714C1216.19 751.249 1163.02 736.75 1108.88 722.251C761.817 627.526 352.883 656.524 277.477 721.285C257.175 738.683 255.242 763.814 269.743 787.012C294.879 706.786 435.057 1089.55 834.323 994.828C886.528 984.195 941.632 970.663 1000.6 952.298C1016.07 947.465 1031.54 943.599 1046.04 938.766C1153.35 903.002 1256.79 874.971 1356.37 850.807C1422.11 834.375 1484.94 816.01 1544.88 799.578C1564.22 794.745 1582.59 787.979 1601.92 784.113C1609.65 782.18 1617.39 781.213 1624.16 778.313C1630.92 772.514 1645.42 776.38 1653.16 770.581C1660.89 764.781 1675.39 748.349 1682.16 742.55C1688.93 736.75 1695.7 729.018 1704.4 721.285C1723.73 702.92 1742.1 685.521 1761.43 668.123C1824.27 611.094 1888.08 555.033 1950.92 503.804C2078.53 399.413 2200.34 316.287 2318.28 264.092C2376.28 237.994 2433.32 220.595 2490.36 211.896C2794.89 167.433 3064.61 337.552 3258.93 749.316Z' stroke='url(#paint29_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3279.23 743.512C3279.23 845.97 3665.93 1545.78 2849.02 1387.26C2789.09 1377.59 2730.11 1363.09 2672.11 1344.73C2528.06 1299.3 2396.59 1235.5 2271.88 1161.08C2197.44 1116.61 2127.83 1071.18 2062.09 1023.82C2040.82 1008.36 2019.56 992.89 1999.25 977.425C1990.55 970.659 1982.82 963.893 1975.09 959.06C1967.35 954.227 1951.88 938.762 1944.15 933.929C1935.45 929.096 1920.95 932.962 1912.25 928.129C1905.48 925.229 1896.78 924.263 1888.08 923.296C1867.78 920.396 1847.47 914.597 1827.17 909.764C1760.47 893.332 1695.7 874.967 1632.86 857.569C1504.28 821.805 1388.27 780.242 1273.23 745.445C1219.09 729.013 1164.95 713.548 1110.81 698.083C760.851 599.491 345.15 638.154 266.844 712.581C245.575 732.88 243.642 758.977 258.143 785.075C282.312 708.715 420.557 1108.88 826.59 1011.26C878.795 1000.62 934.866 985.157 994.804 966.792C1010.27 961.96 1025.74 957.127 1041.21 952.294C1149.48 914.597 1253.89 882.7 1354.43 855.635C1421.14 837.27 1483.98 816.006 1544.88 797.641C1564.22 791.841 1583.55 785.075 1602.89 780.242C1610.62 778.309 1618.36 776.376 1625.12 773.476C1632.86 767.677 1647.36 770.576 1654.13 764.777C1661.86 758.977 1676.36 742.545 1684.09 736.746C1690.86 730.946 1698.6 723.214 1706.33 715.481C1725.66 697.116 1745 679.718 1764.33 662.319C1828.14 604.324 1891.95 549.229 1955.75 497.033C2084.33 392.643 2208.07 307.583 2326.98 255.388C2385.95 229.29 2443.96 210.925 2501 202.226C2806.49 156.797 3078.14 326.915 3279.23 743.512Z' stroke='url(#paint30_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3299.53 737.72C3299.53 835.345 3706.53 1551.58 2871.26 1388.23C2810.36 1378.56 2750.42 1363.1 2692.41 1345.7C2546.43 1300.27 2413.02 1236.48 2287.35 1162.05C2211.94 1117.59 2140.4 1072.16 2074.66 1024.8C2053.39 1009.33 2031.16 993.865 2010.86 978.399C2002.16 971.633 1993.45 964.867 1986.69 960.034C1977.99 955.201 1963.49 940.703 1954.78 934.903C1946.08 929.104 1931.58 932.97 1922.88 928.137C1915.15 925.237 1907.41 924.271 1898.71 922.338C1877.44 918.471 1857.14 912.672 1836.84 906.872C1769.17 888.507 1703.43 868.209 1639.63 848.877C1510.08 809.247 1393.1 764.785 1277.1 727.088C1221.99 709.689 1167.85 693.257 1113.71 677.792C760.852 576.301 339.35 622.697 258.144 706.79C235.909 729.021 233.975 758.018 248.476 786.049C271.678 712.589 408.956 1131.12 820.79 1030.59C873.962 1019 930.033 1003.53 989.971 984.199C1005.44 979.366 1020.91 974.533 1036.38 968.733C1146.58 928.137 1251.96 894.307 1353.47 863.376C1421.14 843.078 1484.95 819.88 1546.82 799.582C1567.12 792.815 1585.49 785.083 1605.79 780.25C1613.52 778.317 1621.26 776.384 1628.99 772.517C1636.72 765.751 1651.23 769.618 1658.96 762.851C1666.69 756.085 1681.2 740.62 1688.93 734.821C1695.7 729.021 1703.43 721.288 1712.13 713.556C1731.47 695.191 1750.8 677.792 1771.1 660.394C1835.87 602.399 1900.65 546.337 1965.42 494.141C2094 385.884 2218.71 301.792 2338.58 247.663C2397.55 221.565 2456.53 202.234 2513.56 193.534C2818.09 147.138 3091.68 315.324 3299.53 737.72Z' stroke='url(#paint31_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3319.83 731.909C3319.83 824.701 3746.16 1558.34 2892.53 1389.18C2830.66 1378.55 2770.72 1364.05 2711.75 1345.69C2563.83 1299.29 2428.49 1235.5 2301.84 1162.04C2225.47 1117.58 2152.97 1072.15 2086.26 1024.78C2064.02 1009.32 2042.76 993.853 2021.49 978.387C2012.79 971.621 2004.09 964.855 1996.35 960.022C1987.65 954.223 1972.18 940.691 1964.45 934.891C1955.75 929.092 1940.28 931.991 1931.58 927.159C1923.85 924.259 1916.11 922.326 1907.41 920.392C1886.14 915.56 1865.84 908.794 1845.54 902.994C1776.9 881.729 1710.2 860.464 1646.39 838.233C1514.91 794.737 1396.97 746.408 1279.99 706.778C1224.89 688.413 1169.78 671.014 1115.65 654.582C758.917 550.191 331.615 605.287 247.508 700.012C225.272 725.143 222.372 755.107 236.873 786.038C258.142 716.444 394.453 1152.37 813.054 1048.95C866.226 1037.35 923.264 1020.92 984.169 999.652C999.637 993.853 1015.1 989.02 1031.54 983.22C1142.72 939.724 1249.06 902.994 1351.53 868.197C1420.17 844.999 1484.94 820.835 1546.82 797.637C1567.12 789.904 1586.45 782.171 1606.75 776.372C1615.45 774.439 1623.19 771.539 1629.96 767.673C1637.69 760.906 1652.19 763.806 1659.92 757.04C1667.66 750.274 1682.16 734.809 1690.86 729.009C1697.63 723.21 1705.36 715.477 1714.06 707.744C1733.4 689.379 1753.7 671.981 1773.03 653.616C1838.77 594.654 1904.51 538.592 1969.28 486.397C2100.76 380.073 2226.44 294.047 2348.25 240.885C2408.19 214.787 2467.16 195.456 2525.16 185.79C2829.69 136.494 3105.21 304.68 3319.83 731.909Z' stroke='url(#paint32_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3339.16 726.117C3339.16 814.076 3785.8 1564.14 2913.8 1390.16C2851.92 1379.53 2791.02 1364.06 2732.05 1345.7C2582.2 1299.3 2444.92 1235.51 2317.31 1162.05C2239.97 1117.58 2166.5 1072.15 2098.83 1024.79C2076.59 1009.33 2054.36 993.86 2033.09 978.395C2023.42 971.629 2015.69 964.863 2007.95 960.03C1999.25 954.23 1983.78 940.698 1975.08 934.899C1966.38 929.099 1950.92 931.999 1942.21 926.199C1934.48 923.3 1925.78 921.366 1917.08 919.433C1895.81 914.6 1874.54 906.868 1854.24 900.102C1784.63 876.904 1716.96 852.739 1652.19 829.541C1519.75 781.212 1400.84 729.983 1282.89 688.42C1227.79 669.089 1172.68 650.723 1116.61 634.292C757.95 526.034 323.88 590.795 236.873 694.22C213.671 721.284 210.771 754.148 226.239 786.045C246.541 720.317 380.918 1174.61 805.32 1067.32C858.491 1055.72 916.496 1038.32 977.401 1016.09C992.869 1010.29 1009.3 1004.49 1024.77 998.693C1136.91 953.264 1244.22 912.667 1347.67 874.971C1417.27 849.839 1482.04 822.775 1544.88 798.611C1565.18 790.878 1584.52 781.212 1604.82 775.413C1613.52 772.513 1621.25 770.58 1628.02 766.713C1636.72 759.947 1650.26 761.88 1658.96 755.114C1667.66 748.348 1681.19 732.883 1689.89 726.117C1696.66 719.351 1704.4 712.585 1713.1 704.852C1733.4 686.487 1753.7 668.122 1773.03 650.723C1839.74 591.762 1906.45 534.734 1971.22 482.538C2104.63 375.248 2231.27 289.222 2354.05 234.127C2414.95 207.062 2473.93 187.731 2532.9 178.065C2841.29 126.836 3117.78 293.088 3339.16 726.117Z' stroke='url(#paint33_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3359.46 721.284C3359.46 804.41 3826.4 1570.91 2936.03 1392.09C2873.19 1381.46 2812.28 1365.99 2752.35 1347.63C2600.57 1301.23 2462.32 1237.44 2332.78 1163.98C2254.47 1119.52 2180.03 1074.09 2111.39 1026.72C2089.16 1011.26 2066.92 995.793 2044.69 979.362C2035.02 972.595 2027.29 965.829 2019.55 960.03C2009.88 954.23 1995.38 940.698 1986.68 934.899C1977.01 929.099 1962.51 931.032 1952.85 924.266C1945.11 920.4 1936.41 918.467 1927.71 916.534C1905.48 910.734 1884.21 903.002 1863.91 895.269C1792.37 870.138 1725.66 844.04 1659.92 818.909C1526.51 766.713 1405.67 712.585 1286.76 668.122C1230.69 646.857 1175.58 628.492 1119.51 611.094C757.947 499.937 318.077 572.431 227.203 686.487C204.001 716.451 199.168 750.282 215.602 785.079C234.937 723.217 367.381 1194.91 798.551 1084.72C852.688 1072.15 909.726 1054.75 972.565 1030.59C988.033 1024.79 1004.47 1018.99 1019.94 1012.23C1133.04 963.896 1242.29 920.4 1345.73 879.804C1415.34 852.739 1482.04 823.742 1545.85 796.678C1566.15 787.978 1586.45 778.312 1606.75 771.546C1615.45 768.647 1623.19 765.747 1629.95 761.881C1638.65 755.114 1652.19 756.081 1660.89 749.315C1669.59 742.549 1684.09 727.084 1691.82 720.318C1699.56 713.552 1707.29 706.785 1715.99 699.053C1736.29 680.688 1756.6 662.323 1776.9 644.924C1844.57 584.996 1911.28 527.968 1977.98 474.806C2112.36 367.515 2240.94 280.523 2364.68 224.461C2425.59 197.397 2485.52 178.065 2544.5 167.433C2851.92 116.204 3131.31 281.489 3359.46 721.284Z' stroke='url(#paint34_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3378.8 715.484C3378.8 792.811 3866.04 1576.71 2956.33 1393.06C2892.53 1381.46 2830.66 1365.99 2770.72 1347.63C2617 1300.27 2476.83 1236.47 2346.32 1163.98C2267.04 1119.52 2191.64 1074.09 2122.03 1026.72C2098.83 1011.26 2076.59 995.793 2054.36 979.361C2044.69 972.595 2035.99 965.829 2028.26 960.03C2018.59 954.23 2004.09 940.698 1994.42 934.899C1984.75 929.099 1970.25 930.066 1960.58 923.3C1952.85 919.433 1944.15 917.5 1935.45 914.6C1913.21 907.834 1891.94 899.135 1870.68 891.402C1798.17 864.338 1730.5 836.307 1663.79 808.276C1528.45 752.215 1406.64 694.22 1286.76 647.824C1230.69 625.592 1174.62 606.261 1118.55 588.862C754.083 473.839 307.446 555.998 214.639 679.721C190.47 711.618 185.636 748.348 202.071 785.078C220.439 726.117 351.917 1216.17 788.886 1102.12C843.024 1089.55 901.029 1071.19 963.867 1046.06C979.335 1040.26 995.77 1033.49 1012.2 1026.72C1126.28 975.495 1236.49 929.099 1340.9 885.603C1411.47 856.606 1478.18 824.708 1542.95 796.677C1564.22 787.012 1583.55 777.346 1604.82 768.647C1613.52 765.747 1621.26 761.88 1628.99 758.014C1637.69 751.248 1652.19 751.248 1659.93 744.482C1668.63 737.716 1683.13 723.217 1691.83 715.484C1699.56 708.718 1707.3 701.952 1716 694.22C1736.3 675.855 1757.57 657.49 1777.87 639.124C1846.51 579.196 1914.18 521.201 1980.89 468.039C2117.2 359.782 2246.74 271.823 2371.45 215.761C2433.32 188.697 2493.26 168.399 2553.2 157.766C2863.52 106.538 3143.88 270.857 3378.8 715.484Z' stroke='url(#paint35_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3399.1 709.683C3399.1 782.176 3905.68 1583.47 2978.57 1393.06C2914.76 1381.46 2851.92 1365.99 2791.02 1347.63C2635.37 1300.26 2493.26 1236.47 2361.78 1163.98C2281.54 1119.51 2205.17 1073.12 2134.6 1025.75C2111.4 1010.29 2088.19 994.824 2065.96 978.392C2056.29 971.626 2047.59 964.86 2039.86 959.061C2030.19 953.261 2015.69 939.729 2006.02 933.93C1996.35 927.164 1980.89 928.13 1971.22 921.364C1963.48 917.498 1954.78 914.598 1945.12 911.698C1922.88 903.966 1900.65 895.266 1879.38 886.567C1805.9 857.57 1737.26 826.639 1670.56 797.642C1534.25 737.713 1411.47 675.852 1290.63 627.523C1233.59 604.325 1177.52 584.027 1120.48 565.662C753.117 447.739 300.679 537.631 204.005 671.986C179.836 705.816 174.035 745.446 190.47 784.109C207.872 729.014 337.416 1236.47 781.152 1119.51C836.257 1105.98 894.262 1086.65 958.067 1060.55C973.535 1053.79 989.97 1047.02 1006.4 1040.25C1122.41 987.092 1232.62 937.796 1338.97 890.433C1410.5 858.536 1478.18 825.672 1543.92 794.742C1565.18 785.076 1585.49 773.477 1606.75 764.778C1615.45 760.911 1623.19 758.012 1630.92 753.179C1639.62 745.446 1654.12 745.446 1662.83 738.68C1671.53 730.947 1686.03 717.415 1694.73 709.683C1702.46 702.916 1710.2 696.15 1718.9 687.451C1739.2 669.086 1760.47 650.721 1781.74 632.356C1851.34 572.428 1919.98 514.433 1987.65 460.304C2123 353.98 2254.47 265.055 2380.15 208.993C2442.02 180.962 2502.93 160.664 2562.87 150.031C2875.13 95.9027 3157.42 259.255 3399.1 709.683Z' stroke='url(#paint36_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3418.44 703.887C3418.44 771.547 3945.31 1589.28 2999.84 1394.03C2935.06 1382.43 2872.22 1366 2810.35 1347.63C2652.77 1299.3 2508.73 1236.47 2376.28 1163.98C2294.11 1119.52 2217.74 1073.12 2146.2 1025.76C2123 1010.29 2099.79 994.828 2076.59 978.396C2066.92 971.63 2058.22 964.864 2049.52 959.064C2039.86 952.298 2024.39 939.733 2014.72 933.933C2004.09 927.167 1989.58 927.167 1979.92 920.401C1971.22 916.535 1962.52 913.635 1953.82 909.769C1930.61 902.036 1909.34 892.37 1887.11 882.704C1812.67 850.807 1743.06 818.91 1675.39 787.013C1537.15 723.218 1413.4 658.457 1291.59 607.228C1234.56 583.064 1177.52 561.799 1120.48 543.434C750.215 421.645 291.011 520.236 191.436 665.223C166.3 701.953 160.5 742.55 176.934 784.113C192.402 732.884 320.98 1258.7 771.484 1137.88C826.588 1124.35 885.56 1104.05 949.365 1076.99C965.8 1070.22 982.235 1063.46 998.669 1054.76C1115.65 998.694 1227.79 946.499 1334.13 896.236C1406.64 862.406 1474.31 827.609 1541.01 794.745C1562.28 784.113 1583.55 772.514 1604.82 762.848C1613.52 758.982 1622.22 755.115 1628.99 750.282C1638.66 742.55 1652.19 741.583 1660.89 733.851C1670.56 726.118 1684.09 712.586 1693.76 704.853C1701.49 698.087 1709.23 690.354 1717.93 682.622C1739.2 664.257 1760.47 645.892 1780.77 627.527C1851.34 566.632 1919.98 508.637 1988.62 454.508C2127.83 344.318 2259.31 255.392 2386.92 198.364C2449.76 170.333 2510.66 150.035 2571.57 139.403C2885.76 86.2405 3169.98 247.66 3418.44 703.887Z' stroke='url(#paint37_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3438.74 698.086C3438.74 760.914 3985.92 1595.07 3021.11 1394.99C2955.37 1382.43 2892.53 1366.96 2830.66 1348.6C2671.15 1300.27 2526.13 1236.47 2391.76 1164.95C2308.62 1120.48 2231.28 1074.09 2158.77 1026.72C2134.6 1011.26 2111.4 995.793 2088.2 979.362C2078.53 972.596 2069.83 965.829 2061.13 960.03C2050.49 953.264 2035.99 940.698 2026.33 934.899C2015.69 928.133 2001.19 927.166 1990.56 920.4C1981.86 916.534 1973.15 912.667 1964.45 909.768C1941.25 901.068 1919.02 890.436 1896.78 880.77C1821.38 846.94 1750.8 813.109 1683.13 779.279C1543.92 711.618 1419.21 642.991 1296.43 589.829C1239.39 564.698 1181.39 542.466 1124.35 523.135C750.219 398.446 286.181 505.736 183.706 660.389C157.604 699.053 151.803 742.549 168.238 785.079C182.739 737.716 309.383 1280.94 765.687 1157.21C820.792 1143.68 880.73 1122.42 945.502 1094.38C961.937 1087.62 978.372 1079.89 994.807 1071.19C1112.75 1012.23 1225.86 957.13 1333.17 903.968C1406.64 868.205 1475.28 830.508 1541.99 795.711C1563.25 784.112 1584.52 772.513 1605.79 761.881C1614.49 758.014 1623.19 754.148 1630.93 748.348C1640.59 740.616 1654.13 738.683 1663.8 730.95C1673.46 723.217 1687 709.685 1696.66 701.952C1704.4 695.186 1713.1 687.454 1721.8 679.721C1743.07 660.389 1764.34 642.024 1785.61 623.659C1857.14 562.765 1926.75 503.803 1996.36 449.674C2136.53 339.484 2269.95 249.592 2399.49 191.597C2462.33 163.566 2524.2 142.301 2586.07 131.669C2897.36 75.607 3183.52 237.026 3438.74 698.086Z' stroke='url(#paint38_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3458.08 693.253C3458.08 751.248 4025.56 1601.84 3042.38 1396.93C2976.64 1384.36 2911.86 1367.93 2849.99 1349.56C2688.55 1301.23 2541.6 1237.44 2406.26 1165.91C2322.15 1121.45 2243.84 1075.05 2170.37 1027.69C2146.2 1012.23 2122.03 996.76 2099.8 980.328C2090.13 973.562 2081.43 966.796 2072.73 960.997C2062.09 954.23 2047.59 942.631 2036.96 935.865C2026.32 929.099 2011.82 928.133 2001.19 920.4C1992.49 915.567 1983.79 912.667 1974.12 908.801C1950.92 899.135 1927.72 888.503 1905.48 877.87C1829.11 842.107 1757.57 805.377 1688.93 770.58C1547.78 698.086 1422.11 626.559 1298.36 571.464C1240.36 545.366 1183.32 522.168 1125.32 502.836C747.319 373.314 276.513 488.338 171.138 653.623C145.035 694.22 138.268 739.649 154.703 785.078C168.237 741.582 293.914 1302.2 756.019 1175.58C812.091 1161.08 872.029 1139.81 936.801 1109.85C953.236 1102.12 969.67 1094.38 986.105 1085.69C1105.01 1024.79 1219.09 965.829 1327.37 909.768C1400.84 872.071 1471.41 832.441 1539.08 795.711C1561.32 784.112 1582.59 770.58 1603.86 759.947C1612.56 755.114 1621.26 751.248 1628.99 746.415C1638.66 738.683 1652.19 735.783 1661.86 728.05C1671.53 720.317 1685.06 706.785 1695.7 699.053C1703.43 692.287 1712.13 684.554 1720.83 676.821C1742.1 657.49 1764.34 639.125 1785.6 620.759C1858.11 558.898 1928.68 499.937 1998.29 445.808C2140.4 334.651 2274.78 243.792 2405.29 185.797C2469.09 156.8 2531.93 135.535 2592.84 124.903C2908 65.9412 3196.09 225.427 3458.08 693.253Z' stroke='url(#paint39_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3477.41 687.459C3477.41 740.621 4064.22 1608.61 3063.64 1397.9C2996.93 1385.33 2932.16 1368.9 2869.32 1349.57C2705.94 1301.24 2557.06 1237.44 2420.75 1164.95C2335.68 1120.49 2256.41 1074.09 2181.97 1026.73C2157.8 1011.26 2133.63 995.799 2110.43 979.367C2100.76 972.601 2091.09 965.835 2082.39 960.036C2071.76 953.269 2057.26 941.67 2046.62 934.904C2035.99 928.138 2021.49 926.205 2009.89 918.473C2001.19 913.64 1991.52 909.773 1982.82 905.907C1958.65 896.241 1936.41 884.642 1913.21 873.043C1835.87 835.346 1763.37 796.683 1693.76 758.986C1551.65 682.626 1425 608.2 1299.33 549.238C1241.32 522.174 1183.32 498.009 1124.35 477.711C744.414 346.256 267.808 469.978 159.532 644.93C132.463 688.426 125.696 735.788 142.131 783.151C154.699 742.555 278.442 1321.54 747.314 1192.02C803.386 1177.52 864.291 1155.29 930.03 1124.35C946.464 1116.62 962.899 1108.89 980.301 1099.22C1100.18 1035.43 1215.22 973.568 1324.46 914.606C1398.9 874.01 1469.47 833.413 1538.11 793.783C1560.35 781.218 1581.62 767.686 1603.85 756.087C1612.55 751.254 1621.25 746.421 1628.99 741.588C1638.66 733.855 1652.19 729.989 1662.82 722.256C1672.49 713.557 1686.99 700.992 1696.66 692.292C1704.39 685.526 1713.09 677.794 1721.8 670.061C1744.03 650.729 1765.3 632.364 1787.53 613.999C1861.01 552.138 1932.55 492.21 2003.12 438.081C2146.2 325.958 2282.51 235.099 2413.99 176.137C2477.79 147.14 2541.6 125.875 2603.47 114.276C2919.6 55.3146 3209.62 214.801 3477.41 687.459Z' stroke='url(#paint40_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3497.71 681.656C3497.71 729.985 4104.83 1614.41 3084.91 1398.86C3017.24 1385.33 2952.47 1368.9 2888.66 1350.53C2722.38 1301.24 2572.53 1237.44 2435.26 1165.91C2349.22 1121.45 2268.98 1075.06 2193.57 1027.69C2168.43 1012.23 2144.27 996.762 2121.06 980.33C2111.4 973.564 2101.73 966.798 2093.03 960.998C2081.43 954.232 2066.93 942.633 2056.29 935.867C2044.69 929.101 2030.19 926.201 2019.55 918.469C2010.85 913.636 2001.19 909.77 1991.52 904.937C1967.35 894.304 1944.15 881.739 1920.95 870.14C1842.64 829.543 1769.17 788.947 1699.56 750.283C1555.52 670.057 1427.91 591.764 1302.23 530.869C1243.26 502.838 1185.25 477.707 1126.28 457.409C743.449 323.054 261.042 454.509 148.9 640.093C121.831 685.522 114.097 734.818 130.531 785.08C142.132 748.35 263.942 1345.7 739.582 1212.31C796.62 1197.81 857.525 1174.61 923.264 1141.75C939.699 1134.02 957.1 1125.32 973.535 1115.65C1095.34 1048.96 1211.35 985.163 1321.56 922.335C1396.97 879.806 1468.51 836.309 1538.11 794.746C1560.35 781.214 1582.59 767.682 1604.82 755.116C1613.52 750.283 1622.22 745.451 1630.92 739.651C1641.56 730.952 1655.09 728.052 1664.76 719.353C1675.39 710.654 1688.93 698.088 1698.59 689.389C1707.3 682.623 1715.03 674.89 1724.7 667.157C1746.93 647.826 1769.17 629.461 1791.4 610.129C1865.84 547.301 1937.38 488.34 2008.92 432.278C2153.93 320.154 2291.21 227.362 2423.66 167.434C2488.43 138.437 2552.23 116.205 2615.07 104.606C2930.23 45.6449 3222.19 203.198 3497.71 681.656Z' stroke='url(#paint41_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3517.04 675.857C3517.04 719.353 4144.46 1620.21 3106.18 1398.86C3038.5 1385.33 2971.8 1368.9 2908.96 1349.56C2740.75 1300.27 2589.93 1236.47 2450.72 1164.95C2363.72 1120.48 2281.54 1074.09 2206.14 1025.76C2181 1010.29 2155.86 993.862 2132.66 978.397C2123 971.631 2113.33 964.865 2104.63 959.065C2093.03 952.299 2078.52 940.7 2067.89 932.967C2056.29 925.235 2041.79 922.335 2030.19 914.602C2021.49 909.769 2011.82 904.936 2002.15 901.07C1977.98 889.471 1954.78 876.906 1931.58 864.34C1852.31 821.81 1778.83 779.281 1707.29 738.684C1562.28 653.625 1433.7 573.399 1306.09 509.604C1247.12 480.607 1188.15 454.509 1129.18 433.244C741.514 297.923 252.34 438.077 137.297 633.327C109.261 680.689 101.527 732.885 117.962 785.08C128.596 752.216 248.473 1366.96 729.913 1230.67C786.951 1215.21 848.823 1192.01 915.528 1158.18C931.963 1149.48 949.365 1140.78 966.766 1131.12C1089.54 1062.49 1206.52 994.829 1317.7 929.101C1394.07 884.638 1465.61 839.209 1536.18 795.713C1558.42 781.214 1580.65 766.715 1603.85 754.15C1612.55 749.317 1621.25 743.517 1629.95 737.718C1640.59 729.018 1654.12 725.152 1663.79 716.453C1674.42 707.754 1687.96 695.188 1698.59 686.489C1707.29 679.723 1715.99 671.99 1724.7 664.258C1746.93 644.926 1769.17 625.594 1791.4 607.229C1865.84 544.401 1939.31 484.473 2010.85 428.411C2156.83 315.321 2296.04 222.529 2429.45 161.635C2495.19 131.671 2559 110.406 2621.84 97.8403C2941.83 35.9791 3234.75 191.599 3517.04 675.857Z' stroke='url(#paint42_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3536.38 670.05C3536.38 708.714 4184.1 1626.97 3127.44 1399.82C3058.81 1386.29 2992.1 1368.89 2928.29 1350.52C2758.15 1300.26 2605.4 1237.43 2465.22 1165.91C2377.25 1121.44 2294.11 1075.05 2216.77 1026.72C2191.63 1011.25 2166.5 994.822 2142.33 979.357C2132.66 972.591 2122.99 965.825 2113.33 960.025C2101.73 952.292 2087.23 941.66 2075.62 933.927C2064.02 926.195 2049.52 922.328 2037.92 914.596C2028.25 909.763 2019.55 904.93 2009.89 900.097C1984.75 887.531 1961.55 874.966 1938.35 861.434C1858.11 816.971 1783.67 772.508 1712.13 729.012C1566.15 640.086 1435.64 555.994 1308.03 490.266C1248.09 460.302 1189.12 433.238 1130.15 411.973C739.58 272.785 244.605 420.672 126.662 626.554C97.6599 675.85 89.926 729.979 106.361 784.107C115.061 755.11 234.938 1387.25 722.178 1247.1C779.216 1231.63 841.088 1206.5 908.761 1171.71C925.195 1163.01 942.597 1154.31 959.998 1143.68C1083.74 1072.15 1201.68 1001.59 1313.83 932.961C1390.2 886.565 1463.67 839.202 1534.25 792.806C1557.45 778.308 1579.68 762.842 1601.92 749.31C1610.62 743.511 1620.29 738.678 1628.02 731.912C1638.65 723.212 1652.19 718.38 1662.82 709.68C1673.46 700.981 1686.99 688.415 1697.63 679.716C1706.33 672.95 1715.03 665.218 1723.73 657.485C1745.96 638.153 1769.17 618.822 1791.4 600.456C1866.81 537.629 1941.25 476.734 2013.75 420.672C2161.66 306.616 2300.88 212.857 2436.22 151.962C2501.96 121.998 2566.73 99.7669 2630.54 87.2014C2952.46 25.3401 3248.29 180.96 3536.38 670.05Z' stroke='url(#paint43_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3555.72 665.219C3555.72 699.049 4222.77 1633.73 3147.75 1401.75C3078.15 1387.26 3011.44 1370.82 2946.67 1351.49C2774.59 1301.23 2619.91 1237.44 2478.76 1166.88C2389.82 1122.41 2305.71 1076.02 2227.41 1027.69C2201.31 1012.22 2176.17 995.79 2152 979.358C2142.33 972.592 2131.7 965.826 2123 960.027C2111.4 952.294 2096.9 941.662 2085.3 933.929C2072.73 926.196 2059.19 921.363 2046.63 913.631C2036.96 907.831 2027.29 902.998 2017.62 898.165C1992.49 885.6 1968.32 871.101 1945.12 857.569C1863.91 811.173 1788.5 764.777 1716 719.348C1568.09 626.556 1436.61 538.597 1308.03 470.936C1248.09 439.039 1188.15 411.975 1128.22 389.743C737.651 246.689 236.876 404.242 115.066 620.756C86.0633 672.952 77.3626 729.013 93.7973 785.075C101.531 759.944 219.474 1409.49 713.482 1266.43C771.487 1250 833.359 1224.87 901.031 1189.11C917.466 1180.41 934.867 1170.74 952.269 1160.11C1076.98 1085.68 1195.89 1012.22 1309 940.695C1386.34 891.399 1460.78 842.104 1532.32 794.741C1555.52 779.276 1577.75 763.81 1600.96 749.312C1609.66 743.512 1619.32 737.713 1628.02 731.913C1638.66 723.214 1652.19 717.414 1662.83 708.715C1674.43 700.016 1687 687.45 1698.6 678.751C1707.3 671.019 1716 664.253 1725.67 656.52C1748.87 637.188 1771.1 617.857 1794.31 598.525C1870.68 534.73 1946.08 473.836 2018.59 417.774C2167.47 302.751 2308.61 208.992 2444.93 147.131C2511.63 117.167 2576.4 93.9689 2641.18 81.4034C2964.07 15.6758 3260.86 169.362 3555.72 665.219Z' stroke='url(#paint44_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3576.02 659.422C3576.02 688.419 4263.37 1639.54 3169.98 1402.72C3100.38 1388.22 3032.71 1370.83 2966.97 1352.46C2792.95 1302.2 2636.34 1238.4 2494.23 1167.84C2404.32 1123.38 2319.25 1076.99 2239.97 1028.66C2213.87 1013.19 2188.74 996.759 2163.6 980.327C2152.97 973.561 2143.3 966.795 2133.63 960.995C2121.06 953.263 2107.53 942.63 2094.96 934.898C2082.39 927.165 2067.89 921.366 2056.29 913.633C2046.62 907.833 2036.96 903 2027.29 897.201C2002.15 883.669 1977.99 869.17 1953.82 854.671C1871.64 806.342 1795.27 757.047 1722.76 710.651C1573.89 613.992 1441.44 523.134 1310.93 452.573C1250.99 419.709 1191.05 391.678 1130.15 369.447C735.716 221.56 228.174 386.845 103.463 613.992C73.4942 668.121 64.7934 726.116 81.2281 785.077C87.9954 762.846 204.005 1431.72 704.78 1284.8C762.785 1268.37 825.623 1242.27 894.262 1205.54C911.664 1195.87 929.065 1186.21 946.467 1175.58C1072.14 1099.22 1192.02 1021.89 1307.06 947.463C1385.37 896.234 1459.81 845.005 1532.32 794.743C1555.52 778.311 1578.72 761.879 1601.92 746.414C1611.59 740.615 1620.29 733.849 1628.99 728.049C1640.59 719.35 1653.16 712.584 1664.76 703.884C1676.36 694.219 1689.89 682.62 1700.53 673.92C1709.23 666.188 1718.9 658.455 1727.6 650.722C1750.8 631.391 1774 612.059 1797.2 592.728C1874.54 528.933 1949.95 467.072 2024.39 411.01C2174.24 295.987 2316.35 200.295 2453.62 138.434C2520.33 107.503 2586.07 85.2718 2650.84 71.7396C2974.7 5.04545 3273.43 158.732 3576.02 659.422Z' stroke='url(#paint45_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3595.36 653.623C3595.36 677.788 4303.01 1645.34 3191.26 1403.69C3120.68 1389.19 3052.04 1371.79 2986.3 1352.46C2810.36 1301.23 2652.78 1238.41 2508.73 1167.84C2416.89 1123.38 2331.82 1076.99 2251.58 1028.66C2225.48 1013.19 2199.37 996.76 2174.24 980.328C2163.6 973.562 2153.94 966.796 2144.27 960.996C2131.7 953.264 2117.2 942.631 2105.6 934.899C2093.03 927.166 2078.53 921.366 2065.96 912.667C2056.29 906.868 2046.63 901.068 2036.96 896.235C2011.82 881.737 1986.69 867.238 1962.52 851.772C1879.38 801.51 1802.04 750.281 1728.57 700.986C1577.75 600.461 1444.34 505.736 1313.83 433.242C1252.93 399.412 1192.99 370.414 1132.08 347.216C733.785 196.43 220.442 369.448 92.8314 607.227C61.8955 663.289 53.1948 724.184 69.6295 785.078C75.4299 766.713 190.473 1452.99 696.082 1303.17C755.053 1286.73 817.892 1259.67 886.531 1221.01C903.932 1211.34 921.334 1201.68 938.735 1190.08C1065.38 1110.82 1187.19 1031.56 1302.23 953.264C1381.51 900.102 1456.91 845.973 1530.38 794.744C1554.55 778.312 1577.75 760.914 1600.96 744.482C1610.62 737.716 1619.32 731.916 1628.03 725.15C1639.63 715.484 1652.19 708.718 1663.8 700.019C1675.4 690.353 1688.93 678.754 1700.53 669.088C1709.23 661.356 1718.9 653.623 1727.6 645.89C1750.8 626.559 1774.97 607.227 1798.17 587.895C1876.48 523.134 1952.85 462.24 2027.29 405.211C2179.07 289.221 2323.12 193.53 2461.36 130.702C2529.03 99.7713 2594.77 76.5733 2660.51 63.0412C2985.34 -4.61958 3286.96 147.134 3595.36 653.623Z' stroke='url(#paint46_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3614.69 647.824C3614.69 667.156 4342.65 1652.1 3211.55 1404.66C3140.01 1389.19 3071.38 1371.79 3005.64 1352.46C2827.75 1301.23 2668.24 1237.44 2523.23 1167.85C2430.42 1123.38 2344.38 1076.02 2263.17 1028.66C2236.11 1013.19 2210 996.761 2184.87 980.329C2174.23 973.563 2164.57 966.797 2154.9 960.997C2142.33 953.264 2127.83 943.599 2115.26 934.899C2102.69 926.2 2088.19 920.401 2075.63 911.701C2065.96 905.902 2055.32 900.102 2045.66 894.303C2019.55 878.838 1995.39 863.372 1970.25 847.907C1886.14 794.745 1807.84 742.55 1734.36 691.321C1581.62 585.963 1447.24 488.338 1314.8 413.912C1253.89 379.115 1192.99 349.151 1132.08 325.953C731.848 171.299 211.738 353.017 81.227 601.429C50.2911 660.39 40.6236 723.218 57.0583 786.046C61.892 771.547 175.001 1475.22 687.377 1322.5C746.349 1305.1 810.154 1278.04 879.76 1238.41C897.161 1228.74 914.563 1218.11 932.931 1206.51C1061.51 1124.35 1183.32 1042.19 1299.33 960.997C1378.6 905.902 1454.97 849.84 1529.41 795.712C1553.58 778.313 1576.78 760.915 1600.95 743.516C1610.62 736.75 1619.32 729.984 1628.99 723.218C1640.59 713.552 1654.12 705.819 1665.73 696.154C1677.33 686.488 1690.86 674.889 1702.46 665.223C1711.16 657.49 1720.83 649.758 1730.5 642.025C1754.67 622.693 1777.87 602.395 1801.07 584.03C1880.34 519.269 1957.68 457.408 2033.09 400.379C2186.8 283.423 2331.81 187.731 2471.03 123.937C2538.7 93.0063 2606.37 69.8083 2672.11 55.3096C2996.94 -14.2843 3299.53 135.536 3614.69 647.824Z' stroke='url(#paint47_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3634.03 642.024C3634.03 656.523 4381.32 1657.9 3232.83 1404.66C3161.29 1389.19 3091.68 1371.79 3024.98 1352.46C2845.16 1300.27 2683.72 1237.44 2537.74 1167.84C2443.96 1123.38 2356.95 1076.02 2274.78 1027.69C2247.71 1012.23 2221.61 995.793 2195.51 979.361C2184.87 972.595 2175.21 965.829 2164.57 960.03C2151.04 952.297 2137.5 942.631 2124.94 933.932C2111.4 925.233 2097.87 918.467 2084.33 909.767C2074.66 903.968 2064.03 897.202 2054.36 891.402C2028.26 875.937 2003.13 859.505 1977.99 843.073C1892.92 787.978 1814.61 732.883 1739.2 679.721C1585.49 571.464 1450.15 469.972 1317.7 392.646C1255.83 356.882 1194.93 325.952 1133.05 301.787C729.92 144.234 204.01 333.684 70.5985 591.762C38.6958 652.657 29.0284 717.418 45.4631 782.179C49.33 773.479 160.506 1495.52 679.649 1339.9C738.621 1322.5 803.393 1294.47 872.998 1252.9C890.4 1243.24 907.801 1231.64 926.169 1220.04C1055.71 1134.98 1178.49 1049.92 1295.47 965.829C1375.71 907.834 1453.05 850.806 1528.45 794.744C1552.62 776.379 1576.79 758.014 1599.99 740.616C1609.66 733.849 1618.36 727.083 1628.03 719.351C1639.63 709.685 1653.16 700.986 1664.76 691.32C1677.33 681.654 1689.9 670.055 1702.47 660.389C1712.13 652.657 1720.84 644.924 1730.5 637.191C1754.67 616.893 1778.84 597.561 1802.04 578.23C1882.28 512.502 1960.59 450.641 2035.99 392.646C2190.67 274.723 2336.65 178.065 2477.8 114.27C2546.44 82.373 2614.11 59.175 2679.85 44.6763C3007.58 -24.9177 3312.1 124.903 3634.03 642.024Z' stroke='url(#paint48_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3653.36 637.195C3653.36 646.86 4420.96 1664.67 3253.13 1406.59C3180.62 1391.13 3111.01 1372.76 3043.34 1353.43C2861.59 1301.24 2698.21 1238.41 2551.27 1167.85C2456.53 1123.39 2368.55 1076.02 2285.41 1027.69C2258.34 1011.26 2231.27 995.797 2205.17 979.365C2194.54 972.599 2183.9 965.833 2174.24 960.033C2160.7 951.334 2147.17 942.635 2133.63 933.935C2120.1 925.236 2106.56 917.503 2093.03 908.804C2082.4 902.038 2072.73 896.239 2062.09 889.473C2035.99 873.041 2009.89 856.609 1984.75 839.21C1898.71 782.182 1819.44 725.154 1744.03 670.058C1589.35 556.968 1452.08 452.577 1318.67 373.318C1256.79 336.588 1194.92 304.69 1133.05 280.526C727.016 120.073 195.305 318.222 58.0271 585.966C26.1244 648.794 15.4902 716.454 31.9249 783.149C33.8584 775.416 144.067 1515.82 669.978 1356.33C730.883 1339.9 795.655 1310.9 866.228 1268.37C883.629 1257.74 901.997 1247.11 919.399 1234.54C1049.91 1147.55 1173.65 1058.62 1291.6 971.632C1372.8 911.704 1451.11 851.776 1526.52 793.781C1550.68 774.449 1574.85 756.084 1599.02 737.719C1608.69 729.986 1618.36 723.22 1627.06 715.488C1639.63 705.822 1652.19 696.156 1663.79 686.49C1676.36 676.825 1688.93 665.225 1701.5 655.56C1711.16 647.827 1720.83 640.094 1729.53 632.362C1753.7 612.063 1777.87 592.732 1802.04 573.4C1883.25 507.673 1961.55 444.845 2038.89 386.85C2195.5 268.927 2342.45 171.302 2484.56 105.574C2554.17 73.6772 2621.84 49.5126 2688.55 35.0139C3018.21 -34.5801 3324.67 113.307 3653.36 637.195Z' stroke='url(#paint49_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M3673.66 631.39C3673.66 636.223 4461.56 1671.43 3275.36 1407.56C3201.89 1391.12 3131.32 1373.73 3063.64 1354.39C2879.96 1302.2 2715.61 1238.4 2566.74 1168.81C2471.03 1124.35 2382.09 1076.98 2297.98 1028.66C2269.94 1012.22 2242.88 996.759 2216.77 980.327C2206.14 973.561 2195.5 967.761 2184.87 960.995C2171.34 952.296 2156.83 943.596 2144.27 934.897C2130.73 926.198 2116.23 917.499 2102.7 908.8C2092.06 902.033 2082.4 895.267 2071.76 888.501C2045.66 871.103 2019.56 853.704 1993.45 836.306C1906.45 777.344 1826.21 718.383 1749.83 661.355C1593.22 544.398 1455.94 437.107 1320.6 354.948C1257.76 317.251 1196.86 284.387 1134.02 259.256C725.083 94.9373 186.605 301.786 47.3932 580.162C15.4906 645.889 3.88959 715.483 21.291 785.077C22.2578 781.211 131.5 1539.01 663.211 1376.63C723.149 1358.26 788.888 1328.3 859.461 1284.8C876.862 1274.17 895.23 1262.57 913.598 1250C1045.08 1160.11 1169.79 1068.29 1289.66 978.393C1371.84 916.532 1450.14 854.671 1526.52 794.743C1551.65 775.411 1575.82 756.08 1599.99 736.748C1609.66 729.015 1619.32 721.283 1628.99 714.517C1641.56 704.851 1654.13 695.185 1666.69 684.552C1679.26 673.92 1691.83 663.288 1704.4 653.622C1714.06 645.889 1723.73 638.157 1733.4 630.424C1757.57 610.126 1782.7 590.794 1806.87 571.462C1889.05 504.768 1968.32 441.94 2045.66 383.945C2203.24 265.056 2352.12 166.464 2495.2 100.737C2564.8 68.8396 2633.44 44.675 2701.11 29.2097C3029.81 -45.2171 3338.2 102.67 3673.66 631.39Z' stroke='url(#paint50_linear_14300_3682)' stroke-miterlimit='10'/>\n<path d='M8.72248 785.078C8.72248 785.078 147.934 1792.26 905.864 1264.5C2184.87 374.281 2839.36 -707.324 3692.03 625.592C3692.03 625.592 4500.23 1677.23 3295.66 1408.52C2091.09 1139.81 1643.49 443.875 1135.95 237.993C628.407 32.1109 -82.1517 406.178 8.72248 785.078Z' stroke='url(#paint51_linear_14300_3682)' stroke-miterlimit='10'/>\n<defs>\n<linearGradient id='paint0_linear_14300_3682' x1='1569.05' y1='466.105' x2='1569.05' y2='1359.23' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint1_linear_14300_3682' x1='1577.72' y1='456.443' x2='1577.72' y2='1359.35' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint2_linear_14300_3682' x1='1586.47' y1='447.721' x2='1586.47' y2='1360.54' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint3_linear_14300_3682' x1='1593.22' y1='439.92' x2='1593.22' y2='1362.81' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint4_linear_14300_3682' x1='1603.02' y1='430.218' x2='1603.02' y2='1364.29' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint5_linear_14300_3682' x1='1610.25' y1='421.466' x2='1610.25' y2='1365.74' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint6_linear_14300_3682' x1='1619.17' y1='415.341' x2='1619.17' y2='1367.25' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint7_linear_14300_3682' x1='1626.48' y1='405.585' x2='1626.48' y2='1368.11' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint8_linear_14300_3682' x1='1635.32' y1='394.952' x2='1635.32' y2='1370.66' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint9_linear_14300_3682' x1='1641.92' y1='386.153' x2='1641.92' y2='1372.29' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint10_linear_14300_3682' x1='1650.93' y1='377.249' x2='1650.93' y2='1373.93' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint11_linear_14300_3682' x1='1658.32' y1='369.154' x2='1658.32' y2='1375.77' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint12_linear_14300_3682' x1='1665.62' y1='358.627' x2='1665.62' y2='1377.45' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint13_linear_14300_3682' x1='1675.76' y1='348.825' x2='1675.76' y2='1378.37' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint14_linear_14300_3682' x1='1682.56' y1='341.474' x2='1682.56' y2='1381.24' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint15_linear_14300_3682' x1='1690.7' y1='333.392' x2='1690.7' y2='1382.98' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint16_linear_14300_3682' x1='1698.83' y1='325.886' x2='1698.83' y2='1384.72' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint17_linear_14300_3682' x1='1706.39' y1='315.222' x2='1706.39' y2='1386.46' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint18_linear_14300_3682' x1='1714.88' y1='304.746' x2='1714.88' y2='1388.43' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint19_linear_14300_3682' x1='1722.24' y1='296.394' x2='1722.24' y2='1389.46' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint20_linear_14300_3682' x1='1730.63' y1='286.769' x2='1730.63' y2='1391.28' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint21_linear_14300_3682' x1='1738.78' y1='277.861' x2='1738.78' y2='1393.07' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint22_linear_14300_3682' x1='1745.64' y1='272.433' x2='1745.64' y2='1396.05' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint23_linear_14300_3682' x1='1755.52' y1='261.044' x2='1755.52' y2='1397.83' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint24_linear_14300_3682' x1='1763.16' y1='253.537' x2='1763.16' y2='1399.63' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint25_linear_14300_3682' x1='1770.42' y1='242.886' x2='1770.42' y2='1400.95' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint26_linear_14300_3682' x1='1779.51' y1='231.742' x2='1779.51' y2='1402.76' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint27_linear_14300_3682' x1='1786.48' y1='222.551' x2='1786.48' y2='1404.57' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint28_linear_14300_3682' x1='1795.3' y1='214.967' x2='1795.3' y2='1407.35' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint29_linear_14300_3682' x1='1801.57' y1='205.016' x2='1801.57' y2='1409.41' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint30_linear_14300_3682' x1='1809.73' y1='195.081' x2='1809.73' y2='1410.52' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint31_linear_14300_3682' x1='1818.93' y1='186.06' x2='1818.93' y2='1412.35' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint32_linear_14300_3682' x1='1827.12' y1='177.469' x2='1827.12' y2='1414.41' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint33_linear_14300_3682' x1='1835.07' y1='169.093' x2='1835.07' y2='1416.24' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint34_linear_14300_3682' x1='1843.87' y1='158.436' x2='1843.87' y2='1419.04' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint35_linear_14300_3682' x1='1850.78' y1='148.741' x2='1850.78' y2='1420.85' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint36_linear_14300_3682' x1='1859.19' y1='140.058' x2='1859.19' y2='1422.23' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint37_linear_14300_3682' x1='1866.24' y1='129.672' x2='1866.24' y2='1424.07' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint38_linear_14300_3682' x1='1876.16' y1='121' x2='1876.16' y2='1425.91' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint39_linear_14300_3682' x1='1883.4' y1='113.179' x2='1883.4' y2='1428.71' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint40_linear_14300_3682' x1='1890.83' y1='102.563' x2='1890.83' y2='1430.81' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint41_linear_14300_3682' x1='1899.49' y1='92.8154' x2='1899.49' y2='1432.65' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint42_linear_14300_3682' x1='1907.17' y1='84.9468' x2='1907.17' y2='1433.81' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint43_linear_14300_3682' x1='1915.36' y1='74.3203' x2='1915.36' y2='1435.9' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint44_linear_14300_3682' x1='1922.92' y1='67.0249' x2='1922.92' y2='1438.71' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint45_linear_14300_3682' x1='1931.15' y1='57.0142' x2='1931.15' y2='1440.56' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint46_linear_14300_3682' x1='1939.4' y1='47.8564' x2='1939.4' y2='1442.41' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint47_linear_14300_3682' x1='1947.19' y1='39.2847' x2='1947.19' y2='1444.51' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint48_linear_14300_3682' x1='1955.28' y1='28.668' x2='1955.28' y2='1445.68' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint49_linear_14300_3682' x1='1962.62' y1='18.9097' x2='1962.62' y2='1448.5' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint50_linear_14300_3682' x1='1971.67' y1='11.2061' x2='1971.67' y2='1450.61' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n<linearGradient id='paint51_linear_14300_3682' x1='1979.09' y1='0.921875' x2='1979.09' y2='1452.46' gradientUnits='userSpaceOnUse'>\n<stop stop-color='#BEBDBD' stop-opacity='0.71'/>\n<stop offset='0.453125' stop-color='#8DFFF3' stop-opacity='0.01'/>\n<stop offset='1' stop-color='#1C60FF' stop-opacity='0.31'/>\n</linearGradient>\n</defs>\n</svg>\n`,\n  darkSvgBG: `<svg id='bgAlphaBg' width='1920' height='1626' viewBox='0 0 1920 1626' fill='none' xmlns='http://www.w3.org/2000/svg'>\n<path opacity='0.1' d='M0 64L1046.69 1110.69H0V64Z' fill='url(#paint0_radial_0_1)'/>\n<path opacity='0.1' d='M0 266L814 1080H0V266Z' fill='url(#paint1_radial_0_1)'/>\n<path opacity='0.1' d='M2161 -461L540 1160H2161V-461Z' fill='url(#paint2_radial_0_1)'/>\n<path d='M5 -461H1915V1626H5V-461Z' fill='url(#paint3_radial_0_1)'/>\n<defs>\n<radialGradient id='paint0_radial_0_1' cx='0' cy='0' r='1' gradientUnits='userSpaceOnUse' gradientTransform='translate(523.344 587.344) rotate(134.7) scale(312.545)'>\n<stop stop-color='#67698E'/>\n<stop offset='1' stop-color='#50516F' stop-opacity='0'/>\n</radialGradient>\n<radialGradient id='paint1_radial_0_1' cx='0' cy='0' r='1' gradientUnits='userSpaceOnUse' gradientTransform='translate(407 673) rotate(134.7) scale(243.064)'>\n<stop stop-color='#67698E'/>\n<stop offset='1' stop-color='#50516F' stop-opacity='0'/>\n</radialGradient>\n<radialGradient id='paint2_radial_0_1' cx='0' cy='0' r='1' gradientUnits='userSpaceOnUse' gradientTransform='translate(1350.5 349.5) rotate(45.2997) scale(484.037)'>\n<stop stop-color='#67698E'/>\n<stop offset='1' stop-color='#50516F' stop-opacity='0'/>\n</radialGradient>\n<radialGradient id='paint3_radial_0_1' cx='0' cy='0' r='1' gradientUnits='userSpaceOnUse' gradientTransform='translate(578.497 110.606) rotate(58.751) scale(1070.04 1040.14)'>\n<stop stop-color='#4868A7' stop-opacity='0.44'/>\n<stop offset='1' stop-color='#1F2034' stop-opacity='0'/>\n</radialGradient>\n</defs>\n</svg>\n`,\n  lightSvgBG: `<svg id='bgAlphaBg' width='1920' height='1626' viewBox='0 0 1920 1626' fill='none' xmlns='http://www.w3.org/2000/svg'>\n<path opacity='0.1' d='M0 64L1046.69 1110.69H0V64Z' fill='url(#paint0_radial_14267_4338)'/>\n<path opacity='0.1' d='M0 266L814 1080H0V266Z' fill='url(#paint1_radial_14267_4338)'/>\n<path opacity='0.1' d='M2161 -461L540 1160H2161V-461Z'  fill='url(#paint2_radial_14267_4338)'/>\n<path d='M5 -461H1915V1626H5V-461Z' fill=''/>\n<defs>\n<radialGradient id='paint0_radial_14267_4338' cx='0' cy='0' r='1' gradientUnits='userSpaceOnUse' gradientTransform='translate(523.344 587.344) rotate(134.7) scale(312.545)'>\n<stop stop-color='#67698E'/>\n<stop offset='1' stop-color='#50516F' stop-opacity='0'/>\n</radialGradient>\n<radialGradient id='paint1_radial_14267_4338' cx='0' cy='0' r='1' gradientUnits='userSpaceOnUse' gradientTransform='translate(407 673) rotate(134.7) scale(243.064)'>\n<stop stop-color='#67698E'/>\n<stop offset='1' stop-color='#50516F' stop-opacity='0'/>\n</radialGradient>\n<radialGradient id='paint2_radial_14267_4338' cx='0' cy='0' r='1' gradientUnits='userSpaceOnUse' gradientTransform='translate(1350.5 349.5) rotate(45.2997) scale(484.037)'>\n<stop stop-color='#ACAED9'/>\n<stop offset='1' stop-color='#8C8EB7' stop-opacity='0'/>\n</radialGradient>\n</defs>\n</svg>`,\n}\n\nconst resources = {\n  en_US: {\n    common: {\n      labelNavZkRollupLayer2: 'zkRollup Layer 2',\n      labelNavWallet: 'Wallet Guardian',\n      labelNavLanuch: 'Launch App',\n      labelAbout: 'About',\n      labelLoopringOrg: 'Loopring.org',\n      labelLoopringTerms: 'Terms of Service',\n      labelPrivacyPolicy: 'Privacy Policy',\n      labelRiskDisclosure: 'Risk Disclosure',\n      labelSupport: 'Support',\n      labelSubmitARequest: '❤️ Submit a Request',\n      labelCreatorGrants: 'Creator Grants',\n      labelListAToken: 'List a Token',\n      labelWalletGuardian: 'Wallet Guardian',\n      labelPlatform: 'Platform',\n      labelFees: 'Fees',\n      labelVIPProgram: 'VIP Program',\n      labelReferrals: 'Referrals',\n      labelDevelopers: 'Developers',\n      labelSmartContracts: 'Smart Contracts',\n      labelAPIs: 'APIs',\n      labelLayer2Explorer: 'Layer 2 Explorer',\n      labelBugBounty: 'Bug Bounty',\n      labelSubgraph: 'Subgraph',\n      labelFollowus: 'Follow us',\n      labelEthereumUnleashed: 'Ethereum Unleashed',\n      labelGatewayToEthereum: 'Your Gateway to Ethereum, DeFi, \\n NFTs, and Financial Freedom',\n      labelIOS: 'iOS',\n      labelAndroid: 'Android',\n      labelGooglePlay: 'Google Play',\n      labelFeature1: 'Fast, Secure, and 100x \\nLower Fees',\n      labelFeatureDes1:\n        'Experience DeFi as it should be - fast and affordable. Built with zkRollups,  Loopring provides instant transactions at 100x  lower fees than Ethereum without sacrificing any of its security.',\n      labelFeature2: 'Invest, Stake, and Earn',\n      labelFeatureDes2:\n        'Easily earn yield on your  crypto. Your funds never leave your wallet and can be accessed at any time.',\n      labelFeature3: 'Dual Investment',\n      labelFeatureDes3:\n        'Buy Low or Sell High. Get rewarded no matter which direction the market moves.',\n      labelFeature4: 'Buy Crypto on L2',\n      labelFeatureDes4:\n        'Use card, bank transfer, or Apple Pay without ever having to leave your wallet.',\n      labelFeature5: 'Your Personal Vault',\n      labelFeatureDes5:\n        'Forget seed phrases.  Choose people, institutions, and hardware you trust to be your Guardians. Set limits on daily  transfers or even lock your wallet if needed. You’re always in control.',\n      labelFeature6: 'Manage and Display \\nYour NFT Collection',\n      labelFeatureDes6:\n        'Immerse yourself in the world of unique digital assets. Safeguard your growing collection, all while enjoying easy access to your favorite marketplaces.',\n      labelFeature7: 'Digital Red Packets',\n      labelFeatureDes7:\n        'Create memorable experiences for friends, family, and your community. Red Packets are perfect for gifts, social events, gaming rewards, airdrops, and more!',\n      labelFeatureDes8: 'Loopring Wallet',\n      labelFeatureDes8_2: 'Crypto exchange on the go',\n      labelCopyRight: '© 2017 Loopring Technology Limited. All rights reserved.',\n    },\n  },\n  // zh_CN: {...zhCN},\n}\n\n// const initLng = JSON.parse(localStorage.getItem('persist:settings') as string)?.language === `\"${LanguageType.zh_CN}\"` ? LanguageType.zh_CN : LanguageType.en_US\nconst initLng = 'en_US'\nconsole.log('en_US')\nconst settingPersist = 'persist:settings'\nlet referralcodeStr = ''\n;(function init() {\n  let themeMode = 'dark'\n  let settingPersistJson = localStorage.getItem(settingPersist)\n  let settings = JSON.parse(settingPersistJson ? settingPersistJson : '{}')\n  if (settings.themeMode && JSON.parse(settings.themeMode)) {\n    themeMode = JSON.parse(settings.themeMode)\n  }\n  const onColorChange = (value = 'dark', _this) => {\n    settings.themeMode = JSON.stringify(value)\n    window.localStorage.setItem(settingPersist, JSON.stringify(settings))\n    let link = document.getElementById('themeModeCss')\n    link.setAttribute('href', value !== 'light' ? './wallet_dark.css' : './wallet_light.css')\n    if (_this) {\n      _this.setAttribute('value', value)\n    }\n  }\n  const onColorChangeLoaded = (value = 'dark') => {\n    const basicUrl = 'https://static.loopring.io/assets/images/landPage/'\n    const imageEnd = value !== 'light' ? '.png' : '_light' + '.png'\n    document\n      .getElementById('imageChang1')\n      .setAttribute('src', basicUrl + 'wallet_banner1' + imageEnd)\n    document\n      .getElementById('imageChang2')\n      .setAttribute('src', basicUrl + 'wallet_banner2' + imageEnd)\n    document\n      .getElementById('imageChang3')\n      .setAttribute('src', basicUrl + 'wallet_banner3' + imageEnd)\n    // document\n    //   .getElementById(\"imageChang4\")\n    //   .setAttribute(\"src\", basicUrl + \"wallet_banner3\" + imageEnd);\n    document\n      .getElementById('imageSection1')\n      .setAttribute('src', basicUrl + 'wallet_section1' + imageEnd)\n    document\n      .getElementById('imageSection2')\n      .setAttribute('src', basicUrl + 'wallet_section2' + imageEnd)\n    document\n      .getElementById('imageSection3')\n      .setAttribute('src', basicUrl + 'wallet_section3' + imageEnd)\n    document\n      .getElementById('imageSection4')\n      .setAttribute('src', basicUrl + 'wallet_section4' + imageEnd)\n    document\n      .getElementById('imageSection5')\n      .setAttribute('src', basicUrl + 'wallet_section5' + imageEnd)\n    document\n      .getElementById('imageSection6')\n      .setAttribute('src', basicUrl + 'wallet_section6' + imageEnd)\n    document\n      .getElementById('imageSection7' + '')\n      .setAttribute('src', basicUrl + 'wallet_section7' + imageEnd)\n    document.getElementById('bgContent').innerHTML =\n      value !== 'light'\n        ? svgGroup.blackSvg + svgGroup.darkSvgBG\n        : svgGroup.lightSvg + svgGroup.lightSvgBG\n    document.getElementById('changeColor').innerHTML =\n      value !== 'light' ? svgGroup.DarkIcon : svgGroup.LightIcon\n    document.getElementById('changeColor').setAttribute('data-theme', themeMode)\n  }\n\n  onColorChange(themeMode !== 'dark' ? 'light' : 'dark')\n  window.onGlobalChange = () => {\n    themeMode = themeMode !== 'dark' ? 'dark' : 'light'\n    onColorChange(themeMode)\n    onColorChangeLoaded(themeMode)\n  }\n  // Language now english only\n  const onlanguagechange = (value) => {\n    let settingPersistJson = localStorage.getItem(settingPersist)\n    let settings = JSON.parse(settingPersistJson ? settingPersistJson : '{}')\n    settings.language = value\n    window.localStorage.setItem(settingPersist, JSON.stringify(settings))\n    i18next.changeLanguage('en_US')\n  }\n  const updateI18n = () => {\n    document.getElementById('labelNavZkRollupLayer2').innerHTML =\n      i18next.t('labelNavZkRollupLayer2')\n    document.getElementById('labelNavWallet').innerHTML = i18next.t('labelNavWallet')\n    document.getElementById('labelNavLanuch').innerHTML = i18next.t('labelNavLanuch')\n    document.getElementById('labelAbout').innerHTML = i18next.t('labelAbout')\n    document.getElementById('labelLoopringOrg').innerHTML = i18next.t('labelLoopringOrg')\n    document.getElementById('labelLoopringTerms').innerHTML = i18next.t('labelLoopringTerms')\n    document.getElementById('labelPrivacyPolicy').innerHTML = i18next.t('labelPrivacyPolicy')\n    document.getElementById('labelRiskDisclosure').innerHTML = i18next.t('labelRiskDisclosure')\n    document.getElementById('labelSupport').innerHTML = i18next.t('labelSupport')\n    document.getElementById('labelSubmitARequest').innerHTML = i18next.t('labelSubmitARequest')\n    document.getElementById('labelCreatorGrants').innerHTML = i18next.t('labelCreatorGrants')\n    document.getElementById('labelListAToken').innerHTML = i18next.t('labelListAToken')\n    document.getElementById('labelWalletGuardian').innerHTML = i18next.t('labelWalletGuardian')\n    document.getElementById('labelPlatform').innerHTML = i18next.t('labelPlatform')\n    document.getElementById('labelFees').innerHTML = i18next.t('labelFees')\n    document.getElementById('labelVIPProgram').innerHTML = i18next.t('labelVIPProgram')\n    document.getElementById('labelReferrals').innerHTML = i18next.t('labelReferrals')\n    document.getElementById('labelDevelopers').innerHTML = i18next.t('labelDevelopers')\n    document.getElementById('labelSmartContracts').innerHTML = i18next.t('labelSmartContracts')\n    document.getElementById('labelAPIs').innerHTML = i18next.t('labelAPIs')\n    document.getElementById('labelLayer2Explorer').innerHTML = i18next.t('labelLayer2Explorer')\n    document.getElementById('labelBugBounty').innerHTML = i18next.t('labelBugBounty')\n    document.getElementById('labelSubgraph').innerHTML = i18next.t('labelSubgraph')\n    document.getElementById('labelFollowus').innerHTML = i18next.t('labelFollowus')\n    document.getElementById('labelEthereumUnleashed').innerHTML =\n      i18next.t('labelEthereumUnleashed')\n    document.getElementById('labelGatewayToEthereum').innerHTML =\n      i18next.t('labelGatewayToEthereum')\n    document.getElementById('labelIOS').innerHTML = i18next.t('labelIOS')\n    document.getElementById('labelAndroid').innerHTML = i18next.t('labelAndroid')\n    document.getElementById('labelGooglePlay').innerHTML = i18next.t('labelGooglePlay')\n    document.getElementById('labelIOS2').innerHTML = i18next.t('labelIOS')\n    document.getElementById('labelAndroid2').innerHTML = i18next.t('labelAndroid')\n    document.getElementById('labelGooglePlay2').innerHTML = i18next.t('labelGooglePlay')\n    document.getElementById('labelFeature1').innerHTML = i18next.t('labelFeature1')\n    document.getElementById('labelFeatureDes1').innerHTML = i18next.t('labelFeatureDes1')\n    document.getElementById('labelFeature2').innerHTML = i18next.t('labelFeature2')\n    document.getElementById('labelFeatureDes2').innerHTML = i18next.t('labelFeatureDes2')\n    document.getElementById('labelFeature3').innerHTML = i18next.t('labelFeature3')\n    document.getElementById('labelFeatureDes3').innerHTML = i18next.t('labelFeatureDes3')\n    document.getElementById('labelFeature4').innerHTML = i18next.t('labelFeature4')\n    document.getElementById('labelFeatureDes4').innerHTML = i18next.t('labelFeatureDes4')\n    document.getElementById('labelFeature5').innerHTML = i18next.t('labelFeature5')\n    document.getElementById('labelFeatureDes5').innerHTML = i18next.t('labelFeatureDes5')\n    document.getElementById('labelFeature6').innerHTML = i18next.t('labelFeature6')\n    document.getElementById('labelFeatureDes6').innerHTML = i18next.t('labelFeatureDes6')\n    document.getElementById('labelFeature7').innerHTML = i18next.t('labelFeature7')\n    document.getElementById('labelFeatureDes7').innerHTML = i18next.t('labelFeatureDes7')\n    document.getElementById('labelFeatureDes8').innerHTML = i18next.t('labelFeatureDes8')\n    document.getElementById('labelFeatureDes8_2').innerHTML = i18next.t('labelFeatureDes8_2')\n    document.getElementById('labelCopyRight').innerHTML = i18next.t('labelCopyRight')\n  }\n\n  const upLoadSvg = () => {\n    document.getElementById('logSvg').innerHTML = svgGroup.logSvg\n    document.getElementById('iconIos').innerHTML = svgGroup.ios\n    document.getElementById('iconAndroid').innerHTML = svgGroup.android\n    document.getElementById('iconGooglePlay').innerHTML = svgGroup.googlePlay\n    document.getElementById('iconIos2').innerHTML = svgGroup.ios\n    document.getElementById('iconAndroid2').innerHTML = svgGroup.android\n    document.getElementById('iconGooglePlay2').innerHTML = svgGroup.googlePlay\n    document.getElementById('youtubeIcon').innerHTML = svgGroup.youtubeIcon\n    document.getElementById('twitterIcon').innerHTML = svgGroup.twitterIcon\n    document.getElementById('mediumIcon').innerHTML = svgGroup.mediumIcon\n    document.getElementById('discordIcon').innerHTML = svgGroup.discordIcon\n  }\n\n  window.onload = () => {\n    i18next\n      // .use(i18nextHttpBackend)\n      .use(i18nextBrowserLanguageDetector)\n      .init(\n        {\n          resources,\n          debug: false,\n          ns: ['common'],\n          defaultNS: 'common',\n          lng: initLng,\n          fallbackLng: initLng,\n          keySeparator: '.', // we do not use keys in form messages.welcome\n          interpolation: {\n            escapeValue: true, // react already safes from xss\n            formatSeparator: `, `,\n          },\n        },\n        function (err, t) {\n          // init set content\n          updateI18n()\n        },\n      )\n    var i18nLng = window.localStorage.getItem('lng')\n    if (!i18nLng) {\n      i18nLng = 'en'\n    }\n    upLoadSvg()\n    onlanguagechange(i18nLng)\n    onColorChangeLoaded(themeMode)\n    let searchParam = window.location.search\n    const searchParams = new URLSearchParams(searchParam)\n    if (searchParams.get('referralcode')) {\n      const referralcode = searchParams.get('referralcode')\n      document\n        .getElementById('logo')\n        .setAttribute('href', 'https://loopring.io/#/?referralcode=' + referralcode)\n      document\n        .getElementById('labelNavLanuch')\n        .setAttribute('href', 'https://loopring.io/#/?referralcode=' + referralcode)\n      referralcodeStr\n    }\n    const handleScroll = () => {\n      const imgs = document.getElementsByClassName('scroll-up-img')\n      for (let index = 0; index < imgs.length; index++) {\n        const img = imgs.item(index)\n        if (img.getBoundingClientRect().top < window.innerHeight) {\n          img.style.opacity = 1\n          img.style.transform = 'translateY(0)'\n        }\n      }\n    }\n    setTimeout(() => {\n      handleScroll()\n    }, 50)\n\n    window.addEventListener('scroll', handleScroll)\n    let clear = -1\n    var options = document.getElementsByName('slider') //.options;\n\n    function loopScroll() {\n      if (clear !== -1) {\n        clearTimeout(clear)\n      }\n      let i = [].slice.call(options).findIndex((item) => item.checked == true)\n      let next = i + 1\n      options[options.length - next > 0 ? next : 0].checked = true\n      clear = setTimeout(() => {\n        if (window.innerWidth < 768) {\n          loopScroll()\n        }\n      }, 3000)\n    }\n\n    loopScroll()\n  }\n})()\n"
  },
  {
    "path": "packages/web-wallet/public/wallet.scss",
    "content": "body {\n  background: var(--color-global-Bg);\n  font-family: Roboto, Helvetica, Arial, '华文细黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体',\n  Heiti, '黑体', sans-serif;\n  user-drag: none;\n  user-select: none;\n}\n\nbutton {\n  border: 1px solid var(--color-border);\n  border-radius: 2px;\n  box-sizing: border-box;\n\n  &:hover {\n    border: 1px solid var(--color-border-hover);\n  }\n}\n\n.Typography-root {\n  font-size: 14px;\n  color: var(--color-text-primary);\n}\n\nheader {\n  .headerGg {\n    width: 100vw;\n    //background-color: var(--color-box);\n  }\n\n  .Toolbar-root {\n    height: var(--header-height);\n    //background-color: var(--color-box);\n    display: flex;\n    flex-direction: row;\n    justify-content: space-between;\n    align-items: center;\n  }\n\n  nav {\n    display: flex;\n    flex-direction: row;\n    align-items: center;\n\n    ul {\n      margin-left: 24px;\n\n      li {\n        display: inline-block;\n        height: var(--header-height);\n        line-height: var(--header-height);\n        padding: 0 8px;\n      }\n    }\n  }\n}\n\nfooter {\n  .Container-root {\n    display: flex;\n    flex-direction: column;\n  }\n\n  .content {\n    display: flex;\n    flex-direction: row;\n    justify-content: space-between;\n  }\n}\n\n.flexBox {\n  display: flex;\n}\n\n.flex-column {\n  flex-direction: column;\n}\n\n.flex-row {\n  flex-direction: row;\n}\n\n.align-center {\n  align-items: center;\n}\n\n/* Rectangle 1662 */\n\n#labelNavLanuch {\n  /*width: 112px;*/\n  padding: 0 16px;\n  line-height: 36px;\n  height: 36px;\n  border-radius: 2px;\n  border: 0;\n  /*border: 1px solid;*/\n  /*border-image: linear-gradient(90deg, #D7B2FF 0%, #77AAFF 53.24%) 1;*/\n  color: var(--color-text-primary);\n  border-image-repeat: round;\n  position: relative;\n  z-index: 99;\n  box-sizing: border-box;\n}\n\n#labelNavLanuch:after {\n  top: 0;\n  left: 0;\n  right: 0;\n  bottom: 0;\n  position: absolute;\n  content: '';\n  border-radius: 2px;\n  z-index: -1;\n  border: 2px solid;\n  border-image: linear-gradient(90deg, #d7b2ff 0%, #77aaff 53.24%) 1;\n  /*background-image: linear-gradient(90deg, #D7B2FF 0%, #77AAFF 53.24%);*/\n  /*mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAABeSURBVHgB7dZBDYAwDIXhtgomAWdowAE4wF5PTMIMNOUtWFgv5P1Jk5329Vh1911V78xssraOORXAg8cmNQ0r/HzWTIojQIAAAQIEfgLgohhSV7eIOOQ7MZY2F8dcL/hCFFUPCYXoAAAAAElFTkSuQmCC);*/\n  /*-webkit-mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAABeSURBVHgB7dZBDYAwDIXhtgomAWdowAE4wF5PTMIMNOUtWFgv5P1Jk5329Vh1911V78xssraOORXAg8cmNQ0r/HzWTIojQIAAAQIEfgLgohhSV7eIOOQ7MZY2F8dcL/hCFFUPCYXoAAAAAElFTkSuQmCC);*/\n  /*mask-size:99%;*/\n  /*-webkit-mask-size:99%;*/\n}\n\n#logo {\n  min-width: auto;\n  border-radius: 0px;\n  text-indent: -999999em;\n  background: var(--color-logo);\n  -webkit-mask: url(https://static.loopring.io/assets/svg/logo.svg) center center / contain space;\n  width: 105px;\n  height: 40px;\n  padding: 8px;\n  color: transparent;\n  display: inline-flex;\n  align-items: center;\n  justify-content: center;\n  position: relative;\n  box-sizing: border-box;\n  outline: 0px;\n  border: 0px;\n  margin: -10px 0px 0px -12px;\n  cursor: pointer;\n\n  &::after {\n    content: 'beta';\n    position: absolute;\n    color: var(--color-logo);\n    display: block;\n    font-size: 1rem;\n    line-height: 0.8rem;\n    right: -24px;\n    top: 14px;\n    font-weight: 200;\n    opacity: 0;\n    box-shadow: 0 0 1px 0 var(--color-logo);\n    border-radius: 2px;\n    padding: 3px 2px;\n  }\n\n  svg {\n    fill: var(--color-text-Secondary);\n  }\n}\n\n/* identical to box height, or 129% */\n\n.Container-root,\n.wrap {\n  max-width: calc(1200px - 32px);\n  padding: 0 16px;\n  margin: 0 auto;\n}\n\na.Typography-root,\na.Typography-root:active,\na.Typography-root:visited,\n.Link-root,\n.Link-root:active,\n.Link-root:visited,\n.MenuItem-root a.Typography-root,\n.MenuItem-root a.Typography-root:active,\n.MenuItem-root a.Typography-root:visited,\n.Link-root {\n  color: var(--color-text-Secondary);\n}\n\na.Typography-root:hover,\n.MenuItem-root a.Typography-root:hover,\n.Link-root:hover {\n  color: var(--color-text-primary);\n}\n\n.Link-underlineAlways:hover {\n  text-decoration: underline;\n}\n\nbody {\n  display: flex;\n  flex-direction: column;\n  justify-content: flex-start;\n  height: 100%;\n}\n\n.sectionDetail {\n  display: flex;\n  flex-direction: column;\n  width: 50%;\n  min-width: 50%;\n\n  h3 {\n    word-break: break-word;\n    white-space: pre-line;\n    line-height: 1.2em;\n    margin: 24px 0;\n  }\n\n  p {\n    line-height: 1.2em;\n    word-break: break-word;\n    white-space: pre-line;\n  }\n}\n\n.sectionFull {\n  align-items: center;\n  justify-content: center;\n  width: 100vw;\n  margin: 160px 0;\n\n  &:nth-child(even) .wrap {\n    flex-direction: row-reverse;\n  }\n\n  &:nth-child(odd) .img-container {\n    display: flex;\n    justify-content: flex-end;\n  }\n\n  .wrap {\n    justify-content: space-between;\n    display: flex;\n\n    align-items: center;\n  }\n}\n\nh3.Typography-root {\n  font-size: var(--h1);\n}\n\nh3 ~ p.Typography-root {\n  color: var(--color-text-third);\n  font-size: var(--h5);\n}\n\n.downLoadBtnGroup .Typography-roo {\n  display: inline-block;\n  margin-left: 8px;\n}\n\n.downLoadBtnGroup svg {\n  fill: var(--color-text-Button);\n}\n\n.downLoadBtnGroup {\n  display: flex;\n  flex-direction: row;\n  justify-content: space-evenly;\n}\n\n.downLoadBtnGroup button {\n  margin-left: 24px;\n  width: 180px;\n  height: 48px;\n  display: flex;\n  flex-direction: row;\n  justify-content: space-evenly;\n  align-items: center;\n  padding: 0 24px;\n}\n\n/* Ethereum Unleashed */\n\n#labelEthereumUnleashed {\n  width: 522px;\n  height: 72px;\n  font-weight: 700;\n  font-size: 56px;\n  line-height: 72px;\n  background: linear-gradient(90deg, #d7b2ff 0%, #77aaff 53.24%);\n  -webkit-background-clip: text;\n  -webkit-text-fill-color: transparent;\n  /*background-clip: text;*/\n  border-radius: 2px;\n  text-fill-color: transparent;\n  margin-top: 120px;\n  margin-bottom: 16px;\n  text-align: center;\n}\n\n#labelGatewayToEthereum {\n  margin-bottom: 32px;\n  line-height: 1.5em;\n  font-size: var(--h4);\n  text-align: center;\n}\n\nfooter {\n  flex: 1;\n  display: flex;\n  flex-direction: column;\n  justify-content: flex-end;\n\n  .content {\n    margin-top: 24px;\n    margin-bottom: 24px;\n  }\n\n  .footerWallet {\n    z-index: 99;\n    background: var(--color-box);\n    padding-top: 16px;\n    padding-bottom: 16px;\n\n    .wrap {\n      flex-direction: row;\n      align-items: center;\n      justify-content: space-between;\n    }\n  }\n\n  .group {\n    padding-top: 16px;\n\n    h6 {\n      font-size: var(--body2);\n      color: var(--color-text-third);\n      line-height: 4em;\n      padding-bottom: 8px;\n    }\n\n    .Typography-root {\n      font-size: var(--body2);\n      line-height: 2em;\n    }\n  }\n}\n\n.Button-root {\n  cursor: pointer;\n}\n\n.groupIcon {\n  li {\n    padding-right: 8px;\n  }\n\n  .icon svg {\n    font-size: var(--h5);\n    fill: var(--color-text-Secondary);\n    width: 36px;\n    height: 36px;\n  }\n\n  a.icon:hover svg {\n    fill: var(--color-text-primary);\n  }\n}\n\n#labelCopyRight {\n  color: var(--color-text-third);\n  text-align: center;\n  height: 40px;\n  line-height: 40px;\n  border-top: 1px solid var(--color-divide);\n}\n\n.logoDex {\n  display: flex;\n  flex-direction: column;\n  justify-content: space-evenly;\n}\n\n.logoDex p:first-child {\n  color: var(--color-text-primary);\n  font-size: var(--h5);\n}\n\n.logoDex p:last-child {\n  color: var(--color-text-third);\n}\n\n.carousel-container {\n  --height: 596px;\n  --width: 280px;\n  --size-image: 0.8;\n  display: flex;\n  margin-top: 120px;\n  overflow: hidden;\n  width: 800px;\n  height: calc(var(--height) + 32px);\n  transform-style: preserve-3d;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  overflow: hidden;\n\n  .container {\n    height: 100%;\n    width: 100%;\n  }\n\n  #slider {\n    width: 100vw;\n    height: 100%;\n    display: flex;\n    justify-content: center;\n    align-items: center;\n  }\n\n  input[type='radio'] {\n    display: none;\n  }\n\n  .cards {\n    position: relative;\n    width: 100%;\n    height: 100%;\n  }\n\n  .card {\n    position: absolute;\n    top: 50%;\n    left: 50%;\n    margin-left: calc(var(--width) / -2);\n    margin-top: calc(var(--height) / -2);\n    cursor: pointer;\n    transition: transform 0.4s cubic-bezier(0.165, 0.84, 0.44, 1);\n  }\n\n  img {\n    width: var(--width);\n    object-fit: cover;\n    //border-radius: 32px;\n    //width: 100%;\n    //height: 100%;\n    //object-fit: cover;\n  }\n}\n\n#bgContent {\n  position: absolute;\n  z-index: 1;\n  top: 0;\n  right: 0;\n  left: 0;\n  height: 100vh;\n  overflow: hidden;\n  pointer-events: none;\n\n  #bgAlphaBg {\n    position: absolute;\n    pointer-events: none;\n    transform: translate(0, -300px) rotate(0);\n    top: 0;\n    left: 0;\n    width: 100%;\n  }\n\n  #bgAlpha {\n    position: absolute;\n    pointer-events: none;\n    transform: translate(12%, -40%) rotate(-13deg);\n  }\n}\n@media only screen and (max-width: 1024px) {\n  .Container-root,\n  .wrap {\n    width: 100vw;\n    padding: 0 16px;\n    margin: 0 auto;\n  }\n\n  .carousel-container {\n    display: flex;\n    overflow: hidden;\n    align-items: center;\n    width: 100%;\n    align-items: center;\n    justify-content: center;\n    margin-top: 40px;\n  }\n\n  #logo {\n    min-width: auto;\n    /*border-radius: 0px;*/\n    /*text-indent: -999999em;*/\n    background: var(--color-logo);\n    -webkit-mask: url(https://static.loopring.io/assets/svg/loopring.svg) center center / contain space;\n    width: 40px;\n    height: 40px;\n    margin-left: 8px;\n  }\n\n  h3.Typography-root {\n    font-size: var(--h4);\n    text-align: center;\n  }\n\n  h3 ~ p.Typography-root {\n    font-size: var(--body);\n    white-space: initial;\n  }\n\n  header ul li:first-child {\n    display: none;\n  }\n\n  .downLoadBtnGroup {\n    flex-direction: column;\n    justify-content: space-between;\n    height: calc(48px * 3 + 16px * 3);\n    margin-left: 0;\n  }\n\n  .downLoadBtnGroup button {\n    margin-left: 0;\n  }\n\n  footer {\n    .footerWallet .wrap {\n      flex-direction: column;\n      align-items: center;\n      justify-content: space-between;\n    }\n\n    .downLoadBtnGroup {\n      margin-top: 24px;\n    }\n\n    .content {\n      flex-direction: column;\n    }\n  }\n\n  #labelEthereumUnleashed {\n    width: 100%;\n    font-size: 36px;\n    margin-top: 32px;\n  }\n\n  #logSvg {\n    display: none;\n  }\n\n  .sectionFull {\n    align-items: flex-start;\n    justify-content: center;\n    height: initial;\n    margin: 80px 0;\n  }\n\n  .sectionFull .wrap {\n    //flex-direction: column !important;\n    flex-direction: column-reverse !important;\n\n    .sectionDetail {\n      width: auto;\n      min-width: auto;\n\n      h3,\n      p {\n        text-align: center;\n      }\n    }\n  }\n\n  .sectionFull .img-container {\n    display: flex;\n    margin-top: 24px;\n    justify-content: center !important;\n  }\n\n  .carousel-container {\n    --size-image: 0.5;\n  }\n  #bgContent {\n    #bgAlphaBg {\n      display: none;\n    }\n\n    #bgAlpha {\n      position: absolute;\n      pointer-events: none;\n      transform: translate(-30%, -20%) rotate(13deg) scale(0.5);\n    }\n  }\n}\n\n.gradient-border {\n  --borderWidth: 3px;\n  background: var(--color-global-Bg);\n  position: relative;\n\n  &:hover {\n    border: 0;\n    box-shadow: 0 5px 15px #f7953304, 0 10px 30px #f3705502;\n    animation: boxShow 3s ease alternate infinite;\n\n    &:after {\n      content: '';\n      position: absolute;\n      top: calc(-1 * var(--borderWidth));\n      left: calc(-1 * var(--borderWidth));\n      right: calc(-1 * var(--borderWidth));\n      bottom: calc(-1 * var(--borderWidth));\n      background: linear-gradient(\n                      60deg,\n                      #f79533,\n                      #f37055,\n                      #ef4e7b,\n                      #a166ab,\n                      #5073b8,\n                      #1098ad,\n                      #07b39b,\n                      #6fba82\n      );\n      border-radius: calc(2 * var(--borderWidth));\n      z-index: -1;\n      animation: animatedgradient 3s ease alternate infinite;\n      background-size: 300% 300%;\n    }\n  }\n\n  //border-radius: var(--borderWidth);\n}\n\n@media only screen and (min-width: 768px) and (max-width: 1024px) {\n  #labelEthereumUnleashed {\n    width: 522px;\n    font-size: 56px;\n  }\n  .carousel-container {\n    --size-image: 0.7;\n    margin-top: 40px;\n  }\n\n  #labelGatewayToEthereum {\n    margin-bottom: 32px;\n    font-size: var(--h4);\n    text-align: center;\n  }\n  h3.Typography-root {\n    font-size: var(--h1);\n    margin: 80px 0 40px 0;\n  }\n\n  h3 ~ p.Typography-root {\n    color: var(--color-text-third);\n    font-size: var(--h5);\n  }\n}\n\n@keyframes boxShow {\n  0% {\n    //background-position: 0% 50%;\n    box-shadow: 0 5px 15px rgba(247, 149, 51, 0.4), 0 10px 30px rgba(243, 112, 85, 0.2);\n  }\n  25% {\n    //background-position: 25% 50%;\n    box-shadow: 0 5px 15px rgba(239, 78, 123, 0.4), 0 10px 30px rgba(161, 102, 171, 0.2);\n  }\n  50% {\n    //background-position: 50% 50%;\n    box-shadow: 0 5px 15px rgba(80, 115, 184, 0.4), 0 10px 30px rgba(16, 152, 173, 0.2);\n  }\n  75% {\n    //background-position: 75% 50%;\n    box-shadow: 0 5px 15px rgba(7, 179, 155, 0.4), 0 10px 30px rgba(111, 186, 130, 0.2);\n  }\n}\n\n@keyframes animatedgradient {\n  0% {\n    background-position: 0% 50%;\n    //box-shadow: 0 5px 15px #f7953304, 0 10px 30px #f3705502\n  }\n  25% {\n    background-position: 25% 50%;\n    //box-shadow: 0 5px 15px #ef4e7b04, 0 10px 30px #a166ab02\n  }\n  50% {\n    background-position: 50% 50%;\n    //box-shadow: 0 5px 15px #5073b804, 0 10px 30px #1098ad02\n  }\n  75% {\n    background-position: 75% 50%;\n    //box-shadow: 0 5px 15px #07b39b04, 0 10px 30px #6fba8202\n  }\n}\n\n#changeColor {\n  margin-right: 24px;\n  border: 0;\n}\n\n//0%,\n// to {\n//   border: 2px solid #00f8ff;\n// }\n//\n//20% {\n//    border: 2px solid #a4ff00;\n//    box-shadow: 0 5px 15px rgba(164, 255, 0, .4), 0 10px 30px rgba(37, 41, 46, .2);\n//  }\n//\n//40% {\n//    border: 2px solid #f7275e;\n//    box-shadow: 0 5px 15px rgba(247, 39, 94, .4), 0 10px 30px rgba(37, 41, 46, .2);\n//  }\n//\n//60% {\n//    border: 2px solid #ffd300;\n//    box-shadow: 0 5px 15px rgba(255, 211, 0, .4), 0 10px 30px rgba(37, 41, 46, .2);\n//  }\n//\n//80% {\n//    border: 2px solid #ff8a00;\n//    box-shadow: 0 5px 15px rgba(255, 138, 0, .4), 0 10px 30px rgba(37, 41, 46, .2);\n//  }\n//\n//\n\n.carousel-container {\n  #item-1:checked ~ .cards #selector-1,\n  #item-2:checked ~ .cards #selector-2,\n  #item-3:checked ~ .cards #selector-3,\n    //#item-4:checked ~ .cards #selector-4,\n    //#item-5:checked ~ .cards #selector-5,\n    //#item-6:checked ~ .cards #selector-6,\n    //#item-7:checked ~ .cards #selector-7\n  {\n    //transform: translateX(-120%) scale(0.4);\n    transform: translateX(0%) scale(1);\n    z-index: 80;\n  }\n\n  #item-1:checked ~ .cards #selector-3,\n  #item-2:checked ~ .cards #selector-1,\n  #item-3:checked ~ .cards #selector-2 {\n    transform: translateX(100%) scale(var(--size-image));\n    z-index: 70;\n  }\n\n  #item-1:checked ~ .cards #selector-2,\n  #item-2:checked ~ .cards #selector-3,\n  #item-3:checked ~ .cards #selector-1 {\n    transform: translateX(-100%) scale(var(--size-image));\n    z-index: 70;\n  }\n\n  //#item-2:checked ~ .cards #selector-1,\n  //#item-3:checked ~ .cards #selector-2,\n  //#item-4:checked ~ .cards #selector-3,\n  ////#item-5:checked ~ .cards #selector-4,\n  ////#item-6:checked ~ .cards #selector-5,\n  ////#item-7:checked ~ .cards #selector-6,\n  ////#item-1:checked ~ .cards #selector-7\n  //{\n  //  transform: translateX(-80%) scale(0.6);\n  //  z-index: 20;\n  //}\n\n  //#item-3:checked ~ .cards #selector-1,\n  //#item-4:checked ~ .cards #selector-2,\n  //#item-5:checked ~ .cards #selector-3,\n  //#item-6:checked ~ .cards #selector-4,\n  //#item-7:checked ~ .cards #selector-5,\n  //#item-1:checked ~ .cards #selector-6,\n  //#item-2:checked ~ .cards #selector-7\n  //{\n  //  transform: translateX(-40%) scale(0.8);\n  //  z-index: 30;\n  //}\n  //\n  //#item-4:checked ~ .cards #selector-1,\n  //#item-5:checked ~ .cards #selector-2,\n  //#item-6:checked ~ .cards #selector-3,\n  //#item-7:checked ~ .cards #selector-4,\n  //#item-1:checked ~ .cards #selector-5,\n  //#item-2:checked ~ .cards #selector-6,\n  //#item-3:checked ~ .cards #selector-7{\n  //  transform: translateX(0) scale(1);\n  //  z-index: 40;\n  //}\n  //\n  //#item-5:checked ~ .cards #selector-1,\n  //#item-6:checked ~ .cards #selector-2,\n  //#item-7:checked ~ .cards #selector-3,\n  //#item-1:checked ~ .cards #selector-4,\n  //#item-2:checked ~ .cards #selector-5,\n  //#item-3:checked ~ .cards #selector-6,\n  //#item-4:checked ~ .cards #selector-7{\n  //  transform: translateX(40%) scale(0.8);\n  //  z-index: 30;\n  //}\n  //\n  //#item-6:checked ~ .cards #selector-1,\n  //#item-7:checked ~ .cards #selector-2,\n  //#item-1:checked ~ .cards #selector-3,\n  //#item-2:checked ~ .cards #selector-4,\n  //#item-3:checked ~ .cards #selector-5,\n  //#item-4:checked ~ .cards #selector-6,\n  //#item-5:checked ~ .cards #selector-7{\n  //  transform: translateX(80%) scale(0.6);\n  //  z-index: 20;\n  //}\n  //\n  //#item-7:checked ~ .cards #selector-1,\n  //#item-1:checked ~ .cards #selector-2,\n  //#item-2:checked ~ .cards #selector-3,\n  //#item-3:checked ~ .cards #selector-4,\n  //#item-4:checked ~ .cards #selector-5,\n  //#item-5:checked ~ .cards #selector-6,\n  //#item-6:checked ~ .cards #selector-7{\n  //  transform: translateX(120%) scale(0.4);\n  //  z-index: 10;\n  //}\n}\n"
  },
  {
    "path": "packages/web-wallet/public/wallet_dark.css",
    "content": "@import 'reset.css';\n\nhtml {\n    --color-global-Bg: var(--dark);\n    --color-primary: #446eff;\n    --color-primary-hover: var(--light900);\n    --color-primary-pressed: #2d49b2;\n    --color-disable: #343754;\n    --color-text-primary: var(--light);\n    --color-border: var(--light900);\n    --color-divide: var(--dark800);\n    --color-border-hover: var(--color-primary);\n    --color-text-Secondary: var(--light500);\n    --color-text-third: var(--dark400);\n    --color-text-Button: var(--light);\n    --color-text-ButtonSelect: var(--light);\n    --color-text-Disable: var(--light) 45;\n    --color-box: var(--dark900);\n    --color-logo: var(--light);\n}\n"
  },
  {
    "path": "packages/web-wallet/public/wallet_light.css",
    "content": "@import 'reset.css';\n\nhtml {\n    --color-global-Bg: var(--light900);\n    --color-primary: #446eff;\n    --color-primary-hover: var(--light900) 20;\n    --color-primary-pressed: #2d49b2;\n    --color-disable: #343754;\n    --color-text-primary: var(--dark);\n    --color-border: var(--dark900);\n    --color-divide: var(--light500);\n    --color-border-hover: var(--color-primary);\n    --color-text-Secondary: var(--dark500);\n    --color-text-third: var(--light400);\n    --color-text-Button: var(--dark);\n    --color-text-ButtonSelect: var(--dark);\n    --color-text-Disable: var(--dark) 25;\n    --color-box: var(--light);\n    --color-logo: #446eff;\n}\n"
  },
  {
    "path": "packages/webapp/.babelrc",
    "content": "{\n  \"presets\": [\n    [\n      \"@babel/react\",\n      {\n        \"runtime\": \"automatic\",\n        \"loose\": true\n      }\n    ],\n    [\n      \"@babel/preset-react\",\n      {\n        \"runtime\": \"automatic\"\n      }\n    ]\n  ]\n}\n"
  },
  {
    "path": "packages/webapp/.eslintrc.json",
    "content": "{\n  \"plugins\": [\n    \"react-hooks\"\n  ],\n  \"extends\": [\n    \"react-app\"\n  ],\n  \"overrides\": [\n    {\n      \"files\": [\n        \"**/*.tsx\",\n        \"**/*.ts\"\n      ],\n      \"rules\": {\n        \"import/no-anonymous-default-export\": \"off\",\n        \"@typescript-eslint/no-unused-vars\": \"warn\",\n        \"@typescript-eslint/ban-types\": \"off\",\n        \"react-hooks/rules-of-hooks\": \"warn\",\n        // 检查 Hook 的规则\n        \"react-hooks/exhaustive-deps\": \"warn\"\n        // 检查 effect 的依赖\n      }\n    }\n  ]\n}\n"
  },
  {
    "path": "packages/webapp/.gitignore",
    "content": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n# Runtime data\npids\n*.pid\n*.seed\n*.pid.lock\n\n# Directory for instrumented libs generated by jscoverage/JSCover\nlib-cov\n\n# Coverage directory used by tools like istanbul\ncoverage\n\n# nyc test coverage\n.nyc_output\n\n# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)\n.grunt\n\n# Bower dependency directory (https://bower.io/)\nbower_components\n\n# node-waf configuration\n.lock-wscript\n\n# Compiled binary addons (https://nodejs.org/api/addons.html)\nbuild/Release\n\n# Dependency directories\nnode_modules/\njspm_packages/\n\n# TypeScript v1 declaration files\ntypings/\n\n# Optional npm cache directory\n.npm\n\n# Optional eslint cache\n.eslintcache\n\n# Optional REPL history\n.node_repl_history\n\n# Output of 'npm pack'\n*.tgz\n\n# Yarn Integrity file\n.yarn-integrity\n\n# dotenv environment variables file\n.env\n\n# parcel-bundler cache (https://parceljs.org/)\n.cache\n\n# next.js build output\n.next\n\n# nuxt.js build output\n.nuxt\n\n# vuepress build output\n.vuepress/dist\n\n# Serverless directories\n.serverless/\n\n# FuseBox cache\n.fusebox/\n\n# DynamoDB Local files\n.dynamodb/\n# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\n/node_modules\n/.pnp\n.pnp.js\n\n# testing\n/coverage\n\n# production\n**/build\n/out\n/dist\n\n# misc\n.DS_Store\n.env.local\n.env.development.local\n.env.development\n# .env.prod_for_dev\n\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n*.code-workspace\n.vscode\nopenapitools.json\n*.tgz\n.idea/\ntestkey.txt\n\ntest_datadir\n\nipfs_deploy.txt\n.env.deploy*\n.testfile*\n.DS_Store\n"
  },
  {
    "path": "packages/webapp/ADD_NEW_CHAIN.md",
    "content": "# Way to add a new Chain\n\n### step1:\n\n.env.production\n\n```.env\n## part1 for connection\n# support chainId list eg:REACT_APP_RPC_OTHERS=167005,12345\nREACT_APP_RPC_OTHERS=167005\n# RPC URL for support chain eg:REACT_APP_RPC_URL_167005=https://rpc.test.taiko.xyz/\nREACT_APP_RPC_URL_167005=https://rpc.test.taiko.xyz/\n# Chian Name for show(if test use `|` split) eg:REACT_APP_RPC_CHAINNAME_167005=Taiko|test\nREACT_APP_RPC_CHAINNAME_167005=Taiko|test\n\n## part2 for Dex & API\n# DEX API URL for chain eg: REACT_APP_API_URL_167005=taikodev.loopring.io\nREACT_APP_API_URL_167005=taikodev.loopring.io\n```\n\n### step2: UI/View config\n\npackages/common-resources/static-resources/src/constant/router.ts\n\n#### navigation\n\n```ts\nexport const headerMenuDataMap: { [ key: string ]: HeaderMenuItemInterface[] } = {\n  TAIKO: [\n    {\n      label: {\n        id: 'L2Assets',\n        i18nKey: 'labelAssets',\n      },\n      router: { path: '/l2assets' },\n      status: HeaderMenuTabStatus.default,\n    },\n    {\n      label: {\n        id: 'Markets',\n        i18nKey: 'labelMarkets',\n      },\n      router: { path: '/markets' },\n      status: HeaderMenuTabStatus.default,\n    },\n    {\n      label: {\n        id: 'Trade',\n        i18nKey: 'labelTrade',\n      },\n      status: HeaderMenuTabStatus.default,\n      child: [\n        {\n          label: {\n            id: 'lite',\n            i18nKey: 'labelClassic',\n            description: 'labelClassicDescription',\n          },\n          router: { path: RouterPath.lite + '/${pair}' },\n        },\n        {\n          label: {\n            id: 'pro',\n            i18nKey: 'labelAdvanced',\n            description: 'labelAdvancedDescription',\n          },\n          router: { path: RouterPath.pro + '/${pair}' },\n        },\n      ],\n    },\n  ],\n}\n```\n\n#### avaiable land page\n\n```ts\nexport const RouterAllowIndex = {\n  TAIKO: [\n    RouterMainKey.lite,\n    RouterMainKey.pro,\n    RouterMainKey.markets,\n    RouterMainKey.l2assets,\n    RouterMainKey.layer2,\n  ],\n  ETHEREUM: [\n    RouterMainKey.lite,\n    RouterMainKey.pro,\n    RouterMainKey.stoplimit,\n    RouterMainKey.btrade,\n    RouterMainKey.fiat,\n    RouterMainKey.markets,\n    RouterMainKey.mining,\n    RouterMainKey.redPacket,\n    RouterMainKey.l2assets,\n    RouterMainKey.layer2,\n    RouterMainKey.nft,\n    RouterMainKey.invest,\n  ],\n  GOERLI: [\n    RouterMainKey.lite,\n    RouterMainKey.pro,\n    RouterMainKey.stoplimit,\n    RouterMainKey.btrade,\n    RouterMainKey.fiat,\n    RouterMainKey.markets,\n    RouterMainKey.mining,\n    RouterMainKey.redPacket,\n    RouterMainKey.l2assets,\n    RouterMainKey.layer2,\n    RouterMainKey.nft,\n    RouterMainKey.invest,\n  ],\n}\n```\n\n#### support send/receive assets way\n\n```ts\nexport const AddAssetListMap = {\n  TAIKO: [\n    AddAssetList.FromMyL1.key,\n    AddAssetList.FromOtherL2.key,\n    // AddAssetList.FromExchange.key,\n  ],\n  ETHEREUM: [\n    AddAssetList.FromMyL1.key,\n    AddAssetList.BuyWithCard.key,\n    AddAssetList.FromOtherL2.key,\n    AddAssetList.FromOtherL1.key,\n    AddAssetList.FromExchange.key,\n    AddAssetList.FromAnotherNet.key,\n  ],\n  GOERLI: [\n    AddAssetList.FromMyL1.key,\n    AddAssetList.BuyWithCard.key,\n    AddAssetList.FromOtherL2.key,\n    AddAssetList.FromOtherL1.key,\n    AddAssetList.FromExchange.key,\n    AddAssetList.FromAnotherNet.key,\n  ],\n}\nexport const SendAssetListMap = {\n  TAIKO: [\n    SendAssetList.SendAssetToMyL1.key,\n    SendAssetList.SendAssetToL2.key,\n    SendAssetList.SendAssetToOtherL1.key,\n  ],\n  ETHEREUM: [\n    SendAssetList.SendAssetToMyL1.key,\n    SendAssetList.SendAssetToL2.key,\n    SendAssetList.SendAssetToOtherL1.key,\n    SendAssetList.SendAssetToAnotherNet.key,\n  ],\n  GOERLI: [\n    SendAssetList.SendAssetToMyL1.key,\n    SendAssetList.SendAssetToL2.key,\n    SendAssetList.SendAssetToOtherL1.key,\n    SendAssetList.SendAssetToAnotherNet.key,\n  ],\n}\n```\n\n#### support AssetL2 assets tab\n\n```ts\nexport const AssetL2TabIndex = {\n  TAIKO: [AssetTabIndex.Tokens],\n  ETHEREUM: [AssetTabIndex.Tokens, AssetTabIndex.Invests, AssetTabIndex.RedPacket],\n  GOERLI: [AssetTabIndex.Tokens, AssetTabIndex.Invests, AssetTabIndex.RedPacket],\n}\n```\n\n#### support user Profile\n\n```ts\nexport const ProfileIndex = {\n  TAIKO: [Layer2RouterID.security, Layer2RouterID.referralrewards],\n  ETHEREUM: [Layer2RouterID.security, Layer2RouterID.vip, Layer2RouterID.contact, Layer2RouterID.referralrewards],\n  GOERLI: [Layer2RouterID.security, Layer2RouterID.vip, Layer2RouterID.contact, Layer2RouterID.referralrewards],\n}\n```\n\n#### 118n key name\n\n```ts\nexport const L1L2_NAME_DEFINED = {\n  TAIKO: {\n    layer2: 'Layer 3',\n    l1ChainName: 'TAIKO',\n    loopringL2: 'Loopring L3',\n    l2Symbol: 'L3',\n    l1Symbol: 'TAIKO',\n    ethereumL1: 'TAIKO',\n    loopringLayer2: 'Loopring Layer 3',\n  },\n  ETHEREUM: {\n    layer2: 'Layer 2',\n    l1ChainName: 'Ethereum',\n    loopringL2: 'Loopring L2',\n    l2Symbol: 'L2',\n    l1Symbol: 'L1',\n    ethereumL1: 'Ethereum L1',\n    loopringLayer2: 'Loopring Layer 2',\n  },\n  GOERLI: {\n    layer2: 'Layer 2',\n    l1ChainName: 'Ethereum',\n    loopringL2: 'Loopring L2',\n    l2Symbol: 'L2',\n    l1Symbol: 'L1',\n    ethereumL1: 'Ethereum L1',\n    loopringLayer2: 'Loopring Layer 2',\n  },\n}\n```\n\n### U base token address\n\n```ts\nexport const TokenPriceBase = {\n  TAIKO: '0x0000000000000000000000000000000000000000',\n  ETHEREUM: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',\n  GOERLI: '0xd4e71c4bb48850f5971ce40aa428b09f242d3e8a',\n}\n```\n\n### Record history\n\n```ts\nexport const RecordMap: { [ key: string ]: RecordTabIndex[] } = {\n  TAIKO: [RecordTabIndex.Transactions, RecordTabIndex.Trades, RecordTabIndex.Orders],\n  ETHEREUM: [\n    RecordTabIndex.Transactions,\n    RecordTabIndex.Trades,\n    RecordTabIndex.Orders,\n    RecordTabIndex.StopLimitRecords,\n    RecordTabIndex.AmmRecords,\n    RecordTabIndex.DefiRecords,\n    RecordTabIndex.DualRecords,\n    RecordTabIndex.SideStakingRecords,\n    RecordTabIndex.BtradeSwapRecords,\n  ],\n  GOERLI: [\n    RecordTabIndex.Transactions,\n    RecordTabIndex.Trades,\n    RecordTabIndex.Orders,\n    RecordTabIndex.StopLimitRecords,\n    RecordTabIndex.AmmRecords,\n    RecordTabIndex.DefiRecords,\n    RecordTabIndex.DualRecords,\n    RecordTabIndex.SideStakingRecords,\n    RecordTabIndex.BtradeSwapRecords,\n  ],\n}\n\n```\n"
  },
  {
    "path": "packages/webapp/README.md",
    "content": "<p align=\"center\">\n  <a href=\"https://github.com/Loopring/loopring-web-v2\" rel=\"noopener\" target=\"_blank\"><img width=\"150\" src=\"https://loopring.org/images/logo.svg\" alt=\"Loopring-website\"></a>\n</p>\n\n<h1 align=\"center\">Loopring Application</h1>\n<div align=\"center\">\n<h2>Ethereum’s First zkRollup Layer2</h2>\n<p>Fast, Secure, and 100x Lower Fees</p>\n\n[![license](https://img.shields.io/badge/license-MIT-blue)](https://github.com/Loopring/loopring-web-v2/master/LICENSE)\n\n[![type-badge](https://img.shields.io/npm/types/react-data-grid)](https://www.npmjs.com/package/react-data-grid)\n\n<!-- [![Materi-UI](https://img.shields.io/npm/types/react-data-grid)](https://www.npmjs.com/package/react-data-grid) -->\n\n</div>\n\n## 🚀 Quick Start\n\n```bash\n// with yarn\nyarn install\nyarn up\ncd ./packages/webapp\nnpm run dev\n\n\n```\n\n## 📚 Loopring UI component StoryBook\n\n```bash\n\ncd ./packages/component-lib\nnpm run storybook\n```\n\n## 🏗 Framework Design\n\n![](https://static.loopring.io/Loopring%20framwork.png)\n\n## 👉 [What is Loopring?](https://loopring.org/#/)\n\n## 🫂 Community\n\n- [Loopring Website](https://loopring.org/)\n- [Loopring Exchange](https://loopring.io/#/layer2)\n- [Loopring Reddit](https://www.reddit.com/r/loopringorg/)\n- [Loopring Medium](https://medium.com/loopring-protocol)\n- [Loopring Twitter](https://twitter.com/loopringorg)\n- [Loopring Telegram](https://t.me/loopring_en)\n\n## 👺 For Developer\n\n- We appreciate any improvements or initiatives for Loopring Layer2 website, please view the source code\n  in `./packages/component-lib`.\n- The project contains a separate lib \"web3-provider\", which is a third-party ETH web3 wallet provider service (\n  wallectConnect & metamask),\n- You are welcome to reuse it or integrate your provider service with our website.\n- Feel free to leave suggestions or ideas.\n\n### 📒 API & Dependency\n\n- [Web3-Provider](https://www.npmjs.com/package/@loopring-web/web3-provider)\n- [Loopring-sdk](https://www.npmjs.com/package/@loopring-web/loopring-sdk)\n- [Python](https://github.com/Loopring/hello_loopring)\n- [APIs](https://docs.loopring.io)\n\n## 🙋 Protocol & Architecture\n\n- [Whitepaper](https://loopring.org/resources/en_whitepaper.pdf)\n- [Design Docs](https://github.com/LoopringSecondary/docs/wiki/Loopring3_Design)\n\n## ❓[Help](https://desk.zoho.com/portal/loopring/en/home)\n\n## 🔑 Security\n\n- [Wallet](https://security.loopring.io/)\n- [Protocol Audit](https://loopring.org/resources/loopring1.0_audit.pdf)\n\n## Release Process\n\nalpha.loopring.io, beta.loopring.io, static.loopring.io, and loopring.io are now auto deployed using Vercel.\n"
  },
  {
    "path": "packages/webapp/craco.config.js",
    "content": "module.exports = require(\"../../craco.config.cjs\")"
  },
  {
    "path": "packages/webapp/electron-builder.env",
    "content": "ELECTRON_BUILDER_ALLOW_UNRESOLVED_DEPENDENCIES=true\n"
  },
  {
    "path": "packages/webapp/generate-react-cli.json",
    "content": "{\n  \"usesTypeScript\": true,\n  \"usesCssModule\": true,\n  \"cssPreprocessor\": \"scss\",\n  \"testLibrary\": \"Testing Library\",\n  \"component\": {\n    \"default\": {\n      \"path\": \"src/components\",\n      \"withLazy\": false,\n      \"withStory\": true,\n      \"withStyle\": true,\n      \"withTest\": true\n    },\n    \"page\": {\n      \"path\": \"src/pages\",\n      \"withLazy\": true,\n      \"withStory\": false,\n      \"withStyle\": true,\n      \"withTest\": true\n    },\n    \"layout\": {\n      \"path\": \"src/layout\",\n      \"withLazy\": false,\n      \"withStory\": false,\n      \"withStyle\": false,\n      \"withTest\": true\n    }\n  }\n}\n"
  },
  {
    "path": "packages/webapp/jest.config.js",
    "content": "module.exports = {\n  testEnvironment: 'node',\n\n  setupFilesAfterEnv: ['./jest.setup.js'],\n}\n"
  },
  {
    "path": "packages/webapp/jest.setup.js",
    "content": "process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0\n\njest.setTimeout(30000)\n"
  },
  {
    "path": "packages/webapp/package.json",
    "content": "{\n  \"name\": \"@loopring-web/webapp\",\n  \"version\": \"1.0.0\",\n  \"author\": \"Loopring L2 App Frontend Team\",\n  \"description\": \"dexwebapp new version\",\n  \"private\": true,\n  \"dependencies\": {\n    \"@loopring-web/common-resources\": \"1.0.0\",\n    \"@loopring-web/component-lib\": \"1.0.0\",\n    \"@loopring-web/core\": \"1.0.0\",\n    \"@manaflair/redux-batch\": \"^1.0.0\",\n    \"clipboard\": \"^2.0.8\",\n    \"cross-env\": \"^7.0.3\",\n    \"export-from-json\": \"^1.4.0\",\n    \"lodash\": \"^4.17.20\",\n    \"ms.macro\": \"^2.0.0\",\n    \"react-device-detect\": \"^1.17.0\",\n    \"react-router-dom\": \"^5.2.0\",\n    \"react-scripts\": \"5.0.1\",\n    \"redux-logger\": \"^3.0.6\",\n    \"redux-saga\": \"^1.1.3\",\n    \"snarkjs\": \"0.1.20\",\n    \"web-vitals\": \"^0.2.4\"\n  },\n  \"resolutions\": {\n    \"@types/react\": \"^18.2.19\",\n    \"@types/react-dom\": \"^18.2.7\"\n  },\n  \"build\": {\n    \"files\": [\n      \"build/**/*\",\n      \"node_modules/**/*\"\n    ],\n    \"publish\": {\n      \"provider\": \"custom\",\n      \"repo\": \"https://github.com/Loopring/loopring-web-v2\",\n      \"owner\": \"Loopring Dex Frontend Team\"\n    }\n  },\n  \"main\": \"./public/electron.js\",\n  \"homepage\": \".\",\n  \"scripts\": {\n    \"prettier\": \"prettier . --write\",\n    \"build\": \"git rev-parse --short HEAD; cross-env REACT_APP_VER=`git rev-parse --short HEAD`_prod dotenv -e .env.production  craco build\",\n    \"dev\": \"cross-env HOST=0.0.0.0 REACT_APP_VER=\\\"git rev-parse --short HEAD\\\"_dev dotenv -e .env.development craco start\",\n    \"build_dev\": \"REACT_APP_VER=`git rev-parse --short HEAD`_dev dotenv -e .env.development craco build\",\n    \"check\": \"yalc remove @loopring-web/web3-provider@dev; yalc add @loopring-web/web3-provider@dev; yarn build\"\n  },\n  \"browserslist\": {\n    \"production\": [\n      \"last 2 chrome version\",\n      \"last 2 firefox version\",\n      \"last 2 safari version\"\n    ],\n    \"development\": [\n      \"last 1 chrome version\",\n      \"last 1 firefox version\",\n      \"last 1 safari version\"\n    ]\n  }\n}\n"
  },
  {
    "path": "packages/webapp/public/badge.xml",
    "content": "<FrameLayout xmlns:android=\"https://download.loopring.io/LoopringWallet.apk\"\n             xmlns:app=\"https://download.loopring.io/\"\n             android:layout_width=\"match_parent\"\n             android:layout_height=\"match_parent\">\n\n    <TextView\n            android:id=\"@+id/notifications.badge\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"top|center_horizontal\"\n            android:layout_marginLeft=\"10dp\"\n            android:layout_marginStart=\"10dp\"\n            android:background=\"@drawable/notification_badge\"\n            android:gravity=\"center\"\n            android:padding=\"3dp\"\n            android:text=\"9+\"\n            android:textColor=\"@color/white\"\n            android:textSize=\"11sp\"/>\n</FrameLayout>"
  },
  {
    "path": "packages/webapp/public/browserconfig.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<browserconfig>\n    <msapplication>\n        <tile>\n            <!--            <square70x70logo src=\"small.png\"/>-->\n            <!--            <square150x150logo src=\"medium.png\"/>-->\n            <!--            <wide310x150logo src=\"wide.png\"/>-->\n            <!--            <square310x310logo src=\"large.png\"/>-->\n            <square129x129logo src=\"loopring129.png\"/>\n            <TileColor>#3B5AF4</TileColor>\n        </tile>\n        <badge>\n            <polling-uri src=\"badge.xml\"/>\n            <frequency>30</frequency>\n        </badge>\n        <!--        <notification>-->\n        <!--            <polling-uri  src=\"1.xml\"/>-->\n        <!--            <polling-uri2 src=\"2.xml\"/>-->\n        <!--            <polling-uri3 src=\"3.xml\"/>-->\n        <!--            <polling-uri4 src=\"4.xml\"/>-->\n        <!--            <polling-uri5 src=\"5.xml\"/>-->\n        <!--            <frequency>30</frequency>-->\n        <!--            <cycle>1</cycle>-->\n        <!--        </notification>-->\n    </msapplication>\n</browserconfig>"
  },
  {
    "path": "packages/webapp/public/electron.js",
    "content": "const path = require('path')\n\nconst { app, BrowserWindow } = require('electron')\nconst isDev = require('electron-is-dev')\n\nconsole.log('BROWSER:', process.env.BROWSER)\nconsole.log('NODE_ENV:', process.env.NODE_ENV)\n\nfunction createWindow() {\n  // Create the browser window.\n  const win = new BrowserWindow({\n    width: 1024,\n    height: 768,\n    frame: true,\n    webPreferences: {\n      nodeIntegration: true,\n    },\n  })\n\n  // and load the index.html of the app.\n  // win.loadFile(\"index.html\");\n  win.loadURL(\n    isDev ? 'http://localhost:3000' : `file://${path.join(__dirname, '../build/index.html')}`,\n  )\n\n  // Open the DevTools.\n  if (isDev) {\n    win.webContents.openDevTools({ mode: 'detach' })\n  }\n}\n\n// This method will be called when Electron has finished\n// initialization and is ready to create browser windows.\n// Some APIs can only be used after this event occurs.\napp.whenReady().then(createWindow)\n\n// Quit when all windows are closed, except on macOS. There, it's common\n// for applications and their menu bar to stay active until the user quits\n// explicitly with Cmd + Q.\napp.on('window-all-closed', () => {\n  if (process.platform !== 'darwin') {\n    app.quit()\n  }\n})\n\napp.on('activate', () => {\n  // On macOS it's common to re-create a window in the app when the\n  // dock icon is clicked and there are no other windows open.\n  if (BrowserWindow.getAllWindows().length === 0) {\n    createWindow()\n  }\n})\n"
  },
  {
    "path": "packages/webapp/public/index.html",
    "content": "<!DOCTYPE html>\n<html lang='en'>\n<head>\n  <meta charset='utf-8' />\n  <link rel='icon' href='%PUBLIC_URL%/favicon.ico' />\n  <link rel='mask-icon' href='%PUBLIC_URL%/loopring.svg' color='#3B5AF4' />\n  <meta name='description' content='Ethereum zkRollup Exchange and Payment Protocol' />\n  <link rel='icon' type='image/png' href='%PUBLIC_URL%/favicon.png' />\n  <link rel='icon' type='image/png' sizes='16x16' href='%PUBLIC_URL%/favicon-16x16.png' />\n  <link rel='icon' type='image/png' sizes='32x32' href='%PUBLIC_URL%/favicon-32x32.png' />\n  <link rel='icon' type='image/png' sizes='48x48' href='%PUBLIC_URL%/favicon-48x48.png' />\n  <link\n    rel='apple-touch-icon'\n    type='image/png'\n    sizes='180x180'\n    href='%PUBLIC_URL%/apple-touch-icon.png'\n  />\n  <meta\n    name='viewport'\n    content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0'\n  />\n  <meta name='theme-color' content='#000000' />\n  <meta\n    name='description'\n    content='Loopring Layer 2, Ethereum zkRollup Exchange and Payment Protocol'\n  />\n  <link\n    rel='stylesheet'\n    href='https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap'\n  />\n  <link href='/apple-touch-icon.png' rel='/apple-touch-icon' />\n  <!--\n    manifest.json provides metadata used when your web app is installed on a\n    user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/\n  -->\n  <link rel='manifest' href='%PUBLIC_URL%/manifest.json' />\n  <!--\n    Notice the use of %PUBLIC_URL% in the tags above.\n    It will be replaced with the URL of the `public` folder during the build.\n    Only files inside the `public` folder can be referenced from the HTML.\n\n    Unlike \"/favicon.ico\" or \"favicon.ico\", \"%PUBLIC_URL%/favicon.ico\" will\n    work correctly both with client-side routing and a non-root public URL.\n    Learn how to configure a non-root public URL by running `npm run build`.\n  -->\n  <style type='text/css'>\n      body {\n          height: 100vh;\n          background: linear-gradient(194.79deg, #141414 17.96%, #141414 44.29%, #1F1F1F 96.93%);\n          color: #fff;\n          flex-direction: column;\n      }\n\n      .iubenda-pure {\n          height: 0;\n      !important;\n          width: 0;\n      !important;\n          line-height: 0;\n      !important;\n          overflow: hidden;\n      !important;\n          padding: 0;\n          margin: 0;\n          display: none;\n      !important;\n\n      }\n\n      #iubenda-pp iframe {\n          display: block;\n      }\n  </style>\n  <script async src='https://www.googletagmanager.com/gtag/js?id=UA-224502206-1'></script>\n  <script>\n    window.dataLayer = window.dataLayer || []\n    window.global = window\n    function gtag() {\n      dataLayer.push(arguments)\n    }\n\n    gtag('js', new Date())\n    gtag('config', 'UA-224502206-1')\n  </script>\n  <title>Loopring</title>\n  <!-- Global site tag (gtag.js) - Google Analytics -->\n</head>\n\n<body ondragstart='return false;' ondrop='return false;' draggable='false'>\n<noscript>You need to enable JavaScript to run this app.</noscript>\n<div id='root' style='width: 100%; height: 100vh; display: flex; flex-direction: column'></div>\n<!--\n  This HTML file is a template.\n  If you open it directly in the browser, you will see an empty page.\n\n  You can add webfonts, meta tags, or analytics to this file.\n  The build step will place the bundled scripts into the <body> tag.\n\n  To begin the development, run `npm start` or `yarn start`.\n  To create a production bundle, use `npm run build` or `yarn build`.\n-->\n<div hidden>\n  <a\n    href='https://www.iubenda.com/terms-and-conditions/74969935'\n    data-index='0'\n    class='iubenda-white iubenda-embed iubenda-pure iubenda-noiframe'\n  ></a>\n  <!--      <a href=\"https://www.iubenda.com/terms-and-conditions/74969935\"-->\n  <!--         class=\"iubenda-black iubenda-embed iubenda-pure iubenda-noiframe\"></a>-->\n</div>\n\n<!--<button id=\"iframeButton\">Launch iframe</button>-->\n<div id='iframeBanxaTarget'>\n  <div id='iframeBanxaClose'>\n    <svg fill='#00C8C0' height='24' viewBox='0 0 24 24' width='24'>\n      <path\n        d='M17.59 5L12 10.59L6.41 5L5 6.41L10.59 12L5 17.59L6.41 19L12 13.41L17.59 19L19 17.59L13.41 12L19 6.41L17.59 5Z'\n      />\n    </svg>\n  </div>\n  <!-- Where the iframe will be loaded  -->\n</div>\n<script type='text/javascript'>\n  ;(function(w, d) {\n    var loader = function() {\n      var s = d.createElement('script'),\n        tag = d.getElementsByTagName('script')[0]\n      s.src = 'https://cdn.iubenda.com/iubenda.js'\n      tag.parentNode.insertBefore(s, tag)\n\n      var b = d.createElement('script')\n      ;(b.type = 'text/javascript'),\n        (b.async = !0),\n        (b.src = 'https://sdk.banxa.com/js/banxa-sdk-latest.js')\n      tag.parentNode.insertBefore(b, tag)\n    }\n    if (w.addEventListener) {\n      w.addEventListener('load', loader, false)\n    } else if (w.attachEvent) {\n      w.attachEvent('onload', loader)\n    } else {\n      w.onload = loader\n    }\n  })(window, document)\n</script>\n<script\n  src='https://ajax.googleapis.com/ajax/libs/model-viewer/3.0.1/model-viewer.min.js'\n  type='module'\n></script>\n</body>\n</html>\n"
  },
  {
    "path": "packages/webapp/public/manifest.json",
    "content": "{\n  \"short_name\": \"Loopring L2\",\n  \"name\": \"Loopring - Ethereum Layer2\",\n  \"icons\": [\n    {\n      \"src\": \"favicon.ico\",\n      \"sizes\": \"64x64 32x32 24x24 16x16\",\n      \"type\": \"image/x-icon\"\n    }\n  ],\n  \"start_url\": \".\",\n  \"display\": \"standalone\",\n  \"theme_color\": \"#000000\",\n  \"background_color\": \"#ffffff\"\n}\n"
  },
  {
    "path": "packages/webapp/public/robots.txt",
    "content": "# https://www.robotstxt.org/robotstxt.html\nUser-agent: *\nDisallow:\n"
  },
  {
    "path": "packages/webapp/src/App.tsx",
    "content": "import RouterView from './routers'\nimport { GlobalStyles } from '@mui/material'\nimport { css, Theme, useTheme } from '@emotion/react'\nimport { globalCss } from '@loopring-web/common-resources'\nimport { AccountStep, setLanguage, useOpenModals } from '@loopring-web/component-lib'\nimport { useInit } from './hook'\nimport React from 'react'\nimport { useTranslation } from 'react-i18next'\n\nimport { HashRouter as Router, useLocation } from 'react-router-dom'\nimport { store } from '@loopring-web/core'\n\nconst ScrollToTop = () => {\n  const { pathname } = useLocation()\n\n  React.useEffect(() => {\n    window.scrollTo(0, 0)\n  }, [pathname])\n\n  return null\n}\nconst App = () => {\n  const theme: Theme = useTheme()\n  const {\n    i18n: { language },\n  } = useTranslation()\n  const storeLan = store.getState().settings.language\n  React.useEffect(() => {\n    if (storeLan !== language) {\n      store.dispatch(setLanguage(language))\n    }\n  }, [storeLan, language])\n  const setShowAccount=useOpenModals().setShowAccount\n\n  React.useEffect(() => {\n    if (window.location.protocol !== 'https:') {\n      console.log('Current PROTOCOL::', window.location.protocol)\n      window.location.replace(\n        `https:${window.location.href.substring(window.location.protocol.length)}`,\n      )\n    }\n    // setInterval(() => {\n    //   setShowAccount({\n    //     isShow: true,\n    //     step: AccountStep.CreateAccount_EOA_Only_Alert\n    //   })\n    // }, 2 * 1000);\n  }, [])\n\n  const { state } = useInit()\n\n  return (\n    <>\n      <GlobalStyles\n        styles={css`\n          ${globalCss({ theme })};\n\n          body {\n            ${\n              theme.mode === 'dark'\n                ? `\n            color: ${theme.colorBase.textPrimary};\n          `\n                : ``\n            }\n\n\n          }\n\n          body:before {\n            ${\n              theme.mode === 'dark'\n                ? `\n            background: var(--color-global-bg);\n       `\n                : ''\n            }\n          }\n        }`}\n      />\n\n      <Router>\n        <ScrollToTop />\n        <RouterView state={state} />\n      </Router>\n    </>\n  )\n}\nconst h = new Headers()\nexport default App\n"
  },
  {
    "path": "packages/webapp/src/hook.ts",
    "content": "import React from 'react'\nimport {\n  useSystem,\n  useAmmMap,\n  useTokenMap,\n  useAccount,\n  useTicker,\n  useAmmActivityMap,\n  useTokenPrices,\n  useAmount,\n  useSocket,\n  useNotify,\n  layer1Store,\n  useDefiMap,\n  useInvestTokenTypeMap,\n  useDualMap,\n  useStakingMap,\n  useBtradeMap,\n  useVaultMap,\n  useInjectWeb3Modal,\n} from '@loopring-web/core'\nimport { ChainId } from '@loopring-web/loopring-sdk'\nimport { myLog, SagaStatus, SUPPORTING_NETWORKS, ThemeType } from '@loopring-web/common-resources'\nimport {\n  ConnectProviders,\n  ConnectProvides,\n  connectProvides,\n  walletServices,\n} from '@loopring-web/web3-provider'\nimport { useAccountInit } from './hookAccountInit'\nimport { useSettings } from '@loopring-web/component-lib'\nimport { useTheme } from '@emotion/react'\nimport {  useAppKitAccount, useAppKitNetwork } from '@reown/appkit/react'\n\n/**\n * @description\n * @step1 subscribe Connect hook\n * @step2 check the session storage ? choose the provider : none provider\n * @step3 decide china ID by step2\n * @step4 prepare the static date (tokenMap, ammMap, faitPrice, gasPrice, Activities ...)\n * @step5 launch the page\n */\nexport function useInit() {\n  const [, search] = window.location?.hash.split('?') ?? []\n  const searchParams = new URLSearchParams(search)\n  const [, pathname1] = window.location.hash.match(/#\\/([\\w\\d\\-]+)\\??/) ?? []\n  const isNoServer: boolean =\n    searchParams.has('noheader') && ['notification', 'document'].includes(pathname1)\n  const [state, setState] = React.useState<keyof typeof SagaStatus>(() => {\n    if (isNoServer) {\n      return SagaStatus.DONE\n    } else {\n      return SagaStatus.PENDING\n    }\n  })\n  const { isMobile, defaultNetwork } = useSettings()\n  const theme = useTheme()\n\n  const {\n    account,\n    updateAccount,\n    resetAccount,\n    status: accountStatus,\n    statusUnset: accountStatusUnset,\n  } = useAccount()\n  const { status: tokenMapStatus, statusUnset: tokenMapStatusUnset } = useTokenMap()\n  const { status: ammMapStatus, statusUnset: ammMapStatusUnset } = useAmmMap()\n  const {\n    status: tokenPricesStatus,\n    getTokenPrices,\n    statusUnset: tokenPricesUnset,\n  } = useTokenPrices()\n  const { status: defiMapStatus, statusUnset: defiMapStatusUnset } = useDefiMap()\n  const { status: dualMapStatus, statusUnset: dualMapStatusUnset } = useDualMap()\n  const { status: stakingMapStatus, statusUnset: stakingMapStatusUnset } = useStakingMap()\n  const { status: btradeMapStatus, statusUnset: btradeMapStatusUnset } = useBtradeMap()\n  const { status: investTokenTypeMapStatus, statusUnset: investTokenTypeMapStatusUnset } =\n    useInvestTokenTypeMap()\n\n  const { updateSystem, status: systemStatus, statusUnset: systemStatusUnset } = useSystem()\n  const { status: ammActivityMapStatus, statusUnset: ammActivityMapStatusUnset } =\n    useAmmActivityMap()\n  const { status: tickerStatus, statusUnset: tickerStatusUnset } = useTicker()\n  const { status: amountStatus, statusUnset: amountStatusUnset } = useAmount()\n  const { status: socketStatus, statusUnset: socketUnset } = useSocket()\n  const { circleUpdateLayer1ActionHistory } = layer1Store.useLayer1Store()\n  const { status: notifyStatus, statusUnset: notifyStatusUnset } = useNotify()\n  const { status: vaultStatus, statusUnset: vaultStatusUnset } = useVaultMap()\n  const { chainId: _chainId } = useAppKitNetwork()\n  const chainId = Number(_chainId)\n\n  React.useEffect(() => {\n    ConnectProvides.walletConnectClientMeta = {\n      ...ConnectProvides.walletConnectClientMeta,\n      url:\n        process?.env?.REACT_APP_WALLETCONNECTCLIENTMETA_URL ??\n        ConnectProvides.walletConnectClientMeta.url,\n      name:\n        process?.env?.REACT_APP_WALLETCONNECTCLIENTMETA_NAME ??\n        ConnectProvides.walletConnectClientMeta.name,\n      description:\n        process?.env?.REACT_APP_WALLETCONNECTCLIENTMETA_DESCRIPTION ??\n        ConnectProvides.walletConnectClientMeta.description,\n    }\n    ;(async (account) => {\n      if (\n        account.accAddress !== ''\n      ) {\n        try {\n          ConnectProvides.IsMobile = isMobile\n          if (chainId) {\n            updateAccount({})\n            const _chainId = !SUPPORTING_NETWORKS\n            .includes(chainId.toString())\n              ? account._chainId && account._chainId !== 'unknown'\n                ? account._chainId\n                : ChainId.MAINNET\n              : chainId\n            circleUpdateLayer1ActionHistory({ chainId: _chainId })\n\n            if (!isNoServer) {\n              updateSystem({ chainId: _chainId as any })\n            }\n            return\n          }\n        } catch (error: any) {\n          walletServices.sendDisconnect('', `error at init loading  ${error}, disconnect`)\n          const chainId =\n            account._chainId && account._chainId !== 'unknown' ? account._chainId : ChainId.MAINNET\n          if (!isNoServer) {\n            updateSystem({ chainId })\n          }\n        }\n      } else {\n        if (account.accAddress === '') {\n          resetAccount()\n        }\n        const chainId = defaultNetwork\n        if (!isNoServer) {\n          updateSystem({ chainId })\n        }\n      }\n    })(account)\n  }, [chainId])\n  React.useEffect(() => {\n    switch (accountStatus) {\n      case SagaStatus.ERROR:\n        accountStatusUnset()\n        setState('ERROR')\n        break\n      case SagaStatus.DONE:\n        accountStatusUnset()\n        break\n      default:\n        break\n    }\n  }, [accountStatus])\n  React.useEffect(() => {\n    switch (systemStatus) {\n      case SagaStatus.PENDING:\n        if (!searchParams.has('noheader') && state !== SagaStatus.PENDING) {\n          setState(SagaStatus.PENDING)\n        }\n        break\n      case SagaStatus.ERROR:\n        systemStatusUnset()\n        setState('ERROR')\n        break\n      case SagaStatus.DONE:\n        systemStatusUnset()\n        break\n      default:\n        break\n    }\n  }, [systemStatus])\n  React.useEffect(() => {\n    if (\n      tokenMapStatus === SagaStatus.UNSET &&\n      ammMapStatus === SagaStatus.UNSET &&\n      tokenPricesStatus === SagaStatus.UNSET\n    ) {\n      setState('DONE')\n    }\n  }, [tokenMapStatus, ammMapStatus, tokenPricesStatus])\n  React.useEffect(() => {\n    switch (tokenMapStatus) {\n      case SagaStatus.ERROR:\n        tokenMapStatusUnset()\n        setState('ERROR')\n        break\n      case SagaStatus.DONE:\n        tokenMapStatusUnset()\n        break\n      default:\n        break\n    }\n  }, [tokenMapStatus])\n  React.useEffect(() => {\n    switch (ammMapStatus) {\n      case SagaStatus.ERROR:\n        ammMapStatusUnset()\n        setState('ERROR')\n        break\n      case SagaStatus.DONE:\n        ammMapStatusUnset()\n        break\n      default:\n        break\n    }\n  }, [ammMapStatus])\n\n  React.useEffect(() => {\n    switch (tokenPricesStatus) {\n      case SagaStatus.ERROR:\n        tokenPricesUnset()\n        setState('ERROR')\n        getTokenPrices()\n        break\n      case SagaStatus.DONE:\n        tokenPricesUnset()\n        break\n      default:\n        break\n    }\n  }, [tokenPricesStatus])\n  React.useEffect(() => {\n    switch (ammActivityMapStatus) {\n      case SagaStatus.ERROR:\n        console.log('Network ERROR::', 'getAmmPoolActivityRules')\n        ammActivityMapStatusUnset()\n        break\n      case SagaStatus.DONE:\n        ammActivityMapStatusUnset()\n        break\n      default:\n        break\n    }\n  }, [ammActivityMapStatus])\n  React.useEffect(() => {\n    switch (tickerStatus) {\n      case SagaStatus.ERROR:\n        console.log('Network ERROR::', 'getMixTicker')\n        tickerStatusUnset()\n        break\n      case SagaStatus.DONE:\n        tickerStatusUnset()\n        break\n      default:\n        break\n    }\n  }, [tickerStatus])\n  React.useEffect(() => {\n    switch (amountStatus) {\n      case SagaStatus.ERROR:\n        console.log('Network ERROR::', 'userAPI getMinimumTokenAmt')\n        amountStatusUnset()\n        break\n      case SagaStatus.DONE:\n        amountStatusUnset()\n        break\n      default:\n        break\n    }\n  }, [amountStatus])\n  React.useEffect(() => {\n    switch (socketStatus) {\n      case SagaStatus.ERROR:\n        socketUnset()\n        break\n      case SagaStatus.DONE:\n        socketUnset()\n        break\n      default:\n        break\n    }\n  }, [socketStatus])\n  React.useEffect(() => {\n    switch (notifyStatus) {\n      case SagaStatus.ERROR:\n        notifyStatusUnset()\n        break\n      case SagaStatus.DONE:\n        notifyStatusUnset()\n        break\n      default:\n        break\n    }\n  }, [notifyStatus])\n\n  React.useEffect(() => {\n    switch (vaultStatus) {\n      case SagaStatus.ERROR:\n        vaultStatusUnset()\n        break\n      case SagaStatus.DONE:\n        vaultStatusUnset()\n        break\n      default:\n        break\n    }\n  }, [vaultStatus])\n\n  // vaultStatus\n  React.useEffect(() => {\n    switch (defiMapStatus) {\n      case SagaStatus.ERROR:\n        defiMapStatusUnset()\n        // setState(\"ERROR\");\n        break\n      case SagaStatus.DONE:\n        defiMapStatusUnset()\n        break\n      default:\n        break\n    }\n  }, [defiMapStatus])\n\n  React.useEffect(() => {\n    switch (dualMapStatus) {\n      case SagaStatus.ERROR:\n        dualMapStatusUnset()\n        // setState(\"ERROR\");\n        break\n      case SagaStatus.DONE:\n        dualMapStatusUnset()\n        break\n      default:\n        break\n    }\n  }, [dualMapStatus])\n  React.useEffect(() => {\n    switch (stakingMapStatus) {\n      case SagaStatus.ERROR:\n        stakingMapStatusUnset()\n        // setState(\"ERROR\");\n        break\n      case SagaStatus.DONE:\n        stakingMapStatusUnset()\n        break\n      default:\n        break\n    }\n  }, [stakingMapStatus])\n  React.useEffect(() => {\n    switch (btradeMapStatus) {\n      case SagaStatus.ERROR:\n        btradeMapStatusUnset()\n        // setState(\"ERROR\");\n        break\n      case SagaStatus.DONE:\n        btradeMapStatusUnset()\n        break\n      default:\n        break\n    }\n  }, [btradeMapStatus])\n\n  React.useEffect(() => {\n    switch (investTokenTypeMapStatus) {\n      case SagaStatus.ERROR:\n        investTokenTypeMapStatusUnset()\n        // setState(\"ERROR\");\n        break\n      case SagaStatus.DONE:\n        investTokenTypeMapStatusUnset()\n        break\n      default:\n        break\n    }\n  }, [investTokenTypeMapStatus])\n\n  useAccountInit({ state })\n  useInjectWeb3Modal('MAIN')\n  return {\n    state,\n  }\n}\n"
  },
  {
    "path": "packages/webapp/src/hookAccountInit.ts",
    "content": "import React from 'react'\nimport {\n  AccountStatus,\n  SagaStatus,\n  SDK_ERROR_MAP_TO_UI,\n  UIERROR_CODE,\n} from '@loopring-web/common-resources'\nimport {\n  useWalletLayer1,\n  useWalletLayer2,\n  useAccount,\n  useUserRewards,\n  useConnect,\n  useWalletLayer2NFT,\n  useWalletL2NFTCollection,\n  useWalletL2Collection,\n  useVaultLayer2,\n  redPacketHistory,\n  offFaitService,\n  store,\n  useContacts,\n  useNotify,\n  useSocket,\n  useVaultTicker,\n  useTargetRedPackets,\n  useWalletLayer2Socket,\n} from '@loopring-web/core'\nimport { ToastType, useOpenModals } from '@loopring-web/component-lib'\n\nexport function useAccountInit({ state }: { state: keyof typeof SagaStatus }) {\n  useConnect({ state })\n  const { sendSocketTopic, socketUserEnd } = useSocket()\n  const {\n    getExclusiveRedpacket,\n    status: targetRedPacketStatus,\n    statusUnset: targetRedPacketUnset,\n  } = useTargetRedPackets()\n\n  const {\n    updateWalletLayer1,\n    status: walletLayer1Status,\n    statusUnset: wallet1statusUnset,\n  } = useWalletLayer1()\n\n  const {\n    updateVaultLayer2,\n    status: vaultLayer2Status,\n    statusUnset: vaultsLayer2Unset,\n  } = useVaultLayer2()\n  const { status: vaultTickerStatus, statusUnset: vaultTickerUnset } = useVaultTicker()\n\n  const {\n    resetLayer2NFT,\n    status: wallet2statusNFTStatus,\n    statusUnset: wallet2statusNFTUnset,\n  } = useWalletLayer2NFT()\n  const {\n    getUserRewards,\n    status: userRewardsStatus,\n    statusUnset: userRewardsUnset,\n  } = useUserRewards()\n  const {\n    updateWalletLayer2,\n    status: walletLayer2Status,\n    statusUnset: wallet2statusUnset,\n  } = useWalletLayer2()\n  const { updateContacts, status: contactsStatus, statusUnset: contactsUnset } = useContacts()\n  const { getUserNotify, restUserNotify } = useNotify()\n\n  const {\n    updateWalletL2Collection,\n    updateLegacyContracts,\n    resetL2Collection,\n    status: walletL2CollectionStatus,\n    statusUnset: walletL2CollectionstatusUnset,\n  } = useWalletL2Collection()\n\n  const {\n    updateWalletL2NFTCollection,\n    resetL2NFTCollection,\n    status: walletL2NFTCollectionStatus,\n    statusUnset: walletL2NFTCollectionstatusUnset,\n  } = useWalletL2NFTCollection()\n  const { clearRedPacketHash } = redPacketHistory.useRedPacketHistory()\n  const { account, status: accountStatus } = useAccount()\n  const { setShowGlobalToast } = useOpenModals()\n  React.useEffect(() => {\n    if (state === SagaStatus.DONE) {\n      offFaitService.banxaEnd()\n      const account = store.getState().account\n      switch (account.readyState) {\n        case AccountStatus.UN_CONNECT:\n        case AccountStatus.ERROR_NETWORK:\n          restUserNotify()\n          socketUserEnd()\n          break\n        case AccountStatus.DEPOSITING:\n        case AccountStatus.NOT_ACTIVE:\n        case AccountStatus.LOCKED:\n        case AccountStatus.NO_ACCOUNT:\n          if (walletLayer1Status !== SagaStatus.PENDING) {\n            updateWalletLayer1()\n          }\n          if (walletLayer2Status !== SagaStatus.PENDING) {\n            updateWalletLayer2()\n            resetLayer2NFT()\n            resetL2NFTCollection()\n            resetL2Collection()\n            restUserNotify()\n          }\n          socketUserEnd()\n          break\n        case AccountStatus.ACTIVATED:\n          clearRedPacketHash()\n          offFaitService.backendCheckStart()\n          if (walletLayer1Status !== SagaStatus.PENDING) {\n            updateWalletLayer1()\n          }\n          if (walletLayer2Status !== SagaStatus.PENDING) {\n            updateWalletLayer2()\n            updateWalletL2NFTCollection({ page: 1 })\n            updateWalletL2Collection({ page: 1 })\n          }\n          sendSocketTopic({})\n          getExclusiveRedpacket()\n          updateLegacyContracts()\n          updateContacts()\n          getUserNotify()\n          break\n      }\n    }\n  }, [accountStatus, state, account.readyState])\n  useWalletLayer2Socket({\n    walletLayer2Callback: () => {\n      const account = store.getState().account\n      if (account.readyState == AccountStatus.ACTIVATED) {\n        getUserRewards()\n      }\n    },\n  })\n  React.useEffect(() => {\n    switch (walletLayer1Status) {\n      case SagaStatus.ERROR:\n        wallet1statusUnset()\n        break\n      case SagaStatus.DONE:\n        wallet1statusUnset()\n        break\n      default:\n        break\n    }\n  }, [walletLayer1Status])\n  React.useEffect(() => {\n    switch (walletLayer2Status) {\n      case SagaStatus.ERROR:\n        wallet2statusUnset()\n        break\n      case SagaStatus.DONE:\n        wallet2statusUnset()\n        break\n      default:\n        break\n    }\n  }, [walletLayer2Status])\n  React.useEffect(() => {\n    switch (targetRedPacketStatus) {\n      case SagaStatus.ERROR:\n        targetRedPacketUnset()\n        break\n      case SagaStatus.DONE:\n        wallet2statusUnset()\n        break\n      default:\n        break\n    }\n  }, [targetRedPacketStatus])\n\n  React.useEffect(() => {\n    switch (vaultLayer2Status) {\n      case SagaStatus.ERROR:\n        vaultsLayer2Unset()\n        break\n      case SagaStatus.DONE:\n        vaultsLayer2Unset()\n        break\n      default:\n        break\n    }\n  }, [vaultLayer2Status])\n  React.useEffect(() => {\n    switch (vaultTickerStatus) {\n      case SagaStatus.ERROR:\n        vaultTickerUnset()\n        break\n      case SagaStatus.DONE:\n        vaultTickerUnset()\n        break\n      default:\n        break\n    }\n  }, [vaultTickerStatus])\n\n  React.useEffect(() => {\n    switch (walletL2CollectionStatus) {\n      case SagaStatus.ERROR:\n        walletL2CollectionstatusUnset()\n        break\n      case SagaStatus.DONE:\n        walletL2CollectionstatusUnset()\n        break\n      default:\n        break\n    }\n  }, [walletL2CollectionStatus])\n  React.useEffect(() => {\n    switch (walletL2NFTCollectionStatus) {\n      case SagaStatus.ERROR:\n        walletL2NFTCollectionstatusUnset()\n        break\n      case SagaStatus.DONE:\n        walletL2NFTCollectionstatusUnset()\n        break\n      default:\n        break\n    }\n  }, [walletL2NFTCollectionStatus])\n  React.useEffect(() => {\n    switch (wallet2statusNFTStatus) {\n      case SagaStatus.ERROR:\n        wallet2statusNFTUnset()\n        break\n      case SagaStatus.DONE:\n        wallet2statusNFTUnset()\n        break\n      default:\n        break\n    }\n  }, [wallet2statusNFTStatus])\n  React.useEffect(() => {\n    switch (userRewardsStatus) {\n      case SagaStatus.ERROR:\n        console.log('Network ERROR::', 'ammpoolAPI getAmmPoolUserRewards')\n        userRewardsUnset()\n        break\n      case SagaStatus.DONE:\n        userRewardsUnset()\n        break\n      default:\n        break\n    }\n  }, [userRewardsStatus])\n  React.useEffect(() => {\n    switch (contactsStatus) {\n      case SagaStatus.ERROR:\n        contactsUnset()\n        break\n      case SagaStatus.DONE:\n        contactsUnset()\n        break\n      default:\n        break\n    }\n  }, [contactsStatus])\n}\n"
  },
  {
    "path": "packages/webapp/src/index.tsx",
    "content": "import { Provider } from 'react-redux'\nimport { createRoot } from 'react-dom/client'\nimport App from './App'\nimport reportWebVitals from './reportWebVitals'\nimport { store, persistor, TimeoutCheckProvider, firebaseProps } from '@loopring-web/core'\nimport { getTheme, i18n } from '@loopring-web/common-resources'\nimport { ThemeProvider as MuThemeProvider } from '@mui/material'\nimport { LocalizationProvider } from '@mui/lab'\nimport MomentUtils from '@mui/lab/AdapterMoment'\n\nimport { ThemeProvider } from '@emotion/react'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { I18nextProvider } from 'react-i18next'\nimport { PersistGate } from 'redux-persist/integration/react'\nimport { provider, ProviderComposer, useSettings } from '@loopring-web/component-lib'\nimport React, { Provider as TProvider } from 'react'\nimport { ReactReduxFirebaseProvider } from 'react-redux-firebase'\nimport VConsole from 'vconsole'\n\nif (process.env.REACT_APP_VER) {\n  console.log('VER:', process.env.REACT_APP_VER)\n}\n// @ts-ignore\nwindow.global = window\nfunction onLongPress(element: any, callback: () => void) {\n  let timer: NodeJS.Timeout | -1 = -1\n\n  element.addEventListener('touchstart', () => {\n    timer = setTimeout(() => {\n      timer = -1\n      callback()\n    }, 3000)\n  })\n\n  function cancel() {\n    if (timer !== -1) {\n      clearTimeout(timer)\n    }\n  }\n\n  element.addEventListener('touchend', cancel)\n  element.addEventListener('touchmove', cancel)\n}\n\nconst ProviderApp = React.memo(({ children }: { children: JSX.Element }) => {\n  const providers: Array<[TProvider<any>, any]> = [\n    provider(Provider as any, { store }),\n    provider(LocalizationProvider as any, { dateAdapter: MomentUtils }),\n    provider(I18nextProvider as any, { i18n: i18n }),\n  ] as any\n  return <ProviderComposer providers={providers}>{children}</ProviderComposer>\n})\nconst isLaunch = { isLaunch: false }\nconst ProviderThen = React.memo(({ children }: { children: JSX.Element }) => {\n  const { themeMode, setIsMobile } = useSettings()\n  const isMobile = sdk.IsMobile.any() ? true : false\n  setIsMobile(isMobile)\n  if (isMobile) {\n    onLongPress(window.document.body, () => {\n      if (!isLaunch.isLaunch) {\n        isLaunch.isLaunch = true\n        const vConsole = new VConsole({})\n      }\n    })\n  }\n  const providers: Array<[TProvider<any>, any]> = [\n    provider(MuThemeProvider as any, { theme: getTheme(themeMode, isMobile) }),\n    provider(ThemeProvider as any, { theme: getTheme(themeMode, isMobile) }),\n    provider(PersistGate as any, { persistor, loading: null }),\n    provider(TimeoutCheckProvider as any),\n  ] as any\n  return <ProviderComposer providers={providers}>{children}</ProviderComposer>\n})\n\nconst root = createRoot(document.getElementById('root') as HTMLElement)\nroot.render(\n  <ProviderApp>\n    <ReactReduxFirebaseProvider {...firebaseProps}>\n      <ProviderThen>\n        <App />\n      </ProviderThen>\n    </ReactReduxFirebaseProvider>\n  </ProviderApp>,\n)\n\n// If you want to start measuring performance in your app, pass a function\n// to log results (for example: reportWebVitals(console.log))\n// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals\n\nif (process.env.NODE_ENV !== 'production') {\n  reportWebVitals(console.log)\n}\n"
  },
  {
    "path": "packages/webapp/src/layouts/footer/index.tsx",
    "content": "import React from 'react'\nimport { FOOTER_LIST_MAP, MEDIA_LIST, TOAST_TIME } from '@loopring-web/common-resources'\nimport { useLocation } from 'react-router-dom'\nimport { Footer as FooterUI, Toast, ToastType } from '@loopring-web/component-lib'\nimport _ from 'lodash'\nimport { useTranslation } from 'react-i18next'\n\nconst linkListMap = _.cloneDeep(FOOTER_LIST_MAP)\nconst mediaList = _.cloneDeep(MEDIA_LIST)\nexport const Footer = () => {\n  const location = useLocation()\n  const { t } = useTranslation()\n  const isLandingPage = location.pathname === '/' || location.pathname === '/pro'\n  const [showBeta, setShowBeta] = React.useState(\n    process.env?.REACT_APP_TEST_ENV == 'true' ? true : false,\n  )\n  // const isWallet = location.pathname === '/wallet'\n  React.useLayoutEffect(() => {\n    function updateSize() {\n      // setSize([1200, window.innerHeight - HeightConfig.headerHeight - HeightConfig.whiteHeight]);\n    }\n\n    window.addEventListener('resize', updateSize)\n    updateSize()\n    return () => window.removeEventListener('resize', updateSize)\n  }, [])\n  return (\n    <>\n      <Toast\n        alertText={t('errorBetaEnv', { ns: 'error' })}\n        open={showBeta}\n        autoHideDuration={TOAST_TIME}\n        onClose={() => {\n          setShowBeta(false)\n        }}\n        severity={ToastType.warning}\n      />\n      <FooterUI\n        isBeta={process.env?.REACT_APP_TEST_ENV == 'true'}\n        isLandingPage={isLandingPage}\n        linkListMap={linkListMap}\n        mediaList={mediaList}\n      />\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/webapp/src/layouts/header/hook.tsx",
    "content": "import React from 'react'\n\nimport {\n  ButtonComponentsMap,\n  fnType,\n  headerMenuDataMap,\n  headerMenuLandingData,\n  headerToolBarData as _initHeaderToolBarData,\n  headerToolBarDataMobile as _initHeaderToolBarDataMobile,\n  MapChainId,\n  Profile,\n  ProfileIndex,\n  SagaStatus,\n} from '@loopring-web/common-resources'\n\nimport {\n  accountReducer,\n  useAccount,\n  store,\n  useNotify,\n  accountStaticCallBack,\n  btnClickMap,\n  useSelectNetwork,\n  useNotificationFunc,\n  unlockAccount,\n  isCoinbaseSmartWallet,\n  useUpdateAccount,\n} from '@loopring-web/core'\n\nimport { AccountStep, useOpenModals, useSettings, useToggle } from '@loopring-web/component-lib'\nimport { myLog } from '@loopring-web/common-resources'\n\nimport _ from 'lodash'\nimport { useAppKit } from '@reown/appkit/react'\n\nexport const useHeader = () => {\n  const accountTotal = useAccount()\n  const { defaultNetwork, isMobile } = useSettings()\n  const { account, setShouldShow, status: accountStatus } = accountTotal\n  const { setShowAccount } = useOpenModals()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const profile = ProfileIndex[network]\n  const modal = useAppKit()\n\n  const _btnClickMap = Object.assign(_.cloneDeep(btnClickMap), {\n    [fnType.NO_ACCOUNT]: [\n      function () {\n        modal.open()\n      },\n    ],\n    [fnType.DEPOSITING]: [\n      function () {\n        modal.open()\n      },\n    ],\n    [fnType.NOT_ACTIVE]: [\n      function () {\n        modal.open()\n      },\n    ],\n    [fnType.ACTIVATED]: [\n      function () {\n        modal.open()\n      },\n    ],\n\n    [fnType.LOCKED]: [\n      function () {\n        modal.open()\n      },\n    ],\n  })\n\n  const onWalletBtnConnect = React.useCallback(async () => {\n    myLog(`onWalletBtnConnect click: ${account.readyState}`)\n    accountStaticCallBack(_btnClickMap, [])\n  }, [account, setShouldShow, _btnClickMap])\n  const { NetWorkItems } = useSelectNetwork({ className: 'header' })\n\n  const headerToolBarData = React.useMemo(() => {\n    const toolBarData = isMobile ? _initHeaderToolBarDataMobile : _initHeaderToolBarData\n    return [SagaStatus.UNSET, SagaStatus.DONE].includes(accountStatus)\n      ? {\n          ...toolBarData,\n          [ButtonComponentsMap.WalletConnect]: {\n            ...toolBarData[ButtonComponentsMap.WalletConnect],\n            handleClick: onWalletBtnConnect,\n            handleClickUnlock: async () => {\n              unlockAccount()\n            },\n            NetWorkItems,\n            accountState: { account },\n            handleClickSignIn: async () => {\n              setShowAccount({ isShow: true, step: AccountStep.CreateAccount_EOA_Only_Alert })\n            },\n          },\n          [ButtonComponentsMap.ProfileMenu]: {\n            ...toolBarData[ButtonComponentsMap.ProfileMenu],\n            subMenu: profile.map((item: string) => Profile[item]),\n            readyState: account.readyState,\n          },\n        }\n      : toolBarData\n  }, [accountStatus, account?.readyState, account, isMobile])\n\n  const { notifyMap, myNotifyMap } = useNotify()\n  const toggle = useToggle()\n  const showVault = toggle.toggle.VaultInvest.enable || toggle.toggle.isSupperUser\n  const headerMenuData = headerMenuDataMap[network].filter((menu) =>\n    showVault ? true : menu.label.id !== 'vault',\n  )\n  return {\n    headerToolBarData,\n    headerMenuData,\n    headerMenuLandingData,\n    account,\n    notifyMap,\n    myNotifyMap,\n  }\n}\n"
  },
  {
    "path": "packages/webapp/src/layouts/header/index.tsx",
    "content": "import {\n  ButtonComponentsMap,\n  CloseIcon,\n  headerRoot,\n  hexToRGB,\n} from '@loopring-web/common-resources'\n\nimport { Box, IconButton, Toolbar, Typography } from '@mui/material'\n\nimport { useHeader } from './hook'\nimport {\n  confirmation,\n  useSystem,\n  useAccount,\n  useTargetRedPackets,\n  useTokenMap,\n} from '@loopring-web/core'\nimport { withTranslation } from 'react-i18next'\n\nimport {\n  BottomRule,\n  Header as HeaderUI,\n  HideOnScroll,\n  RedPacketViewStep,\n  useOpenModals,\n  useSettings,\n} from '@loopring-web/component-lib'\nimport { withRouter, useLocation } from 'react-router-dom'\nimport { RouteComponentProps } from 'react-router'\nimport React from 'react'\n\nconst Header = withTranslation(['common', 'layout', 'landPage'])(\n  withRouter(\n    ({\n      t,\n      location,\n      isHideOnScroll = false,\n      isLandPage = false,\n      isWrap = false,\n      landBtn,\n      ...rest\n    }: any & RouteComponentProps) => {\n      const { headerToolBarData, headerMenuData, notifyMap, myNotifyMap, headerMenuLandingData } =\n        useHeader()\n      const { isMobile, coinJson } = useSettings()\n      const { pathname } = useLocation()\n      const { confirmWrapper } = confirmation.useConfirmation()\n      const { allowTrade, chainId } = useSystem()\n      const { account } = useAccount()\n      const [view, setView] = React.useState(false)\n      const { redPackets, setShowRedPacketsPopup } = useTargetRedPackets()\n      const popUpRedpackets = redPackets\n        ? redPackets.filter((redpacket) => (redpacket as any).notifyType === 'NOTIFY_WINDOW')\n        : []\n      const showExclusiveRedpacket = popUpRedpackets.length > 0\n      const exclusiveRedpacketCount = popUpRedpackets.length\n      const { setShowRedPacket, setShowTargetRedpacketPop } = useOpenModals()\n      const { idIndex } = useTokenMap()\n      const onClickExclusiveredPacket = () => {\n        if (exclusiveRedpacketCount > 1) {\n          setShowTargetRedpacketPop({\n            isShow: true,\n            info: {\n              exclusiveRedPackets: popUpRedpackets.map((redpacket) => {\n                return {\n                  ...redpacket,\n                  tokenName: redpacket.isNft\n                    ? redpacket.nftTokenInfo?.metadata?.base.name ?? ''\n                    : idIndex[redpacket.tokenId],\n                  tokenIcon: coinJson[idIndex[redpacket.tokenId ?? 0]],\n                }\n              }),\n            },\n          })\n        } else {\n          setShowRedPacket({\n            isShow: true,\n            info: {\n              ...popUpRedpackets[0],\n            },\n            step: RedPacketViewStep.OpenPanel,\n          })\n        }\n      }\n\n      return (\n        <>\n          {isHideOnScroll ? (\n            <HideOnScroll window={undefined}>\n              <HeaderUI\n                account={account}\n                isWrap={isLandPage || isWrap}\n                landBtn={landBtn}\n                chainId={chainId}\n                {...rest}\n                isLandPage={isLandPage}\n                isMobile={isMobile}\n                allowTrade={allowTrade}\n                headerMenuData={\n                  /(guardian)|(depositto)/gi.test(pathname) ? headerMenuLandingData : headerMenuData\n                }\n                className={isHideOnScroll ? 'scrollable' : ''}\n                toolBarMap={ButtonComponentsMap}\n                headerToolBarData={\n                  isLandPage\n                    ? isMobile\n                      ? []\n                      : [\n                          {\n                            buttonComponent: ButtonComponentsMap.ColorSwitch,\n                            label: 'labelColors',\n                          },\n                        ]\n                    : headerToolBarData\n                }\n                notification={{ notifyMap, myNotifyMap }}\n                selected={location.pathname === '/' ? headerRoot : location.pathname}\n                onClickExclusiveredPacket={onClickExclusiveredPacket}\n                showExclusiveRedpacket={showExclusiveRedpacket}\n                exclusiveRedpacketCount={exclusiveRedpacketCount}\n                application={'webapp'}\n              />\n            </HideOnScroll>\n          ) : (\n            <HeaderUI\n              {...rest}\n              account={account}\n              allowTrade={allowTrade}\n              isMobile={isMobile}\n              chainId={chainId}\n              headerMenuData={\n                /(guardian)|(depositto)/gi.test(pathname) ? headerMenuLandingData : headerMenuData\n              }\n              toolBarMap={ButtonComponentsMap}\n              headerToolBarData={headerToolBarData}\n              notification={{ notifyMap, myNotifyMap }}\n              selected={location.pathname === '/' ? headerRoot : location.pathname}\n              onClickExclusiveredPacket={onClickExclusiveredPacket}\n              showExclusiveRedpacket={showExclusiveRedpacket}\n              exclusiveRedpacketCount={exclusiveRedpacketCount}\n              application={'webapp'}\n            />\n          )}\n          <Toolbar id='back-to-top-anchor' />\n          {/* <BottomRule isShow={!confirmation?.confirmed} */}\n          <BottomRule\n            isShow={false}\n            content={t('labelAgreeLoopringTxt')}\n            btnTxt={t('labelCookiesAgree')}\n            clickToConfirm={() => confirmWrapper()}\n          />\n\n          <Box\n            display={view ? 'flex' : 'none'}\n            alignItems={'center'}\n            justifyContent={'center'}\n            position={'fixed'}\n            top={58}\n            right={0}\n            left={0}\n            sx={{ background: hexToRGB('#FBA95C', '0.8') }}\n            width={'100%'}\n          >\n            <Typography color={'white'} padding={2}></Typography>\n            <IconButton\n              size={'large'}\n              aria-label={t('labelClose')}\n              color={'inherit'}\n              onClick={(event) => {\n                setView(false)\n              }}\n            >\n              <CloseIcon htmlColor={'white'} />\n            </IconButton>\n          </Box>\n        </>\n      )\n    },\n  ),\n)\n\nexport default Header\n"
  },
  {
    "path": "packages/webapp/src/pages/AssetPage/AssetPanel/hook.ts",
    "content": "import React from 'react'\nimport {\n  LoopringAPI,\n  makeWalletLayer2,\n  store,\n  useAccount,\n  useBtnStatus,\n  useDefiMap,\n  useTokenMap,\n  useTokenPrices,\n  useWalletLayer2,\n  useWalletLayer2Socket,\n  volumeToCountAsBigNumber,\n  useSystem,\n  useConfig,\n  parseRabbitConfig,\n  useSocket,\n} from '@loopring-web/core'\nimport {\n  AccountStep,\n  AssetTitleProps,\n  TransactionTradeViews,\n  useOpenModals,\n  useSettings,\n} from '@loopring-web/component-lib'\nimport {\n  AccountStatus,\n  AssetsRawDataItem,\n  CurrencyToTag,\n  EmptyValueTag,\n  getValuePrecisionThousand,\n  globalSetup,\n  InvestAssetRouter,\n  MapChainId,\n  myLog,\n  PriceTag,\n  RecordTabIndex,\n  RouterPath,\n  SagaStatus,\n  SEND_TO_TAIKO_NETWORK_MAP,\n  TabOrderIndex,\n  TokenType,\n  TradeBtnStatus,\n  VaultKey,\n} from '@loopring-web/common-resources'\n\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport _ from 'lodash'\n\nexport type AssetPanelProps<R = AssetsRawDataItem> = {\n  assetsRawData: R[]\n  assetsRawMap: { [key: string]: R }\n  hideL2Assets: any\n  onSend: any\n  onReceive: any\n  marketArray: any\n  hideInvestToken: any\n  allowTrade: any\n  setHideL2Assets: (value: boolean) => void\n  setHideLpToken: any\n  setHideSmallBalances: any\n  themeMode: any\n  getTokenRelatedMarketArray: any\n  hideSmallBalances: any\n  assetBtnStatus: TradeBtnStatus\n}\nexport const useGetAssets = (): AssetPanelProps & {\n  assetTitleProps: any\n  assetTitleMobileExtendProps: any\n} => {\n  // const [assetsMap, setAssetsMap] = React.useState<{ [key: string]: any }>({})\n  const [{ assetsRawData, assetsRawMap }, setAssetsRawData] = React.useState<{\n    assetsRawData: AssetsRawDataItem[]\n    assetsRawMap: {\n      [key: string]: AssetsRawDataItem\n    }\n  }>({ assetsRawData: [], assetsRawMap: {} })\n  const [totalAsset, setTotalAsset] = React.useState<string>('0')\n  const { account } = useAccount()\n  const { allowTrade, chainId } = useSystem()\n  const { status: tokenPriceStatus } = useTokenPrices()\n  const { btnStatus: assetBtnStatus, enableBtn, setLoadingBtn } = useBtnStatus()\n  const { setShowAccount } = useOpenModals()\n  const {\n    themeMode,\n    currency,\n    hideL2Assets,\n    hideInvestToken,\n    hideSmallBalances,\n    setHideLpToken,\n    setHideSmallBalances,\n    setHideL2Assets,\n  } = useSettings()\n  const { status: walletL2Status } = useWalletLayer2()\n\n  const { marketArray } = useTokenMap()\n  const { marketCoins: defiCoinArray } = useDefiMap()\n  const getAssetsRawData = () => {\n    myLog('assetsRawData', 'getAssetsRawData')\n    const {\n      tokenPrices: { tokenPrices },\n      tokenMap: { tokenMap },\n      amm: {\n        ammMap: { ammMap },\n      },\n    } = store.getState()\n    const tokenPriceList = tokenPrices\n      ? Object.entries(tokenPrices).map((o) => ({\n          token: o[0],\n          detail: o[1],\n        }))\n      : []\n    const { walletMap } = makeWalletLayer2({ needFilterZero: false })\n\n    if (\n      tokenMap &&\n      !!Object.keys(tokenMap).length &&\n      !!Object.keys(walletMap ?? {}).length &&\n      !!tokenPriceList.length\n    ) {\n      let totalAssets = sdk.toBig(0)\n      let data = Object.keys(tokenMap ?? {}).reduce(\n        (pre, key, _index) => {\n          let item: any = undefined\n          const isDefi = [...(defiCoinArray ? defiCoinArray : [])].includes(key)\n          // tokenInfo\n          if (walletMap && walletMap[key]) {\n            let tokenInfo = {\n              token: key,\n              detail: walletMap[key],\n            }\n            let tokenValueDollar = sdk.toBig(0)\n            const withdrawAmount = volumeToCountAsBigNumber(\n              tokenInfo.token,\n              tokenInfo.detail?.detail?.pending?.withdraw ?? 0,\n            )\n            const depositAmount = volumeToCountAsBigNumber(\n              tokenInfo.token,\n              tokenInfo.detail?.detail?.pending?.deposit ?? 0,\n            )\n\n            const totalAmount = volumeToCountAsBigNumber(\n              tokenInfo.token,\n              tokenInfo.detail?.detail?.total ?? 0,\n            )\n              ?.plus(depositAmount || 0)\n              .plus(withdrawAmount || 0)\n            // ?.plus(depositAmount || 0)\n            // .plus(withdrawAmount || 0)\n            const price = tokenPrices?.[tokenInfo.token] || 0\n            if (totalAmount && price) {\n              tokenValueDollar = totalAmount?.times(price)\n            }\n            const isSmallBalance = tokenValueDollar.lt(1)\n            const lockedAmount = volumeToCountAsBigNumber(\n              tokenInfo.token,\n              tokenInfo.detail?.detail?.locked ?? 0,\n            )\n            const frozenAmount = lockedAmount?.plus(withdrawAmount || 0).plus(depositAmount || 0)\n            item = {\n              token: {\n                type: isDefi\n                  ? TokenType.defi\n                  : tokenInfo.token.split('-')[0] === 'LP'\n                  ? TokenType.lp\n                  : TokenType.single,\n                value: tokenInfo.token,\n              },\n              // amount: getThousandFormattedNumbers(volumeToCount(tokenInfo.token, tokenInfo.detail?.detail.total as string)) || EmptyValueTag,\n              amount: totalAmount?.toString() || EmptyValueTag,\n              // available: getThousandFormattedNumbers(Number(tokenInfo.detail?.count)) || EmptyValueTag,\n              available: Number(tokenInfo.detail?.count) || EmptyValueTag,\n              // locked: String(volumeToCountAsBigNumber(tokenInfo.token, tokenInfo.detail?.detail.locked)) || EmptyValueTag,\n              locked: frozenAmount?.toString() || EmptyValueTag,\n              smallBalance: isSmallBalance,\n              tokenValueDollar: tokenValueDollar.toString(),\n              name: tokenInfo.token,\n              withdrawAmount: withdrawAmount?.toString(),\n              depositAmount: depositAmount?.toString(),\n            }\n          } else {\n            item = {\n              token: {\n                type: isDefi\n                  ? TokenType.defi\n                  : key.split('-')[0] === 'LP'\n                  ? TokenType.lp\n                  : TokenType.single,\n                value: key,\n              },\n              amount: EmptyValueTag,\n              available: EmptyValueTag,\n              locked: 0,\n              smallBalance: true,\n              tokenValueDollar: 0,\n              name: key,\n              tokenValueYuan: 0,\n              withdrawAmount: 0,\n              depositAmount: 0,\n            }\n          }\n          if (item) {\n            const token = item.token.value\n            let precision = 0\n            if (token.split('-').length === 3 && ammMap) {\n              const rawList = token.split('-')\n              rawList.splice(0, 1, 'AMM')\n              const ammToken = rawList.join('-')\n              precision =\n                ammMap[ammToken]?.precisions?.amount ?? tokenMap[item.token.value]?.precision ?? 0\n            } else {\n              precision = tokenMap[item.token.value].precision\n            }\n            item.precision = precision\n            pre.assetsRawMap[key] = item\n            pre.assetsRawData.push(item)\n            totalAssets = totalAssets.plus(sdk.toBig(item.tokenValueDollar))\n            // totalAssets = totalAssets.plus(sdk.toBig(item.tokenValueDollar).times(forexMap[currency] ?? 0))\n          }\n          pre?.assetsRawData.sort((a, b) => {\n            const deltaDollar = b.tokenValueDollar - a.tokenValueDollar\n            const deltaAmount = sdk.toBig(b.amount).minus(a.amount).toNumber()\n            const deltaName = b.token.value < a.token.value ? 1 : -1\n            return deltaDollar !== 0 ? deltaDollar : deltaAmount !== 0 ? deltaAmount : deltaName\n          })\n          return pre\n        },\n        { assetsRawData: [], assetsRawMap: {} } as {\n          assetsRawData: AssetsRawDataItem[]\n          assetsRawMap: {\n            [key: string]: AssetsRawDataItem\n          }\n        },\n      )\n      setAssetsRawData(data)\n      setTotalAsset(totalAssets.toString())\n    }\n  }\n  const startWorker = _.debounce(getAssetsRawData, globalSetup.wait)\n  React.useEffect(() => {\n    if (account.readyState === AccountStatus.ACTIVATED) {\n      myLog('setLoadingBtn setLoadingBtn', assetBtnStatus)\n      setLoadingBtn()\n    }\n    return () => {\n      startWorker.cancel()\n    }\n  }, [account.readyState])\n  const { sendSocketTopic } = useSocket()\n  React.useEffect(() => {\n    if (\n      tokenPriceStatus === SagaStatus.UNSET &&\n      walletL2Status === SagaStatus.UNSET &&\n      assetsRawData.length &&\n      assetBtnStatus !== TradeBtnStatus.AVAILABLE\n    ) {\n      enableBtn()\n    }\n  }, [walletL2Status, assetsRawData, tokenPriceStatus, assetBtnStatus])\n  React.useEffect(() => {\n    setTotalAsset('0')\n  }, [account.accAddress, chainId])\n  React.useEffect(() => {\n    sendSocketTopic({\n      [sdk.WsTopicType.account]: true,\n    })\n  }, [])\n  const walletLayer2Callback = React.useCallback(() => {\n    startWorker()\n  }, [])\n  useWalletLayer2Socket({ walletLayer2Callback })\n  const getTokenRelatedMarketArray = React.useCallback((token: string) => {\n    const { marketArray, marketMap } = store.getState().tokenMap\n    if (!marketArray) return []\n    return marketArray.filter((market) => {\n      const marketInfo = marketMap?.[market]\n      if (!marketInfo?.enabled) return false\n      const [coinA, coinB] = market.split('-')\n      return token === coinA || token === coinB\n    })\n  }, [])\n\n  const onReceive = React.useCallback(\n    (token?: any) => {\n      setShowAccount({\n        isShow: true,\n        step: AccountStep.AddAssetGateway,\n        info: token ? { symbol: token } : undefined,\n      })\n    },\n    [setShowAccount],\n  )\n  const{fastWithdrawConfig}=useConfig()\n  const onSend = React.useCallback(\n    async (token?: any, isToL1?: boolean) => {\n      if (token) {\n        const {\n          settings: { defaultNetwork: network },\n          tokenMap: { idIndex },\n        } = store.getState()\n        const parsed = parseRabbitConfig(fastWithdrawConfig, MapChainId[network], idIndex)\n        const sendToTaikoSupportedTokens = parsed.toL1SupportedTokens\n        const hideSendToTaiko = !sendToTaikoSupportedTokens.includes(token)\n        setShowAccount({\n          isShow: true,\n          step: AccountStep.SendAssetGateway,\n          info: token || isToL1 ? { symbol: token, isToL1, hideSendToTaiko } : undefined,\n        })\n      } else {\n        setShowAccount({\n          isShow: true,\n          step: AccountStep.SendAssetGateway,\n          info: token || isToL1 ? { symbol: token, isToL1 } : undefined,\n        })\n      }\n      \n    },\n    [setShowAccount, fastWithdrawConfig],\n  )\n\n  const assetTitleProps: AssetTitleProps = {\n    setHideL2Assets,\n    assetInfo: {\n      totalAsset,\n      priceTag: PriceTag[CurrencyToTag[currency]],\n    },\n    accountId: account.accountId,\n    hideL2Assets,\n    onShowReceive: onReceive,\n    onShowSend: onSend,\n  } as any\n  const assetTitleMobileExtendProps = {\n    btnShowNFTDepositStatus: TradeBtnStatus.AVAILABLE,\n    btnShowNFTMINTStatus: TradeBtnStatus.AVAILABLE,\n  }\n\n  return {\n    assetTitleProps,\n    assetTitleMobileExtendProps,\n    assetsRawData,\n    assetBtnStatus,\n    hideL2Assets,\n    onSend,\n    onReceive,\n    marketArray,\n    hideInvestToken,\n    allowTrade,\n    setHideL2Assets,\n    setHideLpToken,\n    assetsRawMap,\n    setHideSmallBalances,\n    themeMode,\n    getTokenRelatedMarketArray,\n    hideSmallBalances,\n  }\n}\nexport const useAssetAction = () => {\n  const [tokenLockDetail, setTokenLockDetail] = React.useState<\n    | undefined\n    | {\n        list: any[]\n        row: any\n      }\n  >(undefined)\n  const onTokenLockHold = async (_item) => {\n    setTokenLockDetail(undefined)\n    const {\n      account,\n      tokenMap: { tokenMap },\n    } = store.getState()\n    if (LoopringAPI.userAPI && account.accountId) {\n      const response = await LoopringAPI.userAPI.getUserLockSummary(\n        {\n          accountId: account.accountId,\n          tokenId: tokenMap[_item.name].tokenId,\n          // @ts-ignore\n          lockTags: [\n            sdk.LOCK_TYPE.DUAL_CURRENCY,\n            sdk.LOCK_TYPE.DUAL_BASE,\n            sdk.LOCK_TYPE.BTRADE,\n            sdk.LOCK_TYPE.L2STAKING,\n            sdk.LOCK_TYPE.STOP_LIMIT,\n            sdk.LOCK_TYPE.VAULT_COLLATERAL,\n          ].join(','),\n        } as any,\n        account.apiKey,\n      )\n\n      if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n      } else {\n        setTokenLockDetail(() => {\n          // @ts-ignore\n          const sum: { key: string; value: string; link: string }[] = response.lockRecord.reduce(\n            // @ts-ignore\n            (prev, record) => {\n              const amount = sdk\n                .toBig(record.amount)\n                .div('1e' + tokenMap[_item.name].decimals)\n                .toString()\n              prev[0] = {\n                ...prev[0],\n                value: sdk.toBig(prev[0].value?.replaceAll(sdk.SEP, '')).minus(amount).toString(),\n              }\n              let link = ''\n              switch (record.lockTag) {\n                case sdk.LOCK_TYPE.DUAL_CURRENCY:\n                  link = `/#${RouterPath.investBalance}/${InvestAssetRouter.DUAL}`\n                  break\n                case sdk.LOCK_TYPE.DUAL_BASE:\n                  link = `/#${RouterPath.investBalance}/${InvestAssetRouter.DUAL}`\n                  break\n                case sdk.LOCK_TYPE.L2STAKING:\n                  link = `/#${RouterPath.investBalance}/${InvestAssetRouter.STAKELRC}`\n                  break\n                case sdk.LOCK_TYPE.BTRADE:\n                  link = `/#${RouterPath.l2records}/${RecordTabIndex.BtradeSwapRecords}`\n                  break\n                case sdk.LOCK_TYPE.STOP_LIMIT:\n                  link = `/#${RouterPath.l2records}/${RecordTabIndex.Orders}/${TabOrderIndex.orderOpenTable}`\n                  break\n                case sdk.LOCK_TYPE.VAULT_COLLATERAL:\n                  link = `/#${RouterPath.vault}/${VaultKey.VAULT_DASHBOARD}`\n                  break\n              }\n\n              prev.push({\n                key: `label${record.lockTag}`,\n                value: getValuePrecisionThousand(\n                  amount,\n                  tokenMap[_item.name].precision,\n                  tokenMap[_item.name].precision,\n                  undefined,\n                ),\n                link,\n              })\n              return prev\n            },\n            [\n              {\n                key: `labelMarketOrderUnfilled`,\n                value: sdk\n                  .toBig(_item.locked ?? '0')\n                  .minus(_item?.withdrawAmount ?? 0)\n                  .minus(_item?.depositAmount ?? 0)\n                  .toString(),\n                link: `/#${RouterPath.l2records}/${RecordTabIndex.Orders}/${TabOrderIndex.orderOpenTable}`,\n              },\n              ...(sdk.toBig(_item?.depositAmount ?? 0).gt(0)\n                ? [\n                    {\n                      key: `labelDepositPending`,\n                      value: sdk.toBig(_item?.depositAmount ?? '0').toString(),\n                      link: `/#${RouterPath.l2records}/${RecordTabIndex.Transactions}/?types=${TransactionTradeViews.receive}&searchValue=${_item.name}`,\n                    },\n                  ]\n                : []),\n              ...(sdk.toBig(_item?.withdrawAmount ?? 0).gt(0)\n                ? [\n                    {\n                      key: `labelWithDrawPending`,\n                      value: sdk.toBig(_item?.withdrawAmount ?? '0').toString(),\n                      link: `/#${RouterPath.l2records}/${RecordTabIndex.Transactions}/?types=${TransactionTradeViews.send}&searchValue=${_item.name}`,\n                    },\n                  ]\n                : []),\n            ] as { key: string; value: string; link: string }[],\n          )\n          if (_item.locked && sdk.toBig(sum[0].value).gt(0)) {\n            sum[0] = {\n              ...sum[0],\n              value: getValuePrecisionThousand(\n                sum[0].value,\n                tokenMap[_item.name].precision,\n                tokenMap[_item.name].precision,\n                undefined,\n              ),\n            }\n          } else {\n            sum.shift()\n          }\n\n          return {\n            list: sum,\n            row: _item,\n          }\n        })\n      }\n    }\n  }\n  return {\n    tokenLockDetail,\n    onTokenLockHold,\n  }\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/AssetPage/AssetPanel/index.tsx",
    "content": "import { WithTranslation, withTranslation } from 'react-i18next'\n\nimport { Box, Tab, Tabs } from '@mui/material'\nimport styled from '@emotion/styled'\nimport { AssetsTable, AssetTitle, AssetTitleProps, useSettings } from '@loopring-web/component-lib'\n\nimport { StylePaper, useSystem, useTokenMap } from '@loopring-web/core'\nimport { AssetPanelProps, useAssetAction } from './hook'\nimport React from 'react'\nimport { useHistory, useRouteMatch } from 'react-router-dom'\nimport { MyLiquidity } from '../../InvestPage/MyLiquidityPanel'\nimport { RedPacketClaimPanel } from '../../RedPacketPage/RedPacketClaimPanel'\nimport {\n  AssetL2TabIndex,\n  AssetTabIndex,\n  CircleIcon,\n  MapChainId,\n  RouterPath,\n  TradeBtnStatus,\n} from '@loopring-web/common-resources'\nimport RewardsPanel from '../RewardsPanel'\n\nconst StyleTitlePaper = styled(Box)`\n  width: 100%;\n  background: var(--color-box-third);\n  border-radius: ${({ theme }) => theme.unit}px;\n`\nexport const l2assetsRouter = `${RouterPath.l2assets}/:assets?/:item?`\n\nexport const AssetPanel = withTranslation('common')(\n  ({\n    t,\n    assetTitleProps,\n    assetPanelProps: {\n      assetsRawData,\n      getTokenRelatedMarketArray,\n      onSend,\n      assetBtnStatus,\n      onReceive,\n      hideInvestToken,\n      hideSmallBalances,\n      allowTrade,\n      setHideLpToken,\n      setHideSmallBalances,\n      // onTokenLockHold,\n      // tokenLockDetail,\n    },\n    showRedpacketReddot,\n    ...rest\n  }: {\n    showRedpacketReddot: boolean\n    assetTitleProps: AssetTitleProps\n    assetPanelProps: AssetPanelProps\n  } & WithTranslation) => {\n    const container = React.useRef(null)\n    const { disableWithdrawList } = useTokenMap()\n    const { forexMap } = useSystem()\n    const { isMobile, defaultNetwork } = useSettings()\n    const match: any = useRouteMatch(l2assetsRouter)\n    const [currentTab, setCurrentTab] = React.useState<AssetTabIndex>(AssetTabIndex.Tokens)\n    const history = useHistory()\n    const { onTokenLockHold, tokenLockDetail } = useAssetAction()\n\n    const handleTabChange = (value: AssetTabIndex) => {\n      if (AssetL2TabIndex[MapChainId[defaultNetwork]]?.includes(value)) {\n        switch (value) {\n          case AssetTabIndex.Invests:\n            history.replace(`${RouterPath.l2assetsDetail}/${AssetTabIndex.Invests}`)\n            setCurrentTab(AssetTabIndex.Invests)\n            break\n          case AssetTabIndex.RedPacket:\n            history.replace(`${RouterPath.l2assetsDetail}/${AssetTabIndex.RedPacket}`)\n            setCurrentTab(AssetTabIndex.RedPacket)\n            break\n          case AssetTabIndex.Rewards:\n            history.replace(`${RouterPath.l2assetsDetail}/${AssetTabIndex.Rewards}`)\n            setCurrentTab(AssetTabIndex.Rewards)\n            break\n          case AssetTabIndex.Tokens:\n          default:\n            history.replace(`${RouterPath.l2assetsDetail}/${AssetTabIndex.Tokens}`)\n            setCurrentTab(AssetTabIndex.Tokens)\n            break\n        }\n      } else {\n        history.replace(`${RouterPath.l2assetsDetail}/${AssetTabIndex.Tokens}`)\n        setCurrentTab(AssetTabIndex.Tokens)\n      }\n    }\n    React.useEffect(() => {\n      handleTabChange(match?.params?.item)\n    }, [match?.params?.item, defaultNetwork])\n    const hideAssets = assetTitleProps.hideL2Assets\n    return (\n      <>\n        {!isMobile && (\n          <StyleTitlePaper paddingX={3} paddingY={5 / 2}>\n            <AssetTitle\n              {...{\n                t,\n                ...rest,\n                ...assetTitleProps,\n                assetBtnStatus,\n                forexMap,\n              }}\n            />\n          </StyleTitlePaper>\n        )}\n\n        <Tabs\n          value={currentTab}\n          onChange={(_event, value) => handleTabChange(value)}\n          aria-label='l2-history-tabs'\n          variant='scrollable'\n        >\n          {AssetL2TabIndex[MapChainId[defaultNetwork]]?.map((item: string) => {\n            if (item == AssetTabIndex.RedPacket) {\n              if (isMobile) {\n                return <React.Fragment key={item.toString()} />\n              } else {\n                return (\n                  <Tab\n                    key={item.toString()}\n                    label={\n                      <>\n                        {t(`labelAsset${item}`)}\n                        {showRedpacketReddot && (\n                          <CircleIcon\n                            sx={{\n                              position: 'absolute',\n                              top: 2,\n                              right: -0,\n                              pointerEvents: 'none' as any,\n                            }}\n                            className={'noteit'}\n                            fontSize={'large'}\n                            htmlColor={'var(--color-error)'}\n                          />\n                        )}\n                      </>\n                    }\n                    value={item}\n                  />\n                )\n              }\n            } else {\n              return <Tab key={item.toString()} label={t(`labelAsset${item}`)} value={item} />\n            }\n          })}\n        </Tabs>\n        {currentTab === AssetTabIndex.Tokens && (\n          <StylePaper marginTop={1} marginBottom={2} ref={container}>\n            <Box className='tableWrapper table-divide-short'>\n              <AssetsTable\n                {...{\n                  rawData: assetsRawData,\n                  disableWithdrawList,\n                  showFilter: true,\n                  allowTrade,\n                  onSend,\n                  onTokenLockHold: onTokenLockHold as any,\n                  tokenLockDetail,\n                  onReceive,\n                  isLoading: assetBtnStatus === TradeBtnStatus.LOADING,\n                  getMarketArrayListCallback: getTokenRelatedMarketArray,\n                  hideInvestToken,\n                  forexMap: forexMap as any,\n                  hideSmallBalances,\n                  setHideLpToken,\n                  setHideSmallBalances,\n                  hideAssets,\n                  ...rest,\n                }}\n              />\n            </Box>\n          </StylePaper>\n        )}\n        {currentTab === AssetTabIndex.Rewards && <RewardsPanel hideAssets={hideAssets} />}\n        {currentTab === AssetTabIndex.Invests && (\n          <MyLiquidity\n            noHeader\n            path={`${RouterPath.l2assets}/assets/Invests`}\n            className={'assetWrap'}\n            isHideTotal={true}\n            hideAssets={hideAssets}\n          />\n        )}\n        {!isMobile && currentTab === AssetTabIndex.RedPacket && (\n          <RedPacketClaimPanel hideAssets={hideAssets} />\n        )}\n      </>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/webapp/src/pages/AssetPage/HistoryPanel/hooks.ts",
    "content": "import React from 'react'\nimport {\n  fiatNumberDisplay,\n  LoopringAPI,\n  makeDualOrderedItem,\n  numberFormat,\n  numberFormatThousandthPlace,\n  numberStringListSum,\n  store,\n  tradeItemToTableDataItem,\n  useAccount,\n  useDefiMap,\n  useDualMap,\n  useSystem,\n  useTokenMap,\n  useTokenPrices,\n  useVaultMap,\n  useWalletLayer2,\n  volumeToCount,\n  volumeToCountAsBigNumber,\n} from '@loopring-web/core'\nimport {\n  AccountStep,\n  AmmSideTypes,\n  BtradeSwapsType,\n  OrderHistoryRawDataItem,\n  OrderHistoryTableDetailItem,\n  RawDataAmmItem,\n  RawDataBtradeSwapsItem,\n  RawDataDualAssetItem,\n  RawDataDualTxsItem,\n  RawDataTradeItem,\n  RawDataTransactionItem,\n  RawDataVaultTxItem,\n  ToastType,\n  TransactionStatus,\n  useOpenModals,\n  useSettings,\n  VaultRecordType,\n} from '@loopring-web/component-lib'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport {\n  AccountStatus,\n  BTRDE_PRE,\n  DEFI_CONFIG,\n  getValuePrecisionThousand,\n  LEVERAGE_ETH_CONFIG,\n  MapChainId,\n  SagaStatus,\n  SDK_ERROR_MAP_TO_UI,\n  TradeStatus,\n  TradeTypes,\n  RouterPath,\n  RecordTabIndex,\n  EmptyValueTag,\n  DirectionTag,\n  PriceTag,\n  CurrencyToTag,\n  myLog,\n} from '@loopring-web/common-resources'\nimport { TFunction, useTranslation } from 'react-i18next'\nimport BigNumber from 'bignumber.js'\nimport { useHistory, useLocation, useRouteMatch } from 'react-router-dom'\nimport { useDualAsset } from './useDualAsset'\nimport { isEmpty } from 'lodash'\nimport { number } from 'prop-types'\nimport { utils } from 'ethers'\nimport Decimal from 'decimal.js'\n\nexport type TxsFilterProps = {\n  // accountId: number;\n  tokenSymbol?: string\n  start?: number\n  end?: number\n  offset?: number\n  limit?: number\n  types?: sdk.UserTxTypes[] | string\n}\n\nenum TxTypeAMM {\n  Add = 'join_pool',\n  Remove = 'exit_pool',\n}\n\nexport function useGetTxs(setToastOpen: (state: any) => void) {\n  const {\n    account: { accountId, apiKey },\n  } = useAccount()\n  const { search } = useLocation()\n  const searchParams = new URLSearchParams(search)\n  const { tokenMap } = store.getState().tokenMap\n  const { t } = useTranslation(['error'])\n  const [txs, setTxs] = React.useState<RawDataTransactionItem[]>([])\n  const [txsTotal, setTxsTotal] = React.useState(0)\n  const [showLoading, setShowLoading] = React.useState(false)\n\n  const getTxnStatus = (status: string) =>\n    status === ''\n      ? TransactionStatus.processing\n      : status === 'processed'\n      ? TransactionStatus.processed\n      : status === 'processing'\n      ? TransactionStatus.processing\n      : status === 'received'\n      ? TransactionStatus.received\n      : TransactionStatus.failed\n\n  const getUserTxnList = React.useCallback(\n    async ({ tokenSymbol, start, end, limit, offset, types }: TxsFilterProps) => {\n      if (LoopringAPI && LoopringAPI.userAPI && accountId && apiKey) {\n        setShowLoading(true)\n        const response = await LoopringAPI.userAPI.getUserTxs(\n          {\n            accountId,\n            limit,\n            tokenSymbol,\n            start,\n            end,\n            offset,\n            types,\n          },\n          apiKey,\n        )\n        if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n          const errorItem = SDK_ERROR_MAP_TO_UI[(response as sdk.RESULT_INFO)?.code ?? 700001]\n          setToastOpen({\n            open: true,\n            type: ToastType.error,\n            content:\n              'error : ' + errorItem\n                ? t(errorItem.messageKey)\n                : (response as sdk.RESULT_INFO).message,\n          })\n        } else {\n          const formattedList: RawDataTransactionItem[] = response.userTxs.map((order) => {\n            const feePrecision = tokenMap ? tokenMap[order.feeTokenSymbol]?.precision : undefined\n            return {\n              ...order,\n              side: order.txType as any,\n              amount: {\n                unit: order.symbol || '',\n                value: Number(volumeToCount(order.symbol, order.amount)),\n              },\n              fee: {\n                unit: order.feeTokenSymbol || '',\n                value: Number(volumeToCountAsBigNumber(order.feeTokenSymbol, order.feeAmount || 0)),\n              },\n              memo: order.memo || '',\n              time: order.timestamp,\n              txnHash: order.hash,\n              status: getTxnStatus(order.status),\n              feePrecision: feePrecision,\n            } as RawDataTransactionItem\n          })\n          setTxs(formattedList)\n          setTxsTotal(response.totalNum)\n          setShowLoading(false)\n        }\n      }\n    },\n    [accountId, apiKey, setToastOpen, t, tokenMap],\n  )\n\n  return {\n    txs,\n    txsTotal,\n    searchValue: searchParams?.get('searchValue'),\n    showLoading,\n    getUserTxnList,\n  }\n}\n\nexport function useGetTrades(setToastOpen: (state: any) => void) {\n  const [userTrades, setUserTrades] = React.useState<RawDataTradeItem[]>([])\n  const [userTradesTotal, setUserTradesTotal] = React.useState(0)\n  const [showLoading, setShowLoading] = React.useState(true)\n  const [page, setPage] = React.useState(1)\n  const {\n    account: { accountId, apiKey },\n  } = useAccount()\n\n  const tokenMap = store.getState().tokenMap.tokenMap\n  const { t } = useTranslation(['error'])\n\n  const getUserTradeList = React.useCallback(\n    async ({\n      market,\n      orderHash,\n      page = 1,\n      pageSize,\n      fromId,\n      fillTypes,\n    }: {\n      market?: string\n      page?: number\n      total?: number\n      pageSize: number\n      // offset: (page - 1) * pageSize,\n      // limit: pageSize,\n      fromId?: any\n      orderHash?: any\n      fillTypes?: any\n    }) => {\n      if (LoopringAPI && LoopringAPI.userAPI && accountId && apiKey && tokenMap) {\n        setShowLoading(true)\n        setPage(page)\n        const response = await LoopringAPI.userAPI.getUserTrades(\n          {\n            accountId,\n            market,\n            orderHash,\n            offset: (page - 1) * pageSize,\n            limit: pageSize,\n            fromId,\n            fillTypes,\n          },\n          apiKey,\n        )\n        if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n          const errorItem = SDK_ERROR_MAP_TO_UI[(response as sdk.RESULT_INFO)?.code ?? 700001]\n          setToastOpen({\n            open: true,\n            type: ToastType.error,\n            content:\n              'error : ' + errorItem\n                ? t(errorItem.messageKey)\n                : (response as sdk.RESULT_INFO).message,\n          })\n        } else {\n          setUserTrades(\n            response.userTrades.map((o) => {\n              return tradeItemToTableDataItem(o) as RawDataTradeItem\n            }),\n          )\n          setUserTradesTotal(response.totalNum)\n        }\n        setShowLoading(false)\n      }\n    },\n    [accountId, apiKey, setToastOpen, t, tokenMap],\n  )\n\n  return {\n    userTrades,\n    userTradesTotal,\n    getUserTradeList,\n    showLoading,\n    page,\n  }\n}\n\nexport function useGetAmmRecord(setToastOpen: (props: any) => void) {\n  const [ammRecordList, setAmmRecordList] = React.useState<RawDataAmmItem[]>([])\n  const { t } = useTranslation(['error'])\n  const [ammRecordTotal, setAmmRecordTotal] = React.useState(0)\n  const [showLoading, setShowLoading] = React.useState(true)\n  const { accountId, apiKey } = store.getState().account\n  const { tokenMap, idIndex } = useTokenMap()\n  const getAmmpoolList = React.useCallback(\n    async ({ tokenSymbol, start, end, txTypes, offset, limit }: any) => {\n      const ammPoolAddress = tokenMap[tokenSymbol]?.address\n      setShowLoading(true)\n      if (LoopringAPI.ammpoolAPI && accountId && apiKey) {\n        const response = await LoopringAPI.ammpoolAPI.getUserAmmPoolTxs(\n          {\n            accountId,\n            txTypes: txTypes ? TxTypeAMM[txTypes] : '',\n            offset,\n            start,\n            end,\n            limit,\n            ammPoolAddress,\n          },\n          apiKey,\n        )\n        if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n          const errorItem = SDK_ERROR_MAP_TO_UI[(response as sdk.RESULT_INFO)?.code ?? 700001]\n          setToastOpen({\n            open: true,\n            type: ToastType.error,\n            content:\n              'error : ' + errorItem\n                ? t(errorItem.messageKey)\n                : (response as sdk.RESULT_INFO).message,\n          })\n        } else {\n          const result = response.userAmmPoolTxs.map((order) => ({\n            side: order.txType === sdk.AmmTxType.JOIN ? AmmSideTypes.Join : AmmSideTypes.Exit,\n            amount: {\n              from: {\n                key: idIndex[order.poolTokens[0]?.tokenId],\n                value: String(\n                  volumeToCount(\n                    idIndex[order.poolTokens[0]?.tokenId],\n                    order.poolTokens[0]?.actualAmount,\n                  ),\n                ),\n              },\n              to: {\n                key: idIndex[order.poolTokens[1]?.tokenId],\n                value: String(\n                  volumeToCount(\n                    idIndex[order.poolTokens[1]?.tokenId],\n                    order.poolTokens[1]?.actualAmount,\n                  ),\n                ),\n              },\n            },\n            lpTokenAmount: String(\n              volumeToCount(idIndex[order.lpToken?.tokenId], order.lpToken?.actualAmount),\n            ),\n            fee: {\n              key: idIndex[order.poolTokens[1]?.tokenId],\n              value: volumeToCount(\n                idIndex[order.poolTokens[1]?.tokenId],\n                order.poolTokens[1]?.feeAmount,\n              )?.toFixed(6),\n            },\n            time: order.updatedAt,\n          }))\n          setAmmRecordList(result)\n          setShowLoading(false)\n          setAmmRecordTotal(response.totalNum)\n        }\n      }\n      setShowLoading(false)\n    },\n    [accountId, apiKey, idIndex, setToastOpen, t, tokenMap],\n  )\n\n  return {\n    ammRecordList,\n    showLoading,\n    getAmmpoolList,\n    ammRecordTotal,\n  }\n}\n\nexport function useGetDefiRecord(setToastOpen: (props: any) => void) {\n  const { t } = useTranslation(['error'])\n  const [defiList, setDefiRecordList] = React.useState<sdk.UserDefiTxsHistory[]>([])\n  const [defiTotal, setDefiTotal] = React.useState(0)\n  const [showLoading, setShowLoading] = React.useState(true)\n  const { accountId, apiKey } = store.getState().account\n\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n\n  const getDefiTxList = React.useCallback(\n    async ({ start, end, offset, limit }: any) => {\n      setShowLoading(true)\n      if (LoopringAPI.defiAPI && accountId && apiKey) {\n        const markets = DEFI_CONFIG.MARKETS[network]\n        const response = await LoopringAPI.defiAPI.getDefiTransaction(\n          {\n            accountId,\n            offset,\n            start,\n            end,\n            limit,\n            markets: markets.join(','),\n          } as any,\n          apiKey,\n        )\n        if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n          const errorItem = SDK_ERROR_MAP_TO_UI[(response as sdk.RESULT_INFO)?.code ?? 700001]\n          setToastOpen({\n            open: true,\n            type: ToastType.error,\n            content:\n              'error : ' + errorItem\n                ? t(errorItem.messageKey)\n                : (response as sdk.RESULT_INFO).message,\n          })\n        } else {\n          // @ts-ignore\n          const result = (response as any).userDefiTxs\n          setDefiRecordList(result)\n          setShowLoading(false)\n          setDefiTotal((response as any).totalNum)\n        }\n      }\n      setShowLoading(false)\n    },\n    [accountId, apiKey, setToastOpen, t, network],\n  )\n\n  return {\n    defiList,\n    showLoading,\n    getDefiTxList,\n    defiTotal,\n  }\n}\n\nexport function useDefiSideRecord(setToastOpen: (props: any) => void) {\n  const { t } = useTranslation(['error'])\n  const { tokenMap } = useTokenMap()\n  const [sideStakingList, setSideStakingRecordList] = React.useState<sdk.STACKING_TRANSACTIONS[]>(\n    [],\n  )\n  const [sideStakingTotal, setSideStakingTotal] = React.useState(0)\n  const [showLoading, setShowLoading] = React.useState(true)\n  const { accountId, apiKey } = store.getState().account\n  const getSideStakingTxList = React.useCallback(\n    async ({ start, end, offset, limit }: any) => {\n      setShowLoading(true)\n      if (LoopringAPI.defiAPI && accountId && apiKey) {\n        const response = await LoopringAPI.defiAPI.getStakeTransactions(\n          {\n            accountId,\n            tokenId: tokenMap['LRC'].tokenId,\n            start,\n            end,\n            limit,\n            offset,\n          } as any,\n          apiKey,\n        )\n        if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n          const errorItem = SDK_ERROR_MAP_TO_UI[(response as sdk.RESULT_INFO)?.code ?? 700001]\n          setToastOpen({\n            open: true,\n            type: ToastType.error,\n            content:\n              'error : ' + errorItem\n                ? t(errorItem.messageKey)\n                : (response as sdk.RESULT_INFO).message,\n          })\n        } else {\n          const result = response.list\n          setSideStakingRecordList(result)\n          setShowLoading(false)\n          setSideStakingTotal(response.totalNum)\n          // }\n        }\n      }\n      setShowLoading(false)\n    },\n    [accountId, apiKey, setToastOpen, t, tokenMap],\n  )\n\n  return {\n    sideStakingList,\n    showLoading,\n    getSideStakingTxList,\n    sideStakingTotal,\n  }\n}\n\nexport const useOrderList = ({\n  setToastOpen,\n  isStopLimit = false,\n  isOrderBookScroll = false,\n}: {\n  isStopLimit?: boolean\n  setToastOpen?: (props: any) => void\n  isOrderBookScroll?: boolean\n}) => {\n  const { t } = useTranslation(['error'])\n  const [orderOriginalData, setOrderOriginalData] = React.useState<OrderHistoryRawDataItem[]>([])\n  const [orderDetailList, setOrderDetailList] = React.useState<OrderHistoryTableDetailItem[]>([])\n  const [totalNum, setTotalNum] = React.useState(0)\n  const [showLoading, setShowLoading] = React.useState(false)\n  const [showDetailLoading, setShowDetailLoading] = React.useState(false)\n  const {\n    account: { accountId, apiKey, readyState },\n  } = useAccount()\n  const {\n    tokenMap: { marketArray, tokenMap, marketMap },\n  } = store.getState()\n  const {\n    ammMap: { ammMap },\n  } = store.getState().amm\n  const { sk: privateKey } = store.getState().account.eddsaKey\n\n  const { status, updateWalletLayer2 } = useWalletLayer2()\n\n  const ammPairList = ammMap ? Object.keys(ammMap) : []\n  const jointPairs = (marketArray || []).concat(ammPairList)\n\n  const getOrderList = React.useCallback(\n    async ({\n      isScroll,\n      ...props\n    }: Omit<sdk.GetOrdersRequest, 'accountId'> & {\n      isScroll?: boolean\n      extraOrderTypes?: string\n    }) => {\n      setShowLoading(true)\n      if (LoopringAPI && LoopringAPI.userAPI && accountId && apiKey) {\n        const userOrders = await LoopringAPI.userAPI.getOrders(\n          {\n            ...props,\n            accountId,\n            extraOrderTypes: isStopLimit ? 'STOP_LIMIT' : 'TRADITIONAL_ORDER',\n          },\n          apiKey,\n        )\n        if ((userOrders as sdk.RESULT_INFO).code || (userOrders as sdk.RESULT_INFO).message) {\n          const errorItem = SDK_ERROR_MAP_TO_UI[(userOrders as sdk.RESULT_INFO)?.code ?? 700001]\n          if (setToastOpen) {\n            setToastOpen({\n              open: true,\n              type: ToastType.error,\n              content:\n                'error : ' + errorItem\n                  ? t(errorItem.messageKey)\n                  : (userOrders as sdk.RESULT_INFO).message,\n            })\n          }\n        } else {\n          if (userOrders && Array.isArray(userOrders.orders)) {\n            setTotalNum(userOrders.totalNum)\n            const data = userOrders.orders.map((order) => {\n              const { baseAmount, quoteAmount, baseFilled, quoteFilled } = order.volumes\n              const marketList = order.market.split('-')\n              if (marketList.length === 3) {\n                marketList.shift()\n              }\n              // due to AMM case, we cannot use first index\n              const side = order.side === sdk.Side.Buy ? TradeTypes.Buy : TradeTypes.Sell\n              const isBuy = side === TradeTypes.Buy\n              const [tokenFirst, tokenLast] = marketList\n              const baseToken = isBuy ? tokenLast : tokenFirst\n              const quoteToken = isBuy ? tokenFirst : tokenLast\n              const actualBaseFilled = (isBuy ? quoteFilled : baseFilled) as any\n              const actualQuoteFilled = (isBuy ? baseFilled : quoteFilled) as any\n              const baseValue = isBuy\n                ? volumeToCount(baseToken, quoteAmount)\n                : volumeToCount(baseToken, baseAmount)\n              const quoteValue = isBuy\n                ? volumeToCount(quoteToken, baseAmount)\n                : (volumeToCount(baseToken, baseAmount) || 0) * Number(order.price || 0)\n              const baseVolume = volumeToCountAsBigNumber(baseToken, actualBaseFilled)\n              const quoteVolume = volumeToCountAsBigNumber(quoteToken, actualQuoteFilled)\n              const quotefilledValue = volumeToCount(quoteToken, actualQuoteFilled)\n\n              const average = isBuy\n                ? baseVolume?.div(quoteVolume || new BigNumber(1)).toNumber() || 0\n                : quoteVolume?.div(baseVolume || new BigNumber(1)).toNumber() || 0\n              const completion = (quotefilledValue || 0) / (quoteValue || 1)\n\n              const precisionFrom = tokenMap\n                ? (tokenMap as any)[baseToken]?.precisionForOrder\n                : undefined\n              const precisionTo = tokenMap\n                ? (tokenMap as any)[quoteToken]?.precisionForOrder\n                : undefined\n              const precisionMarket = marketMap\n                ? marketMap[order.market]?.precisionForPrice\n                : undefined\n\n              return {\n                market: order.market,\n                side: order.side === 'BUY' ? TradeTypes.Buy : TradeTypes.Sell,\n                orderType: order.orderType,\n                amount: {\n                  from: {\n                    key: baseToken,\n                    value: baseValue as any,\n                    precision: precisionFrom,\n                  },\n                  to: {\n                    key: quoteToken,\n                    value: quoteValue as any,\n                    precision: precisionTo,\n                  },\n                },\n                average: average,\n                price: {\n                  key: quoteToken,\n                  value: Number(order.price),\n                },\n                time: order.validity.start * 1000,\n                status: order.status as unknown as TradeStatus,\n                hash: order.hash,\n                orderId: order.clientOrderId,\n                tradeChannel: order.tradeChannel,\n                completion: completion,\n                precisionMarket: precisionMarket,\n                // @ts-ignore\n                extraOrderInfo: order.extraOrderInfo,\n                __raw__: order,\n              }\n            })\n            if (isScroll) {\n              setOrderOriginalData((_data) => {\n                return [..._data, ...data]\n              })\n            } else {\n              setOrderOriginalData(data)\n            }\n          }\n        }\n      }\n      setShowLoading(false)\n    },\n    [accountId, apiKey, isStopLimit, setToastOpen, t, tokenMap, marketMap],\n  )\n\n  React.useEffect(() => {\n    ;(async () => {\n      if (status === SagaStatus.UNSET && isOrderBookScroll) {\n        getOrderList({\n          limit: 50,\n          status: ['processing'],\n        })\n      }\n    })()\n  }, [isOrderBookScroll, getOrderList, status])\n\n  const clearOrderDetail = React.useCallback(() => {\n    setOrderDetailList([])\n  }, [])\n\n  const isAtBottom = React.useCallback(\n    ({ currentTarget }: React.UIEvent<HTMLDivElement>): boolean => {\n      return currentTarget.scrollTop + 10 >= currentTarget.scrollHeight - currentTarget.clientHeight\n    },\n    [],\n  )\n\n  const handleScroll = React.useCallback(\n    async (event: React.UIEvent<HTMLDivElement>, isOpen: boolean = false) => {\n      if (!isAtBottom(event) || (event.target as any)?.scrollTop === 0) return\n      getOrderList({\n        isScroll: true,\n        offset: orderOriginalData.length,\n        status: isOpen\n          ? ['processing']\n          : ['processed', 'failed', 'cancelled', 'cancelling', 'expired'],\n        extraOrderTypes: isStopLimit ? 'STOP_LIMIT' : 'TRADITIONAL_ORDER',\n      })\n    },\n    [getOrderList, isAtBottom, orderOriginalData, isStopLimit],\n  )\n\n  const cancelOrder = React.useCallback(\n    async ({ orderHash, clientOrderId }: any) => {\n      if (LoopringAPI && LoopringAPI.userAPI && accountId && privateKey && apiKey) {\n        await LoopringAPI.userAPI.cancelOrder(\n          {\n            accountId,\n            orderHash,\n            clientOrderId,\n          },\n          privateKey,\n          apiKey,\n        )\n        updateWalletLayer2()\n      }\n    },\n    [accountId, apiKey, privateKey, updateWalletLayer2],\n  )\n\n  const cancelOrderByHashList = React.useCallback(\n    async (orderHashList: string) => {\n      if (LoopringAPI && LoopringAPI.userAPI && accountId && privateKey && apiKey) {\n        await LoopringAPI.userAPI.cancelMultiOrdersByHash(\n          {\n            accountId,\n            orderHash: orderHashList,\n          },\n          privateKey,\n          apiKey,\n        )\n        updateWalletLayer2()\n      }\n    },\n    [accountId, apiKey, privateKey, updateWalletLayer2],\n  )\n\n  const getOrderDetail = React.useCallback(\n    async (orderHash: string, t: TFunction) => {\n      if (LoopringAPI && LoopringAPI.userAPI && accountId && apiKey) {\n        setShowDetailLoading(true)\n        const response = await LoopringAPI.userAPI.getOrderDetails(\n          {\n            accountId,\n            orderHash,\n          },\n          apiKey,\n        )\n        const formattedData = [response.orderDetail].map((order: any) => {\n          const { baseAmount, quoteAmount, baseFilled, quoteFilled, fee } = order.volumes\n          const marketList = order.market.split('-')\n          if (marketList.length === 3) {\n            marketList.shift()\n          }\n          // due to AMM case, we cannot use first index\n          const side = order.side === sdk.Side.Buy ? TradeTypes.Buy : TradeTypes.Sell\n          const isBuy = side === TradeTypes.Buy\n          const role = isBuy ? t('labelOrderDetailMaker') : t('labelOrderDetailTaker')\n          const [tokenFirst, tokenLast] = marketList\n          const baseToken = isBuy ? tokenLast : tokenFirst\n          const quoteToken = isBuy ? tokenFirst : tokenLast\n          const baseValue = isBuy\n            ? volumeToCount(baseToken, quoteAmount)\n            : volumeToCount(baseToken, baseAmount)\n          const quoteValue = isBuy\n            ? volumeToCount(quoteToken, baseAmount)\n            : (volumeToCount(baseToken, baseAmount) || 0) * Number(order.price || 0)\n          const actualBaseFilled = isBuy ? quoteFilled : baseFilled\n          const actualQuoteFilled = isBuy ? baseFilled : quoteFilled\n          const baseVolume = volumeToCountAsBigNumber(baseToken, actualBaseFilled)\n          const quoteVolume = volumeToCountAsBigNumber(quoteToken, actualQuoteFilled)\n          const filledPrice = baseVolume?.div(quoteVolume || new BigNumber(1)).toNumber() || 0\n          const feeValue = volumeToCountAsBigNumber(quoteToken, fee)?.toNumber() || 0\n\n          const precisionFrom = tokenMap\n            ? (tokenMap as any)[baseToken]?.precisionForOrder\n            : undefined\n          const precisionTo = tokenMap\n            ? (tokenMap as any)[quoteToken]?.precisionForOrder\n            : undefined\n          const precisionMarket = marketMap ? marketMap[order.market]?.precisionForPrice : undefined\n          const precisionFee = tokenMap\n            ? (tokenMap as any)[quoteToken]?.precisionForOrder\n            : undefined\n\n          return {\n            amount: {\n              from: {\n                key: baseToken,\n                value: baseValue as any,\n                precision: precisionFrom,\n              },\n              to: {\n                key: quoteToken,\n                value: quoteValue as any,\n                precision: precisionTo,\n              },\n            },\n            filledPrice: {\n              value: filledPrice,\n              precision: precisionMarket,\n            },\n            fee: {\n              key: quoteToken,\n              value: feeValue,\n              precision: precisionFee,\n            },\n            role: role,\n            time: order.validity.start * 1000,\n            volume: quoteVolume?.toNumber(),\n            orderId: order.clientOrderId,\n            extraOrderInfo: order.extraOrderInfo,\n            __raw__: order,\n          }\n        })\n        setOrderDetailList(formattedData)\n        setShowDetailLoading(false)\n      }\n    },\n    [accountId, apiKey, marketMap, tokenMap],\n  )\n\n  const clearData = React.useCallback(() => {\n    setOrderOriginalData([])\n  }, [])\n\n  React.useEffect(() => {\n    if (readyState !== AccountStatus.ACTIVATED) {\n      clearData()\n    }\n  }, [status, readyState, clearData])\n\n  return {\n    marketArray: jointPairs,\n    getOrderList,\n    setOrderOriginalData,\n    rawData: orderOriginalData,\n    clearRawData: clearData,\n    totalNum,\n    showLoading,\n    showDetailLoading,\n    getOrderDetail,\n    orderDetailList,\n    cancelOrder,\n    handleScroll,\n    clearOrderDetail,\n    cancelOrderByHashList,\n  }\n}\n\nexport const useDualTransaction = <R extends RawDataDualTxsItem>(\n  setToastOpen: (props: any) => void,\n  path = RouterPath.l2records,\n) => {\n  const { t } = useTranslation(['error'])\n  const match: any = useRouteMatch(`${path}/:tab/`)\n  const { search } = useLocation()\n  const searchParams = new URLSearchParams(search)\n  const history = useHistory()\n  const {\n    account: { accountId, apiKey },\n  } = useAccount()\n  const {\n    refresh: refreshDualDetail,\n    detail: dualDetail,\n    open: openDualDetail,\n    setOpen: setDualOpen,\n  } = useDualAsset()\n  const onClose = () => {\n    searchParams.delete('show')\n    history.replace({\n      pathname: `${path}/${RecordTabIndex.DualRecords}`,\n      search: searchParams.toString(),\n    })\n    setDualOpen(false)\n  }\n  const [dualList, setDualList] = React.useState<R[]>([])\n  const { idIndex } = useTokenMap()\n  const [dualTotal, setDualTotal] = React.useState(0)\n  const { marketMap: dualMarketMap } = useDualMap()\n  const [showLoading, setShowLoading] = React.useState(true)\n\n  const getDualTxList = React.useCallback(\n    async ({ start, end, offset, settlementStatus, investmentStatus, dualTypes, limit }: any) => {\n      setShowLoading(true)\n      if (\n        searchParams?.get('show') == 'detail' &&\n        match?.params?.tab == RecordTabIndex.DualRecords &&\n        searchParams?.has('hash')\n      ) {\n        let hash = searchParams.get('hash')\n        refreshDualDetail(hash ?? '', true)\n      }\n      if (LoopringAPI.defiAPI && accountId && apiKey) {\n        const response = await LoopringAPI.defiAPI.getDualTransactions(\n          {\n            dualTypes,\n            accountId,\n            settlementStatus,\n            investmentStatus,\n            offset,\n            limit,\n            start,\n            end,\n          } as any,\n          apiKey,\n        )\n        if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n          const errorItem = SDK_ERROR_MAP_TO_UI[(response as sdk.RESULT_INFO)?.code ?? 700001]\n          if (setToastOpen) {\n            setToastOpen({\n              open: true,\n              type: ToastType.error,\n              content:\n                'error : ' + errorItem\n                  ? t(errorItem.messageKey)\n                  : (response as sdk.RESULT_INFO).message,\n            })\n          }\n        } else {\n          // @ts-ignore\n          let result = (response as any)?.userDualTxs.reduce(\n            (prev: RawDataDualAssetItem[], item: sdk.UserDualTxsHistory) => {\n              const [, , coinA, coinB] =\n                (item.tokenInfoOrigin.market ?? 'dual-').match(/(dual-)?(\\w+)-(\\w+)/i) ?? []\n\n              let [sellTokenSymbol, buyTokenSymbol] =\n                item.dualType === sdk.DUAL_TYPE.DUAL_BASE\n                  ? [\n                      coinA ?? idIndex[item.tokenInfoOrigin.tokenIn],\n                      coinB ?? idIndex[item.tokenInfoOrigin.tokenOut],\n                    ]\n                  : [\n                      coinB ?? idIndex[item.tokenInfoOrigin.tokenIn],\n                      coinA ?? idIndex[item.tokenInfoOrigin.tokenOut],\n                    ]\n              prev.push({\n                ...makeDualOrderedItem(\n                  item,\n                  sellTokenSymbol,\n                  buyTokenSymbol,\n                  0,\n                  dualMarketMap[item.tokenInfoOrigin.market],\n                ),\n                amount: item.tokenInfoOrigin.amountIn,\n              })\n              return prev\n            },\n            [] as RawDataDualAssetItem[],\n          )\n\n          setDualList(result)\n          setShowLoading(false)\n          setDualTotal((response as any).totalNum)\n          // setDualPagination({\n          //   pageSize: limit,\n          //   total: (response as any).totalNum,\n          // });\n        }\n      }\n      setShowLoading(false)\n    },\n    [accountId, apiKey, setToastOpen, t, idIndex, dualMarketMap],\n  )\n\n  return {\n    refreshDualDetail,\n    dualDetail,\n    openDualDetail,\n    onDualClose: onClose,\n    // page,\n    dualList,\n    showLoading,\n    getDualTxList,\n    dualTotal,\n    dualMarketMap,\n  }\n}\n\nexport const useBtradeTransaction = <R extends RawDataBtradeSwapsItem>(\n  setToastOpen: (props: any) => void,\n) => {\n  const { t } = useTranslation(['error'])\n  const [btradeOrderData, setBtradeOrderData] = React.useState<R[]>([])\n  const [totalNum, setTotalNum] = React.useState(0)\n  const [showLoading, setShowLoading] = React.useState(false)\n  const {\n    account: { accountId, apiKey },\n  } = useAccount()\n  const { tokenMap } = useTokenMap()\n  const { setShowAccount } = useOpenModals()\n  const { chainId, baseURL} = useSystem()\n\n  const getBtradeOrderList = React.useCallback(\n    async (props: Omit<sdk.GetOrdersRequest, 'accountId'>) => {\n      \n      if (chainId && baseURL && accountId && apiKey) {\n        const defiAPI = new sdk.DefiAPI({\n          chainId: chainId as sdk.ChainId,\n          baseUrl: baseURL\n        })\n        setShowLoading(true)\n        const userOrders = await defiAPI.getBtradeOrders({\n          request: { accountId, limit: props.limit, offset: props.offset },\n          apiKey,\n        })\n        if ((userOrders as sdk.RESULT_INFO).code || (userOrders as sdk.RESULT_INFO).message) {\n          const errorItem = SDK_ERROR_MAP_TO_UI[(userOrders as sdk.RESULT_INFO)?.code ?? 700001]\n          if (setToastOpen) {\n            setToastOpen({\n              open: true,\n              type: ToastType.error,\n              content:\n                'error : ' + errorItem\n                  ? t(errorItem.messageKey)\n                  : (userOrders as sdk.RESULT_INFO).message,\n            })\n          }\n        } else {\n          if (userOrders && Array.isArray(userOrders.list)) {\n            setTotalNum(userOrders.totalNum)\n            const data = userOrders.list.map((item: any) => {\n              const {\n                status,\n                market,\n                price,\n                // btradeExtraInfo: tokenInfos,\n                volumes: { fee, baseAmount, baseFilled, quoteAmount, quoteFilled },\n                validity: { start },\n                side,\n                baseSettled,\n                quoteSettled,\n              } = item\n              //@ts-ignore\n              const [, baseTokenSymbol, quoteTokenSymbol] = market\n                .replace(BTRDE_PRE, '')\n                .match(/(\\w+)-(\\w+)/i)\n              let amountIn,\n                amountOut,\n                fromSymbol,\n                toSymbol,\n                amountFOut,\n                _price,\n                amountFIn,\n                settledIn,\n                settledOut\n\n              if (side === sdk.Side.Sell) {\n                fromSymbol = baseTokenSymbol\n                toSymbol = quoteTokenSymbol\n                amountFIn = baseFilled\n                amountFOut = quoteFilled\n                amountIn = baseAmount\n                amountOut = quoteAmount\n                settledIn = baseSettled\n                settledOut = quoteSettled\n                _price = {\n                  from: baseTokenSymbol,\n                  key: quoteTokenSymbol,\n                  value: getValuePrecisionThousand(\n                    price,\n                    tokenMap[quoteTokenSymbol].precision,\n                    tokenMap[quoteTokenSymbol].precision,\n                    undefined,\n                  ),\n                }\n              } else {\n                toSymbol = baseTokenSymbol\n                fromSymbol = quoteTokenSymbol\n                amountFOut = baseFilled\n                amountFIn = quoteFilled\n                amountOut = baseAmount\n                amountIn = quoteAmount\n                settledOut = baseSettled\n                settledIn = quoteSettled\n                _price = {\n                  from: baseTokenSymbol,\n                  key: quoteTokenSymbol,\n                  value: getValuePrecisionThousand(\n                    price,\n                    tokenMap[quoteTokenSymbol].precision,\n                    tokenMap[quoteTokenSymbol].precision,\n                    undefined,\n                  ),\n                }\n              }\n\n              const fromToken = tokenMap[fromSymbol]\n              const toToken = tokenMap[toSymbol]\n\n              const fromAmount = sdk.toBig(amountIn).div('1e' + fromToken.decimals)\n              const fromFAmount = sdk.toBig(amountFIn).div('1e' + fromToken.decimals)\n              const settledFromAmount = sdk.toBig(settledIn).div('1e' + fromToken.decimals)\n              const toAmount = sdk.toBig(amountOut).div('1e' + toToken.decimals)\n              const toFAmount = sdk.toBig(amountFOut).div('1e' + toToken.decimals)\n              const settledToAmount = sdk.toBig(settledOut).div('1e' + toToken.decimals)\n              const fromAmountDisplay = getValuePrecisionThousand(\n                sdk.toBig(amountIn).div('1e' + fromToken.decimals),\n                undefined,\n                fromToken.precision,\n                fromToken.precision,\n                false,\n              )\n\n              const toAmountDisplay = getValuePrecisionThousand(\n                sdk.toBig(amountOut).div('1e' + toToken.decimals),\n                undefined,\n                toToken.precision,\n                toToken.precision,\n                false,\n              )\n\n              const feeAmount =\n                fee && fee != 0\n                  ? getValuePrecisionThousand(\n                      sdk.toBig(fee ?? 0).div('1e' + toToken.decimals),\n                      toToken.precision,\n                      toToken.precision,\n                      undefined,\n                    )\n                  : undefined\n              const feeSymbol = toSymbol\n\n              let type\n              switch (status) {\n                case 'processed':\n                  type = BtradeSwapsType.Settled\n                  break\n                case 'failed':\n                case 'cancelled':\n                  type = BtradeSwapsType.Failed\n                  break\n                case 'filled':\n                  type = BtradeSwapsType.Delivering\n                  break\n                case 'processing':\n                default:\n                  type = BtradeSwapsType.Pending\n                  break\n              }\n              return {\n                type,\n                price: _price,\n                fromAmount,\n                fromSymbol,\n                toAmount,\n                fromFAmount,\n                toFAmount,\n                settledFromAmount,\n                settledToAmount,\n                fromAmountDisplay,\n                toAmountDisplay,\n                toSymbol,\n                time: Number(start + '000'),\n                rawData: item,\n                feeSymbol,\n                feeAmount,\n                filledPercent: sdk.toBig(amountFIn).div(amountIn).times(100).toFormat(2),\n              }\n            }, [])\n            setBtradeOrderData(data)\n          }\n        }\n        setShowLoading(false)\n      }\n    },\n    [accountId, apiKey, setToastOpen, t, tokenMap, baseURL, chainId],\n  )\n\n  return {\n    getBtradeOrderList,\n    btradeOrderData,\n    onDetail: (item: R) => {\n      const info = {\n        sellToken: tokenMap[item.fromSymbol],\n        buyToken: tokenMap[item.toSymbol],\n        sellFStr: item.fromFAmount && item.fromFAmount !== '0' ? item.fromFAmount : undefined,\n        sellStr: item.fromAmount,\n        buyFStr: item.toFAmount && item.toFAmount !== '0' ? item.toFAmount : undefined,\n        buyStr: item.toAmount,\n        convertStr: `1 ${item.price.from} \\u2248 ${item.price.value} ${item.price.key}`,\n        // @ts-ignore\n        feeStr: item?.feeAmount == 0 ? undefined : item?.feeAmount,\n        settledToAmount: item.settledToAmount,\n        settledFromAmount: item.settledFromAmount,\n        time: item?.time ?? undefined,\n        placedAmount:\n          tokenMap && item.fromSymbol && item.fromAmount && sdk.toBig(item.fromAmount).gt(0)\n            ? `${getValuePrecisionThousand(\n                sdk.toBig(item.fromAmount),\n                undefined,\n                undefined,\n                tokenMap[item.fromSymbol].precision,\n                false,\n                { isAbbreviate: true },\n              )} ${item.fromSymbol}`\n            : EmptyValueTag,\n        executedAmount:\n          tokenMap && item.fromSymbol && item.settledFromAmount && sdk.toBig(item.settledFromAmount).gt(0)\n            ? `${getValuePrecisionThousand(\n                sdk.toBig(item.settledFromAmount),\n                undefined,\n                undefined,\n                tokenMap[item.fromSymbol].precision,\n                false,\n                { isAbbreviate: true },\n              )} ${item.fromSymbol}`\n            : EmptyValueTag,\n        executedRate:\n          tokenMap && item.fromSymbol && item.settledFromAmount && item.fromAmount && sdk.toBig(item.fromAmount).gt(0)\n            ? `${sdk\n                .toBig(item.settledFromAmount)\n                .div(item.fromAmount)\n                .multipliedBy('100')\n                .toFixed(2)}%`\n            : EmptyValueTag,\n        convertedAmount:\n          tokenMap && item.toSymbol && item.settledToAmount && sdk.toBig(item.settledToAmount).gt(0)\n            ? `${getValuePrecisionThousand(\n                sdk.toBig(item.settledToAmount),\n                undefined,\n                undefined,\n                tokenMap[item.toSymbol].precision,\n                false,\n                { isAbbreviate: true },\n              )} ${item.toSymbol}`\n            : EmptyValueTag,\n        settledAmount:\n          tokenMap && item.toSymbol && item.settledToAmount && item.feeAmount && sdk.toBig(item.settledToAmount).gt(0)\n            ? `${getValuePrecisionThousand(\n                sdk.toBig(item.settledToAmount).minus(item.feeAmount),\n                undefined,\n                undefined,\n                tokenMap[item.toSymbol].precision,\n                false,\n                { isAbbreviate: true },\n              )} ${item.toSymbol}`\n            : EmptyValueTag,\n      }\n      switch (item.type) {\n        case BtradeSwapsType.Delivering:\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.BtradeSwap_Delivering,\n            info: {\n              ...info,\n              isDelivering: true,\n            },\n          })\n          break\n\n        case BtradeSwapsType.Settled:\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.BtradeSwap_Settled,\n            info,\n          })\n          break\n        case BtradeSwapsType.Cancelled:\n        case BtradeSwapsType.Failed:\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.BtradeSwap_Failed,\n            info,\n          })\n          break\n        case BtradeSwapsType.Pending:\n        default:\n          setShowAccount({\n            isShow: true,\n            step: AccountStep.BtradeSwap_Pending,\n            info,\n          })\n          break\n      }\n    },\n    totalNum,\n    showLoading,\n  }\n}\n\nexport function useGetLeverageETHRecord(setToastOpen: (props: any) => void) {\n  const { t } = useTranslation(['error'])\n  const [leverageETHList, setLeverageETHRecordList] = React.useState<sdk.UserDefiTxsHistory[]>([])\n  const [leverageETHTotal, setLeverageETHTotal] = React.useState(0)\n  const [showLoading, setShowLoading] = React.useState(true)\n  const { marketLeverageArray } = useDefiMap()\n  const { accountId, apiKey } = store.getState().account\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const getLeverageETHTxList = React.useCallback(\n    async ({ start, end, offset, limit }: any) => {\n      setShowLoading(true)\n      if (LoopringAPI.defiAPI && accountId && apiKey) {\n        const types = LEVERAGE_ETH_CONFIG.types[network]\n        const response = await LoopringAPI.defiAPI.getDefiTransaction(\n          {\n            accountId,\n            offset,\n            start,\n            end,\n            limit,\n            types: types.join(','),\n          } as any,\n          apiKey,\n        )\n        if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n          const errorItem = SDK_ERROR_MAP_TO_UI[(response as sdk.RESULT_INFO)?.code ?? 700001]\n          setToastOpen({\n            open: true,\n            type: ToastType.error,\n            content:\n              'error : ' + errorItem\n                ? t(errorItem.messageKey)\n                : (response as sdk.RESULT_INFO).message,\n          })\n        } else {\n          // @ts-ignore\n          const result = (response as any).userDefiTxs\n          setLeverageETHRecordList(result)\n          setShowLoading(false)\n          setLeverageETHTotal((response as any).totalNum)\n        }\n      }\n      setShowLoading(false)\n    },\n    [accountId, apiKey, setToastOpen, t, network],\n  )\n\n  return {\n    leverageETHList,\n    showLoading,\n    getLeverageETHTxList,\n    leverageETHTotal,\n  }\n}\n\nexport const useVaultTransaction = <R extends RawDataVaultTxItem>(\n  setToastOpen: (props: any) => void,\n) => {\n  const { t } = useTranslation(['common', 'error'])\n  const { t: t2 } = useTranslation(['tables'])\n  const [vaultOrderData, setVaultOrderData] = React.useState<R[]>([])\n  const [totalNum, setTotalNum] = React.useState(0)\n  const [showLoading, setShowLoading] = React.useState(false)\n  const {\n    account: { accountId, apiKey },\n  } = useAccount()\n  const { currency, coinJson } = useSettings()\n  const { forexMap, getValueInCurrency } = useSystem()\n  const { tokenMap: vaultTokenMap, idIndex: vaultIdIndex, erc20Map, tokenPrices: vaultTokenPrices } = useVaultMap()\n  const { tokenMap, idIndex } = useTokenMap()\n  \n  // const { tokenPrices } = useTokenPrices()\n  const { setShowAccount } = useOpenModals()\n  const getVaultOrderList = React.useCallback(\n    async (\n      props: Omit<\n        {\n          operateTypes: string\n          offset: number\n          start?: number\n          end?: number\n          limit: number\n        },\n        'accountId'\n      >,\n    ) => {\n      if (LoopringAPI && LoopringAPI.vaultAPI && accountId && apiKey) {\n        setShowLoading(true)\n        const response = await LoopringAPI.vaultAPI.getVaultGetOperationHistory(\n          {\n            accountId,\n            limit: props.limit ?? 20,\n            offset: props.offset ?? 0,\n            operateTypes:\n              props?.operateTypes ??\n              [\n                0, 1, 2, 3, 4, 5, 6, 7, 8\n              ].join(','),\n          },\n          apiKey,\n          '1'\n        )\n        if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n          const errorItem = SDK_ERROR_MAP_TO_UI[(response as sdk.RESULT_INFO)?.code ?? 700001]\n          if (setToastOpen) {\n            setToastOpen({\n              open: true,\n              type: ToastType.error,\n              content:\n                'error : ' + errorItem\n                  ? t(errorItem.messageKey)\n                  : (response as sdk.RESULT_INFO).message,\n            })\n          }\n        } else {\n          const { list, totalNum } = response as any\n          if (list && Array.isArray(list) && vaultIdIndex && !isEmpty(vaultIdIndex)) {\n            setTotalNum(totalNum)\n            const data = list.map(\n              ({ operation, order }: { operation: sdk.VaultOperation; order: sdk.VaultOrder }) => {\n                const {\n                  operateSubType,\n                  operateType,\n                  status,\n                  amountIn: amountS,\n                  tokenIn: tokenS,\n                  tokenOut: tokenB,\n                  amountOut: amountB,\n                } = operation\n                let fillAmountB, fillAmountS\n                const { fee, price } = order ?? {}\n                // const { fillAmountS, amountS, tokenS, tokenB, amountB, fillAmountB, price } = order\n                let type,\n                  mainContentRender,\n                  erc20Symbol,\n                  erc20SymbolB,\n                  vSymbol,\n                  precision,\n                  precisionB,\n                  vToken,\n                  fillAmount,\n                  amount,\n                  vTokenB,\n                  tokenBSymbol,\n                  vSymbolB,\n                  symbolB,\n                  percentage,\n                  fillAmountSStr,\n                  fillAmountBStr,\n                  feeStr,\n                  feeToken\n                switch (operateType) {\n                  case sdk.VaultOperationType.VAULT_OPEN_POSITION:\n                  case sdk.VaultOperationType.VAULT_MARGIN_CALL:\n                  case sdk.VaultOperationType.VAULT_JOIN_REDEEM:\n                    type =\n                      sdk.VaultOperationType.VAULT_OPEN_POSITION == operateType\n                        ? VaultRecordType.open\n                        : sdk.VaultOperationType.VAULT_JOIN_REDEEM == operateType\n                        ? VaultRecordType.redeem\n                        : VaultRecordType.margin\n                    //@ts-ignore\n                    const erc20Token = tokenMap[idIndex[tokenS ?? '']]\n                    precision = vToken?.precision\n                    //@ts-ignore\n                    vToken = vaultTokenMap[vaultIdIndex[erc20Map[erc20Token.symbol]?.vaultTokenId]]\n                    vSymbol = vToken.symbol\n                    erc20Symbol = vToken.symbol.slice(2)\n                    amount = sdk.toBig(amountS ?? 0).div('1e' + vToken.decimals)\n                    fillAmountS =\n                      status == sdk.VaultOperationStatus.VAULT_STATUS_SUCCEED ? amountS : 0\n                    fillAmount = sdk.toBig(fillAmountS).div('1e' + vToken.decimals)\n                    percentage = sdk.VaultOperationStatus.VAULT_STATUS_SUCCEED ? 100 : 0\n                    // const amountStr = !amount.eq(0)\n                    //   ? getValuePrecisionThousand(amount, precision, precision)\n                    //   : EmptyValueTag\n                    mainContentRender = !amount.eq(0) ? `${ numberFormatThousandthPlace(new Decimal(amount.toString()).abs().toString()) } ${erc20Symbol}` : EmptyValueTag\n                    break\n                  case sdk.VaultOperationType.VAULT_BORROW:\n                    type = VaultRecordType.borrow\n                    //@ts-ignore\n                    vToken = vaultTokenMap[vaultIdIndex[tokenB ?? '']] ?? {}\n                    erc20Symbol = vToken?.symbol.slice(2)\n                    precision = vToken.precision\n                    vSymbol = vToken?.symbol\n                    amount = sdk.toBig(amountB ?? 0).div('1e' + vToken.decimals)\n                    fillAmountB =\n                      status == sdk.VaultOperationStatus.VAULT_STATUS_SUCCEED ? amountB : 0\n                    fillAmount = sdk.toBig(fillAmountB).div('1e' + vToken.decimals)\n                    percentage = sdk\n                      .toBig(fillAmountB ?? 0)\n                      .div(amountB ?? 1)\n                      .times(100)\n                      .toFixed(2)\n\n                    mainContentRender = `${\n                      amount.gte(0)\n                        ? getValuePrecisionThousand(amount, precision, precision)\n                        : EmptyValueTag\n                    } ${erc20Symbol}`\n                    break\n                  case sdk.VaultOperationType.VAULT_REPAY:\n                    type = VaultRecordType.repay\n                    //@ts-ignore\n                    vToken = vaultTokenMap[vaultIdIndex[tokenS ?? '']] ?? {}\n                    erc20Symbol = vToken?.symbol.slice(2)\n                    precision = vToken?.precision\n                    vSymbol = vToken?.symbol\n                    amount = sdk.toBig(amountS ?? 0).div('1e' + vToken.decimals)\n                    fillAmountS =\n                      status == sdk.VaultOperationStatus.VAULT_STATUS_SUCCEED ? amountS : 0\n                    fillAmount = sdk.toBig(fillAmountS).div('1e' + vToken.decimals)\n                    percentage = sdk.VaultOperationStatus.VAULT_STATUS_SUCCEED ? 100 : 0\n                    // percentage = sdk\n                    //   .toBig(fillAmountS ?? 0)\n                    //   .div(amountS ?? 1)\n                    //   .times(100)\n                    //   .toFixed(2)\n\n                    mainContentRender = `${\n                      amount.gte(0)\n                        ? getValuePrecisionThousand(amount, precision, precision)\n                        : EmptyValueTag\n                    } ${erc20Symbol}`\n                    break\n                  case sdk.VaultOperationType.VAULT_TRADE:\n                    type = VaultRecordType.trade\n                    //@ts-ignore\n                    vToken = vaultTokenMap[vaultIdIndex[tokenS ?? '']]\n                    //@ts-ignore\n                    vTokenB = vaultTokenMap[vaultIdIndex[tokenB ?? '']]\n                    feeToken = vTokenB\n                    erc20Symbol = vToken.symbol.slice(2)\n                    erc20SymbolB = vTokenB.symbol.slice(2)\n                    precision = vToken.precision\n                    precisionB = vTokenB.precision\n                    vSymbol = vToken.symbol\n                    vSymbolB = vTokenB.symbol\n\n                    fillAmountS = sdk.toBig(order.fillAmountS ?? 0).div('1e' + vToken.decimals)\n                    fillAmountB = sdk.toBig(order.fillAmountB ?? 0).div('1e' + vTokenB.decimals)\n                    fillAmountSStr = getValuePrecisionThousand(fillAmountS, precision, precision)\n                    fillAmountBStr = getValuePrecisionThousand(fillAmountB, precisionB, precisionB)\n                    const _amountS = sdk.toBig(order.amountS ?? 0).div('1e' + vToken.decimals)\n                    const _amountB = sdk.toBig(order.amountB ?? 0).div('1e' + vTokenB.decimals)\n                    const _amountSStr = getValuePrecisionThousand(_amountS, precision, precision)\n                    const _amountBStr = getValuePrecisionThousand(_amountB, precisionB, precisionB)\n\n                    percentage = sdk\n                      .toBig(order?.fillAmountS ?? 0)\n                      .div(order?.amountS ?? 1)\n                      .times(100)\n                      .toFixed(2)\n                    feeStr = getValuePrecisionThousand(\n                      sdk.toBig(fee ?? 0).div('1e' + feeToken.decimals),\n                      precisionB,\n                      precisionB,\n                    )\n                    mainContentRender = `${fillAmountS.gte(0) ? fillAmountSStr : EmptyValueTag}  ${erc20Symbol} ${DirectionTag} ${\n                      fillAmountB.gte(0) ? fillAmountBStr : EmptyValueTag\n                    } ${erc20SymbolB}`\n                    break\n                  case sdk.VaultOperationType.VAULT_CLOSE_OUT:\n                    type = VaultRecordType.closeout\n                    let erc20B = tokenMap[idIndex[tokenB ?? '']]\n                    tokenBSymbol = erc20B.symbol\n                    //@ts-ignore\n                    // vTokenB = vaultTokenMap[vaultIdIndex[tokenB ?? '']]\n                    amount = sdk.toBig(amountB ?? 0).div('1e' + erc20B?.decimals ?? 0)\n                    //@ts-ignore\n                    precision = erc20B.precision\n                    fillAmountB =\n                      status == sdk.VaultOperationStatus.VAULT_STATUS_SUCCEED ? amountB : 0\n                    fillAmount = sdk.toBig(fillAmountB).div('1e' + erc20B.decimals)\n                    percentage = sdk.VaultOperationStatus.VAULT_STATUS_SUCCEED ? 100 : 0\n                    // percentage = sdk\n                    //   .toBig(amountB ?? 0)\n                    //   .div(fillAmountB ?? 1)\n                    //   .times(100)\n                    //   .toFixed(2)\n                    mainContentRender = `${\n                      amount.gte(0)\n                        ? getValuePrecisionThousand(amount, precision, precision)\n                        : EmptyValueTag\n                    } ${tokenBSymbol}`\n                    break\n                  case sdk.VaultOperationType.VAULT_CONVERT:\n                    type = VaultRecordType.convert\n                    const buyAmountList : string[] = (operation as any).executionHistory.map((item: string) => {\n                      const itemObj = JSON.parse(item)\n                      const {\n                        amountOut,\n                        tokenOut,\n                      } = itemObj\n                      const vTokenBuyInfo = vaultTokenMap[vaultIdIndex[tokenOut]]\n                      const buyAmount = numberFormat(utils.formatUnits(amountOut, vTokenBuyInfo.decimals), {fixed: vTokenBuyInfo.precision})\n                      return buyAmount\n                    })\n                    const repaymentInUSDT = numberFormat(numberStringListSum(buyAmountList), {fixed: 2});\n                    mainContentRender = repaymentInUSDT + ' USDT'\n                    break\n                  case sdk.VaultOperationType.VAULT_CLOSE_SHORT:\n                    vToken = vaultTokenMap[vaultIdIndex[tokenS ?? '']] ?? {}\n                    erc20Symbol = vToken?.symbol.slice(2)\n                    precision = vToken?.precision\n                    amount = sdk.toBig(amountS ?? 0).div('1e' + vToken.decimals)\n                    mainContentRender = `${\n                      amount.gte(0)\n                        ? getValuePrecisionThousand(amount, precision, precision)\n                        : EmptyValueTag\n                    } ${erc20Symbol}`\n                    type = VaultRecordType.closeShort\n                    break\n                }\n\n                let item = {\n                  status,\n                  type,\n                  vSymbol,\n                  vTokenB,\n                  operateSubType,\n                  operateType,\n                  symbolB,\n                  vSymbolB,\n                  feeStr,\n                  feeTokenSymbol: feeToken?.symbol,\n                  feeErc20Symbol: erc20SymbolB,\n                  erc20SymbolB,\n                  erc20Symbol,\n                  mainContentRender,\n                  fillAmount: fillAmount?.toString(),\n                  percentage,\n                  raw_data: {\n                    order,\n                    operation,\n                  },\n                } as unknown as R\n                return item\n              },\n            )\n            setVaultOrderData(data)\n          }\n        }\n        setShowLoading(false)\n      }\n    },\n    [accountId, apiKey, setToastOpen, t, tokenMap, vaultIdIndex],\n  )\n  const [detail, setShowDetail] = React.useState<\n    | {\n        isShow: true\n        detail:\n          | {\n              type: 'VAULT_OPEN_POSITION' | 'VAULT_MARGIN_CALL' | 'VAULT_BORROW' | 'VAULT_REPAY' | 'VAULT_JOIN_REDEEM' | 'VAULT_CLOSE_SHORT'\n              statusColor: string\n              statusLabel: string\n              statusType: \"success\" | \"processing\" | \"failed\"\n              // collateralSymbol?: string\n              // collateralAmount?: string\n              time: number\n              amount: string\n              amountSymbol: string\n            }\n          | {\n              type: 'VAULT_TRADE'\n              statusColor: string\n              statusLabel: string\n              statusType: \"success\" | \"processing\" | \"failed\"\n              fromSymbol: string\n              toSymbol: string\n              placedAmount: string\n              executedAmount: string\n              executedRate: string\n              convertedAmount: string\n              price: string\n              feeSymbol: string\n              feeAmount: string\n              time: number\n            }\n          | {\n              type: 'VAULT_CLOSE_OUT'\n              vaultCloseDetail: any\n            }\n          | {\n              type: 'VAULT_CONVERT',\n              status: \"success\" | \"processing\" | \"failed\"\n              totalValueInCurrency: string,\n              convertedInUSDT: string,\n              repaymentInUSDT: string,\n              time: number,\n              dusts: Array<{\n                symbol: string,\n                coinJSON: any,\n                amount: string,\n                valueInCurrency: string,\n              }>,\n            }\n      }\n    | { isShow: false }\n  >({\n    isShow: false,\n  })\n\n  const onItemClick = (item: R) => {\n\n    setShowDetail((_state: any) => {\n      const {\n        raw_data: { operation, order },\n      } = item\n      const statusColor = [\n        sdk.VaultOperationStatus.VAULT_STATUS_SUCCEED,\n        'VAULT_STATUS_EARNING',\n      ].includes(operation.status)\n        ? 'var(--color-success)'\n        : [\n            sdk.VaultOperationStatus.VAULT_STATUS_PENDING,\n            sdk.VaultOperationStatus.VAULT_STATUS_PROCESSING,\n          ].includes(operation.status)\n        ? 'var(--color-primary)'\n        : operation.status === sdk.VaultOperationStatus.VAULT_STATUS_FAILED\n        ? 'var(--color-error)'\n        : 'var(--color-text-primary)'\n      const statusType = [\n        sdk.VaultOperationStatus.VAULT_STATUS_SUCCEED,\n        'VAULT_STATUS_EARNING',\n      ].includes(operation.status)\n        ? 'success'\n        : [\n            sdk.VaultOperationStatus.VAULT_STATUS_PENDING,\n            sdk.VaultOperationStatus.VAULT_STATUS_PROCESSING,\n          ].includes(operation.status)\n        ? 'processing'\n        : operation.status === sdk.VaultOperationStatus.VAULT_STATUS_FAILED\n        ? 'failed'\n        : 'processing'\n      const statusLabel = t2(`labelVault${operation.status}`)\n      switch (operation.operateType) {\n        case 'VAULT_BORROW':\n        case 'VAULT_MARGIN_CALL':\n        case 'VAULT_JOIN_REDEEM':\n        case 'VAULT_REPAY':\n        case 'VAULT_CLOSE_SHORT':\n        case 'VAULT_OPEN_POSITION': {\n          const collateralToken = tokenMap[idIndex[operation.tokenIn]]\n          let amount, amountSymbol: string \n          if (operation.operateType === 'VAULT_BORROW' ) {\n            const vAmountToken = vaultTokenMap[vaultIdIndex[operation.tokenOut]]\n            amount = getValuePrecisionThousand(\n              sdk.toBig(operation.amountOut ?? 0).div('1e' + vAmountToken.decimals),\n              vAmountToken.precision,\n              vAmountToken.precision,\n              undefined,\n              false,\n              {\n                floor: false,\n              },\n            )\n            amountSymbol = vAmountToken && vAmountToken.symbol.slice(2)\n          } else if (operation.operateType === 'VAULT_REPAY' || operation.operateType === 'VAULT_CLOSE_SHORT') {\n            const vAmountToken = vaultTokenMap[vaultIdIndex[operation.tokenIn]]\n            amount = getValuePrecisionThousand(\n              sdk.toBig(operation.amountIn ?? 0).div('1e' + vAmountToken.decimals).abs(),\n              vAmountToken.precision,\n              vAmountToken.precision,\n              undefined,\n              false,\n              {\n                floor: false,\n              },\n            )\n            amountSymbol = vAmountToken && vAmountToken.symbol.slice(2)\n          } else {\n            const amountToken = tokenMap[idIndex[operation.tokenIn]]\n            amount = getValuePrecisionThousand(\n              sdk.toBig(operation.amountIn ?? 0).div('1e' + amountToken.decimals).abs(),\n              amountToken.precision,\n              amountToken.precision,\n              undefined,\n              false,\n              {\n                floor: false,\n              },\n            )\n            amountSymbol = amountToken && amountToken.symbol\n          }\n          return {\n            isShow: true,\n            detail: {\n              type: operation.operateType,\n              time: operation && operation.createdAt,\n              statusColor,\n              statusLabel,\n              statusType,\n              amount: amount,\n              amountSymbol: amountSymbol\n            },\n          }\n        }\n        case 'VAULT_CLOSE_OUT': {\n          const profit =\n            (operation as any).accountType === 0 \n            ? (operation?.totalEquity && operation?.Collateral\n              ? sdk.toBig(operation?.totalEquity ?? 0).minus(operation?.Collateral ?? 0)\n              : undefined)\n            : (operation as any)?.profit as string\n          const outTokenInfo = tokenMap[idIndex[operation.tokenOut]]\n          const amount = sdk.toBig(operation.amountOut).div('1e' + outTokenInfo.decimals)\n\n          return {\n            isShow: true,\n            detail: {\n              ...item,\n              type: 'VAULT_CLOSE_OUT',\n              vaultCloseDetail: {\n                statusType,\n                statusLabel,\n                status: t(`labelVault${operation.status}`),\n                amount: amount.gte(0)\n                  ? getValuePrecisionThousand(\n                      amount,\n                      outTokenInfo.precision,\n                      outTokenInfo.precision,\n                      outTokenInfo.precision,\n                      true,\n                      { floor: true },\n                    ) +\n                    ' ' +\n                    outTokenInfo.symbol\n                  : EmptyValueTag,\n                executionHistory: operation?.executionHistory,\n                profit: profit\n                  ? PriceTag[CurrencyToTag[currency]] +\n                    getValuePrecisionThousand(\n                      sdk.toBig(profit).times(forexMap[currency] ?? 0),\n                      2,\n                      2,\n                      2,\n                      true,\n                      { floor: true },\n                    )\n                  : EmptyValueTag,\n                profitPercent:\n                  profit && Number(operation?.Collateral ?? 0)\n                    ? numberFormat(new Decimal(profit.toString()).div(operation?.Collateral).times(100).toString(), {fixed: 2}) + '%'\n                    : EmptyValueTag,\n                usdValue: operation?.totalBalance\n                  ? PriceTag[CurrencyToTag[currency]] +\n                    getValuePrecisionThousand(\n                      sdk.toBig(operation?.totalBalance ?? 0).times(forexMap[currency] ?? 0),\n                      2,\n                      2,\n                      2,\n                      true,\n                      { floor: true },\n                    )\n                  : EmptyValueTag,\n                usdDebt: operation?.totalDebt\n                  ? PriceTag[CurrencyToTag[currency]] +\n                    getValuePrecisionThousand(\n                      sdk.toBig(operation?.totalDebt ?? 0).times(forexMap[currency] ?? 0),\n                      2,\n                      2,\n                      2,\n                      true,\n                      { floor: true },\n                    )\n                  : EmptyValueTag,\n                usdEquity: operation?.totalEquity\n                  ? PriceTag[CurrencyToTag[currency]] +\n                    getValuePrecisionThousand(\n                      sdk.toBig(operation?.totalEquity ?? 0).times(forexMap[currency] ?? 0),\n                      2,\n                      2,\n                      2,\n                      true,\n                      { floor: true },\n                    )\n                  : EmptyValueTag,\n                forexMap,\n                tokenSymbol: outTokenInfo.symbol,\n                isForcedLiqudation:\n                  (item.raw_data.operation.operateSubType as string) === 'VAULT_FORCE_SETTLEMENT' ||\n                  (item.raw_data.operation.operateSubType as string) === 'VAULT_FORCE_WITHDRAW',\n              },\n            },\n          }\n        }\n        case 'VAULT_TRADE': {\n          const vTokenSellInfo = (vaultTokenMap && vaultIdIndex) ? vaultTokenMap[vaultIdIndex[order.tokenS]] : undefined\n          const vTokenBuyInfo = (vaultTokenMap && vaultIdIndex) ? vaultTokenMap[vaultIdIndex[order.tokenB]] : undefined\n\n          return {\n            isShow: true,\n            detail: {\n              type: 'VAULT_TRADE',\n              statusColor,\n              statusLabel,\n              statusType,\n              fromSymbol: vTokenSellInfo && vTokenSellInfo.symbol.slice(2),\n              toSymbol: vTokenBuyInfo && vTokenBuyInfo.symbol.slice(2),\n              placedAmount: vTokenSellInfo && getValuePrecisionThousand(\n                sdk.toBig(order.amountS).div('1e' + vTokenSellInfo.decimals),\n                vTokenSellInfo.precision,\n                vTokenSellInfo.precision,\n                undefined,\n                false,\n                {\n                  floor: false,\n                },\n              ),\n              executedAmount: vTokenSellInfo && getValuePrecisionThousand(\n                sdk.toBig(order.fillAmountS).div('1e' + vTokenSellInfo.decimals),\n                vTokenSellInfo.precision,\n                vTokenSellInfo.precision,\n                undefined,\n                false,\n                {\n                  floor: false,\n                },\n              ),\n              executedRate:\n                sdk.toBig(order.fillAmountS).div(order.amountS).multipliedBy('100').toFixed(2) +\n                '%',\n              convertedAmount: vTokenBuyInfo && getValuePrecisionThousand(\n                sdk.toBig(order.fillAmountB).div('1e' + vTokenBuyInfo.decimals),\n                vTokenBuyInfo.precision,\n                vTokenBuyInfo.precision,\n                undefined,\n                false,\n                {\n                  floor: false,\n                },\n              ),\n              price: order.price,\n              feeSymbol: vTokenBuyInfo && vTokenBuyInfo.symbol.slice(2),\n              feeAmount: vTokenBuyInfo && getValuePrecisionThousand(\n                sdk.toBig(order.fee).div('1e' + vTokenBuyInfo.decimals),\n                vTokenBuyInfo.precision,\n                vTokenBuyInfo.precision,\n                undefined,\n                false,\n                {\n                  floor: false,\n                },\n              ),\n              time: order.createdAt,\n            },\n          }\n        }\n        case 'VAULT_CONVERT': {\n          const executionHistory = (operation as any).executionHistory as string[]\n          const dustList : {\n            symbol: string;\n            coinJSON: any;\n            amount: string;\n            amountRaw: string;\n            valueInCurrency: string | undefined;\n            valueInCurrencyRaw: string | undefined;\n            buyAmount: string | undefined;\n          }[] = executionHistory.map(item => {\n            const itemObj = JSON.parse(item)\n            const {\n              tokenIn,\n              amountIn,\n              amountOut,\n              tokenOut,\n            } = itemObj\n            const vTokenSellInfo = vaultTokenMap[vaultIdIndex[tokenIn]]\n            const vTokenBuyInfo = vaultTokenMap[vaultIdIndex[tokenOut]]\n            const amount = numberFormat(utils.formatUnits(amountIn, vTokenSellInfo.decimals), {fixed: vTokenSellInfo.precision, removeTrailingZero: true})\n            const buyAmount = numberFormat(utils.formatUnits(amountOut, vTokenBuyInfo.decimals), {fixed: vTokenBuyInfo.precision, removeTrailingZero: true})\n            const sellTokenPrice = vaultTokenPrices[vTokenSellInfo.symbol]\n            return {\n              symbol: vTokenSellInfo.symbol.slice(2),\n              coinJSON: coinJson[vTokenSellInfo.symbol.slice(2)],\n              amount,\n              amountRaw: amountIn,\n              valueInCurrency: fiatNumberDisplay(\n                getValueInCurrency(new Decimal(amount).times(sellTokenPrice).toString()),\n                currency\n              ),\n              valueInCurrencyRaw: getValueInCurrency(new Decimal(amount).times(sellTokenPrice).toString()),\n              buyAmount,\n            }\n          })\n\n          return {\n            isShow: true,\n            detail: {\n              type: 'VAULT_CONVERT',\n              statusColor,\n              statusLabel,\n              statusType,\n              status: operation.status === sdk.VaultOperationStatus.VAULT_STATUS_SUCCEED ? 'success' : operation.status === sdk.VaultOperationStatus.VAULT_STATUS_FAILED ? 'failed' : 'processing',\n              totalValueInCurrency: fiatNumberDisplay(numberStringListSum(dustList.map(dust => dust.valueInCurrencyRaw ?? '0')), currency),\n              convertedInUSDT: numberFormat(numberStringListSum(dustList.map(dust => dust.valueInCurrencyRaw ?? '0')), {fixed: 2}),\n              repaymentInUSDT: numberFormat(numberStringListSum(dustList.map(dust => dust.buyAmount ?? '0')), {fixed: 2}), \n              time: operation.createdAt,\n              dusts: dustList,\n            },\n          }\n        }\n        default: {\n          throw 'err'\n        }\n      }\n    })\n  }\n  return {\n    getVaultOrderList,\n    vaultOrderData,\n    totalNum,\n    showLoading,\n    onItemClick,\n    vaultOperationDetail: detail.isShow ? detail.detail : undefined,\n    openVaultDetail: detail.isShow,\n    onVaultDetailClose: () =>\n      setShowDetail({\n        isShow: false,\n      }),\n  }\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/AssetPage/HistoryPanel/index.tsx",
    "content": "import React from 'react'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport { Box, Divider, Modal, Tab, Tabs, Typography } from '@mui/material'\nimport {\n  AmmTable,\n  BtradeSwapTable,\n  Button,\n  CoinIcons,\n  DefiStakingTxTable,\n  DefiTxsTable,\n  DualTxsTable,\n  ModalCloseButton,\n  OrderHistoryTable,\n  SwitchPanelStyled,\n  Toast,\n  ToastType,\n  TradeTable,\n  TransactionTable,\n  useSettings,\n  useToggle,\n  DualDes,\n  ButtonStyle,\n  VaultCloseDetail,\n  VaultTxTable,\n} from '@loopring-web/component-lib'\nimport {\n  StylePaper,\n  useAccount,\n  useAmmMap,\n  useGetOrderHistorys,\n  useSystem,\n  useToast,\n  useTokenMap,\n} from '@loopring-web/core'\nimport {\n  useBtradeTransaction,\n  useDefiSideRecord,\n  useDualTransaction,\n  useGetAmmRecord,\n  useGetDefiRecord,\n  useGetLeverageETHRecord,\n  useGetTrades,\n  useGetTxs,\n  useOrderList,\n  useVaultTransaction,\n} from './hooks'\nimport {\n  BackIcon,\n  MapChainId,\n  RecordMap,\n  RecordTabIndex,\n  RowConfig,\n  TOAST_TIME,\n  TabOrderIndex,\n  TokenType,\n  DualViewBase,\n  RouterPath,\n  InvestAssetRouter,\n  DualViewType,\n} from '@loopring-web/common-resources'\nimport { useHistory, useLocation, useRouteMatch } from 'react-router-dom'\nimport { useDualAsset } from './useDualAsset'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { VaultConvertDetail, VaultOperationDetail, VaultTradeDetail } from '@loopring-web/component-lib/src/components/tableList/vaultTable/VaultTxTable'\nimport Decimal from 'decimal.js'\nexport const l2assetsRouter = `${RouterPath.l2records}/:tab/:orderTab?`\n\n\nconst HistoryPanel = withTranslation('common')((rest: WithTranslation<'common'>) => {\n  const history = useHistory()\n  const { search } = useLocation()\n  const { isMobile, defaultNetwork, coinJson } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const {\n    toggle: { StopLimit },\n  } = useToggle()\n  const match: any = useRouteMatch(l2assetsRouter)\n  const [pageSize, setPageSize] = React.useState(0)\n  const [currentTab, setCurrentTab] = React.useState<RecordTabIndex>(() => {\n    let item = match?.params?.tab ?? RecordTabIndex.Transactions\n    return RecordMap[network]?.includes(item) ? item : RecordTabIndex.Transactions\n  })\n  const [currentOrderTab, setCurrentOrderTab] = React.useState(() => {\n    return match?.params?.orderTab ?? TabOrderIndex.orderOpenTable\n  })\n\n  const { toastOpen, setToastOpen, closeToast } = useToast()\n  const { totalCoinMap, tokenMap, idIndex, marketArray } = useTokenMap()\n  const { ammMap } = useAmmMap()\n  const { etherscanBaseUrl } = useSystem()\n\n  const {\n    txs: txTableData,\n    txsTotal,\n    showLoading: showTxsLoading,\n    getUserTxnList,\n    searchValue,\n  } = useGetTxs(setToastOpen)\n  const {\n    userTrades,\n    getUserTradeList,\n    userTradesTotal,\n    page: tradePage,\n    showLoading: showTradeLoading,\n  } = useGetTrades(setToastOpen)\n  const {\n    defiList,\n    showLoading: showDefiLoading,\n    getDefiTxList,\n    defiTotal,\n  } = useGetDefiRecord(setToastOpen)\n  const {\n    ammRecordList,\n    showLoading: showAmmloading,\n    ammRecordTotal,\n    getAmmpoolList,\n  } = useGetAmmRecord(setToastOpen)\n  const {\n    rawData,\n    getOrderList,\n    totalNum,\n    showLoading,\n    marketArray: orderRaw,\n    cancelOrder,\n  } = useOrderList({ setToastOpen })\n  const {\n    rawData: stopLimitRawData,\n    getOrderList: getStopLimitOrderList,\n    totalNum: totalNumStopLimit,\n    showLoading: showLoadingStopLimit,\n    cancelOrder: cancelOrderStopLimit,\n  } = useOrderList({ setToastOpen, isStopLimit: true })\n\n  const {\n    dualList,\n    showLoading: showDualLoading,\n    getDualTxList,\n    dualMarketMap,\n    dualTotal,\n    refreshDualDetail,\n    dualDetail,\n    openDualDetail,\n    onDualClose,\n  } = useDualTransaction(setToastOpen)\n  const {\n    sideStakingList,\n    showLoading: showDefiSideStakingLoading,\n    getSideStakingTxList,\n    sideStakingTotal,\n  } = useDefiSideRecord(setToastOpen)\n  const {\n    leverageETHList,\n    showLoading: showLeverageETHLoading,\n    getLeverageETHTxList,\n    leverageETHTotal,\n  } = useGetLeverageETHRecord(setToastOpen)\n\n  const { userOrderDetailList, getUserOrderDetailTradeList } = useGetOrderHistorys()\n  const {\n    getVaultOrderList,\n    vaultOrderData,\n    totalNum: vaultTotal,\n    showLoading: showVaultLoaning,\n    onItemClick: onVaultDetail,\n    vaultOperationDetail,\n    openVaultDetail,\n    onVaultDetailClose,\n  } = useVaultTransaction(setToastOpen)\n  const {\n    getBtradeOrderList,\n    btradeOrderData,\n    onDetail,\n    totalNum: btradeTotalNum,\n    showLoading: showBtradeLoading,\n  } = useBtradeTransaction(setToastOpen)\n\n  const {\n    account: { accAddress, accountId },\n  } = useAccount()\n\n  const { t } = rest\n  const container = React.useRef<HTMLDivElement>(null)\n\n  const handleTabChange = React.useCallback(\n    (value: RecordTabIndex, _pageSize?: number) => {\n      setCurrentTab(value)\n      history.replace(`${RouterPath.l2records}/${value}?${search.replace('?', '')}`)\n    },\n    [history, search],\n  )\n  React.useEffect(() => {\n    let height = container?.current?.offsetHeight\n    if (height) {\n      const pageSize = Math.floor((height - 120) / RowConfig.rowHeight) - 3\n      setPageSize(Math.floor((height - 120) / RowConfig.rowHeight) - 3)\n      handleTabChange(currentTab, pageSize)\n    }\n  }, [container?.current?.offsetHeight])\n  // React.useEffect(()=>{},[])\n  return (\n    <Box flex={1} display={'flex'} flexDirection={'column'}>\n      <Box marginBottom={2}>\n        <Button\n          startIcon={<BackIcon fontSize={'small'} />}\n          variant={'text'}\n          size={'medium'}\n          sx={{ color: 'var(--color-text-secondary)' }}\n          color={'inherit'}\n          onClick={history.goBack}\n        >\n          {t('labelTransactions')}\n          {/*<Typography color={\"textPrimary\"}></Typography>*/}\n        </Button>\n      </Box>\n      {/*<IconButton*/}\n      {/*  className={\"back-btn\"}*/}\n      {/*  size={\"large\"}*/}\n      {/*  color={\"inherit\"}*/}\n      {/*  aria-label={t && t(\"labelBack\")}*/}\n      {/*  onClick={() => {*/}\n      {/*    onBack && onBack();*/}\n      {/*  }}*/}\n      {/*>*/}\n      {/*  <BackIcon />*/}\n      {/*</IconButton>*/}\n      <StylePaper ref={container} flex={1}>\n        <Toast\n          alertText={toastOpen?.content ?? ''}\n          severity={toastOpen?.type ?? ToastType.success}\n          open={toastOpen?.open ?? false}\n          autoHideDuration={TOAST_TIME}\n          onClose={closeToast}\n        />\n        <Box marginTop={2} display={'flex'} sx={isMobile ? { maxWidth: 'calc(100vw - 32px)' } : {}}>\n          <Tabs\n            value={currentTab}\n            onChange={(_event, value) => handleTabChange(value)}\n            aria-label='l2-history-tabs'\n            variant='scrollable'\n          >\n            {RecordMap[network]?.map((item) => {\n              return <Tab key={item} label={t(`labelLayer2History${item}`)} value={item} />\n            })}\n          </Tabs>\n        </Box>\n        <Box\n          className='tableWrapper table-divide-short'\n          display={'flex'}\n          flex={1}\n          overflow={'auto'}\n        >\n          {currentTab === RecordTabIndex.Transactions ? (\n            <TransactionTable\n              {...{\n                etherscanBaseUrl,\n                rawData: txTableData,\n                searchValue,\n                pagination: {\n                  pageSize: pageSize,\n                  total: txsTotal,\n                },\n                filterTokens: totalCoinMap ? (Reflect.ownKeys(totalCoinMap) as string[]) : [],\n                showFilter: true,\n                showloading: showTxsLoading,\n                getTxnList: getUserTxnList,\n                accAddress,\n                accountId,\n                ...rest,\n              }}\n            />\n          ) : currentTab === RecordTabIndex.Trades ? (\n            <TradeTable\n              getUserTradeList={getUserTradeList}\n              {...{\n                rawData: userTrades,\n                showFilter: true,\n                filterPairs: marketArray,\n                showloading: showTradeLoading,\n                tokenMap: tokenMap,\n                isL2Trade: true,\n                pagination: {\n                  page: tradePage,\n                  pageSize: pageSize,\n                  total: userTradesTotal,\n                },\n                accAddress,\n                accountId,\n                ...rest,\n              }}\n            />\n          ) : currentTab === RecordTabIndex.AmmRecords ? (\n            <AmmTable\n              {...{\n                rawData: ammRecordList,\n                pagination: {\n                  pageSize: pageSize,\n                  total: ammRecordTotal,\n                },\n                getAmmpoolList,\n                showFilter: true,\n                filterPairs: Reflect.ownKeys(ammMap ?? {}).map((item) =>\n                  item.toString().replace('AMM', 'LP'),\n                ),\n                showloading: showAmmloading,\n                ...rest,\n              }}\n            />\n          ) : currentTab === RecordTabIndex.DefiRecords ? (\n            <DefiTxsTable\n              key={'defi'}\n              {...{\n                rawData: defiList,\n                pagination: {\n                  pageSize: pageSize,\n                  total: defiTotal,\n                },\n                getDefiTxList,\n                showloading: showDefiLoading,\n                ...rest,\n              }}\n              tokenMap={tokenMap}\n              idIndex={idIndex}\n            />\n          ) : currentTab === RecordTabIndex.SideStakingRecords ? (\n            <DefiStakingTxTable\n              {...{\n                rawData: sideStakingList as any[],\n                pagination: {\n                  pageSize: pageSize,\n                  total: sideStakingTotal,\n                },\n                getSideStakingTxList,\n                showloading: showDefiSideStakingLoading,\n                ...rest,\n              }}\n              tokenMap={tokenMap}\n              idIndex={idIndex}\n            />\n          ) : currentTab === RecordTabIndex.DualRecords ? (\n            <>\n              <Modal\n                open={openDualDetail}\n                onClose={onDualClose}\n                aria-labelledby='modal-modal-title'\n                aria-describedby='modal-modal-description'\n              >\n                <SwitchPanelStyled width={'var(--modal-width)'}>\n                  <ModalCloseButton onClose={onDualClose} t={t} />\n                  <Box\n                    display={'flex'}\n                    flexDirection={'column'}\n                    alignItems={'flex-start'}\n                    alignSelf={'stretch'}\n                    marginTop={-4}\n                    justifyContent={'stretch'}\n                  >\n                    <Typography\n                      display={'flex'}\n                      flexDirection={'row'}\n                      component={'header'}\n                      alignItems={'center'}\n                      height={'var(--toolbar-row-height)'}\n                      paddingX={3}\n                    >\n                      <Typography component={'span'} display={'inline-flex'}>\n                        {/* eslint-disable-next-line react/jsx-no-undef */}\n                        <CoinIcons\n                          type={TokenType.dual}\n                          size={32}\n                          tokenIcon={[\n                            coinJson[dualDetail?.dualViewInfo?.sellSymbol ?? ''],\n                            coinJson[dualDetail?.dualViewInfo?.buySymbol ?? ''],\n                          ]}\n                        />\n                      </Typography>\n                      <Typography component={'span'} display={'inline-flex'} color={'textPrimary'}>\n                        {`${dualDetail?.dualViewInfo?.sellSymbol} / ${dualDetail?.dualViewInfo?.buySymbol}`}\n                      </Typography>\n                    </Typography>\n                    <Divider style={{ marginTop: '-1px', width: '100%' }} />\n                  </Box>\n\n                  {dualDetail && dualDetail.dualViewInfo && (\n                    <Box\n                      flex={1}\n                      paddingY={2}\n                      width={'100%'}\n                      display={'flex'}\n                      flexDirection={'column'}\n                      sx={\n                        isMobile\n                          ? {\n                              maxHeight: 'initial',\n                              overflowY: 'initial',\n                            }\n                          : { maxHeight: 'var(--modal-height)', overflowY: 'auto' }\n                      }\n                    >\n                      <DualDes\n                        isOrder={true}\n                        dualViewInfo={dualDetail.dualViewInfo as DualViewBase}\n                        currentPrice={dualDetail.dualViewInfo.currentPrice}\n                      />\n                      <Box paddingX={2}>\n                        <ButtonStyle\n                          fullWidth\n                          variant={'contained'}\n                          size={'medium'}\n                          color={'primary'}\n                          onClick={() => {\n                            history.push(\n                              `${RouterPath.invest}/${InvestAssetRouter.DUAL}/${\n                                dualDetail?.currentPrice?.base\n                              }-${dualDetail?.currentPrice?.quoteUnit}?viewType=${\n                                dualDetail.dualViewInfo.dualType === sdk.DUAL_TYPE.DUAL_BASE\n                                  ? DualViewType.DualGain\n                                  : DualViewType.DualDip\n                              }`,\n                            )\n                          }}\n                        >\n                          {t('labelQuickInvest')}\n                        </ButtonStyle>\n                      </Box>\n                    </Box>\n                  )}\n                </SwitchPanelStyled>\n              </Modal>\n              <DualTxsTable\n                rawData={dualList}\n                getDualTxList={getDualTxList}\n                pagination={{\n                  pageSize: pageSize + 2,\n                  total: dualTotal,\n                }}\n                dualMarketMap={dualMarketMap}\n                showloading={showDualLoading}\n                tokenMap={tokenMap}\n                idIndex={idIndex}\n                {...{\n                  ...rest,\n                }}\n              />\n            </>\n          ) : currentTab === RecordTabIndex.Orders ? (\n            <Box flex={1} display={'flex'} flexDirection={'column'} marginTop={-2}>\n              <Box marginBottom={2} marginLeft={3}>\n                <Tabs\n                  value={currentOrderTab}\n                  onChange={(_event, value) => {\n                    setCurrentOrderTab(value)\n                    history.replace(\n                      `/l2assets/history/${RecordTabIndex.Orders}/${value}?${search.replace(\n                        '?',\n                        '',\n                      )}`,\n                    )\n                  }}\n                  aria-label='l2-history-tabs'\n                  variant='scrollable'\n                >\n                  <Tab label={t('labelOrderTableOpenOrder')} value={TabOrderIndex.orderOpenTable} />\n                  <Tab\n                    label={t('labelOrderTableOrderHistory')}\n                    value={TabOrderIndex.orderHistoryTable}\n                  />\n                </Tabs>\n              </Box>\n\n              <OrderHistoryTable\n                {...{\n                  pagination:\n                    currentOrderTab === TabOrderIndex.orderOpenTable\n                      ? undefined\n                      : {\n                          pageSize: pageSize - 1,\n                          total: totalNum,\n                        },\n                  rawData,\n                  showFilter: true,\n                  getOrderList,\n                  marketArray: orderRaw,\n                  showDetailLoading: false,\n                  userOrderDetailList,\n                  getUserOrderDetailTradeList,\n                  ...rest,\n                  showLoading,\n                  isOpenOrder: currentOrderTab === TabOrderIndex.orderOpenTable,\n                  cancelOrder,\n                }}\n              />\n            </Box>\n          ) : currentTab === RecordTabIndex.StopLimitRecords ? (\n            <Box flex={1} display={'flex'} flexDirection={'column'} marginTop={-2}>\n              <>\n                <Box marginBottom={2} marginLeft={3}>\n                  <Tabs\n                    value={currentOrderTab}\n                    onChange={(_event, value) => {\n                      setCurrentOrderTab(value)\n                      history.replace(\n                        `/l2assets/history/${\n                          RecordTabIndex.StopLimitRecords\n                        }/${value}?${search.replace('?', '')}`,\n                      )\n                    }}\n                    aria-label='l2-history-tabs'\n                    variant='scrollable'\n                  >\n                    <Tab\n                      label={t('labelOrderTableOpenOrder')}\n                      value={TabOrderIndex.orderOpenTable}\n                    />\n                    <Tab\n                      label={t('labelOrderTableOrderHistory')}\n                      value={TabOrderIndex.orderHistoryTable}\n                    />\n                  </Tabs>\n                </Box>\n\n                <OrderHistoryTable\n                  {...{\n                    pagination:\n                      currentOrderTab === TabOrderIndex.orderOpenTable\n                        ? undefined\n                        : {\n                            pageSize: pageSize - 1,\n                            total: totalNumStopLimit,\n                          },\n                    isStopLimit: true,\n                    rawData: stopLimitRawData,\n                    showFilter: true,\n                    getOrderList: getStopLimitOrderList,\n                    marketArray: orderRaw,\n                    showDetailLoading: false,\n                    userOrderDetailList,\n                    getUserOrderDetailTradeList,\n                    ...rest,\n                    showLoading: showLoadingStopLimit,\n                    isOpenOrder: currentOrderTab === TabOrderIndex.orderOpenTable,\n                    cancelOrder: cancelOrderStopLimit,\n                  }}\n                />\n              </>\n            </Box>\n          ) : currentTab === RecordTabIndex.BtradeSwapRecords ? (\n            <Box flex={1} display={'flex'} flexDirection={'column'} marginTop={-2}>\n              <BtradeSwapTable\n                {...{\n                  showloading: showBtradeLoading,\n                  getBtradeOrderList,\n                  rawData: btradeOrderData,\n                }}\n                pagination={{\n                  pageSize: pageSize,\n                  total: btradeTotalNum,\n                }}\n                onItemClick={onDetail}\n              />\n            </Box>\n          ) : currentTab === RecordTabIndex.leverageETHRecords ? (\n            <DefiTxsTable\n              key={'leverage'}\n              {...{\n                rawData: leverageETHList,\n                pagination: {\n                  pageSize: pageSize,\n                  total: leverageETHTotal,\n                },\n                getDefiTxList: getLeverageETHTxList,\n                showloading: showLeverageETHLoading,\n                ...rest,\n              }}\n              tokenMap={tokenMap}\n              idIndex={idIndex}\n            />\n          ) : currentTab === RecordTabIndex.VaultRecords ? (\n            <>\n              <Modal\n                open={openVaultDetail}\n                onClose={onVaultDetailClose}\n                aria-labelledby='modal-modal-title'\n                aria-describedby='modal-modal-description'\n              >\n                <SwitchPanelStyled width={'var(--modal-width)'}>\n                  <ModalCloseButton onClose={onVaultDetailClose} t={t} />\n                  <Box\n                    display={'flex'}\n                    flexDirection={'column'}\n                    alignItems={'flex-start'}\n                    alignSelf={'stretch'}\n                    marginTop={-4}\n                    justifyContent={'stretch'}\n                  >\n                    <Typography\n                      display={'flex'}\n                      flexDirection={'row'}\n                      component={'header'}\n                      alignItems={'center'}\n                      height={'var(--toolbar-row-height)'}\n                      paddingX={3}\n                    >\n                      <Typography component={'span'} display={'inline-flex'}>\n                        {vaultOperationDetail &&\n                          (vaultOperationDetail.type === 'VAULT_BORROW'\n                            ? t('labelBorrowDetail')\n                            : vaultOperationDetail.type === 'VAULT_MARGIN_CALL'\n                            ? t('labelMarginCallDetail')\n                            : vaultOperationDetail.type === 'VAULT_OPEN_POSITION'\n                            ? t('labelVaultJoin')\n                            : vaultOperationDetail.type === 'VAULT_REPAY'\n                            ? t('labelRepayDetail')\n                            : vaultOperationDetail.type === 'VAULT_TRADE'\n                            ? t('labelTradeDetail')\n                            : vaultOperationDetail.type === 'VAULT_CONVERT'\n                            ? t('labelDustCollectorDetail')\n                            : vaultOperationDetail.type === 'VAULT_JOIN_REDEEM'\n                            ? t('labelVaultJoinRedeem')\n                            : vaultOperationDetail.type === 'VAULT_CLOSE_SHORT' \n                            ? 'Close Short'\n                            : t('labelCloseOutDetail'))\n                            }\n                      </Typography>\n                    </Typography>\n                    <Divider style={{ marginTop: '-1px', width: '100%' }} />\n                  </Box>\n                  <Box\n                    sx={{\n                      flex: 1,\n                      paddingY: 2,\n                      width: '100%',\n                      display: 'flex',\n                      flexDirection: 'column',\n                      maxHeight: isMobile ? 'initial' : '75vh',\n                      overflowY: isMobile ? 'initial' : 'auto',\n                    }}\n                  >\n                    {vaultOperationDetail &&\n                      (vaultOperationDetail.type === 'VAULT_BORROW' ||\n                        vaultOperationDetail.type === 'VAULT_MARGIN_CALL' ||\n                        vaultOperationDetail.type === 'VAULT_OPEN_POSITION' ||\n                        vaultOperationDetail.type === 'VAULT_JOIN_REDEEM' ||\n                        vaultOperationDetail.type === 'VAULT_REPAY' ||\n                        vaultOperationDetail.type === 'VAULT_CLOSE_SHORT') && (\n                        <VaultOperationDetail\n                          statusColor={vaultOperationDetail.statusColor}\n                          statusLabel={vaultOperationDetail.statusLabel}\n                          time={vaultOperationDetail.time}\n                          type={vaultOperationDetail.type}\n                          statusType={vaultOperationDetail.statusType}\n                          amount={vaultOperationDetail.amount ? vaultOperationDetail.amount : ''}\n                          amountSymbol={vaultOperationDetail.amountSymbol}\n                        />\n                      )}\n                    {vaultOperationDetail && vaultOperationDetail.type === 'VAULT_CLOSE_OUT' && (\n                      <VaultCloseDetail\n                        vaultCloseDetail={vaultOperationDetail.vaultCloseDetail}\n                      />\n                    )}\n                    {vaultOperationDetail && vaultOperationDetail.type === 'VAULT_TRADE' && (\n                      <VaultTradeDetail\n                        statusColor={vaultOperationDetail.statusColor}\n                        statusLabel={vaultOperationDetail.statusLabel}\n                        fromSymbol={vaultOperationDetail.fromSymbol}\n                        toSymbol={vaultOperationDetail.toSymbol}\n                        placedAmount={vaultOperationDetail.placedAmount}\n                        executedAmount={vaultOperationDetail.executedAmount}\n                        executedRate={vaultOperationDetail.executedRate}\n                        convertedAmount={vaultOperationDetail.convertedAmount}\n                        price={vaultOperationDetail.price}\n                        feeSymbol={vaultOperationDetail.feeSymbol}\n                        feeAmount={vaultOperationDetail.feeAmount}\n                        time={vaultOperationDetail.time}\n                        statusType={vaultOperationDetail.statusType}\n                      />\n                    )}\n                    {vaultOperationDetail && vaultOperationDetail.type === 'VAULT_CONVERT' && (\n                      <VaultConvertDetail\n                        totalValueInCurrency={vaultOperationDetail.totalValueInCurrency}\n                        convertedInUSDT={vaultOperationDetail.convertedInUSDT}\n                        repaymentInUSDT={vaultOperationDetail.repaymentInUSDT}\n                        time={vaultOperationDetail.time}\n                        dusts={vaultOperationDetail.dusts}\n                        status={vaultOperationDetail.status}\n                      />\n                    )}\n                  </Box>\n                </SwitchPanelStyled>\n              </Modal>\n              <Box flex={1} display={'flex'} flexDirection={'column'} marginTop={-2}>\n                <VaultTxTable\n                  {...{\n                    showloading: showVaultLoaning,\n                    getOrderList: getVaultOrderList,\n                    rawData: vaultOrderData,\n                    onItemClick: onVaultDetail,\n                  }}\n                  pagination={{\n                    pageSize: pageSize,\n                    total: vaultTotal,\n                  }}\n                />\n              </Box>\n            </>\n          ) : (\n            <></>\n          )}\n        </Box>\n      </StylePaper>\n    </Box>\n  )\n})\n\nexport { HistoryPanel, useDualAsset }\n"
  },
  {
    "path": "packages/webapp/src/pages/AssetPage/HistoryPanel/useDualAsset.tsx",
    "content": "import {\n  LoopringAPI,\n  makeDualOrderedItem,\n  makeDualViewItem,\n  store,\n  useAccount,\n  useDualEdit,\n  useDualMap,\n  useTokenMap,\n  useTradeDual,\n} from '@loopring-web/core'\nimport React from 'react'\nimport {\n  CompleteIcon,\n  DualViewInfo,\n  EmptyValueTag,\n  getValuePrecisionThousand,\n  myLog,\n  SDK_ERROR_MAP_TO_UI,\n  WaitingIcon,\n  WarningIcon,\n} from '@loopring-web/common-resources'\nimport {\n  DualDetailType,\n  LABEL_INVESTMENT_STATUS_MAP,\n  RawDataDualAssetItem,\n  ToastType,\n} from '@loopring-web/component-lib'\nimport { useTranslation } from 'react-i18next'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { DUAL_TYPE, LABEL_INVESTMENT_STATUS } from '@loopring-web/loopring-sdk'\nimport BigNumber from 'bignumber.js'\nimport _ from 'lodash'\n\nexport const Limit = 50\n\nexport const useDualAsset = <R extends RawDataDualAssetItem>(\n  setToastOpen?: (props: any) => void,\n) => {\n  const { t } = useTranslation(['common', 'error'])\n  const {\n    account: { accountId, apiKey },\n  } = useAccount()\n  const { updateEditDual } = useTradeDual()\n  const { tokenMap, idIndex } = useTokenMap()\n  const { marketMap: dualMarketMap } = useDualMap()\n  const [dualList, setDualList] = React.useState<R[]>([])\n  const [dualOnInvestAsset, setDualOnInvestAsset] = React.useState<any>(undefined)\n  const [pagination, setDualPagination] = React.useState<{\n    pageSize: number\n    total: number\n  }>({\n    pageSize: Limit,\n    total: 0,\n  })\n  const [showLoading, setShowLoading] = React.useState(true)\n  const [open, setOpen] = React.useState<boolean>(false)\n  const [detail, setDetail] = React.useState<DualDetailType | undefined>(undefined)\n  const [showRefreshError, setShowRefreshError] = React.useState<boolean>(false)\n  const [refreshErrorInfo, setRefreshErrorInfo] = React.useState<[string, string]>(['', ''])\n\n  const getDetail = (item: R, index?: number) => {\n    let {\n      sellSymbol,\n      buySymbol,\n      settleRatio,\n      __raw__: {\n        order: {\n          strike,\n          settlementStatus,\n          tokenInfoOrigin: { amountIn, tokenOut, amountOut, tokenIn },\n          dualReinvestInfo,\n          timeOrigin: { expireTime },\n          investmentStatus,\n          dualType,\n          deliveryPrice,\n        },\n      },\n    } = item\n    let icon: any = undefined,\n      status = ''\n    let content = ''\n    const currentPrice = _.cloneDeep(item.currentPrice)\n    if (index) {\n      currentPrice.currentPrice = index\n    }\n    let lessEarnTokenSymbol, greaterEarnTokenSymbol, lessEarnVol, greaterEarnVol\n    const sellAmount = sdk.toBig(amountIn ? amountIn : 0).div('1e' + tokenMap[sellSymbol].decimals)\n    const side =\n      settlementStatus === sdk.SETTLEMENT_STATUS.PAID\n        ? t(LABEL_INVESTMENT_STATUS_MAP.INVESTMENT_RECEIVED)\n        : Date.now() - expireTime >= 0 &&\n          investmentStatus !== LABEL_INVESTMENT_STATUS.CANCELLED &&\n          investmentStatus !== LABEL_INVESTMENT_STATUS.FAILED\n        ? t(LABEL_INVESTMENT_STATUS_MAP.DELIVERING)\n        : t(LABEL_INVESTMENT_STATUS_MAP.INVESTMENT_SUBSCRIBE)\n    const statusColor =\n      settlementStatus === sdk.SETTLEMENT_STATUS.PAID\n        ? 'var(--color-tag)'\n        : Date.now() - expireTime >= 0 &&\n          investmentStatus !== LABEL_INVESTMENT_STATUS.CANCELLED &&\n          investmentStatus !== LABEL_INVESTMENT_STATUS.FAILED\n        ? 'var(--color-warning)'\n        : 'var(--color-text-primary)'\n    let outSymbol: string | undefined = undefined,\n      outAmount\n\n    if (\n      (settlementStatus === sdk.SETTLEMENT_STATUS.PAID ||\n        (Date.now() - expireTime >= 0 &&\n          investmentStatus !== LABEL_INVESTMENT_STATUS.CANCELLED &&\n          investmentStatus !== LABEL_INVESTMENT_STATUS.FAILED)) &&\n      tokenOut !== undefined &&\n      tokenOut &&\n      tokenOut != 0\n    ) {\n      outSymbol = tokenMap[idIndex[tokenOut]].symbol\n      outAmount = getValuePrecisionThousand(\n        sdk.toBig(amountOut ? amountOut : 0).div('1e' + tokenMap[outSymbol].decimals),\n        tokenMap[outSymbol].precision,\n        tokenMap[outSymbol].precision,\n        tokenMap[outSymbol].precision,\n        false,\n      )\n    }\n    if (dualType === sdk.DUAL_TYPE.DUAL_BASE) {\n      lessEarnTokenSymbol = sellSymbol\n      greaterEarnTokenSymbol = buySymbol\n      lessEarnVol = sdk.toBig(settleRatio).plus(1).times(amountIn) //dualViewInfo.strike);\n      greaterEarnVol = sdk\n        .toBig(\n          sdk\n            .toBig(sellAmount ? sellAmount : 0)\n            .times(strike)\n            .toFixed(tokenMap[buySymbol].precision, BigNumber.ROUND_CEIL),\n        )\n        .times('1e' + tokenMap[buySymbol].decimals)\n    } else {\n      lessEarnTokenSymbol = buySymbol\n      greaterEarnTokenSymbol = sellSymbol\n      lessEarnVol = sdk\n        .toBig(\n          sdk\n            .toBig(sellAmount ? sellAmount : 0)\n            // .times(1 + info.ratio)\n            .div(strike)\n            .toFixed(tokenMap[buySymbol].precision, BigNumber.ROUND_CEIL),\n        )\n        .times('1e' + tokenMap[buySymbol].decimals)\n\n      // sellVol.times(1 + info.ratio).div(dualViewInfo.strike); //.times(1 + dualViewInfo.settleRatio);\n      greaterEarnVol = sdk.toBig(settleRatio).plus(1).times(amountIn)\n    }\n    const lessEarnView = amountIn\n      ? getValuePrecisionThousand(\n          sdk.toBig(lessEarnVol).div('1e' + tokenMap[lessEarnTokenSymbol].decimals),\n          tokenMap[lessEarnTokenSymbol].precision,\n          tokenMap[lessEarnTokenSymbol].precision,\n          tokenMap[lessEarnTokenSymbol].precision,\n          false,\n          { floor: true },\n        )\n      : EmptyValueTag\n    const greaterEarnView = amountIn\n      ? getValuePrecisionThousand(\n          sdk.toBig(greaterEarnVol).div('1e' + tokenMap[greaterEarnTokenSymbol].decimals),\n          tokenMap[greaterEarnTokenSymbol].precision,\n          tokenMap[greaterEarnTokenSymbol].precision,\n          tokenMap[greaterEarnTokenSymbol].precision,\n          false,\n          { floor: true },\n        )\n      : EmptyValueTag\n\n    const amount = getValuePrecisionThousand(\n      sellAmount,\n      tokenMap[sellSymbol].precision,\n      tokenMap[sellSymbol].precision,\n      tokenMap[sellSymbol].precision,\n      false,\n    )\n    switch (dualReinvestInfo.retryStatus) {\n      case sdk.DUAL_RETRY_STATUS.RETRY_SUCCESS:\n        icon = <CompleteIcon color={'success'} sx={{ paddingLeft: 1 / 2 }} />\n        status = 'labelDualRetryStatusSuccess'\n        content = 'labelDualRetrySuccess'\n        break\n      case sdk.DUAL_RETRY_STATUS.RETRY_FAILED:\n        icon = <WarningIcon color={'error'} sx={{ paddingLeft: 1 / 2 }} />\n        status = 'labelDualRetryStatusError'\n        content = 'labelDualRetryFailed'\n        break\n      case sdk.DUAL_RETRY_STATUS.NO_RETRY:\n        if (dualReinvestInfo?.isRecursive) {\n          content = 'labelDualAssetReInvestEnable'\n        } else if (\n          dualReinvestInfo.onceRecursive &&\n          settlementStatus === sdk.SETTLEMENT_STATUS.PAID &&\n          tokenIn !== tokenOut\n        ) {\n          icon = <WaitingIcon color={'primary'} sx={{ paddingLeft: 1 / 2 }} />\n          status = 'labelDualRetryStatusTerminated'\n          content = 'labelDualRetryTerminated'\n        } else {\n          content = 'labelDualAssetReInvestDisable'\n        }\n        break\n      case sdk.DUAL_RETRY_STATUS.RETRYING:\n        icon = <WaitingIcon color={'primary'} sx={{ paddingLeft: 1 / 2 }} />\n        status = 'labelDualRetryStatusRetrying'\n        content = 'labelDualRetryPending'\n        break\n      default:\n        content = dualReinvestInfo?.isRecursive\n          ? 'labelDualAssetReInvestEnable'\n          : 'labelDualAssetReInvestDisable'\n    }\n    return {\n      dualViewInfo: {\n        ...item?.__raw__?.order,\n        ...item,\n        quote: item?.__raw__?.order?.tokenInfoOrigin?.quote,\n        amount: amount + ' ' + sellSymbol,\n        currentPrice,\n        __raw__: item.__raw__,\n        outSymbol,\n        outAmount,\n        side,\n        status: settlementStatus,\n        statusColor,\n        maxDuration: dualReinvestInfo.maxDuration,\n        autoIcon: icon,\n        autoStatus: status,\n        autoContent: t(content),\n        newStrike: dualReinvestInfo.newStrike,\n        deliveryPrice:\n          Date.now() - expireTime >= 0\n            ? deliveryPrice\n              ? getValuePrecisionThousand(\n                  deliveryPrice,\n                  tokenMap[currentPrice.quote]?.precision,\n                  tokenMap[currentPrice.quote]?.precision,\n                  tokenMap[currentPrice.quote]?.precision,\n                  true,\n                  { isFait: true },\n                )\n              : EmptyValueTag\n            : undefined,\n      },\n\n      lessEarnTokenSymbol,\n      greaterEarnTokenSymbol,\n      lessEarnView,\n      greaterEarnView,\n      currentPrice,\n      __raw__: item.__raw__,\n    } as DualDetailType\n  }\n  const {\n    editDualTrade,\n    editDualBtnInfo,\n    editDualBtnStatus,\n    dualToastOpen,\n    closeDualToast,\n    // setDualTradeData,\n    handleOnchange,\n    onEditDualClick,\n  } = useDualEdit({\n    refresh: (item, dontCloseModal: boolean) => {\n      refresh((item as any).hash)\n      !dontCloseModal && setOpen(false)\n    },\n  })\n\n  const showDetail = async (item: R) => {\n    const {\n      __raw__: { index },\n    } = item\n    if (index) {\n      const _item = getDetail(item, index?.index)\n      setDetail(_item)\n      const tradeData = {\n        isRenew: _item?.__raw__?.order?.dualReinvestInfo?.isRecursive,\n        renewDuration: _item?.__raw__?.order?.dualReinvestInfo?.maxDuration / 86400000,\n        renewTargetPrice: _item?.__raw__?.order.dualReinvestInfo.newStrike,\n      }\n      updateEditDual({\n        ...(_item as any),\n        tradeData,\n      })\n      if (_item?.__raw__?.order?.dualReinvestInfo?.isRecursive) {\n        getProduct(_item)\n      }\n      handleOnchange({\n        tradeData,\n      })\n\n      setOpen(true)\n    }\n  }\n\n  const refresh = async (hash: string, _showDetail: boolean = false) => {\n    // const hash =\n    // const currentPrice = _item.currentPrice\n    setShowLoading(true)\n    try {\n      const { marketArray, marketMap: dualMarketMap } = store.getState().invest.dualMap\n      if (LoopringAPI.defiAPI && accountId && apiKey && marketArray?.length) {\n        const [response, responseTotal] = await Promise.all([\n          LoopringAPI.defiAPI.getDualTransactions(\n            {\n              accountId,\n              hashes: hash,\n            } as any,\n            apiKey,\n          ),\n          LoopringAPI.defiAPI.getDualUserLocked(\n            {\n              accountId: accountId,\n              lockTag: [DUAL_TYPE.DUAL_BASE, DUAL_TYPE.DUAL_CURRENCY],\n              //@ts-ignore\n              status: 'LOCKED',\n            },\n            apiKey,\n          ),\n        ])\n        if ((responseTotal as sdk.RESULT_INFO).code || (responseTotal as sdk.RESULT_INFO).message) {\n          setDualOnInvestAsset(undefined)\n        } else {\n          setDualOnInvestAsset(responseTotal.lockRecord)\n        }\n        if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n          const errorItem = SDK_ERROR_MAP_TO_UI[(response as sdk.RESULT_INFO)?.code ?? 700001]\n          if (setToastOpen) {\n            setToastOpen({\n              open: true,\n              type: ToastType.error,\n              content:\n                'error : ' + errorItem\n                  ? t(errorItem.messageKey)\n                  : (response as sdk.RESULT_INFO).message,\n            })\n          }\n        } else {\n          // @ts-ignore\n          let _item = (response as any)?.userDualTxs[0] as sdk.UserDualTxsHistory\n          const [, , coinA, coinB] =\n            (_item?.tokenInfoOrigin.market ?? 'dual-').match(/(dual-)?(\\w+)-(\\w+)/i) ?? []\n\n          let [sellTokenSymbol, buyTokenSymbol] =\n            _item.dualType === DUAL_TYPE.DUAL_BASE\n              ? [\n                  coinA ?? idIndex[_item.tokenInfoOrigin.tokenIn],\n                  coinB ?? idIndex[_item.tokenInfoOrigin.tokenOut],\n                ]\n              : [\n                  coinB ?? idIndex[_item.tokenInfoOrigin.tokenIn],\n                  coinA ?? idIndex[_item.tokenInfoOrigin.tokenOut],\n                ]\n          const indexes = response.indexes\n          const findIndex = indexes?.find((indexP) => {\n            return (\n              indexP.base === _item.tokenInfoOrigin.base &&\n              indexP.quote === _item.tokenInfoOrigin.quote\n            )\n          })\n          const market = dualMarketMap[_item.tokenInfoOrigin.market] as sdk.DefiMarketInfo\n          const currentPrice = {\n            base: idIndex[market.baseTokenId],\n            quote: idIndex[market.quoteTokenId],\n            currentPrice: findIndex?.index,\n            precisionForPrice: dualMarketMap[_item.tokenInfoOrigin.market]?.precisionForPrice,\n            quoteUnit: idIndex[market.quoteTokenId],\n          }\n          const format = makeDualOrderedItem(\n            _item,\n            sellTokenSymbol,\n            buyTokenSymbol,\n            currentPrice?.currentPrice ?? 0,\n            dualMarketMap[_item.tokenInfoOrigin.market],\n          )\n\n          const amount = getValuePrecisionThousand(\n            sdk\n              .toBig(_item.tokenInfoOrigin.amountIn)\n              .div('1e' + tokenMap[sellTokenSymbol].decimals),\n            tokenMap[sellTokenSymbol].precision,\n            tokenMap[sellTokenSymbol].precision,\n            tokenMap[sellTokenSymbol].precision,\n            true,\n          )\n          const refreshedRecord = {\n            ...format,\n            amount,\n          } as R\n          if (refreshedRecord.__raw__.order.id === detail?.__raw__.order.id || _showDetail) {\n            if (_showDetail && open == false) {\n              showDetail({\n                ...refreshedRecord,\n                __raw__: {\n                  ...refreshedRecord.__raw__,\n                  index: findIndex?.index,\n                },\n              })\n            } else {\n              setDetail(getDetail(refreshedRecord))\n            }\n          }\n          if (\n            refreshedRecord.__raw__.order.investmentStatus === sdk.LABEL_INVESTMENT_STATUS.CANCELLED\n          ) {\n            setDualList((state) => {\n              return state?.filter((x) => {\n                return x.__raw__.order.id !== refreshedRecord.__raw__.order.id\n              })\n            })\n            setRefreshErrorInfo([refreshedRecord.buySymbol, refreshedRecord.sellSymbol])\n            setShowRefreshError(true)\n            setShowLoading(false)\n          } else if (\n            refreshedRecord.__raw__.order.settlementStatus === sdk.SETTLEMENT_STATUS.SETTLED &&\n            !refreshedRecord.__raw__.order.dualReinvestInfo.isRecursive\n          ) {\n            setDualList((state) => {\n              return state?.filter((x) => {\n                return x.__raw__.order.id !== refreshedRecord.__raw__.order.id\n              })\n            })\n            setShowLoading(false)\n          } else {\n            setDualList((state) => {\n              return state.map((x) => {\n                return x.__raw__.order.id === refreshedRecord.__raw__.order.id\n                  ? {\n                      ...refreshedRecord,\n                      __raw__: {\n                        ...x.__raw__,\n                        ...refreshedRecord.__raw__,\n                      },\n                    }\n                  : x\n              })\n            })\n            setShowLoading(false)\n          }\n        }\n      }\n    } finally {\n      setShowLoading(false)\n    }\n  }\n\n  const getDualTxList = React.useCallback(\n    async ({ start, end, offset, limit = Limit }: any) => {\n      setShowLoading(true)\n      const { marketArray, marketMap: dualMarketMap } = store.getState().invest.dualMap\n      if (LoopringAPI.defiAPI && accountId && apiKey && marketArray?.length) {\n        const [response, responseTotal] = await Promise.all([\n          LoopringAPI.defiAPI.getDualTransactions(\n            {\n              accountId,\n              settlementStatuses: [sdk.SETTLEMENT_STATUS.UNSETTLED, sdk.SETTLEMENT_STATUS.SETTLED],\n              offset,\n              limit,\n              start,\n              end,\n              investmentStatuses: [\n                // sdk.LABEL_INVESTMENT_STATUS.FAILED,\n                sdk.LABEL_INVESTMENT_STATUS.CANCELLED,\n                sdk.LABEL_INVESTMENT_STATUS.SUCCESS,\n                sdk.LABEL_INVESTMENT_STATUS.PROCESSED,\n                sdk.LABEL_INVESTMENT_STATUS.PROCESSING,\n              ].join(','),\n              retryStatuses: [sdk.DUAL_RETRY_STATUS.RETRYING],\n            } as any,\n            apiKey,\n          ),\n          LoopringAPI.defiAPI.getDualUserLocked(\n            {\n              accountId: accountId,\n              lockTag: [DUAL_TYPE.DUAL_BASE, DUAL_TYPE.DUAL_CURRENCY],\n              //@ts-ignore\n              status: 'LOCKED',\n            },\n            apiKey,\n          ),\n        ])\n        if ((responseTotal as sdk.RESULT_INFO).code || (responseTotal as sdk.RESULT_INFO).message) {\n          setDualOnInvestAsset(undefined)\n        } else {\n          setDualOnInvestAsset(responseTotal.lockRecord)\n        }\n        if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n          const errorItem = SDK_ERROR_MAP_TO_UI[(response as sdk.RESULT_INFO)?.code ?? 700001]\n          if (setToastOpen) {\n            setToastOpen({\n              open: true,\n              type: ToastType.error,\n              content:\n                'error : ' + errorItem\n                  ? t(errorItem.messageKey)\n                  : (response as sdk.RESULT_INFO).message,\n            })\n          }\n        } else {\n          const indexes = response.indexes\n          let result = (response as any)?.userDualTxs.reduce(\n            (prev: RawDataDualAssetItem[], item: sdk.UserDualTxsHistory) => {\n              const [, , coinA, coinB] =\n                (item.tokenInfoOrigin.market ?? 'dual-').match(/(dual-)?(\\w+)-(\\w+)/i) ?? []\n              // [] =  item.tokenInfoOrigin.market\n              const findIndex = indexes?.find((_item) => {\n                return (\n                  _item.base === item.tokenInfoOrigin.base &&\n                  _item.quote === item.tokenInfoOrigin.quote\n                )\n              })\n              let [sellTokenSymbol, buyTokenSymbol] =\n                item.dualType === DUAL_TYPE.DUAL_BASE\n                  ? [\n                      coinA ?? idIndex[item.tokenInfoOrigin.tokenIn],\n                      coinB ?? idIndex[item.tokenInfoOrigin.tokenOut],\n                    ]\n                  : [\n                      coinB ?? idIndex[item.tokenInfoOrigin.tokenIn],\n                      coinA ?? idIndex[item.tokenInfoOrigin.tokenOut],\n                    ]\n              const format = makeDualOrderedItem(\n                item,\n                sellTokenSymbol,\n                buyTokenSymbol,\n                findIndex?.index ?? 0,\n                dualMarketMap[item.tokenInfoOrigin.market],\n              )\n\n              const amount = getValuePrecisionThousand(\n                sdk\n                  .toBig(item.tokenInfoOrigin.amountIn)\n                  .div('1e' + tokenMap[sellTokenSymbol].decimals),\n                tokenMap[sellTokenSymbol].precision,\n                tokenMap[sellTokenSymbol].precision,\n                tokenMap[sellTokenSymbol].precision,\n                true,\n              )\n              const market = dualMarketMap[item.tokenInfoOrigin.market] as sdk.DefiMarketInfo\n\n              const currentPrice = {\n                base: idIndex[market.baseTokenId],\n                quote: idIndex[market.quoteTokenId],\n                currentPrice: findIndex?.index,\n                precisionForPrice: dualMarketMap[item.tokenInfoOrigin.market]?.precisionForPrice,\n                quoteUnit: idIndex[market.quoteTokenId],\n              }\n\n              prev.push({\n                ...format,\n                amount,\n                currentPrice,\n                __raw__: {\n                  ...format.__raw__,\n                  currentPrice,\n                  index: findIndex,\n                },\n              })\n              return prev\n            },\n            [] as RawDataDualAssetItem[],\n          )\n          const filteredResult = (result as R[]).filter(\n            (x) => x.__raw__.order.investmentStatus !== sdk.LABEL_INVESTMENT_STATUS.CANCELLED,\n          )\n          setDualList(filteredResult)\n          setShowLoading(false)\n          setDualPagination({\n            pageSize: limit,\n            total: (response as any).totalNum,\n          })\n        }\n      }\n      setShowLoading(false)\n    },\n    [accountId, apiKey, setToastOpen, t, dualMarketMap, idIndex, tokenMap],\n  )\n  const [dualProducts, setDualProducts] = React.useState<DualViewInfo[]>([])\n  const getProduct = async (detail) => {\n    if (detail && detail.dualViewInfo) {\n      const { marketMap: dualMarketMap } = store.getState().invest.dualMap\n      const market =\n        detail.dualViewInfo.dualType === sdk.DUAL_TYPE.DUAL_BASE\n          ? detail.dualViewInfo.sellSymbol + '-' + detail.dualViewInfo.buySymbol\n          : detail.dualViewInfo.buySymbol + '-' + detail.dualViewInfo.sellSymbol\n      const dualMarket = dualMarketMap[`DUAL-${market}`]\n      const { dualType } = detail.dualViewInfo\n      const currency = dualMarket.currency\n      const baseSymbol = idIndex[dualMarket.baseTokenId]\n      const quoteSymbol = dualMarket.quoteAlias ?? idIndex[dualMarket.quoteTokenId]\n      const response = await LoopringAPI.defiAPI?.getDualInfos({\n        baseSymbol,\n        quoteSymbol,\n        currency: currency ?? '',\n        dualType,\n        startTime: Date.now() + 1000 * 60 * 60,\n        timeSpan: 1000 * 60 * 60 * 24 * 9,\n        limit: 50,\n      })\n\n      if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n        setDualProducts([])\n      } else {\n        const {\n          dualInfo: { infos, index },\n          raw_data: { rules },\n        } = response as any\n        const rule = rules[0]\n        const rawData = infos.map((item: sdk.DualProductAndPrice) => {\n          return makeDualViewItem(item, index, rule, baseSymbol, quoteSymbol, dualMarket)\n        })\n        setDualProducts(rawData)\n      }\n    } else {\n      setDualProducts([])\n    }\n  }\n  const cancelReInvest = React.useCallback((item) => {\n    updateEditDual({\n      ...item,\n      dualViewInfo: item,\n      tradeData: {\n        isRenew: false,\n      },\n    })\n    sdk.sleep(0).then(() => {\n      onEditDualClick()\n    })\n  }, [])\n  return {\n    getDetail,\n    showDetail,\n    dualList,\n    showLoading,\n    getDualTxList,\n    pagination,\n    open,\n    detail,\n    setOpen,\n    dualOnInvestAsset,\n    refresh,\n    setShowRefreshError,\n    showRefreshError,\n    refreshErrorInfo,\n    cancelReInvest,\n    dualProducts,\n    getProduct,\n    // onEdit,\n    dualToastOpen,\n    closeDualToast,\n    editDualTrade,\n    editDualBtnInfo,\n    editDualBtnStatus,\n    handleOnchange,\n    onEditDualClick,\n  }\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/AssetPage/RewardsPanel/hook.ts",
    "content": "import { ToastType } from '@loopring-web/component-lib'\nimport { ClaimCommands, claimServices, useAccount, useUserRewards } from '@loopring-web/core'\nimport { useTranslation } from 'react-i18next'\nimport React from 'react'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { CLAIM_TYPE, myLog, SagaStatus, SDK_ERROR_MAP_TO_UI } from '@loopring-web/common-resources'\n\nexport function useRewardsTable(setToastOpen: (state: any) => void) {\n  const {\n    account: { accountId, apiKey },\n  } = useAccount()\n  const { totalClaims, errorMessage, status: userRewardsStatus, getUserRewards } = useUserRewards()\n  const subject = React.useMemo(() => claimServices.onSocket(), [])\n\n  const { t } = useTranslation(['error'])\n  const [claimList, setClaimList] = React.useState(\n    Reflect.ownKeys(totalClaims ?? {}).map((key) => totalClaims[key]) ?? [],\n  )\n  const [showLoading, setShowLoading] = React.useState(false)\n  const getRewardsTableList = React.useCallback(async () => {\n    setShowLoading(true)\n    try {\n      myLog('totalClaims', totalClaims)\n      if (errorMessage) {\n      } else {\n        setClaimList(Reflect.ownKeys(totalClaims).map((key) => totalClaims[key]))\n      }\n    } catch (error) {\n      let errorItem\n      if (typeof (error as sdk.RESULT_INFO)?.code === 'number') {\n        errorItem = SDK_ERROR_MAP_TO_UI[(error as sdk.RESULT_INFO)?.code ?? 700001]\n      } else {\n        errorItem = SDK_ERROR_MAP_TO_UI[700012]\n      }\n      setToastOpen({\n        open: true,\n        type: ToastType.error,\n        content: 'error : ' + errorItem ? t(errorItem.messageKey) : (error as any)?.message,\n      })\n    }\n    setShowLoading(false)\n  }, [accountId, totalClaims, apiKey, setToastOpen, t])\n  React.useEffect(() => {\n    const subscription = subject.subscribe((props) => {\n      switch (props.status) {\n        case ClaimCommands.Success:\n          if (props?.data?.type == CLAIM_TYPE.allToken) {\n            getUserRewards()\n          }\n          break\n        default:\n          break\n      }\n    })\n    return () => {\n      subscription.unsubscribe()\n    }\n  }, [subject])\n  React.useEffect(() => {\n    if (userRewardsStatus === SagaStatus.UNSET) {\n      getRewardsTableList()\n    }\n  }, [userRewardsStatus])\n  return {\n    claimList,\n    showLoading,\n    errorMessage,\n    getRewardsTableList,\n    getUserRewards,\n  }\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/AssetPage/RewardsPanel/index.tsx",
    "content": "import { useTranslation, WithTranslation, withTranslation } from 'react-i18next'\nimport {\n  Button,\n  EarningsRow,\n  RewardsTable,\n  Toast,\n  ToastType,\n  useOpenModals,\n} from '@loopring-web/component-lib'\nimport React from 'react'\nimport { CLAIM_TYPE, TOAST_TIME, TRADE_TYPE } from '@loopring-web/common-resources'\n\nimport { StylePaper, useModalData, useSystem, useToast } from '@loopring-web/core'\n\nimport { useRewardsTable } from './hook'\nimport { Box } from '@mui/material'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nconst RewardsPanel = withTranslation('common')(\n  ({\n    hideAssets,\n  }: WithTranslation<'common'> & {\n    hideAssets?: boolean\n  }) => {\n    const { forexMap } = useSystem()\n    const { t } = useTranslation('common')\n    const { toastOpen, setToastOpen, closeToast } = useToast()\n    const { updateClaimData } = useModalData()\n    const { setShowClaimWithdraw } = useOpenModals()\n    const { claimList, showLoading, errorMessage, getUserRewards } = useRewardsTable(setToastOpen)\n    const container = React.useRef<HTMLDivElement>(null)\n\n    return (\n      <StylePaper ref={container} flex={1} marginTop={2}>\n        <Toast\n          alertText={toastOpen?.content ?? ''}\n          severity={toastOpen?.type ?? ToastType.success}\n          open={toastOpen?.open ?? false}\n          autoHideDuration={TOAST_TIME}\n          onClose={closeToast}\n        />\n\n        <Box className='tableWrapper table-divide-short'>\n          {errorMessage ? (\n            <Box\n              key={'empty'}\n              flexDirection={'column'}\n              display={'flex'}\n              justifyContent={'center'}\n              height={'100%'}\n              width={'100%'}\n              alignItems={'center'}\n            >\n              <Button\n                onClick={() => {\n                  getUserRewards()\n                }}\n                variant={'contained'}\n              >\n                {t('labelRewardRefresh')}\n              </Button>\n            </Box>\n          ) : (\n            <RewardsTable\n              forexMap={forexMap}\n              rawData={claimList}\n              hideAssets={hideAssets}\n              onItemClick={(item: EarningsRow) => {\n                // getUserRewards()\n                updateClaimData({\n                  belong: item.token.value,\n                  tradeValue: item.amountStr?.replaceAll(sdk.SEP, ''),\n                  balance: item.amountStr?.replaceAll(sdk.SEP, ''),\n                  volume: item.amount,\n                  tradeType: TRADE_TYPE.TOKEN,\n                  claimType: CLAIM_TYPE.allToken,\n                })\n                setShowClaimWithdraw({\n                  isShow: true,\n                  claimType: CLAIM_TYPE.allToken,\n                })\n              }}\n              onDetail={(item) => {}}\n              showloading={showLoading}\n            />\n          )}\n        </Box>\n      </StylePaper>\n    )\n  },\n)\n\nexport default RewardsPanel\n"
  },
  {
    "path": "packages/webapp/src/pages/AssetPage/index.tsx",
    "content": "import { useRouteMatch } from 'react-router-dom'\n\nimport { Box } from '@mui/material'\nimport { AssetTitleMobile, useSettings } from '@loopring-web/component-lib'\nimport { RouterPath } from '@loopring-web/common-resources'\n\nimport React from 'react'\nimport { useSystem, useTargetRedPackets, ViewAccountTemplate } from '@loopring-web/core'\nimport { useGetAssets } from './AssetPanel/hook'\nimport { AssetPanel } from './AssetPanel'\nimport { HistoryPanel } from './HistoryPanel'\n\nexport * from './HistoryPanel/hooks'\nexport const l2assetsRouter = `${RouterPath.l2assets}/:item`\nexport const AssetPage = () => {\n  let match: any = useRouteMatch(l2assetsRouter)\n  const selected = match?.params.item ?? 'assets'\n  const { forexMap } = useSystem()\n\n  const { assetTitleProps, assetTitleMobileExtendProps, assetBtnStatus, ...assetPanelProps } =\n    useGetAssets()\n  const { redPackets } = useTargetRedPackets()\n  const layer2Router = React.useMemo(() => {\n    switch (selected.toLowerCase()) {\n      case 'history':\n        return <HistoryPanel />\n      case 'assets':\n      default:\n        return (\n          <AssetPanel\n            showRedpacketReddot={redPackets ? redPackets?.length > 0 : false}\n            assetTitleProps={assetTitleProps}\n            assetPanelProps={{ ...assetPanelProps, assetBtnStatus }}\n          />\n        )\n    }\n  }, [selected, assetTitleProps, assetPanelProps, assetBtnStatus])\n  const { isMobile } = useSettings()\n  const activeView = React.useMemo(\n    () => (\n      <>\n        <Box\n          display={'flex'}\n          alignItems={'stretch'}\n          flexDirection={'column'}\n          marginTop={0}\n          flex={1}\n        >\n          {isMobile && (\n            <AssetTitleMobile\n              forexMap={forexMap}\n              assetBtnStatus={assetBtnStatus}\n              {...{ ...assetTitleProps, ...assetTitleMobileExtendProps }}\n            />\n          )}\n          {layer2Router}\n        </Box>\n      </>\n    ),\n    [assetTitleMobileExtendProps, assetTitleProps, isMobile, assetBtnStatus, layer2Router],\n  )\n  return <ViewAccountTemplate activeViewTemplate={activeView} />\n  // <>{viewTemplate}</>;\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/BtradeSwapPage/index.tsx",
    "content": "import { Box, Typography } from '@mui/material'\nimport { useTranslation, WithTranslation, withTranslation } from 'react-i18next'\nimport {\n  Button,\n  ConfirmBtradeSwapRisk,\n  EmptyDefault,\n  SwapPanel,\n  Toast,\n  ToastType,\n  useSettings,\n} from '@loopring-web/component-lib'\nimport {\n  myLog,\n  HelpIcon,\n  LOOPRING_DOCUMENT,\n  TOAST_TIME,\n  SoursURL,\n  ImageIcon,\n} from '@loopring-web/common-resources'\nimport { confirmation, useBtradeMap, useBtradeSwap, useNotify } from '@loopring-web/core'\nimport React from 'react'\nimport { useHistory } from 'react-router-dom'\nimport styled from '@emotion/styled'\n\nconst BoxStyle = styled(Box)`\n  &.btradePage {\n    .input-wrap {\n      input::placeholder {\n        font-size: 0.65em;\n      }\n    }\n  }\n`\nconst Content = withTranslation('common')(({ ...rest }: WithTranslation) => {\n  const { campaignTagConfig } = useNotify().notifyMap ?? {}\n  const { t } = useTranslation()\n  const {\n    toastOpen,\n    closeToast,\n    setToastOpen,\n    refreshRef,\n    tradeData,\n    tradeCalcData,\n    onSwapClick,\n    swapBtnStatus,\n    swapBtnI18nKey,\n    handleSwapPanelEvent,\n    isSwapLoading,\n    market,\n    should15sRefresh,\n    isMarketInit,\n  } = useBtradeSwap({ path: '/trade/btrade' })\n  return (\n    <Box>\n      <Box display={'flex'} justifyContent={'right'} marginBottom={1}>\n        <Box\n          onClick={() => {\n            window.open(`${LOOPRING_DOCUMENT}Block_Trade_tutorial_en.md`, '_blank')\n            window.opener = null\n          }}\n          sx={{ cursor: 'pointer' }}\n          display={'flex'}\n          color={'var(--color-text-secondary)'}\n          alignItems={'center'}\n        >\n          <HelpIcon fontSize={'large'} color={'inherit'} sx={{ marginRight: 1 / 2 }} />\n          <Typography variant={'h5'}>{t('labelTutorial')}</Typography>\n        </Box>\n      </Box>\n      {tradeData ? (\n        <SwapPanel\n          titleI8nKey={'labelBtradeSwapTitle'}\n          tokenBuyProps={{\n            disableInputValue: isMarketInit,\n            disabled: isSwapLoading || isMarketInit,\n            decimalsLimit: tradeCalcData.buyPrecision,\n          }}\n          tokenSellProps={{\n            disableInputValue: isMarketInit,\n            disabled: isSwapLoading || isMarketInit,\n            placeholderText:\n              tradeCalcData.sellMaxAmtStr && tradeCalcData.sellMaxAmtStr !== ''\n                ? t('labelBtradeSwapMiniMax', {\n                    minValue: tradeCalcData.sellMinAmtStr,\n                    maxValue: tradeCalcData.sellMaxAmtStr,\n                  })\n                : t('labelBtradeSwapMini', {\n                    minValue: tradeCalcData.sellMinAmtStr,\n                  }),\n          }}\n          campaignTagConfig={campaignTagConfig ?? ({} as any)}\n          market={market}\n          onRefreshData={should15sRefresh}\n          refreshRef={refreshRef}\n          tradeData={tradeData as any}\n          tradeCalcData={tradeCalcData as any}\n          onSwapClick={onSwapClick}\n          swapBtnI18nKey={swapBtnI18nKey}\n          swapBtnStatus={swapBtnStatus}\n          setToastOpen={setToastOpen}\n          hideSecondConfirmation\n          {...{ handleSwapPanelEvent, ...rest }}\n        />\n      ) : (\n        <Box\n          flex={1}\n          height={'100%'}\n          display={'flex'}\n          alignItems={'center'}\n          justifyContent={'center'}\n        >\n          <img className='loading-gif' width='36' src={`${SoursURL}images/loading-line.gif`} />\n        </Box>\n      )}\n\n      <Toast\n        alertText={toastOpen?.content ?? ''}\n        severity={toastOpen?.type ?? ToastType.success}\n        open={toastOpen?.open ?? false}\n        autoHideDuration={TOAST_TIME}\n        onClose={closeToast}\n      />\n    </Box>\n  )\n})\nexport const BtradeSwapPage = withTranslation('common')(({ t, ...rest }: WithTranslation) => {\n  const { marketMap, getBtradeMap } = useBtradeMap()\n\n  const {\n    confirmation: { confirmedBtradeSwap: confirmedBtradeSwapStore },\n    confirmedBtradeSwap: confirmedBtradeSwapFunc,\n  } = confirmation.useConfirmation()\n  const [_confirmedBtradeSwap, setConfirmedBtradeSwap] = React.useState<boolean>(\n    !confirmedBtradeSwapStore,\n  )\n\n  const { isMobile } = useSettings()\n  const { marketArray } = useBtradeMap()\n  const history = useHistory()\n\n  const styles = isMobile ? { flex: 1 } : { width: 'var(--swap-box-width)' }\n  myLog('marketArray', marketArray?.length)\n  return (\n    <BoxStyle\n      className={'btradePage'}\n      display={'flex'}\n      flexDirection={'column'}\n      justifyContent={'center'}\n      alignItems={'center'}\n      flex={1}\n    >\n      <Box\n        paddingBottom={isMobile ? 2 : 'initial'}\n        display={'flex'}\n        style={styles}\n        justifyContent={'center'}\n      >\n        {!marketArray?.length ||\n        !marketMap[marketArray[0]] ||\n        marketMap[marketArray[0]].enabled === 'isFormLocal' ? (\n          <Box\n            key={'empty'}\n            flexDirection={'column'}\n            display={'flex'}\n            justifyContent={'center'}\n            flex={1}\n            alignItems={'center'}\n          >\n            <EmptyDefault\n              emptyPic={\n                <img\n                  className='loading-gif'\n                  width='36'\n                  src={`${SoursURL}images/loading-line.gif`}\n                />\n              }\n              message={() => {\n                return (\n                  <Button onClick={getBtradeMap} variant={'contained'}>\n                    {t('labelBtradeRefresh')}\n                  </Button>\n                )\n              }}\n            />\n          </Box>\n        ) : (\n          <Content />\n        )}\n      </Box>\n\n      <ConfirmBtradeSwapRisk\n        open={_confirmedBtradeSwap}\n        handleClose={(_e, isAgree) => {\n          setConfirmedBtradeSwap(false)\n          if (!isAgree) {\n            history.replace('/markets')\n            // history.goBack();\n          } else {\n            confirmedBtradeSwapFunc()\n          }\n        }}\n      />\n    </BoxStyle>\n  )\n})\n"
  },
  {
    "path": "packages/webapp/src/pages/ErrorPage/index.tsx",
    "content": "import { Trans, useTranslation } from 'react-i18next'\nimport { Box, Container, Link, Typography } from '@mui/material'\nimport styled from '@emotion/styled'\nimport { ErrorObject, SoursURL } from '@loopring-web/common-resources'\nimport { getContactInfo } from '@loopring-web/core'\n\nconst StyleBox = styled(Box)`\n  background-image: url('${SoursURL}error_bg.png');\n  background-repeat: no-repeat;\n  background-size: contain;\n  background-position: bottom;\n  white-space: pre-wrap;\n  //h2{\n  //  position: relative;\n  //}\n` as typeof Box\n\nexport const ErrorPage = ({ messageKey, arg, components }: ErrorObject) => {\n  const message = `labelConnectUs`\n  return (\n    <>\n      <Container style={{ flex: 1 }}>\n        {/*style={{height: '100%' }}*/}\n        <StyleBox\n          flex={1}\n          display={'flex'}\n          alignItems={'flex-start'}\n          justifyContent={'center'}\n          flexDirection={'column'}\n          marginTop={4}\n          height={680}\n          maxWidth={1200}\n        >\n          {/*<StyleBox>*/}\n          <Box textAlign={'center'} position={'relative'} left={128} top={-64}>\n            <Typography component={'h2'} variant={'h3'} whiteSpace={'pre-line'}>\n              <Trans\n                i18nKey={messageKey}\n                tOptions={arg ? { ...arg } : undefined}\n                ns={['error', 'common']}\n                components={components ? { ...components } : undefined}\n              />\n            </Typography>\n            <Typography\n              marginY={2}\n              component={'p'}\n              variant={'body1'}\n              color={'textSecondary'}\n              whiteSpace={'pre-line'}\n            >\n              <Trans i18nKey={message}>\n                If you believe this is indeed a bug, please\n                <Link\n                  component={'a'}\n                  sx={{\n                    display: 'inline-flex',\n                  }}\n                  onClick={(e) => {\n                    window.open(getContactInfo(), '_blank')\n                    window.opener = null\n                    e.preventDefault()\n                  }}\n                >\n                  &nbsp; contact us\n                </Link>\n                <br /> We would appreciate your feedback\n              </Trans>\n            </Typography>\n          </Box>\n          {/*</StyleBox>*/}\n        </StyleBox>\n      </Container>\n\n      {/*<Footer></Footer>*/}\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/FiatPage/index.tsx",
    "content": "import { WithTranslation, withTranslation } from 'react-i18next'\nimport { BanxaConfirm, Button, useSettings, VendorMenu } from '@loopring-web/component-lib'\nimport React from 'react'\nimport {\n  banxaService,\n  offFaitService,\n  OrderENDReason,\n  RAMP_SELL_PANEL,\n  useBanxaConfirm,\n  useNotify,\n  useVendor,\n  ViewAccountTemplate,\n} from '@loopring-web/core'\nimport { Box, Grid, Tab, Tabs, Typography } from '@mui/material'\n\nimport {\n  BackIcon,\n  myLog,\n  SoursURL,\n  TradeTypes,\n  VendorProviders,\n} from '@loopring-web/common-resources'\nimport { useHistory, useRouteMatch } from 'react-router-dom'\nimport styled from '@emotion/styled'\n\nconst StyledPaper = styled(Grid)`\n  background: var(--color-box-third);\n  border-radius: ${({ theme }) => theme.unit}px;\n`\nexport const FiatPage = withTranslation('common')(\n  ({\n    t,\n  }: // vendorListBuy,\n  // vendorListSell,\n  // sellPanel,\n  // setSellPanel,\n  // banxaViewProps,\n  // offBanxaValue,\n  WithTranslation & {\n    // vendorListBuy: any;\n    // vendorListSell: any;\n    // banxaViewProps: any;\n    // offBanxaValue: any;\n    // sellPanel: RAMP_SELL_PANEL;\n    // setSellPanel: (value: RAMP_SELL_PANEL) => void;\n  }) => {\n    const history = useHistory()\n    // const { resetTransferRampData, resetTransferBanxaData } = useModalData();\n    const { campaignTagConfig } = useNotify().notifyMap ?? {}\n    const { vendorListBuy, vendorListSell, sellPanel, setSellPanel } = useVendor()\n    const { banxaViewProps, offBanxaValue } = useBanxaConfirm({\n      sellPanel,\n      setSellPanel,\n    })\n    const { isMobile } = useSettings()\n    const match: any = useRouteMatch('/trade/fiat/:tab?')\n    const [tabIndex, setTabIndex] = React.useState<TradeTypes>(\n      // TradeTypes.Buy\n      match?.params?.tab?.toLowerCase() === 'sell'.toLowerCase() ? TradeTypes.Sell : TradeTypes.Buy,\n    )\n    React.useEffect(() => {\n      setTabIndex((state) => {\n        return match?.params?.tab && state.toLowerCase() === match?.params?.tab.toLowerCase()\n          ? state\n          : match?.params?.tab?.toLowerCase() === 'sell'.toLowerCase()\n          ? TradeTypes.Sell\n          : TradeTypes.Buy\n      })\n    }, [match?.params?.tab])\n\n    const fiatView = React.useMemo(() => {\n      return (\n        <Box flex={1} flexDirection={'column'} display={'flex'}>\n          {/*<Box display={\"flex\"}>*/}\n          <Box>\n            <Tabs\n              variant={'scrollable'}\n              value={tabIndex}\n              onChange={(_e, value) => {\n                history.push(`/trade/fiat/${value}`)\n                setTabIndex(value)\n              }}\n            >\n              <Tab\n                value={TradeTypes.Buy}\n                label={\n                  <Typography\n                    display={'inline-flex'}\n                    alignItems={'center'}\n                    component={'span'}\n                    variant={'h5'}\n                    whiteSpace={'pre'}\n                    marginRight={1}\n                    className={'fiat-Title'}\n                  >\n                    {t('labelBuy')}\n                  </Typography>\n                }\n              />\n              <Tab\n                value={TradeTypes.Sell}\n                label={\n                  <Typography\n                    display={'inline-flex'}\n                    alignItems={'center'}\n                    component={'span'}\n                    variant={'h5'}\n                    whiteSpace={'pre'}\n                    marginRight={1}\n                    className={'fiat-Title'}\n                  >\n                    {t('labelSell')}\n                  </Typography>\n                }\n              />\n            </Tabs>\n          </Box>\n          <Box\n            flex={1}\n            component={'section'}\n            alignItems={'center'}\n            justifyContent={'center'}\n            marginTop={1}\n            display={'flex'}\n          >\n            <StyledPaper\n              width={isMobile ? '100%' : 'var(--modal-width)'}\n              paddingY={5 / 2}\n              flex={'initial '}\n            >\n              {tabIndex === TradeTypes.Buy && (\n                <VendorMenu\n                  type={TradeTypes.Buy}\n                  vendorList={vendorListBuy}\n                  vendorForce={undefined}\n                  campaignTagConfig={campaignTagConfig}\n                />\n              )}\n              {tabIndex === TradeTypes.Sell && (\n                <>\n                  {sellPanel === RAMP_SELL_PANEL.LIST && vendorListSell?.length ? (\n                    <VendorMenu\n                      type={TradeTypes.Sell}\n                      vendorList={vendorListSell}\n                      vendorForce={undefined}\n                      campaignTagConfig={campaignTagConfig}\n                    />\n                  ) : (\n                    <></>\n                  )}\n                  {sellPanel === RAMP_SELL_PANEL.BANXA_CONFIRM && (\n                    <Box flex={1} display={'flex'} flexDirection={'column'}>\n                      <Box marginBottom={2}>\n                        <Button\n                          startIcon={<BackIcon fontSize={'small'} />}\n                          variant={'text'}\n                          size={'medium'}\n                          sx={{ color: 'var(--color-text-secondary)' }}\n                          color={'inherit'}\n                          onClick={(e) => {\n                            offFaitService.offRampCancel({\n                              data: {\n                                product: VendorProviders.Banxa,\n                                orderId: offBanxaValue?.id,\n                                ...offBanxaValue,\n                              },\n                            })\n                            setSellPanel(RAMP_SELL_PANEL.LIST)\n\n                            const close = window.document.querySelector('#iframeBanxaClose')\n                            if (close) {\n                              close.dispatchEvent(new Event('click'))\n                            }\n                            banxaService.banxaEnd({\n                              reason: OrderENDReason.UserCancel,\n                              data: { resource: 'on close' },\n                            })\n                          }}\n                        >\n                          {t('labelBack')}\n                        </Button>\n                      </Box>\n                      {banxaViewProps ? (\n                        <BanxaConfirm {...{ ...banxaViewProps }} offBanxaValue={offBanxaValue} />\n                      ) : (\n                        <Box\n                          flex={1}\n                          display={'flex'}\n                          alignItems={'center'}\n                          justifyContent={'center'}\n                          height={'90%'}\n                        >\n                          <img\n                            className='loading-gif'\n                            alt={'loading'}\n                            width='36'\n                            src={`${SoursURL}images/loading-line.gif`}\n                          />\n                          {/*<LoadingIcon style={{ width: 32, height: 32 }} />*/}\n                        </Box>\n                      )}\n                    </Box>\n                  )}\n                  {/*{sellPanel === RAMP_SELL_PANEL.RAMP_CONFIRM && (*/}\n                  {/*  <Box flex={1} display={\"flex\"} flexDirection={\"column\"}>*/}\n                  {/*    <Box marginBottom={2}>*/}\n                  {/*      <Button*/}\n                  {/*        startIcon={<BackIcon fontSize={\"small\"} />}*/}\n                  {/*        variant={\"text\"}*/}\n                  {/*        size={\"medium\"}*/}\n                  {/*        sx={{ color: \"var(--color-text-secondary)\" }}*/}\n                  {/*        color={\"inherit\"}*/}\n                  {/*        onClick={() => {*/}\n                  {/*          if (window.rampInstance) {*/}\n                  {/*            window.rampInstance.close();*/}\n                  {/*          } else {*/}\n                  {/*            setSellPanel(RAMP_SELL_PANEL.LIST);*/}\n                  {/*            resetTransferRampData();*/}\n                  {/*          }*/}\n                  {/*        }}*/}\n                  {/*      >*/}\n                  {/*        {t(\"labelBack\")}*/}\n                  {/*      </Button>*/}\n                  {/*    </Box>*/}\n                  {/*    {rampViewProps ? (*/}\n                  {/*      <RampConfirm {...{ ...rampViewProps }} />*/}\n                  {/*    ) : (*/}\n                  {/*      <Box*/}\n                  {/*        flex={1}*/}\n                  {/*        display={\"flex\"}*/}\n                  {/*        alignItems={\"center\"}*/}\n                  {/*        justifyContent={\"center\"}*/}\n                  {/*        height={\"90%\"}*/}\n                  {/*      >*/}\n                  {/*        <img*/}\n                  {/*          className=\"loading-gif\"*/}\n                  {/*          alt={\"loading\"}*/}\n                  {/*          width=\"36\"*/}\n                  {/*          src={`${SoursURL}images/loading-line.gif`}*/}\n                  {/*        />*/}\n                  {/*        /!*<LoadingIcon style={{ width: 32, height: 32 }} />*!/*/}\n                  {/*      </Box>*/}\n                  {/*    )}*/}\n                  {/*  </Box>*/}\n                  {/*)}*/}\n                </>\n              )}\n            </StyledPaper>\n          </Box>\n        </Box>\n      )\n    }, [t, tabIndex, vendorListBuy, vendorListSell, offBanxaValue])\n    const activeView = React.useMemo(\n      () => (\n        <>\n          <Box\n            // minHeight={420}\n            display={'flex'}\n            alignItems={'stretch'}\n            flexDirection={'column'}\n            marginTop={0}\n            flex={1}\n          >\n            {fiatView}\n          </Box>\n        </>\n      ),\n      [fiatView],\n    )\n    return <ViewAccountTemplate activeViewTemplate={activeView} />\n  },\n)\n"
  },
  {
    "path": "packages/webapp/src/pages/InvestPage/DeFiPanel/DeFiTradePanel.tsx",
    "content": "import { confirmation, useDefiMap, useDefiTrade } from '@loopring-web/core'\nimport { DEFI_ADVICE_MAP, MarketType, myLog } from '@loopring-web/common-resources'\nimport { ConfirmDefiNOBalance, DeFiWrap, LoadingBlock } from '@loopring-web/component-lib'\nimport { Box } from '@mui/material'\nimport React from 'react'\nimport { useTranslation } from 'react-i18next'\n\nexport const DeFiTradePanel = ({\n  isJoin,\n  market,\n  setServerUpdate,\n  setToastOpen,\n}: {\n  market: MarketType\n  isJoin: boolean\n  setServerUpdate: (state: any) => void\n  setToastOpen: (state: any) => void\n}) => {\n  const { marketArray, marketMap } = useDefiMap()\n  myLog('isJoin', isJoin, 'market', market)\n  const [confirmShowLimitBalance, setConfirmShowLimitBalance] = React.useState<boolean>(false)\n  const [confirmShowNoBalance, setConfirmShowNoBalance] = React.useState<boolean>(false)\n  const { deFiWrapProps } = useDefiTrade({\n    isJoin,\n    setToastOpen: setToastOpen as any,\n    market: market ? market : marketArray[0], // marketArray[1] as MarketType,\n    setServerUpdate,\n    setConfirmShowNoBalance,\n    confirmShowLimitBalance,\n    setConfirmShowLimitBalance,\n    isLeverageETH: false,\n  })\n  const [, tokenBase] = market.match(/(\\w+)-(\\w+)/i) ?? []\n  const { t } = useTranslation()\n  const { setShowRETHStakePopup, setShowWSTETHStakePopup } = confirmation.useConfirmation()\n  return (\n    <>\n      {deFiWrapProps.deFiCalcData ? (\n        <Box\n          className={'hasLinerBg'}\n          display={'flex'}\n          sx={{\n            width: 'var(--modal-width)',\n            background: 'var(--color-box-third)',\n          }}\n          justifyContent={'center'}\n          padding={5 / 2}\n          bgcolor={'var(--color-box-third)'}\n        >\n          <DeFiWrap\n            market={market}\n            isJoin={isJoin}\n            setShowRETHStakePopup={setShowRETHStakePopup}\n            setShowWSTETHStakePopup={setShowWSTETHStakePopup}\n            // setShowLeverageETHPopup={setShowLeverageETHPopup}\n            type={DEFI_ADVICE_MAP[tokenBase].project}\n            title={DEFI_ADVICE_MAP[tokenBase].project}\n            {...(deFiWrapProps as any)}\n          />\n        </Box>\n      ) : (\n        <LoadingBlock />\n      )}\n      <ConfirmDefiNOBalance\n        isJoin={isJoin}\n        market={market}\n        type={DEFI_ADVICE_MAP[tokenBase].project}\n        handleClose={(_e) => {\n          setConfirmShowNoBalance(false)\n          if (deFiWrapProps?.onRefreshData) {\n            deFiWrapProps?.onRefreshData(true, true)\n          }\n        }}\n        isLeverage={false}\n        open={confirmShowNoBalance}\n      />\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/InvestPage/DeFiPanel/index.tsx",
    "content": "import React from 'react'\nimport styled from '@emotion/styled'\nimport { Avatar, Box, Card, CardContent, Grid, Tooltip, Typography } from '@mui/material'\nimport { useTranslation, WithTranslation, withTranslation } from 'react-i18next'\nimport { DeFiTradePanel } from './DeFiTradePanel'\nimport {\n  boxLiner,\n  Button,\n  ConfirmInvestDefiServiceUpdate,\n  Toast,\n  useSettings,\n  LoadingBlock,\n  ConfirmInvestDefiRisk,\n  ToastType,\n  MaxWidthContainer,\n} from '@loopring-web/component-lib'\nimport { confirmation, useDefiMap, useNotify, useToast } from '@loopring-web/core'\nimport { useHistory, useRouteMatch } from 'react-router-dom'\nimport {\n  BackIcon,\n  defiRETHAdvice,\n  defiWSTETHAdvice,\n  hexToRGB,\n  Info2Icon,\n  InvestAssetRouter,\n  InvestRouter,\n  InvestType,\n  MarketType,\n  RouterPath,\n  SatkingLogo,\n  TOAST_TIME,\n  UpColor,\n} from '@loopring-web/common-resources'\nimport { containerColors } from '..'\nimport { useTheme } from '@emotion/react'\n\nexport const StyleWrapper = styled(Box)`\n  position: relative;\n  border-radius: ${({ theme }) => theme.unit}px;\n\n  .loading-block {\n    background: initial;\n  }\n\n  .hasLinerBg {\n    ${({ theme }) => boxLiner({ theme })}\n  }\n\n  border-radius: ${({ theme }) => theme.unit}px;\n` as typeof Grid\nexport const StyleCardContent = styled(CardContent)`\n  display: flex;\n\n  &.tableLap {\n    display: block;\n    width: 100%;\n    cursor: pointer;\n\n    .content {\n      flex-direction: column;\n      align-items: center;\n      padding-top: ${({ theme }) => 4 * theme.unit}px;\n\n      .des {\n        align-items: center;\n        margin: ${({ theme }) => 3 * theme.unit}px 0;\n      }\n      .backIcon {\n        display: none;\n      }\n    }\n  }\n\n  padding: 0;\n  &:last-child {\n    padding: 0;\n  }\n\n  &.isMobile {\n    flex: 1;\n\n    .content {\n      flex-direction: row;\n      width: 100%;\n\n      .des {\n        margin-left: ${({ theme }) => 2 * theme.unit}px;\n        align-items: flex-start;\n      }\n    }\n  }\n` as typeof CardContent\n\nconst LandDefiInvest = ({\n  setConfirmedDefiInvest,\n}: {\n  setConfirmedDefiInvest: (props: { isShow: boolean; type: 'RETH' | 'WSETH' }) => void\n}) => {\n  const history = useHistory()\n  const { notifyMap } = useNotify()\n  const { marketMap: defiMarketMap } = useDefiMap()\n  const { t } = useTranslation('common')\n  const { isMobile, upColor } = useSettings()\n  const {\n    confirmation: { confirmedRETHDefiInvest, confirmedWSETHDefiInvest },\n  } = confirmation.useConfirmation()\n  const { marketArray } = useDefiMap()\n  const investAdviceList = [\n    {\n      ...defiWSTETHAdvice,\n      ...(notifyMap?.invest?.STAKE ? notifyMap?.invest?.STAKE[0] : {}),\n      click: () => {\n        if (!confirmedWSETHDefiInvest) {\n          setConfirmedDefiInvest({ isShow: true, type: 'WSETH' })\n        } else {\n          history.push(defiWSTETHAdvice.router + '/redeem')\n        }\n      },\n      apy: defiMarketMap[defiWSTETHAdvice?.market ?? '']?.apy,\n    },\n    {\n      ...defiRETHAdvice,\n      ...(notifyMap?.invest?.STAKE ? notifyMap?.invest?.STAKE[1] : {}),\n      click: () => {\n        if (!confirmedRETHDefiInvest) {\n          setConfirmedDefiInvest({ isShow: true, type: 'RETH' })\n        } else {\n          history.push(defiRETHAdvice.router + '/redeem')\n        }\n      },\n      apy: defiMarketMap[defiRETHAdvice?.market ?? '']?.apy,\n    },\n  ]\n\n  return (\n    <Box flex={1} display={'flex'} alignItems={'center'} alignSelf={'stretch'}>\n      <Grid container spacing={isMobile ? 2 : 4} padding={3} flex={1} justifyContent={'center'}>\n        {investAdviceList.map((item, index) => {\n          return (\n            <React.Fragment key={item.type + index}>\n              {item.enable && marketArray.includes(item?.market ?? '') ? (\n                <Grid item xs={12} md={4} lg={3}>\n                  <Card\n                    sx={{ display: 'flex', bgcolor: 'var(--color-box-third)' }}\n                    onClick={item.click}\n                  >\n                    <StyleCardContent className={isMobile ? 'isMobile' : 'tableLap'}>\n                      <Box\n                        className={'content'}\n                        display={'flex'}\n                        flexDirection={'row'}\n                        alignItems={'center'}\n                      >\n                        <Avatar\n                          variant='circular'\n                          style={{\n                            height: 'var(--svg-size-huge)',\n                            width: 'var(--svg-size-huge)',\n                          }}\n                          src={item.banner}\n                        />\n                        <Box\n                          flex={1}\n                          display={'flex'}\n                          flexDirection={'column'}\n                          paddingLeft={1}\n                          className={'des'}\n                        >\n                          <Typography variant={'h4'}>\n                            {t(item.titleI18n, { ns: 'layout' })}\n                          </Typography>\n                          <Typography\n                            variant={'body2'}\n                            textOverflow={'ellipsis'}\n                            whiteSpace={'pre'}\n                            overflow={'hidden'}\n                            color={'textSecondary'}\n                          >\n                            {t(item.desI18n, { ns: 'layout' })}\n                          </Typography>\n                          {isMobile ? (\n                            <Typography\n                              variant={'body1'}\n                              textOverflow={'ellipsis'}\n                              whiteSpace={'pre'}\n                              overflow={'hidden'}\n                              paddingTop={1}\n                              color={\n                                upColor === UpColor.green\n                                  ? 'var(--color-success)'\n                                  : 'var(--color-error)'\n                              }\n                            >\n                              {'APR: ' + item.apy + '%'}\n                            </Typography>\n                          ) : (\n                            <Typography\n                              display={'flex'}\n                              flexDirection={'column'}\n                              alignItems={'center'}\n                              marginTop={2}\n                              component={'span'}\n                            >\n                              <Typography\n                                variant={'h3'}\n                                component={'span'}\n                                color={\n                                  upColor === UpColor.green\n                                    ? 'var(--color-success)'\n                                    : 'var(--color-error)'\n                                }\n                              >\n                                {item.apy + '%'}\n                              </Typography>\n                              <Tooltip title={t('labelEstRateAprDes').toString()}>\n                                <Typography\n                                  variant={'body2'}\n                                  component={'span'}\n                                  display={'inline-flex'}\n                                  alignItems={'center'}\n                                  color={'var(--color-text-third)'}\n                                >\n                                  {t('labelEstRateApr')}\n                                  <Info2Icon color={'inherit'} sx={{ marginLeft: 1 / 2 }} />\n                                </Typography>\n                              </Tooltip>\n                            </Typography>\n                          )}\n                        </Box>\n                        {isMobile ? (\n                          <BackIcon\n                            className={'backIcon'}\n                            fontSize={'small'}\n                            htmlColor={'var(--color-text-third)'}\n                            sx={{\n                              transform: 'rotate(180deg)',\n                            }}\n                          />\n                        ) : (\n                          <Button variant={'contained'} fullWidth={true} size={'medium'}>\n                            Redeem\n                          </Button>\n                        )}\n                      </Box>\n                    </StyleCardContent>\n                  </Card>\n                </Grid>\n              ) : (\n                ''\n              )}\n            </React.Fragment>\n          )\n        })}\n      </Grid>\n    </Box>\n  )\n}\n\nconst ButtonStyled = styled(Button)`\n  background-color: var(--color-button-outlined);\n  color: var(--color-text-primary);\n  :hover {\n    background-color: var(--color-button-outlined);\n    ::before {\n      border-radius: 4px;\n    }\n  }\n`\nconst InvestRouterMatch = `${RouterPath.invest}/${InvestAssetRouter.STAKE}/:market?/:isJoin?`\n\nexport const DeFiPanel: any = withTranslation('common')(({ t }: WithTranslation & {}) => {\n  const match: any = useRouteMatch(InvestRouterMatch)\n\n  const { marketArray } = useDefiMap()\n\n  const {\n    confirmation: { confirmationNeeded, showRETHStakePopup, showWSTETHStakePopup },\n    setShowRETHStakePopup,\n    setShowWSTETHStakePopup,\n    confirmedRETHDefiInvest: confirmedRETHDefiInvestFun,\n    confirmedWSETHDefiInvest: confirmedWSETHDefiInvestFun,\n  } = confirmation.useConfirmation()\n\n  const _confirmedDefiInvest = {\n    isShow: showRETHStakePopup || showWSTETHStakePopup,\n    type: showRETHStakePopup ? 'RETH' : showWSTETHStakePopup ? 'WSETH' : undefined,\n    confirmationNeeded,\n  }\n  const setConfirmedDefiInvest = ({\n    isShow,\n    type,\n  }: {\n    isShow: boolean\n    type?: 'RETH' | 'WSETH' | undefined\n  }) => {\n    if (isShow) {\n      if (type === 'RETH') {\n        setShowRETHStakePopup({ isShow: true, confirmationNeeded: true })\n      } else {\n        setShowWSTETHStakePopup({ isShow: true, confirmationNeeded: true })\n      }\n    } else {\n      setShowRETHStakePopup({ isShow: false, confirmationNeeded: true })\n      setShowWSTETHStakePopup({ isShow: false, confirmationNeeded: true })\n    }\n  }\n\n  const [serverUpdate, setServerUpdate] = React.useState(false)\n  const { toastOpen, setToastOpen, closeToast } = useToast()\n  const history = useHistory()\n\n  const _market: MarketType = [...(marketArray ? marketArray : [])].find((_item) => {\n    if (match?.params?.market) {\n      //@ts-ignore\n      const [, , base] = _item.match(/(defi-)?(\\w+)(-\\w+)?/i)\n      //@ts-ignore\n      const [_base] = match?.params?.market?.split('-')\n      return base.toUpperCase() == _base.toUpperCase()\n    }\n  }) as MarketType\n  const isJoin = match?.params?.isJoin?.toUpperCase() !== 'Redeem'.toUpperCase()\n  const theme = useTheme()\n  const { isMobile } = useSettings()\n  const isMainView = !(match?.params?.market && _market)\n  const height = isMainView ? (isMobile ? 34 * theme.unit : 30 * theme.unit) : 6 * theme.unit\n\n  return (\n    <Box display={'flex'} flexDirection={'column'} flex={1}>\n      <MaxWidthContainer\n        display={'flex'}\n        sx={{ flexDirection: 'row' }}\n        justifyContent={'space-between'}\n        background={containerColors[0]}\n        alignItems={'center'}\n        containerProps={{\n          sx: {\n            borderBottom: isMainView ? '' : `1px solid ${hexToRGB(theme.colorBase.border, 0.5)}`,\n          },\n        }}\n      >\n        {isMainView ? (\n          <Box\n            display={'flex'}\n            justifyContent={'space-between'}\n            alignItems={'center'}\n            width={'100%'}\n          >\n            <Box>\n              <Typography fontSize={'38px'} variant={'h1'}>\n                {t('labelInvestDefiTitle')}\n              </Typography>\n            </Box>\n            {!isMobile && <SatkingLogo />}\n          </Box>\n        ) : (\n          <Box\n            width={'100%'}\n            display={'flex'}\n            alignItems={'center'}\n            paddingY={2}\n          >\n            <Button\n              startIcon={<BackIcon htmlColor={'var(--color-text-primary)'} fontSize={'small'} />}\n              variant={'text'}\n              size={'medium'}\n              sx={{ color: 'var(--color-text-primary)' }}\n              color={'inherit'}\n              onClick={() => history.push(`${RouterPath.invest}/${InvestAssetRouter.STAKE}`)}\n            >\n              {t('labelInvestDefiTitle')}\n            </Button>\n          </Box>\n        )}\n      </MaxWidthContainer>\n\n      <MaxWidthContainer\n        // height={isMainView ? 'calc(100vh - 360px)' : 'calc(100vh - 180px)'}\n        background={isMainView ? containerColors[1] : 'transparent'}\n        containerProps={{ sx: { flex: 1 } }}\n      >\n        <StyleWrapper\n          display={'flex'}\n          flexDirection={'column'}\n          justifyContent={'center'}\n          alignItems={'center'}\n          flex={1}\n          paddingTop={4}\n          paddingBottom={4}\n        >\n          {marketArray?.length ? (\n            match?.params?.market && _market ? (\n              <DeFiTradePanel\n                market={_market}\n                isJoin={isJoin}\n                setServerUpdate={setServerUpdate}\n                setToastOpen={setToastOpen}\n              />\n            ) : (\n              <LandDefiInvest setConfirmedDefiInvest={setConfirmedDefiInvest} />\n            )\n          ) : (\n            <LoadingBlock />\n          )}\n          <Toast\n            alertText={toastOpen?.content ?? ''}\n            severity={toastOpen?.type ?? ToastType.success}\n            open={toastOpen?.open ?? false}\n            autoHideDuration={TOAST_TIME}\n            onClose={closeToast}\n          />\n\n          <ConfirmInvestDefiServiceUpdate\n            open={serverUpdate}\n            handleClose={() => setServerUpdate(false)}\n          />\n          <ConfirmInvestDefiRisk\n            open={_confirmedDefiInvest.isShow}\n            type={_confirmedDefiInvest.type as any}\n            confirmationNeeded={confirmationNeeded}\n            handleClose={(_e, isAgree) => {\n              if (!isAgree) {\n                setConfirmedDefiInvest({ isShow: false })\n              } else {\n                if (_confirmedDefiInvest.type === 'RETH') {\n                  confirmedRETHDefiInvestFun()\n                  history.push(defiRETHAdvice.router)\n                }\n                if (_confirmedDefiInvest.type === 'WSETH') {\n                  confirmedWSETHDefiInvestFun()\n                  history.push(defiWSTETHAdvice.router)\n                }\n              }\n              setConfirmedDefiInvest({ isShow: false })\n            }}\n          />\n        </StyleWrapper>\n      </MaxWidthContainer>\n    </Box>\n  )\n})\n"
  },
  {
    "path": "packages/webapp/src/pages/InvestPage/DualPanel/BeginnerMode.tsx",
    "content": "import styled from '@emotion/styled'\nimport { Avatar, Box, CardContent, Tab, Tabs, Typography } from '@mui/material'\nimport { Trans, WithTranslation, withTranslation } from 'react-i18next'\nimport {\n  CoinIcon,\n  CoinIcons,\n  DualTable,\n  useOpenModals,\n  useSettings,\n  TickCardStyleItem,\n} from '@loopring-web/component-lib'\nimport { useDualMap, useSystem, useTokenMap } from '@loopring-web/core'\nimport {\n  DualGain,\n  DualDip,\n  DualBegin,\n  DualViewType,\n  getValuePrecisionThousand,\n  SoursURL,\n  TokenType,\n  DualBTC,\n} from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { DUAL_TYPE } from '@loopring-web/loopring-sdk'\nimport { useTheme } from '@emotion/react'\nimport React from 'react'\nimport _ from 'lodash'\nimport { useRouteMatch } from 'react-router-dom'\n\nconst WrapperStyled = styled(Box)`\n  .MuiTab-root.Mui-selected,\n  .MuiTab-root:hover {\n    &:after {\n      visibility: hidden;\n    }\n  }\n  .mainContent {\n    flex: 1;\n    display: flex;\n    flex-direction: column;\n    background: var(--color-box);\n    border-radius: ${({ theme }) => theme.unit}px;\n  }\n`\nexport const ViewStepType = {\n  [DualViewType.DualGain]: DualGain,\n  [DualViewType.DualDip]: DualDip,\n  [DualViewType.DualBegin]: DualBegin,\n  [DualViewType.DualBTC]: DualBTC,\n}\n\nexport const BeginnerMode: any = withTranslation('common')(\n  ({\n    t,\n    dualListProps,\n    viewType,\n  }: WithTranslation & {\n    dualListProps: any\n    viewType: DualViewType\n  }) => {\n    const viewStepType = ViewStepType[viewType]\n    const theme = useTheme()\n    const { tradeMap } = useDualMap()\n    const { coinJson } = useSettings()\n    const { forexMap } = useSystem()\n    const { tokenMap } = useTokenMap()\n    const { setShowDual } = useOpenModals()\n    const {\n      pairASymbol,\n      pairBSymbol,\n      isLoading,\n      dualProducts,\n      currentPrice,\n      market,\n      baseTokenList,\n      step1SelectedToken,\n      step2BuyOrSell,\n      step3Token,\n      onSelectStep1Token,\n      onSelectStep2BuyOrSell,\n      onSelectStep3Token,\n      isDualBalanceSufficient,\n    } = dualListProps\n    const { isMobile } = useSettings()\n    const { marketArray } = useDualMap()\n    const tokenList: any[] = Object.values(baseTokenList ?? {})?.sort((a: any, b: any) =>\n      a?.tokenName?.toString().localeCompare(b?.tokenName?.toString()),\n    )\n    const dualType =\n      step2BuyOrSell === 'Sell' ? sdk.DUAL_TYPE.DUAL_BASE : sdk.DUAL_TYPE.DUAL_CURRENCY\n    const step3Ref = React.useRef(null)\n    const tableRef = React.useRef(null)\n    const quoteList = _.cloneDeep(tradeMap[step1SelectedToken ?? '']?.tokenList ?? [])\n    // const last = quoteList.pop()\n    const scroolStep3ToMiddle = () => {\n      setTimeout(() => {\n        const element = step3Ref.current as any\n        const elementRect = element.getBoundingClientRect()\n        const absoluteElementTop = elementRect.top + window.pageYOffset\n        const middle = absoluteElementTop - window.innerHeight / 2\n        window.scrollTo(0, middle)\n      }, 100)\n    }\n    const scroolTableToMiddle = () => {\n      setTimeout(() => {\n        const element = tableRef.current as any\n        const elementRect = element.getBoundingClientRect()\n        const absoluteElementTop = elementRect.top + window.pageYOffset\n        const middle = absoluteElementTop - window.innerHeight / 2\n        window.scrollTo(0, middle)\n      }, 100)\n    }\n    return (\n      <WrapperStyled display={'flex'} flexDirection={'column'} flex={1} marginBottom={2}>\n        <Box marginBottom={5}>\n          <Typography marginBottom={2} display={'flex'} variant={'h4'}>\n            {t(viewStepType[0].labelKey)}\n          </Typography>\n          <Tabs\n            value={step1SelectedToken}\n            onChange={(_event, value) => onSelectStep1Token(value)}\n            aria-label='l2-history-tabs'\n            variant='scrollable'\n            sx={{\n              display: 'flex',\n              flexWrap: 'nowrap',\n            }}\n          >\n            {tokenList?.map(({ tokenName, minAPY, maxAPY }: any) => {\n              return (\n                <Tab\n                  value={tokenName}\n                  key={tokenName}\n                  label={\n                    <TickCardStyleItem\n                      selected={tokenName == step1SelectedToken}\n                      className={'dualInvestCard btnCard'}\n                      sx={{\n                        minWidth: isMobile ? '180px' : '280px',\n                      }}\n                    >\n                      <CardContent>\n                        <Typography component={'span'} display={'inline-flex'}>\n                          <CoinIcon\n                            size={32}\n                            symbol={typeof tokenName === 'string' ? tokenName : ''}\n                          />\n                        </Typography>\n                        <Typography paddingLeft={1} display={'flex'} flexDirection={'column'}>\n                          <Typography component={'span'} textAlign={'left'} variant={'subtitle1'}>\n                            {tokenName?.toString()}\n                          </Typography>\n                          <Typography\n                            component={'span'}\n                            variant={'body2'}\n                            color={theme.colorBase.textSecondary}\n                          >\n                            {t('labelDualBeginnerAPR', {\n                              APR:\n                                !minAPY && !maxAPY\n                                  ? '--'\n                                  : minAPY === maxAPY || !minAPY || !maxAPY\n                                  ? `${getValuePrecisionThousand(\n                                      Number(minAPY) * 100,\n                                      2,\n                                      2,\n                                      2,\n                                      true,\n                                    )}%`\n                                  : `${getValuePrecisionThousand(\n                                      Number(minAPY) * 100,\n                                      2,\n                                      2,\n                                      2,\n                                      true,\n                                    )}% - ${getValuePrecisionThousand(\n                                      Number(maxAPY) * 100,\n                                      2,\n                                      2,\n                                      2,\n                                      true,\n                                    )}%`,\n                            })}\n                          </Typography>\n                        </Typography>\n                      </CardContent>\n                    </TickCardStyleItem>\n                  }\n                />\n              )\n            })}\n          </Tabs>\n        </Box>\n\n        {step1SelectedToken !== undefined && viewType === DualViewType.DualBegin && (\n          <Box marginBottom={5}>\n            <Typography marginBottom={2} display={'flex'} variant={'h4'}>\n              {t('labelDualBeginnerStep2Title')}\n            </Typography>\n            <Box display={'flex'} flexDirection={'row'}>\n              <Box marginRight={2}>\n                <TickCardStyleItem\n                  className={\n                    step2BuyOrSell === 'Sell'\n                      ? 'btnCard dualInvestCard selected'\n                      : 'btnCard dualInvestCard '\n                  }\n                  selected={step2BuyOrSell === 'Sell'}\n                  onClick={() => {\n                    onSelectStep2BuyOrSell('Sell')\n                    scroolStep3ToMiddle()\n                  }}\n                  width={'310px'}\n                >\n                  <CardContent\n                  // sx={{\n                  //   alignItems: 'center',\n                  //   // paddingX: 3,\n                  //   // paddingY: 2,\n                  //   // '&:last-child': { paddingY: 2 },\n                  // }}\n                  >\n                    <Typography component={'span'} display={'inline-flex'}>\n                      <Avatar alt={'sell-high'} src={SoursURL + '/svg/sell-high.svg'} />\n                    </Typography>\n                    <Typography paddingLeft={1}>\n                      <Typography color={theme.colorBase.textPrimary} variant={'subtitle1'}>\n                        {t('labelDualBeginnerSellHigh', {\n                          token: step1SelectedToken,\n                        })}\n                      </Typography>\n                      <Typography variant={'body2'} color={theme.colorBase.textSecondary}>\n                        {t('labelDualBeginnerReceiveStable', {\n                          ...(quoteList?.length > 1\n                            ? {\n                                last: t('labelDualBeginnerLast', {\n                                  last: quoteList[quoteList.length - 1],\n                                }),\n                                list: [...quoteList.slice(0, quoteList.length - 1)].join(', '),\n                              }\n                            : {\n                                last: '',\n                                list: [...quoteList].join(', '),\n                              }),\n                        })}\n                      </Typography>\n                    </Typography>\n                  </CardContent>\n                </TickCardStyleItem>\n              </Box>\n              <Box marginLeft={2}>\n                <TickCardStyleItem\n                  className={\n                    step2BuyOrSell === 'Buy'\n                      ? 'btnCard dualInvestCard selected'\n                      : 'btnCard dualInvestCard '\n                  }\n                  selected={step2BuyOrSell === 'Buy'}\n                  onClick={() => {\n                    onSelectStep2BuyOrSell('Buy')\n                    scroolStep3ToMiddle()\n                  }}\n                  width={'310px'}\n                >\n                  <CardContent\n                  // sx={{\n                  //   alignItems: 'center',\n                  //   // paddingX: 3,\n                  //   // paddingY: 2,\n                  //   // '&:last-child': { paddingY: 2 },\n                  // }}\n                  >\n                    <Typography component={'span'} display={'inline-flex'}>\n                      <Avatar alt={'buy-low'} src={SoursURL + '/svg/buy-low.svg'} />\n                    </Typography>\n                    <Typography paddingLeft={1}>\n                      <Typography color={theme.colorBase.textPrimary} variant={'subtitle1'}>\n                        {t('labelDualBeginnerBuyLow', {\n                          token: step1SelectedToken,\n                        })}\n                      </Typography>\n                      <Typography variant={'body2'} color={theme.colorBase.textSecondary}>\n                        {t('labelDualBeginnerInvestStable', {\n                          ...(quoteList?.length > 1\n                            ? {\n                                last: t('labelDualBeginnerLast', {\n                                  last: quoteList[quoteList.length - 1],\n                                }),\n                                list: [...quoteList.slice(0, quoteList.length - 1)].join(', '),\n                              }\n                            : {\n                                last: '',\n                                list: [...quoteList].join(', '),\n                              }),\n                        })}\n                      </Typography>\n                    </Typography>\n                  </CardContent>\n                </TickCardStyleItem>\n              </Box>\n            </Box>\n          </Box>\n        )}\n\n        {step1SelectedToken !== undefined && step2BuyOrSell !== undefined && (\n          <Box ref={step3Ref} marginBottom={2}>\n            <Typography marginBottom={2} display={'flex'} variant={'h4'}>\n              {t(viewStepType[2].labelKey)}\n            </Typography>\n\n            <Tabs\n              value={step3Token}\n              onChange={(_event, value) => {\n                if (isLoading) return\n                onSelectStep3Token(value)\n                scroolTableToMiddle()\n              }}\n              aria-label='l2-history-tabs'\n              variant='scrollable'\n              sx={{\n                display: 'flex',\n                flexWrap: 'nowrap',\n              }}\n            >\n              {tradeMap[step1SelectedToken ?? '']?.quoteList?.map((token) => {\n                return (\n                  <Tab\n                    value={token}\n                    key={token}\n                    label={\n                      <TickCardStyleItem\n                        selected={step3Token == token}\n                        className={'dualInvestCard btnCard'}\n                        sx={{\n                          minWidth: isMobile ? '180px' : '280px',\n                        }}\n                      >\n                        <CardContent\n                          sx={{\n                            alignItems: 'center',\n                            paddingX: 3,\n                            paddingY: 2,\n                            '&:last-child': { paddingY: 2 },\n                          }}\n                        >\n                          <Typography component={'span'} display={'inline-flex'}>\n                            <CoinIcon size={32} symbol={token} />\n                          </Typography>\n                          <Typography\n                            color={theme.colorBase.textPrimary}\n                            variant={'subtitle1'}\n                            paddingLeft={1}\n                          >\n                            {step2BuyOrSell === 'Buy'\n                              ? t('labelDualBeginnerBuyLowWith', { token: token })\n                              : t('labelDualBeginnerSellHighFor', {\n                                  token: token,\n                                })}\n                          </Typography>\n                        </CardContent>\n                      </TickCardStyleItem>\n                    }\n                  />\n                )\n              })}\n            </Tabs>\n          </Box>\n        )}\n        {step3Token !== undefined && step1SelectedToken !== undefined && (\n          <Box\n            className={'mainContent'}\n            ref={tableRef}\n            marginTop={1}\n            flex={1}\n            flexDirection={'column'}\n          >\n            {pairASymbol && pairBSymbol && market && (\n              <Box\n                display={'flex'}\n                flexDirection={'row'}\n                paddingTop={3}\n                paddingX={3}\n                justifyContent={'space-between'}\n                alignItems={'center'}\n              >\n                <Box component={'h3'} display={'flex'} flexDirection={'row'} alignItems={'center'}>\n                  <Typography component={'span'} display={'inline-flex'}>\n                    {/* eslint-disable-next-line react/jsx-no-undef */}\n                    <CoinIcons\n                      type={TokenType.dual}\n                      size={32}\n                      tokenIcon={[coinJson[pairASymbol], coinJson[pairBSymbol]]}\n                    />\n                  </Typography>\n                  <Typography component={'span'} flexDirection={'column'} display={'flex'}>\n                    <Typography component={'span'} display={'inline-flex'} color={'textPrimary'}>\n                      {t(\n                        dualType === DUAL_TYPE.DUAL_BASE\n                          ? 'labelDualInvestBaseTitle'\n                          : 'labelDualInvestQuoteTitle',\n                        {\n                          symbolA: pairASymbol,\n                          symbolB: pairBSymbol,\n                        },\n                      )}\n                    </Typography>\n                    {isDualBalanceSufficient === undefined ? (\n                      <Typography\n                        component={'span'}\n                        display={'inline-flex'}\n                        color={'textSecondary'}\n                        variant={'body2'}\n                      >\n                        &nbsp;\n                      </Typography>\n                    ) : isDualBalanceSufficient === true ? (\n                      <Typography\n                        component={'span'}\n                        display={'inline-flex'}\n                        color={'textSecondary'}\n                        variant={'body2'}\n                      >\n                        {t('labelDualInvestDes', {\n                          symbolA: pairASymbol,\n                          symbolB: pairBSymbol,\n                        })}\n                      </Typography>\n                    ) : (\n                      <Typography\n                        component={'span'}\n                        display={'inline-flex'}\n                        color={'var(--color-warning)'}\n                        variant={'body2'}\n                      >\n                        {t('labelDualInvestDesInsufficient')}\n                      </Typography>\n                    )}\n                  </Typography>\n                </Box>\n                <Typography\n                  component={'span'}\n                  display={isMobile ? 'flex' : 'inline-flex'}\n                  color={'textSecondary'}\n                  variant={'body2'}\n                  flexDirection={isMobile ? 'column' : 'row'}\n                  alignItems={'center'}\n                  whiteSpace={'pre-wrap'}\n                >\n                  {currentPrice &&\n                    (!isMobile ? (\n                      <Trans\n                        i18nKey={'labelDualCurrentPrice'}\n                        tOptions={{\n                          price:\n                            // PriceTag[CurrencyToTag[currency]] +\n                            getValuePrecisionThousand(\n                              currentPrice.currentPrice,\n                              currentPrice.precisionForPrice\n                                ? currentPrice.precisionForPrice\n                                : tokenMap[currentPrice.quote].precisionForOrder,\n                              currentPrice.precisionForPrice\n                                ? currentPrice.precisionForPrice\n                                : tokenMap[currentPrice.quote].precisionForOrder,\n                              currentPrice.precisionForPrice\n                                ? currentPrice.precisionForPrice\n                                : tokenMap[currentPrice.quote].precisionForOrder,\n                              true,\n                              { floor: true },\n                            ),\n                          symbol: currentPrice.base,\n                          baseSymbol: /USD/gi.test(currentPrice.quoteUnit ?? '')\n                            ? 'USDT'\n                            : currentPrice.quoteUnit,\n                        }}\n                      >\n                        LRC Current price:\n                        <Typography\n                          component={'span'}\n                          display={'inline-flex'}\n                          color={'textPrimary'}\n                          paddingLeft={1}\n                        >\n                          price\n                        </Typography>\n                        :\n                      </Trans>\n                    ) : (\n                      <>\n                        <Typography\n                          component={'span'}\n                          color={'textSecondary'}\n                          variant={'body2'}\n                          textAlign={'right'}\n                        >\n                          {t('labelDualMobilePrice', {\n                            symbol: currentPrice.base,\n                          })}\n                        </Typography>\n                        <Typography\n                          textAlign={'right'}\n                          component={'span'}\n                          display={'inline-flex'}\n                          color={'textPrimary'}\n                          paddingLeft={1}\n                        >\n                          {getValuePrecisionThousand(\n                            currentPrice.currentPrice,\n                            currentPrice.precisionForPrice\n                              ? currentPrice.precisionForPrice\n                              : tokenMap[currentPrice.quote].precisionForOrder,\n                            currentPrice.precisionForPrice\n                              ? currentPrice.precisionForPrice\n                              : tokenMap[currentPrice.quote].precisionForOrder,\n                            currentPrice.precisionForPrice\n                              ? currentPrice.precisionForPrice\n                              : tokenMap[currentPrice.quote].precisionForOrder,\n                            true,\n                            { floor: true },\n                          )}\n                        </Typography>\n                      </>\n                    ))}\n                </Typography>\n              </Box>\n            )}\n            <Box flex={1}>\n              <DualTable\n                rawData={dualProducts ?? []}\n                showloading={isLoading}\n                forexMap={forexMap as any}\n                onItemClick={(item) => {\n                  setShowDual({\n                    isShow: true,\n                    dualInfo: {\n                      ...item,\n                      sellSymbol: pairASymbol!,\n                      buySymbol: pairBSymbol!,\n                    },\n                  })\n                }}\n              />\n            </Box>\n          </Box>\n        )}\n      </WrapperStyled>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/webapp/src/pages/InvestPage/DualPanel/ChooseDualType.tsx",
    "content": "import { Box, Grid, Typography } from '@mui/material'\nimport {\n  DualViewType,\n  LOOPRING_DOCUMENT,\n  DualInvestmentLogo,\n  RouterPath,\n  InvestRouter,\n  InvestType,\n  SwapSettingIcon,\n} from '@loopring-web/common-resources'\nimport {\n  Button,\n  MenuBtnStyled,\n  useSettings,\n  MaxWidthContainer,\n  IconButtonStyled,\n} from '@loopring-web/component-lib'\nimport React from 'react'\nimport { useTranslation } from 'react-i18next'\nimport styled from '@emotion/styled'\nimport { containerColors } from '../index'\nimport { useHistory } from 'react-router-dom'\nimport { useTheme } from '@emotion/react'\nimport { confirmation, useDualMap } from '@loopring-web/core'\nimport { ChooseDualTypeContentType } from './hook'\n\nexport const TypographyStyle = styled(Typography)`\n  svg {\n    fill: ${({ theme }) => theme.colorBase.textSecondary};\n  }\n` as typeof Typography\nexport const ChooseDualType = ({\n  onSelect,\n  chooseDualTypeContent,\n}: {\n  chooseDualTypeContent: ChooseDualTypeContentType[]\n  onSelect: (props: DualViewType) => void\n}) => {\n  const { isMobile } = useSettings()\n  const theme = useTheme()\n  const history = useHistory()\n  const { t } = useTranslation()\n  const { setShowAutoDefault } = confirmation.useConfirmation()\n  return (\n    <>\n      <MaxWidthContainer\n        sx={{ flexDirection: 'row' }}\n        display={'flex'}\n        justifyContent={'space-between'}\n        background={containerColors[0]}\n        height={isMobile ? 60 * theme.unit : 30 * theme.unit}\n        alignItems={'center'}\n      >\n        <Box paddingY={7}>\n          <Typography marginBottom={2} fontSize={'38px'} variant={'h1'}>\n            {t('labelInvestDualTitle')}\n          </Typography>\n          <Box display={'flex'} alignItems={'center'}>\n            <Button\n              onClick={() =>\n                history.push(`${RouterPath.invest}/${InvestRouter[InvestType.MyBalance]}`)\n              }\n              sx={{ width: isMobile ? 36 * theme.unit : 18 * theme.unit }}\n              variant={'contained'}\n            >\n              {t('labelInvestMyDual')}\n            </Button>\n\n            <Button\n              onClick={() => {\n                window.open(`${LOOPRING_DOCUMENT}dual_investment_tutorial_en.md`, '_blank')\n                window.opener = null\n              }}\n              sx={{ marginLeft: 1.5, height: 40 }}\n              variant={'outlined'}\n              color={'inherit'}\n            >\n              {t('labelInvestDualTutorial')}\n            </Button>\n            <IconButtonStyled\n              onClick={(e) => {\n                setShowAutoDefault(true)\n              }}\n              sx={{ marginLeft: 1.5, height: 40 }}\n              className={'switch outlined'}\n              aria-label='to set dual auto switch'\n              size={'large'}\n            >\n              <SwapSettingIcon htmlColor={'var(--color-text-primary)'} />\n            </IconButtonStyled>\n          </Box>\n        </Box>\n        {!isMobile && <DualInvestmentLogo />}\n      </MaxWidthContainer>\n      <MaxWidthContainer background={containerColors[1]} minHeight={'70vh'} paddingY={3}>\n        <Grid\n          container\n          flex={1}\n          display={'flex'}\n          spacing={2}\n          flexDirection={isMobile ? 'column' : 'row'}\n        >\n          {chooseDualTypeContent?.map((item) => {\n            return (\n              <Grid\n                item\n                xs={6}\n                md={12 / chooseDualTypeContent.length}\n                key={item.type}\n                display={'flex'}\n                justifyContent={'center'}\n              >\n                <MenuBtnStyled\n                  variant={'outlined'}\n                  sx={{\n                    width: 'var(--dual-type-width)',\n                    height: '320px',\n                    flexDirection: 'column',\n                    justifyContent: 'space-around',\n                  }}\n                  onClick={() => onSelect(item.type)}\n                >\n                  <Box display={'flex'} flexDirection={'column'} alignItems={'left'} marginTop={3}>\n                    <Typography\n                      variant={'h5'}\n                      component={'span'}\n                      display={'inline-flex'}\n                      color={'textPrimary'}\n                      textAlign={'left'}\n                      sx={{ textIndent: 0 }}\n                    >\n                      {t(item.titleKey)}\n                    </Typography>\n                    <Typography\n                      sx={{ textIndent: 0 }}\n                      variant={'body1'}\n                      component={'span'}\n                      display={'inline-flex'}\n                      color={'textSecondary'}\n                      textAlign={'left'}\n                    >\n                      {t(item.desKey)}\n                    </Typography>\n                  </Box>\n                  <TypographyStyle component={'span'} display={'inline-flex'}>\n                    {item.icon}\n                  </TypographyStyle>\n                  <Button\n                    sx={{ marginBottom: 3 }}\n                    variant={'contained'}\n                    fullWidth\n                    color={'primary'}\n                    size={'medium'}\n                  >\n                    {t('labelDualInvestGuid')}\n                  </Button>\n                </MenuBtnStyled>\n              </Grid>\n            )\n          })}\n        </Grid>\n      </MaxWidthContainer>\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/InvestPage/DualPanel/DualListPanel.tsx",
    "content": "import React from 'react'\nimport styled from '@emotion/styled'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nimport {\n  Box,\n  CardContent,\n  Divider,\n  FormControlLabel,\n  Grid,\n  Switch,\n  Tabs,\n  Tooltip,\n  Typography,\n} from '@mui/material'\nimport { Trans, useTranslation, WithTranslation, withTranslation } from 'react-i18next'\nimport { useDualHook } from './hook'\nimport {\n  Button,\n  CardStyleItem,\n  CoinIcon,\n  DualTable,\n  EmptyDefault,\n  useOpenModals,\n  useSettings,\n  MaxWidthContainer,\n} from '@loopring-web/component-lib'\nimport {\n  ModalDualPanel,\n  useDualMap,\n  useDualTrade,\n  useSystem,\n  useTokenMap,\n} from '@loopring-web/core'\nimport { useHistory, useLocation } from 'react-router-dom'\nimport {\n  BackIcon,\n  DualViewType,\n  getValuePrecisionThousand,\n  Info2Icon,\n  InvestAssetRouter,\n  InvestRouter,\n  InvestType,\n  LOOPRING_DOCUMENT,\n  RouterPath,\n  SagaStatus,\n  SoursURL,\n} from '@loopring-web/common-resources'\nimport { BeginnerMode } from './BeginnerMode'\nimport { containerColors } from '..'\nimport { ChooseDualType } from './ChooseDualType'\n\nconst StyleDual = styled(Box)`\n  position: relative;\n` as typeof Box\nconst WrapperStyled = styled(Box)`\n  flex: 1;\n  display: flex;\n  flex-direction: column;\n  border-radius: ${({ theme }) => theme.unit}px;\n`\n\nconst MainTabCardStyleItem = styled(CardStyleItem)`\n  &&,\n  &&.selected,\n  &&:hover {\n    border-radius: ${({ theme }) => theme.unit}px;\n    padding-left: ${({ theme }) => 3 * theme.unit}px;\n    padding-right: ${({ theme }) => 3 * theme.unit}px;\n    background: transparent;\n  }\n`\n\nconst SubTabCardStyleItem = styled(CardStyleItem)`\n  &&,\n  &&.selected,\n  &&:hover {\n    padding: ${({ theme }) => theme.unit}px ${({ theme }) => 2.5 * theme.unit}px;\n    width: auto;\n    border-radius: ${({ theme }) => theme.unit}px;\n  }\n`\nexport const DualListBlock = ({\n  marketArray,\n  tradeMap,\n  dualListProps: {\n    pairASymbol,\n    pairBSymbol,\n    isLoading,\n    dualProducts,\n    currentPrice,\n    market,\n    handleOnPairChange,\n  },\n}: {\n  tradeMap: sdk.LoopringMap<{ tokenId: number; tokenList: string[] }>\n  marketArray: string[]\n  dualListProps: any\n}) => {\n  const { t } = useTranslation()\n  const { tokenMap } = useTokenMap()\n  const { forexMap } = useSystem()\n  const { isMobile } = useSettings()\n  const { setShowDual } = useOpenModals()\n\n  return (\n    <StyleDual flexDirection={'column'} display={'flex'} flex={1}>\n      <Tabs\n        value={pairASymbol}\n        onChange={(_event, value) => handleOnPairChange({ pairA: value.toString() })}\n        aria-label='l2-history-tabs'\n        variant='scrollable'\n        sx={{\n          display: 'flex',\n          flexWrap: 'wrap',\n        }}\n      >\n        {tradeMap &&\n          Object.keys(tradeMap)\n            .sort((a, b) => a.toString().localeCompare(b.toString()))\n            .map((item, index) => {\n              return (\n                <Grid\n                  marginBottom={2}\n                  marginLeft={2}\n                  item\n                  xs={6}\n                  md={3}\n                  lg={2}\n                  key={item.toString() + index.toString()}\n                >\n                  <MainTabCardStyleItem\n                    className={\n                      item.toString().toLowerCase() === pairASymbol.toLowerCase()\n                        ? 'btnCard dualInvestCard selected'\n                        : 'btnCard dualInvestCard '\n                    }\n                    sx={{ height: '100%' }}\n                    onClick={() => handleOnPairChange({ pairA: item.toString() })}\n                  >\n                    <CardContent sx={{ alignItems: 'center' }}>\n                      <Typography component={'span'} display={'inline-flex'}>\n                        <CoinIcon symbol={item.toString()} size={28} />\n                      </Typography>\n                      <Typography variant={'h5'} paddingLeft={1}>\n                        {t('labelDualInvest', {\n                          symbol: item.toString(),\n                        })}\n                      </Typography>\n                    </CardContent>\n                  </MainTabCardStyleItem>\n                </Grid>\n              )\n            })}\n      </Tabs>\n\n      <WrapperStyled\n        display={'flex'}\n        marginTop={1}\n        flex={1}\n        flexDirection={'column'}\n        className={'dualList'}\n      >\n        {pairASymbol && pairBSymbol && market && (\n          <>\n            <Box\n              display={'flex'}\n              flexDirection={'row'}\n              paddingTop={1}\n              paddingX={2}\n              justifyContent={'space-between'}\n              alignItems={'center'}\n            >\n              <Box display={'flex'} flexWrap={'wrap'}>\n                {pairASymbol &&\n                  tradeMap[pairASymbol]?.tokenList?.map((item, index) => {\n                    const _index = marketArray.findIndex((_item) =>\n                      new RegExp(pairASymbol + '-' + item.toString(), 'ig').test(_item),\n                    )\n                    return (\n                      <SubTabCardStyleItem\n                        className={\n                          item.toString().toLowerCase() === pairBSymbol.toLowerCase()\n                            ? 'btnCard dualInvestCard selected'\n                            : 'btnCard dualInvestCard '\n                        }\n                        sx={{\n                          marginRight: 2,\n                          marginBottom: isMobile ? 2 : 0,\n                        }}\n                        onClick={() => {\n                          handleOnPairChange({ pairB: item })\n                        }}\n                        key={item.toString() + index.toString()}\n                      >\n                        <Typography variant={isMobile ? 'body1' : 'h5'} padding={2}>\n                          {_index !== -1\n                            ? t('labelDualBase', {\n                                symbol: item.toString(),\n                              })\n                            : t('labelDualQuote', {\n                                symbol: item.toString(),\n                              })}\n                        </Typography>\n                      </SubTabCardStyleItem>\n                    )\n                  })}\n              </Box>\n              <Typography\n                component={'span'}\n                display={isMobile ? 'flex' : 'inline-flex'}\n                color={'textSecondary'}\n                variant={'body2'}\n                flexDirection={isMobile ? 'column' : 'row'}\n                alignItems={'center'}\n                whiteSpace={'pre-wrap'}\n              >\n                {currentPrice &&\n                  (!isMobile ? (\n                    <>\n                      <Tooltip\n                        title={\n                          <>\n                            {t('labelDualCurrentPriceTip', {\n                              symbol: /USD/gi.test(currentPrice?.quoteUnit ?? '')\n                                ? 'USDT'\n                                : currentPrice?.quoteUnit,\n                            })}\n                          </>\n                        }\n                        placement={'top'}\n                      >\n                        <Typography\n                          component={'p'}\n                          variant='body2'\n                          color={'textSecondary'}\n                          display={'inline-flex'}\n                          alignItems={'center'}\n                        >\n                          <Info2Icon fontSize={'small'} color={'inherit'} sx={{ marginX: 1 / 2 }} />\n                        </Typography>\n                      </Tooltip>\n                      <Trans\n                        i18nKey={'labelDualCurrentPrice'}\n                        tOptions={{\n                          price:\n                            // PriceTag[CurrencyToTag[currency]] +\n                            getValuePrecisionThousand(\n                              currentPrice.currentPrice,\n                              currentPrice.precisionForPrice\n                                ? currentPrice.precisionForPrice\n                                : tokenMap[currentPrice.quote].precisionForOrder,\n                              currentPrice.precisionForPrice\n                                ? currentPrice.precisionForPrice\n                                : tokenMap[currentPrice.quote].precisionForOrder,\n                              currentPrice.precisionForPrice\n                                ? currentPrice.precisionForPrice\n                                : tokenMap[currentPrice.quote].precisionForOrder,\n                              true,\n                              { floor: true },\n                            ),\n                          symbol: currentPrice.base,\n                          baseSymbol: /USD/gi.test(currentPrice.quoteUnit ?? '')\n                            ? 'USDT'\n                            : currentPrice.quoteUnit, //currentPrice.quote,\n                        }}\n                      >\n                        LRC Current price:\n                        <Typography\n                          component={'span'}\n                          display={'inline-flex'}\n                          color={'textPrimary'}\n                          paddingLeft={1}\n                        >\n                          price\n                        </Typography>\n                        :\n                      </Trans>\n                    </>\n                  ) : (\n                    <>\n                      <Typography\n                        component={'span'}\n                        color={'textSecondary'}\n                        variant={'body2'}\n                        textAlign={'right'}\n                      >\n                        {t('labelDualMobilePrice', {\n                          symbol: currentPrice.base,\n                        })}\n                      </Typography>\n                      <Typography\n                        textAlign={'right'}\n                        component={'span'}\n                        display={'inline-flex'}\n                        color={'textPrimary'}\n                        paddingLeft={1}\n                      >\n                        {getValuePrecisionThousand(\n                          currentPrice.currentPrice,\n                          currentPrice.precisionForPrice\n                            ? currentPrice.precisionForPrice\n                            : tokenMap[currentPrice.quote].precisionForOrder,\n                          currentPrice.precisionForPrice\n                            ? currentPrice.precisionForPrice\n                            : tokenMap[currentPrice.quote].precisionForOrder,\n                          currentPrice.precisionForPrice\n                            ? currentPrice.precisionForPrice\n                            : tokenMap[currentPrice.quote].precisionForOrder,\n                          true,\n                          { floor: true },\n                        )}\n                      </Typography>\n                    </>\n                  ))}\n              </Typography>\n            </Box>\n            <Box flex={1} display={'flex'}>\n              <DualTable\n                rawData={dualProducts ?? []}\n                showloading={isLoading}\n                forexMap={forexMap as any}\n                onItemClick={(item) => {\n                  setShowDual({\n                    isShow: true,\n                    dualInfo: {\n                      ...item,\n                      sellSymbol: pairASymbol,\n                      buySymbol: pairBSymbol,\n                    },\n                  })\n                }}\n              />\n            </Box>\n          </>\n        )}\n      </WrapperStyled>\n    </StyleDual>\n  )\n}\n\nexport const DualListPanel: any = withTranslation('common')(({ t }: WithTranslation) => {\n  const { search, pathname } = useLocation()\n  const searchParams = new URLSearchParams(search)\n  const viewType = new URLSearchParams(search).get('viewType')\n  const { forexMap } = useSystem()\n  const history = useHistory()\n  const { status: dualStatus, getDualMap } = useDualMap()\n  const [confirmDualAutoInvest, setConfirmDualAutoInvest] = React.useState(false)\n  const dualListProps = useDualHook()\n  const { dualTradeProps, dualToastOpen, closeDualToast } = useDualTrade()\n  const { onSelectStep1Token } = dualListProps\n  React.useEffect(() => {\n    if (dualStatus === SagaStatus.ERROR) {\n      getDualMap()\n    }\n  }, [dualStatus])\n\n  return (\n    <Box display={'flex'} flexDirection={'column'} flex={1} width={'100%'}>\n      {viewType ? (\n        <>\n          <MaxWidthContainer\n            background={containerColors[1]}\n            display={'flex'}\n            justifyContent={'space-between'}\n            paddingY={2}\n            sx={{ flexDirection: 'row' }}\n          >\n            <Button\n              startIcon={<BackIcon fontSize={'small'} />}\n              variant={'text'}\n              sx={{ color: 'var(--color-text-primary)' }}\n              color={'inherit'}\n              onClick={() => {\n                searchParams.set('viewType', '')\n                // history.goBack()\n                history.push(pathname + '?' + searchParams.toString())\n                onSelectStep1Token(undefined)\n              }}\n            >\n              {t('labelBack')}\n            </Button>\n            <Button\n              variant={'text'}\n              sx={{ color: 'var(--color-text-primary)' }}\n              color={'inherit'}\n              endIcon={<BackIcon fontSize={'small'} sx={{ transform: 'rotate(180deg)' }} />}\n              onClick={() =>\n                history.push(`${RouterPath.invest}/${InvestRouter[InvestType.MyBalance]}`)\n              }\n            >\n              {t('labelInvestMyDual')}\n            </Button>\n          </MaxWidthContainer>\n          <Divider />\n          <MaxWidthContainer\n            containerProps={{\n              sx: {\n                background: containerColors[1],\n                display: 'flex',\n                flex: 1,\n                flexDirection: 'column',\n                justifyContent: 'flex-start',\n                alignItems: 'center',\n              },\n            }}\n            sx={{\n              flex: 1,\n              display: 'flex',\n              flexDirection: 'column',\n            }}\n          >\n            <Box display={'flex'} justifyContent={'space-between'} alignItems={'center'}>\n              <Box display={'flex'} alignItems={'center'} marginY={3}>\n                <Typography component={'h4'} variant={'h4'}>\n                  {t(`labelDualType${viewType}`)}\n                </Typography>\n                <Button\n                  onClick={() => {\n                    window.open(`${LOOPRING_DOCUMENT}dual_investment_tutorial_en.md`, '_blank')\n                    window.opener = null\n                  }}\n                  size={'small'}\n                  sx={{ marginLeft: 1.5 }}\n                  variant={'outlined'}\n                >\n                  {t('labelInvestDualTutorial')}\n                </Button>\n              </Box>\n              {[DualViewType.All, DualViewType.DualBegin].includes(viewType as any) && (\n                <FormControlLabel\n                  labelPlacement={'start'}\n                  control={\n                    <Switch\n                      checked={viewType === DualViewType.DualBegin}\n                      onChange={(_event, _checked) => {\n                        searchParams.set(\n                          'viewType',\n                          _checked ? DualViewType.DualBegin : DualViewType.All,\n                        )\n                        history.push(pathname + '?' + searchParams.toString())\n                      }}\n                    />\n                  }\n                  label={\n                    <Typography marginLeft={1.5} variant={'h5'}>\n                      {t('labelInvestDualBeginerMode')}\n                    </Typography>\n                  }\n                />\n              )}\n            </Box>\n            <>\n              {![DualViewType.All, DualViewType.DualBTC].includes(viewType as any) ? (\n                <BeginnerMode dualListProps={dualListProps} viewType={viewType} />\n              ) : dualStatus == SagaStatus.PENDING ? (\n                <Box\n                  key={'loading'}\n                  flexDirection={'column'}\n                  display={'flex'}\n                  justifyContent={'center'}\n                  height={'100%'}\n                  alignItems={'center'}\n                  flex={1}\n                >\n                  <img alt={'loading'} width='36' src={`${SoursURL}images/loading-line.gif`} />\n                </Box>\n              ) : !!dualListProps?.marketArray?.length ? (\n                <DualListBlock\n                  tradeMap={dualListProps.tradeMap}\n                  marketArray={dualListProps.marketArray}\n                  dualListProps={dualListProps}\n                />\n              ) : (\n                <Box\n                  key={'empty'}\n                  flexDirection={'column'}\n                  display={'flex'}\n                  justifyContent={'center'}\n                  height={'100%'}\n                  flex={1}\n                  alignItems={'center'}\n                >\n                  <EmptyDefault\n                    height={'calc(100% - 35px)'}\n                    message={() => {\n                      return (\n                        <Trans i18nKey='labelNoContent'>\n                          <Button onClick={getDualMap} variant={'contained'}>\n                            {t('labelDualRefresh')}\n                          </Button>\n                        </Trans>\n                      )\n                    }}\n                  />\n                </Box>\n              )}\n            </>\n          </MaxWidthContainer>\n        </>\n      ) : (\n        <ChooseDualType\n          chooseDualTypeContent={dualListProps.chooseDualTypeContent}\n          onSelect={(item) => {\n            searchParams.set('viewType', item)\n\n            history.push(\n              `${RouterPath.invest}/${InvestAssetRouter.DUAL}/${\n                item === DualViewType.DualBTC ? 'ETH-WBTC' : 'ETH-USDC'\n              }?${searchParams.toString()}`,\n            )\n          }}\n        />\n      )}\n\n      <ModalDualPanel\n        confirmDualAutoInvest={confirmDualAutoInvest}\n        setConfirmDualAutoInvest={setConfirmDualAutoInvest}\n        viewType={viewType as any}\n        dualTradeProps={{ ...dualTradeProps }}\n        dualToastOpen={dualToastOpen}\n        closeDualToast={closeDualToast}\n        isBeginnerMode={viewType === DualViewType.DualBegin}\n      />\n    </Box>\n  )\n})\n"
  },
  {
    "path": "packages/webapp/src/pages/InvestPage/DualPanel/hook.tsx",
    "content": "import { useHistory, useLocation, useRouteMatch } from 'react-router-dom'\nimport {\n  confirmation,\n  findDualMarket,\n  LoopringAPI,\n  makeDualViewItem,\n  store,\n  useDualMap,\n  useTokenMap,\n} from '@loopring-web/core'\nimport React from 'react'\nimport _ from 'lodash'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport {\n  DUAL_CONFIG,\n  DualBTCIcon,\n  DualConvertIcon,\n  DualCurrentPrice,\n  DualDownIcon,\n  DualUpIcon,\n  DualViewInfo,\n  DualViewType,\n  InvestAssetRouter,\n  MapChainId,\n  myLog,\n  RouterPath,\n  SagaStatus,\n} from '@loopring-web/common-resources'\nimport { useSettings } from '@loopring-web/component-lib'\n\nconst DUALLimit = 20\nexport type ChooseDualTypeContentType = {\n  icon: JSX.Element\n  type: DualViewType\n  titleKey: string\n  desKey: string\n}\nexport const ChooseDualTypeContent: ChooseDualTypeContentType[] = [\n  {\n    icon: (\n      <DualUpIcon\n        style={{\n          width: 156,\n          height: 156,\n        }}\n      />\n    ),\n    type: DualViewType.DualGain,\n    titleKey: 'labelCoverGain',\n    desKey: 'labelCoverGainDes',\n  },\n  {\n    icon: (\n      <DualDownIcon\n        style={{\n          width: 156,\n          height: 156,\n        }}\n      />\n    ),\n    type: DualViewType.DualDip,\n    titleKey: 'labelDip',\n    desKey: 'labelDipDes',\n  },\n\n  {\n    icon: (\n      <DualConvertIcon\n        style={{\n          width: 156,\n          height: 156,\n        }}\n      />\n    ),\n    type: DualViewType.All,\n    titleKey: 'labelDualMerge',\n    desKey: 'labelDualMergeDes',\n  },\n  {\n    icon: (\n      <DualBTCIcon\n        style={{\n          width: 156,\n          height: 156,\n        }}\n      />\n    ),\n    type: DualViewType.DualBTC,\n    titleKey: 'labelDualBTC',\n    desKey: 'labelDualBTCDes',\n  },\n]\nconst InvestRouterMatch = `${RouterPath.invest}/${InvestAssetRouter.DUAL}/:market?`\nexport const useDualHook = () => {\n  const match: any = useRouteMatch(InvestRouterMatch)\n  const { search } = useLocation()\n  const searchParams = new URLSearchParams(search)\n  const viewType = searchParams.get('viewType')\n  const { defaultNetwork } = useSettings()\n  const { tokenMap, idIndex } = useTokenMap()\n  const {\n    marketArray: _marketArray,\n    tradeMap: _tradeMap,\n    marketMap,\n    status: dualStatus,\n  } = useDualMap()\n  const history = useHistory()\n  const nodeTimer = React.useRef<NodeJS.Timeout | -1>(-1)\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const [isLoading, setIsLoading] = React.useState(true)\n  const [currentPrice, setCurrentPrice] = React.useState<DualCurrentPrice | undefined>(undefined)\n  const [, , coinA, coinB] =\n    (match?.params?.market ? match.params.market : 'ETH-USDC').match(/(dual-)?(\\w+)-(\\w+)/i) ?? []\n  const [marketArray, setMarketArray] = React.useState(_marketArray)\n  const [pairASymbol, setPairASymbol] = React.useState(() =>\n    _tradeMap && _tradeMap[coinA] ? coinA : 'ETH',\n  )\n  const [pairBSymbol, setPairBSymbol] = React.useState(\n    coinB && _tradeMap && _tradeMap[pairASymbol]?.tokenList\n      ? _tradeMap[pairASymbol].tokenList.includes(coinB)\n        ? coinB\n        : _tradeMap[pairASymbol].tokenList[0]\n      : 'USDC',\n  )\n\n  const [pair, setPair] = React.useState(`${pairASymbol}-${pairBSymbol}`)\n  const [market, setMarket] = React.useState(() =>\n    marketArray?.length ? findDualMarket(marketArray, pairASymbol, pairBSymbol) : '',\n  )\n  const [[marketBase, marketQuote], setMarketPair] = React.useState(() => {\n    // @ts-ignore\n    const [, , coinA, coinB] = market ? market : 'ETH-USDC'.match(/(dual-)?(\\w+)-(\\w+)/i) ?? []\n    return [coinA, coinB]\n  })\n  const chooseDualTypeContent = React.useMemo(() => {\n    const index = marketArray.findIndex((item) => {\n      return /(\\w+)-(\\w+)-\\w?BTC/gi.test(item)\n    })\n    const list = _.cloneDeep(ChooseDualTypeContent)\n    if (index == -1) {\n      list.pop()\n    }\n    return list ?? []\n  }, [ChooseDualTypeContent, marketArray])\n\n  const handleOnPairChange = React.useCallback(\n    (\n      prosp:\n        | {\n            pairA: string\n          }\n        | { pairB: string },\n    ) => {\n      let market: any\n      let _pairBSymbol: string = ''\n      let _pairASymbol = pairASymbol\n      if (prosp.hasOwnProperty('pairA')) {\n        _pairASymbol = (prosp as any).pairA\n        _pairBSymbol = tradeMap[_pairASymbol]?.tokenList[0]\n        setPairASymbol(_pairASymbol)\n        setPairBSymbol(_pairBSymbol)\n        market = findDualMarket(marketArray, _pairASymbol, _pairBSymbol)\n      } else if (prosp.hasOwnProperty('pairB')) {\n        _pairBSymbol = (prosp as any).pairB\n        setPairBSymbol(_pairBSymbol)\n        market = findDualMarket(marketArray, _pairASymbol, _pairBSymbol)\n      }\n      if (market) {\n        history.push(\n          `${RouterPath.invest}/${InvestAssetRouter.DUAL}/${_pairASymbol}-${_pairBSymbol}${search}`,\n        )\n        const [, , coinA, coinB] = market.match(/(dual-)?(\\w+)-(\\w+)/i)\n        setMarket(market)\n        setPair(`${_pairASymbol}-${_pairBSymbol}`)\n        setMarketPair([coinA, coinB])\n      }\n    },\n    [marketArray, pairASymbol, search],\n  )\n  const tradeMap = React.useMemo(() => {\n    const { tradeMap, marketMap } = store.getState().invest.dualMap\n    const { pairs } = sdk.makeInvestMarkets(\n      { markets: marketArray.length ? marketArray?.map((item) => marketMap[item]) : [] },\n      DUAL_CONFIG.products[network].join(','),\n    )\n\n    const _tradeMap =\n      Reflect.ownKeys(pairs ?? {})?.reduce((prev, key) => {\n        const tokenList = pairs[key as string]?.tokenList?.sort()\n        prev[key] = {\n          ...pairs[key as string],\n          tokenList,\n        }\n        return prev\n      }, {}) ?? tradeMap\n\n    handleOnPairChange({\n      pairB:\n        coinB && tradeMap && tradeMap[pairASymbol]?.tokenList\n          ? tradeMap[pairASymbol].tokenList.includes(coinB)\n            ? coinB\n            : tradeMap[pairASymbol].tokenList[0]\n          : undefined,\n    })\n    return _tradeMap\n  }, [marketArray])\n  const baseTokenList = React.useMemo(() => {\n    if (dualStatus === SagaStatus.UNSET) {\n      const object = Reflect.ownKeys(marketMap ?? {}).reduce((prev, key) => {\n        if (!marketMap[key.toString()].enabled) {\n          return prev\n        }\n        const baseSymbol = idIndex[marketMap[key.toString()].baseTokenId]\n        prev[baseSymbol] = {\n          tokenName: baseSymbol,\n          tokenList: tradeMap[baseSymbol]?.tokenList,\n        }\n        if (viewType === DualViewType.DualGain) {\n          prev[baseSymbol] = {\n            ...prev[baseSymbol],\n          }\n        } else if (viewType === DualViewType.DualDip) {\n          prev[baseSymbol] = {\n            ...prev[baseSymbol],\n          }\n        } else {\n          prev[baseSymbol] = {\n            ...prev[baseSymbol],\n          }\n        }\n\n        return prev\n      }, {} as any)\n      return _.mapValues(object, (token) => {\n        const keys = Object.keys(marketMap).filter((key) => key.includes(token.tokenName))\n        if (viewType === DualViewType.DualGain) {\n          var maxAPY = _.max(keys.map((key) => (marketMap[key] as any).baseTokenApy?.max as number))\n          var minAPY = _.max(keys.map((key) => (marketMap[key] as any).baseTokenApy?.min as number))\n        } else if (viewType === DualViewType.DualDip) {\n          maxAPY = _.max(keys.map((key) => (marketMap[key] as any).quoteTokenApy?.max as number))\n          minAPY = _.max(keys.map((key) => (marketMap[key] as any).quoteTokenApy?.min as number))\n        } else {\n          maxAPY = _.max([\n            ...keys.map((key) => (marketMap[key] as any).quoteTokenApy?.max as number),\n            ...keys.map((key) => (marketMap[key] as any).baseTokenApy?.max as number),\n          ])\n          minAPY = _.max([\n            ...keys.map((key) => (marketMap[key] as any).quoteTokenApy?.min as number),\n            ...keys.map((key) => (marketMap[key] as any).baseTokenApy?.min as number),\n          ])\n        }\n        return {\n          ...token,\n          maxAPY,\n          minAPY,\n        }\n      })\n    } else {\n      return {}\n    }\n  }, [viewType, dualStatus])\n  const [dualProducts, setDualProducts] = React.useState<DualViewInfo[]>([])\n  const [isDualBalanceSufficient, setIsDualBalanceSufficient] = React.useState<boolean | undefined>(\n    undefined,\n  )\n  // const [productRawData,setProductRawData] = React.useState([])\n  const getProduct = _.debounce(async () => {\n    setIsLoading(true)\n    try {\n      setIsDualBalanceSufficient(undefined)\n      const market = marketArray && findDualMarket(marketArray, pairASymbol, pairBSymbol)\n      if (nodeTimer.current !== -1) {\n        clearTimeout(nodeTimer.current as NodeJS.Timeout)\n      }\n      // @ts-ignore\n      const currency = market ? marketMap[market]?.currency : undefined\n      if (pairASymbol && pairBSymbol && market) {\n        // @ts-ignore\n        const [, , marketSymbolA, marketSymbolB] = (market ?? '').match(/(dual-)?(\\w+)-(\\w+)/i)\n        const dualType =\n          marketSymbolA === pairASymbol ? sdk.DUAL_TYPE.DUAL_BASE : sdk.DUAL_TYPE.DUAL_CURRENCY\n        const { quoteAlias } = marketMap[market]\n\n        const response = await LoopringAPI.defiAPI?.getDualInfos({\n          baseSymbol: marketSymbolA,\n          quoteSymbol: quoteAlias ?? marketSymbolB,\n          currency: currency ?? '',\n          dualType,\n          startTime: Date.now() + 1000 * 60 * 60,\n          timeSpan: 1000 * 60 * 60 * 24 * 9,\n          limit: DUALLimit,\n        })\n\n        if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n          setDualProducts([])\n        } else {\n          const {\n            // totalNum,\n            dualInfo: { infos, index, balance, rules },\n          } = response as any\n          const balanceCoin = pairASymbol === 'USDC' ? 'USDT' : pairASymbol\n          const found = balance.find((_balance: any) => _balance.coin === balanceCoin)\n          const sellToken = tokenMap[balanceCoin]\n          if (dualType === sdk.DUAL_TYPE.DUAL_BASE) {\n            var minSellVol = marketMap[market].baseLimitAmount\n          } else {\n            minSellVol = marketMap[market].quoteLimitAmount\n          }\n          setIsDualBalanceSufficient(\n            found && sellToken\n              ? sdk\n                  .toBig(found.free)\n                  .times('1e' + sellToken.decimals)\n                  .isGreaterThanOrEqualTo(minSellVol)\n              : undefined,\n          )\n          setCurrentPrice({\n            base: marketSymbolA,\n            quote: marketSymbolB,\n            currentPrice: index.index,\n            precisionForPrice: marketMap[market].precisionForPrice,\n            quoteUnit: marketSymbolB,\n          })\n\n          const rule = rules[0]\n          const rawData = infos.map((item: sdk.DualProductAndPrice) => {\n            return makeDualViewItem(item, index, rule, pairASymbol, pairBSymbol, marketMap[market])\n          })\n          setDualProducts(rawData)\n          // setIsLoading(false)\n        }\n        // }\n      }\n\n      nodeTimer.current = setTimeout(() => {\n        getProduct()\n      }, 60000)\n    } catch {\n      setDualProducts([])\n    } finally {\n      setIsLoading(false)\n    }\n  }, 100)\n\n  const [step1SelectedToken, setStep1SelectedToken] = React.useState<string | undefined>(\n    [DualViewType.DualGain, DualViewType.DualDip].includes(viewType as any) ? coinA : undefined,\n  )\n  const [step2BuyOrSell, setStep2BuyOrSell] = React.useState<'Buy' | 'Sell' | undefined>(undefined)\n  const [step3Token, setStep3Token] = React.useState<string | undefined>(\n    [DualViewType.DualGain, DualViewType.DualDip].includes(viewType as any) ? coinB : undefined,\n  )\n  const onSelectStep1Token = React.useCallback(\n    (token?: string) => {\n      setStep1SelectedToken(token)\n      //@ts-ignore\n      if (![DualViewType.DualGain, DualViewType.DualDip].includes(viewType)) {\n        setStep2BuyOrSell(undefined)\n      }\n      setStep3Token(undefined)\n    },\n    [viewType],\n  )\n\n  const onSelectStep2BuyOrSell = React.useCallback((which: 'Buy' | 'Sell') => {\n    setStep2BuyOrSell(which)\n    setStep3Token(undefined)\n  }, [])\n  const onSelectStep3Token = React.useCallback(\n    (which: string) => {\n      setStep3Token(which)\n      if (step2BuyOrSell! === 'Sell') {\n        var pairA = step1SelectedToken!\n        var pairB = which\n      } else {\n        pairA = which\n        pairB = step1SelectedToken!\n      }\n      setPairASymbol(pairA)\n      setPairBSymbol(pairB)\n      const market = findDualMarket(marketArray, pairA, pairB)\n      history.push(`${RouterPath.invest}/${InvestAssetRouter.DUAL}/${pairA}-${pairB}${search}`)\n      if (market) {\n        const [, , coinA, coinB] = market ?? ''.match(/(dual-)?(\\w+)-(\\w+)/i)\n        setMarket(market)\n        setPair(`${pairA}-${pairB}`)\n        setMarketPair([coinA, coinB])\n      }\n    },\n    [step1SelectedToken, step2BuyOrSell, marketArray, tradeMap],\n  )\n  React.useEffect(() => {\n    // const { marketArray, marketMap, tradeMap, status: dualStatus, getDualMap } = useDualMap()\n    const { marketArray } = store.getState().invest.dualMap\n    switch (viewType) {\n      case DualViewType.DualGain:\n        setStep2BuyOrSell('Sell')\n        setMarketArray(marketArray)\n        break\n      case DualViewType.DualDip:\n        setStep2BuyOrSell('Buy')\n        setMarketArray(marketArray)\n        break\n      case DualViewType.DualBegin:\n        setStep2BuyOrSell(undefined)\n        setMarketArray(marketArray)\n        break\n      case DualViewType.DualBTC:\n        setMarketArray(marketArray.filter((item) => /(\\w+)-(\\w+)-\\w?BTC/gi.test(item)))\n        setStep2BuyOrSell(undefined)\n        break\n      case DualViewType.All:\n      default:\n        setMarketArray(marketArray)\n        setStep2BuyOrSell(undefined)\n        break\n    }\n  }, [viewType, dualStatus])\n\n  React.useEffect(() => {\n    if (dualStatus === SagaStatus.UNSET && pair) {\n      getProduct.cancel()\n      const [_, _pairASymbol, _pairBSymbol] = pair.match(/(\\w+)-(\\w+)/i)\n      if (marketArray !== undefined && marketArray.length) {\n        const market = findDualMarket(marketArray, _pairASymbol, _pairBSymbol)\n        if (market) {\n          setPairASymbol(_pairASymbol)\n          setPairBSymbol(_pairBSymbol)\n          getProduct()\n          return\n        } else {\n          handleOnPairChange({ pairB: _pairBSymbol })\n        }\n        return\n      }\n      history.push(`${RouterPath.invest}/${InvestAssetRouter.DUAL}/${search}`)\n      myLog('update pair', pair)\n    }\n    return () => {\n      if (nodeTimer.current !== -1) {\n        clearTimeout(nodeTimer.current as NodeJS.Timeout)\n      }\n      getProduct.cancel()\n    }\n  }, [pair, dualStatus])\n\n  return {\n    currentPrice,\n    pairASymbol,\n    pairBSymbol,\n    market,\n    isLoading,\n    dualProducts,\n    handleOnPairChange,\n    marketBase,\n    marketQuote,\n    // priceObj,\n    pair,\n    step1SelectedToken,\n    step2BuyOrSell,\n    step3Token,\n    onSelectStep1Token,\n    onSelectStep2BuyOrSell,\n    onSelectStep3Token,\n    isDualBalanceSufficient,\n    baseTokenList,\n    chooseDualTypeContent,\n    marketArray,\n    tradeMap,\n  }\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/InvestPage/LeverageETHPanel/TradePanel.tsx",
    "content": "import { useDefiTrade, confirmation } from '@loopring-web/core'\nimport {\n  MarketType,\n  leverageETHAdvice,\n  myLog,\n  DEFI_ADVICE_MAP,\n} from '@loopring-web/common-resources'\nimport {\n  ConfirmDefiNOBalance,\n  DeFiWrap,\n  LoadingBlock,\n  useSettings,\n} from '@loopring-web/component-lib'\nimport { Box } from '@mui/material'\nimport React from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { useDefiMap } from '@loopring-web/core'\n\nexport const TradePanel = ({\n  isJoin,\n  setServerUpdate,\n  setToastOpen,\n}: {\n  isJoin: boolean\n  setServerUpdate: (state: any) => void\n  setToastOpen: (state: any) => void\n}) => {\n  const { marketLeverageArray: marketArray } = useDefiMap()\n  // @ts-ignore\n  const market: MarketType = marketArray[0]\n  myLog('isJoin', isJoin, 'market', market)\n  const [confirmShowLimitBalance, setConfirmShowLimitBalance] = React.useState<boolean>(false)\n  const [confirmShowNoBalance, setConfirmShowNoBalance] = React.useState<boolean>(false)\n\n  const { deFiWrapProps } = useDefiTrade({\n    isJoin,\n    setToastOpen: setToastOpen as any,\n    market: market,\n    setServerUpdate,\n    setConfirmShowNoBalance,\n    confirmShowLimitBalance,\n    setConfirmShowLimitBalance,\n    isLeverageETH: true,\n  })\n  const { t } = useTranslation()\n\n  const { isMobile } = useSettings()\n  const [, tokenBase] = market.match(/(\\w+)-(\\w+)/i) ?? []\n\n  const { setShowLeverageETHPopup } = confirmation.useConfirmation()\n  return (\n    <>\n      {deFiWrapProps.deFiCalcData ? (\n        <Box\n          className={'hasLinerBg'}\n          display={'flex'}\n          sx={{\n            width: 'var(--modal-width)',\n            background: 'var(--color-box-third)',\n          }}\n          justifyContent={'center'}\n          padding={5 / 2}\n        >\n          <DeFiWrap\n            isLeverageETH\n            market={market}\n            isJoin={isJoin}\n            setShowLeverageETHPopup={setShowLeverageETHPopup}\n            type={leverageETHAdvice.project}\n            title={DEFI_ADVICE_MAP[tokenBase].project}\n            {...(deFiWrapProps as any)}\n          />\n        </Box>\n      ) : (\n        <LoadingBlock />\n      )}\n      <ConfirmDefiNOBalance\n        isJoin={isJoin}\n        market={market}\n        type={leverageETHAdvice.project as any}\n        handleClose={(_e) => {\n          setConfirmShowNoBalance(false)\n          if (deFiWrapProps?.onRefreshData) {\n            deFiWrapProps?.onRefreshData(true, true)\n          }\n        }}\n        open={confirmShowNoBalance}\n        isLeverage\n      />\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/InvestPage/LeverageETHPanel/index.tsx",
    "content": "import React from 'react'\nimport styled from '@emotion/styled'\nimport { Box, CardContent, Grid } from '@mui/material'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport { TradePanel } from './TradePanel'\nimport {\n  boxLiner,\n  Button,\n  ConfirmInvestDefiServiceUpdate,\n  Toast,\n  LoadingBlock,\n  ConfirmInvestDefiRisk,\n  ToastType,\n  useToggle,\n  useSettings,\n  MaxWidthContainer,\n} from '@loopring-web/component-lib'\nimport { confirmation, useDefiMap, useToast } from '@loopring-web/core'\nimport { useHistory, useRouteMatch } from 'react-router-dom'\nimport {\n  BackIcon,\n  InvestAssetRouter,\n  InvestRouter,\n  InvestType,\n  RouterPath,\n  TOAST_TIME,\n} from '@loopring-web/common-resources'\nimport { containerColors } from '..'\nimport { useTheme } from '@emotion/react'\n\nexport const StyleWrapper = styled(Box)`\n  position: relative;\n  border-radius: ${({ theme }) => theme.unit}px;\n\n  .loading-block {\n    background: initial;\n  }\n\n  .hasLinerBg {\n    ${({ theme }) => boxLiner({ theme })}\n  }\n\n  border-radius: ${({ theme }) => theme.unit}px;\n` as typeof Grid\nexport const StyleCardContent = styled(CardContent)`\n  display: flex;\n\n  &.tableLap {\n    display: block;\n    width: 100%;\n    cursor: pointer;\n\n    .content {\n      flex-direction: column;\n      align-items: center;\n      padding-top: ${({ theme }) => 4 * theme.unit}px;\n\n      .des {\n        align-items: center;\n        margin: ${({ theme }) => 3 * theme.unit}px 0;\n      }\n\n      .backIcon {\n        display: none;\n      }\n    }\n  }\n\n  padding: 0;\n\n  &:last-child {\n    padding: 0;\n  }\n\n  &.isMobile {\n    flex: 1;\n\n    .content {\n      flex-direction: row;\n      width: 100%;\n\n      .des {\n        margin-left: ${({ theme }) => 2 * theme.unit}px;\n        align-items: flex-start;\n      }\n    }\n  }\n` as typeof CardContent\n\nconst ButtonStyled = styled(Button)`\n  background-color: var(--color-button-outlined);\n  color: var(--color-text-primary);\n  :hover {\n    background-color: var(--color-button-outlined);\n    ::before {\n      border-radius: 4px;\n    }\n  }\n`\nconst InvestRouterMatch = `${RouterPath.invest}/${InvestAssetRouter.LEVERAGEETH}/:isJoin?`\n\nconst LeverageETHPanel: any = withTranslation('common')(({ t }: WithTranslation & {}) => {\n  const match: any = useRouteMatch(InvestRouterMatch)\n\n  const { marketLeverageArray: marketArray } = useDefiMap()\n  const {\n    confirmedLeverageETHInvest,\n    setShowLeverageETHPopup,\n    confirmation: {\n      confirmedLeverageETHInvest: confirmed,\n      confirmationNeeded,\n      showLeverageETHPopup,\n    },\n  } = confirmation.useConfirmation()\n  const {\n    toggle: {\n      CIETHInvest: { enable },\n    },\n  } = useToggle()\n\n  const _confirmedDefiInvest = {\n    isShow: showLeverageETHPopup,\n    type: 'CiETH',\n    confirmationNeeded,\n  }\n  const setConfirmedDefiInvest = ({ isShow }: { isShow: boolean }) => {\n    if (isShow) {\n      setShowLeverageETHPopup({ isShow: true, confirmationNeeded: true })\n    } else {\n      setShowLeverageETHPopup({ isShow: false, confirmationNeeded: true })\n    }\n  }\n  const [serverUpdate, setServerUpdate] = React.useState(false)\n  const { toastOpen, setToastOpen, closeToast } = useToast()\n  const history = useHistory()\n  const isJoin = match?.params?.isJoin?.toUpperCase() !== 'Redeem'.toUpperCase()\n  React.useEffect(() => {\n    setConfirmedDefiInvest({\n      isShow: enable ? !confirmed : false,\n    })\n  }, [confirmed, enable])\n  const theme = useTheme()\n  const { isMobile } = useSettings()\n  return (\n    <Box display={'flex'} flexDirection={'column'} flex={1}>\n      <MaxWidthContainer minHeight={'70vh'} paddingY={5}>\n        <StyleWrapper\n          display={'flex'}\n          flexDirection={'column'}\n          justifyContent={'center'}\n          alignItems={'center'}\n          flex={1}\n          marginTop={6}\n        >\n          {marketArray?.length ? (\n            // match?.params?.market && _market ? (\n            <TradePanel\n              isJoin={isJoin}\n              setServerUpdate={setServerUpdate}\n              setToastOpen={setToastOpen}\n            />\n          ) : (\n            // )\n            // : (\n            //   <LandDefiInvest setConfirmedDefiInvest={setConfirmedDefiInvest} />\n            // )\n            <LoadingBlock />\n          )}\n          <Toast\n            alertText={toastOpen?.content ?? ''}\n            severity={toastOpen?.type ?? ToastType.success}\n            open={toastOpen?.open ?? false}\n            autoHideDuration={TOAST_TIME}\n            onClose={closeToast}\n          />\n\n          <ConfirmInvestDefiServiceUpdate\n            isCianETHJoin={isJoin}\n            open={serverUpdate}\n            handleClose={() => setServerUpdate(false)}\n          />\n          <ConfirmInvestDefiRisk\n            confirmationNeeded={confirmationNeeded}\n            open={_confirmedDefiInvest.isShow}\n            type={_confirmedDefiInvest.type as any}\n            handleClose={(_e, isAgree) => {\n              if (!isAgree) {\n                setConfirmedDefiInvest({ isShow: false })\n                history.push(`${RouterPath.invest}/${InvestRouter[InvestType.Overview]}`)\n              } else {\n                confirmedLeverageETHInvest()\n                setConfirmedDefiInvest({ isShow: false })\n              }\n            }}\n          />\n        </StyleWrapper>\n      </MaxWidthContainer>\n    </Box>\n  )\n})\n\nexport default LeverageETHPanel\n"
  },
  {
    "path": "packages/webapp/src/pages/InvestPage/MyLiquidityPanel/hook.ts",
    "content": "import React from 'react'\nimport {\n  AmmRecordRow,\n  MyPoolRow,\n  RawDataDefiSideStakingItem,\n  RawDefiAssetsItem,\n} from '@loopring-web/component-lib'\nimport {\n  LoopringAPI,\n  makeDefiInvestReward,\n  makeWalletLayer2,\n  store,\n  SummaryMyInvest,\n  useAccount,\n  useAmmMap,\n  useDefiMap,\n  useStakingMap,\n  useTokenMap,\n  useTokenPrices,\n  useUserRewards,\n  useWalletLayer2Socket,\n  walletLayer2Service,\n} from '@loopring-web/core'\nimport {\n  AccountStatus,\n  CustomError,\n  ErrorMap,\n  getValuePrecisionThousand,\n  myLog,\n  RowInvestConfig,\n  SagaStatus,\n  STAKING_INVEST_LIMIT,\n} from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { useGetAssets } from '../../AssetPage/AssetPanel/hook'\n\nexport const useOverview = <R extends { [key: string]: any }, I extends { [key: string]: any }>({\n  rowConfig = RowInvestConfig,\n  hideSmallBalances,\n}: {\n  ammActivityMap: sdk.LoopringMap<sdk.LoopringMap<sdk.AmmPoolActivityRule[]>> | undefined\n  dualOnInvestAsset: any //RawDataDualAssetItem[];\n  rowConfig?: any\n  hideSmallBalances: boolean\n}) => {\n  const { assetsRawMap, onReceive, onSend } = useGetAssets()\n  const { account, status: accountStatus } = useAccount()\n  const {\n    status: userRewardsStatus,\n    userRewardsMap,\n    myAmmLPMap,\n    getUserRewards,\n    defiAverageMap,\n  } = useUserRewards()\n  const { tokenMap } = useTokenMap()\n  const {\n    marketCoins: defiCoinArray,\n    marketLeverageMap: defiLeverageMap,\n    marketMap: defiMap,\n    marketLeverageCoins: leverageETHCoinArray,\n  } = useDefiMap()\n  const { status: ammMapStatus, ammMap } = useAmmMap()\n  const { status: tokenPricesStatus, tokenPrices } = useTokenPrices()\n  const { marketMap: stakingMap } = useStakingMap()\n  const [summaryMyInvest, setSummaryMyInvest] = React.useState<Partial<SummaryMyInvest>>({})\n  const [filter, setFilter] = React.useState({\n    searchValue: '',\n  })\n  const [stakeShowLoading, setStakeShowLoading] = React.useState(false)\n  const [\n    {\n      stakingList,\n      total: stakingTotal,\n      totalStaked,\n      totalLastDayPendingRewards,\n      totalStakedRewards,\n      totalClaimableRewards,\n      stakedSymbol,\n    },\n    setStakingProps,\n  ] = React.useState<{\n    stakingList: RawDataDefiSideStakingItem[]\n    totalStaked: string\n    totalLastDayPendingRewards: string\n    totalStakedRewards: string\n    totalClaimableRewards: string\n    total: number\n    stakedSymbol: string\n  }>({\n    stakingList: [],\n    total: 0,\n    totalStaked: '0',\n    totalLastDayPendingRewards: '0',\n    totalStakedRewards: '0',\n    totalClaimableRewards: '0',\n    stakedSymbol: 'LRC',\n  })\n\n  // const [totalData, setTotalData] = React.useState<MyPoolRow<R>[]>([]);\n  const [summaryDefiReward, setSummaryDefiReward] = React.useState('')\n  const [myPoolRow, setMyPoolRow] = React.useState<MyPoolRow<R>[]>([])\n  const [tableHeight, setTableHeight] = React.useState(0)\n  const resetTableData = React.useCallback(\n    (viewData) => {\n      setMyPoolRow(viewData)\n      setTableHeight(\n        viewData.length > 0\n          ? rowConfig.rowHeaderHeight + viewData.length * rowConfig.rowHeight\n          : 350,\n      )\n    },\n    [rowConfig.rowHeaderHeight, rowConfig.rowHeight],\n  )\n  const updateData = React.useCallback(() => {\n    if (myAmmLPMap) {\n      let resultData: MyPoolRow<R>[] = Object.keys(myAmmLPMap).map((key) => ({\n        ...myAmmLPMap[key],\n        ammDetail: ammMap['AMM-' + key],\n      }))\n\n      if (hideSmallBalances) {\n        myLog('hideSmallBalances', hideSmallBalances, resultData)\n        resultData = resultData.filter((o) => sdk.toBig(o?.balanceU ?? 0).gt(0))\n      }\n      if (filter.searchValue) {\n        resultData = resultData.filter(\n          (o) =>\n            o.ammDetail.coinAInfo.simpleName\n              .toLowerCase()\n              .includes(filter.searchValue.toLowerCase()) ||\n            o.ammDetail.coinBInfo.simpleName\n              .toLowerCase()\n              .includes(filter.searchValue.toLowerCase()),\n        )\n      }\n      resetTableData(resultData)\n    }\n  }, [\n    ammMap,\n    myAmmLPMap,\n    filter,\n    hideSmallBalances,\n    resetTableData,\n    defiCoinArray,\n    leverageETHCoinArray,\n  ])\n  const handleFilterChange = React.useCallback(\n    (filter) => {\n      setFilter(filter)\n    },\n    [setFilter],\n  )\n  React.useEffect(() => {\n    updateData()\n  }, [filter, hideSmallBalances])\n\n  const [myAmmMarketArray, setMyAmmMarketArray] = React.useState<AmmRecordRow<R>[]>([])\n  const [showLoading, setShowLoading] = React.useState(false)\n  const mountedRef = React.useRef(false)\n\n  const walletLayer2Callback = React.useCallback(() => {\n    if (ammMap && tokenPrices && userRewardsMap && myAmmLPMap) {\n      setShowLoading(true)\n      updateData()\n      let resultData: MyPoolRow<R>[] = Object.keys(myAmmLPMap).map((key) => ({\n        ...myAmmLPMap[key],\n        ammDetail: ammMap['AMM-' + key],\n      }))\n      let totalCurrentInvest = {\n        ammPoolDollar: 0,\n        stakeETHDollar: 0,\n        leverageETHDollar: 0,\n        // dualStakeDollar: summaryDefiReward,\n      }\n      const { walletMap: _walletMap } = makeWalletLayer2({ needFilterZero: false })\n\n      defiCoinArray?.forEach((defiCoinKey) => {\n        totalCurrentInvest.stakeETHDollar += Number(\n          // @ts-ignore\n          (_walletMap[defiCoinKey]?.count?.toString()?.replaceAll(sdk.SEP, '') ?? 0) *\n            (tokenPrices ? tokenPrices[defiCoinKey] : 0),\n        )\n      }, [])\n      resultData.forEach((item) => {\n        totalCurrentInvest.ammPoolDollar += Number(item.balanceU ?? 0)\n      })\n      leverageETHCoinArray?.forEach((defiCoinKey) => {\n        totalCurrentInvest.leverageETHDollar += Number(\n          // @ts-ignore\n          (_walletMap[defiCoinKey]?.count?.toString()?.replaceAll(sdk.SEP, '') ?? 0) *\n            tokenPrices[defiCoinKey] ?? 0,\n        )\n      })\n      setSummaryMyInvest((state) => {\n        return {\n          ...state,\n          ...totalCurrentInvest,\n          investDollar: sdk\n            .toBig(totalCurrentInvest.ammPoolDollar ?? 0)\n            .plus(totalCurrentInvest.stakeETHDollar ?? 0)\n            .plus(totalCurrentInvest.leverageETHDollar ?? 0)\n            .plus(state.stakeLRCDollar ?? 0)\n            .toString(),\n        }\n      })\n      setShowLoading(false)\n    }\n  }, [\n    ammMap,\n    tokenPrices,\n    userRewardsMap,\n    summaryDefiReward,\n    leverageETHCoinArray,\n    myAmmLPMap,\n    defiCoinArray,\n    updateData,\n  ])\n\n  React.useEffect(() => {\n    if (\n      ammMapStatus === SagaStatus.UNSET &&\n      accountStatus === SagaStatus.UNSET &&\n      tokenPricesStatus === SagaStatus.UNSET\n    ) {\n      walletLayer2Service.sendUserUpdate()\n    }\n  }, [ammMapStatus, accountStatus, tokenPricesStatus])\n\n  React.useEffect(() => {\n    if (userRewardsStatus === SagaStatus.UNSET) {\n      walletLayer2Callback()\n    }\n  }, [userRewardsStatus])\n  useWalletLayer2Socket({\n    walletLayer2Callback: async () => {\n      const account = store.getState().account\n      if (account.readyState == AccountStatus.ACTIVATED) {\n        getStakingList({})\n        await makeDefiInvestReward().then((summaryDefiReward) => {\n          if (mountedRef.current) {\n            setSummaryDefiReward(summaryDefiReward.toString())\n          }\n        })\n        getUserRewards()\n      } else {\n        walletLayer2Callback()\n      }\n    },\n  })\n\n  React.useEffect(() => {\n    mountedRef.current = true\n    setShowLoading(true)\n    return () => {\n      mountedRef.current = false\n    }\n  }, [])\n\n  const getStakingList = React.useCallback(\n    async ({ limit = STAKING_INVEST_LIMIT, offset = 0 }: { limit?: number; offset?: number }) => {\n      setStakeShowLoading(true)\n      const LRCStakingSymbol = 'LRC'\n      if (LoopringAPI.defiAPI && account.readyState === AccountStatus.ACTIVATED) {\n        const [response] = await Promise.all([\n          LoopringAPI.defiAPI.getStakeSummary(\n            {\n              accountId: account.accountId,\n              limit,\n              offset,\n              statuses: 'locked,partial_unlocked',\n              tokenId: tokenMap[LRCStakingSymbol].tokenId,\n            },\n            account.apiKey,\n          ),\n        ])\n        if (\n          (response &&\n            ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message)) ||\n          !stakingMap[LRCStakingSymbol]\n        ) {\n          throw new CustomError(ErrorMap.ERROR_UNKNOWN)\n        } else {\n          let {\n            totalNum,\n            totalStaked,\n            totalStakedRewards,\n            totalLastDayPendingRewards,\n            totalClaimableRewards,\n            list,\n          } = response as any\n\n          list = list.map((item: sdk.StakeInfoOrigin) => {\n            return {\n              ...stakingMap[LRCStakingSymbol],\n              ...item,\n              status_product: stakingMap[LRCStakingSymbol].status,\n            }\n          })\n\n          setStakingProps({\n            total: totalNum,\n            stakingList: list,\n            totalStaked,\n            totalStakedRewards,\n            totalLastDayPendingRewards,\n            totalClaimableRewards,\n            stakedSymbol: LRCStakingSymbol,\n          })\n\n          const totalDollar = sdk\n            .toBig(totalStaked)\n            .div('1e' + tokenMap[LRCStakingSymbol].decimals)\n            .times(tokenPrices[LRCStakingSymbol])\n\n          setSummaryMyInvest((state) => {\n            return {\n              ...state,\n              stakeLRCDollar: totalDollar.toString(),\n              investDollar: sdk\n                .toBig(state.ammPoolDollar ?? 0)\n                .plus(state.dualStakeDollar ?? 0)\n                .plus(state.stakeETHDollar ?? 0)\n                .plus(state.leverageETHDollar ?? 0)\n                .plus(totalDollar ?? 0)\n                .toString(),\n            }\n          })\n        }\n      }\n      setStakeShowLoading(false)\n    },\n    [account, tokenPrices, tokenMap, stakingMap],\n  )\n\n  const reduceDefiFunc = (prev, item) => {\n    if (assetsRawMap[item]) {\n      const market = `${item}-ETH`\n      const defiInfo = {\n        ...defiMap,\n        ...defiLeverageMap,\n      }[market]\n      const precision = item.precision\n      const baseToken = 'ETH'\n      prev.push({\n        ...assetsRawMap[item],\n        market,\n        baseToken,\n        apr: defiInfo?.apy ? Number(defiInfo?.apy) : 0,\n        defiInfo,\n        average:\n          defiAverageMap &&\n          defiAverageMap[market]?.average &&\n          defiAverageMap[market]?.average !== '0'\n            ? getValuePrecisionThousand(defiAverageMap[market]?.average, precision, precision)\n            : undefined,\n      } as any)\n    }\n    return prev\n  }\n  return {\n    myAmmMarketArray,\n    summaryMyInvest,\n    myPoolRow,\n    showLoading,\n    filter,\n    tableHeight,\n    handleFilterChange,\n    stakingList,\n    getStakingList,\n    stakeShowLoading,\n    stakingTotal,\n    totalStaked,\n    totalStakedRewards,\n    totalLastDayPendingRewards,\n    totalClaimableRewards,\n    stakedSymbol,\n    onReceive,\n    onSend,\n    leverageETHAssets: leverageETHCoinArray?.reduce(reduceDefiFunc, [] as Array<RawDefiAssetsItem>),\n    defiAsset: defiCoinArray?.reduce(reduceDefiFunc, [] as Array<RawDefiAssetsItem>),\n  }\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/InvestPage/MyLiquidityPanel/index.tsx",
    "content": "import { Box, Button, Divider, Grid, Modal, Tab, Typography } from '@mui/material'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport { useHistory, useLocation, useRouteMatch } from 'react-router-dom'\nimport {\n  AssetsTable,\n  ButtonStyle,\n  CancelDualAlert,\n  DefiStakingTable,\n  DualAssetTable,\n  DualDetail,\n  EarningsDetail,\n  ModalCloseButton,\n  MyPoolTable,\n  SwitchPanelStyled,\n  Toast,\n  ToastType,\n  useOpenModals,\n  useSettings,\n  Tabs,\n  CoinIcons,\n  MaxWidthContainer,\n  AssetsDefiTable,\n  useToggle,\n} from '@loopring-web/component-lib'\nimport {\n  AccountStatus,\n  AssetTabIndex,\n  CurrencyToTag,\n  DualViewBase,\n  EmptyValueTag,\n  FailedIcon,\n  getValuePrecisionThousand,\n  HiddenTag,\n  INVEST_TABS,\n  InvestAssetRouter,\n  AmmPanelType,\n  L1L2_NAME_DEFINED,\n  MapChainId,\n  myLog,\n  PriceTag,\n  RowInvestConfig,\n  SagaStatus,\n  STAKING_INVEST_LIMIT,\n  TOAST_TIME,\n  TokenType,\n  TradeBtnStatus,\n  RouterPath,\n  RecordTabIndex,\n  InvestRouter,\n  InvestType,\n  RowConfig,\n} from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { useOverview } from './hook'\nimport {\n  TableWrapStyled,\n  useAccount,\n  useAmmActivityMap,\n  useDefiMap,\n  useDualMap,\n  useStakeRedeemClick,\n  useSystem,\n  useTokenMap,\n  useTokenPrices,\n  useUserRewards,\n  confirmation,\n} from '@loopring-web/core'\nimport { useTheme } from '@emotion/react'\nimport React from 'react'\nimport { containerColors } from '..'\nimport _ from 'lodash'\nimport { useDualAsset } from '../../AssetPage/HistoryPanel'\n\nconst MyLiquidity: any = withTranslation('common')(\n  ({\n    t,\n    isHideTotal,\n    hideAssets,\n    className,\n    noHeader,\n    path = `${RouterPath.invest}/${InvestRouter[InvestType.MyBalance]}`,\n    /* ammActivityMap, */ ...rest\n  }: WithTranslation & {\n    isHideTotal?: boolean\n    className?: string\n    ammActivityMap: sdk.LoopringMap<sdk.LoopringMap<sdk.AmmPoolActivityRule[]>> | undefined\n    hideAssets?: boolean\n    noHeader?: boolean\n    path?: string\n  }) => {\n    let match: any = useRouteMatch(path + '/:type')\n    const { toggle } = useToggle()\n    const { search } = useLocation()\n    const searchParams = new URLSearchParams(search)\n    const { totalClaims, getUserRewards, errorMessage: rewardsAPIError } = useUserRewards()\n    const { setShowAutoDefault, confirmation: { showAutoDefault } } = confirmation.useConfirmation()\n    const ammPoolRef = React.useRef(null)\n    const stakingRef = React.useRef(null)\n    const leverageETHRef = React.useRef(null)\n    const dualRef = React.useRef(null)\n    const sideStakeRef = React.useRef(null)\n    const { ammActivityMap } = useAmmActivityMap()\n    const { forexMap } = useSystem()\n    const { tokenMap, disableWithdrawList, idIndex } = useTokenMap()\n    const { tokenPrices } = useTokenPrices()\n    const { redeemItemClick } = useStakeRedeemClick()\n    const { marketMap: dualMarketMap, status: dualMarketMapStatus } = useDualMap()\n    const { account } = useAccount()\n    const history = useHistory()\n    const { currency, hideSmallBalances, defaultNetwork, coinJson } = useSettings()\n    const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n    const { setShowAmm } = useOpenModals()\n    const [showCancelOneAlert, setShowCancelOndAlert] = React.useState<{\n      open: boolean\n      row?: any\n    }>({\n      open: false,\n      row: undefined,\n    })\n    const {\n      dualList,\n      dualOnInvestAsset,\n      getDualTxList,\n      pagination,\n      showDetail,\n      showLoading: dualLoading,\n      open: dualOpen,\n      detail: dualDetail,\n      setOpen: setDualOpen,\n      getDetail,\n      refresh,\n      setShowRefreshError,\n      showRefreshError,\n      refreshErrorInfo,\n      dualProducts,\n      getProduct,\n      cancelReInvest,\n      dualToastOpen,\n      closeDualToast,\n      editDualTrade,\n      editDualBtnInfo,\n      editDualBtnStatus,\n      handleOnchange,\n      onEditDualClick,\n    } = useDualAsset()\n    const {\n      summaryMyInvest,\n      myPoolRow,\n      showLoading,\n      filter,\n      tableHeight,\n      handleFilterChange,\n      stakingList,\n      getStakingList,\n      stakeShowLoading,\n      stakingTotal,\n      totalStakedRewards,\n      stakedSymbol,\n      leverageETHAssets,\n      defiAsset,\n      onReceive,\n      onSend,\n    } = useOverview({\n      ammActivityMap,\n      dualOnInvestAsset,\n      hideSmallBalances,\n      // dualList,\n    })\n    const { marketLeverageCoins: marketCoins, marketCoins: ethStakingCoins } = useDefiMap()\n\n    React.useEffect(() => {\n      if (\n        account.readyState === AccountStatus.ACTIVATED &&\n        dualMarketMapStatus === SagaStatus.UNSET\n      ) {\n        getDualTxList({})\n      }\n    }, [account.readyState, dualMarketMapStatus])\n\n    const theme = useTheme()\n    const { isMobile } = useSettings()\n    const totalClaimableRewardsAmount =\n      rewardsAPIError || !totalClaims\n        ? '0'\n        : getValuePrecisionThousand(\n            sdk\n              .toBig(\n                totalClaims['LRC']?.detail?.find(\n                  (item: EarningsDetail) => item.claimType === sdk.CLAIM_TYPE.LRC_STAKING,\n                )?.amount ?? 0,\n              )\n              .div('1e' + tokenMap[stakedSymbol].decimals),\n            tokenMap[stakedSymbol].precision,\n            tokenMap[stakedSymbol].precision,\n            tokenMap[stakedSymbol].precision,\n            false,\n            { floor: true, isAbbreviate: true },\n          )\n\n    const totalAMMClaims: { totalDollar: string; detail: EarningsDetail[] } = rewardsAPIError\n      ? { totalDollar: '0', detail: [] }\n      : Reflect.ownKeys(totalClaims ?? {}).reduce(\n          (prev, key) => {\n            const item = totalClaims[key]?.detail?.find(\n              (item: EarningsDetail) => item.claimType === sdk.CLAIM_TYPE.PROTOCOL_FEE,\n            )\n            if (item && item.amount !== '0') {\n              prev.detail.push({ ...item })\n              prev.totalDollar = sdk.toBig(item.tokenValueDollar).plus(prev.totalDollar).toString()\n            }\n            return prev\n          },\n          { totalDollar: '0', detail: [] } as { totalDollar: string; detail: EarningsDetail[] },\n        )\n    const dualStakeDollar = React.useMemo(() => {\n      return dualOnInvestAsset\n        ? dualOnInvestAsset.reduce((pre: string, cur: any) => {\n            const price = tokenPrices[idIndex[cur.tokenId]]\n            return sdk\n              .toBig(cur?.amount ?? 0)\n              .div('1e' + tokenMap[idIndex[cur.tokenId]].decimals)\n              .times(price ?? 0)\n              .plus(pre)\n              .toString()\n          }, '0')\n        : undefined\n    }, [dualOnInvestAsset, tokenPrices])\n    const _summaryMyInvest = sdk\n      .toBig(dualStakeDollar ?? 0)\n      .plus(summaryMyInvest.investDollar ?? 0)\n      .toString()\n    const visibaleTabs = _.cloneDeep(INVEST_TABS).filter(() => {\n      return true\n    })\n    const [tab, setTab] = React.useState(match?.params?.type ?? InvestAssetRouter.DUAL)\n    React.useEffect(() => {\n      const tab = match?.params?.type ?? InvestAssetRouter.DUAL\n      setTab(tab)\n      if (account.readyState === AccountStatus.ACTIVATED) {\n        if (tab == InvestAssetRouter.DUAL && dualMarketMapStatus === SagaStatus.UNSET) {\n          getDualTxList({})\n          if (\n            searchParams?.get('show') == 'detail' &&\n            match?.params?.type == InvestAssetRouter.DUAL &&\n            searchParams?.has('hash')\n          ) {\n            let hash = searchParams.get('hash')\n            refresh(hash ?? '', true)\n          }\n        }\n\n        if (searchParams?.get('refreshStake')) {\n          getStakingList({})\n        }\n      }\n    }, [match?.params?.type, searchParams?.toString(), dualMarketMapStatus, account.readyState])\n\n    const label = React.useMemo(() => {\n      if (editDualBtnInfo.label) {\n        const key = editDualBtnInfo.label.split('|')\n        return t(\n          key[0],\n          key && key[1]\n            ? {\n                arg: key[1].toString(),\n                l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n              }\n            : {\n                l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n              },\n        )\n      } else {\n        return t(`labelDualModifyBtn`, {\n          l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n          loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n          l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n          l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n          ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n        })\n      }\n    }, [editDualBtnInfo.label])\n\n    const _cancelReInvest = (item) => {\n      setShowCancelOndAlert({ open: true, row: item })\n    }\n    const nanToEmptyTag = (value: any, prefix: string) => {\n      return value === 'NaN' ? EmptyValueTag : prefix + value\n    }\n    return (\n      <Box display={'flex'} flex={1} position={'relative'} flexDirection={'column'}>\n        {!noHeader && (\n          <MaxWidthContainer\n            height={isMobile ? 70 * theme.unit : 34 * theme.unit}\n            alignItems={'center'}\n            background={containerColors[0]}\n          >\n            <Box\n              display={'flex'}\n              justifyContent={'space-between'}\n              flexDirection={isMobile ? 'column' : 'row'}\n              alignItems={isMobile ? 'start' : 'center'}\n              alignSelf={'stretch'}\n            >\n              <Box paddingY={7}>\n                <Typography marginBottom={5} fontSize={'38px'} variant={'h1'}>\n                  {t('labelInvestBalanceTitle')}\n                </Typography>\n                <Button\n                  onClick={() => {\n                    history.push(`${RouterPath.invest}/${InvestRouter[InvestType.Overview]}`)\n                  }}\n                  sx={{ width: isMobile ? 36 * theme.unit : 18 * theme.unit, marginRight: 2 }}\n                  variant={'contained'}\n                >\n                  {t('labelInvestOverviewTitle')}\n                </Button>\n                <Button\n                  onClick={() => {\n                    let item = RecordTabIndex.Transactions\n                    switch (tab) {\n                      case InvestAssetRouter.DUAL:\n                        item = RecordTabIndex.DualRecords\n                        break\n                      case InvestAssetRouter.AMM:\n                        item = RecordTabIndex.AmmRecords\n                        break\n                      case InvestAssetRouter.STAKE:\n                        item = RecordTabIndex.DefiRecords\n                        break\n                      case InvestAssetRouter.STAKELRC:\n                        item = RecordTabIndex.SideStakingRecords\n                        break\n                      case InvestAssetRouter.LEVERAGEETH:\n                        item = RecordTabIndex.leverageETHRecords\n                        break\n                      default:\n                        break\n                    }\n                    history.push(`${RouterPath.l2records}/${item}`)\n                  }}\n                  sx={{ width: isMobile ? 36 * theme.unit : 18 * theme.unit }}\n                  variant={'contained'}\n                >\n                  {t('labelTxnDetailHeader')}\n                </Button>\n              </Box>\n              <Box\n                sx={{ background: 'var(--color-box-secondary)' }}\n                width={'var(--earning-banner-width)'}\n                border={'1px solid var(--color-border)'}\n                borderRadius={0.5}\n                paddingX={3}\n                paddingY={4}\n                display={'flex'}\n                justifyContent={'space-between'}\n                marginRight={10}\n                marginBottom={isMobile ? 7 : 0}\n              >\n                <Box>\n                  <Typography marginBottom={2} color={'var(--color-text-third)'} variant={'h6'}>\n                    {t('labelTotalPositionValue')}\n                  </Typography>\n                  <Typography>\n                    {_summaryMyInvest\n                      ? PriceTag[CurrencyToTag[currency]] +\n                        getValuePrecisionThousand(\n                          sdk\n                            .toBig(_summaryMyInvest)\n                            .times(forexMap[currency] ?? 0)\n                            .toString(),\n                          undefined,\n                          undefined,\n                          2,\n                          true,\n                          { isFait: true, floor: true },\n                        )\n                      : EmptyValueTag}\n                  </Typography>\n                </Box>\n                <Box>\n                  <Typography color={'var(--color-text-third)'} marginBottom={2} variant={'h6'}>\n                    {t('labelInvestTotalEarnings')}\n                  </Typography>\n                  <Typography>\n                    {summaryMyInvest.rewardU\n                      ? PriceTag[CurrencyToTag[currency]] +\n                        getValuePrecisionThousand(\n                          summaryMyInvest.rewardU,\n                          undefined,\n                          undefined,\n                          2,\n                          true,\n                          { isFait: true, floor: true },\n                        )\n                      : EmptyValueTag}\n                  </Typography>\n                </Box>\n              </Box>\n            </Box>\n          </MaxWidthContainer>\n        )}\n        <MaxWidthContainer\n          marginBottom={3}\n          marginTop={3}\n          minHeight={'80vh'}\n          background={noHeader ? 'var(--color-box-third)' : containerColors[1]}\n          containerProps={{\n            borderRadius: noHeader ? `${theme.unit}px` : 0,\n            marginTop: noHeader ? 1 : 0,\n          }}\n          // sx={{ flexDirection: 'column' }}\n        >\n          {\n            <>\n              <Box width={'100%'} display={'flex'}>\n                <Tabs\n                  variant='scrollable'\n                  className={'btnTab'}\n                  value={tab}\n                  onChange={(_event: any, newValue: any) => {\n                    myLog('newValue', newValue)\n                    history.push(`${path}/${newValue}`)\n                  }}\n                  aria-label='InvestmentsTab'\n                >\n                  {visibaleTabs.map((tab) => (\n                    <Tab value={tab.tab.toString()} label={t(tab.label).toString()} key={tab.tab} />\n                  ))}\n                </Tabs>\n              </Box>\n\n              {tab === InvestAssetRouter.AMM && (\n                <TableWrapStyled\n                  ref={ammPoolRef}\n                  className={`table-divide-short`}\n                  marginTop={2}\n                  paddingY={2}\n                  paddingX={0}\n                  flex={1}\n                  marginLeft={-3}\n                >\n                  <Grid item xs={12} display={'flex'} flexDirection={'column'} flex={1}>\n                    <MyPoolTable\n                      totalAMMClaims={totalAMMClaims}\n                      rewardsAPIError={rewardsAPIError}\n                      getUserRewards={getUserRewards}\n                      forexMap={forexMap as any}\n                      title={\n                        <Typography\n                          variant={'h5'}\n                          // marginBottom={isMobile ? 3 : 0}\n                          // paddingLeft={3}\n                        >\n                          {t('labelMyAmm')}\n                        </Typography>\n                      }\n                      totalDollar={summaryMyInvest.ammPoolDollar}\n                      tableHeight={tableHeight}\n                      filter={filter}\n                      handleFilterChange={handleFilterChange}\n                      hideSmallBalances={hideSmallBalances}\n                      allowTrade={toggle}\n                      rawData={myPoolRow}\n                      showFilter={true}\n                      account={account}\n                      showloading={showLoading}\n                      currency={currency}\n                      tokenMap={tokenMap as any}\n                      idIndex={idIndex}\n                      tokenPrices={tokenPrices as any}\n                      handleWithdraw={(row) => {\n                        const pair = `${row.ammDetail.coinAInfo.simpleName}-${row.ammDetail.coinBInfo.simpleName}`\n                        setShowAmm({\n                          isShow: true,\n                          type: AmmPanelType.Exit,\n                          symbol: pair,\n                        })\n                      }}\n                      handleDeposit={(row) => {\n                        const pair = `${row.ammDetail.coinAInfo.simpleName}-${row.ammDetail.coinBInfo.simpleName}`\n                        setShowAmm({\n                          isShow: true,\n                          type: AmmPanelType.Join,\n                          symbol: pair,\n                        })\n                      }}\n                      rowConfig={RowInvestConfig}\n                      hideAssets={hideAssets}\n                    />\n                  </Grid>\n                </TableWrapStyled>\n              )}\n              {tab === InvestAssetRouter.STAKELRC && (\n                <TableWrapStyled\n                  ref={sideStakeRef}\n                  className={`table-divide-short min-height`}\n                  marginTop={2}\n                  paddingY={2}\n                  paddingX={0}\n                  flex={1}\n                  marginLeft={-3}\n                >\n                  <Grid container>\n                    <Grid item md={6} xs={12}>\n                      <Typography variant={'h5'} marginBottom={2} marginX={3}>\n                        {t('labelInvestType_LRCSTAKE')}\n                      </Typography>\n                      {summaryMyInvest?.stakeLRCDollar !== undefined ? (\n                        <Typography component={'h4'} variant={'h3'} marginX={3}>\n                          {summaryMyInvest?.stakeLRCDollar\n                            ? hideAssets\n                              ? HiddenTag\n                              : nanToEmptyTag(\n                                  getValuePrecisionThousand(\n                                    sdk\n                                      .toBig(summaryMyInvest?.stakeLRCDollar)\n                                      .times(forexMap[currency] ?? 0),\n                                    undefined,\n                                    undefined,\n                                    2,\n                                    true,\n                                    { isFait: true, floor: true },\n                                  ),\n                                  PriceTag[CurrencyToTag[currency]],\n                                )\n                            : EmptyValueTag}\n                        </Typography>\n                      ) : (\n                        ''\n                      )}\n                    </Grid>\n                    <Grid\n                      item\n                      md={3}\n                      xs={6}\n                      justifyContent={'space-evenly'}\n                      flexDirection={'column'}\n                      alignItems={isMobile ? 'flex-start' : 'flex-end'}\n                      display={'flex '}\n                    >\n                      <Typography variant={'body1'} marginBottom={1} marginX={3} component={'span'}>\n                        {t('labelStakingCumulativeEarnings')}\n                      </Typography>\n                      <Typography variant={'body1'} marginBottom={1} marginX={3} component={'span'}>\n                        {totalStakedRewards && totalStakedRewards !== '0'\n                          ? hideAssets\n                            ? HiddenTag\n                            : getValuePrecisionThousand(\n                                sdk\n                                  .toBig(totalStakedRewards ?? 0)\n                                  .div('1e' + tokenMap[stakedSymbol].decimals),\n                                tokenMap[stakedSymbol].precision,\n                                tokenMap[stakedSymbol].precision,\n                                tokenMap[stakedSymbol].precision,\n                                false,\n                                { floor: true, isAbbreviate: true },\n                              ) +\n                              ' ' +\n                              stakedSymbol\n                          : EmptyValueTag}\n                      </Typography>\n                    </Grid>\n\n                    <Grid\n                      item\n                      md={3}\n                      xs={6}\n                      justifyContent={'space-evenly'}\n                      flexDirection={'column'}\n                      alignItems={'flex-end'}\n                      display={'flex'}\n                    >\n                      <Typography variant={'body1'} marginBottom={1} marginX={3} component={'span'}>\n                        {t('labelStakingClaimableEarnings')}\n                      </Typography>\n                      <Box\n                        marginBottom={1}\n                        marginX={3}\n                        display={'flex'}\n                        flexDirection={'row'}\n                        alignItems={'center'}\n                      >\n                        {rewardsAPIError ? (\n                          <Button\n                            onClick={() => {\n                              getUserRewards && getUserRewards()\n                            }}\n                            size={'small'}\n                            variant={'outlined'}\n                          >\n                            {t('labelRewardRefresh', { ns: 'common' })}\n                          </Button>\n                        ) : totalClaimableRewardsAmount !== '0' ? (\n                          <>\n                            <Typography component={'span'} display={'inline-flex'} paddingRight={2}>\n                              {hideAssets\n                                ? HiddenTag\n                                : totalClaimableRewardsAmount + ' ' + stakedSymbol}\n                            </Typography>\n                            <Button\n                              variant={'contained'}\n                              size={'small'}\n                              onClick={() => {\n                                history.push(\n                                  `${RouterPath.l2assetsDetail}/${AssetTabIndex.Rewards}`,\n                                )\n                              }}\n                            >\n                              {t('labelClaimBtn')}\n                            </Button>\n                          </>\n                        ) : (\n                          <Typography component={'span'} display={'inline-flex'}>\n                            {EmptyValueTag}\n                          </Typography>\n                        )}\n                      </Box>\n                    </Grid>\n                  </Grid>\n\n                  <DefiStakingTable\n                    {...{\n                      rawData: stakingList,\n                      pagination: {\n                        pageSize: STAKING_INVEST_LIMIT,\n                        total: stakingTotal,\n                      },\n                      idIndex,\n                      tokenMap,\n                      redeemItemClick,\n                      geDefiSideStakingList: getStakingList,\n                      showloading: stakeShowLoading,\n                      hideAssets,\n                      ...rest,\n                    }}\n                  />\n                </TableWrapStyled>\n              )}\n              {tab === InvestAssetRouter.STAKE && (\n                <TableWrapStyled\n                  ref={stakingRef}\n                  className={`table-divide-short`}\n                  marginTop={2}\n                  paddingY={2}\n                  paddingX={0}\n                  flex={1}\n                  marginLeft={-3}\n                >\n                  <Grid item xs={12}>\n                    <Typography variant={'h5'} marginBottom={1} marginX={3}>\n                      {t('labelInvestType_STAKE')}\n                    </Typography>\n                  </Grid>\n                  <Grid item xs={12} display={'flex'} flexDirection={'column'} flex={1} marginX={0}>\n                    {summaryMyInvest?.stakeETHDollar !== undefined ? (\n                      <Typography component={'h4'} variant={'h3'} marginX={3}>\n                        {summaryMyInvest?.stakeETHDollar\n                          ? hideAssets\n                            ? HiddenTag\n                            : nanToEmptyTag(\n                                getValuePrecisionThousand(\n                                  sdk\n                                    .toBig(summaryMyInvest?.stakeETHDollar)\n                                    .times(forexMap[currency] ?? 0),\n                                  undefined,\n                                  undefined,\n                                  2,\n                                  true,\n                                  { isFait: true, floor: true },\n                                ),\n                                PriceTag[CurrencyToTag[currency]],\n                              )\n                          : EmptyValueTag}\n                      </Typography>\n                    ) : (\n                      ''\n                    )}\n                    <AssetsDefiTable\n                      {...{\n                        disableWithdrawList,\n                        onReceive,\n                        onSend,\n                        rawData: defiAsset,\n                        showFilter: false,\n                        allowTrade: toggle,\n                        rowConfig: RowInvestConfig,\n                        forexMap: forexMap as any,\n                        isInvest: true,\n                        hideAssets,\n                        ...rest,\n                      }}\n                    />\n                  </Grid>\n                </TableWrapStyled>\n              )}\n              {tab === InvestAssetRouter.LEVERAGEETH && (\n                <TableWrapStyled\n                  ref={leverageETHRef}\n                  className={`table-divide-short MuiPaper-elevation2 ${\n                    leverageETHAssets?.length > 0 ? 'min-height' : ''\n                  }`}\n                  marginTop={2}\n                  paddingY={2}\n                  paddingX={0}\n                  flex={1}\n                >\n                  <Grid item xs={12}>\n                    <Typography variant={'h5'} marginBottom={1} marginX={3}>\n                      {t('labelLeverageETHTitle')}\n                    </Typography>\n                  </Grid>\n                  <Grid item xs={12} display={'flex'} flexDirection={'column'} flex={1} marginX={0}>\n                    {summaryMyInvest?.leverageETHDollar !== undefined ? (\n                      <Typography component={'h4'} variant={'h3'} marginX={3}>\n                        {summaryMyInvest?.leverageETHDollar\n                          ? hideAssets\n                            ? HiddenTag\n                            : nanToEmptyTag(\n                                getValuePrecisionThousand(\n                                  sdk\n                                    .toBig(summaryMyInvest?.leverageETHDollar)\n                                    .times(forexMap[currency] ?? 0),\n                                  undefined,\n                                  undefined,\n                                  2,\n                                  true,\n                                  { isFait: true, floor: true },\n                                ),\n                                PriceTag[CurrencyToTag[currency]],\n                              )\n                          : EmptyValueTag}\n                      </Typography>\n                    ) : (\n                      ''\n                    )}\n                    <AssetsDefiTable\n                      {...{\n                        disableWithdrawList,\n                        onReceive,\n                        onSend,\n                        rawData: leverageETHAssets,\n                        showFilter: false,\n                        allowTrade: toggle,\n                        rowConfig: RowInvestConfig,\n                        forexMap: forexMap as any,\n                        hideAssets,\n                        isLeverageETH: true,\n                        ...rest,\n                      }}\n                    />\n                  </Grid>\n                </TableWrapStyled>\n              )}\n              {tab === InvestAssetRouter.DUAL && (\n                <TableWrapStyled\n                  ref={dualRef}\n                  className={`table-divide-short min-height`}\n                  marginTop={2}\n                  paddingY={2}\n                  paddingX={0}\n                  flex={1}\n                  marginLeft={-3}\n                >\n                  <Grid item xs={12}>\n                    <Typography variant={'h5'} marginBottom={1} marginX={3}>\n                      {t('labelInvestType_DUAL')}\n                    </Typography>\n                  </Grid>\n                  <Grid item xs={12} display={'flex'} flexDirection={'column'} flex={1} margin={0}>\n                    {dualStakeDollar !== undefined ? (\n                      <Typography component={'h4'} variant={'h3'} marginX={3}>\n                        {dualStakeDollar && !Number.isNaN(dualStakeDollar)\n                          ? hideAssets\n                            ? HiddenTag\n                            : nanToEmptyTag(\n                                sdk\n                                  .toBig(dualStakeDollar?.replaceAll(sdk.SEP))\n                                  .times(forexMap[currency] ?? 0)\n                                  .toFixed(2, 1),\n                                PriceTag[CurrencyToTag[currency]],\n                              )\n                          : EmptyValueTag}\n                      </Typography>\n                    ) : (\n                      ''\n                    )}\n                    <DualAssetTable\n                      rawData={dualList}\n                      getDetail={getDetail}\n                      idIndex={idIndex}\n                      dualMarketMap={dualMarketMap}\n                      tokenMap={tokenMap}\n                      showloading={dualLoading}\n                      pagination={pagination}\n                      getDualAssetList={getDualTxList}\n                      showDetail={showDetail}\n                      refresh={(item) => refresh(item.__raw__.order.hash)}\n                      hideAssets={hideAssets}\n                      cancelReInvest={_cancelReInvest as any}\n                      getProduct={getProduct}\n                      rowConfig={RowConfig}\n                    />\n                    <Modal\n                      open={dualOpen}\n                      onClose={(_e: any) => setDualOpen(false)}\n                      aria-labelledby='modal-modal-title'\n                      aria-describedby='modal-modal-description'\n                    >\n                      <SwitchPanelStyled width={'var(--modal-width)'}>\n                        <ModalCloseButton onClose={(_e: any) => setDualOpen(false)} t={t} />\n                        <Box\n                          display={'flex'}\n                          flexDirection={'column'}\n                          alignItems={'flex-start'}\n                          alignSelf={'stretch'}\n                          marginTop={-4}\n                          justifyContent={'stretch'}\n                        >\n                          <Typography\n                            display={'flex'}\n                            flexDirection={'row'}\n                            component={'header'}\n                            alignItems={'center'}\n                            height={'var(--toolbar-row-height)'}\n                            paddingX={3}\n                          >\n                            <Typography component={'span'} display={'inline-flex'}>\n                              {/* eslint-disable-next-line react/jsx-no-undef */}\n                              <CoinIcons\n                                type={TokenType.dual}\n                                size={32}\n                                tokenIcon={[\n                                  coinJson[dualDetail?.dualViewInfo?.sellSymbol ?? ''],\n                                  coinJson[dualDetail?.dualViewInfo?.buySymbol ?? ''],\n                                ]}\n                              />\n                            </Typography>\n                            <Typography\n                              component={'span'}\n                              display={'inline-flex'}\n                              color={'textPrimary'}\n                            >\n                              {`${dualDetail?.dualViewInfo?.sellSymbol} / ${dualDetail?.dualViewInfo?.buySymbol}`}\n                            </Typography>\n                          </Typography>\n                          <Divider style={{ marginTop: '-1px', width: '100%' }} />\n                        </Box>\n\n                        {dualDetail && dualDetail.dualViewInfo && (\n                          <Box\n                            flex={1}\n                            paddingY={2}\n                            width={'100%'}\n                            display={'flex'}\n                            flexDirection={'column'}\n                            sx={\n                              isMobile\n                                ? {\n                                    maxHeight: 'initial',\n                                    overflowY: 'initial',\n                                  }\n                                : { maxHeight: 'var(--lage-modal-height)', overflowY: 'scroll' }\n                            }\n                          >\n                            <DualDetail\n                              setShowAutoDefault={setShowAutoDefault}\n                              showAutoDefault={showAutoDefault}\n                              isOrder={true}\n                              order={dualDetail?.__raw__?.order}\n                              btnConfirm={\n                                dualDetail.__raw__?.order?.dualReinvestInfo?.isRecursive && (\n                                  <ButtonStyle\n                                    fullWidth\n                                    variant={'contained'}\n                                    size={'medium'}\n                                    color={'primary'}\n                                    onClick={() => {\n                                      onEditDualClick()\n                                    }}\n                                    loading={\n                                      editDualBtnStatus === TradeBtnStatus.LOADING\n                                        ? 'true'\n                                        : 'false'\n                                    }\n                                    disabled={\n                                      editDualBtnStatus === TradeBtnStatus.LOADING ||\n                                      editDualBtnStatus === TradeBtnStatus.DISABLED\n                                    }\n                                  >\n                                    {label}\n                                  </ButtonStyle>\n                                )\n                              }\n                              showClock={\n                                dualDetail?.__raw__?.order?.dualReinvestInfo?.isRecursive &&\n                                dualDetail?.__raw__?.order?.settlementStatus?.toUpperCase() ==\n                                  sdk.SETTLEMENT_STATUS.PAID &&\n                                dualDetail?.__raw__?.order?.dualReinvestInfo?.retryStatus?.toUpperCase() ===\n                                  sdk.DUAL_RETRY_STATUS.RETRYING\n                              }\n                              dualProducts={dualProducts}\n                              dualViewInfo={dualDetail.dualViewInfo as DualViewBase}\n                              currentPrice={dualDetail.dualViewInfo.currentPrice}\n                              isPriceEditable={true}\n                              toggle={{ enable: true }}\n                              lessEarnTokenSymbol={dualDetail.lessEarnTokenSymbol}\n                              greaterEarnTokenSymbol={dualDetail.greaterEarnTokenSymbol}\n                              lessEarnView={dualDetail.lessEarnView}\n                              greaterEarnView={dualDetail.greaterEarnView}\n                              onChange={(item) => {\n                                handleOnchange({ tradeData: item })\n                              }}\n                              onChangeOrderReinvest={(info, item) => {\n                                if (info.on) {\n                                  handleOnchange({\n                                    tradeData: {\n                                      ...item,\n                                      isRenew: info.on,\n                                      renewTargetPrice: info.renewTargetPrice,\n                                      renewDuration: info.renewDuration,\n                                    } as any,\n                                  })\n                                  onEditDualClick({ dontCloseModal: false })\n                                } else {\n                                  handleOnchange({\n                                    tradeData: {\n                                      ...item,\n                                      isRenew: false,\n                                    } as any,\n                                  })\n                                  onEditDualClick({ dontCloseModal: false })\n                                }\n                              }}\n                              coinSell={{\n                                ...editDualTrade,\n                              }}\n                            />\n                          </Box>\n                        )}\n                      </SwitchPanelStyled>\n                    </Modal>\n                  </Grid>\n                </TableWrapStyled>\n              )}\n            </>\n          }\n        </MaxWidthContainer>\n        <Modal\n          open={showRefreshError}\n          onClose={(_e: any) => setShowRefreshError(false)}\n          aria-labelledby='modal-modal-title'\n          aria-describedby='modal-modal-description'\n        >\n          <SwitchPanelStyled width={'var(--modal-width)'}>\n            <ModalCloseButton onClose={(_e: any) => setShowRefreshError(false)} t={t} />\n            <Box marginTop={9}>\n              <FailedIcon color={'error'} style={{ width: 60, height: 60 }} />\n            </Box>\n\n            <Typography marginTop={1} variant={'h5'}>\n              {t('labelInvestDualRefreshErrorTitle')}\n            </Typography>\n            <Typography marginTop={5} marginBottom={22}>\n              {t('labelInvestDualRefreshError', {\n                token1: refreshErrorInfo[0],\n                token2: refreshErrorInfo[1],\n              })}\n            </Typography>\n          </SwitchPanelStyled>\n        </Modal>\n        <CancelDualAlert\n          open={showCancelOneAlert.open}\n          row={showCancelOneAlert.row}\n          handleCancelOne={async () => await cancelReInvest(showCancelOneAlert.row)}\n          handleClose={() => setShowCancelOndAlert({ open: false, row: undefined })}\n        />\n        <Toast\n          alertText={dualToastOpen?.content ?? ''}\n          severity={dualToastOpen?.type ?? ToastType.success}\n          open={dualToastOpen?.open ?? false}\n          autoHideDuration={TOAST_TIME}\n          onClose={() => {\n            if (closeDualToast) {\n              closeDualToast()\n            }\n          }}\n        />\n      </Box>\n    )\n  },\n)\n\nexport { MyLiquidity }\n"
  },
  {
    "path": "packages/webapp/src/pages/InvestPage/MyLiquidityPanel/interface.ts",
    "content": "export type Tab = 'pools' | 'lido' | 'staking' | 'dual'"
  },
  {
    "path": "packages/webapp/src/pages/InvestPage/OverviewPanel/hook.ts",
    "content": "import { makeInvestRow, useInvestTokenTypeMap, useWalletLayer2 } from '@loopring-web/core'\nimport { RowInvest } from '@loopring-web/component-lib'\nimport { SagaStatus } from '@loopring-web/common-resources'\nimport React from 'react'\n\nexport function useOverview<R extends RowInvest>() {\n  const { investTokenTypeMap, status: investTokenTypeMapStatus } = useInvestTokenTypeMap()\n\n  const { status: walletLayer2Status, walletLayer2 } = useWalletLayer2()\n  const [filterValue, setFilterValue] = React.useState<string>('')\n  const [rawData, setRawData] = React.useState<R[]>([])\n  const [filteredData, setFilteredData] = React.useState<R[]>(rawData)\n  const [myMapLoading, setMyMapLoading] = React.useState(false)\n\n  const [myRawData, setMyRawData] = React.useState<R[]>([])\n  const filterData = (rawData: R[], value: string) => {\n    return rawData.filter((item) => {\n      const regx = new RegExp(value.toLowerCase(), 'ig')\n      return regx.test(item?.token?.symbol ?? '')\n    })\n  }\n  const getFilteredData = React.useCallback(\n    (value: string) => {\n      setFilterValue(value)\n      if (value) {\n        const _rawData = [...filterData(rawData, value)]\n        setFilteredData(_rawData)\n      } else {\n        setFilteredData(rawData)\n      }\n    },\n    [filterData, myRawData, rawData, walletLayer2],\n  )\n\n  React.useEffect(() => {\n    if (investTokenTypeMapStatus === SagaStatus.UNSET) {\n      const _rawData = investTokenTypeMap\n        ? Object.keys(investTokenTypeMap)\n            .reduce((prev, key) => {\n              prev.push(makeInvestRow(investTokenTypeMap, key) as R)\n              return prev\n            }, [] as R[])\n            .sort((a, b) => {\n              return b.apr[1] - a.apr[1]\n            })\n        : []\n      setRawData(_rawData)\n      setFilteredData(\n        _rawData.filter((a) => {\n          return !!a.apr[1]\n        }),\n      )\n    }\n  }, [investTokenTypeMapStatus, investTokenTypeMap])\n  const getMyInvestTokenMap = React.useCallback(() => {\n    if (walletLayer2 && Reflect.ownKeys(walletLayer2 ?? {}).length > 0) {\n      const _rawData = Object.keys(walletLayer2)\n        .reduce((prev, key) => {\n          if (investTokenTypeMap && investTokenTypeMap[key]) {\n            prev.push(makeInvestRow(investTokenTypeMap, key) as R)\n          }\n          return prev\n        }, [] as R[])\n        .sort((a, b) => {\n          return b.apr[1] - a.apr[1]\n        })\n      setMyRawData(_rawData)\n    } else {\n      setMyRawData([])\n    }\n    setMyMapLoading(false)\n  }, [walletLayer2, investTokenTypeMap])\n  React.useEffect(() => {\n    if (walletLayer2Status === 'UNSET' && investTokenTypeMapStatus === 'UNSET') {\n      setMyMapLoading(true)\n      getMyInvestTokenMap()\n    }\n  }, [walletLayer2Status, investTokenTypeMapStatus])\n  return {\n    filteredData,\n    filterValue,\n    getFilteredData,\n    myRawData,\n    // myFilteredData,\n    myMapLoading,\n    rawData,\n  }\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/InvestPage/OverviewPanel/index.tsx",
    "content": "import { WithTranslation, withTranslation } from 'react-i18next'\nimport { Avatar, Box, Card, CardContent, IconButton, Link, Typography } from '@mui/material'\nimport styled from '@emotion/styled'\n\nimport React from 'react'\nimport { useOverview } from './hook'\n\nimport {\n  Button,\n  useSettings,\n  InvestOverviewTable,\n  useToggle,\n  MaxWidthContainer,\n} from '@loopring-web/component-lib'\nimport { useHistory } from 'react-router-dom'\nimport {\n  BackIcon,\n  ammAdvice,\n  defiAdvice,\n  RowInvestConfig,\n  dualAdvice,\n  stakeAdvice,\n  leverageETHAdvice,\n  Overview,\n  getValuePrecisionThousand,\n  EmptyValueTag,\n  RouterPath,\n  InvestRouter,\n  InvestType,\n} from '@loopring-web/common-resources'\nimport {\n  useAccount,\n  useAmmMap,\n  useDefiMap,\n  useDualMap,\n  useNotify,\n  useStakingMap,\n} from '@loopring-web/core'\nimport { useTheme } from '@emotion/react'\nimport { containerColors } from '..'\nimport _ from 'lodash'\n\nconst WrapperStyled = styled(Box)`\n  flex: 1;\n  display: flex;\n  flex-direction: column;\n  /* background: var(--dark700); */\n  border-radius: ${({ theme }) => theme.unit}px;\n  width: 100%;\n  overflow: hidden;\n  .MuiCard-root {\n    padding: ${({ theme }) => 4 * theme.unit}px;\n    padding-top: ${({ theme }) => 6 * theme.unit}px;\n    cursor: pointer;\n    background: var(--dark700);\n    border: 1px solid;\n    border-color: var(--color-border);\n    width: ${({ theme }) => 34 * theme.unit}px;\n    .MuiCardContent-root {\n      padding: 0;\n    }\n    box-shadow: none;\n    .hover-button {\n      background: var(--color-button-inactive);\n      color: var(--color-text-primary);\n    }\n    :hover {\n      /* background: var(--color-box-hover); */\n      box-shadow: var(--color-shadow);\n      .hover-button {\n        color: var(--color-text-button);\n        background: var(--color-primary);\n      }\n    }\n  }\n\n  .scroll-view::-webkit-scrollbar {\n    display: none;\n  }\n  @media only screen and (max-width: 768px) {\n    .MuiCard-root {\n      width: 100%;\n      margin-bottom: 12px;\n    }\n  }\n`\n\nconst getAprRange = (list: number[]) => {\n  const aprs = list.sort((a, b) => a - b)\n  return (\n    aprs.length > 0 && {\n      from: aprs[0],\n      to: aprs[aprs.length - 1],\n    }\n  )\n}\n\nexport const OverviewPanel = withTranslation('common')(({ t }: WithTranslation & {}) => {\n  const { filteredData, filterValue, getFilteredData, rawData, myMapLoading, myRawData } =\n    useOverview()\n  const { coinJson, isMobile } = useSettings()\n  const { account } = useAccount()\n  const { notifyMap } = useNotify()\n  const { ammMap } = useAmmMap()\n  const { marketMap, marketLeverageMap } = useDefiMap()\n  const { marketMap: dualMarketMap } = useDualMap()\n  const { marketMap: LRCMarketMap } = useStakingMap()\n\n  const ammApr = React.useMemo(() => {\n    return getAprRange(\n      _.values(ammMap)\n        .filter((amm) => amm && amm.APR)\n        .map((amm) => amm.APR!),\n    )\n  }, [ammMap])\n  const defiApr = React.useMemo(() => {\n    return getAprRange(\n      _.values(marketMap)\n        .filter((defi) => defi && defi.apy)\n        .map((defi) => Number(defi.apy)),\n    )\n  }, [marketMap])\n  const dualApr = React.useMemo(() => {\n    return getAprRange(\n      _.values(dualMarketMap)\n        .flatMap((dual: any) => [\n          dual.baseTokenApy?.max as string,\n          dual.baseTokenApy?.min as string,\n        ])\n        .filter((apy) => apy)\n        .map((apy) => Number(apy) * 100),\n    )\n  }, [dualMarketMap])\n  const lrcApr = React.useMemo(() => {\n    return getAprRange(\n      _.values(LRCMarketMap)\n        .filter((lrc) => lrc.apr)\n        .map((lrc) => Number(lrc.apr)),\n    )\n  }, [LRCMarketMap])\n  const leverageApr = React.useMemo(() => {\n    return getAprRange(\n      _.values(marketLeverageMap)\n        .filter((leverage) => leverage.apy)\n        .map((leverage) => Number(leverage.apy)),\n    )\n  }, [marketLeverageMap])\n\n  const showLoading = filteredData && !filteredData.length\n  const history = useHistory()\n  const {\n    toggle: { CIETHInvest },\n  } = useToggle()\n  const investAdviceList = [\n    { ...dualAdvice, ...notifyMap?.invest?.investAdvice[2], apyRange: dualApr },\n    { ...defiAdvice, ...notifyMap?.invest?.investAdvice[1], apyRange: defiApr },\n    { ...leverageETHAdvice, ...notifyMap?.invest?.investAdvice[4], apyRange: leverageApr },\n    { ...ammAdvice, ...notifyMap?.invest?.investAdvice[0], apyRange: ammApr },\n    // { ...stakeAdvice, ...notifyMap?.invest?.investAdvice[3], apyRange: lrcApr },\n  ]\n  const theme = useTheme()\n  const scrollViewRef = React.useRef()\n  const [showArrow, setShowArrow] = React.useState({ left: false, right: true })\n\n  return (\n    <>\n      <WrapperStyled>\n        <MaxWidthContainer\n          display={'flex'}\n          sx={{ flexDirection: 'row' }}\n          justifyContent={'space-between'}\n          background={containerColors[0]}\n          height={isMobile ? 60 * theme.unit : 30 * theme.unit}\n          alignItems={'center'}\n        >\n          <Box paddingY={7}>\n            <Typography\n              color={'var(--color-text-primary)'}\n              marginBottom={2}\n              fontSize={'38px'}\n              variant={'h1'}\n            >\n              {t('labelInvestLoopringEarn')}\n            </Typography>\n            <Typography marginBottom={3} color={'var(--color-text-secondary)'} variant={'h4'}>\n              {t('labelInvestLoopringEarnDes')}\n            </Typography>\n            <Button\n              onClick={() =>\n                history.push(`${RouterPath.invest}/${InvestRouter[InvestType.MyBalance]}`)\n              }\n              sx={{ width: isMobile ? 36 * theme.unit : 18 * theme.unit }}\n              variant={'contained'}\n            >\n              {t('labelAssetInvests')}\n            </Button>\n          </Box>\n          <Box marginRight={5}>{!isMobile && <Overview />}</Box>\n        </MaxWidthContainer>\n        <MaxWidthContainer marginTop={5} minHeight={'80vh'} background={containerColors[1]}>\n          <Box position={'relative'}>\n            <Box\n              component='div'\n              onScroll={(event) => {\n                if (\n                  event.currentTarget.scrollLeft + event.currentTarget.offsetWidth ===\n                  event.currentTarget.scrollWidth\n                ) {\n                  setShowArrow({\n                    left: true,\n                    right: false,\n                  })\n                } else if (event.currentTarget.scrollLeft === 0) {\n                  setShowArrow({\n                    left: false,\n                    right: true,\n                  })\n                } else {\n                  setShowArrow({\n                    left: true,\n                    right: true,\n                  })\n                }\n              }}\n              sx={{\n                width: '100%',\n                overflowX: 'scroll',\n                maxWidth: 'lg',\n                paddingY: 3,\n                scrollBehavior: 'smooth',\n              }}\n              className={'scroll-view'}\n              ref={scrollViewRef}\n            >\n              <Box\n                sx={{\n                  display: 'flex',\n                  width: isMobile ? '100%' : 'fit-content',\n                  flexDirection: isMobile ? 'column' : 'row',\n                }}\n              >\n                {investAdviceList.map((item, index) => {\n                  return (\n                    <Card\n                      key={item.type}\n                      onClick={() => history.push(item.router)}\n                      sx={{ marginRight: 2.5 }}\n                    >\n                      <CardContent>\n                        <Box display={'flex'} flexDirection={'column'} alignItems={'center'}>\n                          <Avatar\n                            variant='circular'\n                            style={{\n                              height: 'var(--svg-size-huge)',\n                              width: 'var(--svg-size-huge)',\n                            }}\n                            src={item.banner}\n                          />\n                          <Typography marginTop={0.5} variant={'h5'}>\n                            {t(item.titleI18n, { ns: 'layout' })}\n                          </Typography>\n\n                          <Typography variant={'h3'} marginTop={5}>\n                            {item.apyRange\n                              ? item.apyRange.from === item.apyRange.to\n                                ? `${getValuePrecisionThousand(\n                                    item.apyRange.from,\n                                    undefined,\n                                    2,\n                                    2,\n                                  )}%`\n                                : `${getValuePrecisionThousand(\n                                    item.apyRange.from,\n                                    undefined,\n                                    2,\n                                    2,\n                                  )}%-${getValuePrecisionThousand(\n                                    item.apyRange.to,\n                                    undefined,\n                                    2,\n                                    2,\n                                  )}%`\n                              : EmptyValueTag}\n                          </Typography>\n                          <Typography>{t('labelAPR')}</Typography>\n                          <Button\n                            className={'hover-button'}\n                            sx={{ marginTop: 2 }}\n                            fullWidth\n                            variant={'contained'}\n                          >\n                            {t('labelLiquidityDeposit')}\n                          </Button>\n                        </Box>\n                      </CardContent>\n                    </Card>\n                  )\n                })}\n              </Box>\n            </Box>\n            {showArrow.left && (\n              <IconButton\n                size={'large'}\n                sx={{\n                  position: 'absolute',\n                  transform: 'translateY(-50%)',\n                  top: '50%',\n                  left: -30,\n                }}\n                onClick={() => {\n                  ;(scrollViewRef.current as any).scrollTo(0, 0)\n                }}\n              >\n                <BackIcon />\n              </IconButton>\n            )}\n            {showArrow.right && (\n              <IconButton\n                size={'large'}\n                sx={{\n                  position: 'absolute',\n                  transform: 'rotate(180deg) translateY(50%)',\n                  top: '50%',\n                  right: -30,\n                }}\n                onClick={() => {\n                  ;(scrollViewRef.current as any).scrollTo(1000, 0)\n                }}\n              >\n                <BackIcon />\n              </IconButton>\n            )}\n          </Box>\n\n          <Box marginTop={5} display={'flex'} flex={1} marginBottom={1} flexDirection={'column'}>\n            <InvestOverviewTable\n              showLoading={showLoading}\n              showFilter={true}\n              filterValue={filterValue}\n              getFilteredData={getFilteredData}\n              coinJson={coinJson}\n              rawData={filteredData}\n              rowConfig={RowInvestConfig}\n            />\n            {rawData.length !== filteredData.length && (\n              <Link\n                variant={'body1'}\n                marginY={1}\n                textAlign={'center'}\n                display={'inline-flex'}\n                justifyContent={'center'}\n                onClick={() => {\n                  getFilteredData('')\n                }}\n              >\n                {t('labelViewMore')}\n              </Link>\n            )}\n          </Box>\n        </MaxWidthContainer>\n      </WrapperStyled>\n    </>\n  )\n})\n"
  },
  {
    "path": "packages/webapp/src/pages/InvestPage/PoolsPanel/hook.ts",
    "content": "import React from 'react'\nimport { SagaStatus, AmmPanelType } from '@loopring-web/common-resources'\n\nimport { store, useAmmMap, useSystem } from '@loopring-web/core'\n\nimport { useLocation } from 'react-router-dom'\nimport { AccountStep, PoolRow, useOpenModals } from '@loopring-web/component-lib'\nimport { useTranslation } from 'react-i18next'\nimport _ from 'lodash'\n\n// type Row<R> = AmmDetail<R> & { tradeFloat: TradeFloat };\n\nexport function useAmmMapUI<R extends PoolRow<any>, I extends { [key: string]: any }>() {\n  const location = useLocation()\n  const { t } = useTranslation()\n  const {\n    setShowAmm,\n    setShowTradeIsFrozen,\n    setShowAccount,\n    // modals: { isShowAmm, isShowTradeIsFrozen },\n  } = useOpenModals()\n  const searchParams = new URLSearchParams(location.search)\n  const [showLoading, setShowLoading] = React.useState(true)\n  const [filteredData, setFilteredData] = React.useState<R[]>([])\n  // const { status: tokenMapStatus } = useTokenMap();\n  const { status: ammStatus } = useAmmMap()\n  const { allowTrade } = useSystem()\n  const nodeTimer = React.useRef<NodeJS.Timeout | -1>(-1)\n  const nodePopTimer = React.useRef<NodeJS.Timeout | -1>(-1)\n\n  const getFilteredData = (_value?: string) => {\n    const value = _value ? _value : searchParams.get('search')\n    if (nodeTimer.current !== -1) {\n      clearTimeout(nodeTimer.current as NodeJS.Timeout)\n    }\n    setShowLoading(false)\n    const { ammArrayEnable } = store.getState().amm.ammMap\n    let rawData = _.cloneDeep(ammArrayEnable) as unknown as R[]\n    if (value && value.trim() !== '') {\n      rawData = ammArrayEnable.reduce((prev, ammInfo) => {\n        if (\n          value &&\n          ([ammInfo.coinA].includes(value.toUpperCase()) ||\n            [ammInfo.coinB].includes(value.toUpperCase()))\n        ) {\n          prev.push({\n            ...ammInfo,\n          } as unknown as R)\n        }\n        return prev\n      }, [] as R[])\n    }\n\n    setFilteredData(rawData)\n\n    nodeTimer.current = setTimeout(() => {\n      getFilteredData()\n    }, 60000)\n  }\n\n  const handleWithdraw = React.useCallback((row: R) => {\n    setShowAccount({ isShow: true, step: AccountStep.AMM_Pending })\n    if (nodePopTimer.current !== -1) {\n      clearTimeout(nodePopTimer.current as NodeJS.Timeout)\n    }\n    nodePopTimer.current = _.delay(() => {\n      setShowAmm({\n        isShow: true,\n        type: AmmPanelType.Exit,\n        symbol: row.market,\n      })\n    }, 10) as any\n  }, [])\n  const handleDeposit = React.useCallback((row: R) => {\n    if (allowTrade.joinAmm) {\n      setShowAccount({ isShow: true, step: AccountStep.AMM_Pending })\n\n      nodePopTimer.current = _.delay(() => {\n        setShowAmm({\n          isShow: true,\n          type: AmmPanelType.Join,\n          symbol: row.market,\n        })\n      }, 10) as any\n    } else {\n      setShowTradeIsFrozen({\n        isShow: true,\n        type: t('labelAmmJoin') + ` ${row?.market}`,\n      })\n    }\n  }, [])\n  React.useEffect(() => {\n    if (ammStatus === SagaStatus.UNSET) {\n      getFilteredData()\n    }\n    return () => {\n      clearTimeout(nodeTimer.current as NodeJS.Timeout)\n      clearTimeout(nodePopTimer.current as NodeJS.Timeout)\n    }\n  }, [ammStatus])\n\n  return {\n    rawData: filteredData,\n    filterValue: searchParams.get('search') ?? '',\n    showLoading,\n    getFilteredData,\n    handleWithdraw,\n    handleDeposit,\n  }\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/InvestPage/PoolsPanel/index.tsx",
    "content": "import { WithTranslation, withTranslation } from 'react-i18next'\nimport { Box, Typography } from '@mui/material'\nimport styled from '@emotion/styled'\n\nimport React from 'react'\nimport { useAmmMapUI } from './hook'\n\nimport { Button, PoolsTable, useSettings, MaxWidthContainer } from '@loopring-web/component-lib'\n\nimport { useNotify, useSystem } from '@loopring-web/core'\nimport {\n  AmmLogo,\n  InvestRouter,\n  InvestType,\n  RouterPath,\n  RowInvestConfig,\n} from '@loopring-web/common-resources'\nimport { useHistory } from 'react-router-dom'\nimport { containerColors } from '..'\nimport { useTheme } from '@emotion/react'\n\nconst WrapperStyled = styled(Box)`\n  flex: 1;\n  display: flex;\n  flex-direction: column;\n  background: var(--color-box);\n  border-radius: ${({ theme }) => theme.unit}px;\n`\n\nconst StylePaper = styled(Box)`\n  width: 100%;\n  //height: 100%;\n  flex: 1;\n  padding-bottom: ${({ theme }) => theme.unit}px;\n\n  .rdg {\n    flex: 1;\n  }\n` as typeof Box\n\nexport const PoolsPanel = withTranslation('common')(\n  <R extends { [key: string]: any }, I extends { [key: string]: any }>({\n    t,\n  }: WithTranslation & {}) => {\n    const container = React.useRef(null)\n    const history = useHistory()\n    const { forexMap } = useSystem()\n    const { currency, isMobile } = useSettings()\n    const poolTableProps = useAmmMapUI()\n    const { campaignTagConfig } = useNotify().notifyMap ?? {}\n    const theme = useTheme()\n    return (\n      <Box display={'flex'} flexDirection={'column'} flex={1}>\n        <MaxWidthContainer\n          sx={{ flexDirection: 'row' }}\n          display={'flex'}\n          justifyContent={'space-between'}\n          background={containerColors[0]}\n          height={isMobile ? 50 * theme.unit : 30 * theme.unit}\n          alignItems={'center'}\n        >\n          <Box paddingY={7}>\n            <Typography fontSize={'38px'} variant={'h1'}>\n              {t('labelLiquidityPageTitle')}\n            </Typography>\n          </Box>\n          {!isMobile && <AmmLogo />}\n        </MaxWidthContainer>\n        <MaxWidthContainer minHeight={'70vh'} background={containerColors[1]}>\n          <PoolsTable\n            {...{\n              ...poolTableProps,\n              campaignTagConfig,\n              rowConfig: RowInvestConfig,\n              forexValue: forexMap[currency],\n            }}\n          />\n        </MaxWidthContainer>\n      </Box>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/webapp/src/pages/InvestPage/StakePanel/StackTradePanel.tsx",
    "content": "import { confirmation, useStakeTradeJOIN, useToast } from '@loopring-web/core'\n\nimport {\n  Button,\n  DeFiSideWrap,\n  LoadingBlock,\n  Toast,\n  ToastType,\n  useSettings,\n  useToggle,\n  MaxWidthContainer,\n} from '@loopring-web/component-lib'\nimport { Box, Typography } from '@mui/material'\nimport React from 'react'\nimport {\n  BackIcon,\n  L1L2_NAME_DEFINED,\n  MapChainId,\n  TOAST_TIME,\n  hexToRGB,\n  RouterPath,\n  InvestRouter,\n  InvestType,\n  HelpIcon,\n} from '@loopring-web/common-resources'\nimport { Trans, useTranslation } from 'react-i18next'\nimport { useHistory } from 'react-router-dom'\nimport { StyleWrapper } from '../DeFiPanel/'\nimport { containerColors } from '..'\nimport { useTheme } from '@emotion/react'\nimport styled from '@emotion/styled'\nimport { ErrorPage } from '../../ErrorPage'\n\nconst ButtonStyled = styled(Button)`\n  background-color: var(--color-button-outlined);\n  color: var(--color-text-primary);\n  :hover {\n    background-color: var(--color-button-outlined);\n    ::before {\n      border-radius: 4px;\n    }\n  }\n`\n\nexport const StackTradePanel = ({\n  setConfirmedLRCStakeInvestInvest,\n  isJoin = true,\n  symbol = 'LRC',\n}: {\n  symbol?: string\n  setConfirmedLRCStakeInvestInvest: (state: {\n    isShow: boolean\n    confirmationNeeded: boolean\n  }) => void\n  isJoin?: boolean\n}) => {\n  const {\n    confirmation: { confirmedLRCStakeInvest },\n  } = confirmation.useConfirmation()\n  const { toggle } = useToggle()\n  const { toastOpen, setToastOpen, closeToast } = useToast()\n  const { t } = useTranslation()\n  const history = useHistory()\n  const { stakeWrapProps } = useStakeTradeJOIN({ setToastOpen, symbol })\n\n  const { isMobile } = useSettings()\n\n  const styles = isMobile ? { flex: 1 } : { width: '500px' }\n  React.useEffect(() => {\n    setConfirmedLRCStakeInvestInvest({ show: !confirmedLRCStakeInvest, confirmationNeeded: true })\n  }, [])\n  const theme = useTheme()\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const { setShowLRCStakePopup } = confirmation.useConfirmation()\n  return (\n    <>\n      <Toast\n        alertText={toastOpen?.content ?? ''}\n        severity={toastOpen?.type ?? ToastType.success}\n        open={toastOpen?.open ?? false}\n        autoHideDuration={TOAST_TIME}\n        onClose={closeToast}\n      />\n      {toggle?.LRCStackInvest.enable ? (\n        <Box display={'flex'} flexDirection={'column'} flex={1} marginBottom={2}>\n          <MaxWidthContainer>\n            <Typography\n              marginTop={6}\n              borderRadius={2}\n              bgcolor={'var(--color-box-third)'}\n              paddingY={1.5}\n              paddingX={2}\n            >\n              <Trans\n                i18nKey={'labelLRCStakeRiskDes'}\n                tOptions={{\n                  loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                  l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                  l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                  ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                }}\n              >\n                The staked LRC is locked in Loopring L2 and won't be able to used for other purpose\n                although it can be redeemed any time; while if the staking is redeemed before 90\n                days, the accumulated reward will be dismissed.\n              </Trans>\n            </Typography>\n          </MaxWidthContainer>\n          <MaxWidthContainer background={containerColors[0]} paddingY={3}>\n            <StyleWrapper\n              display={'flex'}\n              flexDirection={'column'}\n              justifyContent={'center'}\n              alignItems={'center'}\n              flex={1}\n            >\n              {stakeWrapProps.deFiSideCalcData ? (\n                <Box\n                  display={'flex'}\n                  style={styles}\n                  justifyContent={'center'}\n                  paddingX={3}\n                  paddingTop={3}\n                  paddingBottom={3}\n                  bgcolor={'var(--color-box-third)'}\n                  border={'1px solid var(--color-border)'}\n                  borderRadius={2}\n                >\n                  <DeFiSideWrap\n                    title={\n                      <>\n                        {t('labelInvestLRCTitle')}\n                        <HelpIcon\n                          fontSize={'large'}\n                          color={'inherit'}\n                          sx={{ marginLeft: 1, cursor: 'pointer' }}\n                          onClick={() => {\n                            setShowLRCStakePopup({ isShow: true, confirmationNeeded: false })\n                          }}\n                        />\n                      </>\n                    }\n                    isJoin={isJoin}\n                    symbol={'LRC'}\n                    {...(stakeWrapProps as any)}\n                  />\n                </Box>\n              ) : (\n                <LoadingBlock />\n              )}\n            </StyleWrapper>\n          </MaxWidthContainer>\n        </Box>\n      ) : (\n        <ErrorPage messageKey={'errorBase'} />\n      )}\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/InvestPage/index.tsx",
    "content": "import { useRouteMatch } from 'react-router-dom'\n\nimport { Box, Modal, Typography } from '@mui/material'\n\nimport { useTranslation, withTranslation } from 'react-i18next'\nimport {\n  ComingSoonPanel,\n  ConfirmInvestLRCStakeRisk,\n  ModalCloseButton,\n  SwitchPanelStyled,\n  useToggle,\n  ModifySetting,\n} from '@loopring-web/component-lib'\nimport React from 'react'\nimport { confirmation, ViewAccountTemplate } from '@loopring-web/core'\nimport { MyLiquidity } from './MyLiquidityPanel'\nimport { PoolsPanel } from './PoolsPanel'\nimport { DeFiPanel } from './DeFiPanel'\nimport { OverviewPanel } from './OverviewPanel'\nimport { DualListPanel } from './DualPanel/DualListPanel'\nimport { StackTradePanel } from './StakePanel/StackTradePanel'\nimport LeverageETHPanel from './LeverageETHPanel'\nimport { InvestType, RouterPath, InvestRouter } from '@loopring-web/common-resources'\n\nexport const containerColors = ['var(--color-global-bg)', 'var(--color-pop-bg)']\n\nexport const BalanceTitle = () => {\n  const { t } = useTranslation()\n  return (\n    <Typography display={'inline-flex'} alignItems={'center'}>\n      <Typography\n        component={'span'}\n        variant={'h5'}\n        whiteSpace={'pre'}\n        marginRight={1}\n        className={'invest-Balance-Title'}\n      >\n        {t('labelInvestBalanceTitle')}\n      </Typography>\n    </Typography>\n  )\n}\nexport const OverviewTitle = () => {\n  const { t } = useTranslation()\n  return (\n    <Typography display={'inline-flex'} alignItems={'center'}>\n      <Typography\n        component={'span'}\n        variant={'h5'}\n        whiteSpace={'pre'}\n        marginRight={1}\n        className={'invest-Overview-Title'}\n      >\n        {t('labelInvestOverviewTitle')}\n      </Typography>\n    </Typography>\n  )\n}\nexport const AmmTitle = () => {\n  const { t } = useTranslation()\n  return (\n    <Typography display={'inline-flex'} alignItems={'center'}>\n      <Typography\n        component={'span'}\n        variant={'h5'}\n        whiteSpace={'pre'}\n        marginRight={1}\n        className={'invest-Amm-Title'}\n      >\n        {t('labelInvestAmmTitle')}\n      </Typography>\n    </Typography>\n  )\n}\n\nexport const DefiTitle = () => {\n  const { t } = useTranslation()\n\n  return (\n    <Typography display={'inline-flex'} alignItems={'center'}>\n      <Typography\n        component={'span'}\n        variant={'h5'}\n        whiteSpace={'pre'}\n        marginRight={1}\n        className={'invest-defi-Title'}\n      >\n        {t('labelInvestDefiTitle')}\n      </Typography>\n    </Typography>\n  )\n}\nconst InvestRouterMatch = `${RouterPath.invest}/:item?`\nexport const InvestPage = withTranslation('common', { withRef: true })(() => {\n  let match: any = useRouteMatch(InvestRouterMatch)\n  let { t } = useTranslation()\n  const {\n    confirmedLRCStakeInvest: confirmedLRCInvestFun,\n    setShowLRCStakePopup: setConfirmedLRCStakeInvestInvest,\n    setShowAutoDefault,\n    confirmation: {\n      showLRCStakePopup: confirmedLRCStakeInvest,\n      confirmationNeeded,\n      showAutoDefault,\n    },\n  } = confirmation.useConfirmation()\n  const {\n    toggle: { CIETHInvest },\n  } = useToggle()\n\n  const [tabIndex, setTabIndex] = React.useState<InvestType>(\n    (InvestRouter.find((item) => item.toLowerCase() === match?.params?.item?.toLowerCase())\n      ? InvestType[match?.params?.item]\n      : InvestType.Overview) as any,\n    // InvestType.Overview\n  )\n  const [isShowTab, setIsShowTab] = React.useState<Boolean>(false)\n  React.useEffect(() => {\n    switch (match?.params.item) {\n      case InvestRouter[InvestType.MyBalance]:\n        setTabIndex(InvestType.MyBalance)\n        setIsShowTab(true)\n        return\n      // return ;\n      case InvestRouter[InvestType.AmmPool]:\n        setTabIndex(InvestType.AmmPool)\n        setIsShowTab(false)\n        return\n      case InvestRouter[InvestType.DeFi]:\n        setTabIndex(InvestType.DeFi)\n        setIsShowTab(false)\n        return\n      case InvestRouter[InvestType.Dual]:\n        setTabIndex(InvestType.Dual)\n        setIsShowTab(false)\n        return\n      case InvestRouter[InvestType.Stack]:\n        setTabIndex(InvestType.Stack)\n        setIsShowTab(false)\n        return\n      case InvestRouter[InvestType.LeverageETH]:\n        setTabIndex(InvestType.LeverageETH)\n        setIsShowTab(false)\n        return\n      case InvestRouter[InvestType.Overview]:\n      default:\n        setTabIndex(InvestType.Overview)\n        setIsShowTab(true)\n        return\n    }\n  }, [match?.params?.item])\n\n  return (\n    <Box flex={1} flexDirection={'column'} display={'flex'}>\n      <Box flex={1} component={'section'} display={'flex'}>\n        {tabIndex === InvestType.Overview && <OverviewPanel />}\n        {tabIndex === InvestType.AmmPool && <PoolsPanel />}\n        {tabIndex === InvestType.DeFi && <DeFiPanel />}\n        {tabIndex === InvestType.Dual && <DualListPanel />}\n        {tabIndex === InvestType.MyBalance && (\n          <Box flex={1} alignItems={'stretch'} display={'flex'} flexDirection={'column'}>\n            <ViewAccountTemplate activeViewTemplate={<MyLiquidity />} />\n          </Box>\n        )}\n        {tabIndex === InvestType.Stack && (\n          <StackTradePanel setConfirmedLRCStakeInvestInvest={setConfirmedLRCStakeInvestInvest} />\n        )}\n        {tabIndex === InvestType.LeverageETH &&\n          (!CIETHInvest.enable && CIETHInvest.reason === 'no view' ? (\n            <ComingSoonPanel />\n          ) : (\n            <LeverageETHPanel />\n          ))}\n      </Box>\n      <ConfirmInvestLRCStakeRisk\n        open={confirmedLRCStakeInvest}\n        confirmationNeeded={confirmationNeeded}\n        handleClose={(_e, isAgree) => {\n          setConfirmedLRCStakeInvestInvest({ isShow: false, confirmationNeeded: false })\n          if (!isAgree) {\n            // history.goBack()\n          } else {\n            confirmedLRCInvestFun()\n          }\n        }}\n      />\n    </Box>\n  )\n})\n"
  },
  {
    "path": "packages/webapp/src/pages/LandPage/Card.tsx",
    "content": "import React from 'react'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport { Box, styled, Typography } from '@mui/material'\nimport { useSettings } from '@loopring-web/component-lib'\nimport { useSpring } from 'react-spring'\nimport { animated, to } from '@react-spring/web'\nimport { useTheme } from '@emotion/react'\nimport { ThemeType } from '@loopring-web/common-resources'\n\nexport type CardProps = {\n  title: string\n  icon: string\n  animationJSON: string\n  describe: string\n}\nconst BoxStyle = styled(animated.div)`\n  svg {\n    fill: ${({ theme }: any) => theme.colorBase.textPrimary};\n\n    .svg-high {\n      fill: ${({ theme }: any) => theme.colorBase.primary};\n    }\n  }\n\n  :hover {\n    svg {\n      fill: ${({ theme }: any) => theme.colorBase.textButton};\n\n      .svg-high {\n        fill: ${({ theme }: any) => theme.colorBase.star};\n      }\n    }\n\n    p,\n    h3 {\n      color: ${({ theme }: any) => theme.colorBase.textButton};\n    }\n  }\n` as unknown as typeof animated.div\nexport const Card = withTranslation(['landPage', 'common'], { withRef: true })(\n  ({\n    t,\n    title,\n    icon,\n    // animationJSON,\n    describe,\n  }: WithTranslation & {\n    title: string\n    icon: React.ReactNode\n    // animationJSON,\n    describe: string\n  }) => {\n    const theme = useTheme()\n    const [styles, api] = useSpring(() => ({\n      scale: 1,\n      zoom: 1,\n      zIndex: 10,\n      border: `1px solid ${theme.colorBase.border}`, //\"var(--border-card)\",\n      boxShadow: 'var(--shadow3)', //theme.colorBase.boxShadow, //\"var(--box-card-shadow)\",\n      background: theme.mode === ThemeType.dark ? '#283485' : '#fff', //\"var(--box-card-background)\",\n      default: {\n        immediate: (key) => {\n          return ['scale', 'zoom', 'zIndex', 'border', 'boxShadow', 'background'].includes(key)\n        },\n      },\n      config: {\n        mass: 5,\n        tension: 350,\n        friction: 40,\n      },\n    }))\n    const { isMobile } = useSettings()\n    return (\n      <BoxStyle\n        onMouseEnter={() =>\n          api({\n            scale: 1.1,\n            zoom: 1,\n            zIndex: 99,\n            border: '0px solid #fff',\n            boxShadow:\n              'inset 0px -16px 0px var(--border-card-hover), inset 0px 16px 0px var(--border-card-hover)',\n            background: 'var(--box-card-background-hover)',\n          })\n        }\n        className={'card'}\n        onMouseLeave={() => {\n          api({\n            scale: 1,\n            zoom: 1,\n            zIndex: 10,\n            border: 'var(--border-card)',\n            boxShadow: 'var(--box-card-shadow)',\n            background: 'var(--box-card-background)',\n          })\n        }}\n        style={{\n          transform: 'perspective(600px)',\n          height: 480,\n          width: isMobile ? 'var(--mobile-full-panel-width)' : 400,\n          zIndex: to([styles.zIndex], (zIndex) => zIndex),\n          background: to([styles.background], (background) => background),\n          boxShadow: to([styles.boxShadow], (boxShadow) => boxShadow),\n          border: to([styles.border], (border) => border),\n          scale: to([styles.scale, styles.zoom], (s, z) => s * z),\n        }}\n      >\n        <Box marginTop={4}>{icon}</Box>\n        <Box\n          position={'absolute'}\n          top={'40%'}\n          display={'flex'}\n          flexDirection={'column'}\n          alignItems={'center'}\n        >\n          <Typography component={'div'} marginTop={4}>\n            <Typography whiteSpace={'pre-line'} fontWeight={500} component={'h5'} variant={'h3'}>\n              {t(title)}\n            </Typography>\n          </Typography>\n          <Typography\n            component={'p'}\n            textAlign={'center'}\n            marginTop={3}\n            variant={'h5'}\n            whiteSpace={'pre-line'}\n            color={'var(--text-secondary)'}\n            fontWeight={400}\n            width={306}\n          >\n            {t(describe)}\n          </Typography>\n        </Box>\n      </BoxStyle>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/webapp/src/pages/LandPage/HomePage.tsx",
    "content": "import { Box, Container, Typography, Grid, BoxProps } from '@mui/material'\nimport React from 'react'\nimport styled from '@emotion/styled'\nimport { Trans, withTranslation } from 'react-i18next'\nimport { useHistory, useLocation } from 'react-router-dom'\nimport { useSettings, Button, MaxWidthContainer } from '@loopring-web/component-lib'\nimport { ContainerStyle, CardBox } from './style'\nimport { useTheme } from '@emotion/react'\nimport ArrowForwardIcon from '@mui/icons-material/ArrowForward'\nimport { hideDefiEntry, SoursURL, ToRightTopArrow } from '@loopring-web/common-resources'\n\nconst BgStyle = styled(Box)`\n  position: absolute;\n  z-index: 1;\n  top: 0;\n  right: 0;\n  left: 0;\n  min-height: 100vh;\n  height: 1200px;\n  overflow: hidden;\n  pointer-events: none;\n  width: 100%;\n  background: url('./bgio.webp') no-repeat;\n  background-position-y: 0;\n  background-position-x: -360px;\n  background-size: 1804px 1073px;\n  @media only screen and (max-width: 768px) {\n    min-width: 360px;\n  }\n  &:before {\n    margin-top: 64px;\n    content: '';\n    position: absolute;\n    display: block;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n    height: 528px;\n    background: url('./bg-2.webp') center center no-repeat;\n    background-size: 528px 528px;\n  }\n`\n\ntype TitleGroupProps = {\n  title: string\n  description: string\n  link?: string\n  onClickLink?: () => void\n  buttonText: string\n  descriptionTextColor?: string\n  desFontSize?: string\n} & BoxProps\n\nconst RoundIndicator = ({\n  iconURL,\n  text,\n  ...rest\n}: { iconURL: string; text: string } & BoxProps) => {\n  const theme = useTheme()\n  return (\n    <Box\n      sx={{\n        display: 'flex',\n        alignItems: 'center',\n        borderRadius: '20px',\n        height: '40px',\n        border: theme.mode === 'dark' ? '1px solid #FFFFFF57' : '1px solid #E1E6F0',\n        marginBottom: 2,\n        paddingX: 2,\n        paddingY: 1,\n        backgroundColor: theme.mode === 'dark' ? '#FFFFFF14' : '#F5F7FC',\n      }}\n      {...rest}\n    >\n      <Box\n        component={'img'}\n        src={iconURL}\n        alt='Network Icon'\n        sx={{ marginRight: 1, width: '24px', height: '24px' }}\n      />\n      <Typography color='var(--color-text-primary)'>{text}</Typography>\n    </Box>\n  )\n}\n\nconst TitleGroup: React.FC<TitleGroupProps> = ({\n  title,\n  description,\n  link,\n  onClickLink,\n  buttonText,\n  descriptionTextColor,\n  desFontSize,\n  ...rest\n}) => {\n  const theme = useTheme()\n  const { isMobile } = useSettings()\n  return (\n    <Box\n      textAlign='center'\n      display={'flex'}\n      flexDirection={'column'}\n      alignItems={'center'}\n      width={isMobile ? '80%' : undefined}\n      mt={isMobile ? 2 : 0}\n      {...rest}\n    >\n      <Typography\n        variant='h1'\n        component='h1'\n        gutterBottom\n        fontWeight={700}\n        mb={4}\n        color={'var(--color-text-primary)'}\n        fontSize={isMobile ? '40px' : '80px'}\n        lineHeight={isMobile ? '48px' : '80px'}\n      >\n        {title}\n      </Typography>\n      <Typography\n        variant='h3'\n        fontWeight={isMobile ? 300 : 400}\n        component='p'\n        color={\n          descriptionTextColor ?? (theme.mode === 'light' ? '#292C33' : 'var(--color-text-third)')\n        }\n        fontSize={isMobile ? '20px' : desFontSize ?? '28px'}\n        mb={8}\n        lineHeight={isMobile ? '24px' : '40px'}\n      >\n        {isMobile\n          ? description.replace('\\n', ' ')\n          : description.split('\\n').map((line, index) => (\n              <React.Fragment key={index}>\n                {line}\n                <br />\n              </React.Fragment>\n            ))}\n      </Typography>\n      <Button\n        sx={{ borderRadius: '8px' }}\n        variant='contained'\n        size={isMobile ? 'small' : 'large'}\n        endIcon={<ToRightTopArrow />}\n        href={link ? link : undefined}\n        color={'primary'}\n        onClick={onClickLink ? onClickLink : undefined}\n      >\n        {buttonText}\n      </Button>\n    </Box>\n  )\n}\n\nconst RoundBoxStyled = styled(Box)<{ bgcolor?: string }>(({ theme, bgcolor }) => ({\n  backgroundColor: bgcolor ?? (theme.mode === 'dark' ? '#1C1C1E' : '#F8F8F8'),\n  borderRadius: '25px',\n}))\n\nconst TitleDes = ({\n  title,\n  description,\n  desColor,\n  ...rest\n}: { title: string; description: string, desColor?: string } & BoxProps) => {\n  return (\n    <Box {...rest}>\n      <Typography mb={2} fontSize={'24px'} color={'var(--color-text-primary)'}>\n        {title}\n      </Typography>\n      <Typography fontSize={'16px'} color={desColor ?? 'var(--color-text-third)'}>\n        {description}\n      </Typography>\n    </Box>\n  )\n}\n\nexport const HomePage = withTranslation(['landPage', 'common'])(({ t }: any) => {\n  const { search, pathname } = useLocation()\n  const searchParams = new URLSearchParams(search)\n\n  const { isMobile } = useSettings()\n\n  const history = useHistory()\n  const boxRef = React.useRef()\n  const [value, setValue] = React.useState('detail1')\n  const theme = useTheme()\n  React.useEffect(() => {\n    if (searchParams?.has('goProd')) {\n      boxRef?.current?.scrollIntoView({ behavior: 'smooth', block: 'center' })\n      searchParams?.delete('goProd')\n      history.push(pathname + '?' + searchParams.toString())\n    }\n  }, [searchParams?.has('goProd')])\n\n  return (\n    <>\n      <ContainerStyle\n        sx={{\n          zIndex: 10,\n          bgcolor: theme.mode === 'dark' ? '#000000' : '#FFFFFF',\n          marginTop: 'calc(var(--header-height) * -1)',\n        }}\n      >\n        {!hideDefiEntry && <MaxWidthContainer\n          containerProps={{\n            sx: {\n              backgroundImage: `url('${\n                SoursURL +\n                (theme.mode === 'dark'\n                  ? 'images/landPage/homepage_bg_dark.png'\n                  : 'images/landPage/homepage_bg_light.png')\n              }')`,\n              backgroundSize: '100% auto',\n              backgroundPosition: 'center 130px',\n              backgroundRepeat: 'no-repeat',\n            },\n          }}\n          pb={8}\n          pt={20}\n        >\n          <Box sx={{}} display={'flex'} flexDirection={'column'} alignItems={'center'}>\n            <RoundIndicator\n              iconURL={SoursURL + 'images/landPage/homepage_network.svg'}\n              text={t('labelSupportedNetworkDes')}\n            />\n\n            111\n            <TitleGroup\n              title={t('labelNavEarn')}\n              description={t('labelTitleLiteDes')}\n              mb={isMobile ? 10 : 15}\n              onClickLink={() => {\n                window.open('https://defi.loopring.io/', '_blank')\n              }}\n              buttonText={t('labelLaunch')}\n              descriptionTextColor={'var(--color-text-primary)'}\n            />\n          </Box>\n\n          <Box\n            height={isMobile ? 'auto' : '550px'}\n            display={'flex'}\n            flexDirection={isMobile ? 'column' : 'row'}\n            justifyContent={'space-between'}\n          >\n            <RoundBoxStyled\n              p={8}\n              pb={0}\n              height={isMobile ? 'auto' : '100%'}\n              width={isMobile ? '100%' : '49.5%'}\n              display={'flex'}\n              flexDirection={'column'}\n              justifyContent={'space-between'}\n              alignItems={'center'}\n            >\n              <TitleDes\n                title={t('labelLeadingOnChainStructuredProduct')}\n                description={t('labelLeadingOnChainStructuredProductDes')}\n                desColor={'var(--color-text-secondary)'}\n              />\n              <Box\n                component={'img'}\n                src={\n                  SoursURL +\n                  (theme.mode === 'dark'\n                    ? 'earn/intro_screenshot_1.png'\n                    : 'earn/intro_screenshot_1_light.png')\n                }\n                mt={isMobile ? 8 : 0}\n                width={isMobile ? '90%' : '70%'}\n              />\n            </RoundBoxStyled>\n\n            <RoundBoxStyled\n              mt={isMobile ? 3 : 0}\n              p={8}\n              pb={0}\n              height={isMobile ? 'auto' : '100%'}\n              width={isMobile ? '100%' : '49.5%'}\n              display={'flex'}\n              flexDirection={'column'}\n              justifyContent={'space-between'}\n              alignItems={'center'}\n            >\n              <TitleDes\n                title={t('labelTradeWithCEXLiquidity')}\n                description={t('labelTradeWithCEXLiquidityDes')}\n                desColor={'var(--color-text-secondary)'}\n              />\n              <Box\n                component={'img'}\n                src={\n                  SoursURL +\n                  (theme.mode === 'dark'\n                    ? 'earn/intro_screenshot_3.png'\n                    : 'earn/intro_screenshot_3_light.png')\n                }\n                mt={isMobile ? 8 : 0}\n                width={isMobile ? '90%' : '70%'}\n              />\n            </RoundBoxStyled>\n          </Box>\n          <RoundBoxStyled\n            height={isMobile ? 'auto' : '300px'}\n            p={8}\n            width={'100%'}\n            mt={3}\n            display={'flex'}\n            flexDirection={isMobile ? 'column' : 'row'}\n            justifyContent={'space-between'}\n            alignItems={'center'}\n          >\n            <TitleDes\n              title={t('labelUnlockThePowerOfLeveragedTrading')}\n              description={t('labelUnlockThePowerOfLeveragedTradingDes')}\n              desColor={'var(--color-text-secondary)'}\n              mr={2}\n            />\n            <Box\n              component={'img'}\n              width={isMobile ? '90%' : '25%'}\n              mt={isMobile ? 8 : 0}\n              height={'auto'}\n              src={\n                SoursURL +\n                (theme.mode === 'dark'\n                  ? 'earn/intro_screenshot_2.png'\n                  : 'earn/intro_screenshot_2_light.png')\n              }\n            />\n          </RoundBoxStyled>\n        </MaxWidthContainer>}\n        <MaxWidthContainer\n          containerProps={{ bgcolor: theme.mode === 'light' ? '#EDF2FA' : undefined }}\n          py={15}\n          pt={hideDefiEntry ? 20 : 0}\n        >\n          <Box display={'flex'} flexDirection={'column'} alignItems={'center'}>\n            <RoundIndicator\n              iconURL={SoursURL + 'images/landPage/homepage_ethereum.svg'}\n              text={t('labelEthereumOnly')}\n            />\n            <TitleGroup\n              mb={isMobile ? 10 : 15}\n              title={t('labelLoopringLayer2')}\n              description={t('labelLoopringLayer2Des')}\n              onClickLink={() => {\n                window.open('/#/pro', '_blank')\n              }}\n              buttonText={t('labelLaunch')}\n            />\n          </Box>\n          <Box\n            height={isMobile ? 'auto' : '600px'}\n            display={'flex'}\n            flexDirection={isMobile ? 'column' : 'row'}\n            justifyContent={'space-between'}\n          >\n            <RoundBoxStyled\n              bgcolor={theme.mode === 'light' ? 'white' : undefined}\n              px={4}\n              py={8}\n              pb={0}\n              width={isMobile ? '100%' : '49.5%'}\n              display={'flex'}\n              flexDirection={'column'}\n              justifyContent={'space-between'}\n              alignItems={'center'}\n            >\n              <TitleDes title={t('labelTrade')} desColor={theme.mode === 'light' ? 'var(--color-text-secondary)' : undefined} description={t('labelTradeDes')} />\n              <Box\n                width={'85%'}\n                component={'img'}\n                src={\n                  SoursURL +\n                  (theme.mode === 'dark'\n                    ? 'images/landPage/homepage_p4_dark.png'\n                    : 'images/landPage/homepage_p4_light.png')\n                }\n              />\n            </RoundBoxStyled>\n            <Box\n              width={isMobile ? '100%' : '49.5%'}\n              display={'flex'}\n              flexDirection={'column'}\n              justifyContent={'space-between'}\n            >\n              <RoundBoxStyled\n                bgcolor={theme.mode === 'light' ? 'white' : undefined}\n                px={4}\n                // py={8}\n                height={isMobile ? '150px' : '32%'}\n                mt={isMobile ? 3 : 0}\n                display={'flex'}\n                alignItems={'center'}\n                justifyContent={'space-between'}\n              >\n                <TitleDes desColor={theme.mode === 'light' ? 'var(--color-text-secondary)' : undefined} title={t('labelEarn')} description={t('labelEarnDes')} mr={4} />\n                <Box\n                  component={'img'}\n                  height={'70%'}\n                  src={\n                    SoursURL +\n                    (theme.mode === 'dark'\n                      ? 'images/landPage/homepage_p5_dark.png'\n                      : 'images/landPage/homepage_p5_light.png')\n                  }\n                />\n              </RoundBoxStyled>\n              <RoundBoxStyled\n                bgcolor={theme.mode === 'light' ? 'white' : undefined}\n                px={4}\n                height={isMobile ? '150px' : '32%'}\n                mt={isMobile ? 3 : 0}\n                display={'flex'}\n                alignItems={'center'}\n                justifyContent={'space-between'}\n              >\n                <TitleDes desColor={theme.mode === 'light' ? 'var(--color-text-secondary)' : undefined} title={t('labelNFT')} description={t('labelNFTDes')} mr={4} />\n                <Box\n                  component={'img'}\n                  height={'90%'}\n                  src={\n                    SoursURL +\n                    (theme.mode === 'dark'\n                      ? 'images/landPage/homepage_p6_dark.png'\n                      : 'images/landPage/homepage_p6_light.png')\n                  }\n                />\n              </RoundBoxStyled>\n              <RoundBoxStyled\n                bgcolor={theme.mode === 'light' ? 'white' : undefined}\n                px={4}\n                height={isMobile ? '150px' : '32%'}\n                mt={isMobile ? 3 : 0}\n                display={'flex'}\n                alignItems={'center'}\n                justifyContent={'space-between'}\n              >\n                <TitleDes\n                  title={t('labelRedPackets2')}\n                  description={t('labelRedPacketsDes2')}\n                  desColor={theme.mode === 'light' ? 'var(--color-text-secondary)' : undefined}\n                  mr={4}\n                />\n                <Box\n                  component={'img'}\n                  height={'90%'}\n                  src={\n                    SoursURL +\n                    (theme.mode === 'dark'\n                      ? 'images/landPage/homepage_p7_dark.png'\n                      : 'images/landPage/homepage_p7_light.png')\n                  }\n                />\n              </RoundBoxStyled>\n            </Box>\n          </Box>\n        </MaxWidthContainer>\n\n        {!hideDefiEntry && <MaxWidthContainer\n          display={'flex'}\n          flexDirection={'column'}\n          justifyContent={'center'}\n          alignItems={'center'}\n          containerProps={{}}\n          py={15}\n        >\n          <TitleGroup\n            mb={isMobile ? 10 : 15}\n            title={t('labelLoopringSmartWallet')}\n            description={t('labelLoopringSmartWalletDes2')}\n            onClickLink={() => {\n              window.open('https://wallet.loopring.io/', '_blank')\n            }}\n            buttonText={t('labelExplore')}\n          />\n          <Box\n            mt={10}\n            ml={'9.5%'}\n            width={isMobile ? '95%' : '80%'}\n            component={'img'}\n            src={\n              SoursURL +\n              (theme.mode === 'dark'\n                ? 'images/landPage/homepage_p8_dark.png'\n                : 'images/landPage/homepage_p8_light.png')\n            }\n          />\n        </MaxWidthContainer>}\n        <MaxWidthContainer\n          containerProps={{\n            bgcolor: theme.mode === 'light' ? '#F8F8F8' : undefined,\n          }}\n          display={'flex'}\n          flexDirection={'column'}\n          justifyContent={'center'}\n          alignItems={'center'}\n          py={15}\n        >\n          <TitleGroup\n            mb={isMobile ? 10 : 15}\n            title={t('labelLoopringProtocol')}\n            description={t('labelLoopringProtocolDes')}\n            onClickLink={() => {\n              window.open('https://loopring.org', '_blank')\n            }}\n            buttonText={t('labelExplore')}\n          />\n          <Box\n            display={'flex'}\n            flexDirection={isMobile ? 'column' : 'row'}\n            justifyContent={'space-between'}\n          >\n            <RoundBoxStyled\n              bgcolor={theme.mode === 'light' ? 'white' : undefined}\n              px={3}\n              py={4}\n              borderRadius={'12px'}\n              width={isMobile ? '100%' : '32%'}\n              mb={isMobile ? 3 : 0}\n            >\n              <Box\n                width={'36px'}\n                component={'img'}\n                src={SoursURL + 'images/landPage/homepage_icon1.svg'}\n              />\n              <Typography mt={2} color={'var(--color-text-primary)'} variant='h5' fontSize={'20px'}>\n                {t('labelProvenAppSpecificZKRollup')}\n              </Typography>\n              <Typography mt={1} color={'var(--color-text-secondary)'} fontSize={'14px'}>\n                {t('labelProvenAppSpecificZKRollupDes')}\n              </Typography>\n            </RoundBoxStyled>\n            <RoundBoxStyled\n              bgcolor={theme.mode === 'light' ? 'white' : undefined}\n              px={3}\n              py={4}\n              borderRadius={'12px'}\n              width={isMobile ? '100%' : '32%'}\n              mb={isMobile ? 3 : 0}\n            >\n              <Box\n                width={'36px'}\n                component={'img'}\n                src={SoursURL + 'images/landPage/homepage_icon2.svg'}\n              />\n              <Typography mt={2} color={'var(--color-text-primary)'} variant='h5' fontSize={'20px'}>\n                {t('labelAuditedAndSecure')}\n              </Typography>\n              <Typography mt={1} color={'var(--color-text-secondary)'} fontSize={'14px'}>\n                {t('labelAuditedAndSecureDes')}\n              </Typography>\n            </RoundBoxStyled>\n            <RoundBoxStyled\n              bgcolor={theme.mode === 'light' ? 'white' : undefined}\n              px={3}\n              py={4}\n              borderRadius={'12px'}\n              width={isMobile ? '100%' : '32%'}\n              mb={isMobile ? 3 : 0}\n            >\n              <Box\n                width={'36px'}\n                component={'img'}\n                src={SoursURL + 'images/landPage/homepage_icon3.svg'}\n              />\n              <Typography mt={2} color={'var(--color-text-primary)'} variant='h5' fontSize={'20px'}>\n                {t('labelBringingCEXToDeFi')}\n              </Typography>\n              <Typography mt={1} color={'var(--color-text-secondary)'} fontSize={'14px'}>\n                {t('labelBringingCEXToDeFiDes')}\n              </Typography>\n            </RoundBoxStyled>\n          </Box>\n        </MaxWidthContainer>\n        <MaxWidthContainer\n          containerProps={{\n            sx: {\n              backgroundImage: `url('${\n                SoursURL +\n                (theme.mode === 'dark'\n                  ? 'images/landPage/homepage_bg2_dark.png'\n                  : 'images/landPage/homepage_bg2_light.png')\n              }')`,\n              backgroundSize: 'auto 100%',\n              backgroundPosition: 'center',\n              backgroundRepeat: 'no-repeat',\n            },\n          }}\n          py={15}\n          display={'flex'}\n          flexDirection={'column'}\n          justifyContent={'center'}\n          alignItems={'center'}\n        >\n          <TitleGroup\n            title={t('labelReadyForDevelopers')}\n            description={t('labelReadyForDevelopersDes2')}\n            onClickLink={() => {\n              window.open('https://docs.loopring.io', '_blank')\n            }}\n            buttonText={t('labelExplore')}\n            desFontSize={'24px'}\n          />\n        </MaxWidthContainer>\n      </ContainerStyle>\n      <BgStyle id='bgContent'></BgStyle>\n    </>\n  )\n})\n"
  },
  {
    "path": "packages/webapp/src/pages/LandPage/LandPage.tsx",
    "content": "import {\n  Avatar,\n  Box,\n  Button,\n  Container,\n  Tabs,\n  Tab,\n  Typography,\n  Grid,\n  BoxProps,\n} from '@mui/material'\nimport React from 'react'\nimport styled from '@emotion/styled'\nimport {\n  ammAdvice,\n  BlockTradeLandIcon,\n  defiAdvice,\n  SpotIcon,\n  SwapLandIcon,\n  dualAdvice,\n  FiatLandIcon,\n  fnType,\n  GoIcon,\n  leverageETHAdvice,\n  RouterPath,\n  stakeAdvice,\n  TokenType,\n  NFTSubRouter,\n  ToRightTopArrow,\n} from '@loopring-web/common-resources'\nimport { Trans, withTranslation } from 'react-i18next'\nimport { useHistory } from 'react-router-dom'\nimport { useNotify, WalletConnectL2Btn } from '@loopring-web/core'\nimport { CoinIcons, MaxWidthContainer, useSettings } from '@loopring-web/component-lib'\nimport { ContainerStyle, CardBox } from './style'\nimport { useTheme } from '@emotion/react'\nimport { SoursURL } from '@loopring-web/loopring-sdk'\n\nconst BgStyle = styled(Box)`\n  position: absolute;\n  z-index: 1;\n  top: 0;\n  right: 0;\n  left: 0;\n  min-height: 100vh;\n  height: 1200px;\n  overflow: hidden;\n  pointer-events: none;\n  background: url('./bgpro-${({ theme }) => theme.mode}.webp') no-repeat;\n  background-position-y: 0;\n  background-position-x: right;\n  background-size: 1804px 1073px;\n  @media only screen and (max-width: 768px) {\n    min-width: 360px;\n  }\n  &:before {\n    margin-top: 64px;\n    content: '';\n    position: absolute;\n    display: block;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n    height: 528px;\n    background-size: 528px 528px;\n  }\n`\n\ntype TitleGroupProps = {\n  title: string\n  description: string\n  link?: string\n  onClickLink?: () => void\n  buttonText: string\n  descriptionTextColor?: string\n  desFontSize?: string\n} & BoxProps\n\nconst RoundIndicator = ({\n  iconURL,\n  text,\n  ...rest\n}: { iconURL: string; text: string } & BoxProps) => {\n  const theme = useTheme()\n  return (\n    <Box\n      sx={{\n        display: 'flex',\n        alignItems: 'center',\n        borderRadius: '20px',\n        height: '40px',\n        border: theme.mode === 'dark' ? '1px solid #FFFFFF57' : '1px solid #E1E6F0',\n        marginBottom: 2,\n        paddingX: 2,\n        paddingY: 1,\n        backgroundColor: theme.mode === 'dark' ? '#FFFFFF14' : '#F5F7FC',\n      }}\n      {...rest}\n    >\n      <Box\n        component={'img'}\n        src={iconURL}\n        alt='Network Icon'\n        sx={{ marginRight: 1, width: '24px', height: '24px' }}\n      />\n      <Typography color='var(--color-text-primary)'>{text}</Typography>\n    </Box>\n  )\n}\n\nconst TitleGroup: React.FC<TitleGroupProps> = ({\n  title,\n  description,\n  link,\n  onClickLink,\n  buttonText,\n  descriptionTextColor,\n  desFontSize,\n  ...rest\n}) => {\n  const theme = useTheme()\n  const { isMobile } = useSettings()\n  return (\n    <Box\n      textAlign='center'\n      display={'flex'}\n      flexDirection={'column'}\n      alignItems={'center'}\n      width={isMobile ? '80%' : undefined}\n      mt={isMobile ? 2 : 0}\n      {...rest}\n    >\n      <Typography\n        variant='h1'\n        component='h1'\n        gutterBottom\n        fontWeight={700}\n        mb={4}\n        color={'var(--color-text-primary)'}\n        fontSize={isMobile ? '40px' : '80px'}\n        lineHeight={isMobile ? '48px' : '80px'}\n      >\n        {title}\n      </Typography>\n      <Typography\n        variant='h3'\n        fontWeight={isMobile ? 300 : 400}\n        component='p'\n        color={\n          descriptionTextColor ?? (theme.mode === 'light' ? '#292C33' : 'var(--color-text-third)')\n        }\n        fontSize={isMobile ? '20px' : desFontSize ?? '28px'}\n        mb={8}\n        lineHeight={isMobile ? '24px' : '40px'}\n      >\n        {isMobile\n          ? description.replace('\\n', ' ')\n          : description.split('\\n').map((line, index) => (\n              <React.Fragment key={index}>\n                {line}\n                <br />\n              </React.Fragment>\n            ))}\n      </Typography>\n      <Button\n        sx={{ borderRadius: '8px' }}\n        variant='contained'\n        size={isMobile ? 'small' : 'large'}\n        endIcon={<ToRightTopArrow />}\n        href={link ? link : undefined}\n        color={'primary'}\n        onClick={onClickLink ? onClickLink : undefined}\n      >\n        {buttonText}\n      </Button>\n    </Box>\n  )\n}\n\nconst RoundBoxStyled = styled(Box)<{ bgcolor?: string }>(({ theme, bgcolor }) => ({\n  backgroundColor: bgcolor ?? (theme.mode === 'dark' ? '#31353d' : '#F8F8F8'),\n  borderRadius: '25px',\n}))\n\nconst TitleDes = ({\n  title,\n  description,\n  desColor,\n  ...rest\n}: { title: string; description: string; desColor?: string } & BoxProps) => {\n  return (\n    <Box {...rest}>\n      <Typography mb={2} fontSize={'24px'} color={'var(--color-text-primary)'}>\n        {title}\n      </Typography>\n      <Typography fontSize={'16px'} color={desColor ?? 'var(--color-text-third)'}>\n        {description}\n      </Typography>\n    </Box>\n  )\n}\nconst ButtonStyled = styled(Button)`\n  .MuiBox-root {\n    justify-content: flex-start;\n  }\n  .MuiButton-startIcon {\n    height: 48px;\n    width: 48px;\n    svg {\n      fill: var(--color-primary);\n      height: 48px;\n      width: 48px;\n    }\n  }\n  span:last-child {\n    text-transform: initial;\n  }\n`\n\nexport const LandPage = withTranslation(['landPage', 'common'])(({ t }: any) => {\n  const history = useHistory()\n  const { isMobile, coinJson } = useSettings()\n  const theme = useTheme()\n  const { notifyMap } = useNotify()\n\n  const investAdviceList = [\n    {\n      ...dualAdvice,\n      ...notifyMap?.invest?.investAdvice[2],\n    },\n    {\n      ...defiAdvice,\n      ...notifyMap?.invest?.investAdvice[1],\n    },\n    {\n      ...leverageETHAdvice,\n      ...notifyMap?.invest?.investAdvice[4],\n    },\n    {\n      ...ammAdvice,\n      ...notifyMap?.invest?.investAdvice[0],\n    },\n    {\n      ...stakeAdvice,\n      ...notifyMap?.invest?.investAdvice[3],\n    },\n  ]\n  return (\n    <>\n      <ContainerStyle sx={{ zIndex: 10 }}>\n        <Container\n          maxWidth='lg'\n          style={{\n            display: 'flex',\n            flexDirection: 'column',\n            flex: 1,\n          }}\n        >\n          <Box\n            display={'flex'}\n            justifyContent={'center'}\n            alignItems={'center'}\n            flexDirection={'column'}\n            height={428}\n          >\n            <Typography\n              component={'p'}\n              variant={'h1'}\n              textAlign={'center'}\n              whiteSpace={'pre-line'}\n              marginBottom={4}\n            >\n              {t('labelMainDes')}\n            </Typography>\n            <WalletConnectL2Btn\n              sx={{ width: '100%' }}\n              className={'walletConnectL2Btn'}\n              btnLabelProps={{\n                [fnType.ACTIVATED]: [\n                  function () {\n                    return t(`labelGoDapps`)\n                  },\n                ],\n              }}\n              btnClickMapProps={{\n                [fnType.ACTIVATED]: [\n                  function () {\n                    history.push(`${RouterPath.lite}`)\n                  },\n                ],\n              }}\n            />\n          </Box>\n          <Box\n            display={'flex'}\n            flexDirection={isMobile ? 'column' : 'row'}\n            justifyContent={'space-between'}\n            mb={5}\n          >\n            <RoundBoxStyled\n              bgcolor={theme.mode === 'light' ? 'white' : undefined}\n              px={3}\n              py={4}\n              borderRadius={'12px'}\n              width={isMobile ? '100%' : '32%'}\n              mb={isMobile ? 3 : 0}\n            >\n              <Box\n                width={'36px'}\n                component={'img'}\n                src={SoursURL + 'images/landPage/homepage_icon1.svg'}\n              />\n              <Typography mt={2} color={'var(--color-text-primary)'} variant='h5' fontSize={'20px'}>\n                {t('labelProvenAppSpecificZKRollup')}\n              </Typography>\n              <Typography mt={1} color={'var(--color-text-secondary)'} fontSize={'14px'}>\n                {t('labelProvenAppSpecificZKRollupDes')}\n              </Typography>\n            </RoundBoxStyled>\n            <RoundBoxStyled\n              bgcolor={theme.mode === 'light' ? 'white' : undefined}\n              px={3}\n              py={4}\n              borderRadius={'12px'}\n              width={isMobile ? '100%' : '32%'}\n              mb={isMobile ? 3 : 0}\n            >\n              <Box\n                width={'36px'}\n                component={'img'}\n                src={SoursURL + 'images/landPage/homepage_icon2.svg'}\n              />\n              <Typography mt={2} color={'var(--color-text-primary)'} variant='h5' fontSize={'20px'}>\n                {t('labelAuditedAndSecure')}\n              </Typography>\n              <Typography mt={1} color={'var(--color-text-secondary)'} fontSize={'14px'}>\n                {t('labelAuditedAndSecureDes')}\n              </Typography>\n            </RoundBoxStyled>\n            <RoundBoxStyled\n              bgcolor={theme.mode === 'light' ? 'white' : undefined}\n              px={3}\n              py={4}\n              borderRadius={'12px'}\n              width={isMobile ? '100%' : '32%'}\n              mb={isMobile ? 3 : 0}\n            >\n              <Box\n                width={'36px'}\n                component={'img'}\n                src={SoursURL + 'images/landPage/homepage_icon3.svg'}\n              />\n              <Typography mt={2} color={'var(--color-text-primary)'} variant='h5' fontSize={'20px'}>\n                Low Transaction Fees\n              </Typography>\n              <Typography mt={1} color={'var(--color-text-secondary)'} fontSize={'14px'}>\n                Loopring processes trades and transfers off-chain (on Ethereum's layer 2), slashing gas fees and costs to a fraction of on-chain transactions.\n              </Typography>\n            </RoundBoxStyled>\n          </Box>\n\n          <MaxWidthContainer\n            containerProps={{ bgcolor: theme.mode === 'light' ? '#EDF2FA' : undefined }}\n            mb={20}\n          >\n            <Box\n              height={isMobile ? 'auto' : '600px'}\n              display={'flex'}\n              flexDirection={isMobile ? 'column' : 'row'}\n              justifyContent={'space-between'}\n            >\n              <RoundBoxStyled\n                bgcolor={theme.mode === 'light' ? 'white' : undefined}\n                px={4}\n                py={8}\n                pb={0}\n                width={isMobile ? '100%' : '49%'}\n                display={'flex'}\n                flexDirection={'column'}\n                justifyContent={'space-between'}\n                alignItems={'center'}\n              >\n                <TitleDes\n                  title={t('labelTrade')}\n                  desColor={theme.mode === 'light' ? 'var(--color-text-secondary)' : undefined}\n                  description={t('labelTradeDes')}\n                />\n                <Box\n                  width={'85%'}\n                  component={'img'}\n                  src={\n                    SoursURL +\n                    (theme.mode === 'dark'\n                      ? 'images/landPage/homepage_p4_dark.png'\n                      : 'images/landPage/homepage_p4_light.png')\n                  }\n                />\n              </RoundBoxStyled>\n              <Box\n                width={isMobile ? '100%' : '49%'}\n                display={'flex'}\n                flexDirection={'column'}\n                justifyContent={'space-between'}\n              >\n                {/* <RoundBoxStyled\n                  bgcolor={theme.mode === 'light' ? 'white' : undefined}\n                  px={4}\n                  // py={8}\n                  height={isMobile ? '150px' : '49%'}\n                  mt={isMobile ? 3 : 0}\n                  display={'flex'}\n                  alignItems={'center'}\n                  justifyContent={'space-between'}\n                >\n                  <TitleDes\n                    desColor={theme.mode === 'light' ? 'var(--color-text-secondary)' : undefined}\n                    title={t('labelEarn')}\n                    description={t('labelEarnDes')}\n                    mr={4}\n                  />\n                  <Box\n                    component={'img'}\n                    height={'70%'}\n                    src={\n                      SoursURL +\n                      (theme.mode === 'dark'\n                        ? 'images/landPage/homepage_p5_dark.png'\n                        : 'images/landPage/homepage_p5_light.png')\n                    }\n                  />\n                </RoundBoxStyled> */}\n                <RoundBoxStyled\n                bgcolor={theme.mode === 'light' ? 'white' : undefined}\n                px={4}\n                height={isMobile ? '150px' : '49%'}\n                mt={isMobile ? 3 : 0}\n                display={'flex'}\n                alignItems={'center'}\n                justifyContent={'space-between'}\n              >\n                <TitleDes desColor={theme.mode === 'light' ? 'var(--color-text-secondary)' : undefined} title={t('labelNFT')} description={t('labelNFTDes')} mr={4} />\n                <Box\n                  component={'img'}\n                  height={'90%'}\n                  src={\n                    SoursURL +\n                    (theme.mode === 'dark'\n                      ? 'images/landPage/homepage_p6_dark.png'\n                      : 'images/landPage/homepage_p6_light.png')\n                  }\n                />\n              </RoundBoxStyled>\n                <RoundBoxStyled\n                  bgcolor={theme.mode === 'light' ? 'white' : undefined}\n                  px={4}\n                  height={isMobile ? '150px' : '49%'}\n                  mt={isMobile ? 3 : 0}\n                  display={'flex'}\n                  alignItems={'center'}\n                  justifyContent={'space-between'}\n                >\n                  <TitleDes\n                    title={t('labelRedPackets2')}\n                    description={t('labelRedPacketsDes2')}\n                    desColor={theme.mode === 'light' ? 'var(--color-text-secondary)' : undefined}\n                    mr={4}\n                  />\n                  <Box\n                    component={'img'}\n                    height={'90%'}\n                    src={\n                      SoursURL +\n                      (theme.mode === 'dark'\n                        ? 'images/landPage/homepage_p7_dark.png'\n                        : 'images/landPage/homepage_p7_light.png')\n                    }\n                  />\n                </RoundBoxStyled>\n              </Box>\n            </Box>\n          </MaxWidthContainer>\n          {/* <Box component='section'>\n            <Box\n              style={{\n                display: 'flex',\n                flexDirection: 'column',\n                flex: 1,\n              }}\n              className={'box6'}\n            >\n              <CardBox\n                display={'flex'}\n                justifyContent={'center'}\n                alignItems={'center'}\n                flexDirection={isMobile ? 'column' : 'row'}\n              >\n                <Box\n                  display={'flex'}\n                  flexDirection={'column'}\n                  flex={1}\n                  alignItems={'stretch'}\n                  paddingRight={isMobile ? 0 : 5}\n                >\n                  <Typography\n                    component={'h4'}\n                    variant={'h4'}\n                    display={'inline-flex'}\n                    alignItems={'center'}\n                    textAlign={'left'}\n                    marginBottom={1}\n                  >\n                    {t('labelProductsTitle')}\n                  </Typography>\n                  <Typography\n                    component={'p'}\n                    variant={'h5'}\n                    textAlign={'left'}\n                    whiteSpace={'pre-line'}\n                    marginBottom={4}\n                    color={'textSecondary'}\n                  >\n                    {t('labelProductsTitleDes')}\n                  </Typography>\n\n                  <ButtonStyled\n                    fullWidth\n                    title={`#${RouterPath.pro}`}\n                    href={`#${RouterPath.pro}`}\n                    className='menuItem'\n                    variant={'text'}\n                    startIcon={<SpotIcon />}\n                  >\n                    <Box display={'flex'} flexDirection={'column'}>\n                      <Typography component={'span'} display={'inline-flex'} alignItems={'center'}>\n                        {t('labelSpot')}\n                        <GoIcon color='inherit' />\n                      </Typography>\n                      <Typography component={'span'} color={'textSecondary'}>\n                        {t('labelSpotDes')}\n                      </Typography>\n                    </Box>\n                  </ButtonStyled>\n                  <ButtonStyled\n                    fullWidth\n                    title={`#${RouterPath.lite}`}\n                    href={`#${RouterPath.lite}`}\n                    className='menuItem'\n                    variant={'text'}\n                    startIcon={<SwapLandIcon />}\n                  >\n                    <Box display={'flex'} flexDirection={'column'}>\n                      <Typography component={'span'} display={'inline-flex'} alignItems={'center'}>\n                        {t('labelSwap')}\n\n                        <GoIcon color='inherit' />\n                      </Typography>\n                      <Typography component={'span'} color={'textSecondary'}>\n                        {t('labelSwapDes')}\n                      </Typography>\n                    </Box>\n                  </ButtonStyled>\n                  <ButtonStyled\n                    fullWidth\n                    title={`#${RouterPath.btrade}`}\n                    href={`#${RouterPath.btrade}`}\n                    className='menuItem'\n                    variant={'text'}\n                    startIcon={<BlockTradeLandIcon />}\n                  >\n                    <Box display={'flex'} flexDirection={'column'}>\n                      <Typography component={'span'} display={'inline-flex'} alignItems={'center'}>\n                        {t('labelBlockTrade')}\n\n                        <GoIcon color='inherit' />\n                      </Typography>\n                      <Typography component={'span'} color={'textSecondary'}>\n                        {t('labelBlockTradeDes')}\n                      </Typography>\n                    </Box>\n                  </ButtonStyled>\n                  <ButtonStyled\n                    fullWidth\n                    title={`#${RouterPath.fiat}`}\n                    href={`#${RouterPath.fiat}`}\n                    className='menuItem'\n                    variant={'text'}\n                    startIcon={<FiatLandIcon />}\n                  >\n                    <Box display={'flex'} flexDirection={'column'}>\n                      <Typography component={'span'} display={'inline-flex'} alignItems={'center'}>\n                        {t('labelFiat')}\n\n                        <GoIcon color='inherit' />\n                      </Typography>\n                      <Typography component={'span'} color={'textSecondary'}>\n                        {t('labelFiatDes')}\n                      </Typography>\n                    </Box>\n                  </ButtonStyled>\n                </Box>\n                <Box>\n                  <img id='mobileBg' width='533' src={`${SoursURL}images/landPage/homepage_p4_${theme.mode}.png`} />\n                </Box>\n              </CardBox>\n            </Box>\n          </Box> */}\n        </Container>\n      </ContainerStyle>\n\n      <BgStyle id='bgContent'></BgStyle>\n    </>\n  )\n})\n"
  },
  {
    "path": "packages/webapp/src/pages/LandPage/WalletPage.tsx",
    "content": "import { Box, Grid, Link, Typography } from '@mui/material'\nimport React, { useEffect } from 'react'\nimport styled from '@emotion/styled'\nimport { LandPageHeightConfig, SoursURL } from '@loopring-web/common-resources'\nimport { withTranslation } from 'react-i18next'\nimport { ContainerStyle, ContainerStyled, TitleTypography } from './style'\nimport { useSettings } from '@loopring-web/component-lib'\nimport { useTheme } from '@emotion/react'\n\n// const LinkStyle = styled(Link)`\n//   color: var(--color-button-select);\n//   text-decoration: underline;\n//   font-size: 1.6rem;\n//   line-height: 2.4rem;\n// ` as typeof Link;\n//\n// const ImgWrapperLeftStyled = styled(Box)`\n//   position: absolute;\n//   top: 50%;\n//   left: 0;\n//   transform: translateY(-50%);\n// `;\n//\n// const ImgWrapperRightStyled = styled(Box)`\n//   position: absolute;\n//   top: 50%;\n//   right: 0;\n//   transform: translateY(-50%);\n// `;\n//\n// const GridBg = styled(Grid)`\n//   background-size: 160%;\n//   background-repeat: no-repeat;\n//   background-position: -360px -110px;\n//   ${({ theme }) => {\n//     return `\n//         background-image: image-set(url(\"https://static.loopring.io/assets/images/landPage/img_wallet_app_${theme.mode}.webp\") 1x,\n//         url(\"https://static.loopring.io/assets/images/landPage/img_wallet_app_${theme.mode}.png\") 1x);\n//             `;\n//   }}\n// ` as typeof Grid;\n//\n// const BottomBanner = styled(Box)`\n//   background: var(--layer-2);\n// ` as typeof Box;\n\nexport const WalletPage = withTranslation(['landPage', 'common'])(({ t }: any) => {\n  const { isMobile } = useSettings()\n  const { mode } = useTheme()\n  return <></>\n})\n"
  },
  {
    "path": "packages/webapp/src/pages/LandPage/coins.json",
    "content": "{\n  \"v\": \"5.7.4\",\n  \"fr\": 25,\n  \"ip\": 0,\n  \"op\": 42,\n  \"w\": 500,\n  \"h\": 500,\n  \"nm\": \"298-coins-outlined\",\n  \"ddd\": 0,\n  \"assets\": [\n    {\n      \"id\": \"comp_0\",\n      \"layers\": [\n        {\n          \"ddd\": 0,\n          \"ind\": 1,\n          \"ty\": 4,\n          \"nm\": \"Rectangle\",\n          \"sr\": 1,\n          \"ks\": {\n            \"o\": {\n              \"a\": 0,\n              \"k\": 100,\n              \"ix\": 11\n            },\n            \"r\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"i\": {\n                    \"x\": [\n                      0.667\n                    ],\n                    \"y\": [\n                      1\n                    ]\n                  },\n                  \"o\": {\n                    \"x\": [\n                      0.167\n                    ],\n                    \"y\": [\n                      0.167\n                    ]\n                  },\n                  \"t\": 0,\n                  \"s\": [\n                    0\n                  ]\n                },\n                {\n                  \"i\": {\n                    \"x\": [\n                      0.833\n                    ],\n                    \"y\": [\n                      0.833\n                    ]\n                  },\n                  \"o\": {\n                    \"x\": [\n                      0.333\n                    ],\n                    \"y\": [\n                      0\n                    ]\n                  },\n                  \"t\": 8,\n                  \"s\": [\n                    -17.333\n                  ]\n                },\n                {\n                  \"i\": {\n                    \"x\": [\n                      0.32\n                    ],\n                    \"y\": [\n                      1\n                    ]\n                  },\n                  \"o\": {\n                    \"x\": [\n                      0.167\n                    ],\n                    \"y\": [\n                      0.167\n                    ]\n                  },\n                  \"t\": 12,\n                  \"s\": [\n                    1\n                  ]\n                },\n                {\n                  \"i\": {\n                    \"x\": [\n                      0.833\n                    ],\n                    \"y\": [\n                      0.833\n                    ]\n                  },\n                  \"o\": {\n                    \"x\": [\n                      0.68\n                    ],\n                    \"y\": [\n                      0\n                    ]\n                  },\n                  \"t\": 16.838,\n                  \"s\": [\n                    10\n                  ]\n                },\n                {\n                  \"i\": {\n                    \"x\": [\n                      0.667\n                    ],\n                    \"y\": [\n                      1\n                    ]\n                  },\n                  \"o\": {\n                    \"x\": [\n                      0.167\n                    ],\n                    \"y\": [\n                      0.167\n                    ]\n                  },\n                  \"t\": 21.677,\n                  \"s\": [\n                    1\n                  ]\n                },\n                {\n                  \"i\": {\n                    \"x\": [\n                      0.833\n                    ],\n                    \"y\": [\n                      0.833\n                    ]\n                  },\n                  \"o\": {\n                    \"x\": [\n                      0.333\n                    ],\n                    \"y\": [\n                      0\n                    ]\n                  },\n                  \"t\": 25.306,\n                  \"s\": [\n                    6\n                  ]\n                },\n                {\n                  \"t\": 30.14453125,\n                  \"s\": [\n                    1\n                  ]\n                }\n              ],\n              \"ix\": 10\n            },\n            \"p\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"i\": {\n                    \"x\": 0.32,\n                    \"y\": 1\n                  },\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"t\": 0,\n                  \"s\": [\n                    228.058,\n                    194.4,\n                    0\n                  ],\n                  \"to\": [\n                    0,\n                    -22.129,\n                    0\n                  ],\n                  \"ti\": [\n                    0,\n                    0,\n                    0\n                  ]\n                },\n                {\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"o\": {\n                    \"x\": 0.68,\n                    \"y\": 0\n                  },\n                  \"t\": 8,\n                  \"s\": [\n                    228.058,\n                    61.628,\n                    0\n                  ],\n                  \"to\": [\n                    0,\n                    0,\n                    0\n                  ],\n                  \"ti\": [\n                    0,\n                    -6.056,\n                    0\n                  ]\n                },\n                {\n                  \"i\": {\n                    \"x\": 0.32,\n                    \"y\": 1\n                  },\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"t\": 12,\n                  \"s\": [\n                    228.058,\n                    194.4,\n                    0\n                  ],\n                  \"to\": [\n                    -0.277,\n                    -6.222,\n                    0\n                  ],\n                  \"ti\": [\n                    0,\n                    0,\n                    0\n                  ]\n                },\n                {\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"o\": {\n                    \"x\": 0.68,\n                    \"y\": 0\n                  },\n                  \"t\": 16.838,\n                  \"s\": [\n                    228.058,\n                    157.474,\n                    0\n                  ],\n                  \"to\": [\n                    0,\n                    0,\n                    0\n                  ],\n                  \"ti\": [\n                    0,\n                    -6.056,\n                    0\n                  ]\n                },\n                {\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"t\": 21.677,\n                  \"s\": [\n                    228.058,\n                    194.4,\n                    0\n                  ],\n                  \"to\": [\n                    -0.277,\n                    -6.222,\n                    0\n                  ],\n                  \"ti\": [\n                    0,\n                    1.231,\n                    0\n                  ]\n                },\n                {\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"t\": 25.306,\n                  \"s\": [\n                    228.058,\n                    172.245,\n                    0\n                  ],\n                  \"to\": [\n                    0,\n                    -1.231,\n                    0\n                  ],\n                  \"ti\": [\n                    0,\n                    -6.056,\n                    0\n                  ]\n                },\n                {\n                  \"t\": 30.14453125,\n                  \"s\": [\n                    228.058,\n                    194.4,\n                    0\n                  ]\n                }\n              ],\n              \"ix\": 2,\n              \"l\": 2\n            },\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                -4,\n                -6.5,\n                0\n              ],\n              \"ix\": 1,\n              \"l\": 2\n            },\n            \"s\": {\n              \"a\": 0,\n              \"k\": [\n                1075.292,\n                1075.292,\n                100\n              ],\n              \"ix\": 6,\n              \"l\": 2\n            }\n          },\n          \"ao\": 0,\n          \"shapes\": [\n            {\n              \"ty\": \"gr\",\n              \"it\": [\n                {\n                  \"ind\": 0,\n                  \"ty\": \"sh\",\n                  \"ix\": 1,\n                  \"ks\": {\n                    \"a\": 0,\n                    \"k\": {\n                      \"i\": [\n                        [\n                          -1.381,\n                          0\n                        ],\n                        [\n                          0,\n                          0\n                        ],\n                        [\n                          0,\n                          -1.381\n                        ],\n                        [\n                          0,\n                          0\n                        ],\n                        [\n                          1.381,\n                          0\n                        ],\n                        [\n                          0,\n                          0\n                        ],\n                        [\n                          0,\n                          1.381\n                        ],\n                        [\n                          0,\n                          0\n                        ]\n                      ],\n                      \"o\": [\n                        [\n                          0,\n                          0\n                        ],\n                        [\n                          1.381,\n                          0\n                        ],\n                        [\n                          0,\n                          0\n                        ],\n                        [\n                          0,\n                          1.381\n                        ],\n                        [\n                          0,\n                          0\n                        ],\n                        [\n                          -1.381,\n                          0\n                        ],\n                        [\n                          0,\n                          0\n                        ],\n                        [\n                          0,\n                          -1.381\n                        ]\n                      ],\n                      \"v\": [\n                        [\n                          -12,\n                          -9\n                        ],\n                        [\n                          4,\n                          -9\n                        ],\n                        [\n                          6.5,\n                          -6.5\n                        ],\n                        [\n                          6.5,\n                          -6.5\n                        ],\n                        [\n                          4,\n                          -4\n                        ],\n                        [\n                          -12,\n                          -4\n                        ],\n                        [\n                          -14.5,\n                          -6.5\n                        ],\n                        [\n                          -14.5,\n                          -6.5\n                        ]\n                      ],\n                      \"c\": true\n                    },\n                    \"ix\": 2\n                  },\n                  \"nm\": \"Path 1\",\n                  \"mn\": \"ADBE Vector Shape - Group\",\n                  \"hd\": false\n                },\n                {\n                  \"ty\": \"st\",\n                  \"c\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0.070588235294,\n                      0.074509803922,\n                      0.192156877705,\n                      1\n                    ],\n                    \"ix\": 3,\n                    \"x\": \"var $bm_rt;\\n$bm_rt = comp('298-coins-outlined').layer('Color  & Stroke Change').effect('Primary')('Color');\"\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 4\n                  },\n                  \"w\": {\n                    \"a\": 0,\n                    \"k\": 1.5,\n                    \"ix\": 5,\n                    \"x\": \"var $bm_rt;\\n$bm_rt = $bm_mul(1.5 / 100, comp('298-coins-outlined').layer('Color  & Stroke Change').effect('Stroke')('Slider'));\"\n                  },\n                  \"lc\": 1,\n                  \"lj\": 1,\n                  \"ml\": 4,\n                  \"bm\": 0,\n                  \"nm\": \"Stroke 1\",\n                  \"mn\": \"ADBE Vector Graphic - Stroke\",\n                  \"hd\": false\n                },\n                {\n                  \"ty\": \"tr\",\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 2\n                  },\n                  \"a\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 1\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      100,\n                      100\n                    ],\n                    \"ix\": 3\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 6\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 7\n                  },\n                  \"sk\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"sa\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"nm\": \"Transform\"\n                }\n              ],\n              \"nm\": \"Rectangle\",\n              \"np\": 2,\n              \"cix\": 2,\n              \"bm\": 0,\n              \"ix\": 1,\n              \"mn\": \"ADBE Vector Group\",\n              \"hd\": false\n            }\n          ],\n          \"ip\": 0,\n          \"op\": 250,\n          \"st\": 0,\n          \"bm\": 0\n        },\n        {\n          \"ddd\": 0,\n          \"ind\": 2,\n          \"ty\": 4,\n          \"nm\": \"Warstwa 4\",\n          \"sr\": 1,\n          \"ks\": {\n            \"o\": {\n              \"a\": 0,\n              \"k\": 100,\n              \"ix\": 11\n            },\n            \"r\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"i\": {\n                    \"x\": [\n                      0.833\n                    ],\n                    \"y\": [\n                      0.833\n                    ]\n                  },\n                  \"o\": {\n                    \"x\": [\n                      0.167\n                    ],\n                    \"y\": [\n                      0.167\n                    ]\n                  },\n                  \"t\": 0,\n                  \"s\": [\n                    0\n                  ]\n                },\n                {\n                  \"i\": {\n                    \"x\": [\n                      0.833\n                    ],\n                    \"y\": [\n                      0.833\n                    ]\n                  },\n                  \"o\": {\n                    \"x\": [\n                      0.167\n                    ],\n                    \"y\": [\n                      0.167\n                    ]\n                  },\n                  \"t\": 7.258,\n                  \"s\": [\n                    6\n                  ]\n                },\n                {\n                  \"t\": 12.09765625,\n                  \"s\": [\n                    0\n                  ]\n                }\n              ],\n              \"ix\": 10\n            },\n            \"p\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"i\": {\n                    \"x\": 0.32,\n                    \"y\": 1\n                  },\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"t\": 0,\n                  \"s\": [\n                    212.578,\n                    355.694,\n                    0\n                  ],\n                  \"to\": [\n                    0,\n                    -1.792,\n                    0\n                  ],\n                  \"ti\": [\n                    0,\n                    0,\n                    0\n                  ]\n                },\n                {\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"o\": {\n                    \"x\": 0.68,\n                    \"y\": 0\n                  },\n                  \"t\": 7.258,\n                  \"s\": [\n                    212.578,\n                    344.941,\n                    0\n                  ],\n                  \"to\": [\n                    0,\n                    0,\n                    0\n                  ],\n                  \"ti\": [\n                    0,\n                    -1.792,\n                    0\n                  ]\n                },\n                {\n                  \"t\": 12.09765625,\n                  \"s\": [\n                    212.578,\n                    355.694,\n                    0\n                  ]\n                }\n              ],\n              \"ix\": 2,\n              \"l\": 2\n            },\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                -4,\n                8.5,\n                0\n              ],\n              \"ix\": 1,\n              \"l\": 2\n            },\n            \"s\": {\n              \"a\": 0,\n              \"k\": [\n                1075.292,\n                1075.292,\n                100\n              ],\n              \"ix\": 6,\n              \"l\": 2\n            }\n          },\n          \"ao\": 0,\n          \"shapes\": [\n            {\n              \"ty\": \"gr\",\n              \"it\": [\n                {\n                  \"ind\": 0,\n                  \"ty\": \"sh\",\n                  \"ix\": 1,\n                  \"ks\": {\n                    \"a\": 0,\n                    \"k\": {\n                      \"i\": [\n                        [\n                          -1.381,\n                          0\n                        ],\n                        [\n                          0,\n                          0\n                        ],\n                        [\n                          0,\n                          -1.381\n                        ],\n                        [\n                          0,\n                          0\n                        ],\n                        [\n                          1.381,\n                          0\n                        ],\n                        [\n                          0,\n                          0\n                        ],\n                        [\n                          0,\n                          1.381\n                        ],\n                        [\n                          0,\n                          0\n                        ]\n                      ],\n                      \"o\": [\n                        [\n                          0,\n                          0\n                        ],\n                        [\n                          1.381,\n                          0\n                        ],\n                        [\n                          0,\n                          0\n                        ],\n                        [\n                          0,\n                          1.381\n                        ],\n                        [\n                          0,\n                          0\n                        ],\n                        [\n                          -1.381,\n                          0\n                        ],\n                        [\n                          0,\n                          0\n                        ],\n                        [\n                          0,\n                          -1.381\n                        ]\n                      ],\n                      \"v\": [\n                        [\n                          -12,\n                          6\n                        ],\n                        [\n                          4,\n                          6\n                        ],\n                        [\n                          6.5,\n                          8.5\n                        ],\n                        [\n                          6.5,\n                          8.5\n                        ],\n                        [\n                          4,\n                          11\n                        ],\n                        [\n                          -12,\n                          11\n                        ],\n                        [\n                          -14.5,\n                          8.5\n                        ],\n                        [\n                          -14.5,\n                          8.5\n                        ]\n                      ],\n                      \"c\": true\n                    },\n                    \"ix\": 2\n                  },\n                  \"nm\": \"Path 1\",\n                  \"mn\": \"ADBE Vector Shape - Group\",\n                  \"hd\": false\n                },\n                {\n                  \"ty\": \"st\",\n                  \"c\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0.070588235294,\n                      0.074509803922,\n                      0.192156877705,\n                      1\n                    ],\n                    \"ix\": 3,\n                    \"x\": \"var $bm_rt;\\n$bm_rt = comp('298-coins-outlined').layer('Color  & Stroke Change').effect('Primary')('Color');\"\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 4\n                  },\n                  \"w\": {\n                    \"a\": 0,\n                    \"k\": 1.5,\n                    \"ix\": 5,\n                    \"x\": \"var $bm_rt;\\n$bm_rt = $bm_mul(1.5 / 100, comp('298-coins-outlined').layer('Color  & Stroke Change').effect('Stroke')('Slider'));\"\n                  },\n                  \"lc\": 1,\n                  \"lj\": 1,\n                  \"ml\": 4,\n                  \"bm\": 0,\n                  \"nm\": \"Stroke 1\",\n                  \"mn\": \"ADBE Vector Graphic - Stroke\",\n                  \"hd\": false\n                },\n                {\n                  \"ty\": \"tr\",\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 2\n                  },\n                  \"a\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 1\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      100,\n                      100\n                    ],\n                    \"ix\": 3\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 6\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 7\n                  },\n                  \"sk\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"sa\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"nm\": \"Transform\"\n                }\n              ],\n              \"nm\": \"Group 1\",\n              \"np\": 2,\n              \"cix\": 2,\n              \"bm\": 0,\n              \"ix\": 1,\n              \"mn\": \"ADBE Vector Group\",\n              \"hd\": false\n            }\n          ],\n          \"ip\": 0,\n          \"op\": 250,\n          \"st\": 0,\n          \"bm\": 0\n        },\n        {\n          \"ddd\": 0,\n          \"ind\": 3,\n          \"ty\": 4,\n          \"nm\": \"Warstwa 3\",\n          \"sr\": 1,\n          \"ks\": {\n            \"o\": {\n              \"a\": 0,\n              \"k\": 100,\n              \"ix\": 11\n            },\n            \"r\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"i\": {\n                    \"x\": [\n                      0.833\n                    ],\n                    \"y\": [\n                      0.833\n                    ]\n                  },\n                  \"o\": {\n                    \"x\": [\n                      0.167\n                    ],\n                    \"y\": [\n                      0.167\n                    ]\n                  },\n                  \"t\": 0,\n                  \"s\": [\n                    0\n                  ]\n                },\n                {\n                  \"i\": {\n                    \"x\": [\n                      0.833\n                    ],\n                    \"y\": [\n                      0.833\n                    ]\n                  },\n                  \"o\": {\n                    \"x\": [\n                      0.167\n                    ],\n                    \"y\": [\n                      0.167\n                    ]\n                  },\n                  \"t\": 7.258,\n                  \"s\": [\n                    -10\n                  ]\n                },\n                {\n                  \"i\": {\n                    \"x\": [\n                      0.833\n                    ],\n                    \"y\": [\n                      0.833\n                    ]\n                  },\n                  \"o\": {\n                    \"x\": [\n                      0.167\n                    ],\n                    \"y\": [\n                      0.167\n                    ]\n                  },\n                  \"t\": 12.098,\n                  \"s\": [\n                    0\n                  ]\n                },\n                {\n                  \"i\": {\n                    \"x\": [\n                      0.833\n                    ],\n                    \"y\": [\n                      0.833\n                    ]\n                  },\n                  \"o\": {\n                    \"x\": [\n                      0.167\n                    ],\n                    \"y\": [\n                      0.167\n                    ]\n                  },\n                  \"t\": 21.774,\n                  \"s\": [\n                    0\n                  ]\n                },\n                {\n                  \"t\": 30.2421875,\n                  \"s\": [\n                    0\n                  ]\n                }\n              ],\n              \"ix\": 10\n            },\n            \"p\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"i\": {\n                    \"x\": 0.32,\n                    \"y\": 1\n                  },\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"t\": 0,\n                  \"s\": [\n                    234.078,\n                    301.93,\n                    0\n                  ],\n                  \"to\": [\n                    0,\n                    -8.961,\n                    0\n                  ],\n                  \"ti\": [\n                    0,\n                    0,\n                    0\n                  ]\n                },\n                {\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"o\": {\n                    \"x\": 0.68,\n                    \"y\": 0\n                  },\n                  \"t\": 7.258,\n                  \"s\": [\n                    234.078,\n                    248.165,\n                    0\n                  ],\n                  \"to\": [\n                    0,\n                    0,\n                    0\n                  ],\n                  \"ti\": [\n                    0,\n                    -6.991,\n                    0\n                  ]\n                },\n                {\n                  \"i\": {\n                    \"x\": 0.32,\n                    \"y\": 1\n                  },\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"t\": 12.098,\n                  \"s\": [\n                    234.078,\n                    301.93,\n                    0\n                  ],\n                  \"to\": [\n                    0,\n                    -4.271,\n                    0\n                  ],\n                  \"ti\": [\n                    0,\n                    0,\n                    0\n                  ]\n                },\n                {\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"o\": {\n                    \"x\": 0.68,\n                    \"y\": 0\n                  },\n                  \"t\": 16.936,\n                  \"s\": [\n                    234.078,\n                    290.113,\n                    0\n                  ],\n                  \"to\": [\n                    0,\n                    0,\n                    0\n                  ],\n                  \"ti\": [\n                    0,\n                    -6.991,\n                    0\n                  ]\n                },\n                {\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"t\": 21.774,\n                  \"s\": [\n                    234.078,\n                    301.93,\n                    0\n                  ],\n                  \"to\": [\n                    0,\n                    -4.271,\n                    0\n                  ],\n                  \"ti\": [\n                    0,\n                    1.231,\n                    0\n                  ]\n                },\n                {\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"t\": 25.403,\n                  \"s\": [\n                    234.078,\n                    295.283,\n                    0\n                  ],\n                  \"to\": [\n                    0,\n                    -1.231,\n                    0\n                  ],\n                  \"ti\": [\n                    0,\n                    -6.991,\n                    0\n                  ]\n                },\n                {\n                  \"t\": 30.2421875,\n                  \"s\": [\n                    234.078,\n                    301.93,\n                    0\n                  ]\n                }\n              ],\n              \"ix\": 2,\n              \"l\": 2\n            },\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                -4,\n                3.5,\n                0\n              ],\n              \"ix\": 1,\n              \"l\": 2\n            },\n            \"s\": {\n              \"a\": 0,\n              \"k\": [\n                1075.292,\n                1075.292,\n                100\n              ],\n              \"ix\": 6,\n              \"l\": 2\n            }\n          },\n          \"ao\": 0,\n          \"shapes\": [\n            {\n              \"ty\": \"gr\",\n              \"it\": [\n                {\n                  \"ind\": 0,\n                  \"ty\": \"sh\",\n                  \"ix\": 1,\n                  \"ks\": {\n                    \"a\": 0,\n                    \"k\": {\n                      \"i\": [\n                        [\n                          -1.381,\n                          0\n                        ],\n                        [\n                          0,\n                          0\n                        ],\n                        [\n                          0,\n                          -1.381\n                        ],\n                        [\n                          0,\n                          0\n                        ],\n                        [\n                          1.381,\n                          0\n                        ],\n                        [\n                          0,\n                          0\n                        ],\n                        [\n                          0,\n                          1.381\n                        ],\n                        [\n                          0,\n                          0\n                        ]\n                      ],\n                      \"o\": [\n                        [\n                          0,\n                          0\n                        ],\n                        [\n                          1.381,\n                          0\n                        ],\n                        [\n                          0,\n                          0\n                        ],\n                        [\n                          0,\n                          1.381\n                        ],\n                        [\n                          0,\n                          0\n                        ],\n                        [\n                          -1.381,\n                          0\n                        ],\n                        [\n                          0,\n                          0\n                        ],\n                        [\n                          0,\n                          -1.381\n                        ]\n                      ],\n                      \"v\": [\n                        [\n                          -12,\n                          1\n                        ],\n                        [\n                          4,\n                          1\n                        ],\n                        [\n                          6.5,\n                          3.5\n                        ],\n                        [\n                          6.5,\n                          3.5\n                        ],\n                        [\n                          4,\n                          6\n                        ],\n                        [\n                          -12,\n                          6\n                        ],\n                        [\n                          -14.5,\n                          3.5\n                        ],\n                        [\n                          -14.5,\n                          3.5\n                        ]\n                      ],\n                      \"c\": true\n                    },\n                    \"ix\": 2\n                  },\n                  \"nm\": \"Path 1\",\n                  \"mn\": \"ADBE Vector Shape - Group\",\n                  \"hd\": false\n                },\n                {\n                  \"ty\": \"st\",\n                  \"c\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0.070588235294,\n                      0.074509803922,\n                      0.192156877705,\n                      1\n                    ],\n                    \"ix\": 3,\n                    \"x\": \"var $bm_rt;\\n$bm_rt = comp('298-coins-outlined').layer('Color  & Stroke Change').effect('Primary')('Color');\"\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 4\n                  },\n                  \"w\": {\n                    \"a\": 0,\n                    \"k\": 1.5,\n                    \"ix\": 5,\n                    \"x\": \"var $bm_rt;\\n$bm_rt = $bm_mul(1.5 / 100, comp('298-coins-outlined').layer('Color  & Stroke Change').effect('Stroke')('Slider'));\"\n                  },\n                  \"lc\": 1,\n                  \"lj\": 1,\n                  \"ml\": 4,\n                  \"bm\": 0,\n                  \"nm\": \"Stroke 1\",\n                  \"mn\": \"ADBE Vector Graphic - Stroke\",\n                  \"hd\": false\n                },\n                {\n                  \"ty\": \"tr\",\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 2\n                  },\n                  \"a\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 1\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      100,\n                      100\n                    ],\n                    \"ix\": 3\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 6\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 7\n                  },\n                  \"sk\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"sa\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"nm\": \"Transform\"\n                }\n              ],\n              \"nm\": \"Group 1\",\n              \"np\": 2,\n              \"cix\": 2,\n              \"bm\": 0,\n              \"ix\": 1,\n              \"mn\": \"ADBE Vector Group\",\n              \"hd\": false\n            }\n          ],\n          \"ip\": 0,\n          \"op\": 250,\n          \"st\": 0,\n          \"bm\": 0\n        },\n        {\n          \"ddd\": 0,\n          \"ind\": 4,\n          \"ty\": 4,\n          \"nm\": \"Warstwa 2\",\n          \"sr\": 1,\n          \"ks\": {\n            \"o\": {\n              \"a\": 0,\n              \"k\": 100,\n              \"ix\": 11\n            },\n            \"r\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"i\": {\n                    \"x\": [\n                      0.833\n                    ],\n                    \"y\": [\n                      0.833\n                    ]\n                  },\n                  \"o\": {\n                    \"x\": [\n                      0.167\n                    ],\n                    \"y\": [\n                      0.167\n                    ]\n                  },\n                  \"t\": 0,\n                  \"s\": [\n                    0\n                  ]\n                },\n                {\n                  \"i\": {\n                    \"x\": [\n                      0.833\n                    ],\n                    \"y\": [\n                      0.833\n                    ]\n                  },\n                  \"o\": {\n                    \"x\": [\n                      0.167\n                    ],\n                    \"y\": [\n                      0.167\n                    ]\n                  },\n                  \"t\": 7,\n                  \"s\": [\n                    14\n                  ]\n                },\n                {\n                  \"i\": {\n                    \"x\": [\n                      0.833\n                    ],\n                    \"y\": [\n                      0.833\n                    ]\n                  },\n                  \"o\": {\n                    \"x\": [\n                      0.167\n                    ],\n                    \"y\": [\n                      0.167\n                    ]\n                  },\n                  \"t\": 12.098,\n                  \"s\": [\n                    0\n                  ]\n                },\n                {\n                  \"i\": {\n                    \"x\": [\n                      0.833\n                    ],\n                    \"y\": [\n                      0.833\n                    ]\n                  },\n                  \"o\": {\n                    \"x\": [\n                      0.167\n                    ],\n                    \"y\": [\n                      0.167\n                    ]\n                  },\n                  \"t\": 21.774,\n                  \"s\": [\n                    0\n                  ]\n                },\n                {\n                  \"t\": 30.2421875,\n                  \"s\": [\n                    0\n                  ]\n                }\n              ],\n              \"ix\": 10\n            },\n            \"p\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"i\": {\n                    \"x\": 0.32,\n                    \"y\": 1\n                  },\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"t\": 0,\n                  \"s\": [\n                    212.578,\n                    248.165,\n                    0\n                  ],\n                  \"to\": [\n                    0,\n                    -14.534,\n                    0\n                  ],\n                  \"ti\": [\n                    0,\n                    0,\n                    0\n                  ]\n                },\n                {\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"o\": {\n                    \"x\": 0.68,\n                    \"y\": 0\n                  },\n                  \"t\": 7,\n                  \"s\": [\n                    212.578,\n                    160.959,\n                    0\n                  ],\n                  \"to\": [\n                    0,\n                    0,\n                    0\n                  ],\n                  \"ti\": [\n                    0,\n                    -7.508,\n                    0\n                  ]\n                },\n                {\n                  \"i\": {\n                    \"x\": 0.32,\n                    \"y\": 1\n                  },\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"t\": 12.098,\n                  \"s\": [\n                    212.578,\n                    248.165,\n                    0\n                  ],\n                  \"to\": [\n                    0.369,\n                    -6.154,\n                    0\n                  ],\n                  \"ti\": [\n                    0,\n                    0,\n                    0\n                  ]\n                },\n                {\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"o\": {\n                    \"x\": 0.68,\n                    \"y\": 0\n                  },\n                  \"t\": 16.936,\n                  \"s\": [\n                    212.578,\n                    226.009,\n                    0\n                  ],\n                  \"to\": [\n                    0,\n                    0,\n                    0\n                  ],\n                  \"ti\": [\n                    0,\n                    -7.508,\n                    0\n                  ]\n                },\n                {\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"t\": 21.774,\n                  \"s\": [\n                    212.578,\n                    248.165,\n                    0\n                  ],\n                  \"to\": [\n                    0.369,\n                    -6.154,\n                    0\n                  ],\n                  \"ti\": [\n                    0,\n                    1.231,\n                    0\n                  ]\n                },\n                {\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"t\": 25.403,\n                  \"s\": [\n                    212.578,\n                    235.61,\n                    0\n                  ],\n                  \"to\": [\n                    0,\n                    -1.231,\n                    0\n                  ],\n                  \"ti\": [\n                    0,\n                    -7.508,\n                    0\n                  ]\n                },\n                {\n                  \"t\": 30.2421875,\n                  \"s\": [\n                    212.578,\n                    248.165,\n                    0\n                  ]\n                }\n              ],\n              \"ix\": 2,\n              \"l\": 2\n            },\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                -4,\n                -1.5,\n                0\n              ],\n              \"ix\": 1,\n              \"l\": 2\n            },\n            \"s\": {\n              \"a\": 0,\n              \"k\": [\n                1075.292,\n                1075.292,\n                100\n              ],\n              \"ix\": 6,\n              \"l\": 2\n            }\n          },\n          \"ao\": 0,\n          \"shapes\": [\n            {\n              \"ty\": \"gr\",\n              \"it\": [\n                {\n                  \"ind\": 0,\n                  \"ty\": \"sh\",\n                  \"ix\": 1,\n                  \"ks\": {\n                    \"a\": 0,\n                    \"k\": {\n                      \"i\": [\n                        [\n                          -1.381,\n                          0\n                        ],\n                        [\n                          0,\n                          0\n                        ],\n                        [\n                          0,\n                          -1.381\n                        ],\n                        [\n                          0,\n                          0\n                        ],\n                        [\n                          1.381,\n                          0\n                        ],\n                        [\n                          0,\n                          0\n                        ],\n                        [\n                          0,\n                          1.381\n                        ],\n                        [\n                          0,\n                          0\n                        ]\n                      ],\n                      \"o\": [\n                        [\n                          0,\n                          0\n                        ],\n                        [\n                          1.381,\n                          0\n                        ],\n                        [\n                          0,\n                          0\n                        ],\n                        [\n                          0,\n                          1.381\n                        ],\n                        [\n                          0,\n                          0\n                        ],\n                        [\n                          -1.381,\n                          0\n                        ],\n                        [\n                          0,\n                          0\n                        ],\n                        [\n                          0,\n                          -1.381\n                        ]\n                      ],\n                      \"v\": [\n                        [\n                          -12,\n                          -4\n                        ],\n                        [\n                          4,\n                          -4\n                        ],\n                        [\n                          6.5,\n                          -1.5\n                        ],\n                        [\n                          6.5,\n                          -1.5\n                        ],\n                        [\n                          4,\n                          1\n                        ],\n                        [\n                          -12,\n                          1\n                        ],\n                        [\n                          -14.5,\n                          -1.5\n                        ],\n                        [\n                          -14.5,\n                          -1.5\n                        ]\n                      ],\n                      \"c\": true\n                    },\n                    \"ix\": 2\n                  },\n                  \"nm\": \"Path 1\",\n                  \"mn\": \"ADBE Vector Shape - Group\",\n                  \"hd\": false\n                },\n                {\n                  \"ty\": \"st\",\n                  \"c\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0.070588235294,\n                      0.074509803922,\n                      0.192156877705,\n                      1\n                    ],\n                    \"ix\": 3,\n                    \"x\": \"var $bm_rt;\\n$bm_rt = comp('298-coins-outlined').layer('Color  & Stroke Change').effect('Primary')('Color');\"\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 4\n                  },\n                  \"w\": {\n                    \"a\": 0,\n                    \"k\": 1.5,\n                    \"ix\": 5,\n                    \"x\": \"var $bm_rt;\\n$bm_rt = $bm_mul(1.5 / 100, comp('298-coins-outlined').layer('Color  & Stroke Change').effect('Stroke')('Slider'));\"\n                  },\n                  \"lc\": 1,\n                  \"lj\": 1,\n                  \"ml\": 4,\n                  \"bm\": 0,\n                  \"nm\": \"Stroke 1\",\n                  \"mn\": \"ADBE Vector Graphic - Stroke\",\n                  \"hd\": false\n                },\n                {\n                  \"ty\": \"tr\",\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 2\n                  },\n                  \"a\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 1\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      100,\n                      100\n                    ],\n                    \"ix\": 3\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 6\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 7\n                  },\n                  \"sk\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"sa\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"nm\": \"Transform\"\n                }\n              ],\n              \"nm\": \"Group 1\",\n              \"np\": 2,\n              \"cix\": 2,\n              \"bm\": 0,\n              \"ix\": 1,\n              \"mn\": \"ADBE Vector Group\",\n              \"hd\": false\n            }\n          ],\n          \"ip\": 0,\n          \"op\": 250,\n          \"st\": 0,\n          \"bm\": 0\n        }\n      ]\n    }\n  ],\n  \"layers\": [\n    {\n      \"ddd\": 0,\n      \"ind\": 1,\n      \"ty\": 3,\n      \"nm\": \"02092020\",\n      \"sr\": 1,\n      \"ks\": {\n        \"o\": {\n          \"a\": 0,\n          \"k\": 0,\n          \"ix\": 11\n        },\n        \"r\": {\n          \"a\": 0,\n          \"k\": 0,\n          \"ix\": 10\n        },\n        \"p\": {\n          \"a\": 0,\n          \"k\": [\n            -105,\n            15,\n            0\n          ],\n          \"ix\": 2,\n          \"l\": 2\n        },\n        \"a\": {\n          \"a\": 0,\n          \"k\": [\n            60,\n            60,\n            0\n          ],\n          \"ix\": 1,\n          \"l\": 2\n        },\n        \"s\": {\n          \"a\": 0,\n          \"k\": [\n            100,\n            100,\n            100\n          ],\n          \"ix\": 6,\n          \"l\": 2\n        }\n      },\n      \"ao\": 0,\n      \"ef\": [\n        {\n          \"ty\": 5,\n          \"nm\": \"02092020002\",\n          \"np\": 3,\n          \"mn\": \"ADBE Checkbox Control\",\n          \"ix\": 1,\n          \"en\": 1,\n          \"ef\": [\n            {\n              \"ty\": 7,\n              \"nm\": \"Checkbox\",\n              \"mn\": \"ADBE Checkbox Control-0001\",\n              \"ix\": 1,\n              \"v\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 1\n              }\n            }\n          ]\n        }\n      ],\n      \"ip\": 0,\n      \"op\": 125,\n      \"st\": 0,\n      \"bm\": 0\n    },\n    {\n      \"ddd\": 0,\n      \"ind\": 2,\n      \"ty\": 4,\n      \"nm\": \"lordicon.com outlineds\",\n      \"cl\": \"com\",\n      \"sr\": 1,\n      \"ks\": {\n        \"o\": {\n          \"a\": 0,\n          \"k\": 20,\n          \"ix\": 11,\n          \"x\": \"var $bm_rt;\\nvar checkbox = thisComp.layer('02092020').effect('02092020002')('Checkbox');\\nif (checkbox == 1) {\\n    $bm_rt = 20;\\n} else {\\n    $bm_rt = 0;\\n}\\n;\"\n        },\n        \"r\": {\n          \"a\": 0,\n          \"k\": 0,\n          \"ix\": 10\n        },\n        \"p\": {\n          \"a\": 0,\n          \"k\": [\n            249.934,\n            481.369,\n            0\n          ],\n          \"ix\": 2,\n          \"l\": 2\n        },\n        \"a\": {\n          \"a\": 0,\n          \"k\": [\n            79.934,\n            0.369,\n            0\n          ],\n          \"ix\": 1,\n          \"l\": 2\n        },\n        \"s\": {\n          \"a\": 0,\n          \"k\": [\n            265.159,\n            265.159,\n            100\n          ],\n          \"ix\": 6,\n          \"l\": 2\n        }\n      },\n      \"ao\": 0,\n      \"shapes\": [\n        {\n          \"ty\": \"gr\",\n          \"it\": [\n            {\n              \"ind\": 0,\n              \"ty\": \"sh\",\n              \"ix\": 1,\n              \"ks\": {\n                \"a\": 0,\n                \"k\": {\n                  \"i\": [\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ]\n                  ],\n                  \"o\": [\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ]\n                  ],\n                  \"v\": [\n                    [\n                      1.415,\n                      0\n                    ],\n                    [\n                      11.014,\n                      0\n                    ],\n                    [\n                      11.014,\n                      -2.523\n                    ],\n                    [\n                      4.656,\n                      -2.523\n                    ],\n                    [\n                      4.656,\n                      -14.809\n                    ],\n                    [\n                      1.415,\n                      -14.809\n                    ]\n                  ],\n                  \"c\": true\n                },\n                \"ix\": 2\n              },\n              \"nm\": \"l\",\n              \"mn\": \"ADBE Vector Shape - Group\",\n              \"hd\": false\n            },\n            {\n              \"ty\": \"fl\",\n              \"c\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0,\n                  0,\n                  1\n                ],\n                \"ix\": 4\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 100,\n                \"ix\": 5\n              },\n              \"r\": 1,\n              \"bm\": 0,\n              \"nm\": \"Fill 1\",\n              \"mn\": \"ADBE Vector Graphic - Fill\",\n              \"hd\": false\n            },\n            {\n              \"ty\": \"tr\",\n              \"p\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 2\n              },\n              \"a\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 1\n              },\n              \"s\": {\n                \"a\": 0,\n                \"k\": [\n                  100,\n                  100\n                ],\n                \"ix\": 3\n              },\n              \"r\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 6\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 100,\n                \"ix\": 7\n              },\n              \"sk\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 4\n              },\n              \"sa\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 5\n              },\n              \"nm\": \"Transform\"\n            }\n          ],\n          \"nm\": \"l\",\n          \"np\": 3,\n          \"cix\": 2,\n          \"bm\": 0,\n          \"ix\": 1,\n          \"mn\": \"ADBE Vector Group\",\n          \"hd\": false\n        },\n        {\n          \"ty\": \"gr\",\n          \"it\": [\n            {\n              \"ind\": 0,\n              \"ty\": \"sh\",\n              \"ix\": 1,\n              \"ks\": {\n                \"a\": 0,\n                \"k\": {\n                  \"i\": [\n                    [\n                      0,\n                      -3.938\n                    ],\n                    [\n                      -1.62,\n                      -1.723\n                    ],\n                    [\n                      -1.949,\n                      0\n                    ],\n                    [\n                      -1.641,\n                      1.846\n                    ],\n                    [\n                      0,\n                      2.154\n                    ],\n                    [\n                      1.579,\n                      1.805\n                    ],\n                    [\n                      1.579,\n                      0\n                    ]\n                  ],\n                  \"o\": [\n                    [\n                      0,\n                      1.354\n                    ],\n                    [\n                      1.354,\n                      1.415\n                    ],\n                    [\n                      1.231,\n                      0\n                    ],\n                    [\n                      1.21,\n                      -1.354\n                    ],\n                    [\n                      0,\n                      -1.456\n                    ],\n                    [\n                      -1.456,\n                      -1.641\n                    ],\n                    [\n                      -5.333,\n                      0\n                    ]\n                  ],\n                  \"v\": [\n                    [\n                      11.167,\n                      -7.199\n                    ],\n                    [\n                      12.992,\n                      -1.661\n                    ],\n                    [\n                      18.243,\n                      0.369\n                    ],\n                    [\n                      23.514,\n                      -1.743\n                    ],\n                    [\n                      25.381,\n                      -7.548\n                    ],\n                    [\n                      23.494,\n                      -13.127\n                    ],\n                    [\n                      18.284,\n                      -15.137\n                    ]\n                  ],\n                  \"c\": true\n                },\n                \"ix\": 2\n              },\n              \"nm\": \"o\",\n              \"mn\": \"ADBE Vector Shape - Group\",\n              \"hd\": false\n            },\n            {\n              \"ind\": 1,\n              \"ty\": \"sh\",\n              \"ix\": 2,\n              \"ks\": {\n                \"a\": 0,\n                \"k\": {\n                  \"i\": [\n                    [\n                      0,\n                      1.415\n                    ],\n                    [\n                      -0.841,\n                      1.026\n                    ],\n                    [\n                      -1.19,\n                      0\n                    ],\n                    [\n                      -0.615,\n                      -1.825\n                    ],\n                    [\n                      0,\n                      -0.718\n                    ],\n                    [\n                      0.492,\n                      -0.738\n                    ],\n                    [\n                      1.292,\n                      0\n                    ],\n                    [\n                      0.451,\n                      0.615\n                    ]\n                  ],\n                  \"o\": [\n                    [\n                      0,\n                      -1.682\n                    ],\n                    [\n                      0.595,\n                      -0.759\n                    ],\n                    [\n                      1.518,\n                      0\n                    ],\n                    [\n                      0.308,\n                      0.902\n                    ],\n                    [\n                      0,\n                      2.359\n                    ],\n                    [\n                      -0.595,\n                      0.923\n                    ],\n                    [\n                      -1.477,\n                      0\n                    ],\n                    [\n                      -0.882,\n                      -1.149\n                    ]\n                  ],\n                  \"v\": [\n                    [\n                      14.49,\n                      -7.302\n                    ],\n                    [\n                      15.577,\n                      -11.609\n                    ],\n                    [\n                      18.305,\n                      -12.86\n                    ],\n                    [\n                      21.689,\n                      -10.235\n                    ],\n                    [\n                      22.058,\n                      -7.589\n                    ],\n                    [\n                      21.053,\n                      -3.343\n                    ],\n                    [\n                      18.284,\n                      -1.969\n                    ],\n                    [\n                      15.597,\n                      -3.159\n                    ]\n                  ],\n                  \"c\": true\n                },\n                \"ix\": 2\n              },\n              \"nm\": \"o\",\n              \"mn\": \"ADBE Vector Shape - Group\",\n              \"hd\": false\n            },\n            {\n              \"ty\": \"mm\",\n              \"mm\": 1,\n              \"nm\": \"Merge Paths 1\",\n              \"mn\": \"ADBE Vector Filter - Merge\",\n              \"hd\": false\n            },\n            {\n              \"ty\": \"fl\",\n              \"c\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0,\n                  0,\n                  1\n                ],\n                \"ix\": 4\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 100,\n                \"ix\": 5\n              },\n              \"r\": 1,\n              \"bm\": 0,\n              \"nm\": \"Fill 1\",\n              \"mn\": \"ADBE Vector Graphic - Fill\",\n              \"hd\": false\n            },\n            {\n              \"ty\": \"tr\",\n              \"p\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 2\n              },\n              \"a\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 1\n              },\n              \"s\": {\n                \"a\": 0,\n                \"k\": [\n                  100,\n                  100\n                ],\n                \"ix\": 3\n              },\n              \"r\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 6\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 100,\n                \"ix\": 7\n              },\n              \"sk\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 4\n              },\n              \"sa\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 5\n              },\n              \"nm\": \"Transform\"\n            }\n          ],\n          \"nm\": \"o\",\n          \"np\": 5,\n          \"cix\": 2,\n          \"bm\": 0,\n          \"ix\": 2,\n          \"mn\": \"ADBE Vector Group\",\n          \"hd\": false\n        },\n        {\n          \"ty\": \"gr\",\n          \"it\": [\n            {\n              \"ind\": 0,\n              \"ty\": \"sh\",\n              \"ix\": 1,\n              \"ks\": {\n                \"a\": 0,\n                \"k\": {\n                  \"i\": [\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      -0.287,\n                      -0.841\n                    ],\n                    [\n                      -0.144,\n                      -0.82\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0.164,\n                      0.656\n                    ],\n                    [\n                      0.226,\n                      1.743\n                    ],\n                    [\n                      2.236,\n                      0.205\n                    ],\n                    [\n                      0,\n                      2.769\n                    ],\n                    [\n                      0.923,\n                      0.8\n                    ],\n                    [\n                      1.641,\n                      -0.021\n                    ],\n                    [\n                      0,\n                      0\n                    ]\n                  ],\n                  \"o\": [\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0.533,\n                      0\n                    ],\n                    [\n                      0.205,\n                      0.574\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      -0.164,\n                      -0.246\n                    ],\n                    [\n                      -0.103,\n                      -0.41\n                    ],\n                    [\n                      -0.267,\n                      -1.928\n                    ],\n                    [\n                      0.718,\n                      -0.205\n                    ],\n                    [\n                      0,\n                      -0.964\n                    ],\n                    [\n                      -1.19,\n                      -1.026\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ]\n                  ],\n                  \"v\": [\n                    [\n                      27.381,\n                      0\n                    ],\n                    [\n                      30.622,\n                      0\n                    ],\n                    [\n                      30.622,\n                      -5.989\n                    ],\n                    [\n                      33.411,\n                      -5.989\n                    ],\n                    [\n                      35.011,\n                      -5.148\n                    ],\n                    [\n                      35.811,\n                      0\n                    ],\n                    [\n                      39.318,\n                      0\n                    ],\n                    [\n                      38.867,\n                      -1.067\n                    ],\n                    [\n                      38.416,\n                      -3.938\n                    ],\n                    [\n                      35.749,\n                      -7.343\n                    ],\n                    [\n                      38.847,\n                      -10.973\n                    ],\n                    [\n                      37.554,\n                      -13.824\n                    ],\n                    [\n                      33.063,\n                      -14.829\n                    ],\n                    [\n                      27.381,\n                      -14.829\n                    ]\n                  ],\n                  \"c\": true\n                },\n                \"ix\": 2\n              },\n              \"nm\": \"r\",\n              \"mn\": \"ADBE Vector Shape - Group\",\n              \"hd\": false\n            },\n            {\n              \"ind\": 1,\n              \"ty\": \"sh\",\n              \"ix\": 2,\n              \"ks\": {\n                \"a\": 0,\n                \"k\": {\n                  \"i\": [\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      -0.492,\n                      -0.349\n                    ],\n                    [\n                      0,\n                      -1.005\n                    ],\n                    [\n                      0.226,\n                      -0.164\n                    ],\n                    [\n                      0.369,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ]\n                  ],\n                  \"o\": [\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      1.005,\n                      0\n                    ],\n                    [\n                      0.287,\n                      0.185\n                    ],\n                    [\n                      0,\n                      1.046\n                    ],\n                    [\n                      -0.513,\n                      0.41\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ]\n                  ],\n                  \"v\": [\n                    [\n                      30.519,\n                      -12.491\n                    ],\n                    [\n                      32.652,\n                      -12.491\n                    ],\n                    [\n                      34.744,\n                      -12.142\n                    ],\n                    [\n                      35.524,\n                      -10.481\n                    ],\n                    [\n                      34.703,\n                      -8.758\n                    ],\n                    [\n                      33.083,\n                      -8.348\n                    ],\n                    [\n                      30.519,\n                      -8.348\n                    ]\n                  ],\n                  \"c\": true\n                },\n                \"ix\": 2\n              },\n              \"nm\": \"r\",\n              \"mn\": \"ADBE Vector Shape - Group\",\n              \"hd\": false\n            },\n            {\n              \"ty\": \"mm\",\n              \"mm\": 1,\n              \"nm\": \"Merge Paths 1\",\n              \"mn\": \"ADBE Vector Filter - Merge\",\n              \"hd\": false\n            },\n            {\n              \"ty\": \"fl\",\n              \"c\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0,\n                  0,\n                  1\n                ],\n                \"ix\": 4\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 100,\n                \"ix\": 5\n              },\n              \"r\": 1,\n              \"bm\": 0,\n              \"nm\": \"Fill 1\",\n              \"mn\": \"ADBE Vector Graphic - Fill\",\n              \"hd\": false\n            },\n            {\n              \"ty\": \"tr\",\n              \"p\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 2\n              },\n              \"a\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 1\n              },\n              \"s\": {\n                \"a\": 0,\n                \"k\": [\n                  100,\n                  100\n                ],\n                \"ix\": 3\n              },\n              \"r\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 6\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 100,\n                \"ix\": 7\n              },\n              \"sk\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 4\n              },\n              \"sa\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 5\n              },\n              \"nm\": \"Transform\"\n            }\n          ],\n          \"nm\": \"r\",\n          \"np\": 5,\n          \"cix\": 2,\n          \"bm\": 0,\n          \"ix\": 3,\n          \"mn\": \"ADBE Vector Group\",\n          \"hd\": false\n        },\n        {\n          \"ty\": \"gr\",\n          \"it\": [\n            {\n              \"ind\": 0,\n              \"ty\": \"sh\",\n              \"ix\": 1,\n              \"ks\": {\n                \"a\": 0,\n                \"k\": {\n                  \"i\": [\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      -0.554,\n                      0.103\n                    ],\n                    [\n                      0,\n                      4.553\n                    ],\n                    [\n                      1.866,\n                      1.374\n                    ],\n                    [\n                      0.82,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ]\n                  ],\n                  \"o\": [\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      1.497,\n                      0\n                    ],\n                    [\n                      2.81,\n                      -0.513\n                    ],\n                    [\n                      0,\n                      -2.113\n                    ],\n                    [\n                      -1.784,\n                      -1.313\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ]\n                  ],\n                  \"v\": [\n                    [\n                      41.068,\n                      0\n                    ],\n                    [\n                      45.683,\n                      0\n                    ],\n                    [\n                      48.349,\n                      -0.164\n                    ],\n                    [\n                      53.6,\n                      -7.609\n                    ],\n                    [\n                      51.077,\n                      -13.434\n                    ],\n                    [\n                      45.97,\n                      -14.768\n                    ],\n                    [\n                      41.068,\n                      -14.788\n                    ]\n                  ],\n                  \"c\": true\n                },\n                \"ix\": 2\n              },\n              \"nm\": \"d\",\n              \"mn\": \"ADBE Vector Shape - Group\",\n              \"hd\": false\n            },\n            {\n              \"ind\": 1,\n              \"ty\": \"sh\",\n              \"ix\": 2,\n              \"ks\": {\n                \"a\": 0,\n                \"k\": {\n                  \"i\": [\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      -0.656,\n                      -0.185\n                    ],\n                    [\n                      0,\n                      -2.092\n                    ],\n                    [\n                      1.251,\n                      -1.251\n                    ],\n                    [\n                      1.354,\n                      0\n                    ],\n                    [\n                      0.349,\n                      0.021\n                    ]\n                  ],\n                  \"o\": [\n                    [\n                      1.825,\n                      -0.082\n                    ],\n                    [\n                      1.99,\n                      0.554\n                    ],\n                    [\n                      0,\n                      0.718\n                    ],\n                    [\n                      -0.923,\n                      0.923\n                    ],\n                    [\n                      -0.369,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ]\n                  ],\n                  \"v\": [\n                    [\n                      44.288,\n                      -12.388\n                    ],\n                    [\n                      47.611,\n                      -12.183\n                    ],\n                    [\n                      50.318,\n                      -7.609\n                    ],\n                    [\n                      48.985,\n                      -3.425\n                    ],\n                    [\n                      45.539,\n                      -2.4\n                    ],\n                    [\n                      44.288,\n                      -2.441\n                    ]\n                  ],\n                  \"c\": true\n                },\n                \"ix\": 2\n              },\n              \"nm\": \"d\",\n              \"mn\": \"ADBE Vector Shape - Group\",\n              \"hd\": false\n            },\n            {\n              \"ty\": \"mm\",\n              \"mm\": 1,\n              \"nm\": \"Merge Paths 1\",\n              \"mn\": \"ADBE Vector Filter - Merge\",\n              \"hd\": false\n            },\n            {\n              \"ty\": \"fl\",\n              \"c\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0,\n                  0,\n                  1\n                ],\n                \"ix\": 4\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 100,\n                \"ix\": 5\n              },\n              \"r\": 1,\n              \"bm\": 0,\n              \"nm\": \"Fill 1\",\n              \"mn\": \"ADBE Vector Graphic - Fill\",\n              \"hd\": false\n            },\n            {\n              \"ty\": \"tr\",\n              \"p\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 2\n              },\n              \"a\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 1\n              },\n              \"s\": {\n                \"a\": 0,\n                \"k\": [\n                  100,\n                  100\n                ],\n                \"ix\": 3\n              },\n              \"r\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 6\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 100,\n                \"ix\": 7\n              },\n              \"sk\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 4\n              },\n              \"sa\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 5\n              },\n              \"nm\": \"Transform\"\n            }\n          ],\n          \"nm\": \"d\",\n          \"np\": 5,\n          \"cix\": 2,\n          \"bm\": 0,\n          \"ix\": 4,\n          \"mn\": \"ADBE Vector Group\",\n          \"hd\": false\n        },\n        {\n          \"ty\": \"gr\",\n          \"it\": [\n            {\n              \"ind\": 0,\n              \"ty\": \"sh\",\n              \"ix\": 1,\n              \"ks\": {\n                \"a\": 0,\n                \"k\": {\n                  \"i\": [\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ]\n                  ],\n                  \"o\": [\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ]\n                  ],\n                  \"v\": [\n                    [\n                      55.669,\n                      0\n                    ],\n                    [\n                      58.849,\n                      0\n                    ],\n                    [\n                      58.849,\n                      -14.87\n                    ],\n                    [\n                      55.669,\n                      -14.87\n                    ]\n                  ],\n                  \"c\": true\n                },\n                \"ix\": 2\n              },\n              \"nm\": \"i\",\n              \"mn\": \"ADBE Vector Shape - Group\",\n              \"hd\": false\n            },\n            {\n              \"ty\": \"fl\",\n              \"c\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0,\n                  0,\n                  1\n                ],\n                \"ix\": 4\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 100,\n                \"ix\": 5\n              },\n              \"r\": 1,\n              \"bm\": 0,\n              \"nm\": \"Fill 1\",\n              \"mn\": \"ADBE Vector Graphic - Fill\",\n              \"hd\": false\n            },\n            {\n              \"ty\": \"tr\",\n              \"p\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 2\n              },\n              \"a\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 1\n              },\n              \"s\": {\n                \"a\": 0,\n                \"k\": [\n                  100,\n                  100\n                ],\n                \"ix\": 3\n              },\n              \"r\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 6\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 100,\n                \"ix\": 7\n              },\n              \"sk\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 4\n              },\n              \"sa\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 5\n              },\n              \"nm\": \"Transform\"\n            }\n          ],\n          \"nm\": \"i\",\n          \"np\": 3,\n          \"cix\": 2,\n          \"bm\": 0,\n          \"ix\": 5,\n          \"mn\": \"ADBE Vector Group\",\n          \"hd\": false\n        },\n        {\n          \"ty\": \"gr\",\n          \"it\": [\n            {\n              \"ind\": 0,\n              \"ty\": \"sh\",\n              \"ix\": 1,\n              \"ks\": {\n                \"a\": 0,\n                \"k\": {\n                  \"i\": [\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      3.241,\n                      0\n                    ],\n                    [\n                      0,\n                      -4.697\n                    ],\n                    [\n                      -5.107,\n                      0\n                    ],\n                    [\n                      -1.313,\n                      1.354\n                    ],\n                    [\n                      -0.062,\n                      0.882\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      1.333,\n                      0\n                    ],\n                    [\n                      0,\n                      0.882\n                    ],\n                    [\n                      -2.359,\n                      0\n                    ],\n                    [\n                      -0.062,\n                      -0.513\n                    ]\n                  ],\n                  \"o\": [\n                    [\n                      0,\n                      -2.954\n                    ],\n                    [\n                      -4.164,\n                      0\n                    ],\n                    [\n                      0,\n                      3.671\n                    ],\n                    [\n                      1.354,\n                      0\n                    ],\n                    [\n                      1.19,\n                      -1.231\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      -0.062,\n                      1.969\n                    ],\n                    [\n                      -3.097,\n                      0\n                    ],\n                    [\n                      0,\n                      -3.056\n                    ],\n                    [\n                      2.154,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ]\n                  ],\n                  \"v\": [\n                    [\n                      73.104,\n                      -9.989\n                    ],\n                    [\n                      67.587,\n                      -14.911\n                    ],\n                    [\n                      60.798,\n                      -7.097\n                    ],\n                    [\n                      67.566,\n                      0.349\n                    ],\n                    [\n                      71.894,\n                      -1.313\n                    ],\n                    [\n                      73.227,\n                      -4.799\n                    ],\n                    [\n                      69.884,\n                      -4.799\n                    ],\n                    [\n                      67.218,\n                      -1.99\n                    ],\n                    [\n                      64.121,\n                      -7.076\n                    ],\n                    [\n                      67.464,\n                      -12.593\n                    ],\n                    [\n                      69.864,\n                      -9.989\n                    ]\n                  ],\n                  \"c\": true\n                },\n                \"ix\": 2\n              },\n              \"nm\": \"c\",\n              \"mn\": \"ADBE Vector Shape - Group\",\n              \"hd\": false\n            },\n            {\n              \"ty\": \"fl\",\n              \"c\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0,\n                  0,\n                  1\n                ],\n                \"ix\": 4\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 100,\n                \"ix\": 5\n              },\n              \"r\": 1,\n              \"bm\": 0,\n              \"nm\": \"Fill 1\",\n              \"mn\": \"ADBE Vector Graphic - Fill\",\n              \"hd\": false\n            },\n            {\n              \"ty\": \"tr\",\n              \"p\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 2\n              },\n              \"a\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 1\n              },\n              \"s\": {\n                \"a\": 0,\n                \"k\": [\n                  100,\n                  100\n                ],\n                \"ix\": 3\n              },\n              \"r\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 6\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 100,\n                \"ix\": 7\n              },\n              \"sk\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 4\n              },\n              \"sa\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 5\n              },\n              \"nm\": \"Transform\"\n            }\n          ],\n          \"nm\": \"c\",\n          \"np\": 3,\n          \"cix\": 2,\n          \"bm\": 0,\n          \"ix\": 6,\n          \"mn\": \"ADBE Vector Group\",\n          \"hd\": false\n        },\n        {\n          \"ty\": \"gr\",\n          \"it\": [\n            {\n              \"ind\": 0,\n              \"ty\": \"sh\",\n              \"ix\": 1,\n              \"ks\": {\n                \"a\": 0,\n                \"k\": {\n                  \"i\": [\n                    [\n                      0,\n                      -3.938\n                    ],\n                    [\n                      -1.62,\n                      -1.723\n                    ],\n                    [\n                      -1.949,\n                      0\n                    ],\n                    [\n                      -1.641,\n                      1.846\n                    ],\n                    [\n                      0,\n                      2.154\n                    ],\n                    [\n                      1.579,\n                      1.805\n                    ],\n                    [\n                      1.579,\n                      0\n                    ]\n                  ],\n                  \"o\": [\n                    [\n                      0,\n                      1.354\n                    ],\n                    [\n                      1.354,\n                      1.415\n                    ],\n                    [\n                      1.231,\n                      0\n                    ],\n                    [\n                      1.21,\n                      -1.354\n                    ],\n                    [\n                      0,\n                      -1.456\n                    ],\n                    [\n                      -1.456,\n                      -1.641\n                    ],\n                    [\n                      -5.333,\n                      0\n                    ]\n                  ],\n                  \"v\": [\n                    [\n                      74.546,\n                      -7.199\n                    ],\n                    [\n                      76.372,\n                      -1.661\n                    ],\n                    [\n                      81.622,\n                      0.369\n                    ],\n                    [\n                      86.894,\n                      -1.743\n                    ],\n                    [\n                      88.76,\n                      -7.548\n                    ],\n                    [\n                      86.873,\n                      -13.127\n                    ],\n                    [\n                      81.663,\n                      -15.137\n                    ]\n                  ],\n                  \"c\": true\n                },\n                \"ix\": 2\n              },\n              \"nm\": \"o\",\n              \"mn\": \"ADBE Vector Shape - Group\",\n              \"hd\": false\n            },\n            {\n              \"ind\": 1,\n              \"ty\": \"sh\",\n              \"ix\": 2,\n              \"ks\": {\n                \"a\": 0,\n                \"k\": {\n                  \"i\": [\n                    [\n                      0,\n                      1.415\n                    ],\n                    [\n                      -0.841,\n                      1.026\n                    ],\n                    [\n                      -1.19,\n                      0\n                    ],\n                    [\n                      -0.615,\n                      -1.825\n                    ],\n                    [\n                      0,\n                      -0.718\n                    ],\n                    [\n                      0.492,\n                      -0.738\n                    ],\n                    [\n                      1.292,\n                      0\n                    ],\n                    [\n                      0.451,\n                      0.615\n                    ]\n                  ],\n                  \"o\": [\n                    [\n                      0,\n                      -1.682\n                    ],\n                    [\n                      0.595,\n                      -0.759\n                    ],\n                    [\n                      1.518,\n                      0\n                    ],\n                    [\n                      0.308,\n                      0.902\n                    ],\n                    [\n                      0,\n                      2.359\n                    ],\n                    [\n                      -0.595,\n                      0.923\n                    ],\n                    [\n                      -1.477,\n                      0\n                    ],\n                    [\n                      -0.882,\n                      -1.149\n                    ]\n                  ],\n                  \"v\": [\n                    [\n                      77.869,\n                      -7.302\n                    ],\n                    [\n                      78.956,\n                      -11.609\n                    ],\n                    [\n                      81.684,\n                      -12.86\n                    ],\n                    [\n                      85.068,\n                      -10.235\n                    ],\n                    [\n                      85.437,\n                      -7.589\n                    ],\n                    [\n                      84.432,\n                      -3.343\n                    ],\n                    [\n                      81.663,\n                      -1.969\n                    ],\n                    [\n                      78.977,\n                      -3.159\n                    ]\n                  ],\n                  \"c\": true\n                },\n                \"ix\": 2\n              },\n              \"nm\": \"o\",\n              \"mn\": \"ADBE Vector Shape - Group\",\n              \"hd\": false\n            },\n            {\n              \"ty\": \"mm\",\n              \"mm\": 1,\n              \"nm\": \"Merge Paths 1\",\n              \"mn\": \"ADBE Vector Filter - Merge\",\n              \"hd\": false\n            },\n            {\n              \"ty\": \"fl\",\n              \"c\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0,\n                  0,\n                  1\n                ],\n                \"ix\": 4\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 100,\n                \"ix\": 5\n              },\n              \"r\": 1,\n              \"bm\": 0,\n              \"nm\": \"Fill 1\",\n              \"mn\": \"ADBE Vector Graphic - Fill\",\n              \"hd\": false\n            },\n            {\n              \"ty\": \"tr\",\n              \"p\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 2\n              },\n              \"a\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 1\n              },\n              \"s\": {\n                \"a\": 0,\n                \"k\": [\n                  100,\n                  100\n                ],\n                \"ix\": 3\n              },\n              \"r\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 6\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 100,\n                \"ix\": 7\n              },\n              \"sk\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 4\n              },\n              \"sa\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 5\n              },\n              \"nm\": \"Transform\"\n            }\n          ],\n          \"nm\": \"o\",\n          \"np\": 5,\n          \"cix\": 2,\n          \"bm\": 0,\n          \"ix\": 7,\n          \"mn\": \"ADBE Vector Group\",\n          \"hd\": false\n        },\n        {\n          \"ty\": \"gr\",\n          \"it\": [\n            {\n              \"ind\": 0,\n              \"ty\": \"sh\",\n              \"ix\": 1,\n              \"ks\": {\n                \"a\": 0,\n                \"k\": {\n                  \"i\": [\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ]\n                  ],\n                  \"o\": [\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ]\n                  ],\n                  \"v\": [\n                    [\n                      91.007,\n                      0\n                    ],\n                    [\n                      94.001,\n                      0\n                    ],\n                    [\n                      94.001,\n                      -12.306\n                    ],\n                    [\n                      99.744,\n                      0\n                    ],\n                    [\n                      104.113,\n                      0\n                    ],\n                    [\n                      104.113,\n                      -14.829\n                    ],\n                    [\n                      101.159,\n                      -14.829\n                    ],\n                    [\n                      101.159,\n                      -3.159\n                    ],\n                    [\n                      95.601,\n                      -14.829\n                    ],\n                    [\n                      91.007,\n                      -14.829\n                    ]\n                  ],\n                  \"c\": true\n                },\n                \"ix\": 2\n              },\n              \"nm\": \"n\",\n              \"mn\": \"ADBE Vector Shape - Group\",\n              \"hd\": false\n            },\n            {\n              \"ty\": \"fl\",\n              \"c\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0,\n                  0,\n                  1\n                ],\n                \"ix\": 4\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 100,\n                \"ix\": 5\n              },\n              \"r\": 1,\n              \"bm\": 0,\n              \"nm\": \"Fill 1\",\n              \"mn\": \"ADBE Vector Graphic - Fill\",\n              \"hd\": false\n            },\n            {\n              \"ty\": \"tr\",\n              \"p\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 2\n              },\n              \"a\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 1\n              },\n              \"s\": {\n                \"a\": 0,\n                \"k\": [\n                  100,\n                  100\n                ],\n                \"ix\": 3\n              },\n              \"r\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 6\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 100,\n                \"ix\": 7\n              },\n              \"sk\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 4\n              },\n              \"sa\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 5\n              },\n              \"nm\": \"Transform\"\n            }\n          ],\n          \"nm\": \"n\",\n          \"np\": 3,\n          \"cix\": 2,\n          \"bm\": 0,\n          \"ix\": 8,\n          \"mn\": \"ADBE Vector Group\",\n          \"hd\": false\n        },\n        {\n          \"ty\": \"gr\",\n          \"it\": [\n            {\n              \"ind\": 0,\n              \"ty\": \"sh\",\n              \"ix\": 1,\n              \"ks\": {\n                \"a\": 0,\n                \"k\": {\n                  \"i\": [\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ]\n                  ],\n                  \"o\": [\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ]\n                  ],\n                  \"v\": [\n                    [\n                      106.893,\n                      0\n                    ],\n                    [\n                      109.497,\n                      0\n                    ],\n                    [\n                      109.497,\n                      -2.728\n                    ],\n                    [\n                      106.893,\n                      -2.728\n                    ]\n                  ],\n                  \"c\": true\n                },\n                \"ix\": 2\n              },\n              \"nm\": \".\",\n              \"mn\": \"ADBE Vector Shape - Group\",\n              \"hd\": false\n            },\n            {\n              \"ty\": \"fl\",\n              \"c\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0,\n                  0,\n                  1\n                ],\n                \"ix\": 4\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 100,\n                \"ix\": 5\n              },\n              \"r\": 1,\n              \"bm\": 0,\n              \"nm\": \"Fill 1\",\n              \"mn\": \"ADBE Vector Graphic - Fill\",\n              \"hd\": false\n            },\n            {\n              \"ty\": \"tr\",\n              \"p\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 2\n              },\n              \"a\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 1\n              },\n              \"s\": {\n                \"a\": 0,\n                \"k\": [\n                  100,\n                  100\n                ],\n                \"ix\": 3\n              },\n              \"r\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 6\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 100,\n                \"ix\": 7\n              },\n              \"sk\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 4\n              },\n              \"sa\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 5\n              },\n              \"nm\": \"Transform\"\n            }\n          ],\n          \"nm\": \".\",\n          \"np\": 3,\n          \"cix\": 2,\n          \"bm\": 0,\n          \"ix\": 9,\n          \"mn\": \"ADBE Vector Group\",\n          \"hd\": false\n        },\n        {\n          \"ty\": \"gr\",\n          \"it\": [\n            {\n              \"ind\": 0,\n              \"ty\": \"sh\",\n              \"ix\": 1,\n              \"ks\": {\n                \"a\": 0,\n                \"k\": {\n                  \"i\": [\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      3.241,\n                      0\n                    ],\n                    [\n                      0,\n                      -4.697\n                    ],\n                    [\n                      -5.107,\n                      0\n                    ],\n                    [\n                      -1.313,\n                      1.354\n                    ],\n                    [\n                      -0.062,\n                      0.882\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      1.333,\n                      0\n                    ],\n                    [\n                      0,\n                      0.882\n                    ],\n                    [\n                      -2.359,\n                      0\n                    ],\n                    [\n                      -0.062,\n                      -0.513\n                    ]\n                  ],\n                  \"o\": [\n                    [\n                      0,\n                      -2.954\n                    ],\n                    [\n                      -4.164,\n                      0\n                    ],\n                    [\n                      0,\n                      3.671\n                    ],\n                    [\n                      1.354,\n                      0\n                    ],\n                    [\n                      1.19,\n                      -1.231\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      -0.062,\n                      1.969\n                    ],\n                    [\n                      -3.097,\n                      0\n                    ],\n                    [\n                      0,\n                      -3.056\n                    ],\n                    [\n                      2.154,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ]\n                  ],\n                  \"v\": [\n                    [\n                      124.04,\n                      -9.989\n                    ],\n                    [\n                      118.523,\n                      -14.911\n                    ],\n                    [\n                      111.734,\n                      -7.097\n                    ],\n                    [\n                      118.502,\n                      0.349\n                    ],\n                    [\n                      122.83,\n                      -1.313\n                    ],\n                    [\n                      124.163,\n                      -4.799\n                    ],\n                    [\n                      120.82,\n                      -4.799\n                    ],\n                    [\n                      118.154,\n                      -1.99\n                    ],\n                    [\n                      115.057,\n                      -7.076\n                    ],\n                    [\n                      118.4,\n                      -12.593\n                    ],\n                    [\n                      120.8,\n                      -9.989\n                    ]\n                  ],\n                  \"c\": true\n                },\n                \"ix\": 2\n              },\n              \"nm\": \"c\",\n              \"mn\": \"ADBE Vector Shape - Group\",\n              \"hd\": false\n            },\n            {\n              \"ty\": \"fl\",\n              \"c\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0,\n                  0,\n                  1\n                ],\n                \"ix\": 4\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 100,\n                \"ix\": 5\n              },\n              \"r\": 1,\n              \"bm\": 0,\n              \"nm\": \"Fill 1\",\n              \"mn\": \"ADBE Vector Graphic - Fill\",\n              \"hd\": false\n            },\n            {\n              \"ty\": \"tr\",\n              \"p\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 2\n              },\n              \"a\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 1\n              },\n              \"s\": {\n                \"a\": 0,\n                \"k\": [\n                  100,\n                  100\n                ],\n                \"ix\": 3\n              },\n              \"r\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 6\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 100,\n                \"ix\": 7\n              },\n              \"sk\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 4\n              },\n              \"sa\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 5\n              },\n              \"nm\": \"Transform\"\n            }\n          ],\n          \"nm\": \"c\",\n          \"np\": 3,\n          \"cix\": 2,\n          \"bm\": 0,\n          \"ix\": 10,\n          \"mn\": \"ADBE Vector Group\",\n          \"hd\": false\n        },\n        {\n          \"ty\": \"gr\",\n          \"it\": [\n            {\n              \"ind\": 0,\n              \"ty\": \"sh\",\n              \"ix\": 1,\n              \"ks\": {\n                \"a\": 0,\n                \"k\": {\n                  \"i\": [\n                    [\n                      0,\n                      -3.938\n                    ],\n                    [\n                      -1.62,\n                      -1.723\n                    ],\n                    [\n                      -1.949,\n                      0\n                    ],\n                    [\n                      -1.641,\n                      1.846\n                    ],\n                    [\n                      0,\n                      2.154\n                    ],\n                    [\n                      1.579,\n                      1.805\n                    ],\n                    [\n                      1.579,\n                      0\n                    ]\n                  ],\n                  \"o\": [\n                    [\n                      0,\n                      1.354\n                    ],\n                    [\n                      1.354,\n                      1.415\n                    ],\n                    [\n                      1.231,\n                      0\n                    ],\n                    [\n                      1.21,\n                      -1.354\n                    ],\n                    [\n                      0,\n                      -1.456\n                    ],\n                    [\n                      -1.456,\n                      -1.641\n                    ],\n                    [\n                      -5.333,\n                      0\n                    ]\n                  ],\n                  \"v\": [\n                    [\n                      125.482,\n                      -7.199\n                    ],\n                    [\n                      127.308,\n                      -1.661\n                    ],\n                    [\n                      132.558,\n                      0.369\n                    ],\n                    [\n                      137.829,\n                      -1.743\n                    ],\n                    [\n                      139.696,\n                      -7.548\n                    ],\n                    [\n                      137.809,\n                      -13.127\n                    ],\n                    [\n                      132.599,\n                      -15.137\n                    ]\n                  ],\n                  \"c\": true\n                },\n                \"ix\": 2\n              },\n              \"nm\": \"o\",\n              \"mn\": \"ADBE Vector Shape - Group\",\n              \"hd\": false\n            },\n            {\n              \"ind\": 1,\n              \"ty\": \"sh\",\n              \"ix\": 2,\n              \"ks\": {\n                \"a\": 0,\n                \"k\": {\n                  \"i\": [\n                    [\n                      0,\n                      1.415\n                    ],\n                    [\n                      -0.841,\n                      1.026\n                    ],\n                    [\n                      -1.19,\n                      0\n                    ],\n                    [\n                      -0.615,\n                      -1.825\n                    ],\n                    [\n                      0,\n                      -0.718\n                    ],\n                    [\n                      0.492,\n                      -0.738\n                    ],\n                    [\n                      1.292,\n                      0\n                    ],\n                    [\n                      0.451,\n                      0.615\n                    ]\n                  ],\n                  \"o\": [\n                    [\n                      0,\n                      -1.682\n                    ],\n                    [\n                      0.595,\n                      -0.759\n                    ],\n                    [\n                      1.518,\n                      0\n                    ],\n                    [\n                      0.308,\n                      0.902\n                    ],\n                    [\n                      0,\n                      2.359\n                    ],\n                    [\n                      -0.595,\n                      0.923\n                    ],\n                    [\n                      -1.477,\n                      0\n                    ],\n                    [\n                      -0.882,\n                      -1.149\n                    ]\n                  ],\n                  \"v\": [\n                    [\n                      128.805,\n                      -7.302\n                    ],\n                    [\n                      129.892,\n                      -11.609\n                    ],\n                    [\n                      132.62,\n                      -12.86\n                    ],\n                    [\n                      136.004,\n                      -10.235\n                    ],\n                    [\n                      136.373,\n                      -7.589\n                    ],\n                    [\n                      135.368,\n                      -3.343\n                    ],\n                    [\n                      132.599,\n                      -1.969\n                    ],\n                    [\n                      129.912,\n                      -3.159\n                    ]\n                  ],\n                  \"c\": true\n                },\n                \"ix\": 2\n              },\n              \"nm\": \"o\",\n              \"mn\": \"ADBE Vector Shape - Group\",\n              \"hd\": false\n            },\n            {\n              \"ty\": \"mm\",\n              \"mm\": 1,\n              \"nm\": \"Merge Paths 1\",\n              \"mn\": \"ADBE Vector Filter - Merge\",\n              \"hd\": false\n            },\n            {\n              \"ty\": \"fl\",\n              \"c\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0,\n                  0,\n                  1\n                ],\n                \"ix\": 4\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 100,\n                \"ix\": 5\n              },\n              \"r\": 1,\n              \"bm\": 0,\n              \"nm\": \"Fill 1\",\n              \"mn\": \"ADBE Vector Graphic - Fill\",\n              \"hd\": false\n            },\n            {\n              \"ty\": \"tr\",\n              \"p\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 2\n              },\n              \"a\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 1\n              },\n              \"s\": {\n                \"a\": 0,\n                \"k\": [\n                  100,\n                  100\n                ],\n                \"ix\": 3\n              },\n              \"r\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 6\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 100,\n                \"ix\": 7\n              },\n              \"sk\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 4\n              },\n              \"sa\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 5\n              },\n              \"nm\": \"Transform\"\n            }\n          ],\n          \"nm\": \"o\",\n          \"np\": 5,\n          \"cix\": 2,\n          \"bm\": 0,\n          \"ix\": 11,\n          \"mn\": \"ADBE Vector Group\",\n          \"hd\": false\n        },\n        {\n          \"ty\": \"gr\",\n          \"it\": [\n            {\n              \"ind\": 0,\n              \"ty\": \"sh\",\n              \"ix\": 1,\n              \"ks\": {\n                \"a\": 0,\n                \"k\": {\n                  \"i\": [\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ]\n                  ],\n                  \"o\": [\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ],\n                    [\n                      0,\n                      0\n                    ]\n                  ],\n                  \"v\": [\n                    [\n                      141.696,\n                      0\n                    ],\n                    [\n                      144.67,\n                      0\n                    ],\n                    [\n                      144.67,\n                      -12.716\n                    ],\n                    [\n                      148.629,\n                      0\n                    ],\n                    [\n                      151.254,\n                      0\n                    ],\n                    [\n                      155.295,\n                      -12.716\n                    ],\n                    [\n                      155.295,\n                      0\n                    ],\n                    [\n                      158.453,\n                      0\n                    ],\n                    [\n                      158.453,\n                      -14.829\n                    ],\n                    [\n                      153.408,\n                      -14.829\n                    ],\n                    [\n                      150.024,\n                      -4.041\n                    ],\n                    [\n                      146.885,\n                      -14.829\n                    ],\n                    [\n                      141.696,\n                      -14.829\n                    ]\n                  ],\n                  \"c\": true\n                },\n                \"ix\": 2\n              },\n              \"nm\": \"m\",\n              \"mn\": \"ADBE Vector Shape - Group\",\n              \"hd\": false\n            },\n            {\n              \"ty\": \"fl\",\n              \"c\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0,\n                  0,\n                  1\n                ],\n                \"ix\": 4\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 100,\n                \"ix\": 5\n              },\n              \"r\": 1,\n              \"bm\": 0,\n              \"nm\": \"Fill 1\",\n              \"mn\": \"ADBE Vector Graphic - Fill\",\n              \"hd\": false\n            },\n            {\n              \"ty\": \"tr\",\n              \"p\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 2\n              },\n              \"a\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 1\n              },\n              \"s\": {\n                \"a\": 0,\n                \"k\": [\n                  100,\n                  100\n                ],\n                \"ix\": 3\n              },\n              \"r\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 6\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 100,\n                \"ix\": 7\n              },\n              \"sk\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 4\n              },\n              \"sa\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 5\n              },\n              \"nm\": \"Transform\"\n            }\n          ],\n          \"nm\": \"m\",\n          \"np\": 3,\n          \"cix\": 2,\n          \"bm\": 0,\n          \"ix\": 12,\n          \"mn\": \"ADBE Vector Group\",\n          \"hd\": false\n        }\n      ],\n      \"ip\": 1.04166666666667,\n      \"op\": 10.4166666666667,\n      \"st\": 0,\n      \"bm\": 0\n    },\n    {\n      \"ddd\": 0,\n      \"ind\": 3,\n      \"ty\": 3,\n      \"nm\": \"Color  & Stroke Change\",\n      \"sr\": 1,\n      \"ks\": {\n        \"o\": {\n          \"a\": 0,\n          \"k\": 0,\n          \"ix\": 11\n        },\n        \"r\": {\n          \"a\": 0,\n          \"k\": 0,\n          \"ix\": 10\n        },\n        \"p\": {\n          \"a\": 0,\n          \"k\": [\n            0,\n            0\n          ],\n          \"ix\": 2,\n          \"l\": 2\n        },\n        \"a\": {\n          \"a\": 0,\n          \"k\": [\n            0,\n            0,\n            0\n          ],\n          \"ix\": 1,\n          \"l\": 2\n        },\n        \"s\": {\n          \"a\": 0,\n          \"k\": [\n            100,\n            100,\n            100\n          ],\n          \"ix\": 6,\n          \"l\": 2\n        }\n      },\n      \"ao\": 0,\n      \"ef\": [\n        {\n          \"ty\": 5,\n          \"nm\": \"Primary\",\n          \"np\": 3,\n          \"mn\": \"ADBE Color Control\",\n          \"ix\": 1,\n          \"en\": 1,\n          \"ef\": [\n            {\n              \"ty\": 2,\n              \"nm\": \"Color\",\n              \"mn\": \"ADBE Color Control-0001\",\n              \"ix\": 1,\n              \"v\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0,\n                  0\n                ],\n                \"ix\": 1\n              }\n            }\n          ]\n        },\n        {\n          \"ty\": 5,\n          \"nm\": \"Secondary\",\n          \"np\": 3,\n          \"mn\": \"ADBE Color Control\",\n          \"ix\": 2,\n          \"en\": 1,\n          \"ef\": [\n            {\n              \"ty\": 2,\n              \"nm\": \"Color\",\n              \"mn\": \"ADBE Color Control-0001\",\n              \"ix\": 1,\n              \"v\": {\n                \"a\": 0,\n                \"k\": [\n                  0.941,\n                  0.725,\n                  0.043\n                ],\n                \"ix\": 1\n              }\n            }\n          ]\n        },\n        {\n          \"ty\": 5,\n          \"nm\": \"Stroke\",\n          \"np\": 3,\n          \"mn\": \"ADBE Slider Control\",\n          \"ix\": 3,\n          \"en\": 1,\n          \"ef\": [\n            {\n              \"ty\": 0,\n              \"nm\": \"Slider\",\n              \"mn\": \"ADBE Slider Control-0001\",\n              \"ix\": 1,\n              \"v\": {\n                \"a\": 0,\n                \"k\": 70,\n                \"ix\": 1\n              }\n            }\n          ]\n        },\n        {\n          \"ty\": 5,\n          \"nm\": \"Scale\",\n          \"np\": 3,\n          \"mn\": \"ADBE Slider Control\",\n          \"ix\": 4,\n          \"en\": 1,\n          \"ef\": [\n            {\n              \"ty\": 0,\n              \"nm\": \"Slider\",\n              \"mn\": \"ADBE Slider Control-0001\",\n              \"ix\": 1,\n              \"v\": {\n                \"a\": 0,\n                \"k\": 100,\n                \"ix\": 1\n              }\n            }\n          ]\n        },\n        {\n          \"ty\": 5,\n          \"nm\": \"Axis\",\n          \"np\": 3,\n          \"mn\": \"ADBE Point Control\",\n          \"ix\": 5,\n          \"en\": 1,\n          \"ef\": [\n            {\n              \"ty\": 3,\n              \"nm\": \"Point\",\n              \"mn\": \"ADBE Point Control-0001\",\n              \"ix\": 1,\n              \"v\": {\n                \"a\": 0,\n                \"k\": [\n                  250,\n                  250\n                ],\n                \"ix\": 1\n              }\n            }\n          ]\n        }\n      ],\n      \"ip\": 0,\n      \"op\": 125,\n      \"st\": 0,\n      \"bm\": 0\n    },\n    {\n      \"ddd\": 0,\n      \"ind\": 4,\n      \"ty\": 3,\n      \"nm\": \"NULL 2\",\n      \"sr\": 1,\n      \"ks\": {\n        \"o\": {\n          \"a\": 0,\n          \"k\": 0,\n          \"ix\": 11\n        },\n        \"r\": {\n          \"a\": 0,\n          \"k\": 0,\n          \"ix\": 10\n        },\n        \"p\": {\n          \"a\": 0,\n          \"k\": [\n            250,\n            250,\n            0\n          ],\n          \"ix\": 2,\n          \"x\": \"var $bm_rt;\\n$bm_rt = thisComp.layer('Color  & Stroke Change').effect('Axis')('Point');\",\n          \"l\": 2\n        },\n        \"a\": {\n          \"a\": 0,\n          \"k\": [\n            60,\n            60,\n            0\n          ],\n          \"ix\": 1,\n          \"l\": 2\n        },\n        \"s\": {\n          \"a\": 0,\n          \"k\": [\n            100,\n            100,\n            100\n          ],\n          \"ix\": 6,\n          \"x\": \"var $bm_rt;\\nvar temp;\\ntemp = thisComp.layer('Color  & Stroke Change').effect('Scale')('Slider');\\n$bm_rt = [\\n    temp,\\n    temp\\n];\",\n          \"l\": 2\n        }\n      },\n      \"ao\": 0,\n      \"ip\": 0,\n      \"op\": 125,\n      \"st\": 0,\n      \"bm\": 0\n    },\n    {\n      \"ddd\": 0,\n      \"ind\": 6,\n      \"ty\": 3,\n      \"nm\": \"NULL\",\n      \"parent\": 4,\n      \"sr\": 1,\n      \"ks\": {\n        \"o\": {\n          \"a\": 0,\n          \"k\": 0,\n          \"ix\": 11\n        },\n        \"r\": {\n          \"a\": 0,\n          \"k\": 0,\n          \"ix\": 10\n        },\n        \"p\": {\n          \"a\": 0,\n          \"k\": [\n            60,\n            30,\n            0\n          ],\n          \"ix\": 2,\n          \"l\": 2\n        },\n        \"a\": {\n          \"a\": 0,\n          \"k\": [\n            60,\n            60,\n            0\n          ],\n          \"ix\": 1,\n          \"l\": 2\n        },\n        \"s\": {\n          \"a\": 0,\n          \"k\": [\n            430,\n            430,\n            100\n          ],\n          \"ix\": 6,\n          \"l\": 2\n        }\n      },\n      \"ao\": 0,\n      \"ip\": 0,\n      \"op\": 125,\n      \"st\": 0,\n      \"bm\": 0\n    },\n    {\n      \"ddd\": 0,\n      \"ind\": 7,\n      \"ty\": 3,\n      \"nm\": \"NULL CONTROL\",\n      \"parent\": 6,\n      \"sr\": 1,\n      \"ks\": {\n        \"o\": {\n          \"a\": 0,\n          \"k\": 0,\n          \"ix\": 11\n        },\n        \"r\": {\n          \"a\": 0,\n          \"k\": 0,\n          \"ix\": 10\n        },\n        \"p\": {\n          \"a\": 0,\n          \"k\": [\n            59.5,\n            60.25,\n            0\n          ],\n          \"ix\": 2,\n          \"l\": 2\n        },\n        \"a\": {\n          \"a\": 0,\n          \"k\": [\n            60,\n            60,\n            0\n          ],\n          \"ix\": 1,\n          \"l\": 2\n        },\n        \"s\": {\n          \"a\": 0,\n          \"k\": [\n            9,\n            9,\n            100\n          ],\n          \"ix\": 6,\n          \"l\": 2\n        }\n      },\n      \"ao\": 0,\n      \"ip\": 0,\n      \"op\": 250,\n      \"st\": 0,\n      \"bm\": 0\n    },\n    {\n      \"ddd\": 0,\n      \"ind\": 8,\n      \"ty\": 4,\n      \"nm\": \"Warstwa 5\",\n      \"parent\": 7,\n      \"sr\": 1,\n      \"ks\": {\n        \"o\": {\n          \"a\": 0,\n          \"k\": 100,\n          \"ix\": 11\n        },\n        \"r\": {\n          \"a\": 1,\n          \"k\": [\n            {\n              \"i\": {\n                \"x\": [\n                  0.582\n                ],\n                \"y\": [\n                  0.428\n                ]\n              },\n              \"o\": {\n                \"x\": [\n                  0.578\n                ],\n                \"y\": [\n                  0.816\n                ]\n              },\n              \"t\": 0,\n              \"s\": [\n                0\n              ]\n            },\n            {\n              \"i\": {\n                \"x\": [\n                  0.519\n                ],\n                \"y\": [\n                  0.336\n                ]\n              },\n              \"o\": {\n                \"x\": [\n                  0.483\n                ],\n                \"y\": [\n                  0.702\n                ]\n              },\n              \"t\": 13.778,\n              \"s\": [\n                300\n              ]\n            },\n            {\n              \"i\": {\n                \"x\": [\n                  0.667\n                ],\n                \"y\": [\n                  1\n                ]\n              },\n              \"o\": {\n                \"x\": [\n                  0.167\n                ],\n                \"y\": [\n                  0.167\n                ]\n              },\n              \"t\": 24.799,\n              \"s\": [\n                334.632\n              ]\n            },\n            {\n              \"t\": 41,\n              \"s\": [\n                360\n              ]\n            }\n          ],\n          \"ix\": 10\n        },\n        \"p\": {\n          \"a\": 1,\n          \"k\": [\n            {\n              \"i\": {\n                \"x\": 0.32,\n                \"y\": 1\n              },\n              \"o\": {\n                \"x\": 0.167,\n                \"y\": 0.167\n              },\n              \"t\": 0,\n              \"s\": [\n                191.141,\n                268.927,\n                0\n              ],\n              \"to\": [\n                -7.792,\n                -32.76,\n                0\n              ],\n              \"ti\": [\n                34.748,\n                2.491,\n                0\n              ]\n            },\n            {\n              \"i\": {\n                \"x\": 0.833,\n                \"y\": 0.833\n              },\n              \"o\": {\n                \"x\": 0.68,\n                \"y\": 0\n              },\n              \"t\": 8,\n              \"s\": [\n                134.693,\n                71.2,\n                0\n              ],\n              \"to\": [\n                -29.218,\n                -2.094,\n                0\n              ],\n              \"ti\": [\n                0,\n                -17.366,\n                0\n              ]\n            },\n            {\n              \"i\": {\n                \"x\": 0.667,\n                \"y\": 1\n              },\n              \"o\": {\n                \"x\": 0.167,\n                \"y\": 0.167\n              },\n              \"t\": 13.778,\n              \"s\": [\n                95.629,\n                268.927,\n                0\n              ],\n              \"to\": [\n                0,\n                -9.117,\n                0\n              ],\n              \"ti\": [\n                -14.935,\n                0.102,\n                0\n              ]\n            },\n            {\n              \"i\": {\n                \"x\": 0.833,\n                \"y\": 0.833\n              },\n              \"o\": {\n                \"x\": 0.333,\n                \"y\": 0\n              },\n              \"t\": 19.288,\n              \"s\": [\n                123.415,\n                215.446,\n                0\n              ],\n              \"to\": [\n                15.653,\n                -0.107,\n                0\n              ],\n              \"ti\": [\n                0,\n                -5.789,\n                0\n              ]\n            },\n            {\n              \"i\": {\n                \"x\": 0.667,\n                \"y\": 1\n              },\n              \"o\": {\n                \"x\": 0.167,\n                \"y\": 0.167\n              },\n              \"t\": 24.562,\n              \"s\": [\n                149.463,\n                268.927,\n                0\n              ],\n              \"to\": [\n                -0.434,\n                -6.802,\n                0\n              ],\n              \"ti\": [\n                -7.767,\n                -0.249,\n                0\n              ]\n            },\n            {\n              \"i\": {\n                \"x\": 0.833,\n                \"y\": 0.833\n              },\n              \"o\": {\n                \"x\": 0.333,\n                \"y\": 0\n              },\n              \"t\": 28.932,\n              \"s\": [\n                163.139,\n                247.076,\n                0\n              ],\n              \"to\": [\n                8.023,\n                0.258,\n                0\n              ],\n              \"ti\": [\n                0,\n                -2.894,\n                0\n              ]\n            },\n            {\n              \"i\": {\n                \"x\": 0.667,\n                \"y\": 1\n              },\n              \"o\": {\n                \"x\": 0.167,\n                \"y\": 0.167\n              },\n              \"t\": 34.442,\n              \"s\": [\n                174.644,\n                268.927,\n                0\n              ],\n              \"to\": [\n                5.644,\n                -0.579,\n                0\n              ],\n              \"ti\": [\n                -5.246,\n                -0.072,\n                0\n              ]\n            },\n            {\n              \"t\": 41,\n              \"s\": [\n                191.141,\n                268.927,\n                0\n              ]\n            }\n          ],\n          \"ix\": 2,\n          \"l\": 2\n        },\n        \"a\": {\n          \"a\": 0,\n          \"k\": [\n            4,\n            3.5,\n            0\n          ],\n          \"ix\": 1,\n          \"l\": 2\n        },\n        \"s\": {\n          \"a\": 0,\n          \"k\": [\n            2778.533,\n            2778.533,\n            100\n          ],\n          \"ix\": 6,\n          \"l\": 2\n        }\n      },\n      \"ao\": 0,\n      \"shapes\": [\n        {\n          \"ty\": \"gr\",\n          \"it\": [\n            {\n              \"ind\": 0,\n              \"ty\": \"sh\",\n              \"ix\": 1,\n              \"ks\": {\n                \"a\": 0,\n                \"k\": {\n                  \"i\": [\n                    [\n                      -3.932,\n                      0\n                    ],\n                    [\n                      0,\n                      -3.932\n                    ],\n                    [\n                      3.932,\n                      0\n                    ],\n                    [\n                      0,\n                      3.932\n                    ]\n                  ],\n                  \"o\": [\n                    [\n                      3.932,\n                      0\n                    ],\n                    [\n                      0,\n                      3.932\n                    ],\n                    [\n                      -3.932,\n                      0\n                    ],\n                    [\n                      0,\n                      -3.932\n                    ]\n                  ],\n                  \"v\": [\n                    [\n                      4,\n                      -3.619\n                    ],\n                    [\n                      11.119,\n                      3.5\n                    ],\n                    [\n                      4,\n                      10.619\n                    ],\n                    [\n                      -3.119,\n                      3.5\n                    ]\n                  ],\n                  \"c\": true\n                },\n                \"ix\": 2\n              },\n              \"nm\": \"Path 1\",\n              \"mn\": \"ADBE Vector Shape - Group\",\n              \"hd\": false\n            },\n            {\n              \"ty\": \"st\",\n              \"c\": {\n                \"a\": 0,\n                \"k\": [\n                  0.031372550875,\n                  0.658823549747,\n                  0.541176497936,\n                  1\n                ],\n                \"ix\": 3,\n                \"x\": \"var $bm_rt;\\n$bm_rt = thisComp.layer('Color  & Stroke Change').effect('Secondary')('Color');\"\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 100,\n                \"ix\": 4\n              },\n              \"w\": {\n                \"a\": 0,\n                \"k\": 1.5,\n                \"ix\": 5,\n                \"x\": \"var $bm_rt;\\n$bm_rt = $bm_mul(1.5 / 100, thisComp.layer('Color  & Stroke Change').effect('Stroke')('Slider'));\"\n              },\n              \"lc\": 1,\n              \"lj\": 1,\n              \"ml\": 4,\n              \"bm\": 0,\n              \"nm\": \"Stroke 1\",\n              \"mn\": \"ADBE Vector Graphic - Stroke\",\n              \"hd\": false\n            },\n            {\n              \"ty\": \"tr\",\n              \"p\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 2\n              },\n              \"a\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 1\n              },\n              \"s\": {\n                \"a\": 0,\n                \"k\": [\n                  100,\n                  100\n                ],\n                \"ix\": 3\n              },\n              \"r\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 6\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 100,\n                \"ix\": 7\n              },\n              \"sk\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 4\n              },\n              \"sa\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 5\n              },\n              \"nm\": \"Transform\"\n            }\n          ],\n          \"nm\": \"Oval 2\",\n          \"np\": 2,\n          \"cix\": 2,\n          \"bm\": 0,\n          \"ix\": 1,\n          \"mn\": \"ADBE Vector Group\",\n          \"hd\": false\n        },\n        {\n          \"ty\": \"gr\",\n          \"it\": [\n            {\n              \"ind\": 0,\n              \"ty\": \"sh\",\n              \"ix\": 1,\n              \"ks\": {\n                \"a\": 0,\n                \"k\": {\n                  \"i\": [\n                    [\n                      -5.799,\n                      0\n                    ],\n                    [\n                      0,\n                      -5.799\n                    ],\n                    [\n                      5.799,\n                      0\n                    ],\n                    [\n                      0,\n                      5.799\n                    ]\n                  ],\n                  \"o\": [\n                    [\n                      5.799,\n                      0\n                    ],\n                    [\n                      0,\n                      5.799\n                    ],\n                    [\n                      -5.799,\n                      0\n                    ],\n                    [\n                      0,\n                      -5.799\n                    ]\n                  ],\n                  \"v\": [\n                    [\n                      4,\n                      -7\n                    ],\n                    [\n                      14.5,\n                      3.5\n                    ],\n                    [\n                      4,\n                      14\n                    ],\n                    [\n                      -6.5,\n                      3.5\n                    ]\n                  ],\n                  \"c\": true\n                },\n                \"ix\": 2\n              },\n              \"nm\": \"Path 1\",\n              \"mn\": \"ADBE Vector Shape - Group\",\n              \"hd\": false\n            },\n            {\n              \"ty\": \"st\",\n              \"c\": {\n                \"a\": 0,\n                \"k\": [\n                  0.031372550875,\n                  0.658823549747,\n                  0.541176497936,\n                  1\n                ],\n                \"ix\": 3,\n                \"x\": \"var $bm_rt;\\n$bm_rt = thisComp.layer('Color  & Stroke Change').effect('Primary')('Color');\"\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 100,\n                \"ix\": 4\n              },\n              \"w\": {\n                \"a\": 0,\n                \"k\": 1.5,\n                \"ix\": 5,\n                \"x\": \"var $bm_rt;\\n$bm_rt = $bm_mul(1.5 / 100, thisComp.layer('Color  & Stroke Change').effect('Stroke')('Slider'));\"\n              },\n              \"lc\": 1,\n              \"lj\": 1,\n              \"ml\": 4,\n              \"bm\": 0,\n              \"nm\": \"Stroke 1\",\n              \"mn\": \"ADBE Vector Graphic - Stroke\",\n              \"hd\": false\n            },\n            {\n              \"ty\": \"tr\",\n              \"p\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 2\n              },\n              \"a\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 1\n              },\n              \"s\": {\n                \"a\": 0,\n                \"k\": [\n                  100,\n                  100\n                ],\n                \"ix\": 3\n              },\n              \"r\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 6\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 100,\n                \"ix\": 7\n              },\n              \"sk\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 4\n              },\n              \"sa\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 5\n              },\n              \"nm\": \"Transform\"\n            }\n          ],\n          \"nm\": \"Oval\",\n          \"np\": 2,\n          \"cix\": 2,\n          \"bm\": 0,\n          \"ix\": 2,\n          \"mn\": \"ADBE Vector Group\",\n          \"hd\": false\n        }\n      ],\n      \"ip\": 0,\n      \"op\": 250,\n      \"st\": 0,\n      \"bm\": 0\n    },\n    {\n      \"ddd\": 0,\n      \"ind\": 9,\n      \"ty\": 4,\n      \"nm\": \"Warstwa 6\",\n      \"parent\": 8,\n      \"td\": 1,\n      \"sr\": 1,\n      \"ks\": {\n        \"o\": {\n          \"a\": 0,\n          \"k\": 100,\n          \"ix\": 11\n        },\n        \"r\": {\n          \"a\": 0,\n          \"k\": 0,\n          \"ix\": 10\n        },\n        \"p\": {\n          \"a\": 0,\n          \"k\": [\n            4,\n            3.5,\n            0\n          ],\n          \"ix\": 2,\n          \"l\": 2\n        },\n        \"a\": {\n          \"a\": 0,\n          \"k\": [\n            4,\n            3.5,\n            0\n          ],\n          \"ix\": 1,\n          \"l\": 2\n        },\n        \"s\": {\n          \"a\": 0,\n          \"k\": [\n            100,\n            100,\n            100\n          ],\n          \"ix\": 6,\n          \"l\": 2\n        }\n      },\n      \"ao\": 0,\n      \"shapes\": [\n        {\n          \"ty\": \"gr\",\n          \"it\": [\n            {\n              \"ind\": 0,\n              \"ty\": \"sh\",\n              \"ix\": 1,\n              \"ks\": {\n                \"a\": 0,\n                \"k\": {\n                  \"i\": [\n                    [\n                      -3.932,\n                      0\n                    ],\n                    [\n                      0,\n                      -3.932\n                    ],\n                    [\n                      3.932,\n                      0\n                    ],\n                    [\n                      0,\n                      3.932\n                    ]\n                  ],\n                  \"o\": [\n                    [\n                      3.932,\n                      0\n                    ],\n                    [\n                      0,\n                      3.932\n                    ],\n                    [\n                      -3.932,\n                      0\n                    ],\n                    [\n                      0,\n                      -3.932\n                    ]\n                  ],\n                  \"v\": [\n                    [\n                      4,\n                      -3.619\n                    ],\n                    [\n                      11.119,\n                      3.5\n                    ],\n                    [\n                      4,\n                      10.619\n                    ],\n                    [\n                      -3.119,\n                      3.5\n                    ]\n                  ],\n                  \"c\": true\n                },\n                \"ix\": 2\n              },\n              \"nm\": \"Path 1\",\n              \"mn\": \"ADBE Vector Shape - Group\",\n              \"hd\": false\n            },\n            {\n              \"ty\": \"st\",\n              \"c\": {\n                \"a\": 0,\n                \"k\": [\n                  0.031372550875,\n                  0.658823549747,\n                  0.541176497936,\n                  1\n                ],\n                \"ix\": 3\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 100,\n                \"ix\": 4\n              },\n              \"w\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 5\n              },\n              \"lc\": 1,\n              \"lj\": 1,\n              \"ml\": 4,\n              \"bm\": 0,\n              \"nm\": \"Stroke 1\",\n              \"mn\": \"ADBE Vector Graphic - Stroke\",\n              \"hd\": false\n            },\n            {\n              \"ty\": \"tr\",\n              \"p\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 2\n              },\n              \"a\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 1\n              },\n              \"s\": {\n                \"a\": 0,\n                \"k\": [\n                  100,\n                  100\n                ],\n                \"ix\": 3\n              },\n              \"r\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 6\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 100,\n                \"ix\": 7\n              },\n              \"sk\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 4\n              },\n              \"sa\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 5\n              },\n              \"nm\": \"Transform\"\n            }\n          ],\n          \"nm\": \"Oval 2\",\n          \"np\": 2,\n          \"cix\": 2,\n          \"bm\": 0,\n          \"ix\": 1,\n          \"mn\": \"ADBE Vector Group\",\n          \"hd\": false\n        },\n        {\n          \"ty\": \"gr\",\n          \"it\": [\n            {\n              \"ind\": 0,\n              \"ty\": \"sh\",\n              \"ix\": 1,\n              \"ks\": {\n                \"a\": 0,\n                \"k\": {\n                  \"i\": [\n                    [\n                      -5.799,\n                      0\n                    ],\n                    [\n                      0,\n                      -5.799\n                    ],\n                    [\n                      5.799,\n                      0\n                    ],\n                    [\n                      0,\n                      5.799\n                    ]\n                  ],\n                  \"o\": [\n                    [\n                      5.799,\n                      0\n                    ],\n                    [\n                      0,\n                      5.799\n                    ],\n                    [\n                      -5.799,\n                      0\n                    ],\n                    [\n                      0,\n                      -5.799\n                    ]\n                  ],\n                  \"v\": [\n                    [\n                      4,\n                      -7\n                    ],\n                    [\n                      14.5,\n                      3.5\n                    ],\n                    [\n                      4,\n                      14\n                    ],\n                    [\n                      -6.5,\n                      3.5\n                    ]\n                  ],\n                  \"c\": true\n                },\n                \"ix\": 2\n              },\n              \"nm\": \"Path 1\",\n              \"mn\": \"ADBE Vector Shape - Group\",\n              \"hd\": false\n            },\n            {\n              \"ty\": \"st\",\n              \"c\": {\n                \"a\": 0,\n                \"k\": [\n                  0.031372550875,\n                  0.658823549747,\n                  0.541176497936,\n                  1\n                ],\n                \"ix\": 3\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 100,\n                \"ix\": 4\n              },\n              \"w\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 5\n              },\n              \"lc\": 1,\n              \"lj\": 1,\n              \"ml\": 4,\n              \"bm\": 0,\n              \"nm\": \"Stroke 1\",\n              \"mn\": \"ADBE Vector Graphic - Stroke\",\n              \"hd\": false\n            },\n            {\n              \"ty\": \"tr\",\n              \"p\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 2\n              },\n              \"a\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 1\n              },\n              \"s\": {\n                \"a\": 0,\n                \"k\": [\n                  100,\n                  100\n                ],\n                \"ix\": 3\n              },\n              \"r\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 6\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 100,\n                \"ix\": 7\n              },\n              \"sk\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 4\n              },\n              \"sa\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 5\n              },\n              \"nm\": \"Transform\"\n            }\n          ],\n          \"nm\": \"Oval\",\n          \"np\": 2,\n          \"cix\": 2,\n          \"bm\": 0,\n          \"ix\": 2,\n          \"mn\": \"ADBE Vector Group\",\n          \"hd\": false\n        },\n        {\n          \"ty\": \"fl\",\n          \"c\": {\n            \"a\": 0,\n            \"k\": [\n              0.070588235294,\n              0.074509803922,\n              0.192156877705,\n              1\n            ],\n            \"ix\": 4\n          },\n          \"o\": {\n            \"a\": 0,\n            \"k\": 100,\n            \"ix\": 5\n          },\n          \"r\": 1,\n          \"bm\": 0,\n          \"nm\": \"Fill 1\",\n          \"mn\": \"ADBE Vector Graphic - Fill\",\n          \"hd\": false\n        }\n      ],\n      \"ip\": 0,\n      \"op\": 250,\n      \"st\": 0,\n      \"bm\": 0\n    },\n    {\n      \"ddd\": 0,\n      \"ind\": 10,\n      \"ty\": 0,\n      \"nm\": \"Stuck\",\n      \"parent\": 4,\n      \"tt\": 2,\n      \"refId\": \"comp_0\",\n      \"sr\": 1,\n      \"ks\": {\n        \"o\": {\n          \"a\": 0,\n          \"k\": 100,\n          \"ix\": 11\n        },\n        \"r\": {\n          \"a\": 0,\n          \"k\": 0,\n          \"ix\": 10\n        },\n        \"p\": {\n          \"a\": 0,\n          \"k\": [\n            60,\n            60,\n            0\n          ],\n          \"ix\": 2,\n          \"l\": 2\n        },\n        \"a\": {\n          \"a\": 0,\n          \"k\": [\n            250,\n            250,\n            0\n          ],\n          \"ix\": 1,\n          \"l\": 2\n        },\n        \"s\": {\n          \"a\": 0,\n          \"k\": [\n            100,\n            100,\n            100\n          ],\n          \"ix\": 6,\n          \"l\": 2\n        }\n      },\n      \"ao\": 0,\n      \"w\": 500,\n      \"h\": 500,\n      \"ip\": 0,\n      \"op\": 125,\n      \"st\": 0,\n      \"bm\": 0\n    }\n  ],\n  \"markers\": []\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/LandPage/index.ts",
    "content": "export * from './LandPage'\nexport * from './WalletPage'\nexport * from './HomePage'\nexport { LandBtn } from './style'\n"
  },
  {
    "path": "packages/webapp/src/pages/LandPage/style.tsx",
    "content": "import styled from '@emotion/styled'\nimport { Box, Container, Typography, TypographyProps } from '@mui/material'\nimport { SoursURL, ThemeType } from '@loopring-web/common-resources'\nimport { ContainerProps } from '@mui/material/Container/Container'\nimport { Button } from '@loopring-web/component-lib'\nimport { withTranslation } from 'react-i18next'\n\nexport const ContainerStyle = styled(Box)`\n  .MuiContainer-root {\n    width: fit-content;\n\n    @media only screen and (min-width: 1200px) {\n      min-width: 1200px;\n    }\n    @media only screen and (max-width: 768px) {\n      min-width: 360px;\n    }\n  }\n  --dark: #000000;\n  --dark1000: #31353d;\n  --dark900: #141414;\n  --dark800: #1f1f1f;\n  --dark700: #262626;\n  --dark600: #434343;\n  --dark500: #595959;\n  --dark400: #8c8c8c;\n  --light400: #bfbfbf;\n  --light500: #d9d9d9;\n  --light600: #ebebeb;\n  --light700: #f0f0f0;\n  --light800: #f5f5f5;\n  --light900: #fafafa;\n  --light1000: #ffffff;\n  --light: #ffffff;\n  --color-success: #00bba8;\n  --color-warning: #fba95c;\n  --color-error: #ff5677;\n  /**** config pex ****/\n  --h1: 48px;\n  --h2: 30px;\n  --h3: 24px;\n  --h4: 20px;\n  --h5: 16px;\n  --body: 14px;\n  --body2: 12px;\n  --header-row-height: 44px;\n  --header-height: 64px;\n  --header-submenu-item-height: 52px;\n  --header-submenu-item-width: 250px;\n  ${({ theme }) => {\n    let result = `\n       --img-banner-url: url(\"${SoursURL}landPage/img_home_banner_${theme.mode}@2x.png\");\n      `\n    if (theme.mode === ThemeType.dark) {\n      result += `\n    --color-global-Bg: var(--dark);\n    --color-primary: #446eff;\n    --color-primary-hover: var(--light900);\n    --color-primary-pressed: #2d49b2;\n    --color-disable: #343754;\n    --color-text-primary: var(--light);\n    --color-border: var(--light900);\n    --color-divide: var(--dark800);\n    --color-border-hover: var(--color-primary);\n    --color-text-secondary: var(--light500);\n    --color-text-third: var(--dark400);\n    --color-text-button: var(--light);\n    --color-text-buttonSelect: var(--light);\n    --color-text-disable: var(--light) 45;\n    --color-box: var(--dark1000);\n    --color-logo: var(--light);\n    --color-field:#6B8FEB20;\n        `\n    } else {\n      result += `\n    --color-global-Bg: var(--light);\n    --color-primary: #446eff;\n    --color-primary-hover: var(--light900) 20;\n    --color-primary-pressed: #2d49b2;\n    --color-disable: #343754;\n    --color-text-primary: var(--dark);\n    --color-border: var(--dark900);\n    --color-divide: var(--light500);\n    --color-border-hover: var(--color-primary);\n    --color-text-secondary: var(--dark500);\n    --color-text-third: var(--light400);\n    --color-text-button: var(--light);\n    --color-text-buttonSelect: var(--light);\n    --color-text-disable: var(--light) 45;\n    --color-box: var(--light1000);\n    --color-logo: #446eff;\n    --color-field:#6B8FEB20;\n        `\n    }\n    return result\n  }};\n\n  .MuiButton-root {\n    min-height: 48px;\n    padding: 0 48px;\n    --color-text: var(--color-text-button);\n    box-sizing: border-box;\n    background: var(--color-primary);\n    color: var(--color-text);\n    width: fit-content;\n    display: flex;\n    align-items: center;\n    font-size: var(--h5);\n    & .MuiButton-endIcon {\n      color: inherit;\n    }\n    &:hover {\n      color: inherit;\n      background: var(--color-primary-pressed);\n      .MuiButton-endIcon {\n        color: inherit;\n      }\n      svg {\n        color: inherit;\n      }\n    }\n  }\n  .product {\n    position: relative;\n\n    .MuiButton-root {\n      text-align: left;\n    }\n    .MuiTabs-scrollButtons {\n      position: absolute;\n      height: 100%;\n      z-index: 99;\n      svg {\n        height: 32px;\n        width: 32px;\n        background: #4a505c;\n        color: var(--color-text-button);\n        outline: 2px solid #4a505c;\n        border-radius: 50%;\n      }\n    }\n    .MuiTab-root {\n      display: flex;\n      align-items: stretch;\n    }\n\n    .MuiTab-root:first-of-type {\n      padding-left: 0;\n    }\n    .MuiTabs-scrollButtons:first-of-type {\n      left: 0;\n    }\n    .MuiTabs-scrollButtons:last-child {\n      right: 0;\n    }\n  }\n  .MuiButton-root.walletConnectL2Btn {\n    width: 100%;\n  }\n\n  .MuiButton-root.menuItem {\n    display: flex;\n    justify-content: flex-start;\n    padding-left: 2rem;\n    height: 80px;\n    min-width: 248px;\n    @media only screen and (max-width: 768px) {\n      padding-left: 0rem;\n    }\n    width: 100%;\n    fontsize: 1.4rem;\n    padding-right: ${({ theme }) => theme.unit * 3}px;\n    .MuiButton-startIcon svg {\n      fill: var(--color-primary);\n    }\n    & {\n      background: none;\n      :hover {\n        background: none;\n        outline: 1px solid var(--color-border-hover);\n      }\n    }\n  }\n  .box1,\n  .box5,\n  .box6,\n  .box3 {\n    margin-bottom: 40px;\n    > div {\n      background: var(--color-box);\n      border-radius: 12px;\n      padding: 48px;\n    }\n  }\n  .box1,\n  .box5,\n  .box3 {\n    h4 {\n      margin-bottom: ${({ theme }) => theme.unit * 3}px;\n    }\n  }\n\n  .box6 {\n    > div {\n      flex: 1;\n      justify-content: space-between;\n    }\n  }\n  .box1 {\n    > div {\n      flex: 1;\n      justify-content: space-between;\n    }\n  }\n  .box4 {\n    margin-bottom: 80px;\n    & .MuiGrid-grid-md-8 {\n      flex-basis: auto;\n      width: calc(66% - 48px);\n      max-width: inherit;\n      position: relative;\n      overflow: hidden;\n      svg {\n        position: absolute;\n        right: 20px;\n        bottom: 20px;\n      }\n    }\n    & .MuiGrid-grid-md-2 {\n      flex-basis: auto;\n      width: 22%;\n      max-width: inherit;\n      position: relative;\n      overflow: hidden;\n      svg {\n        position: absolute;\n        right: -72px;\n        bottom: 20px;\n      }\n    }\n\n    > .MuiGrid-root {\n      transition: all 0.5s ease;\n      svg {\n        transition: all 0.5s ease;\n      }\n    }\n    .boxDetail {\n      overflow: hidden;\n      border-radius: ${({ theme }) => theme.unit}px;\n    }\n\n    p {\n      display: none;\n      opacity: 0;\n    }\n    & .MuiGrid-grid-md-12 {\n      p {\n        display: block;\n        opacity: 1;\n      }\n    }\n    svg {\n      opacity: 0.5;\n      .fill-light {\n        fill: var(--color-text-primary);\n      }\n      .fill-primary {\n        fill: var(--color-primary);\n      }\n    }\n\n    .selected,\n    > .MuiGrid-root:hover {\n      p {\n        display: block;\n        opacity: 1;\n      }\n      .boxDetail {\n        border: 1px solid var(--color-border-hover);\n      }\n\n      svg {\n        align-self: flex-end;\n        opacity: 1;\n      }\n    }\n  }\n\n  .box2 {\n    margin-bottom: 80px;\n    h4 {\n      margin-bottom: ${({ theme }) => theme.unit * 3}px;\n    }\n\n    .MuiButton-root {\n      margin-top: ${({ theme }) => theme.unit * 3}px;\n    }\n    > .MuiGrid-root div {\n      border-radius: ${({ theme }) => theme.unit}px;\n    }\n    > .MuiGrid-root:first-of-type div {\n      .MuiButton-root {\n        background: white;\n        color: var(--color-primary);\n        &:hover {\n          svg {\n            fill: var(--color-primary);\n          }\n          opacity: 0.6;\n        }\n      }\n      .MuiTypography-root {\n        color: var(--color-text-button);\n      }\n      background: linear-gradient(260.11deg, #547fe7 18.38%, #2e60e3 85.98%);\n      /* Rectangle 41978 */\n    }\n    > .MuiGrid-root:last-child div {\n      background: var(--light1000);\n      .MuiTypography-root {\n        color: var(--dark);\n      }\n    }\n  }\n  body {\n    background: var(--main-page-bg);\n  }\n\n  .MuiTab-root {\n    width: 30%;\n  }\n\n  @media only screen and (max-width: 1024px) {\n    .box1 {\n      .MuiBox-root {\n        flex-direction: column;\n        > div {\n          margin-bottom: 24px;\n        }\n      }\n    }\n    .box4 {\n      p {\n        display: block;\n      }\n    }\n\n    .box2 {\n      padding: 0 20px;\n      flex-direction: column;\n      align-items: center;\n      margin-bottom: 24px;\n      > .flexBox {\n        &:first-of-type {\n          margin-left: 0px;\n        }\n        flex-direction: column;\n        margin-left: 0px;\n        > div {\n          margin-bottom: 24px;\n        }\n        margin-bottom: 24px;\n      }\n    }\n    .box2 {\n      padding: 0;\n    }\n\n    #mobileBg {\n      width: 100%;\n    }\n\n    #labelEthereumUnleashed {\n      width: 100%;\n      font-size: 36px;\n      margin-top: 32px;\n    }\n  }\n\n  @media only screen and (max-width: 768px) {\n    header {\n      .Ul-root {\n        position: absolute;\n        display: flex;\n        top: 0;\n        flex-direction: column;\n        margin-left: 56px;\n        li {\n          height: 48px;\n          line-height: 48px;\n        }\n      }\n    }\n  }\n` as typeof Box\nexport const TitleTypography = styled(Typography)<TypographyProps & { isMobile?: boolean }>`\n  text-transform: uppercase;\n  font-size: ${({ isMobile }) => (isMobile ? '2rem' : '4rem')};\n  font-weight: 700;\n  white-space: pre-line;\n  line-height: 5.6rem;\n  position: relative;\n  display: flex;\n  align-items: flex-start;\n  flex-direction: column;\n  &.right {\n    align-items: flex-end;\n  }\n  justify-content: space-between;\n  align-self: flex-start;\n  height: ${({ isMobile }) => (isMobile ? 'auto' : 'calc(80px + 24px)')};\n  width: 100%;\n  &:before {\n    margin-top: 24px;\n    content: '';\n\n    height: 6px;\n    width: 96px;\n    display: block;\n    background: var(--color-primary);\n  }\n` as (props: TypographyProps & { isMobile?: boolean }) => JSX.Element\n\nexport const ContainerStyled = styled(Container)<ContainerProps & { isMobile?: boolean }>`\n  padding: 0 !important;\n` as (props: ContainerProps & { isMobile?: boolean }) => JSX.Element\n\nconst ButtonStyled = styled(Button)`\n  background: linear-gradient(94.92deg, #4169ff 0.91%, #a016c2 103.55%);\n  padding-left: ${({ theme }) => 3 * theme.unit}px;\n  padding-right: ${({ theme }) => 3 * theme.unit}px;\n`\nexport const LandBtn = withTranslation(['landPage'])(({ t }) => {\n  return (\n    <ButtonStyled size={'small'} variant={'contained'} href={'/#/?goProd'}>\n      {t('labelLaunchApp')}\n    </ButtonStyled>\n  )\n})\n\nexport const CardBox = styled(Box)`\n  display: flex;\n  justify-content: center;\n  background: var(--color-box);\n  border-radius: ${({ theme }) => theme.unit * 2}px;\n  cursor: pointer;\n  box-sizing: border-box;\n  &.hasHover {\n    p {\n      text-transform: initial;\n    }\n  }\n  border: 1px solid var(--opacity);\n  box-shadow: 0 0 0.5px 0.5px var(--color-divide);\n  &.hasHover:hover {\n    border: 1px solid var(--color-border-hover);\n    box-shadow: none;\n  }\n` as typeof Box\n"
  },
  {
    "path": "packages/webapp/src/pages/Layer2Page/ContactPanel/delete.tsx",
    "content": "import React from 'react'\nimport {\n  Box,\n  Button,\n  Dialog,\n  DialogActions,\n  DialogContent,\n  DialogTitle,\n  IconButton,\n  Typography,\n} from '@mui/material'\nimport { CloseIcon, LoadingIcon, Contact } from '@loopring-web/common-resources'\nimport { TextField } from '@loopring-web/component-lib'\nimport { useTheme } from '@emotion/react'\nimport { useTranslation } from 'react-i18next'\n\ninterface DeleteDialogProps {\n  deleteInfo: {\n    open: boolean\n    selected: Contact | undefined\n  }\n  onCloseDelete: () => void\n  submitDeleteContact: (address: string, name: string) => void\n  loading: boolean\n}\n\nexport const Delete: React.FC<DeleteDialogProps> = (props) => {\n  const { deleteInfo, onCloseDelete, submitDeleteContact, loading } = props\n\n  const theme = useTheme()\n  const { t } = useTranslation()\n\n  return (\n    <div>\n      <Dialog\n        open={deleteInfo.open}\n        onClose={() => {\n          onCloseDelete()\n        }}\n      >\n        <DialogTitle>\n          <Typography variant={'h3'} textAlign={'center'}>\n            {t('labelContactsDeleteContact')}\n          </Typography>\n          <IconButton\n            size={'medium'}\n            sx={{\n              position: 'absolute',\n              right: 8,\n              top: 8,\n            }}\n            color={'inherit'}\n            onClick={() => {\n              onCloseDelete()\n            }}\n          >\n            <CloseIcon />\n          </IconButton>\n        </DialogTitle>\n        <DialogContent style={{ width: 'var(--modal-width)' }}>\n          <Box marginBottom={12} marginTop={6}>\n            <TextField\n              label={t('labelDeleteContactInfo')}\n              style={{\n                backgroundColor: 'var(--box-card-decorate)',\n              }}\n              color={'primary'}\n              InputProps={{\n                style: {\n                  background: 'var(--field-opacity)',\n                  height: `${theme.unit * 6}px`,\n                },\n              }}\n              fullWidth\n              value={`${deleteInfo.selected?.name}\\/${deleteInfo.selected?.address}`}\n            />\n          </Box>\n        </DialogContent>\n        <DialogActions>\n          <Box width={'100%'} flexDirection={'column'} display={'flex'}>\n            <Button\n              variant='contained'\n              onClick={() => {\n                submitDeleteContact!(deleteInfo.selected!.address, deleteInfo.selected!.name)\n              }}\n              fullWidth\n            >\n              {loading ? <LoadingIcon></LoadingIcon> : t('labelContactsDeleteContactBtn')}\n            </Button>\n            <Box></Box>\n            <Button\n              variant={'outlined'}\n              style={{\n                border: 'none',\n                marginTop: `${theme.unit}px`,\n              }}\n              color={'info'}\n              onClick={() => {\n                onCloseDelete()\n              }}\n            >\n              {t('labelCancel')}\n            </Button>\n          </Box>\n        </DialogActions>\n      </Dialog>\n    </div>\n  )\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/Layer2Page/ContactPanel/history.tsx",
    "content": "import React from 'react'\nimport { Box, Divider } from '@mui/material'\nimport {\n  Button,\n  MaxWidthContainer,\n  Toast,\n  ToastType,\n  TransactionTable,\n} from '@loopring-web/component-lib'\nimport { useContractRecord, useAccount, useSystem, useToast, useTokenMap } from '@loopring-web/core'\nimport { BackIcon, RowConfig, TOAST_TIME } from '@loopring-web/common-resources'\nimport { useHistory } from 'react-router-dom'\nimport { WithTranslation, withTranslation } from 'react-i18next'\n\nexport const ContactTransactionsPage = withTranslation('common')(\n  (rest: WithTranslation<'common'>) => {\n    const history = useHistory()\n\n    const [pageSize, setPageSize] = React.useState(0)\n\n    const { toastOpen, setToastOpen, closeToast } = useToast()\n    const { totalCoinMap } = useTokenMap()\n    const { etherscanBaseUrl } = useSystem()\n\n    const {\n      account: { accAddress, accountId },\n    } = useAccount()\n\n    const container = React.useRef<HTMLDivElement>(null)\n\n    React.useEffect(() => {\n      let height = container?.current?.offsetHeight\n      if (height) {\n        // const pageSize = Math.floor((height - 120) / RowConfig.rowHeight) - 3;\n        setPageSize(Math.floor((height - 120) / RowConfig.rowHeight) - 3)\n        // handleTabChange(currentTab, pageSize);\n      }\n    }, [container?.current?.offsetHeight])\n    const {\n      txs: txTableData,\n      txsTotal,\n      showLoading: showTxsLoading,\n      getUserTxnList,\n    } = useContractRecord(setToastOpen)\n\n    return (\n      <Box flex={1} display={'flex'} flexDirection={'column'}>\n        <MaxWidthContainer\n          sx={{ flexDirection: 'row' }}\n          background={'var(--color-global-bg)'}\n          display={'flex'}\n          justifyContent={'space-between'}\n          padding={2}\n        >\n          <Button\n            startIcon={<BackIcon fontSize={'small'} />}\n            variant={'text'}\n            size={'medium'}\n            sx={{ color: 'var(--color-text-secondary)' }}\n            color={'inherit'}\n            onClick={history.goBack}\n          >\n            {rest.t('labelContacts')}\n          </Button>\n        </MaxWidthContainer>\n        <Divider />\n        <MaxWidthContainer\n          background={'var(--color-pop-bg)'}\n          display={'flex'}\n          justifyContent={'space-between'}\n          paddingY={2}\n          flexDirection={'column'}\n        >\n          <Toast\n            alertText={toastOpen?.content ?? ''}\n            severity={toastOpen?.type ?? ToastType.success}\n            open={toastOpen?.open ?? false}\n            autoHideDuration={TOAST_TIME}\n            onClose={closeToast}\n          />\n          <Box\n            className='tableWrapper table-divide-short'\n            display={'flex'}\n            flex={1}\n            overflow={'scroll'}\n            ref={container}\n          >\n            <TransactionTable\n              {...{\n                etherscanBaseUrl,\n                rawData: txTableData,\n                pagination: {\n                  pageSize: pageSize,\n                  total: txsTotal,\n                },\n                filterTokens: totalCoinMap ? (Reflect.ownKeys(totalCoinMap) as string[]) : [],\n                showFilter: true,\n                showloading: showTxsLoading,\n                getTxnList: getUserTxnList,\n                accAddress,\n                accountId,\n                ...rest,\n              }}\n            />\n          </Box>\n        </MaxWidthContainer>\n      </Box>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/webapp/src/pages/Layer2Page/ContactPanel/index.tsx",
    "content": "import { Box, Divider, Grid, IconButton, Popover, Typography } from '@mui/material'\nimport {\n  AddressTypeTag,\n  InputSearch,\n  TablePagination,\n  Toast,\n  ToastType,\n  useSettings,\n  InitialNameAvatar,\n  MaxWidthContainer,\n  Button,\n  MenuItem,\n} from '@loopring-web/component-lib'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nimport {\n  CopyIcon,\n  EditIcon,\n  getShortAddr,\n  MoreIcon,\n  TOAST_TIME,\n  ContactType,\n  Contact,\n  RouterPath,\n  myLog,\n} from '@loopring-web/common-resources'\nimport { Delete } from './delete'\nimport { useHistory } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport React from 'react'\nimport { useRouteMatch } from 'react-router-dom'\nimport { ContactTransactionsPage } from './history'\nimport { bindMenu, bindTrigger, usePopupState } from 'material-ui-popup-state/hooks'\nimport styled from '@emotion/styled'\nimport { useContact } from '@loopring-web/core'\n\nconst StyledPaper = styled(Box)`\n  width: 100%;\n  height: 100%;\n  background: var(--color-box);\n  border-radius: ${({ theme }) => theme.unit}px;\n`\n\nexport enum ContactL3Router {\n  list = 'list',\n  transactions = 'transactions',\n}\n\nexport const ContactPage = () => {\n  let match: any = useRouteMatch('/layer2/contact/:item')\n  const view = React.useMemo(() => {\n    return match?.params?.item == 'transactions' ? <ContactTransactionsPage /> : <ContractPanel />\n  }, [match?.params?.item])\n  return <>{view}</>\n}\n\nconst ActionMemo = React.memo(\n  <N = ContactType,>({\n    data,\n    onClickSend,\n    onClickDelete,\n    index,\n    btnLoading,\n  }: {\n    data: ContactType\n    index: number\n    onClickSend: (data: Contact, index: number) => void\n    onClickDelete: (contactAddress: string, contactName: string) => void\n    btnLoading: { index: number; loading: boolean }\n  }) => {\n    const history = useHistory()\n    const { isMobile } = useSettings()\n    const { t } = useTranslation('common')\n    const popupState = usePopupState({\n      variant: 'popover',\n      popupId: 'contact-action',\n    })\n    const bindContent = bindMenu(popupState)\n    const bindAction = bindTrigger(popupState)\n    myLog('btnLoading', btnLoading)\n    return (\n      <Grid item marginTop={1}>\n        {isMobile ? (\n          <>\n            <IconButton size={'large'} edge={'end'} {...{ ...bindAction }}>\n              <MoreIcon cursor={'pointer'} />\n            </IconButton>\n            <Popover\n              {...bindContent}\n              anchorReference='anchorEl'\n              anchorOrigin={{\n                vertical: 'bottom',\n                horizontal: 'right',\n              }}\n              transformOrigin={{\n                vertical: 'top',\n                horizontal: 'right',\n              }}\n            >\n              <Box borderRadius={'inherit'} minWidth={110}>\n                <MenuItem onClick={() => onClickSend(data, index)}>\n                  {t('labelContactsSend')}\n                </MenuItem>\n                <MenuItem\n                  onClick={() => {\n                    history.push(\n                      '/layer2/contact/transactions?contactAddress=' + data.contactAddress,\n                    )\n                  }}\n                >\n                  {t('labelContactsTransactions')}\n                </MenuItem>\n                <MenuItem\n                  onClick={() => {\n                    onClickDelete(data.contactAddress, data.contactName)\n                  }}\n                >\n                  {t('labelContactsDeleteContactBtn')}\n                </MenuItem>\n              </Box>\n            </Popover>\n          </>\n        ) : (\n          <>\n            <Button\n              onClick={() => onClickSend(data, index)}\n              variant={'contained'}\n              size={'small'}\n              sx={{ marginLeft: 1 }}\n              disabled={btnLoading.index == index && btnLoading.loading}\n              loading={btnLoading.index == index && btnLoading.loading ? 'true' : 'false'}\n            >\n              {t('labelContactsSend')}\n            </Button>\n            <Button\n              variant={'outlined'}\n              size={'medium'}\n              onClick={() => {\n                history.push(\n                  `${RouterPath.layer2}/contact/transactions?contactAddress=${data.contactAddress}`,\n                )\n              }}\n              sx={{ marginLeft: 1 }}\n            >\n              {t('labelContactsTransactions')}\n            </Button>\n            <Button\n              variant={'outlined'}\n              size={'medium'}\n              onClick={() => {\n                onClickDelete(data.contactAddress, data.contactName)\n              }}\n              sx={{ marginLeft: 1 }}\n            >\n              {t('labelContactsDeleteContactBtn')}\n            </Button>\n          </>\n        )}\n      </Grid>\n    )\n  },\n)\nexport const ContractPanel = ({ viewHeightRatio = 0.85, viewHeightOffset = 130 }) => {\n  const {\n    contacts,\n    searchValue,\n    onChangeSearch,\n    onClickDelete,\n    setShowEditContact,\n    toastInfo,\n    deleteInfo,\n    onCloseDelete,\n    submitDeleteContact,\n    deleteLoading,\n    onClickSend,\n    btnLoading,\n    closeToast,\n    setToast,\n    pagination,\n    onPageChange,\n    showPagination,\n  } = useContact({\n    viewHeightRatio,\n    viewHeightOffset,\n  })\n  const { t } = useTranslation()\n\n  const noContact = (\n    <Box height={'80vh'} display={'flex'} justifyContent={'center'} alignItems={'center'}>\n      <Typography component={'span'} variant={'body1'} color={'var(--color-text-third)'}>\n        {t('labelContactsNoContact')}\n      </Typography>\n    </Box>\n  )\n\n  const { isMobile } = useSettings()\n\n  return (\n    <>\n      <Toast\n        alertText={toastInfo.content ?? ''}\n        severity={toastInfo?.type}\n        open={toastInfo.open}\n        autoHideDuration={TOAST_TIME}\n        onClose={closeToast}\n        // onClose={closeToastL}\n      />\n      <Delete\n        deleteInfo={deleteInfo}\n        onCloseDelete={onCloseDelete}\n        submitDeleteContact={submitDeleteContact}\n        loading={deleteLoading}\n      />\n      <MaxWidthContainer\n        sx={{ flexDirection: 'row' }}\n        background={'var(--color-global-bg)'}\n        display={'flex'}\n        justifyContent={'space-between'}\n      >\n        <Typography\n          component={'h3'}\n          variant={'h5'}\n          paddingX={5 / 2}\n          display={'inline-flex'}\n          alignItems={'center'}\n          paddingY={2}\n        >\n          {t('labelContacts')}\n        </Typography>\n        <Box display={'flex'} alignItems={'center'}>\n          <InputSearch\n            value={searchValue}\n            onChange={(e) => {\n              onChangeSearch(e as unknown as string)\n            }}\n          />\n          <Box marginLeft={2}>\n            <Button\n              variant={'contained'}\n              size={'small'}\n              onClick={() => {\n                setShowEditContact({ isShow: true })\n                // setSelectAddress(undefined)\n                // setAddOpen(true)\n              }}\n            >\n              {t('labelContactsAddContactBtn')}\n            </Button>\n          </Box>\n        </Box>\n      </MaxWidthContainer>\n      <Divider />\n      <MaxWidthContainer\n        background={'var(--color-pop-bg)'}\n        display={'flex'}\n        justifyContent={'space-between'}\n        paddingY={2}\n        flexDirection={'column'}\n      >\n        <StyledPaper\n          className={'MuiPaper-elevation2'}\n          margin={0}\n          marginBottom={2}\n          paddingX={2}\n          paddingY={2}\n        >\n          <Box className='table-divide'>\n            {!contacts || contacts.length === 0 ? (\n              noContact\n            ) : (\n              <>\n                <Box\n                  height={`calc(${viewHeightRatio * 100}vh - ${viewHeightOffset}px)`}\n                  overflow={'scroll'}\n                >\n                  {contacts &&\n                    contacts.map((data, index) => {\n                      return (\n                        <Box\n                          key={data.contactAddress}\n                          paddingY={2}\n                          display={data.addressType === sdk.AddressType.OFFICIAL ? 'none' : 'flex'}\n                          justifyContent={'space-between'}\n                        >\n                          <Box display={'flex'}>\n                            <InitialNameAvatar name={data.contactName} />\n                            <Typography\n                              component={'p'}\n                              marginLeft={1}\n                              display={'flex'}\n                              flexDirection={'column'}\n                            >\n                              <Typography\n                                display={'inline-flex'}\n                                alignItems={'center'}\n                                component={'span'}\n                                paddingRight={1}\n                              >\n                                <Typography\n                                  display={'inline-flex'}\n                                  paddingRight={1}\n                                  component={'span'}\n                                >\n                                  {data.contactName}\n                                </Typography>\n                                <AddressTypeTag addressType={data.addressType} />\n                                <EditIcon\n                                  sx={{\n                                    paddingLeft: 1,\n                                  }}\n                                  fontSize={'large'}\n                                  onClick={() => {\n                                    setShowEditContact({\n                                      isShow: true,\n                                      info: {\n                                        ...data,\n                                      },\n                                    })\n                                  }}\n                                />\n                              </Typography>\n                              <Typography component={'span'} title={data.contactAddress}>\n                                {(data?.ens ? `${data?.ens} / ` : '') +\n                                  (isMobile\n                                    ? getShortAddr(data.contactAddress ?? '')\n                                    : data.contactAddress)}\n                                <IconButton\n                                  onClick={() => {\n                                    navigator.clipboard.writeText(data.contactAddress)\n                                    setToast({\n                                      open: true,\n                                      type: ToastType.success,\n                                      content: t('labelContactsCopySuccess'),\n                                    })\n                                  }}\n                                >\n                                  <CopyIcon />\n                                </IconButton>\n                              </Typography>\n                            </Typography>\n                          </Box>\n                          <Box display={'flex'}>\n                            <ActionMemo\n                              data={data}\n                              btnLoading={btnLoading}\n                              index={index}\n                              onClickSend={onClickSend}\n                              onClickDelete={onClickDelete}\n                            />\n                          </Box>\n                        </Box>\n                      )\n                    })}\n                </Box>\n                {showPagination && pagination && (\n                  <TablePagination\n                    page={pagination.page}\n                    pageSize={pagination.pageSize}\n                    total={pagination.total}\n                    onPageChange={onPageChange}\n                  />\n                )}\n              </>\n            )}\n          </Box>\n        </StyledPaper>\n      </MaxWidthContainer>\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/Layer2Page/ForcewithdrawPanel/index.tsx",
    "content": "import styled from '@emotion/styled'\nimport { Box, Divider } from '@mui/material'\nimport React from 'react'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport {\n  Button,\n  ForceWithdrawPanel,\n  TransactionTradeViews,\n  useSettings,\n  MaxWidthContainer,\n} from '@loopring-web/component-lib'\nimport { useForceWithdraw } from '@loopring-web/core'\nimport { useTheme } from '@emotion/react'\nimport { useHistory } from 'react-router-dom'\nimport { BackIcon, RecordTabIndex, RouterPath } from '@loopring-web/common-resources'\n\nconst StylePaper = styled(Box)`\n  background: var(--color-box);\n  border-radius: ${({ theme }) => theme.unit}px;\n\n  .content {\n    width: 420px;\n  }\n\n  &.isMobile {\n    .content {\n      flex: 1;\n      width: var(--swap-box-width);\n    }\n  }\n`\n\nexport const ForcewithdrawPanel = withTranslation(['common', 'layout'])(\n  ({ t }: WithTranslation) => {\n    const { isMobile } = useSettings()\n    const history = useHistory()\n    const { forceWithdrawProps } = useForceWithdraw()\n    const theme = useTheme()\n    const extendsProps = isMobile ? { _width: 420 } : { _width: 'auto' }\n    return (\n      <>\n        <MaxWidthContainer\n          background={'var(--color-global-bg)'}\n          display={'flex'}\n          justifyContent={'space-between'}\n          flexDirection={'row'}\n          paddingY={2}\n        >\n          <Button\n            startIcon={<BackIcon fontSize={'small'} />}\n            variant={'text'}\n            size={'medium'}\n            sx={{ color: 'var(--color-text-primary)' }}\n            color={'inherit'}\n            onClick={history.goBack}\n          >\n            {t('labelForceWithdrawTitle')}\n          </Button>\n          <Button\n            variant={'text'}\n            sx={{ color: 'var(--color-text-primary)' }}\n            color={'inherit'}\n            endIcon={<BackIcon fontSize={'small'} sx={{ transform: 'rotate(180deg)' }} />}\n            onClick={() =>\n              history.push(\n                `${RouterPath.l2records}/${RecordTabIndex.Transactions}?types=${TransactionTradeViews.forceWithdraw}`,\n              )\n            }\n          >\n            {t('labelTransactionsLink')}\n          </Button>\n        </MaxWidthContainer>\n        <Divider />\n        <MaxWidthContainer\n          maxWidth='lg'\n          style={{\n            display: 'flex',\n            flexDirection: 'column',\n            flex: 1,\n          }}\n        >\n          <Box flex={1} display={'flex'} flexDirection={'column'}>\n            <Box marginBottom={2}></Box>\n            <StylePaper\n              flex={1}\n              display={'flex'}\n              alignItems={'center'}\n              justifyContent={'center'}\n              className={isMobile ? 'isMobile' : 'MuiPaper-elevation2'}\n              marginBottom={2}\n              position={'relative'}\n            >\n              <Box\n                display={'flex'}\n                alignItems={'center'}\n                justifyContent={'center'}\n                className={'content'}\n              >\n                <ForceWithdrawPanel {...{ ...forceWithdrawProps, ...extendsProps }} />\n              </Box>\n            </StylePaper>\n          </Box>\n        </MaxWidthContainer>\n      </>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/webapp/src/pages/Layer2Page/Notification/hook.ts",
    "content": "import { LoopringAPI, useAccount, useNotificationFunc, useNotify } from '@loopring-web/core'\nimport React from 'react'\nimport { MapChainId, SDK_ERROR_MAP_TO_UI } from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { ToastType, useSettings } from '@loopring-web/component-lib'\nimport { useTranslation } from 'react-i18next'\n\nexport const useNotification = <R extends sdk.UserNotification>({\n  setToastOpen,\n}: {\n  setToastOpen: (state: any) => void\n  page: number\n  pageSize: number\n}) => {\n  const { t } = useTranslation()\n  const { myNotifyMap, getUserNotify } = useNotify()\n  const [rawData, setRawData] = React.useState<R[]>([])\n  const [total, setTotal] = React.useState<number>(0)\n  const [showLoading, setShowLoading] = React.useState(false)\n  const { account } = useAccount()\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const networkWallet: sdk.NetworkWallet = [\n    sdk.NetworkWallet.ETHEREUM,\n    sdk.NetworkWallet.GOERLI,\n    sdk.NetworkWallet.SEPOLIA,\n  ].includes(network as sdk.NetworkWallet)\n    ? sdk.NetworkWallet.ETHEREUM\n    : sdk.NetworkWallet[network]\n\n  const { onReadClick, onReadAllClick, onClearAllClick } = useNotificationFunc({ setToastOpen })\n  const getNotification = React.useCallback(\n    async ({ offset = 0, limit = 20, filter }: any) => {\n      setShowLoading(true)\n      try {\n        if (account.accAddress && LoopringAPI.userAPI) {\n          const response = await LoopringAPI.userAPI?.getNotificationAll(\n            {\n              accountId: account.accountId,\n              offset,\n              limit,\n              network: networkWallet,\n              notRead: filter?.notRead ?? false,\n            },\n            account.apiKey,\n          )\n          if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n            throw response\n          } else {\n            const { totalNum, notifications } = response\n            if (!filter?.notRead && myNotifyMap.total! == totalNum) {\n              getUserNotify()\n            }\n            setTotal(totalNum)\n            setRawData(notifications as R[])\n          }\n        }\n      } catch (error) {\n        let errorItem\n        if (typeof (error as sdk.RESULT_INFO)?.code === 'number') {\n          errorItem = SDK_ERROR_MAP_TO_UI[(error as sdk.RESULT_INFO)?.code ?? 700001]\n        } else {\n          errorItem = SDK_ERROR_MAP_TO_UI[700012]\n        }\n        setToastOpen({\n          open: true,\n          type: ToastType.error,\n          content: 'error : ' + errorItem ? t(errorItem.messageKey) : (error as any)?.message,\n        })\n      }\n      setShowLoading(false)\n    },\n    [account.accAddress],\n  )\n  return {\n    showLoading,\n    getNotification,\n    rawData,\n    total,\n    unReads: myNotifyMap.unReads,\n    onReadClick: (index: number, item: R) => {\n      setShowLoading(true)\n      onReadClick(index, item).finally(() => {\n        rawData[index].read = true\n        setShowLoading(false)\n      })\n    },\n    onReadAllClick: async () => {\n      setShowLoading(true)\n      await onReadAllClick()\n      setShowLoading(false)\n    },\n    onClearAllClick: async () => {\n      setShowLoading(true)\n      await onClearAllClick()\n      setShowLoading(false)\n    },\n  }\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/Layer2Page/Notification/index.tsx",
    "content": "import styled from '@emotion/styled'\nimport {\n  Box,\n  Checkbox,\n  Divider,\n  FormControlLabel as MuiFormControlLabel,\n  Grid,\n  Typography,\n} from '@mui/material'\nimport React from 'react'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport {\n  MaxWidthContainer,\n  TablePagination,\n  ToastType,\n  Toast,\n  LoadingStyled,\n  Button,\n  EmptyDefault,\n} from '@loopring-web/component-lib'\nimport { useToast, NotificationItem, useNFTDeploy } from '@loopring-web/core'\n\nimport {\n  CheckBoxIcon,\n  CheckedIcon,\n  DeleteIcon,\n  NotificationIcon,\n  ReadIcon,\n  SoursURL,\n  TOAST_TIME,\n} from '@loopring-web/common-resources'\nimport { useNotification } from './hook'\n\nconst RowHeight = 116\nconst StyledPaper = styled(Box)`\n  width: 100%;\n  height: 100%;\n  background: var(--color-box);\n  border-radius: ${({ theme }) => theme.unit}px;\n`\nconst PageSizeHeight = 44\nexport const NotificationPanel = withTranslation(['common', 'layout'])(({ t }: WithTranslation) => {\n  const container = React.useRef<HTMLDivElement>(null)\n  const { toastOpen, setToastOpen, closeToast } = useToast()\n  const [{ pageSize, page, hideRead }, setPageFilter] = React.useState({\n    pageSize: 0,\n    page: 1,\n    hideRead: true,\n  })\n  const {\n    showLoading,\n    getNotification,\n    rawData,\n    total,\n    onReadClick,\n    onReadAllClick,\n    onClearAllClick,\n  } = useNotification({ setToastOpen, page, pageSize })\n  const handlePageChange = React.useCallback(\n    async ({\n      page,\n      _pageSize,\n      _hideRead = hideRead,\n    }: {\n      page: number\n      _pageSize?: number\n      _hideRead?: boolean\n    }) => {\n      setPageFilter((state) => {\n        if (!_pageSize || !(Math.abs(state.pageSize - _pageSize) > 1 && _pageSize > 3)) {\n          _pageSize = state.pageSize && state.pageSize > 3 ? state.pageSize : 4\n        }\n        _hideRead = _hideRead !== undefined ? _hideRead : state.hideRead\n        return {\n          page,\n          hideRead: _hideRead,\n          pageSize: _pageSize,\n        }\n      })\n    },\n    [pageSize, page, hideRead],\n  )\n  React.useEffect(() => {\n    if (pageSize) {\n      getNotification({\n        offset: (page - 1) * pageSize,\n        limit: pageSize ?? 4,\n        filter: { notRead: hideRead },\n      })\n    }\n  }, [pageSize, page, hideRead])\n\n  React.useEffect(() => {\n    if (container?.current?.offsetHeight && pageSize == 0) {\n      let pageSize = Math.floor((container.current.offsetHeight - 10) / RowHeight)\n      handlePageChange({ page, _pageSize: pageSize })\n    }\n  }, [container?.current?.offsetHeight])\n\n  return (\n    <Box flex={1} display={'flex'} flexDirection={'column'}>\n      <MaxWidthContainer\n        sx={{ flexDirection: 'row' }}\n        background={'var(--color-global-bg)'}\n        display={'flex'}\n        justifyContent={'space-between'}\n        paddingY={2}\n      >\n        <Typography component={'h3'} variant={'h5'} display={'inline-flex'} alignItems={'center'}>\n          <NotificationIcon color={'inherit'} sx={{ marginRight: 1 }} /> {t('labelNoticeTitle')}\n        </Typography>\n        <Box>\n          <MuiFormControlLabel\n            control={\n              <Checkbox\n                checked={hideRead}\n                onChange={(_event: any, state: boolean) => {\n                  handlePageChange({ page, _hideRead: state })\n                }}\n                checkedIcon={<CheckedIcon />}\n                icon={<CheckBoxIcon />}\n                color='default'\n              />\n            }\n            label={t('labelHideRead')}\n          />\n          <Button\n            startIcon={<ReadIcon color={'inherit'} fontSize={'small'} />}\n            variant={'text'}\n            size={'small'}\n            sx={{ color: 'var(--color-text-primary)' }}\n            onClick={async () => {\n              await onReadAllClick()\n              handlePageChange({ page })\n            }}\n          >\n            {t('labelNotificationReadAll')}\n          </Button>\n          <Button\n            startIcon={<DeleteIcon color={'inherit'} fontSize={'small'} />}\n            variant={'text'}\n            size={'small'}\n            sx={{ color: 'var(--color-text-primary)' }}\n            onClick={async () => {\n              await onClearAllClick()\n              handlePageChange({ page })\n            }}\n          >\n            {t('labelNotificationClear')}\n          </Button>\n        </Box>\n      </MaxWidthContainer>\n      <Divider />\n      <MaxWidthContainer\n        background={'var(--color-pop-bg)'}\n        containerProps={{ flex: 1 }}\n        display={'flex'}\n        justifyContent={'space-between'}\n        paddingY={2}\n      >\n        <StyledPaper\n          className={'MuiPaper-elevation2'}\n          margin={0}\n          marginBottom={2}\n          paddingX={2}\n          paddingY={2}\n          flex={1}\n          height={'100%'}\n        >\n          <Box display={'flex'} flex={1} ref={container} height={'95%'}>\n            {!!rawData.length ? (\n              <Grid\n                container\n                paddingBottom={2}\n                display={'flex'}\n                flex={1}\n                alignContent={'flex-start'}\n              >\n                {rawData.map((ele, index) => {\n                  return (\n                    <Grid\n                      item\n                      xs={12}\n                      key={ele.id}\n                      maxHeight={RowHeight}\n                      sx={{ overflow: 'scroll' }}\n                    >\n                      <NotificationItem {...ele} index={index} onReadClick={onReadClick} />\n                      {index !== rawData?.length - 1 && <Divider />}\n                    </Grid>\n                  )\n                })}\n              </Grid>\n            ) : (\n              <EmptyDefault\n                style={{ flex: 1 }}\n                height={'100%'}\n                message={() => (\n                  <Box flex={1} display={'flex'} alignItems={'center'} justifyContent={'center'}>\n                    {t('labelNoContent')}\n                  </Box>\n                )}\n              />\n            )}\n            {showLoading && (\n              <LoadingStyled color={'inherit'}>\n                <img\n                  className='loading-gif'\n                  alt={'loading'}\n                  width='36'\n                  src={`${SoursURL}images/loading-line.gif`}\n                />\n              </LoadingStyled>\n            )}\n          </Box>\n          <Box height={PageSizeHeight}>\n            {total && total > pageSize ? (\n              <TablePagination\n                page={page}\n                pageSize={pageSize}\n                total={total}\n                onPageChange={(page) => {\n                  handlePageChange({ page })\n                }}\n              />\n            ) : (\n              <></>\n            )}\n          </Box>\n        </StyledPaper>\n      </MaxWidthContainer>\n      <Toast\n        alertText={toastOpen?.content ?? ''}\n        severity={toastOpen?.type ?? ToastType.success}\n        open={toastOpen?.open ?? false}\n        autoHideDuration={TOAST_TIME}\n        onClose={closeToast}\n      />\n    </Box>\n  )\n})\n"
  },
  {
    "path": "packages/webapp/src/pages/Layer2Page/ReferralRewardsPanel/hook.ts",
    "content": "import { LoopringAPI, store, useAccount } from '@loopring-web/core'\nimport { useTranslation } from 'react-i18next'\nimport React from 'react'\nimport { ReferralsRow, ToastType, RefundRow } from '@loopring-web/component-lib'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport {\n  AccountStatus,\n  getValuePrecisionThousand,\n  SagaStatus,\n  SDK_ERROR_MAP_TO_UI,\n} from '@loopring-web/common-resources'\nexport function useRefundTable<R = RefundRow>(setToastOpen: (state: any) => void) {\n  const {\n    account: { accountId, apiKey },\n    status: accountStatus,\n  } = useAccount()\n  const { tokenMap } = store.getState().tokenMap\n  const { t } = useTranslation(['error'])\n  const [summary, setSummary] = React.useState<undefined | any>(undefined)\n  const [record, setRecord] = React.useState<R[]>([])\n  const [recordTotal, setRecordTotal] = React.useState(0)\n  const [showLoading, setShowLoading] = React.useState(false)\n  const getRefundTableList = React.useCallback(\n    async ({ start, end, limit, offset }: Partial<sdk.GetReferSelf>) => {\n      if (LoopringAPI && LoopringAPI.userAPI && accountId && apiKey) {\n        setShowLoading(true)\n        try {\n          const response = await LoopringAPI.userAPI.getReferSelf(\n            {\n              accountId: accountId.toString(),\n              limit,\n              start,\n              end,\n              offset,\n            },\n            apiKey,\n          )\n          if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n            throw response as sdk.RESULT_INFO\n          } else {\n            const list = response?.records.map(({ lrcAmount, ...item }) => {\n              return {\n                ...item,\n                amount: {\n                  unit: 'LRC',\n                  value: getValuePrecisionThousand(\n                    sdk.toBig(lrcAmount).div('1e' + tokenMap['LRC'].decimals),\n                    tokenMap['LRC'].precision,\n                    tokenMap['LRC'].precision,\n                    tokenMap['LRC'].precision,\n                    false,\n                  ),\n                },\n              } as unknown as R\n            })\n            setRecord(list)\n            setRecordTotal(response.totalNum)\n          }\n        } catch (error) {\n          let errorItem\n          if (typeof (error as sdk.RESULT_INFO)?.code === 'number') {\n            errorItem = SDK_ERROR_MAP_TO_UI[(error as sdk.RESULT_INFO)?.code ?? 700001]\n          } else {\n            errorItem = SDK_ERROR_MAP_TO_UI[700012]\n          }\n          setToastOpen({\n            open: true,\n            type: ToastType.error,\n            content: 'error : ' + errorItem ? t(errorItem.messageKey) : (error as any)?.message,\n          })\n        }\n\n        setShowLoading(false)\n      }\n    },\n    [accountId, apiKey, setToastOpen, t, tokenMap],\n  )\n  React.useEffect(() => {\n    const account = store.getState().account\n    if (accountStatus === SagaStatus.UNSET && account.readyState == AccountStatus.ACTIVATED) {\n      LoopringAPI.userAPI\n        ?.geReferStatistic<sdk.ReferStatistic>(\n          {\n            accountId: accountId.toString(),\n            reason: sdk.GetReferStatisticReason.Recommender,\n          },\n          apiKey,\n        )\n        .then((response) => {\n          if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n            const errorItem = SDK_ERROR_MAP_TO_UI[(response as sdk.RESULT_INFO)?.code ?? 700001]\n            setToastOpen({\n              open: true,\n              type: ToastType.error,\n              content:\n                'error : ' + errorItem\n                  ? t(errorItem.messageKey)\n                  : (response as sdk.RESULT_INFO).message,\n            })\n          } else {\n            // ;\n            // ;\n\n            setSummary({\n              ...response,\n              totalValue:\n                response.totalProfit == '' || response.totalProfit == '0'\n                  ? undefined\n                  : getValuePrecisionThousand(\n                      sdk.toBig(response.totalProfit).div('1e' + tokenMap['LRC'].decimals),\n                      tokenMap['LRC'].precision,\n                      tokenMap['LRC'].precision,\n                      tokenMap['LRC'].precision,\n                      false,\n                    ),\n              claimableValue:\n                response.claimableProfit == '' || response.claimableProfit == '0'\n                  ? undefined\n                  : getValuePrecisionThousand(\n                      sdk.toBig(response.claimableProfit).div('1e' + tokenMap['LRC'].decimals),\n                      tokenMap['LRC'].precision,\n                      tokenMap['LRC'].precision,\n                      tokenMap['LRC'].precision,\n                      false,\n                    ),\n            })\n          }\n        })\n    }\n  }, [accountStatus])\n\n  return {\n    summary,\n    record,\n    recordTotal,\n    showLoading,\n    getRefundTableList,\n  }\n}\n\nexport function useReferralsTable<R = ReferralsRow>(setToastOpen: (state: any) => void) {\n  const {\n    account: { accountId, apiKey },\n    status: accountStatus,\n  } = useAccount()\n  const { tokenMap } = store.getState().tokenMap\n  const { t } = useTranslation(['error'])\n  const [summary, setSummary] = React.useState<undefined | any>(undefined)\n  const [record, setRecord] = React.useState<R[]>([])\n  const [recordTotal, setRecordTotal] = React.useState(0)\n  const [showLoading, setShowLoading] = React.useState(false)\n  const getReferralsTableList = React.useCallback(\n    async ({ start, end, limit, offset }: Partial<sdk.GetReferDownsides>) => {\n      if (LoopringAPI && LoopringAPI.userAPI && accountId && apiKey) {\n        setShowLoading(true)\n        try {\n          const response = await LoopringAPI.userAPI.getReferDownsides(\n            {\n              accountId: accountId.toString(),\n              limit,\n              start,\n              end,\n              offset,\n            },\n            apiKey,\n          )\n          if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n            throw response\n          } else {\n            const list = response?.records.map(({ lrcAmount, ...item }) => {\n              return {\n                ...item,\n                amount: {\n                  unit: 'LRC',\n                  value: getValuePrecisionThousand(\n                    sdk.toBig(lrcAmount).div('1e' + tokenMap['LRC'].decimals),\n                    tokenMap['LRC'].precision,\n                    tokenMap['LRC'].precision,\n                    tokenMap['LRC'].precision,\n                    false,\n                  ),\n                },\n              } as unknown as R\n            })\n            setRecord(list)\n            setRecordTotal(response.totalNum)\n          }\n        } catch (error) {\n          let errorItem\n          if (typeof (error as sdk.RESULT_INFO)?.code === 'number') {\n            errorItem = SDK_ERROR_MAP_TO_UI[(error as sdk.RESULT_INFO)?.code ?? 700001]\n          } else {\n            errorItem = SDK_ERROR_MAP_TO_UI[700012]\n          }\n          setToastOpen({\n            open: true,\n            type: ToastType.error,\n            content: 'error : ' + errorItem ? t(errorItem.messageKey) : (error as any)?.message,\n          })\n        }\n\n        setShowLoading(false)\n      }\n    },\n    [accountId, apiKey, setToastOpen, t, tokenMap],\n  )\n  React.useEffect(() => {\n    const account = store.getState().account\n    if (accountStatus === SagaStatus.UNSET && account.readyState == AccountStatus.ACTIVATED) {\n      LoopringAPI.userAPI\n        ?.geReferStatistic<sdk.ReferStatistic>(\n          {\n            accountId: accountId.toString(),\n            reason: sdk.GetReferStatisticReason.Invited,\n          },\n          apiKey,\n        )\n        .then((response) => {\n          if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n            const errorItem = SDK_ERROR_MAP_TO_UI[(response as sdk.RESULT_INFO)?.code ?? 700001]\n            setToastOpen({\n              open: true,\n              type: ToastType.error,\n              content:\n                'error : ' + errorItem\n                  ? t(errorItem.messageKey)\n                  : (response as sdk.RESULT_INFO).message,\n            })\n          } else {\n            setSummary({\n              ...response,\n              totalValue:\n                response.totalProfit == '' || response.totalProfit == '0'\n                  ? undefined\n                  : getValuePrecisionThousand(\n                      sdk.toBig(response.totalProfit).div('1e' + tokenMap['LRC'].decimals),\n                      tokenMap['LRC'].precision,\n                      tokenMap['LRC'].precision,\n                      tokenMap['LRC'].precision,\n                      false,\n                    ),\n              claimableValue:\n                response.claimableProfit == '' || response.claimableProfit == '0'\n                  ? undefined\n                  : getValuePrecisionThousand(\n                      sdk.toBig(response.claimableProfit).div('1e' + tokenMap['LRC'].decimals),\n                      tokenMap['LRC'].precision,\n                      tokenMap['LRC'].precision,\n                      tokenMap['LRC'].precision,\n                      false,\n                    ),\n            })\n          }\n        })\n    }\n  }, [accountStatus])\n\n  return {\n    summary,\n    record,\n    recordTotal,\n    showLoading,\n    getReferralsTableList,\n  }\n}\n\n// export function useReferralRewardSumInfo() {\n//   const {\n//     account: { accountId, apiKey },\n//   } = useAccount();\n//   const [summary, setSummary] = React.useState();\n//\n//\n//   return {};\n// }\n"
  },
  {
    "path": "packages/webapp/src/pages/Layer2Page/ReferralRewardsPanel/index.tsx",
    "content": "import styled from '@emotion/styled'\nimport {\n  Box,\n  BoxProps,\n  Container,\n  Grid,\n  InputAdornment,\n  Link,\n  Tab,\n  Tabs,\n  Typography,\n} from '@mui/material'\nimport React from 'react'\nimport { Trans, useTranslation } from 'react-i18next'\nimport { useAccount, useSubmitBtn, useToast } from '@loopring-web/core'\nimport {\n  AccountStatus,\n  AssetTabIndex,\n  copyToClipBoard,\n  EmptyValueTag,\n  Exchange,\n  ExchangeIO,\n  L1L2_NAME_DEFINED,\n  Layer2RouterID,\n  LinkSharedIcon,\n  MapChainId,\n  myLog,\n  ProfileIndex,\n  SoursURL,\n  TOAST_TIME,\n  TradeBtnStatus,\n  url_path,\n  WalletSite,\n} from '@loopring-web/common-resources'\nimport {\n  Button,\n  ReferralsTable,\n  RefundTable,\n  Toast,\n  ToastType,\n  useSettings,\n  OutlinedInput,\n} from '@loopring-web/component-lib'\nimport { useReferralsTable, useRefundTable } from './hook'\nimport { useHistory } from 'react-router-dom'\nimport { ErrorPage } from '../../ErrorPage'\n\nconst BoxStyled = styled(Box)`\n  ol {\n    list-style: decimal inside;\n\n    li {\n      //list-item;\n      color: var(--color-text-third);\n      display: list-item;\n      font-size: ${({ theme }) => theme.fontDefault.body1};\n      // padding: ${({ theme }) => `0 ${theme.unit}`}px;\n      line-height: 2em;\n    }\n  }\n`\nexport const BoxBannerStyle = styled(Box)<\n  BoxProps & { backGroundUrl?: string | number; direction?: 'left' | 'right' }\n>`\n  background-color: var(--color-box);\n\n  .bg:after {\n    display: block;\n    content: '';\n    float: ${({ direction }) => direction};\n    width: 35%;\n    background-repeat: no-repeat;\n    background-position: center;\n    background-size: contain;\n    background-image: url('${({ backGroundUrl }) => backGroundUrl}');\n  }\n\n  &.mobile .bg {\n    position: relative;\n    display: flex;\n    flex-direction: column;\n\n    &:after {\n      opacity: 0.08;\n      z-index: 1;\n      position: absolute;\n      top: 0;\n      width: 100%;\n      height: 100%;\n      pointer-events: none;\n    }\n  }\n` as (\n  props: BoxProps & {\n    backGroundUrl?: string | number\n    direction?: 'left' | 'right'\n  },\n) => JSX.Element\n\nenum ReferStep {\n  method1 = 0,\n  method2 = 1,\n}\n\nexport type ImageReferralBanner = {\n  referralBanners: { en: string[] }\n  lng: string[]\n  position: {\n    code: { default: any[]; [key: number]: any[] }\n    [key: string]: any\n  }\n}\n\nconst ReferHeader = <R extends ImageReferralBanner>({\n  isActive = true,\n  handleCopy,\n  link,\n}: {\n  link: string\n  isActive?: boolean\n  handleCopy: (selected: 'id' | 'link') => void\n}) => {\n  const { account } = useAccount()\n  const { t } = useTranslation(['common', 'layout'])\n  const { defaultNetwork, isMobile } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const [imageList, setImageList] = React.useState<R>({\n    // @ts-ignore\n    referralBanners: {\n      en: [],\n    },\n    lng: ['en'],\n    position: {\n      code: { default: [48, 30, 230, 64, '#000000', 630, 880] },\n    },\n  })\n  // const [images, setImages] = React.useState<JSX.Element[]>([]);\n  React.useEffect(() => {\n    fetch(`${url_path}/referral/information.json`)\n      .then((response) => response.json())\n      .then((result) => {\n        if (result.referralBanners) {\n          setImageList(result)\n          renderImage(result)\n        }\n      })\n  }, [])\n  const renderImage = React.useCallback(\n    (imageList: R) => {\n      let images: any[] = []\n      imageList?.referralBanners?.en.forEach((item, index) => {\n        const canvas: HTMLCanvasElement = document.createElement('canvas')\n        let _default: any = undefined\n        if (imageList?.position?.code[index]) {\n          _default = imageList?.position?.code[index]\n        } else {\n          _default = imageList?.position?.code?.default\n        }\n        let [left, bottom, , , color, width, height] = _default ?? [\n          48,\n          30,\n          230,\n          64,\n          '#000000',\n          630,\n          880,\n        ]\n        const lebelY = height - bottom - 100 + 20\n        const lebelX = left\n        const lebelCodeY = lebelY + 64\n        const lebelCodeX = left\n        const labelCode = t('labelReferralImageCode', {\n          code: account.accountId,\n        })\n        const label = t('labelReferralImageDes')\n\n        canvas.width = width\n        canvas.height = height\n        // @ts-ignore\n        const context: CanvasRenderingContext2D = canvas.getContext('2d')\n        const image = new Image()\n        image.crossOrigin = 'true'\n        image.src = item\n\n        image.onload = function () {\n          context.clearRect(0, 0, width, width)\n          context.drawImage(image, 0, 0, width, height)\n          context.font = '28px Roboto'\n          context.fillStyle = color\n          context.textAlign = 'left'\n          context.fillText(label, lebelX, lebelY)\n          context.font = '44px Roboto'\n          context.fillText(labelCode, lebelCodeX, lebelCodeY)\n\n          // myLog('imageUrl createObjectURL', canvas.toDataURL())\n          images.push({ imageUrl: canvas.toDataURL(), size: [width / 2, height / 2] })\n          if (index + 1 == imageList?.referralBanners?.en?.length) {\n            myLog('imageList', images)\n\n            // setImages(images)\n          }\n          // canvas.toBlob((blob) => {\n          // const a = document.createElement('a')\n          // // @ts-ignore\n          // a.download = (item ?? '/').split('/')?.pop()\n          // a.style.display = 'none'\n          // // @ts-ignore\n          // a.href = URL.createObjectURL(blob)\n          // document.body.appendChild(a)\n          // a.click()\n          // document.body.removeChild(a)\n          // }, 'image/png')\n        }\n      })\n    },\n    [imageList, account],\n  )\n  const onDownloadImage = () => {\n    imageList?.referralBanners?.en.map((item, index) => {\n      const canvas: HTMLCanvasElement = document.createElement('canvas')\n      let _default: any = undefined\n      if (imageList?.position?.code[index]) {\n        _default = imageList?.position?.code[index]\n      } else {\n        _default = imageList?.position?.code?.default\n      }\n      let [left, bottom, , , color, width, height] = _default ?? [\n        48,\n        30,\n        230,\n        64,\n        '#000000',\n        630,\n        880,\n      ]\n      const lebelY = height - bottom - 100 + 20\n      const lebelX = left\n      const lebelCodeY = lebelY + 64\n      const lebelCodeX = left\n      const labelCode = t('labelReferralImageCode', {\n        code: account.accountId,\n      })\n      const label = t('labelReferralImageDes')\n\n      canvas.width = width\n      canvas.height = height\n      // @ts-ignore\n      const context: CanvasRenderingContext2D = canvas.getContext('2d')\n      const image = new Image()\n      image.crossOrigin = 'true'\n      image.src = item\n      image.onload = function () {\n        context.clearRect(0, 0, width, width)\n        context.drawImage(image, 0, 0, width, height)\n        context.font = '28px Roboto'\n        context.fillStyle = color\n        context.textAlign = 'left'\n        context.fillText(label, lebelX, lebelY)\n        context.font = '44px Roboto'\n        context.fillText(labelCode, lebelCodeX, lebelCodeY)\n\n        canvas.toBlob((blob) => {\n          const a = document.createElement('a')\n          // @ts-ignore\n          a.download = (item ?? '/').split('/')?.pop()\n          a.style.display = 'none'\n          // @ts-ignore\n          a.href = URL.createObjectURL(blob)\n          document.body.appendChild(a)\n          a.click()\n          document.body.removeChild(a)\n        }, 'image/jpeg')\n      }\n    })\n  }\n  const { btnStatus, onBtnClick, btnLabel } = useSubmitBtn({\n    availableTradeCheck: () => {\n      return { tradeBtnStatus: TradeBtnStatus.AVAILABLE, label: '' }\n    },\n    isLoading: false,\n    submitCallback: async () => {\n      onDownloadImage()\n    },\n  })\n\n  const label = React.useMemo(() => {\n    if (btnLabel) {\n      const key = btnLabel.split('|')\n      if (key) {\n        return t(\n          key[0],\n          key && key[1]\n            ? {\n                arg: key[1],\n                l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n              }\n            : {\n                l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n              },\n        )\n      } else {\n        return t(btnLabel, {\n          l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n          loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n          l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n          l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n          ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n        })\n      }\n    } else {\n      return t(`labelInvite`)\n    }\n  }, [t, btnLabel])\n\n  return (\n    <BoxBannerStyle\n      className={isMobile ? 'mobile' : ''}\n      backGroundUrl={SoursURL + '/images/giftReward.webp'}\n      direction={'right'}\n    >\n      <Container>\n        <Box className={'bg'} marginY={3} display={'flex'}>\n          <Box width={isMobile ? '100%' : '65%'}>\n            <Typography\n              component={'h1'}\n              variant={isMobile ? 'h4' : 'h2'}\n              sx={{ whiteSpace: 'pre-line', wordBreak: 'break-all' }}\n            >\n              {t('labelReferTitle')}\n            </Typography>\n            <Typography\n              paddingY={1}\n              component={'h2'}\n              variant={'body1'}\n              color={'textSecondary'}\n              sx={{ whiteSpace: 'pre-line', wordBreak: 'break-all' }}\n            >\n              {t('labelReferTitleDes')}\n            </Typography>\n            {account.readyState == AccountStatus.ACTIVATED && (\n              <>\n                <Box paddingTop={1} width={isMobile ? '100%' : '70%'}>\n                  <OutlinedInput\n                    size={'large'}\n                    className={'copy'}\n                    placeholder={'copy'}\n                    value={link}\n                    disabled={true}\n                    fullWidth={true}\n                    // onChange={(event: any) => {}}\n                    startAdornment={\n                      <InputAdornment position='start'>\n                        <LinkSharedIcon color={'inherit'} />\n                      </InputAdornment>\n                    }\n                    endAdornment={\n                      <Button size={'small'} variant={'text'} onClick={() => handleCopy('link')}>\n                        {t('labelCopy')}\n                      </Button>\n                    }\n                  />\n                </Box>\n                <Box paddingTop={1} width={isMobile ? '100%' : '70%'}>\n                  <OutlinedInput\n                    size={'large'}\n                    className={'copy'}\n                    placeholder={'copy'}\n                    value={account.accountId}\n                    disabled={true}\n                    fullWidth={true}\n                    // onChange={(event: any) => {}}\n                    startAdornment={\n                      <InputAdornment position='start'>\n                        <Typography\n                          color={'var(--color-text-third)'}\n                          variant={'h2'}\n                          display={'inline-flex'}\n                          width={36}\n                          textAlign={'center'}\n                          component={'span'}\n                          paddingX={1 / 2}\n                        >\n                          #\n                        </Typography>\n                        {/*<LinkIcon color={\"inherit\"} />*/}\n                      </InputAdornment>\n                    }\n                    endAdornment={\n                      <Button size={'small'} variant={'text'} onClick={() => handleCopy('id')}>\n                        {t('labelCopy')}\n                      </Button>\n                    }\n                  />\n                </Box>\n              </>\n            )}\n            <Box marginY={2}>\n              <Button\n                size={'medium'}\n                onClick={onBtnClick}\n                loading={'false'}\n                variant={'contained'}\n                sx={{ minWidth: 'var(--walletconnect-width)' }}\n                disabled={\n                  btnStatus === TradeBtnStatus.DISABLED || btnStatus === TradeBtnStatus.LOADING\n                }\n              >\n                {label}\n              </Button>\n              {/*{image.map((item, index) => (*/}\n              {/*  <React.Fragment key={index}>{item}</React.Fragment>*/}\n              {/*))}*/}\n              <Box sx={{ display: 'block' }} height={0} width={0} overflow={'hidden'}>\n                <canvas className={'canvas'} />\n                {/*{images.map((item, index) => (*/}\n                {/*  <React.Fragment key={index}>{item}</React.Fragment>*/}\n                {/*))}*/}\n              </Box>\n            </Box>\n          </Box>\n        </Box>\n      </Container>\n    </BoxBannerStyle>\n  )\n}\n\nconst ReferView = () => {\n  const { account } = useAccount()\n  const { t } = useTranslation()\n  const { defaultNetwork, isMobile } = useSettings()\n  const { toastOpen, setToastOpen, closeToast } = useToast()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const refundData = useRefundTable(setToastOpen)\n  const referralsData = useReferralsTable(setToastOpen)\n  const [currentTab, setCurrentTab] = React.useState(ReferStep.method1)\n  const link = `${WalletSite}?referralcode=${account.accountId}`\n  const linkExchange = `${Exchange}?referralcode=${account.accountId}`\n  const history = useHistory()\n\n  const handleCopy = (selected: 'id' | 'link') => {\n    switch (selected) {\n      case 'id':\n        copyToClipBoard(account?.accountId?.toString())\n        setToastOpen({\n          open: true,\n          type: ToastType.success,\n          content: t('labelCopyCodeClip'),\n        })\n        break\n      case 'link':\n        copyToClipBoard(link)\n        setToastOpen({\n          open: true,\n          type: ToastType.success,\n          content: t('labelCopyAddClip'),\n        })\n        break\n    }\n  }\n  myLog('refundData', refundData, referralsData)\n  return (\n    <>\n      {ProfileIndex[network]?.includes(Layer2RouterID.referralrewards) ? (\n        <>\n          <Toast\n            alertText={toastOpen?.content ?? ''}\n            open={toastOpen?.open ?? false}\n            autoHideDuration={TOAST_TIME}\n            onClose={closeToast}\n            severity={toastOpen.type}\n          />\n          <ReferHeader handleCopy={handleCopy} link={link} />\n          <Container>\n            <BoxStyled marginTop={2} paddingY={2} paddingX={0} flex={1}>\n              <Typography component={'h3'} variant={'h4'} marginY={2}>\n                {t('labelReferralRules')}\n              </Typography>\n              <Tabs\n                sx={{ marginLeft: -1 }}\n                value={currentTab}\n                className={'MuiTabs-small'}\n                onChange={(_event, value) => {\n                  setCurrentTab(value)\n                }}\n                aria-label='reward-rule-tabs'\n                variant='scrollable'\n              >\n                <Tab label={t('labelReferralMethod1')} value={ReferStep.method1} />\n                <Tab label={t('labelReferralMethod2')} value={ReferStep.method2} />\n              </Tabs>\n              <Box>\n                {currentTab === ReferStep.method1 && (\n                  <ol>\n                    <li>{t('labelReferralMethod1Step1')}</li>\n                    <li>{t('labelReferralMethod1Step2')}</li>\n                    <li>\n                      {t('labelReferralMethod1Step3', {\n                        loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                        l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                        l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                        ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                        loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n                      })}\n                    </li>\n                    <li>{t('labelReferralMethod1Step4')}</li>\n                  </ol>\n                )}\n                {currentTab === ReferStep.method2 && (\n                  <ol>\n                    <li>\n                      {' '}\n                      <Trans i18nKey={'labelReferralMethod2Step1'}>\n                        Access the website\n                        <Link href={linkExchange} target={'_blank'}>\n                          {ExchangeIO}\n                        </Link>\n                      </Trans>\n                    </li>\n                    <li>{t('labelReferralMethod2Step2')}</li>\n                    <li>\n                      {t('labelReferralMethod2Step3', {\n                        loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                        l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                        l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                        ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                        loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n                      })}\n                    </li>\n                    <li>{t('labelReferralMethod2Step4')}</li>\n                  </ol>\n                )}\n              </Box>\n\n              {account.readyState === AccountStatus.ACTIVATED && (\n                <>\n                  <BoxStyled marginTop={2} paddingY={2} paddingX={0} flex={1}>\n                    <Typography component={'h3'} variant={'h4'} marginY={2}>\n                      {t('labelReferralMyReferrals')}\n                    </Typography>\n\n                    <Box display={'flex'} flexDirection={'column'}>\n                      <Grid container marginY={2}>\n                        <Grid item md={4} xs={6}>\n                          <Typography\n                            component={'span'}\n                            color={'var(--color-text-third)'}\n                            variant={'body1'}\n                            paddingRight={isMobile ? '' : 2}\n                          >\n                            {t('labelReferralsTotalReferrals')}\n                            {referralsData.summary?.downsidesNum &&\n                            referralsData.summary?.downsidesNum != '0' ? (\n                              <Typography\n                                variant={'inherit'}\n                                component={'span'}\n                                color={'textPrimary'}\n                                paddingLeft={1}\n                              >\n                                {referralsData.summary?.downsidesNum}\n                              </Typography>\n                            ) : (\n                              EmptyValueTag\n                            )}\n                          </Typography>\n                        </Grid>\n                        <Grid\n                          item\n                          md={4}\n                          xs={6}\n                          justifyContent={'space-evenly'}\n                          flexDirection={'column'}\n                          alignItems={'flex-end'}\n                          display={'flex '}\n                        >\n                          <Typography\n                            component={'span'}\n                            color={'var(--color-text-third)'}\n                            variant={'body1'}\n                            paddingRight={isMobile ? '' : 2}\n                          >\n                            {t('labelReferralsTotalEarning')}\n                            {referralsData.summary?.totalValue ? (\n                              <Typography\n                                variant={'inherit'}\n                                component={'span'}\n                                color={'textPrimary'}\n                                paddingLeft={1}\n                              >\n                                {referralsData.summary?.totalValue + ' LRC'}\n                              </Typography>\n                            ) : (\n                              EmptyValueTag\n                            )}\n                          </Typography>\n                        </Grid>\n\n                        <Grid\n                          item\n                          md={4}\n                          xs={12}\n                          flexDirection={'row'}\n                          alignItems={'center'}\n                          display={'flex'}\n                          paddingTop={isMobile ? 1 : ''}\n                          justifyContent={isMobile ? 'space-between' : 'flex-end'}\n                        >\n                          <Typography\n                            component={'span'}\n                            color={'var(--color-text-third)'}\n                            variant={'body1'}\n                            paddingRight={isMobile ? '' : 2}\n                          >\n                            {t('labelReferralsClaimEarning')}\n                            {referralsData.summary?.claimableValue ? (\n                              <Typography\n                                paddingLeft={1}\n                                variant={'inherit'}\n                                component={'span'}\n                                color={'textPrimary'}\n                              >\n                                {referralsData.summary?.claimableValue + ' LRC'}\n                              </Typography>\n                            ) : (\n                              <Typography\n                                variant={'inherit'}\n                                component={'span'}\n                                color={'var(--color-text-third)'}\n                              >\n                                {EmptyValueTag}\n                              </Typography>\n                            )}\n                          </Typography>\n                          {referralsData.summary?.claimableValue ? (\n                            <Button\n                              variant={'contained'}\n                              size={'small'}\n                              sx={{ marginLeft: 2 }}\n                              onClick={() => {\n                                history.push(`/l2assets/assets/${AssetTabIndex.Rewards}`)\n                              }}\n                            >\n                              {t('labelClaimBtn')}\n                            </Button>\n                          ) : (\n                            <></>\n                          )}\n                        </Grid>\n                      </Grid>\n                      <ReferralsTable\n                        {...{\n                          rawData: referralsData.record,\n                          pagination: {\n                            pageSize: 8,\n                            total: referralsData.recordTotal,\n                          },\n                          getList: referralsData.getReferralsTableList,\n                          showloading: referralsData.showLoading,\n                        }}\n                      />\n                    </Box>\n                  </BoxStyled>\n                  <BoxStyled marginTop={2} paddingY={2} paddingX={0} flex={1}>\n                    <Typography component={'h3'} variant={'h4'} marginY={2}>\n                      {t('labelReferralReferralsRefunds')}\n                    </Typography>\n                    <Grid container marginY={2}>\n                      <Grid item md={4} xs={6}>\n                        <Typography\n                          component={'span'}\n                          color={'var(--color-text-third)'}\n                          variant={'body1'}\n                          paddingRight={isMobile ? '' : 2}\n                        >\n                          {t('labelReferralsTotalTradeNumber')}\n                          {refundData.summary?.tradeNum && refundData.summary?.tradeNum != '0' ? (\n                            <Typography\n                              variant={'inherit'}\n                              component={'span'}\n                              color={'textPrimary'}\n                              paddingLeft={1}\n                            >\n                              {refundData.summary?.tradeNum}\n                            </Typography>\n                          ) : (\n                            EmptyValueTag\n                          )}\n                        </Typography>\n                      </Grid>\n                      <Grid\n                        item\n                        md={4}\n                        xs={6}\n                        justifyContent={'space-evenly'}\n                        flexDirection={'column'}\n                        alignItems={'flex-end'}\n                        display={'flex '}\n                      >\n                        <Typography\n                          component={'span'}\n                          color={'var(--color-text-third)'}\n                          variant={'body1'}\n                          paddingRight={isMobile ? '' : 2}\n                        >\n                          {t('labelReferralsTotalRefund')}\n                          {refundData.summary?.totalValue ? (\n                            <Typography\n                              variant={'inherit'}\n                              component={'span'}\n                              color={'textPrimary'}\n                              paddingLeft={1}\n                            >\n                              {refundData.summary?.totalValue + ' LRC'}\n                            </Typography>\n                          ) : (\n                            EmptyValueTag\n                          )}\n                        </Typography>\n                      </Grid>\n\n                      <Grid\n                        item\n                        md={4}\n                        xs={12}\n                        flexDirection={'row'}\n                        alignItems={'center'}\n                        display={'flex'}\n                        paddingTop={isMobile ? 1 : ''}\n                        justifyContent={isMobile ? 'space-between' : 'flex-end'}\n                      >\n                        <Typography\n                          component={'span'}\n                          color={'var(--color-text-third)'}\n                          variant={'body1'}\n                          paddingRight={isMobile ? '' : 2}\n                        >\n                          {t('labelReferralsClaimRefund')}\n\n                          {refundData.summary?.claimableValue ? (\n                            <Typography\n                              variant={'inherit'}\n                              component={'span'}\n                              color={'textPrimary'}\n                              paddingLeft={1}\n                            >\n                              {refundData.summary?.claimableValue + ' LRC'}\n                            </Typography>\n                          ) : (\n                            <Typography\n                              variant={'inherit'}\n                              component={'span'}\n                              color={'var(--color-text-third)'}\n                            >\n                              {EmptyValueTag}\n                            </Typography>\n                          )}\n                        </Typography>\n                        {refundData.summary?.claimableValue ? (\n                          <Button\n                            variant={'contained'}\n                            size={'small'}\n                            sx={{ marginLeft: 2 }}\n                            onClick={() => {\n                              history.push(`/l2assets/assets/${AssetTabIndex.Rewards}`)\n                            }}\n                          >\n                            {t('labelClaimBtn')}\n                          </Button>\n                        ) : (\n                          <></>\n                        )}\n                      </Grid>\n                    </Grid>\n                    <Box display={'flex'} flexDirection={'column'}>\n                      <RefundTable\n                        {...{\n                          rawData: refundData.record,\n                          pagination: {\n                            pageSize: 8,\n                            total: refundData.recordTotal,\n                          },\n                          getList: refundData.getRefundTableList,\n                          showloading: refundData.showLoading,\n                        }}\n                      />\n                    </Box>\n                  </BoxStyled>\n                </>\n              )}\n            </BoxStyled>\n          </Container>\n        </>\n      ) : (\n        <ErrorPage messageKey={'error404'} />\n      )}\n    </>\n  )\n}\nexport const ReferralRewardsPanel = () => {\n  return <ReferView />\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/Layer2Page/SecurityPanel/hook.ts",
    "content": "import { AccountStatus, MapChainId, myLog, UIERROR_CODE } from '@loopring-web/common-resources'\nimport { LoopringAPI, store, useAccount } from '@loopring-web/core'\nimport React from 'react'\n\nimport { AccountStep, useOpenModals } from '@loopring-web/component-lib'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nimport { ConnectProviders, connectProvides } from '@loopring-web/web3-provider'\n\nimport Web3 from 'web3'\n\nexport function useResetAccount() {\n  const { setShowResetAccount } = useOpenModals()\n  const {\n    account: { accountId, apiKey },\n  } = useAccount()\n  const [hasDualInvest, setHasDualInvest] = React.useState<boolean | undefined>(undefined)\n  React.useEffect(() => {\n    ;(async () => {\n      if (LoopringAPI.defiAPI && accountId && apiKey) {\n        const response = await LoopringAPI.defiAPI.getDualTransactions(\n          {\n            accountId,\n            settlementStatuses: sdk.SETTLEMENT_STATUS.UNSETTLED,\n            investmentStatuses: [\n              sdk.LABEL_INVESTMENT_STATUS.CANCELLED,\n              sdk.LABEL_INVESTMENT_STATUS.SUCCESS,\n              sdk.LABEL_INVESTMENT_STATUS.PROCESSED,\n              sdk.LABEL_INVESTMENT_STATUS.PROCESSING,\n            ].join(','),\n            retryStatuses: [sdk.DUAL_RETRY_STATUS.RETRYING],\n          } as any,\n          apiKey,\n        )\n        setHasDualInvest(response.totalNum && response.totalNum > 0)\n      }\n    })()\n  }, [apiKey])\n  const resetKeypair = React.useCallback(() => {\n    setShowResetAccount({\n      isShow: true,\n      info: {\n        confirmationType:\n          hasDualInvest === undefined\n            ? 'lockedReset'\n            : hasDualInvest === true\n            ? 'unlockedWithDual'\n            : 'unlockedWithoutDual',\n      },\n    })\n  }, [setShowResetAccount, hasDualInvest])\n\n  return {\n    resetKeypair,\n  }\n}\n\nexport function useExportAccountInfo() {\n  const { account } = useAccount()\n\n  const { setShowExportAccount, setShowAccount } = useOpenModals()\n\n  const exportAccInfo = React.useCallback(() => {\n    if (account.readyState !== AccountStatus.ACTIVATED) {\n      return undefined\n    }\n\n    return {\n      address: account.accAddress,\n      accountId: account.accountId,\n      level: account.level,\n      nonce: account.nonce,\n      apiKey: account.apiKey,\n      publicX: account.eddsaKey.formatedPx,\n      publicY: account.eddsaKey.formatedPy,\n      privateKey: account.eddsaKey.sk,\n    }\n  }, [account])\n\n  const exportAccount = React.useCallback(async () => {\n    const _account = store.getState().account\n    const connectName = (ConnectProviders[_account.connectName] ??\n      _account.connectName) as unknown as sdk.ConnectorNames\n    const { exchangeInfo, chainId } = store.getState().system\n    const { isMobile, defaultNetwork } = store.getState().settings\n    let walletType, account\n    if (exchangeInfo && LoopringAPI.userAPI && LoopringAPI.walletAPI && LoopringAPI.exchangeAPI) {\n      try {\n        setShowAccount({\n          isShow: true,\n          step: AccountStep.ExportAccount_Approve_WaitForAuth,\n        })\n        const walletTypePromise: Promise<{ walletType: any }> =\n          window.ethereum &&\n          (_account.connectName as unknown as sdk.ConnectorNames) === sdk.ConnectorNames.MetaMask &&\n          isMobile\n            ? Promise.resolve({ walletType: undefined })\n            : LoopringAPI.walletAPI.getWalletType({\n                wallet: _account.accAddress,\n                network: MapChainId[defaultNetwork] as sdk.NetworkWallet\n              })\n        ;[{ accInfo: account }, { walletType }] = await Promise.all([\n          LoopringAPI.exchangeAPI.getAccount({\n            owner: _account.accAddress,\n          }),\n          walletTypePromise,\n        ])\n          .then((response) => {\n            if ((response[0] as sdk.RESULT_INFO)?.code) {\n              throw response[0]\n            }\n            return response\n          })\n          .catch((error) => {\n            throw error\n          })\n\n        myLog('exportAccount account:', account)\n\n        try {\n          const eddsaKey = await sdk.generateKeyPair({\n            web3: connectProvides.usedWeb3 as unknown as Web3,\n            address: account.owner,\n            chainId: chainId as any,\n            keySeed:\n              account.keySeed && _account.keySeed !== ''\n                ? _account.keySeed\n                : sdk.GlobalAPI.KEY_MESSAGE.replace(\n                    '${exchangeAddress}',\n                    exchangeInfo.exchangeAddress,\n                  ).replace('${nonce}', (account.nonce - 1).toString()),\n            walletType: connectName,\n            accountId: account.accountId,\n          })\n          if (eddsaKey.sk === _account.eddsaKey.sk) {\n            myLog('try to sendAccountSigned....')\n            setShowAccount({ isShow: false })\n            setShowExportAccount({ isShow: true })\n          } else {\n            throw {\n              code: UIERROR_CODE.ERROR_PRIVATE_KEY,\n              msg: 'Wrong private key',\n              message: 'Wrong private key',\n            }\n          }\n        } catch (error) {\n          throw error\n        }\n      } catch (e: any) {\n        myLog('ExportAccount e:', e)\n        const error = LoopringAPI.exchangeAPI.genErr(e)\n        const errType = sdk.checkErrorInfo(error, true)\n        switch (errType) {\n          case sdk.ConnectorError.USER_DENIED:\n          case sdk.ConnectorError.USER_DENIED_2:\n            setShowAccount({\n              isShow: true,\n              step: AccountStep.ExportAccount_User_Denied,\n            })\n            return\n          default:\n            break\n        }\n        setShowAccount({\n          isShow: true,\n          step: AccountStep.ExportAccount_Failed,\n          error: {\n            code: UIERROR_CODE.UNKNOWN,\n            msg: e?.message,\n            ...e,\n          },\n        })\n      }\n    }\n  }, [setShowAccount, setShowExportAccount])\n\n  return {\n    exportAccInfo,\n    exportAccount,\n  }\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/Layer2Page/SecurityPanel/index.tsx",
    "content": "import styled from '@emotion/styled'\nimport { Box, Button, Container, Divider, Grid, Typography } from '@mui/material'\nimport React from 'react'\nimport { Trans, WithTranslation, withTranslation } from 'react-i18next'\nimport { useExportAccountInfo, useResetAccount } from './hook'\nimport {\n  MaxWidthContainer,\n  useOpenModals,\n  useSettings,\n  useToggle,\n} from '@loopring-web/component-lib'\nimport { useAccount } from '@loopring-web/core'\nimport { useHistory } from 'react-router-dom'\nimport {\n  ProfileIndex,\n  MapChainId,\n  Layer2RouterID,\n  L1L2_NAME_DEFINED,\n} from '@loopring-web/common-resources'\n\nconst StyledPaper = styled(Grid)`\n  width: 100%;\n  height: 100%;\n  background: var(--color-box);\n  border-radius: ${({ theme }) => theme.unit}px;\n`\n\nconst StyledDivider = styled(Divider)`\n  margin: ${({ theme }) => theme.unit}px ${({ theme }) => (theme.unit * 5) / 2}px;\n`\n\nexport const SecurityPanel = withTranslation(['common', 'layout'])(({ t }: WithTranslation) => {\n  const { account } = useAccount()\n  const { resetKeypair } = useResetAccount()\n  const { setShowFeeSetting } = useOpenModals()\n  const { exportAccount } = useExportAccountInfo()\n  const history = useHistory()\n  const { setShowAccount } = useOpenModals()\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const { toggle } = useToggle()\n\n  return (\n    <>\n      <MaxWidthContainer\n        background={'var(--color-global-bg)'}\n        display={'flex'}\n        justifyContent={'space-between'}\n        paddingY={2}\n      >\n        <Typography component={'h3'} variant={'h5'} paddingX={5 / 2}>\n          {t('labelSecurity')}\n        </Typography>\n      </MaxWidthContainer>\n      <Divider />\n      <MaxWidthContainer\n        background={'var(--color-pop-bg)'}\n        display={'flex'}\n        justifyContent={'space-between'}\n        paddingY={2}\n      >\n        <Box flex={1} display={'flex'} flexDirection={'column'}>\n          <StyledPaper container marginBottom={2}>\n            <Grid item xs={12} display={'flex'} flexDirection={'row'} alignItems={'center'}></Grid>\n            <Grid item xs={12} display={'flex'} flexDirection={'column'} paddingY={1}>\n              {!account.isContract && !account.isInCounterFactualStatus && (\n                <Box\n                  component={'section'}\n                  display={'flex'}\n                  flexDirection={'column'}\n                  padding={5 / 2}\n                >\n                  <Grid container display={'flex'}>\n                    <Grid item xs={7}>\n                      <Typography\n                        variant={'h4'}\n                        color={'text.primary'}\n                        component={'h4'}\n                        marginBottom={1}\n                      >\n                        {t('labelTitleResetL2Keypair', {\n                          loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                        })}\n                      </Typography>\n                      <Typography variant={'body1'} color={'text.secondary'} component={'p'}>\n                        <Trans\n                          i18nKey='labelResetDescription'\n                          tOptions={{\n                            layer2: L1L2_NAME_DEFINED[network].layer2,\n                            loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                          }}\n                        >\n                          Create a new signing key for layer-2 authentication (no backup needed).\n                          This will\n                          <Typography component={'span'}>cancel all your pending orders</Typography>\n                          .\n                        </Trans>\n                      </Typography>\n                    </Grid>\n\n                    <Grid\n                      item\n                      xs={5}\n                      display={'flex'}\n                      justifyContent={'flex-start'}\n                      alignItems={'flex-end'}\n                      flexDirection={'column'}\n                    >\n                      <Button\n                        variant={'outlined'}\n                        size={'medium'}\n                        color={'primary'}\n                        onClick={() => {\n                          resetKeypair()\n                        }}\n                        disabled={false}\n                      >\n                        {t('labelBtnReset')}\n                      </Button>\n                    </Grid>\n                  </Grid>\n                </Box>\n              )}\n              <StyledDivider />\n              <Box component={'section'} display={'flex'} flexDirection={'column'} padding={5 / 2}>\n                <Grid container display={'flex'}>\n                  <Grid item xs={7}>\n                    <Typography\n                      variant={'h4'}\n                      color={'text.primary'}\n                      component={'h4'}\n                      marginBottom={1}\n                    >\n                      {t('labelTitleExportAccount')}\n                    </Typography>\n                    <Typography variant={'body1'} color={'text.secondary'} component={'p'}>\n                      {t('labelDescriptionExportAccount', {\n                        loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n                        loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                        l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                        l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                        ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                      })}\n                    </Typography>\n                  </Grid>\n                  <Grid\n                    item\n                    xs={5}\n                    display={'flex'}\n                    justifyContent={'flex-start'}\n                    alignItems={'flex-end'}\n                    flexDirection={'column'}\n                  >\n                    <Button\n                      onClick={() => {\n                        // exportAccInfo()\n                        exportAccount()\n                      }}\n                      variant={'outlined'}\n                      size={'medium'}\n                      color={'primary'}\n                      disabled={false}\n                    >\n                      {t('labelBtnExportAccount')}\n                    </Button>\n                  </Grid>\n                </Grid>\n              </Box>\n              <StyledDivider />\n              <Box component={'section'} display={'flex'} flexDirection={'column'} padding={5 / 2}>\n                <Grid\n                  container\n                  display={'flex'}\n                  flexDirection={'row'}\n                  justifyContent={'stretch'}\n                  alignItems={'flex-start'}\n                >\n                  <Grid item xs={7} display={'flex'} flexDirection={'column'}>\n                    <Typography\n                      variant={'h4'}\n                      color={'text.primary'}\n                      component={'h4'}\n                      marginBottom={1}\n                    >\n                      {t('labelSettingFee')}\n                    </Typography>\n                    <Typography variant={'body1'} color={'text.secondary'} component={'p'}>\n                      {t('descriptionSettingFee')}\n                    </Typography>\n                  </Grid>\n                  <Grid\n                    item\n                    xs={5}\n                    display={'flex'}\n                    flexDirection={'column'}\n                    justifyContent={'flex-start'}\n                    alignItems={'flex-end'}\n                    alignSelf={'stretch'}\n                  >\n                    <Grid item>\n                      <Button\n                        onClick={() => {\n                          // exportAccInfo()\n                          setShowFeeSetting({ isShow: true })\n                        }}\n                        variant={'outlined'}\n                        size={'medium'}\n                        color={'primary'}\n                        disabled={false}\n                      >\n                        {t('labelBtnEdit')}\n                      </Button>\n                    </Grid>\n                  </Grid>\n                </Grid>\n              </Box>\n              {ProfileIndex[network]?.includes(Layer2RouterID.forcewithdraw) && (\n                <>\n                  <StyledDivider />\n                  <Box\n                    component={'section'}\n                    display={'flex'}\n                    flexDirection={'column'}\n                    padding={5 / 2}\n                  >\n                    <Grid\n                      container\n                      display={'flex'}\n                      flexDirection={'row'}\n                      justifyContent={'stretch'}\n                      alignItems={'flex-start'}\n                    >\n                      <Grid item xs={7} display={'flex'} flexDirection={'column'}>\n                        <Typography\n                          variant={'h4'}\n                          color={'text.primary'}\n                          component={'h4'}\n                          marginBottom={1}\n                        >\n                          {t('labelForceWithdrawTitle')}\n                        </Typography>\n                        <Typography variant={'body1'} color={'text.secondary'} component={'p'}>\n                          {t('labelForceWithdrawDes', {\n                            layer2: L1L2_NAME_DEFINED[network].layer2,\n                            l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n                            loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                            l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                            l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                            ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                          })}\n                        </Typography>\n                      </Grid>\n                      <Grid\n                        item\n                        xs={5}\n                        display={'flex'}\n                        flexDirection={'column'}\n                        justifyContent={'flex-start'}\n                        alignItems={'flex-end'}\n                        alignSelf={'stretch'}\n                      >\n                        <Grid item>\n                          <Button\n                            onClick={() => {\n                              // exportAccInfo()\n                              setShowAccount({\n                                isShow: false,\n                                info: { lastFailed: undefined },\n                              })\n                              history.push(`/layer2/forcewithdraw`)\n                            }}\n                            variant={'outlined'}\n                            size={'medium'}\n                            color={'primary'}\n                            disabled={false}\n                          >\n                            {t('labelForceWithdrawBtn')}\n                          </Button>\n                        </Grid>\n                      </Grid>\n                    </Grid>\n                  </Box>\n                </>\n              )}\n              <StyledDivider />\n              {!!toggle?.isSupperUser?.length && (\n                <Box\n                  component={'section'}\n                  display={'flex'}\n                  flexDirection={'column'}\n                  padding={5 / 2}\n                >\n                  <Grid\n                    container\n                    display={'flex'}\n                    flexDirection={'row'}\n                    justifyContent={'stretch'}\n                    alignItems={'flex-start'}\n                  >\n                    <Grid item xs={7} display={'flex'} flexDirection={'column'}>\n                      <Typography component={'h3'} variant={'h4'} marginBottom={1}>\n                        {t('labelSuperUserTitle')}\n                      </Typography>\n                      <Typography variant={'body1'} color={'text.secondary'} component={'p'}>\n                        {t('labelFunctionList', {\n                          loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                        })}\n                        {toggle?.isSupperUser?.map((item: any, index: number) => {\n                          return (\n                            <Typography\n                              variant={'body1'}\n                              color={'text.secondary'}\n                              component={'span'}\n                              paddingLeft={1}\n                            >\n                              {item.toString() +\n                                (index + 1 != toggle?.isSupperUser?.length ? ', ' : '')}\n                            </Typography>\n                          )\n                        })}\n                      </Typography>\n                    </Grid>\n                  </Grid>\n                </Box>\n              )}\n            </Grid>\n          </StyledPaper>\n        </Box>\n      </MaxWidthContainer>\n    </>\n    // <Container\n    //   maxWidth='lg'\n    //   style={{\n    //     display: 'flex',\n    //     flexDirection: 'column',\n    //     flex: 1,\n    //   }}\n    // >\n    //   <Box display={'flex'} flex={1} alignItems={'stretch'} flexDirection={'column'} marginTop={3}>\n    //\n    //   </Box>\n    // </Container>\n  )\n})\n"
  },
  {
    "path": "packages/webapp/src/pages/Layer2Page/VipPanel/hooks.ts",
    "content": "import React from 'react'\nimport { LoopringAPI, useAccount, useTokenMap } from '@loopring-web/core'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { myLog } from '@loopring-web/common-resources'\n\nexport function useGetVIPInfo() {\n  const {\n    account: { accountId, accAddress, apiKey },\n  } = useAccount()\n  const [tradeAmountInfo, setTraeAmountInfo] = React.useState<any>(null)\n  const [userVIPInfo, setUserVIPInfo] = React.useState<any>(null)\n  const [userAssets, setUserAssets] = React.useState<any[]>([])\n\n  const { tokenMap } = useTokenMap()\n\n  const getUserTradeAmount = React.useCallback(\n    async (markets: string = '', limit: number = 30) => {\n      if (LoopringAPI && LoopringAPI.exchangeAPI && accountId) {\n        const data = await LoopringAPI.exchangeAPI.getUserTradeAmount({\n          accountId,\n          markets,\n          limit,\n        })\n        setTraeAmountInfo(data)\n      }\n    },\n    [accountId],\n  )\n\n  const getUserVIPInfo = React.useCallback(async () => {\n    if (LoopringAPI && LoopringAPI.userAPI && accountId) {\n      const data = await LoopringAPI.userAPI.getUserVIPInfo(\n        {\n          userAddress: accAddress,\n        },\n        apiKey,\n      )\n      setUserVIPInfo(data)\n    }\n  }, [accAddress, accountId, apiKey])\n\n  const getUserAssets = React.useCallback(async () => {\n    if (LoopringAPI && LoopringAPI.userAPI && tokenMap) {\n      const lrcAddress = tokenMap['LRC'].address\n      const response = await LoopringAPI.userAPI.getUserVIPAssets({\n        address: accAddress,\n        assetTypes: 'DEX',\n        token: lrcAddress,\n      })\n      if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n        myLog((response as sdk.RESULT_INFO).message)\n      } else {\n        setUserAssets(response.vipAsset as any[])\n      }\n    }\n    setUserAssets([])\n  }, [accAddress, tokenMap])\n\n  return {\n    tradeAmountInfo,\n    getUserTradeAmount,\n    userVIPInfo,\n    getUserVIPInfo,\n    userAssets,\n    getUserAssets,\n  }\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/Layer2Page/VipPanel/index.tsx",
    "content": "import styled from '@emotion/styled'\nimport { Box, Divider, Grid, LinearProgress, Link, Typography } from '@mui/material'\nimport React from 'react'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport { useHistory } from 'react-router-dom'\nimport { LoopringAPI, useAccount, useTokenMap, useWalletLayer2 } from '@loopring-web/core'\nimport { getValuePrecisionThousand, SoursURL ,RouterPath} from '@loopring-web/common-resources'\nimport { MaxWidthContainer, useSettings, VipPanel as VipView } from '@loopring-web/component-lib'\nimport { useGetVIPInfo } from './hooks'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nconst StyledPaper = styled(Grid)`\n  width: 100%;\n  height: 100%;\n  background: var(--color-box);\n  border-radius: ${({ theme }) => theme.unit}px;\n`\n\nconst feeRate = {\n  vip1: {\n    eth: 75,\n    lrc: 25000,\n  },\n  vip2: {\n    eth: 750,\n    lrc: 50000,\n  },\n  vip3: {\n    eth: 3750,\n    lrc: 125000,\n  },\n  vip4: {\n    eth: 7500,\n    lrc: 250000,\n  },\n}\n\nconst rawData = [\n  {\n    level: 'VIP 0',\n    tradeVolume: '< 75 ETH',\n    rule: 'or',\n    balance: '>= 0 LRC',\n    maker: '-0.02%',\n    taker: '0.3%',\n  },\n  {\n    level: 'VIP 1',\n    tradeVolume: '>= 75 ETH',\n    rule: 'or',\n    balance: '>= 25,000 LRC',\n    maker: '-0.02%',\n    taker: '0.25%',\n  },\n  {\n    level: 'VIP 2',\n    tradeVolume: '>= 750 ETH',\n    rule: 'and',\n    balance: '>= 50,000 LRC',\n    maker: '-0.02%',\n    taker: '0.2%',\n  },\n  {\n    level: 'VIP 3',\n    tradeVolume: '>= 3750 ETH',\n    rule: 'and',\n    balance: '>= 125,000 LRC',\n    maker: '-0.02%',\n    taker: '0.15%',\n  },\n  {\n    level: 'VIP 4',\n    tradeVolume: '>= 7500 ETH',\n    rule: 'and',\n    balance: '>= 250,000 LRC',\n    maker: '-0.02%',\n    taker: '0.1%',\n  },\n]\n\nexport const VipPanel = withTranslation(['common', 'layout'])(({ t }: WithTranslation) => {\n  const {\n    account: { level },\n  } = useAccount()\n  const history = useHistory()\n  const { isMobile } = useSettings()\n  const { tokenMap } = useTokenMap()\n  const { walletLayer2 } = useWalletLayer2()\n  const currentBalanceLRC = sdk\n    .toBig(walletLayer2?.LRC?.total ?? 0)\n    .div('1e' + tokenMap?.LRC?.decimals ?? 0)\n    .toNumber()\n  const { getUserTradeAmount, tradeAmountInfo, userVIPInfo, getUserVIPInfo, getUserAssets } =\n    useGetVIPInfo()\n\n  const getVIPLevel = React.useCallback(() => {\n    if (userVIPInfo && userVIPInfo?.vipInfo?.vipTag) {\n      if (userVIPInfo.vipInfo.vipTag === 'spam') {\n        return 'vip_0'\n      }\n      return userVIPInfo.vipInfo.vipTag\n    }\n    return 'vip_0'\n  }, [userVIPInfo])\n\n  const getNextVIPlevel = React.useCallback(() => {\n    const level = getVIPLevel()\n    if (level === 'super_vip' || level === 'vip_4') {\n      return level\n    }\n    let [_, number] = getVIPLevel().toUpperCase().replace('_', ',').split(',')\n    return `${++number}`\n  }, [getVIPLevel])\n\n  const getViewTableLevel = React.useCallback(() => {\n    if (!getVIPLevel()) {\n      return 0\n    }\n    if (getVIPLevel() === 'super_vip' || getVIPLevel() === 'vip_4') {\n      return 4\n    }\n    let [_, number] = getVIPLevel().toUpperCase().replace('_', ',').split(',')\n    return number\n  }, [getVIPLevel])\n\n  const getCurrentETHTradeAmount = React.useCallback(() => {\n    if (tradeAmountInfo && !!tradeAmountInfo.raw_data.data.length) {\n      const sum: number[] = tradeAmountInfo.raw_data.data.map((o: any) => Number(o.ethValue))\n      return sum.reduce((prev, next) => prev + next, 0).toFixed(7)\n    }\n    return 0\n  }, [tradeAmountInfo])\n\n  // const [vipTable, setVipTable] = React.useState<string[][]>(vipDefault);\n  const [userFee, setUserFee] = React.useState<{\n    maker: string\n    taker: string\n  }>({\n    maker: '0',\n    taker: '0.0025%',\n  })\n\n  const isVIP4 = getVIPLevel() === 'vip_4'\n  const isSVIP = getVIPLevel() === 'super_vip'\n\n  const getNextLevelAmount = React.useCallback(\n    (type: 'lrc' | 'eth', currLevel: number) => {\n      const isLrc = type === 'lrc'\n      const amount = Math.round(\n        feeRate[`vip${currLevel}`][type] -\n          (isLrc ? currentBalanceLRC : Number(getCurrentETHTradeAmount())),\n      )\n      return amount < 0 ? 0 : amount\n    },\n    [currentBalanceLRC, getCurrentETHTradeAmount],\n  )\n\n  const getImagePath = React.useMemo(() => {\n    const path = SoursURL + `images/vips/${level.toUpperCase().replace('_', '')}`\n    return (\n      <img\n        alt='VIP'\n        style={{\n          verticalAlign: 'text-bottom',\n          width: '32px',\n          height: '16px',\n        }}\n        src={`${path}.webp`}\n        // srcSet={`${path}.webp 1x, ${path}.png 1x`}\n      />\n    )\n  }, [level])\n  const result = React.useCallback(async () => {\n    if (LoopringAPI.exchangeAPI) {\n      const {\n        // orderbookTradingFeesStablecoin,\n        orderbookTradingFees,\n        // ammTradingFees,\n        // otherFees,\n      } = await LoopringAPI.exchangeAPI.getExchangeFeeInfo()\n      const _level = level === 'super_vip' ? 'vip_4' : level === '' ? 'default' : level\n      if (orderbookTradingFees[_level]) {\n        setUserFee({\n          maker: (orderbookTradingFees[_level].makerRate / 10000).toString() + '%',\n          taker: (orderbookTradingFees[_level].takerRate / 10000).toString() + '%',\n        })\n      }\n    }\n  }, [level])\n\n  React.useEffect(() => {\n    getUserTradeAmount()\n    getUserVIPInfo()\n    getUserAssets()\n    result()\n  }, [])\n\n  const handleTradeLinkClick = React.useCallback(() => {\n    if (history) {\n      history.push(`${RouterPath.lite}/LRC-ETH`)\n    }\n  }, [history])\n\n  const getTradeVolETHLinear = React.useMemo(() => {\n    if (isSVIP) {\n      return 0\n    }\n    if (isVIP4) {\n      return 100\n    }\n    const rate =\n      (Number(getCurrentETHTradeAmount()) / feeRate[`vip${getNextVIPlevel()}`]['eth']) * 100\n    return rate > 100 ? 100 : rate\n  }, [isVIP4, isSVIP, getCurrentETHTradeAmount, getNextVIPlevel])\n\n  const balanceLinearLRC = React.useMemo(() => {\n    if (isSVIP) {\n      return 0\n    }\n    if (isVIP4) {\n      return 100\n    }\n    const rate = (currentBalanceLRC / feeRate[`vip${getNextVIPlevel()}`]['lrc']) * 100\n    return rate > 100 ? 100 : rate\n  }, [currentBalanceLRC, getNextVIPlevel, isSVIP, isVIP4])\n\n  const getCurrVIPLevel = React.useCallback(\n    (direction: 'left' | 'right') => {\n      const isLeft = direction === 'left'\n      const isRight = direction === 'right'\n      if (getVIPLevel() !== 'super_vip' && getVIPLevel() !== 'vip_4' && isLeft) {\n        return getVIPLevel().toUpperCase().replace('_', ' ')\n      }\n      if (getVIPLevel() !== 'super_vip' && getVIPLevel() !== 'vip_4' && isRight) {\n        let [vip, number] = getVIPLevel().toUpperCase().replace('_', ',').split(',')\n        return `${vip} ${++number}`\n      }\n      if (isSVIP && direction === 'left') {\n        return 'Super VIP'\n      }\n      if (isSVIP && direction === 'right') {\n        return ''\n      }\n      if (isVIP4) {\n        return direction === 'left' ? 'VIP 3' : 'VIP 4'\n      }\n      return ''\n    },\n    [isSVIP, isVIP4, getVIPLevel],\n  )\n\n  return (\n    <>\n      <MaxWidthContainer\n        background={'var(--color-global-bg)'}\n        display={'flex'}\n        justifyContent={'space-between'}\n        paddingY={2}\n      >\n        <Typography component={'h3'} variant={'h5'} paddingX={5 / 2}>\n          {t('labelVipTitle')}\n        </Typography>\n      </MaxWidthContainer>\n      <Divider />\n      <MaxWidthContainer\n        background={'var(--color-pop-bg)'}\n        display={'flex'}\n        justifyContent={'space-between'}\n        paddingY={2}\n      >\n        <Box flex={1} display={'flex'} flexDirection={'column'}>\n          <StyledPaper\n            container\n            className={'MuiPaper-elevation2'}\n            margin={0}\n            marginBottom={2}\n            paddingBottom={5 / 2}\n            spacing={3}\n          >\n            <Grid item xs={12}>\n              <Typography\n                variant={isMobile ? 'body1' : 'h5'}\n                component={'h2'}\n                marginY={1}\n                display={'flex'}\n                flexDirection={'column'}\n              >\n                <Typography\n                  component={'div'}\n                  flexDirection={'row'}\n                  display={'flex'}\n                  alignSelf={'flex-start'}\n                >\n                  <Typography\n                    component={'p'}\n                    variant={isMobile ? 'h5' : 'h4'}\n                    color={'text.primary'}\n                    paddingRight={1}\n                  >\n                    {t('labelTradeFeeLevel')}\n                  </Typography>\n                  <Typography\n                    variant={'body1'}\n                    component={'span'}\n                    display={'flex'}\n                    flexDirection={'row'}\n                    alignItems={'center'}\n                  >\n                    <Typography component={'span'} variant={'body1'}>\n                      {level && userVIPInfo?.vipInfo?.vipTag ? getImagePath : ''}\n                    </Typography>\n                  </Typography>\n                </Typography>\n                <Typography\n                  variant={isMobile ? 'body1' : 'h5'}\n                  component={'p'}\n                  color={'var(--color-text-secondary)'}\n                  marginTop={2}\n                >\n                  {isVIP4\n                    ? 'Congratulations you have reached the highest level'\n                    : isSVIP\n                    ? 'Congratulations! You are already a super VIP, enjoying the highest discount privileges, and will not be affected by balance and trading volume.'\n                    : `Upgrade to VIP ${getNextVIPlevel()} by either trading ${getValuePrecisionThousand(\n                        getNextLevelAmount('eth', getNextVIPlevel()),\n                      )} ETH on our spot exchange and/or increase your LRC holdings by ${getValuePrecisionThousand(\n                        getNextLevelAmount('lrc', getNextVIPlevel()),\n                      )} LRC`}\n                </Typography>\n              </Typography>\n            </Grid>\n            <Grid item xs={12} md={6}>\n              <Typography fontWeight={400} variant={'h6'} color={'var(--color-text-secondary)'}>\n                {t('labelSpotTrading')}\n              </Typography>\n              <Typography\n                display={'inline-flex'}\n                justifyContent={'space-between'}\n                alignItems={'center'}\n                width={'100%'}\n                paddingRight={2}\n              >\n                <Typography variant={isMobile ? 'h5' : 'h4'} marginTop={0.5}>\n                  {t('labelCurrentlyLevel', {\n                    value: getValuePrecisionThousand(getCurrentETHTradeAmount()),\n                    token: 'ETH',\n                  })}\n                </Typography>\n                {isMobile && (\n                  <Link\n                    variant={'body1'}\n                    onClick={handleTradeLinkClick}\n                    style={{\n                      textDecoration: 'underline',\n                      color: 'var(--color-text-secondary)',\n                    }}\n                  >\n                    {t('labelTradeSpot')}\n                  </Link>\n                )}\n              </Typography>\n              <Box width={'100%'} paddingRight={2} marginY={1.5}>\n                <LinearProgress variant='determinate' value={getTradeVolETHLinear} />\n                <Box marginTop={1} display={'flex'} justifyContent={'space-between'}>\n                  <Typography\n                    fontWeight={400}\n                    color={isVIP4 ? 'var(--color-text-secondary)' : 'var(--color-star)'}\n                  >\n                    {getCurrVIPLevel('left')}\n                  </Typography>\n                  <Typography\n                    fontWeight={400}\n                    color={isSVIP || isVIP4 ? 'var(--color-star)' : 'var(--color-text-secondary)'}\n                  >\n                    {getCurrVIPLevel('right')}\n                  </Typography>\n                </Box>\n              </Box>\n              {!isMobile && (\n                <Link\n                  variant={'body1'}\n                  onClick={handleTradeLinkClick}\n                  style={{\n                    textDecoration: 'underline',\n                    color: 'var(--color-text-secondary)',\n                  }}\n                >\n                  {t('labelTradeSpot')}\n                </Link>\n              )}\n            </Grid>\n            <Grid item xs={12} md={6}>\n              <Typography fontWeight={400} variant={'h6'} color={'var(--color-text-secondary)'}>\n                {t('labelLRCBalance')}\n              </Typography>\n              <Typography\n                display={'inline-flex'}\n                justifyContent={'space-between'}\n                alignItems={'center'}\n                width={'100%'}\n                paddingRight={2}\n              >\n                <Typography variant={isMobile ? 'h5' : 'h4'} marginTop={0.5}>\n                  {t('labelCurrentlyLevel', {\n                    value: getValuePrecisionThousand(\n                      currentBalanceLRC,\n                      tokenMap?.LRC.precision,\n                      tokenMap?.LRC.precision,\n                      tokenMap?.LRC.precision,\n                      false,\n                      { floor: true },\n                    ),\n                    token: 'LRC',\n                  })}\n                </Typography>\n                {isMobile && (\n                  <Link\n                    variant={'body1'}\n                    onClick={handleTradeLinkClick}\n                    style={{\n                      textDecoration: 'underline',\n                      color: 'var(--color-text-secondary)',\n                    }}\n                  >\n                    {t('labelBuyToken', { token: 'LRC' })}\n                  </Link>\n                )}\n              </Typography>\n              <Box width={'100%'} paddingRight={2} marginY={1.5}>\n                <LinearProgress variant='determinate' value={balanceLinearLRC} />\n                <Box marginTop={1} display={'flex'} justifyContent={'space-between'}>\n                  <Typography\n                    fontWeight={400}\n                    color={isVIP4 ? 'var(--color-text-secondary)' : 'var(--color-star)'}\n                  >\n                    {getCurrVIPLevel('left')}\n                  </Typography>\n                  <Typography\n                    fontWeight={400}\n                    color={isSVIP || isVIP4 ? 'var(--color-star)' : 'var(--color-text-secondary)'}\n                  >\n                    {getCurrVIPLevel('right')}\n                  </Typography>\n                </Box>\n              </Box>\n              {!isMobile && (\n                <Link\n                  variant={'body1'}\n                  onClick={handleTradeLinkClick}\n                  style={{\n                    textDecoration: 'underline',\n                    color: 'var(--color-text-secondary)',\n                  }}\n                >\n                  {t('labelBuyToken', { token: 'LRC' })}\n                </Link>\n              )}\n            </Grid>\n            <Grid item xs={12}>\n              <Typography\n                variant={'h6'}\n                component={'p'}\n                fontWeight={400}\n                color={'var(--color-text-secondary)'}\n              >\n                The cumulative 30-day trading volume ( in ETH ) and 24-hour LRC balance are updated\n                at 0:00 (UTC+0) each day. After the update, you can access the corresponding fee\n                discount in the table below.\n              </Typography>\n            </Grid>\n          </StyledPaper>\n          {isMobile ? (\n            <Typography variant={'body1'} paddingY={2} textAlign={'center'}>\n              For details, please view on desktop.\n            </Typography>\n          ) : (\n            <StyledPaper\n              container\n              className={'MuiPaper-elevation2'}\n              margin={0}\n              marginBottom={2}\n              spacing={3}\n            >\n              <Grid item xs={12}>\n                <Typography\n                  component={'h4'}\n                  variant={isMobile ? 'h6' : 'h5'}\n                  color={'text.secondary'}\n                >\n                  {t('labelFeeTitleList')}\n                </Typography>\n              </Grid>\n              <Grid item xs={12} paddingRight={2}>\n                <VipView rawData={rawData} currentLevel={getViewTableLevel()} />\n              </Grid>\n            </StyledPaper>\n          )}\n        </Box>\n      </MaxWidthContainer>\n    </>\n  )\n})\n"
  },
  {
    "path": "packages/webapp/src/pages/Layer2Page/index.tsx",
    "content": "import { useRouteMatch } from 'react-router-dom'\n\nimport { Box } from '@mui/material'\n\nimport React from 'react'\nimport { ViewAccountTemplate } from '@loopring-web/core'\nimport { SecurityPanel } from './SecurityPanel'\nimport { VipPanel } from './VipPanel'\nimport { ForcewithdrawPanel } from './ForcewithdrawPanel'\nimport { ReferralRewardsPanel } from './ReferralRewardsPanel'\nimport { ContactPage } from './ContactPanel'\nimport { Layer2RouterID, ProfileIndex, MapChainId } from '@loopring-web/common-resources'\nimport { useSettings } from '@loopring-web/component-lib'\nimport { NotificationPanel } from './Notification'\n\nexport const Layer2Page = () => {\n  let match: any = useRouteMatch('/layer2/:item')\n  const selected = match?.params.item ?? 'vip'\n  const { defaultNetwork } = useSettings()\n\n  const layer2Router = React.useMemo(() => {\n    let _selected\n    const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n    if (ProfileIndex[network]?.includes(selected)) {\n      _selected = selected\n    } else {\n      _selected = ''\n    }\n    switch (_selected) {\n      case Layer2RouterID.forcewithdraw:\n        return <ForcewithdrawPanel />\n      case Layer2RouterID.security:\n        return <SecurityPanel />\n      case Layer2RouterID.vip:\n        return <VipPanel />\n      case Layer2RouterID.contact:\n        return <ContactPage />\n      case Layer2RouterID.notification:\n        return <NotificationPanel />\n      default:\n        return <SecurityPanel />\n    }\n  }, [selected])\n\n  return selected === Layer2RouterID.referralrewards ? (\n    <Box flex={1} display={'flex'} flexDirection={'column'}>\n      <ReferralRewardsPanel />\n    </Box>\n  ) : (\n    <ViewAccountTemplate activeViewTemplate={layer2Router} />\n  )\n  // <>{viewTemplate}</>;\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/LoadingPage/index.tsx",
    "content": "import { useTranslation } from 'react-i18next'\nimport { Box } from '@mui/material'\nimport styled from '@emotion/styled'\n// import { ErrorObject } from '@loopring-web/common-resources';\n// import { getContactInfo } from '../../utils/dt_tools';\nimport { boxLiner } from '@loopring-web/component-lib'\nimport { SoursURL } from '@loopring-web/common-resources'\nimport React from 'react'\n// ${({theme}) => boxLiner({theme})}\nconst StyleBox = styled(Box)`\n  ${({ theme }) => boxLiner({ theme })}\n\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  left: 0;\n  right: 0;\n  width: 0;\n  z-index: 500;\n  height: 100%;\n  width: 100%;\n  svg path,\n  svg rect {\n    fill: var(--color-primary);\n  }\n` as typeof Box\n\nexport const LoadingPage = () => {\n  const { t } = useTranslation('layout')\n  return (\n    <>\n      <StyleBox\n        flex={1}\n        display={'flex'}\n        alignItems={'center'}\n        justifyContent={'center'}\n        flexDirection={'column'}\n        height={'100%'}\n        width={'100%'}\n      >\n        <div className='loader loader--style3' title='2'>\n          <img\n            className='loading-gif'\n            alt={'loading'}\n            width='36'\n            src={`${SoursURL}images/loading-line.gif`}\n          />\n        </div>\n      </StyleBox>\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/MarkdownPage/index.tsx",
    "content": "import { Box, Grid } from '@mui/material'\nimport { useRouteMatch, useLocation } from 'react-router-dom'\nimport React from 'react'\nimport { EmptyDefault, LoadingBlock } from '@loopring-web/component-lib'\nimport Template from 'easy-template-string'\nimport gfm from 'remark-gfm'\nimport ReactMarkdown from 'react-markdown'\nimport { useTheme } from '@emotion/react'\n\nimport { useTranslation } from 'react-i18next'\nimport { MarkdownStyle } from '@loopring-web/common-resources'\nimport { useAppKit, useAppKitState } from '@reown/appkit/react'\n\nconst url_path = 'https://static.loopring.io/documents'\n\nconst formatInput = async (textContent: string): Promise<string> => {\n  // let [data, content] = args;\n  const data = await fetch('https://api3.loopring.io/api/v2/exchange/feeInfo')\n    .then((res) => res.json())\n    .then((data) => data.data)\n  let { ORDERBOOK_TRADING_FEES_STABLECOIN, ORDERBOOK_TRADING_FEES, AMM_TRADING_FEES } = data\n  ORDERBOOK_TRADING_FEES_STABLECOIN = Object.keys(ORDERBOOK_TRADING_FEES_STABLECOIN).reduce(\n    (pre, key) => {\n      pre['ORDERBOOK_TRADING_FEES_STABLECOIN.' + key] = (\n        ORDERBOOK_TRADING_FEES_STABLECOIN[key].takerRate / 100\n      ).toFixed(2)\n      return pre\n    },\n    {},\n  )\n  ORDERBOOK_TRADING_FEES = Object.keys(ORDERBOOK_TRADING_FEES).reduce((pre, key) => {\n    pre['ORDERBOOK_TRADING_FEES.' + key] = (ORDERBOOK_TRADING_FEES[key].takerRate / 100).toFixed(2)\n    return pre\n  }, {})\n  AMM_TRADING_FEES = Object.keys(AMM_TRADING_FEES).reduce((pre, key) => {\n    pre['AMM_TRADING_FEES.' + key] = (AMM_TRADING_FEES[key].takerRate / 100).toFixed(2)\n    return pre\n  }, {})\n  const template1 = new Template(textContent)\n  return template1.interpolate({\n    ...ORDERBOOK_TRADING_FEES_STABLECOIN,\n    ...ORDERBOOK_TRADING_FEES,\n    ...AMM_TRADING_FEES,\n  })\n}\nconst list = ['wallet_fees_zh.md', 'wallet_fees_en.md', 'dex_fees_en.md', 'dex_fees_zh.md']\nexport const MarkdownPage = () => {\n  const location = useLocation()\n  const path = location.pathname.split('/').slice(2).join('/')\n  const [input, setInput] = React.useState<string>('')\n  const { t } = useTranslation('common')\n  React.useEffect(() => {\n    if (path) {\n      try {\n        const _path = `markdown/${path}`\n        fetch(url_path + '/' + _path)\n          .then((response) => response.text())\n          .then((input) => {\n            if (list.findIndex((f) => f === path) !== -1) {\n              return formatInput(input)\n            } else {\n              return input\n            }\n          })\n          .then((input) => {\n            setInput(input)\n          })\n          .catch(() => {})\n      } catch (e: any) {}\n    }\n  }, [path])\n  const theme = useTheme()\n  const { close } = useAppKit()\n  const { open } = useAppKitState()\n  React.useEffect(() => {\n    open && close()\n  }, [open])\n\n  return (\n    <MarkdownStyle\n      container\n      minHeight={'calc(100% - 260px)'}\n      flex={1}\n      marginTop={3}\n      marginBottom={2}\n    >\n      <Grid item xs={12}>\n        {path ? (\n          input ? (\n            <Box\n              flex={1}\n              padding={3}\n              boxSizing={'border-box'}\n              className={`${theme.mode}  ${theme.mode}-scheme markdown-body MuiPaper-elevation2`}\n            >\n              <ReactMarkdown remarkPlugins={[gfm]} children={input} />\n            </Box>\n          ) : (\n            <LoadingBlock />\n          )\n        ) : (\n          <EmptyDefault\n            height={'100%'}\n            message={() => (\n              <Box flex={1} display={'flex'} alignItems={'center'} justifyContent={'center'}>\n                {t('labelNoContent')}\n              </Box>\n            )}\n          />\n        )}\n      </Grid>\n    </MarkdownStyle>\n  )\n}\n\nexport * from './notifyMarkdown'\nexport * from './investMarkdown'\n"
  },
  {
    "path": "packages/webapp/src/pages/MarkdownPage/investMarkdown.tsx",
    "content": "// import { Box, Grid } from '@mui/material'\n// import { useLocation, useRouteMatch } from 'react-router-dom'\nimport React from 'react'\n// import { EmptyDefault, LoadingBlock } from '@loopring-web/component-lib'\n// import gfm from 'remark-gfm'\n// import ReactMarkdown from 'react-markdown'\n// import { useTheme } from '@emotion/react'\n//\n// import {\n//   InvestAssetRouter,\n//   MarkdownStyle,\n//   RouterPath,\n//   url_test_path,\n// } from '@loopring-web/common-resources'\n// import { useTranslation } from 'react-i18next'\n// import { useNotify, useSystem } from '@loopring-web/core'\n//\n// const url_path = 'https://static.loopring.io/documents/notification'\n// const InvestRouter = `/investrule/:type`\n\nexport const InvestMarkdownPage = () => {\n  return <></>\n  // let match: any = useRouteMatch(InvestRouter)\n  // const { i18n, t } = useTranslation()\n  // const { search } = useLocation()\n  // const { notifyMap } = useNotify()\n  // const searchParams = new URLSearchParams(search)\n  // const { baseURL } = useSystem()\n  // // const history = useHistory();\n  //\n  // const [input, setInput] = React.useState<string>('')\n  // //\n  // const [path, setPath] = React.useState<null | string>(match?.params?.type)\n  // React.useEffect(() => {\n  //   if (baseURL) {\n  //     try {\n  //       // follow /2021/01/2021-01-01.en.json\n  //       const [year, month] = match?.params.type.split('-')\n  //       const type = searchParams.get('type')\n  //       const index =\n  //         notifyMap?.invest.investAdvice.findIndex((invest) => invest.type === type) ?? -1\n  //       let filePath = ''\n  //       if (notifyMap?.invest && index >= 0) {\n  //         filePath = notifyMap.invest[index].linkRule\n  //       } else {\n  //         const path = `${/uat/gi.test(baseURL) ? url_test_path : url_path}/${year}/${month}/`\n  //         filePath = `${path}/invest/${type}_rule.en.md`\n  //       }\n  //       if (year && month && filePath !== '') {\n  //         fetch(filePath)\n  //           .then((response) => response.text())\n  //           .then((input) => {\n  //             setInput(input)\n  //           })\n  //           .catch((e) => {\n  //             setPath(null)\n  //           })\n  //       } else {\n  //         throw 'url format wrong'\n  //       }\n  //     } catch (e: any) {\n  //       setPath(null)\n  //     }\n  //   }\n  // }, [baseURL, i18n.language])\n  //\n  // const theme = useTheme()\n  //\n  // return (\n  //   <MarkdownStyle\n  //     container\n  //     minHeight={'calc(100% - 260px)'}\n  //     flex={1}\n  //     marginTop={3}\n  //     marginBottom={2}\n  //   >\n  //     <Grid item xs={12}>\n  //       {path ? (\n  //         input ? (\n  //           <Box\n  //             flex={1}\n  //             padding={3}\n  //             boxSizing={'border-box'}\n  //             className={`${theme.mode}  ${theme.mode}-scheme markdown-body MuiPaper-elevation2`}\n  //           >\n  //             <ReactMarkdown remarkPlugins={[gfm]} children={input} />\n  //           </Box>\n  //         ) : (\n  //           <LoadingBlock />\n  //         )\n  //       ) : (\n  //         <EmptyDefault\n  //           height={'100%'}\n  //           message={() => (\n  //             <Box flex={1} display={'flex'} alignItems={'center'} justifyContent={'center'}>\n  //               {t('labelNoContent')}\n  //             </Box>\n  //           )}\n  //         />\n  //       )}\n  //     </Grid>\n  //   </MarkdownStyle>\n  // )\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/MarkdownPage/notifyMarkdown.tsx",
    "content": "import { Box, Grid } from '@mui/material'\nimport { useRouteMatch } from 'react-router-dom'\nimport React from 'react'\nimport { EmptyDefault, LoadingBlock } from '@loopring-web/component-lib'\nimport gfm from 'remark-gfm'\nimport ReactMarkdown from 'react-markdown'\nimport { useTheme } from '@emotion/react'\n\nimport { languageMap, MarkdownStyle } from '@loopring-web/common-resources'\nimport { useTranslation } from 'react-i18next'\n\nconst url_path = 'https://static.loopring.io/documents/notification'\nexport const NotifyMarkdownPage = () => {\n  let match: any = useRouteMatch('/notification/:path')\n  const { i18n, t } = useTranslation()\n  const [input, setInput] = React.useState<string>('')\n\n  const [path, setPath] = React.useState<null | string>(match?.params.path)\n  React.useEffect(() => {\n    if (path) {\n      try {\n        const _path =\n          path.split('/').length > 1 ? path : `${path.replace('{lng}', languageMap[i18n.language])}`\n\n        fetch(url_path + '/' + _path)\n          .then((response) => response.text())\n          .then((input) => {\n            setInput(input)\n          })\n          .catch(() => {\n            setPath(null)\n          })\n      } catch (e: any) {\n        setPath(null)\n      }\n    }\n  }, [path])\n  const theme = useTheme()\n\n  return (\n    <MarkdownStyle\n      container\n      minHeight={'calc(100% - 260px)'}\n      flex={1}\n      marginTop={3}\n      marginBottom={2}\n    >\n      <Grid item xs={12}>\n        {path ? (\n          input ? (\n            <Box\n              flex={1}\n              padding={3}\n              boxSizing={'border-box'}\n              className={`${theme.mode}  ${theme.mode}-scheme markdown-body MuiPaper-elevation2`}\n            >\n              <ReactMarkdown\n                remarkPlugins={[gfm]}\n                children={input}\n                // escapeHtml={false}\n              />\n            </Box>\n          ) : (\n            <LoadingBlock />\n          )\n        ) : (\n          <EmptyDefault\n            height={'100%'}\n            message={() => (\n              <Box flex={1} display={'flex'} alignItems={'center'} justifyContent={'center'}>\n                {t('labelNoContent')}\n              </Box>\n            )}\n          />\n        )}\n      </Grid>\n    </MarkdownStyle>\n  )\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/MiningPage/hook.ts",
    "content": "import { AmmCardProps } from '@loopring-web/common-resources'\nimport { AmmPoolActivityRule, AmmPoolActivityStatus, LoopringMap } from '@loopring-web/loopring-sdk'\nimport React from 'react'\nimport {\n  LoopringAPI,\n  makeUIAmmActivityMap,\n  makeWalletLayer2,\n  store,\n  useAmmMap,\n  useUserRewards,\n} from '@loopring-web/core'\nimport { MyPoolRow } from '@loopring-web/component-lib'\n\nexport type RewardListItem = {\n  amount: string\n  time: number\n}\n\nexport const useAmmMiningUI = <R extends { [key: string]: any }, I extends { [key: string]: any }>({\n  ammActivityMap,\n}: {\n  ammActivityMap: LoopringMap<LoopringMap<AmmPoolActivityRule[]>> | undefined\n}): {\n  ammActivityViewMap: Array<AmmCardProps<I>>\n  ammRewardRecordList: RewardListItem[]\n  ammActivityPastViewMap: Array<AmmCardProps<I>>\n  getLiquidityMining: (market: string, size?: number) => Promise<void>\n  showRewardDetail: boolean\n  setShowRewardDetail: React.Dispatch<React.SetStateAction<boolean>>\n  getMyAmmShare: (market: string) => any\n} => {\n  const userRewardsMapState = useUserRewards() // store.getState().userRewardsMap\n  const { userRewardsMap, myAmmLPMap } = useUserRewards()\n  const { apiKey, accountId } = store.getState().account\n  const { tokenPrices } = store.getState().tokenPrices\n  const { tokenMap } = store.getState().tokenMap\n  const { ammMap } = useAmmMap()\n  const { walletMap: _walletMap } = makeWalletLayer2({ needFilterZero: false })\n  const [ammActivityViewMap, setAmmActivityViewMap] = React.useState<Array<AmmCardProps<I>>>([])\n  const [ammRewardRecordList, setAmmRewardRecordList] = React.useState<RewardListItem[]>([])\n  const [ammActivityPastViewMap, setAmmActivityPastViewMap] = React.useState<\n    Array<AmmCardProps<I>>\n  >([])\n  // const [ammUserRewardMap, setAmmUserRewardMap] = React.useState<AmmUserRewardMap>(\n  //     {});\n  const [showRewardDetail, setShowRewardDetail] = React.useState(false)\n\n  const getLiquidityMining = React.useCallback(\n    async (market: string, size: number = 120) => {\n      if (LoopringAPI && LoopringAPI.ammpoolAPI) {\n        const ammRewardList = await LoopringAPI.ammpoolAPI.getLiquidityMining(\n          {\n            accountId: accountId,\n            market: market,\n            size: size,\n          },\n          apiKey,\n        )\n        const { rewards } = ammRewardList\n        const formattedRes = rewards.map((o) => ({\n          amount: o.amount,\n          time: o.startAt,\n        }))\n        setAmmRewardRecordList(formattedRes)\n      }\n    },\n    [apiKey, accountId],\n  )\n\n  const getMyAmmShare = React.useCallback(\n    (market: string) => {\n      if (_walletMap && ammMap && userRewardsMap && myAmmLPMap && tokenPrices && tokenMap) {\n        const ammKey = market.replace('LP-', 'AMM-')\n        const marketKey = market.replace('LP-', '')\n        let rowData: MyPoolRow<R> = {\n          ammDetail: ammMap[ammKey],\n          ...myAmmLPMap[marketKey],\n        }\n        //\n        // const formattedPoolRow = [rawData].map((o: any) => {\n        //   const market = `LP-${o?.ammDetail?.coinAInfo.simpleName}-${o?.ammDetail?.coinBInfo.simpleName}`;\n        //   const totalAmount = o.totalLpAmount;\n        //   const totalAmmValueDollar = (tokenPrices[market] || 0) * totalAmount;\n        //   const coinA = o?.ammDetail?.coinAInfo?.simpleName;\n        //   const coinB = o?.ammDetail?.coinBInfo?.simpleName;\n        //   const precisionA = tokenMap ? tokenMap[coinA]?.precision : undefined;\n        //   const precisionB = tokenMap ? tokenMap[coinB]?.precision : undefined;\n        //\n        //   return {\n        //     ...o,\n        //     totalAmmValueDollar,\n        //     precisionA,\n        //     precisionB,\n        //   };\n        // });\n        return rowData\n      }\n      return undefined\n    },\n    [_walletMap, ammMap, tokenPrices, userRewardsMap, tokenMap],\n  )\n\n  // );\n  React.useEffect(() => {\n    if (ammActivityMap && Object.keys(ammActivityMap).length > 0) {\n      // getAmmPoolUserRewards().then((ammUserRewardMap)=>{\n      // setAmmUserRewardMap(ammUserRewardMap as AmmUserRewardMap);\n      setAmmActivityViewMap(\n        makeUIAmmActivityMap(\n          {\n            ammActivityMap,\n            ammPoolActivityStatus: [\n              AmmPoolActivityStatus.NotStarted,\n              AmmPoolActivityStatus.InProgress,\n            ],\n          },\n          userRewardsMapState.userRewardsMap,\n        ),\n      )\n      setAmmActivityPastViewMap(\n        makeUIAmmActivityMap(\n          {\n            ammActivityMap,\n            ammPoolActivityStatus: [AmmPoolActivityStatus.EndOfGame],\n          },\n          userRewardsMapState.userRewardsMap,\n        ),\n      )\n      //  })\n    }\n  }, [ammActivityMap, userRewardsMapState.userRewardsMap])\n  React.useEffect(() => {\n    if (userRewardsMapState.status === 'ERROR') {\n      userRewardsMapState.statusUnset()\n    } else if (userRewardsMapState.status === 'DONE') {\n      userRewardsMapState.statusUnset()\n      setAmmActivityViewMap(\n        makeUIAmmActivityMap(\n          {\n            ammActivityMap,\n            ammPoolActivityStatus: [\n              AmmPoolActivityStatus.NotStarted,\n              AmmPoolActivityStatus.InProgress,\n            ],\n          },\n          userRewardsMapState.userRewardsMap,\n        ),\n      )\n      setAmmActivityPastViewMap(\n        makeUIAmmActivityMap(\n          {\n            ammActivityMap,\n            ammPoolActivityStatus: [AmmPoolActivityStatus.EndOfGame],\n          },\n          userRewardsMapState.userRewardsMap,\n        ),\n      )\n      // if (userRewardsMapState.ammMap) {\n      //     setAmmActivityViewMap(\n      //         makeUIAmmActivityMap(\n      //             {\n      //                 ammActivityMap,\n      //                 type: 'AMM_MINING',\n      //                 ammPoolActivityStatus: [AmmPoolActivityStatus.NotStarted, AmmPoolActivityStatus.InProgress]\n      //             }, ammUserRewardMap\n      //         ))\n      //     setAmmActivityPastViewMap(\n      //         makeUIAmmActivityMap(\n      //             {\n      //                 ammActivityMap,\n      //                 type: 'AMM_MINING',\n      //                 ammPoolActivityStatus: [AmmPoolActivityStatus.EndOfGame]\n      //             }, ammUserRewardMap\n      //         ))\n      //\n      // }\n    }\n  }, [ammActivityMap, userRewardsMapState, userRewardsMapState.status])\n\n  return {\n    ammActivityViewMap,\n    ammRewardRecordList,\n    ammActivityPastViewMap,\n    getLiquidityMining,\n    showRewardDetail,\n    setShowRewardDetail,\n    getMyAmmShare,\n  }\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/MiningPage/index.tsx",
    "content": "import { AmmCard, AmmProps, EmptyDefault, RewardTable } from '@loopring-web/component-lib'\nimport React from 'react'\nimport { useHistory } from 'react-router-dom'\nimport {\n  AmmCardProps,\n  AmmExitData,\n  AmmInData,\n  AmmJoinData,\n  getMiningLinkList,\n  IBData,\n} from '@loopring-web/common-resources'\nimport { Box, Grid, Modal, Typography } from '@mui/material'\nimport styled from '@emotion/styled'\nimport { RewardListItem, useAmmMiningUI } from './hook'\nimport { Trans, withTranslation } from 'react-i18next'\nimport { AmmPoolActivityRule, LoopringMap } from '@loopring-web/loopring-sdk'\nimport { store, useAccount, useAmmActivityMap } from '@loopring-web/core'\n\nexport enum MiningJumpType {\n  orderbook = 'orderbook',\n  amm = 'amm',\n}\n\nconst WrapperStyled = styled(Box)`\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n` as typeof Box\n\nconst ContentWrapperStyled = styled(Box)`\n  position: absolute;\n  top: 45%;\n  left: 50%;\n  transform: translate(-50%, -50%);\n  width: ${({ theme }) => theme.unit * 37.5}px;\n  max-height: ${({ theme }) => theme.unit * 30}px;\n  background-color: var(--color-box);\n  box-shadow: 0 ${({ theme }) => theme.unit / 2}px ${({ theme }) => theme.unit / 2}px\n    rgba(0, 0, 0, 0.25);\n  border-radius: ${({ theme }) => theme.unit / 2}px;\n`\n\ntype ClickHandler = {\n  handleClick: (pair: string, type: MiningJumpType) => void\n}\n\nconst AmmCardWrap = React.memo(\n  React.forwardRef(\n    (\n      props: AmmCardProps<{ [key: string]: any }> &\n        ClickHandler & {\n          popoverIdx: number\n          ammRewardRecordList: RewardListItem[]\n          getLiquidityMining: (market: string, size?: number) => Promise<void>\n          setShowRewardDetail: React.Dispatch<React.SetStateAction<boolean>>\n          setChosenCardInfo: React.Dispatch<React.SetStateAction<any>>\n          getMyAmmShare: (market: string) => any\n        },\n      ref,\n    ) => {\n      // const pair = `${props.coinAInfo?.simpleName}-${props.coinBInfo?.simpleName}`;\n      const { ruleType } = props.activity\n      const { account } = useAccount()\n      const type = ruleType === 'ORDERBOOK_MINING' ? MiningJumpType.orderbook : MiningJumpType.amm\n      const popoverIdx = props.popoverIdx\n      const { setShowRewardDetail, setChosenCardInfo, getMyAmmShare } = props\n      const ammInfo = getMyAmmShare(`LP-${props.market}`)\n      return props ? (\n        <AmmCard\n          ref={ref}\n          {...props}\n          {...{\n            popoverIdx,\n            getMiningLinkList,\n            setShowRewardDetail,\n            setChosenCardInfo,\n            ammInfo,\n          }}\n          account={account}\n          handleClick={() => props.handleClick(props.market, type)}\n        />\n      ) : (\n        <></>\n      )\n    },\n  ),\n)\n\nconst AmmList = <I extends { [key: string]: any }>({\n  ammActivityViewMap,\n  ammRewardRecordList,\n  getLiquidityMining,\n  setShowRewardDetail,\n  setChosenCardInfo,\n  getMyAmmShare,\n}: {\n  ammActivityViewMap: Array<AmmCardProps<I>>\n  ammRewardRecordList: RewardListItem[]\n  getLiquidityMining: (market: string, size?: number) => Promise<void>\n  setShowRewardDetail: React.Dispatch<React.SetStateAction<boolean>>\n  setChosenCardInfo: React.Dispatch<React.SetStateAction<any>>\n  getMyAmmShare: (market: string) => any\n}) => {\n  let history = useHistory()\n  const { tokenMap } = store.getState().tokenMap\n\n  const jumpTo = React.useCallback(\n    (pair: string, type: MiningJumpType) => {\n      if (history) {\n        // if (type === MiningJumpType.amm) {\n        //   history.push(`/liquidity/pools/coinPair/${pair}`);\n        // } else {\n        //   history.push(`/trade/lite/${pair}`);\n        // }\n      }\n    },\n    [history],\n  )\n\n  return (\n    <>\n      {ammActivityViewMap.length ? (\n        ammActivityViewMap.map((item: AmmCardProps<I>, index) => {\n          const precisionA = tokenMap ? tokenMap[item.coinAInfo?.simpleName]?.precision : undefined\n          const precisionB = tokenMap ? tokenMap[item.coinBInfo?.simpleName]?.precision : undefined\n          return (\n            <Grid item xs={12} sm={6} lg={4} key={index}>\n              <AmmCardWrap\n                {...{\n                  popoverIdx: index,\n                  precisionA,\n                  precisionB,\n                  ammRewardRecordList,\n                  getLiquidityMining,\n                  setShowRewardDetail,\n                  setChosenCardInfo: setChosenCardInfo,\n                  getMyAmmShare,\n                }}\n                handleClick={jumpTo}\n                {...(item as any)}\n              />\n            </Grid>\n          )\n        })\n      ) : (\n        <Box\n          flex={1}\n          display={'flex'}\n          alignItems={'center'}\n          justifyContent={'center'}\n          flexDirection={'column'}\n        >\n          <EmptyDefault\n            height={'calc(100% - 35px)'}\n            marginTop={10}\n            display={'flex'}\n            flexWrap={'nowrap'}\n            alignItems={'center'}\n            justifyContent={'center'}\n            flexDirection={'column'}\n            message={() => {\n              return <Trans i18nKey='labelEmptyDefault'>Content is Empty</Trans>\n            }}\n          />\n        </Box>\n      )}\n    </>\n  )\n}\n\nexport const MiningPage = withTranslation('common')(\n  <\n    T extends AmmJoinData<C extends IBData<I> ? C : IBData<I>>,\n    I,\n    TW extends AmmExitData<C extends IBData<I> ? C : IBData<I>>,\n    ACD extends AmmInData<I>,\n    C = IBData<I>,\n  >({\n    ammProps,\n    t,\n    ...rest\n  }: {\n    ammProps: AmmProps<T, TW, I, ACD>\n    ammActivityMap: LoopringMap<LoopringMap<AmmPoolActivityRule[]>> | undefined\n  } & any) => {\n    const [chosenCardInfo, setChosenCardInfo] = React.useState(undefined)\n    const { ammActivityMap } = useAmmActivityMap()\n    const {\n      ammActivityViewMap,\n      ammActivityPastViewMap,\n      ammRewardRecordList,\n      getLiquidityMining,\n      showRewardDetail,\n      setShowRewardDetail,\n      getMyAmmShare,\n    } = useAmmMiningUI({ ammActivityMap })\n    // const [tabIndex, setTabIndex] = React.useState<0 | 1>(0);\n    // const handleChange = (event: any, newValue: 0 | 1) => {\n    //     setTabIndex(newValue);\n    // }\n    const jointAmmViewMap = [...ammActivityViewMap, ...ammActivityPastViewMap]\n    // hide orderbook activity for now\n    const filteredJointAmmViewMap = jointAmmViewMap.filter(\n      (o) =>\n        o.activity.ruleType !== 'SWAP_VOLUME_RANKING' && o.activity.ruleType !== 'ORDERBOOK_MINING',\n    )\n    const orderedViewMap = filteredJointAmmViewMap.sort((a, b) => {\n      if (a.APR && !b.APR) {\n        return -1\n      }\n      if (b.APR && !a.APR) {\n        return 1\n      }\n      return 0\n    })\n\n    return (\n      <WrapperStyled>\n        {/* <Tabs value={tabIndex}\n                onChange={handleChange}\n                aria-label=\"tabs switch\">\n            <Tab label={t('labelCurrentActivities')}/>\n            <Tab label={t('labelPastActivities')}/>\n        </Tabs> */}\n        <Typography variant={'h3'} component={'div'} fontFamily={'Roboto'} marginTop={2}>\n          {t('labelMiningPageTitle')}\n        </Typography>\n        <Typography\n          variant={'h6'}\n          component={'div'}\n          marginTop={1}\n          marginBottom={4.5}\n          color={'var(--color-text-secondary)'}\n        >\n          {t('labelMiningPageViceTitle')}\n        </Typography>\n        <Grid container spacing={5}>\n          <AmmList\n            ammActivityViewMap={orderedViewMap}\n            ammRewardRecordList={ammRewardRecordList}\n            getLiquidityMining={getLiquidityMining}\n            setChosenCardInfo={setChosenCardInfo}\n            {...{\n              setShowRewardDetail,\n              getMyAmmShare,\n            }}\n          />\n        </Grid>\n        <Modal open={showRewardDetail} onClose={() => setShowRewardDetail(false)}>\n          <ContentWrapperStyled>\n            <RewardTable rawData={ammRewardRecordList} chosenCardInfo={chosenCardInfo} />\n          </ContentWrapperStyled>\n\n          {/* <OrderDetailPanel rawData={orderDetailList} showLoading={showDetailLoading} orderId={currOrderId} /> */}\n        </Modal>\n      </WrapperStyled>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/webapp/src/pages/NFTPage/CollectionPanel/index.tsx",
    "content": "import {\n  CollectionCardList,\n  CollectionDetailView,\n  StyledPaperBg,\n  Toast,\n  ToastType,\n  useOpenModals,\n  useSettings,\n  useToggle,\n} from '@loopring-web/component-lib'\nimport { useTranslation } from 'react-i18next'\nimport { Box, Button, Tooltip, Typography } from '@mui/material'\nimport React from 'react'\nimport {\n  AddIcon,\n  CollectionMeta,\n  CreateCollectionStep,\n  Explorer,\n  TOAST_TIME,\n  TradeNFT,\n  RouterPath,\n  NFTSubRouter,\n} from '@loopring-web/common-resources'\nimport {\n  getIPFSString,\n  LoopringAPI,\n  useAccount,\n  useModalData,\n  useMyCollection,\n  useSystem,\n} from '@loopring-web/core'\nimport { CreateUrlPanel } from '../components/landingPanel'\nimport { useHistory, useLocation, useRouteMatch } from 'react-router-dom'\nimport { useTheme } from '@emotion/react'\nimport { CollectionItemPanel } from '../components/CollectionItemPanel'\nimport { usePublicNFTs } from '../components/usePublicNFTs'\n\nenum MyCollectionView {\n  List = 'List',\n  Item = 'Item',\n}\n\nexport const NFTCollectPanel = <Co extends CollectionMeta>() => {\n  const { t } = useTranslation(['common'])\n  const { baseURL } = useSystem()\n  const theme = useTheme()\n  const { copyToastOpen, ...collectionListProps } = useMyCollection()\n  const [showCreateOpen, setCreateOpen] = React.useState(false)\n  const [view, setView] = React.useState<MyCollectionView>(MyCollectionView.List)\n  const { updateCollectionData } = useModalData()\n  const { isMobile } = useSettings()\n\n  const [detail, setDetail] = React.useState<CollectionMeta | undefined>(undefined)\n  const history = useHistory()\n  const match: any = useRouteMatch('/nft/myCollection/:id')\n  React.useEffect(() => {\n    if (match?.params?.id) {\n      const loopringId = match.params.id.split('--')[1]\n      if (loopringId && detail) {\n        setView(MyCollectionView.Item)\n        return\n      }\n    }\n    setView(MyCollectionView.List)\n  }, [match?.params?.id])\n\n  const { account } = useAccount()\n  const {\n    toggle: { deployNFT },\n  } = useToggle()\n  const { setShowNFTDeploy, setShowTradeIsFrozen } = useOpenModals()\n  const { updateNFTDeployData, updateNFTMintData, nftMintValue } = useModalData()\n  const { search, ...rest } = useLocation()\n  const searchParams = new URLSearchParams(search)\n  const nftPublicProps = usePublicNFTs({\n    collection: detail ?? ({} as any),\n    page: searchParams?.get('totalPage') ? Number(searchParams?.get('totalPage')) : 1,\n  })\n  return (\n    <Box flex={1} marginTop={0} marginBottom={2} display={'flex'} flexDirection={'column'}>\n      {view === MyCollectionView.List && (\n        <>\n          <Box\n            display={'flex'}\n            flexDirection={isMobile ? 'column' : 'row'}\n            alignItems={isMobile ? 'flex-start' : 'center'}\n            justifyContent={'space-between'}\n          >\n            <Typography component={'h3'} variant={'h4'} paddingBottom={2}>\n              {t('labelMyCollection')}\n            </Typography>\n\n            <Box display={'flex'} flexDirection={isMobile ? 'column' : 'row'}>\n              {/*<Tooltip title={t('labelCheckImportCollectionDes').toString()}>\n                <Button\n                  onClick={() => {\n                    history.push(`${RouterPath.nft}/${NFTSubRouter.importLegacyCollection}`)\n                  }}\n                  sx={isMobile ? { marginBottom: 2 } : { marginRight: 1 }}\n                  // startIcon={<DownloadIcon />}\n                  variant={'outlined'}\n                  color={'primary'}\n                >\n                  {t('labelImportCollection')}\n                </Button>\n              </Tooltip>*/}\n              {/* <Button\n                onClick={() => {\n                  history.push(`${RouterPath.nft}/${NFTSubRouter.addCollection}`)\n                }}\n                startIcon={<AddIcon />}\n                variant={'contained'}\n                size={'small'}\n                color={'primary'}\n              >\n                {t('labelCreateCollection')}\n              </Button> */}\n              <Button\n                onClick={() => {\n                  window?.open(`${Explorer}/account/${account.accountId}-nfts`, '_blank')?.focus()\n                }}\n                sx={isMobile ? { marginTop: 2 } : { marginLeft: 1 }}\n                variant={'outlined'}\n                color={'primary'}\n              >\n                {t('labelExplorer')}\n              </Button>\n            </Box>\n          </Box>\n          <Box flex={1} paddingBottom={2} display={'flex'}>\n            <CollectionCardList\n              {...{ ...(collectionListProps as any) }}\n              account={account}\n              toggle={deployNFT}\n              size={isMobile ? 'small' : 'large'}\n              setShowEdit={(item) => {\n                updateCollectionData({ ...item })\n                history.push(\n                  `${RouterPath.nft}/${NFTSubRouter.editCollection}/${item.contractAddress}--${item.id}`,\n                )\n              }}\n              setShowManageLegacy={(item) => {\n                updateCollectionData({ ...item })\n                history.push(\n                  `${RouterPath.nft}/${NFTSubRouter.importLegacyCollection}/${item.contractAddress}--${item.id}?isEdit=true`,\n                )\n              }}\n              onItemClick={(item) => {\n                history.push(\n                  `${RouterPath.nft}/${NFTSubRouter.myCollection}/${item.contractAddress}--${item.id}`,\n                )\n                setDetail(item)\n              }}\n              setShowMintNFT={(item) => {\n                setCreateOpen(true)\n                updateNFTMintData({\n                  nftMETA: nftMintValue.mintData,\n                  mintData: nftMintValue.nftMETA,\n                  collection: undefined,\n                })\n                history.push(`${RouterPath.nft}/${NFTSubRouter.mintNFT}/${item.contractAddress}`)\n              }}\n              setShowTradeIsFrozen={(item, typeKey) => {\n                setShowTradeIsFrozen({\n                  isShow: true,\n                  type: typeKey,\n                })\n              }}\n              setShowDeploy={(item: Co) => {\n                const _deployItem: TradeNFT<any, any> = {\n                  tokenAddress: item?.contractAddress,\n                  nftType: item.nftType,\n                  collectionMeta: item,\n                }\n                LoopringAPI.userAPI?.getAvailableBroker({ type: 0 }).then(({ broker }) => {\n                  updateNFTDeployData({ broker })\n                })\n                updateNFTDeployData(_deployItem)\n                deployNFT.enable\n                  ? setShowNFTDeploy({\n                      isShow: true,\n                      info: { ...{ _deployItem } },\n                    })\n                  : setShowTradeIsFrozen({\n                      isShow: true,\n                      type: t('nftDeployDescription'),\n                    })\n              }}\n            />\n          </Box>\n        </>\n      )}\n      {view === MyCollectionView.Item && detail && (\n        <Box flex={1} display={'flex'} flexDirection={'column'}>\n          <CollectionDetailView\n            collectionDate={detail}\n            getIPFSString={getIPFSString}\n            baseURL={baseURL}\n            account={account}\n            setShowEdit={(item) => {\n              updateCollectionData({ ...item })\n              history.push(\n                `${RouterPath.nft}/${NFTSubRouter.editCollection}/${item.contractAddress}--${item.id}`,\n              )\n            }}\n            setShowManageLegacy={(item) => {\n              updateCollectionData({ ...item })\n              history.push(\n                `${RouterPath.nft}/${NFTSubRouter.importLegacyCollection}/${item.contractAddress}--${item.id}?isEdit=true`,\n              )\n            }}\n            count={nftPublicProps?.total}\n            setCopyToastOpen={collectionListProps.setCopyToastOpen}\n          />\n          <StyledPaperBg flex={1} marginTop={2} marginX={2} height={'100%'} display={'flex'}>\n            <CollectionItemPanel\n              nftPublicProps={nftPublicProps}\n              collectionDate={detail}\n              getIPFSString={getIPFSString}\n              baseURL={baseURL}\n            />\n            {/*<EmptyDefault*/}\n            {/*  sx={{ flex: 1 }}*/}\n            {/*  message={() => {*/}\n            {/*    return <Trans i18nKey=\"labelComingSoon\">Coming Soon</Trans>;*/}\n            {/*  }}*/}\n            {/*/>*/}\n          </StyledPaperBg>\n        </Box>\n      )}\n\n      <CreateUrlPanel\n        open={showCreateOpen}\n        step={CreateCollectionStep.ChooseMethod}\n        onClose={() => {\n          setCreateOpen(false)\n        }}\n      />\n      <Toast\n        alertText={\n          copyToastOpen?.type === 'json'\n            ? t('labelCopyMetaClip')\n            : copyToastOpen.type === 'url'\n            ? t('labelCopyUrlClip')\n            : t('labelCopyAddClip')\n        }\n        open={copyToastOpen?.isShow}\n        autoHideDuration={TOAST_TIME}\n        onClose={() => {\n          collectionListProps.setCopyToastOpen({ isShow: false, type: '' })\n        }}\n        severity={ToastType.success}\n      />\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/NFTPage/EditCollectionPanel/hook.ts",
    "content": "import {\n  AccountStatus,\n  CollectionMeta,\n  NFTSubRouter,\n  RouterPath,\n  SagaStatus,\n} from '@loopring-web/common-resources'\nimport {\n  collectionService,\n  useAccount,\n  useEditCollection,\n  useSystem,\n  getIPFSString,\n} from '@loopring-web/core'\nimport { BigNumber } from 'bignumber.js'\nimport React from 'react'\nimport { useHistory, useRouteMatch } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\n\nBigNumber.config({ EXPONENTIAL_AT: 100 })\nexport const useCollectionPanel = <T extends CollectionMeta>({\n  type,\n}: {\n  type: 'addCollection' | 'editCollection' | 'addLegacyCollection'\n}) => {\n  const match: any = useRouteMatch('/nft/:item?/:id?')\n  const { t } = useTranslation('common')\n  const isEdit = match?.params?.item === 'editCollection'\n  const history = useHistory()\n  const { baseURL } = useSystem()\n  const {\n    keys,\n    collectionToastOpen,\n    collectionToastClose,\n    onFilesLoad,\n    onDelete,\n    btnStatus,\n    btnInfo,\n    disabled,\n    handleOnDataChange,\n    collectionValue,\n    onSubmitClick,\n    resetEdit,\n  } = useEditCollection({ isEdit, type })\n  const { account, status: accountStatus } = useAccount()\n  const title = React.useMemo(() => {\n    if (match?.params.item === 'addCollection') {\n      return t(t('labelCollectionCreateERC1155'))\n    } else if (match?.params.item === 'editCollection') {\n      return t('labelEditCollectionERC1155')\n    } else if (match?.params?.item === 'addLegacyCollection') {\n      return t('labelLegacyCollectionTitle')\n    }\n  }, [account.readyState, accountStatus, match.params.id, match.params.item, t])\n\n  const goBack = React.useCallback(() => {\n    if (match?.params.item === 'addCollection') {\n      history.goBack()\n    } else if (match?.params.item === 'editCollection') {\n      history.push(`${RouterPath.nft}/${NFTSubRouter.myCollection}`)\n    } else if (match?.params?.item === 'addLegacyCollection') {\n      history.push(`${RouterPath.nft}/${NFTSubRouter.importLegacyCollection}/${match?.params?.id}`)\n    }\n  }, [account.readyState, accountStatus, history, match?.params?.id, match?.params?.item])\n  React.useEffect(() => {\n    if (\n      accountStatus === SagaStatus.UNSET &&\n      account.readyState === AccountStatus.ACTIVATED &&\n      match?.params.item === 'addCollection'\n    ) {\n      collectionService.emptyData()\n    } else if (match?.params.item === 'editCollection' && match?.params?.id) {\n      const loopringId = match?.params?.id.split('--')[1]\n      if (collectionValue?.id?.toString() === loopringId.toString()) {\n      } else {\n        history.push(`${RouterPath.nft}/${NFTSubRouter.myCollection}`)\n      }\n    } else if (match?.params?.item === 'addLegacyCollection' && match?.params?.id) {\n      const contract = match?.params?.id\n      if (contract.startsWith('0x')) {\n      } else {\n        history.push(`${RouterPath.nft}/${NFTSubRouter.importLegacyCollection}`)\n      }\n    }\n  }, [accountStatus, account.readyState, match?.params?.item])\n\n  return {\n    keys,\n    title,\n    goBack,\n    collectionToastOpen,\n    collectionToastClose,\n    onFilesLoad,\n    onDelete,\n    btnStatus,\n    btnInfo,\n    disabled,\n    baseURL,\n    getIPFSString,\n    handleOnDataChange,\n    collectionValue,\n    resetEdit,\n    isEdit,\n    onSubmitClick,\n  }\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/NFTPage/EditCollectionPanel/index.tsx",
    "content": "import styled from '@emotion/styled'\nimport { Button, CreateCollectionWrap, Toast, ToastType } from '@loopring-web/component-lib'\nimport { Box } from '@mui/material'\nimport React from 'react'\nimport { useCollectionPanel } from './hook'\nimport { BackIcon, TOAST_TIME } from '@loopring-web/common-resources'\n\nconst StyledPaper = styled(Box)`\n  background: var(--color-box-third);\n  border-radius: ${({ theme }) => theme.unit}px;\n`\n\nexport const EditCollectionPanel = ({\n  type,\n}: {\n  type: 'addCollection' | 'editCollection' | 'addLegacyCollection'\n}) => {\n  // 0x47a6884c9f2e5627ad82bfa94c999a59e0310906\n  const { goBack, title, collectionToastOpen, collectionToastClose, ...editCollectionViewProps } =\n    useCollectionPanel({ type })\n\n  return (\n    <>\n      <Box display={'flex'} justifyContent={'space-between'} alignItems={'center'} marginBottom={2}>\n        <Button\n          startIcon={<BackIcon fontSize={'small'} />}\n          variant={'text'}\n          size={'medium'}\n          sx={{ color: 'var(--color-text-secondary)' }}\n          color={'inherit'}\n          onClick={goBack}\n        >\n          {title}\n        </Button>\n      </Box>\n      <StyledPaper flex={1} display={'flex'} justifyContent={'center'} marginBottom={2}>\n        <CreateCollectionWrap {...{ ...editCollectionViewProps }} />\n      </StyledPaper>\n      <Toast\n        alertText={collectionToastOpen?.content ?? ''}\n        severity={collectionToastOpen?.type ?? ToastType.success}\n        open={collectionToastOpen?.open ?? false}\n        autoHideDuration={TOAST_TIME}\n        onClose={collectionToastClose}\n      />\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/NFTPage/ImportCollectionPanel/CollectionManage.tsx",
    "content": "import { CollectionMeta } from '@loopring-web/common-resources'\nimport { CollectionManageWrap } from '@loopring-web/component-lib'\nimport { useCollectionManage } from '@loopring-web/core'\n\nexport const CollectionManage = ({ collection }: { collection: CollectionMeta }) => {\n  const props = useCollectionManage({ collection })\n  return <CollectionManageWrap {...props} />\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/NFTPage/ImportCollectionPanel/ImportCollection.tsx",
    "content": "import { ImportCollectionWrap } from '@loopring-web/component-lib'\nimport { CollectionMeta } from '@loopring-web/common-resources'\nimport { useCollectionImport } from '@loopring-web/core'\n\nexport const ImportCollection = <Co extends CollectionMeta>() => {\n  const props = useCollectionImport()\n\n  return <ImportCollectionWrap {...{ ...props }} />\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/NFTPage/ImportCollectionPanel/index.tsx",
    "content": "import { Box } from '@mui/material'\nimport React from 'react'\nimport {\n  AccountStatus,\n  BackIcon,\n  CollectionMeta,\n  NFTSubRouter,\n  RouterPath,\n} from '@loopring-web/common-resources'\nimport { useAccount, useModalData } from '@loopring-web/core'\nimport { useHistory, useLocation, useRouteMatch } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport { Button, LoadingBlock, StyledPaperBg } from '@loopring-web/component-lib'\nimport { CollectionManage } from './CollectionManage'\nimport { ImportCollection } from './ImportCollection'\n\nenum CollectionImportView {\n  Guide = 'Guide',\n  Item = 'Item',\n}\n\nexport const ImportCollectionPanel = <Co extends CollectionMeta>() => {\n  const { t } = useTranslation()\n  const match: any = useRouteMatch('/nft/importLegacyCollection/:id?')\n  const { collectionValue } = useModalData()\n  const { search } = useLocation()\n  const searchParams = new URLSearchParams(search)\n  const history = useHistory()\n  const { account } = useAccount()\n  const [_collection, setCollection] = React.useState<undefined | Co>(\n    searchParams.get('isEdit') ? (collectionValue as Co) : undefined,\n  )\n  const [view, setView] = React.useState<CollectionImportView>(CollectionImportView.Guide)\n\n  React.useEffect(() => {\n    const stepList = match?.params?.id?.split('--')\n    const contractId = stepList && stepList[1]\n    if (searchParams.has('isEdit')) {\n      if (\n        collectionValue?.id?.toString() === contractId.toString() &&\n        account.readyState === AccountStatus.ACTIVATED &&\n        collectionValue?.owner?.toLowerCase() === account.accAddress.toLowerCase()\n      ) {\n        setCollection(collectionValue as Co)\n        setView(CollectionImportView.Item)\n      } else {\n        setView(CollectionImportView.Guide)\n        history.replace(`${RouterPath.nft}/${NFTSubRouter.importLegacyCollection}`)\n      }\n    }\n  }, [search, account.readyState])\n  return (\n    <Box flex={1} display={'flex'} flexDirection={'column'} marginBottom={2}>\n      <Box display={'flex'} justifyContent={'space-between'} alignItems={'center'} marginBottom={2}>\n        <Button\n          startIcon={<BackIcon fontSize={'small'} />}\n          variant={'text'}\n          size={'medium'}\n          sx={{ color: 'var(--color-text-secondary)' }}\n          color={'inherit'}\n          onClick={() => history.push(`${RouterPath.nft}/${NFTSubRouter.myCollection}`)}\n        >\n          {searchParams.get('isEdit')\n            ? t('labelManageCollectionTitle')\n            : t('labelImportCollectionTitle')}\n        </Button>\n      </Box>\n      <StyledPaperBg flex={1} display={'flex'}>\n        {view === CollectionImportView.Guide && <ImportCollection />}\n        {view === CollectionImportView.Item &&\n          (_collection?.owner ? (\n            <Box flex={1} display={'flex'} paddingX={2}>\n              <CollectionManage collection={_collection} />\n            </Box>\n          ) : (\n            <LoadingBlock />\n          ))}\n      </StyledPaperBg>\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/NFTPage/MintNFTPanel/hook.ts",
    "content": "import {\n  AccountStatus,\n  CollectionMeta,\n  FeeInfo,\n  MintTradeNFT,\n  NFTMETA,\n  SagaStatus,\n} from '@loopring-web/common-resources'\nimport { mintService, useAccount, useModalData, useNFTMeta, useNFTMint } from '@loopring-web/core'\nimport { BigNumber } from 'bignumber.js'\nimport React from 'react'\nimport { useRouteMatch } from 'react-router-dom'\n\nconst enum MINT_VIEW_STEP {\n  METADATA,\n  MINT_CONFIRM,\n}\n\nBigNumber.config({ EXPONENTIAL_AT: 100 })\nexport const useMintNFTPanel = <\n  Me extends NFTMETA,\n  Mi extends MintTradeNFT<I>,\n  Co extends CollectionMeta,\n  I,\n  C extends FeeInfo,\n>() => {\n  const [currentTab, setCurrentTab] = React.useState<MINT_VIEW_STEP>(MINT_VIEW_STEP.METADATA)\n  const { account, status: accountStatus } = useAccount()\n  let match: any = useRouteMatch('/nft/:item/:contract?')\n  const handleTabChange = React.useCallback((value: MINT_VIEW_STEP) => {\n    setCurrentTab(value)\n  }, [])\n  const { nftMintValue } = useModalData()\n  const {\n    onFilesLoad,\n    onDelete,\n    keys,\n    ipfsProvides,\n    nftMetaProps,\n    chargeFeeTokenList,\n    isFeeNotEnough,\n    checkFeeIsEnough,\n    handleFeeChange,\n    resetIntervalTime,\n    feeInfo,\n    errorOnMeta,\n  } = useNFTMeta<Me, Co>({ handleTabChange, nftMintValue })\n\n  const { nftMintProps } = useNFTMint<Me, Mi, I, C>({\n    chargeFeeTokenList,\n    isFeeNotEnough,\n    checkFeeIsEnough,\n    handleFeeChange,\n    feeInfo,\n    handleTabChange,\n    nftMintValue,\n    // resetIntervalTime,\n  })\n\n  React.useEffect(() => {\n    if (\n      accountStatus === SagaStatus.UNSET &&\n      account.readyState === AccountStatus.ACTIVATED &&\n      match?.params?.item === 'mintNFT'\n    ) {\n      mintService.emptyData({ contractAddress: match?.params?.contract ?? '' })\n    } else {\n      resetIntervalTime()\n    }\n    return () => {\n      resetIntervalTime()\n    }\n  }, [accountStatus, account.readyState, match?.params?.item])\n\n  return {\n    errorOnMeta,\n    onFilesLoad,\n    onDelete,\n    keys,\n    ipfsProvides,\n    nftMetaProps,\n    chargeFeeTokenList,\n    isFeeNotEnough,\n    checkFeeIsEnough,\n    handleFeeChange,\n    feeInfo,\n    // resetMETADAT,\n    nftMintProps,\n    nftMintValue,\n    currentTab,\n    handleTabChange,\n  }\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/NFTPage/MintNFTPanel/index.tsx",
    "content": "import { useTranslation } from 'react-i18next'\nimport { Box, Button } from '@mui/material'\nimport {\n  MintAdvanceNFTWrap,\n  MintNFTConfirm,\n  PanelContent,\n  StyledPaperBg,\n} from '@loopring-web/component-lib'\nimport React from 'react'\nimport { MetaNFTPanel } from './metaNFTPanel'\nimport { useMintNFTPanel } from './hook'\nimport { useHistory, useRouteMatch } from 'react-router-dom'\nimport { BackIcon, CollectionMeta, TradeNFT } from '@loopring-web/common-resources'\nimport {\n  getIPFSString,\n  LoopringAPI,\n  makeMeta,\n  useMyCollection,\n  useNFTMintAdvance,\n  useSystem,\n} from '@loopring-web/core'\n\nexport const MintNFTPanel = <Co extends CollectionMeta>() => {\n  const history = useHistory()\n  const mintWholeProps = useMintNFTPanel()\n  const collectionListProps = useMyCollection()\n  const { t } = useTranslation(['common'])\n  const { baseURL } = useSystem()\n\n  const panelList: Pick<PanelContent<'METADATA' | 'MINT_CONFIRM'>, 'key' | 'element'>[] = [\n    {\n      key: 'METADATA',\n      element: (\n        <MetaNFTPanel\n          {...{\n            getIPFSString,\n            baseURL,\n            ...mintWholeProps,\n            nftMetaProps: {\n              ...mintWholeProps.nftMetaProps,\n              collectionInputProps: {\n                collection: mintWholeProps.nftMintValue.collection,\n                collectionListProps: {\n                  ...collectionListProps,\n                  size: 'small',\n                },\n                domain: LoopringAPI.delegate?.getCollectionDomain(),\n                makeMeta,\n              } as any,\n            },\n          }}\n          // collectionInputProps={}\n          nftMetaBtnStatus={mintWholeProps.nftMetaProps.nftMetaBtnStatus}\n          btnInfo={mintWholeProps.nftMetaProps.btnInfo}\n        />\n      ),\n    },\n    {\n      key: 'MINT_CONFIRM',\n      element: (\n        <MintNFTConfirm\n          disabled={false}\n          // baseURL={mintWholeProps.nftMetaProps.baseURL}\n          walletMap={{}}\n          {...{ ...mintWholeProps.nftMintProps, getIPFSString, baseURL }}\n          metaData={mintWholeProps.nftMintValue.nftMETA}\n          isFeeNotEnough={mintWholeProps.isFeeNotEnough}\n          handleFeeChange={mintWholeProps.handleFeeChange}\n          chargeFeeTokenList={mintWholeProps.chargeFeeTokenList}\n          feeInfo={mintWholeProps.feeInfo}\n        />\n      ),\n    },\n  ]\n  return (\n    <>\n      <Box marginBottom={2}>\n        <Button\n          startIcon={<BackIcon fontSize={'small'} />}\n          variant={'text'}\n          size={'medium'}\n          sx={{ color: 'var(--color-text-secondary)' }}\n          color={'inherit'}\n          onClick={history.goBack}\n        >\n          {t('labelMINTNFTTitle')}\n          {/*<Typography color={\"textPrimary\"}></Typography>*/}\n        </Button>\n      </Box>\n      <StyledPaperBg\n        flex={1}\n        className={'MuiPaper-elevation2'}\n        marginTop={0}\n        marginBottom={2}\n        display={'flex'}\n        flexDirection={'column'}\n      >\n        <Box flex={1} display={'flex'}>\n          {\n            panelList.map((panel, index) => {\n              return (\n                <Box\n                  flex={1}\n                  display={mintWholeProps.currentTab === index ? 'flex' : 'none'}\n                  alignItems={'stretch'}\n                  key={index}\n                >\n                  {panel.element}\n                </Box>\n              )\n            })\n            // panelList[currentTab].element\n          }\n        </Box>\n      </StyledPaperBg>\n    </>\n  )\n}\nexport const MintNFTAdvancePanel = <T extends TradeNFT<I, Co>, Co extends CollectionMeta, I>() => {\n  const { resetDefault: resetNFTMint, nftMintAdvanceProps, resetIntervalTime } = useNFTMintAdvance()\n\n  const history = useHistory()\n  const match: any = useRouteMatch('/nft/:type')\n  React.useEffect(() => {\n    if (match.params?.type === 'mintNFTAdvance') {\n      resetNFTMint()\n    } else {\n      resetIntervalTime()\n    }\n    return () => {\n      resetIntervalTime()\n    }\n  }, [match.params?.type])\n  const { t } = useTranslation('common')\n\n  return (\n    <>\n      <Box marginBottom={2}>\n        <Button\n          startIcon={<BackIcon fontSize={'small'} />}\n          variant={'text'}\n          size={'medium'}\n          sx={{ color: 'var(--color-text-secondary)' }}\n          color={'inherit'}\n          onClick={history.goBack}\n        >\n          {t('labelAdMintTitle')}\n        </Button>\n      </Box>\n      <StyledPaperBg\n        flex={1}\n        className={'MuiPaper-elevation2'}\n        marginTop={0}\n        marginBottom={2}\n        display={'flex'}\n        flexDirection={'column'}\n        alignItems={'stretch'}\n      >\n        <MintAdvanceNFTWrap {...{ ...nftMintAdvanceProps }} />\n      </StyledPaperBg>\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/NFTPage/MintNFTPanel/metaNFTPanel.tsx",
    "content": "import {\n  Box,\n  Checkbox,\n  FormControlLabel as MuiFormControlLabel,\n  FormLabel,\n  Grid,\n  Tooltip,\n  Typography,\n} from '@mui/material'\nimport {\n  DropdownIconStyled,\n  ImageUploadWrapper,\n  IpfsFile,\n  IPFSSourceUpload,\n  MediaTYPES,\n  MintNFTBlock,\n  NFTMetaBlockProps,\n  NFTMetaProps,\n  NFTMintProps,\n  TextareaAutosizeStyled,\n  TransErrorHelp,\n  TYPES,\n} from '@loopring-web/component-lib'\nimport { Trans, useTranslation } from 'react-i18next'\nimport React from 'react'\nimport {\n  CheckBoxIcon,\n  CheckedIcon,\n  CollectionMeta,\n  FeeInfo,\n  Info2Icon,\n  MintTradeNFT,\n  NFTMETA,\n} from '@loopring-web/common-resources'\nimport { getIPFSString, LoopringAPI, NFT_MINT_VALUE, useSystem } from '@loopring-web/core'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nconst MaxSize = 10485760\nconst MaxMediaSize = 10485760 * 5\n\nexport const MetaNFTPanel = <\n  Me extends NFTMETA,\n  Mi extends MintTradeNFT<I>,\n  Co extends CollectionMeta,\n  I,\n  C extends FeeInfo,\n>({\n  nftMetaProps,\n  nftMintProps,\n  keys,\n  onFilesLoad,\n  onDelete,\n  nftMintValue,\n  errorOnMeta,\n}: Partial<NFTMetaBlockProps<Me, Co, Mi, C>> & {\n  feeInfo: C\n  errorOnMeta: undefined | sdk.RESULT_INFO\n  nftMintValue: NFT_MINT_VALUE<I>\n  nftMintProps: NFTMintProps<Me, Mi, C>\n  nftMetaProps: NFTMetaProps<Me, Co, C>\n  onFilesLoad: (key: string, value: IpfsFile) => void\n  onDelete: (keys: string[]) => void\n  keys: { [key: string]: undefined | IpfsFile }\n}) => {\n  const { t } = useTranslation('common')\n  const { baseURL } = useSystem()\n  const domain: string = LoopringAPI.delegate?.getCollectionDomain() ?? ''\n  const [dropdownErrorStatus, setDropdownErrorStatus] = React.useState<'up' | 'down'>('down')\n\n  return (\n    <ImageUploadWrapper flex={1} display={'flex'} flexDirection={'column'} marginBottom={2}>\n      <Grid container spacing={5 / 2} paddingX={5 / 2} paddingTop={5 / 2} flex={1}>\n        <Grid item xs={12} md={5} position={'relative'}>\n          <Box display={'flex'} flexDirection={'column'} marginBottom={2}>\n            <FormLabel>\n              <Tooltip title={t('labelIPFSUploadTooltips').toString()} placement={'top'}>\n                <Typography\n                  variant={'body2'}\n                  marginBottom={1}\n                  display={'inline-flex'}\n                  alignItems={'center'}\n                >\n                  <Trans i18nKey={'labelIPFSUploadTitle'}>\n                    Cover Image\n                    <Typography component={'span'} variant={'inherit'} color={'error'}>\n                      {'\\uFE61'}\n                    </Typography>\n                    <Info2Icon fontSize={'small'} color={'inherit'} sx={{ marginX: 1 / 2 }} />\n                  </Trans>\n                </Typography>\n              </Tooltip>\n            </FormLabel>\n            <Box maxWidth={240} maxHeight={240}>\n              <IPFSSourceUpload\n                fullSize={true}\n                value={keys?.image}\n                maxSize={MaxSize}\n                types={TYPES}\n                getIPFSString={getIPFSString}\n                baseURL={baseURL}\n                onChange={(value) => {\n                  onFilesLoad('image', value)\n                }}\n                onDelete={() => onDelete(['image'])}\n              />\n            </Box>\n          </Box>\n          <Box display={'flex'} flexDirection={'column'} marginBottom={2}>\n            <FormLabel>\n              <Tooltip title={t('labelIPFSUploadMediaTooltips').toString()} placement={'top'}>\n                <Typography\n                  variant={'body2'}\n                  marginBottom={1}\n                  display={'inline-flex'}\n                  alignItems={'center'}\n                >\n                  <Trans i18nKey={'labelIPFSUploadMediaTitle'}>\n                    Multimedia Content (image, audio, video and 3D)\n                    <Info2Icon fontSize={'small'} color={'inherit'} sx={{ marginX: 1 / 2 }} />\n                  </Trans>\n                </Typography>\n              </Tooltip>\n            </FormLabel>\n            <Box maxWidth={320}>\n              <IPFSSourceUpload\n                height={'40%'}\n                fullSize={true}\n                value={keys.animationUrl}\n                maxSize={MaxMediaSize}\n                types={[]}\n                messageTypes={MediaTYPES}\n                getIPFSString={getIPFSString}\n                baseURL={baseURL}\n                onChange={(value) => {\n                  onFilesLoad('animationUrl', value)\n                }}\n                onDelete={() => onDelete(['animationUrl'])}\n              />\n            </Box>\n          </Box>\n\n          <Box marginTop={1}>\n            <MuiFormControlLabel\n              control={\n                <Checkbox\n                  checked={nftMetaProps.userAgree}\n                  onChange={(_event: any, state: boolean) => {\n                    nftMetaProps.handleUserAgree(state)\n                  }}\n                  checkedIcon={<CheckedIcon />}\n                  icon={<CheckBoxIcon />}\n                  color='default'\n                />\n              }\n              label={t('labelUseIpfsMintAgree')}\n            />\n          </Box>\n        </Grid>\n        <Grid item xs={12} md={7} flex={1} display={'flex'}>\n          <MintNFTBlock\n            {...nftMetaProps}\n            baseURL={baseURL}\n            domain={domain}\n            handleMintDataChange={nftMintProps.handleMintDataChange}\n            disabled={keys['image']?.isProcessing || keys['animationUrl']?.isProcessing}\n            nftMeta={nftMintValue.nftMETA as Me}\n            mintData={nftMintValue.mintData as Mi}\n            feeInfo={nftMintProps.feeInfo}\n            handleFeeChange={nftMintProps.handleFeeChange}\n          />\n        </Grid>\n        {errorOnMeta && (\n          <Grid item xs={12} md={7} flex={1} display={'flex'}>\n            <Typography\n              marginX={3}\n              whiteSpace={'pre-line'}\n              variant={'body2'}\n              color={'var(--color-text-third)'}\n              component={'div'}\n              marginBottom={2}\n              alignSelf={'flex-center'}\n              paddingX={1}\n              marginY={1}\n              textAlign={'center'}\n            >\n              <Typography\n                variant={'inherit'}\n                display={'inline-flex'}\n                onClick={() => setDropdownErrorStatus((prev) => (prev === 'up' ? 'down' : 'up'))}\n              >\n                {`${t('labelErrorTitle')}`}\n                <TransErrorHelp error={errorOnMeta} />\n                <DropdownIconStyled status={dropdownErrorStatus} fontSize={'medium'} />\n              </Typography>\n\n              {dropdownErrorStatus === 'up' && (\n                <TextareaAutosizeStyled\n                  aria-label='NFT Description'\n                  minRows={4}\n                  disabled={true}\n                  value={`${JSON.stringify(errorOnMeta)}}`}\n                />\n              )}\n\n              {/*{\\`Error Description:\\\\n {code: ${error?.code}, message:${error?.message}}\\`}*/}\n            </Typography>\n          </Grid>\n        )}\n      </Grid>\n    </ImageUploadWrapper>\n  )\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/NFTPage/MyNFT/MyNFTCollectionList.tsx",
    "content": "import { Box, Link, Typography } from '@mui/material'\nimport { NFTSubRouter, RouterPath, TOAST_TIME } from '@loopring-web/common-resources'\nimport { CollectionCardList, Toast, ToastType, useSettings } from '@loopring-web/component-lib'\nimport { useAccount, useMyNFTCollection } from '@loopring-web/core'\nimport React from 'react'\nimport { useHistory, useLocation } from 'react-router-dom'\nimport { Trans, WithTranslation, withTranslation } from 'react-i18next'\nimport styled from '@emotion/styled'\n\nconst _StyledPaper = styled(Box)`\n  background: var(--color-box);\n  border-radius: ${({ theme }) => theme.unit}px;\n`\nexport const MyNFTCollectionList = withTranslation('common')(\n  ({\n    t,\n    size,\n    matchPreUrl,\n  }: {\n    size?: 'large' | 'medium' | 'small' | undefined\n    matchPreUrl: string\n  } & WithTranslation) => {\n    const history = useHistory()\n    const { search } = useLocation()\n    const searchParams = new URLSearchParams(search)\n    const { account } = useAccount()\n    const { isMobile } = useSettings()\n    const { copyToastOpen, ...collectionListProps } = useMyNFTCollection()\n    return (\n      <Box\n        flex={1}\n        marginTop={0}\n        paddingX={2}\n        marginBottom={2}\n        display={'flex'}\n        flexDirection={'column'}\n      >\n        {/*<Typography variant={'body1'} marginY={2} color={'textSecondary'}>\n          <Trans i18nKey={'labelMyCollectionsDes'}>\n            Legacy NFTs created in Loopring don't contain collection information. We have added the\n            feature to allow creators to import the collection information so that those NFTs can be\n            categorized well.\n            <Link\n              href={`/#${RouterPath.nft}/${NFTSubRouter.importLegacyCollection}`}\n              target={'_self'}\n            >\n              Go to Import Collection for Legacy NFT\n            </Link>\n          </Trans>\n        </Typography>*/}\n        <CollectionCardList\n          noEdit={true}\n          account={account}\n          size={size ?? isMobile ? 'small' : 'large'}\n          onItemClick={(item) => {\n            searchParams.set('myNFTPage', '1')\n            history.push({\n              pathname: `${matchPreUrl}byCollection/${item.contractAddress}--${item.id}`,\n              search: searchParams.toString(),\n            })\n            window.scrollTo(0, 0)\n          }}\n          {...{ ...(collectionListProps as any) }}\n        />\n        <Toast\n          alertText={\n            copyToastOpen?.type === 'json'\n              ? t('labelCopyMetaClip')\n              : copyToastOpen.type === 'url'\n              ? t('labelCopyUrlClip')\n              : t('labelCopyAddClip')\n          }\n          open={copyToastOpen?.isShow}\n          autoHideDuration={TOAST_TIME}\n          onClose={() => {\n            collectionListProps.setCopyToastOpen({ isShow: false, type: '' })\n          }}\n          severity={ToastType.success}\n        />\n      </Box>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/webapp/src/pages/NFTPage/MyNFT/MyNFTList.tsx",
    "content": "import {\n  AccountStatus,\n  CollectionMeta,\n  NFTWholeINFO,\n  SagaStatus,\n} from '@loopring-web/common-resources'\nimport { NFTList, useOpenModals, useSettings, useToggle } from '@loopring-web/component-lib'\nimport { getIPFSString, useAccount, useModalData, useSystem } from '@loopring-web/core'\nimport React from 'react'\nimport { useMyNFT } from './useMyNFT'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { Tab, Tabs, Typography } from '@mui/material'\nimport { useLocation } from 'react-router-dom'\n\nexport type MyNFTListProps<NFT> = {\n  collectionMeta: CollectionMeta | undefined\n  collectionPage?: number\n  myNFTPage?: number\n  size?: string\n  isSelect?: boolean\n  selected?: NFT[]\n  isMultipleSelect?: boolean\n  onSelect: (value: NFT) => void\n}\nexport const MyNFTList = withTranslation('common')(\n  <NFT extends NFTWholeINFO>({\n    collectionMeta,\n    collectionPage,\n    myNFTPage,\n    size,\n    isSelect,\n    selected,\n    isMultipleSelect,\n    onSelect,\n    t,\n  }: MyNFTListProps<NFT> & WithTranslation) => {\n    const { baseURL } = useSystem()\n    const { isMobile } = useSettings()\n    const { status: accountStatus, account } = useAccount()\n    const { search } = useLocation()\n    const searchParam = new URLSearchParams(search)\n    const [tab, setTab] = React.useState<sdk.NFT_PREFERENCE_TYPE | 'all'>('all')\n    const nftProps = useMyNFT({\n      collectionMeta,\n      collectionPage,\n      myNFTPage,\n    })\n    const {\n      // setShowNFTDetail,\n      // setShowAccount,\n      setShowNFTDeploy,\n      setShowNFTDetail,\n      setShowNFTTransfer,\n      setShowNFTWithdraw,\n      setShowTradeIsFrozen,\n      setShowRedPacket,\n      setShowAccount,\n      setNFTMetaNotReady,\n      // modals: { isShowNFTDetail },\n    } = useOpenModals()\n    const { updateNFTDeployData, updateNFTTransferData, updateNFTWithdrawData } = useModalData()\n    const { toggle } = useToggle()\n\n    const onPageChange = React.useCallback(\n      (page, filter) => {\n        nftProps.onPageChange(page, { ...filter })\n      },\n      [nftProps?.onPageChange],\n    )\n    const handleTabChange = React.useCallback(\n      (_e, value, page = 1) => {\n        let _filter = {}\n        setTab(value)\n        switch (value) {\n          case 'all':\n            _filter = { favourite: false, hidden: false }\n            break\n          case sdk.NFT_PREFERENCE_TYPE.fav:\n            _filter = { favourite: true }\n            break\n          case sdk.NFT_PREFERENCE_TYPE.hide:\n            _filter = { favourite: false, hidden: true }\n            break\n        }\n        onPageChange(page, _filter)\n      },\n      [tab, onPageChange],\n    )\n\n    React.useEffect(() => {\n      if (\n        accountStatus === SagaStatus.UNSET &&\n        account.readyState === AccountStatus.ACTIVATED &&\n        nftProps?.collectionMeta?.contractAddress === collectionMeta?.contractAddress\n      ) {\n        const page = myNFTPage\n        // const page = searchParam.get(\"myNFTPage\");\n        const filter = JSON.parse(\n          searchParam.get('filter') ??\n            JSON.stringify({\n              favourite: false,\n              hidden: false,\n            }),\n        )\n        let tab = filter?.favourite\n          ? sdk.NFT_PREFERENCE_TYPE.fav\n          : filter?.hidden\n          ? sdk.NFT_PREFERENCE_TYPE.hide\n          : 'all'\n\n        handleTabChange(undefined, tab, page ?? 1)\n      }\n    }, [nftProps?.collectionMeta?.contractAddress, accountStatus, myNFTPage, account.readyState])\n\n    return (\n      <>\n        <Tabs value={tab} onChange={handleTabChange} aria-label='NFT Group Tab'>\n          {['all', sdk.NFT_PREFERENCE_TYPE.fav, sdk.NFT_PREFERENCE_TYPE.hide].map((item) => {\n            return (\n              <Tab\n                disabled={nftProps?.isLoading}\n                key={item.toString()}\n                value={item.toString()}\n                label={\n                  <Typography component={'span'} display={'inline-flex'} alignItems={'center'}>\n                    {t(`labelNFTList${item}`)}\n                  </Typography>\n                  // </Tooltip>\n                }\n              />\n            )\n          })}\n        </Tabs>\n        <NFTList\n          {...{\n            ...nftProps,\n            baseURL,\n            onClick: isSelect\n              ? (value: NFT) => {\n                  onSelect(value)\n                }\n              : nftProps.onDetail,\n            getIPFSString,\n          }}\n          onPageChange={(page) => {\n            const filter = JSON.parse(\n              searchParam.get('filter') ??\n                JSON.stringify({\n                  favourite: false,\n                  hidden: false,\n                }),\n            )\n            onPageChange(page, filter)\n          }}\n          account={account}\n          isEdit={false}\n          isSelectOnly={isSelect}\n          isMultipleSelect={isMultipleSelect}\n          selected={selected}\n          toggle={toggle}\n          // @ts-ignore\n          setShowNFTDeploy={(item: any) => {\n            updateNFTDeployData({ ...item })\n            setShowNFTDeploy({ isShow: true, info: { ...{ item } } })\n            setShowAccount({ isShow: false })\n          }}\n          setShowNFTDetail={(item: any) => {\n            // updateNFTDetail({...item})\n            setShowNFTDetail({ isShow: true, info: { ...{ item } } })\n            setShowAccount({ isShow: false })\n          }}\n          setShowNFTTransfer={(item: any) => {\n            updateNFTTransferData({ ...item })\n            setShowNFTTransfer({ isShow: false, info: { ...{ item } } })\n            setShowAccount({ isShow: false })\n          }}\n          setShowNFTWithdraw={(item: any) => {\n            updateNFTWithdrawData({ ...item })\n            setShowNFTWithdraw({ isShow: false, info: { ...{ item } } })\n            setShowAccount({ isShow: false })\n          }}\n          setShowTradeIsFrozen={setShowTradeIsFrozen}\n          setShowRedPacket={(item: any) => {\n            setShowRedPacket({ isShow: true, info: { ...item } })\n            setShowAccount({ isShow: false })\n          }}\n          setShowAccount={setShowAccount}\n          setNFTMetaNotReady={setNFTMetaNotReady}\n          isManage={false}\n          size={size ?? isMobile ? 'small' : 'large'}\n        />\n      </>\n    )\n  },\n) as <NFT extends NFTWholeINFO>(pros: MyNFTListProps<NFT>) => JSX.Element\n"
  },
  {
    "path": "packages/webapp/src/pages/NFTPage/MyNFT/index.tsx",
    "content": "import React from 'react'\nimport { useTranslation } from 'react-i18next'\n\nimport { useHistory, useLocation, useRouteMatch } from 'react-router-dom'\nimport { MyNFTList } from './MyNFTList'\nimport { NFTDetail, useSystem, useToast } from '@loopring-web/core'\nimport {\n  BackIcon,\n  CollectionMeta,\n  EmptyValueTag,\n  getShortAddr,\n  htmlDecode,\n  MY_NFT_VIEW,\n  NFTSubRouter,\n  NFTWholeINFO,\n  RouterPath,\n  SoursURL,\n  TOAST_TIME,\n} from '@loopring-web/common-resources'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { MyNFTCollectionList } from './MyNFTCollectionList'\nimport { Box, Breadcrumbs, Link, Tab, Tabs, Typography } from '@mui/material'\nimport {\n  Button,\n  Toast,\n  ToastType,\n  ToggleState,\n  useOpenModals,\n  useSettings,\n  useToggle,\n} from '@loopring-web/component-lib'\nimport { sanitize } from 'dompurify'\nimport { useNFTCollection } from './useMyNFT'\nimport { XOR } from '@loopring-web/loopring-sdk'\n\nexport const MyNFTPanelUI = <NFT extends NFTWholeINFO>({\n  tabBy,\n  matchPreUrl,\n  contractStr,\n  isSelect = false,\n  isMultipleSelect,\n  collectionMeta,\n  toggle,\n  selected,\n  onSelect,\n  size = 'medium',\n}: {\n  tabBy: MY_NFT_VIEW\n  matchPreUrl: string\n  contractStr: string\n  filter: string\n  toggle: ToggleState\n  collectionMeta?: CollectionMeta\n  size?: 'small' | 'large' | 'medium'\n} & XOR<\n  {\n    isSelect: true\n    selected: NFT[]\n    isMultipleSelect: boolean\n    onSelect: (value: NFT) => void\n  },\n  { isSelect?: false }\n>) => {\n  const { t } = useTranslation('common')\n  const [currentTab, setCurrentTab] = React.useState(tabBy)\n  const { toastOpen, closeToast } = useToast()\n  const { isMobile } = useSettings()\n  const history = useHistory()\n  const { search } = useLocation()\n  const { setShowTradeIsFrozen } = useOpenModals()\n  const searchParams = new URLSearchParams(search)\n\n  return (\n    <Box flex={1} display={'flex'} flexDirection={'column'}>\n      {tabBy === MY_NFT_VIEW.LIST_COLLECTION && contractStr ? (\n        <>\n          <Box\n            display={'flex'}\n            flexDirection={'row'}\n            alignItems={'center'}\n            justifyContent={'space-between'}\n            marginBottom={2}\n          >\n            <Button\n              startIcon={<BackIcon fontSize={'small'} />}\n              variant={'text'}\n              size={'medium'}\n              sx={{ color: 'var(--color-text-secondary)' }}\n              color={'inherit'}\n              onClick={() => history.push(`${matchPreUrl}byCollection?${searchParams.toString()}`)}\n            >\n              <Typography\n                component={'span'}\n                color={'inherit'}\n                dangerouslySetInnerHTML={{\n                  __html: sanitize(\n                    t('labelNFTMyNFT', {\n                      collection: collectionMeta\n                        ? collectionMeta.name\n                          ? htmlDecode(collectionMeta?.name)\n                          : t('labelUnknown') +\n                            ' - ' +\n                            getShortAddr(collectionMeta.contractAddress ?? '')\n                        : EmptyValueTag,\n                    }),\n                  ),\n                }}\n              />\n            </Button>\n          </Box>\n          {collectionMeta ? (\n            <Box flex={1} display={'flex'} flexDirection={'column'} alignItems={'stretch'}>\n              <MyNFTList\n                collectionMeta={collectionMeta}\n                collectionPage={\n                  searchParams?.get('collectionPage')\n                    ? Number(searchParams?.get('collectionPage'))\n                    : 1\n                }\n                size={size}\n                onSelect={onSelect as any}\n                isSelect={isSelect}\n                isMultipleSelect={isMultipleSelect}\n                selected={selected}\n                myNFTPage={\n                  searchParams?.get('myNFTPage') ? Number(searchParams?.get('myNFTPage')) : 1\n                }\n              />\n            </Box>\n          ) : (\n            <Box\n              flex={1}\n              display={'flex'}\n              alignItems={'center'}\n              justifyContent={'center'}\n              height={'90%'}\n            >\n              <img\n                className='loading-gif'\n                alt={'loading'}\n                width='36'\n                src={`${SoursURL}images/loading-line.gif`}\n              />\n            </Box>\n          )}\n        </>\n      ) : (\n        <>\n          <Box\n            display={'flex'}\n            justifyContent={'space-between'}\n            alignItems={isMobile ? 'stretch' : 'center'}\n            marginBottom={1}\n            flexDirection={isMobile ? 'column' : 'row'}\n          >\n            <Tabs\n              value={currentTab}\n              onChange={(_event, value) => {\n                history.replace(`${matchPreUrl}${value}`)\n                setCurrentTab(value)\n              }}\n              aria-label='my-nft-tabs'\n              variant='scrollable'\n              sx={{ order: isMobile ? 1 : 0 }}\n            >\n              <Tab label={t('labelNFTMyNFTList')} value={MY_NFT_VIEW.LIST_NFT} />\n              <Tab label={t('labelNFTMyNFTCollection')} value={MY_NFT_VIEW.LIST_COLLECTION} />\n            </Tabs>\n            {!isSelect && (\n              <Box\n                sx={{ order: isMobile ? 0 : 0 }}\n                display={'flex'}\n                flexDirection={'row'}\n                paddingX={isMobile ? 0 : 5 / 2}\n                paddingY={isMobile ? 2 : 0}\n              >\n                <Box marginLeft={1}>\n                  <Button\n                    variant={'contained'}\n                    size={'small'}\n                    color={'primary'}\n                    // disabled={!toggle.depositNFT}\n                    onClick={() => {\n                      if (toggle.depositNFT.enable) {\n                        history.push(`${RouterPath.nft}/${NFTSubRouter.depositNFT}`)\n                      } else {\n                        setShowTradeIsFrozen({ isShow: true, type: 'Deposit' })\n                      }\n                    }}\n                  >\n                    {t('labelL1toL2NFT')}\n                  </Button>\n                </Box>\n                <Box marginLeft={1}>\n                  <Button\n                    variant={'outlined'}\n                    color={'primary'}\n                    onClick={() => history.push(`${RouterPath.nft}/${NFTSubRouter.transactionNFT}`)}\n                  >\n                    {t('labelTransactionNFT')}\n                  </Button>\n                </Box>\n              </Box>\n            )}\n          </Box>\n          <Box display={'flex'} flex={1} flexDirection={'column'} justifyContent={'stretch'}>\n            {currentTab === MY_NFT_VIEW.LIST_NFT && (\n              <MyNFTList\n                size={size}\n                onSelect={onSelect as any}\n                collectionMeta={undefined}\n                isSelect={isSelect}\n                isMultipleSelect={isMultipleSelect}\n                selected={selected}\n                myNFTPage={\n                  searchParams?.get('myNFTPage') ? Number(searchParams?.get('myNFTPage')) : 1\n                }\n              />\n            )}\n            {currentTab === MY_NFT_VIEW.LIST_COLLECTION && (\n              <MyNFTCollectionList size={size} matchPreUrl={matchPreUrl} />\n            )}\n          </Box>\n        </>\n      )}\n\n      <Toast\n        alertText={toastOpen?.content ?? ''}\n        severity={toastOpen?.type ?? ToastType.success}\n        open={toastOpen?.open ?? false}\n        autoHideDuration={TOAST_TIME}\n        onClose={closeToast}\n      />\n    </Box>\n  )\n}\nexport const MyNFTPanel = ({}: any) => {\n  const matchPreUrl = '/nft/assetsNFT/'\n  const preMatch = useRouteMatch(`/nft/assetsNFT/:tab?/:contract?`)\n  const { baseURL, etherscanBaseUrl } = useSystem()\n  const { search, pathname } = useLocation()\n  const history = useHistory()\n  const { t } = useTranslation('common')\n  const { toggle } = useToggle()\n  const searchParams = new URLSearchParams(search)\n  const filter = JSON.parse(\n    searchParams.get('filter') ??\n      JSON.stringify({\n        favourite: false,\n        hidden: false,\n      }),\n  )\n  const tabBy = preMatch?.params['tab'] ?? MY_NFT_VIEW.LIST_COLLECTION\n  const contractStr = preMatch?.params['contract'] ?? ''\n  const { collectionMeta } = useNFTCollection({ contractStr, matchPreUrl })\n  const {\n    modals: { isShowNFTDetail },\n    setShowNFTDetail,\n    setNFTMetaNotReady,\n  } = useOpenModals()\n  React.useEffect(() => {\n    if (isShowNFTDetail.isShow) {\n      searchParams.set('detail', 'true')\n    } else {\n      searchParams.delete('detail')\n    }\n    history.replace(pathname + '?' + searchParams.toString())\n\n    return () => {\n      if (isShowNFTDetail.isShow) {\n        setShowNFTDetail({ isShow: false })\n      }\n    }\n  }, [isShowNFTDetail.isShow])\n  const breadcrumbs = React.useMemo(() => {\n    const [contract, id] = contractStr ? contractStr.split('--') : [null, null]\n    return [\n      <Link\n        underline='hover'\n        key='1'\n        color='inherit'\n        onClick={() => {\n          if (tabBy === MY_NFT_VIEW.LIST_NFT) {\n            history.replace(\n              `${matchPreUrl}${tabBy ?? MY_NFT_VIEW.LIST_NFT}?${searchParams.toString()}`,\n            )\n          } else {\n            history.replace(`${matchPreUrl}byCollection?${searchParams.toString()}`)\n          }\n          setShowNFTDetail({ isShow: false })\n        }}\n      >\n        {t('labelNFTTitleMyNFT')}\n      </Link>,\n      ...[\n        tabBy === MY_NFT_VIEW.LIST_COLLECTION && contract && id && contract.startsWith('0x')\n          ? [\n              <Link\n                underline='hover'\n                key='2'\n                color='inherit'\n                onClick={() => {\n                  history.replace(\n                    `${matchPreUrl}${\n                      MY_NFT_VIEW.LIST_COLLECTION\n                    }/${contract}--${id}?${searchParams.toString()}`,\n                  )\n                  setShowNFTDetail({ isShow: false })\n                }}\n              >\n                <Typography\n                  component={'span'}\n                  color={'inherit'}\n                  dangerouslySetInnerHTML={{\n                    __html: sanitize(\n                      t('labelNFTMyCollection', {\n                        collection: collectionMeta\n                          ? collectionMeta.name\n                            ? htmlDecode(collectionMeta?.name)\n                            : t('labelUnknown') +\n                              ' - ' +\n                              getShortAddr(collectionMeta.contractAddress ?? '')\n                          : EmptyValueTag,\n                      }),\n                    ),\n                  }}\n                />\n              </Link>,\n            ]\n          : [],\n      ],\n      <Typography key='3' color={'textPrimary'}>\n        {t('labelDetail')}\n      </Typography>,\n    ]\n  }, [contractStr, tabBy, collectionMeta, searchParams.get('filter')])\n\n  return (\n    <>\n      {isShowNFTDetail.isShow ? (\n        <>\n          <Breadcrumbs\n            separator={<BackIcon fontSize={'small'} sx={{ transform: 'rotate(180deg)' }} />}\n            aria-label='breadcrumb'\n          >\n            {breadcrumbs}\n          </Breadcrumbs>\n          <NFTDetail\n            baseURL={baseURL}\n            etherscanBaseUrl={etherscanBaseUrl}\n            popItem={isShowNFTDetail}\n            assetsRawData={[]}\n            setNFTMetaNotReady={setNFTMetaNotReady}\n          />\n        </>\n      ) : (\n        <MyNFTPanelUI\n          tabBy={tabBy}\n          filter={\n            filter?.favourite\n              ? sdk.NFT_PREFERENCE_TYPE.fav\n              : filter?.hidden\n              ? sdk.NFT_PREFERENCE_TYPE.hide\n              : 'all'\n          }\n          toggle={toggle}\n          collectionMeta={collectionMeta}\n          contractStr={contractStr}\n          matchPreUrl={matchPreUrl}\n        />\n      )}\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/NFTPage/MyNFT/useMyNFT.ts",
    "content": "import {\n  CollectionLimit,\n  CollectionMeta,\n  CustomError,\n  ErrorMap,\n  myLog,\n  MyNFTFilter,\n  NFTWholeINFO,\n  SagaStatus,\n} from '@loopring-web/common-resources'\nimport React from 'react'\nimport {\n  LoopringAPI,\n  store,\n  useAccount,\n  useModalData,\n  useNFTListDeep,\n  useSystem,\n  useWalletL2NFTCollection,\n  useWalletLayer2NFT,\n} from '@loopring-web/core'\nimport { useOpenModals } from '@loopring-web/component-lib'\nimport { BigNumber } from 'bignumber.js'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { useHistory, useLocation } from 'react-router-dom'\n\nBigNumber.config({ EXPONENTIAL_AT: 100 })\nexport const useMyNFT = ({\n  collectionMeta,\n  collectionPage,\n  myNFTPage,\n}: {\n  collectionMeta: CollectionMeta | undefined\n  collectionPage?: number\n  myNFTPage?: number\n}) => {\n  const { search, ...rest } = useLocation()\n  const { renderNFTPromise, infoDetail, nftListReduce } = useNFTListDeep()\n  const history = useHistory()\n  const [filter, setFilter] = React.useState<MyNFTFilter | undefined>(undefined)\n  const searchParams = new URLSearchParams(search)\n  const [nftList, setNFTList] = React.useState<Partial<NFTWholeINFO>[]>([])\n  const [isLoading, setIsLoading] = React.useState(true)\n  const { account } = useAccount()\n  const {\n    status: walletLayer2NFTStatus,\n    walletLayer2NFT,\n    total,\n    page: page_redux,\n    collection: collection_redux,\n    updateWalletLayer2NFT,\n  } = useWalletLayer2NFT()\n  const { updateNFTTransferData, updateNFTWithdrawData, updateNFTDeployData } = useModalData()\n\n  const {\n    setShowNFTDetail,\n    modals: { isShowNFTDetail },\n  } = useOpenModals()\n  const { etherscanBaseUrl } = useSystem()\n  const [page, setPage] = React.useState(-1)\n\n  // const onDetailClose = React.useCallback(() => setIsShow(false), []);\n\n  const onPageChange = (page: number = 1, filter?: MyNFTFilter | undefined) => {\n    setFilter(filter ?? undefined)\n    setPage(page)\n    setIsLoading(true)\n    if (page !== -1) {\n      updateWalletLayer2NFT({\n        page,\n        collectionId: collectionMeta?.id?.toString() ?? undefined,\n        collectionContractAddress: collectionMeta?.contractAddress.toString()\n          ? collectionMeta?.contractAddress.toString()\n          : collectionMeta?.collectionAddress?.toString() ?? undefined,\n        filter,\n      })\n    }\n    searchParams.set('myNFTPage', page.toString())\n    if (filter) {\n      searchParams.set('filter', JSON.stringify(filter))\n    }\n    history.replace({ ...rest, search: searchParams.toString() })\n  }\n\n  const onDetail = React.useCallback(\n    async (item: Partial<NFTWholeINFO>) => {\n      let _collectionMeta = item.collectionInfo ?? collectionMeta\n      if (\n        item.hasOwnProperty('pendingOnSync') &&\n        !item.collectionInfo &&\n        collectionMeta === undefined &&\n        LoopringAPI.userAPI\n      ) {\n        const response = await LoopringAPI.userAPI\n          .getUserNFTCollection(\n            {\n              accountId: account.accountId.toString(),\n              //@ts-ignore\n              tokenAddress: item.tokenAddress,\n            },\n            account.apiKey,\n          )\n          .catch((_error) => {\n            throw new CustomError(ErrorMap.TIME_OUT)\n          })\n        if (\n          response &&\n          ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message)\n        ) {\n          throw new CustomError(ErrorMap.ERROR_UNKNOWN)\n        }\n        _collectionMeta = response.collections?.find((_item: CollectionMeta) => {\n          return (\n            _item?.contractAddress?.toLowerCase() === item?.tokenAddress?.toLowerCase() &&\n            _item.baseUri !== ''\n          )\n        })\n      }\n      window.scrollTo(0, 0)\n      setShowNFTDetail({\n        isShow: true,\n        ...item,\n        collectionInfo: _collectionMeta,\n      })\n      updateNFTWithdrawData({ ...item, collectionInfo: _collectionMeta })\n      updateNFTTransferData({ ...item, collectionInfo: _collectionMeta })\n      if (\n        item.isCounterFactualNFT &&\n        item.deploymentStatus === sdk.DEPLOYMENT_STATUS.NOT_DEPLOYED\n      ) {\n        await LoopringAPI.userAPI?.getAvailableBroker({ type: 0 }).then(({ broker }) => {\n          updateNFTDeployData({ broker })\n        })\n        updateNFTDeployData({ ...item, collectionInfo: _collectionMeta })\n      }\n    },\n    [\n      collectionMeta,\n      setShowNFTDetail,\n      updateNFTDeployData,\n      updateNFTTransferData,\n      updateNFTWithdrawData,\n    ],\n  )\n\n  const onNFTReload = async (item: Partial<NFTWholeINFO>, index?: number) => {\n    const tokenInfo = await infoDetail(item)\n    let _index = index\n\n    setNFTList((state) => {\n      if (index === undefined) {\n        _index = state.findIndex(\n          (_item) =>\n            _item.tokenAddress?.toLowerCase() === item.tokenAddress?.toLowerCase() &&\n            _item.nftId === item.nftId,\n        )\n      }\n      if (_index) {\n        state[_index] = {\n          ...state[_index],\n          isFailedLoadMeta: false,\n          ...tokenInfo,\n        }\n      }\n      return state\n    })\n  }\n\n  const renderNFT = React.useCallback(async () => {\n    setNFTList(nftListReduce(walletLayer2NFT))\n    setIsLoading(false)\n    renderNFTPromise({ nftLists: walletLayer2NFT as any }).then((meta: any[]) => {\n      const {\n        walletLayer2NFT,\n        page: page_reudex,\n        filter: filter_redux,\n      } = store.getState().walletLayer2NFT\n      myLog('walletLayer2NFT  async media render', page, page_reudex)\n      if (\n        page === page_reudex &&\n        (!filter ||\n          (filter &&\n            filter?.favourite == filter_redux?.favourite &&\n            filter?.hidden == filter_redux?.hidden))\n      ) {\n        setNFTList((state) => {\n          return walletLayer2NFT.map((item, index) => {\n            return {\n              ...state[index],\n              ...meta[index],\n              tokenAddress: item.tokenAddress?.toLowerCase(),\n              etherscanBaseUrl,\n            }\n          })\n        })\n      }\n    })\n  }, [etherscanBaseUrl, page, walletLayer2NFT, filter])\n\n  React.useEffect(() => {\n    if (\n      walletLayer2NFTStatus === SagaStatus.UNSET &&\n      Number(page_redux) === Number(page) &&\n      ((collectionMeta === undefined && collection_redux === undefined) ||\n        (collection_redux?.id == collectionMeta?.id &&\n          collection_redux?.contractAddress == collectionMeta?.contractAddress))\n    ) {\n      renderNFT()\n    }\n  }, [walletLayer2NFTStatus, page, collectionMeta, page_redux, collection_redux])\n\n  return {\n    collectionMeta,\n    nftList,\n    onDetail,\n    etherscanBaseUrl,\n    onNFTReload,\n    onPageChange,\n    total,\n    page,\n    isLoading,\n    walletLayer2NFT,\n  }\n}\n\nexport const useNFTCollection = ({\n  contractStr,\n  matchPreUrl,\n}: {\n  contractStr: string\n  matchPreUrl: string\n}) => {\n  const history = useHistory()\n  const { search } = useLocation()\n\n  const searchParams = new URLSearchParams(search)\n  const { walletL2NFTCollection } = useWalletL2NFTCollection()\n  const {\n    account: { accountId, apiKey },\n  } = useAccount()\n\n  const [collectionMeta, setCollectionMeta] = React.useState<undefined | CollectionMeta>(undefined)\n  const checkCollection = async () => {\n    const [contract, id] = contractStr ? contractStr.split('--') : [null, null]\n    if (contract !== undefined && id !== undefined && LoopringAPI.userAPI) {\n      const collectionMeta = walletL2NFTCollection.find((item) => {\n        return (\n          (id !== undefined ? Number(item.id) === Number(id) : true) &&\n          item.contractAddress?.toLowerCase() === contract?.toLowerCase()\n        )\n      })\n      if (collectionMeta) {\n        setCollectionMeta(collectionMeta)\n        return\n      } else {\n        const response = await LoopringAPI.userAPI\n          .getUserNFTCollection(\n            {\n              tokenAddress: contract,\n              collectionId: id,\n              accountId: accountId.toString(),\n              limit: CollectionLimit,\n            } as any,\n            apiKey,\n          )\n          .catch((_error) => {\n            throw new CustomError(ErrorMap.TIME_OUT)\n          })\n        if (\n          response &&\n          ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message)\n        ) {\n          throw new CustomError(ErrorMap.ERROR_UNKNOWN)\n        }\n        const collections = response.collections\n        if (collections.length) {\n          const collectionMeta = collections.find((item: any) => {\n            return (\n              (id !== undefined ? Number(item.id) === Number(id) : true) &&\n              item.contractAddress?.toLowerCase() === contract?.toLowerCase()\n            )\n          })\n\n          setCollectionMeta(collectionMeta)\n          return\n        } else {\n          history.push(`${matchPreUrl}/byCollection` + '?' + searchParams.toString())\n        }\n      }\n    }\n  }\n\n  React.useEffect(() => {\n    const [contract, id] = contractStr ? contractStr.split('--') : [null, null]\n    if (contract && id && contract.startsWith('0x')) {\n      checkCollection()\n    }\n  }, [contractStr])\n  return {\n    collectionMeta,\n  }\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/NFTPage/NFTDeposit/index.tsx",
    "content": "import styled from '@emotion/styled'\nimport { Box, Typography } from '@mui/material'\nimport React from 'react'\nimport {\n  Button,\n  DepositNFTWrap,\n  PopoverPure,\n  useOpenModals,\n  useSettings,\n  useToggle,\n} from '@loopring-web/component-lib'\n\nimport { useNFTDeposit } from '@loopring-web/core'\nimport { BackIcon, Info2Icon, L1L2_NAME_DEFINED, MapChainId } from '@loopring-web/common-resources'\nimport { bindHover } from 'material-ui-popup-state/es'\nimport { bindPopper, usePopupState } from 'material-ui-popup-state/hooks'\nimport { Trans, useTranslation } from 'react-i18next'\nimport { useHistory } from 'react-router-dom'\n\nconst StyledPaper = styled(Box)`\n  background: var(--color-box-third);\n  border-radius: ${({ theme }) => theme.unit}px;\n`\n\nexport const DepositNFTPanel = () => {\n  const { nftDepositProps } = useNFTDeposit()\n  const { t } = useTranslation(['common'])\n  const history = useHistory()\n  const { setShowTradeIsFrozen } = useOpenModals()\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  const popupState = usePopupState({\n    variant: 'popover',\n    popupId: `popupId-nftDeposit`,\n  })\n  const { toggle } = useToggle()\n  React.useEffect(() => {\n    if (!toggle.depositNFT?.enable) {\n      setShowTradeIsFrozen({ isShow: true, type: 'Deposit' })\n      history.goBack()\n    }\n  }, [toggle.depositNFT?.enable])\n  return (\n    <Box flex={1} display={'flex'} flexDirection={'column'}>\n      <Box marginBottom={2}>\n        <Button\n          startIcon={<BackIcon fontSize={'small'} />}\n          variant={'text'}\n          size={'medium'}\n          sx={{ color: 'var(--color-text-secondary)' }}\n          color={'inherit'}\n          onClick={history.goBack}\n        >\n          {t('labelNFTDepositLabel')}\n          {/*<Typography color={\"textPrimary\"}></Typography>*/}\n        </Button>\n      </Box>\n      <StyledPaper\n        flex={1}\n        className={'MuiPaper-elevation2'}\n        marginTop={0}\n        marginBottom={2}\n        display={'flex'}\n        flexDirection={'column'}\n      >\n        <Typography\n          component={'h3'}\n          variant={'h4'}\n          paddingX={5 / 2}\n          paddingTop={5 / 2}\n          display={'inline-flex'}\n          alignItems={'center'}\n        >\n          <Typography variant={'inherit'} component={'span'}>\n            {nftDepositProps.title\n              ? nftDepositProps.title\n              : t('labelNFTDepositTitle', { l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol })}\n          </Typography>\n          <Info2Icon\n            {...bindHover(popupState)}\n            fontSize={'large'}\n            htmlColor={'var(--color-text-third)'}\n          />\n\n          <PopoverPure\n            className={'arrow-center'}\n            {...bindPopper(popupState)}\n            anchorOrigin={{\n              vertical: 'bottom',\n              horizontal: 'center',\n            }}\n            transformOrigin={{\n              vertical: 'top',\n              horizontal: 'center',\n            }}\n          >\n            <Typography padding={2} component={'p'} variant={'body2'} whiteSpace={'pre-line'}>\n              <Trans\n                i18nKey={\n                  nftDepositProps.description\n                    ? nftDepositProps.description\n                    : 'nftDepositDescription'\n                }\n                tOptions={{\n                  loopringLayer2: L1L2_NAME_DEFINED[network].loopringLayer2,\n                  loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n                  l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n                  l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n                  ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n                }}\n              >\n                Creates a smart contract on Ethereum L1, which requires a gas fee. NFTs minted here\n                are on L2 only until deployed.\n              </Trans>\n            </Typography>\n          </PopoverPure>\n        </Typography>\n\n        <DepositNFTWrap {...nftDepositProps} />\n      </StyledPaper>\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/NFTPage/NFThistory/hookHistory.ts",
    "content": "import React from 'react'\nimport { LoopringAPI, useAccount, useSystem, volumeToCountAsBigNumber } from '@loopring-web/core'\nimport { BigNumber } from 'bignumber.js'\nimport {\n  NFTTableFilter,\n  NFTTableProps,\n  NFTTradeFilter,\n  NFTTradeProps,\n  TxnDetailProps,\n  useSettings,\n} from '@loopring-web/component-lib'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { RowConfig, UNIX_TIMESTAMP_FORMAT } from '@loopring-web/common-resources'\n\nBigNumber.config({ EXPONENTIAL_AT: 100 })\nconst LimitNFTHistory = 20\n\nexport const useHistoryNFT = <\n  Row extends TxnDetailProps,\n  TradeRow extends sdk.UserNFTTradeHistory,\n>() => {\n  const { etherscanBaseUrl } = useSystem()\n  const { account } = useAccount()\n  const { isMobile } = useSettings()\n  const [tabIndex, setTabIndex] = React.useState(0)\n  const container = React.useRef(null)\n  // const [showLoading, setShowLoading] = useState(false);\n\n  const [nftHistory, setNftHistory] = React.useState<{\n    userNFTTxs: Partial<NFTTableProps<Row>>\n  }>({\n    userNFTTxs: {\n      etherscanBaseUrl,\n      rawData: [],\n      pagination: {\n        pageSize: LimitNFTHistory,\n        total: 0,\n      },\n      txType: sdk.UserNFTTxTypes[sdk.TxNFTType.ALL],\n      showloading: false,\n    },\n  })\n\n  const [nftTrades, setTrades] = React.useState<{\n    nftTrades: NFTTradeProps<TradeRow>\n  }>({\n    nftTrades: {\n      etherscanBaseUrl,\n      rawData: [],\n      pagination: {\n        pageSize: LimitNFTHistory,\n        total: 0,\n        page: 1,\n      },\n      showLoading: false,\n      // getTxnList: (filter: NFTTradeFilter) => Promise<void>;\n      showFilter: true,\n      accAddress: account.accAddress,\n      accountId: account.accountId,\n    } as unknown as NFTTradeProps<TradeRow>,\n  })\n\n  const getTxnList = React.useCallback(\n    async ({\n      page = 1,\n      limit,\n      txType = sdk.UserNFTTxTypes[sdk.TxNFTType.ALL],\n      duration = [null, null],\n    }: NFTTableFilter) => {\n      if (LoopringAPI.userAPI) {\n        const _limit = limit ? limit : nftHistory.userNFTTxs.pagination?.pageSize ?? LimitNFTHistory\n\n        const { totalNum, userNFTTxs } = await LoopringAPI.userAPI.getUserNFTTransactionHistory(\n          {\n            accountId: account.accountId,\n            // @ts-ignore\n            metadata: true,\n            offset: (page - 1) * _limit,\n            types: txType ? ([txType] as any[]) : undefined,\n            // start: (page - 1) * limit,\n            start:\n              duration && duration[0]\n                ? (duration[0] as any)?.format(UNIX_TIMESTAMP_FORMAT) ?? undefined\n                : undefined,\n            end:\n              duration && duration[1]\n                ? (duration[1] as any)?.format(UNIX_TIMESTAMP_FORMAT) ?? undefined\n                : undefined,\n            limit: _limit,\n          },\n          account.apiKey,\n        )\n        setNftHistory((state) => {\n          return {\n            ...state,\n            userNFTTxs: {\n              ...state.userNFTTxs,\n              totalNum,\n              duration,\n              txType,\n              // limit,\n              page,\n              pagination: {\n                pageSize: limit ?? nftHistory.userNFTTxs.pagination?.pageSize ?? LimitNFTHistory,\n                total: totalNum,\n              },\n              rawData: (userNFTTxs ?? []).map((item) => {\n                return {\n                  ...item,\n                  amount: item.amount.toString(),\n                  // (item.payeeAddress === account.accAddress ? \"+\" : \"-\") +\n                  // item.amount.toString(),\n                  fee: {\n                    unit: item.feeTokenSymbol || '',\n                    value: Number(\n                      volumeToCountAsBigNumber(item.feeTokenSymbol, item.feeAmount || 0),\n                    ),\n                  },\n                }\n              }) as Row[],\n            },\n          }\n        })\n      }\n    },\n    [nftHistory],\n  )\n\n  const getTradeList = React.useCallback(\n    async ({\n      page = 1,\n      limit,\n      start,\n      end,\n      side = undefined,\n    }: // duration = [null, null],\n    NFTTradeFilter) => {\n      if (LoopringAPI.userAPI) {\n        setTrades((state) => ({\n          ...state,\n          nftTrades: {\n            ...state.nftTrades,\n            showLoading: true,\n          },\n        }))\n        const _limit = limit ? limit : nftHistory.userNFTTxs.pagination?.pageSize ?? LimitNFTHistory\n\n        const result = await LoopringAPI.userAPI.getUserNFTTradeHistory(\n          {\n            accountId: account.accountId,\n            offset: (page - 1) * _limit,\n            limit: _limit,\n            start,\n            end,\n            metadata: true,\n            side: side as sdk.NFT_TRADE,\n          },\n          account.apiKey,\n        )\n        const { totalNum, trades } = result as any\n        setTrades((state) => {\n          return {\n            ...state,\n            nftTrades: {\n              ...state.nftTrades,\n              totalNum,\n              pagination: {\n                pageSize: limit ?? nftHistory.userNFTTxs.pagination?.pageSize ?? LimitNFTHistory,\n                total: totalNum,\n                page,\n              },\n              showLoading: false,\n              rawData: trades as TradeRow[],\n            },\n          }\n        })\n      }\n    },\n    [nftHistory],\n  )\n\n  React.useEffect(() => {\n    // @ts-ignore\n    let height = container?.current?.offsetHeight\n    const pageSize = Math.floor(height / RowConfig.rowHeight) - (isMobile ? 1 : 3)\n    if (height) {\n      setNftHistory((state) => {\n        const userNFTTxs = state.userNFTTxs\n\n        userNFTTxs.pagination = {\n          ...state.userNFTTxs.pagination,\n          pageSize,\n        } as any\n        getTxnList({\n          page: 1,\n          limit: pageSize,\n          txType: userNFTTxs.txType,\n          duration: userNFTTxs.duration,\n        })\n        return state\n      })\n      setTrades((state) => {\n        const nftTrades = state.nftTrades\n        nftTrades.currentHeight = height\n        nftTrades.pagination = {\n          ...state.nftTrades.pagination,\n          pageSize,\n        } as any\n        getTradeList({\n          page: 1,\n          // offset:0\n\n          limit: pageSize,\n          side: undefined,\n        })\n        return state\n      })\n    }\n  }, [container])\n\n  return {\n    container,\n    nftHistory,\n    getTxnList,\n    tabIndex,\n    setTabIndex,\n    getTradeList,\n    nftTrades: nftTrades.nftTrades,\n  }\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/NFTPage/NFThistory/index.tsx",
    "content": "import styled from '@emotion/styled'\nimport { Box, Tab, Tabs } from '@mui/material'\nimport React from 'react'\nimport { Button, TradeNFTTable, TsNFTTable } from '@loopring-web/component-lib'\nimport { useTranslation } from 'react-i18next'\nimport { useHistoryNFT } from './hookHistory'\nimport { useAccount, useTokenMap } from '@loopring-web/core'\nimport { useHistory, useLocation, useRouteMatch } from 'react-router-dom'\nimport { BackIcon } from '@loopring-web/common-resources'\n\nconst StyledPaper = styled(Box)`\n  background: var(--color-box-third);\n  border-radius: ${({ theme }) => theme.unit}px;\n`\n\nenum TabIndex {\n  transactions = 'transactions',\n  trades = 'trades',\n}\n\nexport const MyNFTHistory = () => {\n  const { t } = useTranslation('common')\n  const match: any = useRouteMatch('/nft/transactionNFT/:tab')\n  const { search } = useLocation()\n\n  const [currentTab, setCurrentTab] = React.useState(() => {\n    return match?.params.tab ?? TabIndex.transactions\n  })\n  const { idIndex, tokenMap } = useTokenMap()\n  const { nftHistory, container, getTxnList, getTradeList, nftTrades } = useHistoryNFT()\n  const {\n    account: { accountId, accAddress },\n  } = useAccount()\n  const history = useHistory()\n  const handleTabChange = React.useCallback(\n    (value: TabIndex, _pageSize?: number) => {\n      setCurrentTab(value)\n      history.replace(`/nft/transactionNFT/${value}?${search.replace('?', '')}`)\n    },\n    [history, search],\n  )\n\n  // React.useEffect(() => {\n  //   let height = container?.current?.offsetHeight;\n  //   if (height) {\n  //     const pageSize = Math.floor((height - 120) / RowConfig.rowHeight) - 3;\n  //     setPageSize(Math.floor((height - 120) / RowConfig.rowHeight) - 3);\n  //     handleTabChange(currentTab, pageSize);\n  //   }\n  // }, [container?.current?.offsetHeight]);\n  return (\n    <Box flex={1} marginTop={0} marginBottom={2} display={'flex'} flexDirection={'column'}>\n      <Box marginBottom={2}>\n        <Button\n          startIcon={<BackIcon fontSize={'small'} />}\n          variant={'text'}\n          size={'medium'}\n          sx={{ color: 'var(--color-text-secondary)' }}\n          color={'inherit'}\n          onClick={history.goBack}\n        >\n          {t('labelTransactions')}\n        </Button>\n      </Box>\n      <StyledPaper\n        className={'MuiPaper-elevation2'}\n        flex={1}\n        display={'flex'}\n        flexDirection={'column'}\n      >\n        <Box marginTop={2} marginLeft={2}>\n          <Tabs\n            value={currentTab}\n            onChange={(_event, value) => handleTabChange(value)}\n            aria-label='l2-history-tabs'\n            variant='scrollable'\n          >\n            <Tab label={t('labelLayer2HistoryTransactions')} value={TabIndex.transactions} />\n            <Tab label={t('labelLayer2HistoryTrades')} value={TabIndex.trades} />\n          </Tabs>\n        </Box>\n        <Box flex={1} display={'flex'} ref={container} marginTop={2}>\n          {currentTab === TabIndex.transactions ? (\n            <TsNFTTable\n              {...{\n                ...(nftHistory.userNFTTxs as any),\n                getTxnList,\n                accAddress,\n                accountId,\n              }}\n            />\n          ) : currentTab === TabIndex.trades ? (\n            <TradeNFTTable {...{ ...nftTrades, getTradeList, idIndex, tokenMap }} />\n          ) : (\n            <></>\n          )}\n        </Box>\n      </StyledPaper>\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/NFTPage/components/CollectionItemPanel.tsx",
    "content": "import { CollectionMeta, GET_IPFS_STRING } from '@loopring-web/common-resources'\nimport styled from '@emotion/styled'\nimport { Box, BoxProps, Typography } from '@mui/material'\nimport React from 'react'\nimport { NFTList, useOpenModals } from '@loopring-web/component-lib'\nimport { useTranslation } from 'react-i18next'\nimport { useAccount } from '@loopring-web/core'\nimport { useLocation } from 'react-router-dom'\n\nexport const CollectionItemPanel = <Co extends CollectionMeta>({\n  getIPFSString,\n  baseURL,\n  nftPublicProps,\n}: {\n  collectionDate: Co\n  getIPFSString: GET_IPFS_STRING\n  baseURL: string\n  nftPublicProps: any\n}) => {\n  const { t } = useTranslation()\n  const { setNFTMetaNotReady } = useOpenModals()\n\n  return (\n    <Box flex={1} display={'flex'} flexDirection={'column'} paddingY={2}>\n      <Box display={'flex'} flex={1} marginBottom={1} flexDirection={'column'}>\n        <Typography variant={'h5'} marginBottom={1} marginX={3}>\n          {t('labelTitleTotalAvailable', { ns: 'common' })}\n        </Typography>\n        <NFTList\n          onPageChange={(page: number) => {\n            nftPublicProps.onFilterNFT({ ...nftPublicProps.filter, page })\n          }}\n          isManage={false}\n          isSelectOnly={false}\n          isMultipleSelect={false}\n          getIPFSString={getIPFSString}\n          baseURL={baseURL}\n          nftList={nftPublicProps.listNFT}\n          isLoading={nftPublicProps.isLoading}\n          total={nftPublicProps.total}\n          page={nftPublicProps.page}\n          size={'medium'}\n          onClick={async (_item) => {\n            nftPublicProps.onDetail()\n          }}\n          setNFTMetaNotReady={setNFTMetaNotReady}\n        />\n      </Box>\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/NFTPage/components/landingPanel.tsx",
    "content": "import { useHistory } from 'react-router-dom'\nimport {\n  CardNFTStyled,\n  ModalBackButton,\n  ModalCloseButton,\n  ModelPanelStyle,\n  NftImage,\n  useOpenModals,\n  useSettings,\n} from '@loopring-web/component-lib'\nimport { useTranslation } from 'react-i18next'\nimport { Box, Button, Modal, Typography } from '@mui/material'\nimport {\n  CreateCollectionStep,\n  NFTSubRouter,\n  RouterPath,\n  SoursURL,\n} from '@loopring-web/common-resources'\nimport React from 'react'\n\nexport const MintLandingPanel = () => {\n  return null\n}\nexport const CreateUrlPanel = ({\n  open,\n  onClose,\n  step,\n}: {\n  onClose: () => void\n  open: boolean\n  step: CreateCollectionStep\n}) => {\n  const { t } = useTranslation()\n  const { setShowCollectionAdvance } = useOpenModals()\n  const history = useHistory()\n  const { isMobile } = useSettings()\n  const panelList: Array<{\n    view: JSX.Element\n    onBack?: undefined | (() => void)\n    height?: any\n    width?: any\n  }> = React.useMemo(() => {\n    return [\n      {\n        view: (\n          <Box\n            flex={1}\n            alignItems={'center'}\n            display={'flex'}\n            justifyContent={'center'}\n            flexDirection={'column'}\n            marginTop={-3}\n          >\n            <Typography component={'h4'} variant={'h4'} textAlign={'center'} marginBottom={3}>\n              {t('labelMintSelect')}\n            </Typography>\n            <Box\n              flex={1}\n              alignItems={'center'}\n              display={'flex'}\n              flexDirection={isMobile ? 'column' : 'row'}\n              justifyContent={'center'}\n            >\n              <CardNFTStyled\n                sx={{ background: 'var(--color-global-bg)' }}\n                onClick={() => {\n                  onClose()\n                  setShowCollectionAdvance({ isShow: true })\n                }}\n              >\n                <Box\n                  display={'flex'}\n                  alignItems={'center'}\n                  justifyContent={'center'}\n                  flex={1}\n                  marginBottom={2}\n                  minHeight={200}\n                  width={'100%'}\n                >\n                  <NftImage\n                    alt={'Collection Created'}\n                    onError={() => undefined}\n                    src={`${SoursURL}images/nft_guid1.webp`}\n                  />\n                </Box>\n                <Typography\n                  display={'flex'}\n                  flexDirection={'column'}\n                  justifyContent={'space-between'}\n                  paddingX={2}\n                  component={'p'}\n                  variant={'body1'}\n                  minHeight={'148px'}\n                  marginBottom={2}\n                >\n                  Fill up content in GUI and let Loopring to generate necessary metadata and upload\n                  to IPFS for you, then use \"Mint\" to create your NFT.\n                  <Button variant={'contained'} color={'primary'} fullWidth={true}>\n                    {t('labelAdvanceCreateCollection')}\n                  </Button>\n                </Typography>\n              </CardNFTStyled>\n              <CardNFTStyled\n                sx={{\n                  marginLeft: isMobile ? 0 : 4,\n                  background: 'var(--color-global-bg)',\n                }}\n                onClick={() => {\n                  history.push(`${RouterPath.nft}/${NFTSubRouter.addCollection}`)\n                }}\n              >\n                <Box\n                  display={'flex'}\n                  alignItems={'center'}\n                  justifyContent={'center'}\n                  flex={1}\n                  marginBottom={2}\n                  minHeight={200}\n                  width={'100%'}\n                >\n                  <NftImage\n                    alt={'Collection Created'}\n                    onError={() => undefined}\n                    src={`${SoursURL}images/nft_guid2.webp`}\n                  />\n                </Box>\n                {/*<Typography component={'p'} variant={'body1'} height={\"48px\"} marginBottom={1}*/}\n                {/*>*/}\n                {/*  Fill up content in GUI and let Loopring to generate necessary metadata and upload to IPFS for you, then use \"Mint\" to create your NFT.*/}\n                {/*</Typography>*/}\n                {/*<Button*/}\n                {/*  variant={\"outlined\"}*/}\n                {/*  color={\"primary\"}*/}\n                {/*>*/}\n                {/*  {t(\"labelMintNFT\")}*/}\n                {/*</Button>*/}\n                <Typography\n                  display={'flex'}\n                  flexDirection={'column'}\n                  justifyContent={'space-between'}\n                  paddingX={2}\n                  component={'p'}\n                  variant={'body1'}\n                  minHeight={'148px'}\n                  marginBottom={2}\n                >\n                  Generate all the required metadata and upload to IPFS by yourself first, then use\n                  \"Advanced Mint\" to create your NFT.\n                  <Button variant={'contained'} color={'primary'} fullWidth={true}>\n                    {t('labelCollectionCreateBtn')}\n                  </Button>\n                </Typography>\n              </CardNFTStyled>\n            </Box>\n            <Box marginLeft={1}></Box>\n          </Box>\n        ),\n        // onBack: () => setStep(CreateCollectionStep.ChooseMethod)\n      },\n      {\n        view: <MintLandingPanel />,\n      },\n      {\n        view: <Typography>Go toEdit Panel....</Typography>,\n      },\n    ]\n  }, [history, isMobile, onClose, setShowCollectionAdvance, t])\n  return (\n    <Modal\n      open={open}\n      onClose={onClose}\n      aria-labelledby='modal-modal-title'\n      aria-describedby='modal-modal-description'\n    >\n      <ModelPanelStyle style={{ boxShadow: '24' }}>\n        {panelList.map((panel, index) => {\n          return (\n            <React.Fragment key={index + '0'}>\n              <Box\n                display={step === index ? 'flex' : 'none'}\n                width={'100%'}\n                flexDirection={'column'}\n              >\n                <ModalCloseButton onClose={onClose} t={t} />\n                {panel.onBack ? <ModalBackButton onBack={panel.onBack} /> : <></>}\n              </Box>\n              <Box\n                display={step === index ? 'flex' : 'none'}\n                alignItems={'stretch'}\n                flex={1}\n                key={index}\n                margin={5 / 2}\n              >\n                {panel.view}\n              </Box>\n            </React.Fragment>\n          )\n        })}\n      </ModelPanelStyle>\n    </Modal>\n  )\n}\n\nexport const MintLandingPage = () => {\n  // const history = useHistory();\n  // const {t} = useTranslation([\"common\"]);\n  // const {isMobile} = useSettings();\n  return (\n    <Box flex={1} display={'flex'} justifyContent={'stretch'} flexDirection={'column'}>\n      <MintLandingPanel />\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/NFTPage/components/titleNFTMobile.tsx",
    "content": "import {\n  AnimationArrow,\n  Button,\n  DropdownIconStyled,\n  useSettings,\n} from '@loopring-web/component-lib'\nimport { useTranslation } from 'react-i18next'\nimport { useRouteMatch } from 'react-router-dom'\nimport {\n  HeaderMenuItemInterface,\n  NFTSubRouter,\n  RouterPath,\n  subMenuLayer2,\n} from '@loopring-web/common-resources'\nimport { Box, Grid } from '@mui/material'\n\nexport const TitleNFTMobile = () => {\n  const { hideL2Action, setHideL2Action } = useSettings()\n  const { t } = useTranslation(['common', 'layout'])\n  let match: any = useRouteMatch('/nft/:item')\n  const label = Reflect.ownKeys(subMenuLayer2)\n    .reduce((pre, item) => [...pre, ...subMenuLayer2[item]], [] as HeaderMenuItemInterface[])\n    .find((item) => RegExp(item?.router?.path ?? '').test(match?.url ?? ''))?.label?.i18nKey\n  return (\n    <Box display={'flex'} flexDirection={'column'} marginBottom={2}>\n      <Box\n        component={'span'}\n        display={'flex'}\n        alignItems={'center'}\n        style={{ cursor: 'pointer' }}\n        justifyContent={'center'}\n        onClick={() => setHideL2Action(!hideL2Action)}\n        marginBottom={1}\n      >\n        {!hideL2Action ? (\n          <DropdownIconStyled status={hideL2Action ? 'down' : 'up'} fontSize={'medium'} />\n        ) : (\n          <AnimationArrow className={'arrowCta'} />\n        )}\n      </Box>\n      {!hideL2Action && (\n        <Grid container spacing={2}>\n          {/* <Grid item xs={4}>\n            <Button\n              fullWidth\n              variant={'outlined'}\n              size={'medium'}\n              color={'primary'}\n              href={`/#${RouterPath.nft}/${NFTSubRouter.mintNFT}`}\n            >\n              {t('labelMintNFT')}\n            </Button>\n          </Grid> */}\n          <Grid item xs={4}>\n            <Button\n              fullWidth\n              variant={'outlined'}\n              size={'medium'}\n              color={'primary'}\n              href={`/#${RouterPath.nft}/${NFTSubRouter.depositNFT}`}\n            >\n              {t('labelL1toL2NFT')}\n            </Button>\n          </Grid>\n        </Grid>\n      )}\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/NFTPage/components/usePublicNFTs.ts",
    "content": "import {\n  CollectionMeta,\n  GET_IPFS_STRING,\n  NFTLimit,\n  NFTWholeINFO,\n} from '@loopring-web/common-resources'\nimport React from 'react'\nimport {\n  getIPFSString,\n  LoopringAPI,\n  useNFTListDeep,\n  useSystem,\n  useWalletLayer2NFT,\n} from '@loopring-web/core'\nimport { BigNumber } from 'bignumber.js'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nBigNumber.config({ EXPONENTIAL_AT: 100 })\nexport type CollectionProps<Co, NFT> = {\n  collection: Partial<Co>\n  total: number\n  page: number\n  filter: object\n  listNFT: NFT[]\n  baseURL: string\n  getIPFSString: GET_IPFS_STRING\n  onDetail: () => void\n  onFilterNFT: (props: {\n    legacyFilter?: sdk.LegacyNFT | 'all'\n    limit?: number\n    page?: number\n  }) => void\n  isLoading: boolean\n}\nexport const usePublicNFTs = <Co extends CollectionMeta, NFT extends Partial<NFTWholeINFO>>({\n  collection,\n  page: _page,\n  pageSize = NFTLimit,\n}: {\n  collection: Co\n  page?: number\n  pageSize?: number\n}) => {\n  const { renderNFTPromise, infoDetail, nftListReduce } = useNFTListDeep()\n  const [filter, setFilter] = React.useState({})\n  const { page: page_redux, collection: collection_redux } = useWalletLayer2NFT()\n  const [{ listNFT, total, page }, setListNFTValue] = React.useState<{\n    listNFT: NFT[]\n    total: number\n    page: number\n  }>({\n    listNFT: [],\n    total: 0,\n    page: _page ?? 1,\n  })\n  const [isLoading, setIsLoading] = React.useState(false)\n  const onFilterNFT = React.useCallback(\n    async (props: { legacyFilter?: sdk.LegacyNFT | 'all'; limit?: number; page?: number }) => {\n      if (collection?.id && LoopringAPI.nftAPI) {\n        setFilter(props)\n        setIsLoading(true)\n        const { legacyFilter = sdk.LegacyNFT.undecided, limit = pageSize, page: _page = 1 } = props\n        const response = await LoopringAPI.nftAPI.getCollectionWholeNFTs({\n          id: collection.id as any,\n          offset: (_page - 1) * limit,\n          limit,\n          metadata: true,\n        })\n        if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n        } else {\n          setListNFTValue({\n            total: response.totalNum,\n            page: _page,\n            listNFT: nftListReduce(response.userNFTBalances),\n          })\n          setIsLoading(false)\n          renderNFTPromise({ nftLists: response.userNFTBalances }).then((meta: any[]) => {\n            if (page === _page) {\n              setListNFTValue((state) => {\n                return {\n                  ...state,\n                  listNFT: state.listNFT?.map((item, index) => {\n                    return {\n                      ...item,\n                      ...meta[index],\n                      tokenAddress: item.tokenAddress?.toLowerCase(),\n                      // etherscanBaseUrl,\n                    }\n                  }),\n                }\n              })\n            }\n          })\n        }\n        setIsLoading(false)\n      }\n    },\n    [collection],\n  )\n  const { baseURL } = useSystem()\n  React.useEffect(() => {\n    // if (Number(page) !== Number(page_redux)) {\n    //\n    // }\n    onFilterNFT({ page: 1 })\n  }, [collection?.id])\n\n  return {\n    collection: (collection ?? {}) as Partial<Co>,\n    total,\n    page,\n    filter,\n    listNFT,\n    baseURL,\n    getIPFSString,\n    onDetail: () => {},\n    onFilterNFT,\n    isLoading,\n  }\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/NFTPage/index.tsx",
    "content": "import { useRouteMatch } from 'react-router-dom'\nimport { Box, Link, Typography } from '@mui/material'\nimport {\n  AccountStatus,\n  SagaStatus,\n  subMenuNFT,\n  SUBMIT_PANEL_AUTO_CLOSE,\n  RouterPath,\n  NFTSubRouter,\n} from '@loopring-web/common-resources'\nimport React from 'react'\nimport { onchainHashInfo, store, useAccount, ViewAccountTemplate } from '@loopring-web/core'\nimport { MyNFTPanel } from './MyNFT'\nimport { MyNFTHistory } from './NFThistory'\nimport { MintNFTAdvancePanel, MintNFTPanel } from './MintNFTPanel'\nimport { DepositNFTPanel } from './NFTDeposit'\nimport { NFTCollectPanel } from './CollectionPanel'\nimport { EditCollectionPanel } from './EditCollectionPanel'\nimport { MintLandingPage } from './components/landingPanel'\nimport { ImportCollectionPanel } from './ImportCollectionPanel'\nimport { CollectionHadUnknown, ToastType, Toast } from '@loopring-web/component-lib'\nimport { Trans } from 'react-i18next'\nimport styled from '@emotion/styled'\n\nexport const subMenu = subMenuNFT\nexport const BoxStyle = styled(Box)`\n  .MuiSnackbar-root {\n    max-width: var(--modal-min-width);\n    pointer-events: initial;\n  }\n` as typeof Box\n\nexport const NFTPage = () => {\n  let match: any = useRouteMatch('/NFT/:item')\n  const selected = match?.params?.item ?? 'assetsNFT'\n  const { account, status: accountStatus } = useAccount()\n  const [showUnknownCollection, setShowUnknownCollection] = React.useState(false)\n  const { updateHadUnknownCollection } = onchainHashInfo.useOnChainInfo()\n  const [open, setOpen] = React.useState(false)\n  const routerNFT = React.useMemo(() => {\n    switch (selected) {\n      case NFTSubRouter.transactionNFT:\n        return <MyNFTHistory />\n      case NFTSubRouter.mintNFTLanding:\n        return <MintLandingPage />\n      case NFTSubRouter.mintNFT:\n        return <MintNFTPanel />\n      case NFTSubRouter.mintNFTAdvance:\n        return <MintNFTAdvancePanel />\n      case NFTSubRouter.depositNFT:\n        return <DepositNFTPanel />\n      case NFTSubRouter.myCollection:\n        return <NFTCollectPanel />\n      case NFTSubRouter.addCollection:\n      case NFTSubRouter.editCollection:\n      case NFTSubRouter.addLegacyCollection:\n        return <EditCollectionPanel type={selected} />\n      case NFTSubRouter.importLegacyCollection:\n        return <ImportCollectionPanel />\n      default:\n        return <MyNFTPanel />\n    }\n  }, [selected])\n  React.useEffect(() => {\n    if (accountStatus === SagaStatus.UNSET) {\n      const {\n        account,\n        system: { chainId },\n        localStore: { chainHashInfos },\n      } = store.getState()\n      if (account?.hasUnknownCollection && account.readyState === AccountStatus.ACTIVATED) {\n        const showHadUnknownCollection = chainHashInfos[chainId]?.showHadUnknownCollection\n        if (\n          !(\n            showHadUnknownCollection && showHadUnknownCollection[account?.accAddress?.toLowerCase()]\n          )\n        ) {\n          setOpen(true)\n        } else {\n          // setShowUnknownCollection(true)\n        }\n      }\n    }\n  }, [accountStatus, account?.hasUnknownCollection])\n\n  const activeViewTemplate = React.useMemo(\n    () => (\n      <>\n        <Box\n          // minHeight={420}\n          display={'flex'}\n          alignItems={'stretch'}\n          flexDirection={'column'}\n          marginTop={0}\n          flex={1}\n        >\n          {routerNFT}\n        </Box>\n      </>\n    ),\n    [routerNFT],\n  )\n\n  return (\n    <BoxStyle flex={1} display={'flex'} flexDirection={'column'}>\n      {/*<Toast\n        alertText={\n          <Typography component={'span'}>\n            <Trans i18nKey={'errorHadUnknownCollectionDes'} ns={['error']}>\n              As the creator, you will be able to generate collection information for those NFT\n              minted earlier that belong to nowhere. And once done, the other people holding your\n              NFT will be able to view those NFT with proper collection information via loopring.io\n              and loopring wallet.\n              <Link\n                display={'inline-flex'}\n                target='_self'\n                rel='noopener noreferrer'\n                href={`/#${RouterPath.nft}/${NFTSubRouter.importLegacyCollection}`}\n                paddingLeft={1 / 2}\n              >\n                GO\n              </Link>\n            </Trans>\n          </Typography>\n        }\n        open={showUnknownCollection}\n        autoHideDuration={SUBMIT_PANEL_AUTO_CLOSE}\n        onClose={() => {\n          setShowUnknownCollection(false)\n        }}\n        severity={ToastType.warning}\n      />*/}\n      {/*<CollectionHadUnknown\n        open={open}\n        onClose={() => {\n          updateHadUnknownCollection({ accountAddress: account?.accAddress?.toLowerCase() })\n          setOpen(false)\n        }}\n      />*/}\n      <ViewAccountTemplate activeViewTemplate={activeViewTemplate} />\n    </BoxStyle>\n  )\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/ProTradePage/hookPro.ts",
    "content": "import React from 'react'\nimport {\n  AccountStatus,\n  CoinMap,\n  MarketType,\n  myLog,\n  PrecisionTree,\n  RouterPath,\n  SagaStatus,\n  WalletMap,\n} from '@loopring-web/common-resources'\n\nimport {\n  makeWalletLayer2,\n  marketInitCheck,\n  store,\n  useAccount,\n  useAmount,\n  usePageTradePro,\n  usePairMatch,\n  useTokenMap,\n  useWalletLayer2,\n} from '@loopring-web/core'\nimport * as sdk from '@loopring-web/loopring-sdk'\n// import { useOrderList } from './panel/orderTable/hookTable'\nimport { useProSocket, useSocketProService } from './proService'\nimport { useHistory } from 'react-router-dom'\nimport { useGetAssets } from '../AssetPage/AssetPanel/hook'\nimport { useOrderList } from '../AssetPage'\n\nexport const usePro = <C extends { [key: string]: any }>({\n  path = '/trade/pro',\n}: {\n  path?: string\n}): {\n  [key: string]: any\n  market: MarketType | undefined\n  resetTradeCalcData: (props: { tradeData?: any; market: MarketType | string }) => void\n  // marketTicker: MarketBlockProps<C> |undefined,\n} => {\n  //High: No not Move!!!!!!\n  let { realMarket } = usePairMatch({ path })\n  const history = useHistory()\n  const { updatePageTradePro } = usePageTradePro()\n  const [market, setMarket] = React.useState<MarketType>(realMarket as MarketType)\n  const { getAmount } = useAmount()\n  const { account, status: accountStatus } = useAccount()\n  const { status: walletLayer2Status } = useWalletLayer2()\n  const { assetBtnStatus } = useGetAssets()\n  const { getOrderList } = useOrderList({ isOrderBookScroll: true })\n  const { coinMap, tokenMap, marketArray, marketCoins, marketMap } = useTokenMap()\n  useProSocket({ market })\n  React.useEffect(() => {\n    myLog('account.status', accountStatus, account.readyState)\n    if (account.readyState !== AccountStatus.ACTIVATED && accountStatus === SagaStatus.UNSET) {\n      userInfoUpdateCallback()\n    }\n  }, [accountStatus])\n  const updateWalletLayer2Balance = React.useCallback(\n    (_tradeCalcProData?, _market?: MarketType) => {\n      const pageTradePro = store.getState()._router_pageTradePro.pageTradePro\n      const account = store.getState().account\n      // @ts-ignore\n      let tradeCalcProData = _tradeCalcProData ? _tradeCalcProData : pageTradePro.tradeCalcProData\n      let market: MarketType = _market ? _market : pageTradePro.market\n      let walletMap: WalletMap<any> | undefined\n      if (account.readyState === AccountStatus.ACTIVATED) {\n        walletMap = makeWalletLayer2({ needFilterZero: false }).walletMap ?? {}\n      }\n      tradeCalcProData = {\n        ...pageTradePro.tradeCalcProData,\n        ...tradeCalcProData,\n        walletMap,\n        priceImpact: '',\n        priceImpactColor: 'inherit',\n        minimumReceived: '',\n      }\n      updatePageTradePro({ market, tradeCalcProData })\n    },\n    [market, walletLayer2Status],\n  )\n\n  const userInfoUpdateCallback = React.useCallback(() => {\n    updateWalletLayer2Balance()\n    getOrderList({})\n  }, [updateWalletLayer2Balance, getOrderList])\n\n  useSocketProService({\n    market,\n    userInfoUpdateCallback,\n  })\n  React.useEffect(() => {\n    resetTradeCalcData({ market })\n    precisionList(market)\n  }, [market, account.readyState])\n\n  React.useEffect(() => {\n    if (account.readyState === AccountStatus.ACTIVATED && accountStatus === SagaStatus.UNSET) {\n      getAmount({ market })\n    }\n  }, [market, accountStatus, account.readyState])\n\n  const handleOnMarketChange = React.useCallback(async (newMarket: MarketType) => {\n    setMarket(newMarket)\n    history.push(`${path}/${newMarket}`)\n  }, [])\n\n  const precisionList = React.useCallback((market: MarketType) => {\n    const precisionForPrice = marketMap[market]?.precisionForPrice\n    const orderbookAggLevels = marketMap[market]?.orderbookAggLevels\n    let precisionLevels: { value: number; label: string }[] = []\n    for (let i = 0; i < orderbookAggLevels; i++) {\n      if (PrecisionTree[precisionForPrice - i]) {\n        precisionLevels.push({\n          value: precisionForPrice - i,\n          label: PrecisionTree[precisionForPrice - i],\n        })\n      }\n    }\n    updatePageTradePro({\n      market,\n      precisionLevels: precisionLevels,\n      depthLevel: precisionForPrice,\n    })\n  }, [])\n\n  const resetTradeCalcData = React.useCallback(\n    (props: { tradeData?: any; market: MarketType | string }) => {\n      const pageTradePro = store.getState()._router_pageTradePro.pageTradePro\n      if (coinMap && tokenMap && marketMap && marketArray) {\n        const { tradePair } = marketInitCheck({\n          market: props.market as string,\n        })\n        // @ts-ignore\n        let [, coinA, coinB] = tradePair.match(/([\\w]+)-([\\w]+)/i)\n        let { market: _market } = sdk.getExistedMarket(marketArray, coinA, coinB)\n        if (_market !== market) {\n          setMarket(_market)\n          history.push(`${RouterPath.pro}/${_market}`)\n        }\n        // @ts-ignore\n        ;[, coinA, coinB] = _market?.match(/([\\w]+)-([\\w]+)/i)\n        let tradeCalcProData = pageTradePro.tradeCalcProData\n        tradeCalcProData = {\n          ...tradeCalcProData,\n          coinBase: coinA,\n          coinQuote: coinB,\n          fee: undefined,\n          minimumReceived: undefined,\n          priceImpact: undefined,\n          priceImpactColor: 'inherit',\n          coinInfoMap: marketCoins?.reduce((prev: any, item: string | number) => {\n            return { ...prev, [item]: coinMap ? coinMap[item] : {} }\n          }, {} as CoinMap<C>),\n        }\n        updateWalletLayer2Balance(tradeCalcProData, _market)\n      }\n    },\n    [coinMap, tokenMap, marketMap, marketArray, market],\n  )\n  return {\n    market,\n    assetBtnStatus,\n    handleOnMarketChange,\n    resetTradeCalcData,\n  }\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/ProTradePage/index.tsx",
    "content": "import { withTranslation } from 'react-i18next'\n\nimport React from 'react'\nimport { Layout, Layouts, Responsive, WidthProvider } from 'react-grid-layout'\n\nimport { usePro } from './hookPro'\nimport { useTheme } from '@emotion/react'\nimport { Box, IconButton } from '@mui/material'\nimport {\n  BreakPoint,\n  DragIcon,\n  LayoutConfig,\n  LayoutConfigInfo,\n  layoutConfigs,\n  myLog,\n  ResizeIcon,\n  RouterPath,\n  RowConfig,\n  SoursURL,\n} from '@loopring-web/common-resources'\nimport {\n  ChartView,\n  MarketView,\n  OrderTableView,\n  SpotView,\n  TabMarketIndex,\n  Toolbar,\n  WalletInfo,\n} from './panel'\nimport { boxLiner, useSettings } from '@loopring-web/component-lib'\nimport styled from '@emotion/styled'\nimport { usePageTradePro } from '@loopring-web/core'\nimport { useHistory } from 'react-router-dom'\n\nconst MARKET_ROW_LENGTH: number = 8\n// const MARKET_ROW_LENGTH_LG: number = 11;\n\nconst MARKET_TRADES_LENGTH: number = 19\n// const MARKET_TRADES_LENGTH_LG: number = 24;\nexport const HeaderHeight = RowConfig.rowHeaderHeight\n\nconst BoxStyle = styled(Box)`\n  --tab-header: ${HeaderHeight}px;\n  background: var(--color-global-bg);\n\n  &.spot {\n    ${({ theme }: any) => boxLiner({ theme })}\n    background-color: var(--color-global-bg);\n  }\n\n  .MuiTabs-root {\n    min-height: var(--tab-header);\n\n    .MuiTab-root.MuiTab-fullWidth,\n    .MuiTab-root {\n      font-size: ${({ theme }) => theme.fontDefault.body1};\n      min-height: var(--tab-header);\n      padding: ${({ theme }) => theme.unit}px;\n\n      &:after {\n        margin: 0;\n      }\n    }\n  }\n`\nconst ResponsiveGridLayout = WidthProvider(Responsive)\n\nconst initBreakPoint = (): BreakPoint => {\n  if (window.innerWidth >= layoutConfigs[0].breakpoints[BreakPoint.xlg]) {\n    return BreakPoint.xlg\n  } else if (window.innerWidth >= layoutConfigs[0].breakpoints[BreakPoint.lg]) {\n    return BreakPoint.lg\n  } else if (window.innerWidth >= layoutConfigs[0].breakpoints[BreakPoint.md]) {\n    return BreakPoint.md\n  } else if (window.innerWidth >= layoutConfigs[0].breakpoints[BreakPoint.sm]) {\n    return BreakPoint.sm\n  } else if (window.innerWidth >= layoutConfigs[0].breakpoints[BreakPoint.xs]) {\n    return BreakPoint.xs\n  } else if (window.innerWidth >= layoutConfigs[0].breakpoints[BreakPoint.xxs]) {\n    return BreakPoint.xxs\n  } else {\n    return BreakPoint.md\n  }\n}\nexport const OrderbookPage = withTranslation('common')(<Config extends LayoutConfigInfo>() => {\n  const {\n    pageTradePro: { depthLevel, depthForCalc },\n  } = usePageTradePro()\n  const { market, handleOnMarketChange, assetBtnStatus, resetTradeCalcData } = usePro({})\n  const { unit } = useTheme()\n  const { proLayout, setLayouts, isMobile } = useSettings()\n\n  const history = useHistory()\n\n  const [rowLength, setRowLength] = React.useState<number>(MARKET_ROW_LENGTH)\n  const [tradeTableLengths, setTradeTableLengths] = React.useState<{\n    market: number\n    market2: number\n  }>({\n    market: MARKET_TRADES_LENGTH,\n    market2: MARKET_TRADES_LENGTH,\n  })\n\n  const [configLayout, setConfigLayout] = React.useState<Config>({\n    // @ts-ignore\n    compactType: 'vertical',\n    currentBreakpoint: initBreakPoint(),\n    mounted: false,\n    layouts: proLayout ?? layoutConfigs[0].layouts,\n  })\n  const sportMemo = React.useMemo(() => {\n    return (\n      <>\n        {depthForCalc ? (\n          <SpotView market={market as any} resetTradeCalcData={resetTradeCalcData} />\n        ) : (\n          <Box\n            flex={1}\n            height={'100%'}\n            display={'flex'}\n            alignItems={'center'}\n            justifyContent={'center'}\n          >\n            <img\n              className='loading-gif'\n              alt={'loading'}\n              width='36'\n              src={`${SoursURL}images/loading-line.gif`}\n            />\n          </Box>\n        )}\n      </>\n    )\n  }, [market, depthForCalc])\n\n  const onRestDepthTableLength = React.useCallback(\n    (h: number) => {\n      if (h) {\n        const i = Math.floor((h * unit - (isMobile ? 88 : 144)) / 40)\n        if (i <= 40) {\n          setRowLength(i)\n        } else {\n          setRowLength(48)\n        }\n      }\n    },\n    [isMobile],\n  )\n  const onRestMarketTableLength = React.useCallback(\n    (layout: Layout | undefined) => {\n      if (layout && layout.h) {\n        const h = layout.h\n        const i = Math.floor((h * unit - (isMobile ? 88 : 144)) / 20)\n        setTradeTableLengths((state) => {\n          if (i <= 30) {\n            //32\n            return {\n              ...state,\n              [layout.i]: i,\n            }\n          } else {\n            return {\n              ...state,\n              [layout.i]: MARKET_TRADES_LENGTH + 30,\n            }\n          }\n        })\n      }\n    },\n    [isMobile],\n  )\n\n  const onBreakpointChange = React.useCallback(\n    (breakpoint: BreakPoint) => {\n      setConfigLayout((state) => {\n        return {\n          ...state,\n          currentBreakpoint: breakpoint,\n        }\n      })\n      configLayout.layouts[breakpoint].forEach((layoutItem, index) => {\n        onResize(\n          configLayout.layouts[breakpoint],\n          configLayout.layouts[configLayout.currentBreakpoint][index],\n          layoutItem,\n        )\n      })\n    },\n    [configLayout],\n  )\n\n  const onResize = React.useCallback(\n    (layout: Layout[], oldLayoutItem, layoutItem) => {\n      if (layoutItem.i === 'market') {\n        onRestDepthTableLength(layoutItem.h)\n        onRestMarketTableLength(layoutItem)\n      }\n      if (layoutItem.i === 'market2') {\n        onRestMarketTableLength(layoutItem)\n      }\n      setLayouts({ [configLayout.currentBreakpoint]: layout })\n    },\n    [configLayout, setRowLength],\n  )\n\n  const handleLayoutChange = React.useCallback(\n    (currentLayout: Layout[], allLayouts?: Layouts, defaultlayouts?: Layouts) => {\n      if (defaultlayouts) {\n        setLayouts(defaultlayouts)\n        history.push(RouterPath.loading)\n        setTimeout(() => {\n          history.go(-1)\n        }, 0)\n      } else {\n      }\n      myLog(currentLayout)\n    },\n    [configLayout, proLayout, setConfigLayout, setLayouts],\n  )\n  const ViewList = {\n    toolbar: React.useMemo(\n      () => (\n        <Toolbar\n          market={market as any}\n          handleLayoutChange={handleLayoutChange}\n          handleOnMarketChange={handleOnMarketChange}\n        />\n      ),\n      [market, handleLayoutChange, handleOnMarketChange],\n    ),\n    walletInfo: React.useMemo(\n      () => <WalletInfo market={market as any} assetBtnStatus={assetBtnStatus} />,\n      [market, assetBtnStatus],\n    ),\n    spot: sportMemo,\n    market: React.useMemo(\n      () => (\n        <>\n          {depthLevel && (\n            <MarketView\n              market={market as any}\n              rowLength={rowLength}\n              tableLength={tradeTableLengths.market}\n              main={TabMarketIndex.Orderbook}\n              breakpoint={configLayout.currentBreakpoint}\n            />\n          )}\n        </>\n      ),\n      [market, rowLength, configLayout.currentBreakpoint, depthLevel, tradeTableLengths.market],\n    ),\n    market2: React.useMemo(\n      () => (\n        <>\n          <MarketView\n            isOnlyTrade={true}\n            market={market as any}\n            main={TabMarketIndex.Trades}\n            tableLength={tradeTableLengths.market2}\n            rowLength={0}\n            breakpoint={configLayout.currentBreakpoint}\n          />\n        </>\n      ),\n      [market, rowLength, configLayout.currentBreakpoint, depthLevel, tradeTableLengths.market2],\n    ), //<MarketView market={market as any}/>, [market])\n    chart: React.useMemo(\n      () => <ChartView market={market} rowLength={rowLength} />,\n      [market, rowLength],\n    ),\n    orderTable: React.useMemo(\n      () => <OrderTableView market={market} handleOnMarketChange={handleOnMarketChange} />,\n      [market],\n    ),\n  }\n  return (\n    <Box\n      bgcolor={'var(--color-box-third)'}\n      display={'block'}\n      margin={'0 auto'}\n      width={'100%'}\n      position={'relative'}\n    >\n      {market ? (\n        <ResponsiveGridLayout\n          className='layout'\n          {...{ ...configLayout }}\n          onBreakpointChange={onBreakpointChange}\n          onLayoutChange={handleLayoutChange}\n          onResizeStop={onResize}\n          resizeHandle={\n            <IconButton\n              size={'medium'}\n              style={{\n                position: 'absolute',\n                zIndex: 78,\n                right: 0,\n                bottom: 0,\n              }}\n              className={'resize-holder'}\n            >\n              <ResizeIcon\n                htmlColor={'var(--color-text-third)'}\n                style={{\n                  marginRight: `-${unit}px`,\n                  marginBottom: `-${unit}px`,\n                }}\n              />\n            </IconButton>\n          }\n          draggableHandle={'.drag-holder'}\n          breakpoints={layoutConfigs[0].breakpoints}\n          cols={layoutConfigs[0].cols}\n          rowHeight={unit / 2}\n          margin={[unit / 2, unit / 2]}\n        >\n          {configLayout.layouts[configLayout.currentBreakpoint].map((layout) => {\n            return (\n              <BoxStyle\n                key={layout.i}\n                overflow={'hidden'}\n                className={layout.i}\n                component={'section'}\n                position={'relative'}\n                display={'flex'}\n                flexDirection={'column'}\n              >\n                {ViewList[layout.i]}\n                <IconButton\n                  size={'medium'}\n                  style={{\n                    position: 'absolute',\n                    zIndex: 78,\n                    right: 0,\n                    top: 0,\n                  }}\n                  className={'drag-holder'}\n                >\n                  <DragIcon\n                    htmlColor={'var(--color-text-third)'}\n                    style={{ marginRight: `-${unit}px`, marginTop: '' }}\n                  />\n                </IconButton>\n              </BoxStyle>\n            )\n          })}\n        </ResponsiveGridLayout>\n      ) : (\n        <Box\n          flex={1}\n          height={'100%'}\n          display={'flex'}\n          alignItems={'center'}\n          justifyContent={'center'}\n        >\n          <img\n            className='loading-gif'\n            alt={'loading'}\n            width='36'\n            src={`${SoursURL}images/loading-line.gif`}\n          />\n        </Box>\n      )}\n    </Box>\n  )\n})\n"
  },
  {
    "path": "packages/webapp/src/pages/ProTradePage/panel/chart/hook.ts",
    "content": "import React, { useEffect } from 'react'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { TradingInterval } from '@loopring-web/loopring-sdk'\nimport { IOHLCData, RawDataTradeItem } from '@loopring-web/component-lib'\nimport { LoopringAPI, store, usePageTradePro, useTokenMap, volumeToCount } from '@loopring-web/core'\nimport moment from 'moment'\nimport { getValuePrecisionThousand, myLog } from '@loopring-web/common-resources'\n\nexport enum TradingIntervalToTimer {\n  '1min' = 60000,\n  '5min' = 300000,\n  '15min' = 15 * 60000,\n  '30min' = 30 * 60000,\n  '1hr' = 3600000000,\n  '2hr' = 2 * 3600000000,\n  '4hr' = 4 * 3600000000,\n  '12hr' = 12 * 3600000000,\n  '1d' = 24 * 3600000000,\n  '1w' = 7 * 24 * 3600000000,\n}\n\nexport function useKlineChart(market: string | undefined) {\n  const { tokenMap, marketMap } = useTokenMap()\n  const [timeInterval, setTimeInterval] = React.useState(TradingInterval.hr4)\n\n  const [lastMinutes, setLastMinutes] = React.useState(Date.now())\n  const [candlestickViewData, setCandlestickViewData] = React.useState<IOHLCData[]>([])\n  const {\n    pageTradePro: { tradeArray },\n  } = usePageTradePro()\n\n  const genCandlestickData = React.useCallback(\n    async ({\n      market,\n      timeInterval = sdk.TradingInterval.d1,\n    }: {\n      market: string | undefined\n      timeInterval?: sdk.TradingInterval\n    }) => {\n      if (market && LoopringAPI.exchangeAPI && tokenMap) {\n        // @ts-ignore\n        const [_, coinBase, coinQuote] = market.match(/(\\w+)-(\\w+)/i)\n\n        const decimals = tokenMap[coinBase] ? tokenMap[coinBase].decimals : -1\n\n        if (decimals > 0) {\n          const candlesticks = await LoopringAPI.exchangeAPI.getMixCandlestick({\n            market,\n            interval: timeInterval,\n          })\n          setLastMinutes(Date.now())\n          let candlestickViewData: IOHLCData[] = []\n\n          candlesticks.candlesticks.forEach((item: sdk.Candlestick) => {\n            const dataItem: IOHLCData = {\n              date: new Date(item.timestamp),\n              open: item.open,\n              high: item.high,\n              low: item.low,\n              close: item.close,\n              volume: sdk\n                .toBig(item.baseVol)\n                .div('1e' + decimals)\n                .toNumber(),\n              txs: item.txs,\n            }\n\n            candlestickViewData.push(dataItem)\n          })\n\n          setCandlestickViewData(candlestickViewData.reverse())\n        } else {\n          throw Error('wrong decimals')\n        }\n      }\n    },\n    [tokenMap],\n  )\n\n  const addCandlestick = React.useCallback(() => {\n    if (market) {\n      const now = Date.now()\n      const [, base, quote] = market.replace('AMM-', '').match(/(\\w+)-(\\w+)/i)\n      const precision = marketMap[market]?.precisionForPrice\n      const tradeArray = store.getState()._router_pageTradePro.pageTradePro.tradeArray\n      setCandlestickViewData((candlestickViewData) => {\n        if (tradeArray && candlestickViewData.length) {\n          const viewDate = candlestickViewData[candlestickViewData.length - 1].date\n\n          let index =\n            tradeArray.findIndex((item) => {\n              myLog(\n                'millisecond',\n                new Date(item.time),\n                new Date(lastMinutes),\n                moment(item.time).diff(moment(lastMinutes), 'millisecond'),\n              )\n              return moment(item.time).diff(moment(lastMinutes), 'millisecond') < 0\n            }) - 1\n          let newtTadeArrayView: RawDataTradeItem[] = [],\n            volume = 0,\n            _high = 0,\n            _low = Infinity\n          if (index >= 0) {\n            for (let i = index; i >= 0; i--) {\n              const item: RawDataTradeItem = tradeArray[i]\n              newtTadeArrayView.push(item)\n              let price = getValuePrecisionThousand(\n                tradeArray[i].price.value,\n                undefined,\n                undefined,\n                precision,\n                true,\n                { isPrice: true },\n              )\n\n              volume += volumeToCount(base, item.__raw__.volume ?? 0) ?? 0\n              if (price < _low) {\n                _low = price\n              }\n              if (price > _high) {\n                _high = price\n              }\n            }\n          }\n          myLog('addCandlestick', newtTadeArrayView.length)\n          if (\n            moment(now).diff(moment(viewDate), 'millisecond') > TradingIntervalToTimer[timeInterval]\n          ) {\n            let index = Math.floor(\n              (now - viewDate.getTime()) / TradingIntervalToTimer[timeInterval],\n            )\n            const open =\n              newtTadeArrayView.length && newtTadeArrayView[0].price?.value\n                ? getValuePrecisionThousand(\n                    newtTadeArrayView[0].price.value,\n                    undefined,\n                    undefined,\n                    precision,\n                    true,\n                    { isPrice: true },\n                  )\n                : candlestickViewData[candlestickViewData.length - 1].close\n            let i = 1\n            while (i <= index) {\n              candlestickViewData.push({\n                date: new Date(\n                  viewDate.getTime() + TradingIntervalToTimer[timeInterval] * i,\n                  // now - index * TradingIntervalToTimer[timeInterval]\n                ),\n                open,\n                high: open,\n                low: open,\n                close: open,\n                volume: 0,\n                txs: 0,\n              })\n              i++\n            }\n          }\n          if (newtTadeArrayView.length) {\n            let lastOne = candlestickViewData[candlestickViewData.length - 1]\n            lastOne.volume += volume\n            lastOne.close = getValuePrecisionThousand(\n              newtTadeArrayView[newtTadeArrayView.length - 1].price.value,\n              undefined,\n              undefined,\n              precision,\n              true,\n              { isPrice: true },\n            )\n            lastOne.high = lastOne.high > _high ? lastOne.high : _high\n            lastOne.low = lastOne.low < _low ? lastOne.low : _low\n            lastOne.txs += newtTadeArrayView.length\n          }\n        }\n        return candlestickViewData\n      })\n      setLastMinutes(now)\n    }\n  }, [market, marketMap, , lastMinutes])\n  const handleTimeIntervalChange = React.useCallback((timeInterval: TradingInterval) => {\n    setTimeInterval(timeInterval)\n  }, [])\n  React.useEffect(() => {\n    genCandlestickData({ market, timeInterval })\n  }, [market, timeInterval])\n\n  useEffect(() => {\n    addCandlestick()\n  }, [tradeArray])\n\n  return {\n    market,\n    timeInterval,\n    candlestickViewData,\n    genCandlestickData,\n    handleTimeIntervalChange,\n  }\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/ProTradePage/panel/chart/index.tsx",
    "content": "import React from 'react'\nimport { bindTrigger } from 'material-ui-popup-state/es'\nimport { bindPopper, usePopupState } from 'material-ui-popup-state/hooks'\nimport { withTranslation, WithTranslation } from 'react-i18next'\nimport {\n  Box,\n  Checkbox,\n  ClickAwayListener,\n  Divider,\n  Grid,\n  MenuItem,\n  Typography,\n} from '@mui/material'\nimport { ChartType, PopoverPure, ScaleAreaChart, SubIndicator } from '@loopring-web/component-lib'\nimport {\n  depth2ViewData,\n  DepthViewData,\n  KLineFeaturesIcon,\n  MarketType,\n} from '@loopring-web/common-resources'\nimport styled from '@emotion/styled'\nimport { usePageTradePro, useTokenMap } from '@loopring-web/core'\n\nimport { useKlineChart } from './hook'\nimport { chartFearturesList, SubIndicatorList, timeIntervalData } from './klineConfig'\nimport { cloneDeepWith } from 'lodash'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nconst ChartItemStyled = styled(Typography)`\n  //font-size: 1.2em;\n  cursor: pointer;\n  margin-top: 1px;\n`\n\nexport const ChartView = withTranslation('common')(\n  ({\n    market,\n    rowLength,\n    t,\n    i18n,\n    isShowDepth = true,\n    ...rest\n  }: {\n    market?: MarketType\n    rowLength: number\n    isShowDepth?: boolean\n  } & WithTranslation) => {\n    const { candlestickViewData, timeInterval, handleTimeIntervalChange } = useKlineChart(market)\n    const [subChart, setSubChart] = React.useState(SubIndicator.VOLUME)\n    const [chosenIndicators, setChosenIndicators] = React.useState<string[]>(\n      chartFearturesList.map((o) => o.id),\n    )\n    const [chosenChart, setChosenChart] = React.useState(\n      !isShowDepth ? ChartType.Kline : ChartType.Kline,\n    )\n\n    const [depthViewData, setDepthViewData] = React.useState<{\n      asks: DepthViewData[]\n      bids: DepthViewData[]\n    }>({\n      asks: [],\n      bids: [],\n    })\n\n    // @ts-ignore\n    const [, baseSymbol, quoteSymbol] = market.match(/(\\w+)-(\\w+)/i)\n\n    const { pageTradePro } = usePageTradePro()\n    const { marketMap, tokenMap } = useTokenMap()\n\n    const isKline = chosenChart === ChartType.Kline\n    const precisionForPrice = marketMap[market || '']?.precisionForPrice\n\n    const rebuildList = React.useCallback(() => {\n      const depth = pageTradePro.depth\n      if (depth && (depth.bids.length || depth.asks.length)) {\n        const baseDecimal = tokenMap[baseSymbol]?.decimals\n        const quoteDecimal = tokenMap[baseSymbol]?.decimals\n        // const precisionForPrice = marketMap[ (market || '') ]?.precisionForPrice;\n        //@ts-ignore\n        const basePrecision = tokenMap[baseSymbol].precisionForOrder\n        let [countAsk, countBid] = [rowLength, rowLength]\n        // if (depthType === DepthShowType.bids) {\n        //     [countAsk, countBid] = [0, rowLength * 2]\n        // } else if (depthType === DepthShowType.asks) {\n        //     [countAsk, countBid] = [rowLength * 2, 0]\n        // } else {\n        // }\n        const viewData = depth2ViewData({\n          depth,\n          countAsk: countAsk,\n          countBid: countBid,\n          baseDecimal,\n          quoteDecimal,\n          precisionForPrice,\n          basePrecision,\n        })\n        setDepthViewData(viewData)\n      }\n    }, [pageTradePro.depth, tokenMap, baseSymbol, rowLength, precisionForPrice])\n\n    React.useEffect(() => {\n      rebuildList()\n    }, [rebuildList, pageTradePro.depth, tokenMap, baseSymbol, marketMap, market, rowLength])\n\n    const getTrendData = React.useCallback(() => {\n      const originalData = cloneDeepWith(depthViewData)\n      const formattedData = {\n        bidsPrices: originalData.bids.map((o) => o.price).reverse(),\n        bidsAmtTotals: originalData.bids\n          .map((o) => Number(o.amtTotalForShow.replaceAll(sdk.SEP, '')))\n          .reverse(),\n        asksPrices: originalData.asks.map((o) => o.price).reverse(),\n        asksAmtTotals: originalData.asks\n          .map((o) => Number(o.amtTotalForShow.replaceAll(sdk.SEP, '')))\n          .reverse(),\n      }\n      return formattedData\n    }, [depthViewData])\n\n    const handleSubChartFeatureClick = React.useCallback((sub: SubIndicator) => {\n      setSubChart(sub)\n    }, [])\n\n    const handleChartTypeChange = React.useCallback((chartType: ChartType) => {\n      setChosenChart(chartType)\n    }, [])\n\n    const popState = usePopupState({\n      variant: 'popover',\n      popupId: `popup-pro-kline-features`,\n    })\n\n    return (\n      <>\n        <Box display={'flex'} flexDirection={'column'} alignItems={'stretch'} height={'100%'}>\n          <Box component={'header'} width={'100%'} paddingX={2}>\n            <Typography variant={'body1'} lineHeight={'44px'}>\n              {t(`labelProChartTitle`)}\n            </Typography>\n          </Box>\n          <Divider style={{ marginTop: '-1px' }} />\n          <Box\n            width={'100%'}\n            height={'36px'}\n            paddingX={1}\n            paddingY={1}\n            display={'flex'}\n            justifyContent={'space-between'}\n            alignItems={'center'}\n          >\n            <Box display={'flex'} alignItems={'center'} style={{ overflowX: 'auto' }}>\n              {isKline && (\n                <Grid container spacing={1} marginRight={1} minWidth={296}>\n                  {timeIntervalData.map((item) => {\n                    const { id, i18nKey } = item\n                    const isSelected = id === timeInterval\n                    return (\n                      <Grid key={id} item>\n                        <ChartItemStyled\n                          variant={'body2'}\n                          color={\n                            isSelected ? 'var(--color-text-primary)' : 'var(--color-text-third)'\n                          }\n                          onClick={() => handleTimeIntervalChange(id)}\n                        >\n                          {t(i18nKey)}\n                        </ChartItemStyled>\n                      </Grid>\n                    )\n                  })}\n                  <Grid item>\n                    <KLineFeaturesIcon\n                      {...bindTrigger(popState)}\n                      onClick={(e: any) => {\n                        bindTrigger(popState).onClick(e)\n                      }}\n                      style={{ cursor: 'pointer', marginTop: 2 }}\n                      htmlColor={'var(--color-text-third)'}\n                    />\n\n                    <PopoverPure\n                      className={'arrow-center no-arrow'}\n                      {...bindPopper(popState)}\n                      anchorOrigin={{\n                        vertical: 'bottom',\n                        horizontal: 'center',\n                      }}\n                      transformOrigin={{\n                        vertical: 'top',\n                        horizontal: 'center',\n                      }}\n                    >\n                      <ClickAwayListener onClickAway={() => popState.setOpen(false)}>\n                        <Box>\n                          {chartFearturesList.map((o) => (\n                            <MenuItem key={o.id} value={o.label}>\n                              <Box\n                                width={'9rem'}\n                                display={'flex'}\n                                justifyContent={'space-between'}\n                                alignItems={'center'}\n                              >\n                                <Typography>{o.label}</Typography>\n                                <Checkbox\n                                  checked={chosenIndicators.includes(o.id)}\n                                  onChange={(\n                                    event: React.ChangeEvent<HTMLInputElement>,\n                                    checked: boolean,\n                                  ) =>\n                                    checked\n                                      ? setChosenIndicators((prev) => [...prev, o.id])\n                                      : setChosenIndicators((prev) =>\n                                          prev.filter((indicator) => indicator !== o.id),\n                                        )\n                                  }\n                                />\n                              </Box>\n                            </MenuItem>\n                          ))}\n                        </Box>\n                      </ClickAwayListener>\n                    </PopoverPure>\n                  </Grid>\n                </Grid>\n              )}\n            </Box>\n            {isShowDepth ? (\n              <Box style={{ overflowX: 'auto' }}>\n                <Grid container spacing={2} minWidth={160}>\n                  <Grid item onClick={() => handleChartTypeChange(ChartType.Kline)}>\n                    <ChartItemStyled\n                      style={{ fontSize: 14 }}\n                      color={isKline ? 'var(--color-text-primary)' : 'var(--color-text-third)'}\n                    >\n                      {t('labelProChartTradingView')}\n                    </ChartItemStyled>\n                  </Grid>\n                  <Grid item onClick={() => handleChartTypeChange(ChartType.Depth)}>\n                    <ChartItemStyled\n                      style={{ fontSize: 14 }}\n                      color={!isKline ? 'var(--color-text-primary)' : 'var(--color-text-third)'}\n                    >\n                      {t('labelProChartDepth')}\n                    </ChartItemStyled>\n                  </Grid>\n                </Grid>\n              </Box>\n            ) : (\n              <></>\n            )}\n          </Box>\n          <Divider style={{ marginTop: '-1px' }} />\n          <Box flex={1} width={'100%'}>\n            <ScaleAreaChart\n              type={isKline ? ChartType.Kline : ChartType.Depth}\n              data={isKline ? candlestickViewData : getTrendData()}\n              interval={isKline ? timeInterval : undefined}\n              marketPrecision={precisionForPrice}\n              indicator={\n                isKline\n                  ? {\n                      mainIndicators: chartFearturesList\n                        .filter((o) => chosenIndicators.includes(o.id))\n                        .map((item) => ({\n                          indicator: item.id,\n                          params: item.params,\n                        })),\n                      subIndicator: [\n                        {\n                          indicator: subChart,\n                          params:\n                            subChart === SubIndicator.SAR\n                              ? {\n                                  accelerationFactor: 0.02,\n                                  maxAccelerationFactor: 0.2,\n                                }\n                              : {},\n                        },\n                      ],\n                    }\n                  : undefined\n              }\n            />\n          </Box>\n          {isKline && (\n            <>\n              <Divider style={{ marginTop: '-1px' }} />\n              <Box\n                width={'100%'}\n                height={'36px'}\n                paddingX={1}\n                display={'flex'}\n                justifyContent={'space-between'}\n                alignItems={'center'}\n              >\n                <Grid container spacing={1}>\n                  {SubIndicatorList.map((o) => {\n                    const isSelected = o.id === subChart\n                    return (\n                      <Grid key={o.id} item>\n                        <ChartItemStyled\n                          color={\n                            isSelected ? 'var(--color-text-primary)' : 'var(--color-text-third)'\n                          }\n                          onClick={() => handleSubChartFeatureClick(o.id)}\n                        >\n                          {o.id}\n                        </ChartItemStyled>\n                      </Grid>\n                    )\n                  })}\n                </Grid>\n              </Box>\n            </>\n          )}\n        </Box>\n      </>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/webapp/src/pages/ProTradePage/panel/chart/klineConfig.ts",
    "content": "import { TradingInterval } from '@loopring-web/loopring-sdk'\nimport { MainIndicator, SubIndicator } from '@loopring-web/component-lib'\n\nexport const timeIntervalData = [\n  {\n    id: TradingInterval.min1,\n    i18nKey: 'labelProTime1m',\n  },\n  {\n    id: TradingInterval.min5,\n    i18nKey: 'labelProTime5m',\n  },\n  {\n    id: TradingInterval.min15,\n    i18nKey: 'labelProTime15m',\n  },\n  {\n    id: TradingInterval.min30,\n    i18nKey: 'labelProTime30m',\n  },\n  {\n    id: TradingInterval.hr1,\n    i18nKey: 'labelProTime1H',\n  },\n  {\n    id: TradingInterval.hr2,\n    i18nKey: 'labelProTime2H',\n  },\n  {\n    id: TradingInterval.hr4,\n    i18nKey: 'labelProTime4H',\n  },\n  {\n    id: TradingInterval.hr12,\n    i18nKey: 'labelProTime12H',\n  },\n  {\n    id: TradingInterval.d1,\n    i18nKey: 'labelProTime1D',\n  },\n  {\n    id: TradingInterval.w1,\n    i18nKey: 'labelProTime1W',\n  },\n]\n\nexport const SubIndicatorList = [\n  {\n    id: SubIndicator.VOLUME,\n  },\n  {\n    id: SubIndicator.MACD,\n  },\n  {\n    id: SubIndicator.RSI,\n  },\n  {\n    id: SubIndicator.SAR,\n  },\n]\n\nexport const chartFearturesList = [\n  {\n    id: MainIndicator.MA,\n    label: 'MA',\n    params: { period: 7 },\n  },\n  {\n    id: MainIndicator.EMA,\n    label: 'EMA',\n    params: { period: 7 },\n  },\n  {\n    id: MainIndicator.BOLL,\n    label: 'BOLL',\n    params: {},\n  },\n]\n"
  },
  {
    "path": "packages/webapp/src/pages/ProTradePage/panel/index.ts",
    "content": "export * from './toolbar'\nexport * from './walletInfo'\nexport * from './chart'\nexport * from './market'\nexport * from './spot'\nexport * from './orderTable'\n"
  },
  {
    "path": "packages/webapp/src/pages/ProTradePage/panel/market/index.tsx",
    "content": "import { WithTranslation, withTranslation } from 'react-i18next'\nimport {\n  DepthBlock,\n  DepthTitle,\n  DepthType,\n  ToggleButtonGroup,\n  TradePro,\n  useSettings,\n} from '@loopring-web/component-lib'\nimport {\n  BreakPoint,\n  CurrencyToTag,\n  depth2ViewData,\n  DepthFIcon,\n  DepthHIcon,\n  DepthViewData,\n  DropDownIcon,\n  EmptyValueTag,\n  getValuePrecisionThousand,\n  MarketType,\n  PriceTag,\n  SoursURL,\n  UpColor,\n  UpIcon,\n} from '@loopring-web/common-resources'\nimport { Box, Divider, MenuItem, Tab, Tabs, Typography } from '@mui/material'\nimport React from 'react'\nimport { usePageTradePro, useSystem, useTokenMap, useTokenPrices } from '@loopring-web/core'\nimport styled from '@emotion/styled'\nimport { TextField } from '@loopring-web/component-lib'\nexport enum TabMarketIndex {\n  Orderbook = 'Orderbook',\n  Trades = 'Trades',\n}\n\nenum DepthShowType {\n  asks = 'asks',\n  half = 'half',\n  bids = 'bids',\n}\n\nconst MarketToolbar = styled(Box)`\n  &.pro .MuiToggleButtonGroup-root {\n    .MuiToggleButton-root.MuiToggleButton-sizeSmall,\n    .MuiToggleButton-root.MuiToggleButton-sizeSmall.Mui-selected {\n      //&:not(:first-of-type), &:not(:last-child) {\n      //  border:0;\n      //}\n      height: 24px;\n      width: 24px;\n      padding: 0;\n      border: 0;\n      background: var(--opacity) !important;\n\n      :hover {\n        border: 0;\n\n        svg {\n          path {\n            fill: var(--color-text-button-Select);\n          }\n        }\n      }\n    }\n\n    .MuiToggleButton-root.MuiToggleButton-sizeSmall.Mui-selected {\n      svg {\n        path {\n          fill: var(--color-text-button-Select);\n        }\n      }\n    }\n  }\n\n  //.MuiToggleButton-root.MuiToggleButton-sizeSmall.Mui-selected{\n  //  depthType === DepthShowType.bids ?  :\n  //}\n` as typeof Box\n\nexport const MarketView = withTranslation('common')(\n  ({\n    rowLength,\n    tableLength,\n    breakpoint,\n    main,\n    t,\n    market,\n    isOnlyTrade = false,\n    ...rest\n  }: {\n    market: MarketType\n    main: keyof typeof TabMarketIndex\n    breakpoint: BreakPoint\n    rowLength: number\n    tableLength: number\n    isOnlyTrade?: boolean\n  } & WithTranslation) => {\n    // @ts-ignore\n    const [, baseSymbol, quoteSymbol] = market.match(/(\\w+)-(\\w+)/i)\n    const [tabIndex, setTabIndex] = React.useState<TabMarketIndex>(main as TabMarketIndex)\n    const { pageTradePro, updatePageTradePro } = usePageTradePro()\n    const { marketMap, tokenMap } = useTokenMap()\n    const { upColor, currency } = useSettings()\n    const { tokenPrices } = useTokenPrices()\n    const { forexMap } = useSystem()\n\n    const [depthViewData, setDepthViewData] = React.useState<{\n      asks: DepthViewData[]\n      bids: DepthViewData[]\n    }>({\n      asks: [],\n      bids: [],\n    })\n    const [depthType, setDepthType] = React.useState<DepthShowType>(DepthShowType.half)\n    const handleOnDepthTypeChange = React.useCallback(\n      (event: React.MouseEvent<HTMLElement> | any, newValue) => {\n        setDepthType(newValue)\n        rebuildList()\n      },\n      [],\n    )\n\n    const handleOnLevelChange = React.useCallback(\n      (event: React.ChangeEvent<{ value: string }>) => {\n        updatePageTradePro({ market, depthLevel: Number(event.target?.value) })\n      },\n      [market],\n    )\n    React.useEffect(() => {\n      if ([BreakPoint.lg, BreakPoint.xlg].includes(breakpoint)) {\n        setTabIndex(main as TabMarketIndex)\n      }\n    }, [breakpoint])\n    const rebuildList = React.useCallback(() => {\n      const depth = pageTradePro.depth\n      if (depth && (depth.bids.length || depth.asks.length)) {\n        const baseDecimal = tokenMap[baseSymbol]?.decimals\n        const quoteDecimal = tokenMap[baseSymbol]?.decimals\n        const precisionForPrice = marketMap[market]?.precisionForPrice\n        //@ts-ignore\n        const basePrecision = tokenMap[baseSymbol].precisionForOrder\n        let [countAsk, countBid] = [rowLength, rowLength]\n        if (depthType === DepthShowType.bids) {\n          ;[countAsk, countBid] = [0, rowLength * 2]\n        } else if (depthType === DepthShowType.asks) {\n          ;[countAsk, countBid] = [rowLength * 2, 0]\n        } else {\n        }\n        const viewData = depth2ViewData({\n          depth,\n          countAsk,\n          countBid,\n          baseDecimal,\n          quoteDecimal,\n          precisionForPrice,\n          basePrecision,\n        })\n        setDepthViewData(viewData)\n      }\n    }, [pageTradePro, depthType, rowLength])\n    const middlePrice = React.useMemo(() => {\n      const { ticker, depth } = pageTradePro\n      let close: number | string | undefined = undefined\n      let up: 'up' | 'down' | '' = ''\n      let priceColor = ''\n      let value = ''\n      if (ticker && depth && tokenPrices && depth.mid_price && depth.symbol === market) {\n        const quotePrice = tokenPrices[quoteSymbol]\n        close = ticker.close ? ticker.close : depth?.mid_price\n        if (depth.mid_price === close) {\n          priceColor = ''\n          up = ''\n        } else if (depth.mid_price < close) {\n          priceColor = upColor == UpColor.green ? 'var(--color-success)' : 'var(--color-error)'\n          up = 'up'\n        } else {\n          up = 'down'\n          priceColor = upColor == UpColor.green ? 'var(--color-error)' : 'var(--color-success)'\n        }\n\n        value =\n          '\\u2248 ' +\n          PriceTag[CurrencyToTag[currency]] +\n          getValuePrecisionThousand(\n            close * (quotePrice ?? 0) * (forexMap[currency] ?? 0),\n            undefined,\n            undefined,\n            2,\n            true,\n            { isFait: true },\n          )\n      }\n      close = close ? close.toFixed(marketMap[market]?.precisionForPrice) : undefined\n      return (\n        <Typography\n          color={'var(--color-text-third)'}\n          variant={'body2'}\n          component={'p'}\n          display={'inline-flex'}\n          textAlign={'center'}\n          alignItems={'baseline'}\n          onClick={(event: any) => {\n            priceClick(event, { price: close } as any, 'close')\n          }}\n        >\n          {close ? (\n            <>\n              <Typography\n                lineHeight={1}\n                color={priceColor}\n                component={'span'}\n                paddingRight={1}\n                alignItems={'center'}\n                display={'inline-flex'}\n              >\n                {close}\n                {up && (\n                  <UpIcon\n                    fontSize={'small'}\n                    htmlColor={priceColor}\n                    style={{\n                      transform: priceColor === 'up' ? '' : 'rotate(-180deg)',\n                    }}\n                  />\n                )}\n              </Typography>\n              {value}\n            </>\n          ) : (\n            EmptyValueTag\n          )}\n        </Typography>\n      )\n    }, [pageTradePro, market, currency, tokenPrices])\n    const toggleData = React.useMemo(() => {\n      return [\n        {\n          value: DepthShowType.half,\n          JSX: (\n            <DepthHIcon\n              fontSize={'large'}\n              bo={'var(--color-border)'}\n              l={'var(--color-border)'}\n              a={'var(--color-error)'}\n              b={'var(--color-success)'}\n            />\n          ),\n          key: DepthShowType.half,\n        },\n        {\n          value: DepthShowType.bids,\n          JSX: (\n            <DepthFIcon\n              fontSize={'large'}\n              bo={'var(--color-border)'}\n              l={'var(--color-border)'}\n              a={'var(--color-success)'}\n              b={''}\n            />\n          ),\n          key: DepthShowType.bids,\n        },\n        {\n          value: DepthShowType.asks,\n          JSX: (\n            <DepthFIcon\n              fontSize={'large'}\n              bo={'var(--color-border)'}\n              l={'var(--color-border)'}\n              a={'var(--color-error)'}\n              b={''}\n            />\n          ),\n          key: DepthShowType.asks,\n        },\n      ]\n    }, [depthType])\n    const tradeProTable = React.useMemo(() => {\n      // myLog('tableLength',tableLength)\n\n      return (\n        <>\n          {pageTradePro.tradeArray && market && marketMap ? (\n            <TradePro\n              // rowHeight={MarketRowHeight}\n              // headerRowHeight={20}\n              marketInfo={marketMap[market]}\n              rawData={pageTradePro.tradeArray ? pageTradePro.tradeArray.slice(0, tableLength) : []}\n              // basePrecision={basePrecision}\n              precision={marketMap[market]?.precisionForPrice}\n              currentheight={tableLength * 20 + 20}\n            />\n          ) : (\n            <Box\n              flex={1}\n              height={'100%'}\n              display={'flex'}\n              alignItems={'center'}\n              justifyContent={'center'}\n            >\n              <img className='loading-gif' width='36' src={`${SoursURL}images/loading-line.gif`} />\n            </Box>\n          )}\n        </>\n      )\n    }, [tableLength, market, pageTradePro.tradeArray, pageTradePro.depthLevel])\n\n    const priceClick = React.useCallback(\n      (event, chooseDepth, type) => {\n        updatePageTradePro({ market, chooseDepth: { ...chooseDepth, type } })\n      },\n      [updatePageTradePro, market],\n    )\n    React.useEffect(() => {\n      if (pageTradePro.depth?.symbol === market && rowLength) {\n        rebuildList()\n      }\n    }, [pageTradePro.depth, depthType, rowLength])\n    // const defaultDepth =\n    // React.useEffect(() => {\n    //     // if (pageTradePro.depth?.symbol === market && rowLength) {\n    //     //     rebuildList()\n    //     // }\n    // }, [pageTradePro.depthLevel])\n    // const Select = React.useMemo(() => {\n    //     return\n    // }, [pageTradePro.precisionLevels, pageTradePro.depthLevel, handleOnLevelChange])\n    return (\n      <Box display={'flex'} flexDirection={'column'} alignItems={'stretch'} height={'100%'}>\n        <Box component={'header'} width={'100%'} paddingX={2}>\n          {[BreakPoint.lg, BreakPoint.xlg].includes(breakpoint) ? (\n            // <Tabs value={tabIndex}>\n            //     <Tab value={tabIndex} labelProl={t(`labelPro${tabIndex}`)}/>\n            <Typography variant={'body1'} lineHeight={'44px'}>\n              {t(`labelPro${tabIndex}`)}\n            </Typography>\n          ) : (\n            // </Tabs>\n            <Tabs\n              value={tabIndex}\n              onChange={(_e, value) => {\n                setTabIndex(value)\n              }}\n            >\n              {!isOnlyTrade && (\n                <Tab\n                  key={TabMarketIndex.Orderbook}\n                  value={TabMarketIndex.Orderbook}\n                  label={t(`labelPro${TabMarketIndex.Orderbook}`)}\n                />\n              )}\n\n              <Tab\n                key={TabMarketIndex.Trades}\n                value={TabMarketIndex.Trades}\n                label={t(`labelPro${TabMarketIndex.Trades}`)}\n              />\n            </Tabs>\n          )}\n        </Box>\n        <Divider style={{ marginTop: '-1px' }} />\n        {tabIndex === TabMarketIndex.Orderbook ? (\n          <Box className={'depthPanel'} flex={1} paddingY={1}>\n            <MarketToolbar\n              component={'header'}\n              className={'pro'}\n              width={'100%'}\n              display={'flex'}\n              paddingX={2}\n              alignItems={'stretch'}\n              justifyContent={'space-between'}\n              height={24}\n            >\n              <ToggleButtonGroup\n                exclusive\n                {...{\n                  ...rest,\n                  t,\n                  tgItemJSXs: toggleData,\n                  value: depthType,\n                  size: 'small',\n                }}\n                onChange={handleOnDepthTypeChange}\n              />\n              <TextField\n                id='outlined-select-level'\n                select\n                size={'small'}\n                value={pageTradePro.depthLevel}\n                onChange={handleOnLevelChange}\n                inputProps={{ IconComponent: DropDownIcon }}\n              >\n                {pageTradePro.precisionLevels &&\n                  pageTradePro.precisionLevels.map(({ value, label }) => (\n                    <MenuItem key={value} value={value}>\n                      {label}\n                    </MenuItem>\n                  ))}\n              </TextField>\n            </MarketToolbar>\n\n            {pageTradePro.ticker && pageTradePro.depth?.symbol === pageTradePro.market ? (\n              <Box display={'flex'} flexDirection={'column'} alignItems={'stretch'} paddingX={2}>\n                <Box paddingTop={1 / 2}>\n                  <DepthTitle marketInfo={marketMap[market]} />\n                </Box>\n                <DepthBlock\n                  onClick={priceClick}\n                  marketInfo={marketMap[market]}\n                  type={DepthType.ask}\n                  // quotePrecision={tokenMap[quoteSymbol].precision}\n                  depths={depthViewData.asks}\n                  depthLevel={pageTradePro.depthLevel}\n                  // showTitle={true}\n                />\n                <Box\n                  display={'flex'}\n                  flexDirection={'column'}\n                  alignItems={'center'}\n                  justifyContent={'center'}\n                  height={24}\n                  style={{ cursor: 'pointer' }}\n                >\n                  {middlePrice}\n                </Box>\n                <DepthBlock\n                  onClick={priceClick}\n                  marketInfo={marketMap[market]}\n                  type={DepthType.bid}\n                  depths={depthViewData.bids}\n                  depthLevel={pageTradePro.depthLevel}\n                  // showTitle={false}\n                />\n              </Box>\n            ) : (\n              <Box\n                flex={1}\n                height={'100%'}\n                display={'flex'}\n                alignItems={'center'}\n                justifyContent={'center'}\n              >\n                <img\n                  className='loading-gif'\n                  alt={'loading'}\n                  width='36'\n                  src={`${SoursURL}images/loading-line.gif`}\n                />\n              </Box>\n            )}\n          </Box>\n        ) : (\n          <Box className={'tradePanel'} flex={1} paddingY={1}>\n            {tradeProTable}\n          </Box>\n        )}\n      </Box>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/webapp/src/pages/ProTradePage/panel/orderTable/index.tsx",
    "content": "import React from 'react'\nimport { TFunction, withTranslation } from 'react-i18next'\nimport { Box, Checkbox, Divider, FormControlLabel, Tab, Tabs } from '@mui/material'\nimport { OrderHistoryTable } from '@loopring-web/component-lib'\nimport { CheckBoxIcon, CheckedIcon, MarketType } from '@loopring-web/common-resources'\nimport {\n  tradeProSettings as tradeProSettingsReduce,\n  useAccount,\n  useGetOrderHistorys,\n} from '@loopring-web/core'\nimport styled from '@emotion/styled'\nimport { useOrderList } from '../../../AssetPage'\n\nconst CheckboxStyled = styled(Box)`\n  position: absolute;\n  top: 50%;\n  right: ${({ theme }) => theme.unit * 3}px;\n  transform: translateY(-50%);\n`\n\nconst BoxStyle = styled(Box)`\n  & .rdg {\n    min-height: initial;\n  }\n\n  overflow: auto;\n\n  &.min-height .rdg {\n    min-height: 240px;\n  }\n` as typeof Box\nexport const OrderTableView = withTranslation('common')(\n  <C extends { [key: string]: any }>({\n    t,\n    market,\n    handleOnMarketChange,\n    isStopLimit = false,\n  }: {\n    t: TFunction<'translation'>\n    market?: string\n    handleOnMarketChange: (newMarket: MarketType) => void\n    isStopLimit?: boolean\n  }) => {\n    const {\n      getOrderDetail,\n      getOrderList,\n      rawData,\n      orderDetailList,\n      cancelOrder,\n      showLoading,\n      clearRawData,\n      setOrderOriginalData,\n      handleScroll,\n      clearOrderDetail,\n      showDetailLoading,\n      cancelOrderByHashList,\n    } = useOrderList({ isStopLimit, isOrderBookScroll: true })\n    const { userOrderDetailList, getUserOrderDetailTradeList } = useGetOrderHistorys()\n    const [tabValue, setTabValue] = React.useState(0)\n    const {\n      account: { readyState },\n    } = useAccount()\n    const isShowHidePairsOption = readyState === 'ACTIVATED'\n    const { tradeProSettings, updateIsHideOtherPairs } =\n      tradeProSettingsReduce.useTradeProSettings()\n\n    const filteredData = React.useMemo(() => {\n      return tradeProSettings?.hideOtherTradingPairs\n        ? rawData.filter((o) => o.market === market)\n        : rawData\n    }, [tradeProSettings, market, rawData])\n\n    const updateOrderList = React.useCallback(\n      async (currentTabIndex: number) => {\n        getOrderList({\n          limit: 50,\n          status:\n            currentTabIndex === 0\n              ? ['processing']\n              : ['processed', 'failed', 'cancelled', 'cancelling', 'expired'],\n        })\n      },\n      [getOrderList, setOrderOriginalData],\n    )\n\n    const handleTabSwitch = React.useCallback(\n      (index: number) => {\n        setTabValue(index)\n        clearRawData()\n        updateOrderList(index)\n      },\n      [clearRawData, updateOrderList],\n    )\n\n    const handleCheckBoxChange = React.useCallback(\n      (event: React.ChangeEvent<HTMLInputElement>) => {\n        // setHideOtherPairs(event.target.checked)\n        updateIsHideOtherPairs({\n          isHide: event.target.checked,\n        })\n      },\n      [updateIsHideOtherPairs],\n    )\n    const onRowClick = (_rowIdx: number, row: any) => {\n      if (row.market !== market) {\n        handleOnMarketChange(row.market)\n        // history.push(`/trade/pro/${row.market}`);\n      } else {\n        return\n      }\n    }\n    const container = React.useRef()\n\n    const height = React.useMemo(() => {\n      // @ts-ignore\n      return container?.current?.offsetHeight\n      // @ts-ignore\n    }, [container?.current?.offsetHeight])\n    return (\n      <>\n        <Box padding={2} paddingTop={0} paddingBottom={0} style={{ position: 'relative' }}>\n          <Tabs\n            value={tabValue}\n            onChange={(e, index) => handleTabSwitch(index)}\n            aria-label='tabs orderTable'\n          >\n            <Tab label={t('labelOrderTableOpenOrder')} />\n            <Tab label={t('labelOrderTableOrderHistory')} />\n          </Tabs>\n          {isShowHidePairsOption && (\n            <CheckboxStyled>\n              <FormControlLabel\n                style={{ marginRight: 0 }}\n                control={\n                  <Checkbox\n                    checked={tradeProSettings?.hideOtherTradingPairs}\n                    checkedIcon={<CheckedIcon />}\n                    icon={<CheckBoxIcon />}\n                    color='default'\n                    onChange={handleCheckBoxChange}\n                  />\n                }\n                label={t('labelTradeProHideOtherPairs')}\n              />\n            </CheckboxStyled>\n          )}\n        </Box>\n        <Divider />\n        <BoxStyle\n          flex={1}\n          ref={container}\n          className={filteredData?.length > 0 ? '' : 'min-height'}\n          display={'flex'}\n          flexDirection={'column'}\n        >\n          <OrderHistoryTable\n            {...{\n              // height,\n              // height: height-\n              isStopLimit,\n              rawData: filteredData,\n              getOrderList,\n              getOrderDetail,\n              orderDetailList,\n              cancelOrder,\n              onRowClick,\n              cancelOrderByHashList,\n              showLoading,\n              isOpenOrder: tabValue === 0,\n              isPro: true,\n              isScroll: true,\n              handleScroll: handleScroll,\n              clearOrderDetail,\n              showDetailLoading,\n              userOrderDetailList,\n              getUserOrderDetailTradeList,\n            }}\n          />\n        </BoxStyle>\n      </>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/webapp/src/pages/ProTradePage/panel/spot/hookLimit.ts",
    "content": "import React from 'react'\nimport {\n    BIGO,\n    getPriceImpactInfo,\n    LoopringAPI,\n    PriceLevel, ShowWitchAle3t1,\n    store,\n    useAccount, useAlert,\n    usePageTradePro,\n    usePlaceOrder,\n    useSubmitBtn,\n    useSystem,\n    useToast,\n    useTokenMap,\n    useTokenPrices,\n    walletLayer2Service,\n} from '@loopring-web/core'\nimport {\n    AccountStatus,\n    getValuePrecisionThousand,\n    IBData,\n    MarketType,\n    myLog,\n    TradeBaseType,\n    TradeBtnStatus,\n    TradeProType,\n} from '@loopring-web/common-resources'\nimport {\n    DepthType,\n    LimitTradeData,\n    ToastType,\n    useOpenModals,\n    useSettings,\n    useToggle,\n} from '@loopring-web/component-lib'\nimport { useTranslation } from 'react-i18next'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport * as _ from 'lodash'\nimport BigNumber from 'bignumber.js'\n\nexport const useLimit = <C extends { [key: string]: any }>({\n                                                               market,\n                                                           }: { market: MarketType } & any) => {\n    const {\n        pageTradePro,\n        updatePageTradePro,\n        // __DAYS__,\n        __SUBMIT_LOCK_TIMER__,\n        // __TOAST_AUTO_CLOSE_TIMER__\n    } = usePageTradePro()\n    const {marketMap, tokenMap} = useTokenMap()\n    const {tokenPrices} = useTokenPrices()\n    const {forexMap, allowTrade} = useSystem()\n    const {account} = useAccount()\n    const {setShowSupport, setShowTradeIsFrozen} = useOpenModals()\n    const {\n        toggle: {order},\n    } = useToggle()\n    const {currency, isMobile} = useSettings()\n\n    const {t} = useTranslation('common')\n\n    // const [alertOpen, setAlertOpen] = React.useState<boolean>(false)\n    // @ts-ignore\n    const [, baseSymbol, quoteSymbol] = market.match(/(\\w+)-(\\w+)/i)\n    // const [isMarketLoading, setIsMarketLoading] = React.useState(false)\n\n    const walletMap = pageTradePro.tradeCalcProData.walletMap ?? {}\n    const marketPrecision = marketMap[market].precisionForPrice\n    const tradePrice =\n        pageTradePro.market === market && pageTradePro.ticker\n            ? pageTradePro.ticker.close\n                ? pageTradePro.ticker.close.toFixed(marketPrecision)\n                : pageTradePro?.depth?.mid_price.toFixed(marketPrecision)\n            : 0\n    let balance =\n        tradePrice &&\n        tokenPrices &&\n        forexMap &&\n        Number(tradePrice) * tokenPrices[quoteSymbol as string] * (forexMap[currency] ?? 0)\n\n    const [limitTradeData, setLimitTradeData] = React.useState<LimitTradeData<IBData<any>>>({\n        base: {\n            belong: baseSymbol,\n            balance: walletMap ? walletMap[baseSymbol as string]?.count : 0,\n        } as IBData<any>,\n        quote: {\n            belong: quoteSymbol,\n            balance: walletMap ? walletMap[quoteSymbol as string]?.count : 0,\n        } as IBData<any>,\n        price: {\n            belong: pageTradePro.tradeCalcProData.coinQuote,\n            tradeValue: tradePrice,\n            balance,\n        } as IBData<any>,\n        type: pageTradePro.tradeType ?? TradeProType.buy,\n        isChecked: undefined,\n    })\n    const [isLimitLoading, setIsLimitLoading] = React.useState(false)\n\n    const {toastOpen, setToastOpen, closeToast} = useToast()\n\n    React.useEffect(() => {\n        resetTradeData()\n    }, [pageTradePro.tradeCalcProData.walletMap, pageTradePro.market, currency])\n\n    React.useEffect(() => {\n        if (pageTradePro.chooseDepth) {\n            const {\n                system: {forexMap},\n                settings: {currency},\n            } = store.getState()\n            //@ts-ignore\n            const [, baseSymbol, quoteSymbol] = pageTradePro.market.match(/(\\w+)-(\\w+)/i)\n            const {decimals: baseDecimal, precision: basePrecision} = tokenMap[baseSymbol]\n            const tradePrice = pageTradePro.chooseDepth\n                ? pageTradePro.chooseDepth.price\n                : pageTradePro.market === market && pageTradePro.ticker\n                    ? pageTradePro.ticker.close\n                        ? pageTradePro.ticker.close.toFixed(marketPrecision)\n                        : pageTradePro?.depth?.mid_price.toFixed(marketPrecision)\n                    : 0\n            let balance =\n                tradePrice &&\n                tokenPrices &&\n                forexMap &&\n                Number(tradePrice) * tokenPrices[quoteSymbol as string] * (forexMap[currency] ?? 0)\n\n            if (\n                (pageTradePro.tradeType === TradeProType.buy &&\n                    pageTradePro.chooseDepth.type === DepthType.ask) ||\n                (pageTradePro.tradeType === TradeProType.sell &&\n                    pageTradePro.chooseDepth.type === DepthType.bid)\n            ) {\n                const amount = getValuePrecisionThousand(\n                    sdk.toBig(pageTradePro.chooseDepth.amtTotal).div('1e' + baseDecimal),\n                    undefined,\n                    undefined,\n                    basePrecision,\n                    true,\n                ).replaceAll(sdk.SEP, '')\n                onChangeLimitEvent(\n                    {\n                        ...limitTradeData,\n                        base: {\n                            ...limitTradeData.base,\n                            tradeValue: Number(amount),\n                        },\n                        price: {\n                            ...limitTradeData.price,\n                            tradeValue: Number(tradePrice),\n                            balance: Number(balance) ?? 0,\n                        },\n                    },\n                    TradeBaseType.price,\n                )\n            } else {\n                onChangeLimitEvent(\n                    {\n                        ...limitTradeData,\n                        price: {\n                            ...limitTradeData.price,\n                            tradeValue: Number(tradePrice),\n                            balance: getValuePrecisionThousand(balance, undefined, undefined, undefined, true, {\n                                isFait: true,\n                            }),\n                        },\n                    },\n                    TradeBaseType.price,\n                )\n            }\n\n            // (tradeData: LimitTradeData<IBData<any>>, formType: TradeBaseType)\n        }\n    }, [pageTradePro.chooseDepth])\n\n    const resetTradeData = React.useCallback(\n        (type?: TradeProType) => {\n            const pageTradePro = store.getState()._router_pageTradePro.pageTradePro\n            const walletMap = pageTradePro.tradeCalcProData.walletMap ?? {}\n            // @ts-ignore\n            const [, baseSymbol, quoteSymbol] = market.match(/(\\w+)-(\\w+)/i)\n            setLimitTradeData((state) => {\n                const tradePrice =\n                    pageTradePro.market === market && pageTradePro.ticker\n                        ? pageTradePro.ticker.close\n                            ? pageTradePro.ticker.close.toFixed(marketPrecision)\n                            : pageTradePro?.depth?.mid_price.toFixed(marketPrecision)\n                        : 0\n                let balance =\n                    tradePrice &&\n                    tokenPrices &&\n                    forexMap &&\n                    Number(tradePrice) * tokenPrices[quoteSymbol as string] * (forexMap[currency] ?? 0)\n\n                return {\n                    ...state,\n                    type: type ?? pageTradePro.tradeType,\n                    base: {\n                        belong: baseSymbol,\n                        balance: walletMap ? walletMap[baseSymbol as string]?.count : 0,\n                    } as IBData<any>,\n                    quote: {\n                        belong: quoteSymbol,\n                        balance: walletMap ? walletMap[quoteSymbol as string]?.count : 0,\n                    } as IBData<any>,\n                    price: {\n                        belong: quoteSymbol,\n                        tradeValue: tradePrice,\n                        balance,\n                    } as IBData<any>,\n                }\n            })\n            updatePageTradePro({\n                market,\n                tradeType: type ?? pageTradePro.tradeType,\n                minOrderInfo: null,\n                sellUserOrderInfo: null,\n                buyUserOrderInfo: null,\n                request: null,\n                calcTradeParams: null,\n                limitCalcTradeParams: null,\n                chooseDepth: null,\n                tradeCalcProData: {\n                    ...pageTradePro.tradeCalcProData,\n                    // walletMap:walletMap as any,\n                    fee: undefined,\n                    minimumReceived: undefined,\n                    priceImpact: undefined,\n                    priceImpactColor: 'inherit',\n                    isNotMatchMarketPrice: false,\n                    marketPrice: undefined,\n                    marketRatePrice: undefined,\n                    isChecked: undefined,\n                },\n            })\n        },\n        [market, updatePageTradePro, marketPrecision, tokenPrices, forexMap, currency],\n    )\n\n    const limitSubmit = React.useCallback(\n        async (event: MouseEvent, isAgree?: boolean) => {\n            myLog('limitSubmit:', event, isAgree)\n\n            const pageTradePro = store.getState()._router_pageTradePro.pageTradePro\n            const {limitCalcTradeParams, request, tradeCalcProData} = pageTradePro\n\n            // setAlertOpen(false)\n\n            if (isAgree && LoopringAPI.userAPI && request) {\n                try {\n                    myLog('try to submit order', limitCalcTradeParams, tradeCalcProData)\n\n                    const account = store.getState().account\n\n                    const req: sdk.GetNextStorageIdRequest = {\n                        accountId: account.accountId,\n                        sellTokenId: request.sellToken.tokenId as number,\n                    }\n\n                    const storageId = await LoopringAPI.userAPI.getNextStorageId(req, account.apiKey)\n\n                    const requestClone = _.cloneDeep(request)\n                    requestClone.storageId = storageId.orderId\n\n                    myLog(requestClone)\n\n                    const response: { hash: string } | any = await LoopringAPI.userAPI.submitOrder(\n                        requestClone,\n                        account.eddsaKey.sk,\n                        account.apiKey,\n                    )\n\n                    myLog(response)\n                    if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n                        setToastOpen({\n                            open: true,\n                            type: ToastType.error,\n                            content: t('labelLimitFailed') + ' : ' + response.message,\n                        })\n                    } else {\n                        await sdk.sleep(__SUBMIT_LOCK_TIMER__)\n\n                        const resp = await LoopringAPI.userAPI.getOrderDetails(\n                            {\n                                accountId: account.accountId,\n                                orderHash: response?.hash,\n                            },\n                            account.apiKey,\n                        )\n\n                        myLog('-----> resp:', resp)\n\n                        if (resp.orderDetail?.status !== undefined) {\n                            myLog('resp.orderDetail:', resp.orderDetail)\n                            switch (resp.orderDetail?.status) {\n                                case sdk.OrderStatus.cancelled:\n                                    const baseAmount = sdk.toBig(resp.orderDetail.volumes.baseAmount)\n                                    const baseFilled = sdk.toBig(resp.orderDetail.volumes.baseFilled)\n                                    const quoteAmount = sdk.toBig(resp.orderDetail.volumes.quoteAmount)\n                                    const quoteFilled = sdk.toBig(resp.orderDetail.volumes.quoteFilled)\n                                    const percentage1 = baseAmount.eq(BIGO)\n                                        ? 0\n                                        : baseFilled.div(baseAmount).toNumber()\n                                    const percentage2 = quoteAmount.eq(BIGO)\n                                        ? 0\n                                        : quoteFilled.div(quoteAmount).toNumber()\n                                    myLog('percentage1:', percentage1, ' percentage2:', percentage2)\n                                    if (percentage1 === 0 || percentage2 === 0) {\n                                        setToastOpen({\n                                            open: true,\n                                            type: ToastType.warning,\n                                            content: t('labelSwapCancelled'),\n                                        })\n                                    } else {\n                                        setToastOpen({\n                                            open: true,\n                                            type: ToastType.success,\n                                            content: t('labelSwapSuccess'),\n                                        })\n                                    }\n                                    break\n                                case sdk.OrderStatus.processed:\n                                    setToastOpen({\n                                        open: true,\n                                        type: ToastType.success,\n                                        content: t('labelSwapSuccess'),\n                                    })\n                                    break\n                                case sdk.OrderStatus.processing:\n                                    setToastOpen({\n                                        open: true,\n                                        type: ToastType.success,\n                                        content: t('labelOrderProcessing'),\n                                    })\n                                    break\n                                default:\n                                    setToastOpen({\n                                        open: true,\n                                        type: ToastType.error,\n                                        content: t('labelLimitFailed'),\n                                    })\n                            }\n                        }\n                        resetTradeData(pageTradePro.tradeType)\n                        walletLayer2Service.sendUserUpdate()\n                    }\n\n                    setIsLimitLoading(false)\n                } catch (reason: any) {\n                    sdk.dumpError400(reason)\n                    setToastOpen({\n                        open: true,\n                        type: ToastType.error,\n                        content: t('labelLimitFailed'),\n                    })\n                }\n                setIsLimitLoading(false)\n            } else {\n                setIsLimitLoading(false)\n            }\n        },\n        [__SUBMIT_LOCK_TIMER__, resetTradeData, setToastOpen, t],\n    )\n\n    const {makeLimitReqInHook} = usePlaceOrder()\n    const onChangeLimitEvent = React.useCallback(\n        (tradeData: LimitTradeData<IBData<any>>, formType: TradeBaseType) => {\n            const pageTradePro = store.getState()._router_pageTradePro.pageTradePro\n\n            if (formType === TradeBaseType.tab) {\n                resetTradeData(tradeData.type)\n            } else {\n                let amountBase = formType === TradeBaseType.base ? tradeData.base.tradeValue : undefined\n                let amountQuote = formType === TradeBaseType.quote ? tradeData.quote.tradeValue : undefined\n                let dustCalcTradeParams: any\n\n                if (formType === TradeBaseType.price || formType === TradeBaseType.checkMarketPrice) {\n                    amountBase =\n                        tradeData.base.tradeValue !== undefined ? tradeData.base.tradeValue : undefined\n                    amountQuote =\n                        amountBase !== undefined\n                            ? undefined\n                            : tradeData.quote.tradeValue !== undefined\n                                ? tradeData.quote.tradeValue\n                                : undefined\n                }\n\n                // myLog(`tradeData price:${tradeData.price.tradeValue}`, tradeData.type, amountBase, amountQuote)\n\n                const {limitRequest, calcTradeParams, sellUserOrderInfo, buyUserOrderInfo, minOrderInfo} =\n                    makeLimitReqInHook({\n                        isBuy: tradeData.type === 'buy',\n                        base: tradeData.base.belong,\n                        quote: tradeData.quote.belong,\n                        price: tradeData.price.tradeValue as number,\n                        depth: pageTradePro.depthForCalc,\n                        amountBase,\n                        amountQuote,\n                    })\n\n                let isNotMatchMarketPrice, marketPrice, marketRatePrice\n                if (\n                    tokenPrices &&\n                    tradeData?.price?.tradeValue &&\n                    // @ts-ignore\n                    sdk.toBig(tradeData.price.tradeValue).gt(0)\n                ) {\n                    marketPrice = sdk\n                        .toBig(tokenPrices[tradeData.base.belong])\n                        .div(tokenPrices[tradeData.quote.belong])\n                    marketRatePrice =\n                        tradeData.type === 'sell'\n                            ? marketPrice.div(tradeData?.price?.tradeValue)\n                            : sdk\n                                .toBig(1)\n                                .div(marketPrice)\n                                .div(1 / tradeData?.price?.tradeValue)\n\n                    isNotMatchMarketPrice = marketRatePrice.gt(1.05)\n                    marketPrice = getValuePrecisionThousand(\n                        marketPrice.toString(),\n                        tokenMap[tradeData.quote.belong].precision,\n                        tokenMap[tradeData.quote.belong].precision,\n                        tokenMap[tradeData.quote.belong].precision,\n                    )\n                    marketRatePrice = marketRatePrice.minus(1).times(100).toFixed(2)\n                    dustCalcTradeParams = makeLimitReqInHook({\n                        isBuy: tradeData.type === 'buy',\n                        base: tradeData.base.belong,\n                        quote: tradeData.quote.belong,\n                        price: tradeData.price.tradeValue as number,\n                        depth: pageTradePro.depthForCalc,\n                        // @ts-ignore\n                        amountBase:\n                            tradeData.type === 'buy'\n                                ? undefined\n                                : sdk\n                                    .toBig(tokenMap[baseSymbol]?.orderAmounts.dust)\n                                    .div('1e' + tokenMap[tradeData.base.belong].decimals)\n                                    .toString(),\n                        // @ts-ignore\n                        amountQuote:\n                            tradeData.type === 'buy'\n                                ? sdk\n                                    .toBig(tokenMap[quoteSymbol]?.orderAmounts.dust)\n                                    .div('1e' + tokenMap[tradeData.quote.belong].decimals)\n                                    .toString()\n                                : undefined,\n                    }).calcTradeParams\n                }\n                const minAmount = BigNumber.max(\n                    minOrderInfo?.minAmount ?? 0,\n                    dustCalcTradeParams?.baseVol ?? 0,\n                ).toString()\n                const minAmtShow = sdk\n                    .toBig(minAmount)\n                    .div('1e' + tokenMap[minOrderInfo?.symbol ?? baseSymbol].decimals)\n                    .toNumber()\n                updatePageTradePro({\n                    market,\n                    sellUserOrderInfo,\n                    buyUserOrderInfo,\n                    minOrderInfo: {\n                        ...minOrderInfo,\n                        minAmount,\n                        minAmtShow,\n                        minAmtCheck: sdk.toBig(calcTradeParams?.baseVol ?? 0).gte(minAmount),\n                    },\n                    request: limitRequest as sdk.SubmitOrderRequestV3,\n                    limitCalcTradeParams: calcTradeParams,\n                    tradeCalcProData: {\n                        ...pageTradePro.tradeCalcProData,\n                        fee:\n                            calcTradeParams && calcTradeParams.maxFeeBips\n                                ? calcTradeParams.maxFeeBips?.toString()\n                                : undefined,\n                        isNotMatchMarketPrice,\n                        marketPrice,\n                        marketRatePrice,\n                        isChecked: tradeData.isChecked !== undefined && tradeData.isChecked,\n                    },\n                })\n                setLimitTradeData((state) => {\n                    const tradePrice = tradeData.price.tradeValue\n                    let balance =\n                        tradePrice &&\n                        tokenPrices &&\n                        forexMap &&\n                        Number(tradePrice) * tokenPrices[quoteSymbol as string] * (forexMap[currency] ?? 0)\n\n                    return {\n                        ...state,\n                        price: {\n                            belong: quoteSymbol,\n                            tradeValue: tradePrice,\n                            balance,\n                        } as IBData<any>,\n                        base: {\n                            ...state.base,\n                            tradeValue: calcTradeParams?.baseVolShow as number,\n                        },\n                        quote: {\n                            ...state.quote,\n                            tradeValue: calcTradeParams?.quoteVolShow as number,\n                        },\n                        isChecked: tradeData.isChecked !== undefined && tradeData.isChecked,\n                    }\n                })\n            }\n        },\n        [\n            resetTradeData,\n            makeLimitReqInHook,\n            updatePageTradePro,\n            market,\n            tokenPrices,\n            quoteSymbol,\n            forexMap,\n            currency,\n        ],\n    )\n    const handlePriceError = React.useCallback(\n        (data: IBData<any>): { error: boolean; message?: string | JSX.Element } | undefined => {\n            const tradeValue = data.tradeValue\n            if (tradeValue) {\n                const [, precision] = tradeValue.toString().split('.')\n                if (precision && precision.length > marketMap[market].precisionForPrice) {\n                    return {\n                        error: true,\n                        message: t('labelErrorPricePrecisionLimit', {\n                            symbol: data.belong,\n                            decimal: marketMap[market].precisionForPrice,\n                        }),\n                    }\n                }\n                return undefined\n            } else {\n                return undefined\n            }\n        },\n        [market, marketMap, t],\n    )\n    const {showAlert, confirmed, setShowWhich, setConfirmed} = useAlert()\n    const doShowAlert = () => {\n        const pageTradePro = store.getState()._router_pageTradePro.pageTradePro\n        const {priceLevel} = getPriceImpactInfo(\n            pageTradePro.limitCalcTradeParams,\n            account.readyState,\n            false,\n        )\n        myLog('hookSwap:---- swapCalculatorCallback priceLevel:', priceLevel)\n        setConfirmed((state) => {\n            state[1] = true\n            setShowWhich(() => {\n                if (pageTradePro?.tradeCalcProData?.isNotMatchMarketPrice) {\n                    return {isShow: true, step: 1, showWitch: ShowWitchAle3t1.AlertImpact}\n                } else if (priceLevel === PriceLevel.Lv1 || priceLevel === PriceLevel.Lv2) {\n                    return {isShow: true, step: 1, showWitch: ShowWitchAle3t1.ConfirmImpact}\n                } else {\n                    state[0] = true\n                    return {isShow: false, step: 2, showWitch: ''}\n                }\n            })\n            return state\n        })\n    }\n    React.useEffect(() => {\n        if (confirmed[0] === true && confirmed[1] === true) {\n            limitSubmit(undefined as any, true)\n            setConfirmed([false, false])\n        }\n    }, [confirmed[0], confirmed[1]])\n    const onSubmitBtnClick = React.useCallback(async () => {\n        setIsLimitLoading(true)\n        const pageTradePro = store.getState()._router_pageTradePro.pageTradePro\n        const {priceLevel} = getPriceImpactInfo(\n            pageTradePro.limitCalcTradeParams,\n            account.readyState,\n            false,\n        )\n        if (!allowTrade?.order?.enable) {\n            setShowSupport({isShow: true})\n            setIsLimitLoading(false)\n        } else if (!order.enable) {\n            setShowTradeIsFrozen({isShow: true, type: 'Limit'})\n            setIsLimitLoading(false)\n        } else {\n            doShowAlert()\n        }\n        // switch (priceLevel) {\n        //   case PriceLevel.Lv1:\n        //     setAlertOpen(true)\n        //     break\n        //   default:\n        //     limitSubmit(undefined as any, true)\n        //     break\n        // }\n        // }\n    }, [\n        account.readyState,\n        allowTrade.order.enable,\n        limitSubmit,\n        order.enable,\n        setShowSupport,\n        setShowTradeIsFrozen,\n    ])\n    const availableTradeCheck = React.useCallback((): {\n        tradeBtnStatus: TradeBtnStatus\n        label: string\n    } => {\n        const account = store.getState().account\n        const pageTradePro = store.getState()._router_pageTradePro.pageTradePro\n        const {\n            minOrderInfo,\n            // calcTradeParams,\n        } = pageTradePro\n        if (account.readyState === AccountStatus.ACTIVATED) {\n            // const type = limitTradeData.type === TradeProType.sell ? 'quote' : 'base';\n            if (\n                limitTradeData?.base.tradeValue === undefined ||\n                limitTradeData?.quote.tradeValue === undefined ||\n                limitTradeData?.price.tradeValue === undefined ||\n                limitTradeData?.base.tradeValue === 0 ||\n                limitTradeData?.quote.tradeValue === 0 ||\n                limitTradeData?.price.tradeValue === 0\n            ) {\n                return {\n                    tradeBtnStatus: TradeBtnStatus.DISABLED,\n                    label: 'labelEnterAmount',\n                }\n            } else if (!minOrderInfo?.minAmtCheck) {\n                let minOrderSize = 'Error'\n                if (minOrderInfo?.symbol) {\n                    const basePrecision = tokenMap[minOrderInfo.symbol].precision\n                    const showValue = getValuePrecisionThousand(\n                        minOrderInfo?.minAmtShow,\n                        undefined,\n                        undefined,\n                        basePrecision,\n                        true,\n                        {isAbbreviate: true},\n                    )\n                    minOrderSize = `${showValue} ${minOrderInfo?.symbol}`\n                }\n                return {\n                    tradeBtnStatus: TradeBtnStatus.DISABLED,\n                    label: `labelLimitMin| ${minOrderSize}`,\n                }\n            } else if (\n                sdk\n                    .toBig(\n                        limitTradeData[limitTradeData.type === TradeProType.buy ? 'quote' : 'base']\n                            ?.tradeValue ?? '',\n                    )\n                    .gt(limitTradeData[limitTradeData.type === TradeProType.buy ? 'quote' : 'base'].balance)\n            ) {\n                return {tradeBtnStatus: TradeBtnStatus.DISABLED, label: ''}\n            } else {\n                return {\n                    label: '',\n                    tradeBtnStatus: TradeBtnStatus.AVAILABLE,\n                }\n                // if (\n                //   pageTradePro?.tradeCalcProData.isNotMatchMarketPrice &&\n                //   !pageTradePro.tradeCalcProData.isChecked\n                // ) {\n                //   return {\n                //     label: '',\n                //     tradeBtnStatus: TradeBtnStatus.DISABLED,\n                //   }\n                // } else {\n                //   return {\n                //     label: '',\n                //     tradeBtnStatus: TradeBtnStatus.AVAILABLE,\n                //   }\n                // }\n            }\n        }\n        return {tradeBtnStatus: TradeBtnStatus.AVAILABLE, label: ''}\n    }, [limitTradeData, tokenMap, pageTradePro.tradeCalcProData?.isChecked])\n\n    const {\n        btnStatus: tradeLimitBtnStatus,\n        onBtnClick: limitBtnClick,\n        btnLabel: tradeLimitI18nKey,\n        btnStyle: tradeLimitBtnStyle,\n    } = useSubmitBtn({\n        availableTradeCheck,\n        isLoading: isLimitLoading,\n        submitCallback: onSubmitBtnClick,\n    })\n    return {\n        toastOpen,\n        setToastOpen,\n        closeToast,\n        // limitAlertOpen: alertOpen,\n        resetLimitData: resetTradeData,\n        isLimitLoading: false,\n        limitTradeData,\n        onChangeLimitEvent,\n        tradeLimitI18nKey,\n        tradeLimitBtnStatus,\n        limitSubmit,\n        limitBtnClick,\n        handlePriceError,\n        tradeLimitBtnStyle: {\n            ...tradeLimitBtnStyle,\n            ...{\n                fontSize: isMobile ? (tradeLimitI18nKey !== '' ? '1.2rem' : '1.4rem') : '1.6rem',\n            },\n        },\n        showAlert,\n        handleClose: () => {\n            setShowWhich((state) => ({...state, isShow: false}))\n            setConfirmed([false, false])\n            setIsLimitLoading(false)\n            // setIsMarketLoading(false)\n        },\n        handleConfirm: () => {\n            setShowWhich((state) => ({...state, isShow: false}))\n            setConfirmed((state) => {\n                state[showAlert.step - 1] = true\n                return state\n            })\n        },\n        priceLevel: getPriceImpactInfo(pageTradePro.calcTradeParams, account.readyState),\n\n        // marketTicker,\n    }\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/ProTradePage/panel/spot/hookMarket.ts",
    "content": "import {\n  AccountStatus,\n  defaultSlipage,\n  getValuePrecisionThousand,\n  IBData,\n  MarketType,\n  myLog,\n  TradeBtnStatus,\n  TradeProType,\n  TradeBaseType,\n} from '@loopring-web/common-resources'\nimport React from 'react'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport {\n  MarketTradeData,\n  ToastType,\n  useOpenModals,\n  useSettings,\n  useToggle,\n} from '@loopring-web/component-lib'\nimport {\n  BIGO,\n  getPriceImpactInfo,\n  LoopringAPI,\n  PriceLevel,\n  reCalcStoB,\n  ShowWitchAle3t1,\n  store,\n  useAccount,\n  useAlert,\n  useAmount,\n  usePageTradePro,\n  usePlaceOrder,\n  useSubmitBtn,\n  useSystem,\n  useTicker,\n  useToast,\n  useTokenMap,\n  useTokenPrices,\n  walletLayer2Service,\n} from '@loopring-web/core'\nimport { useTranslation } from 'react-i18next'\nimport * as _ from 'lodash'\n\nexport const useMarket = <C extends { [key: string]: any }>({\n  market,\n}: { market: MarketType } & any): {\n  [key: string]: any\n} => {\n  const { t } = useTranslation()\n  const { getAmount } = useAmount()\n  const { tokenMap, marketArray, marketMap } = useTokenMap()\n  const { tokenPrices } = useTokenPrices()\n  const { tickerMap } = useTicker()\n  // const [alertOpen, setAlertOpen] = React.useState<boolean>(false)\n  // const [confirmOpen, setConfirmOpen] = React.useState<boolean>(false)\n  const { toastOpen, setToastOpen, closeToast } = useToast()\n  const { account } = useAccount()\n  const { slippage, isMobile } = useSettings()\n  const { exchangeInfo, allowTrade } = useSystem()\n  const {\n    toggle: { order },\n  } = useToggle()\n  const { setShowSupport, setShowTradeIsFrozen } = useOpenModals()\n  const autoRefresh = React.useRef<NodeJS.Timeout | -1>(-1)\n\n  const {\n    pageTradePro,\n    updatePageTradePro,\n    __SUBMIT_LOCK_TIMER__,\n    __TOAST_AUTO_CLOSE_TIMER__,\n    __AUTO_RE_CALC__,\n  } = usePageTradePro()\n\n  // @ts-ignore\n  const [, baseSymbol, quoteSymbol] = market.match(/(\\w+)-(\\w+)/i)\n  const walletMap = pageTradePro.tradeCalcProData?.walletMap ?? {}\n  const [isMarketLoading, setIsMarketLoading] = React.useState(false)\n\n  const [marketTradeData, setMarketTradeData] = React.useState<MarketTradeData<IBData<any>>>(\n    // pageTradePro.market === market ?\n    {\n      base: {\n        belong: baseSymbol,\n        balance: walletMap ? walletMap[baseSymbol as string]?.count : 0,\n      } as IBData<any>,\n      quote: {\n        belong: quoteSymbol,\n        balance: walletMap ? walletMap[quoteSymbol as string]?.count : 0,\n      } as IBData<any>,\n      slippage: slippage && slippage !== 'N' ? slippage : defaultSlipage,\n      type: TradeProType.buy,\n    },\n  )\n  React.useEffect(() => {\n    return () => {\n      if (autoRefresh.current !== -1) {\n        clearTimeout(autoRefresh.current as NodeJS.Timeout)\n      }\n    }\n  }, [])\n  React.useEffect(() => {\n    resetTradeData()\n  }, [pageTradePro.market, pageTradePro.tradeCalcProData.walletMap])\n\n  const autoReCalc = React.useCallback(() => {\n    const pageTradePro = store.getState()._router_pageTradePro.pageTradePro\n    if (autoRefresh.current !== -1) {\n      clearTimeout(autoRefresh.current as NodeJS.Timeout)\n    }\n    if (pageTradePro.lastStepAt && marketTradeData[pageTradePro.lastStepAt].tradeValue) {\n      myLog('autoUpdate', marketTradeData)\n      onChangeMarketEvent(marketTradeData, pageTradePro.lastStepAt as TradeBaseType)\n    }\n  }, [])\n  const { makeMarketReqInHook } = usePlaceOrder()\n\n  const onChangeMarketEvent = React.useCallback(\n    (tradeData: MarketTradeData<IBData<any>>, formType: TradeBaseType) => {\n      const pageTradePro = store.getState()._router_pageTradePro.pageTradePro\n      // myLog(`onChangeMarketEvent ammPoolSnapshot:`, pageTradePro.ammPoolSnapshot)\n      if (!pageTradePro.depth) {\n        // myLog(`onChangeMarketEvent data not ready!`)\n        setIsMarketLoading(true)\n        return\n      } else {\n        setIsMarketLoading(false)\n      }\n\n      let lastStepAt = pageTradePro.lastStepAt\n\n      if (formType === TradeBaseType.tab) {\n        resetTradeData(tradeData.type)\n        return\n        // amountBase = tradeData.base.tradeValue ? tradeData.base.tradeValue : undefined\n        // amountQuote = amountBase !== undefined ? undefined : tradeData.quote.tradeValue ? tradeData.quote.tradeValue : undefined\n      } else if (['base', 'quote'].includes(formType)) {\n        lastStepAt = formType as any\n      }\n\n      if (lastStepAt) {\n        if (autoRefresh.current !== -1) {\n          clearTimeout(autoRefresh.current as NodeJS.Timeout)\n        }\n        autoRefresh.current = setTimeout(() => {\n          // myLog('autoUpdate',marketTradeData)\n          autoReCalc()\n        }, __AUTO_RE_CALC__)\n      }\n\n      // myLog(`onChangeMarketEvent tradeData:`, tradeData, 'formType',formType)\n\n      // setMarketTradeData(tradeData)\n\n      let slippage = sdk\n        .toBig(tradeData.slippage ? tradeData.slippage : defaultSlipage)\n        .times(100)\n        .toString()\n\n      let amountBase = lastStepAt === TradeBaseType.base ? tradeData.base.tradeValue : undefined\n      let amountQuote = lastStepAt === TradeBaseType.quote ? tradeData.quote.tradeValue : undefined\n\n      let {\n        marketRequest,\n        calcTradeParams,\n        sellUserOrderInfo,\n        buyUserOrderInfo,\n        minOrderInfo,\n        totalFee,\n        maxFeeBips,\n        feeTakerRate,\n        tradeCost,\n      } = makeMarketReqInHook({\n        isBuy: tradeData.type === 'buy',\n        base: tradeData.base.belong,\n        quote: tradeData.quote.belong,\n        amountBase,\n        amountQuote,\n        marketArray,\n        marketMap,\n        depth: pageTradePro.depthForCalc,\n        ammPoolSnapshot: pageTradePro.ammPoolSnapshot,\n        slippage,\n      })\n      let _tradeData = {\n        ...tradeData,\n      }\n      // let baseValue = undefined;\n      // let quoteValue = undefined;\n      if (calcTradeParams) {\n        _tradeData.base.tradeValue = calcTradeParams.isReverse\n          ? Number(calcTradeParams.buyAmt)\n          : Number(calcTradeParams.sellAmt)\n        _tradeData.quote.tradeValue = calcTradeParams.isReverse\n          ? Number(calcTradeParams.sellAmt)\n          : Number(calcTradeParams.buyAmt)\n      }\n\n      // myLog('depth:',pageTradePro.depth)\n      const minSymbol =\n        tradeData.type === TradeProType.buy ? tradeData.base.belong : tradeData.quote.belong\n      const minimumReceived = getValuePrecisionThousand(\n        sdk\n          .toBig(calcTradeParams?.amountBOutSlip?.minReceivedVal ?? 0)\n          .minus(totalFee)\n          .toString(),\n        tokenMap[minSymbol].precision,\n        tokenMap[minSymbol].precision,\n        tokenMap[minSymbol].precision,\n        false,\n        { floor: true },\n      )\n      const minimumConverted = calcTradeParams?.amountBOut\n        ? getValuePrecisionThousand(\n            sdk\n              .toBig(calcTradeParams?.amountBOut)\n              .times(sdk.toBig(1).minus(sdk.toBig(slippage).div('10000')))\n              .div('1e' + tokenMap[minSymbol].decimals)\n              .toString(),\n            tokenMap[minSymbol].precision,\n            tokenMap[minSymbol].precision,\n            tokenMap[minSymbol].precision,\n            false,\n            { floor: true },\n          )\n        : undefined\n      const priceImpactObj = getPriceImpactInfo(calcTradeParams, account.readyState)\n      const [sell, buy] =\n        _tradeData.type === TradeProType.sell ? ['base', 'quote'] : ['quote', 'base']\n      let { stob } = reCalcStoB({\n        market,\n        tradeData: {\n          sell: _tradeData[sell],\n          buy: _tradeData[buy],\n          ...(_tradeData as any),\n        },\n        tradePair: `${_tradeData[sell].belong}-${_tradeData[buy].belong}`,\n      }) ?? { stob: undefined }\n\n      const { close } = tickerMap[market]\n\n      if (!stob || sdk.toBig(stob?.replaceAll(sdk.SEP, '') ?? 0).eq(0)) {\n        if (close) {\n          // @ts-ignore\n          // const [, _coinA] = market.match(/(\\w+)-(\\w+)/i);\n          if (_tradeData.type === TradeProType.sell) {\n            stob = close.toString().replaceAll(sdk.SEP, '')\n          } else {\n            stob = getValuePrecisionThousand(\n              1 / Number(close.toString().replaceAll(sdk.SEP, '')),\n              tokenMap[quoteSymbol].precision,\n              tokenMap[quoteSymbol].precision,\n              tokenMap[quoteSymbol].precision,\n              true,\n            )\n          }\n        }\n      }\n      let isNotMatchMarketPrice, marketPrice, marketRatePrice\n      if (tokenPrices && stob) {\n        marketPrice = sdk\n          .toBig(tokenPrices[_tradeData[sell].belong])\n          .div(tokenPrices[_tradeData[buy].belong])\n        marketRatePrice = marketPrice.div(stob?.replaceAll(sdk.SEP, '') ?? 1)\n        isNotMatchMarketPrice = marketRatePrice.gt(1.05)\n        marketPrice = getValuePrecisionThousand(\n          marketPrice.toString(),\n          tokenMap[_tradeData[buy].belong].precision,\n          tokenMap[_tradeData[buy].belong].precision,\n          tokenMap[_tradeData[buy].belong].precision,\n        )\n        marketRatePrice = marketRatePrice.minus(1).times(100).toFixed(2)\n      }\n\n      updatePageTradePro({\n        market,\n        sellUserOrderInfo,\n        buyUserOrderInfo,\n        minOrderInfo: minOrderInfo as any,\n        request: marketRequest as any,\n        calcTradeParams: calcTradeParams,\n        tradeCalcProData: {\n          ...pageTradePro.tradeCalcProData,\n          fee: totalFee,\n          minimumReceived: !minimumReceived?.toString().startsWith('-')\n            ? minimumReceived\n            : undefined,\n          minimumConverted: minimumConverted,\n          priceImpact: priceImpactObj ? priceImpactObj.value : undefined,\n          priceImpactColor: priceImpactObj?.priceImpactColor,\n          isNotMatchMarketPrice,\n          marketPrice,\n          marketRatePrice,\n          StoB: stob,\n          isChecked: tradeData.isChecked !== undefined ? tradeData.isChecked : undefined,\n          lastStepAt,\n        },\n        lastStepAt,\n        totalFee,\n        maxFeeBips,\n        feeTakerRate,\n        tradeCost,\n      })\n\n      setMarketTradeData((state) => {\n        return {\n          ...state,\n          // ...tradeData,\n          ..._tradeData,\n          base: {\n            ...state.base,\n            tradeValue: _tradeData.base?.tradeValue\n              ? Number(_tradeData.base?.tradeValue?.toFixed(tokenMap[state.base.belong].precision))\n              : undefined,\n          },\n          quote: {\n            ...state.quote,\n            tradeValue: _tradeData.quote.tradeValue\n              ? Number(_tradeData.quote.tradeValue.toFixed(tokenMap[state.quote.belong].precision))\n              : undefined,\n          },\n        }\n      })\n    },\n    [autoReCalc, account.readyState, tickerMap],\n  )\n\n  const resetTradeData = React.useCallback(\n    (type?: TradeProType) => {\n      const pageTradePro = store.getState()._router_pageTradePro.pageTradePro\n      const walletMap = pageTradePro.tradeCalcProData?.walletMap ?? {}\n      setMarketTradeData((state) => {\n        return {\n          ...state,\n          type: type ?? pageTradePro.tradeType,\n          base: {\n            ...state.base,\n            // belong: baseSymbol,\n            balance: walletMap ? walletMap[baseSymbol as string]?.count : 0,\n            tradeValue: undefined,\n          } as IBData<any>,\n          isChecked: undefined,\n          quote: {\n            ...state.quote,\n            balance: walletMap ? walletMap[quoteSymbol as string]?.count : 0,\n            tradeValue: undefined,\n          } as IBData<any>,\n        }\n      })\n      updatePageTradePro({\n        market,\n        tradeType: type ?? pageTradePro.tradeType,\n        sellUserOrderInfo: null,\n        buyUserOrderInfo: null,\n        minOrderInfo: null,\n        request: null,\n        calcTradeParams: null,\n        limitCalcTradeParams: null,\n        lastStepAt: undefined,\n        tradeCalcProData: {\n          ...pageTradePro.tradeCalcProData,\n          // walletMap:walletMap as any,\n          priceImpact: undefined,\n          priceImpactColor: undefined,\n          minimumReceived: undefined,\n          fee: undefined,\n          isNotMatchMarketPrice: undefined,\n          marketPrice: undefined,\n          marketRatePrice: undefined,\n          StoB: undefined,\n        },\n        totalFee: undefined,\n        maxFeeBips: undefined,\n        feeTakerRate: undefined,\n        tradeCost: undefined,\n      })\n    },\n    [baseSymbol, quoteSymbol],\n  )\n  const marketSubmit = React.useCallback(async () => {\n    // const {calcTradeParams, request, tradeCalcProData,} = pageTradePro;\n    const pageTradePro = store.getState()._router_pageTradePro.pageTradePro\n    const { calcTradeParams, request } = pageTradePro\n    // setAlertOpen(false);\n    // setConfirmOpen(false);\n    if (\n      !LoopringAPI.userAPI ||\n      !tokenMap ||\n      !exchangeInfo ||\n      !calcTradeParams ||\n      !request ||\n      account.readyState !== AccountStatus.ACTIVATED\n    ) {\n      setToastOpen({\n        open: true,\n        type: ToastType.error,\n        content: t('labelSwapFailed'),\n      })\n      setIsMarketLoading(false)\n\n      return\n    }\n\n    try {\n      const req: sdk.GetNextStorageIdRequest = {\n        accountId: account.accountId,\n        sellTokenId: request.sellToken.tokenId as number,\n      }\n\n      const storageId = await LoopringAPI.userAPI.getNextStorageId(req, account.apiKey)\n\n      const requestClone = _.cloneDeep(request)\n\n      requestClone.storageId = storageId.orderId\n\n      myLog(requestClone)\n\n      const response: { hash: string } | any = await LoopringAPI.userAPI.submitOrder(\n        requestClone,\n        account.eddsaKey.sk,\n        account.apiKey,\n      )\n\n      myLog(response)\n\n      if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n        if ((response as sdk.RESULT_INFO).code === 114002) {\n          getAmount({ market })\n          resetTradeData(pageTradePro.tradeType)\n        }\n        setToastOpen({\n          open: true,\n          type: ToastType.error,\n          content: t('labelSwapFailed') + ' : ' + response.message,\n        })\n      } else {\n        await sdk.sleep(__TOAST_AUTO_CLOSE_TIMER__)\n\n        const resp = await LoopringAPI.userAPI.getOrderDetails(\n          {\n            accountId: account.accountId,\n            orderHash: response.hash,\n          },\n          account.apiKey,\n        )\n\n        myLog('-----> resp:', resp)\n\n        if (resp.orderDetail?.status !== undefined) {\n          myLog('resp.orderDetail:', resp.orderDetail)\n          switch (resp.orderDetail?.status) {\n            case sdk.OrderStatus.cancelled:\n              const baseAmount = sdk.toBig(resp.orderDetail.volumes.baseAmount)\n              const baseFilled = sdk.toBig(resp.orderDetail.volumes.baseFilled)\n              const quoteAmount = sdk.toBig(resp.orderDetail.volumes.quoteAmount)\n              const quoteFilled = sdk.toBig(resp.orderDetail.volumes.quoteFilled)\n              const percentage1 = baseAmount.eq(BIGO) ? 0 : baseFilled.div(baseAmount).toNumber()\n              const percentage2 = quoteAmount.eq(BIGO) ? 0 : quoteFilled.div(quoteAmount).toNumber()\n              myLog('percentage1:', percentage1, ' percentage2:', percentage2)\n              if (percentage1 === 0 || percentage2 === 0) {\n                setToastOpen({\n                  open: true,\n                  type: ToastType.warning,\n                  content: t('labelSwapCancelled'),\n                })\n              } else {\n                setToastOpen({\n                  open: true,\n                  type: ToastType.success,\n                  content: t('labelSwapSuccess'),\n                })\n              }\n              break\n            case sdk.OrderStatus.processed:\n              setToastOpen({\n                open: true,\n                type: ToastType.success,\n                content: t('labelSwapSuccess'),\n              })\n              break\n            case sdk.OrderStatus.processing:\n              setToastOpen({\n                open: true,\n                type: ToastType.success,\n                content: t('labelOrderProcessing'),\n              })\n              break\n            default:\n              setToastOpen({\n                open: true,\n                type: ToastType.error,\n                content: t('labelSwapFailed'),\n              })\n              break\n          }\n        }\n        resetTradeData(pageTradePro.tradeType)\n        walletLayer2Service.sendUserUpdate()\n      }\n    } catch (reason: any) {\n      sdk.dumpError400(reason)\n      setToastOpen({\n        open: true,\n        type: ToastType.error,\n        content: t('labelSwapFailed'),\n      })\n    }\n\n    // setOutput(undefined)\n    await sdk.sleep(__SUBMIT_LOCK_TIMER__)\n    setIsMarketLoading(false)\n  }, [\n    account.readyState,\n    tokenMap,\n    marketTradeData,\n    setIsMarketLoading,\n    setToastOpen,\n    setMarketTradeData,\n  ])\n\n  const availableTradeCheck = React.useCallback((): {\n    tradeBtnStatus: TradeBtnStatus\n    label: string\n  } => {\n    const account = store.getState().account\n    const pageTradePro = store.getState()._router_pageTradePro.pageTradePro\n    const { minOrderInfo } = pageTradePro\n\n    if (account.readyState === AccountStatus.ACTIVATED) {\n      if (\n        marketTradeData?.base.tradeValue === undefined ||\n        marketTradeData?.quote.tradeValue === undefined ||\n        marketTradeData?.base.tradeValue === 0 ||\n        marketTradeData?.quote.tradeValue === 0\n      ) {\n        return {\n          tradeBtnStatus: TradeBtnStatus.DISABLED,\n          label: 'labelEnterAmount',\n        }\n      } else if (!minOrderInfo?.minAmtCheck) {\n        let minOrderSize = 'Error'\n        if (minOrderInfo && minOrderInfo?.symbol) {\n          const symbol = minOrderInfo.symbol\n          const minToken = tokenMap[symbol]\n          const showValue = getValuePrecisionThousand(\n            minOrderInfo?.minAmtShow,\n            minToken.precision,\n            minToken.precision,\n            minToken.precision,\n            false,\n            { isAbbreviate: true, floor: false },\n          )\n          minOrderSize = `${showValue} ${minOrderInfo?.symbol}`\n          return {\n            tradeBtnStatus: TradeBtnStatus.DISABLED,\n            label: `labelLimitMin| ${minOrderSize}`,\n          }\n        } else {\n          return {\n            tradeBtnStatus: TradeBtnStatus.DISABLED,\n            label: ``,\n          }\n        }\n      } else if (\n        sdk\n          .toBig(\n            marketTradeData[marketTradeData.type === TradeProType.buy ? 'quote' : 'base']\n              ?.tradeValue ?? '',\n          )\n          .gt(marketTradeData[marketTradeData.type === TradeProType.buy ? 'quote' : 'base'].balance)\n      ) {\n        return { tradeBtnStatus: TradeBtnStatus.DISABLED, label: '' }\n      } else {\n        return {\n          label: '',\n          tradeBtnStatus: TradeBtnStatus.AVAILABLE,\n        }\n        // if (\n        //   pageTradePro?.tradeCalcProData?.isNotMatchMarketPrice &&\n        //   !pageTradePro?.tradeCalcProData?.isChecked\n        // ) {\n        //   return {\n        //     label: '',\n        //     tradeBtnStatus: TradeBtnStatus.DISABLED,\n        //   }\n        // } else {\n        //\n        // }\n      }\n    }\n\n    return { tradeBtnStatus: TradeBtnStatus.AVAILABLE, label: '' }\n  }, [marketTradeData, marketSubmit])\n  // const [smallOrderAlertOpen, setSmallOrderAlertOpen] = React.useState<boolean>(false)\n  // const [secondConfirmationOpen, setSecondConfirmationOpen] = React.useState<boolean>(false)\n  const isSmallOrder =\n    marketTradeData && marketTradeData.quote.tradeValue\n      ? tokenPrices[marketTradeData.quote.belong] * marketTradeData.quote.tradeValue < 100\n      : false\n  // const priceAlertCallBack = React.useCallback(\n  //   (confirm: boolean) => {\n  //     if (confirm) {\n  //       if (isSmallOrder) {\n  //         setSmallOrderAlertOpen(true)\n  //       } else {\n  //         setIsMarketLoading(true)\n  //         marketSubmit()\n  //       }\n  //       setAlertOpen(false)\n  //       setConfirmOpen(false)\n  //     } else {\n  //       setAlertOpen(false)\n  //       setConfirmOpen(false)\n  //       setIsMarketLoading(false)\n  //     }\n  //   },\n  //   [isSmallOrder],\n  // )\n  // const smallOrderAlertCallBack = React.useCallback(\n  //   (confirm: boolean) => {\n  //     if (confirm) {\n  //       setIsMarketLoading(true)\n  //       marketSubmit()\n  //       setSmallOrderAlertOpen(false)\n  //     } else {\n  //       setSmallOrderAlertOpen(false)\n  //       setIsMarketLoading(false)\n  //     }\n  //   },\n  //   [marketSubmit],\n  // )\n  // const secondConfirmationCallBack = React.useCallback(\n  //   (confirm: boolean) => {\n  //     if (confirm) {\n  //       setIsMarketLoading(true)\n  //       marketSubmit()\n  //       setSecondConfirmationOpen(false)\n  //     } else {\n  //       setSecondConfirmationOpen(false)\n  //       setIsMarketLoading(false)\n  //     }\n  //   },\n  //   [marketSubmit],\n  // )\n  const { showAlert, confirmed, setShowWhich, setConfirmed } = useAlert()\n  const doShowAlert = () => {\n    const pageTradePro = store.getState()._router_pageTradePro.pageTradePro\n    const { priceLevel } = getPriceImpactInfo(pageTradePro.calcTradeParams, account.readyState)\n    myLog('hookSwap:---- swapCalculatorCallback priceLevel:', priceLevel)\n    setConfirmed((state) => {\n      if (isSmallOrder) {\n        state[1] = false\n      } else {\n        state[1] = true\n      }\n      setShowWhich(() => {\n        if (pageTradePro?.tradeCalcProData?.isNotMatchMarketPrice) {\n          return { isShow: true, step: 1, showWitch: ShowWitchAle3t1.AlertImpact }\n        } else if (priceLevel === PriceLevel.Lv1 || priceLevel === PriceLevel.Lv2) {\n          return { isShow: true, step: 1, showWitch: ShowWitchAle3t1.ConfirmImpact }\n        } else if (isSmallOrder) {\n          state[0] = true\n          return { isShow: true, step: 2, showWitch: ShowWitchAle3t1.SmallPrice }\n        }\n        // else if (showSwapSecondConfirmation) {\n        //   return { isShow: true, step: 1, showWitch: ShowWitchAle3t1.SwapSecondConfirmation }\n        // }\n        else {\n          state[0] = true\n          return { isShow: false, step: 2, showWitch: '' }\n        }\n      })\n      return state\n    })\n  }\n  React.useEffect(() => {\n    if (confirmed[0] === true && confirmed[1] === true) {\n      marketSubmit()\n      setConfirmed([false, false])\n    }\n  }, [confirmed[0], confirmed[1]])\n\n  const onSubmitBtnClick = React.useCallback(async () => {\n    setIsMarketLoading(true)\n    const pageTradePro = store.getState()._router_pageTradePro.pageTradePro\n    // const isIpValid = true\n    if (!allowTrade.order.enable) {\n      setShowSupport({ isShow: true })\n      setIsMarketLoading(false)\n    } else if (!order.enable) {\n      setShowTradeIsFrozen({ isShow: true, type: 'Market' })\n      setIsMarketLoading(false)\n    } else {\n      doShowAlert()\n    }\n    // else if (priceLevel === PriceLevel.Lv1) {\n    //   setAlertOpen(true)\n    // } else if (priceLevel === PriceLevel.Lv2) {\n    //   setConfirmOpen(true)\n    // } else if (isSmallOrder) {\n    //   setSmallOrderAlertOpen(true)\n    // } else {\n    //   marketSubmit()\n    // }\n  }, [allowTrade, account.readyState, isSmallOrder])\n\n  const {\n    btnStatus: tradeMarketBtnStatus,\n    onBtnClick: marketBtnClick,\n    btnLabel: tradeMarketI18nKey,\n    btnStyle: tradeMarketBtnStyle,\n    // btnClickCallbackArray\n  } = useSubmitBtn({\n    availableTradeCheck: availableTradeCheck,\n    isLoading: isMarketLoading,\n    submitCallback: onSubmitBtnClick,\n  })\n  return {\n    toastOpen,\n    closeToast,\n    marketTradeData,\n    onChangeMarketEvent,\n    tradeMarketI18nKey,\n    tradeMarketBtnStatus,\n    tradeMarketBtnStyle: {\n      ...tradeMarketBtnStyle,\n      ...{ fontSize: isMobile ? '1.4rem' : '1.6rem' },\n    },\n    resetMarketData: resetTradeData,\n    marketBtnClick,\n    isMarketLoading,\n    marketSubmit,\n    // smallOrderAlertCallBack,\n    // secondConfirmationCallBack,\n    // smallOrderAlertOpen,\n    // secondConfirmationOpen,\n    setToastOpen,\n    // priceAlertCallBack,\n    showAlert,\n    handleClose: () => {\n      setShowWhich((state) => ({ ...state, isShow: false }))\n      setConfirmed([false, false])\n      setIsMarketLoading(false)\n    },\n    handleConfirm: () => {\n      if (showAlert.step == 1 && confirmed[1] == false) {\n        setShowWhich(() => ({ step: 2, showWitch: ShowWitchAle3t1.SmallPrice, isShow: true }))\n      } else {\n        setShowWhich((state) => ({ ...state, isShow: false }))\n      }\n      setConfirmed((state) => {\n        state[showAlert.step - 1] = true\n        return state\n      })\n    },\n    priceLevel: getPriceImpactInfo(pageTradePro.calcTradeParams, account.readyState),\n    // marketTicker,\n  }\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/ProTradePage/panel/spot/hookStopLimit.ts",
    "content": "import React from 'react'\nimport {\n  BIGO,\n  getPriceImpactInfo,\n  LoopringAPI,\n  PriceLevel,\n  store,\n  useAccount,\n  usePageTradePro,\n  usePlaceOrder,\n  useSubmitBtn,\n  useSystem,\n  useTicker,\n  useToast,\n  useTokenMap,\n  useTokenPrices,\n  walletLayer2Service,\n} from '@loopring-web/core'\nimport {\n  AccountStatus,\n  getValuePrecisionThousand,\n  IBData,\n  MarketType,\n  myLog,\n  TradeBtnStatus,\n  TradeBaseType,\n  TradeProType,\n} from '@loopring-web/common-resources'\nimport {\n  StopLimitTradeData,\n  ToastType,\n  useOpenModals,\n  useSettings,\n  useToggle,\n} from '@loopring-web/component-lib'\nimport { useTranslation } from 'react-i18next'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport * as _ from 'lodash'\nimport BigNumber from 'bignumber.js'\n\nexport const useStopLimit = <\n  C extends { [key: string]: any },\n  T extends StopLimitTradeData<I>,\n  I extends IBData<any>,\n>({\n  market,\n  setConfirmed,\n}: { market: MarketType } & any) => {\n  const { pageTradePro, updatePageTradePro, __SUBMIT_LOCK_TIMER__ } = usePageTradePro()\n  const { marketMap, tokenMap } = useTokenMap()\n  const { tokenPrices } = useTokenPrices()\n  const { forexMap, allowTrade } = useSystem()\n  const { account } = useAccount()\n  const { setShowSupport, setShowTradeIsFrozen } = useOpenModals()\n  const { tickerMap } = useTicker()\n  const {\n    toggle: { StopLimit },\n  } = useToggle()\n  const { currency, isMobile } = useSettings()\n\n  const { t } = useTranslation('common')\n\n  const [alertOpen, setAlertOpen] = React.useState<boolean>(false)\n\n  // @ts-ignore\n  const [, baseSymbol, quoteSymbol] = market.match(/(\\w+)-(\\w+)/i)\n  const walletMap = pageTradePro.tradeCalcProData.walletMap ?? {}\n  const marketPrecision = marketMap[market].precisionForPrice\n  const tradePrice =\n    pageTradePro.market === market && pageTradePro.ticker\n      ? pageTradePro.ticker.close\n        ? pageTradePro.ticker.close.toFixed(marketPrecision)\n        : pageTradePro?.depth?.mid_price.toFixed(marketPrecision)\n      : 0\n  let balance =\n    tradePrice &&\n    tokenPrices &&\n    forexMap &&\n    Number(tradePrice) * tokenPrices[quoteSymbol as string] * (forexMap[currency] ?? 0)\n\n  const [stopLimitTradeData, setStopLimitTradeData] = React.useState<T>({\n    base: {\n      belong: baseSymbol,\n      balance: walletMap ? walletMap[baseSymbol as string]?.count : 0,\n    } as I,\n    quote: {\n      belong: quoteSymbol,\n      balance: walletMap ? walletMap[quoteSymbol as string]?.count : 0,\n    } as I,\n    price: {\n      belong: pageTradePro.tradeCalcProData.coinQuote,\n      tradeValue: undefined,\n      balance,\n    } as I,\n    stopPrice: {\n      belong: pageTradePro.tradeCalcProData.coinQuote,\n      tradeValue: undefined,\n      balance,\n    } as I,\n    type: pageTradePro.tradeType ?? TradeProType.buy,\n  } as T)\n  const [isLimitLoading, setIsLimitLoading] = React.useState(false)\n\n  const { toastOpen, setToastOpen, closeToast } = useToast()\n\n  React.useEffect(() => {\n    resetTradeData()\n  }, [pageTradePro.tradeCalcProData.walletMap, pageTradePro.market, currency])\n  React.useEffect(() => {\n    const pageTradePro = store.getState()._router_pageTradePro.pageTradePro\n    if (pageTradePro?.depth?.symbol === pageTradePro.market && pageTradePro?.ticker?.close) {\n      const midStopPrice = pageTradePro.ticker.close\n      const [, , _quoteSymbol] = market.match(/(\\w+)-(\\w+)/i)\n      const quoteTokenInfo = tokenMap[_quoteSymbol]\n\n      updatePageTradePro({\n        ...pageTradePro,\n        tradeCalcProData: {\n          ...pageTradePro.tradeCalcProData,\n          stopRange: [\n            getValuePrecisionThousand(\n              sdk.toBig(midStopPrice).div(10).toString(),\n              quoteTokenInfo.precision,\n              quoteTokenInfo.precision,\n              undefined,\n              false,\n            ),\n            getValuePrecisionThousand(\n              sdk.toBig(midStopPrice).times(10).toString(),\n              quoteTokenInfo.precision,\n              quoteTokenInfo.precision,\n              undefined,\n              false,\n            ),\n          ],\n        },\n      })\n    } else {\n      setToastOpen({\n        open: true,\n        type: ToastType.error,\n        content: t('labelLimitMarket'),\n      })\n    }\n  }, [pageTradePro?.ticker?.close])\n\n  const resetTradeData = React.useCallback(\n    (type?: TradeProType) => {\n      const pageTradePro = store.getState()._router_pageTradePro.pageTradePro\n      const walletMap = pageTradePro.tradeCalcProData.walletMap ?? {}\n      // @ts-ignore\n      const [, baseSymbol, quoteSymbol] = market.match(/(\\w+)-(\\w+)/i)\n      setStopLimitTradeData((state) => {\n        return {\n          ...state,\n          type: type ?? pageTradePro.tradeType,\n          base: {\n            belong: baseSymbol,\n            balance: walletMap ? walletMap[baseSymbol as string]?.count : 0,\n          } as IBData<any>,\n          quote: {\n            belong: quoteSymbol,\n            balance: walletMap ? walletMap[quoteSymbol as string]?.count : 0,\n          } as IBData<any>,\n          price: {\n            belong: quoteSymbol,\n            tradeValue: undefined,\n            balance: 0,\n          } as IBData<any>,\n          stopPrice: {\n            belong: quoteSymbol,\n            tradeValue: undefined,\n            balance: 0,\n          } as IBData<any>,\n        }\n      })\n      updatePageTradePro({\n        market,\n        tradeType: type ?? pageTradePro.tradeType,\n        minOrderInfo: null,\n        sellUserOrderInfo: null,\n        buyUserOrderInfo: null,\n        request: null,\n        calcTradeParams: null,\n        stopLimitCalcTradeParams: null,\n        chooseDepth: null,\n        tradeCalcProData: {\n          ...pageTradePro.tradeCalcProData,\n          // walletMap:walletMap as any,\n          fee: undefined,\n          minimumReceived: undefined,\n          priceImpact: undefined,\n          priceImpactColor: 'inherit',\n        },\n      })\n    },\n    [market, marketPrecision, tokenPrices, forexMap, currency],\n  )\n\n  const limitSubmit = React.useCallback(\n    async (event: MouseEvent, isAgree?: boolean) => {\n      myLog('limitSubmit:', event, isAgree)\n\n      const pageTradePro = store.getState()._router_pageTradePro.pageTradePro\n      const { limitCalcTradeParams, request, tradeCalcProData } = pageTradePro\n\n      setAlertOpen(false)\n\n      if (isAgree && LoopringAPI.userAPI && request) {\n        try {\n          myLog('try to submit order', limitCalcTradeParams, tradeCalcProData)\n\n          const account = store.getState().account\n\n          const req: sdk.GetNextStorageIdRequest = {\n            accountId: account.accountId,\n            sellTokenId: request.sellToken.tokenId as number,\n          }\n\n          const storageId = await LoopringAPI.userAPI.getNextStorageId(req, account.apiKey)\n\n          const requestClone = _.cloneDeep(request)\n          requestClone.storageId = storageId.orderId\n\n          myLog(requestClone)\n\n          const response: { hash: string } | any = await LoopringAPI.userAPI.submitStopOrder(\n            requestClone as any,\n            account.eddsaKey.sk,\n            account.apiKey,\n          )\n\n          myLog(response)\n          if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n            setToastOpen({\n              open: true,\n              type: ToastType.error,\n              content: t('labelLimitFailed') + ' : ' + response.message,\n            })\n          } else {\n            await sdk.sleep(__SUBMIT_LOCK_TIMER__)\n\n            const resp = await LoopringAPI.userAPI.getOrderDetails(\n              {\n                accountId: account.accountId,\n                orderHash: response?.hash,\n              },\n              account.apiKey,\n            )\n\n            myLog('-----> resp:', resp)\n\n            if (resp.orderDetail?.status !== undefined) {\n              myLog('resp.orderDetail:', resp.orderDetail)\n              switch (resp.orderDetail?.status) {\n                case sdk.OrderStatus.cancelled:\n                  const baseAmount = sdk.toBig(resp.orderDetail.volumes.baseAmount)\n                  const baseFilled = sdk.toBig(resp.orderDetail.volumes.baseFilled)\n                  const quoteAmount = sdk.toBig(resp.orderDetail.volumes.quoteAmount)\n                  const quoteFilled = sdk.toBig(resp.orderDetail.volumes.quoteFilled)\n                  const percentage1 = baseAmount.eq(BIGO)\n                    ? 0\n                    : baseFilled.div(baseAmount).toNumber()\n                  const percentage2 = quoteAmount.eq(BIGO)\n                    ? 0\n                    : quoteFilled.div(quoteAmount).toNumber()\n                  myLog('percentage1:', percentage1, ' percentage2:', percentage2)\n                  if (percentage1 === 0 || percentage2 === 0) {\n                    setToastOpen({\n                      open: true,\n                      type: ToastType.warning,\n                      content: t('labelSwapCancelled'),\n                    })\n                  } else {\n                    setToastOpen({\n                      open: true,\n                      type: ToastType.success,\n                      content: t('labelSwapSuccess'),\n                    })\n                  }\n                  break\n                case sdk.OrderStatus.processed:\n                  setToastOpen({\n                    open: true,\n                    type: ToastType.success,\n                    content: t('labelSwapSuccess'),\n                  })\n                  break\n                case sdk.OrderStatus.processing:\n                  setToastOpen({\n                    open: true,\n                    type: ToastType.success,\n                    content: t('labelOrderProcessing'),\n                  })\n                  break\n                default:\n                  setToastOpen({\n                    open: true,\n                    type: ToastType.error,\n                    content: t('labelLimitFailed'),\n                  })\n              }\n            }\n            resetTradeData(pageTradePro.tradeType)\n            walletLayer2Service.sendUserUpdate()\n          }\n\n          setIsLimitLoading(false)\n        } catch (reason: any) {\n          sdk.dumpError400(reason)\n          setToastOpen({\n            open: true,\n            type: ToastType.error,\n            content: t('labelLimitFailed'),\n          })\n        }\n        setIsLimitLoading(false)\n      } else {\n        setIsLimitLoading(false)\n      }\n    },\n    [__SUBMIT_LOCK_TIMER__, resetTradeData, setToastOpen, t],\n  )\n\n  const { makeStopLimitReqInHook } = usePlaceOrder()\n  const onChangeLimitEvent = React.useCallback(\n    (tradeData: T, formType: TradeBaseType) => {\n      const pageTradePro = store.getState()._router_pageTradePro.pageTradePro\n      let dustCalcTradeParams: any\n      if (formType === TradeBaseType.tab) {\n        resetTradeData(tradeData.type)\n      } else {\n        let amountBase = formType === TradeBaseType.base ? tradeData.base.tradeValue : undefined\n        let amountQuote = formType === TradeBaseType.quote ? tradeData.quote.tradeValue : undefined\n\n        if (formType === TradeBaseType.price || formType === TradeBaseType.stopPrice) {\n          amountBase =\n            tradeData.base.tradeValue !== undefined ? tradeData.base.tradeValue : undefined\n          amountQuote =\n            amountBase !== undefined\n              ? undefined\n              : tradeData.quote.tradeValue !== undefined\n              ? tradeData.quote.tradeValue\n              : undefined\n        }\n        if (tradeData.price?.tradeValue) {\n          dustCalcTradeParams = makeStopLimitReqInHook({\n            isBuy: tradeData.type === 'buy',\n            base: tradeData.base.belong,\n            quote: tradeData.quote.belong,\n            price: tradeData.price.tradeValue as number,\n            depth: pageTradePro.depthForCalc,\n            // @ts-ignore\n            amountBase:\n              tradeData.type === 'buy'\n                ? undefined\n                : sdk\n                    .toBig(tokenMap[baseSymbol]?.orderAmounts.dust)\n                    .div('1e' + tokenMap[tradeData.base.belong]?.decimals)\n                    .toString(),\n            // @ts-ignore\n            amountQuote:\n              tradeData.type === 'buy'\n                ? sdk\n                    .toBig(tokenMap[quoteSymbol]?.orderAmounts.dust)\n                    .div('1e' + tokenMap[tradeData.quote.belong]?.decimals)\n                    .toString()\n                : undefined,\n          }).calcTradeParams\n        }\n\n        const {\n          stopLimitRequest,\n          calcTradeParams,\n          sellUserOrderInfo,\n          buyUserOrderInfo,\n          minOrderInfo,\n        } = makeStopLimitReqInHook({\n          isBuy: tradeData.type === 'buy',\n          base: tradeData.base.belong,\n          quote: tradeData.quote.belong,\n          stopLimitPrice: tradeData.stopPrice.tradeValue as number,\n          price: tradeData.price.tradeValue as number,\n          depth: pageTradePro.depthForCalc,\n          amountBase,\n          amountQuote,\n        })\n\n        const minAmount = BigNumber.max(\n          minOrderInfo?.minAmount ?? 0,\n          dustCalcTradeParams?.baseVol ?? 0,\n        ).toString()\n        const minAmtShow = sdk\n          .toBig(minAmount)\n          .div('1e' + tokenMap[minOrderInfo?.symbol ?? baseSymbol].decimals)\n          .toNumber()\n        updatePageTradePro({\n          market,\n          sellUserOrderInfo,\n          buyUserOrderInfo,\n          minOrderInfo: {\n            ...minOrderInfo,\n            minAmount,\n            minAmtShow,\n            minAmtCheck: sdk.toBig(calcTradeParams?.baseVol ?? 0).gte(minAmount),\n          },\n          request: stopLimitRequest as sdk.SubmitOrderRequestV3,\n          stopLimitCalcTradeParams: {\n            ...calcTradeParams,\n            stopPrice: tradeData?.stopPrice?.tradeValue?.toString(),\n          },\n          tradeCalcProData: {\n            ...pageTradePro.tradeCalcProData,\n            fee:\n              calcTradeParams && calcTradeParams.maxFeeBips\n                ? calcTradeParams.maxFeeBips?.toString()\n                : undefined,\n          },\n        })\n        myLog(\n          'stopLimit',\n          calcTradeParams?.baseVolShow as number,\n          calcTradeParams?.quoteVolShow as number,\n        )\n        setStopLimitTradeData((state) => {\n          const tradePrice = tradeData.price.tradeValue\n          let balance =\n            tradePrice &&\n            tokenPrices &&\n            forexMap &&\n            sdk\n              .toBig(tradePrice)\n              .times(tokenPrices[quoteSymbol as string])\n              .times(forexMap[currency] ?? 0)\n              .toFixed(2)\n          const stopPrice = tradeData.stopPrice.tradeValue\n          const stopPriceBalance =\n            stopPrice &&\n            tokenPrices &&\n            forexMap &&\n            sdk\n              .toBig(stopPrice)\n              .times(tokenPrices[quoteSymbol as string])\n              .times(forexMap[currency] ?? 0)\n              .toFixed(2)\n\n          return {\n            ...state,\n            price: {\n              belong: quoteSymbol,\n              tradeValue: tradePrice,\n              balance,\n            } as IBData<any>,\n            stopPrice: {\n              belong: quoteSymbol,\n              tradeValue: stopPrice,\n              balance: stopPriceBalance,\n            } as IBData<any>,\n            base: {\n              ...state.base,\n              tradeValue:\n                calcTradeParams?.baseVolShow == Infinity\n                  ? undefined\n                  : (calcTradeParams?.baseVolShow as number),\n            },\n            quote: {\n              ...state.quote,\n              tradeValue:\n                calcTradeParams?.quoteVolShow == Infinity\n                  ? undefined\n                  : (calcTradeParams?.quoteVolShow as number),\n            },\n          }\n        })\n      }\n    },\n    [resetTradeData, makeStopLimitReqInHook, market, tokenPrices, quoteSymbol, forexMap, currency],\n  )\n  const handlePriceError = React.useCallback(\n    (data: IBData<any>): { error: boolean; message?: string | JSX.Element } | undefined => {\n      const tradeValue = data.tradeValue\n      if (tradeValue) {\n        const [, precision] = tradeValue.toString().split('.')\n        if (precision && precision.length > marketMap[market].precisionForPrice) {\n          return {\n            error: true,\n            message: t('labelErrorPricePrecisionLimit', {\n              symbol: data.belong,\n              decimal: marketMap[market].precisionForPrice,\n            }),\n          }\n        }\n        return undefined\n      } else {\n        return undefined\n      }\n    },\n    [market, marketMap, t],\n  )\n\n  const onSubmitBtnClick = React.useCallback(async () => {\n    setIsLimitLoading(true)\n    const pageTradePro = store.getState()._router_pageTradePro.pageTradePro\n    const { priceLevel } = getPriceImpactInfo(\n      pageTradePro.limitCalcTradeParams,\n      account.readyState,\n      false,\n    )\n    if (!allowTrade?.order?.enable) {\n      setShowSupport({ isShow: true })\n      setIsLimitLoading(false)\n    } else if (!StopLimit.enable) {\n      setShowTradeIsFrozen({ isShow: true, type: 'StopLimit' })\n      setIsLimitLoading(false)\n    } else {\n      switch (priceLevel) {\n        case PriceLevel.Lv1:\n          setAlertOpen(true)\n          break\n        default:\n          setConfirmed(true)\n          break\n      }\n    }\n  }, [\n    account.readyState,\n    allowTrade.order.enable,\n    limitSubmit,\n    StopLimit.enable,\n    setShowSupport,\n    setShowTradeIsFrozen,\n  ])\n  const availableTradeCheck = React.useCallback((): {\n    tradeBtnStatus: TradeBtnStatus\n    label: string\n  } => {\n    const account = store.getState().account\n    const pageTradePro = store.getState()._router_pageTradePro.pageTradePro\n    const {\n      minOrderInfo,\n      tradeCalcProData: { stopRange },\n      market,\n      // calcTradeParams,\n    } = pageTradePro\n    if (account.readyState === AccountStatus.ACTIVATED) {\n      // const type = limitTradeData.type === TradeProType.sell ? 'quote' : 'base';\n      if (\n        stopLimitTradeData?.base.tradeValue === undefined ||\n        stopLimitTradeData?.quote.tradeValue === undefined ||\n        stopLimitTradeData?.base.tradeValue === 0 ||\n        stopLimitTradeData?.quote.tradeValue === 0\n      ) {\n        return {\n          tradeBtnStatus: TradeBtnStatus.DISABLED,\n          label: 'labelEnterAmount',\n        }\n      } else if (!tickerMap[market].close) {\n        return {\n          tradeBtnStatus: TradeBtnStatus.DISABLED,\n          label: 'labelStopLimitCurrentlyInsufficient',\n        }\n      } else if (!minOrderInfo?.minAmtCheck) {\n        let minOrderSize = 'Error'\n        if (minOrderInfo?.symbol) {\n          const basePrecision = tokenMap[minOrderInfo.symbol].precision\n          const showValue = getValuePrecisionThousand(\n            minOrderInfo?.minAmtShow,\n            undefined,\n            undefined,\n            basePrecision,\n            true,\n            { isAbbreviate: true },\n          )\n          minOrderSize = `${showValue} ${minOrderInfo?.symbol}`\n        }\n        return {\n          tradeBtnStatus: TradeBtnStatus.DISABLED,\n          label: `labelLimitMin| ${minOrderSize}`,\n        }\n      } else if (\n        sdk\n          .toBig(\n            stopLimitTradeData[stopLimitTradeData.type === TradeProType.buy ? 'quote' : 'base']\n              ?.tradeValue ?? '',\n          )\n          .gt(\n            stopLimitTradeData[stopLimitTradeData.type === TradeProType.buy ? 'quote' : 'base']\n              .balance,\n          )\n      ) {\n        return { tradeBtnStatus: TradeBtnStatus.DISABLED, label: '' }\n      } else {\n        if (\n          // @ts-ignore\n          sdk.toBig(stopLimitTradeData[TradeBaseType.stopPrice]?.tradeValue ?? 0).lte(0)\n        ) {\n          return { tradeBtnStatus: TradeBtnStatus.DISABLED, label: '' }\n        } else if (\n          stopRange &&\n          stopRange[0] &&\n          stopRange[1] &&\n          (sdk\n            // @ts-ignore\n            .toBig(stopLimitTradeData[TradeBaseType.stopPrice]?.tradeValue ?? 0)\n            .lt(stopRange[0]) ||\n            sdk\n              // @ts-ignore\n              .toBig(stopLimitTradeData[TradeBaseType.stopPrice]?.tradeValue ?? 0)\n              .gt(stopRange[1]))\n        ) {\n          return {\n            tradeBtnStatus: TradeBtnStatus.DISABLED,\n            label: `labelLimitStopPriceMinMax| ${stopRange[0]}-${stopRange[1]}`,\n          }\n        } else {\n          return { tradeBtnStatus: TradeBtnStatus.AVAILABLE, label: '' } // label: ''}\n        }\n      }\n    }\n    return { tradeBtnStatus: TradeBtnStatus.AVAILABLE, label: '' }\n  }, [stopLimitTradeData, tokenMap, tickerMap])\n\n  const {\n    btnStatus: tradeLimitBtnStatus,\n    onBtnClick: limitBtnClick,\n    btnLabel: tradeLimitI18nKey,\n    btnStyle: tradeLimitBtnStyle,\n  } = useSubmitBtn({\n    availableTradeCheck,\n    isLoading: isLimitLoading,\n    submitCallback: onSubmitBtnClick,\n  })\n  return {\n    toastOpen,\n    setToastOpen,\n    closeToast,\n    limitAlertOpen: alertOpen,\n    resetLimitData: resetTradeData,\n    isLimitLoading: false,\n    stopLimitTradeData,\n    onChangeLimitEvent,\n    tradeLimitI18nKey,\n    tradeLimitBtnStatus,\n    confirmStopLimit: {\n      baseSymbol,\n      quoteSymbol,\n      tradeType: pageTradePro.tradeType,\n      limitPrice: getValuePrecisionThousand(\n        stopLimitTradeData?.price?.tradeValue,\n        tokenMap[quoteSymbol]?.precision,\n        tokenMap[quoteSymbol]?.precision,\n        undefined,\n        false,\n      ),\n      stopPrice: getValuePrecisionThousand(\n        stopLimitTradeData?.stopPrice.tradeValue,\n        tokenMap[quoteSymbol]?.precision,\n        tokenMap[quoteSymbol]?.precision,\n        undefined,\n        false,\n      ),\n      baseValue: getValuePrecisionThousand(\n        stopLimitTradeData?.base?.tradeValue,\n        tokenMap[baseSymbol]?.precision,\n        tokenMap[baseSymbol]?.precision,\n        undefined,\n        false,\n      ),\n      quoteValue: getValuePrecisionThousand(\n        stopLimitTradeData?.quote?.tradeValue,\n        tokenMap[quoteSymbol]?.precision,\n        tokenMap[quoteSymbol]?.precision,\n        undefined,\n        false,\n      ),\n      stopSide: pageTradePro.request?.stopSide,\n      handleClose: () => {\n        setIsLimitLoading(false)\n        setConfirmed(false)\n      },\n      onSubmit: (e: any) => {\n        setConfirmed(false)\n        limitSubmit(e as any, true)\n      },\n    },\n    limitSubmit,\n    limitBtnClick,\n    handlePriceError,\n    tradeLimitBtnStyle: {\n      ...tradeLimitBtnStyle,\n      ...{\n        fontSize: isMobile ? (tradeLimitI18nKey !== '' ? '1.2rem' : '1.4rem') : '1.6rem',\n      },\n    },\n  }\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/ProTradePage/panel/spot/index.tsx",
    "content": "import { Trans, WithTranslation, withTranslation } from 'react-i18next'\nimport React from 'react'\nimport {\n  AlertImpact,\n  AlertLimitPriceRisk,\n  ConfirmImpact,\n  LimitTrade,\n  MarketTrade,\n  PopoverPure,\n  SmallOrderAlert,\n  Toast,\n  ToastType,\n} from '@loopring-web/component-lib'\nimport {\n  EmptyValueTag,\n  getValuePrecisionThousand,\n  Info2Icon,\n  MarketType,\n  TOAST_TIME,\n  TradeProType,\n} from '@loopring-web/common-resources'\nimport { PriceLevel, ShowWitchAle3t1, usePageTradePro, useTokenMap } from '@loopring-web/core'\nimport { useMarket } from './hookMarket'\nimport { useLimit } from './hookLimit'\nimport { Box, Divider, Tab, Tabs, Typography } from '@mui/material'\nimport { bindHover } from 'material-ui-popup-state/es'\nimport { bindPopper, usePopupState } from 'material-ui-popup-state/hooks'\n\n// const TabsStyle = styled(Tabs)`\n//   flex: 1;\n//   width: 100%;\n// ` as typeof Tabs\nexport enum TabIndex {\n  market = 'market',\n  limit = 'limit',\n}\n\nexport const SpotView = withTranslation('common')(\n  ({\n    t,\n    market,\n    resetTradeCalcData,\n  }: // ,marketTicker\n  {\n    market: MarketType\n    resetTradeCalcData: (props: { tradeData?: any; market: MarketType | string }) => void\n    // marketTicker:  MarketBlockProps<C>\n  } & WithTranslation) => {\n    const { pageTradePro } = usePageTradePro()\n    const [tabIndex, setTabIndex] = React.useState<TabIndex>(TabIndex.limit)\n    const { marketMap, tokenMap } = useTokenMap()\n    //@ts-ignore\n    const [, baseSymbol, quoteSymbol] = market.match(/(\\w+)-(\\w+)/i)\n    const {\n      toastOpen: toastOpenL,\n      closeToast: closeToastL,\n      limitTradeData,\n      onChangeLimitEvent,\n      tradeLimitI18nKey,\n      tradeLimitBtnStatus,\n      tradeLimitBtnStyle,\n      limitBtnClick,\n      isLimitLoading,\n      handlePriceError,\n      resetLimitData,\n      // limitAlertOpen,\n      limitSubmit,\n      showAlert: limitShowAlert,\n      handleConfirm: handleLimitConfirm,\n      handleClose: handleLimitClose,\n      // priceLevel,\n    } = useLimit({ market, resetTradeCalcData })\n\n    const {\n      // alertOpen,\n      // confirmOpen,\n      toastOpen,\n      closeToast,\n      marketTradeData,\n      onChangeMarketEvent,\n      tradeMarketI18nKey,\n      tradeMarketBtnStatus,\n      tradeMarketBtnStyle,\n      resetMarketData,\n      marketBtnClick,\n      isMarketLoading,\n      showAlert,\n      handleConfirm,\n      handleClose,\n      priceLevel,\n      // priceAlertCallBack,\n      // smallOrderAlertCallBack,\n      // smallOrderAlertOpen,\n    } = useMarket({ market, resetTradeCalcData })\n    const onTabChange = React.useCallback(\n      (_e, value) => {\n        setTabIndex(value)\n        //HIGH: Do not move the query\n        resetLimitData()\n        resetMarketData()\n        resetTradeCalcData({ market })\n\n        //HIGH: Do not move the query\n      },\n      [market],\n    )\n\n    const priceImpact = (getValuePrecisionThousand(\n      parseFloat(pageTradePro.calcTradeParams?.priceImpact ?? '0') * 100,\n      2,\n    ) + '%') as any\n    const popupLimitState = usePopupState({\n      variant: 'popover',\n      popupId: `popupId-limit`,\n    })\n    const popupMarketState = usePopupState({\n      variant: 'popover',\n      popupId: `popupId-market`,\n    })\n\n    const limitLabel = React.useMemo(() => {\n      return (\n        <>\n          <Typography display={'inline-flex'} alignItems={'center'}>\n            <Typography component={'span'} marginRight={1}>\n              {t('labelProLimit')}\n            </Typography>\n            <Info2Icon\n              {...bindHover(popupLimitState)}\n              fontSize={'medium'}\n              htmlColor={'var(--color-text-third)'}\n            />\n          </Typography>\n          <PopoverPure\n            className={'arrow-center'}\n            {...bindPopper(popupLimitState)}\n            anchorOrigin={{\n              vertical: 'bottom',\n              horizontal: 'center',\n            }}\n            transformOrigin={{\n              vertical: 'top',\n              horizontal: 'center',\n            }}\n          >\n            <Typography\n              padding={2}\n              component={'p'}\n              variant={'body2'}\n              whiteSpace={'pre-line'}\n              maxWidth={280}\n            >\n              <Trans i18nKey={'depositLimit'}>\n                Limit orders set the maximum or minimum price at which you are willing to buy or\n                sell.\n              </Trans>\n            </Typography>\n          </PopoverPure>\n        </>\n      )\n    }, [popupLimitState])\n    const marketLabel = React.useMemo(() => {\n      return (\n        <>\n          <Typography display={'inline-flex'} alignItems={'center'}>\n            <Typography component={'span'} marginRight={1}>\n              {t('labelProMarket')}\n            </Typography>\n            <Info2Icon\n              {...bindHover(popupMarketState)}\n              fontSize={'medium'}\n              htmlColor={'var(--color-text-third)'}\n            />\n          </Typography>\n          <PopoverPure\n            className={'arrow-center'}\n            {...bindPopper(popupMarketState)}\n            anchorOrigin={{\n              vertical: 'bottom',\n              horizontal: 'center',\n            }}\n            transformOrigin={{\n              vertical: 'top',\n              horizontal: 'center',\n            }}\n          >\n            <Typography\n              padding={2}\n              component={'p'}\n              variant={'body2'}\n              whiteSpace={'pre-line'}\n              maxWidth={280}\n            >\n              <Trans i18nKey={'depositMarket'}>\n                Market orders are transactions meant to execute as quickly as possible at the\n                current market price.\n              </Trans>\n            </Typography>\n          </PopoverPure>\n        </>\n      )\n    }, [popupMarketState])\n\n    const isMarketUnavailable =\n      marketMap && marketMap.market && (marketMap.market.status || 0) % 3 !== 0\n    const marketUnavailableConent =\n      isMarketUnavailable && (marketMap.market.status || 0) % 3 === 2\n        ? 'This pair doesn’t support limit order, please place a market order'\n        : ''\n\n    const tradeType = pageTradePro.tradeType\n    const tradeCalcData = pageTradePro.tradeCalcProData\n    const tradeData = marketTradeData\n    const estimatedFee =\n      tradeCalcData && tradeCalcData.fee\n        ? `${tradeCalcData.fee} ${\n            tradeType === TradeProType.sell ? tradeData.quote?.belong : tradeData.base?.belong\n          }` //(parseFloat(tradeCalcData.fee) / 100).toString() + \"%\"\n        : EmptyValueTag\n    const minimumReceived =\n      tradeCalcData && tradeCalcData.minimumReceived\n        ? `${tradeCalcData.minimumReceived}  ${\n            tradeType === TradeProType.buy ? tradeData.base.belong : tradeData.quote.belong\n          }`\n        : EmptyValueTag\n    const feePercentage =\n      tradeCalcData && tradeData?.quote?.tradeValue\n        ? (\n            (Number(tradeCalcData.fee) /\n              (tradeType === TradeProType.sell\n                ? tradeData.quote.tradeValue\n                : tradeData.base.tradeValue)) *\n            100\n          ).toFixed(2)\n        : EmptyValueTag\n\n    return (\n      <>\n        <Toast\n          alertText={toastOpen?.content ?? ''}\n          severity={toastOpen?.type ?? ToastType.success}\n          open={toastOpen?.open ?? false}\n          autoHideDuration={TOAST_TIME}\n          onClose={closeToast}\n        />\n        <Toast\n          alertText={isMarketUnavailable ? marketUnavailableConent : toastOpenL?.content ?? ''}\n          severity={toastOpenL?.type ?? ToastType.success}\n          open={toastOpenL?.open ?? false}\n          autoHideDuration={TOAST_TIME}\n          onClose={closeToastL}\n        />\n        <AlertImpact\n          open={showAlert.isShow && showAlert.showWitch === ShowWitchAle3t1.AlertImpact}\n          handleClose={handleClose}\n          handleConfirm={handleConfirm}\n          variance={tradeCalcData?.marketRatePrice ?? ''}\n          marketPrice={tradeCalcData?.marketPrice ?? ''}\n          settlementPrice={tradeCalcData?.StoB ?? ''}\n          symbol={`${tradeCalcData?.coinBase}/${tradeCalcData?.coinQuote}`}\n        />\n        <ConfirmImpact\n          open={showAlert.isShow && showAlert.showWitch === ShowWitchAle3t1.ConfirmImpact}\n          handleClose={handleClose}\n          handleConfirm={handleConfirm}\n          priceImpact={getValuePrecisionThousand(pageTradePro?.priceImpactObj?.value, 2)}\n          color={'var(--color-error)'} //priceLevel.priceImpactColor\n          shouldInputAgree={priceLevel.priceLevel === PriceLevel.Lv2}\n        />\n        <SmallOrderAlert\n          open={showAlert.isShow && showAlert.showWitch === ShowWitchAle3t1.SmallPrice}\n          handleClose={handleClose}\n          handleConfirm={handleConfirm}\n          estimatedFee={estimatedFee}\n          feePercentage={feePercentage}\n          minimumReceived={minimumReceived}\n          symbol={`${tradeData?.sell?.belong}/${tradeData?.buy?.belong}`}\n        />\n        <AlertImpact\n          open={limitShowAlert.isShow && limitShowAlert.showWitch === ShowWitchAle3t1.AlertImpact}\n          handleClose={handleLimitClose}\n          handleConfirm={handleLimitConfirm}\n          variance={tradeCalcData?.marketRatePrice ?? ''}\n          marketPrice={tradeCalcData?.marketPrice ?? ''}\n          settlementPrice={limitTradeData.price?.tradeValue?.toString() ?? ''}\n          symbol={`${tradeCalcData?.coinBase}/${tradeCalcData?.coinQuote}`}\n        />\n        <AlertLimitPriceRisk\n          open={limitShowAlert.isShow && limitShowAlert.showWitch === ShowWitchAle3t1.ConfirmImpact}\n          handleClose={handleLimitClose}\n          handleConfirm={handleLimitConfirm}\n          fromSymbol={\n            tradeType === TradeProType.sell\n              ? limitTradeData.base?.belong\n              : limitTradeData.quote?.belong\n          }\n          fromAmount={\n            tradeType === TradeProType.sell\n              ? limitTradeData.base?.tradeValue ?? ''\n              : limitTradeData.quote?.tradeValue ?? ''\n          }\n          toSymbol={\n            tradeType === TradeProType.buy\n              ? limitTradeData.base?.belong\n              : limitTradeData.quote?.belong\n          }\n          toAmount={\n            tradeType === TradeProType.buy\n              ? limitTradeData.base?.tradeValue ?? ''\n              : limitTradeData.quote?.tradeValue ?? ''\n          }\n          price={limitTradeData?.price?.tradeValue ?? ''}\n          priceSymbol={`${tradeCalcData?.coinBase}/${tradeCalcData?.coinQuote}`}\n          value={\n            pageTradePro.tradeType === TradeProType.buy\n              ? 'labelPriceCompareGreat'\n              : 'labelPriceCompareLess'\n          }\n        />\n\n        <Box\n          display={'flex'}\n          flexDirection={'column'}\n          alignItems={'stretch'}\n          height={'inherit'}\n          sx={{ overflowY: 'auto' }}\n          marginBottom={2}\n        >\n          <Box component={'header'} width={'100%'}>\n            <Tabs variant={'fullWidth'} value={tabIndex} onChange={onTabChange}>\n              <Tab value={TabIndex.limit} label={limitLabel} />\n              <Tab value={TabIndex.market} label={marketLabel} />\n            </Tabs>\n          </Box>\n\n          <Divider style={{ marginTop: '-1px' }} />\n          <Box display={'flex'} flex={1} component={'section'}>\n            {tabIndex === TabIndex.limit && (\n              <LimitTrade\n                // disabled={false}\n                tokenPriceProps={{\n                  handleError: handlePriceError as any,\n                  decimalsLimit: marketMap[market]?.precisionForPrice,\n                }}\n                tradeType={pageTradePro.tradeType}\n                tokenBaseProps={{\n                  disabled: isLimitLoading,\n                  decimalsLimit: tokenMap[baseSymbol].precision,\n                }}\n                tokenQuoteProps={{\n                  disabled: isLimitLoading,\n                  decimalsLimit: tokenMap[quoteSymbol].precision,\n                }}\n                tradeLimitI18nKey={tradeLimitI18nKey}\n                tradeLimitBtnStyle={tradeLimitBtnStyle}\n                tradeLimitBtnStatus={tradeLimitBtnStatus as any}\n                handleSubmitEvent={limitBtnClick as any}\n                tradeCalcProData={pageTradePro.tradeCalcProData}\n                tradeData={limitTradeData}\n                onChangeEvent={onChangeLimitEvent as any}\n              />\n            )}\n            {tabIndex === TabIndex.market && (\n              <MarketTrade\n                // disabled={false}\n\n                tokenBaseProps={{\n                  disabled: isMarketLoading,\n                  decimalsLimit: tokenMap[baseSymbol].precision,\n                }}\n                tokenQuoteProps={{\n                  disabled: isMarketLoading,\n                  decimalsLimit: tokenMap[quoteSymbol].precision,\n                }}\n                tradeMarketI18nKey={tradeMarketI18nKey}\n                tradeMarketBtnStyle={tradeMarketBtnStyle}\n                tradeType={tradeType}\n                tradeMarketBtnStatus={tradeMarketBtnStatus}\n                handleSubmitEvent={marketBtnClick}\n                tradeCalcProData={pageTradePro.tradeCalcProData}\n                tradeData={tradeData}\n                onChangeEvent={onChangeMarketEvent}\n              />\n            )}\n          </Box>\n        </Box>\n      </>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/webapp/src/pages/ProTradePage/panel/spot/stopLimit.tsx",
    "content": "import { WithTranslation, withTranslation } from 'react-i18next'\nimport React from 'react'\nimport { ConfirmStopLimitRisk, StopLimitTrade, Toast, ToastType } from '@loopring-web/component-lib'\nimport { MarketType, TOAST_TIME } from '@loopring-web/common-resources'\nimport { usePageTradePro, useTicker, useTokenMap } from '@loopring-web/core'\nimport { Box, Divider, Typography } from '@mui/material'\nimport { useStopLimit } from './hookStopLimit'\n\nexport const StopLimitView = withTranslation('common')(\n  ({\n    t,\n    market,\n    resetTradeCalcData,\n  }: // ,marketTicker\n  {\n    market: MarketType\n    resetTradeCalcData: (props: { tradeData?: any; market: MarketType | string }) => void\n    // marketTicker:  MarketBlockProps<C>\n  } & WithTranslation) => {\n    const { pageTradePro } = usePageTradePro()\n    const { marketMap, tokenMap } = useTokenMap()\n    const [confirmed, setConfirmed] = React.useState<boolean>(false)\n    const { tickerMap } = useTicker()\n\n    //@ts-ignore\n    const [, baseSymbol, quoteSymbol] = market.match(/(\\w+)-(\\w+)/i)\n    const {\n      toastOpen: toastOpenL,\n      closeToast: closeToastL,\n      stopLimitTradeData,\n      onChangeLimitEvent,\n      tradeLimitI18nKey,\n      tradeLimitBtnStatus,\n      tradeLimitBtnStyle,\n      limitBtnClick,\n      isLimitLoading,\n      handlePriceError,\n      confirmStopLimit,\n      limitAlertOpen,\n      limitSubmit,\n    } = useStopLimit({ market, resetTradeCalcData, setConfirmed })\n\n    const isMarketUnavailable =\n      marketMap && marketMap.market && (marketMap.market.status || 0) % 3 !== 0\n    const marketUnavailableConent =\n      isMarketUnavailable && (marketMap.market.status || 0) % 3 === 2\n        ? 'This pair doesn’t support limit order, please place a market order'\n        : ''\n\n    return (\n      <>\n        <Toast\n          alertText={isMarketUnavailable ? marketUnavailableConent : toastOpenL?.content ?? ''}\n          severity={toastOpenL?.type ?? ToastType.success}\n          open={toastOpenL?.open ?? false}\n          autoHideDuration={TOAST_TIME}\n          onClose={closeToastL}\n        />\n        <ConfirmStopLimitRisk\n          open={confirmed}\n          handleClose={(_e) => {\n            confirmStopLimit.handleClose()\n          }}\n          {...{ ...(confirmStopLimit as any) }}\n        />\n        <Box\n          display={'flex'}\n          flexDirection={'column'}\n          alignItems={'stretch'}\n          height={'inherit'}\n          sx={{ overflowY: 'scroll', background: 'var(--color-global-bg)' }}\n          marginBottom={2}\n          flex={1}\n        >\n          <Box component={'header'} width={'100%'}>\n            <Typography variant={'body1'} paddingX={2} lineHeight={'44px'}>\n              {t('labelStopLimitTitle')}\n            </Typography>\n          </Box>\n          <Divider style={{ marginTop: '-1px' }} />\n          <Box display={'flex'} component={'section'} flexDirection={'column'}>\n            {pageTradePro.market && (\n              <StopLimitTrade\n                // @ts-ignore\n                stopPriceProps={{\n                  handleError: handlePriceError as any,\n                  decimalsLimit: marketMap[market]?.precisionForPrice,\n                }}\n                tokenPriceProps={{\n                  handleError: handlePriceError as any,\n                  decimalsLimit: marketMap[market]?.precisionForPrice,\n                }}\n                tradeType={pageTradePro.tradeType}\n                tokenBaseProps={{\n                  disabled: isLimitLoading,\n                  decimalsLimit: tokenMap[baseSymbol].precision,\n                }}\n                tokenQuoteProps={{\n                  disabled: isLimitLoading,\n                  decimalsLimit: tokenMap[quoteSymbol].precision,\n                }}\n                tradeLimitI18nKey={tradeLimitI18nKey}\n                tradeLimitBtnStyle={tradeLimitBtnStyle}\n                tradeLimitBtnStatus={tradeLimitBtnStatus as any}\n                handleSubmitEvent={limitBtnClick as any}\n                tradeCalcProData={pageTradePro.tradeCalcProData}\n                tradeData={stopLimitTradeData}\n                onChangeEvent={onChangeLimitEvent as any}\n              />\n            )}\n            {pageTradePro.market && !tickerMap[pageTradePro.market].close && (\n              <Typography\n                variant={'body1'}\n                paddingX={2}\n                paddingTop={1}\n                color={'var(--color-warning)'}\n              >\n                {t('labelStopLimitNotSupport')}\n              </Typography>\n            )}\n          </Box>\n        </Box>\n      </>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/webapp/src/pages/ProTradePage/panel/toolbar/hook.ts",
    "content": "import React from 'react'\nimport { LoopringAPI } from '@loopring-web/core'\n\nexport const useToolbar = () => {\n  const [ammPoolBalances, setAmmPoolBalances] = React.useState<any[]>([])\n\n  const getAmmPoolBalances = React.useCallback(async () => {\n    if (LoopringAPI.ammpoolAPI) {\n      const response = await LoopringAPI.ammpoolAPI.getAmmPoolBalances<any[]>()\n      const fomattedRes = response.raw_data.map((o) => ({\n        ...o,\n        poolName: o.poolName.replace('AMM-', ''),\n      }))\n      setAmmPoolBalances(fomattedRes)\n    }\n  }, [])\n\n  React.useEffect(() => {\n    getAmmPoolBalances()\n  }, [])\n\n  return {\n    ammPoolBalances,\n  }\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/ProTradePage/panel/toolbar/index.tsx",
    "content": "import React from 'react'\nimport { TFunction, withTranslation } from 'react-i18next'\nimport * as _ from 'lodash'\nimport {\n  CoinInfo,\n  ConfigLayout,\n  CurrencyToTag,\n  DropDownIcon,\n  EmptyValueTag,\n  getValuePrecisionThousand,\n  layoutConfigs as _layoutConfigs,\n  MarketType,\n  PriceTag,\n  SagaStatus,\n  SCENARIO,\n  TableFilterParams,\n} from '@loopring-web/common-resources'\nimport {\n  Button,\n  InputSearch,\n  InputSearchWrapperStyled,\n  MarketBlockProps,\n  PopoverPure,\n  QuoteTable,\n  QuoteTableRawDataItem,\n  TagIconList,\n  useSettings,\n} from '@loopring-web/component-lib'\n\nimport { Box, ClickAwayListener, Divider, Grid, Tab, Tabs, Typography } from '@mui/material'\nimport { bindPopper, usePopupState } from 'material-ui-popup-state/hooks'\nimport { bindTrigger } from 'material-ui-popup-state/es'\n\nimport styled from '@emotion/styled'\nimport { Currency } from '@loopring-web/loopring-sdk'\nimport { Layout, Layouts } from 'react-grid-layout'\nimport {\n  favoriteMarket as favoriteMarketRD,\n  TableProWrapStyled,\n  useAccount,\n  useNotify,\n  useSystem,\n  useTicker,\n  useTokenMap,\n  useTokenPrices,\n  volumeToCount,\n} from '@loopring-web/core'\nimport { useToolbar } from './hook'\nimport { useHistory } from 'react-router-dom'\nimport { useTickList } from '../../../QuotePage/hook'\n\nconst PriceTitleStyled = styled(Typography)`\n  color: var(--color-text-third);\n  font-size: 1.2rem;\n`\n\nconst PriceValueStyled = styled(Typography)`\n  font-size: 1.2rem;\n`\n\nexport const Toolbar = withTranslation('common')(\n  <C extends { [key: string]: any }>({\n    market,\n    handleLayoutChange,\n    handleOnMarketChange,\n    layoutConfigs = _layoutConfigs,\n    // ,marketTicker\n    t,\n  }: {\n    t: TFunction<'translation'>\n    market: MarketType\n    layoutConfigs?: Array<ConfigLayout>\n    handleLayoutChange: (currentLayout: Layout[], allLayouts?: Layouts, layouts?: Layouts) => void\n\n    handleOnMarketChange: (newMarket: MarketType) => void\n  }) => {\n    //@ts-ignore\n    const [, coinA, coinB] = market.match(/(\\w+)-(\\w+)/i)\n    const { coinMap, marketMap, tokenMap } = useTokenMap()\n    const { tickerMap, status: tickerStatus } = useTicker()\n    const { favoriteMarket, removeMarket, addMarket } = favoriteMarketRD.useFavoriteMarket()\n    const { campaignTagConfig } = useNotify().notifyMap ?? {}\n    const { ammPoolBalances } = useToolbar()\n    const { tickList } = useTickList()\n    const { account } = useAccount()\n    const [filteredData, setFilteredData] = React.useState<QuoteTableRawDataItem[]>([])\n    const [searchValue, setSearchValue] = React.useState<string>('')\n    const [tableTabValue, setTableTabValue] = React.useState('all')\n    const [isDropdownOpen, setIsDropdownOpen] = React.useState(false)\n\n    const [marketTicker, setMarketTicker] = React.useState<(MarketBlockProps<C> & any) | undefined>(\n      {\n        coinAInfo: coinMap[coinA] as CoinInfo<C>,\n        coinBInfo: coinMap[coinB] as CoinInfo<C>,\n        tradeFloat: tickerMap[market],\n      },\n    )\n    const { currency } = useSettings()\n    const { forexMap } = useSystem()\n    const { tokenPrices } = useTokenPrices()\n    const getMarketPrecision = React.useCallback(\n      (market: string) => {\n        if (marketMap) {\n          return marketMap[market]?.precisionForPrice\n        }\n        return undefined\n      },\n      [marketMap],\n    )\n\n    const getTokenPrecision = React.useCallback(\n      (token: string) => {\n        if (tokenMap) {\n          return tokenMap[token]?.precision\n        }\n        return undefined\n      },\n      [tokenMap],\n    )\n\n    const setDefaultData = React.useCallback(() => {\n      if (\n        coinMap &&\n        tickerMap &&\n        tokenPrices &&\n        tickerMap[market] &&\n        tickerMap[market].__rawTicker__\n      ) {\n        const ticker = tickerMap[market]\n        const base: string = ticker.__rawTicker__?.base ?? ''\n        const quote: string = ticker.__rawTicker__?.quote ?? ''\n        const baseVol = volumeToCount(base, ticker.__rawTicker__?.base_token_volume || 0)\n\n        const quoteVol = volumeToCount(quote, ticker.__rawTicker__?.quote_token_volume || 0)\n        const isRise = ticker.floatTag === 'increase'\n\n        const basepriceU = ticker.close * (tokenPrices[quote] ?? 0) ?? tokenPrices[base] ?? 0\n        setMarketTicker((state: any) => {\n          return {\n            ...state,\n            tradeFloat: ticker,\n            base,\n            quote,\n            isRise,\n            baseVol,\n            quoteVol,\n            basepriceU,\n          }\n        })\n      }\n    }, [coinMap, tickerMap, tokenPrices, market])\n    React.useEffect(() => {\n      if (tickerStatus === SagaStatus.UNSET && market !== undefined) {\n        setDefaultData()\n      }\n    }, [tickerStatus, market, setDefaultData])\n    const getFilteredTickList = React.useCallback(() => {\n      if (tickList && !!tickList.length) {\n        return tickList.filter((o: any) => {\n          const pair = `${o.pair.coinA}-${o.pair.coinB}`\n          const status = ('00' + marketMap[pair]?.status?.toString(2)).split('')\n          return status[status.length - 2] === '1'\n        })\n      }\n      return []\n    }, [tickList, ammPoolBalances])\n    const { isMobile } = useSettings()\n    const resetTableData = React.useCallback(\n      (tableData) => {\n        setFilteredData(tableData)\n      },\n      [setFilteredData],\n    )\n\n    React.useEffect(() => {\n      const data = getFilteredTickList()\n      resetTableData(data)\n    }, [tickerStatus, tickList])\n\n    const handleTableFilterChange = React.useCallback(\n      ({\n        type = TableFilterParams.all,\n        keyword = '',\n      }: {\n        type?: TableFilterParams\n        keyword?: string\n      }) => {\n        let data = _.cloneDeep(tickList)\n        if (type === TableFilterParams.favourite) {\n          data = data.filter((o: any) => {\n            const pair = `${o.pair.coinA}-${o.pair.coinB}`\n            return favoriteMarket?.includes(pair)\n          })\n        }\n        data = data.filter((o: any) => {\n          const formattedKeyword = keyword?.toLocaleLowerCase()\n          const coinA = o.pair.coinA.toLowerCase()\n          const coinB = o.pair.coinB.toLowerCase()\n          if (keyword === '') {\n            return true\n          }\n          return coinA?.includes(formattedKeyword) || coinB?.includes(formattedKeyword)\n        })\n        if (type === TableFilterParams.all && !keyword) {\n          data = getFilteredTickList()\n        }\n        resetTableData(data)\n      },\n      [tickList, resetTableData, favoriteMarket, getFilteredTickList],\n    )\n\n    const handleTabChange = React.useCallback(\n      (_event: any, newValue: string) => {\n        setTableTabValue(newValue)\n        handleTableFilterChange({\n          type:\n            newValue === 'favourite'\n              ? TableFilterParams.favourite\n              : newValue === 'tradeRanking'\n              ? TableFilterParams.ranking\n              : TableFilterParams.all,\n          keyword: searchValue,\n        })\n      },\n      [handleTableFilterChange, searchValue],\n    )\n\n    const handleSearchChange = React.useCallback((value) => {\n      setSearchValue(value)\n    }, [])\n\n    React.useEffect(() => {\n      const type =\n        tableTabValue === 'favourite'\n          ? TableFilterParams.favourite\n          : tableTabValue === 'tradeRanking'\n          ? TableFilterParams.ranking\n          : TableFilterParams.all\n      handleTableFilterChange({ keyword: searchValue, type: type })\n    }, [searchValue, handleSearchChange, tableTabValue, handleTableFilterChange])\n\n    const popState = usePopupState({\n      variant: 'popover',\n      popupId: `popup-pro-toolbar-markets`,\n    })\n\n    const handleClickAway = React.useCallback(() => {\n      popState.setOpen(false)\n      setIsDropdownOpen(false)\n      setSearchValue('')\n    }, [popState])\n\n    return (\n      <Box\n        display={'flex'}\n        alignItems={'center'}\n        height={'100%'}\n        paddingX={2}\n        justifyContent={'space-between'}\n      >\n        <Box alignItems={'center'} display={'flex'}>\n          <Box\n            display={'flex'}\n            alignItems={'center'}\n            fontSize={'1.6rem'}\n            {...bindTrigger(popState)}\n            onClick={(e: any) => {\n              bindTrigger(popState).onClick(e)\n              setIsDropdownOpen(true)\n              if (tableTabValue === 'favourite') {\n                handleTabChange(_, 'favourite')\n              }\n            }}\n            style={{ cursor: 'pointer', whiteSpace: 'nowrap' }}\n          >\n            {market}\n            <DropDownIcon\n              htmlColor={'var(--color-text-third)'}\n              style={{\n                marginBottom: 2,\n                transform: isDropdownOpen ? 'rotate(0.5turn)' : 'rotate(0)',\n              }}\n            />\n          </Box>\n\n          <PopoverPure\n            className={'arrow-center no-arrow'}\n            {...bindPopper(popState)}\n            anchorOrigin={{\n              vertical: 'bottom',\n              horizontal: 'center',\n            }}\n            transformOrigin={{\n              vertical: 'top',\n              horizontal: 'center',\n            }}\n          >\n            <ClickAwayListener onClickAway={handleClickAway}>\n              <Box>\n                <InputSearchWrapperStyled>\n                  <InputSearch fullWidth value={searchValue} onChange={handleSearchChange} />\n                </InputSearchWrapperStyled>\n                <Box\n                  display={'flex'}\n                  flexDirection={'row'}\n                  justifyContent={'space-between'}\n                  alignItems={'center'}\n                >\n                  <Tabs\n                    value={tableTabValue}\n                    onChange={handleTabChange}\n                    aria-label='Market Switch Tab'\n                  >\n                    <Tab label={t('labelQuotePageFavourite')} value='favourite' />\n                    <Tab label={t('labelAll')} value='all' />\n                  </Tabs>\n                </Box>\n                <Divider style={{ marginTop: '-1px' }} />\n                <TableProWrapStyled width={isMobile ? '360px' : '580px'}>\n                  <QuoteTable\n                    isPro\n                    forexMap={forexMap as any}\n                    campaignTagConfig={campaignTagConfig ?? ({} as any)}\n                    account={account}\n                    rawData={filteredData}\n                    favoriteMarket={favoriteMarket}\n                    addFavoriteMarket={addMarket}\n                    removeFavoriteMarket={removeMarket}\n                    onRowClick={(_: any, row: any) => {\n                      handleOnMarketChange(`${row.pair.coinA}-${row.pair.coinB}` as MarketType)\n                      popState.setOpen(false)\n                      setIsDropdownOpen(false)\n                      setSearchValue('')\n                    }}\n                  />\n                </TableProWrapStyled>\n              </Box>\n            </ClickAwayListener>\n          </PopoverPure>\n          {campaignTagConfig && (\n            <TagIconList\n              scenario={SCENARIO.ORDERBOOK}\n              campaignTagConfig={campaignTagConfig}\n              symbol={market}\n            />\n          )}\n          <Grid container spacing={3} marginLeft={0} display={'flex'} alignItems={'center'}>\n            <Grid item>\n              <Typography\n                fontWeight={500}\n                color={\n                  !marketTicker?.tradeFloat?.close\n                    ? 'var(--color-text-primary)'\n                    : marketTicker.isRise\n                    ? 'var(--color-success)'\n                    : 'var(--color-error)'\n                }\n              >\n                {marketTicker?.tradeFloat?.close ?? EmptyValueTag}\n              </Typography>\n              <PriceValueStyled>\n                {PriceTag[CurrencyToTag[currency]] +\n                  getValuePrecisionThousand(\n                    (marketTicker.basepriceU || 0) * (forexMap[currency] ?? 0),\n                    undefined,\n                    undefined,\n                    2,\n                    true,\n                    {\n                      isFait: true,\n                      floor: false,\n                      isAbbreviate: true,\n                      abbreviate: 6,\n                    },\n                  )}\n              </PriceValueStyled>\n            </Grid>\n            <Grid item>\n              <PriceTitleStyled>{t('labelProToolbar24hChange')}</PriceTitleStyled>\n              <PriceValueStyled\n                color={marketTicker.isRise ? 'var(--color-success)' : 'var(--color-error)'}\n              >\n                {`${marketTicker.isRise ? '+' : ''} ${getValuePrecisionThousand(\n                  marketTicker?.tradeFloat?.change,\n                  undefined,\n                  undefined,\n                  2,\n                  true,\n                )}%`}\n              </PriceValueStyled>\n            </Grid>\n            {!isMobile && (\n              <Grid item>\n                <PriceTitleStyled>{t('labelProToolbar24hHigh')}</PriceTitleStyled>\n                <PriceValueStyled>\n                  {getValuePrecisionThousand(\n                    marketTicker?.tradeFloat?.high,\n                    undefined,\n                    undefined,\n                    getMarketPrecision(market),\n                    true,\n                    { isPrice: true },\n                  )}\n                </PriceValueStyled>\n              </Grid>\n            )}\n            {!isMobile && (\n              <Grid item>\n                <PriceTitleStyled>{t('labelProToolbar24hLow')}</PriceTitleStyled>\n                <PriceValueStyled>\n                  {getValuePrecisionThousand(\n                    marketTicker?.tradeFloat?.low,\n                    undefined,\n                    undefined,\n                    getMarketPrecision(market),\n                    true,\n                    { isPrice: true },\n                  )}\n                </PriceValueStyled>\n              </Grid>\n            )}\n            {!isMobile && (\n              <Grid item>\n                <PriceTitleStyled>\n                  {t('labelProToolbar24hBaseVol', {\n                    symbol: marketTicker.base,\n                  })}\n                </PriceTitleStyled>\n                <PriceValueStyled>\n                  {getValuePrecisionThousand(\n                    marketTicker.baseVol,\n                    undefined,\n                    undefined,\n                    getTokenPrecision(marketTicker.base),\n                    true,\n                    { isPrice: true },\n                  )}\n                </PriceValueStyled>\n              </Grid>\n            )}\n            {!isMobile && (\n              <Grid item>\n                <PriceTitleStyled>\n                  {t('labelProToolbar24hQuoteVol', {\n                    symbol: marketTicker.quote,\n                  })}\n                </PriceTitleStyled>\n                <PriceValueStyled>\n                  {getValuePrecisionThousand(\n                    marketTicker.quoteVol,\n                    undefined,\n                    undefined,\n                    getTokenPrecision(marketTicker.quote),\n                    true,\n                    { isPrice: true },\n                  )}\n                </PriceValueStyled>\n              </Grid>\n            )}\n          </Grid>\n        </Box>\n        <Box>\n          <Button\n            onClick={() => {\n              handleLayoutChange([], undefined, layoutConfigs[0].layouts)\n            }}\n          >\n            {isMobile ? t('labelResetMobileLayout') : t('labelResetLayout')}\n          </Button>\n        </Box>\n      </Box>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/webapp/src/pages/ProTradePage/panel/walletInfo/index.tsx",
    "content": "import { TFunction, withTranslation, WithTranslation } from 'react-i18next'\nimport React from 'react'\n\nimport {\n  AccountStatus,\n  EmptyValueTag,\n  fnType,\n  getValuePrecisionThousand,\n  i18n,\n  L1L2_NAME_DEFINED,\n  LockIcon,\n  MapChainId,\n  MarketType,\n  myLog,\n  SagaStatus,\n  SoursURL,\n  TradeBtnStatus,\n} from '@loopring-web/common-resources'\nimport { Avatar, Box, Divider, Typography } from '@mui/material'\nimport {\n  AccountStep,\n  AvatarCoin,\n  Button,\n  useOpenModals,\n  useSettings,\n} from '@loopring-web/component-lib'\nimport _ from 'lodash'\nimport {\n  accountStaticCallBack,\n  btnClickMap,\n  btnLabel,\n  useAccount,\n  usePageTradePro,\n  useTokenMap,\n  ViewAccountTemplate,\n  volumeToCount,\n  volumeToCountAsBigNumber,\n} from '@loopring-web/core'\n\nimport { HeaderHeight } from '../../index'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\n// const OtherView = React.memo(({ t }: { market: MarketType; t: TFunction }) => {\n//   const { status: accountStatus, account } = useAccount()\n//   const [label, setLabel] = React.useState('')\n//   const { defaultNetwork } = useSettings()\n//   const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n//   const _btnLabel = Object.assign(_.cloneDeep(btnLabel), {\n//     [fnType.NO_ACCOUNT]: [\n//       function () {\n//         return `depositAndActiveBtn`\n//       },\n//     ],\n//     [fnType.ERROR_NETWORK]: [\n//       function () {\n//         return `labelWrongNetwork`\n//       },\n//     ],\n//   })\n//\n//   React.useEffect(() => {\n//     if (accountStatus === SagaStatus.UNSET) {\n//       setLabel(accountStaticCallBack(_btnLabel))\n//     }\n//   }, [accountStatus, account.readyState, i18n.language])\n//   const _btnClickMap = Object.assign(_.cloneDeep(btnClickMap), {})\n//   const BtnConnect = React.useMemo(() => {\n//     return (\n//       <Button\n//         style={{ height: 28, fontSize: '1.4rem' }}\n//         variant={'contained'}\n//         size={'small'}\n//         color={'primary'}\n//         onClick={() => {\n//           accountStaticCallBack(_btnClickMap, [])\n//         }}\n//       >\n//         {t(label, {\n//           loopringL2: L1L2_NAME_DEFINED[network].loopringL2,\n//           l2Symbol: L1L2_NAME_DEFINED[network].l2Symbol,\n//           l1Symbol: L1L2_NAME_DEFINED[network].l1Symbol,\n//           ethereumL1: L1L2_NAME_DEFINED[network].ethereumL1,\n//         })}\n//       </Button>\n//     )\n//   }, [label])\n//   const viewTemplate = React.useMemo(() => {\n//     switch (account.readyState) {\n//       case AccountStatus.UN_CONNECT:\n//         return (\n//           <Box\n//             flex={1}\n//             height={'100%'}\n//             display={'flex'}\n//             justifyContent={'center'}\n//             alignItems={'center'}\n//             flexDirection={'column'}\n//           >\n//             <Typography\n//               lineHeight={1.5}\n//               paddingX={2}\n//               color={'text.primary'}\n//               marginBottom={2}\n//               variant={'body1'}\n//               textOverflow={'ellipsis'}\n//               whiteSpace={'pre-line'}\n//               textAlign={'center'}\n//               overflow={'hidden'}\n//               display={'flex'}\n//               sx={{ wordBreak: 'break-word', lineClamp: 4 }}\n//             >\n//               {t('describeTitleConnectToWallet', {\n//                 layer2: L1L2_NAME_DEFINED[network].layer2,\n//                 l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n//               })}\n//             </Typography>\n//             {BtnConnect}\n//           </Box>\n//         )\n//\n//         break\n//       case AccountStatus.LOCKED:\n//         return (\n//           <Box\n//             flex={1}\n//             height={'100%'}\n//             display={'flex'}\n//             justifyContent={'center'}\n//             alignItems={'center'}\n//             flexDirection={'column'}\n//           >\n//             <Typography\n//               lineHeight={2}\n//               paddingX={2}\n//               color={'text.primary'}\n//               marginBottom={2}\n//               variant={'body1'}\n//               whiteSpace={'pre-line'}\n//               textAlign={'center'}\n//             >\n//               {t('describeTitleLocked')}\n//             </Typography>\n//             {BtnConnect}\n//           </Box>\n//         )\n//         break\n//       case AccountStatus.NO_ACCOUNT:\n//         return (\n//           <Box\n//             flex={1}\n//             height={'100%'}\n//             display={'flex'}\n//             justifyContent={'center'}\n//             alignItems={'center'}\n//             flexDirection={'column'}\n//           >\n//             <Typography\n//               lineHeight={2}\n//               paddingX={2}\n//               color={'text.primary'}\n//               marginBottom={2}\n//               variant={'body1'}\n//               whiteSpace={'pre-line'}\n//               textAlign={'center'}\n//             >\n//               {t('describeTitleNoAccount', {\n//                 layer2: L1L2_NAME_DEFINED[network].layer2,\n//                 l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n//               })}\n//             </Typography>\n//             {BtnConnect}\n//           </Box>\n//         )\n//         break\n//       case AccountStatus.NOT_ACTIVE:\n//         return (\n//           <Box\n//             flex={1}\n//             height={'100%'}\n//             display={'flex'}\n//             justifyContent={'center'}\n//             alignItems={'center'}\n//             flexDirection={'column'}\n//           >\n//             <Typography\n//               lineHeight={2}\n//               paddingX={2}\n//               color={'text.primary'}\n//               marginBottom={2}\n//               variant={'body1'}\n//               whiteSpace={'pre-line'}\n//               textAlign={'center'}\n//             >\n//               {t('describeTitleNotActive', {\n//                 layer2: L1L2_NAME_DEFINED[network].layer2,\n//                 l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n//               })}\n//             </Typography>\n//             {BtnConnect}\n//           </Box>\n//         )\n//         break\n//       case AccountStatus.DEPOSITING:\n//         return (\n//           <Box\n//             flex={1}\n//             height={'100%'}\n//             display={'flex'}\n//             justifyContent={'center'}\n//             alignItems={'center'}\n//             flexDirection={'column'}\n//           >\n//             <Typography\n//               lineHeight={2}\n//               paddingX={2}\n//               color={'text.primary'}\n//               marginBottom={2}\n//               variant={'body1'}\n//               whiteSpace={'pre-line'}\n//               textAlign={'center'}\n//             >\n//               {t('describeTitleOpenAccounting', {\n//                 layer2: L1L2_NAME_DEFINED[network].layer2,\n//                 l1ChainName: L1L2_NAME_DEFINED[network].l1ChainName,\n//               })}\n//             </Typography>\n//             {BtnConnect}\n//           </Box>\n//         )\n//         break\n//       case AccountStatus.ERROR_NETWORK:\n//         return (\n//           <Box\n//             flex={1}\n//             height={'100%'}\n//             display={'flex'}\n//             justifyContent={'center'}\n//             alignItems={'center'}\n//             flexDirection={'column'}\n//           >\n//             <Typography\n//               lineHeight={2}\n//               paddingX={2}\n//               color={'text.primary'}\n//               marginBottom={2}\n//               variant={'body1'}\n//               whiteSpace={'pre-line'}\n//               textAlign={'center'}\n//             >\n//               {t('describeTitleOnErrorNetwork', {\n//                 connectName: account.connectName,\n//               })}\n//             </Typography>\n//           </Box>\n//         )\n//         break\n//       default:\n//         break\n//     }\n//   }, [t, account.readyState, BtnConnect])\n//\n//   return <>{viewTemplate}</>\n//\n//   // const swapBtnClickArray = Object.assign(_.cloneDeep(btnClickMap), {\n//   //     [ fnType.ACTIVATED ]: [swapCalculatorCallback]\n//   // })\n// })\nconst AssetsValue = React.memo(({ symbol }: { symbol: string }) => {\n  const {\n    pageTradePro: {\n      tradeCalcProData: { walletMap },\n    },\n  } = usePageTradePro()\n  const { tokenMap } = useTokenMap()\n  if (walletMap && walletMap[symbol]?.detail) {\n    const total = getValuePrecisionThousand(\n      volumeToCountAsBigNumber(symbol, sdk.toBig(walletMap[symbol].detail.total ?? 0)),\n      undefined,\n      undefined,\n      tokenMap[symbol].precision,\n      false,\n      { floor: true, isFait: true },\n    )\n\n    const locked = Number(walletMap[symbol].detail.locked)\n      ? volumeToCount(symbol, walletMap[symbol].detail.locked)\n      : 0\n\n    return (\n      <Box display={'flex'} flexDirection={'column'} alignItems={'flex-end'}>\n        <Typography variant={'body1'} color={'text.primary'}>\n          {total}\n        </Typography>\n        {locked ? (\n          <Typography\n            variant={'body2'}\n            color={'text.secondary'}\n            display={'inline-flex'}\n            marginTop={1 / 2}\n          >\n            <LockIcon fontSize={'small'} /> : {locked}\n          </Typography>\n        ) : (\n          EmptyValueTag\n        )}\n      </Box>\n    )\n  } else {\n    return <Box>{EmptyValueTag}</Box>\n  }\n})\nconst UnLookView = React.memo(\n  ({\n    t,\n    market,\n    assetBtnStatus,\n  }: {\n    assetBtnStatus: TradeBtnStatus\n    market: MarketType\n    t: TFunction\n  }) => {\n    // const {pageTradePro: {tradeCalcProData}} = usePageTradePro();\n    //@ts-ignore\n    const [, coinA, coinB] = market.match(/(\\w+)-(\\w+)/i)\n    const { coinJson } = useSettings()\n    const tokenAIcon: any = coinJson[coinA]\n    const tokenBIcon: any = coinJson[coinB]\n    const { setShowAccount } = useOpenModals()\n\n    return (\n      <Box paddingBottom={2}>\n        <Typography\n          height={HeaderHeight}\n          lineHeight={`${HeaderHeight}px`}\n          paddingX={2}\n          variant={'body1'}\n          component={'h4'}\n        >\n          {t('labelAssetsTitle')}\n        </Typography>\n        <Divider />\n        <Box paddingX={2} display={'flex'} flex={1} flexDirection={'column'} justifyContent={''}>\n          <Box\n            height={44}\n            marginTop={1}\n            display={'flex'}\n            flexDirection={'row'}\n            alignItems={'center'}\n            justifyContent={'space-between'}\n          >\n            <Box\n              component={'span'}\n              display={'flex'}\n              flexDirection={'row'}\n              alignItems={'center'}\n              className={'logo-icon'}\n              height={'var(--withdraw-coin-size)'}\n              justifyContent={'flex-start'}\n              marginRight={1 / 2}\n            >\n              {tokenAIcon ? (\n                <AvatarCoin\n                  imgx={tokenAIcon.x}\n                  imgy={tokenAIcon.y}\n                  imgheight={tokenAIcon.h}\n                  imgwidth={tokenAIcon.w}\n                  size={16}\n                  variant='circular'\n                  style={{ marginLeft: '-8px' }}\n                  alt={coinA}\n                  src={\n                    'data:image/svg+xml;utf8,' +\n                    '<svg width=\"36\" height=\"36\" viewBox=\"0 0 36 36\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M0 0H36V36H0V0Z\"/></svg>'\n                  }\n                />\n              ) : (\n                <Avatar\n                  variant='circular'\n                  alt={coinA}\n                  style={{\n                    width: 'var(--withdraw-coin-size)',\n                    height: 'var(--withdraw-coin-size)',\n                  }}\n                  src={SoursURL + 'images/icon-default.png'}\n                />\n              )}\n              <Typography variant={'body1'}>{coinA}</Typography>\n            </Box>\n            <AssetsValue symbol={coinA} />\n          </Box>\n          <Box\n            height={44}\n            marginTop={1}\n            display={'flex'}\n            flexDirection={'row'}\n            alignItems={'center'}\n            justifyContent={'space-between'}\n          >\n            <Box\n              component={'span'}\n              display={'flex'}\n              flexDirection={'row'}\n              alignItems={'center'}\n              className={'logo-icon'}\n              height={'var(--withdraw-coin-size)'}\n              justifyContent={'flex-start'}\n              marginRight={1 / 2}\n            >\n              {tokenBIcon ? (\n                <AvatarCoin\n                  imgx={tokenBIcon.x}\n                  imgy={tokenBIcon.y}\n                  imgheight={tokenBIcon.h}\n                  imgwidth={tokenBIcon.w}\n                  size={16}\n                  variant='circular'\n                  style={{ marginLeft: '-8px' }}\n                  alt={coinB}\n                  src={\n                    'data:image/svg+xml;utf8,' +\n                    '<svg width=\"36\" height=\"36\" viewBox=\"0 0 36 36\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M0 0H36V36H0V0Z\"/></svg>'\n                  }\n                />\n              ) : (\n                <Avatar\n                  variant='circular'\n                  alt={coinB}\n                  style={{\n                    width: 'var(--withdraw-coin-size)',\n                    height: 'var(--withdraw-coin-size)',\n                  }}\n                  src={SoursURL + 'images/icon-default.png'}\n                />\n              )}\n              <Typography variant={'body1'}>{coinB}</Typography>\n            </Box>\n            <AssetsValue symbol={coinB} />\n          </Box>\n          <Box\n            display={'flex'}\n            flexDirection={'row'}\n            alignItems={'center'}\n            marginTop={2}\n            justifyContent={'center'}\n          >\n            <Box marginRight={1}>\n              <Button\n                style={{ height: 28, fontSize: '1.4rem' }}\n                variant={'contained'}\n                size={'small'}\n                color={'primary'}\n                disabled={assetBtnStatus === TradeBtnStatus.LOADING}\n                onClick={() =>\n                  setShowAccount({\n                    isShow: true,\n                    step: AccountStep.AddAssetGateway,\n                    // info: { symbol: coinA },\n                  })\n                }\n              >\n                {t('labelAddAssetBtn')}\n              </Button>\n            </Box>\n            <Box marginLeft={1}>\n              <Button\n                style={{ height: 28, fontSize: '1.4rem' }}\n                variant={'outlined'}\n                size={'small'}\n                disabled={assetBtnStatus === TradeBtnStatus.LOADING}\n                onClick={() =>\n                  setShowAccount({\n                    isShow: true,\n                    step: AccountStep.SendAssetGateway,\n                    // info: { symbol: coinA },\n                  })\n                }\n              >\n                {t('labelSendAssetBtn')}\n              </Button>\n            </Box>\n          </Box>\n        </Box>\n      </Box>\n    )\n  },\n)\n\nexport const WalletInfo = withTranslation(['common', 'layout'])(\n  (\n    props: {\n      assetBtnStatus: TradeBtnStatus\n      market: MarketType\n    } & WithTranslation,\n  ) => {\n    return (\n      <Box\n        paddingX={2}\n        flex={1}\n        display={'flex'}\n        justifyContent={'stretch'}\n        flexDirection={'column'}\n        alignItems={'center'}\n      >\n        <ViewAccountTemplate\n          className={'inBlock'}\n          size={'medium'}\n          activeViewTemplate={<UnLookView {...props} />}\n        />\n      </Box>\n    )\n  },\n)\n"
  },
  {
    "path": "packages/webapp/src/pages/ProTradePage/panel/walletInfo/stopLimitInfo.tsx",
    "content": "import { Trans, WithTranslation, withTranslation } from 'react-i18next'\n\nimport { Avatar, Box, Divider, List, ListItem, Typography } from '@mui/material'\nimport { SoursURL, ThemeType } from '@loopring-web/common-resources'\nimport React from 'react'\nimport { useTheme } from '@emotion/react'\n\nexport const StopLimitInfo = withTranslation('common')(({ t }: WithTranslation) => {\n  const theme = useTheme()\n  return (\n    <Box display={'flex'} flexDirection={'column'} alignItems={'stretch'} height={'100%'}>\n      <Box component={'header'} width={'100%'} paddingX={2}>\n        <Typography variant={'body1'} lineHeight={'44px'}>\n          {t(`labelStopLimitWhatIs`)}\n        </Typography>\n      </Box>\n      <Divider style={{ marginTop: '-1px' }} />\n      <Box\n        flex={'1'}\n        display={'flex'}\n        flexDirection={'column'}\n        sx={{ overflowY: 'scroll' }}\n        paddingX={2}\n      >\n        <Typography component={'p'} variant={'body1'} color={'textPrimary'} marginTop={2}>\n          {t('labelLimitMainContent')}\n        </Typography>\n        <Box display={'flex'} flexDirection={'column'} marginTop={2}>\n          <Typography component={'h6'} variant={'body1'} color={'textPrimary'}>\n            {t('labelLimitStopPriceLabel')}\n          </Typography>\n          <Typography component={'p'} variant={'body1'} color={'textSecondary'} marginTop={1}>\n            {t('labelStopStopPriceDes')}\n          </Typography>\n        </Box>\n        <Box display={'flex'} flexDirection={'column'} marginTop={2}>\n          <Typography component={'h6'} variant={'body1'} color={'textPrimary'}>\n            {t('labelLimitLimitPriceLabel')}\n          </Typography>\n          <Typography component={'p'} variant={'body1'} color={'textSecondary'} marginTop={1}>\n            {t('labelStopPriceDes')}\n          </Typography>\n        </Box>\n        <Box display={'flex'} flexDirection={'column'} marginTop={2}>\n          <Typography component={'h6'} variant={'body1'} color={'textPrimary'}>\n            {t('labelLimitAmountLabel')}\n          </Typography>\n          <Typography component={'p'} variant={'body1'} color={'textSecondary'} marginTop={1}>\n            {t('labelLimitAmountContent')}\n          </Typography>\n        </Box>\n        <Typography component={'p'} marginTop={2} variant={'body1'} color={'textPrimary'}>\n          {t('labelLimitDes')}\n        </Typography>\n        <Box display={'flex'} flexDirection={'column'} marginTop={2}>\n          <Typography component={'h6'} variant={'body1'} color={'textPrimary'}>\n            {t('labelLimitDemoTitle')}\n          </Typography>\n          <Typography component={'span'} marginTop={1}>\n            <Avatar\n              variant='rounded'\n              style={{\n                width: '100%',\n                height: '100%',\n              }}\n              alt={''}\n              // src={sellData?.icon}\n              src={\n                SoursURL +\n                (theme.mode === ThemeType.dark\n                  ? 'images/stoplimit_dark.svg'\n                  : 'images/stoplimit_light.svg')\n              }\n            />\n          </Typography>\n        </Box>\n        <Box display={'flex'} flexDirection={'column'} marginTop={2}>\n          <Typography\n            variant={'body1'}\n            component={'div'}\n            color={'textPrimary'}\n            sx={{ whiteSpace: 'pre-line', wordBreak: 'break-all' }}\n          >\n            <Trans\n              i18nKey={'labelLimitDemoDes'}\n              components={{\n                li: (\n                  <ListItem\n                    sx={{\n                      height: 'auto',\n                      display: 'list-item',\n                      paddingLeft: 1 / 2,\n                    }}\n                  />\n                ),\n                ol: (\n                  <List\n                    sx={{\n                      marginTop: 1,\n                      listStyle: 'disc outside',\n                      marginLeft: 1 / 2,\n                    }}\n                  />\n                ),\n              }}\n            >\n              The current price is 2,400 (A). You can set the stop price above the current price,\n              such as 3,000 (B), or below the current price, such as 1,500 (C). Once the price goes\n              up to 3,000 (B) or drops to 1,500 (C), the Stop-Limit order will be triggered, and the\n              limit order will be automatically placed on the order book. Note:\n              <List sx={{ marginTop: 1 }}>\n                <ListItem>\n                  Limit price can be set above or below the stop price for both buy and sell orders.\n                  For example, stop price B can be placed along with a lower limit price B1 or a\n                  higher limit price B2.\n                </ListItem>\n                <ListItem>\n                  A limit order is invalid before the stop price is triggered, including when the\n                  limit price is reached ahead of the stop price.\n                </ListItem>\n                <ListItem>\n                  When the stop price is reached, it only indicates that a limit order is activated\n                  and will be submitted to the order book rather than the limit order being filled\n                  immediately. The limit order will be executed according to its own rules.\n                </ListItem>\n              </List>\n            </Trans>\n          </Typography>\n        </Box>\n      </Box>\n    </Box>\n  )\n})\n"
  },
  {
    "path": "packages/webapp/src/pages/ProTradePage/proService.ts",
    "content": "import * as _ from 'lodash'\nimport {\n  ammMapReducer,\n  ammPoolService,\n  bookService,\n  LoopringAPI,\n  makeMarketArray,\n  mixorderService,\n  mixtradeService,\n  SocketMap,\n  store,\n  swapDependAsync,\n  tickerService,\n  updatePageTradePro,\n  useAccount,\n  useAmmMap,\n  usePageTradePro,\n  useSocket,\n  useTicker,\n  useTokenMap,\n  useWalletLayer1,\n  useWalletLayer2,\n  walletLayer2Service,\n} from '@loopring-web/core'\nimport React from 'react'\nimport {\n  AccountStatus,\n  globalSetup,\n  MarketType,\n  myLog,\n  SagaStatus,\n} from '@loopring-web/common-resources'\nimport { debounceTime, map, merge, of, Subject, switchAll } from 'rxjs'\n\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nconst TRADE_ARRAY_MAX_LENGTH = 50\n\n/**\n *\n * @param throttleWait\n * @param depDataCallback\n * @param userInfoUpdateCallback\n * @param walletLayer1Callback\n */\nexport const useSocketProService = ({\n  throttleWait = globalSetup.throttleWait,\n  market,\n  userInfoUpdateCallback,\n  walletLayer1Callback,\n}: {\n  throttleWait?: number\n  market: MarketType\n  depDataCallback?: () => void\n  userInfoUpdateCallback?: () => void\n  walletLayer1Callback?: () => void\n}) => {\n  const { updateWalletLayer1, status: walletLayer1Status } = useWalletLayer1()\n  const { updateWalletLayer2, status: walletLayer2Status } = useWalletLayer2()\n  const subjectWallet = React.useMemo(() => walletLayer2Service.onSocket(), [])\n  const subjectBook = React.useMemo(() => bookService.onSocket(), [])\n  const { ammMap } = useAmmMap()\n\n  const subjectAmmpool = React.useMemo(() => ammPoolService.onSocket(), [])\n  const subjectMixorder = React.useMemo(() => mixorderService.onSocket(), [])\n  const subjectTicker = React.useMemo(() => tickerService.onSocket(), [])\n  const subjectMixtrade = React.useMemo(() => mixtradeService.onSocket(), [])\n\n  const _accountUpdate = _.throttle(({ walletLayer1Status, walletLayer2Status }) => {\n    if (walletLayer1Status !== SagaStatus.PENDING) {\n      updateWalletLayer1()\n    }\n    if (walletLayer2Status !== SagaStatus.PENDING) {\n      updateWalletLayer2()\n    }\n  }, throttleWait)\n  React.useEffect(() => {\n    const subscription = merge(\n      subjectAmmpool,\n      subjectMixorder,\n      subjectTicker,\n      subjectMixtrade,\n    ).subscribe((value) => {\n      const pageTradePro = store.getState()._router_pageTradePro.pageTradePro\n      const market = pageTradePro.market\n      const address = ammMap && ammMap['AMM-' + market]?.address\n\n      if (\n        address &&\n        ammMap &&\n        value &&\n        // @ts-ignore\n        value.ammPoolMap &&\n        pageTradePro.market === market\n      ) {\n        // @ts-ignore\n        const ammPoolMap = value.ammPoolMap\n        if (address && ammPoolMap && ammPoolMap[address]?.pooled && pageTradePro.ammPoolSnapshot) {\n          const { pooled: _pooled, lp } = ammPoolMap[address]\n          let pooled = pageTradePro.ammPoolSnapshot.pooled\n          pooled = [\n            {\n              ...pooled[0],\n              volume: _pooled[0],\n            },\n            {\n              ...pooled[1],\n              volume: _pooled[1],\n            },\n          ]\n          const ammPoolSnapshot = {\n            ...pageTradePro.ammPoolSnapshot,\n            pooled,\n            lp: {\n              ...pageTradePro.ammPoolSnapshot.lp,\n              volume: lp,\n            },\n          }\n          store.dispatch(updatePageTradePro({ market, ammPoolSnapshot: ammPoolSnapshot }))\n          store.dispatch(\n            ammMapReducer.updateRealTimeAmmMap({\n              ammPoolStats: {\n                ['AMM-' + market]: {\n                  ...ammMap['AMM-' + market].__rawConfig__,\n                  liquidity: [ammPoolSnapshot.pooled[0].volume, ammPoolSnapshot.pooled[1].volume],\n                  lpLiquidity: ammPoolSnapshot.lp.volume,\n                },\n              },\n            }),\n          )\n        }\n      }\n      // @ts-ignore\n      if (value && value.tickerMap) {\n        const market = pageTradePro.market\n        // @ts-ignore\n        const tickerMap = value.tickerMap\n        if (tickerMap.market === market) {\n          store.dispatch(updatePageTradePro({ market, ticker: tickerMap[market] }))\n        }\n      }\n      // @ts-ignore\n      if (value && value.mixorderMap) {\n        const market = pageTradePro.market\n        // @ts-ignore\n        const mixorder = value.mixorderMap[market]\n        if (mixorder && mixorder.symbol) {\n          store.dispatch(updatePageTradePro({ market, depth: mixorder }))\n        }\n      }\n\n      if (\n        value &&\n        // @ts-ignore\n        value.mixtrades &&\n        // @ts-ignore\n        value.mixtrades[0].market === pageTradePro.market\n      ) {\n        const market = pageTradePro.market\n        // @ts-ignore\n        const _tradeArray = makeMarketArray(market, value.mixtrades)\n        let tradeArray = [\n          ..._tradeArray,\n          ...(pageTradePro.tradeArray ? pageTradePro.tradeArray : []),\n        ]\n\n        tradeArray.length = TRADE_ARRAY_MAX_LENGTH\n        store.dispatch(updatePageTradePro({ market, tradeArray }))\n      }\n    })\n    return () => subscription.unsubscribe()\n  }, [market])\n\n  React.useEffect(() => {\n    const subscription = merge(subjectWallet, subjectBook).subscribe(() => {\n      const walletLayer2Status = store.getState().walletLayer2.status\n      const walletLayer1Status = store.getState().walletLayer1.status\n      _accountUpdate({ walletLayer2Status, walletLayer1Status })\n    })\n    return () => {\n      subscription.unsubscribe()\n    }\n  }, [])\n\n  React.useEffect(() => {\n    if (userInfoUpdateCallback && walletLayer2Status === SagaStatus.UNSET) {\n      userInfoUpdateCallback()\n    }\n  }, [walletLayer2Status])\n  React.useEffect(() => {\n    if (walletLayer1Callback && walletLayer1Status === SagaStatus.UNSET) {\n      walletLayer1Callback()\n    }\n  }, [walletLayer1Status])\n}\n\nexport const useProSocket = ({ market }: { market: MarketType }) => {\n  const { socket, sendSocketTopic, socketEnd, status: socketStatus } = useSocket()\n  const { account, status: accountStatus } = useAccount()\n  const { marketArray, marketMap } = useTokenMap()\n  const { ammMap } = useAmmMap()\n  const { tickerMap } = useTicker()\n  const socketEventSubject = new Subject<SocketMap>()\n\n  const { pageTradePro, updatePageTradePro, __API_REFRESH__ } = usePageTradePro()\n  const nodeTimer = React.useRef<NodeJS.Timeout | -1>(-1)\n\n  React.useEffect(() => {\n    getDependencyData()\n  }, [pageTradePro.market, pageTradePro.depthLevel])\n  React.useEffect(() => {\n    getMarketDepData()\n  }, [pageTradePro.market])\n  const noSocketAndAPILoop = React.useCallback(async () => {\n    const pageTradePro = store.getState()._router_pageTradePro.pageTradePro\n    if (nodeTimer.current !== -1) {\n      clearTimeout(nodeTimer.current as NodeJS.Timeout)\n    }\n    if (\n      ((window as any).loopringSocket === undefined ||\n        (window as any).loopringSocket.ws === undefined ||\n        !(window as any).loopringSocket.isConnectSocket()) &&\n      pageTradePro.depth\n    ) {\n      getDependencyData()\n      getMarketDepData()\n    }\n    // getMarketDepData();\n\n    if (market === pageTradePro.market && LoopringAPI.exchangeAPI) {\n      const { depth } = await LoopringAPI.exchangeAPI.getMixDepth({\n        market: pageTradePro.market,\n        level: 0,\n        limit: 50,\n      })\n      updatePageTradePro({\n        market: pageTradePro.market,\n        depthForCalc: depth,\n      })\n      nodeTimer.current = setTimeout(noSocketAndAPILoop, __API_REFRESH__)\n    }\n  }, [nodeTimer, updatePageTradePro, market])\n  const getDependencyData = React.useCallback(async () => {\n    try {\n      const pageTradePro = store.getState()._router_pageTradePro.pageTradePro\n      if (\n        market === pageTradePro.market &&\n        ammMap &&\n        pageTradePro.depthLevel &&\n        LoopringAPI.exchangeAPI\n      ) {\n        const { depth, ammPoolSnapshot } = await swapDependAsync(\n          pageTradePro.market,\n          marketMap[pageTradePro.market].precisionForPrice - Number(pageTradePro.depthLevel),\n          50,\n        )\n        const { tickerMap } = store.getState().tickerMap\n        updatePageTradePro({\n          market: pageTradePro.market,\n          depth,\n          depthForCalc: depth,\n          ammPoolSnapshot,\n          ticker: tickerMap[pageTradePro.market],\n        })\n      }\n    } catch (error: any) {}\n  }, [pageTradePro, ammMap, tickerMap, market])\n  const getMarketDepData = React.useCallback(async () => {\n    const pageTradePro = store.getState()._router_pageTradePro.pageTradePro\n    if (market === pageTradePro.market && LoopringAPI.exchangeAPI) {\n      const { marketTrades } = await LoopringAPI.exchangeAPI.getMarketTrades({\n        market: pageTradePro.market,\n        limit: TRADE_ARRAY_MAX_LENGTH,\n      })\n      const _tradeArray = makeMarketArray(pageTradePro.market, marketTrades)\n\n      updatePageTradePro({\n        market: pageTradePro.market,\n        tradeArray: _tradeArray,\n      })\n    }\n  }, [pageTradePro, ammMap, market])\n\n  const doSend = async (dataSocket: SocketMap) => {\n    socketEnd()\n    socketEventSubject.next(dataSocket)\n  }\n  const sendCallback = async (dataSocket: SocketMap) => {\n    myLog('doSocket Pro Send', pageTradePro.market, socketStatus, nodeTimer.current)\n    if (socketStatus !== SagaStatus.PENDING || nodeTimer.current == -1) {\n      myLog('doSocket Pro Send', pageTradePro.market)\n      if (account.readyState === AccountStatus.ACTIVATED) {\n        sendSocketTopic({\n          ...dataSocket,\n          // [sdk.WsTopicType.account]: true,\n          [sdk.WsTopicType.order]: marketArray, // user order\n        })\n      } else {\n        sendSocketTopic(dataSocket)\n      }\n    }\n    // if (nodeTimer.current !== -1) {\n    //   clearTimeout(nodeTimer.current as NodeJS.Timeout);\n    // }\n    noSocketAndAPILoop()\n  }\n\n  React.useEffect(() => {\n    socketEventSubject\n      .pipe(map((item) => of(item)))\n      .pipe(switchAll())\n      .pipe(debounceTime(200))\n      .pipe()\n      .subscribe((dataSocket) => {\n        if (dataSocket) {\n          myLog('pro socketEventSubject', dataSocket)\n          sendCallback(dataSocket)\n        }\n      })\n    return () => {\n      socketEventSubject.unsubscribe()\n    }\n  }, [socketEventSubject])\n  React.useEffect(() => {\n    if (ammMap && pageTradePro.market && accountStatus === SagaStatus.UNSET) {\n      try {\n        const dataSocket: SocketMap = {\n          [sdk.WsTopicType.ammpool]: ammMap['AMM-' + pageTradePro.market]\n            ? [ammMap['AMM-' + pageTradePro.market].address]\n            : [],\n          [sdk.WsTopicType.ticker]: [pageTradePro.market as string],\n          [sdk.WsTopicType.mixorder]: {\n            markets: [pageTradePro.market],\n            level:\n              marketMap[pageTradePro.market].precisionForPrice - Number(pageTradePro.depthLevel),\n            count: 50,\n            snapshot: true,\n          },\n          [sdk.WsTopicType.mixtrade]: [pageTradePro.market as string],\n        }\n        if (socket.mixorder?.markets[0] !== pageTradePro.market) {\n          doSend(dataSocket)\n          myLog('doSocket market update', dataSocket)\n        } else if (socket.mixorder?.markets[0] === pageTradePro.market) {\n          if (socket.mixorder.level !== pageTradePro.depthLevel) {\n            doSend(dataSocket)\n            myLog('doSocket level update', pageTradePro.market)\n          } else if (\n            (account.readyState === AccountStatus.ACTIVATED && !socket.account) ||\n            socket.account\n          ) {\n            doSend(dataSocket)\n            myLog('doSocket account update', pageTradePro.market)\n          } else {\n            myLog('NO doSocket ', pageTradePro.market)\n          }\n        } else {\n          myLog('NO doSocket ', pageTradePro.market)\n        }\n      } catch (e: any) {\n        socketEnd()\n      }\n    }\n  }, [pageTradePro.market, pageTradePro.depthLevel, accountStatus])\n\n  React.useEffect(() => {\n    return () => {\n      if (nodeTimer.current !== -1) {\n        clearTimeout(nodeTimer.current)\n      }\n      socketEnd()\n    }\n  }, [])\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/ProTradePage/stopLimtPage.tsx",
    "content": "import { withTranslation } from 'react-i18next'\n\nimport React from 'react'\nimport { Layout, Layouts, Responsive, WidthProvider } from 'react-grid-layout'\n\nimport { usePro } from './hookPro'\nimport { useTheme } from '@emotion/react'\nimport { Box, IconButton } from '@mui/material'\nimport {\n  BreakPoint,\n  DragIcon,\n  stopLimitLayoutConfigs,\n  myLog,\n  ResizeIcon,\n  RowConfig,\n  SoursURL,\n  LayoutConfigInfo,\n  RouterPath,\n} from '@loopring-web/common-resources'\nimport { ChartView, OrderTableView, Toolbar } from './panel'\nimport { boxLiner, useSettings } from '@loopring-web/component-lib'\nimport styled from '@emotion/styled'\nimport { usePageTradePro } from '@loopring-web/core'\nimport { useHistory } from 'react-router-dom'\nimport { StopLimitView } from './panel/spot/stopLimit'\nimport { StopLimitInfo } from './panel/walletInfo/stopLimitInfo'\n\nconst MARKET_ROW_LENGTH: number = 8\n// const MARKET_ROW_LENGTH_LG: number = 11;\n\nconst MARKET_TRADES_LENGTH: number = 19\n// const MARKET_TRADES_LENGTH_LG: number = 24;\nexport const HeaderHeight = RowConfig.rowHeaderHeight\n\nconst BoxStyle = styled(Box)`\n  --tab-header: ${HeaderHeight}px;\n  background: var(--color-global-bg);\n\n  &.spot {\n    ${({ theme }: any) => boxLiner({ theme })}\n  }\n\n  .MuiTabs-root {\n    min-height: var(--tab-header);\n\n    .MuiTab-root.MuiTab-fullWidth,\n    .MuiTab-root {\n      font-size: ${({ theme }) => theme.fontDefault.body1};\n      min-height: var(--tab-header);\n      padding: ${({ theme }) => theme.unit}px;\n\n      &:after {\n        margin: 0;\n      }\n    }\n  }\n`\nconst ResponsiveGridLayout = WidthProvider(Responsive)\n\nconst initBreakPoint = (): BreakPoint => {\n  if (window.innerWidth >= stopLimitLayoutConfigs[0].breakpoints[BreakPoint.xlg]) {\n    return BreakPoint.xlg\n  } else if (window.innerWidth >= stopLimitLayoutConfigs[0].breakpoints[BreakPoint.lg]) {\n    return BreakPoint.lg\n  } else if (window.innerWidth >= stopLimitLayoutConfigs[0].breakpoints[BreakPoint.md]) {\n    return BreakPoint.md\n  } else if (window.innerWidth >= stopLimitLayoutConfigs[0].breakpoints[BreakPoint.sm]) {\n    return BreakPoint.sm\n  } else if (window.innerWidth >= stopLimitLayoutConfigs[0].breakpoints[BreakPoint.xs]) {\n    return BreakPoint.xs\n  } else if (window.innerWidth >= stopLimitLayoutConfigs[0].breakpoints[BreakPoint.xxs]) {\n    return BreakPoint.xxs\n  } else {\n    return BreakPoint.md\n  }\n}\nexport const StopLimitPage = withTranslation('common')(<Config extends LayoutConfigInfo>() => {\n  const {\n    pageTradePro: { depthForCalc },\n  } = usePageTradePro()\n  const { market, handleOnMarketChange, resetTradeCalcData } = usePro({\n    path: '/trade/stoplimit',\n  })\n  const { unit } = useTheme()\n  const { stopLimitLayout, setStopLimitLayouts } = useSettings()\n  const history = useHistory()\n\n  const [configLayout, setConfigLayout] = React.useState<Config>({\n    // @ts-ignore\n    compactType: 'vertical',\n    currentBreakpoint: initBreakPoint(),\n    mounted: false,\n    layouts: stopLimitLayout ?? stopLimitLayoutConfigs[0].layouts,\n  })\n  const sportMemo = React.useMemo(() => {\n    return (\n      <>\n        {depthForCalc ? (\n          <StopLimitView market={market as any} resetTradeCalcData={resetTradeCalcData} />\n        ) : (\n          <Box\n            flex={1}\n            height={'100%'}\n            display={'flex'}\n            alignItems={'center'}\n            justifyContent={'center'}\n          >\n            {/*<LoadingIcon />*/}\n            <img\n              className='loading-gif'\n              alt={'loading'}\n              width='36'\n              src={`${SoursURL}images/loading-line.gif`}\n            />\n          </Box>\n        )}\n      </>\n    )\n  }, [market, depthForCalc])\n\n  const onBreakpointChange = React.useCallback(\n    (breakpoint: BreakPoint) => {\n      setConfigLayout((state: Config) => {\n        return {\n          ...state,\n          currentBreakpoint: breakpoint,\n        }\n      })\n      configLayout.layouts[breakpoint].forEach((layoutItem, index) => {\n        onResize(\n          configLayout.layouts[breakpoint],\n          configLayout.layouts[configLayout.currentBreakpoint][index],\n          layoutItem,\n        )\n      })\n    },\n    [configLayout],\n  )\n\n  const onResize = React.useCallback(\n    (layout: Layout[], _oldLayoutItem, _layoutItem) => {\n      setStopLimitLayouts({ [configLayout.currentBreakpoint]: layout })\n    },\n    [configLayout],\n  )\n\n  const handleLayoutChange = React.useCallback(\n    (currentLayout: Layout[], allLayouts?: Layouts, defaultlayouts?: Layouts) => {\n      if (defaultlayouts) {\n        setStopLimitLayouts(defaultlayouts)\n        history.push(RouterPath.loading)\n        setTimeout(() => {\n          history.go(-1)\n        }, 0)\n      } else {\n      }\n      myLog(currentLayout)\n    },\n    [configLayout, stopLimitLayout, setConfigLayout, setStopLimitLayouts],\n  )\n  const ViewList = {\n    toolbar: React.useMemo(\n      () => (\n        <Toolbar\n          market={market as any}\n          layoutConfigs={stopLimitLayoutConfigs}\n          handleLayoutChange={handleLayoutChange}\n          handleOnMarketChange={handleOnMarketChange}\n        />\n      ),\n      [market, handleLayoutChange, handleOnMarketChange],\n    ),\n    spot: sportMemo,\n    markdown: <StopLimitInfo />,\n    chart: React.useMemo(\n      () => <ChartView market={market} rowLength={0} isShowDepth={false} />,\n      [market],\n    ),\n    orderTable: React.useMemo(\n      () => (\n        <OrderTableView\n          isStopLimit={true}\n          market={market}\n          handleOnMarketChange={handleOnMarketChange}\n        />\n      ),\n      [market],\n    ),\n  }\n  return (\n    <Box\n      bgcolor={'var(--color-box-third)'}\n      display={'block'}\n      margin={'0 auto'}\n      width={'100%'}\n      position={'relative'}\n    >\n      {market ? (\n        <ResponsiveGridLayout\n          className='layout'\n          {...{ ...configLayout }}\n          onBreakpointChange={onBreakpointChange}\n          onLayoutChange={handleLayoutChange}\n          onResizeStop={onResize}\n          resizeHandle={\n            <IconButton\n              size={'medium'}\n              style={{\n                position: 'absolute',\n                zIndex: 78,\n                right: 0,\n                bottom: 0,\n              }}\n              className={'resize-holder'}\n            >\n              <ResizeIcon\n                htmlColor={'var(--color-text-third)'}\n                style={{\n                  marginRight: `-${unit}px`,\n                  marginBottom: `-${unit}px`,\n                }}\n              />\n            </IconButton>\n          }\n          draggableHandle={'.drag-holder'}\n          breakpoints={stopLimitLayoutConfigs[0].breakpoints}\n          cols={stopLimitLayoutConfigs[0].cols}\n          rowHeight={unit / 2}\n          margin={[unit / 2, unit / 2]}\n        >\n          {configLayout.layouts[configLayout.currentBreakpoint].map((layout) => {\n            return (\n              <BoxStyle\n                key={layout.i}\n                overflow={'hidden'}\n                className={layout.i}\n                component={'section'}\n                position={'relative'}\n                display={'flex'}\n                flexDirection={'column'}\n              >\n                {ViewList[layout.i]}\n                <IconButton\n                  size={'medium'}\n                  style={{\n                    position: 'absolute',\n                    zIndex: 78,\n                    right: 0,\n                    top: 0,\n                  }}\n                  className={'drag-holder'}\n                >\n                  <DragIcon\n                    htmlColor={'var(--color-text-third)'}\n                    style={{ marginRight: `-${unit}px`, marginTop: '' }}\n                  />\n                </IconButton>\n              </BoxStyle>\n            )\n          })}\n        </ResponsiveGridLayout>\n      ) : (\n        <Box\n          flex={1}\n          height={'100%'}\n          display={'flex'}\n          alignItems={'center'}\n          justifyContent={'center'}\n        >\n          {/*<LoadingIcon />*/}\n          <img\n            className='loading-gif'\n            alt={'loading'}\n            width='36'\n            src={`${SoursURL}images/loading-line.gif`}\n          />\n        </Box>\n      )}\n    </Box>\n  )\n})\n"
  },
  {
    "path": "packages/webapp/src/pages/QuotePage/hook.ts",
    "content": "import React, { useCallback } from 'react'\n\nimport { QuoteTableRawDataItem } from '@loopring-web/component-lib'\nimport { WsTopicType } from '@loopring-web/loopring-sdk'\n\nimport { RowConfig, SagaStatus, TableFilterParams } from '@loopring-web/common-resources'\nimport _ from 'lodash'\nimport {\n  favoriteMarket as favoriteMarketReducer,\n  LAYOUT,\n  LoopringAPI,\n  store,\n  tickerService,\n  useNotify,\n  useSocket,\n  useSystem,\n  useTicker,\n  useTokenMap,\n  useTokenPrices,\n} from '@loopring-web/core'\nimport { useHistory } from 'react-router-dom'\n\nexport function useTickList<C extends { [key: string]: string }>() {\n  const [tickList, setTickList] = React.useState<any>([])\n  const { marketArray, coinMap, marketMap, tokenMap, status: tokenMapStatus } = useTokenMap()\n\n  const { forexMap } = useSystem()\n  const { tickerMap, status: tickerStatus } = useTicker()\n  const { tokenPrices } = useTokenPrices()\n  const updateRawData = React.useCallback(async () => {\n    let _recommendationsFloat: QuoteTableRawDataItem[] = []\n    let defaultRecommendationsFloat: QuoteTableRawDataItem[] = []\n    const _tickList =\n      tickerMap && Object.keys(tickerMap)\n        ? Reflect.ownKeys(tickerMap).reduce((prev, key) => {\n            // @ts-ignore\n            const [, coinA, coinB] = key.match(/(\\w+)-(\\w+)/i)\n            const ticker = tickerMap[key as string]\n            const coinApriceU = ticker.close * (tokenPrices[coinB] ?? 0) ?? tokenPrices[coinB] ?? 0\n            let _item: QuoteTableRawDataItem = {\n              ...ticker,\n              pair: {\n                coinA,\n                coinB,\n              },\n              coinApriceU,\n            } as QuoteTableRawDataItem\n\n            if (marketArray && marketArray.findIndex((m) => m === key) !== -1) {\n              defaultRecommendationsFloat.push(_.cloneDeep(_item))\n            }\n            prev.push(_item)\n            return prev\n          }, [] as QuoteTableRawDataItem[])\n        : []\n\n    const newTickListWithPrecision = _tickList\n      .filter((o: any) => {\n        const pair = o.__rawTicker__.symbol\n        return marketMap ? marketMap[pair]?.enabled : undefined\n      })\n      .map((o: any) => {\n        const pair = o.__rawTicker__.symbol\n        const precision = marketMap ? marketMap[pair]?.precisionForPrice : undefined\n        return {\n          ...o,\n          precision,\n        }\n      })\n\n    setTickList(newTickListWithPrecision)\n    while (_recommendationsFloat.length < 4) {\n      _recommendationsFloat.push(_.cloneDeep(_recommendationsFloat[0]))\n    }\n  }, [coinMap, forexMap, marketArray, marketMap, tokenMap, tokenPrices, tickerMap])\n\n  React.useEffect(() => {\n    if (tickerStatus === SagaStatus.UNSET && tokenMapStatus === SagaStatus.UNSET) {\n      updateRawData()\n    }\n  }, [tickerStatus, tokenMapStatus])\n  return {\n    tickList,\n    tickerMap,\n    updateRawData,\n  }\n}\n\nexport function useQuote<C extends { [key: string]: string }>() {\n  const { sendSocketTopic, socketEnd } = useSocket()\n  const { marketArray } = store.getState().tokenMap\n  const { tickList } = useTickList()\n  const subject = React.useMemo(() => tickerService.onSocket(), [])\n\n  React.useEffect(() => {\n    const subscription = subject.subscribe(({ tickerMap }) => {})\n    return () => subscription.unsubscribe()\n  }, [subject])\n\n  const socketSendTicker = React.useCallback(() => {\n    sendSocketTopic({ [WsTopicType.ticker]: marketArray })\n  }, [marketArray])\n\n  React.useEffect(() => {\n    socketSendTicker()\n    return () => {\n      socketEnd()\n    }\n  }, [])\n\n  return {\n    tickList,\n  }\n}\n\nexport const useQuotePage = ({ tableRef }: { tableRef: React.Ref<any> }) => {\n  const { status: tickerStatus } = useTicker()\n  const { marketMap } = useTokenMap()\n  const [ammPoolBalances, setAmmPoolBalances] = React.useState<any[]>([])\n  const [tableTabValue, setTableTabValue] = React.useState(TableFilterParams.all)\n  const { campaignTagConfig } = useNotify().notifyMap ?? {}\n  const [searchValue, setSearchValue] = React.useState<string>('')\n\n  const [filteredData, setFilteredData] = React.useState<QuoteTableRawDataItem[]>([])\n  const [tableHeight, setTableHeight] = React.useState(0)\n\n  const { favoriteMarket, removeMarket, addMarket } = favoriteMarketReducer.useFavoriteMarket()\n\n  const { tickList } = useQuote()\n  const handleCurrentScroll = React.useCallback((currentTarget, tableRef) => {\n    if (currentTarget && tableRef.current) {\n      const calcHeight = tableRef.current?.offsetTop - LAYOUT.HEADER_HEIGHT - currentTarget.scrollY\n      if (calcHeight < 2) {\n        tableRef.current.classList.add('fixed')\n      } else {\n        tableRef.current.classList.remove('fixed')\n      }\n    }\n  }, [])\n  const currentScroll = React.useCallback(\n    (event) => {\n      handleCurrentScroll(event.currentTarget, tableRef)\n    },\n    [handleCurrentScroll, tableRef],\n  )\n  const resetTableData = React.useCallback(\n    (tableData) => {\n      setFilteredData(tableData)\n      setTableHeight(RowConfig.rowHeaderHeight + tableData.length * RowConfig.rowHeight)\n    },\n    [setFilteredData, setTableHeight],\n  )\n  React.useEffect(() => {\n    window.addEventListener('scroll', currentScroll)\n    return () => {\n      window.removeEventListener('scroll', currentScroll)\n    }\n  }, [currentScroll])\n\n  const getAmmPoolBalances = React.useCallback(async () => {\n    if (LoopringAPI.ammpoolAPI) {\n      const ammRes = await LoopringAPI.ammpoolAPI?.getAmmPoolBalances<any[]>()\n      const fomattedRes = ammRes?.raw_data.map((o: any) => ({\n        ...o,\n        poolName: o.poolName.replace('AMM-', ''),\n      }))\n      setAmmPoolBalances(fomattedRes)\n    }\n  }, [])\n\n  React.useEffect(() => {\n    getAmmPoolBalances()\n  }, [])\n\n  let history = useHistory()\n\n  // prevent amm risky pair\n  const getFilteredTickList = React.useCallback(() => {\n    if (tickList && !!tickList.length) {\n      return tickList.filter((o: any) => {\n        const pair = `${o.pair.coinA}-${o.pair.coinB}`\n        const status = ('00' + marketMap[pair]?.status?.toString(2)).split('')\n        if (status[status.length - 2] === '1') {\n          return true\n        } else if (\n          status[status.length - 1] === '1' &&\n          ammPoolBalances.find((o) => o.poolName === pair)\n        ) {\n          return !ammPoolBalances.find((o) => o.poolName === pair).risky\n        }\n      })\n    }\n    return []\n  }, [tickList, ammPoolBalances, marketMap])\n\n  React.useEffect(() => {\n    if (tickerStatus === SagaStatus.UNSET && tickList.length) {\n      // const data = getFilteredTickList();\n      handleTableFilterChange({})\n    }\n  }, [ammPoolBalances, tickerStatus, tickList])\n\n  const handleTableFilterChange = React.useCallback(\n    ({\n      type = tableTabValue,\n      keyword = searchValue,\n    }: {\n      type?: TableFilterParams\n      keyword?: string\n    }) => {\n      let data = _.cloneDeep(tickList)\n      // myLog(\"tickList\", data);\n      if (type === TableFilterParams.favourite) {\n        data = data.filter((o: any) => {\n          const pair = `${o.pair.coinA}-${o.pair.coinB}`\n          return favoriteMarket?.includes(pair)\n        })\n      }\n      data = data.filter((o: any) => {\n        const formattedKeyword = keyword?.toLocaleLowerCase()\n        const coinA = o.pair.coinA.toLowerCase()\n        const coinB = o.pair.coinB.toLowerCase()\n        if (keyword === '') {\n          return true\n        }\n        return coinA?.includes(formattedKeyword) || coinB?.includes(formattedKeyword)\n      })\n      if (type === TableFilterParams.all && !keyword) {\n        data = getFilteredTickList()\n      }\n      resetTableData(data)\n    },\n    [\n      tickList,\n      tableTabValue,\n      resetTableData,\n      favoriteMarket,\n      // swapRankingList,\n      getFilteredTickList,\n    ],\n  )\n\n  const handleRowClick = useCallback(\n    (row: QuoteTableRawDataItem) => {\n      const { coinA, coinB } = row.pair\n      const tradePair = `${coinA}-${coinB}`\n      history &&\n        history.push({\n          pathname: `/trade/lite/${tradePair}`,\n        })\n    },\n    [history],\n  )\n\n  const handleTabChange = useCallback(\n    (_event: any, newValue: TableFilterParams) => {\n      // if (tickList?.length) {\n      setTableTabValue(newValue)\n      handleTableFilterChange({\n        keyword: searchValue,\n        type: newValue,\n      })\n      // }\n    },\n    [handleTableFilterChange, searchValue],\n  )\n\n  const handleSearchChange = React.useCallback(\n    (value) => {\n      setSearchValue(value)\n      handleTableFilterChange({ keyword: value, type: tableTabValue })\n    },\n    [handleTableFilterChange, tableTabValue],\n  )\n\n  return {\n    campaignTagConfig,\n    tableTabValue,\n    handleTabChange,\n    searchValue,\n    removeMarket,\n    favoriteMarket,\n    handleSearchChange,\n    addMarket,\n    showLoading: !tickList?.length,\n    tickList,\n    filteredData,\n    tableHeight,\n    handleRowClick,\n  }\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/QuotePage/index.tsx",
    "content": "import React from 'react'\nimport { InputSearch, QuoteTable } from '@loopring-web/component-lib'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport { RowConfig } from '@loopring-web/common-resources'\nimport { Box, Container, Divider, Tab, Tabs } from '@mui/material'\nimport { useQuotePage } from './hook'\nimport { TableWrapStyled, useAccount, useSystem } from '@loopring-web/core'\nexport const QuotePage = withTranslation('common')(({ t, ...rest }: WithTranslation) => {\n  const tableRef = React.useRef<HTMLDivElement>()\n  const { account } = useAccount()\n  const { forexMap } = useSystem()\n  const {\n    tableTabValue,\n    handleTabChange,\n    searchValue,\n    removeMarket,\n    favoriteMarket,\n    handleSearchChange,\n    addMarket,\n    tableHeight,\n    filteredData,\n    showLoading,\n    campaignTagConfig,\n    handleRowClick,\n  } = useQuotePage({ tableRef })\n  return (\n    <Box\n      display={'flex'}\n      flexDirection={'column'}\n      flex={1}\n      bgcolor={'var(--color-box-third)'}\n      borderRadius={2}\n    >\n      <TableWrapStyled\n        ref={tableRef as any}\n        paddingBottom={1}\n        flex={1}\n        bgcolor={'var(--color-box)'}\n        className={'MuiPaper-elevation2'}\n      >\n        <Box display={'flex'} flexDirection={'column'}>\n          <Container className={'toolbar'}>\n            <Box\n              paddingLeft={1}\n              paddingRight={2}\n              display={'flex'}\n              flexDirection={'row'}\n              justifyContent={'space-between'}\n              alignItems={'center'}\n            >\n              <Tabs\n                value={tableTabValue}\n                onChange={handleTabChange}\n                disabled={showLoading}\n                aria-label='Market Switch'\n              >\n                <Tab label={t('labelQuotePageFavourite')} value='favourite' />\n                <Tab label={t('labelAll')} value='all' />\n              </Tabs>\n              <InputSearch value={searchValue} onChange={handleSearchChange} />\n            </Box>\n            <Divider style={{ marginTop: '-1px' }} />\n          </Container>\n\n          <QuoteTable /* onVisibleRowsChange={onVisibleRowsChange} */\n            onRowClick={(index: any, row: any, col: any) => handleRowClick(row)}\n            campaignTagConfig={campaignTagConfig ?? ({} as any)}\n            forexMap={forexMap as any}\n            account={account}\n            rawData={filteredData}\n            favoriteMarket={favoriteMarket}\n            addFavoriteMarket={addMarket}\n            removeFavoriteMarket={removeMarket}\n            currentheight={tableHeight}\n            rowHeight={RowConfig.rowHeight}\n            headerRowHeight={RowConfig.rowHeaderHeight}\n            showLoading={showLoading}\n            {...{ ...rest }}\n          />\n        </Box>\n      </TableWrapStyled>\n    </Box>\n  )\n})\n"
  },
  {
    "path": "packages/webapp/src/pages/QuotePage/useMaket.ts",
    "content": "import {\n  RowConfig,\n  RowConfigType,\n  TableFilterParams,\n  TickerNew,\n} from '@loopring-web/common-resources'\nimport React, { useCallback } from 'react'\nimport {\n  favoriteVaultMarket as favoriteMarketReducer,\n  LAYOUT,\n  store,\n  TokenMap,\n  useAccount,\n  useSystem,\n} from '@loopring-web/core'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nexport const useMarket = <\n  R extends TickerNew & { cmcTokenId: number; isFavorite: boolean },\n  T = sdk.TokenInfo,\n>({\n  tableRef,\n  rowConfig = RowConfig,\n  tickerMap,\n  handleRowClick,\n  handleItemClick,\n  tokenMap = store.getState()?.tokenMap?.tokenMap,\n}: {\n  tickerMap: { [key: string]: R }\n  tableRef: React.Ref<any>\n  rowConfig?: RowConfigType\n  handleRowClick?: (index: number, props: T & R) => void\n  handleItemClick?: (index: number, props: T & R) => void\n  tokenMap: TokenMap<any>\n}) => {\n  const { account } = useAccount()\n  // const { marketMap, tokenMap } = useTokenMap()\n  const [tableTabValue, setTableTabValue] = React.useState(TableFilterParams.all)\n  const [searchValue, setSearchValue] = React.useState<string>('')\n  const [filteredData, setFilteredData] = React.useState<(sdk.TokenInfo & R)[]>([])\n  const [tableHeight, setTableHeight] = React.useState(0)\n  const { favoriteMarket, removeMarket, addMarket } = favoriteMarketReducer.useFavoriteVaultMarket()\n\n  // const { tickList } = useQuote()\n  const handleCurrentScroll = React.useCallback((currentTarget, tableRef) => {\n    if (currentTarget && tableRef.current) {\n      const calcHeight = tableRef.current?.offsetTop - LAYOUT.HEADER_HEIGHT - currentTarget.scrollY\n      if (calcHeight < 2) {\n        tableRef.current.classList.add('fixed')\n      } else {\n        tableRef.current.classList.remove('fixed')\n      }\n    }\n  }, [])\n  const currentScroll = React.useCallback(\n    (event) => {\n      handleCurrentScroll(event.currentTarget, tableRef)\n    },\n    [handleCurrentScroll, tableRef],\n  )\n\n  const handleTableFilterChange = React.useCallback(\n    ({\n      type = tableTabValue,\n      // keyword,\n      ...rest\n    }: {\n      type?: TableFilterParams\n      keyword?: string\n    }) => {\n      let filter = ''\n      const favoriteMarket = store.getState().localStore.favoriteVaultMarket\n      setSearchValue((state) => {\n        filter = state\n        if (rest.hasOwnProperty('keyword')) {\n          filter = rest.keyword ?? ''\n        }\n        return filter\n      })\n      let data: Array<R & sdk.TokenInfo> = Object.values(tickerMap) ?? []\n      data = data\n      .filter((item) => {\n        if (!(item as any).vaultTokenAmounts) {\n          return false\n        }\n        const status = (item as any).vaultTokenAmounts.status as number\n        return item.enabled && status & 1\n      })\n      .map((item) => {\n        return {\n          ...tokenMap[item.symbol],\n          ...item,\n          isFavorite: favoriteMarket?.includes(item.symbol),\n        }\n      })\n      if (type === TableFilterParams.favourite) {\n        // myLog(\"tickList\", data);\n        data = data.filter((item) => {\n          return favoriteMarket?.includes(item.symbol)\n        })\n      }\n      if (filter) {\n        data = data.filter((o: any) => {\n          return new RegExp(filter, 'ig').test(o.symbol)\n        })\n      }\n      setFilteredData(data)\n      setTableHeight(\n        (rowConfig.rowHeaderHeight ?? RowConfig.rowHeaderHeight) +\n          data.length * (rowConfig?.rowHeight ?? RowConfig.rowHeaderHeight),\n      )\n    },\n    [\n      tickerMap,\n      tableTabValue,\n\n      searchValue,\n\n      // swapRankingList,\n      // getFilteredTickList,\n    ],\n  )\n\n  const handleTabChange = useCallback(\n    (_event: any, newValue: TableFilterParams) => {\n      // if (tickList?.length) {\n      setTableTabValue(newValue)\n      handleTableFilterChange({\n        keyword: searchValue,\n        type: newValue,\n      })\n      // }\n    },\n    [handleTableFilterChange, searchValue],\n  )\n\n  const handleSearchChange = React.useCallback(\n    (value) => {\n      handleTableFilterChange({ keyword: value, type: tableTabValue })\n    },\n    [tableTabValue],\n  )\n  const { forexMap } = useSystem()\n\n  return {\n    campaignTagConfig: {} as any,\n    tableTabValue,\n    handleTabChange,\n    searchValue,\n    handleStartClick: (symbol: string, rowIdx) => {\n      if (favoriteMarket.includes(symbol)) {\n        removeMarket(symbol)\n      } else {\n        addMarket(symbol)\n      }\n      handleTableFilterChange({})\n    },\n    favoriteMarket,\n    handleSearchChange,\n    addFavoriteMarket: addMarket,\n    showLoading: !Object.keys(tickerMap ?? {})?.length,\n    // tickList,\n    rawData: filteredData,\n    currentheight: tableHeight,\n    onRowClick: handleRowClick,\n    account,\n    forexMap,\n    rowConfig,\n    handleTableFilterChange,\n    onItemClick: handleItemClick,\n  }\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/RedPacketPage/CreateRedPacketPanel/index.tsx",
    "content": "import { Box, Button } from '@mui/material'\nimport { CreateRedPacketPanel, LoadingBlock, useToggle } from '@loopring-web/component-lib'\n\nimport React from 'react'\nimport {\n  getIPFSString,\n  StylePaper,\n  useContacts,\n  useCreateRedPacket,\n  useSystem,\n} from '@loopring-web/core'\nimport {\n  BackIcon,\n  FeeInfo,\n  MY_NFT_VIEW,\n  NFTWholeINFO,\n  RedPacketOrderData,\n  TradeBtnStatus,\n  RouterPath,\n  RedPacketRouterIndex,\n} from '@loopring-web/common-resources'\nimport { useGetAssets } from '../../AssetPage/AssetPanel/hook'\nimport { useTranslation } from 'react-i18next'\nimport { useHistory, useLocation, useRouteMatch } from 'react-router-dom'\nimport { useNFTCollection } from '../../NFTPage/MyNFT/useMyNFT'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { MyNFTPanelUI } from '../../NFTPage/MyNFT'\n\nexport const ChooseNFTPanel = React.memo(\n  <NFT extends NFTWholeINFO>({\n    selectNFT,\n    onSelect,\n  }: {\n    selectNFT: NFT[]\n    onSelect: (value: NFT) => void\n  }) => {\n    const matchPreUrl = '/redPacket/create/'\n    const preMatch = useRouteMatch(`/redPacket/create/:tab?/:contract?`)\n    const { search } = useLocation()\n    const searchParam = new URLSearchParams(search)\n    const tabBy = preMatch?.params['tab'] ?? MY_NFT_VIEW.LIST_COLLECTION\n    const { toggle } = useToggle()\n    const contractStr = preMatch?.params['contract'] ?? ''\n    const filter = JSON.parse(\n      searchParam.get('filter') ??\n        JSON.stringify({\n          favourite: false,\n          hidden: false,\n        }),\n    )\n    const { collectionMeta } = useNFTCollection({ contractStr, matchPreUrl })\n\n    return (\n      <MyNFTPanelUI\n        tabBy={tabBy}\n        filter={\n          filter?.favourite\n            ? sdk.NFT_PREFERENCE_TYPE.fav\n            : filter?.hidden\n            ? sdk.NFT_PREFERENCE_TYPE.hide\n            : 'all'\n        }\n        collectionMeta={collectionMeta}\n        isMultipleSelect={false}\n        isSelect={true}\n        size={'small'}\n        selected={selectNFT}\n        onSelect={onSelect}\n        contractStr={preMatch?.params['contract'] ?? ''}\n        matchPreUrl={matchPreUrl}\n        toggle={toggle}\n      />\n    )\n  },\n)\nexport const CreateRedPacketUIPanel = <\n  T extends RedPacketOrderData<I>,\n  I extends any,\n  F extends FeeInfo,\n>() => {\n  const { assetsRawData, assetBtnStatus } = useGetAssets()\n  let match: any = useRouteMatch('/redPacket/:item')\n  const history = useHistory()\n  const { baseURL } = useSystem()\n  const { t } = useTranslation()\n  const { createRedPacketProps } = useCreateRedPacket<T, I, F>({\n    assetsRawData,\n    isShow: match?.params?.item?.toLowerCase() === 'create',\n  })\n\n  const { contacts, errorMessage: contactsErrorMessage, updateContacts } = useContacts()\n  React.useEffect(() => {\n    if (contactsErrorMessage) {\n      updateContacts()\n    }\n  }, [])\n  return (\n    <Box display={'flex'} flex={1} flexDirection={'column'}>\n      <Box display={'flex'} justifyContent={'space-between'} alignItems={'center'} marginBottom={2}>\n        <Button\n          startIcon={<BackIcon fontSize={'small'} />}\n          variant={'text'}\n          size={'medium'}\n          sx={{ color: 'var(--color-text-secondary)' }}\n          color={'inherit'}\n          onClick={() => history.push(`${RouterPath.redPacket}/${RedPacketRouterIndex.markets}`)}\n        >\n          {t('labelCreateRedPacketTitle')}\n        </Button>\n      </Box>\n      <StylePaper\n        style={{ backgroundColor: 'var(--color-pop-bg)' }}\n        flex={1}\n        display={'flex'}\n        justifyContent={'center'}\n      >\n        {assetBtnStatus === TradeBtnStatus.LOADING ? (\n          <LoadingBlock />\n        ) : (\n          <CreateRedPacketPanel\n            {...{\n              _height: 'auto',\n              ...createRedPacketProps,\n              tradeType: createRedPacketProps.tradeType,\n              getIPFSString: getIPFSString,\n              baseURL,\n              myNFTPanel: (\n                <ChooseNFTPanel\n                  onSelect={(value: any) => {\n                    createRedPacketProps.handleOnChoose &&\n                      createRedPacketProps.handleOnChoose(value)\n                  }}\n                  selectNFT={\n                    createRedPacketProps?.selectNFT ? [createRedPacketProps.selectNFT] : []\n                  }\n                />\n              ) as any,\n              contacts,\n            }}\n          />\n        )}\n      </StylePaper>\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/RedPacketPage/MyRedPacketPanel/hooks.ts",
    "content": "import { useTranslation } from 'react-i18next'\nimport {\n  amountStrCallback,\n  amountStrNFTCallback,\n  LoopringAPI,\n  useAccount,\n  useTokenMap,\n} from '@loopring-web/core'\nimport React from 'react'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport {\n  CLAIM_TYPE,\n  getShortAddr,\n  myLog,\n  SDK_ERROR_MAP_TO_UI,\n  TokenType,\n} from '@loopring-web/common-resources'\nimport {\n  AccountStep,\n  RawDataRedPacketReceivesItem,\n  RawDataRedPacketRecordsItem,\n  RedPacketViewStep,\n  ToastType,\n  useOpenModals,\n} from '@loopring-web/component-lib'\n\nexport const useMyRedPacketRecordTransaction = <R extends RawDataRedPacketRecordsItem>({\n  setToastOpen,\n}: // tabType,\n{\n  setToastOpen: (props: any) => void\n  // tabType: TabTokenTypeIndex;\n}) => {\n  const { t } = useTranslation(['error'])\n\n  const {\n    account: { accountId, apiKey },\n  } = useAccount()\n\n  const [myRedPacketRecordList, setMyRedPacketRecordList] = React.useState<R[]>([])\n  const { setShowRedPacket } = useOpenModals()\n  const { idIndex, coinMap, tokenMap } = useTokenMap()\n  const [myRedPacketRecordTotal, setMyRedPacketRecordTotal] = React.useState(0)\n  const [showLoading, setShowLoading] = React.useState(true)\n  // let match: any = useRouteMatch(\"/redPacket/records/?:item/?:type\");\n  const getMyRedPacketRecordTxList = React.useCallback(\n    async ({ offset, limit, filter }: any) => {\n      setShowLoading(true)\n      if (LoopringAPI.luckTokenAPI && accountId) {\n        if (apiKey) {\n          myLog('filterfilterfilterfilterfilter', filter)\n          const response = await LoopringAPI.luckTokenAPI.getLuckTokenLuckyTokens(\n            {\n              senderId: accountId,\n              scopes: '0,1,2',\n              partitions: '0,1',\n              statuses: '1,2,3,4',\n              official: false,\n              offset,\n              limit,\n              ...filter,\n            } as any,\n            apiKey,\n          )\n          if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n            const errorItem = SDK_ERROR_MAP_TO_UI[(response as sdk.RESULT_INFO)?.code ?? 700001]\n            if (setToastOpen) {\n              setToastOpen({\n                open: true,\n                type: ToastType.error,\n                content:\n                  'error : ' + errorItem\n                    ? t(errorItem.messageKey)\n                    : (response as sdk.RESULT_INFO).message,\n              })\n            }\n          } else {\n            setMyRedPacketRecordTotal((response as any)?.totalNum)\n            // @ts-ignore\n            let result = (response as any)?.list.reduce(\n              (prev: RawDataRedPacketRecordsItem[], item: sdk.LuckyTokenItemForReceive) => {\n                // const type = coinMap[idIndex[item.tokenId] ?? \"\"];\n                let remainAmount, totalAmount, tokenInfo\n                if (item.isNft) {\n                  tokenInfo = {\n                    ...item.nftTokenInfo,\n                    type: TokenType.nft,\n                    // icon:\n                  }\n                  totalAmount = amountStrNFTCallback(\n                    item.nftTokenInfo as any,\n                    item.tokenAmount.totalAmount ?? 0,\n                  ).amount\n                  remainAmount = amountStrNFTCallback(\n                    item.nftTokenInfo as any,\n                    item.tokenAmount.remainAmount ?? 0,\n                  ).amount\n                } else {\n                  const token = tokenMap[idIndex[item.tokenId]]\n                  tokenInfo = {\n                    ...coinMap[token.symbol ?? ''],\n                    name: token?.name,\n                    type: TokenType.single,\n                  }\n                  totalAmount = amountStrCallback(\n                    tokenMap,\n                    idIndex,\n                    item.tokenId,\n                    item.tokenAmount.totalAmount ?? 0,\n                  ).amount\n                  remainAmount = amountStrCallback(\n                    tokenMap,\n                    idIndex,\n                    item.tokenId,\n                    item.tokenAmount.remainAmount ?? 0,\n                  ).amount\n                }\n\n                prev.push({\n                  token: {\n                    ...tokenInfo,\n                  } as any,\n                  type: item.type, //sdk.LuckyTokenItemStatus\n                  status: item.status,\n                  validSince: item.validSince,\n                  validUntil: item.validUntil,\n                  totalCount: item.tokenAmount.totalCount,\n                  remainCount: item.tokenAmount.remainCount,\n                  totalAmount,\n                  remainAmount,\n                  createdAt: item.createdAt,\n                  rawData: item,\n                })\n                return prev\n              },\n              [] as RawDataRedPacketRecordsItem[],\n            )\n\n            setMyRedPacketRecordList(result)\n          }\n        }\n      }\n      setShowLoading(false)\n    },\n    [accountId, apiKey, setToastOpen, t, idIndex],\n  )\n  const onItemClick = async (item: sdk.LuckyTokenItemForReceive) => {\n    const resposne = await LoopringAPI.luckTokenAPI?.getLuckTokenDetail(\n      {\n        hash: item.hash,\n      },\n      apiKey,\n    )\n    if (resposne?.detail.luckyToken.type.mode === sdk.LuckyTokenClaimType.BLIND_BOX) {\n      if (\n        resposne?.detail.luckyToken.status === sdk.LuckyTokenItemStatus.PENDING &&\n        (resposne?.raw_data as any).blindBoxStatus === '' && \n        resposne?.detail.luckyToken.type.scope !== sdk.LuckyTokenViewType.TARGET\n      ) {\n        setShowRedPacket({\n          isShow: true,\n          info: {\n            ...item,\n            hash: item.hash,\n            serialNo: item.serialNo\n          },\n          step: RedPacketViewStep.OpenPanel,\n        })\n      } else {\n        setShowRedPacket({\n          isShow: true,\n          info: {\n            ...item,\n            hash: item.hash,\n            serialNo: item.serialNo\n          },\n          step: RedPacketViewStep.BlindBoxDetail,\n        })\n      }\n    } else {\n      if (\n        resposne?.detail.luckyToken.status === sdk.LuckyTokenItemStatus.PENDING &&\n        !resposne?.detail.claimStatus &&\n        resposne?.detail.luckyToken.type.scope !== sdk.LuckyTokenViewType.TARGET\n      ) {\n        setShowRedPacket({\n          isShow: true,\n          info: {\n            ...item,\n            hash: item.hash,\n            serialNo: item.serialNo\n          },\n          step: RedPacketViewStep.OpenPanel,\n        })\n      } else {\n        setShowRedPacket({\n          isShow: true,\n          info: {\n            ...item,\n            hash: item.hash,\n            serialNo: item.serialNo\n          },\n          step: RedPacketViewStep.DetailPanel,\n        })\n      }\n    }\n  }\n\n  return {\n    // page,\n    onItemClick,\n    myRedPacketRecordList,\n    showLoading,\n    getMyRedPacketRecordTxList,\n    myRedPacketRecordTotal,\n  }\n}\n\nexport const useMyRedPacketReceiveTransaction = <R extends RawDataRedPacketReceivesItem>({\n  setToastOpen,\n}: {\n  setToastOpen: (props: any) => void\n}) => {\n  const { t } = useTranslation(['error'])\n\n  const {\n    account: { accountId, apiKey, accAddress },\n  } = useAccount()\n\n  const [redPacketReceiveList, setRedPacketReceiveList] = React.useState<R[]>([])\n  const { setShowRedPacket, setShowClaimWithdraw } = useOpenModals()\n\n  const { idIndex, coinMap, tokenMap } = useTokenMap()\n  const [redPacketReceiveTotal, setRedPacketReceiveTotal] = React.useState(0)\n  const [showLoading, setShowLoading] = React.useState(true)\n  // let match: any = useRouteMatch(\"/redPacket/records/?:item/?:type\");\n\n  const getRedPacketReceiveList = React.useCallback(\n    async ({ offset, limit, filter }: any) => {\n      setShowLoading(true)\n      try {\n        if (LoopringAPI.luckTokenAPI && accountId) {\n          if (apiKey) {\n            const response = await LoopringAPI.luckTokenAPI.getLuckTokenClaimHistory(\n              {\n                offset,\n                limit,\n                ...filter,\n              } as any,\n              apiKey,\n            )\n            if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n              const errorItem = SDK_ERROR_MAP_TO_UI[(response as sdk.RESULT_INFO)?.code ?? 700001]\n              if (setToastOpen) {\n                setToastOpen({\n                  open: true,\n                  type: ToastType.error,\n                  content:\n                    'error : ' + errorItem\n                      ? t(errorItem.messageKey)\n                      : (response as sdk.RESULT_INFO).message,\n                })\n              }\n            } else {\n              setRedPacketReceiveTotal((response as any)?.totalNum)\n              // @ts-ignore\n              let result = (response as any)?.list.reduce(\n                (prev: R[], item: sdk.LuckTokenHistory) => {\n                  // @ts-ignore\n                  const { luckyToken, claim: myClaim } = item\n\n                  let amount, tokenInfo\n                  if (luckyToken.isNft) {\n                    amount = amountStrNFTCallback(\n                      luckyToken.nftTokenInfo as any,\n                      myClaim?.amount?.toString() ?? 0,\n                    ).amount\n                    tokenInfo = {\n                      ...luckyToken.nftTokenInfo,\n                      type: TokenType.nft,\n                    }\n                  } else {\n                    const token = tokenMap[idIndex[luckyToken.tokenId]]\n                    tokenInfo = {\n                      ...coinMap[token.symbol ?? ''],\n                      name: token.name,\n                      type: TokenType.single,\n                    }\n                    amount = amountStrCallback(\n                      tokenMap,\n                      idIndex,\n                      luckyToken.tokenId,\n                      myClaim?.amount?.toString() ?? 0,\n                    ).amount\n                  }\n\n                  prev.push()\n                  return [\n                    ...prev,\n                    {\n                      token: {\n                        ...tokenInfo,\n                      } as any,\n                      amount,\n                      type: luckyToken.type, //sdk.LuckyTokenItemStatus\n                      status: luckyToken.status,\n                      claimAt: myClaim?.createdAt,\n                      sender: luckyToken?.sender?.ens\n                        ? luckyToken?.sender?.ens\n                        : getShortAddr(luckyToken?.sender?.address),\n                      rawData: item,\n                    },\n                  ]\n                },\n                [] as R[],\n              )\n\n              setRedPacketReceiveList(result)\n            }\n          }\n        }\n      } finally {\n        setShowLoading(false)\n      }\n    },\n    [accountId, apiKey, setToastOpen, t, idIndex],\n  )\n\n  const onItemClick = (item: sdk.LuckTokenHistory) => {\n    if (item.luckyToken.type.mode === sdk.LuckyTokenClaimType.BLIND_BOX) {\n      setShowRedPacket({\n        isShow: true,\n        step: RedPacketViewStep.BlindBoxDetail,\n        info: {\n          ...item.luckyToken,\n          serialNo: item.claim.serialNo\n        },\n      })\n    } else {\n      setShowRedPacket({\n        isShow: true,\n        step: RedPacketViewStep.DetailPanel,\n        info: {\n          ...item.luckyToken,\n          serialNo: item.claim.serialNo\n        },\n      })\n    }\n  }\n  const onClaimItem = async (item: sdk.LuckTokenHistory) => {\n    const response = await LoopringAPI.luckTokenAPI?.getLuckTokenBalances(\n      {\n        accountId: accountId,\n        isNft: item.luckyToken.isNft,\n        tokens: [item.luckyToken.tokenId],\n      },\n      apiKey,\n    )\n    if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n      const errorItem = SDK_ERROR_MAP_TO_UI[(response as sdk.RESULT_INFO)?.code ?? 700001]\n      if (setToastOpen) {\n        setToastOpen({\n          open: true,\n          type: ToastType.error,\n          content:\n            'error : ' + errorItem\n              ? t(errorItem.messageKey)\n              : (response as sdk.RESULT_INFO).message,\n        })\n      }\n    } else {\n      setShowClaimWithdraw({\n        isShow: true,\n        claimToken: {\n          tokenId: item.luckyToken.tokenId,\n          total: item.claim.amount.toString(),\n          locked: response!.tokenBalance[0].locked,\n          pending: response!.tokenBalance[0].pending,\n          nftTokenInfo: item.luckyToken.nftTokenInfo,\n          isNft: item.luckyToken.isNft,\n          luckyTokenHash: item.luckyToken.hash,\n        },\n        claimType: CLAIM_TYPE.redPacket,\n      })\n    }\n  }\n  return {\n    onItemClick,\n    redPacketReceiveList,\n    showLoading,\n    getRedPacketReceiveList,\n    redPacketReceiveTotal,\n    onClaimItem,\n  }\n}\n\nexport const useMyRedPacketBlindBoxReceiveTransaction = <R extends RawDataRedPacketReceivesItem>({\n  setToastOpen,\n}: // showActionableRecords\n{\n  setToastOpen: (props: any) => void\n  // showActionableRecords: boolean\n}) => {\n  const { t } = useTranslation(['error'])\n\n  const {\n    account: { accountId, apiKey, eddsaKey, accAddress },\n  } = useAccount()\n\n  const [redPacketReceiveList, setRedPacketReceiveList] = React.useState<R[]>([])\n  const { setShowRedPacket, setShowAccount } = useOpenModals()\n\n  const { idIndex, coinMap, tokenMap } = useTokenMap()\n  const [redPacketReceiveTotal, setRedPacketReceiveTotal] = React.useState(0)\n  const [showLoading, setShowLoading] = React.useState(true)\n  // let match: any = useRouteMatch(\"/redPacket/records/?:item/?:type\");\n\n  const getRedPacketReceiveList = React.useCallback(\n    async ({ offset, limit, filter }: any) => {\n      const _filer = {\n        ...filter,\n        // statuses: showActionableRecords\n        //   ? [sdk.BlindBoxStatus.NOT_OPENED]\n        //   : undefined\n      }\n      setShowLoading(true)\n      try {\n        if (LoopringAPI.luckTokenAPI && accountId) {\n          if (apiKey) {\n            const response = await LoopringAPI.luckTokenAPI.getLuckTokenClaimedBlindBox(\n              {\n                offset,\n                limit,\n                isNft: true,\n                ..._filer,\n              } as any,\n              apiKey,\n            )\n            if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n              const errorItem = SDK_ERROR_MAP_TO_UI[(response as sdk.RESULT_INFO)?.code ?? 700001]\n              if (setToastOpen) {\n                setToastOpen({\n                  open: true,\n                  type: ToastType.error,\n                  content:\n                    'error : ' + errorItem\n                      ? t(errorItem.messageKey)\n                      : (response as sdk.RESULT_INFO).message,\n                })\n              }\n            } else {\n              setRedPacketReceiveTotal((response as any)?.totalNum)\n              let result = (response as any)?.list.map(\n                (item: sdk.LuckyTokenBlindBoxItemReceive) => {\n                  // @ts-ignore\n                  const { luckyToken, claim: myClaim } = item\n                  let tokenInfo\n                  if (!luckyToken.isNft) {\n                    const token = tokenMap[idIndex[luckyToken.tokenId]]\n                    tokenInfo = {\n                      ...coinMap[token.symbol ?? ''],\n                      name: token.name,\n                      type: TokenType.single,\n                      decimals: token.decimals,\n                      precision: token.precision,\n                    }\n                  }\n                  return {\n                    type: luckyToken.type,\n                    status: luckyToken.status,\n                    claimAt: myClaim?.createdAt,\n                    sender: luckyToken?.sender?.ens\n                      ? luckyToken?.sender?.ens\n                      : getShortAddr(luckyToken?.sender?.address),\n                    rawData: item,\n                    token: tokenInfo,\n                  }\n                },\n              )\n\n              setRedPacketReceiveList(result)\n            }\n          }\n        }\n      } finally {\n        setShowLoading(false)\n      }\n    },\n    [accountId, apiKey, setToastOpen, t, idIndex],\n  )\n\n  const onItemClick = async (item: sdk.LuckyTokenBlindBoxItemReceive) => {\n    setShowRedPacket({\n      isShow: true,\n      step: RedPacketViewStep.BlindBoxDetail,\n      info: {\n        ...item.luckyToken,\n        serialNo: item.claim.serialNo\n      },\n    })\n  }\n  \n  const onItemClickOpen = async (\n    item: sdk.LuckyTokenBlindBoxItemReceive,\n    pageInfo?: {\n      offset: number\n      limit: number\n      filter: any\n    },\n  ) => {\n    if (LoopringAPI.luckTokenAPI && accountId) {\n      const response = await LoopringAPI.luckTokenAPI.sendLuckTokenClaimLuckyToken({\n        request: {\n          hash: item.luckyToken.hash,\n          serialNo: item.claim.serialNo,\n          claimer: accAddress,\n          referrer: '',\n        },\n        apiKey,\n        eddsaKey: eddsaKey.sk,\n      })\n      if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n        setShowAccount({\n          isShow: true,\n          step: AccountStep.ClaimWithdraw_Failed,\n          error: {\n            code: (response as sdk.RESULT_INFO).code,\n            message: (response as sdk.RESULT_INFO).message,\n          },\n        })\n        return\n      }\n      setShowRedPacket({\n        isShow: true,\n        step: RedPacketViewStep.BlindBoxDetail,\n        info: {\n          ...item.luckyToken,\n          serialNo: item.claim.serialNo,\n        },\n      })\n      getRedPacketReceiveList(pageInfo)\n    }\n  }\n  return {\n    onItemClick,\n    onItemClickOpen,\n    redPacketReceiveList,\n    showLoading,\n    getRedPacketReceiveList,\n    redPacketReceiveTotal,\n  }\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/RedPacketPage/MyRedPacketPanel/index.tsx",
    "content": "import { useTheme } from '@emotion/react'\nimport { useHistory, useRouteMatch } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport {\n  RedPacketReceiveTable,\n  RedPacketRecordTable,\n  useSettings,\n  RedPacketBlindBoxReceiveTable,\n} from '@loopring-web/component-lib'\nimport { ClaimCommands, claimServices, redpacketService, StylePaper, useSystem } from '@loopring-web/core'\nimport React from 'react'\nimport {\n  useMyRedPacketBlindBoxReceiveTransaction,\n  useMyRedPacketReceiveTransaction,\n  useMyRedPacketRecordTransaction,\n} from './hooks'\nimport {\n  BackIcon,\n  RedPacketRouterIndex,\n  RouterPath,\n  TokenType,\n  RedPacketRecordsTabIndex,\n  AssetTabIndex,\n} from '@loopring-web/common-resources'\nimport { Box, Button, Checkbox, FormControlLabel, Tab, Tabs, Typography } from '@mui/material'\nimport styled from '@emotion/styled'\nimport { useNotify } from '@loopring-web/core'\n\nconst SelectButton = styled(Button)<{ selected?: boolean }>`\n  color: ${({ selected, theme }) => (selected ? theme.colorBase.textPrimary : 'auto')};\n  border-color: ${({ selected, theme }) => (selected ? theme.colorBase.borderHover : 'auto')};\n  background-color: transparent;\n  :hover {\n    background-color: transparent;\n    border-color: ${({ selected, theme }) => theme.colorBase.borderHover};\n  }\n`\n\nexport const MyRedPacketPanel = ({ setToastOpen }: { setToastOpen: (props: any) => void }) => {\n  const theme = useTheme()\n  const history = useHistory()\n  const { t } = useTranslation()\n  const { isMobile } = useSettings()\n  const { etherscanBaseUrl, forexMap } = useSystem()\n  let match: any = useRouteMatch('/redPacket/records/:item/:type?')\n\n  const container = React.useRef<HTMLDivElement>(null)\n  const [currentTab, setCurrentTab] = React.useState<RedPacketRecordsTabIndex>(\n    match?.params.item ?? RedPacketRecordsTabIndex.Received,\n  )\n  const isUnClaimed =\n    currentTab === RedPacketRecordsTabIndex.BlindBoxUnClaimed ||\n    currentTab === RedPacketRecordsTabIndex.NFTsUnClaimed\n  const pageSize = 10\n\n  const {\n    showLoading: showloadingRecord,\n    getMyRedPacketRecordTxList,\n    myRedPacketRecordList,\n    myRedPacketRecordTotal,\n    onItemClick,\n  } = useMyRedPacketRecordTransaction({\n    setToastOpen,\n  })\n\n  const [showActionableRecords, setShowActionableRecords] = React.useState(true)\n  const onChangeShowActionableRecords = React.useCallback(() => {\n    setShowActionableRecords(!showActionableRecords)\n  }, [showActionableRecords])\n  const {\n    showLoading: showloadingReceive,\n    getRedPacketReceiveList,\n    redPacketReceiveList,\n    redPacketReceiveTotal,\n    onItemClick: onReceiveItemClick,\n    onClaimItem: onReceiveClaimItem,\n  } = useMyRedPacketReceiveTransaction({\n    setToastOpen,\n    // showActionableRecords\n  })\n  const {\n    showLoading: showloadingReceive_BlindBox,\n    getRedPacketReceiveList: getRedPacketReceiveList_BlindBox,\n    redPacketReceiveList: redPacketReceiveList_BlindBox,\n    redPacketReceiveTotal: redPacketReceiveTotal_BlindBox,\n    onItemClick: onReceiveItemClick_BlindBox,\n    onItemClickOpen: onReceiveItemClickOpen_BlindBox,\n  } = useMyRedPacketBlindBoxReceiveTransaction({\n    setToastOpen,\n    // showActionableRecords\n  })\n  const handleTabChange = (value: RedPacketRecordsTabIndex) => {\n    history.push(`/redPacket/records/${value}`)\n    setCurrentTab(value)\n  }\n\n  const isRecieve = [\n    RedPacketRecordsTabIndex.Received,\n    RedPacketRecordsTabIndex.BlindBoxReceived,\n    RedPacketRecordsTabIndex.NFTReceived,\n    RedPacketRecordsTabIndex.BlindBoxUnClaimed,\n    RedPacketRecordsTabIndex.NFTsUnClaimed,\n  ].includes(currentTab)\n  const tabType = [RedPacketRecordsTabIndex.Received, RedPacketRecordsTabIndex.Send].includes(\n    currentTab,\n  )\n    ? 'tokens'\n    : [RedPacketRecordsTabIndex.NFTReceived, RedPacketRecordsTabIndex.NFTSend].includes(currentTab)\n    ? 'NFTs'\n    : 'blindBox'\n\n  const showNFT = useNotify().notifyMap?.redPacket.showNFT\n  const tabsView = isUnClaimed ? (\n    <Tabs\n      value={currentTab}\n      onChange={(_event, value) => {\n        handleTabChange(value)\n      }}\n      aria-label='l2-history-tabs'\n      variant='scrollable'\n    >\n      <Tab\n        key={'NFTs'}\n        label={t('labelRedPacketTabNFTs')}\n        value={RedPacketRecordsTabIndex.NFTsUnClaimed}\n      />\n      <Tab\n        key={'Blind Box'}\n        label={t('labelRedPacketTabBlindBox')}\n        value={RedPacketRecordsTabIndex.BlindBoxUnClaimed}\n      />\n    </Tabs>\n  ) : (\n    <>\n      <Tabs\n        value={isRecieve ? 'Received' : 'Sent'}\n        onChange={(_event, value) => {\n          if (tabType === 'tokens' && value === 'Received') {\n            handleTabChange(RedPacketRecordsTabIndex.Received)\n          } else if (tabType === 'tokens' && value === 'Sent') {\n            handleTabChange(RedPacketRecordsTabIndex.Send)\n          } else if (tabType === 'NFTs' && value === 'Received') {\n            handleTabChange(RedPacketRecordsTabIndex.NFTReceived)\n          } else if (tabType === 'NFTs' && value === 'Sent') {\n            handleTabChange(RedPacketRecordsTabIndex.NFTSend)\n          } else if (tabType === 'blindBox' && value === 'Received') {\n            handleTabChange(RedPacketRecordsTabIndex.BlindBoxReceived)\n          } else if (tabType === 'blindBox' && value === 'Sent') {\n            handleTabChange(RedPacketRecordsTabIndex.BlindBoxSend)\n          }\n        }}\n        aria-label='l2-history-tabs'\n        variant='scrollable'\n      >\n        <Tab key={'Received'} label={t('labelRedPacketTabReceived')} value={'Received'} />\n        <Tab key={'Sent'} label={t('labelRedPacketTabSent')} value={'Sent'} />\n      </Tabs>\n      <Box paddingX={2} marginTop={3} display={'flex'} justifyContent='space-between'>\n        <Box>\n          <SelectButton\n            onClick={() => {\n              isRecieve\n                ? handleTabChange(RedPacketRecordsTabIndex.Received)\n                : handleTabChange(RedPacketRecordsTabIndex.Send)\n            }}\n            selected={[RedPacketRecordsTabIndex.Send, RedPacketRecordsTabIndex.Received].includes(\n              currentTab,\n            )}\n            style={{ marginRight: `${theme.unit}px` }}\n            variant={'outlined'}\n          >\n            {t('labelRedpacketTokensShort')}\n          </SelectButton>\n          {showNFT && (\n            <>\n              <SelectButton\n                onClick={() => {\n                  isRecieve\n                    ? handleTabChange(RedPacketRecordsTabIndex.NFTReceived)\n                    : handleTabChange(RedPacketRecordsTabIndex.NFTSend)\n                }}\n                selected={[\n                  RedPacketRecordsTabIndex.NFTReceived,\n                  RedPacketRecordsTabIndex.NFTSend,\n                ].includes(currentTab)}\n                style={{ marginRight: `${theme.unit}px` }}\n                variant={'outlined'}\n              >\n                {t('labelRedpacketNFTS')}\n              </SelectButton>\n\n              <SelectButton\n                onClick={() => {\n                  isRecieve\n                    ? handleTabChange(RedPacketRecordsTabIndex.BlindBoxReceived)\n                    : handleTabChange(RedPacketRecordsTabIndex.BlindBoxSend)\n                }}\n                selected={[\n                  RedPacketRecordsTabIndex.BlindBoxReceived,\n                  RedPacketRecordsTabIndex.BlindBoxSend,\n                ].includes(currentTab)}\n                variant={'outlined'}\n              >\n                {t('labelRedpacketBlindBox')}\n              </SelectButton>\n            </>\n          )}\n        </Box>\n        {isRecieve && (tabType === 'NFTs' || tabType === 'blindBox') && (\n          <FormControlLabel\n            control={\n              <Checkbox\n                checked={showActionableRecords}\n                onChange={() => {\n                  onChangeShowActionableRecords()\n                }}\n              />\n            }\n            label={t('labelRedpacketHideInactionable')}\n          />\n        )}\n      </Box>\n    </>\n  )\n  const [pageReceive, setReceivePage] = React.useState(1)\n  const [pageBlindBox, setBlindBoxPage] = React.useState(1)\n\n  const onRefresh = React.useCallback(async () => {\n    if ([RedPacketRecordsTabIndex.NFTsUnClaimed, RedPacketRecordsTabIndex.NFTReceived, RedPacketRecordsTabIndex.NFTSend].includes(currentTab)) {\n      await getRedPacketReceiveList({\n        offset: (pageReceive - 1) * (pageSize ?? 12),\n        limit: pageSize ?? 12,\n        filter: {\n          statuses: showActionableRecords ? [0] : undefined,\n          isNft: true,\n        },\n      })\n    } else if ([RedPacketRecordsTabIndex.BlindBoxReceived, RedPacketRecordsTabIndex.BlindBoxUnClaimed].includes(currentTab)) {\n      getRedPacketReceiveList_BlindBox({ \n        offset: (pageReceive - 1) * (pageSize ?? 12),\n        limit: pageSize ?? 12,\n        filter: {\n          statuses: showActionableRecords ? [0] : undefined,\n          isNft: true,\n        },\n      })\n    }\n  }, [currentTab])\n\n  const claimeSubject = React.useMemo(() => claimServices.onSocket(), [])\n  React.useEffect(() => {\n    const subscription = claimeSubject.subscribe((props) => {\n      switch (props.status) {\n        case ClaimCommands.Success: {\n          onRefresh()\n          break\n        }\n        default:\n          break\n      }\n    })\n    return () => {\n      subscription.unsubscribe()\n    }\n  }, [claimeSubject])\n\n  const subject = React.useMemo(() => redpacketService.onRefresh(), [])\n  React.useEffect(() => {\n    const subscription = subject.subscribe(() => {\n      onRefresh()\n    })\n    return () => {\n      subscription.unsubscribe()\n    }\n  }, [subject])\n\n  return (\n    <Box\n      flex={1}\n      display={'flex'}\n      flexDirection={'column'}\n      sx={isMobile ? { maxWidth: 'calc(100vw - 32px)' } : {}}\n    >\n      <Box display={'flex'} flexDirection={isMobile ? 'column' : 'row'} marginBottom={2}>\n        <Button\n          startIcon={<BackIcon fontSize={'small'} />}\n          variant={'text'}\n          size={'medium'}\n          sx={{ color: 'var(--color-text-secondary)' }}\n          color={'inherit'}\n          onClick={() => {\n            if (isUnClaimed) {\n              history.push(`${RouterPath.l2assetsDetail}/${AssetTabIndex.RedPacket}`)\n            } else {\n              history.push(`${RouterPath.redPacket}/${RedPacketRouterIndex.markets}`)\n            }\n          }}\n        >\n          {isUnClaimed ? t('labelViewMore') : t('labelRedPacketRecordTitle')}\n        </Button>\n      </Box>\n\n      <StylePaper overflow={'auto'} ref={container} flex={1}>\n        {tabsView}\n        {[\n          RedPacketRecordsTabIndex.Received,\n          RedPacketRecordsTabIndex.NFTReceived,\n          RedPacketRecordsTabIndex.NFTsUnClaimed,\n        ].includes(currentTab) && (\n          <Box\n            className='tableWrapper table-divide-short'\n            display={'flex'}\n            flexDirection={'column'}\n            flex={1}\n          >\n            {currentTab == RedPacketRecordsTabIndex.NFTReceived && isUnClaimed && (\n              <Typography component={'h4'} paddingX={2} variant={'body1'} color={'textSecondary'}>\n                {t('labelNFTRedPackAskClaim')}\n              </Typography>\n            )}\n            <RedPacketReceiveTable\n              {...{\n                tokenType:\n                  currentTab === RedPacketRecordsTabIndex.NFTReceived ||\n                  currentTab === RedPacketRecordsTabIndex.NFTSend ||\n                  currentTab === RedPacketRecordsTabIndex.NFTsUnClaimed\n                    ? TokenType.nft\n                    : TokenType.single,\n                page: pageReceive,\n                setPage: setReceivePage,\n                onItemClick: onReceiveItemClick,\n                onClaimItem: onReceiveClaimItem,\n                showloading: showloadingReceive,\n                forexMap,\n                etherscanBaseUrl,\n                rawData: redPacketReceiveList,\n                getRedPacketReceiveList,\n                pagination: {\n                  pageSize: pageSize,\n                  total: redPacketReceiveTotal,\n                },\n                showActionableRecords,\n                isUncliamedNFT: currentTab === RedPacketRecordsTabIndex.NFTsUnClaimed,\n              }}\n            />\n          </Box>\n        )}\n        {[\n          RedPacketRecordsTabIndex.BlindBoxReceived,\n          RedPacketRecordsTabIndex.BlindBoxUnClaimed,\n        ].includes(currentTab) && (\n          <Box\n            className='tableWrapper table-divide-short'\n            display={'flex'}\n            flexDirection={'column'}\n            flex={1}\n          >\n            <RedPacketBlindBoxReceiveTable\n              onItemClick={onReceiveItemClick_BlindBox}\n              onItemClickOpen={onReceiveItemClickOpen_BlindBox}\n              showloading={showloadingReceive_BlindBox}\n              forexMap={forexMap}\n              etherscanBaseUrl={etherscanBaseUrl}\n              rawData={redPacketReceiveList_BlindBox}\n              getRedPacketReceiveList={getRedPacketReceiveList_BlindBox}\n              pagination={{\n                pageSize: pageSize,\n                total: redPacketReceiveTotal_BlindBox,\n              }}\n              page={pageBlindBox}\n              setPage={setBlindBoxPage}\n              showActionableRecords={showActionableRecords}\n              isUnclaimed={currentTab === RedPacketRecordsTabIndex.BlindBoxUnClaimed}\n            />\n          </Box>\n        )}\n        {[\n          RedPacketRecordsTabIndex.Send,\n          RedPacketRecordsTabIndex.NFTSend,\n          RedPacketRecordsTabIndex.BlindBoxSend,\n        ].includes(currentTab) && (\n          <Box className='tableWrapper table-divide-short'>\n            <RedPacketRecordTable\n              {...{\n                tokenType: /nft/gi.test(currentTab) ? TokenType.nft : TokenType.single,\n                showloading: showloadingRecord,\n                etherscanBaseUrl,\n                forexMap,\n                rawData: myRedPacketRecordList,\n                getMyRedPacketRecordTxList,\n                pagination: {\n                  pageSize: pageSize,\n                  total: myRedPacketRecordTotal,\n                },\n                onItemClick,\n                tableType:\n                  currentTab === RedPacketRecordsTabIndex.Send\n                    ? 'token'\n                    : currentTab === RedPacketRecordsTabIndex.NFTSend\n                    ? 'NFT'\n                    : 'blindbox',\n              }}\n            />\n          </Box>\n        )}\n      </StylePaper>\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/RedPacketPage/RedPacketClaimPanel/hooks.ts",
    "content": "import {\n  RawDataNFTRedPacketClaimItem,\n  RawDataRedPacketClaimItem,\n  ToastType,\n  useOpenModals,\n} from '@loopring-web/component-lib'\nimport { useTranslation } from 'react-i18next'\nimport {\n  amountStrCallback,\n  amountStrNFTCallback,\n  LoopringAPI,\n  useAccount,\n  useTokenMap,\n  useTokenPrices,\n  volumeToCountAsBigNumber,\n} from '@loopring-web/core'\nimport React from 'react'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport {\n  CLAIM_TYPE,\n  ClaimToken,\n  RedPacketLimit,\n  RouterPath,\n  SDK_ERROR_MAP_TO_UI,\n  TokenType,\n  RedPacketRouterIndex,\n  RedPacketRecordsTabIndex,\n} from '@loopring-web/common-resources'\nimport { useHistory } from 'react-router-dom'\n\nexport const useClaimRedPacket = <R extends RawDataRedPacketClaimItem>(\n  setToastOpen: (props: any) => void,\n) => {\n  const { t } = useTranslation(['error'])\n\n  const {\n    account: { accountId, apiKey },\n  } = useAccount()\n\n  const [redPacketClaimList, setRedPacketClaimList] = React.useState<R[]>([])\n  const [redPacketClaimTotal, setRedPacketClaimTotal] = React.useState(0)\n  const { idIndex, coinMap, tokenMap } = useTokenMap()\n  const { tokenPrices } = useTokenPrices()\n  const [showLoading, setShowLoading] = React.useState(true)\n  const { setShowClaimWithdraw } = useOpenModals()\n  const getClaimRedPacket = React.useCallback(async () => {\n    setShowLoading(true)\n    if (LoopringAPI.luckTokenAPI && accountId && apiKey) {\n      const response = await LoopringAPI.luckTokenAPI.getLuckTokenBalances(\n        {\n          accountId,\n          tokens: Reflect.ownKeys(idIndex ?? {}).map((key) => Number(key)),\n        },\n        apiKey,\n      )\n      if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n        const errorItem = SDK_ERROR_MAP_TO_UI[(response as sdk.RESULT_INFO)?.code ?? 700001]\n        if (setToastOpen) {\n          setToastOpen({\n            open: true,\n            type: ToastType.error,\n            content:\n              'error : ' + errorItem\n                ? t(errorItem.messageKey)\n                : (response as sdk.RESULT_INFO).message,\n          })\n        }\n      } else {\n        setRedPacketClaimTotal((response as any)?.totalNum)\n        // @ts-ignore\n        let result = (response as any)?.tokenBalance.reduce(\n          (prev: R[], item: sdk.UserBalanceInfo & any) => {\n            const token = tokenMap[idIndex[item.tokenId]]\n            const tokenInfo = coinMap[token.symbol ?? '']\n            const amountStr = amountStrCallback(tokenMap, idIndex, item.tokenId, item.total).amount\n\n            const volume =\n              volumeToCountAsBigNumber(token.symbol, item.total)\n                ?.times(tokenPrices[token.symbol ?? ''])\n                .toNumber() ?? 0\n            const _item: R = {\n              token: { ...tokenInfo, type: TokenType.single } as any,\n              amountStr,\n              volume,\n              rawData: item,\n            } as R\n            prev.push(_item)\n            return prev\n          },\n          [] as R[],\n        )\n\n        setRedPacketClaimList(result)\n      }\n    }\n    setShowLoading(false)\n  }, [accountId, apiKey, t, idIndex])\n  const onItemClick = (item: ClaimToken) => {\n    setShowClaimWithdraw({\n      isShow: true,\n      claimToken: {\n        ...item,\n      },\n      claimType: CLAIM_TYPE.redPacket,\n    })\n  }\n  const [showNFTsPanel, setShowNFTsPanel] = React.useState(false)\n  const history = useHistory()\n  const onViewMoreClick = (type: 'NFTs' | 'blindbox') => {\n    if (type === 'NFTs') {\n      history.push(\n        `${RouterPath.redPacket}/${RedPacketRouterIndex.records}/${RedPacketRecordsTabIndex.NFTsUnClaimed}`,\n      )\n    } else {\n      history.push(\n        `${RouterPath.redPacket}/${RedPacketRouterIndex.records}/${RedPacketRecordsTabIndex.BlindBoxUnClaimed}`,\n      )\n    }\n  }\n  const onCloseNFts = () => {\n    setShowNFTsPanel(false)\n  }\n\n  return {\n    onViewMoreClick,\n    onItemClick,\n    redPacketClaimList,\n    showLoading,\n    redPacketClaimTotal,\n    getClaimRedPacket,\n    showNFTsPanel,\n    onCloseNFts,\n  }\n}\n\nexport const useClaimNFTRedPacket = <R extends RawDataNFTRedPacketClaimItem>({\n  setToastOpen,\n}: {\n  setToastOpen: (props: any) => void\n}) => {\n  const { t } = useTranslation(['error'])\n\n  const {\n    account: { accountId, apiKey },\n  } = useAccount()\n\n  const [redPacketNFTClaimList, setNFTRedPacketClaimList] = React.useState<R[]>([])\n\n  const [page, setPage] = React.useState(1)\n  const [total, setTotal] = React.useState(0)\n\n  const [showLoading, setShowLoading] = React.useState(true)\n  const { setShowClaimWithdraw } = useOpenModals()\n  const getClaimNFTRedPacket = React.useCallback(\n    async ({ offset = 0, limit = RedPacketLimit, filter }: any) => {\n      setShowLoading(true)\n      if (LoopringAPI.luckTokenAPI && accountId && apiKey) {\n        const response = await LoopringAPI.luckTokenAPI.getLuckTokenBalances(\n          {\n            accountId,\n            isNft: true,\n            offset,\n            limit,\n          },\n          apiKey,\n        )\n        if ((response as sdk.RESULT_INFO).code || (response as sdk.RESULT_INFO).message) {\n          const errorItem = SDK_ERROR_MAP_TO_UI[(response as sdk.RESULT_INFO)?.code ?? 700001]\n          if (setToastOpen) {\n            setToastOpen({\n              open: true,\n              type: ToastType.error,\n              content:\n                'error : ' + errorItem\n                  ? t(errorItem.messageKey)\n                  : (response as sdk.RESULT_INFO).message,\n            })\n          }\n        } else {\n          setTotal((response as any)?.totalNum)\n          setPage(Number(1 + (offset / limit).toFixed()))\n          // @ts-ignore\n          let result = (response as any).tokenBalance?.reduce(\n            (prev: R[], item: sdk.UserBalanceInfo & { nftTokenInfo: any }) => {\n              const amountStr = amountStrNFTCallback(item?.nftTokenInfo as any, item.total).amount\n\n              // const volume = item.total;\n              const _item = {\n                token: { ...item.nftTokenInfo, type: TokenType.nft },\n                amountStr,\n                volume: 0,\n                rawData: item,\n              } as unknown as R\n              prev.push(_item)\n              return prev\n            },\n            [] as R[],\n          )\n\n          setNFTRedPacketClaimList(result)\n        }\n      }\n      setShowLoading(false)\n    },\n    [accountId, apiKey, t],\n  )\n  const onItemClick = (item: ClaimToken) => {\n    setShowClaimWithdraw({\n      isShow: true,\n      claimToken: {\n        ...item,\n      },\n      claimType: CLAIM_TYPE.redPacket,\n    })\n  }\n\n  return {\n    page,\n    onItemClick,\n    redPacketNFTClaimList,\n    showLoading,\n    redPacketNFTClaimTotal: total,\n    getClaimNFTRedPacket,\n  }\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/RedPacketPage/RedPacketClaimPanel/index.tsx",
    "content": "import React from 'react'\nimport {\n  LoopringAPI,\n  StylePaper,\n  useAccount,\n  useSystem,\n  useTargetRedPackets,\n  useToast,\n  useTokenMap,\n  useWalletLayer2,\n} from '@loopring-web/core'\nimport {\n  CoinIcons,\n  Modal,\n  NftImageStyle,\n  RedPacketClaimTable,\n  RedPacketViewStep,\n  Toast,\n  ToastType,\n  TransactionTradeViews,\n  useOpenModals,\n  useSettings,\n} from '@loopring-web/component-lib'\nimport { useTranslation } from 'react-i18next'\nimport { useHistory, useRouteMatch } from 'react-router-dom'\nimport { useClaimNFTRedPacket, useClaimRedPacket } from './hooks'\nimport {\n  Box,\n  Button,\n  Dialog,\n  DialogContent,\n  DialogTitle,\n  IconButton,\n  Tooltip,\n  Typography,\n} from '@mui/material'\nimport {\n  CloseIcon,\n  RecordTabIndex,\n  RedPacketColorConfig,\n  RedPacketIcon,\n  SagaStatus,\n  TOAST_TIME,\n  TokenType,\n  RouterPath,\n  RedPacketRouterIndex,\n} from '@loopring-web/common-resources'\nimport { LuckyTokenClaimType, LuckyTokenItemForReceive, SoursURL } from '@loopring-web/loopring-sdk'\nimport styled from '@emotion/styled'\nimport { useTheme } from '@emotion/react'\n\nconst RedPacktButton = styled(Button)`\n  background: ${RedPacketColorConfig.default.btnColor};\n  :hover {\n    background: ${RedPacketColorConfig.default.btnColor};\n    opacity: 0.7;\n  }\n`\n\nexport const RedPacketClaimPanel = ({ hideAssets }: { hideAssets?: boolean }) => {\n  const container = React.useRef<HTMLDivElement>(null)\n  const { etherscanBaseUrl, forexMap } = useSystem()\n  const { toastOpen, setToastOpen, closeToast } = useToast()\n  const { status: walletLayer2Status } = useWalletLayer2()\n  const { t } = useTranslation()\n  const { isMobile } = useSettings()\n  const history = useHistory()\n\n  const {\n    redPacketClaimList,\n    showNFTsPanel,\n    showLoading,\n    getClaimRedPacket,\n    onItemClick,\n    onViewMoreClick,\n    onCloseNFts,\n  } = useClaimRedPacket(setToastOpen)\n  const {\n    onItemClick: onItemNFTClick,\n    redPacketNFTClaimList,\n    showLoading: showNFTLoading,\n    getClaimNFTRedPacket,\n  } = useClaimNFTRedPacket({ setToastOpen })\n  const {\n    redPackets: exclusiveRedPackets,\n    setShowRedPacketsPopup\n  } = useTargetRedPackets()\n  React.useEffect(() => {\n    if (getClaimRedPacket && walletLayer2Status === SagaStatus.UNSET) {\n      getClaimRedPacket()\n    }\n  }, [walletLayer2Status, exclusiveRedPackets?.length])\n\n  const { account } = useAccount()\n  const [totalLuckyTokenNFTBalance, setTotalLuckyTokenNFTBalance] = React.useState(\n    undefined as number | undefined,\n  )\n  const [blindboxBalance, setBlindboxBalance] = React.useState(undefined as number | undefined)\n\n  \n  const { setShowRedPacket, setShowTargetRedpacketPop } = useOpenModals()\n\n  React.useEffect(() => {\n    LoopringAPI.luckTokenAPI\n      ?.getLuckTokenClaimHistory(\n        {\n          isNft: true,\n          // @ts-ignore\n          statuses: '0',\n        },\n        account.apiKey,\n      )\n      .then((response) => {\n        const sum = response.list?.reduce((acc, cur) => acc + Number(cur.claim.amount), 0)\n        setTotalLuckyTokenNFTBalance(sum)\n      })\n    LoopringAPI.luckTokenAPI\n      ?.getLuckTokenClaimedBlindBox(\n        {\n          isNft: true,\n          statuses: [0],\n          fromId: 0,\n        },\n        account.apiKey,\n      )\n      .then((response) => {\n        setBlindboxBalance(response.totalNum)\n      })\n  }, [exclusiveRedPackets?.length]) // if open exclusiveRedPacket then refresh\n  const theme = useTheme()\n  const { coinJson } = useSettings()\n  const { idIndex } = useTokenMap()\n  return (\n    <Box\n      flex={1}\n      display={'flex'}\n      flexDirection={'column'}\n      sx={isMobile ? { maxWidth: 'calc(100vw - 32px)' } : {}}\n      paddingTop={2}\n      position={'relative'}\n    >\n      <Box\n        position={'absolute'}\n        display={'flex'}\n        alignItems={'center'}\n        sx={{\n          right: 0,\n          top: -42,\n          zIndex: 99,\n        }}\n      >\n        <Button\n          variant={'text'}\n          target='_self'\n          rel='noopener noreferrer'\n          href={`/#${RouterPath.l2records}/${RecordTabIndex.Transactions}?types=${TransactionTradeViews.redPacket}`}\n        >\n          {t('labelTransactionsLink')}\n        </Button>\n        {/* <Button\n          startIcon={<RedPacketIcon fontSize={'small'} />}\n          variant={'contained'}\n          size={'small'}\n          // sx={{ color: \"var(--color-text-secondary)\" }}\n          color={'primary'}\n          onClick={() => history.push(`${RouterPath.redPacket}/${RedPacketRouterIndex.markets}`)}\n        >\n          {t('labelRedPacketMarketsBtn')}\n        </Button> */}\n      </Box>\n      <StylePaper ref={container} flex={1} display={'flex'} flexDirection={'column'}>\n        {exclusiveRedPackets && exclusiveRedPackets.length > 0 && (\n          <Box paddingX={2} paddingY={1} bgcolor={'var(--color-box-hover)'} borderRadius={0.5}>\n            <Typography>\n              {t('labelRedPacketHaveExclusive', { count: exclusiveRedPackets.length })}{' '}\n              <Button\n                onClick={() => {\n                  setShowTargetRedpacketPop({\n                    isShow: true,\n                    info: {\n                      exclusiveRedPackets: exclusiveRedPackets.map(redpacket => {\n                        return {\n                          ...redpacket,\n                          tokenName: \n                            redpacket.isNft\n                            ? (redpacket.nftTokenInfo?.metadata?.base.name ?? '')\n                            : idIndex[redpacket.tokenId],\n                          tokenIcon: coinJson[idIndex[redpacket.tokenId ?? 0]] \n                        }\n                      })\n                    }\n                  })\n                  // setShowRedPacketsPopup(true)\n                }}\n                variant={'text'}\n              >\n                {t('labelRedPacketExclusiveViewDetails')}\n              </Button>{' '}\n            </Typography>\n          </Box>\n        )}\n        <Box className='tableWrapper table-divide-short'>\n          <RedPacketClaimTable\n            {...{\n              rawData: redPacketClaimList,\n              showloading: showLoading,\n              forexMap,\n              onItemClick,\n              etherscanBaseUrl,\n              getClaimRedPacket,\n              onViewMoreClick,\n              hideAssets,\n            }}\n            totalLuckyTokenNFTBalance={totalLuckyTokenNFTBalance}\n            blindBoxBalance={blindboxBalance}\n          />\n        </Box>\n        <Dialog\n          maxWidth={'lg'}\n          open={showNFTsPanel}\n          onClose={() => {\n            onCloseNFts()\n          }}\n        >\n          <DialogTitle>\n            <Typography variant={'h3'} textAlign={'center'}>\n              {t('labelBlindBoxRecievedRedPackets')}\n            </Typography>\n            <IconButton\n              size={'medium'}\n              sx={{\n                position: 'absolute',\n                right: 8,\n                top: 8,\n              }}\n              color={'inherit'}\n              onClick={() => {\n                onCloseNFts()\n              }}\n            >\n              <CloseIcon />\n            </IconButton>\n          </DialogTitle>\n          <DialogContent style={{ width: '960px' }}>\n            <RedPacketClaimTable\n              isNFT\n              rawData={redPacketNFTClaimList}\n              showloading={showNFTLoading}\n              forexMap={forexMap}\n              onItemClick={onItemNFTClick}\n              etherscanBaseUrl={etherscanBaseUrl}\n              getClaimRedPacket={getClaimNFTRedPacket}\n            />\n          </DialogContent>\n        </Dialog>\n        \n      </StylePaper>\n      <Toast\n        alertText={toastOpen?.content ?? ''}\n        severity={toastOpen?.type ?? ToastType.success}\n        open={toastOpen?.open ?? false}\n        autoHideDuration={TOAST_TIME}\n        onClose={closeToast}\n      />\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/RedPacketPage/RedPacketMarketPanel/hooks.ts",
    "content": "import { useTranslation } from 'react-i18next'\nimport { LoopringAPI, useAccount, useTokenMap } from '@loopring-web/core'\nimport React from 'react'\nimport * as sdk from '@loopring-web/loopring-sdk'\nimport { globalSetup, RedPacketLimit, SDK_ERROR_MAP_TO_UI } from '@loopring-web/common-resources'\nimport _ from 'lodash'\nimport { useRouteMatch } from 'react-router-dom'\nimport { ToastType } from '@loopring-web/component-lib'\n\nexport const useMarketRedPacket = <R extends sdk.LuckyTokenItemForReceive>({\n  setToastOpen,\n}: {\n  setToastOpen: (props: any) => void\n}) => {\n  const { t } = useTranslation(['error'])\n  const {\n    account: { accountId, apiKey },\n  } = useAccount()\n  const { idIndex } = useTokenMap()\n  const [hideOpen, setHideOpen] = React.useState<boolean>(false)\n  const [showLoading, setShowLoading] = React.useState(true)\n  let match: any = useRouteMatch('/redPacket/markets/:item')\n\n  const [pagination, setPagination] = React.useState<{\n    pageSize: number\n    total: number\n    page: number\n  }>({\n    pageSize: RedPacketLimit,\n    total: 0,\n    page: 1,\n  })\n  const [luckTokenList, setLuckTokenList] = React.useState<{\n    officialList: R[]\n    publicList: R[]\n    publicTotal: number\n  }>({\n    officialList: [],\n    publicList: [],\n    publicTotal: 0,\n  })\n\n  const getMarketRedPacket = React.useCallback(\n    async ({ showOfficial, offset }: any) => {\n      setShowLoading(true)\n      const statuses = [\n        sdk.LuckyTokenWithdrawStatus.PROCESSING,\n        sdk.LuckyTokenWithdrawStatus.PROCESSED,\n      ]\n      if (LoopringAPI.luckTokenAPI && accountId && apiKey) {\n        const isNft = match?.params?.item?.toUpperCase() === 'NFT'\n        let responses: any[]\n        if (showOfficial) {\n          responses = await LoopringAPI.luckTokenAPI\n            ?.getLuckTokenLuckyTokens(\n              {\n                senderId: 0,\n                hash: '',\n                partitions: '0,1',\n                modes: '0,1,2',\n                scopes: sdk.LuckyTokenViewType.PUBLIC,\n                statuses: statuses.join(','),\n                offset: 0,\n                limit: 50,\n                official: true,\n                isNft,\n              } as any,\n              apiKey,\n            )\n            .then(async (resOfficial) => {\n              const officialLength = resOfficial.list.length\n              const resNonOfficial = await LoopringAPI.luckTokenAPI?.getLuckTokenLuckyTokens(\n                {\n                  senderId: 0,\n                  hash: '',\n                  partitions: '0,1',\n                  modes: '0,1,2',\n                  scopes: sdk.LuckyTokenViewType.PUBLIC,\n                  statuses: statuses.join(','),\n                  offset,\n                  limit: pagination?.pageSize - officialLength,\n                  isNft,\n                } as any,\n                apiKey,\n              )\n              return [resOfficial, resNonOfficial]\n            })\n        } else {\n          const nonOfficialRes = await LoopringAPI.luckTokenAPI?.getLuckTokenLuckyTokens(\n            {\n              senderId: 0,\n              hash: '',\n              partitions: '0,1',\n              modes: '0,1,2',\n              scopes: sdk.LuckyTokenViewType.PUBLIC,\n              statuses: statuses.join(','),\n              offset,\n              limit: pagination?.pageSize,\n              isNft,\n            } as any,\n            apiKey,\n          )\n          responses = [{}, nonOfficialRes]\n        }\n\n        if ((responses[0] as sdk.RESULT_INFO).code || (responses[0] as sdk.RESULT_INFO).message) {\n          const errorItem = SDK_ERROR_MAP_TO_UI[(responses[0] as sdk.RESULT_INFO)?.code ?? 700001]\n          if (setToastOpen) {\n            setToastOpen({\n              open: true,\n              type: ToastType.error,\n              content:\n                'error : ' + errorItem\n                  ? t(errorItem.messageKey)\n                  : (responses[0] as sdk.RESULT_INFO).message,\n            })\n          }\n        } else {\n          setLuckTokenList({\n            officialList: (responses[0]?.list ?? []) as R[],\n            publicList: responses?.length === 2 ? (responses[1]?.list as R[]) : [],\n            publicTotal: responses[1]?.totalNum!,\n          })\n          setShowLoading(false)\n          setPagination((state) => {\n            return {\n              ...state,\n              totalNum: responses?.length === 2 ? responses[1].totalNum : 0,\n            }\n          })\n        }\n      }\n      setShowLoading(false)\n    },\n    [accountId, apiKey, t, idIndex, match?.params?.item],\n  )\n  const updateData = _.debounce(({ currPage, showOfficial }) => {\n    getMarketRedPacket({\n      offset: (currPage - 1) * pagination?.pageSize,\n      showOfficial: currPage === 1,\n    })\n    setPagination((state) => {\n      return {\n        ...state,\n        page: currPage,\n      }\n    })\n  }, globalSetup.wait)\n\n  const handlePageChange = React.useCallback(\n    ({ page }: { page: number; showOfficial?: boolean }) => {\n      updateData({ currPage: page })\n    },\n    [updateData],\n  )\n  React.useEffect(() => {\n    updateData.cancel()\n    handlePageChange({ page: 1 })\n    return () => {\n      updateData.cancel()\n    }\n  }, [pagination?.pageSize, match?.params?.item])\n\n  return {\n    pagination,\n    luckTokenList,\n    showLoading,\n    hideOpen,\n    setHideOpen,\n    getMarketRedPacket,\n    handlePageChange,\n  }\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/RedPacketPage/RedPacketMarketPanel/index.tsx",
    "content": "import React from 'react'\nimport {\n  AccountStep,\n  EmptyDefault,\n  FormControlLabel,\n  RedPacketBlindBoxDetail,\n  RedPacketPrepare,\n  RedPacketViewStep,\n  TablePagination,\n  useOpenModals,\n  useSettings,\n} from '@loopring-web/component-lib'\nimport { useTranslation } from 'react-i18next'\nimport { useHistory, useRouteMatch } from 'react-router-dom'\nimport {\n  getIPFSString,\n  makeViewCard,\n  StylePaper,\n  useOpenRedpacket,\n  useSystem,\n  redPacketHistory as redPacketHistoryStore,\n} from '@loopring-web/core'\nimport { useMarketRedPacket } from './hooks'\nimport { Box, Button, Checkbox, Grid, Tab, Tabs, Typography } from '@mui/material'\nimport * as sdk from '@loopring-web/loopring-sdk'\n\nimport {\n  AssetTabIndex,\n  BackIcon,\n  CheckBoxIcon,\n  CheckedIcon,\n  RedPacketRouterIndex,\n  RefreshIcon,\n  RouterPath,\n  ScanQRIcon,\n  SoursURL,\n  TabTokenTypeIndex,\n} from '@loopring-web/common-resources'\nimport styled from '@emotion/styled'\n\nconst LoadingStyled = styled(Box)`\n  position: fixed;\n  z-index: 21;\n  top: 50%;\n  left: 50%;\n  transform: translate(-50%, -50%);\n  background: var(--field-opacity);\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  height: 100%;\n  width: 100%;\n`\n\nexport const RedPacketMarketPanel = ({ setToastOpen }: { setToastOpen: (props: any) => void }) => {\n  const container = React.useRef<HTMLDivElement>(null)\n  const {\n    setShowAccount,\n    setShowRedPacket,\n    modals: { isShowRedPacket },\n  } = useOpenModals()\n  const { t } = useTranslation()\n  const { isMobile } = useSettings()\n  const history = useHistory()\n  const { baseURL } = useSystem()\n  const { redPacketHistory } = redPacketHistoryStore.useRedPacketHistory()\n  const { callOpen } = useOpenRedpacket()\n  let match: any = useRouteMatch('/redPacket/markets/:item')\n  const { showLoading, hideOpen, setHideOpen, luckTokenList, pagination, handlePageChange } =\n    useMarketRedPacket({\n      setToastOpen,\n    })\n\n  const [currentTab, setCurrentTab] = React.useState<TabTokenTypeIndex>(\n    match?.params.item ?? TabTokenTypeIndex.ERC20,\n  )\n\n  const handleTabChange = (value: TabTokenTypeIndex) => {\n    switch (value) {\n      case TabTokenTypeIndex.ERC20:\n        history.push(\n          `${RouterPath.redPacket}/${RedPacketRouterIndex.markets}/${TabTokenTypeIndex.ERC20}`,\n        )\n        setCurrentTab(TabTokenTypeIndex.ERC20)\n        break\n      case TabTokenTypeIndex.NFT:\n      default:\n        history.replace(\n          `${RouterPath.redPacket}/${RedPacketRouterIndex.markets}/${TabTokenTypeIndex.NFT}`,\n        )\n        setCurrentTab(TabTokenTypeIndex.NFT)\n        break\n    }\n  }\n  const listMemo = (list: sdk.LuckyTokenItemForReceive[] | undefined) => {\n    return (\n      <>\n        {list?.length ? (\n          list.map((item, index) => {\n            // item.isOfficial\n            if (\n              isShowRedPacket.step === RedPacketViewStep.TimeOutPanel &&\n              isShowRedPacket.info &&\n              isShowRedPacket.info.hash === item.hash &&\n              // @ts-ignore\n              isShowRedPacket.info.id == item.id\n            ) {\n              item = {\n                ...item,\n                ...isShowRedPacket.info,\n              }\n            }\n            const { chainId, account, amountStr, myAmountStr, tokenInfo, claim, claimed } =\n              makeViewCard(item)\n\n            return !(hideOpen && claim) ? (\n              <Grid\n                item\n                xs={6}\n                md={4}\n                lg={3}\n                key={index + item.hash}\n                position={'relative'}\n                marginY={1}\n              >\n                <RedPacketPrepare\n                  {...{ ...item }}\n                  claim={claim}\n                  setShowRedPacket={setShowRedPacket} //\n                  chainId={chainId as any}\n                  account={account}\n                  amountStr={amountStr}\n                  myAmountStr={myAmountStr}\n                  onOpen={callOpen}\n                  tokenInfo={tokenInfo}\n                  getIPFSString={getIPFSString}\n                  baseURL={baseURL}\n                  _type={\n                    item.type.mode === sdk.LuckyTokenClaimType.BLIND_BOX\n                      ? 'blindbox'\n                      : (item as any)?.isOfficial\n                      ? 'official'\n                      : 'default'\n                  }\n                  claimed={claimed}\n                />\n              </Grid>\n            ) : (\n              <></>\n            )\n          })\n        ) : (\n          <></>\n        )}\n      </>\n    )\n  }\n  const listERC20 = React.useMemo(() => {\n    return (\n      <>\n        {listMemo(\n          luckTokenList.officialList.map((x) => ({\n            ...x,\n            isOfficial: true,\n            info: { ...x.info },\n          })),\n        )}\n        {listMemo(luckTokenList.publicList.map((x) => ({ ...x, isOfficial: false })))}\n      </>\n    )\n  }, [hideOpen, redPacketHistory, luckTokenList.officialList, luckTokenList.publicList])\n  return (\n    <Box\n      flex={1}\n      display={'flex'}\n      flexDirection={'column'}\n      sx={isMobile ? { maxWidth: 'calc(100vw - 32px)' } : {}}\n    >\n      <Box display={'flex'} justifyContent={'space-between'} alignItems={'center'} marginBottom={2}>\n        <Button\n          startIcon={<BackIcon fontSize={'small'} />}\n          variant={'text'}\n          size={'medium'}\n          sx={{ color: 'var(--color-text-secondary)' }}\n          color={'inherit'}\n          onClick={() => history.push(`${RouterPath.l2assetsDetail}/${AssetTabIndex.RedPacket}`)}\n        >\n          {t('labelRedPacketMarkets')}\n        </Button>\n        <Box display={'flex'} alignItems={'center'} justifyContent={'flex-end'}>\n          {/* <Button\n            variant={'contained'}\n            size={'small'}\n            sx={{ marginLeft: 1 }}\n            onClick={() => history.push(`${RouterPath.redPacket}/${RedPacketRouterIndex.create}`)}\n          >\n            <Typography variant={'body1'}>{t('labelCreateRedPacket')}</Typography>\n          </Button> */}\n          <Button\n            variant={'outlined'}\n            size={'medium'}\n            color={'inherit'}\n            sx={{ marginLeft: 1 }}\n            onClick={() => history.push(`${RouterPath.redPacket}/${RedPacketRouterIndex.records}`)}\n          >\n            {t('labelMyRedPacket')}\n          </Button>\n          <Button\n            startIcon={<ScanQRIcon fontSize={'small'} />}\n            variant={'outlined'}\n            size={'medium'}\n            color={'inherit'}\n            sx={{ marginLeft: 1 }}\n            onClick={() => {\n              setShowAccount({ isShow: true, step: AccountStep.QRCodeScanner })\n            }}\n          >\n            {t('labelRedPacketQRCodeImport')}\n          </Button>\n        </Box>\n      </Box>\n      <StylePaper\n        ref={container}\n        flex={1}\n        display={'flex'}\n        flexDirection={'column'}\n        paddingBottom={2}\n        position={'relative'}\n      >\n        <Box\n          display={'flex'}\n          flexDirection={'row'}\n          justifyContent={'space-between'}\n          marginBottom={1}\n        >\n          <Tabs\n            value={currentTab}\n            onChange={(_event, value) => handleTabChange(value)}\n            aria-label='l2-history-tabs'\n            variant='scrollable'\n          >\n            <Tab\n              label={t('labelRedPacketMarket' + TabTokenTypeIndex.ERC20)}\n              value={TabTokenTypeIndex.ERC20}\n            />\n            {/*<Tab*/}\n            {/*  label={t(\"labelRedPacketMarket\" + TabTokenTypeIndex.NFT)}*/}\n            {/*  value={TabTokenTypeIndex.NFT}*/}\n            {/*/>*/}\n          </Tabs>\n          <Box justifyContent={'flex-end'} marginY={1} paddingX={2} display={'flex'}>\n            <Box>\n              <Button\n                startIcon={<RefreshIcon fontSize={'small'} />}\n                variant={'outlined'}\n                size={'medium'}\n                color={'primary'}\n                onClick={() => {\n                  handlePageChange({ page: 1 })\n                }}\n              >\n                {t('labelRefreshRedPacket')}\n              </Button>\n            </Box>\n            <Box marginLeft={1}>\n              <FormControlLabel\n                style={{ marginRight: 0, paddingRight: 0 }}\n                control={\n                  <Checkbox\n                    checked={hideOpen}\n                    checkedIcon={<CheckedIcon />}\n                    icon={<CheckBoxIcon />}\n                    color='default'\n                    onChange={(event) => {\n                      setHideOpen(event.target.checked)\n                    }}\n                  />\n                }\n                label={t('labelRedpacketNotActive')}\n              />\n            </Box>\n          </Box>\n        </Box>\n        <>\n          {!luckTokenList.officialList?.length && !luckTokenList.publicList?.length ? (\n            <Box\n              flex={1}\n              display={'flex'}\n              alignItems={'center'}\n              height={'100%'}\n              justifyContent={'center'}\n            >\n              <EmptyDefault\n                // width={\"100%\"}\n                height={'100%'}\n                message={() => (\n                  <Box flex={1} display={'flex'} alignItems={'center'} justifyContent={'center'}>\n                    {t('labelNoContent')}\n                  </Box>\n                )}\n              />\n            </Box>\n          ) : (\n            <Grid container display={'flex'} paddingX={1} spacing={2}>\n              {listERC20}\n            </Grid>\n          )}\n          {showLoading && (\n            <LoadingStyled color={'inherit'}>\n              <img\n                className='loading-gif'\n                alt={'loading'}\n                width='36'\n                src={`${SoursURL}images/loading-line.gif`}\n              />\n            </LoadingStyled>\n          )}\n          <Box>\n            <TablePagination\n              page={pagination.page}\n              pageSize={pagination.pageSize}\n              total={luckTokenList.publicTotal}\n              onPageChange={(page) => {\n                handlePageChange({ page })\n              }}\n            />\n          </Box>\n        </>\n      </StylePaper>\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/RedPacketPage/index.tsx",
    "content": "import React from 'react'\nimport { Box, Typography } from '@mui/material'\nimport { useRouteMatch } from 'react-router-dom'\nimport { useToast, ViewAccountTemplate } from '@loopring-web/core'\nimport { RedPacketMarketPanel } from './RedPacketMarketPanel'\nimport { CreateRedPacketUIPanel } from './CreateRedPacketPanel'\nimport { MyRedPacketPanel } from './MyRedPacketPanel'\nimport { TOAST_TIME, RedPacketRouterIndex } from '@loopring-web/common-resources'\nimport { Toast, ToastType, useSettings } from '@loopring-web/component-lib'\nimport { useTranslation } from 'react-i18next'\n\nexport const RedPacketPage = () => {\n  let match: any = useRouteMatch('/redPacket/:item')\n  const selected = match?.params.item ?? 'markets'\n  const { toastOpen, setToastOpen, closeToast } = useToast()\n  const { isMobile } = useSettings()\n  const { t } = useTranslation()\n  const reaPacketRouter = React.useMemo(() => {\n    switch (selected) {\n      case RedPacketRouterIndex.create:\n        return <CreateRedPacketUIPanel />\n      case RedPacketRouterIndex.records:\n        return <MyRedPacketPanel setToastOpen={setToastOpen} />\n      case RedPacketRouterIndex.markets:\n        return <RedPacketMarketPanel setToastOpen={setToastOpen} />\n      default:\n        ;<RedPacketMarketPanel setToastOpen={setToastOpen} />\n    }\n  }, [selected])\n\n  const activeView = React.useMemo(\n    () => (\n      <>\n        <Toast\n          alertText={toastOpen?.content ?? ''}\n          severity={toastOpen?.type ?? ToastType.success}\n          open={toastOpen?.open ?? false}\n          autoHideDuration={TOAST_TIME}\n          onClose={closeToast}\n        />\n        <Box\n          display={'flex'}\n          alignItems={'stretch'}\n          flexDirection={'column'}\n          marginTop={0}\n          flex={1}\n        >\n          {reaPacketRouter}\n        </Box>\n      </>\n    ),\n    [reaPacketRouter],\n  )\n  return (\n    <>\n      {isMobile ? (\n        <Typography component={'h3'}>{t('labelRedPacketNotSupport')}</Typography>\n      ) : (\n        <ViewAccountTemplate activeViewTemplate={activeView} />\n      )}\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/SwapPage/index.tsx",
    "content": "import { Box } from '@mui/material'\nimport { WithTranslation, withTranslation } from 'react-i18next'\nimport {\n  AlertImpact,\n  ConfirmImpact,\n  SmallOrderAlert,\n  SwapPanel,\n  SwapSecondConfirmation,\n  Toast,\n  ToastType,\n} from '@loopring-web/component-lib'\nimport {\n  EmptyValueTag,\n  getValuePrecisionThousand,\n  myLog,\n  SoursURL,\n  TOAST_TIME,\n} from '@loopring-web/common-resources'\nimport { PriceLevel, ShowWitchAle3t1, useNotify, useSwap } from '@loopring-web/core'\nimport React from 'react'\n\nexport const SwapPage = withTranslation('common')(({ ...rest }: WithTranslation) => {\n  const {\n    tradeCalcData,\n    tradeData,\n    handleSwapPanelEvent,\n    onSwapClick,\n    swapBtnI18nKey,\n    swapBtnStatus,\n    toastOpen,\n    closeToast,\n    should15sRefresh,\n    market,\n    refreshRef,\n    pageTradeLite,\n    isSwapLoading,\n    toPro,\n    isMarketInit,\n    isMobile,\n    setToastOpen,\n    showAlert,\n    handleConfirm,\n    handleClose,\n    priceLevel,\n  } = useSwap({ path: '/trade/lite' })\n  const styles = isMobile ? { flex: 1 } : { width: 'var(--swap-box-width)' }\n  const { campaignTagConfig } = useNotify().notifyMap ?? {}\n  const estimatedFee =\n    tradeCalcData && tradeCalcData.fee && tradeData\n      ? `${tradeCalcData.fee} ${tradeData.buy?.belong}` //(parseFloat(tradeCalcData.fee) / 100).toString() + \"%\"\n      : EmptyValueTag\n  const minimumReceived =\n    tradeCalcData && tradeCalcData.minimumReceived && tradeData\n      ? `${tradeCalcData.minimumReceived}  ${tradeData.buy?.belong}`\n      : EmptyValueTag\n  const feePercentage =\n    tradeCalcData && tradeData?.buy.tradeValue\n      ? ((Number(tradeCalcData.fee) / tradeData.buy.tradeValue) * 100).toFixed(2)\n      : EmptyValueTag\n  const priceImpactColor = tradeCalcData?.priceImpactColor\n    ? tradeCalcData.priceImpactColor\n    : 'textPrimary'\n  const priceImpact =\n    tradeCalcData?.priceImpact !== undefined\n      ? getValuePrecisionThousand(tradeCalcData.priceImpact, undefined, undefined, 2, true) + ' %'\n      : EmptyValueTag\n  const userTakerRate =\n    tradeCalcData && tradeCalcData.feeTakerRate\n      ? (tradeCalcData.feeTakerRate / 100).toString()\n      : EmptyValueTag\n  const tradeCostMin =\n    tradeCalcData && tradeCalcData.tradeCost && tradeData\n      ? `${tradeCalcData.tradeCost} ${tradeData.buy?.belong}` //(parseFloat(tradeCalcData.fee) / 100).toString() + \"%\"\n      : EmptyValueTag\n\n  const fromSymbol = tradeData?.sell.belong ?? EmptyValueTag\n  const fromAmount = tradeData?.sell.tradeValue?.toString() ?? EmptyValueTag\n  const toSymbol = tradeData?.buy.belong ?? EmptyValueTag\n  const toAmount = tradeData?.buy.tradeValue?.toString() ?? EmptyValueTag\n  const slippage = tradeData\n    ? tradeData.slippage\n      ? `${tradeData.slippage}`\n      : '0.1'\n    : EmptyValueTag\n  myLog('useSwap', showAlert)\n  return (\n    <Box\n      display={'flex'}\n      flexDirection={'column'}\n      justifyContent={'center'}\n      alignItems={'center'}\n      flex={1}\n    >\n      <Box\n        paddingBottom={isMobile ? 2 : 'initial'}\n        display={'flex'}\n        style={styles}\n        justifyContent={'center'}\n      >\n        {tradeData ? (\n          <SwapPanel\n            toPro={toPro}\n            tokenBuyProps={{\n              disableInputValue: isMarketInit || isSwapLoading,\n              disabled: isMarketInit || isSwapLoading,\n              decimalsLimit: tradeCalcData.buyPrecision,\n            }}\n            tokenSellProps={{\n              disableInputValue: isMarketInit || isSwapLoading,\n              disabled: isMarketInit || isSwapLoading,\n              decimalsLimit: tradeCalcData.sellPrecision,\n            }}\n            campaignTagConfig={campaignTagConfig ?? ({} as any)}\n            market={market}\n            onRefreshData={should15sRefresh}\n            refreshRef={refreshRef}\n            tradeData={tradeData as any}\n            tradeCalcData={tradeCalcData as any}\n            onSwapClick={onSwapClick}\n            swapBtnI18nKey={swapBtnI18nKey}\n            swapBtnStatus={swapBtnStatus}\n            setToastOpen={setToastOpen}\n            scrollDisabled\n            {...{ handleSwapPanelEvent, ...rest }}\n          />\n        ) : (\n          <Box\n            flex={1}\n            height={'100%'}\n            display={'flex'}\n            alignItems={'center'}\n            justifyContent={'center'}\n          >\n            <img className='loading-gif' width='36' src={`${SoursURL}images/loading-line.gif`} />\n          </Box>\n        )}\n      </Box>\n      <Toast\n        alertText={toastOpen?.content ?? ''}\n        severity={toastOpen?.type ?? ToastType.success}\n        open={toastOpen?.open ?? false}\n        autoHideDuration={TOAST_TIME}\n        onClose={closeToast}\n      />\n      <AlertImpact\n        open={showAlert.isShow && showAlert.showWitch === ShowWitchAle3t1.AlertImpact}\n        handleClose={handleClose}\n        handleConfirm={handleConfirm}\n        variance={tradeCalcData?.marketRatePrice ?? ''}\n        marketPrice={tradeCalcData?.marketPrice ?? ''}\n        settlementPrice={tradeCalcData?.StoB ?? ''}\n        symbol={`${tradeData?.sell?.belong}/${tradeData?.buy?.belong}`}\n      />\n      <ConfirmImpact\n        open={showAlert.isShow && showAlert.showWitch === ShowWitchAle3t1.ConfirmImpact}\n        handleClose={handleClose}\n        handleConfirm={handleConfirm}\n        priceImpact={getValuePrecisionThousand(pageTradeLite?.priceImpactObj?.value, 2)}\n        color={'var(--color-error)'} //priceLevel.priceImpactColor\n        shouldInputAgree={priceLevel.priceLevel === PriceLevel.Lv2}\n      />\n      <SmallOrderAlert\n        open={showAlert.isShow && showAlert.showWitch === ShowWitchAle3t1.SmallPrice}\n        handleClose={handleClose}\n        handleConfirm={handleConfirm}\n        estimatedFee={estimatedFee}\n        feePercentage={feePercentage}\n        minimumReceived={minimumReceived}\n        symbol={`${tradeData?.sell?.belong}/${tradeData?.buy?.belong}`}\n      />\n      <SwapSecondConfirmation\n        open={showAlert.isShow && showAlert.showWitch === ShowWitchAle3t1.SwapSecondConfirmation}\n        handleClose={handleClose}\n        handleConfirm={handleConfirm}\n        fromSymbol={fromSymbol}\n        fromAmount={fromAmount}\n        toSymbol={toSymbol}\n        toAmount={toAmount}\n        slippage={slippage}\n        userTakerRate={userTakerRate}\n        tradeCostMin={tradeCostMin}\n        estimateFee={estimatedFee}\n        priceImpactColor={priceImpactColor}\n        priceImpact={priceImpact}\n        minimumReceived={minimumReceived}\n      />\n    </Box>\n  )\n})\n"
  },
  {
    "path": "packages/webapp/src/pages/TradeRacePage/hook.ts",
    "content": "import React from 'react'\nimport { languageMap, myLog, url_path, url_test_path } from '@loopring-web/common-resources'\nimport { useHistory, useLocation, useRouteMatch } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport { Config_INFO_URL, EventData } from './interface'\nimport { useSystem } from '@loopring-web/core'\nimport moment from 'moment'\n\nexport enum EVENT_STATUS {\n  EVENT_START = 'labelTradeRaceStart',\n  EVENT_READY = 'labelTradeRaceReady',\n  EVENT_END = 'labelTradeRaceEnd',\n}\n\nexport const useTradeRace = () => {\n  const match: any = useRouteMatch('/race-event/:path')\n  const nodeTimer = React.useRef<NodeJS.Timeout | -1>(-1)\n  const { i18n } = useTranslation()\n  const { baseURL } = useSystem()\n  const { search } = useLocation()\n  const searchParams = new URLSearchParams(search)\n  const history = useHistory()\n\n  const [eventData, setEventData] = React.useState<EventData>()\n  const [eventsList, setEventsList] = React.useState<Array<EventData & { type: string }>>([])\n  const [eventStatus, setEventStatus] = React.useState<EVENT_STATUS | undefined>()\n\n  const [countDown, setCountDown] = React.useState<{\n    days: undefined | string\n    hours: undefined | string\n    seconds: undefined | string\n    minutes: undefined | string\n  }>()\n\n  React.useEffect(() => {\n    if (baseURL) {\n      try {\n        // follow /2021/01/2021-01-01.en.json\n        const [year, month] = match?.params.path.split('-')\n        const type = searchParams.get('type')\n        const path = `${/uat/gi.test(baseURL) ? url_test_path : url_path}/${year}/${month}/`\n        if (year && month && type) {\n          fetch(`${path}activities.${languageMap[i18n.language]}.json`)\n            .then((response) => {\n              if (response.ok) {\n                return response.json()\n              } else {\n                history.replace(`/race-event?${searchParams.toString()}`)\n              }\n            })\n            .then((input: { [key: string]: EventData }) => input[type])\n            .then(async (eventData: EventData) => {\n              myLog('useTradeRace eventData', eventData)\n              if (eventData) {\n                // https://uat2.loopring.io/api/v3/activity/getFilterInfo?version=1\n                const configUrl = `${baseURL}/${Config_INFO_URL}?version=${eventData.api?.version}`\n                myLog('baseURL', configUrl)\n                const config: [{ [key: string]: any }, string] = await Promise.all([\n                  fetch(configUrl).then((response) => {\n                    if (response.ok) {\n                      return response.json()\n                    } else {\n                      return {}\n                    }\n                  }),\n                  fetch(`${path}activities/${eventData.rule?.split('/').pop()}`)\n                    .then((response) => response.text())\n                    .then((input) => {\n                      return input\n                    })\n                    .catch(() => {\n                      return ''\n                    }),\n                ])\n                const startUnix =\n                  config[0].start ??\n                  moment.utc(eventData.duration.startDate, 'MM/DD/YYYY HH:mm:ss').valueOf()\n                const endUnix =\n                  config[0].end ??\n                  moment.utc(eventData.duration.endDate, 'MM/DD/YYYY HH:mm:ss').valueOf()\n\n                setEventData({\n                  ...eventData,\n                  banner: {\n                    pad: eventData.banner?.pad\n                      ? /uat/gi.test(baseURL)\n                        ? `${path}activities/${eventData.banner?.pad?.split('/').pop()}`\n                        : eventData.banner.pad //`${path}/`\n                      : undefined,\n                    laptop: eventData.banner?.laptop\n                      ? /uat/gi.test(baseURL)\n                        ? `${path}activities/${eventData.banner?.laptop?.split('/').pop()}`\n                        : eventData.banner.laptop //`${path}/`\n                      : undefined,\n                    mobile: eventData.banner?.mobile\n                      ? /uat/gi.test(baseURL)\n                        ? `${path}activities/${eventData.banner?.mobile?.split('/').pop()}`\n                        : eventData.banner.mobile\n                      : undefined,\n                  },\n                  duration: {\n                    ...eventData.duration,\n                    startDate: startUnix,\n                    endDate: endUnix,\n                  },\n                  ruleMarkdown: config[1],\n                  api: {\n                    ...eventData.api,\n                    ...config[0],\n                  },\n                })\n\n                if (startUnix > Date.now()) {\n                  setEventStatus(EVENT_STATUS.EVENT_READY)\n                } else if (endUnix > Date.now()) {\n                  setEventStatus(EVENT_STATUS.EVENT_START)\n                } else {\n                  setEventStatus(EVENT_STATUS.EVENT_END)\n                }\n              } else {\n                throw 'no EventData'\n              }\n            })\n            .catch((e) => {\n              searchParams.set('type', '')\n              // history.push(match.url + \"?\" + searchParams.toString());\n              window.open(`./#${match.url}?` + searchParams.toString(), '_self')\n              window.opener = null\n              window.location.reload()\n            })\n        } else if (year && month && !type) {\n          fetch(`${path}activities.${languageMap[i18n.language]}.json`)\n            .then((response) => {\n              if (response.ok) {\n                return response.json()\n              } else {\n                history.replace(`/race-event?${searchParams.toString()}`)\n              }\n            })\n            .then((input) => {\n              const eventsList = Reflect.ownKeys(input).map((key) => {\n                // input[key]\n                const startUnix = moment\n                  .utc(input[key].duration?.startDate ?? '', 'MM/DD/YYYY HH:mm:ss')\n                  .valueOf()\n                const endUnix = moment\n                  .utc(input[key].duration?.endDate ?? '', 'MM/DD/YYYY HH:mm:ss')\n                  .valueOf()\n                return {\n                  ...input[key],\n                  type: key,\n                  duration: {\n                    ...input[key].duration,\n                    startDate: startUnix,\n                    endDate: endUnix,\n                  },\n                }\n              })\n              setEventsList(eventsList)\n            })\n        } else {\n          throw 'url format wrong'\n        }\n      } catch (e: any) {\n        myLog(e?.message)\n        history.push('/race-event')\n      }\n    }\n  }, [baseURL, i18n.language])\n\n  const scrollToRule = (event: React.MouseEvent<HTMLElement>) => {\n    const anchor = ((event.target as HTMLElement).ownerDocument || document).querySelector(\n      '#event-rule',\n    )\n\n    if (anchor) {\n      anchor.scrollIntoView({ behavior: 'smooth', block: 'center' })\n    }\n  }\n\n  const calculateTimeLeft = React.useCallback(() => {\n    if (eventData && eventStatus) {\n      if (eventStatus === EVENT_STATUS.EVENT_READY) {\n        let difference = +new Date(eventData.duration.startDate) - Date.now()\n\n        setCountDown({\n          days: Math.floor(difference / (1000 * 60 * 60 * 24)).toString(),\n          hours: ('0' + Math.floor((difference / (1000 * 60 * 60)) % 24).toString()).slice(-2),\n          minutes: ('0' + Math.floor((difference / 1000 / 60) % 60).toString()).slice(-2),\n          seconds: ('0' + Math.floor((difference / 1000) % 60).toString()).slice(-2),\n        })\n      } else if (eventStatus === EVENT_STATUS.EVENT_START) {\n        let difference = +new Date(eventData.duration.endDate) - Date.now()\n        setCountDown({\n          days: Math.floor(difference / (1000 * 60 * 60 * 24)).toString(),\n          hours: ('0' + Math.floor((difference / (1000 * 60 * 60)) % 24).toString()).slice(-2),\n          minutes: ('0' + Math.floor((difference / 1000 / 60) % 60).toString()).slice(-2),\n          seconds: ('0' + Math.floor((difference / 1000) % 60).toString()).slice(-2),\n        })\n      }\n      if (nodeTimer.current !== -1) {\n        clearTimeout(nodeTimer.current as NodeJS.Timeout)\n      }\n      nodeTimer.current = setTimeout(calculateTimeLeft, 1000)\n    }\n\n  }, [eventData, eventStatus])\n  React\n    .useEffect(() => {\n      if (eventStatus) {\n        if (nodeTimer.current !== -1) {\n          clearTimeout(nodeTimer.current as NodeJS.Timeout)\n        }\n        calculateTimeLeft()\n      }\n      return () => {\n        if (nodeTimer.current !== -1) {\n          clearTimeout(nodeTimer.current as NodeJS.Timeout)\n        }\n    }\n  }, [eventStatus])\n\n  return {\n    eventData,\n    match,\n    // selected,\n    // currMarketPair,\n    filteredAmmViewMap: [],\n    countDown,\n    eventsList,\n    // handleFilterChange,\n    searchParams,\n    // onChange,\n    // duration,\n    scrollToRule,\n    // activityRule,\n    eventStatus,\n  }\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/TradeRacePage/index.tsx",
    "content": "import React from 'react'\nimport { withTranslation, WithTranslation } from 'react-i18next'\nimport {\n  Box,\n  BoxProps,\n  Card,\n  CardContent,\n  Container,\n  Fab,\n  Grid,\n  Link,\n  Typography,\n} from '@mui/material'\nimport styled from '@emotion/styled'\nimport { LoadingBlock, ScrollTop } from '@loopring-web/component-lib'\nimport { EVENT_STATUS, useTradeRace } from './hook'\nimport {\n  EmptyValueTag,\n  GoTopIcon,\n  MarkdownStyle,\n  YEAR_DAY_SECOND_FORMAT,\n} from '@loopring-web/common-resources'\n\nimport { RankRaw } from './rank'\nimport moment from 'moment'\nimport ReactMarkdown from 'react-markdown'\nimport gfm from 'remark-gfm'\nimport rehypeRaw from 'rehype-raw'\nimport { useTheme } from '@emotion/react'\nimport { EventData } from './interface'\n\nconst CardStyled = styled(Card)`\n  // min-height: ${({ theme }) => theme.unit * 61.5}px;\n  display: flex;\n  flex-direction: column;\n  justify-content: space-between;\n  position: relative;\n`\nconst LayoutStyled = styled(Box)<BoxProps & { eventData: EventData }>`\n  width: 100%;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n\n  ${({ eventData: { showBannerOrTitle, banner } }) => {\n    if (showBannerOrTitle == '1' && banner.laptop) {\n      return `\n          margin-top:0;\n          .title-banner {        \n            h1,\n            h2 {\n             overflow: hidden;\n             text-indent:-999999em; \n            }\n            width:100%;\n            min-height: 65.6vw; \n            background-position:50%;\n            background-size: cover;\n            background-repeat: no-repeat;\n            background-image: url(${banner.pad});\n            @media only screen and (max-width: 600px) {\n                background-image: url(${banner.mobile});\n            }\n            @media only screen and (max-width: 992px) {\n              background-image: url(${banner.pad});\n            };\n            @media only screen and (min-width: 1200px) {\n              background-image: url(${banner.laptop});\n              min-height: 280px;\n            }\n          }`\n    }\n  }}\n  ol,\n  ul {\n    list-style: dismal;\n    font-size: ${({ theme }) => theme.fontDefault.body1};\n    margin-left: ${({ theme }) => theme.unit * 2}px;\n\n    li {\n      color: var(--color-text-secondary);\n    }\n\n    li ::marker {\n      content: '  ' counter(list-item) ')  ';\n      display: inline-flex;\n      color: var(--color-text-secondary);\n    }\n  }\n\n  .hours,\n  .minutes {\n    position: relative;\n\n    span:after {\n      display: block;\n      content: ':';\n      position: absolute;\n      right: -8px;\n      top: 0;\n    }\n  }\n` as (props: BoxProps & { eventData: EventData }) => JSX.Element\n// ${cssStyle}\n\nexport const TradeRacePage = withTranslation('common')(({ t }: WithTranslation) => {\n  const { eventData, countDown, scrollToRule, eventStatus, eventsList, searchParams, match } =\n    useTradeRace()\n  const theme = useTheme()\n  const anchorRef = React.useRef()\n  const anchorTopRef = React.createRef()\n\n  // const history = useHistory();\n\n  // myLog(\"activityRule\", eventStatus, activityRule);\n  /*remove: holiday only end\n      const flakes = 160;\n      const flake = React.useMemo(() => {\n        return <div className={\"flake\"} />;\n      }, []);\n      const snows = new Array(flakes).fill(flake, 0, flakes);\n    */\n  return (\n    <>\n      {eventData ? (\n        <>\n          <LayoutStyled\n            ref={anchorTopRef}\n            marginY={4}\n            eventData={eventData}\n            flex={1}\n            id={'tradeRaceTop'}\n          >\n            <ScrollTop>\n              <Fab color='primary' size={'large'} aria-label='scroll back to top'>\n                <GoTopIcon htmlColor={'var(--color-text-button)'} />\n              </Fab>\n            </ScrollTop>\n            <Box className={'title-banner'} marginBottom={4}>\n              <Typography\n                marginY={1}\n                component={'h1'}\n                variant={'h1'}\n                whiteSpace={'pre-line'}\n                textAlign={'center'}\n                dangerouslySetInnerHTML={{ __html: eventData.eventTitle }}\n              />\n\n              <Typography\n                component={'h2'}\n                variant={'h2'}\n                whiteSpace={'pre-line'}\n                textAlign={'center'}\n                dangerouslySetInnerHTML={{ __html: eventData.subTitle }}\n              />\n            </Box>\n\n            {eventStatus && (\n              <Box component={'section'} paddingX={3} marginBottom={4} textAlign={'center'}>\n                <Typography\n                  component={'h2'}\n                  variant={'h4'}\n                  marginBottom={2}\n                  color={'var(--color-text-secondary)'}\n                >\n                  {t(eventStatus)}\n                </Typography>\n                {eventStatus !== EVENT_STATUS.EVENT_END && (\n                  <Box display={'flex'} flexDirection={'row'} alignItems={'center'}>\n                    <Box\n                      className={'day'}\n                      display={'flex'}\n                      flexDirection={'column'}\n                      minWidth={86}\n                      alignItems={'center'}\n                      marginRight={2}\n                    >\n                      <Typography\n                        variant={'h2'}\n                        component={'span'}\n                        color={'var(--color-text-primary)'}\n                      >\n                        {Number(countDown?.days) >= 0 ? countDown?.days : EmptyValueTag}\n                      </Typography>\n                      <Typography\n                        variant={'h4'}\n                        color={'var(--color-text-secondary)'}\n                        marginTop={1}\n                        style={{ textTransform: 'uppercase' }}\n                      >\n                        {t('labelDay')}\n                      </Typography>\n                    </Box>\n                    <Box\n                      className={'hours'}\n                      display={'flex'}\n                      minWidth={86}\n                      flexDirection={'column'}\n                      alignItems={'center'}\n                      marginRight={2}\n                    >\n                      <Typography\n                        variant={'h2'}\n                        component={'span'}\n                        color={'var(--color-text-primary)'}\n                      >\n                        {Number(countDown?.hours) >= 0 ? countDown?.hours : EmptyValueTag}\n                      </Typography>\n                      <Typography\n                        variant={'h4'}\n                        color={'var(--color-text-secondary)'}\n                        marginTop={1}\n                        style={{ textTransform: 'uppercase' }}\n                      >\n                        {t('labelHours')}\n                      </Typography>\n                    </Box>\n                    <Box\n                      className={'minutes'}\n                      display={'flex'}\n                      minWidth={86}\n                      flexDirection={'column'}\n                      alignItems={'center'}\n                      marginRight={2}\n                    >\n                      <Typography\n                        variant={'h2'}\n                        component={'span'}\n                        color={'var(--color-text-primary)'}\n                      >\n                        {Number(countDown?.minutes) >= 0 ? countDown?.minutes : EmptyValueTag}\n                      </Typography>\n                      <Typography\n                        variant={'h4'}\n                        color={'var(--color-text-secondary)'}\n                        marginTop={1}\n                        style={{ textTransform: 'uppercase' }}\n                      >\n                        {t('labelMinutes')}\n                      </Typography>\n                    </Box>\n                    <Box\n                      className={'secondary'}\n                      display={'flex'}\n                      minWidth={86}\n                      flexDirection={'column'}\n                      alignItems={'center'}\n                      marginRight={2}\n                    >\n                      <Typography\n                        variant={'h2'}\n                        component={'span'}\n                        color={'var(--color-text-primary)'}\n                      >\n                        {Number(countDown?.seconds) >= 0 ? countDown?.seconds : EmptyValueTag}\n                      </Typography>\n                      <Typography\n                        variant={'h4'}\n                        color={'var(--color-text-secondary)'}\n                        marginTop={1}\n                        style={{ textTransform: 'uppercase' }}\n                      >\n                        {t('labelSeconds')}\n                      </Typography>\n                    </Box>\n                  </Box>\n                )}\n              </Box>\n            )}\n            {eventData.duration && (\n              <Typography marginBottom={2} paddingX={3} variant={'body1'}>\n                {eventData?.duration?.prev}\n                <Typography\n                  component={'time'}\n                  paddingX={1}\n                  variant={'h5'}\n                  dateTime={eventData.duration.startDate.toFixed()}\n                >\n                  {moment(eventData.duration.startDate).utc().format(YEAR_DAY_SECOND_FORMAT)}\n                </Typography>\n                <Typography component={'span'} variant={'h5'}>\n                  {eventData?.duration?.middle}\n                </Typography>\n                <Typography\n                  component={'time'}\n                  paddingX={1}\n                  variant={'h5'}\n                  dateTime={eventData.duration.endDate.toFixed()}\n                >\n                  {moment(eventData.duration.endDate).utc().format(YEAR_DAY_SECOND_FORMAT)}\n                </Typography>\n                {eventData?.duration?.timeZone && `(${eventData?.duration?.timeZone})`}{' '}\n                {eventData?.duration?.end}\n                <Typography marginLeft={1} component={'span'}>\n                  <Link onClick={(e) => scrollToRule(e)}>{t('labelTradeReadRule')}</Link>\n                </Typography>\n              </Typography>\n            )}\n            {!!(\n              !searchParams.has('rule') &&\n              eventData.api &&\n              eventData.api.version &&\n              eventStatus !== EVENT_STATUS.EVENT_READY\n            ) && <RankRaw {...eventData.api} />}\n\n            <Box\n              ref={anchorRef}\n              maxWidth={1200}\n              width={'100%'}\n              paddingX={3}\n              marginTop={3}\n              id={'event-rule'}\n            >\n              {eventData.ruleMarkdown ? (\n                <MarkdownStyle\n                  container\n                  minHeight={'calc(100% - 260px)'}\n                  flex={1}\n                  marginTop={3}\n                  marginBottom={2}\n                >\n                  <Box\n                    flex={1}\n                    padding={3}\n                    boxSizing={'border-box'}\n                    className={`${theme.mode}  ${theme.mode}-scheme markdown-body MuiPaper-elevation2 no-bg`}\n                  >\n                    <ReactMarkdown\n                      remarkPlugins={[gfm, ...(eventData.rehypeRaw == '1' ? [rehypeRaw] : [])]}\n                      children={eventData.ruleMarkdown}\n                    />\n                  </Box>\n                </MarkdownStyle>\n              ) : (\n                <LoadingBlock />\n              )}\n            </Box>\n          </LayoutStyled>\n        </>\n      ) : eventsList.length ? (\n        <Container\n          maxWidth='lg'\n          style={{\n            display: 'flex',\n            flexDirection: 'column',\n            flex: 1,\n          }}\n        >\n          <Grid container spacing={2} flex={1} marginTop={2}>\n            {eventsList.map((item, index) => (\n              <Grid item sm={12} md={6} lg={4} key={item.type}>\n                <Link\n                  onClick={() => {\n                    searchParams.set('type', item.type)\n                    // window.opene\n                    window.open(`./#${match.url}?` + searchParams.toString(), '_self')\n                    window.opener = null\n                    window.location.reload()\n                    // history.push(match.url + \"?\" );\n                  }}\n                >\n                  <CardStyled>\n                    <CardContent style={{ paddingBottom: 0 }}>\n                      <Box\n                        display={'flex'}\n                        flexDirection={'column'}\n                        justifyContent={'space-between'}\n                        alignItems={'flex-start'}\n                      >\n                        <Typography\n                          variant={'h3'}\n                          component={'p'}\n                          color={'textPrimary'}\n                          fontFamily={'Roboto'}\n                          textAlign={'center'}\n                          width={'100%'}\n                          dangerouslySetInnerHTML={{\n                            __html: item.eventTitle,\n                          }}\n                        />\n                        <Typography\n                          component={'h2'}\n                          variant={'body1'}\n                          whiteSpace={'pre-line'}\n                          textAlign={'left'}\n                          marginTop={2}\n                          paddingX={3}\n                          dangerouslySetInnerHTML={{ __html: item.subTitle }}\n                        />\n                        {item.duration && (\n                          <Typography\n                            marginBottom={2}\n                            paddingX={3}\n                            variant={'body1'}\n                            marginTop={1}\n                            textAlign={'left'}\n                          >\n                            {item?.duration?.prev}\n                            <Typography\n                              component={'time'}\n                              paddingX={1}\n                              variant={'inherit'}\n                              dateTime={item.duration.startDate.toFixed()}\n                            >\n                              {moment(item.duration.startDate).utc().format(YEAR_DAY_SECOND_FORMAT)}\n                            </Typography>\n                            <Typography component={'span'} variant={'inherit'}>\n                              {item?.duration?.middle}\n                            </Typography>\n                            <Typography\n                              component={'time'}\n                              paddingX={1}\n                              variant={'inherit'}\n                              dateTime={item.duration.endDate.toFixed()}\n                            >\n                              {moment(item.duration.endDate).utc().format(YEAR_DAY_SECOND_FORMAT)}\n                            </Typography>\n                            {item?.duration?.timeZone && `(${item?.duration?.timeZone})`}{' '}\n                            {item?.duration?.end}\n                          </Typography>\n                        )}\n                      </Box>\n                    </CardContent>\n                  </CardStyled>\n                </Link>\n              </Grid>\n            ))}\n          </Grid>\n        </Container>\n      ) : (\n        <LoadingBlock />\n      )}\n    </>\n  )\n})\n"
  },
  {
    "path": "packages/webapp/src/pages/TradeRacePage/interface.ts",
    "content": "export type EventAPI = {\n  version: string\n  column: { key: string; label: string }[]\n  start: number\n  end: number\n}\nexport type EventAPIExtender = {\n  tableColumn: string[]\n  filters: string[]\n}\nexport type EventData = {\n  eventTitle: string\n  subTitle: string\n  local: 'en-US'\n  banner: {\n    laptop?: string\n    mobile?: string\n    pad?: string\n  }\n  showBannerOrTitle: '0' | '1'\n  rule: string\n  ruleMarkdown?: string\n  rehypeRaw: '0' | '1'\n  duration: {\n    prev?: string\n    startDate: number\n    middle?: 'to'\n    endDate: number\n    end?: string\n    timeZone?: string\n  }\n  api: EventAPI & Partial<EventAPIExtender>\n}\n\nexport type API_DATA<R extends object> = {\n  version: number\n  selected: string\n  owner: {\n    rank: string\n    accountId: string\n    address: string\n    usdtValue: string\n  }\n  data: R[]\n}\n\nexport const Config_INFO_URL = 'api/v3/activity/getFilterInfo'\nexport const Activity_URL = '/api/v3/activity/getActivityList'\n"
  },
  {
    "path": "packages/webapp/src/pages/TradeRacePage/rank.tsx",
    "content": "import React from 'react'\nimport {\n  DropDownIcon,\n  EmptyValueTag,\n  getShortAddr,\n  RowConfig,\n  SoursURL,\n} from '@loopring-web/common-resources'\nimport { Box, MenuItem, Typography } from '@mui/material'\nimport {\n  InputSearch,\n  TablePaddingX,\n  TextField,\n  TradeRaceTable,\n  useSettings,\n} from '@loopring-web/component-lib'\nimport styled from '@emotion/styled'\nimport { useHistory, useLocation } from 'react-router-dom'\nimport { useSystem } from '@loopring-web/core'\nimport { Activity_URL, API_DATA, EventAPI, EventAPIExtender } from './interface'\nimport { useTranslation } from 'react-i18next'\n\nconst WrapperStyled = styled(Box)`\n  background-color: var(--color-box);\n  border-radius: ${({ theme }) => theme.unit}px;\n`\nconst StyledTextFiled = styled(TextField)`\n  &.MuiTextField-root {\n    max-width: initial;\n  }\n\n  .MuiInputBase-root {\n    width: initial;\n    max-width: initial;\n  }\n`\n\nconst TableStyled = styled(Box)<{ height: number | undefined | string }>`\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n\n  .rdg {\n    height: ${({ height }) => height}px;\n    height: auto;\n\n    .rdgCellCenter {\n      height: 100%;\n      //   display: flex;\n      justify-content: center;\n      align-items: center;\n    }\n\n    .textAlignRight {\n      text-align: right;\n    }\n\n    .textAlignCenter {\n      text-align: center;\n    }\n\n    .textAlignLeft {\n      text-align: left;\n    }\n  }\n\n  ${({ theme }) => TablePaddingX({ pLeft: theme.unit * 3, pRight: theme.unit * 3 })}\n` as typeof Box\n\nexport const RankRaw = <R extends object>({\n  column,\n  version,\n  filters = [],\n}: EventAPI & Partial<EventAPIExtender>) => {\n  const history = useHistory()\n  const { t } = useTranslation()\n  const { isMobile } = useSettings()\n  const { chainId, baseURL } = useSystem()\n  const { search, pathname } = useLocation()\n  const searchParams = new URLSearchParams(search)\n  const [rank, setRank] = React.useState<API_DATA<R> | undefined>(undefined)\n  const [rankTableData, setRankTableData] = React.useState<R[]>([])\n  const [searchValue, setSearchValue] = React.useState<string>('')\n  const [showLoading, setShowLoading] = React.useState(true)\n  const [selected, setSelected] = React.useState<string>(searchParams.get('selected') ?? filters[0])\n  const onChange = (event: React.ChangeEvent<{ value: string }>) => {\n    if (event.target.value) {\n      // setFilter((state) => ({ ...state, value: event.target.value } as any));\n      setSelected(event.target.value)\n      searchParams.set('selected', event.target.value)\n      history.push(pathname + '?' + searchParams.toString())\n    }\n  }\n\n  React.useEffect(() => {\n    if (searchValue !== '' && rank?.data?.length) {\n      setRankTableData((state) =>\n        rank?.data?.filter((item: any) => {\n          if (searchValue.startsWith('0x')) {\n            const regx = new RegExp(searchValue.toLowerCase(), 'ig')\n            return regx.test(item?.address)\n          } else {\n            const regx = new RegExp(searchValue.toLowerCase(), 'ig')\n            return regx.test(item?.address) || regx.test(item?.accountId)\n          }\n        }),\n      )\n    } else if (rank?.data?.length) {\n      setRankTableData([...rank?.data])\n    } else {\n      setRankTableData([])\n    }\n  }, [rank?.data, searchValue])\n\n  React.useEffect(() => {\n    getTableValues()\n  }, [selected])\n  const getTableValues = React.useCallback(async () => {\n    const l2account = searchParams.get('l2account') || searchParams.get('owner')\n    const _selected = filters?.find((item) => selected === item)\n    const url = `${baseURL}/${Activity_URL}?${_selected ? `&selected=${_selected}` : ''}${\n      l2account && l2account !== 'undefined' && l2account !== 'null' ? `&owner=${l2account}` : ''\n    }&version=${version}`\n    fetch(url)\n      .then((response) => response.json())\n      .then((json) => {\n        setRank(() => {\n          return { ...json } as API_DATA<R>\n        })\n        setShowLoading(false)\n      })\n      .catch(() => {\n        return []\n      })\n  }, [chainId, selected])\n\n  return (\n    <Box\n      flex={1}\n      display={'flex'}\n      flexDirection={'column'}\n      maxWidth={1200}\n      width={'100%'}\n      paddingX={isMobile ? 1 : 3}\n    >\n      <WrapperStyled flex={1} padding={isMobile ? 1 : 3}>\n        <Box\n          alignSelf={'flex-end'}\n          marginY={2}\n          display={'flex'}\n          justifyContent={'space-between'}\n          width={'100%'}\n        >\n          {!!filters?.length && (\n            <StyledTextFiled\n              id={'trading-race-filter'}\n              select\n              style={{ width: 150, textAlign: 'left' }}\n              value={selected}\n              onChange={onChange}\n              inputProps={{ IconComponent: DropDownIcon }}\n            >\n              {filters.map((item, index) => (\n                <MenuItem key={item + index} value={item}>\n                  {item}\n                </MenuItem>\n              ))}\n            </StyledTextFiled>\n          )}\n          <InputSearch\n            value={searchValue}\n            onChange={(value: any) => {\n              // setSearchValue(value)\n              setSearchValue(value)\n            }}\n          />\n        </Box>\n        <Box\n          display={'flex'}\n          justifyContent={'center'}\n          alignItems={'center'}\n          flexDirection={isMobile ? 'column' : 'row'}\n        >\n          <Typography\n            variant={'h5'}\n            display={'inline-flex'}\n            alignItems={'center'}\n            paddingRight={3}\n            component={'p'}\n          >\n            {t('labelTradeRaceYourRanking')}\n          </Typography>\n          {column.map((item, index) => (\n            <Typography\n              variant={'body1'}\n              key={item.key}\n              component={'span'}\n              display={'inline-flex'}\n              alignItems={'center'}\n              color={'textSecondary'}\n              whiteSpace={'pre-line'}\n              sx={{ wordBreak: 'break-all' }}\n              paddingRight={2}\n            >\n              {`${item.label}: `}\n              <Typography paddingLeft={1} component={'span'} color={'textPrimary'}>\n                {rank?.owner && rank?.owner[item.key] && rank?.owner[item.key] != '0'\n                  ? /address/gi.test(item.key.toLowerCase())\n                    ? getShortAddr(rank?.owner[item.key])\n                    : rank?.owner[item.key]\n                  : EmptyValueTag}\n              </Typography>\n              {index + 1 !== column.length ? ', ' : ''}\n            </Typography>\n          ))}\n        </Box>\n        <TableStyled\n          minHeight={120}\n          height={(((rankTableData && rankTableData?.length) ?? 0) + 1) * RowConfig.rowHeight}\n        >\n          {rank?.data?.length ? (\n            <TradeRaceTable\n              scrollable={true}\n              column={column}\n              rawData={rankTableData}\n              showloading={showLoading}\n            />\n          ) : (\n            <Box\n              flex={1}\n              height={'100%'}\n              display={'flex'}\n              alignItems={'center'}\n              justifyContent={'center'}\n            >\n              <img\n                className='loading-gif'\n                alt={'loading'}\n                width='60'\n                src={`${SoursURL}images/loading-line.gif`}\n              />\n            </Box>\n          )}\n        </TableStyled>\n      </WrapperStyled>\n    </Box>\n  )\n}\n"
  },
  {
    "path": "packages/webapp/src/pages/TradeRacePage/snow.css",
    "content": "@import url(https://fonts.googleapis.com/css?family=Varela+Round);\n\n.snow {\n    position: relative;\n    width: 100%;\n    height: 100%;\n    pointer-events: none;\n    opacity: 0.6;\n}\n\n.flake {\n    position: absolute;\n    border-radius: 50%;\n    transform: translateY(0) rotateX(0) rotateY(0);\n    background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuNSIgeTE9IjAuMCIgeDI9IjAuNSIgeTI9IjEuMCI+PHN0b3Agb2Zmc2V0PSIzMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiIHN0b3Atb3BhY2l0eT0iMC4wIi8+PHN0b3Agb2Zmc2V0PSI1MCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48c3RvcCBvZmZzZXQ9IjYwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIvPjxzdG9wIG9mZnNldD0iNjAlIiBzdG9wLWNvbG9yPSIjZmZmZmZmIiBzdG9wLW9wYWNpdHk9IjAuMCIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA=='),\n    url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIzMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiIHN0b3Atb3BhY2l0eT0iMC4wIi8+PHN0b3Agb2Zmc2V0PSI1MCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48c3RvcCBvZmZzZXQ9IjYwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIvPjxzdG9wIG9mZnNldD0iNjAlIiBzdG9wLWNvbG9yPSIjZmZmZmZmIiBzdG9wLW9wYWNpdHk9IjAuMCIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA=='),\n    url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjEuMCIgeDI9IjEuMCIgeTI9IjAuMCI+PHN0b3Agb2Zmc2V0PSIzMyUiIHN0b3AtY29sb3I9IiNmZmZmZmYiIHN0b3Atb3BhY2l0eT0iMC4wIi8+PHN0b3Agb2Zmc2V0PSI1MyUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48c3RvcCBvZmZzZXQ9IjU3JSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIvPjxzdG9wIG9mZnNldD0iNjUlIiBzdG9wLWNvbG9yPSIjZmZmZmZmIiBzdG9wLW9wYWNpdHk9IjAuMCIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA=='),\n    url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuMCIgeDI9IjEuMCIgeTI9IjEuMCI+PHN0b3Agb2Zmc2V0PSIzMyUiIHN0b3AtY29sb3I9IiNmZmZmZmYiIHN0b3Atb3BhY2l0eT0iMC4wIi8+PHN0b3Agb2Zmc2V0PSI1MyUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48c3RvcCBvZmZzZXQ9IjU3JSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIvPjxzdG9wIG9mZnNldD0iNjUlIiBzdG9wLWNvbG9yPSIjZmZmZmZmIiBzdG9wLW9wYWNpdHk9IjAuMCIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');\n    background-size: 100%;\n    background-image: linear-gradient(\n            180deg,\n            rgba(255, 255, 255, 0) 30%,\n            #ffffff 50%,\n            #ffffff 60%,\n            rgba(255, 255, 255, 0) 60%\n    ),\n    linear-gradient(\n            90deg,\n            rgba(255, 255, 255, 0) 30%,\n            #ffffff 50%,\n            #ffffff 60%,\n            rgba(255, 255, 255, 0) 60%\n    ),\n    linear-gradient(\n            45deg,\n            rgba(255, 255, 255, 0) 33%,\n            #ffffff 53%,\n            #ffffff 57%,\n            rgba(255, 255, 255, 0) 65%\n    ),\n    linear-gradient(\n            135deg,\n            rgba(255, 255, 255, 0) 33%,\n            #ffffff 53%,\n            #ffffff 57%,\n            rgba(255, 255, 255, 0) 65%\n    );\n}\n\n.flake:nth-child(1) {\n    width: 7px;\n    height: 7px;\n    top: -35px;\n    left: 55%;\n    opacity: 0.79;\n    filter: blur(3px);\n    -webkit-animation: 36s flakes linear infinite;\n    animation: 36s flakes linear infinite;\n}\n\n.flake:nth-child(2) {\n    width: 19px;\n    height: 19px;\n    top: -51px;\n    left: 25%;\n    opacity: 0.94;\n    filter: blur(3px);\n    -webkit-animation: 19s flakes linear infinite;\n    animation: 19s flakes linear infinite;\n}\n\n.flake:nth-child(3) {\n    width: 9px;\n    height: 9px;\n    top: -457px;\n    left: 33%;\n    opacity: 0.68;\n    filter: blur(3px);\n    -webkit-animation: 26s flakes linear infinite;\n    animation: 26s flakes linear infinite;\n}\n\n.flake:nth-child(4) {\n    width: 16px;\n    height: 16px;\n    top: -626px;\n    left: 72%;\n    opacity: 0.59;\n    filter: blur(4px);\n    -webkit-animation: 16s flakes linear infinite;\n    animation: 16s flakes linear infinite;\n}\n\n.flake:nth-child(5) {\n    width: 9px;\n    height: 9px;\n    top: -487px;\n    left: 3%;\n    opacity: 0.93;\n    filter: blur(3px);\n    -webkit-animation: 18s flakes linear infinite;\n    animation: 18s flakes linear infinite;\n}\n\n.flake:nth-child(6) {\n    width: 14px;\n    height: 14px;\n    top: -591px;\n    left: 85%;\n    opacity: 0.61;\n    filter: blur(4px);\n    -webkit-animation: 18s flakes linear infinite;\n    animation: 18s flakes linear infinite;\n}\n\n.flake:nth-child(7) {\n    width: 16px;\n    height: 16px;\n    top: -229px;\n    left: 83%;\n    opacity: 0.72;\n    filter: blur(3px);\n    -webkit-animation: 57s flakes linear infinite;\n    animation: 57s flakes linear infinite;\n}\n\n.flake:nth-child(8) {\n    width: 18px;\n    height: 18px;\n    top: -289px;\n    left: 29%;\n    opacity: 0.84;\n    filter: blur(4px);\n    -webkit-animation: 28s flakes linear infinite;\n    animation: 28s flakes linear infinite;\n}\n\n.flake:nth-child(9) {\n    width: 18px;\n    height: 18px;\n    top: -159px;\n    left: 71%;\n    opacity: 0.7;\n    filter: blur(3px);\n    -webkit-animation: 59s flakes linear infinite;\n    animation: 59s flakes linear infinite;\n}\n\n.flake:nth-child(10) {\n    width: 11px;\n    height: 11px;\n    top: -591px;\n    left: 8%;\n    opacity: 0.9;\n    filter: blur(3px);\n    -webkit-animation: 66s flakes linear infinite;\n    animation: 66s flakes linear infinite;\n}\n\n.flake:nth-child(11) {\n    width: 11px;\n    height: 11px;\n    top: -234px;\n    left: 86%;\n    opacity: 0.88;\n    filter: blur(4px);\n    -webkit-animation: 26s flakes linear infinite;\n    animation: 26s flakes linear infinite;\n}\n\n.flake:nth-child(12) {\n    width: 18px;\n    height: 18px;\n    top: -568px;\n    left: 26%;\n    opacity: 0.82;\n    filter: blur(4px);\n    -webkit-animation: 54s flakes linear infinite;\n    animation: 54s flakes linear infinite;\n}\n\n.flake:nth-child(13) {\n    width: 19px;\n    height: 19px;\n    top: -229px;\n    left: 14%;\n    opacity: 0.77;\n    filter: blur(3px);\n    -webkit-animation: 33s flakes linear infinite;\n    animation: 33s flakes linear infinite;\n}\n\n.flake:nth-child(14) {\n    width: 8px;\n    height: 8px;\n    top: -15px;\n    left: 5%;\n    opacity: 0.65;\n    filter: blur(4px);\n    -webkit-animation: 45s flakes linear infinite;\n    animation: 45s flakes linear infinite;\n}\n\n.flake:nth-child(15) {\n    width: 17px;\n    height: 17px;\n    top: -192px;\n    left: 96%;\n    opacity: 0.67;\n    filter: blur(3px);\n    -webkit-animation: 65s flakes linear infinite;\n    animation: 65s flakes linear infinite;\n}\n\n.flake:nth-child(16) {\n    width: 12px;\n    height: 12px;\n    top: -486px;\n    left: 66%;\n    opacity: 0.83;\n    filter: blur(3px);\n    -webkit-animation: 34s flakes linear infinite;\n    animation: 34s flakes linear infinite;\n}\n\n.flake:nth-child(17) {\n    width: 20px;\n    height: 20px;\n    top: -659px;\n    left: 85%;\n    opacity: 0.95;\n    filter: blur(3px);\n    -webkit-animation: 62s flakes linear infinite;\n    animation: 62s flakes linear infinite;\n}\n\n.flake:nth-child(18) {\n    width: 6px;\n    height: 6px;\n    top: -62px;\n    left: 29%;\n    opacity: 0.67;\n    filter: blur(3px);\n    -webkit-animation: 30s flakes linear infinite;\n    animation: 30s flakes linear infinite;\n}\n\n.flake:nth-child(19) {\n    width: 11px;\n    height: 11px;\n    top: -380px;\n    left: 21%;\n    opacity: 0.97;\n    filter: blur(4px);\n    -webkit-animation: 16s flakes linear infinite;\n    animation: 16s flakes linear infinite;\n}\n\n.flake:nth-child(20) {\n    width: 10px;\n    height: 10px;\n    top: -340px;\n    left: 10%;\n    opacity: 0.69;\n    filter: blur(3px);\n    -webkit-animation: 32s flakes linear infinite;\n    animation: 32s flakes linear infinite;\n}\n\n.flake:nth-child(21) {\n    width: 14px;\n    height: 14px;\n    top: -390px;\n    left: 28%;\n    opacity: 0.84;\n    filter: blur(3px);\n    -webkit-animation: 70s flakes linear infinite;\n    animation: 70s flakes linear infinite;\n}\n\n.flake:nth-child(22) {\n    width: 10px;\n    height: 10px;\n    top: -630px;\n    left: 45%;\n    opacity: 0.87;\n    filter: blur(3px);\n    -webkit-animation: 38s flakes linear infinite;\n    animation: 38s flakes linear infinite;\n}\n\n.flake:nth-child(23) {\n    width: 11px;\n    height: 11px;\n    top: -402px;\n    left: 82%;\n    opacity: 0.95;\n    filter: blur(4px);\n    -webkit-animation: 26s flakes linear infinite;\n    animation: 26s flakes linear infinite;\n}\n\n.flake:nth-child(24) {\n    width: 11px;\n    height: 11px;\n    top: -403px;\n    left: 61%;\n    opacity: 0.87;\n    filter: blur(3px);\n    -webkit-animation: 55s flakes linear infinite;\n    animation: 55s flakes linear infinite;\n}\n\n.flake:nth-child(25) {\n    width: 9px;\n    height: 9px;\n    top: -294px;\n    left: 57%;\n    opacity: 0.93;\n    filter: blur(4px);\n    -webkit-animation: 37s flakes linear infinite;\n    animation: 37s flakes linear infinite;\n}\n\n.flake:nth-child(26) {\n    width: 7px;\n    height: 7px;\n    top: -175px;\n    left: 45%;\n    opacity: 0.56;\n    filter: blur(4px);\n    -webkit-animation: 18s flakes linear infinite;\n    animation: 18s flakes linear infinite;\n}\n\n.flake:nth-child(27) {\n    width: 9px;\n    height: 9px;\n    top: -113px;\n    left: 2%;\n    opacity: 0.77;\n    filter: blur(3px);\n    -webkit-animation: 39s flakes linear infinite;\n    animation: 39s flakes linear infinite;\n}\n\n.flake:nth-child(28) {\n    width: 10px;\n    height: 10px;\n    top: -167px;\n    left: 50%;\n    opacity: 0.63;\n    filter: blur(3px);\n    -webkit-animation: 26s flakes linear infinite;\n    animation: 26s flakes linear infinite;\n}\n\n.flake:nth-child(29) {\n    width: 13px;\n    height: 13px;\n    top: -27px;\n    left: 59%;\n    opacity: 0.99;\n    filter: blur(3px);\n    -webkit-animation: 57s flakes linear infinite;\n    animation: 57s flakes linear infinite;\n}\n\n.flake:nth-child(30) {\n    width: 19px;\n    height: 19px;\n    top: -331px;\n    left: 94%;\n    opacity: 0.55;\n    filter: blur(4px);\n    -webkit-animation: 25s flakes linear infinite;\n    animation: 25s flakes linear infinite;\n}\n\n.flake:nth-child(31) {\n    width: 10px;\n    height: 10px;\n    top: -464px;\n    left: 73%;\n    opacity: 0.89;\n    filter: blur(4px);\n    -webkit-animation: 16s flakes linear infinite;\n    animation: 16s flakes linear infinite;\n}\n\n.flake:nth-child(32) {\n    width: 18px;\n    height: 18px;\n    top: -92px;\n    left: 66%;\n    opacity: 0.88;\n    filter: blur(3px);\n    -webkit-animation: 31s flakes linear infinite;\n    animation: 31s flakes linear infinite;\n}\n\n.flake:nth-child(33) {\n    width: 11px;\n    height: 11px;\n    top: -183px;\n    left: 76%;\n    opacity: 0.57;\n    filter: blur(4px);\n    -webkit-animation: 26s flakes linear infinite;\n    animation: 26s flakes linear infinite;\n}\n\n.flake:nth-child(34) {\n    width: 9px;\n    height: 9px;\n    top: -183px;\n    left: 15%;\n    opacity: 0.87;\n    filter: blur(3px);\n    -webkit-animation: 54s flakes linear infinite;\n    animation: 54s flakes linear infinite;\n}\n\n.flake:nth-child(35) {\n    width: 9px;\n    height: 9px;\n    top: -425px;\n    left: 10%;\n    opacity: 0.74;\n    filter: blur(3px);\n    -webkit-animation: 17s flakes linear infinite;\n    animation: 17s flakes linear infinite;\n}\n\n.flake:nth-child(36) {\n    width: 20px;\n    height: 20px;\n    top: -72px;\n    left: 23%;\n    opacity: 0.53;\n    filter: blur(3px);\n    -webkit-animation: 19s flakes linear infinite;\n    animation: 19s flakes linear infinite;\n}\n\n.flake:nth-child(37) {\n    width: 7px;\n    height: 7px;\n    top: -308px;\n    left: 56%;\n    opacity: 0.87;\n    filter: blur(4px);\n    -webkit-animation: 17s flakes linear infinite;\n    animation: 17s flakes linear infinite;\n}\n\n.flake:nth-child(38) {\n    width: 18px;\n    height: 18px;\n    top: -199px;\n    left: 15%;\n    opacity: 0.64;\n    filter: blur(4px);\n    -webkit-animation: 56s flakes linear infinite;\n    animation: 56s flakes linear infinite;\n}\n\n.flake:nth-child(39) {\n    width: 13px;\n    height: 13px;\n    top: -262px;\n    left: 59%;\n    opacity: 0.64;\n    filter: blur(4px);\n    -webkit-animation: 49s flakes linear infinite;\n    animation: 49s flakes linear infinite;\n}\n\n.flake:nth-child(40) {\n    width: 7px;\n    height: 7px;\n    top: -26px;\n    left: 83%;\n    opacity: 0.71;\n    filter: blur(4px);\n    -webkit-animation: 42s flakes linear infinite;\n    animation: 42s flakes linear infinite;\n}\n\n.flake:nth-child(41) {\n    width: 9px;\n    height: 9px;\n    top: -250px;\n    left: 67%;\n    opacity: 0.63;\n    filter: blur(4px);\n    -webkit-animation: 63s flakes linear infinite;\n    animation: 63s flakes linear infinite;\n}\n\n.flake:nth-child(42) {\n    width: 20px;\n    height: 20px;\n    top: -178px;\n    left: 86%;\n    opacity: 0.96;\n    filter: blur(4px);\n    -webkit-animation: 29s flakes linear infinite;\n    animation: 29s flakes linear infinite;\n}\n\n.flake:nth-child(43) {\n    width: 6px;\n    height: 6px;\n    top: -586px;\n    left: 73%;\n    opacity: 0.53;\n    filter: blur(4px);\n    -webkit-animation: 48s flakes linear infinite;\n    animation: 48s flakes linear infinite;\n}\n\n.flake:nth-child(44) {\n    width: 14px;\n    height: 14px;\n    top: -660px;\n    left: 47%;\n    opacity: 0.67;\n    filter: blur(4px);\n    -webkit-animation: 39s flakes linear infinite;\n    animation: 39s flakes linear infinite;\n}\n\n.flake:nth-child(45) {\n    width: 19px;\n    height: 19px;\n    top: -201px;\n    left: 95%;\n    opacity: 0.85;\n    filter: blur(3px);\n    -webkit-animation: 18s flakes linear infinite;\n    animation: 18s flakes linear infinite;\n}\n\n.flake:nth-child(46) {\n    width: 9px;\n    height: 9px;\n    top: -511px;\n    left: 90%;\n    opacity: 0.64;\n    filter: blur(3px);\n    -webkit-animation: 63s flakes linear infinite;\n    animation: 63s flakes linear infinite;\n}\n\n.flake:nth-child(47) {\n    width: 18px;\n    height: 18px;\n    top: -665px;\n    left: 62%;\n    opacity: 0.8;\n    filter: blur(3px);\n    -webkit-animation: 18s flakes linear infinite;\n    animation: 18s flakes linear infinite;\n}\n\n.flake:nth-child(48) {\n    width: 14px;\n    height: 14px;\n    top: -199px;\n    left: 93%;\n    opacity: 0.61;\n    filter: blur(4px);\n    -webkit-animation: 18s flakes linear infinite;\n    animation: 18s flakes linear infinite;\n}\n\n.flake:nth-child(49) {\n    width: 11px;\n    height: 11px;\n    top: -239px;\n    left: 34%;\n    opacity: 0.63;\n    filter: blur(4px);\n    -webkit-animation: 61s flakes linear infinite;\n    animation: 61s flakes linear infinite;\n}\n\n.flake:nth-child(50) {\n    width: 9px;\n    height: 9px;\n    top: -255px;\n    left: 98%;\n    opacity: 0.92;\n    filter: blur(3px);\n    -webkit-animation: 43s flakes linear infinite;\n    animation: 43s flakes linear infinite;\n}\n\n.flake:nth-child(51) {\n    width: 13px;\n    height: 13px;\n    top: -638px;\n    left: 1%;\n    opacity: 0.67;\n    filter: blur(3px);\n    -webkit-animation: 59s flakes linear infinite;\n    animation: 59s flakes linear infinite;\n}\n\n.flake:nth-child(52) {\n    width: 14px;\n    height: 14px;\n    top: -51px;\n    left: 99%;\n    opacity: 0.94;\n    filter: blur(3px);\n    -webkit-animation: 44s flakes linear infinite;\n    animation: 44s flakes linear infinite;\n}\n\n.flake:nth-child(53) {\n    width: 15px;\n    height: 15px;\n    top: -660px;\n    left: 76%;\n    opacity: 0.95;\n    filter: blur(3px);\n    -webkit-animation: 48s flakes linear infinite;\n    animation: 48s flakes linear infinite;\n}\n\n.flake:nth-child(54) {\n    width: 7px;\n    height: 7px;\n    top: -367px;\n    left: 10%;\n    opacity: 0.91;\n    filter: blur(4px);\n    -webkit-animation: 69s flakes linear infinite;\n    animation: 69s flakes linear infinite;\n}\n\n.flake:nth-child(55) {\n    width: 10px;\n    height: 10px;\n    top: -226px;\n    left: 16%;\n    opacity: 0.58;\n    filter: blur(4px);\n    -webkit-animation: 23s flakes linear infinite;\n    animation: 23s flakes linear infinite;\n}\n\n.flake:nth-child(56) {\n    width: 19px;\n    height: 19px;\n    top: -253px;\n    left: 51%;\n    opacity: 0.52;\n    filter: blur(3px);\n    -webkit-animation: 26s flakes linear infinite;\n    animation: 26s flakes linear infinite;\n}\n\n.flake:nth-child(57) {\n    width: 14px;\n    height: 14px;\n    top: -608px;\n    left: 87%;\n    opacity: 0.66;\n    filter: blur(3px);\n    -webkit-animation: 43s flakes linear infinite;\n    animation: 43s flakes linear infinite;\n}\n\n.flake:nth-child(58) {\n    width: 14px;\n    height: 14px;\n    top: -96px;\n    left: 64%;\n    opacity: 0.89;\n    filter: blur(4px);\n    -webkit-animation: 22s flakes linear infinite;\n    animation: 22s flakes linear infinite;\n}\n\n.flake:nth-child(59) {\n    width: 15px;\n    height: 15px;\n    top: -289px;\n    left: 61%;\n    opacity: 0.67;\n    filter: blur(3px);\n    -webkit-animation: 67s flakes linear infinite;\n    animation: 67s flakes linear infinite;\n}\n\n.flake:nth-child(60) {\n    width: 8px;\n    height: 8px;\n    top: -12px;\n    left: 75%;\n    opacity: 0.63;\n    filter: blur(4px);\n    -webkit-animation: 40s flakes linear infinite;\n    animation: 40s flakes linear infinite;\n}\n\n.flake:nth-child(61) {\n    width: 19px;\n    height: 19px;\n    top: -577px;\n    left: 85%;\n    opacity: 0.64;\n    filter: blur(4px);\n    -webkit-animation: 61s flakes linear infinite;\n    animation: 61s flakes linear infinite;\n}\n\n.flake:nth-child(62) {\n    width: 17px;\n    height: 17px;\n    top: -460px;\n    left: 17%;\n    opacity: 0.98;\n    filter: blur(3px);\n    -webkit-animation: 62s flakes linear infinite;\n    animation: 62s flakes linear infinite;\n}\n\n.flake:nth-child(63) {\n    width: 9px;\n    height: 9px;\n    top: -185px;\n    left: 20%;\n    opacity: 0.86;\n    filter: blur(3px);\n    -webkit-animation: 40s flakes linear infinite;\n    animation: 40s flakes linear infinite;\n}\n\n.flake:nth-child(64) {\n    width: 14px;\n    height: 14px;\n    top: -513px;\n    left: 14%;\n    opacity: 0.65;\n    filter: blur(3px);\n    -webkit-animation: 67s flakes linear infinite;\n    animation: 67s flakes linear infinite;\n}\n\n.flake:nth-child(65) {\n    width: 9px;\n    height: 9px;\n    top: -626px;\n    left: 8%;\n    opacity: 0.61;\n    filter: blur(3px);\n    -webkit-animation: 70s flakes linear infinite;\n    animation: 70s flakes linear infinite;\n}\n\n.flake:nth-child(66) {\n    width: 14px;\n    height: 14px;\n    top: -433px;\n    left: 68%;\n    opacity: 0.95;\n    filter: blur(3px);\n    -webkit-animation: 20s flakes linear infinite;\n    animation: 20s flakes linear infinite;\n}\n\n.flake:nth-child(67) {\n    width: 16px;\n    height: 16px;\n    top: -283px;\n    left: 41%;\n    opacity: 0.58;\n    filter: blur(4px);\n    -webkit-animation: 68s flakes linear infinite;\n    animation: 68s flakes linear infinite;\n}\n\n.flake:nth-child(68) {\n    width: 15px;\n    height: 15px;\n    top: -242px;\n    left: 57%;\n    opacity: 0.95;\n    filter: blur(4px);\n    -webkit-animation: 38s flakes linear infinite;\n    animation: 38s flakes linear infinite;\n}\n\n.flake:nth-child(69) {\n    width: 8px;\n    height: 8px;\n    top: -505px;\n    left: 90%;\n    opacity: 0.66;\n    filter: blur(3px);\n    -webkit-animation: 51s flakes linear infinite;\n    animation: 51s flakes linear infinite;\n}\n\n.flake:nth-child(70) {\n    width: 16px;\n    height: 16px;\n    top: -15px;\n    left: 34%;\n    opacity: 0.96;\n    filter: blur(3px);\n    -webkit-animation: 53s flakes linear infinite;\n    animation: 53s flakes linear infinite;\n}\n\n.flake:nth-child(71) {\n    width: 17px;\n    height: 17px;\n    top: -386px;\n    left: 34%;\n    opacity: 0.62;\n    filter: blur(4px);\n    -webkit-animation: 28s flakes linear infinite;\n    animation: 28s flakes linear infinite;\n}\n\n.flake:nth-child(72) {\n    width: 16px;\n    height: 16px;\n    top: -42px;\n    left: 47%;\n    opacity: 0.96;\n    filter: blur(4px);\n    -webkit-animation: 18s flakes linear infinite;\n    animation: 18s flakes linear infinite;\n}\n\n.flake:nth-child(73) {\n    width: 15px;\n    height: 15px;\n    top: -559px;\n    left: 17%;\n    opacity: 0.93;\n    filter: blur(4px);\n    -webkit-animation: 47s flakes linear infinite;\n    animation: 47s flakes linear infinite;\n}\n\n.flake:nth-child(74) {\n    width: 15px;\n    height: 15px;\n    top: -570px;\n    left: 2%;\n    opacity: 0.9;\n    filter: blur(3px);\n    -webkit-animation: 30s flakes linear infinite;\n    animation: 30s flakes linear infinite;\n}\n\n.flake:nth-child(75) {\n    width: 10px;\n    height: 10px;\n    top: -612px;\n    left: 53%;\n    opacity: 0.92;\n    filter: blur(4px);\n    -webkit-animation: 40s flakes linear infinite;\n    animation: 40s flakes linear infinite;\n}\n\n.flake:nth-child(76) {\n    width: 19px;\n    height: 19px;\n    top: -185px;\n    left: 84%;\n    opacity: 0.91;\n    filter: blur(3px);\n    -webkit-animation: 37s flakes linear infinite;\n    animation: 37s flakes linear infinite;\n}\n\n.flake:nth-child(77) {\n    width: 9px;\n    height: 9px;\n    top: -605px;\n    left: 1%;\n    opacity: 0.83;\n    filter: blur(4px);\n    -webkit-animation: 62s flakes linear infinite;\n    animation: 62s flakes linear infinite;\n}\n\n.flake:nth-child(78) {\n    width: 19px;\n    height: 19px;\n    top: -95px;\n    left: 43%;\n    opacity: 0.69;\n    filter: blur(3px);\n    -webkit-animation: 23s flakes linear infinite;\n    animation: 23s flakes linear infinite;\n}\n\n.flake:nth-child(79) {\n    width: 8px;\n    height: 8px;\n    top: -547px;\n    left: 53%;\n    opacity: 0.76;\n    filter: blur(4px);\n    -webkit-animation: 46s flakes linear infinite;\n    animation: 46s flakes linear infinite;\n}\n\n.flake:nth-child(80) {\n    width: 17px;\n    height: 17px;\n    top: -118px;\n    left: 88%;\n    opacity: 0.68;\n    filter: blur(3px);\n    -webkit-animation: 37s flakes linear infinite;\n    animation: 37s flakes linear infinite;\n}\n\n.flake:nth-child(81) {\n    width: 17px;\n    height: 17px;\n    top: -466px;\n    left: 38%;\n    opacity: 0.67;\n    filter: blur(3px);\n    -webkit-animation: 26s flakes linear infinite;\n    animation: 26s flakes linear infinite;\n}\n\n.flake:nth-child(82) {\n    width: 11px;\n    height: 11px;\n    top: -670px;\n    left: 24%;\n    opacity: 0.74;\n    filter: blur(4px);\n    -webkit-animation: 37s flakes linear infinite;\n    animation: 37s flakes linear infinite;\n}\n\n.flake:nth-child(83) {\n    width: 9px;\n    height: 9px;\n    top: -188px;\n    left: 37%;\n    opacity: 0.89;\n    filter: blur(4px);\n    -webkit-animation: 40s flakes linear infinite;\n    animation: 40s flakes linear infinite;\n}\n\n.flake:nth-child(84) {\n    width: 13px;\n    height: 13px;\n    top: -273px;\n    left: 44%;\n    opacity: 0.53;\n    filter: blur(3px);\n    -webkit-animation: 58s flakes linear infinite;\n    animation: 58s flakes linear infinite;\n}\n\n.flake:nth-child(85) {\n    width: 14px;\n    height: 14px;\n    top: -579px;\n    left: 6%;\n    opacity: 0.82;\n    filter: blur(4px);\n    -webkit-animation: 29s flakes linear infinite;\n    animation: 29s flakes linear infinite;\n}\n\n.flake:nth-child(86) {\n    width: 13px;\n    height: 13px;\n    top: -699px;\n    left: 88%;\n    opacity: 0.91;\n    filter: blur(4px);\n    -webkit-animation: 51s flakes linear infinite;\n    animation: 51s flakes linear infinite;\n}\n\n.flake:nth-child(87) {\n    width: 14px;\n    height: 14px;\n    top: -265px;\n    left: 64%;\n    opacity: 0.92;\n    filter: blur(3px);\n    -webkit-animation: 67s flakes linear infinite;\n    animation: 67s flakes linear infinite;\n}\n\n.flake:nth-child(88) {\n    width: 10px;\n    height: 10px;\n    top: -113px;\n    left: 76%;\n    opacity: 0.87;\n    filter: blur(3px);\n    -webkit-animation: 61s flakes linear infinite;\n    animation: 61s flakes linear infinite;\n}\n\n.flake:nth-child(89) {\n    width: 7px;\n    height: 7px;\n    top: -146px;\n    left: 78%;\n    opacity: 0.97;\n    filter: blur(4px);\n    -webkit-animation: 38s flakes linear infinite;\n    animation: 38s flakes linear infinite;\n}\n\n.flake:nth-child(90) {\n    width: 19px;\n    height: 19px;\n    top: -105px;\n    left: 82%;\n    opacity: 0.85;\n    filter: blur(4px);\n    -webkit-animation: 61s flakes linear infinite;\n    animation: 61s flakes linear infinite;\n}\n\n.flake:nth-child(91) {\n    width: 10px;\n    height: 10px;\n    top: -287px;\n    left: 94%;\n    opacity: 0.9;\n    filter: blur(4px);\n    -webkit-animation: 38s flakes linear infinite;\n    animation: 38s flakes linear infinite;\n}\n\n.flake:nth-child(92) {\n    width: 10px;\n    height: 10px;\n    top: -140px;\n    left: 28%;\n    opacity: 0.96;\n    filter: blur(4px);\n    -webkit-animation: 27s flakes linear infinite;\n    animation: 27s flakes linear infinite;\n}\n\n.flake:nth-child(93) {\n    width: 16px;\n    height: 16px;\n    top: -494px;\n    left: 3%;\n    opacity: 0.54;\n    filter: blur(3px);\n    -webkit-animation: 32s flakes linear infinite;\n    animation: 32s flakes linear infinite;\n}\n\n.flake:nth-child(94) {\n    width: 7px;\n    height: 7px;\n    top: -482px;\n    left: 91%;\n    opacity: 0.76;\n    filter: blur(4px);\n    -webkit-animation: 58s flakes linear infinite;\n    animation: 58s flakes linear infinite;\n}\n\n.flake:nth-child(95) {\n    width: 7px;\n    height: 7px;\n    top: -334px;\n    left: 48%;\n    opacity: 0.87;\n    filter: blur(3px);\n    -webkit-animation: 21s flakes linear infinite;\n    animation: 21s flakes linear infinite;\n}\n\n.flake:nth-child(96) {\n    width: 9px;\n    height: 9px;\n    top: -147px;\n    left: 65%;\n    opacity: 0.85;\n    filter: blur(4px);\n    -webkit-animation: 33s flakes linear infinite;\n    animation: 33s flakes linear infinite;\n}\n\n.flake:nth-child(97) {\n    width: 20px;\n    height: 20px;\n    top: -33px;\n    left: 52%;\n    opacity: 0.67;\n    filter: blur(3px);\n    -webkit-animation: 49s flakes linear infinite;\n    animation: 49s flakes linear infinite;\n}\n\n.flake:nth-child(98) {\n    width: 7px;\n    height: 7px;\n    top: -260px;\n    left: 65%;\n    opacity: 0.69;\n    filter: blur(4px);\n    -webkit-animation: 27s flakes linear infinite;\n    animation: 27s flakes linear infinite;\n}\n\n.flake:nth-child(99) {\n    width: 15px;\n    height: 15px;\n    top: -249px;\n    left: 47%;\n    opacity: 0.66;\n    filter: blur(4px);\n    -webkit-animation: 26s flakes linear infinite;\n    animation: 26s flakes linear infinite;\n}\n\n.flake:nth-child(100) {\n    width: 16px;\n    height: 16px;\n    top: -490px;\n    left: 86%;\n    opacity: 0.63;\n    filter: blur(3px);\n    -webkit-animation: 26s flakes linear infinite;\n    animation: 26s flakes linear infinite;\n}\n\n.flake:nth-child(101) {\n    width: 9px;\n    height: 9px;\n    top: -363px;\n    left: 49%;\n    opacity: 0.89;\n    filter: blur(3px);\n    -webkit-animation: 67s flakes linear infinite;\n    animation: 67s flakes linear infinite;\n}\n\n.flake:nth-child(102) {\n    width: 19px;\n    height: 19px;\n    top: -103px;\n    left: 1%;\n    opacity: 0.77;\n    filter: blur(4px);\n    -webkit-animation: 31s flakes linear infinite;\n    animation: 31s flakes linear infinite;\n}\n\n.flake:nth-child(103) {\n    width: 7px;\n    height: 7px;\n    top: -660px;\n    left: 17%;\n    opacity: 0.93;\n    filter: blur(4px);\n    -webkit-animation: 68s flakes linear infinite;\n    animation: 68s flakes linear infinite;\n}\n\n.flake:nth-child(104) {\n    width: 15px;\n    height: 15px;\n    top: -679px;\n    left: 46%;\n    opacity: 0.53;\n    filter: blur(3px);\n    -webkit-animation: 48s flakes linear infinite;\n    animation: 48s flakes linear infinite;\n}\n\n.flake:nth-child(105) {\n    width: 11px;\n    height: 11px;\n    top: -217px;\n    left: 92%;\n    opacity: 0.78;\n    filter: blur(4px);\n    -webkit-animation: 69s flakes linear infinite;\n    animation: 69s flakes linear infinite;\n}\n\n.flake:nth-child(106) {\n    width: 7px;\n    height: 7px;\n    top: -239px;\n    left: 32%;\n    opacity: 0.62;\n    filter: blur(4px);\n    -webkit-animation: 51s flakes linear infinite;\n    animation: 51s flakes linear infinite;\n}\n\n.flake:nth-child(107) {\n    width: 19px;\n    height: 19px;\n    top: -373px;\n    left: 56%;\n    opacity: 0.82;\n    filter: blur(4px);\n    -webkit-animation: 53s flakes linear infinite;\n    animation: 53s flakes linear infinite;\n}\n\n.flake:nth-child(108) {\n    width: 16px;\n    height: 16px;\n    top: -625px;\n    left: 90%;\n    opacity: 0.77;\n    filter: blur(3px);\n    -webkit-animation: 42s flakes linear infinite;\n    animation: 42s flakes linear infinite;\n}\n\n.flake:nth-child(109) {\n    width: 14px;\n    height: 14px;\n    top: -551px;\n    left: 90%;\n    opacity: 0.78;\n    filter: blur(3px);\n    -webkit-animation: 60s flakes linear infinite;\n    animation: 60s flakes linear infinite;\n}\n\n.flake:nth-child(110) {\n    width: 8px;\n    height: 8px;\n    top: -662px;\n    left: 12%;\n    opacity: 0.82;\n    filter: blur(4px);\n    -webkit-animation: 57s flakes linear infinite;\n    animation: 57s flakes linear infinite;\n}\n\n.flake:nth-child(111) {\n    width: 14px;\n    height: 14px;\n    top: -308px;\n    left: 43%;\n    opacity: 0.97;\n    filter: blur(4px);\n    -webkit-animation: 65s flakes linear infinite;\n    animation: 65s flakes linear infinite;\n}\n\n.flake:nth-child(112) {\n    width: 6px;\n    height: 6px;\n    top: -677px;\n    left: 24%;\n    opacity: 0.58;\n    filter: blur(3px);\n    -webkit-animation: 55s flakes linear infinite;\n    animation: 55s flakes linear infinite;\n}\n\n.flake:nth-child(113) {\n    width: 12px;\n    height: 12px;\n    top: -650px;\n    left: 11%;\n    opacity: 0.99;\n    filter: blur(4px);\n    -webkit-animation: 46s flakes linear infinite;\n    animation: 46s flakes linear infinite;\n}\n\n.flake:nth-child(114) {\n    width: 14px;\n    height: 14px;\n    top: -460px;\n    left: 72%;\n    opacity: 0.96;\n    filter: blur(4px);\n    -webkit-animation: 58s flakes linear infinite;\n    animation: 58s flakes linear infinite;\n}\n\n.flake:nth-child(115) {\n    width: 19px;\n    height: 19px;\n    top: -187px;\n    left: 8%;\n    opacity: 0.73;\n    filter: blur(3px);\n    -webkit-animation: 27s flakes linear infinite;\n    animation: 27s flakes linear infinite;\n}\n\n.flake:nth-child(116) {\n    width: 13px;\n    height: 13px;\n    top: -54px;\n    left: 70%;\n    opacity: 0.64;\n    filter: blur(3px);\n    -webkit-animation: 26s flakes linear infinite;\n    animation: 26s flakes linear infinite;\n}\n\n.flake:nth-child(117) {\n    width: 15px;\n    height: 15px;\n    top: -231px;\n    left: 2%;\n    opacity: 0.93;\n    filter: blur(3px);\n    -webkit-animation: 51s flakes linear infinite;\n    animation: 51s flakes linear infinite;\n}\n\n.flake:nth-child(118) {\n    width: 10px;\n    height: 10px;\n    top: -439px;\n    left: 6%;\n    opacity: 0.94;\n    filter: blur(4px);\n    -webkit-animation: 40s flakes linear infinite;\n    animation: 40s flakes linear infinite;\n}\n\n.flake:nth-child(119) {\n    width: 12px;\n    height: 12px;\n    top: -371px;\n    left: 69%;\n    opacity: 0.93;\n    filter: blur(4px);\n    -webkit-animation: 41s flakes linear infinite;\n    animation: 41s flakes linear infinite;\n}\n\n.flake:nth-child(120) {\n    width: 16px;\n    height: 16px;\n    top: -295px;\n    left: 68%;\n    opacity: 0.72;\n    filter: blur(4px);\n    -webkit-animation: 39s flakes linear infinite;\n    animation: 39s flakes linear infinite;\n}\n\n.flake:nth-child(121) {\n    width: 19px;\n    height: 19px;\n    top: -610px;\n    left: 35%;\n    opacity: 0.8;\n    filter: blur(3px);\n    -webkit-animation: 33s flakes linear infinite;\n    animation: 33s flakes linear infinite;\n}\n\n.flake:nth-child(122) {\n    width: 12px;\n    height: 12px;\n    top: -405px;\n    left: 27%;\n    opacity: 0.68;\n    filter: blur(3px);\n    -webkit-animation: 43s flakes linear infinite;\n    animation: 43s flakes linear infinite;\n}\n\n.flake:nth-child(123) {\n    width: 19px;\n    height: 19px;\n    top: -166px;\n    left: 30%;\n    opacity: 0.61;\n    filter: blur(3px);\n    -webkit-animation: 33s flakes linear infinite;\n    animation: 33s flakes linear infinite;\n}\n\n.flake:nth-child(124) {\n    width: 7px;\n    height: 7px;\n    top: -69px;\n    left: 33%;\n    opacity: 0.66;\n    filter: blur(4px);\n    -webkit-animation: 57s flakes linear infinite;\n    animation: 57s flakes linear infinite;\n}\n\n.flake:nth-child(125) {\n    width: 16px;\n    height: 16px;\n    top: -196px;\n    left: 95%;\n    opacity: 0.51;\n    filter: blur(4px);\n    -webkit-animation: 23s flakes linear infinite;\n    animation: 23s flakes linear infinite;\n}\n\n.flake:nth-child(126) {\n    width: 7px;\n    height: 7px;\n    top: -470px;\n    left: 31%;\n    opacity: 0.52;\n    filter: blur(4px);\n    -webkit-animation: 52s flakes linear infinite;\n    animation: 52s flakes linear infinite;\n}\n\n.flake:nth-child(127) {\n    width: 11px;\n    height: 11px;\n    top: -233px;\n    left: 67%;\n    opacity: 0.98;\n    filter: blur(4px);\n    -webkit-animation: 70s flakes linear infinite;\n    animation: 70s flakes linear infinite;\n}\n\n.flake:nth-child(128) {\n    width: 9px;\n    height: 9px;\n    top: -489px;\n    left: 96%;\n    opacity: 0.62;\n    filter: blur(4px);\n    -webkit-animation: 18s flakes linear infinite;\n    animation: 18s flakes linear infinite;\n}\n\n.flake:nth-child(129) {\n    width: 10px;\n    height: 10px;\n    top: -285px;\n    left: 94%;\n    opacity: 0.73;\n    filter: blur(4px);\n    -webkit-animation: 49s flakes linear infinite;\n    animation: 49s flakes linear infinite;\n}\n\n.flake:nth-child(130) {\n    width: 18px;\n    height: 18px;\n    top: -619px;\n    left: 44%;\n    opacity: 0.64;\n    filter: blur(3px);\n    -webkit-animation: 38s flakes linear infinite;\n    animation: 38s flakes linear infinite;\n}\n\n.flake:nth-child(131) {\n    width: 18px;\n    height: 18px;\n    top: -50px;\n    left: 100%;\n    opacity: 0.71;\n    filter: blur(3px);\n    -webkit-animation: 39s flakes linear infinite;\n    animation: 39s flakes linear infinite;\n}\n\n.flake:nth-child(132) {\n    width: 16px;\n    height: 16px;\n    top: -423px;\n    left: 56%;\n    opacity: 0.68;\n    filter: blur(3px);\n    -webkit-animation: 50s flakes linear infinite;\n    animation: 50s flakes linear infinite;\n}\n\n.flake:nth-child(133) {\n    width: 18px;\n    height: 18px;\n    top: -616px;\n    left: 93%;\n    opacity: 0.79;\n    filter: blur(3px);\n    -webkit-animation: 29s flakes linear infinite;\n    animation: 29s flakes linear infinite;\n}\n\n.flake:nth-child(134) {\n    width: 13px;\n    height: 13px;\n    top: -618px;\n    left: 73%;\n    opacity: 0.71;\n    filter: blur(4px);\n    -webkit-animation: 18s flakes linear infinite;\n    animation: 18s flakes linear infinite;\n}\n\n.flake:nth-child(135) {\n    width: 17px;\n    height: 17px;\n    top: -239px;\n    left: 31%;\n    opacity: 0.64;\n    filter: blur(4px);\n    -webkit-animation: 48s flakes linear infinite;\n    animation: 48s flakes linear infinite;\n}\n\n.flake:nth-child(136) {\n    width: 11px;\n    height: 11px;\n    top: -522px;\n    left: 57%;\n    opacity: 0.95;\n    filter: blur(3px);\n    -webkit-animation: 21s flakes linear infinite;\n    animation: 21s flakes linear infinite;\n}\n\n.flake:nth-child(137) {\n    width: 17px;\n    height: 17px;\n    top: -78px;\n    left: 73%;\n    opacity: 0.52;\n    filter: blur(4px);\n    -webkit-animation: 30s flakes linear infinite;\n    animation: 30s flakes linear infinite;\n}\n\n.flake:nth-child(138) {\n    width: 10px;\n    height: 10px;\n    top: -108px;\n    left: 100%;\n    opacity: 0.96;\n    filter: blur(4px);\n    -webkit-animation: 29s flakes linear infinite;\n    animation: 29s flakes linear infinite;\n}\n\n.flake:nth-child(139) {\n    width: 18px;\n    height: 18px;\n    top: -441px;\n    left: 58%;\n    opacity: 0.81;\n    filter: blur(4px);\n    -webkit-animation: 67s flakes linear infinite;\n    animation: 67s flakes linear infinite;\n}\n\n.flake:nth-child(140) {\n    width: 9px;\n    height: 9px;\n    top: -144px;\n    left: 30%;\n    opacity: 0.96;\n    filter: blur(4px);\n    -webkit-animation: 45s flakes linear infinite;\n    animation: 45s flakes linear infinite;\n}\n\n.flake:nth-child(141) {\n    width: 20px;\n    height: 20px;\n    top: -176px;\n    left: 67%;\n    opacity: 0.71;\n    filter: blur(4px);\n    -webkit-animation: 46s flakes linear infinite;\n    animation: 46s flakes linear infinite;\n}\n\n.flake:nth-child(142) {\n    width: 6px;\n    height: 6px;\n    top: -583px;\n    left: 60%;\n    opacity: 0.92;\n    filter: blur(4px);\n    -webkit-animation: 29s flakes linear infinite;\n    animation: 29s flakes linear infinite;\n}\n\n.flake:nth-child(143) {\n    width: 10px;\n    height: 10px;\n    top: -570px;\n    left: 31%;\n    opacity: 0.64;\n    filter: blur(4px);\n    -webkit-animation: 18s flakes linear infinite;\n    animation: 18s flakes linear infinite;\n}\n\n.flake:nth-child(144) {\n    width: 13px;\n    height: 13px;\n    top: -313px;\n    left: 78%;\n    opacity: 0.51;\n    filter: blur(3px);\n    -webkit-animation: 58s flakes linear infinite;\n    animation: 58s flakes linear infinite;\n}\n\n.flake:nth-child(145) {\n    width: 20px;\n    height: 20px;\n    top: -663px;\n    left: 28%;\n    opacity: 0.97;\n    filter: blur(3px);\n    -webkit-animation: 68s flakes linear infinite;\n    animation: 68s flakes linear infinite;\n}\n\n.flake:nth-child(146) {\n    width: 6px;\n    height: 6px;\n    top: -445px;\n    left: 18%;\n    opacity: 0.76;\n    filter: blur(3px);\n    -webkit-animation: 27s flakes linear infinite;\n    animation: 27s flakes linear infinite;\n}\n\n.flake:nth-child(147) {\n    width: 6px;\n    height: 6px;\n    top: -464px;\n    left: 2%;\n    opacity: 0.56;\n    filter: blur(4px);\n    -webkit-animation: 23s flakes linear infinite;\n    animation: 23s flakes linear infinite;\n}\n\n.flake:nth-child(148) {\n    width: 18px;\n    height: 18px;\n    top: -523px;\n    left: 82%;\n    opacity: 0.56;\n    filter: blur(4px);\n    -webkit-animation: 66s flakes linear infinite;\n    animation: 66s flakes linear infinite;\n}\n\n.flake:nth-child(149) {\n    width: 20px;\n    height: 20px;\n    top: -400px;\n    left: 62%;\n    opacity: 0.6;\n    filter: blur(4px);\n    -webkit-animation: 48s flakes linear infinite;\n    animation: 48s flakes linear infinite;\n}\n\n.flake:nth-child(150) {\n    width: 20px;\n    height: 20px;\n    top: -399px;\n    left: 36%;\n    opacity: 0.72;\n    filter: blur(3px);\n    -webkit-animation: 69s flakes linear infinite;\n    animation: 69s flakes linear infinite;\n}\n\n@-webkit-keyframes flakes {\n    100% {\n        transform: translateY(1000px) rotateX(35deg) rotateY(27deg);\n        opacity: 0;\n    }\n}\n\n@keyframes flakes {\n    100% {\n        transform: translateY(1000px) rotateX(35deg) rotateY(27deg);\n        opacity: 0;\n    }\n}\n"
  },
  {
    "path": "packages/webapp/src/react-app-env.d.ts",
    "content": "/// <reference types=\"react-scripts\" />\n// window.__loopringEnv__ = process.env;\n"
  },
  {
    "path": "packages/webapp/src/reportWebVitals.ts",
    "content": "import { ReportHandler } from 'web-vitals'\n\nconst reportWebVitals = (onPerfEntry?: ReportHandler) => {\n  if (onPerfEntry && onPerfEntry instanceof Function) {\n    import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {\n      getCLS(onPerfEntry)\n      getFID(onPerfEntry)\n      getFCP(onPerfEntry)\n      getLCP(onPerfEntry)\n      getTTFB(onPerfEntry)\n    })\n  }\n}\n\nexport default reportWebVitals\n"
  },
  {
    "path": "packages/webapp/src/routers/index.tsx",
    "content": "import { Route, Switch, useHistory, useLocation, Redirect } from 'react-router-dom'\nimport React from 'react'\nimport { Box, Container, Link, Snackbar, Typography } from '@mui/material'\nimport Header from 'layouts/header'\nimport { QuotePage } from 'pages/QuotePage'\nimport { SwapPage } from 'pages/SwapPage'\nimport { Layer2Page } from 'pages/Layer2Page'\nimport { MiningPage } from 'pages/MiningPage'\nimport { OrderbookPage } from 'pages/ProTradePage'\nimport {\n  ModalCoinPairPanel,\n  ModalGroup,\n  ModalRedPacketPanel,\n  store,\n  useDeposit,\n  useNotificationSocket,\n  useNotify,\n  useOffFaitModal,\n  useSystem,\n  useTicker,\n  useTokenMap,\n  useVaultMap,\n  NoticePop,\n} from '@loopring-web/core'\nimport { LoadingPage } from '../pages/LoadingPage'\nimport { LandPage, HomePage, LandBtn } from '../pages/LandPage'\nimport {\n  ErrorMap,\n  GUARDIAN_URL,\n  MapChainId,\n  RouterAllowIndex,\n  RouterMainKey,\n  RouterPath,\n  SagaStatus,\n  setMyLog,\n  ThemeType,\n  VendorProviders,\n  WalletSite,\n} from '@loopring-web/common-resources'\nimport { ErrorPage } from '../pages/ErrorPage'\nimport {\n  LoadingBlock,\n  NoticePanelSnackBar,\n  NoticeSnack,\n  useSettings,\n  useToggle,\n} from '@loopring-web/component-lib'\nimport { MarkdownPage, NotifyMarkdownPage } from '../pages/MarkdownPage'\nimport { TradeRacePage } from '../pages/TradeRacePage'\nimport { NFTPage } from '../pages/NFTPage'\nimport { useGetAssets } from '../pages/AssetPage/AssetPanel/hook'\nimport { Footer } from '../layouts/footer'\nimport { InvestPage } from '../pages/InvestPage'\nimport { getAnalytics, logEvent } from 'firebase/analytics'\nimport { AssetPage } from '../pages/AssetPage'\nimport { FiatPage } from '../pages/FiatPage'\nimport { RedPacketPage } from '../pages/RedPacketPage'\nimport { useTranslation } from 'react-i18next'\nimport { BtradeSwapPage } from '../pages/BtradeSwapPage'\nimport { StopLimitPage } from '../pages/ProTradePage/stopLimtPage'\nimport { VaultPage } from '@loopring-web/component-lib'\nconst ContentWrap = ({\n  children,\n  state,\n  noContainer = false,\n  value,\n}: React.PropsWithChildren<any> & {\n  state: keyof typeof SagaStatus\n  noContainer: boolean\n  value: string\n}) => {\n  const { defaultNetwork } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n  return (\n    <>\n      <Header isHideOnScroll={false} />\n      {state === 'PENDING' ? (\n        <LoadingBlock />\n      ) : state === 'ERROR' || !RouterAllowIndex[network]?.includes(value) ? (\n        <ErrorPage\n          {...(!RouterAllowIndex[network]?.includes(value)\n            ? ErrorMap.TRADE_404\n            : ErrorMap.NO_NETWORK_ERROR)}\n        />\n      ) : noContainer ? (\n        <>{children}</>\n      ) : (\n        <Container\n          maxWidth='lg'\n          style={{\n            display: 'flex',\n            flexDirection: 'column',\n            flex: 1,\n          }}\n        >\n          <Box display={'flex'} flex={1} alignItems={'stretch'} flexDirection={'row'} marginTop={3}>\n            {children}\n          </Box>\n        </Container>\n      )}\n    </>\n  )\n}\n\nconst WrapModal = () => {\n  const { assetsRawData } = useGetAssets()\n  const location = useLocation()\n  const { etherscanBaseUrl } = useSystem()\n  const { t } = useTranslation()\n  const { getUserNotify } = useNotify()\n\n  const { depositProps } = useDeposit(false, { owner: store.getState()?.account?.accAddress })\n  const [notificationPush, setNotificationPush] = React.useState({ isShow: false, item: {} })\n  const { open, actionEle, handleClose } = useOffFaitModal()\n\n  const notificationCallback = React.useCallback((notification) => {\n    if (notification) {\n      setNotificationPush({ isShow: true, item: { ...notification } })\n      getUserNotify()\n    }\n  }, [])\n  useNotificationSocket({ notificationCallback })\n\n  const noticeSnacksElEs = React.useMemo(() => {\n    return [\n      <NoticeSnack\n        actionEle={actionEle}\n        open={open}\n        handleClose={handleClose}\n        messageInfo={{\n          svgIcon: 'BanxaIcon',\n          key: VendorProviders.Banxa,\n          message: t('labelOrderBanxaIsReadyToPay'),\n        }}\n      />,\n      ,\n    ] as any\n  }, [open, actionEle, notificationPush])\n  return (\n    <>\n      <ModalCoinPairPanel />\n      <ModalRedPacketPanel etherscanBaseUrl={etherscanBaseUrl} />\n      <ModalGroup\n        assetsRawData={assetsRawData}\n        depositProps={depositProps}\n        isLayer1Only={/(guardian)|(depositto)/gi.test(location.pathname ?? '')}\n      />\n      <NoticePanelSnackBar\n        noticeSnacksElEs={[\n          ...noticeSnacksElEs,\n          ...(notificationPush.isShow && notificationPush?.item\n            ? [\n                <NoticePop\n                  {...notificationPush?.item}\n                  isShow={notificationPush.isShow}\n                  setNotificationPush={setNotificationPush}\n                />,\n              ]\n            : []),\n        ]}\n      />\n    </>\n  )\n}\n\nconst RouterView = ({ state }: { state: keyof typeof SagaStatus }) => {\n  const location = useLocation()\n  const searchParams = new URLSearchParams(location.search)\n  const { tickerMap } = useTicker()\n  const { tokenMap: vaultTokenMap } = useVaultMap()\n\n  const { marketArray } = useTokenMap()\n  const { setTheme, defaultNetwork, setReferralCode } = useSettings()\n  const network = MapChainId[defaultNetwork] ?? MapChainId[1]\n\n  const {\n    toggle: { BTradeInvest, StopLimit, VaultInvest, isSupperUser },\n  } = useToggle()\n  const vaultEnabled = VaultInvest.enable || isSupperUser\n\n  React.useEffect(() => {\n    if (searchParams.has('theme')) {\n      searchParams.get('theme') === ThemeType.dark ? setTheme('dark') : setTheme('light')\n    }\n    if (searchParams.has('referralcode')) {\n      const value = searchParams.get('referralcode')\n      setReferralCode(value ? value : '')\n    }\n  }, [location.search])\n  if (searchParams.has('___OhTrustDebugger___')) {\n    // @ts-ignore\n    setMyLog(true)\n  }\n  const analytics = getAnalytics()\n\n  logEvent(analytics, 'Route', {\n    protocol: window.location.protocol,\n    pathname: window.location.pathname,\n    query: searchParams,\n  })\n  React.useEffect(() => {\n    if (/^\\/?wallet/.test(location.pathname)) {\n      window.open(WalletSite, '_self')\n      window.opener = null\n    }\n  }, [location.pathname])\n  return (\n    <>\n      <Switch>\n        <Route exact path='/loading'>\n          <LoadingPage />\n        </Route>\n        <Route exact path='/'>\n          {searchParams && searchParams.has('noheader') ? <></> : <Header isHideOnScroll={true} />}\n          <LandPage />\n        </Route>\n        <Route exact path='/pro'>\n          <Redirect to=\"/\" />\n        </Route>\n        <Route path='/document'>\n          {searchParams && searchParams.has('noheader') ? (\n            <></>\n          ) : (\n            <Header isHideOnScroll={true} isLandPage />\n          )}\n          <Container\n            maxWidth='lg'\n            style={{\n              display: 'flex',\n              flexDirection: 'column',\n              flex: 1,\n            }}\n          >\n            <MarkdownPage />\n          </Container>\n        </Route>\n        <Route exact path='/notification/:path'>\n          {searchParams && searchParams.has('noheader') ? (\n            <></>\n          ) : (\n            <Header isHideOnScroll={true} isLandPage />\n          )}\n          <Container\n            maxWidth='lg'\n            style={{\n              display: 'flex',\n              flexDirection: 'column',\n              flex: 1,\n            }}\n          >\n            <NotifyMarkdownPage />\n          </Container>\n        </Route>\n        <Route exact path={['/document', '/race-event', '/notification', '/investrule']}>\n          {searchParams && searchParams.has('noheader') ? <></> : <Header isHideOnScroll={true} />}\n          <ErrorPage messageKey={'error404'} />\n        </Route>\n        <Route exact path={['/race-event/:path']}>\n          {searchParams && searchParams.has('noheader') ? <></> : <Header isHideOnScroll={true} />}\n          <TradeRacePage />\n        </Route>\n\n        <Route path={RouterPath.pro}>\n          {searchParams && searchParams.has('noheader') ? <></> : <Header isHideOnScroll={true} />}\n\n          {state === 'PENDING' && tickerMap ? (\n            <LoadingBlock />\n          ) : RouterAllowIndex[network]?.includes(RouterMainKey.pro) ? (\n            <OrderbookPage />\n          ) : (\n            <ErrorPage {...ErrorMap.TRADE_404} />\n          )}\n        </Route>\n        <Route path={RouterPath.stoplimit}>\n          {searchParams && searchParams.has('noheader') ? <></> : <Header isHideOnScroll={true} />}\n\n          {state === 'PENDING' || !marketArray.length || !Object.keys(tickerMap ?? {}).length ? (\n            <LoadingBlock />\n          ) : RouterAllowIndex[network]?.includes(RouterMainKey.stoplimit) ? (\n            <StopLimitPage />\n          ) : (\n            <ErrorPage {...ErrorMap.TRADE_404} />\n          )}\n        </Route>\n        <Route path={RouterPath.btrade}>\n          <ContentWrap state={state} value={RouterMainKey.btrade}>\n            <BtradeSwapPage />\n          </ContentWrap>\n        </Route>\n        <Route exact path={[RouterPath.fiat, RouterPath.fiat + '/*']}>\n          <ContentWrap state={state} value={RouterMainKey.fiat}>\n            <FiatPage />\n          </ContentWrap>\n        </Route>\n        <Route path={[RouterPath.lite, RouterPath.trade]}>\n          <ContentWrap state={state} value={RouterMainKey.lite}>\n            <SwapPage />\n          </ContentWrap>\n        </Route>\n        <Route exact path={RouterPath.markets}>\n          <ContentWrap state={state} value={RouterMainKey.markets}>\n            <QuotePage />\n          </ContentWrap>\n        </Route>\n        <Route exact path={RouterPath.mining}>\n          <ContentWrap state={state} value={RouterMainKey.mining}>\n            <MiningPage />\n          </ContentWrap>\n        </Route>\n        <Route exact path={[RouterPath.redPacket, RouterPath.redPacket + '/*']}>\n          <ContentWrap state={state} value={RouterMainKey.redPacket}>\n            <RedPacketPage />\n          </ContentWrap>\n        </Route>\n        <Route exact path={[RouterPath.l2assets, RouterPath.l2assets + '/*']}>\n          <ContentWrap state={state} value={RouterMainKey.l2assets}>\n            <AssetPage />\n          </ContentWrap>\n        </Route>\n        <Route exact path={[RouterPath.layer2, RouterPath.layer2 + '/*']}>\n          <ContentWrap state={state} noContainer={true} value={RouterMainKey.layer2}>\n            <Layer2Page />\n          </ContentWrap>\n        </Route>\n\n        <Route exact path={[RouterPath.vault, RouterPath.vault + '/*']}>\n          <ContentWrap state={state} noContainer={true} value={RouterMainKey.layer2}>\n            {state === 'PENDING' && tickerMap ? (\n              <LoadingBlock />\n            ) : vaultEnabled && RouterAllowIndex[network]?.includes(RouterMainKey.vault) ? (\n              <VaultPage />\n            ) : (\n              <ErrorPage {...ErrorMap.TRADE_404} />\n            )}\n          </ContentWrap>\n        </Route>\n        <Route exact path={[RouterPath.nft, RouterPath.nft + '/*']}>\n          <ContentWrap state={state} value={RouterMainKey.nft}>\n            <NFTPage />\n          </ContentWrap>\n        </Route>\n        <Redirect exact path='/invest/leverageETH' to='/invest/leverageETH/redeem' />\n        <Redirect exact path='/invest/defi/WSTETH' to='/invest/defi/WSTETH/redeem' />\n        <Redirect exact path='/invest/defi/RETH' to='/invest/defi/RETH/redeem' />\n        \n        <Route exact path={[RouterPath.invest, RouterPath.invest + '/*']}>\n          <ContentWrap noContainer state={state} value={RouterMainKey.invest}>\n            <InvestPage />\n          </ContentWrap>\n        </Route>\n\n        <Route\n          path={['/guardian', '/guardian/*']}\n          component={() => (\n            <>\n              <Header isHideOnScroll={true} isLandPage />\n              <ErrorPage\n                {...ErrorMap.GUARDIAN_ROUTER_ERROR}\n                components={{\n                  a: <Link target='_blank' rel='noopener noreferrer' href={GUARDIAN_URL} />,\n                }}\n              />\n            </>\n          )}\n        />\n        <Route\n          path={['/error/:messageKey', '/error']}\n          component={() => (\n            <>\n              <Header isHideOnScroll={true} isLandPage />\n              <ErrorPage {...ErrorMap.NO_NETWORK_ERROR} />\n            </>\n          )}\n        />\n        <Route\n          component={() => (\n            <>\n              <Header isHideOnScroll={true} isLandPage />\n              <ErrorPage messageKey={'error404'} />\n            </>\n          )}\n        />\n      </Switch>\n      {state === SagaStatus.DONE && <WrapModal />}\n      {searchParams && searchParams.has('nofooter') ? <></> : <Footer />}\n    </>\n  )\n}\n\nexport default RouterView\n"
  },
  {
    "path": "packages/webapp/src/setupTests.ts",
    "content": "// jest-dom adds custom jest matchers for asserting on DOM nodes.\n// allows you to do things like:\n// expect(element).toHaveTextContent(/react/i)\n// learn more: https://github.com/testing-library/jest-dom\nimport '@testing-library/jest-dom'\n"
  },
  {
    "path": "packages/webapp/src/types.d.ts",
    "content": "import { LoopringSocket } from '@loopring-web/core'\nimport { RampInstantSDK } from '@ramp-network/ramp-instant-sdk'\n\ndeclare module '*.html' {\n  const value: string\n  export default value\n}\n/// <reference types=\"@google/model-viewer\" />\n\ndeclare global {\n  interface Window {\n    loopringSocket: InstanceType<LoopringSocket>\n    __renderReportCall__: () => void\n    rampInstance: RampInstantSDK | undefined\n    __ChainIdExtends: any\n    __MapChainId: any\n  }\n\n  namespace JSX {\n    interface IntrinsicElements {\n      'model-viewer': MyElementAttributes\n    }\n\n    interface MyElementAttributes {\n      src: string\n      'auto-rotate': any\n      'camera-controls': any\n      'ar-modes': any\n      'touch-action': any\n      'shadow-intensity': any\n      poster?: string\n\n      [key: string]: any\n    }\n  }\n}\n"
  },
  {
    "path": "packages/webapp/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.build.json\",\n  \"compilerOptions\": {\n    \"baseUrl\": \"src/\",\n    \"rootDir\": \".\",\n    \"noEmit\": true\n  },\n  \"include\": [\n    \"src\",\n    \"src/*\",\n    \"src/**/*.json\",\n    \"src/types.d.ts\"\n  ],\n  \"awesomeTypescriptLoaderOptions\": {\n    \"useCache\": true,\n    \"transpileOnly\": true\n  }\n}\n"
  },
  {
    "path": "tsconfig.build.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"ES2020\",\n    \"lib\": [\n      \"dom\",\n      \"dom.iterable\",\n      \"esnext\",\n      \"es2016\",\n      \"es2017\",\n      \"es2020\"\n    ],\n    \"files\": [\n      \"./node_modules/@types/node/index.d.ts\"\n    ],\n    \"module\": \"commonjs\",\n    \"jsx\": \"react-jsx\",\n    \"sourceMap\": true,\n    \"allowJs\": true,\n    \"composite\": true,\n    \"keyofStringsOnly\": true,\n    \"noImplicitAny\": false,\n    \"moduleResolution\": \"node\",\n    \"resolveJsonModule\": true,\n    \"isolatedModules\": true,\n    \"allowSyntheticDefaultImports\": true,\n    \"suppressImplicitAnyIndexErrors\": true,\n    \"skipLibCheck\": true,\n    \"esModuleInterop\": true,\n    \"strict\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"noFallthroughCasesInSwitch\": true,\n    \"noEmit\": true,\n    \"module\": \"esnext\"\n  },\n  \"exclude\": [\n    \"node_modules\",\n    \"dist\"\n  ]\n}\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"extends\": \"./tsconfig.build.json\",\n  \"compilerOptions\": {\n    \"baseUrl\": \"./\",\n    \"paths\": {\n      \"@loopring-web/webapp\": [\n        \"./packages/webapp/src\"\n      ],\n      \"@loopring-web/webapp/*\": [\n        \"./packages/webapp/src/*\"\n      ],\n      \"@loopring-web/web-bridge\": [\n        \"./packages/web-bridge/src\"\n      ],\n      \"@loopring-web/web-bridge/*\": [\n        \"./packages/web-bridge/src/*\"\n      ]\n    }\n  },\n  \"include\": [\n    \"**/*\"\n  ],\n  \"exclude\": [\n    \"node_modules\",\n    \"dist\",\n    \"../*.stories.*\",\n    \"docs\"\n  ]\n}\n"
  }
]